提交 4d50a2b4 编写于 作者: D Dr. Stephen Henson

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.
上级 7f430166
......@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册