driver_test: Remove forgotten, unused prototypes
[hostap-gosc2009.git] / src / tls / pkcs8.c
blob69ab262e5ebedcd4fb21eaa04059933547a28532
1 /*
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
10 * license.
12 * See README and COPYING for more details.
15 #include "includes.h"
17 #include "common.h"
18 #include "asn1.h"
19 #include "bignum.h"
20 #include "rsa.h"
21 #include "pkcs5.h"
22 #include "pkcs8.h"
25 struct crypto_private_key * pkcs8_key_import(const u8 *buf, size_t len)
27 struct asn1_hdr hdr;
28 const u8 *pos, *end;
29 struct bignum *zero;
30 struct asn1_oid oid;
31 char obuf[80];
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");
41 return NULL;
43 pos = hdr.payload;
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",
51 hdr.class, hdr.tag);
52 return NULL;
55 zero = bignum_init();
56 if (zero == NULL)
57 return NULL;
59 if (bignum_set_unsigned_bin(zero, hdr.payload, hdr.length) < 0) {
60 wpa_printf(MSG_DEBUG, "PKCS #8: Failed to parse INTEGER");
61 bignum_deinit(zero);
62 return NULL;
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 "
69 "PKCS #8 not used");
70 bignum_deinit(zero);
71 return NULL;
73 bignum_deinit(zero);
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",
83 hdr.class, hdr.tag);
84 return NULL;
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");
90 return NULL;
93 asn1_oid_to_str(&oid, obuf, sizeof(obuf));
94 wpa_printf(MSG_DEBUG, "PKCS #8: algorithm=%s", obuf);
96 if (oid.len != 7 ||
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);
106 return NULL;
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",
117 hdr.class, hdr.tag);
118 return NULL;
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)
130 struct asn1_hdr hdr;
131 const u8 *pos, *end, *enc_alg;
132 size_t enc_alg_len;
133 u8 *data;
134 size_t data_len;
136 if (passwd == NULL)
137 return NULL;
140 * PKCS #8, Chapter 7
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 "
153 "used");
154 return NULL;
156 pos = hdr.payload;
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",
166 hdr.class, hdr.tag);
167 return NULL;
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",
179 hdr.class, hdr.tag);
180 return NULL;
183 data = pkcs5_decrypt(enc_alg, enc_alg_len, hdr.payload, hdr.length,
184 passwd, &data_len);
185 if (data) {
186 struct crypto_private_key *key;
187 key = pkcs8_key_import(data, data_len);
188 os_free(data);
189 return key;
192 return NULL;