2 * PKCS #8 (Private-key information syntax)
3 * Copyright (c) 2006-2009, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
25 struct crypto_private_key
* pkcs8_key_import(const u8
*buf
, size_t len
)
33 /* PKCS #8, Chapter 6 */
35 /* PrivateKeyInfo ::= SEQUENCE */
36 if (asn1_get_next(buf
, len
, &hdr
) < 0 ||
37 hdr
.class != ASN1_CLASS_UNIVERSAL
||
38 hdr
.tag
!= ASN1_TAG_SEQUENCE
) {
39 wpa_printf(MSG_DEBUG
, "PKCS #8: Does not start with PKCS #8 "
40 "header (SEQUENCE); assume PKCS #8 not used");
44 end
= pos
+ hdr
.length
;
46 /* version Version (Version ::= INTEGER) */
47 if (asn1_get_next(pos
, end
- pos
, &hdr
) < 0 ||
48 hdr
.class != ASN1_CLASS_UNIVERSAL
|| hdr
.tag
!= ASN1_TAG_INTEGER
) {
49 wpa_printf(MSG_DEBUG
, "PKCS #8: Expected INTEGER - found "
50 "class %d tag 0x%x; assume PKCS #8 not used",
59 if (bignum_set_unsigned_bin(zero
, hdr
.payload
, hdr
.length
) < 0) {
60 wpa_printf(MSG_DEBUG
, "PKCS #8: Failed to parse INTEGER");
64 pos
= hdr
.payload
+ hdr
.length
;
66 if (bignum_cmp_d(zero
, 0) != 0) {
67 wpa_printf(MSG_DEBUG
, "PKCS #8: Expected zero INTEGER in the "
68 "beginning of private key; not found; assume "
75 /* privateKeyAlgorithm PrivateKeyAlgorithmIdentifier
76 * (PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier) */
77 if (asn1_get_next(pos
, len
, &hdr
) < 0 ||
78 hdr
.class != ASN1_CLASS_UNIVERSAL
||
79 hdr
.tag
!= ASN1_TAG_SEQUENCE
) {
80 wpa_printf(MSG_DEBUG
, "PKCS #8: Expected SEQUENCE "
81 "(AlgorithmIdentifier) - found class %d tag 0x%x; "
82 "assume PKCS #8 not used",
87 if (asn1_get_oid(hdr
.payload
, hdr
.length
, &oid
, &pos
)) {
88 wpa_printf(MSG_DEBUG
, "PKCS #8: Failed to parse OID "
89 "(algorithm); assume PKCS #8 not used");
93 asn1_oid_to_str(&oid
, obuf
, sizeof(obuf
));
94 wpa_printf(MSG_DEBUG
, "PKCS #8: algorithm=%s", obuf
);
97 oid
.oid
[0] != 1 /* iso */ ||
98 oid
.oid
[1] != 2 /* member-body */ ||
99 oid
.oid
[2] != 840 /* us */ ||
100 oid
.oid
[3] != 113549 /* rsadsi */ ||
101 oid
.oid
[4] != 1 /* pkcs */ ||
102 oid
.oid
[5] != 1 /* pkcs-1 */ ||
103 oid
.oid
[6] != 1 /* rsaEncryption */) {
104 wpa_printf(MSG_DEBUG
, "PKCS #8: Unsupported private key "
105 "algorithm %s", obuf
);
109 pos
= hdr
.payload
+ hdr
.length
;
111 /* privateKey PrivateKey (PrivateKey ::= OCTET STRING) */
112 if (asn1_get_next(pos
, end
- pos
, &hdr
) < 0 ||
113 hdr
.class != ASN1_CLASS_UNIVERSAL
||
114 hdr
.tag
!= ASN1_TAG_OCTETSTRING
) {
115 wpa_printf(MSG_DEBUG
, "PKCS #8: Expected OCTETSTRING "
116 "(privateKey) - found class %d tag 0x%x",
120 wpa_printf(MSG_DEBUG
, "PKCS #8: Try to parse RSAPrivateKey");
122 return (struct crypto_private_key
*)
123 crypto_rsa_import_private_key(hdr
.payload
, hdr
.length
);
127 struct crypto_private_key
*
128 pkcs8_enc_key_import(const u8
*buf
, size_t len
, const char *passwd
)
131 const u8
*pos
, *end
, *enc_alg
;
141 * EncryptedPrivateKeyInfo ::= SEQUENCE {
142 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
143 * encryptedData EncryptedData }
144 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
145 * EncryptedData ::= OCTET STRING
148 if (asn1_get_next(buf
, len
, &hdr
) < 0 ||
149 hdr
.class != ASN1_CLASS_UNIVERSAL
||
150 hdr
.tag
!= ASN1_TAG_SEQUENCE
) {
151 wpa_printf(MSG_DEBUG
, "PKCS #8: Does not start with PKCS #8 "
152 "header (SEQUENCE); assume encrypted PKCS #8 not "
157 end
= pos
+ hdr
.length
;
159 /* encryptionAlgorithm EncryptionAlgorithmIdentifier */
160 if (asn1_get_next(pos
, end
- pos
, &hdr
) < 0 ||
161 hdr
.class != ASN1_CLASS_UNIVERSAL
||
162 hdr
.tag
!= ASN1_TAG_SEQUENCE
) {
163 wpa_printf(MSG_DEBUG
, "PKCS #8: Expected SEQUENCE "
164 "(AlgorithmIdentifier) - found class %d tag 0x%x; "
165 "assume encrypted PKCS #8 not used",
169 enc_alg
= hdr
.payload
;
170 enc_alg_len
= hdr
.length
;
171 pos
= hdr
.payload
+ hdr
.length
;
173 /* encryptedData EncryptedData */
174 if (asn1_get_next(pos
, end
- pos
, &hdr
) < 0 ||
175 hdr
.class != ASN1_CLASS_UNIVERSAL
||
176 hdr
.tag
!= ASN1_TAG_OCTETSTRING
) {
177 wpa_printf(MSG_DEBUG
, "PKCS #8: Expected OCTETSTRING "
178 "(encryptedData) - found class %d tag 0x%x",
183 data
= pkcs5_decrypt(enc_alg
, enc_alg_len
, hdr
.payload
, hdr
.length
,
186 struct crypto_private_key
*key
;
187 key
= pkcs8_key_import(data
, data_len
);