Fix: PEM_read_bio_PrivateKey with no-ui / no-stdio
[openssl.git] / crypto / o_str.c
1 /*
2  * Copyright 2003-2016 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 <ctype.h>
11 #include <limits.h>
12 #include <e_os.h>
13 #include <openssl/crypto.h>
14 #include "internal/cryptlib.h"
15 #include "internal/o_str.h"
16
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;
21
22     while (n && (ret = *c1 - *c2) == 0)
23         n--, c1++, c2++;
24
25     return ret;
26 }
27
28 char *CRYPTO_strdup(const char *str, const char* file, int line)
29 {
30     char *ret;
31     size_t size;
32
33     if (str == NULL)
34         return NULL;
35     size = strlen(str) + 1;
36     ret = CRYPTO_malloc(size, file, line);
37     if (ret != NULL)
38         memcpy(ret, str, size);
39     return ret;
40 }
41
42 char *CRYPTO_strndup(const char *str, size_t s, const char* file, int line)
43 {
44     size_t maxlen;
45     char *ret;
46
47     if (str == NULL)
48         return NULL;
49
50     maxlen = OPENSSL_strnlen(str, s);
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 }
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;
154     int chi, cli;
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         }
174         cli = OPENSSL_hexchar2int(cl);
175         chi = OPENSSL_hexchar2int(ch);
176         if (cli < 0 || chi < 0) {
177             OPENSSL_free(hexbuf);
178             CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, CRYPTO_R_ILLEGAL_HEX_DIGIT);
179             return NULL;
180         }
181         *q++ = (unsigned char)((chi << 4) | cli);
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 {
196     const static char hexdig[] = "0123456789ABCDEF";
197     char *tmp, *q;
198     const unsigned char *p;
199     int i;
200
201     if ((tmp = OPENSSL_malloc(len * 3 + 1)) == NULL) {
202         CRYPTOerr(CRYPTO_F_OPENSSL_BUF2HEXSTR, ERR_R_MALLOC_FAILURE);
203         return NULL;
204     }
205     q = tmp;
206     for (i = 0, p = buffer; i < len; i++, p++) {
207         *q++ = hexdig[(*p >> 4) & 0xf];
208         *q++ = hexdig[*p & 0xf];
209         *q++ = ':';
210     }
211     q[-1] = 0;
212 #ifdef CHARSET_EBCDIC
213     ebcdic2ascii(tmp, tmp, q - tmp - 1);
214 #endif
215
216     return tmp;
217 }
218
219 int openssl_strerror_r(int errnum, char *buf, size_t buflen)
220 {
221 #if defined(_MSC_VER) && _MSC_VER>=1400
222     return !strerror_s(buf, buflen, errnum);
223 #elif defined(_GNU_SOURCE)
224     return strerror_r(errnum, buf, buflen) != NULL;
225 #elif (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)
226     /*
227      * We can use "real" strerror_r. The OpenSSL version differs in that it
228      * gives 1 on success and 0 on failure for consistency with other OpenSSL
229      * functions. Real strerror_r does it the other way around
230      */
231     return !strerror_r(errnum, buf, buflen);
232 #else
233     char *err;
234     /* Fall back to non-thread safe strerror()...its all we can do */
235     if (buflen < 2)
236         return 0;
237     err = strerror(errnum);
238     /* Can this ever happen? */
239     if (err == NULL)
240         return 0;
241     strncpy(buf, err, buflen - 1);
242     buf[buflen - 1] = '\0';
243     return 1;
244 #endif
245 }