summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/hx509/crypto.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/heimdal/lib/hx509/crypto.c')
-rw-r--r--source4/heimdal/lib/hx509/crypto.c995
1 files changed, 763 insertions, 232 deletions
diff --git a/source4/heimdal/lib/hx509/crypto.c b/source4/heimdal/lib/hx509/crypto.c
index 4a8ec8f756..8063100717 100644
--- a/source4/heimdal/lib/hx509/crypto.c
+++ b/source4/heimdal/lib/hx509/crypto.c
@@ -32,7 +32,6 @@
*/
#include "hx_locl.h"
-RCSID("$Id$");
struct hx509_crypto;
@@ -50,40 +49,21 @@ struct hx509_generate_private_context {
struct hx509_private_key_ops {
const char *pemtype;
- const heim_oid *(*key_oid)(void);
+ const heim_oid *key_oid;
+ int (*available)(const hx509_private_key,
+ const AlgorithmIdentifier *);
int (*get_spki)(hx509_context,
const hx509_private_key,
SubjectPublicKeyInfo *);
int (*export)(hx509_context context,
const hx509_private_key,
heim_octet_string *);
- int (*import)(hx509_context,
- const void *data,
- size_t len,
- hx509_private_key private_key);
+ int (*import)(hx509_context, const AlgorithmIdentifier *,
+ const void *, size_t, hx509_private_key);
int (*generate_private_key)(hx509_context,
struct hx509_generate_private_context *,
hx509_private_key);
BIGNUM *(*get_internal)(hx509_context, hx509_private_key, const char *);
- int (*handle_alg)(const hx509_private_key,
- const AlgorithmIdentifier *,
- enum crypto_op_type);
- int (*sign)(hx509_context context,
- const hx509_private_key,
- const AlgorithmIdentifier *,
- const heim_octet_string *,
- AlgorithmIdentifier *,
- heim_octet_string *);
-#if 0
- const AlgorithmIdentifier *(*preferred_sig_alg)
- (const hx509_private_key,
- const hx509_peer_info);
- int (*unwrap)(hx509_context context,
- const hx509_private_key,
- const AlgorithmIdentifier *,
- const heim_octet_string *,
- heim_octet_string *);
-#endif
};
struct hx509_private_key {
@@ -93,8 +73,10 @@ 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;
};
@@ -104,10 +86,10 @@ struct hx509_private_key {
struct signature_alg {
const char *name;
- const heim_oid *(*sig_oid)(void);
- const AlgorithmIdentifier *(*sig_alg)(void);
- const heim_oid *(*key_oid)(void);
- const heim_oid *(*digest_oid)(void);
+ const heim_oid *sig_oid;
+ const AlgorithmIdentifier *sig_alg;
+ const heim_oid *key_oid;
+ const AlgorithmIdentifier *digest_alg;
int flags;
#define PROVIDE_CONF 1
#define REQUIRE_SIGNER 2
@@ -118,7 +100,7 @@ struct signature_alg {
#define RA_RSA_USES_DIGEST_INFO 0x1000000
-
+ time_t best_before; /* refuse signature made after best before date */
int (*verify_signature)(hx509_context context,
const struct signature_alg *,
const Certificate *,
@@ -132,6 +114,116 @@ struct signature_alg {
const heim_octet_string *,
AlgorithmIdentifier *,
heim_octet_string *);
+ int digest_size;
+};
+
+static const struct signature_alg *
+find_sig_alg(const heim_oid *oid);
+
+/*
+ *
+ */
+
+static const heim_octet_string null_entry_oid = { 2, rk_UNCONST("\x05\x00") };
+
+static const unsigned sha512_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 3 };
+const AlgorithmIdentifier _hx509_signature_sha512_data = {
+ { 9, rk_UNCONST(sha512_oid_tree) }, rk_UNCONST(&null_entry_oid)
+};
+
+static const unsigned sha384_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 2 };
+const AlgorithmIdentifier _hx509_signature_sha384_data = {
+ { 9, rk_UNCONST(sha384_oid_tree) }, rk_UNCONST(&null_entry_oid)
+};
+
+static const unsigned sha256_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 1 };
+const AlgorithmIdentifier _hx509_signature_sha256_data = {
+ { 9, rk_UNCONST(sha256_oid_tree) }, rk_UNCONST(&null_entry_oid)
+};
+
+static const unsigned sha1_oid_tree[] = { 1, 3, 14, 3, 2, 26 };
+const AlgorithmIdentifier _hx509_signature_sha1_data = {
+ { 6, rk_UNCONST(sha1_oid_tree) }, rk_UNCONST(&null_entry_oid)
+};
+
+static const unsigned md5_oid_tree[] = { 1, 2, 840, 113549, 2, 5 };
+const AlgorithmIdentifier _hx509_signature_md5_data = {
+ { 6, rk_UNCONST(md5_oid_tree) }, rk_UNCONST(&null_entry_oid)
+};
+
+static const unsigned md2_oid_tree[] = { 1, 2, 840, 113549, 2, 2 };
+const AlgorithmIdentifier _hx509_signature_md2_data = {
+ { 6, rk_UNCONST(md2_oid_tree) }, rk_UNCONST(&null_entry_oid)
+};
+
+static const unsigned ecPublicKey[] ={ 1, 2, 840, 10045, 2, 1 };
+const AlgorithmIdentifier _hx509_signature_ecPublicKey = {
+ { 6, rk_UNCONST(ecPublicKey) }, NULL
+};
+
+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 ecdsa_with_sha1_oid[] ={ 1, 2, 840, 10045, 4, 1 };
+const AlgorithmIdentifier _hx509_signature_ecdsa_with_sha1_data = {
+ { 6, rk_UNCONST(ecdsa_with_sha1_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
+};
+
+static const unsigned rsa_with_sha384_oid[] ={ 1, 2, 840, 113549, 1, 1, 12 };
+const AlgorithmIdentifier _hx509_signature_rsa_with_sha384_data = {
+ { 7, rk_UNCONST(rsa_with_sha384_oid) }, NULL
+};
+
+static const unsigned rsa_with_sha256_oid[] ={ 1, 2, 840, 113549, 1, 1, 11 };
+const AlgorithmIdentifier _hx509_signature_rsa_with_sha256_data = {
+ { 7, rk_UNCONST(rsa_with_sha256_oid) }, NULL
+};
+
+static const unsigned rsa_with_sha1_oid[] ={ 1, 2, 840, 113549, 1, 1, 5 };
+const AlgorithmIdentifier _hx509_signature_rsa_with_sha1_data = {
+ { 7, rk_UNCONST(rsa_with_sha1_oid) }, NULL
+};
+
+static const unsigned rsa_with_md5_oid[] ={ 1, 2, 840, 113549, 1, 1, 4 };
+const AlgorithmIdentifier _hx509_signature_rsa_with_md5_data = {
+ { 7, rk_UNCONST(rsa_with_md5_oid) }, NULL
+};
+
+static const unsigned rsa_with_md2_oid[] ={ 1, 2, 840, 113549, 1, 1, 2 };
+const AlgorithmIdentifier _hx509_signature_rsa_with_md2_data = {
+ { 7, rk_UNCONST(rsa_with_md2_oid) }, NULL
+};
+
+static const unsigned rsa_oid[] ={ 1, 2, 840, 113549, 1, 1, 1 };
+const AlgorithmIdentifier _hx509_signature_rsa_data = {
+ { 7, rk_UNCONST(rsa_oid) }, NULL
+};
+
+static const unsigned rsa_pkcs1_x509_oid[] ={ 1, 2, 752, 43, 16, 1 };
+const AlgorithmIdentifier _hx509_signature_rsa_pkcs1_x509_data = {
+ { 6, rk_UNCONST(rsa_pkcs1_x509_oid) }, NULL
+};
+
+static const unsigned des_rsdi_ede3_cbc_oid[] ={ 1, 2, 840, 113549, 3, 7 };
+const AlgorithmIdentifier _hx509_des_rsdi_ede3_cbc_oid = {
+ { 6, rk_UNCONST(des_rsdi_ede3_cbc_oid) }, NULL
+};
+
+static const unsigned aes128_cbc_oid[] ={ 2, 16, 840, 1, 101, 3, 4, 1, 2 };
+const AlgorithmIdentifier _hx509_crypto_aes128_cbc_data = {
+ { 9, rk_UNCONST(aes128_cbc_oid) }, NULL
+};
+
+static const unsigned aes256_cbc_oid[] ={ 2, 16, 840, 1, 101, 3, 4, 1, 42 };
+const AlgorithmIdentifier _hx509_crypto_aes256_cbc_data = {
+ { 9, rk_UNCONST(aes256_cbc_oid) }, NULL
};
/*
@@ -184,6 +276,265 @@ set_digest_alg(DigestAlgorithmIdentifier *id,
return 0;
}
+#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(hx509_context context,
+ heim_octet_string *parameters, int *nid)
+{
+ ECParameters ecparam;
+ size_t size;
+ int ret;
+
+ if (parameters == NULL) {
+ ret = HX509_PARSING_KEY_FAILED;
+ hx509_set_error_string(context, 0, ret,
+ "EC parameters missing");
+ return ret;
+ }
+
+ ret = decode_ECParameters(parameters->data, parameters->length,
+ &ecparam, &size);
+ if (ret) {
+ hx509_set_error_string(context, 0, ret,
+ "Failed to decode EC parameters");
+ return ret;
+ }
+
+ if (ecparam.element != choice_ECParameters_namedCurve) {
+ free_ECParameters(&ecparam);
+ hx509_set_error_string(context, 0, ret,
+ "EC parameters is not a named curve");
+ return HX509_CRYPTO_SIG_INVALID_FORMAT;
+ }
+
+ *nid = heim_oid2ecnid(&ecparam.u.namedCurve);
+ free_ECParameters(&ecparam);
+ if (*nid == -1) {
+ hx509_set_error_string(context, 0, ret,
+ "Failed to find matcing NID for EC curve");
+ return HX509_CRYPTO_SIG_INVALID_FORMAT;
+ }
+ return 0;
+}
+
+
+/*
+ *
+ */
+
+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 AlgorithmIdentifier *digest_alg;
+ const SubjectPublicKeyInfo *spi;
+ heim_octet_string digest;
+ int ret;
+ EC_KEY *key = NULL;
+ int groupnid;
+ EC_GROUP *group;
+ const unsigned char *p;
+ long len;
+
+ digest_alg = sig_alg->digest_alg;
+
+ 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, &asn1_oid_id_ecPublicKey) != 0)
+ return HX509_CRYPTO_SIG_INVALID_FORMAT;
+
+#ifdef HAVE_OPENSSL
+ /*
+ * Find the group id
+ */
+
+ ret = parse_ECParameters(context, spi->algorithm.parameters, &groupnid);
+ if (ret) {
+ der_free_octet_string(&digest);
+ return ret;
+ }
+
+ /*
+ * Create group, key, parse key
+ */
+
+ 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 / 8;
+
+ 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 0;
+}
+
+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;
+
+ if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, &asn1_oid_id_ecPublicKey) != 0)
+ _hx509_abort("internal error passing private key to wrong ops");
+
+ sig_oid = sig_alg->sig_oid;
+ digest_alg = sig_alg->digest_alg;
+
+ if (signatureAlgorithm) {
+ ret = set_digest_alg(signatureAlgorithm, sig_oid, "\x05\x00", 2);
+ if (ret) {
+ hx509_clear_error_string(context);
+ goto error;
+ }
+ }
+
+ ret = _hx509_create_signature(context,
+ NULL,
+ digest_alg,
+ data,
+ NULL,
+ &indata);
+ if (ret) {
+ if (signatureAlgorithm)
+ free_AlgorithmIdentifier(signatureAlgorithm);
+ goto error;
+ }
+
+ sig->length = ECDSA_size(signer->private_key.ecdsa);
+ sig->data = malloc(sig->length);
+ if (sig->data == NULL) {
+ der_free_octet_string(&indata);
+ ret = ENOMEM;
+ hx509_set_error_string(context, 0, ret, "out of memory");
+ goto error;
+ }
+
+ 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,
+ "ECDSA sign failed: %d", ret);
+ goto error;
+ }
+ if (siglen > sig->length)
+ _hx509_abort("ECDSA signature prelen longer the output len");
+
+ sig->length = siglen;
+
+ return 0;
+ error:
+ if (signatureAlgorithm)
+ free_AlgorithmIdentifier(signatureAlgorithm);
+ return ret;
+}
+
+static int
+ecdsa_available(const hx509_private_key signer,
+ const AlgorithmIdentifier *sig_alg)
+{
+ const struct signature_alg *sig;
+ const EC_GROUP *group;
+ BN_CTX *bnctx = NULL;
+ BIGNUM *order = NULL;
+ int ret = 0;
+
+ if (der_heim_oid_cmp(signer->ops->key_oid, &asn1_oid_id_ecPublicKey) != 0)
+ _hx509_abort("internal error passing private key to wrong ops");
+
+ sig = find_sig_alg(&sig_alg->algorithm);
+
+ if (sig == NULL || sig->digest_size == 0)
+ return 0;
+
+ group = EC_KEY_get0_group(signer->private_key.ecdsa);
+ if (group == NULL)
+ return 0;
+
+ bnctx = BN_CTX_new();
+ order = BN_new();
+ if (order == NULL)
+ goto err;
+
+ if (EC_GROUP_get_order(group, order, bnctx) != 1)
+ goto err;
+
+ if (BN_num_bytes(order) > sig->digest_size)
+ ret = 1;
+ err:
+ if (bnctx)
+ BN_CTX_free(bnctx);
+ if (order)
+ BN_clear_free(order);
+
+ return ret;
+}
+
+
+#endif /* HAVE_OPENSSL */
+
/*
*
*/
@@ -268,9 +619,9 @@ rsa_verify_signature(hx509_context context,
goto out;
}
- if (sig_alg->digest_oid &&
+ if (sig_alg->digest_alg &&
der_heim_oid_cmp(&di.digestAlgorithm.algorithm,
- (*sig_alg->digest_oid)()) != 0)
+ &sig_alg->digest_alg->algorithm) != 0)
{
ret = HX509_CRYPTO_OID_MISMATCH;
hx509_set_error_string(context, 0, ret, "object identifier in RSA sig mismatch");
@@ -324,24 +675,27 @@ rsa_create_signature(hx509_context context,
size_t size;
int ret;
+ if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, &asn1_oid_id_pkcs1_rsaEncryption) != 0)
+ return HX509_ALG_NOT_SUPP;
+
if (alg)
sig_oid = &alg->algorithm;
else
sig_oid = signer->signature_alg;
- if (der_heim_oid_cmp(sig_oid, oid_id_pkcs1_sha256WithRSAEncryption()) == 0) {
+ if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_sha256WithRSAEncryption) == 0) {
digest_alg = hx509_signature_sha256();
- } else if (der_heim_oid_cmp(sig_oid, oid_id_pkcs1_sha1WithRSAEncryption()) == 0) {
+ } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_sha1WithRSAEncryption) == 0) {
digest_alg = hx509_signature_sha1();
- } else if (der_heim_oid_cmp(sig_oid, oid_id_pkcs1_md5WithRSAEncryption()) == 0) {
+ } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_md5WithRSAEncryption) == 0) {
digest_alg = hx509_signature_md5();
- } else if (der_heim_oid_cmp(sig_oid, oid_id_pkcs1_md5WithRSAEncryption()) == 0) {
+ } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_md5WithRSAEncryption) == 0) {
digest_alg = hx509_signature_md5();
- } else if (der_heim_oid_cmp(sig_oid, oid_id_dsa_with_sha1()) == 0) {
+ } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_dsa_with_sha1) == 0) {
digest_alg = hx509_signature_sha1();
- } else if (der_heim_oid_cmp(sig_oid, oid_id_pkcs1_rsaEncryption()) == 0) {
+ } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_rsaEncryption) == 0) {
digest_alg = hx509_signature_sha1();
- } else if (der_heim_oid_cmp(sig_oid, oid_id_heim_rsa_pkcs1_x509()) == 0) {
+ } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_heim_rsa_pkcs1_x509) == 0) {
digest_alg = NULL;
} else
return HX509_ALG_NOT_SUPP;
@@ -413,6 +767,7 @@ rsa_create_signature(hx509_context context,
static int
rsa_private_key_import(hx509_context context,
+ const AlgorithmIdentifier *keyai,
const void *data,
size_t len,
hx509_private_key private_key)
@@ -426,7 +781,7 @@ rsa_private_key_import(hx509_context context,
"Failed to parse RSA key");
return HX509_PARSING_KEY_FAILED;
}
- private_key->signature_alg = oid_id_pkcs1_sha1WithRSAEncryption();
+ private_key->signature_alg = &asn1_oid_id_pkcs1_sha1WithRSAEncryption;
return 0;
}
@@ -449,7 +804,7 @@ rsa_private_key2SPKI(hx509_context context,
}
spki->subjectPublicKey.length = len * 8;
- ret = set_digest_alg(&spki->algorithm,oid_id_pkcs1_rsaEncryption(),
+ ret = set_digest_alg(&spki->algorithm, &asn1_oid_id_pkcs1_rsaEncryption,
"\x05\x00", 2);
if (ret) {
hx509_set_error_string(context, 0, ret, "malloc - out of memory");
@@ -503,7 +858,7 @@ rsa_generate_private_key(hx509_context context,
"Failed to generate RSA key");
return HX509_PARSING_KEY_FAILED;
}
- private_key->signature_alg = oid_id_pkcs1_sha1WithRSAEncryption();
+ private_key->signature_alg = &asn1_oid_id_pkcs1_sha1WithRSAEncryption;
return 0;
}
@@ -543,7 +898,9 @@ rsa_private_key_export(hx509_context context,
}
static BIGNUM *
-rsa_get_internal(hx509_context context, hx509_private_key key, const char *type)
+rsa_get_internal(hx509_context context,
+ hx509_private_key key,
+ const char *type)
{
if (strcasecmp(type, "rsa-modulus") == 0) {
return BN_dup(key->private_key.rsa->n);
@@ -557,7 +914,8 @@ rsa_get_internal(hx509_context context, hx509_private_key key, const char *type)
static hx509_private_key_ops rsa_private_key_ops = {
"RSA PRIVATE KEY",
- oid_id_pkcs1_rsaEncryption,
+ &asn1_oid_id_pkcs1_rsaEncryption,
+ NULL,
rsa_private_key2SPKI,
rsa_private_key_export,
rsa_private_key_import,
@@ -565,6 +923,104 @@ static hx509_private_key_ops rsa_private_key_ops = {
rsa_get_internal
};
+#ifdef HAVE_OPENSSL
+
+static int
+ecdsa_private_key2SPKI(hx509_context context,
+ hx509_private_key private_key,
+ SubjectPublicKeyInfo *spki)
+{
+ memset(spki, 0, sizeof(*spki));
+ return ENOMEM;
+}
+
+static int
+ecdsa_private_key_export(hx509_context context,
+ const hx509_private_key key,
+ heim_octet_string *data)
+{
+ return ENOMEM;
+}
+
+static int
+ecdsa_private_key_import(hx509_context context,
+ const AlgorithmIdentifier *keyai,
+ const void *data,
+ size_t len,
+ hx509_private_key private_key)
+{
+ const unsigned char *p = data;
+ EC_KEY **pkey = NULL;
+
+ if (keyai->parameters) {
+ EC_GROUP *group;
+ int groupnid;
+ EC_KEY *key;
+ int ret;
+
+ ret = parse_ECParameters(context, 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);
+ pkey = &key;
+ }
+
+ private_key->private_key.ecdsa = d2i_ECPrivateKey(pkey, &p, len);
+ if (private_key->private_key.ecdsa == NULL) {
+ hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
+ "Failed to parse EC private key");
+ return HX509_PARSING_KEY_FAILED;
+ }
+ private_key->signature_alg = &asn1_oid_id_ecdsa_with_SHA256;
+
+ return 0;
+}
+
+static int
+ecdsa_generate_private_key(hx509_context context,
+ struct hx509_generate_private_context *ctx,
+ hx509_private_key private_key)
+{
+ return ENOMEM;
+}
+
+static BIGNUM *
+ecdsa_get_internal(hx509_context context,
+ hx509_private_key key,
+ const char *type)
+{
+ return NULL;
+}
+
+
+static hx509_private_key_ops ecdsa_private_key_ops = {
+ "EC PRIVATE KEY",
+ &asn1_oid_id_ecPublicKey,
+ ecdsa_available,
+ ecdsa_private_key2SPKI,
+ ecdsa_private_key_export,
+ ecdsa_private_key_import,
+ ecdsa_generate_private_key,
+ ecdsa_get_internal
+};
+
+#endif /* HAVE_OPENSSL */
/*
*
@@ -668,7 +1124,7 @@ dsa_parse_private_key(hx509_context context,
d2i_DSAPrivateKey(NULL, &p, len);
if (private_key->private_key.dsa == NULL)
return EINVAL;
- private_key->signature_alg = oid_id_dsa_with_sha1();
+ private_key->signature_alg = &asn1_oid_id_dsa_with_sha1;
return 0;
/* else */
@@ -724,7 +1180,7 @@ sha256_create_signature(hx509_context context,
if (signatureAlgorithm) {
int ret;
- ret = set_digest_alg(signatureAlgorithm, (*sig_alg->sig_oid)(),
+ ret = set_digest_alg(signatureAlgorithm, sig_alg->sig_oid,
"\x05\x00", 2);
if (ret)
return ret;
@@ -790,7 +1246,7 @@ sha1_create_signature(hx509_context context,
if (signatureAlgorithm) {
int ret;
- ret = set_digest_alg(signatureAlgorithm, (*sig_alg->sig_oid)(),
+ ret = set_digest_alg(signatureAlgorithm, sig_alg->sig_oid,
"\x05\x00", 2);
if (ret)
return ret;
@@ -871,131 +1327,176 @@ md2_verify_signature(hx509_context context,
return 0;
}
+#ifdef HAVE_OPENSSL
+
+static const struct signature_alg ecdsa_with_sha256_alg = {
+ "ecdsa-with-sha256",
+ &asn1_oid_id_ecdsa_with_SHA256,
+ &_hx509_signature_ecdsa_with_sha256_data,
+ &asn1_oid_id_ecPublicKey,
+ &_hx509_signature_sha256_data,
+ PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
+ 0,
+ ecdsa_verify_signature,
+ ecdsa_create_signature,
+ 32
+};
+
+static const struct signature_alg ecdsa_with_sha1_alg = {
+ "ecdsa-with-sha1",
+ &asn1_oid_id_ecdsa_with_SHA1,
+ &_hx509_signature_ecdsa_with_sha1_data,
+ &asn1_oid_id_ecPublicKey,
+ &_hx509_signature_sha1_data,
+ PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
+ 0,
+ ecdsa_verify_signature,
+ ecdsa_create_signature,
+ 20
+};
+
+#endif
+
static const struct signature_alg heim_rsa_pkcs1_x509 = {
"rsa-pkcs1-x509",
- oid_id_heim_rsa_pkcs1_x509,
- hx509_signature_rsa_pkcs1_x509,
- oid_id_pkcs1_rsaEncryption,
+ &asn1_oid_id_heim_rsa_pkcs1_x509,
+ &_hx509_signature_rsa_pkcs1_x509_data,
+ &asn1_oid_id_pkcs1_rsaEncryption,
NULL,
PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
+ 0,
rsa_verify_signature,
rsa_create_signature
};
static const struct signature_alg pkcs1_rsa_sha1_alg = {
"rsa",
- oid_id_pkcs1_rsaEncryption,
- hx509_signature_rsa_with_sha1,
- oid_id_pkcs1_rsaEncryption,
+ &asn1_oid_id_pkcs1_rsaEncryption,
+ &_hx509_signature_rsa_with_sha1_data,
+ &asn1_oid_id_pkcs1_rsaEncryption,
NULL,
PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
+ 0,
rsa_verify_signature,
rsa_create_signature
};
static const struct signature_alg rsa_with_sha256_alg = {
"rsa-with-sha256",
- oid_id_pkcs1_sha256WithRSAEncryption,
- hx509_signature_rsa_with_sha256,
- oid_id_pkcs1_rsaEncryption,
- oid_id_sha256,
+ &asn1_oid_id_pkcs1_sha256WithRSAEncryption,
+ &_hx509_signature_rsa_with_sha256_data,
+ &asn1_oid_id_pkcs1_rsaEncryption,
+ &_hx509_signature_sha256_data,
PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
+ 0,
rsa_verify_signature,
rsa_create_signature
};
static const struct signature_alg rsa_with_sha1_alg = {
"rsa-with-sha1",
- oid_id_pkcs1_sha1WithRSAEncryption,
- hx509_signature_rsa_with_sha1,
- oid_id_pkcs1_rsaEncryption,
- oid_id_secsig_sha_1,
+ &asn1_oid_id_pkcs1_sha1WithRSAEncryption,
+ &_hx509_signature_rsa_with_sha1_data,
+ &asn1_oid_id_pkcs1_rsaEncryption,
+ &_hx509_signature_sha1_data,
PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
+ 0,
rsa_verify_signature,
rsa_create_signature
};
static const struct signature_alg rsa_with_md5_alg = {
"rsa-with-md5",
- oid_id_pkcs1_md5WithRSAEncryption,
- hx509_signature_rsa_with_md5,
- oid_id_pkcs1_rsaEncryption,
- oid_id_rsa_digest_md5,
+ &asn1_oid_id_pkcs1_md5WithRSAEncryption,
+ &_hx509_signature_rsa_with_md5_data,
+ &asn1_oid_id_pkcs1_rsaEncryption,
+ &_hx509_signature_md5_data,
PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
+ 1230739889,
rsa_verify_signature,
rsa_create_signature
};
static const struct signature_alg rsa_with_md2_alg = {
"rsa-with-md2",
- oid_id_pkcs1_md2WithRSAEncryption,
- hx509_signature_rsa_with_md2,
- oid_id_pkcs1_rsaEncryption,
- oid_id_rsa_digest_md2,
+ &asn1_oid_id_pkcs1_md2WithRSAEncryption,
+ &_hx509_signature_rsa_with_md2_data,
+ &asn1_oid_id_pkcs1_rsaEncryption,
+ &_hx509_signature_md2_data,
PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
+ 1230739889,
rsa_verify_signature,
rsa_create_signature
};
static const struct signature_alg dsa_sha1_alg = {
"dsa-with-sha1",
- oid_id_dsa_with_sha1,
+ &asn1_oid_id_dsa_with_sha1,
NULL,
- oid_id_dsa,
- oid_id_secsig_sha_1,
+ &asn1_oid_id_dsa,
+ &_hx509_signature_sha1_data,
PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
+ 0,
dsa_verify_signature,
/* create_signature */ NULL,
};
static const struct signature_alg sha256_alg = {
"sha-256",
- oid_id_sha256,
- hx509_signature_sha256,
+ &asn1_oid_id_sha256,
+ &_hx509_signature_sha256_data,
NULL,
NULL,
SIG_DIGEST,
+ 0,
sha256_verify_signature,
sha256_create_signature
};
static const struct signature_alg sha1_alg = {
"sha1",
- oid_id_secsig_sha_1,
- hx509_signature_sha1,
+ &asn1_oid_id_secsig_sha_1,
+ &_hx509_signature_sha1_data,
NULL,
NULL,
SIG_DIGEST,
+ 0,
sha1_verify_signature,
sha1_create_signature
};
static const struct signature_alg md5_alg = {
"rsa-md5",
- oid_id_rsa_digest_md5,
- hx509_signature_md5,
+ &asn1_oid_id_rsa_digest_md5,
+ &_hx509_signature_md5_data,
NULL,
NULL,
SIG_DIGEST,
+ 0,
md5_verify_signature
};
static const struct signature_alg md2_alg = {
"rsa-md2",
- oid_id_rsa_digest_md2,
- hx509_signature_md2,
+ &asn1_oid_id_rsa_digest_md2,
+ &_hx509_signature_md2_data,
NULL,
NULL,
SIG_DIGEST,
+ 0,
md2_verify_signature
};
/*
* Order matter in this structure, "best" first for each "key
- * compatible" type (type is RSA, DSA, none, etc)
+ * compatible" type (type is ECDSA, RSA, DSA, none, etc)
*/
static const struct signature_alg *sig_algs[] = {
+#ifdef HAVE_OPENSSL
+ &ecdsa_with_sha256_alg,
+ &ecdsa_with_sha1_alg,
+#endif
&rsa_with_sha256_alg,
&rsa_with_sha1_alg,
&pkcs1_rsa_sha1_alg,
@@ -1013,19 +1514,51 @@ static const struct signature_alg *sig_algs[] = {
static const struct signature_alg *
find_sig_alg(const heim_oid *oid)
{
- int i;
+ unsigned int i;
for (i = 0; sig_algs[i]; i++)
- if (der_heim_oid_cmp((*sig_algs[i]->sig_oid)(), oid) == 0)
+ if (der_heim_oid_cmp(sig_algs[i]->sig_oid, oid) == 0)
return sig_algs[i];
return NULL;
}
+static const AlgorithmIdentifier *
+alg_for_privatekey(const hx509_private_key pk, int type)
+{
+ const heim_oid *keytype;
+ unsigned int i;
+
+ if (pk->ops == NULL)
+ return NULL;
+
+ keytype = pk->ops->key_oid;
+
+ for (i = 0; sig_algs[i]; i++) {
+ if (sig_algs[i]->key_oid == NULL)
+ continue;
+ if (der_heim_oid_cmp(sig_algs[i]->key_oid, keytype) != 0)
+ continue;
+ if (pk->ops->available &&
+ pk->ops->available(pk, sig_algs[i]->sig_alg) == 0)
+ continue;
+ if (type == HX509_SELECT_PUBLIC_SIG)
+ return sig_algs[i]->sig_alg;
+ if (type == HX509_SELECT_DIGEST)
+ return sig_algs[i]->digest_alg;
+
+ return NULL;
+ }
+ return NULL;
+}
+
/*
*
*/
static struct hx509_private_key_ops *private_algs[] = {
&rsa_private_key_ops,
+#ifdef HAVE_OPENSSL
+ &ecdsa_private_key_ops,
+#endif
NULL
};
@@ -1036,12 +1569,37 @@ find_private_alg(const heim_oid *oid)
for (i = 0; private_algs[i]; i++) {
if (private_algs[i]->key_oid == NULL)
continue;
- if (der_heim_oid_cmp((*private_algs[i]->key_oid)(), oid) == 0)
+ if (der_heim_oid_cmp(private_algs[i]->key_oid, oid) == 0)
return private_algs[i];
}
return NULL;
}
+/*
+ * Check if the algorithm `alg' have a best before date, and if it
+ * des, make sure the its before the time `t'.
+ */
+
+int
+_hx509_signature_best_before(hx509_context context,
+ const AlgorithmIdentifier *alg,
+ time_t t)
+{
+ const struct signature_alg *md;
+
+ md = find_sig_alg(&alg->algorithm);
+ if (md == NULL) {
+ hx509_clear_error_string(context);
+ return HX509_SIG_ALG_NO_SUPPORTED;
+ }
+ if (md->best_before && md->best_before < t) {
+ hx509_set_error_string(context, 0, HX509_CRYPTO_ALGORITHM_BEST_BEFORE,
+ "Algorithm %s has passed it best before date",
+ md->name);
+ return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
+ }
+ return 0;
+}
int
_hx509_verify_signature(hx509_context context,
@@ -1069,7 +1627,7 @@ _hx509_verify_signature(hx509_context context,
const SubjectPublicKeyInfo *spi;
spi = &signer->tbsCertificate.subjectPublicKeyInfo;
- if (der_heim_oid_cmp(&spi->algorithm.algorithm, (*md->key_oid)()) != 0) {
+ if (der_heim_oid_cmp(&spi->algorithm.algorithm, md->key_oid) != 0) {
hx509_clear_error_string(context);
return HX509_SIG_ALG_DONT_MATCH_KEY_ALG;
}
@@ -1108,13 +1666,6 @@ _hx509_create_signature(hx509_context context,
{
const struct signature_alg *md;
- if (signer && signer->ops && signer->ops->handle_alg &&
- (*signer->ops->handle_alg)(signer, alg, COT_SIGN))
- {
- return (*signer->ops->sign)(context, signer, alg, data,
- signatureAlgorithm, sig);
- }
-
md = find_sig_alg(&alg->algorithm);
if (md == NULL) {
hx509_set_error_string(context, 0, HX509_SIG_ALG_NO_SUPPORTED,
@@ -1221,7 +1772,7 @@ _hx509_public_encrypt(hx509_context context,
ciphertext->length = ret;
ciphertext->data = to;
- ret = der_copy_oid(oid_id_pkcs1_rsaEncryption(), encryption_oid);
+ ret = der_copy_oid(&asn1_oid_id_pkcs1_rsaEncryption, encryption_oid);
if (ret) {
der_free_octet_string(ciphertext);
hx509_set_error_string(context, 0, ENOMEM, "out of memory");
@@ -1276,7 +1827,7 @@ _hx509_private_key_private_decrypt(hx509_context context,
int
_hx509_parse_private_key(hx509_context context,
- const heim_oid *key_oid,
+ const AlgorithmIdentifier *keyai,
const void *data,
size_t len,
hx509_private_key *private_key)
@@ -1286,7 +1837,7 @@ _hx509_parse_private_key(hx509_context context,
*private_key = NULL;
- ops = find_private_alg(key_oid);
+ ops = find_private_alg(&keyai->algorithm);
if (ops == NULL) {
hx509_clear_error_string(context);
return HX509_SIG_ALG_NO_SUPPORTED;
@@ -1298,7 +1849,7 @@ _hx509_parse_private_key(hx509_context context,
return ret;
}
- ret = (*ops->import)(context, data, len, *private_key);
+ ret = (*ops->import)(context, keyai, data, len, *private_key);
if (ret)
_hx509_private_key_free(private_key);
@@ -1330,7 +1881,7 @@ _hx509_generate_private_key_init(hx509_context context,
{
*ctx = NULL;
- if (der_heim_oid_cmp(oid, oid_id_pkcs1_rsaEncryption()) != 0) {
+ if (der_heim_oid_cmp(oid, &asn1_oid_id_pkcs1_rsaEncryption) != 0) {
hx509_set_error_string(context, 0, EINVAL,
"private key not an RSA key");
return EINVAL;
@@ -1400,98 +1951,10 @@ _hx509_generate_private_key(hx509_context context,
return ret;
}
-
/*
*
*/
-static const heim_octet_string null_entry_oid = { 2, rk_UNCONST("\x05\x00") };
-
-static const unsigned sha512_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 3 };
-const AlgorithmIdentifier _hx509_signature_sha512_data = {
- { 9, rk_UNCONST(sha512_oid_tree) }, rk_UNCONST(&null_entry_oid)
-};
-
-static const unsigned sha384_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 2 };
-const AlgorithmIdentifier _hx509_signature_sha384_data = {
- { 9, rk_UNCONST(sha384_oid_tree) }, rk_UNCONST(&null_entry_oid)
-};
-
-static const unsigned sha256_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 1 };
-const AlgorithmIdentifier _hx509_signature_sha256_data = {
- { 9, rk_UNCONST(sha256_oid_tree) }, rk_UNCONST(&null_entry_oid)
-};
-
-static const unsigned sha1_oid_tree[] = { 1, 3, 14, 3, 2, 26 };
-const AlgorithmIdentifier _hx509_signature_sha1_data = {
- { 6, rk_UNCONST(sha1_oid_tree) }, rk_UNCONST(&null_entry_oid)
-};
-
-static const unsigned md5_oid_tree[] = { 1, 2, 840, 113549, 2, 5 };
-const AlgorithmIdentifier _hx509_signature_md5_data = {
- { 6, rk_UNCONST(md5_oid_tree) }, rk_UNCONST(&null_entry_oid)
-};
-
-static const unsigned md2_oid_tree[] = { 1, 2, 840, 113549, 2, 2 };
-const AlgorithmIdentifier _hx509_signature_md2_data = {
- { 6, rk_UNCONST(md2_oid_tree) }, rk_UNCONST(&null_entry_oid)
-};
-
-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
-};
-
-static const unsigned rsa_with_sha384_oid[] ={ 1, 2, 840, 113549, 1, 1, 12 };
-const AlgorithmIdentifier _hx509_signature_rsa_with_sha384_data = {
- { 7, rk_UNCONST(rsa_with_sha384_oid) }, NULL
-};
-
-static const unsigned rsa_with_sha256_oid[] ={ 1, 2, 840, 113549, 1, 1, 11 };
-const AlgorithmIdentifier _hx509_signature_rsa_with_sha256_data = {
- { 7, rk_UNCONST(rsa_with_sha256_oid) }, NULL
-};
-
-static const unsigned rsa_with_sha1_oid[] ={ 1, 2, 840, 113549, 1, 1, 5 };
-const AlgorithmIdentifier _hx509_signature_rsa_with_sha1_data = {
- { 7, rk_UNCONST(rsa_with_sha1_oid) }, NULL
-};
-
-static const unsigned rsa_with_md5_oid[] ={ 1, 2, 840, 113549, 1, 1, 4 };
-const AlgorithmIdentifier _hx509_signature_rsa_with_md5_data = {
- { 7, rk_UNCONST(rsa_with_md5_oid) }, NULL
-};
-
-static const unsigned rsa_with_md2_oid[] ={ 1, 2, 840, 113549, 1, 1, 2 };
-const AlgorithmIdentifier _hx509_signature_rsa_with_md2_data = {
- { 7, rk_UNCONST(rsa_with_md2_oid) }, NULL
-};
-
-static const unsigned rsa_oid[] ={ 1, 2, 840, 113549, 1, 1, 1 };
-const AlgorithmIdentifier _hx509_signature_rsa_data = {
- { 7, rk_UNCONST(rsa_oid) }, NULL
-};
-
-static const unsigned rsa_pkcs1_x509_oid[] ={ 1, 2, 752, 43, 16, 1 };
-const AlgorithmIdentifier _hx509_signature_rsa_pkcs1_x509_data = {
- { 6, rk_UNCONST(rsa_pkcs1_x509_oid) }, NULL
-};
-
-static const unsigned des_rsdi_ede3_cbc_oid[] ={ 1, 2, 840, 113549, 3, 7 };
-const AlgorithmIdentifier _hx509_des_rsdi_ede3_cbc_oid = {
- { 6, rk_UNCONST(des_rsdi_ede3_cbc_oid) }, NULL
-};
-
-static const unsigned aes128_cbc_oid[] ={ 2, 16, 840, 1, 101, 3, 4, 1, 2 };
-const AlgorithmIdentifier _hx509_crypto_aes128_cbc_data = {
- { 9, rk_UNCONST(aes128_cbc_oid) }, NULL
-};
-
-static const unsigned aes256_cbc_oid[] ={ 2, 16, 840, 1, 101, 3, 4, 1, 42 };
-const AlgorithmIdentifier _hx509_crypto_aes256_cbc_data = {
- { 9, rk_UNCONST(aes256_cbc_oid) }, NULL
-};
-
const AlgorithmIdentifier *
hx509_signature_sha512(void)
{ return &_hx509_signature_sha512_data; }
@@ -1517,6 +1980,18 @@ hx509_signature_md2(void)
{ return &_hx509_signature_md2_data; }
const AlgorithmIdentifier *
+hx509_signature_ecPublicKey(void)
+{ return &_hx509_signature_ecPublicKey; }
+
+const AlgorithmIdentifier *
+hx509_signature_ecdsa_with_sha256(void)
+{ return &_hx509_signature_ecdsa_with_sha256_data; }
+
+const AlgorithmIdentifier *
+hx509_signature_ecdsa_with_sha1(void)
+{ return &_hx509_signature_ecdsa_with_sha1_data; }
+
+const AlgorithmIdentifier *
hx509_signature_rsa_with_sha512(void)
{ return &_hx509_signature_rsa_with_sha512_data; }
@@ -1565,9 +2040,9 @@ hx509_crypto_aes256_cbc(void)
*/
const AlgorithmIdentifier * _hx509_crypto_default_sig_alg =
- &_hx509_signature_rsa_with_sha1_data;
+ &_hx509_signature_rsa_with_sha256_data;
const AlgorithmIdentifier * _hx509_crypto_default_digest_alg =
- &_hx509_signature_sha1_data;
+ &_hx509_signature_sha256_data;
const AlgorithmIdentifier * _hx509_crypto_default_secret_alg =
&_hx509_crypto_aes128_cbc_data;
@@ -1617,8 +2092,15 @@ _hx509_private_key_free(hx509_private_key *key)
if (--(*key)->ref > 0)
return 0;
- if ((*key)->private_key.rsa)
- RSA_free((*key)->private_key.rsa);
+ if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, &asn1_oid_id_pkcs1_rsaEncryption) == 0) {
+ if ((*key)->private_key.rsa)
+ RSA_free((*key)->private_key.rsa);
+#ifdef HAVE_OPENSSL
+ } else if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, &asn1_oid_id_ecPublicKey) == 0) {
+ if ((*key)->private_key.ecdsa)
+ EC_KEY_free((*key)->private_key.ecdsa);
+#endif
+ }
(*key)->private_key.rsa = NULL;
free(*key);
*key = NULL;
@@ -1631,7 +2113,7 @@ _hx509_private_key_assign_rsa(hx509_private_key key, void *ptr)
if (key->private_key.rsa)
RSA_free(key->private_key.rsa);
key->private_key.rsa = ptr;
- key->signature_alg = oid_id_pkcs1_sha1WithRSAEncryption();
+ key->signature_alg = &asn1_oid_id_pkcs1_sha1WithRSAEncryption;
key->md = &pkcs1_rsa_sha1_alg;
}
@@ -1641,7 +2123,7 @@ _hx509_private_key_oid(hx509_context context,
heim_oid *data)
{
int ret;
- ret = der_copy_oid((*key->ops->key_oid)(), data);
+ ret = der_copy_oid(key->ops->key_oid, data);
if (ret)
hx509_set_error_string(context, 0, ret, "malloc out of memory");
return ret;
@@ -1683,7 +2165,9 @@ _hx509_private_key_export(hx509_context context,
struct hx509cipher {
const char *name;
- const heim_oid *(*oid_func)(void);
+ int flags;
+#define CIPHER_WEAK 1
+ const heim_oid *oid;
const AlgorithmIdentifier *(*ai_func)(void);
const EVP_CIPHER *(*evp_func)(void);
int (*get_params)(hx509_context, const hx509_crypto,
@@ -1694,6 +2178,8 @@ struct hx509cipher {
struct hx509_crypto_data {
char *name;
+ int flags;
+#define ALLOW_WEAK 1
const struct hx509cipher *cipher;
const EVP_CIPHER *c;
heim_octet_string key;
@@ -1705,15 +2191,10 @@ struct hx509_crypto_data {
*
*/
-static const heim_oid *
-oid_private_rc2_40(void)
-{
- static unsigned oid_data[] = { 127, 1 };
- static const heim_oid oid = { 2, oid_data };
-
- return &oid;
-}
+static unsigned private_rc2_40_oid_data[] = { 127, 1 };
+static heim_oid asn1_oid_private_rc2_40 =
+ { 2, private_rc2_40_oid_data };
/*
*
@@ -1853,7 +2334,8 @@ CMSRC2CBCParam_set(hx509_context context, const heim_octet_string *param,
static const struct hx509cipher ciphers[] = {
{
"rc2-cbc",
- oid_id_pkcs3_rc2_cbc,
+ CIPHER_WEAK,
+ &asn1_oid_id_pkcs3_rc2_cbc,
NULL,
EVP_rc2_cbc,
CMSRC2CBCParam_get,
@@ -1861,7 +2343,8 @@ static const struct hx509cipher ciphers[] = {
},
{
"rc2-cbc",
- oid_id_rsadsi_rc2_cbc,
+ CIPHER_WEAK,
+ &asn1_oid_id_rsadsi_rc2_cbc,
NULL,
EVP_rc2_cbc,
CMSRC2CBCParam_get,
@@ -1869,7 +2352,8 @@ static const struct hx509cipher ciphers[] = {
},
{
"rc2-40-cbc",
- oid_private_rc2_40,
+ CIPHER_WEAK,
+ &asn1_oid_private_rc2_40,
NULL,
EVP_rc2_40_cbc,
CMSRC2CBCParam_get,
@@ -1877,7 +2361,8 @@ static const struct hx509cipher ciphers[] = {
},
{
"des-ede3-cbc",
- oid_id_pkcs3_des_ede3_cbc,
+ 0,
+ &asn1_oid_id_pkcs3_des_ede3_cbc,
NULL,
EVP_des_ede3_cbc,
CMSCBCParam_get,
@@ -1885,7 +2370,8 @@ static const struct hx509cipher ciphers[] = {
},
{
"des-ede3-cbc",
- oid_id_rsadsi_des_ede3_cbc,
+ 0,
+ &asn1_oid_id_rsadsi_des_ede3_cbc,
hx509_crypto_des_rsdi_ede3_cbc,
EVP_des_ede3_cbc,
CMSCBCParam_get,
@@ -1893,7 +2379,8 @@ static const struct hx509cipher ciphers[] = {
},
{
"aes-128-cbc",
- oid_id_aes_128_cbc,
+ 0,
+ &asn1_oid_id_aes_128_cbc,
hx509_crypto_aes128_cbc,
EVP_aes_128_cbc,
CMSCBCParam_get,
@@ -1901,7 +2388,8 @@ static const struct hx509cipher ciphers[] = {
},
{
"aes-192-cbc",
- oid_id_aes_192_cbc,
+ 0,
+ &asn1_oid_id_aes_192_cbc,
NULL,
EVP_aes_192_cbc,
CMSCBCParam_get,
@@ -1909,7 +2397,8 @@ static const struct hx509cipher ciphers[] = {
},
{
"aes-256-cbc",
- oid_id_aes_256_cbc,
+ 0,
+ &asn1_oid_id_aes_256_cbc,
hx509_crypto_aes256_cbc,
EVP_aes_256_cbc,
CMSCBCParam_get,
@@ -1923,7 +2412,7 @@ find_cipher_by_oid(const heim_oid *oid)
int i;
for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++)
- if (der_heim_oid_cmp(oid, (*ciphers[i].oid_func)()) == 0)
+ if (der_heim_oid_cmp(oid, ciphers[i].oid) == 0)
return &ciphers[i];
return NULL;
@@ -1950,7 +2439,7 @@ hx509_crypto_enctype_by_name(const char *name)
cipher = find_cipher_by_name(name);
if (cipher == NULL)
return NULL;
- return (*cipher->oid_func)();
+ return cipher->oid;
}
int
@@ -2015,6 +2504,12 @@ hx509_crypto_set_key_name(hx509_crypto crypto, const char *name)
return 0;
}
+void
+hx509_crypto_allow_weak(hx509_crypto crypto)
+{
+ crypto->flags |= ALLOW_WEAK;
+}
+
int
hx509_crypto_set_key_data(hx509_crypto crypto, const void *data, size_t length)
{
@@ -2111,6 +2606,10 @@ hx509_crypto_encrypt(hx509_crypto crypto,
*ciphertext = NULL;
+ if ((crypto->cipher->flags & CIPHER_WEAK) &&
+ (crypto->flags & ALLOW_WEAK) == 0)
+ return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
+
assert(EVP_CIPHER_iv_length(crypto->c) == ivec->length);
EVP_CIPHER_CTX_init(&evp);
@@ -2189,6 +2688,10 @@ hx509_crypto_decrypt(hx509_crypto crypto,
clear->data = NULL;
clear->length = 0;
+ if ((crypto->cipher->flags & CIPHER_WEAK) &&
+ (crypto->flags & ALLOW_WEAK) == 0)
+ return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
+
if (ivec && EVP_CIPHER_iv_length(crypto->c) < ivec->length)
return HX509_CRYPTO_INTERNAL_ERROR;
@@ -2312,6 +2815,8 @@ PBE_string2key(hx509_context context,
if (ret)
goto out;
+ hx509_crypto_allow_weak(c);
+
ret = hx509_crypto_set_key_data(c, key->data, key->length);
if (ret) {
hx509_crypto_destroy(c);
@@ -2330,33 +2835,33 @@ find_string2key(const heim_oid *oid,
const EVP_MD **md,
PBE_string2key_func *s2k)
{
- if (der_heim_oid_cmp(oid, oid_id_pbewithSHAAnd40BitRC2_CBC()) == 0) {
+ if (der_heim_oid_cmp(oid, &asn1_oid_id_pbewithSHAAnd40BitRC2_CBC) == 0) {
*c = EVP_rc2_40_cbc();
*md = EVP_sha1();
*s2k = PBE_string2key;
- return oid_private_rc2_40();
- } else if (der_heim_oid_cmp(oid, oid_id_pbeWithSHAAnd128BitRC2_CBC()) == 0) {
+ return &asn1_oid_private_rc2_40;
+ } else if (der_heim_oid_cmp(oid, &asn1_oid_id_pbeWithSHAAnd128BitRC2_CBC) == 0) {
*c = EVP_rc2_cbc();
*md = EVP_sha1();
*s2k = PBE_string2key;
- return oid_id_pkcs3_rc2_cbc();
+ return &asn1_oid_id_pkcs3_rc2_cbc;
#if 0
- } else if (der_heim_oid_cmp(oid, oid_id_pbeWithSHAAnd40BitRC4()) == 0) {
+ } else if (der_heim_oid_cmp(oid, &asn1_oid_id_pbeWithSHAAnd40BitRC4) == 0) {
*c = EVP_rc4_40();
*md = EVP_sha1();
*s2k = PBE_string2key;
return NULL;
- } else if (der_heim_oid_cmp(oid, oid_id_pbeWithSHAAnd128BitRC4()) == 0) {
+ } else if (der_heim_oid_cmp(oid, &asn1_oid_id_pbeWithSHAAnd128BitRC4) == 0) {
*c = EVP_rc4();
*md = EVP_sha1();
*s2k = PBE_string2key;
- return oid_id_pkcs3_rc4();
+ return &asn1_oid_id_pkcs3_rc4;
#endif
- } else if (der_heim_oid_cmp(oid, oid_id_pbeWithSHAAnd3_KeyTripleDES_CBC()) == 0) {
+ } else if (der_heim_oid_cmp(oid, &asn1_oid_id_pbeWithSHAAnd3_KeyTripleDES_CBC) == 0) {
*c = EVP_des_ede3_cbc();
*md = EVP_sha1();
*s2k = PBE_string2key;
- return oid_id_pkcs3_des_ede3_cbc();
+ return &asn1_oid_id_pkcs3_des_ede3_cbc;
}
return NULL;
@@ -2467,8 +2972,8 @@ out:
*/
-int
-_hx509_match_keys(hx509_cert c, hx509_private_key private_key)
+static int
+match_keys_rsa(hx509_cert c, hx509_private_key private_key)
{
const Certificate *cert;
const SubjectPublicKeyInfo *spi;
@@ -2523,6 +3028,25 @@ _hx509_match_keys(hx509_cert c, hx509_private_key private_key)
return ret == 1;
}
+static int
+match_keys_ec(hx509_cert c, hx509_private_key private_key)
+{
+ return 1; /* XXX use EC_KEY_check_key */
+}
+
+
+int
+_hx509_match_keys(hx509_cert c, hx509_private_key key)
+{
+ if (der_heim_oid_cmp(key->ops->key_oid, &asn1_oid_id_pkcs1_rsaEncryption) == 0)
+ return match_keys_rsa(c, key);
+ if (der_heim_oid_cmp(key->ops->key_oid, &asn1_oid_id_ecPublicKey) == 0)
+ return match_keys_ec(c, key);
+ return 0;
+
+}
+
+
static const heim_oid *
find_keytype(const hx509_private_key key)
{
@@ -2534,10 +3058,9 @@ find_keytype(const hx509_private_key key)
md = find_sig_alg(key->signature_alg);
if (md == NULL)
return NULL;
- return (*md->key_oid)();
+ return md->key_oid;
}
-
int
hx509_crypto_select(const hx509_context context,
int type,
@@ -2545,7 +3068,7 @@ hx509_crypto_select(const hx509_context context,
hx509_peer_info peer,
AlgorithmIdentifier *selected)
{
- const AlgorithmIdentifier *def;
+ const AlgorithmIdentifier *def = NULL;
size_t i, j;
int ret, bits;
@@ -2553,11 +3076,17 @@ hx509_crypto_select(const hx509_context context,
if (type == HX509_SELECT_DIGEST) {
bits = SIG_DIGEST;
- def = _hx509_crypto_default_digest_alg;
+ if (source)
+ def = alg_for_privatekey(source, type);
+ if (def == NULL)
+ def = _hx509_crypto_default_digest_alg;
} else if (type == HX509_SELECT_PUBLIC_SIG) {
bits = SIG_PUBLIC_SIG;
/* XXX depend on `sourceĀ“ and `peerĀ“ */
- def = _hx509_crypto_default_sig_alg;
+ if (source)
+ def = alg_for_privatekey(source, type);
+ if (def == NULL)
+ def = _hx509_crypto_default_sig_alg;
} else if (type == HX509_SELECT_SECRET_ENC) {
bits = SIG_SECRET;
def = _hx509_crypto_default_secret_alg;
@@ -2576,11 +3105,11 @@ hx509_crypto_select(const hx509_context context,
for (j = 0; sig_algs[j]; j++) {
if ((sig_algs[j]->flags & bits) != bits)
continue;
- if (der_heim_oid_cmp((*sig_algs[j]->sig_oid)(),
+ if (der_heim_oid_cmp(sig_algs[j]->sig_oid,
&peer->val[i].algorithm) != 0)
continue;
if (keytype && sig_algs[j]->key_oid &&
- der_heim_oid_cmp(keytype, (*sig_algs[j]->key_oid)()))
+ der_heim_oid_cmp(keytype, sig_algs[j]->key_oid))
continue;
/* found one, use that */
@@ -2648,7 +3177,7 @@ hx509_crypto_available(hx509_context context,
if (sig_algs[i]->sig_alg == NULL)
continue;
if (keytype && sig_algs[i]->key_oid &&
- der_heim_oid_cmp((*sig_algs[i]->key_oid)(), keytype))
+ der_heim_oid_cmp(sig_algs[i]->key_oid, keytype))
continue;
/* found one, add that to the list */
@@ -2657,7 +3186,7 @@ hx509_crypto_available(hx509_context context,
goto out;
*val = ptr;
- ret = copy_AlgorithmIdentifier((*sig_algs[i]->sig_alg)(), &(*val)[len]);
+ ret = copy_AlgorithmIdentifier(sig_algs[i]->sig_alg, &(*val)[len]);
if (ret)
goto out;
len++;
@@ -2667,7 +3196,9 @@ hx509_crypto_available(hx509_context context,
if (bits & SIG_SECRET) {
for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++) {
-
+
+ if (ciphers[i].flags & CIPHER_WEAK)
+ continue;
if (ciphers[i].ai_func == NULL)
continue;