Skip to content

Commit aa0dce6

Browse files
julek-wolfsslrizlik
andcommitted
tls13 ocsp: suppot lazy cert loading with ocsp stapling
- Expose dynamic TLS certificate loading via WOLFSSL_CERT_SETUP_CB - Expose OCSP Status Cb to load responses directly. This bypasses internal checks on the OCSP response which is desirable if the CA is not loaded on the server. - Add `wc_InitOCSP`, `wc_FreeOCSP`, and `wc_CheckCertOcspResponse` as wrapper functions around existing OCSP functionality - Add `wolfSSL_GetOcspStaple` to retrieve OCSP staple data in TLS 1.3 - Add test for OCSP cert callback - Expose store_ctx functions - Add cert-setup-cb to os-check Co-Authored-By: Marco Oliverio <[email protected]>
1 parent 0224ef3 commit aa0dce6

File tree

19 files changed

+755
-260
lines changed

19 files changed

+755
-260
lines changed

.github/workflows/os-check.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ jobs:
6060
'--disable-sys-ca-certs',
6161
'--enable-all CPPFLAGS=-DWOLFSSL_DEBUG_CERTS ',
6262
'--enable-all CFLAGS="-DWOLFSSL_CHECK_MEM_ZERO"',
63+
'--enable-dtls --enable-dtls13 --enable-ocspstapling --enable-cert-setup-cb',
6364
]
6465
name: make check
6566
if: github.repository_owner == 'wolfssl'

configure.ac

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9782,6 +9782,13 @@ AC_ARG_ENABLE([rpk],
97829782
[ ENABLED_RPK=no ]
97839783
)
97849784
9785+
# Allows dynamically loading the certificate
9786+
AC_ARG_ENABLE([cert-setup-cb],
9787+
[AS_HELP_STRING([--enable-cert-setup-cb],[Enable support for dynamically loading TLS certificates (default: disabled)])],
9788+
[ ENABLED_CERT_SETUP_CB=$enableval ],
9789+
[ ENABLED_CERT_SETUP_CB=no ]
9790+
)
9791+
97859792
# check if should run the trusted peer certs test
97869793
# (for now checking both C_FLAGS and C_EXTRA_FLAGS)
97879794
AS_CASE(["$CFLAGS $CPPFLAGS"],[*'WOLFSSL_TRUST_PEER_CERT'*],[ENABLED_TRUSTED_PEER_CERT=yes])
@@ -10203,6 +10210,9 @@ AS_IF([test "x$ENABLED_DUAL_ALG_CERTS" = "xyes"],
1020310210
AS_IF([test "x$ENABLED_RPK" = "xyes"],
1020410211
[AM_CFLAGS="$AM_CFLAGS -DHAVE_RPK"])
1020510212
10213+
AS_IF([test "x$ENABLED_CERT_SETUP_CB" = "xyes"],
10214+
[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CERT_SETUP_CB"])
10215+
1020610216
AS_IF([test "x$ENABLED_ALTNAMES" = "xyes"],
1020710217
[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ALT_NAMES"])
1020810218

src/internal.c

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6755,13 +6755,21 @@ int InitSSL_Suites(WOLFSSL* ssl)
67556755
!havePSK && !haveAnon && !haveMcast) {
67566756

67576757
/* server certificate must be loaded */
6758-
if (!ssl->buffers.certificate || !ssl->buffers.certificate->buffer) {
6758+
if ((!ssl->buffers.certificate || !ssl->buffers.certificate->buffer)
6759+
#ifdef WOLFSSL_CERT_SETUP_CB
6760+
&& ssl->ctx->certSetupCb == NULL
6761+
#endif
6762+
) {
67596763
WOLFSSL_MSG("Server missing certificate");
67606764
WOLFSSL_ERROR_VERBOSE(NO_PRIVATE_KEY);
67616765
return NO_PRIVATE_KEY;
67626766
}
67636767

6764-
if (!ssl->buffers.key || !ssl->buffers.key->buffer) {
6768+
if ((!ssl->buffers.key || !ssl->buffers.key->buffer)
6769+
#ifdef WOLFSSL_CERT_SETUP_CB
6770+
&& ssl->ctx->certSetupCb == NULL
6771+
#endif
6772+
) {
67656773
/* allow no private key if using existing key */
67666774
#ifdef WOLF_PRIVATE_KEY_ID
67676775
if (ssl->devId != INVALID_DEVID
@@ -24359,10 +24367,9 @@ int CreateOcspRequest(WOLFSSL* ssl, OcspRequest* request,
2435924367

2436024368
InitDecodedCert(cert, certData, length, ssl->heap);
2436124369
/* TODO: Setup async support here */
24362-
ret = ParseCertRelative(cert, CERT_TYPE, VERIFY, SSL_CM(ssl), NULL);
24363-
if (ret != 0) {
24370+
ret = ParseCertRelative(cert, CERT_TYPE, NO_VERIFY, SSL_CM(ssl), NULL);
24371+
if (ret != 0)
2436424372
WOLFSSL_MSG("ParseCert failed");
24365-
}
2436624373
if (ret == 0)
2436724374
ret = InitOcspRequest(request, cert, 0, ssl->heap);
2436824375
if (ret == 0) {
@@ -25115,9 +25122,7 @@ static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer* status,
2511525122
}
2511625123
#endif
2511725124

25118-
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) && \
25119-
(defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
25120-
defined(WOLFSSL_HAPROXY))
25125+
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST)
2512125126
static int BuildCertificateStatusWithStatusCB(WOLFSSL* ssl)
2512225127
{
2512325128
WOLFSSL_OCSP *ocsp;
@@ -25137,7 +25142,7 @@ static int BuildCertificateStatusWithStatusCB(WOLFSSL* ssl)
2513725142
WOLFSSL_MSG("Calling ocsp->statusCb");
2513825143
ret = ocsp->statusCb(ssl, ioCtx);
2513925144
switch (ret) {
25140-
case SSL_TLSEXT_ERR_OK:
25145+
case WOLFSSL_OCSP_STATUS_CB_OK:
2514125146
if (ssl->ocspResp == NULL || ssl->ocspRespSz == 0) {
2514225147
ret = 0;
2514325148
break;
@@ -25146,20 +25151,19 @@ static int BuildCertificateStatusWithStatusCB(WOLFSSL* ssl)
2514625151
response.length = ssl->ocspRespSz;
2514725152
ret = BuildCertificateStatus(ssl, WOLFSSL_CSR_OCSP, &response, 1);
2514825153
break;
25149-
case SSL_TLSEXT_ERR_NOACK:
25154+
case WOLFSSL_OCSP_STATUS_CB_NOACK:
2515025155
/* No OCSP response to send */
2515125156
ret = 0;
2515225157
break;
25153-
case SSL_TLSEXT_ERR_ALERT_FATAL:
25158+
case WOLFSSL_OCSP_STATUS_CB_ALERT_FATAL:
2515425159
/* fall through */
2515525160
default:
2515625161
ret = WOLFSSL_FATAL_ERROR;
2515725162
break;
2515825163
}
2515925164
return ret;
2516025165
}
25161-
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST && (defined(OPENSSL_ALL) ||
25162-
defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)) */
25166+
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
2516325167

2516425168
#endif /* NO_WOLFSSL_SERVER */
2516525169

@@ -25185,9 +25189,7 @@ int SendCertificateStatus(WOLFSSL* ssl)
2518525189
status_type = status_type ? status_type : ssl->status_request_v2;
2518625190
#endif
2518725191

25188-
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) && \
25189-
(defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
25190-
defined(WOLFSSL_HAPROXY))
25192+
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST)
2519125193
if (SSL_CM(ssl)->ocsp_stapling != NULL &&
2519225194
SSL_CM(ssl)->ocsp_stapling->statusCb != NULL) {
2519325195
if (ssl->status_request == WOLFSSL_CSR_OCSP)
@@ -31704,7 +31706,8 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
3170431706
word16 len;
3170531707
word32 begin = *inOutIdx;
3170631708
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) || \
31707-
defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY)
31709+
defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) || \
31710+
defined(WOLFSSL_CERT_SETUP_CB)
3170831711
int ret;
3170931712
#endif
3171031713
#ifdef OPENSSL_EXTRA
@@ -31851,6 +31854,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
3185131854
len -= (word16)(OPAQUE16_LEN) + dnSz;
3185231855
}
3185331856

31857+
#ifdef WOLFSSL_CERT_SETUP_CB
3185431858
#ifdef OPENSSL_EXTRA
3185531859
/* call client cert callback if no cert has been loaded */
3185631860
if ((ssl->ctx->CBClientCert != NULL) &&
@@ -31872,6 +31876,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType,
3187231876
return WOLFSSL_ERROR_WANT_X509_LOOKUP;
3187331877
}
3187431878
}
31879+
#endif
3187531880
if ((ret = CertSetupCbWrapper(ssl)) != 0)
3187631881
return ret;
3187731882
#endif
@@ -38698,7 +38703,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
3869838703
#endif
3869938704
#endif
3870038705

38701-
#ifdef OPENSSL_EXTRA
38706+
#ifdef WOLFSSL_CERT_SETUP_CB
3870238707
/* Give user last chance to provide a cert for cipher selection */
3870338708
if (ret == 0 && ssl->ctx->certSetupCb != NULL)
3870438709
ret = CertSetupCbWrapper(ssl);

src/ocsp.c

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,52 @@
4545
#endif
4646

4747

48+
int wc_InitOCSP(WOLFSSL_OCSP* ocsp, WOLFSSL_CERT_MANAGER* cm)
49+
{
50+
return InitOCSP(ocsp, cm);
51+
}
52+
53+
void wc_FreeOCSP(WOLFSSL_OCSP* ocsp)
54+
{
55+
FreeOCSP(ocsp, 0);
56+
}
57+
58+
int wc_CheckCertOcspResponse(WOLFSSL_OCSP *ocsp, DecodedCert *cert,
59+
byte *response, int responseSz, void* heap)
60+
{
61+
int ret = WC_NO_ERR_TRACE(ASN_OCSP_CONFIRM_E);
62+
63+
#ifdef WOLFSSL_SMALL_STACK
64+
OcspRequest* ocspRequest;
65+
#else
66+
OcspRequest ocspRequest[1];
67+
#endif
68+
69+
70+
#ifdef WOLFSSL_SMALL_STACK
71+
ocspRequest = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL,
72+
DYNAMIC_TYPE_TMP_BUFFER);
73+
if (ocspRequest == NULL) {
74+
WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
75+
return MEMORY_E;
76+
}
77+
#endif
78+
79+
if (InitOcspRequest(ocspRequest, cert, ocsp->cm->ocspSendNonce,
80+
ocsp->cm->heap) == 0) {
81+
ret = CheckOcspResponse(ocsp, response, responseSz, NULL, NULL, NULL,
82+
ocspRequest, heap);
83+
FreeOcspRequest(ocspRequest);
84+
}
85+
86+
#ifdef WOLFSSL_SMALL_STACK
87+
XFREE(ocspRequest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
88+
#endif
89+
90+
WOLFSSL_LEAVE("CheckCertOCSP", ret);
91+
return ret;
92+
}
93+
4894
int InitOCSP(WOLFSSL_OCSP* ocsp, WOLFSSL_CERT_MANAGER* cm)
4995
{
5096
WOLFSSL_ENTER("InitOCSP");
@@ -375,7 +421,7 @@ int CheckOcspResponse(WOLFSSL_OCSP *ocsp, byte *response, int responseSz,
375421
ocspResponse->single->status->next = status->next;
376422
XMEMCPY(status, ocspResponse->single->status, sizeof(CertStatus));
377423
}
378-
else {
424+
else if (entry != NULL) {
379425
/* Save new certificate entry */
380426
status = (CertStatus*)XMALLOC(sizeof(CertStatus),
381427
ocsp->cm->heap, DYNAMIC_TYPE_OCSP_STATUS);

0 commit comments

Comments
 (0)