Allow to enable client authentication on the OpenSslEngine

Motivation:

At the moment there is no way to enable client authentication when using OpenSslEngine. This limits the uses of OpenSslEngine.

Modifications:

Add support for different authentication modes.

Result:

OpenSslEngine can now also be used when client authenticiation is needed.
This commit is contained in:
Norman Maurer 2014-10-21 10:14:15 +02:00 committed by Norman Maurer
parent 87eca066da
commit 473c23aec9

View File

@ -91,6 +91,12 @@ public final class OpenSslEngine extends SSLEngine {
static final int MAX_ENCRYPTION_OVERHEAD_LENGTH = MAX_ENCRYPTED_PACKET_LENGTH - MAX_PLAINTEXT_LENGTH; static final int MAX_ENCRYPTION_OVERHEAD_LENGTH = MAX_ENCRYPTED_PACKET_LENGTH - MAX_PLAINTEXT_LENGTH;
enum ClientAuthMode {
NONE,
OPTIONAL,
REQUIRE,
}
private static final AtomicIntegerFieldUpdater<OpenSslEngine> DESTROYED_UPDATER; private static final AtomicIntegerFieldUpdater<OpenSslEngine> DESTROYED_UPDATER;
private static final AtomicReferenceFieldUpdater<OpenSslEngine, SSLSession> SESSION_UPDATER; private static final AtomicReferenceFieldUpdater<OpenSslEngine, SSLSession> SESSION_UPDATER;
@ -115,6 +121,7 @@ public final class OpenSslEngine extends SSLEngine {
// We store this outside of the SslSession so we not need to create an instance during verifyCertificates(...) // We store this outside of the SslSession so we not need to create an instance during verifyCertificates(...)
private volatile Certificate[] peerCerts; private volatile Certificate[] peerCerts;
private volatile ClientAuthMode clientAuth = ClientAuthMode.NONE;
// SSL Engine status variables // SSL Engine status variables
private boolean isInboundDone; private boolean isInboundDone;
@ -1070,26 +1077,46 @@ public final class OpenSslEngine extends SSLEngine {
@Override @Override
public void setNeedClientAuth(boolean b) { public void setNeedClientAuth(boolean b) {
if (b) { setClientAuth(b ? ClientAuthMode.REQUIRE : ClientAuthMode.NONE);
throw new UnsupportedOperationException();
}
} }
@Override @Override
public boolean getNeedClientAuth() { public boolean getNeedClientAuth() {
return false; return clientAuth == ClientAuthMode.REQUIRE;
} }
@Override @Override
public void setWantClientAuth(boolean b) { public void setWantClientAuth(boolean b) {
if (b) { setClientAuth(b ? ClientAuthMode.OPTIONAL : ClientAuthMode.NONE);
throw new UnsupportedOperationException();
}
} }
@Override @Override
public boolean getWantClientAuth() { public boolean getWantClientAuth() {
return false; return clientAuth == ClientAuthMode.OPTIONAL;
}
private void setClientAuth(ClientAuthMode mode) {
if (clientMode) {
return;
}
synchronized (this) {
if (clientAuth == mode) {
// No need to issue any JNI calls if the mode is the same
return;
}
switch (mode) {
case NONE:
SSL.setVerify(ssl, SSL.SSL_CVERIFY_NONE, OpenSslContext.VERIFY_DEPTH);
break;
case REQUIRE:
SSL.setVerify(ssl, SSL.SSL_CVERIFY_REQUIRE, OpenSslContext.VERIFY_DEPTH);
break;
case OPTIONAL:
SSL.setVerify(ssl, SSL.SSL_CVERIFY_OPTIONAL, OpenSslContext.VERIFY_DEPTH);
break;
}
clientAuth = mode;
}
} }
@Override @Override