Qt: Add testTofuSignCount
[gpgme.git] / src / conversion.c
1 /* conversion.c - String conversion helper functions.
2    Copyright (C) 2000 Werner Koch (dd9jn)
3    Copyright (C) 2001, 2002, 2003, 2004, 2007 g10 Code GmbH
4
5    This file is part of GPGME.
6
7    GPGME is free software; you can redistribute it and/or modify it
8    under the terms of the GNU Lesser General Public License as
9    published by the Free Software Foundation; either version 2.1 of
10    the License, or (at your option) any later version.
11
12    GPGME is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Lesser General Public License for more details.
16
17    You should have received a copy of the GNU Lesser General Public
18    License along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20    02111-1307, USA.  */
21
22 #if HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdlib.h>
27 #include <string.h>
28 #ifdef HAVE_SYS_TYPES_H
29   /* Solaris 8 needs sys/types.h before time.h.  */
30 # include <sys/types.h>
31 #endif
32 #include <time.h>
33 #include <errno.h>
34
35 #include "gpgme.h"
36 #include "util.h"
37 #include "debug.h"
38
39 #define atoi_1(p)   (*(p) - '0' )
40 #define atoi_2(p)   ((atoi_1(p) * 10) + atoi_1((p)+1))
41 #define atoi_4(p)   ((atoi_2(p) * 100) + atoi_2((p)+2))
42
43
44 \f
45 /* Convert two hexadecimal digits from STR to the value they
46    represent.  Returns -1 if one of the characters is not a
47    hexadecimal digit.  */
48 int
49 _gpgme_hextobyte (const char *str)
50 {
51   int val = 0;
52   int i;
53
54 #define NROFHEXDIGITS 2
55   for (i = 0; i < NROFHEXDIGITS; i++)
56     {
57       if (*str >= '0' && *str <= '9')
58         val += *str - '0';
59       else if (*str >= 'A' && *str <= 'F')
60         val += 10 + *str - 'A';
61       else if (*str >= 'a' && *str <= 'f')
62         val += 10 + *str - 'a';
63       else
64         return -1;
65       if (i < NROFHEXDIGITS - 1)
66         val *= 16;
67       str++;
68     }
69   return val;
70 }
71
72
73 /* Decode the C formatted string SRC and store the result in the
74    buffer *DESTP which is LEN bytes long.  If LEN is zero, then a
75    large enough buffer is allocated with malloc and *DESTP is set to
76    the result.  Currently, LEN is only used to specify if allocation
77    is desired or not, the caller is expected to make sure that *DESTP
78    is large enough if LEN is not zero.  */
79 gpgme_error_t
80 _gpgme_decode_c_string (const char *src, char **destp, size_t len)
81 {
82   char *dest;
83
84   /* Set up the destination buffer.  */
85   if (len)
86     {
87       if (len < strlen (src) + 1)
88         return gpg_error (GPG_ERR_INTERNAL);
89
90       dest = *destp;
91     }
92   else
93     {
94       /* The converted string will never be larger than the original
95          string.  */
96       dest = malloc (strlen (src) + 1);
97       if (!dest)
98         return gpg_error_from_syserror ();
99
100       *destp = dest;
101     }
102
103   /* Convert the string.  */
104   while (*src)
105     {
106       if (*src != '\\')
107         {
108           *(dest++) = *(src++);
109           continue;
110         }
111
112       switch (src[1])
113         {
114 #define DECODE_ONE(match,result)        \
115         case match:                     \
116           src += 2;                     \
117           *(dest++) = result;           \
118           break;
119
120           DECODE_ONE ('\'', '\'');
121           DECODE_ONE ('\"', '\"');
122           DECODE_ONE ('\?', '\?');
123           DECODE_ONE ('\\', '\\');
124           DECODE_ONE ('a', '\a');
125           DECODE_ONE ('b', '\b');
126           DECODE_ONE ('f', '\f');
127           DECODE_ONE ('n', '\n');
128           DECODE_ONE ('r', '\r');
129           DECODE_ONE ('t', '\t');
130           DECODE_ONE ('v', '\v');
131
132         case 'x':
133           {
134             int val = _gpgme_hextobyte (&src[2]);
135
136             if (val == -1)
137               {
138                 /* Should not happen.  */
139                 *(dest++) = *(src++);
140                 *(dest++) = *(src++);
141                 if (*src)
142                   *(dest++) = *(src++);
143                 if (*src)
144                   *(dest++) = *(src++);
145               }
146             else
147               {
148                 if (!val)
149                   {
150                     /* A binary zero is not representable in a C
151                        string.  */
152                     *(dest++) = '\\';
153                     *(dest++) = '0';
154                   }
155                 else
156                   *((unsigned char *) dest++) = val;
157                 src += 4;
158               }
159           }
160           break;
161
162         default:
163           {
164             /* Should not happen.  */
165             *(dest++) = *(src++);
166             *(dest++) = *(src++);
167           }
168         }
169     }
170   *(dest++) = 0;
171
172   return 0;
173 }
174
175
176 /* Decode the percent escaped string SRC and store the result in the
177    buffer *DESTP which is LEN bytes long.  If LEN is zero, then a
178    large enough buffer is allocated with malloc and *DESTP is set to
179    the result.  Currently, LEN is only used to specify if allocation
180    is desired or not, the caller is expected to make sure that *DESTP
181    is large enough if LEN is not zero.  If BINARY is 1, then '\0'
182    characters are allowed in the output.  */
183 gpgme_error_t
184 _gpgme_decode_percent_string (const char *src, char **destp, size_t len,
185                               int binary)
186 {
187   char *dest;
188
189   /* Set up the destination buffer.  */
190   if (len)
191     {
192       if (len < strlen (src) + 1)
193         return gpg_error (GPG_ERR_INTERNAL);
194
195       dest = *destp;
196     }
197   else
198     {
199       /* The converted string will never be larger than the original
200          string.  */
201       dest = malloc (strlen (src) + 1);
202       if (!dest)
203         return gpg_error_from_syserror ();
204
205       *destp = dest;
206     }
207
208   /* Convert the string.  */
209   while (*src)
210     {
211       if (*src != '%')
212         {
213           *(dest++) = *(src++);
214           continue;
215         }
216       else
217         {
218           int val = _gpgme_hextobyte (&src[1]);
219
220           if (val == -1)
221             {
222               /* Should not happen.  */
223               *(dest++) = *(src++);
224               if (*src)
225                 *(dest++) = *(src++);
226               if (*src)
227                 *(dest++) = *(src++);
228             }
229           else
230             {
231               if (!val && !binary)
232                 {
233                   /* A binary zero is not representable in a C
234                      string.  */
235                   *(dest++) = '\\';
236                   *(dest++) = '0';
237                 }
238               else
239                 *((unsigned char *) dest++) = val;
240               src += 3;
241             }
242         }
243     }
244   *(dest++) = 0;
245
246   return 0;
247 }
248
249
250 /* Encode the string SRC with percent escaping and store the result in
251    the buffer *DESTP which is LEN bytes long.  If LEN is zero, then a
252    large enough buffer is allocated with malloc and *DESTP is set to
253    the result.  Currently, LEN is only used to specify if allocation
254    is desired or not, the caller is expected to make sure that *DESTP
255    is large enough if LEN is not zero.  If BINARY is 1, then '\0'
256    characters are allowed in the output.  */
257 gpgme_error_t
258 _gpgme_encode_percent_string (const char *src, char **destp, size_t len)
259 {
260   size_t destlen;
261   char *dest;
262   const char *str;
263
264   destlen = 0;
265   str = src;
266   /* We percent-escape the + character because the user might need a
267      "percent plus" escaped string (special gpg format).  But we
268      percent-escape the space character, which works with and without
269      the special plus format.  */
270   while (*str)
271     {
272       if (*str == '+' || *str == '\"' || *str == '%'
273           || *(const unsigned char *)str <= 0x20)
274         destlen += 3;
275       else
276         destlen++;
277       str++;
278     }
279   /* Terminating nul byte.  */
280   destlen++;
281
282   /* Set up the destination buffer.  */
283   if (len)
284     {
285       if (len < destlen)
286         return gpg_error (GPG_ERR_INTERNAL);
287
288       dest = *destp;
289     }
290   else
291     {
292       /* The converted string will never be larger than the original
293          string.  */
294       dest = malloc (destlen);
295       if (!dest)
296         return gpg_error_from_syserror ();
297
298       *destp = dest;
299     }
300
301   /* Convert the string.  */
302   while (*src)
303     {
304       if (*src == '+' || *src == '\"' || *src == '%'
305           || *(const unsigned char *)src <= 0x20)
306         {
307           snprintf (dest, 4, "%%%02X", *(unsigned char *)src);
308           dest += 3;
309         }
310       else
311         *(dest++) = *src;
312       src++;
313     }
314   *(dest++) = 0;
315
316   return 0;
317 }
318
319
320 /* Split a string into space delimited fields and remove leading and
321  * trailing spaces from each field.  A pointer to the each field is
322  * stored in ARRAY.  Stop splitting at ARRAYSIZE fields.  The function
323  * modifies STRING.  The number of parsed fields is returned.
324  */
325 int
326 _gpgme_split_fields (char *string, char **array, int arraysize)
327 {
328   int n = 0;
329   char *p, *pend;
330
331   for (p = string; *p == ' '; p++)
332     ;
333   do
334     {
335       if (n == arraysize)
336         break;
337       array[n++] = p;
338       pend = strchr (p, ' ');
339       if (!pend)
340         break;
341       *pend++ = 0;
342       for (p = pend; *p == ' '; p++)
343         ;
344     }
345   while (*p);
346
347   return n;
348 }
349
350 /* Convert the field STRING into an unsigned long value.  Check for
351  * trailing garbage.  */
352 gpgme_error_t
353 _gpgme_strtoul_field (const char *string, unsigned long *result)
354 {
355   char *endp;
356
357   gpg_err_set_errno (0);
358   *result = strtoul (string, &endp, 0);
359   if (errno)
360     return gpg_error_from_syserror ();
361   if (endp == string || *endp)
362     return gpg_error (GPG_ERR_INV_VALUE);
363   return 0;
364 }
365
366
367 #ifdef HAVE_W32_SYSTEM
368 static time_t
369 _gpgme_timegm (struct tm *tm)
370 {
371   /* This one is thread safe.  */
372   SYSTEMTIME st;
373   FILETIME ft;
374   unsigned long long cnsecs;
375
376   st.wYear   = tm->tm_year + 1900;
377   st.wMonth  = tm->tm_mon  + 1;
378   st.wDay    = tm->tm_mday;
379   st.wHour   = tm->tm_hour;
380   st.wMinute = tm->tm_min;
381   st.wSecond = tm->tm_sec;
382   st.wMilliseconds = 0; /* Not available.  */
383   st.wDayOfWeek = 0;    /* Ignored.  */
384
385   /* System time is UTC thus the conversion is pretty easy.  */
386   if (!SystemTimeToFileTime (&st, &ft))
387     {
388       gpg_err_set_errno (EINVAL);
389       return (time_t)(-1);
390     }
391
392   cnsecs = (((unsigned long long)ft.dwHighDateTime << 32)
393             | ft.dwLowDateTime);
394   cnsecs -= 116444736000000000ULL; /* The filetime epoch is 1601-01-01.  */
395   return (time_t)(cnsecs / 10000000ULL);
396 }
397 #endif
398
399
400 /* Parse the string TIMESTAMP into a time_t.  The string may either be
401    seconds since Epoch or in the ISO 8601 format like
402    "20390815T143012".  Returns 0 for an empty string or seconds since
403    Epoch. Leading spaces are skipped. If ENDP is not NULL, it will
404    point to the next non-parsed character in TIMESTRING. */
405 time_t
406 _gpgme_parse_timestamp (const char *timestamp, char **endp)
407 {
408   /* Need to skip leading spaces, because that is what strtoul does
409      but not our ISO 8601 checking code. */
410   while (*timestamp && *timestamp== ' ')
411     timestamp++;
412   if (!*timestamp)
413     return 0;
414
415   if (strlen (timestamp) >= 15 && timestamp[8] == 'T')
416     {
417       struct tm buf;
418       int year;
419
420       year = atoi_4 (timestamp);
421       if (year < 1900)
422         return (time_t)(-1);
423
424       if (endp)
425         *endp = (char*)(timestamp + 15);
426
427       /* Fixme: We would better use a configure test to see whether
428          mktime can handle dates beyond 2038. */
429       if (sizeof (time_t) <= 4 && year >= 2038)
430         return (time_t)2145914603; /* 2037-12-31 23:23:23 */
431
432       memset (&buf, 0, sizeof buf);
433       buf.tm_year = year - 1900;
434       buf.tm_mon = atoi_2 (timestamp+4) - 1;
435       buf.tm_mday = atoi_2 (timestamp+6);
436       buf.tm_hour = atoi_2 (timestamp+9);
437       buf.tm_min = atoi_2 (timestamp+11);
438       buf.tm_sec = atoi_2 (timestamp+13);
439
440 #ifdef HAVE_W32_SYSTEM
441       return _gpgme_timegm (&buf);
442 #else
443 #ifdef HAVE_TIMEGM
444       return timegm (&buf);
445 #else
446       {
447         time_t tim;
448
449         putenv ("TZ=UTC");
450         tim = mktime (&buf);
451 #ifdef __GNUC__
452 #warning fixme: we must somehow reset TZ here.  It is not threadsafe anyway.
453 #endif
454         return tim;
455       }
456 #endif /* !HAVE_TIMEGM */
457 #endif /* !HAVE_W32_SYSTEM */
458     }
459   else
460     return (time_t)strtoul (timestamp, endp, 10);
461 }
462
463
464 /* The GPG backend uses OpenPGP algorithm numbers which we need to map
465    to our algorithm numbers.  This function MUST not change ERRNO. */
466 int
467 _gpgme_map_pk_algo (int algo, gpgme_protocol_t protocol)
468 {
469   if (protocol == GPGME_PROTOCOL_OPENPGP)
470     {
471       switch (algo)
472         {
473         case 1: case 2: case 3: case 16: case 17: break;
474         case 18: algo = GPGME_PK_ECDH; break;
475         case 19: algo = GPGME_PK_ECDSA; break;
476         case 20: break;
477         case 22: algo = GPGME_PK_EDDSA; break;
478         default: algo = 0; break; /* Unknown.  */
479         }
480     }
481
482   return algo;
483 }