]> git.ipfire.org Git - thirdparty/openssl.git/blobdiff - crypto/x509/x509_vfy.c
Add X509 version constants.
[thirdparty/openssl.git] / crypto / x509 / x509_vfy.c
index 58598bbf1f39cca66f41e1b3c952d5a07053dfec..4e6ce11f4efddd5146b9411846ce7bc610861187 100644 (file)
@@ -46,7 +46,7 @@ static int dane_verify(X509_STORE_CTX *ctx);
 static int null_callback(int ok, X509_STORE_CTX *e);
 static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
 static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x);
-static int check_chain(X509_STORE_CTX *ctx);
+static int check_extensions(X509_STORE_CTX *ctx);
 static int check_name_constraints(X509_STORE_CTX *ctx);
 static int check_id(X509_STORE_CTX *ctx);
 static int check_trust(X509_STORE_CTX *ctx, int num_untrusted);
@@ -85,7 +85,7 @@ static int null_callback(int ok, X509_STORE_CTX *e)
 /*-
  * Return 1 if given cert is considered self-signed, 0 if not, or -1 on error.
  * This actually verifies self-signedness only if requested.
- * It calls X509v3_cache_extensions()
+ * It calls ossl_x509v3_cache_extensions()
  * to match issuer and subject names (i.e., the cert being self-issued) and any
  * present authority key identifier to match the subject key identifier, etc.
  */
@@ -97,7 +97,7 @@ int X509_self_signed(X509 *cert, int verify_signature)
         ERR_raise(ERR_LIB_X509, X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY);
         return -1;
     }
-    if (!x509v3_cache_extensions(cert))
+    if (!ossl_x509v3_cache_extensions(cert))
         return -1;
     if ((cert->ex_flags & EXFLAG_SS) == 0)
         return 0;
@@ -213,7 +213,7 @@ static int verify_chain(X509_STORE_CTX *ctx)
     int ok;
 
     if ((ok = build_chain(ctx)) <= 0
-        || (ok = check_chain(ctx)) <= 0
+        || (ok = check_extensions(ctx)) <= 0
         || (ok = check_auth_level(ctx)) <= 0
         || (ok = check_id(ctx)) <= 0
         || (ok = X509_get_pubkey_parameters(NULL, ctx->chain) ? 1 : -1) <= 0
@@ -281,7 +281,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
         return -1;
     }
 
-    if (!X509_add_cert_new(&ctx->chain, ctx->cert, X509_ADD_FLAG_UP_REF)) {
+    if (!ossl_x509_add_cert_new(&ctx->chain, ctx->cert, X509_ADD_FLAG_UP_REF)) {
         ctx->error = X509_V_ERR_OUT_OF_MEM;
         return -1;
     }
@@ -329,7 +329,7 @@ static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x)
         if (ctx->check_issued(ctx, x, issuer)
             && (((x->ex_flags & EXFLAG_SI) != 0 && sk_X509_num(ctx->chain) == 1)
                 || !sk_X509_contains(ctx->chain, issuer))) {
-            if (x509_check_cert_time(ctx, issuer, -1))
+            if (ossl_x509_check_cert_time(ctx, issuer, -1))
                 return issuer;
             if (rv == NULL || ASN1_TIME_compare(X509_get0_notAfter(issuer),
                                                 X509_get0_notAfter(rv)) > 0)
@@ -342,7 +342,7 @@ static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x)
 /* Check that the given certificate 'x' is issued by the certificate 'issuer' */
 static int check_issued(ossl_unused X509_STORE_CTX *ctx, X509 *x, X509 *issuer)
 {
-    int err = x509_likely_issued(issuer, x);
+    int err = ossl_x509_likely_issued(issuer, x);
 
     if (err == X509_V_OK)
         return 1;
@@ -352,7 +352,7 @@ static int check_issued(ossl_unused X509_STORE_CTX *ctx, X509 *x, X509 *issuer)
      */
     if (err != X509_V_ERR_SUBJECT_ISSUER_MISMATCH)
         ctx->error = err;
-    return 0; /* Better call verify_cb_cert(ctx, x, ctx->error_depth, err) ? */
+    return 0;
 }
 
 /*
@@ -446,7 +446,7 @@ static int check_purpose(X509_STORE_CTX *ctx, X509 *x, int purpose, int depth,
  * Check extensions of a cert chain for consistency with the supplied purpose.
  * Sadly, returns 0 also on internal error.
  */
-static int check_chain(X509_STORE_CTX *ctx)
+static int check_extensions(X509_STORE_CTX *ctx)
 {
     int i, must_be_ca, plen = 0;
     X509 *x;
@@ -562,7 +562,7 @@ static int check_chain(X509_STORE_CTX *ctx)
             CB_FAIL_IF(x->skid != NULL
                            && (x->ex_flags & EXFLAG_SKID_CRITICAL) != 0,
                        ctx, x, i, X509_V_ERR_SUBJECT_KEY_IDENTIFIER_CRITICAL);
-            if (X509_get_version(x) >= 2) { /* at least X.509v3 */
+            if (X509_get_version(x) >= X509_VERSION_3) {
                 /* Check AKID presence acc. to RFC 5280 section 4.2.1.1 */
                 CB_FAIL_IF(i + 1 < num /*
                                         * this means not last cert in chain,
@@ -1701,7 +1701,7 @@ static int check_policy(X509_STORE_CTX *ctx)
  *
  * Return 1 on success, 0 otherwise.
  */
-int x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth)
+int ossl_x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth)
 {
     time_t *ptime;
     int i;
@@ -1745,7 +1745,7 @@ static int internal_verify(X509_STORE_CTX *ctx)
          * We report the issuer as NULL because all we have is a bare key.
          */
         xi = NULL;
-    } else if (x509_likely_issued(xi, xi) != X509_V_OK
+    } else if (ossl_x509_likely_issued(xi, xi) != X509_V_OK
                /* exceptional case: last cert in the chain is not self-issued */
                && ((ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) == 0)) {
         if (n > 0) {
@@ -1804,7 +1804,7 @@ static int internal_verify(X509_STORE_CTX *ctx)
              * we are free to ignore any key usage restrictions on such certs.
              */
             int ret = xs == xi && (xi->ex_flags & EXFLAG_CA) == 0
-                ? X509_V_OK : x509_signing_allowed(xi, xs);
+                ? X509_V_OK : ossl_x509_signing_allowed(xi, xs);
 
             CB_FAIL_IF(ret != X509_V_OK, ctx, xi, issuer_depth, ret);
             if ((pkey = X509_get0_pubkey(xi)) == NULL) {
@@ -1818,7 +1818,7 @@ static int internal_verify(X509_STORE_CTX *ctx)
 
         /* in addition to RFC 5280, do also for trusted (root) cert */
         /* Calls verify callback as needed */
-        if (!x509_check_cert_time(ctx, xs, n))
+        if (!ossl_x509_check_cert_time(ctx, xs, n))
             return 0;
 
         /*
@@ -1886,7 +1886,7 @@ int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
      * Digit and date ranges will be verified in the conversion methods.
      */
     for (i = 0; i < ctm->length - 1; i++) {
-        if (!ascii_isdigit(ctm->data[i]))
+        if (!ossl_ascii_isdigit(ctm->data[i]))
             return 0;
     }
     if (ctm->data[ctm->length - 1] != upper_z)
@@ -2052,8 +2052,8 @@ X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
         return NULL;
     }
     /* Create new CRL */
-    crl = X509_CRL_new();
-    if (crl == NULL || !X509_CRL_set_version(crl, 1))
+    crl = X509_CRL_new_ex(base->libctx, base->propq);
+    if (crl == NULL || !X509_CRL_set_version(crl, X509_CRL_VERSION_2))
         goto memerr;
     /* Set issuer name */
     if (!X509_CRL_set_issuer_name(crl, X509_CRL_get_issuer(newer)))
@@ -3033,22 +3033,11 @@ static int build_chain(X509_STORE_CTX *ctx)
 
     /*
      * If we got any "DANE-TA(2) Cert(0) Full(0)" trust anchors from DNS, add
-     * them to our working copy of the untrusted certificate stack.  Since the
-     * caller of X509_STORE_CTX_init() may have provided only a leaf cert with
-     * no corresponding stack of untrusted certificates, we may need to create
-     * an empty stack first.  [ At present only the ssl library provides DANE
-     * support, and ssl_verify_cert_chain() always provides a non-null stack
-     * containing at least the leaf certificate, but we must be prepared for
-     * this to change. ]
+     * them to our working copy of the untrusted certificate stack.
      */
-    if (DANETLS_ENABLED(dane) && dane->certs != NULL) {
-        if (sk_untrusted == NULL && (sk_untrusted = sk_X509_new_null()) == NULL)
-            goto memerr;
-        if (!X509_add_certs(sk_untrusted, dane->certs, X509_ADD_FLAG_DEFAULT)) {
-            sk_X509_free(sk_untrusted);
-            goto memerr;
-        }
-    }
+    if (DANETLS_ENABLED(dane) && dane->certs != NULL
+        && !X509_add_certs(sk_untrusted, dane->certs, X509_ADD_FLAG_DEFAULT))
+        goto memerr;
 
     /*
      * Still absurdly large, but arithmetically safe, a lower hard upper bound
@@ -3293,10 +3282,17 @@ static int build_chain(X509_STORE_CTX *ctx)
         return 0;
     case X509_TRUST_UNTRUSTED:
     default:
-        if (ctx->error != X509_V_OK)
-            /* Callback already issued in most such cases */
-            return 0;
-        num = sk_X509_num(ctx->chain);
+        switch(ctx->error) {
+        case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+        case X509_V_ERR_CERT_NOT_YET_VALID:
+        case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+        case X509_V_ERR_CERT_HAS_EXPIRED:
+            return 0; /* Callback already issued by ossl_x509_check_cert_time() */
+        default: /* A preliminary error has become final */
+            return verify_cb_cert(ctx, NULL, num - 1, ctx->error);
+        case X509_V_OK:
+            break;
+        }
         CB_FAIL_IF(num > depth,
                    ctx, NULL, num - 1, X509_V_ERR_CERT_CHAIN_TOO_LONG);
         CB_FAIL_IF(DANETLS_ENABLED(dane)
@@ -3314,17 +3310,60 @@ static int build_chain(X509_STORE_CTX *ctx)
     }
 
  int_err:
-    sk_X509_free(sk_untrusted);
     ERR_raise(ERR_LIB_X509, ERR_R_INTERNAL_ERROR);
     ctx->error = X509_V_ERR_UNSPECIFIED;
+    sk_X509_free(sk_untrusted);
     return -1;
 
  memerr:
     ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
     ctx->error = X509_V_ERR_OUT_OF_MEM;
+    sk_X509_free(sk_untrusted);
     return -1;
 }
 
+STACK_OF(X509) *X509_build_chain(X509 *target, STACK_OF(X509) *certs,
+                                 X509_STORE *store, int with_self_signed,
+                                 OSSL_LIB_CTX *libctx, const char *propq)
+{
+    int finish_chain = store != NULL;
+    X509_STORE_CTX *ctx;
+    int flags = X509_ADD_FLAG_UP_REF;
+    STACK_OF(X509) *result = NULL;
+
+    if (target == NULL) {
+        ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
+        return NULL;
+    }
+
+    if ((ctx = X509_STORE_CTX_new_ex(libctx, propq)) == NULL)
+        return NULL;
+    if (!X509_STORE_CTX_init(ctx, store, target, finish_chain ? certs : NULL))
+        goto err;
+    if (!finish_chain)
+        X509_STORE_CTX_set0_trusted_stack(ctx, certs);
+    if (!ossl_x509_add_cert_new(&ctx->chain, target, X509_ADD_FLAG_UP_REF)) {
+        ctx->error = X509_V_ERR_OUT_OF_MEM;
+        goto err;
+    }
+    ctx->num_untrusted = 1;
+
+    if (!build_chain(ctx) && finish_chain)
+        goto err;
+
+    /* result list to store the up_ref'ed certificates */
+    if (sk_X509_num(ctx->chain) > 1 && !with_self_signed)
+        flags |= X509_ADD_FLAG_NO_SS;
+    if (!ossl_x509_add_certs_new(&result, ctx->chain, flags)) {
+        sk_X509_free(result);
+        result = NULL;
+    }
+
+ err:
+    X509_STORE_CTX_free(ctx);
+    return result;
+}
+
 static const int minbits_table[] = { 80, 112, 128, 192, 256 };
 static const int NUM_AUTH_LEVELS = OSSL_NELEM(minbits_table);