diff --git a/examples/server/server.c b/examples/server/server.c index 713963a7f..a64f2cfda 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -984,7 +984,13 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) myVerifyFail = 1; } else if (XSTRNCMP(myoptarg, "loadSSL", 7) == 0) { - printf("Load cert/key into wolfSSL object\n"); + printf("Also load cert/key into wolfSSL object\n"); + #ifndef NO_CERTS + loadCertKeyIntoSSLObj = 2; + #endif + } + else if (XSTRNCMP(myoptarg, "loadSSLOnly", 11) == 0) { + printf("Only load cert/key into wolfSSL object\n"); #ifndef NO_CERTS loadCertKeyIntoSSLObj = 1; #endif @@ -1387,7 +1393,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) #endif #if !defined(NO_CERTS) - if ((!usePsk || usePskPlus) && !useAnon && !loadCertKeyIntoSSLObj) { + if ((!usePsk || usePskPlus) && !useAnon && !(loadCertKeyIntoSSLObj == 1)) { #ifndef TEST_LOAD_BUFFER if (SSL_CTX_use_certificate_chain_file(ctx, ourCert) != WOLFSSL_SUCCESS) @@ -1428,7 +1434,8 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) #ifdef HAVE_PK_CALLBACKS pkCbInfo.ourKey = ourKey; #endif - if (!useNtruKey && (!usePsk || usePskPlus) && !useAnon && !loadCertKeyIntoSSLObj + if (!useNtruKey && (!usePsk || usePskPlus) && !useAnon + && !(loadCertKeyIntoSSLObj == 1) #if defined(HAVE_PK_CALLBACKS) && defined(TEST_PK_PRIVKEY) && !pkCallbacks #endif /* HAVE_PK_CALLBACKS && TEST_PK_PRIVKEY */ diff --git a/scripts/ocsp-stapling2.test b/scripts/ocsp-stapling2.test index 87ce20319..c4c2df13b 100755 --- a/scripts/ocsp-stapling2.test +++ b/scripts/ocsp-stapling2.test @@ -354,6 +354,23 @@ CLI_PORT=`cat $ready_file5` RESULT=$? [ $RESULT -ne 1 ] && printf '\n\n%s\n' "Client connection suceeded $RESULT" && exit 1 printf '%s\n\n' "Test successfully REVOKED!" +printf '%s\n\n' "------------- TEST CASE 7 LOAD CERT IN SSL -------------------" +remove_single_rF $ready_file5 +./examples/server/server -c certs/ocsp/server1-cert.pem \ + -k certs/ocsp/server1-key.pem -R $ready_file5 \ + -p $resume_port -H loadSSL & +wolf_pid=$! +wait_for_readyFile $ready_file5 +CLI_PORT=`cat $ready_file5` +echo "test connection" | openssl s_client -status -connect 127.0.0.1:$CLI_PORT -cert ./certs/client-cert.pem -key ./certs/client-key.pem -CAfile ./certs/ocsp/root-ca-cert.pem +RESULT=$? +[ $RESULT -ne 0 ] && printf '\n\n%s\n' "Client connection failed $RESULT" && exit 1 +wait $wolf_pid +if [ $? -ne 0 ]; then + printf '%s\n' "Unexpected server result" + exit 1 +fi +printf '%s\n\n' "Test successful" printf '%s\n\n' "------------------- TESTS COMPLETE ---------------------------" exit 0 diff --git a/src/internal.c b/src/internal.c index bc9c6a255..e43bd0653 100644 --- a/src/internal.c +++ b/src/internal.c @@ -14163,6 +14163,11 @@ int SendFinished(WOLFSSL* ssl) (defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \ defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2))) || \ (defined(WOLFSSL_TLS13) && defined(HAVE_CERTIFICATE_STATUS_REQUEST)) +/* Parses and decodes the certificate then initializes "request". In the case + * of !ssl->buffers.weOwnCert, ssl->ctx->certOcspRequest gets set to "request". + * + * Returns 0 on success + */ static int CreateOcspRequest(WOLFSSL* ssl, OcspRequest* request, DecodedCert* cert, byte* certData, word32 length) { @@ -14197,18 +14202,29 @@ static int CreateOcspRequest(WOLFSSL* ssl, OcspRequest* request, } +/* Creates OCSP response and places it in variable "response". Memory + * management for "buffer* response" is up to the caller. + * + * Also creates an OcspRequest in the case that ocspRequest is null or that + * ssl->buffers.weOwnCert is set. In those cases managing ocspRequest free'ing + * is up to the caller. NOTE: in OcspCreateRequest ssl->ctx->certOcspRequest can + * be set to point to "ocspRequest" and it then should not be free'd since + * wolfSSL_CTX_free will take care of it. + * + * Returns 0 on success + */ int CreateOcspResponse(WOLFSSL* ssl, OcspRequest** ocspRequest, buffer* response) { int ret = 0; - OcspRequest* request; + OcspRequest* request = NULL; + byte createdRequest = 0; if (ssl == NULL || ocspRequest == NULL || response == NULL) return BAD_FUNC_ARG; - request = *ocspRequest; - XMEMSET(response, 0, sizeof(*response)); + request = *ocspRequest; /* unable to fetch status. skip. */ if (ssl->ctx->cm == NULL || ssl->ctx->cm->ocspStaplingEnabled == 0) @@ -14237,16 +14253,17 @@ int CreateOcspResponse(WOLFSSL* ssl, OcspRequest** ocspRequest, if (request == NULL) ret = MEMORY_E; + createdRequest = 1; if (ret == 0) { ret = CreateOcspRequest(ssl, request, cert, der->buffer, der->length); } - if (request != NULL && ret != 0) { - FreeOcspRequest(request); + if (ret != 0) { XFREE(request, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST); request = NULL; } + #ifdef WOLFSSL_SMALL_STACK XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT); #endif @@ -14264,7 +14281,14 @@ int CreateOcspResponse(WOLFSSL* ssl, OcspRequest** ocspRequest, } } - *ocspRequest = request; + /* free request up if error case found otherwise return it */ + if (ret != 0 && createdRequest) { + FreeOcspRequest(request); + XFREE(request, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST); + } + + if (ret == 0) + *ocspRequest = request; return ret; } @@ -14826,13 +14850,21 @@ int SendCertificateStatus(WOLFSSL* ssl) buffer response; ret = CreateOcspResponse(ssl, &request, &response); + + /* if a request was successfully created and not stored in + * ssl->ctx then free it */ + if (ret == 0 && request != ssl->ctx->certOcspRequest) { + FreeOcspRequest(request); + XFREE(request, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST); + request = NULL; + } + if (ret == 0 && response.buffer) { ret = BuildCertificateStatus(ssl, status_type, &response, 1); XFREE(response.buffer, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST); response.buffer = NULL; } - break; } @@ -14849,6 +14881,15 @@ int SendCertificateStatus(WOLFSSL* ssl) XMEMSET(responses, 0, sizeof(responses)); ret = CreateOcspResponse(ssl, &request, &responses[0]); + + /* if a request was successfully created and not stored in + * ssl->ctx then free it */ + if (ret == 0 && request != ssl->ctx->certOcspRequest) { + FreeOcspRequest(request); + XFREE(request, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST); + request = NULL; + } + if (ret == 0 && (!ssl->ctx->chainOcspRequest[0] || ssl->buffers.weOwnCertChain)) { buffer der; diff --git a/src/ocsp.c b/src/ocsp.c index 5a2bd9138..6afb8e458 100644 --- a/src/ocsp.c +++ b/src/ocsp.c @@ -199,6 +199,10 @@ static int GetOcspEntry(WOLFSSL_OCSP* ocsp, OcspRequest* request, } +/* Mallocs responseBuffer->buffer and is up to caller to free on success + * + * Returns OCSP status + */ static int GetOcspStatus(WOLFSSL_OCSP* ocsp, OcspRequest* request, OcspEntry* entry, CertStatus** status, buffer* responseBuffer) { @@ -452,6 +456,10 @@ int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest, request = (byte*)XMALLOC(requestSz, ocsp->cm->heap, DYNAMIC_TYPE_OCSP); if (request == NULL) { WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR); + if (responseBuffer) { + XFREE(responseBuffer->buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER); + responseBuffer->buffer = NULL; + } return MEMORY_ERROR; } @@ -474,6 +482,11 @@ int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest, if (response != NULL && ocsp->cm->ocspRespFreeCb) ocsp->cm->ocspRespFreeCb(ioCtx, response); + if (responseBuffer && ret != 0 ) { + XFREE(responseBuffer->buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER); + responseBuffer->buffer = NULL; + } + WOLFSSL_LEAVE("CheckOcspRequest", ret); return ret; }