diff --git a/common/java/com/android/common/DNParser.java b/common/java/com/android/common/DNParser.java
new file mode 100644
index 0000000..32d57c0
--- /dev/null
+++ b/common/java/com/android/common/DNParser.java
@@ -0,0 +1,447 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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 com.android.common;
+
+import android.util.Log;
+
+import java.io.IOException;
+
+import javax.security.auth.x500.X500Principal;
+
+/**
+ * A simple distinguished name(DN) parser.
+ *
+ * <p>This class is based on org.apache.harmony.security.x509.DNParser.  It's customized to remove
+ * external references which are unnecessary for our requirements.
+ *
+ * <p>This class is only meant for extracting a string value from a DN.  e.g. it doesn't support
+ * values in the hex-string style.
+ *
+ * <p>This class is used by {@link DomainNameValidator} only.  However, in order to make this
+ * class visible from unit tests, it's made public.
+ */
+public final class DNParser {
+    private static final String TAG = "DNParser";
+
+    /** DN to be parsed. */
+    private final String dn;
+
+    // length of distinguished name string
+    private final int length;
+
+    private int pos, beg, end;
+
+    // tmp vars to store positions of the currently parsed item
+    private int cur;
+
+    // distinguished name chars
+    private char[] chars;
+
+    /**
+     * Exception message thrown when we failed to parse DN, which shouldn't happen because we
+     * only handle DNs that {@link X500Principal#getName} returns, which shouldn't be malformed.
+     */
+    private static final String ERROR_PARSE_ERROR = "Failed to parse DN";
+
+    /**
+     * Constructor.
+     *
+     * @param principal - {@link X500Principal} to be parsed
+     */
+    public DNParser(X500Principal principal) {
+        this.dn = principal.getName(X500Principal.RFC2253);
+        this.length = dn.length();
+    }
+
+    // gets next attribute type: (ALPHA 1*keychar) / oid
+    private String nextAT() throws IOException {
+
+        // skip preceding space chars, they can present after
+        // comma or semicolon (compatibility with RFC 1779)
+        for (; pos < length && chars[pos] == ' '; pos++) {
+        }
+        if (pos == length) {
+            return null; // reached the end of DN
+        }
+
+        // mark the beginning of attribute type
+        beg = pos;
+
+        // attribute type chars
+        pos++;
+        for (; pos < length && chars[pos] != '=' && chars[pos] != ' '; pos++) {
+            // we don't follow exact BNF syntax here:
+            // accept any char except space and '='
+        }
+        if (pos >= length) {
+            // unexpected end of DN
+            throw new IOException(ERROR_PARSE_ERROR);
+        }
+
+        // mark the end of attribute type
+        end = pos;
+
+        // skip trailing space chars between attribute type and '='
+        // (compatibility with RFC 1779)
+        if (chars[pos] == ' ') {
+            for (; pos < length && chars[pos] != '=' && chars[pos] == ' '; pos++) {
+            }
+
+            if (chars[pos] != '=' || pos == length) {
+                // unexpected end of DN
+                throw new IOException(ERROR_PARSE_ERROR);
+            }
+        }
+
+        pos++; //skip '=' char
+
+        // skip space chars between '=' and attribute value
+        // (compatibility with RFC 1779)
+        for (; pos < length && chars[pos] == ' '; pos++) {
+        }
+
+        // in case of oid attribute type skip its prefix: "oid." or "OID."
+        // (compatibility with RFC 1779)
+        if ((end - beg > 4) && (chars[beg + 3] == '.')
+                && (chars[beg] == 'O' || chars[beg] == 'o')
+                && (chars[beg + 1] == 'I' || chars[beg + 1] == 'i')
+                && (chars[beg + 2] == 'D' || chars[beg + 2] == 'd')) {
+            beg += 4;
+        }
+
+        return new String(chars, beg, end - beg);
+    }
+
+    // gets quoted attribute value: QUOTATION *( quotechar / pair ) QUOTATION
+    private String quotedAV() throws IOException {
+
+        pos++;
+        beg = pos;
+        end = beg;
+        while (true) {
+
+            if (pos == length) {
+                // unexpected end of DN
+                throw new IOException(ERROR_PARSE_ERROR);
+            }
+
+            if (chars[pos] == '"') {
+                // enclosing quotation was found
+                pos++;
+                break;
+            } else if (chars[pos] == '\\') {
+                chars[end] = getEscaped();
+            } else {
+                // shift char: required for string with escaped chars
+                chars[end] = chars[pos];
+            }
+            pos++;
+            end++;
+        }
+
+        // skip trailing space chars before comma or semicolon.
+        // (compatibility with RFC 1779)
+        for (; pos < length && chars[pos] == ' '; pos++) {
+        }
+
+        return new String(chars, beg, end - beg);
+    }
+
+    // gets hex string attribute value: "#" hexstring
+    private String hexAV() throws IOException {
+
+        if (pos + 4 >= length) {
+            // encoded byte array  must be not less then 4 c
+            throw new IOException(ERROR_PARSE_ERROR);
+        }
+
+        beg = pos; // store '#' position
+        pos++;
+        while (true) {
+
+            // check for end of attribute value
+            // looks for space and component separators
+            if (pos == length || chars[pos] == '+' || chars[pos] == ','
+                    || chars[pos] == ';') {
+                end = pos;
+                break;
+            }
+
+            if (chars[pos] == ' ') {
+                end = pos;
+                pos++;
+                // skip trailing space chars before comma or semicolon.
+                // (compatibility with RFC 1779)
+                for (; pos < length && chars[pos] == ' '; pos++) {
+                }
+                break;
+            } else if (chars[pos] >= 'A' && chars[pos] <= 'F') {
+                chars[pos] += 32; //to low case
+            }
+
+            pos++;
+        }
+
+        // verify length of hex string
+        // encoded byte array  must be not less then 4 and must be even number
+        int hexLen = end - beg; // skip first '#' char
+        if (hexLen < 5 || (hexLen & 1) == 0) {
+            throw new IOException(ERROR_PARSE_ERROR);
+        }
+
+        // get byte encoding from string representation
+        byte[] encoded = new byte[hexLen / 2];
+        for (int i = 0, p = beg + 1; i < encoded.length; p += 2, i++) {
+            encoded[i] = (byte) getByte(p);
+        }
+
+        return new String(chars, beg, hexLen);
+    }
+
+    // gets string attribute value: *( stringchar / pair )
+    private String escapedAV() throws IOException {
+
+        beg = pos;
+        end = pos;
+        while (true) {
+
+            if (pos >= length) {
+                // the end of DN has been found
+                return new String(chars, beg, end - beg);
+            }
+
+            switch (chars[pos]) {
+            case '+':
+            case ',':
+            case ';':
+                // separator char has beed found
+                return new String(chars, beg, end - beg);
+            case '\\':
+                // escaped char
+                chars[end++] = getEscaped();
+                pos++;
+                break;
+            case ' ':
+                // need to figure out whether space defines
+                // the end of attribute value or not
+                cur = end;
+
+                pos++;
+                chars[end++] = ' ';
+
+                for (; pos < length && chars[pos] == ' '; pos++) {
+                    chars[end++] = ' ';
+                }
+                if (pos == length || chars[pos] == ',' || chars[pos] == '+'
+                        || chars[pos] == ';') {
+                    // separator char or the end of DN has beed found
+                    return new String(chars, beg, cur - beg);
+                }
+                break;
+            default:
+                chars[end++] = chars[pos];
+                pos++;
+            }
+        }
+    }
+
+    // returns escaped char
+    private char getEscaped() throws IOException {
+
+        pos++;
+        if (pos == length) {
+            throw new IOException(ERROR_PARSE_ERROR);
+        }
+
+        switch (chars[pos]) {
+        case '"':
+        case '\\':
+        case ',':
+        case '=':
+        case '+':
+        case '<':
+        case '>':
+        case '#':
+        case ';':
+        case ' ':
+        case '*':
+        case '%':
+        case '_':
+            //FIXME: escaping is allowed only for leading or trailing space char
+            return chars[pos];
+        default:
+            // RFC doesn't explicitly say that escaped hex pair is
+            // interpreted as UTF-8 char. It only contains an example of such DN.
+            return getUTF8();
+        }
+    }
+
+    // decodes UTF-8 char
+    // see http://www.unicode.org for UTF-8 bit distribution table
+    private char getUTF8() throws IOException {
+
+        int res = getByte(pos);
+        pos++; //FIXME tmp
+
+        if (res < 128) { // one byte: 0-7F
+            return (char) res;
+        } else if (res >= 192 && res <= 247) {
+
+            int count;
+            if (res <= 223) { // two bytes: C0-DF
+                count = 1;
+                res = res & 0x1F;
+            } else if (res <= 239) { // three bytes: E0-EF
+                count = 2;
+                res = res & 0x0F;
+            } else { // four bytes: F0-F7
+                count = 3;
+                res = res & 0x07;
+            }
+
+            int b;
+            for (int i = 0; i < count; i++) {
+                pos++;
+                if (pos == length || chars[pos] != '\\') {
+                    return 0x3F; //FIXME failed to decode UTF-8 char - return '?'
+                }
+                pos++;
+
+                b = getByte(pos);
+                pos++; //FIXME tmp
+                if ((b & 0xC0) != 0x80) {
+                    return 0x3F; //FIXME failed to decode UTF-8 char - return '?'
+                }
+
+                res = (res << 6) + (b & 0x3F);
+            }
+            return (char) res;
+        } else {
+            return 0x3F; //FIXME failed to decode UTF-8 char - return '?'
+        }
+    }
+
+    // Returns byte representation of a char pair
+    // The char pair is composed of DN char in
+    // specified 'position' and the next char
+    // According to BNF syntax:
+    // hexchar    = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
+    //                    / "a" / "b" / "c" / "d" / "e" / "f"
+    private int getByte(int position) throws IOException {
+
+        if ((position + 1) >= length) {
+            // to avoid ArrayIndexOutOfBoundsException
+            throw new IOException(ERROR_PARSE_ERROR);
+        }
+
+        int b1, b2;
+
+        b1 = chars[position];
+        if (b1 >= '0' && b1 <= '9') {
+            b1 = b1 - '0';
+        } else if (b1 >= 'a' && b1 <= 'f') {
+            b1 = b1 - 87; // 87 = 'a' - 10
+        } else if (b1 >= 'A' && b1 <= 'F') {
+            b1 = b1 - 55; // 55 = 'A' - 10
+        } else {
+            throw new IOException(ERROR_PARSE_ERROR);
+        }
+
+        b2 = chars[position + 1];
+        if (b2 >= '0' && b2 <= '9') {
+            b2 = b2 - '0';
+        } else if (b2 >= 'a' && b2 <= 'f') {
+            b2 = b2 - 87; // 87 = 'a' - 10
+        } else if (b2 >= 'A' && b2 <= 'F') {
+            b2 = b2 - 55; // 55 = 'A' - 10
+        } else {
+            throw new IOException(ERROR_PARSE_ERROR);
+        }
+
+        return (b1 << 4) + b2;
+    }
+
+    /**
+     * Parses the DN and returns the attribute value for an attribute type.
+     *
+     * @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) {
+        try {
+            // Initialize internal state.
+            pos = 0;
+            beg = 0;
+            end = 0;
+            cur = 0;
+            chars = dn.toCharArray();
+
+            String attType = nextAT();
+            if (attType == null) {
+                return null;
+            }
+            while (true) {
+                String attValue = "";
+
+                if (pos == length) {
+                    return null;
+                }
+
+                switch (chars[pos]) {
+                case '"':
+                    attValue = quotedAV();
+                    break;
+                case '#':
+                    attValue = hexAV();
+                    break;
+                case '+':
+                case ',':
+                case ';': // compatibility with RFC 1779: semicolon can separate RDNs
+                    //empty attribute value
+                    break;
+                default:
+                    attValue = escapedAV();
+                }
+
+                if (attributeType.equalsIgnoreCase(attType)) {
+                    return attValue;
+                }
+
+                if (pos >= length) {
+                    return null;
+                }
+
+                if (chars[pos] == ',' || chars[pos] == ';') {
+                } else if (chars[pos] != '+') {
+                    throw new IOException(ERROR_PARSE_ERROR);
+                }
+
+                pos++;
+                attType = nextAT();
+                if (attType == null) {
+                    throw new IOException(ERROR_PARSE_ERROR);
+                }
+            }
+        } catch (IOException e) {
+            // Parse error shouldn't happen, because we only handle DNs that
+            // X500Principal.getName() returns, which shouldn't be malformed.
+            Log.e(TAG, "Failed to parse DN: " + dn);
+            return null;
+        }
+    }
+}
diff --git a/common/java/com/android/common/DomainNameValidator.java b/common/java/com/android/common/DomainNameValidator.java
new file mode 100644
index 0000000..ad44a7d
--- /dev/null
+++ b/common/java/com/android/common/DomainNameValidator.java
@@ -0,0 +1,281 @@
+/*
+ * 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 com.android.common;
+
+import android.util.Config;
+import android.util.Log;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import javax.security.auth.x500.X500Principal;
+
+public class DomainNameValidator {
+    private final static String TAG = "DomainNameValidator";
+
+    private static final boolean DEBUG = false;
+    private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
+
+    private static Pattern QUICK_IP_PATTERN;
+    static {
+        try {
+            QUICK_IP_PATTERN = Pattern.compile("^[a-f0-9\\.:]+$");
+        } catch (PatternSyntaxException e) {}
+    }
+
+    private static final int ALT_DNS_NAME = 2;
+    private static final int ALT_IPA_NAME = 7;
+
+    /**
+     * Checks the site certificate against the domain name of the site being visited
+     * @param certificate The certificate to check
+     * @param thisDomain The domain name of the site being visited
+     * @return True iff if there is a domain match as specified by RFC2818
+     */
+    public static boolean match(X509Certificate certificate, String thisDomain) {
+        if (certificate == null || thisDomain == null || thisDomain.length() == 0) {
+            return false;
+        }
+
+        thisDomain = thisDomain.toLowerCase();
+        if (!isIpAddress(thisDomain)) {
+            return matchDns(certificate, thisDomain);
+        } else {
+            return matchIpAddress(certificate, thisDomain);
+        }
+    }
+
+    /**
+     * @return True iff the domain name is specified as an IP address
+     */
+    private static boolean isIpAddress(String domain) {
+        boolean rval = (domain != null && domain.length() != 0);
+        if (rval) {
+            try {
+                // do a quick-dirty IP match first to avoid DNS lookup
+                rval = QUICK_IP_PATTERN.matcher(domain).matches();
+                if (rval) {
+                    rval = domain.equals(
+                        InetAddress.getByName(domain).getHostAddress());
+                }
+            } catch (UnknownHostException e) {
+                String errorMessage = e.getMessage();
+                if (errorMessage == null) {
+                  errorMessage = "unknown host exception";
+                }
+
+                if (LOG_ENABLED) {
+                    Log.v(TAG, "DomainNameValidator.isIpAddress(): " + errorMessage);
+                }
+
+                rval = false;
+            }
+        }
+
+        return rval;
+    }
+
+    /**
+     * Checks the site certificate against the IP domain name of the site being visited
+     * @param certificate The certificate to check
+     * @param thisDomain The DNS domain name of the site being visited
+     * @return True iff if there is a domain match as specified by RFC2818
+     */
+    private static boolean matchIpAddress(X509Certificate certificate, String thisDomain) {
+        if (LOG_ENABLED) {
+            Log.v(TAG, "DomainNameValidator.matchIpAddress(): this domain: " + thisDomain);
+        }
+
+        try {
+            Collection subjectAltNames = certificate.getSubjectAlternativeNames();
+            if (subjectAltNames != null) {
+                Iterator i = subjectAltNames.iterator();
+                while (i.hasNext()) {
+                    List altNameEntry = (List)(i.next());
+                    if (altNameEntry != null && 2 <= altNameEntry.size()) {
+                        Integer altNameType = (Integer)(altNameEntry.get(0));
+                        if (altNameType != null) {
+                            if (altNameType.intValue() == ALT_IPA_NAME) {
+                                String altName = (String)(altNameEntry.get(1));
+                                if (altName != null) {
+                                    if (LOG_ENABLED) {
+                                        Log.v(TAG, "alternative IP: " + altName);
+                                    }
+                                    if (thisDomain.equalsIgnoreCase(altName)) {
+                                        return true;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        } catch (CertificateParsingException e) {}
+
+        return false;
+    }
+
+    /**
+     * Checks the site certificate against the DNS domain name of the site being visited
+     * @param certificate The certificate to check
+     * @param thisDomain The DNS domain name of the site being visited
+     * @return True iff if there is a domain match as specified by RFC2818
+     */
+    private static boolean matchDns(X509Certificate certificate, String thisDomain) {
+        boolean hasDns = false;
+        try {
+            Collection subjectAltNames = certificate.getSubjectAlternativeNames();
+            if (subjectAltNames != null) {
+                Iterator i = subjectAltNames.iterator();
+                while (i.hasNext()) {
+                    List altNameEntry = (List)(i.next());
+                    if (altNameEntry != null && 2 <= altNameEntry.size()) {
+                        Integer altNameType = (Integer)(altNameEntry.get(0));
+                        if (altNameType != null) {
+                            if (altNameType.intValue() == ALT_DNS_NAME) {
+                                hasDns = true;
+                                String altName = (String)(altNameEntry.get(1));
+                                if (altName != null) {
+                                    if (matchDns(thisDomain, altName)) {
+                                        return true;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        } catch (CertificateParsingException e) {
+            // one way we can get here is if an alternative name starts with
+            // '*' character, which is contrary to one interpretation of the
+            // spec (a valid DNS name must start with a letter); there is no
+            // good way around this, and in order to be compatible we proceed
+            // to check the common name (ie, ignore alternative names)
+            if (LOG_ENABLED) {
+                String errorMessage = e.getMessage();
+                if (errorMessage == null) {
+                    errorMessage = "failed to parse certificate";
+                }
+
+                Log.v(TAG, "DomainNameValidator.matchDns(): " + errorMessage);
+            }
+        }
+
+        if (!hasDns) {
+            final String cn = new DNParser(certificate.getSubjectX500Principal())
+                    .find("cn");
+            if (LOG_ENABLED) {
+                Log.v(TAG, "Validating subject: DN:"
+                        + certificate.getSubjectX500Principal().getName(X500Principal.CANONICAL)
+                        + "  CN:" + cn);
+            }
+            if (cn != null) {
+                return matchDns(thisDomain, cn);
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * @param thisDomain The domain name of the site being visited
+     * @param thatDomain The domain name from the certificate
+     * @return True iff thisDomain matches thatDomain as specified by RFC2818
+     */
+    // not private for testing
+    public static boolean matchDns(String thisDomain, String thatDomain) {
+        if (LOG_ENABLED) {
+            Log.v(TAG, "DomainNameValidator.matchDns():" +
+                      " this domain: " + thisDomain +
+                      " that domain: " + thatDomain);
+        }
+
+        if (thisDomain == null || thisDomain.length() == 0 ||
+            thatDomain == null || thatDomain.length() == 0) {
+            return false;
+        }
+
+        thatDomain = thatDomain.toLowerCase();
+
+        // (a) domain name strings are equal, ignoring case: X matches X
+        boolean rval = thisDomain.equals(thatDomain);
+        if (!rval) {
+            String[] thisDomainTokens = thisDomain.split("\\.");
+            String[] thatDomainTokens = thatDomain.split("\\.");
+
+            int thisDomainTokensNum = thisDomainTokens.length;
+            int thatDomainTokensNum = thatDomainTokens.length;
+
+            // (b) OR thatHost is a '.'-suffix of thisHost: Z.Y.X matches X
+            if (thisDomainTokensNum >= thatDomainTokensNum) {
+                for (int i = thatDomainTokensNum - 1; i >= 0; --i) {
+                    rval = thisDomainTokens[i].equals(thatDomainTokens[i]);
+                    if (!rval) {
+                        // (c) OR we have a special *-match:
+                        // *.Y.X matches Z.Y.X but *.X doesn't match Z.Y.X
+                        rval = (i == 0 && thisDomainTokensNum == thatDomainTokensNum);
+                        if (rval) {
+                            rval = thatDomainTokens[0].equals("*");
+                            if (!rval) {
+                                // (d) OR we have a *-component match:
+                                // f*.com matches foo.com but not bar.com
+                                rval = domainTokenMatch(
+                                    thisDomainTokens[0], thatDomainTokens[0]);
+                            }
+                        }
+                        break;
+                    }
+                }
+            } else {
+              // (e) OR thatHost has a '*.'-prefix of thisHost:
+              // *.Y.X matches Y.X
+              rval = thatDomain.equals("*." + thisDomain);
+            }
+        }
+
+        return rval;
+    }
+
+    /**
+     * @param thisDomainToken The domain token from the current domain name
+     * @param thatDomainToken The domain token from the certificate
+     * @return True iff thisDomainToken matches thatDomainToken, using the
+     * wildcard match as specified by RFC2818-3.1. For example, f*.com must
+     * match foo.com but not bar.com
+     */
+    private static boolean domainTokenMatch(String thisDomainToken, String thatDomainToken) {
+        if (thisDomainToken != null && thatDomainToken != null) {
+            int starIndex = thatDomainToken.indexOf('*');
+            if (starIndex >= 0) {
+                if (thatDomainToken.length() - 1 <= thisDomainToken.length()) {
+                    String prefix = thatDomainToken.substring(0,  starIndex);
+                    String suffix = thatDomainToken.substring(starIndex + 1);
+
+                    return thisDomainToken.startsWith(prefix) && thisDomainToken.endsWith(suffix);
+                }
+            }
+        }
+
+        return false;
+    }
+}
diff --git a/common/java/com/android/common/Patterns.java b/common/java/com/android/common/Patterns.java
index 2eab3e1..24a18c0 100644
--- a/common/java/com/android/common/Patterns.java
+++ b/common/java/com/android/common/Patterns.java
@@ -122,7 +122,7 @@
 
     public static final Pattern EMAIL_ADDRESS
         = Pattern.compile(
-            "[a-zA-Z0-9\\+\\.\\_\\%\\-]{1,256}" +
+            "[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]{1,256}" +
             "\\@" +
             "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" +
             "(" +
diff --git a/common/tests/src/com/android/common/DNParserTest.java b/common/tests/src/com/android/common/DNParserTest.java
new file mode 100644
index 0000000..34b140a
--- /dev/null
+++ b/common/tests/src/com/android/common/DNParserTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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 com.android.common;
+
+import javax.security.auth.x500.X500Principal;
+
+import junit.framework.TestCase;
+
+public class DNParserTest extends TestCase {
+    public void testFind() {
+        checkFind("", "cn", null);
+        checkFind("ou=xxx", "cn", null);
+        checkFind("ou=xxx,cn=xxx", "cn", "xxx");
+        checkFind("ou=xxx+cn=yyy,cn=zzz+cn=abc", "cn", "yyy");
+        checkFind("2.5.4.3=a,ou=xxx", "cn", "a"); // OID
+        checkFind("cn=a,cn=b", "cn", "a");
+        checkFind("ou=Cc,ou=Bb,ou=Aa", "ou", "Cc");
+        checkFind("cn=imap.gmail.com", "cn", "imap.gmail.com");
+
+        // Quoted string (see http://www.ietf.org/rfc/rfc2253.txt)
+        checkFind("o=\"\\\" a ,=<>#;\"", "o", "\" a ,=<>#;");
+        checkFind("o=abc\\,def", "o", "abc,def");
+
+        // UTF-8 (example in rfc 2253)
+        checkFind("cn=Lu\\C4\\8Di\\C4\\87", "cn", "\u004c\u0075\u010d\u0069\u0107");
+
+        // whitespaces
+        checkFind("ou=a, o=  a  b  ,cn=x", "o", "a  b");
+        checkFind("o=\"  a  b  \" ,cn=x", "o", "  a  b  ");
+    }
+
+    private void checkFind(String dn, String attrType, String expected) {
+        String actual = new DNParser(new X500Principal(dn)).find(attrType);
+        assertEquals("dn:" + dn + "  attr:" + attrType, expected, actual);
+    }
+}
diff --git a/common/tests/src/com/android/common/DomainNameValidatorTest.java b/common/tests/src/com/android/common/DomainNameValidatorTest.java
new file mode 100644
index 0000000..4fdd4cd
--- /dev/null
+++ b/common/tests/src/com/android/common/DomainNameValidatorTest.java
@@ -0,0 +1,336 @@
+/*
+ * 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 com.android.common;
+
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import javax.security.auth.x500.X500Principal;
+
+import junit.framework.TestCase;
+
+public class DomainNameValidatorTest extends TestCase {
+    private static final int ALT_UNKNOWN = 0;
+    private static final int ALT_DNS_NAME = 2;
+    private static final int ALT_IPA_NAME = 7;
+
+    /**
+     * Tests {@link DomainNameValidator#match}
+     */
+    public void testMatch() {
+        // TODO Use actual X509Certificate objects, instead of StubX509Certificate.
+        // Comment in DomainNameValidator suggests X509Certificate fails to parse a certificate
+        // if subject alternative names contain a domain name that begins with '*'.
+        // This test won't cover this kind of errors.
+
+        checkMatch("11", new StubX509Certificate("cn=imap.g.com"), "imap.g.com", true);
+        checkMatch("12", new StubX509Certificate("cn=imap2.g.com"), "imap.g.com", false);
+        checkMatch("13", new StubX509Certificate("cn=sub.imap.g.com"), "imap.g.com", false);
+
+        // If a subjectAltName extension of type dNSName is present, that MUST
+        // be used as the identity
+        checkMatch("21", new StubX509Certificate("")
+                .addSubjectAlternativeName(ALT_DNS_NAME, "a.y.com")
+                , "imap.g.com", false);
+        checkMatch("22", new StubX509Certificate("cn=imap.g.com") // This cn should be ignored
+                .addSubjectAlternativeName(ALT_DNS_NAME, "a.y.com")
+                , "imap.g.com", false);
+        checkMatch("23", new StubX509Certificate("")
+                .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com")
+                , "imap.g.com", true);
+
+        // With wildcards
+        checkMatch("24", new StubX509Certificate("")
+                .addSubjectAlternativeName(ALT_DNS_NAME, "*.g.com")
+                , "imap.g.com", true);
+
+
+        // host name is ip address
+        checkMatch("31", new StubX509Certificate("")
+                .addSubjectAlternativeName(ALT_IPA_NAME, "1.2.3.4")
+                , "1.2.3.4", true);
+        checkMatch("32", new StubX509Certificate("")
+                .addSubjectAlternativeName(ALT_IPA_NAME, "1.2.3.4")
+                , "1.2.3.5", false);
+        checkMatch("32", new StubX509Certificate("")
+                .addSubjectAlternativeName(ALT_IPA_NAME, "1.2.3.4")
+                .addSubjectAlternativeName(ALT_IPA_NAME, "192.168.100.1")
+                , "192.168.100.1", true);
+
+        // Has unknown subject alternative names
+        checkMatch("41", new StubX509Certificate("")
+                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 1")
+                .addSubjectAlternativeName(ALT_UNKNOWN,  "random string 2")
+                .addSubjectAlternativeName(ALT_DNS_NAME, "a.b.c.d")
+                .addSubjectAlternativeName(ALT_DNS_NAME, "*.google.com")
+                .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com")
+                .addSubjectAlternativeName(ALT_IPA_NAME, "2.33.44.55")
+                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 3")
+                , "imap.g.com", true);
+
+        checkMatch("42", new StubX509Certificate("")
+                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 1")
+                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 2")
+                .addSubjectAlternativeName(ALT_DNS_NAME, "a.b.c.d")
+                .addSubjectAlternativeName(ALT_DNS_NAME, "*.google.com")
+                .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com")
+                .addSubjectAlternativeName(ALT_IPA_NAME, "2.33.44.55")
+                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 3")
+                , "2.33.44.55", true);
+
+        checkMatch("43", new StubX509Certificate("")
+                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 1")
+                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 2")
+                .addSubjectAlternativeName(ALT_DNS_NAME, "a.b.c.d")
+                .addSubjectAlternativeName(ALT_DNS_NAME, "*.google.com")
+                .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com")
+                .addSubjectAlternativeName(ALT_IPA_NAME, "2.33.44.55")
+                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 3")
+                , "g.com", false);
+
+        checkMatch("44", new StubX509Certificate("")
+                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 1")
+                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 2")
+                .addSubjectAlternativeName(ALT_DNS_NAME, "a.b.c.d")
+                .addSubjectAlternativeName(ALT_DNS_NAME, "*.google.com")
+                .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com")
+                .addSubjectAlternativeName(ALT_IPA_NAME, "2.33.44.55")
+                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 3")
+                , "2.33.44.1", false);
+    }
+
+    private void checkMatch(String message, X509Certificate certificate, String thisDomain,
+            boolean expected) {
+        Boolean actual = DomainNameValidator.match(certificate, thisDomain);
+        assertEquals(message, (Object) expected, (Object) actual);
+    }
+
+    /**
+     * Tests {@link DomainNameValidator#matchDns}
+     */
+    public void testMatchDns() {
+        checkMatchDns("11", "a.b.c.d", "a.b.c.d", true);
+        checkMatchDns("12", "a.b.c.d", "*.b.c.d", true);
+        checkMatchDns("13", "b.c.d", "*.b.c.d", true);
+        checkMatchDns("14", "b.c.d", "b*.c.d", true);
+
+        checkMatchDns("15", "a.b.c.d", "*.*.c.d", false);
+        checkMatchDns("16", "a.b.c.d", "*.c.d", false);
+
+        checkMatchDns("21", "imap.google.com", "imap.google.com", true);
+        checkMatchDns("22", "imap2.google.com", "imap.google.com", false);
+        checkMatchDns("23", "imap.google.com", "*.google.com", true);
+        checkMatchDns("24", "imap2.google.com", "*.google.com", true);
+        checkMatchDns("25", "imap.google.com", "*.googl.com", false);
+        checkMatchDns("26", "imap2.google2.com", "*.google3.com", false);
+        checkMatchDns("27", "imap.google.com", "ima*.google.com", true);
+        checkMatchDns("28", "imap.google.com", "imap*.google.com", true);
+        checkMatchDns("29", "imap.google.com", "*.imap.google.com", true);
+
+        checkMatchDns("41", "imap.google.com", "a*.google.com", false);
+        checkMatchDns("42", "imap.google.com", "ix*.google.com", false);
+
+        checkMatchDns("51", "imap.google.com", "iMap.Google.Com", true);
+    }
+
+    private void checkMatchDns(String message, String thisDomain, String thatDomain,
+            boolean expected) {
+        boolean actual = DomainNameValidator.matchDns(thisDomain, thatDomain);
+        assertEquals(message, expected, actual);
+    }
+
+    /**
+     * Minimal {@link X509Certificate} implementation for {@link DomainNameValidator}.
+     */
+    private static class StubX509Certificate extends X509Certificate {
+        private final X500Principal subjectX500Principal;
+        private Collection<List<?>> subjectAlternativeNames;
+
+        public StubX509Certificate(String subjectDn) {
+            subjectX500Principal = new X500Principal(subjectDn);
+            subjectAlternativeNames = null;
+        }
+
+        public StubX509Certificate addSubjectAlternativeName(int type, String name) {
+            if (subjectAlternativeNames == null) {
+                subjectAlternativeNames = new ArrayList<List<?>>();
+            }
+            LinkedList<Object> entry = new LinkedList<Object>();
+            entry.add(type);
+            entry.add(name);
+            subjectAlternativeNames.add(entry);
+            return this;
+        }
+
+        @Override
+        public Collection<List<?>> getSubjectAlternativeNames() throws CertificateParsingException {
+            return subjectAlternativeNames;
+        }
+
+        @Override
+        public X500Principal getSubjectX500Principal() {
+            return subjectX500Principal;
+        }
+
+        @Override
+        public void checkValidity() throws CertificateExpiredException,
+                CertificateNotYetValidException {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        @Override
+        public void checkValidity(Date date) throws CertificateExpiredException,
+                CertificateNotYetValidException {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        @Override
+        public int getBasicConstraints() {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        @Override
+        public Principal getIssuerDN() {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        @Override
+        public boolean[] getIssuerUniqueID() {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        @Override
+        public boolean[] getKeyUsage() {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        @Override
+        public Date getNotAfter() {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        @Override
+        public Date getNotBefore() {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        @Override
+        public BigInteger getSerialNumber() {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        @Override
+        public String getSigAlgName() {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        @Override
+        public String getSigAlgOID() {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        @Override
+        public byte[] getSigAlgParams() {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        @Override
+        public byte[] getSignature() {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        @Override
+        public Principal getSubjectDN() {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        @Override
+        public boolean[] getSubjectUniqueID() {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        @Override
+        public byte[] getTBSCertificate() throws CertificateEncodingException {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        @Override
+        public int getVersion() {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        @Override
+        public byte[] getEncoded() throws CertificateEncodingException {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        @Override
+        public PublicKey getPublicKey() {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        @Override
+        public String toString() {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        @Override
+        public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException,
+                InvalidKeyException, NoSuchProviderException, SignatureException {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        @Override
+        public void verify(PublicKey key, String sigProvider) throws CertificateException,
+                NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException,
+                SignatureException {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        public Set<String> getCriticalExtensionOIDs() {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        public byte[] getExtensionValue(String oid) {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        public Set<String> getNonCriticalExtensionOIDs() {
+            throw new RuntimeException("Method not implemented");
+        }
+
+        public boolean hasUnsupportedCriticalExtension() {
+            throw new RuntimeException("Method not implemented");
+        }
+    }
+}
