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);
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) {
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);
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;
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));
377 EC_POINT *point =
NULL;
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)
671ossl_ec_group_free(
void *
ptr)
673 EC_GROUP_clear_free(
ptr);
679 0, ossl_ec_group_free,
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)
768 group = PEM_read_bio_ECPKParameters(in,
NULL,
NULL,
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,
1307ec_point_new(
const EC_POINT *point,
const EC_GROUP *group)
1309 EC_POINT *point_new;
1313 point_new = EC_POINT_dup(point, 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;
1466 switch (EC_POINT_is_on_curve(group, point,
ossl_bn_ctx)) {
1467 case 1:
return Qtrue;
1479static VALUE ossl_ec_point_make_affine(
VALUE self)
1482 const EC_GROUP *group;
1487 if (EC_POINT_make_affine(group, point,
ossl_bn_ctx) != 1)
1500 const EC_GROUP *group;
1505 if (EC_POINT_invert(group, point,
ossl_bn_ctx) != 1)
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,
1584 EC_POINT *point_self, *point_result;
1585 const EC_GROUP *group;
1587 VALUE arg1, arg2, arg3, result;
1588 const BIGNUM *bn_g =
NULL;
1594 ossl_ec_point_initialize(1, &group_v, result);
1603 if (EC_POINT_mul(group, point_result, bn_g, point_self, bn,
ossl_bn_ctx) != 1)
1611 VALUE bns_tmp, tmp_p, tmp_b;
1612 const EC_POINT **points;
1613 const BIGNUM **bignums;
1622 bignums =
ALLOCV_N(
const BIGNUM *, tmp_b, num);
1623 for (
i = 0;
i < num;
i++) {
1629 points =
ALLOCV_N(
const EC_POINT *, tmp_p, num);
1630 points[0] = point_self;
1631 for (
i = 0;
i < num - 1;
i++)
1637 if (EC_POINTs_mul(group, point_result, bn_g, num, points, bignums,
ossl_bn_ctx) != 1) {
1688 s_GF2m_simple =
rb_intern(
"GF2m_simple");
1690 ID_uncompressed =
rb_intern(
"uncompressed");
1691 ID_compressed =
rb_intern(
"compressed");
1695#if defined(OPENSSL_EC_EXPLICIT_CURVE)
char str[HTML_ESCAPE_MAX_LEN+1]
VALUE rb_define_class_under(VALUE, const char *, VALUE)
Defines a class under the namespace of outer.
VALUE rb_define_module_under(VALUE, const char *)
void rb_define_alias(VALUE, const char *, const char *)
Defines an alias of a method.
VALUE rb_cObject
Object class.
void rb_raise(VALUE exc, const char *fmt,...)
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.
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)