Fixed importing certs created by newer versions of Mozilla.
[gnupg.git] / agent / minip12.c
1 /* minip12.c - A minimal pkcs-12 implementation.
2  *      Copyright (C) 2002, 2003, 2004 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 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <assert.h>
28 #include <gcrypt.h>
29
30 #ifdef TEST
31 #include <sys/stat.h>
32 #include <unistd.h>
33 #include <errno.h>
34 #endif
35
36 #include "../jnlib/logging.h"
37 #include "minip12.h"
38
39 #ifndef DIM
40 #define DIM(v)               (sizeof(v)/sizeof((v)[0]))
41 #endif
42
43 enum
44 {
45   UNIVERSAL = 0,
46   APPLICATION = 1,
47   CONTEXT = 2,
48   PRIVATE = 3
49 };
50
51
52 enum
53 {
54   TAG_NONE = 0,
55   TAG_BOOLEAN = 1,
56   TAG_INTEGER = 2,
57   TAG_BIT_STRING = 3,
58   TAG_OCTET_STRING = 4,
59   TAG_NULL = 5,
60   TAG_OBJECT_ID = 6,
61   TAG_OBJECT_DESCRIPTOR = 7,
62   TAG_EXTERNAL = 8,
63   TAG_REAL = 9,
64   TAG_ENUMERATED = 10,
65   TAG_EMBEDDED_PDV = 11,
66   TAG_UTF8_STRING = 12,
67   TAG_REALTIVE_OID = 13,
68   TAG_SEQUENCE = 16,
69   TAG_SET = 17,
70   TAG_NUMERIC_STRING = 18,
71   TAG_PRINTABLE_STRING = 19,
72   TAG_TELETEX_STRING = 20,
73   TAG_VIDEOTEX_STRING = 21,
74   TAG_IA5_STRING = 22,
75   TAG_UTC_TIME = 23,
76   TAG_GENERALIZED_TIME = 24,
77   TAG_GRAPHIC_STRING = 25,
78   TAG_VISIBLE_STRING = 26,
79   TAG_GENERAL_STRING = 27,
80   TAG_UNIVERSAL_STRING = 28,
81   TAG_CHARACTER_STRING = 29,
82   TAG_BMP_STRING = 30
83 };
84
85
86 static unsigned char const oid_data[9] = {
87   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01 };
88 static unsigned char const oid_encryptedData[9] = {
89   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06 };
90 static unsigned char const oid_pkcs_12_pkcs_8ShroudedKeyBag[11] = {
91   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x02 };
92 static unsigned char const oid_pkcs_12_CertBag[11] = {
93   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x03 };
94 static unsigned char const oid_pkcs_12_CrlBag[11] = {
95   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x04 };
96
97 static unsigned char const oid_pbeWithSHAAnd3_KeyTripleDES_CBC[10] = {
98   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03 };
99 static unsigned char const oid_pbeWithSHAAnd40BitRC2_CBC[10] = {
100   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x06 };
101 static unsigned char const oid_x509Certificate_for_pkcs_12[10] = {
102   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x16, 0x01 };
103
104
105 static unsigned char const oid_rsaEncryption[9] = {
106   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 };
107
108
109 static unsigned char const data_3desiter2048[30] = {
110   0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86,
111   0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30, 0x0E, 
112   0x04, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
113   0xFF, 0xFF, 0x02, 0x02, 0x08, 0x00 };
114 #define DATA_3DESITER2048_SALT_OFF  18
115
116 static unsigned char const data_rc2iter2048[30] = {
117   0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86,
118   0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x06, 0x30, 0x0E, 
119   0x04, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
120   0xFF, 0xFF, 0x02, 0x02, 0x08, 0x00 };
121 #define DATA_RC2ITER2048_SALT_OFF  18
122
123
124 struct buffer_s 
125 {
126   unsigned char *buffer;
127   size_t length;
128 };  
129
130
131 struct tag_info 
132 {
133   int class;
134   int is_constructed;
135   unsigned long tag;
136   unsigned long length;  /* length part of the TLV */
137   int nhdr;
138   int ndef;              /* It is an indefinite length */
139 };
140
141
142 /* Parse the buffer at the address BUFFER which is of SIZE and return
143    the tag and the length part from the TLV triplet.  Update BUFFER
144    and SIZE on success.  Checks that the encoded length does not
145    exhaust the length of the provided buffer. */
146 static int 
147 parse_tag (unsigned char const **buffer, size_t *size, struct tag_info *ti)
148 {
149   int c;
150   unsigned long tag;
151   const unsigned char *buf = *buffer;
152   size_t length = *size;
153
154   ti->length = 0;
155   ti->ndef = 0;
156   ti->nhdr = 0;
157
158   /* Get the tag */
159   if (!length)
160     return -1; /* premature eof */
161   c = *buf++; length--;
162   ti->nhdr++;
163
164   ti->class = (c & 0xc0) >> 6;
165   ti->is_constructed = !!(c & 0x20);
166   tag = c & 0x1f;
167
168   if (tag == 0x1f)
169     {
170       tag = 0;
171       do
172         {
173           tag <<= 7;
174           if (!length)
175             return -1; /* premature eof */
176           c = *buf++; length--;
177           ti->nhdr++;
178           tag |= c & 0x7f;
179         }
180       while (c & 0x80);
181     }
182   ti->tag = tag;
183
184   /* Get the length */
185   if (!length)
186     return -1; /* prematureeof */
187   c = *buf++; length--;
188   ti->nhdr++;
189
190   if ( !(c & 0x80) )
191     ti->length = c;
192   else if (c == 0x80)
193     ti->ndef = 1;
194   else if (c == 0xff)
195     return -1; /* forbidden length value */
196   else
197     {
198       unsigned long len = 0;
199       int count = c & 0x7f;
200
201       for (; count; count--)
202         {
203           len <<= 8;
204           if (!length)
205             return -1; /* premature_eof */
206           c = *buf++; length--;
207           ti->nhdr++;
208           len |= c & 0xff;
209         }
210       ti->length = len;
211     }
212   
213   if (ti->class == UNIVERSAL && !ti->tag)
214     ti->length = 0;
215
216   if (ti->length > length)
217     return -1; /* data larger than buffer. */
218   
219   *buffer = buf;
220   *size = length;
221   return 0;
222 }
223
224
225 /* Given an ASN.1 chunk of a structure like:
226
227      24 NDEF:       OCTET STRING  -- This is not passed to us
228      04    1:         OCTET STRING  -- INPUT point s to here
229             :           30
230      04    1:         OCTET STRING
231             :           80
232           [...]
233      04    2:         OCTET STRING
234             :           00 00
235             :         } -- This denotes a Null tag and are the last 
236                         -- two bytes in INPUT.
237    
238    Create a new buffer with the content of that octet string.  INPUT
239    is the orginal buffer with a length as stored at LENGTH.  Returns
240    NULL on error or a new malloced buffer with the length of this new
241    buffer stored at LENGTH and the number of bytes parsed from input
242    are added to the value stored at INPUT_CONSUMED.  INPUT_CONSUMED is
243    allowed to be passed as NULL if the caller is not interested in
244    this value. */
245 static unsigned char *
246 cram_octet_string (const unsigned char *input, size_t *length,
247                    size_t *input_consumed)
248 {
249   const unsigned char *s = input;
250   size_t n = *length;
251   unsigned char *output, *d;
252   struct tag_info ti;
253
254   /* Allocate output buf.  We know that it won't be longer than the
255      input buffer. */
256   d = output = gcry_malloc (n);
257   if (!output)
258     goto bailout;
259
260   for (;;)
261     {
262       if (parse_tag (&s, &n, &ti))
263         goto bailout;
264       if (ti.class == UNIVERSAL && ti.tag == TAG_OCTET_STRING 
265           && !ti.ndef && !ti.is_constructed)
266         {
267           memcpy (d, s, ti.length);
268           s += ti.length;
269           d += ti.length;
270           n -= ti.length;
271         }
272       else if (ti.class == UNIVERSAL && !ti.tag && !ti.is_constructed)
273         break; /* Ready */ 
274       else
275         goto bailout;
276     }
277
278
279   *length = d - output;
280   if (input_consumed)
281     *input_consumed += s - input;
282   return output;
283
284  bailout:
285   if (input_consumed)
286     *input_consumed += s - input;
287   gcry_free (output);
288   return NULL;
289 }
290
291
292
293 static int 
294 string_to_key (int id, char *salt, size_t saltlen, int iter, const char *pw,
295                int req_keylen, unsigned char *keybuf)
296 {
297   int rc, i, j;
298   gcry_md_hd_t md;
299   gcry_mpi_t num_b1 = NULL;
300   int pwlen;
301   unsigned char hash[20], buf_b[64], buf_i[128], *p;
302   size_t cur_keylen;
303   size_t n;
304
305   cur_keylen = 0;
306   pwlen = strlen (pw);
307   if (pwlen > 63/2)
308     {
309       log_error ("password too long\n");
310       return -1;
311     }
312
313   if (saltlen < 8)
314     {
315       log_error ("salt too short\n");
316       return -1;
317     }
318   
319   /* Store salt and password in BUF_I */
320   p = buf_i;
321   for(i=0; i < 64; i++)
322     *p++ = salt [i%saltlen];
323   for(i=j=0; i < 64; i += 2)
324     {
325       *p++ = 0;
326       *p++ = pw[j];
327       if (++j > pwlen) /* Note, that we include the trailing zero */
328         j = 0;
329     }
330
331   for (;;)
332     {
333       rc = gcry_md_open (&md, GCRY_MD_SHA1, 0);
334       if (rc)
335         {
336           log_error ( "gcry_md_open failed: %s\n", gpg_strerror (rc));
337           return rc;
338         }
339       for(i=0; i < 64; i++)
340         gcry_md_putc (md, id);
341       gcry_md_write (md, buf_i, 128);
342       memcpy (hash, gcry_md_read (md, 0), 20);
343       gcry_md_close (md);
344       for (i=1; i < iter; i++)
345         gcry_md_hash_buffer (GCRY_MD_SHA1, hash, hash, 20);
346
347       for (i=0; i < 20 && cur_keylen < req_keylen; i++)
348         keybuf[cur_keylen++] = hash[i];
349       if (cur_keylen == req_keylen)
350         {
351           gcry_mpi_release (num_b1);
352           return 0; /* ready */
353         }
354       
355       /* need more bytes. */
356       for(i=0; i < 64; i++)
357         buf_b[i] = hash[i % 20];
358       rc = gcry_mpi_scan (&num_b1, GCRYMPI_FMT_USG, buf_b, 64, &n);
359       if (rc)
360         {
361           log_error ( "gcry_mpi_scan failed: %s\n", gpg_strerror (rc));
362           return -1;
363         }
364       gcry_mpi_add_ui (num_b1, num_b1, 1);
365       for (i=0; i < 128; i += 64)
366         {
367           gcry_mpi_t num_ij;
368
369           rc = gcry_mpi_scan (&num_ij, GCRYMPI_FMT_USG, buf_i + i, 64, &n);
370           if (rc)
371             {
372               log_error ( "gcry_mpi_scan failed: %s\n",
373                        gpg_strerror (rc));
374               return -1;
375             }
376           gcry_mpi_add (num_ij, num_ij, num_b1);
377           gcry_mpi_clear_highbit (num_ij, 64*8);
378           rc = gcry_mpi_print (GCRYMPI_FMT_USG, buf_i + i, 64, &n, num_ij);
379           if (rc)
380             {
381               log_error ( "gcry_mpi_print failed: %s\n",
382                           gpg_strerror (rc));
383               return -1;
384             }
385           gcry_mpi_release (num_ij);
386         }
387     }
388 }
389
390
391 static int 
392 set_key_iv (gcry_cipher_hd_t chd, char *salt, size_t saltlen, int iter,
393             const char *pw, int keybytes)
394 {
395   unsigned char keybuf[24];
396   int rc;
397
398   assert (keybytes == 5 || keybytes == 24);
399   if (string_to_key (1, salt, saltlen, iter, pw, keybytes, keybuf))
400     return -1;
401   rc = gcry_cipher_setkey (chd, keybuf, keybytes);
402   if (rc)
403     {
404       log_error ( "gcry_cipher_setkey failed: %s\n", gpg_strerror (rc));
405       return -1;
406     }
407
408   if (string_to_key (2, salt, saltlen, iter, pw, 8, keybuf))
409     return -1;
410   rc = gcry_cipher_setiv (chd, keybuf, 8);
411   if (rc)
412     {
413       log_error ("gcry_cipher_setiv failed: %s\n", gpg_strerror (rc));
414       return -1;
415     }
416   return 0;
417 }
418
419
420 static void
421 crypt_block (unsigned char *buffer, size_t length, char *salt, size_t saltlen,
422              int iter, const char *pw, int cipher_algo, int encrypt)
423 {
424   gcry_cipher_hd_t chd;
425   int rc;
426
427   rc = gcry_cipher_open (&chd, cipher_algo, GCRY_CIPHER_MODE_CBC, 0); 
428   if (rc)
429     {
430       log_error ( "gcry_cipher_open failed: %s\n", gpg_strerror(rc));
431       wipememory (buffer, length);
432       return;
433     }
434   if (set_key_iv (chd, salt, saltlen, iter, pw,
435                   cipher_algo == GCRY_CIPHER_RFC2268_40? 5:24))
436     {
437       wipememory (buffer, length);
438       goto leave;
439     }
440
441   rc = encrypt? gcry_cipher_encrypt (chd, buffer, length, NULL, 0)
442               : gcry_cipher_decrypt (chd, buffer, length, NULL, 0);
443
444   if (rc)
445     {
446       wipememory (buffer, length);
447       log_error ( "en/de-crytion failed: %s\n", gpg_strerror (rc));
448       goto leave;
449     }
450
451  leave:
452   gcry_cipher_close (chd);
453 }
454   
455
456
457 static int
458 parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
459                           int startoffset, size_t *r_consumed, const char *pw,
460                           void (*certcb)(void*, const unsigned char*, size_t),
461                           void *certcbarg)
462 {
463   struct tag_info ti;
464   const unsigned char *p = buffer;
465   const unsigned char *p_start = buffer;
466   size_t n = length;
467   const char *where;
468   char salt[16];
469   size_t saltlen;
470   unsigned int iter;
471   unsigned char *plain = NULL;
472   int bad_pass = 0;
473   unsigned char *cram_buffer = NULL;
474   size_t consumed = 0; /* Number of bytes consumed from the orginal buffer. */
475   
476   where = "start";
477   if (parse_tag (&p, &n, &ti))
478     goto bailout;
479   if (ti.class != CONTEXT || ti.tag)
480     goto bailout;
481   if (parse_tag (&p, &n, &ti))
482     goto bailout;
483   if (ti.tag != TAG_SEQUENCE)
484     goto bailout;
485
486   where = "bag.encryptedData.version";
487   if (parse_tag (&p, &n, &ti))
488     goto bailout;
489   if (ti.tag != TAG_INTEGER || ti.length != 1 || *p != 0)
490     goto bailout;
491   p++; n--;
492   if (parse_tag (&p, &n, &ti))
493     goto bailout;
494   if (ti.tag != TAG_SEQUENCE)
495     goto bailout;
496
497   where = "bag.encryptedData.data";
498   if (parse_tag (&p, &n, &ti))
499     goto bailout;
500   if (ti.tag != TAG_OBJECT_ID || ti.length != DIM(oid_data)
501       || memcmp (p, oid_data, DIM(oid_data)))
502     goto bailout;
503   p += DIM(oid_data);
504   n -= DIM(oid_data);
505
506   where = "bag.encryptedData.keyinfo";
507   if (parse_tag (&p, &n, &ti))
508     goto bailout;
509   if (ti.class || ti.tag != TAG_SEQUENCE)
510     goto bailout;
511   if (parse_tag (&p, &n, &ti))
512     goto bailout;
513   if (!ti.class && ti.tag == TAG_OBJECT_ID 
514       && ti.length == DIM(oid_pbeWithSHAAnd40BitRC2_CBC)
515       && !memcmp (p, oid_pbeWithSHAAnd40BitRC2_CBC,
516                   DIM(oid_pbeWithSHAAnd40BitRC2_CBC)))
517     {
518       p += DIM(oid_pbeWithSHAAnd40BitRC2_CBC);
519       n -= DIM(oid_pbeWithSHAAnd40BitRC2_CBC);
520     }
521   else
522     goto bailout;
523
524   where = "rc2-params";
525   if (parse_tag (&p, &n, &ti))
526     goto bailout;
527   if (ti.class || ti.tag != TAG_SEQUENCE)
528     goto bailout;
529   if (parse_tag (&p, &n, &ti))
530     goto bailout;
531   if (ti.class || ti.tag != TAG_OCTET_STRING
532       || ti.length < 8 || ti.length > 16 )
533     goto bailout;
534   saltlen = ti.length;
535   memcpy (salt, p, saltlen);
536   p += saltlen;
537   n -= saltlen;
538   if (parse_tag (&p, &n, &ti))
539     goto bailout;
540   if (ti.class || ti.tag != TAG_INTEGER || !ti.length )
541     goto bailout;
542   for (iter=0; ti.length; ti.length--)
543     {
544       iter <<= 8;
545       iter |= (*p++) & 0xff; 
546       n--;
547     }
548   
549   where = "rc2-ciphertext";
550   if (parse_tag (&p, &n, &ti))
551     goto bailout;
552
553   consumed = p - p_start;
554   if (ti.class == CONTEXT && ti.tag == 0 && ti.is_constructed && ti.ndef)
555     {
556       /* Mozilla exported certs now come with single byte chunks of
557          octect strings.  (Mozilla Firefox 1.0.4).  Arghh. */
558       where = "cram-rc2-ciphertext";
559       cram_buffer = cram_octet_string ( p, &n, &consumed);
560       if (!cram_buffer)
561         goto bailout;
562       p = p_start = cram_buffer;
563       if (r_consumed)
564         *r_consumed = consumed;
565       r_consumed = NULL; /* Ugly hack to not update that value any further. */
566       ti.length = n;
567     }
568   else if (ti.class == CONTEXT && ti.tag == 0 && ti.length )
569     ;
570   else
571     goto bailout;
572   
573   log_info ("%lu bytes of RC2 encrypted text\n", ti.length);
574
575   plain = gcry_malloc_secure (ti.length);
576   if (!plain)
577     {
578       log_error ("error allocating decryption buffer\n");
579       goto bailout;
580     }
581   memcpy (plain, p, ti.length);
582   crypt_block (plain, ti.length, salt, saltlen,
583                iter, pw, GCRY_CIPHER_RFC2268_40, 0);
584   n = ti.length;
585   startoffset = 0;
586   p_start = p = plain;
587
588 /*   { */
589 /* #  warning debug code is enabled */
590 /*     FILE *fp = fopen ("tmp-rc2-plain.der", "wb"); */
591 /*     if (!fp || fwrite (p, n, 1, fp) != 1) */
592 /*       exit (2); */
593 /*     fclose (fp); */
594 /*   } */
595
596   where = "outer.outer.seq";
597   if (parse_tag (&p, &n, &ti))
598     {
599       bad_pass = 1;
600       goto bailout;
601     }
602   if (ti.class || ti.tag != TAG_SEQUENCE)
603     {
604       bad_pass = 1;
605       goto bailout;
606     }
607
608   if (parse_tag (&p, &n, &ti))
609     {
610       bad_pass = 1;
611       goto bailout;
612     }
613
614   /* Loop over all certificates inside the bag. */
615   while (n)
616     {
617       int isbag = 0;
618
619       where = "certbag.nextcert";
620       if (ti.class || ti.tag != TAG_SEQUENCE)
621         goto bailout;
622
623       where = "certbag.objectidentifier";
624       if (parse_tag (&p, &n, &ti))
625         goto bailout;
626       if (ti.class || ti.tag != TAG_OBJECT_ID)
627         goto bailout;
628       if ( ti.length == DIM(oid_pkcs_12_CertBag)
629            && !memcmp (p, oid_pkcs_12_CertBag, DIM(oid_pkcs_12_CertBag)))
630         {
631           p += DIM(oid_pkcs_12_CertBag);
632           n -= DIM(oid_pkcs_12_CertBag);
633         }
634       else if ( ti.length == DIM(oid_pkcs_12_CrlBag)
635            && !memcmp (p, oid_pkcs_12_CrlBag, DIM(oid_pkcs_12_CrlBag)))
636         {
637           p += DIM(oid_pkcs_12_CrlBag);
638           n -= DIM(oid_pkcs_12_CrlBag);
639           isbag = 1;
640         }
641       else
642         goto bailout;
643
644       where = "certbag.before.certheader";
645       if (parse_tag (&p, &n, &ti))
646         goto bailout;
647       if (ti.class != CONTEXT || ti.tag)
648         goto bailout;
649       if (isbag)
650         {
651           log_info ("skipping unsupported crlBag\n");
652           p += ti.length;
653           n -= ti.length;
654         }
655       else
656         {
657           if (parse_tag (&p, &n, &ti))
658             goto bailout;
659           if (ti.class || ti.tag != TAG_SEQUENCE)
660             goto bailout;
661           if (parse_tag (&p, &n, &ti))
662             goto bailout;
663           if (ti.class || ti.tag != TAG_OBJECT_ID
664               || ti.length != DIM(oid_x509Certificate_for_pkcs_12)
665               || memcmp (p, oid_x509Certificate_for_pkcs_12,
666                          DIM(oid_x509Certificate_for_pkcs_12)))
667             goto bailout;
668           p += DIM(oid_x509Certificate_for_pkcs_12);
669           n -= DIM(oid_x509Certificate_for_pkcs_12);
670           
671           where = "certbag.before.octetstring";
672           if (parse_tag (&p, &n, &ti))
673             goto bailout;
674           if (ti.class != CONTEXT || ti.tag)
675             goto bailout;
676           if (parse_tag (&p, &n, &ti))
677             goto bailout;
678           if (ti.class || ti.tag != TAG_OCTET_STRING || ti.ndef)
679             goto bailout;
680           
681           /* Return the certificate. */
682           if (certcb)
683             certcb (certcbarg, p, ti.length);
684    
685           p += ti.length;
686           n -= ti.length;
687         }
688
689       /* Ugly hack to cope with the padding: Forget about the rest if
690          that is less or equal to the cipher's block length.  We can
691          reasonable assume that all valid data will be longer than
692          just one block. */
693       if (n <= 8)
694         n = 0;  
695
696       /* Skip the optional SET with the pkcs12 cert attributes. */
697       if (n)
698         {
699           where = "bag.attributes";
700           if (parse_tag (&p, &n, &ti))
701             goto bailout;
702           if (!ti.class && ti.tag == TAG_SEQUENCE)
703             ; /* No attributes. */
704           else if (!ti.class && ti.tag == TAG_SET && !ti.ndef)
705             { /* The optional SET. */
706               p += ti.length;
707               n -= ti.length;
708               if (n <= 8)
709                 n = 0;
710               if (n && parse_tag (&p, &n, &ti))
711                 goto bailout;
712             }
713           else
714             goto bailout;
715         }
716     }
717   
718   if (r_consumed)
719     *r_consumed = consumed;
720   gcry_free (plain);
721   gcry_free (cram_buffer);
722   return 0;
723
724  bailout:
725   if (r_consumed)
726     *r_consumed = consumed;
727   gcry_free (plain);
728   gcry_free (cram_buffer);
729   log_error ("encryptedData error at \"%s\", offset %u\n",
730              where, (p - p_start)+startoffset);
731   if (bad_pass)
732     {
733       /* Note, that the following string might be used by other programs
734          to check for a bad passphrase; it should therefore not be
735          translated or changed. */
736       log_error ("possibly bad passphrase given\n");
737     }
738   return -1;
739 }
740
741 static gcry_mpi_t *
742 parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
743                 size_t *r_consumed, const char *pw)
744 {
745   int rc;
746   struct tag_info ti;
747   const unsigned char *p = buffer;
748   const unsigned char *p_start = buffer;
749   size_t n = length;
750   const char *where;
751   char salt[16];
752   size_t saltlen;
753   unsigned int iter;
754   int len;
755   unsigned char *plain = NULL;
756   gcry_mpi_t *result = NULL;
757   int result_count, i;
758   unsigned char *cram_buffer = NULL;
759   size_t consumed = 0; /* Number of bytes consumed from the orginal buffer. */
760
761   where = "start";
762   if (parse_tag (&p, &n, &ti))
763     goto bailout;
764   if (ti.class != CONTEXT || ti.tag)
765     goto bailout;
766   if (parse_tag (&p, &n, &ti))
767     goto bailout;
768   if (ti.class || ti.tag != TAG_OCTET_STRING)
769     goto bailout;
770
771   consumed = p - p_start;
772   if (ti.is_constructed && ti.ndef)
773     {
774       /* Mozilla exported certs now come with single byte chunks of
775          octect strings.  (Mozilla Firefox 1.0.4).  Arghh. */
776       where = "cram-data.outersegs";
777       cram_buffer = cram_octet_string ( p, &n, &consumed);
778       if (!cram_buffer)
779         goto bailout;
780       p = p_start = cram_buffer;
781       if (r_consumed)
782         *r_consumed = consumed;
783       r_consumed = NULL; /* Ugly hack to not update that value any further. */
784     }
785   
786
787   where = "data.outerseqs";
788   if (parse_tag (&p, &n, &ti))
789     goto bailout;
790   if (ti.class || ti.tag != TAG_SEQUENCE)
791     goto bailout;
792   if (parse_tag (&p, &n, &ti))
793     goto bailout;
794   if (ti.class || ti.tag != TAG_SEQUENCE)
795     goto bailout;
796
797   where = "data.objectidentifier";
798   if (parse_tag (&p, &n, &ti))
799     goto bailout;
800   if (ti.class || ti.tag != TAG_OBJECT_ID
801       || ti.length != DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag)
802       || memcmp (p, oid_pkcs_12_pkcs_8ShroudedKeyBag,
803                  DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag)))
804     goto bailout;
805   p += DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag);
806   n -= DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag);
807
808   where = "shrouded,outerseqs";
809   if (parse_tag (&p, &n, &ti))
810     goto bailout;
811   if (ti.class != CONTEXT || ti.tag)
812     goto bailout;
813   if (parse_tag (&p, &n, &ti))
814     goto bailout;
815   if (ti.class || ti.tag != TAG_SEQUENCE)
816     goto bailout;
817   if (parse_tag (&p, &n, &ti))
818     goto bailout;
819   if (ti.class || ti.tag != TAG_SEQUENCE)
820     goto bailout;
821   if (parse_tag (&p, &n, &ti))
822     goto bailout;
823   if (ti.class || ti.tag != TAG_OBJECT_ID
824       || ti.length != DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)
825       || memcmp (p, oid_pbeWithSHAAnd3_KeyTripleDES_CBC,
826                  DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)))
827     goto bailout;
828   p += DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
829   n -= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
830
831   where = "3des-params";
832   if (parse_tag (&p, &n, &ti))
833     goto bailout;
834   if (ti.class || ti.tag != TAG_SEQUENCE)
835     goto bailout;
836   if (parse_tag (&p, &n, &ti))
837     goto bailout;
838   if (ti.class || ti.tag != TAG_OCTET_STRING
839       || ti.length < 8 || ti.length > 16)
840     goto bailout;
841   saltlen = ti.length;
842   memcpy (salt, p, saltlen);
843   p += saltlen;
844   n -= saltlen;
845   if (parse_tag (&p, &n, &ti))
846     goto bailout;
847   if (ti.class || ti.tag != TAG_INTEGER || !ti.length )
848     goto bailout;
849   for (iter=0; ti.length; ti.length--)
850     {
851       iter <<= 8;
852       iter |= (*p++) & 0xff; 
853       n--;
854     }
855   
856   where = "3des-ciphertext";
857   if (parse_tag (&p, &n, &ti))
858     goto bailout;
859   if (ti.class || ti.tag != TAG_OCTET_STRING || !ti.length )
860     goto bailout;
861   
862   log_info ("%lu bytes of 3DES encrypted text\n", ti.length);
863   
864   plain = gcry_malloc_secure (ti.length);
865   if (!plain)
866     {
867       log_error ("error allocating decryption buffer\n");
868       goto bailout;
869     }
870   memcpy (plain, p, ti.length);
871   consumed += p - p_start + ti.length;
872   crypt_block (plain, ti.length, salt, saltlen, iter, pw, GCRY_CIPHER_3DES, 0);
873   n = ti.length;
874   startoffset = 0;
875   p_start = p = plain;
876
877 /*   { */
878 /* #  warning debug code is enabled */
879 /*     FILE *fp = fopen ("tmp-rc2-plain-key.der", "wb"); */
880 /*     if (!fp || fwrite (p, n, 1, fp) != 1) */
881 /*       exit (2); */
882 /*     fclose (fp); */
883 /*   } */
884
885
886   where = "decrypted-text";
887   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
888     goto bailout;
889   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER
890       || ti.length != 1 || *p)
891     goto bailout;
892   p++; n--;
893   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
894     goto bailout;
895   len = ti.length;
896   if (parse_tag (&p, &n, &ti))
897     goto bailout;
898   if (len < ti.nhdr)
899     goto bailout;
900   len -= ti.nhdr;
901   if (ti.class || ti.tag != TAG_OBJECT_ID
902       || ti.length != DIM(oid_rsaEncryption)
903       || memcmp (p, oid_rsaEncryption,
904                  DIM(oid_rsaEncryption)))
905     goto bailout;
906   p += DIM (oid_rsaEncryption);
907   n -= DIM (oid_rsaEncryption);
908   if (len < ti.length)
909     goto bailout;
910   len -= ti.length;
911   if (n < len)
912     goto bailout;
913   p += len;
914   n -= len;
915   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_OCTET_STRING)
916     goto bailout;
917   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
918     goto bailout;
919   len = ti.length;
920
921   result = gcry_calloc (10, sizeof *result);
922   if (!result)
923     {
924       log_error ( "error allocating result array\n");
925       goto bailout;
926     }
927   result_count = 0;
928
929   where = "reading.key-parameters";
930   for (result_count=0; len && result_count < 9;)
931     {
932       if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER)
933         goto bailout;
934       if (len < ti.nhdr)
935         goto bailout;
936       len -= ti.nhdr;
937       if (len < ti.length)
938         goto bailout;
939       len -= ti.length;
940       if (!result_count && ti.length == 1 && !*p)
941         ; /* ignore the very first one if it is a 0 */
942       else 
943         {
944           rc = gcry_mpi_scan (result+result_count, GCRYMPI_FMT_USG, p,
945                               ti.length, NULL);
946           if (rc)
947             {
948               log_error ("error parsing key parameter: %s\n",
949                          gpg_strerror (rc));
950               goto bailout;
951             }
952           result_count++;
953         }
954       p += ti.length;
955       n -= ti.length;
956     }
957   if (len)
958     goto bailout;
959
960   gcry_free (cram_buffer);
961   if (r_consumed)
962     *r_consumed = consumed;
963   return result;
964
965  bailout:
966   gcry_free (plain);
967   if (result)
968     {
969       for (i=0; result[i]; i++)
970         gcry_mpi_release (result[i]);
971       gcry_free (result);
972     }
973   gcry_free (cram_buffer);
974   log_error ( "data error at \"%s\", offset %u\n",
975               where, (p - buffer) + startoffset);
976   if (r_consumed)
977     *r_consumed = consumed;
978   return NULL;
979 }
980
981
982 /* Parse a PKCS12 object and return an array of MPI representing the
983    secret key parameters.  This is a very limited implementation in
984    that it is only able to look for 3DES encoded encryptedData and
985    tries to extract the first private key object it finds.  In case of
986    an error NULL is returned. CERTCB and CERRTCBARG are used to pass
987    X.509 certificates back to the caller. */
988 gcry_mpi_t *
989 p12_parse (const unsigned char *buffer, size_t length, const char *pw,
990            void (*certcb)(void*, const unsigned char*, size_t),
991            void *certcbarg)
992 {
993   struct tag_info ti;
994   const unsigned char *p = buffer;
995   const unsigned char *p_start = buffer;
996   size_t n = length;
997   const char *where;
998   int bagseqlength, len;
999   int bagseqndef, lenndef;
1000   gcry_mpi_t *result = NULL;
1001   unsigned char *cram_buffer = NULL;
1002
1003   where = "pfx";
1004   if (parse_tag (&p, &n, &ti))
1005     goto bailout;
1006   if (ti.tag != TAG_SEQUENCE)
1007     goto bailout;
1008
1009   where = "pfxVersion";
1010   if (parse_tag (&p, &n, &ti))
1011     goto bailout;
1012   if (ti.tag != TAG_INTEGER || ti.length != 1 || *p != 3)
1013     goto bailout;
1014   p++; n--;
1015   
1016   where = "authSave";
1017   if (parse_tag (&p, &n, &ti))
1018     goto bailout;
1019   if (ti.tag != TAG_SEQUENCE)
1020     goto bailout;
1021   if (parse_tag (&p, &n, &ti))
1022     goto bailout;
1023   if (ti.tag != TAG_OBJECT_ID || ti.length != DIM(oid_data)
1024       || memcmp (p, oid_data, DIM(oid_data)))
1025     goto bailout;
1026   p += DIM(oid_data);
1027   n -= DIM(oid_data);
1028
1029   if (parse_tag (&p, &n, &ti))
1030     goto bailout;
1031   if (ti.class != CONTEXT || ti.tag)
1032     goto bailout;
1033   if (parse_tag (&p, &n, &ti))
1034     goto bailout;
1035   if (ti.class != UNIVERSAL || ti.tag != TAG_OCTET_STRING)
1036     goto bailout;
1037
1038   if (ti.is_constructed && ti.ndef)
1039     {
1040       /* Mozilla exported certs now come with single byte chunks of
1041          octect strings.  (Mozilla Firefox 1.0.4).  Arghh. */
1042       where = "cram-bags";
1043       cram_buffer = cram_octet_string ( p, &n, NULL);
1044       if (!cram_buffer)
1045         goto bailout;
1046       p = p_start = cram_buffer;
1047     }
1048
1049   where = "bags";
1050   if (parse_tag (&p, &n, &ti))
1051     goto bailout;
1052   if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE)
1053     goto bailout;
1054   bagseqndef = ti.ndef;
1055   bagseqlength = ti.length;
1056   while (bagseqlength || bagseqndef)
1057     {
1058       log_debug ( "at offset %u\n", (p - p_start));
1059       where = "bag-sequence";
1060       if (parse_tag (&p, &n, &ti))
1061         goto bailout;
1062       if (bagseqndef && ti.class == UNIVERSAL && !ti.tag && !ti.is_constructed)
1063         break; /* Ready */ 
1064       if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE)
1065         goto bailout;
1066
1067       if (!bagseqndef)
1068         {
1069           if (bagseqlength < ti.nhdr)
1070             goto bailout;
1071           bagseqlength -= ti.nhdr;
1072           if (bagseqlength < ti.length)
1073             goto bailout;
1074           bagseqlength -= ti.length;
1075         }
1076       lenndef = ti.ndef;
1077       len = ti.length;
1078
1079       if (parse_tag (&p, &n, &ti))
1080         goto bailout;
1081       if (lenndef)
1082         len = ti.nhdr; 
1083       else
1084         len -= ti.nhdr; 
1085
1086       if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_encryptedData)
1087           && !memcmp (p, oid_encryptedData, DIM(oid_encryptedData)))
1088         {
1089           size_t consumed = 0;
1090
1091           p += DIM(oid_encryptedData);
1092           n -= DIM(oid_encryptedData);
1093           if (!lenndef)
1094             len -= DIM(oid_encryptedData);
1095           where = "bag.encryptedData";
1096           if (parse_bag_encrypted_data (p, n, (p - p_start), &consumed, pw,
1097                                         certcb, certcbarg))
1098             goto bailout;
1099           if (lenndef)
1100             len += consumed;
1101         }
1102       else if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_data)
1103                && !memcmp (p, oid_data, DIM(oid_data)))
1104         {
1105           if (result)
1106             {
1107               log_info ("already got an data object, skipping next one\n");
1108               p += ti.length;
1109               n -= ti.length;
1110             }
1111           else
1112             {
1113               size_t consumed = 0;
1114
1115               p += DIM(oid_data);
1116               n -= DIM(oid_data);
1117               if (!lenndef)
1118                 len -= DIM(oid_data);
1119               result = parse_bag_data (p, n, (p - p_start), &consumed, pw);
1120               if (!result)
1121                 goto bailout;
1122               if (lenndef)
1123                 len += consumed;
1124             }
1125         }
1126       else
1127         {
1128           log_info ("unknown bag type - skipped\n");
1129           p += ti.length;
1130           n -= ti.length;
1131         }
1132
1133       if (len < 0 || len > n)
1134         goto bailout;
1135       p += len;
1136       n -= len;
1137       if (lenndef)
1138         {
1139           /* Need to skip the Null Tag. */
1140           if (parse_tag (&p, &n, &ti))
1141             goto bailout;
1142           if (!(ti.class == UNIVERSAL && !ti.tag && !ti.is_constructed))
1143             goto bailout;
1144         }
1145     }
1146   
1147   gcry_free (cram_buffer);
1148   return result;
1149  bailout:
1150   log_error ("error at \"%s\", offset %u\n", where, (p - p_start));
1151   /* fixme: need to release RESULT. */
1152   gcry_free (cram_buffer);
1153   return NULL;
1154 }
1155
1156
1157 \f
1158 static size_t
1159 compute_tag_length (size_t n)
1160 {     
1161   int needed = 0;
1162
1163   if (n < 128)
1164     needed += 2; /* tag and one length byte */
1165   else if (n < 256)
1166     needed += 3; /* tag, number of length bytes, 1 length byte */
1167   else if (n < 65536)
1168     needed += 4; /* tag, number of length bytes, 2 length bytes */
1169   else
1170     {
1171       log_error ("object too larger to encode\n");
1172       return 0;
1173     }
1174   return needed;
1175 }
1176
1177 static unsigned char *
1178 store_tag_length (unsigned char *p, int tag, size_t n)
1179 {     
1180   if (tag == TAG_SEQUENCE)
1181     tag |= 0x20; /* constructed */
1182
1183   *p++ = tag;
1184   if (n < 128)
1185     *p++ = n;
1186   else if (n < 256)
1187     {
1188       *p++ = 0x81;
1189       *p++ = n;
1190     }
1191   else if (n < 65536)
1192     {
1193       *p++ = 0x82;
1194       *p++ = n >> 8;
1195       *p++ = n;
1196     }
1197
1198   return p;
1199 }
1200
1201
1202 /* Create the final PKCS-12 object from the sequences contained in
1203    SEQLIST.  That array is terminated with an NULL object */
1204 static unsigned char *
1205 create_final (struct buffer_s *sequences, size_t *r_length)
1206 {
1207   int i;
1208   size_t needed = 0;
1209   size_t len[8], n;
1210   unsigned char *result, *p;
1211   size_t resultlen;
1212
1213   /* 8 steps to create the pkcs#12 Krampf. */
1214
1215   /* 7. All the buffers. */
1216   for (i=0; sequences[i].buffer; i++)
1217     needed += sequences[i].length;
1218
1219   /* 6. This goes into a sequences. */
1220   len[6] = needed;
1221   n = compute_tag_length (needed);
1222   needed += n;
1223
1224   /* 5. Encapsulate all in an octet string. */
1225   len[5] = needed;
1226   n = compute_tag_length (needed);
1227   needed += n;
1228
1229   /* 4. And tag it with [0]. */
1230   len[4] = needed;
1231   n = compute_tag_length (needed);
1232   needed += n;
1233
1234   /* 3. Prepend an data OID. */
1235   needed += 2 + DIM (oid_data);
1236
1237   /* 2. Put all into a sequences. */
1238   len[2] = needed;
1239   n = compute_tag_length (needed);
1240   needed += n;
1241
1242   /* 1. Prepend the version integer 3. */
1243   needed += 3;
1244
1245   /* 0. And the final outer sequence. */
1246   len[0] = needed;
1247   n = compute_tag_length (needed);
1248   needed += n;
1249
1250   /* Allocate a buffer. */
1251   result = gcry_malloc (needed);
1252   if (!result)
1253     {
1254       log_error ("error allocating buffer\n");
1255       return NULL;
1256     }
1257   p = result;
1258
1259   /* 0. Store the very outer sequence. */
1260   p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1261
1262   /* 1. Store the version integer 3. */
1263   *p++ = TAG_INTEGER;
1264   *p++ = 1; 
1265   *p++ = 3;
1266  
1267   /* 2. Store another sequence. */
1268   p = store_tag_length (p, TAG_SEQUENCE, len[2]);
1269
1270   /* 3. Store the data OID. */
1271   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
1272   memcpy (p, oid_data, DIM (oid_data)); 
1273   p += DIM (oid_data); 
1274
1275   /* 4. Next comes a context tag. */
1276   p = store_tag_length (p, 0xa0, len[4]);
1277
1278   /* 5. And an octet string. */
1279   p = store_tag_length (p, TAG_OCTET_STRING, len[5]);
1280
1281   /* 6. And the inner sequence. */
1282   p = store_tag_length (p, TAG_SEQUENCE, len[6]);
1283
1284   /* 7. Append all the buffers. */
1285   for (i=0; sequences[i].buffer; i++)
1286     {
1287       memcpy (p, sequences[i].buffer, sequences[i].length);
1288       p += sequences[i].length;
1289     }
1290
1291   /* Ready. */
1292   resultlen = p - result;
1293   if (needed != resultlen)
1294     log_debug ("length mismatch: %lu, %lu\n",
1295                (unsigned long)needed, (unsigned long)resultlen);
1296
1297   *r_length = resultlen;
1298   return result;
1299 }
1300
1301
1302 /* Build a DER encoded SEQUENCE with the key:
1303
1304    SEQUENCE {
1305      INTEGER 0
1306      SEQUENCE {
1307        OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
1308        NULL
1309        }
1310      OCTET STRING, encapsulates {
1311        SEQUENCE {
1312          INTEGER 0
1313          INTEGER
1314          INTEGER 
1315          INTEGER
1316          INTEGER
1317          INTEGER
1318          INTEGER
1319          INTEGER
1320          INTEGER
1321          }
1322        }
1323      }
1324 */  
1325   
1326 static unsigned char * 
1327 build_key_sequence (gcry_mpi_t *kparms, size_t *r_length)
1328 {
1329   int rc, i;
1330   size_t needed, n;
1331   unsigned char *plain, *p;
1332   size_t plainlen;
1333   size_t outseqlen, oidseqlen, octstrlen, inseqlen;
1334
1335   needed = 3; /* The version(?) integer of value 0. */
1336   for (i=0; kparms[i]; i++)
1337     {
1338       n = 0;
1339       rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, kparms[i]);
1340       if (rc)
1341         {
1342           log_error ("error formatting parameter: %s\n", gpg_strerror (rc));
1343           return NULL;
1344         }
1345       needed += n;
1346       n = compute_tag_length (n);
1347       if (!n)
1348         return NULL;
1349       needed += n;
1350     }
1351   if (i != 8)
1352     {
1353       log_error ("invalid paramters for p12_build\n");
1354       return NULL;
1355     }
1356   /* Now this all goes into a sequence. */
1357   inseqlen = needed;
1358   n = compute_tag_length (needed);
1359   if (!n)
1360     return NULL;
1361   needed += n;
1362   /* Encapsulate all into an octet string. */
1363   octstrlen = needed;
1364   n = compute_tag_length (needed);
1365   if (!n)
1366     return NULL;
1367   needed += n;
1368   /* Prepend the object identifier sequence. */
1369   oidseqlen = 2 + DIM (oid_rsaEncryption) + 2;
1370   needed += 2 + oidseqlen;
1371   /* The version number. */
1372   needed += 3;
1373   /* And finally put the whole thing into a sequence. */
1374   outseqlen = needed;
1375   n = compute_tag_length (needed);
1376   if (!n)
1377     return NULL;
1378   needed += n;
1379   
1380   /* allocate 8 extra bytes for padding */
1381   plain = gcry_malloc_secure (needed+8);
1382   if (!plain)
1383     {
1384       log_error ("error allocating encryption buffer\n");
1385       return NULL;
1386     }
1387   
1388   /* And now fill the plaintext buffer. */
1389   p = plain;
1390   p = store_tag_length (p, TAG_SEQUENCE, outseqlen);
1391   /* Store version. */
1392   *p++ = TAG_INTEGER;
1393   *p++ = 1;
1394   *p++ = 0;
1395   /* Store object identifier sequence. */
1396   p = store_tag_length (p, TAG_SEQUENCE, oidseqlen);
1397   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_rsaEncryption));
1398   memcpy (p, oid_rsaEncryption, DIM (oid_rsaEncryption)); 
1399   p += DIM (oid_rsaEncryption); 
1400   *p++ = TAG_NULL;
1401   *p++ = 0;
1402   /* Start with the octet string. */
1403   p = store_tag_length (p, TAG_OCTET_STRING, octstrlen);
1404   p = store_tag_length (p, TAG_SEQUENCE, inseqlen);
1405   /* Store the key parameters. */
1406   *p++ = TAG_INTEGER;
1407   *p++ = 1;
1408   *p++ = 0;
1409   for (i=0; kparms[i]; i++)
1410     {
1411       n = 0;
1412       rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, kparms[i]);
1413       if (rc)
1414         {
1415           log_error ("oops: error formatting parameter: %s\n",
1416                      gpg_strerror (rc));
1417           gcry_free (plain);
1418           return NULL;
1419         }
1420       p = store_tag_length (p, TAG_INTEGER, n);
1421       
1422       n = plain + needed - p;
1423       rc = gcry_mpi_print (GCRYMPI_FMT_STD, p, n, &n, kparms[i]);
1424       if (rc)
1425         {
1426           log_error ("oops: error storing parameter: %s\n",
1427                      gpg_strerror (rc));
1428           gcry_free (plain);
1429           return NULL;
1430         }
1431       p += n;
1432     }
1433
1434   plainlen = p - plain;
1435   assert (needed == plainlen);
1436   /* Append some pad characters; we already allocated extra space. */
1437   n = 8 - plainlen % 8;
1438   for (i=0; i < n; i++, plainlen++)
1439     *p++ = n;
1440
1441   *r_length = plainlen;
1442   return plain;
1443 }
1444
1445
1446
1447 static unsigned char *
1448 build_key_bag (unsigned char *buffer, size_t buflen, char *salt,
1449                size_t *r_length)
1450 {
1451   size_t len[11], needed;
1452   unsigned char *p, *keybag;
1453   size_t keybaglen;
1454
1455   /* Walk 11 steps down to collect the info: */
1456
1457   /* 10. The data goes into an octet string. */
1458   needed = compute_tag_length (buflen);
1459   needed += buflen;
1460
1461   /* 9. Prepend the algorithm identifier. */
1462   needed += DIM (data_3desiter2048);
1463
1464   /* 8. Put a sequence around. */
1465   len[8] = needed;
1466   needed += compute_tag_length (needed);
1467
1468   /* 7. Prepend a [0] tag. */
1469   len[7] = needed;
1470   needed += compute_tag_length (needed);
1471
1472   /* 6. Prepend the shroudedKeyBag OID. */
1473   needed += 2 + DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag);
1474
1475   /* 5+4. Put all into two sequences. */
1476   len[5] = needed;
1477   needed += compute_tag_length ( needed);
1478   len[4] = needed;
1479   needed += compute_tag_length (needed);
1480
1481   /* 3. This all goes into an octet string. */
1482   len[3] = needed;
1483   needed += compute_tag_length (needed);
1484
1485   /* 2. Prepend another [0] tag. */
1486   len[2] = needed;
1487   needed += compute_tag_length (needed);
1488
1489   /* 1. Prepend the data OID. */
1490   needed += 2 + DIM (oid_data);
1491
1492   /* 0. Prepend another sequence. */
1493   len[0] = needed;
1494   needed += compute_tag_length (needed);
1495
1496   /* Now that we have all length information, allocate a buffer. */
1497   p = keybag = gcry_malloc (needed);
1498   if (!keybag)
1499     {
1500       log_error ("error allocating buffer\n");
1501       return NULL;
1502     }
1503
1504   /* Walk 11 steps up to store the data. */
1505
1506   /* 0. Store the first sequence. */
1507   p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1508
1509   /* 1. Store the data OID. */
1510   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
1511   memcpy (p, oid_data, DIM (oid_data)); 
1512   p += DIM (oid_data); 
1513
1514   /* 2. Store a [0] tag. */
1515   p = store_tag_length (p, 0xa0, len[2]);
1516
1517   /* 3. And an octet string. */
1518   p = store_tag_length (p, TAG_OCTET_STRING, len[3]);
1519
1520   /* 4+5. Two sequences. */
1521   p = store_tag_length (p, TAG_SEQUENCE, len[4]);
1522   p = store_tag_length (p, TAG_SEQUENCE, len[5]);
1523
1524   /* 6. Store the shroudedKeyBag OID. */
1525   p = store_tag_length (p, TAG_OBJECT_ID,
1526                         DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag));
1527   memcpy (p, oid_pkcs_12_pkcs_8ShroudedKeyBag,
1528           DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag)); 
1529   p += DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag); 
1530
1531   /* 7. Store a [0] tag. */
1532   p = store_tag_length (p, 0xa0, len[7]);
1533
1534   /* 8. Store a sequence. */
1535   p = store_tag_length (p, TAG_SEQUENCE, len[8]);
1536
1537   /* 9. Now for the pre-encoded algorithm identifier and the salt. */
1538   memcpy (p, data_3desiter2048, DIM (data_3desiter2048));
1539   memcpy (p + DATA_3DESITER2048_SALT_OFF, salt, 8);
1540   p += DIM (data_3desiter2048);
1541
1542   /* 10. And finally the octet string with the encrypted data. */
1543   p = store_tag_length (p, TAG_OCTET_STRING, buflen);
1544   memcpy (p, buffer, buflen);
1545   p += buflen;
1546   keybaglen = p - keybag;
1547   
1548   if (needed != keybaglen)
1549     log_debug ("length mismatch: %lu, %lu\n",
1550                (unsigned long)needed, (unsigned long)keybaglen);
1551   
1552   *r_length = keybaglen;
1553   return keybag;
1554 }
1555
1556
1557 static unsigned char *
1558 build_cert_bag (unsigned char *buffer, size_t buflen, char *salt,
1559                 size_t *r_length)
1560 {
1561   size_t len[9], needed;
1562   unsigned char *p, *certbag;
1563   size_t certbaglen;
1564
1565   /* Walk 9 steps down to collect the info: */
1566
1567   /* 8. The data goes into an octet string. */
1568   needed = compute_tag_length (buflen);
1569   needed += buflen;
1570
1571   /* 7. The algorithm identifier. */
1572   needed += DIM (data_rc2iter2048);
1573
1574   /* 6. The data OID. */
1575   needed += 2 + DIM (oid_data);
1576
1577   /* 5. A sequence. */
1578   len[5] = needed;
1579   needed += compute_tag_length ( needed);
1580
1581   /* 4. An integer. */
1582   needed += 3;
1583
1584   /* 3. A sequence. */
1585   len[3] = needed;
1586   needed += compute_tag_length (needed);
1587
1588   /* 2.  A [0] tag. */
1589   len[2] = needed;
1590   needed += compute_tag_length (needed);
1591
1592   /* 1. The encryptedData OID. */
1593   needed += 2 + DIM (oid_encryptedData);
1594
1595   /* 0. The first sequence. */
1596   len[0] = needed;
1597   needed += compute_tag_length (needed);
1598
1599   /* Now that we have all length information, allocate a buffer. */
1600   p = certbag = gcry_malloc (needed);
1601   if (!certbag)
1602     {
1603       log_error ("error allocating buffer\n");
1604       return NULL;
1605     }
1606
1607   /* Walk 9 steps up to store the data. */
1608
1609   /* 0. Store the first sequence. */
1610   p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1611
1612   /* 1. Store the encryptedData OID. */
1613   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_encryptedData));
1614   memcpy (p, oid_encryptedData, DIM (oid_encryptedData)); 
1615   p += DIM (oid_encryptedData); 
1616
1617   /* 2. Store a [0] tag. */
1618   p = store_tag_length (p, 0xa0, len[2]);
1619
1620   /* 3. Store a sequence. */
1621   p = store_tag_length (p, TAG_SEQUENCE, len[3]);
1622
1623   /* 4. Store the integer 0. */
1624   *p++ = TAG_INTEGER;
1625   *p++ = 1; 
1626   *p++ = 0;
1627
1628   /* 5. Store a sequence. */
1629   p = store_tag_length (p, TAG_SEQUENCE, len[5]);
1630
1631   /* 6. Store the data OID. */
1632   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
1633   memcpy (p, oid_data, DIM (oid_data)); 
1634   p += DIM (oid_data); 
1635
1636   /* 7. Now for the pre-encoded algorithm identifier and the salt. */
1637   memcpy (p, data_rc2iter2048, DIM (data_rc2iter2048));
1638   memcpy (p + DATA_RC2ITER2048_SALT_OFF, salt, 8);
1639   p += DIM (data_rc2iter2048);
1640
1641   /* 8. And finally the [0] tag with the encrypted data. */
1642   p = store_tag_length (p, 0x80, buflen);
1643   memcpy (p, buffer, buflen);
1644   p += buflen;
1645   certbaglen = p - certbag;
1646   
1647   if (needed != certbaglen)
1648     log_debug ("length mismatch: %lu, %lu\n",
1649                (unsigned long)needed, (unsigned long)certbaglen);
1650
1651   *r_length = certbaglen;
1652   return certbag;
1653 }
1654
1655
1656 static unsigned char *
1657 build_cert_sequence (unsigned char *buffer, size_t buflen, size_t *r_length)
1658 {
1659   size_t len[8], needed, n;
1660   unsigned char *p, *certseq;
1661   size_t certseqlen;
1662   int i;
1663
1664   /* Walk 8 steps down to collect the info: */
1665
1666   /* 7. The data goes into an octet string. */
1667   needed = compute_tag_length (buflen);
1668   needed += buflen;
1669
1670   /* 6. A [0] tag. */
1671   len[6] = needed;
1672   needed += compute_tag_length (needed);
1673
1674   /* 5. An OID. */
1675   needed += 2 + DIM (oid_x509Certificate_for_pkcs_12);
1676
1677   /* 4. A sequence. */
1678   len[4] = needed;
1679   needed += compute_tag_length (needed);
1680
1681   /* 3. A [0] tag. */
1682   len[3] = needed;
1683   needed += compute_tag_length (needed);
1684
1685   /* 2. An OID. */
1686   needed += 2 + DIM (oid_pkcs_12_CertBag);
1687
1688   /* 1. A sequence. */
1689   len[1] = needed;
1690   needed += compute_tag_length (needed);
1691
1692   /* 0. The first sequence. */
1693   len[0] = needed;
1694   needed += compute_tag_length (needed);
1695
1696   /* Now that we have all length information, allocate a buffer. */
1697   p = certseq = gcry_malloc (needed + 8 /*(for padding)*/);
1698   if (!certseq)
1699     {
1700       log_error ("error allocating buffer\n");
1701       return NULL;
1702     }
1703
1704   /* Walk 8 steps up to store the data. */
1705
1706   /* 0. Store the first sequence. */
1707   p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1708
1709   /* 1. Store the second sequence. */
1710   p = store_tag_length (p, TAG_SEQUENCE, len[1]);
1711
1712   /* 2. Store the pkcs12-cert-bag OID. */
1713   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_pkcs_12_CertBag));
1714   memcpy (p, oid_pkcs_12_CertBag, DIM (oid_pkcs_12_CertBag)); 
1715   p += DIM (oid_pkcs_12_CertBag); 
1716
1717   /* 3. Store a [0] tag. */
1718   p = store_tag_length (p, 0xa0, len[3]);
1719
1720   /* 4. Store a sequence. */
1721   p = store_tag_length (p, TAG_SEQUENCE, len[4]);
1722
1723   /* 5. Store the x509Certificate OID. */
1724   p = store_tag_length (p, TAG_OBJECT_ID,
1725                         DIM (oid_x509Certificate_for_pkcs_12));
1726   memcpy (p, oid_x509Certificate_for_pkcs_12,
1727           DIM (oid_x509Certificate_for_pkcs_12)); 
1728   p += DIM (oid_x509Certificate_for_pkcs_12); 
1729
1730   /* 6. Store a [0] tag. */
1731   p = store_tag_length (p, 0xa0, len[6]);
1732
1733   /* 7. And finally the octet string with the actual certificate. */
1734   p = store_tag_length (p, TAG_OCTET_STRING, buflen);
1735   memcpy (p, buffer, buflen);
1736   p += buflen;
1737   certseqlen = p - certseq;
1738   
1739   if (needed != certseqlen)
1740     log_debug ("length mismatch: %lu, %lu\n",
1741                (unsigned long)needed, (unsigned long)certseqlen);
1742   
1743   /* Append some pad characters; we already allocated extra space. */
1744   n = 8 - certseqlen % 8;
1745   for (i=0; i < n; i++, certseqlen++)
1746     *p++ = n;
1747   
1748   *r_length = certseqlen;
1749   return certseq;
1750 }
1751
1752
1753 /* Expect the RSA key parameters in KPARMS and a password in
1754    PW. Create a PKCS structure from it and return it as well as the
1755    length in R_LENGTH; return NULL in case of an error. */
1756 unsigned char * 
1757 p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen,
1758            const char *pw, size_t *r_length)
1759 {
1760   unsigned char *buffer;
1761   size_t n, buflen;
1762   char salt[8];
1763   struct buffer_s seqlist[3];
1764   int seqlistidx = 0;
1765
1766   n = buflen = 0; /* (avoid compiler warning). */
1767
1768   if (cert && certlen)
1769     {
1770       /* Encode the certificate. */
1771       buffer = build_cert_sequence (cert, certlen, &buflen);
1772       if (!buffer)
1773         goto failure;
1774
1775       /* Encrypt it. */
1776       gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
1777       crypt_block (buffer, buflen, salt, 8, 2048, pw,
1778                    GCRY_CIPHER_RFC2268_40, 1);
1779       
1780       /* Encode the encrypted stuff into a bag. */
1781       seqlist[seqlistidx].buffer = build_cert_bag (buffer, buflen, salt, &n);
1782       seqlist[seqlistidx].length = n;
1783       gcry_free (buffer);
1784       buffer = NULL;
1785       if (!seqlist[seqlistidx].buffer)
1786         goto failure;
1787       seqlistidx++;
1788     }
1789
1790   if (kparms)
1791     {
1792       /* Encode the key. */
1793       buffer = build_key_sequence (kparms, &buflen);
1794       if (!buffer)
1795         goto failure;
1796       
1797       /* Encrypt it. */
1798       gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
1799       crypt_block (buffer, buflen, salt, 8, 2048, pw, GCRY_CIPHER_3DES, 1);
1800
1801       /* Encode the encrypted stuff into a bag. */
1802       seqlist[seqlistidx].buffer = build_key_bag (buffer, buflen, salt, &n);
1803       seqlist[seqlistidx].length = n;
1804       gcry_free (buffer);
1805       buffer = NULL;
1806       if (!seqlist[seqlistidx].buffer)
1807         goto failure;
1808       seqlistidx++;
1809     }
1810
1811   seqlist[seqlistidx].buffer = NULL;
1812   seqlist[seqlistidx].length = 0;
1813
1814   buffer = create_final (seqlist, &buflen);
1815
1816  failure:
1817   for ( ; seqlistidx; seqlistidx--)
1818     gcry_free (seqlist[seqlistidx].buffer);
1819
1820   *r_length = buffer? buflen : 0;
1821   return buffer;
1822 }
1823
1824
1825 #ifdef TEST
1826
1827 static void 
1828 cert_cb (void *opaque, const unsigned char *cert, size_t certlen)
1829 {
1830   printf ("got a certificate of %u bytes length\n", certlen);
1831 }
1832
1833 int
1834 main (int argc, char **argv)
1835 {
1836   FILE *fp;
1837   struct stat st;
1838   unsigned char *buf;
1839   size_t buflen;
1840   gcry_mpi_t *result;
1841
1842   if (argc != 3)
1843     {
1844       fprintf (stderr, "usage: testp12 file passphrase\n");
1845       return 1;
1846     }
1847
1848   gcry_control (GCRYCTL_DISABLE_SECMEM, NULL);
1849   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL);
1850
1851   fp = fopen (argv[1], "rb");
1852   if (!fp)
1853     {
1854       fprintf (stderr, "can't open `%s': %s\n", argv[1], strerror (errno));
1855       return 1;
1856     }
1857   
1858   if (fstat (fileno(fp), &st))
1859     {
1860       fprintf (stderr, "can't stat `%s': %s\n", argv[1], strerror (errno));
1861       return 1;
1862     }
1863
1864   buflen = st.st_size;
1865   buf = gcry_malloc (buflen+1);
1866   if (!buf || fread (buf, buflen, 1, fp) != 1)
1867     {
1868       fprintf (stderr, "error reading `%s': %s\n", argv[1], strerror (errno));
1869       return 1;
1870     }
1871   fclose (fp);
1872
1873   result = p12_parse (buf, buflen, argv[2], cert_cb, NULL);
1874   if (result)
1875     {
1876       int i, rc;
1877       unsigned char *tmpbuf;
1878
1879       for (i=0; result[i]; i++)
1880         {
1881           rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &tmpbuf,
1882                                 NULL, result[i]);
1883           if (rc)
1884             printf ("%d: [error printing number: %s]\n",
1885                     i, gpg_strerror (rc));
1886           else
1887             {
1888               printf ("%d: %s\n", i, tmpbuf);
1889               gcry_free (tmpbuf);
1890             }
1891         }
1892     }
1893
1894   return 0;
1895
1896 }
1897
1898 /*
1899 Local Variables:
1900 compile-command: "gcc -Wall -O -g -DTEST=1 -o minip12 minip12.c ../jnlib/libjnlib.a -L /usr/local/lib -lgcrypt -lgpg-error"
1901 End:
1902 */
1903 #endif /* TEST */