Support SSLSession.getLocalCertificates() and getLocalPrincipal() when using OpenSSL

Motivation:

SSLSession.getLocalCertificates() and getLocalPrincipal() was not supported when using OpenSSL, which can produce problems when switch from JDK to OpenSSL impl.

Modifications:

Implement SSLSession.getLocalCertificates() and getLocalPrincipal() for OpenSslEngine.

Result:

More consistent behaving between JDK and OpenSSL based SSLEngine.
This commit is contained in:
Norman Maurer 2015-09-09 21:12:04 +02:00
parent 6e3acfeb06
commit 30b30f77c6
4 changed files with 23 additions and 13 deletions

View File

@ -171,7 +171,7 @@ public final class OpenSslClientContext extends OpenSslContext {
CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
long sessionCacheSize, long sessionTimeout) long sessionCacheSize, long sessionTimeout)
throws SSLException { throws SSLException {
super(ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, SSL.SSL_MODE_CLIENT); super(ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, SSL.SSL_MODE_CLIENT, null);
boolean success = false; boolean success = false;
try { try {
if (trustCertChainFile != null && !trustCertChainFile.isFile()) { if (trustCertChainFile != null && !trustCertChainFile.isFile()) {
@ -271,7 +271,7 @@ public final class OpenSslClientContext extends OpenSslContext {
CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
long sessionCacheSize, long sessionTimeout) long sessionCacheSize, long sessionTimeout)
throws SSLException { throws SSLException {
super(ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, SSL.SSL_MODE_CLIENT); super(ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, SSL.SSL_MODE_CLIENT, keyCertChain);
boolean success = false; boolean success = false;
try { try {
if (key == null && keyCertChain != null || key != null && keyCertChain == null) { if (key == null && keyCertChain != null || key != null && keyCertChain == null) {

View File

@ -36,6 +36,7 @@ import javax.net.ssl.TrustManager;
import javax.net.ssl.X509ExtendedTrustManager; import javax.net.ssl.X509ExtendedTrustManager;
import javax.net.ssl.X509TrustManager; import javax.net.ssl.X509TrustManager;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -81,6 +82,7 @@ public abstract class OpenSslContext extends SslContext {
private final OpenSslEngineMap engineMap = new DefaultOpenSslEngineMap(); private final OpenSslEngineMap engineMap = new DefaultOpenSslEngineMap();
private final OpenSslApplicationProtocolNegotiator apn; private final OpenSslApplicationProtocolNegotiator apn;
private final int mode; private final int mode;
private final Certificate[] keyCertChain;
static final OpenSslApplicationProtocolNegotiator NONE_PROTOCOL_NEGOTIATOR = static final OpenSslApplicationProtocolNegotiator NONE_PROTOCOL_NEGOTIATOR =
new OpenSslApplicationProtocolNegotiator() { new OpenSslApplicationProtocolNegotiator() {
@ -125,13 +127,14 @@ public abstract class OpenSslContext extends SslContext {
} }
OpenSslContext(Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apnCfg, OpenSslContext(Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apnCfg,
long sessionCacheSize, long sessionTimeout, int mode) throws SSLException { long sessionCacheSize, long sessionTimeout, int mode, Certificate[] keyCertChain)
this(ciphers, cipherFilter, toNegotiator(apnCfg), sessionCacheSize, sessionTimeout, mode); throws SSLException {
this(ciphers, cipherFilter, toNegotiator(apnCfg), sessionCacheSize, sessionTimeout, mode, keyCertChain);
} }
OpenSslContext(Iterable<String> ciphers, CipherSuiteFilter cipherFilter, OpenSslContext(Iterable<String> ciphers, CipherSuiteFilter cipherFilter,
OpenSslApplicationProtocolNegotiator apn, long sessionCacheSize, OpenSslApplicationProtocolNegotiator apn, long sessionCacheSize,
long sessionTimeout, int mode) throws SSLException { long sessionTimeout, int mode, Certificate[] keyCertChain) throws SSLException {
OpenSsl.ensureAvailability(); OpenSsl.ensureAvailability();
if (mode != SSL.SSL_MODE_SERVER && mode != SSL.SSL_MODE_CLIENT) { if (mode != SSL.SSL_MODE_SERVER && mode != SSL.SSL_MODE_CLIENT) {
@ -143,6 +146,7 @@ public abstract class OpenSslContext extends SslContext {
rejectRemoteInitiatedRenegotiation = rejectRemoteInitiatedRenegotiation =
JDK_REJECT_CLIENT_INITIATED_RENEGOTIATION; JDK_REJECT_CLIENT_INITIATED_RENEGOTIATION;
} }
this.keyCertChain = keyCertChain == null ? null : keyCertChain.clone();
final List<String> convertedCiphers; final List<String> convertedCiphers;
if (ciphers == null) { if (ciphers == null) {
convertedCiphers = null; convertedCiphers = null;
@ -287,7 +291,7 @@ public abstract class OpenSslContext extends SslContext {
@Override @Override
public final SSLEngine newEngine(ByteBufAllocator alloc, String peerHost, int peerPort) { public final SSLEngine newEngine(ByteBufAllocator alloc, String peerHost, int peerPort) {
final OpenSslEngine engine = new OpenSslEngine(ctx, alloc, isClient(), sessionContext(), apn, engineMap, final OpenSslEngine engine = new OpenSslEngine(ctx, alloc, isClient(), sessionContext(), apn, engineMap,
rejectRemoteInitiatedRenegotiation, peerHost, peerPort); rejectRemoteInitiatedRenegotiation, peerHost, peerPort, keyCertChain);
engineMap.add(engine); engineMap.add(engine);
return engine; return engine;
} }

View File

@ -174,6 +174,7 @@ public final class OpenSslEngine extends SSLEngine {
private final OpenSslApplicationProtocolNegotiator apn; private final OpenSslApplicationProtocolNegotiator apn;
private final boolean rejectRemoteInitiatedRenegation; private final boolean rejectRemoteInitiatedRenegation;
private final OpenSslSession session; private final OpenSslSession session;
private final java.security.cert.Certificate[] localCerts;
// This is package-private as we set it from OpenSslContext if an exception is thrown during // This is package-private as we set it from OpenSslContext if an exception is thrown during
// the verification step. // the verification step.
@ -203,13 +204,15 @@ public final class OpenSslEngine extends SSLEngine {
boolean clientMode, OpenSslSessionContext sessionContext, boolean clientMode, OpenSslSessionContext sessionContext,
OpenSslApplicationProtocolNegotiator apn, OpenSslEngineMap engineMap, OpenSslApplicationProtocolNegotiator apn, OpenSslEngineMap engineMap,
boolean rejectRemoteInitiatedRenegation) { boolean rejectRemoteInitiatedRenegation) {
this(sslCtx, alloc, clientMode, sessionContext, apn, engineMap, rejectRemoteInitiatedRenegation, null, -1); this(sslCtx, alloc, clientMode, sessionContext, apn, engineMap, rejectRemoteInitiatedRenegation, null, -1,
null);
} }
OpenSslEngine(long sslCtx, ByteBufAllocator alloc, OpenSslEngine(long sslCtx, ByteBufAllocator alloc,
boolean clientMode, OpenSslSessionContext sessionContext, boolean clientMode, OpenSslSessionContext sessionContext,
OpenSslApplicationProtocolNegotiator apn, OpenSslEngineMap engineMap, OpenSslApplicationProtocolNegotiator apn, OpenSslEngineMap engineMap,
boolean rejectRemoteInitiatedRenegation, String peerHost, int peerPort) { boolean rejectRemoteInitiatedRenegation, String peerHost, int peerPort,
java.security.cert.Certificate[] localCerts) {
super(peerHost, peerPort); super(peerHost, peerPort);
OpenSsl.ensureAvailability(); OpenSsl.ensureAvailability();
if (sslCtx == 0) { if (sslCtx == 0) {
@ -224,6 +227,7 @@ public final class OpenSslEngine extends SSLEngine {
this.clientMode = clientMode; this.clientMode = clientMode;
this.engineMap = engineMap; this.engineMap = engineMap;
this.rejectRemoteInitiatedRenegation = rejectRemoteInitiatedRenegation; this.rejectRemoteInitiatedRenegation = rejectRemoteInitiatedRenegation;
this.localCerts = localCerts;
} }
@Override @Override
@ -1537,8 +1541,10 @@ public final class OpenSslEngine extends SSLEngine {
@Override @Override
public Certificate[] getLocalCertificates() { public Certificate[] getLocalCertificates() {
// TODO: Find out how to get these if (localCerts == null) {
return EMPTY_CERTIFICATES; return null;
}
return localCerts.clone();
} }
@Override @Override
@ -1561,7 +1567,7 @@ public final class OpenSslEngine extends SSLEngine {
@Override @Override
public Principal getLocalPrincipal() { public Principal getLocalPrincipal() {
Certificate[] local = getLocalCertificates(); Certificate[] local = localCerts;
if (local == null || local.length == 0) { if (local == null || local.length == 0) {
return null; return null;
} }

View File

@ -317,7 +317,7 @@ public final class OpenSslServerContext extends OpenSslContext {
File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory, File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory,
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, OpenSslApplicationProtocolNegotiator apn, Iterable<String> ciphers, CipherSuiteFilter cipherFilter, OpenSslApplicationProtocolNegotiator apn,
long sessionCacheSize, long sessionTimeout) throws SSLException { long sessionCacheSize, long sessionTimeout) throws SSLException {
super(ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, SSL.SSL_MODE_SERVER); super(ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, SSL.SSL_MODE_SERVER, null);
OpenSsl.ensureAvailability(); OpenSsl.ensureAvailability();
checkNotNull(keyCertChainFile, "keyCertChainFile"); checkNotNull(keyCertChainFile, "keyCertChainFile");
@ -418,7 +418,7 @@ public final class OpenSslServerContext extends OpenSslContext {
X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory, X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory,
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
long sessionCacheSize, long sessionTimeout) throws SSLException { long sessionCacheSize, long sessionTimeout) throws SSLException {
super(ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, SSL.SSL_MODE_SERVER); super(ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, SSL.SSL_MODE_SERVER, keyCertChain);
OpenSsl.ensureAvailability(); OpenSsl.ensureAvailability();
checkNotNull(keyCertChain, "keyCertChainFile"); checkNotNull(keyCertChain, "keyCertChainFile");