Add code to allow for late memory cleanup.
[gnupg.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 <http://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 inbetween 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 character.
179    BUFSIZE is the availabe length of BUFFER; if the converted result
180    plus a possible required Nul character does not fit into this
181    buffer, the function returns NULL and won't change the existing
182    conent of buffer.  In-place conversion is possible as long as
183    BUFFER points to HEXSTRING.
184
185    If BUFFER is NULL and bufsize is 0 the function scans HEXSTRING but
186    does not store anything.  This may be used to find the end of
187    hexstring.
188
189    On sucess the function returns a pointer to the next character
190    after HEXSTRING (which is either end-of-string or a the next white
191    space).  If BUFLEN is not NULL the strlen of buffer is stored
192    there; this will even be done if BUFFER has been passed as NULL. */
193 const char *
194 hex2str (const char *hexstring, char *buffer, size_t bufsize, size_t *buflen)
195 {
196   const char *s = hexstring;
197   int idx, count;
198   int need_nul = 0;
199
200   if (buflen)
201     *buflen = 0;
202
203   for (s=hexstring, count=0; hexdigitp (s) && hexdigitp (s+1); s += 2, count++)
204     ;
205   if (*s && (!isascii (*s) || !isspace (*s)) )
206     return NULL;   /* Not followed by Nul or white space.  */
207   /* We need to append a nul character.  However we don't want that if
208      the hexstring already ends with "00".  */
209   need_nul = ((s == hexstring) || !(s[-2] == '0' && s[-1] == '0'));
210   if (need_nul)
211     count++;
212
213   if (buffer)
214     {
215       if (count > bufsize)
216         return NULL; /* Too long.  */
217
218       for (s=hexstring, idx=0; hexdigitp (s) && hexdigitp (s+1); s += 2)
219         ((unsigned char*)buffer)[idx++] = xtoi_2 (s);
220       if (need_nul)
221         buffer[idx] = 0;
222     }
223
224   if (buflen)
225     *buflen = count - 1;
226   return s;
227 }
228
229
230 /* Same as hex2str but this function allocated a new string.  Returns
231    NULL on error.  If R_COUNT is not NULL, the number of scanned bytes
232    will be stored there.  ERRNO is set on error. */
233 char *
234 hex2str_alloc (const char *hexstring, size_t *r_count)
235 {
236   const char *tail;
237   size_t nbytes;
238   char *result;
239
240   tail = hex2str (hexstring, NULL, 0, &nbytes);
241   if (!tail)
242     {
243       if (r_count)
244         *r_count = 0;
245       gpg_err_set_errno (EINVAL);
246       return NULL;
247     }
248   if (r_count)
249     *r_count = tail - hexstring;
250   result = xtrymalloc (nbytes+1);
251   if (!result)
252     return NULL;
253   if (!hex2str (hexstring, result, nbytes+1, NULL))
254     BUG ();
255   return result;
256 }