mark all block comments that need format preserving so that
[openssl.git] / crypto / x509v3 / v3_purp.c
index 181bd34979bc5ed1709fb62849e3c78155411214..8e0a685d19d82387e2df3932f35ac8375c236ff1 100644 (file)
@@ -368,9 +368,6 @@ static void x509v3_cache_extensions(X509 *x)
 #ifndef OPENSSL_NO_SHA
        X509_digest(x, EVP_sha1(), x->sha1_hash, NULL);
 #endif
-       /* Does subject name match issuer ? */
-       if(!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x)))
-                        x->ex_flags |= EXFLAG_SI;
        /* V1 should mean no extensions ... */
        if(!X509_get_version(x)) x->ex_flags |= EXFLAG_V1;
        /* Handle basic constraints */
@@ -389,8 +386,8 @@ static void x509v3_cache_extensions(X509 *x)
        /* Handle proxy certificates */
        if((pci=X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) {
                if (x->ex_flags & EXFLAG_CA
-                   || X509_get_ext_by_NID(x, NID_subject_alt_name, 0) >= 0
-                   || X509_get_ext_by_NID(x, NID_issuer_alt_name, 0) >= 0) {
+                   || X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0
+                   || X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) {
                        x->ex_flags |= EXFLAG_INVALID;
                }
                if (pci->pcPathLengthConstraint) {
@@ -447,6 +444,10 @@ static void x509v3_cache_extensions(X509 *x)
                                case NID_dvcs:
                                x->ex_xkusage |= XKU_DVCS;
                                break;
+
+                               case NID_anyExtendedKeyUsage:
+                               x->ex_xkusage |= XKU_ANYEKU;
+                               break;
                        }
                }
                sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
@@ -460,6 +461,14 @@ static void x509v3_cache_extensions(X509 *x)
        }
        x->skid =X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL);
        x->akid =X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL);
+       /* Does subject name match issuer ? */
+       if(!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x)))
+                       {
+                       x->ex_flags |= EXFLAG_SI;
+                       /* If SKID matches AKID also indicate self signed */
+                       if (X509_check_akid(x, x->akid) == X509_V_OK)
+                               x->ex_flags |= EXFLAG_SS;
+                       }
        x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
        x->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL);
        if (!x->nc && (i != -1))
@@ -474,11 +483,11 @@ static void x509v3_cache_extensions(X509 *x)
        for (i = 0; i < X509_get_ext_count(x); i++)
                {
                ex = X509_get_ext(x, i);
-               if (!X509_EXTENSION_get_critical(ex))
-                       continue;
                if (OBJ_obj2nid(X509_EXTENSION_get_object(ex))
                                        == NID_freshest_crl)
                        x->ex_flags |= EXFLAG_FRESHEST;
+               if (!X509_EXTENSION_get_critical(ex))
+                       continue;
                if (!X509_supported_extension(ex))
                        {
                        x->ex_flags |= EXFLAG_CRITICAL;
@@ -488,7 +497,8 @@ static void x509v3_cache_extensions(X509 *x)
        x->ex_flags |= EXFLAG_SET;
 }
 
-/* CA checks common to all purposes
+/*-
+ * CA checks common to all purposes
  * return codes:
  * 0 not a CA
  * 1 is a CA
@@ -553,12 +563,18 @@ static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int c
 {
        if(xku_reject(x,XKU_SSL_CLIENT)) return 0;
        if(ca) return check_ssl_ca(x);
-       /* We need to do digital signatures with it */
-       if(ku_reject(x,KU_DIGITAL_SIGNATURE)) return 0;
+       /* We need to do digital signatures or key agreement */
+       if(ku_reject(x,KU_DIGITAL_SIGNATURE|KU_KEY_AGREEMENT)) return 0;
        /* nsCertType if present should allow SSL client use */ 
        if(ns_reject(x, NS_SSL_CLIENT)) return 0;
        return 1;
 }
+/* Key usage needed for TLS/SSL server: digital signature, encipherment or
+ * key agreement. The ssl code can check this more thoroughly for individual
+ * key types.
+ */
+#define KU_TLS \
+       KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT|KU_KEY_AGREEMENT
 
 static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca)
 {
@@ -566,8 +582,7 @@ static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int c
        if(ca) return check_ssl_ca(x);
 
        if(ns_reject(x, NS_SSL_SERVER)) return 0;
-       /* Now as for keyUsage: we'll at least need to sign OR encipher */
-       if(ku_reject(x, KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT)) return 0;
+       if(ku_reject(x, KU_TLS)) return 0;
        
        return 1;
 
@@ -670,7 +685,7 @@ static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
                return 0;
 
        /* Extended Key Usage MUST be critical */
-       i_ext = X509_get_ext_by_NID((X509 *) x, NID_ext_key_usage, 0);
+       i_ext = X509_get_ext_by_NID((X509 *) x, NID_ext_key_usage, -1);
        if (i_ext >= 0)
                {
                X509_EXTENSION *ext = X509_get_ext((X509 *) x, i_ext);
@@ -686,7 +701,8 @@ static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca)
        return 1;
 }
 
-/* Various checks to see if one certificate issued the second.
+/*-
+ * Various checks to see if one certificate issued the second.
  * This can be used to prune a set of possible issuer certificates
  * which have been looked up using some simple method such as by
  * subject name.