core: Do not crash if CMS plaintext is ignored
[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 #include <stdarg.h>
35
36 #include "gpgme.h"
37 #include "util.h"
38 #include "debug.h"
39
40 #define atoi_1(p)   (*(p) - '0' )
41 #define atoi_2(p)   ((atoi_1(p) * 10) + atoi_1((p)+1))
42 #define atoi_4(p)   ((atoi_2(p) * 100) + atoi_2((p)+2))
43
44
45 \f
46 static char *
47 do_strconcat (const char *s1, va_list arg_ptr)
48 {
49   const char *argv[16];
50   size_t argc;
51   size_t needed;
52   char *buffer, *p;
53
54   argc = 0;
55   argv[argc++] = s1;
56   needed = strlen (s1);
57   while (((argv[argc] = va_arg (arg_ptr, const char *))))
58     {
59       needed += strlen (argv[argc]);
60       if (argc >= DIM (argv)-1)
61         {
62           gpg_err_set_errno (EINVAL);
63           return NULL;
64         }
65       argc++;
66     }
67   needed++;
68   buffer = malloc (needed);
69   if (buffer)
70     {
71       for (p = buffer, argc=0; argv[argc]; argc++)
72         p = stpcpy (p, argv[argc]);
73     }
74   return buffer;
75 }
76
77
78 /* Concatenate the string S1 with all the following strings up to a
79  * NULL.  Returns a malloced buffer with the new string or NULL on a
80    malloc error or if too many arguments are given.  */
81 char *
82 _gpgme_strconcat (const char *s1, ...)
83 {
84   va_list arg_ptr;
85   char *result;
86
87   if (!s1)
88     result = strdup ("");
89   else
90     {
91       va_start (arg_ptr, s1);
92       result = do_strconcat (s1, arg_ptr);
93       va_end (arg_ptr);
94     }
95   return result;
96 }
97
98
99
100 \f
101 /* Convert two hexadecimal digits from STR to the value they
102    represent.  Returns -1 if one of the characters is not a
103    hexadecimal digit.  */
104 int
105 _gpgme_hextobyte (const char *str)
106 {
107   int val = 0;
108   int i;
109
110 #define NROFHEXDIGITS 2
111   for (i = 0; i < NROFHEXDIGITS; i++)
112     {
113       if (*str >= '0' && *str <= '9')
114         val += *str - '0';
115       else if (*str >= 'A' && *str <= 'F')
116         val += 10 + *str - 'A';
117       else if (*str >= 'a' && *str <= 'f')
118         val += 10 + *str - 'a';
119       else
120         return -1;
121       if (i < NROFHEXDIGITS - 1)
122         val *= 16;
123       str++;
124     }
125   return val;
126 }
127
128
129 /* Decode the C formatted string SRC and store the result in the
130    buffer *DESTP which is LEN bytes long.  If LEN is zero, then a
131    large enough buffer is allocated with malloc and *DESTP is set to
132    the result.  Currently, LEN is only used to specify if allocation
133    is desired or not, the caller is expected to make sure that *DESTP
134    is large enough if LEN is not zero.  */
135 gpgme_error_t
136 _gpgme_decode_c_string (const char *src, char **destp, size_t len)
137 {
138   char *dest;
139
140   /* Set up the destination buffer.  */
141   if (len)
142     {
143       if (len < strlen (src) + 1)
144         return gpg_error (GPG_ERR_INTERNAL);
145
146       dest = *destp;
147     }
148   else
149     {
150       /* The converted string will never be larger than the original
151          string.  */
152       dest = malloc (strlen (src) + 1);
153       if (!dest)
154         return gpg_error_from_syserror ();
155
156       *destp = dest;
157     }
158
159   /* Convert the string.  */
160   while (*src)
161     {
162       if (*src != '\\')
163         {
164           *(dest++) = *(src++);
165           continue;
166         }
167
168       switch (src[1])
169         {
170 #define DECODE_ONE(match,result)        \
171         case match:                     \
172           src += 2;                     \
173           *(dest++) = result;           \
174           break;
175
176           DECODE_ONE ('\'', '\'');
177           DECODE_ONE ('\"', '\"');
178           DECODE_ONE ('\?', '\?');
179           DECODE_ONE ('\\', '\\');
180           DECODE_ONE ('a', '\a');
181           DECODE_ONE ('b', '\b');
182           DECODE_ONE ('f', '\f');
183           DECODE_ONE ('n', '\n');
184           DECODE_ONE ('r', '\r');
185           DECODE_ONE ('t', '\t');
186           DECODE_ONE ('v', '\v');
187
188         case 'x':
189           {
190             int val = _gpgme_hextobyte (&src[2]);
191
192             if (val == -1)
193               {
194                 /* Should not happen.  */
195                 *(dest++) = *(src++);
196                 *(dest++) = *(src++);
197                 if (*src)
198                   *(dest++) = *(src++);
199                 if (*src)
200                   *(dest++) = *(src++);
201               }
202             else
203               {
204                 if (!val)
205                   {
206                     /* A binary zero is not representable in a C
207                        string.  */
208                     *(dest++) = '\\';
209                     *(dest++) = '0';
210                   }
211                 else
212                   *((unsigned char *) dest++) = val;
213                 src += 4;
214               }
215           }
216           break;
217
218         default:
219           {
220             /* Should not happen.  */
221             *(dest++) = *(src++);
222             *(dest++) = *(src++);
223           }
224         }
225     }
226   *(dest++) = 0;
227
228   return 0;
229 }
230
231
232 /* Decode the percent escaped string SRC and store the result in the
233    buffer *DESTP which is LEN bytes long.  If LEN is zero, then a
234    large enough buffer is allocated with malloc and *DESTP is set to
235    the result.  Currently, LEN is only used to specify if allocation
236    is desired or not, the caller is expected to make sure that *DESTP
237    is large enough if LEN is not zero.  If BINARY is 1, then '\0'
238    characters are allowed in the output.  */
239 gpgme_error_t
240 _gpgme_decode_percent_string (const char *src, char **destp, size_t len,
241                               int binary)
242 {
243   char *dest;
244
245   /* Set up the destination buffer.  */
246   if (len)
247     {
248       if (len < strlen (src) + 1)
249         return gpg_error (GPG_ERR_INTERNAL);
250
251       dest = *destp;
252     }
253   else
254     {
255       /* The converted string will never be larger than the original
256          string.  */
257       dest = malloc (strlen (src) + 1);
258       if (!dest)
259         return gpg_error_from_syserror ();
260
261       *destp = dest;
262     }
263
264   /* Convert the string.  */
265   while (*src)
266     {
267       if (*src != '%')
268         {
269           *(dest++) = *(src++);
270           continue;
271         }
272       else
273         {
274           int val = _gpgme_hextobyte (&src[1]);
275
276           if (val == -1)
277             {
278               /* Should not happen.  */
279               *(dest++) = *(src++);
280               if (*src)
281                 *(dest++) = *(src++);
282               if (*src)
283                 *(dest++) = *(src++);
284             }
285           else
286             {
287               if (!val && !binary)
288                 {
289                   /* A binary zero is not representable in a C
290                      string.  */
291                   *(dest++) = '\\';
292                   *(dest++) = '0';
293                 }
294               else
295                 *((unsigned char *) dest++) = val;
296               src += 3;
297             }
298         }
299     }
300   *(dest++) = 0;
301
302   return 0;
303 }
304
305
306 /* Encode the string SRC with percent escaping and store the result in
307    the buffer *DESTP which is LEN bytes long.  If LEN is zero, then a
308    large enough buffer is allocated with malloc and *DESTP is set to
309    the result.  Currently, LEN is only used to specify if allocation
310    is desired or not, the caller is expected to make sure that *DESTP
311    is large enough if LEN is not zero.  If BINARY is 1, then '\0'
312    characters are allowed in the output.  */
313 gpgme_error_t
314 _gpgme_encode_percent_string (const char *src, char **destp, size_t len)
315 {
316   size_t destlen;
317   char *dest;
318   const char *str;
319
320   destlen = 0;
321   str = src;
322   /* We percent-escape the + character because the user might need a
323      "percent plus" escaped string (special gpg format).  But we
324      percent-escape the space character, which works with and without
325      the special plus format.  */
326   while (*str)
327     {
328       if (*str == '+' || *str == '\"' || *str == '%'
329           || *(const unsigned char *)str <= 0x20)
330         destlen += 3;
331       else
332         destlen++;
333       str++;
334     }
335   /* Terminating nul byte.  */
336   destlen++;
337
338   /* Set up the destination buffer.  */
339   if (len)
340     {
341       if (len < destlen)
342         return gpg_error (GPG_ERR_INTERNAL);
343
344       dest = *destp;
345     }
346   else
347     {
348       /* The converted string will never be larger than the original
349          string.  */
350       dest = malloc (destlen);
351       if (!dest)
352         return gpg_error_from_syserror ();
353
354       *destp = dest;
355     }
356
357   /* Convert the string.  */
358   while (*src)
359     {
360       if (*src == '+' || *src == '\"' || *src == '%'
361           || *(const unsigned char *)src <= 0x20)
362         {
363           snprintf (dest, 4, "%%%02X", *(unsigned char *)src);
364           dest += 3;
365         }
366       else
367         *(dest++) = *src;
368       src++;
369     }
370   *(dest++) = 0;
371
372   return 0;
373 }
374
375
376 /* Split a string into space delimited fields and remove leading and
377  * trailing spaces from each field.  A pointer to each field is
378  * stored in ARRAY.  Stop splitting at ARRAYSIZE fields.  The function
379  * modifies STRING.  The number of parsed fields is returned.
380  */
381 int
382 _gpgme_split_fields (char *string, char **array, int arraysize)
383 {
384   int n = 0;
385   char *p, *pend;
386
387   for (p = string; *p == ' '; p++)
388     ;
389   do
390     {
391       if (n == arraysize)
392         break;
393       array[n++] = p;
394       pend = strchr (p, ' ');
395       if (!pend)
396         break;
397       *pend++ = 0;
398       for (p = pend; *p == ' '; p++)
399         ;
400     }
401   while (*p);
402
403   return n;
404 }
405
406 /* Convert the field STRING into an unsigned long value.  Check for
407  * trailing garbage.  */
408 gpgme_error_t
409 _gpgme_strtoul_field (const char *string, unsigned long *result)
410 {
411   char *endp;
412
413   gpg_err_set_errno (0);
414   *result = strtoul (string, &endp, 0);
415   if (errno)
416     return gpg_error_from_syserror ();
417   if (endp == string || *endp)
418     return gpg_error (GPG_ERR_INV_VALUE);
419   return 0;
420 }
421
422
423 /* Convert STRING into an offset value.  Note that this functions only
424  * allows for a base-10 length.  This function is similar to atoi()
425  * and thus there is no error checking.  */
426 gpgme_off_t
427 _gpgme_string_to_off (const char *string)
428 {
429   gpgme_off_t value = 0;
430
431   while (*string == ' ' || *string == '\t')
432     string++;
433   for (; *string >= '0' && *string <= '9'; string++)
434     {
435       value *= 10;
436       value += atoi_1 (string);
437     }
438   return value;
439 }
440
441
442 #ifdef HAVE_W32_SYSTEM
443 static time_t
444 _gpgme_timegm (struct tm *tm)
445 {
446   /* This one is thread safe.  */
447   SYSTEMTIME st;
448   FILETIME ft;
449   unsigned long long cnsecs;
450
451   st.wYear   = tm->tm_year + 1900;
452   st.wMonth  = tm->tm_mon  + 1;
453   st.wDay    = tm->tm_mday;
454   st.wHour   = tm->tm_hour;
455   st.wMinute = tm->tm_min;
456   st.wSecond = tm->tm_sec;
457   st.wMilliseconds = 0; /* Not available.  */
458   st.wDayOfWeek = 0;    /* Ignored.  */
459
460   /* System time is UTC thus the conversion is pretty easy.  */
461   if (!SystemTimeToFileTime (&st, &ft))
462     {
463       gpg_err_set_errno (EINVAL);
464       return (time_t)(-1);
465     }
466
467   cnsecs = (((unsigned long long)ft.dwHighDateTime << 32)
468             | ft.dwLowDateTime);
469   cnsecs -= 116444736000000000ULL; /* The filetime epoch is 1601-01-01.  */
470   return (time_t)(cnsecs / 10000000ULL);
471 }
472 #endif
473
474
475 /* Parse the string TIMESTAMP into a time_t.  The string may either be
476    seconds since Epoch or in the ISO 8601 format like
477    "20390815T143012".  Returns 0 for an empty string or seconds since
478    Epoch. Leading spaces are skipped. If ENDP is not NULL, it will
479    point to the next non-parsed character in TIMESTRING. */
480 time_t
481 _gpgme_parse_timestamp (const char *timestamp, char **endp)
482 {
483   /* Need to skip leading spaces, because that is what strtoul does
484      but not our ISO 8601 checking code. */
485   while (*timestamp && *timestamp== ' ')
486     timestamp++;
487   if (!*timestamp)
488     return 0;
489
490   if (strlen (timestamp) >= 15 && timestamp[8] == 'T')
491     {
492       struct tm buf;
493       int year;
494
495       year = atoi_4 (timestamp);
496       if (year < 1900)
497         return (time_t)(-1);
498
499       if (endp)
500         *endp = (char*)(timestamp + 15);
501
502       /* Fixme: We would better use a configure test to see whether
503          mktime can handle dates beyond 2038. */
504       if (sizeof (time_t) <= 4 && year >= 2038)
505         return (time_t)2145914603; /* 2037-12-31 23:23:23 */
506
507       memset (&buf, 0, sizeof buf);
508       buf.tm_year = year - 1900;
509       buf.tm_mon = atoi_2 (timestamp+4) - 1;
510       buf.tm_mday = atoi_2 (timestamp+6);
511       buf.tm_hour = atoi_2 (timestamp+9);
512       buf.tm_min = atoi_2 (timestamp+11);
513       buf.tm_sec = atoi_2 (timestamp+13);
514
515 #ifdef HAVE_W32_SYSTEM
516       return _gpgme_timegm (&buf);
517 #else
518 #ifdef HAVE_TIMEGM
519       return timegm (&buf);
520 #else
521       {
522         time_t tim;
523
524         putenv ("TZ=UTC");
525         tim = mktime (&buf);
526 #ifdef __GNUC__
527 #warning fixme: we must somehow reset TZ here.  It is not threadsafe anyway.
528 #endif
529         return tim;
530       }
531 #endif /* !HAVE_TIMEGM */
532 #endif /* !HAVE_W32_SYSTEM */
533     }
534   else
535     return (time_t)strtoul (timestamp, endp, 10);
536 }
537
538
539 /* This function is similar to _gpgme_parse_timestamp but returns an
540  * unsigned long and 0 on error.  */
541 unsigned long
542 _gpgme_parse_timestamp_ul (const char *timestamp)
543 {
544   time_t tim;
545   char *tail;
546
547   if (!*timestamp)
548     return 0; /* Shortcut empty strings.  */
549
550   tim = _gpgme_parse_timestamp (timestamp, &tail);
551   if (tim == -1 || timestamp == tail || (*tail && *tail != ' '))
552     tim = 0; /* No time given or invalid engine.  */
553
554   return (unsigned long)tim;
555 }
556
557
558 /* The GPG backend uses OpenPGP algorithm numbers which we need to map
559    to our algorithm numbers.  This function MUST not change ERRNO. */
560 int
561 _gpgme_map_pk_algo (int algo, gpgme_protocol_t protocol)
562 {
563   if (protocol == GPGME_PROTOCOL_OPENPGP)
564     {
565       switch (algo)
566         {
567         case 1: case 2: case 3: case 16: case 17: break;
568         case 18: algo = GPGME_PK_ECDH; break;
569         case 19: algo = GPGME_PK_ECDSA; break;
570         case 20: break;
571         case 22: algo = GPGME_PK_EDDSA; break;
572         default: algo = 0; break; /* Unknown.  */
573         }
574     }
575
576   return algo;
577 }
578
579
580 /* Return a string with a cipher algorithm.  */
581 const char *
582 _gpgme_cipher_algo_name (int algo, gpgme_protocol_t protocol)
583 {
584   if (protocol == GPGME_PROTOCOL_OPENPGP)
585     {
586       /* The algo is given according to OpenPGP specs.  */
587       switch (algo)
588         {
589         case 1:  return "IDEA";
590         case 2:  return "3DES";
591         case 3:  return "CAST5";
592         case 4:  return "BLOWFISH";
593         case 7:  return "AES";
594         case 8:  return "AES192";
595         case 9:  return "AES256";
596         case 10: return "TWOFISH";
597         case 11: return "CAMELLIA128";
598         case 12: return "CAMELLIA192";
599         case 13: return "CAMELLIA256";
600         }
601     }
602
603   return "Unknown";
604 }
605
606
607 /* Return a string with the cipher mode.  */
608 const char *
609 _gpgme_cipher_mode_name (int algo, gpgme_protocol_t protocol)
610 {
611   if (protocol == GPGME_PROTOCOL_OPENPGP)
612     {
613       /* The algo is given according to OpenPGP specs.  */
614       switch (algo)
615         {
616         case 0:  return "CFB";
617         case 1:  return "EAX";
618         case 2:  return "OCB";
619         }
620     }
621
622   return "Unknown";
623 }