/*
* 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 okhttp3.internal.tls;
import javax.security.auth.x500.X500Principal;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
public final class DistinguishedNameParserTest {
@Test public void regularCases() {
assertCn("xxx", "ou=xxx,cn=xxx");
assertCn("yyy", "ou=xxx+cn=yyy,cn=zzz+cn=abc");
assertCn("a", "cn=a,cn=b");
assertCn("a c", "cn=a c,cn=b");
assertCn("Cc", "cn=Cc,cn=Bb,cn=Aa");
assertCn("imap.gmail.com", "cn=imap.gmail.com");
assertCn("c", "l=\"abcn=a,b\", cn=c");
assertCn("c", "l=\"abcn=a,b\", cn=c");
assertCn("c", "l=\"abcn=a,b\", cn= c");
assertCn("a b", "cn=a b");
assertCn("a b", "cn =a b");
assertCn("a b", "Cn=a b");
assertCn("a b", "cN=a b");
assertCn("a b", "CN=a b");
assertCn("a#b", "cn=a#b");
assertCn("a", "cn=#130161");
assertCn("p", "l=q\t+cn=p");
assertCn("p", "l=q\n+cn=p");
assertCn("p", "l=q\n,cn=p");
assertCn("p", "l=,cn=p");
assertCn("\tp", "l=\tq\n,cn=\tp");
}
@Test public void emptyValues() {
assertCn(null, "");
assertCn(null, "ou=xxx");
assertCn("", "l=,cn=+cn=q");
assertCn("", "l=,cn=,cn=q");
assertCn(null, "l=,cn=");
assertCn("q", "l=,cn=q,cn= ");
assertCn("q", "l=,cn=q ,cn= ");
assertCn(null, "l=,cn=\"\"");
assertCn("", "l=,cn= ,cn= ");
assertCn("", "l=,cn=,cn= ,cn= ");
}
@Test public void escapedChars() {
assertCn(",", "cn=\\,");
assertCn("#", "cn=\\#");
assertCn("+", "cn=\\+");
assertCn("\"", "cn=\\\"");
assertCn("\\", "cn=\\\\");
assertCn("<", "cn=\\<");
assertCn(">", "cn=\\>");
assertCn(";", "cn=\\;");
assertCn("+", "cn=\\+");
assertCn("+", "cn=\"\\+\"");
assertCn(",", "cn=\"\\,\"");
assertCn("a =", "cn= a =");
assertCn("=", "cn==");
}
@Test public void whitespace() {
assertCn("p", "cn= p");
assertCn("p", "cn=\np");
assertCn("\tp", "cn=\tp");
}
@Test public void withOid() {
assertCn("a", "2.5.4.3=a,ou=xxx");
assertCn("a", "2.5.4.3=\" a \",ou=xxx");
assertCn("b", "2.5.5.3=a,ou=xxx,cn=b");
}
@Test public void quotedStrings() {
assertCn("\" a ,=<>#;", "cn=\"\\\" a ,=<>#;\"");
assertCn("abc,def", "cn=abc\\,def");
assertCn("\" a ,=<>#;", "cn=\"\\\" a ,\\=<>\\#;\"");
}
@Test public void utf8() {
assertCn("\u004c\u0075\u010d\u0069\u0107", "cn=\"Lu\\C4\\8Di\\C4\\87\"");
assertCn("\u004c\u0075\u010d\u0069\u0107", "cn=Lu\\C4\\8Di\\C4\\87");
assertCn("\u004c\u0075\u010d\u0069\u0107", "cn=Lu\\C4\\8di\\c4\\87");
assertCn("\u004c\u0075\u010d\u0069\u0107", "cn=\"Lu\\C4\\8di\\c4\\87\"");
assertCn("\u004c\u0075\u010d\u0069\u0107", "cn=\u004c\u0075\u010d\u0069\u0107");
// \63=c
expectExceptionInPrincipal("\\63n=ab");
expectExceptionInPrincipal("cn=\\a");
}
@Test public void trailingWhitespace() {
assertCn("a b", "ou=a, cn= a b ,o=x");
assertCn("a b", "cn=\" a b \" ,o=x");
assertCn("a", "cn=a ,cn=b");
assertCn("", "l=,cn=\" \",cn=\" \"");
}
/**
* @param expected the value of the first "cn=" argument in {@code dn},
* or null if none is expected
*/
private void assertCn(String expected, String dn) {
X500Principal principal = new X500Principal(dn);
DistinguishedNameParser parser = new DistinguishedNameParser(principal);
assertEquals(dn, expected, parser.findMostSpecific("cn"));
}
private void expectExceptionInPrincipal(String dn) {
try {
new X500Principal(dn);
fail("Expected " + IllegalArgumentException.class.getName()
+ " because of incorrect input name");
} catch (IllegalArgumentException expected) {
}
}
}