forked from wolfSSL/wolfssl
Merge pull request #3389 from tmael/ocsp_status
Process multiple OCSP responses
This commit is contained in:
@@ -9844,7 +9844,7 @@ static int ProcessCSR(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
InitOcspResponse(response, status, input +*inOutIdx, status_length);
|
InitOcspResponse(response, status, input +*inOutIdx, status_length, ssl->heap);
|
||||||
|
|
||||||
if (OcspResponseDecode(response, ssl->ctx->cm, ssl->heap, 0) != 0)
|
if (OcspResponseDecode(response, ssl->ctx->cm, ssl->heap, 0) != 0)
|
||||||
ret = BAD_CERTIFICATE_STATUS_ERROR;
|
ret = BAD_CERTIFICATE_STATUS_ERROR;
|
||||||
@@ -9864,6 +9864,7 @@ static int ProcessCSR(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
|
|
||||||
*inOutIdx += status_length;
|
*inOutIdx += status_length;
|
||||||
|
|
||||||
|
FreeOcspResponse(response);
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
XFREE(status, ssl->heap, DYNAMIC_TYPE_OCSP_STATUS);
|
XFREE(status, ssl->heap, DYNAMIC_TYPE_OCSP_STATUS);
|
||||||
XFREE(response, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST);
|
XFREE(response, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST);
|
||||||
@@ -11841,7 +11842,7 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
|
|
||||||
if (status_length) {
|
if (status_length) {
|
||||||
InitOcspResponse(response, status, input +*inOutIdx,
|
InitOcspResponse(response, status, input +*inOutIdx,
|
||||||
status_length);
|
status_length, ssl->heap);
|
||||||
|
|
||||||
if ((OcspResponseDecode(response, ssl->ctx->cm, ssl->heap,
|
if ((OcspResponseDecode(response, ssl->ctx->cm, ssl->heap,
|
||||||
0) != 0)
|
0) != 0)
|
||||||
@@ -11860,6 +11861,7 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
else if (idx == 1) /* server cert must be OK */
|
else if (idx == 1) /* server cert must be OK */
|
||||||
ret = BAD_CERTIFICATE_STATUS_ERROR;
|
ret = BAD_CERTIFICATE_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
FreeOcspResponse(response);
|
||||||
|
|
||||||
*inOutIdx += status_length;
|
*inOutIdx += status_length;
|
||||||
list_length -= status_length;
|
list_length -= status_length;
|
||||||
|
@@ -296,7 +296,7 @@ WOLFSSL_LOCAL int CheckOcspResponse(WOLFSSL_OCSP *ocsp, byte *response, int resp
|
|||||||
#endif
|
#endif
|
||||||
XMEMSET(newStatus, 0, sizeof(CertStatus));
|
XMEMSET(newStatus, 0, sizeof(CertStatus));
|
||||||
|
|
||||||
InitOcspResponse(ocspResponse, newStatus, response, responseSz);
|
InitOcspResponse(ocspResponse, newStatus, response, responseSz, ocsp->cm->heap);
|
||||||
ret = OcspResponseDecode(ocspResponse, ocsp->cm, ocsp->cm->heap, 0);
|
ret = OcspResponseDecode(ocspResponse, ocsp->cm, ocsp->cm->heap, 0);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
ocsp->error = ret;
|
ocsp->error = ret;
|
||||||
@@ -378,6 +378,7 @@ end:
|
|||||||
ret = OCSP_LOOKUP_FAIL;
|
ret = OCSP_LOOKUP_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FreeOcspResponse(ocspResponse);
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
XFREE(newStatus, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(newStatus, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
@@ -8887,6 +8887,7 @@ static int DecodeCertExtensions(DecodedCert* cert)
|
|||||||
case OCSP_NOCHECK_OID:
|
case OCSP_NOCHECK_OID:
|
||||||
VERIFY_AND_SET_OID(cert->ocspNoCheckSet);
|
VERIFY_AND_SET_OID(cert->ocspNoCheckSet);
|
||||||
ret = GetASNNull(input, &idx, sz);
|
ret = GetASNNull(input, &idx, sz);
|
||||||
|
length = 0; /* idx is already incremented, reset length to 0 */
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
break;
|
break;
|
||||||
@@ -16533,25 +16534,18 @@ static int GetEnumerated(const byte* input, word32* inOutIdx, int *value,
|
|||||||
|
|
||||||
|
|
||||||
static int DecodeSingleResponse(byte* source,
|
static int DecodeSingleResponse(byte* source,
|
||||||
word32* ioIndex, OcspResponse* resp, word32 size)
|
word32* ioIndex, OcspResponse* resp, word32 size, int wrapperSz,
|
||||||
|
CertStatus* cs)
|
||||||
{
|
{
|
||||||
word32 idx = *ioIndex, prevIndex, oid, localIdx;
|
word32 idx = *ioIndex, prevIndex, oid, localIdx;
|
||||||
int length, wrapperSz;
|
int length;
|
||||||
CertStatus* cs = resp->status;
|
|
||||||
int ret;
|
int ret;
|
||||||
byte tag;
|
byte tag;
|
||||||
|
|
||||||
WOLFSSL_ENTER("DecodeSingleResponse");
|
WOLFSSL_ENTER("DecodeSingleResponse");
|
||||||
|
|
||||||
/* Outer wrapper of the SEQUENCE OF Single Responses. */
|
|
||||||
if (GetSequence(source, &idx, &wrapperSz, size) < 0)
|
|
||||||
return ASN_PARSE_E;
|
|
||||||
|
|
||||||
prevIndex = idx;
|
prevIndex = idx;
|
||||||
|
|
||||||
/* When making a request, we only request one status on one certificate
|
|
||||||
* at a time. There should only be one SingleResponse */
|
|
||||||
|
|
||||||
/* Wrapper around the Single Response */
|
/* Wrapper around the Single Response */
|
||||||
if (GetSequence(source, &idx, &length, size) < 0)
|
if (GetSequence(source, &idx, &length, size) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
@@ -16627,7 +16621,6 @@ static int DecodeSingleResponse(byte* source,
|
|||||||
|
|
||||||
/* The following items are optional. Only check for them if there is more
|
/* The following items are optional. Only check for them if there is more
|
||||||
* unprocessed data in the singleResponse wrapper. */
|
* unprocessed data in the singleResponse wrapper. */
|
||||||
|
|
||||||
localIdx = idx;
|
localIdx = idx;
|
||||||
if (((int)(idx - prevIndex) < wrapperSz) &&
|
if (((int)(idx - prevIndex) < wrapperSz) &&
|
||||||
GetASNTag(source, &localIdx, &tag, size) == 0 &&
|
GetASNTag(source, &localIdx, &tag, size) == 0 &&
|
||||||
@@ -16659,17 +16652,6 @@ static int DecodeSingleResponse(byte* source,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
localIdx = idx;
|
|
||||||
if (((int)(idx - prevIndex) < wrapperSz) &&
|
|
||||||
GetASNTag(source, &localIdx, &tag, size) == 0 &&
|
|
||||||
tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
|
|
||||||
{
|
|
||||||
idx++;
|
|
||||||
if (GetLength(source, &idx, &length, size) < 0)
|
|
||||||
return ASN_PARSE_E;
|
|
||||||
idx += length;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ioIndex = idx;
|
*ioIndex = idx;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -16762,6 +16744,8 @@ static int DecodeResponseData(byte* source,
|
|||||||
int version;
|
int version;
|
||||||
int ret;
|
int ret;
|
||||||
byte tag;
|
byte tag;
|
||||||
|
int wrapperSz;
|
||||||
|
CertStatus* cs;
|
||||||
|
|
||||||
WOLFSSL_ENTER("DecodeResponseData");
|
WOLFSSL_ENTER("DecodeResponseData");
|
||||||
|
|
||||||
@@ -16803,8 +16787,27 @@ static int DecodeResponseData(byte* source,
|
|||||||
&resp->producedDateFormat, size) < 0)
|
&resp->producedDateFormat, size) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
if ((ret = DecodeSingleResponse(source, &idx, resp, size)) < 0)
|
/* Outer wrapper of the SEQUENCE OF Single Responses. */
|
||||||
return ret; /* ASN_PARSE_E, ASN_BEFORE_DATE_E, ASN_AFTER_DATE_E */
|
if (GetSequence(source, &idx, &wrapperSz, size) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
|
localIdx = idx;
|
||||||
|
cs = resp->status;
|
||||||
|
while (idx - localIdx < (word32)wrapperSz) {
|
||||||
|
ret = DecodeSingleResponse(source, &idx, resp, size, wrapperSz, cs);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret; /* ASN_PARSE_E, ASN_BEFORE_DATE_E, ASN_AFTER_DATE_E */
|
||||||
|
if (idx - localIdx < (word32)wrapperSz) {
|
||||||
|
cs->next = (CertStatus*)XMALLOC(sizeof(CertStatus), resp->heap,
|
||||||
|
DYNAMIC_TYPE_OCSP_STATUS);
|
||||||
|
if (cs->next == NULL) {
|
||||||
|
return MEMORY_E;
|
||||||
|
}
|
||||||
|
cs = cs->next;
|
||||||
|
XMEMSET(cs, 0, sizeof(CertStatus));
|
||||||
|
cs->isDynamic = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check the length of the ResponseData against the current index to
|
* Check the length of the ResponseData against the current index to
|
||||||
@@ -16977,7 +16980,7 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
|
|||||||
|
|
||||||
|
|
||||||
void InitOcspResponse(OcspResponse* resp, CertStatus* status,
|
void InitOcspResponse(OcspResponse* resp, CertStatus* status,
|
||||||
byte* source, word32 inSz)
|
byte* source, word32 inSz, void* heap)
|
||||||
{
|
{
|
||||||
WOLFSSL_ENTER("InitOcspResponse");
|
WOLFSSL_ENTER("InitOcspResponse");
|
||||||
|
|
||||||
@@ -16988,6 +16991,17 @@ void InitOcspResponse(OcspResponse* resp, CertStatus* status,
|
|||||||
resp->status = status;
|
resp->status = status;
|
||||||
resp->source = source;
|
resp->source = source;
|
||||||
resp->maxIdx = inSz;
|
resp->maxIdx = inSz;
|
||||||
|
resp->heap = heap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreeOcspResponse(OcspResponse* resp)
|
||||||
|
{
|
||||||
|
CertStatus *status, *next;
|
||||||
|
for (status = resp->status; status; status = next) {
|
||||||
|
next = status->next;
|
||||||
|
if (status->isDynamic)
|
||||||
|
XFREE(status, resp->heap, DYNAMIC_TYPE_OCSP_STATUS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -17262,6 +17276,7 @@ void FreeOcspRequest(OcspRequest* req)
|
|||||||
int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)
|
int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)
|
||||||
{
|
{
|
||||||
int cmp;
|
int cmp;
|
||||||
|
CertStatus *status, *next, *prev = NULL, *top;
|
||||||
|
|
||||||
WOLFSSL_ENTER("CompareOcspReqResp");
|
WOLFSSL_ENTER("CompareOcspReqResp");
|
||||||
|
|
||||||
@@ -17307,13 +17322,27 @@ int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)
|
|||||||
return cmp;
|
return cmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmp = req->serialSz - resp->status->serialSz;
|
/* match based on found status and return */
|
||||||
if (cmp != 0) {
|
for (status = resp->status; status; status = next) {
|
||||||
WOLFSSL_MSG("\tserialSz mismatch");
|
cmp = req->serialSz - status->serialSz;
|
||||||
return cmp;
|
if (cmp == 0) {
|
||||||
|
cmp = XMEMCMP(req->serial, status->serial, req->serialSz);
|
||||||
|
if (cmp == 0) {
|
||||||
|
/* match found */
|
||||||
|
if (resp->status != status && prev) {
|
||||||
|
/* move to top of list */
|
||||||
|
top = resp->status;
|
||||||
|
resp->status = status;
|
||||||
|
prev->next = status->next;
|
||||||
|
status->next = top;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
next = status->next;
|
||||||
|
prev = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmp = XMEMCMP(req->serial, resp->status->serial, req->serialSz);
|
|
||||||
if (cmp != 0) {
|
if (cmp != 0) {
|
||||||
WOLFSSL_MSG("\tserial mismatch");
|
WOLFSSL_MSG("\tserial mismatch");
|
||||||
return cmp;
|
return cmp;
|
||||||
|
@@ -1267,8 +1267,10 @@ struct CertStatus {
|
|||||||
|
|
||||||
byte* rawOcspResponse;
|
byte* rawOcspResponse;
|
||||||
word32 rawOcspResponseSz;
|
word32 rawOcspResponseSz;
|
||||||
};
|
|
||||||
|
|
||||||
|
/* option bits - using 32-bit for alignment */
|
||||||
|
word32 isDynamic:1; /* was allocated cert status */
|
||||||
|
};
|
||||||
|
|
||||||
struct OcspResponse {
|
struct OcspResponse {
|
||||||
int responseStatus; /* return code from Responder */
|
int responseStatus; /* return code from Responder */
|
||||||
@@ -1300,6 +1302,7 @@ struct OcspResponse {
|
|||||||
#ifdef OPENSSL_EXTRA
|
#ifdef OPENSSL_EXTRA
|
||||||
int verifyError;
|
int verifyError;
|
||||||
#endif
|
#endif
|
||||||
|
void* heap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1337,7 +1340,8 @@ struct OcspEntry
|
|||||||
int totalStatus; /* number on list */
|
int totalStatus; /* number on list */
|
||||||
};
|
};
|
||||||
|
|
||||||
WOLFSSL_LOCAL void InitOcspResponse(OcspResponse*, CertStatus*, byte*, word32);
|
WOLFSSL_LOCAL void InitOcspResponse(OcspResponse*, CertStatus*, byte*, word32, void*);
|
||||||
|
WOLFSSL_LOCAL void FreeOcspResponse(OcspResponse*);
|
||||||
WOLFSSL_LOCAL int OcspResponseDecode(OcspResponse*, void*, void* heap, int);
|
WOLFSSL_LOCAL int OcspResponseDecode(OcspResponse*, void*, void* heap, int);
|
||||||
|
|
||||||
WOLFSSL_LOCAL int InitOcspRequest(OcspRequest*, DecodedCert*, byte, void*);
|
WOLFSSL_LOCAL int InitOcspRequest(OcspRequest*, DecodedCert*, byte, void*);
|
||||||
|
Reference in New Issue
Block a user