Merge pull request #8498 from rizlik/ocsp_fixes

OCSP openssl compat fixes
This commit is contained in:
Sean Parkinson
2025-02-28 13:42:50 +10:00
committed by GitHub
7 changed files with 408 additions and 140 deletions

View File

@ -727,13 +727,23 @@ WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_cert_to_id(
WOLFSSL_CERT_MANAGER* cm = NULL;
int ret = -1;
DerBuffer* derCert = NULL;
int dgstType;
#ifdef WOLFSSL_SMALL_STACK
DecodedCert *cert = NULL;
#else
DecodedCert cert[1];
#endif
(void)dgst;
if (dgst == NULL) {
dgstType = WC_HASH_TYPE_SHA;
}
else if (wolfSSL_EVP_get_hashinfo(dgst, &dgstType, NULL) !=
WOLFSSL_SUCCESS) {
return NULL;
}
if (dgstType != OCSP_DIGEST)
return NULL;
cm = wolfSSL_CertManagerNew();
if (cm == NULL
@ -785,6 +795,7 @@ WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_cert_to_id(
goto out;
}
else {
certId->hashAlgoOID = wc_HashGetOID(OCSP_DIGEST);
XMEMCPY(certId->issuerHash, cert->issuerHash, OCSP_DIGEST_SIZE);
XMEMCPY(certId->issuerKeyHash, cert->issuerKeyHash, OCSP_DIGEST_SIZE);
XMEMCPY(certId->status->serial, cert->serial, (size_t)cert->serialSz);
@ -822,6 +833,78 @@ void wolfSSL_OCSP_BASICRESP_free(WOLFSSL_OCSP_BASICRESP* basicResponse)
wolfSSL_OCSP_RESPONSE_free(basicResponse);
}
/* Calculate ancode CertID DER encoding following RFC 6960:
CertID ::= SEQUENCE {
hashAlgorithm AlgorithmIdentifier,
issuerNameHash OCTET STRING,
issuerKeyHash OCTET STRING,
serialNumber CertificateSerialNumber }
*/
static int OcspEncodeCertID(WOLFSSL_OCSP_CERTID* id, byte* output,
word32* totalSz, word32* intSize)
{
word32 idx = 0;
int ret;
if (id == NULL || totalSz == NULL || intSize == NULL ||
(output != NULL && (*totalSz == 0 || *totalSz <= *intSize)))
return BAD_FUNC_ARG;
if (output != NULL) {
ret = SetSequence(*intSize, output);
if (ret < 0)
return ret;
idx += ret;
}
ret = SetAlgoID(id->hashAlgoOID, ((output != NULL) ? output + idx : output),
oidHashType, 0);
if (ret <= 0)
return -1;
idx += ret;
/* issuerNameHash */
ret = SetOctetString(OCSP_DIGEST_SIZE, ((output != NULL) ? output + idx : output));
if (ret < 0)
return ret;
idx += ret;
if (output != NULL)
XMEMCPY(output + idx, id->issuerHash, OCSP_DIGEST_SIZE);
idx += OCSP_DIGEST_SIZE;
/* issuerKeyHash */
ret = SetOctetString(OCSP_DIGEST_SIZE, ((output != NULL) ? output + idx : output));
if (ret < 0)
return ret;
idx += ret;
if (output != NULL)
XMEMCPY(output + idx, id->issuerKeyHash, OCSP_DIGEST_SIZE);
idx += OCSP_DIGEST_SIZE;
/* serialNumber */
ret = SetASNInt(id->status->serialSz, id->status->serial[0], ((output != NULL) ? output + idx : output));
if (ret < 0)
return ret;
idx += ret;
if (output != NULL)
XMEMCPY(output + idx, id->status->serial, id->status->serialSz);
idx += id->status->serialSz;
if (output == NULL) {
*intSize = idx;
ret = SetSequence(idx, NULL);
if (ret < 0)
return ret;
idx += ret;
*totalSz = idx;
}
else if (idx != *totalSz) {
return BUFFER_E;
}
return 0;
}
static int OcspRespIdMatches(OcspResponse* resp, const byte* NameHash,
const byte* keyHash)
{
@ -1284,22 +1367,59 @@ int wolfSSL_i2d_OCSP_REQUEST_bio(WOLFSSL_BIO* out,
int wolfSSL_i2d_OCSP_CERTID(WOLFSSL_OCSP_CERTID* id, unsigned char** data)
{
if (id == NULL || data == NULL)
return WOLFSSL_FAILURE;
int allocated = 0;
word32 derSz = 0;
word32 intSz = 0;
int ret;
WOLFSSL_ENTER("wolfSSL_i2d_OCSP_CERTID");
if (*data != NULL) {
XMEMCPY(*data, id->rawCertId, (size_t)id->rawCertIdSize);
*data = *data + id->rawCertIdSize;
if (id == NULL)
return -1;
if (id->rawCertId != NULL) {
derSz = id->rawCertIdSize;
}
else {
*data = (unsigned char*)XMALLOC((size_t)id->rawCertIdSize, NULL, DYNAMIC_TYPE_OPENSSL);
if (*data == NULL) {
return WOLFSSL_FAILURE;
ret = OcspEncodeCertID(id, NULL, &derSz, &intSz);
if (ret != 0) {
WOLFSSL_MSG("Failed to calculate CertID size");
return -1;
}
XMEMCPY(*data, id->rawCertId, (size_t)id->rawCertIdSize);
}
return id->rawCertIdSize;
if (data == NULL) {
return derSz;
}
if (*data == NULL) {
/* Allocate buffer for DER encoding */
*data = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL);
if (*data == NULL) {
WOLFSSL_MSG("Failed to allocate memory for CertID DER encoding");
return -1;
}
allocated = 1;
}
if (id->rawCertId != NULL) {
XMEMCPY(*data, id->rawCertId, id->rawCertIdSize);
}
else {
ret = OcspEncodeCertID(id, *data, &derSz, &intSz);
if (ret < 0) {
WOLFSSL_MSG("Failed to encode CertID");
if (allocated) {
XFREE(*data, NULL, DYNAMIC_TYPE_OPENSSL);
*data = NULL;
}
return -1;
}
}
if (!allocated)
*data += derSz;
return derSz;
}
WOLFSSL_OCSP_CERTID* wolfSSL_d2i_OCSP_CERTID(WOLFSSL_OCSP_CERTID** cidOut,
@ -1307,46 +1427,52 @@ WOLFSSL_OCSP_CERTID* wolfSSL_d2i_OCSP_CERTID(WOLFSSL_OCSP_CERTID** cidOut,
int length)
{
WOLFSSL_OCSP_CERTID *cid = NULL;
int isAllocated = 0;
word32 idx = 0;
int ret;
if ((cidOut != NULL) && (derIn != NULL) && (*derIn != NULL) &&
(length > 0)) {
if (derIn == NULL || *derIn == NULL || length <= 0)
return NULL;
if (cidOut != NULL && *cidOut != NULL) {
cid = *cidOut;
/* If a NULL is passed we allocate the memory for the caller. */
if (cid == NULL) {
cid = (WOLFSSL_OCSP_CERTID*)XMALLOC(sizeof(*cid), NULL,
FreeOcspEntry(cid, NULL);
}
else {
cid = (WOLFSSL_OCSP_CERTID*)XMALLOC(sizeof(WOLFSSL_OCSP_CERTID), NULL,
DYNAMIC_TYPE_OPENSSL);
}
else if (cid->rawCertId != NULL) {
XFREE(cid->rawCertId, NULL, DYNAMIC_TYPE_OPENSSL);
cid->rawCertId = NULL;
cid->rawCertIdSize = 0;
if (cid == NULL)
return NULL;
isAllocated = 1;
}
if (cid != NULL) {
cid->rawCertId = (byte*)XMALLOC((size_t)length + 1, NULL, DYNAMIC_TYPE_OPENSSL);
if (cid->rawCertId != NULL) {
XMEMCPY(cid->rawCertId, *derIn, (size_t)length);
cid->rawCertIdSize = length;
/* Per spec. advance past the data that is being returned
* to the caller. */
*cidOut = cid;
*derIn = *derIn + length;
return cid;
}
}
XMEMSET(cid, 0, sizeof(WOLFSSL_OCSP_CERTID));
cid->status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
DYNAMIC_TYPE_OCSP_STATUS);
if (cid->status == NULL) {
XFREE(cid, NULL, DYNAMIC_TYPE_OPENSSL);
return NULL;
}
XMEMSET(cid->status, 0, sizeof(CertStatus));
cid->ownStatus = 1;
if ((cid != NULL) && ((cidOut == NULL) || (cid != *cidOut))) {
ret = OcspDecodeCertID(*derIn, &idx, length, cid);
if (ret != 0) {
FreeOcspEntry(cid, NULL);
if (isAllocated) {
XFREE(cid, NULL, DYNAMIC_TYPE_OPENSSL);
}
return NULL;
}
*derIn += idx;
if (isAllocated && cidOut != NULL)
*cidOut = cid;
return cid;
}
const WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_SINGLERESP_get0_id(
const WOLFSSL_OCSP_SINGLERESP *single)
{

View File

@ -66217,7 +66217,8 @@ static int test_wolfSSL_OCSP_id_get0_info(void)
{
EXPECT_DECLS;
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY)) && \
defined(HAVE_OCSP) && !defined(NO_FILESYSTEM) && !defined(NO_RSA)
defined(HAVE_OCSP) && !defined(NO_FILESYSTEM) && !defined(NO_RSA) && \
!defined(WOLFSSL_SM2) && !defined(WOLFSSL_SM3)
X509* cert = NULL;
X509* issuer = NULL;
OCSP_CERTID* id = NULL;
@ -66349,10 +66350,9 @@ static int test_wolfSSL_d2i_OCSP_CERTID(void)
WOLFSSL_OCSP_CERTID* certId = NULL;
ExpectNotNull(certId = wolfSSL_d2i_OCSP_CERTID(&certId, &rawCertIdPtr,
sizeof(rawCertId)));
ExpectIntEQ(certId->rawCertIdSize, sizeof(rawCertId));
if (certId != NULL) {
XFREE(certId->rawCertId, NULL, DYNAMIC_TYPE_OPENSSL);
XFREE(certId, NULL, DYNAMIC_TYPE_OPENSSL);
wolfSSL_OCSP_CERTID_free(certId);
}
}
@ -66370,10 +66370,9 @@ static int test_wolfSSL_d2i_OCSP_CERTID(void)
ExpectNotNull(certIdGood = wolfSSL_d2i_OCSP_CERTID(&certId, &rawCertIdPtr,
sizeof(rawCertId)));
ExpectPtrEq(certIdGood, certId);
ExpectIntEQ(certId->rawCertIdSize, sizeof(rawCertId));
if (certId != NULL) {
XFREE(certId->rawCertId, NULL, DYNAMIC_TYPE_OPENSSL);
XFREE(certId, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL_OCSP_CERTID_free(certId);
certId = NULL;
}
}
@ -66382,8 +66381,6 @@ static int test_wolfSSL_d2i_OCSP_CERTID(void)
* always be returned. */
{
WOLFSSL_OCSP_CERTID* certId = NULL;
ExpectNull(certIdBad = wolfSSL_d2i_OCSP_CERTID(NULL, &rawCertIdPtr,
sizeof(rawCertId)));
ExpectNull(certIdBad = wolfSSL_d2i_OCSP_CERTID(&certId, NULL,
sizeof(rawCertId)));
ExpectNull(certIdBad = wolfSSL_d2i_OCSP_CERTID(&certId, &rawCertIdPtr, 0));
@ -90451,6 +90448,7 @@ TEST_CASE testCases[] = {
TEST_DECL(test_ocsp_status_callback),
TEST_DECL(test_ocsp_basic_verify),
TEST_DECL(test_ocsp_response_parsing),
TEST_DECL(test_ocsp_certid_enc_dec),
/* This test needs to stay at the end to clean up any caches allocated. */
TEST_DECL(test_wolfSSL_Cleanup)
};

View File

@ -401,7 +401,7 @@ if __name__ == '__main__':
},
]
with open('./tests/api/ocsp_test_blobs.h', 'w') as f:
with open('./tests/api/test_ocsp_test_blobs.h', 'w') as f:
f.write(
"""/*
* This file is generated automatically by running ./tests/api/create_ocsp_test_blobs.py.

View File

@ -34,7 +34,7 @@
#include <wolfssl/ocsp.h>
#include <wolfssl/ssl.h>
#if defined(HAVE_OCSP)
#if defined(HAVE_OCSP) && !defined(NO_SHA)
struct ocsp_cb_ctx {
byte* response;
int responseSz;
@ -158,12 +158,12 @@ int test_ocsp_response_parsing(void)
return EXPECT_SUCCESS();
}
#else /* HAVE_OCSP */
#else /* HAVE_OCSP && !NO_SHA */
int test_ocsp_response_parsing(void)
{
return TEST_SKIPPED;
}
#endif /* HAVE_OCSP */
#endif /* HAVE_OCSP && !NO_SHA */
#if defined(HAVE_OCSP) && (defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA))
static int test_ocsp_create_x509store(WOLFSSL_X509_STORE** store,
@ -222,7 +222,7 @@ int test_ocsp_basic_verify(void)
ExpectIntEQ(response->responseStatus, 0);
ExpectIntEQ(response->responderIdType, OCSP_RESPONDER_ID_KEY);
ExpectBufEQ(response->responderId.keyHash, cert.subjectKeyHash,
OCSP_DIGEST_SIZE);
OCSP_RESPONDER_ID_KEY_SZ);
wolfSSL_OCSP_RESPONSE_free(response);
/* decoding with no embedded certificates */
@ -592,3 +592,71 @@ int test_ocsp_status_callback(void)
&& defined(HAVE_CERTIFICATE_STATUS_REQUEST) && \
!defined(WOLFSSL_NO_TLS12) \
&& defined(OPENSSL_ALL) */
#if !defined(NO_SHA) && defined(OPENSSL_ALL) && defined(HAVE_OCSP) && \
!defined(WOLFSSL_SM3) && !defined(WOLFSSL_SM2)
int test_ocsp_certid_enc_dec(void)
{
EXPECT_DECLS;
WOLFSSL_OCSP_CERTID* certIdDec = NULL;
WOLFSSL_OCSP_CERTID* certId = NULL;
WOLFSSL_X509* subject = NULL;
WOLFSSL_X509* issuer = NULL;
unsigned char* temp = NULL;
unsigned char* der2 = NULL;
unsigned char* der = NULL;
int derSz = 0, derSz1 = 0;
/* Load test certificates */
ExpectNotNull(
subject = wolfSSL_X509_load_certificate_file(
"./certs/ocsp/intermediate1-ca-cert.pem", WOLFSSL_FILETYPE_PEM));
ExpectNotNull(issuer = wolfSSL_X509_load_certificate_file(
"./certs/ocsp/root-ca-cert.pem", WOLFSSL_FILETYPE_PEM));
/* Create CERTID from certificates */
ExpectNotNull(certId = wolfSSL_OCSP_cert_to_id(NULL, subject, issuer));
/* get len */
ExpectIntGT(derSz = wolfSSL_i2d_OCSP_CERTID(certId, NULL), 0);
/* encode it */
ExpectIntGT(derSz1 = wolfSSL_i2d_OCSP_CERTID(certId, &der), 0);
ExpectIntEQ(derSz, derSz1);
if (EXPECT_SUCCESS())
temp = der2 = (unsigned char*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL);
ExpectNotNull(der2);
/* encode without allocation */
ExpectIntGT(derSz1 = wolfSSL_i2d_OCSP_CERTID(certId, &der2), 0);
ExpectIntEQ(derSz, derSz1);
ExpectPtrEq(der2, temp + derSz);
ExpectBufEQ(der, temp, derSz);
XFREE(temp, NULL, DYNAMIC_TYPE_OPENSSL);
/* save original */
temp = der;
/* decode it */
ExpectNotNull(certIdDec = wolfSSL_d2i_OCSP_CERTID(NULL,
(const unsigned char**)&der, derSz));
/* check ptr is advanced */
ExpectPtrEq(der, temp + derSz);
der = der2;
XFREE(temp, NULL, DYNAMIC_TYPE_OPENSSL);
/* compare */
ExpectIntEQ(wolfSSL_OCSP_id_cmp(certId, certIdDec), 0);
wolfSSL_OCSP_CERTID_free(certId);
wolfSSL_OCSP_CERTID_free(certIdDec);
wolfSSL_X509_free(subject);
wolfSSL_X509_free(issuer);
return EXPECT_SUCCESS();
}
#else /* !NO_SHA && OPENSSL_ALL && HAVE_OCSP && !WOLFSSL_SM3 && !WOLFSSL_SM2 */
int test_ocsp_certid_enc_dec(void)
{
return TEST_SKIPPED;
}
#endif

View File

@ -22,6 +22,7 @@
#ifndef WOLFSSL_TEST_OCSP_H
#define WOLFSSL_TEST_OCSP_H
int test_ocsp_certid_enc_dec(void);
int test_ocsp_status_callback(void);
int test_ocsp_basic_verify(void);
int test_ocsp_response_parsing(void);

View File

@ -36374,17 +36374,7 @@ static int GetEnumerated(const byte* input, word32* inOutIdx, int *value,
static const ASNItem singleResponseASN[] = {
/* SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 },
/* certId */
/* CID_SEQ */ { 1, ASN_SEQUENCE, 1, 1, 0 },
/* hashAlgorithm */
/* CID_HASHALGO_SEQ */ { 2, ASN_SEQUENCE, 1, 1, 0 },
/* CID_HASHALGO_OID */ { 3, ASN_OBJECT_ID, 0, 0, 0 },
/* CID_HASHALGO_NULL */ { 3, ASN_TAG_NULL, 0, 0, 1 },
/* issuerNameHash */
/* CID_ISSUERHASH */ { 2, ASN_OCTET_STRING, 0, 0, 0 },
/* issuerKeyHash */
/* CID_ISSUERKEYHASH */ { 2, ASN_OCTET_STRING, 0, 0, 0 },
/* serialNumber */
/* CID_SERIAL */ { 2, ASN_INTEGER, 0, 0, 0 },
/* CID_SEQ */ { 1, ASN_SEQUENCE, 1, 0, 0 },
/* certStatus - CHOICE */
/* good [0] IMPLICIT NULL */
/* CS_GOOD */ { 1, ASN_CONTEXT_SPECIFIC | 0, 0, 0, 2 },
@ -36410,12 +36400,6 @@ static const ASNItem singleResponseASN[] = {
enum {
SINGLERESPONSEASN_IDX_SEQ = 0,
SINGLERESPONSEASN_IDX_CID_SEQ,
SINGLERESPONSEASN_IDX_CID_HASHALGO_SEQ,
SINGLERESPONSEASN_IDX_CID_HASHALGO_OID,
SINGLERESPONSEASN_IDX_CID_HASHALGO_NULL,
SINGLERESPONSEASN_IDX_CID_ISSUERHASH,
SINGLERESPONSEASN_IDX_CID_ISSUERKEYHASH,
SINGLERESPONSEASN_IDX_CID_SERIAL,
SINGLERESPONSEASN_IDX_CS_GOOD,
SINGLERESPONSEASN_IDX_CS_REVOKED,
SINGLERESPONSEASN_IDX_CS_REVOKED_TIME,
@ -36430,13 +36414,139 @@ enum {
/* Number of items in ASN.1 template for OCSP single response. */
#define singleResponseASN_Length (sizeof(singleResponseASN) / sizeof(ASNItem))
static const ASNItem certIDASNItems[] = {
/* hashAlgorithm */
/* CID_HASHALGO_SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 },
/* CID_HASHALGO_OID */ { 1, ASN_OBJECT_ID, 0, 0, 0 },
/* CID_HASHALGO_NULL */ { 1, ASN_TAG_NULL, 0, 0, 1 },
/* issuerNameHash */
/* CID_ISSUERHASH */ { 0, ASN_OCTET_STRING, 0, 0, 0 },
/* issuerKeyHash */
/* CID_ISSUERKEYHASH */ { 0, ASN_OCTET_STRING, 0, 0, 0 },
/* serialNumber */
/* CID_SERIAL */ { 0, ASN_INTEGER, 0, 0, 0 },
};
enum {
CERTIDASN_IDX_CID_HASHALGO_SEQ,
CERTIDASN_IDX_CID_HASHALGO_OID,
CERTIDASN_IDX_CID_HASHALGO_NULL,
CERTIDASN_IDX_CID_ISSUERHASH,
CERTIDASN_IDX_CID_ISSUERKEYHASH,
CERTIDASN_IDX_CID_SERIAL,
};
#define certidasn_Length (sizeof(certIDASNItems) / sizeof(ASNItem))
#endif
#ifndef WOLFSSL_ASN_TEMPLATE
static int OcspDecodeCertIDInt(const byte* input, word32* inOutIdx, word32 inSz,
OcspEntry* entry)
{
int length;
word32 oid;
int ret;
/* Hash algorithm */
ret = GetAlgoId(input, inOutIdx, &oid, oidHashType, inSz);
if (ret < 0)
return ret;
entry->hashAlgoOID = oid;
/* Save reference to the hash of CN */
ret = GetOctetString(input, inOutIdx, &length, inSz);
if (ret < 0)
return ret;
if (length != OCSP_DIGEST_SIZE)
return ASN_PARSE_E;
XMEMCPY(entry->issuerHash, input + *inOutIdx, length);
*inOutIdx += length;
/* Save reference to the hash of the issuer public key */
ret = GetOctetString(input, inOutIdx, &length, inSz);
if (ret < 0)
return ret;
if (length != OCSP_DIGEST_SIZE)
return ASN_PARSE_E;
XMEMCPY(entry->issuerKeyHash, input + *inOutIdx, length);
*inOutIdx += length;
/* Get serial number */
if (wc_GetSerialNumber(input, inOutIdx, entry->status->serial,
&entry->status->serialSz, inSz) < 0)
return ASN_PARSE_E;
return 0;
}
#else
static int OcspDecodeCertIDInt(const byte* input, word32* inOutIdx, word32 inSz,
OcspEntry* entry)
{
DECL_ASNGETDATA(dataASN, certidasn_Length);
word32 issuerKeyHashLen = OCSP_DIGEST_SIZE;
word32 issuerHashLen = OCSP_DIGEST_SIZE;
word32 serialSz = EXTERNAL_SERIAL_SIZE;
word32 digestSz;
int ret = 0;
WOLFSSL_ENTER("DecodeCertIdTemplate");
CALLOC_ASNGETDATA(dataASN, certidasn_Length, ret, NULL);
if (ret != 0)
return ret;
GetASN_OID(&dataASN[CERTIDASN_IDX_CID_HASHALGO_OID], oidHashType);
GetASN_Buffer(&dataASN[CERTIDASN_IDX_CID_ISSUERHASH], entry->issuerHash,
&issuerHashLen);
GetASN_Buffer(&dataASN[CERTIDASN_IDX_CID_ISSUERKEYHASH],
entry->issuerKeyHash, &issuerKeyHashLen);
GetASN_Buffer(&dataASN[CERTIDASN_IDX_CID_SERIAL], entry->status->serial,
&serialSz);
ret = GetASN_Items(certIDASNItems, dataASN, certidasn_Length,
1, input, inOutIdx, inSz);
if (ret != 0) {
goto out;
}
entry->status->serialSz = serialSz;
entry->hashAlgoOID =
dataASN[CERTIDASN_IDX_CID_HASHALGO_OID].data.oid.sum;
digestSz = wc_HashGetDigestSize(wc_OidGetHash(entry->hashAlgoOID));
if (issuerKeyHashLen != digestSz || issuerHashLen != digestSz) {
ret = ASN_PARSE_E;
goto out;
}
out:
FREE_ASNGETDATA(dataASN, NULL);
return ret;
}
#endif
int OcspDecodeCertID(const byte *input, word32 *inOutIdx, word32 inSz,
OcspEntry *entry)
{
word32 seqIdx = 0;
int len = inSz;
int ret;
#ifndef WOLFSSL_ASN_TEMPLATE
ret = GetSequence(input, inOutIdx, &len, inSz);
#else
ret = GetASN_Sequence(input, inOutIdx, &len, inSz, 0);
#endif
if (ret < 0)
return ASN_PARSE_E;
ret = OcspDecodeCertIDInt(input + *inOutIdx, &seqIdx, len, entry);
if (ret < 0)
return ASN_PARSE_E;
if (seqIdx != (word32)len)
return ASN_PARSE_E;
*inOutIdx += len;
return 0;
}
static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size,
int wrapperSz, OcspEntry* single)
{
#ifndef WOLFSSL_ASN_TEMPLATE
word32 idx = *ioIndex, prevIndex, oid, localIdx, certIdIdx;
word32 idx = *ioIndex, prevIndex, localIdx, certIdIdx;
int length;
int ret;
byte tag;
@ -36454,31 +36564,8 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size,
if (GetSequence(source, &idx, &length, size) < 0)
return ASN_PARSE_E;
single->rawCertId = source + certIdIdx;
/* Hash algorithm */
ret = GetAlgoId(source, &idx, &oid, oidIgnoreType, size);
ret = OcspDecodeCertIDInt(source, &idx, size, single);
if (ret < 0)
return ret;
single->hashAlgoOID = oid;
/* Save reference to the hash of CN */
ret = GetOctetString(source, &idx, &length, size);
if (ret < 0)
return ret;
if (length > (int)sizeof(single->issuerHash))
return BUFFER_E;
XMEMCPY(single->issuerHash, source + idx, length);
idx += length;
/* Save reference to the hash of the issuer public key */
ret = GetOctetString(source, &idx, &length, size);
if (ret < 0)
return ret;
if (length > (int)sizeof(single->issuerKeyHash))
return BUFFER_E;
XMEMCPY(single->issuerKeyHash, source + idx, length);
idx += length;
/* Get serial number */
if (wc_GetSerialNumber(source, &idx, single->status->serial,
&single->status->serialSz, size) < 0)
return ASN_PARSE_E;
single->rawCertIdSize = idx - certIdIdx;
@ -36591,13 +36678,10 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size,
#else /* WOLFSSL_ASN_TEMPLATE */
DECL_ASNGETDATA(dataASN, singleResponseASN_Length);
int ret = 0;
word32 ocspDigestSize = OCSP_DIGEST_SIZE;
CertStatus* cs = NULL;
word32 serialSz;
word32 issuerHashLen;
word32 issuerKeyHashLen;
word32 thisDateLen;
word32 nextDateLen;
word32 certIdSeqIdx;
(void)wrapperSz;
@ -36606,25 +36690,12 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size,
CALLOC_ASNGETDATA(dataASN, singleResponseASN_Length, ret, NULL);
if (ret == 0) {
/* Certificate Status field. */
cs = single->status;
/* Set maximum lengths for data. */
issuerHashLen = OCSP_DIGEST_SIZE;
issuerKeyHashLen = OCSP_DIGEST_SIZE;
serialSz = EXTERNAL_SERIAL_SIZE;
thisDateLen = MAX_DATE_SIZE;
nextDateLen = MAX_DATE_SIZE;
/* Set OID type, buffers to hold data and variables to hold size. */
GetASN_OID(&dataASN[SINGLERESPONSEASN_IDX_CID_HASHALGO_OID],
oidHashType);
GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_CID_ISSUERHASH],
single->issuerHash, &issuerHashLen);
GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_CID_ISSUERKEYHASH],
single->issuerKeyHash, &issuerKeyHashLen);
GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_CID_SERIAL], cs->serial,
&serialSz);
GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_THISUPDATE_GT],
cs->thisDate, &thisDateLen);
GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_NEXTUPDATE_GT],
@ -36635,27 +36706,11 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size,
1, source, ioIndex, size);
}
if (ret == 0) {
single->hashAlgoOID =
dataASN[SINGLERESPONSEASN_IDX_CID_HASHALGO_OID].data.oid.sum;
ocspDigestSize = (word32)wc_HashGetDigestSize(
wc_OidGetHash((int)single->hashAlgoOID));
}
/* Validate the issuer hash length is the size required. */
if ((ret == 0) && (issuerHashLen != ocspDigestSize)) {
ret = ASN_PARSE_E;
}
/* Validate the issuer key hash length is the size required. */
if (ret == 0) {
if (issuerKeyHashLen != ocspDigestSize) {
ret = ASN_PARSE_E;
}
certIdSeqIdx = 0;
ret = OcspDecodeCertIDInt(dataASN[SINGLERESPONSEASN_IDX_CID_SEQ].data.ref.data,
&certIdSeqIdx, dataASN[SINGLERESPONSEASN_IDX_CID_SEQ].data.ref.length, single);
}
if (ret == 0) {
/* Store serial size. */
cs->serialSz = (int)serialSz;
/* Set the hash algorithm OID */
single->hashAlgoOID =
dataASN[SINGLERESPONSEASN_IDX_CID_HASHALGO_OID].data.oid.sum;
/* Determine status by which item was found. */
if (dataASN[SINGLERESPONSEASN_IDX_CS_GOOD].tag != 0) {
@ -36964,7 +37019,7 @@ static int DecodeResponseData(byte* source, word32* ioIndex,
/* compute the hash of the name */
resp->responderIdType = OCSP_RESPONDER_ID_NAME;
ret = CalcHashId_ex(source + idx, length,
resp->responderId.nameHash, WC_SHA);
resp->responderId.nameHash, OCSP_RESPONDER_ID_HASH_TYPE);
if (ret != 0)
return ret;
idx += length;
@ -36978,7 +37033,7 @@ static int DecodeResponseData(byte* source, word32* ioIndex,
if (GetOctetString(source, &idx, &length, size) < 0)
return ASN_PARSE_E;
if (length != KEYID_SIZE)
if (length != OCSP_RESPONDER_ID_KEY_SZ)
return ASN_PARSE_E;
resp->responderIdType = OCSP_RESPONDER_ID_KEY;
XMEMCPY(resp->responderId.keyHash, source + idx, length);
@ -37041,7 +37096,7 @@ static int DecodeResponseData(byte* source, word32* ioIndex,
int ret = 0;
byte version;
word32 dateSz = 0;
word32 responderByKeySz = KEYID_SIZE;
word32 responderByKeySz = OCSP_RESPONDER_ID_KEY_SZ;
word32 idx = *ioIndex;
OcspEntry* single = NULL;
@ -37084,10 +37139,11 @@ static int DecodeResponseData(byte* source, word32* ioIndex,
ret = CalcHashId_ex(
dataASN[OCSPRESPDATAASN_IDX_BYNAME].data.ref.data,
dataASN[OCSPRESPDATAASN_IDX_BYNAME].data.ref.length,
resp->responderId.nameHash, WC_SHA);
resp->responderId.nameHash, OCSP_RESPONDER_ID_HASH_TYPE);
} else {
resp->responderIdType = OCSP_RESPONDER_ID_KEY;
if (dataASN[OCSPRESPDATAASN_IDX_BYKEY_OCT].length != KEYID_SIZE) {
if (dataASN[OCSPRESPDATAASN_IDX_BYKEY_OCT].length
!= OCSP_RESPONDER_ID_KEY_SZ) {
ret = ASN_PARSE_E;
} else {
resp->responderIdType = OCSP_RESPONDER_ID_KEY;
@ -37240,10 +37296,14 @@ enum {
static int OcspRespIdMatch(OcspResponse *resp, const byte *NameHash,
const byte *keyHash)
{
if (resp->responderIdType == OCSP_RESPONDER_ID_INVALID)
return 0;
if (resp->responderIdType == OCSP_RESPONDER_ID_NAME)
return XMEMCMP(NameHash, resp->responderId.nameHash,
SIGNER_DIGEST_SIZE) == 0;
return XMEMCMP(keyHash, resp->responderId.keyHash, KEYID_SIZE) == 0;
/* OCSP_RESPONDER_ID_KEY */
return ((int)KEYID_SIZE == OCSP_RESPONDER_ID_KEY_SZ) &&
XMEMCMP(keyHash, resp->responderId.keyHash, KEYID_SIZE) == 0;
}
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
@ -37282,7 +37342,7 @@ static Signer *OcspFindSigner(OcspResponse *resp, WOLFSSL_CERT_MANAGER *cm)
if (s)
return s;
}
else {
else if ((int)KEYID_SIZE == OCSP_RESPONDER_ID_KEY_SZ) {
s = GetCAByKeyHash(cm, resp->responderId.keyHash);
if (s)
return s;

View File

@ -2707,6 +2707,14 @@ struct CertStatus {
typedef struct OcspEntry OcspEntry;
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
#define OCSP_DIGEST WC_HASH_TYPE_SM3
#elif defined(NO_SHA)
#define OCSP_DIGEST WC_HASH_TYPE_SHA256
#else
#define OCSP_DIGEST WC_HASH_TYPE_SHA
#endif
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
#define OCSP_DIGEST_SIZE WC_SM3_DIGEST_SIZE
#elif defined(NO_SHA)
@ -2732,6 +2740,12 @@ struct OcspEntry
WC_BITFIELD used:1; /* entry used */
};
#define OCSP_RESPONDER_ID_KEY_SZ 20
#if !defined(NO_SHA)
#define OCSP_RESPONDER_ID_HASH_TYPE WC_SHA
#else
#define OCSP_RESPONDER_ID_HASH_TYPE WC_SHA256
#endif
enum responderIdType {
OCSP_RESPONDER_ID_INVALID = 0,
OCSP_RESPONDER_ID_NAME = 1,
@ -2750,7 +2764,7 @@ struct OcspResponse {
enum responderIdType responderIdType;
union {
byte keyHash[KEYID_SIZE];
byte keyHash[OCSP_RESPONDER_ID_KEY_SZ];
byte nameHash[KEYID_SIZE];
} responderId ;
@ -2817,7 +2831,8 @@ WOLFSSL_LOCAL word32 EncodeOcspRequestExtensions(OcspRequest* req, byte* output,
WOLFSSL_LOCAL int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp);
WOLFSSL_LOCAL int OcspDecodeCertID(const byte* input, word32* inOutIdx, word32 inSz,
OcspEntry* entry);
#endif /* HAVE_OCSP */