Skip to content

Commit

Permalink
ocsp: adapt ASN original to new OCSP response refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
rizlik committed Jan 31, 2025
1 parent 93c922f commit f400102
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 115 deletions.
171 changes: 57 additions & 114 deletions wolfcrypt/src/asn.c
Original file line number Diff line number Diff line change
Expand Up @@ -36916,16 +36916,39 @@ static int DecodeResponseData(byte* source, word32* ioIndex,
version = 0;

localIdx = idx;
if (GetASNTag(source, &localIdx, &tag, size) == 0 &&
( tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1) ||
tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2) ))
if (GetASNTag(source, &localIdx, &tag, size) != 0)
return ASN_PARSE_E;

resp->responderIdType = OCSP_RESPONDER_ID_INVALID;
/* parse byName */
if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
{
idx++; /* advance past ASN tag */
if (GetLength(source, &idx, &length, size) < 0)
return ASN_PARSE_E;
/* compute the hash of the name */
resp->responderIdType = OCSP_RESPONDER_ID_NAME;
ret = CalcHashId_ex(source + idx, length, resp->responderId.nameHash, WC_SHA);
if (ret != 0)
return ret;
idx += length;
}
else
else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2))
{
idx++; /* advance past ASN tag */
if (GetLength(source, &idx, &length, size) < 0)
return ASN_PARSE_E;

if (GetOctetString(source, &idx, &length, size) < 0)
return ASN_PARSE_E;

if (length != KEYID_SIZE)
return ASN_PARSE_E;
resp->responderIdType = OCSP_RESPONDER_ID_KEY;
XMEMCPY(resp->responderId.keyHash, source + idx, length);
idx += length;
}
if (resp->responderIdType == OCSP_RESPONDER_ID_INVALID)
return ASN_PARSE_E;

/* save pointer to the producedAt time */
Expand Down Expand Up @@ -37315,8 +37338,6 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
#endif
int ret;
int sigLength;
const byte* sigParams = NULL;
word32 sigParamsSz = 0;
WOLFSSL_ENTER("DecodeBasicOcspResponse");
(void)heap;

Expand All @@ -37340,16 +37361,16 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
else if (resp->sigOID == CTC_RSASSAPSS) {
word32 sz;
int len;
const byte* params;
byte* params;

sz = idx;
params = source + idx;
if (GetSequence(source, &idx, &len, size) < 0)
ret = ASN_PARSE_E;
return ASN_PARSE_E;
if (ret == 0) {
idx += len;
sigParams = params;
sigParamsSz = idx - sz;
resp->sigParams = params;
resp->sigParamsSz = idx - sz;
}
}
#endif
Expand All @@ -37369,120 +37390,52 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
if (idx < end_index)
{
int cert_inited = 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

do {
if (DecodeCerts(source, &idx, resp, size) < 0) {
ret = ASN_PARSE_E;
break;
}

InitDecodedCert(cert, resp->cert, resp->certSz, heap);
cert_inited = 1;

/* Don't verify if we don't have access to Cert Manager. */
ret = ParseCertRelative(cert, CERT_TYPE,
noVerify ? NO_VERIFY : VERIFY_OCSP_CERT,
cm, resp->pendingCAs);
if (ret < 0) {
WOLFSSL_MSG("\tOCSP Responder certificate parsing failed");
break;
}

#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
if ((cert->extExtKeyUsage & EXTKEYUSE_OCSP_SIGN) == 0) {
if (XMEMCMP(cert->subjectHash,
resp->single->issuerHash, OCSP_DIGEST_SIZE) == 0) {
WOLFSSL_MSG("\tOCSP Response signed by issuer");
}
else {
WOLFSSL_MSG("\tOCSP Responder key usage check failed");
ret = BAD_OCSP_RESPONDER;
break;
}
}
#endif

/* ConfirmSignature is blocking here */
ret = ConfirmSignature(
&cert->sigCtx,
resp->response, resp->responseSz,
cert->publicKey, cert->pubKeySize, cert->keyOID,
resp->sig, resp->sigSz, resp->sigOID, sigParams, sigParamsSz,
NULL);

if (ret != 0) {
WOLFSSL_MSG("\tOCSP Confirm signature failed");
ret = ASN_OCSP_CONFIRM_E;
break;
}
} while(0);

if (cert_inited)
FreeDecodedCert(cert);
#ifdef WOLFSSL_SMALL_STACK
XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
if (DecodeCerts(source, &idx, resp, size) < 0)
return ASN_PARSE_E;

if (ret != 0)
return ret;
ret = OcspCheckIntCert(resp, noVerify, noVerifySignature, cm, heap);
if (ret != 0) {
WOLFSSL_MSG("\tOCSP Confirm signature failed");
return ASN_OCSP_CONFIRM_E;
}
}
else
#endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
{
Signer* ca;
int sigValid = -1;
SignatureCtx sigCtx;
if (noVerifySignature)
goto out;
ca = OcspFindSigner(resp, cm);
if (ca == NULL)
return ASN_NO_SIGNER_E;

#ifndef NO_SKID
ca = GetCAByKeyHash(cm, resp->single->issuerKeyHash);
#else
ca = GetCA(cm, resp->single->issuerHash);
#endif
#if defined(HAVE_CERTIFICATE_STATUS_V2)
if (ca == NULL && resp->pendingCAs != NULL) {
ca = findSignerByName(resp->pendingCAs, resp->single->issuerHash);
}
#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
if (OcspRespCheck(resp, ca) != 0)
return BAD_OCSP_RESPONDER;
#endif
if (ca) {
SignatureCtx sigCtx;
InitSignatureCtx(&sigCtx, heap, INVALID_DEVID);
InitSignatureCtx(&sigCtx, heap, INVALID_DEVID);

/* ConfirmSignature is blocking here */
sigValid = ConfirmSignature(&sigCtx, resp->response,
resp->responseSz, ca->publicKey, ca->pubKeySize, ca->keyOID,
resp->sig, resp->sigSz, resp->sigOID, sigParams, sigParamsSz,
NULL);
}
if (ca == NULL || sigValid != 0) {
/* ConfirmSignature is blocking here */
sigValid = ConfirmSignature(&sigCtx, resp->response,
resp->responseSz, ca->publicKey, ca->pubKeySize, ca->keyOID,
resp->sig, resp->sigSz, resp->sigOID, resp->sigParams, resp->sigParamsSz,
NULL);
if (sigValid != 0) {
WOLFSSL_MSG("\tOCSP Confirm signature failed");
return ASN_OCSP_CONFIRM_E;
}

(void)noVerify;
}

out:
*ioIndex = idx;
return 0;
#else
DECL_ASNGETDATA(dataASN, ocspBasicRespASN_Length);
int ret = 0;
word32 idx = *ioIndex;
#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
#ifdef WOLFSSL_SMALL_STACK
DecodedCert* cert = NULL;
#else
DecodedCert cert[1];
#endif
int certInit = 0;
#endif

WOLFSSL_ENTER("DecodeBasicOcspResponse");
(void)heap;
Expand Down Expand Up @@ -37579,17 +37532,6 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
*ioIndex = idx;
}

#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
if (certInit) {
FreeDecodedCert(cert);
}
#ifdef WOLFSSL_SMALL_STACK
if (cert != NULL) {
/* Dispose of certificate object. */
XFREE(cert, heap, DYNAMIC_TYPE_TMP_BUFFER);
}
#endif
#endif
FREE_ASNGETDATA(dataASN, heap);
return ret;
#endif /* WOLFSSL_ASN_TEMPLATE */
Expand Down Expand Up @@ -37734,7 +37676,8 @@ int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap, int noVerifyCer
return ret;
}

ret = DecodeBasicOcspResponse(source, &idx, resp, size, cm, heap, noVerify, 0);
ret = DecodeBasicOcspResponse(source, &idx, resp, size, cm, heap,
noVerifyCert, noVerifySignature);
if (ret < 0) {
WOLFSSL_LEAVE("OcspResponseDecode", ret);
return ret;
Expand Down
3 changes: 2 additions & 1 deletion wolfssl/wolfcrypt/asn.h
Original file line number Diff line number Diff line change
Expand Up @@ -2741,7 +2741,8 @@ struct OcspEntry

enum responderIdType {
OCSP_RESPONDER_ID_NAME = 0,
OCSP_RESPONDER_ID_KEY = 1
OCSP_RESPONDER_ID_KEY = 1,
OCSP_RESPONDER_ID_INVALID = 2
};
/* 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
Expand Down

0 comments on commit f400102

Please sign in to comment.