From edc540211c4852c57c01743a068aecc0e0a97b5c Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Mon, 24 Jul 2006 12:39:22 +0000 Subject: [PATCH] Cache some CRL related extensions. --- CHANGES | 6 ++++++ crypto/asn1/x_crl.c | 38 +++++++++++++++++++++++++++++++++++++- crypto/asn1/x_x509.c | 2 ++ crypto/ossl_typ.h | 4 ++++ crypto/x509/x509.h | 10 +++++++++- crypto/x509/x509_cmp.c | 7 +++++++ crypto/x509v3/v3_purp.c | 1 + crypto/x509v3/x509v3.h | 12 ++++++------ 8 files changed, 72 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index 2c1daddf2b..96f2fbdd09 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,12 @@ Changes between 0.9.8b and 0.9.9 [xx XXX xxxx] + *) New function X509_CRL_match() to check if two CRLs are identical. Normally + this would be called X509_CRL_cmp() but that name is already used by + a function that just compares CRL issuer names. Cache several CRL + extensions in X509_CRL structure and cache CRLDP in X509. + [Steve Henson] + *) Store a "canonical" representation of X509_NAME structure (ASN1 Name) this maps equivalent X509_NAME structures into a consistent structure. Name comparison can then be performed rapidly using memcmp(). diff --git a/crypto/asn1/x_crl.c b/crypto/asn1/x_crl.c index 0f72711452..8943b84373 100644 --- a/crypto/asn1/x_crl.c +++ b/crypto/asn1/x_crl.c @@ -60,6 +60,7 @@ #include "cryptlib.h" #include #include +#include static int X509_REVOKED_cmp(const X509_REVOKED * const *a, const X509_REVOKED * const *b); @@ -102,7 +103,42 @@ ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = { ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0) } ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO) -ASN1_SEQUENCE_ref(X509_CRL, 0, CRYPTO_LOCK_X509_CRL) = { +/* The X509_CRL structure needs a bit of customisation. Cache some extensions + * and hash of the whole CRL. + */ +static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) + { + X509_CRL *crl = (X509_CRL *)*pval; + + switch(operation) + { + case ASN1_OP_NEW_POST: + crl->idp = NULL; + crl->akid = NULL; + break; + + case ASN1_OP_D2I_POST: +#ifndef OPENSSL_NO_SHA + X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL); +#endif + crl->idp = X509_CRL_get_ext_d2i(crl, + NID_issuing_distribution_point, NULL, NULL); + crl->akid = X509_CRL_get_ext_d2i(crl, + NID_authority_key_identifier, NULL, NULL); + break; + + case ASN1_OP_FREE_POST: + if (crl->akid) + AUTHORITY_KEYID_free(crl->akid); + if (crl->idp) + ISSUING_DIST_POINT_free(crl->idp); + break; + } + return 1; + } + +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), ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING) diff --git a/crypto/asn1/x_x509.c b/crypto/asn1/x_x509.c index 086021c5a1..73f61e1eb9 100644 --- a/crypto/asn1/x_x509.c +++ b/crypto/asn1/x_x509.c @@ -96,6 +96,7 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, ret->skid = NULL; ret->akid = NULL; ret->aux = NULL; + ret->crldp = NULL; CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data); break; @@ -109,6 +110,7 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, X509_CERT_AUX_free(ret->aux); ASN1_OCTET_STRING_free(ret->skid); AUTHORITY_KEYID_free(ret->akid); + CRL_DIST_POINTS_free(ret->crldp); policy_cache_free(ret->policy_cache); if (ret->name != NULL) OPENSSL_free(ret->name); diff --git a/crypto/ossl_typ.h b/crypto/ossl_typ.h index 7cc38ce734..5ebf0fab1c 100644 --- a/crypto/ossl_typ.h +++ b/crypto/ossl_typ.h @@ -168,6 +168,10 @@ typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL; typedef struct X509_POLICY_TREE_st X509_POLICY_TREE; typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE; +typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID; +typedef struct DIST_POINT_st DIST_POINT; +typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT; + /* If placed in pkcs12.h, we end up with a circular depency with pkcs7.h */ #define DECLARE_PKCS12_STACK_OF(type) /* Nothing */ #define IMPLEMENT_PKCS12_STACK_OF(type) /* Nothing */ diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h index 51d8baf82e..ac5e4b60e4 100644 --- a/crypto/x509/x509.h +++ b/crypto/x509/x509.h @@ -288,8 +288,9 @@ struct x509_st unsigned long ex_xkusage; unsigned long ex_nscert; ASN1_OCTET_STRING *skid; - struct AUTHORITY_KEYID_st *akid; + AUTHORITY_KEYID *akid; X509_POLICY_CACHE *policy_cache; + STACK_OF(DIST_POINT) *crldp; #ifndef OPENSSL_NO_SHA unsigned char sha1_hash[SHA_DIGEST_LENGTH]; #endif @@ -449,6 +450,13 @@ struct X509_crl_st X509_ALGOR *sig_alg; ASN1_BIT_STRING *signature; int references; + int flags; + /* Copies of various extensions */ + AUTHORITY_KEYID *akid; + ISSUING_DIST_POINT *idp; +#ifndef OPENSSL_NO_SHA + unsigned char sha1_hash[SHA_DIGEST_LENGTH]; +#endif } /* X509_CRL */; DECLARE_STACK_OF(X509_CRL) diff --git a/crypto/x509/x509_cmp.c b/crypto/x509/x509_cmp.c index 4f157ba807..180dedc7fa 100644 --- a/crypto/x509/x509_cmp.c +++ b/crypto/x509/x509_cmp.c @@ -116,6 +116,13 @@ int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b) return(X509_NAME_cmp(a->crl->issuer,b->crl->issuer)); } +#ifndef OPENSSL_NO_SHA +int X509_CRL_match(const X509_CRL *a, const X509_CRL *b) + { + return memcmp(a->sha1_hash, b->sha1_hash, 20); + } +#endif + X509_NAME *X509_get_issuer_name(X509 *a) { return(a->cert_info->issuer); diff --git a/crypto/x509v3/v3_purp.c b/crypto/x509v3/v3_purp.c index e64a528bf7..ee2f08fe2d 100644 --- a/crypto/x509v3/v3_purp.c +++ b/crypto/x509v3/v3_purp.c @@ -412,6 +412,7 @@ static void x509v3_cache_extensions(X509 *x) } x->skid =X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL); x->akid =X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL); + x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL); for (i = 0; i < X509_get_ext_count(x); i++) { ex = X509_get_ext(x, i); diff --git a/crypto/x509v3/x509v3.h b/crypto/x509v3/x509v3.h index f42f0f7463..1e2f00ab24 100644 --- a/crypto/x509v3/x509v3.h +++ b/crypto/x509v3/x509v3.h @@ -222,22 +222,22 @@ union { } name; } DIST_POINT_NAME; -typedef struct DIST_POINT_st { +struct DIST_POINT_st { DIST_POINT_NAME *distpoint; ASN1_BIT_STRING *reasons; GENERAL_NAMES *CRLissuer; -} DIST_POINT; +}; typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS; DECLARE_STACK_OF(DIST_POINT) DECLARE_ASN1_SET_OF(DIST_POINT) -typedef struct AUTHORITY_KEYID_st { +struct AUTHORITY_KEYID_st { ASN1_OCTET_STRING *keyid; GENERAL_NAMES *issuer; ASN1_INTEGER *serial; -} AUTHORITY_KEYID; +}; /* Strong extranet structures */ @@ -329,7 +329,7 @@ typedef struct PROXY_CERT_INFO_EXTENSION_st DECLARE_ASN1_FUNCTIONS(PROXY_POLICY) DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) -typedef struct ISSUING_DIST_POINT_st +struct ISSUING_DIST_POINT_st { DIST_POINT_NAME *distpoint; int onlyuser; @@ -337,7 +337,7 @@ typedef struct ISSUING_DIST_POINT_st ASN1_BIT_STRING *onlysomereasons; int indirectCRL; int onlyattr; - } ISSUING_DIST_POINT; + }; #define X509V3_conf_err(val) ERR_add_error_data(6, "section:", val->section, \ ",name:", val->name, ",value:", val->value); -- 2.25.1