класс OpenSSL::PKey::EC
Константы
- NAMED_CURVE
Общедоступные методы класса
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;
} См. документацию OpenSSL для EC_builtin_curves()
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;
} См. документацию OpenSSL для:
EC_KEY_*
Общедоступные методы экземпляра
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;
} Вызовет исключение, если ключ недействителен.
См. документацию OpenSSL для EC_KEY_check_key()
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;
} См. документацию OpenSSL для ECDH_compute_key()
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;
} См. документацию OpenSSL для ECDSA_sign()
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;
} См. документацию OpenSSL для ECDSA_verify()
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 в формате PEM. Если cipher и pass_phrase указаны, они будут использованы для шифрования ключа. cipher должен быть экземпляром OpenSSL::Cipher::Cipher. Обратите внимание, что шифрование будет эффективно только для закрытого ключа, открытые ключи всегда будут закодированы в открытом виде.
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;
} См. документацию OpenSSL для EC_KEY_generate_key()
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;
} Возвращает константу OpenSSL::EC::Group, связанную с ключом. Изменение возвращаемой группы может сделать ключ недействительным.
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;
} Возвращает тот же объект, что и передан, а не объект группы, связанный с ключом. Если вы хотите получить доступ к объекту группы, связанному с ключом, вызовите key.group после установки группы.
Установка группы немедленно уничтожает любой ранее назначенный объект группы. Группа внутренне копируется в OpenSSL. Изменение исходной группы после назначения не повлияет на внутреннюю структуру ключа. (ваши изменения могут быть потеряны). БУДЬТЕ ОСТОРОЖНЫ.
EC_KEY_set_group вызывает EC_GROUP_free(key->group) затем EC_GROUP_dup(), а не EC_GROUP_copy. Данная документация актуальна для OpenSSL 0.9.8b.
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);
} См. документацию OpenSSL для EC_KEY_get0_private_key()
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;
} См. документацию OpenSSL для EC_KEY_set_private_key()
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);
} И #public_key? и #private_key? могут возвращать false одновременно в отличие от других классов PKey.
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);
} См. документацию OpenSSL для EC_KEY_get0_public_key()
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;
} См. документацию OpenSSL для EC_KEY_set_public_key()
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);
} И #public_key? и #private_key? могут возвращать false одновременно в отличие от других классов PKey.
static VALUE ossl_ec_key_to_der(VALUE self)
{
return ossl_ec_key_to_string(self, Qnil, Qnil, EXPORT_DER);
} См. документацию OpenSSL для i2d_ECPrivateKey_bio()
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;
} См. документацию OpenSSL для EC_KEY_print()
Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.