]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/o_str.c
Revert "GH614: Use memcpy()/strdup() when possible"
[thirdparty/openssl.git] / crypto / o_str.c
1 /*
2 * Copyright 2003-2017 The OpenSSL Project Authors. All Rights Reserved.
3 *
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
8 */
9
10 #include "e_os.h"
11 #include <limits.h>
12 #include <openssl/crypto.h>
13 #include "internal/cryptlib.h"
14 #include "internal/o_str.h"
15
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;
20
21 while (n && (ret = *c1 - *c2) == 0)
22 n--, c1++, c2++;
23
24 return ret;
25 }
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;
33 ret = CRYPTO_malloc(strlen(str) + 1, file, line);
34 if (ret != NULL)
35 strcpy(ret, str);
36 return ret;
37 }
38
39 char *CRYPTO_strndup(const char *str, size_t s, const char* file, int line)
40 {
41 size_t maxlen;
42 char *ret;
43
44 if (str == NULL)
45 return NULL;
46
47 maxlen = OPENSSL_strnlen(str, s);
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 }
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;
151 int chi, cli;
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 }
171 cli = OPENSSL_hexchar2int(cl);
172 chi = OPENSSL_hexchar2int(ch);
173 if (cli < 0 || chi < 0) {
174 OPENSSL_free(hexbuf);
175 CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, CRYPTO_R_ILLEGAL_HEX_DIGIT);
176 return NULL;
177 }
178 *q++ = (unsigned char)((chi << 4) | cli);
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 {
193 static const char hexdig[] = "0123456789ABCDEF";
194 char *tmp, *q;
195 const unsigned char *p;
196 int i;
197
198 if (len == 0)
199 {
200 return OPENSSL_zalloc(1);
201 }
202
203 if ((tmp = OPENSSL_malloc(len * 3)) == NULL) {
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 }
220
221 int openssl_strerror_r(int errnum, char *buf, size_t buflen)
222 {
223 #if defined(_MSC_VER) && _MSC_VER>=1400
224 return !strerror_s(buf, buflen, errnum);
225 #elif defined(_GNU_SOURCE)
226 return strerror_r(errnum, buf, buflen) != NULL;
227 #elif (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || \
228 (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600)
229 /*
230 * We can use "real" strerror_r. The OpenSSL version differs in that it
231 * gives 1 on success and 0 on failure for consistency with other OpenSSL
232 * functions. Real strerror_r does it the other way around
233 */
234 return !strerror_r(errnum, buf, buflen);
235 #else
236 char *err;
237 /* Fall back to non-thread safe strerror()...its all we can do */
238 if (buflen < 2)
239 return 0;
240 err = strerror(errnum);
241 /* Can this ever happen? */
242 if (err == NULL)
243 return 0;
244 strncpy(buf, err, buflen - 1);
245 buf[buflen - 1] = '\0';
246 return 1;
247 #endif
248 }