Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 39 additions & 1 deletion src/ocsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -772,12 +772,50 @@ const char *wolfSSL_OCSP_cert_status_str(long s)
int wolfSSL_OCSP_check_validity(WOLFSSL_ASN1_TIME* thisupd,
WOLFSSL_ASN1_TIME* nextupd, long sec, long maxsec)
{
#ifndef NO_ASN_TIME
int ret = WOLFSSL_SUCCESS;
time_t now = wc_Time(0);
time_t cmp;

/* Same semantics as OpenSSL's OCSP_check_validity: sec is the allowed
* clock skew and maxsec, when non-negative, the maximum age of thisUpdate.
* wolfSSL_X509_cmp_time() returns 0 for a NULL or malformed time. */
if (sec < 0)
sec = 0;

cmp = now + sec;
if (wolfSSL_X509_cmp_time(thisupd, &cmp) != -1) {
Comment thread
jackctj117 marked this conversation as resolved.
Resolved
Comment thread
jackctj117 marked this conversation as resolved.
Resolved
WOLFSSL_MSG("OCSP thisUpdate missing, malformed or in the future");
ret = WOLFSSL_FAILURE;
}
else if (maxsec >= 0) {
cmp = now - maxsec;
if (wolfSSL_X509_cmp_time(thisupd, &cmp) != 1) {
WOLFSSL_MSG("OCSP thisUpdate is too old");
ret = WOLFSSL_FAILURE;
}
}

if ((ret == WOLFSSL_SUCCESS) && (nextupd != NULL)) {
cmp = now - sec;
if (wolfSSL_X509_cmp_time(nextupd, &cmp) != 1) {
WOLFSSL_MSG("OCSP nextUpdate has passed or is malformed");
ret = WOLFSSL_FAILURE;
}
else if (wolfSSL_ASN1_TIME_compare(nextupd, thisupd) < 0) {
WOLFSSL_MSG("OCSP nextUpdate precedes thisUpdate");
ret = WOLFSSL_FAILURE;
}
}

return ret;
#else
(void)thisupd;
(void)nextupd;
(void)sec;
(void)maxsec;
/* Dates validated in DecodeSingleResponse. */
return WOLFSSL_SUCCESS;
#endif /* !NO_ASN_TIME */
}

void wolfSSL_OCSP_CERTID_free(WOLFSSL_OCSP_CERTID* certId)
Expand Down
1 change: 1 addition & 0 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -48027,6 +48027,7 @@ TEST_CASE testCases[] = {
TEST_DECL_GROUP("ocsp", test_ocsp_responder_keyhash_binding),
TEST_DECL_GROUP("ocsp", test_ocsp_response_parsing),
TEST_DECL_GROUP("ocsp", test_ocsp_certid_enc_dec),
TEST_DECL_GROUP("ocsp", test_ocsp_check_validity),
TEST_DECL_GROUP("ocsp", test_ocsp_certid_dup),
TEST_DECL_GROUP("ocsp", test_ocsp_resp_find_status_serial_prefix),
TEST_DECL_GROUP("ocsp", test_ocsp_resp_times),
Expand Down
121 changes: 121 additions & 0 deletions tests/api/test_ocsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -6937,3 +6937,124 @@ int test_wolfIO_DecodeUrl_host_bounds(void)
return TEST_SKIPPED;
}
#endif /* HAVE_HTTP_CLIENT */

/* thisUpdate must be present, no more than sec seconds in the future and no
* older than maxsec; nextUpdate is optional but when present must be valid
* and not have passed. Issue 10718. */
#if defined(HAVE_OCSP) && (defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) && \
!defined(NO_ASN_TIME) && !defined(USER_TIME) && !defined(TIME_OVERRIDES)
int test_ocsp_check_validity(void)
{
EXPECT_DECLS;
time_t now = wc_Time(0);
WOLFSSL_ASN1_TIME thisUpd;
WOLFSSL_ASN1_TIME nextUpd;
const long DAY = 24L * 60 * 60;

/* Fresh thisUpdate, no nextUpdate. */
ExpectNotNull(wolfSSL_ASN1_TIME_adj(&thisUpd, now, 0, -60));
ExpectIntEQ(wolfSSL_OCSP_check_validity(&thisUpd, NULL, 300, 300),
WOLFSSL_SUCCESS);

/* thisUpdate older than maxsec (replayed response). */
ExpectNotNull(wolfSSL_ASN1_TIME_adj(&thisUpd, now, 0, -DAY));
ExpectIntEQ(wolfSSL_OCSP_check_validity(&thisUpd, NULL, 300, 300),
WOLFSSL_FAILURE);

/* thisUpdate in the future beyond the skew. */
ExpectNotNull(wolfSSL_ASN1_TIME_adj(&thisUpd, now, 0, DAY));
ExpectIntEQ(wolfSSL_OCSP_check_validity(&thisUpd, NULL, 300, 300),
WOLFSSL_FAILURE);

/* thisUpdate in the future within the skew. */
ExpectNotNull(wolfSSL_ASN1_TIME_adj(&thisUpd, now, 0, 100));
ExpectIntEQ(wolfSSL_OCSP_check_validity(&thisUpd, NULL, 300, 300),
WOLFSSL_SUCCESS);

/* NULL thisUpdate. */
ExpectIntEQ(wolfSSL_OCSP_check_validity(NULL, NULL, 300, 300),
WOLFSSL_FAILURE);

/* Zero-length thisUpdate. */
XMEMSET(&thisUpd, 0, sizeof(thisUpd));
ExpectIntEQ(wolfSSL_OCSP_check_validity(&thisUpd, NULL, 300, 300),
WOLFSSL_FAILURE);

/* Expired nextUpdate. */
ExpectNotNull(wolfSSL_ASN1_TIME_adj(&thisUpd, now, 0, -60));
ExpectNotNull(wolfSSL_ASN1_TIME_adj(&nextUpd, now, 0, -DAY));
ExpectIntEQ(wolfSSL_OCSP_check_validity(&thisUpd, &nextUpd, 300, 300),
WOLFSSL_FAILURE);

/* nextUpdate in the past within the skew. */
ExpectNotNull(wolfSSL_ASN1_TIME_adj(&thisUpd, now, 0, -120));
ExpectNotNull(wolfSSL_ASN1_TIME_adj(&nextUpd, now, 0, -100));
ExpectIntEQ(wolfSSL_OCSP_check_validity(&thisUpd, &nextUpd, 300, DAY),
WOLFSSL_SUCCESS);

/* nextUpdate in the future. */
ExpectNotNull(wolfSSL_ASN1_TIME_adj(&thisUpd, now, 0, -60));
ExpectNotNull(wolfSSL_ASN1_TIME_adj(&nextUpd, now, 0, DAY));
ExpectIntEQ(wolfSSL_OCSP_check_validity(&thisUpd, &nextUpd, 300, 300),
WOLFSSL_SUCCESS);

/* nextUpdate before thisUpdate. */
ExpectNotNull(wolfSSL_ASN1_TIME_adj(&thisUpd, now, 0, -60));
ExpectNotNull(wolfSSL_ASN1_TIME_adj(&nextUpd, now, 0, -120));
ExpectIntEQ(wolfSSL_OCSP_check_validity(&thisUpd, &nextUpd, 300, 300),
WOLFSSL_FAILURE);

/* Zero-length nextUpdate. */
ExpectNotNull(wolfSSL_ASN1_TIME_adj(&thisUpd, now, 0, -60));
XMEMSET(&nextUpd, 0, sizeof(nextUpd));
ExpectIntEQ(wolfSSL_OCSP_check_validity(&thisUpd, &nextUpd, 300, DAY),
WOLFSSL_FAILURE);

/* Negative maxsec disables the age check. */
ExpectNotNull(wolfSSL_ASN1_TIME_adj(&thisUpd, now, 0, -DAY));
ExpectIntEQ(wolfSSL_OCSP_check_validity(&thisUpd, NULL, 300, -1),
WOLFSSL_SUCCESS);

/* thisUpdate within a larger maxsec. */
ExpectNotNull(wolfSSL_ASN1_TIME_adj(&thisUpd, now, 0, -DAY));
ExpectIntEQ(wolfSSL_OCSP_check_validity(&thisUpd, NULL, 300, 2 * DAY),
WOLFSSL_SUCCESS);

#ifdef WOLFSSL_OCSP_PARSE_STATUS
/* Through wolfSSL_OCSP_single_get0_status, which returns NULL for an
* absent nextUpdate. */
{
WOLFSSL_OCSP_SINGLERESP single;
CertStatus certStatus;
WOLFSSL_ASN1_TIME* gThis = NULL;
WOLFSSL_ASN1_TIME* gNext = NULL;

XMEMSET(&single, 0, sizeof(single));
XMEMSET(&certStatus, 0, sizeof(certStatus));
certStatus.status = CERT_GOOD;
single.status = &certStatus;

ExpectNotNull(wolfSSL_ASN1_TIME_adj(&certStatus.thisDateParsed, now, 0,
-60));
ExpectIntEQ(wolfSSL_OCSP_single_get0_status(&single, NULL, NULL,
&gThis, &gNext), CERT_GOOD);
ExpectIntEQ(wolfSSL_OCSP_check_validity(gThis, gNext, 300, DAY),
WOLFSSL_SUCCESS);

ExpectNotNull(wolfSSL_ASN1_TIME_adj(&certStatus.thisDateParsed, now, 0,
-DAY));
ExpectIntEQ(wolfSSL_OCSP_single_get0_status(&single, NULL, NULL,
&gThis, &gNext), CERT_GOOD);
ExpectIntEQ(wolfSSL_OCSP_check_validity(gThis, gNext, 300, 300),
WOLFSSL_FAILURE);
}
#endif /* WOLFSSL_OCSP_PARSE_STATUS */

return EXPECT_RESULT();
}
#else
int test_ocsp_check_validity(void)
{
return TEST_SKIPPED;
}
#endif
1 change: 1 addition & 0 deletions tests/api/test_ocsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#define WOLFSSL_TEST_OCSP_H

int test_ocsp_certid_enc_dec(void);
int test_ocsp_check_validity(void);
int test_ocsp_certid_dup(void);
int test_ocsp_resp_find_status_serial_prefix(void);
int test_ocsp_resp_times(void);
Expand Down
10 changes: 4 additions & 6 deletions wolfcrypt/src/asn.c
Original file line number Diff line number Diff line change
Expand Up @@ -37349,8 +37349,10 @@ static int DecodeSingleResponse(const byte* source, word32* ioIndex,
DECL_ASNGETDATA(dataASN, singleResponseASN_Length);
int ret = 0;
CertStatus* cs = NULL;
word32 thisDateLen;
word32 nextDateLen;
/* Maximum lengths for the date buffers. Initialized here so MSVC does not
* warn (C4701) about the WOLFSSL_OCSP_PARSE_STATUS uses below. */
word32 thisDateLen = MAX_DATE_SIZE;
word32 nextDateLen = MAX_DATE_SIZE;
word32 certIdSeqIdx;

(void)wrapperSz;
Expand All @@ -37361,10 +37363,6 @@ static int DecodeSingleResponse(const byte* source, word32* ioIndex,

if (ret == 0) {
cs = single->status;
/* Set maximum lengths for data. */
thisDateLen = MAX_DATE_SIZE;
nextDateLen = MAX_DATE_SIZE;

/* Set OID type, buffers to hold data and variables to hold size. */
GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_THISUPDATE_GT],
cs->thisDate, &thisDateLen);
Expand Down
8 changes: 5 additions & 3 deletions wolfssl/wolfcrypt/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -4454,9 +4454,11 @@
#endif

#if defined(HAVE_OCSP) && !defined(WOLFCRYPT_ONLY) && \
(defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY) || \
defined(WOLFSSL_APACHE_HTTPD))
(defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
defined(HAVE_LIGHTY) || defined(WOLFSSL_APACHE_HTTPD))
/* OPENSSL_EXTRA: the compat getters must return the parsed
* thisUpdate/nextUpdate for wolfSSL_OCSP_check_validity. */
#undef WOLFSSL_OCSP_PARSE_STATUS
#define WOLFSSL_OCSP_PARSE_STATUS
#endif
Expand Down
Loading