Enhanced last patch.
[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 3 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, see <http://www.gnu.org/licenses/>.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <assert.h>
27 #include <gcrypt.h>
28 #include <errno.h>
29
30 #ifdef TEST
31 #include <sys/stat.h>
32 #include <unistd.h>
33 #endif
34
35 #include "../jnlib/logging.h"
36 #include "../jnlib/utf8conv.h"
37 #include "minip12.h"
38
39 #ifndef DIM
40 #define DIM(v)               (sizeof(v)/sizeof((v)[0]))
41 #endif
42
43
44 enum
45 {
46   UNIVERSAL = 0,
47   APPLICATION = 1,
48   ASNCONTEXT = 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_keyBag[11] = {
92   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x01 };
93 static unsigned char const oid_pkcs_12_pkcs_8ShroudedKeyBag[11] = {
94   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x02 };
95 static unsigned char const oid_pkcs_12_CertBag[11] = {
96   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x03 };
97 static unsigned char const oid_pkcs_12_CrlBag[11] = {
98   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x04 };
99
100 static unsigned char const oid_pbeWithSHAAnd3_KeyTripleDES_CBC[10] = {
101   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03 };
102 static unsigned char const oid_pbeWithSHAAnd40BitRC2_CBC[10] = {
103   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x06 };
104 static unsigned char const oid_x509Certificate_for_pkcs_12[10] = {
105   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x16, 0x01 };
106
107
108 static unsigned char const oid_rsaEncryption[9] = {
109   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 };
110
111
112 static unsigned char const data_3desiter2048[30] = {
113   0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86,
114   0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30, 0x0E, 
115   0x04, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
116   0xFF, 0xFF, 0x02, 0x02, 0x08, 0x00 };
117 #define DATA_3DESITER2048_SALT_OFF  18
118
119 static unsigned char const data_rc2iter2048[30] = {
120   0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86,
121   0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x06, 0x30, 0x0E, 
122   0x04, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
123   0xFF, 0xFF, 0x02, 0x02, 0x08, 0x00 };
124 #define DATA_RC2ITER2048_SALT_OFF  18
125
126 static unsigned char const data_mactemplate[51] = {
127   0x30, 0x31, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
128   0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04,
129   0x14, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
130   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
131   0xff, 0xff, 0xff, 0xff, 0xff, 0x04, 0x08, 0xff,
132   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02,
133   0x02, 0x08, 0x00 }; 
134 #define DATA_MACTEMPLATE_MAC_OFF 17
135 #define DATA_MACTEMPLATE_SALT_OFF 39
136
137 static unsigned char const data_attrtemplate[106] = {
138   0x31, 0x7c, 0x30, 0x55, 0x06, 0x09, 0x2a, 0x86,
139   0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x14, 0x31,
140   0x48, 0x1e, 0x46, 0x00, 0x47, 0x00, 0x6e, 0x00,
141   0x75, 0x00, 0x50, 0x00, 0x47, 0x00, 0x20, 0x00,
142   0x65, 0x00, 0x78, 0x00, 0x70, 0x00, 0x6f, 0x00,
143   0x72, 0x00, 0x74, 0x00, 0x65, 0x00, 0x64, 0x00,
144   0x20, 0x00, 0x63, 0x00, 0x65, 0x00, 0x72, 0x00,
145   0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00,
146   0x63, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00,
147   0x20, 0x00, 0x66, 0x00, 0x66, 0x00, 0x66, 0x00,
148   0x66, 0x00, 0x66, 0x00, 0x66, 0x00, 0x66, 0x00,
149   0x66, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48,
150   0x86, 0xf7, 0x0d, 0x01, 0x09, 0x15, 0x31, 0x16,
151   0x04, 0x14 }; /* Need to append SHA-1 digest. */
152 #define DATA_ATTRTEMPLATE_KEYID_OFF 73
153
154 struct buffer_s 
155 {
156   unsigned char *buffer;
157   size_t length;
158 };  
159
160
161 struct tag_info 
162 {
163   int class;
164   int is_constructed;
165   unsigned long tag;
166   unsigned long length;  /* length part of the TLV */
167   int nhdr;
168   int ndef;              /* It is an indefinite length */
169 };
170
171
172 /* Parse the buffer at the address BUFFER which is of SIZE and return
173    the tag and the length part from the TLV triplet.  Update BUFFER
174    and SIZE on success.  Checks that the encoded length does not
175    exhaust the length of the provided buffer. */
176 static int 
177 parse_tag (unsigned char const **buffer, size_t *size, struct tag_info *ti)
178 {
179   int c;
180   unsigned long tag;
181   const unsigned char *buf = *buffer;
182   size_t length = *size;
183
184   ti->length = 0;
185   ti->ndef = 0;
186   ti->nhdr = 0;
187
188   /* Get the tag */
189   if (!length)
190     return -1; /* premature eof */
191   c = *buf++; length--;
192   ti->nhdr++;
193
194   ti->class = (c & 0xc0) >> 6;
195   ti->is_constructed = !!(c & 0x20);
196   tag = c & 0x1f;
197
198   if (tag == 0x1f)
199     {
200       tag = 0;
201       do
202         {
203           tag <<= 7;
204           if (!length)
205             return -1; /* premature eof */
206           c = *buf++; length--;
207           ti->nhdr++;
208           tag |= c & 0x7f;
209         }
210       while (c & 0x80);
211     }
212   ti->tag = tag;
213
214   /* Get the length */
215   if (!length)
216     return -1; /* prematureeof */
217   c = *buf++; length--;
218   ti->nhdr++;
219
220   if ( !(c & 0x80) )
221     ti->length = c;
222   else if (c == 0x80)
223     ti->ndef = 1;
224   else if (c == 0xff)
225     return -1; /* forbidden length value */
226   else
227     {
228       unsigned long len = 0;
229       int count = c & 0x7f;
230
231       for (; count; count--)
232         {
233           len <<= 8;
234           if (!length)
235             return -1; /* premature_eof */
236           c = *buf++; length--;
237           ti->nhdr++;
238           len |= c & 0xff;
239         }
240       ti->length = len;
241     }
242   
243   if (ti->class == UNIVERSAL && !ti->tag)
244     ti->length = 0;
245
246   if (ti->length > length)
247     return -1; /* data larger than buffer. */
248   
249   *buffer = buf;
250   *size = length;
251   return 0;
252 }
253
254
255 /* Given an ASN.1 chunk of a structure like:
256
257      24 NDEF:       OCTET STRING  -- This is not passed to us
258      04    1:         OCTET STRING  -- INPUT point s to here
259             :           30
260      04    1:         OCTET STRING
261             :           80
262           [...]
263      04    2:         OCTET STRING
264             :           00 00
265             :         } -- This denotes a Null tag and are the last 
266                         -- two bytes in INPUT.
267    
268    Create a new buffer with the content of that octet string.  INPUT
269    is the orginal buffer with a length as stored at LENGTH.  Returns
270    NULL on error or a new malloced buffer with the length of this new
271    buffer stored at LENGTH and the number of bytes parsed from input
272    are added to the value stored at INPUT_CONSUMED.  INPUT_CONSUMED is
273    allowed to be passed as NULL if the caller is not interested in
274    this value. */
275 static unsigned char *
276 cram_octet_string (const unsigned char *input, size_t *length,
277                    size_t *input_consumed)
278 {
279   const unsigned char *s = input;
280   size_t n = *length;
281   unsigned char *output, *d;
282   struct tag_info ti;
283
284   /* Allocate output buf.  We know that it won't be longer than the
285      input buffer. */
286   d = output = gcry_malloc (n);
287   if (!output)
288     goto bailout;
289
290   for (;;)
291     {
292       if (parse_tag (&s, &n, &ti))
293         goto bailout;
294       if (ti.class == UNIVERSAL && ti.tag == TAG_OCTET_STRING 
295           && !ti.ndef && !ti.is_constructed)
296         {
297           memcpy (d, s, ti.length);
298           s += ti.length;
299           d += ti.length;
300           n -= ti.length;
301         }
302       else if (ti.class == UNIVERSAL && !ti.tag && !ti.is_constructed)
303         break; /* Ready */ 
304       else
305         goto bailout;
306     }
307
308
309   *length = d - output;
310   if (input_consumed)
311     *input_consumed += s - input;
312   return output;
313
314  bailout:
315   if (input_consumed)
316     *input_consumed += s - input;
317   gcry_free (output);
318   return NULL;
319 }
320
321
322
323 static int 
324 string_to_key (int id, char *salt, size_t saltlen, int iter, const char *pw,
325                int req_keylen, unsigned char *keybuf)
326 {
327   int rc, i, j;
328   gcry_md_hd_t md;
329   gcry_mpi_t num_b1 = NULL;
330   int pwlen;
331   unsigned char hash[20], buf_b[64], buf_i[128], *p;
332   size_t cur_keylen;
333   size_t n;
334
335   cur_keylen = 0;
336   pwlen = strlen (pw);
337   if (pwlen > 63/2)
338     {
339       log_error ("password too long\n");
340       return -1;
341     }
342
343   if (saltlen < 8)
344     {
345       log_error ("salt too short\n");
346       return -1;
347     }
348   
349   /* Store salt and password in BUF_I */
350   p = buf_i;
351   for(i=0; i < 64; i++)
352     *p++ = salt [i%saltlen];
353   for(i=j=0; i < 64; i += 2)
354     {
355       *p++ = 0;
356       *p++ = pw[j];
357       if (++j > pwlen) /* Note, that we include the trailing zero */
358         j = 0;
359     }
360
361   for (;;)
362     {
363       rc = gcry_md_open (&md, GCRY_MD_SHA1, 0);
364       if (rc)
365         {
366           log_error ( "gcry_md_open failed: %s\n", gpg_strerror (rc));
367           return rc;
368         }
369       for(i=0; i < 64; i++)
370         gcry_md_putc (md, id);
371       gcry_md_write (md, buf_i, 128);
372       memcpy (hash, gcry_md_read (md, 0), 20);
373       gcry_md_close (md);
374       for (i=1; i < iter; i++)
375         gcry_md_hash_buffer (GCRY_MD_SHA1, hash, hash, 20);
376
377       for (i=0; i < 20 && cur_keylen < req_keylen; i++)
378         keybuf[cur_keylen++] = hash[i];
379       if (cur_keylen == req_keylen)
380         {
381           gcry_mpi_release (num_b1);
382           return 0; /* ready */
383         }
384       
385       /* need more bytes. */
386       for(i=0; i < 64; i++)
387         buf_b[i] = hash[i % 20];
388       rc = gcry_mpi_scan (&num_b1, GCRYMPI_FMT_USG, buf_b, 64, &n);
389       if (rc)
390         {
391           log_error ( "gcry_mpi_scan failed: %s\n", gpg_strerror (rc));
392           return -1;
393         }
394       gcry_mpi_add_ui (num_b1, num_b1, 1);
395       for (i=0; i < 128; i += 64)
396         {
397           gcry_mpi_t num_ij;
398
399           rc = gcry_mpi_scan (&num_ij, GCRYMPI_FMT_USG, buf_i + i, 64, &n);
400           if (rc)
401             {
402               log_error ( "gcry_mpi_scan failed: %s\n",
403                        gpg_strerror (rc));
404               return -1;
405             }
406           gcry_mpi_add (num_ij, num_ij, num_b1);
407           gcry_mpi_clear_highbit (num_ij, 64*8);
408           rc = gcry_mpi_print (GCRYMPI_FMT_USG, buf_i + i, 64, &n, num_ij);
409           if (rc)
410             {
411               log_error ( "gcry_mpi_print failed: %s\n",
412                           gpg_strerror (rc));
413               return -1;
414             }
415           gcry_mpi_release (num_ij);
416         }
417     }
418 }
419
420
421 static int 
422 set_key_iv (gcry_cipher_hd_t chd, char *salt, size_t saltlen, int iter,
423             const char *pw, int keybytes)
424 {
425   unsigned char keybuf[24];
426   int rc;
427
428   assert (keybytes == 5 || keybytes == 24);
429   if (string_to_key (1, salt, saltlen, iter, pw, keybytes, keybuf))
430     return -1;
431   rc = gcry_cipher_setkey (chd, keybuf, keybytes);
432   if (rc)
433     {
434       log_error ( "gcry_cipher_setkey failed: %s\n", gpg_strerror (rc));
435       return -1;
436     }
437
438   if (string_to_key (2, salt, saltlen, iter, pw, 8, keybuf))
439     return -1;
440   rc = gcry_cipher_setiv (chd, keybuf, 8);
441   if (rc)
442     {
443       log_error ("gcry_cipher_setiv failed: %s\n", gpg_strerror (rc));
444       return -1;
445     }
446   return 0;
447 }
448
449
450 static void
451 crypt_block (unsigned char *buffer, size_t length, char *salt, size_t saltlen,
452              int iter, const char *pw, int cipher_algo, int encrypt)
453 {
454   gcry_cipher_hd_t chd;
455   int rc;
456
457   rc = gcry_cipher_open (&chd, cipher_algo, GCRY_CIPHER_MODE_CBC, 0); 
458   if (rc)
459     {
460       log_error ( "gcry_cipher_open failed: %s\n", gpg_strerror(rc));
461       wipememory (buffer, length);
462       return;
463     }
464   if (set_key_iv (chd, salt, saltlen, iter, pw,
465                   cipher_algo == GCRY_CIPHER_RFC2268_40? 5:24))
466     {
467       wipememory (buffer, length);
468       goto leave;
469     }
470
471   rc = encrypt? gcry_cipher_encrypt (chd, buffer, length, NULL, 0)
472               : gcry_cipher_decrypt (chd, buffer, length, NULL, 0);
473
474   if (rc)
475     {
476       wipememory (buffer, length);
477       log_error ( "en/de-crytion failed: %s\n", gpg_strerror (rc));
478       goto leave;
479     }
480
481  leave:
482   gcry_cipher_close (chd);
483 }
484   
485
486 /* Decrypt a block of data and try several encodings of the key.
487    CIPHERTEXT is the encrypted data of size LENGTH bytes; PLAINTEXT is
488    a buffer of the same size to receive the decryption result. SALT,
489    SALTLEN, ITER and PW are the information required for decryption
490    and CIPHER_ALGO is the algorithm id to use.  CHECK_FNC is a
491    function called with the plaintext and used to check whether the
492    decryption succeeded; i.e. that a correct passphrase has been
493    given.  That function shall return true if the decryption has likely
494    succeeded. */
495 static void
496 decrypt_block (const void *ciphertext, unsigned char *plaintext, size_t length,
497                char *salt, size_t saltlen,
498                int iter, const char *pw, int cipher_algo,
499                int (*check_fnc) (const void *, size_t))
500 {
501   static const char * const charsets[] = {
502     "",   /* No conversion - use the UTF-8 passphrase direct.  */
503     "ISO-8859-1",
504     "ISO-8859-15",
505     "ISO-8859-2",
506     "ISO-8859-3",
507     "ISO-8859-4",
508     "ISO-8859-5",
509     "ISO-8859-6",
510     "ISO-8859-7",
511     "ISO-8859-8",
512     "ISO-8859-9",
513     "KOI8-R",
514     "IBM437",
515     "IBM850",
516     "EUC-JP",
517     "BIG5",
518     NULL
519   };
520   int charsetidx = 0;
521   char *convertedpw = NULL;   /* Malloced and converted password or NULL.  */
522   size_t convertedpwsize = 0; /* Allocated length.  */
523
524   for (charsetidx=0; charsets[charsetidx]; charsetidx++)
525     {
526       if (*charsets[charsetidx])
527         {
528           jnlib_iconv_t cd;
529           const char *inptr;
530           char *outptr;
531           size_t inbytes, outbytes;
532
533           if (!convertedpw)
534             {
535               /* We assume one byte encodings.  Thus we can allocate
536                  the buffer of the same size as the original
537                  passphrase; the result will actually be shorter
538                  then.  */
539               convertedpwsize = strlen (pw) + 1;
540               convertedpw = gcry_malloc_secure (convertedpwsize);
541               if (!convertedpw)
542                 {
543                   log_info ("out of secure memory while"
544                             " converting passphrase\n");
545                   break; /* Give up.  */
546                 }
547             }
548
549           cd = jnlib_iconv_open (charsets[charsetidx], "utf-8");
550           if (cd == (jnlib_iconv_t)(-1))
551             continue;
552
553           inptr = pw;
554           inbytes = strlen (pw);
555           outptr = convertedpw;
556           outbytes = convertedpwsize - 1;
557           if ( jnlib_iconv (cd, (const char **)&inptr, &inbytes,
558                       &outptr, &outbytes) == (size_t)-1) 
559             {
560               jnlib_iconv_close (cd);
561               continue;
562             }
563           *outptr = 0;
564           jnlib_iconv_close (cd);
565           log_info ("decryption failed; trying charset `%s'\n",
566                     charsets[charsetidx]);
567         }
568       memcpy (plaintext, ciphertext, length);
569       crypt_block (plaintext, length, salt, saltlen, iter,
570                    convertedpw? convertedpw:pw, cipher_algo, 0);
571       if (check_fnc (plaintext, length))
572         break; /* Decryption succeeded. */
573     }
574   gcry_free (convertedpw);
575 }
576
577
578 /* Return true if the decryption of an bag_encrypted_data object has
579    likely succeeded.  */
580 static int
581 bag_decrypted_data_p (const void *plaintext, size_t length)
582 {
583   struct tag_info ti;
584   const unsigned char *p = plaintext;
585   size_t n = length;
586
587   /*   { */
588   /* #  warning debug code is enabled */
589   /*     FILE *fp = fopen ("tmp-rc2-plain.der", "wb"); */
590   /*     if (!fp || fwrite (p, n, 1, fp) != 1) */
591   /*       exit (2); */
592   /*     fclose (fp); */
593   /*   } */
594   
595   if (parse_tag (&p, &n, &ti))
596     return 0;
597   if (ti.class || ti.tag != TAG_SEQUENCE)
598     return 0;
599   if (parse_tag (&p, &n, &ti))
600     return 0;
601
602   return 1; 
603 }
604
605 /* Note: If R_RESULT is passed as NULL, a key object as already be
606    processed and thus we need to skip it here. */
607 static int
608 parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
609                           int startoffset, size_t *r_consumed, const char *pw,
610                           void (*certcb)(void*, const unsigned char*, size_t),
611                           void *certcbarg, gcry_mpi_t **r_result)
612 {
613   struct tag_info ti;
614   const unsigned char *p = buffer;
615   const unsigned char *p_start = buffer;
616   size_t n = length;
617   const char *where;
618   char salt[20];
619   size_t saltlen;
620   unsigned int iter;
621   unsigned char *plain = NULL;
622   int bad_pass = 0;
623   unsigned char *cram_buffer = NULL;
624   size_t consumed = 0; /* Number of bytes consumed from the orginal buffer. */
625   int is_3des = 0;
626   gcry_mpi_t *result = NULL;
627   int result_count;
628
629   if (r_result)
630     *r_result = NULL;
631   where = "start";
632   if (parse_tag (&p, &n, &ti))
633     goto bailout;
634   if (ti.class != ASNCONTEXT || ti.tag)
635     goto bailout;
636   if (parse_tag (&p, &n, &ti))
637     goto bailout;
638   if (ti.tag != TAG_SEQUENCE)
639     goto bailout;
640
641   where = "bag.encryptedData.version";
642   if (parse_tag (&p, &n, &ti))
643     goto bailout;
644   if (ti.tag != TAG_INTEGER || ti.length != 1 || *p != 0)
645     goto bailout;
646   p++; n--;
647   if (parse_tag (&p, &n, &ti))
648     goto bailout;
649   if (ti.tag != TAG_SEQUENCE)
650     goto bailout;
651
652   where = "bag.encryptedData.data";
653   if (parse_tag (&p, &n, &ti))
654     goto bailout;
655   if (ti.tag != TAG_OBJECT_ID || ti.length != DIM(oid_data)
656       || memcmp (p, oid_data, DIM(oid_data)))
657     goto bailout;
658   p += DIM(oid_data);
659   n -= DIM(oid_data);
660
661   where = "bag.encryptedData.keyinfo";
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_OBJECT_ID 
669       && ti.length == DIM(oid_pbeWithSHAAnd40BitRC2_CBC)
670       && !memcmp (p, oid_pbeWithSHAAnd40BitRC2_CBC,
671                   DIM(oid_pbeWithSHAAnd40BitRC2_CBC)))
672     {
673       p += DIM(oid_pbeWithSHAAnd40BitRC2_CBC);
674       n -= DIM(oid_pbeWithSHAAnd40BitRC2_CBC);
675     }
676   else if (!ti.class && ti.tag == TAG_OBJECT_ID 
677       && ti.length == DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)
678       && !memcmp (p, oid_pbeWithSHAAnd3_KeyTripleDES_CBC,
679                   DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)))
680     {
681       p += DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
682       n -= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
683       is_3des = 1;
684     }
685   else
686     goto bailout;
687
688   where = "rc2or3des-params";
689   if (parse_tag (&p, &n, &ti))
690     goto bailout;
691   if (ti.class || ti.tag != TAG_SEQUENCE)
692     goto bailout;
693   if (parse_tag (&p, &n, &ti))
694     goto bailout;
695   if (ti.class || ti.tag != TAG_OCTET_STRING
696       || ti.length < 8 || ti.length > 20 )
697     goto bailout;
698   saltlen = ti.length;
699   memcpy (salt, p, saltlen);
700   p += saltlen;
701   n -= saltlen;
702   if (parse_tag (&p, &n, &ti))
703     goto bailout;
704   if (ti.class || ti.tag != TAG_INTEGER || !ti.length )
705     goto bailout;
706   for (iter=0; ti.length; ti.length--)
707     {
708       iter <<= 8;
709       iter |= (*p++) & 0xff; 
710       n--;
711     }
712   
713   where = "rc2or3des-ciphertext";
714   if (parse_tag (&p, &n, &ti))
715     goto bailout;
716
717   consumed = p - p_start;
718   if (ti.class == ASNCONTEXT && ti.tag == 0 && ti.is_constructed && ti.ndef)
719     {
720       /* Mozilla exported certs now come with single byte chunks of
721          octect strings.  (Mozilla Firefox 1.0.4).  Arghh. */
722       where = "cram-rc2or3des-ciphertext";
723       cram_buffer = cram_octet_string ( p, &n, &consumed);
724       if (!cram_buffer)
725         goto bailout;
726       p = p_start = cram_buffer;
727       if (r_consumed)
728         *r_consumed = consumed;
729       r_consumed = NULL; /* Ugly hack to not update that value any further. */
730       ti.length = n;
731     }
732   else if (ti.class == ASNCONTEXT && ti.tag == 0 && ti.length )
733     ;
734   else
735     goto bailout;
736   
737   log_info ("%lu bytes of %s encrypted text\n",ti.length,is_3des?"3DES":"RC2");
738
739   plain = gcry_malloc_secure (ti.length);
740   if (!plain)
741     {
742       log_error ("error allocating decryption buffer\n");
743       goto bailout;
744     }
745   decrypt_block (p, plain, ti.length, salt, saltlen, iter, pw, 
746                  is_3des? GCRY_CIPHER_3DES : GCRY_CIPHER_RFC2268_40, 
747                  bag_decrypted_data_p);
748   n = ti.length;
749   startoffset = 0;
750   p_start = p = plain;
751
752   where = "outer.outer.seq";
753   if (parse_tag (&p, &n, &ti))
754     {
755       bad_pass = 1;
756       goto bailout;
757     }
758   if (ti.class || ti.tag != TAG_SEQUENCE)
759     {
760       bad_pass = 1;
761       goto bailout;
762     }
763
764   if (parse_tag (&p, &n, &ti))
765     {
766       bad_pass = 1;
767       goto bailout;
768     }
769
770   /* Loop over all certificates inside the bag. */
771   while (n)
772     {
773       int iscrlbag = 0;
774       int iskeybag = 0;
775
776       where = "certbag.nextcert";
777       if (ti.class || ti.tag != TAG_SEQUENCE)
778         goto bailout;
779
780       where = "certbag.objectidentifier";
781       if (parse_tag (&p, &n, &ti))
782         goto bailout;
783       if (ti.class || ti.tag != TAG_OBJECT_ID)
784         goto bailout;
785       if ( ti.length == DIM(oid_pkcs_12_CertBag)
786            && !memcmp (p, oid_pkcs_12_CertBag, DIM(oid_pkcs_12_CertBag)))
787         {
788           p += DIM(oid_pkcs_12_CertBag);
789           n -= DIM(oid_pkcs_12_CertBag);
790         }
791       else if ( ti.length == DIM(oid_pkcs_12_CrlBag)
792            && !memcmp (p, oid_pkcs_12_CrlBag, DIM(oid_pkcs_12_CrlBag)))
793         {
794           p += DIM(oid_pkcs_12_CrlBag);
795           n -= DIM(oid_pkcs_12_CrlBag);
796           iscrlbag = 1;
797         }
798       else if ( ti.length == DIM(oid_pkcs_12_keyBag)
799            && !memcmp (p, oid_pkcs_12_keyBag, DIM(oid_pkcs_12_keyBag)))
800         {
801           /* The TrustedMIME plugin for MS Outlook started to create
802              files with just one outer 3DES encrypted container and
803              inside the certificates as well as the key. */
804           p += DIM(oid_pkcs_12_keyBag);
805           n -= DIM(oid_pkcs_12_keyBag);
806           iskeybag = 1;
807         }
808       else
809         goto bailout;
810
811       where = "certbag.before.certheader";
812       if (parse_tag (&p, &n, &ti))
813         goto bailout;
814       if (ti.class != ASNCONTEXT || ti.tag)
815         goto bailout;
816       if (iscrlbag)
817         {
818           log_info ("skipping unsupported crlBag\n");
819           p += ti.length;
820           n -= ti.length;
821         }
822       else if (iskeybag && (result || !r_result))
823         {
824           log_info ("one keyBag already processed; skipping this one\n");
825           p += ti.length;
826           n -= ti.length;
827         }
828       else if (iskeybag)
829         {
830           int len;
831
832           log_info ("processing simple keyBag\n");
833
834           /* Fixme: This code is duplicated from parse_bag_data.  */
835           if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
836             goto bailout;
837           if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER
838               || ti.length != 1 || *p)
839             goto bailout;
840           p++; n--;
841           if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
842             goto bailout;
843           len = ti.length;
844           if (parse_tag (&p, &n, &ti))
845             goto bailout;
846           if (len < ti.nhdr)
847             goto bailout;
848           len -= ti.nhdr;
849           if (ti.class || ti.tag != TAG_OBJECT_ID
850               || ti.length != DIM(oid_rsaEncryption)
851               || memcmp (p, oid_rsaEncryption,
852                          DIM(oid_rsaEncryption)))
853             goto bailout;
854           p += DIM (oid_rsaEncryption);
855           n -= DIM (oid_rsaEncryption);
856           if (len < ti.length)
857             goto bailout;
858           len -= ti.length;
859           if (n < len)
860             goto bailout;
861           p += len;
862           n -= len;
863           if ( parse_tag (&p, &n, &ti)
864                || ti.class || ti.tag != TAG_OCTET_STRING)
865             goto bailout;
866           if ( parse_tag (&p, &n, &ti)
867                || ti.class || ti.tag != TAG_SEQUENCE)
868             goto bailout;
869           len = ti.length;
870
871           result = gcry_calloc (10, sizeof *result);
872           if (!result)
873             {
874               log_error ( "error allocating result array\n");
875               goto bailout;
876             }
877           result_count = 0;
878
879           where = "reading.keybag.key-parameters";
880           for (result_count = 0; len && result_count < 9;)
881             {
882               if ( parse_tag (&p, &n, &ti)
883                    || ti.class || ti.tag != TAG_INTEGER)
884                 goto bailout;
885               if (len < ti.nhdr)
886                 goto bailout;
887               len -= ti.nhdr;
888               if (len < ti.length)
889                 goto bailout;
890               len -= ti.length;
891               if (!result_count && ti.length == 1 && !*p)
892                 ; /* ignore the very first one if it is a 0 */
893               else 
894                 {
895                   int rc;
896
897                   rc = gcry_mpi_scan (result+result_count, GCRYMPI_FMT_USG, p,
898                                       ti.length, NULL);
899                   if (rc)
900                     {
901                       log_error ("error parsing key parameter: %s\n",
902                                  gpg_strerror (rc));
903                       goto bailout;
904                     }
905                   result_count++;
906                 }
907               p += ti.length;
908               n -= ti.length;
909             }
910           if (len)
911             goto bailout;
912         }
913       else
914         {
915           log_info ("processing certBag\n");
916           if (parse_tag (&p, &n, &ti))
917             goto bailout;
918           if (ti.class || ti.tag != TAG_SEQUENCE)
919             goto bailout;
920           if (parse_tag (&p, &n, &ti))
921             goto bailout;
922           if (ti.class || ti.tag != TAG_OBJECT_ID
923               || ti.length != DIM(oid_x509Certificate_for_pkcs_12)
924               || memcmp (p, oid_x509Certificate_for_pkcs_12,
925                          DIM(oid_x509Certificate_for_pkcs_12)))
926             goto bailout;
927           p += DIM(oid_x509Certificate_for_pkcs_12);
928           n -= DIM(oid_x509Certificate_for_pkcs_12);
929           
930           where = "certbag.before.octetstring";
931           if (parse_tag (&p, &n, &ti))
932             goto bailout;
933           if (ti.class != ASNCONTEXT || ti.tag)
934             goto bailout;
935           if (parse_tag (&p, &n, &ti))
936             goto bailout;
937           if (ti.class || ti.tag != TAG_OCTET_STRING || ti.ndef)
938             goto bailout;
939           
940           /* Return the certificate. */
941           if (certcb)
942             certcb (certcbarg, p, ti.length);
943    
944           p += ti.length;
945           n -= ti.length;
946         }
947
948       /* Ugly hack to cope with the padding: Forget about the rest if
949          that is less or equal to the cipher's block length.  We can
950          reasonable assume that all valid data will be longer than
951          just one block. */
952       if (n <= 8)
953         n = 0;  
954
955       /* Skip the optional SET with the pkcs12 cert attributes. */
956       if (n)
957         {
958           where = "bag.attributes";
959           if (parse_tag (&p, &n, &ti))
960             goto bailout;
961           if (!ti.class && ti.tag == TAG_SEQUENCE)
962             ; /* No attributes. */
963           else if (!ti.class && ti.tag == TAG_SET && !ti.ndef)
964             { /* The optional SET. */
965               p += ti.length;
966               n -= ti.length;
967               if (n <= 8)
968                 n = 0;
969               if (n && parse_tag (&p, &n, &ti))
970                 goto bailout;
971             }
972           else
973             goto bailout;
974         }
975     }
976   
977   if (r_consumed)
978     *r_consumed = consumed;
979   gcry_free (plain);
980   gcry_free (cram_buffer);
981   if (r_result)
982     *r_result = result;
983   return 0;
984
985  bailout:
986   if (result)
987     {
988       int i;
989
990       for (i=0; result[i]; i++)
991         gcry_mpi_release (result[i]);
992       gcry_free (result);
993     }
994   if (r_consumed)
995     *r_consumed = consumed;
996   gcry_free (plain);
997   gcry_free (cram_buffer);
998   log_error ("encryptedData error at \"%s\", offset %u\n",
999              where, (unsigned int)((p - p_start)+startoffset));
1000   if (bad_pass)
1001     {
1002       /* Note, that the following string might be used by other programs
1003          to check for a bad passphrase; it should therefore not be
1004          translated or changed. */
1005       log_error ("possibly bad passphrase given\n");
1006     }
1007   return -1;
1008 }
1009
1010
1011 /* Return true if the decryption of a bag_data object has likely
1012    succeeded.  */
1013 static int
1014 bag_data_p (const void *plaintext, size_t length)
1015 {
1016   struct tag_info ti;
1017   const unsigned char *p = plaintext;
1018   size_t n = length;
1019
1020 /*   { */
1021 /* #  warning debug code is enabled */
1022 /*     FILE *fp = fopen ("tmp-3des-plain-key.der", "wb"); */
1023 /*     if (!fp || fwrite (p, n, 1, fp) != 1) */
1024 /*       exit (2); */
1025 /*     fclose (fp); */
1026 /*   } */
1027
1028   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
1029     return 0;
1030   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER
1031       || ti.length != 1 || *p)
1032     return 0;
1033
1034   return 1; 
1035 }
1036
1037
1038 static gcry_mpi_t *
1039 parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
1040                 size_t *r_consumed, const char *pw)
1041 {
1042   int rc;
1043   struct tag_info ti;
1044   const unsigned char *p = buffer;
1045   const unsigned char *p_start = buffer;
1046   size_t n = length;
1047   const char *where;
1048   char salt[20];
1049   size_t saltlen;
1050   unsigned int iter;
1051   int len;
1052   unsigned char *plain = NULL;
1053   gcry_mpi_t *result = NULL;
1054   int result_count, i;
1055   unsigned char *cram_buffer = NULL;
1056   size_t consumed = 0; /* Number of bytes consumed from the orginal buffer. */
1057
1058   where = "start";
1059   if (parse_tag (&p, &n, &ti))
1060     goto bailout;
1061   if (ti.class != ASNCONTEXT || ti.tag)
1062     goto bailout;
1063   if (parse_tag (&p, &n, &ti))
1064     goto bailout;
1065   if (ti.class || ti.tag != TAG_OCTET_STRING)
1066     goto bailout;
1067
1068   consumed = p - p_start;
1069   if (ti.is_constructed && ti.ndef)
1070     {
1071       /* Mozilla exported certs now come with single byte chunks of
1072          octect strings.  (Mozilla Firefox 1.0.4).  Arghh. */
1073       where = "cram-data.outersegs";
1074       cram_buffer = cram_octet_string ( p, &n, &consumed);
1075       if (!cram_buffer)
1076         goto bailout;
1077       p = p_start = cram_buffer;
1078       if (r_consumed)
1079         *r_consumed = consumed;
1080       r_consumed = NULL; /* Ugly hack to not update that value any further. */
1081     }
1082   
1083
1084   where = "data.outerseqs";
1085   if (parse_tag (&p, &n, &ti))
1086     goto bailout;
1087   if (ti.class || ti.tag != TAG_SEQUENCE)
1088     goto bailout;
1089   if (parse_tag (&p, &n, &ti))
1090     goto bailout;
1091   if (ti.class || ti.tag != TAG_SEQUENCE)
1092     goto bailout;
1093
1094   where = "data.objectidentifier";
1095   if (parse_tag (&p, &n, &ti))
1096     goto bailout;
1097   if (ti.class || ti.tag != TAG_OBJECT_ID
1098       || ti.length != DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag)
1099       || memcmp (p, oid_pkcs_12_pkcs_8ShroudedKeyBag,
1100                  DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag)))
1101     goto bailout;
1102   p += DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag);
1103   n -= DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag);
1104
1105   where = "shrouded,outerseqs";
1106   if (parse_tag (&p, &n, &ti))
1107     goto bailout;
1108   if (ti.class != ASNCONTEXT || ti.tag)
1109     goto bailout;
1110   if (parse_tag (&p, &n, &ti))
1111     goto bailout;
1112   if (ti.class || ti.tag != TAG_SEQUENCE)
1113     goto bailout;
1114   if (parse_tag (&p, &n, &ti))
1115     goto bailout;
1116   if (ti.class || ti.tag != TAG_SEQUENCE)
1117     goto bailout;
1118   if (parse_tag (&p, &n, &ti))
1119     goto bailout;
1120   if (ti.class || ti.tag != TAG_OBJECT_ID
1121       || ti.length != DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)
1122       || memcmp (p, oid_pbeWithSHAAnd3_KeyTripleDES_CBC,
1123                  DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)))
1124     goto bailout;
1125   p += DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
1126   n -= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
1127
1128   where = "3des-params";
1129   if (parse_tag (&p, &n, &ti))
1130     goto bailout;
1131   if (ti.class || ti.tag != TAG_SEQUENCE)
1132     goto bailout;
1133   if (parse_tag (&p, &n, &ti))
1134     goto bailout;
1135   if (ti.class || ti.tag != TAG_OCTET_STRING
1136       || ti.length < 8 || ti.length > 20)
1137     goto bailout;
1138   saltlen = ti.length;
1139   memcpy (salt, p, saltlen);
1140   p += saltlen;
1141   n -= saltlen;
1142   if (parse_tag (&p, &n, &ti))
1143     goto bailout;
1144   if (ti.class || ti.tag != TAG_INTEGER || !ti.length )
1145     goto bailout;
1146   for (iter=0; ti.length; ti.length--)
1147     {
1148       iter <<= 8;
1149       iter |= (*p++) & 0xff; 
1150       n--;
1151     }
1152   
1153   where = "3des-ciphertext";
1154   if (parse_tag (&p, &n, &ti))
1155     goto bailout;
1156   if (ti.class || ti.tag != TAG_OCTET_STRING || !ti.length )
1157     goto bailout;
1158   
1159   log_info ("%lu bytes of 3DES encrypted text\n", ti.length);
1160   
1161   plain = gcry_malloc_secure (ti.length);
1162   if (!plain)
1163     {
1164       log_error ("error allocating decryption buffer\n");
1165       goto bailout;
1166     }
1167   consumed += p - p_start + ti.length;
1168   decrypt_block (p, plain, ti.length, salt, saltlen, iter, pw, 
1169                  GCRY_CIPHER_3DES, 
1170                  bag_data_p);
1171   n = ti.length;
1172   startoffset = 0;
1173   p_start = p = plain;
1174
1175   where = "decrypted-text";
1176   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
1177     goto bailout;
1178   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER
1179       || ti.length != 1 || *p)
1180     goto bailout;
1181   p++; n--;
1182   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
1183     goto bailout;
1184   len = ti.length;
1185   if (parse_tag (&p, &n, &ti))
1186     goto bailout;
1187   if (len < ti.nhdr)
1188     goto bailout;
1189   len -= ti.nhdr;
1190   if (ti.class || ti.tag != TAG_OBJECT_ID
1191       || ti.length != DIM(oid_rsaEncryption)
1192       || memcmp (p, oid_rsaEncryption,
1193                  DIM(oid_rsaEncryption)))
1194     goto bailout;
1195   p += DIM (oid_rsaEncryption);
1196   n -= DIM (oid_rsaEncryption);
1197   if (len < ti.length)
1198     goto bailout;
1199   len -= ti.length;
1200   if (n < len)
1201     goto bailout;
1202   p += len;
1203   n -= len;
1204   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_OCTET_STRING)
1205     goto bailout;
1206   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
1207     goto bailout;
1208   len = ti.length;
1209
1210   result = gcry_calloc (10, sizeof *result);
1211   if (!result)
1212     {
1213       log_error ( "error allocating result array\n");
1214       goto bailout;
1215     }
1216   result_count = 0;
1217
1218   where = "reading.key-parameters";
1219   for (result_count=0; len && result_count < 9;)
1220     {
1221       if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER)
1222         goto bailout;
1223       if (len < ti.nhdr)
1224         goto bailout;
1225       len -= ti.nhdr;
1226       if (len < ti.length)
1227         goto bailout;
1228       len -= ti.length;
1229       if (!result_count && ti.length == 1 && !*p)
1230         ; /* ignore the very first one if it is a 0 */
1231       else 
1232         {
1233           rc = gcry_mpi_scan (result+result_count, GCRYMPI_FMT_USG, p,
1234                               ti.length, NULL);
1235           if (rc)
1236             {
1237               log_error ("error parsing key parameter: %s\n",
1238                          gpg_strerror (rc));
1239               goto bailout;
1240             }
1241           result_count++;
1242         }
1243       p += ti.length;
1244       n -= ti.length;
1245     }
1246   if (len)
1247     goto bailout;
1248
1249   gcry_free (cram_buffer);
1250   if (r_consumed)
1251     *r_consumed = consumed;
1252   return result;
1253
1254  bailout:
1255   gcry_free (plain);
1256   if (result)
1257     {
1258       for (i=0; result[i]; i++)
1259         gcry_mpi_release (result[i]);
1260       gcry_free (result);
1261     }
1262   gcry_free (cram_buffer);
1263   log_error ( "data error at \"%s\", offset %u\n",
1264               where, (unsigned int)((p - buffer) + startoffset));
1265   if (r_consumed)
1266     *r_consumed = consumed;
1267   return NULL;
1268 }
1269
1270
1271 /* Parse a PKCS12 object and return an array of MPI representing the
1272    secret key parameters.  This is a very limited implementation in
1273    that it is only able to look for 3DES encoded encryptedData and
1274    tries to extract the first private key object it finds.  In case of
1275    an error NULL is returned. CERTCB and CERRTCBARG are used to pass
1276    X.509 certificates back to the caller. */
1277 gcry_mpi_t *
1278 p12_parse (const unsigned char *buffer, size_t length, const char *pw,
1279            void (*certcb)(void*, const unsigned char*, size_t),
1280            void *certcbarg)
1281 {
1282   struct tag_info ti;
1283   const unsigned char *p = buffer;
1284   const unsigned char *p_start = buffer;
1285   size_t n = length;
1286   const char *where;
1287   int bagseqlength, len;
1288   int bagseqndef, lenndef;
1289   gcry_mpi_t *result = NULL;
1290   unsigned char *cram_buffer = NULL;
1291
1292   where = "pfx";
1293   if (parse_tag (&p, &n, &ti))
1294     goto bailout;
1295   if (ti.tag != TAG_SEQUENCE)
1296     goto bailout;
1297
1298   where = "pfxVersion";
1299   if (parse_tag (&p, &n, &ti))
1300     goto bailout;
1301   if (ti.tag != TAG_INTEGER || ti.length != 1 || *p != 3)
1302     goto bailout;
1303   p++; n--;
1304   
1305   where = "authSave";
1306   if (parse_tag (&p, &n, &ti))
1307     goto bailout;
1308   if (ti.tag != TAG_SEQUENCE)
1309     goto bailout;
1310   if (parse_tag (&p, &n, &ti))
1311     goto bailout;
1312   if (ti.tag != TAG_OBJECT_ID || ti.length != DIM(oid_data)
1313       || memcmp (p, oid_data, DIM(oid_data)))
1314     goto bailout;
1315   p += DIM(oid_data);
1316   n -= DIM(oid_data);
1317
1318   if (parse_tag (&p, &n, &ti))
1319     goto bailout;
1320   if (ti.class != ASNCONTEXT || ti.tag)
1321     goto bailout;
1322   if (parse_tag (&p, &n, &ti))
1323     goto bailout;
1324   if (ti.class != UNIVERSAL || ti.tag != TAG_OCTET_STRING)
1325     goto bailout;
1326
1327   if (ti.is_constructed && ti.ndef)
1328     {
1329       /* Mozilla exported certs now come with single byte chunks of
1330          octect strings.  (Mozilla Firefox 1.0.4).  Arghh. */
1331       where = "cram-bags";
1332       cram_buffer = cram_octet_string ( p, &n, NULL);
1333       if (!cram_buffer)
1334         goto bailout;
1335       p = p_start = cram_buffer;
1336     }
1337
1338   where = "bags";
1339   if (parse_tag (&p, &n, &ti))
1340     goto bailout;
1341   if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE)
1342     goto bailout;
1343   bagseqndef = ti.ndef;
1344   bagseqlength = ti.length;
1345   while (bagseqlength || bagseqndef)
1346     {
1347 /*       log_debug ( "at offset %u\n", (p - p_start)); */
1348       where = "bag-sequence";
1349       if (parse_tag (&p, &n, &ti))
1350         goto bailout;
1351       if (bagseqndef && ti.class == UNIVERSAL && !ti.tag && !ti.is_constructed)
1352         break; /* Ready */ 
1353       if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE)
1354         goto bailout;
1355
1356       if (!bagseqndef)
1357         {
1358           if (bagseqlength < ti.nhdr)
1359             goto bailout;
1360           bagseqlength -= ti.nhdr;
1361           if (bagseqlength < ti.length)
1362             goto bailout;
1363           bagseqlength -= ti.length;
1364         }
1365       lenndef = ti.ndef;
1366       len = ti.length;
1367
1368       if (parse_tag (&p, &n, &ti))
1369         goto bailout;
1370       if (lenndef)
1371         len = ti.nhdr; 
1372       else
1373         len -= ti.nhdr; 
1374
1375       if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_encryptedData)
1376           && !memcmp (p, oid_encryptedData, DIM(oid_encryptedData)))
1377         {
1378           size_t consumed = 0;
1379
1380           p += DIM(oid_encryptedData);
1381           n -= DIM(oid_encryptedData);
1382           if (!lenndef)
1383             len -= DIM(oid_encryptedData);
1384           where = "bag.encryptedData";
1385           if (parse_bag_encrypted_data (p, n, (p - p_start), &consumed, pw,
1386                                         certcb, certcbarg,
1387                                         result? NULL : &result))
1388             goto bailout;
1389           if (lenndef)
1390             len += consumed;
1391         }
1392       else if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_data)
1393                && !memcmp (p, oid_data, DIM(oid_data)))
1394         {
1395           if (result)
1396             {
1397               log_info ("already got an key object, skipping this one\n");
1398               p += ti.length;
1399               n -= ti.length;
1400             }
1401           else
1402             {
1403               size_t consumed = 0;
1404
1405               p += DIM(oid_data);
1406               n -= DIM(oid_data);
1407               if (!lenndef)
1408                 len -= DIM(oid_data);
1409               result = parse_bag_data (p, n, (p - p_start), &consumed, pw);
1410               if (!result)
1411                 goto bailout;
1412               if (lenndef)
1413                 len += consumed;
1414             }
1415         }
1416       else
1417         {
1418           log_info ("unknown bag type - skipped\n");
1419           p += ti.length;
1420           n -= ti.length;
1421         }
1422
1423       if (len < 0 || len > n)
1424         goto bailout;
1425       p += len;
1426       n -= len;
1427       if (lenndef)
1428         {
1429           /* Need to skip the Null Tag. */
1430           if (parse_tag (&p, &n, &ti))
1431             goto bailout;
1432           if (!(ti.class == UNIVERSAL && !ti.tag && !ti.is_constructed))
1433             goto bailout;
1434         }
1435     }
1436   
1437   gcry_free (cram_buffer);
1438   return result;
1439  bailout:
1440   log_error ("error at \"%s\", offset %u\n",
1441              where, (unsigned int)(p - p_start));
1442   if (result)
1443     {
1444       int i;
1445
1446       for (i=0; result[i]; i++)
1447         gcry_mpi_release (result[i]);
1448       gcry_free (result);
1449     }
1450   gcry_free (cram_buffer);
1451   return NULL;
1452 }
1453
1454
1455 \f
1456 static size_t
1457 compute_tag_length (size_t n)
1458 {     
1459   int needed = 0;
1460
1461   if (n < 128)
1462     needed += 2; /* tag and one length byte */
1463   else if (n < 256)
1464     needed += 3; /* tag, number of length bytes, 1 length byte */
1465   else if (n < 65536)
1466     needed += 4; /* tag, number of length bytes, 2 length bytes */
1467   else
1468     {
1469       log_error ("object too larger to encode\n");
1470       return 0;
1471     }
1472   return needed;
1473 }
1474
1475 static unsigned char *
1476 store_tag_length (unsigned char *p, int tag, size_t n)
1477 {     
1478   if (tag == TAG_SEQUENCE)
1479     tag |= 0x20; /* constructed */
1480
1481   *p++ = tag;
1482   if (n < 128)
1483     *p++ = n;
1484   else if (n < 256)
1485     {
1486       *p++ = 0x81;
1487       *p++ = n;
1488     }
1489   else if (n < 65536)
1490     {
1491       *p++ = 0x82;
1492       *p++ = n >> 8;
1493       *p++ = n;
1494     }
1495
1496   return p;
1497 }
1498
1499
1500 /* Create the final PKCS-12 object from the sequences contained in
1501    SEQLIST.  PW is the password. That array is terminated with an NULL
1502    object. */
1503 static unsigned char *
1504 create_final (struct buffer_s *sequences, const char *pw, size_t *r_length)
1505 {
1506   int i;
1507   size_t needed = 0;
1508   size_t len[8], n;
1509   unsigned char *macstart;
1510   size_t maclen;
1511   unsigned char *result, *p;
1512   size_t resultlen;
1513   char salt[8];
1514   unsigned char keybuf[20];
1515   gcry_md_hd_t md;
1516   int rc;
1517   int with_mac = 1;
1518
1519
1520   /* 9 steps to create the pkcs#12 Krampf. */
1521
1522   /* 8. The MAC. */
1523   /* We add this at step 0. */
1524
1525   /* 7. All the buffers. */
1526   for (i=0; sequences[i].buffer; i++)
1527     needed += sequences[i].length;
1528
1529   /* 6. This goes into a sequences. */
1530   len[6] = needed;
1531   n = compute_tag_length (needed);
1532   needed += n;
1533
1534   /* 5. Encapsulate all in an octet string. */
1535   len[5] = needed;
1536   n = compute_tag_length (needed);
1537   needed += n;
1538
1539   /* 4. And tag it with [0]. */
1540   len[4] = needed;
1541   n = compute_tag_length (needed);
1542   needed += n;
1543
1544   /* 3. Prepend an data OID. */
1545   needed += 2 + DIM (oid_data);
1546
1547   /* 2. Put all into a sequences. */
1548   len[2] = needed;
1549   n = compute_tag_length (needed);
1550   needed += n;
1551
1552   /* 1. Prepend the version integer 3. */
1553   needed += 3;
1554
1555   /* 0. And the final outer sequence. */
1556   if (with_mac)
1557     needed += DIM (data_mactemplate);
1558   len[0] = needed;
1559   n = compute_tag_length (needed);
1560   needed += n;
1561
1562   /* Allocate a buffer. */
1563   result = gcry_malloc (needed);
1564   if (!result)
1565     {
1566       log_error ("error allocating buffer\n");
1567       return NULL;
1568     }
1569   p = result;
1570
1571   /* 0. Store the very outer sequence. */
1572   p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1573
1574   /* 1. Store the version integer 3. */
1575   *p++ = TAG_INTEGER;
1576   *p++ = 1; 
1577   *p++ = 3;
1578
1579   /* 2. Store another sequence. */
1580   p = store_tag_length (p, TAG_SEQUENCE, len[2]);
1581
1582   /* 3. Store the data OID. */
1583   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
1584   memcpy (p, oid_data, DIM (oid_data)); 
1585   p += DIM (oid_data); 
1586
1587   /* 4. Next comes a context tag. */
1588   p = store_tag_length (p, 0xa0, len[4]);
1589
1590   /* 5. And an octet string. */
1591   p = store_tag_length (p, TAG_OCTET_STRING, len[5]);
1592
1593   /* 6. And the inner sequence. */
1594   macstart = p;
1595   p = store_tag_length (p, TAG_SEQUENCE, len[6]);
1596
1597   /* 7. Append all the buffers. */
1598   for (i=0; sequences[i].buffer; i++)
1599     {
1600       memcpy (p, sequences[i].buffer, sequences[i].length);
1601       p += sequences[i].length;
1602     }
1603
1604   if (with_mac)
1605     {
1606       /* Intermezzo to compute the MAC. */
1607       maclen = p - macstart;
1608       gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
1609       if (string_to_key (3, salt, 8, 2048, pw, 20, keybuf))
1610         {
1611           gcry_free (result);
1612           return NULL;
1613         }
1614       rc = gcry_md_open (&md, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC);
1615       if (rc)
1616         {
1617           log_error ("gcry_md_open failed: %s\n", gpg_strerror (rc));
1618           gcry_free (result);
1619           return NULL;
1620         }
1621       rc = gcry_md_setkey (md, keybuf, 20);
1622       if (rc)
1623         {
1624           log_error ("gcry_md_setkey failed: %s\n", gpg_strerror (rc));
1625           gcry_md_close (md);
1626           gcry_free (result);
1627           return NULL;
1628         }
1629       gcry_md_write (md, macstart, maclen);
1630
1631       /* 8. Append the MAC template and fix it up. */
1632       memcpy (p, data_mactemplate, DIM (data_mactemplate));
1633       memcpy (p + DATA_MACTEMPLATE_SALT_OFF, salt, 8);
1634       memcpy (p + DATA_MACTEMPLATE_MAC_OFF, gcry_md_read (md, 0), 20);
1635       p += DIM (data_mactemplate);
1636       gcry_md_close (md);
1637     }
1638
1639   /* Ready. */
1640   resultlen = p - result;
1641   if (needed != resultlen)
1642     log_debug ("length mismatch: %lu, %lu\n",
1643                (unsigned long)needed, (unsigned long)resultlen);
1644
1645   *r_length = resultlen;
1646   return result;
1647 }
1648
1649
1650 /* Build a DER encoded SEQUENCE with the key:
1651
1652    SEQUENCE {
1653      INTEGER 0
1654      SEQUENCE {
1655        OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
1656        NULL
1657        }
1658      OCTET STRING, encapsulates {
1659        SEQUENCE {
1660          INTEGER 0
1661          INTEGER
1662          INTEGER 
1663          INTEGER
1664          INTEGER
1665          INTEGER
1666          INTEGER
1667          INTEGER
1668          INTEGER
1669          }
1670        }
1671      }
1672 */  
1673   
1674 static unsigned char * 
1675 build_key_sequence (gcry_mpi_t *kparms, size_t *r_length)
1676 {
1677   int rc, i;
1678   size_t needed, n;
1679   unsigned char *plain, *p;
1680   size_t plainlen;
1681   size_t outseqlen, oidseqlen, octstrlen, inseqlen;
1682
1683   needed = 3; /* The version(?) integer of value 0. */
1684   for (i=0; kparms[i]; i++)
1685     {
1686       n = 0;
1687       rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, kparms[i]);
1688       if (rc)
1689         {
1690           log_error ("error formatting parameter: %s\n", gpg_strerror (rc));
1691           return NULL;
1692         }
1693       needed += n;
1694       n = compute_tag_length (n);
1695       if (!n)
1696         return NULL;
1697       needed += n;
1698     }
1699   if (i != 8)
1700     {
1701       log_error ("invalid paramters for p12_build\n");
1702       return NULL;
1703     }
1704   /* Now this all goes into a sequence. */
1705   inseqlen = needed;
1706   n = compute_tag_length (needed);
1707   if (!n)
1708     return NULL;
1709   needed += n;
1710   /* Encapsulate all into an octet string. */
1711   octstrlen = needed;
1712   n = compute_tag_length (needed);
1713   if (!n)
1714     return NULL;
1715   needed += n;
1716   /* Prepend the object identifier sequence. */
1717   oidseqlen = 2 + DIM (oid_rsaEncryption) + 2;
1718   needed += 2 + oidseqlen;
1719   /* The version number. */
1720   needed += 3;
1721   /* And finally put the whole thing into a sequence. */
1722   outseqlen = needed;
1723   n = compute_tag_length (needed);
1724   if (!n)
1725     return NULL;
1726   needed += n;
1727   
1728   /* allocate 8 extra bytes for padding */
1729   plain = gcry_malloc_secure (needed+8);
1730   if (!plain)
1731     {
1732       log_error ("error allocating encryption buffer\n");
1733       return NULL;
1734     }
1735   
1736   /* And now fill the plaintext buffer. */
1737   p = plain;
1738   p = store_tag_length (p, TAG_SEQUENCE, outseqlen);
1739   /* Store version. */
1740   *p++ = TAG_INTEGER;
1741   *p++ = 1;
1742   *p++ = 0;
1743   /* Store object identifier sequence. */
1744   p = store_tag_length (p, TAG_SEQUENCE, oidseqlen);
1745   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_rsaEncryption));
1746   memcpy (p, oid_rsaEncryption, DIM (oid_rsaEncryption)); 
1747   p += DIM (oid_rsaEncryption); 
1748   *p++ = TAG_NULL;
1749   *p++ = 0;
1750   /* Start with the octet string. */
1751   p = store_tag_length (p, TAG_OCTET_STRING, octstrlen);
1752   p = store_tag_length (p, TAG_SEQUENCE, inseqlen);
1753   /* Store the key parameters. */
1754   *p++ = TAG_INTEGER;
1755   *p++ = 1;
1756   *p++ = 0;
1757   for (i=0; kparms[i]; i++)
1758     {
1759       n = 0;
1760       rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, kparms[i]);
1761       if (rc)
1762         {
1763           log_error ("oops: error formatting parameter: %s\n",
1764                      gpg_strerror (rc));
1765           gcry_free (plain);
1766           return NULL;
1767         }
1768       p = store_tag_length (p, TAG_INTEGER, n);
1769       
1770       n = plain + needed - p;
1771       rc = gcry_mpi_print (GCRYMPI_FMT_STD, p, n, &n, kparms[i]);
1772       if (rc)
1773         {
1774           log_error ("oops: error storing parameter: %s\n",
1775                      gpg_strerror (rc));
1776           gcry_free (plain);
1777           return NULL;
1778         }
1779       p += n;
1780     }
1781
1782   plainlen = p - plain;
1783   assert (needed == plainlen);
1784   /* Append some pad characters; we already allocated extra space. */
1785   n = 8 - plainlen % 8;
1786   for (i=0; i < n; i++, plainlen++)
1787     *p++ = n;
1788
1789   *r_length = plainlen;
1790   return plain;
1791 }
1792
1793
1794
1795 static unsigned char *
1796 build_key_bag (unsigned char *buffer, size_t buflen, char *salt,
1797                const unsigned char *sha1hash, const char *keyidstr,
1798                size_t *r_length)
1799 {
1800   size_t len[11], needed;
1801   unsigned char *p, *keybag;
1802   size_t keybaglen;
1803
1804   /* Walk 11 steps down to collect the info: */
1805
1806   /* 10. The data goes into an octet string. */
1807   needed = compute_tag_length (buflen);
1808   needed += buflen;
1809
1810   /* 9. Prepend the algorithm identifier. */
1811   needed += DIM (data_3desiter2048);
1812
1813   /* 8. Put a sequence around. */
1814   len[8] = needed;
1815   needed += compute_tag_length (needed);
1816
1817   /* 7. Prepend a [0] tag. */
1818   len[7] = needed;
1819   needed += compute_tag_length (needed);
1820
1821   /* 6b. The attributes which are appended at the end. */
1822   if (sha1hash)
1823     needed += DIM (data_attrtemplate) + 20;
1824
1825   /* 6. Prepend the shroudedKeyBag OID. */
1826   needed += 2 + DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag);
1827
1828   /* 5+4. Put all into two sequences. */
1829   len[5] = needed;
1830   needed += compute_tag_length ( needed);
1831   len[4] = needed;
1832   needed += compute_tag_length (needed);
1833
1834   /* 3. This all goes into an octet string. */
1835   len[3] = needed;
1836   needed += compute_tag_length (needed);
1837
1838   /* 2. Prepend another [0] tag. */
1839   len[2] = needed;
1840   needed += compute_tag_length (needed);
1841
1842   /* 1. Prepend the data OID. */
1843   needed += 2 + DIM (oid_data);
1844
1845   /* 0. Prepend another sequence. */
1846   len[0] = needed;
1847   needed += compute_tag_length (needed);
1848
1849   /* Now that we have all length information, allocate a buffer. */
1850   p = keybag = gcry_malloc (needed);
1851   if (!keybag)
1852     {
1853       log_error ("error allocating buffer\n");
1854       return NULL;
1855     }
1856
1857   /* Walk 11 steps up to store the data. */
1858
1859   /* 0. Store the first sequence. */
1860   p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1861
1862   /* 1. Store the data OID. */
1863   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
1864   memcpy (p, oid_data, DIM (oid_data)); 
1865   p += DIM (oid_data); 
1866
1867   /* 2. Store a [0] tag. */
1868   p = store_tag_length (p, 0xa0, len[2]);
1869
1870   /* 3. And an octet string. */
1871   p = store_tag_length (p, TAG_OCTET_STRING, len[3]);
1872
1873   /* 4+5. Two sequences. */
1874   p = store_tag_length (p, TAG_SEQUENCE, len[4]);
1875   p = store_tag_length (p, TAG_SEQUENCE, len[5]);
1876
1877   /* 6. Store the shroudedKeyBag OID. */
1878   p = store_tag_length (p, TAG_OBJECT_ID,
1879                         DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag));
1880   memcpy (p, oid_pkcs_12_pkcs_8ShroudedKeyBag,
1881           DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag)); 
1882   p += DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag); 
1883
1884   /* 7. Store a [0] tag. */
1885   p = store_tag_length (p, 0xa0, len[7]);
1886
1887   /* 8. Store a sequence. */
1888   p = store_tag_length (p, TAG_SEQUENCE, len[8]);
1889
1890   /* 9. Now for the pre-encoded algorithm identifier and the salt. */
1891   memcpy (p, data_3desiter2048, DIM (data_3desiter2048));
1892   memcpy (p + DATA_3DESITER2048_SALT_OFF, salt, 8);
1893   p += DIM (data_3desiter2048);
1894
1895   /* 10. And the octet string with the encrypted data. */
1896   p = store_tag_length (p, TAG_OCTET_STRING, buflen);
1897   memcpy (p, buffer, buflen);
1898   p += buflen;
1899
1900   /* Append the attributes whose length we calculated at step 2b. */
1901   if (sha1hash)
1902     {
1903       int i;
1904
1905       memcpy (p, data_attrtemplate, DIM (data_attrtemplate));
1906       for (i=0; i < 8; i++)
1907         p[DATA_ATTRTEMPLATE_KEYID_OFF+2*i+1] = keyidstr[i];
1908       p += DIM (data_attrtemplate);
1909       memcpy (p, sha1hash, 20);
1910       p += 20;
1911     }
1912
1913
1914   keybaglen = p - keybag;
1915   if (needed != keybaglen)
1916     log_debug ("length mismatch: %lu, %lu\n",
1917                (unsigned long)needed, (unsigned long)keybaglen);
1918   
1919   *r_length = keybaglen;
1920   return keybag;
1921 }
1922
1923
1924 static unsigned char *
1925 build_cert_bag (unsigned char *buffer, size_t buflen, char *salt,
1926                 size_t *r_length)
1927 {
1928   size_t len[9], needed;
1929   unsigned char *p, *certbag;
1930   size_t certbaglen;
1931
1932   /* Walk 9 steps down to collect the info: */
1933
1934   /* 8. The data goes into an octet string. */
1935   needed = compute_tag_length (buflen);
1936   needed += buflen;
1937
1938   /* 7. The algorithm identifier. */
1939   needed += DIM (data_rc2iter2048);
1940
1941   /* 6. The data OID. */
1942   needed += 2 + DIM (oid_data);
1943
1944   /* 5. A sequence. */
1945   len[5] = needed;
1946   needed += compute_tag_length ( needed);
1947
1948   /* 4. An integer. */
1949   needed += 3;
1950
1951   /* 3. A sequence. */
1952   len[3] = needed;
1953   needed += compute_tag_length (needed);
1954
1955   /* 2.  A [0] tag. */
1956   len[2] = needed;
1957   needed += compute_tag_length (needed);
1958
1959   /* 1. The encryptedData OID. */
1960   needed += 2 + DIM (oid_encryptedData);
1961
1962   /* 0. The first sequence. */
1963   len[0] = needed;
1964   needed += compute_tag_length (needed);
1965
1966   /* Now that we have all length information, allocate a buffer. */
1967   p = certbag = gcry_malloc (needed);
1968   if (!certbag)
1969     {
1970       log_error ("error allocating buffer\n");
1971       return NULL;
1972     }
1973
1974   /* Walk 9 steps up to store the data. */
1975
1976   /* 0. Store the first sequence. */
1977   p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1978
1979   /* 1. Store the encryptedData OID. */
1980   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_encryptedData));
1981   memcpy (p, oid_encryptedData, DIM (oid_encryptedData)); 
1982   p += DIM (oid_encryptedData); 
1983
1984   /* 2. Store a [0] tag. */
1985   p = store_tag_length (p, 0xa0, len[2]);
1986
1987   /* 3. Store a sequence. */
1988   p = store_tag_length (p, TAG_SEQUENCE, len[3]);
1989
1990   /* 4. Store the integer 0. */
1991   *p++ = TAG_INTEGER;
1992   *p++ = 1; 
1993   *p++ = 0;
1994
1995   /* 5. Store a sequence. */
1996   p = store_tag_length (p, TAG_SEQUENCE, len[5]);
1997
1998   /* 6. Store the data OID. */
1999   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
2000   memcpy (p, oid_data, DIM (oid_data)); 
2001   p += DIM (oid_data); 
2002
2003   /* 7. Now for the pre-encoded algorithm identifier and the salt. */
2004   memcpy (p, data_rc2iter2048, DIM (data_rc2iter2048));
2005   memcpy (p + DATA_RC2ITER2048_SALT_OFF, salt, 8);
2006   p += DIM (data_rc2iter2048);
2007
2008   /* 8. And finally the [0] tag with the encrypted data. */
2009   p = store_tag_length (p, 0x80, buflen);
2010   memcpy (p, buffer, buflen);
2011   p += buflen;
2012   certbaglen = p - certbag;
2013   
2014   if (needed != certbaglen)
2015     log_debug ("length mismatch: %lu, %lu\n",
2016                (unsigned long)needed, (unsigned long)certbaglen);
2017
2018   *r_length = certbaglen;
2019   return certbag;
2020 }
2021
2022
2023 static unsigned char *
2024 build_cert_sequence (unsigned char *buffer, size_t buflen, 
2025                      const unsigned char *sha1hash, const char *keyidstr,
2026                      size_t *r_length)
2027 {
2028   size_t len[8], needed, n;
2029   unsigned char *p, *certseq;
2030   size_t certseqlen;
2031   int i;
2032
2033   assert (strlen (keyidstr) == 8);
2034
2035   /* Walk 8 steps down to collect the info: */
2036
2037   /* 7. The data goes into an octet string. */
2038   needed = compute_tag_length (buflen);
2039   needed += buflen;
2040
2041   /* 6. A [0] tag. */
2042   len[6] = needed;
2043   needed += compute_tag_length (needed);
2044
2045   /* 5. An OID. */
2046   needed += 2 + DIM (oid_x509Certificate_for_pkcs_12);
2047
2048   /* 4. A sequence. */
2049   len[4] = needed;
2050   needed += compute_tag_length (needed);
2051
2052   /* 3. A [0] tag. */
2053   len[3] = needed;
2054   needed += compute_tag_length (needed);
2055
2056   /* 2b. The attributes which are appended at the end. */
2057   if (sha1hash)
2058     needed += DIM (data_attrtemplate) + 20;
2059
2060   /* 2. An OID. */
2061   needed += 2 + DIM (oid_pkcs_12_CertBag);
2062
2063   /* 1. A sequence. */
2064   len[1] = needed;
2065   needed += compute_tag_length (needed);
2066
2067   /* 0. The first sequence. */
2068   len[0] = needed;
2069   needed += compute_tag_length (needed);
2070
2071   /* Now that we have all length information, allocate a buffer. */
2072   p = certseq = gcry_malloc (needed + 8 /*(for padding)*/);
2073   if (!certseq)
2074     {
2075       log_error ("error allocating buffer\n");
2076       return NULL;
2077     }
2078
2079   /* Walk 8 steps up to store the data. */
2080
2081   /* 0. Store the first sequence. */
2082   p = store_tag_length (p, TAG_SEQUENCE, len[0]);
2083
2084   /* 1. Store the second sequence. */
2085   p = store_tag_length (p, TAG_SEQUENCE, len[1]);
2086
2087   /* 2. Store the pkcs12-cert-bag OID. */
2088   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_pkcs_12_CertBag));
2089   memcpy (p, oid_pkcs_12_CertBag, DIM (oid_pkcs_12_CertBag)); 
2090   p += DIM (oid_pkcs_12_CertBag); 
2091
2092   /* 3. Store a [0] tag. */
2093   p = store_tag_length (p, 0xa0, len[3]);
2094
2095   /* 4. Store a sequence. */
2096   p = store_tag_length (p, TAG_SEQUENCE, len[4]);
2097
2098   /* 5. Store the x509Certificate OID. */
2099   p = store_tag_length (p, TAG_OBJECT_ID,
2100                         DIM (oid_x509Certificate_for_pkcs_12));
2101   memcpy (p, oid_x509Certificate_for_pkcs_12,
2102           DIM (oid_x509Certificate_for_pkcs_12)); 
2103   p += DIM (oid_x509Certificate_for_pkcs_12); 
2104
2105   /* 6. Store a [0] tag. */
2106   p = store_tag_length (p, 0xa0, len[6]);
2107
2108   /* 7. And the octet string with the actual certificate. */
2109   p = store_tag_length (p, TAG_OCTET_STRING, buflen);
2110   memcpy (p, buffer, buflen);
2111   p += buflen;
2112   
2113   /* Append the attributes whose length we calculated at step 2b. */
2114   if (sha1hash)
2115     {
2116       memcpy (p, data_attrtemplate, DIM (data_attrtemplate));
2117       for (i=0; i < 8; i++)
2118         p[DATA_ATTRTEMPLATE_KEYID_OFF+2*i+1] = keyidstr[i];
2119       p += DIM (data_attrtemplate);
2120       memcpy (p, sha1hash, 20);
2121       p += 20;
2122     }
2123
2124   certseqlen = p - certseq;
2125   if (needed != certseqlen)
2126     log_debug ("length mismatch: %lu, %lu\n",
2127                (unsigned long)needed, (unsigned long)certseqlen);
2128
2129   /* Append some pad characters; we already allocated extra space. */
2130   n = 8 - certseqlen % 8;
2131   for (i=0; i < n; i++, certseqlen++)
2132     *p++ = n;
2133   
2134   *r_length = certseqlen;
2135   return certseq;
2136 }
2137
2138
2139 /* Expect the RSA key parameters in KPARMS and a password in PW.
2140    Create a PKCS structure from it and return it as well as the length
2141    in R_LENGTH; return NULL in case of an error.  If CHARSET is not
2142    NULL, re-encode PW to that character set. */
2143 unsigned char * 
2144 p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen,
2145            const char *pw, const char *charset, size_t *r_length)
2146 {
2147   unsigned char *buffer = NULL;
2148   size_t n, buflen;
2149   char salt[8];
2150   struct buffer_s seqlist[3];
2151   int seqlistidx = 0;
2152   unsigned char sha1hash[20];
2153   char keyidstr[8+1];
2154   char *pwbuf = NULL;
2155   size_t pwbufsize = 0;
2156
2157   n = buflen = 0; /* (avoid compiler warning). */
2158   memset (sha1hash, 0, 20);
2159   *keyidstr = 0;
2160
2161   if (charset && pw && *pw)
2162     {
2163       jnlib_iconv_t cd;
2164       const char *inptr;
2165       char *outptr;
2166       size_t inbytes, outbytes;
2167
2168       /* We assume that the converted passphrase is at max 2 times
2169          longer than its utf-8 encoding. */
2170       pwbufsize = strlen (pw)*2 + 1;
2171       pwbuf = gcry_malloc_secure (pwbufsize);
2172       if (!pwbuf)
2173         {
2174           log_error ("out of secure memory while converting passphrase\n");
2175           goto failure;
2176         }
2177
2178       cd = jnlib_iconv_open (charset, "utf-8");
2179       if (cd == (jnlib_iconv_t)(-1))
2180         {
2181           log_error ("can't convert passphrase to"
2182                      " requested charset `%s': %s\n",
2183                      charset, strerror (errno));
2184           gcry_free (pwbuf);
2185           goto failure;
2186         }
2187
2188       inptr = pw;
2189       inbytes = strlen (pw);
2190       outptr = pwbuf;
2191       outbytes = pwbufsize - 1;
2192       if ( jnlib_iconv (cd, (const char **)&inptr, &inbytes,
2193                       &outptr, &outbytes) == (size_t)-1) 
2194         {
2195           log_error ("error converting passphrase to"
2196                      " requested charset `%s': %s\n",
2197                      charset, strerror (errno));
2198           gcry_free (pwbuf);
2199           jnlib_iconv_close (cd);
2200           goto failure;
2201         }
2202       *outptr = 0;
2203       jnlib_iconv_close (cd);
2204       pw = pwbuf;
2205     }
2206
2207
2208   if (cert && certlen)
2209     {
2210       /* Calculate the hash value we need for the bag attributes. */
2211       gcry_md_hash_buffer (GCRY_MD_SHA1, sha1hash, cert, certlen);
2212       sprintf (keyidstr, "%02x%02x%02x%02x",
2213                sha1hash[16], sha1hash[17], sha1hash[18], sha1hash[19]);
2214
2215       /* Encode the certificate. */
2216       buffer = build_cert_sequence (cert, certlen, sha1hash, keyidstr,
2217                                     &buflen);
2218       if (!buffer)
2219         goto failure;
2220
2221       /* Encrypt it. */
2222       gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
2223       crypt_block (buffer, buflen, salt, 8, 2048, pw,
2224                    GCRY_CIPHER_RFC2268_40, 1);
2225       
2226       /* Encode the encrypted stuff into a bag. */
2227       seqlist[seqlistidx].buffer = build_cert_bag (buffer, buflen, salt, &n);
2228       seqlist[seqlistidx].length = n;
2229       gcry_free (buffer);
2230       buffer = NULL;
2231       if (!seqlist[seqlistidx].buffer)
2232         goto failure;
2233       seqlistidx++;
2234     }
2235
2236
2237   if (kparms)
2238     {
2239       /* Encode the key. */
2240       buffer = build_key_sequence (kparms, &buflen);
2241       if (!buffer)
2242         goto failure;
2243       
2244       /* Encrypt it. */
2245       gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
2246       crypt_block (buffer, buflen, salt, 8, 2048, pw, GCRY_CIPHER_3DES, 1);
2247
2248       /* Encode the encrypted stuff into a bag. */
2249       if (cert && certlen)
2250         seqlist[seqlistidx].buffer = build_key_bag (buffer, buflen, salt, 
2251                                                     sha1hash, keyidstr, &n);
2252       else
2253         seqlist[seqlistidx].buffer = build_key_bag (buffer, buflen, salt,
2254                                                     NULL, NULL, &n);
2255       seqlist[seqlistidx].length = n;
2256       gcry_free (buffer);
2257       buffer = NULL;
2258       if (!seqlist[seqlistidx].buffer)
2259         goto failure;
2260       seqlistidx++;
2261     }
2262
2263   seqlist[seqlistidx].buffer = NULL;
2264   seqlist[seqlistidx].length = 0;
2265
2266   buffer = create_final (seqlist, pw, &buflen);
2267
2268  failure:
2269   if (pwbuf)
2270     {
2271       wipememory (pwbuf, pwbufsize);
2272       gcry_free (pwbuf);
2273     }
2274   for ( ; seqlistidx; seqlistidx--)
2275     gcry_free (seqlist[seqlistidx].buffer);
2276
2277   *r_length = buffer? buflen : 0;
2278   return buffer;
2279 }
2280
2281
2282 #ifdef TEST
2283
2284 static void 
2285 cert_cb (void *opaque, const unsigned char *cert, size_t certlen)
2286 {
2287   printf ("got a certificate of %u bytes length\n", certlen);
2288 }
2289
2290 int
2291 main (int argc, char **argv)
2292 {
2293   FILE *fp;
2294   struct stat st;
2295   unsigned char *buf;
2296   size_t buflen;
2297   gcry_mpi_t *result;
2298
2299   if (argc != 3)
2300     {
2301       fprintf (stderr, "usage: testp12 file passphrase\n");
2302       return 1;
2303     }
2304
2305   gcry_control (GCRYCTL_DISABLE_SECMEM, NULL);
2306   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL);
2307
2308   fp = fopen (argv[1], "rb");
2309   if (!fp)
2310     {
2311       fprintf (stderr, "can't open `%s': %s\n", argv[1], strerror (errno));
2312       return 1;
2313     }
2314   
2315   if (fstat (fileno(fp), &st))
2316     {
2317       fprintf (stderr, "can't stat `%s': %s\n", argv[1], strerror (errno));
2318       return 1;
2319     }
2320
2321   buflen = st.st_size;
2322   buf = gcry_malloc (buflen+1);
2323   if (!buf || fread (buf, buflen, 1, fp) != 1)
2324     {
2325       fprintf (stderr, "error reading `%s': %s\n", argv[1], strerror (errno));
2326       return 1;
2327     }
2328   fclose (fp);
2329
2330   result = p12_parse (buf, buflen, argv[2], cert_cb, NULL);
2331   if (result)
2332     {
2333       int i, rc;
2334       unsigned char *tmpbuf;
2335
2336       for (i=0; result[i]; i++)
2337         {
2338           rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &tmpbuf,
2339                                 NULL, result[i]);
2340           if (rc)
2341             printf ("%d: [error printing number: %s]\n",
2342                     i, gpg_strerror (rc));
2343           else
2344             {
2345               printf ("%d: %s\n", i, tmpbuf);
2346               gcry_free (tmpbuf);
2347             }
2348         }
2349     }
2350
2351   return 0;
2352
2353 }
2354
2355 /*
2356 Local Variables:
2357 compile-command: "gcc -Wall -O0 -g -DTEST=1 -o minip12 minip12.c ../jnlib/libjnlib.a -L /usr/local/lib -lgcrypt -lgpg-error"
2358 End:
2359 */
2360 #endif /* TEST */