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