src/share/classes/sun/security/ssl/ClientHandshaker.java

Print this page

        

*** 57,66 **** --- 57,70 ---- * * @author David Brownell */ 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; // the server's ephemeral public key from the server key exchange message // for ECDHE/ECDH_anon and RSA_EXPORT.
*** 1495,1519 **** X509Certificate prevCert) { if (thisCert.equals(prevCert)) { 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 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); } // check the certificate subject and issuer X500Principal thisSubject = thisCert.getSubjectX500Principal(); X500Principal prevSubject = prevCert.getSubjectX500Principal(); X500Principal thisIssuer = thisCert.getIssuerX500Principal(); --- 1499,1552 ---- X509Certificate prevCert) { if (thisCert.equals(prevCert)) { return true; } + // 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!"); + } + } + + 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 X500Principal thisSubject = thisCert.getSubjectX500Principal(); X500Principal prevSubject = prevCert.getSubjectX500Principal(); X500Principal thisIssuer = thisCert.getIssuerX500Principal();
*** 1529,1559 **** } /* * Returns the subject alternative name of the specified type in the * subjectAltNames extension of a certificate. */ ! private static Object getSubjectAltName(X509Certificate cert, int type) { ! Collection<List<?>> subjectAltNames; ! 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); } } } ! return null; } } --- 1562,1606 ---- } /* * 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 Collection<String> getSubjectAltNames( ! Collection<List<?>> subjectAltNames, int type) { ! 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 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; + } }