summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Carlstrom <bdc@google.com>2012-12-21 14:21:40 -0800
committerPaul Kocialkowski <contact@paulk.fr>2014-11-16 13:52:28 +0100
commit4417e2559ac202e01f9d795970df5319ea31f83d (patch)
treea442ab9da2ecc6c7af518c76c8a2d46052b36af9
parent7687ea60d46816c65832d061780fb5b02e5e4d7a (diff)
downloadlibcore-4417e2559ac202e01f9d795970df5319ea31f83d.zip
libcore-4417e2559ac202e01f9d795970df5319ea31f83d.tar.gz
libcore-4417e2559ac202e01f9d795970df5319ea31f83d.tar.bz2
Should favor last CN when working with distinguished names
Bug: 7894348 Bug: http://code.google.com/p/android/issues/detail?id=41662 Change-Id: I3814d653b628f6af12ce1ba59b39b1c7cc45e124
-rw-r--r--luni/src/main/java/javax/net/ssl/DefaultHostnameVerifier.java3
-rw-r--r--luni/src/main/java/javax/net/ssl/DistinguishedNameParser.java16
-rw-r--r--luni/src/test/java/libcore/javax/net/ssl/DefaultHostnameVerifierTest.java34
-rw-r--r--luni/src/test/java/libcore/javax/net/ssl/DistinguishedNameParserTest.java56
4 files changed, 68 insertions, 41 deletions
diff --git a/luni/src/main/java/javax/net/ssl/DefaultHostnameVerifier.java b/luni/src/main/java/javax/net/ssl/DefaultHostnameVerifier.java
index e68baca..fa11371 100644
--- a/luni/src/main/java/javax/net/ssl/DefaultHostnameVerifier.java
+++ b/luni/src/main/java/javax/net/ssl/DefaultHostnameVerifier.java
@@ -80,7 +80,8 @@ public final class DefaultHostnameVerifier implements HostnameVerifier {
if (!hasDns) {
X500Principal principal = certificate.getSubjectX500Principal();
- String cn = new DistinguishedNameParser(principal).find("cn");
+ // RFC 2818 advises using the most specific name for matching.
+ String cn = new DistinguishedNameParser(principal).findMostSpecific("cn");
if (cn != null) {
return verifyHostName(hostName, cn);
}
diff --git a/luni/src/main/java/javax/net/ssl/DistinguishedNameParser.java b/luni/src/main/java/javax/net/ssl/DistinguishedNameParser.java
index fa8ed1b..6280baa 100644
--- a/luni/src/main/java/javax/net/ssl/DistinguishedNameParser.java
+++ b/luni/src/main/java/javax/net/ssl/DistinguishedNameParser.java
@@ -340,12 +340,12 @@ public final class DistinguishedNameParser {
}
/**
- * Parses the DN and returns the attribute value for an attribute type.
+ * Parses the DN and returns the most significant attribute value
+ * for an attribute type, or null if none found.
*
* @param attributeType attribute type to look for (e.g. "ca")
- * @return value of the attribute that first found, or null if none found
*/
- public String find(String attributeType) {
+ public String findMostSpecific(String attributeType) {
// Initialize internal state.
pos = 0;
beg = 0;
@@ -357,11 +357,15 @@ public final class DistinguishedNameParser {
if (attType == null) {
return null;
}
+ // Values are ordered from least specific to most specific. We
+ // remember the most recent choice in result and return it
+ // when we reach the end of the input.
+ String result = null;
while (true) {
String attValue = "";
if (pos == length) {
- return null;
+ return result;
}
switch (chars[pos]) {
@@ -381,11 +385,11 @@ public final class DistinguishedNameParser {
}
if (attributeType.equalsIgnoreCase(attType)) {
- return attValue;
+ result = attValue;
}
if (pos >= length) {
- return null;
+ return result;
}
if (chars[pos] == ',' || chars[pos] == ';') {
diff --git a/luni/src/test/java/libcore/javax/net/ssl/DefaultHostnameVerifierTest.java b/luni/src/test/java/libcore/javax/net/ssl/DefaultHostnameVerifierTest.java
index 7cb7792..69ae1c1 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/DefaultHostnameVerifierTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/DefaultHostnameVerifierTest.java
@@ -31,7 +31,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import javax.net.ssl.DefaultHostnameVerifier;
-import javax.net.ssl.DistinguishedNameParser;
import javax.security.auth.x500.X500Principal;
import junit.framework.TestCase;
@@ -42,39 +41,6 @@ public final class DefaultHostnameVerifierTest extends TestCase {
private final DefaultHostnameVerifier verifier = new DefaultHostnameVerifier();
- public void testGetFirstCn() {
- assertFirstCn("", null);
- assertFirstCn("ou=xxx", null);
- assertFirstCn("ou=xxx,cn=xxx", "xxx");
- assertFirstCn("ou=xxx+cn=yyy,cn=zzz+cn=abc", "yyy");
- assertFirstCn("cn=a,cn=b", "a");
- assertFirstCn("cn=Cc,cn=Bb,cn=Aa", "Cc");
- assertFirstCn("cn=imap.gmail.com", "imap.gmail.com");
- }
-
- public void testGetFirstCnWithOid() {
- assertFirstCn("2.5.4.3=a,ou=xxx", "a");
- }
-
- public void testGetFirstCnWithQuotedStrings() {
- assertFirstCn("cn=\"\\\" a ,=<>#;\"", "\" a ,=<>#;");
- assertFirstCn("cn=abc\\,def", "abc,def");
- }
-
- public void testGetFirstCnWithUtf8() {
- assertFirstCn("cn=Lu\\C4\\8Di\\C4\\87", "\u004c\u0075\u010d\u0069\u0107");
- }
-
- public void testGetFirstCnWithWhitespace() {
- assertFirstCn("ou=a, cn= a b ,o=x", "a b");
- assertFirstCn("cn=\" a b \" ,o=x", " a b ");
- }
-
- private void assertFirstCn(String dn, String expected) {
- X500Principal principal = new X500Principal(dn);
- assertEquals("dn:" + dn, expected, new DistinguishedNameParser(principal).find("cn"));
- }
-
public void testVerify() {
assertTrue(verifier.verify("imap.g.com", new StubX509Certificate("cn=imap.g.com")));
assertFalse(verifier.verify("imap.g.com", new StubX509Certificate("cn=imap2.g.com")));
diff --git a/luni/src/test/java/libcore/javax/net/ssl/DistinguishedNameParserTest.java b/luni/src/test/java/libcore/javax/net/ssl/DistinguishedNameParserTest.java
new file mode 100644
index 0000000..19430de
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/net/ssl/DistinguishedNameParserTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed 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 libcore.javax.net.ssl;
+
+import javax.net.ssl.DistinguishedNameParser;
+import javax.security.auth.x500.X500Principal;
+import junit.framework.TestCase;
+
+public final class DistinguishedNameParserTest extends TestCase {
+ public void testGetLastCn() {
+ assertLastCn("", null);
+ assertLastCn("ou=xxx", null);
+ assertLastCn("ou=xxx,cn=xxx", "xxx");
+ assertLastCn("ou=xxx+cn=yyy,cn=zzz+cn=abc", "abc");
+ assertLastCn("cn=a,cn=b", "b");
+ assertLastCn("cn=Cc,cn=Bb,cn=Aa", "Aa");
+ assertLastCn("cn=imap.gmail.com", "imap.gmail.com");
+ }
+
+ public void testGetFirstCnWithOid() {
+ assertLastCn("2.5.4.3=a,ou=xxx", "a");
+ }
+
+ public void testGetFirstCnWithQuotedStrings() {
+ assertLastCn("cn=\"\\\" a ,=<>#;\"", "\" a ,=<>#;");
+ assertLastCn("cn=abc\\,def", "abc,def");
+ }
+
+ public void testGetFirstCnWithUtf8() {
+ assertLastCn("cn=Lu\\C4\\8Di\\C4\\87", "\u004c\u0075\u010d\u0069\u0107");
+ }
+
+ public void testGetFirstCnWithWhitespace() {
+ assertLastCn("ou=a, cn= a b ,o=x", "a b");
+ assertLastCn("cn=\" a b \" ,o=x", " a b ");
+ }
+
+ private void assertLastCn(String dn, String expected) {
+ X500Principal principal = new X500Principal(dn);
+ assertEquals(dn, expected, new DistinguishedNameParser(principal).findMostSpecific("cn"));
+ }
+}