Fixed card key generation of gpg2.
[gnupg.git] / common / convert.c
1 /* convert.c - Hex conversion functions.
2  *      Copyright (C) 2006 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <stdlib.h>
22 #include <errno.h>
23 #include <ctype.h>
24
25 #include "util.h"
26
27
28 #define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
29
30
31 /* Convert STRING consisting of hex characters into its binary
32    representation and store that at BUFFER.  BUFFER needs to be of
33    LENGTH bytes.  The function check that the STRING will convert
34    exactly to LENGTH bytes. The string is delimited by either end of
35    string or a white space character.  The function returns -1 on
36    error or the length of the parsed string.  */
37 int
38 hex2bin (const char *string, void *buffer, size_t length)
39 {
40   int i;
41   const char *s = string;
42
43   for (i=0; i < length; )
44     {
45       if (!hexdigitp (s) || !hexdigitp (s+1))
46         return -1;           /* Invalid hex digits. */
47       ((unsigned char*)buffer)[i++] = xtoi_2 (s);
48       s += 2;
49     }
50   if (*s && (!isascii (*s) || !isspace (*s)) )
51     return -1;             /* Not followed by Nul or white space.  */
52   if (i != length)
53     return -1;             /* Not of expected length.  */
54   if (*s)
55     s++; /* Skip the delimiter. */
56   return s - string;
57 }
58
59
60 /* Convert STRING consisting of hex characters into its binary representation
61    and store that at BUFFER.  BUFFER needs to be of LENGTH bytes.  The
62    function check that the STRING will convert exactly to LENGTH
63    bytes. Colons inbetween the hex digits are allowed, if one colon
64    has been given a colon is expected very 2 characters. The string
65    is delimited by either end of string or a white space character.
66    The function returns -1 on error or the length of the parsed
67    string.  */
68 int
69 hexcolon2bin (const char *string, void *buffer, size_t length)
70 {
71   int i;
72   const char *s = string;
73   int need_colon = 0;
74
75   for (i=0; i < length; )
76     {
77       if (i==1 && *s == ':')  /* Skip colons between hex digits.  */
78         {
79           need_colon = 1;
80           s++;
81         }
82       else if (need_colon && *s == ':')
83         s++;
84       else if (need_colon)
85         return -1;           /* Colon expected. */
86       if (!hexdigitp (s) || !hexdigitp (s+1))
87         return -1;           /* Invalid hex digits. */
88       ((unsigned char*)buffer)[i++] = xtoi_2 (s);
89       s += 2;
90     }
91   if (*s == ':')
92     return -1;             /* Trailing colons are not allowed.  */
93   if (*s && (!isascii (*s) || !isspace (*s)) )
94     return -1;             /* Not followed by Nul or white space.  */
95   if (i != length)
96     return -1;             /* Not of expected length.  */
97   if (*s)
98     s++; /* Skip the delimiter. */
99   return s - string;
100 }
101
102
103 static char *
104 do_bin2hex (const void *buffer, size_t length, char *stringbuf, int with_colon)
105 {
106   const unsigned char *s;
107   char *p;
108   
109   if (!stringbuf)
110     {
111       /* Not really correct for with_colon but we don't care about the
112          one wasted byte. */
113       size_t n = with_colon? 3:2; 
114       size_t nbytes = n * length + 1; 
115       if (length &&  (nbytes-1) / n != length) 
116         {
117           errno = ENOMEM;
118           return NULL;
119         }
120       stringbuf = xtrymalloc (nbytes);
121       if (!stringbuf)
122         return NULL;
123     }
124   
125   for (s = buffer, p = stringbuf; length; length--, s++)
126     {
127       if (with_colon && s != buffer)
128         *p++ = ':';
129       *p++ = tohex ((*s>>4)&15);
130       *p++ = tohex (*s&15);
131     }
132   *p = 0;
133
134   return stringbuf;
135 }
136
137
138 /* Convert LENGTH bytes of data in BUFFER into hex encoding and store
139    that at the provided STRINGBUF.  STRINGBUF must be allocated of at
140    least (2*LENGTH+1) bytes or be NULL so that the function mallocs an
141    appropriate buffer.  Returns STRINGBUF or NULL on error (which may
142    only occur if STRINGBUF has been NULL and the internal malloc
143    failed). */
144 char *
145 bin2hex (const void *buffer, size_t length, char *stringbuf)
146 {
147   return do_bin2hex (buffer, length, stringbuf, 0);
148 }
149
150 /* Convert LENGTH bytes of data in BUFFER into hex encoding and store
151    that at the provided STRINGBUF.  STRINGBUF must be allocated of at
152    least (3*LENGTH+1) bytes or be NULL so that the function mallocs an
153    appropriate buffer.  Returns STRINGBUF or NULL on error (which may
154    only occur if STRINGBUF has been NULL and the internal malloc
155    failed). */
156 char *
157 bin2hexcolon (const void *buffer, size_t length, char *stringbuf)
158 {
159   return do_bin2hex (buffer, length, stringbuf, 1);
160 }
161
162