forked from wolfSSL/wolfssl
Process multiple ocsp responses
This commit is contained in:
@@ -8885,6 +8885,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;
|
||||||
@@ -16546,115 +16547,120 @@ static int DecodeSingleResponse(byte* source,
|
|||||||
|
|
||||||
prevIndex = idx;
|
prevIndex = idx;
|
||||||
|
|
||||||
/* When making a request, we only request one status on one certificate
|
/* wolfSSL only requests one status for one certificate at a time but
|
||||||
* at a time. There should only be one SingleResponse */
|
some OCSP responders can reply with multiple SingleResponse items.
|
||||||
|
Expect to handle one SingleResponse. Otherwise, we can process the
|
||||||
|
responses but only the last entry in the list is verified. */
|
||||||
|
|
||||||
/* Wrapper around the Single Response */
|
while ((idx-prevIndex) < (word32)wrapperSz) {
|
||||||
if (GetSequence(source, &idx, &length, size) < 0)
|
/* Wrapper around the Single Response */
|
||||||
return ASN_PARSE_E;
|
if (GetSequence(source, &idx, &length, size) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
/* Wrapper around the CertID */
|
/* Wrapper around the CertID */
|
||||||
if (GetSequence(source, &idx, &length, size) < 0)
|
if (GetSequence(source, &idx, &length, size) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
/* Skip the hash algorithm */
|
/* Skip the hash algorithm */
|
||||||
if (GetAlgoId(source, &idx, &oid, oidIgnoreType, size) < 0)
|
if (GetAlgoId(source, &idx, &oid, oidIgnoreType, size) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
/* Save reference to the hash of CN */
|
/* Save reference to the hash of CN */
|
||||||
ret = GetOctetString(source, &idx, &length, size);
|
ret = GetOctetString(source, &idx, &length, size);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
resp->issuerHash = source + idx;
|
resp->issuerHash = source + idx;
|
||||||
idx += length;
|
idx += length;
|
||||||
/* Save reference to the hash of the issuer public key */
|
/* Save reference to the hash of the issuer public key */
|
||||||
ret = GetOctetString(source, &idx, &length, size);
|
ret = GetOctetString(source, &idx, &length, size);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
resp->issuerKeyHash = source + idx;
|
resp->issuerKeyHash = source + idx;
|
||||||
idx += length;
|
idx += length;
|
||||||
|
|
||||||
/* Get serial number */
|
/* Get serial number */
|
||||||
if (GetSerialNumber(source, &idx, cs->serial, &cs->serialSz, size) < 0)
|
if (GetSerialNumber(source, &idx, cs->serial, &cs->serialSz, size) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
if ( idx >= size )
|
if ( idx >= size )
|
||||||
return BUFFER_E;
|
return BUFFER_E;
|
||||||
|
|
||||||
/* CertStatus */
|
/* CertStatus */
|
||||||
switch (source[idx++])
|
switch (source[idx++])
|
||||||
{
|
{
|
||||||
case (ASN_CONTEXT_SPECIFIC | CERT_GOOD):
|
case (ASN_CONTEXT_SPECIFIC | CERT_GOOD):
|
||||||
cs->status = CERT_GOOD;
|
cs->status = CERT_GOOD;
|
||||||
|
idx++;
|
||||||
|
break;
|
||||||
|
case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_REVOKED):
|
||||||
|
cs->status = CERT_REVOKED;
|
||||||
|
if (GetLength(source, &idx, &length, size) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
idx += length;
|
||||||
|
break;
|
||||||
|
case (ASN_CONTEXT_SPECIFIC | CERT_UNKNOWN):
|
||||||
|
cs->status = CERT_UNKNOWN;
|
||||||
|
idx++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
|
||||||
|
cs->thisDateAsn = source + idx;
|
||||||
|
localIdx = 0;
|
||||||
|
if (GetDateInfo(cs->thisDateAsn, &localIdx, NULL,
|
||||||
|
(byte*)&cs->thisDateParsed.type,
|
||||||
|
&cs->thisDateParsed.length, size) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
XMEMCPY(cs->thisDateParsed.data,
|
||||||
|
cs->thisDateAsn + localIdx - cs->thisDateParsed.length,
|
||||||
|
cs->thisDateParsed.length);
|
||||||
|
#endif
|
||||||
|
if (GetBasicDate(source, &idx, cs->thisDate,
|
||||||
|
&cs->thisDateFormat, size) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
|
#ifndef NO_ASN_TIME
|
||||||
|
#ifndef WOLFSSL_NO_OCSP_DATE_CHECK
|
||||||
|
if (!XVALIDATE_DATE(cs->thisDate, cs->thisDateFormat, BEFORE))
|
||||||
|
return ASN_BEFORE_DATE_E;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* The following items are optional. Only check for them if there is more
|
||||||
|
* unprocessed data in the singleResponse wrapper. */
|
||||||
|
|
||||||
|
localIdx = idx;
|
||||||
|
if (((int)(idx - prevIndex) < wrapperSz) &&
|
||||||
|
GetASNTag(source, &localIdx, &tag, size) == 0 &&
|
||||||
|
tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
|
||||||
|
{
|
||||||
idx++;
|
idx++;
|
||||||
break;
|
|
||||||
case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_REVOKED):
|
|
||||||
cs->status = CERT_REVOKED;
|
|
||||||
if (GetLength(source, &idx, &length, size) < 0)
|
if (GetLength(source, &idx, &length, size) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
idx += length;
|
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
|
||||||
break;
|
cs->nextDateAsn = source + idx;
|
||||||
case (ASN_CONTEXT_SPECIFIC | CERT_UNKNOWN):
|
localIdx = 0;
|
||||||
cs->status = CERT_UNKNOWN;
|
if (GetDateInfo(cs->nextDateAsn, &localIdx, NULL,
|
||||||
idx++;
|
(byte*)&cs->nextDateParsed.type,
|
||||||
break;
|
&cs->nextDateParsed.length, size) < 0)
|
||||||
default:
|
return ASN_PARSE_E;
|
||||||
return ASN_PARSE_E;
|
XMEMCPY(cs->nextDateParsed.data,
|
||||||
}
|
cs->nextDateAsn + localIdx - cs->nextDateParsed.length,
|
||||||
|
cs->nextDateParsed.length);
|
||||||
|
#endif
|
||||||
|
if (GetBasicDate(source, &idx, cs->nextDate,
|
||||||
|
&cs->nextDateFormat, size) < 0)
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
|
#ifndef NO_ASN_TIME
|
||||||
cs->thisDateAsn = source + idx;
|
#ifndef WOLFSSL_NO_OCSP_DATE_CHECK
|
||||||
localIdx = 0;
|
if (!XVALIDATE_DATE(cs->nextDate, cs->nextDateFormat, AFTER))
|
||||||
if (GetDateInfo(cs->thisDateAsn, &localIdx, NULL,
|
return ASN_AFTER_DATE_E;
|
||||||
(byte*)&cs->thisDateParsed.type,
|
#endif
|
||||||
&cs->thisDateParsed.length, size) < 0)
|
#endif
|
||||||
return ASN_PARSE_E;
|
}
|
||||||
XMEMCPY(cs->thisDateParsed.data,
|
} /* while, process multiple SingleResponse items */
|
||||||
cs->thisDateAsn + localIdx - cs->thisDateParsed.length,
|
|
||||||
cs->thisDateParsed.length);
|
|
||||||
#endif
|
|
||||||
if (GetBasicDate(source, &idx, cs->thisDate,
|
|
||||||
&cs->thisDateFormat, size) < 0)
|
|
||||||
return ASN_PARSE_E;
|
|
||||||
|
|
||||||
#ifndef NO_ASN_TIME
|
|
||||||
#ifndef WOLFSSL_NO_OCSP_DATE_CHECK
|
|
||||||
if (!XVALIDATE_DATE(cs->thisDate, cs->thisDateFormat, BEFORE))
|
|
||||||
return ASN_BEFORE_DATE_E;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The following items are optional. Only check for them if there is more
|
|
||||||
* unprocessed data in the singleResponse wrapper. */
|
|
||||||
|
|
||||||
localIdx = idx;
|
|
||||||
if (((int)(idx - prevIndex) < wrapperSz) &&
|
|
||||||
GetASNTag(source, &localIdx, &tag, size) == 0 &&
|
|
||||||
tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
|
|
||||||
{
|
|
||||||
idx++;
|
|
||||||
if (GetLength(source, &idx, &length, size) < 0)
|
|
||||||
return ASN_PARSE_E;
|
|
||||||
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
|
|
||||||
cs->nextDateAsn = source + idx;
|
|
||||||
localIdx = 0;
|
|
||||||
if (GetDateInfo(cs->nextDateAsn, &localIdx, NULL,
|
|
||||||
(byte*)&cs->nextDateParsed.type,
|
|
||||||
&cs->nextDateParsed.length, size) < 0)
|
|
||||||
return ASN_PARSE_E;
|
|
||||||
XMEMCPY(cs->nextDateParsed.data,
|
|
||||||
cs->nextDateAsn + localIdx - cs->nextDateParsed.length,
|
|
||||||
cs->nextDateParsed.length);
|
|
||||||
#endif
|
|
||||||
if (GetBasicDate(source, &idx, cs->nextDate,
|
|
||||||
&cs->nextDateFormat, size) < 0)
|
|
||||||
return ASN_PARSE_E;
|
|
||||||
|
|
||||||
#ifndef NO_ASN_TIME
|
|
||||||
#ifndef WOLFSSL_NO_OCSP_DATE_CHECK
|
|
||||||
if (!XVALIDATE_DATE(cs->nextDate, cs->nextDateFormat, AFTER))
|
|
||||||
return ASN_AFTER_DATE_E;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
localIdx = idx;
|
localIdx = idx;
|
||||||
if (((int)(idx - prevIndex) < wrapperSz) &&
|
if (((int)(idx - prevIndex) < wrapperSz) &&
|
||||||
|
Reference in New Issue
Block a user