Constify ...
[oweals/openssl.git] / crypto / x509 / x509_vfy.c
index 360664a81353d63c54dd529e3b97907218adb149..2a157021dd39e7d3d03da50e3ca50e4b8ce25ff5 100644 (file)
@@ -461,12 +461,6 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
     } else {
         allow_proxy_certs =
             ! !(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
-        /*
-         * A hack to keep people who don't want to modify their software
-         * happy
-         */
-        if (getenv("OPENSSL_ALLOW_PROXY_CERTS"))
-            allow_proxy_certs = 1;
         purpose = ctx->param->purpose;
     }
 
@@ -533,10 +527,24 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
          * the next certificate must be a CA certificate.
          */
         if (x->ex_flags & EXFLAG_PROXY) {
-            if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen) {
-                if (!verify_cb_cert(ctx, x, i,
-                                    X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED))
-                    return 0;
+            /*
+             * RFC3820, 4.1.3 (b)(1) stipulates that if pCPathLengthConstraint
+             * is less than max_path_length, the former should be copied to
+             * the latter, and 4.1.4 (a) stipulates that max_path_length
+             * should be verified to be larger than zero and decrement it.
+             *
+             * Because we're checking the certs in the reverse order, we start
+             * with verifying that proxy_path_length isn't larger than pcPLC,
+             * and copy the latter to the former if it is, and finally,
+             * increment proxy_path_length.
+             */
+            if (x->ex_pcpathlen != -1) {
+                if (proxy_path_length > x->ex_pcpathlen) {
+                    if (!verify_cb_cert(ctx, x, i,
+                                        X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED))
+                        return 0;
+                }
+                proxy_path_length = x->ex_pcpathlen;
             }
             proxy_path_length++;
             must_be_ca = 0;
@@ -643,6 +651,10 @@ static int check_name_constraints(X509_STORE_CTX *ctx)
             if (nc) {
                 int rv = NAME_CONSTRAINTS_check(x, nc);
 
+                /* If EE certificate check commonName too */
+                if (rv == X509_V_OK && i == 0)
+                    rv = NAME_CONSTRAINTS_check_CN(x, nc);
+
                 switch (rv) {
                 case X509_V_OK:
                     break;
@@ -959,13 +971,21 @@ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
         crl = sk_X509_CRL_value(crls, i);
         reasons = *preasons;
         crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x);
-
-        if (crl_score > best_score) {
-            best_crl = crl;
-            best_crl_issuer = crl_issuer;
-            best_score = crl_score;
-            best_reasons = reasons;
+        if (crl_score < best_score)
+            continue;
+        /* If current CRL is equivalent use it if it is newer */
+        if (crl_score == best_score) {
+            int day, sec;
+            if (ASN1_TIME_diff(&day, &sec, X509_CRL_get_lastUpdate(best_crl),
+                               X509_CRL_get_lastUpdate(crl)) == 0)
+                continue;
+            if (day < 0 || sec <= 0)
+                continue;
         }
+        best_crl = crl;
+        best_crl_issuer = crl_issuer;
+        best_score = crl_score;
+        best_reasons = reasons;
     }
 
     if (best_crl) {
@@ -2524,7 +2544,7 @@ static int dane_match(X509_STORE_CTX *ctx, X509 *cert, int depth)
 
     /*
      * If we've previously matched a PKIX-?? record, no need to test any
-     * further PKIX-?? records,  it remains to just build the PKIX chain.
+     * further PKIX-?? records, it remains to just build the PKIX chain.
      * Had the match been a DANE-?? record, we'd be done already.
      */
     if (dane->mdpth >= 0)
@@ -2753,6 +2773,10 @@ static int dane_verify(X509_STORE_CTX *ctx)
         /* Callback invoked as needed */
         if (!check_leaf_suiteb(ctx, cert))
             return 0;
+        /* Callback invoked as needed */
+        if ((dane->flags & DANE_FLAG_NO_DANE_EE_NAMECHECKS) == 0 &&
+            !check_id(ctx))
+            return 0;
         /* Bypass internal_verify(), issue depth 0 success callback */
         ctx->error_depth = 0;
         ctx->current_cert = cert;