]>
Commit | Line | Data |
---|---|---|
0f113f3e | 1 | /* |
a1df06b3 | 2 | * Copyright 2003-2017 The OpenSSL Project Authors. All Rights Reserved. |
e6fa67fa | 3 | * |
0e9725bc | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
62867571 RS |
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 | ||
bef7a815 | 10 | #include "e_os.h" |
07016a8a | 11 | #include <limits.h> |
7644a9ae RS |
12 | #include <openssl/crypto.h> |
13 | #include "internal/cryptlib.h" | |
68570797 | 14 | #include "internal/o_str.h" |
e6fa67fa | 15 | |
0f113f3e MC |
16 | int OPENSSL_memcmp(const void *v1, const void *v2, size_t n) |
17 | { | |
18 | const unsigned char *c1 = v1, *c2 = v2; | |
19 | int ret = 0; | |
7a06050c | 20 | |
0f113f3e MC |
21 | while (n && (ret = *c1 - *c2) == 0) |
22 | n--, c1++, c2++; | |
7a06050c | 23 | |
0f113f3e MC |
24 | return ret; |
25 | } | |
7644a9ae RS |
26 | |
27 | char *CRYPTO_strdup(const char *str, const char* file, int line) | |
28 | { | |
29 | char *ret; | |
30 | ||
31 | if (str == NULL) | |
32 | return NULL; | |
4cacc9d5 | 33 | ret = CRYPTO_malloc(strlen(str) + 1, file, line); |
7644a9ae | 34 | if (ret != NULL) |
4cacc9d5 | 35 | strcpy(ret, str); |
7644a9ae RS |
36 | return ret; |
37 | } | |
38 | ||
39 | char *CRYPTO_strndup(const char *str, size_t s, const char* file, int line) | |
40 | { | |
7644a9ae RS |
41 | size_t maxlen; |
42 | char *ret; | |
43 | ||
44 | if (str == NULL) | |
45 | return NULL; | |
46 | ||
b6e78584 | 47 | maxlen = OPENSSL_strnlen(str, s); |
7644a9ae RS |
48 | |
49 | ret = CRYPTO_malloc(maxlen + 1, file, line); | |
50 | if (ret) { | |
51 | memcpy(ret, str, maxlen); | |
52 | ret[maxlen] = '\0'; | |
53 | } | |
54 | return ret; | |
55 | } | |
56 | ||
57 | void *CRYPTO_memdup(const void *data, size_t siz, const char* file, int line) | |
58 | { | |
59 | void *ret; | |
60 | ||
61 | if (data == NULL || siz >= INT_MAX) | |
62 | return NULL; | |
63 | ||
64 | ret = CRYPTO_malloc(siz, file, line); | |
65 | if (ret == NULL) { | |
66 | CRYPTOerr(CRYPTO_F_CRYPTO_MEMDUP, ERR_R_MALLOC_FAILURE); | |
67 | return NULL; | |
68 | } | |
69 | return memcpy(ret, data, siz); | |
70 | } | |
71 | ||
72 | size_t OPENSSL_strnlen(const char *str, size_t maxlen) | |
73 | { | |
74 | const char *p; | |
75 | ||
76 | for (p = str; maxlen-- != 0 && *p != '\0'; ++p) ; | |
77 | ||
78 | return p - str; | |
79 | } | |
80 | ||
81 | size_t OPENSSL_strlcpy(char *dst, const char *src, size_t size) | |
82 | { | |
83 | size_t l = 0; | |
84 | for (; size > 1 && *src; size--) { | |
85 | *dst++ = *src++; | |
86 | l++; | |
87 | } | |
88 | if (size) | |
89 | *dst = '\0'; | |
90 | return l + strlen(src); | |
91 | } | |
92 | ||
93 | size_t OPENSSL_strlcat(char *dst, const char *src, size_t size) | |
94 | { | |
95 | size_t l = 0; | |
96 | for (; size > 0 && *dst; size--, dst++) | |
97 | l++; | |
98 | return l + OPENSSL_strlcpy(dst, src, size); | |
99 | } | |
14f051a0 RS |
100 | |
101 | int OPENSSL_hexchar2int(unsigned char c) | |
102 | { | |
103 | #ifdef CHARSET_EBCDIC | |
104 | c = os_toebcdic[c]; | |
105 | #endif | |
106 | ||
107 | switch (c) { | |
108 | case '0': | |
109 | return 0; | |
110 | case '1': | |
111 | return 1; | |
112 | case '2': | |
113 | return 2; | |
114 | case '3': | |
115 | return 3; | |
116 | case '4': | |
117 | return 4; | |
118 | case '5': | |
119 | return 5; | |
120 | case '6': | |
121 | return 6; | |
122 | case '7': | |
123 | return 7; | |
124 | case '8': | |
125 | return 8; | |
126 | case '9': | |
127 | return 9; | |
128 | case 'a': case 'A': | |
129 | return 0x0A; | |
130 | case 'b': case 'B': | |
131 | return 0x0B; | |
132 | case 'c': case 'C': | |
133 | return 0x0C; | |
134 | case 'd': case 'D': | |
135 | return 0x0D; | |
136 | case 'e': case 'E': | |
137 | return 0x0E; | |
138 | case 'f': case 'F': | |
139 | return 0x0F; | |
140 | } | |
141 | return -1; | |
142 | } | |
143 | ||
144 | /* | |
145 | * Give a string of hex digits convert to a buffer | |
146 | */ | |
147 | unsigned char *OPENSSL_hexstr2buf(const char *str, long *len) | |
148 | { | |
149 | unsigned char *hexbuf, *q; | |
150 | unsigned char ch, cl; | |
235f9329 | 151 | int chi, cli; |
14f051a0 RS |
152 | const unsigned char *p; |
153 | size_t s; | |
154 | ||
155 | s = strlen(str); | |
156 | if ((hexbuf = OPENSSL_malloc(s >> 1)) == NULL) { | |
157 | CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, ERR_R_MALLOC_FAILURE); | |
158 | return NULL; | |
159 | } | |
160 | for (p = (const unsigned char *)str, q = hexbuf; *p; ) { | |
161 | ch = *p++; | |
162 | if (ch == ':') | |
163 | continue; | |
164 | cl = *p++; | |
165 | if (!cl) { | |
166 | CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, | |
167 | CRYPTO_R_ODD_NUMBER_OF_DIGITS); | |
168 | OPENSSL_free(hexbuf); | |
169 | return NULL; | |
170 | } | |
235f9329 MC |
171 | cli = OPENSSL_hexchar2int(cl); |
172 | chi = OPENSSL_hexchar2int(ch); | |
173 | if (cli < 0 || chi < 0) { | |
14f051a0 RS |
174 | OPENSSL_free(hexbuf); |
175 | CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, CRYPTO_R_ILLEGAL_HEX_DIGIT); | |
176 | return NULL; | |
177 | } | |
235f9329 | 178 | *q++ = (unsigned char)((chi << 4) | cli); |
14f051a0 RS |
179 | } |
180 | ||
181 | if (len) | |
182 | *len = q - hexbuf; | |
183 | return hexbuf; | |
184 | } | |
185 | ||
186 | /* | |
187 | * Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its | |
188 | * hex representation @@@ (Contents of buffer are always kept in ASCII, also | |
189 | * on EBCDIC machines) | |
190 | */ | |
191 | char *OPENSSL_buf2hexstr(const unsigned char *buffer, long len) | |
192 | { | |
f44903a4 | 193 | static const char hexdig[] = "0123456789ABCDEF"; |
14f051a0 RS |
194 | char *tmp, *q; |
195 | const unsigned char *p; | |
196 | int i; | |
197 | ||
01238aec KR |
198 | if (len == 0) |
199 | { | |
200 | return OPENSSL_zalloc(1); | |
201 | } | |
202 | ||
203 | if ((tmp = OPENSSL_malloc(len * 3)) == NULL) { | |
14f051a0 RS |
204 | CRYPTOerr(CRYPTO_F_OPENSSL_BUF2HEXSTR, ERR_R_MALLOC_FAILURE); |
205 | return NULL; | |
206 | } | |
207 | q = tmp; | |
208 | for (i = 0, p = buffer; i < len; i++, p++) { | |
209 | *q++ = hexdig[(*p >> 4) & 0xf]; | |
210 | *q++ = hexdig[*p & 0xf]; | |
211 | *q++ = ':'; | |
212 | } | |
213 | q[-1] = 0; | |
214 | #ifdef CHARSET_EBCDIC | |
215 | ebcdic2ascii(tmp, tmp, q - tmp - 1); | |
216 | #endif | |
217 | ||
218 | return tmp; | |
219 | } | |
7d37818d MC |
220 | |
221 | int openssl_strerror_r(int errnum, char *buf, size_t buflen) | |
222 | { | |
43c4116c AP |
223 | #if defined(_MSC_VER) && _MSC_VER>=1400 |
224 | return !strerror_s(buf, buflen, errnum); | |
efdb2d6c | 225 | #elif defined(_GNU_SOURCE) |
e3b35d2b VC |
226 | char *err; |
227 | ||
228 | /* | |
229 | * GNU strerror_r may not actually set buf. | |
230 | * It can return a pointer to some (immutable) static string in which case | |
231 | * buf is left unused. | |
232 | */ | |
233 | err = strerror_r(errnum, buf, buflen); | |
234 | if (err == NULL) | |
235 | return 0; | |
236 | /* | |
237 | * If err is statically allocated, err != buf and we need to copy the data. | |
238 | * If err points somewhere inside buf, OPENSSL_strlcpy can handle this, | |
239 | * since src and dest are not annotated with __restrict and the function | |
240 | * reads src byte for byte and writes to dest. | |
241 | * If err == buf we do not have to copy anything. | |
242 | */ | |
243 | if (err != buf) | |
244 | OPENSSL_strlcpy(buf, err, buflen); | |
245 | return 1; | |
01b76c2c BE |
246 | #elif (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || \ |
247 | (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600) | |
7d37818d MC |
248 | /* |
249 | * We can use "real" strerror_r. The OpenSSL version differs in that it | |
250 | * gives 1 on success and 0 on failure for consistency with other OpenSSL | |
251 | * functions. Real strerror_r does it the other way around | |
252 | */ | |
253 | return !strerror_r(errnum, buf, buflen); | |
254 | #else | |
255 | char *err; | |
e3b35d2b | 256 | |
7d37818d MC |
257 | /* Fall back to non-thread safe strerror()...its all we can do */ |
258 | if (buflen < 2) | |
259 | return 0; | |
260 | err = strerror(errnum); | |
261 | /* Can this ever happen? */ | |
262 | if (err == NULL) | |
263 | return 0; | |
e3b35d2b | 264 | OPENSSL_strlcpy(buf, err, buflen); |
7d37818d MC |
265 | return 1; |
266 | #endif | |
267 | } |