1
0
mirror of https://github.com/wolfSSL/wolfssl.git synced 2026-10-24 04:09:07 +03:00

Merge commit from fork

Fix trusted peer cert matching to verify full certificate, not just n…
This commit is contained in:
JacobBarthelmeh
2026-09-24 10:57:41 -06:00
committed by GitHub
5 changed files with 44 additions and 149 deletions

View File

@@ -18516,17 +18516,14 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
tp = GetTrustedPeer(SSL_CM(ssl), args->dCert);
WOLFSSL_MSG("Checking for trusted peer cert");
if (tp && MatchTrustedPeer(tp, args->dCert)) {
if (tp) {
WOLFSSL_MSG("Found matching trusted peer cert");
args->haveTrustPeer = 1;
}
else if (tp == NULL) {
else {
/* no trusted peer cert */
WOLFSSL_MSG("No matching trusted peer cert. Checking CAs");
}
else {
WOLFSSL_MSG("Trusted peer cert did not match!");
}
if (!args->haveTrustPeer)
#endif
{

View File

@@ -2728,39 +2728,31 @@ int AlreadySigner(WOLFSSL_CERT_MANAGER* cm, byte* hash)
}
#ifdef WOLFSSL_TRUST_PEER_CERT
/* hash is the SHA digest of name, just use first 32 bits as hash */
/* use the first 32 bits of the digest as the table row */
static WC_INLINE word32 TrustedPeerHashSigner(const byte* hash)
{
return MakeWordFromHash(hash) % TP_TABLE_SIZE;
}
/* does trusted peer already exist on signer list */
/* does trusted peer already exist in the table */
int AlreadyTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DecodedCert* cert)
{
TrustedPeerCert* tp;
int ret = 0;
word32 row = TrustedPeerHashSigner(cert->subjectHash);
byte certHash[KEYID_SIZE];
word32 row;
if (cert->source == NULL || cert->maxIdx == 0 ||
CalcHashId(cert->source, cert->maxIdx, certHash) != 0)
return ret;
row = TrustedPeerHashSigner(certHash);
if (wc_LockMutex(&cm->tpLock) != 0)
return ret;
tp = cm->tpTable[row];
while (tp) {
if ((XMEMCMP(cert->subjectHash, tp->subjectNameHash,
SIGNER_DIGEST_SIZE) == 0)
#ifndef WOLFSSL_NO_ISSUERHASH_TDPEER
&& (XMEMCMP(cert->issuerHash, tp->issuerHash,
SIGNER_DIGEST_SIZE) == 0)
#endif
)
if (XMEMCMP(tp->certHash, certHash, KEYID_SIZE) == 0)
ret = 1;
#ifndef NO_SKID
if (cert->extSubjKeyIdSet) {
/* Compare SKID as well if available */
if (ret == 1 && XMEMCMP(cert->extSubjKeyId, tp->subjectKeyIdHash,
SIGNER_DIGEST_SIZE) != 0)
ret = 0;
}
#endif
if (ret == 1)
break;
tp = tp->next;
@@ -2778,34 +2770,27 @@ TrustedPeerCert* GetTrustedPeer(void* vp, DecodedCert* cert)
WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
TrustedPeerCert* ret = NULL;
TrustedPeerCert* tp = NULL;
byte certHash[KEYID_SIZE];
word32 row;
if (cm == NULL || cert == NULL)
return NULL;
row = TrustedPeerHashSigner(cert->subjectHash);
/* whole-certificate identity test: index the table by the hash of the
* presented certificate's exact bytes and compare the full digest */
if (cert->source == NULL || cert->maxIdx == 0 ||
CalcHashId(cert->source, cert->maxIdx, certHash) != 0)
return NULL;
row = TrustedPeerHashSigner(certHash);
if (wc_LockMutex(&cm->tpLock) != 0)
return ret;
tp = cm->tpTable[row];
while (tp) {
if ((XMEMCMP(cert->subjectHash, tp->subjectNameHash,
SIGNER_DIGEST_SIZE) == 0)
#ifndef WOLFSSL_NO_ISSUERHASH_TDPEER
&& (XMEMCMP(cert->issuerHash, tp->issuerHash,
SIGNER_DIGEST_SIZE) == 0)
#endif
)
if (XMEMCMP(tp->certHash, certHash, KEYID_SIZE) == 0)
ret = tp;
#ifndef NO_SKID
if (cert->extSubjKeyIdSet) {
/* Compare SKID as well if available */
if (ret != NULL && XMEMCMP(cert->extSubjKeyId, tp->subjectKeyIdHash,
SIGNER_DIGEST_SIZE) != 0)
ret = NULL;
}
#endif
if (ret != NULL)
break;
tp = tp->next;
@@ -2814,28 +2799,6 @@ TrustedPeerCert* GetTrustedPeer(void* vp, DecodedCert* cert)
return ret;
}
int MatchTrustedPeer(TrustedPeerCert* tp, DecodedCert* cert)
{
if (tp == NULL || cert == NULL)
return BAD_FUNC_ARG;
/* subject key id or subject hash has been compared when searching
tpTable for the cert from function GetTrustedPeer */
/* compare signatures */
if (tp->sigLen == cert->sigLength) {
if (XMEMCMP(tp->sig, cert->signature, cert->sigLength)) {
return WOLFSSL_FAILURE;
}
}
else {
return WOLFSSL_FAILURE;
}
return WOLFSSL_SUCCESS;
}
#endif /* WOLFSSL_TRUST_PEER_CERT */
/* return CA if found, otherwise NULL */
@@ -3019,68 +2982,39 @@ int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int verify)
}
XMEMSET(peerCert, 0, sizeof(TrustedPeerCert));
/* hash of the whole certificate DER: table index and identity test */
ret = CalcHashId(der->buffer, der->length, peerCert->certHash);
if (ret != 0) {
FreeDecodedCert(cert);
XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
FreeTrustedPeer(peerCert, cm->heap);
FreeDer(&der);
return ret;
}
if (AlreadyTrustedPeer(cm, cert)) {
WOLFSSL_MSG("\tAlready have this CA, not adding again");
FreeTrustedPeer(peerCert, cm->heap);
(void)ret;
}
else {
/* add trusted peer signature */
peerCert->sigLen = cert->sigLength;
peerCert->sig = (byte *)XMALLOC(cert->sigLength, cm->heap,
DYNAMIC_TYPE_SIGNATURE);
if (peerCert->sig == NULL) {
peerCert->next = NULL;
row = (int)TrustedPeerHashSigner(peerCert->certHash);
if (wc_LockMutex(&cm->tpLock) == 0) {
peerCert->next = cm->tpTable[row];
cm->tpTable[row] = peerCert; /* takes ownership */
wc_UnLockMutex(&cm->tpLock);
}
else {
WOLFSSL_MSG("\tTrusted Peer Cert Mutex Lock failed");
FreeDecodedCert(cert);
XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
FreeTrustedPeer(peerCert, cm->heap);
FreeDer(&der);
return MEMORY_E;
}
XMEMCPY(peerCert->sig, cert->signature, cert->sigLength);
/* add trusted peer name */
peerCert->nameLen = cert->subjectCNLen;
peerCert->name = cert->subjectCN;
#ifndef IGNORE_NAME_CONSTRAINTS
peerCert->permittedNames = cert->permittedNames;
peerCert->excludedNames = cert->excludedNames;
#endif
/* add SKID when available and hash of name */
#ifndef NO_SKID
XMEMCPY(peerCert->subjectKeyIdHash, cert->extSubjKeyId,
SIGNER_DIGEST_SIZE);
#endif
XMEMCPY(peerCert->subjectNameHash, cert->subjectHash,
SIGNER_DIGEST_SIZE);
#ifndef WOLFSSL_NO_ISSUERHASH_TDPEER
XMEMCPY(peerCert->issuerHash, cert->issuerHash,
SIGNER_DIGEST_SIZE);
#endif
/* If Key Usage not set, all uses valid. */
peerCert->next = NULL;
cert->subjectCN = 0;
#ifndef IGNORE_NAME_CONSTRAINTS
cert->permittedNames = NULL;
cert->excludedNames = NULL;
#endif
row = (int)TrustedPeerHashSigner(peerCert->subjectNameHash);
if (wc_LockMutex(&cm->tpLock) == 0) {
peerCert->next = cm->tpTable[row];
cm->tpTable[row] = peerCert; /* takes ownership */
wc_UnLockMutex(&cm->tpLock);
}
else {
WOLFSSL_MSG("\tTrusted Peer Cert Mutex Lock failed");
FreeDecodedCert(cert);
XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
FreeTrustedPeer(peerCert, cm->heap);
FreeDer(&der);
return BAD_MUTEX_E;
}
return BAD_MUTEX_E;
}
}
WOLFSSL_MSG("\tFreeing parsed trusted peer cert");
FreeDecodedCert(cert);

View File

@@ -26157,23 +26157,7 @@ void FreeTrustedPeer(TrustedPeerCert* tp, void* heap)
if (tp == NULL) {
return;
}
/* safe cast -- when .name is set in AddTrustedPeer() from cert->subjectCN,
* it inherits the allocation from ParseCert(), and cert->subjectCN is set
* to NULL.
*/
XFREE((void *)(wc_ptr_t)tp->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
XFREE(tp->sig, heap, DYNAMIC_TYPE_SIGNATURE);
#ifndef IGNORE_NAME_CONSTRAINTS
if (tp->permittedNames)
FreeNameSubtrees(tp->permittedNames, heap);
if (tp->excludedNames)
FreeNameSubtrees(tp->excludedNames, heap);
#endif
XFREE(tp, heap, DYNAMIC_TYPE_CERT);
(void)heap;
}
/* Free the whole Trusted Peer linked list.

View File

@@ -7598,8 +7598,6 @@ WOLFSSL_LOCAL WC_RNG* WOLFSSL_RSA_GetRNG(WOLFSSL_RSA *rsa, WC_RNG **tmpRNG,
#define WC_MATCH_NAME 1
WOLFSSL_LOCAL TrustedPeerCert* GetTrustedPeer(void* vp, DecodedCert* cert);
WOLFSSL_LOCAL int MatchTrustedPeer(TrustedPeerCert* tp,
DecodedCert* cert);
#endif

View File

@@ -2385,25 +2385,7 @@ struct Signer {
#ifdef WOLFSSL_TRUST_PEER_CERT
/* used for having trusted peer certs rather then CA */
struct TrustedPeerCert {
int nameLen;
const char*
name; /* common name */
#ifndef IGNORE_NAME_CONSTRAINTS
Base_entry* permittedNames;
Base_entry* excludedNames;
#endif /* IGNORE_NAME_CONSTRAINTS */
byte subjectNameHash[SIGNER_DIGEST_SIZE];
/* sha hash of names in certificate */
#ifndef WOLFSSL_NO_ISSUERHASH_TDPEER
byte issuerHash[SIGNER_DIGEST_SIZE];
/* sha hash of issuer name in certificate */
#endif
#ifndef NO_SKID
byte subjectKeyIdHash[SIGNER_DIGEST_SIZE];
/* sha hash of SKID in certificate */
#endif
word32 sigLen;
byte* sig;
byte certHash[KEYID_SIZE]; /* hash of the whole certificate DER */
struct TrustedPeerCert* next;
};
#endif /* WOLFSSL_TRUST_PEER_CERT */