memory management with OCSP requests

This commit is contained in:
Jacob Barthelmeh 2019-01-14 09:49:50 -07:00
parent 141b263546
commit 6ac384793f
4 changed files with 88 additions and 10 deletions

View File

@ -984,7 +984,13 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
myVerifyFail = 1; myVerifyFail = 1;
} }
else if (XSTRNCMP(myoptarg, "loadSSL", 7) == 0) { 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 #ifndef NO_CERTS
loadCertKeyIntoSSLObj = 1; loadCertKeyIntoSSLObj = 1;
#endif #endif
@ -1387,7 +1393,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
#endif #endif
#if !defined(NO_CERTS) #if !defined(NO_CERTS)
if ((!usePsk || usePskPlus) && !useAnon && !loadCertKeyIntoSSLObj) { if ((!usePsk || usePskPlus) && !useAnon && !(loadCertKeyIntoSSLObj == 1)) {
#ifndef TEST_LOAD_BUFFER #ifndef TEST_LOAD_BUFFER
if (SSL_CTX_use_certificate_chain_file(ctx, ourCert) if (SSL_CTX_use_certificate_chain_file(ctx, ourCert)
!= WOLFSSL_SUCCESS) != WOLFSSL_SUCCESS)
@ -1428,7 +1434,8 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
#ifdef HAVE_PK_CALLBACKS #ifdef HAVE_PK_CALLBACKS
pkCbInfo.ourKey = ourKey; pkCbInfo.ourKey = ourKey;
#endif #endif
if (!useNtruKey && (!usePsk || usePskPlus) && !useAnon && !loadCertKeyIntoSSLObj if (!useNtruKey && (!usePsk || usePskPlus) && !useAnon
&& !(loadCertKeyIntoSSLObj == 1)
#if defined(HAVE_PK_CALLBACKS) && defined(TEST_PK_PRIVKEY) #if defined(HAVE_PK_CALLBACKS) && defined(TEST_PK_PRIVKEY)
&& !pkCallbacks && !pkCallbacks
#endif /* HAVE_PK_CALLBACKS && TEST_PK_PRIVKEY */ #endif /* HAVE_PK_CALLBACKS && TEST_PK_PRIVKEY */

View File

@ -354,6 +354,23 @@ CLI_PORT=`cat $ready_file5`
RESULT=$? RESULT=$?
[ $RESULT -ne 1 ] && printf '\n\n%s\n' "Client connection suceeded $RESULT" && exit 1 [ $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 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 ---------------------------" printf '%s\n\n' "------------------- TESTS COMPLETE ---------------------------"
exit 0 exit 0

View File

@ -14163,6 +14163,11 @@ int SendFinished(WOLFSSL* ssl)
(defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \ (defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2))) || \ defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2))) || \
(defined(WOLFSSL_TLS13) && defined(HAVE_CERTIFICATE_STATUS_REQUEST)) (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, static int CreateOcspRequest(WOLFSSL* ssl, OcspRequest* request,
DecodedCert* cert, byte* certData, word32 length) 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, int CreateOcspResponse(WOLFSSL* ssl, OcspRequest** ocspRequest,
buffer* response) buffer* response)
{ {
int ret = 0; int ret = 0;
OcspRequest* request; OcspRequest* request = NULL;
byte createdRequest = 0;
if (ssl == NULL || ocspRequest == NULL || response == NULL) if (ssl == NULL || ocspRequest == NULL || response == NULL)
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
request = *ocspRequest;
XMEMSET(response, 0, sizeof(*response)); XMEMSET(response, 0, sizeof(*response));
request = *ocspRequest;
/* unable to fetch status. skip. */ /* unable to fetch status. skip. */
if (ssl->ctx->cm == NULL || ssl->ctx->cm->ocspStaplingEnabled == 0) if (ssl->ctx->cm == NULL || ssl->ctx->cm->ocspStaplingEnabled == 0)
@ -14237,16 +14253,17 @@ int CreateOcspResponse(WOLFSSL* ssl, OcspRequest** ocspRequest,
if (request == NULL) if (request == NULL)
ret = MEMORY_E; ret = MEMORY_E;
createdRequest = 1;
if (ret == 0) { if (ret == 0) {
ret = CreateOcspRequest(ssl, request, cert, der->buffer, ret = CreateOcspRequest(ssl, request, cert, der->buffer,
der->length); der->length);
} }
if (request != NULL && ret != 0) { if (ret != 0) {
FreeOcspRequest(request);
XFREE(request, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST); XFREE(request, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST);
request = NULL; request = NULL;
} }
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT); XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT);
#endif #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; return ret;
} }
@ -14826,13 +14850,21 @@ int SendCertificateStatus(WOLFSSL* ssl)
buffer response; buffer response;
ret = CreateOcspResponse(ssl, &request, &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) { if (ret == 0 && response.buffer) {
ret = BuildCertificateStatus(ssl, status_type, &response, 1); ret = BuildCertificateStatus(ssl, status_type, &response, 1);
XFREE(response.buffer, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST); XFREE(response.buffer, ssl->heap, DYNAMIC_TYPE_OCSP_REQUEST);
response.buffer = NULL; response.buffer = NULL;
} }
break; break;
} }
@ -14849,6 +14881,15 @@ int SendCertificateStatus(WOLFSSL* ssl)
XMEMSET(responses, 0, sizeof(responses)); XMEMSET(responses, 0, sizeof(responses));
ret = CreateOcspResponse(ssl, &request, &responses[0]); 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] if (ret == 0 && (!ssl->ctx->chainOcspRequest[0]
|| ssl->buffers.weOwnCertChain)) { || ssl->buffers.weOwnCertChain)) {
buffer der; buffer der;

View File

@ -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, static int GetOcspStatus(WOLFSSL_OCSP* ocsp, OcspRequest* request,
OcspEntry* entry, CertStatus** status, buffer* responseBuffer) 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); request = (byte*)XMALLOC(requestSz, ocsp->cm->heap, DYNAMIC_TYPE_OCSP);
if (request == NULL) { if (request == NULL) {
WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR); WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
if (responseBuffer) {
XFREE(responseBuffer->buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
responseBuffer->buffer = NULL;
}
return MEMORY_ERROR; return MEMORY_ERROR;
} }
@ -474,6 +482,11 @@ int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest,
if (response != NULL && ocsp->cm->ocspRespFreeCb) if (response != NULL && ocsp->cm->ocspRespFreeCb)
ocsp->cm->ocspRespFreeCb(ioCtx, response); ocsp->cm->ocspRespFreeCb(ioCtx, response);
if (responseBuffer && ret != 0 ) {
XFREE(responseBuffer->buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
responseBuffer->buffer = NULL;
}
WOLFSSL_LEAVE("CheckOcspRequest", ret); WOLFSSL_LEAVE("CheckOcspRequest", ret);
return ret; return ret;
} }