class OpenSSL::PKey::EC - RDoc Documentation (original) (raw)

OpenSSL::PKey::EC provides access to Elliptic Curve Digital Signature Algorithm (ECDSA) and Elliptic Curve Diffie-Hellman (ECDH).

Key exchange

ec1 = OpenSSL::PKey::EC.generate("prime256v1") ec2 = OpenSSL::PKey::EC.generate("prime256v1")

shared_key1 = ec1.dh_compute_key(ec2.public_key) shared_key2 = ec2.dh_compute_key(ec1.public_key)

p shared_key1 == shared_key2

Constants

EXPLICIT_CURVE

NAMED_CURVE

Public Class Methods

builtin_curves → [[sn, comment], ...] click to toggle source

Obtains a list of all predefined curves by the OpenSSL. Curve names are returned as sn.

See the OpenSSL documentation for EC_get_builtin_curves().

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;

}

generate(ec_group) → ec click to toggle source

generate(string) → ec

Creates a new EC instance with a new random private and public key.

static VALUE ossl_ec_key_s_generate(VALUE klass, VALUE arg) { EC_KEY *ec; VALUE obj;

ec = ec_key_new_from_group(arg);

obj = ec_instance(klass, ec);
if (obj == Qfalse) {
    EC_KEY_free(ec);
    ossl_raise(eECError, NULL);
}

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

return obj;

}

OpenSSL::PKey::EC.new click to toggle source

OpenSSL::PKey::EC.new(ec_key)

OpenSSL::PKey::EC.new(ec_group)

OpenSSL::PKey::EC.new("secp112r1")

OpenSSL::PKey::EC.new(pem_string [, pwd])

OpenSSL::PKey::EC.new(der_string)

Creates a new EC object from given arguments.

static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self) { EVP_PKEY *pkey; EC_KEY *ec; VALUE arg, pass;

GetPKey(self, pkey);
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
    ossl_raise(eECError, "EC_KEY already initialized");

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

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

    GetEC(arg, other_ec);
    if (!(ec = EC_KEY_dup(other_ec)))
        ossl_raise(eECError, NULL);
} 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_free(in);

    if (!ec) {
        ossl_clear_error();
        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");
}

return self;

}

Public Instance Methods

check_key → true click to toggle source

Raises an exception if the key is invalid.

See the OpenSSL documentation for EC_KEY_check_key()

static VALUE ossl_ec_key_check_key(VALUE self) { EC_KEY *ec;

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

return Qtrue;

}

dh_compute_key(pubkey) → String click to toggle source

See the OpenSSL documentation for ECDH_compute_key()

static VALUE ossl_ec_key_dh_compute_key(VALUE self, VALUE pubkey) { EC_KEY *ec; EC_POINT *point; int buf_len; VALUE str;

GetEC(self, ec);
GetECPoint(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;

}

dsa_sign_asn1(data) → String click to toggle source

See the OpenSSL documentation for ECDSA_sign()

static VALUE ossl_ec_key_dsa_sign_asn1(VALUE self, VALUE data) { EC_KEY *ec; unsigned int buf_len; VALUE str;

GetEC(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));
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_set_len(str, buf_len);

return str;

}

dsa_verify_asn1(data, sig) → true or false click to toggle source

See the OpenSSL documentation for ECDSA_verify()

static VALUE ossl_ec_key_dsa_verify_asn1(VALUE self, VALUE data, VALUE sig) { EC_KEY *ec;

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

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

}

export([cipher, pass_phrase]) → String click to toggle source

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 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) { VALUE cipher, passwd; rb_scan_args(argc, argv, "02", &cipher, &passwd); return ossl_ec_key_to_string(self, cipher, passwd, EXPORT_PEM); }

Generates a new random private and public key.

See also the OpenSSL documentation for EC_KEY_generate_key()

Example

ec = OpenSSL::PKey::EC.new("prime256v1") p ec.private_key ec.generate_key! p ec.private_key

Generates a new random private and public key.

See also the OpenSSL documentation for EC_KEY_generate_key()

Example

ec = OpenSSL::PKey::EC.new("prime256v1") p ec.private_key ec.generate_key! p ec.private_key

static VALUE ossl_ec_key_generate_key(VALUE self) { EC_KEY *ec;

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

return self;

}

group → group click to toggle source

Returns the EC::Group that the key is associated with. Modifying the returned group does not affect key.

static VALUE ossl_ec_key_get_group(VALUE self) { EC_KEY *ec; const EC_GROUP *group;

GetEC(self, ec);
group = EC_KEY_get0_group(ec);
if (!group)
    return Qnil;

return ec_group_new(group);

}

group = group click to toggle source

Sets the EC::Group for the key. The group structure is internally copied so modification to group after assigning to a key has no effect on the key.

static VALUE ossl_ec_key_set_group(VALUE self, VALUE group_v) { EC_KEY *ec; EC_GROUP *group;

GetEC(self, ec);
GetECGroup(group_v, group);

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

return group_v;

}

initialize_copy(p1) click to toggle source

static VALUE ossl_ec_key_initialize_copy(VALUE self, VALUE other) { EVP_PKEY *pkey; EC_KEY *ec, *ec_new;

GetPKey(self, pkey);
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
    ossl_raise(eECError, "EC already initialized");
GetEC(other, ec);

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

return self;

}

private? → true or false click to toggle source

Returns whether this EC instance has a private key. The private key (BN) can be retrieved with EC#private_key.

static VALUE ossl_ec_key_is_private(VALUE self) { EC_KEY *ec;

GetEC(self, ec);

return EC_KEY_get0_private_key(ec) ? Qtrue : Qfalse;

}

private_key → OpenSSL::BN click to toggle source

See the OpenSSL documentation for EC_KEY_get0_private_key()

static VALUE ossl_ec_key_get_private_key(VALUE self) { EC_KEY *ec; const BIGNUM *bn;

GetEC(self, ec);
if ((bn = EC_KEY_get0_private_key(ec)) == NULL)
    return Qnil;

return ossl_bn_new(bn);

}

private_key = openssl_bn click to toggle source

See the OpenSSL documentation for EC_KEY_set_private_key()

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

GetEC(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;

}

Returns whether this EC instance has a private key. The private key (BN) can be retrieved with EC#private_key.

public? → true or false click to toggle source

Returns whether this EC instance has a public key. The public key (EC::Point) can be retrieved with EC#public_key.

static VALUE ossl_ec_key_is_public(VALUE self) { EC_KEY *ec;

GetEC(self, ec);

return EC_KEY_get0_public_key(ec) ? Qtrue : Qfalse;

}

public_key → OpenSSL::PKey::EC::Point click to toggle source

See the OpenSSL documentation for EC_KEY_get0_public_key()

static VALUE ossl_ec_key_get_public_key(VALUE self) { EC_KEY *ec; const EC_POINT *point;

GetEC(self, ec);
if ((point = EC_KEY_get0_public_key(ec)) == NULL)
    return Qnil;

return ec_point_new(point, EC_KEY_get0_group(ec));

}

public_key = ec_point click to toggle source

See the OpenSSL documentation for EC_KEY_set_public_key()

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

GetEC(self, ec);
if (!NIL_P(public_key))
    GetECPoint(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;

}

to_der → String click to toggle source

See the OpenSSL documentation for i2d_ECPrivateKey_bio()

static VALUE ossl_ec_key_to_der(VALUE self) { return ossl_ec_key_to_string(self, Qnil, Qnil, EXPORT_DER); }

to_pem([cipher, pass_phrase]) → String

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 instance. Note that encryption will only be effective for a private key, public keys will always be encoded in plain text.

to_text → String click to toggle source

See the OpenSSL documentation for EC_KEY_print()

static VALUE ossl_ec_key_to_text(VALUE self) { EC_KEY *ec; BIO *out; VALUE str;

GetEC(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;

}