Add fallback in case of locale initialization failure
[openssl.git] / crypto / o_str.c
1 /*
2  * Copyright 2003-2022 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include "internal/e_os.h"
11 #include <string.h>
12 #include <limits.h>
13 #ifndef OPENSSL_NO_LOCALE
14 # include <locale.h>
15 # ifdef OPENSSL_SYS_MACOSX
16 #  include <xlocale.h>
17 # endif
18 #endif
19 #include <openssl/crypto.h>
20 #include "internal/cryptlib.h"
21
22 #define DEFAULT_SEPARATOR ':'
23 #define CH_ZERO '\0'
24
25 char *CRYPTO_strdup(const char *str, const char* file, int line)
26 {
27     char *ret;
28
29     if (str == NULL)
30         return NULL;
31     ret = CRYPTO_malloc(strlen(str) + 1, file, line);
32     if (ret != NULL)
33         strcpy(ret, str);
34     return ret;
35 }
36
37 char *CRYPTO_strndup(const char *str, size_t s, const char* file, int line)
38 {
39     size_t maxlen;
40     char *ret;
41
42     if (str == NULL)
43         return NULL;
44
45     maxlen = OPENSSL_strnlen(str, s);
46
47     ret = CRYPTO_malloc(maxlen + 1, file, line);
48     if (ret) {
49         memcpy(ret, str, maxlen);
50         ret[maxlen] = CH_ZERO;
51     }
52     return ret;
53 }
54
55 void *CRYPTO_memdup(const void *data, size_t siz, const char* file, int line)
56 {
57     void *ret;
58
59     if (data == NULL || siz >= INT_MAX)
60         return NULL;
61
62     ret = CRYPTO_malloc(siz, file, line);
63     if (ret == NULL) {
64         ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
65         return NULL;
66     }
67     return memcpy(ret, data, siz);
68 }
69
70 size_t OPENSSL_strnlen(const char *str, size_t maxlen)
71 {
72     const char *p;
73
74     for (p = str; maxlen-- != 0 && *p != CH_ZERO; ++p) ;
75
76     return p - str;
77 }
78
79 size_t OPENSSL_strlcpy(char *dst, const char *src, size_t size)
80 {
81     size_t l = 0;
82     for (; size > 1 && *src; size--) {
83         *dst++ = *src++;
84         l++;
85     }
86     if (size)
87         *dst = CH_ZERO;
88     return l + strlen(src);
89 }
90
91 size_t OPENSSL_strlcat(char *dst, const char *src, size_t size)
92 {
93     size_t l = 0;
94     for (; size > 0 && *dst; size--, dst++)
95         l++;
96     return l + OPENSSL_strlcpy(dst, src, size);
97 }
98
99 int OPENSSL_hexchar2int(unsigned char c)
100 {
101 #ifdef CHARSET_EBCDIC
102     c = os_toebcdic[c];
103 #endif
104
105     switch (c) {
106     case '0':
107         return 0;
108     case '1':
109         return 1;
110     case '2':
111         return 2;
112     case '3':
113         return 3;
114     case '4':
115           return 4;
116     case '5':
117           return 5;
118     case '6':
119           return 6;
120     case '7':
121           return 7;
122     case '8':
123           return 8;
124     case '9':
125           return 9;
126     case 'a': case 'A':
127           return 0x0A;
128     case 'b': case 'B':
129           return 0x0B;
130     case 'c': case 'C':
131           return 0x0C;
132     case 'd': case 'D':
133           return 0x0D;
134     case 'e': case 'E':
135           return 0x0E;
136     case 'f': case 'F':
137           return 0x0F;
138     }
139     return -1;
140 }
141
142 static int hexstr2buf_sep(unsigned char *buf, size_t buf_n, size_t *buflen,
143                           const char *str, const char sep)
144 {
145     unsigned char *q;
146     unsigned char ch, cl;
147     int chi, cli;
148     const unsigned char *p;
149     size_t cnt;
150
151     for (p = (const unsigned char *)str, q = buf, cnt = 0; *p; ) {
152         ch = *p++;
153         /* A separator of CH_ZERO means there is no separator */
154         if (ch == sep && sep != CH_ZERO)
155             continue;
156         cl = *p++;
157         if (!cl) {
158             ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_ODD_NUMBER_OF_DIGITS);
159             return 0;
160         }
161         cli = OPENSSL_hexchar2int(cl);
162         chi = OPENSSL_hexchar2int(ch);
163         if (cli < 0 || chi < 0) {
164             ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_ILLEGAL_HEX_DIGIT);
165             return 0;
166         }
167         cnt++;
168         if (q != NULL) {
169             if (cnt > buf_n) {
170                 ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_SMALL_BUFFER);
171                 return 0;
172             }
173             *q++ = (unsigned char)((chi << 4) | cli);
174         }
175     }
176
177     if (buflen != NULL)
178         *buflen = cnt;
179     return 1;
180 }
181
182 /*
183  * Given a string of hex digits convert to a buffer
184  */
185 int OPENSSL_hexstr2buf_ex(unsigned char *buf, size_t buf_n, size_t *buflen,
186                           const char *str, const char sep)
187 {
188     return hexstr2buf_sep(buf, buf_n, buflen, str, sep);
189 }
190
191 unsigned char *ossl_hexstr2buf_sep(const char *str, long *buflen,
192                                    const char sep)
193 {
194     unsigned char *buf;
195     size_t buf_n, tmp_buflen;
196
197     buf_n = strlen(str);
198     if (buf_n <= 1) {
199         ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_HEX_STRING_TOO_SHORT);
200         return NULL;
201     }
202     buf_n /= 2;
203     if ((buf = OPENSSL_malloc(buf_n)) == NULL) {
204         ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
205         return NULL;
206     }
207
208     if (buflen != NULL)
209         *buflen = 0;
210     tmp_buflen = 0;
211     if (hexstr2buf_sep(buf, buf_n, &tmp_buflen, str, sep)) {
212         if (buflen != NULL)
213             *buflen = (long)tmp_buflen;
214         return buf;
215     }
216     OPENSSL_free(buf);
217     return NULL;
218 }
219
220 unsigned char *OPENSSL_hexstr2buf(const char *str, long *buflen)
221 {
222     return ossl_hexstr2buf_sep(str, buflen, DEFAULT_SEPARATOR);
223 }
224
225 static int buf2hexstr_sep(char *str, size_t str_n, size_t *strlength,
226                           const unsigned char *buf, size_t buflen,
227                           const char sep)
228 {
229     static const char hexdig[] = "0123456789ABCDEF";
230     const unsigned char *p;
231     char *q;
232     size_t i;
233     int has_sep = (sep != CH_ZERO);
234     size_t len = has_sep ? buflen * 3 : 1 + buflen * 2;
235
236     if (strlength != NULL)
237         *strlength = len;
238     if (str == NULL)
239         return 1;
240
241     if (str_n < (unsigned long)len) {
242         ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_SMALL_BUFFER);
243         return 0;
244     }
245
246     q = str;
247     for (i = 0, p = buf; i < buflen; i++, p++) {
248         *q++ = hexdig[(*p >> 4) & 0xf];
249         *q++ = hexdig[*p & 0xf];
250         if (has_sep)
251             *q++ = sep;
252     }
253     if (has_sep)
254         --q;
255     *q = CH_ZERO;
256
257 #ifdef CHARSET_EBCDIC
258     ebcdic2ascii(str, str, q - str - 1);
259 #endif
260     return 1;
261 }
262
263 int OPENSSL_buf2hexstr_ex(char *str, size_t str_n, size_t *strlength,
264                           const unsigned char *buf, size_t buflen,
265                           const char sep)
266 {
267     return buf2hexstr_sep(str, str_n, strlength, buf, buflen, sep);
268 }
269
270 char *ossl_buf2hexstr_sep(const unsigned char *buf, long buflen, char sep)
271 {
272     char *tmp;
273     size_t tmp_n;
274
275     if (buflen == 0)
276         return OPENSSL_zalloc(1);
277
278     tmp_n = (sep != CH_ZERO) ? buflen * 3 : 1 + buflen * 2;
279     if ((tmp = OPENSSL_malloc(tmp_n)) == NULL) {
280         ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
281         return NULL;
282     }
283
284     if (buf2hexstr_sep(tmp, tmp_n, NULL, buf, buflen, sep))
285         return tmp;
286     OPENSSL_free(tmp);
287     return NULL;
288 }
289
290
291 /*
292  * Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its
293  * hex representation @@@ (Contents of buffer are always kept in ASCII, also
294  * on EBCDIC machines)
295  */
296 char *OPENSSL_buf2hexstr(const unsigned char *buf, long buflen)
297 {
298     return ossl_buf2hexstr_sep(buf, buflen, ':');
299 }
300
301 int openssl_strerror_r(int errnum, char *buf, size_t buflen)
302 {
303 #if defined(_MSC_VER) && _MSC_VER>=1400 && !defined(_WIN32_WCE)
304     return !strerror_s(buf, buflen, errnum);
305 #elif defined(_GNU_SOURCE)
306     char *err;
307
308     /*
309      * GNU strerror_r may not actually set buf.
310      * It can return a pointer to some (immutable) static string in which case
311      * buf is left unused.
312      */
313     err = strerror_r(errnum, buf, buflen);
314     if (err == NULL || buflen == 0)
315         return 0;
316     /*
317      * If err is statically allocated, err != buf and we need to copy the data.
318      * If err points somewhere inside buf, OPENSSL_strlcpy can handle this,
319      * since src and dest are not annotated with __restrict and the function
320      * reads src byte for byte and writes to dest.
321      * If err == buf we do not have to copy anything.
322      */
323     if (err != buf)
324         OPENSSL_strlcpy(buf, err, buflen);
325     return 1;
326 #elif (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || \
327       (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600)
328     /*
329      * We can use "real" strerror_r. The OpenSSL version differs in that it
330      * gives 1 on success and 0 on failure for consistency with other OpenSSL
331      * functions. Real strerror_r does it the other way around
332      */
333     return !strerror_r(errnum, buf, buflen);
334 #else
335     char *err;
336
337     /* Fall back to non-thread safe strerror()...its all we can do */
338     if (buflen < 2)
339         return 0;
340     err = strerror(errnum);
341     /* Can this ever happen? */
342     if (err == NULL)
343         return 0;
344     OPENSSL_strlcpy(buf, err, buflen);
345     return 1;
346 #endif
347 }
348
349 #ifndef OPENSSL_NO_LOCALE
350 static locale_t loc;
351
352 static locale_t ossl_c_locale(void) {
353     return loc;
354 }
355
356 int ossl_init_casecmp_int(void) {
357 # ifdef OPENSSL_SYS_WINDOWS
358     loc = _create_locale(LC_COLLATE, "C");
359 # else
360     loc = newlocale(LC_COLLATE_MASK, "C", (locale_t) 0);
361 # endif
362     return (loc == (locale_t)0) ? 0 : 1;
363 }
364
365 void ossl_deinit_casecmp(void) {
366     freelocale(loc);
367     loc = (locale_t)0;
368 }
369
370 int OPENSSL_strcasecmp(const char *s1, const char *s2)
371 {
372     locale_t l = ossl_c_locale();
373
374     /* Fallback in case of locale initialization failure */
375     if (l == (locale_t)0)
376         return strcasecmp(s1, s2);
377     return strcasecmp_l(s1, s2, l);
378 }
379
380 int OPENSSL_strncasecmp(const char *s1, const char *s2, size_t n)
381 {
382     locale_t l = ossl_c_locale();
383
384     /* Fallback in case of locale initialization failure */
385     if (l == (locale_t)0)
386         return strncasecmp(s1, s2, n);
387     return strncasecmp_l(s1, s2, n, l);
388 }
389 #else
390 int ossl_init_casecmp_int(void) {
391     return 1;
392 }
393
394 void ossl_deinit_casecmp(void) {
395 }
396
397 int OPENSSL_strcasecmp(const char *s1, const char *s2)
398 {
399     return strcasecmp(s1, s2);
400 }
401
402 int OPENSSL_strncasecmp(const char *s1, const char *s2, size_t n)
403 {
404     return strncasecmp(s1, s2, n);
405 }
406 #endif