From 293719c16850aa5bfc98587e615095f4da520262 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 2 Sep 2024 15:25:53 +0000 Subject: [PATCH 1/2] ocsp: search CA by key hash instead of ext key id --- src/ssl.c | 30 ++++++++++++++++++++++++++++++ wolfcrypt/src/asn.c | 4 ++-- wolfssl/internal.h | 3 +++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index b4bf40744..2940215e8 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -5102,6 +5102,36 @@ Signer* GetCA(void* vp, byte* hash) return ret; } +#if defined(HAVE_OCSP) +Signer* GetCAByKeyHash(void* vp, const byte* keyHash) +{ + WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp; + Signer* ret = NULL; + Signer* signers; + int row; + + if (cm == NULL || keyHash == NULL) + return NULL; + + if (wc_LockMutex(&cm->caLock) != 0) + return NULL; + + /* Unfortunately we need to look through the entire table */ + for (row = 0; row < CA_TABLE_SIZE && ret == NULL; row++) { + for (signers = cm->caTable[row]; signers != NULL; + signers = signers->next) { + if (XMEMCMP(signers->subjectKeyHash, keyHash, KEYID_SIZE) + == 0) { + ret = signers; + break; + } + } + } + + wc_UnLockMutex(&cm->caLock); + return ret; +} +#endif #ifdef WOLFSSL_AKID_NAME Signer* GetCAByAKID(void* vp, const byte* issuer, word32 issuerSz, const byte* serial, word32 serialSz) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 06dfa0df5..431b833d7 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -36770,7 +36770,7 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex, int sigValid = -1; #ifndef NO_SKID - ca = GetCA(cm, resp->single->issuerKeyHash); + ca = GetCAByKeyHash(cm, resp->single->issuerKeyHash); #else ca = GetCA(cm, resp->single->issuerHash); #endif @@ -36911,7 +36911,7 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex, /* Response didn't have a certificate - lookup CA. */ #ifndef NO_SKID - ca = GetCA(cm, resp->single->issuerKeyHash); + ca = GetCAByKeyHash(cm, resp->single->issuerKeyHash); #else ca = GetCA(cm, resp->single->issuerHash); #endif diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 9e57ab0c4..b5f643574 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -6460,6 +6460,9 @@ WOLFSSL_LOCAL WC_RNG* WOLFSSL_RSA_GetRNG(WOLFSSL_RSA *rsa, WC_RNG **tmpRNG, WOLFSSL_LOCAL Signer* GetCAByAKID(void* vp, const byte* issuer, word32 issuerSz, const byte* serial, word32 serialSz); #endif + #ifdef HAVE_OCSP + WOLFSSL_LOCAL Signer* GetCAByKeyHash(void* vp, const byte* keyHash); + #endif #if !defined(NO_SKID) && !defined(GetCAByName) WOLFSSL_LOCAL Signer* GetCAByName(void* cm, byte* hash); #endif From 6114691fd6ff22e5b3635209cec284292fc95468 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Thu, 5 Sep 2024 09:49:01 +0000 Subject: [PATCH 2/2] ocsp: try lookup certificate using keyHash as KeyId try to lookup the certificate using the key hash as key identifier first. If we can't find a certificate, it means that the certificate uses another method to compute the key identifier so we need to fallback to linear search. --- src/ssl.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 2940215e8..37e5ce065 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -5113,6 +5113,13 @@ Signer* GetCAByKeyHash(void* vp, const byte* keyHash) if (cm == NULL || keyHash == NULL) return NULL; + /* try lookup using keyHash as subjKeyID first */ + ret = GetCA(vp, (byte*)keyHash); + if (ret != NULL && XMEMCMP(ret->subjectKeyHash, keyHash, KEYID_SIZE) == 0) { + return ret; + } + + /* if we can't find the cert, we have to scan the full table */ if (wc_LockMutex(&cm->caLock) != 0) return NULL; @@ -5120,8 +5127,7 @@ Signer* GetCAByKeyHash(void* vp, const byte* keyHash) for (row = 0; row < CA_TABLE_SIZE && ret == NULL; row++) { for (signers = cm->caTable[row]; signers != NULL; signers = signers->next) { - if (XMEMCMP(signers->subjectKeyHash, keyHash, KEYID_SIZE) - == 0) { + if (XMEMCMP(signers->subjectKeyHash, keyHash, KEYID_SIZE) == 0) { ret = signers; break; }