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

View File

@ -174,6 +174,7 @@ public final class OpenSslEngine extends SSLEngine {
private final OpenSslApplicationProtocolNegotiator apn;
private final boolean rejectRemoteInitiatedRenegation;
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
// the verification step.
@ -203,13 +204,15 @@ public final class OpenSslEngine extends SSLEngine {
boolean clientMode, OpenSslSessionContext sessionContext,
OpenSslApplicationProtocolNegotiator apn, OpenSslEngineMap engineMap,
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,
boolean clientMode, OpenSslSessionContext sessionContext,
OpenSslApplicationProtocolNegotiator apn, OpenSslEngineMap engineMap,
boolean rejectRemoteInitiatedRenegation, String peerHost, int peerPort) {
boolean rejectRemoteInitiatedRenegation, String peerHost, int peerPort,
java.security.cert.Certificate[] localCerts) {
super(peerHost, peerPort);
OpenSsl.ensureAvailability();
if (sslCtx == 0) {
@ -224,6 +227,7 @@ public final class OpenSslEngine extends SSLEngine {
this.clientMode = clientMode;
this.engineMap = engineMap;
this.rejectRemoteInitiatedRenegation = rejectRemoteInitiatedRenegation;
this.localCerts = localCerts;
}
@Override
@ -1537,8 +1541,10 @@ public final class OpenSslEngine extends SSLEngine {
@Override
public Certificate[] getLocalCertificates() {
// TODO: Find out how to get these
return EMPTY_CERTIFICATES;
if (localCerts == null) {
return null;
}
return localCerts.clone();
}
@Override
@ -1561,7 +1567,7 @@ public final class OpenSslEngine extends SSLEngine {
@Override
public Principal getLocalPrincipal() {
Certificate[] local = getLocalCertificates();
Certificate[] local = localCerts;
if (local == null || local.length == 0) {
return null;
}

View File

@ -317,7 +317,7 @@ public final class OpenSslServerContext extends OpenSslContext {
File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory,
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, OpenSslApplicationProtocolNegotiator apn,
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();
checkNotNull(keyCertChainFile, "keyCertChainFile");
@ -418,7 +418,7 @@ public final class OpenSslServerContext extends OpenSslContext {
X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory,
Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
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();
checkNotNull(keyCertChain, "keyCertChainFile");