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);