b4e836f5b9e00c9d5d2822421f910a24524298ba
[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 bab. */
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   where = "decrypted-text";
749   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
750     goto bailout;
751   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER
752       || ti.length != 1 || *p)
753     goto bailout;
754   p++; n--;
755   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
756     goto bailout;
757   len = ti.length;
758   if (parse_tag (&p, &n, &ti))
759     goto bailout;
760   if (len < ti.nhdr)
761     goto bailout;
762   len -= ti.nhdr;
763   if (ti.class || ti.tag != TAG_OBJECT_ID
764       || ti.length != DIM(oid_rsaEncryption)
765       || memcmp (p, oid_rsaEncryption,
766                  DIM(oid_rsaEncryption)))
767     goto bailout;
768   p += DIM (oid_rsaEncryption);
769   n -= DIM (oid_rsaEncryption);
770   if (len < ti.length)
771     goto bailout;
772   len -= ti.length;
773   if (n < len)
774     goto bailout;
775   p += len;
776   n -= len;
777   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_OCTET_STRING)
778     goto bailout;
779   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
780     goto bailout;
781   len = ti.length;
782
783   result = gcry_calloc (10, sizeof *result);
784   if (!result)
785     {
786       log_error ( "error allocating result array\n");
787       goto bailout;
788     }
789   result_count = 0;
790
791   where = "reading.key-parameters";
792   for (result_count=0; len && result_count < 9;)
793     {
794       if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER)
795         goto bailout;
796       if (len < ti.nhdr)
797         goto bailout;
798       len -= ti.nhdr;
799       if (len < ti.length)
800         goto bailout;
801       len -= ti.length;
802       if (!result_count && ti.length == 1 && !*p)
803         ; /* ignore the very first one if it is a 0 */
804       else 
805         {
806           rc = gcry_mpi_scan (result+result_count, GCRYMPI_FMT_USG, p,
807                               ti.length, NULL);
808           if (rc)
809             {
810               log_error ("error parsing key parameter: %s\n",
811                          gpg_strerror (rc));
812               goto bailout;
813             }
814           result_count++;
815         }
816       p += ti.length;
817       n -= ti.length;
818     }
819   if (len)
820     goto bailout;
821
822   return result;
823
824  bailout:
825   gcry_free (plain);
826   if (result)
827     {
828       for (i=0; result[i]; i++)
829         gcry_mpi_release (result[i]);
830       gcry_free (result);
831     }
832   log_error ( "data error at \"%s\", offset %u\n",
833               where, (p - buffer) + startoffset);
834   return NULL;
835 }
836
837
838 /* Parse a PKCS12 object and return an array of MPI representing the
839    secret key parameters.  This is a very limited implementation in
840    that it is only able to look for 3DES encoded encryptedData and
841    tries to extract the first private key object it finds.  In case of
842    an error NULL is returned. CERTCB and CERRTCBARG are used to pass
843    X.509 certificates back to the caller. */
844 gcry_mpi_t *
845 p12_parse (const unsigned char *buffer, size_t length, const char *pw,
846            void (*certcb)(void*, const unsigned char*, size_t),
847            void *certcbarg)
848 {
849   struct tag_info ti;
850   const unsigned char *p = buffer;
851   size_t n = length;
852   const char *where;
853   int bagseqlength, len;
854
855   where = "pfx";
856   if (parse_tag (&p, &n, &ti))
857     goto bailout;
858   if (ti.tag != TAG_SEQUENCE)
859     goto bailout;
860
861   where = "pfxVersion";
862   if (parse_tag (&p, &n, &ti))
863     goto bailout;
864   if (ti.tag != TAG_INTEGER || ti.length != 1 || *p != 3)
865     goto bailout;
866   p++; n--;
867   
868   where = "authSave";
869   if (parse_tag (&p, &n, &ti))
870     goto bailout;
871   if (ti.tag != TAG_SEQUENCE)
872     goto bailout;
873   if (parse_tag (&p, &n, &ti))
874     goto bailout;
875   if (ti.tag != TAG_OBJECT_ID || ti.length != DIM(oid_data)
876       || memcmp (p, oid_data, DIM(oid_data)))
877     goto bailout;
878   p += DIM(oid_data);
879   n -= DIM(oid_data);
880
881   if (parse_tag (&p, &n, &ti))
882     goto bailout;
883   if (ti.class != CONTEXT || ti.tag)
884     goto bailout;
885   if (parse_tag (&p, &n, &ti))
886     goto bailout;
887   if (ti.class != UNIVERSAL || ti.tag != TAG_OCTET_STRING)
888     goto bailout;
889
890   where = "bags";
891   if (parse_tag (&p, &n, &ti))
892     goto bailout;
893   if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE)
894     goto bailout;
895   bagseqlength = ti.length;
896   while (bagseqlength)
897     {
898       /*log_debug ( "at offset %u\n", (p - buffer));*/
899       where = "bag-sequence";
900       if (parse_tag (&p, &n, &ti))
901         goto bailout;
902       if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE)
903         goto bailout;
904
905       if (bagseqlength < ti.nhdr)
906         goto bailout;
907       bagseqlength -= ti.nhdr;
908       if (bagseqlength < ti.length)
909         goto bailout;
910       bagseqlength -= ti.length;
911       len = ti.length;
912
913       if (parse_tag (&p, &n, &ti))
914         goto bailout;
915       len -= ti.nhdr;
916       if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_encryptedData)
917           && !memcmp (p, oid_encryptedData, DIM(oid_encryptedData)))
918         {
919           p += DIM(oid_encryptedData);
920           n -= DIM(oid_encryptedData);
921           len -= DIM(oid_encryptedData);
922           where = "bag.encryptedData";
923           if (parse_bag_encrypted_data (p, n, (p - buffer), pw,
924                                         certcb, certcbarg))
925             goto bailout;
926         }
927       else if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_data)
928           && !memcmp (p, oid_data, DIM(oid_data)))
929         {
930           p += DIM(oid_data);
931           n -= DIM(oid_data);
932           len -= DIM(oid_data);
933           return parse_bag_data (p, n, (p-buffer), pw);
934         }
935       else
936         log_info ( "unknown bag type - skipped\n");
937
938       if (len < 0 || len > n)
939         goto bailout;
940       p += len;
941       n -= len;
942     }
943   
944   return NULL;
945  bailout:
946   log_error ("error at \"%s\", offset %u\n", where, (p - buffer));
947   return NULL;
948 }
949
950
951 \f
952 static size_t
953 compute_tag_length (size_t n)
954 {     
955   int needed = 0;
956
957   if (n < 128)
958     needed += 2; /* tag and one length byte */
959   else if (n < 256)
960     needed += 3; /* tag, number of length bytes, 1 length byte */
961   else if (n < 65536)
962     needed += 4; /* tag, number of length bytes, 2 length bytes */
963   else
964     {
965       log_error ("object too larger to encode\n");
966       return 0;
967     }
968   return needed;
969 }
970
971 static unsigned char *
972 store_tag_length (unsigned char *p, int tag, size_t n)
973 {     
974   if (tag == TAG_SEQUENCE)
975     tag |= 0x20; /* constructed */
976
977   *p++ = tag;
978   if (n < 128)
979     *p++ = n;
980   else if (n < 256)
981     {
982       *p++ = 0x81;
983       *p++ = n;
984     }
985   else if (n < 65536)
986     {
987       *p++ = 0x82;
988       *p++ = n >> 8;
989       *p++ = n;
990     }
991
992   return p;
993 }
994
995
996 /* Create the final PKCS-12 object from the sequences contained in
997    SEQLIST.  That array is terminated with an NULL object */
998 static unsigned char *
999 create_final (struct buffer_s *sequences, size_t *r_length)
1000 {
1001   int i;
1002   size_t needed = 0;
1003   size_t len[8], n;
1004   unsigned char *result, *p;
1005   size_t resultlen;
1006
1007   /* 8 steps to create the pkcs#12 Krampf. */
1008
1009   /* 7. All the buffers. */
1010   for (i=0; sequences[i].buffer; i++)
1011     needed += sequences[i].length;
1012
1013   /* 6. This goes into a sequences. */
1014   len[6] = needed;
1015   n = compute_tag_length (needed);
1016   needed += n;
1017
1018   /* 5. Encapsulate all in an octet string. */
1019   len[5] = needed;
1020   n = compute_tag_length (needed);
1021   needed += n;
1022
1023   /* 4. And tag it with [0]. */
1024   len[4] = needed;
1025   n = compute_tag_length (needed);
1026   needed += n;
1027
1028   /* 3. Prepend an data OID. */
1029   needed += 2 + DIM (oid_data);
1030
1031   /* 2. Put all into a sequences. */
1032   len[2] = needed;
1033   n = compute_tag_length (needed);
1034   needed += n;
1035
1036   /* 1. Prepend the version integer 3. */
1037   needed += 3;
1038
1039   /* 0. And the final outer sequence. */
1040   len[0] = needed;
1041   n = compute_tag_length (needed);
1042   needed += n;
1043
1044   /* Allocate a buffer. */
1045   result = gcry_malloc (needed);
1046   if (!result)
1047     {
1048       log_error ("error allocating buffer\n");
1049       return NULL;
1050     }
1051   p = result;
1052
1053   /* 0. Store the very outer sequence. */
1054   p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1055
1056   /* 1. Store the version integer 3. */
1057   *p++ = TAG_INTEGER;
1058   *p++ = 1; 
1059   *p++ = 3;
1060  
1061   /* 2. Store another sequence. */
1062   p = store_tag_length (p, TAG_SEQUENCE, len[2]);
1063
1064   /* 3. Store the data OID. */
1065   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
1066   memcpy (p, oid_data, DIM (oid_data)); 
1067   p += DIM (oid_data); 
1068
1069   /* 4. Next comes a context tag. */
1070   p = store_tag_length (p, 0xa0, len[4]);
1071
1072   /* 5. And an octet string. */
1073   p = store_tag_length (p, TAG_OCTET_STRING, len[5]);
1074
1075   /* 6. And the inner sequence. */
1076   p = store_tag_length (p, TAG_SEQUENCE, len[6]);
1077
1078   /* 7. Append all the buffers. */
1079   for (i=0; sequences[i].buffer; i++)
1080     {
1081       memcpy (p, sequences[i].buffer, sequences[i].length);
1082       p += sequences[i].length;
1083     }
1084
1085   /* Ready. */
1086   resultlen = p - result;
1087   if (needed != resultlen)
1088     log_debug ("length mismatch: %lu, %lu\n",
1089                (unsigned long)needed, (unsigned long)resultlen);
1090
1091   *r_length = resultlen;
1092   return result;
1093 }
1094
1095
1096 /* Build a DER encoded SEQUENCE with the key:
1097
1098    SEQUENCE {
1099      INTEGER 0
1100      SEQUENCE {
1101        OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
1102        NULL
1103        }
1104      OCTET STRING, encapsulates {
1105        SEQUENCE {
1106          INTEGER 0
1107          INTEGER
1108          INTEGER 
1109          INTEGER
1110          INTEGER
1111          INTEGER
1112          INTEGER
1113          INTEGER
1114          INTEGER
1115          }
1116        }
1117      }
1118 */  
1119   
1120 static unsigned char * 
1121 build_key_sequence (gcry_mpi_t *kparms, size_t *r_length)
1122 {
1123   int rc, i;
1124   size_t needed, n;
1125   unsigned char *plain, *p;
1126   size_t plainlen;
1127   size_t outseqlen, oidseqlen, octstrlen, inseqlen;
1128
1129   needed = 3; /* The version(?) integer of value 0. */
1130   for (i=0; kparms[i]; i++)
1131     {
1132       n = 0;
1133       rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, kparms[i]);
1134       if (rc)
1135         {
1136           log_error ("error formatting parameter: %s\n", gpg_strerror (rc));
1137           return NULL;
1138         }
1139       needed += n;
1140       n = compute_tag_length (n);
1141       if (!n)
1142         return NULL;
1143       needed += n;
1144     }
1145   if (i != 8)
1146     {
1147       log_error ("invalid paramters for p12_build\n");
1148       return NULL;
1149     }
1150   /* Now this all goes into a sequence. */
1151   inseqlen = needed;
1152   n = compute_tag_length (needed);
1153   if (!n)
1154     return NULL;
1155   needed += n;
1156   /* Encapsulate all into an octet string. */
1157   octstrlen = needed;
1158   n = compute_tag_length (needed);
1159   if (!n)
1160     return NULL;
1161   needed += n;
1162   /* Prepend the object identifier sequence. */
1163   oidseqlen = 2 + DIM (oid_rsaEncryption) + 2;
1164   needed += 2 + oidseqlen;
1165   /* The version number. */
1166   needed += 3;
1167   /* And finally put the whole thing into a sequence. */
1168   outseqlen = needed;
1169   n = compute_tag_length (needed);
1170   if (!n)
1171     return NULL;
1172   needed += n;
1173   
1174   /* allocate 8 extra bytes for padding */
1175   plain = gcry_malloc_secure (needed+8);
1176   if (!plain)
1177     {
1178       log_error ("error allocating encryption buffer\n");
1179       return NULL;
1180     }
1181   
1182   /* And now fill the plaintext buffer. */
1183   p = plain;
1184   p = store_tag_length (p, TAG_SEQUENCE, outseqlen);
1185   /* Store version. */
1186   *p++ = TAG_INTEGER;
1187   *p++ = 1;
1188   *p++ = 0;
1189   /* Store object identifier sequence. */
1190   p = store_tag_length (p, TAG_SEQUENCE, oidseqlen);
1191   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_rsaEncryption));
1192   memcpy (p, oid_rsaEncryption, DIM (oid_rsaEncryption)); 
1193   p += DIM (oid_rsaEncryption); 
1194   *p++ = TAG_NULL;
1195   *p++ = 0;
1196   /* Start with the octet string. */
1197   p = store_tag_length (p, TAG_OCTET_STRING, octstrlen);
1198   p = store_tag_length (p, TAG_SEQUENCE, inseqlen);
1199   /* Store the key parameters. */
1200   *p++ = TAG_INTEGER;
1201   *p++ = 1;
1202   *p++ = 0;
1203   for (i=0; kparms[i]; i++)
1204     {
1205       n = 0;
1206       rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, kparms[i]);
1207       if (rc)
1208         {
1209           log_error ("oops: error formatting parameter: %s\n",
1210                      gpg_strerror (rc));
1211           gcry_free (plain);
1212           return NULL;
1213         }
1214       p = store_tag_length (p, TAG_INTEGER, n);
1215       
1216       n = plain + needed - p;
1217       rc = gcry_mpi_print (GCRYMPI_FMT_STD, p, n, &n, kparms[i]);
1218       if (rc)
1219         {
1220           log_error ("oops: error storing parameter: %s\n",
1221                      gpg_strerror (rc));
1222           gcry_free (plain);
1223           return NULL;
1224         }
1225       p += n;
1226     }
1227
1228   plainlen = p - plain;
1229   assert (needed == plainlen);
1230   /* Append some pad characters; we already allocated extra space. */
1231   n = 8 - plainlen % 8;
1232   for (;(plainlen % 8); plainlen++)
1233     *p++ = n;
1234
1235   *r_length = plainlen;
1236   return plain;
1237 }
1238
1239
1240
1241 static unsigned char *
1242 build_key_bag (unsigned char *buffer, size_t buflen, char *salt,
1243                size_t *r_length)
1244 {
1245   size_t len[11], needed;
1246   unsigned char *p, *keybag;
1247   size_t keybaglen;
1248
1249   /* Walk 11 steps down to collect the info: */
1250
1251   /* 10. The data goes into an octet string. */
1252   needed = compute_tag_length (buflen);
1253   needed += buflen;
1254
1255   /* 9. Prepend the algorithm identifier. */
1256   needed += DIM (data_3desiter2048);
1257
1258   /* 8. Put a sequence around. */
1259   len[8] = needed;
1260   needed += compute_tag_length (needed);
1261
1262   /* 7. Prepend a [0] tag. */
1263   len[7] = needed;
1264   needed += compute_tag_length (needed);
1265
1266   /* 6. Prepend the shroudedKeyBag OID. */
1267   needed += 2 + DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag);
1268
1269   /* 5+4. Put all into two sequences. */
1270   len[5] = needed;
1271   needed += compute_tag_length ( needed);
1272   len[4] = needed;
1273   needed += compute_tag_length (needed);
1274
1275   /* 3. This all goes into an octet string. */
1276   len[3] = needed;
1277   needed += compute_tag_length (needed);
1278
1279   /* 2. Prepend another [0] tag. */
1280   len[2] = needed;
1281   needed += compute_tag_length (needed);
1282
1283   /* 1. Prepend the data OID. */
1284   needed += 2 + DIM (oid_data);
1285
1286   /* 0. Prepend another sequence. */
1287   len[0] = needed;
1288   needed += compute_tag_length (needed);
1289
1290   /* Now that we have all length information, allocate a buffer. */
1291   p = keybag = gcry_malloc (needed);
1292   if (!keybag)
1293     {
1294       log_error ("error allocating buffer\n");
1295       return NULL;
1296     }
1297
1298   /* Walk 11 steps up to store the data. */
1299
1300   /* 0. Store the first sequence. */
1301   p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1302
1303   /* 1. Store the data OID. */
1304   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
1305   memcpy (p, oid_data, DIM (oid_data)); 
1306   p += DIM (oid_data); 
1307
1308   /* 2. Store a [0] tag. */
1309   p = store_tag_length (p, 0xa0, len[2]);
1310
1311   /* 3. And an octet string. */
1312   p = store_tag_length (p, TAG_OCTET_STRING, len[3]);
1313
1314   /* 4+5. Two sequences. */
1315   p = store_tag_length (p, TAG_SEQUENCE, len[4]);
1316   p = store_tag_length (p, TAG_SEQUENCE, len[5]);
1317
1318   /* 6. Store the shroudedKeyBag OID. */
1319   p = store_tag_length (p, TAG_OBJECT_ID,
1320                         DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag));
1321   memcpy (p, oid_pkcs_12_pkcs_8ShroudedKeyBag,
1322           DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag)); 
1323   p += DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag); 
1324
1325   /* 7. Store a [0] tag. */
1326   p = store_tag_length (p, 0xa0, len[7]);
1327
1328   /* 8. Store a sequence. */
1329   p = store_tag_length (p, TAG_SEQUENCE, len[8]);
1330
1331   /* 9. Now for the pre-encoded algorithm identifier and the salt. */
1332   memcpy (p, data_3desiter2048, DIM (data_3desiter2048));
1333   memcpy (p + DATA_3DESITER2048_SALT_OFF, salt, 8);
1334   p += DIM (data_3desiter2048);
1335
1336   /* 10. And finally the octet string with the encrypted data. */
1337   p = store_tag_length (p, TAG_OCTET_STRING, buflen);
1338   memcpy (p, buffer, buflen);
1339   p += buflen;
1340   keybaglen = p - keybag;
1341   
1342   if (needed != keybaglen)
1343     log_debug ("length mismatch: %lu, %lu\n",
1344                (unsigned long)needed, (unsigned long)keybaglen);
1345   
1346   *r_length = keybaglen;
1347   return keybag;
1348 }
1349
1350
1351 static unsigned char *
1352 build_cert_bag (unsigned char *buffer, size_t buflen, char *salt,
1353                 size_t *r_length)
1354 {
1355   size_t len[9], needed;
1356   unsigned char *p, *certbag;
1357   size_t certbaglen;
1358
1359   /* Walk 9 steps down to collect the info: */
1360
1361   /* 8. The data goes into an octet string. */
1362   needed = compute_tag_length (buflen);
1363   needed += buflen;
1364
1365   /* 7. The algorithm identifier. */
1366   needed += DIM (data_rc2iter2048);
1367
1368   /* 6. The data OID. */
1369   needed += 2 + DIM (oid_data);
1370
1371   /* 5. A sequence. */
1372   len[5] = needed;
1373   needed += compute_tag_length ( needed);
1374
1375   /* 4. An integer. */
1376   needed += 3;
1377
1378   /* 3. A sequence. */
1379   len[3] = needed;
1380   needed += compute_tag_length (needed);
1381
1382   /* 2.  A [0] tag. */
1383   len[2] = needed;
1384   needed += compute_tag_length (needed);
1385
1386   /* 1. The encryptedData OID. */
1387   needed += 2 + DIM (oid_encryptedData);
1388
1389   /* 0. The first sequence. */
1390   len[0] = needed;
1391   needed += compute_tag_length (needed);
1392
1393   /* Now that we have all length information, allocate a buffer. */
1394   p = certbag = gcry_malloc (needed);
1395   if (!certbag)
1396     {
1397       log_error ("error allocating buffer\n");
1398       return NULL;
1399     }
1400
1401   /* Walk 9 steps up to store the data. */
1402
1403   /* 0. Store the first sequence. */
1404   p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1405
1406   /* 1. Store the encryptedData OID. */
1407   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_encryptedData));
1408   memcpy (p, oid_encryptedData, DIM (oid_encryptedData)); 
1409   p += DIM (oid_encryptedData); 
1410
1411   /* 2. Store a [0] tag. */
1412   p = store_tag_length (p, 0xa0, len[2]);
1413
1414   /* 3. Store a sequence. */
1415   p = store_tag_length (p, TAG_SEQUENCE, len[3]);
1416
1417   /* 4. Store the integer 0. */
1418   *p++ = TAG_INTEGER;
1419   *p++ = 1; 
1420   *p++ = 0;
1421
1422   /* 5. Store a sequence. */
1423   p = store_tag_length (p, TAG_SEQUENCE, len[5]);
1424
1425   /* 6. Store the data OID. */
1426   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
1427   memcpy (p, oid_data, DIM (oid_data)); 
1428   p += DIM (oid_data); 
1429
1430   /* 7. Now for the pre-encoded algorithm identifier and the salt. */
1431   memcpy (p, data_rc2iter2048, DIM (data_rc2iter2048));
1432   memcpy (p + DATA_RC2ITER2048_SALT_OFF, salt, 8);
1433   p += DIM (data_rc2iter2048);
1434
1435   /* 8. And finally the [0] tag with the encrypted data. */
1436   p = store_tag_length (p, 0x80, buflen);
1437   memcpy (p, buffer, buflen);
1438   p += buflen;
1439   certbaglen = p - certbag;
1440   
1441   if (needed != certbaglen)
1442     log_debug ("length mismatch: %lu, %lu\n",
1443                (unsigned long)needed, (unsigned long)certbaglen);
1444
1445   *r_length = certbaglen;
1446   return certbag;
1447 }
1448
1449
1450 static unsigned char *
1451 build_cert_sequence (unsigned char *buffer, size_t buflen, size_t *r_length)
1452 {
1453   size_t len[8], needed, n;
1454   unsigned char *p, *certseq;
1455   size_t certseqlen;
1456
1457   /* Walk 8 steps down to collect the info: */
1458
1459   /* 7. The data goes into an octet string. */
1460   needed = compute_tag_length (buflen);
1461   needed += buflen;
1462
1463   /* 6. A [0] tag. */
1464   len[6] = needed;
1465   needed += compute_tag_length (needed);
1466
1467   /* 5. An OID. */
1468   needed += 2 + DIM (oid_x509Certificate_for_pkcs_12);
1469
1470   /* 4. A sequence. */
1471   len[4] = needed;
1472   needed += compute_tag_length (needed);
1473
1474   /* 3. A [0] tag. */
1475   len[3] = needed;
1476   needed += compute_tag_length (needed);
1477
1478   /* 2. An OID. */
1479   needed += 2 + DIM (oid_pkcs_12_CertBag);
1480
1481   /* 1. A sequence. */
1482   len[1] = needed;
1483   needed += compute_tag_length (needed);
1484
1485   /* 0. The first sequence. */
1486   len[0] = needed;
1487   needed += compute_tag_length (needed);
1488
1489   /* Now that we have all length information, allocate a buffer. */
1490   p = certseq = gcry_malloc (needed + 8 /*(for padding)*/);
1491   if (!certseq)
1492     {
1493       log_error ("error allocating buffer\n");
1494       return NULL;
1495     }
1496
1497   /* Walk 8 steps up to store the data. */
1498
1499   /* 0. Store the first sequence. */
1500   p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1501
1502   /* 1. Store the second sequence. */
1503   p = store_tag_length (p, TAG_SEQUENCE, len[1]);
1504
1505   /* 2. Store the pkcs12-cert-bag OID. */
1506   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_pkcs_12_CertBag));
1507   memcpy (p, oid_pkcs_12_CertBag, DIM (oid_pkcs_12_CertBag)); 
1508   p += DIM (oid_pkcs_12_CertBag); 
1509
1510   /* 3. Store a [0] tag. */
1511   p = store_tag_length (p, 0xa0, len[3]);
1512
1513   /* 4. Store a sequence. */
1514   p = store_tag_length (p, TAG_SEQUENCE, len[4]);
1515
1516   /* 5. Store the x509Certificate OID. */
1517   p = store_tag_length (p, TAG_OBJECT_ID,
1518                         DIM (oid_x509Certificate_for_pkcs_12));
1519   memcpy (p, oid_x509Certificate_for_pkcs_12,
1520           DIM (oid_x509Certificate_for_pkcs_12)); 
1521   p += DIM (oid_x509Certificate_for_pkcs_12); 
1522
1523   /* 6. Store a [0] tag. */
1524   p = store_tag_length (p, 0xa0, len[6]);
1525
1526   /* 7. And finally the octet string with the actual certificate. */
1527   p = store_tag_length (p, TAG_OCTET_STRING, buflen);
1528   memcpy (p, buffer, buflen);
1529   p += buflen;
1530   certseqlen = p - certseq;
1531   
1532   if (needed != certseqlen)
1533     log_debug ("length mismatch: %lu, %lu\n",
1534                (unsigned long)needed, (unsigned long)certseqlen);
1535   
1536   /* Append some pad characters; we already allocated extra space. */
1537   n = 8 - certseqlen % 8;
1538   for (;(certseqlen % 8); certseqlen++)
1539     *p++ = n;
1540   
1541   *r_length = certseqlen;
1542   return certseq;
1543 }
1544
1545
1546 /* Expect the RSA key parameters in KPARMS and a password in
1547    PW. Create a PKCS structure from it and return it as well as the
1548    length in R_LENGTH; return NULL in case of an error. */
1549 unsigned char * 
1550 p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen,
1551            const char *pw, size_t *r_length)
1552 {
1553   unsigned char *buffer;
1554   size_t n, buflen;
1555   char salt[8];
1556   struct buffer_s seqlist[3];
1557   int seqlistidx = 0;
1558
1559   n = buflen = 0; /* (avoid compiler warning). */
1560
1561   if (cert && certlen)
1562     {
1563       /* Encode the certificate. */
1564       buffer = build_cert_sequence (cert, certlen, &buflen);
1565       if (!buffer)
1566         goto failure;
1567
1568       /* Encrypt it. */
1569       gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
1570       crypt_block (buffer, buflen, salt, 2048, pw, GCRY_CIPHER_RFC2268_40, 1);
1571       
1572       /* Encode the encrypted stuff into a bag. */
1573       seqlist[seqlistidx].buffer = build_cert_bag (buffer, buflen, salt, &n);
1574       seqlist[seqlistidx].length = n;
1575       gcry_free (buffer);
1576       buffer = NULL;
1577       if (!seqlist[seqlistidx].buffer)
1578         goto failure;
1579       seqlistidx++;
1580     }
1581
1582   if (kparms)
1583     {
1584       /* Encode the key. */
1585       buffer = build_key_sequence (kparms, &buflen);
1586       if (!buffer)
1587         goto failure;
1588       
1589       /* Encrypt it. */
1590       gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
1591       crypt_block (buffer, buflen, salt, 2048, pw, GCRY_CIPHER_3DES, 1);
1592
1593       /* Encode the encrypted stuff into a bag. */
1594       seqlist[seqlistidx].buffer = build_key_bag (buffer, buflen, salt, &n);
1595       seqlist[seqlistidx].length = n;
1596       gcry_free (buffer);
1597       buffer = NULL;
1598       if (!seqlist[seqlistidx].buffer)
1599         goto failure;
1600       seqlistidx++;
1601     }
1602
1603   seqlist[seqlistidx].buffer = NULL;
1604   seqlist[seqlistidx].length = 0;
1605
1606   buffer = create_final (seqlist, &buflen);
1607
1608  failure:
1609   for ( ; seqlistidx; seqlistidx--)
1610     gcry_free (seqlist[seqlistidx].buffer);
1611
1612   *r_length = buffer? buflen : 0;
1613   return buffer;
1614 }
1615
1616
1617 #ifdef TEST
1618
1619 static void 
1620 cert_cb (void *opaque, const unsigned char *cert, size_t certlen)
1621 {
1622   printf ("got a certificate of %u bytes length\n", certlen);
1623 }
1624
1625 int
1626 main (int argc, char **argv)
1627 {
1628   FILE *fp;
1629   struct stat st;
1630   unsigned char *buf;
1631   size_t buflen;
1632   gcry_mpi_t *result;
1633
1634   if (argc != 3)
1635     {
1636       fprintf (stderr, "usage: testp12 file passphrase\n");
1637       return 1;
1638     }
1639
1640   gcry_control (GCRYCTL_DISABLE_SECMEM, NULL);
1641   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL);
1642
1643   fp = fopen (argv[1], "rb");
1644   if (!fp)
1645     {
1646       fprintf (stderr, "can't open `%s': %s\n", argv[1], strerror (errno));
1647       return 1;
1648     }
1649   
1650   if (fstat (fileno(fp), &st))
1651     {
1652       fprintf (stderr, "can't stat `%s': %s\n", argv[1], strerror (errno));
1653       return 1;
1654     }
1655
1656   buflen = st.st_size;
1657   buf = gcry_malloc (buflen+1);
1658   if (!buf || fread (buf, buflen, 1, fp) != 1)
1659     {
1660       fprintf (stderr, "error reading `%s': %s\n", argv[1], strerror (errno));
1661       return 1;
1662     }
1663   fclose (fp);
1664
1665   result = p12_parse (buf, buflen, argv[2], cert_cb, NULL);
1666   if (result)
1667     {
1668       int i, rc;
1669       unsigned char *tmpbuf;
1670
1671       for (i=0; result[i]; i++)
1672         {
1673           rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &tmpbuf,
1674                                 NULL, result[i]);
1675           if (rc)
1676             printf ("%d: [error printing number: %s]\n",
1677                     i, gpg_strerror (rc));
1678           else
1679             {
1680               printf ("%d: %s\n", i, tmpbuf);
1681               gcry_free (tmpbuf);
1682             }
1683         }
1684     }
1685
1686   return 0;
1687
1688 }
1689
1690 /*
1691 Local Variables:
1692 compile-command: "gcc -Wall -O -g -DTEST=1 -o minip12 minip12.c ../jnlib/libjnlib.a -L /usr/local/lib -lgcrypt -lgpg-error"
1693 End:
1694 */
1695 #endif /* TEST */