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