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