CRL refactor

- CheckCertCRLList: check all entries in case a single issuer has multiple CRL's loaded
- test_multiple_crls_same_issuer: testing two different certificates forcing the client to check both CRL's from the same issuer
- CRL_Entry
  - use a lock instead of a mutex to allow multiple threads to access the same list simultaneously
  - add a verifyMutex when doing verification so that we don't have to release the crlLock
- Add allocation and free functions for CRL_Entry
- DupCRL_Entry: simplify copying by copying all static fields in one memcpy
This commit is contained in:
Juliusz Sosinowicz 2023-08-23 16:05:10 +02:00
parent abfcda8750
commit 57ce894393
6 changed files with 218 additions and 205 deletions

View File

@ -0,0 +1,13 @@
-----BEGIN X509 CRL-----
MIICBDCB7QIBATANBgkqhkiG9w0BAQsFADCBlDELMAkGA1UEBhMCVVMxEDAOBgNV
BAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xETAPBgNVBAoMCFNhd3Rvb3Ro
MRMwEQYDVQQLDApDb25zdWx0aW5nMRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20x
HzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20XDTIzMDgyMjE3NDgzNloX
DTI2MDUxODE3NDgzNlowFDASAgEBFw0yMzA4MjIxNzQ4MjlaoA4wDDAKBgNVHRQE
AwIBAzANBgkqhkiG9w0BAQsFAAOCAQEArb/WuyC0mGBJXNdWFACKd8t3xHP1ypbH
IkRyTBXGgsb7zjCiwraMxNBwaypaDURv3uVBIjSF+toJYnEB2cCj8K6VBeMOeqz7
9l7gsP9xy6LP2YosqiN1MuGZP8SxUxBX9RlHPXO4i85s2DKwdBftg0rXdXLbhafx
m6F3+CIIG+J6BO6D9KOrfaNcLZOgY3LTF2Rc1Y9qH2CUNBgfGMalFt1c13MsP2Oa
Z22HWuJbiLPdeyEsFNy/4ROshgB85kMwZWZQA0LnD5gedwRuaAmlFwSuayl3epwE
v0SQy1Kcp6UbZFTELiIoCNC8y9hL56okbux/TtiukU6mQkvIQBidtQ==
-----END X509 CRL-----

View File

@ -92,6 +92,18 @@ mv tmp crl.revoked
#cp crl.revoked ~/wolfssl/certs/crl/crl.revoked
# remove revoked so next time through the normal CA won't have server revoked
cp blank.index.txt demoCA/index.txt
# revoke the general server cert
echo "Step 10"
openssl ca -config ../renewcerts/wolfssl.cnf -revoke ../server-cert.pem -keyfile ../ca-key.pem -cert ../ca-cert.pem
check_result $?
echo "Step 11"
openssl ca -config ../renewcerts/wolfssl.cnf -gencrl -crldays 1000 -out extra-crls/general-server-crl.pem -keyfile ../ca-key.pem -cert ../ca-cert.pem
check_result $?
# remove revoked so next time through the normal CA won't have server revoked
cp blank.index.txt demoCA/index.txt
@ -105,7 +117,7 @@ openssl ca -config ../renewcerts/wolfssl.cnf -gencrl -crldays 1000 -out caEccCrl
check_result $?
# metadata
echo "Step 12"
echo "Step 13"
openssl crl -in caEccCrl.pem -text > tmp
check_result $?
mv tmp caEccCrl.pem
@ -116,12 +128,12 @@ mv tmp caEccCrl.pem
# server-revoked-cert.pem is already revoked in Step 10
#openssl ca -config ../renewcerts/wolfssl.cnf -revoke ../server-revoked-cert.pem -keyfile ../ca-ecc384-key.pem -cert ../ca-ecc384-cert.pem
echo "Step 13"
echo "Step 14"
openssl ca -config ../renewcerts/wolfssl.cnf -gencrl -crldays 1000 -out caEcc384Crl.pem -keyfile ../ca-ecc384-key.pem -cert ../ca-ecc384-cert.pem
check_result $?
# metadata
echo "Step 14"
echo "Step 15"
openssl crl -in caEcc384Crl.pem -text > tmp
check_result $?
mv tmp caEcc384Crl.pem
@ -129,12 +141,12 @@ mv tmp caEcc384Crl.pem
#cp caEcc384Crl.pem ~/wolfssl/certs/crl/caEcc384Crl.pem
# cliCrl
echo "Step 15"
echo "Step 16"
openssl ca -config ../renewcerts/wolfssl.cnf -gencrl -crldays 1000 -out cliCrl.pem -keyfile ../client-key.pem -cert ../client-cert.pem
check_result $?
# metadata
echo "Step 16"
echo "Step 17"
openssl crl -in cliCrl.pem -text > tmp
check_result $?
mv tmp cliCrl.pem
@ -142,12 +154,12 @@ mv tmp cliCrl.pem
#cp cliCrl.pem ~/wolfssl/certs/crl/cliCrl.pem
# eccCliCRL
echo "Step 17"
echo "Step 18"
openssl ca -config ../renewcerts/wolfssl.cnf -gencrl -crldays 1000 -out eccCliCRL.pem -keyfile ../ecc-client-key.pem -cert ../client-ecc-cert.pem
check_result $?
# metadata
echo "Step 18"
echo "Step 19"
openssl crl -in eccCliCRL.pem -text > tmp
check_result $?
mv tmp eccCliCRL.pem
@ -155,12 +167,12 @@ mv tmp eccCliCRL.pem
#cp eccCliCRL.pem ~/wolfssl/certs/crl/eccCliCRL.pem
# eccSrvCRL
echo "Step 19"
echo "Step 20"
openssl ca -config ../renewcerts/wolfssl.cnf -gencrl -crldays 1000 -out eccSrvCRL.pem -keyfile ../ecc-key.pem -cert ../server-ecc.pem
check_result $?
# metadata
echo "Step 20"
echo "Step 21"
openssl crl -in eccSrvCRL.pem -text > tmp
check_result $?
mv tmp eccSrvCRL.pem
@ -168,17 +180,17 @@ mv tmp eccSrvCRL.pem
#cp eccSrvCRL.pem ~/wolfssl/certs/crl/eccSrvCRL.pem
# caEccCrl
echo "Step 21"
echo "Step 22"
openssl ca -config ./wolfssl.cnf -gencrl -crldays 1000 -out caEccCrl.pem -keyfile ../ca-ecc-key.pem -cert ../ca-ecc-cert.pem
check_result $?
# ca-ecc384-cert
echo "Step 22"
echo "Step 23"
openssl ca -config ./wolfssl.cnf -gencrl -crldays 1000 -out caEcc384Crl.pem -keyfile ../ca-ecc384-key.pem -cert ../ca-ecc384-cert.pem
check_result $?
# create crl and crl2 der files for unit test
echo "Step 23"
echo "Step 24"
openssl crl -in crl.pem -inform PEM -out crl.der -outform DER
openssl crl -in crl2.pem -inform PEM -out crl2.der -outform DER

307
src/crl.c
View File

@ -83,7 +83,7 @@ int InitCRL(WOLFSSL_CRL* crl, WOLFSSL_CERT_MANAGER* cm)
#ifdef HAVE_CRL_IO
crl->crlIOCb = NULL;
#endif
if (wc_InitMutex(&crl->crlLock) != 0) {
if (wc_InitRwLock(&crl->crlLock) != 0) {
WOLFSSL_MSG("Init Mutex failed");
return BAD_MUTEX_E;
}
@ -168,9 +168,23 @@ static int InitCRL_Entry(CRL_Entry* crle, DecodedCRL* dcrl, const byte* buff,
return 0;
}
static CRL_Entry* CRL_Entry_new(void* heap)
{
CRL_Entry* crle = (CRL_Entry*)XMALLOC(sizeof(CRL_Entry), heap,
DYNAMIC_TYPE_CRL_ENTRY);
if (crle != NULL) {
XMEMSET(crle, 0, sizeof(CRL_Entry));
if (wc_InitMutex(&crle->verifyMutex) != 0) {
XFREE(crle, heap, DYNAMIC_TYPE_CRL_ENTRY);
crle = NULL;
}
}
(void)heap;
return crle;
}
/* Free all CRL Entry resources */
static void FreeCRL_Entry(CRL_Entry* crle, void* heap)
static void CRL_Entry_free(CRL_Entry* crle, void* heap)
{
#ifdef CRL_STATIC_REVOKED_LIST
if (crle != NULL) {
@ -198,11 +212,12 @@ static void FreeCRL_Entry(CRL_Entry* crle, void* heap)
XFREE(crle->issuer, heap, DYNAMIC_TYPE_X509);
}
#endif
wc_FreeMutex(&crle->verifyMutex);
XFREE(crle, heap, DYNAMIC_TYPE_CRL_ENTRY);
(void)heap;
}
/* Free all CRL resources */
void FreeCRL(WOLFSSL_CRL* crl, int dynamic)
{
@ -219,8 +234,7 @@ void FreeCRL(WOLFSSL_CRL* crl, int dynamic)
crl->currentEntry = NULL;
while(tmp) {
CRL_Entry* next = tmp->next;
FreeCRL_Entry(tmp, crl->heap);
XFREE(tmp, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
CRL_Entry_free(tmp, crl->heap);
tmp = next;
}
@ -238,7 +252,7 @@ void FreeCRL(WOLFSSL_CRL* crl, int dynamic)
if (wolfSSL_CondFree(&crl->cond) != 0)
WOLFSSL_MSG("wolfSSL_CondFree failed in FreeCRL");
#endif
wc_FreeMutex(&crl->crlLock);
wc_FreeRwLock(&crl->crlLock);
if (dynamic) /* free self */
XFREE(crl, crl->heap, DYNAMIC_TYPE_CRL);
}
@ -285,108 +299,71 @@ static int FindRevokedSerial(DecodedCert* cert, RevokedCert* rc, int totalCerts)
#endif
return ret;
}
static int VerifyCRLE(const WOLFSSL_CRL* crl, CRL_Entry* crle)
{
Signer* ca = NULL;
SignatureCtx sigCtx;
int ret = 0;
#ifndef NO_SKID
if (crle->extAuthKeyIdSet)
ca = GetCA(crl->cm, crle->extAuthKeyId);
if (ca == NULL)
ca = GetCAByName(crl->cm, crle->issuerHash);
#else /* NO_SKID */
ca = GetCA(crl->cm, crle->issuerHash);
#endif /* NO_SKID */
if (ca == NULL) {
WOLFSSL_MSG("Did NOT find CRL issuer CA");
return ASN_CRL_NO_SIGNER_E;
}
ret = VerifyCRL_Signature(&sigCtx, crle->toBeSigned, crle->tbsSz,
crle->signature, crle->signatureSz, crle->signatureOID, ca,
crl->heap);
if (ret == 0)
crle->verified = 1;
else
crle->verified = ret;
return ret;
}
static int CheckCertCRLList(WOLFSSL_CRL* crl, DecodedCert* cert, int *pFoundEntry)
{
CRL_Entry* crle;
int foundEntry = 0;
int ret = 0;
if (wc_LockMutex(&crl->crlLock) != 0) {
WOLFSSL_MSG("wc_LockMutex failed");
if (wc_LockRwLock_Rd(&crl->crlLock) != 0) {
WOLFSSL_MSG("wc_LockRwLock_Rd failed");
return BAD_MUTEX_E;
}
crle = crl->crlList;
while (crle) {
for (crle = crl->crlList; crle != NULL; crle = crle->next) {
if (XMEMCMP(crle->issuerHash, cert->issuerHash, CRL_DIGEST_SIZE) == 0) {
WOLFSSL_MSG("Found CRL Entry on list");
if (crle->verified == 0) {
Signer* ca = NULL;
#ifndef NO_SKID
byte extAuthKeyId[KEYID_SIZE];
#endif
byte issuerHash[CRL_DIGEST_SIZE];
byte* tbs;
word32 tbsSz = crle->tbsSz;
byte* sig = NULL;
word32 sigSz = crle->signatureSz;
word32 sigOID = crle->signatureOID;
SignatureCtx sigCtx;
tbs = (byte*)XMALLOC(tbsSz, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
if (tbs == NULL) {
wc_UnLockMutex(&crl->crlLock);
return MEMORY_E;
}
sig = (byte*)XMALLOC(sigSz, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
if (sig == NULL) {
XFREE(tbs, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
wc_UnLockMutex(&crl->crlLock);
return MEMORY_E;
}
XMEMCPY(tbs, crle->toBeSigned, tbsSz);
XMEMCPY(sig, crle->signature, sigSz);
#ifndef NO_SKID
XMEMCPY(extAuthKeyId, crle->extAuthKeyId,
sizeof(extAuthKeyId));
#endif
XMEMCPY(issuerHash, crle->issuerHash, sizeof(issuerHash));
wc_UnLockMutex(&crl->crlLock);
#ifndef NO_SKID
if (crle->extAuthKeyIdSet)
ca = GetCA(crl->cm, extAuthKeyId);
if (ca == NULL)
ca = GetCAByName(crl->cm, issuerHash);
#else /* NO_SKID */
ca = GetCA(crl->cm, issuerHash);
#endif /* NO_SKID */
if (ca == NULL) {
XFREE(sig, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
XFREE(tbs, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
WOLFSSL_MSG("Did NOT find CRL issuer CA");
return ASN_CRL_NO_SIGNER_E;
}
ret = VerifyCRL_Signature(&sigCtx, tbs, tbsSz, sig, sigSz,
sigOID, ca, crl->heap);
XFREE(sig, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
XFREE(tbs, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
if (wc_LockMutex(&crl->crlLock) != 0) {
if (wc_LockMutex(&crle->verifyMutex) != 0) {
WOLFSSL_MSG("wc_LockMutex failed");
return BAD_MUTEX_E;
break;
}
crle = crl->crlList;
while (crle) {
if (XMEMCMP(crle->issuerHash, cert->issuerHash,
CRL_DIGEST_SIZE) == 0) {
/* A different thread may have verified the entry while we were
* waiting for the mutex. */
if (crle->verified == 0)
ret = VerifyCRLE(crl, crle);
if (ret == 0)
crle->verified = 1;
else
crle->verified = ret;
wc_UnLockMutex(&crle->verifyMutex);
XFREE(crle->toBeSigned, crl->heap,
DYNAMIC_TYPE_CRL_ENTRY);
crle->toBeSigned = NULL;
XFREE(crle->signature, crl->heap,
DYNAMIC_TYPE_CRL_ENTRY);
crle->signature = NULL;
break;
}
crle = crle->next;
}
if (crle == NULL || crle->verified < 0)
if (ret != 0)
break;
}
else if (crle->verified < 0) {
if (crle->verified < 0) {
WOLFSSL_MSG("Cannot use CRL as it didn't verify");
ret = crle->verified;
break;
@ -407,17 +384,14 @@ static int CheckCertCRLList(WOLFSSL_CRL* crl, DecodedCert* cert, int *pFoundEntr
}
if (ret == 0) {
foundEntry = 1;
ret = FindRevokedSerial(cert, crle->certs, crle->totalCerts);
if (ret != 0)
break;
}
break;
}
crle = crle->next;
}
if (foundEntry) {
ret = FindRevokedSerial(cert, crle->certs, crle->totalCerts);
}
wc_UnLockMutex(&crl->crlLock);
wc_UnLockRwLock(&crl->crlLock);
*pFoundEntry = foundEntry;
@ -520,8 +494,7 @@ static int AddCRL(WOLFSSL_CRL* crl, DecodedCRL* dcrl, const byte* buff,
crle = crl->currentEntry;
if (crle == NULL) {
crle = (CRL_Entry*)XMALLOC(sizeof(CRL_Entry), crl->heap,
DYNAMIC_TYPE_CRL_ENTRY);
crle = CRL_Entry_new(crl->heap);
if (crle == NULL) {
WOLFSSL_MSG("alloc CRL Entry failed");
return MEMORY_E;
@ -530,25 +503,19 @@ static int AddCRL(WOLFSSL_CRL* crl, DecodedCRL* dcrl, const byte* buff,
if (InitCRL_Entry(crle, dcrl, buff, verified, crl->heap) < 0) {
WOLFSSL_MSG("Init CRL Entry failed");
FreeCRL_Entry(crle, crl->heap);
if (crle != crl->currentEntry) {
XFREE(crle, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
}
CRL_Entry_free(crle, crl->heap);
return -1;
}
if (wc_LockMutex(&crl->crlLock) != 0) {
WOLFSSL_MSG("wc_LockMutex failed");
FreeCRL_Entry(crle, crl->heap);
if (crle != crl->currentEntry) {
XFREE(crle, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
}
if (wc_LockRwLock_Wr(&crl->crlLock) != 0) {
WOLFSSL_MSG("wc_LockRwLock_Wr failed");
CRL_Entry_free(crle, crl->heap);
return BAD_MUTEX_E;
}
crle->next = crl->crlList;
crl->crlList = crle;
wc_UnLockMutex(&crl->crlLock);
wc_UnLockRwLock(&crl->crlLock);
/* Avoid heap-use-after-free after crl->crlList is released */
crl->currentEntry = NULL;
@ -599,8 +566,7 @@ int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type,
}
#endif
crl->currentEntry = (CRL_Entry*)XMALLOC(sizeof(CRL_Entry), crl->heap,
DYNAMIC_TYPE_CRL_ENTRY);
crl->currentEntry = CRL_Entry_new(crl->heap);
if (crl->currentEntry == NULL) {
WOLFSSL_MSG("alloc CRL Entry failed");
#ifdef WOLFSSL_SMALL_STACK
@ -609,14 +575,13 @@ int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type,
FreeDer(&der);
return MEMORY_E;
}
XMEMSET(crl->currentEntry, 0, sizeof(CRL_Entry));
InitDecodedCRL(dcrl, crl->heap);
ret = ParseCRL(crl->currentEntry->certs, dcrl, myBuffer, (word32)sz,
verify, crl->cm);
if (ret != 0 && !(ret == ASN_CRL_NO_SIGNER_E && verify == NO_VERIFY)) {
WOLFSSL_MSG("ParseCRL error");
XFREE(crl->currentEntry, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
CRL_Entry_free(crl->currentEntry, crl->heap);
crl->currentEntry = NULL;
}
else {
@ -701,75 +666,49 @@ static RevokedCert *DupRevokedCertList(RevokedCert* in, void* heap)
static CRL_Entry* DupCRL_Entry(const CRL_Entry* ent, void* heap)
{
CRL_Entry *dupl;
const size_t copyOffset = OFFSETOF(CRL_Entry, next) +
sizeof(ent->next);
#ifdef CRL_STATIC_REVOKED_LIST
if (ent->totalCerts > CRL_MAX_REVOKED_CERTS) {
return NULL;
}
#endif
dupl = (CRL_Entry*)XMALLOC(sizeof(CRL_Entry), heap, DYNAMIC_TYPE_CRL_ENTRY);
dupl = CRL_Entry_new(heap);
if (dupl == NULL) {
WOLFSSL_MSG("alloc CRL Entry failed");
return NULL;
}
XMEMSET(dupl, 0, sizeof(CRL_Entry));
XMEMCPY(dupl->issuerHash, ent->issuerHash, CRL_DIGEST_SIZE);
XMEMCPY(dupl->lastDate, ent->lastDate, MAX_DATE_SIZE);
XMEMCPY(dupl->nextDate, ent->nextDate, MAX_DATE_SIZE);
dupl->lastDateFormat = ent->lastDateFormat;
dupl->nextDateFormat = ent->nextDateFormat;
XMEMCPY((byte*)dupl + copyOffset, (byte*)ent + copyOffset,
sizeof(CRL_Entry) - copyOffset);
#if defined(OPENSSL_EXTRA)
dupl->lastDateAsn1.length = MAX_DATE_SIZE;
XMEMCPY (dupl->lastDateAsn1.data, dupl->lastDate,
dupl->lastDateAsn1.length);
dupl->lastDateAsn1.type = dupl->lastDateFormat;
dupl->nextDateAsn1.length = MAX_DATE_SIZE;
XMEMCPY (dupl->nextDateAsn1.data, dupl->nextDate,
dupl->nextDateAsn1.length);
dupl->nextDateAsn1.type = dupl->nextDateFormat;
#endif
#ifdef CRL_STATIC_REVOKED_LIST
XMEMCPY(dupl->certs, ent->certs, ent->totalCerts*sizeof(RevokedCert));
#else
#ifndef CRL_STATIC_REVOKED_LIST
dupl->certs = DupRevokedCertList(ent->certs, heap);
#endif
dupl->totalCerts = ent->totalCerts;
dupl->verified = ent->verified;
#ifdef OPENSSL_EXTRA
dupl->issuer = wolfSSL_X509_NAME_dup(ent->issuer);
#endif
if (!ent->verified) {
dupl->tbsSz = ent->tbsSz;
dupl->signatureSz = ent->signatureSz;
dupl->signatureOID = ent->signatureOID;
dupl->toBeSigned = (byte*)XMALLOC(dupl->tbsSz, heap,
DYNAMIC_TYPE_CRL_ENTRY);
if (dupl->toBeSigned == NULL) {
FreeCRL_Entry(dupl, heap);
XFREE(dupl, heap, DYNAMIC_TYPE_CRL_ENTRY);
return NULL;
}
dupl->signature = (byte*)XMALLOC(dupl->signatureSz, heap,
DYNAMIC_TYPE_CRL_ENTRY);
if (dupl->signature == NULL) {
FreeCRL_Entry(dupl, heap);
XFREE(dupl, heap, DYNAMIC_TYPE_CRL_ENTRY);
if (dupl->toBeSigned == NULL || dupl->signature == NULL) {
CRL_Entry_free(dupl, heap);
return NULL;
}
XMEMCPY(dupl->toBeSigned, ent->toBeSigned, dupl->tbsSz);
XMEMCPY(dupl->signature, ent->signature, dupl->signatureSz);
#ifndef NO_SKID
dupl->extAuthKeyIdSet = ent->extAuthKeyIdSet;
if (dupl->extAuthKeyIdSet)
XMEMCPY(dupl->extAuthKeyId, ent->extAuthKeyId, KEYID_SIZE);
#endif
}
else {
dupl->toBeSigned = NULL;
dupl->tbsSz = 0;
dupl->signature = NULL;
dupl->signatureSz = 0;
#if !defined(NO_SKID) && !defined(NO_ASN)
dupl->extAuthKeyIdSet = 0;
#endif
}
return dupl;
@ -781,33 +720,26 @@ static CRL_Entry* DupCRL_list(CRL_Entry* crl, void* heap)
{
CRL_Entry* current;
CRL_Entry* head = NULL;
CRL_Entry* prev = NULL;
CRL_Entry** prev = &head;
current = crl;
while (current != NULL) {
for (current = crl; current != NULL; current = current->next) {
CRL_Entry* tmp = DupCRL_Entry(current, heap);
if (tmp != NULL) {
tmp->next = NULL;
if (head == NULL)
head = tmp;
if (prev != NULL)
prev->next = tmp;
prev = tmp;
*prev = tmp;
prev = &tmp->next;
}
else {
WOLFSSL_MSG("Failed to allocate new CRL_Entry structure");
/* free up any existing list */
while (head != NULL) {
current = head;
head = head->next;
FreeCRL_Entry(current, heap);
XFREE(current, heap, DYNAMIC_TYPE_CRL_ENTRY);
CRL_Entry* next = head->next;
CRL_Entry_free(head, heap);
head = next;
}
return NULL;
}
current = current->next;
}
return head;
}
@ -860,7 +792,6 @@ static int DupX509_CRL(WOLFSSL_X509_CRL *dupl, const WOLFSSL_X509_CRL* crl)
/* returns WOLFSSL_SUCCESS on success. Does not take ownership of newcrl */
int wolfSSL_X509_STORE_add_crl(WOLFSSL_X509_STORE *store, WOLFSSL_X509_CRL *newcrl)
{
CRL_Entry *crle;
WOLFSSL_X509_CRL *crl;
WOLFSSL_ENTER("wolfSSL_X509_STORE_add_crl");
@ -872,11 +803,16 @@ int wolfSSL_X509_STORE_add_crl(WOLFSSL_X509_STORE *store, WOLFSSL_X509_CRL *newc
if (crl == NULL) {
return WOLFSSL_FAILURE;
}
if (wc_LockRwLock_Rd(&newcrl->crlLock) != 0) {
WOLFSSL_MSG("wc_LockRwLock_Rd failed");
return BAD_MUTEX_E;
}
if (DupX509_CRL(crl, newcrl) != 0) {
if (crl != NULL)
FreeCRL(crl, 1);
return WOLFSSL_FAILURE;
}
wc_UnLockRwLock(&newcrl->crlLock);
store->crl = store->cm->crl = crl;
if (wolfSSL_CertManagerEnableCRL(store->cm, WOLFSSL_CRL_CHECKALL)
!= WOLFSSL_SUCCESS) {
@ -888,26 +824,29 @@ int wolfSSL_X509_STORE_add_crl(WOLFSSL_X509_STORE *store, WOLFSSL_X509_CRL *newc
/* find tail of current list and add new list */
crl = store->cm->crl;
crle = crl->crlList;
if (newcrl->crlList != NULL) {
CRL_Entry *tail = crle;
CRL_Entry **tail;
CRL_Entry *toAdd;
if (wc_LockMutex(&crl->crlLock) != 0)
{
WOLFSSL_MSG("wc_LockMutex failed");
if (wc_LockRwLock_Wr(&crl->crlLock) != 0) {
WOLFSSL_MSG("wc_LockRwLock_Wr failed");
return BAD_MUTEX_E;
}
if (crl != newcrl && wc_LockRwLock_Rd(&newcrl->crlLock) != 0) {
WOLFSSL_MSG("wc_LockRwLock_Wr failed");
wc_UnLockRwLock(&crl->crlLock);
return BAD_MUTEX_E;
}
toAdd = DupCRL_list(newcrl->crlList, crl->heap);
if (tail == NULL) {
crl->crlList = toAdd;
}
else {
while (tail->next != NULL) tail = tail->next;
tail->next = toAdd;
}
wc_UnLockMutex(&crl->crlLock);
if (crl != newcrl)
wc_UnLockRwLock(&newcrl->crlLock);
tail = &crl->crlList;
while (*tail != NULL)
tail = &(*tail)->next;
*tail = toAdd;
wc_UnLockRwLock(&crl->crlLock);
}
if (wolfSSL_CertManagerEnableCRL(store->cm, WOLFSSL_CRL_CHECKALL)
@ -994,8 +933,8 @@ static int SwapLists(WOLFSSL_CRL* crl)
}
}
if (wc_LockMutex(&crl->crlLock) != 0) {
WOLFSSL_MSG("wc_LockMutex failed");
if (wc_LockRwLock_Wr(&crl->crlLock) != 0) {
WOLFSSL_MSG("wc_LockRwLock_Wr failed");
FreeCRL(tmp, 0);
#ifdef WOLFSSL_SMALL_STACK
XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
@ -1009,7 +948,7 @@ static int SwapLists(WOLFSSL_CRL* crl)
tmp->crlList = crl->crlList;
crl->crlList = newList;
wc_UnLockMutex(&crl->crlLock);
wc_UnLockRwLock(&crl->crlLock);
FreeCRL(tmp, 0);

View File

@ -57789,6 +57789,48 @@ static int test_wolfSSL_CTX_LoadCRL(void)
return EXPECT_RESULT();
}
#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && defined(HAVE_CRL)
static int test_multiple_crls_same_issuer_ctx_ready(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
ExpectIntEQ(wolfSSL_CTX_LoadCRLFile(ctx, "./certs/crl/crl.pem",
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
return EXPECT_RESULT();
}
#endif
static int test_multiple_crls_same_issuer(void)
{
EXPECT_DECLS;
#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && defined(HAVE_CRL)
test_ssl_cbf client_cbs, server_cbs;
struct {
const char* server_cert;
const char* server_key;
} test_params[] = {
{ "./certs/server-cert.pem", "./certs/server-key.pem" },
{ "./certs/server-revoked-cert.pem", "./certs/server-revoked-key.pem" }
};
size_t i;
for (i = 0; i < (sizeof(test_params)/sizeof(*test_params)); i++) {
XMEMSET(&client_cbs, 0, sizeof(client_cbs));
XMEMSET(&server_cbs, 0, sizeof(server_cbs));
server_cbs.certPemFile = test_params[i].server_cert;
server_cbs.keyPemFile = test_params[i].server_key;
client_cbs.crlPemFile = "./certs/crl/extra-crls/general-server-crl.pem";
client_cbs.ctx_ready = test_multiple_crls_same_issuer_ctx_ready;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbs,
&server_cbs, NULL), TEST_FAIL);
}
#endif
return EXPECT_RESULT();
}
static int test_SetTmpEC_DHE_Sz(void)
{
EXPECT_DECLS;
@ -64901,7 +64943,10 @@ static int test_dtls_client_hello_timeout(void)
static int test_certreq_sighash_algos(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
!defined(WOLFSSL_MAX_STRENGTH) && defined(HAVE_ECC) && \
defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256) && \
defined(HAVE_AES_CBC)
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
@ -64911,7 +64956,8 @@ static int test_certreq_sighash_algos(void)
int maxIdx = 0;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
test_ctx.c_ciphers = test_ctx.s_ciphers = "TLS_ECDHE_ECDSA_WITH_NULL_SHA:"
test_ctx.c_ciphers = test_ctx.s_ciphers =
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:"
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
@ -66048,6 +66094,7 @@ TEST_CASE testCases[] = {
TEST_DECL(test_wolfSSL_CTX_use_certificate_chain_file_format),
TEST_DECL(test_wolfSSL_CTX_trust_peer_cert),
TEST_DECL(test_wolfSSL_CTX_LoadCRL),
TEST_DECL(test_multiple_crls_same_issuer),
TEST_DECL(test_wolfSSL_CTX_SetTmpDH_file),
TEST_DECL(test_wolfSSL_CTX_SetTmpDH_buffer),
TEST_DECL(test_wolfSSL_CTX_SetMinMaxDhKey_Sz),

View File

@ -19247,7 +19247,7 @@ static int DecodeKeyUsage(const byte* input, word32 sz, DecodedCert* cert)
#else
ASNGetData dataASN[keyUsageASN_Length];
word32 idx = 0;
byte keyUsage[OPAQUE16_LEN];
byte keyUsage[2];
word32 keyUsageSz = sizeof(keyUsage);
int ret;
WOLFSSL_ENTER("DecodeKeyUsage");

View File

@ -2464,7 +2464,14 @@ typedef struct CRL_Entry CRL_Entry;
#endif
/* Complete CRL */
struct CRL_Entry {
wolfSSL_Mutex verifyMutex;
byte* toBeSigned;
byte* signature;
#if defined(OPENSSL_EXTRA)
WOLFSSL_X509_NAME* issuer; /* X509_NAME type issuer */
#endif
CRL_Entry* next; /* next entry */
/* DupCRL_Entry copies data after the `next` member */
byte issuerHash[CRL_DIGEST_SIZE]; /* issuer hash */
/* byte crlHash[CRL_DIGEST_SIZE]; raw crl data hash */
/* restore the hash here if needed for optimized comparisons */
@ -2484,9 +2491,7 @@ struct CRL_Entry {
int totalCerts; /* number on list */
int version; /* version of certificate */
int verified;
byte* toBeSigned;
word32 tbsSz;
byte* signature;
word32 signatureSz;
word32 signatureOID;
#if !defined(NO_SKID) && !defined(NO_ASN)
@ -2494,9 +2499,6 @@ struct CRL_Entry {
byte extAuthKeyId[KEYID_SIZE];
#endif
int crlNumber; /* CRL number extension */
#if defined(OPENSSL_EXTRA)
WOLFSSL_X509_NAME* issuer; /* X509_NAME type issuer */
#endif
};
@ -2534,7 +2536,7 @@ struct WOLFSSL_CRL {
#ifdef HAVE_CRL_IO
CbCrlIO crlIOCb;
#endif
wolfSSL_Mutex crlLock; /* CRL list lock */
wolfSSL_RwLock crlLock; /* CRL list lock */
CRL_Monitor monitors[WOLFSSL_CRL_MONITORS_LEN];
#ifdef HAVE_CRL_MONITOR
COND_TYPE cond; /* condition to signal setup */