diff --git a/src/internal.c b/src/internal.c index d0859b5284..65c0c44e34 100644 --- a/src/internal.c +++ b/src/internal.c @@ -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 { diff --git a/src/ssl_certman.c b/src/ssl_certman.c index 09b8b7a5bc..c3579fc7a0 100644 --- a/src/ssl_certman.c +++ b/src/ssl_certman.c @@ -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); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 71bf8abb87..3c1a2eda0d 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -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. diff --git a/wolfssl/internal.h b/wolfssl/internal.h index b00ac2d512..eaeef302ff 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -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 diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 2b4479a773..f0594d229f 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -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 */