summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorDmitry Belyavskiy <beldmit@gmail.com>2022-04-13 12:32:14 +0200
committerDmitry Belyavskiy <beldmit@gmail.com>2022-04-21 17:12:31 +0200
commit130de70e0f85ecec08fcfe4daed1d0c491089ea6 (patch)
tree2a0da8004ede970436f3888d632c42f09ecdbb93 /crypto
parent455e158ef9b3b600738f5b01190c2b7083d3d0ba (diff)
Public API functions OPENSSL_str[n]casecmp
Reviewed-by: Tim Hudson <tjh@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/18103)
Diffstat (limited to 'crypto')
-rw-r--r--crypto/context.c4
-rw-r--r--crypto/ctype.c100
-rw-r--r--crypto/init.c7
3 files changed, 110 insertions, 1 deletions
diff --git a/crypto/context.c b/crypto/context.c
index 3333af4c53..4fef24cadd 100644
--- a/crypto/context.c
+++ b/crypto/context.c
@@ -14,6 +14,7 @@
#include "internal/core.h"
#include "internal/bio.h"
#include "internal/provider.h"
+#include "crypto/ctype.h"
struct ossl_lib_ctx_onfree_list_st {
ossl_lib_ctx_onfree_fn *fn;
@@ -150,7 +151,8 @@ static CRYPTO_THREAD_LOCAL default_context_thread_local;
DEFINE_RUN_ONCE_STATIC(default_context_do_init)
{
return CRYPTO_THREAD_init_local(&default_context_thread_local, NULL)
- && context_init(&default_context_int);
+ && context_init(&default_context_int)
+ && ossl_init_casecmp();
}
void ossl_lib_ctx_default_deinit(void)
diff --git a/crypto/ctype.c b/crypto/ctype.c
index 83c24a546f..321306eb5f 100644
--- a/crypto/ctype.c
+++ b/crypto/ctype.c
@@ -12,6 +12,19 @@
#include "crypto/ctype.h"
#include <openssl/ebcdic.h>
+#include <openssl/crypto.h>
+#include "internal/core.h"
+#include "internal/thread_once.h"
+
+#ifndef OPENSSL_SYS_WINDOWS
+#include <strings.h>
+#endif
+#include <locale.h>
+
+#ifdef OPENSSL_SYS_MACOSX
+#include <xlocale.h>
+#endif
+
/*
* Define the character classes for each character in the seven bit ASCII
* character set. This is independent of the host's character set, characters
@@ -278,3 +291,90 @@ int ossl_ascii_isdigit(const char inchar) {
return 1;
return 0;
}
+
+/* str[n]casecmp_l is defined in POSIX 2008-01. Value is taken accordingly
+ * https://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html */
+
+#if (defined OPENSSL_SYS_WINDOWS) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200809L)
+
+# if defined OPENSSL_SYS_WINDOWS
+# define locale_t _locale_t
+# define freelocale _free_locale
+# define strcasecmp_l _stricmp_l
+# define strncasecmp_l _strnicmp_l
+# endif
+
+# ifndef FIPS_MODULE
+static locale_t loc;
+
+static int locale_base_inited = 0;
+static CRYPTO_ONCE locale_base = CRYPTO_ONCE_STATIC_INIT;
+static CRYPTO_ONCE locale_base_deinit = CRYPTO_ONCE_STATIC_INIT;
+
+void *ossl_c_locale() {
+ return (void *)loc;
+}
+
+DEFINE_RUN_ONCE_STATIC(ossl_init_locale_base)
+{
+# ifdef OPENSSL_SYS_WINDOWS
+ loc = _create_locale(LC_COLLATE, "C");
+# else
+ loc = newlocale(LC_COLLATE_MASK, "C", (locale_t) 0);
+# endif
+ locale_base_inited = 1;
+ return (loc == (locale_t) 0) ? 0 : 1;
+}
+
+DEFINE_RUN_ONCE_STATIC(ossl_deinit_locale_base)
+{
+ if (locale_base_inited && loc) {
+ freelocale(loc);
+ loc = NULL;
+ }
+ return 1;
+}
+
+int ossl_init_casecmp()
+{
+ return RUN_ONCE(&locale_base, ossl_init_locale_base);
+}
+
+void ossl_deinit_casecmp() {
+ (void)RUN_ONCE(&locale_base_deinit, ossl_deinit_locale_base);
+}
+# endif
+
+int OPENSSL_strcasecmp(const char *s1, const char *s2)
+{
+ return strcasecmp_l(s1, s2, (locale_t)ossl_c_locale());
+}
+
+int OPENSSL_strncasecmp(const char *s1, const char *s2, size_t n)
+{
+ return strncasecmp_l(s1, s2, n, (locale_t)ossl_c_locale());
+}
+#else
+# ifndef FIPS_MODULE
+void *ossl_c_locale() {
+ return NULL;
+}
+# endif
+
+int ossl_init_casecmp() {
+ return 1;
+}
+
+void ossl_deinit_casecmp() {
+}
+
+int OPENSSL_strcasecmp(const char *s1, const char *s2)
+{
+ return strcasecmp(s1, s2);
+}
+
+int OPENSSL_strncasecmp(const char *s1, const char *s2, size_t n)
+{
+ return strncasecmp(s1, s2, n);
+}
+#endif
diff --git a/crypto/init.c b/crypto/init.c
index 6a27d1a8e4..1569c35a6b 100644
--- a/crypto/init.c
+++ b/crypto/init.c
@@ -32,6 +32,7 @@
#include "crypto/store.h"
#include <openssl/cmp_util.h> /* for OSSL_CMP_log_close() */
#include <openssl/trace.h>
+#include "crypto/ctype.h"
static int stopped = 0;
static uint64_t optsdone = 0;
@@ -447,6 +448,9 @@ void OPENSSL_cleanup(void)
OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_trace_cleanup()\n");
ossl_trace_cleanup();
+ OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_deinit_casecmp()\n");
+ ossl_deinit_casecmp();
+
base_inited = 0;
}
@@ -460,6 +464,9 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
uint64_t tmp;
int aloaddone = 0;
+ if (!ossl_init_casecmp())
+ return 0;
+
/* Applications depend on 0 being returned when cleanup was already done */
if (stopped) {
if (!(opts & OPENSSL_INIT_BASE_ONLY))