Cache some CRL related extensions.
authorDr. Stephen Henson <steve@openssl.org>
Mon, 24 Jul 2006 12:39:22 +0000 (12:39 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Mon, 24 Jul 2006 12:39:22 +0000 (12:39 +0000)
CHANGES
crypto/asn1/x_crl.c
crypto/asn1/x_x509.c
crypto/ossl_typ.h
crypto/x509/x509.h
crypto/x509/x509_cmp.c
crypto/x509v3/v3_purp.c
crypto/x509v3/x509v3.h

diff --git a/CHANGES b/CHANGES
index 2c1dadd..96f2fbd 100644 (file)
--- 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().
index 0f72711..8943b84 100644 (file)
@@ -60,6 +60,7 @@
 #include "cryptlib.h"
 #include <openssl/asn1t.h>
 #include <openssl/x509.h>
+#include <openssl/x509v3.h>
 
 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)
index 086021c..73f61e1 100644 (file)
@@ -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);
index 7cc38ce..5ebf0fa 100644 (file)
@@ -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 */
index 51d8baf..ac5e4b6 100644 (file)
@@ -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)
index 4f157ba..180dedc 100644 (file)
@@ -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);
index e64a528..ee2f08f 100644 (file)
@@ -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);
index f42f0f7..1e2f00a 100644 (file)
@@ -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);