aboutsummaryrefslogtreecommitdiffstats
path: root/security-utils/src/main/java/com/yahoo/security/tls/PeerAuthorizerTrustManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'security-utils/src/main/java/com/yahoo/security/tls/PeerAuthorizerTrustManager.java')
-rw-r--r--security-utils/src/main/java/com/yahoo/security/tls/PeerAuthorizerTrustManager.java51
1 files changed, 23 insertions, 28 deletions
diff --git a/security-utils/src/main/java/com/yahoo/security/tls/PeerAuthorizerTrustManager.java b/security-utils/src/main/java/com/yahoo/security/tls/PeerAuthorizerTrustManager.java
index b92cd6c9538..c3dcdf1dc9e 100644
--- a/security-utils/src/main/java/com/yahoo/security/tls/PeerAuthorizerTrustManager.java
+++ b/security-utils/src/main/java/com/yahoo/security/tls/PeerAuthorizerTrustManager.java
@@ -6,6 +6,7 @@ import com.yahoo.security.X509CertificateUtils;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.X509ExtendedTrustManager;
import java.net.Socket;
@@ -13,18 +14,20 @@ import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;
-import java.util.Optional;
+import java.util.logging.Level;
import java.util.logging.Logger;
/**
* A {@link X509ExtendedTrustManager} that performs additional certificate verification through {@link PeerAuthorizer}.
*
+ * Implementation assumes that provided {@link X509ExtendedTrustManager} will throw {@link IllegalArgumentException}
+ * when chain is empty or null.
+ *
* @author bjorncs
*/
-// Note: Implementation assumes that provided X509ExtendedTrustManager will throw IllegalArgumentException when chain is empty or null
-public class PeerAuthorizerTrustManager extends X509ExtendedTrustManager {
+class PeerAuthorizerTrustManager extends X509ExtendedTrustManager {
- public static final String HANDSHAKE_SESSION_AUTH_CONTEXT_PROPERTY = "vespa.tls.auth.ctx";
+ static final String AUTH_CONTEXT_PROPERTY = "vespa.tls.auth.ctx";
private static final Logger log = Logger.getLogger(PeerAuthorizerTrustManager.class.getName());
@@ -33,20 +36,16 @@ public class PeerAuthorizerTrustManager extends X509ExtendedTrustManager {
private final AuthorizationMode mode;
private final HostnameVerification hostnameVerification;
- public PeerAuthorizerTrustManager(AuthorizedPeers authorizedPeers,
- AuthorizationMode mode,
- HostnameVerification hostnameVerification,
- X509ExtendedTrustManager defaultTrustManager) {
+ PeerAuthorizerTrustManager(AuthorizedPeers authorizedPeers, AuthorizationMode mode,
+ HostnameVerification hostnameVerification, X509ExtendedTrustManager defaultTrustManager) {
this.authorizer = new PeerAuthorizer(authorizedPeers);
this.mode = mode;
this.hostnameVerification = hostnameVerification;
this.defaultTrustManager = defaultTrustManager;
}
- public PeerAuthorizerTrustManager(AuthorizedPeers authorizedPeers,
- AuthorizationMode mode,
- HostnameVerification hostnameVerification,
- KeyStore truststore) {
+ PeerAuthorizerTrustManager(AuthorizedPeers authorizedPeers, AuthorizationMode mode,
+ HostnameVerification hostnameVerification, KeyStore truststore) {
this(authorizedPeers, mode, hostnameVerification, TrustManagerUtils.createDefaultX509TrustManager(truststore));
}
@@ -65,27 +64,27 @@ public class PeerAuthorizerTrustManager extends X509ExtendedTrustManager {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException {
defaultTrustManager.checkClientTrusted(chain, authType, socket);
- authorizePeer(chain, authType, true, null);
+ authorizePeer(chain, authType, true, ((SSLSocket)socket).getHandshakeSession());
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException {
overrideHostnameVerificationForClient(socket);
defaultTrustManager.checkServerTrusted(chain, authType, socket);
- authorizePeer(chain, authType, false, null);
+ authorizePeer(chain, authType, false, ((SSLSocket)socket).getHandshakeSession());
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine sslEngine) throws CertificateException {
defaultTrustManager.checkClientTrusted(chain, authType, sslEngine);
- authorizePeer(chain, authType, true, sslEngine);
+ authorizePeer(chain, authType, true, sslEngine.getHandshakeSession());
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine sslEngine) throws CertificateException {
overrideHostnameVerificationForClient(sslEngine);
defaultTrustManager.checkServerTrusted(chain, authType, sslEngine);
- authorizePeer(chain, authType, false, sslEngine);
+ authorizePeer(chain, authType, false, sslEngine.getHandshakeSession());
}
@Override
@@ -93,21 +92,17 @@ public class PeerAuthorizerTrustManager extends X509ExtendedTrustManager {
return defaultTrustManager.getAcceptedIssuers();
}
- /**
- * Note: The authorization result is only available during handshake. The underlying handshake session is removed once handshake is complete.
- */
- public static Optional<ConnectionAuthContext> getConnectionAuthContext(SSLEngine sslEngine) {
- return Optional.ofNullable(sslEngine.getHandshakeSession())
- .flatMap(session -> Optional.ofNullable((ConnectionAuthContext) session.getValue(HANDSHAKE_SESSION_AUTH_CONTEXT_PROPERTY)));
- }
-
- private void authorizePeer(X509Certificate[] certChain, String authType, boolean isVerifyingClient, SSLEngine sslEngine) throws CertificateException {
+ private void authorizePeer(X509Certificate[] certChain, String authType, boolean isVerifyingClient,
+ SSLSession handshakeSessionOrNull) throws PeerAuthorizationFailedException {
log.fine(() -> "Verifying certificate: " + createInfoString(certChain[0], authType, isVerifyingClient));
ConnectionAuthContext result = mode != AuthorizationMode.DISABLE
? authorizer.authorizePeer(List.of(certChain))
: ConnectionAuthContext.defaultAllCapabilities(List.of(certChain));
- if (sslEngine != null) { // getHandshakeSession() will never return null in this context
- sslEngine.getHandshakeSession().putValue(HANDSHAKE_SESSION_AUTH_CONTEXT_PROPERTY, result);
+ if (handshakeSessionOrNull != null) {
+ handshakeSessionOrNull.putValue(AUTH_CONTEXT_PROPERTY, result);
+ } else {
+ log.log(Level.FINE,
+ () -> "Warning: unable to provide ConnectionAuthContext as no SSLSession is available");
}
if (result.authorized()) {
log.fine(() -> String.format("Verification result: %s", result));
@@ -115,7 +110,7 @@ public class PeerAuthorizerTrustManager extends X509ExtendedTrustManager {
String errorMessage = "Authorization failed: " + createInfoString(certChain[0], authType, isVerifyingClient);
log.warning(errorMessage);
if (mode == AuthorizationMode.ENFORCE) {
- throw new CertificateException(errorMessage);
+ throw new PeerAuthorizationFailedException(errorMessage, List.of(certChain));
}
}
}