Skip to content

Commit 4f8a39c

Browse files
authored
Merge pull request wolfSSL#8498 from rizlik/ocsp_fixes
OCSP openssl compat fixes
2 parents d63a180 + 194db7e commit 4f8a39c

File tree

7 files changed

+406
-138
lines changed

7 files changed

+406
-138
lines changed

src/ocsp.c

Lines changed: 165 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -727,13 +727,23 @@ WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_cert_to_id(
727727
WOLFSSL_CERT_MANAGER* cm = NULL;
728728
int ret = -1;
729729
DerBuffer* derCert = NULL;
730+
int dgstType;
730731
#ifdef WOLFSSL_SMALL_STACK
731732
DecodedCert *cert = NULL;
732733
#else
733734
DecodedCert cert[1];
734735
#endif
735736

736-
(void)dgst;
737+
if (dgst == NULL) {
738+
dgstType = WC_HASH_TYPE_SHA;
739+
}
740+
else if (wolfSSL_EVP_get_hashinfo(dgst, &dgstType, NULL) !=
741+
WOLFSSL_SUCCESS) {
742+
return NULL;
743+
}
744+
745+
if (dgstType != OCSP_DIGEST)
746+
return NULL;
737747

738748
cm = wolfSSL_CertManagerNew();
739749
if (cm == NULL
@@ -785,6 +795,7 @@ WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_cert_to_id(
785795
goto out;
786796
}
787797
else {
798+
certId->hashAlgoOID = wc_HashGetOID(OCSP_DIGEST);
788799
XMEMCPY(certId->issuerHash, cert->issuerHash, OCSP_DIGEST_SIZE);
789800
XMEMCPY(certId->issuerKeyHash, cert->issuerKeyHash, OCSP_DIGEST_SIZE);
790801
XMEMCPY(certId->status->serial, cert->serial, (size_t)cert->serialSz);
@@ -822,6 +833,78 @@ void wolfSSL_OCSP_BASICRESP_free(WOLFSSL_OCSP_BASICRESP* basicResponse)
822833
wolfSSL_OCSP_RESPONSE_free(basicResponse);
823834
}
824835

836+
/* Calculate ancode CertID DER encoding following RFC 6960:
837+
CertID ::= SEQUENCE {
838+
hashAlgorithm AlgorithmIdentifier,
839+
issuerNameHash OCTET STRING,
840+
issuerKeyHash OCTET STRING,
841+
serialNumber CertificateSerialNumber }
842+
*/
843+
static int OcspEncodeCertID(WOLFSSL_OCSP_CERTID* id, byte* output,
844+
word32* totalSz, word32* intSize)
845+
{
846+
word32 idx = 0;
847+
int ret;
848+
849+
if (id == NULL || totalSz == NULL || intSize == NULL ||
850+
(output != NULL && (*totalSz == 0 || *totalSz <= *intSize)))
851+
return BAD_FUNC_ARG;
852+
853+
if (output != NULL) {
854+
ret = SetSequence(*intSize, output);
855+
if (ret < 0)
856+
return ret;
857+
idx += ret;
858+
}
859+
860+
ret = SetAlgoID(id->hashAlgoOID, ((output != NULL) ? output + idx : output),
861+
oidHashType, 0);
862+
if (ret <= 0)
863+
return -1;
864+
idx += ret;
865+
866+
/* issuerNameHash */
867+
ret = SetOctetString(OCSP_DIGEST_SIZE, ((output != NULL) ? output + idx : output));
868+
if (ret < 0)
869+
return ret;
870+
idx += ret;
871+
if (output != NULL)
872+
XMEMCPY(output + idx, id->issuerHash, OCSP_DIGEST_SIZE);
873+
idx += OCSP_DIGEST_SIZE;
874+
875+
/* issuerKeyHash */
876+
ret = SetOctetString(OCSP_DIGEST_SIZE, ((output != NULL) ? output + idx : output));
877+
if (ret < 0)
878+
return ret;
879+
idx += ret;
880+
if (output != NULL)
881+
XMEMCPY(output + idx, id->issuerKeyHash, OCSP_DIGEST_SIZE);
882+
idx += OCSP_DIGEST_SIZE;
883+
884+
/* serialNumber */
885+
ret = SetASNInt(id->status->serialSz, id->status->serial[0], ((output != NULL) ? output + idx : output));
886+
if (ret < 0)
887+
return ret;
888+
idx += ret;
889+
if (output != NULL)
890+
XMEMCPY(output + idx, id->status->serial, id->status->serialSz);
891+
idx += id->status->serialSz;
892+
893+
if (output == NULL) {
894+
*intSize = idx;
895+
ret = SetSequence(idx, NULL);
896+
if (ret < 0)
897+
return ret;
898+
idx += ret;
899+
*totalSz = idx;
900+
}
901+
else if (idx != *totalSz) {
902+
return BUFFER_E;
903+
}
904+
905+
return 0;
906+
}
907+
825908
static int OcspRespIdMatches(OcspResponse* resp, const byte* NameHash,
826909
const byte* keyHash)
827910
{
@@ -1284,67 +1367,110 @@ int wolfSSL_i2d_OCSP_REQUEST_bio(WOLFSSL_BIO* out,
12841367

12851368
int wolfSSL_i2d_OCSP_CERTID(WOLFSSL_OCSP_CERTID* id, unsigned char** data)
12861369
{
1287-
if (id == NULL || data == NULL)
1288-
return WOLFSSL_FAILURE;
1370+
int allocated = 0;
1371+
word32 derSz = 0;
1372+
word32 intSz = 0;
1373+
int ret;
1374+
WOLFSSL_ENTER("wolfSSL_i2d_OCSP_CERTID");
1375+
1376+
if (id == NULL)
1377+
return -1;
12891378

1290-
if (*data != NULL) {
1291-
XMEMCPY(*data, id->rawCertId, (size_t)id->rawCertIdSize);
1292-
*data = *data + id->rawCertIdSize;
1379+
if (id->rawCertId != NULL) {
1380+
derSz = id->rawCertIdSize;
12931381
}
12941382
else {
1295-
*data = (unsigned char*)XMALLOC((size_t)id->rawCertIdSize, NULL, DYNAMIC_TYPE_OPENSSL);
1383+
ret = OcspEncodeCertID(id, NULL, &derSz, &intSz);
1384+
if (ret != 0) {
1385+
WOLFSSL_MSG("Failed to calculate CertID size");
1386+
return -1;
1387+
}
1388+
}
1389+
1390+
if (data == NULL) {
1391+
return derSz;
1392+
}
1393+
1394+
if (*data == NULL) {
1395+
/* Allocate buffer for DER encoding */
1396+
*data = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL);
12961397
if (*data == NULL) {
1297-
return WOLFSSL_FAILURE;
1398+
WOLFSSL_MSG("Failed to allocate memory for CertID DER encoding");
1399+
return -1;
1400+
}
1401+
allocated = 1;
1402+
}
1403+
1404+
if (id->rawCertId != NULL) {
1405+
XMEMCPY(*data, id->rawCertId, id->rawCertIdSize);
1406+
}
1407+
else {
1408+
ret = OcspEncodeCertID(id, *data, &derSz, &intSz);
1409+
if (ret < 0) {
1410+
WOLFSSL_MSG("Failed to encode CertID");
1411+
if (allocated) {
1412+
XFREE(*data, NULL, DYNAMIC_TYPE_OPENSSL);
1413+
*data = NULL;
1414+
}
1415+
return -1;
12981416
}
1299-
XMEMCPY(*data, id->rawCertId, (size_t)id->rawCertIdSize);
13001417
}
13011418

1302-
return id->rawCertIdSize;
1419+
if (!allocated)
1420+
*data += derSz;
1421+
1422+
return derSz;
13031423
}
13041424

13051425
WOLFSSL_OCSP_CERTID* wolfSSL_d2i_OCSP_CERTID(WOLFSSL_OCSP_CERTID** cidOut,
13061426
const unsigned char** derIn,
13071427
int length)
13081428
{
13091429
WOLFSSL_OCSP_CERTID *cid = NULL;
1430+
int isAllocated = 0;
1431+
word32 idx = 0;
1432+
int ret;
13101433

1311-
if ((cidOut != NULL) && (derIn != NULL) && (*derIn != NULL) &&
1312-
(length > 0)) {
1434+
if (derIn == NULL || *derIn == NULL || length <= 0)
1435+
return NULL;
13131436

1437+
if (cidOut != NULL && *cidOut != NULL) {
13141438
cid = *cidOut;
1439+
FreeOcspEntry(cid, NULL);
1440+
}
1441+
else {
1442+
cid = (WOLFSSL_OCSP_CERTID*)XMALLOC(sizeof(WOLFSSL_OCSP_CERTID), NULL,
1443+
DYNAMIC_TYPE_OPENSSL);
1444+
if (cid == NULL)
1445+
return NULL;
1446+
isAllocated = 1;
1447+
}
13151448

1316-
/* If a NULL is passed we allocate the memory for the caller. */
1317-
if (cid == NULL) {
1318-
cid = (WOLFSSL_OCSP_CERTID*)XMALLOC(sizeof(*cid), NULL,
1319-
DYNAMIC_TYPE_OPENSSL);
1320-
}
1321-
else if (cid->rawCertId != NULL) {
1322-
XFREE(cid->rawCertId, NULL, DYNAMIC_TYPE_OPENSSL);
1323-
cid->rawCertId = NULL;
1324-
cid->rawCertIdSize = 0;
1325-
}
1326-
1327-
if (cid != NULL) {
1328-
cid->rawCertId = (byte*)XMALLOC((size_t)length + 1, NULL, DYNAMIC_TYPE_OPENSSL);
1329-
if (cid->rawCertId != NULL) {
1330-
XMEMCPY(cid->rawCertId, *derIn, (size_t)length);
1331-
cid->rawCertIdSize = length;
1332-
1333-
/* Per spec. advance past the data that is being returned
1334-
* to the caller. */
1335-
*cidOut = cid;
1336-
*derIn = *derIn + length;
1449+
XMEMSET(cid, 0, sizeof(WOLFSSL_OCSP_CERTID));
1450+
cid->status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
1451+
DYNAMIC_TYPE_OCSP_STATUS);
1452+
if (cid->status == NULL) {
1453+
XFREE(cid, NULL, DYNAMIC_TYPE_OPENSSL);
1454+
return NULL;
1455+
}
1456+
XMEMSET(cid->status, 0, sizeof(CertStatus));
1457+
cid->ownStatus = 1;
13371458

1338-
return cid;
1339-
}
1459+
ret = OcspDecodeCertID(*derIn, &idx, length, cid);
1460+
if (ret != 0) {
1461+
FreeOcspEntry(cid, NULL);
1462+
if (isAllocated) {
1463+
XFREE(cid, NULL, DYNAMIC_TYPE_OPENSSL);
13401464
}
1465+
return NULL;
13411466
}
13421467

1343-
if ((cid != NULL) && ((cidOut == NULL) || (cid != *cidOut))) {
1344-
XFREE(cid, NULL, DYNAMIC_TYPE_OPENSSL);
1345-
}
1468+
*derIn += idx;
13461469

1347-
return NULL;
1470+
if (isAllocated && cidOut != NULL)
1471+
*cidOut = cid;
1472+
1473+
return cid;
13481474
}
13491475

13501476
const WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_SINGLERESP_get0_id(

tests/api.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66217,7 +66217,8 @@ static int test_wolfSSL_OCSP_id_get0_info(void)
6621766217
{
6621866218
EXPECT_DECLS;
6621966219
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY)) && \
66220-
defined(HAVE_OCSP) && !defined(NO_FILESYSTEM) && !defined(NO_RSA)
66220+
defined(HAVE_OCSP) && !defined(NO_FILESYSTEM) && !defined(NO_RSA) && \
66221+
!defined(WOLFSSL_SM2) && !defined(WOLFSSL_SM3)
6622166222
X509* cert = NULL;
6622266223
X509* issuer = NULL;
6622366224
OCSP_CERTID* id = NULL;
@@ -66349,10 +66350,9 @@ static int test_wolfSSL_d2i_OCSP_CERTID(void)
6634966350
WOLFSSL_OCSP_CERTID* certId = NULL;
6635066351
ExpectNotNull(certId = wolfSSL_d2i_OCSP_CERTID(&certId, &rawCertIdPtr,
6635166352
sizeof(rawCertId)));
66352-
ExpectIntEQ(certId->rawCertIdSize, sizeof(rawCertId));
6635366353
if (certId != NULL) {
6635466354
XFREE(certId->rawCertId, NULL, DYNAMIC_TYPE_OPENSSL);
66355-
XFREE(certId, NULL, DYNAMIC_TYPE_OPENSSL);
66355+
wolfSSL_OCSP_CERTID_free(certId);
6635666356
}
6635766357
}
6635866358

@@ -66370,10 +66370,9 @@ static int test_wolfSSL_d2i_OCSP_CERTID(void)
6637066370
ExpectNotNull(certIdGood = wolfSSL_d2i_OCSP_CERTID(&certId, &rawCertIdPtr,
6637166371
sizeof(rawCertId)));
6637266372
ExpectPtrEq(certIdGood, certId);
66373-
ExpectIntEQ(certId->rawCertIdSize, sizeof(rawCertId));
6637466373
if (certId != NULL) {
6637566374
XFREE(certId->rawCertId, NULL, DYNAMIC_TYPE_OPENSSL);
66376-
XFREE(certId, NULL, DYNAMIC_TYPE_TMP_BUFFER);
66375+
wolfSSL_OCSP_CERTID_free(certId);
6637766376
certId = NULL;
6637866377
}
6637966378
}
@@ -66382,8 +66381,6 @@ static int test_wolfSSL_d2i_OCSP_CERTID(void)
6638266381
* always be returned. */
6638366382
{
6638466383
WOLFSSL_OCSP_CERTID* certId = NULL;
66385-
ExpectNull(certIdBad = wolfSSL_d2i_OCSP_CERTID(NULL, &rawCertIdPtr,
66386-
sizeof(rawCertId)));
6638766384
ExpectNull(certIdBad = wolfSSL_d2i_OCSP_CERTID(&certId, NULL,
6638866385
sizeof(rawCertId)));
6638966386
ExpectNull(certIdBad = wolfSSL_d2i_OCSP_CERTID(&certId, &rawCertIdPtr, 0));
@@ -90451,6 +90448,7 @@ TEST_CASE testCases[] = {
9045190448
TEST_DECL(test_ocsp_status_callback),
9045290449
TEST_DECL(test_ocsp_basic_verify),
9045390450
TEST_DECL(test_ocsp_response_parsing),
90451+
TEST_DECL(test_ocsp_certid_enc_dec),
9045490452
/* This test needs to stay at the end to clean up any caches allocated. */
9045590453
TEST_DECL(test_wolfSSL_Cleanup)
9045690454
};

tests/api/create_ocsp_test_blobs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ def create_bad_response(rd: dict) -> bytes:
401401
},
402402
]
403403

404-
with open('./tests/api/ocsp_test_blobs.h', 'w') as f:
404+
with open('./tests/api/test_ocsp_test_blobs.h', 'w') as f:
405405
f.write(
406406
"""/*
407407
* This file is generated automatically by running ./tests/api/create_ocsp_test_blobs.py.

0 commit comments

Comments
 (0)