Line data Source code
1 : /* minip12.c - A minimal pkcs-12 implementation.
2 : * Copyright (C) 2002, 2003, 2004, 2006, 2011 Free Software Foundation, Inc.
3 : * Copyright (C) 2014 Werner Koch
4 : *
5 : * This file is part of GnuPG.
6 : *
7 : * GnuPG is free software; you can redistribute it and/or modify
8 : * it under the terms of the GNU General Public License as published by
9 : * the Free Software Foundation; either version 3 of the License, or
10 : * (at your option) any later version.
11 : *
12 : * GnuPG is distributed in the hope that it will be useful,
13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : * GNU General Public License for more details.
16 : *
17 : * You should have received a copy of the GNU General Public License
18 : * along with this program; if not, see <http://www.gnu.org/licenses/>.
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 : #include <errno.h>
30 :
31 : #ifdef TEST
32 : #include <sys/stat.h>
33 : #include <unistd.h>
34 : #endif
35 :
36 : #include "../common/logging.h"
37 : #include "../common/utf8conv.h"
38 : #include "minip12.h"
39 :
40 : #ifndef DIM
41 : #define DIM(v) (sizeof(v)/sizeof((v)[0]))
42 : #endif
43 :
44 :
45 : enum
46 : {
47 : UNIVERSAL = 0,
48 : APPLICATION = 1,
49 : ASNCONTEXT = 2,
50 : PRIVATE = 3
51 : };
52 :
53 :
54 : enum
55 : {
56 : TAG_NONE = 0,
57 : TAG_BOOLEAN = 1,
58 : TAG_INTEGER = 2,
59 : TAG_BIT_STRING = 3,
60 : TAG_OCTET_STRING = 4,
61 : TAG_NULL = 5,
62 : TAG_OBJECT_ID = 6,
63 : TAG_OBJECT_DESCRIPTOR = 7,
64 : TAG_EXTERNAL = 8,
65 : TAG_REAL = 9,
66 : TAG_ENUMERATED = 10,
67 : TAG_EMBEDDED_PDV = 11,
68 : TAG_UTF8_STRING = 12,
69 : TAG_REALTIVE_OID = 13,
70 : TAG_SEQUENCE = 16,
71 : TAG_SET = 17,
72 : TAG_NUMERIC_STRING = 18,
73 : TAG_PRINTABLE_STRING = 19,
74 : TAG_TELETEX_STRING = 20,
75 : TAG_VIDEOTEX_STRING = 21,
76 : TAG_IA5_STRING = 22,
77 : TAG_UTC_TIME = 23,
78 : TAG_GENERALIZED_TIME = 24,
79 : TAG_GRAPHIC_STRING = 25,
80 : TAG_VISIBLE_STRING = 26,
81 : TAG_GENERAL_STRING = 27,
82 : TAG_UNIVERSAL_STRING = 28,
83 : TAG_CHARACTER_STRING = 29,
84 : TAG_BMP_STRING = 30
85 : };
86 :
87 :
88 : static unsigned char const oid_data[9] = {
89 : 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01 };
90 : static unsigned char const oid_encryptedData[9] = {
91 : 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06 };
92 : static unsigned char const oid_pkcs_12_keyBag[11] = {
93 : 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x01 };
94 : static unsigned char const oid_pkcs_12_pkcs_8ShroudedKeyBag[11] = {
95 : 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x02 };
96 : static unsigned char const oid_pkcs_12_CertBag[11] = {
97 : 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x03 };
98 : static unsigned char const oid_pkcs_12_CrlBag[11] = {
99 : 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x04 };
100 :
101 : static unsigned char const oid_pbeWithSHAAnd3_KeyTripleDES_CBC[10] = {
102 : 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03 };
103 : static unsigned char const oid_pbeWithSHAAnd40BitRC2_CBC[10] = {
104 : 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x06 };
105 : static unsigned char const oid_x509Certificate_for_pkcs_12[10] = {
106 : 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x16, 0x01 };
107 :
108 : static unsigned char const oid_pkcs5PBKDF2[9] = {
109 : 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x0C };
110 : static unsigned char const oid_pkcs5PBES2[9] = {
111 : 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x0D };
112 : static unsigned char const oid_aes128_CBC[9] = {
113 : 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x02 };
114 :
115 : static unsigned char const oid_rsaEncryption[9] = {
116 : 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 };
117 :
118 :
119 : static unsigned char const data_3desiter2048[30] = {
120 : 0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86,
121 : 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30, 0x0E,
122 : 0x04, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
123 : 0xFF, 0xFF, 0x02, 0x02, 0x08, 0x00 };
124 : #define DATA_3DESITER2048_SALT_OFF 18
125 :
126 : static unsigned char const data_rc2iter2048[30] = {
127 : 0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86,
128 : 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x06, 0x30, 0x0E,
129 : 0x04, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
130 : 0xFF, 0xFF, 0x02, 0x02, 0x08, 0x00 };
131 : #define DATA_RC2ITER2048_SALT_OFF 18
132 :
133 : static unsigned char const data_mactemplate[51] = {
134 : 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
135 : 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04,
136 : 0x14, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
137 : 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
138 : 0xff, 0xff, 0xff, 0xff, 0xff, 0x04, 0x08, 0xff,
139 : 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02,
140 : 0x02, 0x08, 0x00 };
141 : #define DATA_MACTEMPLATE_MAC_OFF 17
142 : #define DATA_MACTEMPLATE_SALT_OFF 39
143 :
144 : static unsigned char const data_attrtemplate[106] = {
145 : 0x31, 0x7c, 0x30, 0x55, 0x06, 0x09, 0x2a, 0x86,
146 : 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x14, 0x31,
147 : 0x48, 0x1e, 0x46, 0x00, 0x47, 0x00, 0x6e, 0x00,
148 : 0x75, 0x00, 0x50, 0x00, 0x47, 0x00, 0x20, 0x00,
149 : 0x65, 0x00, 0x78, 0x00, 0x70, 0x00, 0x6f, 0x00,
150 : 0x72, 0x00, 0x74, 0x00, 0x65, 0x00, 0x64, 0x00,
151 : 0x20, 0x00, 0x63, 0x00, 0x65, 0x00, 0x72, 0x00,
152 : 0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00,
153 : 0x63, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00,
154 : 0x20, 0x00, 0x66, 0x00, 0x66, 0x00, 0x66, 0x00,
155 : 0x66, 0x00, 0x66, 0x00, 0x66, 0x00, 0x66, 0x00,
156 : 0x66, 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48,
157 : 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x15, 0x31, 0x16,
158 : 0x04, 0x14 }; /* Need to append SHA-1 digest. */
159 : #define DATA_ATTRTEMPLATE_KEYID_OFF 73
160 :
161 : struct buffer_s
162 : {
163 : unsigned char *buffer;
164 : size_t length;
165 : };
166 :
167 :
168 : struct tag_info
169 : {
170 : int class;
171 : int is_constructed;
172 : unsigned long tag;
173 : unsigned long length; /* length part of the TLV */
174 : int nhdr;
175 : int ndef; /* It is an indefinite length */
176 : };
177 :
178 :
179 : /* Parse the buffer at the address BUFFER which is of SIZE and return
180 : the tag and the length part from the TLV triplet. Update BUFFER
181 : and SIZE on success. Checks that the encoded length does not
182 : exhaust the length of the provided buffer. */
183 : static int
184 0 : parse_tag (unsigned char const **buffer, size_t *size, struct tag_info *ti)
185 : {
186 : int c;
187 : unsigned long tag;
188 0 : const unsigned char *buf = *buffer;
189 0 : size_t length = *size;
190 :
191 0 : ti->length = 0;
192 0 : ti->ndef = 0;
193 0 : ti->nhdr = 0;
194 :
195 : /* Get the tag */
196 0 : if (!length)
197 0 : return -1; /* premature eof */
198 0 : c = *buf++; length--;
199 0 : ti->nhdr++;
200 :
201 0 : ti->class = (c & 0xc0) >> 6;
202 0 : ti->is_constructed = !!(c & 0x20);
203 0 : tag = c & 0x1f;
204 :
205 0 : if (tag == 0x1f)
206 : {
207 0 : tag = 0;
208 : do
209 : {
210 0 : tag <<= 7;
211 0 : if (!length)
212 0 : return -1; /* premature eof */
213 0 : c = *buf++; length--;
214 0 : ti->nhdr++;
215 0 : tag |= c & 0x7f;
216 : }
217 0 : while (c & 0x80);
218 : }
219 0 : ti->tag = tag;
220 :
221 : /* Get the length */
222 0 : if (!length)
223 0 : return -1; /* prematureeof */
224 0 : c = *buf++; length--;
225 0 : ti->nhdr++;
226 :
227 0 : if ( !(c & 0x80) )
228 0 : ti->length = c;
229 0 : else if (c == 0x80)
230 0 : ti->ndef = 1;
231 0 : else if (c == 0xff)
232 0 : return -1; /* forbidden length value */
233 : else
234 : {
235 0 : unsigned long len = 0;
236 0 : int count = c & 0x7f;
237 :
238 0 : for (; count; count--)
239 : {
240 0 : len <<= 8;
241 0 : if (!length)
242 0 : return -1; /* premature_eof */
243 0 : c = *buf++; length--;
244 0 : ti->nhdr++;
245 0 : len |= c & 0xff;
246 : }
247 0 : ti->length = len;
248 : }
249 :
250 0 : if (ti->class == UNIVERSAL && !ti->tag)
251 0 : ti->length = 0;
252 :
253 0 : if (ti->length > length)
254 0 : return -1; /* data larger than buffer. */
255 :
256 0 : *buffer = buf;
257 0 : *size = length;
258 0 : return 0;
259 : }
260 :
261 :
262 : /* Given an ASN.1 chunk of a structure like:
263 :
264 : 24 NDEF: OCTET STRING -- This is not passed to us
265 : 04 1: OCTET STRING -- INPUT point s to here
266 : : 30
267 : 04 1: OCTET STRING
268 : : 80
269 : [...]
270 : 04 2: OCTET STRING
271 : : 00 00
272 : : } -- This denotes a Null tag and are the last
273 : -- two bytes in INPUT.
274 :
275 : Create a new buffer with the content of that octet string. INPUT
276 : is the original buffer with a length as stored at LENGTH. Returns
277 : NULL on error or a new malloced buffer with the length of this new
278 : buffer stored at LENGTH and the number of bytes parsed from input
279 : are added to the value stored at INPUT_CONSUMED. INPUT_CONSUMED is
280 : allowed to be passed as NULL if the caller is not interested in
281 : this value. */
282 : static unsigned char *
283 0 : cram_octet_string (const unsigned char *input, size_t *length,
284 : size_t *input_consumed)
285 : {
286 0 : const unsigned char *s = input;
287 0 : size_t n = *length;
288 : unsigned char *output, *d;
289 : struct tag_info ti;
290 :
291 : /* Allocate output buf. We know that it won't be longer than the
292 : input buffer. */
293 0 : d = output = gcry_malloc (n);
294 0 : if (!output)
295 0 : goto bailout;
296 :
297 : for (;;)
298 : {
299 0 : if (parse_tag (&s, &n, &ti))
300 0 : goto bailout;
301 0 : if (ti.class == UNIVERSAL && ti.tag == TAG_OCTET_STRING
302 0 : && !ti.ndef && !ti.is_constructed)
303 : {
304 0 : memcpy (d, s, ti.length);
305 0 : s += ti.length;
306 0 : d += ti.length;
307 0 : n -= ti.length;
308 : }
309 0 : else if (ti.class == UNIVERSAL && !ti.tag && !ti.is_constructed)
310 : break; /* Ready */
311 : else
312 : goto bailout;
313 0 : }
314 :
315 :
316 0 : *length = d - output;
317 0 : if (input_consumed)
318 0 : *input_consumed += s - input;
319 0 : return output;
320 :
321 : bailout:
322 0 : if (input_consumed)
323 0 : *input_consumed += s - input;
324 0 : gcry_free (output);
325 0 : return NULL;
326 : }
327 :
328 :
329 :
330 : static int
331 0 : string_to_key (int id, char *salt, size_t saltlen, int iter, const char *pw,
332 : int req_keylen, unsigned char *keybuf)
333 : {
334 : int rc, i, j;
335 : gcry_md_hd_t md;
336 0 : gcry_mpi_t num_b1 = NULL;
337 : int pwlen;
338 : unsigned char hash[20], buf_b[64], buf_i[128], *p;
339 : size_t cur_keylen;
340 : size_t n;
341 :
342 0 : cur_keylen = 0;
343 0 : pwlen = strlen (pw);
344 0 : if (pwlen > 63/2)
345 : {
346 0 : log_error ("password too long\n");
347 0 : return -1;
348 : }
349 :
350 0 : if (saltlen < 8)
351 : {
352 0 : log_error ("salt too short\n");
353 0 : return -1;
354 : }
355 :
356 : /* Store salt and password in BUF_I */
357 0 : p = buf_i;
358 0 : for(i=0; i < 64; i++)
359 0 : *p++ = salt [i%saltlen];
360 0 : for(i=j=0; i < 64; i += 2)
361 : {
362 0 : *p++ = 0;
363 0 : *p++ = pw[j];
364 0 : if (++j > pwlen) /* Note, that we include the trailing zero */
365 0 : j = 0;
366 : }
367 :
368 : for (;;)
369 : {
370 0 : rc = gcry_md_open (&md, GCRY_MD_SHA1, 0);
371 0 : if (rc)
372 : {
373 0 : log_error ( "gcry_md_open failed: %s\n", gpg_strerror (rc));
374 0 : return rc;
375 : }
376 0 : for(i=0; i < 64; i++)
377 0 : gcry_md_putc (md, id);
378 0 : gcry_md_write (md, buf_i, 128);
379 0 : memcpy (hash, gcry_md_read (md, 0), 20);
380 0 : gcry_md_close (md);
381 0 : for (i=1; i < iter; i++)
382 0 : gcry_md_hash_buffer (GCRY_MD_SHA1, hash, hash, 20);
383 :
384 0 : for (i=0; i < 20 && cur_keylen < req_keylen; i++)
385 0 : keybuf[cur_keylen++] = hash[i];
386 0 : if (cur_keylen == req_keylen)
387 : {
388 0 : gcry_mpi_release (num_b1);
389 0 : return 0; /* ready */
390 : }
391 :
392 : /* need more bytes. */
393 0 : for(i=0; i < 64; i++)
394 0 : buf_b[i] = hash[i % 20];
395 0 : rc = gcry_mpi_scan (&num_b1, GCRYMPI_FMT_USG, buf_b, 64, &n);
396 0 : if (rc)
397 : {
398 0 : log_error ( "gcry_mpi_scan failed: %s\n", gpg_strerror (rc));
399 0 : return -1;
400 : }
401 0 : gcry_mpi_add_ui (num_b1, num_b1, 1);
402 0 : for (i=0; i < 128; i += 64)
403 : {
404 : gcry_mpi_t num_ij;
405 :
406 0 : rc = gcry_mpi_scan (&num_ij, GCRYMPI_FMT_USG, buf_i + i, 64, &n);
407 0 : if (rc)
408 : {
409 0 : log_error ( "gcry_mpi_scan failed: %s\n",
410 : gpg_strerror (rc));
411 0 : return -1;
412 : }
413 0 : gcry_mpi_add (num_ij, num_ij, num_b1);
414 0 : gcry_mpi_clear_highbit (num_ij, 64*8);
415 0 : rc = gcry_mpi_print (GCRYMPI_FMT_USG, buf_i + i, 64, &n, num_ij);
416 0 : if (rc)
417 : {
418 0 : log_error ( "gcry_mpi_print failed: %s\n",
419 : gpg_strerror (rc));
420 0 : return -1;
421 : }
422 0 : gcry_mpi_release (num_ij);
423 : }
424 0 : }
425 : }
426 :
427 :
428 : static int
429 0 : set_key_iv (gcry_cipher_hd_t chd, char *salt, size_t saltlen, int iter,
430 : const char *pw, int keybytes)
431 : {
432 : unsigned char keybuf[24];
433 : int rc;
434 :
435 0 : assert (keybytes == 5 || keybytes == 24);
436 0 : if (string_to_key (1, salt, saltlen, iter, pw, keybytes, keybuf))
437 0 : return -1;
438 0 : rc = gcry_cipher_setkey (chd, keybuf, keybytes);
439 0 : if (rc)
440 : {
441 0 : log_error ( "gcry_cipher_setkey failed: %s\n", gpg_strerror (rc));
442 0 : return -1;
443 : }
444 :
445 0 : if (string_to_key (2, salt, saltlen, iter, pw, 8, keybuf))
446 0 : return -1;
447 0 : rc = gcry_cipher_setiv (chd, keybuf, 8);
448 0 : if (rc)
449 : {
450 0 : log_error ("gcry_cipher_setiv failed: %s\n", gpg_strerror (rc));
451 0 : return -1;
452 : }
453 0 : return 0;
454 : }
455 :
456 :
457 : static int
458 0 : set_key_iv_pbes2 (gcry_cipher_hd_t chd, char *salt, size_t saltlen, int iter,
459 : const void *iv, size_t ivlen, const char *pw, int algo)
460 : {
461 : unsigned char *keybuf;
462 : size_t keylen;
463 : int rc;
464 :
465 0 : keylen = gcry_cipher_get_algo_keylen (algo);
466 0 : if (!keylen)
467 0 : return -1;
468 0 : keybuf = gcry_malloc_secure (keylen);
469 0 : if (!keybuf)
470 0 : return -1;
471 :
472 0 : rc = gcry_kdf_derive (pw, strlen (pw),
473 : GCRY_KDF_PBKDF2, GCRY_MD_SHA1,
474 : salt, saltlen, iter, keylen, keybuf);
475 0 : if (rc)
476 : {
477 0 : log_error ("gcry_kdf_derive failed: %s\n", gpg_strerror (rc));
478 0 : gcry_free (keybuf);
479 0 : return -1;
480 : }
481 :
482 0 : rc = gcry_cipher_setkey (chd, keybuf, keylen);
483 0 : gcry_free (keybuf);
484 0 : if (rc)
485 : {
486 0 : log_error ("gcry_cipher_setkey failed: %s\n", gpg_strerror (rc));
487 0 : return -1;
488 : }
489 :
490 :
491 0 : rc = gcry_cipher_setiv (chd, iv, ivlen);
492 0 : if (rc)
493 : {
494 0 : log_error ("gcry_cipher_setiv failed: %s\n", gpg_strerror (rc));
495 0 : return -1;
496 : }
497 0 : return 0;
498 : }
499 :
500 :
501 : static void
502 0 : crypt_block (unsigned char *buffer, size_t length, char *salt, size_t saltlen,
503 : int iter, const void *iv, size_t ivlen,
504 : const char *pw, int cipher_algo, int encrypt)
505 : {
506 : gcry_cipher_hd_t chd;
507 : int rc;
508 :
509 0 : rc = gcry_cipher_open (&chd, cipher_algo, GCRY_CIPHER_MODE_CBC, 0);
510 0 : if (rc)
511 : {
512 0 : log_error ( "gcry_cipher_open failed: %s\n", gpg_strerror(rc));
513 0 : wipememory (buffer, length);
514 0 : return;
515 : }
516 :
517 0 : if (cipher_algo == GCRY_CIPHER_AES128
518 0 : ? set_key_iv_pbes2 (chd, salt, saltlen, iter, iv, ivlen, pw, cipher_algo)
519 0 : : set_key_iv (chd, salt, saltlen, iter, pw,
520 : cipher_algo == GCRY_CIPHER_RFC2268_40? 5:24))
521 : {
522 0 : wipememory (buffer, length);
523 0 : goto leave;
524 : }
525 :
526 0 : rc = encrypt? gcry_cipher_encrypt (chd, buffer, length, NULL, 0)
527 0 : : gcry_cipher_decrypt (chd, buffer, length, NULL, 0);
528 :
529 0 : if (rc)
530 : {
531 0 : wipememory (buffer, length);
532 0 : log_error ( "en/de-crytion failed: %s\n", gpg_strerror (rc));
533 0 : goto leave;
534 : }
535 :
536 : leave:
537 0 : gcry_cipher_close (chd);
538 : }
539 :
540 :
541 : /* Decrypt a block of data and try several encodings of the key.
542 : CIPHERTEXT is the encrypted data of size LENGTH bytes; PLAINTEXT is
543 : a buffer of the same size to receive the decryption result. SALT,
544 : SALTLEN, ITER and PW are the information required for decryption
545 : and CIPHER_ALGO is the algorithm id to use. CHECK_FNC is a
546 : function called with the plaintext and used to check whether the
547 : decryption succeeded; i.e. that a correct passphrase has been
548 : given. That function shall return true if the decryption has likely
549 : succeeded. */
550 : static void
551 0 : decrypt_block (const void *ciphertext, unsigned char *plaintext, size_t length,
552 : char *salt, size_t saltlen,
553 : int iter, const void *iv, size_t ivlen,
554 : const char *pw, int cipher_algo,
555 : int (*check_fnc) (const void *, size_t))
556 : {
557 : static const char * const charsets[] = {
558 : "", /* No conversion - use the UTF-8 passphrase direct. */
559 : "ISO-8859-1",
560 : "ISO-8859-15",
561 : "ISO-8859-2",
562 : "ISO-8859-3",
563 : "ISO-8859-4",
564 : "ISO-8859-5",
565 : "ISO-8859-6",
566 : "ISO-8859-7",
567 : "ISO-8859-8",
568 : "ISO-8859-9",
569 : "KOI8-R",
570 : "IBM437",
571 : "IBM850",
572 : "EUC-JP",
573 : "BIG5",
574 : NULL
575 : };
576 0 : int charsetidx = 0;
577 0 : char *convertedpw = NULL; /* Malloced and converted password or NULL. */
578 0 : size_t convertedpwsize = 0; /* Allocated length. */
579 :
580 0 : for (charsetidx=0; charsets[charsetidx]; charsetidx++)
581 : {
582 0 : if (*charsets[charsetidx])
583 : {
584 : jnlib_iconv_t cd;
585 : const char *inptr;
586 : char *outptr;
587 : size_t inbytes, outbytes;
588 :
589 0 : if (!convertedpw)
590 : {
591 : /* We assume one byte encodings. Thus we can allocate
592 : the buffer of the same size as the original
593 : passphrase; the result will actually be shorter
594 : then. */
595 0 : convertedpwsize = strlen (pw) + 1;
596 0 : convertedpw = gcry_malloc_secure (convertedpwsize);
597 0 : if (!convertedpw)
598 : {
599 0 : log_info ("out of secure memory while"
600 : " converting passphrase\n");
601 0 : break; /* Give up. */
602 : }
603 : }
604 :
605 0 : cd = jnlib_iconv_open (charsets[charsetidx], "utf-8");
606 0 : if (cd == (jnlib_iconv_t)(-1))
607 0 : continue;
608 :
609 0 : inptr = pw;
610 0 : inbytes = strlen (pw);
611 0 : outptr = convertedpw;
612 0 : outbytes = convertedpwsize - 1;
613 0 : if ( jnlib_iconv (cd, (const char **)&inptr, &inbytes,
614 : &outptr, &outbytes) == (size_t)-1)
615 : {
616 0 : jnlib_iconv_close (cd);
617 0 : continue;
618 : }
619 0 : *outptr = 0;
620 0 : jnlib_iconv_close (cd);
621 0 : log_info ("decryption failed; trying charset '%s'\n",
622 : charsets[charsetidx]);
623 : }
624 0 : memcpy (plaintext, ciphertext, length);
625 0 : crypt_block (plaintext, length, salt, saltlen, iter, iv, ivlen,
626 : convertedpw? convertedpw:pw, cipher_algo, 0);
627 0 : if (check_fnc (plaintext, length))
628 0 : break; /* Decryption succeeded. */
629 : }
630 0 : gcry_free (convertedpw);
631 0 : }
632 :
633 :
634 : /* Return true if the decryption of an bag_encrypted_data object has
635 : likely succeeded. */
636 : static int
637 0 : bag_decrypted_data_p (const void *plaintext, size_t length)
638 : {
639 : struct tag_info ti;
640 0 : const unsigned char *p = plaintext;
641 0 : size_t n = length;
642 :
643 : /* { */
644 : /* # warning debug code is enabled */
645 : /* FILE *fp = fopen ("tmp-rc2-plain.der", "wb"); */
646 : /* if (!fp || fwrite (p, n, 1, fp) != 1) */
647 : /* exit (2); */
648 : /* fclose (fp); */
649 : /* } */
650 :
651 0 : if (parse_tag (&p, &n, &ti))
652 0 : return 0;
653 0 : if (ti.class || ti.tag != TAG_SEQUENCE)
654 0 : return 0;
655 0 : if (parse_tag (&p, &n, &ti))
656 0 : return 0;
657 :
658 0 : return 1;
659 : }
660 :
661 : /* Note: If R_RESULT is passed as NULL, a key object as already be
662 : processed and thus we need to skip it here. */
663 : static int
664 0 : parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
665 : int startoffset, size_t *r_consumed, const char *pw,
666 : void (*certcb)(void*, const unsigned char*, size_t),
667 : void *certcbarg, gcry_mpi_t **r_result,
668 : int *r_badpass)
669 : {
670 : struct tag_info ti;
671 0 : const unsigned char *p = buffer;
672 0 : const unsigned char *p_start = buffer;
673 0 : size_t n = length;
674 : const char *where;
675 : char salt[20];
676 : size_t saltlen;
677 : char iv[16];
678 : unsigned int iter;
679 0 : unsigned char *plain = NULL;
680 0 : int bad_pass = 0;
681 0 : unsigned char *cram_buffer = NULL;
682 0 : size_t consumed = 0; /* Number of bytes consumed from the original buffer. */
683 0 : int is_3des = 0;
684 0 : int is_pbes2 = 0;
685 0 : gcry_mpi_t *result = NULL;
686 : int result_count;
687 :
688 0 : if (r_result)
689 0 : *r_result = NULL;
690 0 : where = "start";
691 0 : if (parse_tag (&p, &n, &ti))
692 0 : goto bailout;
693 0 : if (ti.class != ASNCONTEXT || ti.tag)
694 : goto bailout;
695 0 : if (parse_tag (&p, &n, &ti))
696 0 : goto bailout;
697 0 : if (ti.tag != TAG_SEQUENCE)
698 0 : goto bailout;
699 :
700 0 : where = "bag.encryptedData.version";
701 0 : if (parse_tag (&p, &n, &ti))
702 0 : goto bailout;
703 0 : if (ti.tag != TAG_INTEGER || ti.length != 1 || *p != 0)
704 : goto bailout;
705 0 : p++; n--;
706 0 : if (parse_tag (&p, &n, &ti))
707 0 : goto bailout;
708 0 : if (ti.tag != TAG_SEQUENCE)
709 0 : goto bailout;
710 :
711 0 : where = "bag.encryptedData.data";
712 0 : if (parse_tag (&p, &n, &ti))
713 0 : goto bailout;
714 0 : if (ti.tag != TAG_OBJECT_ID || ti.length != DIM(oid_data)
715 0 : || memcmp (p, oid_data, DIM(oid_data)))
716 : goto bailout;
717 0 : p += DIM(oid_data);
718 0 : n -= DIM(oid_data);
719 :
720 0 : where = "bag.encryptedData.keyinfo";
721 0 : if (parse_tag (&p, &n, &ti))
722 0 : goto bailout;
723 0 : if (ti.class || ti.tag != TAG_SEQUENCE)
724 : goto bailout;
725 0 : if (parse_tag (&p, &n, &ti))
726 0 : goto bailout;
727 0 : if (!ti.class && ti.tag == TAG_OBJECT_ID
728 0 : && ti.length == DIM(oid_pbeWithSHAAnd40BitRC2_CBC)
729 0 : && !memcmp (p, oid_pbeWithSHAAnd40BitRC2_CBC,
730 : DIM(oid_pbeWithSHAAnd40BitRC2_CBC)))
731 : {
732 0 : p += DIM(oid_pbeWithSHAAnd40BitRC2_CBC);
733 0 : n -= DIM(oid_pbeWithSHAAnd40BitRC2_CBC);
734 : }
735 0 : else if (!ti.class && ti.tag == TAG_OBJECT_ID
736 0 : && ti.length == DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)
737 0 : && !memcmp (p, oid_pbeWithSHAAnd3_KeyTripleDES_CBC,
738 : DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)))
739 : {
740 0 : p += DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
741 0 : n -= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
742 0 : is_3des = 1;
743 : }
744 0 : else if (!ti.class && ti.tag == TAG_OBJECT_ID
745 0 : && ti.length == DIM(oid_pkcs5PBES2)
746 0 : && !memcmp (p, oid_pkcs5PBES2, ti.length))
747 : {
748 0 : p += ti.length;
749 0 : n -= ti.length;
750 0 : is_pbes2 = 1;
751 : }
752 : else
753 : goto bailout;
754 :
755 0 : if (is_pbes2)
756 : {
757 0 : where = "pkcs5PBES2-params";
758 0 : if (parse_tag (&p, &n, &ti))
759 0 : goto bailout;
760 0 : if (ti.class || ti.tag != TAG_SEQUENCE)
761 : goto bailout;
762 0 : if (parse_tag (&p, &n, &ti))
763 0 : goto bailout;
764 0 : if (ti.class || ti.tag != TAG_SEQUENCE)
765 : goto bailout;
766 0 : if (parse_tag (&p, &n, &ti))
767 0 : goto bailout;
768 0 : if (!(!ti.class && ti.tag == TAG_OBJECT_ID
769 0 : && ti.length == DIM(oid_pkcs5PBKDF2)
770 0 : && !memcmp (p, oid_pkcs5PBKDF2, ti.length)))
771 : goto bailout; /* Not PBKDF2. */
772 0 : p += ti.length;
773 0 : n -= ti.length;
774 0 : if (parse_tag (&p, &n, &ti))
775 0 : goto bailout;
776 0 : if (ti.class || ti.tag != TAG_SEQUENCE)
777 : goto bailout;
778 0 : if (parse_tag (&p, &n, &ti))
779 0 : goto bailout;
780 0 : if (!(!ti.class && ti.tag == TAG_OCTET_STRING
781 0 : && ti.length >= 8 && ti.length < sizeof salt))
782 : goto bailout; /* No salt or unsupported length. */
783 0 : saltlen = ti.length;
784 0 : memcpy (salt, p, saltlen);
785 0 : p += saltlen;
786 0 : n -= saltlen;
787 :
788 0 : if (parse_tag (&p, &n, &ti))
789 0 : goto bailout;
790 0 : if (!(!ti.class && ti.tag == TAG_INTEGER && ti.length))
791 : goto bailout; /* No valid iteration count. */
792 0 : for (iter=0; ti.length; ti.length--)
793 : {
794 0 : iter <<= 8;
795 0 : iter |= (*p++) & 0xff;
796 0 : n--;
797 : }
798 : /* Note: We don't support the optional parameters but assume
799 : that the algorithmIdentifier follows. */
800 0 : if (parse_tag (&p, &n, &ti))
801 0 : goto bailout;
802 0 : if (ti.class || ti.tag != TAG_SEQUENCE)
803 : goto bailout;
804 0 : if (parse_tag (&p, &n, &ti))
805 0 : goto bailout;
806 0 : if (!(!ti.class && ti.tag == TAG_OBJECT_ID
807 0 : && ti.length == DIM(oid_aes128_CBC)
808 0 : && !memcmp (p, oid_aes128_CBC, ti.length)))
809 : goto bailout; /* Not AES-128. */
810 0 : p += ti.length;
811 0 : n -= ti.length;
812 0 : if (parse_tag (&p, &n, &ti))
813 0 : goto bailout;
814 0 : if (!(!ti.class && ti.tag == TAG_OCTET_STRING && ti.length == sizeof iv))
815 : goto bailout; /* Bad IV. */
816 0 : memcpy (iv, p, sizeof iv);
817 0 : p += sizeof iv;
818 0 : n -= sizeof iv;
819 : }
820 : else
821 : {
822 0 : where = "rc2or3des-params";
823 0 : if (parse_tag (&p, &n, &ti))
824 0 : goto bailout;
825 0 : if (ti.class || ti.tag != TAG_SEQUENCE)
826 : goto bailout;
827 0 : if (parse_tag (&p, &n, &ti))
828 0 : goto bailout;
829 0 : if (ti.class || ti.tag != TAG_OCTET_STRING
830 0 : || ti.length < 8 || ti.length > 20 )
831 : goto bailout;
832 0 : saltlen = ti.length;
833 0 : memcpy (salt, p, saltlen);
834 0 : p += saltlen;
835 0 : n -= saltlen;
836 0 : if (parse_tag (&p, &n, &ti))
837 0 : goto bailout;
838 0 : if (ti.class || ti.tag != TAG_INTEGER || !ti.length )
839 : goto bailout;
840 0 : for (iter=0; ti.length; ti.length--)
841 : {
842 0 : iter <<= 8;
843 0 : iter |= (*p++) & 0xff;
844 0 : n--;
845 : }
846 : }
847 :
848 0 : where = "rc2or3desoraes-ciphertext";
849 0 : if (parse_tag (&p, &n, &ti))
850 0 : goto bailout;
851 :
852 0 : consumed = p - p_start;
853 0 : if (ti.class == ASNCONTEXT && ti.tag == 0 && ti.is_constructed && ti.ndef)
854 : {
855 : /* Mozilla exported certs now come with single byte chunks of
856 : octect strings. (Mozilla Firefox 1.0.4). Arghh. */
857 0 : where = "cram-rc2or3des-ciphertext";
858 0 : cram_buffer = cram_octet_string ( p, &n, &consumed);
859 0 : if (!cram_buffer)
860 0 : goto bailout;
861 0 : p = p_start = cram_buffer;
862 0 : if (r_consumed)
863 0 : *r_consumed = consumed;
864 0 : r_consumed = NULL; /* Ugly hack to not update that value any further. */
865 0 : ti.length = n;
866 : }
867 0 : else if (ti.class == ASNCONTEXT && ti.tag == 0 && ti.length )
868 : ;
869 : else
870 : goto bailout;
871 :
872 0 : log_info ("%lu bytes of %s encrypted text\n",ti.length,
873 0 : is_pbes2?"AES128":is_3des?"3DES":"RC2");
874 :
875 0 : plain = gcry_malloc_secure (ti.length);
876 0 : if (!plain)
877 : {
878 0 : log_error ("error allocating decryption buffer\n");
879 0 : goto bailout;
880 : }
881 0 : decrypt_block (p, plain, ti.length, salt, saltlen, iter,
882 : iv, is_pbes2?16:0, pw,
883 : is_pbes2 ? GCRY_CIPHER_AES128 :
884 0 : is_3des ? GCRY_CIPHER_3DES : GCRY_CIPHER_RFC2268_40,
885 : bag_decrypted_data_p);
886 0 : n = ti.length;
887 0 : startoffset = 0;
888 0 : p_start = p = plain;
889 :
890 0 : where = "outer.outer.seq";
891 0 : if (parse_tag (&p, &n, &ti))
892 : {
893 0 : bad_pass = 1;
894 0 : goto bailout;
895 : }
896 0 : if (ti.class || ti.tag != TAG_SEQUENCE)
897 : {
898 0 : bad_pass = 1;
899 0 : goto bailout;
900 : }
901 :
902 0 : if (parse_tag (&p, &n, &ti))
903 : {
904 0 : bad_pass = 1;
905 0 : goto bailout;
906 : }
907 :
908 : /* Loop over all certificates inside the bag. */
909 0 : while (n)
910 : {
911 0 : int iscrlbag = 0;
912 0 : int iskeybag = 0;
913 :
914 0 : where = "certbag.nextcert";
915 0 : if (ti.class || ti.tag != TAG_SEQUENCE)
916 : goto bailout;
917 :
918 0 : where = "certbag.objectidentifier";
919 0 : if (parse_tag (&p, &n, &ti))
920 0 : goto bailout;
921 0 : if (ti.class || ti.tag != TAG_OBJECT_ID)
922 : goto bailout;
923 0 : if ( ti.length == DIM(oid_pkcs_12_CertBag)
924 0 : && !memcmp (p, oid_pkcs_12_CertBag, DIM(oid_pkcs_12_CertBag)))
925 : {
926 0 : p += DIM(oid_pkcs_12_CertBag);
927 0 : n -= DIM(oid_pkcs_12_CertBag);
928 : }
929 0 : else if ( ti.length == DIM(oid_pkcs_12_CrlBag)
930 0 : && !memcmp (p, oid_pkcs_12_CrlBag, DIM(oid_pkcs_12_CrlBag)))
931 : {
932 0 : p += DIM(oid_pkcs_12_CrlBag);
933 0 : n -= DIM(oid_pkcs_12_CrlBag);
934 0 : iscrlbag = 1;
935 : }
936 0 : else if ( ti.length == DIM(oid_pkcs_12_keyBag)
937 0 : && !memcmp (p, oid_pkcs_12_keyBag, DIM(oid_pkcs_12_keyBag)))
938 : {
939 : /* The TrustedMIME plugin for MS Outlook started to create
940 : files with just one outer 3DES encrypted container and
941 : inside the certificates as well as the key. */
942 0 : p += DIM(oid_pkcs_12_keyBag);
943 0 : n -= DIM(oid_pkcs_12_keyBag);
944 0 : iskeybag = 1;
945 : }
946 : else
947 : goto bailout;
948 :
949 0 : where = "certbag.before.certheader";
950 0 : if (parse_tag (&p, &n, &ti))
951 0 : goto bailout;
952 0 : if (ti.class != ASNCONTEXT || ti.tag)
953 : goto bailout;
954 0 : if (iscrlbag)
955 : {
956 0 : log_info ("skipping unsupported crlBag\n");
957 0 : p += ti.length;
958 0 : n -= ti.length;
959 : }
960 0 : else if (iskeybag && (result || !r_result))
961 : {
962 0 : log_info ("one keyBag already processed; skipping this one\n");
963 0 : p += ti.length;
964 0 : n -= ti.length;
965 : }
966 0 : else if (iskeybag)
967 : {
968 : int len;
969 :
970 0 : log_info ("processing simple keyBag\n");
971 :
972 : /* Fixme: This code is duplicated from parse_bag_data. */
973 0 : if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
974 : goto bailout;
975 0 : if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER
976 0 : || ti.length != 1 || *p)
977 : goto bailout;
978 0 : p++; n--;
979 0 : if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
980 : goto bailout;
981 0 : len = ti.length;
982 0 : if (parse_tag (&p, &n, &ti))
983 0 : goto bailout;
984 0 : if (len < ti.nhdr)
985 0 : goto bailout;
986 0 : len -= ti.nhdr;
987 0 : if (ti.class || ti.tag != TAG_OBJECT_ID
988 0 : || ti.length != DIM(oid_rsaEncryption)
989 0 : || memcmp (p, oid_rsaEncryption,
990 : DIM(oid_rsaEncryption)))
991 : goto bailout;
992 0 : p += DIM (oid_rsaEncryption);
993 0 : n -= DIM (oid_rsaEncryption);
994 0 : if (len < ti.length)
995 0 : goto bailout;
996 0 : len -= ti.length;
997 0 : if (n < len)
998 0 : goto bailout;
999 0 : p += len;
1000 0 : n -= len;
1001 0 : if ( parse_tag (&p, &n, &ti)
1002 0 : || ti.class || ti.tag != TAG_OCTET_STRING)
1003 : goto bailout;
1004 0 : if ( parse_tag (&p, &n, &ti)
1005 0 : || ti.class || ti.tag != TAG_SEQUENCE)
1006 : goto bailout;
1007 0 : len = ti.length;
1008 :
1009 0 : result = gcry_calloc (10, sizeof *result);
1010 0 : if (!result)
1011 : {
1012 0 : log_error ( "error allocating result array\n");
1013 0 : goto bailout;
1014 : }
1015 0 : result_count = 0;
1016 :
1017 0 : where = "reading.keybag.key-parameters";
1018 0 : for (result_count = 0; len && result_count < 9;)
1019 : {
1020 0 : if ( parse_tag (&p, &n, &ti)
1021 0 : || ti.class || ti.tag != TAG_INTEGER)
1022 : goto bailout;
1023 0 : if (len < ti.nhdr)
1024 0 : goto bailout;
1025 0 : len -= ti.nhdr;
1026 0 : if (len < ti.length)
1027 0 : goto bailout;
1028 0 : len -= ti.length;
1029 0 : if (!result_count && ti.length == 1 && !*p)
1030 : ; /* ignore the very first one if it is a 0 */
1031 : else
1032 : {
1033 : int rc;
1034 :
1035 0 : rc = gcry_mpi_scan (result+result_count, GCRYMPI_FMT_USG, p,
1036 : ti.length, NULL);
1037 0 : if (rc)
1038 : {
1039 0 : log_error ("error parsing key parameter: %s\n",
1040 : gpg_strerror (rc));
1041 0 : goto bailout;
1042 : }
1043 0 : result_count++;
1044 : }
1045 0 : p += ti.length;
1046 0 : n -= ti.length;
1047 : }
1048 0 : if (len)
1049 0 : goto bailout;
1050 : }
1051 : else
1052 : {
1053 0 : log_info ("processing certBag\n");
1054 0 : if (parse_tag (&p, &n, &ti))
1055 0 : goto bailout;
1056 0 : if (ti.class || ti.tag != TAG_SEQUENCE)
1057 : goto bailout;
1058 0 : if (parse_tag (&p, &n, &ti))
1059 0 : goto bailout;
1060 0 : if (ti.class || ti.tag != TAG_OBJECT_ID
1061 0 : || ti.length != DIM(oid_x509Certificate_for_pkcs_12)
1062 0 : || memcmp (p, oid_x509Certificate_for_pkcs_12,
1063 : DIM(oid_x509Certificate_for_pkcs_12)))
1064 : goto bailout;
1065 0 : p += DIM(oid_x509Certificate_for_pkcs_12);
1066 0 : n -= DIM(oid_x509Certificate_for_pkcs_12);
1067 :
1068 0 : where = "certbag.before.octetstring";
1069 0 : if (parse_tag (&p, &n, &ti))
1070 0 : goto bailout;
1071 0 : if (ti.class != ASNCONTEXT || ti.tag)
1072 : goto bailout;
1073 0 : if (parse_tag (&p, &n, &ti))
1074 0 : goto bailout;
1075 0 : if (ti.class || ti.tag != TAG_OCTET_STRING || ti.ndef)
1076 : goto bailout;
1077 :
1078 : /* Return the certificate. */
1079 0 : if (certcb)
1080 0 : certcb (certcbarg, p, ti.length);
1081 :
1082 0 : p += ti.length;
1083 0 : n -= ti.length;
1084 : }
1085 :
1086 : /* Ugly hack to cope with the padding: Forget about the rest if
1087 : that is less or equal to the cipher's block length. We can
1088 : reasonable assume that all valid data will be longer than
1089 : just one block. */
1090 0 : if (n <= (is_pbes2? 16:8))
1091 0 : n = 0;
1092 :
1093 : /* Skip the optional SET with the pkcs12 cert attributes. */
1094 0 : if (n)
1095 : {
1096 0 : where = "bag.attributes";
1097 0 : if (parse_tag (&p, &n, &ti))
1098 0 : goto bailout;
1099 0 : if (!ti.class && ti.tag == TAG_SEQUENCE)
1100 : ; /* No attributes. */
1101 0 : else if (!ti.class && ti.tag == TAG_SET && !ti.ndef)
1102 : { /* The optional SET. */
1103 0 : p += ti.length;
1104 0 : n -= ti.length;
1105 0 : if (n <= (is_pbes2?16:8))
1106 0 : n = 0;
1107 0 : if (n && parse_tag (&p, &n, &ti))
1108 0 : goto bailout;
1109 : }
1110 : else
1111 : goto bailout;
1112 : }
1113 : }
1114 :
1115 0 : if (r_consumed)
1116 0 : *r_consumed = consumed;
1117 0 : gcry_free (plain);
1118 0 : gcry_free (cram_buffer);
1119 0 : if (r_result)
1120 0 : *r_result = result;
1121 0 : return 0;
1122 :
1123 : bailout:
1124 0 : if (result)
1125 : {
1126 : int i;
1127 :
1128 0 : for (i=0; result[i]; i++)
1129 0 : gcry_mpi_release (result[i]);
1130 0 : gcry_free (result);
1131 : }
1132 0 : if (r_consumed)
1133 0 : *r_consumed = consumed;
1134 0 : gcry_free (plain);
1135 0 : gcry_free (cram_buffer);
1136 0 : log_error ("encryptedData error at \"%s\", offset %u\n",
1137 0 : where, (unsigned int)((p - p_start)+startoffset));
1138 0 : if (bad_pass)
1139 : {
1140 : /* Note, that the following string might be used by other programs
1141 : to check for a bad passphrase; it should therefore not be
1142 : translated or changed. */
1143 0 : log_error ("possibly bad passphrase given\n");
1144 0 : *r_badpass = 1;
1145 : }
1146 0 : return -1;
1147 : }
1148 :
1149 :
1150 : /* Return true if the decryption of a bag_data object has likely
1151 : succeeded. */
1152 : static int
1153 0 : bag_data_p (const void *plaintext, size_t length)
1154 : {
1155 : struct tag_info ti;
1156 0 : const unsigned char *p = plaintext;
1157 0 : size_t n = length;
1158 :
1159 : /* { */
1160 : /* # warning debug code is enabled */
1161 : /* FILE *fp = fopen ("tmp-3des-plain-key.der", "wb"); */
1162 : /* if (!fp || fwrite (p, n, 1, fp) != 1) */
1163 : /* exit (2); */
1164 : /* fclose (fp); */
1165 : /* } */
1166 :
1167 0 : if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
1168 0 : return 0;
1169 0 : if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER
1170 0 : || ti.length != 1 || *p)
1171 0 : return 0;
1172 :
1173 0 : return 1;
1174 : }
1175 :
1176 :
1177 : static gcry_mpi_t *
1178 0 : parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
1179 : size_t *r_consumed, const char *pw)
1180 : {
1181 : int rc;
1182 : struct tag_info ti;
1183 0 : const unsigned char *p = buffer;
1184 0 : const unsigned char *p_start = buffer;
1185 0 : size_t n = length;
1186 : const char *where;
1187 : char salt[20];
1188 : size_t saltlen;
1189 : char iv[16];
1190 : unsigned int iter;
1191 : int len;
1192 0 : unsigned char *plain = NULL;
1193 0 : gcry_mpi_t *result = NULL;
1194 : int result_count, i;
1195 0 : unsigned char *cram_buffer = NULL;
1196 0 : size_t consumed = 0; /* Number of bytes consumed from the original buffer. */
1197 0 : int is_pbes2 = 0;
1198 :
1199 0 : where = "start";
1200 0 : if (parse_tag (&p, &n, &ti))
1201 0 : goto bailout;
1202 0 : if (ti.class != ASNCONTEXT || ti.tag)
1203 : goto bailout;
1204 0 : if (parse_tag (&p, &n, &ti))
1205 0 : goto bailout;
1206 0 : if (ti.class || ti.tag != TAG_OCTET_STRING)
1207 : goto bailout;
1208 :
1209 0 : consumed = p - p_start;
1210 0 : if (ti.is_constructed && ti.ndef)
1211 : {
1212 : /* Mozilla exported certs now come with single byte chunks of
1213 : octect strings. (Mozilla Firefox 1.0.4). Arghh. */
1214 0 : where = "cram-data.outersegs";
1215 0 : cram_buffer = cram_octet_string ( p, &n, &consumed);
1216 0 : if (!cram_buffer)
1217 0 : goto bailout;
1218 0 : p = p_start = cram_buffer;
1219 0 : if (r_consumed)
1220 0 : *r_consumed = consumed;
1221 0 : r_consumed = NULL; /* Ugly hack to not update that value any further. */
1222 : }
1223 :
1224 :
1225 0 : where = "data.outerseqs";
1226 0 : if (parse_tag (&p, &n, &ti))
1227 0 : goto bailout;
1228 0 : if (ti.class || ti.tag != TAG_SEQUENCE)
1229 : goto bailout;
1230 0 : if (parse_tag (&p, &n, &ti))
1231 0 : goto bailout;
1232 0 : if (ti.class || ti.tag != TAG_SEQUENCE)
1233 : goto bailout;
1234 :
1235 0 : where = "data.objectidentifier";
1236 0 : if (parse_tag (&p, &n, &ti))
1237 0 : goto bailout;
1238 0 : if (ti.class || ti.tag != TAG_OBJECT_ID
1239 0 : || ti.length != DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag)
1240 0 : || memcmp (p, oid_pkcs_12_pkcs_8ShroudedKeyBag,
1241 : DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag)))
1242 : goto bailout;
1243 0 : p += DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag);
1244 0 : n -= DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag);
1245 :
1246 0 : where = "shrouded,outerseqs";
1247 0 : if (parse_tag (&p, &n, &ti))
1248 0 : goto bailout;
1249 0 : if (ti.class != ASNCONTEXT || ti.tag)
1250 : goto bailout;
1251 0 : if (parse_tag (&p, &n, &ti))
1252 0 : goto bailout;
1253 0 : if (ti.class || ti.tag != TAG_SEQUENCE)
1254 : goto bailout;
1255 0 : if (parse_tag (&p, &n, &ti))
1256 0 : goto bailout;
1257 0 : if (ti.class || ti.tag != TAG_SEQUENCE)
1258 : goto bailout;
1259 0 : if (parse_tag (&p, &n, &ti))
1260 0 : goto bailout;
1261 0 : if (ti.class == 0 && ti.tag == TAG_OBJECT_ID
1262 0 : && ti.length == DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)
1263 0 : && !memcmp (p, oid_pbeWithSHAAnd3_KeyTripleDES_CBC,
1264 : DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC)))
1265 : {
1266 0 : p += DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
1267 0 : n -= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC);
1268 : }
1269 0 : else if (ti.class == 0 && ti.tag == TAG_OBJECT_ID
1270 0 : && ti.length == DIM(oid_pkcs5PBES2)
1271 0 : && !memcmp (p, oid_pkcs5PBES2, DIM(oid_pkcs5PBES2)))
1272 : {
1273 0 : p += DIM(oid_pkcs5PBES2);
1274 0 : n -= DIM(oid_pkcs5PBES2);
1275 0 : is_pbes2 = 1;
1276 : }
1277 : else
1278 : goto bailout;
1279 :
1280 0 : if (is_pbes2)
1281 : {
1282 0 : where = "pkcs5PBES2-params";
1283 0 : if (parse_tag (&p, &n, &ti))
1284 0 : goto bailout;
1285 0 : if (ti.class || ti.tag != TAG_SEQUENCE)
1286 : goto bailout;
1287 0 : if (parse_tag (&p, &n, &ti))
1288 0 : goto bailout;
1289 0 : if (ti.class || ti.tag != TAG_SEQUENCE)
1290 : goto bailout;
1291 0 : if (parse_tag (&p, &n, &ti))
1292 0 : goto bailout;
1293 0 : if (!(!ti.class && ti.tag == TAG_OBJECT_ID
1294 0 : && ti.length == DIM(oid_pkcs5PBKDF2)
1295 0 : && !memcmp (p, oid_pkcs5PBKDF2, ti.length)))
1296 : goto bailout; /* Not PBKDF2. */
1297 0 : p += ti.length;
1298 0 : n -= ti.length;
1299 0 : if (parse_tag (&p, &n, &ti))
1300 0 : goto bailout;
1301 0 : if (ti.class || ti.tag != TAG_SEQUENCE)
1302 : goto bailout;
1303 0 : if (parse_tag (&p, &n, &ti))
1304 0 : goto bailout;
1305 0 : if (!(!ti.class && ti.tag == TAG_OCTET_STRING
1306 0 : && ti.length >= 8 && ti.length < sizeof salt))
1307 : goto bailout; /* No salt or unsupported length. */
1308 0 : saltlen = ti.length;
1309 0 : memcpy (salt, p, saltlen);
1310 0 : p += saltlen;
1311 0 : n -= saltlen;
1312 :
1313 0 : if (parse_tag (&p, &n, &ti))
1314 0 : goto bailout;
1315 0 : if (!(!ti.class && ti.tag == TAG_INTEGER && ti.length))
1316 : goto bailout; /* No valid iteration count. */
1317 0 : for (iter=0; ti.length; ti.length--)
1318 : {
1319 0 : iter <<= 8;
1320 0 : iter |= (*p++) & 0xff;
1321 0 : n--;
1322 : }
1323 : /* Note: We don't support the optional parameters but assume
1324 : that the algorithmIdentifier follows. */
1325 0 : if (parse_tag (&p, &n, &ti))
1326 0 : goto bailout;
1327 0 : if (ti.class || ti.tag != TAG_SEQUENCE)
1328 : goto bailout;
1329 0 : if (parse_tag (&p, &n, &ti))
1330 0 : goto bailout;
1331 0 : if (!(!ti.class && ti.tag == TAG_OBJECT_ID
1332 0 : && ti.length == DIM(oid_aes128_CBC)
1333 0 : && !memcmp (p, oid_aes128_CBC, ti.length)))
1334 : goto bailout; /* Not AES-128. */
1335 0 : p += ti.length;
1336 0 : n -= ti.length;
1337 0 : if (parse_tag (&p, &n, &ti))
1338 0 : goto bailout;
1339 0 : if (!(!ti.class && ti.tag == TAG_OCTET_STRING && ti.length == sizeof iv))
1340 : goto bailout; /* Bad IV. */
1341 0 : memcpy (iv, p, sizeof iv);
1342 0 : p += sizeof iv;
1343 0 : n -= sizeof iv;
1344 : }
1345 : else
1346 : {
1347 0 : where = "3des-params";
1348 0 : if (parse_tag (&p, &n, &ti))
1349 0 : goto bailout;
1350 0 : if (ti.class || ti.tag != TAG_SEQUENCE)
1351 : goto bailout;
1352 0 : if (parse_tag (&p, &n, &ti))
1353 0 : goto bailout;
1354 0 : if (ti.class || ti.tag != TAG_OCTET_STRING
1355 0 : || ti.length < 8 || ti.length > 20)
1356 : goto bailout;
1357 0 : saltlen = ti.length;
1358 0 : memcpy (salt, p, saltlen);
1359 0 : p += saltlen;
1360 0 : n -= saltlen;
1361 0 : if (parse_tag (&p, &n, &ti))
1362 0 : goto bailout;
1363 0 : if (ti.class || ti.tag != TAG_INTEGER || !ti.length )
1364 : goto bailout;
1365 0 : for (iter=0; ti.length; ti.length--)
1366 : {
1367 0 : iter <<= 8;
1368 0 : iter |= (*p++) & 0xff;
1369 0 : n--;
1370 : }
1371 : }
1372 :
1373 0 : where = "3desoraes-ciphertext";
1374 0 : if (parse_tag (&p, &n, &ti))
1375 0 : goto bailout;
1376 0 : if (ti.class || ti.tag != TAG_OCTET_STRING || !ti.length )
1377 : goto bailout;
1378 :
1379 0 : log_info ("%lu bytes of %s encrypted text\n",
1380 : ti.length, is_pbes2? "AES128":"3DES");
1381 :
1382 0 : plain = gcry_malloc_secure (ti.length);
1383 0 : if (!plain)
1384 : {
1385 0 : log_error ("error allocating decryption buffer\n");
1386 0 : goto bailout;
1387 : }
1388 0 : consumed += p - p_start + ti.length;
1389 0 : decrypt_block (p, plain, ti.length, salt, saltlen, iter,
1390 : iv, is_pbes2? 16:0, pw,
1391 : is_pbes2? GCRY_CIPHER_AES128 : GCRY_CIPHER_3DES,
1392 : bag_data_p);
1393 0 : n = ti.length;
1394 0 : startoffset = 0;
1395 0 : p_start = p = plain;
1396 :
1397 0 : where = "decrypted-text";
1398 0 : if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
1399 : goto bailout;
1400 0 : if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER
1401 0 : || ti.length != 1 || *p)
1402 : goto bailout;
1403 0 : p++; n--;
1404 0 : if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
1405 : goto bailout;
1406 0 : len = ti.length;
1407 0 : if (parse_tag (&p, &n, &ti))
1408 0 : goto bailout;
1409 0 : if (len < ti.nhdr)
1410 0 : goto bailout;
1411 0 : len -= ti.nhdr;
1412 0 : if (ti.class || ti.tag != TAG_OBJECT_ID
1413 0 : || ti.length != DIM(oid_rsaEncryption)
1414 0 : || memcmp (p, oid_rsaEncryption,
1415 : DIM(oid_rsaEncryption)))
1416 : goto bailout;
1417 0 : p += DIM (oid_rsaEncryption);
1418 0 : n -= DIM (oid_rsaEncryption);
1419 0 : if (len < ti.length)
1420 0 : goto bailout;
1421 0 : len -= ti.length;
1422 0 : if (n < len)
1423 0 : goto bailout;
1424 0 : p += len;
1425 0 : n -= len;
1426 0 : if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_OCTET_STRING)
1427 : goto bailout;
1428 0 : if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
1429 : goto bailout;
1430 0 : len = ti.length;
1431 :
1432 0 : result = gcry_calloc (10, sizeof *result);
1433 0 : if (!result)
1434 : {
1435 0 : log_error ( "error allocating result array\n");
1436 0 : goto bailout;
1437 : }
1438 0 : result_count = 0;
1439 :
1440 0 : where = "reading.key-parameters";
1441 0 : for (result_count=0; len && result_count < 9;)
1442 : {
1443 0 : if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER)
1444 : goto bailout;
1445 0 : if (len < ti.nhdr)
1446 0 : goto bailout;
1447 0 : len -= ti.nhdr;
1448 0 : if (len < ti.length)
1449 0 : goto bailout;
1450 0 : len -= ti.length;
1451 0 : if (!result_count && ti.length == 1 && !*p)
1452 : ; /* ignore the very first one if it is a 0 */
1453 : else
1454 : {
1455 0 : rc = gcry_mpi_scan (result+result_count, GCRYMPI_FMT_USG, p,
1456 : ti.length, NULL);
1457 0 : if (rc)
1458 : {
1459 0 : log_error ("error parsing key parameter: %s\n",
1460 : gpg_strerror (rc));
1461 0 : goto bailout;
1462 : }
1463 0 : result_count++;
1464 : }
1465 0 : p += ti.length;
1466 0 : n -= ti.length;
1467 : }
1468 0 : if (len)
1469 0 : goto bailout;
1470 :
1471 0 : gcry_free (cram_buffer);
1472 0 : if (r_consumed)
1473 0 : *r_consumed = consumed;
1474 0 : return result;
1475 :
1476 : bailout:
1477 0 : gcry_free (plain);
1478 0 : if (result)
1479 : {
1480 0 : for (i=0; result[i]; i++)
1481 0 : gcry_mpi_release (result[i]);
1482 0 : gcry_free (result);
1483 : }
1484 0 : gcry_free (cram_buffer);
1485 0 : log_error ( "data error at \"%s\", offset %u\n",
1486 0 : where, (unsigned int)((p - buffer) + startoffset));
1487 0 : if (r_consumed)
1488 0 : *r_consumed = consumed;
1489 0 : return NULL;
1490 : }
1491 :
1492 :
1493 : /* Parse a PKCS12 object and return an array of MPI representing the
1494 : secret key parameters. This is a very limited implementation in
1495 : that it is only able to look for 3DES encoded encryptedData and
1496 : tries to extract the first private key object it finds. In case of
1497 : an error NULL is returned. CERTCB and CERRTCBARG are used to pass
1498 : X.509 certificates back to the caller. */
1499 : gcry_mpi_t *
1500 0 : p12_parse (const unsigned char *buffer, size_t length, const char *pw,
1501 : void (*certcb)(void*, const unsigned char*, size_t),
1502 : void *certcbarg, int *r_badpass)
1503 : {
1504 : struct tag_info ti;
1505 0 : const unsigned char *p = buffer;
1506 0 : const unsigned char *p_start = buffer;
1507 0 : size_t n = length;
1508 : const char *where;
1509 : int bagseqlength, len;
1510 : int bagseqndef, lenndef;
1511 0 : gcry_mpi_t *result = NULL;
1512 0 : unsigned char *cram_buffer = NULL;
1513 :
1514 0 : *r_badpass = 0;
1515 0 : where = "pfx";
1516 0 : if (parse_tag (&p, &n, &ti))
1517 0 : goto bailout;
1518 0 : if (ti.tag != TAG_SEQUENCE)
1519 0 : goto bailout;
1520 :
1521 0 : where = "pfxVersion";
1522 0 : if (parse_tag (&p, &n, &ti))
1523 0 : goto bailout;
1524 0 : if (ti.tag != TAG_INTEGER || ti.length != 1 || *p != 3)
1525 : goto bailout;
1526 0 : p++; n--;
1527 :
1528 0 : where = "authSave";
1529 0 : if (parse_tag (&p, &n, &ti))
1530 0 : goto bailout;
1531 0 : if (ti.tag != TAG_SEQUENCE)
1532 0 : goto bailout;
1533 0 : if (parse_tag (&p, &n, &ti))
1534 0 : goto bailout;
1535 0 : if (ti.tag != TAG_OBJECT_ID || ti.length != DIM(oid_data)
1536 0 : || memcmp (p, oid_data, DIM(oid_data)))
1537 : goto bailout;
1538 0 : p += DIM(oid_data);
1539 0 : n -= DIM(oid_data);
1540 :
1541 0 : if (parse_tag (&p, &n, &ti))
1542 0 : goto bailout;
1543 0 : if (ti.class != ASNCONTEXT || ti.tag)
1544 : goto bailout;
1545 0 : if (parse_tag (&p, &n, &ti))
1546 0 : goto bailout;
1547 0 : if (ti.class != UNIVERSAL || ti.tag != TAG_OCTET_STRING)
1548 : goto bailout;
1549 :
1550 0 : if (ti.is_constructed && ti.ndef)
1551 : {
1552 : /* Mozilla exported certs now come with single byte chunks of
1553 : octect strings. (Mozilla Firefox 1.0.4). Arghh. */
1554 0 : where = "cram-bags";
1555 0 : cram_buffer = cram_octet_string ( p, &n, NULL);
1556 0 : if (!cram_buffer)
1557 0 : goto bailout;
1558 0 : p = p_start = cram_buffer;
1559 : }
1560 :
1561 0 : where = "bags";
1562 0 : if (parse_tag (&p, &n, &ti))
1563 0 : goto bailout;
1564 0 : if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE)
1565 : goto bailout;
1566 0 : bagseqndef = ti.ndef;
1567 0 : bagseqlength = ti.length;
1568 0 : while (bagseqlength || bagseqndef)
1569 : {
1570 : /* log_debug ( "at offset %u\n", (p - p_start)); */
1571 0 : where = "bag-sequence";
1572 0 : if (parse_tag (&p, &n, &ti))
1573 0 : goto bailout;
1574 0 : if (bagseqndef && ti.class == UNIVERSAL && !ti.tag && !ti.is_constructed)
1575 0 : break; /* Ready */
1576 0 : if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE)
1577 : goto bailout;
1578 :
1579 0 : if (!bagseqndef)
1580 : {
1581 0 : if (bagseqlength < ti.nhdr)
1582 0 : goto bailout;
1583 0 : bagseqlength -= ti.nhdr;
1584 0 : if (bagseqlength < ti.length)
1585 0 : goto bailout;
1586 0 : bagseqlength -= ti.length;
1587 : }
1588 0 : lenndef = ti.ndef;
1589 0 : len = ti.length;
1590 :
1591 0 : if (parse_tag (&p, &n, &ti))
1592 0 : goto bailout;
1593 0 : if (lenndef)
1594 0 : len = ti.nhdr;
1595 : else
1596 0 : len -= ti.nhdr;
1597 :
1598 0 : if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_encryptedData)
1599 0 : && !memcmp (p, oid_encryptedData, DIM(oid_encryptedData)))
1600 0 : {
1601 0 : size_t consumed = 0;
1602 :
1603 0 : p += DIM(oid_encryptedData);
1604 0 : n -= DIM(oid_encryptedData);
1605 0 : if (!lenndef)
1606 0 : len -= DIM(oid_encryptedData);
1607 0 : where = "bag.encryptedData";
1608 0 : if (parse_bag_encrypted_data (p, n, (p - p_start), &consumed, pw,
1609 : certcb, certcbarg,
1610 0 : result? NULL : &result, r_badpass))
1611 0 : goto bailout;
1612 0 : if (lenndef)
1613 0 : len += consumed;
1614 : }
1615 0 : else if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_data)
1616 0 : && !memcmp (p, oid_data, DIM(oid_data)))
1617 : {
1618 0 : if (result)
1619 : {
1620 0 : log_info ("already got an key object, skipping this one\n");
1621 0 : p += ti.length;
1622 0 : n -= ti.length;
1623 : }
1624 : else
1625 : {
1626 0 : size_t consumed = 0;
1627 :
1628 0 : p += DIM(oid_data);
1629 0 : n -= DIM(oid_data);
1630 0 : if (!lenndef)
1631 0 : len -= DIM(oid_data);
1632 0 : result = parse_bag_data (p, n, (p - p_start), &consumed, pw);
1633 0 : if (!result)
1634 0 : goto bailout;
1635 0 : if (lenndef)
1636 0 : len += consumed;
1637 : }
1638 : }
1639 : else
1640 : {
1641 0 : log_info ("unknown bag type - skipped\n");
1642 0 : p += ti.length;
1643 0 : n -= ti.length;
1644 : }
1645 :
1646 0 : if (len < 0 || len > n)
1647 : goto bailout;
1648 0 : p += len;
1649 0 : n -= len;
1650 0 : if (lenndef)
1651 : {
1652 : /* Need to skip the Null Tag. */
1653 0 : if (parse_tag (&p, &n, &ti))
1654 0 : goto bailout;
1655 0 : if (!(ti.class == UNIVERSAL && !ti.tag && !ti.is_constructed))
1656 : goto bailout;
1657 : }
1658 : }
1659 :
1660 0 : gcry_free (cram_buffer);
1661 0 : return result;
1662 : bailout:
1663 0 : log_error ("error at \"%s\", offset %u\n",
1664 0 : where, (unsigned int)(p - p_start));
1665 0 : if (result)
1666 : {
1667 : int i;
1668 :
1669 0 : for (i=0; result[i]; i++)
1670 0 : gcry_mpi_release (result[i]);
1671 0 : gcry_free (result);
1672 : }
1673 0 : gcry_free (cram_buffer);
1674 0 : return NULL;
1675 : }
1676 :
1677 :
1678 :
1679 : static size_t
1680 0 : compute_tag_length (size_t n)
1681 : {
1682 0 : int needed = 0;
1683 :
1684 0 : if (n < 128)
1685 0 : needed += 2; /* tag and one length byte */
1686 0 : else if (n < 256)
1687 0 : needed += 3; /* tag, number of length bytes, 1 length byte */
1688 0 : else if (n < 65536)
1689 0 : needed += 4; /* tag, number of length bytes, 2 length bytes */
1690 : else
1691 : {
1692 0 : log_error ("object too larger to encode\n");
1693 0 : return 0;
1694 : }
1695 0 : return needed;
1696 : }
1697 :
1698 : static unsigned char *
1699 0 : store_tag_length (unsigned char *p, int tag, size_t n)
1700 : {
1701 0 : if (tag == TAG_SEQUENCE)
1702 0 : tag |= 0x20; /* constructed */
1703 :
1704 0 : *p++ = tag;
1705 0 : if (n < 128)
1706 0 : *p++ = n;
1707 0 : else if (n < 256)
1708 : {
1709 0 : *p++ = 0x81;
1710 0 : *p++ = n;
1711 : }
1712 0 : else if (n < 65536)
1713 : {
1714 0 : *p++ = 0x82;
1715 0 : *p++ = n >> 8;
1716 0 : *p++ = n;
1717 : }
1718 :
1719 0 : return p;
1720 : }
1721 :
1722 :
1723 : /* Create the final PKCS-12 object from the sequences contained in
1724 : SEQLIST. PW is the password. That array is terminated with an NULL
1725 : object. */
1726 : static unsigned char *
1727 0 : create_final (struct buffer_s *sequences, const char *pw, size_t *r_length)
1728 : {
1729 : int i;
1730 0 : size_t needed = 0;
1731 : size_t len[8], n;
1732 : unsigned char *macstart;
1733 : size_t maclen;
1734 : unsigned char *result, *p;
1735 : size_t resultlen;
1736 : char salt[8];
1737 : unsigned char keybuf[20];
1738 : gcry_md_hd_t md;
1739 : int rc;
1740 0 : int with_mac = 1;
1741 :
1742 :
1743 : /* 9 steps to create the pkcs#12 Krampf. */
1744 :
1745 : /* 8. The MAC. */
1746 : /* We add this at step 0. */
1747 :
1748 : /* 7. All the buffers. */
1749 0 : for (i=0; sequences[i].buffer; i++)
1750 0 : needed += sequences[i].length;
1751 :
1752 : /* 6. This goes into a sequences. */
1753 0 : len[6] = needed;
1754 0 : n = compute_tag_length (needed);
1755 0 : needed += n;
1756 :
1757 : /* 5. Encapsulate all in an octet string. */
1758 0 : len[5] = needed;
1759 0 : n = compute_tag_length (needed);
1760 0 : needed += n;
1761 :
1762 : /* 4. And tag it with [0]. */
1763 0 : len[4] = needed;
1764 0 : n = compute_tag_length (needed);
1765 0 : needed += n;
1766 :
1767 : /* 3. Prepend an data OID. */
1768 0 : needed += 2 + DIM (oid_data);
1769 :
1770 : /* 2. Put all into a sequences. */
1771 0 : len[2] = needed;
1772 0 : n = compute_tag_length (needed);
1773 0 : needed += n;
1774 :
1775 : /* 1. Prepend the version integer 3. */
1776 0 : needed += 3;
1777 :
1778 : /* 0. And the final outer sequence. */
1779 0 : if (with_mac)
1780 0 : needed += DIM (data_mactemplate);
1781 0 : len[0] = needed;
1782 0 : n = compute_tag_length (needed);
1783 0 : needed += n;
1784 :
1785 : /* Allocate a buffer. */
1786 0 : result = gcry_malloc (needed);
1787 0 : if (!result)
1788 : {
1789 0 : log_error ("error allocating buffer\n");
1790 0 : return NULL;
1791 : }
1792 0 : p = result;
1793 :
1794 : /* 0. Store the very outer sequence. */
1795 0 : p = store_tag_length (p, TAG_SEQUENCE, len[0]);
1796 :
1797 : /* 1. Store the version integer 3. */
1798 0 : *p++ = TAG_INTEGER;
1799 0 : *p++ = 1;
1800 0 : *p++ = 3;
1801 :
1802 : /* 2. Store another sequence. */
1803 0 : p = store_tag_length (p, TAG_SEQUENCE, len[2]);
1804 :
1805 : /* 3. Store the data OID. */
1806 0 : p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
1807 0 : memcpy (p, oid_data, DIM (oid_data));
1808 0 : p += DIM (oid_data);
1809 :
1810 : /* 4. Next comes a context tag. */
1811 0 : p = store_tag_length (p, 0xa0, len[4]);
1812 :
1813 : /* 5. And an octet string. */
1814 0 : p = store_tag_length (p, TAG_OCTET_STRING, len[5]);
1815 :
1816 : /* 6. And the inner sequence. */
1817 0 : macstart = p;
1818 0 : p = store_tag_length (p, TAG_SEQUENCE, len[6]);
1819 :
1820 : /* 7. Append all the buffers. */
1821 0 : for (i=0; sequences[i].buffer; i++)
1822 : {
1823 0 : memcpy (p, sequences[i].buffer, sequences[i].length);
1824 0 : p += sequences[i].length;
1825 : }
1826 :
1827 0 : if (with_mac)
1828 : {
1829 : /* Intermezzo to compute the MAC. */
1830 0 : maclen = p - macstart;
1831 0 : gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
1832 0 : if (string_to_key (3, salt, 8, 2048, pw, 20, keybuf))
1833 : {
1834 0 : gcry_free (result);
1835 0 : return NULL;
1836 : }
1837 0 : rc = gcry_md_open (&md, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC);
1838 0 : if (rc)
1839 : {
1840 0 : log_error ("gcry_md_open failed: %s\n", gpg_strerror (rc));
1841 0 : gcry_free (result);
1842 0 : return NULL;
1843 : }
1844 0 : rc = gcry_md_setkey (md, keybuf, 20);
1845 0 : if (rc)
1846 : {
1847 0 : log_error ("gcry_md_setkey failed: %s\n", gpg_strerror (rc));
1848 0 : gcry_md_close (md);
1849 0 : gcry_free (result);
1850 0 : return NULL;
1851 : }
1852 0 : gcry_md_write (md, macstart, maclen);
1853 :
1854 : /* 8. Append the MAC template and fix it up. */
1855 0 : memcpy (p, data_mactemplate, DIM (data_mactemplate));
1856 0 : memcpy (p + DATA_MACTEMPLATE_SALT_OFF, salt, 8);
1857 0 : memcpy (p + DATA_MACTEMPLATE_MAC_OFF, gcry_md_read (md, 0), 20);
1858 0 : p += DIM (data_mactemplate);
1859 0 : gcry_md_close (md);
1860 : }
1861 :
1862 : /* Ready. */
1863 0 : resultlen = p - result;
1864 0 : if (needed != resultlen)
1865 0 : log_debug ("length mismatch: %lu, %lu\n",
1866 : (unsigned long)needed, (unsigned long)resultlen);
1867 :
1868 0 : *r_length = resultlen;
1869 0 : return result;
1870 : }
1871 :
1872 :
1873 : /* Build a DER encoded SEQUENCE with the key:
1874 :
1875 : SEQUENCE {
1876 : INTEGER 0
1877 : SEQUENCE {
1878 : OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
1879 : NULL
1880 : }
1881 : OCTET STRING, encapsulates {
1882 : SEQUENCE {
1883 : INTEGER 0
1884 : INTEGER
1885 : INTEGER
1886 : INTEGER
1887 : INTEGER
1888 : INTEGER
1889 : INTEGER
1890 : INTEGER
1891 : INTEGER
1892 : }
1893 : }
1894 : }
1895 :
1896 : MODE controls what is being generated:
1897 : 0 - As described above
1898 : 1 - Ditto but without the padding
1899 : 2 - Only the inner part (pkcs#1)
1900 : */
1901 :
1902 : static unsigned char *
1903 0 : build_key_sequence (gcry_mpi_t *kparms, int mode, size_t *r_length)
1904 : {
1905 : int rc, i;
1906 : size_t needed, n;
1907 : unsigned char *plain, *p;
1908 : size_t plainlen;
1909 : size_t outseqlen, oidseqlen, octstrlen, inseqlen;
1910 :
1911 0 : needed = 3; /* The version integer with value 0. */
1912 0 : for (i=0; kparms[i]; i++)
1913 : {
1914 0 : n = 0;
1915 0 : rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, kparms[i]);
1916 0 : if (rc)
1917 : {
1918 0 : log_error ("error formatting parameter: %s\n", gpg_strerror (rc));
1919 0 : return NULL;
1920 : }
1921 0 : needed += n;
1922 0 : n = compute_tag_length (n);
1923 0 : if (!n)
1924 0 : return NULL;
1925 0 : needed += n;
1926 : }
1927 0 : if (i != 8)
1928 : {
1929 0 : log_error ("invalid parameters for p12_build\n");
1930 0 : return NULL;
1931 : }
1932 : /* Now this all goes into a sequence. */
1933 0 : inseqlen = needed;
1934 0 : n = compute_tag_length (needed);
1935 0 : if (!n)
1936 0 : return NULL;
1937 0 : needed += n;
1938 :
1939 0 : if (mode != 2)
1940 : {
1941 : /* Encapsulate all into an octet string. */
1942 0 : octstrlen = needed;
1943 0 : n = compute_tag_length (needed);
1944 0 : if (!n)
1945 0 : return NULL;
1946 0 : needed += n;
1947 : /* Prepend the object identifier sequence. */
1948 0 : oidseqlen = 2 + DIM (oid_rsaEncryption) + 2;
1949 0 : needed += 2 + oidseqlen;
1950 : /* The version number. */
1951 0 : needed += 3;
1952 : /* And finally put the whole thing into a sequence. */
1953 0 : outseqlen = needed;
1954 0 : n = compute_tag_length (needed);
1955 0 : if (!n)
1956 0 : return NULL;
1957 0 : needed += n;
1958 : }
1959 :
1960 : /* allocate 8 extra bytes for padding */
1961 0 : plain = gcry_malloc_secure (needed+8);
1962 0 : if (!plain)
1963 : {
1964 0 : log_error ("error allocating encryption buffer\n");
1965 0 : return NULL;
1966 : }
1967 :
1968 : /* And now fill the plaintext buffer. */
1969 0 : p = plain;
1970 0 : if (mode != 2)
1971 : {
1972 0 : p = store_tag_length (p, TAG_SEQUENCE, outseqlen);
1973 : /* Store version. */
1974 0 : *p++ = TAG_INTEGER;
1975 0 : *p++ = 1;
1976 0 : *p++ = 0;
1977 : /* Store object identifier sequence. */
1978 0 : p = store_tag_length (p, TAG_SEQUENCE, oidseqlen);
1979 0 : p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_rsaEncryption));
1980 0 : memcpy (p, oid_rsaEncryption, DIM (oid_rsaEncryption));
1981 0 : p += DIM (oid_rsaEncryption);
1982 0 : *p++ = TAG_NULL;
1983 0 : *p++ = 0;
1984 : /* Start with the octet string. */
1985 0 : p = store_tag_length (p, TAG_OCTET_STRING, octstrlen);
1986 : }
1987 :
1988 0 : p = store_tag_length (p, TAG_SEQUENCE, inseqlen);
1989 : /* Store the key parameters. */
1990 0 : *p++ = TAG_INTEGER;
1991 0 : *p++ = 1;
1992 0 : *p++ = 0;
1993 0 : for (i=0; kparms[i]; i++)
1994 : {
1995 0 : n = 0;
1996 0 : rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, kparms[i]);
1997 0 : if (rc)
1998 : {
1999 0 : log_error ("oops: error formatting parameter: %s\n",
2000 : gpg_strerror (rc));
2001 0 : gcry_free (plain);
2002 0 : return NULL;
2003 : }
2004 0 : p = store_tag_length (p, TAG_INTEGER, n);
2005 :
2006 0 : n = plain + needed - p;
2007 0 : rc = gcry_mpi_print (GCRYMPI_FMT_STD, p, n, &n, kparms[i]);
2008 0 : if (rc)
2009 : {
2010 0 : log_error ("oops: error storing parameter: %s\n",
2011 : gpg_strerror (rc));
2012 0 : gcry_free (plain);
2013 0 : return NULL;
2014 : }
2015 0 : p += n;
2016 : }
2017 :
2018 0 : plainlen = p - plain;
2019 0 : assert (needed == plainlen);
2020 :
2021 0 : if (!mode)
2022 : {
2023 : /* Append some pad characters; we already allocated extra space. */
2024 0 : n = 8 - plainlen % 8;
2025 0 : for (i=0; i < n; i++, plainlen++)
2026 0 : *p++ = n;
2027 : }
2028 :
2029 0 : *r_length = plainlen;
2030 0 : return plain;
2031 : }
2032 :
2033 :
2034 :
2035 : static unsigned char *
2036 0 : build_key_bag (unsigned char *buffer, size_t buflen, char *salt,
2037 : const unsigned char *sha1hash, const char *keyidstr,
2038 : size_t *r_length)
2039 : {
2040 : size_t len[11], needed;
2041 : unsigned char *p, *keybag;
2042 : size_t keybaglen;
2043 :
2044 : /* Walk 11 steps down to collect the info: */
2045 :
2046 : /* 10. The data goes into an octet string. */
2047 0 : needed = compute_tag_length (buflen);
2048 0 : needed += buflen;
2049 :
2050 : /* 9. Prepend the algorithm identifier. */
2051 0 : needed += DIM (data_3desiter2048);
2052 :
2053 : /* 8. Put a sequence around. */
2054 0 : len[8] = needed;
2055 0 : needed += compute_tag_length (needed);
2056 :
2057 : /* 7. Prepend a [0] tag. */
2058 0 : len[7] = needed;
2059 0 : needed += compute_tag_length (needed);
2060 :
2061 : /* 6b. The attributes which are appended at the end. */
2062 0 : if (sha1hash)
2063 0 : needed += DIM (data_attrtemplate) + 20;
2064 :
2065 : /* 6. Prepend the shroudedKeyBag OID. */
2066 0 : needed += 2 + DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag);
2067 :
2068 : /* 5+4. Put all into two sequences. */
2069 0 : len[5] = needed;
2070 0 : needed += compute_tag_length ( needed);
2071 0 : len[4] = needed;
2072 0 : needed += compute_tag_length (needed);
2073 :
2074 : /* 3. This all goes into an octet string. */
2075 0 : len[3] = needed;
2076 0 : needed += compute_tag_length (needed);
2077 :
2078 : /* 2. Prepend another [0] tag. */
2079 0 : len[2] = needed;
2080 0 : needed += compute_tag_length (needed);
2081 :
2082 : /* 1. Prepend the data OID. */
2083 0 : needed += 2 + DIM (oid_data);
2084 :
2085 : /* 0. Prepend another sequence. */
2086 0 : len[0] = needed;
2087 0 : needed += compute_tag_length (needed);
2088 :
2089 : /* Now that we have all length information, allocate a buffer. */
2090 0 : p = keybag = gcry_malloc (needed);
2091 0 : if (!keybag)
2092 : {
2093 0 : log_error ("error allocating buffer\n");
2094 0 : return NULL;
2095 : }
2096 :
2097 : /* Walk 11 steps up to store the data. */
2098 :
2099 : /* 0. Store the first sequence. */
2100 0 : p = store_tag_length (p, TAG_SEQUENCE, len[0]);
2101 :
2102 : /* 1. Store the data OID. */
2103 0 : p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
2104 0 : memcpy (p, oid_data, DIM (oid_data));
2105 0 : p += DIM (oid_data);
2106 :
2107 : /* 2. Store a [0] tag. */
2108 0 : p = store_tag_length (p, 0xa0, len[2]);
2109 :
2110 : /* 3. And an octet string. */
2111 0 : p = store_tag_length (p, TAG_OCTET_STRING, len[3]);
2112 :
2113 : /* 4+5. Two sequences. */
2114 0 : p = store_tag_length (p, TAG_SEQUENCE, len[4]);
2115 0 : p = store_tag_length (p, TAG_SEQUENCE, len[5]);
2116 :
2117 : /* 6. Store the shroudedKeyBag OID. */
2118 0 : p = store_tag_length (p, TAG_OBJECT_ID,
2119 : DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag));
2120 0 : memcpy (p, oid_pkcs_12_pkcs_8ShroudedKeyBag,
2121 : DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag));
2122 0 : p += DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag);
2123 :
2124 : /* 7. Store a [0] tag. */
2125 0 : p = store_tag_length (p, 0xa0, len[7]);
2126 :
2127 : /* 8. Store a sequence. */
2128 0 : p = store_tag_length (p, TAG_SEQUENCE, len[8]);
2129 :
2130 : /* 9. Now for the pre-encoded algorithm identifier and the salt. */
2131 0 : memcpy (p, data_3desiter2048, DIM (data_3desiter2048));
2132 0 : memcpy (p + DATA_3DESITER2048_SALT_OFF, salt, 8);
2133 0 : p += DIM (data_3desiter2048);
2134 :
2135 : /* 10. And the octet string with the encrypted data. */
2136 0 : p = store_tag_length (p, TAG_OCTET_STRING, buflen);
2137 0 : memcpy (p, buffer, buflen);
2138 0 : p += buflen;
2139 :
2140 : /* Append the attributes whose length we calculated at step 2b. */
2141 0 : if (sha1hash)
2142 : {
2143 : int i;
2144 :
2145 0 : memcpy (p, data_attrtemplate, DIM (data_attrtemplate));
2146 0 : for (i=0; i < 8; i++)
2147 0 : p[DATA_ATTRTEMPLATE_KEYID_OFF+2*i+1] = keyidstr[i];
2148 0 : p += DIM (data_attrtemplate);
2149 0 : memcpy (p, sha1hash, 20);
2150 0 : p += 20;
2151 : }
2152 :
2153 :
2154 0 : keybaglen = p - keybag;
2155 0 : if (needed != keybaglen)
2156 0 : log_debug ("length mismatch: %lu, %lu\n",
2157 : (unsigned long)needed, (unsigned long)keybaglen);
2158 :
2159 0 : *r_length = keybaglen;
2160 0 : return keybag;
2161 : }
2162 :
2163 :
2164 : static unsigned char *
2165 0 : build_cert_bag (unsigned char *buffer, size_t buflen, char *salt,
2166 : size_t *r_length)
2167 : {
2168 : size_t len[9], needed;
2169 : unsigned char *p, *certbag;
2170 : size_t certbaglen;
2171 :
2172 : /* Walk 9 steps down to collect the info: */
2173 :
2174 : /* 8. The data goes into an octet string. */
2175 0 : needed = compute_tag_length (buflen);
2176 0 : needed += buflen;
2177 :
2178 : /* 7. The algorithm identifier. */
2179 0 : needed += DIM (data_rc2iter2048);
2180 :
2181 : /* 6. The data OID. */
2182 0 : needed += 2 + DIM (oid_data);
2183 :
2184 : /* 5. A sequence. */
2185 0 : len[5] = needed;
2186 0 : needed += compute_tag_length ( needed);
2187 :
2188 : /* 4. An integer. */
2189 0 : needed += 3;
2190 :
2191 : /* 3. A sequence. */
2192 0 : len[3] = needed;
2193 0 : needed += compute_tag_length (needed);
2194 :
2195 : /* 2. A [0] tag. */
2196 0 : len[2] = needed;
2197 0 : needed += compute_tag_length (needed);
2198 :
2199 : /* 1. The encryptedData OID. */
2200 0 : needed += 2 + DIM (oid_encryptedData);
2201 :
2202 : /* 0. The first sequence. */
2203 0 : len[0] = needed;
2204 0 : needed += compute_tag_length (needed);
2205 :
2206 : /* Now that we have all length information, allocate a buffer. */
2207 0 : p = certbag = gcry_malloc (needed);
2208 0 : if (!certbag)
2209 : {
2210 0 : log_error ("error allocating buffer\n");
2211 0 : return NULL;
2212 : }
2213 :
2214 : /* Walk 9 steps up to store the data. */
2215 :
2216 : /* 0. Store the first sequence. */
2217 0 : p = store_tag_length (p, TAG_SEQUENCE, len[0]);
2218 :
2219 : /* 1. Store the encryptedData OID. */
2220 0 : p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_encryptedData));
2221 0 : memcpy (p, oid_encryptedData, DIM (oid_encryptedData));
2222 0 : p += DIM (oid_encryptedData);
2223 :
2224 : /* 2. Store a [0] tag. */
2225 0 : p = store_tag_length (p, 0xa0, len[2]);
2226 :
2227 : /* 3. Store a sequence. */
2228 0 : p = store_tag_length (p, TAG_SEQUENCE, len[3]);
2229 :
2230 : /* 4. Store the integer 0. */
2231 0 : *p++ = TAG_INTEGER;
2232 0 : *p++ = 1;
2233 0 : *p++ = 0;
2234 :
2235 : /* 5. Store a sequence. */
2236 0 : p = store_tag_length (p, TAG_SEQUENCE, len[5]);
2237 :
2238 : /* 6. Store the data OID. */
2239 0 : p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data));
2240 0 : memcpy (p, oid_data, DIM (oid_data));
2241 0 : p += DIM (oid_data);
2242 :
2243 : /* 7. Now for the pre-encoded algorithm identifier and the salt. */
2244 0 : memcpy (p, data_rc2iter2048, DIM (data_rc2iter2048));
2245 0 : memcpy (p + DATA_RC2ITER2048_SALT_OFF, salt, 8);
2246 0 : p += DIM (data_rc2iter2048);
2247 :
2248 : /* 8. And finally the [0] tag with the encrypted data. */
2249 0 : p = store_tag_length (p, 0x80, buflen);
2250 0 : memcpy (p, buffer, buflen);
2251 0 : p += buflen;
2252 0 : certbaglen = p - certbag;
2253 :
2254 0 : if (needed != certbaglen)
2255 0 : log_debug ("length mismatch: %lu, %lu\n",
2256 : (unsigned long)needed, (unsigned long)certbaglen);
2257 :
2258 0 : *r_length = certbaglen;
2259 0 : return certbag;
2260 : }
2261 :
2262 :
2263 : static unsigned char *
2264 0 : build_cert_sequence (const unsigned char *buffer, size_t buflen,
2265 : const unsigned char *sha1hash, const char *keyidstr,
2266 : size_t *r_length)
2267 : {
2268 : size_t len[8], needed, n;
2269 : unsigned char *p, *certseq;
2270 : size_t certseqlen;
2271 : int i;
2272 :
2273 0 : assert (strlen (keyidstr) == 8);
2274 :
2275 : /* Walk 8 steps down to collect the info: */
2276 :
2277 : /* 7. The data goes into an octet string. */
2278 0 : needed = compute_tag_length (buflen);
2279 0 : needed += buflen;
2280 :
2281 : /* 6. A [0] tag. */
2282 0 : len[6] = needed;
2283 0 : needed += compute_tag_length (needed);
2284 :
2285 : /* 5. An OID. */
2286 0 : needed += 2 + DIM (oid_x509Certificate_for_pkcs_12);
2287 :
2288 : /* 4. A sequence. */
2289 0 : len[4] = needed;
2290 0 : needed += compute_tag_length (needed);
2291 :
2292 : /* 3. A [0] tag. */
2293 0 : len[3] = needed;
2294 0 : needed += compute_tag_length (needed);
2295 :
2296 : /* 2b. The attributes which are appended at the end. */
2297 0 : if (sha1hash)
2298 0 : needed += DIM (data_attrtemplate) + 20;
2299 :
2300 : /* 2. An OID. */
2301 0 : needed += 2 + DIM (oid_pkcs_12_CertBag);
2302 :
2303 : /* 1. A sequence. */
2304 0 : len[1] = needed;
2305 0 : needed += compute_tag_length (needed);
2306 :
2307 : /* 0. The first sequence. */
2308 0 : len[0] = needed;
2309 0 : needed += compute_tag_length (needed);
2310 :
2311 : /* Now that we have all length information, allocate a buffer. */
2312 0 : p = certseq = gcry_malloc (needed + 8 /*(for padding)*/);
2313 0 : if (!certseq)
2314 : {
2315 0 : log_error ("error allocating buffer\n");
2316 0 : return NULL;
2317 : }
2318 :
2319 : /* Walk 8 steps up to store the data. */
2320 :
2321 : /* 0. Store the first sequence. */
2322 0 : p = store_tag_length (p, TAG_SEQUENCE, len[0]);
2323 :
2324 : /* 1. Store the second sequence. */
2325 0 : p = store_tag_length (p, TAG_SEQUENCE, len[1]);
2326 :
2327 : /* 2. Store the pkcs12-cert-bag OID. */
2328 0 : p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_pkcs_12_CertBag));
2329 0 : memcpy (p, oid_pkcs_12_CertBag, DIM (oid_pkcs_12_CertBag));
2330 0 : p += DIM (oid_pkcs_12_CertBag);
2331 :
2332 : /* 3. Store a [0] tag. */
2333 0 : p = store_tag_length (p, 0xa0, len[3]);
2334 :
2335 : /* 4. Store a sequence. */
2336 0 : p = store_tag_length (p, TAG_SEQUENCE, len[4]);
2337 :
2338 : /* 5. Store the x509Certificate OID. */
2339 0 : p = store_tag_length (p, TAG_OBJECT_ID,
2340 : DIM (oid_x509Certificate_for_pkcs_12));
2341 0 : memcpy (p, oid_x509Certificate_for_pkcs_12,
2342 : DIM (oid_x509Certificate_for_pkcs_12));
2343 0 : p += DIM (oid_x509Certificate_for_pkcs_12);
2344 :
2345 : /* 6. Store a [0] tag. */
2346 0 : p = store_tag_length (p, 0xa0, len[6]);
2347 :
2348 : /* 7. And the octet string with the actual certificate. */
2349 0 : p = store_tag_length (p, TAG_OCTET_STRING, buflen);
2350 0 : memcpy (p, buffer, buflen);
2351 0 : p += buflen;
2352 :
2353 : /* Append the attributes whose length we calculated at step 2b. */
2354 0 : if (sha1hash)
2355 : {
2356 0 : memcpy (p, data_attrtemplate, DIM (data_attrtemplate));
2357 0 : for (i=0; i < 8; i++)
2358 0 : p[DATA_ATTRTEMPLATE_KEYID_OFF+2*i+1] = keyidstr[i];
2359 0 : p += DIM (data_attrtemplate);
2360 0 : memcpy (p, sha1hash, 20);
2361 0 : p += 20;
2362 : }
2363 :
2364 0 : certseqlen = p - certseq;
2365 0 : if (needed != certseqlen)
2366 0 : log_debug ("length mismatch: %lu, %lu\n",
2367 : (unsigned long)needed, (unsigned long)certseqlen);
2368 :
2369 : /* Append some pad characters; we already allocated extra space. */
2370 0 : n = 8 - certseqlen % 8;
2371 0 : for (i=0; i < n; i++, certseqlen++)
2372 0 : *p++ = n;
2373 :
2374 0 : *r_length = certseqlen;
2375 0 : return certseq;
2376 : }
2377 :
2378 :
2379 : /* Expect the RSA key parameters in KPARMS and a password in PW.
2380 : Create a PKCS structure from it and return it as well as the length
2381 : in R_LENGTH; return NULL in case of an error. If CHARSET is not
2382 : NULL, re-encode PW to that character set. */
2383 : unsigned char *
2384 0 : p12_build (gcry_mpi_t *kparms, const void *cert, size_t certlen,
2385 : const char *pw, const char *charset, size_t *r_length)
2386 : {
2387 0 : unsigned char *buffer = NULL;
2388 : size_t n, buflen;
2389 : char salt[8];
2390 : struct buffer_s seqlist[3];
2391 0 : int seqlistidx = 0;
2392 : unsigned char sha1hash[20];
2393 : char keyidstr[8+1];
2394 0 : char *pwbuf = NULL;
2395 0 : size_t pwbufsize = 0;
2396 :
2397 0 : n = buflen = 0; /* (avoid compiler warning). */
2398 0 : memset (sha1hash, 0, 20);
2399 0 : *keyidstr = 0;
2400 :
2401 0 : if (charset && pw && *pw)
2402 : {
2403 : jnlib_iconv_t cd;
2404 : const char *inptr;
2405 : char *outptr;
2406 : size_t inbytes, outbytes;
2407 :
2408 : /* We assume that the converted passphrase is at max 2 times
2409 : longer than its utf-8 encoding. */
2410 0 : pwbufsize = strlen (pw)*2 + 1;
2411 0 : pwbuf = gcry_malloc_secure (pwbufsize);
2412 0 : if (!pwbuf)
2413 : {
2414 0 : log_error ("out of secure memory while converting passphrase\n");
2415 0 : goto failure;
2416 : }
2417 :
2418 0 : cd = jnlib_iconv_open (charset, "utf-8");
2419 0 : if (cd == (jnlib_iconv_t)(-1))
2420 : {
2421 0 : log_error ("can't convert passphrase to"
2422 : " requested charset '%s': %s\n",
2423 0 : charset, strerror (errno));
2424 0 : goto failure;
2425 : }
2426 :
2427 0 : inptr = pw;
2428 0 : inbytes = strlen (pw);
2429 0 : outptr = pwbuf;
2430 0 : outbytes = pwbufsize - 1;
2431 0 : if ( jnlib_iconv (cd, (const char **)&inptr, &inbytes,
2432 : &outptr, &outbytes) == (size_t)-1)
2433 : {
2434 0 : log_error ("error converting passphrase to"
2435 : " requested charset '%s': %s\n",
2436 0 : charset, strerror (errno));
2437 0 : jnlib_iconv_close (cd);
2438 0 : goto failure;
2439 : }
2440 0 : *outptr = 0;
2441 0 : jnlib_iconv_close (cd);
2442 0 : pw = pwbuf;
2443 : }
2444 :
2445 :
2446 0 : if (cert && certlen)
2447 : {
2448 : /* Calculate the hash value we need for the bag attributes. */
2449 0 : gcry_md_hash_buffer (GCRY_MD_SHA1, sha1hash, cert, certlen);
2450 0 : sprintf (keyidstr, "%02x%02x%02x%02x",
2451 0 : sha1hash[16], sha1hash[17], sha1hash[18], sha1hash[19]);
2452 :
2453 : /* Encode the certificate. */
2454 0 : buffer = build_cert_sequence (cert, certlen, sha1hash, keyidstr,
2455 : &buflen);
2456 0 : if (!buffer)
2457 0 : goto failure;
2458 :
2459 : /* Encrypt it. */
2460 0 : gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
2461 0 : crypt_block (buffer, buflen, salt, 8, 2048, NULL, 0, pw,
2462 : GCRY_CIPHER_RFC2268_40, 1);
2463 :
2464 : /* Encode the encrypted stuff into a bag. */
2465 0 : seqlist[seqlistidx].buffer = build_cert_bag (buffer, buflen, salt, &n);
2466 0 : seqlist[seqlistidx].length = n;
2467 0 : gcry_free (buffer);
2468 0 : buffer = NULL;
2469 0 : if (!seqlist[seqlistidx].buffer)
2470 0 : goto failure;
2471 0 : seqlistidx++;
2472 : }
2473 :
2474 :
2475 0 : if (kparms)
2476 : {
2477 : /* Encode the key. */
2478 0 : buffer = build_key_sequence (kparms, 0, &buflen);
2479 0 : if (!buffer)
2480 0 : goto failure;
2481 :
2482 : /* Encrypt it. */
2483 0 : gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
2484 0 : crypt_block (buffer, buflen, salt, 8, 2048, NULL, 0,
2485 : pw, GCRY_CIPHER_3DES, 1);
2486 :
2487 : /* Encode the encrypted stuff into a bag. */
2488 0 : if (cert && certlen)
2489 0 : seqlist[seqlistidx].buffer = build_key_bag (buffer, buflen, salt,
2490 : sha1hash, keyidstr, &n);
2491 : else
2492 0 : seqlist[seqlistidx].buffer = build_key_bag (buffer, buflen, salt,
2493 : NULL, NULL, &n);
2494 0 : seqlist[seqlistidx].length = n;
2495 0 : gcry_free (buffer);
2496 0 : buffer = NULL;
2497 0 : if (!seqlist[seqlistidx].buffer)
2498 0 : goto failure;
2499 0 : seqlistidx++;
2500 : }
2501 :
2502 0 : seqlist[seqlistidx].buffer = NULL;
2503 0 : seqlist[seqlistidx].length = 0;
2504 :
2505 0 : buffer = create_final (seqlist, pw, &buflen);
2506 :
2507 : failure:
2508 0 : if (pwbuf)
2509 : {
2510 : /* Note that wipememory is not really needed due to the use of
2511 : gcry_malloc_secure. */
2512 0 : wipememory (pwbuf, pwbufsize);
2513 0 : gcry_free (pwbuf);
2514 : }
2515 0 : for ( ; seqlistidx; seqlistidx--)
2516 0 : gcry_free (seqlist[seqlistidx].buffer);
2517 :
2518 0 : *r_length = buffer? buflen : 0;
2519 0 : return buffer;
2520 : }
2521 :
2522 :
2523 : /* This is actually not a pkcs#12 function but one which creates an
2524 : unencrypted a pkcs#1 private key. */
2525 : unsigned char *
2526 0 : p12_raw_build (gcry_mpi_t *kparms, int rawmode, size_t *r_length)
2527 : {
2528 : unsigned char *buffer;
2529 : size_t buflen;
2530 :
2531 0 : assert (rawmode == 1 || rawmode == 2);
2532 0 : buffer = build_key_sequence (kparms, rawmode, &buflen);
2533 0 : if (!buffer)
2534 0 : return NULL;
2535 :
2536 0 : *r_length = buflen;
2537 0 : return buffer;
2538 : }
2539 :
2540 :
2541 : #ifdef TEST
2542 :
2543 : static void
2544 : cert_cb (void *opaque, const unsigned char *cert, size_t certlen)
2545 : {
2546 : printf ("got a certificate of %u bytes length\n", certlen);
2547 : }
2548 :
2549 : int
2550 : main (int argc, char **argv)
2551 : {
2552 : FILE *fp;
2553 : struct stat st;
2554 : unsigned char *buf;
2555 : size_t buflen;
2556 : gcry_mpi_t *result;
2557 : int badpass;
2558 :
2559 : if (argc != 3)
2560 : {
2561 : fprintf (stderr, "usage: testp12 file passphrase\n");
2562 : return 1;
2563 : }
2564 :
2565 : gcry_control (GCRYCTL_DISABLE_SECMEM, NULL);
2566 : gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL);
2567 :
2568 : fp = fopen (argv[1], "rb");
2569 : if (!fp)
2570 : {
2571 : fprintf (stderr, "can't open '%s': %s\n", argv[1], strerror (errno));
2572 : return 1;
2573 : }
2574 :
2575 : if (fstat (fileno(fp), &st))
2576 : {
2577 : fprintf (stderr, "can't stat '%s': %s\n", argv[1], strerror (errno));
2578 : return 1;
2579 : }
2580 :
2581 : buflen = st.st_size;
2582 : buf = gcry_malloc (buflen+1);
2583 : if (!buf || fread (buf, buflen, 1, fp) != 1)
2584 : {
2585 : fprintf (stderr, "error reading '%s': %s\n", argv[1], strerror (errno));
2586 : return 1;
2587 : }
2588 : fclose (fp);
2589 :
2590 : result = p12_parse (buf, buflen, argv[2], cert_cb, NULL, &badpass);
2591 : if (result)
2592 : {
2593 : int i, rc;
2594 : unsigned char *tmpbuf;
2595 :
2596 : for (i=0; result[i]; i++)
2597 : {
2598 : rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &tmpbuf,
2599 : NULL, result[i]);
2600 : if (rc)
2601 : printf ("%d: [error printing number: %s]\n",
2602 : i, gpg_strerror (rc));
2603 : else
2604 : {
2605 : printf ("%d: %s\n", i, tmpbuf);
2606 : gcry_free (tmpbuf);
2607 : }
2608 : }
2609 : }
2610 :
2611 : return 0;
2612 :
2613 : }
2614 :
2615 : /*
2616 : Local Variables:
2617 : compile-command: "gcc -Wall -O0 -g -DTEST=1 -o minip12 minip12.c ../common/libcommon.a -L /usr/local/lib -lgcrypt -lgpg-error"
2618 : End:
2619 : */
2620 : #endif /* TEST */
|