pkcs1: Support building of KEY_ANY private keys
We try to detect the type of key by parsing the basic structure of the passed ASN.1 blob.
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2016 Tobias Brunner
|
||||
* Copyright (C) 2008-2009 Martin Willi
|
||||
* Copyright (C) 2008 Tobias Brunner
|
||||
* Copyright (C) 2000-2008 Andreas Steffen
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -204,7 +204,6 @@ static private_key_t *parse_rsa_private_key(chunk_t blob)
|
||||
case PRIV_KEY_VERSION:
|
||||
if (object.len > 0 && *object.ptr != 0)
|
||||
{
|
||||
DBG1(DBG_ASN, "PKCS#1 private key format is not version 1");
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
@@ -248,6 +247,63 @@ end:
|
||||
BUILD_RSA_EXP2, exp2, BUILD_RSA_COEFF, coeff, BUILD_END);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the ASN.1 structure looks like an EC private key according to
|
||||
* RFC 5915.
|
||||
*
|
||||
* ECPrivateKey :=: SEQUENCE {
|
||||
* version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
|
||||
* privateKey OCTET STRING,
|
||||
* parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
|
||||
* publicKey [1] BIT STRING OPTIONAL
|
||||
* }
|
||||
*
|
||||
* While the parameters and publicKey fields are OPTIONAL, RFC 5915 says that
|
||||
* paramaters MUST be included and publicKey SHOULD be.
|
||||
*/
|
||||
static bool is_ec_private_key(chunk_t blob)
|
||||
{
|
||||
chunk_t data;
|
||||
return asn1_unwrap(&blob, &blob) == ASN1_SEQUENCE &&
|
||||
asn1_unwrap(&blob, &data) == ASN1_INTEGER &&
|
||||
asn1_parse_integer_uint64(data) == 1 &&
|
||||
asn1_unwrap(&blob, &data) == ASN1_OCTET_STRING &&
|
||||
asn1_unwrap(&blob, &data) == ASN1_CONTEXT_C_0 &&
|
||||
asn1_unwrap(&blob, &data) == ASN1_CONTEXT_C_1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the ASN.1 structure looks like a BLISS private key.
|
||||
*/
|
||||
static bool is_bliss_private_key(chunk_t blob)
|
||||
{
|
||||
chunk_t data;
|
||||
return asn1_unwrap(&blob, &blob) == ASN1_SEQUENCE &&
|
||||
asn1_unwrap(&blob, &data) == ASN1_OID &&
|
||||
asn1_unwrap(&blob, &data) == ASN1_BIT_STRING &&
|
||||
asn1_unwrap(&blob, &data) == ASN1_BIT_STRING &&
|
||||
asn1_unwrap(&blob, &data) == ASN1_BIT_STRING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a private key from an ASN.1 encoded blob trying to detect the type
|
||||
* automatically.
|
||||
*/
|
||||
static private_key_t *parse_private_key(chunk_t blob)
|
||||
{
|
||||
if (is_ec_private_key(blob))
|
||||
{
|
||||
return lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
|
||||
BUILD_BLOB_ASN1_DER, blob, BUILD_END);
|
||||
}
|
||||
else if (is_bliss_private_key(blob))
|
||||
{
|
||||
return lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
|
||||
BUILD_BLOB_ASN1_DER, blob, BUILD_END);
|
||||
}
|
||||
return parse_rsa_private_key(blob);
|
||||
}
|
||||
|
||||
/**
|
||||
* See header.
|
||||
*/
|
||||
@@ -301,6 +357,14 @@ private_key_t *pkcs1_private_key_load(key_type_t type, va_list args)
|
||||
}
|
||||
break;
|
||||
}
|
||||
return parse_rsa_private_key(blob);
|
||||
switch (type)
|
||||
{
|
||||
case KEY_ANY:
|
||||
return parse_private_key(blob);
|
||||
case KEY_RSA:
|
||||
return parse_rsa_private_key(blob);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2009 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -42,6 +42,10 @@ METHOD(plugin_t, get_features, int,
|
||||
private_pkcs1_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_REGISTER(PRIVKEY, pkcs1_private_key_load, FALSE),
|
||||
PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
|
||||
PLUGIN_SDEPEND(PRIVKEY, KEY_RSA),
|
||||
PLUGIN_SDEPEND(PRIVKEY, KEY_ECDSA),
|
||||
PLUGIN_REGISTER(PRIVKEY, pkcs1_private_key_load, FALSE),
|
||||
PLUGIN_PROVIDE(PRIVKEY, KEY_RSA),
|
||||
PLUGIN_REGISTER(PUBKEY, pkcs1_public_key_load, FALSE),
|
||||
|
||||
Reference in New Issue
Block a user