Internal TLS: Added support for parsing PKCS formatted private keys

The internal TLS implementation can now use both PKCS  RSA private key
and PKCS  encapsulated RSA private key. PKCS  encrypted private key is
not yet supported.
This commit is contained in:
Jouni Malinen 2008-06-02 19:39:46 +03:00
parent b5aebee49e
commit d952d16df4
2 changed files with 117 additions and 0 deletions
src/crypto
wpa_supplicant

View file

@ -22,6 +22,7 @@
#include "aes.h"
#include "tls/rsa.h"
#include "tls/bignum.h"
#include "tls/asn1.h"
#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,
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 *)
crypto_rsa_import_private_key(key, len);
}

View file

@ -8,6 +8,9 @@ ChangeLog for wpa_supplicant
* 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
* 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
* removed 'nai' and 'eappsk' network configuration variables that were