2009-05-15 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / agent / minip12.c
blob6b65c8c3633d1b876e8ed8b9ea4a297a601eab55
1 /* minip12.c - A minimal pkcs-12 implementation.
2 * Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
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 3 of the License, or
9 * (at your option) any later version.
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.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <assert.h>
27 #include <gcrypt.h>
28 #include <errno.h>
30 #ifdef TEST
31 #include <sys/stat.h>
32 #include <unistd.h>
33 #endif
35 #include "../jnlib/logging.h"
36 #include "../jnlib/utf8conv.h"
37 #include "minip12.h"
39 #ifndef DIM
40 #define DIM(v) (sizeof(v)/sizeof((v)[0]))
41 #endif
44 enum
46 UNIVERSAL = 0,
47 APPLICATION = 1,
48 ASNCONTEXT = 2,
49 PRIVATE = 3
53 enum
55 TAG_NONE = 0,
56 TAG_BOOLEAN = 1,
57 TAG_INTEGER = 2,
58 TAG_BIT_STRING = 3,
59 TAG_OCTET_STRING = 4,
60 TAG_NULL = 5,
61 TAG_OBJECT_ID = 6,
62 TAG_OBJECT_DESCRIPTOR = 7,
63 TAG_EXTERNAL = 8,
64 TAG_REAL = 9,
65 TAG_ENUMERATED = 10,
66 TAG_EMBEDDED_PDV = 11,
67 TAG_UTF8_STRING = 12,
68 TAG_REALTIVE_OID = 13,
69 TAG_SEQUENCE = 16,
70 TAG_SET = 17,
71 TAG_NUMERIC_STRING = 18,
72 TAG_PRINTABLE_STRING = 19,
73 TAG_TELETEX_STRING = 20,
74 TAG_VIDEOTEX_STRING = 21,
75 TAG_IA5_STRING = 22,
76 TAG_UTC_TIME = 23,
77 TAG_GENERALIZED_TIME = 24,
78 TAG_GRAPHIC_STRING = 25,
79 TAG_VISIBLE_STRING = 26,
80 TAG_GENERAL_STRING = 27,
81 TAG_UNIVERSAL_STRING = 28,
82 TAG_CHARACTER_STRING = 29,
83 TAG_BMP_STRING = 30
87 static unsigned char const oid_data[9] = {
88 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01 };
89 static unsigned char const oid_encryptedData[9] = {
90 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06 };
91 static unsigned char const oid_pkcs_12_keyBag[11] = {
92 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x01 };
93 static unsigned char const oid_pkcs_12_pkcs_8ShroudedKeyBag[11] = {
94 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x02 };
95 static unsigned char const oid_pkcs_12_CertBag[11] = {
96 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x03 };
97 static unsigned char const oid_pkcs_12_CrlBag[11] = {
98 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x04 };
100 static unsigned char const oid_pbeWithSHAAnd3_KeyTripleDES_CBC[10] = {
101 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03 };
102 static unsigned char const oid_pbeWithSHAAnd40BitRC2_CBC[10] = {
103 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x06 };
104 static unsigned char const oid_x509Certificate_for_pkcs_12[10] = {
105 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x16, 0x01 };
108 static unsigned char const oid_rsaEncryption[9] = {
109 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 };
112 static unsigned char const data_3desiter2048[30] = {
113 0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86,
114 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30, 0x0E,
115 0x04, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
116 0xFF, 0xFF, 0x02, 0x02, 0x08, 0x00 };
117 #define DATA_3DESITER2048_SALT_OFF 18
119 static unsigned char const data_rc2iter2048[30] = {
120 0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86,
121 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x06, 0x30, 0x0E,
122 0x04, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
123 0xFF, 0xFF, 0x02, 0x02, 0x08, 0x00 };
124 #define DATA_RC2ITER2048_SALT_OFF 18
126 static unsigned char const data_mactemplate[51] = {
127 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
128 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04,
129 0x14, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
130 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
131 0xff, 0xff, 0xff, 0xff, 0xff, 0x04, 0x08, 0xff,
132 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02,
133 0x02, 0x08, 0x00 };
134 #define DATA_MACTEMPLATE_MAC_OFF 17
135 #define DATA_MACTEMPLATE_SALT_OFF 39
137 static unsigned char const data_attrtemplate[106] = {
138 0x31, 0x7c, 0x30, 0x55, 0x06, 0x09, 0x2a, 0x86,
139 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x14, 0x31,
140 0x48, 0x1e, 0x46, 0x00, 0x47, 0x00, 0x6e, 0x00,
141 0x75, 0x00, 0x50, 0x00, 0x47, 0x00, 0x20, 0x00,
142 0x65, 0x00, 0x78, 0x00, 0x70, 0x00, 0x6f, 0x00,
143 0x72, 0x00, 0x74, 0x00, 0x65, 0x00, 0x64, 0x00,
144 0x20, 0x00, 0x63, 0x00, 0x65, 0x00, 0x72, 0x00,
145 0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00,
146 0x63, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00,
147 0x20, 0x00, 0x66, 0x00, 0x66, 0x00, 0x66, 0x00,
148 0x66, 0x00, 0x66, 0x00, 0x66, 0x00, 0x66, 0x00,
149 0x66, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48,
150 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x15, 0x31, 0x16,
151 0x04, 0x14 }; /* Need to append SHA-1 digest. */
152 #define DATA_ATTRTEMPLATE_KEYID_OFF 73
154 struct buffer_s
156 unsigned char *buffer;
157 size_t length;
161 struct tag_info
163 int class;
164 int is_constructed;
165 unsigned long tag;
166 unsigned long length; /* length part of the TLV */
167 int nhdr;
168 int ndef; /* It is an indefinite length */
172 /* Parse the buffer at the address BUFFER which is of SIZE and return
173 the tag and the length part from the TLV triplet. Update BUFFER
174 and SIZE on success. Checks that the encoded length does not
175 exhaust the length of the provided buffer. */
176 static int
177 parse_tag (unsigned char const **buffer, size_t *size, struct tag_info *ti)
179 int c;
180 unsigned long tag;
181 const unsigned char *buf = *buffer;
182 size_t length = *size;
184 ti->length = 0;
185 ti->ndef = 0;
186 ti->nhdr = 0;
188 /* Get the tag */
189 if (!length)
190 return -1; /* premature eof */
191 c = *buf++; length--;
192 ti->nhdr++;
194 ti->class = (c & 0xc0) >> 6;
195 ti->is_constructed = !!(c & 0x20);
196 tag = c & 0x1f;
198 if (tag == 0x1f)
200 tag = 0;
203 tag <<= 7;
204 if (!length)
205 return -1; /* premature eof */
206 c = *buf++; length--;
207 ti->nhdr++;
208 tag |= c & 0x7f;
210 while (c & 0x80);
212 ti->tag = tag;
214 /* Get the length */
215 if (!length)
216 return -1; /* prematureeof */
217 c = *buf++; length--;
218 ti->nhdr++;
220 if ( !(c & 0x80) )
221 ti->length = c;
222 else if (c == 0x80)
223 ti->ndef = 1;
224 else if (c == 0xff)
225 return -1; /* forbidden length value */
226 else
228 unsigned long len = 0;
229 int count = c & 0x7f;
231 for (; count; count--)
233 len <<= 8;
234 if (!length)
235 return -1; /* premature_eof */
236 c = *buf++; length--;
237 ti->nhdr++;
238 len |= c & 0xff;
240 ti->length = len;
243 if (ti->class == UNIVERSAL && !ti->tag)
244 ti->length = 0;
246 if (ti->length > length)
247 return -1; /* data larger than buffer. */
249 *buffer = buf;
250 *size = length;
251 return 0;
255 /* Given an ASN.1 chunk of a structure like:
257 24 NDEF: OCTET STRING -- This is not passed to us
258 04 1: OCTET STRING -- INPUT point s to here
259 : 30
260 04 1: OCTET STRING
261 : 80
262 [...]
263 04 2: OCTET STRING
264 : 00 00
265 : } -- This denotes a Null tag and are the last
266 -- two bytes in INPUT.
268 Create a new buffer with the content of that octet string. INPUT
269 is the orginal buffer with a length as stored at LENGTH. Returns
270 NULL on error or a new malloced buffer with the length of this new
271 buffer stored at LENGTH and the number of bytes parsed from input
272 are added to the value stored at INPUT_CONSUMED. INPUT_CONSUMED is
273 allowed to be passed as NULL if the caller is not interested in
274 this value. */
275 static unsigned char *
276 cram_octet_string (const unsigned char *input, size_t *length,
277 size_t *input_consumed)
279 const unsigned char *s = input;
280 size_t n = *length;
281 unsigned char *output, *d;
282 struct tag_info ti;
284 /* Allocate output buf. We know that it won't be longer than the
285 input buffer. */
286 d = output = gcry_malloc (n);
287 if (!output)
288 goto bailout;
290 for (;;)
292 if (parse_tag (&s, &n, &ti))
293 goto bailout;
294 if (ti.class == UNIVERSAL && ti.tag == TAG_OCTET_STRING
295 && !ti.ndef && !ti.is_constructed)
297 memcpy (d, s, ti.length);
298 s += ti.length;
299 d += ti.length;
300 n -= ti.length;
302 else if (ti.class == UNIVERSAL && !ti.tag && !ti.is_constructed)
303 break; /* Ready */
304 else
305 goto bailout;
309 *length = d - output;
310 if (input_consumed)
311 *input_consumed += s - input;
312 return output;
314 bailout:
315 if (input_consumed)
316 *input_consumed += s - input;
317 gcry_free (output);
318 return NULL;
323 static int
324 string_to_key (int id, char *salt, size_t saltlen, int iter, const char *pw,
325 int req_keylen, unsigned char *keybuf)
327 int rc, i, j;
328 gcry_md_hd_t md;
329 gcry_mpi_t num_b1 = NULL;
330 int pwlen;
331 unsigned char hash[20], buf_b[64], buf_i[128], *p;
332 size_t cur_keylen;
333 size_t n;
335 cur_keylen = 0;
336 pwlen = strlen (pw);
337 if (pwlen > 63/2)
339 log_error ("password too long\n");
340 return -1;
343 if (saltlen < 8)
345 log_error ("salt too short\n");
346 return -1;
349 /* Store salt and password in BUF_I */
350 p = buf_i;
351 for(i=0; i < 64; i++)
352 *p++ = salt [i%saltlen];
353 for(i=j=0; i < 64; i += 2)
355 *p++ = 0;
356 *p++ = pw[j];
357 if (++j > pwlen) /* Note, that we include the trailing zero */
358 j = 0;
361 for (;;)
363 rc = gcry_md_open (&md, GCRY_MD_SHA1, 0);
364 if (rc)
366 log_error ( "gcry_md_open failed: %s\n", gpg_strerror (rc));
367 return rc;
369 for(i=0; i < 64; i++)
370 gcry_md_putc (md, id);
371 gcry_md_write (md, buf_i, 128);
372 memcpy (hash, gcry_md_read (md, 0), 20);
373 gcry_md_close (md);
374 for (i=1; i < iter; i++)
375 gcry_md_hash_buffer (GCRY_MD_SHA1, hash, hash, 20);
377 for (i=0; i < 20 && cur_keylen < req_keylen; i++)
378 keybuf[cur_keylen++] = hash[i];
379 if (cur_keylen == req_keylen)
381 gcry_mpi_release (num_b1);
382 return 0; /* ready */
385 /* need more bytes. */
386 for(i=0; i < 64; i++)
387 buf_b[i] = hash[i % 20];
388 rc = gcry_mpi_scan (&num_b1, GCRYMPI_FMT_USG, buf_b, 64, &n);
389 if (rc)
391 log_error ( "gcry_mpi_scan failed: %s\n", gpg_strerror (rc));
392 return -1;
394 gcry_mpi_add_ui (num_b1, num_b1, 1);
395 for (i=0; i < 128; i += 64)
397 gcry_mpi_t num_ij;
399 rc = gcry_mpi_scan (&num_ij, GCRYMPI_FMT_USG, buf_i + i, 64, &n);
400 if (rc)
402 log_error ( "gcry_mpi_scan failed: %s\n",
403 gpg_strerror (rc));
404 return -1;
406 gcry_mpi_add (num_ij, num_ij, num_b1);
407 gcry_mpi_clear_highbit (num_ij, 64*8);
408 rc = gcry_mpi_print (GCRYMPI_FMT_USG, buf_i + i, 64, &n, num_ij);
409 if (rc)
411 log_error ( "gcry_mpi_print failed: %s\n",
412 gpg_strerror (rc));
413 return -1;
415 gcry_mpi_release (num_ij);
421 static int
422 set_key_iv (gcry_cipher_hd_t chd, char *salt, size_t saltlen, int iter,
423 const char *pw, int keybytes)
425 unsigned char keybuf[24];
426 int rc;
428 assert (keybytes == 5 || keybytes == 24);
429 if (string_to_key (1, salt, saltlen, iter, pw, keybytes, keybuf))
430 return -1;
431 rc = gcry_cipher_setkey (chd, keybuf, keybytes);
432 if (rc)
434 log_error ( "gcry_cipher_setkey failed: %s\n", gpg_strerror (rc));
435 return -1;
438 if (string_to_key (2, salt, saltlen, iter, pw, 8, keybuf))
439 return -1;
440 rc = gcry_cipher_setiv (chd, keybuf, 8);
441 if (rc)
443 log_error ("gcry_cipher_setiv failed: %s\n", gpg_strerror (rc));
444 return -1;
446 return 0;
450 static void
451 crypt_block (unsigned char *buffer, size_t length, char *salt, size_t saltlen,
452 int iter, const char *pw, int cipher_algo, int encrypt)
454 gcry_cipher_hd_t chd;
455 int rc;
457 rc = gcry_cipher_open (&chd, cipher_algo, GCRY_CIPHER_MODE_CBC, 0);
458 if (rc)
460 log_error ( "gcry_cipher_open failed: %s\n", gpg_strerror(rc));
461 wipememory (buffer, length);
462 return;
464 if (set_key_iv (chd, salt, saltlen, iter, pw,
465 cipher_algo == GCRY_CIPHER_RFC2268_40? 5:24))
467 wipememory (buffer, length);
468 goto leave;
471 rc = encrypt? gcry_cipher_encrypt (chd, buffer, length, NULL, 0)
472 : gcry_cipher_decrypt (chd, buffer, length, NULL, 0);
474 if (rc)
476 wipememory (buffer, length);
477 log_error ( "en/de-crytion failed: %s\n", gpg_strerror (rc));
478 goto leave;
481 leave:
482 gcry_cipher_close (chd);
486 /* Decrypt a block of data and try several encodings of the key.
487 CIPHERTEXT is the encrypted data of size LENGTH bytes; PLAINTEXT is
488 a buffer of the same size to receive the decryption result. SALT,
489 SALTLEN, ITER and PW are the information required for decryption
490 and CIPHER_ALGO is the algorithm id to use. CHECK_FNC is a
491 function called with the plaintext and used to check whether the
492 decryption succeeded; i.e. that a correct passphrase has been
493 given. That function shall return true if the decryption has likely
494 succeeded. */
495 static void
496 decrypt_block (const void *ciphertext, unsigned char *plaintext, size_t length,
497 char *salt, size_t saltlen,
498 int iter, const char *pw, int cipher_algo,
499 int (*check_fnc) (const void *, size_t))
501 static const char * const charsets[] = {
502 "", /* No conversion - use the UTF-8 passphrase direct. */
503 "ISO-8859-1",
504 "ISO-8859-15",
505 "ISO-8859-2",
506 "ISO-8859-3",
507 "ISO-8859-4",
508 "ISO-8859-5",
509 "ISO-8859-6",
510 "ISO-8859-7",
511 "ISO-8859-8",
512 "ISO-8859-9",
513 "KOI8-R",
514 "IBM437",
515 "IBM850",
516 "EUC-JP",
517 "BIG5",
518 NULL
520 int charsetidx = 0;
521 char *convertedpw = NULL; /* Malloced and converted password or NULL. */
522 size_t convertedpwsize = 0; /* Allocated length. */
524 for (charsetidx=0; charsets[charsetidx]; charsetidx++)
526 if (*charsets[charsetidx])
528 jnlib_iconv_t cd;
529 const char *inptr;
530 char *outptr;
531 size_t inbytes, outbytes;
533 if (!convertedpw)
535 /* We assume one byte encodings. Thus we can allocate
536 the buffer of the same size as the original
537 passphrase; the result will actually be shorter
538 then. */
539 convertedpwsize = strlen (pw) + 1;
540 convertedpw = gcry_malloc_secure (convertedpwsize);
541 if (!convertedpw)
543 log_info ("out of secure memory while"
544 " converting passphrase\n");
545 break; /* Give up. */
549 cd = jnlib_iconv_open (charsets[charsetidx], "utf-8");
550 if (cd == (jnlib_iconv_t)(-1))
551 continue;
553 inptr = pw;
554 inbytes = strlen (pw);
555 outptr = convertedpw;
556 outbytes = convertedpwsize - 1;
557 if ( jnlib_iconv (cd, (const char **)&inptr, &inbytes,
558 &outptr, &outbytes) == (size_t)-1)
560 jnlib_iconv_close (cd);
561 continue;
563 *outptr = 0;
564 jnlib_iconv_close (cd);
565 log_info ("decryption failed; trying charset `%s'\n",
566 charsets[charsetidx]);
568 memcpy (plaintext, ciphertext, length);
569 crypt_block (plaintext, length, salt, saltlen, iter,
570 convertedpw? convertedpw:pw, cipher_algo, 0);
571 if (check_fnc (plaintext, length))
572 break; /* Decryption succeeded. */
574 gcry_free (convertedpw);
578 /* Return true if the decryption of an bag_encrypted_data object has
579 likely succeeded. */
580 static int
581 bag_decrypted_data_p (const void *plaintext, size_t length)
583 struct tag_info ti;
584 const unsigned char *p = plaintext;
585 size_t n = length;
587 /* { */
588 /* # warning debug code is enabled */
589 /* FILE *fp = fopen ("tmp-rc2-plain.der", "wb"); */
590 /* if (!fp || fwrite (p, n, 1, fp) != 1) */
591 /* exit (2); */
592 /* fclose (fp); */
593 /* } */
595 if (parse_tag (&p, &n, &ti))
596 return 0;
597 if (ti.class || ti.tag != TAG_SEQUENCE)
598 return 0;
599 if (parse_tag (&p, &n, &ti))
600 return 0;
602 return 1;
605 /* Note: If R_RESULT is passed as NULL, a key object as already be
606 processed and thus we need to skip it here. */
607 static int
608 parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
609 int startoffset, size_t *r_consumed, const char *pw,
610 void (*certcb)(void*, const unsigned char*, size_t),
611 void *certcbarg, gcry_mpi_t **r_result)
613 struct tag_info ti;
614 const unsigned char *p = buffer;
615 const unsigned char *p_start = buffer;
616 size_t n = length;
617 const char *where;
618 char salt[20];
619 size_t saltlen;
620 unsigned int iter;
621 unsigned char *plain = NULL;
622 int bad_pass = 0;
623 unsigned char *cram_buffer = NULL;
624 size_t consumed = 0; /* Number of bytes consumed from the orginal buffer. */
625 int is_3des = 0;
626 gcry_mpi_t *result = NULL;
627 int result_count;
629 if (r_result)
630 *r_result = NULL;
631 where = "start";
632 if (parse_tag (&p, &n, &ti))
633 goto bailout;
634 if (ti.class != ASNCONTEXT || ti.tag)
635 goto bailout;
636 if (parse_tag (&p, &n, &ti))
637 goto bailout;
638 if (ti.tag != TAG_SEQUENCE)
639 goto bailout;
641 where = "bag.encryptedData.version";
642 if (parse_tag (&p, &n, &ti))
643 goto bailout;
644 if (ti.tag != TAG_INTEGER || ti.length != 1 || *p != 0)
645 goto bailout;
646 p++; n--;
647 if (parse_tag (&p, &n, &ti))
648 goto bailout;
649 if (ti.tag != TAG_SEQUENCE)
650 goto bailout;
652 where = "bag.encryptedData.data";
653 if (parse_tag (&p, &n, &ti))
654 goto bailout;
655 if (ti.tag != TAG_OBJECT_ID || ti.length != DIM(oid_data)
656 || memcmp (p, oid_data, DIM(oid_data)))
657 goto bailout;
658 p += DIM(oid_data);
659 n -= DIM(oid_data);
661 where = "bag.encryptedData.keyinfo";
662 if (parse_tag (&p, &n, &ti))
663 goto bailout;
664 if (ti.class || ti.tag != TAG_SEQUENCE)
665 goto bailout;
666 if (parse_tag (&p, &n, &ti))
667 goto bailout;
668 if (!ti.class && ti.tag == TAG_OBJECT_ID
669 && ti.length == DIM(oid_pbeWithSHAAnd40BitRC2_CBC)
670 && !memcmp (p, oid_pbeWithSHAAnd40BitRC2_CBC,
671 DIM(oid_pbeWithSHAAnd40BitRC2_CBC)))
673 p += DIM(oid_pbeWithSHAAnd40BitRC2_CBC);
674 n -= DIM(oid_pbeWithSHAAnd40BitRC2_CBC);
676 else if (!ti.class && ti.tag == TAG_OBJECT_ID
677 && ti.length == DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)
678 && !memcmp (p, oid_pbeWithSHAAnd3_KeyTripleDES_CBC,
679 DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)))
681 p += DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
682 n -= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
683 is_3des = 1;
685 else
686 goto bailout;
688 where = "rc2or3des-params";
689 if (parse_tag (&p, &n, &ti))
690 goto bailout;
691 if (ti.class || ti.tag != TAG_SEQUENCE)
692 goto bailout;
693 if (parse_tag (&p, &n, &ti))
694 goto bailout;
695 if (ti.class || ti.tag != TAG_OCTET_STRING
696 || ti.length < 8 || ti.length > 20 )
697 goto bailout;
698 saltlen = ti.length;
699 memcpy (salt, p, saltlen);
700 p += saltlen;
701 n -= saltlen;
702 if (parse_tag (&p, &n, &ti))
703 goto bailout;
704 if (ti.class || ti.tag != TAG_INTEGER || !ti.length )
705 goto bailout;
706 for (iter=0; ti.length; ti.length--)
708 iter <<= 8;
709 iter |= (*p++) & 0xff;
710 n--;
713 where = "rc2or3des-ciphertext";
714 if (parse_tag (&p, &n, &ti))
715 goto bailout;
717 consumed = p - p_start;
718 if (ti.class == ASNCONTEXT && ti.tag == 0 && ti.is_constructed && ti.ndef)
720 /* Mozilla exported certs now come with single byte chunks of
721 octect strings. (Mozilla Firefox 1.0.4). Arghh. */
722 where = "cram-rc2or3des-ciphertext";
723 cram_buffer = cram_octet_string ( p, &n, &consumed);
724 if (!cram_buffer)
725 goto bailout;
726 p = p_start = cram_buffer;
727 if (r_consumed)
728 *r_consumed = consumed;
729 r_consumed = NULL; /* Ugly hack to not update that value any further. */
730 ti.length = n;
732 else if (ti.class == ASNCONTEXT && ti.tag == 0 && ti.length )
734 else
735 goto bailout;
737 log_info ("%lu bytes of %s encrypted text\n",ti.length,is_3des?"3DES":"RC2");
739 plain = gcry_malloc_secure (ti.length);
740 if (!plain)
742 log_error ("error allocating decryption buffer\n");
743 goto bailout;
745 decrypt_block (p, plain, ti.length, salt, saltlen, iter, pw,
746 is_3des? GCRY_CIPHER_3DES : GCRY_CIPHER_RFC2268_40,
747 bag_decrypted_data_p);
748 n = ti.length;
749 startoffset = 0;
750 p_start = p = plain;
752 where = "outer.outer.seq";
753 if (parse_tag (&p, &n, &ti))
755 bad_pass = 1;
756 goto bailout;
758 if (ti.class || ti.tag != TAG_SEQUENCE)
760 bad_pass = 1;
761 goto bailout;
764 if (parse_tag (&p, &n, &ti))
766 bad_pass = 1;
767 goto bailout;
770 /* Loop over all certificates inside the bag. */
771 while (n)
773 int iscrlbag = 0;
774 int iskeybag = 0;
776 where = "certbag.nextcert";
777 if (ti.class || ti.tag != TAG_SEQUENCE)
778 goto bailout;
780 where = "certbag.objectidentifier";
781 if (parse_tag (&p, &n, &ti))
782 goto bailout;
783 if (ti.class || ti.tag != TAG_OBJECT_ID)
784 goto bailout;
785 if ( ti.length == DIM(oid_pkcs_12_CertBag)
786 && !memcmp (p, oid_pkcs_12_CertBag, DIM(oid_pkcs_12_CertBag)))
788 p += DIM(oid_pkcs_12_CertBag);
789 n -= DIM(oid_pkcs_12_CertBag);
791 else if ( ti.length == DIM(oid_pkcs_12_CrlBag)
792 && !memcmp (p, oid_pkcs_12_CrlBag, DIM(oid_pkcs_12_CrlBag)))
794 p += DIM(oid_pkcs_12_CrlBag);
795 n -= DIM(oid_pkcs_12_CrlBag);
796 iscrlbag = 1;
798 else if ( ti.length == DIM(oid_pkcs_12_keyBag)
799 && !memcmp (p, oid_pkcs_12_keyBag, DIM(oid_pkcs_12_keyBag)))
801 /* The TrustedMIME plugin for MS Outlook started to create
802 files with just one outer 3DES encrypted container and
803 inside the certificates as well as the key. */
804 p += DIM(oid_pkcs_12_keyBag);
805 n -= DIM(oid_pkcs_12_keyBag);
806 iskeybag = 1;
808 else
809 goto bailout;
811 where = "certbag.before.certheader";
812 if (parse_tag (&p, &n, &ti))
813 goto bailout;
814 if (ti.class != ASNCONTEXT || ti.tag)
815 goto bailout;
816 if (iscrlbag)
818 log_info ("skipping unsupported crlBag\n");
819 p += ti.length;
820 n -= ti.length;
822 else if (iskeybag && (result || !r_result))
824 log_info ("one keyBag already processed; skipping this one\n");
825 p += ti.length;
826 n -= ti.length;
828 else if (iskeybag)
830 int len;
832 log_info ("processing simple keyBag\n");
834 /* Fixme: This code is duplicated from parse_bag_data. */
835 if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
836 goto bailout;
837 if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER
838 || ti.length != 1 || *p)
839 goto bailout;
840 p++; n--;
841 if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
842 goto bailout;
843 len = ti.length;
844 if (parse_tag (&p, &n, &ti))
845 goto bailout;
846 if (len < ti.nhdr)
847 goto bailout;
848 len -= ti.nhdr;
849 if (ti.class || ti.tag != TAG_OBJECT_ID
850 || ti.length != DIM(oid_rsaEncryption)
851 || memcmp (p, oid_rsaEncryption,
852 DIM(oid_rsaEncryption)))
853 goto bailout;
854 p += DIM (oid_rsaEncryption);
855 n -= DIM (oid_rsaEncryption);
856 if (len < ti.length)
857 goto bailout;
858 len -= ti.length;
859 if (n < len)
860 goto bailout;
861 p += len;
862 n -= len;
863 if ( parse_tag (&p, &n, &ti)
864 || ti.class || ti.tag != TAG_OCTET_STRING)
865 goto bailout;
866 if ( parse_tag (&p, &n, &ti)
867 || ti.class || ti.tag != TAG_SEQUENCE)
868 goto bailout;
869 len = ti.length;
871 result = gcry_calloc (10, sizeof *result);
872 if (!result)
874 log_error ( "error allocating result array\n");
875 goto bailout;
877 result_count = 0;
879 where = "reading.keybag.key-parameters";
880 for (result_count = 0; len && result_count < 9;)
882 if ( parse_tag (&p, &n, &ti)
883 || ti.class || ti.tag != TAG_INTEGER)
884 goto bailout;
885 if (len < ti.nhdr)
886 goto bailout;
887 len -= ti.nhdr;
888 if (len < ti.length)
889 goto bailout;
890 len -= ti.length;
891 if (!result_count && ti.length == 1 && !*p)
892 ; /* ignore the very first one if it is a 0 */
893 else
895 int rc;
897 rc = gcry_mpi_scan (result+result_count, GCRYMPI_FMT_USG, p,
898 ti.length, NULL);
899 if (rc)
901 log_error ("error parsing key parameter: %s\n",
902 gpg_strerror (rc));
903 goto bailout;
905 result_count++;
907 p += ti.length;
908 n -= ti.length;
910 if (len)
911 goto bailout;
913 else
915 log_info ("processing certBag\n");
916 if (parse_tag (&p, &n, &ti))
917 goto bailout;
918 if (ti.class || ti.tag != TAG_SEQUENCE)
919 goto bailout;
920 if (parse_tag (&p, &n, &ti))
921 goto bailout;
922 if (ti.class || ti.tag != TAG_OBJECT_ID
923 || ti.length != DIM(oid_x509Certificate_for_pkcs_12)
924 || memcmp (p, oid_x509Certificate_for_pkcs_12,
925 DIM(oid_x509Certificate_for_pkcs_12)))
926 goto bailout;
927 p += DIM(oid_x509Certificate_for_pkcs_12);
928 n -= DIM(oid_x509Certificate_for_pkcs_12);
930 where = "certbag.before.octetstring";
931 if (parse_tag (&p, &n, &ti))
932 goto bailout;
933 if (ti.class != ASNCONTEXT || ti.tag)
934 goto bailout;
935 if (parse_tag (&p, &n, &ti))
936 goto bailout;
937 if (ti.class || ti.tag != TAG_OCTET_STRING || ti.ndef)
938 goto bailout;
940 /* Return the certificate. */
941 if (certcb)
942 certcb (certcbarg, p, ti.length);
944 p += ti.length;
945 n -= ti.length;
948 /* Ugly hack to cope with the padding: Forget about the rest if
949 that is less or equal to the cipher's block length. We can
950 reasonable assume that all valid data will be longer than
951 just one block. */
952 if (n <= 8)
953 n = 0;
955 /* Skip the optional SET with the pkcs12 cert attributes. */
956 if (n)
958 where = "bag.attributes";
959 if (parse_tag (&p, &n, &ti))
960 goto bailout;
961 if (!ti.class && ti.tag == TAG_SEQUENCE)
962 ; /* No attributes. */
963 else if (!ti.class && ti.tag == TAG_SET && !ti.ndef)
964 { /* The optional SET. */
965 p += ti.length;
966 n -= ti.length;
967 if (n <= 8)
968 n = 0;
969 if (n && parse_tag (&p, &n, &ti))
970 goto bailout;
972 else
973 goto bailout;
977 if (r_consumed)
978 *r_consumed = consumed;
979 gcry_free (plain);
980 gcry_free (cram_buffer);
981 if (r_result)
982 *r_result = result;
983 return 0;
985 bailout:
986 if (result)
988 int i;
990 for (i=0; result[i]; i++)
991 gcry_mpi_release (result[i]);
992 gcry_free (result);
994 if (r_consumed)
995 *r_consumed = consumed;
996 gcry_free (plain);
997 gcry_free (cram_buffer);
998 log_error ("encryptedData error at \"%s\", offset %u\n",
999 where, (unsigned int)((p - p_start)+startoffset));
1000 if (bad_pass)
1002 /* Note, that the following string might be used by other programs
1003 to check for a bad passphrase; it should therefore not be
1004 translated or changed. */
1005 log_error ("possibly bad passphrase given\n");
1007 return -1;
1011 /* Return true if the decryption of a bag_data object has likely
1012 succeeded. */
1013 static int
1014 bag_data_p (const void *plaintext, size_t length)
1016 struct tag_info ti;
1017 const unsigned char *p = plaintext;
1018 size_t n = length;
1020 /* { */
1021 /* # warning debug code is enabled */
1022 /* FILE *fp = fopen ("tmp-3des-plain-key.der", "wb"); */
1023 /* if (!fp || fwrite (p, n, 1, fp) != 1) */
1024 /* exit (2); */
1025 /* fclose (fp); */
1026 /* } */
1028 if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
1029 return 0;
1030 if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER
1031 || ti.length != 1 || *p)
1032 return 0;
1034 return 1;
1038 static gcry_mpi_t *
1039 parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
1040 size_t *r_consumed, const char *pw)
1042 int rc;
1043 struct tag_info ti;
1044 const unsigned char *p = buffer;
1045 const unsigned char *p_start = buffer;
1046 size_t n = length;
1047 const char *where;
1048 char salt[20];
1049 size_t saltlen;
1050 unsigned int iter;
1051 int len;
1052 unsigned char *plain = NULL;
1053 gcry_mpi_t *result = NULL;
1054 int result_count, i;
1055 unsigned char *cram_buffer = NULL;
1056 size_t consumed = 0; /* Number of bytes consumed from the orginal buffer. */
1058 where = "start";
1059 if (parse_tag (&p, &n, &ti))
1060 goto bailout;
1061 if (ti.class != ASNCONTEXT || ti.tag)
1062 goto bailout;
1063 if (parse_tag (&p, &n, &ti))
1064 goto bailout;
1065 if (ti.class || ti.tag != TAG_OCTET_STRING)
1066 goto bailout;
1068 consumed = p - p_start;
1069 if (ti.is_constructed && ti.ndef)
1071 /* Mozilla exported certs now come with single byte chunks of
1072 octect strings. (Mozilla Firefox 1.0.4). Arghh. */
1073 where = "cram-data.outersegs";
1074 cram_buffer = cram_octet_string ( p, &n, &consumed);
1075 if (!cram_buffer)
1076 goto bailout;
1077 p = p_start = cram_buffer;
1078 if (r_consumed)
1079 *r_consumed = consumed;
1080 r_consumed = NULL; /* Ugly hack to not update that value any further. */
1084 where = "data.outerseqs";
1085 if (parse_tag (&p, &n, &ti))
1086 goto bailout;
1087 if (ti.class || ti.tag != TAG_SEQUENCE)
1088 goto bailout;
1089 if (parse_tag (&p, &n, &ti))
1090 goto bailout;
1091 if (ti.class || ti.tag != TAG_SEQUENCE)
1092 goto bailout;
1094 where = "data.objectidentifier";
1095 if (parse_tag (&p, &n, &ti))
1096 goto bailout;
1097 if (ti.class || ti.tag != TAG_OBJECT_ID
1098 || ti.length != DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag)
1099 || memcmp (p, oid_pkcs_12_pkcs_8ShroudedKeyBag,
1100 DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag)))
1101 goto bailout;
1102 p += DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag);
1103 n -= DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag);
1105 where = "shrouded,outerseqs";
1106 if (parse_tag (&p, &n, &ti))
1107 goto bailout;
1108 if (ti.class != ASNCONTEXT || ti.tag)
1109 goto bailout;
1110 if (parse_tag (&p, &n, &ti))
1111 goto bailout;
1112 if (ti.class || ti.tag != TAG_SEQUENCE)
1113 goto bailout;
1114 if (parse_tag (&p, &n, &ti))
1115 goto bailout;
1116 if (ti.class || ti.tag != TAG_SEQUENCE)
1117 goto bailout;
1118 if (parse_tag (&p, &n, &ti))
1119 goto bailout;
1120 if (ti.class || ti.tag != TAG_OBJECT_ID
1121 || ti.length != DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)
1122 || memcmp (p, oid_pbeWithSHAAnd3_KeyTripleDES_CBC,
1123 DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)))
1124 goto bailout;
1125 p += DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
1126 n -= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
1128 where = "3des-params";
1129 if (parse_tag (&p, &n, &ti))
1130 goto bailout;
1131 if (ti.class || ti.tag != TAG_SEQUENCE)
1132 goto bailout;
1133 if (parse_tag (&p, &n, &ti))
1134 goto bailout;
1135 if (ti.class || ti.tag != TAG_OCTET_STRING
1136 || ti.length < 8 || ti.length > 20)
1137 goto bailout;
1138 saltlen = ti.length;
1139 memcpy (salt, p, saltlen);
1140 p += saltlen;
1141 n -= saltlen;
1142 if (parse_tag (&p, &n, &ti))
1143 goto bailout;
1144 if (ti.class || ti.tag != TAG_INTEGER || !ti.length )
1145 goto bailout;
1146 for (iter=0; ti.length; ti.length--)
1148 iter <<= 8;
1149 iter |= (*p++) & 0xff;
1150 n--;
1153 where = "3des-ciphertext";
1154 if (parse_tag (&p, &n, &ti))
1155 goto bailout;
1156 if (ti.class || ti.tag != TAG_OCTET_STRING || !ti.length )
1157 goto bailout;
1159 log_info ("%lu bytes of 3DES encrypted text\n", ti.length);
1161 plain = gcry_malloc_secure (ti.length);
1162 if (!plain)
1164 log_error ("error allocating decryption buffer\n");
1165 goto bailout;
1167 consumed += p - p_start + ti.length;
1168 decrypt_block (p, plain, ti.length, salt, saltlen, iter, pw,
1169 GCRY_CIPHER_3DES,
1170 bag_data_p);
1171 n = ti.length;
1172 startoffset = 0;
1173 p_start = p = plain;
1175 where = "decrypted-text";
1176 if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
1177 goto bailout;
1178 if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER
1179 || ti.length != 1 || *p)
1180 goto bailout;
1181 p++; n--;
1182 if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
1183 goto bailout;
1184 len = ti.length;
1185 if (parse_tag (&p, &n, &ti))
1186 goto bailout;
1187 if (len < ti.nhdr)
1188 goto bailout;
1189 len -= ti.nhdr;
1190 if (ti.class || ti.tag != TAG_OBJECT_ID
1191 || ti.length != DIM(oid_rsaEncryption)
1192 || memcmp (p, oid_rsaEncryption,
1193 DIM(oid_rsaEncryption)))
1194 goto bailout;
1195 p += DIM (oid_rsaEncryption);
1196 n -= DIM (oid_rsaEncryption);
1197 if (len < ti.length)
1198 goto bailout;
1199 len -= ti.length;
1200 if (n < len)
1201 goto bailout;
1202 p += len;
1203 n -= len;
1204 if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_OCTET_STRING)
1205 goto bailout;
1206 if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
1207 goto bailout;
1208 len = ti.length;
1210 result = gcry_calloc (10, sizeof *result);
1211 if (!result)
1213 log_error ( "error allocating result array\n");
1214 goto bailout;
1216 result_count = 0;
1218 where = "reading.key-parameters";
1219 for (result_count=0; len && result_count < 9;)
1221 if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER)
1222 goto bailout;
1223 if (len < ti.nhdr)
1224 goto bailout;
1225 len -= ti.nhdr;
1226 if (len < ti.length)
1227 goto bailout;
1228 len -= ti.length;
1229 if (!result_count && ti.length == 1 && !*p)
1230 ; /* ignore the very first one if it is a 0 */
1231 else
1233 rc = gcry_mpi_scan (result+result_count, GCRYMPI_FMT_USG, p,
1234 ti.length, NULL);
1235 if (rc)
1237 log_error ("error parsing key parameter: %s\n",
1238 gpg_strerror (rc));
1239 goto bailout;
1241 result_count++;
1243 p += ti.length;
1244 n -= ti.length;
1246 if (len)
1247 goto bailout;
1249 gcry_free (cram_buffer);
1250 if (r_consumed)
1251 *r_consumed = consumed;
1252 return result;
1254 bailout:
1255 gcry_free (plain);
1256 if (result)
1258 for (i=0; result[i]; i++)
1259 gcry_mpi_release (result[i]);
1260 gcry_free (result);
1262 gcry_free (cram_buffer);
1263 log_error ( "data error at \"%s\", offset %u\n",
1264 where, (unsigned int)((p - buffer) + startoffset));
1265 if (r_consumed)
1266 *r_consumed = consumed;
1267 return NULL;
1271 /* Parse a PKCS12 object and return an array of MPI representing the
1272 secret key parameters. This is a very limited implementation in
1273 that it is only able to look for 3DES encoded encryptedData and
1274 tries to extract the first private key object it finds. In case of
1275 an error NULL is returned. CERTCB and CERRTCBARG are used to pass
1276 X.509 certificates back to the caller. */
1277 gcry_mpi_t *
1278 p12_parse (const unsigned char *buffer, size_t length, const char *pw,
1279 void (*certcb)(void*, const unsigned char*, size_t),
1280 void *certcbarg)
1282 struct tag_info ti;
1283 const unsigned char *p = buffer;
1284 const unsigned char *p_start = buffer;
1285 size_t n = length;
1286 const char *where;
1287 int bagseqlength, len;
1288 int bagseqndef, lenndef;
1289 gcry_mpi_t *result = NULL;
1290 unsigned char *cram_buffer = NULL;
1292 where = "pfx";
1293 if (parse_tag (&p, &n, &ti))
1294 goto bailout;
1295 if (ti.tag != TAG_SEQUENCE)
1296 goto bailout;
1298 where = "pfxVersion";
1299 if (parse_tag (&p, &n, &ti))
1300 goto bailout;
1301 if (ti.tag != TAG_INTEGER || ti.length != 1 || *p != 3)
1302 goto bailout;
1303 p++; n--;
1305 where = "authSave";
1306 if (parse_tag (&p, &n, &ti))
1307 goto bailout;
1308 if (ti.tag != TAG_SEQUENCE)
1309 goto bailout;
1310 if (parse_tag (&p, &n, &ti))
1311 goto bailout;
1312 if (ti.tag != TAG_OBJECT_ID || ti.length != DIM(oid_data)
1313 || memcmp (p, oid_data, DIM(oid_data)))
1314 goto bailout;
1315 p += DIM(oid_data);
1316 n -= DIM(oid_data);
1318 if (parse_tag (&p, &n, &ti))
1319 goto bailout;
1320 if (ti.class != ASNCONTEXT || ti.tag)
1321 goto bailout;
1322 if (parse_tag (&p, &n, &ti))
1323 goto bailout;
1324 if (ti.class != UNIVERSAL || ti.tag != TAG_OCTET_STRING)
1325 goto bailout;
1327 if (ti.is_constructed && ti.ndef)
1329 /* Mozilla exported certs now come with single byte chunks of
1330 octect strings. (Mozilla Firefox 1.0.4). Arghh. */
1331 where = "cram-bags";
1332 cram_buffer = cram_octet_string ( p, &n, NULL);
1333 if (!cram_buffer)
1334 goto bailout;
1335 p = p_start = cram_buffer;
1338 where = "bags";
1339 if (parse_tag (&p, &n, &ti))
1340 goto bailout;
1341 if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE)
1342 goto bailout;
1343 bagseqndef = ti.ndef;
1344 bagseqlength = ti.length;
1345 while (bagseqlength || bagseqndef)
1347 /* log_debug ( "at offset %u\n", (p - p_start)); */
1348 where = "bag-sequence";
1349 if (parse_tag (&p, &n, &ti))
1350 goto bailout;
1351 if (bagseqndef && ti.class == UNIVERSAL && !ti.tag && !ti.is_constructed)
1352 break; /* Ready */
1353 if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE)
1354 goto bailout;
1356 if (!bagseqndef)
1358 if (bagseqlength < ti.nhdr)
1359 goto bailout;
1360 bagseqlength -= ti.nhdr;
1361 if (bagseqlength < ti.length)
1362 goto bailout;
1363 bagseqlength -= ti.length;
1365 lenndef = ti.ndef;
1366 len = ti.length;
1368 if (parse_tag (&p, &n, &ti))
1369 goto bailout;
1370 if (lenndef)
1371 len = ti.nhdr;
1372 else
1373 len -= ti.nhdr;
1375 if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_encryptedData)
1376 && !memcmp (p, oid_encryptedData, DIM(oid_encryptedData)))
1378 size_t consumed = 0;
1380 p += DIM(oid_encryptedData);
1381 n -= DIM(oid_encryptedData);
1382 if (!lenndef)
1383 len -= DIM(oid_encryptedData);
1384 where = "bag.encryptedData";
1385 if (parse_bag_encrypted_data (p, n, (p - p_start), &consumed, pw,
1386 certcb, certcbarg,
1387 result? NULL : &result))
1388 goto bailout;
1389 if (lenndef)
1390 len += consumed;
1392 else if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_data)
1393 && !memcmp (p, oid_data, DIM(oid_data)))
1395 if (result)
1397 log_info ("already got an key object, skipping this one\n");
1398 p += ti.length;
1399 n -= ti.length;
1401 else
1403 size_t consumed = 0;
1405 p += DIM(oid_data);
1406 n -= DIM(oid_data);
1407 if (!lenndef)
1408 len -= DIM(oid_data);
1409 result = parse_bag_data (p, n, (p - p_start), &consumed, pw);
1410 if (!result)
1411 goto bailout;
1412 if (lenndef)
1413 len += consumed;
1416 else
1418 log_info ("unknown bag type - skipped\n");
1419 p += ti.length;
1420 n -= ti.length;
1423 if (len < 0 || len > n)
1424 goto bailout;
1425 p += len;
1426 n -= len;
1427 if (lenndef)
1429 /* Need to skip the Null Tag. */
1430 if (parse_tag (&p, &n, &ti))
1431 goto bailout;
1432 if (!(ti.class == UNIVERSAL && !ti.tag && !ti.is_constructed))
1433 goto bailout;
1437 gcry_free (cram_buffer);
1438 return result;
1439 bailout:
1440 log_error ("error at \"%s\", offset %u\n",
1441 where, (unsigned int)(p - p_start));
1442 if (result)
1444 int i;
1446 for (i=0; result[i]; i++)
1447 gcry_mpi_release (result[i]);
1448 gcry_free (result);
1450 gcry_free (cram_buffer);
1451 return NULL;
1456 static size_t
1457 compute_tag_length (size_t n)
1459 int needed = 0;
1461 if (n < 128)
1462 needed += 2; /* tag and one length byte */
1463 else if (n < 256)
1464 needed += 3; /* tag, number of length bytes, 1 length byte */
1465 else if (n < 65536)
1466 needed += 4; /* tag, number of length bytes, 2 length bytes */
1467 else
1469 log_error ("object too larger to encode\n");
1470 return 0;
1472 return needed;
1475 static unsigned char *
1476 store_tag_length (unsigned char *p, int tag, size_t n)
1478 if (tag == TAG_SEQUENCE)
1479 tag |= 0x20; /* constructed */
1481 *p++ = tag;
1482 if (n < 128)
1483 *p++ = n;
1484 else if (n < 256)
1486 *p++ = 0x81;
1487 *p++ = n;
1489 else if (n < 65536)
1491 *p++ = 0x82;
1492 *p++ = n >> 8;
1493 *p++ = n;
1496 return p;
1500 /* Create the final PKCS-12 object from the sequences contained in
1501 SEQLIST. PW is the password. That array is terminated with an NULL
1502 object. */
1503 static unsigned char *
1504 create_final (struct buffer_s *sequences, const char *pw, size_t *r_length)
1506 int i;
1507 size_t needed = 0;
1508 size_t len[8], n;
1509 unsigned char *macstart;
1510 size_t maclen;
1511 unsigned char *result, *p;
1512 size_t resultlen;
1513 char salt[8];
1514 unsigned char keybuf[20];
1515 gcry_md_hd_t md;
1516 int rc;
1517 int with_mac = 1;
1520 /* 9 steps to create the pkcs#12 Krampf. */
1522 /* 8. The MAC. */
1523 /* We add this at step 0. */
1525 /* 7. All the buffers. */
1526 for (i=0; sequences[i].buffer; i++)
1527 needed += sequences[i].length;
1529 /* 6. This goes into a sequences. */
1530 len[6] = needed;
1531 n = compute_tag_length (needed);
1532 needed += n;
1534 /* 5. Encapsulate all in an octet string. */
1535 len[5] = needed;
1536 n = compute_tag_length (needed);
1537 needed += n;
1539 /* 4. And tag it with [0]. */
1540 len[4] = needed;
1541 n = compute_tag_length (needed);
1542 needed += n;
1544 /* 3. Prepend an data OID. */
1545 needed += 2 + DIM (oid_data);
1547 /* 2. Put all into a sequences. */
1548 len[2] = needed;
1549 n = compute_tag_length (needed);
1550 needed += n;
1552 /* 1. Prepend the version integer 3. */
1553 needed += 3;
1555 /* 0. And the final outer sequence. */
1556 if (with_mac)
1557 needed += DIM (data_mactemplate);
1558 len[0] = needed;
1559 n = compute_tag_length (needed);
1560 needed += n;
1562 /* Allocate a buffer. */
1563 result = gcry_malloc (needed);
1564 if (!result)
1566 log_error ("error allocating buffer\n");
1567 return NULL;
1569 p = result;
1571 /* 0. Store the very outer sequence. */
1572 p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1574 /* 1. Store the version integer 3. */
1575 *p++ = TAG_INTEGER;
1576 *p++ = 1;
1577 *p++ = 3;
1579 /* 2. Store another sequence. */
1580 p = store_tag_length (p, TAG_SEQUENCE, len[2]);
1582 /* 3. Store the data OID. */
1583 p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
1584 memcpy (p, oid_data, DIM (oid_data));
1585 p += DIM (oid_data);
1587 /* 4. Next comes a context tag. */
1588 p = store_tag_length (p, 0xa0, len[4]);
1590 /* 5. And an octet string. */
1591 p = store_tag_length (p, TAG_OCTET_STRING, len[5]);
1593 /* 6. And the inner sequence. */
1594 macstart = p;
1595 p = store_tag_length (p, TAG_SEQUENCE, len[6]);
1597 /* 7. Append all the buffers. */
1598 for (i=0; sequences[i].buffer; i++)
1600 memcpy (p, sequences[i].buffer, sequences[i].length);
1601 p += sequences[i].length;
1604 if (with_mac)
1606 /* Intermezzo to compute the MAC. */
1607 maclen = p - macstart;
1608 gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
1609 if (string_to_key (3, salt, 8, 2048, pw, 20, keybuf))
1611 gcry_free (result);
1612 return NULL;
1614 rc = gcry_md_open (&md, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC);
1615 if (rc)
1617 log_error ("gcry_md_open failed: %s\n", gpg_strerror (rc));
1618 gcry_free (result);
1619 return NULL;
1621 rc = gcry_md_setkey (md, keybuf, 20);
1622 if (rc)
1624 log_error ("gcry_md_setkey failed: %s\n", gpg_strerror (rc));
1625 gcry_md_close (md);
1626 gcry_free (result);
1627 return NULL;
1629 gcry_md_write (md, macstart, maclen);
1631 /* 8. Append the MAC template and fix it up. */
1632 memcpy (p, data_mactemplate, DIM (data_mactemplate));
1633 memcpy (p + DATA_MACTEMPLATE_SALT_OFF, salt, 8);
1634 memcpy (p + DATA_MACTEMPLATE_MAC_OFF, gcry_md_read (md, 0), 20);
1635 p += DIM (data_mactemplate);
1636 gcry_md_close (md);
1639 /* Ready. */
1640 resultlen = p - result;
1641 if (needed != resultlen)
1642 log_debug ("length mismatch: %lu, %lu\n",
1643 (unsigned long)needed, (unsigned long)resultlen);
1645 *r_length = resultlen;
1646 return result;
1650 /* Build a DER encoded SEQUENCE with the key:
1652 SEQUENCE {
1653 INTEGER 0
1654 SEQUENCE {
1655 OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
1656 NULL
1658 OCTET STRING, encapsulates {
1659 SEQUENCE {
1660 INTEGER 0
1661 INTEGER
1662 INTEGER
1663 INTEGER
1664 INTEGER
1665 INTEGER
1666 INTEGER
1667 INTEGER
1668 INTEGER
1674 static unsigned char *
1675 build_key_sequence (gcry_mpi_t *kparms, size_t *r_length)
1677 int rc, i;
1678 size_t needed, n;
1679 unsigned char *plain, *p;
1680 size_t plainlen;
1681 size_t outseqlen, oidseqlen, octstrlen, inseqlen;
1683 needed = 3; /* The version(?) integer of value 0. */
1684 for (i=0; kparms[i]; i++)
1686 n = 0;
1687 rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, kparms[i]);
1688 if (rc)
1690 log_error ("error formatting parameter: %s\n", gpg_strerror (rc));
1691 return NULL;
1693 needed += n;
1694 n = compute_tag_length (n);
1695 if (!n)
1696 return NULL;
1697 needed += n;
1699 if (i != 8)
1701 log_error ("invalid paramters for p12_build\n");
1702 return NULL;
1704 /* Now this all goes into a sequence. */
1705 inseqlen = needed;
1706 n = compute_tag_length (needed);
1707 if (!n)
1708 return NULL;
1709 needed += n;
1710 /* Encapsulate all into an octet string. */
1711 octstrlen = needed;
1712 n = compute_tag_length (needed);
1713 if (!n)
1714 return NULL;
1715 needed += n;
1716 /* Prepend the object identifier sequence. */
1717 oidseqlen = 2 + DIM (oid_rsaEncryption) + 2;
1718 needed += 2 + oidseqlen;
1719 /* The version number. */
1720 needed += 3;
1721 /* And finally put the whole thing into a sequence. */
1722 outseqlen = needed;
1723 n = compute_tag_length (needed);
1724 if (!n)
1725 return NULL;
1726 needed += n;
1728 /* allocate 8 extra bytes for padding */
1729 plain = gcry_malloc_secure (needed+8);
1730 if (!plain)
1732 log_error ("error allocating encryption buffer\n");
1733 return NULL;
1736 /* And now fill the plaintext buffer. */
1737 p = plain;
1738 p = store_tag_length (p, TAG_SEQUENCE, outseqlen);
1739 /* Store version. */
1740 *p++ = TAG_INTEGER;
1741 *p++ = 1;
1742 *p++ = 0;
1743 /* Store object identifier sequence. */
1744 p = store_tag_length (p, TAG_SEQUENCE, oidseqlen);
1745 p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_rsaEncryption));
1746 memcpy (p, oid_rsaEncryption, DIM (oid_rsaEncryption));
1747 p += DIM (oid_rsaEncryption);
1748 *p++ = TAG_NULL;
1749 *p++ = 0;
1750 /* Start with the octet string. */
1751 p = store_tag_length (p, TAG_OCTET_STRING, octstrlen);
1752 p = store_tag_length (p, TAG_SEQUENCE, inseqlen);
1753 /* Store the key parameters. */
1754 *p++ = TAG_INTEGER;
1755 *p++ = 1;
1756 *p++ = 0;
1757 for (i=0; kparms[i]; i++)
1759 n = 0;
1760 rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, kparms[i]);
1761 if (rc)
1763 log_error ("oops: error formatting parameter: %s\n",
1764 gpg_strerror (rc));
1765 gcry_free (plain);
1766 return NULL;
1768 p = store_tag_length (p, TAG_INTEGER, n);
1770 n = plain + needed - p;
1771 rc = gcry_mpi_print (GCRYMPI_FMT_STD, p, n, &n, kparms[i]);
1772 if (rc)
1774 log_error ("oops: error storing parameter: %s\n",
1775 gpg_strerror (rc));
1776 gcry_free (plain);
1777 return NULL;
1779 p += n;
1782 plainlen = p - plain;
1783 assert (needed == plainlen);
1784 /* Append some pad characters; we already allocated extra space. */
1785 n = 8 - plainlen % 8;
1786 for (i=0; i < n; i++, plainlen++)
1787 *p++ = n;
1789 *r_length = plainlen;
1790 return plain;
1795 static unsigned char *
1796 build_key_bag (unsigned char *buffer, size_t buflen, char *salt,
1797 const unsigned char *sha1hash, const char *keyidstr,
1798 size_t *r_length)
1800 size_t len[11], needed;
1801 unsigned char *p, *keybag;
1802 size_t keybaglen;
1804 /* Walk 11 steps down to collect the info: */
1806 /* 10. The data goes into an octet string. */
1807 needed = compute_tag_length (buflen);
1808 needed += buflen;
1810 /* 9. Prepend the algorithm identifier. */
1811 needed += DIM (data_3desiter2048);
1813 /* 8. Put a sequence around. */
1814 len[8] = needed;
1815 needed += compute_tag_length (needed);
1817 /* 7. Prepend a [0] tag. */
1818 len[7] = needed;
1819 needed += compute_tag_length (needed);
1821 /* 6b. The attributes which are appended at the end. */
1822 if (sha1hash)
1823 needed += DIM (data_attrtemplate) + 20;
1825 /* 6. Prepend the shroudedKeyBag OID. */
1826 needed += 2 + DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag);
1828 /* 5+4. Put all into two sequences. */
1829 len[5] = needed;
1830 needed += compute_tag_length ( needed);
1831 len[4] = needed;
1832 needed += compute_tag_length (needed);
1834 /* 3. This all goes into an octet string. */
1835 len[3] = needed;
1836 needed += compute_tag_length (needed);
1838 /* 2. Prepend another [0] tag. */
1839 len[2] = needed;
1840 needed += compute_tag_length (needed);
1842 /* 1. Prepend the data OID. */
1843 needed += 2 + DIM (oid_data);
1845 /* 0. Prepend another sequence. */
1846 len[0] = needed;
1847 needed += compute_tag_length (needed);
1849 /* Now that we have all length information, allocate a buffer. */
1850 p = keybag = gcry_malloc (needed);
1851 if (!keybag)
1853 log_error ("error allocating buffer\n");
1854 return NULL;
1857 /* Walk 11 steps up to store the data. */
1859 /* 0. Store the first sequence. */
1860 p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1862 /* 1. Store the data OID. */
1863 p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
1864 memcpy (p, oid_data, DIM (oid_data));
1865 p += DIM (oid_data);
1867 /* 2. Store a [0] tag. */
1868 p = store_tag_length (p, 0xa0, len[2]);
1870 /* 3. And an octet string. */
1871 p = store_tag_length (p, TAG_OCTET_STRING, len[3]);
1873 /* 4+5. Two sequences. */
1874 p = store_tag_length (p, TAG_SEQUENCE, len[4]);
1875 p = store_tag_length (p, TAG_SEQUENCE, len[5]);
1877 /* 6. Store the shroudedKeyBag OID. */
1878 p = store_tag_length (p, TAG_OBJECT_ID,
1879 DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag));
1880 memcpy (p, oid_pkcs_12_pkcs_8ShroudedKeyBag,
1881 DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag));
1882 p += DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag);
1884 /* 7. Store a [0] tag. */
1885 p = store_tag_length (p, 0xa0, len[7]);
1887 /* 8. Store a sequence. */
1888 p = store_tag_length (p, TAG_SEQUENCE, len[8]);
1890 /* 9. Now for the pre-encoded algorithm identifier and the salt. */
1891 memcpy (p, data_3desiter2048, DIM (data_3desiter2048));
1892 memcpy (p + DATA_3DESITER2048_SALT_OFF, salt, 8);
1893 p += DIM (data_3desiter2048);
1895 /* 10. And the octet string with the encrypted data. */
1896 p = store_tag_length (p, TAG_OCTET_STRING, buflen);
1897 memcpy (p, buffer, buflen);
1898 p += buflen;
1900 /* Append the attributes whose length we calculated at step 2b. */
1901 if (sha1hash)
1903 int i;
1905 memcpy (p, data_attrtemplate, DIM (data_attrtemplate));
1906 for (i=0; i < 8; i++)
1907 p[DATA_ATTRTEMPLATE_KEYID_OFF+2*i+1] = keyidstr[i];
1908 p += DIM (data_attrtemplate);
1909 memcpy (p, sha1hash, 20);
1910 p += 20;
1914 keybaglen = p - keybag;
1915 if (needed != keybaglen)
1916 log_debug ("length mismatch: %lu, %lu\n",
1917 (unsigned long)needed, (unsigned long)keybaglen);
1919 *r_length = keybaglen;
1920 return keybag;
1924 static unsigned char *
1925 build_cert_bag (unsigned char *buffer, size_t buflen, char *salt,
1926 size_t *r_length)
1928 size_t len[9], needed;
1929 unsigned char *p, *certbag;
1930 size_t certbaglen;
1932 /* Walk 9 steps down to collect the info: */
1934 /* 8. The data goes into an octet string. */
1935 needed = compute_tag_length (buflen);
1936 needed += buflen;
1938 /* 7. The algorithm identifier. */
1939 needed += DIM (data_rc2iter2048);
1941 /* 6. The data OID. */
1942 needed += 2 + DIM (oid_data);
1944 /* 5. A sequence. */
1945 len[5] = needed;
1946 needed += compute_tag_length ( needed);
1948 /* 4. An integer. */
1949 needed += 3;
1951 /* 3. A sequence. */
1952 len[3] = needed;
1953 needed += compute_tag_length (needed);
1955 /* 2. A [0] tag. */
1956 len[2] = needed;
1957 needed += compute_tag_length (needed);
1959 /* 1. The encryptedData OID. */
1960 needed += 2 + DIM (oid_encryptedData);
1962 /* 0. The first sequence. */
1963 len[0] = needed;
1964 needed += compute_tag_length (needed);
1966 /* Now that we have all length information, allocate a buffer. */
1967 p = certbag = gcry_malloc (needed);
1968 if (!certbag)
1970 log_error ("error allocating buffer\n");
1971 return NULL;
1974 /* Walk 9 steps up to store the data. */
1976 /* 0. Store the first sequence. */
1977 p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1979 /* 1. Store the encryptedData OID. */
1980 p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_encryptedData));
1981 memcpy (p, oid_encryptedData, DIM (oid_encryptedData));
1982 p += DIM (oid_encryptedData);
1984 /* 2. Store a [0] tag. */
1985 p = store_tag_length (p, 0xa0, len[2]);
1987 /* 3. Store a sequence. */
1988 p = store_tag_length (p, TAG_SEQUENCE, len[3]);
1990 /* 4. Store the integer 0. */
1991 *p++ = TAG_INTEGER;
1992 *p++ = 1;
1993 *p++ = 0;
1995 /* 5. Store a sequence. */
1996 p = store_tag_length (p, TAG_SEQUENCE, len[5]);
1998 /* 6. Store the data OID. */
1999 p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
2000 memcpy (p, oid_data, DIM (oid_data));
2001 p += DIM (oid_data);
2003 /* 7. Now for the pre-encoded algorithm identifier and the salt. */
2004 memcpy (p, data_rc2iter2048, DIM (data_rc2iter2048));
2005 memcpy (p + DATA_RC2ITER2048_SALT_OFF, salt, 8);
2006 p += DIM (data_rc2iter2048);
2008 /* 8. And finally the [0] tag with the encrypted data. */
2009 p = store_tag_length (p, 0x80, buflen);
2010 memcpy (p, buffer, buflen);
2011 p += buflen;
2012 certbaglen = p - certbag;
2014 if (needed != certbaglen)
2015 log_debug ("length mismatch: %lu, %lu\n",
2016 (unsigned long)needed, (unsigned long)certbaglen);
2018 *r_length = certbaglen;
2019 return certbag;
2023 static unsigned char *
2024 build_cert_sequence (unsigned char *buffer, size_t buflen,
2025 const unsigned char *sha1hash, const char *keyidstr,
2026 size_t *r_length)
2028 size_t len[8], needed, n;
2029 unsigned char *p, *certseq;
2030 size_t certseqlen;
2031 int i;
2033 assert (strlen (keyidstr) == 8);
2035 /* Walk 8 steps down to collect the info: */
2037 /* 7. The data goes into an octet string. */
2038 needed = compute_tag_length (buflen);
2039 needed += buflen;
2041 /* 6. A [0] tag. */
2042 len[6] = needed;
2043 needed += compute_tag_length (needed);
2045 /* 5. An OID. */
2046 needed += 2 + DIM (oid_x509Certificate_for_pkcs_12);
2048 /* 4. A sequence. */
2049 len[4] = needed;
2050 needed += compute_tag_length (needed);
2052 /* 3. A [0] tag. */
2053 len[3] = needed;
2054 needed += compute_tag_length (needed);
2056 /* 2b. The attributes which are appended at the end. */
2057 if (sha1hash)
2058 needed += DIM (data_attrtemplate) + 20;
2060 /* 2. An OID. */
2061 needed += 2 + DIM (oid_pkcs_12_CertBag);
2063 /* 1. A sequence. */
2064 len[1] = needed;
2065 needed += compute_tag_length (needed);
2067 /* 0. The first sequence. */
2068 len[0] = needed;
2069 needed += compute_tag_length (needed);
2071 /* Now that we have all length information, allocate a buffer. */
2072 p = certseq = gcry_malloc (needed + 8 /*(for padding)*/);
2073 if (!certseq)
2075 log_error ("error allocating buffer\n");
2076 return NULL;
2079 /* Walk 8 steps up to store the data. */
2081 /* 0. Store the first sequence. */
2082 p = store_tag_length (p, TAG_SEQUENCE, len[0]);
2084 /* 1. Store the second sequence. */
2085 p = store_tag_length (p, TAG_SEQUENCE, len[1]);
2087 /* 2. Store the pkcs12-cert-bag OID. */
2088 p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_pkcs_12_CertBag));
2089 memcpy (p, oid_pkcs_12_CertBag, DIM (oid_pkcs_12_CertBag));
2090 p += DIM (oid_pkcs_12_CertBag);
2092 /* 3. Store a [0] tag. */
2093 p = store_tag_length (p, 0xa0, len[3]);
2095 /* 4. Store a sequence. */
2096 p = store_tag_length (p, TAG_SEQUENCE, len[4]);
2098 /* 5. Store the x509Certificate OID. */
2099 p = store_tag_length (p, TAG_OBJECT_ID,
2100 DIM (oid_x509Certificate_for_pkcs_12));
2101 memcpy (p, oid_x509Certificate_for_pkcs_12,
2102 DIM (oid_x509Certificate_for_pkcs_12));
2103 p += DIM (oid_x509Certificate_for_pkcs_12);
2105 /* 6. Store a [0] tag. */
2106 p = store_tag_length (p, 0xa0, len[6]);
2108 /* 7. And the octet string with the actual certificate. */
2109 p = store_tag_length (p, TAG_OCTET_STRING, buflen);
2110 memcpy (p, buffer, buflen);
2111 p += buflen;
2113 /* Append the attributes whose length we calculated at step 2b. */
2114 if (sha1hash)
2116 memcpy (p, data_attrtemplate, DIM (data_attrtemplate));
2117 for (i=0; i < 8; i++)
2118 p[DATA_ATTRTEMPLATE_KEYID_OFF+2*i+1] = keyidstr[i];
2119 p += DIM (data_attrtemplate);
2120 memcpy (p, sha1hash, 20);
2121 p += 20;
2124 certseqlen = p - certseq;
2125 if (needed != certseqlen)
2126 log_debug ("length mismatch: %lu, %lu\n",
2127 (unsigned long)needed, (unsigned long)certseqlen);
2129 /* Append some pad characters; we already allocated extra space. */
2130 n = 8 - certseqlen % 8;
2131 for (i=0; i < n; i++, certseqlen++)
2132 *p++ = n;
2134 *r_length = certseqlen;
2135 return certseq;
2139 /* Expect the RSA key parameters in KPARMS and a password in PW.
2140 Create a PKCS structure from it and return it as well as the length
2141 in R_LENGTH; return NULL in case of an error. If CHARSET is not
2142 NULL, re-encode PW to that character set. */
2143 unsigned char *
2144 p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen,
2145 const char *pw, const char *charset, size_t *r_length)
2147 unsigned char *buffer = NULL;
2148 size_t n, buflen;
2149 char salt[8];
2150 struct buffer_s seqlist[3];
2151 int seqlistidx = 0;
2152 unsigned char sha1hash[20];
2153 char keyidstr[8+1];
2154 char *pwbuf = NULL;
2155 size_t pwbufsize = 0;
2157 n = buflen = 0; /* (avoid compiler warning). */
2158 memset (sha1hash, 0, 20);
2159 *keyidstr = 0;
2161 if (charset && pw && *pw)
2163 jnlib_iconv_t cd;
2164 const char *inptr;
2165 char *outptr;
2166 size_t inbytes, outbytes;
2168 /* We assume that the converted passphrase is at max 2 times
2169 longer than its utf-8 encoding. */
2170 pwbufsize = strlen (pw)*2 + 1;
2171 pwbuf = gcry_malloc_secure (pwbufsize);
2172 if (!pwbuf)
2174 log_error ("out of secure memory while converting passphrase\n");
2175 goto failure;
2178 cd = jnlib_iconv_open (charset, "utf-8");
2179 if (cd == (jnlib_iconv_t)(-1))
2181 log_error ("can't convert passphrase to"
2182 " requested charset `%s': %s\n",
2183 charset, strerror (errno));
2184 gcry_free (pwbuf);
2185 goto failure;
2188 inptr = pw;
2189 inbytes = strlen (pw);
2190 outptr = pwbuf;
2191 outbytes = pwbufsize - 1;
2192 if ( jnlib_iconv (cd, (const char **)&inptr, &inbytes,
2193 &outptr, &outbytes) == (size_t)-1)
2195 log_error ("error converting passphrase to"
2196 " requested charset `%s': %s\n",
2197 charset, strerror (errno));
2198 gcry_free (pwbuf);
2199 jnlib_iconv_close (cd);
2200 goto failure;
2202 *outptr = 0;
2203 jnlib_iconv_close (cd);
2204 pw = pwbuf;
2208 if (cert && certlen)
2210 /* Calculate the hash value we need for the bag attributes. */
2211 gcry_md_hash_buffer (GCRY_MD_SHA1, sha1hash, cert, certlen);
2212 sprintf (keyidstr, "%02x%02x%02x%02x",
2213 sha1hash[16], sha1hash[17], sha1hash[18], sha1hash[19]);
2215 /* Encode the certificate. */
2216 buffer = build_cert_sequence (cert, certlen, sha1hash, keyidstr,
2217 &buflen);
2218 if (!buffer)
2219 goto failure;
2221 /* Encrypt it. */
2222 gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
2223 crypt_block (buffer, buflen, salt, 8, 2048, pw,
2224 GCRY_CIPHER_RFC2268_40, 1);
2226 /* Encode the encrypted stuff into a bag. */
2227 seqlist[seqlistidx].buffer = build_cert_bag (buffer, buflen, salt, &n);
2228 seqlist[seqlistidx].length = n;
2229 gcry_free (buffer);
2230 buffer = NULL;
2231 if (!seqlist[seqlistidx].buffer)
2232 goto failure;
2233 seqlistidx++;
2237 if (kparms)
2239 /* Encode the key. */
2240 buffer = build_key_sequence (kparms, &buflen);
2241 if (!buffer)
2242 goto failure;
2244 /* Encrypt it. */
2245 gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
2246 crypt_block (buffer, buflen, salt, 8, 2048, pw, GCRY_CIPHER_3DES, 1);
2248 /* Encode the encrypted stuff into a bag. */
2249 if (cert && certlen)
2250 seqlist[seqlistidx].buffer = build_key_bag (buffer, buflen, salt,
2251 sha1hash, keyidstr, &n);
2252 else
2253 seqlist[seqlistidx].buffer = build_key_bag (buffer, buflen, salt,
2254 NULL, NULL, &n);
2255 seqlist[seqlistidx].length = n;
2256 gcry_free (buffer);
2257 buffer = NULL;
2258 if (!seqlist[seqlistidx].buffer)
2259 goto failure;
2260 seqlistidx++;
2263 seqlist[seqlistidx].buffer = NULL;
2264 seqlist[seqlistidx].length = 0;
2266 buffer = create_final (seqlist, pw, &buflen);
2268 failure:
2269 if (pwbuf)
2271 wipememory (pwbuf, pwbufsize);
2272 gcry_free (pwbuf);
2274 for ( ; seqlistidx; seqlistidx--)
2275 gcry_free (seqlist[seqlistidx].buffer);
2277 *r_length = buffer? buflen : 0;
2278 return buffer;
2282 #ifdef TEST
2284 static void
2285 cert_cb (void *opaque, const unsigned char *cert, size_t certlen)
2287 printf ("got a certificate of %u bytes length\n", certlen);
2291 main (int argc, char **argv)
2293 FILE *fp;
2294 struct stat st;
2295 unsigned char *buf;
2296 size_t buflen;
2297 gcry_mpi_t *result;
2299 if (argc != 3)
2301 fprintf (stderr, "usage: testp12 file passphrase\n");
2302 return 1;
2305 gcry_control (GCRYCTL_DISABLE_SECMEM, NULL);
2306 gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL);
2308 fp = fopen (argv[1], "rb");
2309 if (!fp)
2311 fprintf (stderr, "can't open `%s': %s\n", argv[1], strerror (errno));
2312 return 1;
2315 if (fstat (fileno(fp), &st))
2317 fprintf (stderr, "can't stat `%s': %s\n", argv[1], strerror (errno));
2318 return 1;
2321 buflen = st.st_size;
2322 buf = gcry_malloc (buflen+1);
2323 if (!buf || fread (buf, buflen, 1, fp) != 1)
2325 fprintf (stderr, "error reading `%s': %s\n", argv[1], strerror (errno));
2326 return 1;
2328 fclose (fp);
2330 result = p12_parse (buf, buflen, argv[2], cert_cb, NULL);
2331 if (result)
2333 int i, rc;
2334 unsigned char *tmpbuf;
2336 for (i=0; result[i]; i++)
2338 rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &tmpbuf,
2339 NULL, result[i]);
2340 if (rc)
2341 printf ("%d: [error printing number: %s]\n",
2342 i, gpg_strerror (rc));
2343 else
2345 printf ("%d: %s\n", i, tmpbuf);
2346 gcry_free (tmpbuf);
2351 return 0;
2356 Local Variables:
2357 compile-command: "gcc -Wall -O0 -g -DTEST=1 -o minip12 minip12.c ../jnlib/libjnlib.a -L /usr/local/lib -lgcrypt -lgpg-error"
2358 End:
2360 #endif /* TEST */