Internal TLS: Added support for parsing PKCS #8 formatted private keys
The internal TLS implementation can now use both PKCS #1 RSA private key and PKCS #8 encapsulated RSA private key. PKCS #8 encrypted private key is not yet supported.
This commit is contained in:
parent
b5aebee49e
commit
d952d16df4
2 changed files with 117 additions and 0 deletions
|
@ -22,6 +22,7 @@
|
||||||
#include "aes.h"
|
#include "aes.h"
|
||||||
#include "tls/rsa.h"
|
#include "tls/rsa.h"
|
||||||
#include "tls/bignum.h"
|
#include "tls/bignum.h"
|
||||||
|
#include "tls/asn1.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef EAP_TLS_FUNCS
|
#ifdef EAP_TLS_FUNCS
|
||||||
|
@ -434,9 +435,122 @@ struct crypto_public_key * crypto_public_key_import(const u8 *key, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct crypto_private_key *
|
||||||
|
crypto_pkcs8_key_import(const u8 *buf, size_t len)
|
||||||
|
{
|
||||||
|
struct asn1_hdr hdr;
|
||||||
|
const u8 *pos, *end;
|
||||||
|
struct bignum *zero;
|
||||||
|
struct asn1_oid oid;
|
||||||
|
char obuf[80];
|
||||||
|
|
||||||
|
/* PKCS #8, Chapter 6 */
|
||||||
|
|
||||||
|
/* PrivateKeyInfo ::= SEQUENCE */
|
||||||
|
if (asn1_get_next(buf, len, &hdr) < 0 ||
|
||||||
|
hdr.class != ASN1_CLASS_UNIVERSAL ||
|
||||||
|
hdr.tag != ASN1_TAG_SEQUENCE) {
|
||||||
|
wpa_printf(MSG_DEBUG, "PKCS #8: Does not start with PKCS #8 "
|
||||||
|
"header (SEQUENCE); assume PKCS #8 not used");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
pos = hdr.payload;
|
||||||
|
end = pos + hdr.length;
|
||||||
|
|
||||||
|
/* version Version (Version ::= INTEGER) */
|
||||||
|
if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
|
||||||
|
hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_INTEGER) {
|
||||||
|
wpa_printf(MSG_DEBUG, "PKCS #8: Expected INTEGER - found "
|
||||||
|
"class %d tag 0x%x; assume PKCS #8 not used",
|
||||||
|
hdr.class, hdr.tag);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
zero = bignum_init();
|
||||||
|
if (zero == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (bignum_set_unsigned_bin(zero, hdr.payload, hdr.length) < 0) {
|
||||||
|
wpa_printf(MSG_DEBUG, "PKCS #8: Failed to parse INTEGER");
|
||||||
|
bignum_deinit(zero);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
pos = hdr.payload + hdr.length;
|
||||||
|
|
||||||
|
if (bignum_cmp_d(zero, 0) != 0) {
|
||||||
|
wpa_printf(MSG_DEBUG, "PKCS #8: Expected zero INTEGER in the "
|
||||||
|
"beginning of private key; not found; assume "
|
||||||
|
"PKCS #8 not used");
|
||||||
|
bignum_deinit(zero);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
bignum_deinit(zero);
|
||||||
|
|
||||||
|
/* privateKeyAlgorithm PrivateKeyAlgorithmIdentifier
|
||||||
|
* (PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier) */
|
||||||
|
if (asn1_get_next(pos, len, &hdr) < 0 ||
|
||||||
|
hdr.class != ASN1_CLASS_UNIVERSAL ||
|
||||||
|
hdr.tag != ASN1_TAG_SEQUENCE) {
|
||||||
|
wpa_printf(MSG_DEBUG, "PKCS #8: Expected SEQUENCE "
|
||||||
|
"(AlgorithmIdentifier) - found class %d tag 0x%x; "
|
||||||
|
"assume PKCS #8 not used",
|
||||||
|
hdr.class, hdr.tag);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (asn1_get_oid(hdr.payload, hdr.length, &oid, &pos)) {
|
||||||
|
wpa_printf(MSG_DEBUG, "PKCS #8: Failed to parse OID "
|
||||||
|
"(algorithm); assume PKCS #8 not used");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
asn1_oid_to_str(&oid, obuf, sizeof(obuf));
|
||||||
|
wpa_printf(MSG_DEBUG, "PKCS #8: algorithm=%s", obuf);
|
||||||
|
|
||||||
|
if (oid.len != 7 ||
|
||||||
|
oid.oid[0] != 1 /* iso */ ||
|
||||||
|
oid.oid[1] != 2 /* member-body */ ||
|
||||||
|
oid.oid[2] != 840 /* us */ ||
|
||||||
|
oid.oid[3] != 113549 /* rsadsi */ ||
|
||||||
|
oid.oid[4] != 1 /* pkcs */ ||
|
||||||
|
oid.oid[5] != 1 /* pkcs-1 */ ||
|
||||||
|
oid.oid[6] != 1 /* rsaEncryption */) {
|
||||||
|
wpa_printf(MSG_DEBUG, "PKCS #8: Unsupported private key "
|
||||||
|
"algorithm %s", obuf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = hdr.payload + hdr.length;
|
||||||
|
|
||||||
|
/* privateKey PrivateKey (PrivateKey ::= OCTET STRING) */
|
||||||
|
if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
|
||||||
|
hdr.class != ASN1_CLASS_UNIVERSAL ||
|
||||||
|
hdr.tag != ASN1_TAG_OCTETSTRING) {
|
||||||
|
wpa_printf(MSG_DEBUG, "PKCS #8: Expected OCTETSTRING "
|
||||||
|
"(privateKey) - found class %d tag 0x%x",
|
||||||
|
hdr.class, hdr.tag);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
wpa_printf(MSG_DEBUG, "PKCS #8: Try to parse RSAPrivateKey");
|
||||||
|
|
||||||
|
return (struct crypto_private_key *)
|
||||||
|
crypto_rsa_import_private_key(hdr.payload, hdr.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct crypto_private_key * crypto_private_key_import(const u8 *key,
|
struct crypto_private_key * crypto_private_key_import(const u8 *key,
|
||||||
size_t len)
|
size_t len)
|
||||||
{
|
{
|
||||||
|
struct crypto_private_key *res;
|
||||||
|
|
||||||
|
/* First, check for possible PKCS #8 encoding */
|
||||||
|
res = crypto_pkcs8_key_import(key, len);
|
||||||
|
if (res)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/* Not PKCS#8, so try to import PKCS #1 encoded RSA private key */
|
||||||
|
wpa_printf(MSG_DEBUG, "Trying to parse PKCS #1 encoded RSA private "
|
||||||
|
"key");
|
||||||
return (struct crypto_private_key *)
|
return (struct crypto_private_key *)
|
||||||
crypto_rsa_import_private_key(key, len);
|
crypto_rsa_import_private_key(key, len);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,9 @@ ChangeLog for wpa_supplicant
|
||||||
* fixed the OpenSSL patches (0.9.8g and 0.9.9) for EAP-FAST to
|
* fixed the OpenSSL patches (0.9.8g and 0.9.9) for EAP-FAST to
|
||||||
allow fallback to full handshake if server rejects PAC-Opaque
|
allow fallback to full handshake if server rejects PAC-Opaque
|
||||||
* added fragmentation support for EAP-TNC
|
* added fragmentation support for EAP-TNC
|
||||||
|
* added support for parsing PKCS #8 formatted private keys into the
|
||||||
|
internal TLS implementation (both PKCS #1 RSA key and PKCS #8
|
||||||
|
encapsulated RSA key can now be used)
|
||||||
|
|
||||||
2008-02-22 - v0.6.3
|
2008-02-22 - v0.6.3
|
||||||
* removed 'nai' and 'eappsk' network configuration variables that were
|
* removed 'nai' and 'eappsk' network configuration variables that were
|
||||||
|
|
Loading…
Reference in a new issue