summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenny Root <kroot@google.com>2013-05-06 15:13:56 -0700
committerAndroid Git Automerger <android-git-automerger@android.com>2013-05-06 15:13:56 -0700
commit6c52dfedcb0d303b89672d3cb132346bd183f486 (patch)
tree60f013e108912a7ca8409ac21665945ce50b6e77
parentc3c970df63201c5807fc9a6ee64e5912533f0c73 (diff)
parentab4ab99b79b10a157ab313e57dc2d243ebb5cdcf (diff)
downloadlibcore-6c52dfedcb0d303b89672d3cb132346bd183f486.zip
libcore-6c52dfedcb0d303b89672d3cb132346bd183f486.tar.gz
libcore-6c52dfedcb0d303b89672d3cb132346bd183f486.tar.bz2
am ab4ab99b: Merge "NativeCrypto: remove dep on Android host verifier"
* commit 'ab4ab99b79b10a157ab313e57dc2d243ebb5cdcf': NativeCrypto: remove dep on Android host verifier
-rw-r--r--crypto/src/main/java/org/conscrypt/CertPinManager.java51
1 files changed, 48 insertions, 3 deletions
diff --git a/crypto/src/main/java/org/conscrypt/CertPinManager.java b/crypto/src/main/java/org/conscrypt/CertPinManager.java
index df0cb8f..22578fc 100644
--- a/crypto/src/main/java/org/conscrypt/CertPinManager.java
+++ b/crypto/src/main/java/org/conscrypt/CertPinManager.java
@@ -22,8 +22,8 @@ import java.io.IOException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
-import javax.net.ssl.DefaultHostnameVerifier;
import libcore.io.IoUtils;
import libcore.util.BasicLruCache;
@@ -36,7 +36,6 @@ public class CertPinManager {
private final Map<String, PinListEntry> entries = new HashMap<String, PinListEntry>();
private final BasicLruCache<String, String> hostnameCache = new BasicLruCache<String, String>(10);
- private final DefaultHostnameVerifier verifier = new DefaultHostnameVerifier();
private boolean initialized = false;
private static final boolean DEBUG = false;
@@ -166,13 +165,59 @@ public class CertPinManager {
continue;
}
// now verify that the CN matches at all
- if (verifier.verifyHostName(hostname, cn)) {
+ if (isHostnameMatchedBy(hostname, cn)) {
bestMatch = cn;
}
}
return bestMatch;
}
+ /**
+ * Returns true if {@code hostName} matches the name or pattern {@code cn}.
+ *
+ * @param hostName lowercase host name.
+ * @param cn certificate host name. May include wildcards like
+ * {@code *.android.com}.
+ */
+ private static boolean isHostnameMatchedBy(String hostName, String cn) {
+ if (hostName == null || hostName.isEmpty() || cn == null || cn.isEmpty()) {
+ return false;
+ }
+
+ cn = cn.toLowerCase(Locale.US);
+
+ if (!cn.contains("*")) {
+ return hostName.equals(cn);
+ }
+
+ if (cn.startsWith("*.") && hostName.regionMatches(0, cn, 2, cn.length() - 2)) {
+ return true; // "*.foo.com" matches "foo.com"
+ }
+
+ int asterisk = cn.indexOf('*');
+ int dot = cn.indexOf('.');
+ if (asterisk > dot) {
+ return false; // malformed; wildcard must be in the first part of
+ // the cn
+ }
+
+ if (!hostName.regionMatches(0, cn, 0, asterisk)) {
+ return false; // prefix before '*' doesn't match
+ }
+
+ int suffixLength = cn.length() - (asterisk + 1);
+ int suffixStart = hostName.length() - suffixLength;
+ if (hostName.indexOf('.', asterisk) < suffixStart) {
+ return false; // wildcard '*' can't match a '.'
+ }
+
+ if (!hostName.regionMatches(suffixStart, cn, asterisk + 1, suffixLength)) {
+ return false; // suffix after '*' doesn't match
+ }
+
+ return true;
+ }
+
private static void log(String s, Exception e) {
if (DEBUG) {
System.out.println("PINFILE: " + s);