Updated FSF's address.
[gnupg.git] / agent / minip12.c
1 /* minip12.c - A minimal pkcs-12 implementation.
2  * Copyright (C) 2002, 2003, 2004, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19  * USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
29 #include <gcrypt.h>
30
31 #ifdef TEST
32 #include <sys/stat.h>
33 #include <unistd.h>
34 #include <errno.h>
35 #endif
36
37 #include "../jnlib/logging.h"
38 #include "minip12.h"
39
40 #ifndef DIM
41 #define DIM(v)               (sizeof(v)/sizeof((v)[0]))
42 #endif
43
44 enum
45 {
46   UNIVERSAL = 0,
47   APPLICATION = 1,
48   CONTEXT = 2,
49   PRIVATE = 3
50 };
51
52
53 enum
54 {
55   TAG_NONE = 0,
56   TAG_BOOLEAN = 1,
57   TAG_INTEGER = 2,
58   TAG_BIT_STRING = 3,
59   TAG_OCTET_STRING = 4,
60   TAG_NULL = 5,
61   TAG_OBJECT_ID = 6,
62   TAG_OBJECT_DESCRIPTOR = 7,
63   TAG_EXTERNAL = 8,
64   TAG_REAL = 9,
65   TAG_ENUMERATED = 10,
66   TAG_EMBEDDED_PDV = 11,
67   TAG_UTF8_STRING = 12,
68   TAG_REALTIVE_OID = 13,
69   TAG_SEQUENCE = 16,
70   TAG_SET = 17,
71   TAG_NUMERIC_STRING = 18,
72   TAG_PRINTABLE_STRING = 19,
73   TAG_TELETEX_STRING = 20,
74   TAG_VIDEOTEX_STRING = 21,
75   TAG_IA5_STRING = 22,
76   TAG_UTC_TIME = 23,
77   TAG_GENERALIZED_TIME = 24,
78   TAG_GRAPHIC_STRING = 25,
79   TAG_VISIBLE_STRING = 26,
80   TAG_GENERAL_STRING = 27,
81   TAG_UNIVERSAL_STRING = 28,
82   TAG_CHARACTER_STRING = 29,
83   TAG_BMP_STRING = 30
84 };
85
86
87 static unsigned char const oid_data[9] = {
88   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01 };
89 static unsigned char const oid_encryptedData[9] = {
90   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06 };
91 static unsigned char const oid_pkcs_12_pkcs_8ShroudedKeyBag[11] = {
92   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x02 };
93 static unsigned char const oid_pkcs_12_CertBag[11] = {
94   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x03 };
95 static unsigned char const oid_pkcs_12_CrlBag[11] = {
96   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x04 };
97
98 static unsigned char const oid_pbeWithSHAAnd3_KeyTripleDES_CBC[10] = {
99   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03 };
100 static unsigned char const oid_pbeWithSHAAnd40BitRC2_CBC[10] = {
101   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x06 };
102 static unsigned char const oid_x509Certificate_for_pkcs_12[10] = {
103   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x16, 0x01 };
104
105
106 static unsigned char const oid_rsaEncryption[9] = {
107   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 };
108
109
110 static unsigned char const data_3desiter2048[30] = {
111   0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86,
112   0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30, 0x0E, 
113   0x04, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
114   0xFF, 0xFF, 0x02, 0x02, 0x08, 0x00 };
115 #define DATA_3DESITER2048_SALT_OFF  18
116
117 static unsigned char const data_rc2iter2048[30] = {
118   0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86,
119   0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x06, 0x30, 0x0E, 
120   0x04, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
121   0xFF, 0xFF, 0x02, 0x02, 0x08, 0x00 };
122 #define DATA_RC2ITER2048_SALT_OFF  18
123
124 static unsigned char const data_mactemplate[51] = {
125   0x30, 0x31, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
126   0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04,
127   0x14, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
128   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
129   0xff, 0xff, 0xff, 0xff, 0xff, 0x04, 0x08, 0xff,
130   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02,
131   0x02, 0x08, 0x00 }; 
132 #define DATA_MACTEMPLATE_MAC_OFF 17
133 #define DATA_MACTEMPLATE_SALT_OFF 39
134
135 struct buffer_s 
136 {
137   unsigned char *buffer;
138   size_t length;
139 };  
140
141
142 struct tag_info 
143 {
144   int class;
145   int is_constructed;
146   unsigned long tag;
147   unsigned long length;  /* length part of the TLV */
148   int nhdr;
149   int ndef;              /* It is an indefinite length */
150 };
151
152
153 /* Parse the buffer at the address BUFFER which is of SIZE and return
154    the tag and the length part from the TLV triplet.  Update BUFFER
155    and SIZE on success.  Checks that the encoded length does not
156    exhaust the length of the provided buffer. */
157 static int 
158 parse_tag (unsigned char const **buffer, size_t *size, struct tag_info *ti)
159 {
160   int c;
161   unsigned long tag;
162   const unsigned char *buf = *buffer;
163   size_t length = *size;
164
165   ti->length = 0;
166   ti->ndef = 0;
167   ti->nhdr = 0;
168
169   /* Get the tag */
170   if (!length)
171     return -1; /* premature eof */
172   c = *buf++; length--;
173   ti->nhdr++;
174
175   ti->class = (c & 0xc0) >> 6;
176   ti->is_constructed = !!(c & 0x20);
177   tag = c & 0x1f;
178
179   if (tag == 0x1f)
180     {
181       tag = 0;
182       do
183         {
184           tag <<= 7;
185           if (!length)
186             return -1; /* premature eof */
187           c = *buf++; length--;
188           ti->nhdr++;
189           tag |= c & 0x7f;
190         }
191       while (c & 0x80);
192     }
193   ti->tag = tag;
194
195   /* Get the length */
196   if (!length)
197     return -1; /* prematureeof */
198   c = *buf++; length--;
199   ti->nhdr++;
200
201   if ( !(c & 0x80) )
202     ti->length = c;
203   else if (c == 0x80)
204     ti->ndef = 1;
205   else if (c == 0xff)
206     return -1; /* forbidden length value */
207   else
208     {
209       unsigned long len = 0;
210       int count = c & 0x7f;
211
212       for (; count; count--)
213         {
214           len <<= 8;
215           if (!length)
216             return -1; /* premature_eof */
217           c = *buf++; length--;
218           ti->nhdr++;
219           len |= c & 0xff;
220         }
221       ti->length = len;
222     }
223   
224   if (ti->class == UNIVERSAL && !ti->tag)
225     ti->length = 0;
226
227   if (ti->length > length)
228     return -1; /* data larger than buffer. */
229   
230   *buffer = buf;
231   *size = length;
232   return 0;
233 }
234
235
236 /* Given an ASN.1 chunk of a structure like:
237
238      24 NDEF:       OCTET STRING  -- This is not passed to us
239      04    1:         OCTET STRING  -- INPUT point s to here
240             :           30
241      04    1:         OCTET STRING
242             :           80
243           [...]
244      04    2:         OCTET STRING
245             :           00 00
246             :         } -- This denotes a Null tag and are the last 
247                         -- two bytes in INPUT.
248    
249    Create a new buffer with the content of that octet string.  INPUT
250    is the orginal buffer with a length as stored at LENGTH.  Returns
251    NULL on error or a new malloced buffer with the length of this new
252    buffer stored at LENGTH and the number of bytes parsed from input
253    are added to the value stored at INPUT_CONSUMED.  INPUT_CONSUMED is
254    allowed to be passed as NULL if the caller is not interested in
255    this value. */
256 static unsigned char *
257 cram_octet_string (const unsigned char *input, size_t *length,
258                    size_t *input_consumed)
259 {
260   const unsigned char *s = input;
261   size_t n = *length;
262   unsigned char *output, *d;
263   struct tag_info ti;
264
265   /* Allocate output buf.  We know that it won't be longer than the
266      input buffer. */
267   d = output = gcry_malloc (n);
268   if (!output)
269     goto bailout;
270
271   for (;;)
272     {
273       if (parse_tag (&s, &n, &ti))
274         goto bailout;
275       if (ti.class == UNIVERSAL && ti.tag == TAG_OCTET_STRING 
276           && !ti.ndef && !ti.is_constructed)
277         {
278           memcpy (d, s, ti.length);
279           s += ti.length;
280           d += ti.length;
281           n -= ti.length;
282         }
283       else if (ti.class == UNIVERSAL && !ti.tag && !ti.is_constructed)
284         break; /* Ready */ 
285       else
286         goto bailout;
287     }
288
289
290   *length = d - output;
291   if (input_consumed)
292     *input_consumed += s - input;
293   return output;
294
295  bailout:
296   if (input_consumed)
297     *input_consumed += s - input;
298   gcry_free (output);
299   return NULL;
300 }
301
302
303
304 static int 
305 string_to_key (int id, char *salt, size_t saltlen, int iter, const char *pw,
306                int req_keylen, unsigned char *keybuf)
307 {
308   int rc, i, j;
309   gcry_md_hd_t md;
310   gcry_mpi_t num_b1 = NULL;
311   int pwlen;
312   unsigned char hash[20], buf_b[64], buf_i[128], *p;
313   size_t cur_keylen;
314   size_t n;
315
316   cur_keylen = 0;
317   pwlen = strlen (pw);
318   if (pwlen > 63/2)
319     {
320       log_error ("password too long\n");
321       return -1;
322     }
323
324   if (saltlen < 8)
325     {
326       log_error ("salt too short\n");
327       return -1;
328     }
329   
330   /* Store salt and password in BUF_I */
331   p = buf_i;
332   for(i=0; i < 64; i++)
333     *p++ = salt [i%saltlen];
334   for(i=j=0; i < 64; i += 2)
335     {
336       *p++ = 0;
337       *p++ = pw[j];
338       if (++j > pwlen) /* Note, that we include the trailing zero */
339         j = 0;
340     }
341
342   for (;;)
343     {
344       rc = gcry_md_open (&md, GCRY_MD_SHA1, 0);
345       if (rc)
346         {
347           log_error ( "gcry_md_open failed: %s\n", gpg_strerror (rc));
348           return rc;
349         }
350       for(i=0; i < 64; i++)
351         gcry_md_putc (md, id);
352       gcry_md_write (md, buf_i, 128);
353       memcpy (hash, gcry_md_read (md, 0), 20);
354       gcry_md_close (md);
355       for (i=1; i < iter; i++)
356         gcry_md_hash_buffer (GCRY_MD_SHA1, hash, hash, 20);
357
358       for (i=0; i < 20 && cur_keylen < req_keylen; i++)
359         keybuf[cur_keylen++] = hash[i];
360       if (cur_keylen == req_keylen)
361         {
362           gcry_mpi_release (num_b1);
363           return 0; /* ready */
364         }
365       
366       /* need more bytes. */
367       for(i=0; i < 64; i++)
368         buf_b[i] = hash[i % 20];
369       rc = gcry_mpi_scan (&num_b1, GCRYMPI_FMT_USG, buf_b, 64, &n);
370       if (rc)
371         {
372           log_error ( "gcry_mpi_scan failed: %s\n", gpg_strerror (rc));
373           return -1;
374         }
375       gcry_mpi_add_ui (num_b1, num_b1, 1);
376       for (i=0; i < 128; i += 64)
377         {
378           gcry_mpi_t num_ij;
379
380           rc = gcry_mpi_scan (&num_ij, GCRYMPI_FMT_USG, buf_i + i, 64, &n);
381           if (rc)
382             {
383               log_error ( "gcry_mpi_scan failed: %s\n",
384                        gpg_strerror (rc));
385               return -1;
386             }
387           gcry_mpi_add (num_ij, num_ij, num_b1);
388           gcry_mpi_clear_highbit (num_ij, 64*8);
389           rc = gcry_mpi_print (GCRYMPI_FMT_USG, buf_i + i, 64, &n, num_ij);
390           if (rc)
391             {
392               log_error ( "gcry_mpi_print failed: %s\n",
393                           gpg_strerror (rc));
394               return -1;
395             }
396           gcry_mpi_release (num_ij);
397         }
398     }
399 }
400
401
402 static int 
403 set_key_iv (gcry_cipher_hd_t chd, char *salt, size_t saltlen, int iter,
404             const char *pw, int keybytes)
405 {
406   unsigned char keybuf[24];
407   int rc;
408
409   assert (keybytes == 5 || keybytes == 24);
410   if (string_to_key (1, salt, saltlen, iter, pw, keybytes, keybuf))
411     return -1;
412   rc = gcry_cipher_setkey (chd, keybuf, keybytes);
413   if (rc)
414     {
415       log_error ( "gcry_cipher_setkey failed: %s\n", gpg_strerror (rc));
416       return -1;
417     }
418
419   if (string_to_key (2, salt, saltlen, iter, pw, 8, keybuf))
420     return -1;
421   rc = gcry_cipher_setiv (chd, keybuf, 8);
422   if (rc)
423     {
424       log_error ("gcry_cipher_setiv failed: %s\n", gpg_strerror (rc));
425       return -1;
426     }
427   return 0;
428 }
429
430
431 static void
432 crypt_block (unsigned char *buffer, size_t length, char *salt, size_t saltlen,
433              int iter, const char *pw, int cipher_algo, int encrypt)
434 {
435   gcry_cipher_hd_t chd;
436   int rc;
437
438   rc = gcry_cipher_open (&chd, cipher_algo, GCRY_CIPHER_MODE_CBC, 0); 
439   if (rc)
440     {
441       log_error ( "gcry_cipher_open failed: %s\n", gpg_strerror(rc));
442       wipememory (buffer, length);
443       return;
444     }
445   if (set_key_iv (chd, salt, saltlen, iter, pw,
446                   cipher_algo == GCRY_CIPHER_RFC2268_40? 5:24))
447     {
448       wipememory (buffer, length);
449       goto leave;
450     }
451
452   rc = encrypt? gcry_cipher_encrypt (chd, buffer, length, NULL, 0)
453               : gcry_cipher_decrypt (chd, buffer, length, NULL, 0);
454
455   if (rc)
456     {
457       wipememory (buffer, length);
458       log_error ( "en/de-crytion failed: %s\n", gpg_strerror (rc));
459       goto leave;
460     }
461
462  leave:
463   gcry_cipher_close (chd);
464 }
465   
466
467
468 static int
469 parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
470                           int startoffset, size_t *r_consumed, const char *pw,
471                           void (*certcb)(void*, const unsigned char*, size_t),
472                           void *certcbarg)
473 {
474   struct tag_info ti;
475   const unsigned char *p = buffer;
476   const unsigned char *p_start = buffer;
477   size_t n = length;
478   const char *where;
479   char salt[16];
480   size_t saltlen;
481   unsigned int iter;
482   unsigned char *plain = NULL;
483   int bad_pass = 0;
484   unsigned char *cram_buffer = NULL;
485   size_t consumed = 0; /* Number of bytes consumed from the orginal buffer. */
486   
487   where = "start";
488   if (parse_tag (&p, &n, &ti))
489     goto bailout;
490   if (ti.class != CONTEXT || ti.tag)
491     goto bailout;
492   if (parse_tag (&p, &n, &ti))
493     goto bailout;
494   if (ti.tag != TAG_SEQUENCE)
495     goto bailout;
496
497   where = "bag.encryptedData.version";
498   if (parse_tag (&p, &n, &ti))
499     goto bailout;
500   if (ti.tag != TAG_INTEGER || ti.length != 1 || *p != 0)
501     goto bailout;
502   p++; n--;
503   if (parse_tag (&p, &n, &ti))
504     goto bailout;
505   if (ti.tag != TAG_SEQUENCE)
506     goto bailout;
507
508   where = "bag.encryptedData.data";
509   if (parse_tag (&p, &n, &ti))
510     goto bailout;
511   if (ti.tag != TAG_OBJECT_ID || ti.length != DIM(oid_data)
512       || memcmp (p, oid_data, DIM(oid_data)))
513     goto bailout;
514   p += DIM(oid_data);
515   n -= DIM(oid_data);
516
517   where = "bag.encryptedData.keyinfo";
518   if (parse_tag (&p, &n, &ti))
519     goto bailout;
520   if (ti.class || ti.tag != TAG_SEQUENCE)
521     goto bailout;
522   if (parse_tag (&p, &n, &ti))
523     goto bailout;
524   if (!ti.class && ti.tag == TAG_OBJECT_ID 
525       && ti.length == DIM(oid_pbeWithSHAAnd40BitRC2_CBC)
526       && !memcmp (p, oid_pbeWithSHAAnd40BitRC2_CBC,
527                   DIM(oid_pbeWithSHAAnd40BitRC2_CBC)))
528     {
529       p += DIM(oid_pbeWithSHAAnd40BitRC2_CBC);
530       n -= DIM(oid_pbeWithSHAAnd40BitRC2_CBC);
531     }
532   else
533     goto bailout;
534
535   where = "rc2-params";
536   if (parse_tag (&p, &n, &ti))
537     goto bailout;
538   if (ti.class || ti.tag != TAG_SEQUENCE)
539     goto bailout;
540   if (parse_tag (&p, &n, &ti))
541     goto bailout;
542   if (ti.class || ti.tag != TAG_OCTET_STRING
543       || ti.length < 8 || ti.length > 16 )
544     goto bailout;
545   saltlen = ti.length;
546   memcpy (salt, p, saltlen);
547   p += saltlen;
548   n -= saltlen;
549   if (parse_tag (&p, &n, &ti))
550     goto bailout;
551   if (ti.class || ti.tag != TAG_INTEGER || !ti.length )
552     goto bailout;
553   for (iter=0; ti.length; ti.length--)
554     {
555       iter <<= 8;
556       iter |= (*p++) & 0xff; 
557       n--;
558     }
559   
560   where = "rc2-ciphertext";
561   if (parse_tag (&p, &n, &ti))
562     goto bailout;
563
564   consumed = p - p_start;
565   if (ti.class == CONTEXT && ti.tag == 0 && ti.is_constructed && ti.ndef)
566     {
567       /* Mozilla exported certs now come with single byte chunks of
568          octect strings.  (Mozilla Firefox 1.0.4).  Arghh. */
569       where = "cram-rc2-ciphertext";
570       cram_buffer = cram_octet_string ( p, &n, &consumed);
571       if (!cram_buffer)
572         goto bailout;
573       p = p_start = cram_buffer;
574       if (r_consumed)
575         *r_consumed = consumed;
576       r_consumed = NULL; /* Ugly hack to not update that value any further. */
577       ti.length = n;
578     }
579   else if (ti.class == CONTEXT && ti.tag == 0 && ti.length )
580     ;
581   else
582     goto bailout;
583   
584   log_info ("%lu bytes of RC2 encrypted text\n", ti.length);
585
586   plain = gcry_malloc_secure (ti.length);
587   if (!plain)
588     {
589       log_error ("error allocating decryption buffer\n");
590       goto bailout;
591     }
592   memcpy (plain, p, ti.length);
593   crypt_block (plain, ti.length, salt, saltlen,
594                iter, pw, GCRY_CIPHER_RFC2268_40, 0);
595   n = ti.length;
596   startoffset = 0;
597   p_start = p = plain;
598
599 /*   { */
600 /* #  warning debug code is enabled */
601 /*     FILE *fp = fopen ("tmp-rc2-plain.der", "wb"); */
602 /*     if (!fp || fwrite (p, n, 1, fp) != 1) */
603 /*       exit (2); */
604 /*     fclose (fp); */
605 /*   } */
606
607   where = "outer.outer.seq";
608   if (parse_tag (&p, &n, &ti))
609     {
610       bad_pass = 1;
611       goto bailout;
612     }
613   if (ti.class || ti.tag != TAG_SEQUENCE)
614     {
615       bad_pass = 1;
616       goto bailout;
617     }
618
619   if (parse_tag (&p, &n, &ti))
620     {
621       bad_pass = 1;
622       goto bailout;
623     }
624
625   /* Loop over all certificates inside the bag. */
626   while (n)
627     {
628       int isbag = 0;
629
630       where = "certbag.nextcert";
631       if (ti.class || ti.tag != TAG_SEQUENCE)
632         goto bailout;
633
634       where = "certbag.objectidentifier";
635       if (parse_tag (&p, &n, &ti))
636         goto bailout;
637       if (ti.class || ti.tag != TAG_OBJECT_ID)
638         goto bailout;
639       if ( ti.length == DIM(oid_pkcs_12_CertBag)
640            && !memcmp (p, oid_pkcs_12_CertBag, DIM(oid_pkcs_12_CertBag)))
641         {
642           p += DIM(oid_pkcs_12_CertBag);
643           n -= DIM(oid_pkcs_12_CertBag);
644         }
645       else if ( ti.length == DIM(oid_pkcs_12_CrlBag)
646            && !memcmp (p, oid_pkcs_12_CrlBag, DIM(oid_pkcs_12_CrlBag)))
647         {
648           p += DIM(oid_pkcs_12_CrlBag);
649           n -= DIM(oid_pkcs_12_CrlBag);
650           isbag = 1;
651         }
652       else
653         goto bailout;
654
655       where = "certbag.before.certheader";
656       if (parse_tag (&p, &n, &ti))
657         goto bailout;
658       if (ti.class != CONTEXT || ti.tag)
659         goto bailout;
660       if (isbag)
661         {
662           log_info ("skipping unsupported crlBag\n");
663           p += ti.length;
664           n -= ti.length;
665         }
666       else
667         {
668           if (parse_tag (&p, &n, &ti))
669             goto bailout;
670           if (ti.class || ti.tag != TAG_SEQUENCE)
671             goto bailout;
672           if (parse_tag (&p, &n, &ti))
673             goto bailout;
674           if (ti.class || ti.tag != TAG_OBJECT_ID
675               || ti.length != DIM(oid_x509Certificate_for_pkcs_12)
676               || memcmp (p, oid_x509Certificate_for_pkcs_12,
677                          DIM(oid_x509Certificate_for_pkcs_12)))
678             goto bailout;
679           p += DIM(oid_x509Certificate_for_pkcs_12);
680           n -= DIM(oid_x509Certificate_for_pkcs_12);
681           
682           where = "certbag.before.octetstring";
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_OCTET_STRING || ti.ndef)
690             goto bailout;
691           
692           /* Return the certificate. */
693           if (certcb)
694             certcb (certcbarg, p, ti.length);
695    
696           p += ti.length;
697           n -= ti.length;
698         }
699
700       /* Ugly hack to cope with the padding: Forget about the rest if
701          that is less or equal to the cipher's block length.  We can
702          reasonable assume that all valid data will be longer than
703          just one block. */
704       if (n <= 8)
705         n = 0;  
706
707       /* Skip the optional SET with the pkcs12 cert attributes. */
708       if (n)
709         {
710           where = "bag.attributes";
711           if (parse_tag (&p, &n, &ti))
712             goto bailout;
713           if (!ti.class && ti.tag == TAG_SEQUENCE)
714             ; /* No attributes. */
715           else if (!ti.class && ti.tag == TAG_SET && !ti.ndef)
716             { /* The optional SET. */
717               p += ti.length;
718               n -= ti.length;
719               if (n <= 8)
720                 n = 0;
721               if (n && parse_tag (&p, &n, &ti))
722                 goto bailout;
723             }
724           else
725             goto bailout;
726         }
727     }
728   
729   if (r_consumed)
730     *r_consumed = consumed;
731   gcry_free (plain);
732   gcry_free (cram_buffer);
733   return 0;
734
735  bailout:
736   if (r_consumed)
737     *r_consumed = consumed;
738   gcry_free (plain);
739   gcry_free (cram_buffer);
740   log_error ("encryptedData error at \"%s\", offset %u\n",
741              where, (p - p_start)+startoffset);
742   if (bad_pass)
743     {
744       /* Note, that the following string might be used by other programs
745          to check for a bad passphrase; it should therefore not be
746          translated or changed. */
747       log_error ("possibly bad passphrase given\n");
748     }
749   return -1;
750 }
751
752 static gcry_mpi_t *
753 parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
754                 size_t *r_consumed, const char *pw)
755 {
756   int rc;
757   struct tag_info ti;
758   const unsigned char *p = buffer;
759   const unsigned char *p_start = buffer;
760   size_t n = length;
761   const char *where;
762   char salt[16];
763   size_t saltlen;
764   unsigned int iter;
765   int len;
766   unsigned char *plain = NULL;
767   gcry_mpi_t *result = NULL;
768   int result_count, i;
769   unsigned char *cram_buffer = NULL;
770   size_t consumed = 0; /* Number of bytes consumed from the orginal buffer. */
771
772   where = "start";
773   if (parse_tag (&p, &n, &ti))
774     goto bailout;
775   if (ti.class != CONTEXT || ti.tag)
776     goto bailout;
777   if (parse_tag (&p, &n, &ti))
778     goto bailout;
779   if (ti.class || ti.tag != TAG_OCTET_STRING)
780     goto bailout;
781
782   consumed = p - p_start;
783   if (ti.is_constructed && ti.ndef)
784     {
785       /* Mozilla exported certs now come with single byte chunks of
786          octect strings.  (Mozilla Firefox 1.0.4).  Arghh. */
787       where = "cram-data.outersegs";
788       cram_buffer = cram_octet_string ( p, &n, &consumed);
789       if (!cram_buffer)
790         goto bailout;
791       p = p_start = cram_buffer;
792       if (r_consumed)
793         *r_consumed = consumed;
794       r_consumed = NULL; /* Ugly hack to not update that value any further. */
795     }
796   
797
798   where = "data.outerseqs";
799   if (parse_tag (&p, &n, &ti))
800     goto bailout;
801   if (ti.class || ti.tag != TAG_SEQUENCE)
802     goto bailout;
803   if (parse_tag (&p, &n, &ti))
804     goto bailout;
805   if (ti.class || ti.tag != TAG_SEQUENCE)
806     goto bailout;
807
808   where = "data.objectidentifier";
809   if (parse_tag (&p, &n, &ti))
810     goto bailout;
811   if (ti.class || ti.tag != TAG_OBJECT_ID
812       || ti.length != DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag)
813       || memcmp (p, oid_pkcs_12_pkcs_8ShroudedKeyBag,
814                  DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag)))
815     goto bailout;
816   p += DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag);
817   n -= DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag);
818
819   where = "shrouded,outerseqs";
820   if (parse_tag (&p, &n, &ti))
821     goto bailout;
822   if (ti.class != CONTEXT || ti.tag)
823     goto bailout;
824   if (parse_tag (&p, &n, &ti))
825     goto bailout;
826   if (ti.class || ti.tag != TAG_SEQUENCE)
827     goto bailout;
828   if (parse_tag (&p, &n, &ti))
829     goto bailout;
830   if (ti.class || ti.tag != TAG_SEQUENCE)
831     goto bailout;
832   if (parse_tag (&p, &n, &ti))
833     goto bailout;
834   if (ti.class || ti.tag != TAG_OBJECT_ID
835       || ti.length != DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)
836       || memcmp (p, oid_pbeWithSHAAnd3_KeyTripleDES_CBC,
837                  DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)))
838     goto bailout;
839   p += DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
840   n -= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
841
842   where = "3des-params";
843   if (parse_tag (&p, &n, &ti))
844     goto bailout;
845   if (ti.class || ti.tag != TAG_SEQUENCE)
846     goto bailout;
847   if (parse_tag (&p, &n, &ti))
848     goto bailout;
849   if (ti.class || ti.tag != TAG_OCTET_STRING
850       || ti.length < 8 || ti.length > 16)
851     goto bailout;
852   saltlen = ti.length;
853   memcpy (salt, p, saltlen);
854   p += saltlen;
855   n -= saltlen;
856   if (parse_tag (&p, &n, &ti))
857     goto bailout;
858   if (ti.class || ti.tag != TAG_INTEGER || !ti.length )
859     goto bailout;
860   for (iter=0; ti.length; ti.length--)
861     {
862       iter <<= 8;
863       iter |= (*p++) & 0xff; 
864       n--;
865     }
866   
867   where = "3des-ciphertext";
868   if (parse_tag (&p, &n, &ti))
869     goto bailout;
870   if (ti.class || ti.tag != TAG_OCTET_STRING || !ti.length )
871     goto bailout;
872   
873   log_info ("%lu bytes of 3DES encrypted text\n", ti.length);
874   
875   plain = gcry_malloc_secure (ti.length);
876   if (!plain)
877     {
878       log_error ("error allocating decryption buffer\n");
879       goto bailout;
880     }
881   memcpy (plain, p, ti.length);
882   consumed += p - p_start + ti.length;
883   crypt_block (plain, ti.length, salt, saltlen, iter, pw, GCRY_CIPHER_3DES, 0);
884   n = ti.length;
885   startoffset = 0;
886   p_start = p = plain;
887
888 /*   { */
889 /* #  warning debug code is enabled */
890 /*     FILE *fp = fopen ("tmp-rc2-plain-key.der", "wb"); */
891 /*     if (!fp || fwrite (p, n, 1, fp) != 1) */
892 /*       exit (2); */
893 /*     fclose (fp); */
894 /*   } */
895
896
897   where = "decrypted-text";
898   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
899     goto bailout;
900   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER
901       || ti.length != 1 || *p)
902     goto bailout;
903   p++; n--;
904   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
905     goto bailout;
906   len = ti.length;
907   if (parse_tag (&p, &n, &ti))
908     goto bailout;
909   if (len < ti.nhdr)
910     goto bailout;
911   len -= ti.nhdr;
912   if (ti.class || ti.tag != TAG_OBJECT_ID
913       || ti.length != DIM(oid_rsaEncryption)
914       || memcmp (p, oid_rsaEncryption,
915                  DIM(oid_rsaEncryption)))
916     goto bailout;
917   p += DIM (oid_rsaEncryption);
918   n -= DIM (oid_rsaEncryption);
919   if (len < ti.length)
920     goto bailout;
921   len -= ti.length;
922   if (n < len)
923     goto bailout;
924   p += len;
925   n -= len;
926   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_OCTET_STRING)
927     goto bailout;
928   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
929     goto bailout;
930   len = ti.length;
931
932   result = gcry_calloc (10, sizeof *result);
933   if (!result)
934     {
935       log_error ( "error allocating result array\n");
936       goto bailout;
937     }
938   result_count = 0;
939
940   where = "reading.key-parameters";
941   for (result_count=0; len && result_count < 9;)
942     {
943       if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER)
944         goto bailout;
945       if (len < ti.nhdr)
946         goto bailout;
947       len -= ti.nhdr;
948       if (len < ti.length)
949         goto bailout;
950       len -= ti.length;
951       if (!result_count && ti.length == 1 && !*p)
952         ; /* ignore the very first one if it is a 0 */
953       else 
954         {
955           rc = gcry_mpi_scan (result+result_count, GCRYMPI_FMT_USG, p,
956                               ti.length, NULL);
957           if (rc)
958             {
959               log_error ("error parsing key parameter: %s\n",
960                          gpg_strerror (rc));
961               goto bailout;
962             }
963           result_count++;
964         }
965       p += ti.length;
966       n -= ti.length;
967     }
968   if (len)
969     goto bailout;
970
971   gcry_free (cram_buffer);
972   if (r_consumed)
973     *r_consumed = consumed;
974   return result;
975
976  bailout:
977   gcry_free (plain);
978   if (result)
979     {
980       for (i=0; result[i]; i++)
981         gcry_mpi_release (result[i]);
982       gcry_free (result);
983     }
984   gcry_free (cram_buffer);
985   log_error ( "data error at \"%s\", offset %u\n",
986               where, (p - buffer) + startoffset);
987   if (r_consumed)
988     *r_consumed = consumed;
989   return NULL;
990 }
991
992
993 /* Parse a PKCS12 object and return an array of MPI representing the
994    secret key parameters.  This is a very limited implementation in
995    that it is only able to look for 3DES encoded encryptedData and
996    tries to extract the first private key object it finds.  In case of
997    an error NULL is returned. CERTCB and CERRTCBARG are used to pass
998    X.509 certificates back to the caller. */
999 gcry_mpi_t *
1000 p12_parse (const unsigned char *buffer, size_t length, const char *pw,
1001            void (*certcb)(void*, const unsigned char*, size_t),
1002            void *certcbarg)
1003 {
1004   struct tag_info ti;
1005   const unsigned char *p = buffer;
1006   const unsigned char *p_start = buffer;
1007   size_t n = length;
1008   const char *where;
1009   int bagseqlength, len;
1010   int bagseqndef, lenndef;
1011   gcry_mpi_t *result = NULL;
1012   unsigned char *cram_buffer = NULL;
1013
1014   where = "pfx";
1015   if (parse_tag (&p, &n, &ti))
1016     goto bailout;
1017   if (ti.tag != TAG_SEQUENCE)
1018     goto bailout;
1019
1020   where = "pfxVersion";
1021   if (parse_tag (&p, &n, &ti))
1022     goto bailout;
1023   if (ti.tag != TAG_INTEGER || ti.length != 1 || *p != 3)
1024     goto bailout;
1025   p++; n--;
1026   
1027   where = "authSave";
1028   if (parse_tag (&p, &n, &ti))
1029     goto bailout;
1030   if (ti.tag != TAG_SEQUENCE)
1031     goto bailout;
1032   if (parse_tag (&p, &n, &ti))
1033     goto bailout;
1034   if (ti.tag != TAG_OBJECT_ID || ti.length != DIM(oid_data)
1035       || memcmp (p, oid_data, DIM(oid_data)))
1036     goto bailout;
1037   p += DIM(oid_data);
1038   n -= DIM(oid_data);
1039
1040   if (parse_tag (&p, &n, &ti))
1041     goto bailout;
1042   if (ti.class != CONTEXT || ti.tag)
1043     goto bailout;
1044   if (parse_tag (&p, &n, &ti))
1045     goto bailout;
1046   if (ti.class != UNIVERSAL || ti.tag != TAG_OCTET_STRING)
1047     goto bailout;
1048
1049   if (ti.is_constructed && ti.ndef)
1050     {
1051       /* Mozilla exported certs now come with single byte chunks of
1052          octect strings.  (Mozilla Firefox 1.0.4).  Arghh. */
1053       where = "cram-bags";
1054       cram_buffer = cram_octet_string ( p, &n, NULL);
1055       if (!cram_buffer)
1056         goto bailout;
1057       p = p_start = cram_buffer;
1058     }
1059
1060   where = "bags";
1061   if (parse_tag (&p, &n, &ti))
1062     goto bailout;
1063   if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE)
1064     goto bailout;
1065   bagseqndef = ti.ndef;
1066   bagseqlength = ti.length;
1067   while (bagseqlength || bagseqndef)
1068     {
1069       log_debug ( "at offset %u\n", (p - p_start));
1070       where = "bag-sequence";
1071       if (parse_tag (&p, &n, &ti))
1072         goto bailout;
1073       if (bagseqndef && ti.class == UNIVERSAL && !ti.tag && !ti.is_constructed)
1074         break; /* Ready */ 
1075       if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE)
1076         goto bailout;
1077
1078       if (!bagseqndef)
1079         {
1080           if (bagseqlength < ti.nhdr)
1081             goto bailout;
1082           bagseqlength -= ti.nhdr;
1083           if (bagseqlength < ti.length)
1084             goto bailout;
1085           bagseqlength -= ti.length;
1086         }
1087       lenndef = ti.ndef;
1088       len = ti.length;
1089
1090       if (parse_tag (&p, &n, &ti))
1091         goto bailout;
1092       if (lenndef)
1093         len = ti.nhdr; 
1094       else
1095         len -= ti.nhdr; 
1096
1097       if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_encryptedData)
1098           && !memcmp (p, oid_encryptedData, DIM(oid_encryptedData)))
1099         {
1100           size_t consumed = 0;
1101
1102           p += DIM(oid_encryptedData);
1103           n -= DIM(oid_encryptedData);
1104           if (!lenndef)
1105             len -= DIM(oid_encryptedData);
1106           where = "bag.encryptedData";
1107           if (parse_bag_encrypted_data (p, n, (p - p_start), &consumed, pw,
1108                                         certcb, certcbarg))
1109             goto bailout;
1110           if (lenndef)
1111             len += consumed;
1112         }
1113       else if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_data)
1114                && !memcmp (p, oid_data, DIM(oid_data)))
1115         {
1116           if (result)
1117             {
1118               log_info ("already got an data object, skipping next one\n");
1119               p += ti.length;
1120               n -= ti.length;
1121             }
1122           else
1123             {
1124               size_t consumed = 0;
1125
1126               p += DIM(oid_data);
1127               n -= DIM(oid_data);
1128               if (!lenndef)
1129                 len -= DIM(oid_data);
1130               result = parse_bag_data (p, n, (p - p_start), &consumed, pw);
1131               if (!result)
1132                 goto bailout;
1133               if (lenndef)
1134                 len += consumed;
1135             }
1136         }
1137       else
1138         {
1139           log_info ("unknown bag type - skipped\n");
1140           p += ti.length;
1141           n -= ti.length;
1142         }
1143
1144       if (len < 0 || len > n)
1145         goto bailout;
1146       p += len;
1147       n -= len;
1148       if (lenndef)
1149         {
1150           /* Need to skip the Null Tag. */
1151           if (parse_tag (&p, &n, &ti))
1152             goto bailout;
1153           if (!(ti.class == UNIVERSAL && !ti.tag && !ti.is_constructed))
1154             goto bailout;
1155         }
1156     }
1157   
1158   gcry_free (cram_buffer);
1159   return result;
1160  bailout:
1161   log_error ("error at \"%s\", offset %u\n", where, (p - p_start));
1162   /* fixme: need to release RESULT. */
1163   gcry_free (cram_buffer);
1164   return NULL;
1165 }
1166
1167
1168 \f
1169 static size_t
1170 compute_tag_length (size_t n)
1171 {     
1172   int needed = 0;
1173
1174   if (n < 128)
1175     needed += 2; /* tag and one length byte */
1176   else if (n < 256)
1177     needed += 3; /* tag, number of length bytes, 1 length byte */
1178   else if (n < 65536)
1179     needed += 4; /* tag, number of length bytes, 2 length bytes */
1180   else
1181     {
1182       log_error ("object too larger to encode\n");
1183       return 0;
1184     }
1185   return needed;
1186 }
1187
1188 static unsigned char *
1189 store_tag_length (unsigned char *p, int tag, size_t n)
1190 {     
1191   if (tag == TAG_SEQUENCE)
1192     tag |= 0x20; /* constructed */
1193
1194   *p++ = tag;
1195   if (n < 128)
1196     *p++ = n;
1197   else if (n < 256)
1198     {
1199       *p++ = 0x81;
1200       *p++ = n;
1201     }
1202   else if (n < 65536)
1203     {
1204       *p++ = 0x82;
1205       *p++ = n >> 8;
1206       *p++ = n;
1207     }
1208
1209   return p;
1210 }
1211
1212
1213 /* Create the final PKCS-12 object from the sequences contained in
1214    SEQLIST.  PW is the password. That array is terminated with an NULL
1215    object. */
1216 static unsigned char *
1217 create_final (struct buffer_s *sequences, const char *pw, size_t *r_length)
1218 {
1219   int i;
1220   size_t needed = 0;
1221   size_t len[8], n;
1222   unsigned char *macstart;
1223   size_t maclen;
1224   unsigned char *result, *p;
1225   size_t resultlen;
1226   char salt[8];
1227   unsigned char keybuf[20];
1228   gcry_md_hd_t md;
1229   int rc;
1230
1231   /* 9 steps to create the pkcs#12 Krampf. */
1232
1233   /* 8. The MAC. */
1234   /* We add this at step 0. */
1235
1236   /* 7. All the buffers. */
1237   for (i=0; sequences[i].buffer; i++)
1238     needed += sequences[i].length;
1239
1240   /* 6. This goes into a sequences. */
1241   len[6] = needed;
1242   n = compute_tag_length (needed);
1243   needed += n;
1244
1245   /* 5. Encapsulate all in an octet string. */
1246   len[5] = needed;
1247   n = compute_tag_length (needed);
1248   needed += n;
1249
1250   /* 4. And tag it with [0]. */
1251   len[4] = needed;
1252   n = compute_tag_length (needed);
1253   needed += n;
1254
1255   /* 3. Prepend an data OID. */
1256   needed += 2 + DIM (oid_data);
1257
1258   /* 2. Put all into a sequences. */
1259   len[2] = needed;
1260   n = compute_tag_length (needed);
1261   needed += n;
1262
1263   /* 1. Prepend the version integer 3. */
1264   needed += 3;
1265
1266   /* 0. And the final outer sequence. */
1267   needed += DIM (data_mactemplate);
1268   len[0] = needed;
1269   n = compute_tag_length (needed);
1270   needed += n;
1271
1272   /* Allocate a buffer. */
1273   result = gcry_malloc (needed);
1274   if (!result)
1275     {
1276       log_error ("error allocating buffer\n");
1277       return NULL;
1278     }
1279   p = result;
1280
1281   /* 0. Store the very outer sequence. */
1282   p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1283
1284   /* 1. Store the version integer 3. */
1285   *p++ = TAG_INTEGER;
1286   *p++ = 1; 
1287   *p++ = 3;
1288
1289   /* 2. Store another sequence. */
1290   p = store_tag_length (p, TAG_SEQUENCE, len[2]);
1291
1292   /* 3. Store the data OID. */
1293   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
1294   memcpy (p, oid_data, DIM (oid_data)); 
1295   p += DIM (oid_data); 
1296
1297   /* 4. Next comes a context tag. */
1298   p = store_tag_length (p, 0xa0, len[4]);
1299
1300   /* 5. And an octet string. */
1301   p = store_tag_length (p, TAG_OCTET_STRING, len[5]);
1302
1303   /* 6. And the inner sequence. */
1304   macstart = p;
1305   p = store_tag_length (p, TAG_SEQUENCE, len[6]);
1306
1307   /* 7. Append all the buffers. */
1308   for (i=0; sequences[i].buffer; i++)
1309     {
1310       memcpy (p, sequences[i].buffer, sequences[i].length);
1311       p += sequences[i].length;
1312     }
1313
1314   /* Intermezzo to compute the MAC. */
1315   maclen = p - macstart;
1316   gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
1317   if (string_to_key (3, salt, 8, 2048, pw, 20, keybuf))
1318     {
1319       gcry_free (result);
1320       return NULL;
1321     }
1322   rc = gcry_md_open (&md, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC);
1323   if (rc)
1324     {
1325       log_error ("gcry_md_open failed: %s\n", gpg_strerror (rc));
1326       gcry_free (result);
1327       return NULL;
1328     }
1329   rc = gcry_md_setkey (md, keybuf, 20);
1330   if (rc)
1331     {
1332       log_error ("gcry_md_setkey failed: %s\n", gpg_strerror (rc));
1333       gcry_md_close (md);
1334       gcry_free (result);
1335       return NULL;
1336     }
1337   gcry_md_write (md, macstart, maclen);
1338
1339   /* 8. Append the MAC template and fix it up. */
1340   memcpy (p, data_mactemplate, DIM (data_mactemplate));
1341   memcpy (p + DATA_MACTEMPLATE_SALT_OFF, salt, 8);
1342   memcpy (p + DATA_MACTEMPLATE_MAC_OFF, gcry_md_read (md, 0), 20);
1343   p += DIM (data_mactemplate);
1344   gcry_md_close (md);
1345
1346   /* Ready. */
1347   resultlen = p - result;
1348   if (needed != resultlen)
1349     log_debug ("length mismatch: %lu, %lu\n",
1350                (unsigned long)needed, (unsigned long)resultlen);
1351
1352   *r_length = resultlen;
1353   return result;
1354 }
1355
1356
1357 /* Build a DER encoded SEQUENCE with the key:
1358
1359    SEQUENCE {
1360      INTEGER 0
1361      SEQUENCE {
1362        OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
1363        NULL
1364        }
1365      OCTET STRING, encapsulates {
1366        SEQUENCE {
1367          INTEGER 0
1368          INTEGER
1369          INTEGER 
1370          INTEGER
1371          INTEGER
1372          INTEGER
1373          INTEGER
1374          INTEGER
1375          INTEGER
1376          }
1377        }
1378      }
1379 */  
1380   
1381 static unsigned char * 
1382 build_key_sequence (gcry_mpi_t *kparms, size_t *r_length)
1383 {
1384   int rc, i;
1385   size_t needed, n;
1386   unsigned char *plain, *p;
1387   size_t plainlen;
1388   size_t outseqlen, oidseqlen, octstrlen, inseqlen;
1389
1390   needed = 3; /* The version(?) integer of value 0. */
1391   for (i=0; kparms[i]; i++)
1392     {
1393       n = 0;
1394       rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, kparms[i]);
1395       if (rc)
1396         {
1397           log_error ("error formatting parameter: %s\n", gpg_strerror (rc));
1398           return NULL;
1399         }
1400       needed += n;
1401       n = compute_tag_length (n);
1402       if (!n)
1403         return NULL;
1404       needed += n;
1405     }
1406   if (i != 8)
1407     {
1408       log_error ("invalid paramters for p12_build\n");
1409       return NULL;
1410     }
1411   /* Now this all goes into a sequence. */
1412   inseqlen = needed;
1413   n = compute_tag_length (needed);
1414   if (!n)
1415     return NULL;
1416   needed += n;
1417   /* Encapsulate all into an octet string. */
1418   octstrlen = needed;
1419   n = compute_tag_length (needed);
1420   if (!n)
1421     return NULL;
1422   needed += n;
1423   /* Prepend the object identifier sequence. */
1424   oidseqlen = 2 + DIM (oid_rsaEncryption) + 2;
1425   needed += 2 + oidseqlen;
1426   /* The version number. */
1427   needed += 3;
1428   /* And finally put the whole thing into a sequence. */
1429   outseqlen = needed;
1430   n = compute_tag_length (needed);
1431   if (!n)
1432     return NULL;
1433   needed += n;
1434   
1435   /* allocate 8 extra bytes for padding */
1436   plain = gcry_malloc_secure (needed+8);
1437   if (!plain)
1438     {
1439       log_error ("error allocating encryption buffer\n");
1440       return NULL;
1441     }
1442   
1443   /* And now fill the plaintext buffer. */
1444   p = plain;
1445   p = store_tag_length (p, TAG_SEQUENCE, outseqlen);
1446   /* Store version. */
1447   *p++ = TAG_INTEGER;
1448   *p++ = 1;
1449   *p++ = 0;
1450   /* Store object identifier sequence. */
1451   p = store_tag_length (p, TAG_SEQUENCE, oidseqlen);
1452   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_rsaEncryption));
1453   memcpy (p, oid_rsaEncryption, DIM (oid_rsaEncryption)); 
1454   p += DIM (oid_rsaEncryption); 
1455   *p++ = TAG_NULL;
1456   *p++ = 0;
1457   /* Start with the octet string. */
1458   p = store_tag_length (p, TAG_OCTET_STRING, octstrlen);
1459   p = store_tag_length (p, TAG_SEQUENCE, inseqlen);
1460   /* Store the key parameters. */
1461   *p++ = TAG_INTEGER;
1462   *p++ = 1;
1463   *p++ = 0;
1464   for (i=0; kparms[i]; i++)
1465     {
1466       n = 0;
1467       rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, kparms[i]);
1468       if (rc)
1469         {
1470           log_error ("oops: error formatting parameter: %s\n",
1471                      gpg_strerror (rc));
1472           gcry_free (plain);
1473           return NULL;
1474         }
1475       p = store_tag_length (p, TAG_INTEGER, n);
1476       
1477       n = plain + needed - p;
1478       rc = gcry_mpi_print (GCRYMPI_FMT_STD, p, n, &n, kparms[i]);
1479       if (rc)
1480         {
1481           log_error ("oops: error storing parameter: %s\n",
1482                      gpg_strerror (rc));
1483           gcry_free (plain);
1484           return NULL;
1485         }
1486       p += n;
1487     }
1488
1489   plainlen = p - plain;
1490   assert (needed == plainlen);
1491   /* Append some pad characters; we already allocated extra space. */
1492   n = 8 - plainlen % 8;
1493   for (i=0; i < n; i++, plainlen++)
1494     *p++ = n;
1495
1496   *r_length = plainlen;
1497   return plain;
1498 }
1499
1500
1501
1502 static unsigned char *
1503 build_key_bag (unsigned char *buffer, size_t buflen, char *salt,
1504                size_t *r_length)
1505 {
1506   size_t len[11], needed;
1507   unsigned char *p, *keybag;
1508   size_t keybaglen;
1509
1510   /* Walk 11 steps down to collect the info: */
1511
1512   /* 10. The data goes into an octet string. */
1513   needed = compute_tag_length (buflen);
1514   needed += buflen;
1515
1516   /* 9. Prepend the algorithm identifier. */
1517   needed += DIM (data_3desiter2048);
1518
1519   /* 8. Put a sequence around. */
1520   len[8] = needed;
1521   needed += compute_tag_length (needed);
1522
1523   /* 7. Prepend a [0] tag. */
1524   len[7] = needed;
1525   needed += compute_tag_length (needed);
1526
1527   /* 6. Prepend the shroudedKeyBag OID. */
1528   needed += 2 + DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag);
1529
1530   /* 5+4. Put all into two sequences. */
1531   len[5] = needed;
1532   needed += compute_tag_length ( needed);
1533   len[4] = needed;
1534   needed += compute_tag_length (needed);
1535
1536   /* 3. This all goes into an octet string. */
1537   len[3] = needed;
1538   needed += compute_tag_length (needed);
1539
1540   /* 2. Prepend another [0] tag. */
1541   len[2] = needed;
1542   needed += compute_tag_length (needed);
1543
1544   /* 1. Prepend the data OID. */
1545   needed += 2 + DIM (oid_data);
1546
1547   /* 0. Prepend another sequence. */
1548   len[0] = needed;
1549   needed += compute_tag_length (needed);
1550
1551   /* Now that we have all length information, allocate a buffer. */
1552   p = keybag = gcry_malloc (needed);
1553   if (!keybag)
1554     {
1555       log_error ("error allocating buffer\n");
1556       return NULL;
1557     }
1558
1559   /* Walk 11 steps up to store the data. */
1560
1561   /* 0. Store the first sequence. */
1562   p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1563
1564   /* 1. Store the data OID. */
1565   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
1566   memcpy (p, oid_data, DIM (oid_data)); 
1567   p += DIM (oid_data); 
1568
1569   /* 2. Store a [0] tag. */
1570   p = store_tag_length (p, 0xa0, len[2]);
1571
1572   /* 3. And an octet string. */
1573   p = store_tag_length (p, TAG_OCTET_STRING, len[3]);
1574
1575   /* 4+5. Two sequences. */
1576   p = store_tag_length (p, TAG_SEQUENCE, len[4]);
1577   p = store_tag_length (p, TAG_SEQUENCE, len[5]);
1578
1579   /* 6. Store the shroudedKeyBag OID. */
1580   p = store_tag_length (p, TAG_OBJECT_ID,
1581                         DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag));
1582   memcpy (p, oid_pkcs_12_pkcs_8ShroudedKeyBag,
1583           DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag)); 
1584   p += DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag); 
1585
1586   /* 7. Store a [0] tag. */
1587   p = store_tag_length (p, 0xa0, len[7]);
1588
1589   /* 8. Store a sequence. */
1590   p = store_tag_length (p, TAG_SEQUENCE, len[8]);
1591
1592   /* 9. Now for the pre-encoded algorithm identifier and the salt. */
1593   memcpy (p, data_3desiter2048, DIM (data_3desiter2048));
1594   memcpy (p + DATA_3DESITER2048_SALT_OFF, salt, 8);
1595   p += DIM (data_3desiter2048);
1596
1597   /* 10. And finally the octet string with the encrypted data. */
1598   p = store_tag_length (p, TAG_OCTET_STRING, buflen);
1599   memcpy (p, buffer, buflen);
1600   p += buflen;
1601   keybaglen = p - keybag;
1602   
1603   if (needed != keybaglen)
1604     log_debug ("length mismatch: %lu, %lu\n",
1605                (unsigned long)needed, (unsigned long)keybaglen);
1606   
1607   *r_length = keybaglen;
1608   return keybag;
1609 }
1610
1611
1612 static unsigned char *
1613 build_cert_bag (unsigned char *buffer, size_t buflen, char *salt,
1614                 size_t *r_length)
1615 {
1616   size_t len[9], needed;
1617   unsigned char *p, *certbag;
1618   size_t certbaglen;
1619
1620   /* Walk 9 steps down to collect the info: */
1621
1622   /* 8. The data goes into an octet string. */
1623   needed = compute_tag_length (buflen);
1624   needed += buflen;
1625
1626   /* 7. The algorithm identifier. */
1627   needed += DIM (data_rc2iter2048);
1628
1629   /* 6. The data OID. */
1630   needed += 2 + DIM (oid_data);
1631
1632   /* 5. A sequence. */
1633   len[5] = needed;
1634   needed += compute_tag_length ( needed);
1635
1636   /* 4. An integer. */
1637   needed += 3;
1638
1639   /* 3. A sequence. */
1640   len[3] = needed;
1641   needed += compute_tag_length (needed);
1642
1643   /* 2.  A [0] tag. */
1644   len[2] = needed;
1645   needed += compute_tag_length (needed);
1646
1647   /* 1. The encryptedData OID. */
1648   needed += 2 + DIM (oid_encryptedData);
1649
1650   /* 0. The first sequence. */
1651   len[0] = needed;
1652   needed += compute_tag_length (needed);
1653
1654   /* Now that we have all length information, allocate a buffer. */
1655   p = certbag = gcry_malloc (needed);
1656   if (!certbag)
1657     {
1658       log_error ("error allocating buffer\n");
1659       return NULL;
1660     }
1661
1662   /* Walk 9 steps up to store the data. */
1663
1664   /* 0. Store the first sequence. */
1665   p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1666
1667   /* 1. Store the encryptedData OID. */
1668   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_encryptedData));
1669   memcpy (p, oid_encryptedData, DIM (oid_encryptedData)); 
1670   p += DIM (oid_encryptedData); 
1671
1672   /* 2. Store a [0] tag. */
1673   p = store_tag_length (p, 0xa0, len[2]);
1674
1675   /* 3. Store a sequence. */
1676   p = store_tag_length (p, TAG_SEQUENCE, len[3]);
1677
1678   /* 4. Store the integer 0. */
1679   *p++ = TAG_INTEGER;
1680   *p++ = 1; 
1681   *p++ = 0;
1682
1683   /* 5. Store a sequence. */
1684   p = store_tag_length (p, TAG_SEQUENCE, len[5]);
1685
1686   /* 6. Store the data OID. */
1687   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
1688   memcpy (p, oid_data, DIM (oid_data)); 
1689   p += DIM (oid_data); 
1690
1691   /* 7. Now for the pre-encoded algorithm identifier and the salt. */
1692   memcpy (p, data_rc2iter2048, DIM (data_rc2iter2048));
1693   memcpy (p + DATA_RC2ITER2048_SALT_OFF, salt, 8);
1694   p += DIM (data_rc2iter2048);
1695
1696   /* 8. And finally the [0] tag with the encrypted data. */
1697   p = store_tag_length (p, 0x80, buflen);
1698   memcpy (p, buffer, buflen);
1699   p += buflen;
1700   certbaglen = p - certbag;
1701   
1702   if (needed != certbaglen)
1703     log_debug ("length mismatch: %lu, %lu\n",
1704                (unsigned long)needed, (unsigned long)certbaglen);
1705
1706   *r_length = certbaglen;
1707   return certbag;
1708 }
1709
1710
1711 static unsigned char *
1712 build_cert_sequence (unsigned char *buffer, size_t buflen, size_t *r_length)
1713 {
1714   size_t len[8], needed, n;
1715   unsigned char *p, *certseq;
1716   size_t certseqlen;
1717   int i;
1718
1719   /* Walk 8 steps down to collect the info: */
1720
1721   /* 7. The data goes into an octet string. */
1722   needed = compute_tag_length (buflen);
1723   needed += buflen;
1724
1725   /* 6. A [0] tag. */
1726   len[6] = needed;
1727   needed += compute_tag_length (needed);
1728
1729   /* 5. An OID. */
1730   needed += 2 + DIM (oid_x509Certificate_for_pkcs_12);
1731
1732   /* 4. A sequence. */
1733   len[4] = needed;
1734   needed += compute_tag_length (needed);
1735
1736   /* 3. A [0] tag. */
1737   len[3] = needed;
1738   needed += compute_tag_length (needed);
1739
1740   /* 2. An OID. */
1741   needed += 2 + DIM (oid_pkcs_12_CertBag);
1742
1743   /* 1. A sequence. */
1744   len[1] = needed;
1745   needed += compute_tag_length (needed);
1746
1747   /* 0. The first sequence. */
1748   len[0] = needed;
1749   needed += compute_tag_length (needed);
1750
1751   /* Now that we have all length information, allocate a buffer. */
1752   p = certseq = gcry_malloc (needed + 8 /*(for padding)*/);
1753   if (!certseq)
1754     {
1755       log_error ("error allocating buffer\n");
1756       return NULL;
1757     }
1758
1759   /* Walk 8 steps up to store the data. */
1760
1761   /* 0. Store the first sequence. */
1762   p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1763
1764   /* 1. Store the second sequence. */
1765   p = store_tag_length (p, TAG_SEQUENCE, len[1]);
1766
1767   /* 2. Store the pkcs12-cert-bag OID. */
1768   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_pkcs_12_CertBag));
1769   memcpy (p, oid_pkcs_12_CertBag, DIM (oid_pkcs_12_CertBag)); 
1770   p += DIM (oid_pkcs_12_CertBag); 
1771
1772   /* 3. Store a [0] tag. */
1773   p = store_tag_length (p, 0xa0, len[3]);
1774
1775   /* 4. Store a sequence. */
1776   p = store_tag_length (p, TAG_SEQUENCE, len[4]);
1777
1778   /* 5. Store the x509Certificate OID. */
1779   p = store_tag_length (p, TAG_OBJECT_ID,
1780                         DIM (oid_x509Certificate_for_pkcs_12));
1781   memcpy (p, oid_x509Certificate_for_pkcs_12,
1782           DIM (oid_x509Certificate_for_pkcs_12)); 
1783   p += DIM (oid_x509Certificate_for_pkcs_12); 
1784
1785   /* 6. Store a [0] tag. */
1786   p = store_tag_length (p, 0xa0, len[6]);
1787
1788   /* 7. And finally the octet string with the actual certificate. */
1789   p = store_tag_length (p, TAG_OCTET_STRING, buflen);
1790   memcpy (p, buffer, buflen);
1791   p += buflen;
1792   certseqlen = p - certseq;
1793   
1794   if (needed != certseqlen)
1795     log_debug ("length mismatch: %lu, %lu\n",
1796                (unsigned long)needed, (unsigned long)certseqlen);
1797   
1798   /* Append some pad characters; we already allocated extra space. */
1799   n = 8 - certseqlen % 8;
1800   for (i=0; i < n; i++, certseqlen++)
1801     *p++ = n;
1802   
1803   *r_length = certseqlen;
1804   return certseq;
1805 }
1806
1807
1808 /* Expect the RSA key parameters in KPARMS and a password in
1809    PW. Create a PKCS structure from it and return it as well as the
1810    length in R_LENGTH; return NULL in case of an error. */
1811 unsigned char * 
1812 p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen,
1813            const char *pw, size_t *r_length)
1814 {
1815   unsigned char *buffer;
1816   size_t n, buflen;
1817   char salt[8];
1818   struct buffer_s seqlist[3];
1819   int seqlistidx = 0;
1820
1821   n = buflen = 0; /* (avoid compiler warning). */
1822
1823   if (cert && certlen)
1824     {
1825       /* Encode the certificate. */
1826       buffer = build_cert_sequence (cert, certlen, &buflen);
1827       if (!buffer)
1828         goto failure;
1829
1830       /* Encrypt it. */
1831       gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
1832       crypt_block (buffer, buflen, salt, 8, 2048, pw,
1833                    GCRY_CIPHER_RFC2268_40, 1);
1834       
1835       /* Encode the encrypted stuff into a bag. */
1836       seqlist[seqlistidx].buffer = build_cert_bag (buffer, buflen, salt, &n);
1837       seqlist[seqlistidx].length = n;
1838       gcry_free (buffer);
1839       buffer = NULL;
1840       if (!seqlist[seqlistidx].buffer)
1841         goto failure;
1842       seqlistidx++;
1843     }
1844
1845   if (kparms)
1846     {
1847       /* Encode the key. */
1848       buffer = build_key_sequence (kparms, &buflen);
1849       if (!buffer)
1850         goto failure;
1851       
1852       /* Encrypt it. */
1853       gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
1854       crypt_block (buffer, buflen, salt, 8, 2048, pw, GCRY_CIPHER_3DES, 1);
1855
1856       /* Encode the encrypted stuff into a bag. */
1857       seqlist[seqlistidx].buffer = build_key_bag (buffer, buflen, salt, &n);
1858       seqlist[seqlistidx].length = n;
1859       gcry_free (buffer);
1860       buffer = NULL;
1861       if (!seqlist[seqlistidx].buffer)
1862         goto failure;
1863       seqlistidx++;
1864     }
1865
1866   seqlist[seqlistidx].buffer = NULL;
1867   seqlist[seqlistidx].length = 0;
1868
1869   buffer = create_final (seqlist, pw, &buflen);
1870
1871  failure:
1872   for ( ; seqlistidx; seqlistidx--)
1873     gcry_free (seqlist[seqlistidx].buffer);
1874
1875   *r_length = buffer? buflen : 0;
1876   return buffer;
1877 }
1878
1879
1880 #ifdef TEST
1881
1882 static void 
1883 cert_cb (void *opaque, const unsigned char *cert, size_t certlen)
1884 {
1885   printf ("got a certificate of %u bytes length\n", certlen);
1886 }
1887
1888 int
1889 main (int argc, char **argv)
1890 {
1891   FILE *fp;
1892   struct stat st;
1893   unsigned char *buf;
1894   size_t buflen;
1895   gcry_mpi_t *result;
1896
1897   if (argc != 3)
1898     {
1899       fprintf (stderr, "usage: testp12 file passphrase\n");
1900       return 1;
1901     }
1902
1903   gcry_control (GCRYCTL_DISABLE_SECMEM, NULL);
1904   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL);
1905
1906   fp = fopen (argv[1], "rb");
1907   if (!fp)
1908     {
1909       fprintf (stderr, "can't open `%s': %s\n", argv[1], strerror (errno));
1910       return 1;
1911     }
1912   
1913   if (fstat (fileno(fp), &st))
1914     {
1915       fprintf (stderr, "can't stat `%s': %s\n", argv[1], strerror (errno));
1916       return 1;
1917     }
1918
1919   buflen = st.st_size;
1920   buf = gcry_malloc (buflen+1);
1921   if (!buf || fread (buf, buflen, 1, fp) != 1)
1922     {
1923       fprintf (stderr, "error reading `%s': %s\n", argv[1], strerror (errno));
1924       return 1;
1925     }
1926   fclose (fp);
1927
1928   result = p12_parse (buf, buflen, argv[2], cert_cb, NULL);
1929   if (result)
1930     {
1931       int i, rc;
1932       unsigned char *tmpbuf;
1933
1934       for (i=0; result[i]; i++)
1935         {
1936           rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &tmpbuf,
1937                                 NULL, result[i]);
1938           if (rc)
1939             printf ("%d: [error printing number: %s]\n",
1940                     i, gpg_strerror (rc));
1941           else
1942             {
1943               printf ("%d: %s\n", i, tmpbuf);
1944               gcry_free (tmpbuf);
1945             }
1946         }
1947     }
1948
1949   return 0;
1950
1951 }
1952
1953 /*
1954 Local Variables:
1955 compile-command: "gcc -Wall -O -g -DTEST=1 -o minip12 minip12.c ../jnlib/libjnlib.a -L /usr/local/lib -lgcrypt -lgpg-error"
1956 End:
1957 */
1958 #endif /* TEST */