diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2006-09-10 12:38:37 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2006-09-10 12:38:37 +0000 |
commit | 4d50a2b4d6ae7618844380c1ebd5437226286db7 (patch) | |
tree | 72f5b13d45f7f766bbf52e4953aba1804c960b84 /crypto/x509 | |
parent | 7f4301668f83950b33f79424d047832a1989bec2 (diff) |
Add verify callback functions to lookup a STACK of matching certs or CRLs
based on subject name.
New thread safe functions to retrieve matching STACK from X509_STORE.
Cache some IDP components.
Diffstat (limited to 'crypto/x509')
-rw-r--r-- | crypto/x509/x509.h | 3 | ||||
-rw-r--r-- | crypto/x509/x509_lu.c | 95 | ||||
-rw-r--r-- | crypto/x509/x509_vfy.c | 24 | ||||
-rw-r--r-- | crypto/x509/x509_vfy.h | 6 |
4 files changed, 124 insertions, 4 deletions
diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h index 31bc7539bf..de93bf9005 100644 --- a/crypto/x509/x509.h +++ b/crypto/x509/x509.h @@ -454,6 +454,9 @@ struct X509_crl_st /* Copies of various extensions */ AUTHORITY_KEYID *akid; ISSUING_DIST_POINT *idp; + /* Convenient breakdown of IDP */ + int idp_flags; + int idp_reasons; #ifndef OPENSSL_NO_SHA unsigned char sha1_hash[SHA_DIGEST_LENGTH]; #endif diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c index fbb1497fe2..35a8e351c0 100644 --- a/crypto/x509/x509_lu.c +++ b/crypto/x509/x509_lu.c @@ -414,14 +414,15 @@ void X509_OBJECT_free_contents(X509_OBJECT *a) } } -int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, - X509_NAME *name) +static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type, + X509_NAME *name, int *pnmatch) { X509_OBJECT stmp; X509 x509_s; X509_CINF cinf_s; X509_CRL crl_s; X509_CRL_INFO crl_info_s; + int idx; stmp.type=type; switch (type) @@ -441,7 +442,29 @@ int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, return -1; } - return sk_X509_OBJECT_find(h,&stmp); + idx = sk_X509_OBJECT_find(h,&stmp); + if (idx >= 0 && pnmatch) + { + int tidx; + const X509_OBJECT *tobj, *pstmp; + *pnmatch = 1; + pstmp = &stmp; + for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++) + { + tobj = sk_X509_OBJECT_value(h, tidx); + if (!x509_object_cmp(&tobj, &pstmp)) + break; + *pnmatch++; + } + } + return idx; + } + + +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); } X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type, @@ -453,6 +476,72 @@ X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type, return sk_X509_OBJECT_value(h, idx); } +STACK_OF(X509)* X509_STORE_get_certs(X509_STORE *st, X509_NAME *nm) + { + int i, idx, cnt; + STACK_OF(X509) *sk; + X509 *x; + X509_OBJECT *obj; + sk = sk_X509_new_null(); + CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE); + idx = x509_object_idx_cnt(st->objs, X509_LU_X509, nm, &cnt); + if (idx < 0) + { + CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE); + sk_X509_free(sk); + return NULL; + } + for (i = 0; i < cnt; i++, idx++) + { + obj = sk_X509_OBJECT_value(st->objs, i); + x = obj->data.x509; + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + if (!sk_X509_push(sk, x)) + { + CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE); + X509_free(x); + sk_X509_pop_free(sk, X509_free); + return NULL; + } + } + CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE); + return sk; + + } + +STACK_OF(X509_CRL)* X509_STORE_get_crls(X509_STORE *st, X509_NAME *nm) + { + int i, idx, cnt; + STACK_OF(X509_CRL) *sk; + X509_CRL *x; + X509_OBJECT *obj; + sk = sk_X509_CRL_new_null(); + CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE); + idx = x509_object_idx_cnt(st->objs, X509_LU_CRL, nm, &cnt); + if (idx < 0) + { + CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE); + sk_X509_CRL_free(sk); + return NULL; + } + for (i = 0; i < cnt; i++, idx++) + { + obj = sk_X509_OBJECT_value(st->objs, i); + x = obj->data.crl; + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL); + if (!sk_X509_CRL_push(sk, x)) + { + CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE); + X509_CRL_free(x); + sk_X509_CRL_pop_free(sk, X509_CRL_free); + return NULL; + } + } + CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE); + return sk; + + } + X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x) { int idx, i; diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index e2109a4c35..51db63101f 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -79,6 +79,8 @@ static int check_revocation(X509_STORE_CTX *ctx); static int check_cert(X509_STORE_CTX *ctx); static int check_policy(X509_STORE_CTX *ctx); static int internal_verify(X509_STORE_CTX *ctx); +static STACK_OF(X509) * lookup_certs(X509_STORE_CTX *ctx, X509_NAME *nm); +static STACK_OF(X509_CRL) * lookup_crls(X509_STORE_CTX *ctx, X509_NAME *nm); const char *X509_version="X.509" OPENSSL_VERSION_PTEXT; @@ -669,7 +671,7 @@ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, if (check_crl_time(ctx, crl, 0)) { *pcrl = crl; - CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509); + CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL); return 1; } best_crl = crl; @@ -874,6 +876,16 @@ static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) return 1; } +static STACK_OF(X509) * lookup_certs(X509_STORE_CTX *ctx, X509_NAME *nm) + { + return X509_STORE_get_certs(ctx->ctx, nm); + } + +static STACK_OF(X509_CRL) * lookup_crls(X509_STORE_CTX *ctx, X509_NAME *nm) + { + return X509_STORE_get_crls(ctx->ctx, nm); + } + static int check_policy(X509_STORE_CTX *ctx) { int ret; @@ -1461,6 +1473,16 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, else ctx->cert_crl = cert_crl; + if (store && store->lookup_certs) + ctx->lookup_certs = store->lookup_certs; + else + ctx->lookup_certs = lookup_certs; + + if (store && store->lookup_crls) + ctx->lookup_crls = store->lookup_crls; + else + ctx->lookup_crls = lookup_crls; + ctx->check_policy = check_policy; diff --git a/crypto/x509/x509_vfy.h b/crypto/x509/x509_vfy.h index 3f16330444..3c550e1433 100644 --- a/crypto/x509/x509_vfy.h +++ b/crypto/x509/x509_vfy.h @@ -198,6 +198,8 @@ struct x509_store_st int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */ int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */ int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */ + STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm); + STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm); int (*cleanup)(X509_STORE_CTX *ctx); CRYPTO_EX_DATA ex_data; @@ -246,6 +248,8 @@ struct x509_store_ctx_st /* X509_STORE_CTX */ int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */ int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */ int (*check_policy)(X509_STORE_CTX *ctx); + STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm); + STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm); int (*cleanup)(X509_STORE_CTX *ctx); /* The following is built up */ @@ -383,6 +387,8 @@ void X509_OBJECT_free_contents(X509_OBJECT *a); X509_STORE *X509_STORE_new(void ); void X509_STORE_free(X509_STORE *v); +STACK_OF(X509)* X509_STORE_get_certs(X509_STORE *st, X509_NAME *nm); +STACK_OF(X509_CRL)* X509_STORE_get_crls(X509_STORE *st, X509_NAME *nm); int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags); int X509_STORE_set_purpose(X509_STORE *ctx, int purpose); int X509_STORE_set_trust(X509_STORE *ctx, int trust); |