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