Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion doc/dox_comments/header_files/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,8 @@ int wolfSSL_is_static_memory(WOLFSSL* ssl,
given using the “format” argument, file doesn’t exist, can’t be read,
or is corrupted, an out of memory condition occurs, Base16 decoding
fails on the file.
\return CTX_BUSY_E if any WOLFSSL session created from this context is
still active; see the note below.

\param ctx a pointer to a WOLFSSL_CTX structure, created using
wolfSSL_CTX_new()
Expand All @@ -1048,9 +1050,17 @@ int wolfSSL_is_static_memory(WOLFSSL* ssl,
...
\endcode

\note The context certificate is shared with every WOLFSSL session created
from it, so this function refuses to change it while any such session is
active and returns CTX_BUSY_E. Load the certificate before creating
sessions. To set a certificate for one connection, call
wolfSSL_use_certificate_file() on the WOLFSSL object, or switch the session
to a preconfigured context with wolfSSL_set_SSL_CTX().

\sa wolfSSL_CTX_use_certificate_buffer
\sa wolfSSL_use_certificate_file
\sa wolfSSL_use_certificate_buffer
\sa wolfSSL_set_SSL_CTX
*/
int wolfSSL_CTX_use_certificate_file(WOLFSSL_CTX* ctx, const char* file,
int format);
Expand All @@ -1077,6 +1087,8 @@ int wolfSSL_CTX_use_certificate_file(WOLFSSL_CTX* ctx, const char* file,
be read, or is corrupted. An out of memory condition occurs. Base16
decoding fails on the file. The key file is encrypted but no password
is provided.
\return CTX_BUSY_E if any WOLFSSL session created from this context is
still active; see the note below.

\param ctx pointer to a WOLFSSL_CTX structure.
\param file path to the private key file.
Expand All @@ -1096,11 +1108,19 @@ int wolfSSL_CTX_use_certificate_file(WOLFSSL_CTX* ctx, const char* file,
...
\endcode

\note The context private key is shared with every WOLFSSL session created
from it (the server signs with it), so this function refuses to change it
while any such session is active and returns CTX_BUSY_E. Load the key
before creating sessions. To set a key for one connection, call
wolfSSL_use_PrivateKey_file() on the WOLFSSL object, or switch the session
to a preconfigured context with wolfSSL_set_SSL_CTX().

\sa wolfSSL_CTX_use_PrivateKey_buffer
\sa wolfSSL_use_PrivateKey_file
\sa wolfSSL_use_PrivateKey_buffer
\sa wc_CryptoCb_RegisterDevice
\sa wolfSSL_CTX_SetDevId
\sa wolfSSL_set_SSL_CTX
*/
int wolfSSL_CTX_use_PrivateKey_file(WOLFSSL_CTX* ctx, const char* file, int format);

Expand Down Expand Up @@ -1543,9 +1563,15 @@ long wolfSSL_CTX_get_verify_depth(WOLFSSL_CTX* ctx);
...
\endcode

\note This updates the WOLFSSL session's own buffers and does not touch the
shared WOLFSSL_CTX, so unlike wolfSSL_CTX_use_certificate_file() it is safe
to call while other sessions are active, including from the SNI (server
name) callback to set a certificate for the current connection.

\sa wolfSSL_CTX_use_certificate_buffer
\sa wolfSSL_CTX_use_certificate_file
\sa wolfSSL_use_certificate_buffer
\sa wolfSSL_set_SSL_CTX
*/
int wolfSSL_use_certificate_file(WOLFSSL* ssl, const char* file, int format);

Expand Down Expand Up @@ -1591,11 +1617,17 @@ int wolfSSL_use_certificate_file(WOLFSSL* ssl, const char* file, int format);
...
\endcode

\note This updates the WOLFSSL session's own buffers and does not touch the
shared WOLFSSL_CTX, so unlike wolfSSL_CTX_use_PrivateKey_file() it is safe
to call while other sessions are active, including from the SNI (server
name) callback to set a private key for the current connection.

\sa wolfSSL_CTX_use_PrivateKey_buffer
\sa wolfSSL_CTX_use_PrivateKey_file
\sa wolfSSL_use_PrivateKey_buffer
\sa wc_CryptoCb_RegisterDevice
\sa wolfSSL_SetDevId
\sa wolfSSL_set_SSL_CTX
*/
int wolfSSL_use_PrivateKey_file(WOLFSSL* ssl, const char* file, int format);

Expand Down Expand Up @@ -7707,6 +7739,9 @@ int wolfSSL_SetTmpDH_file(WOLFSSL* ssl, const char* f, int format);
than the value of the maxDhKeySz member of the WOLFSSL_CTX struct.
\return MEMORY_E returned if the allocation of memory failed in this
function or a subroutine.
\return CTX_BUSY_E returned if any WOLFSSL session created from this context
is still active; the shared DH parameters cannot be changed then. Set them
before creating sessions, or use wolfSSL_SetTmpDH() on the WOLFSSL object.

\param ctx a pointer to a WOLFSSL_CTX structure, created using
wolfSSL_CTX_new().
Expand Down Expand Up @@ -8237,7 +8272,8 @@ int wolfSSL_CTX_UnloadCAs(WOLFSSL_CTX* ctx);
\return SSL_SUCCESS returned on successful execution of the function.
\return BAD_FUNC_ARG returned if the WOLFSSL_CTX struct is NULL or there
are otherwise unpermitted argument values passed in a subroutine.
\return BAD_STATE_E returned if the WOLFSSL_CTX has a reference count > 1.
\return CTX_BUSY_E returned if the WOLFSSL_CTX has a reference count > 1
(active sessions exist).
\return BAD_MUTEX_E returned if there was a mutex error. The LockMutex()
did not return 0.

Expand Down
3 changes: 3 additions & 0 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -29047,6 +29047,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)

case RPK_UNTRUSTED_E:
return "RFC 7250 Raw Public Key not trusted";

case CTX_BUSY_E:
return "Context in use by active sessions, operation not allowed";
}

return "unknown error number";
Expand Down
4 changes: 4 additions & 0 deletions src/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -12830,6 +12830,10 @@ long wolfSSL_CTX_ctrl(WOLFSSL_CTX* ctx, int cmd, long opt, void* pt)
ret = WOLFSSL_FAILURE;
break;
}
if (wolfssl_ctx_resources_in_use(ctx)) {
ret = CTX_BUSY_E;
break;
}
/* Clear certificate chain */
FreeDer(&ctx->certChain);
if (sk) {
Expand Down
2 changes: 1 addition & 1 deletion src/ssl_api_cert.c
Original file line number Diff line number Diff line change
Expand Up @@ -1065,7 +1065,7 @@ int wolfSSL_CTX_UnloadIntermediateCerts(WOLFSSL_CTX* ctx)
if (ctx->ref.count > 1) {
WOLFSSL_MSG("ctx object must have a ref count of 1 before "
"unloading intermediate certs");
ret = BAD_STATE_E;
ret = CTX_BUSY_E;
}
else {
ret = wolfSSL_CertManagerUnloadIntermediateCerts(ctx->cm);
Expand Down
86 changes: 86 additions & 0 deletions src/ssl_load.c
Original file line number Diff line number Diff line change
Expand Up @@ -2377,6 +2377,35 @@ static int ProcessBufferResetSuites(WOLFSSL_CTX* ctx, WOLFSSL* ssl, int type)
((type) == ALT_PRIVATEKEY_TYPE))
#endif

/* Whether other objects still reference this context's shared buffers.
*
* Every WOLFSSL created from a context aliases the context's certificate, key
* and DH buffers and holds a reference on the context. A reference count above
* one therefore means such aliases exist, so those buffers must not be freed
* or replaced.
*
* @param [in] ctx SSL context object.
* @return 1 when the context is in use by other objects.
* @return 0 otherwise.
*/
static int wolfssl_ctx_resources_in_use(WOLFSSL_CTX* ctx)
{
int inUse = 0;

if (ctx != NULL) {
/* Block when the count can't be read so we never free a live alias. */
if (wolfSSL_RefWithMutexLock(&ctx->ref) != 0) {
inUse = 1;
}
else {
inUse = (ctx->ref.count > 1);
(void)wolfSSL_RefWithMutexUnlock(&ctx->ref);
}
}

return inUse;
}

/* Process a buffer of data.
*
* Data type is a private key or a certificate.
Expand Down Expand Up @@ -2435,6 +2464,11 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, long sz,
if ((ret == 0) && (sz < 0)) {
ret = BAD_FUNC_ARG;
}
if ((ret == 0) && (ssl == NULL) &&
((type == CERT_TYPE) || IS_PRIVKEY_TYPE(type)) &&
wolfssl_ctx_resources_in_use(ctx)) {
ret = CTX_BUSY_E;
}

#ifdef WOLFSSL_SMALL_STACK
if (ret == 0) {
Expand Down Expand Up @@ -3206,6 +3240,10 @@ int wolfSSL_CTX_use_certificate_file(WOLFSSL_CTX* ctx, const char* file,

WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_file");

if (wolfssl_ctx_resources_in_use(ctx)) {
return CTX_BUSY_E;
}

ret = ProcessFile(ctx, file, format, CERT_TYPE, NULL, 0, NULL,
GET_VERIFY_SETTING_CTX(ctx));

Expand All @@ -3231,6 +3269,10 @@ int wolfSSL_CTX_use_PrivateKey_file(WOLFSSL_CTX* ctx, const char* file,

WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_file");

if (wolfssl_ctx_resources_in_use(ctx)) {
return CTX_BUSY_E;
}

ret = ProcessFile(ctx, file, format, PRIVATEKEY_TYPE, NULL, 0, NULL,
GET_VERIFY_SETTING_CTX(ctx));

Expand All @@ -3255,6 +3297,10 @@ int wolfSSL_CTX_use_AltPrivateKey_file(WOLFSSL_CTX* ctx, const char* file,

WOLFSSL_ENTER("wolfSSL_CTX_use_AltPrivateKey_file");

if (wolfssl_ctx_resources_in_use(ctx)) {
return CTX_BUSY_E;
}

ret = ProcessFile(ctx, file, format, ALT_PRIVATEKEY_TYPE, NULL, 0, NULL,
GET_VERIFY_SETTING_CTX(ctx));

Expand All @@ -3279,6 +3325,10 @@ int wolfSSL_CTX_use_certificate_chain_file(WOLFSSL_CTX* ctx, const char* file)
/* process up to MAX_CHAIN_DEPTH plus subject cert */
WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_file");

if (wolfssl_ctx_resources_in_use(ctx)) {
return CTX_BUSY_E;
}

#ifdef WOLFSSL_PEM_TO_DER
ret = ProcessFile(ctx, file, WOLFSSL_FILETYPE_PEM, CERT_TYPE, NULL, 1, NULL,
GET_VERIFY_SETTING_CTX(ctx));
Expand Down Expand Up @@ -3309,6 +3359,10 @@ int wolfSSL_CTX_use_certificate_chain_file_format(WOLFSSL_CTX* ctx,

WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_file_format");

if (wolfssl_ctx_resources_in_use(ctx)) {
return CTX_BUSY_E;
}

ret = ProcessFile(ctx, file, format, CERT_TYPE, NULL, 1, NULL,
GET_VERIFY_SETTING_CTX(ctx));

Expand Down Expand Up @@ -4211,6 +4265,9 @@ int wolfSSL_CTX_use_PrivateKey_Id(WOLFSSL_CTX* ctx, const unsigned char* id,
if (ctx == NULL || id == NULL || sz < 0) {
return 0;
}
if (wolfssl_ctx_resources_in_use(ctx)) {
return CTX_BUSY_E;
}

/* Dispose of old private key and allocate and copy in id. */
FreeDer(&ctx->privateKey);
Expand Down Expand Up @@ -4287,6 +4344,9 @@ int wolfSSL_CTX_use_PrivateKey_Label(WOLFSSL_CTX* ctx, const char* label,
if (ctx == NULL || label == NULL) {
return 0;
}
if (wolfssl_ctx_resources_in_use(ctx)) {
return CTX_BUSY_E;
}

sz = (word32)XSTRLEN(label) + 1;

Expand Down Expand Up @@ -4330,6 +4390,9 @@ int wolfSSL_CTX_use_AltPrivateKey_Id(WOLFSSL_CTX* ctx, const unsigned char* id,
if ((ctx == NULL) || (id == NULL) || (sz < 0)) {
ret = 0;
}
if ((ret == 1) && wolfssl_ctx_resources_in_use(ctx)) {
ret = CTX_BUSY_E;
}

if (ret == 1) {
FreeDer(&ctx->altPrivateKey);
Expand Down Expand Up @@ -4380,6 +4443,9 @@ int wolfSSL_CTX_use_AltPrivateKey_Label(WOLFSSL_CTX* ctx, const char* label,
if ((ctx == NULL) || (label == NULL)) {
ret = 0;
}
if ((ret == 1) && wolfssl_ctx_resources_in_use(ctx)) {
ret = CTX_BUSY_E;
}

if (ret == 1) {
sz = (word32)XSTRLEN(label) + 1;
Expand Down Expand Up @@ -4954,6 +5020,10 @@ static int wolfssl_ctx_add_to_chain(WOLFSSL_CTX* ctx, const byte* der,
int ret;
DerBuffer* derBuffer = NULL;

if (wolfssl_ctx_resources_in_use(ctx)) {
return CTX_BUSY_E;
}

/* Create a DER buffer from DER encoding. */
ret = AllocCopyDer(&derBuffer, der, (word32)derSz, CERT_TYPE, ctx->heap);
if (ret != 0) {
Expand Down Expand Up @@ -5063,6 +5133,9 @@ int wolfSSL_CTX_use_certificate(WOLFSSL_CTX *ctx, WOLFSSL_X509 *x)
WOLFSSL_MSG("Bad parameter");
res = 0;
}
if ((res == 1) && wolfssl_ctx_resources_in_use(ctx)) {
res = CTX_BUSY_E;
}

if (res == 1) {
/* Replace certificate buffer with one holding the new certificate. */
Expand Down Expand Up @@ -5305,6 +5378,9 @@ int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey)
if ((ctx == NULL) || (pkey == NULL) || (pkey->pkey.ptr == NULL)) {
ret = 0;
}
if ((ret == 1) && wolfssl_ctx_resources_in_use(ctx)) {
ret = CTX_BUSY_E;
}

if (ret == 1) {
switch (pkey->type) {
Expand Down Expand Up @@ -5376,6 +5452,9 @@ int wolfSSL_CTX_use_certificate_ASN1(WOLFSSL_CTX *ctx, int derSz,
if ((ctx == NULL) || (der == NULL)) {
ret = 0;
}
if ((ret == 1) && wolfssl_ctx_resources_in_use(ctx)) {
ret = CTX_BUSY_E;
}
/* Load DER encoded certificate into SSL context. */
if ((ret == 1) && (wolfSSL_CTX_use_certificate_buffer(ctx, der, derSz,
WOLFSSL_FILETYPE_ASN1) != 1)) {
Expand Down Expand Up @@ -5409,6 +5488,9 @@ int wolfSSL_CTX_use_RSAPrivateKey(WOLFSSL_CTX* ctx, WOLFSSL_RSA* rsa)
WOLFSSL_MSG("one or more inputs were NULL");
ret = BAD_FUNC_ARG;
}
if ((ret == 1) && wolfssl_ctx_resources_in_use(ctx)) {
ret = CTX_BUSY_E;
}

/* Get DER encoding size. */
if ((ret == 1) && ((derSize = wolfSSL_i2d_RSAPrivateKey(rsa, NULL)) <= 0)) {
Expand Down Expand Up @@ -5752,6 +5834,10 @@ static int wolfssl_ctx_set_tmp_dh(WOLFSSL_CTX* ctx, unsigned char* p, int pSz,
if ((ctx == NULL) || (p == NULL) || (g == NULL))
ret = BAD_FUNC_ARG;

if ((ret == 1) && wolfssl_ctx_resources_in_use(ctx)) {
ret = CTX_BUSY_E;
}

/* Check the size of the prime meets the requirements of the SSL context. */
if (ret == 1) {
if (((word16)pSz < ctx->minDhKeySz) || ((word16)pSz > ctx->maxDhKeySz)) {
Expand Down
Loading
Loading