src/java.base/share/classes/sun/security/util/HostnameChecker.java
changeset 50768 68fa3d4026ea
parent 47216 71c04702a3d5
child 50788 6274aee1f692
equal deleted inserted replaced
50767:356eaea05bf0 50768:68fa3d4026ea
    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