You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2020/06/04 21:14:53 UTC

[tomcat] branch 9.0.x updated: Implement more of the TLS env in rewrite resolver

This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/9.0.x by this push:
     new 55443d3  Implement more of the TLS env in rewrite resolver
55443d3 is described below

commit 55443d317da37d6c6bc1ee1f81078e1d9dea91c7
Author: remm <re...@apache.org>
AuthorDate: Thu Jun 4 23:13:36 2020 +0200

    Implement more of the TLS env in rewrite resolver
---
 .../catalina/valves/rewrite/ResolverImpl.java      | 78 +++++++++++++++++-----
 .../catalina/valves/rewrite/TestResolverSSL.java   | 20 +++---
 2 files changed, 75 insertions(+), 23 deletions(-)

diff --git a/java/org/apache/catalina/valves/rewrite/ResolverImpl.java b/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
index 51566f0..dfa0ebd 100644
--- a/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
+++ b/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
@@ -19,9 +19,15 @@ package org.apache.catalina.valves.rewrite;
 import java.io.IOException;
 import java.nio.charset.Charset;
 import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateParsingException;
 import java.security.cert.X509Certificate;
+import java.util.ArrayList;
 import java.util.Calendar;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
 import java.util.Set;
+import java.util.StringTokenizer;
 import java.util.concurrent.TimeUnit;
 
 import org.apache.catalina.WebResource;
@@ -145,18 +151,22 @@ public class ResolverImpl extends Resolver {
     public String resolveSsl(String key) {
         SSLSupport sslSupport = (SSLSupport) request.getAttribute(SSLSupport.SESSION_MGR);
         try {
-            // FIXME SSL_SESSION_RESUMED in SSLHostConfig
-            // FIXME SSL_SECURE_RENEG in SSLHostConfig
-            // FIXME SSL_COMPRESS_METHOD in SSLHostConfig
-            // FIXME SSL_TLS_SNI from handshake
-            // FIXME SSL_SRP_USER
-            // FIXME SSL_SRP_USERINFO
+            // SSL_SRP_USER: no planned support for SRP
+            // SSL_SRP_USERINFO: no planned support for SRP
             if (key.equals("HTTPS")) {
                 return String.valueOf(sslSupport != null);
             } else if (key.equals("SSL_PROTOCOL")) {
                 return sslSupport.getProtocol();
             } else if (key.equals("SSL_SESSION_ID")) {
                 return sslSupport.getSessionId();
+            } else if (key.equals("SSL_SESSION_RESUMED")) {
+                // FIXME session resumption state, not available anywhere
+            } else if (key.equals("SSL_SECURE_RENEG")) {
+                // FIXME available from SSLHostConfig
+            } else if (key.equals("SSL_COMPRESS_METHOD")) {
+                // FIXME available from SSLHostConfig
+            } else if (key.equals("SSL_TLS_SNI")) {
+                // FIXME from handshake SNI processing
             } else if (key.equals("SSL_CIPHER")) {
                 return sslSupport.getCipherSuite();
             } else if (key.equals("SSL_CIPHER_EXPORT")) {
@@ -188,12 +198,13 @@ public class ResolverImpl extends Resolver {
                     if (result != null) {
                         return result;
                     } else if (key.startsWith("SAN_OTHER_msUPN_")) {
+                        // Type otherName, which is 0
                         key = key.substring("SAN_OTHER_msUPN_".length());
-                        // FIXME return certificates[0].getSubjectAlternativeNames()
+                        // FIXME OID from resolveAlternateName
                     } else if (key.equals("CERT_RFC4523_CEA")) {
-                        // FIXME return certificates[0]
+                        // FIXME return certificate[0] format CertificateExactAssertion in RFC4523
                     } else if (key.equals("VERIFY")) {
-                        // FIXME return verification state
+                        // FIXME return verification state, not available anywhere
                     }
                 }
             } else if (key.startsWith("SSL_SERVER_")) {
@@ -204,8 +215,9 @@ public class ResolverImpl extends Resolver {
                     if (result != null) {
                         return result;
                     } else if (key.startsWith("SAN_OTHER_dnsSRV_")) {
+                        // Type otherName, which is 0
                         key = key.substring("SAN_OTHER_dnsSRV_".length());
-                        // FIXME return certificates[0].getSubjectAlternativeNames()
+                        // FIXME OID from resolveAlternateName
                     }
                 }
             }
@@ -224,18 +236,20 @@ public class ResolverImpl extends Resolver {
             return certificates[0].getSubjectDN().getName();
         } else if (key.startsWith("S_DN_")) {
             key = key.substring("S_DN_".length());
-            // FIXME would need access to X500Name from X500Principal
+            return resolveComponent(certificates[0].getSubjectX500Principal().getName(), key);
         } else if (key.startsWith("SAN_Email_")) {
+            // Type rfc822Name, which is 1
             key = key.substring("SAN_Email_".length());
-            // FIXME return certificates[0].getSubjectAlternativeNames()
+            return resolveAlternateName(certificates[0], 1, Integer.parseInt(key));
         } else if (key.startsWith("SAN_DNS_")) {
+            // Type dNSName, which is 2
             key = key.substring("SAN_DNS_".length());
-            // FIXME return certificates[0].getSubjectAlternativeNames()
+            return resolveAlternateName(certificates[0], 2, Integer.parseInt(key));
         } else if (key.equals("I_DN")) {
             return certificates[0].getIssuerDN().getName();
         } else if (key.startsWith("I_DN_")) {
             key = key.substring("I_DN_".length());
-            // FIXME would need access to X500Name from X500Principal
+            return resolveComponent(certificates[0].getIssuerX500Principal().getName(), key);
         } else if (key.equals("V_START")) {
             return String.valueOf(certificates[0].getNotBefore().getTime());
         } else if (key.equals("V_END")) {
@@ -260,13 +274,47 @@ public class ResolverImpl extends Resolver {
             key = key.substring("CERT_CHAIN_".length());
             try {
                 return toPEM(certificates[Integer.parseInt(key)]);
-            } catch (NumberFormatException | CertificateEncodingException e) {
+            } catch (NumberFormatException | ArrayIndexOutOfBoundsException
+                    | CertificateEncodingException e) {
                 // Ignore
             }
         }
         return null;
     }
 
+    private String resolveComponent(String fullDN, String component) {
+        HashMap<String, String> components = new HashMap<>();
+        StringTokenizer tokenizer = new StringTokenizer(fullDN, ",");
+        while (tokenizer.hasMoreElements()) {
+            String token = tokenizer.nextToken().trim();
+            int pos = token.indexOf("=");
+            if (pos > 0 && (pos + 1) < token.length()) {
+                components.put(token.substring(0, pos), token.substring(pos + 1));
+            }
+        }
+        return components.get(component);
+    }
+
+    private String resolveAlternateName(X509Certificate certificate, int type, int n) {
+        try {
+            Collection<List<?>> alternateNames = certificate.getSubjectAlternativeNames();
+            if (alternateNames != null) {
+                List<String> elements = new ArrayList<>();
+                for (List<?> alternateName : alternateNames) {
+                    Integer alternateNameType = (Integer) alternateName.get(0);
+                    if (alternateNameType.intValue() == type) {
+                        elements.add(String.valueOf(alternateName.get(1)));
+                    }
+                }
+                return elements.get(n);
+            }
+        } catch (NumberFormatException | ArrayIndexOutOfBoundsException
+                | CertificateParsingException e) {
+            // Ignore
+        }
+        return null;
+    }
+
     private String toPEM(X509Certificate certificate) throws CertificateEncodingException {
         StringBuilder result = new StringBuilder();
         result.append("-----BEGIN CERTIFICATE-----");
diff --git a/test/org/apache/catalina/valves/rewrite/TestResolverSSL.java b/test/org/apache/catalina/valves/rewrite/TestResolverSSL.java
index 2930ae5..d4624a3 100644
--- a/test/org/apache/catalina/valves/rewrite/TestResolverSSL.java
+++ b/test/org/apache/catalina/valves/rewrite/TestResolverSSL.java
@@ -68,11 +68,13 @@ public class TestResolverSSL extends TomcatBaseTest {
             "SSL_CLIENT_S_DN_CN", // CN component
             "SSL_CLIENT_S_DN_O", // O component
             "SSL_CLIENT_S_DN_C", // C component
-            "SSL_CLIENT_SAN_Email_n", // FXIME: n
-            "SSL_CLIENT_SAN_DNS_n", // FXIME: n
-            "SSL_CLIENT_SAN_OTHER_msUPN_n", // FXIME: n
+            "SSL_CLIENT_SAN_Email_0",
+            "SSL_CLIENT_SAN_DNS_0",
+            "SSL_CLIENT_SAN_OTHER_msUPN_0",
             "SSL_CLIENT_I_DN",
-            "SSL_CLIENT_I_DN_x509", // FXIME: x509
+            "SSL_CLIENT_I_DN_CN", // CN component
+            "SSL_CLIENT_I_DN_O", // O component
+            "SSL_CLIENT_I_DN_C", // C component
             "SSL_CLIENT_V_START",
             "SSL_CLIENT_V_END",
             "SSL_CLIENT_V_REMAIN",
@@ -85,14 +87,16 @@ public class TestResolverSSL extends TomcatBaseTest {
             "SSL_SERVER_M_VERSION",
             "SSL_SERVER_M_SERIAL",
             "SSL_SERVER_S_DN",
-            "SSL_SERVER_SAN_Email_n", // FXIME: n
-            "SSL_SERVER_SAN_DNS_n", // FXIME: n
-            "SSL_SERVER_SAN_OTHER_dnsSRV_n", // FXIME: n
+            "SSL_SERVER_SAN_Email_0",
+            "SSL_SERVER_SAN_DNS_0",
+            "SSL_SERVER_SAN_OTHER_dnsSRV_0",
             "SSL_SERVER_S_DN_CN", // CN component
             "SSL_SERVER_S_DN_O", // O component
             "SSL_SERVER_S_DN_C", // C component
             "SSL_SERVER_I_DN",
-            "SSL_SERVER_I_DN_x509", // FXIME: x509
+            "SSL_SERVER_I_DN_CN", // CN component
+            "SSL_SERVER_I_DN_O", // O component
+            "SSL_SERVER_I_DN_C", // C component
             "SSL_SERVER_V_START",
             "SSL_SERVER_V_END",
             "SSL_SERVER_A_SIG",


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