diff options
author | Shane Lontis <shane.lontis@oracle.com> | 2020-07-24 22:53:27 +1000 |
---|---|---|
committer | Shane Lontis <shane.lontis@oracle.com> | 2020-07-24 22:53:27 +1000 |
commit | 6725682d77510bf6d499957897d7be124d603f40 (patch) | |
tree | 447e5bce5607b4873f7f018df1b2e4c21a394e92 /crypto/x509 | |
parent | ae89578be2930c726d6ef56451233757a89f224f (diff) | |
download | openssl-6725682d77510bf6d499957897d7be124d603f40.tar.gz |
Add X509 related libctx changes.
- In order to not add many X509_XXXX_with_libctx() functions the libctx and propq may be stored in the X509 object via a call to X509_new_with_libctx().
- Loading via PEM_read_bio_X509() or d2i_X509() should pass in a created cert using X509_new_with_libctx().
- Renamed some XXXX_ex() to XXX_with_libctx() for X509 API's.
- Removed the extra parameters in check_purpose..
- X509_digest() has been modified so that it expects a const EVP_MD object() and then internally it does the fetch when it needs to (via ASN1_item_digest_with_libctx()).
- Added API's that set the libctx when they load such as X509_STORE_new_with_libctx() so that the cert chains can be verified.
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/12153)
Diffstat (limited to 'crypto/x509')
-rw-r--r-- | crypto/x509/by_dir.c | 56 | ||||
-rw-r--r-- | crypto/x509/by_file.c | 95 | ||||
-rw-r--r-- | crypto/x509/by_store.c | 42 | ||||
-rw-r--r-- | crypto/x509/v3_purp.c | 31 | ||||
-rw-r--r-- | crypto/x509/x509_d2.c | 48 | ||||
-rw-r--r-- | crypto/x509/x509_local.h | 9 | ||||
-rw-r--r-- | crypto/x509/x509_lu.c | 53 | ||||
-rw-r--r-- | crypto/x509/x509_vfy.c | 30 | ||||
-rw-r--r-- | crypto/x509/x_all.c | 31 | ||||
-rw-r--r-- | crypto/x509/x_x509.c | 31 |
10 files changed, 276 insertions, 150 deletions
diff --git a/crypto/x509/by_dir.c b/crypto/x509/by_dir.c index 43b175e2dc..ff6e4cf03c 100644 --- a/crypto/x509/by_dir.c +++ b/crypto/x509/by_dir.c @@ -42,23 +42,32 @@ typedef struct lookup_dir_st { } BY_DIR; static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, - char **ret); + char **retp); + static int new_dir(X509_LOOKUP *lu); static void free_dir(X509_LOOKUP *lu); static int add_cert_dir(BY_DIR *ctx, const char *dir, int type); static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, const X509_NAME *name, X509_OBJECT *ret); +static int get_cert_by_subject_with_libctx(X509_LOOKUP *xl, + X509_LOOKUP_TYPE type, + const X509_NAME *name, + X509_OBJECT *ret, + OPENSSL_CTX *libctx, + const char *propq); static X509_LOOKUP_METHOD x509_dir_lookup = { "Load certs from files in a directory", - new_dir, /* new_item */ - free_dir, /* free */ - NULL, /* init */ - NULL, /* shutdown */ - dir_ctrl, /* ctrl */ - get_cert_by_subject, /* get_by_subject */ - NULL, /* get_by_issuer_serial */ - NULL, /* get_by_fingerprint */ - NULL, /* get_by_alias */ + new_dir, /* new_item */ + free_dir, /* free */ + NULL, /* init */ + NULL, /* shutdown */ + dir_ctrl, /* ctrl */ + get_cert_by_subject, /* get_by_subject */ + NULL, /* get_by_issuer_serial */ + NULL, /* get_by_fingerprint */ + NULL, /* get_by_alias */ + get_cert_by_subject_with_libctx, /* get_by_subject_with_libctx */ + NULL, /* ctrl_with_libctx */ }; X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void) @@ -210,8 +219,12 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) return 1; } -static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, - const X509_NAME *name, X509_OBJECT *ret) +static int get_cert_by_subject_with_libctx(X509_LOOKUP *xl, + X509_LOOKUP_TYPE type, + const X509_NAME *name, + X509_OBJECT *ret, + OPENSSL_CTX *libctx, + const char *propq) { BY_DIR *ctx; union { @@ -238,12 +251,12 @@ static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, stmp.data.crl = &data.crl; postfix = "r"; } else { - X509err(X509_F_GET_CERT_BY_SUBJECT, X509_R_WRONG_LOOKUP_TYPE); + X509err(0, X509_R_WRONG_LOOKUP_TYPE); goto finish; } if ((b = BUF_MEM_new()) == NULL) { - X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_BUF_LIB); + X509err(0, ERR_R_BUF_LIB); goto finish; } @@ -258,7 +271,7 @@ static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i); j = strlen(ent->dir) + 1 + 8 + 6 + 1 + 1; if (!BUF_MEM_grow(b, j)) { - X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE); + X509err(0, ERR_R_MALLOC_FAILURE); goto finish; } if (type == X509_LU_CRL && ent->hashes) { @@ -316,7 +329,8 @@ static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, #endif /* found one. */ if (type == X509_LU_X509) { - if ((X509_load_cert_file(xl, b->data, ent->dir_type)) == 0) + if ((X509_load_cert_file_with_libctx(xl, b->data, ent->dir_type, + libctx, propq)) == 0) break; } else if (type == X509_LU_CRL) { if ((X509_load_crl_file(xl, b->data, ent->dir_type)) == 0) @@ -351,7 +365,7 @@ static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, hent = OPENSSL_malloc(sizeof(*hent)); if (hent == NULL) { CRYPTO_THREAD_unlock(ctx->lock); - X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE); + X509err(0, ERR_R_MALLOC_FAILURE); ok = 0; goto finish; } @@ -360,7 +374,7 @@ static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) { CRYPTO_THREAD_unlock(ctx->lock); OPENSSL_free(hent); - X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE); + X509err(0, ERR_R_MALLOC_FAILURE); ok = 0; goto finish; } @@ -390,3 +404,9 @@ static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, BUF_MEM_free(b); return ok; } + +static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, + const X509_NAME *name, X509_OBJECT *ret) +{ + return get_cert_by_subject_with_libctx(xl, type, name, ret, NULL, NULL); +} diff --git a/crypto/x509/by_file.c b/crypto/x509/by_file.c index f9e1e73fc4..d5e6dde4f8 100644 --- a/crypto/x509/by_file.c +++ b/crypto/x509/by_file.c @@ -21,6 +21,11 @@ DEFINE_STACK_OF(X509_INFO) static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **ret); +static int by_file_ctrl_with_libctx(X509_LOOKUP *ctx, int cmd, + const char *argc, long argl, char **ret, + OPENSSL_CTX *libctx, const char *propq); + + static X509_LOOKUP_METHOD x509_file_lookup = { "Load file into cache", NULL, /* new_item */ @@ -32,6 +37,8 @@ static X509_LOOKUP_METHOD x509_file_lookup = { NULL, /* get_by_issuer_serial */ NULL, /* get_by_fingerprint */ NULL, /* get_by_alias */ + NULL, /* get_by_subject_with_libctx */ + by_file_ctrl_with_libctx, /* ctrl_with_libctx */ }; X509_LOOKUP_METHOD *X509_LOOKUP_file(void) @@ -39,8 +46,9 @@ X509_LOOKUP_METHOD *X509_LOOKUP_file(void) return &x509_file_lookup; } -static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, - long argl, char **ret) +static int by_file_ctrl_with_libctx(X509_LOOKUP *ctx, int cmd, + const char *argp, long argl, char **ret, + OPENSSL_CTX *libctx, const char *propq) { int ok = 0; const char *file; @@ -50,30 +58,40 @@ static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, if (argl == X509_FILETYPE_DEFAULT) { file = ossl_safe_getenv(X509_get_default_cert_file_env()); if (file) - ok = (X509_load_cert_crl_file(ctx, file, - X509_FILETYPE_PEM) != 0); + ok = (X509_load_cert_crl_file_with_libctx(ctx, file, + X509_FILETYPE_PEM, + libctx, propq) != 0); else - ok = (X509_load_cert_crl_file - (ctx, X509_get_default_cert_file(), - X509_FILETYPE_PEM) != 0); + ok = (X509_load_cert_crl_file_with_libctx( + ctx, X509_get_default_cert_file(), + X509_FILETYPE_PEM, libctx, propq) != 0); if (!ok) { - X509err(X509_F_BY_FILE_CTRL, X509_R_LOADING_DEFAULTS); + X509err(0, X509_R_LOADING_DEFAULTS); } } else { if (argl == X509_FILETYPE_PEM) - ok = (X509_load_cert_crl_file(ctx, argp, - X509_FILETYPE_PEM) != 0); + ok = (X509_load_cert_crl_file_with_libctx(ctx, argp, + X509_FILETYPE_PEM, + libctx, propq) != 0); else - ok = (X509_load_cert_file(ctx, argp, (int)argl) != 0); + ok = (X509_load_cert_file_with_libctx(ctx, argp, (int)argl, + libctx, propq) != 0); } break; } return ok; } -int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) +static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, + const char *argp, long argl, char **ret) +{ + return by_file_ctrl_with_libctx(ctx, cmd, argp, argl, ret, NULL, NULL); +} + +int X509_load_cert_file_with_libctx(X509_LOOKUP *ctx, const char *file, int type, + OPENSSL_CTX *libctx, const char *propq) { int ret = 0; BIO *in = NULL; @@ -83,20 +101,29 @@ int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) in = BIO_new(BIO_s_file()); if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { - X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_SYS_LIB); + X509err(0, ERR_R_SYS_LIB); + goto err; + } + + if (type != X509_FILETYPE_PEM && type != X509_FILETYPE_ASN1) { + X509err(0, X509_R_BAD_X509_FILETYPE); + goto err; + } + x = X509_new_with_libctx(libctx, propq); + if (x == NULL) { + X509err(0, ERR_R_MALLOC_FAILURE); goto err; } if (type == X509_FILETYPE_PEM) { for (;;) { - x = PEM_read_bio_X509_AUX(in, NULL, NULL, ""); - if (x == NULL) { + if (PEM_read_bio_X509_AUX(in, &x, NULL, "") == NULL) { if ((ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) && (count > 0)) { ERR_clear_error(); break; } else { - X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_PEM_LIB); + X509err(0, ERR_R_PEM_LIB); goto err; } } @@ -109,27 +136,28 @@ int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) } ret = count; } else if (type == X509_FILETYPE_ASN1) { - x = d2i_X509_bio(in, NULL); - if (x == NULL) { - X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_ASN1_LIB); + if (d2i_X509_bio(in, &x) == NULL) { + X509err(0, ERR_R_ASN1_LIB); goto err; } i = X509_STORE_add_cert(ctx->store_ctx, x); if (!i) goto err; ret = i; - } else { - X509err(X509_F_X509_LOAD_CERT_FILE, X509_R_BAD_X509_FILETYPE); - goto err; } if (ret == 0) - X509err(X509_F_X509_LOAD_CERT_FILE, X509_R_NO_CERTIFICATE_FOUND); + X509err(0, X509_R_NO_CERTIFICATE_FOUND); err: X509_free(x); BIO_free(in); return ret; } +int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) +{ + return X509_load_cert_file_with_libctx(ctx, file, type, NULL, NULL); +} + int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) { int ret = 0; @@ -187,7 +215,9 @@ int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) return ret; } -int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) +int X509_load_cert_crl_file_with_libctx(X509_LOOKUP *ctx, const char *file, + int type, OPENSSL_CTX *libctx, + const char *propq) { STACK_OF(X509_INFO) *inf; X509_INFO *itmp; @@ -195,16 +225,16 @@ int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) int i, count = 0; if (type != X509_FILETYPE_PEM) - return X509_load_cert_file(ctx, file, type); + return X509_load_cert_file_with_libctx(ctx, file, type, libctx, propq); in = BIO_new_file(file, "r"); if (!in) { - X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_SYS_LIB); + X509err(0, ERR_R_SYS_LIB); return 0; } - inf = PEM_X509_INFO_read_bio(in, NULL, NULL, ""); + inf = PEM_X509_INFO_read_bio_with_libctx(in, NULL, NULL, "", libctx, propq); BIO_free(in); if (!inf) { - X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_PEM_LIB); + X509err(0, ERR_R_PEM_LIB); return 0; } for (i = 0; i < sk_X509_INFO_num(inf); i++) { @@ -221,9 +251,14 @@ int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) } } if (count == 0) - X509err(X509_F_X509_LOAD_CERT_CRL_FILE, - X509_R_NO_CERTIFICATE_OR_CRL_FOUND); + X509err(0, X509_R_NO_CERTIFICATE_OR_CRL_FOUND); err: sk_X509_INFO_pop_free(inf, X509_INFO_free); return count; } + +int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) +{ + return X509_load_cert_crl_file_with_libctx(ctx, file, type, NULL, NULL); +} + diff --git a/crypto/x509/by_store.c b/crypto/x509/by_store.c index 7141c1bd2f..debb76150d 100644 --- a/crypto/x509/by_store.c +++ b/crypto/x509/by_store.c @@ -17,13 +17,14 @@ DEFINE_STACK_OF_STRING() /* Generic object loader, given expected type and criterion */ static int cache_objects(X509_LOOKUP *lctx, const char *uri, const OSSL_STORE_SEARCH *criterion, - int depth) + int depth, OPENSSL_CTX *libctx, const char *propq) { int ok = 0; OSSL_STORE_CTX *ctx = NULL; X509_STORE *xstore = X509_LOOKUP_get_store(lctx); - if ((ctx = OSSL_STORE_open(uri, NULL, NULL, NULL, NULL)) == NULL) + if ((ctx = OSSL_STORE_open_with_libctx(uri, libctx, propq, + NULL, NULL, NULL, NULL)) == NULL) return 0; /* @@ -65,7 +66,7 @@ static int cache_objects(X509_LOOKUP *lctx, const char *uri, */ if (depth > 0) ok = cache_objects(lctx, OSSL_STORE_INFO_get0_NAME(info), - criterion, depth - 1); + criterion, depth - 1, libctx, propq); } else { /* * We know that X509_STORE_add_{cert|crl} increments the object's @@ -106,9 +107,10 @@ static void by_store_free(X509_LOOKUP *ctx) sk_OPENSSL_STRING_pop_free(uris, free_uri); } -static int by_store_ctrl(X509_LOOKUP *ctx, int cmd, - const char *argp, long argl, - char **retp) +static int by_store_ctrl_with_libctx(X509_LOOKUP *ctx, int cmd, + const char *argp, long argl, + char **retp, + OPENSSL_CTX *libctx, const char *propq) { switch (cmd) { case X509_L_ADD_STORE: @@ -129,14 +131,21 @@ static int by_store_ctrl(X509_LOOKUP *ctx, int cmd, } case X509_L_LOAD_STORE: /* This is a shortcut for quick loading of specific containers */ - return cache_objects(ctx, argp, NULL, 0); + return cache_objects(ctx, argp, NULL, 0, libctx, propq); } return 0; } +static int by_store_ctrl(X509_LOOKUP *ctx, int cmd, + const char *argp, long argl, char **retp) +{ + return by_store_ctrl_with_libctx(ctx, cmd, argp, argl, retp, NULL, NULL); +} + static int by_store(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, - const OSSL_STORE_SEARCH *criterion, X509_OBJECT *ret) + const OSSL_STORE_SEARCH *criterion, X509_OBJECT *ret, + OPENSSL_CTX *libctx, const char *propq) { STACK_OF(OPENSSL_STRING) *uris = X509_LOOKUP_get_method_data(ctx); int i; @@ -144,7 +153,7 @@ static int by_store(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, for (i = 0; i < sk_OPENSSL_STRING_num(uris); i++) { ok = cache_objects(ctx, sk_OPENSSL_STRING_value(uris, i), criterion, - 1 /* depth */); + 1 /* depth */, libctx, propq); if (ok) break; @@ -152,12 +161,13 @@ static int by_store(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, return ok; } -static int by_store_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, - const X509_NAME *name, X509_OBJECT *ret) +static int by_store_subject_with_libctx(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const X509_NAME *name, X509_OBJECT *ret, + OPENSSL_CTX *libctx, const char *propq) { OSSL_STORE_SEARCH *criterion = OSSL_STORE_SEARCH_by_name((X509_NAME *)name); /* won't modify it */ - int ok = by_store(ctx, type, criterion, ret); + int ok = by_store(ctx, type, criterion, ret, libctx, propq); STACK_OF(X509_OBJECT) *store_objects = X509_STORE_get0_objects(X509_LOOKUP_get_store(ctx)); X509_OBJECT *tmp = NULL; @@ -205,6 +215,12 @@ static int by_store_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, return ok; } +static int by_store_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const X509_NAME *name, X509_OBJECT *ret) +{ + return by_store_subject_with_libctx(ctx, type, name, ret, NULL, NULL); +} + /* * We lack the implementations for get_by_issuer_serial, get_by_fingerprint * and get_by_alias. There's simply not enough support in the X509_LOOKUP @@ -222,6 +238,8 @@ static X509_LOOKUP_METHOD x509_store_lookup = { NULL, /* get_by_issuer_serial */ NULL, /* get_by_fingerprint */ NULL, /* get_by_alias */ + by_store_subject_with_libctx, + by_store_ctrl_with_libctx }; X509_LOOKUP_METHOD *X509_LOOKUP_store(void) diff --git a/crypto/x509/v3_purp.c b/crypto/x509/v3_purp.c index 4a2b549199..9e0190a038 100644 --- a/crypto/x509/v3_purp.c +++ b/crypto/x509/v3_purp.c @@ -84,7 +84,7 @@ int X509_check_purpose(X509 *x, int id, int ca) int idx; const X509_PURPOSE *pt; - if (!X509v3_cache_extensions(x, NULL, NULL)) + if (!x509v3_cache_extensions(x)) return -1; /* Return if side-effect only call */ @@ -375,7 +375,7 @@ static int check_sig_alg_match(const EVP_PKEY *pkey, const X509 *subject) * e.g., if cert 'x' is self-issued, in x->ex_flags and other internal fields. * Set EXFLAG_INVALID and return 0 in case the certificate is invalid. */ -int X509v3_cache_extensions(X509 *x, OPENSSL_CTX *libctx, const char *propq) +int x509v3_cache_extensions(X509 *x) { BASIC_CONSTRAINTS *bs; PROXY_CERT_INFO_EXTENSION *pci; @@ -384,7 +384,6 @@ int X509v3_cache_extensions(X509 *x, OPENSSL_CTX *libctx, const char *propq) EXTENDED_KEY_USAGE *extusage; X509_EXTENSION *ex; int i; - EVP_MD *sha1; #ifdef tsan_ld_acq /* fast lock-free check, see end of the function for details. */ @@ -398,13 +397,8 @@ int X509v3_cache_extensions(X509 *x, OPENSSL_CTX *libctx, const char *propq) return (x->ex_flags & EXFLAG_INVALID) == 0; } - /* Cache the SHA1 digest of the cert */ - sha1 = EVP_MD_fetch(libctx, "SHA1", propq); - if (sha1 != NULL) { - if (!X509_digest(x, sha1, x->sha1_hash, NULL)) + if (!X509_digest(x, EVP_sha1(), x->sha1_hash, NULL)) x->ex_flags |= EXFLAG_INVALID; - EVP_MD_free(sha1); - } /* V1 should mean no extensions ... */ if (X509_get_version(x) == 0) @@ -636,7 +630,7 @@ void X509_set_proxy_pathlen(X509 *x, long l) int X509_check_ca(X509 *x) { /* Note 0 normally means "not a CA" - but in this case means error. */ - if (!X509v3_cache_extensions(x, NULL, NULL)) + if (!x509v3_cache_extensions(x)) return 0; return check_ca(x); @@ -846,19 +840,17 @@ static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca) * Returns 0 for OK, or positive for reason for mismatch * where reason codes match those for X509_verify_cert(). */ -int x509_check_issued_int(X509 *issuer, X509 *subject, - OPENSSL_CTX *libctx, const char *propq) +int X509_check_issued(X509 *issuer, X509 *subject) { int ret; - if ((ret = x509_likely_issued(issuer, subject, libctx, propq)) != X509_V_OK) + if ((ret = x509_likely_issued(issuer, subject)) != X509_V_OK) return ret; return x509_signing_allowed(issuer, subject); } /* do the checks 1., 2., and 3. as described above for X509_check_issued() */ -int x509_likely_issued(X509 *issuer, X509 *subject, - OPENSSL_CTX *libctx, const char *propq) +int x509_likely_issued(X509 *issuer, X509 *subject) { int ret; @@ -867,8 +859,8 @@ int x509_likely_issued(X509 *issuer, X509 *subject, return X509_V_ERR_SUBJECT_ISSUER_MISMATCH; /* set issuer->skid and subject->akid */ - if (!X509v3_cache_extensions(issuer, libctx, propq) - || !X509v3_cache_extensions(subject, libctx, propq)) + if (!x509v3_cache_extensions(issuer) + || !x509v3_cache_extensions(subject)) return X509_V_ERR_UNSPECIFIED; ret = X509_check_akid(issuer, subject->akid); @@ -896,11 +888,6 @@ int x509_signing_allowed(const X509 *issuer, const X509 *subject) return X509_V_OK; } -int X509_check_issued(X509 *issuer, X509 *subject) -{ - return x509_check_issued_int(issuer, subject, NULL, NULL); -} - int X509_check_akid(const X509 *issuer, const AUTHORITY_KEYID *akid) { if (akid == NULL) diff --git a/crypto/x509/x509_d2.c b/crypto/x509/x509_d2.c index c0543adf1e..512c7ae13e 100644 --- a/crypto/x509/x509_d2.c +++ b/crypto/x509/x509_d2.c @@ -12,14 +12,17 @@ #include <openssl/crypto.h> #include <openssl/x509.h> -int X509_STORE_set_default_paths(X509_STORE *ctx) +int X509_STORE_set_default_paths_with_libctx(X509_STORE *ctx, + OPENSSL_CTX *libctx, + const char *propq) { X509_LOOKUP *lookup; lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); if (lookup == NULL) return 0; - X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); + X509_LOOKUP_load_file_with_libctx(lookup, NULL, X509_FILETYPE_DEFAULT, + libctx, propq); lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); if (lookup == NULL) @@ -29,26 +32,37 @@ int X509_STORE_set_default_paths(X509_STORE *ctx) lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_store()); if (lookup == NULL) return 0; - X509_LOOKUP_add_store(lookup, NULL); + X509_LOOKUP_add_store_with_libctx(lookup, NULL, libctx, propq); /* clear any errors */ ERR_clear_error(); return 1; } +int X509_STORE_set_default_paths(X509_STORE *ctx) +{ + return X509_STORE_set_default_paths_with_libctx(ctx, NULL, NULL); +} -int X509_STORE_load_file(X509_STORE *ctx, const char *file) +int X509_STORE_load_file_with_libctx(X509_STORE *ctx, const char *file, + OPENSSL_CTX *libctx, const char *propq) { X509_LOOKUP *lookup; if (file == NULL || (lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file())) == NULL - || X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM) == 0) + || X509_LOOKUP_load_file_with_libctx(lookup, file, X509_FILETYPE_PEM, + libctx, propq) == 0) return 0; return 1; } +int X509_STORE_load_file(X509_STORE *ctx, const char *file) +{ + return X509_STORE_load_file_with_libctx(ctx, file, NULL, NULL); +} + int X509_STORE_load_path(X509_STORE *ctx, const char *path) { X509_LOOKUP *lookup; @@ -61,26 +75,40 @@ int X509_STORE_load_path(X509_STORE *ctx, const char *path) return 1; } -int X509_STORE_load_store(X509_STORE *ctx, const char *uri) +int X509_STORE_load_store_with_libctx(X509_STORE *ctx, const char *uri, + OPENSSL_CTX *libctx, const char *propq) { X509_LOOKUP *lookup; if (uri == NULL || (lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_store())) == NULL - || X509_LOOKUP_add_store(lookup, uri) == 0) + || X509_LOOKUP_add_store_with_libctx(lookup, uri, libctx, propq) == 0) return 0; return 1; } -int X509_STORE_load_locations(X509_STORE *ctx, const char *file, - const char *path) +int X509_STORE_load_store(X509_STORE *ctx, const char *uri) +{ + return X509_STORE_load_store_with_libctx(ctx, uri, NULL, NULL); +} + +int X509_STORE_load_locations_with_libctx(X509_STORE *ctx, const char *file, + const char *path, + OPENSSL_CTX *libctx, const char *propq) { if (file == NULL && path == NULL) return 0; - if (file != NULL && !X509_STORE_load_file(ctx, file)) + if (file != NULL && !X509_STORE_load_file_with_libctx(ctx, file, + libctx, propq)) return 0; if (path != NULL && !X509_STORE_load_path(ctx, path)) return 0; return 1; } + +int X509_STORE_load_locations(X509_STORE *ctx, const char *file, + const char *path) +{ + return X509_STORE_load_locations_with_libctx(ctx, file, path, NULL, NULL); +} diff --git a/crypto/x509/x509_local.h b/crypto/x509/x509_local.h index a1fe4203b9..e944d16afe 100644 --- a/crypto/x509/x509_local.h +++ b/crypto/x509/x509_local.h @@ -87,6 +87,12 @@ struct x509_lookup_method_st { X509_OBJECT *ret); int (*get_by_alias) (X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, const char *str, int len, X509_OBJECT *ret); + int (*get_by_subject_with_libctx) (X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const X509_NAME *name, X509_OBJECT *ret, + OPENSSL_CTX *libctx, const char *propq); + int (*ctrl_with_libctx) (X509_LOOKUP *ctx, int cmd, + const char *argc, long argl, char **ret, + OPENSSL_CTX *libctx, const char *propq); }; /* This is the functions plus an instance of the local variables. */ @@ -149,6 +155,5 @@ DEFINE_STACK_OF(STACK_OF_X509_NAME_ENTRY) void x509_set_signature_info(X509_SIG_INFO *siginf, const X509_ALGOR *alg, const ASN1_STRING *sig); -int x509_likely_issued(X509 *issuer, X509 *subject, - OPENSSL_CTX *libctx, const char *propq); +int x509_likely_issued(X509 *issuer, X509 *subject); int x509_signing_allowed(const X509 *issuer, const X509 *subject); diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c index 421f26ba16..e66cfb1825 100644 --- a/crypto/x509/x509_lu.c +++ b/crypto/x509/x509_lu.c @@ -76,25 +76,46 @@ int X509_LOOKUP_shutdown(X509_LOOKUP *ctx) return 1; } -int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, - char **ret) +int X509_LOOKUP_ctrl_with_libctx(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret, + OPENSSL_CTX *libctx, const char *propq) { if (ctx->method == NULL) return -1; + if (ctx->method->ctrl_with_libctx != NULL) + return ctx->method->ctrl_with_libctx(ctx, cmd, argc, argl, ret, + libctx, propq); if (ctx->method->ctrl != NULL) return ctx->method->ctrl(ctx, cmd, argc, argl, ret); + return 1; +} + +int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, + char **ret) +{ + return X509_LOOKUP_ctrl_with_libctx(ctx, cmd, argc, argl, ret, NULL, NULL); +} + +int X509_LOOKUP_by_subject_with_libctx(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const X509_NAME *name, X509_OBJECT *ret, + OPENSSL_CTX *libctx, const char *propq) +{ + if (ctx->skip + || ctx->method == NULL + || (ctx->method->get_by_subject == NULL + && ctx->method->get_by_subject_with_libctx == NULL)) + return 0; + if (ctx->method->get_by_subject_with_libctx != NULL) + return ctx->method->get_by_subject_with_libctx(ctx, type, name, ret, + libctx, propq); else - return 1; + return ctx->method->get_by_subject(ctx, type, name, ret); } int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, const X509_NAME *name, X509_OBJECT *ret) { - if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL)) - return 0; - if (ctx->skip) - return 0; - return ctx->method->get_by_subject(ctx, type, name, ret); + return X509_LOOKUP_by_subject_with_libctx(ctx, type, name, ret, NULL, NULL); } int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, @@ -168,34 +189,33 @@ X509_STORE *X509_STORE_new(void) X509_STORE *ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE); + X509err(0, ERR_R_MALLOC_FAILURE); return NULL; } if ((ret->objs = sk_X509_OBJECT_new(x509_object_cmp)) == NULL) { - X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE); + X509err(0, ERR_R_MALLOC_FAILURE); goto err; } ret->cache = 1; if ((ret->get_cert_methods = sk_X509_LOOKUP_new_null()) == NULL) { - X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE); + X509err(0, ERR_R_MALLOC_FAILURE); goto err; } if ((ret->param = X509_VERIFY_PARAM_new()) == NULL) { - X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE); + X509err(0, ERR_R_MALLOC_FAILURE); goto err; } if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data)) { - X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE); + X509err(0, ERR_R_MALLOC_FAILURE); goto err; } ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - X509err(X509_F_X509_STORE_NEW, ERR_R_MALLOC_FAILURE); + X509err(0, ERR_R_MALLOC_FAILURE); goto err; } - ret->references = 1; return ret; @@ -315,7 +335,8 @@ int X509_STORE_CTX_get_by_subject(const X509_STORE_CTX *vs, if (tmp == NULL || type == X509_LU_CRL) { for (i = 0; i < sk_X509_LOOKUP_num(store->get_cert_methods); i++) { lu = sk_X509_LOOKUP_value(store->get_cert_methods, i); - j = X509_LOOKUP_by_subject(lu, type, name, &stmp); + j = X509_LOOKUP_by_subject_with_libctx(lu, type, name, &stmp, + vs->libctx, vs->propq); if (j) { tmp = &stmp; break; diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 3bd23d131c..012f932ee5 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -118,8 +118,7 @@ static int null_callback(int ok, X509_STORE_CTX *e) * 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. */ -static int x509_self_signed_ex(X509 *cert, int verify_signature, - OPENSSL_CTX *libctx, const char *propq) +int X509_self_signed(X509 *cert, int verify_signature) { EVP_PKEY *pkey; @@ -127,24 +126,13 @@ static int x509_self_signed_ex(X509 *cert, int verify_signature, X509err(0, X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY); return -1; } - if (!X509v3_cache_extensions(cert, libctx, propq)) + if (!x509v3_cache_extensions(cert)) return -1; if ((cert->ex_flags & EXFLAG_SS) == 0) return 0; if (!verify_signature) return 1; - return X509_verify_ex(cert, pkey, libctx, propq); -} - -/* wrapper for internal use */ -static int cert_self_signed(X509_STORE_CTX *ctx, X509 *x, int verify_signature) -{ - return x509_self_signed_ex(x, verify_signature, ctx->libctx, ctx->propq); -} - -int X509_self_signed(X509 *cert, int verify_signature) -{ - return x509_self_signed_ex(cert, verify_signature, NULL, NULL); + return X509_verify(cert, pkey); } /* Given a certificate try and find an exact match in the store */ @@ -367,7 +355,7 @@ static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x) */ static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer) { - if (x509_likely_issued(issuer, x, ctx->libctx, ctx->propq) != X509_V_OK) + if (x509_likely_issued(issuer, x) != X509_V_OK) return 0; if ((x->ex_flags & EXFLAG_SI) == 0 || sk_X509_num(ctx->chain) != 1) { int i; @@ -1825,7 +1813,7 @@ static int internal_verify(X509_STORE_CTX *ctx) ret = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; if (!verify_cb_cert(ctx, xi, issuer_depth, ret)) return 0; - } else if (X509_verify_ex(xs, pkey, ctx->libctx, ctx->propq) <= 0) { + } else if (X509_verify(xs, pkey) <= 0) { ret = X509_V_ERR_CERT_SIGNATURE_FAILURE; if (!verify_cb_cert(ctx, xs, n, ret)) return 0; @@ -2871,7 +2859,7 @@ static int check_dane_pkeys(X509_STORE_CTX *ctx) if (t->usage != DANETLS_USAGE_DANE_TA || t->selector != DANETLS_SELECTOR_SPKI || t->mtype != DANETLS_MATCHING_FULL || - X509_verify_ex(cert, t->spki, ctx->libctx, ctx->propq) <= 0) + X509_verify(cert, t->spki) <= 0) continue; /* Clear any PKIX-?? matches that failed to extend to a full chain */ @@ -3013,7 +3001,7 @@ static int build_chain(X509_STORE_CTX *ctx) return 0; } - self_signed = cert_self_signed(ctx, cert, 0); + self_signed = X509_self_signed(cert, 0); if (self_signed < 0) { ctx->error = X509_V_ERR_UNSPECIFIED; return 0; @@ -3191,7 +3179,7 @@ static int build_chain(X509_STORE_CTX *ctx) search = 0; continue; } - self_signed = cert_self_signed(ctx, x, 0); + self_signed = X509_self_signed(x, 0); if (self_signed < 0) { ctx->error = X509_V_ERR_UNSPECIFIED; return 0; @@ -3317,7 +3305,7 @@ static int build_chain(X509_STORE_CTX *ctx) x = xtmp; ++ctx->num_untrusted; - self_signed = cert_self_signed(ctx, xtmp, 0); + self_signed = X509_self_signed(xtmp, 0); if (self_signed < 0) { sk_X509_free(sktmp); ctx->error = X509_V_ERR_UNSPECIFIED; diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c index 6d7f341c7f..b06828f718 100644 --- a/crypto/x509/x_all.c +++ b/crypto/x509/x_all.c @@ -19,12 +19,12 @@ #include <openssl/asn1.h> #include <openssl/evp.h> #include <openssl/x509.h> -#include "crypto/x509.h" #include <openssl/http.h> #include <openssl/rsa.h> #include <openssl/dsa.h> #include <openssl/x509v3.h> #include "crypto/asn1.h" +#include "crypto/x509.h" static void clean_id_ctx(EVP_MD_CTX *ctx) { @@ -64,7 +64,7 @@ static EVP_MD_CTX *make_id_ctx(EVP_PKEY *r, ASN1_OCTET_STRING *id, return NULL; } -int X509_verify_ex(X509 *a, EVP_PKEY *r, OPENSSL_CTX *libctx, const char *propq) +int X509_verify(X509 *a, EVP_PKEY *r) { int rv = 0; EVP_MD_CTX *ctx = NULL; @@ -74,7 +74,7 @@ int X509_verify_ex(X509 *a, EVP_PKEY *r, OPENSSL_CTX *libctx, const char *propq) return 0; id = a->distinguishing_id; - if ((ctx = make_id_ctx(r, id, libctx, propq)) != NULL) { + if ((ctx = make_id_ctx(r, id, a->libctx, a->propq)) != NULL) { rv = ASN1_item_verify_ctx(ASN1_ITEM_rptr(X509_CINF), &a->sig_alg, &a->signature, &a->cert_info, ctx); clean_id_ctx(ctx); @@ -82,13 +82,8 @@ int X509_verify_ex(X509 *a, EVP_PKEY *r, OPENSSL_CTX *libctx, const char *propq) return rv; } -int X509_verify(X509 *a, EVP_PKEY *r) -{ - return X509_verify_ex(a, r, NULL, NULL); -} - -int X509_REQ_verify_ex(X509_REQ *a, EVP_PKEY *r, OPENSSL_CTX *libctx, - const char *propq) +int X509_REQ_verify_with_libctx(X509_REQ *a, EVP_PKEY *r, OPENSSL_CTX *libctx, + const char *propq) { int rv = 0; EVP_MD_CTX *ctx = NULL; @@ -105,7 +100,7 @@ int X509_REQ_verify_ex(X509_REQ *a, EVP_PKEY *r, OPENSSL_CTX *libctx, int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r) { - return X509_REQ_verify_ex(a, r, NULL, NULL); + return X509_REQ_verify_with_libctx(a, r, NULL, NULL); } int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r) @@ -443,19 +438,19 @@ int X509_pubkey_digest(const X509 *data, const EVP_MD *type, return EVP_Digest(key->data, key->length, md, len, type, NULL); } -int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md, +int X509_digest(const X509 *cert, const EVP_MD *md, unsigned char *data, unsigned int *len) { - if (type == EVP_sha1() && (data->ex_flags & EXFLAG_SET) != 0 - && (data->ex_flags & EXFLAG_INVALID) == 0) { + if (EVP_MD_is_a(md, SN_sha1) && (cert->ex_flags & EXFLAG_SET) != 0 + && (cert->ex_flags & EXFLAG_INVALID) == 0) { /* Asking for SHA1 and we already computed it. */ if (len != NULL) - *len = sizeof(data->sha1_hash); - memcpy(md, data->sha1_hash, sizeof(data->sha1_hash)); + *len = sizeof(cert->sha1_hash); + memcpy(data, cert->sha1_hash, sizeof(cert->sha1_hash)); return 1; } - return (ASN1_item_digest - (ASN1_ITEM_rptr(X509), type, (char *)data, md, len)); + return (asn1_item_digest_with_libctx(ASN1_ITEM_rptr(X509), md, (char *)cert, + data, len, cert->libctx, cert->propq)); } /* calculate cert digest using the same hash algorithm as in its signature */ diff --git a/crypto/x509/x_x509.c b/crypto/x509/x_x509.c index 8a216c49cf..9358c46a7f 100644 --- a/crypto/x509/x_x509.c +++ b/crypto/x509/x_x509.c @@ -113,9 +113,38 @@ ASN1_SEQUENCE_ref(X509, x509_cb) = { ASN1_EMBED(X509, signature, ASN1_BIT_STRING) } ASN1_SEQUENCE_END_ref(X509, X509) -IMPLEMENT_ASN1_FUNCTIONS(X509) +IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(X509, X509, X509) IMPLEMENT_ASN1_DUP_FUNCTION(X509) +X509 *d2i_X509(X509 **a, const unsigned char **in, long len) +{ + X509 *cert = NULL; + + cert = (X509 *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, (X509_it())); + /* Only cache the extensions if the cert object was passed in */ + if (cert != NULL && a != NULL) { + if (!x509v3_cache_extensions(cert)) + cert = NULL; + } + return cert; +} +int i2d_X509(const X509 *a, unsigned char **out) +{ + return ASN1_item_i2d((const ASN1_VALUE *)a, out, (X509_it())); +} + +X509 *X509_new_with_libctx(OPENSSL_CTX *libctx, const char *propq) +{ + X509 *cert = NULL; + + cert = (X509 *)ASN1_item_new((X509_it())); + if (cert != NULL) { + cert->libctx = libctx; + cert->propq = propq; + } + return cert; +} + int X509_set_ex_data(X509 *r, int idx, void *arg) { return CRYPTO_set_ex_data(&r->ex_data, idx, arg); |