Mercurial > hg > release > icedtea7-forest-2.5 > jdk
changeset 8186:ef3273e2be46
8072385, PR2387: Only the first DNSName entry is checked for endpoint identification
Reviewed-by: xuelei
author | robm |
---|---|
date | Mon, 23 Mar 2015 17:05:01 +0000 |
parents | 4ca679b197d8 |
children | f4334685483a |
files | src/share/classes/sun/security/ssl/ClientHandshaker.java |
diffstat | 1 files changed, 77 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/sun/security/ssl/ClientHandshaker.java Wed Jun 03 15:52:40 2015 +0100 +++ b/src/share/classes/sun/security/ssl/ClientHandshaker.java Mon Mar 23 17:05:01 2015 +0000 @@ -62,6 +62,10 @@ */ final class ClientHandshaker extends Handshaker { + // constants for subject alt names of type DNS and IP + private final static int ALTNAME_DNS = 2; + private final static int ALTNAME_IP = 7; + // the server's public key from its certificate. private PublicKey serverKey; @@ -1466,20 +1470,49 @@ return true; } - // check the iPAddress field in subjectAltName extension - Object thisIPAddress = getSubjectAltName(thisCert, 7); // 7: iPAddress - Object prevIPAddress = getSubjectAltName(prevCert, 7); - if (thisIPAddress != null && prevIPAddress!= null) { - // only allow the exactly match - return Objects.equals(thisIPAddress, prevIPAddress); + // check subject alternative names + Collection<List<?>> thisSubjectAltNames = null; + try { + thisSubjectAltNames = thisCert.getSubjectAlternativeNames(); + } catch (CertificateParsingException cpe) { + if (debug != null && Debug.isOn("handshake")) { + System.out.println( + "Attempt to obtain subjectAltNames extension failed!"); + } + } + + Collection<List<?>> prevSubjectAltNames = null; + try { + prevSubjectAltNames = prevCert.getSubjectAlternativeNames(); + } catch (CertificateParsingException cpe) { + if (debug != null && Debug.isOn("handshake")) { + System.out.println( + "Attempt to obtain subjectAltNames extension failed!"); + } } - // check the dNSName field in subjectAltName extension - Object thisDNSName = getSubjectAltName(thisCert, 2); // 2: dNSName - Object prevDNSName = getSubjectAltName(prevCert, 2); - if (thisDNSName != null && prevDNSName!= null) { - // only allow the exactly match - return Objects.equals(thisDNSName, prevDNSName); + if ((thisSubjectAltNames != null) && (prevSubjectAltNames != null)) { + // check the iPAddress field in subjectAltName extension + Collection<String> thisSubAltIPAddrs = + getSubjectAltNames(thisSubjectAltNames, ALTNAME_IP); + Collection<String> prevSubAltIPAddrs = + getSubjectAltNames(prevSubjectAltNames, ALTNAME_IP); + if ((thisSubAltIPAddrs != null) && (prevSubAltIPAddrs != null) && + (isEquivalent(thisSubAltIPAddrs, prevSubAltIPAddrs))) { + + return true; + } + + // check the dNSName field in subjectAltName extension + Collection<String> thisSubAltDnsNames = + getSubjectAltNames(thisSubjectAltNames, ALTNAME_DNS); + Collection<String> prevSubAltDnsNames = + getSubjectAltNames(prevSubjectAltNames, ALTNAME_DNS); + if ((thisSubAltDnsNames != null) && (prevSubAltDnsNames != null) && + (isEquivalent(thisSubAltDnsNames, prevSubAltDnsNames))) { + + return true; + } } // check the certificate subject and issuer @@ -1500,29 +1533,43 @@ /* * Returns the subject alternative name of the specified type in the * subjectAltNames extension of a certificate. + * + * Note that only those subjectAltName types that use String data + * should be passed into this function. */ - private static Object getSubjectAltName(X509Certificate cert, int type) { - Collection<List<?>> subjectAltNames; + private static Collection<String> getSubjectAltNames( + Collection<List<?>> subjectAltNames, int type) { - try { - subjectAltNames = cert.getSubjectAlternativeNames(); - } catch (CertificateParsingException cpe) { - if (debug != null && Debug.isOn("handshake")) { - System.out.println( - "Attempt to obtain subjectAltNames extension failed!"); - } - return null; - } - - if (subjectAltNames != null) { - for (List<?> subjectAltName : subjectAltNames) { - int subjectAltNameType = (Integer)subjectAltName.get(0); - if (subjectAltNameType == type) { - return subjectAltName.get(1); + HashSet<String> subAltDnsNames = null; + for (List<?> subjectAltName : subjectAltNames) { + int subjectAltNameType = (Integer)subjectAltName.get(0); + if (subjectAltNameType == type) { + String subAltDnsName = (String)subjectAltName.get(1); + if ((subAltDnsName != null) && !subAltDnsName.isEmpty()) { + if (subAltDnsNames == null) { + subAltDnsNames = + new HashSet<>(subjectAltNames.size()); + } + subAltDnsNames.add(subAltDnsName); } } } - return null; + return subAltDnsNames; + } + + private static boolean isEquivalent(Collection<String> thisSubAltNames, + Collection<String> prevSubAltNames) { + + for (String thisSubAltName : thisSubAltNames) { + for (String prevSubAltName : prevSubAltNames) { + // Only allow the exactly match. Check no wildcard character. + if (thisSubAltName.equalsIgnoreCase(prevSubAltName)) { + return true; + } + } + } + + return false; } }