summaryrefslogtreecommitdiff
path: root/src/crypto/x509/x509_lu.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto/x509/x509_lu.c')
-rw-r--r--src/crypto/x509/x509_lu.c326
1 files changed, 225 insertions, 101 deletions
diff --git a/src/crypto/x509/x509_lu.c b/src/crypto/x509/x509_lu.c
index 7139aced..814f0ce9 100644
--- a/src/crypto/x509/x509_lu.c
+++ b/src/crypto/x509/x509_lu.c
@@ -60,34 +60,25 @@
#include <openssl/mem.h>
#include <openssl/thread.h>
#include <openssl/x509.h>
+#include <openssl/x509v3.h>
#include "../internal.h"
#include "internal.h"
+X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method) {
+ X509_LOOKUP *ret;
-static int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
- X509_NAME *name);
-static X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
- int type, X509_NAME *name);
-static X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
- X509_OBJECT *x);
-static int X509_OBJECT_up_ref_count(X509_OBJECT *a);
-
-static X509_LOOKUP *X509_LOOKUP_new(const X509_LOOKUP_METHOD *method,
- X509_STORE *store);
-static int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
- X509_OBJECT *ret);
-
-static X509_LOOKUP *X509_LOOKUP_new(const X509_LOOKUP_METHOD *method,
- X509_STORE *store) {
- X509_LOOKUP *ret = OPENSSL_zalloc(sizeof(X509_LOOKUP));
+ ret = (X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP));
if (ret == NULL) {
return NULL;
}
+ ret->init = 0;
+ ret->skip = 0;
ret->method = method;
- ret->store_ctx = store;
- if (method->new_item != NULL && !method->new_item(ret)) {
+ ret->method_data = NULL;
+ ret->store_ctx = NULL;
+ if ((method->new_item != NULL) && !method->new_item(ret)) {
OPENSSL_free(ret);
return NULL;
}
@@ -98,12 +89,34 @@ void X509_LOOKUP_free(X509_LOOKUP *ctx) {
if (ctx == NULL) {
return;
}
- if (ctx->method != NULL && ctx->method->free != NULL) {
+ if ((ctx->method != NULL) && (ctx->method->free != NULL)) {
(*ctx->method->free)(ctx);
}
OPENSSL_free(ctx);
}
+int X509_LOOKUP_init(X509_LOOKUP *ctx) {
+ if (ctx->method == NULL) {
+ return 0;
+ }
+ if (ctx->method->init != NULL) {
+ return ctx->method->init(ctx);
+ } else {
+ return 1;
+ }
+}
+
+int X509_LOOKUP_shutdown(X509_LOOKUP *ctx) {
+ if (ctx->method == NULL) {
+ return 0;
+ }
+ if (ctx->method->shutdown != NULL) {
+ return ctx->method->shutdown(ctx);
+ } else {
+ return 1;
+ }
+}
+
int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
char **ret) {
if (ctx->method == NULL) {
@@ -116,15 +129,14 @@ int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
}
}
-static int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
- X509_OBJECT *ret) {
- if (ctx->method == NULL || ctx->method->get_by_subject == NULL) {
+int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
+ X509_OBJECT *ret) {
+ if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL)) {
+ return 0;
+ }
+ if (ctx->skip) {
return 0;
}
- // Note |get_by_subject| leaves |ret| in an inconsistent state. It has
- // pointers to an |X509| or |X509_CRL|, but has not bumped the refcount yet.
- // For now, the caller is expected to fix this, but ideally we'd fix the
- // |X509_LOOKUP| convention itself.
return ctx->method->get_by_subject(ctx, type, name, ret) > 0;
}
@@ -150,24 +162,42 @@ static int x509_object_cmp_sk(const X509_OBJECT *const *a,
}
X509_STORE *X509_STORE_new(void) {
- X509_STORE *ret = OPENSSL_zalloc(sizeof(X509_STORE));
- if (ret == NULL) {
+ X509_STORE *ret;
+
+ if ((ret = (X509_STORE *)OPENSSL_zalloc(sizeof(X509_STORE))) == NULL) {
return NULL;
}
-
- ret->references = 1;
CRYPTO_MUTEX_init(&ret->objs_lock);
ret->objs = sk_X509_OBJECT_new(x509_object_cmp_sk);
+ if (ret->objs == NULL) {
+ goto err;
+ }
ret->get_cert_methods = sk_X509_LOOKUP_new_null();
+ if (ret->get_cert_methods == NULL) {
+ goto err;
+ }
ret->param = X509_VERIFY_PARAM_new();
- if (ret->objs == NULL ||
- ret->get_cert_methods == NULL ||
- ret->param == NULL) {
- X509_STORE_free(ret);
- return NULL;
+ if (ret->param == NULL) {
+ goto err;
}
+ ret->references = 1;
return ret;
+err:
+ if (ret) {
+ CRYPTO_MUTEX_cleanup(&ret->objs_lock);
+ if (ret->param) {
+ X509_VERIFY_PARAM_free(ret->param);
+ }
+ if (ret->get_cert_methods) {
+ sk_X509_LOOKUP_free(ret->get_cert_methods);
+ }
+ if (ret->objs) {
+ sk_X509_OBJECT_free(ret->objs);
+ }
+ OPENSSL_free(ret);
+ }
+ return NULL;
}
int X509_STORE_up_ref(X509_STORE *store) {
@@ -175,7 +205,26 @@ int X509_STORE_up_ref(X509_STORE *store) {
return 1;
}
+static void cleanup(X509_OBJECT *a) {
+ if (a == NULL) {
+ return;
+ }
+ if (a->type == X509_LU_X509) {
+ X509_free(a->data.x509);
+ } else if (a->type == X509_LU_CRL) {
+ X509_CRL_free(a->data.crl);
+ } else {
+ // abort();
+ }
+
+ OPENSSL_free(a);
+}
+
void X509_STORE_free(X509_STORE *vfy) {
+ size_t j;
+ STACK_OF(X509_LOOKUP) *sk;
+ X509_LOOKUP *lu;
+
if (vfy == NULL) {
return;
}
@@ -185,41 +234,63 @@ void X509_STORE_free(X509_STORE *vfy) {
}
CRYPTO_MUTEX_cleanup(&vfy->objs_lock);
- sk_X509_LOOKUP_pop_free(vfy->get_cert_methods, X509_LOOKUP_free);
- sk_X509_OBJECT_pop_free(vfy->objs, X509_OBJECT_free);
- X509_VERIFY_PARAM_free(vfy->param);
+
+ sk = vfy->get_cert_methods;
+ for (j = 0; j < sk_X509_LOOKUP_num(sk); j++) {
+ lu = sk_X509_LOOKUP_value(sk, j);
+ X509_LOOKUP_shutdown(lu);
+ X509_LOOKUP_free(lu);
+ }
+ sk_X509_LOOKUP_free(sk);
+ sk_X509_OBJECT_pop_free(vfy->objs, cleanup);
+
+ if (vfy->param) {
+ X509_VERIFY_PARAM_free(vfy->param);
+ }
OPENSSL_free(vfy);
}
-X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, const X509_LOOKUP_METHOD *m) {
- STACK_OF(X509_LOOKUP) *sk = v->get_cert_methods;
- for (size_t i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
- X509_LOOKUP *lu = sk_X509_LOOKUP_value(sk, i);
+X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m) {
+ size_t i;
+ STACK_OF(X509_LOOKUP) *sk;
+ X509_LOOKUP *lu;
+
+ sk = v->get_cert_methods;
+ for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
+ lu = sk_X509_LOOKUP_value(sk, i);
if (m == lu->method) {
return lu;
}
}
-
- X509_LOOKUP *lu = X509_LOOKUP_new(m, v);
- if (lu == NULL || !sk_X509_LOOKUP_push(v->get_cert_methods, lu)) {
- X509_LOOKUP_free(lu);
+ // a new one
+ lu = X509_LOOKUP_new(m);
+ if (lu == NULL) {
return NULL;
+ } else {
+ lu->store_ctx = v;
+ if (sk_X509_LOOKUP_push(v->get_cert_methods, lu)) {
+ return lu;
+ } else {
+ X509_LOOKUP_free(lu);
+ return NULL;
+ }
}
-
- return lu;
}
-int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
- X509_OBJECT *ret) {
+int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
+ X509_OBJECT *ret) {
X509_STORE *ctx = vs->ctx;
- X509_OBJECT stmp;
+ X509_LOOKUP *lu;
+ X509_OBJECT stmp, *tmp;
+ int i;
+
CRYPTO_MUTEX_lock_write(&ctx->objs_lock);
- X509_OBJECT *tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name);
+ tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name);
CRYPTO_MUTEX_unlock_write(&ctx->objs_lock);
if (tmp == NULL || type == X509_LU_CRL) {
- for (size_t i = 0; i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) {
- X509_LOOKUP *lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i);
+ for (i = 0; i < (int)sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) {
+ lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i);
if (X509_LOOKUP_by_subject(lu, type, name, &stmp)) {
tmp = &stmp;
break;
@@ -245,7 +316,7 @@ static int x509_store_add(X509_STORE *ctx, void *x, int is_crl) {
return 0;
}
- X509_OBJECT *const obj = X509_OBJECT_new();
+ X509_OBJECT *const obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
if (obj == NULL) {
return 0;
}
@@ -271,7 +342,8 @@ static int x509_store_add(X509_STORE *ctx, void *x, int is_crl) {
CRYPTO_MUTEX_unlock_write(&ctx->objs_lock);
if (!added) {
- X509_OBJECT_free(obj);
+ X509_OBJECT_free_contents(obj);
+ OPENSSL_free(obj);
}
return ret;
@@ -285,19 +357,7 @@ int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x) {
return x509_store_add(ctx, x, /*is_crl=*/1);
}
-X509_OBJECT *X509_OBJECT_new(void) {
- return OPENSSL_zalloc(sizeof(X509_OBJECT));
-}
-
-void X509_OBJECT_free(X509_OBJECT *obj) {
- if (obj == NULL) {
- return;
- }
- X509_OBJECT_free_contents(obj);
- OPENSSL_free(obj);
-}
-
-static int X509_OBJECT_up_ref_count(X509_OBJECT *a) {
+int X509_OBJECT_up_ref_count(X509_OBJECT *a) {
switch (a->type) {
case X509_LU_X509:
X509_up_ref(a->data.x509);
@@ -318,8 +378,6 @@ void X509_OBJECT_free_contents(X509_OBJECT *a) {
X509_CRL_free(a->data.crl);
break;
}
-
- OPENSSL_memset(a, 0, sizeof(X509_OBJECT));
}
int X509_OBJECT_get_type(const X509_OBJECT *a) { return a->type; }
@@ -376,13 +434,13 @@ static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type,
return (int)idx;
}
-static int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
- X509_NAME *name) {
+int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
+ X509_NAME *name) {
return x509_object_idx_cnt(h, type, name, NULL);
}
-static X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
- int type, X509_NAME *name) {
+X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type,
+ X509_NAME *name) {
int idx;
idx = X509_OBJECT_idx_by_subject(h, type, name);
if (idx == -1) {
@@ -395,20 +453,23 @@ STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *st) {
return st->objs;
}
-STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm) {
- int cnt;
- STACK_OF(X509) *sk = sk_X509_new_null();
+STACK_OF(X509) *X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm) {
+ int i, idx, cnt;
+ STACK_OF(X509) *sk;
+ X509 *x;
+ X509_OBJECT *obj;
+ sk = sk_X509_new_null();
if (sk == NULL) {
return NULL;
}
CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
- int idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
+ idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
if (idx < 0) {
// Nothing found in cache: do lookup to possibly add new objects to
// cache
X509_OBJECT xobj;
CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock);
- if (!X509_STORE_CTX_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) {
+ if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) {
sk_X509_free(sk);
return NULL;
}
@@ -421,9 +482,9 @@ STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm) {
return NULL;
}
}
- for (int i = 0; i < cnt; i++, idx++) {
- X509_OBJECT *obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
- X509 *x = obj->data.x509;
+ for (i = 0; i < cnt; i++, idx++) {
+ obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
+ x = obj->data.x509;
if (!sk_X509_push(sk, x)) {
CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock);
sk_X509_pop_free(sk, X509_free);
@@ -435,32 +496,33 @@ STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm) {
return sk;
}
-STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *ctx,
- X509_NAME *nm) {
- int cnt;
- X509_OBJECT xobj;
- STACK_OF(X509_CRL) *sk = sk_X509_CRL_new_null();
+STACK_OF(X509_CRL) *X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm) {
+ int i, idx, cnt;
+ STACK_OF(X509_CRL) *sk;
+ X509_CRL *x;
+ X509_OBJECT *obj, xobj;
+ sk = sk_X509_CRL_new_null();
if (sk == NULL) {
return NULL;
}
// Always do lookup to possibly add new CRLs to cache.
- if (!X509_STORE_CTX_get_by_subject(ctx, X509_LU_CRL, nm, &xobj)) {
+ if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj)) {
sk_X509_CRL_free(sk);
return NULL;
}
X509_OBJECT_free_contents(&xobj);
CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
- int idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
+ idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
if (idx < 0) {
CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock);
sk_X509_CRL_free(sk);
return NULL;
}
- for (int i = 0; i < cnt; i++, idx++) {
- X509_OBJECT *obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
- X509_CRL *x = obj->data.crl;
+ for (i = 0; i < cnt; i++, idx++) {
+ obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
+ x = obj->data.crl;
X509_CRL_up_ref(x);
if (!sk_X509_CRL_push(sk, x)) {
CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock);
@@ -473,8 +535,8 @@ STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *ctx,
return sk;
}
-static X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
- X509_OBJECT *x) {
+X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
+ X509_OBJECT *x) {
sk_X509_OBJECT_sort(h);
size_t idx;
if (!sk_X509_OBJECT_find(h, &idx, x)) {
@@ -514,18 +576,17 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) {
int idx, ret;
size_t i;
xn = X509_get_issuer_name(x);
- if (!X509_STORE_CTX_get_by_subject(ctx, X509_LU_X509, xn, &obj)) {
+ if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj)) {
return 0;
}
// If certificate matches all OK
- if (x509_check_issued_with_callback(ctx, x, obj.data.x509)) {
+ if (ctx->check_issued(ctx, x, obj.data.x509)) {
*issuer = obj.data.x509;
return 1;
}
X509_OBJECT_free_contents(&obj);
- // Else find index of first cert accepted by
- // |x509_check_issued_with_callback|.
+ // Else find index of first cert accepted by 'check_issued'
ret = 0;
CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
@@ -541,7 +602,7 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) {
if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509))) {
break;
}
- if (x509_check_issued_with_callback(ctx, x, pobj->data.x509)) {
+ if (ctx->check_issued(ctx, x, pobj->data.x509)) {
*issuer = pobj->data.x509;
X509_OBJECT_up_ref_count(pobj);
ret = 1;
@@ -570,12 +631,20 @@ int X509_STORE_set_trust(X509_STORE *ctx, int trust) {
return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
}
-int X509_STORE_set1_param(X509_STORE *ctx, const X509_VERIFY_PARAM *param) {
+int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param) {
return X509_VERIFY_PARAM_set1(ctx->param, param);
}
X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx) { return ctx->param; }
+void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify) {
+ ctx->verify = verify;
+}
+
+X509_STORE_CTX_verify_fn X509_STORE_get_verify(X509_STORE *ctx) {
+ return ctx->verify;
+}
+
void X509_STORE_set_verify_cb(X509_STORE *ctx,
X509_STORE_CTX_verify_cb verify_cb) {
ctx->verify_cb = verify_cb;
@@ -594,6 +663,25 @@ X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(X509_STORE *ctx) {
return ctx->get_issuer;
}
+void X509_STORE_set_check_issued(X509_STORE *ctx,
+ X509_STORE_CTX_check_issued_fn check_issued) {
+ ctx->check_issued = check_issued;
+}
+
+X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(X509_STORE *ctx) {
+ return ctx->check_issued;
+}
+
+void X509_STORE_set_check_revocation(
+ X509_STORE *ctx, X509_STORE_CTX_check_revocation_fn check_revocation) {
+ ctx->check_revocation = check_revocation;
+}
+
+X509_STORE_CTX_check_revocation_fn X509_STORE_get_check_revocation(
+ X509_STORE *ctx) {
+ return ctx->check_revocation;
+}
+
void X509_STORE_set_get_crl(X509_STORE *ctx,
X509_STORE_CTX_get_crl_fn get_crl) {
ctx->get_crl = get_crl;
@@ -612,4 +700,40 @@ X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(X509_STORE *ctx) {
return ctx->check_crl;
}
+void X509_STORE_set_cert_crl(X509_STORE *ctx,
+ X509_STORE_CTX_cert_crl_fn cert_crl) {
+ ctx->cert_crl = cert_crl;
+}
+
+X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(X509_STORE *ctx) {
+ return ctx->cert_crl;
+}
+
+void X509_STORE_set_lookup_certs(X509_STORE *ctx,
+ X509_STORE_CTX_lookup_certs_fn lookup_certs) {
+ ctx->lookup_certs = lookup_certs;
+}
+
+X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(X509_STORE *ctx) {
+ return ctx->lookup_certs;
+}
+
+void X509_STORE_set_lookup_crls(X509_STORE *ctx,
+ X509_STORE_CTX_lookup_crls_fn lookup_crls) {
+ ctx->lookup_crls = lookup_crls;
+}
+
+X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(X509_STORE *ctx) {
+ return ctx->lookup_crls;
+}
+
+void X509_STORE_set_cleanup(X509_STORE *ctx,
+ X509_STORE_CTX_cleanup_fn ctx_cleanup) {
+ ctx->cleanup = ctx_cleanup;
+}
+
+X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(X509_STORE *ctx) {
+ return ctx->cleanup;
+}
+
X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx) { return ctx->ctx; }