Skip to content

Commit b5206e8

Browse files
committed
csrv2multi: pending ca list
1 parent 7814e4c commit b5206e8

7 files changed

Lines changed: 347 additions & 87 deletions

File tree

src/internal.c

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14022,6 +14022,7 @@ static int ProcessPeerCertParse(WOLFSSL* ssl, ProcPeerCertArgs* args,
1402214022
buffer* cert;
1402314023
byte* subjectHash = NULL;
1402414024
int alreadySigner = 0;
14025+
Signer *extraSigners = NULL;
1402514026
#if defined(HAVE_RPK)
1402614027
int cType;
1402714028
#endif
@@ -14123,9 +14124,13 @@ PRAGMA_GCC_DIAG_POP
1412314124
return ret;
1412414125
#endif
1412514126
}
14126-
14127+
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
14128+
if (verify != NO_VERIFY && TLSX_CSR2_IsMulti(ssl->extensions)) {
14129+
extraSigners = TLSX_CSR2_GetPendingSigners(ssl->extensions);
14130+
}
14131+
#endif
1412714132
/* Parse Certificate */
14128-
ret = ParseCertRelative(args->dCert, certType, verify, SSL_CM(ssl));
14133+
ret = ParseCertRelativeEx(args->dCert, certType, verify, SSL_CM(ssl), extraSigners);
1412914134

1413014135
#if defined(HAVE_RPK)
1413114136
/* if cert type has negotiated with peer, confirm the cert received has
@@ -14358,6 +14363,9 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1435814363
byte* subjectHash = NULL;
1435914364
int alreadySigner = 0;
1436014365

14366+
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
14367+
int addToPendingCAs = 0;
14368+
#endif
1436114369
WOLFSSL_ENTER("ProcessPeerCerts");
1436214370

1436314371
#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_NONBLOCK_OCSP)
@@ -14783,9 +14791,11 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1478314791
if (ret == 0) {
1478414792
#ifdef HAVE_OCSP
1478514793
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
14786-
if (ssl->status_request_v2) {
14794+
addToPendingCAs = 0;
14795+
if (ssl->status_request_v2 && TLSX_CSR2_IsMulti(ssl->extensions)) {
1478714796
ret = TLSX_CSR2_InitRequests(ssl->extensions,
1478814797
args->dCert, 0, ssl->heap);
14798+
addToPendingCAs = 1;
1478914799
}
1479014800
else /* skips OCSP and force CRL check */
1479114801
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
@@ -14930,6 +14940,45 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1493014940
skipAddCA = 1;
1493114941
}
1493214942
#endif
14943+
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
14944+
if (ret == 0 && addToPendingCAs && !alreadySigner) {
14945+
DecodedCert dCertAdd;
14946+
DerBuffer *derBuffer;
14947+
buffer* cert = &args->certs[args->certIdx];
14948+
Signer *s;
14949+
InitDecodedCert(&dCertAdd, cert->buffer, cert->length, ssl->heap);
14950+
ret = ParseCert(&dCertAdd, CA_TYPE, NO_VERIFY, SSL_CM(ssl));
14951+
if (ret != 0) {
14952+
FreeDecodedCert(&dCertAdd);
14953+
goto exit_ppc;
14954+
}
14955+
ret = AllocDer(&derBuffer, cert->length, CA_TYPE, ssl->heap);
14956+
if (ret != 0 || derBuffer == NULL) {
14957+
FreeDecodedCert(&dCertAdd);
14958+
goto exit_ppc;
14959+
}
14960+
XMEMCPY(derBuffer->buffer, cert->buffer, cert->length);
14961+
s = MakeSigner(SSL_CM(ssl)->heap);
14962+
if (s == NULL) {
14963+
FreeDecodedCert(&dCertAdd);
14964+
ret = MEMORY_E;
14965+
goto exit_ppc;
14966+
}
14967+
ret = FillSigner(s, &dCertAdd, CA_TYPE, derBuffer);
14968+
FreeDecodedCert(&dCertAdd);
14969+
FreeDer(&derBuffer);
14970+
if (ret != 0) {
14971+
FreeSigner(s, SSL_CM(ssl)->heap);
14972+
goto exit_ppc;
14973+
}
14974+
skipAddCA = 1;
14975+
ret = TLSX_CSR2_AddPendingSigner(ssl->extensions, s);
14976+
if (ret != 0) {
14977+
FreeSigner(s, ssl->heap);
14978+
goto exit_ppc;
14979+
}
14980+
}
14981+
#endif
1493314982

1493414983
/* If valid CA then add to Certificate Manager */
1493514984
if (ret == 0 && args->dCert->isCA &&
@@ -16082,6 +16131,7 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1608216131
OcspRequest* request;
1608316132
word32 list_length = status_length;
1608416133
byte idx = 0;
16134+
Signer *pendingCAs = NULL;
1608516135

1608616136
#ifdef WOLFSSL_SMALL_STACK
1608716137
CertStatus* status;
@@ -16098,6 +16148,8 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1609816148

1609916149
ssl->status_request_v2 = 0;
1610016150

16151+
pendingCAs = TLSX_CSR2_GetPendingSigners(ssl->extensions);
16152+
1610116153
#ifdef WOLFSSL_SMALL_STACK
1610216154
status = (CertStatus*)XMALLOC(sizeof(CertStatus), ssl->heap,
1610316155
DYNAMIC_TYPE_OCSP_STATUS);
@@ -16136,7 +16188,7 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1613616188
if (status_length) {
1613716189
InitOcspResponse(response, single, status, input +*inOutIdx,
1613816190
status_length, ssl->heap);
16139-
16191+
response->pendingCAs = pendingCAs;
1614016192
if ((OcspResponseDecode(response, SSL_CM(ssl), ssl->heap,
1614116193
0) != 0)
1614216194
|| (response->responseStatus != OCSP_SUCCESSFUL)
@@ -16180,6 +16232,17 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1618016232
ret = BUFFER_ERROR;
1618116233
}
1618216234

16235+
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
16236+
if (ret == 0) {
16237+
if (TLSX_CSR2_MergePendingCA(ssl) < 0) {
16238+
WOLFSSL_MSG("Failed to merge pending CAs");
16239+
}
16240+
}
16241+
else {
16242+
TLSX_CSR2_ClearPendingCA(ssl);
16243+
}
16244+
#endif
16245+
1618316246
if (ret != 0) {
1618416247
WOLFSSL_ERROR_VERBOSE(ret);
1618516248
SendAlert(ssl, alert_fatal, bad_certificate_status_response);

src/ocsp.c

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,12 @@ int CheckOcspResponse(WOLFSSL_OCSP *ocsp, byte *response, int responseSz,
328328
#endif
329329
InitOcspResponse(ocspResponse, newSingle, newStatus, response,
330330
(word32)responseSz, ocsp->cm->heap);
331-
331+
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
332+
if (ocspRequest != NULL && ocspRequest->ssl != NULL &&
333+
TLSX_CSR2_IsMulti(((WOLFSSL*)ocspRequest->ssl)->extensions)) {
334+
ocspResponse->pendingCAs = TLSX_CSR2_GetPendingSigners(((WOLFSSL*)ocspRequest->ssl)->extensions);
335+
}
336+
#endif
332337
ret = OcspResponseDecode(ocspResponse, ocsp->cm, ocsp->cm->heap, 0);
333338
if (ret != 0) {
334339
ocsp->error = ret;
@@ -555,7 +560,7 @@ int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest,
555560

556561
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHAIN_CHECK
557562
static int CheckOcspResponderChain(OcspEntry* single, DecodedCert *cert,
558-
void* vp) {
563+
void* vp, Signer* pendingCAs) {
559564
/* Attempt to build a chain up to cert's issuer */
560565
WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
561566
Signer* ca = NULL;
@@ -574,8 +579,16 @@ static int CheckOcspResponderChain(OcspEntry* single, DecodedCert *cert,
574579

575580
/* End loop if no more issuers found or if we have found a self
576581
* signed cert (ca == prev) */
577-
for (ca = GetCAByName(cm, single->issuerHash); ca != NULL && ca != prev;
578-
prev = ca, ca = GetCAByName(cm, ca->issuerNameHash)) {
582+
ca = GetCAByName(cm, single->issuerHash);
583+
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
584+
if (ca == NULL && pendingCAs != NULL) {
585+
ca = findSignerByName(pendingCAs, single->issuerHash);
586+
}
587+
#else
588+
(void)pendingCAs;
589+
#endif
590+
for (; ca != NULL && ca != prev;
591+
prev = ca) {
579592
if (XMEMCMP(cert->issuerHash, ca->issuerNameHash,
580593
OCSP_DIGEST_SIZE) == 0) {
581594
WOLFSSL_MSG("\tOCSP Response signed by authorized "
@@ -584,6 +597,12 @@ static int CheckOcspResponderChain(OcspEntry* single, DecodedCert *cert,
584597
passed = 1;
585598
break;
586599
}
600+
ca = GetCAByName(cm, ca->issuerNameHash);
601+
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
602+
if (ca == NULL && pendingCAs != NULL) {
603+
ca = findSignerByName(pendingCAs, single->issuerHash);
604+
}
605+
#endif
587606
}
588607
return passed;
589608
}
@@ -632,7 +651,7 @@ int CheckOcspResponder(OcspResponse *bs, DecodedCert *cert, void* vp)
632651
}
633652
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHAIN_CHECK
634653
else if (vp != NULL) {
635-
passed = CheckOcspResponderChain(single, cert, vp);
654+
passed = CheckOcspResponderChain(single, cert, vp, bs->pendingCAs);
636655
}
637656
#endif
638657
}

src/ssl.c

Lines changed: 35 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -5283,6 +5283,38 @@ int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int verify)
52835283
}
52845284
#endif /* WOLFSSL_TRUST_PEER_CERT */
52855285

5286+
int AddSigner(WOLFSSL_CERT_MANAGER* cm, Signer *s)
5287+
{
5288+
byte* subjectHash;
5289+
Signer* signers;
5290+
word32 row;
5291+
5292+
if (cm == NULL || s == NULL)
5293+
return BAD_FUNC_ARG;
5294+
5295+
#ifndef NO_SKID
5296+
subjectHash = s->subjectKeyIdHash;
5297+
#else
5298+
subjectHash = s->subjectNameHash;
5299+
#endif
5300+
5301+
if (AlreadySigner(cm, subjectHash)) {
5302+
FreeSigner(s, cm->heap);
5303+
return 0;
5304+
}
5305+
5306+
row = HashSigner(subjectHash);
5307+
5308+
if (wc_LockMutex(&cm->caLock) != 0)
5309+
return BAD_MUTEX_E;
5310+
5311+
signers = cm->caTable[row];
5312+
s->next = signers;
5313+
cm->caTable[row] = s;
5314+
5315+
wc_UnLockMutex(&cm->caLock);
5316+
return 0;
5317+
}
52865318

52875319
/* owns der, internal now uses too */
52885320
/* type flag ids from user or from chain received during verify
@@ -5437,84 +5469,17 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
54375469
if (!signer)
54385470
ret = MEMORY_ERROR;
54395471
}
5440-
5441-
#ifdef WOLFSSL_DUAL_ALG_CERTS
5442-
if (ret == 0 && signer != NULL) {
5443-
if (cert->extSapkiSet && cert->sapkiLen > 0) {
5444-
/* Allocated space for alternative public key. */
5445-
signer->sapkiDer = (byte*)XMALLOC(cert->sapkiLen, cm->heap,
5446-
DYNAMIC_TYPE_PUBLIC_KEY);
5447-
if (signer->sapkiDer == NULL) {
5448-
ret = MEMORY_E;
5449-
}
5450-
else {
5451-
XMEMCPY(signer->sapkiDer, cert->sapkiDer, cert->sapkiLen);
5452-
signer->sapkiLen = cert->sapkiLen;
5453-
signer->sapkiOID = cert->sapkiOID;
5454-
}
5455-
}
5456-
}
5457-
#endif /* WOLFSSL_DUAL_ALG_CERTS */
5458-
5459-
#if defined(WOLFSSL_AKID_NAME) || defined(HAVE_CRL)
5460-
if (ret == 0 && signer != NULL)
5461-
ret = CalcHashId(cert->serial, cert->serialSz, signer->serialHash);
5462-
#endif
5463-
if (ret == 0 && signer != NULL) {
5464-
#ifdef WOLFSSL_SIGNER_DER_CERT
5465-
ret = AllocDer(&signer->derCert, der->length, der->type, NULL);
5466-
}
54675472
if (ret == 0 && signer != NULL) {
5468-
XMEMCPY(signer->derCert->buffer, der->buffer, der->length);
5469-
#endif
5470-
signer->keyOID = cert->keyOID;
5471-
if (cert->pubKeyStored) {
5472-
signer->publicKey = cert->publicKey;
5473-
signer->pubKeySize = cert->pubKeySize;
5474-
}
5475-
5476-
if (cert->subjectCNStored) {
5477-
signer->nameLen = cert->subjectCNLen;
5478-
signer->name = cert->subjectCN;
5479-
}
5480-
signer->maxPathLen = cert->maxPathLen;
5481-
signer->selfSigned = cert->selfSigned;
5482-
#ifndef IGNORE_NAME_CONSTRAINTS
5483-
signer->permittedNames = cert->permittedNames;
5484-
signer->excludedNames = cert->excludedNames;
5485-
#endif
5486-
#ifndef NO_SKID
5487-
XMEMCPY(signer->subjectKeyIdHash, cert->extSubjKeyId,
5488-
SIGNER_DIGEST_SIZE);
5489-
#endif
5490-
XMEMCPY(signer->subjectNameHash, cert->subjectHash,
5491-
SIGNER_DIGEST_SIZE);
5492-
#if defined(HAVE_OCSP) || defined(HAVE_CRL)
5493-
XMEMCPY(signer->issuerNameHash, cert->issuerHash,
5494-
SIGNER_DIGEST_SIZE);
5495-
#endif
5496-
#ifdef HAVE_OCSP
5497-
XMEMCPY(signer->subjectKeyHash, cert->subjectKeyHash,
5498-
KEYID_SIZE);
5499-
#endif
5500-
signer->keyUsage = cert->extKeyUsageSet ? cert->extKeyUsage
5501-
: 0xFFFF;
5502-
signer->next = NULL; /* If Key Usage not set, all uses valid. */
5503-
cert->publicKey = 0; /* in case lock fails don't free here. */
5504-
cert->subjectCN = 0;
5505-
#ifndef IGNORE_NAME_CONSTRAINTS
5506-
cert->permittedNames = NULL;
5507-
cert->excludedNames = NULL;
5508-
#endif
5509-
signer->type = (byte)type;
5473+
ret = FillSigner(signer, cert, type, der);
55105474

55115475
#ifndef NO_SKID
55125476
row = HashSigner(signer->subjectKeyIdHash);
55135477
#else
55145478
row = HashSigner(signer->subjectNameHash);
55155479
#endif
55165480

5517-
if (wc_LockMutex(&cm->caLock) == 0) {
5481+
5482+
if (ret == 0 && wc_LockMutex(&cm->caLock) == 0) {
55185483
signer->next = cm->caTable[row];
55195484
cm->caTable[row] = signer; /* takes ownership */
55205485
wc_UnLockMutex(&cm->caLock);

0 commit comments

Comments
 (0)