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