Allow a CRL's signature to be verified on use

This commit is contained in:
Sean Parkinson
2017-04-07 14:59:53 +10:00
committed by Sean Parkinson
parent 4d77e80d04
commit 4723b8470a
5 changed files with 129 additions and 27 deletions

View File

@ -74,7 +74,8 @@ int InitCRL(WOLFSSL_CRL* crl, WOLFSSL_CERT_MANAGER* cm)
/* Initialize CRL Entry */ /* Initialize CRL Entry */
static int InitCRL_Entry(CRL_Entry* crle, DecodedCRL* dcrl) static int InitCRL_Entry(CRL_Entry* crle, DecodedCRL* dcrl, const byte* buff,
int verified, void* heap)
{ {
WOLFSSL_ENTER("InitCRL_Entry"); WOLFSSL_ENTER("InitCRL_Entry");
@ -89,6 +90,34 @@ static int InitCRL_Entry(CRL_Entry* crle, DecodedCRL* dcrl)
crle->certs = dcrl->certs; /* take ownsership */ crle->certs = dcrl->certs; /* take ownsership */
dcrl->certs = NULL; dcrl->certs = NULL;
crle->totalCerts = dcrl->totalCerts; crle->totalCerts = dcrl->totalCerts;
crle->verified = verified;
if (!verified) {
crle->tbsSz = dcrl->sigIndex - dcrl->certBegin;
crle->signatureSz = dcrl->sigLength;
crle->signatureOID = dcrl->signatureOID;
crle->toBeSigned = XMALLOC(crle->tbsSz, heap, DYNAMIC_TYPE_CRL_ENTRY);
if (crle->toBeSigned == NULL)
return -1;
crle->signature = XMALLOC(crle->signatureSz, heap,
DYNAMIC_TYPE_CRL_ENTRY);
if (crle->signature == NULL) {
XFREE(crle->signature, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
return -1;
}
XMEMCPY(crle->toBeSigned, buff + dcrl->certBegin, crle->tbsSz);
XMEMCPY(crle->signature, dcrl->signature, crle->signatureSz);
#if !defined(NO_SKID) && defined(CRL_SKID_READY)
crle->extAuthKeyIdSet = dcrl->extAuthKeyIdSet;
if (crle->extAuthKeyIdSet)
XMEMCPY(crle->extAuthKeyId, dcrl->extAuthKeyId, KEYID_SIZE);
#endif
}
else {
crle->toBeSigned = NULL;
crle->signature = NULL;
}
(void)verified;
return 0; return 0;
} }
@ -106,6 +135,10 @@ static void FreeCRL_Entry(CRL_Entry* crle, void* heap)
XFREE(tmp, heap, DYNAMIC_TYPE_REVOKED); XFREE(tmp, heap, DYNAMIC_TYPE_REVOKED);
tmp = next; tmp = next;
} }
if (crle->signature != NULL)
XFREE(crle->signature, heap, DYNAMIC_TYPE_REVOKED);
if (crle->toBeSigned != NULL)
XFREE(crle->toBeSigned, heap, DYNAMIC_TYPE_REVOKED);
(void)heap; (void)heap;
} }
@ -167,6 +200,46 @@ static int CheckCertCRLList(WOLFSSL_CRL* crl, DecodedCert* cert, int *pFoundEntr
int doNextDate = 1; int doNextDate = 1;
WOLFSSL_MSG("Found CRL Entry on list"); WOLFSSL_MSG("Found CRL Entry on list");
if (crle->verified == 0) {
Signer* ca;
wc_UnLockMutex(&crl->crlLock);
#if !defined(NO_SKID) && defined(CRL_SKID_READY)
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(crle->toBeSigned, crle->tbsSz,
crle->signature, crle->signatureSz, crle->signatureOID, ca);
if (wc_LockMutex(&crl->crlLock) != 0) {
WOLFSSL_MSG("wc_LockMutex failed");
return BAD_MUTEX_E;
}
if (ret == 0)
crle->verified = 1;
else {
crle->verified = ret;
break;
}
}
else if (crle->verified < 0) {
WOLFSSL_MSG("Cannot use CRL as it didn't verify");
ret = crle->verified;
break;
}
WOLFSSL_MSG("Checking next date validity"); WOLFSSL_MSG("Checking next date validity");
#ifdef WOLFSSL_NO_CRL_NEXT_DATE #ifdef WOLFSSL_NO_CRL_NEXT_DATE
@ -260,7 +333,8 @@ int CheckCertCRL(WOLFSSL_CRL* crl, DecodedCert* cert)
/* Add Decoded CRL, 0 on success */ /* Add Decoded CRL, 0 on success */
static int AddCRL(WOLFSSL_CRL* crl, DecodedCRL* dcrl) static int AddCRL(WOLFSSL_CRL* crl, DecodedCRL* dcrl, const byte* buff,
int verified)
{ {
CRL_Entry* crle; CRL_Entry* crle;
@ -272,7 +346,7 @@ static int AddCRL(WOLFSSL_CRL* crl, DecodedCRL* dcrl)
return -1; return -1;
} }
if (InitCRL_Entry(crle, dcrl) < 0) { if (InitCRL_Entry(crle, dcrl, buff, verified, crl->heap) < 0) {
WOLFSSL_MSG("Init CRL Entry failed"); WOLFSSL_MSG("Init CRL Entry failed");
XFREE(crle, crl->heap, DYNAMIC_TYPE_CRL_ENTRY); XFREE(crle, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
return -1; return -1;
@ -341,7 +415,7 @@ int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type,
WOLFSSL_MSG("ParseCRL error"); WOLFSSL_MSG("ParseCRL error");
} }
else { else {
ret = AddCRL(crl, dcrl); ret = AddCRL(crl, dcrl, myBuffer, ret != ASN_CRL_NO_SIGNER_E);
if (ret != 0) { if (ret != 0) {
WOLFSSL_MSG("AddCRL error"); WOLFSSL_MSG("AddCRL error");
} }

View File

@ -2763,8 +2763,20 @@ static void test_wolfSSL_X509_LOOKUP_load_file(void)
AssertNotNull(store = wolfSSL_X509_STORE_new()); AssertNotNull(store = wolfSSL_X509_STORE_new());
AssertNotNull(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file())); AssertNotNull(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()));
AssertIntEQ(wolfSSL_X509_LOOKUP_load_file(lookup, "certs/client-ca.pem",
X509_FILETYPE_PEM), 1);
AssertIntEQ(wolfSSL_X509_LOOKUP_load_file(lookup, "certs/crl/crl2.pem", AssertIntEQ(wolfSSL_X509_LOOKUP_load_file(lookup, "certs/crl/crl2.pem",
X509_FILETYPE_PEM), 1); X509_FILETYPE_PEM), 1);
AssertIntEQ(wolfSSL_CertManagerVerify(store->cm, cliCert, SSL_FILETYPE_PEM),
1);
AssertIntEQ(wolfSSL_CertManagerVerify(store->cm, svrCert, SSL_FILETYPE_PEM),
ASN_NO_SIGNER_E);
AssertIntEQ(wolfSSL_X509_LOOKUP_load_file(lookup, "certs/ca-cert.pem",
X509_FILETYPE_PEM), 1);
AssertIntEQ(wolfSSL_CertManagerVerify(store->cm, svrCert, SSL_FILETYPE_PEM),
1);
wolfSSL_X509_STORE_free(store); wolfSSL_X509_STORE_free(store);
printf(resultFmt, passed); printf(resultFmt, passed);

View File

@ -10700,6 +10700,27 @@ static int GetCRL_Signature(const byte* source, word32* idx, DecodedCRL* dcrl,
return 0; return 0;
} }
int VerifyCRL_Signature(const byte* toBeSigned, word32 tbsSz,
const byte* signature, word32 sigSz,
word32 signatureOID, Signer *ca)
{
/* try to confirm/verify signature */
#ifndef IGNORE_KEY_EXTENSIONS
if ((ca->keyUsage & KEYUSE_CRL_SIGN) == 0) {
WOLFSSL_MSG("CA cannot sign CRLs");
return ASN_CRL_NO_SIGNER_E;
}
#endif /* IGNORE_KEY_EXTENSIONS */
InitSignatureCtx(&sigCtx, dcrl->heap, INVALID_DEVID);
if (ConfirmSignature(toBeSigned, tbsSz, ca->publicKey, ca->pubKeySize,
ca->keyOID, signature, sigSz, signatureOID, NULL) != 0) {
WOLFSSL_MSG("CRL Confirm signature failed");
return ASN_CRL_CONFIRM_E;
}
return 0;
}
/* prase crl buffer into decoded state, 0 on success */ /* prase crl buffer into decoded state, 0 on success */
int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm) int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm)
@ -10797,33 +10818,15 @@ int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm)
#endif /* !NO_SKID && CRL_SKID_READY */ #endif /* !NO_SKID && CRL_SKID_READY */
WOLFSSL_MSG("About to verify CRL signature"); WOLFSSL_MSG("About to verify CRL signature");
if (ca) { if (ca == NULL) {
SignatureCtx sigCtx;
WOLFSSL_MSG("Found CRL issuer CA");
/* try to confirm/verify signature */
#ifndef IGNORE_KEY_EXTENSIONS
if ((ca->keyUsage & KEYUSE_CRL_SIGN) == 0) {
WOLFSSL_MSG("CA cannot sign CRLs");
return ASN_CRL_NO_SIGNER_E;
}
#endif /* IGNORE_KEY_EXTENSIONS */
InitSignatureCtx(&sigCtx, dcrl->heap, INVALID_DEVID);
if (ConfirmSignature(&sigCtx, buff + dcrl->certBegin,
dcrl->sigIndex - dcrl->certBegin,
ca->publicKey, ca->pubKeySize, ca->keyOID,
dcrl->signature, dcrl->sigLength, dcrl->signatureOID) != 0) {
WOLFSSL_MSG("CRL Confirm signature failed");
return ASN_CRL_CONFIRM_E;
}
}
else {
WOLFSSL_MSG("Did NOT find CRL issuer CA"); WOLFSSL_MSG("Did NOT find CRL issuer CA");
return ASN_CRL_NO_SIGNER_E; return ASN_CRL_NO_SIGNER_E;
} }
return ret; WOLFSSL_MSG("Found CRL issuer CA");
return VerifyCRL_Signature(buff + dcrl->certBegin,
dcrl->sigIndex - dcrl->certBegin, dcrl->signature, dcrl->sigLength,
dcrl->signatureOID, ca);
} }
#endif /* HAVE_CRL */ #endif /* HAVE_CRL */

View File

@ -1571,6 +1571,16 @@ struct CRL_Entry {
byte nextDateFormat; /* next date format */ byte nextDateFormat; /* next date format */
RevokedCert* certs; /* revoked cert list */ RevokedCert* certs; /* revoked cert list */
int totalCerts; /* number on list */ int totalCerts; /* number on list */
int verified;
byte* toBeSigned;
word32 tbsSz;
byte* signature;
word32 signatureSz;
word32 signatureOID;
#if !defined(NO_SKID) && defined(CRL_SKID_READY)
byte extAuthKeyIdSet;
byte extAuthKeyId[KEYID_SIZE];
#endif
}; };

View File

@ -976,6 +976,9 @@ struct DecodedCRL {
}; };
WOLFSSL_LOCAL void InitDecodedCRL(DecodedCRL*, void* heap); WOLFSSL_LOCAL void InitDecodedCRL(DecodedCRL*, void* heap);
WOLFSSL_LOCAL int VerifyCRL_Signature(const byte* toBeSigned, word32 tbsSz,
const byte* signature, word32 sigSz,
word32 signatureOID, Signer *ca);
WOLFSSL_LOCAL int ParseCRL(DecodedCRL*, const byte* buff, word32 sz, void* cm); WOLFSSL_LOCAL int ParseCRL(DecodedCRL*, const byte* buff, word32 sz, void* cm);
WOLFSSL_LOCAL void FreeDecodedCRL(DecodedCRL*); WOLFSSL_LOCAL void FreeDecodedCRL(DecodedCRL*);