]>
Commit | Line | Data |
---|---|---|
0f113f3e | 1 | /* |
62867571 | 2 | * Copyright 2003-2016 The OpenSSL Project Authors. All Rights Reserved. |
e6fa67fa | 3 | * |
62867571 RS |
4 | * Licensed under the OpenSSL license (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 | |
e6fa67fa RL |
8 | */ |
9 | ||
8ee18dd5 | 10 | #include <ctype.h> |
7644a9ae | 11 | #include <limits.h> |
3b4de6e4 | 12 | #include <e_os.h> |
7644a9ae RS |
13 | #include <openssl/crypto.h> |
14 | #include "internal/cryptlib.h" | |
68570797 | 15 | #include "internal/o_str.h" |
e6fa67fa | 16 | |
01768425 | 17 | #if !defined(OPENSSL_IMPLEMENTS_strncasecmp) && \ |
68b00c23 | 18 | !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_WINCE) && \ |
01768425 | 19 | !defined(NETWARE_CLIB) |
f12797a4 BL |
20 | # include <strings.h> |
21 | #endif | |
22 | ||
e6fa67fa | 23 | int OPENSSL_strncasecmp(const char *str1, const char *str2, size_t n) |
0f113f3e | 24 | { |
e6d27baf | 25 | #if defined(OPENSSL_IMPLEMENTS_strncasecmp) |
0f113f3e MC |
26 | while (*str1 && *str2 && n) { |
27 | int res = toupper(*str1) - toupper(*str2); | |
28 | if (res) | |
29 | return res < 0 ? -1 : 1; | |
30 | str1++; | |
31 | str2++; | |
32 | n--; | |
33 | } | |
34 | if (n == 0) | |
35 | return 0; | |
36 | if (*str1) | |
37 | return 1; | |
38 | if (*str2) | |
39 | return -1; | |
40 | return 0; | |
e6fa67fa | 41 | #else |
0f113f3e MC |
42 | /* |
43 | * Recursion hazard warning! Whenever strncasecmp is #defined as | |
44 | * OPENSSL_strncasecmp, OPENSSL_IMPLEMENTS_strncasecmp must be defined as | |
45 | * well. | |
46 | */ | |
47 | return strncasecmp(str1, str2, n); | |
e6fa67fa | 48 | #endif |
0f113f3e MC |
49 | } |
50 | ||
e6fa67fa | 51 | int OPENSSL_strcasecmp(const char *str1, const char *str2) |
0f113f3e | 52 | { |
e6d27baf | 53 | #if defined(OPENSSL_IMPLEMENTS_strncasecmp) |
0f113f3e | 54 | return OPENSSL_strncasecmp(str1, str2, (size_t)-1); |
e6fa67fa | 55 | #else |
0f113f3e | 56 | return strcasecmp(str1, str2); |
e6fa67fa | 57 | #endif |
0f113f3e | 58 | } |
e6fa67fa | 59 | |
0f113f3e MC |
60 | int OPENSSL_memcmp(const void *v1, const void *v2, size_t n) |
61 | { | |
62 | const unsigned char *c1 = v1, *c2 = v2; | |
63 | int ret = 0; | |
7a06050c | 64 | |
0f113f3e MC |
65 | while (n && (ret = *c1 - *c2) == 0) |
66 | n--, c1++, c2++; | |
7a06050c | 67 | |
0f113f3e MC |
68 | return ret; |
69 | } | |
7644a9ae RS |
70 | |
71 | char *CRYPTO_strdup(const char *str, const char* file, int line) | |
72 | { | |
73 | char *ret; | |
a89c9a0d | 74 | size_t size; |
7644a9ae RS |
75 | |
76 | if (str == NULL) | |
77 | return NULL; | |
a89c9a0d DM |
78 | size = strlen(str) + 1; |
79 | ret = CRYPTO_malloc(size, file, line); | |
7644a9ae | 80 | if (ret != NULL) |
a89c9a0d | 81 | memcpy(ret, str, size); |
7644a9ae RS |
82 | return ret; |
83 | } | |
84 | ||
85 | char *CRYPTO_strndup(const char *str, size_t s, const char* file, int line) | |
86 | { | |
7644a9ae RS |
87 | size_t maxlen; |
88 | char *ret; | |
89 | ||
90 | if (str == NULL) | |
91 | return NULL; | |
92 | ||
b6e78584 | 93 | maxlen = OPENSSL_strnlen(str, s); |
7644a9ae RS |
94 | |
95 | ret = CRYPTO_malloc(maxlen + 1, file, line); | |
96 | if (ret) { | |
97 | memcpy(ret, str, maxlen); | |
98 | ret[maxlen] = '\0'; | |
99 | } | |
100 | return ret; | |
101 | } | |
102 | ||
103 | void *CRYPTO_memdup(const void *data, size_t siz, const char* file, int line) | |
104 | { | |
105 | void *ret; | |
106 | ||
107 | if (data == NULL || siz >= INT_MAX) | |
108 | return NULL; | |
109 | ||
110 | ret = CRYPTO_malloc(siz, file, line); | |
111 | if (ret == NULL) { | |
112 | CRYPTOerr(CRYPTO_F_CRYPTO_MEMDUP, ERR_R_MALLOC_FAILURE); | |
113 | return NULL; | |
114 | } | |
115 | return memcpy(ret, data, siz); | |
116 | } | |
117 | ||
118 | size_t OPENSSL_strnlen(const char *str, size_t maxlen) | |
119 | { | |
120 | const char *p; | |
121 | ||
122 | for (p = str; maxlen-- != 0 && *p != '\0'; ++p) ; | |
123 | ||
124 | return p - str; | |
125 | } | |
126 | ||
127 | size_t OPENSSL_strlcpy(char *dst, const char *src, size_t size) | |
128 | { | |
129 | size_t l = 0; | |
130 | for (; size > 1 && *src; size--) { | |
131 | *dst++ = *src++; | |
132 | l++; | |
133 | } | |
134 | if (size) | |
135 | *dst = '\0'; | |
136 | return l + strlen(src); | |
137 | } | |
138 | ||
139 | size_t OPENSSL_strlcat(char *dst, const char *src, size_t size) | |
140 | { | |
141 | size_t l = 0; | |
142 | for (; size > 0 && *dst; size--, dst++) | |
143 | l++; | |
144 | return l + OPENSSL_strlcpy(dst, src, size); | |
145 | } | |
14f051a0 RS |
146 | |
147 | int OPENSSL_hexchar2int(unsigned char c) | |
148 | { | |
149 | #ifdef CHARSET_EBCDIC | |
150 | c = os_toebcdic[c]; | |
151 | #endif | |
152 | ||
153 | switch (c) { | |
154 | case '0': | |
155 | return 0; | |
156 | case '1': | |
157 | return 1; | |
158 | case '2': | |
159 | return 2; | |
160 | case '3': | |
161 | return 3; | |
162 | case '4': | |
163 | return 4; | |
164 | case '5': | |
165 | return 5; | |
166 | case '6': | |
167 | return 6; | |
168 | case '7': | |
169 | return 7; | |
170 | case '8': | |
171 | return 8; | |
172 | case '9': | |
173 | return 9; | |
174 | case 'a': case 'A': | |
175 | return 0x0A; | |
176 | case 'b': case 'B': | |
177 | return 0x0B; | |
178 | case 'c': case 'C': | |
179 | return 0x0C; | |
180 | case 'd': case 'D': | |
181 | return 0x0D; | |
182 | case 'e': case 'E': | |
183 | return 0x0E; | |
184 | case 'f': case 'F': | |
185 | return 0x0F; | |
186 | } | |
187 | return -1; | |
188 | } | |
189 | ||
190 | /* | |
191 | * Give a string of hex digits convert to a buffer | |
192 | */ | |
193 | unsigned char *OPENSSL_hexstr2buf(const char *str, long *len) | |
194 | { | |
195 | unsigned char *hexbuf, *q; | |
196 | unsigned char ch, cl; | |
235f9329 | 197 | int chi, cli; |
14f051a0 RS |
198 | const unsigned char *p; |
199 | size_t s; | |
200 | ||
201 | s = strlen(str); | |
202 | if ((hexbuf = OPENSSL_malloc(s >> 1)) == NULL) { | |
203 | CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, ERR_R_MALLOC_FAILURE); | |
204 | return NULL; | |
205 | } | |
206 | for (p = (const unsigned char *)str, q = hexbuf; *p; ) { | |
207 | ch = *p++; | |
208 | if (ch == ':') | |
209 | continue; | |
210 | cl = *p++; | |
211 | if (!cl) { | |
212 | CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, | |
213 | CRYPTO_R_ODD_NUMBER_OF_DIGITS); | |
214 | OPENSSL_free(hexbuf); | |
215 | return NULL; | |
216 | } | |
235f9329 MC |
217 | cli = OPENSSL_hexchar2int(cl); |
218 | chi = OPENSSL_hexchar2int(ch); | |
219 | if (cli < 0 || chi < 0) { | |
14f051a0 RS |
220 | OPENSSL_free(hexbuf); |
221 | CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, CRYPTO_R_ILLEGAL_HEX_DIGIT); | |
222 | return NULL; | |
223 | } | |
235f9329 | 224 | *q++ = (unsigned char)((chi << 4) | cli); |
14f051a0 RS |
225 | } |
226 | ||
227 | if (len) | |
228 | *len = q - hexbuf; | |
229 | return hexbuf; | |
230 | } | |
231 | ||
232 | /* | |
233 | * Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its | |
234 | * hex representation @@@ (Contents of buffer are always kept in ASCII, also | |
235 | * on EBCDIC machines) | |
236 | */ | |
237 | char *OPENSSL_buf2hexstr(const unsigned char *buffer, long len) | |
238 | { | |
239 | const static char hexdig[] = "0123456789ABCDEF"; | |
240 | char *tmp, *q; | |
241 | const unsigned char *p; | |
242 | int i; | |
243 | ||
244 | if ((tmp = OPENSSL_malloc(len * 3 + 1)) == NULL) { | |
245 | CRYPTOerr(CRYPTO_F_OPENSSL_BUF2HEXSTR, ERR_R_MALLOC_FAILURE); | |
246 | return NULL; | |
247 | } | |
248 | q = tmp; | |
249 | for (i = 0, p = buffer; i < len; i++, p++) { | |
250 | *q++ = hexdig[(*p >> 4) & 0xf]; | |
251 | *q++ = hexdig[*p & 0xf]; | |
252 | *q++ = ':'; | |
253 | } | |
254 | q[-1] = 0; | |
255 | #ifdef CHARSET_EBCDIC | |
256 | ebcdic2ascii(tmp, tmp, q - tmp - 1); | |
257 | #endif | |
258 | ||
259 | return tmp; | |
260 | } |