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