5ca85033d761481710e25adf091578968624d590
[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: %u, %u\n", needed, resultlen);
1089
1090   *r_length = resultlen;
1091   return result;
1092 }
1093
1094
1095 /* Build a DER encoded SEQUENCE with the key:
1096
1097    SEQUENCE {
1098      INTEGER 0
1099      SEQUENCE {
1100        OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
1101        NULL
1102        }
1103      OCTET STRING, encapsulates {
1104        SEQUENCE {
1105          INTEGER 0
1106          INTEGER
1107          INTEGER 
1108          INTEGER
1109          INTEGER
1110          INTEGER
1111          INTEGER
1112          INTEGER
1113          INTEGER
1114          }
1115        }
1116      }
1117 */  
1118   
1119 static unsigned char * 
1120 build_key_sequence (gcry_mpi_t *kparms, size_t *r_length)
1121 {
1122   int rc, i;
1123   size_t needed, n;
1124   unsigned char *plain, *p;
1125   size_t plainlen;
1126   size_t outseqlen, oidseqlen, octstrlen, inseqlen;
1127
1128   needed = 3; /* The version(?) integer of value 0. */
1129   for (i=0; kparms[i]; i++)
1130     {
1131       n = 0;
1132       rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, kparms[i]);
1133       if (rc)
1134         {
1135           log_error ("error formatting parameter: %s\n", gpg_strerror (rc));
1136           return NULL;
1137         }
1138       needed += n;
1139       n = compute_tag_length (n);
1140       if (!n)
1141         return NULL;
1142       needed += n;
1143     }
1144   if (i != 8)
1145     {
1146       log_error ("invalid paramters for p12_build\n");
1147       return NULL;
1148     }
1149   /* Now this all goes into a sequence. */
1150   inseqlen = needed;
1151   n = compute_tag_length (needed);
1152   if (!n)
1153     return NULL;
1154   needed += n;
1155   /* Encapsulate all into an octet string. */
1156   octstrlen = needed;
1157   n = compute_tag_length (needed);
1158   if (!n)
1159     return NULL;
1160   needed += n;
1161   /* Prepend the object identifier sequence. */
1162   oidseqlen = 2 + DIM (oid_rsaEncryption) + 2;
1163   needed += 2 + oidseqlen;
1164   /* The version number. */
1165   needed += 3;
1166   /* And finally put the whole thing into a sequence. */
1167   outseqlen = needed;
1168   n = compute_tag_length (needed);
1169   if (!n)
1170     return NULL;
1171   needed += n;
1172   
1173   /* allocate 8 extra bytes for padding */
1174   plain = gcry_malloc_secure (needed+8);
1175   if (!plain)
1176     {
1177       log_error ("error allocating encryption buffer\n");
1178       return NULL;
1179     }
1180   
1181   /* And now fill the plaintext buffer. */
1182   p = plain;
1183   p = store_tag_length (p, TAG_SEQUENCE, outseqlen);
1184   /* Store version. */
1185   *p++ = TAG_INTEGER;
1186   *p++ = 1;
1187   *p++ = 0;
1188   /* Store object identifier sequence. */
1189   p = store_tag_length (p, TAG_SEQUENCE, oidseqlen);
1190   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_rsaEncryption));
1191   memcpy (p, oid_rsaEncryption, DIM (oid_rsaEncryption)); 
1192   p += DIM (oid_rsaEncryption); 
1193   *p++ = TAG_NULL;
1194   *p++ = 0;
1195   /* Start with the octet string. */
1196   p = store_tag_length (p, TAG_OCTET_STRING, octstrlen);
1197   p = store_tag_length (p, TAG_SEQUENCE, inseqlen);
1198   /* Store the key parameters. */
1199   *p++ = TAG_INTEGER;
1200   *p++ = 1;
1201   *p++ = 0;
1202   for (i=0; kparms[i]; i++)
1203     {
1204       n = 0;
1205       rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, kparms[i]);
1206       if (rc)
1207         {
1208           log_error ("oops: error formatting parameter: %s\n",
1209                      gpg_strerror (rc));
1210           gcry_free (plain);
1211           return NULL;
1212         }
1213       p = store_tag_length (p, TAG_INTEGER, n);
1214       
1215       n = plain + needed - p;
1216       rc = gcry_mpi_print (GCRYMPI_FMT_STD, p, n, &n, kparms[i]);
1217       if (rc)
1218         {
1219           log_error ("oops: error storing parameter: %s\n",
1220                      gpg_strerror (rc));
1221           gcry_free (plain);
1222           return NULL;
1223         }
1224       p += n;
1225     }
1226
1227   plainlen = p - plain;
1228   assert (needed == plainlen);
1229   /* Append some pad characters; we already allocated extra space. */
1230   n = 8 - plainlen % 8;
1231   for (;(plainlen % 8); plainlen++)
1232     *p++ = n;
1233
1234   *r_length = plainlen;
1235   return plain;
1236 }
1237
1238
1239
1240 static unsigned char *
1241 build_key_bag (unsigned char *buffer, size_t buflen, char *salt,
1242                size_t *r_length)
1243 {
1244   size_t len[11], needed;
1245   unsigned char *p, *keybag;
1246   size_t keybaglen;
1247
1248   /* Walk 11 steps down to collect the info: */
1249
1250   /* 10. The data goes into an octet string. */
1251   needed = compute_tag_length (buflen);
1252   needed += buflen;
1253
1254   /* 9. Prepend the algorithm identifier. */
1255   needed += DIM (data_3desiter2048);
1256
1257   /* 8. Put a sequence around. */
1258   len[8] = needed;
1259   needed += compute_tag_length (needed);
1260
1261   /* 7. Prepend a [0] tag. */
1262   len[7] = needed;
1263   needed += compute_tag_length (needed);
1264
1265   /* 6. Prepend the shroudedKeyBag OID. */
1266   needed += 2 + DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag);
1267
1268   /* 5+4. Put all into two sequences. */
1269   len[5] = needed;
1270   needed += compute_tag_length ( needed);
1271   len[4] = needed;
1272   needed += compute_tag_length (needed);
1273
1274   /* 3. This all goes into an octet string. */
1275   len[3] = needed;
1276   needed += compute_tag_length (needed);
1277
1278   /* 2. Prepend another [0] tag. */
1279   len[2] = needed;
1280   needed += compute_tag_length (needed);
1281
1282   /* 1. Prepend the data OID. */
1283   needed += 2 + DIM (oid_data);
1284
1285   /* 0. Prepend another sequence. */
1286   len[0] = needed;
1287   needed += compute_tag_length (needed);
1288
1289   /* Now that we have all length information, allocate a buffer. */
1290   p = keybag = gcry_malloc (needed);
1291   if (!keybag)
1292     {
1293       log_error ("error allocating buffer\n");
1294       return NULL;
1295     }
1296
1297   /* Walk 11 steps up to store the data. */
1298
1299   /* 0. Store the first sequence. */
1300   p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1301
1302   /* 1. Store the data OID. */
1303   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
1304   memcpy (p, oid_data, DIM (oid_data)); 
1305   p += DIM (oid_data); 
1306
1307   /* 2. Store a [0] tag. */
1308   p = store_tag_length (p, 0xa0, len[2]);
1309
1310   /* 3. And an octet string. */
1311   p = store_tag_length (p, TAG_OCTET_STRING, len[3]);
1312
1313   /* 4+5. Two sequences. */
1314   p = store_tag_length (p, TAG_SEQUENCE, len[4]);
1315   p = store_tag_length (p, TAG_SEQUENCE, len[5]);
1316
1317   /* 6. Store the shroudedKeyBag OID. */
1318   p = store_tag_length (p, TAG_OBJECT_ID,
1319                         DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag));
1320   memcpy (p, oid_pkcs_12_pkcs_8ShroudedKeyBag,
1321           DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag)); 
1322   p += DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag); 
1323
1324   /* 7. Store a [0] tag. */
1325   p = store_tag_length (p, 0xa0, len[7]);
1326
1327   /* 8. Store a sequence. */
1328   p = store_tag_length (p, TAG_SEQUENCE, len[8]);
1329
1330   /* 9. Now for the pre-encoded algorithm identifier and the salt. */
1331   memcpy (p, data_3desiter2048, DIM (data_3desiter2048));
1332   memcpy (p + DATA_3DESITER2048_SALT_OFF, salt, 8);
1333   p += DIM (data_3desiter2048);
1334
1335   /* 10. And finally the octet string with the encrypted data. */
1336   p = store_tag_length (p, TAG_OCTET_STRING, buflen);
1337   memcpy (p, buffer, buflen);
1338   p += buflen;
1339   keybaglen = p - keybag;
1340   
1341   if (needed != keybaglen)
1342     log_debug ("length mismatch: %u, %u\n", needed, keybaglen);
1343   
1344   *r_length = keybaglen;
1345   return keybag;
1346 }
1347
1348
1349 static unsigned char *
1350 build_cert_bag (unsigned char *buffer, size_t buflen, char *salt,
1351                 size_t *r_length)
1352 {
1353   size_t len[9], needed;
1354   unsigned char *p, *certbag;
1355   size_t certbaglen;
1356
1357   /* Walk 9 steps down to collect the info: */
1358
1359   /* 8. The data goes into an octet string. */
1360   needed = compute_tag_length (buflen);
1361   needed += buflen;
1362
1363   /* 7. The algorithm identifier. */
1364   needed += DIM (data_rc2iter2048);
1365
1366   /* 6. The data OID. */
1367   needed += 2 + DIM (oid_data);
1368
1369   /* 5. A sequence. */
1370   len[5] = needed;
1371   needed += compute_tag_length ( needed);
1372
1373   /* 4. An integer. */
1374   needed += 3;
1375
1376   /* 3. A sequence. */
1377   len[3] = needed;
1378   needed += compute_tag_length (needed);
1379
1380   /* 2.  A [0] tag. */
1381   len[2] = needed;
1382   needed += compute_tag_length (needed);
1383
1384   /* 1. The encryptedData OID. */
1385   needed += 2 + DIM (oid_encryptedData);
1386
1387   /* 0. The first sequence. */
1388   len[0] = needed;
1389   needed += compute_tag_length (needed);
1390
1391   /* Now that we have all length information, allocate a buffer. */
1392   p = certbag = gcry_malloc (needed);
1393   if (!certbag)
1394     {
1395       log_error ("error allocating buffer\n");
1396       return NULL;
1397     }
1398
1399   /* Walk 9 steps up to store the data. */
1400
1401   /* 0. Store the first sequence. */
1402   p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1403
1404   /* 1. Store the encryptedData OID. */
1405   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_encryptedData));
1406   memcpy (p, oid_encryptedData, DIM (oid_encryptedData)); 
1407   p += DIM (oid_encryptedData); 
1408
1409   /* 2. Store a [0] tag. */
1410   p = store_tag_length (p, 0xa0, len[2]);
1411
1412   /* 3. Store a sequence. */
1413   p = store_tag_length (p, TAG_SEQUENCE, len[3]);
1414
1415   /* 4. Store the integer 0. */
1416   *p++ = TAG_INTEGER;
1417   *p++ = 1; 
1418   *p++ = 0;
1419
1420   /* 5. Store a sequence. */
1421   p = store_tag_length (p, TAG_SEQUENCE, len[5]);
1422
1423   /* 6. Store the data OID. */
1424   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
1425   memcpy (p, oid_data, DIM (oid_data)); 
1426   p += DIM (oid_data); 
1427
1428   /* 7. Now for the pre-encoded algorithm identifier and the salt. */
1429   memcpy (p, data_rc2iter2048, DIM (data_rc2iter2048));
1430   memcpy (p + DATA_RC2ITER2048_SALT_OFF, salt, 8);
1431   p += DIM (data_rc2iter2048);
1432
1433   /* 8. And finally the [0] tag with the encrypted data. */
1434   p = store_tag_length (p, 0xa0, buflen);
1435   memcpy (p, buffer, buflen);
1436   p += buflen;
1437   certbaglen = p - certbag;
1438   
1439   if (needed != certbaglen)
1440     log_debug ("length mismatch: %u, %u\n", needed, certbaglen);
1441
1442   *r_length = certbaglen;
1443   return certbag;
1444 }
1445
1446
1447 static unsigned char *
1448 build_cert_sequence (unsigned char *buffer, size_t buflen, size_t *r_length)
1449 {
1450   size_t len[8], needed, n;
1451   unsigned char *p, *certseq;
1452   size_t certseqlen;
1453
1454   /* Walk 8 steps down to collect the info: */
1455
1456   /* 7. The data goes into an octet string. */
1457   needed = compute_tag_length (buflen);
1458   needed += buflen;
1459
1460   /* 6. A [0] tag. */
1461   len[6] = needed;
1462   needed += compute_tag_length (needed);
1463
1464   /* 5. An OID. */
1465   needed += 2 + DIM (oid_x509Certificate_for_pkcs_12);
1466
1467   /* 4. A sequence. */
1468   len[4] = needed;
1469   needed += compute_tag_length (needed);
1470
1471   /* 3. A [0] tag. */
1472   len[3] = needed;
1473   needed += compute_tag_length (needed);
1474
1475   /* 2. An OID. */
1476   needed += 2 + DIM (oid_pkcs_12_CertBag);
1477
1478   /* 1. A sequence. */
1479   len[1] = needed;
1480   needed += compute_tag_length (needed);
1481
1482   /* 0. The first sequence. */
1483   len[0] = needed;
1484   needed += compute_tag_length (needed);
1485
1486   /* Now that we have all length information, allocate a buffer. */
1487   p = certseq = gcry_malloc (needed + 8 /*(for padding)*/);
1488   if (!certseq)
1489     {
1490       log_error ("error allocating buffer\n");
1491       return NULL;
1492     }
1493
1494   /* Walk 8 steps up to store the data. */
1495
1496   /* 0. Store the first sequence. */
1497   p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1498
1499   /* 1. Store the second sequence. */
1500   p = store_tag_length (p, TAG_SEQUENCE, len[1]);
1501
1502   /* 2. Store the pkcs12-cert-bag OID. */
1503   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_pkcs_12_CertBag));
1504   memcpy (p, oid_pkcs_12_CertBag, DIM (oid_pkcs_12_CertBag)); 
1505   p += DIM (oid_pkcs_12_CertBag); 
1506
1507   /* 3. Store a [0] tag. */
1508   p = store_tag_length (p, 0xa0, len[3]);
1509
1510   /* 4. Store a sequence. */
1511   p = store_tag_length (p, TAG_SEQUENCE, len[4]);
1512
1513   /* 5. Store the x509Certificate OID. */
1514   p = store_tag_length (p, TAG_OBJECT_ID,
1515                         DIM (oid_x509Certificate_for_pkcs_12));
1516   memcpy (p, oid_x509Certificate_for_pkcs_12,
1517           DIM (oid_x509Certificate_for_pkcs_12)); 
1518   p += DIM (oid_x509Certificate_for_pkcs_12); 
1519
1520   /* 6. Store a [0] tag. */
1521   p = store_tag_length (p, 0xa0, len[6]);
1522
1523   /* 7. And finally the octet string with the actual certificate. */
1524   p = store_tag_length (p, TAG_OCTET_STRING, buflen);
1525   memcpy (p, buffer, buflen);
1526   p += buflen;
1527   certseqlen = p - certseq;
1528   
1529   if (needed != certseqlen)
1530     log_debug ("length mismatch: %u, %u\n", needed, certseqlen);
1531   
1532   /* Append some pad characters; we already allocated extra space. */
1533   n = 8 - certseqlen % 8;
1534   for (;(certseqlen % 8); certseqlen++)
1535     *p++ = n;
1536   
1537   *r_length = certseqlen;
1538   return certseq;
1539 }
1540
1541
1542 /* Expect the RSA key parameters in KPARMS and a password in
1543    PW. Create a PKCS structure from it and return it as well as the
1544    length in R_LENGTH; return NULL in case of an error. */
1545 unsigned char * 
1546 p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen,
1547            const char *pw, size_t *r_length)
1548 {
1549   unsigned char *buffer;
1550   size_t n, buflen;
1551   char salt[8];
1552   struct buffer_s seqlist[2];
1553   int seqlistidx = 0;
1554
1555   if (cert && certlen)
1556     {
1557       /* Encode the certificate. */
1558       buffer = build_cert_sequence (cert, certlen, &buflen);
1559       if (!buffer)
1560         goto failure;
1561
1562       /* Encrypt it. */
1563       gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
1564       crypt_block (buffer, buflen, salt, 2048, pw, GCRY_CIPHER_RFC2268_40, 1);
1565       
1566       /* Encode the encrypted stuff into a bag. */
1567       seqlist[seqlistidx].buffer = build_cert_bag (buffer, buflen, salt, &n);
1568       seqlist[seqlistidx].length = n;
1569       gcry_free (buffer);
1570       buffer = NULL;
1571       if (!seqlist[seqlistidx].buffer)
1572         goto failure;
1573       seqlistidx++;
1574     }
1575
1576   if (kparms)
1577     {
1578       /* Encode the key. */
1579       buffer = build_key_sequence (kparms, &buflen);
1580       if (!buffer)
1581         goto failure;
1582       
1583       /* Encrypt it. */
1584       gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
1585       crypt_block (buffer, buflen, salt, 2048, pw, GCRY_CIPHER_3DES, 1);
1586
1587       /* Encode the encrypted stuff into a bag. */
1588       seqlist[seqlistidx].buffer = build_key_bag (buffer, buflen, salt, &n);
1589       seqlist[seqlistidx].length = n;
1590       gcry_free (buffer);
1591       buffer = NULL;
1592       if (!seqlist[seqlistidx].buffer)
1593         goto failure;
1594       seqlistidx++;
1595     }
1596
1597   seqlist[seqlistidx].buffer = NULL;
1598   seqlist[seqlistidx].length = 0;
1599
1600   buffer = create_final (seqlist, &buflen);
1601
1602  failure:
1603   for ( ; seqlistidx; seqlistidx--)
1604     gcry_free (seqlist[seqlistidx].buffer);
1605
1606   *r_length = buffer? buflen : 0;
1607   return buffer;
1608 }
1609
1610
1611 #ifdef TEST
1612
1613 static void 
1614 cert_cb (void *opaque, const unsigned char *cert, size_t certlen)
1615 {
1616   printf ("got a certificate of %u bytes length\n", certlen);
1617 }
1618
1619 int
1620 main (int argc, char **argv)
1621 {
1622   FILE *fp;
1623   struct stat st;
1624   unsigned char *buf;
1625   size_t buflen;
1626   gcry_mpi_t *result;
1627
1628   if (argc != 3)
1629     {
1630       fprintf (stderr, "usage: testp12 file passphrase\n");
1631       return 1;
1632     }
1633
1634   gcry_control (GCRYCTL_DISABLE_SECMEM, NULL);
1635   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL);
1636
1637   fp = fopen (argv[1], "rb");
1638   if (!fp)
1639     {
1640       fprintf (stderr, "can't open `%s': %s\n", argv[1], strerror (errno));
1641       return 1;
1642     }
1643   
1644   if (fstat (fileno(fp), &st))
1645     {
1646       fprintf (stderr, "can't stat `%s': %s\n", argv[1], strerror (errno));
1647       return 1;
1648     }
1649
1650   buflen = st.st_size;
1651   buf = gcry_malloc (buflen+1);
1652   if (!buf || fread (buf, buflen, 1, fp) != 1)
1653     {
1654       fprintf (stderr, "error reading `%s': %s\n", argv[1], strerror (errno));
1655       return 1;
1656     }
1657   fclose (fp);
1658
1659   result = p12_parse (buf, buflen, argv[2], cert_cb, NULL);
1660   if (result)
1661     {
1662       int i, rc;
1663       unsigned char *tmpbuf;
1664
1665       for (i=0; result[i]; i++)
1666         {
1667           rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &tmpbuf,
1668                                 NULL, result[i]);
1669           if (rc)
1670             printf ("%d: [error printing number: %s]\n",
1671                     i, gpg_strerror (rc));
1672           else
1673             {
1674               printf ("%d: %s\n", i, tmpbuf);
1675               gcry_free (tmpbuf);
1676             }
1677         }
1678     }
1679
1680   return 0;
1681
1682 }
1683
1684 /*
1685 Local Variables:
1686 compile-command: "gcc -Wall -O -g -DTEST=1 -o minip12 minip12.c ../jnlib/libjnlib.a -L /usr/local/lib -lgcrypt -lgpg-error"
1687 End:
1688 */
1689 #endif /* TEST */