chiark / gitweb /
dirmngr: New debug message on correctly initialized libdns.
[gnupg2.git] / common / convert.c
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 hex2bin (const char *string, void *buffer, size_t length)
49 {
50   int i;
51   const char *s = string;
52
53   for (i=0; i < length; )
54     {
55       if (!hexdigitp (s) || !hexdigitp (s+1))
56         return -1;           /* Invalid hex digits. */
57       ((unsigned char*)buffer)[i++] = xtoi_2 (s);
58       s += 2;
59     }
60   if (*s && (!isascii (*s) || !isspace (*s)) )
61     return -1;             /* Not followed by Nul or white space.  */
62   if (i != length)
63     return -1;             /* Not of expected length.  */
64   if (*s)
65     s++; /* Skip the delimiter. */
66   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 hexcolon2bin (const char *string, void *buffer, size_t length)
80 {
81   int i;
82   const char *s = string;
83   int need_colon = 0;
84
85   for (i=0; i < length; )
86     {
87       if (i==1 && *s == ':')  /* Skip colons between hex digits.  */
88         {
89           need_colon = 1;
90           s++;
91         }
92       else if (need_colon && *s == ':')
93         s++;
94       else if (need_colon)
95         return -1;           /* Colon expected. */
96       if (!hexdigitp (s) || !hexdigitp (s+1))
97         return -1;           /* Invalid hex digits. */
98       ((unsigned char*)buffer)[i++] = xtoi_2 (s);
99       s += 2;
100     }
101   if (*s == ':')
102     return -1;             /* Trailing colons are not allowed.  */
103   if (*s && (!isascii (*s) || !isspace (*s)) )
104     return -1;             /* Not followed by Nul or white space.  */
105   if (i != length)
106     return -1;             /* Not of expected length.  */
107   if (*s)
108     s++; /* Skip the delimiter. */
109   return s - string;
110 }
111
112
113
114 static char *
115 do_bin2hex (const void *buffer, size_t length, char *stringbuf, int with_colon)
116 {
117   const unsigned char *s;
118   char *p;
119
120   if (!stringbuf)
121     {
122       /* Not really correct for with_colon but we don't care about the
123          one wasted byte. */
124       size_t n = with_colon? 3:2;
125       size_t nbytes = n * length + 1;
126       if (length &&  (nbytes-1) / n != length)
127         {
128           gpg_err_set_errno (ENOMEM);
129           return NULL;
130         }
131       stringbuf = xtrymalloc (nbytes);
132       if (!stringbuf)
133         return NULL;
134     }
135
136   for (s = buffer, p = stringbuf; length; length--, s++)
137     {
138       if (with_colon && s != buffer)
139         *p++ = ':';
140       *p++ = tohex ((*s>>4)&15);
141       *p++ = tohex (*s&15);
142     }
143   *p = 0;
144
145   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 bin2hex (const void *buffer, size_t length, char *stringbuf)
157 {
158   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 bin2hexcolon (const void *buffer, size_t length, char *stringbuf)
169 {
170   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 hex2str (const char *hexstring, char *buffer, size_t bufsize, size_t *buflen)
200 {
201   const char *s = hexstring;
202   int idx, count;
203   int need_nul = 0;
204
205   if (buflen)
206     *buflen = 0;
207
208   for (s=hexstring, count=0; hexdigitp (s) && hexdigitp (s+1); s += 2, count++)
209     ;
210   if (*s && (!isascii (*s) || !isspace (*s)) )
211     {
212       gpg_err_set_errno (EINVAL);
213       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   need_nul = ((s == hexstring) || !(s[-2] == '0' && s[-1] == '0'));
218   if (need_nul)
219     count++;
220
221   if (buffer)
222     {
223       if (count > bufsize)
224         {
225           gpg_err_set_errno (EINVAL);
226           return NULL; /* Too long.  */
227         }
228
229       for (s=hexstring, idx=0; hexdigitp (s) && hexdigitp (s+1); s += 2)
230         ((unsigned char*)buffer)[idx++] = xtoi_2 (s);
231       if (need_nul)
232         buffer[idx] = 0;
233     }
234
235   if (buflen)
236     *buflen = count - need_nul;
237   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 hex2str_alloc (const char *hexstring, size_t *r_count)
246 {
247   const char *tail;
248   size_t nbytes;
249   char *result;
250
251   tail = hex2str (hexstring, NULL, 0, &nbytes);
252   if (!tail)
253     {
254       if (r_count)
255         *r_count = 0;
256       return NULL;
257     }
258   if (r_count)
259     *r_count = tail - hexstring;
260   result = xtrymalloc (nbytes+1);
261   if (!result)
262     return NULL;
263   if (!hex2str (hexstring, result, nbytes+1, NULL))
264     BUG ();
265   return result;
266 }