Always try locale initialization from OPENSSL_strcasecmp
authorTomas Mraz <tomas@openssl.org>
Tue, 10 May 2022 15:22:24 +0000 (17:22 +0200)
committerTomas Mraz <tomas@openssl.org>
Fri, 13 May 2022 06:30:48 +0000 (08:30 +0200)
Fixes #18172

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/18282)

crypto/evp/evp_lib.c
crypto/init.c
crypto/o_str.c
include/internal/cryptlib.h

index c1793c95fd2517a8b7d444da62c08c54880d5212..89381f11c7aae60ec9399d45bbdc4dc39421947e 100644 (file)
@@ -1196,8 +1196,6 @@ EVP_PKEY *EVP_PKEY_Q_keygen(OSSL_LIB_CTX *libctx, const char *propq,
 
     va_start(args, type);
 
-    OPENSSL_init_crypto(OPENSSL_INIT_BASE_ONLY, NULL);
-
     if (OPENSSL_strcasecmp(type, "RSA") == 0) {
         bits = va_arg(args, size_t);
         params[0] = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_RSA_BITS, &bits);
index 8d51a1329b9859530d356c0a8ba5dc5978cfb78d..cca93df1a85c4091b17a22efff647fbf859765bf 100644 (file)
@@ -270,15 +270,6 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_async)
     return 1;
 }
 
-static CRYPTO_ONCE casecmp = CRYPTO_ONCE_STATIC_INIT;
-static int casecmp_inited = 0;
-DEFINE_RUN_ONCE_STATIC(ossl_init_casecmp)
-{
-    int ret = ossl_init_casecmp_int();
-
-    casecmp_inited = 1;
-    return ret;
-}
 #ifndef OPENSSL_NO_ENGINE
 static CRYPTO_ONCE engine_openssl = CRYPTO_ONCE_STATIC_INIT;
 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_openssl)
@@ -451,10 +442,8 @@ void OPENSSL_cleanup(void)
     OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_trace_cleanup()\n");
     ossl_trace_cleanup();
 
-    if (casecmp_inited) {
-        OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_deinit_casecmp()\n");
-        ossl_deinit_casecmp();
-    }
+    OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_deinit_casecmp()\n");
+    ossl_deinit_casecmp();
 
     base_inited = 0;
 }
@@ -468,9 +457,6 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
 {
     uint64_t tmp;
     int aloaddone = 0;
-    if (!RUN_ONCE(&casecmp, ossl_init_casecmp))
-        return 0;
-
 
    /* Applications depend on 0 being returned when cleanup was already done */
     if (stopped) {
@@ -498,6 +484,9 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
         aloaddone = 1;
     }
 
+    if (!ossl_init_casecmp())
+        return 0;
+
     /*
      * At some point we should look at this function with a view to moving
      * most/all of this into OSSL_LIB_CTX.
index d91ac8ff84ed7a6880a00dc46cf26a0f38891adc..40473a42a6ae3e99c4058e7a98ef1c5a50ad6fe8 100644 (file)
@@ -18,6 +18,7 @@
 #endif
 #include <openssl/crypto.h>
 #include "internal/cryptlib.h"
+#include "internal/thread_once.h"
 
 #define DEFAULT_SEPARATOR ':'
 #define CH_ZERO '\0'
@@ -347,13 +348,36 @@ int openssl_strerror_r(int errnum, char *buf, size_t buflen)
 }
 
 #ifndef OPENSSL_NO_LOCALE
+# ifndef FIPS_MODULE
+static CRYPTO_ONCE casecmp = CRYPTO_ONCE_STATIC_INIT;
+DEFINE_RUN_ONCE_STATIC(init_casecmp)
+{
+    int ret = ossl_init_casecmp_int();
+
+    return ret;
+}
+
+int ossl_init_casecmp(void)
+{
+    if (!RUN_ONCE(&casecmp, init_casecmp))
+        return 0;
+    return 1;
+}
+# endif
+
 static locale_t loc;
 
-static locale_t ossl_c_locale(void) {
+static locale_t ossl_c_locale(void)
+{
+# ifndef FIPS_MODULE
+    if (!ossl_init_casecmp())
+        return (locale_t)0;
+# endif
     return loc;
 }
 
-int ossl_init_casecmp_int(void) {
+int ossl_init_casecmp_int(void)
+{
 # ifdef OPENSSL_SYS_WINDOWS
     loc = _create_locale(LC_COLLATE, "C");
 # else
@@ -362,9 +386,12 @@ int ossl_init_casecmp_int(void) {
     return (loc == (locale_t)0) ? 0 : 1;
 }
 
-void ossl_deinit_casecmp(void) {
-    freelocale(loc);
-    loc = (locale_t)0;
+void ossl_deinit_casecmp(void)
+{
+    if (loc != (locale_t)0) {
+        freelocale(loc);
+        loc = (locale_t)0;
+    }
 }
 
 int OPENSSL_strcasecmp(const char *s1, const char *s2)
@@ -387,11 +414,18 @@ int OPENSSL_strncasecmp(const char *s1, const char *s2, size_t n)
     return strncasecmp_l(s1, s2, n, l);
 }
 #else
-int ossl_init_casecmp_int(void) {
+int ossl_init_casecmp(void)
+{
     return 1;
 }
 
-void ossl_deinit_casecmp(void) {
+int ossl_init_casecmp_int(void)
+{
+    return 1;
+}
+
+void ossl_deinit_casecmp(void)
+{
 }
 
 int OPENSSL_strcasecmp(const char *s1, const char *s2)
index 408924f5ddeda345154cf8f429fda88f58417dd8..ebb945f40cc2ea1d3747b95e03175f353545be0e 100644 (file)
@@ -158,5 +158,6 @@ char *ossl_buf2hexstr_sep(const unsigned char *buf, long buflen, char sep);
 unsigned char *ossl_hexstr2buf_sep(const char *str, long *buflen,
                                    const char sep);
 int ossl_init_casecmp_int(void);
+int ossl_init_casecmp(void);
 void ossl_deinit_casecmp(void);
 #endif