提交 b9b979b1 编写于 作者: R robm

8072385: Only the first DNSName entry is checked for endpoint identification

Reviewed-by: xuelei
上级 3df95fba
...@@ -59,6 +59,10 @@ import static sun.security.ssl.CipherSuite.KeyExchange.*; ...@@ -59,6 +59,10 @@ import static sun.security.ssl.CipherSuite.KeyExchange.*;
*/ */
final class ClientHandshaker extends Handshaker { 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. // the server's public key from its certificate.
private PublicKey serverKey; private PublicKey serverKey;
...@@ -1502,20 +1506,49 @@ final class ClientHandshaker extends Handshaker { ...@@ -1502,20 +1506,49 @@ final class ClientHandshaker extends Handshaker {
return true; return true;
} }
// check the iPAddress field in subjectAltName extension // check subject alternative names
Object thisIPAddress = getSubjectAltName(thisCert, 7); // 7: iPAddress Collection<List<?>> thisSubjectAltNames = null;
Object prevIPAddress = getSubjectAltName(prevCert, 7); try {
if (thisIPAddress != null && prevIPAddress!= null) { thisSubjectAltNames = thisCert.getSubjectAlternativeNames();
// only allow the exactly match } catch (CertificateParsingException cpe) {
return Objects.equals(thisIPAddress, prevIPAddress); if (debug != null && Debug.isOn("handshake")) {
System.out.println(
"Attempt to obtain subjectAltNames extension failed!");
}
} }
// check the dNSName field in subjectAltName extension Collection<List<?>> prevSubjectAltNames = null;
Object thisDNSName = getSubjectAltName(thisCert, 2); // 2: dNSName try {
Object prevDNSName = getSubjectAltName(prevCert, 2); prevSubjectAltNames = prevCert.getSubjectAlternativeNames();
if (thisDNSName != null && prevDNSName!= null) { } catch (CertificateParsingException cpe) {
// only allow the exactly match if (debug != null && Debug.isOn("handshake")) {
return Objects.equals(thisDNSName, prevDNSName); 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 // check the certificate subject and issuer
...@@ -1536,29 +1569,43 @@ final class ClientHandshaker extends Handshaker { ...@@ -1536,29 +1569,43 @@ final class ClientHandshaker extends Handshaker {
/* /*
* Returns the subject alternative name of the specified type in the * Returns the subject alternative name of the specified type in the
* subjectAltNames extension of a certificate. * 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) { private static Collection<String> getSubjectAltNames(
Collection<List<?>> subjectAltNames; Collection<List<?>> subjectAltNames, int type) {
try { HashSet<String> subAltDnsNames = null;
subjectAltNames = cert.getSubjectAlternativeNames(); for (List<?> subjectAltName : subjectAltNames) {
} catch (CertificateParsingException cpe) { int subjectAltNameType = (Integer)subjectAltName.get(0);
if (debug != null && Debug.isOn("handshake")) { if (subjectAltNameType == type) {
System.out.println( String subAltDnsName = (String)subjectAltName.get(1);
"Attempt to obtain subjectAltNames extension failed!"); if ((subAltDnsName != null) && !subAltDnsName.isEmpty()) {
if (subAltDnsNames == null) {
subAltDnsNames =
new HashSet<>(subjectAltNames.size());
}
subAltDnsNames.add(subAltDnsName);
}
} }
return null;
} }
if (subjectAltNames != null) { return subAltDnsNames;
for (List<?> subjectAltName : subjectAltNames) { }
int subjectAltNameType = (Integer)subjectAltName.get(0);
if (subjectAltNameType == type) { private static boolean isEquivalent(Collection<String> thisSubAltNames,
return subjectAltName.get(1); 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 null; return false;
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册