# HG changeset patch # User igerasim # Date 1500333423 -3600 # Node ID fbe9c6c3e78cbf9c69fd3baadca6b2eaeea5619c # Parent 0e846618238e7d0470c38ecc721dee785cdfd9dc 8174873: Improved certificate procesing Reviewed-by: jnimeh, ahgross, rhalade diff -r 0e846618238e -r fbe9c6c3e78c src/share/classes/sun/security/util/HostnameChecker.java --- a/src/share/classes/sun/security/util/HostnameChecker.java Sun Jul 16 00:29:10 2017 +0100 +++ b/src/share/classes/sun/security/util/HostnameChecker.java Tue Jul 18 00:17:03 2017 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package sun.security.util; import java.io.IOException; +import java.net.IDN; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.*; @@ -186,6 +187,15 @@ */ private void matchDNS(String expectedName, X509Certificate cert) throws CertificateException { + // Check that the expected name is a valid domain name. + try { + // Using the checking taken from OpenJDK 8's SNIHostName + checkHostName(expectedName); + } catch (IllegalArgumentException iae) { + throw new CertificateException( + "Illegal given domain name: " + expectedName, iae); + } + Collection> subjAltNames = cert.getSubjectAlternativeNames(); if (subjAltNames != null) { boolean foundDNS = false; @@ -257,6 +267,18 @@ * may contain the wildcard character * */ private boolean isMatched(String name, String template) { + // check the validity of the domain name template. + try { + // Replacing wildcard character '*' with 'x' so as to check + // the domain name template validity. + // + // Using the checking taken from OpenJDK 8's SNIHostName + checkHostName(template.replace('*', 'x')); + } catch (IllegalArgumentException iae) { + // It would be nice to add debug log if not matching. + return false; + } + if (checkType == TYPE_TLS) { return matchAllWildcards(name, template); } else if (checkType == TYPE_LDAP) { @@ -366,4 +388,22 @@ } return name.endsWith(afterWildcard); } + + // check the validity of the string hostname + private void checkHostName(String hostname) { + hostname = IDN.toASCII(Objects.requireNonNull(hostname, + "Server name value of host_name cannot be null"), + IDN.USE_STD3_ASCII_RULES); + + if (hostname.isEmpty()) { + throw new IllegalArgumentException( + "Server name value of host_name cannot be empty"); + } + + if (hostname.endsWith(".")) { + throw new IllegalArgumentException( + "Server name value of host_name cannot have the trailing dot"); + } + } + }