2 * Copyright (C) 2012 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 #include "pkcs8_builder.h"
20 #include <asn1/asn1.h>
21 #include <asn1/asn1_parser.h>
22 #include <credentials/keys/private_key.h>
25 * ASN.1 definition of a privateKeyInfo structure
27 static const asn1Object_t pkinfoObjects
[] = {
28 { 0, "privateKeyInfo", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
29 { 1, "version", ASN1_INTEGER
, ASN1_BODY
}, /* 1 */
30 { 1, "privateKeyAlgorithm", ASN1_EOC
, ASN1_RAW
}, /* 2 */
31 { 1, "privateKey", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 3 */
32 { 1, "attributes", ASN1_CONTEXT_C_0
, ASN1_OPT
}, /* 4 */
33 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 5 */
34 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
36 #define PKINFO_PRIVATE_KEY_ALGORITHM 2
37 #define PKINFO_PRIVATE_KEY 3
40 * Load a generic private key from an ASN.1 encoded blob
42 static private_key_t
*parse_private_key(chunk_t blob
)
44 asn1_parser_t
*parser
;
45 chunk_t object
, params
= chunk_empty
;
47 private_key_t
*key
= NULL
;
48 key_type_t type
= KEY_ANY
;
50 parser
= asn1_parser_create(pkinfoObjects
, blob
);
51 parser
->set_flags(parser
, FALSE
, TRUE
);
53 while (parser
->iterate(parser
, &objectID
, &object
))
57 case PKINFO_PRIVATE_KEY_ALGORITHM
:
59 int oid
= asn1_parse_algorithmIdentifier(object
,
60 parser
->get_level(parser
) + 1, ¶ms
);
64 case OID_RSA_ENCRYPTION
:
67 case OID_EC_PUBLICKEY
:
71 /* key type not supported */
76 case PKINFO_PRIVATE_KEY
:
78 DBG2(DBG_ASN
, "-- > --");
81 key
= lib
->creds
->create(lib
->creds
, CRED_PRIVATE_KEY
,
82 type
, BUILD_BLOB_ALGID_PARAMS
,
83 params
, BUILD_BLOB_ASN1_DER
,
88 key
= lib
->creds
->create(lib
->creds
, CRED_PRIVATE_KEY
,
89 type
, BUILD_BLOB_ASN1_DER
, object
,
92 DBG2(DBG_ASN
, "-- < --");
99 parser
->destroy(parser
);
104 * Verify padding of decrypted blob.
105 * Length of blob is adjusted accordingly.
107 static bool verify_padding(chunk_t
*blob
)
109 u_int8_t padding
, count
;
111 padding
= count
= blob
->ptr
[blob
->len
- 1];
116 for (; blob
->len
&& count
; --blob
->len
, --count
)
118 if (blob
->ptr
[blob
->len
- 1] != padding
)
127 * Prototype for key derivation functions.
129 typedef bool (*kdf_t
)(void *generator
, chunk_t password
, chunk_t salt
,
130 u_int64_t iterations
, chunk_t key
);
133 * Try to decrypt the given blob with multiple passwords using the given
134 * key derivation function. keymat is where the kdf function writes the key
135 * to, key and iv point to the actual keys and initialization vectors resp.
137 static private_key_t
*decrypt_private_key(chunk_t blob
,
138 encryption_algorithm_t encr
, size_t key_len
, kdf_t kdf
,
139 void *generator
, chunk_t salt
, u_int64_t iterations
,
140 chunk_t keymat
, chunk_t key
, chunk_t iv
)
142 enumerator_t
*enumerator
;
143 shared_key_t
*shared
;
145 private_key_t
*private_key
= NULL
;
147 crypter
= lib
->crypto
->create_crypter(lib
->crypto
, encr
, key_len
);
150 DBG1(DBG_ASN
, " %N encryption algorithm not available",
151 encryption_algorithm_names
, encr
);
154 if (blob
.len
% crypter
->get_block_size(crypter
))
156 DBG1(DBG_ASN
, " data size is not a multiple of block size");
157 crypter
->destroy(crypter
);
161 enumerator
= lib
->credmgr
->create_shared_enumerator(lib
->credmgr
,
162 SHARED_PRIVATE_KEY_PASS
, NULL
, NULL
);
163 while (enumerator
->enumerate(enumerator
, &shared
, NULL
, NULL
))
167 if (!kdf(generator
, shared
->get_key(shared
), salt
, iterations
, keymat
))
172 crypter
->set_key(crypter
, key
);
173 if (!crypter
->decrypt(crypter
, blob
, iv
, &decrypted
))
177 if (verify_padding(&decrypted
))
179 private_key
= parse_private_key(decrypted
);
182 chunk_clear(&decrypted
);
186 chunk_free(&decrypted
);
188 enumerator
->destroy(enumerator
);
189 crypter
->destroy(crypter
);
195 * Function F of PBKDF2
197 static bool pbkdf2_f(chunk_t block
, prf_t
*prf
, chunk_t seed
,
198 u_int64_t iterations
)
203 u
= chunk_alloca(prf
->get_block_size(prf
));
204 if (!prf
->get_bytes(prf
, seed
, u
.ptr
))
208 memcpy(block
.ptr
, u
.ptr
, block
.len
);
210 for (i
= 1; i
< iterations
; i
++)
212 if (!prf
->get_bytes(prf
, u
, u
.ptr
))
216 memxor(block
.ptr
, u
.ptr
, block
.len
);
222 * PBKDF2 key derivation function
224 static bool pbkdf2(prf_t
*prf
, chunk_t password
, chunk_t salt
,
225 u_int64_t iterations
, chunk_t key
)
227 chunk_t keymat
, block
, seed
;
229 u_int32_t i
= 0, *ni
;
231 if (!prf
->set_key(prf
, password
))
236 block
.len
= prf
->get_block_size(prf
);
237 blocks
= (key
.len
- 1) / block
.len
+ 1;
238 keymat
= chunk_alloca(blocks
* block
.len
);
240 seed
= chunk_cata("cc", salt
, chunk_from_thing(i
));
241 ni
= (u_int32_t
*)(seed
.ptr
+ salt
.len
);
243 for (; i
< blocks
; i
++)
246 block
.ptr
= keymat
.ptr
+ (i
* block
.len
);
247 if (!pbkdf2_f(block
, prf
, seed
, iterations
))
253 memcpy(key
.ptr
, keymat
.ptr
, key
.len
);
259 * Decrypt an encrypted PKCS#8 encoded private key according to PBES2
261 static private_key_t
*decrypt_private_key_pbes2(chunk_t blob
,
262 encryption_algorithm_t encr
, size_t key_len
,
263 chunk_t iv
, pseudo_random_function_t prf_func
,
264 chunk_t salt
, u_int64_t iterations
)
266 private_key_t
*private_key
;
270 prf
= lib
->crypto
->create_prf(lib
->crypto
, prf_func
);
273 DBG1(DBG_ASN
, " %N prf algorithm not available",
274 pseudo_random_function_names
, prf_func
);
278 key
= chunk_alloca(key_len
);
280 private_key
= decrypt_private_key(blob
, encr
, key_len
, (kdf_t
)pbkdf2
, prf
,
281 salt
, iterations
, key
, key
, iv
);
288 * PBKDF1 key derivation function
290 static bool pbkdf1(hasher_t
*hasher
, chunk_t password
, chunk_t salt
,
291 u_int64_t iterations
, chunk_t key
)
296 hash
= chunk_alloca(hasher
->get_hash_size(hasher
));
297 hasher
->get_hash(hasher
, password
, NULL
);
298 hasher
->get_hash(hasher
, salt
, hash
.ptr
);
300 for (i
= 1; i
< iterations
; i
++)
302 hasher
->get_hash(hasher
, hash
, hash
.ptr
);
305 memcpy(key
.ptr
, hash
.ptr
, key
.len
);
311 * Decrypt an encrypted PKCS#8 encoded private key according to PBES1
313 static private_key_t
*decrypt_private_key_pbes1(chunk_t blob
,
314 encryption_algorithm_t encr
, size_t key_len
,
315 hash_algorithm_t hash
, chunk_t salt
,
316 u_int64_t iterations
)
318 private_key_t
*private_key
= NULL
;
319 hasher_t
*hasher
= NULL
;
320 chunk_t keymat
, key
, iv
;
322 hasher
= lib
->crypto
->create_hasher(lib
->crypto
, hash
);
325 DBG1(DBG_ASN
, " %N hash algorithm not available",
326 hash_algorithm_names
, hash
);
329 if (hasher
->get_hash_size(hasher
) < key_len
)
334 keymat
= chunk_alloca(key_len
* 2);
336 key
.ptr
= keymat
.ptr
;
338 iv
.ptr
= keymat
.ptr
+ key_len
;
340 private_key
= decrypt_private_key(blob
, encr
, key_len
, (kdf_t
)pbkdf1
,
341 hasher
, salt
, iterations
, keymat
,
350 * Parse an ASN1_INTEGER to a u_int64_t.
352 static u_int64_t
parse_asn1_integer_uint64(chunk_t blob
)
357 for (i
= 0; i
< blob
.len
; i
++)
358 { /* if it is longer than 8 bytes, we just use the 8 LSBs */
360 val
|= (u_int64_t
)blob
.ptr
[i
];
366 * ASN.1 definition of a PBKDF2-params structure
367 * The salt is actually a CHOICE and could be an AlgorithmIdentifier from
368 * PBKDF2-SaltSources (but as per RFC 2898 that's for future versions).
370 static const asn1Object_t pbkdf2ParamsObjects
[] = {
371 { 0, "PBKDF2-params", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
372 { 1, "salt", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 1 */
373 { 1, "iterationCount",ASN1_INTEGER
, ASN1_BODY
}, /* 2 */
374 { 1, "keyLength", ASN1_INTEGER
, ASN1_OPT
|ASN1_BODY
}, /* 3 */
375 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 4 */
376 { 1, "prf", ASN1_EOC
, ASN1_DEF
|ASN1_RAW
}, /* 5 */
377 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
379 #define PBKDF2_SALT 1
380 #define PBKDF2_ITERATION_COUNT 2
381 #define PBKDF2_KEY_LENGTH 3
385 * Parse a PBKDF2-params structure
387 static void parse_pbkdf2_params(chunk_t blob
, chunk_t
*salt
,
388 u_int64_t
*iterations
, size_t *key_len
,
389 pseudo_random_function_t
*prf
)
391 asn1_parser_t
*parser
;
395 parser
= asn1_parser_create(pbkdf2ParamsObjects
, blob
);
397 *key_len
= 0; /* key_len is optional */
399 while (parser
->iterate(parser
, &objectID
, &object
))
408 case PBKDF2_ITERATION_COUNT
:
410 *iterations
= parse_asn1_integer_uint64(object
);
413 case PBKDF2_KEY_LENGTH
:
415 *key_len
= (size_t)parse_asn1_integer_uint64(object
);
419 { /* defaults to id-hmacWithSHA1 */
420 *prf
= PRF_HMAC_SHA1
;
426 parser
->destroy(parser
);
430 * ASN.1 definition of a PBES2-params structure
432 static const asn1Object_t pbes2ParamsObjects
[] = {
433 { 0, "PBES2-params", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
434 { 1, "keyDerivationFunc", ASN1_EOC
, ASN1_RAW
}, /* 1 */
435 { 1, "encryptionScheme", ASN1_EOC
, ASN1_RAW
}, /* 2 */
436 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
438 #define PBES2PARAMS_KEY_DERIVATION_FUNC 1
439 #define PBES2PARAMS_ENCRYPTION_SCHEME 2
442 * Parse a PBES2-params structure
444 static void parse_pbes2_params(chunk_t blob
, chunk_t
*salt
,
445 u_int64_t
*iterations
, size_t *key_len
,
446 pseudo_random_function_t
*prf
,
447 encryption_algorithm_t
*encr
, chunk_t
*iv
)
449 asn1_parser_t
*parser
;
450 chunk_t object
, params
;
453 parser
= asn1_parser_create(pbes2ParamsObjects
, blob
);
455 while (parser
->iterate(parser
, &objectID
, &object
))
459 case PBES2PARAMS_KEY_DERIVATION_FUNC
:
461 int oid
= asn1_parse_algorithmIdentifier(object
,
462 parser
->get_level(parser
) + 1, ¶ms
);
463 if (oid
!= OID_PBKDF2
)
464 { /* unsupported key derivation function */
467 parse_pbkdf2_params(params
, salt
, iterations
, key_len
, prf
);
470 case PBES2PARAMS_ENCRYPTION_SCHEME
:
472 int oid
= asn1_parse_algorithmIdentifier(object
,
473 parser
->get_level(parser
) + 1, ¶ms
);
474 if (oid
!= OID_3DES_EDE_CBC
)
475 { /* unsupported encryption scheme */
479 { /* default key len for DES-EDE3-CBC-Pad */
482 if (!asn1_parse_simple_object(¶ms
, ASN1_OCTET_STRING
,
483 parser
->get_level(parser
) + 1, "IV"))
495 parser
->destroy(parser
);
499 * ASN.1 definition of a PBEParameter structure
501 static const asn1Object_t pbeParameterObjects
[] = {
502 { 0, "PBEParameter", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
503 { 1, "salt", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 1 */
504 { 1, "iterationCount", ASN1_INTEGER
, ASN1_BODY
}, /* 2 */
505 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
507 #define PBEPARAM_SALT 1
508 #define PBEPARAM_ITERATION_COUNT 2
511 * Parse a PBEParameter structure
513 static void parse_pbe_parameters(chunk_t blob
, chunk_t
*salt
,
514 u_int64_t
*iterations
)
516 asn1_parser_t
*parser
;
520 parser
= asn1_parser_create(pbeParameterObjects
, blob
);
522 while (parser
->iterate(parser
, &objectID
, &object
))
531 case PBEPARAM_ITERATION_COUNT
:
533 *iterations
= parse_asn1_integer_uint64(object
);
539 parser
->destroy(parser
);
543 * ASN.1 definition of an encryptedPrivateKeyInfo structure
545 static const asn1Object_t encryptedPKIObjects
[] = {
546 { 0, "encryptedPrivateKeyInfo", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
547 { 1, "encryptionAlgorithm", ASN1_EOC
, ASN1_RAW
}, /* 1 */
548 { 1, "encryptedData", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 2 */
549 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
551 #define EPKINFO_ENCRYPTION_ALGORITHM 1
552 #define EPKINFO_ENCRYPTED_DATA 2
555 * Load an encrypted private key from an ASN.1 encoded blob
556 * Schemes per PKCS#5 (RFC 2898)
558 static private_key_t
*parse_encrypted_private_key(chunk_t blob
)
560 asn1_parser_t
*parser
;
561 chunk_t object
, params
, salt
= chunk_empty
, iv
= chunk_empty
;
562 u_int64_t iterations
= 0;
564 encryption_algorithm_t encr
= ENCR_UNDEFINED
;
565 hash_algorithm_t hash
= HASH_UNKNOWN
;
566 pseudo_random_function_t prf
= PRF_UNDEFINED
;
567 private_key_t
*key
= NULL
;
570 parser
= asn1_parser_create(encryptedPKIObjects
, blob
);
572 while (parser
->iterate(parser
, &objectID
, &object
))
576 case EPKINFO_ENCRYPTION_ALGORITHM
:
578 int oid
= asn1_parse_algorithmIdentifier(object
,
579 parser
->get_level(parser
) + 1, ¶ms
);
583 case OID_PBE_MD5_DES_CBC
:
586 parse_pbe_parameters(params
, &salt
, &iterations
);
588 case OID_PBE_SHA1_DES_CBC
:
591 parse_pbe_parameters(params
, &salt
, &iterations
);
594 parse_pbes2_params(params
, &salt
, &iterations
,
595 &key_len
, &prf
, &encr
, &iv
);
598 /* encryption scheme not supported */
603 case EPKINFO_ENCRYPTED_DATA
:
605 if (prf
!= PRF_UNDEFINED
)
607 key
= decrypt_private_key_pbes2(object
, encr
, key_len
, iv
,
608 prf
, salt
, iterations
);
612 key
= decrypt_private_key_pbes1(object
, encr
, key_len
, hash
,
621 parser
->destroy(parser
);
628 private_key_t
*pkcs8_private_key_load(key_type_t type
, va_list args
)
630 chunk_t blob
= chunk_empty
;
635 switch (va_arg(args
, builder_part_t
))
637 case BUILD_BLOB_ASN1_DER
:
638 blob
= va_arg(args
, chunk_t
);
647 /* we don't know whether it is encrypted or not, try both ways */
648 key
= parse_encrypted_private_key(blob
);
651 key
= parse_private_key(blob
);