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 StringValue(pass);
00497 if (RSTRING_LENINT(pass) < OSSL_MIN_PWD_LEN)
00498 ossl_raise(eOSSLError, "OpenSSL requires passwords to be at least four characters long");
00499 password = RSTRING_PTR(pass);
00500 }
00501 }
00502 else {
00503 cipher = NULL;
00504 }
00505 i = PEM_write_bio_ECPrivateKey(out, ec, cipher, NULL, 0, NULL, password);
00506 } else {
00507 i = PEM_write_bio_EC_PUBKEY(out, ec);
00508 }
00509
00510 break;
00511 case EXPORT_DER:
00512 if (private) {
00513 i = i2d_ECPrivateKey_bio(out, ec);
00514 } else {
00515 i = i2d_EC_PUBKEY_bio(out, ec);
00516 }
00517
00518 break;
00519 default:
00520 BIO_free(out);
00521 ossl_raise(rb_eRuntimeError, "unknown format (internal error)");
00522 }
00523
00524 if (i != 1) {
00525 BIO_free(out);
00526 ossl_raise(eECError, "outlen=%d", i);
00527 }
00528
00529 str = ossl_membio2str(out);
00530
00531 return str;
00532 }
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546 static VALUE ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
00547 {
00548 VALUE cipher, passwd;
00549 rb_scan_args(argc, argv, "02", &cipher, &passwd);
00550 return ossl_ec_key_to_string(self, cipher, passwd, EXPORT_PEM);
00551 }
00552
00553
00554
00555
00556
00557
00558
00559 static VALUE ossl_ec_key_to_der(VALUE self)
00560 {
00561 return ossl_ec_key_to_string(self, Qnil, Qnil, EXPORT_DER);
00562 }
00563
00564
00565
00566
00567
00568
00569
00570 static VALUE ossl_ec_key_to_text(VALUE self)
00571 {
00572 EC_KEY *ec;
00573 BIO *out;
00574 VALUE str;
00575
00576 Require_EC_KEY(self, ec);
00577 if (!(out = BIO_new(BIO_s_mem()))) {
00578 ossl_raise(eECError, "BIO_new(BIO_s_mem())");
00579 }
00580 if (!EC_KEY_print(out, ec, 0)) {
00581 BIO_free(out);
00582 ossl_raise(eECError, "EC_KEY_print");
00583 }
00584 str = ossl_membio2str(out);
00585
00586 return str;
00587 }
00588
00589
00590
00591
00592
00593
00594
00595 static VALUE ossl_ec_key_generate_key(VALUE self)
00596 {
00597 EC_KEY *ec;
00598
00599 Require_EC_KEY(self, ec);
00600
00601 if (EC_KEY_generate_key(ec) != 1)
00602 ossl_raise(eECError, "EC_KEY_generate_key");
00603
00604 return self;
00605 }
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615 static VALUE ossl_ec_key_check_key(VALUE self)
00616 {
00617 EC_KEY *ec;
00618
00619 Require_EC_KEY(self, ec);
00620
00621 if (EC_KEY_check_key(ec) != 1)
00622 ossl_raise(eECError, "EC_KEY_check_key");
00623
00624 return Qtrue;
00625 }
00626
00627
00628
00629
00630
00631
00632
00633 static VALUE ossl_ec_key_dh_compute_key(VALUE self, VALUE pubkey)
00634 {
00635 EC_KEY *ec;
00636 EC_POINT *point;
00637 int buf_len;
00638 VALUE str;
00639
00640 Require_EC_KEY(self, ec);
00641 SafeRequire_EC_POINT(pubkey, point);
00642
00643
00644 buf_len = 1024;
00645 str = rb_str_new(0, buf_len);
00646
00647 buf_len = ECDH_compute_key(RSTRING_PTR(str), buf_len, point, ec, NULL);
00648 if (buf_len < 0)
00649 ossl_raise(eECError, "ECDH_compute_key");
00650
00651 rb_str_resize(str, buf_len);
00652
00653 return str;
00654 }
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664 static VALUE ossl_ec_key_dsa_sign_asn1(VALUE self, VALUE data)
00665 {
00666 EC_KEY *ec;
00667 unsigned int buf_len;
00668 VALUE str;
00669
00670 Require_EC_KEY(self, ec);
00671 StringValue(data);
00672
00673 if (EC_KEY_get0_private_key(ec) == NULL)
00674 ossl_raise(eECError, "Private EC key needed!");
00675
00676 str = rb_str_new(0, ECDSA_size(ec) + 16);
00677 if (ECDSA_sign(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LENINT(data), (unsigned char *) RSTRING_PTR(str), &buf_len, ec) != 1)
00678 ossl_raise(eECError, "ECDSA_sign");
00679
00680 rb_str_resize(str, buf_len);
00681
00682 return str;
00683 }
00684
00685
00686
00687
00688
00689
00690
00691 static VALUE ossl_ec_key_dsa_verify_asn1(VALUE self, VALUE data, VALUE sig)
00692 {
00693 EC_KEY *ec;
00694
00695 Require_EC_KEY(self, ec);
00696 StringValue(data);
00697 StringValue(sig);
00698
00699 switch (ECDSA_verify(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LENINT(data), (unsigned char *) RSTRING_PTR(sig), (int)RSTRING_LEN(sig), ec)) {
00700 case 1: return Qtrue;
00701 case 0: return Qfalse;
00702 default: break;
00703 }
00704
00705 ossl_raise(eECError, "ECDSA_verify");
00706
00707 UNREACHABLE;
00708 }
00709
00710 static void ossl_ec_group_free(ossl_ec_group *ec_group)
00711 {
00712 if (!ec_group->dont_free && ec_group->group)
00713 EC_GROUP_clear_free(ec_group->group);
00714 ruby_xfree(ec_group);
00715 }
00716
00717 static VALUE ossl_ec_group_alloc(VALUE klass)
00718 {
00719 ossl_ec_group *ec_group;
00720 VALUE obj;
00721
00722 obj = Data_Make_Struct(klass, ossl_ec_group, 0, ossl_ec_group_free, ec_group);
00723
00724 return obj;
00725 }
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743 static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self)
00744 {
00745 VALUE arg1, arg2, arg3, arg4;
00746 ossl_ec_group *ec_group;
00747 EC_GROUP *group = NULL;
00748
00749 Data_Get_Struct(self, ossl_ec_group, ec_group);
00750 if (ec_group->group != NULL)
00751 ossl_raise(rb_eRuntimeError, "EC_GROUP is already initialized");
00752
00753 switch (rb_scan_args(argc, argv, "13", &arg1, &arg2, &arg3, &arg4)) {
00754 case 1:
00755 if (SYMBOL_P(arg1)) {
00756 const EC_METHOD *method = NULL;
00757 ID id = SYM2ID(arg1);
00758
00759 if (id == s_GFp_simple) {
00760 method = EC_GFp_simple_method();
00761 } else if (id == s_GFp_mont) {
00762 method = EC_GFp_mont_method();
00763 } else if (id == s_GFp_nist) {
00764 method = EC_GFp_nist_method();
00765 #if !defined(OPENSSL_NO_EC2M)
00766 } else if (id == s_GF2m_simple) {
00767 method = EC_GF2m_simple_method();
00768 #endif
00769 }
00770
00771 if (method) {
00772 if ((group = EC_GROUP_new(method)) == NULL)
00773 ossl_raise(eEC_GROUP, "EC_GROUP_new");
00774 } else {
00775 ossl_raise(rb_eArgError, "unknown symbol, must be :GFp_simple, :GFp_mont, :GFp_nist or :GF2m_simple");
00776 }
00777 } else if (rb_obj_is_kind_of(arg1, cEC_GROUP)) {
00778 const EC_GROUP *arg1_group;
00779
00780 SafeRequire_EC_GROUP(arg1, arg1_group);
00781 if ((group = EC_GROUP_dup(arg1_group)) == NULL)
00782 ossl_raise(eEC_GROUP, "EC_GROUP_dup");
00783 } else {
00784 BIO *in = ossl_obj2bio(arg1);
00785
00786 group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
00787 if (!group) {
00788 OSSL_BIO_reset(in);
00789 group = d2i_ECPKParameters_bio(in, NULL);
00790 }
00791
00792 BIO_free(in);
00793
00794 if (!group) {
00795 const char *name = StringValueCStr(arg1);
00796 int nid = OBJ_sn2nid(name);
00797
00798 (void)ERR_get_error();
00799 if (nid == NID_undef)
00800 ossl_raise(eEC_GROUP, "unknown curve name (%s)", name);
00801
00802 group = EC_GROUP_new_by_curve_name(nid);
00803 if (group == NULL)
00804 ossl_raise(eEC_GROUP, "unable to create curve (%s)", name);
00805
00806 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
00807 EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_UNCOMPRESSED);
00808 }
00809 }
00810
00811 break;
00812 case 4:
00813 if (SYMBOL_P(arg1)) {
00814 ID id = SYM2ID(arg1);
00815 EC_GROUP *(*new_curve)(const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *) = NULL;
00816 const BIGNUM *p = GetBNPtr(arg2);
00817 const BIGNUM *a = GetBNPtr(arg3);
00818 const BIGNUM *b = GetBNPtr(arg4);
00819
00820 if (id == s_GFp) {
00821 new_curve = EC_GROUP_new_curve_GFp;
00822 #if !defined(OPENSSL_NO_EC2M)
00823 } else if (id == s_GF2m) {
00824 new_curve = EC_GROUP_new_curve_GF2m;
00825 #endif
00826 } else {
00827 ossl_raise(rb_eArgError, "unknown symbol, must be :GFp or :GF2m");
00828 }
00829
00830 if ((group = new_curve(p, a, b, ossl_bn_ctx)) == NULL)
00831 ossl_raise(eEC_GROUP, "EC_GROUP_new_by_GF*");
00832 } else {
00833 ossl_raise(rb_eArgError, "unknown argument, must be :GFp or :GF2m");
00834 }
00835
00836 break;
00837 default:
00838 ossl_raise(rb_eArgError, "wrong number of arguments");
00839 }
00840
00841 if (group == NULL)
00842 ossl_raise(eEC_GROUP, "");
00843
00844 ec_group->group = group;
00845
00846 return self;
00847 }
00848
00849
00850
00851
00852
00853
00854 static VALUE ossl_ec_group_eql(VALUE a, VALUE b)
00855 {
00856 EC_GROUP *group1 = NULL, *group2 = NULL;
00857
00858 Require_EC_GROUP(a, group1);
00859 SafeRequire_EC_GROUP(b, group2);
00860
00861 if (EC_GROUP_cmp(group1, group2, ossl_bn_ctx) == 1)
00862 return Qfalse;
00863
00864 return Qtrue;
00865 }
00866
00867
00868
00869
00870
00871
00872 static VALUE ossl_ec_group_get_generator(VALUE self)
00873 {
00874 VALUE point_obj;
00875 EC_GROUP *group = NULL;
00876
00877 Require_EC_GROUP(self, group);
00878
00879 point_obj = ossl_ec_point_dup(EC_GROUP_get0_generator(group), self);
00880
00881 return point_obj;
00882 }
00883
00884
00885
00886
00887
00888
00889 static VALUE ossl_ec_group_set_generator(VALUE self, VALUE generator, VALUE order, VALUE cofactor)
00890 {
00891 EC_GROUP *group = NULL;
00892 const EC_POINT *point;
00893 const BIGNUM *o, *co;
00894
00895 Require_EC_GROUP(self, group);
00896 SafeRequire_EC_POINT(generator, point);
00897 o = GetBNPtr(order);
00898 co = GetBNPtr(cofactor);
00899
00900 if (EC_GROUP_set_generator(group, point, o, co) != 1)
00901 ossl_raise(eEC_GROUP, "EC_GROUP_set_generator");
00902
00903 return self;
00904 }
00905
00906
00907
00908
00909
00910
00911 static VALUE ossl_ec_group_get_order(VALUE self)
00912 {
00913 VALUE bn_obj;
00914 BIGNUM *bn;
00915 EC_GROUP *group = NULL;
00916
00917 Require_EC_GROUP(self, group);
00918
00919 bn_obj = ossl_bn_new(NULL);
00920 bn = GetBNPtr(bn_obj);
00921
00922 if (EC_GROUP_get_order(group, bn, ossl_bn_ctx) != 1)
00923 ossl_raise(eEC_GROUP, "EC_GROUP_get_order");
00924
00925 return bn_obj;
00926 }
00927
00928
00929
00930
00931
00932
00933 static VALUE ossl_ec_group_get_cofactor(VALUE self)
00934 {
00935 VALUE bn_obj;
00936 BIGNUM *bn;
00937 EC_GROUP *group = NULL;
00938
00939 Require_EC_GROUP(self, group);
00940
00941 bn_obj = ossl_bn_new(NULL);
00942 bn = GetBNPtr(bn_obj);
00943
00944 if (EC_GROUP_get_cofactor(group, bn, ossl_bn_ctx) != 1)
00945 ossl_raise(eEC_GROUP, "EC_GROUP_get_cofactor");
00946
00947 return bn_obj;
00948 }
00949
00950
00951
00952
00953
00954
00955 static VALUE ossl_ec_group_get_curve_name(VALUE self)
00956 {
00957 EC_GROUP *group = NULL;
00958 int nid;
00959
00960 Get_EC_GROUP(self, group);
00961 if (group == NULL)
00962 return Qnil;
00963
00964 nid = EC_GROUP_get_curve_name(group);
00965
00966
00967 return rb_str_new2(OBJ_nid2sn(nid));
00968 }
00969
00970
00971
00972
00973
00974
00975 static VALUE ossl_s_builtin_curves(VALUE self)
00976 {
00977 EC_builtin_curve *curves = NULL;
00978 int n;
00979 int crv_len = rb_long2int(EC_get_builtin_curves(NULL, 0));
00980 VALUE ary, ret;
00981
00982 curves = ALLOCA_N(EC_builtin_curve, crv_len);
00983 if (curves == NULL)
00984 return Qnil;
00985 if (!EC_get_builtin_curves(curves, crv_len))
00986 ossl_raise(rb_eRuntimeError, "EC_get_builtin_curves");
00987
00988 ret = rb_ary_new2(crv_len);
00989
00990 for (n = 0; n < crv_len; n++) {
00991 const char *sname = OBJ_nid2sn(curves[n].nid);
00992 const char *comment = curves[n].comment;
00993
00994 ary = rb_ary_new2(2);
00995 rb_ary_push(ary, rb_str_new2(sname));
00996 rb_ary_push(ary, comment ? rb_str_new2(comment) : Qnil);
00997 rb_ary_push(ret, ary);
00998 }
00999
01000 return ret;
01001 }
01002
01003
01004
01005
01006
01007
01008 static VALUE ossl_ec_group_get_asn1_flag(VALUE self)
01009 {
01010 EC_GROUP *group = NULL;
01011 int flag;
01012
01013 Require_EC_GROUP(self, group);
01014
01015 flag = EC_GROUP_get_asn1_flag(group);
01016
01017 return INT2FIX(flag);
01018 }
01019
01020
01021
01022
01023
01024
01025 static VALUE ossl_ec_group_set_asn1_flag(VALUE self, VALUE flag_v)
01026 {
01027 EC_GROUP *group = NULL;
01028
01029 Require_EC_GROUP(self, group);
01030
01031 EC_GROUP_set_asn1_flag(group, NUM2INT(flag_v));
01032
01033 return flag_v;
01034 }
01035
01036
01037
01038
01039
01040
01041 static VALUE ossl_ec_group_get_point_conversion_form(VALUE self)
01042 {
01043 EC_GROUP *group = NULL;
01044 point_conversion_form_t form;
01045 VALUE ret;
01046
01047 Require_EC_GROUP(self, group);
01048
01049 form = EC_GROUP_get_point_conversion_form(group);
01050
01051 switch (form) {
01052 case POINT_CONVERSION_UNCOMPRESSED: ret = ID_uncompressed; break;
01053 case POINT_CONVERSION_COMPRESSED: ret = ID_compressed; break;
01054 case POINT_CONVERSION_HYBRID: ret = ID_hybrid; break;
01055 default: ossl_raise(eEC_GROUP, "unsupported point conversion form: %d, this module should be updated", form);
01056 }
01057
01058 return ID2SYM(ret);
01059 }
01060
01061
01062
01063
01064
01065
01066 static VALUE ossl_ec_group_set_point_conversion_form(VALUE self, VALUE form_v)
01067 {
01068 EC_GROUP *group = NULL;
01069 point_conversion_form_t form;
01070 ID form_id = SYM2ID(form_v);
01071
01072 Require_EC_GROUP(self, group);
01073
01074 if (form_id == ID_uncompressed) {
01075 form = POINT_CONVERSION_UNCOMPRESSED;
01076 } else if (form_id == ID_compressed) {
01077 form = POINT_CONVERSION_COMPRESSED;
01078 } else if (form_id == ID_hybrid) {
01079 form = POINT_CONVERSION_HYBRID;
01080 } else {
01081 ossl_raise(rb_eArgError, "form must be :compressed, :uncompressed, or :hybrid");
01082 }
01083
01084 EC_GROUP_set_point_conversion_form(group, form);
01085
01086 return form_v;
01087 }
01088
01089
01090
01091
01092
01093
01094 static VALUE ossl_ec_group_get_seed(VALUE self)
01095 {
01096 EC_GROUP *group = NULL;
01097 size_t seed_len;
01098
01099 Require_EC_GROUP(self, group);
01100
01101 seed_len = EC_GROUP_get_seed_len(group);
01102
01103 if (seed_len == 0)
01104 return Qnil;
01105
01106 return rb_str_new((const char *)EC_GROUP_get0_seed(group), seed_len);
01107 }
01108
01109
01110
01111
01112
01113
01114 static VALUE ossl_ec_group_set_seed(VALUE self, VALUE seed)
01115 {
01116 EC_GROUP *group = NULL;
01117
01118 Require_EC_GROUP(self, group);
01119 StringValue(seed);
01120
01121 if (EC_GROUP_set_seed(group, (unsigned char *)RSTRING_PTR(seed), RSTRING_LEN(seed)) != (size_t)RSTRING_LEN(seed))
01122 ossl_raise(eEC_GROUP, "EC_GROUP_set_seed");
01123
01124 return seed;
01125 }
01126
01127
01128
01129
01130
01131
01132
01133
01134 static VALUE ossl_ec_group_get_degree(VALUE self)
01135 {
01136 EC_GROUP *group = NULL;
01137
01138 Require_EC_GROUP(self, group);
01139
01140 return INT2NUM(EC_GROUP_get_degree(group));
01141 }
01142
01143 static VALUE ossl_ec_group_to_string(VALUE self, int format)
01144 {
01145 EC_GROUP *group;
01146 BIO *out;
01147 int i = -1;
01148 VALUE str;
01149
01150 Get_EC_GROUP(self, group);
01151
01152 if (!(out = BIO_new(BIO_s_mem())))
01153 ossl_raise(eEC_GROUP, "BIO_new(BIO_s_mem())");
01154
01155 switch(format) {
01156 case EXPORT_PEM:
01157 i = PEM_write_bio_ECPKParameters(out, group);
01158 break;
01159 case EXPORT_DER:
01160 i = i2d_ECPKParameters_bio(out, group);
01161 break;
01162 default:
01163 BIO_free(out);
01164 ossl_raise(rb_eRuntimeError, "unknown format (internal error)");
01165 }
01166
01167 if (i != 1) {
01168 BIO_free(out);
01169 ossl_raise(eECError, NULL);
01170 }
01171
01172 str = ossl_membio2str(out);
01173
01174 return str;
01175 }
01176
01177
01178
01179
01180
01181
01182 static VALUE ossl_ec_group_to_pem(VALUE self)
01183 {
01184 return ossl_ec_group_to_string(self, EXPORT_PEM);
01185 }
01186
01187
01188
01189
01190
01191
01192 static VALUE ossl_ec_group_to_der(VALUE self)
01193 {
01194 return ossl_ec_group_to_string(self, EXPORT_DER);
01195 }
01196
01197
01198
01199
01200
01201
01202 static VALUE ossl_ec_group_to_text(VALUE self)
01203 {
01204 EC_GROUP *group;
01205 BIO *out;
01206 VALUE str;
01207
01208 Require_EC_GROUP(self, group);
01209 if (!(out = BIO_new(BIO_s_mem()))) {
01210 ossl_raise(eEC_GROUP, "BIO_new(BIO_s_mem())");
01211 }
01212 if (!ECPKParameters_print(out, group, 0)) {
01213 BIO_free(out);
01214 ossl_raise(eEC_GROUP, NULL);
01215 }
01216 str = ossl_membio2str(out);
01217
01218 return str;
01219 }
01220
01221
01222 static void ossl_ec_point_free(ossl_ec_point *ec_point)
01223 {
01224 if (!ec_point->dont_free && ec_point->point)
01225 EC_POINT_clear_free(ec_point->point);
01226 ruby_xfree(ec_point);
01227 }
01228
01229 static VALUE ossl_ec_point_alloc(VALUE klass)
01230 {
01231 ossl_ec_point *ec_point;
01232 VALUE obj;
01233
01234 obj = Data_Make_Struct(klass, ossl_ec_point, 0, ossl_ec_point_free, ec_point);
01235
01236 return obj;
01237 }
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247 static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self)
01248 {
01249 ossl_ec_point *ec_point;
01250 EC_POINT *point = NULL;
01251 VALUE arg1, arg2;
01252 VALUE group_v = Qnil;
01253 const EC_GROUP *group = NULL;
01254
01255 Data_Get_Struct(self, ossl_ec_point, ec_point);
01256 if (ec_point->point)
01257 ossl_raise(eEC_POINT, "EC_POINT already initialized");
01258
01259 switch (rb_scan_args(argc, argv, "11", &arg1, &arg2)) {
01260 case 1:
01261 if (rb_obj_is_kind_of(arg1, cEC_POINT)) {
01262 const EC_POINT *arg_point;
01263
01264 group_v = rb_iv_get(arg1, "@group");
01265 SafeRequire_EC_GROUP(group_v, group);
01266 SafeRequire_EC_POINT(arg1, arg_point);
01267
01268 point = EC_POINT_dup(arg_point, group);
01269 } else if (rb_obj_is_kind_of(arg1, cEC_GROUP)) {
01270 group_v = arg1;
01271 SafeRequire_EC_GROUP(group_v, group);
01272
01273 point = EC_POINT_new(group);
01274 } else {
01275 ossl_raise(eEC_POINT, "wrong argument type: must be OpenSSL::PKey::EC::Point or OpenSSL::Pkey::EC::Group");
01276 }
01277
01278 break;
01279 case 2:
01280 if (!rb_obj_is_kind_of(arg1, cEC_GROUP))
01281 ossl_raise(rb_eArgError, "1st argument must be OpenSSL::PKey::EC::Group");
01282 group_v = arg1;
01283 SafeRequire_EC_GROUP(group_v, group);
01284
01285 if (rb_obj_is_kind_of(arg2, cBN)) {
01286 const BIGNUM *bn = GetBNPtr(arg2);
01287
01288 point = EC_POINT_bn2point(group, bn, NULL, ossl_bn_ctx);
01289 } else {
01290 BIO *in = ossl_obj2bio(arg1);
01291
01292
01293
01294 BIO_free(in);
01295
01296 if (point == NULL) {
01297 ossl_raise(eEC_POINT, "unknown type for 2nd arg");
01298 }
01299 }
01300 break;
01301 default:
01302 ossl_raise(rb_eArgError, "wrong number of arguments");
01303 }
01304
01305 if (point == NULL)
01306 ossl_raise(eEC_POINT, NULL);
01307
01308 if (NIL_P(group_v))
01309 ossl_raise(rb_eRuntimeError, "missing group (internal error)");
01310
01311 ec_point->point = point;
01312
01313 rb_iv_set(self, "@group", group_v);
01314
01315 return self;
01316 }
01317
01318
01319
01320
01321
01322
01323
01324 static VALUE ossl_ec_point_eql(VALUE a, VALUE b)
01325 {
01326 EC_POINT *point1, *point2;
01327 VALUE group_v1 = rb_iv_get(a, "@group");
01328 VALUE group_v2 = rb_iv_get(b, "@group");
01329 const EC_GROUP *group;
01330
01331 if (ossl_ec_group_eql(group_v1, group_v2) == Qfalse)
01332 return Qfalse;
01333
01334 Require_EC_POINT(a, point1);
01335 SafeRequire_EC_POINT(b, point2);
01336 SafeRequire_EC_GROUP(group_v1, group);
01337
01338 if (EC_POINT_cmp(group, point1, point2, ossl_bn_ctx) == 1)
01339 return Qfalse;
01340
01341 return Qtrue;
01342 }
01343
01344
01345
01346
01347
01348
01349 static VALUE ossl_ec_point_is_at_infinity(VALUE self)
01350 {
01351 EC_POINT *point;
01352 VALUE group_v = rb_iv_get(self, "@group");
01353 const EC_GROUP *group;
01354
01355 Require_EC_POINT(self, point);
01356 SafeRequire_EC_GROUP(group_v, group);
01357
01358 switch (EC_POINT_is_at_infinity(group, point)) {
01359 case 1: return Qtrue;
01360 case 0: return Qfalse;
01361 default: ossl_raise(cEC_POINT, "EC_POINT_is_at_infinity");
01362 }
01363
01364 UNREACHABLE;
01365 }
01366
01367
01368
01369
01370
01371
01372 static VALUE ossl_ec_point_is_on_curve(VALUE self)
01373 {
01374 EC_POINT *point;
01375 VALUE group_v = rb_iv_get(self, "@group");
01376 const EC_GROUP *group;
01377
01378 Require_EC_POINT(self, point);
01379 SafeRequire_EC_GROUP(group_v, group);
01380
01381 switch (EC_POINT_is_on_curve(group, point, ossl_bn_ctx)) {
01382 case 1: return Qtrue;
01383 case 0: return Qfalse;
01384 default: ossl_raise(cEC_POINT, "EC_POINT_is_on_curve");
01385 }
01386
01387 UNREACHABLE;
01388 }
01389
01390
01391
01392
01393
01394
01395 static VALUE ossl_ec_point_make_affine(VALUE self)
01396 {
01397 EC_POINT *point;
01398 VALUE group_v = rb_iv_get(self, "@group");
01399 const EC_GROUP *group;
01400
01401 Require_EC_POINT(self, point);
01402 SafeRequire_EC_GROUP(group_v, group);
01403
01404 if (EC_POINT_make_affine(group, point, ossl_bn_ctx) != 1)
01405 ossl_raise(cEC_POINT, "EC_POINT_make_affine");
01406
01407 return self;
01408 }
01409
01410
01411
01412
01413
01414
01415 static VALUE ossl_ec_point_invert(VALUE self)
01416 {
01417 EC_POINT *point;
01418 VALUE group_v = rb_iv_get(self, "@group");
01419 const EC_GROUP *group;
01420
01421 Require_EC_POINT(self, point);
01422 SafeRequire_EC_GROUP(group_v, group);
01423
01424 if (EC_POINT_invert(group, point, ossl_bn_ctx) != 1)
01425 ossl_raise(cEC_POINT, "EC_POINT_invert");
01426
01427 return self;
01428 }
01429
01430
01431
01432
01433
01434
01435 static VALUE ossl_ec_point_set_to_infinity(VALUE self)
01436 {
01437 EC_POINT *point;
01438 VALUE group_v = rb_iv_get(self, "@group");
01439 const EC_GROUP *group;
01440
01441 Require_EC_POINT(self, point);
01442 SafeRequire_EC_GROUP(group_v, group);
01443
01444 if (EC_POINT_set_to_infinity(group, point) != 1)
01445 ossl_raise(cEC_POINT, "EC_POINT_set_to_infinity");
01446
01447 return self;
01448 }
01449
01450
01451
01452
01453
01454
01455
01456 static VALUE ossl_ec_point_to_bn(VALUE self)
01457 {
01458 EC_POINT *point;
01459 VALUE bn_obj;
01460 VALUE group_v = rb_iv_get(self, "@group");
01461 const EC_GROUP *group;
01462 point_conversion_form_t form;
01463 BIGNUM *bn;
01464
01465 Require_EC_POINT(self, point);
01466 SafeRequire_EC_GROUP(group_v, group);
01467
01468 form = EC_GROUP_get_point_conversion_form(group);
01469
01470 bn_obj = rb_obj_alloc(cBN);
01471 bn = GetBNPtr(bn_obj);
01472
01473 if (EC_POINT_point2bn(group, point, form, bn, ossl_bn_ctx) == NULL)
01474 ossl_raise(eEC_POINT, "EC_POINT_point2bn");
01475
01476 return bn_obj;
01477 }
01478
01479
01480
01481
01482
01483
01484
01485
01486 static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self)
01487 {
01488 EC_POINT *point1, *point2;
01489 const EC_GROUP *group;
01490 VALUE group_v = rb_iv_get(self, "@group");
01491 VALUE bn_v1, bn_v2, r, points_v;
01492 BIGNUM *bn1 = NULL, *bn2 = NULL;
01493
01494 Require_EC_POINT(self, point1);
01495 SafeRequire_EC_GROUP(group_v, group);
01496
01497 r = rb_obj_alloc(cEC_POINT);
01498 ossl_ec_point_initialize(1, &group_v, r);
01499 Require_EC_POINT(r, point2);
01500
01501 argc = rb_scan_args(argc, argv, "12", &bn_v1, &points_v, &bn_v2);
01502
01503 if (rb_obj_is_kind_of(bn_v1, cBN)) {
01504 bn1 = GetBNPtr(bn_v1);
01505 if (argc >= 2) {
01506 bn2 = GetBNPtr(points_v);
01507 }
01508 if (EC_POINT_mul(group, point2, bn2, point1, bn1, ossl_bn_ctx) != 1)
01509 ossl_raise(eEC_POINT, "Multiplication failed");
01510 } else {
01511 size_t i, points_len, bignums_len;
01512 const EC_POINT **points;
01513 const BIGNUM **bignums;
01514
01515 Check_Type(bn_v1, T_ARRAY);
01516 bignums_len = RARRAY_LEN(bn_v1);
01517 bignums = (const BIGNUM **)OPENSSL_malloc(bignums_len * (int)sizeof(BIGNUM *));
01518
01519 for (i = 0; i < bignums_len; ++i) {
01520 bignums[i] = GetBNPtr(rb_ary_entry(bn_v1, i));
01521 }
01522
01523 if (!rb_obj_is_kind_of(points_v, rb_cArray)) {
01524 OPENSSL_free((void *)bignums);
01525 rb_raise(rb_eTypeError, "Argument2 must be an array");
01526 }
01527
01528 rb_ary_unshift(points_v, self);
01529 points_len = RARRAY_LEN(points_v);
01530 points = (const EC_POINT **)OPENSSL_malloc(points_len * (int)sizeof(EC_POINT *));
01531
01532 for (i = 0; i < points_len; ++i) {
01533 Get_EC_POINT(rb_ary_entry(points_v, i), points[i]);
01534 }
01535
01536 if (argc >= 3) {
01537 bn2 = GetBNPtr(bn_v2);
01538 }
01539 if (EC_POINTs_mul(group, point2, bn2, points_len, points, bignums, ossl_bn_ctx) != 1) {
01540 OPENSSL_free((void *)bignums);
01541 OPENSSL_free((void *)points);
01542 ossl_raise(eEC_POINT, "Multiplication failed");
01543 }
01544 OPENSSL_free((void *)bignums);
01545 OPENSSL_free((void *)points);
01546 }
01547
01548 return r;
01549 }
01550
01551 static void no_copy(VALUE klass)
01552 {
01553 rb_undef_method(klass, "copy");
01554 rb_undef_method(klass, "clone");
01555 rb_undef_method(klass, "dup");
01556 rb_undef_method(klass, "initialize_copy");
01557 }
01558
01559 void Init_ossl_ec()
01560 {
01561 #ifdef DONT_NEED_RDOC_WORKAROUND
01562 mOSSL = rb_define_module("OpenSSL");
01563 mPKey = rb_define_module_under(mOSSL, "PKey");
01564 #endif
01565
01566 eECError = rb_define_class_under(mPKey, "ECError", ePKeyError);
01567
01568 cEC = rb_define_class_under(mPKey, "EC", cPKey);
01569 cEC_GROUP = rb_define_class_under(cEC, "Group", rb_cObject);
01570 cEC_POINT = rb_define_class_under(cEC, "Point", rb_cObject);
01571 eEC_GROUP = rb_define_class_under(cEC_GROUP, "Error", eOSSLError);
01572 eEC_POINT = rb_define_class_under(cEC_POINT, "Error", eOSSLError);
01573
01574 s_GFp = rb_intern("GFp");
01575 s_GF2m = rb_intern("GF2m");
01576 s_GFp_simple = rb_intern("GFp_simple");
01577 s_GFp_mont = rb_intern("GFp_mont");
01578 s_GFp_nist = rb_intern("GFp_nist");
01579 s_GF2m_simple = rb_intern("GF2m_simple");
01580
01581 ID_uncompressed = rb_intern("uncompressed");
01582 ID_compressed = rb_intern("compressed");
01583 ID_hybrid = rb_intern("hybrid");
01584
01585 #ifdef OPENSSL_EC_NAMED_CURVE
01586 rb_define_const(cEC, "NAMED_CURVE", ULONG2NUM(OPENSSL_EC_NAMED_CURVE));
01587 #endif
01588
01589 rb_define_singleton_method(cEC, "builtin_curves", ossl_s_builtin_curves, 0);
01590
01591 rb_define_method(cEC, "initialize", ossl_ec_key_initialize, -1);
01592
01593
01594 rb_define_method(cEC, "group", ossl_ec_key_get_group, 0);
01595 rb_define_method(cEC, "group=", ossl_ec_key_set_group, 1);
01596 rb_define_method(cEC, "private_key", ossl_ec_key_get_private_key, 0);
01597 rb_define_method(cEC, "private_key=", ossl_ec_key_set_private_key, 1);
01598 rb_define_method(cEC, "public_key", ossl_ec_key_get_public_key, 0);
01599 rb_define_method(cEC, "public_key=", ossl_ec_key_set_public_key, 1);
01600 rb_define_method(cEC, "private_key?", ossl_ec_key_is_private_key, 0);
01601 rb_define_method(cEC, "public_key?", ossl_ec_key_is_public_key, 0);
01602
01603
01604
01605
01606
01607
01608
01609 rb_define_method(cEC, "generate_key", ossl_ec_key_generate_key, 0);
01610 rb_define_method(cEC, "check_key", ossl_ec_key_check_key, 0);
01611
01612 rb_define_method(cEC, "dh_compute_key", ossl_ec_key_dh_compute_key, 1);
01613 rb_define_method(cEC, "dsa_sign_asn1", ossl_ec_key_dsa_sign_asn1, 1);
01614 rb_define_method(cEC, "dsa_verify_asn1", ossl_ec_key_dsa_verify_asn1, 2);
01615
01616
01617 rb_define_method(cEC, "export", ossl_ec_key_export, -1);
01618 rb_define_alias(cEC, "to_pem", "export");
01619 rb_define_method(cEC, "to_der", ossl_ec_key_to_der, 0);
01620 rb_define_method(cEC, "to_text", ossl_ec_key_to_text, 0);
01621
01622
01623 rb_define_alloc_func(cEC_GROUP, ossl_ec_group_alloc);
01624 rb_define_method(cEC_GROUP, "initialize", ossl_ec_group_initialize, -1);
01625 rb_define_method(cEC_GROUP, "eql?", ossl_ec_group_eql, 1);
01626 rb_define_alias(cEC_GROUP, "==", "eql?");
01627
01628
01629 rb_define_method(cEC_GROUP, "generator", ossl_ec_group_get_generator, 0);
01630 rb_define_method(cEC_GROUP, "set_generator", ossl_ec_group_set_generator, 3);
01631 rb_define_method(cEC_GROUP, "order", ossl_ec_group_get_order, 0);
01632 rb_define_method(cEC_GROUP, "cofactor", ossl_ec_group_get_cofactor, 0);
01633
01634 rb_define_method(cEC_GROUP, "curve_name", ossl_ec_group_get_curve_name, 0);
01635
01636
01637 rb_define_method(cEC_GROUP, "asn1_flag", ossl_ec_group_get_asn1_flag, 0);
01638 rb_define_method(cEC_GROUP, "asn1_flag=", ossl_ec_group_set_asn1_flag, 1);
01639
01640 rb_define_method(cEC_GROUP, "point_conversion_form", ossl_ec_group_get_point_conversion_form, 0);
01641 rb_define_method(cEC_GROUP, "point_conversion_form=", ossl_ec_group_set_point_conversion_form, 1);
01642
01643 rb_define_method(cEC_GROUP, "seed", ossl_ec_group_get_seed, 0);
01644 rb_define_method(cEC_GROUP, "seed=", ossl_ec_group_set_seed, 1);
01645
01646
01647
01648 rb_define_method(cEC_GROUP, "degree", ossl_ec_group_get_degree, 0);
01649
01650
01651
01652
01653 rb_define_method(cEC_GROUP, "to_pem", ossl_ec_group_to_pem, 0);
01654 rb_define_method(cEC_GROUP, "to_der", ossl_ec_group_to_der, 0);
01655 rb_define_method(cEC_GROUP, "to_text", ossl_ec_group_to_text, 0);
01656
01657
01658 rb_define_alloc_func(cEC_POINT, ossl_ec_point_alloc);
01659 rb_define_method(cEC_POINT, "initialize", ossl_ec_point_initialize, -1);
01660 rb_attr(cEC_POINT, rb_intern("group"), 1, 0, 0);
01661 rb_define_method(cEC_POINT, "eql?", ossl_ec_point_eql, 1);
01662 rb_define_alias(cEC_POINT, "==", "eql?");
01663
01664 rb_define_method(cEC_POINT, "infinity?", ossl_ec_point_is_at_infinity, 0);
01665 rb_define_method(cEC_POINT, "on_curve?", ossl_ec_point_is_on_curve, 0);
01666 rb_define_method(cEC_POINT, "make_affine!", ossl_ec_point_make_affine, 0);
01667 rb_define_method(cEC_POINT, "invert!", ossl_ec_point_invert, 0);
01668 rb_define_method(cEC_POINT, "set_to_infinity!", ossl_ec_point_set_to_infinity, 0);
01669
01670
01671 rb_define_method(cEC_POINT, "to_bn", ossl_ec_point_to_bn, 0);
01672 rb_define_method(cEC_POINT, "mul", ossl_ec_point_mul, -1);
01673
01674 no_copy(cEC);
01675 no_copy(cEC_GROUP);
01676 no_copy(cEC_POINT);
01677 }
01678
01679 #else
01680 void Init_ossl_ec()
01681 {
01682 }
01683 #endif
01684