1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.hc.client5.http.ssl;
29
30 import java.io.ByteArrayInputStream;
31 import java.io.IOException;
32 import java.io.InputStream;
33 import java.io.InputStreamReader;
34 import java.nio.charset.StandardCharsets;
35 import java.security.cert.CertificateFactory;
36 import java.security.cert.X509Certificate;
37 import java.util.Arrays;
38 import java.util.Collections;
39 import java.util.List;
40
41 import javax.net.ssl.SSLException;
42
43 import org.apache.hc.client5.http.psl.DomainType;
44 import org.apache.hc.client5.http.psl.PublicSuffixList;
45 import org.apache.hc.client5.http.psl.PublicSuffixListParser;
46 import org.apache.hc.client5.http.psl.PublicSuffixMatcher;
47 import org.junit.jupiter.api.Assertions;
48 import org.junit.jupiter.api.BeforeEach;
49 import org.junit.jupiter.api.Test;
50
51
52
53
54 class TestDefaultHostnameVerifier {
55
56 private DefaultHostnameVerifier impl;
57 private PublicSuffixMatcher publicSuffixMatcher;
58
59 private static final String PUBLIC_SUFFIX_MATCHER_SOURCE_FILE = "suffixlistmatcher.txt";
60
61 @BeforeEach
62 void setup() throws IOException {
63 impl = new DefaultHostnameVerifier();
64
65
66 final ClassLoader classLoader = getClass().getClassLoader();
67 final InputStream in = classLoader.getResourceAsStream(PUBLIC_SUFFIX_MATCHER_SOURCE_FILE);
68 Assertions.assertNotNull(in);
69 final List<PublicSuffixList> lists = PublicSuffixListParser.INSTANCE.parseByType(
70 new InputStreamReader(in, StandardCharsets.UTF_8));
71 publicSuffixMatcher = new PublicSuffixMatcher(lists);
72 }
73
74 @Test
75 void testVerify() throws Exception {
76 final CertificateFactory cf = CertificateFactory.getInstance("X.509");
77 InputStream in;
78 X509Certificate x509;
79 in = new ByteArrayInputStream(CertificatesToPlayWith.X509_FOO);
80 x509 = (X509Certificate) cf.generateCertificate(in);
81
82 impl.verify("foo.com", x509);
83 exceptionPlease(impl, "a.foo.com", x509);
84 exceptionPlease(impl, "bar.com", x509);
85
86 in = new ByteArrayInputStream(CertificatesToPlayWith.X509_HANAKO);
87 x509 = (X509Certificate) cf.generateCertificate(in);
88 impl.verify("\u82b1\u5b50.co.jp", x509);
89 exceptionPlease(impl, "a.\u82b1\u5b50.co.jp", x509);
90
91 in = new ByteArrayInputStream(CertificatesToPlayWith.X509_FOO_BAR);
92 x509 = (X509Certificate) cf.generateCertificate(in);
93 exceptionPlease(impl, "foo.com", x509);
94 exceptionPlease(impl, "a.foo.com", x509);
95 impl.verify("bar.com", x509);
96 exceptionPlease(impl, "a.bar.com", x509);
97
98 in = new ByteArrayInputStream(CertificatesToPlayWith.X509_FOO_BAR_HANAKO);
99 x509 = (X509Certificate) cf.generateCertificate(in);
100 exceptionPlease(impl, "foo.com", x509);
101 exceptionPlease(impl, "a.foo.com", x509);
102 impl.verify("bar.com", x509);
103 exceptionPlease(impl, "a.bar.com", x509);
104
105
106
107
108
109
110
111 exceptionPlease(impl, "a.\u82b1\u5b50.co.jp", x509);
112
113 in = new ByteArrayInputStream(CertificatesToPlayWith.X509_NO_CNS_FOO);
114 x509 = (X509Certificate) cf.generateCertificate(in);
115 impl.verify("foo.com", x509);
116 exceptionPlease(impl, "a.foo.com", x509);
117
118 in = new ByteArrayInputStream(CertificatesToPlayWith.X509_NO_CNS_FOO);
119 x509 = (X509Certificate) cf.generateCertificate(in);
120 impl.verify("foo.com", x509);
121 exceptionPlease(impl, "a.foo.com", x509);
122
123 in = new ByteArrayInputStream(CertificatesToPlayWith.X509_THREE_CNS_FOO_BAR_HANAKO);
124 x509 = (X509Certificate) cf.generateCertificate(in);
125 exceptionPlease(impl, "foo.com", x509);
126 exceptionPlease(impl, "a.foo.com", x509);
127 exceptionPlease(impl, "bar.com", x509);
128 exceptionPlease(impl, "a.bar.com", x509);
129 impl.verify("\u82b1\u5b50.co.jp", x509);
130 exceptionPlease(impl, "a.\u82b1\u5b50.co.jp", x509);
131
132 in = new ByteArrayInputStream(CertificatesToPlayWith.X509_WILD_FOO);
133 x509 = (X509Certificate) cf.generateCertificate(in);
134 exceptionPlease(impl, "foo.com", x509);
135 impl.verify("www.foo.com", x509);
136 impl.verify("\u82b1\u5b50.foo.com", x509);
137 exceptionPlease(impl, "a.b.foo.com", x509);
138
139 in = new ByteArrayInputStream(CertificatesToPlayWith.X509_WILD_CO_JP);
140 x509 = (X509Certificate) cf.generateCertificate(in);
141
142
143 impl.verify("*.co.jp", x509);
144 impl.verify("foo.co.jp", x509);
145 impl.verify("\u82b1\u5b50.co.jp", x509);
146
147 in = new ByteArrayInputStream(CertificatesToPlayWith.X509_WILD_FOO_BAR_HANAKO);
148 x509 = (X509Certificate) cf.generateCertificate(in);
149
150 exceptionPlease(impl, "foo.com", x509);
151 exceptionPlease(impl, "www.foo.com", x509);
152 exceptionPlease(impl, "\u82b1\u5b50.foo.com", x509);
153 exceptionPlease(impl, "a.b.foo.com", x509);
154
155 exceptionPlease(impl, "bar.com", x509);
156 impl.verify("www.bar.com", x509);
157 impl.verify("\u82b1\u5b50.bar.com", x509);
158 exceptionPlease(impl, "a.b.bar.com", x509);
159
160 in = new ByteArrayInputStream(CertificatesToPlayWith.X509_MULTIPLE_VALUE_AVA);
161 x509 = (X509Certificate) cf.generateCertificate(in);
162 impl.verify("repository.infonotary.com", x509);
163
164 in = new ByteArrayInputStream(CertificatesToPlayWith.S_GOOGLE_COM);
165 x509 = (X509Certificate) cf.generateCertificate(in);
166 impl.verify("*.google.com", x509);
167
168 in = new ByteArrayInputStream(CertificatesToPlayWith.S_GOOGLE_COM);
169 x509 = (X509Certificate) cf.generateCertificate(in);
170 impl.verify("*.Google.com", x509);
171
172 in = new ByteArrayInputStream(CertificatesToPlayWith.IP_1_1_1_1);
173 x509 = (X509Certificate) cf.generateCertificate(in);
174 impl.verify("1.1.1.1", x509);
175 impl.verify("dummy-value.com", x509);
176
177 exceptionPlease(impl, "1.1.1.2", x509);
178 exceptionPlease(impl, "not-the-cn.com", x509);
179
180 in = new ByteArrayInputStream(CertificatesToPlayWith.EMAIL_ALT_SUBJECT_NAME);
181 x509 = (X509Certificate) cf.generateCertificate(in);
182 impl.verify("www.company.com", x509);
183 }
184
185 @Test
186 void testSubjectAlt() throws Exception {
187 final CertificateFactory cf = CertificateFactory.getInstance("X.509");
188 final InputStream in = new ByteArrayInputStream(CertificatesToPlayWith.X509_MULTIPLE_SUBJECT_ALT);
189 final X509Certificate x509 = (X509Certificate) cf.generateCertificate(in);
190
191 Assertions.assertEquals("CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=CH",
192 x509.getSubjectDN().getName());
193
194 impl.verify("localhost.localdomain", x509);
195 impl.verify("127.0.0.1", x509);
196
197 Assertions.assertThrows(SSLException.class, () -> impl.verify("localhost", x509));
198 Assertions.assertThrows(SSLException.class, () -> impl.verify("local.host", x509));
199 Assertions.assertThrows(SSLException.class, () -> impl.verify("127.0.0.2", x509));
200 }
201
202 public void exceptionPlease(final DefaultHostnameVerifier hv, final String host,
203 final X509Certificate x509) {
204 Assertions.assertThrows(SSLException.class, () -> hv.verify(host, x509));
205 }
206
207 @Test
208 void testParseFQDN() {
209 Assertions.assertEquals(Arrays.asList("blah"),
210 DefaultHostnameVerifier.parseFQDN("blah"));
211 Assertions.assertEquals(Arrays.asList("blah", "blah"),
212 DefaultHostnameVerifier.parseFQDN("blah.blah"));
213 Assertions.assertEquals(Arrays.asList("blah", "blah", "blah"),
214 DefaultHostnameVerifier.parseFQDN("blah.blah.blah"));
215 Assertions.assertEquals(Arrays.asList("", "", "blah", ""),
216 DefaultHostnameVerifier.parseFQDN(".blah.."));
217 Assertions.assertEquals(Arrays.asList(""),
218 DefaultHostnameVerifier.parseFQDN(""));
219 Assertions.assertEquals(Arrays.asList("", ""),
220 DefaultHostnameVerifier.parseFQDN("."));
221 Assertions.assertEquals(Arrays.asList("com", "domain", "host"),
222 DefaultHostnameVerifier.parseFQDN("host.domain.com"));
223 }
224
225 @Test
226 void testDomainRootMatching() {
227 Assertions.assertFalse(DefaultHostnameVerifier.matchDomainRoot("a.b.c", null));
228 Assertions.assertTrue(DefaultHostnameVerifier.matchDomainRoot("a.b.c", "a.b.c"));
229 Assertions.assertFalse(DefaultHostnameVerifier.matchDomainRoot("aa.b.c", "a.b.c"));
230 Assertions.assertFalse(DefaultHostnameVerifier.matchDomainRoot("a.b.c", "aa.b.c"));
231 Assertions.assertTrue(DefaultHostnameVerifier.matchDomainRoot("a.a.b.c", "a.b.c"));
232 }
233
234 @Test
235 void testIdentityMatching() {
236
237 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentity("a.b.c", "*.b.c"));
238 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentityStrict("a.b.c", "*.b.c"));
239
240 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentity("s.a.b.c", "*.b.c"));
241 Assertions.assertFalse(DefaultHostnameVerifier.matchIdentityStrict("s.a.b.c", "*.b.c"));
242
243 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentity("a.gov.uk", "*.gov.uk", publicSuffixMatcher));
244 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentityStrict("a.gov.uk", "*.gov.uk", publicSuffixMatcher));
245
246 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentity("s.a.gov.uk", "*.a.gov.uk", publicSuffixMatcher));
247 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentityStrict("s.a.gov.uk", "*.a.gov.uk", publicSuffixMatcher));
248
249 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentity("s.a.gov.uk", "*.gov.uk", publicSuffixMatcher));
250 Assertions.assertFalse(DefaultHostnameVerifier.matchIdentityStrict("s.a.gov.uk", "*.gov.uk", publicSuffixMatcher));
251
252 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentity("a.gov.com", "*.gov.com", publicSuffixMatcher));
253 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentityStrict("a.gov.com", "*.gov.com", publicSuffixMatcher));
254
255 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentity("s.a.gov.com", "*.gov.com", publicSuffixMatcher));
256 Assertions.assertFalse(DefaultHostnameVerifier.matchIdentityStrict("s.a.gov.com", "*.gov.com", publicSuffixMatcher));
257
258 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentity("a.gov.uk", "a*.gov.uk", publicSuffixMatcher));
259 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentityStrict("a.gov.uk", "a*.gov.uk", publicSuffixMatcher));
260
261 Assertions.assertFalse(DefaultHostnameVerifier.matchIdentity("s.a.gov.uk", "a*.gov.uk", publicSuffixMatcher));
262 Assertions.assertFalse(DefaultHostnameVerifier.matchIdentityStrict("s.a.gov.uk", "a*.gov.uk", publicSuffixMatcher));
263
264 Assertions.assertFalse(DefaultHostnameVerifier.matchIdentity("a.b.c", "*.b.*"));
265 Assertions.assertFalse(DefaultHostnameVerifier.matchIdentityStrict("a.b.c", "*.b.*"));
266
267 Assertions.assertFalse(DefaultHostnameVerifier.matchIdentity("a.b.c", "*.*.c"));
268 Assertions.assertFalse(DefaultHostnameVerifier.matchIdentityStrict("a.b.c", "*.*.c"));
269
270 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentity("a.b.xxx.uk", "a.b.xxx.uk", publicSuffixMatcher));
271 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentityStrict("a.b.xxx.uk", "a.b.xxx.uk", publicSuffixMatcher));
272
273 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentity("a.b.xxx.uk", "*.b.xxx.uk", publicSuffixMatcher));
274 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentityStrict("a.b.xxx.uk", "*.b.xxx.uk", publicSuffixMatcher));
275
276 Assertions.assertFalse(DefaultHostnameVerifier.matchIdentity("b.xxx.uk", "b.xxx.uk", publicSuffixMatcher));
277 Assertions.assertFalse(DefaultHostnameVerifier.matchIdentityStrict("b.xxx.uk", "b.xxx.uk", publicSuffixMatcher));
278
279 Assertions.assertFalse(DefaultHostnameVerifier.matchIdentity("b.xxx.uk", "*.xxx.uk", publicSuffixMatcher));
280 Assertions.assertFalse(DefaultHostnameVerifier.matchIdentityStrict("b.xxx.uk", "*.xxx.uk", publicSuffixMatcher));
281 }
282
283 @Test
284 void testHTTPCLIENT_1097() {
285 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentity("a.b.c", "a*.b.c"));
286 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentityStrict("a.b.c", "a*.b.c"));
287
288 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentity("a.a.b.c", "a*.b.c"));
289 Assertions.assertFalse(DefaultHostnameVerifier.matchIdentityStrict("a.a.b.c", "a*.b.c"));
290 }
291
292 @Test
293 void testHTTPCLIENT_1255() {
294 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentity("mail.a.b.c.com", "m*.a.b.c.com"));
295 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentityStrict("mail.a.b.c.com", "m*.a.b.c.com"));
296 }
297
298 @Test
299 void testHTTPCLIENT_1997_ANY() {
300 String domain;
301
302 domain = "dev.b.cloud.a";
303 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentity( "service.apps." + domain, "*.apps." + domain));
304 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentityStrict( "service.apps." + domain, "*.apps." + domain));
305 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentity( "service.apps." + domain, "*.apps." + domain, publicSuffixMatcher));
306 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentityStrict( "service.apps." + domain, "*.apps." + domain, publicSuffixMatcher));
307
308
309 domain = "dev.b.cloud.com";
310 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentity( "service.apps." + domain, "*.apps." + domain));
311 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentityStrict( "service.apps." + domain, "*.apps." + domain));
312 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentity( "service.apps." + domain, "*.apps." + domain, publicSuffixMatcher));
313 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentityStrict( "service.apps." + domain, "*.apps." + domain, publicSuffixMatcher));
314
315
316 domain = "dev.b.cloud.lan";
317 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentity( "service.apps." + domain, "*.apps." + domain));
318 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentityStrict( "service.apps." + domain, "*.apps." + domain));
319 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentity( "service.apps." + domain, "*.apps." + domain, publicSuffixMatcher));
320 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentityStrict( "service.apps." + domain, "*.apps." + domain, publicSuffixMatcher));
321 }
322
323 @Test
324 void testHTTPCLIENT_1997_ICANN() {
325 String domain;
326
327 domain = "dev.b.cloud.a";
328 Assertions.assertFalse(DefaultHostnameVerifier.matchIdentity( "service.apps." + domain, "*.apps." + domain, publicSuffixMatcher, DomainType.ICANN));
329 Assertions.assertFalse(DefaultHostnameVerifier.matchIdentityStrict( "service.apps." + domain, "*.apps." + domain, publicSuffixMatcher, DomainType.ICANN));
330
331
332 domain = "dev.b.cloud.com";
333 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentity( "service.apps." + domain, "*.apps." + domain, publicSuffixMatcher, DomainType.ICANN));
334 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentityStrict( "service.apps." + domain, "*.apps." + domain, publicSuffixMatcher, DomainType.ICANN));
335
336
337 domain = "dev.b.cloud.lan";
338 Assertions.assertFalse(DefaultHostnameVerifier.matchIdentity( "service.apps." + domain, "*.apps." + domain, publicSuffixMatcher, DomainType.ICANN));
339 Assertions.assertFalse(DefaultHostnameVerifier.matchIdentityStrict( "service.apps." + domain, "*.apps." + domain, publicSuffixMatcher, DomainType.ICANN));
340 }
341
342 @Test
343 void testHTTPCLIENT_1997_PRIVATE() {
344 String domain;
345
346 domain = "dev.b.cloud.a";
347 Assertions.assertFalse(DefaultHostnameVerifier.matchIdentity( "service.apps." + domain, "*.apps." + domain, publicSuffixMatcher, DomainType.PRIVATE));
348 Assertions.assertFalse(DefaultHostnameVerifier.matchIdentityStrict( "service.apps." + domain, "*.apps." + domain, publicSuffixMatcher, DomainType.PRIVATE));
349
350
351 domain = "dev.b.cloud.com";
352 Assertions.assertFalse(DefaultHostnameVerifier.matchIdentity( "service.apps." + domain, "*.apps." + domain, publicSuffixMatcher, DomainType.PRIVATE));
353 Assertions.assertFalse(DefaultHostnameVerifier.matchIdentityStrict( "service.apps." + domain, "*.apps." + domain, publicSuffixMatcher, DomainType.PRIVATE));
354
355
356 domain = "dev.b.cloud.lan";
357 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentity( "service.apps." + domain, "*.apps." + domain, publicSuffixMatcher, DomainType.PRIVATE));
358 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentityStrict( "service.apps." + domain, "*.apps." + domain, publicSuffixMatcher, DomainType.PRIVATE));
359 }
360
361 @Test
362 void testHTTPCLIENT_1997_UNKNOWN() {
363 String domain;
364
365 domain = "dev.b.cloud.a";
366 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentity( "service.apps." + domain, "*.apps." + domain, publicSuffixMatcher, DomainType.UNKNOWN));
367 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentityStrict( "service.apps." + domain, "*.apps." + domain, publicSuffixMatcher, DomainType.UNKNOWN));
368
369
370 domain = "dev.b.cloud.com";
371 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentity( "service.apps." + domain, "*.apps." + domain, publicSuffixMatcher, DomainType.UNKNOWN));
372 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentityStrict( "service.apps." + domain, "*.apps." + domain, publicSuffixMatcher, DomainType.UNKNOWN));
373
374
375 domain = "dev.b.cloud.lan";
376 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentity( "service.apps." + domain, "*.apps." + domain, publicSuffixMatcher, DomainType.UNKNOWN));
377 Assertions.assertTrue(DefaultHostnameVerifier.matchIdentityStrict( "service.apps." + domain, "*.apps." + domain, publicSuffixMatcher, DomainType.UNKNOWN));
378 }
379
380 @Test
381 void testHTTPCLIENT_1316() throws Exception{
382 final String host1 = "2001:0db8:aaaa:bbbb:cccc:0:0:0001";
383 DefaultHostnameVerifier.matchIPv6Address(host1, Collections.singletonList(SubjectName.IP("2001:0db8:aaaa:bbbb:cccc:0:0:0001")));
384 DefaultHostnameVerifier.matchIPv6Address(host1, Collections.singletonList(SubjectName.IP("2001:0db8:aaaa:bbbb:cccc::1")));
385 Assertions.assertThrows(SSLException.class, () ->
386 DefaultHostnameVerifier.matchIPv6Address(host1, Collections.singletonList(SubjectName.IP("2001:0db8:aaaa:bbbb:cccc::10"))));
387 final String host2 = "2001:0db8:aaaa:bbbb:cccc::1";
388 DefaultHostnameVerifier.matchIPv6Address(host2, Collections.singletonList(SubjectName.IP("2001:0db8:aaaa:bbbb:cccc:0:0:0001")));
389 DefaultHostnameVerifier.matchIPv6Address(host2, Collections.singletonList(SubjectName.IP("2001:0db8:aaaa:bbbb:cccc::1")));
390 Assertions.assertThrows(SSLException.class, () ->
391 DefaultHostnameVerifier.matchIPv6Address(host2, Collections.singletonList(SubjectName.IP("2001:0db8:aaaa:bbbb:cccc::10"))));
392 }
393
394 @Test
395 void testHTTPCLIENT_2149() throws Exception {
396 final CertificateFactory cf = CertificateFactory.getInstance("X.509");
397 final InputStream in = new ByteArrayInputStream(CertificatesToPlayWith.SUBJECT_ALT_IP_ONLY);
398 final X509Certificate x509 = (X509Certificate) cf.generateCertificate(in);
399
400 Assertions.assertEquals("CN=www.foo.com", x509.getSubjectDN().getName());
401
402 impl.verify("127.0.0.1", x509);
403 impl.verify("www.foo.com", x509);
404
405 exceptionPlease(impl, "127.0.0.2", x509);
406 exceptionPlease(impl, "www.bar.com", x509);
407 }
408
409 @Test
410 void testExtractCN() throws Exception {
411 Assertions.assertEquals("blah", DefaultHostnameVerifier.extractCN("cn=blah, ou=blah, o=blah"));
412 Assertions.assertEquals("blah", DefaultHostnameVerifier.extractCN("cn=blah, cn=yada, cn=booh"));
413 Assertions.assertEquals("blah", DefaultHostnameVerifier.extractCN("c = pampa , cn = blah , ou = blah , o = blah"));
414 Assertions.assertEquals("blah", DefaultHostnameVerifier.extractCN("cn=\"blah\", ou=blah, o=blah"));
415 Assertions.assertEquals("blah blah", DefaultHostnameVerifier.extractCN("cn=\"blah blah\", ou=blah, o=blah"));
416 Assertions.assertEquals("blah, blah", DefaultHostnameVerifier.extractCN("cn=\"blah, blah\", ou=blah, o=blah"));
417 Assertions.assertEquals("blah, blah", DefaultHostnameVerifier.extractCN("cn=blah\\, blah, ou=blah, o=blah"));
418 Assertions.assertEquals("blah", DefaultHostnameVerifier.extractCN("c = cn=uuh, cn=blah, ou=blah, o=blah"));
419 Assertions.assertThrows(SSLException.class, () ->
420 DefaultHostnameVerifier.extractCN("blah,blah"));
421 Assertions.assertThrows(SSLException.class, () ->
422 DefaultHostnameVerifier.extractCN("cn,o=blah"));
423 }
424
425 @Test
426 void testMatchDNSName() throws Exception {
427 DefaultHostnameVerifier.matchDNSName(
428 "host.domain.com",
429 Collections.singletonList(SubjectName.DNS("*.domain.com")),
430 publicSuffixMatcher);
431 DefaultHostnameVerifier.matchDNSName(
432 "host.xx",
433 Collections.singletonList(SubjectName.DNS("*.xx")),
434 publicSuffixMatcher);
435 DefaultHostnameVerifier.matchDNSName(
436 "host.appspot.com",
437 Collections.singletonList(SubjectName.DNS("*.appspot.com")),
438 publicSuffixMatcher);
439 DefaultHostnameVerifier.matchDNSName(
440 "demo-s3-bucket.s3.eu-central-1.amazonaws.com",
441 Collections.singletonList(SubjectName.DNS("*.s3.eu-central-1.amazonaws.com")),
442 publicSuffixMatcher);
443 DefaultHostnameVerifier.matchDNSName(
444 "hostname-workspace-1.local",
445 Collections.singletonList(SubjectName.DNS("hostname-workspace-1.local")),
446 publicSuffixMatcher);
447
448 Assertions.assertThrows(SSLException.class, () ->
449 DefaultHostnameVerifier.matchDNSName(
450 "host.domain.com",
451 Collections.singletonList(SubjectName.DNS("some.other.com")),
452 publicSuffixMatcher));
453
454 DefaultHostnameVerifier.matchDNSName(
455 "host.ec2.compute-1.amazonaws.com",
456 Collections.singletonList(SubjectName.DNS("host.ec2.compute-1.amazonaws.com")),
457 publicSuffixMatcher);
458 DefaultHostnameVerifier.matchDNSName(
459 "host.ec2.compute-1.amazonaws.com",
460 Collections.singletonList(SubjectName.DNS("*.ec2.compute-1.amazonaws.com")),
461 publicSuffixMatcher);
462 Assertions.assertThrows(SSLException.class, () ->
463 DefaultHostnameVerifier.matchDNSName(
464 "ec2.compute-1.amazonaws.com",
465 Collections.singletonList(SubjectName.DNS("ec2.compute-1.amazonaws.com")),
466 publicSuffixMatcher));
467 Assertions.assertThrows(SSLException.class, () ->
468 DefaultHostnameVerifier.matchDNSName(
469 "ec2.compute-1.amazonaws.com",
470 Collections.singletonList(SubjectName.DNS("*.compute-1.amazonaws.com")),
471 publicSuffixMatcher));
472 }
473
474 @Test
475 void testMatchIdentity() {
476
477 final String unicodeHost1 = "поиск-слов.рф";
478 final String punycodeHost1 = "xn----dtbqigoecuc.xn--p1ai";
479
480
481 Assertions.assertTrue(
482 DefaultHostnameVerifier.matchIdentity(unicodeHost1, punycodeHost1),
483 "Expected the Unicode host and its punycode to match"
484 );
485
486
487 Assertions.assertFalse(
488 DefaultHostnameVerifier.matchIdentity("example.com", punycodeHost1),
489 "Expected mismatch between example.com and xn----dtbqigoecuc.xn--p1ai"
490 );
491
492
493 final String unicodeHost2 = "пример.рф";
494 final String unicodeIdentity2 = "пример.рф";
495 Assertions.assertTrue(
496 DefaultHostnameVerifier.matchIdentity(unicodeHost2, unicodeIdentity2),
497 "Expected Unicode host and Unicode identity to match"
498 );
499
500
501 final String unicodeHost3 = "пример.рф";
502 final String punycodeIdentity3 = "xn--e1afmkfd.xn--p1ai";
503 Assertions.assertTrue(
504 DefaultHostnameVerifier.matchIdentity(unicodeHost3, punycodeIdentity3),
505 "Expected Unicode host and punycode identity to match"
506 );
507
508
509 final String unicodeHost4 = "sub.пример.рф";
510 final String unicodeIdentity4 = "*.пример.рф";
511 Assertions.assertTrue(
512 DefaultHostnameVerifier.matchIdentity(unicodeHost4, unicodeIdentity4),
513 "Expected wildcard to match subdomain"
514 );
515
516
517 final String invalidHost = "invalid_host";
518 final String unicodeIdentity5 = "пример.рф";
519 Assertions.assertFalse(
520 DefaultHostnameVerifier.matchIdentity(invalidHost, unicodeIdentity5),
521 "Expected invalid host to not match"
522 );
523
524
525 final String unicodeHost4b = "пример.рф";
526 final String invalidIdentity = "xn--invalid-punycode";
527 Assertions.assertFalse(
528 DefaultHostnameVerifier.matchIdentity(unicodeHost4b, invalidIdentity),
529 "Expected invalid identity to not match"
530 );
531
532
533 final String unicodeHost5 = "ПрИмеР.рф";
534 final String unicodeIdentity6 = "пример.рф";
535 Assertions.assertTrue(
536 DefaultHostnameVerifier.matchIdentity(unicodeHost5, unicodeIdentity6),
537 "Expected case-insensitive Unicode comparison to match"
538 );
539
540
541
542 final String unicodeHost6 = "sub.пример.рф";
543 final String unicodeIdentity8 = "sub.*.рф";
544 Assertions.assertTrue(
545 DefaultHostnameVerifier.matchIdentity(unicodeHost6, unicodeIdentity8),
546 "Expected wildcard in the middle label to match"
547 );
548 }
549
550 }