Merge pull request #3544 from haydenroche5/ocsp_stapling_bug

Fix bug where OCSP stapling wasn't happening even when requested by client
This commit is contained in:
John Safranek
2020-12-29 14:23:10 -08:00
committed by GitHub
4 changed files with 81 additions and 34 deletions

View File

@ -311,7 +311,7 @@ wolf_pid3=$!
wait_for_readyFile $ready_file2 $wolf_pid3 $port3 wait_for_readyFile $ready_file2 $wolf_pid3 $port3
./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 1 -p $port3 ./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 1 -p $port3
RESULT=$? RESULT=$?
[ $RESULT -ne 0 ] && printf '\n\n%s\n' "Client connection 2 failed" && exit 1 [ $RESULT -ne 0 ] && printf '\n\n%s\n' "Client connection 1 failed" && exit 1
printf '%s\n\n' "Test PASSED!" printf '%s\n\n' "Test PASSED!"
printf '%s\n\n' "------------- TEST CASE 2 SHOULD REVOKE ----------------------" printf '%s\n\n' "------------- TEST CASE 2 SHOULD REVOKE ----------------------"
@ -324,7 +324,7 @@ wait_for_readyFile $ready_file2 $wolf_pid3 $port3
sleep 0.1 sleep 0.1
./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 1 -p $port3 ./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 1 -p $port3
RESULT=$? RESULT=$?
[ $RESULT -ne 1 ] && printf '\n\n%s\n' "Client connection succeeded $RESULT" \ [ $RESULT -ne 1 ] && printf '\n\n%s\n' "Client connection 2 succeeded $RESULT" \
&& exit 1 && exit 1
printf '%s\n\n' "Test successfully REVOKED!" printf '%s\n\n' "Test successfully REVOKED!"
@ -345,7 +345,21 @@ if [ $? -ne 0 ]; then
[ $RESULT -ne 0 ] && printf '\n\n%s\n' "Client connection 3 failed" && exit 1 [ $RESULT -ne 0 ] && printf '\n\n%s\n' "Client connection 3 failed" && exit 1
printf '%s\n\n' "Test PASSED!" printf '%s\n\n' "Test PASSED!"
printf '%s\n\n' "------------- TEST CASE 4 SHOULD REVOKE ------------------" printf '%s\n\n' "------------- TEST CASE 4 SHOULD PASS --------------------"
# client test against our own server, must staple - GOOD CERT
remove_single_rF $ready_file2
./examples/server/server -c certs/ocsp/server1-cert.pem -R $ready_file2 \
-k certs/ocsp/server1-key.pem -v 4 \
-p $port3 &
wolf_pid3=$!
wait_for_readyFile $ready_file2 $wolf_pid3 $port3
./examples/client/client -C -A certs/ocsp/root-ca-cert.pem -W 1m -v 4 -F 1 \
-p $port3
RESULT=$?
[ $RESULT -ne 0 ] && printf '\n\n%s\n' "Client connection 4 failed" && exit 1
printf '%s\n\n' "Test PASSED!"
printf '%s\n\n' "------------- TEST CASE 5 SHOULD REVOKE ------------------"
# client test against our own server - REVOKED CERT # client test against our own server - REVOKED CERT
remove_single_rF $ready_file2 remove_single_rF $ready_file2
./examples/server/server -c certs/ocsp/server2-cert.pem -R $ready_file2 \ ./examples/server/server -c certs/ocsp/server2-cert.pem -R $ready_file2 \
@ -357,7 +371,7 @@ if [ $? -ne 0 ]; then
-p $port3 -p $port3
RESULT=$? RESULT=$?
[ $RESULT -ne 1 ] && \ [ $RESULT -ne 1 ] && \
printf '\n\n%s\n' "Client connection succeeded $RESULT" \ printf '\n\n%s\n' "Client connection 5 succeeded $RESULT" \
&& exit 1 && exit 1
printf '%s\n\n' "Test successfully REVOKED!" printf '%s\n\n' "Test successfully REVOKED!"
fi fi
@ -373,20 +387,20 @@ openssl s_server $V4V6_FLAG -cert ./certs/server-cert.pem -key certs/server-key.
openssl_pid=$! openssl_pid=$!
sleep 0.1 sleep 0.1
printf '%s\n\n' "------------- TEST CASE 5 SHOULD PASS ----------------------" printf '%s\n\n' "------------- TEST CASE 6 SHOULD PASS ----------------------"
# client asks for OCSP staple but doesn't fail when none returned # client asks for OCSP staple but doesn't fail when none returned
./examples/client/client -p $port -g -v 3 -W 1 ./examples/client/client -p $port -g -v 3 -W 1
RESULT=$? RESULT=$?
[ $RESULT -ne 0 ] && printf '\n\n%s\n' "Client connection 5 failed" && exit 1 [ $RESULT -ne 0 ] && printf '\n\n%s\n' "Client connection 6 failed" && exit 1
printf '%s\n\n' "Test PASSED!" printf '%s\n\n' "Test PASSED!"
printf '%s\n\n' "------------- TEST CASE 6 SHOULD UNKNOWN -------------------" printf '%s\n\n' "------------- TEST CASE 7 SHOULD UNKNOWN -------------------"
# client asks for OCSP staple but doesn't fail when none returned # client asks for OCSP staple but doesn't fail when none returned
./examples/client/client -p $port -g -v 3 -W 1m ./examples/client/client -p $port -g -v 3 -W 1m
RESULT=$? RESULT=$?
[ $RESULT -ne 1 ] && printf '\n\n%s\n' "Client connection 6 succeeded $RESULT" \ [ $RESULT -ne 1 ] && printf '\n\n%s\n' "Client connection 7 succeeded $RESULT" \
&& exit 1 && exit 1
printf '%s\n\n' "Test PASSED!" printf '%s\n\n' "Test PASSED!"
@ -395,21 +409,21 @@ openssl_tls13=$?
./examples/client/client -v 4 2>&1 | grep -- 'Bad SSL version' ./examples/client/client -v 4 2>&1 | grep -- 'Bad SSL version'
wolfssl_not_tls13=$? wolfssl_not_tls13=$?
if [ "$openssl_tls13" = "0" -a "wolfssl_not_tls13" != "0" ]; then if [ "$openssl_tls13" = "0" -a "wolfssl_not_tls13" != "0" ]; then
printf '%s\n\n' "------------- TEST CASE 7 SHOULD PASS --------------------" printf '%s\n\n' "------------- TEST CASE 8 SHOULD PASS --------------------"
# client asks for OCSP staple but doesn't fail when none returned # client asks for OCSP staple but doesn't fail when none returned
./examples/client/client -p $port -g -v 4 -W 1 ./examples/client/client -p $port -g -v 4 -W 1
RESULT=$? RESULT=$?
[ $RESULT -ne 0 ] && printf '\n\n%s\n' "Client connection 7 failed" && exit 1 [ $RESULT -ne 0 ] && printf '\n\n%s\n' "Client connection 8 failed" && exit 1
printf '%s\n\n' "Test PASSED!" printf '%s\n\n' "Test PASSED!"
printf '%s\n\n' "------------- TEST CASE 8 SHOULD UNKNOWN -----------------" printf '%s\n\n' "------------- TEST CASE 9 SHOULD UNKNOWN -----------------"
# client asks for OCSP staple but doesn't fail when none returned # client asks for OCSP staple but doesn't fail when none returned
./examples/client/client -p $port -g -v 4 -W 1m ./examples/client/client -p $port -g -v 4 -W 1m
RESULT=$? RESULT=$?
[ $RESULT -ne 1 ] \ [ $RESULT -ne 1 ] \
&& printf '\n\n%s\n' "Client connection 8 succeeded $RESULT" \ && printf '\n\n%s\n' "Client connection 9 succeeded $RESULT" \
&& exit 1 && exit 1
printf '%s\n\n' "Test PASSED!" printf '%s\n\n' "Test PASSED!"
fi fi

View File

@ -9918,6 +9918,7 @@ static int ProcessCSR(WOLFSSL* ssl, byte* input, word32* inOutIdx,
{ {
int ret = 0; int ret = 0;
OcspRequest* request; OcspRequest* request;
WOLFSSL_ENTER("ProcessCSR");
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
CertStatus* status; CertStatus* status;
@ -9999,6 +10000,7 @@ static int ProcessCSR(WOLFSSL* ssl, byte* input, word32* inOutIdx,
XFREE(response, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST); XFREE(response, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST);
#endif #endif
WOLFSSL_LEAVE("ProcessCSR", ret);
return ret; return ret;
} }
#endif #endif
@ -11289,7 +11291,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
args->fatal = TLSX_CSR_InitRequest(ssl->extensions, args->fatal = TLSX_CSR_InitRequest(ssl->extensions,
args->dCert, ssl->heap); args->dCert, ssl->heap);
doLookup = 0; doLookup = 0;
#if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_CLIENT) #if defined(WOLFSSL_TLS13)
if (ssl->options.tls1_3) { if (ssl->options.tls1_3) {
TLSX* ext = TLSX_Find(ssl->extensions, TLSX* ext = TLSX_Find(ssl->extensions,
TLSX_STATUS_REQUEST); TLSX_STATUS_REQUEST);

View File

@ -2980,15 +2980,37 @@ static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length,
byte isRequest) byte isRequest)
{ {
int ret; int ret;
#if !defined(NO_WOLFSSL_SERVER)
byte status_type;
word16 size = 0;
#if defined(WOLFSSL_TLS13)
DecodedCert* cert;
#endif
#endif
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER) \
&& defined(WOLFSSL_TLS13)
OcspRequest* request;
TLSX* extension;
CertificateStatusRequest* csr;
#endif
#if !defined(NO_WOLFSSL_CLIENT) && defined(WOLFSSL_TLS13) \
|| !defined(NO_WOLFSSL_SERVER)
word32 offset = 0;
#endif
#if !defined(NO_WOLFSSL_CLIENT) && defined(WOLFSSL_TLS13)
word32 resp_length;
#endif
/* shut up compiler warnings */ /* shut up compiler warnings */
(void) ssl; (void) input; (void) ssl; (void) input;
if (!isRequest) { if (!isRequest) {
#ifndef NO_WOLFSSL_CLIENT #ifndef NO_WOLFSSL_CLIENT
TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST); extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
CertificateStatusRequest* csr = extension ? csr = extension ? (CertificateStatusRequest*)extension->data : NULL;
(CertificateStatusRequest*)extension->data : NULL;
if (!csr) { if (!csr) {
/* look at context level */ /* look at context level */
@ -3009,8 +3031,8 @@ static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length,
case WOLFSSL_CSR_OCSP: case WOLFSSL_CSR_OCSP:
/* propagate nonce */ /* propagate nonce */
if (csr->request.ocsp.nonceSz) { if (csr->request.ocsp.nonceSz) {
OcspRequest* request = request =
(OcspRequest*)TLSX_CSR_GetRequest(ssl->extensions); (OcspRequest*)TLSX_CSR_GetRequest(ssl->extensions);
if (request) { if (request) {
XMEMCPY(request->nonce, csr->request.ocsp.nonce, XMEMCPY(request->nonce, csr->request.ocsp.nonce,
@ -3026,9 +3048,6 @@ static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length,
#ifdef WOLFSSL_TLS13 #ifdef WOLFSSL_TLS13
if (ssl->options.tls1_3) { if (ssl->options.tls1_3) {
word32 resp_length;
word32 offset = 0;
/* Get the new extension potentially created above. */ /* Get the new extension potentially created above. */
extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST); extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
csr = extension ? (CertificateStatusRequest*)extension->data : NULL; csr = extension ? (CertificateStatusRequest*)extension->data : NULL;
@ -3046,12 +3065,10 @@ static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length,
if (offset + resp_length != length) if (offset + resp_length != length)
ret = BUFFER_ERROR; ret = BUFFER_ERROR;
} }
#if !defined(NO_WOLFSSL_SERVER)
if (ret == 0) { if (ret == 0) {
csr->response.buffer = input + offset; csr->response.buffer = input + offset;
csr->response.length = resp_length; csr->response.length = resp_length;
} }
#endif
return ret; return ret;
} }
@ -3065,10 +3082,6 @@ static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length,
} }
else { else {
#ifndef NO_WOLFSSL_SERVER #ifndef NO_WOLFSSL_SERVER
byte status_type;
word16 offset = 0;
word16 size = 0;
if (length == 0) if (length == 0)
return 0; return 0;
@ -3117,11 +3130,29 @@ static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length,
if (ret != WOLFSSL_SUCCESS) if (ret != WOLFSSL_SUCCESS)
return ret; /* throw error */ return ret; /* throw error */
#if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER) #if defined(WOLFSSL_TLS13)
if (ssl->options.tls1_3) { if (ssl->options.tls1_3) {
OcspRequest* request; cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), ssl->heap,
TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST); DYNAMIC_TYPE_DCERT);
CertificateStatusRequest* csr = extension ? if (cert == NULL) {
return MEMORY_E;
}
InitDecodedCert(cert, ssl->buffers.certificate->buffer,
ssl->buffers.certificate->length, ssl->heap);
ret = ParseCert(cert, CERT_TYPE, 1, ssl->ctx->cm);
if (ret != 0 ) {
XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT);
return ret;
}
ret = TLSX_CSR_InitRequest(ssl->extensions, cert, ssl->heap);
if (ret != 0 ) {
XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT);
return ret;
}
XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT);
extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
csr = extension ?
(CertificateStatusRequest*)extension->data : NULL; (CertificateStatusRequest*)extension->data : NULL;
if (csr == NULL) if (csr == NULL)
return MEMORY_ERROR; return MEMORY_ERROR;

View File

@ -2020,8 +2020,8 @@ struct WOLFSSL_CERT_MANAGER {
byte ocspSendNonce:1; /* send the OCSP nonce ? */ byte ocspSendNonce:1; /* send the OCSP nonce ? */
byte ocspUseOverrideURL:1; /* ignore cert responder, override */ byte ocspUseOverrideURL:1; /* ignore cert responder, override */
byte ocspStaplingEnabled:1; /* is OCSP Stapling on ? */ byte ocspStaplingEnabled:1; /* is OCSP Stapling on ? */
#if !defined(NO_WOLFSSL_CLIENT) && (defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)) || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
byte ocspMustStaple:1; /* server must respond with staple */ byte ocspMustStaple:1; /* server must respond with staple */
#endif #endif
@ -2356,7 +2356,7 @@ typedef struct {
union { union {
OcspRequest ocsp; OcspRequest ocsp;
} request; } request;
#if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER) #if defined(WOLFSSL_TLS13)
buffer response; buffer response;
#endif #endif
} CertificateStatusRequest; } CertificateStatusRequest;