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