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