Line data Source code
1 : /* convert.c - Hex conversion functions.
2 : * Copyright (C) 2006, 2008 Free Software Foundation, Inc.
3 : *
4 : * This file is part of GnuPG.
5 : *
6 : * This file is free software; you can redistribute it and/or modify
7 : * it under the terms of either
8 : *
9 : * - the GNU Lesser General Public License as published by the Free
10 : * Software Foundation; either version 3 of the License, or (at
11 : * your option) any later version.
12 : *
13 : * or
14 : *
15 : * - the GNU General Public License as published by the Free
16 : * Software Foundation; either version 2 of the License, or (at
17 : * your option) any later version.
18 : *
19 : * or both in parallel, as here.
20 : *
21 : * This file is distributed in the hope that it will be useful,
22 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 : * GNU General Public License for more details.
25 : *
26 : * You should have received a copy of the GNU General Public License
27 : * along with this program; if not, see <https://www.gnu.org/licenses/>.
28 : */
29 :
30 : #include <config.h>
31 : #include <stdlib.h>
32 : #include <errno.h>
33 : #include <ctype.h>
34 :
35 : #include "util.h"
36 :
37 :
38 : #define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
39 :
40 :
41 : /* Convert STRING consisting of hex characters into its binary
42 : representation and store that at BUFFER. BUFFER needs to be of
43 : LENGTH bytes. The function checks that the STRING will convert
44 : exactly to LENGTH bytes. The string is delimited by either end of
45 : string or a white space character. The function returns -1 on
46 : error or the length of the parsed string. */
47 : int
48 1755 : hex2bin (const char *string, void *buffer, size_t length)
49 : {
50 : int i;
51 1755 : const char *s = string;
52 :
53 38363 : for (i=0; i < length; )
54 : {
55 34863 : if (!hexdigitp (s) || !hexdigitp (s+1))
56 10 : return -1; /* Invalid hex digits. */
57 34853 : ((unsigned char*)buffer)[i++] = xtoi_2 (s);
58 34853 : s += 2;
59 : }
60 1745 : if (*s && (!isascii (*s) || !isspace (*s)) )
61 6 : return -1; /* Not followed by Nul or white space. */
62 1739 : if (i != length)
63 0 : return -1; /* Not of expected length. */
64 1739 : if (*s)
65 415 : s++; /* Skip the delimiter. */
66 1739 : return s - string;
67 : }
68 :
69 :
70 : /* Convert STRING consisting of hex characters into its binary representation
71 : and store that at BUFFER. BUFFER needs to be of LENGTH bytes. The
72 : function check that the STRING will convert exactly to LENGTH
73 : bytes. Colons between the hex digits are allowed, if one colon
74 : has been given a colon is expected very 2 characters. The string
75 : is delimited by either end of string or a white space character.
76 : The function returns -1 on error or the length of the parsed
77 : string. */
78 : int
79 32 : hexcolon2bin (const char *string, void *buffer, size_t length)
80 : {
81 : int i;
82 32 : const char *s = string;
83 32 : int need_colon = 0;
84 :
85 389 : for (i=0; i < length; )
86 : {
87 339 : if (i==1 && *s == ':') /* Skip colons between hex digits. */
88 : {
89 5 : need_colon = 1;
90 5 : s++;
91 : }
92 334 : else if (need_colon && *s == ':')
93 53 : s++;
94 281 : else if (need_colon)
95 3 : return -1; /* Colon expected. */
96 336 : if (!hexdigitp (s) || !hexdigitp (s+1))
97 11 : return -1; /* Invalid hex digits. */
98 325 : ((unsigned char*)buffer)[i++] = xtoi_2 (s);
99 325 : s += 2;
100 : }
101 18 : if (*s == ':')
102 2 : return -1; /* Trailing colons are not allowed. */
103 16 : if (*s && (!isascii (*s) || !isspace (*s)) )
104 4 : return -1; /* Not followed by Nul or white space. */
105 12 : if (i != length)
106 0 : return -1; /* Not of expected length. */
107 12 : if (*s)
108 6 : s++; /* Skip the delimiter. */
109 12 : return s - string;
110 : }
111 :
112 :
113 :
114 : static char *
115 5110 : do_bin2hex (const void *buffer, size_t length, char *stringbuf, int with_colon)
116 : {
117 : const unsigned char *s;
118 : char *p;
119 :
120 5110 : if (!stringbuf)
121 : {
122 : /* Not really correct for with_colon but we don't care about the
123 : one wasted byte. */
124 280 : size_t n = with_colon? 3:2;
125 280 : size_t nbytes = n * length + 1;
126 280 : if (length && (nbytes-1) / n != length)
127 : {
128 2 : gpg_err_set_errno (ENOMEM);
129 2 : return NULL;
130 : }
131 278 : stringbuf = xtrymalloc (nbytes);
132 278 : if (!stringbuf)
133 0 : return NULL;
134 : }
135 :
136 105920 : for (s = buffer, p = stringbuf; length; length--, s++)
137 : {
138 100812 : if (with_colon && s != buffer)
139 203 : *p++ = ':';
140 100812 : *p++ = tohex ((*s>>4)&15);
141 100812 : *p++ = tohex (*s&15);
142 : }
143 5108 : *p = 0;
144 :
145 5108 : return stringbuf;
146 : }
147 :
148 :
149 : /* Convert LENGTH bytes of data in BUFFER into hex encoding and store
150 : that at the provided STRINGBUF. STRINGBUF must be allocated of at
151 : least (2*LENGTH+1) bytes or be NULL so that the function mallocs an
152 : appropriate buffer. Returns STRINGBUF or NULL on error (which may
153 : only occur if STRINGBUF has been NULL and the internal malloc
154 : failed). */
155 : char *
156 5096 : bin2hex (const void *buffer, size_t length, char *stringbuf)
157 : {
158 5096 : return do_bin2hex (buffer, length, stringbuf, 0);
159 : }
160 :
161 : /* Convert LENGTH bytes of data in BUFFER into hex encoding and store
162 : that at the provided STRINGBUF. STRINGBUF must be allocated of at
163 : least (3*LENGTH+1) bytes or be NULL so that the function mallocs an
164 : appropriate buffer. Returns STRINGBUF or NULL on error (which may
165 : only occur if STRINGBUF has been NULL and the internal malloc
166 : failed). */
167 : char *
168 14 : bin2hexcolon (const void *buffer, size_t length, char *stringbuf)
169 : {
170 14 : return do_bin2hex (buffer, length, stringbuf, 1);
171 : }
172 :
173 :
174 :
175 : /* Convert HEXSTRING consisting of hex characters into string and
176 : store that at BUFFER. HEXSTRING is either delimited by end of
177 : string or a white space character. The function makes sure that
178 : the resulting string in BUFFER is terminated by a Nul byte. Note
179 : that the returned string may include embedded Nul bytes; the extra
180 : Nul byte at the end is used to make sure tha the result can always
181 : be used as a C-string.
182 :
183 : BUFSIZE is the available length of BUFFER; if the converted result
184 : plus a possible required extra Nul character does not fit into this
185 : buffer, the function returns NULL and won't change the existing
186 : content of BUFFER. In-place conversion is possible as long as
187 : BUFFER points to HEXSTRING.
188 :
189 : If BUFFER is NULL and BUFSIZE is 0 the function scans HEXSTRING but
190 : does not store anything. This may be used to find the end of
191 : HEXSTRING.
192 :
193 : On success the function returns a pointer to the next character
194 : after HEXSTRING (which is either end-of-string or a the next white
195 : space). If BUFLEN is not NULL the number of valid vytes in BUFFER
196 : is stored there (an extra Nul byte is not counted); this will even
197 : be done if BUFFER has been passed as NULL. */
198 : const char *
199 221 : hex2str (const char *hexstring, char *buffer, size_t bufsize, size_t *buflen)
200 : {
201 221 : const char *s = hexstring;
202 : int idx, count;
203 221 : int need_nul = 0;
204 :
205 221 : if (buflen)
206 74 : *buflen = 0;
207 :
208 221 : for (s=hexstring, count=0; hexdigitp (s) && hexdigitp (s+1); s += 2, count++)
209 : ;
210 221 : if (*s && (!isascii (*s) || !isspace (*s)) )
211 : {
212 30 : gpg_err_set_errno (EINVAL);
213 30 : return NULL; /* Not followed by Nul or white space. */
214 : }
215 : /* We need to append a nul character. However we don't want that if
216 : the hexstring already ends with "00". */
217 191 : need_nul = ((s == hexstring) || !(s[-2] == '0' && s[-1] == '0'));
218 191 : if (need_nul)
219 169 : count++;
220 :
221 191 : if (buffer)
222 : {
223 179 : if (count > bufsize)
224 : {
225 8 : gpg_err_set_errno (EINVAL);
226 8 : return NULL; /* Too long. */
227 : }
228 :
229 1017 : for (s=hexstring, idx=0; hexdigitp (s) && hexdigitp (s+1); s += 2)
230 846 : ((unsigned char*)buffer)[idx++] = xtoi_2 (s);
231 171 : if (need_nul)
232 156 : buffer[idx] = 0;
233 : }
234 :
235 183 : if (buflen)
236 36 : *buflen = count - need_nul;
237 183 : return s;
238 : }
239 :
240 :
241 : /* Same as hex2str but this function allocated a new string. Returns
242 : NULL on error. If R_COUNT is not NULL, the number of scanned bytes
243 : will be stored there. ERRNO is set on error. */
244 : char *
245 22 : hex2str_alloc (const char *hexstring, size_t *r_count)
246 : {
247 : const char *tail;
248 : size_t nbytes;
249 : char *result;
250 :
251 22 : tail = hex2str (hexstring, NULL, 0, &nbytes);
252 22 : if (!tail)
253 : {
254 10 : if (r_count)
255 10 : *r_count = 0;
256 10 : return NULL;
257 : }
258 12 : if (r_count)
259 12 : *r_count = tail - hexstring;
260 12 : result = xtrymalloc (nbytes+1);
261 12 : if (!result)
262 0 : return NULL;
263 12 : if (!hex2str (hexstring, result, nbytes+1, NULL))
264 0 : BUG ();
265 12 : return result;
266 : }
|