Include the e_os.h before string.h
[openssl.git] / crypto / ctype.c
1 /*
2  * Copyright 2017-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 <stdio.h>
13 #include "crypto/ctype.h"
14 #include <openssl/ebcdic.h>
15 #include "internal/core.h"
16 #ifndef OPENSSL_NO_LOCALE
17 # include <locale.h>
18 # ifdef OPENSSL_SYS_MACOSX
19 #  include <xlocale.h>
20 # endif
21 #endif
22 /*
23  * Define the character classes for each character in the seven bit ASCII
24  * character set.  This is independent of the host's character set, characters
25  * are converted to ASCII before being used as an index in to this table.
26  * Characters outside of the seven bit ASCII range are detected before indexing.
27  */
28 static const unsigned short ctype_char_map[128] = {
29    /* 00 nul */ CTYPE_MASK_cntrl,
30    /* 01 soh */ CTYPE_MASK_cntrl,
31    /* 02 stx */ CTYPE_MASK_cntrl,
32    /* 03 etx */ CTYPE_MASK_cntrl,
33    /* 04 eot */ CTYPE_MASK_cntrl,
34    /* 05 enq */ CTYPE_MASK_cntrl,
35    /* 06 ack */ CTYPE_MASK_cntrl,
36    /* 07 \a  */ CTYPE_MASK_cntrl,
37    /* 08 \b  */ CTYPE_MASK_cntrl,
38    /* 09 \t  */ CTYPE_MASK_blank | CTYPE_MASK_cntrl | CTYPE_MASK_space,
39    /* 0A \n  */ CTYPE_MASK_cntrl | CTYPE_MASK_space,
40    /* 0B \v  */ CTYPE_MASK_cntrl | CTYPE_MASK_space,
41    /* 0C \f  */ CTYPE_MASK_cntrl | CTYPE_MASK_space,
42    /* 0D \r  */ CTYPE_MASK_cntrl | CTYPE_MASK_space,
43    /* 0E so  */ CTYPE_MASK_cntrl,
44    /* 0F si  */ CTYPE_MASK_cntrl,
45    /* 10 dle */ CTYPE_MASK_cntrl,
46    /* 11 dc1 */ CTYPE_MASK_cntrl,
47    /* 12 dc2 */ CTYPE_MASK_cntrl,
48    /* 13 dc3 */ CTYPE_MASK_cntrl,
49    /* 14 dc4 */ CTYPE_MASK_cntrl,
50    /* 15 nak */ CTYPE_MASK_cntrl,
51    /* 16 syn */ CTYPE_MASK_cntrl,
52    /* 17 etb */ CTYPE_MASK_cntrl,
53    /* 18 can */ CTYPE_MASK_cntrl,
54    /* 19 em  */ CTYPE_MASK_cntrl,
55    /* 1A sub */ CTYPE_MASK_cntrl,
56    /* 1B esc */ CTYPE_MASK_cntrl,
57    /* 1C fs  */ CTYPE_MASK_cntrl,
58    /* 1D gs  */ CTYPE_MASK_cntrl,
59    /* 1E rs  */ CTYPE_MASK_cntrl,
60    /* 1F us  */ CTYPE_MASK_cntrl,
61    /* 20     */ CTYPE_MASK_blank | CTYPE_MASK_print | CTYPE_MASK_space
62                 | CTYPE_MASK_asn1print,
63    /* 21  !  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
64    /* 22  "  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
65    /* 23  #  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
66    /* 24  $  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
67    /* 25  %  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
68    /* 26  &  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
69    /* 27  '  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct
70                 | CTYPE_MASK_asn1print,
71    /* 28  (  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct
72                 | CTYPE_MASK_asn1print,
73    /* 29  )  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct
74                 | CTYPE_MASK_asn1print,
75    /* 2A  *  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
76    /* 2B  +  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct
77                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
78    /* 2C  ,  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct
79                 | CTYPE_MASK_asn1print,
80    /* 2D  -  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct
81                 | CTYPE_MASK_asn1print,
82    /* 2E  .  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct
83                 | CTYPE_MASK_asn1print,
84    /* 2F  /  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct
85                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
86    /* 30  0  */ CTYPE_MASK_digit | CTYPE_MASK_graph | CTYPE_MASK_print
87                 | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
88    /* 31  1  */ CTYPE_MASK_digit | CTYPE_MASK_graph | CTYPE_MASK_print
89                 | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
90    /* 32  2  */ CTYPE_MASK_digit | CTYPE_MASK_graph | CTYPE_MASK_print
91                 | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
92    /* 33  3  */ CTYPE_MASK_digit | CTYPE_MASK_graph | CTYPE_MASK_print
93                 | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
94    /* 34  4  */ CTYPE_MASK_digit | CTYPE_MASK_graph | CTYPE_MASK_print
95                 | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
96    /* 35  5  */ CTYPE_MASK_digit | CTYPE_MASK_graph | CTYPE_MASK_print
97                 | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
98    /* 36  6  */ CTYPE_MASK_digit | CTYPE_MASK_graph | CTYPE_MASK_print
99                 | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
100    /* 37  7  */ CTYPE_MASK_digit | CTYPE_MASK_graph | CTYPE_MASK_print
101                 | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
102    /* 38  8  */ CTYPE_MASK_digit | CTYPE_MASK_graph | CTYPE_MASK_print
103                 | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
104    /* 39  9  */ CTYPE_MASK_digit | CTYPE_MASK_graph | CTYPE_MASK_print
105                 | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
106    /* 3A  :  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct
107                 | CTYPE_MASK_asn1print,
108    /* 3B  ;  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
109    /* 3C  <  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
110    /* 3D  =  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct
111                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
112    /* 3E  >  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
113    /* 3F  ?  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct
114                 | CTYPE_MASK_asn1print,
115    /* 40  @  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
116    /* 41  A  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
117                 | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
118    /* 42  B  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
119                 | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
120    /* 43  C  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
121                 | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
122    /* 44  D  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
123                 | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
124    /* 45  E  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
125                 | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
126    /* 46  F  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
127                 | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
128    /* 47  G  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
129                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
130    /* 48  H  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
131                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
132    /* 49  I  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
133                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
134    /* 4A  J  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
135                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
136    /* 4B  K  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
137                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
138    /* 4C  L  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
139                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
140    /* 4D  M  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
141                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
142    /* 4E  N  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
143                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
144    /* 4F  O  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
145                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
146    /* 50  P  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
147                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
148    /* 51  Q  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
149                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
150    /* 52  R  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
151                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
152    /* 53  S  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
153                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
154    /* 54  T  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
155                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
156    /* 55  U  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
157                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
158    /* 56  V  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
159                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
160    /* 57  W  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
161                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
162    /* 58  X  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
163                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
164    /* 59  Y  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
165                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
166    /* 5A  Z  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_upper
167                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
168    /* 5B  [  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
169    /* 5C  \  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
170    /* 5D  ]  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
171    /* 5E  ^  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
172    /* 5F  _  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
173    /* 60  `  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
174    /* 61  a  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
175                 | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
176    /* 62  b  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
177                 | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
178    /* 63  c  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
179                 | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
180    /* 64  d  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
181                 | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
182    /* 65  e  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
183                 | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
184    /* 66  f  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
185                 | CTYPE_MASK_xdigit | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
186    /* 67  g  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
187                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
188    /* 68  h  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
189                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
190    /* 69  i  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
191                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
192    /* 6A  j  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
193                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
194    /* 6B  k  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
195                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
196    /* 6C  l  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
197                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
198    /* 6D  m  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
199                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
200    /* 6E  n  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
201                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
202    /* 6F  o  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
203                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
204    /* 70  p  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
205                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
206    /* 71  q  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
207                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
208    /* 72  r  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
209                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
210    /* 73  s  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
211                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
212    /* 74  t  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
213                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
214    /* 75  u  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
215                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
216    /* 76  v  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
217                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
218    /* 77  w  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
219                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
220    /* 78  x  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
221                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
222    /* 79  y  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
223                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
224    /* 7A  z  */ CTYPE_MASK_graph | CTYPE_MASK_lower | CTYPE_MASK_print
225                 | CTYPE_MASK_base64 | CTYPE_MASK_asn1print,
226    /* 7B  {  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
227    /* 7C  |  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
228    /* 7D  }  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
229    /* 7E  ~  */ CTYPE_MASK_graph | CTYPE_MASK_print | CTYPE_MASK_punct,
230    /* 7F del */ CTYPE_MASK_cntrl
231 };
232
233 #ifdef CHARSET_EBCDIC
234 int ossl_toascii(int c)
235 {
236     if (c < -128 || c > 256 || c == EOF)
237         return c;
238     /*
239      * Adjust negatively signed characters.
240      * This is not required for ASCII because any character that sign extends
241      * is not seven bit and all of the checks are on the seven bit characters.
242      * I.e. any check must fail on sign extension.
243      */
244     if (c < 0)
245         c += 256;
246     return os_toascii[c];
247 }
248
249 int ossl_fromascii(int c)
250 {
251     if (c < -128 || c > 256 || c == EOF)
252         return c;
253     if (c < 0)
254         c += 256;
255     return os_toebcdic[c];
256 }
257 #endif
258
259 int ossl_ctype_check(int c, unsigned int mask)
260 {
261     const int max = sizeof(ctype_char_map) / sizeof(*ctype_char_map);
262     const int a = ossl_toascii(c);
263
264     return a >= 0 && a < max && (ctype_char_map[a] & mask) != 0;
265 }
266
267 #if defined(CHARSET_EBCDIC) && !defined(CHARSET_EBCDIC_TEST)
268 static const int case_change = 0x40;
269 #else
270 static const int case_change = 0x20;
271 #endif
272
273 int ossl_tolower(int c)
274 {
275     return ossl_isupper(c) ? c ^ case_change : c;
276 }
277
278 int ossl_toupper(int c)
279 {
280     return ossl_islower(c) ? c ^ case_change : c;
281 }
282
283 int ossl_ascii_isdigit(const char inchar) {
284     if (inchar > 0x2F && inchar < 0x3A)
285         return 1;
286     return 0;
287 }
288
289 #ifndef OPENSSL_NO_LOCALE
290 # ifndef FIPS_MODULE
291 static locale_t loc;
292
293
294 void *ossl_c_locale() {
295     return (void *)loc;
296 }
297
298 int ossl_init_casecmp_int() {
299 # ifdef OPENSSL_SYS_WINDOWS
300     loc = _create_locale(LC_COLLATE, "C");
301 # else
302     loc = newlocale(LC_COLLATE_MASK, "C", (locale_t) 0);
303 # endif
304     return (loc == (locale_t) 0) ? 0 : 1;
305 }
306
307 void ossl_deinit_casecmp() {
308     freelocale(loc);
309 }
310 # endif
311
312 int OPENSSL_strcasecmp(const char *s1, const char *s2)
313 {
314     return strcasecmp_l(s1, s2, (locale_t)ossl_c_locale());
315 }
316
317 int OPENSSL_strncasecmp(const char *s1, const char *s2, size_t n)
318 {
319     return strncasecmp_l(s1, s2, n, (locale_t)ossl_c_locale());
320 }
321 #else
322 # ifndef FIPS_MODULE
323 void *ossl_c_locale() {
324     return NULL;
325 }
326 # endif
327
328 int ossl_init_casecmp_int() {
329     return 1;
330 }
331
332 void ossl_deinit_casecmp() {
333 }
334
335 int OPENSSL_strcasecmp(const char *s1, const char *s2)
336 {
337     return strcasecmp(s1, s2);
338 }
339
340 int OPENSSL_strncasecmp(const char *s1, const char *s2, size_t n)
341 {
342     return strncasecmp(s1, s2, n);
343 }
344 #endif