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 #if !defined(OPENSSL_NO_EC2M)
00761 } else if (id == s_GF2m_simple) {
00762 method = EC_GF2m_simple_method();
00763 #endif
00764 }
00765
00766 if (method) {
00767 if ((group = EC_GROUP_new(method)) == NULL)
00768 ossl_raise(eEC_GROUP, "EC_GROUP_new");
00769 } else {
00770 ossl_raise(rb_eArgError, "unknown symbol, must be :GFp_simple, :GFp_mont, :GFp_nist or :GF2m_simple");
00771 }
00772 } else if (rb_obj_is_kind_of(arg1, cEC_GROUP)) {
00773 const EC_GROUP *arg1_group;
00774
00775 SafeRequire_EC_GROUP(arg1, arg1_group);
00776 if ((group = EC_GROUP_dup(arg1_group)) == NULL)
00777 ossl_raise(eEC_GROUP, "EC_GROUP_dup");
00778 } else {
00779 BIO *in = ossl_obj2bio(arg1);
00780
00781 group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
00782 if (!group) {
00783 OSSL_BIO_reset(in);
00784 group = d2i_ECPKParameters_bio(in, NULL);
00785 }
00786
00787 BIO_free(in);
00788
00789 if (!group) {
00790 const char *name = StringValueCStr(arg1);
00791 int nid = OBJ_sn2nid(name);
00792
00793 (void)ERR_get_error();
00794 if (nid == NID_undef)
00795 ossl_raise(eEC_GROUP, "unknown curve name (%s)", name);
00796
00797 group = EC_GROUP_new_by_curve_name(nid);
00798 if (group == NULL)
00799 ossl_raise(eEC_GROUP, "unable to create curve (%s)", name);
00800
00801 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
00802 EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_UNCOMPRESSED);
00803 }
00804 }
00805
00806 break;
00807 case 4:
00808 if (SYMBOL_P(arg1)) {
00809 ID id = SYM2ID(arg1);
00810 EC_GROUP *(*new_curve)(const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *) = NULL;
00811 const BIGNUM *p = GetBNPtr(arg2);
00812 const BIGNUM *a = GetBNPtr(arg3);
00813 const BIGNUM *b = GetBNPtr(arg4);
00814
00815 if (id == s_GFp) {
00816 new_curve = EC_GROUP_new_curve_GFp;
00817 #if !defined(OPENSSL_NO_EC2M)
00818 } else if (id == s_GF2m) {
00819 new_curve = EC_GROUP_new_curve_GF2m;
00820 #endif
00821 } else {
00822 ossl_raise(rb_eArgError, "unknown symbol, must be :GFp or :GF2m");
00823 }
00824
00825 if ((group = new_curve(p, a, b, ossl_bn_ctx)) == NULL)
00826 ossl_raise(eEC_GROUP, "EC_GROUP_new_by_GF*");
00827 } else {
00828 ossl_raise(rb_eArgError, "unknown argument, must be :GFp or :GF2m");
00829 }
00830
00831 break;
00832 default:
00833 ossl_raise(rb_eArgError, "wrong number of arguments");
00834 }
00835
00836 if (group == NULL)
00837 ossl_raise(eEC_GROUP, "");
00838
00839 ec_group->group = group;
00840
00841 return self;
00842 }
00843
00844
00845
00846
00847
00848 static VALUE ossl_ec_group_eql(VALUE a, VALUE b)
00849 {
00850 EC_GROUP *group1 = NULL, *group2 = NULL;
00851
00852 Require_EC_GROUP(a, group1);
00853 SafeRequire_EC_GROUP(b, group2);
00854
00855 if (EC_GROUP_cmp(group1, group2, ossl_bn_ctx) == 1)
00856 return Qfalse;
00857
00858 return Qtrue;
00859 }
00860
00861
00862
00863
00864
00865
00866 static VALUE ossl_ec_group_get_generator(VALUE self)
00867 {
00868 VALUE point_obj;
00869 EC_GROUP *group = NULL;
00870
00871 Require_EC_GROUP(self, group);
00872
00873 point_obj = ossl_ec_point_dup(EC_GROUP_get0_generator(group), self);
00874
00875 return point_obj;
00876 }
00877
00878
00879
00880
00881
00882
00883 static VALUE ossl_ec_group_set_generator(VALUE self, VALUE generator, VALUE order, VALUE cofactor)
00884 {
00885 EC_GROUP *group = NULL;
00886 const EC_POINT *point;
00887 const BIGNUM *o, *co;
00888
00889 Require_EC_GROUP(self, group);
00890 SafeRequire_EC_POINT(generator, point);
00891 o = GetBNPtr(order);
00892 co = GetBNPtr(cofactor);
00893
00894 if (EC_GROUP_set_generator(group, point, o, co) != 1)
00895 ossl_raise(eEC_GROUP, "EC_GROUP_set_generator");
00896
00897 return self;
00898 }
00899
00900
00901
00902
00903
00904
00905 static VALUE ossl_ec_group_get_order(VALUE self)
00906 {
00907 VALUE bn_obj;
00908 BIGNUM *bn;
00909 EC_GROUP *group = NULL;
00910
00911 Require_EC_GROUP(self, group);
00912
00913 bn_obj = ossl_bn_new(NULL);
00914 bn = GetBNPtr(bn_obj);
00915
00916 if (EC_GROUP_get_order(group, bn, ossl_bn_ctx) != 1)
00917 ossl_raise(eEC_GROUP, "EC_GROUP_get_order");
00918
00919 return bn_obj;
00920 }
00921
00922
00923
00924
00925
00926
00927 static VALUE ossl_ec_group_get_cofactor(VALUE self)
00928 {
00929 VALUE bn_obj;
00930 BIGNUM *bn;
00931 EC_GROUP *group = NULL;
00932
00933 Require_EC_GROUP(self, group);
00934
00935 bn_obj = ossl_bn_new(NULL);
00936 bn = GetBNPtr(bn_obj);
00937
00938 if (EC_GROUP_get_cofactor(group, bn, ossl_bn_ctx) != 1)
00939 ossl_raise(eEC_GROUP, "EC_GROUP_get_cofactor");
00940
00941 return bn_obj;
00942 }
00943
00944
00945
00946
00947
00948
00949 static VALUE ossl_ec_group_get_curve_name(VALUE self)
00950 {
00951 EC_GROUP *group = NULL;
00952 int nid;
00953
00954 Get_EC_GROUP(self, group);
00955 if (group == NULL)
00956 return Qnil;
00957
00958 nid = EC_GROUP_get_curve_name(group);
00959
00960
00961 return rb_str_new2(OBJ_nid2sn(nid));
00962 }
00963
00964
00965
00966
00967
00968
00969 static VALUE ossl_s_builtin_curves(VALUE self)
00970 {
00971 EC_builtin_curve *curves = NULL;
00972 int n;
00973 int crv_len = rb_long2int(EC_get_builtin_curves(NULL, 0));
00974 VALUE ary, ret;
00975
00976 curves = ALLOCA_N(EC_builtin_curve, crv_len);
00977 if (curves == NULL)
00978 return Qnil;
00979 if (!EC_get_builtin_curves(curves, crv_len))
00980 ossl_raise(rb_eRuntimeError, "EC_get_builtin_curves");
00981
00982 ret = rb_ary_new2(crv_len);
00983
00984 for (n = 0; n < crv_len; n++) {
00985 const char *sname = OBJ_nid2sn(curves[n].nid);
00986 const char *comment = curves[n].comment;
00987
00988 ary = rb_ary_new2(2);
00989 rb_ary_push(ary, rb_str_new2(sname));
00990 rb_ary_push(ary, comment ? rb_str_new2(comment) : Qnil);
00991 rb_ary_push(ret, ary);
00992 }
00993
00994 return ret;
00995 }
00996
00997
00998
00999
01000
01001
01002 static VALUE ossl_ec_group_get_asn1_flag(VALUE self)
01003 {
01004 EC_GROUP *group = NULL;
01005 int flag;
01006
01007 Require_EC_GROUP(self, group);
01008
01009 flag = EC_GROUP_get_asn1_flag(group);
01010
01011 return INT2FIX(flag);
01012 }
01013
01014
01015
01016
01017
01018
01019 static VALUE ossl_ec_group_set_asn1_flag(VALUE self, VALUE flag_v)
01020 {
01021 EC_GROUP *group = NULL;
01022
01023 Require_EC_GROUP(self, group);
01024
01025 EC_GROUP_set_asn1_flag(group, NUM2INT(flag_v));
01026
01027 return flag_v;
01028 }
01029
01030
01031
01032
01033
01034
01035 static VALUE ossl_ec_group_get_point_conversion_form(VALUE self)
01036 {
01037 EC_GROUP *group = NULL;
01038 point_conversion_form_t form;
01039 VALUE ret;
01040
01041 Require_EC_GROUP(self, group);
01042
01043 form = EC_GROUP_get_point_conversion_form(group);
01044
01045 switch (form) {
01046 case POINT_CONVERSION_UNCOMPRESSED: ret = ID_uncompressed; break;
01047 case POINT_CONVERSION_COMPRESSED: ret = ID_compressed; break;
01048 case POINT_CONVERSION_HYBRID: ret = ID_hybrid; break;
01049 default: ossl_raise(eEC_GROUP, "unsupported point conversion form: %d, this module should be updated", form);
01050 }
01051
01052 return ID2SYM(ret);
01053 }
01054
01055
01056
01057
01058
01059
01060 static VALUE ossl_ec_group_set_point_conversion_form(VALUE self, VALUE form_v)
01061 {
01062 EC_GROUP *group = NULL;
01063 point_conversion_form_t form;
01064 ID form_id = SYM2ID(form_v);
01065
01066 Require_EC_GROUP(self, group);
01067
01068 if (form_id == ID_uncompressed) {
01069 form = POINT_CONVERSION_UNCOMPRESSED;
01070 } else if (form_id == ID_compressed) {
01071 form = POINT_CONVERSION_COMPRESSED;
01072 } else if (form_id == ID_hybrid) {
01073 form = POINT_CONVERSION_HYBRID;
01074 } else {
01075 ossl_raise(rb_eArgError, "form must be :compressed, :uncompressed, or :hybrid");
01076 }
01077
01078 EC_GROUP_set_point_conversion_form(group, form);
01079
01080 return form_v;
01081 }
01082
01083
01084
01085
01086
01087
01088 static VALUE ossl_ec_group_get_seed(VALUE self)
01089 {
01090 EC_GROUP *group = NULL;
01091 size_t seed_len;
01092
01093 Require_EC_GROUP(self, group);
01094
01095 seed_len = EC_GROUP_get_seed_len(group);
01096
01097 if (seed_len == 0)
01098 return Qnil;
01099
01100 return rb_str_new((const char *)EC_GROUP_get0_seed(group), seed_len);
01101 }
01102
01103
01104
01105
01106
01107
01108 static VALUE ossl_ec_group_set_seed(VALUE self, VALUE seed)
01109 {
01110 EC_GROUP *group = NULL;
01111
01112 Require_EC_GROUP(self, group);
01113 StringValue(seed);
01114
01115 if (EC_GROUP_set_seed(group, (unsigned char *)RSTRING_PTR(seed), RSTRING_LEN(seed)) != (size_t)RSTRING_LEN(seed))
01116 ossl_raise(eEC_GROUP, "EC_GROUP_set_seed");
01117
01118 return seed;
01119 }
01120
01121
01122
01123
01124
01125
01126
01127
01128 static VALUE ossl_ec_group_get_degree(VALUE self)
01129 {
01130 EC_GROUP *group = NULL;
01131
01132 Require_EC_GROUP(self, group);
01133
01134 return INT2NUM(EC_GROUP_get_degree(group));
01135 }
01136
01137 static VALUE ossl_ec_group_to_string(VALUE self, int format)
01138 {
01139 EC_GROUP *group;
01140 BIO *out;
01141 int i = -1;
01142 VALUE str;
01143
01144 Get_EC_GROUP(self, group);
01145
01146 if (!(out = BIO_new(BIO_s_mem())))
01147 ossl_raise(eEC_GROUP, "BIO_new(BIO_s_mem())");
01148
01149 switch(format) {
01150 case EXPORT_PEM:
01151 i = PEM_write_bio_ECPKParameters(out, group);
01152 break;
01153 case EXPORT_DER:
01154 i = i2d_ECPKParameters_bio(out, group);
01155 break;
01156 default:
01157 BIO_free(out);
01158 ossl_raise(rb_eRuntimeError, "unknown format (internal error)");
01159 }
01160
01161 if (i != 1) {
01162 BIO_free(out);
01163 ossl_raise(eECError, NULL);
01164 }
01165
01166 str = ossl_membio2str(out);
01167
01168 return str;
01169 }
01170
01171
01172
01173
01174
01175
01176 static VALUE ossl_ec_group_to_pem(VALUE self)
01177 {
01178 return ossl_ec_group_to_string(self, EXPORT_PEM);
01179 }
01180
01181
01182
01183
01184
01185
01186 static VALUE ossl_ec_group_to_der(VALUE self)
01187 {
01188 return ossl_ec_group_to_string(self, EXPORT_DER);
01189 }
01190
01191
01192
01193
01194
01195
01196 static VALUE ossl_ec_group_to_text(VALUE self)
01197 {
01198 EC_GROUP *group;
01199 BIO *out;
01200 VALUE str;
01201
01202 Require_EC_GROUP(self, group);
01203 if (!(out = BIO_new(BIO_s_mem()))) {
01204 ossl_raise(eEC_GROUP, "BIO_new(BIO_s_mem())");
01205 }
01206 if (!ECPKParameters_print(out, group, 0)) {
01207 BIO_free(out);
01208 ossl_raise(eEC_GROUP, NULL);
01209 }
01210 str = ossl_membio2str(out);
01211
01212 return str;
01213 }
01214
01215
01216 static void ossl_ec_point_free(ossl_ec_point *ec_point)
01217 {
01218 if (!ec_point->dont_free && ec_point->point)
01219 EC_POINT_clear_free(ec_point->point);
01220 ruby_xfree(ec_point);
01221 }
01222
01223 static VALUE ossl_ec_point_alloc(VALUE klass)
01224 {
01225 ossl_ec_point *ec_point;
01226 VALUE obj;
01227
01228 obj = Data_Make_Struct(klass, ossl_ec_point, 0, ossl_ec_point_free, ec_point);
01229
01230 return obj;
01231 }
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241 static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self)
01242 {
01243 ossl_ec_point *ec_point;
01244 EC_POINT *point = NULL;
01245 VALUE arg1, arg2;
01246 VALUE group_v = Qnil;
01247 const EC_GROUP *group = NULL;
01248
01249 Data_Get_Struct(self, ossl_ec_point, ec_point);
01250 if (ec_point->point)
01251 ossl_raise(eEC_POINT, "EC_POINT already initialized");
01252
01253 switch (rb_scan_args(argc, argv, "11", &arg1, &arg2)) {
01254 case 1:
01255 if (rb_obj_is_kind_of(arg1, cEC_POINT)) {
01256 const EC_POINT *arg_point;
01257
01258 group_v = rb_iv_get(arg1, "@group");
01259 SafeRequire_EC_GROUP(group_v, group);
01260 SafeRequire_EC_POINT(arg1, arg_point);
01261
01262 point = EC_POINT_dup(arg_point, group);
01263 } else if (rb_obj_is_kind_of(arg1, cEC_GROUP)) {
01264 group_v = arg1;
01265 SafeRequire_EC_GROUP(group_v, group);
01266
01267 point = EC_POINT_new(group);
01268 } else {
01269 ossl_raise(eEC_POINT, "wrong argument type: must be OpenSSL::PKey::EC::Point or OpenSSL::Pkey::EC::Group");
01270 }
01271
01272 break;
01273 case 2:
01274 if (!rb_obj_is_kind_of(arg1, cEC_GROUP))
01275 ossl_raise(rb_eArgError, "1st argument must be OpenSSL::PKey::EC::Group");
01276 group_v = arg1;
01277 SafeRequire_EC_GROUP(group_v, group);
01278
01279 if (rb_obj_is_kind_of(arg2, cBN)) {
01280 const BIGNUM *bn = GetBNPtr(arg2);
01281
01282 point = EC_POINT_bn2point(group, bn, NULL, ossl_bn_ctx);
01283 } else {
01284 BIO *in = ossl_obj2bio(arg1);
01285
01286
01287
01288 BIO_free(in);
01289
01290 if (point == NULL) {
01291 ossl_raise(eEC_POINT, "unknown type for 2nd arg");
01292 }
01293 }
01294 break;
01295 default:
01296 ossl_raise(rb_eArgError, "wrong number of arguments");
01297 }
01298
01299 if (point == NULL)
01300 ossl_raise(eEC_POINT, NULL);
01301
01302 if (NIL_P(group_v))
01303 ossl_raise(rb_eRuntimeError, "missing group (internal error)");
01304
01305 ec_point->point = point;
01306
01307 rb_iv_set(self, "@group", group_v);
01308
01309 return self;
01310 }
01311
01312
01313
01314
01315
01316
01317 static VALUE ossl_ec_point_eql(VALUE a, VALUE b)
01318 {
01319 EC_POINT *point1, *point2;
01320 VALUE group_v1 = rb_iv_get(a, "@group");
01321 VALUE group_v2 = rb_iv_get(b, "@group");
01322 const EC_GROUP *group;
01323
01324 if (ossl_ec_group_eql(group_v1, group_v2) == Qfalse)
01325 return Qfalse;
01326
01327 Require_EC_POINT(a, point1);
01328 SafeRequire_EC_POINT(b, point2);
01329 SafeRequire_EC_GROUP(group_v1, group);
01330
01331 if (EC_POINT_cmp(group, point1, point2, ossl_bn_ctx) == 1)
01332 return Qfalse;
01333
01334 return Qtrue;
01335 }
01336
01337
01338
01339
01340
01341
01342 static VALUE ossl_ec_point_is_at_infinity(VALUE self)
01343 {
01344 EC_POINT *point;
01345 VALUE group_v = rb_iv_get(self, "@group");
01346 const EC_GROUP *group;
01347
01348 Require_EC_POINT(self, point);
01349 SafeRequire_EC_GROUP(group_v, group);
01350
01351 switch (EC_POINT_is_at_infinity(group, point)) {
01352 case 1: return Qtrue;
01353 case 0: return Qfalse;
01354 default: ossl_raise(cEC_POINT, "EC_POINT_is_at_infinity");
01355 }
01356 }
01357
01358
01359
01360
01361
01362
01363 static VALUE ossl_ec_point_is_on_curve(VALUE self)
01364 {
01365 EC_POINT *point;
01366 VALUE group_v = rb_iv_get(self, "@group");
01367 const EC_GROUP *group;
01368
01369 Require_EC_POINT(self, point);
01370 SafeRequire_EC_GROUP(group_v, group);
01371
01372 switch (EC_POINT_is_on_curve(group, point, ossl_bn_ctx)) {
01373 case 1: return Qtrue;
01374 case 0: return Qfalse;
01375 default: ossl_raise(cEC_POINT, "EC_POINT_is_on_curve");
01376 }
01377 }
01378
01379
01380
01381
01382
01383
01384 static VALUE ossl_ec_point_make_affine(VALUE self)
01385 {
01386 EC_POINT *point;
01387 VALUE group_v = rb_iv_get(self, "@group");
01388 const EC_GROUP *group;
01389
01390 Require_EC_POINT(self, point);
01391 SafeRequire_EC_GROUP(group_v, group);
01392
01393 if (EC_POINT_make_affine(group, point, ossl_bn_ctx) != 1)
01394 ossl_raise(cEC_POINT, "EC_POINT_make_affine");
01395
01396 return self;
01397 }
01398
01399
01400
01401
01402
01403
01404 static VALUE ossl_ec_point_invert(VALUE self)
01405 {
01406 EC_POINT *point;
01407 VALUE group_v = rb_iv_get(self, "@group");
01408 const EC_GROUP *group;
01409
01410 Require_EC_POINT(self, point);
01411 SafeRequire_EC_GROUP(group_v, group);
01412
01413 if (EC_POINT_invert(group, point, ossl_bn_ctx) != 1)
01414 ossl_raise(cEC_POINT, "EC_POINT_invert");
01415
01416 return self;
01417 }
01418
01419
01420
01421
01422
01423
01424 static VALUE ossl_ec_point_set_to_infinity(VALUE self)
01425 {
01426 EC_POINT *point;
01427 VALUE group_v = rb_iv_get(self, "@group");
01428 const EC_GROUP *group;
01429
01430 Require_EC_POINT(self, point);
01431 SafeRequire_EC_GROUP(group_v, group);
01432
01433 if (EC_POINT_set_to_infinity(group, point) != 1)
01434 ossl_raise(cEC_POINT, "EC_POINT_set_to_infinity");
01435
01436 return self;
01437 }
01438
01439
01440
01441
01442
01443
01444
01445 static VALUE ossl_ec_point_to_bn(VALUE self)
01446 {
01447 EC_POINT *point;
01448 VALUE bn_obj;
01449 VALUE group_v = rb_iv_get(self, "@group");
01450 const EC_GROUP *group;
01451 point_conversion_form_t form;
01452 BIGNUM *bn;
01453
01454 Require_EC_POINT(self, point);
01455 SafeRequire_EC_GROUP(group_v, group);
01456
01457 form = EC_GROUP_get_point_conversion_form(group);
01458
01459 bn_obj = rb_obj_alloc(cBN);
01460 bn = GetBNPtr(bn_obj);
01461
01462 if (EC_POINT_point2bn(group, point, form, bn, ossl_bn_ctx) == NULL)
01463 ossl_raise(eEC_POINT, "EC_POINT_point2bn");
01464
01465 return bn_obj;
01466 }
01467
01468 static void no_copy(VALUE klass)
01469 {
01470 rb_undef_method(klass, "copy");
01471 rb_undef_method(klass, "clone");
01472 rb_undef_method(klass, "dup");
01473 rb_undef_method(klass, "initialize_copy");
01474 }
01475
01476 void Init_ossl_ec()
01477 {
01478 #ifdef DONT_NEED_RDOC_WORKAROUND
01479 mOSSL = rb_define_module("OpenSSL");
01480 mPKey = rb_define_module_under(mOSSL, "PKey");
01481 #endif
01482
01483 eECError = rb_define_class_under(mPKey, "ECError", ePKeyError);
01484
01485 cEC = rb_define_class_under(mPKey, "EC", cPKey);
01486 cEC_GROUP = rb_define_class_under(cEC, "Group", rb_cObject);
01487 cEC_POINT = rb_define_class_under(cEC, "Point", rb_cObject);
01488 eEC_GROUP = rb_define_class_under(cEC_GROUP, "Error", eOSSLError);
01489 eEC_POINT = rb_define_class_under(cEC_POINT, "Error", eOSSLError);
01490
01491 s_GFp = rb_intern("GFp");
01492 s_GF2m = rb_intern("GF2m");
01493 s_GFp_simple = rb_intern("GFp_simple");
01494 s_GFp_mont = rb_intern("GFp_mont");
01495 s_GFp_nist = rb_intern("GFp_nist");
01496 s_GF2m_simple = rb_intern("GF2m_simple");
01497
01498 ID_uncompressed = rb_intern("uncompressed");
01499 ID_compressed = rb_intern("compressed");
01500 ID_hybrid = rb_intern("hybrid");
01501
01502 #ifdef OPENSSL_EC_NAMED_CURVE
01503 rb_define_const(cEC, "NAMED_CURVE", ULONG2NUM(OPENSSL_EC_NAMED_CURVE));
01504 #endif
01505
01506 rb_define_singleton_method(cEC, "builtin_curves", ossl_s_builtin_curves, 0);
01507
01508 rb_define_method(cEC, "initialize", ossl_ec_key_initialize, -1);
01509
01510
01511 rb_define_method(cEC, "group", ossl_ec_key_get_group, 0);
01512 rb_define_method(cEC, "group=", ossl_ec_key_set_group, 1);
01513 rb_define_method(cEC, "private_key", ossl_ec_key_get_private_key, 0);
01514 rb_define_method(cEC, "private_key=", ossl_ec_key_set_private_key, 1);
01515 rb_define_method(cEC, "public_key", ossl_ec_key_get_public_key, 0);
01516 rb_define_method(cEC, "public_key=", ossl_ec_key_set_public_key, 1);
01517 rb_define_method(cEC, "private_key?", ossl_ec_key_is_private_key, 0);
01518 rb_define_method(cEC, "public_key?", ossl_ec_key_is_public_key, 0);
01519
01520
01521
01522
01523
01524
01525
01526 rb_define_method(cEC, "generate_key", ossl_ec_key_generate_key, 0);
01527 rb_define_method(cEC, "check_key", ossl_ec_key_check_key, 0);
01528
01529 rb_define_method(cEC, "dh_compute_key", ossl_ec_key_dh_compute_key, 1);
01530 rb_define_method(cEC, "dsa_sign_asn1", ossl_ec_key_dsa_sign_asn1, 1);
01531 rb_define_method(cEC, "dsa_verify_asn1", ossl_ec_key_dsa_verify_asn1, 2);
01532
01533
01534 rb_define_method(cEC, "to_pem", ossl_ec_key_to_pem, -1);
01535 rb_define_method(cEC, "to_der", ossl_ec_key_to_der, 0);
01536 rb_define_method(cEC, "to_text", ossl_ec_key_to_text, 0);
01537
01538
01539 rb_define_alloc_func(cEC_GROUP, ossl_ec_group_alloc);
01540 rb_define_method(cEC_GROUP, "initialize", ossl_ec_group_initialize, -1);
01541 rb_define_method(cEC_GROUP, "eql?", ossl_ec_group_eql, 1);
01542 rb_define_alias(cEC_GROUP, "==", "eql?");
01543
01544
01545 rb_define_method(cEC_GROUP, "generator", ossl_ec_group_get_generator, 0);
01546 rb_define_method(cEC_GROUP, "set_generator", ossl_ec_group_set_generator, 3);
01547 rb_define_method(cEC_GROUP, "order", ossl_ec_group_get_order, 0);
01548 rb_define_method(cEC_GROUP, "cofactor", ossl_ec_group_get_cofactor, 0);
01549
01550 rb_define_method(cEC_GROUP, "curve_name", ossl_ec_group_get_curve_name, 0);
01551
01552
01553 rb_define_method(cEC_GROUP, "asn1_flag", ossl_ec_group_get_asn1_flag, 0);
01554 rb_define_method(cEC_GROUP, "asn1_flag=", ossl_ec_group_set_asn1_flag, 1);
01555
01556 rb_define_method(cEC_GROUP, "point_conversion_form", ossl_ec_group_get_point_conversion_form, 0);
01557 rb_define_method(cEC_GROUP, "point_conversion_form=", ossl_ec_group_set_point_conversion_form, 1);
01558
01559 rb_define_method(cEC_GROUP, "seed", ossl_ec_group_get_seed, 0);
01560 rb_define_method(cEC_GROUP, "seed=", ossl_ec_group_set_seed, 1);
01561
01562
01563
01564 rb_define_method(cEC_GROUP, "degree", ossl_ec_group_get_degree, 0);
01565
01566
01567
01568
01569 rb_define_method(cEC_GROUP, "to_pem", ossl_ec_group_to_pem, 0);
01570 rb_define_method(cEC_GROUP, "to_der", ossl_ec_group_to_der, 0);
01571 rb_define_method(cEC_GROUP, "to_text", ossl_ec_group_to_text, 0);
01572
01573
01574 rb_define_alloc_func(cEC_POINT, ossl_ec_point_alloc);
01575 rb_define_method(cEC_POINT, "initialize", ossl_ec_point_initialize, -1);
01576 rb_attr(cEC_POINT, rb_intern("group"), 1, 0, 0);
01577 rb_define_method(cEC_POINT, "eql?", ossl_ec_point_eql, 1);
01578 rb_define_alias(cEC_POINT, "==", "eql?");
01579
01580 rb_define_method(cEC_POINT, "infinity?", ossl_ec_point_is_at_infinity, 0);
01581 rb_define_method(cEC_POINT, "on_curve?", ossl_ec_point_is_on_curve, 0);
01582 rb_define_method(cEC_POINT, "make_affine!", ossl_ec_point_make_affine, 0);
01583 rb_define_method(cEC_POINT, "invert!", ossl_ec_point_invert, 0);
01584 rb_define_method(cEC_POINT, "set_to_infinity!", ossl_ec_point_set_to_infinity, 0);
01585
01586
01587 rb_define_method(cEC_POINT, "to_bn", ossl_ec_point_to_bn, 0);
01588
01589 no_copy(cEC);
01590 no_copy(cEC_GROUP);
01591 no_copy(cEC_POINT);
01592 }
01593
01594 #else
01595 void Init_ossl_ec()
01596 {
01597 }
01598 #endif
01599