Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -5760,7 +5760,7 @@ Signer* GetCAByAKID(void* vp, const byte* issuer, word32 issuerSz,
for (row = 0; row < CA_TABLE_SIZE && ret == NULL; row++) {
for (signers = cm->caTable[row]; signers != NULL;
signers = signers->next) {
if (XMEMCMP(signers->subjectNameHash, nameHash, SIGNER_DIGEST_SIZE)
if (XMEMCMP(signers->issuerNameHash, nameHash, SIGNER_DIGEST_SIZE)
== 0 && XMEMCMP(signers->serialHash, serialHash,
SIGNER_DIGEST_SIZE) == 0) {
ret = signers;
Expand Down
93 changes: 93 additions & 0 deletions tests/api/test_x509.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
#include <wolfssl/openssl/x509.h>
#include <wolfssl/openssl/x509v3.h>

#include <wolfssl/internal.h>
#include <wolfssl/wolfcrypt/asn.h>

#if defined(OPENSSL_ALL) && \
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)
#define HAVE_TEST_X509_RFC2818_VERIFICATION_CALLBACK
Expand Down Expand Up @@ -148,3 +151,93 @@ int test_x509_rfc2818_verification_callback(void)
#endif
return EXPECT_RESULT();
}

/* Basic unit coverage for GetCAByAKID.
*
* These tests construct a minimal WOLFSSL_CERT_MANAGER and Signer objects in
* memory and then call GetCAByAKID directly, verifying that:
* - a NULL or incomplete input returns NULL,
* - a matching issuer/serial pair returns the expected Signer, and
* - a non-matching pair returns NULL.
*
* These tests are intended to check the behaviour of the lookup logic itself;
* they do not exercise certificate parsing or real CA loading.
*/
int test_x509_GetCAByAKID(void)
{
EXPECT_DECLS;
#ifdef WOLFSSL_AKID_NAME
WOLFSSL_CERT_MANAGER cm;
Signer signerA;
Signer signerB;
Signer* found;
byte issuerBuf[] = { 0x01, 0x02, 0x03, 0x04 };
byte serialBuf[] = { 0x0a, 0x0b, 0x0c, 0x0d };
byte wrongSerial[] = { 0x07, 0x07, 0x07, 0x07 };
byte issuerHash[SIGNER_DIGEST_SIZE];
byte serialHash[SIGNER_DIGEST_SIZE];
word32 row;

XMEMSET(&cm, 0, sizeof(cm));
XMEMSET(&signerA, 0, sizeof(signerA));
XMEMSET(&signerB, 0, sizeof(signerB));

/* Initialize CA mutex so GetCAByAKID can lock/unlock it. */
ExpectIntEQ(wc_InitMutex(&cm.caLock), 0);

/* Place both signers into the same CA table bucket. */
row = 0;
cm.caTable[row] = &signerA;
signerA.next = &signerB;
signerB.next = NULL;

/* Pre-compute the expected name and serial hashes using the same helper
* that GetCAByAKID uses internally. */
ExpectIntEQ(CalcHashId(issuerBuf, sizeof(issuerBuf), issuerHash), 0);
ExpectIntEQ(CalcHashId(serialBuf, sizeof(serialBuf), serialHash), 0);

/* Configure signerA as the matching signer. */
XMEMCPY(signerA.issuerNameHash, issuerHash, SIGNER_DIGEST_SIZE);
XMEMCPY(signerA.serialHash, serialHash, SIGNER_DIGEST_SIZE);

/* Configure signerB with different hashes so it should not match. */
XMEMSET(signerB.issuerNameHash, 0x11, SIGNER_DIGEST_SIZE);
XMEMSET(signerB.serialHash, 0x22, SIGNER_DIGEST_SIZE);

/* 1) NULL manager should yield NULL. */
found = GetCAByAKID(NULL, issuerBuf, (word32)sizeof(issuerBuf),
serialBuf, (word32)sizeof(serialBuf));
ExpectNull(found);

/* 2) NULL issuer should yield NULL. */
found = GetCAByAKID(&cm, NULL, (word32)sizeof(issuerBuf),
serialBuf, (word32)sizeof(serialBuf));
ExpectNull(found);

/* 3) NULL serial should yield NULL. */
found = GetCAByAKID(&cm, issuerBuf, (word32)sizeof(issuerBuf),
NULL, (word32)sizeof(serialBuf));
ExpectNull(found);

/* 4) Zero-length issuer/serial should yield NULL. */
found = GetCAByAKID(&cm, issuerBuf, 0, serialBuf, (word32)sizeof(serialBuf));
ExpectNull(found);
found = GetCAByAKID(&cm, issuerBuf, (word32)sizeof(issuerBuf),
serialBuf, 0);
ExpectNull(found);

/* 5) Non-matching serial should yield NULL. */
found = GetCAByAKID(&cm, issuerBuf, (word32)sizeof(issuerBuf),
wrongSerial, (word32)sizeof(wrongSerial));
ExpectNull(found);

/* 6) Matching issuer/serial should return signerA. */
found = GetCAByAKID(&cm, issuerBuf, (word32)sizeof(issuerBuf),
serialBuf, (word32)sizeof(serialBuf));
ExpectPtrEq(found, &signerA);

wc_FreeMutex(&cm.caLock);

#endif /* WOLFSSL_AKID_NAME */
return EXPECT_RESULT();
}
4 changes: 3 additions & 1 deletion tests/api/test_x509.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@
#define WOLFCRYPT_TEST_X509_H

int test_x509_rfc2818_verification_callback(void);
int test_x509_GetCAByAKID(void);

#define TEST_X509_DECLS \
TEST_DECL_GROUP("x509", test_x509_rfc2818_verification_callback)
TEST_DECL_GROUP("x509", test_x509_rfc2818_verification_callback), \
TEST_DECL_GROUP("x509", test_x509_GetCAByAKID)

#endif /* WOLFCRYPT_TEST_X509_H */
2 changes: 1 addition & 1 deletion wolfcrypt/src/asn.c
Original file line number Diff line number Diff line change
Expand Up @@ -26077,7 +26077,7 @@ int FillSigner(Signer* signer, DecodedCert* cert, int type, DerBuffer *der)
#endif
XMEMCPY(signer->subjectNameHash, cert->subjectHash,
SIGNER_DIGEST_SIZE);
#if defined(HAVE_OCSP) || defined(HAVE_CRL)
#if defined(HAVE_OCSP) || defined(HAVE_CRL) || defined(WOLFSSL_AKID_NAME)
XMEMCPY(signer->issuerNameHash, cert->issuerHash,
SIGNER_DIGEST_SIZE);
#endif
Expand Down
6 changes: 5 additions & 1 deletion wolfssl/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -6694,11 +6694,15 @@ WOLFSSL_LOCAL WC_RNG* WOLFSSL_RSA_GetRNG(WOLFSSL_RSA *rsa, WC_RNG **tmpRNG,
DecodedCert* cert);
#endif


#ifndef GetCA
WOLFSSL_LOCAL Signer* GetCA(void* vp, byte* hash);
#endif
#if defined(WOLFSSL_AKID_NAME) && !defined(GetCAByAKID)
WOLFSSL_LOCAL Signer* GetCAByAKID(void* vp, const byte* issuer,
#ifdef WOLFSSL_API_PREFIX_MAP
#define GetCAByAKID wolfSSL_GetCAByAKID
#endif
WOLFSSL_TEST_VIS Signer* GetCAByAKID(void* vp, const byte* issuer,
word32 issuerSz, const byte* serial, word32 serialSz);
#endif
#if defined(HAVE_OCSP) && !defined(GetCAByKeyHash)
Expand Down
33 changes: 17 additions & 16 deletions wolfssl/wolfcrypt/asn.h
Original file line number Diff line number Diff line change
Expand Up @@ -1957,7 +1957,7 @@ struct Signer {
#endif /* !IGNORE_NAME_CONSTRAINTS */
byte subjectNameHash[SIGNER_DIGEST_SIZE];
/* sha hash of names in certificate */
#if defined(HAVE_OCSP) || defined(HAVE_CRL)
#if defined(HAVE_OCSP) || defined(HAVE_CRL) || defined(WOLFSSL_AKID_NAME)
byte issuerNameHash[SIGNER_DIGEST_SIZE];
/* sha hash of issuer names in certificate.
* Used in OCSP to check for authorized
Expand Down Expand Up @@ -2059,21 +2059,6 @@ typedef enum MimeStatus
} MimeStatus;
#endif /* HAVE_SMIME */

WOLFSSL_LOCAL int HashIdAlg(word32 oidSum);
WOLFSSL_LOCAL int CalcHashId(const byte* data, word32 len, byte* hash);
WOLFSSL_LOCAL int CalcHashId_ex(const byte* data, word32 len, byte* hash,
int hashAlg);
WOLFSSL_LOCAL int GetHashId(const byte* id, int length, byte* hash,
int hashAlg);
WOLFSSL_LOCAL int GetName(DecodedCert* cert, int nameType, int maxIdx);

#ifdef ASN_BER_TO_DER
WOLFSSL_API int wc_BerToDer(const byte* ber, word32 berSz, byte* der,
word32* derSz);
#endif
WOLFSSL_LOCAL int StreamOctetString(const byte* inBuf, word32 inBufSz,
byte* out, word32* outSz, word32* idx);

#ifdef WOLFSSL_API_PREFIX_MAP
#define FreeAltNames wc_FreeAltNames
#define AltNameNew wc_AltNameNew
Expand All @@ -2098,8 +2083,24 @@ WOLFSSL_LOCAL int StreamOctetString(const byte* inBuf, word32 inBufSz,
#define GetASNTag wc_GetASNTag
#define SetAlgoID wc_SetAlgoID
#define SetAsymKeyDer wc_SetAsymKeyDer
#define CalcHashId wc_CalcHashId
#endif /* WOLFSSL_API_PREFIX_MAP */

WOLFSSL_LOCAL int HashIdAlg(word32 oidSum);
WOLFSSL_TEST_VIS int CalcHashId(const byte* data, word32 len, byte* hash);
WOLFSSL_LOCAL int CalcHashId_ex(const byte* data, word32 len, byte* hash,
int hashAlg);
WOLFSSL_LOCAL int GetHashId(const byte* id, int length, byte* hash,
int hashAlg);
WOLFSSL_LOCAL int GetName(DecodedCert* cert, int nameType, int maxIdx);

#ifdef ASN_BER_TO_DER
WOLFSSL_API int wc_BerToDer(const byte* ber, word32 berSz, byte* der,
word32* derSz);
#endif
WOLFSSL_LOCAL int StreamOctetString(const byte* inBuf, word32 inBufSz,
byte* out, word32* outSz, word32* idx);

WOLFSSL_ASN_API void FreeAltNames(DNS_entry* altNames, void* heap);
WOLFSSL_ASN_API DNS_entry* AltNameNew(void* heap);
WOLFSSL_ASN_API DNS_entry* AltNameDup(DNS_entry* from, void* heap);
Expand Down