mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-30 02:37:28 +02:00
Merge pull request #5884 from icing/ssl-set-ssl-ctx
Fix wolfSSL_set_SSL_CTX() to be usable during handshake.
This commit is contained in:
63
src/ssl.c
63
src/ssl.c
@ -31987,9 +31987,68 @@ const char * wolfSSL_get_servername(WOLFSSL* ssl, byte type)
|
||||
|
||||
WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
|
||||
{
|
||||
if (ssl && ctx && SetSSL_CTX(ssl, ctx, 0) == WOLFSSL_SUCCESS)
|
||||
/* This method requires some explanation. Its sibling is
|
||||
* int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
|
||||
* which re-inits the WOLFSSL* with all settings in the new CTX.
|
||||
* That one is the right one to use *before* a handshake is started.
|
||||
*
|
||||
* This method was added by OpenSSL to be used *during* the handshake, e.g.
|
||||
* when a server inspects the SNI in a ClientHello callback and
|
||||
* decides which set of certificates to use.
|
||||
*
|
||||
* Since, at the time the SNI callback is run, some decisions on
|
||||
* Extensions or the ServerHello might already have been taken, this
|
||||
* method is very restricted in what it does:
|
||||
* - changing the server certificate(s)
|
||||
* - changing the server id for session handling
|
||||
* and everything else in WOLFSSL* needs to remain untouched.
|
||||
*/
|
||||
WOLFSSL_ENTER("wolfSSL_set_SSL_CTX");
|
||||
if (ssl == NULL || ctx == NULL)
|
||||
return NULL;
|
||||
if (ssl->ctx == ctx)
|
||||
return ssl->ctx;
|
||||
return NULL;
|
||||
|
||||
if (SSL_CTX_RefCount(ctx, 1) < 0) {
|
||||
/* can only fail on serious stuff, like mutex not working
|
||||
* or ctx refcount out of whack. */
|
||||
return NULL;
|
||||
}
|
||||
if (ssl->ctx) {
|
||||
wolfSSL_CTX_free(ssl->ctx);
|
||||
}
|
||||
ssl->ctx = ctx;
|
||||
|
||||
#ifndef NO_CERTS
|
||||
/* ctx owns certificate, certChain and key */
|
||||
ssl->buffers.certificate = ctx->certificate;
|
||||
ssl->buffers.certChain = ctx->certChain;
|
||||
#ifdef WOLFSSL_TLS13
|
||||
ssl->buffers.certChainCnt = ctx->certChainCnt;
|
||||
#endif
|
||||
ssl->buffers.key = ctx->privateKey;
|
||||
ssl->buffers.keyType = ctx->privateKeyType;
|
||||
ssl->buffers.keyId = ctx->privateKeyId;
|
||||
ssl->buffers.keyLabel = ctx->privateKeyLabel;
|
||||
ssl->buffers.keySz = ctx->privateKeySz;
|
||||
ssl->buffers.keyDevId = ctx->privateKeyDevId;
|
||||
/* flags indicating what certs/keys are available */
|
||||
ssl->options.haveRSA = ctx->haveRSA;
|
||||
ssl->options.haveDH = ctx->haveDH;
|
||||
ssl->options.haveECDSAsig = ctx->haveECDSAsig;
|
||||
ssl->options.haveECC = ctx->haveECC;
|
||||
ssl->options.haveStaticECC = ctx->haveStaticECC;
|
||||
ssl->options.haveFalconSig = ctx->haveFalconSig;
|
||||
ssl->options.haveDilithiumSig = ctx->haveDilithiumSig;
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_EXTRA
|
||||
/* copy over application session context ID */
|
||||
ssl->sessionCtxSz = ctx->sessionCtxSz;
|
||||
XMEMCPY(ssl->sessionCtx, ctx->sessionCtx, ctx->sessionCtxSz);
|
||||
#endif
|
||||
|
||||
return ssl->ctx;
|
||||
}
|
||||
|
||||
|
||||
|
93
tests/api.c
93
tests/api.c
@ -57299,6 +57299,93 @@ static int test_wolfSSL_CTX_get_min_proto_version(void)
|
||||
return res;
|
||||
}
|
||||
|
||||
#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
|
||||
(defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
|
||||
defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
|
||||
defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB)))
|
||||
static int test_wolfSSL_set_SSL_CTX(void)
|
||||
{
|
||||
int res = TEST_SKIPPED;
|
||||
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) \
|
||||
&& !defined(WOLFSSL_NO_TLS12) && defined(WOLFSSL_TLS13)
|
||||
WOLFSSL_CTX *ctx1, *ctx2;
|
||||
WOLFSSL *ssl;
|
||||
const byte *session_id1 = (const byte *)"CTX1";
|
||||
const byte *session_id2 = (const byte *)"CTX2";
|
||||
|
||||
AssertNotNull(ctx1 = wolfSSL_CTX_new(wolfTLS_server_method()));
|
||||
AssertTrue(wolfSSL_CTX_use_certificate_file(ctx1, svrCertFile,
|
||||
WOLFSSL_FILETYPE_PEM));
|
||||
AssertTrue(wolfSSL_CTX_use_PrivateKey_file(ctx1, svrKeyFile,
|
||||
WOLFSSL_FILETYPE_PEM));
|
||||
AssertIntEQ(wolfSSL_CTX_set_min_proto_version(ctx1, TLS1_2_VERSION),
|
||||
WOLFSSL_SUCCESS);
|
||||
AssertIntEQ(wolfSSL_CTX_get_min_proto_version(ctx1), TLS1_2_VERSION);
|
||||
AssertIntEQ(wolfSSL_CTX_get_max_proto_version(ctx1), TLS1_3_VERSION);
|
||||
AssertIntEQ(wolfSSL_CTX_set_session_id_context(ctx1, session_id1, 4),
|
||||
WOLFSSL_SUCCESS);
|
||||
|
||||
AssertNotNull(ctx2 = wolfSSL_CTX_new(wolfTLS_server_method()));
|
||||
AssertTrue(wolfSSL_CTX_use_certificate_file(ctx2, svrCertFile,
|
||||
WOLFSSL_FILETYPE_PEM));
|
||||
AssertTrue(wolfSSL_CTX_use_PrivateKey_file(ctx2, svrKeyFile,
|
||||
WOLFSSL_FILETYPE_PEM));
|
||||
AssertIntEQ(wolfSSL_CTX_set_min_proto_version(ctx2, TLS1_2_VERSION),
|
||||
WOLFSSL_SUCCESS);
|
||||
AssertIntEQ(wolfSSL_CTX_set_max_proto_version(ctx2, TLS1_2_VERSION),
|
||||
WOLFSSL_SUCCESS);
|
||||
AssertIntEQ(wolfSSL_CTX_get_min_proto_version(ctx2), TLS1_2_VERSION);
|
||||
AssertIntEQ(wolfSSL_CTX_get_max_proto_version(ctx2), TLS1_2_VERSION);
|
||||
AssertIntEQ(wolfSSL_CTX_set_session_id_context(ctx2, session_id2, 4),
|
||||
WOLFSSL_SUCCESS);
|
||||
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
AssertIntEQ((wolfSSL_CTX_get_options(ctx1) & SSL_OP_NO_TICKET), 0);
|
||||
wolfSSL_CTX_set_options(ctx2, SSL_OP_NO_TICKET);
|
||||
AssertIntNE((wolfSSL_CTX_get_options(ctx2) & SSL_OP_NO_TICKET), 0);
|
||||
#endif
|
||||
|
||||
AssertNotNull(ssl = wolfSSL_new(ctx2));
|
||||
AssertIntNE((wolfSSL_get_options(ssl) & WOLFSSL_OP_NO_TLSv1_3), 0);
|
||||
#ifdef WOLFSSL_INT_H
|
||||
AssertIntEQ(XMEMCMP(ssl->sessionCtx, session_id2, 4), 0);
|
||||
AssertTrue(ssl->buffers.certificate == ctx2->certificate);
|
||||
AssertTrue(ssl->buffers.certChain == ctx2->certChain);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
AssertIntNE((wolfSSL_get_options(ssl) & SSL_OP_NO_TICKET), 0);
|
||||
#endif
|
||||
|
||||
/* Set the ctx1 that has TLSv1.3 as max proto version */
|
||||
AssertNotNull(wolfSSL_set_SSL_CTX(ssl, ctx1));
|
||||
|
||||
/* MUST not change proto versions of ssl */
|
||||
AssertIntNE((wolfSSL_get_options(ssl) & WOLFSSL_OP_NO_TLSv1_3), 0);
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
/* MUST not change */
|
||||
AssertIntNE((wolfSSL_get_options(ssl) & SSL_OP_NO_TICKET), 0);
|
||||
#endif
|
||||
/* MUST change */
|
||||
#ifdef WOLFSSL_INT_H
|
||||
AssertTrue(ssl->buffers.certificate == ctx1->certificate);
|
||||
AssertTrue(ssl->buffers.certChain == ctx1->certChain);
|
||||
AssertIntEQ(XMEMCMP(ssl->sessionCtx, session_id1, 4), 0);
|
||||
#endif
|
||||
|
||||
wolfSSL_free(ssl);
|
||||
wolfSSL_CTX_free(ctx1);
|
||||
wolfSSL_CTX_free(ctx2);
|
||||
|
||||
res = TEST_RES_CHECK(1);
|
||||
#endif /* defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) */
|
||||
return res;
|
||||
}
|
||||
#endif /* defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
|
||||
(defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
|
||||
defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
|
||||
defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB))) */
|
||||
|
||||
static int test_wolfSSL_security_level(void)
|
||||
{
|
||||
int res = TEST_SKIPPED;
|
||||
@ -60062,6 +60149,12 @@ TEST_CASE testCases[] = {
|
||||
#endif
|
||||
|
||||
TEST_DECL(test_wolfSSL_CTX_get_min_proto_version),
|
||||
#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
|
||||
(defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
|
||||
defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
|
||||
defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB)))
|
||||
TEST_DECL(test_wolfSSL_set_SSL_CTX),
|
||||
#endif
|
||||
|
||||
TEST_DECL(test_wolfSSL_security_level),
|
||||
TEST_DECL(test_wolfSSL_SSL_in_init),
|
||||
|
Reference in New Issue
Block a user