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