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