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 */
|
/* 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");
|
||||||
}
|
}
|
||||||
|
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(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);
|
||||||
|
@ -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 */
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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*);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user