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