jdk/src/java.base/share/classes/sun/security/ssl/ClientHandshaker.java
changeset 29266 5705356edc61
parent 29264 5172066a2da6
child 29390 9927a5ff3ded
equal deleted inserted replaced
29265:4e0df0a96081 29266:5705356edc61
    56  * common functionality (e.g. key generation) that is provided there.
    56  * common functionality (e.g. key generation) that is provided there.
    57  *
    57  *
    58  * @author David Brownell
    58  * @author David Brownell
    59  */
    59  */
    60 final class ClientHandshaker extends Handshaker {
    60 final class ClientHandshaker extends Handshaker {
       
    61 
       
    62     // constants for subject alt names of type DNS and IP
       
    63     private final static int ALTNAME_DNS = 2;
       
    64     private final static int ALTNAME_IP  = 7;
    61 
    65 
    62     // the server's public key from its certificate.
    66     // the server's public key from its certificate.
    63     private PublicKey serverKey;
    67     private PublicKey serverKey;
    64 
    68 
    65     // the server's ephemeral public key from the server key exchange message
    69     // the server's ephemeral public key from the server key exchange message
  1500             X509Certificate prevCert) {
  1504             X509Certificate prevCert) {
  1501         if (thisCert.equals(prevCert)) {
  1505         if (thisCert.equals(prevCert)) {
  1502             return true;
  1506             return true;
  1503         }
  1507         }
  1504 
  1508 
  1505         // check the iPAddress field in subjectAltName extension
  1509         // check subject alternative names
  1506         Object thisIPAddress = getSubjectAltName(thisCert, 7);  // 7: iPAddress
  1510         Collection<List<?>> thisSubjectAltNames = null;
  1507         Object prevIPAddress = getSubjectAltName(prevCert, 7);
  1511         try {
  1508         if (thisIPAddress != null && prevIPAddress!= null) {
  1512             thisSubjectAltNames = thisCert.getSubjectAlternativeNames();
  1509             // only allow the exactly match
  1513         } catch (CertificateParsingException cpe) {
  1510             return Objects.equals(thisIPAddress, prevIPAddress);
  1514             if (debug != null && Debug.isOn("handshake")) {
  1511         }
  1515                 System.out.println(
  1512 
  1516                         "Attempt to obtain subjectAltNames extension failed!");
  1513         // check the dNSName field in subjectAltName extension
  1517             }
  1514         Object thisDNSName = getSubjectAltName(thisCert, 2);    // 2: dNSName
  1518         }
  1515         Object prevDNSName = getSubjectAltName(prevCert, 2);
  1519 
  1516         if (thisDNSName != null && prevDNSName!= null) {
  1520         Collection<List<?>> prevSubjectAltNames = null;
  1517             // only allow the exactly match
  1521         try {
  1518             return Objects.equals(thisDNSName, prevDNSName);
  1522             prevSubjectAltNames = prevCert.getSubjectAlternativeNames();
       
  1523         } catch (CertificateParsingException cpe) {
       
  1524             if (debug != null && Debug.isOn("handshake")) {
       
  1525                 System.out.println(
       
  1526                         "Attempt to obtain subjectAltNames extension failed!");
       
  1527             }
       
  1528         }
       
  1529 
       
  1530         if ((thisSubjectAltNames != null) && (prevSubjectAltNames != null)) {
       
  1531             // check the iPAddress field in subjectAltName extension
       
  1532             Collection<String> thisSubAltIPAddrs =
       
  1533                         getSubjectAltNames(thisSubjectAltNames, ALTNAME_IP);
       
  1534             Collection<String> prevSubAltIPAddrs =
       
  1535                         getSubjectAltNames(prevSubjectAltNames, ALTNAME_IP);
       
  1536             if ((thisSubAltIPAddrs != null) && (prevSubAltIPAddrs != null) &&
       
  1537                 (isEquivalent(thisSubAltIPAddrs, prevSubAltIPAddrs))) {
       
  1538 
       
  1539                 return true;
       
  1540             }
       
  1541 
       
  1542             // check the dNSName field in subjectAltName extension
       
  1543             Collection<String> thisSubAltDnsNames =
       
  1544                         getSubjectAltNames(thisSubjectAltNames, ALTNAME_DNS);
       
  1545             Collection<String> prevSubAltDnsNames =
       
  1546                         getSubjectAltNames(prevSubjectAltNames, ALTNAME_DNS);
       
  1547             if ((thisSubAltDnsNames != null) && (prevSubAltDnsNames != null) &&
       
  1548                 (isEquivalent(thisSubAltDnsNames, prevSubAltDnsNames))) {
       
  1549 
       
  1550                 return true;
       
  1551             }
  1519         }
  1552         }
  1520 
  1553 
  1521         // check the certificate subject and issuer
  1554         // check the certificate subject and issuer
  1522         X500Principal thisSubject = thisCert.getSubjectX500Principal();
  1555         X500Principal thisSubject = thisCert.getSubjectX500Principal();
  1523         X500Principal prevSubject = prevCert.getSubjectX500Principal();
  1556         X500Principal prevSubject = prevCert.getSubjectX500Principal();
  1535 
  1568 
  1536     /*
  1569     /*
  1537      * Returns the subject alternative name of the specified type in the
  1570      * Returns the subject alternative name of the specified type in the
  1538      * subjectAltNames extension of a certificate.
  1571      * subjectAltNames extension of a certificate.
  1539      */
  1572      */
  1540     private static Object getSubjectAltName(X509Certificate cert, int type) {
  1573     private static Collection<String> getSubjectAltNames(
  1541         Collection<List<?>> subjectAltNames;
  1574             Collection<List<?>> subjectAltNames, int type) {
  1542 
  1575 
  1543         try {
  1576         HashSet<String> subAltDnsNames = null;
  1544             subjectAltNames = cert.getSubjectAlternativeNames();
  1577         for (List<?> subjectAltName : subjectAltNames) {
  1545         } catch (CertificateParsingException cpe) {
  1578             int subjectAltNameType = (Integer)subjectAltName.get(0);
  1546             if (debug != null && Debug.isOn("handshake")) {
  1579             if (subjectAltNameType == type) {
  1547                 System.out.println(
  1580                 String subAltDnsName = (String)subjectAltName.get(1);
  1548                         "Attempt to obtain subjectAltNames extension failed!");
  1581                 if ((subAltDnsName != null) && !subAltDnsName.isEmpty()) {
  1549             }
  1582                     if (subAltDnsNames == null) {
  1550             return null;
  1583                         subAltDnsNames =
  1551         }
  1584                                 new HashSet<>(subjectAltNames.size());
  1552 
  1585                     }
  1553         if (subjectAltNames != null) {
  1586                     subAltDnsNames.add(subAltDnsName);
  1554             for (List<?> subjectAltName : subjectAltNames) {
  1587                 }
  1555                 int subjectAltNameType = (Integer)subjectAltName.get(0);
  1588             }
  1556                 if (subjectAltNameType == type) {
  1589         }
  1557                     return subjectAltName.get(1);
  1590 
  1558                 }
  1591         return subAltDnsNames;
  1559             }
  1592     }
  1560         }
  1593 
  1561 
  1594     private static boolean isEquivalent(Collection<String> thisSubAltNames,
  1562         return null;
  1595             Collection<String> prevSubAltNames) {
       
  1596 
       
  1597         for (String thisSubAltName : thisSubAltNames) {
       
  1598             for (String prevSubAltName : prevSubAltNames) {
       
  1599                 // Only allow the exactly match.  Check no wildcard character.
       
  1600                 if (thisSubAltName.equalsIgnoreCase(prevSubAltName)) {
       
  1601                     return true;
       
  1602                 }
       
  1603             }
       
  1604         }
       
  1605 
       
  1606         return false;
  1563     }
  1607     }
  1564 }
  1608 }