forked from wolfSSL/wolfssl
Allow a CRL's signature to be verified on use
This commit is contained in:
committed by
Sean Parkinson
parent
4d77e80d04
commit
4723b8470a
82
src/crl.c
82
src/crl.c
@ -74,7 +74,8 @@ int InitCRL(WOLFSSL_CRL* crl, WOLFSSL_CERT_MANAGER* cm)
|
||||
|
||||
|
||||
/* 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");
|
||||
|
||||
@ -89,6 +90,34 @@ static int InitCRL_Entry(CRL_Entry* crle, DecodedCRL* dcrl)
|
||||
crle->certs = dcrl->certs; /* take ownsership */
|
||||
dcrl->certs = NULL;
|
||||
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;
|
||||
}
|
||||
@ -106,6 +135,10 @@ static void FreeCRL_Entry(CRL_Entry* crle, void* heap)
|
||||
XFREE(tmp, heap, DYNAMIC_TYPE_REVOKED);
|
||||
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;
|
||||
}
|
||||
@ -167,6 +200,46 @@ static int CheckCertCRLList(WOLFSSL_CRL* crl, DecodedCert* cert, int *pFoundEntr
|
||||
int doNextDate = 1;
|
||||
|
||||
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");
|
||||
|
||||
#ifdef WOLFSSL_NO_CRL_NEXT_DATE
|
||||
@ -260,7 +333,8 @@ int CheckCertCRL(WOLFSSL_CRL* crl, DecodedCert* cert)
|
||||
|
||||
|
||||
/* 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;
|
||||
|
||||
@ -272,7 +346,7 @@ static int AddCRL(WOLFSSL_CRL* crl, DecodedCRL* dcrl)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (InitCRL_Entry(crle, dcrl) < 0) {
|
||||
if (InitCRL_Entry(crle, dcrl, buff, verified, crl->heap) < 0) {
|
||||
WOLFSSL_MSG("Init CRL Entry failed");
|
||||
XFREE(crle, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
|
||||
return -1;
|
||||
@ -341,7 +415,7 @@ int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type,
|
||||
WOLFSSL_MSG("ParseCRL error");
|
||||
}
|
||||
else {
|
||||
ret = AddCRL(crl, dcrl);
|
||||
ret = AddCRL(crl, dcrl, myBuffer, ret != ASN_CRL_NO_SIGNER_E);
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("AddCRL error");
|
||||
}
|
||||
|
12
tests/api.c
12
tests/api.c
@ -2763,8 +2763,20 @@ static void test_wolfSSL_X509_LOOKUP_load_file(void)
|
||||
|
||||
AssertNotNull(store = wolfSSL_X509_STORE_new());
|
||||
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",
|
||||
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);
|
||||
|
||||
printf(resultFmt, passed);
|
||||
|
@ -10700,6 +10700,27 @@ static int GetCRL_Signature(const byte* source, word32* idx, DecodedCRL* dcrl,
|
||||
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 */
|
||||
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 */
|
||||
WOLFSSL_MSG("About to verify CRL signature");
|
||||
|
||||
if (ca) {
|
||||
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 {
|
||||
if (ca == NULL) {
|
||||
WOLFSSL_MSG("Did NOT find CRL issuer CA");
|
||||
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 */
|
||||
|
@ -1571,6 +1571,16 @@ struct CRL_Entry {
|
||||
byte nextDateFormat; /* next date format */
|
||||
RevokedCert* certs; /* revoked cert 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
|
||||
};
|
||||
|
||||
|
||||
|
@ -976,6 +976,9 @@ struct DecodedCRL {
|
||||
};
|
||||
|
||||
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 void FreeDecodedCRL(DecodedCRL*);
|
||||
|
||||
|
Reference in New Issue
Block a user