Author: remm Date: Thu Dec 10 15:41:17 2015 New Revision: 1719101 URL: http://svn.apache.org/viewvc?rev=1719101&view=rev Log: - Support server initiated renegotiation for OpenSSL, looks ok with the testsuite now. - Client initiated renegotiation seems rather hopeless though since the engine code has no idea this may be going on (it would need to enter handshake mode I think and hope for the best). At least that's what I understand about it. - If a SSL error occurs, don't call shutdown immediately, it is not possible to know what the error is really about [well, it is possible, but the error check would have to be a lot fancier and know the OpenSSL error codes].
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/openssl/LocalStrings.properties tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java tomcat/trunk/webapps/docs/changelog.xml Modified: tomcat/trunk/java/org/apache/tomcat/util/net/openssl/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/openssl/LocalStrings.properties?rev=1719101&r1=1719100&r2=1719101&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/openssl/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/openssl/LocalStrings.properties Thu Dec 10 15:41:17 2015 @@ -29,7 +29,7 @@ engine.writeToSSLFailed=Failed writing t engine.invalidBufferArray=offset: {0}, length: {1} (expected: offset <= offset + length <= srcs.length ({2})) engine.nullBufferInArray=Null buffer in array engine.nullBuffer=Null buffer -engine.readFromSSLFailed=Read from SSL failed, {0} SSL_read failed: primingReadResult: {1} OpenSSL error: {2} +engine.openSSLError=OpenSSL error: {0} message: {1} engine.inboundClose=Inbound closed before receiving peer's close_notify engine.nullCipherSuite=Null cipher suite engine.unsupportedCipher=Unsupported cipher suite: {0} ({1}) Modified: tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java?rev=1719101&r1=1719100&r2=1719101&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java Thu Dec 10 15:41:17 2015 @@ -167,6 +167,7 @@ public final class OpenSSLEngine extends private boolean isInboundDone; private boolean isOutboundDone; private boolean engineClosed; + private boolean needCertificate; private final boolean clientMode; private final String fallbackApplicationProtocol; @@ -883,11 +884,14 @@ public final class OpenSSLEngine extends } } - private void renegotiate() throws SSLException { + private synchronized void renegotiate() throws SSLException { int code = SSL.renegotiate(ssl); if (code <= 0) { checkLastError(); } + if (clientAuth == ClientAuthMode.REQUIRE) { + needCertificate = true; + } handshakeFinished = false; peerCerts = null; x509PeerCerts = null; @@ -901,9 +905,16 @@ public final class OpenSSLEngine extends long error = SSL.getLastErrorNumber(); if (error != SSL.SSL_ERROR_NONE) { String err = SSL.getErrorString(error); - // There was an internal error -- shutdown - shutdown(); - throw new SSLException(err); + if (logger.isDebugEnabled()) { + logger.debug(sm.getString("engine.openSSLError", error, err)); + } + // It is possible the error occurs during a rehandshake, so consider it done + // but delay an error + if (needCertificate) { + needCertificate = false; + } else { + throw new SSLException(err); + } } } @@ -928,6 +939,10 @@ public final class OpenSSLEngine extends return SSLEngineResult.HandshakeStatus.NEED_WRAP; } + if (needCertificate && getPeerCertificate() == null) { + return SSLEngineResult.HandshakeStatus.NEED_UNWRAP; + } + // No pending data to be sent to the peer // Check to see if we have finished handshaking if (SSL.isInInit(ssl) == 0) { @@ -1063,6 +1078,14 @@ public final class OpenSSLEngine extends return false; } + private byte[] getPeerCertificate() { + byte[] result = SSL.getPeerCertificate(ssl); + if (result != null) { + needCertificate = false; + } + return result; + } + @Override protected void finalize() throws Throwable { super.finalize(); @@ -1189,7 +1212,7 @@ public final class OpenSSLEngine extends // We use SSL_get_peer_certificate to get it in this case and add it to our array later. // // See https://www.openssl.org/docs/ssl/SSL_get_peer_cert_chain.html - clientCert = SSL.getPeerCertificate(ssl); + clientCert = getPeerCertificate(); } else { clientCert = null; } Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1719101&r1=1719100&r2=1719101&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Thu Dec 10 15:41:17 2015 @@ -143,14 +143,18 @@ Improve upgrade context classloader handling by using Context.bind and unbind. (remm) </fix> - <fix> + <add> Improve OpenSSL keystore/truststore configuration by using the code from the JSSE implementation. (remm, jfclere) - </fix> + </add> <fix> Fix a potential loop when a client drops the connection unexpectedly. (markt) </fix> + <add> + OpenSSL renegotiation support for client certificate authentication. + (remm) + </add> </changelog> </subsection> <subsection name="Jasper"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org