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);
/*-
* 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.
*/
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;
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
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;
}
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)
/* 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;
*/
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;
}
/*
* 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;
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,
*
* 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;
* 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) {
* 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) {
/* 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;
/*
* 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)
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)))
/*
* 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
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)
}
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);