equal
deleted
inserted
replaced
33 import java.util.*; |
33 import java.util.*; |
34 import javax.security.auth.x500.X500Principal; |
34 import javax.security.auth.x500.X500Principal; |
35 import javax.net.ssl.SNIHostName; |
35 import javax.net.ssl.SNIHostName; |
36 |
36 |
37 import sun.net.util.IPAddressUtil; |
37 import sun.net.util.IPAddressUtil; |
38 import sun.security.ssl.ClientKeyExchangeService; |
|
39 import sun.security.ssl.Debug; |
|
40 import sun.security.x509.X500Name; |
38 import sun.security.x509.X500Name; |
|
39 import sun.security.ssl.SSLLogger; |
41 |
40 |
42 /** |
41 /** |
43 * Class to check hostnames against the names specified in a certificate as |
42 * Class to check hostnames against the names specified in a certificate as |
44 * required for TLS and LDAP. |
43 * required for TLS and LDAP. |
45 * |
44 * |
58 |
57 |
59 // constants for subject alt names of type DNS and IP |
58 // constants for subject alt names of type DNS and IP |
60 private static final int ALTNAME_DNS = 2; |
59 private static final int ALTNAME_DNS = 2; |
61 private static final int ALTNAME_IP = 7; |
60 private static final int ALTNAME_IP = 7; |
62 |
61 |
63 private static final Debug debug = Debug.getInstance("ssl"); |
|
64 |
|
65 // the algorithm to follow to perform the check. Currently unused. |
62 // the algorithm to follow to perform the check. Currently unused. |
66 private final byte checkType; |
63 private final byte checkType; |
67 |
64 |
68 private HostnameChecker(byte checkType) { |
65 private HostnameChecker(byte checkType) { |
69 this.checkType = checkType; |
66 this.checkType = checkType; |
102 } |
99 } |
103 |
100 |
104 public void match(String expectedName, X509Certificate cert) |
101 public void match(String expectedName, X509Certificate cert) |
105 throws CertificateException { |
102 throws CertificateException { |
106 match(expectedName, cert, false); |
103 match(expectedName, cert, false); |
107 } |
|
108 |
|
109 /** |
|
110 * Perform the check for Kerberos. |
|
111 */ |
|
112 public static boolean match(String expectedName, Principal principal) { |
|
113 String hostName = getServerName(principal); |
|
114 return (expectedName.equalsIgnoreCase(hostName)); |
|
115 } |
|
116 |
|
117 /** |
|
118 * Return the Server name from Kerberos principal. |
|
119 */ |
|
120 public static String getServerName(Principal principal) { |
|
121 ClientKeyExchangeService p = |
|
122 ClientKeyExchangeService.find("KRB5"); |
|
123 if (p == null) { |
|
124 throw new AssertionError("Kerberos should have been available"); |
|
125 } |
|
126 return p.getServiceHostName(principal); |
|
127 } |
104 } |
128 |
105 |
129 /** |
106 /** |
130 * Test whether the given hostname looks like a literal IPv4 or IPv6 |
107 * Test whether the given hostname looks like a literal IPv4 or IPv6 |
131 * address. The hostname does not need to be a fully qualified name. |
108 * address. The hostname does not need to be a fully qualified name. |
314 */ |
291 */ |
315 private static boolean hasIllegalWildcard(String domain, String template, |
292 private static boolean hasIllegalWildcard(String domain, String template, |
316 boolean chainsToPublicCA) { |
293 boolean chainsToPublicCA) { |
317 // not ok if it is a single wildcard character or "*." |
294 // not ok if it is a single wildcard character or "*." |
318 if (template.equals("*") || template.equals("*.")) { |
295 if (template.equals("*") || template.equals("*.")) { |
319 if (debug != null) { |
296 if (SSLLogger.isOn) { |
320 debug.println("Certificate domain name has illegal single " + |
297 SSLLogger.fine( |
321 "wildcard character: " + template); |
298 "Certificate domain name has illegal single " + |
|
299 "wildcard character: " + template); |
322 } |
300 } |
323 return true; |
301 return true; |
324 } |
302 } |
325 |
303 |
326 int lastWildcardIndex = template.lastIndexOf("*"); |
304 int lastWildcardIndex = template.lastIndexOf("*"); |
333 String afterWildcard = template.substring(lastWildcardIndex); |
311 String afterWildcard = template.substring(lastWildcardIndex); |
334 int firstDotIndex = afterWildcard.indexOf("."); |
312 int firstDotIndex = afterWildcard.indexOf("."); |
335 |
313 |
336 // not ok if there is no dot after wildcard (ex: "*com") |
314 // not ok if there is no dot after wildcard (ex: "*com") |
337 if (firstDotIndex == -1) { |
315 if (firstDotIndex == -1) { |
338 if (debug != null) { |
316 if (SSLLogger.isOn) { |
339 debug.println("Certificate domain name has illegal wildcard, " + |
317 SSLLogger.fine( |
340 "no dot after wildcard character: " + template); |
318 "Certificate domain name has illegal wildcard, " + |
|
319 "no dot after wildcard character: " + template); |
341 } |
320 } |
342 return true; |
321 return true; |
343 } |
322 } |
344 |
323 |
345 // If the wildcarded domain is a top-level domain under which names |
324 // If the wildcarded domain is a top-level domain under which names |
352 .filter(d -> d.type() == RegisteredDomain.Type.ICANN); |
331 .filter(d -> d.type() == RegisteredDomain.Type.ICANN); |
353 |
332 |
354 if (rd.isPresent()) { |
333 if (rd.isPresent()) { |
355 String wDomain = afterWildcard.substring(firstDotIndex + 1); |
334 String wDomain = afterWildcard.substring(firstDotIndex + 1); |
356 if (rd.get().publicSuffix().equalsIgnoreCase(wDomain)) { |
335 if (rd.get().publicSuffix().equalsIgnoreCase(wDomain)) { |
357 if (debug != null) { |
336 if (SSLLogger.isOn) { |
358 debug.println("Certificate domain name has illegal " + |
337 SSLLogger.fine( |
359 "wildcard for public suffix: " + template); |
338 "Certificate domain name has illegal " + |
|
339 "wildcard for public suffix: " + template); |
360 } |
340 } |
361 return true; |
341 return true; |
362 } |
342 } |
363 } |
343 } |
364 |
344 |