* gpg-agent.c (handle_signal): Reload the trustlist on SIGHUP.
[gnupg.git] / sm / base64.c
1 /* base64.c 
2  *      Copyright (C) 2001, 2003 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 2 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, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <unistd.h> 
27 #include <time.h>
28 #include <assert.h>
29
30 #include "gpgsm.h"
31
32 #include <ksba.h>
33
34 #include "i18n.h"
35
36 #ifdef HAVE_DOSISH_SYSTEM
37   #define LF "\r\n"
38 #else
39   #define LF "\n"
40 #endif
41
42 /* data used by the reader callbacks */
43 struct reader_cb_parm_s {
44   FILE *fp;
45   unsigned char line[1024];
46   int linelen;
47   int readpos;
48   int have_lf;
49   unsigned long line_counter;
50
51   int allow_multi_pem;  /* Allow processing of multiple PEM objects. */
52   int autodetect;       /* Try to detect the input encoding. */
53   int assume_pem;       /* Assume input encoding is PEM. */
54   int assume_base64;    /* Assume input is base64 encoded. */
55
56   int identified;
57   int is_pem;
58   int is_base64;
59   int stop_seen;
60   int might_be_smime;
61
62   int eof_seen;         
63
64   struct {
65     int idx;
66     unsigned char val;
67     int stop_seen;
68   } base64;
69 };
70
71 /* data used by the writer callbacks */
72 struct writer_cb_parm_s {
73   FILE *fp;
74   const char *pem_name;
75   
76   int wrote_begin;
77   int did_finish;
78
79   struct {
80     int idx;
81     int quad_count;
82     unsigned char radbuf[4];
83   } base64;
84
85 };
86
87
88 /* context for this module's functions */
89 struct base64_context_s {
90   union {
91     struct reader_cb_parm_s rparm;
92     struct writer_cb_parm_s wparm;
93   } u;
94 };
95
96
97 /* The base-64 character list */
98 static unsigned char bintoasc[64] = 
99        "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
100        "abcdefghijklmnopqrstuvwxyz" 
101        "0123456789+/"; 
102 /* The reverse base-64 list */
103 static unsigned char asctobin[256] = {
104   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
105   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
106   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
107   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, 
108   0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, 
109   0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 
110   0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 
111   0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, 
112   0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 
113   0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 
114   0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
115   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
116   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
117   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
118   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
119   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
120   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
121   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
122   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
123   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
124   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
125   0xff, 0xff, 0xff, 0xff
126 };
127
128
129 static int
130 has_only_base64 (const unsigned char *line, int linelen)
131 {
132   if (linelen < 20)
133     return 0;
134   for (; linelen; line++, linelen--)
135     {
136       if (*line == '\n' || (linelen > 1 && *line == '\r' && line[1] == '\n'))
137           break;
138       if ( !strchr (bintoasc, *line) )
139         return 0;
140     }
141   return 1;  /* yes */
142 }
143
144 static int
145 is_empty_line (const unsigned char *line, int linelen)
146 {
147   if (linelen >= 2 && *line == '\r' && line[1] == '\n')
148     return 1;
149   if (linelen >= 1 && *line == '\n')
150     return 1;
151   return 0;
152 }
153
154
155 static int
156 base64_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
157 {
158   struct reader_cb_parm_s *parm = cb_value;
159   size_t n;
160   int c, c2;
161
162   *nread = 0;
163   if (!buffer)
164     return -1; /* not supported */
165
166  next:
167   if (!parm->linelen)
168     {
169       /* read an entire line or up to the size of the buffer */
170       parm->line_counter++;
171       parm->have_lf = 0;
172       for (n=0; n < DIM(parm->line);)
173         {
174           c = getc (parm->fp);
175           if (c == EOF)
176             {
177               parm->eof_seen = 1;
178               if (ferror (parm->fp))
179                 return -1;
180               break; 
181             }
182           parm->line[n++] = c;
183           if (c == '\n')
184             {
185               parm->have_lf = 1;
186               /* Fixme: we need to skip overlong lines while detecting
187                  the dashed lines */
188               break;
189             }
190         }
191       parm->linelen = n;
192       if (!n)
193         return -1; /* eof */
194       parm->readpos = 0;
195     }
196
197   if (!parm->identified)
198     {
199       if (!parm->autodetect)
200         {
201           if (parm->assume_pem)
202             {
203               /* wait for the header line */
204               parm->linelen = parm->readpos = 0;
205               if (!parm->have_lf || strncmp (parm->line, "-----BEGIN ", 11)
206                   || !strncmp (parm->line+11, "PGP ", 4))
207                 goto next;
208               parm->is_pem = 1;
209             }
210           else if (parm->assume_base64)
211             parm->is_base64 = 1;
212         }
213       else if (parm->line_counter == 1 && !parm->have_lf)
214         {
215           /* first line too long - assume DER encoding */
216           parm->is_pem = 0;
217         }
218       else if (parm->line_counter == 1 && parm->linelen && *parm->line == 0x30)
219         {
220           /* the very first byte does pretty much look like a SEQUENCE tag*/
221           parm->is_pem = 0;
222         }
223       else if ( parm->have_lf && !strncmp (parm->line, "-----BEGIN ", 11)
224                 && strncmp (parm->line+11, "PGP ", 4) )
225         {
226           /* Fixme: we must only compare if the line really starts at
227              the beginning */
228           parm->is_pem = 1;
229           parm->linelen = parm->readpos = 0;
230         }
231       else if ( parm->have_lf && parm->line_counter == 1
232                 && parm->linelen >= 13
233                 && !ascii_memcasecmp (parm->line, "Content-Type:", 13))
234         { /* might be a S/MIME body */
235           parm->might_be_smime = 1;
236           parm->linelen = parm->readpos = 0;
237           goto next;
238         }
239       else if (parm->might_be_smime == 1
240                && is_empty_line (parm->line, parm->linelen))
241         {
242           parm->might_be_smime = 2;
243           parm->linelen = parm->readpos = 0;
244           goto next;
245         }
246       else if (parm->might_be_smime == 2)
247         {
248           parm->might_be_smime = 0;
249           if ( !has_only_base64 (parm->line, parm->linelen))
250             {
251               parm->linelen = parm->readpos = 0;
252               goto next;
253             }
254           parm->is_pem = 1;
255         }
256       else
257         {
258           parm->linelen = parm->readpos = 0;
259           goto next;
260         }
261       parm->identified = 1;
262       parm->base64.stop_seen = 0;
263       parm->base64.idx = 0;
264     }
265   
266
267   n = 0;
268   if (parm->is_pem || parm->is_base64)
269     {  
270       if (parm->is_pem && parm->have_lf
271           && !strncmp (parm->line, "-----END ", 9))
272         { 
273           parm->identified = 0;
274           parm->linelen = parm->readpos = 0;
275
276           /* If the caller want to read multiple PEM objects from one
277              file, we have to reset our internal state and return a
278              EOF immediately. The caller is the expected to use
279              ksba_reader_clear to clear the EOF condition and continue
280              to read.  If we don't want to do that we just return 0
281              bytes which will force the ksba_reader to skip until
282              EOF. */
283           if (parm->allow_multi_pem)
284             {
285               parm->identified = 0;
286               parm->autodetect = 0;
287               parm->assume_pem = 1;
288               parm->stop_seen = 0;
289               return -1; /* Send EOF now. */
290             }
291         }
292       else if (parm->stop_seen)
293         { /* skip the rest of the line */
294           parm->linelen = parm->readpos = 0;
295         }
296       else
297         {
298           int idx = parm->base64.idx;
299           unsigned char val = parm->base64.val;
300
301           while (n < count && parm->readpos < parm->linelen )
302             {
303               c = parm->line[parm->readpos++];
304               if (c == '\n' || c == ' ' || c == '\r' || c == '\t')
305                 continue;
306               if (c == '=')
307                 { /* pad character: stop */
308                   if (idx == 1)
309                     buffer[n++] = val; 
310                   parm->stop_seen = 1;
311                   break;
312                 }
313               if( (c = asctobin[(c2=c)]) == 255 ) 
314                 {
315                   log_error (_("invalid radix64 character %02x skipped\n"),
316                              c2);
317                   continue;
318                 }
319               switch (idx) 
320                 {
321                 case 0: 
322                   val = c << 2;
323                   break;
324                 case 1: 
325                   val |= (c>>4)&3;
326                   buffer[n++] = val;
327                   val = (c<<4)&0xf0;
328                   break;
329                 case 2: 
330                   val |= (c>>2)&15;
331                   buffer[n++] = val;
332                   val = (c<<6)&0xc0;
333                   break;
334                 case 3: 
335                   val |= c&0x3f;
336                   buffer[n++] = val;
337                   break;
338                 }
339               idx = (idx+1) % 4;
340             }
341           if (parm->readpos == parm->linelen)
342             parm->linelen = parm->readpos = 0;
343
344           parm->base64.idx = idx;
345           parm->base64.val = val;
346         }
347     }
348   else
349     { /* DER encoded */
350       while (n < count && parm->readpos < parm->linelen)
351           buffer[n++] = parm->line[parm->readpos++];
352       if (parm->readpos == parm->linelen)
353         parm->linelen = parm->readpos = 0;
354     }
355
356   *nread = n;
357   return 0;
358 }
359
360
361
362 static int
363 simple_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
364 {
365   struct reader_cb_parm_s *parm = cb_value;
366   size_t n;
367   int c = 0;
368
369   *nread = 0;
370   if (!buffer)
371     return -1; /* not supported */
372
373   for (n=0; n < count; n++)
374     {
375       c = getc (parm->fp);
376       if (c == EOF)
377         {
378           parm->eof_seen = 1;
379           if ( ferror (parm->fp) )
380             return -1;
381           if (n)
382             break; /* return what we have before an EOF */
383           return -1;
384         }
385       *(byte *)buffer++ = c;
386     }
387
388   *nread = n;
389   return 0;
390 }
391
392
393
394 \f
395 static int
396 base64_writer_cb (void *cb_value, const void *buffer, size_t count)
397 {
398   struct writer_cb_parm_s *parm = cb_value;
399   unsigned char radbuf[4];
400   int i, c, idx, quad_count;
401   const unsigned char *p;
402   FILE *fp = parm->fp;
403
404   if (!count)
405     return 0;
406
407   if (!parm->wrote_begin)
408     {
409       if (parm->pem_name)
410         {
411           fputs ("-----BEGIN ", fp);
412           fputs (parm->pem_name, fp);
413           fputs ("-----\n", fp);
414         }
415       parm->wrote_begin = 1;
416       parm->base64.idx = 0;
417       parm->base64.quad_count = 0;
418     }
419
420   idx = parm->base64.idx;
421   quad_count = parm->base64.quad_count;
422   for (i=0; i < idx; i++)
423     radbuf[i] = parm->base64.radbuf[i];
424
425   for (p=buffer; count; p++, count--)
426     {
427       radbuf[idx++] = *p;
428       if (idx > 2)
429         {
430           idx = 0;
431           c = bintoasc[(*radbuf >> 2) & 077];
432           putc (c, fp);
433           c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
434           putc (c, fp);
435           c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
436           putc (c, fp);
437           c = bintoasc[radbuf[2]&077];
438           putc (c, fp);
439           if (++quad_count >= (64/4)) 
440             {
441               fputs (LF, fp);
442               quad_count = 0;
443             }
444         }
445     }
446   for (i=0; i < idx; i++)
447     parm->base64.radbuf[i] = radbuf[i];
448   parm->base64.idx = idx;
449   parm->base64.quad_count = quad_count;
450
451   return ferror (fp) ? gpg_error_from_errno (errno) : 0;
452 }
453
454 static int
455 base64_finish_write (struct writer_cb_parm_s *parm)
456 {
457   unsigned char radbuf[4];
458   int i, c, idx, quad_count;
459   FILE *fp = parm->fp;
460
461   if (!parm->wrote_begin)
462     return 0; /* nothing written */
463
464   /* flush the base64 encoding */
465   idx = parm->base64.idx;
466   quad_count = parm->base64.quad_count;
467   for (i=0; i < idx; i++)
468     radbuf[i] = parm->base64.radbuf[i];
469
470   if (idx)
471     {
472       c = bintoasc[(*radbuf>>2)&077];
473       putc (c, fp);
474       if (idx == 1)
475         {
476           c = bintoasc[((*radbuf << 4) & 060) & 077];
477           putc (c, fp);
478           putc ('=', fp);
479           putc ('=', fp);
480         }
481       else 
482         { 
483           c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077];
484           putc (c, fp);
485           c = bintoasc[((radbuf[1] << 2) & 074) & 077];
486           putc (c, fp);
487           putc ('=', fp);
488
489         }
490       if (++quad_count >= (64/4)) 
491         {
492           fputs (LF, fp);
493           quad_count = 0;
494         }
495     }
496
497   if (quad_count)
498     fputs (LF, fp);
499
500   if (parm->pem_name)
501     {
502       fputs ("-----END ", fp);
503       fputs (parm->pem_name, fp);
504       fputs ("-----\n", fp);
505     }
506   return ferror (fp)? gpg_error (gpg_err_code_from_errno (errno)) : 0;
507 }
508
509
510
511 \f
512 /* Create a reader for the given file descriptor.  Depending on the
513    control information an input decoding is automagically choosen.
514    The function returns a Base64Context object which must be passed to
515    the gpgme_destroy_reader function.  The created KsbaReader object
516    is also returned, but the caller must not call the
517    ksba_reader_release function on.  If ALLOW_MULTI_PEM is true, the
518    reader expects that the caller uses ksba_reader_clear after EOF
519    until no more objects were found. */
520 int
521 gpgsm_create_reader (Base64Context *ctx,
522                      CTRL ctrl, FILE *fp, int allow_multi_pem,
523                      ksba_reader_t *r_reader)
524 {
525   int rc;
526   ksba_reader_t r;
527
528   *r_reader = NULL;
529   *ctx = xtrycalloc (1, sizeof **ctx);
530   if (!*ctx)
531     return OUT_OF_CORE (errno);
532   (*ctx)->u.rparm.allow_multi_pem = allow_multi_pem;
533
534   rc = ksba_reader_new (&r);
535   if (rc)
536     {
537       xfree (*ctx); *ctx = NULL;
538       return rc;
539     }
540
541   (*ctx)->u.rparm.fp = fp;
542   if (ctrl->is_pem)
543     {
544       (*ctx)->u.rparm.assume_pem = 1;
545       (*ctx)->u.rparm.assume_base64 = 1;
546       rc = ksba_reader_set_cb (r, base64_reader_cb, &(*ctx)->u.rparm);
547     }
548   else if (ctrl->is_base64)
549     {
550       (*ctx)->u.rparm.assume_base64 = 1;
551       rc = ksba_reader_set_cb (r, base64_reader_cb, &(*ctx)->u.rparm);
552     }
553   else if (ctrl->autodetect_encoding)
554     {
555       (*ctx)->u.rparm.autodetect = 1;
556       rc = ksba_reader_set_cb (r, base64_reader_cb, &(*ctx)->u.rparm);
557     }
558   else
559       rc = ksba_reader_set_cb (r, simple_reader_cb, &(*ctx)->u.rparm);
560
561   if (rc)
562     {
563       ksba_reader_release (r);
564       xfree (*ctx); *ctx = NULL;
565       return rc;
566     }
567
568   *r_reader = r;
569   return 0;
570 }
571
572
573 int
574 gpgsm_reader_eof_seen (Base64Context ctx)
575 {
576   return ctx && ctx->u.rparm.eof_seen;
577 }
578
579 void
580 gpgsm_destroy_reader (Base64Context ctx)
581 {
582   xfree (ctx);
583 }
584
585
586 \f
587 /* Create a writer for the given stream.  Depending on the control
588    information an output encoding is automagically choosen.  The
589    function returns a Base64Context object which must be passed to the
590    gpgme_destroy_writer function.  The created KsbaWriter object is
591    also returned, but the caller must not call the ksba_reader_release
592    function on. */
593 int
594 gpgsm_create_writer (Base64Context *ctx,
595                      CTRL ctrl, FILE *fp, ksba_writer_t *r_writer)
596 {
597   int rc;
598   ksba_writer_t w;
599
600   *r_writer = NULL;
601   *ctx = xtrycalloc (1, sizeof **ctx);
602   if (!*ctx)
603     return OUT_OF_CORE (errno);
604
605   rc = ksba_writer_new (&w);
606   if (rc)
607     {
608       xfree (*ctx); *ctx = NULL;
609       return rc;
610     }
611
612   if (ctrl->create_pem || ctrl->create_base64)
613     {
614       (*ctx)->u.wparm.fp = fp;
615       if (ctrl->create_pem)
616         (*ctx)->u.wparm.pem_name = ctrl->pem_name? ctrl->pem_name
617                                                  : "CMS OBJECT";
618       rc = ksba_writer_set_cb (w, base64_writer_cb, &(*ctx)->u.wparm);
619     }
620   else
621     rc = ksba_writer_set_file (w, fp);
622
623   if (rc)
624     {
625       ksba_writer_release (w);
626       xfree (*ctx); *ctx = NULL;
627       return rc;
628     }
629
630   *r_writer = w;
631   return 0;
632 }
633
634
635 int
636 gpgsm_finish_writer (Base64Context ctx)
637 {
638   struct writer_cb_parm_s *parm;
639   
640   if (!ctx)
641     return gpg_error (GPG_ERR_INV_VALUE);
642   parm = &ctx->u.wparm;
643   if (parm->did_finish)
644     return 0; /* already done */
645   parm->did_finish = 1;
646   if (!parm->fp)
647     return 0; /* callback was not used */
648   return base64_finish_write (parm);
649 }
650
651 void
652 gpgsm_destroy_writer (Base64Context ctx)
653 {
654   xfree (ctx);
655 }