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: [email protected]
For additional commands, e-mail: [email protected]