ASF Bugzilla – Attachment 27749 Details for
Bug 45708
CRL verification fails if CA have distinct AKID for CRL and client certificates
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
patch for mod_ssl in order to support more than one crl issued by different CAs with the same subject
httpd-2.2.21_crl.diff (text/plain), 11.54 KB, created by
sektor
on 2011-10-10 08:02:55 UTC
(
hide
)
Description:
patch for mod_ssl in order to support more than one crl issued by different CAs with the same subject
Filename:
MIME Type:
Creator:
sektor
Created:
2011-10-10 08:02:55 UTC
Size:
11.54 KB
patch
obsolete
>diff -rupN httpd-2.2.21.orig/modules/ssl/ssl_engine_kernel.c httpd-2.2.21.new/modules/ssl/ssl_engine_kernel.c >--- httpd-2.2.21.orig/modules/ssl/ssl_engine_kernel.c 2010-02-27 22:00:58.000000000 +0100 >+++ httpd-2.2.21.new/modules/ssl/ssl_engine_kernel.c 2011-10-06 18:42:25.000000000 +0200 >@@ -1433,6 +1433,9 @@ int ssl_callback_SSLVerify_CRL(int ok, X > X509 *cert; > X509_CRL *crl; > EVP_PKEY *pubkey; >+ ASN1_OCTET_STRING *skid = NULL; >+ ASN1_OCTET_STRING *akid = NULL; >+ AUTHORITY_KEYID *akid_st = NULL; > int i, n, rc; > > /* >@@ -1449,6 +1452,10 @@ int ssl_callback_SSLVerify_CRL(int ok, X > cert = X509_STORE_CTX_get_current_cert(ctx); > subject = X509_get_subject_name(cert); > issuer = X509_get_issuer_name(cert); >+ skid = X509_get_ext_d2i(cert, NID_subject_key_identifier, NULL, NULL); >+ akid_st = X509_get_ext_d2i(cert, NID_authority_key_identifier, NULL, NULL); >+ if (akid_st) >+ akid = akid_st->keyid; > > /* > * OpenSSL provides the general mechanism to deal with CRLs but does not >@@ -1482,12 +1489,16 @@ int ssl_callback_SSLVerify_CRL(int ok, X > */ > > /* >- * Try to retrieve a CRL corresponding to the _subject_ of >- * the current certificate in order to verify it's integrity. >+ * Try to retrieve a CRL where: >+ * 1. CRL subject == current certificate subject (we can have multiple CRLs >+ * with same subject) AND >+ * 2. CRL authority key identifier == current certificate subject key >+ * identifier > */ > memset((char *)&obj, 0, sizeof(obj)); >- rc = SSL_X509_STORE_lookup(mctx->crl, >- X509_LU_CRL, subject, &obj); >+ rc = SSL_X509_STORE_lookup_by_suject_and_akid(mctx->crl, >+ X509_LU_CRL, subject, skid, &obj); >+ > crl = obj.data.crl; > > if ((rc > 0) && crl) { >@@ -1496,9 +1507,11 @@ int ssl_callback_SSLVerify_CRL(int ok, X > * (A little bit complicated because of ASN.1 and BIOs...) > */ > if (s->loglevel >= APLOG_DEBUG) { >- char buff[512]; /* should be plenty */ >+ char buff[1024]; /* should be plenty */ >+ AUTHORITY_KEYID *crlakid_st = NULL; > BIO *bio = BIO_new(BIO_s_mem()); > >+ BIO_printf(bio, "First step - "); > BIO_printf(bio, "CA CRL: Issuer: "); > X509_NAME_print(bio, issuer, 0); > >@@ -1508,6 +1521,16 @@ int ssl_callback_SSLVerify_CRL(int ok, X > BIO_printf(bio, ", nextUpdate: "); > ASN1_UTCTIME_print(bio, X509_CRL_get_nextUpdate(crl)); > >+ crlakid_st = X509_CRL_get_ext_d2i(crl, NID_authority_key_identifier, NULL, NULL); >+ BIO_printf(bio, ", CRL akid: "); >+ i2a_ASN1_STRING(bio, (ASN1_STRING*)(crlakid_st->keyid), 0); >+ >+ BIO_printf(bio, ", Certificate akid: "); >+ i2a_ASN1_STRING(bio, (ASN1_STRING*)akid, 0); >+ >+ BIO_printf(bio, ", Certificate skid: "); >+ i2a_ASN1_STRING(bio, (ASN1_STRING*)skid, 0); >+ > n = BIO_read(bio, buff, sizeof(buff) - 1); > buff[n] = '\0'; > >@@ -1566,29 +1589,73 @@ int ssl_callback_SSLVerify_CRL(int ok, X > } > > /* >- * Try to retrieve a CRL corresponding to the _issuer_ of >- * the current certificate in order to check for revocation. >+ * Try to retrieve a CRL where: >+ * 1. CRL subject == current certificate issuer (we can have multiple CRLs >+ * with same subject) AND >+ * 2. CRL authority key identifier == current certificate authority key >+ * identifier > */ > memset((char *)&obj, 0, sizeof(obj)); >- rc = SSL_X509_STORE_lookup(mctx->crl, >- X509_LU_CRL, issuer, &obj); >+ rc = SSL_X509_STORE_lookup_by_suject_and_akid(mctx->crl, >+ X509_LU_CRL, issuer, akid, &obj); >+ > > crl = obj.data.crl; > if ((rc > 0) && crl) { >+ >+ if (s->loglevel >= APLOG_DEBUG) { >+ char buff[1024]; /* should be plenty */ >+ AUTHORITY_KEYID *crlakid_st = NULL; >+ BIO *bio = BIO_new(BIO_s_mem()); >+ >+ BIO_printf(bio, "Second step - "); >+ BIO_printf(bio, "CA CRL: Issuer: "); >+ X509_NAME_print(bio, issuer, 0); >+ >+ BIO_printf(bio, ", lastUpdate: "); >+ ASN1_UTCTIME_print(bio, X509_CRL_get_lastUpdate(crl)); >+ >+ BIO_printf(bio, ", nextUpdate: "); >+ ASN1_UTCTIME_print(bio, X509_CRL_get_nextUpdate(crl)); >+ >+ crlakid_st = X509_CRL_get_ext_d2i(crl, NID_authority_key_identifier, NULL, NULL); >+ BIO_printf(bio, ", CRL akid: "); >+ i2a_ASN1_STRING(bio, (ASN1_STRING*)(crlakid_st->keyid), 0); >+ >+ BIO_printf(bio, ", Certificate akid: "); >+ i2a_ASN1_STRING(bio, (ASN1_STRING*)akid, 0); >+ >+ BIO_printf(bio, ", Certificate skid: "); >+ i2a_ASN1_STRING(bio, (ASN1_STRING*)skid, 0); >+ >+ n = BIO_read(bio, buff, sizeof(buff) - 1); >+ buff[n] = '\0'; >+ >+ BIO_free(bio); >+ >+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "%s", buff); >+ } >+ >+ > /* > * Check if the current certificate is revoked by this CRL > */ > n = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl)); > >+ /* >+ * Get serial number of current certificate. >+ */ >+ ASN1_INTEGER *cert_sn = X509_get_serialNumber(cert); > for (i = 0; i < n; i++) { > X509_REVOKED *revoked = > sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i); > > ASN1_INTEGER *sn = X509_REVOKED_get_serialNumber(revoked); > >- if (!ASN1_INTEGER_cmp(sn, X509_get_serialNumber(cert))) { >+ if (!ASN1_INTEGER_cmp(sn, cert_sn)) { > if (s->loglevel >= APLOG_DEBUG) { > char *cp = X509_NAME_oneline(issuer, NULL, 0); >+ /* Here we should use BIGNUM instead of long. */ > long serial = ASN1_INTEGER_get(sn); > > ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, >@@ -1949,7 +2016,7 @@ void ssl_callback_Info(MODSSL_INFO_CB_AR > * read. */ > if ((where & SSL_CB_ACCEPT_LOOP) && scr->reneg_state == RENEG_REJECT) { > int state = SSL_get_state(ssl); >- >+ > if (state == SSL3_ST_SR_CLNT_HELLO_A > || state == SSL23_ST_SR_CLNT_HELLO_A) { > scr->reneg_state = RENEG_ABORT; >diff -rupN httpd-2.2.21.orig/modules/ssl/ssl_util_ssl.c httpd-2.2.21.new/modules/ssl/ssl_util_ssl.c >--- httpd-2.2.21.orig/modules/ssl/ssl_util_ssl.c 2009-08-06 09:28:47.000000000 +0200 >+++ httpd-2.2.21.new/modules/ssl/ssl_util_ssl.c 2011-10-06 12:52:43.000000000 +0200 >@@ -241,6 +241,163 @@ int SSL_X509_STORE_lookup(X509_STORE *pS > return rc; > } > >+#if SSL_LIBRARY_VERSION <= 0x00909000 >+/* This function is defined in the upcoming 0.9.9 version of OpenSSL, >+ * I'm just replicating its behaviour, and its prototype >+ */ >+static int x509_object_cmp(const X509_OBJECT * const *a, const X509_OBJECT * const *b) >+{ >+ int ret; >+ >+ ret=((*a)->type - (*b)->type); >+ if (ret) return ret; >+ switch ((*a)->type) >+ { >+ case X509_LU_X509: >+ ret=X509_subject_name_cmp((*a)->data.x509,(*b)->data.x509); >+ break; >+ case X509_LU_CRL: >+ ret=X509_CRL_cmp((*a)->data.crl,(*b)->data.crl); >+ break; >+ default: >+ /* abort(); */ >+ return 0; >+ } >+ return ret; >+} >+ >+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) >+ { >+ case X509_LU_X509: >+ stmp.data.x509= &x509_s; >+ x509_s.cert_info= &cinf_s; >+ cinf_s.subject=name; >+ break; >+ case X509_LU_CRL: >+ stmp.data.crl= &crl_s; >+ crl_s.crl= &crl_info_s; >+ crl_info_s.issuer=name; >+ break; >+ default: >+ /* abort(); */ >+ return -1; >+ } >+ >+ 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; >+} >+ >+STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm) >+{ >+ int i, idx, cnt; >+ STACK_OF(X509_CRL) *sk; >+ X509_CRL *x; >+ X509_OBJECT *obj, xobj; >+ sk = sk_X509_CRL_new_null(); >+ CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); >+ /* Check cache first */ >+ idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt); >+ >+ /* Always do lookup to possibly add new CRLs to cache >+ */ >+ CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); >+ if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj)) >+ { >+ sk_X509_CRL_free(sk); >+ return NULL; >+ } >+ X509_OBJECT_free_contents(&xobj); >+ CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); >+ idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_CRL, nm, &cnt); >+ if (idx < 0) >+ { >+ CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); >+ sk_X509_CRL_free(sk); >+ return NULL; >+ } >+ >+ for (i = 0; i < cnt; i++, idx++) >+ { >+ obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); >+ x = obj->data.crl; >+ CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL); >+ if (!sk_X509_CRL_push(sk, x)) >+ { >+ CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); >+ X509_CRL_free(x); >+ sk_X509_CRL_pop_free(sk, X509_CRL_free); >+ return NULL; >+ } >+ } >+ CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); >+ return sk; >+} >+ >+#endif >+ >+int SSL_X509_STORE_lookup_by_suject_and_akid(X509_STORE *pStore, int nType, >+ X509_NAME *pName, ASN1_OCTET_STRING *akid, X509_OBJECT *pObj) >+{ >+ X509_STORE_CTX pStoreCtx; >+ int rc = 0; >+ STACK_OF(X509_CRL) *crls; >+ int n, i; >+ AUTHORITY_KEYID *akid_st; >+ ASN1_OCTET_STRING *testedakid; >+ X509_CRL *testedcrl; >+ X509_CRL *foundcrl = NULL; >+ >+ X509_STORE_CTX_init(&pStoreCtx, pStore, NULL, NULL); >+ crls = X509_STORE_get1_crls(&pStoreCtx, pName); >+ if (crls) { >+ n = sk_X509_CRL_num(crls); >+ for (i = 0; i < n; i++) { >+ testedcrl = sk_X509_CRL_value(crls, i); >+ akid_st = X509_CRL_get_ext_d2i(testedcrl, NID_authority_key_identifier, NULL, NULL); >+ if (!akid_st) >+ continue; >+ testedakid = akid_st->keyid; >+ if (ASN1_OCTET_STRING_cmp(testedakid, akid) == 0) { >+ foundcrl = sk_X509_CRL_delete(crls, i); >+ break; >+ } >+ } >+ if (foundcrl) { >+ pObj->type = X509_LU_CRL; >+ pObj->data.crl = foundcrl; >+ rc = 1; >+ } >+ sk_X509_CRL_pop_free(crls, X509_CRL_free); >+ } >+ X509_STORE_CTX_cleanup(&pStoreCtx); >+ return rc; >+} >+ > /* _________________________________________________________________ > ** > ** Cipher Suite Spec String Creation >diff -rupN httpd-2.2.21.orig/modules/ssl/ssl_util_ssl.h httpd-2.2.21.new/modules/ssl/ssl_util_ssl.h >--- httpd-2.2.21.orig/modules/ssl/ssl_util_ssl.h 2007-08-28 15:40:01.000000000 +0200 >+++ httpd-2.2.21.new/modules/ssl/ssl_util_ssl.h 2011-10-06 18:38:58.000000000 +0200 >@@ -82,6 +82,7 @@ EVP_PKEY *SSL_read_PrivateKey(char *, > int SSL_smart_shutdown(SSL *ssl); > X509_STORE *SSL_X509_STORE_create(char *, char *); > int SSL_X509_STORE_lookup(X509_STORE *, int, X509_NAME *, X509_OBJECT *); >+int SSL_X509_STORE_lookup_by_suject_and_akid(X509_STORE *pStore, int nType, X509_NAME *pName, ASN1_OCTET_STRING *akid, X509_OBJECT *pObj); > char *SSL_make_ciphersuite(apr_pool_t *, SSL *); > BOOL SSL_X509_isSGC(X509 *); > BOOL SSL_X509_getBC(X509 *, int *, int *);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 45708
: 27749