aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/https/x509/privkey_pkcs8.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/https/x509/privkey_pkcs8.c')
-rw-r--r--src/daemon/https/x509/privkey_pkcs8.c984
1 files changed, 0 insertions, 984 deletions
diff --git a/src/daemon/https/x509/privkey_pkcs8.c b/src/daemon/https/x509/privkey_pkcs8.c
deleted file mode 100644
index 30f2caae..00000000
--- a/src/daemon/https/x509/privkey_pkcs8.c
+++ /dev/null
@@ -1,984 +0,0 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26
27#ifdef ENABLE_PKI
28
29#include <gnutls_datum.h>
30#include <gnutls_global.h>
31#include <gnutls_errors.h>
32#include <gnutls_rsa_export.h>
33#include <common.h>
34#include <gnutls_x509.h>
35#include <x509_b64.h>
36#include <x509.h>
37#include <pkcs12.h>
38#include <dn.h>
39#include <privkey.h>
40#include <extensions.h>
41#include <mpi.h>
42#include <gnutls_algorithms.h>
43#include <gnutls_num.h>
44#include "gc.h"
45
46#define PBES2_OID "1.2.840.113549.1.5.13"
47#define PBKDF2_OID "1.2.840.113549.1.5.12"
48#define DES_EDE3_CBC_OID "1.2.840.113549.3.7"
49#define DES_CBC_OID "1.3.14.3.2.7"
50
51/* oid_pbeWithSHAAnd3_KeyTripleDES_CBC */
52#define PKCS12_PBE_3DES_SHA1_OID "1.2.840.113549.1.12.1.3"
53#define PKCS12_PBE_ARCFOUR_SHA1_OID "1.2.840.113549.1.12.1.1"
54#define PKCS12_PBE_RC2_40_SHA1_OID "1.2.840.113549.1.12.1.6"
55
56struct pbkdf2_params
57{
58 opaque salt[32];
59 int salt_size;
60 unsigned int iter_count;
61 unsigned int key_size;
62};
63
64struct pbe_enc_params
65{
66 enum MHD_GNUTLS_CipherAlgorithm cipher;
67 opaque iv[8];
68 int iv_size;
69};
70
71static int read_pbkdf2_params (ASN1_TYPE pbes2_asn,
72 const MHD_gnutls_datum_t * der,
73 struct pbkdf2_params *params);
74static int read_pbe_enc_params (ASN1_TYPE pbes2_asn,
75 const MHD_gnutls_datum_t * der,
76 struct pbe_enc_params *params);
77static int decrypt_data (schema_id, ASN1_TYPE pkcs8_asn, const char *root,
78 const char *password,
79 const struct pbkdf2_params *kdf_params,
80 const struct pbe_enc_params *enc_params,
81 MHD_gnutls_datum_t * decrypted_data);
82static int decode_private_key_info (const MHD_gnutls_datum_t * der,
83 MHD_gnutls_x509_privkey_t pkey);
84static int readMHD_pkcs12_kdf_params (ASN1_TYPE pbes2_asn,
85 struct pbkdf2_params *params);
86
87#define PEM_PKCS8 "ENCRYPTED PRIVATE KEY"
88#define PEM_UNENCRYPTED_PKCS8 "PRIVATE KEY"
89
90/* Returns a negative error code if the encryption schema in
91 * the OID is not supported. The schema ID is returned.
92 */
93static int
94check_schema (const char *oid)
95{
96
97 if (strcmp (oid, PBES2_OID) == 0)
98 return PBES2;
99
100 if (strcmp (oid, PKCS12_PBE_3DES_SHA1_OID) == 0)
101 return PKCS12_3DES_SHA1;
102
103 if (strcmp (oid, PKCS12_PBE_ARCFOUR_SHA1_OID) == 0)
104 return PKCS12_ARCFOUR_SHA1;
105
106 if (strcmp (oid, PKCS12_PBE_RC2_40_SHA1_OID) == 0)
107 return PKCS12_RC2_40_SHA1;
108
109 MHD__gnutls_x509_log ("PKCS encryption schema OID '%s' is unsupported.\n",
110 oid);
111
112 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
113}
114
115/* Read the parameters cipher, IV, salt etc using the given
116 * schema ID.
117 */
118static int
119read_pkcs_schema_params (schema_id schema, const char *password,
120 const opaque * data, int data_size,
121 struct pbkdf2_params *kdf_params,
122 struct pbe_enc_params *enc_params)
123{
124 ASN1_TYPE pbes2_asn = ASN1_TYPE_EMPTY;
125 int result;
126 MHD_gnutls_datum_t tmp;
127
128 switch (schema)
129 {
130
131 case PBES2:
132
133 /* Now check the key derivation and the encryption
134 * functions.
135 */
136 if ((result =
137 MHD__asn1_create_element (MHD__gnutls_get_pkix (),
138 "PKIX1.pkcs-5-PBES2-params",
139 &pbes2_asn)) != ASN1_SUCCESS)
140 {
141 MHD_gnutls_assert ();
142 result = MHD_gtls_asn2err (result);
143 goto error;
144 }
145
146 /* Decode the parameters.
147 */
148 result = MHD__asn1_der_decoding (&pbes2_asn, data, data_size, NULL);
149 if (result != ASN1_SUCCESS)
150 {
151 MHD_gnutls_assert ();
152 result = MHD_gtls_asn2err (result);
153 goto error;
154 }
155
156 tmp.data = (opaque *) data;
157 tmp.size = data_size;
158
159 result = read_pbkdf2_params (pbes2_asn, &tmp, kdf_params);
160 if (result < 0)
161 {
162 MHD_gnutls_assert ();
163 result = MHD_gtls_asn2err (result);
164 goto error;
165 }
166
167 result = read_pbe_enc_params (pbes2_asn, &tmp, enc_params);
168 if (result < 0)
169 {
170 MHD_gnutls_assert ();
171 result = MHD_gtls_asn2err (result);
172 goto error;
173 }
174
175 MHD__asn1_delete_structure (&pbes2_asn);
176 return 0;
177 break;
178
179 case PKCS12_3DES_SHA1:
180 case PKCS12_ARCFOUR_SHA1:
181 case PKCS12_RC2_40_SHA1:
182
183 if ((schema) == PKCS12_3DES_SHA1)
184 {
185 enc_params->cipher = MHD_GNUTLS_CIPHER_3DES_CBC;
186 enc_params->iv_size = 8;
187 }
188 else if ((schema) == PKCS12_ARCFOUR_SHA1)
189 {
190 enc_params->cipher = MHD_GNUTLS_CIPHER_ARCFOUR_128;
191 enc_params->iv_size = 0;
192 }
193 else if ((schema) == PKCS12_RC2_40_SHA1)
194 {
195 enc_params->cipher = MHD_GNUTLS_CIPHER_RC2_40_CBC;
196 enc_params->iv_size = 8;
197 }
198
199 if ((result =
200 MHD__asn1_create_element (MHD__gnutls_get_pkix (),
201 "PKIX1.pkcs-12-PbeParams",
202 &pbes2_asn)) != ASN1_SUCCESS)
203 {
204 MHD_gnutls_assert ();
205 result = MHD_gtls_asn2err (result);
206 goto error;
207 }
208
209 /* Decode the parameters.
210 */
211 result = MHD__asn1_der_decoding (&pbes2_asn, data, data_size, NULL);
212 if (result != ASN1_SUCCESS)
213 {
214 MHD_gnutls_assert ();
215 result = MHD_gtls_asn2err (result);
216 goto error;
217 }
218
219 result = readMHD_pkcs12_kdf_params (pbes2_asn, kdf_params);
220 if (result < 0)
221 {
222 MHD_gnutls_assert ();
223 goto error;
224 }
225
226 if (enc_params->iv_size)
227 {
228 result =
229 MHD_pkcs12_string_to_key (2 /*IV*/, kdf_params->salt,
230 kdf_params->salt_size,
231 kdf_params->iter_count, password,
232 enc_params->iv_size, enc_params->iv);
233 if (result < 0)
234 {
235 MHD_gnutls_assert ();
236 goto error;
237 }
238
239 }
240
241 MHD__asn1_delete_structure (&pbes2_asn);
242
243 return 0;
244 break;
245
246 } /* switch */
247
248 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
249
250error:
251 MHD__asn1_delete_structure (&pbes2_asn);
252 return result;
253}
254
255/* Converts a PKCS #8 key to
256 * an internal structure (MHD_gnutls_private_key)
257 * (normally a PKCS #1 encoded RSA key)
258 */
259static int
260decode_pkcs8_key (const MHD_gnutls_datum_t * raw_key,
261 const char *password, MHD_gnutls_x509_privkey_t pkey)
262{
263 int result, len;
264 char enc_oid[64];
265 MHD_gnutls_datum_t tmp;
266 ASN1_TYPE pbes2_asn = ASN1_TYPE_EMPTY, pkcs8_asn = ASN1_TYPE_EMPTY;
267 int params_start, params_end, params_len;
268 struct pbkdf2_params kdf_params;
269 struct pbe_enc_params enc_params;
270 schema_id schema;
271
272 if ((result =
273 MHD__asn1_create_element (MHD__gnutls_get_pkix (),
274 "PKIX1.pkcs-8-EncryptedPrivateKeyInfo",
275 &pkcs8_asn)) != ASN1_SUCCESS)
276 {
277 MHD_gnutls_assert ();
278 result = MHD_gtls_asn2err (result);
279 goto error;
280 }
281
282 result =
283 MHD__asn1_der_decoding (&pkcs8_asn, raw_key->data, raw_key->size, NULL);
284 if (result != ASN1_SUCCESS)
285 {
286 MHD_gnutls_assert ();
287 result = MHD_gtls_asn2err (result);
288 goto error;
289 }
290
291 /* Check the encryption schema OID
292 */
293 len = sizeof (enc_oid);
294 result =
295 MHD__asn1_read_value (pkcs8_asn, "encryptionAlgorithm.algorithm",
296 enc_oid, &len);
297 if (result != ASN1_SUCCESS)
298 {
299 MHD_gnutls_assert ();
300 goto error;
301 }
302
303 if ((result = check_schema (enc_oid)) < 0)
304 {
305 MHD_gnutls_assert ();
306 goto error;
307 }
308
309 schema = result;
310
311 /* Get the DER encoding of the parameters.
312 */
313 result =
314 MHD__asn1_der_decoding_startEnd (pkcs8_asn, raw_key->data,
315 raw_key->size,
316 "encryptionAlgorithm.parameters",
317 &params_start, &params_end);
318 if (result != ASN1_SUCCESS)
319 {
320 MHD_gnutls_assert ();
321 result = MHD_gtls_asn2err (result);
322 goto error;
323 }
324 params_len = params_end - params_start + 1;
325
326 result =
327 read_pkcs_schema_params (schema, password,
328 &raw_key->data[params_start],
329 params_len, &kdf_params, &enc_params);
330
331 /* Parameters have been decoded. Now
332 * decrypt the EncryptedData.
333 */
334 result =
335 decrypt_data (schema, pkcs8_asn, "encryptedData", password,
336 &kdf_params, &enc_params, &tmp);
337 if (result < 0)
338 {
339 MHD_gnutls_assert ();
340 goto error;
341 }
342
343 MHD__asn1_delete_structure (&pkcs8_asn);
344
345 result = decode_private_key_info (&tmp, pkey);
346 MHD__gnutls_free_datum (&tmp);
347
348 if (result < 0)
349 {
350 /* We've gotten this far. In the real world it's almost certain
351 * that we're dealing with a good file, but wrong password.
352 * Sadly like 90% of random data is somehow valid DER for the
353 * a first small number of bytes, so no easy way to guarantee. */
354 if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND ||
355 result == GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND ||
356 result == GNUTLS_E_ASN1_DER_ERROR ||
357 result == GNUTLS_E_ASN1_VALUE_NOT_FOUND ||
358 result == GNUTLS_E_ASN1_GENERIC_ERROR ||
359 result == GNUTLS_E_ASN1_VALUE_NOT_VALID ||
360 result == GNUTLS_E_ASN1_TAG_ERROR ||
361 result == GNUTLS_E_ASN1_TAG_IMPLICIT ||
362 result == GNUTLS_E_ASN1_TYPE_ANY_ERROR ||
363 result == GNUTLS_E_ASN1_SYNTAX_ERROR ||
364 result == GNUTLS_E_ASN1_DER_OVERFLOW)
365 {
366 result = GNUTLS_E_DECRYPTION_FAILED;
367 }
368
369 MHD_gnutls_assert ();
370 goto error;
371 }
372
373 return 0;
374
375error:
376 MHD__asn1_delete_structure (&pbes2_asn);
377 MHD__asn1_delete_structure (&pkcs8_asn);
378 return result;
379}
380
381/* Decodes an RSA privateKey from a PKCS8 structure.
382 */
383static int
384_decode_pkcs8_rsa_key (ASN1_TYPE pkcs8_asn, MHD_gnutls_x509_privkey_t pkey)
385{
386 int ret;
387 MHD_gnutls_datum_t tmp;
388
389 ret = MHD__gnutls_x509_read_value (pkcs8_asn, "privateKey", &tmp, 0);
390 if (ret < 0)
391 {
392 MHD_gnutls_assert ();
393 goto error;
394 }
395
396 pkey->key = MHD__gnutls_privkey_decode_pkcs1_rsa_key (&tmp, pkey);
397 MHD__gnutls_free_datum (&tmp);
398 if (pkey->key == NULL)
399 {
400 MHD_gnutls_assert ();
401 goto error;
402 }
403
404 return 0;
405
406error:
407 MHD_gnutls_x509_privkey_deinit (pkey);
408 return ret;
409}
410
411static int
412decode_private_key_info (const MHD_gnutls_datum_t * der,
413 MHD_gnutls_x509_privkey_t pkey)
414{
415 int result, len;
416 opaque oid[64];
417 ASN1_TYPE pkcs8_asn = ASN1_TYPE_EMPTY;
418
419 if ((result =
420 MHD__asn1_create_element (MHD__gnutls_get_pkix (),
421 "PKIX1.pkcs-8-PrivateKeyInfo",
422 &pkcs8_asn)) != ASN1_SUCCESS)
423 {
424 MHD_gnutls_assert ();
425 result = MHD_gtls_asn2err (result);
426 goto error;
427 }
428
429 result = MHD__asn1_der_decoding (&pkcs8_asn, der->data, der->size, NULL);
430 if (result != ASN1_SUCCESS)
431 {
432 MHD_gnutls_assert ();
433 result = MHD_gtls_asn2err (result);
434 goto error;
435 }
436
437 /* Check the private key algorithm OID
438 */
439 len = sizeof (oid);
440 result =
441 MHD__asn1_read_value (pkcs8_asn, "privateKeyAlgorithm.algorithm", oid,
442 &len);
443 if (result != ASN1_SUCCESS)
444 {
445 MHD_gnutls_assert ();
446 result = MHD_gtls_asn2err (result);
447 goto error;
448 }
449
450 /* we only support RSA and DSA private keys.
451 */
452 if (strcmp ((const char *) oid, PK_PKIX1_RSA_OID) == 0)
453 pkey->pk_algorithm = MHD_GNUTLS_PK_RSA;
454 else
455 {
456 MHD_gnutls_assert ();
457 MHD__gnutls_x509_log
458 ("PKCS #8 private key OID '%s' is unsupported.\n", oid);
459 result = GNUTLS_E_UNKNOWN_PK_ALGORITHM;
460 goto error;
461 }
462
463 /* Get the DER encoding of the actual private key.
464 */
465
466 if (pkey->pk_algorithm == MHD_GNUTLS_PK_RSA)
467 result = _decode_pkcs8_rsa_key (pkcs8_asn, pkey);
468 if (result < 0)
469 {
470 MHD_gnutls_assert ();
471 return result;
472 }
473
474 result = 0;
475
476error:
477 MHD__asn1_delete_structure (&pkcs8_asn);
478
479 return result;
480
481}
482
483/**
484 * MHD_gnutls_x509_privkey_import_pkcs8 - This function will import a DER or PEM PKCS8 encoded key
485 * @key: The structure to store the parsed key
486 * @data: The DER or PEM encoded key.
487 * @format: One of DER or PEM
488 * @password: the password to decrypt the key (if it is encrypted).
489 * @flags: 0 if encrypted or GNUTLS_PKCS_PLAIN if not encrypted.
490 *
491 * This function will convert the given DER or PEM encoded PKCS8 2.0 encrypted key
492 * to the native MHD_gnutls_x509_privkey_t format. The output will be stored in @key.
493 * Both RSA and DSA keys can be imported, and flags can only be used to indicate
494 * an unencrypted key.
495 *
496 * The @password can be either ASCII or UTF-8 in the default PBES2
497 * encryption schemas, or ASCII for the PKCS12 schemas.
498 *
499 * If the Certificate is PEM encoded it should have a header of "ENCRYPTED PRIVATE KEY",
500 * or "PRIVATE KEY". You only need to specify the flags if the key is DER encoded, since
501 * in that case the encryption status cannot be auto-detected.
502 *
503 * Returns 0 on success.
504 *
505 **/
506int
507MHD_gnutls_x509_privkey_import_pkcs8 (MHD_gnutls_x509_privkey_t key,
508 const MHD_gnutls_datum_t * data,
509 MHD_gnutls_x509_crt_fmt_t format,
510 const char *password,
511 unsigned int flags)
512{
513 int result = 0, need_free = 0;
514 MHD_gnutls_datum_t _data;
515
516 if (key == NULL)
517 {
518 MHD_gnutls_assert ();
519 return GNUTLS_E_INVALID_REQUEST;
520 }
521
522 _data.data = data->data;
523 _data.size = data->size;
524
525 key->pk_algorithm = MHD_GNUTLS_PK_UNKNOWN;
526
527 /* If the Certificate is in PEM format then decode it
528 */
529 if (format == GNUTLS_X509_FMT_PEM)
530 {
531 opaque *out;
532
533 /* Try the first header
534 */
535 result =
536 MHD__gnutls_fbase64_decode (PEM_UNENCRYPTED_PKCS8,
537 data->data, data->size, &out);
538
539 if (result < 0)
540 { /* Try the encrypted header
541 */
542 result =
543 MHD__gnutls_fbase64_decode (PEM_PKCS8, data->data, data->size,
544 &out);
545
546 if (result <= 0)
547 {
548 if (result == 0)
549 result = GNUTLS_E_INTERNAL_ERROR;
550 MHD_gnutls_assert ();
551 return result;
552 }
553 }
554 else if (flags == 0)
555 flags |= GNUTLS_PKCS_PLAIN;
556
557 _data.data = out;
558 _data.size = result;
559
560 need_free = 1;
561 }
562
563 if (flags & GNUTLS_PKCS_PLAIN)
564 {
565 result = decode_private_key_info (&_data, key);
566 }
567 else
568 { /* encrypted. */
569 result = decode_pkcs8_key (&_data, password, key);
570 }
571
572 if (result < 0)
573 {
574 MHD_gnutls_assert ();
575 goto cleanup;
576 }
577
578 if (need_free)
579 MHD__gnutls_free_datum (&_data);
580
581 /* The key has now been decoded.
582 */
583
584 return 0;
585
586cleanup:
587 key->pk_algorithm = MHD_GNUTLS_PK_UNKNOWN;
588 if (need_free)
589 MHD__gnutls_free_datum (&_data);
590 return result;
591}
592
593/* Reads the PBKDF2 parameters.
594 */
595static int
596read_pbkdf2_params (ASN1_TYPE pbes2_asn,
597 const MHD_gnutls_datum_t * der,
598 struct pbkdf2_params *params)
599{
600 int params_start, params_end;
601 int params_len, len, result;
602 ASN1_TYPE pbkdf2_asn = ASN1_TYPE_EMPTY;
603 char oid[64];
604
605 memset (params, 0, sizeof (params));
606
607 /* Check the key derivation algorithm
608 */
609 len = sizeof (oid);
610 result =
611 MHD__asn1_read_value (pbes2_asn, "keyDerivationFunc.algorithm", oid,
612 &len);
613 if (result != ASN1_SUCCESS)
614 {
615 MHD_gnutls_assert ();
616 return MHD_gtls_asn2err (result);
617 }
618 MHD__gnutls_hard_log ("keyDerivationFunc.algorithm: %s\n", oid);
619
620 if (strcmp (oid, PBKDF2_OID) != 0)
621 {
622 MHD_gnutls_assert ();
623 MHD__gnutls_x509_log
624 ("PKCS #8 key derivation OID '%s' is unsupported.\n", oid);
625 return MHD_gtls_asn2err (result);
626 }
627
628 result =
629 MHD__asn1_der_decoding_startEnd (pbes2_asn, der->data, der->size,
630 "keyDerivationFunc.parameters",
631 &params_start, &params_end);
632 if (result != ASN1_SUCCESS)
633 {
634 MHD_gnutls_assert ();
635 return MHD_gtls_asn2err (result);
636 }
637 params_len = params_end - params_start + 1;
638
639 /* Now check the key derivation and the encryption
640 * functions.
641 */
642 if ((result =
643 MHD__asn1_create_element (MHD__gnutls_get_pkix (),
644 "PKIX1.pkcs-5-PBKDF2-params",
645 &pbkdf2_asn)) != ASN1_SUCCESS)
646 {
647 MHD_gnutls_assert ();
648 return MHD_gtls_asn2err (result);
649 }
650
651 result =
652 MHD__asn1_der_decoding (&pbkdf2_asn, &der->data[params_start],
653 params_len, NULL);
654 if (result != ASN1_SUCCESS)
655 {
656 MHD_gnutls_assert ();
657 result = MHD_gtls_asn2err (result);
658 goto error;
659 }
660
661 /* read the salt */
662 params->salt_size = sizeof (params->salt);
663 result =
664 MHD__asn1_read_value (pbkdf2_asn, "salt.specified", params->salt,
665 &params->salt_size);
666 if (result != ASN1_SUCCESS)
667 {
668 MHD_gnutls_assert ();
669 result = MHD_gtls_asn2err (result);
670 goto error;
671 }
672 MHD__gnutls_hard_log ("salt.specified.size: %d\n", params->salt_size);
673
674 /* read the iteration count
675 */
676 result =
677 MHD__gnutls_x509_read_uint (pbkdf2_asn, "iterationCount",
678 &params->iter_count);
679 if (result != ASN1_SUCCESS)
680 {
681 MHD_gnutls_assert ();
682 goto error;
683 }
684 MHD__gnutls_hard_log ("iterationCount: %d\n", params->iter_count);
685
686 /* read the keylength, if it is set.
687 */
688 result =
689 MHD__gnutls_x509_read_uint (pbkdf2_asn, "keyLength", &params->key_size);
690 if (result < 0)
691 {
692 params->key_size = 0;
693 }
694 MHD__gnutls_hard_log ("keyLength: %d\n", params->key_size);
695
696 /* We don't read the PRF. We only use the default.
697 */
698
699 return 0;
700
701error:
702 MHD__asn1_delete_structure (&pbkdf2_asn);
703 return result;
704
705}
706
707/* Reads the PBE parameters from PKCS-12 schemas (*&#%*&#% RSA).
708 */
709static int
710readMHD_pkcs12_kdf_params (ASN1_TYPE pbes2_asn, struct pbkdf2_params *params)
711{
712 int result;
713
714 memset (params, 0, sizeof (params));
715
716 /* read the salt */
717 params->salt_size = sizeof (params->salt);
718 result =
719 MHD__asn1_read_value (pbes2_asn, "salt", params->salt,
720 &params->salt_size);
721 if (result != ASN1_SUCCESS)
722 {
723 MHD_gnutls_assert ();
724 result = MHD_gtls_asn2err (result);
725 goto error;
726 }
727 MHD__gnutls_hard_log ("salt.size: %d\n", params->salt_size);
728
729 /* read the iteration count
730 */
731 result =
732 MHD__gnutls_x509_read_uint (pbes2_asn, "iterations", &params->iter_count);
733 if (result != ASN1_SUCCESS)
734 {
735 MHD_gnutls_assert ();
736 goto error;
737 }
738 MHD__gnutls_hard_log ("iterationCount: %d\n", params->iter_count);
739
740 params->key_size = 0;
741
742 return 0;
743
744error:
745 return result;
746
747}
748
749/* Converts an OID to a gnutls cipher type.
750 */
751static int
752oid2cipher (const char *oid, enum MHD_GNUTLS_CipherAlgorithm *algo)
753{
754
755 *algo = 0;
756
757 if (strcmp (oid, DES_EDE3_CBC_OID) == 0)
758 {
759 *algo = MHD_GNUTLS_CIPHER_3DES_CBC;
760 return 0;
761 }
762
763 if (strcmp (oid, DES_CBC_OID) == 0)
764 {
765 *algo = MHD_GNUTLS_CIPHER_DES_CBC;
766 return 0;
767 }
768
769 MHD__gnutls_x509_log ("PKCS #8 encryption OID '%s' is unsupported.\n", oid);
770 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
771}
772
773static int
774read_pbe_enc_params (ASN1_TYPE pbes2_asn,
775 const MHD_gnutls_datum_t * der,
776 struct pbe_enc_params *params)
777{
778 int params_start, params_end;
779 int params_len, len, result;
780 ASN1_TYPE pbe_asn = ASN1_TYPE_EMPTY;
781 char oid[64];
782
783 memset (params, 0, sizeof (params));
784
785 /* Check the encryption algorithm
786 */
787 len = sizeof (oid);
788 result =
789 MHD__asn1_read_value (pbes2_asn, "encryptionScheme.algorithm", oid, &len);
790 if (result != ASN1_SUCCESS)
791 {
792 MHD_gnutls_assert ();
793 goto error;
794 }
795 MHD__gnutls_hard_log ("encryptionScheme.algorithm: %s\n", oid);
796
797 if ((result = oid2cipher (oid, &params->cipher)) < 0)
798 {
799 MHD_gnutls_assert ();
800 goto error;
801 }
802
803 result =
804 MHD__asn1_der_decoding_startEnd (pbes2_asn, der->data, der->size,
805 "encryptionScheme.parameters",
806 &params_start, &params_end);
807 if (result != ASN1_SUCCESS)
808 {
809 MHD_gnutls_assert ();
810 return MHD_gtls_asn2err (result);
811 }
812 params_len = params_end - params_start + 1;
813
814 /* Now check the encryption parameters.
815 */
816 if ((result =
817 MHD__asn1_create_element (MHD__gnutls_get_pkix (),
818 "PKIX1.pkcs-5-des-EDE3-CBC-params",
819 &pbe_asn)) != ASN1_SUCCESS)
820 {
821 MHD_gnutls_assert ();
822 return MHD_gtls_asn2err (result);
823 }
824
825 result =
826 MHD__asn1_der_decoding (&pbe_asn, &der->data[params_start], params_len,
827 NULL);
828 if (result != ASN1_SUCCESS)
829 {
830 MHD_gnutls_assert ();
831 result = MHD_gtls_asn2err (result);
832 goto error;
833 }
834
835 /* read the IV */
836 params->iv_size = sizeof (params->iv);
837 result = MHD__asn1_read_value (pbe_asn, "", params->iv, &params->iv_size);
838 if (result != ASN1_SUCCESS)
839 {
840 MHD_gnutls_assert ();
841 result = MHD_gtls_asn2err (result);
842 goto error;
843 }
844 MHD__gnutls_hard_log ("IV.size: %d\n", params->iv_size);
845
846 return 0;
847
848error:
849 MHD__asn1_delete_structure (&pbe_asn);
850 return result;
851
852}
853
854static int
855decrypt_data (schema_id schema, ASN1_TYPE pkcs8_asn,
856 const char *root, const char *password,
857 const struct pbkdf2_params *kdf_params,
858 const struct pbe_enc_params *enc_params,
859 MHD_gnutls_datum_t * decrypted_data)
860{
861 int result;
862 int data_size;
863 opaque *data = NULL, *key = NULL;
864 MHD_gnutls_datum_t dkey, d_iv;
865 cipher_hd_t ch = NULL;
866 int key_size;
867
868 data_size = 0;
869 result = MHD__asn1_read_value (pkcs8_asn, root, NULL, &data_size);
870 if (result != ASN1_MEM_ERROR)
871 {
872 MHD_gnutls_assert ();
873 return MHD_gtls_asn2err (result);
874 }
875
876 data = MHD_gnutls_malloc (data_size);
877 if (data == NULL)
878 {
879 MHD_gnutls_assert ();
880 return GNUTLS_E_MEMORY_ERROR;
881 }
882
883 result = MHD__asn1_read_value (pkcs8_asn, root, data, &data_size);
884 if (result != ASN1_SUCCESS)
885 {
886 MHD_gnutls_assert ();
887 result = MHD_gtls_asn2err (result);
888 goto error;
889 }
890
891 if (kdf_params->key_size == 0)
892 {
893 key_size = MHD__gnutls_cipher_get_key_size (enc_params->cipher);
894 }
895 else
896 key_size = kdf_params->key_size;
897
898 key = MHD_gnutls_alloca (key_size);
899 if (key == NULL)
900 {
901 MHD_gnutls_assert ();
902 result = GNUTLS_E_MEMORY_ERROR;
903 goto error;
904 }
905
906 /* generate the key
907 */
908 if (schema == PBES2)
909 {
910 result = MHD_gc_pbkdf2_sha1 (password, strlen (password),
911 (const char *) kdf_params->salt,
912 kdf_params->salt_size,
913 kdf_params->iter_count, (char *) key,
914 key_size);
915
916 if (result != GC_OK)
917 {
918 MHD_gnutls_assert ();
919 result = GNUTLS_E_DECRYPTION_FAILED;
920 goto error;
921 }
922 }
923 else
924 {
925 result =
926 MHD_pkcs12_string_to_key (1 /*KEY*/, kdf_params->salt,
927 kdf_params->salt_size,
928 kdf_params->iter_count, password,
929 key_size, key);
930
931 if (result < 0)
932 {
933 MHD_gnutls_assert ();
934 goto error;
935 }
936 }
937
938 /* do the decryption.
939 */
940 dkey.data = key;
941 dkey.size = key_size;
942
943 d_iv.data = (opaque *) enc_params->iv;
944 d_iv.size = enc_params->iv_size;
945 ch = MHD_gtls_cipher_init (enc_params->cipher, &dkey, &d_iv);
946
947 MHD_gnutls_afree (key);
948 key = NULL;
949
950 if (ch == NULL)
951 {
952 MHD_gnutls_assert ();
953 result = GNUTLS_E_DECRYPTION_FAILED;
954 goto error;
955 }
956
957 result = MHD_gtls_cipher_decrypt (ch, data, data_size);
958 if (result < 0)
959 {
960 MHD_gnutls_assert ();
961 goto error;
962 }
963
964 decrypted_data->data = data;
965
966 if (MHD_gtls_cipher_get_block_size (enc_params->cipher) != 1)
967 decrypted_data->size = data_size - data[data_size - 1];
968 else
969 decrypted_data->size = data_size;
970
971 MHD_gnutls_cipher_deinit (ch);
972
973 return 0;
974
975error:
976 MHD_gnutls_free (data);
977 MHD_gnutls_afree (key);
978 if (ch != NULL)
979 MHD_gnutls_cipher_deinit (ch);
980 return result;
981}
982
983
984#endif