< prev index next >

src/share/classes/sun/security/x509/NameConstraintsExtension.java

Print this page
rev 12538 : 8178714: PKIX validator nameConstraints check failing after change 8175940
Reviewed-by: mullan, ahgross

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this

@@ -31,10 +31,11 @@
 import java.security.cert.X509Certificate;
 import java.util.*;
 
 import javax.security.auth.x500.X500Principal;
 
+import sun.net.util.IPAddressUtil;
 import sun.security.util.*;
 import sun.security.pkcs.PKCS9Attribute;
 
 /**
  * This class defines the Name Constraints Extension.

@@ -431,10 +432,11 @@
         }
 
         X500Principal subjectPrincipal = cert.getSubjectX500Principal();
         X500Name subject = X500Name.asX500Name(subjectPrincipal);
 
+        // Check subject as an X500Name
         if (subject.isEmpty() == false) {
             if (verify(subject) == false) {
                 return false;
             }
         }

@@ -456,16 +458,55 @@
         } catch (CertificateException ce) {
             throw new IOException("Unable to extract extensions from " +
                         "certificate: " + ce.getMessage());
         }
 
-        // If there are no subjectAlternativeNames, perform the special-case
-        // check where if the subjectName contains any EMAILADDRESS
-        // attributes, they must be checked against RFC822 constraints.
-        // If that passes, we're fine.
         if (altNames == null) {
-            return verifyRFC822SpecialCase(subject);
+            altNames = new GeneralNames();
+
+            // RFC 5280 4.2.1.10:
+            // When constraints are imposed on the rfc822Name name form,
+            // but the certificate does not include a subject alternative name,
+            // the rfc822Name constraint MUST be applied to the attribute of
+            // type emailAddress in the subject distinguished name.
+            for (AVA ava : subject.allAvas()) {
+                ObjectIdentifier attrOID = ava.getObjectIdentifier();
+                if (attrOID.equals(PKCS9Attribute.EMAIL_ADDRESS_OID)) {
+                    String attrValue = ava.getValueString();
+                    if (attrValue != null) {
+                        try {
+                            altNames.add(new GeneralName(
+                                    new RFC822Name(attrValue)));
+                        } catch (IOException ioe) {
+                            continue;
+                        }
+                    }
+                }
+            }
+        }
+
+        // If there is no IPAddressName or DNSName in subjectAlternativeNames,
+        // see if the last CN inside subjectName can be used instead.
+        DerValue derValue = subject.findMostSpecificAttribute
+                (X500Name.commonName_oid);
+        String cn = derValue == null ? null : derValue.getAsString();
+
+        if (cn != null) {
+            try {
+                if (IPAddressUtil.isIPv4LiteralAddress(cn) ||
+                        IPAddressUtil.isIPv6LiteralAddress(cn)) {
+                    if (!hasNameType(altNames, GeneralNameInterface.NAME_IP)) {
+                        altNames.add(new GeneralName(new IPAddressName(cn)));
+                    }
+                } else {
+                    if (!hasNameType(altNames, GeneralNameInterface.NAME_DNS)) {
+                        altNames.add(new GeneralName(new DNSName(cn)));
+                    }
+                }
+            } catch (IOException ioe) {
+                // OK, cn is neither IP nor DNS
+            }
         }
 
         // verify each subjectAltName
         for (int i = 0; i < altNames.size(); i++) {
             GeneralNameInterface altGNI = altNames.get(i).getName();

@@ -476,10 +517,19 @@
 
         // All tests passed.
         return true;
     }
 
+    private static boolean hasNameType(GeneralNames names, int type) {
+        for (GeneralName name : names.names()) {
+            if (name.getType() == type) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * check whether a name conforms to these NameConstraints.
      * This involves verifying that the name is consistent with the
      * permitted and excluded subtrees variables.
      *

@@ -558,41 +608,10 @@
         }
         return true;
     }
 
     /**
-     * Perform the RFC 822 special case check. We have a certificate
-     * that does not contain any subject alternative names. Check that
-     * any EMAILADDRESS attributes in its subject name conform to these
-     * NameConstraints.
-     *
-     * @param subject the certificate's subject name
-     * @returns true if certificate verifies successfully
-     * @throws IOException on error
-     */
-    public boolean verifyRFC822SpecialCase(X500Name subject) throws IOException {
-        for (AVA ava : subject.allAvas()) {
-            ObjectIdentifier attrOID = ava.getObjectIdentifier();
-            if (attrOID.equals((Object)PKCS9Attribute.EMAIL_ADDRESS_OID)) {
-                String attrValue = ava.getValueString();
-                if (attrValue != null) {
-                    RFC822Name emailName;
-                    try {
-                        emailName = new RFC822Name(attrValue);
-                    } catch (IOException ioe) {
-                        continue;
-                    }
-                    if (!verify(emailName)) {
-                        return(false);
-                    }
-                }
-             }
-        }
-        return true;
-    }
-
-    /**
      * Clone all objects that may be modified during certificate validation.
      */
     public Object clone() {
         try {
             NameConstraintsExtension newNCE =
< prev index next >