7#if !defined(OPENSSL_NO_EC)
15#define GetPKeyEC(obj, pkey) do { \
16 GetPKey((obj), (pkey)); \
17 if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) { \
18 ossl_raise(rb_eRuntimeError, "THIS IS NOT A EC PKEY!"); \
21#define GetEC(obj, key) do { \
23 GetPKeyEC(obj, _pkey); \
24 (key) = EVP_PKEY_get0_EC_KEY(_pkey); \
27#define GetECGroup(obj, group) do { \
28 TypedData_Get_Struct(obj, EC_GROUP, &ossl_ec_group_type, group); \
29 if ((group) == NULL) \
30 ossl_raise(eEC_GROUP, "EC_GROUP is not initialized"); \
33#define GetECPoint(obj, point) do { \
34 TypedData_Get_Struct(obj, EC_POINT, &ossl_ec_point_type, point); \
35 if ((point) == NULL) \
36 ossl_raise(eEC_POINT, "EC_POINT is not initialized"); \
38#define GetECPointGroup(obj, group) do { \
39 VALUE _group = rb_attr_get(obj, id_i_group); \
40 GetECGroup(_group, group); \
51static ID s_GFp_simple;
55static ID s_GF2m_simple;
57static ID ID_uncompressed;
58static ID ID_compressed;
63static VALUE ec_group_new(
const EC_GROUP *group);
64static VALUE ec_point_new(
const EC_POINT *
point,
const EC_GROUP *group);
66static VALUE ec_instance(
VALUE klass, EC_KEY *ec)
75 if (!(pkey = EVP_PKEY_new())) {
78 if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) {
92 obj = ec_instance(
cEC, EC_KEY_new());
95 if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) {
112ec_key_new_from_group(
VALUE arg)
120 if (!(ec = EC_KEY_new()))
123 if (!EC_KEY_set_group(ec, group)) {
130 if (
nid == NID_undef)
133 if (!(ec = EC_KEY_new_by_curve_name(
nid)))
136 EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
137 EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED);
156 ec = ec_key_new_from_group(arg);
158 obj = ec_instance(klass, ec);
164 if (!EC_KEY_generate_key(ec))
188 if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
194 if (!(ec = EC_KEY_new()))
197 EC_KEY *other_ec =
NULL;
199 GetEC(arg, other_ec);
200 if (!(ec = EC_KEY_dup(other_ec)))
203 ec = ec_key_new_from_group(arg);
217 ec = d2i_ECPrivateKey_bio(
in,
NULL);
221 ec = d2i_EC_PUBKEY_bio(
in,
NULL);
227 ec = ec_key_new_from_group(arg);
231 if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) {
240ossl_ec_key_initialize_copy(
VALUE self,
VALUE other)
246 if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
250 ec_new = EC_KEY_dup(ec);
253 if (!EVP_PKEY_assign_EC_KEY(pkey, ec_new)) {
269ossl_ec_key_get_group(
VALUE self)
272 const EC_GROUP *group;
275 group = EC_KEY_get0_group(ec);
279 return ec_group_new(group);
290ossl_ec_key_set_group(
VALUE self,
VALUE group_v)
298 if (EC_KEY_set_group(ec, group) != 1)
310static VALUE ossl_ec_key_get_private_key(
VALUE self)
316 if ((bn = EC_KEY_get0_private_key(ec)) ==
NULL)
334 if (!
NIL_P(private_key))
337 switch (EC_KEY_set_private_key(ec, bn)) {
356static VALUE ossl_ec_key_get_public_key(
VALUE self)
359 const EC_POINT *
point;
362 if ((
point = EC_KEY_get0_public_key(ec)) ==
NULL)
365 return ec_point_new(
point, EC_KEY_get0_group(ec));
380 if (!
NIL_P(public_key))
383 switch (EC_KEY_set_public_key(ec,
point)) {
409 return EC_KEY_get0_public_key(ec) ?
Qtrue :
Qfalse;
419static VALUE ossl_ec_key_is_private(
VALUE self)
425 return EC_KEY_get0_private_key(ec) ?
Qtrue :
Qfalse;
435 const EVP_CIPHER *cipher =
NULL;
439 if (EC_KEY_get0_public_key(ec) ==
NULL)
442 if (EC_KEY_check_key(ec) != 1)
445 if (EC_KEY_get0_private_key(ec))
453 if (!(
out = BIO_new(BIO_s_mem())))
461 i = PEM_write_bio_EC_PUBKEY(
out, ec);
467 i = i2d_ECPrivateKey_bio(
out, ec);
469 i = i2d_EC_PUBKEY_bio(
out, ec);
500 VALUE cipher, passwd;
502 return ossl_ec_key_to_string(self, cipher, passwd,
EXPORT_PEM);
529 if (!(
out = BIO_new(BIO_s_mem()))) {
532 if (!EC_KEY_print(
out, ec, 0)) {
555static VALUE ossl_ec_key_generate_key(
VALUE self)
560 if (EC_KEY_generate_key(ec) != 1)
579 if (EC_KEY_check_key(ec) != 1)
625 unsigned int buf_len;
631 if (EC_KEY_get0_private_key(ec) ==
NULL)
635 if (ECDSA_sign(0, (
unsigned char *)
RSTRING_PTR(data), RSTRING_LENINT(data), (
unsigned char *)
RSTRING_PTR(
str), &buf_len, ec) != 1)
656 switch (ECDSA_verify(0, (
unsigned char *)
RSTRING_PTR(data), RSTRING_LENINT(data),
657 (
unsigned char *)
RSTRING_PTR(sig), RSTRING_LENINT(sig), ec)) {
671ossl_ec_group_free(
void *
ptr)
673 EC_GROUP_clear_free(
ptr);
679 0, ossl_ec_group_free,
685ossl_ec_group_alloc(
VALUE klass)
691ec_group_new(
const EC_GROUP *group)
697 group_new = EC_GROUP_dup(group);
728 VALUE arg1, arg2, arg3, arg4;
738 const EC_METHOD *method =
NULL;
741 if (
id == s_GFp_simple) {
742 method = EC_GFp_simple_method();
743 }
else if (
id == s_GFp_mont) {
744 method = EC_GFp_mont_method();
745 }
else if (
id == s_GFp_nist) {
746 method = EC_GFp_nist_method();
747#if !defined(OPENSSL_NO_EC2M)
748 }
else if (
id == s_GF2m_simple) {
749 method = EC_GF2m_simple_method();
754 if ((group = EC_GROUP_new(method)) ==
NULL)
760 const EC_GROUP *arg1_group;
763 if ((group = EC_GROUP_dup(arg1_group)) ==
NULL)
771 group = d2i_ECPKParameters_bio(
in,
NULL);
781 if (
nid == NID_undef)
784 group = EC_GROUP_new_by_curve_name(
nid);
788 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
789 EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_UNCOMPRESSED);
797 EC_GROUP *(*new_curve)(
const BIGNUM *,
const BIGNUM *,
const BIGNUM *, BN_CTX *) =
NULL;
803 new_curve = EC_GROUP_new_curve_GFp;
804#if !defined(OPENSSL_NO_EC2M)
805 }
else if (
id == s_GF2m) {
806 new_curve = EC_GROUP_new_curve_GF2m;
831ossl_ec_group_initialize_copy(
VALUE self,
VALUE other)
833 EC_GROUP *group, *group_new;
840 group_new = EC_GROUP_dup(group);
858 EC_GROUP *group1 =
NULL, *group2 =
NULL;
863 if (EC_GROUP_cmp(group1, group2,
ossl_bn_ctx) == 1)
877static VALUE ossl_ec_group_get_generator(
VALUE self)
883 generator = EC_GROUP_get0_generator(group);
901 EC_GROUP *group =
NULL;
902 const EC_POINT *
point;
903 const BIGNUM *o, *co;
910 if (EC_GROUP_set_generator(group,
point, o, co) != 1)
924static VALUE ossl_ec_group_get_order(
VALUE self)
928 EC_GROUP *group =
NULL;
935 if (EC_GROUP_get_order(group, bn,
ossl_bn_ctx) != 1)
949static VALUE ossl_ec_group_get_cofactor(
VALUE self)
953 EC_GROUP *group =
NULL;
960 if (EC_GROUP_get_cofactor(group, bn,
ossl_bn_ctx) != 1)
974static VALUE ossl_ec_group_get_curve_name(
VALUE self)
976 EC_GROUP *group =
NULL;
983 nid = EC_GROUP_get_curve_name(group);
1000 EC_builtin_curve *curves =
NULL;
1005 curves =
ALLOCA_N(EC_builtin_curve, crv_len);
1008 if (!EC_get_builtin_curves(curves, crv_len))
1013 for (n = 0; n < crv_len; n++) {
1014 const char *sname = OBJ_nid2sn(curves[n].
nid);
1015 const char *comment = curves[n].comment;
1034static VALUE ossl_ec_group_get_asn1_flag(
VALUE self)
1036 EC_GROUP *group =
NULL;
1040 flag = EC_GROUP_get_asn1_flag(group);
1061 EC_GROUP *group =
NULL;
1064 EC_GROUP_set_asn1_flag(group,
NUM2INT(flag_v));
1077static VALUE ossl_ec_group_get_point_conversion_form(
VALUE self)
1079 EC_GROUP *group =
NULL;
1080 point_conversion_form_t form;
1084 form = EC_GROUP_get_point_conversion_form(group);
1087 case POINT_CONVERSION_UNCOMPRESSED: ret = ID_uncompressed;
break;
1088 case POINT_CONVERSION_COMPRESSED: ret = ID_compressed;
break;
1089 case POINT_CONVERSION_HYBRID: ret = ID_hybrid;
break;
1090 default:
ossl_raise(
eEC_GROUP,
"unsupported point conversion form: %d, this module should be updated", form);
1096static point_conversion_form_t
1097parse_point_conversion_form_symbol(
VALUE sym)
1101 if (
id == ID_uncompressed)
1102 return POINT_CONVERSION_UNCOMPRESSED;
1103 else if (
id == ID_compressed)
1104 return POINT_CONVERSION_COMPRESSED;
1105 else if (
id == ID_hybrid)
1106 return POINT_CONVERSION_HYBRID;
1109 " (expected :compressed, :uncompressed, or :hybrid)",
sym);
1132ossl_ec_group_set_point_conversion_form(
VALUE self,
VALUE form_v)
1135 point_conversion_form_t form;
1138 form = parse_point_conversion_form_symbol(form_v);
1140 EC_GROUP_set_point_conversion_form(group, form);
1151static VALUE ossl_ec_group_get_seed(
VALUE self)
1153 EC_GROUP *group =
NULL;
1157 seed_len = EC_GROUP_get_seed_len(group);
1162 return rb_str_new((
const char *)EC_GROUP_get0_seed(group), seed_len);
1173 EC_GROUP *group =
NULL;
1192static VALUE ossl_ec_group_get_degree(
VALUE self)
1194 EC_GROUP *group =
NULL;
1198 return INT2NUM(EC_GROUP_get_degree(group));
1201static VALUE ossl_ec_group_to_string(
VALUE self,
int format)
1210 if (!(
out = BIO_new(BIO_s_mem())))
1215 i = PEM_write_bio_ECPKParameters(
out, group);
1218 i = i2d_ECPKParameters_bio(
out, group);
1243 return ossl_ec_group_to_string(self,
EXPORT_PEM);
1254 return ossl_ec_group_to_string(self,
EXPORT_DER);
1263static VALUE ossl_ec_group_to_text(
VALUE self)
1270 if (!(
out = BIO_new(BIO_s_mem()))) {
1273 if (!ECPKParameters_print(
out, group, 0)) {
1287ossl_ec_point_free(
void *
ptr)
1289 EC_POINT_clear_free(
ptr);
1295 0, ossl_ec_point_free,
1301ossl_ec_point_alloc(
VALUE klass)
1307ec_point_new(
const EC_POINT *
point,
const EC_GROUP *group)
1309 EC_POINT *point_new;
1313 point_new = EC_POINT_dup(
point, group);
1317 rb_ivar_set(obj, id_i_group, ec_group_new(group));
1338 VALUE group_v, arg2;
1339 const EC_GROUP *group;
1349 return ossl_ec_point_initialize_copy(self, group_v);
1354 point = EC_POINT_new(group);
1366 point = EC_POINT_new(group);
1369 if (!EC_POINT_oct2point(group,
point,
1372 EC_POINT_free(
point);
1385ossl_ec_point_initialize_copy(
VALUE self,
VALUE other)
1387 EC_POINT *
point, *point_new;
1399 point_new = EC_POINT_dup(
point, group);
1415 EC_POINT *point1, *point2;
1418 const EC_GROUP *group;
1420 if (ossl_ec_group_eql(group_v1, group_v2) ==
Qfalse)
1427 if (EC_POINT_cmp(group, point1, point2,
ossl_bn_ctx) == 1)
1437static VALUE ossl_ec_point_is_at_infinity(
VALUE self)
1440 const EC_GROUP *group;
1445 switch (EC_POINT_is_at_infinity(group,
point)) {
1446 case 1:
return Qtrue;
1458static VALUE ossl_ec_point_is_on_curve(
VALUE self)
1461 const EC_GROUP *group;
1467 case 1:
return Qtrue;
1479static VALUE ossl_ec_point_make_affine(
VALUE self)
1482 const EC_GROUP *group;
1500 const EC_GROUP *group;
1515static VALUE ossl_ec_point_set_to_infinity(
VALUE self)
1518 const EC_GROUP *group;
1523 if (EC_POINT_set_to_infinity(group,
point) != 1)
1542ossl_ec_point_to_octet_string(
VALUE self,
VALUE conversion_form)
1545 const EC_GROUP *group;
1546 point_conversion_form_t form;
1552 form = parse_point_conversion_form_symbol(conversion_form);
1558 if (!EC_POINT_point2oct(group,
point, form,
1573 EC_POINT *point_self, *point_other, *point_result;
1574 const EC_GROUP *group;
1583 ossl_ec_point_initialize(1, &group_v, result);
1586 if (EC_POINT_add(group, point_result, point_self, point_other,
ossl_bn_ctx) != 1) {
1612 EC_POINT *point_self, *point_result;
1613 const EC_GROUP *group;
1615 VALUE arg1, arg2, arg3, result;
1616 const BIGNUM *bn_g =
NULL;
1622 ossl_ec_point_initialize(1, &group_v, result);
1626 if (!RB_TYPE_P(arg1,
T_ARRAY)) {
1631 if (EC_POINT_mul(group, point_result, bn_g, point_self, bn,
ossl_bn_ctx) != 1)
1639 VALUE bns_tmp, tmp_p, tmp_b;
1640 const EC_POINT **points;
1641 const BIGNUM **bignums;
1651 for (i = 0; i <
num; i++) {
1658 points[0] = point_self;
1659 for (i = 0; i <
num - 1; i++)
1665 if (EC_POINTs_mul(group, point_result, bn_g,
num, points, bignums,
ossl_bn_ctx) != 1) {
1716 s_GF2m_simple =
rb_intern(
"GF2m_simple");
1718 ID_uncompressed =
rb_intern(
"uncompressed");
1719 ID_compressed =
rb_intern(
"compressed");
1723#if defined(OPENSSL_EC_EXPLICIT_CURVE)
VALUE rb_ary_push(VALUE ary, VALUE item)
VALUE rb_ary_tmp_new(long capa)
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
char str[HTML_ESCAPE_MAX_LEN+1]
#define RSTRING_LEN(string)
#define RSTRING_PTR(string)
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
VALUE rb_define_module_under(VALUE outer, const char *name)
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
void rb_raise(VALUE exc, const char *fmt,...)
VALUE rb_cObject
Object class.
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
VALUE rb_obj_dup(VALUE)
Equivalent to Object#dup in Ruby.
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Determines if obj is a kind of c.
unsigned in(void *in_desc, z_const unsigned char **buf)
VALUE rb_str_resize(VALUE, long)
#define rb_str_new(str, len)
void rb_str_set_len(VALUE, long)
VALUE rb_attr_get(VALUE, ID)
VALUE rb_ivar_set(VALUE, ID, VALUE)
void rb_attr(VALUE, ID, int, int, int)
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
ID rb_intern(const char *)
void rb_define_const(VALUE, const char *, VALUE)
#define ALLOCA_N(type, n)
int ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd_)
VALUE ossl_pem_passwd_value(VALUE pass)
void ossl_raise(VALUE exc, const char *fmt,...)
void ossl_clear_error(void)
#define OSSL_BIO_reset(bio)
BIO * ossl_obj2bio(volatile VALUE *pobj)
VALUE ossl_membio2str(BIO *bio)
VALUE ossl_bn_new(const BIGNUM *bn)
const EVP_CIPHER * ossl_evp_get_cipherbyname(VALUE obj)
#define GetPKey(obj, pkey)
#define SetPKey(obj, pkey)
#define GetECGroup(obj, group)
#define GetECPointGroup(obj, group)
VALUE ossl_ec_new(EVP_PKEY *pkey)
#define GetECPoint(obj, point)
#define RARRAY_AREF(a, i)
#define StringValueCStr(v)
#define RTYPEDDATA_DATA(v)
#define TypedData_Get_Struct(obj, type, data_type, sval)
#define TypedData_Wrap_Struct(klass, data_type, sval)
@ RUBY_TYPED_FREE_IMMEDIATELY