aboutsummaryrefslogtreecommitdiffstats
path: root/ext/openssl/ossl_pkey_ec.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/openssl/ossl_pkey_ec.c')
-rw-r--r--ext/openssl/ossl_pkey_ec.c169
1 files changed, 37 insertions, 132 deletions
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c
index fc2bc6c8..6fe2533e 100644
--- a/ext/openssl/ossl_pkey_ec.c
+++ b/ext/openssl/ossl_pkey_ec.c
@@ -63,47 +63,6 @@ static ID id_i_group;
static VALUE ec_group_new(const EC_GROUP *group);
static VALUE ec_point_new(const EC_POINT *point, const EC_GROUP *group);
-static VALUE ec_instance(VALUE klass, EC_KEY *ec)
-{
- EVP_PKEY *pkey;
- VALUE obj;
-
- if (!ec) {
- return Qfalse;
- }
- obj = NewPKey(klass);
- if (!(pkey = EVP_PKEY_new())) {
- return Qfalse;
- }
- if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) {
- EVP_PKEY_free(pkey);
- return Qfalse;
- }
- SetPKey(obj, pkey);
-
- return obj;
-}
-
-VALUE ossl_ec_new(EVP_PKEY *pkey)
-{
- VALUE obj;
-
- if (!pkey) {
- obj = ec_instance(cEC, EC_KEY_new());
- } else {
- obj = NewPKey(cEC);
- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) {
- ossl_raise(rb_eTypeError, "Not a EC key!");
- }
- SetPKey(obj, pkey);
- }
- if (obj == Qfalse) {
- ossl_raise(eECError, NULL);
- }
-
- return obj;
-}
-
/*
* Creates a new EC_KEY on the EC group obj. arg can be an EC::Group or a String
* representing an OID.
@@ -150,17 +109,18 @@ ec_key_new_from_group(VALUE arg)
static VALUE
ossl_ec_key_s_generate(VALUE klass, VALUE arg)
{
+ EVP_PKEY *pkey;
EC_KEY *ec;
VALUE obj;
- ec = ec_key_new_from_group(arg);
+ obj = rb_obj_alloc(klass);
+ GetPKey(obj, pkey);
- obj = ec_instance(klass, ec);
- if (obj == Qfalse) {
- EC_KEY_free(ec);
- ossl_raise(eECError, NULL);
+ ec = ec_key_new_from_group(arg);
+ if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) {
+ EC_KEY_free(ec);
+ ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
}
-
if (!EC_KEY_generate_key(ec))
ossl_raise(eECError, "EC_KEY_generate_key");
@@ -181,7 +141,7 @@ ossl_ec_key_s_generate(VALUE klass, VALUE arg)
static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
{
EVP_PKEY *pkey;
- EC_KEY *ec;
+ EC_KEY *ec = NULL;
VALUE arg, pass;
GetPKey(self, pkey);
@@ -202,24 +162,17 @@ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
} else if (rb_obj_is_kind_of(arg, cEC_GROUP)) {
ec = ec_key_new_from_group(arg);
} else {
- BIO *in;
-
- pass = ossl_pem_passwd_value(pass);
- in = ossl_obj2bio(&arg);
-
- ec = PEM_read_bio_ECPrivateKey(in, NULL, ossl_pem_passwd_cb, (void *)pass);
- if (!ec) {
- OSSL_BIO_reset(in);
- ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, (void *)pass);
- }
- if (!ec) {
- OSSL_BIO_reset(in);
- ec = d2i_ECPrivateKey_bio(in, NULL);
- }
- if (!ec) {
- OSSL_BIO_reset(in);
- ec = d2i_EC_PUBKEY_bio(in, NULL);
- }
+ BIO *in = ossl_obj2bio(&arg);
+ EVP_PKEY *tmp;
+ pass = ossl_pem_passwd_value(pass);
+ tmp = ossl_pkey_read_generic(in, pass);
+ if (tmp) {
+ if (EVP_PKEY_base_id(tmp) != EVP_PKEY_EC)
+ rb_raise(eECError, "incorrect pkey type: %s",
+ OBJ_nid2sn(EVP_PKEY_base_id(tmp)));
+ ec = EVP_PKEY_get1_EC_KEY(tmp);
+ EVP_PKEY_free(tmp);
+ }
BIO_free(in);
if (!ec) {
@@ -425,66 +378,6 @@ static VALUE ossl_ec_key_is_private(VALUE self)
return EC_KEY_get0_private_key(ec) ? Qtrue : Qfalse;
}
-static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int format)
-{
- EC_KEY *ec;
- BIO *out;
- int i = -1;
- int private = 0;
- VALUE str;
- const EVP_CIPHER *cipher = NULL;
-
- GetEC(self, ec);
-
- if (EC_KEY_get0_public_key(ec) == NULL)
- ossl_raise(eECError, "can't export - no public key set");
-
- if (EC_KEY_check_key(ec) != 1)
- ossl_raise(eECError, "can't export - EC_KEY_check_key failed");
-
- if (EC_KEY_get0_private_key(ec))
- private = 1;
-
- if (!NIL_P(ciph)) {
- cipher = ossl_evp_get_cipherbyname(ciph);
- pass = ossl_pem_passwd_value(pass);
- }
-
- if (!(out = BIO_new(BIO_s_mem())))
- ossl_raise(eECError, "BIO_new(BIO_s_mem())");
-
- switch(format) {
- case EXPORT_PEM:
- if (private) {
- i = PEM_write_bio_ECPrivateKey(out, ec, cipher, NULL, 0, ossl_pem_passwd_cb, (void *)pass);
- } else {
- i = PEM_write_bio_EC_PUBKEY(out, ec);
- }
-
- break;
- case EXPORT_DER:
- if (private) {
- i = i2d_ECPrivateKey_bio(out, ec);
- } else {
- i = i2d_EC_PUBKEY_bio(out, ec);
- }
-
- break;
- default:
- BIO_free(out);
- ossl_raise(rb_eRuntimeError, "unknown format (internal error)");
- }
-
- if (i != 1) {
- BIO_free(out);
- ossl_raise(eECError, "outlen=%d", i);
- }
-
- str = ossl_membio2str(out);
-
- return str;
-}
-
/*
* call-seq:
* key.export([cipher, pass_phrase]) => String
@@ -495,11 +388,16 @@ static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int forma
* instance. Note that encryption will only be effective for a private key,
* public keys will always be encoded in plain text.
*/
-static VALUE ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
+static VALUE
+ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
{
- VALUE cipher, passwd;
- rb_scan_args(argc, argv, "02", &cipher, &passwd);
- return ossl_ec_key_to_string(self, cipher, passwd, EXPORT_PEM);
+ EC_KEY *ec;
+
+ GetEC(self, ec);
+ if (EC_KEY_get0_private_key(ec))
+ return ossl_pkey_export_traditional(argc, argv, self, 0);
+ else
+ return ossl_pkey_export_spki(self, 0);
}
/*
@@ -508,9 +406,16 @@ static VALUE ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
*
* See the OpenSSL documentation for i2d_ECPrivateKey_bio()
*/
-static VALUE ossl_ec_key_to_der(VALUE self)
+static VALUE
+ossl_ec_key_to_der(VALUE self)
{
- return ossl_ec_key_to_string(self, Qnil, Qnil, EXPORT_DER);
+ EC_KEY *ec;
+
+ GetEC(self, ec);
+ if (EC_KEY_get0_private_key(ec))
+ return ossl_pkey_export_traditional(0, NULL, self, 1);
+ else
+ return ossl_pkey_export_spki(self, 1);
}
/*