Author: markt Date: Tue Sep 15 17:50:54 2009 New Revision: 815418 URL: http://svn.apache.org/viewvc?rev=815418&view=rev Log: Fix Tomcat side of https://issues.apache.org/bugzilla/show_bug.cgi?id=46950 - adds new setVerify() method - uses it before renegotiation to change the cert verification level for the connection - increments minimum tc native version to 1.1.17 as it requires the new setVerify() method
Modified: tomcat/trunk/java/org/apache/catalina/core/AprLifecycleListener.java tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java tomcat/trunk/java/org/apache/tomcat/jni/SSLSocket.java Modified: tomcat/trunk/java/org/apache/catalina/core/AprLifecycleListener.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/AprLifecycleListener.java?rev=815418&r1=815417&r2=815418&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/AprLifecycleListener.java (original) +++ tomcat/trunk/java/org/apache/catalina/core/AprLifecycleListener.java Tue Sep 15 17:50:54 2009 @@ -58,9 +58,9 @@ protected static final int TCN_REQUIRED_MAJOR = 1; protected static final int TCN_REQUIRED_MINOR = 1; - protected static final int TCN_REQUIRED_PATCH = 8; + protected static final int TCN_REQUIRED_PATCH = 17; protected static final int TCN_RECOMMENDED_MIN = 1; - protected static final int TCN_RECOMMENDED_PV = 16; + protected static final int TCN_RECOMMENDED_PV = 17; // ---------------------------------------------- Properties Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java?rev=815418&r1=815417&r2=815418&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java Tue Sep 15 17:50:54 2009 @@ -1118,10 +1118,11 @@ request.setAttribute(AprEndpoint.CIPHER_SUITE_KEY, sslO); } // Get client certificate and the certificate chain if present + // certLength == -1 indicates an error int certLength = SSLSocket.getInfoI(socket, SSL.SSL_INFO_CLIENT_CERT_CHAIN); byte[] clientCert = SSLSocket.getInfoB(socket, SSL.SSL_INFO_CLIENT_CERT); X509Certificate[] certs = null; - if (clientCert != null) { + if (clientCert != null && certLength > -1) { certs = new X509Certificate[certLength + 1]; CertificateFactory cf = CertificateFactory.getInstance("X.509"); certs[0] = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(clientCert)); @@ -1152,29 +1153,35 @@ } else if (actionCode == ActionCode.ACTION_REQ_SSL_CERTIFICATE) { if (ssl && (socket != 0)) { - // Consume and buffer the request body, so that it does not - // interfere with the client's handshake messages + // Consume and buffer the request body, so that it does not + // interfere with the client's handshake messages InputFilter[] inputFilters = inputBuffer.getFilters(); ((BufferedInputFilter) inputFilters[Constants.BUFFERED_FILTER]).setLimit(maxSavePostSize); inputBuffer.addActiveFilter(inputFilters[Constants.BUFFERED_FILTER]); try { - // Renegociate certificates - SSLSocket.renegotiate(socket); - // Get client certificate and the certificate chain if present - int certLength = SSLSocket.getInfoI(socket, SSL.SSL_INFO_CLIENT_CERT_CHAIN); - byte[] clientCert = SSLSocket.getInfoB(socket, SSL.SSL_INFO_CLIENT_CERT); - X509Certificate[] certs = null; - if (clientCert != null) { - certs = new X509Certificate[certLength + 1]; - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - certs[0] = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(clientCert)); - for (int i = 0; i < certLength; i++) { - byte[] data = SSLSocket.getInfoB(socket, SSL.SSL_INFO_CLIENT_CERT_CHAIN + i); - certs[i+1] = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(data)); + // Configure connection to require a certificate + SSLSocket.setVerify(socket, SSL.SSL_CVERIFY_REQUIRE, + endpoint.getSSLVerifyDepth()); + // Renegotiate certificates + if (SSLSocket.renegotiate(socket) == 0) { + // Don't look for certs unless we know renegotiation worked. + // Get client certificate and the certificate chain if present + // certLength == -1 indicates an error + int certLength = SSLSocket.getInfoI(socket,SSL.SSL_INFO_CLIENT_CERT_CHAIN); + byte[] clientCert = SSLSocket.getInfoB(socket, SSL.SSL_INFO_CLIENT_CERT); + X509Certificate[] certs = null; + if (clientCert != null && certLength > -1) { + certs = new X509Certificate[certLength + 1]; + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + certs[0] = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(clientCert)); + for (int i = 0; i < certLength; i++) { + byte[] data = SSLSocket.getInfoB(socket, SSL.SSL_INFO_CLIENT_CERT_CHAIN + i); + certs[i+1] = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(data)); + } + } + if (certs != null) { + request.setAttribute(AprEndpoint.CERTIFICATE_KEY, certs); } - } - if (certs != null) { - request.setAttribute(AprEndpoint.CERTIFICATE_KEY, certs); } } catch (Exception e) { log.warn(sm.getString("http11processor.socket.ssl"), e); Modified: tomcat/trunk/java/org/apache/tomcat/jni/SSLSocket.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/jni/SSLSocket.java?rev=815418&r1=815417&r2=815418&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/jni/SSLSocket.java (original) +++ tomcat/trunk/java/org/apache/tomcat/jni/SSLSocket.java Tue Sep 15 17:50:54 2009 @@ -48,7 +48,7 @@ * response is sent. In more detail: the renegotiation happens after the * request line and MIME headers were read, but _before_ the attached * request body is read. The reason simply is that in the HTTP protocol - * usually there is no acknowledgment step between the headers and the + * usually there is no acknowledgement step between the headers and the * body (there is the 100-continue feature and the chunking facility * only), so Apache has no API hook for this step. * @@ -57,7 +57,30 @@ public static native int renegotiate(long thesocket); /** - * Retrun SSL Info parameter as byte array. + * Set Type of Client Certificate verification and Maximum depth of CA + * Certificates in Client Certificate verification. + * <br /> + * This is used to change the verification level for a connection prior to + * starting a re-negotiation. + * <br /> + * The following levels are available for level: + * <PRE> + * SSL_CVERIFY_NONE - No client Certificate is required at all + * SSL_CVERIFY_OPTIONAL - The client may present a valid Certificate + * SSL_CVERIFY_REQUIRE - The client has to present a valid + * Certificate + * SSL_CVERIFY_OPTIONAL_NO_CA - The client may present a valid Certificate + * but it need not to be (successfully) + * verifiable + * </PRE> + * <br /> + * @param sock The socket to change. + * @param level Type of Client Certificate verification. + */ + public static native void setVerify(long sock, int level, int depth); + + /** + * Return SSL Info parameter as byte array. * * @param sock The socket to read the data from. * @param id Parameter id. @@ -67,7 +90,7 @@ throws Exception; /** - * Retrun SSL Info parameter as String. + * Return SSL Info parameter as String. * * @param sock The socket to read the data from. * @param id Parameter id. @@ -77,7 +100,7 @@ throws Exception; /** - * Retrun SSL Info parameter as integer. + * Return SSL Info parameter as integer. * * @param sock The socket to read the data from. * @param id Parameter id. --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org