handle EC private keys for real
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@25218 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -58,10 +58,8 @@ struct hx509_private_key_ops {
|
|||||||
int (*export)(hx509_context context,
|
int (*export)(hx509_context context,
|
||||||
const hx509_private_key,
|
const hx509_private_key,
|
||||||
heim_octet_string *);
|
heim_octet_string *);
|
||||||
int (*import)(hx509_context,
|
int (*import)(hx509_context, const AlgorithmIdentifier *,
|
||||||
const void *data,
|
const void *, size_t, hx509_private_key);
|
||||||
size_t len,
|
|
||||||
hx509_private_key private_key);
|
|
||||||
int (*generate_private_key)(hx509_context,
|
int (*generate_private_key)(hx509_context,
|
||||||
struct hx509_generate_private_context *,
|
struct hx509_generate_private_context *,
|
||||||
hx509_private_key);
|
hx509_private_key);
|
||||||
@@ -280,6 +278,48 @@ set_digest_alg(DigestAlgorithmIdentifier *id,
|
|||||||
|
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_OPENSSL
|
||||||
|
|
||||||
|
static int
|
||||||
|
heim_oid2ecnid(heim_oid *oid)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Now map to openssl OID fun
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (der_heim_oid_cmp(oid, &asn1_oid_id_ec_group_secp256r1) == 0)
|
||||||
|
return NID_X9_62_prime256v1;
|
||||||
|
else if (der_heim_oid_cmp(oid, &asn1_oid_id_ec_group_secp160r1) == 0)
|
||||||
|
return NID_secp160r1;
|
||||||
|
else if (der_heim_oid_cmp(oid, &asn1_oid_id_ec_group_secp160r2) == 0)
|
||||||
|
return NID_secp160r2;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
parse_ECParameters(heim_octet_string *parameters, int *nid)
|
||||||
|
{
|
||||||
|
ECParameters ecparam;
|
||||||
|
size_t size;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = decode_ECParameters(parameters->data, parameters->length,
|
||||||
|
&ecparam, &size);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (ecparam.element != choice_ECParameters_namedCurve) {
|
||||||
|
free_ECParameters(&ecparam);
|
||||||
|
return HX509_CRYPTO_SIG_INVALID_FORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
*nid = heim_oid2ecnid(&ecparam.u.namedCurve);
|
||||||
|
free_ECParameters(&ecparam);
|
||||||
|
if (*nid == -1)
|
||||||
|
return HX509_CRYPTO_SIG_INVALID_FORMAT;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -298,7 +338,6 @@ ecdsa_verify_signature(hx509_context context,
|
|||||||
int ret;
|
int ret;
|
||||||
EC_KEY *key = NULL;
|
EC_KEY *key = NULL;
|
||||||
size_t size;
|
size_t size;
|
||||||
ECParameters ecparam;
|
|
||||||
int groupnid;
|
int groupnid;
|
||||||
EC_GROUP *group;
|
EC_GROUP *group;
|
||||||
const unsigned char *p;
|
const unsigned char *p;
|
||||||
@@ -327,38 +366,12 @@ ecdsa_verify_signature(hx509_context context,
|
|||||||
* Find the group id
|
* Find the group id
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ret = decode_ECParameters(spi->algorithm.parameters->data,
|
ret = parse_ECParameters(spi->algorithm.parameters, &groupnid);
|
||||||
spi->algorithm.parameters->length,
|
|
||||||
&ecparam, &size);
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
der_free_octet_string(&digest);
|
der_free_octet_string(&digest);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ecparam.element != choice_ECParameters_namedCurve) {
|
|
||||||
der_free_octet_string(&digest);
|
|
||||||
free_ECParameters(&ecparam);
|
|
||||||
return HX509_CRYPTO_SIG_INVALID_FORMAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now map to openssl OID fun
|
|
||||||
*/
|
|
||||||
groupnid = -1;
|
|
||||||
|
|
||||||
if (der_heim_oid_cmp(&ecparam.u.namedCurve, &asn1_oid_id_ec_group_secp256r1) == 0)
|
|
||||||
groupnid = NID_X9_62_prime256v1;
|
|
||||||
else if (der_heim_oid_cmp(&ecparam.u.namedCurve, &asn1_oid_id_ec_group_secp160r1) == 0)
|
|
||||||
groupnid = NID_secp160r1;
|
|
||||||
else if (der_heim_oid_cmp(&ecparam.u.namedCurve, &asn1_oid_id_ec_group_secp160r2) == 0)
|
|
||||||
groupnid = NID_secp160r2;
|
|
||||||
|
|
||||||
free_ECParameters(&ecparam);
|
|
||||||
if (groupnid == -1) {
|
|
||||||
der_free_octet_string(&digest);
|
|
||||||
return HX509_CRYPTO_SIG_INVALID_FORMAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create group, key, parse key
|
* Create group, key, parse key
|
||||||
*/
|
*/
|
||||||
@@ -740,6 +753,7 @@ rsa_create_signature(hx509_context context,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
rsa_private_key_import(hx509_context context,
|
rsa_private_key_import(hx509_context context,
|
||||||
|
const AlgorithmIdentifier *keyai,
|
||||||
const void *data,
|
const void *data,
|
||||||
size_t len,
|
size_t len,
|
||||||
hx509_private_key private_key)
|
hx509_private_key private_key)
|
||||||
@@ -916,14 +930,43 @@ ecdsa_private_key_export(hx509_context context,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
ecdsa_private_key_import(hx509_context context,
|
ecdsa_private_key_import(hx509_context context,
|
||||||
|
const AlgorithmIdentifier *keyai,
|
||||||
const void *data,
|
const void *data,
|
||||||
size_t len,
|
size_t len,
|
||||||
hx509_private_key private_key)
|
hx509_private_key private_key)
|
||||||
{
|
{
|
||||||
const unsigned char *p = data;
|
const unsigned char *p = data;
|
||||||
|
EC_GROUP *group;
|
||||||
|
EC_KEY *key;
|
||||||
|
int groupnid;
|
||||||
|
int ret;
|
||||||
|
|
||||||
private_key->private_key.ecdsa =
|
if (keyai->parameters == NULL)
|
||||||
d2i_ECPrivateKey(NULL, &p, len);
|
return HX509_PARSING_KEY_FAILED;
|
||||||
|
|
||||||
|
ret = parse_ECParameters(keyai->parameters, &groupnid);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
key = EC_KEY_new();
|
||||||
|
if (key == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
|
||||||
|
group = EC_GROUP_new_by_curve_name(groupnid);
|
||||||
|
if (group == NULL) {
|
||||||
|
EC_KEY_free(key);
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
|
||||||
|
if (EC_KEY_set_group(key, group) == 0) {
|
||||||
|
EC_KEY_free(key);
|
||||||
|
EC_GROUP_free(group);
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
EC_GROUP_free(group);
|
||||||
|
|
||||||
|
|
||||||
|
private_key->private_key.ecdsa = d2i_ECPrivateKey(&key, &p, len);
|
||||||
if (private_key->private_key.ecdsa == NULL) {
|
if (private_key->private_key.ecdsa == NULL) {
|
||||||
hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
|
hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
|
||||||
"Failed to parse EC private key");
|
"Failed to parse EC private key");
|
||||||
@@ -1769,7 +1812,7 @@ _hx509_private_key_private_decrypt(hx509_context context,
|
|||||||
|
|
||||||
int
|
int
|
||||||
_hx509_parse_private_key(hx509_context context,
|
_hx509_parse_private_key(hx509_context context,
|
||||||
const heim_oid *key_oid,
|
const AlgorithmIdentifier *keyai,
|
||||||
const void *data,
|
const void *data,
|
||||||
size_t len,
|
size_t len,
|
||||||
hx509_private_key *private_key)
|
hx509_private_key *private_key)
|
||||||
@@ -1779,7 +1822,7 @@ _hx509_parse_private_key(hx509_context context,
|
|||||||
|
|
||||||
*private_key = NULL;
|
*private_key = NULL;
|
||||||
|
|
||||||
ops = find_private_alg(key_oid);
|
ops = find_private_alg(&keyai->algorithm);
|
||||||
if (ops == NULL) {
|
if (ops == NULL) {
|
||||||
hx509_clear_error_string(context);
|
hx509_clear_error_string(context);
|
||||||
return HX509_SIG_ALG_NO_SUPPORTED;
|
return HX509_SIG_ALG_NO_SUPPORTED;
|
||||||
@@ -1791,7 +1834,7 @@ _hx509_parse_private_key(hx509_context context,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = (*ops->import)(context, data, len, *private_key);
|
ret = (*ops->import)(context, keyai, data, len, *private_key);
|
||||||
if (ret)
|
if (ret)
|
||||||
_hx509_private_key_free(private_key);
|
_hx509_private_key_free(private_key);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user