diff --git a/src/internal.c b/src/internal.c index b08e6f7715..4ba6013fe7 100644 --- a/src/internal.c +++ b/src/internal.c @@ -6803,9 +6803,35 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) #endif /* HAVE_RPK */ #ifndef NO_CERTS +#ifdef WOLFSSL_COPY_CERT + /* If WOLFSSL_COPY_CERT is defined, always copy the cert */ + if (ctx->certificate != NULL) { + ret = AllocCopyDer(&ssl->buffers.certificate, ctx->certificate->buffer, + ctx->certificate->length, ctx->certificate->type, + ctx->certificate->heap); + if (ret != 0) { + return ret; + } + + ssl->buffers.weOwnCert = 1; + ret = WOLFSSL_SUCCESS; + } + if (ctx->certChain != NULL) { + ret = AllocCopyDer(&ssl->buffers.certChain, ctx->certChain->buffer, + ctx->certChain->length, ctx->certChain->type, + ctx->certChain->heap); + if (ret != 0) { + return ret; + } + + ssl->buffers.weOwnCertChain = 1; + ret = WOLFSSL_SUCCESS; + } +#else /* ctx still owns certificate, certChain, key, dh, and cm */ ssl->buffers.certificate = ctx->certificate; ssl->buffers.certChain = ctx->certChain; +#endif #ifdef WOLFSSL_TLS13 ssl->buffers.certChainCnt = ctx->certChainCnt; #endif diff --git a/src/ssl.c b/src/ssl.c index afd505027a..594cc0ceee 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -20151,9 +20151,41 @@ WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx) ssl->ctx = ctx; #ifndef NO_CERTS +#ifdef WOLFSSL_COPY_CERT + /* If WOLFSSL_COPY_CERT defined, always make new copy of cert from ctx */ + if (ctx->certificate != NULL) { + if (ssl->buffers.certificate != NULL) { + FreeDer(&ssl->buffers.certificate); + } + ret = AllocCopyDer(&ssl->buffers.certificate, ctx->certificate->buffer, + ctx->certificate->length, ctx->certificate->type, + ctx->certificate->heap); + if (ret != 0) { + return NULL; + } + + ssl->buffers.weOwnCert = 1; + ret = WOLFSSL_SUCCESS; + } + if (ctx->certChain != NULL) { + if (ssl->buffers.certChain != NULL) { + FreeDer(&ssl->buffers.certChain); + } + ret = AllocCopyDer(&ssl->buffers.certChain, ctx->certChain->buffer, + ctx->certChain->length, ctx->certChain->type, + ctx->certChain->heap); + if (ret != 0) { + return NULL; + } + + ssl->buffers.weOwnCertChain = 1; + ret = WOLFSSL_SUCCESS; + } +#else /* ctx owns certificate, certChain and key */ ssl->buffers.certificate = ctx->certificate; ssl->buffers.certChain = ctx->certChain; +#endif #ifdef WOLFSSL_TLS13 ssl->buffers.certChainCnt = ctx->certChainCnt; #endif diff --git a/tests/api.c b/tests/api.c index 138f7fcdf9..6dc73cce8f 100644 --- a/tests/api.c +++ b/tests/api.c @@ -77500,9 +77500,18 @@ static int test_wolfSSL_set_SSL_CTX(void) #ifdef WOLFSSL_SESSION_ID_CTX ExpectIntEQ(XMEMCMP(ssl->sessionCtx, session_id2, 4), 0); #endif +#ifdef WOLFSSL_COPY_CERT + if (ctx2 != NULL && ctx2->certificate != NULL) { + ExpectFalse(ssl->buffers.certificate == ctx2->certificate); + } + if (ctx2 != NULL && ctx2->certChain != NULL) { + ExpectFalse(ssl->buffers.certChain == ctx2->certChain); + } +#else ExpectTrue(ssl->buffers.certificate == ctx2->certificate); ExpectTrue(ssl->buffers.certChain == ctx2->certChain); #endif +#endif #ifdef HAVE_SESSION_TICKET ExpectIntNE((wolfSSL_get_options(ssl) & SSL_OP_NO_TICKET), 0); @@ -77519,8 +77528,17 @@ static int test_wolfSSL_set_SSL_CTX(void) #endif /* MUST change */ #ifdef WOLFSSL_INT_H +#ifdef WOLFSSL_COPY_CERT + if (ctx1 != NULL && ctx1->certificate != NULL) { + ExpectFalse(ssl->buffers.certificate == ctx1->certificate); + } + if (ctx1 != NULL && ctx1->certChain != NULL) { + ExpectFalse(ssl->buffers.certChain == ctx1->certChain); + } +#else ExpectTrue(ssl->buffers.certificate == ctx1->certificate); ExpectTrue(ssl->buffers.certChain == ctx1->certChain); +#endif #ifdef WOLFSSL_SESSION_ID_CTX ExpectIntEQ(XMEMCMP(ssl->sessionCtx, session_id1, 4), 0); #endif diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 4415a8c7ac..ab068cff6b 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -3260,6 +3260,11 @@ extern void uITRON4_free(void *p) ; #define KEEP_PEER_CERT #endif +#if defined(OPENSSL_ALL) && !defined(WOLFSSL_NO_COPY_CERT) + #undef WOLFSSL_COPY_CERT + #define WOLFSSL_COPY_CERT +#endif + /* * Keeps the "Finished" messages after a TLS handshake for use as the so-called * "tls-unique" channel binding. See comment in internal.h around clientFinished