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