1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package org.apache.http.conn.ssl.cts;
18 
19 import javax.security.auth.x500.X500Principal;
20 import junit.framework.TestCase;
21 
22 import org.apache.http.conn.ssl.AbstractVerifier;
23 
24 import java.lang.Override;
25 import java.math.BigInteger;
26 import java.security.InvalidKeyException;
27 import java.security.NoSuchAlgorithmException;
28 import java.security.NoSuchProviderException;
29 import java.security.Principal;
30 import java.security.PublicKey;
31 import java.security.SignatureException;
32 import java.security.cert.CertificateEncodingException;
33 import java.security.cert.CertificateException;
34 import java.security.cert.CertificateExpiredException;
35 import java.security.cert.CertificateNotYetValidException;
36 import java.security.cert.X509Certificate;
37 import java.util.Arrays;
38 import java.util.Date;
39 import java.util.Set;
40 
41 /**
42  * See also {@link libcore.javax.security.auth.x500.X500PrincipalTest} as it shows some cases
43  * we are not checking as they are not allowed by the X500 principal in the first place.
44  */
45 public final class AbstractVerifierTest extends TestCase {
46 
testGetCns()47     public void testGetCns() {
48         assertCns("");
49         assertCns("ou=xxx");
50         assertCns("ou=xxx,cn=xxx", "xxx");
51         assertCns("ou=xxx+cn=yyy,cn=zzz+cn=abc", "yyy", "zzz", "abc");
52         assertCns("cn=a,cn=b", "a", "b");
53         assertCns("cn=a   c,cn=b", "a   c", "b");
54         assertCns("cn=a   ,cn=b", "a", "b");
55         assertCns("cn=Cc,cn=Bb,cn=Aa", "Cc", "Bb", "Aa");
56         assertCns("cn=imap.gmail.com", "imap.gmail.com");
57         assertCns("l=\"abcn=a,b\", cn=c", "c");
58         assertCns("l=\"abcn=a,b\", cn=c", "c");
59         assertCns("l=\"abcn=a,b\", cn= c", "c");
60         assertCns("cn=<", "<");
61         assertCns("cn=>", ">");
62         assertCns("cn= >", ">");
63         assertCns("cn=a b", "a b");
64         assertCns("cn   =a b", "a b");
65         assertCns("Cn=a b", "a b");
66         assertCns("cN=a b", "a b");
67         assertCns("CN=a b", "a b");
68         assertCns("cn=a#b", "a#b");
69         assertCns("cn=#130161", "a");
70         assertCns("l=q\t+cn=p", "p");
71         assertCns("l=q\n+cn=p", "p");
72         assertCns("l=q\n,cn=p", "p");
73         assertCns("l=,cn=p", "p");
74         assertCns("l=\tq\n,cn=\tp", "\tp");
75     }
76 
77     /** A cn=, generates an empty value, unless it's at the very end */
testEmptyValues()78     public void testEmptyValues() {
79         assertCns("l=,cn=+cn=q", "", "q");
80         assertCns("l=,cn=,cn=q", "", "q");
81         assertCns("l=,cn=");
82         assertCns("l=,cn=q,cn=   ", "q");
83         assertCns("l=,cn=q  ,cn=   ", "q");
84         assertCns("l=,cn=\"\"");
85         assertCns("l=,cn=\"  \",cn=\"  \"", "  ", "  ");
86         assertCns("l=,cn=  ,cn=  ","");
87         assertCns("l=,cn=,cn=  ,cn=  ", "", "");
88     }
89 
90 
testGetCns_escapedChars()91     public void testGetCns_escapedChars() {
92         assertCns("cn=\\,", ",");
93         assertCns("cn=\\#", "#");
94         assertCns("cn=\\+", "+");
95         assertCns("cn=\\\"", "\"");
96         assertCns("cn=\\\\", "\\");
97         assertCns("cn=\\<", "<");
98         assertCns("cn=\\>", ">");
99         assertCns("cn=\\;", ";");
100         assertCns("cn=\\+", "+");
101         assertCns("cn=\"\\+\"", "+");
102         assertCns("cn=\"\\,\"", ",");
103         assertCns("cn= a =", "a =");
104         assertCns("cn==", "=");
105     }
106 
testGetCns_whitespace()107     public void testGetCns_whitespace() {
108         assertCns("cn= p", "p");
109         assertCns("cn=\np", "p");
110         assertCns("cn=\tp", "\tp");
111     }
112 
testGetCnsWithOid()113     public void testGetCnsWithOid() {
114         assertCns("2.5.4.3=a,ou=xxx", "a");
115         assertCns("2.5.4.3=\" a \",ou=xxx", " a ");
116         assertCns("2.5.5.3=a,ou=xxx,cn=b", "b");
117     }
118 
testGetCnsWithQuotedStrings()119     public void testGetCnsWithQuotedStrings() {
120         assertCns("cn=\"\\\" a ,=<>#;\"", "\" a ,=<>#;");
121         assertCns("cn=abc\\,def", "abc,def");
122         assertCns("cn=\"\\\" a ,\\=<>\\#;\"", "\" a ,=<>#;");
123     }
124 
testGetCnsWithUtf8()125     public void testGetCnsWithUtf8() {
126         assertCns("cn=\"Lu\\C4\\8Di\\C4\\87\"", "\u004c\u0075\u010d\u0069\u0107");
127         assertCns("cn=Lu\\C4\\8Di\\C4\\87", "\u004c\u0075\u010d\u0069\u0107");
128         assertCns("cn=Lu\\C4\\8di\\c4\\87", "\u004c\u0075\u010d\u0069\u0107");
129         assertCns("cn=\"Lu\\C4\\8di\\c4\\87\"", "\u004c\u0075\u010d\u0069\u0107");
130         assertCns("cn=\u004c\u0075\u010d\u0069\u0107", "\u004c\u0075\u010d\u0069\u0107");
131         // \63=c
132         assertExceptionInPrincipal("\\63n=ab");
133         assertExceptionInPrincipal("cn=\\a");
134     }
135 
testGetCnsWithWhitespace()136     public void testGetCnsWithWhitespace() {
137         assertCns("ou=a, cn=  a  b  ,o=x", "a  b");
138         assertCns("cn=\"  a  b  \" ,o=x", "  a  b  ");
139     }
140 
assertCns(String dn, String... expected)141     private static void assertCns(String dn, String... expected) {
142         String[] result = AbstractVerifier.getCNs(createStubCertificate(dn));
143         if (expected.length == 0) {
144             assertNull(result);
145         } else {
146             assertNotNull(dn, result);
147             assertEquals(dn, Arrays.asList(expected), Arrays.asList(result));
148         }
149     }
150 
assertExceptionInPrincipal(String dn)151     private static void assertExceptionInPrincipal(String dn) {
152         try {
153             X500Principal principal = new X500Principal(dn);
154             fail("Expected " + IllegalArgumentException.class.getName()
155                     + " because of incorrect input name");
156         } catch (IllegalArgumentException e) {
157             // Expected.
158         }
159     }
160 
createStubCertificate(final String subjectName)161     private static X509Certificate createStubCertificate(final String subjectName) {
162         return new X509Certificate() {
163             @Override
164             public X500Principal getSubjectX500Principal() {
165                 return new X500Principal(subjectName);
166             }
167 
168             @Override
169             public Set<String> getCriticalExtensionOIDs() {
170                 return null;
171             }
172 
173             @Override
174             public byte[] getExtensionValue(String oid) {
175                 return new byte[0];
176             }
177 
178             @Override
179             public Set<String> getNonCriticalExtensionOIDs() {
180                 return null;
181             }
182 
183             @Override
184             public boolean hasUnsupportedCriticalExtension() {
185                 return false;
186             }
187 
188             @Override
189             public byte[] getEncoded() throws CertificateEncodingException {
190                 return new byte[0];
191             }
192 
193             @Override
194             public void verify(PublicKey key)
195                     throws CertificateException, NoSuchAlgorithmException, InvalidKeyException,
196                     NoSuchProviderException, SignatureException {
197 
198             }
199 
200             @Override
201             public void verify(PublicKey key, String sigProvider)
202                     throws CertificateException, NoSuchAlgorithmException, InvalidKeyException,
203                     NoSuchProviderException, SignatureException {
204 
205             }
206 
207             @Override
208             public String toString() {
209                 return null;
210             }
211 
212             @Override
213             public PublicKey getPublicKey() {
214                 return null;
215             }
216 
217             @Override
218             public void checkValidity()
219                     throws CertificateExpiredException, CertificateNotYetValidException {
220 
221             }
222 
223             @Override
224             public void checkValidity(Date date)
225                     throws CertificateExpiredException, CertificateNotYetValidException {
226 
227             }
228 
229             @Override
230             public int getVersion() {
231                 return 0;
232             }
233 
234             @Override
235             public BigInteger getSerialNumber() {
236                 return null;
237             }
238 
239             @Override
240             public Principal getIssuerDN() {
241                 return null;
242             }
243 
244             @Override
245             public Principal getSubjectDN() {
246                 return null;
247             }
248 
249             @Override
250             public Date getNotBefore() {
251                 return null;
252             }
253 
254             @Override
255             public Date getNotAfter() {
256                 return null;
257             }
258 
259             @Override
260             public byte[] getTBSCertificate() throws CertificateEncodingException {
261                 return new byte[0];
262             }
263 
264             @Override
265             public byte[] getSignature() {
266                 return new byte[0];
267             }
268 
269             @Override
270             public String getSigAlgName() {
271                 return null;
272             }
273 
274             @Override
275             public String getSigAlgOID() {
276                 return null;
277             }
278 
279             @Override
280             public byte[] getSigAlgParams() {
281                 return new byte[0];
282             }
283 
284             @Override
285             public boolean[] getIssuerUniqueID() {
286                 return new boolean[0];
287             }
288 
289             @Override
290             public boolean[] getSubjectUniqueID() {
291                 return new boolean[0];
292             }
293 
294             @Override
295             public boolean[] getKeyUsage() {
296                 return new boolean[0];
297             }
298 
299             @Override
300             public int getBasicConstraints() {
301                 return 0;
302             }
303         };
304     }
305 }
306 
307