diff options
author | Dmitry Belyavskiy <beldmit@gmail.com> | 2022-04-13 12:32:14 +0200 |
---|---|---|
committer | Dmitry Belyavskiy <beldmit@gmail.com> | 2022-04-21 17:12:31 +0200 |
commit | 130de70e0f85ecec08fcfe4daed1d0c491089ea6 (patch) | |
tree | 2a0da8004ede970436f3888d632c42f09ecdbb93 /crypto | |
parent | 455e158ef9b3b600738f5b01190c2b7083d3d0ba (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.c | 4 | ||||
-rw-r--r-- | crypto/ctype.c | 100 | ||||
-rw-r--r-- | crypto/init.c | 7 |
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)) |