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:
@@ -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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user