First drop of EC support.
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@24637 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -83,6 +83,9 @@ struct hx509_private_key {
|
||||
union {
|
||||
RSA *rsa;
|
||||
void *keydata;
|
||||
#ifdef HAVE_OPENSSL
|
||||
EC_KEY *ecdsa;
|
||||
#endif
|
||||
} private_key;
|
||||
/* new crypto layer */
|
||||
hx509_private_key_ops *ops;
|
||||
@@ -175,6 +178,181 @@ set_digest_alg(DigestAlgorithmIdentifier *id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
static int
|
||||
ecdsa_verify_signature(hx509_context context,
|
||||
const struct signature_alg *sig_alg,
|
||||
const Certificate *signer,
|
||||
const AlgorithmIdentifier *alg,
|
||||
const heim_octet_string *data,
|
||||
const heim_octet_string *sig)
|
||||
{
|
||||
const SubjectPublicKeyInfo *spi;
|
||||
heim_octet_string digest;
|
||||
int ret;
|
||||
EC_KEY *key = NULL;
|
||||
size_t size;
|
||||
ECParameters ecparam;
|
||||
int groupnid;
|
||||
EC_GROUP *group;
|
||||
const unsigned char *p;
|
||||
long len;
|
||||
const AlgorithmIdentifier *digest_alg;
|
||||
|
||||
if (der_heim_oid_cmp((*sig_alg->sig_oid)(),
|
||||
oid_id_ecdsa_with_SHA256()) == 0) {
|
||||
digest_alg = hx509_signature_sha256();
|
||||
} else
|
||||
return HX509_ALG_NOT_SUPP;
|
||||
|
||||
ret = _hx509_create_signature(context,
|
||||
NULL,
|
||||
digest_alg,
|
||||
data,
|
||||
NULL,
|
||||
&digest);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* set up EC KEY */
|
||||
spi = &signer->tbsCertificate.subjectPublicKeyInfo;
|
||||
|
||||
if (der_heim_oid_cmp(&spi->algorithm.algorithm, oid_id_ecPublicKey()) != 0 ||
|
||||
spi->algorithm.parameters == NULL)
|
||||
return HX509_CRYPTO_SIG_INVALID_FORMAT;
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
/*
|
||||
* Find the group id
|
||||
*/
|
||||
|
||||
ret = decode_ECParameters(spi->algorithm.parameters->data,
|
||||
spi->algorithm.parameters->length,
|
||||
&ecparam, &size);
|
||||
if (ret) {
|
||||
der_free_octet_string(&digest);
|
||||
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, oid_id_ec_group_secp256r1()) == 0)
|
||||
groupnid = NID_X9_62_prime256v1;
|
||||
|
||||
free_ECParameters(&ecparam);
|
||||
if (groupnid == -1) {
|
||||
der_free_octet_string(&digest);
|
||||
return HX509_CRYPTO_SIG_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
key = EC_KEY_new();
|
||||
group = EC_GROUP_new_by_curve_name(groupnid);
|
||||
EC_KEY_set_group(key, group);
|
||||
EC_GROUP_free(group);
|
||||
|
||||
p = spi->subjectPublicKey.data;
|
||||
len = spi->subjectPublicKey.length;
|
||||
|
||||
if (o2i_ECPublicKey(&key, &p, len) == NULL) {
|
||||
EC_KEY_free(key);
|
||||
return HX509_CRYPTO_SIG_INVALID_FORMAT;
|
||||
}
|
||||
#else
|
||||
key = SubjectPublicKeyInfo2EC_KEY(spi);
|
||||
#endif
|
||||
|
||||
ret = ECDSA_verify(-1, digest.data, digest.length,
|
||||
sig->data, sig->length, key);
|
||||
der_free_octet_string(&digest);
|
||||
EC_KEY_free(key);
|
||||
if (ret != 1) {
|
||||
ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
ecdsa_create_signature(hx509_context context,
|
||||
const struct signature_alg *sig_alg,
|
||||
const hx509_private_key signer,
|
||||
const AlgorithmIdentifier *alg,
|
||||
const heim_octet_string *data,
|
||||
AlgorithmIdentifier *signatureAlgorithm,
|
||||
heim_octet_string *sig)
|
||||
{
|
||||
const AlgorithmIdentifier *digest_alg;
|
||||
heim_octet_string indata;
|
||||
const heim_oid *sig_oid;
|
||||
unsigned int siglen;
|
||||
int ret;
|
||||
|
||||
sig_oid = (*sig_alg->sig_oid)();
|
||||
|
||||
if (der_heim_oid_cmp(sig_oid, oid_id_ecdsa_with_SHA256()) == 0) {
|
||||
digest_alg = hx509_signature_sha256();
|
||||
} else
|
||||
return HX509_ALG_NOT_SUPP;
|
||||
|
||||
if (signatureAlgorithm) {
|
||||
ret = set_digest_alg(signatureAlgorithm, sig_oid, "\x05\x00", 2);
|
||||
if (ret) {
|
||||
hx509_clear_error_string(context);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = _hx509_create_signature(context,
|
||||
NULL,
|
||||
digest_alg,
|
||||
data,
|
||||
NULL,
|
||||
&indata);
|
||||
|
||||
sig->length = ECDSA_size(signer->private_key.ecdsa);
|
||||
sig->data = malloc(sig->length);
|
||||
if (sig->data == NULL) {
|
||||
der_free_octet_string(&indata);
|
||||
hx509_set_error_string(context, 0, ENOMEM, "out of memory");
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
siglen = sig->length;
|
||||
|
||||
ret = ECDSA_sign(-1, indata.data, indata.length,
|
||||
sig->data, &siglen, signer->private_key.ecdsa);
|
||||
der_free_octet_string(&indata);
|
||||
if (ret != 1) {
|
||||
ret = HX509_CMS_FAILED_CREATE_SIGATURE;
|
||||
hx509_set_error_string(context, 0, ret,
|
||||
"RSA private decrypt failed: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
if (siglen > sig->length)
|
||||
_hx509_abort("RSA signature prelen longer the output len");
|
||||
|
||||
sig->length = ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
@@ -862,6 +1040,22 @@ md2_verify_signature(hx509_context context,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
static const struct signature_alg ecdsa_with_sha256_alg = {
|
||||
"ecdsa-with-sha256",
|
||||
oid_id_ecdsa_with_SHA256,
|
||||
hx509_signature_ecdsa_with_sha256,
|
||||
oid_id_ecPublicKey,
|
||||
oid_id_sha256,
|
||||
PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
|
||||
0,
|
||||
ecdsa_verify_signature,
|
||||
ecdsa_create_signature
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
static const struct signature_alg heim_rsa_pkcs1_x509 = {
|
||||
"rsa-pkcs1-x509",
|
||||
oid_id_heim_rsa_pkcs1_x509,
|
||||
@@ -998,6 +1192,9 @@ static const struct signature_alg md2_alg = {
|
||||
*/
|
||||
|
||||
static const struct signature_alg *sig_algs[] = {
|
||||
#ifdef HAVE_OPENSSL
|
||||
&ecdsa_with_sha256_alg,
|
||||
#endif
|
||||
&rsa_with_sha256_alg,
|
||||
&rsa_with_sha1_alg,
|
||||
&pkcs1_rsa_sha1_alg,
|
||||
@@ -1464,6 +1661,11 @@ const AlgorithmIdentifier _hx509_signature_md2_data = {
|
||||
{ 6, rk_UNCONST(md2_oid_tree) }, rk_UNCONST(&null_entry_oid)
|
||||
};
|
||||
|
||||
static const unsigned ecdsa_with_sha256_oid[] ={ 1, 2, 840, 10045, 4, 3, 2 };
|
||||
const AlgorithmIdentifier _hx509_signature_ecdsa_with_sha256_data = {
|
||||
{ 7, rk_UNCONST(ecdsa_with_sha256_oid) }, NULL
|
||||
};
|
||||
|
||||
static const unsigned rsa_with_sha512_oid[] ={ 1, 2, 840, 113549, 1, 1, 13 };
|
||||
const AlgorithmIdentifier _hx509_signature_rsa_with_sha512_data = {
|
||||
{ 7, rk_UNCONST(rsa_with_sha512_oid) }, NULL
|
||||
@@ -1543,6 +1745,10 @@ const AlgorithmIdentifier *
|
||||
hx509_signature_md2(void)
|
||||
{ return &_hx509_signature_md2_data; }
|
||||
|
||||
const AlgorithmIdentifier *
|
||||
hx509_signature_ecdsa_with_sha256(void)
|
||||
{ return &_hx509_signature_ecdsa_with_sha256_data; }
|
||||
|
||||
const AlgorithmIdentifier *
|
||||
hx509_signature_rsa_with_sha512(void)
|
||||
{ return &_hx509_signature_rsa_with_sha512_data; }
|
||||
|
Reference in New Issue
Block a user