Merge pull request #3812 from haydenroche5/get-certs-refactor

Improve wolfSSL_CertManagerGetCerts.
This commit is contained in:
toddouska
2021-03-04 11:14:05 -08:00
committed by GitHub

134
src/ssl.c
View File

@ -3792,97 +3792,101 @@ int wolfSSL_CertManager_up_ref(WOLFSSL_CERT_MANAGER* cm)
WOLFSSL_STACK* wolfSSL_CertManagerGetCerts(WOLFSSL_CERT_MANAGER* cm)
{
WOLFSSL_STACK* sk = NULL;
int numCerts = 0;
DerBuffer** certBuffers = NULL;
const byte* derBuffer = NULL;
Signer* signers = NULL;
word32 row = 0;
DecodedCert* dCert = NULL;
WOLFSSL_X509* x509 = NULL;
int found = 0;
int i = 0;
int ret = 0;
if (cm == NULL)
return NULL;
sk = wolfSSL_sk_X509_new();
if (sk == NULL)
goto error;
if (sk == NULL) {
return NULL;
}
if (wc_LockMutex(&cm->caLock) != 0) {
goto error_init;
}
if (wc_LockMutex(&cm->caLock) != 0)
goto error;
/* Iterate once to get the number of certs, for memory allocation
purposes. */
for (row = 0; row < CA_TABLE_SIZE; row++) {
signers = cm->caTable[row];
while (signers && signers->derCert && signers->derCert->buffer) {
dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap,
DYNAMIC_TYPE_DCERT);
if (dCert == NULL) {
goto error;
}
XMEMSET(dCert, 0, sizeof(DecodedCert));
InitDecodedCert(dCert, signers->derCert->buffer,
signers->derCert->length, cm->heap);
/* Parse Certificate */
if (ParseCert(dCert, CERT_TYPE, NO_VERIFY, cm)) {
goto error;
}
x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), cm->heap,
DYNAMIC_TYPE_X509);
if (x509 == NULL) {
goto error;
}
InitX509(x509, 1, NULL);
if (CopyDecodedToX509(x509, dCert) == 0) {
if (wolfSSL_sk_X509_push(sk, x509) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Unable to load x509 into stack");
FreeX509(x509);
XFREE(x509, cm->heap, DYNAMIC_TYPE_X509);
goto error;
}
}
else {
goto error;
}
found = 1;
++numCerts;
signers = signers->next;
FreeDecodedCert(dCert);
XFREE(dCert, cm->heap, DYNAMIC_TYPE_DCERT);
dCert = NULL;
}
}
if (numCerts == 0) {
wc_UnLockMutex(&cm->caLock);
goto error;
}
certBuffers = (DerBuffer**)XMALLOC(sizeof(DerBuffer*) * numCerts, cm->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (certBuffers == NULL) {
wc_UnLockMutex(&cm->caLock);
goto error;
}
XMEMSET(certBuffers, 0, sizeof(DerBuffer*) * numCerts);
/* Copy the certs locally so that we can release the caLock. If the lock is
held when wolfSSL_d2i_X509 is called, GetCA will also try to get the
lock, leading to deadlock. */
for (row = 0; row < CA_TABLE_SIZE; row++) {
signers = cm->caTable[row];
while (signers && signers->derCert && signers->derCert->buffer) {
ret = AllocDer(&certBuffers[i], signers->derCert->length, CA_TYPE,
cm->heap);
if (ret < 0) {
wc_UnLockMutex(&cm->caLock);
goto error;
}
XMEMCPY(certBuffers[i]->buffer, signers->derCert->buffer,
signers->derCert->length);
certBuffers[i]->length = signers->derCert->length;
++i;
signers = signers->next;
}
}
wc_UnLockMutex(&cm->caLock);
if (!found) {
goto error_init;
for (i = 0; i < numCerts; ++i) {
derBuffer = certBuffers[i]->buffer;
wolfSSL_d2i_X509(&x509, &derBuffer, certBuffers[i]->length);
if (x509 == NULL)
goto error;
if (wolfSSL_sk_X509_push(sk, x509) != WOLFSSL_SUCCESS)
goto error;
}
for (i = 0; i < numCerts && certBuffers[i] != NULL; ++i) {
FreeDer(&certBuffers[i]);
}
XFREE(certBuffers, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
return sk;
error:
wc_UnLockMutex(&cm->caLock);
error_init:
if (dCert) {
FreeDecodedCert(dCert);
XFREE(dCert, cm->heap, DYNAMIC_TYPE_DCERT);
}
if (sk)
wolfSSL_sk_X509_free(sk);
for (i = 0; i < numCerts && certBuffers[i] != NULL; ++i) {
FreeDer(&certBuffers[i]);
}
if (certBuffers)
XFREE(certBuffers, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
return NULL;
}
#endif /* WOLFSSL_SIGNER_DER_CERT */