diff options
author | Kenny Root <kroot@google.com> | 2013-05-06 15:13:56 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2013-05-06 15:13:56 -0700 |
commit | 6c52dfedcb0d303b89672d3cb132346bd183f486 (patch) | |
tree | 60f013e108912a7ca8409ac21665945ce50b6e77 | |
parent | c3c970df63201c5807fc9a6ee64e5912533f0c73 (diff) | |
parent | ab4ab99b79b10a157ab313e57dc2d243ebb5cdcf (diff) | |
download | libcore-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.java | 51 |
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); |