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

markt-asf 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 094c7b0357 Follow-up to parsing improvements
094c7b0357 is described below

commit 094c7b03574e1cd93c8b388ec3b9525039fe614e
Author: Mark Thomas <[email protected]>
AuthorDate: Mon Jul 20 18:07:38 2026 +0100

    Follow-up to parsing improvements
---
 .../catalina/valves/rewrite/ResolverImpl.java      |  5 +-
 .../valves/rewrite/TestResolverSSLComponents.java  | 58 ++++++++++++++++++++++
 webapps/docs/changelog.xml                         |  4 ++
 3 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/java/org/apache/catalina/valves/rewrite/ResolverImpl.java 
b/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
index 59de049a31..e0a1b2dc79 100644
--- a/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
+++ b/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
@@ -283,7 +283,7 @@ public class ResolverImpl extends Resolver {
         } else if (key.equals("M_SERIAL")) {
             return certificates[0].getSerialNumber().toString();
         } else if (key.equals("S_DN")) {
-            return certificates[0].getSubjectX500Principal().toString();
+            return certificates[0].getSubjectX500Principal().getName();
         } else if (key.startsWith("S_DN_")) {
             key = key.substring("S_DN_".length());
             return 
resolveComponent(certificates[0].getSubjectX500Principal().getName(), key);
@@ -299,7 +299,7 @@ public class ResolverImpl extends Resolver {
             return certificates[0].getIssuerX500Principal().getName();
         } else if (key.startsWith("I_DN_")) {
             key = key.substring("I_DN_".length());
-            return 
resolveComponent(certificates[0].getIssuerX500Principal().toString(), key);
+            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")) {
@@ -389,6 +389,7 @@ public class ResolverImpl extends Resolver {
         StringBuilder sb = new StringBuilder(s.length());
         for (int i = 0; i < s.length(); i++) {
             char c = s.charAt(i);
+            // Note: Does not handle hex escapes
             if (c == '\\' && i + 1 < s.length()) {
                 char next = s.charAt(i + 1);
                 sb.append(next);
diff --git 
a/test/org/apache/catalina/valves/rewrite/TestResolverSSLComponents.java 
b/test/org/apache/catalina/valves/rewrite/TestResolverSSLComponents.java
new file mode 100644
index 0000000000..0aa3f60f52
--- /dev/null
+++ b/test/org/apache/catalina/valves/rewrite/TestResolverSSLComponents.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.catalina.valves.rewrite;
+
+import java.io.IOException;
+import java.security.cert.X509Certificate;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.apache.catalina.connector.Request;
+import org.apache.juli.logging.Log;
+import org.apache.tomcat.util.net.SSLSupport;
+import org.easymock.EasyMock;
+
+public class TestResolverSSLComponents {
+
+    @Test
+    public void testEscapedComma() throws Exception {
+        Resolver resolver = createResolver("CN=abc\\,def,OU=xyz");
+
+        Assert.assertEquals("abc,def", 
resolver.resolveSsl("SSL_CLIENT_S_DN_CN"));
+        Assert.assertEquals("xyz", resolver.resolveSsl("SSL_CLIENT_S_DN_OU"));
+    }
+
+
+    private Resolver createResolver(String subjectDn) throws IOException {
+        X509Certificate certificate = 
EasyMock.createMock(X509Certificate.class);
+        
EasyMock.expect(certificate.getSubjectX500Principal()).andStubReturn(new 
X500Principal(subjectDn));
+
+        SSLSupport sslSupport = EasyMock.createMock(SSLSupport.class);
+        
EasyMock.expect(sslSupport.getPeerCertificateChain()).andStubReturn(new 
X509Certificate[] { certificate });
+
+        Request request = EasyMock.createMock(Request.class);
+        
EasyMock.expect(request.getAttribute(SSLSupport.SESSION_MGR)).andStubReturn(sslSupport);
+
+        Log log = EasyMock.createNiceMock(Log.class);
+        EasyMock.replay(certificate, sslSupport, request, log);
+
+        return new ResolverImpl(request, log);
+    }
+}
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index ff03f0def7..eee2f627c0 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -148,6 +148,10 @@
         parent directory name for directory listings produced by the default
         servlet. Ensure XML escaping is used with XML output. (markt)
       </fix>
+      <fix>
+        When processing certificate subject names and issuer names within
+        RewriteValve rules, always use the RFC 2253 format name. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to