Process multiple ocsp responses

This commit is contained in:
Tesfa Mael
2020-10-14 01:10:07 -07:00
parent 232028d03b
commit 5ac3e7d542

View File

@@ -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) &&