@@ -2377,6 +2377,35 @@ static int ProcessBufferResetSuites(WOLFSSL_CTX* ctx, WOLFSSL* ssl, int type)
23772377 ((type) == ALT_PRIVATEKEY_TYPE))
23782378#endif
23792379
2380+ /* Whether other objects still reference this context's shared buffers.
2381+ *
2382+ * Every WOLFSSL created from a context aliases the context's certificate, key
2383+ * and DH buffers and holds a reference on the context. A reference count above
2384+ * one therefore means such aliases exist, so those buffers must not be freed
2385+ * or replaced.
2386+ *
2387+ * @param [in] ctx SSL context object.
2388+ * @return 1 when the context is in use by other objects.
2389+ * @return 0 otherwise.
2390+ */
2391+ static int wolfssl_ctx_resources_in_use (WOLFSSL_CTX * ctx )
2392+ {
2393+ int inUse = 0 ;
2394+
2395+ if (ctx != NULL ) {
2396+ /* Block when the count can't be read so we never free a live alias. */
2397+ if (wolfSSL_RefWithMutexLock (& ctx -> ref ) != 0 ) {
2398+ inUse = 1 ;
2399+ }
2400+ else {
2401+ inUse = (ctx -> ref .count > 1 );
2402+ (void )wolfSSL_RefWithMutexUnlock (& ctx -> ref );
2403+ }
2404+ }
2405+
2406+ return inUse ;
2407+ }
2408+
23802409/* Process a buffer of data.
23812410 *
23822411 * Data type is a private key or a certificate.
@@ -2435,6 +2464,11 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, long sz,
24352464 if ((ret == 0 ) && (sz < 0 )) {
24362465 ret = BAD_FUNC_ARG ;
24372466 }
2467+ if ((ret == 0 ) && (ssl == NULL ) &&
2468+ ((type == CERT_TYPE ) || IS_PRIVKEY_TYPE (type )) &&
2469+ wolfssl_ctx_resources_in_use (ctx )) {
2470+ ret = CTX_BUSY_E ;
2471+ }
24382472
24392473#ifdef WOLFSSL_SMALL_STACK
24402474 if (ret == 0 ) {
@@ -3206,6 +3240,10 @@ int wolfSSL_CTX_use_certificate_file(WOLFSSL_CTX* ctx, const char* file,
32063240
32073241 WOLFSSL_ENTER ("wolfSSL_CTX_use_certificate_file" );
32083242
3243+ if (wolfssl_ctx_resources_in_use (ctx )) {
3244+ return CTX_BUSY_E ;
3245+ }
3246+
32093247 ret = ProcessFile (ctx , file , format , CERT_TYPE , NULL , 0 , NULL ,
32103248 GET_VERIFY_SETTING_CTX (ctx ));
32113249
@@ -3231,6 +3269,10 @@ int wolfSSL_CTX_use_PrivateKey_file(WOLFSSL_CTX* ctx, const char* file,
32313269
32323270 WOLFSSL_ENTER ("wolfSSL_CTX_use_PrivateKey_file" );
32333271
3272+ if (wolfssl_ctx_resources_in_use (ctx )) {
3273+ return CTX_BUSY_E ;
3274+ }
3275+
32343276 ret = ProcessFile (ctx , file , format , PRIVATEKEY_TYPE , NULL , 0 , NULL ,
32353277 GET_VERIFY_SETTING_CTX (ctx ));
32363278
@@ -3255,6 +3297,10 @@ int wolfSSL_CTX_use_AltPrivateKey_file(WOLFSSL_CTX* ctx, const char* file,
32553297
32563298 WOLFSSL_ENTER ("wolfSSL_CTX_use_AltPrivateKey_file" );
32573299
3300+ if (wolfssl_ctx_resources_in_use (ctx )) {
3301+ return CTX_BUSY_E ;
3302+ }
3303+
32583304 ret = ProcessFile (ctx , file , format , ALT_PRIVATEKEY_TYPE , NULL , 0 , NULL ,
32593305 GET_VERIFY_SETTING_CTX (ctx ));
32603306
@@ -3279,6 +3325,10 @@ int wolfSSL_CTX_use_certificate_chain_file(WOLFSSL_CTX* ctx, const char* file)
32793325 /* process up to MAX_CHAIN_DEPTH plus subject cert */
32803326 WOLFSSL_ENTER ("wolfSSL_CTX_use_certificate_chain_file" );
32813327
3328+ if (wolfssl_ctx_resources_in_use (ctx )) {
3329+ return CTX_BUSY_E ;
3330+ }
3331+
32823332#ifdef WOLFSSL_PEM_TO_DER
32833333 ret = ProcessFile (ctx , file , WOLFSSL_FILETYPE_PEM , CERT_TYPE , NULL , 1 , NULL ,
32843334 GET_VERIFY_SETTING_CTX (ctx ));
@@ -3309,6 +3359,10 @@ int wolfSSL_CTX_use_certificate_chain_file_format(WOLFSSL_CTX* ctx,
33093359
33103360 WOLFSSL_ENTER ("wolfSSL_CTX_use_certificate_chain_file_format" );
33113361
3362+ if (wolfssl_ctx_resources_in_use (ctx )) {
3363+ return CTX_BUSY_E ;
3364+ }
3365+
33123366 ret = ProcessFile (ctx , file , format , CERT_TYPE , NULL , 1 , NULL ,
33133367 GET_VERIFY_SETTING_CTX (ctx ));
33143368
@@ -4211,6 +4265,9 @@ int wolfSSL_CTX_use_PrivateKey_Id(WOLFSSL_CTX* ctx, const unsigned char* id,
42114265 if (ctx == NULL || id == NULL || sz < 0 ) {
42124266 return 0 ;
42134267 }
4268+ if (wolfssl_ctx_resources_in_use (ctx )) {
4269+ return CTX_BUSY_E ;
4270+ }
42144271
42154272 /* Dispose of old private key and allocate and copy in id. */
42164273 FreeDer (& ctx -> privateKey );
@@ -4287,6 +4344,9 @@ int wolfSSL_CTX_use_PrivateKey_Label(WOLFSSL_CTX* ctx, const char* label,
42874344 if (ctx == NULL || label == NULL ) {
42884345 return 0 ;
42894346 }
4347+ if (wolfssl_ctx_resources_in_use (ctx )) {
4348+ return CTX_BUSY_E ;
4349+ }
42904350
42914351 sz = (word32 )XSTRLEN (label ) + 1 ;
42924352
@@ -4330,6 +4390,9 @@ int wolfSSL_CTX_use_AltPrivateKey_Id(WOLFSSL_CTX* ctx, const unsigned char* id,
43304390 if ((ctx == NULL ) || (id == NULL ) || (sz < 0 )) {
43314391 ret = 0 ;
43324392 }
4393+ if ((ret == 1 ) && wolfssl_ctx_resources_in_use (ctx )) {
4394+ ret = CTX_BUSY_E ;
4395+ }
43334396
43344397 if (ret == 1 ) {
43354398 FreeDer (& ctx -> altPrivateKey );
@@ -4380,6 +4443,9 @@ int wolfSSL_CTX_use_AltPrivateKey_Label(WOLFSSL_CTX* ctx, const char* label,
43804443 if ((ctx == NULL ) || (label == NULL )) {
43814444 ret = 0 ;
43824445 }
4446+ if ((ret == 1 ) && wolfssl_ctx_resources_in_use (ctx )) {
4447+ ret = CTX_BUSY_E ;
4448+ }
43834449
43844450 if (ret == 1 ) {
43854451 sz = (word32 )XSTRLEN (label ) + 1 ;
@@ -4954,6 +5020,10 @@ static int wolfssl_ctx_add_to_chain(WOLFSSL_CTX* ctx, const byte* der,
49545020 int ret ;
49555021 DerBuffer * derBuffer = NULL ;
49565022
5023+ if (wolfssl_ctx_resources_in_use (ctx )) {
5024+ return CTX_BUSY_E ;
5025+ }
5026+
49575027 /* Create a DER buffer from DER encoding. */
49585028 ret = AllocCopyDer (& derBuffer , der , (word32 )derSz , CERT_TYPE , ctx -> heap );
49595029 if (ret != 0 ) {
@@ -5063,6 +5133,9 @@ int wolfSSL_CTX_use_certificate(WOLFSSL_CTX *ctx, WOLFSSL_X509 *x)
50635133 WOLFSSL_MSG ("Bad parameter" );
50645134 res = 0 ;
50655135 }
5136+ if ((res == 1 ) && wolfssl_ctx_resources_in_use (ctx )) {
5137+ res = CTX_BUSY_E ;
5138+ }
50665139
50675140 if (res == 1 ) {
50685141 /* Replace certificate buffer with one holding the new certificate. */
@@ -5305,6 +5378,9 @@ int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey)
53055378 if ((ctx == NULL ) || (pkey == NULL ) || (pkey -> pkey .ptr == NULL )) {
53065379 ret = 0 ;
53075380 }
5381+ if ((ret == 1 ) && wolfssl_ctx_resources_in_use (ctx )) {
5382+ ret = CTX_BUSY_E ;
5383+ }
53085384
53095385 if (ret == 1 ) {
53105386 switch (pkey -> type ) {
@@ -5376,6 +5452,9 @@ int wolfSSL_CTX_use_certificate_ASN1(WOLFSSL_CTX *ctx, int derSz,
53765452 if ((ctx == NULL ) || (der == NULL )) {
53775453 ret = 0 ;
53785454 }
5455+ if ((ret == 1 ) && wolfssl_ctx_resources_in_use (ctx )) {
5456+ ret = CTX_BUSY_E ;
5457+ }
53795458 /* Load DER encoded certificate into SSL context. */
53805459 if ((ret == 1 ) && (wolfSSL_CTX_use_certificate_buffer (ctx , der , derSz ,
53815460 WOLFSSL_FILETYPE_ASN1 ) != 1 )) {
@@ -5409,6 +5488,9 @@ int wolfSSL_CTX_use_RSAPrivateKey(WOLFSSL_CTX* ctx, WOLFSSL_RSA* rsa)
54095488 WOLFSSL_MSG ("one or more inputs were NULL" );
54105489 ret = BAD_FUNC_ARG ;
54115490 }
5491+ if ((ret == 1 ) && wolfssl_ctx_resources_in_use (ctx )) {
5492+ ret = CTX_BUSY_E ;
5493+ }
54125494
54135495 /* Get DER encoding size. */
54145496 if ((ret == 1 ) && ((derSize = wolfSSL_i2d_RSAPrivateKey (rsa , NULL )) <= 0 )) {
@@ -5752,6 +5834,10 @@ static int wolfssl_ctx_set_tmp_dh(WOLFSSL_CTX* ctx, unsigned char* p, int pSz,
57525834 if ((ctx == NULL ) || (p == NULL ) || (g == NULL ))
57535835 ret = BAD_FUNC_ARG ;
57545836
5837+ if ((ret == 1 ) && wolfssl_ctx_resources_in_use (ctx )) {
5838+ ret = CTX_BUSY_E ;
5839+ }
5840+
57555841 /* Check the size of the prime meets the requirements of the SSL context. */
57565842 if (ret == 1 ) {
57575843 if (((word16 )pSz < ctx -> minDhKeySz ) || ((word16 )pSz > ctx -> maxDhKeySz )) {
0 commit comments