From 529421359507a03f9a860d4eae27115e94b5f409 Mon Sep 17 00:00:00 2001 From: isudana Date: Sun, 5 Apr 2026 22:46:07 +0530 Subject: [PATCH] Fix CN issue Co-Authored-By: Claude Sonnet 4.6 --- .../transport/nhttp/HostnameVerifier.java | 43 ++++++------------- .../transport/passthru/HostnameVerifier.java | 43 ++++++------------- 2 files changed, 28 insertions(+), 58 deletions(-) diff --git a/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/HostnameVerifier.java b/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/HostnameVerifier.java index 24abd23a2..a5bb20aea 100644 --- a/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/HostnameVerifier.java +++ b/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/HostnameVerifier.java @@ -18,6 +18,9 @@ */ package org.apache.synapse.transport.nhttp; +import javax.naming.InvalidNameException; +import javax.naming.ldap.LdapName; +import javax.naming.ldap.Rdn; import javax.net.ssl.SSLException; import javax.net.ssl.SSLPeerUnverifiedException; import javax.net.ssl.SSLSession; @@ -504,36 +507,18 @@ public static int countDots(final String s) { class Certificates { public static String[] getCNs(X509Certificate cert) { LinkedList cnList = new LinkedList(); - /* - Sebastian Hauer's original StrictSSLProtocolSocketFactory used - getName() and had the following comment: - - Parses a X.500 distinguished name for the value of the - "Common Name" field. This is done a bit sloppy right - now and should probably be done a bit more according to - RFC 2253. - - I've noticed that toString() seems to do a better job than - getName() on these X500Principal objects, so I'm hoping that - addresses Sebastian's concern. - - For example, getName() gives me this: - 1.2.840.113549.1.9.1=#16166a756c6975736461766965734063756362632e636f6d - - whereas toString() gives me this: - EMAILADDRESS=juliusdavies@cucbc.com - - Looks like toString() even works with non-ascii domain names! - I tested it with "花子.co.jp" and it worked fine. - */ - String subjectPrincipal = cert.getSubjectX500Principal().toString(); - StringTokenizer st = new StringTokenizer(subjectPrincipal, ","); - while (st.hasMoreTokens()) { - String tok = st.nextToken(); - int x = tok.indexOf("CN="); - if (x >= 0) { - cnList.add(tok.substring(x + 3)); + try { + LdapName ldapDN = new LdapName(cert.getSubjectX500Principal().getName()); + for (Rdn rdn : ldapDN.getRdns()) { + if ("CN".equalsIgnoreCase(rdn.getType())) { + Object value = rdn.getValue(); + if (value != null) { + cnList.add(value.toString()); + } + } } + } catch (InvalidNameException e) { + // unparseable DN — no CNs extractable } if (!cnList.isEmpty()) { String[] cns = new String[cnList.size()]; diff --git a/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/passthru/HostnameVerifier.java b/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/passthru/HostnameVerifier.java index 86088299f..96bc6a6c8 100644 --- a/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/passthru/HostnameVerifier.java +++ b/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/passthru/HostnameVerifier.java @@ -51,6 +51,9 @@ package org.apache.synapse.transport.passthru; +import javax.naming.InvalidNameException; +import javax.naming.ldap.LdapName; +import javax.naming.ldap.Rdn; import javax.net.ssl.SSLException; import javax.net.ssl.SSLPeerUnverifiedException; import javax.net.ssl.SSLSession; @@ -506,36 +509,18 @@ public static int countDots(final String s) { class Certificates { public static String[] getCNs(X509Certificate cert) { LinkedList cnList = new LinkedList(); - /* - Sebastian Hauer's original StrictSSLProtocolSocketFactory used - getName() and had the following comment: - - Parses a X.500 distinguished name for the value of the - "Common Name" field. This is done a bit sloppy right - now and should probably be done a bit more according to - RFC 2253. - - I've noticed that toString() seems to do a better job than - getName() on these X500Principal objects, so I'm hoping that - addresses Sebastian's concern. - - For example, getName() gives me this: - 1.2.840.113549.1.9.1=#16166a756c6975736461766965734063756362632e636f6d - - whereas toString() gives me this: - EMAILADDRESS=juliusdavies@cucbc.com - - Looks like toString() even works with non-ascii domain names! - I tested it with "花子.co.jp" and it worked fine. - */ - String subjectPrincipal = cert.getSubjectX500Principal().toString(); - StringTokenizer st = new StringTokenizer(subjectPrincipal, ","); - while (st.hasMoreTokens()) { - String tok = st.nextToken(); - int x = tok.indexOf("CN="); - if (x >= 0) { - cnList.add(tok.substring(x + 3)); + try { + LdapName ldapDN = new LdapName(cert.getSubjectX500Principal().getName()); + for (Rdn rdn : ldapDN.getRdns()) { + if ("CN".equalsIgnoreCase(rdn.getType())) { + Object value = rdn.getValue(); + if (value != null) { + cnList.add(value.toString()); + } + } } + } catch (InvalidNameException e) { + // unparseable DN — no CNs extractable } if (!cnList.isEmpty()) { String[] cns = new String[cnList.size()];