Skip to content

Commit c4d0e08

Browse files
JulekCopilot
andcommitted
ocsp_responder: fix UTC time parsing and CERT_UNKNOWN response
- ParseIndexFile: replace XMKTIME() with UtcMkTime() to correctly interpret the trailing 'Z' (UTC) in the index file's revocation timestamps; XMKTIME/mktime uses local time, skewing the result on machines not running in UTC. - wc_OcspResponder_WriteResponse: when a certificate is not found in the status list, write a successful OCSPResponse with per-certificate status CERT_UNKNOWN instead of returning OCSP_CERT_UNKNOWN. Per RFC 6960, 'unknown' belongs in a SingleResponse inside a successful response, not as an OCSPResponseStatus error, so OCSP clients can distinguish 'unknown cert' from 'not authorized to answer'. - MapErrorToOcspStatus: remove the now-unreachable OCSP_CERT_UNKNOWN case. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 2bb98cb commit c4d0e08

File tree

2 files changed

+40
-5
lines changed

2 files changed

+40
-5
lines changed

examples/ocsp_responder/ocsp_responder.c

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,27 @@ static int LoadKeyDer(const char* filename, byte** der, word32* derSz)
258258
}
259259
}
260260

261+
/* Compute UTC unix timestamp from broken-down time without timezone conversion.
262+
* This avoids XMKTIME()/mktime(), which interprets struct tm as local time and
263+
* would skew revocation timestamps on machines not running in UTC. */
264+
static time_t UtcMkTime(struct tm* t)
265+
{
266+
static const int monthDaysCumulative[12] = {
267+
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
268+
};
269+
int year = t->tm_year + 1900;
270+
int leapDays = year;
271+
272+
if (t->tm_mon <= 1)
273+
--leapDays;
274+
leapDays = leapDays / 4 - leapDays / 100 + leapDays / 400
275+
- 1969 / 4 + 1969 / 100 - 1969 / 400;
276+
277+
return (time_t)(((((long long)(year - 1970) * 365 + leapDays +
278+
monthDaysCumulative[t->tm_mon] + t->tm_mday - 1) * 24 +
279+
t->tm_hour) * 60 + t->tm_min) * 60 + t->tm_sec);
280+
}
281+
261282
/* Free index entries */
262283
static void FreeIndexEntries(IndexEntry* head)
263284
{
@@ -331,7 +352,10 @@ static IndexEntry* ParseIndexFile(const char* filename)
331352
tm.tm_hour = (field[6] - '0') * 10 + (field[7] - '0');
332353
tm.tm_min = (field[8] - '0') * 10 + (field[9] - '0');
333354
tm.tm_sec = (field[10] - '0') * 10 + (field[11] - '0');
334-
entry->revocationTime = XMKTIME(&tm);
355+
/* Use UTC conversion: the 'Z' suffix in the index
356+
* file indicates UTC, but XMKTIME() uses local
357+
* time, which would skew the timestamp. */
358+
entry->revocationTime = UtcMkTime(&tm);
335359
}
336360
}
337361
break;
@@ -686,8 +710,6 @@ static enum Ocsp_Response_Status MapErrorToOcspStatus(int err)
686710
return OCSP_INTERNAL_ERROR;
687711
case ASN_NO_SIGNER_E:
688712
return OCSP_UNAUTHORIZED;
689-
case OCSP_CERT_UNKNOWN:
690-
return OCSP_UNAUTHORIZED;
691713
default:
692714
return OCSP_INTERNAL_ERROR;
693715
}

src/ocsp.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2753,8 +2753,21 @@ int wc_OcspResponder_WriteResponse(OcspResponder* responder,
27532753
/* Find the certificate status */
27542754
certStatus = FindCertStatus(ca, req.serial, req.serialSz);
27552755
if (certStatus == NULL) {
2756-
WOLFSSL_MSG("No status configured for requested certificate");
2757-
ret = OCSP_CERT_UNKNOWN;
2756+
/* RFC 6960: 'unknown' is a per-certificate status inside a successful
2757+
* OCSPResponse, not an error response. Generate a successful response
2758+
* with CERT_UNKNOWN so clients can distinguish it from UNAUTHORIZED. */
2759+
OcspResponderCertStatus unknownStatus;
2760+
WOLFSSL_MSG("No status for requested certificate, responding CERT_UNKNOWN");
2761+
if (req.serialSz > EXTERNAL_SERIAL_SIZE) {
2762+
ret = BUFFER_E;
2763+
goto out;
2764+
}
2765+
XMEMSET(&unknownStatus, 0, sizeof(unknownStatus));
2766+
XMEMCPY(unknownStatus.serial, req.serial, req.serialSz);
2767+
unknownStatus.serialSz = req.serialSz;
2768+
unknownStatus.status = CERT_UNKNOWN;
2769+
ret = OcspResponse_WriteResponse(responder, response, responseSz, ca,
2770+
&unknownStatus, &req);
27582771
goto out;
27592772
}
27602773

0 commit comments

Comments
 (0)