00001
00002
00003
00004
00005 #include "ossl.h"
00006
00007 #if !defined(OPENSSL_NO_EC) && (OPENSSL_VERSION_NUMBER >= 0x0090802fL)
00008
00009 typedef struct {
00010 EC_GROUP *group;
00011 int dont_free;
00012 } ossl_ec_group;
00013
00014 typedef struct {
00015 EC_POINT *point;
00016 int dont_free;
00017 } ossl_ec_point;
00018
00019
00020 #define EXPORT_PEM 0
00021 #define EXPORT_DER 1
00022
00023
00024 #define GetPKeyEC(obj, pkey) do { \
00025 GetPKey(obj, pkey); \
00026 if (EVP_PKEY_type(pkey->type) != EVP_PKEY_EC) { \
00027 ossl_raise(rb_eRuntimeError, "THIS IS NOT A EC PKEY!"); \
00028 } \
00029 } while (0)
00030
00031 #define SafeGet_ec_group(obj, group) do { \
00032 OSSL_Check_Kind(obj, cEC_GROUP); \
00033 Data_Get_Struct(obj, ossl_ec_group, group); \
00034 } while(0)
00035
00036 #define Get_EC_KEY(obj, key) do { \
00037 EVP_PKEY *pkey; \
00038 GetPKeyEC(obj, pkey); \
00039 key = pkey->pkey.ec; \
00040 } while(0)
00041
00042 #define Require_EC_KEY(obj, key) do { \
00043 Get_EC_KEY(obj, key); \
00044 if (key == NULL) \
00045 rb_raise(eECError, "EC_KEY is not initialized"); \
00046 } while(0)
00047
00048 #define SafeRequire_EC_KEY(obj, key) do { \
00049 OSSL_Check_Kind(obj, cEC); \
00050 Require_EC_KEY(obj, key); \
00051 } while (0)
00052
00053 #define Get_EC_GROUP(obj, g) do { \
00054 ossl_ec_group *ec_group; \
00055 Data_Get_Struct(obj, ossl_ec_group, ec_group); \
00056 if (ec_group == NULL) \
00057 rb_raise(eEC_GROUP, "missing ossl_ec_group structure"); \
00058 g = ec_group->group; \
00059 } while(0)
00060
00061 #define Require_EC_GROUP(obj, group) do { \
00062 Get_EC_GROUP(obj, group); \
00063 if (group == NULL) \
00064 rb_raise(eEC_GROUP, "EC_GROUP is not initialized"); \
00065 } while(0)
00066
00067 #define SafeRequire_EC_GROUP(obj, group) do { \
00068 OSSL_Check_Kind(obj, cEC_GROUP); \
00069 Require_EC_GROUP(obj, group); \
00070 } while(0)
00071
00072 #define Get_EC_POINT(obj, p) do { \
00073 ossl_ec_point *ec_point; \
00074 Data_Get_Struct(obj, ossl_ec_point, ec_point); \
00075 if (ec_point == NULL) \
00076 rb_raise(eEC_POINT, "missing ossl_ec_point structure"); \
00077 p = ec_point->point; \
00078 } while(0)
00079
00080 #define Require_EC_POINT(obj, point) do { \
00081 Get_EC_POINT(obj, point); \
00082 if (point == NULL) \
00083 rb_raise(eEC_POINT, "EC_POINT is not initialized"); \
00084 } while(0)
00085
00086 #define SafeRequire_EC_POINT(obj, point) do { \
00087 OSSL_Check_Kind(obj, cEC_POINT); \
00088 Require_EC_POINT(obj, point); \
00089 } while(0)
00090
00091 VALUE cEC;
00092 VALUE eECError;
00093 VALUE cEC_GROUP;
00094 VALUE eEC_GROUP;
00095 VALUE cEC_POINT;
00096 VALUE eEC_POINT;
00097
00098 static ID s_GFp;
00099 static ID s_GFp_simple;
00100 static ID s_GFp_mont;
00101 static ID s_GFp_nist;
00102 static ID s_GF2m;
00103 static ID s_GF2m_simple;
00104
00105 static ID ID_uncompressed;
00106 static ID ID_compressed;
00107 static ID ID_hybrid;
00108
00109 static VALUE ec_instance(VALUE klass, EC_KEY *ec)
00110 {
00111 EVP_PKEY *pkey;
00112 VALUE obj;
00113
00114 if (!ec) {
00115 return Qfalse;
00116 }
00117 if (!(pkey = EVP_PKEY_new())) {
00118 return Qfalse;
00119 }
00120 if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) {
00121 EVP_PKEY_free(pkey);
00122 return Qfalse;
00123 }
00124 WrapPKey(klass, obj, pkey);
00125
00126 return obj;
00127 }
00128
00129 VALUE ossl_ec_new(EVP_PKEY *pkey)
00130 {
00131 VALUE obj;
00132
00133 if (!pkey) {
00134 obj = ec_instance(cEC, EC_KEY_new());
00135 } else {
00136 if (EVP_PKEY_type(pkey->type) != EVP_PKEY_EC) {
00137 ossl_raise(rb_eTypeError, "Not a EC key!");
00138 }
00139 WrapPKey(cEC, obj, pkey);
00140 }
00141 if (obj == Qfalse) {
00142 ossl_raise(eECError, NULL);
00143 }
00144
00145 return obj;
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
00161 {
00162 EVP_PKEY *pkey;
00163 EC_KEY *ec = NULL;
00164 VALUE arg, pass;
00165 VALUE group = Qnil;
00166
00167 GetPKey(self, pkey);
00168 if (pkey->pkey.ec)
00169 rb_raise(eECError, "EC_KEY already initialized");
00170
00171 rb_scan_args(argc, argv, "02", &arg, &pass);
00172
00173 if (NIL_P(arg)) {
00174 ec = EC_KEY_new();
00175 } else {
00176 if (rb_obj_is_kind_of(arg, cEC)) {
00177 EC_KEY *other_ec = NULL;
00178
00179 SafeRequire_EC_KEY(arg, other_ec);
00180 ec = EC_KEY_dup(other_ec);
00181 } else if (rb_obj_is_kind_of(arg, cEC_GROUP)) {
00182 ec = EC_KEY_new();
00183 group = arg;
00184 } else {
00185 BIO *in = ossl_obj2bio(arg);
00186
00187 ec = PEM_read_bio_ECPrivateKey(in, NULL, NULL, NULL);
00188 if (!ec) {
00189 (void)BIO_reset(in);
00190 ec = PEM_read_bio_EC_PUBKEY(in, NULL, NULL, NULL);
00191 }
00192 if (!ec) {
00193 (void)BIO_reset(in);
00194 ec = d2i_ECPrivateKey_bio(in, NULL);
00195 }
00196 if (!ec) {
00197 (void)BIO_reset(in);
00198 ec = d2i_EC_PUBKEY_bio(in, NULL);
00199 }
00200
00201 BIO_free(in);
00202
00203 if (ec == NULL) {
00204 const char *name = StringValueCStr(arg);
00205 int nid = OBJ_sn2nid(name);
00206
00207 if (nid == NID_undef)
00208 ossl_raise(eECError, "unknown curve name (%s)\n", name);
00209
00210 if ((ec = EC_KEY_new_by_curve_name(nid)) == NULL)
00211 ossl_raise(eECError, "unable to create curve (%s)\n", name);
00212
00213 EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
00214 EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED);
00215 }
00216 }
00217 }
00218
00219 if (ec == NULL)
00220 ossl_raise(eECError, NULL);
00221
00222 if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) {
00223 EC_KEY_free(ec);
00224 ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
00225 }
00226
00227 rb_iv_set(self, "@group", Qnil);
00228
00229 if (!NIL_P(group))
00230 rb_funcall(self, rb_intern("group="), 1, arg);
00231
00232 return self;
00233 }
00234
00235
00236
00237
00238
00239
00240
00241
00242 static VALUE ossl_ec_key_get_group(VALUE self)
00243 {
00244 VALUE group_v;
00245 EC_KEY *ec;
00246 ossl_ec_group *ec_group;
00247 EC_GROUP *group;
00248
00249 Require_EC_KEY(self, ec);
00250
00251 group_v = rb_iv_get(self, "@group");
00252 if (!NIL_P(group_v))
00253 return group_v;
00254
00255 if ((group = (EC_GROUP *)EC_KEY_get0_group(ec)) != NULL) {
00256 group_v = rb_obj_alloc(cEC_GROUP);
00257 SafeGet_ec_group(group_v, ec_group);
00258 ec_group->group = group;
00259 ec_group->dont_free = 1;
00260 rb_iv_set(group_v, "@key", self);
00261 rb_iv_set(self, "@group", group_v);
00262 return group_v;
00263 }
00264
00265 return Qnil;
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 static VALUE ossl_ec_key_set_group(VALUE self, VALUE group_v)
00285 {
00286 VALUE old_group_v;
00287 EC_KEY *ec;
00288 EC_GROUP *group;
00289
00290 Require_EC_KEY(self, ec);
00291 SafeRequire_EC_GROUP(group_v, group);
00292
00293 old_group_v = rb_iv_get(self, "@group");
00294 if (!NIL_P(old_group_v)) {
00295 ossl_ec_group *old_ec_group;
00296 SafeGet_ec_group(old_group_v, old_ec_group);
00297
00298 old_ec_group->group = NULL;
00299 old_ec_group->dont_free = 0;
00300 rb_iv_set(old_group_v, "@key", Qnil);
00301 }
00302
00303 rb_iv_set(self, "@group", Qnil);
00304
00305 if (EC_KEY_set_group(ec, group) != 1)
00306 ossl_raise(eECError, "EC_KEY_set_group");
00307
00308 return group_v;
00309 }
00310
00311
00312
00313
00314
00315
00316
00317 static VALUE ossl_ec_key_get_private_key(VALUE self)
00318 {
00319 EC_KEY *ec;
00320 const BIGNUM *bn;
00321
00322 Require_EC_KEY(self, ec);
00323
00324 if ((bn = EC_KEY_get0_private_key(ec)) == NULL)
00325 return Qnil;
00326
00327 return ossl_bn_new(bn);
00328 }
00329
00330
00331
00332
00333
00334
00335
00336 static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key)
00337 {
00338 EC_KEY *ec;
00339 BIGNUM *bn = NULL;
00340
00341 Require_EC_KEY(self, ec);
00342 if (!NIL_P(private_key))
00343 bn = GetBNPtr(private_key);
00344
00345 switch (EC_KEY_set_private_key(ec, bn)) {
00346 case 1:
00347 break;
00348 case 0:
00349 if (bn == NULL)
00350 break;
00351 default:
00352 ossl_raise(eECError, "EC_KEY_set_private_key");
00353 }
00354
00355 return private_key;
00356 }
00357
00358
00359 static VALUE ossl_ec_point_dup(const EC_POINT *point, VALUE group_v)
00360 {
00361 VALUE obj;
00362 const EC_GROUP *group;
00363 ossl_ec_point *new_point;
00364
00365 obj = rb_obj_alloc(cEC_POINT);
00366 Data_Get_Struct(obj, ossl_ec_point, new_point);
00367
00368 SafeRequire_EC_GROUP(group_v, group);
00369
00370 new_point->point = EC_POINT_dup(point, group);
00371 if (new_point->point == NULL)
00372 ossl_raise(eEC_POINT, "EC_POINT_dup");
00373 rb_iv_set(obj, "@group", group_v);
00374
00375 return obj;
00376 }
00377
00378
00379
00380
00381
00382
00383
00384 static VALUE ossl_ec_key_get_public_key(VALUE self)
00385 {
00386 EC_KEY *ec;
00387 const EC_POINT *point;
00388 VALUE group;
00389
00390 Require_EC_KEY(self, ec);
00391
00392 if ((point = EC_KEY_get0_public_key(ec)) == NULL)
00393 return Qnil;
00394
00395 group = rb_funcall(self, rb_intern("group"), 0);
00396 if (NIL_P(group))
00397 ossl_raise(eECError, "EC_KEY_get0_get0_group (has public_key but no group???");
00398
00399 return ossl_ec_point_dup(point, group);
00400 }
00401
00402
00403
00404
00405
00406
00407
00408 static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key)
00409 {
00410 EC_KEY *ec;
00411 EC_POINT *point = NULL;
00412
00413 Require_EC_KEY(self, ec);
00414 if (!NIL_P(public_key))
00415 SafeRequire_EC_POINT(public_key, point);
00416
00417 switch (EC_KEY_set_public_key(ec, point)) {
00418 case 1:
00419 break;
00420 case 0:
00421 if (point == NULL)
00422 break;
00423 default:
00424 ossl_raise(eECError, "EC_KEY_set_public_key");
00425 }
00426
00427 return public_key;
00428 }
00429
00430
00431
00432
00433
00434
00435
00436 static VALUE ossl_ec_key_is_public_key(VALUE self)
00437 {
00438 EC_KEY *ec;
00439
00440 Require_EC_KEY(self, ec);
00441
00442 return (EC_KEY_get0_public_key(ec) ? Qtrue : Qfalse);
00443 }
00444
00445
00446
00447
00448
00449
00450
00451 static VALUE ossl_ec_key_is_private_key(VALUE self)
00452 {
00453 EC_KEY *ec;
00454
00455 Require_EC_KEY(self, ec);
00456
00457 return (EC_KEY_get0_private_key(ec) ? Qtrue : Qfalse);
00458 }
00459
00460 static VALUE ossl_ec_key_to_string(VALUE self, int format)
00461 {
00462 EC_KEY *ec;
00463 BIO *out;
00464 int i = -1;
00465 int private = 0;
00466 #if 0
00467 EVP_CIPHER *cipher = NULL;
00468 char *password = NULL;
00469 #endif
00470 VALUE str;
00471
00472 Require_EC_KEY(self, ec);
00473
00474 if (EC_KEY_get0_public_key(ec) == NULL)
00475 rb_raise(eECError, "can't export - no public key set");
00476
00477 if (EC_KEY_check_key(ec) != 1)
00478 ossl_raise(eECError, "can't export - EC_KEY_check_key failed");
00479
00480 if (EC_KEY_get0_private_key(ec))
00481 private = 1;
00482
00483 if (!(out = BIO_new(BIO_s_mem())))
00484 ossl_raise(eECError, "BIO_new(BIO_s_mem())");
00485
00486 switch(format) {
00487 case EXPORT_PEM:
00488 if (private) {
00489 #if 0
00490 if (cipher || password)
00491
00492 rb_notimplement();
00493 i = PEM_write_bio_ECPrivateKey(out, ec, cipher, NULL, 0, NULL, password);
00494 #endif
00495 i = PEM_write_bio_ECPrivateKey(out, ec, NULL, NULL, 0, NULL, NULL);
00496 } else {
00497 #if 0
00498 if (cipher || password)
00499 rb_raise(rb_eArgError, "encryption is not supported when exporting this key type");
00500 #endif
00501
00502 i = PEM_write_bio_EC_PUBKEY(out, ec);
00503 }
00504
00505 break;
00506 case EXPORT_DER:
00507 if (private) {
00508 #if 0
00509 if (cipher || password)
00510 rb_raise(rb_eArgError, "encryption is not supported when exporting this key type");
00511 #endif
00512
00513 i = i2d_ECPrivateKey_bio(out, ec);
00514 } else {
00515 #if 0
00516 if (cipher || password)
00517 rb_raise(rb_eArgError, "encryption is not supported when exporting this key type");
00518 #endif
00519
00520 i = i2d_EC_PUBKEY_bio(out, ec);
00521 }
00522
00523 break;
00524 default:
00525 BIO_free(out);
00526 rb_raise(rb_eRuntimeError, "unknown format (internal error)");
00527 }
00528
00529 if (i != 1) {
00530 BIO_free(out);
00531 ossl_raise(eECError, "outlen=%d", i);
00532 }
00533
00534 str = ossl_membio2str(out);
00535
00536 return str;
00537 }
00538
00539
00540
00541
00542
00543
00544
00545 static VALUE ossl_ec_key_to_pem(VALUE self)
00546 {
00547 return ossl_ec_key_to_string(self, EXPORT_PEM);
00548 }
00549
00550
00551
00552
00553
00554
00555
00556 static VALUE ossl_ec_key_to_der(VALUE self)
00557 {
00558 return ossl_ec_key_to_string(self, EXPORT_DER);
00559 }
00560
00561
00562
00563
00564
00565
00566
00567 static VALUE ossl_ec_key_to_text(VALUE self)
00568 {
00569 EC_KEY *ec;
00570 BIO *out;
00571 VALUE str;
00572
00573 Require_EC_KEY(self, ec);
00574 if (!(out = BIO_new(BIO_s_mem()))) {
00575 ossl_raise(eECError, "BIO_new(BIO_s_mem())");
00576 }
00577 if (!EC_KEY_print(out, ec, 0)) {
00578 BIO_free(out);
00579 ossl_raise(eECError, "EC_KEY_print");
00580 }
00581 str = ossl_membio2str(out);
00582
00583 return str;
00584 }
00585
00586
00587
00588
00589
00590
00591
00592 static VALUE ossl_ec_key_generate_key(VALUE self)
00593 {
00594 EC_KEY *ec;
00595
00596 Require_EC_KEY(self, ec);
00597
00598 if (EC_KEY_generate_key(ec) != 1)
00599 ossl_raise(eECError, "EC_KEY_generate_key");
00600
00601 return self;
00602 }
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612 static VALUE ossl_ec_key_check_key(VALUE self)
00613 {
00614 EC_KEY *ec;
00615
00616 Require_EC_KEY(self, ec);
00617
00618 if (EC_KEY_check_key(ec) != 1)
00619 ossl_raise(eECError, "EC_KEY_check_key");
00620
00621 return Qtrue;
00622 }
00623
00624
00625
00626
00627
00628
00629
00630 static VALUE ossl_ec_key_dh_compute_key(VALUE self, VALUE pubkey)
00631 {
00632 EC_KEY *ec;
00633 EC_POINT *point;
00634 int buf_len;
00635 VALUE str;
00636
00637 Require_EC_KEY(self, ec);
00638 SafeRequire_EC_POINT(pubkey, point);
00639
00640
00641 buf_len = 1024;
00642 str = rb_str_new(0, buf_len);
00643
00644 buf_len = ECDH_compute_key(RSTRING_PTR(str), buf_len, point, ec, NULL);
00645 if (buf_len < 0)
00646 ossl_raise(eECError, "ECDH_compute_key");
00647
00648 rb_str_resize(str, buf_len);
00649
00650 return str;
00651 }
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661 static VALUE ossl_ec_key_dsa_sign_asn1(VALUE self, VALUE data)
00662 {
00663 EC_KEY *ec;
00664 unsigned int buf_len;
00665 VALUE str;
00666
00667 Require_EC_KEY(self, ec);
00668 StringValue(data);
00669
00670 if (EC_KEY_get0_private_key(ec) == NULL)
00671 ossl_raise(eECError, "Private EC key needed!");
00672
00673 str = rb_str_new(0, ECDSA_size(ec) + 16);
00674 if (ECDSA_sign(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LEN(data), (unsigned char *) RSTRING_PTR(str), &buf_len, ec) != 1)
00675 ossl_raise(eECError, "ECDSA_sign");
00676
00677 rb_str_resize(str, buf_len);
00678
00679 return str;
00680 }
00681
00682
00683
00684
00685
00686
00687
00688 static VALUE ossl_ec_key_dsa_verify_asn1(VALUE self, VALUE data, VALUE sig)
00689 {
00690 EC_KEY *ec;
00691
00692 Require_EC_KEY(self, ec);
00693 StringValue(data);
00694 StringValue(sig);
00695
00696 switch (ECDSA_verify(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LEN(data), (unsigned char *) RSTRING_PTR(sig), RSTRING_LEN(sig), ec)) {
00697 case 1: return Qtrue;
00698 case 0: return Qfalse;
00699 default: break;
00700 }
00701
00702 ossl_raise(eECError, "ECDSA_verify");
00703 }
00704
00705 static void ossl_ec_group_free(ossl_ec_group *ec_group)
00706 {
00707 if (!ec_group->dont_free && ec_group->group)
00708 EC_GROUP_clear_free(ec_group->group);
00709 ruby_xfree(ec_group);
00710 }
00711
00712 static VALUE ossl_ec_group_alloc(VALUE klass)
00713 {
00714 ossl_ec_group *ec_group;
00715 VALUE obj;
00716
00717 obj = Data_Make_Struct(klass, ossl_ec_group, 0, ossl_ec_group_free, ec_group);
00718
00719 return obj;
00720 }
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738 static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self)
00739 {
00740 VALUE arg1, arg2, arg3, arg4;
00741 ossl_ec_group *ec_group;
00742 EC_GROUP *group = NULL;
00743
00744 Data_Get_Struct(self, ossl_ec_group, ec_group);
00745 if (ec_group->group != NULL)
00746 rb_raise(rb_eRuntimeError, "EC_GROUP is already initialized");
00747
00748 switch (rb_scan_args(argc, argv, "13", &arg1, &arg2, &arg3, &arg4)) {
00749 case 1:
00750 if (SYMBOL_P(arg1)) {
00751 const EC_METHOD *method = NULL;
00752 ID id = SYM2ID(arg1);
00753
00754 if (id == s_GFp_simple) {
00755 method = EC_GFp_simple_method();
00756 } else if (id == s_GFp_mont) {
00757 method = EC_GFp_mont_method();
00758 } else if (id == s_GFp_nist) {
00759 method = EC_GFp_nist_method();
00760 } else if (id == s_GF2m_simple) {
00761 method = EC_GF2m_simple_method();
00762 }
00763
00764 if (method) {
00765 if ((group = EC_GROUP_new(method)) == NULL)
00766 ossl_raise(eEC_GROUP, "EC_GROUP_new");
00767 } else {
00768 rb_raise(rb_eArgError, "unknown symbol, must be :GFp_simple, :GFp_mont, :GFp_nist or :GF2m_simple");
00769 }
00770 } else if (rb_obj_is_kind_of(arg1, cEC_GROUP)) {
00771 const EC_GROUP *arg1_group;
00772
00773 SafeRequire_EC_GROUP(arg1, arg1_group);
00774 if ((group = EC_GROUP_dup(arg1_group)) == NULL)
00775 ossl_raise(eEC_GROUP, "EC_GROUP_dup");
00776 } else {
00777 BIO *in = ossl_obj2bio(arg1);
00778
00779 group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
00780 if (!group) {
00781 (void)BIO_reset(in);
00782 group = d2i_ECPKParameters_bio(in, NULL);
00783 }
00784
00785 BIO_free(in);
00786
00787 if (!group) {
00788 const char *name = StringValueCStr(arg1);
00789 int nid = OBJ_sn2nid(name);
00790
00791 if (nid == NID_undef)
00792 ossl_raise(eEC_GROUP, "unknown curve name (%s)", name);
00793
00794 group = EC_GROUP_new_by_curve_name(nid);
00795 if (group == NULL)
00796 ossl_raise(eEC_GROUP, "unable to create curve (%s)", name);
00797
00798 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
00799 EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_UNCOMPRESSED);
00800 }
00801 }
00802
00803 break;
00804 case 4:
00805 if (SYMBOL_P(arg1)) {
00806 ID id = SYM2ID(arg1);
00807 EC_GROUP *(*new_curve)(const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *) = NULL;
00808 const BIGNUM *p = GetBNPtr(arg2);
00809 const BIGNUM *a = GetBNPtr(arg3);
00810 const BIGNUM *b = GetBNPtr(arg4);
00811
00812 if (id == s_GFp) {
00813 new_curve = EC_GROUP_new_curve_GFp;
00814 } else if (id == s_GF2m) {
00815 new_curve = EC_GROUP_new_curve_GF2m;
00816 } else {
00817 rb_raise(rb_eArgError, "unknown symbol, must be :GFp or :GF2m");
00818 }
00819
00820 if ((group = new_curve(p, a, b, ossl_bn_ctx)) == NULL)
00821 ossl_raise(eEC_GROUP, "EC_GROUP_new_by_GF*");
00822 } else {
00823 rb_raise(rb_eArgError, "unknown argument, must be :GFp or :GF2m");
00824 }
00825
00826 break;
00827 default:
00828 rb_raise(rb_eArgError, "wrong number of arguments");
00829 }
00830
00831 if (group == NULL)
00832 ossl_raise(eEC_GROUP, "");
00833
00834 ec_group->group = group;
00835
00836 return self;
00837 }
00838
00839
00840
00841
00842
00843 static VALUE ossl_ec_group_eql(VALUE a, VALUE b)
00844 {
00845 EC_GROUP *group1 = NULL, *group2 = NULL;
00846
00847 Require_EC_GROUP(a, group1);
00848 SafeRequire_EC_GROUP(b, group2);
00849
00850 if (EC_GROUP_cmp(group1, group2, ossl_bn_ctx) == 1)
00851 return Qfalse;
00852
00853 return Qtrue;
00854 }
00855
00856
00857
00858
00859
00860
00861 static VALUE ossl_ec_group_get_generator(VALUE self)
00862 {
00863 VALUE point_obj;
00864 EC_GROUP *group = NULL;
00865
00866 Require_EC_GROUP(self, group);
00867
00868 point_obj = ossl_ec_point_dup(EC_GROUP_get0_generator(group), self);
00869
00870 return point_obj;
00871 }
00872
00873
00874
00875
00876
00877
00878 static VALUE ossl_ec_group_set_generator(VALUE self, VALUE generator, VALUE order, VALUE cofactor)
00879 {
00880 EC_GROUP *group = NULL;
00881 const EC_POINT *point;
00882 const BIGNUM *o, *co;
00883
00884 Require_EC_GROUP(self, group);
00885 SafeRequire_EC_POINT(generator, point);
00886 o = GetBNPtr(order);
00887 co = GetBNPtr(cofactor);
00888
00889 if (EC_GROUP_set_generator(group, point, o, co) != 1)
00890 ossl_raise(eEC_GROUP, "EC_GROUP_set_generator");
00891
00892 return self;
00893 }
00894
00895
00896
00897
00898
00899
00900 static VALUE ossl_ec_group_get_order(VALUE self)
00901 {
00902 VALUE bn_obj;
00903 BIGNUM *bn;
00904 EC_GROUP *group = NULL;
00905
00906 Require_EC_GROUP(self, group);
00907
00908 bn_obj = ossl_bn_new(NULL);
00909 bn = GetBNPtr(bn_obj);
00910
00911 if (EC_GROUP_get_order(group, bn, ossl_bn_ctx) != 1)
00912 ossl_raise(eEC_GROUP, "EC_GROUP_get_order");
00913
00914 return bn_obj;
00915 }
00916
00917
00918
00919
00920
00921
00922 static VALUE ossl_ec_group_get_cofactor(VALUE self)
00923 {
00924 VALUE bn_obj;
00925 BIGNUM *bn;
00926 EC_GROUP *group = NULL;
00927
00928 Require_EC_GROUP(self, group);
00929
00930 bn_obj = ossl_bn_new(NULL);
00931 bn = GetBNPtr(bn_obj);
00932
00933 if (EC_GROUP_get_cofactor(group, bn, ossl_bn_ctx) != 1)
00934 ossl_raise(eEC_GROUP, "EC_GROUP_get_cofactor");
00935
00936 return bn_obj;
00937 }
00938
00939
00940
00941
00942
00943
00944 static VALUE ossl_ec_group_get_curve_name(VALUE self)
00945 {
00946 EC_GROUP *group = NULL;
00947 int nid;
00948
00949 Get_EC_GROUP(self, group);
00950 if (group == NULL)
00951 return Qnil;
00952
00953 nid = EC_GROUP_get_curve_name(group);
00954
00955
00956 return rb_str_new2(OBJ_nid2sn(nid));
00957 }
00958
00959
00960
00961
00962
00963
00964 static VALUE ossl_s_builtin_curves(VALUE self)
00965 {
00966 EC_builtin_curve *curves = NULL;
00967 int n;
00968 int crv_len = EC_get_builtin_curves(NULL, 0);
00969 VALUE ary, ret;
00970
00971 curves = ALLOCA_N(EC_builtin_curve, crv_len);
00972 if (curves == NULL)
00973 return Qnil;
00974 if (!EC_get_builtin_curves(curves, crv_len))
00975 ossl_raise(rb_eRuntimeError, "EC_get_builtin_curves");
00976
00977 ret = rb_ary_new2(crv_len);
00978
00979 for (n = 0; n < crv_len; n++) {
00980 const char *sname = OBJ_nid2sn(curves[n].nid);
00981 const char *comment = curves[n].comment;
00982
00983 ary = rb_ary_new2(2);
00984 rb_ary_push(ary, rb_str_new2(sname));
00985 rb_ary_push(ary, comment ? rb_str_new2(comment) : Qnil);
00986 rb_ary_push(ret, ary);
00987 }
00988
00989 return ret;
00990 }
00991
00992
00993
00994
00995
00996
00997 static VALUE ossl_ec_group_get_asn1_flag(VALUE self)
00998 {
00999 EC_GROUP *group = NULL;
01000 int flag;
01001
01002 Require_EC_GROUP(self, group);
01003
01004 flag = EC_GROUP_get_asn1_flag(group);
01005
01006 return INT2FIX(flag);
01007 }
01008
01009
01010
01011
01012
01013
01014 static VALUE ossl_ec_group_set_asn1_flag(VALUE self, VALUE flag_v)
01015 {
01016 EC_GROUP *group = NULL;
01017
01018 Require_EC_GROUP(self, group);
01019
01020 EC_GROUP_set_asn1_flag(group, NUM2INT(flag_v));
01021
01022 return flag_v;
01023 }
01024
01025
01026
01027
01028
01029
01030 static VALUE ossl_ec_group_get_point_conversion_form(VALUE self)
01031 {
01032 EC_GROUP *group = NULL;
01033 point_conversion_form_t form;
01034 VALUE ret;
01035
01036 Require_EC_GROUP(self, group);
01037
01038 form = EC_GROUP_get_point_conversion_form(group);
01039
01040 switch (form) {
01041 case POINT_CONVERSION_UNCOMPRESSED: ret = ID_uncompressed; break;
01042 case POINT_CONVERSION_COMPRESSED: ret = ID_compressed; break;
01043 case POINT_CONVERSION_HYBRID: ret = ID_hybrid; break;
01044 default: rb_raise(eEC_GROUP, "unsupported point conversion form: %d, this module should be updated", form);
01045 }
01046
01047 return ID2SYM(ret);
01048 }
01049
01050
01051
01052
01053
01054
01055 static VALUE ossl_ec_group_set_point_conversion_form(VALUE self, VALUE form_v)
01056 {
01057 EC_GROUP *group = NULL;
01058 point_conversion_form_t form;
01059 ID form_id = SYM2ID(form_v);
01060
01061 Require_EC_GROUP(self, group);
01062
01063 if (form_id == ID_uncompressed) {
01064 form = POINT_CONVERSION_UNCOMPRESSED;
01065 } else if (form_id == ID_compressed) {
01066 form = POINT_CONVERSION_COMPRESSED;
01067 } else if (form_id == ID_hybrid) {
01068 form = POINT_CONVERSION_HYBRID;
01069 } else {
01070 rb_raise(rb_eArgError, "form must be :compressed, :uncompressed, or :hybrid");
01071 }
01072
01073 EC_GROUP_set_point_conversion_form(group, form);
01074
01075 return form_v;
01076 }
01077
01078
01079
01080
01081
01082
01083 static VALUE ossl_ec_group_get_seed(VALUE self)
01084 {
01085 EC_GROUP *group = NULL;
01086 size_t seed_len;
01087
01088 Require_EC_GROUP(self, group);
01089
01090 seed_len = EC_GROUP_get_seed_len(group);
01091
01092 if (seed_len == 0)
01093 return Qnil;
01094
01095 return rb_str_new((const char *)EC_GROUP_get0_seed(group), seed_len);
01096 }
01097
01098
01099
01100
01101
01102
01103 static VALUE ossl_ec_group_set_seed(VALUE self, VALUE seed)
01104 {
01105 EC_GROUP *group = NULL;
01106
01107 Require_EC_GROUP(self, group);
01108 StringValue(seed);
01109
01110 if (EC_GROUP_set_seed(group, (unsigned char *)RSTRING_PTR(seed), RSTRING_LEN(seed)) != RSTRING_LEN(seed))
01111 ossl_raise(eEC_GROUP, "EC_GROUP_set_seed");
01112
01113 return seed;
01114 }
01115
01116
01117
01118
01119
01120
01121
01122
01123 static VALUE ossl_ec_group_get_degree(VALUE self)
01124 {
01125 EC_GROUP *group = NULL;
01126
01127 Require_EC_GROUP(self, group);
01128
01129 return INT2NUM(EC_GROUP_get_degree(group));
01130 }
01131
01132 static VALUE ossl_ec_group_to_string(VALUE self, int format)
01133 {
01134 EC_GROUP *group;
01135 BIO *out;
01136 int i = -1;
01137 VALUE str;
01138
01139 Get_EC_GROUP(self, group);
01140
01141 if (!(out = BIO_new(BIO_s_mem())))
01142 ossl_raise(eEC_GROUP, "BIO_new(BIO_s_mem())");
01143
01144 switch(format) {
01145 case EXPORT_PEM:
01146 i = PEM_write_bio_ECPKParameters(out, group);
01147 break;
01148 case EXPORT_DER:
01149 i = i2d_ECPKParameters_bio(out, group);
01150 break;
01151 default:
01152 BIO_free(out);
01153 rb_raise(rb_eRuntimeError, "unknown format (internal error)");
01154 }
01155
01156 if (i != 1) {
01157 BIO_free(out);
01158 ossl_raise(eECError, NULL);
01159 }
01160
01161 str = ossl_membio2str(out);
01162
01163 return str;
01164 }
01165
01166
01167
01168
01169
01170
01171 static VALUE ossl_ec_group_to_pem(VALUE self)
01172 {
01173 return ossl_ec_group_to_string(self, EXPORT_PEM);
01174 }
01175
01176
01177
01178
01179
01180
01181 static VALUE ossl_ec_group_to_der(VALUE self)
01182 {
01183 return ossl_ec_group_to_string(self, EXPORT_DER);
01184 }
01185
01186
01187
01188
01189
01190
01191 static VALUE ossl_ec_group_to_text(VALUE self)
01192 {
01193 EC_GROUP *group;
01194 BIO *out;
01195 VALUE str;
01196
01197 Require_EC_GROUP(self, group);
01198 if (!(out = BIO_new(BIO_s_mem()))) {
01199 ossl_raise(eEC_GROUP, "BIO_new(BIO_s_mem())");
01200 }
01201 if (!ECPKParameters_print(out, group, 0)) {
01202 BIO_free(out);
01203 ossl_raise(eEC_GROUP, NULL);
01204 }
01205 str = ossl_membio2str(out);
01206
01207 return str;
01208 }
01209
01210
01211 static void ossl_ec_point_free(ossl_ec_point *ec_point)
01212 {
01213 if (!ec_point->dont_free && ec_point->point)
01214 EC_POINT_clear_free(ec_point->point);
01215 ruby_xfree(ec_point);
01216 }
01217
01218 static VALUE ossl_ec_point_alloc(VALUE klass)
01219 {
01220 ossl_ec_point *ec_point;
01221 VALUE obj;
01222
01223 obj = Data_Make_Struct(klass, ossl_ec_point, 0, ossl_ec_point_free, ec_point);
01224
01225 return obj;
01226 }
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236 static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self)
01237 {
01238 ossl_ec_point *ec_point;
01239 EC_POINT *point = NULL;
01240 VALUE arg1, arg2;
01241 VALUE group_v = Qnil;
01242 const EC_GROUP *group = NULL;
01243
01244 Data_Get_Struct(self, ossl_ec_point, ec_point);
01245 if (ec_point->point)
01246 rb_raise(eEC_POINT, "EC_POINT already initialized");
01247
01248 switch (rb_scan_args(argc, argv, "11", &arg1, &arg2)) {
01249 case 1:
01250 if (rb_obj_is_kind_of(arg1, cEC_POINT)) {
01251 const EC_POINT *arg_point;
01252
01253 group_v = rb_iv_get(arg1, "@group");
01254 SafeRequire_EC_GROUP(group_v, group);
01255 SafeRequire_EC_POINT(arg1, arg_point);
01256
01257 point = EC_POINT_dup(arg_point, group);
01258 } else if (rb_obj_is_kind_of(arg1, cEC_GROUP)) {
01259 group_v = arg1;
01260 SafeRequire_EC_GROUP(group_v, group);
01261
01262 point = EC_POINT_new(group);
01263 } else {
01264 rb_raise(eEC_POINT, "wrong argument type: must be OpenSSL::PKey::EC::Point or OpenSSL::Pkey::EC::Group");
01265 }
01266
01267 break;
01268 case 2:
01269 if (!rb_obj_is_kind_of(arg1, cEC_GROUP))
01270 rb_raise(rb_eArgError, "1st argument must be OpenSSL::PKey::EC::Group");
01271 group_v = arg1;
01272 SafeRequire_EC_GROUP(group_v, group);
01273
01274 if (rb_obj_is_kind_of(arg2, cBN)) {
01275 const BIGNUM *bn = GetBNPtr(arg2);
01276
01277 point = EC_POINT_bn2point(group, bn, NULL, ossl_bn_ctx);
01278 } else {
01279 BIO *in = ossl_obj2bio(arg1);
01280
01281
01282
01283 BIO_free(in);
01284
01285 if (point == NULL) {
01286 ossl_raise(eEC_POINT, "unknown type for 2nd arg");
01287 }
01288 }
01289 break;
01290 default:
01291 rb_raise(rb_eArgError, "wrong number of arguments");
01292 }
01293
01294 if (point == NULL)
01295 ossl_raise(eEC_POINT, NULL);
01296
01297 if (NIL_P(group_v))
01298 rb_raise(rb_eRuntimeError, "missing group (internal error)");
01299
01300 ec_point->point = point;
01301
01302 rb_iv_set(self, "@group", group_v);
01303
01304 return self;
01305 }
01306
01307
01308
01309
01310
01311
01312 static VALUE ossl_ec_point_eql(VALUE a, VALUE b)
01313 {
01314 EC_POINT *point1, *point2;
01315 VALUE group_v1 = rb_iv_get(a, "@group");
01316 VALUE group_v2 = rb_iv_get(b, "@group");
01317 const EC_GROUP *group;
01318
01319 if (ossl_ec_group_eql(group_v1, group_v2) == Qfalse)
01320 return Qfalse;
01321
01322 Require_EC_POINT(a, point1);
01323 SafeRequire_EC_POINT(b, point2);
01324 SafeRequire_EC_GROUP(group_v1, group);
01325
01326 if (EC_POINT_cmp(group, point1, point2, ossl_bn_ctx) == 1)
01327 return Qfalse;
01328
01329 return Qtrue;
01330 }
01331
01332
01333
01334
01335
01336
01337 static VALUE ossl_ec_point_is_at_infinity(VALUE self)
01338 {
01339 EC_POINT *point;
01340 VALUE group_v = rb_iv_get(self, "@group");
01341 const EC_GROUP *group;
01342
01343 Require_EC_POINT(self, point);
01344 SafeRequire_EC_GROUP(group_v, group);
01345
01346 switch (EC_POINT_is_at_infinity(group, point)) {
01347 case 1: return Qtrue;
01348 case 0: return Qfalse;
01349 default: ossl_raise(cEC_POINT, "EC_POINT_is_at_infinity");
01350 }
01351 }
01352
01353
01354
01355
01356
01357
01358 static VALUE ossl_ec_point_is_on_curve(VALUE self)
01359 {
01360 EC_POINT *point;
01361 VALUE group_v = rb_iv_get(self, "@group");
01362 const EC_GROUP *group;
01363
01364 Require_EC_POINT(self, point);
01365 SafeRequire_EC_GROUP(group_v, group);
01366
01367 switch (EC_POINT_is_on_curve(group, point, ossl_bn_ctx)) {
01368 case 1: return Qtrue;
01369 case 0: return Qfalse;
01370 default: ossl_raise(cEC_POINT, "EC_POINT_is_on_curve");
01371 }
01372 }
01373
01374
01375
01376
01377
01378
01379 static VALUE ossl_ec_point_make_affine(VALUE self)
01380 {
01381 EC_POINT *point;
01382 VALUE group_v = rb_iv_get(self, "@group");
01383 const EC_GROUP *group;
01384
01385 Require_EC_POINT(self, point);
01386 SafeRequire_EC_GROUP(group_v, group);
01387
01388 if (EC_POINT_make_affine(group, point, ossl_bn_ctx) != 1)
01389 ossl_raise(cEC_POINT, "EC_POINT_make_affine");
01390
01391 return self;
01392 }
01393
01394
01395
01396
01397
01398
01399 static VALUE ossl_ec_point_invert(VALUE self)
01400 {
01401 EC_POINT *point;
01402 VALUE group_v = rb_iv_get(self, "@group");
01403 const EC_GROUP *group;
01404
01405 Require_EC_POINT(self, point);
01406 SafeRequire_EC_GROUP(group_v, group);
01407
01408 if (EC_POINT_invert(group, point, ossl_bn_ctx) != 1)
01409 ossl_raise(cEC_POINT, "EC_POINT_invert");
01410
01411 return self;
01412 }
01413
01414
01415
01416
01417
01418
01419 static VALUE ossl_ec_point_set_to_infinity(VALUE self)
01420 {
01421 EC_POINT *point;
01422 VALUE group_v = rb_iv_get(self, "@group");
01423 const EC_GROUP *group;
01424
01425 Require_EC_POINT(self, point);
01426 SafeRequire_EC_GROUP(group_v, group);
01427
01428 if (EC_POINT_set_to_infinity(group, point) != 1)
01429 ossl_raise(cEC_POINT, "EC_POINT_set_to_infinity");
01430
01431 return self;
01432 }
01433
01434
01435
01436
01437
01438
01439
01440 static VALUE ossl_ec_point_to_bn(VALUE self)
01441 {
01442 EC_POINT *point;
01443 VALUE bn_obj;
01444 VALUE group_v = rb_iv_get(self, "@group");
01445 const EC_GROUP *group;
01446 point_conversion_form_t form;
01447 BIGNUM *bn;
01448
01449 Require_EC_POINT(self, point);
01450 SafeRequire_EC_GROUP(group_v, group);
01451
01452 form = EC_GROUP_get_point_conversion_form(group);
01453
01454 bn_obj = rb_obj_alloc(cBN);
01455 bn = GetBNPtr(bn_obj);
01456
01457 if (EC_POINT_point2bn(group, point, form, bn, ossl_bn_ctx) == NULL)
01458 ossl_raise(eEC_POINT, "EC_POINT_point2bn");
01459
01460 return bn_obj;
01461 }
01462
01463 static void no_copy(VALUE klass)
01464 {
01465 rb_undef_method(klass, "copy");
01466 rb_undef_method(klass, "clone");
01467 rb_undef_method(klass, "dup");
01468 rb_undef_method(klass, "initialize_copy");
01469 }
01470
01471 void Init_ossl_ec()
01472 {
01473 #ifdef DONT_NEED_RDOC_WORKAROUND
01474 mOSSL = rb_define_module("OpenSSL");
01475 mPKey = rb_define_module_under(mOSSL, "PKey");
01476 #endif
01477
01478 eECError = rb_define_class_under(mPKey, "ECError", ePKeyError);
01479
01480 cEC = rb_define_class_under(mPKey, "EC", cPKey);
01481 cEC_GROUP = rb_define_class_under(cEC, "Group", rb_cObject);
01482 cEC_POINT = rb_define_class_under(cEC, "Point", rb_cObject);
01483 eEC_GROUP = rb_define_class_under(cEC_GROUP, "Error", eOSSLError);
01484 eEC_POINT = rb_define_class_under(cEC_POINT, "Error", eOSSLError);
01485
01486 s_GFp = rb_intern("GFp");
01487 s_GF2m = rb_intern("GF2m");
01488 s_GFp_simple = rb_intern("GFp_simple");
01489 s_GFp_mont = rb_intern("GFp_mont");
01490 s_GFp_nist = rb_intern("GFp_nist");
01491 s_GF2m_simple = rb_intern("GF2m_simple");
01492
01493 ID_uncompressed = rb_intern("uncompressed");
01494 ID_compressed = rb_intern("compressed");
01495 ID_hybrid = rb_intern("hybrid");
01496
01497 #ifdef OPENSSL_EC_NAMED_CURVE
01498 rb_define_const(cEC, "NAMED_CURVE", ULONG2NUM(OPENSSL_EC_NAMED_CURVE));
01499 #endif
01500
01501 rb_define_singleton_method(cEC, "builtin_curves", ossl_s_builtin_curves, 0);
01502
01503 rb_define_method(cEC, "initialize", ossl_ec_key_initialize, -1);
01504
01505
01506 rb_define_method(cEC, "group", ossl_ec_key_get_group, 0);
01507 rb_define_method(cEC, "group=", ossl_ec_key_set_group, 1);
01508 rb_define_method(cEC, "private_key", ossl_ec_key_get_private_key, 0);
01509 rb_define_method(cEC, "private_key=", ossl_ec_key_set_private_key, 1);
01510 rb_define_method(cEC, "public_key", ossl_ec_key_get_public_key, 0);
01511 rb_define_method(cEC, "public_key=", ossl_ec_key_set_public_key, 1);
01512 rb_define_method(cEC, "private_key?", ossl_ec_key_is_private_key, 0);
01513 rb_define_method(cEC, "public_key?", ossl_ec_key_is_public_key, 0);
01514
01515
01516
01517
01518
01519
01520
01521 rb_define_method(cEC, "generate_key", ossl_ec_key_generate_key, 0);
01522 rb_define_method(cEC, "check_key", ossl_ec_key_check_key, 0);
01523
01524 rb_define_method(cEC, "dh_compute_key", ossl_ec_key_dh_compute_key, 1);
01525 rb_define_method(cEC, "dsa_sign_asn1", ossl_ec_key_dsa_sign_asn1, 1);
01526 rb_define_method(cEC, "dsa_verify_asn1", ossl_ec_key_dsa_verify_asn1, 2);
01527
01528
01529 rb_define_method(cEC, "to_pem", ossl_ec_key_to_pem, 0);
01530 rb_define_method(cEC, "to_der", ossl_ec_key_to_der, 0);
01531 rb_define_method(cEC, "to_text", ossl_ec_key_to_text, 0);
01532
01533
01534 rb_define_alloc_func(cEC_GROUP, ossl_ec_group_alloc);
01535 rb_define_method(cEC_GROUP, "initialize", ossl_ec_group_initialize, -1);
01536 rb_define_method(cEC_GROUP, "eql?", ossl_ec_group_eql, 1);
01537 rb_define_alias(cEC_GROUP, "==", "eql?");
01538
01539
01540 rb_define_method(cEC_GROUP, "generator", ossl_ec_group_get_generator, 0);
01541 rb_define_method(cEC_GROUP, "set_generator", ossl_ec_group_set_generator, 3);
01542 rb_define_method(cEC_GROUP, "order", ossl_ec_group_get_order, 0);
01543 rb_define_method(cEC_GROUP, "cofactor", ossl_ec_group_get_cofactor, 0);
01544
01545 rb_define_method(cEC_GROUP, "curve_name", ossl_ec_group_get_curve_name, 0);
01546
01547
01548 rb_define_method(cEC_GROUP, "asn1_flag", ossl_ec_group_get_asn1_flag, 0);
01549 rb_define_method(cEC_GROUP, "asn1_flag=", ossl_ec_group_set_asn1_flag, 1);
01550
01551 rb_define_method(cEC_GROUP, "point_conversion_form", ossl_ec_group_get_point_conversion_form, 0);
01552 rb_define_method(cEC_GROUP, "point_conversion_form=", ossl_ec_group_set_point_conversion_form, 1);
01553
01554 rb_define_method(cEC_GROUP, "seed", ossl_ec_group_get_seed, 0);
01555 rb_define_method(cEC_GROUP, "seed=", ossl_ec_group_set_seed, 1);
01556
01557
01558
01559 rb_define_method(cEC_GROUP, "degree", ossl_ec_group_get_degree, 0);
01560
01561
01562
01563
01564 rb_define_method(cEC_GROUP, "to_pem", ossl_ec_group_to_pem, 0);
01565 rb_define_method(cEC_GROUP, "to_der", ossl_ec_group_to_der, 0);
01566 rb_define_method(cEC_GROUP, "to_text", ossl_ec_group_to_text, 0);
01567
01568
01569 rb_define_alloc_func(cEC_POINT, ossl_ec_point_alloc);
01570 rb_define_method(cEC_POINT, "initialize", ossl_ec_point_initialize, -1);
01571 rb_attr(cEC_POINT, rb_intern("group"), 1, 0, 0);
01572 rb_define_method(cEC_POINT, "eql?", ossl_ec_point_eql, 1);
01573 rb_define_alias(cEC_POINT, "==", "eql?");
01574
01575 rb_define_method(cEC_POINT, "infinity?", ossl_ec_point_is_at_infinity, 0);
01576 rb_define_method(cEC_POINT, "on_curve?", ossl_ec_point_is_on_curve, 0);
01577 rb_define_method(cEC_POINT, "make_affine!", ossl_ec_point_make_affine, 0);
01578 rb_define_method(cEC_POINT, "invert!", ossl_ec_point_invert, 0);
01579 rb_define_method(cEC_POINT, "set_to_infinity!", ossl_ec_point_set_to_infinity, 0);
01580
01581
01582 rb_define_method(cEC_POINT, "to_bn", ossl_ec_point_to_bn, 0);
01583
01584 no_copy(cEC);
01585 no_copy(cEC_GROUP);
01586 no_copy(cEC_POINT);
01587 }
01588
01589 #else
01590 void Init_ossl_ec()
01591 {
01592 }
01593 #endif
01594