Skip to content

Commit 6e14fc1

Browse files
committed
Fixed CN extraction from DN of X500 principal
git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1411702 13f79535-47bb-0310-9956-ffa450edef68
1 parent 5295414 commit 6e14fc1

File tree

2 files changed

+24
-7
lines changed

2 files changed

+24
-7
lines changed

httpclient/src/main/java/org/apache/http/conn/ssl/AbstractVerifier.java

+8-6
Original file line numberDiff line numberDiff line change
@@ -178,12 +178,12 @@ public final void verify(final String host, final String[] cns,
178178

179179
// We're can be case-insensitive when comparing the host we used to
180180
// establish the socket to the hostname in the certificate.
181-
String hostName = host.trim().toLowerCase(Locale.ENGLISH);
181+
String hostName = host.trim().toLowerCase(Locale.US);
182182
boolean match = false;
183183
for(Iterator<String> it = names.iterator(); it.hasNext();) {
184184
// Don't trim the CN, though!
185185
String cn = it.next();
186-
cn = cn.toLowerCase(Locale.ENGLISH);
186+
cn = cn.toLowerCase(Locale.US);
187187
// Store CN in StringBuilder in case we need to report an error.
188188
buf.append(" <");
189189
buf.append(cn);
@@ -260,13 +260,15 @@ whereas toString() gives me this:
260260
Looks like toString() even works with non-ascii domain names!
261261
I tested it with "&#x82b1;&#x5b50;.co.jp" and it worked fine.
262262
*/
263+
263264
String subjectPrincipal = cert.getSubjectX500Principal().toString();
264265
StringTokenizer st = new StringTokenizer(subjectPrincipal, ",");
265266
while(st.hasMoreTokens()) {
266-
String tok = st.nextToken();
267-
int x = tok.indexOf("CN=");
268-
if(x >= 0) {
269-
cnList.add(tok.substring(x + 3));
267+
String tok = st.nextToken().trim();
268+
if (tok.length() > 3) {
269+
if (tok.substring(0, 3).equalsIgnoreCase("CN=")) {
270+
cnList.add(tok.substring(3));
271+
}
270272
}
271273
}
272274
if(!cnList.isEmpty()) {

httpclient/src/test/java/org/apache/http/conn/ssl/TestHostnameVerifier.java

+16-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
import java.io.ByteArrayInputStream;
3131
import java.io.InputStream;
32+
import java.security.Principal;
3233
import java.security.cert.CertificateFactory;
3334
import java.security.cert.X509Certificate;
3435
import java.util.Arrays;
@@ -37,6 +38,7 @@
3738

3839
import org.junit.Assert;
3940
import org.junit.Test;
41+
import org.mockito.Mockito;
4042

4143
/**
4244
* Unit tests for {@link X509HostnameVerifier}.
@@ -336,7 +338,7 @@ private void checkWildcard(String host, boolean isOK) {
336338

337339
@Test
338340
// Various checks of 2TLDs
339-
public void testacceptableCountryWildcards() {
341+
public void testAcceptableCountryWildcards() {
340342
checkWildcard("*.co.org", true); // Not a 2 character TLD
341343
checkWildcard("s*.co.org", true); // Not a 2 character TLD
342344
checkWildcard("*.co.uk", false); // 2 character TLD, invalid 2TLD
@@ -345,4 +347,17 @@ public void testacceptableCountryWildcards() {
345347
checkWildcard("*.a.co.uk", true); // 2 character TLD, invalid 2TLD, but using subdomain
346348
checkWildcard("s*.a.co.uk", true); // 2 character TLD, invalid 2TLD, but using subdomain
347349
}
350+
351+
public void testGetCNs() {
352+
Principal principal = Mockito.mock(Principal.class);
353+
X509Certificate cert = Mockito.mock(X509Certificate.class);
354+
Mockito.when(cert.getSubjectDN()).thenReturn(principal);
355+
Mockito.when(principal.toString()).thenReturn("bla, bla, blah");
356+
Assert.assertArrayEquals(new String[] {}, AbstractVerifier.getCNs(cert));
357+
Mockito.when(principal.toString()).thenReturn("Cn=, Cn= , CN, OU=CN=");
358+
Assert.assertArrayEquals(new String[] {}, AbstractVerifier.getCNs(cert));
359+
Mockito.when(principal.toString()).thenReturn(" Cn=blah, CN= blah , OU=CN=yada");
360+
Assert.assertArrayEquals(new String[] {"blah", " blah"}, AbstractVerifier.getCNs(cert));
361+
}
362+
348363
}

0 commit comments

Comments
 (0)