Fixed a build bug (straw letter in sm/import.c) and updated the documentation.
[gnupg.git] / agent / minip12.c
1 /* minip12.c - A minimal pkcs-12 implementation.
2  *      Copyright (C) 2002, 2003 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <assert.h>
28 #include <gcrypt.h>
29
30 #undef TEST 
31
32 #ifdef TEST
33 #include <sys/stat.h>
34 #include <unistd.h>
35 #include <errno.h>
36 #endif
37
38 #include "../jnlib/logging.h"
39 #include "minip12.h"
40
41 #ifndef DIM
42 #define DIM(v)               (sizeof(v)/sizeof((v)[0]))
43 #endif
44
45 enum
46 {
47   UNIVERSAL = 0,
48   APPLICATION = 1,
49   CONTEXT = 2,
50   PRIVATE = 3
51 };
52
53
54 enum
55 {
56   TAG_NONE = 0,
57   TAG_BOOLEAN = 1,
58   TAG_INTEGER = 2,
59   TAG_BIT_STRING = 3,
60   TAG_OCTET_STRING = 4,
61   TAG_NULL = 5,
62   TAG_OBJECT_ID = 6,
63   TAG_OBJECT_DESCRIPTOR = 7,
64   TAG_EXTERNAL = 8,
65   TAG_REAL = 9,
66   TAG_ENUMERATED = 10,
67   TAG_EMBEDDED_PDV = 11,
68   TAG_UTF8_STRING = 12,
69   TAG_REALTIVE_OID = 13,
70   TAG_SEQUENCE = 16,
71   TAG_SET = 17,
72   TAG_NUMERIC_STRING = 18,
73   TAG_PRINTABLE_STRING = 19,
74   TAG_TELETEX_STRING = 20,
75   TAG_VIDEOTEX_STRING = 21,
76   TAG_IA5_STRING = 22,
77   TAG_UTC_TIME = 23,
78   TAG_GENERALIZED_TIME = 24,
79   TAG_GRAPHIC_STRING = 25,
80   TAG_VISIBLE_STRING = 26,
81   TAG_GENERAL_STRING = 27,
82   TAG_UNIVERSAL_STRING = 28,
83   TAG_CHARACTER_STRING = 29,
84   TAG_BMP_STRING = 30
85 };
86
87
88 static unsigned char const oid_data[9] = {
89   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01 };
90 static unsigned char const oid_encryptedData[9] = {
91   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06 };
92 static unsigned char const oid_pkcs_12_pkcs_8ShroudedKeyBag[11] = {
93   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x02 };
94 static unsigned char const oid_pkcs_12_CertBag[11] = {
95   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x03 };
96 static unsigned char const oid_pbeWithSHAAnd3_KeyTripleDES_CBC[10] = {
97   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03 };
98 static unsigned char const oid_pbeWithSHAAnd40BitRC2_CBC[10] = {
99   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x06 };
100
101 static unsigned char const oid_rsaEncryption[9] = {
102   0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 };
103
104
105 static unsigned char const data_3desiter1024[30] = {
106   0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86,
107   0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30, 0x0E, 
108   0x04, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
109   0xFF, 0xFF, 0x02, 0x02, 0x04, 0x00 };
110 #define DATA_3DESITER1024_SALT_OFF  18
111
112
113 struct buffer_s 
114 {
115   unsigned char *buffer;
116   size_t length;
117 };  
118
119
120 struct tag_info 
121 {
122   int class;
123   int is_constructed;
124   unsigned long tag;
125   unsigned long length;  /* length part of the TLV */
126   int nhdr;
127   int ndef;              /* It is an indefinite length */
128 };
129
130
131 /* Parse the buffer at the address BUFFER which is of SIZE and return
132    the tag and the length part from the TLV triplet.  Update BUFFER
133    and SIZE on success. */
134 static int 
135 parse_tag (unsigned char const **buffer, size_t *size, struct tag_info *ti)
136 {
137   int c;
138   unsigned long tag;
139   const unsigned char *buf = *buffer;
140   size_t length = *size;
141
142   ti->length = 0;
143   ti->ndef = 0;
144   ti->nhdr = 0;
145
146   /* Get the tag */
147   if (!length)
148     return -1; /* premature eof */
149   c = *buf++; length--;
150   ti->nhdr++;
151
152   ti->class = (c & 0xc0) >> 6;
153   ti->is_constructed = !!(c & 0x20);
154   tag = c & 0x1f;
155
156   if (tag == 0x1f)
157     {
158       tag = 0;
159       do
160         {
161           tag <<= 7;
162           if (!length)
163             return -1; /* premature eof */
164           c = *buf++; length--;
165           ti->nhdr++;
166           tag |= c & 0x7f;
167         }
168       while (c & 0x80);
169     }
170   ti->tag = tag;
171
172   /* Get the length */
173   if (!length)
174     return -1; /* prematureeof */
175   c = *buf++; length--;
176   ti->nhdr++;
177
178   if ( !(c & 0x80) )
179     ti->length = c;
180   else if (c == 0x80)
181     ti->ndef = 1;
182   else if (c == 0xff)
183     return -1; /* forbidden length value */
184   else
185     {
186       unsigned long len = 0;
187       int count = c & 0x7f;
188
189       for (; count; count--)
190         {
191           len <<= 8;
192           if (!length)
193             return -1; /* premature_eof */
194           c = *buf++; length--;
195           ti->nhdr++;
196           len |= c & 0xff;
197         }
198       ti->length = len;
199     }
200   
201   if (ti->class == UNIVERSAL && !ti->tag)
202     ti->length = 0;
203
204   if (ti->length > length)
205     return -1; /* data larger than buffer. */
206   
207   *buffer = buf;
208   *size = length;
209   return 0;
210 }
211
212
213 static int 
214 string_to_key (int id, char *salt, int iter, const char *pw,
215                int req_keylen, unsigned char *keybuf)
216 {
217   int rc, i, j;
218   gcry_md_hd_t md;
219   gcry_mpi_t num_b1 = NULL;
220   int pwlen;
221   unsigned char hash[20], buf_b[64], buf_i[128], *p;
222   size_t cur_keylen;
223   size_t n;
224
225   cur_keylen = 0;
226   pwlen = strlen (pw);
227   if (pwlen > 63/2)
228     {
229       log_error ("password too long\n");
230       return -1;
231     }
232
233   /* Store salt and password in BUF_I */
234   p = buf_i;
235   for(i=0; i < 64; i++)
236     *p++ = salt [i%8];
237   for(i=j=0; i < 64; i += 2)
238     {
239       *p++ = 0;
240       *p++ = pw[j];
241       if (++j > pwlen) /* Note, that we include the trailing zero */
242         j = 0;
243     }
244
245   for (;;)
246     {
247       rc = gcry_md_open (&md, GCRY_MD_SHA1, 0);
248       if (rc)
249         {
250           log_error ( "gcry_md_open failed: %s\n", gpg_strerror (rc));
251           return rc;
252         }
253       for(i=0; i < 64; i++)
254         gcry_md_putc (md, id);
255       gcry_md_write (md, buf_i, 128);
256       memcpy (hash, gcry_md_read (md, 0), 20);
257       gcry_md_close (md);
258       for (i=1; i < iter; i++)
259         gcry_md_hash_buffer (GCRY_MD_SHA1, hash, hash, 20);
260
261       for (i=0; i < 20 && cur_keylen < req_keylen; i++)
262         keybuf[cur_keylen++] = hash[i];
263       if (cur_keylen == req_keylen)
264         {
265           gcry_mpi_release (num_b1);
266           return 0; /* ready */
267         }
268       
269       /* need more bytes. */
270       for(i=0; i < 64; i++)
271         buf_b[i] = hash[i % 20];
272       rc = gcry_mpi_scan (&num_b1, GCRYMPI_FMT_USG, buf_b, 64, &n);
273       if (rc)
274         {
275           log_error ( "gcry_mpi_scan failed: %s\n", gpg_strerror (rc));
276           return -1;
277         }
278       gcry_mpi_add_ui (num_b1, num_b1, 1);
279       for (i=0; i < 128; i += 64)
280         {
281           gcry_mpi_t num_ij;
282
283           rc = gcry_mpi_scan (&num_ij, GCRYMPI_FMT_USG, buf_i + i, 64, &n);
284           if (rc)
285             {
286               log_error ( "gcry_mpi_scan failed: %s\n",
287                        gpg_strerror (rc));
288               return -1;
289             }
290           gcry_mpi_add (num_ij, num_ij, num_b1);
291           gcry_mpi_clear_highbit (num_ij, 64*8);
292           rc = gcry_mpi_print (GCRYMPI_FMT_USG, buf_i + i, 64, &n, num_ij);
293           if (rc)
294             {
295               log_error ( "gcry_mpi_print failed: %s\n",
296                           gpg_strerror (rc));
297               return -1;
298             }
299           gcry_mpi_release (num_ij);
300         }
301     }
302 }
303
304
305 static int 
306 set_key_iv (gcry_cipher_hd_t chd, char *salt, int iter, const char *pw)
307 {
308   unsigned char keybuf[24];
309   int rc;
310
311   if (string_to_key (1, salt, iter, pw, 24, keybuf))
312     return -1;
313   rc = gcry_cipher_setkey (chd, keybuf, 24);
314   if (rc)
315     {
316       log_error ( "gcry_cipher_setkey failed: %s\n", gpg_strerror (rc));
317       return -1;
318     }
319
320   if (string_to_key (2, salt, iter, pw, 8, keybuf))
321     return -1;
322   rc = gcry_cipher_setiv (chd, keybuf, 8);
323   if (rc)
324     {
325       log_error ("gcry_cipher_setiv failed: %s\n", gpg_strerror (rc));
326       return -1;
327     }
328   return 0;
329 }
330
331
332 static void
333 crypt_block (unsigned char *buffer, size_t length, char *salt, int iter,
334              const char *pw, int encrypt)
335 {
336   gcry_cipher_hd_t chd;
337   int rc;
338
339   rc = gcry_cipher_open (&chd, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0);
340   if (rc)
341     {
342       log_error ( "gcry_cipher_open failed: %s\n", gpg_strerror(-1));
343       return;
344     }
345   if (set_key_iv (chd, salt, iter, pw))
346     goto leave;
347
348   rc = encrypt? gcry_cipher_encrypt (chd, buffer, length, NULL, 0)
349               : gcry_cipher_decrypt (chd, buffer, length, NULL, 0);
350
351   if (rc)
352     {
353       log_error ( "en/de-crytion failed: %s\n", gpg_strerror (rc));
354       goto leave;
355     }
356
357 /*    { */
358 /*      FILE *fp = fopen("inner.der", "wb"); */
359 /*      fwrite (buffer, 1, length, fp); */
360 /*      fclose (fp); */
361 /*    } */
362
363  leave:
364   gcry_cipher_close (chd);
365 }
366   
367
368
369
370 static int
371 parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
372                           int startoffset)
373 {
374   struct tag_info ti;
375   const unsigned char *p = buffer;
376   size_t n = length;
377   const char *where;
378
379   where = "start";
380   if (parse_tag (&p, &n, &ti))
381     goto bailout;
382   if (ti.class != CONTEXT || ti.tag)
383     goto bailout;
384   if (parse_tag (&p, &n, &ti))
385     goto bailout;
386   if (ti.tag != TAG_SEQUENCE)
387     goto bailout;
388
389   where = "bag.encryptedData.version";
390   if (parse_tag (&p, &n, &ti))
391     goto bailout;
392   if (ti.tag != TAG_INTEGER || ti.length != 1 || *p != 0)
393     goto bailout;
394   p++; n--;
395   if (parse_tag (&p, &n, &ti))
396     goto bailout;
397   if (ti.tag != TAG_SEQUENCE)
398     goto bailout;
399
400   where = "bag.encryptedData.data";
401   if (parse_tag (&p, &n, &ti))
402     goto bailout;
403   if (ti.tag != TAG_OBJECT_ID || ti.length != DIM(oid_data)
404       || memcmp (p, oid_data, DIM(oid_data)))
405     goto bailout;
406   p += DIM(oid_data);
407   n -= DIM(oid_data);
408
409 #if 0
410   where = "bag.encryptedData.keyinfo"
411   if (parse_tag (&p, &n, &ti))
412     goto bailout;
413   if (ti.class || ti.tag != TAG_SEQUENCE)
414     goto bailout;
415   if (parse_tag (&p, &n, &ti))
416     goto bailout;
417   if (!ti.class && ti.tag == TAG_OBJECT_ID
418       && ti.length == DIM(oid_pbeWithSHAAnd40BitRC2_CBC)
419       && memcmp (p, oid_pbeWithSHAAnd40BitRC2_CBC,
420                  DIM(oid_pbeWithSHAAnd40BitRC2_CBC)))
421     {
422       p += DIM(oid_pbeWithSHAAnd40BitRC2_CBC);
423       n -= DIM(oid_pbeWithSHAAnd40BitRC2_CBC);
424     }
425   else
426     goto bailout;
427
428   where = "rc2-params";
429   if (parse_tag (&p, &n, &ti))
430     goto bailout;
431   if (ti.class || ti.tag != TAG_SEQUENCE)
432     goto bailout;
433   if (parse_tag (&p, &n, &ti))
434     goto bailout;
435   if (ti.class || ti.tag != TAG_OCTET_STRING || ti.length != 8 )
436     goto bailout;
437   memcpy (salt, p, 8);
438   p += 8;
439   n -= 8;
440   if (parse_tag (&p, &n, &ti))
441     goto bailout;
442   if (ti.class || ti.tag != TAG_INTEGER || !ti.length )
443     goto bailout;
444   for (iter=0; ti.length; ti.length--)
445     {
446       iter <<= 8;
447       iter |= (*p++) & 0xff; 
448       n--;
449     }
450   
451   where = "rc2-ciphertext";
452   if (parse_tag (&p, &n, &ti))
453     goto bailout;
454   if (ti.class || ti.tag != TAG_OCTET_STRING || !ti.length )
455     goto bailout;
456   
457   log_info ("%lu bytes of RC2 encrypted text\n", ti.length);
458 #endif
459
460
461
462   return 0;
463  bailout:
464   log_error ("encryptedData error at \"%s\", offset %u\n",
465              where, (p - buffer)+startoffset);
466   return -1;
467 }
468
469 static gcry_mpi_t *
470 parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
471                 const char *pw)
472 {
473   int rc;
474   struct tag_info ti;
475   const unsigned char *p = buffer;
476   size_t n = length;
477   const char *where;
478   char salt[8];
479   unsigned int iter;
480   int len;
481   unsigned char *plain = NULL;
482   gcry_mpi_t *result = NULL;
483   int result_count, i;
484
485   where = "start";
486   if (parse_tag (&p, &n, &ti))
487     goto bailout;
488   if (ti.class != CONTEXT || ti.tag)
489     goto bailout;
490   if (parse_tag (&p, &n, &ti))
491     goto bailout;
492   if (ti.class || ti.tag != TAG_OCTET_STRING)
493     goto bailout;
494
495   where = "data.outerseqs";
496   if (parse_tag (&p, &n, &ti))
497     goto bailout;
498   if (ti.class || ti.tag != TAG_SEQUENCE)
499     goto bailout;
500   if (parse_tag (&p, &n, &ti))
501     goto bailout;
502   if (ti.class || ti.tag != TAG_SEQUENCE)
503     goto bailout;
504
505   where = "data.objectidentifier";
506   if (parse_tag (&p, &n, &ti))
507     goto bailout;
508   if (ti.class || ti.tag != TAG_OBJECT_ID
509       || ti.length != DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag)
510       || memcmp (p, oid_pkcs_12_pkcs_8ShroudedKeyBag,
511                  DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag)))
512     goto bailout;
513   p += DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag);
514   n -= DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag);
515
516   where = "shrouded,outerseqs";
517   if (parse_tag (&p, &n, &ti))
518     goto bailout;
519   if (ti.class != CONTEXT || ti.tag)
520     goto bailout;
521   if (parse_tag (&p, &n, &ti))
522     goto bailout;
523   if (ti.class || ti.tag != TAG_SEQUENCE)
524     goto bailout;
525   if (parse_tag (&p, &n, &ti))
526     goto bailout;
527   if (ti.class || ti.tag != TAG_SEQUENCE)
528     goto bailout;
529   if (parse_tag (&p, &n, &ti))
530     goto bailout;
531   if (ti.class || ti.tag != TAG_OBJECT_ID
532       || ti.length != DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)
533       || memcmp (p, oid_pbeWithSHAAnd3_KeyTripleDES_CBC,
534                  DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)))
535     goto bailout;
536   p += DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
537   n -= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
538
539   where = "3des-params";
540   if (parse_tag (&p, &n, &ti))
541     goto bailout;
542   if (ti.class || ti.tag != TAG_SEQUENCE)
543     goto bailout;
544   if (parse_tag (&p, &n, &ti))
545     goto bailout;
546   if (ti.class || ti.tag != TAG_OCTET_STRING || ti.length != 8 )
547     goto bailout;
548   memcpy (salt, p, 8);
549   p += 8;
550   n -= 8;
551   if (parse_tag (&p, &n, &ti))
552     goto bailout;
553   if (ti.class || ti.tag != TAG_INTEGER || !ti.length )
554     goto bailout;
555   for (iter=0; ti.length; ti.length--)
556     {
557       iter <<= 8;
558       iter |= (*p++) & 0xff; 
559       n--;
560     }
561   
562   where = "3des-ciphertext";
563   if (parse_tag (&p, &n, &ti))
564     goto bailout;
565   if (ti.class || ti.tag != TAG_OCTET_STRING || !ti.length )
566     goto bailout;
567   
568   log_info ("%lu bytes of 3DES encrypted text\n", ti.length);
569   
570   plain = gcry_malloc_secure (ti.length);
571   if (!plain)
572     {
573       log_error ("error allocating decryption buffer\n");
574       goto bailout;
575     }
576   memcpy (plain, p, ti.length);
577   crypt_block (plain, ti.length, salt, iter, pw, 0);
578   n = ti.length;
579   startoffset = 0;
580   buffer = p = plain;
581
582   where = "decrypted-text";
583   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
584     goto bailout;
585   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER
586       || ti.length != 1 || *p)
587     goto bailout;
588   p++; n--;
589   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
590     goto bailout;
591   len = ti.length;
592   if (parse_tag (&p, &n, &ti))
593     goto bailout;
594   if (len < ti.nhdr)
595     goto bailout;
596   len -= ti.nhdr;
597   if (ti.class || ti.tag != TAG_OBJECT_ID
598       || ti.length != DIM(oid_rsaEncryption)
599       || memcmp (p, oid_rsaEncryption,
600                  DIM(oid_rsaEncryption)))
601     goto bailout;
602   p += DIM (oid_rsaEncryption);
603   n -= DIM (oid_rsaEncryption);
604   if (len < ti.length)
605     goto bailout;
606   len -= ti.length;
607   if (n < len)
608     goto bailout;
609   p += len;
610   n -= len;
611   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_OCTET_STRING)
612     goto bailout;
613   if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
614     goto bailout;
615   len = ti.length;
616
617   result = gcry_calloc (10, sizeof *result);
618   if (!result)
619     {
620       log_error ( "error allocating result array\n");
621       goto bailout;
622     }
623   result_count = 0;
624
625   where = "reading.key-parameters";
626   for (result_count=0; len && result_count < 9;)
627     {
628       if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER)
629         goto bailout;
630       if (len < ti.nhdr)
631         goto bailout;
632       len -= ti.nhdr;
633       if (len < ti.length)
634         goto bailout;
635       len -= ti.length;
636       if (!result_count && ti.length == 1 && !*p)
637         ; /* ignore the very first one if it is a 0 */
638       else 
639         {
640           rc = gcry_mpi_scan (result+result_count, GCRYMPI_FMT_USG, p,
641                               ti.length, NULL);
642           if (rc)
643             {
644               log_error ("error parsing key parameter: %s\n",
645                          gpg_strerror (rc));
646               goto bailout;
647             }
648           result_count++;
649         }
650       p += ti.length;
651       n -= ti.length;
652     }
653   if (len)
654     goto bailout;
655
656   return result;
657
658  bailout:
659   gcry_free (plain);
660   if (result)
661     {
662       for (i=0; result[i]; i++)
663         gcry_mpi_release (result[i]);
664       gcry_free (result);
665     }
666   log_error ( "data error at \"%s\", offset %u\n",
667               where, (p - buffer) + startoffset);
668   return NULL;
669 }
670
671
672 /* Parse a PKCS12 object and return an array of MPI representing the
673    secret key parameters.  This is a very limited implementation in
674    that it is only able to look for 3DES encoded encryptedData and
675    tries to extract the first private key object it finds.  In case of
676    an error NULL is returned. */
677 gcry_mpi_t *
678 p12_parse (const unsigned char *buffer, size_t length, const char *pw)
679 {
680   struct tag_info ti;
681   const unsigned char *p = buffer;
682   size_t n = length;
683   const char *where;
684   int bagseqlength, len;
685
686   where = "pfx";
687   if (parse_tag (&p, &n, &ti))
688     goto bailout;
689   if (ti.tag != TAG_SEQUENCE)
690     goto bailout;
691
692   where = "pfxVersion";
693   if (parse_tag (&p, &n, &ti))
694     goto bailout;
695   if (ti.tag != TAG_INTEGER || ti.length != 1 || *p != 3)
696     goto bailout;
697   p++; n--;
698   
699   where = "authSave";
700   if (parse_tag (&p, &n, &ti))
701     goto bailout;
702   if (ti.tag != TAG_SEQUENCE)
703     goto bailout;
704   if (parse_tag (&p, &n, &ti))
705     goto bailout;
706   if (ti.tag != TAG_OBJECT_ID || ti.length != DIM(oid_data)
707       || memcmp (p, oid_data, DIM(oid_data)))
708     goto bailout;
709   p += DIM(oid_data);
710   n -= DIM(oid_data);
711
712   if (parse_tag (&p, &n, &ti))
713     goto bailout;
714   if (ti.class != CONTEXT || ti.tag)
715     goto bailout;
716   if (parse_tag (&p, &n, &ti))
717     goto bailout;
718   if (ti.class != UNIVERSAL || ti.tag != TAG_OCTET_STRING)
719     goto bailout;
720
721   where = "bags";
722   if (parse_tag (&p, &n, &ti))
723     goto bailout;
724   if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE)
725     goto bailout;
726   bagseqlength = ti.length;
727   while (bagseqlength)
728     {
729       /*log_debug ( "at offset %u\n", (p - buffer));*/
730       where = "bag-sequence";
731       if (parse_tag (&p, &n, &ti))
732         goto bailout;
733       if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE)
734         goto bailout;
735
736       if (bagseqlength < ti.nhdr)
737         goto bailout;
738       bagseqlength -= ti.nhdr;
739       if (bagseqlength < ti.length)
740         goto bailout;
741       bagseqlength -= ti.length;
742       len = ti.length;
743
744       if (parse_tag (&p, &n, &ti))
745         goto bailout;
746       len -= ti.nhdr;
747       if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_encryptedData)
748           && !memcmp (p, oid_encryptedData, DIM(oid_encryptedData)))
749         {
750           p += DIM(oid_encryptedData);
751           n -= DIM(oid_encryptedData);
752           len -= DIM(oid_encryptedData);
753           where = "bag.encryptedData";
754           if (parse_bag_encrypted_data (p, n, (p - buffer)))
755             goto bailout;
756         }
757       else if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_data)
758           && !memcmp (p, oid_data, DIM(oid_data)))
759         {
760           p += DIM(oid_data);
761           n -= DIM(oid_data);
762           len -= DIM(oid_data);
763           return parse_bag_data (p, n, (p-buffer), pw);
764         }
765       else
766         log_info ( "unknown bag type - skipped\n");
767
768       if (len < 0 || len > n)
769         goto bailout;
770       p += len;
771       n -= len;
772     }
773   
774   return NULL;
775  bailout:
776   log_error ("error at \"%s\", offset %u\n", where, (p - buffer));
777   return NULL;
778 }
779
780
781 \f
782 static size_t
783 compute_tag_length (size_t n)
784 {     
785   int needed = 0;
786
787   if (n < 128)
788     needed += 2; /* tag and one length byte */
789   else if (n < 256)
790     needed += 3; /* tag, number of length bytes, 1 length byte */
791   else if (n < 65536)
792     needed += 4; /* tag, number of length bytes, 2 length bytes */
793   else
794     {
795       log_error ("object too larger to encode\n");
796       return 0;
797     }
798   return needed;
799 }
800
801 static unsigned char *
802 store_tag_length (unsigned char *p, int tag, size_t n)
803 {     
804   if (tag == TAG_SEQUENCE)
805     tag |= 0x20; /* constructed */
806
807   *p++ = tag;
808   if (n < 128)
809     *p++ = n;
810   else if (n < 256)
811     {
812       *p++ = 0x81;
813       *p++ = n;
814     }
815   else if (n < 65536)
816     {
817       *p++ = 0x82;
818       *p++ = n >> 8;
819       *p++ = n;
820     }
821
822   return p;
823 }
824
825
826 /* Create the final PKCS-12 object from the sequences contained in
827    SEQLIST.  That array is terminated with an NULL object */
828 static unsigned char *
829 create_final (struct buffer_s *sequences, size_t *r_length)
830 {
831   int i;
832   size_t needed = 0;
833   size_t n, outseqlen, notsooutseqlen, out0taglen, octstrlen, inseqlen;
834   unsigned char *result, *p;
835   size_t resultlen;
836
837   for (i=0; sequences[i].buffer; i++)
838     needed += sequences[i].length;
839   /* This goes into a sequences. */
840   inseqlen = needed;
841   n = compute_tag_length (needed);
842   needed += n;
843   /* And encapsulate all in an octet string. */
844   octstrlen = needed;
845   n = compute_tag_length (needed);
846   needed += n;
847   /* And tag it with [0]. */
848   out0taglen = needed;
849   n = compute_tag_length (needed);
850   needed += n;
851   /* Prepend an data OID. */
852   needed += 2 + DIM (oid_data);
853   /* This all into a sequences. */
854   notsooutseqlen = needed;
855   n = compute_tag_length (needed);
856   needed += n;
857   /* Prepend the version integer 3. */
858   needed += 3;
859   /* And the final sequence. */
860   outseqlen = needed;
861   n = compute_tag_length (needed);
862   needed += n;
863
864   result = gcry_malloc (needed);
865   if (!result)
866     {
867       log_error ("error allocating buffer\n");
868       return NULL;
869     }
870   p = result;
871
872   /* Store the very outer sequence. */
873   p = store_tag_length (p, TAG_SEQUENCE, outseqlen);
874   /* Store the version integer 3. */
875   *p++ = TAG_INTEGER;
876   *p++ = 1; 
877   *p++ = 3; 
878   /* Store another sequence. */
879   p = store_tag_length (p, TAG_SEQUENCE, notsooutseqlen);
880   /* Store the data OID. */
881   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
882   memcpy (p, oid_data, DIM (oid_data)); 
883   p += DIM (oid_data); 
884   /* Next comes a context tag. */
885   p = store_tag_length (p, 0xa0, out0taglen);
886   /* And an octet string. */
887   p = store_tag_length (p, TAG_OCTET_STRING, octstrlen);
888   /* And the inner sequence. */
889   p = store_tag_length (p, TAG_SEQUENCE, inseqlen);
890   /* And append all the buffers. */
891   for (i=0; sequences[i].buffer; i++)
892     {
893       memcpy (p, sequences[i].buffer, sequences[i].length);
894       p += sequences[i].length;
895     }
896
897   /* Ready. */
898   resultlen = p - result;
899   if (needed != resultlen)
900     log_debug ("length mismatch: %u, %u\n", needed, resultlen);
901
902   *r_length = resultlen;
903   return result;
904 }
905
906
907 /* Expect the RSA key parameters in KPARMS and a password in
908    PW. Create a PKCS structure from it and return it as well as the
909    length in R_LENGTH; return NULL in case of an error. */
910 unsigned char * 
911 p12_build (gcry_mpi_t *kparms, const char *pw, size_t *r_length)
912 {
913   int rc, i;
914   size_t needed, n;
915   unsigned char *plain, *p, *cipher;
916   size_t plainlen, cipherlen;
917   size_t outseqlen, oidseqlen, octstrlen, inseqlen;
918   size_t out0taglen, in0taglen, outoctstrlen;
919   size_t aseq1len, aseq2len, aseq3len;
920   char salt[8];
921
922   needed = 3; /* The version(?) integer of value 0. */
923   for (i=0; kparms[i]; i++)
924     {
925       n = 0;
926       rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, kparms[i]);
927       if (rc)
928         {
929           log_error ("error formatting parameter: %s\n", gpg_strerror (rc));
930           return NULL;
931         }
932       needed += n;
933       n = compute_tag_length (n);
934       if (!n)
935         return NULL;
936       needed += n;
937     }
938   if (i != 8)
939     {
940       log_error ("invalid paramters for p12_build\n");
941       return NULL;
942     }
943   /* Now this all goes into a sequence. */
944   inseqlen = needed;
945   n = compute_tag_length (needed);
946   if (!n)
947     return NULL;
948   needed += n;
949   /* Encapsulate all into an octet string. */
950   octstrlen = needed;
951   n = compute_tag_length (needed);
952   if (!n)
953     return NULL;
954   needed += n;
955   /* Prepend the object identifier sequence. */
956   oidseqlen = 2 + DIM (oid_rsaEncryption) + 2;
957   needed += 2 + oidseqlen;
958   /* The version number. */
959   needed += 3;
960   /* And finally put the whole thing into a sequence. */
961   outseqlen = needed;
962   n = compute_tag_length (needed);
963   if (!n)
964     return NULL;
965   needed += n;
966   
967   /* allocate 8 extra bytes for padding */
968   plain = gcry_malloc_secure (needed+8);
969   if (!plain)
970     {
971       log_error ("error allocating encryption buffer\n");
972       return NULL;
973     }
974   
975   /* And now fill the plaintext buffer. */
976   p = plain;
977   p = store_tag_length (p, TAG_SEQUENCE, outseqlen);
978   /* Store version. */
979   *p++ = TAG_INTEGER;
980   *p++ = 1;
981   *p++ = 0;
982   /* Store object identifier sequence. */
983   p = store_tag_length (p, TAG_SEQUENCE, oidseqlen);
984   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_rsaEncryption));
985   memcpy (p, oid_rsaEncryption, DIM (oid_rsaEncryption)); 
986   p += DIM (oid_rsaEncryption); 
987   *p++ = TAG_NULL;
988   *p++ = 0;
989   /* Start with the octet string. */
990   p = store_tag_length (p, TAG_OCTET_STRING, octstrlen);
991   p = store_tag_length (p, TAG_SEQUENCE, inseqlen);
992   /* Store the key parameters. */
993   *p++ = TAG_INTEGER;
994   *p++ = 1;
995   *p++ = 0;
996   for (i=0; kparms[i]; i++)
997     {
998       n = 0;
999       rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, kparms[i]);
1000       if (rc)
1001         {
1002           log_error ("oops: error formatting parameter: %s\n",
1003                      gpg_strerror (rc));
1004           gcry_free (plain);
1005           return NULL;
1006         }
1007       p = store_tag_length (p, TAG_INTEGER, n);
1008       
1009       n = plain + needed - p;
1010       rc = gcry_mpi_print (GCRYMPI_FMT_STD, p, n, &n, kparms[i]);
1011       if (rc)
1012         {
1013           log_error ("oops: error storing parameter: %s\n",
1014                      gpg_strerror (rc));
1015           gcry_free (plain);
1016           return NULL;
1017         }
1018       p += n;
1019     }
1020
1021   plainlen = p - plain;
1022   assert (needed == plainlen);
1023   /* Append some pad characters; we already allocated extra space. */
1024   n = 8 - plainlen % 8;
1025   for (;(plainlen % 8); plainlen++)
1026     *p++ = n;
1027
1028   {
1029     FILE *fp = fopen("inner-out.der", "wb");
1030     fwrite (plain, 1, plainlen, fp);
1031     fclose (fp);
1032   }
1033
1034
1035   /* Encrypt it and prepend a lot of stupid things. */
1036   gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
1037   crypt_block (plain, plainlen, salt, 1024, pw, 1);
1038   /* the data goes into an octet string. */
1039   needed = compute_tag_length (plainlen);
1040   needed += plainlen;
1041   /* we prepend the the algorithm identifier (we use a pre-encoded one)*/
1042   needed += DIM (data_3desiter1024);
1043   /* we put a sequence around. */
1044   aseq3len = needed;
1045   needed += compute_tag_length (needed);
1046   /* Prepend it with a [0] tag. */
1047   in0taglen = needed;
1048   needed += compute_tag_length (needed);
1049   /* Prepend that shroudedKeyBag OID. */
1050   needed += 2 + DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag);
1051   /* Put it all into two sequence. */
1052   aseq2len = needed;
1053   needed += compute_tag_length ( needed);
1054   aseq1len = needed;
1055   needed += compute_tag_length (needed);
1056   /* This all goes into an octet string. */
1057   outoctstrlen = needed;
1058   needed += compute_tag_length (needed);
1059   /* Prepend it with a [0] tag. */
1060   out0taglen = needed;
1061   needed += compute_tag_length (needed);
1062   /* Prepend the data OID. */
1063   needed += 2 + DIM (oid_data);
1064   /* And a sequence. */
1065   outseqlen = needed;
1066   needed += compute_tag_length (needed);
1067
1068   cipher = gcry_malloc (needed);
1069   if (!cipher)
1070     {
1071       log_error ("error allocating buffer\n");
1072       gcry_free (plain);
1073       return NULL;
1074     }
1075   p = cipher;
1076   /* Store the first sequence. */
1077   p = store_tag_length (p, TAG_SEQUENCE, outseqlen);
1078   /* Store the data OID. */
1079   p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
1080   memcpy (p, oid_data, DIM (oid_data)); 
1081   p += DIM (oid_data); 
1082   /* Next comes a context tag. */
1083   p = store_tag_length (p, 0xa0, out0taglen);
1084   /* And an octet string. */
1085   p = store_tag_length (p, TAG_OCTET_STRING, outoctstrlen);
1086   /* Two sequences. */
1087   p = store_tag_length (p, TAG_SEQUENCE, aseq1len);
1088   p = store_tag_length (p, TAG_SEQUENCE, aseq2len);
1089   /* Store the shroudedKeyBag OID. */
1090   p = store_tag_length (p, TAG_OBJECT_ID,
1091                         DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag));
1092   memcpy (p, oid_pkcs_12_pkcs_8ShroudedKeyBag,
1093           DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag)); 
1094   p += DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag); 
1095   /* Next comes a context tag. */
1096   p = store_tag_length (p, 0xa0, in0taglen);
1097   /* And a sequence. */
1098   p = store_tag_length (p, TAG_SEQUENCE, aseq3len);
1099   /* Now for the pre-encoded algorithm indentifier and the salt. */
1100   memcpy (p, data_3desiter1024, DIM (data_3desiter1024));
1101   memcpy (p + DATA_3DESITER1024_SALT_OFF, salt, 8);
1102   p += DIM (data_3desiter1024);
1103   /* And finally the octet string with the encrypted data. */
1104   p = store_tag_length (p, TAG_OCTET_STRING, plainlen);
1105   memcpy (p, plain, plainlen);
1106   p += plainlen;
1107   cipherlen = p - cipher;
1108   
1109   if (needed != cipherlen)
1110     log_debug ("length mismatch: %u, %u\n", needed, cipherlen);
1111   gcry_free (plain);
1112
1113   {
1114     struct buffer_s seqlist[2];
1115
1116     seqlist[0].buffer = cipher;
1117     seqlist[0].length = cipherlen;
1118     seqlist[1].buffer = NULL;
1119     seqlist[1].length = 0;
1120
1121     cipher = create_final (seqlist, &cipherlen);
1122     gcry_free (seqlist[0].buffer);
1123   }
1124
1125   *r_length = cipherlen;
1126   return cipher;
1127 }
1128
1129
1130 #ifdef TEST
1131 int
1132 main (int argc, char **argv)
1133 {
1134   FILE *fp;
1135   struct stat st;
1136   char *buf;
1137   size_t buflen;
1138   GcryMPI *result;
1139
1140   if (argc != 3)
1141     {
1142       fprintf (stderr, "usage: testp12 file passphrase\n");
1143       return 1;
1144     }
1145
1146   gcry_control (GCRYCTL_DISABLE_SECMEM, NULL);
1147   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL);
1148
1149   fp = fopen (argv[1], "rb");
1150   if (!fp)
1151     {
1152       fprintf (stderr, "can't open `%s': %s\n", argv[1], strerror (errno));
1153       return 1;
1154     }
1155   
1156   if (fstat (fileno(fp), &st))
1157     {
1158       fprintf (stderr, "can't stat `%s': %s\n", argv[1], strerror (errno));
1159       return 1;
1160     }
1161
1162   buflen = st.st_size;
1163   buf = gcry_malloc (buflen+1);
1164   if (!buf || fread (buf, buflen, 1, fp) != 1)
1165     {
1166       fprintf (stderr, "error reading `%s': %s\n", argv[1], strerror (errno));
1167       return 1;
1168     }
1169   fclose (fp);
1170
1171   result = p12_parse (buf, buflen, argv[2]);
1172   if (result)
1173     {
1174       int i, rc;
1175       char *buf;
1176
1177       for (i=0; result[i]; i++)
1178         {
1179           rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, (void**)&buf,
1180                                 NULL, result[i]);
1181           if (rc)
1182             printf ("%d: [error printing number: %s]\n",
1183                     i, gpg_strerror (rc));
1184           else
1185             {
1186               printf ("%d: %s\n", i, buf);
1187               gcry_free (buf);
1188             }
1189         }
1190     }
1191
1192   return 0;
1193
1194 }
1195 #endif /* TEST */