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.
This commit is contained in:
parent
7f4301668f
commit
4d50a2b4d6
@ -64,6 +64,7 @@
|
||||
|
||||
static int X509_REVOKED_cmp(const X509_REVOKED * const *a,
|
||||
const X509_REVOKED * const *b);
|
||||
static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp);
|
||||
|
||||
ASN1_SEQUENCE(X509_REVOKED) = {
|
||||
ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER),
|
||||
@ -116,6 +117,8 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
case ASN1_OP_NEW_POST:
|
||||
crl->idp = NULL;
|
||||
crl->akid = NULL;
|
||||
crl->flags = 0;
|
||||
crl->idp_flags = 0;
|
||||
break;
|
||||
|
||||
case ASN1_OP_D2I_POST:
|
||||
@ -124,6 +127,9 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
#endif
|
||||
crl->idp = X509_CRL_get_ext_d2i(crl,
|
||||
NID_issuing_distribution_point, NULL, NULL);
|
||||
if (crl->idp)
|
||||
setup_idp(crl, crl->idp);
|
||||
|
||||
crl->akid = X509_CRL_get_ext_d2i(crl,
|
||||
NID_authority_key_identifier, NULL, NULL);
|
||||
break;
|
||||
@ -138,6 +144,46 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Convert IDP into a more convenient form */
|
||||
|
||||
static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
|
||||
{
|
||||
int idp_only = 0;
|
||||
/* Set various flags according to IDP */
|
||||
crl->idp_flags |= IDP_PRESENT;
|
||||
if (idp->onlyuser > 0)
|
||||
{
|
||||
idp_only++;
|
||||
crl->idp_flags |= IDP_ONLYUSER;
|
||||
}
|
||||
if (idp->onlyCA > 0)
|
||||
{
|
||||
idp_only++;
|
||||
crl->idp_flags |= IDP_ONLYCA;
|
||||
}
|
||||
if (idp->onlyattr > 0)
|
||||
{
|
||||
idp_only++;
|
||||
crl->idp_flags |= IDP_ONLYATTR;
|
||||
}
|
||||
|
||||
if (idp_only > 1)
|
||||
crl->idp_flags |= IDP_INVALID;
|
||||
|
||||
if (idp->indirectCRL > 0)
|
||||
crl->idp_flags |= IDP_INDIRECT;
|
||||
|
||||
if (idp->onlysomereasons)
|
||||
{
|
||||
crl->idp_flags |= IDP_REASONS;
|
||||
if (idp->onlysomereasons->length > 0)
|
||||
crl->idp_reasons = idp->onlysomereasons->data[0];
|
||||
if (idp->onlysomereasons->length > 1)
|
||||
crl->idp_reasons |=
|
||||
(idp->onlysomereasons->data[1] << 8);
|
||||
}
|
||||
}
|
||||
|
||||
ASN1_SEQUENCE_ref(X509_CRL, crl_cb, CRYPTO_LOCK_X509_CRL) = {
|
||||
ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO),
|
||||
ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR),
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -339,6 +339,22 @@ struct ISSUING_DIST_POINT_st
|
||||
int onlyattr;
|
||||
};
|
||||
|
||||
/* Values in idp_flags field */
|
||||
/* IDP present */
|
||||
#define IDP_PRESENT 0x1
|
||||
/* IDP values inconsistent */
|
||||
#define IDP_INVALID 0x2
|
||||
/* onlyuser true */
|
||||
#define IDP_ONLYUSER 0x4
|
||||
/* onlyCA true */
|
||||
#define IDP_ONLYCA 0x8
|
||||
/* onlyattr true */
|
||||
#define IDP_ONLYATTR 0x10
|
||||
/* indirectCRL true */
|
||||
#define IDP_INDIRECT 0x20
|
||||
/* onlysomereasons present */
|
||||
#define IDP_REASONS 0x40
|
||||
|
||||
#define X509V3_conf_err(val) ERR_add_error_data(6, "section:", val->section, \
|
||||
",name:", val->name, ",value:", val->value);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user