aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/x509
diff options
context:
space:
mode:
authorShane Lontis <shane.lontis@oracle.com>2020-07-24 22:53:27 +1000
committerShane Lontis <shane.lontis@oracle.com>2020-07-24 22:53:27 +1000
commit6725682d77510bf6d499957897d7be124d603f40 (patch)
tree447e5bce5607b4873f7f018df1b2e4c21a394e92 /crypto/x509
parentae89578be2930c726d6ef56451233757a89f224f (diff)
downloadopenssl-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.c56
-rw-r--r--crypto/x509/by_file.c95
-rw-r--r--crypto/x509/by_store.c42
-rw-r--r--crypto/x509/v3_purp.c31
-rw-r--r--crypto/x509/x509_d2.c48
-rw-r--r--crypto/x509/x509_local.h9
-rw-r--r--crypto/x509/x509_lu.c53
-rw-r--r--crypto/x509/x509_vfy.c30
-rw-r--r--crypto/x509/x_all.c31
-rw-r--r--crypto/x509/x_x509.c31
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);