class OpenSSL::PKey::EC

Parent:
cPKey

Constants

NAMED_CURVE

Public Class Methods

builtin_curves → [[name, comment], ...] Show source
static VALUE ossl_s_builtin_curves(VALUE self)
{
    EC_builtin_curve *curves = NULL;
    int n;
    int crv_len = rb_long2int(EC_get_builtin_curves(NULL, 0));
    VALUE ary, ret;

    curves = ALLOCA_N(EC_builtin_curve, crv_len);
    if (curves == NULL)
        return Qnil;
    if (!EC_get_builtin_curves(curves, crv_len))
        ossl_raise(rb_eRuntimeError, "EC_get_builtin_curves");

    ret = rb_ary_new2(crv_len);

    for (n = 0; n < crv_len; n++) {
        const char *sname = OBJ_nid2sn(curves[n].nid);
        const char *comment = curves[n].comment;

        ary = rb_ary_new2(2);
        rb_ary_push(ary, rb_str_new2(sname));
        rb_ary_push(ary, comment ? rb_str_new2(comment) : Qnil);
        rb_ary_push(ret, ary);
    }

    return ret;
}

See the OpenSSL documentation for EC_builtin_curves()

OpenSSL::PKey::EC.new() Show source
OpenSSL::PKey::EC.new(ec_key)
OpenSSL::PKey::EC.new(ec_group)
OpenSSL::PKey::EC.new("secp112r1")
OpenSSL::PKey::EC.new(pem_string)
OpenSSL::PKey::EC.new(pem_string [, pwd])
OpenSSL::PKey::EC.new(der_string)
static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
{
    EVP_PKEY *pkey;
    EC_KEY *ec = NULL;
    VALUE arg, pass;
    VALUE group = Qnil;
    char *passwd = NULL;

    GetPKey(self, pkey);
    if (pkey->pkey.ec)
        ossl_raise(eECError, "EC_KEY already initialized");

    rb_scan_args(argc, argv, "02", &arg, &pass);

    if (NIL_P(arg)) {
        ec = EC_KEY_new();
    } else {
        if (rb_obj_is_kind_of(arg, cEC)) {
            EC_KEY *other_ec = NULL;

            SafeRequire_EC_KEY(arg, other_ec);
            ec = EC_KEY_dup(other_ec);
        } else if (rb_obj_is_kind_of(arg, cEC_GROUP)) {
                ec = EC_KEY_new();
                group = arg;
        } else {
            BIO *in = ossl_obj2bio(arg);

            if (!NIL_P(pass)) {
                passwd = StringValuePtr(pass);
            }
            ec = PEM_read_bio_ECPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
            if (!ec) {
                OSSL_BIO_reset(in);
                ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, passwd);
            }
            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_free(in);

            if (ec == NULL) {
                const char *name = StringValueCStr(arg);
                int nid = OBJ_sn2nid(name);

                (void)ERR_get_error();
                if (nid == NID_undef)
                    ossl_raise(eECError, "unknown curve name (%s)\n", name);

                if ((ec = EC_KEY_new_by_curve_name(nid)) == NULL)
                    ossl_raise(eECError, "unable to create curve (%s)\n", name);

                EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
                EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED);
            }
        }
    }

    if (ec == NULL)
        ossl_raise(eECError, NULL);

    if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) {
        EC_KEY_free(ec);
        ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
    }

    rb_iv_set(self, "@group", Qnil);

    if (!NIL_P(group))
        rb_funcall(self, rb_intern("group="), 1, arg);

    return self;
}

See the OpenSSL documentation for:

EC_KEY_*

Public Instance Methods

check_key → true Show source
static VALUE ossl_ec_key_check_key(VALUE self)
{
    EC_KEY *ec;

    Require_EC_KEY(self, ec);

    if (EC_KEY_check_key(ec) != 1)
        ossl_raise(eECError, "EC_KEY_check_key");

    return Qtrue;
}

Raises an exception if the key is invalid.

See the OpenSSL documentation for EC_KEY_check_key()

dh_compute_key(pubkey) → String Show source
static VALUE ossl_ec_key_dh_compute_key(VALUE self, VALUE pubkey)
{
    EC_KEY *ec;
    EC_POINT *point;
    int buf_len;
    VALUE str;

    Require_EC_KEY(self, ec);
    SafeRequire_EC_POINT(pubkey, point);

/* BUG: need a way to figure out the maximum string size */
    buf_len = 1024;
    str = rb_str_new(0, buf_len);
/* BUG: take KDF as a block */
    buf_len = ECDH_compute_key(RSTRING_PTR(str), buf_len, point, ec, NULL);
    if (buf_len < 0)
         ossl_raise(eECError, "ECDH_compute_key");

    rb_str_resize(str, buf_len);

    return str;
}

See the OpenSSL documentation for ECDH_compute_key()

dsa_sign_asn1(data) → String Show source
static VALUE ossl_ec_key_dsa_sign_asn1(VALUE self, VALUE data)
{
    EC_KEY *ec;
    unsigned int buf_len;
    VALUE str;

    Require_EC_KEY(self, ec);
    StringValue(data);

    if (EC_KEY_get0_private_key(ec) == NULL)
        ossl_raise(eECError, "Private EC key needed!");

    str = rb_str_new(0, ECDSA_size(ec) + 16);
    if (ECDSA_sign(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LENINT(data), (unsigned char *) RSTRING_PTR(str), &buf_len, ec) != 1)
         ossl_raise(eECError, "ECDSA_sign");

    rb_str_resize(str, buf_len);

    return str;
}

See the OpenSSL documentation for ECDSA_sign()

dsa_verify_asn1(data, sig) → true or false Show source
static VALUE ossl_ec_key_dsa_verify_asn1(VALUE self, VALUE data, VALUE sig)
{
    EC_KEY *ec;

    Require_EC_KEY(self, ec);
    StringValue(data);
    StringValue(sig);

    switch (ECDSA_verify(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LENINT(data), (unsigned char *) RSTRING_PTR(sig), (int)RSTRING_LEN(sig), ec)) {
    case 1:     return Qtrue;
    case 0:     return Qfalse;
    default:    break;
    }

    ossl_raise(eECError, "ECDSA_verify");

    UNREACHABLE;
}

See the OpenSSL documentation for ECDSA_verify()

export([cipher, pass_phrase]) → String Show source
to_pem([cipher, pass_phrase]) → String
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);
}

Outputs the EC key in PEM encoding. If cipher and pass_phrase are given they will be used to encrypt the key. cipher must be an OpenSSL::Cipher::Cipher instance. Note that encryption will only be effective for a private key, public keys will always be encoded in plain text.

Also aliased as: to_pem
generate_key → self Show source
static VALUE ossl_ec_key_generate_key(VALUE self)
{
    EC_KEY *ec;

    Require_EC_KEY(self, ec);

    if (EC_KEY_generate_key(ec) != 1)
        ossl_raise(eECError, "EC_KEY_generate_key");

    return self;
}

See the OpenSSL documentation for EC_KEY_generate_key()

group → group Show source
static VALUE ossl_ec_key_get_group(VALUE self)
{
    VALUE group_v;
    EC_KEY *ec;
    ossl_ec_group *ec_group;
    EC_GROUP *group;

    Require_EC_KEY(self, ec);

    group_v = rb_iv_get(self, "@group");
    if (!NIL_P(group_v))
        return group_v;

    if ((group = (EC_GROUP *)EC_KEY_get0_group(ec)) != NULL) {
        group_v = rb_obj_alloc(cEC_GROUP);
        SafeGet_ec_group(group_v, ec_group);
        ec_group->group = group;
        ec_group->dont_free = 1;
        rb_iv_set(group_v, "@key", self);
        rb_iv_set(self, "@group", group_v);
        return group_v;
    }

    return Qnil;
}

Returns a constant OpenSSL::EC::Group that is tied to the key. Modifying the returned group can make the key invalid.

group = group → group Show source
static VALUE ossl_ec_key_set_group(VALUE self, VALUE group_v)
{
    VALUE old_group_v;
    EC_KEY *ec;
    EC_GROUP *group;

    Require_EC_KEY(self, ec);
    SafeRequire_EC_GROUP(group_v, group);

    old_group_v = rb_iv_get(self, "@group");
    if (!NIL_P(old_group_v)) {
        ossl_ec_group *old_ec_group;
        SafeGet_ec_group(old_group_v, old_ec_group);

        old_ec_group->group = NULL;
        old_ec_group->dont_free = 0;
        rb_iv_set(old_group_v, "@key", Qnil);
    }

    rb_iv_set(self, "@group", Qnil);

    if (EC_KEY_set_group(ec, group) != 1)
        ossl_raise(eECError, "EC_KEY_set_group");

    return group_v;
}

Returns the same object passed, not the group object associated with the key. If you wish to access the group object tied to the key call key.group after setting the group.

Setting the group will immediately destroy any previously assigned group object. The group is internally copied by OpenSSL. Modifying the original group after assignment will not effect the internal key structure. (your changes may be lost). BE CAREFUL.

EC_KEY_set_group calls EC_GROUP_free(key->group) then EC_GROUP_dup(), not EC_GROUP_copy. This documentation is accurate for OpenSSL 0.9.8b.

private_key → OpenSSL::BN Show source
static VALUE ossl_ec_key_get_private_key(VALUE self)
{
    EC_KEY *ec;
    const BIGNUM *bn;

    Require_EC_KEY(self, ec);

    if ((bn = EC_KEY_get0_private_key(ec)) == NULL)
        return Qnil;

    return ossl_bn_new(bn);
}

See the OpenSSL documentation for EC_KEY_get0_private_key()

private_key = openssl_bn Show source
static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key)
{
    EC_KEY *ec;
    BIGNUM *bn = NULL;

    Require_EC_KEY(self, ec);
    if (!NIL_P(private_key))
        bn = GetBNPtr(private_key);

    switch (EC_KEY_set_private_key(ec, bn)) {
    case 1:
        break;
    case 0:
        if (bn == NULL)
            break;
    default:
        ossl_raise(eECError, "EC_KEY_set_private_key");
    }

    return private_key;
}

See the OpenSSL documentation for EC_KEY_set_private_key()

private_key? → true or false Show source
static VALUE ossl_ec_key_is_private_key(VALUE self)
{
    EC_KEY *ec;

    Require_EC_KEY(self, ec);

    return (EC_KEY_get0_private_key(ec) ? Qtrue : Qfalse);
}

Both #public_key? and #private_key? may return false at the same time unlike other PKey classes.

public_key → OpenSSL::PKey::EC::Point Show source
static VALUE ossl_ec_key_get_public_key(VALUE self)
{
    EC_KEY *ec;
    const EC_POINT *point;
    VALUE group;

    Require_EC_KEY(self, ec);

    if ((point = EC_KEY_get0_public_key(ec)) == NULL)
        return Qnil;

    group = rb_funcall(self, rb_intern("group"), 0);
    if (NIL_P(group))
        ossl_raise(eECError, "EC_KEY_get0_get0_group (has public_key but no group???");

    return ossl_ec_point_dup(point, group);
}

See the OpenSSL documentation for EC_KEY_get0_public_key()

public_key = ec_point Show source
static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key)
{
    EC_KEY *ec;
    EC_POINT *point = NULL;

    Require_EC_KEY(self, ec);
    if (!NIL_P(public_key))
        SafeRequire_EC_POINT(public_key, point);

    switch (EC_KEY_set_public_key(ec, point)) {
    case 1:
        break;
    case 0:
        if (point == NULL)
            break;
    default:
        ossl_raise(eECError, "EC_KEY_set_public_key");
    }

    return public_key;
}

See the OpenSSL documentation for EC_KEY_set_public_key()

public_key? → true or false Show source
static VALUE ossl_ec_key_is_public_key(VALUE self)
{
    EC_KEY *ec;

    Require_EC_KEY(self, ec);

    return (EC_KEY_get0_public_key(ec) ? Qtrue : Qfalse);
}

Both #public_key? and #private_key? may return false at the same time unlike other PKey classes.

to_der → String Show source
static VALUE ossl_ec_key_to_der(VALUE self)
{
    return ossl_ec_key_to_string(self, Qnil, Qnil, EXPORT_DER);
}

See the OpenSSL documentation for i2d_ECPrivateKey_bio()

to_pem(p1 = v1, p2 = v2)
Alias for: export
to_text → String Show source
static VALUE ossl_ec_key_to_text(VALUE self)
{
    EC_KEY *ec;
    BIO *out;
    VALUE str;

    Require_EC_KEY(self, ec);
    if (!(out = BIO_new(BIO_s_mem()))) {
        ossl_raise(eECError, "BIO_new(BIO_s_mem())");
    }
    if (!EC_KEY_print(out, ec, 0)) {
        BIO_free(out);
        ossl_raise(eECError, "EC_KEY_print");
    }
    str = ossl_membio2str(out);

    return str;
}

See the OpenSSL documentation for EC_KEY_print()

Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.