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