You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2015/12/03 18:14:57 UTC
svn commit: r1717808 - in /tomcat/trunk: build.xml
java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java
java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java
test/org/apache/tomcat/util/net/TesterSupport.java
Author: remm
Date: Thu Dec 3 17:14:57 2015
New Revision: 1717808
URL: http://svn.apache.org/viewvc?rev=1717808&view=rev
Log:
- Add some renegotiation code to the OpenSSL SSLEngine. It seems to do something, but certificate extraction doesn't work (returns null).
- Allow using the OpenSSL engine with the testsuite using a test.sslImplementation property (set to the sslImplementationName from server.xml).
Modified:
tomcat/trunk/build.xml
tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java
tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java
tomcat/trunk/test/org/apache/tomcat/util/net/TesterSupport.java
Modified: tomcat/trunk/build.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/build.xml?rev=1717808&r1=1717807&r2=1717808&view=diff
==============================================================================
--- tomcat/trunk/build.xml (original)
+++ tomcat/trunk/build.xml Thu Dec 3 17:14:57 2015
@@ -1455,6 +1455,7 @@
<sysproperty key="tomcat.test.reports" value="${test.reports}" />
<sysproperty key="tomcat.test.openssl.path" value="${test.openssl.path}" />
<sysproperty key="tomcat.test.relaxTiming" value="${test.relaxTiming}" />
+ <sysproperty key="tomcat.test.sslImplementation" value="${test.sslImplementation}" />
<!-- File for Cobertura to write coverage results to -->
<sysproperty key="net.sourceforge.cobertura.datafile" file="${cobertura.datafile}" />
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java?rev=1717808&r1=1717807&r2=1717808&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java Thu Dec 3 17:14:57 2015
@@ -445,6 +445,7 @@ public class OpenSSLContext implements o
SSLContext.free(ctx);
}
}
- destroyPools();
+ //FIXME: this causes crashes in the testsuite
+ //destroyPools();
}
}
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=1717808&r1=1717807&r2=1717808&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 3 17:14:57 2015
@@ -161,8 +161,8 @@ public final class OpenSSLEngine extends
private volatile String cipher;
private volatile String applicationProtocol;
- // We store this outside of the SslSession so we not need to create an instance during verifyCertificates(...)
private volatile Certificate[] peerCerts;
+ private volatile X509Certificate[] x509PeerCerts;
private volatile ClientAuthMode clientAuth = ClientAuthMode.NONE;
// SSL Engine status variables
@@ -629,18 +629,7 @@ public final class OpenSSLEngine extends
// check if SSL_read returned <= 0. In this case we need to check the error and see if it was something
// fatal.
if (lastPrimingReadResult <= 0) {
- // Check for OpenSSL errors caused by the priming read
- long error = SSL.getLastErrorNumber();
- if (error != SSL.SSL_ERROR_NONE) {
- String err = SSL.getErrorString(error);
- if (logger.isDebugEnabled()) {
- logger.debug(sm.getString("engine.readFromSSLFailed", Long.toString(error),
- Integer.toString(lastPrimingReadResult), err));
- }
- // There was an internal error -- shutdown
- shutdown();
- throw new SSLException(err);
- }
+ checkLastError();
}
return SSL.pendingReadableBytesInSSL(ssl);
}
@@ -835,45 +824,6 @@ public final class OpenSSLEngine extends
}
}
- private Certificate[] initPeerCertChain() throws SSLPeerUnverifiedException {
- byte[][] chain = SSL.getPeerCertChain(ssl);
- byte[] clientCert;
- if (!clientMode) {
- // if used on the server side SSL_get_peer_cert_chain(...) will not include the remote peer certificate.
- // 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);
- } else {
- clientCert = null;
- }
-
- if (chain == null && clientCert == null) {
- throw new SSLPeerUnverifiedException(sm.getString("engine.unverifiedPeer"));
- }
- int len = 0;
- if (chain != null) {
- len += chain.length;
- }
-
- int i = 0;
- Certificate[] peerCerts;
- if (clientCert != null) {
- len++;
- peerCerts = new Certificate[len];
- peerCerts[i++] = new OpenSslX509Certificate(clientCert);
- } else {
- peerCerts = new Certificate[len];
- }
- if (chain != null) {
- int a = 0;
- for (; i < peerCerts.length; i++) {
- peerCerts[i] = new OpenSslX509Certificate(chain[a++]);
- }
- }
- return peerCerts;
- }
-
@Override
public SSLSession getSession() {
return session;
@@ -899,7 +849,8 @@ public final class OpenSSLEngine extends
accepted = 2; // Next time this method is invoked by the user, we should raise an exception.
break;
case 2:
- throw RENEGOTIATION_UNSUPPORTED;
+ renegotiate();
+ break;
default:
throw new Error();
}
@@ -919,17 +870,7 @@ public final class OpenSSLEngine extends
private void handshake() throws SSLException {
int code = SSL.doHandshake(ssl);
if (code <= 0) {
- // Check for OpenSSL errors caused by the handshake
- long error = SSL.getLastErrorNumber();
- if (error != SSL.SSL_ERROR_NONE) {
- String err = SSL.getErrorString(error);
- if (logger.isDebugEnabled()) {
- logger.debug(sm.getString("engine.handshakeFailure", err));
- }
- // There was an internal error -- shutdown
- shutdown();
- throw new SSLException(err);
- }
+ checkLastError();
} else {
if (alpn) {
selectedProtocol = SSL.getAlpnSelected(ssl);
@@ -944,6 +885,31 @@ public final class OpenSSLEngine extends
}
}
+ private void renegotiate() throws SSLException {
+ int code = SSL.renegotiate(ssl);
+ if (code <= 0) {
+ checkLastError();
+ } else {
+ handshakeFinished = false;
+ peerCerts = null;
+ x509PeerCerts = null;
+ }
+ code = SSL.doHandshake(ssl);
+ if (code <= 0) {
+ checkLastError();
+ }
+ }
+
+ private void checkLastError() throws SSLException {
+ 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);
+ }
+ }
+
private static long memoryAddress(ByteBuffer buf) {
return Buffer.address(buf);
}
@@ -1109,9 +1075,6 @@ public final class OpenSSLEngine extends
private class OpenSSLSession implements SSLSession {
- // SSLSession implementation seems to not need to be thread-safe so no need for volatile etc.
- private X509Certificate[] x509PeerCerts;
-
// lazy init for memory reasons
private Map<String, Object> values;
@@ -1222,7 +1185,41 @@ public final class OpenSSLEngine extends
if (SSL.isInInit(ssl) != 0) {
throw new SSLPeerUnverifiedException(sm.getString("engine.unverifiedPeer"));
}
- c = peerCerts = initPeerCertChain();
+ byte[][] chain = SSL.getPeerCertChain(ssl);
+ byte[] clientCert;
+ if (!clientMode) {
+ // if used on the server side SSL_get_peer_cert_chain(...) will not include the remote peer certificate.
+ // 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);
+ } else {
+ clientCert = null;
+ }
+ if (chain == null && clientCert == null) {
+ return null;
+ }
+ int len = 0;
+ if (chain != null) {
+ len += chain.length;
+ }
+
+ int i = 0;
+ Certificate[] certificates;
+ if (clientCert != null) {
+ len++;
+ certificates = new Certificate[len];
+ certificates[i++] = new OpenSslX509Certificate(clientCert);
+ } else {
+ certificates = new Certificate[len];
+ }
+ if (chain != null) {
+ int a = 0;
+ for (; i < certificates.length; i++) {
+ certificates[i] = new OpenSslX509Certificate(chain[a++]);
+ }
+ }
+ c = peerCerts = certificates;
}
return c;
}
Modified: tomcat/trunk/test/org/apache/tomcat/util/net/TesterSupport.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/util/net/TesterSupport.java?rev=1717808&r1=1717807&r2=1717808&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/tomcat/util/net/TesterSupport.java (original)
+++ tomcat/trunk/test/org/apache/tomcat/util/net/TesterSupport.java Thu Dec 3 17:14:57 2015
@@ -38,6 +38,8 @@ import javax.servlet.http.HttpServletRes
import org.apache.catalina.Context;
import org.apache.catalina.authenticator.SSLAuthenticator;
import org.apache.catalina.connector.Connector;
+import org.apache.catalina.core.AprLifecycleListener;
+import org.apache.catalina.core.StandardServer;
import org.apache.catalina.startup.TesterMapRealm;
import org.apache.catalina.startup.Tomcat;
import org.apache.tomcat.util.descriptor.web.LoginConfig;
@@ -58,6 +60,14 @@ public final class TesterSupport {
String protocol = tomcat.getConnector().getProtocolHandlerClassName();
if (protocol.indexOf("Apr") == -1) {
Connector connector = tomcat.getConnector();
+ String sslImplementation = System.getProperty("tomcat.test.sslImplementation");
+ if (sslImplementation != null && !"${test.sslImplementation}".equals(sslImplementation)) {
+ StandardServer server = (StandardServer) tomcat.getServer();
+ AprLifecycleListener listener = new AprLifecycleListener();
+ listener.setSSLRandomSeed("/dev/urandom");
+ server.addLifecycleListener(listener);
+ tomcat.getConnector().setAttribute("sslImplementationName", sslImplementation);
+ }
connector.setProperty("sslProtocol", "tls");
File keystoreFile =
new File("test/org/apache/tomcat/util/net/" + keystore);
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org