mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-31 11:17:29 +02:00
ocsp: refactor OCSP response decoding and wolfSSL_OCSP_basic_verify
- Search certificate based on responderId - Verify response signer is authorized for all single responses - Align with OpenSSL behavior - Separate wolfSSL_OCSP_basic_verify from verification done during decoding
This commit is contained in:
@@ -13876,7 +13876,7 @@ static int ProcessCSR_ex(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
/* InitOcspResponse sets single and status to response struct. */
|
/* InitOcspResponse sets single and status to response struct. */
|
||||||
InitOcspResponse(response, single, status, input +*inOutIdx, status_length, ssl->heap);
|
InitOcspResponse(response, single, status, input +*inOutIdx, status_length, ssl->heap);
|
||||||
|
|
||||||
if (OcspResponseDecode(response, SSL_CM(ssl), ssl->heap, 0) != 0)
|
if (OcspResponseDecode(response, SSL_CM(ssl), ssl->heap, 0, 0) != 0)
|
||||||
ret = BAD_CERTIFICATE_STATUS_ERROR;
|
ret = BAD_CERTIFICATE_STATUS_ERROR;
|
||||||
else if (CompareOcspReqResp(request, response) != 0)
|
else if (CompareOcspReqResp(request, response) != 0)
|
||||||
ret = BAD_CERTIFICATE_STATUS_ERROR;
|
ret = BAD_CERTIFICATE_STATUS_ERROR;
|
||||||
@@ -16982,7 +16982,7 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
status_length, ssl->heap);
|
status_length, ssl->heap);
|
||||||
response->pendingCAs = pendingCAs;
|
response->pendingCAs = pendingCAs;
|
||||||
if ((OcspResponseDecode(response, SSL_CM(ssl), ssl->heap,
|
if ((OcspResponseDecode(response, SSL_CM(ssl), ssl->heap,
|
||||||
0) != 0)
|
0, 0) != 0)
|
||||||
|| (response->responseStatus != OCSP_SUCCESSFUL)
|
|| (response->responseStatus != OCSP_SUCCESSFUL)
|
||||||
|| (response->single->status->status != CERT_GOOD))
|
|| (response->single->status->status != CERT_GOOD))
|
||||||
ret = BAD_CERTIFICATE_STATUS_ERROR;
|
ret = BAD_CERTIFICATE_STATUS_ERROR;
|
||||||
|
191
src/ocsp.c
191
src/ocsp.c
@@ -333,7 +333,7 @@ int CheckOcspResponse(WOLFSSL_OCSP *ocsp, byte *response, int responseSz,
|
|||||||
ocspResponse->pendingCAs = TLSX_CSR2_GetPendingSigners(((WOLFSSL*)ocspRequest->ssl)->extensions);
|
ocspResponse->pendingCAs = TLSX_CSR2_GetPendingSigners(((WOLFSSL*)ocspRequest->ssl)->extensions);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
ret = OcspResponseDecode(ocspResponse, ocsp->cm, ocsp->cm->heap, 0);
|
ret = OcspResponseDecode(ocspResponse, ocsp->cm, ocsp->cm->heap, 0, 0);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
ocsp->error = ret;
|
ocsp->error = ret;
|
||||||
WOLFSSL_LEAVE("OcspResponseDecode failed", ocsp->error);
|
WOLFSSL_LEAVE("OcspResponseDecode failed", ocsp->error);
|
||||||
@@ -631,9 +631,6 @@ int CheckOcspResponder(OcspResponse *bs, DecodedCert *cert, void* vp)
|
|||||||
|
|
||||||
if (!passed) {
|
if (!passed) {
|
||||||
WOLFSSL_MSG("\tOCSP Responder not authorized");
|
WOLFSSL_MSG("\tOCSP Responder not authorized");
|
||||||
#ifdef OPENSSL_EXTRA
|
|
||||||
bs->verifyError = OCSP_BAD_ISSUER;
|
|
||||||
#endif
|
|
||||||
ret = BAD_OCSP_RESPONDER;
|
ret = BAD_OCSP_RESPONDER;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -825,69 +822,155 @@ void wolfSSL_OCSP_BASICRESP_free(WOLFSSL_OCSP_BASICRESP* basicResponse)
|
|||||||
wolfSSL_OCSP_RESPONSE_free(basicResponse);
|
wolfSSL_OCSP_RESPONSE_free(basicResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int OcspRespIdMatches(OcspResponse* resp, const byte* NameHash,
|
||||||
|
const byte* keyHash)
|
||||||
|
{
|
||||||
|
if (resp->responderIdType == OCSP_RESPONDER_ID_NAME)
|
||||||
|
return (XMEMCMP(NameHash, resp->responderId.nameHash,
|
||||||
|
SIGNER_DIGEST_SIZE) == 0);
|
||||||
|
else if (resp->responderIdType == OCSP_RESPONDER_ID_KEY)
|
||||||
|
return (XMEMCMP(keyHash, resp->responderId.keyHash, KEYID_SIZE) == 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int OcspFindSigner(WOLFSSL_OCSP_BASICRESP *resp,
|
||||||
|
WOLF_STACK_OF(WOLFSSL_X509) *certs, DecodedCert **signer, int *embedded,
|
||||||
|
unsigned long flags)
|
||||||
|
{
|
||||||
|
WOLFSSL_X509 *signer_x509 = NULL;
|
||||||
|
DecodedCert *certDecoded;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
certDecoded = (DecodedCert *)XMALLOC(sizeof(*certDecoded), NULL,
|
||||||
|
DYNAMIC_TYPE_DCERT);
|
||||||
|
if (certDecoded == NULL)
|
||||||
|
return MEMORY_E;
|
||||||
|
|
||||||
|
for (i = 0; i < wolfSSL_sk_X509_num(certs); i++) {
|
||||||
|
signer_x509 = wolfSSL_sk_X509_value(certs, i);
|
||||||
|
|
||||||
|
InitDecodedCert(certDecoded, signer_x509->derCert->buffer,
|
||||||
|
signer_x509->derCert->length, NULL);
|
||||||
|
if (ParseCertRelative(certDecoded, CERT_TYPE, NO_VERIFY,
|
||||||
|
NULL, NULL) == 0) {
|
||||||
|
if (OcspRespIdMatches(resp, certDecoded->subjectHash,
|
||||||
|
certDecoded->subjectKeyHash)) {
|
||||||
|
*signer = certDecoded;
|
||||||
|
*embedded = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FreeDecodedCert(certDecoded);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & WOLFSSL_OCSP_NOINTERN) {
|
||||||
|
XFREE(certDecoded, NULL, DYNAMIC_TYPE_DCERT);
|
||||||
|
return ASN_NO_SIGNER_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* not found in certs, search the cert embedded in the response */
|
||||||
|
InitDecodedCert(certDecoded, resp->cert, resp->certSz, NULL);
|
||||||
|
if (ParseCertRelative(certDecoded, CERT_TYPE, NO_VERIFY, NULL, NULL) == 0) {
|
||||||
|
if (OcspRespIdMatches(resp, certDecoded->subjectHash,
|
||||||
|
certDecoded->subjectKeyHash)) {
|
||||||
|
*signer = certDecoded;
|
||||||
|
*embedded = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FreeDecodedCert(certDecoded);
|
||||||
|
|
||||||
|
XFREE(certDecoded, NULL, DYNAMIC_TYPE_DCERT);
|
||||||
|
return ASN_NO_SIGNER_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int OcspVerifySigner(WOLFSSL_OCSP_BASICRESP *resp, DecodedCert *cert,
|
||||||
|
WOLFSSL_X509_STORE *st, unsigned long flags)
|
||||||
|
{
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
DecodedCert *c = NULL;
|
||||||
|
#else
|
||||||
|
DecodedCert c[1];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int ret = -1;
|
||||||
|
if (st == NULL)
|
||||||
|
return ASN_OCSP_CONFIRM_E;
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
c = (DecodedCert *)XMALLOC(sizeof(*c), NULL, DYNAMIC_TYPE_DCERT);
|
||||||
|
if (c == NULL)
|
||||||
|
return MEMORY_E;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
InitDecodedCert(c, cert->source, cert->maxIdx, NULL);
|
||||||
|
if (ParseCertRelative(c, CERT_TYPE, VERIFY, st->cm, NULL) != 0) {
|
||||||
|
ret = ASN_OCSP_CONFIRM_E;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
|
||||||
|
if ((flags & WOLFSSL_OCSP_NOCHECKS) == 0) {
|
||||||
|
ret = CheckOcspResponder(resp, c, st->cm);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
(void)resp;
|
||||||
|
(void)flags;
|
||||||
|
ret = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
out:
|
||||||
|
FreeDecodedCert(c);
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
XFREE(c, NULL, DYNAMIC_TYPE_DCERT);
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
/* Signature verified in DecodeBasicOcspResponse.
|
/* Signature verified in DecodeBasicOcspResponse.
|
||||||
* But no store available to verify certificate. */
|
* But no store available to verify certificate. */
|
||||||
int wolfSSL_OCSP_basic_verify(WOLFSSL_OCSP_BASICRESP *bs,
|
int wolfSSL_OCSP_basic_verify(WOLFSSL_OCSP_BASICRESP* bs,
|
||||||
WOLF_STACK_OF(WOLFSSL_X509) *certs, WOLFSSL_X509_STORE *st, unsigned long flags)
|
WOLF_STACK_OF(WOLFSSL_X509) * certs, WOLFSSL_X509_STORE* st,
|
||||||
|
unsigned long flags)
|
||||||
{
|
{
|
||||||
int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
|
int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
int embedded;
|
||||||
DecodedCert *cert;
|
DecodedCert *cert = NULL;
|
||||||
#else
|
|
||||||
DecodedCert cert[1];
|
|
||||||
#endif
|
|
||||||
byte certInit = 0;
|
|
||||||
int idx;
|
|
||||||
|
|
||||||
(void)certs;
|
ret = OcspFindSigner(bs, certs, &cert, &embedded, flags);
|
||||||
|
if (ret != 0) {
|
||||||
if (flags & WOLFSSL_OCSP_NOVERIFY)
|
WOLFSSL_MSG("OCSP no signer found");
|
||||||
return WOLFSSL_SUCCESS;
|
|
||||||
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
cert = (DecodedCert *)
|
|
||||||
XMALLOC(sizeof(*cert), (st && st->cm) ? st->cm->heap : NULL,
|
|
||||||
DYNAMIC_TYPE_DCERT);
|
|
||||||
if (cert == NULL)
|
|
||||||
return WOLFSSL_FAILURE;
|
return WOLFSSL_FAILURE;
|
||||||
#endif
|
|
||||||
|
|
||||||
if (bs->verifyError != OCSP_VERIFY_ERROR_NONE)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (flags & WOLFSSL_OCSP_TRUSTOTHER) {
|
|
||||||
for (idx = 0; idx < wolfSSL_sk_X509_num(certs); idx++) {
|
|
||||||
WOLFSSL_X509* x = wolfSSL_sk_X509_value(certs, idx);
|
|
||||||
int derSz = 0;
|
|
||||||
const byte* der = wolfSSL_X509_get_der(x, &derSz);
|
|
||||||
if (der != NULL && derSz == (int)bs->certSz &&
|
|
||||||
XMEMCMP(bs->cert, der, (size_t)derSz) == 0) {
|
|
||||||
ret = WOLFSSL_SUCCESS;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InitDecodedCert(cert, bs->cert, bs->certSz, NULL);
|
/* skip certificate verification if cert in certs and TRUST_OTHER is true */
|
||||||
certInit = 1;
|
if (!embedded && (flags & WOLFSSL_OCSP_TRUSTOTHER) != 0)
|
||||||
if (ParseCertRelative(cert, CERT_TYPE, VERIFY, st->cm, NULL) < 0)
|
flags |= WOLFSSL_OCSP_NOVERIFY;
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (!(flags & WOLFSSL_OCSP_NOCHECKS)) {
|
/* verify response signature */
|
||||||
if (CheckOcspResponder(bs, cert, st->cm) != 0)
|
ret = ConfirmSignature(
|
||||||
|
&cert->sigCtx,
|
||||||
|
bs->response, bs->responseSz,
|
||||||
|
cert->publicKey, cert->pubKeySize, cert->keyOID,
|
||||||
|
bs->sig, bs->sigSz, bs->sigOID, bs->sigParams, bs->sigParamsSz,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
WOLFSSL_MSG("OCSP signature verification failed");
|
||||||
|
ret = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = WOLFSSL_SUCCESS;
|
if ((flags & WOLFSSL_OCSP_NOVERIFY) == 0) {
|
||||||
|
ret = OcspVerifySigner(bs, cert, st, flags);
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (certInit)
|
|
||||||
FreeDecodedCert(cert);
|
FreeDecodedCert(cert);
|
||||||
|
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
return ret == 0 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
|
||||||
XFREE(cert, (st && st->cm) ? st->cm->heap : NULL, DYNAMIC_TYPE_DCERT);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wolfSSL_OCSP_RESPONSE_free(OcspResponse* response)
|
void wolfSSL_OCSP_RESPONSE_free(OcspResponse* response)
|
||||||
@@ -1025,7 +1108,7 @@ OcspResponse* wolfSSL_d2i_OCSP_RESPONSE(OcspResponse** response,
|
|||||||
XMEMCPY(resp->source, *data, (size_t)len);
|
XMEMCPY(resp->source, *data, (size_t)len);
|
||||||
resp->maxIdx = (word32)len;
|
resp->maxIdx = (word32)len;
|
||||||
|
|
||||||
ret = OcspResponseDecode(resp, NULL, NULL, 1);
|
ret = OcspResponseDecode(resp, NULL, NULL, 1, 1);
|
||||||
if (ret != 0 && ret != WC_NO_ERR_TRACE(ASN_OCSP_CONFIRM_E)) {
|
if (ret != 0 && ret != WC_NO_ERR_TRACE(ASN_OCSP_CONFIRM_E)) {
|
||||||
/* for just converting from a DER to an internal structure the CA may
|
/* for just converting from a DER to an internal structure the CA may
|
||||||
* not yet be known to this function for signature verification */
|
* not yet be known to this function for signature verification */
|
||||||
|
@@ -4622,7 +4622,11 @@ static int test_wolfSSL_CheckOCSPResponse(void)
|
|||||||
wolfSSL_CertManagerFree(cm);
|
wolfSSL_CertManagerFree(cm);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(WC_RSA_PSS)
|
/* FIPS v2 and below don't support long salts. */
|
||||||
|
#if defined(WC_RSA_PSS) && \
|
||||||
|
(!defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
|
||||||
|
(HAVE_FIPS_VERSION > 2))) && (!defined(HAVE_SELFTEST) || \
|
||||||
|
(defined(HAVE_SELFTEST_VERSION) && (HAVE_SELFTEST_VERSION > 2)))
|
||||||
{
|
{
|
||||||
const char* responsePssFile = "./certs/ocsp/test-response-rsapss.der";
|
const char* responsePssFile = "./certs/ocsp/test-response-rsapss.der";
|
||||||
|
|
||||||
|
@@ -16822,7 +16822,7 @@ static int HashForSignature(const byte* buf, word32 bufSz, word32 sigOID,
|
|||||||
#endif /* !NO_ASN_CRYPT && !NO_HASH_WRAPPER */
|
#endif /* !NO_ASN_CRYPT && !NO_HASH_WRAPPER */
|
||||||
|
|
||||||
/* Return codes: 0=Success, Negative (see error-crypt.h), ASN_SIG_CONFIRM_E */
|
/* Return codes: 0=Success, Negative (see error-crypt.h), ASN_SIG_CONFIRM_E */
|
||||||
static int ConfirmSignature(SignatureCtx* sigCtx,
|
int ConfirmSignature(SignatureCtx* sigCtx,
|
||||||
const byte* buf, word32 bufSz,
|
const byte* buf, word32 bufSz,
|
||||||
const byte* key, word32 keySz, word32 keyOID,
|
const byte* key, word32 keySz, word32 keyOID,
|
||||||
const byte* sig, word32 sigSz, word32 sigOID,
|
const byte* sig, word32 sigSz, word32 sigOID,
|
||||||
@@ -23634,6 +23634,19 @@ int wc_CertGetPubKey(const byte* cert, word32 certSz,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_OCSP
|
||||||
|
Signer* findSignerByKeyHash(Signer *list, byte *hash)
|
||||||
|
{
|
||||||
|
Signer *s;
|
||||||
|
for (s = list; s != NULL; s = s->next) {
|
||||||
|
if (XMEMCMP(s->subjectKeyHash, hash, KEYID_SIZE) == 0) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_OCSP */
|
||||||
|
|
||||||
Signer* findSignerByName(Signer *list, byte *hash)
|
Signer* findSignerByName(Signer *list, byte *hash)
|
||||||
{
|
{
|
||||||
Signer *s;
|
Signer *s;
|
||||||
@@ -36864,7 +36877,8 @@ static const ASNItem ocspRespDataASN[] = {
|
|||||||
/* byName */
|
/* byName */
|
||||||
/* BYNAME */ { 1, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 2 },
|
/* BYNAME */ { 1, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 2 },
|
||||||
/* byKey */
|
/* byKey */
|
||||||
/* BYKEY */ { 1, ASN_CONTEXT_SPECIFIC | 2, 1, 0, 2 },
|
/* BYKEY */ { 1, ASN_CONTEXT_SPECIFIC | 2, 1, 1, 2 },
|
||||||
|
/* BYKEY_OCT */ { 2, ASN_OCTET_STRING, 0, 0, 0 },
|
||||||
/* producedAt */
|
/* producedAt */
|
||||||
/* PA */ { 1, ASN_GENERALIZED_TIME, 0, 0, 0, },
|
/* PA */ { 1, ASN_GENERALIZED_TIME, 0, 0, 0, },
|
||||||
/* responses */
|
/* responses */
|
||||||
@@ -36878,6 +36892,7 @@ enum {
|
|||||||
OCSPRESPDATAASN_IDX_VER,
|
OCSPRESPDATAASN_IDX_VER,
|
||||||
OCSPRESPDATAASN_IDX_BYNAME,
|
OCSPRESPDATAASN_IDX_BYNAME,
|
||||||
OCSPRESPDATAASN_IDX_BYKEY,
|
OCSPRESPDATAASN_IDX_BYKEY,
|
||||||
|
OCSPRESPDATAASN_IDX_BYKEY_OCT,
|
||||||
OCSPRESPDATAASN_IDX_PA,
|
OCSPRESPDATAASN_IDX_PA,
|
||||||
OCSPRESPDATAASN_IDX_RESP,
|
OCSPRESPDATAASN_IDX_RESP,
|
||||||
OCSPRESPDATAASN_IDX_RESPEXT,
|
OCSPRESPDATAASN_IDX_RESPEXT,
|
||||||
@@ -36988,6 +37003,7 @@ static int DecodeResponseData(byte* source, word32* ioIndex,
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
byte version;
|
byte version;
|
||||||
word32 dateSz = 0;
|
word32 dateSz = 0;
|
||||||
|
word32 responderByKeySz = KEYID_SIZE;
|
||||||
word32 idx = *ioIndex;
|
word32 idx = *ioIndex;
|
||||||
OcspEntry* single = NULL;
|
OcspEntry* single = NULL;
|
||||||
|
|
||||||
@@ -37006,6 +37022,8 @@ static int DecodeResponseData(byte* source, word32* ioIndex,
|
|||||||
GetASN_Int8Bit(&dataASN[OCSPRESPDATAASN_IDX_VER], &version);
|
GetASN_Int8Bit(&dataASN[OCSPRESPDATAASN_IDX_VER], &version);
|
||||||
GetASN_Buffer(&dataASN[OCSPRESPDATAASN_IDX_PA], resp->producedDate,
|
GetASN_Buffer(&dataASN[OCSPRESPDATAASN_IDX_PA], resp->producedDate,
|
||||||
&dateSz);
|
&dateSz);
|
||||||
|
GetASN_Buffer(&dataASN[OCSPRESPDATAASN_IDX_BYKEY_OCT],
|
||||||
|
resp->responderId.keyHash, &responderByKeySz);
|
||||||
/* Decode the ResponseData. */
|
/* Decode the ResponseData. */
|
||||||
ret = GetASN_Items(ocspRespDataASN, dataASN, ocspRespDataASN_Length,
|
ret = GetASN_Items(ocspRespDataASN, dataASN, ocspRespDataASN_Length,
|
||||||
1, source, ioIndex, size);
|
1, source, ioIndex, size);
|
||||||
@@ -37023,7 +37041,22 @@ static int DecodeResponseData(byte* source, word32* ioIndex,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/* TODO: use byName/byKey fields. */
|
if (dataASN[OCSPRESPDATAASN_IDX_BYNAME].tag != 0) {
|
||||||
|
resp->responderIdType = OCSP_RESPONDER_ID_NAME;
|
||||||
|
ret = CalcHashId_ex(
|
||||||
|
dataASN[OCSPRESPDATAASN_IDX_BYNAME].data.ref.data,
|
||||||
|
dataASN[OCSPRESPDATAASN_IDX_BYNAME].data.ref.length,
|
||||||
|
resp->responderId.nameHash, WC_SHA);
|
||||||
|
} else {
|
||||||
|
resp->responderIdType = OCSP_RESPONDER_ID_KEY;
|
||||||
|
if (dataASN[OCSPRESPDATAASN_IDX_BYKEY_OCT].length != KEYID_SIZE) {
|
||||||
|
ret = ASN_PARSE_E;
|
||||||
|
} else {
|
||||||
|
resp->responderIdType = OCSP_RESPONDER_ID_KEY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ret == 0) {
|
||||||
/* Store size of response. */
|
/* Store size of response. */
|
||||||
resp->responseSz = *ioIndex - idx;
|
resp->responseSz = *ioIndex - idx;
|
||||||
/* Store date format/tag. */
|
/* Store date format/tag. */
|
||||||
@@ -37166,8 +37199,133 @@ enum {
|
|||||||
#define ocspBasicRespASN_Length (sizeof(ocspBasicRespASN) / sizeof(ASNItem))
|
#define ocspBasicRespASN_Length (sizeof(ocspBasicRespASN) / sizeof(ASNItem))
|
||||||
#endif /* WOLFSSL_ASN_TEMPLATE */
|
#endif /* WOLFSSL_ASN_TEMPLATE */
|
||||||
|
|
||||||
|
static int OcspRespIdMatch(OcspResponse *resp, const byte *NameHash,
|
||||||
|
const byte *keyHash)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
|
||||||
|
static int OcspRespCheck(OcspResponse *resp, Signer *responder)
|
||||||
|
{
|
||||||
|
OcspEntry *s;
|
||||||
|
|
||||||
|
s = resp->single;
|
||||||
|
if (s == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* singles responses must have the same issuer */
|
||||||
|
for (; s != NULL; s = s->next) {
|
||||||
|
if (XMEMCMP(s->issuerKeyHash, responder->subjectKeyHash,
|
||||||
|
KEYID_SIZE) != 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static Signer *OcspFindSigner(OcspResponse *resp, WOLFSSL_CERT_MANAGER *cm)
|
||||||
|
{
|
||||||
|
Signer *s;
|
||||||
|
|
||||||
|
if (cm == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (resp->responderIdType == OCSP_RESPONDER_ID_NAME) {
|
||||||
|
#ifndef NO_SKID
|
||||||
|
s = GetCAByName(cm, resp->responderId.nameHash);
|
||||||
|
#else
|
||||||
|
s = GetCA(cm, resp->responderId.nameHash);
|
||||||
|
#endif
|
||||||
|
if (s)
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
s = GetCAByKeyHash(cm, resp->responderId.keyHash);
|
||||||
|
if (s)
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
|
||||||
|
if (resp->pendingCAs == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (resp->responderIdType == OCSP_RESPONDER_ID_NAME) {
|
||||||
|
s = findSignerByName(resp->pendingCAs, resp->responderId.nameHash);
|
||||||
|
if (s)
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
s = findSignerByKeyHash(resp->pendingCAs, resp->responderId.keyHash);
|
||||||
|
if (s)
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int OcspCheckCert(OcspResponse *resp, int noVerify,
|
||||||
|
int noVerifySignature, WOLFSSL_CERT_MANAGER *cm, void *heap)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
DecodedCert *cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
|
||||||
|
DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
if (cert == NULL)
|
||||||
|
return MEMORY_E;
|
||||||
|
#else
|
||||||
|
DecodedCert cert[1];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
InitDecodedCert(cert, resp->cert, resp->certSz, heap);
|
||||||
|
ret = ParseCertRelative(cert, CERT_TYPE,
|
||||||
|
noVerify ? NO_VERIFY : VERIFY_OCSP_CERT,
|
||||||
|
cm, resp->pendingCAs);
|
||||||
|
if (ret < 0) {
|
||||||
|
WOLFSSL_MSG("\tOCSP Responder certificate parsing failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == 0 && OcspRespIdMatch(resp, cert->subjectHash, cert->subjectKeyHash) == 0) {
|
||||||
|
WOLFSSL_MSG("\tInternal check doesn't match responder ID, ignoring\n");
|
||||||
|
ret = BAD_OCSP_RESPONDER;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
|
||||||
|
if (ret == 0 && !noVerify) {
|
||||||
|
ret = CheckOcspResponder(resp, cert, cm);
|
||||||
|
if (ret < 0) {
|
||||||
|
WOLFSSL_MSG("\tOCSP Responder certificate issuer check failed");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_NO_OCSP_ISSUER_CHECK */
|
||||||
|
if (ret == 0 && !noVerifySignature) {
|
||||||
|
ret = ConfirmSignature(
|
||||||
|
&cert->sigCtx,
|
||||||
|
resp->response, resp->responseSz,
|
||||||
|
cert->publicKey, cert->pubKeySize, cert->keyOID,
|
||||||
|
resp->sig, resp->sigSz, resp->sigOID, resp->sigParams,
|
||||||
|
resp->sigParamsSz, NULL);
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
FreeDecodedCert(cert);
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
if (cert != NULL) {
|
||||||
|
XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
|
static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
|
||||||
OcspResponse* resp, word32 size, void* cm, void* heap, int noVerify)
|
OcspResponse* resp, word32 size, void* cm, void* heap, int noVerify,
|
||||||
|
int noVerifySignature)
|
||||||
{
|
{
|
||||||
#ifndef WOLFSSL_ASN_TEMPLATE
|
#ifndef WOLFSSL_ASN_TEMPLATE
|
||||||
int length;
|
int length;
|
||||||
@@ -37267,12 +37425,8 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
WOLFSSL_MSG("\tOCSP Responder key usage check failed");
|
WOLFSSL_MSG("\tOCSP Responder key usage check failed");
|
||||||
#ifdef OPENSSL_EXTRA
|
|
||||||
resp->verifyError = OCSP_BAD_ISSUER;
|
|
||||||
#else
|
|
||||||
ret = BAD_OCSP_RESPONDER;
|
ret = BAD_OCSP_RESPONDER;
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -37341,8 +37495,6 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
|
|||||||
DECL_ASNGETDATA(dataASN, ocspBasicRespASN_Length);
|
DECL_ASNGETDATA(dataASN, ocspBasicRespASN_Length);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
word32 idx = *ioIndex;
|
word32 idx = *ioIndex;
|
||||||
const byte* sigParams = NULL;
|
|
||||||
word32 sigParamsSz = 0;
|
|
||||||
#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
|
#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
DecodedCert* cert = NULL;
|
DecodedCert* cert = NULL;
|
||||||
@@ -37375,10 +37527,10 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
|
|||||||
}
|
}
|
||||||
#ifdef WC_RSA_PSS
|
#ifdef WC_RSA_PSS
|
||||||
if (ret == 0 && (dataASN[OCSPBASICRESPASN_IDX_SIGNATURE_PARAMS].tag != 0)) {
|
if (ret == 0 && (dataASN[OCSPBASICRESPASN_IDX_SIGNATURE_PARAMS].tag != 0)) {
|
||||||
sigParams = GetASNItem_Addr(
|
resp->sigParams = GetASNItem_Addr(
|
||||||
dataASN[OCSPBASICRESPASN_IDX_SIGNATURE_PARAMS],
|
dataASN[OCSPBASICRESPASN_IDX_SIGNATURE_PARAMS],
|
||||||
source);
|
source);
|
||||||
sigParamsSz =
|
resp->sigParamsSz =
|
||||||
GetASNItem_Length(dataASN[OCSPBASICRESPASN_IDX_SIGNATURE_PARAMS],
|
GetASNItem_Length(dataASN[OCSPBASICRESPASN_IDX_SIGNATURE_PARAMS],
|
||||||
source);
|
source);
|
||||||
}
|
}
|
||||||
@@ -37389,6 +37541,7 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
|
|||||||
GetASN_GetRef(&dataASN[OCSPBASICRESPASN_IDX_SIGNATURE], &resp->sig,
|
GetASN_GetRef(&dataASN[OCSPBASICRESPASN_IDX_SIGNATURE], &resp->sig,
|
||||||
&resp->sigSz);
|
&resp->sigSz);
|
||||||
}
|
}
|
||||||
|
resp->certSz = 0;
|
||||||
#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
|
#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
|
||||||
if ((ret == 0) &&
|
if ((ret == 0) &&
|
||||||
(dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data != NULL)) {
|
(dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data != NULL)) {
|
||||||
@@ -37396,73 +37549,34 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
|
|||||||
/* Store reference to certificate BER data. */
|
/* Store reference to certificate BER data. */
|
||||||
GetASN_GetRef(&dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ], &resp->cert,
|
GetASN_GetRef(&dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ], &resp->cert,
|
||||||
&resp->certSz);
|
&resp->certSz);
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate a certificate object to decode cert into. */
|
if ((ret == 0) && resp->certSz > 0) {
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
ret = OcspCheckCert(resp, noVerify, noVerifySignature,
|
||||||
cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), heap,
|
(WOLFSSL_CERT_MANAGER*)cm, heap);
|
||||||
DYNAMIC_TYPE_TMP_BUFFER);
|
if (ret == 0) {
|
||||||
if (cert == NULL) {
|
goto out;
|
||||||
ret = MEMORY_E;
|
|
||||||
}
|
}
|
||||||
|
ret = 0; /* try to verify the OCSP response with CA certs */
|
||||||
}
|
}
|
||||||
if ((ret == 0) &&
|
#endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
|
||||||
(dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data != NULL)) {
|
/* try to verify using cm certs */
|
||||||
#endif
|
if (ret == 0 && !noVerifySignature)
|
||||||
/* Initialize the certificate object. */
|
{
|
||||||
InitDecodedCert(cert, resp->cert, resp->certSz, heap);
|
ca = OcspFindSigner(resp, (WOLFSSL_CERT_MANAGER*)cm);
|
||||||
certInit = 1;
|
if (ca == NULL)
|
||||||
/* Parse the certificate and don't verify if we don't have access to
|
ret = ASN_NO_SIGNER_E;
|
||||||
* Cert Manager. */
|
|
||||||
ret = ParseCertRelative(cert, CERT_TYPE, noVerify ? NO_VERIFY : VERIFY,
|
|
||||||
cm, resp->pendingCAs);
|
|
||||||
if (ret < 0) {
|
|
||||||
WOLFSSL_MSG("\tOCSP Responder certificate parsing failed");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
|
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
|
||||||
if ((ret == 0) &&
|
if (ret == 0 && !noVerifySignature) {
|
||||||
(dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data != NULL) &&
|
if (OcspRespCheck(resp, ca) != 0) {
|
||||||
!noVerify) {
|
ret = BAD_OCSP_RESPONDER;
|
||||||
ret = CheckOcspResponder(resp, cert, cm);
|
|
||||||
}
|
|
||||||
#endif /* WOLFSSL_NO_OCSP_ISSUER_CHECK */
|
|
||||||
if ((ret == 0) &&
|
|
||||||
(dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data != NULL)) {
|
|
||||||
/* TODO: ConfirmSignature is blocking here */
|
|
||||||
/* Check the signature of the response. */
|
|
||||||
ret = ConfirmSignature(&cert->sigCtx, resp->response, resp->responseSz,
|
|
||||||
cert->publicKey, cert->pubKeySize, cert->keyOID, resp->sig,
|
|
||||||
resp->sigSz, resp->sigOID, NULL, 0, NULL);
|
|
||||||
if (ret != 0) {
|
|
||||||
WOLFSSL_MSG("\tOCSP Confirm signature failed");
|
|
||||||
ret = ASN_OCSP_CONFIRM_E;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((ret == 0) &&
|
#endif
|
||||||
(dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data == NULL))
|
if (ret == 0 && !noVerifySignature) {
|
||||||
#else
|
|
||||||
if (ret == 0)
|
|
||||||
#endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
|
|
||||||
{
|
|
||||||
Signer* ca;
|
|
||||||
int sigValid = -1;
|
int sigValid = -1;
|
||||||
|
|
||||||
/* Response didn't have a certificate - lookup CA. */
|
|
||||||
#ifndef NO_SKID
|
|
||||||
ca = GetCAByKeyHash(cm, resp->single->issuerKeyHash);
|
|
||||||
#else
|
|
||||||
ca = GetCA(cm, resp->single->issuerHash);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
|
|
||||||
if (ca == NULL && resp->pendingCAs != NULL) {
|
|
||||||
ca = findSignerByName(resp->pendingCAs, resp->single->issuerHash);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (ca) {
|
|
||||||
SignatureCtx sigCtx;
|
SignatureCtx sigCtx;
|
||||||
|
|
||||||
/* Initialize he signature context. */
|
/* Initialize he signature context. */
|
||||||
InitSignatureCtx(&sigCtx, heap, INVALID_DEVID);
|
InitSignatureCtx(&sigCtx, heap, INVALID_DEVID);
|
||||||
|
|
||||||
@@ -37470,16 +37584,14 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
|
|||||||
/* Check the signature of the response CA public key. */
|
/* Check the signature of the response CA public key. */
|
||||||
sigValid = ConfirmSignature(&sigCtx, resp->response,
|
sigValid = ConfirmSignature(&sigCtx, resp->response,
|
||||||
resp->responseSz, ca->publicKey, ca->pubKeySize, ca->keyOID,
|
resp->responseSz, ca->publicKey, ca->pubKeySize, ca->keyOID,
|
||||||
resp->sig, resp->sigSz, resp->sigOID, sigParams, sigParamsSz,
|
resp->sig, resp->sigSz, resp->sigOID, resp->sigParams,
|
||||||
NULL);
|
resp->sigParamsSz, NULL);
|
||||||
}
|
if (sigValid != 0) {
|
||||||
if ((ca == NULL) || (sigValid != 0)) {
|
|
||||||
/* Didn't find certificate or signature verificate failed. */
|
|
||||||
WOLFSSL_MSG("\tOCSP Confirm signature failed");
|
WOLFSSL_MSG("\tOCSP Confirm signature failed");
|
||||||
ret = ASN_OCSP_CONFIRM_E;
|
ret = ASN_OCSP_CONFIRM_E;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/* Update the position to after response data. */
|
/* Update the position to after response data. */
|
||||||
*ioIndex = idx;
|
*ioIndex = idx;
|
||||||
@@ -37518,6 +37630,9 @@ void InitOcspResponse(OcspResponse* resp, OcspEntry* single, CertStatus* status,
|
|||||||
resp->maxIdx = inSz;
|
resp->maxIdx = inSz;
|
||||||
resp->heap = heap;
|
resp->heap = heap;
|
||||||
resp->pendingCAs = NULL;
|
resp->pendingCAs = NULL;
|
||||||
|
resp->sigParams = NULL;
|
||||||
|
resp->sigParamsSz = 0;
|
||||||
|
resp->responderIdType = OCSP_RESPONDER_ID_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreeOcspResponse(OcspResponse* resp)
|
void FreeOcspResponse(OcspResponse* resp)
|
||||||
@@ -37571,7 +37686,8 @@ enum {
|
|||||||
#define ocspResponseASN_Length (sizeof(ocspResponseASN) / sizeof(ASNItem))
|
#define ocspResponseASN_Length (sizeof(ocspResponseASN) / sizeof(ASNItem))
|
||||||
#endif /* WOLFSSL_ASN_TEMPLATE */
|
#endif /* WOLFSSL_ASN_TEMPLATE */
|
||||||
|
|
||||||
int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap, int noVerify)
|
int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap,
|
||||||
|
int noVerifyCert, int noVerifySignature)
|
||||||
{
|
{
|
||||||
#ifndef WOLFSSL_ASN_TEMPLATE
|
#ifndef WOLFSSL_ASN_TEMPLATE
|
||||||
int ret;
|
int ret;
|
||||||
@@ -37640,7 +37756,7 @@ int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap, int noVerify)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = DecodeBasicOcspResponse(source, &idx, resp, size, cm, heap, noVerify);
|
ret = DecodeBasicOcspResponse(source, &idx, resp, size, cm, heap, noVerify, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
WOLFSSL_LEAVE("OcspResponseDecode", ret);
|
WOLFSSL_LEAVE("OcspResponseDecode", ret);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -37680,7 +37796,7 @@ int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap, int noVerify)
|
|||||||
idx = 0;
|
idx = 0;
|
||||||
/* Decode BasicOCSPResponse. */
|
/* Decode BasicOCSPResponse. */
|
||||||
ret = DecodeBasicOcspResponse(basic, &idx, resp, basicSz, cm, heap,
|
ret = DecodeBasicOcspResponse(basic, &idx, resp, basicSz, cm, heap,
|
||||||
noVerify);
|
noVerifyCert, noVerifySignature);
|
||||||
}
|
}
|
||||||
/* Only support BasicOCSPResponse. */
|
/* Only support BasicOCSPResponse. */
|
||||||
else {
|
else {
|
||||||
|
@@ -2352,7 +2352,12 @@ WOLFSSL_LOCAL int CheckCertSignaturePubKey(const byte* cert, word32 certSz,
|
|||||||
WOLFSSL_LOCAL int wc_CertGetPubKey(const byte* cert, word32 certSz,
|
WOLFSSL_LOCAL int wc_CertGetPubKey(const byte* cert, word32 certSz,
|
||||||
const unsigned char** pubKey, word32* pubKeySz);
|
const unsigned char** pubKey, word32* pubKeySz);
|
||||||
#endif
|
#endif
|
||||||
|
WOLFSSL_LOCAL int ConfirmSignature(SignatureCtx* sigCtx,
|
||||||
|
const byte* buf, word32 bufSz,
|
||||||
|
const byte* key, word32 keySz, word32 keyOID,
|
||||||
|
const byte* sig, word32 sigSz, word32 sigOID,
|
||||||
|
const byte* sigParams, word32 sigParamsSz,
|
||||||
|
byte* rsaKeyIdx);
|
||||||
#ifdef WOLFSSL_CERT_REQ
|
#ifdef WOLFSSL_CERT_REQ
|
||||||
WOLFSSL_LOCAL int CheckCSRSignaturePubKey(const byte* cert, word32 certSz,
|
WOLFSSL_LOCAL int CheckCSRSignaturePubKey(const byte* cert, word32 certSz,
|
||||||
void* heap, const byte* pubKey, word32 pubKeySz, int pubKeyOID);
|
void* heap, const byte* pubKey, word32 pubKeySz, int pubKeyOID);
|
||||||
@@ -2369,6 +2374,7 @@ WOLFSSL_LOCAL int TryDecodeRPKToKey(DecodedCert* cert);
|
|||||||
WOLFSSL_LOCAL int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate);
|
WOLFSSL_LOCAL int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate);
|
||||||
|
|
||||||
WOLFSSL_LOCAL const byte* OidFromId(word32 id, word32 type, word32* oidSz);
|
WOLFSSL_LOCAL const byte* OidFromId(word32 id, word32 type, word32* oidSz);
|
||||||
|
WOLFSSL_LOCAL Signer* findSignerByKeyHash(Signer *list, byte *hash);
|
||||||
WOLFSSL_LOCAL Signer* findSignerByName(Signer *list, byte *hash);
|
WOLFSSL_LOCAL Signer* findSignerByName(Signer *list, byte *hash);
|
||||||
WOLFSSL_LOCAL int FillSigner(Signer* signer, DecodedCert* cert, int type, DerBuffer *der);
|
WOLFSSL_LOCAL int FillSigner(Signer* signer, DecodedCert* cert, int type, DerBuffer *der);
|
||||||
WOLFSSL_LOCAL Signer* MakeSigner(void* heap);
|
WOLFSSL_LOCAL Signer* MakeSigner(void* heap);
|
||||||
@@ -2726,6 +2732,11 @@ struct OcspEntry
|
|||||||
WC_BITFIELD used:1; /* entry used */
|
WC_BITFIELD used:1; /* entry used */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum responderIdType {
|
||||||
|
OCSP_RESPONDER_ID_INVALID = 0,
|
||||||
|
OCSP_RESPONDER_ID_NAME = 1,
|
||||||
|
OCSP_RESPONDER_ID_KEY = 2,
|
||||||
|
};
|
||||||
/* TODO: Long-term, it would be helpful if we made this struct and other OCSP
|
/* TODO: Long-term, it would be helpful if we made this struct and other OCSP
|
||||||
structs conform to the ASN spec as described in RFC 6960. It will help
|
structs conform to the ASN spec as described in RFC 6960. It will help
|
||||||
with readability and with implementing OpenSSL compatibility API
|
with readability and with implementing OpenSSL compatibility API
|
||||||
@@ -2737,6 +2748,12 @@ struct OcspResponse {
|
|||||||
byte* response; /* Pointer to beginning of OCSP Response */
|
byte* response; /* Pointer to beginning of OCSP Response */
|
||||||
word32 responseSz; /* length of the OCSP Response */
|
word32 responseSz; /* length of the OCSP Response */
|
||||||
|
|
||||||
|
enum responderIdType responderIdType;
|
||||||
|
union {
|
||||||
|
byte keyHash[KEYID_SIZE];
|
||||||
|
byte nameHash[KEYID_SIZE];
|
||||||
|
} responderId ;
|
||||||
|
|
||||||
byte producedDate[MAX_DATE_SIZE];
|
byte producedDate[MAX_DATE_SIZE];
|
||||||
/* Date at which this response was signed */
|
/* Date at which this response was signed */
|
||||||
byte producedDateFormat; /* format of the producedDate */
|
byte producedDateFormat; /* format of the producedDate */
|
||||||
@@ -2748,6 +2765,9 @@ struct OcspResponse {
|
|||||||
word32 sigSz; /* Length in octets for the sig */
|
word32 sigSz; /* Length in octets for the sig */
|
||||||
word32 sigOID; /* OID for hash used for sig */
|
word32 sigOID; /* OID for hash used for sig */
|
||||||
|
|
||||||
|
byte* sigParams;
|
||||||
|
word32 sigParamsSz;
|
||||||
|
|
||||||
OcspEntry* single; /* chain of OCSP single responses */
|
OcspEntry* single; /* chain of OCSP single responses */
|
||||||
|
|
||||||
byte* nonce; /* pointer to nonce inside ASN.1 response */
|
byte* nonce; /* pointer to nonce inside ASN.1 response */
|
||||||
@@ -2756,9 +2776,6 @@ struct OcspResponse {
|
|||||||
byte* source; /* pointer to source buffer, not owned */
|
byte* source; /* pointer to source buffer, not owned */
|
||||||
word32 maxIdx; /* max offset based on init size */
|
word32 maxIdx; /* max offset based on init size */
|
||||||
Signer* pendingCAs;
|
Signer* pendingCAs;
|
||||||
#ifdef OPENSSL_EXTRA
|
|
||||||
int verifyError;
|
|
||||||
#endif
|
|
||||||
void* heap;
|
void* heap;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2788,7 +2805,7 @@ WOLFSSL_LOCAL void InitOcspResponse(OcspResponse* resp, OcspEntry* single,
|
|||||||
CertStatus* status, byte* source, word32 inSz, void* heap);
|
CertStatus* status, byte* source, word32 inSz, void* heap);
|
||||||
WOLFSSL_LOCAL void FreeOcspResponse(OcspResponse* resp);
|
WOLFSSL_LOCAL void FreeOcspResponse(OcspResponse* resp);
|
||||||
WOLFSSL_LOCAL int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap,
|
WOLFSSL_LOCAL int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap,
|
||||||
int noVerify);
|
int noVerifyCert, int noVerifySignature);
|
||||||
|
|
||||||
WOLFSSL_LOCAL int InitOcspRequest(OcspRequest* req, DecodedCert* cert,
|
WOLFSSL_LOCAL int InitOcspRequest(OcspRequest* req, DecodedCert* cert,
|
||||||
byte useNonce, void* heap);
|
byte useNonce, void* heap);
|
||||||
|
Reference in New Issue
Block a user