Author: rjung
Date: Sun Aug 13 14:35:05 2017
New Revision: 1804915

URL: http://svn.apache.org/viewvc?rev=1804915&view=rev
Log:
Wrap the KeyManagers used by the client to
allow tracking for which CA subjects a client
certificate was requested.

Modified:
    tomcat/trunk/test/org/apache/tomcat/util/net/TesterSupport.java

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=1804915&r1=1804914&r2=1804915&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/tomcat/util/net/TesterSupport.java (original)
+++ tomcat/trunk/test/org/apache/tomcat/util/net/TesterSupport.java Sun Aug 13 
14:35:05 2017
@@ -20,7 +20,10 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.Socket;
 import java.security.KeyStore;
+import java.security.Principal;
+import java.security.PrivateKey;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
 import java.util.Locale;
@@ -28,9 +31,13 @@ import java.util.Locale;
 import javax.net.ssl.KeyManager;
 import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509ExtendedKeyManager;
+import javax.net.ssl.X509KeyManager;
 import javax.net.ssl.X509TrustManager;
+import javax.security.auth.x500.X500Principal;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
@@ -63,6 +70,10 @@ public final class TesterSupport {
 
     public static final String ROLE = "testrole";
 
+    private static String clientAuthExpectedIssuer = null;
+    private static String lastUsage = "NONE";
+    private static Principal[] lastRequestedIssuers = new Principal[0];
+
     public static void initSsl(Tomcat tomcat) {
         initSsl(tomcat, LOCALHOST_JKS, null, null);
     }
@@ -113,7 +124,17 @@ public final class TesterSupport {
         KeyManagerFactory kmf = KeyManagerFactory.getInstance(
                 KeyManagerFactory.getDefaultAlgorithm());
         kmf.init(getKeyStore(CLIENT_JKS), JKS_PASS.toCharArray());
-        return kmf.getKeyManagers();
+        KeyManager[] managers = kmf.getKeyManagers();
+        KeyManager manager;
+        for (int i=0; i < managers.length; i++) {
+            manager = managers[i];
+            if (manager instanceof X509ExtendedKeyManager) {
+                managers[i] = new 
TrackingExtendedKeyManager((X509ExtendedKeyManager)manager);
+            } else if (manager instanceof X509KeyManager) {
+                managers[i] = new TrackingKeyManager((X509KeyManager)manager);
+            }
+        }
+        return managers;
     }
 
     protected static TrustManager[] getTrustManagers() throws Exception {
@@ -199,6 +220,15 @@ public final class TesterSupport {
         // Configure the Realm
         TesterMapRealm realm = new TesterMapRealm();
 
+        // Get the CA subject the server should send us for client cert 
selection
+        try {
+            KeyStore ks = getKeyStore(CA_JKS);
+            X509Certificate cert = 
(X509Certificate)ks.getCertificate(CA_ALIAS);
+            clientAuthExpectedIssuer = cert.getSubjectDN().getName();
+        } catch (Exception ex) {
+            // Ignore
+        }
+
         String cn = "NOTFOUND";
         try {
             KeyStore ks = getKeyStore(CLIENT_JKS);
@@ -219,6 +249,35 @@ public final class TesterSupport {
         ctx.getPipeline().addValve(new SSLAuthenticator());
     }
 
+    protected static String getClientAuthExpectedIssuer() {
+        return clientAuthExpectedIssuer;
+    }
+
+    protected static void trackTrackingKeyManagers(KeyManager wrapper, 
KeyManager wrapped,
+                                                   String usage, Principal[] 
issuers) {
+        lastUsage = usage;
+        lastRequestedIssuers = issuers;
+    }
+
+    protected static String getLastClientAuthKeyManagerUsage() {
+        return lastUsage;
+    }
+
+    protected static int getLastClientAuthRequestedIssuerCount() {
+        return lastRequestedIssuers == null ? 0 : lastRequestedIssuers.length;
+    }
+
+    protected static Principal getLastClientAuthRequestedIssuer(int index) {
+        return lastRequestedIssuers[0];
+    }
+
+    protected static boolean checkLastClientAuthRequestedIssuers() {
+        if (lastRequestedIssuers == null || lastRequestedIssuers.length != 1)
+            return false;
+        return (new X500Principal(clientAuthExpectedIssuer)).equals(
+                    new X500Principal(lastRequestedIssuers[0].getName()));
+    }
+
     public static final byte DATA = (byte)33;
 
     public static class SimpleServlet extends HttpServlet {
@@ -263,6 +322,104 @@ public final class TesterSupport {
         }
     }
 
+    public static class TrackingKeyManager implements X509KeyManager {
+
+        private X509KeyManager manager = null;
+
+        public TrackingKeyManager(X509KeyManager manager) {
+            this.manager = manager;
+        }
+
+        @Override
+        public String chooseClientAlias(String[] keyType, Principal[] issuers, 
Socket socket) {
+            trackTrackingKeyManagers(this, manager, "chooseClientAlias", 
issuers);
+            return manager.chooseClientAlias(keyType, issuers, socket);
+        }
+
+        @Override
+        public String chooseServerAlias(String keyType, Principal[] issuers, 
Socket socket) {
+            trackTrackingKeyManagers(this, manager, "chooseServerAlias", 
issuers);
+            return manager.chooseServerAlias(keyType, issuers, socket);
+        }
+
+        @Override
+        public X509Certificate[] getCertificateChain(String alias) {
+            return manager.getCertificateChain(alias);
+        }
+
+        @Override
+        public String[] getClientAliases(String keyType, Principal[] issuers) {
+            trackTrackingKeyManagers(this, manager, "getClientAliases", 
issuers);
+            return manager.getClientAliases(keyType, issuers);
+        }
+
+        @Override
+        public PrivateKey getPrivateKey(String alias) {
+            return manager.getPrivateKey(alias);
+        }
+
+        @Override
+        public String[] getServerAliases(String keyType, Principal[] issuers) {
+            trackTrackingKeyManagers(this, manager, "getServerAliases", 
issuers);
+            return manager.getServerAliases(keyType, issuers);
+        }
+    }
+
+    public static class TrackingExtendedKeyManager extends 
X509ExtendedKeyManager {
+
+        private X509ExtendedKeyManager manager = null;
+
+        public TrackingExtendedKeyManager(X509ExtendedKeyManager manager) {
+            this.manager = manager;
+        }
+
+        @Override
+        public String chooseClientAlias(String[] keyType, Principal[] issuers, 
Socket socket) {
+            trackTrackingKeyManagers(this, manager, "chooseClientAlias", 
issuers);
+            return manager.chooseClientAlias(keyType, issuers, socket);
+        }
+
+        @Override
+        public String chooseServerAlias(String keyType, Principal[] issuers, 
Socket socket) {
+            trackTrackingKeyManagers(this, manager, "chooseServerAlias", 
issuers);
+            return manager.chooseServerAlias(keyType, issuers, socket);
+        }
+
+        @Override
+        public X509Certificate[] getCertificateChain(String alias) {
+            return manager.getCertificateChain(alias);
+        }
+
+        @Override
+        public String[] getClientAliases(String keyType, Principal[] issuers) {
+            trackTrackingKeyManagers(this, manager, "getClientAliases", 
issuers);
+            return manager.getClientAliases(keyType, issuers);
+        }
+
+        @Override
+        public PrivateKey getPrivateKey(String alias) {
+            return manager.getPrivateKey(alias);
+        }
+
+        @Override
+        public String[] getServerAliases(String keyType, Principal[] issuers) {
+            trackTrackingKeyManagers(this, manager, "getServerAliases", 
issuers);
+            return manager.getServerAliases(keyType, issuers);
+        }
+
+        @Override
+        public String chooseEngineClientAlias(String[] keyType, Principal[] 
issuers, SSLEngine engine) {
+            trackTrackingKeyManagers(this, manager, "chooseEngineClientAlias", 
issuers);
+            return manager.chooseEngineClientAlias(keyType, issuers, engine);
+        }
+
+        @Override
+        public String chooseEngineServerAlias(String keyType, Principal[] 
issuers, SSLEngine engine) {
+            trackTrackingKeyManagers(this, manager, "chooseEngineServerAlias", 
issuers);
+            return manager.chooseEngineServerAlias(keyType, issuers, engine);
+        }
+    }
+
     public static class TrustAllCerts implements X509TrustManager {
 
         @Override



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to