rubysl-openssl 2.10 → 2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/ext/rubysl/openssl/deprecation.rb +7 -3
- data/ext/rubysl/openssl/extconf.rb +148 -103
- data/ext/rubysl/openssl/openssl_missing.c +94 -275
- data/ext/rubysl/openssl/openssl_missing.h +167 -98
- data/ext/rubysl/openssl/ossl.c +266 -212
- data/ext/rubysl/openssl/ossl.h +27 -89
- data/ext/rubysl/openssl/ossl_asn1.c +157 -221
- data/ext/rubysl/openssl/ossl_asn1.h +11 -3
- data/ext/rubysl/openssl/ossl_bio.c +10 -40
- data/ext/rubysl/openssl/ossl_bio.h +1 -2
- data/ext/rubysl/openssl/ossl_bn.c +144 -100
- data/ext/rubysl/openssl/ossl_bn.h +3 -1
- data/ext/rubysl/openssl/ossl_cipher.c +270 -195
- data/ext/rubysl/openssl/ossl_config.c +7 -1
- data/ext/rubysl/openssl/ossl_config.h +0 -1
- data/ext/rubysl/openssl/ossl_digest.c +40 -29
- data/ext/rubysl/openssl/ossl_engine.c +23 -62
- data/ext/rubysl/openssl/ossl_hmac.c +82 -55
- data/ext/rubysl/openssl/ossl_ns_spki.c +22 -22
- data/ext/rubysl/openssl/ossl_ocsp.c +894 -144
- data/ext/rubysl/openssl/ossl_ocsp.h +1 -1
- data/ext/rubysl/openssl/ossl_pkcs12.c +47 -19
- data/ext/rubysl/openssl/ossl_pkcs5.c +7 -15
- data/ext/rubysl/openssl/ossl_pkcs7.c +38 -15
- data/ext/rubysl/openssl/ossl_pkey.c +151 -99
- data/ext/rubysl/openssl/ossl_pkey.h +123 -29
- data/ext/rubysl/openssl/ossl_pkey_dh.c +143 -92
- data/ext/rubysl/openssl/ossl_pkey_dsa.c +149 -104
- data/ext/rubysl/openssl/ossl_pkey_ec.c +646 -524
- data/ext/rubysl/openssl/ossl_pkey_rsa.c +180 -121
- data/ext/rubysl/openssl/ossl_rand.c +25 -21
- data/ext/rubysl/openssl/ossl_ssl.c +795 -413
- data/ext/rubysl/openssl/ossl_ssl.h +3 -0
- data/ext/rubysl/openssl/ossl_ssl_session.c +83 -77
- data/ext/rubysl/openssl/ossl_version.h +1 -1
- data/ext/rubysl/openssl/ossl_x509.c +92 -8
- data/ext/rubysl/openssl/ossl_x509.h +14 -5
- data/ext/rubysl/openssl/ossl_x509attr.c +77 -41
- data/ext/rubysl/openssl/ossl_x509cert.c +45 -46
- data/ext/rubysl/openssl/ossl_x509crl.c +51 -57
- data/ext/rubysl/openssl/ossl_x509ext.c +39 -33
- data/ext/rubysl/openssl/ossl_x509name.c +68 -45
- data/ext/rubysl/openssl/ossl_x509req.c +32 -38
- data/ext/rubysl/openssl/ossl_x509revoked.c +43 -9
- data/ext/rubysl/openssl/ossl_x509store.c +309 -104
- data/ext/rubysl/openssl/ruby_missing.h +8 -6
- data/lib/openssl/buffering.rb +11 -5
- data/lib/openssl/cipher.rb +23 -15
- data/lib/openssl/digest.rb +7 -10
- data/lib/openssl/pkey.rb +15 -8
- data/lib/openssl/ssl.rb +81 -105
- data/lib/rubysl/openssl.rb +1 -4
- data/lib/rubysl/openssl/version.rb +1 -1
- metadata +3 -4
| @@ -6,17 +6,6 @@ | |
| 6 6 |  | 
| 7 7 | 
             
            #if !defined(OPENSSL_NO_EC) && (OPENSSL_VERSION_NUMBER >= 0x0090802fL)
         | 
| 8 8 |  | 
| 9 | 
            -
            typedef struct {
         | 
| 10 | 
            -
            	EC_GROUP *group;
         | 
| 11 | 
            -
            	int dont_free;
         | 
| 12 | 
            -
            } ossl_ec_group;
         | 
| 13 | 
            -
             | 
| 14 | 
            -
            typedef struct {
         | 
| 15 | 
            -
            	EC_POINT *point;
         | 
| 16 | 
            -
            	int dont_free;
         | 
| 17 | 
            -
            } ossl_ec_point;
         | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 20 9 | 
             
            #define EXPORT_PEM 0
         | 
| 21 10 | 
             
            #define EXPORT_DER 1
         | 
| 22 11 |  | 
| @@ -25,70 +14,43 @@ static const rb_data_type_t ossl_ec_point_type; | |
| 25 14 |  | 
| 26 15 | 
             
            #define GetPKeyEC(obj, pkey) do { \
         | 
| 27 16 | 
             
                GetPKey((obj), (pkey)); \
         | 
| 28 | 
            -
                if ( | 
| 17 | 
            +
                if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) { \
         | 
| 29 18 | 
             
            	ossl_raise(rb_eRuntimeError, "THIS IS NOT A EC PKEY!"); \
         | 
| 30 19 | 
             
                } \
         | 
| 31 20 | 
             
            } while (0)
         | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
                 | 
| 35 | 
            -
                 | 
| 36 | 
            -
            } while(0)
         | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
                 | 
| 40 | 
            -
                GetPKeyEC((obj), pkey); \
         | 
| 41 | 
            -
                (key) = pkey->pkey.ec; \
         | 
| 42 | 
            -
            } while(0)
         | 
| 43 | 
            -
             | 
| 44 | 
            -
            #define Require_EC_KEY(obj, key) do { \
         | 
| 45 | 
            -
                Get_EC_KEY((obj), (key)); \
         | 
| 46 | 
            -
                if ((key) == NULL) \
         | 
| 47 | 
            -
                    ossl_raise(eECError, "EC_KEY is not initialized"); \
         | 
| 48 | 
            -
            } while(0)
         | 
| 49 | 
            -
             | 
| 50 | 
            -
            #define SafeRequire_EC_KEY(obj, key) do { \
         | 
| 51 | 
            -
                OSSL_Check_Kind((obj), cEC); \
         | 
| 52 | 
            -
                Require_EC_KEY((obj), (key)); \
         | 
| 21 | 
            +
            #define GetEC(obj, key) do { \
         | 
| 22 | 
            +
                EVP_PKEY *_pkey; \
         | 
| 23 | 
            +
                GetPKeyEC(obj, _pkey); \
         | 
| 24 | 
            +
                (key) = EVP_PKEY_get0_EC_KEY(_pkey); \
         | 
| 25 | 
            +
            } while (0)
         | 
| 26 | 
            +
            #define SafeGetEC(obj, key) do { \
         | 
| 27 | 
            +
                OSSL_Check_Kind(obj, cEC); \
         | 
| 28 | 
            +
                GetEC(obj, key); \
         | 
| 53 29 | 
             
            } while (0)
         | 
| 54 30 |  | 
| 55 | 
            -
            #define  | 
| 56 | 
            -
                 | 
| 57 | 
            -
                TypedData_Get_Struct((obj), ossl_ec_group, &ossl_ec_group_type, ec_group); \
         | 
| 58 | 
            -
                if (ec_group == NULL) \
         | 
| 59 | 
            -
                    ossl_raise(eEC_GROUP, "missing ossl_ec_group structure"); \
         | 
| 60 | 
            -
                (g) = ec_group->group; \
         | 
| 61 | 
            -
            } while(0)
         | 
| 62 | 
            -
             | 
| 63 | 
            -
            #define Require_EC_GROUP(obj, group) do { \
         | 
| 64 | 
            -
                Get_EC_GROUP((obj), (group)); \
         | 
| 31 | 
            +
            #define GetECGroup(obj, group) do { \
         | 
| 32 | 
            +
                TypedData_Get_Struct(obj, EC_GROUP, &ossl_ec_group_type, group); \
         | 
| 65 33 | 
             
                if ((group) == NULL) \
         | 
| 66 | 
            -
             | 
| 67 | 
            -
            } while(0)
         | 
| 68 | 
            -
             | 
| 69 | 
            -
            #define SafeRequire_EC_GROUP(obj, group) do { \
         | 
| 34 | 
            +
            	ossl_raise(eEC_GROUP, "EC_GROUP is not initialized"); \
         | 
| 35 | 
            +
            } while (0)
         | 
| 36 | 
            +
            #define SafeGetECGroup(obj, group) do { \
         | 
| 70 37 | 
             
                OSSL_Check_Kind((obj), cEC_GROUP); \
         | 
| 71 | 
            -
                 | 
| 72 | 
            -
            } while(0)
         | 
| 73 | 
            -
             | 
| 74 | 
            -
            #define Get_EC_POINT(obj, p) do { \
         | 
| 75 | 
            -
                ossl_ec_point *ec_point; \
         | 
| 76 | 
            -
                TypedData_Get_Struct((obj), ossl_ec_point, &ossl_ec_point_type, ec_point); \
         | 
| 77 | 
            -
                if (ec_point == NULL) \
         | 
| 78 | 
            -
                    ossl_raise(eEC_POINT, "missing ossl_ec_point structure"); \
         | 
| 79 | 
            -
                (p) = ec_point->point; \
         | 
| 80 | 
            -
            } while(0)
         | 
| 38 | 
            +
                GetECGroup(obj, group); \
         | 
| 39 | 
            +
            } while (0)
         | 
| 81 40 |  | 
| 82 | 
            -
            #define  | 
| 83 | 
            -
                 | 
| 41 | 
            +
            #define GetECPoint(obj, point) do { \
         | 
| 42 | 
            +
                TypedData_Get_Struct(obj, EC_POINT, &ossl_ec_point_type, point); \
         | 
| 84 43 | 
             
                if ((point) == NULL) \
         | 
| 85 | 
            -
             | 
| 86 | 
            -
            } while(0)
         | 
| 87 | 
            -
             | 
| 88 | 
            -
            #define SafeRequire_EC_POINT(obj, point) do { \
         | 
| 44 | 
            +
            	ossl_raise(eEC_POINT, "EC_POINT is not initialized"); \
         | 
| 45 | 
            +
            } while (0)
         | 
| 46 | 
            +
            #define SafeGetECPoint(obj, point) do { \
         | 
| 89 47 | 
             
                OSSL_Check_Kind((obj), cEC_POINT); \
         | 
| 90 | 
            -
                 | 
| 48 | 
            +
                GetECPoint(obj, point); \
         | 
| 91 49 | 
             
            } while(0)
         | 
| 50 | 
            +
            #define GetECPointGroup(obj, group) do { \
         | 
| 51 | 
            +
                VALUE _group = rb_attr_get(obj, id_i_group); \
         | 
| 52 | 
            +
                SafeGetECGroup(_group, group); \
         | 
| 53 | 
            +
            } while (0)
         | 
| 92 54 |  | 
| 93 55 | 
             
            VALUE cEC;
         | 
| 94 56 | 
             
            VALUE eECError;
         | 
| @@ -108,6 +70,11 @@ static ID ID_uncompressed; | |
| 108 70 | 
             
            static ID ID_compressed;
         | 
| 109 71 | 
             
            static ID ID_hybrid;
         | 
| 110 72 |  | 
| 73 | 
            +
            static ID id_i_group;
         | 
| 74 | 
            +
             | 
| 75 | 
            +
            static VALUE ec_group_new(const EC_GROUP *group);
         | 
| 76 | 
            +
            static VALUE ec_point_new(const EC_POINT *point, const EC_GROUP *group);
         | 
| 77 | 
            +
             | 
| 111 78 | 
             
            static VALUE ec_instance(VALUE klass, EC_KEY *ec)
         | 
| 112 79 | 
             
            {
         | 
| 113 80 | 
             
                EVP_PKEY *pkey;
         | 
| @@ -137,7 +104,7 @@ VALUE ossl_ec_new(EVP_PKEY *pkey) | |
| 137 104 | 
             
            	obj = ec_instance(cEC, EC_KEY_new());
         | 
| 138 105 | 
             
                } else {
         | 
| 139 106 | 
             
            	obj = NewPKey(cEC);
         | 
| 140 | 
            -
            	if ( | 
| 107 | 
            +
            	if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) {
         | 
| 141 108 | 
             
            	    ossl_raise(rb_eTypeError, "Not a EC key!");
         | 
| 142 109 | 
             
            	}
         | 
| 143 110 | 
             
            	SetPKey(obj, pkey);
         | 
| @@ -149,168 +116,196 @@ VALUE ossl_ec_new(EVP_PKEY *pkey) | |
| 149 116 | 
             
                return obj;
         | 
| 150 117 | 
             
            }
         | 
| 151 118 |  | 
| 119 | 
            +
            /*
         | 
| 120 | 
            +
             * Creates a new EC_KEY on the EC group obj. arg can be an EC::Group or a String
         | 
| 121 | 
            +
             * representing an OID.
         | 
| 122 | 
            +
             */
         | 
| 123 | 
            +
            static EC_KEY *
         | 
| 124 | 
            +
            ec_key_new_from_group(VALUE arg)
         | 
| 125 | 
            +
            {
         | 
| 126 | 
            +
                EC_KEY *ec;
         | 
| 127 | 
            +
             | 
| 128 | 
            +
                if (rb_obj_is_kind_of(arg, cEC_GROUP)) {
         | 
| 129 | 
            +
            	EC_GROUP *group;
         | 
| 130 | 
            +
             | 
| 131 | 
            +
            	SafeGetECGroup(arg, group);
         | 
| 132 | 
            +
            	if (!(ec = EC_KEY_new()))
         | 
| 133 | 
            +
            	    ossl_raise(eECError, NULL);
         | 
| 134 | 
            +
             | 
| 135 | 
            +
            	if (!EC_KEY_set_group(ec, group)) {
         | 
| 136 | 
            +
            	    EC_KEY_free(ec);
         | 
| 137 | 
            +
            	    ossl_raise(eECError, NULL);
         | 
| 138 | 
            +
            	}
         | 
| 139 | 
            +
                } else {
         | 
| 140 | 
            +
            	int nid = OBJ_sn2nid(StringValueCStr(arg));
         | 
| 141 | 
            +
             | 
| 142 | 
            +
            	if (nid == NID_undef)
         | 
| 143 | 
            +
            	    ossl_raise(eECError, "invalid curve name");
         | 
| 152 144 |  | 
| 153 | 
            -
             | 
| 154 | 
            -
              | 
| 155 | 
            -
             | 
| 156 | 
            -
              | 
| 157 | 
            -
              | 
| 158 | 
            -
             | 
| 159 | 
            -
             | 
| 160 | 
            -
              | 
| 145 | 
            +
            	if (!(ec = EC_KEY_new_by_curve_name(nid)))
         | 
| 146 | 
            +
            	    ossl_raise(eECError, NULL);
         | 
| 147 | 
            +
             | 
| 148 | 
            +
            	EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
         | 
| 149 | 
            +
            	EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED);
         | 
| 150 | 
            +
                }
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                return ec;
         | 
| 153 | 
            +
            }
         | 
| 154 | 
            +
             | 
| 155 | 
            +
            /*
         | 
| 156 | 
            +
             *  call-seq:
         | 
| 157 | 
            +
             *     EC.generate(ec_group) -> ec
         | 
| 158 | 
            +
             *     EC.generate(string) -> ec
         | 
| 161 159 | 
             
             *
         | 
| 162 | 
            -
             * | 
| 163 | 
            -
              | 
| 160 | 
            +
             * Creates a new EC instance with a new random private and public key.
         | 
| 161 | 
            +
             */
         | 
| 162 | 
            +
            static VALUE
         | 
| 163 | 
            +
            ossl_ec_key_s_generate(VALUE klass, VALUE arg)
         | 
| 164 | 
            +
            {
         | 
| 165 | 
            +
                EC_KEY *ec;
         | 
| 166 | 
            +
                VALUE obj;
         | 
| 167 | 
            +
             | 
| 168 | 
            +
                ec = ec_key_new_from_group(arg);
         | 
| 169 | 
            +
             | 
| 170 | 
            +
                obj = ec_instance(klass, ec);
         | 
| 171 | 
            +
                if (obj == Qfalse) {
         | 
| 172 | 
            +
            	EC_KEY_free(ec);
         | 
| 173 | 
            +
            	ossl_raise(eECError, NULL);
         | 
| 174 | 
            +
                }
         | 
| 175 | 
            +
             | 
| 176 | 
            +
                if (!EC_KEY_generate_key(ec))
         | 
| 177 | 
            +
            	ossl_raise(eECError, "EC_KEY_generate_key");
         | 
| 178 | 
            +
             | 
| 179 | 
            +
                return obj;
         | 
| 180 | 
            +
            }
         | 
| 181 | 
            +
             | 
| 182 | 
            +
            /*
         | 
| 183 | 
            +
             * call-seq:
         | 
| 184 | 
            +
             *   OpenSSL::PKey::EC.new
         | 
| 185 | 
            +
             *   OpenSSL::PKey::EC.new(ec_key)
         | 
| 186 | 
            +
             *   OpenSSL::PKey::EC.new(ec_group)
         | 
| 187 | 
            +
             *   OpenSSL::PKey::EC.new("secp112r1")
         | 
| 188 | 
            +
             *   OpenSSL::PKey::EC.new(pem_string [, pwd])
         | 
| 189 | 
            +
             *   OpenSSL::PKey::EC.new(der_string)
         | 
| 190 | 
            +
             *
         | 
| 191 | 
            +
             * Creates a new EC object from given arguments.
         | 
| 164 192 | 
             
             */
         | 
| 165 193 | 
             
            static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
         | 
| 166 194 | 
             
            {
         | 
| 167 195 | 
             
                EVP_PKEY *pkey;
         | 
| 168 | 
            -
                EC_KEY *ec | 
| 196 | 
            +
                EC_KEY *ec;
         | 
| 169 197 | 
             
                VALUE arg, pass;
         | 
| 170 | 
            -
                VALUE group = Qnil;
         | 
| 171 | 
            -
                char *passwd = NULL;
         | 
| 172 198 |  | 
| 173 199 | 
             
                GetPKey(self, pkey);
         | 
| 174 | 
            -
                if (pkey | 
| 200 | 
            +
                if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
         | 
| 175 201 | 
             
                    ossl_raise(eECError, "EC_KEY already initialized");
         | 
| 176 202 |  | 
| 177 203 | 
             
                rb_scan_args(argc, argv, "02", &arg, &pass);
         | 
| 178 204 |  | 
| 179 205 | 
             
                if (NIL_P(arg)) {
         | 
| 180 | 
            -
                    ec = EC_KEY_new() | 
| 206 | 
            +
                    if (!(ec = EC_KEY_new()))
         | 
| 207 | 
            +
            	    ossl_raise(eECError, NULL);
         | 
| 208 | 
            +
                } else if (rb_obj_is_kind_of(arg, cEC)) {
         | 
| 209 | 
            +
            	EC_KEY *other_ec = NULL;
         | 
| 210 | 
            +
             | 
| 211 | 
            +
            	SafeGetEC(arg, other_ec);
         | 
| 212 | 
            +
            	if (!(ec = EC_KEY_dup(other_ec)))
         | 
| 213 | 
            +
            	    ossl_raise(eECError, NULL);
         | 
| 214 | 
            +
                } else if (rb_obj_is_kind_of(arg, cEC_GROUP)) {
         | 
| 215 | 
            +
            	ec = ec_key_new_from_group(arg);
         | 
| 181 216 | 
             
                } else {
         | 
| 182 | 
            -
             | 
| 183 | 
            -
                        EC_KEY *other_ec = NULL;
         | 
| 184 | 
            -
             | 
| 185 | 
            -
                        SafeRequire_EC_KEY(arg, other_ec);
         | 
| 186 | 
            -
                        ec = EC_KEY_dup(other_ec);
         | 
| 187 | 
            -
                    } else if (rb_obj_is_kind_of(arg, cEC_GROUP)) {
         | 
| 188 | 
            -
                    	ec = EC_KEY_new();
         | 
| 189 | 
            -
                    	group = arg;
         | 
| 190 | 
            -
                    } else {
         | 
| 191 | 
            -
                        BIO *in = ossl_obj2bio(arg);
         | 
| 192 | 
            -
             | 
| 193 | 
            -
                        if (!NIL_P(pass)) {
         | 
| 194 | 
            -
            		passwd = StringValuePtr(pass);
         | 
| 195 | 
            -
            	    }
         | 
| 196 | 
            -
            	    ec = PEM_read_bio_ECPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
         | 
| 197 | 
            -
                        if (!ec) {
         | 
| 198 | 
            -
            		OSSL_BIO_reset(in);
         | 
| 199 | 
            -
            		ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, passwd);
         | 
| 200 | 
            -
                        }
         | 
| 201 | 
            -
                        if (!ec) {
         | 
| 202 | 
            -
            		OSSL_BIO_reset(in);
         | 
| 203 | 
            -
                            ec = d2i_ECPrivateKey_bio(in, NULL);
         | 
| 204 | 
            -
                        }
         | 
| 205 | 
            -
                        if (!ec) {
         | 
| 206 | 
            -
            		OSSL_BIO_reset(in);
         | 
| 207 | 
            -
                            ec = d2i_EC_PUBKEY_bio(in, NULL);
         | 
| 208 | 
            -
                        }
         | 
| 209 | 
            -
             | 
| 210 | 
            -
                        BIO_free(in);
         | 
| 211 | 
            -
             | 
| 212 | 
            -
                        if (ec == NULL) {
         | 
| 213 | 
            -
                            const char *name = StringValueCStr(arg);
         | 
| 214 | 
            -
                            int nid = OBJ_sn2nid(name);
         | 
| 217 | 
            +
            	BIO *in;
         | 
| 215 218 |  | 
| 216 | 
            -
             | 
| 217 | 
            -
             | 
| 218 | 
            -
                                ossl_raise(eECError, "unknown curve name (%s)\n", name);
         | 
| 219 | 
            +
            	pass = ossl_pem_passwd_value(pass);
         | 
| 220 | 
            +
            	in = ossl_obj2bio(&arg);
         | 
| 219 221 |  | 
| 220 | 
            -
             | 
| 221 | 
            -
             | 
| 222 | 
            +
            	ec = PEM_read_bio_ECPrivateKey(in, NULL, ossl_pem_passwd_cb, (void *)pass);
         | 
| 223 | 
            +
            	if (!ec) {
         | 
| 224 | 
            +
            	    OSSL_BIO_reset(in);
         | 
| 225 | 
            +
            	    ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, (void *)pass);
         | 
| 226 | 
            +
            	}
         | 
| 227 | 
            +
            	if (!ec) {
         | 
| 228 | 
            +
            	    OSSL_BIO_reset(in);
         | 
| 229 | 
            +
            	    ec = d2i_ECPrivateKey_bio(in, NULL);
         | 
| 230 | 
            +
            	}
         | 
| 231 | 
            +
            	if (!ec) {
         | 
| 232 | 
            +
            	    OSSL_BIO_reset(in);
         | 
| 233 | 
            +
            	    ec = d2i_EC_PUBKEY_bio(in, NULL);
         | 
| 234 | 
            +
            	}
         | 
| 235 | 
            +
            	BIO_free(in);
         | 
| 222 236 |  | 
| 223 | 
            -
             | 
| 224 | 
            -
             | 
| 225 | 
            -
             | 
| 226 | 
            -
             | 
| 237 | 
            +
            	if (!ec) {
         | 
| 238 | 
            +
            	    ossl_clear_error();
         | 
| 239 | 
            +
            	    ec = ec_key_new_from_group(arg);
         | 
| 240 | 
            +
            	}
         | 
| 227 241 | 
             
                }
         | 
| 228 242 |  | 
| 229 | 
            -
                if (ec == NULL)
         | 
| 230 | 
            -
                    ossl_raise(eECError, NULL);
         | 
| 231 | 
            -
             | 
| 232 243 | 
             
                if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) {
         | 
| 233 244 | 
             
            	EC_KEY_free(ec);
         | 
| 234 245 | 
             
            	ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
         | 
| 235 246 | 
             
                }
         | 
| 236 247 |  | 
| 237 | 
            -
                 | 
| 248 | 
            +
                return self;
         | 
| 249 | 
            +
            }
         | 
| 238 250 |  | 
| 239 | 
            -
             | 
| 240 | 
            -
             | 
| 251 | 
            +
            static VALUE
         | 
| 252 | 
            +
            ossl_ec_key_initialize_copy(VALUE self, VALUE other)
         | 
| 253 | 
            +
            {
         | 
| 254 | 
            +
                EVP_PKEY *pkey;
         | 
| 255 | 
            +
                EC_KEY *ec, *ec_new;
         | 
| 256 | 
            +
             | 
| 257 | 
            +
                GetPKey(self, pkey);
         | 
| 258 | 
            +
                if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
         | 
| 259 | 
            +
            	ossl_raise(eECError, "EC already initialized");
         | 
| 260 | 
            +
                SafeGetEC(other, ec);
         | 
| 261 | 
            +
             | 
| 262 | 
            +
                ec_new = EC_KEY_dup(ec);
         | 
| 263 | 
            +
                if (!ec_new)
         | 
| 264 | 
            +
            	ossl_raise(eECError, "EC_KEY_dup");
         | 
| 265 | 
            +
                if (!EVP_PKEY_assign_EC_KEY(pkey, ec_new)) {
         | 
| 266 | 
            +
            	EC_KEY_free(ec_new);
         | 
| 267 | 
            +
            	ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
         | 
| 268 | 
            +
                }
         | 
| 241 269 |  | 
| 242 270 | 
             
                return self;
         | 
| 243 271 | 
             
            }
         | 
| 244 272 |  | 
| 245 273 | 
             
            /*
         | 
| 246 | 
            -
             * | 
| 247 | 
            -
             * | 
| 274 | 
            +
             * call-seq:
         | 
| 275 | 
            +
             *   key.group   => group
         | 
| 248 276 | 
             
             *
         | 
| 249 | 
            -
             * | 
| 250 | 
            -
             * | 
| 277 | 
            +
             * Returns the EC::Group that the key is associated with. Modifying the returned
         | 
| 278 | 
            +
             * group does not affect +key+.
         | 
| 251 279 | 
             
             */
         | 
| 252 | 
            -
            static VALUE | 
| 280 | 
            +
            static VALUE
         | 
| 281 | 
            +
            ossl_ec_key_get_group(VALUE self)
         | 
| 253 282 | 
             
            {
         | 
| 254 | 
            -
                VALUE group_v;
         | 
| 255 283 | 
             
                EC_KEY *ec;
         | 
| 256 | 
            -
                 | 
| 257 | 
            -
                EC_GROUP *group;
         | 
| 258 | 
            -
             | 
| 259 | 
            -
                Require_EC_KEY(self, ec);
         | 
| 260 | 
            -
             | 
| 261 | 
            -
                group_v = rb_iv_get(self, "@group");
         | 
| 262 | 
            -
                if (!NIL_P(group_v))
         | 
| 263 | 
            -
                    return group_v;
         | 
| 284 | 
            +
                const EC_GROUP *group;
         | 
| 264 285 |  | 
| 265 | 
            -
                 | 
| 266 | 
            -
             | 
| 267 | 
            -
             | 
| 268 | 
            -
             | 
| 269 | 
            -
                    ec_group->dont_free = 1;
         | 
| 270 | 
            -
                    rb_iv_set(group_v, "@key", self);
         | 
| 271 | 
            -
                    rb_iv_set(self, "@group", group_v);
         | 
| 272 | 
            -
                    return group_v;
         | 
| 273 | 
            -
                }
         | 
| 286 | 
            +
                GetEC(self, ec);
         | 
| 287 | 
            +
                group = EC_KEY_get0_group(ec);
         | 
| 288 | 
            +
                if (!group)
         | 
| 289 | 
            +
            	return Qnil;
         | 
| 274 290 |  | 
| 275 | 
            -
                return  | 
| 291 | 
            +
                return ec_group_new(group);
         | 
| 276 292 | 
             
            }
         | 
| 277 293 |  | 
| 278 294 | 
             
            /*
         | 
| 279 | 
            -
             * | 
| 280 | 
            -
             * | 
| 281 | 
            -
             *
         | 
| 282 | 
            -
             *  Returns the same object passed, not the group object associated with the key.
         | 
| 283 | 
            -
             *  If you wish to access the group object tied to the key call key.group after setting
         | 
| 284 | 
            -
             *  the group.
         | 
| 295 | 
            +
             * call-seq:
         | 
| 296 | 
            +
             *   key.group = group
         | 
| 285 297 | 
             
             *
         | 
| 286 | 
            -
             * | 
| 287 | 
            -
             * | 
| 288 | 
            -
             *  assignment will not effect the internal key structure.
         | 
| 289 | 
            -
             *  (your changes may be lost).  BE CAREFUL.
         | 
| 290 | 
            -
             *
         | 
| 291 | 
            -
             *  EC_KEY_set_group calls EC_GROUP_free(key->group) then EC_GROUP_dup(), not EC_GROUP_copy.
         | 
| 292 | 
            -
             *  This documentation is accurate for OpenSSL 0.9.8b.
         | 
| 298 | 
            +
             * Sets the EC::Group for the key. The group structure is internally copied so
         | 
| 299 | 
            +
             * modification to +group+ after assigning to a key has no effect on the key.
         | 
| 293 300 | 
             
             */
         | 
| 294 | 
            -
            static VALUE | 
| 301 | 
            +
            static VALUE
         | 
| 302 | 
            +
            ossl_ec_key_set_group(VALUE self, VALUE group_v)
         | 
| 295 303 | 
             
            {
         | 
| 296 | 
            -
                VALUE old_group_v;
         | 
| 297 304 | 
             
                EC_KEY *ec;
         | 
| 298 305 | 
             
                EC_GROUP *group;
         | 
| 299 306 |  | 
| 300 | 
            -
                 | 
| 301 | 
            -
                 | 
| 302 | 
            -
             | 
| 303 | 
            -
                old_group_v = rb_iv_get(self, "@group");
         | 
| 304 | 
            -
                if (!NIL_P(old_group_v)) {
         | 
| 305 | 
            -
                    ossl_ec_group *old_ec_group;
         | 
| 306 | 
            -
                    SafeGet_ec_group(old_group_v, old_ec_group);
         | 
| 307 | 
            -
             | 
| 308 | 
            -
                    old_ec_group->group = NULL;
         | 
| 309 | 
            -
                    old_ec_group->dont_free = 0;
         | 
| 310 | 
            -
                    rb_iv_set(old_group_v, "@key", Qnil);
         | 
| 311 | 
            -
                }
         | 
| 312 | 
            -
             | 
| 313 | 
            -
                rb_iv_set(self, "@group", Qnil);
         | 
| 307 | 
            +
                GetEC(self, ec);
         | 
| 308 | 
            +
                SafeGetECGroup(group_v, group);
         | 
| 314 309 |  | 
| 315 310 | 
             
                if (EC_KEY_set_group(ec, group) != 1)
         | 
| 316 311 | 
             
                    ossl_raise(eECError, "EC_KEY_set_group");
         | 
| @@ -329,8 +324,7 @@ static VALUE ossl_ec_key_get_private_key(VALUE self) | |
| 329 324 | 
             
                EC_KEY *ec;
         | 
| 330 325 | 
             
                const BIGNUM *bn;
         | 
| 331 326 |  | 
| 332 | 
            -
                 | 
| 333 | 
            -
             | 
| 327 | 
            +
                GetEC(self, ec);
         | 
| 334 328 | 
             
                if ((bn = EC_KEY_get0_private_key(ec)) == NULL)
         | 
| 335 329 | 
             
                    return Qnil;
         | 
| 336 330 |  | 
| @@ -348,7 +342,7 @@ static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key) | |
| 348 342 | 
             
                EC_KEY *ec;
         | 
| 349 343 | 
             
                BIGNUM *bn = NULL;
         | 
| 350 344 |  | 
| 351 | 
            -
                 | 
| 345 | 
            +
                GetEC(self, ec);
         | 
| 352 346 | 
             
                if (!NIL_P(private_key))
         | 
| 353 347 | 
             
                    bn = GetBNPtr(private_key);
         | 
| 354 348 |  | 
| @@ -365,26 +359,6 @@ static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key) | |
| 365 359 | 
             
                return private_key;
         | 
| 366 360 | 
             
            }
         | 
| 367 361 |  | 
| 368 | 
            -
             | 
| 369 | 
            -
            static VALUE ossl_ec_point_dup(const EC_POINT *point, VALUE group_v)
         | 
| 370 | 
            -
            {
         | 
| 371 | 
            -
                VALUE obj;
         | 
| 372 | 
            -
                const EC_GROUP *group;
         | 
| 373 | 
            -
                ossl_ec_point *new_point;
         | 
| 374 | 
            -
             | 
| 375 | 
            -
                obj = rb_obj_alloc(cEC_POINT);
         | 
| 376 | 
            -
                TypedData_Get_Struct(obj, ossl_ec_point, &ossl_ec_point_type, new_point);
         | 
| 377 | 
            -
             | 
| 378 | 
            -
                SafeRequire_EC_GROUP(group_v, group);
         | 
| 379 | 
            -
             | 
| 380 | 
            -
                new_point->point = EC_POINT_dup(point, group);
         | 
| 381 | 
            -
                if (new_point->point == NULL)
         | 
| 382 | 
            -
                    ossl_raise(eEC_POINT, "EC_POINT_dup");
         | 
| 383 | 
            -
                rb_iv_set(obj, "@group", group_v);
         | 
| 384 | 
            -
             | 
| 385 | 
            -
                return obj;
         | 
| 386 | 
            -
            }
         | 
| 387 | 
            -
             | 
| 388 362 | 
             
            /*
         | 
| 389 363 | 
             
             *  call-seq:
         | 
| 390 364 | 
             
             *     key.public_key   => OpenSSL::PKey::EC::Point
         | 
| @@ -395,18 +369,12 @@ static VALUE ossl_ec_key_get_public_key(VALUE self) | |
| 395 369 | 
             
            {
         | 
| 396 370 | 
             
                EC_KEY *ec;
         | 
| 397 371 | 
             
                const EC_POINT *point;
         | 
| 398 | 
            -
                VALUE group;
         | 
| 399 | 
            -
             | 
| 400 | 
            -
                Require_EC_KEY(self, ec);
         | 
| 401 372 |  | 
| 373 | 
            +
                GetEC(self, ec);
         | 
| 402 374 | 
             
                if ((point = EC_KEY_get0_public_key(ec)) == NULL)
         | 
| 403 375 | 
             
                    return Qnil;
         | 
| 404 376 |  | 
| 405 | 
            -
                 | 
| 406 | 
            -
                if (NIL_P(group))
         | 
| 407 | 
            -
                    ossl_raise(eECError, "EC_KEY_get0_get0_group (has public_key but no group???");
         | 
| 408 | 
            -
             | 
| 409 | 
            -
                return ossl_ec_point_dup(point, group);
         | 
| 377 | 
            +
                return ec_point_new(point, EC_KEY_get0_group(ec));
         | 
| 410 378 | 
             
            }
         | 
| 411 379 |  | 
| 412 380 | 
             
            /*
         | 
| @@ -420,9 +388,9 @@ static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key) | |
| 420 388 | 
             
                EC_KEY *ec;
         | 
| 421 389 | 
             
                EC_POINT *point = NULL;
         | 
| 422 390 |  | 
| 423 | 
            -
                 | 
| 391 | 
            +
                GetEC(self, ec);
         | 
| 424 392 | 
             
                if (!NIL_P(public_key))
         | 
| 425 | 
            -
                     | 
| 393 | 
            +
                    SafeGetECPoint(public_key, point);
         | 
| 426 394 |  | 
| 427 395 | 
             
                switch (EC_KEY_set_public_key(ec, point)) {
         | 
| 428 396 | 
             
                case 1:
         | 
| @@ -439,32 +407,34 @@ static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key) | |
| 439 407 |  | 
| 440 408 | 
             
            /*
         | 
| 441 409 | 
             
             *  call-seq:
         | 
| 442 | 
            -
             *     key. | 
| 410 | 
            +
             *     key.public? => true or false
         | 
| 443 411 | 
             
             *
         | 
| 444 | 
            -
             *   | 
| 412 | 
            +
             *  Returns whether this EC instance has a public key. The public key
         | 
| 413 | 
            +
             *  (EC::Point) can be retrieved with EC#public_key.
         | 
| 445 414 | 
             
             */
         | 
| 446 | 
            -
            static VALUE  | 
| 415 | 
            +
            static VALUE ossl_ec_key_is_public(VALUE self)
         | 
| 447 416 | 
             
            {
         | 
| 448 417 | 
             
                EC_KEY *ec;
         | 
| 449 418 |  | 
| 450 | 
            -
                 | 
| 419 | 
            +
                GetEC(self, ec);
         | 
| 451 420 |  | 
| 452 | 
            -
                return  | 
| 421 | 
            +
                return EC_KEY_get0_public_key(ec) ? Qtrue : Qfalse;
         | 
| 453 422 | 
             
            }
         | 
| 454 423 |  | 
| 455 424 | 
             
            /*
         | 
| 456 425 | 
             
             *  call-seq:
         | 
| 457 | 
            -
             *     key. | 
| 426 | 
            +
             *     key.private? => true or false
         | 
| 458 427 | 
             
             *
         | 
| 459 | 
            -
             *   | 
| 428 | 
            +
             *  Returns whether this EC instance has a private key. The private key (BN) can
         | 
| 429 | 
            +
             *  be retrieved with EC#private_key.
         | 
| 460 430 | 
             
             */
         | 
| 461 | 
            -
            static VALUE  | 
| 431 | 
            +
            static VALUE ossl_ec_key_is_private(VALUE self)
         | 
| 462 432 | 
             
            {
         | 
| 463 433 | 
             
                EC_KEY *ec;
         | 
| 464 434 |  | 
| 465 | 
            -
                 | 
| 435 | 
            +
                GetEC(self, ec);
         | 
| 466 436 |  | 
| 467 | 
            -
                return  | 
| 437 | 
            +
                return EC_KEY_get0_private_key(ec) ? Qtrue : Qfalse;
         | 
| 468 438 | 
             
            }
         | 
| 469 439 |  | 
| 470 440 | 
             
            static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int format)
         | 
| @@ -473,11 +443,10 @@ static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int forma | |
| 473 443 | 
             
                BIO *out;
         | 
| 474 444 | 
             
                int i = -1;
         | 
| 475 445 | 
             
                int private = 0;
         | 
| 476 | 
            -
                char *password = NULL;
         | 
| 477 446 | 
             
                VALUE str;
         | 
| 478 447 | 
             
                const EVP_CIPHER *cipher = NULL;
         | 
| 479 448 |  | 
| 480 | 
            -
                 | 
| 449 | 
            +
                GetEC(self, ec);
         | 
| 481 450 |  | 
| 482 451 | 
             
                if (EC_KEY_get0_public_key(ec) == NULL)
         | 
| 483 452 | 
             
                    ossl_raise(eECError, "can't export - no public key set");
         | 
| @@ -490,12 +459,7 @@ static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int forma | |
| 490 459 |  | 
| 491 460 | 
             
                if (!NIL_P(ciph)) {
         | 
| 492 461 | 
             
            	cipher = GetCipherPtr(ciph);
         | 
| 493 | 
            -
            	 | 
| 494 | 
            -
            	    StringValue(pass);
         | 
| 495 | 
            -
            	    if (RSTRING_LENINT(pass) < OSSL_MIN_PWD_LEN)
         | 
| 496 | 
            -
            		ossl_raise(eOSSLError, "OpenSSL requires passwords to be at least four characters long");
         | 
| 497 | 
            -
            	    password = RSTRING_PTR(pass);
         | 
| 498 | 
            -
            	}
         | 
| 462 | 
            +
            	pass = ossl_pem_passwd_value(pass);
         | 
| 499 463 | 
             
                }
         | 
| 500 464 |  | 
| 501 465 | 
             
                if (!(out = BIO_new(BIO_s_mem())))
         | 
| @@ -504,7 +468,7 @@ static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int forma | |
| 504 468 | 
             
                switch(format) {
         | 
| 505 469 | 
             
                case EXPORT_PEM:
         | 
| 506 470 | 
             
                	if (private) {
         | 
| 507 | 
            -
                        i = PEM_write_bio_ECPrivateKey(out, ec, cipher, NULL, 0,  | 
| 471 | 
            +
                        i = PEM_write_bio_ECPrivateKey(out, ec, cipher, NULL, 0, ossl_pem_passwd_cb, (void *)pass);
         | 
| 508 472 | 
             
                	} else {
         | 
| 509 473 | 
             
                        i = PEM_write_bio_EC_PUBKEY(out, ec);
         | 
| 510 474 | 
             
                    }
         | 
| @@ -538,12 +502,10 @@ static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int forma | |
| 538 502 | 
             
             *     key.export([cipher, pass_phrase]) => String
         | 
| 539 503 | 
             
             *     key.to_pem([cipher, pass_phrase]) => String
         | 
| 540 504 | 
             
             *
         | 
| 541 | 
            -
             * Outputs the EC key in PEM encoding.  If +cipher+ and +pass_phrase+ are
         | 
| 542 | 
            -
             *  | 
| 543 | 
            -
             *  | 
| 544 | 
            -
             *  | 
| 545 | 
            -
             * text.
         | 
| 546 | 
            -
             *
         | 
| 505 | 
            +
             * Outputs the EC key in PEM encoding.  If +cipher+ and +pass_phrase+ are given
         | 
| 506 | 
            +
             * they will be used to encrypt the key.  +cipher+ must be an OpenSSL::Cipher
         | 
| 507 | 
            +
             * instance. Note that encryption will only be effective for a private key,
         | 
| 508 | 
            +
             * public keys will always be encoded in plain text.
         | 
| 547 509 | 
             
             */
         | 
| 548 510 | 
             
            static VALUE ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
         | 
| 549 511 | 
             
            {
         | 
| @@ -575,7 +537,7 @@ static VALUE ossl_ec_key_to_text(VALUE self) | |
| 575 537 | 
             
                BIO *out;
         | 
| 576 538 | 
             
                VALUE str;
         | 
| 577 539 |  | 
| 578 | 
            -
                 | 
| 540 | 
            +
                GetEC(self, ec);
         | 
| 579 541 | 
             
                if (!(out = BIO_new(BIO_s_mem()))) {
         | 
| 580 542 | 
             
            	ossl_raise(eECError, "BIO_new(BIO_s_mem())");
         | 
| 581 543 | 
             
                }
         | 
| @@ -590,16 +552,23 @@ static VALUE ossl_ec_key_to_text(VALUE self) | |
| 590 552 |  | 
| 591 553 | 
             
            /*
         | 
| 592 554 | 
             
             *  call-seq:
         | 
| 593 | 
            -
             *     key.generate_key   => self
         | 
| 555 | 
            +
             *     key.generate_key!   => self
         | 
| 556 | 
            +
             *
         | 
| 557 | 
            +
             * Generates a new random private and public key.
         | 
| 594 558 | 
             
             *
         | 
| 595 | 
            -
             * | 
| 559 | 
            +
             * See also the OpenSSL documentation for EC_KEY_generate_key()
         | 
| 560 | 
            +
             *
         | 
| 561 | 
            +
             * === Example
         | 
| 562 | 
            +
             *   ec = OpenSSL::PKey::EC.new("prime256v1")
         | 
| 563 | 
            +
             *   p ec.private_key # => nil
         | 
| 564 | 
            +
             *   ec.generate_key!
         | 
| 565 | 
            +
             *   p ec.private_key # => #<OpenSSL::BN XXXXXX>
         | 
| 596 566 | 
             
             */
         | 
| 597 567 | 
             
            static VALUE ossl_ec_key_generate_key(VALUE self)
         | 
| 598 568 | 
             
            {
         | 
| 599 569 | 
             
                EC_KEY *ec;
         | 
| 600 570 |  | 
| 601 | 
            -
                 | 
| 602 | 
            -
             | 
| 571 | 
            +
                GetEC(self, ec);
         | 
| 603 572 | 
             
                if (EC_KEY_generate_key(ec) != 1)
         | 
| 604 573 | 
             
            	ossl_raise(eECError, "EC_KEY_generate_key");
         | 
| 605 574 |  | 
| @@ -618,8 +587,7 @@ static VALUE ossl_ec_key_check_key(VALUE self) | |
| 618 587 | 
             
            {
         | 
| 619 588 | 
             
                EC_KEY *ec;
         | 
| 620 589 |  | 
| 621 | 
            -
                 | 
| 622 | 
            -
             | 
| 590 | 
            +
                GetEC(self, ec);
         | 
| 623 591 | 
             
                if (EC_KEY_check_key(ec) != 1)
         | 
| 624 592 | 
             
            	ossl_raise(eECError, "EC_KEY_check_key");
         | 
| 625 593 |  | 
| @@ -639,8 +607,8 @@ static VALUE ossl_ec_key_dh_compute_key(VALUE self, VALUE pubkey) | |
| 639 607 | 
             
                int buf_len;
         | 
| 640 608 | 
             
                VALUE str;
         | 
| 641 609 |  | 
| 642 | 
            -
                 | 
| 643 | 
            -
                 | 
| 610 | 
            +
                GetEC(self, ec);
         | 
| 611 | 
            +
                SafeGetECPoint(pubkey, point);
         | 
| 644 612 |  | 
| 645 613 | 
             
            /* BUG: need a way to figure out the maximum string size */
         | 
| 646 614 | 
             
                buf_len = 1024;
         | 
| @@ -669,17 +637,16 @@ static VALUE ossl_ec_key_dsa_sign_asn1(VALUE self, VALUE data) | |
| 669 637 | 
             
                unsigned int buf_len;
         | 
| 670 638 | 
             
                VALUE str;
         | 
| 671 639 |  | 
| 672 | 
            -
                 | 
| 640 | 
            +
                GetEC(self, ec);
         | 
| 673 641 | 
             
                StringValue(data);
         | 
| 674 642 |  | 
| 675 643 | 
             
                if (EC_KEY_get0_private_key(ec) == NULL)
         | 
| 676 644 | 
             
            	ossl_raise(eECError, "Private EC key needed!");
         | 
| 677 645 |  | 
| 678 | 
            -
                str = rb_str_new(0, ECDSA_size(ec) | 
| 646 | 
            +
                str = rb_str_new(0, ECDSA_size(ec));
         | 
| 679 647 | 
             
                if (ECDSA_sign(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LENINT(data), (unsigned char *) RSTRING_PTR(str), &buf_len, ec) != 1)
         | 
| 680 | 
            -
             | 
| 681 | 
            -
             | 
| 682 | 
            -
                rb_str_resize(str, buf_len);
         | 
| 648 | 
            +
            	ossl_raise(eECError, "ECDSA_sign");
         | 
| 649 | 
            +
                rb_str_set_len(str, buf_len);
         | 
| 683 650 |  | 
| 684 651 | 
             
                return str;
         | 
| 685 652 | 
             
            }
         | 
| @@ -694,7 +661,7 @@ static VALUE ossl_ec_key_dsa_verify_asn1(VALUE self, VALUE data, VALUE sig) | |
| 694 661 | 
             
            {
         | 
| 695 662 | 
             
                EC_KEY *ec;
         | 
| 696 663 |  | 
| 697 | 
            -
                 | 
| 664 | 
            +
                GetEC(self, ec);
         | 
| 698 665 | 
             
                StringValue(data);
         | 
| 699 666 | 
             
                StringValue(sig);
         | 
| 700 667 |  | 
| @@ -709,12 +676,13 @@ static VALUE ossl_ec_key_dsa_verify_asn1(VALUE self, VALUE data, VALUE sig) | |
| 709 676 | 
             
                UNREACHABLE;
         | 
| 710 677 | 
             
            }
         | 
| 711 678 |  | 
| 712 | 
            -
             | 
| 679 | 
            +
            /*
         | 
| 680 | 
            +
             * OpenSSL::PKey::EC::Group
         | 
| 681 | 
            +
             */
         | 
| 682 | 
            +
            static void
         | 
| 683 | 
            +
            ossl_ec_group_free(void *ptr)
         | 
| 713 684 | 
             
            {
         | 
| 714 | 
            -
                 | 
| 715 | 
            -
                if (!ec_group->dont_free && ec_group->group)
         | 
| 716 | 
            -
                    EC_GROUP_clear_free(ec_group->group);
         | 
| 717 | 
            -
                ruby_xfree(ec_group);
         | 
| 685 | 
            +
                EC_GROUP_clear_free(ptr);
         | 
| 718 686 | 
             
            }
         | 
| 719 687 |  | 
| 720 688 | 
             
            static const rb_data_type_t ossl_ec_group_type = {
         | 
| @@ -725,40 +693,55 @@ static const rb_data_type_t ossl_ec_group_type = { | |
| 725 693 | 
             
                0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
         | 
| 726 694 | 
             
            };
         | 
| 727 695 |  | 
| 728 | 
            -
            static VALUE | 
| 696 | 
            +
            static VALUE
         | 
| 697 | 
            +
            ossl_ec_group_alloc(VALUE klass)
         | 
| 698 | 
            +
            {
         | 
| 699 | 
            +
                return TypedData_Wrap_Struct(klass, &ossl_ec_group_type, NULL);
         | 
| 700 | 
            +
            }
         | 
| 701 | 
            +
             | 
| 702 | 
            +
            static VALUE
         | 
| 703 | 
            +
            ec_group_new(const EC_GROUP *group)
         | 
| 729 704 | 
             
            {
         | 
| 730 | 
            -
                ossl_ec_group *ec_group;
         | 
| 731 705 | 
             
                VALUE obj;
         | 
| 706 | 
            +
                EC_GROUP *group_new;
         | 
| 732 707 |  | 
| 733 | 
            -
                obj =  | 
| 708 | 
            +
                obj = ossl_ec_group_alloc(cEC_GROUP);
         | 
| 709 | 
            +
                group_new = EC_GROUP_dup(group);
         | 
| 710 | 
            +
                if (!group_new)
         | 
| 711 | 
            +
            	ossl_raise(eEC_GROUP, "EC_GROUP_dup");
         | 
| 712 | 
            +
                RTYPEDDATA_DATA(obj) = group_new;
         | 
| 734 713 |  | 
| 735 714 | 
             
                return obj;
         | 
| 736 715 | 
             
            }
         | 
| 737 716 |  | 
| 738 | 
            -
            /* | 
| 739 | 
            -
             * | 
| 740 | 
            -
             * | 
| 741 | 
            -
             * | 
| 742 | 
            -
             * | 
| 743 | 
            -
             * | 
| 744 | 
            -
             * | 
| 745 | 
            -
             * | 
| 746 | 
            -
             * | 
| 747 | 
            -
             * | 
| 748 | 
            -
             * | 
| 749 | 
            -
             * | 
| 750 | 
            -
             * | 
| 717 | 
            +
            /*
         | 
| 718 | 
            +
             * call-seq:
         | 
| 719 | 
            +
             *   OpenSSL::PKey::EC::Group.new(ec_group)
         | 
| 720 | 
            +
             *   OpenSSL::PKey::EC::Group.new(pem_or_der_encoded)
         | 
| 721 | 
            +
             *   OpenSSL::PKey::EC::Group.new(ec_method)
         | 
| 722 | 
            +
             *   OpenSSL::PKey::EC::Group.new(:GFp, bignum_p, bignum_a, bignum_b)
         | 
| 723 | 
            +
             *   OpenSSL::PKey::EC::Group.new(:GF2m, bignum_p, bignum_a, bignum_b)
         | 
| 724 | 
            +
             *
         | 
| 725 | 
            +
             * Creates a new EC::Group object.
         | 
| 726 | 
            +
             *
         | 
| 727 | 
            +
             * +ec_method+ is a symbol that represents an EC_METHOD. Currently the following
         | 
| 728 | 
            +
             * are supported:
         | 
| 729 | 
            +
             *
         | 
| 730 | 
            +
             * * :GFp_simple
         | 
| 731 | 
            +
             * * :GFp_mont
         | 
| 732 | 
            +
             * * :GFp_nist
         | 
| 733 | 
            +
             * * :GF2m_simple
         | 
| 751 734 | 
             
             *
         | 
| 752 | 
            -
             * | 
| 735 | 
            +
             * If the first argument is :GFp or :GF2m, creates a new curve with given
         | 
| 736 | 
            +
             * parameters.
         | 
| 753 737 | 
             
             */
         | 
| 754 738 | 
             
            static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self)
         | 
| 755 739 | 
             
            {
         | 
| 756 740 | 
             
                VALUE arg1, arg2, arg3, arg4;
         | 
| 757 | 
            -
                 | 
| 758 | 
            -
                EC_GROUP *group = NULL;
         | 
| 741 | 
            +
                EC_GROUP *group;
         | 
| 759 742 |  | 
| 760 | 
            -
                TypedData_Get_Struct(self,  | 
| 761 | 
            -
                if ( | 
| 743 | 
            +
                TypedData_Get_Struct(self, EC_GROUP, &ossl_ec_group_type, group);
         | 
| 744 | 
            +
                if (group)
         | 
| 762 745 | 
             
                    ossl_raise(rb_eRuntimeError, "EC_GROUP is already initialized");
         | 
| 763 746 |  | 
| 764 747 | 
             
                switch (rb_scan_args(argc, argv, "13", &arg1, &arg2, &arg3, &arg4)) {
         | 
| @@ -788,11 +771,11 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self) | |
| 788 771 | 
             
                    } else if (rb_obj_is_kind_of(arg1, cEC_GROUP)) {
         | 
| 789 772 | 
             
                        const EC_GROUP *arg1_group;
         | 
| 790 773 |  | 
| 791 | 
            -
                         | 
| 774 | 
            +
                        SafeGetECGroup(arg1, arg1_group);
         | 
| 792 775 | 
             
                        if ((group = EC_GROUP_dup(arg1_group)) == NULL)
         | 
| 793 776 | 
             
                            ossl_raise(eEC_GROUP, "EC_GROUP_dup");
         | 
| 794 777 | 
             
                    } else {
         | 
| 795 | 
            -
                        BIO *in = ossl_obj2bio(arg1);
         | 
| 778 | 
            +
                        BIO *in = ossl_obj2bio(&arg1);
         | 
| 796 779 |  | 
| 797 780 | 
             
                        group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
         | 
| 798 781 | 
             
                        if (!group) {
         | 
| @@ -806,13 +789,13 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self) | |
| 806 789 | 
             
                            const char *name = StringValueCStr(arg1);
         | 
| 807 790 | 
             
                            int nid = OBJ_sn2nid(name);
         | 
| 808 791 |  | 
| 809 | 
            -
            		( | 
| 792 | 
            +
            		ossl_clear_error(); /* ignore errors in d2i_ECPKParameters_bio() */
         | 
| 810 793 | 
             
                            if (nid == NID_undef)
         | 
| 811 | 
            -
                                ossl_raise(eEC_GROUP, "unknown curve name (% | 
| 794 | 
            +
                                ossl_raise(eEC_GROUP, "unknown curve name (%"PRIsVALUE")", arg1);
         | 
| 812 795 |  | 
| 813 796 | 
             
                            group = EC_GROUP_new_by_curve_name(nid);
         | 
| 814 797 | 
             
                            if (group == NULL)
         | 
| 815 | 
            -
                                ossl_raise(eEC_GROUP, "unable to create curve (% | 
| 798 | 
            +
                                ossl_raise(eEC_GROUP, "unable to create curve (%"PRIsVALUE")", arg1);
         | 
| 816 799 |  | 
| 817 800 | 
             
                            EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
         | 
| 818 801 | 
             
                            EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_UNCOMPRESSED);
         | 
| @@ -851,23 +834,43 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self) | |
| 851 834 |  | 
| 852 835 | 
             
                if (group == NULL)
         | 
| 853 836 | 
             
                    ossl_raise(eEC_GROUP, "");
         | 
| 837 | 
            +
                RTYPEDDATA_DATA(self) = group;
         | 
| 838 | 
            +
             | 
| 839 | 
            +
                return self;
         | 
| 840 | 
            +
            }
         | 
| 841 | 
            +
             | 
| 842 | 
            +
            static VALUE
         | 
| 843 | 
            +
            ossl_ec_group_initialize_copy(VALUE self, VALUE other)
         | 
| 844 | 
            +
            {
         | 
| 845 | 
            +
                EC_GROUP *group, *group_new;
         | 
| 846 | 
            +
             | 
| 847 | 
            +
                TypedData_Get_Struct(self, EC_GROUP, &ossl_ec_group_type, group_new);
         | 
| 848 | 
            +
                if (group_new)
         | 
| 849 | 
            +
            	ossl_raise(eEC_GROUP, "EC::Group already initialized");
         | 
| 850 | 
            +
                SafeGetECGroup(other, group);
         | 
| 854 851 |  | 
| 855 | 
            -
                 | 
| 852 | 
            +
                group_new = EC_GROUP_dup(group);
         | 
| 853 | 
            +
                if (!group_new)
         | 
| 854 | 
            +
            	ossl_raise(eEC_GROUP, "EC_GROUP_dup");
         | 
| 855 | 
            +
                RTYPEDDATA_DATA(self) = group_new;
         | 
| 856 856 |  | 
| 857 857 | 
             
                return self;
         | 
| 858 858 | 
             
            }
         | 
| 859 859 |  | 
| 860 | 
            -
            /* | 
| 861 | 
            -
             * | 
| 862 | 
            -
             * | 
| 860 | 
            +
            /*
         | 
| 861 | 
            +
             * call-seq:
         | 
| 862 | 
            +
             *   group1.eql?(group2)   => true | false
         | 
| 863 | 
            +
             *   group1 == group2   => true | false
         | 
| 863 864 | 
             
             *
         | 
| 865 | 
            +
             * Returns true if the two groups use the same curve and have the same
         | 
| 866 | 
            +
             * parameters, false otherwise.
         | 
| 864 867 | 
             
             */
         | 
| 865 868 | 
             
            static VALUE ossl_ec_group_eql(VALUE a, VALUE b)
         | 
| 866 869 | 
             
            {
         | 
| 867 870 | 
             
                EC_GROUP *group1 = NULL, *group2 = NULL;
         | 
| 868 871 |  | 
| 869 | 
            -
                 | 
| 870 | 
            -
                 | 
| 872 | 
            +
                GetECGroup(a, group1);
         | 
| 873 | 
            +
                SafeGetECGroup(b, group2);
         | 
| 871 874 |  | 
| 872 875 | 
             
                if (EC_GROUP_cmp(group1, group2, ossl_bn_ctx) == 1)
         | 
| 873 876 | 
             
                   return Qfalse;
         | 
| @@ -875,27 +878,35 @@ static VALUE ossl_ec_group_eql(VALUE a, VALUE b) | |
| 875 878 | 
             
                return Qtrue;
         | 
| 876 879 | 
             
            }
         | 
| 877 880 |  | 
| 878 | 
            -
            /* | 
| 879 | 
            -
             * | 
| 881 | 
            +
            /*
         | 
| 882 | 
            +
             * call-seq:
         | 
| 883 | 
            +
             *   group.generator   => ec_point
         | 
| 880 884 | 
             
             *
         | 
| 881 | 
            -
             * | 
| 885 | 
            +
             * Returns the generator of the group.
         | 
| 886 | 
            +
             *
         | 
| 887 | 
            +
             * See the OpenSSL documentation for EC_GROUP_get0_generator()
         | 
| 882 888 | 
             
             */
         | 
| 883 889 | 
             
            static VALUE ossl_ec_group_get_generator(VALUE self)
         | 
| 884 890 | 
             
            {
         | 
| 885 | 
            -
                 | 
| 886 | 
            -
                 | 
| 887 | 
            -
             | 
| 888 | 
            -
                Require_EC_GROUP(self, group);
         | 
| 891 | 
            +
                EC_GROUP *group;
         | 
| 892 | 
            +
                const EC_POINT *generator;
         | 
| 889 893 |  | 
| 890 | 
            -
                 | 
| 894 | 
            +
                GetECGroup(self, group);
         | 
| 895 | 
            +
                generator = EC_GROUP_get0_generator(group);
         | 
| 896 | 
            +
                if (!generator)
         | 
| 897 | 
            +
            	return Qnil;
         | 
| 891 898 |  | 
| 892 | 
            -
                return  | 
| 899 | 
            +
                return ec_point_new(generator, group);
         | 
| 893 900 | 
             
            }
         | 
| 894 901 |  | 
| 895 | 
            -
            /* | 
| 896 | 
            -
             * | 
| 902 | 
            +
            /*
         | 
| 903 | 
            +
             * call-seq:
         | 
| 904 | 
            +
             *   group.set_generator(generator, order, cofactor)   => self
         | 
| 897 905 | 
             
             *
         | 
| 898 | 
            -
             * | 
| 906 | 
            +
             * Sets the curve parameters. +generator+ must be an instance of EC::Point that
         | 
| 907 | 
            +
             * is on the curve. +order+ and +cofactor+ are integers.
         | 
| 908 | 
            +
             *
         | 
| 909 | 
            +
             * See the OpenSSL documentation for EC_GROUP_set_generator()
         | 
| 899 910 | 
             
             */
         | 
| 900 911 | 
             
            static VALUE ossl_ec_group_set_generator(VALUE self, VALUE generator, VALUE order, VALUE cofactor)
         | 
| 901 912 | 
             
            {
         | 
| @@ -903,8 +914,8 @@ static VALUE ossl_ec_group_set_generator(VALUE self, VALUE generator, VALUE orde | |
| 903 914 | 
             
                const EC_POINT *point;
         | 
| 904 915 | 
             
                const BIGNUM *o, *co;
         | 
| 905 916 |  | 
| 906 | 
            -
                 | 
| 907 | 
            -
                 | 
| 917 | 
            +
                GetECGroup(self, group);
         | 
| 918 | 
            +
                SafeGetECPoint(generator, point);
         | 
| 908 919 | 
             
                o = GetBNPtr(order);
         | 
| 909 920 | 
             
                co = GetBNPtr(cofactor);
         | 
| 910 921 |  | 
| @@ -914,10 +925,13 @@ static VALUE ossl_ec_group_set_generator(VALUE self, VALUE generator, VALUE orde | |
| 914 925 | 
             
                return self;
         | 
| 915 926 | 
             
            }
         | 
| 916 927 |  | 
| 917 | 
            -
            /* | 
| 918 | 
            -
             * | 
| 928 | 
            +
            /*
         | 
| 929 | 
            +
             * call-seq:
         | 
| 930 | 
            +
             *   group.get_order   => order_bn
         | 
| 919 931 | 
             
             *
         | 
| 920 | 
            -
             * | 
| 932 | 
            +
             * Returns the order of the group.
         | 
| 933 | 
            +
             *
         | 
| 934 | 
            +
             * See the OpenSSL documentation for EC_GROUP_get_order()
         | 
| 921 935 | 
             
             */
         | 
| 922 936 | 
             
            static VALUE ossl_ec_group_get_order(VALUE self)
         | 
| 923 937 | 
             
            {
         | 
| @@ -925,7 +939,7 @@ static VALUE ossl_ec_group_get_order(VALUE self) | |
| 925 939 | 
             
                BIGNUM *bn;
         | 
| 926 940 | 
             
                EC_GROUP *group = NULL;
         | 
| 927 941 |  | 
| 928 | 
            -
                 | 
| 942 | 
            +
                GetECGroup(self, group);
         | 
| 929 943 |  | 
| 930 944 | 
             
                bn_obj = ossl_bn_new(NULL);
         | 
| 931 945 | 
             
                bn = GetBNPtr(bn_obj);
         | 
| @@ -936,10 +950,13 @@ static VALUE ossl_ec_group_get_order(VALUE self) | |
| 936 950 | 
             
                return bn_obj;
         | 
| 937 951 | 
             
            }
         | 
| 938 952 |  | 
| 939 | 
            -
            /* | 
| 940 | 
            -
             * | 
| 953 | 
            +
            /*
         | 
| 954 | 
            +
             * call-seq:
         | 
| 955 | 
            +
             *   group.get_cofactor   => cofactor_bn
         | 
| 941 956 | 
             
             *
         | 
| 942 | 
            -
             * | 
| 957 | 
            +
             * Returns the cofactor of the group.
         | 
| 958 | 
            +
             *
         | 
| 959 | 
            +
             * See the OpenSSL documentation for EC_GROUP_get_cofactor()
         | 
| 943 960 | 
             
             */
         | 
| 944 961 | 
             
            static VALUE ossl_ec_group_get_cofactor(VALUE self)
         | 
| 945 962 | 
             
            {
         | 
| @@ -947,7 +964,7 @@ static VALUE ossl_ec_group_get_cofactor(VALUE self) | |
| 947 964 | 
             
                BIGNUM *bn;
         | 
| 948 965 | 
             
                EC_GROUP *group = NULL;
         | 
| 949 966 |  | 
| 950 | 
            -
                 | 
| 967 | 
            +
                GetECGroup(self, group);
         | 
| 951 968 |  | 
| 952 969 | 
             
                bn_obj = ossl_bn_new(NULL);
         | 
| 953 970 | 
             
                bn = GetBNPtr(bn_obj);
         | 
| @@ -958,17 +975,20 @@ static VALUE ossl_ec_group_get_cofactor(VALUE self) | |
| 958 975 | 
             
                return bn_obj;
         | 
| 959 976 | 
             
            }
         | 
| 960 977 |  | 
| 961 | 
            -
            /* | 
| 962 | 
            -
             * | 
| 978 | 
            +
            /*
         | 
| 979 | 
            +
             * call-seq:
         | 
| 980 | 
            +
             *   group.curve_name  => String
         | 
| 963 981 | 
             
             *
         | 
| 964 | 
            -
             * | 
| 982 | 
            +
             * Returns the curve name (sn).
         | 
| 983 | 
            +
             *
         | 
| 984 | 
            +
             * See the OpenSSL documentation for EC_GROUP_get_curve_name()
         | 
| 965 985 | 
             
             */
         | 
| 966 986 | 
             
            static VALUE ossl_ec_group_get_curve_name(VALUE self)
         | 
| 967 987 | 
             
            {
         | 
| 968 988 | 
             
                EC_GROUP *group = NULL;
         | 
| 969 989 | 
             
                int nid;
         | 
| 970 990 |  | 
| 971 | 
            -
                 | 
| 991 | 
            +
                GetECGroup(self, group);
         | 
| 972 992 | 
             
                if (group == NULL)
         | 
| 973 993 | 
             
                    return Qnil;
         | 
| 974 994 |  | 
| @@ -978,10 +998,14 @@ static VALUE ossl_ec_group_get_curve_name(VALUE self) | |
| 978 998 | 
             
                return rb_str_new2(OBJ_nid2sn(nid));
         | 
| 979 999 | 
             
            }
         | 
| 980 1000 |  | 
| 981 | 
            -
            /* | 
| 982 | 
            -
             * | 
| 1001 | 
            +
            /*
         | 
| 1002 | 
            +
             * call-seq:
         | 
| 1003 | 
            +
             *   EC.builtin_curves => [[sn, comment], ...]
         | 
| 983 1004 | 
             
             *
         | 
| 984 | 
            -
             * | 
| 1005 | 
            +
             * Obtains a list of all predefined curves by the OpenSSL. Curve names are
         | 
| 1006 | 
            +
             * returned as sn.
         | 
| 1007 | 
            +
             *
         | 
| 1008 | 
            +
             * See the OpenSSL documentation for EC_get_builtin_curves().
         | 
| 985 1009 | 
             
             */
         | 
| 986 1010 | 
             
            static VALUE ossl_s_builtin_curves(VALUE self)
         | 
| 987 1011 | 
             
            {
         | 
| @@ -1011,43 +1035,56 @@ static VALUE ossl_s_builtin_curves(VALUE self) | |
| 1011 1035 | 
             
                return ret;
         | 
| 1012 1036 | 
             
            }
         | 
| 1013 1037 |  | 
| 1014 | 
            -
            /* | 
| 1015 | 
            -
             * | 
| 1038 | 
            +
            /*
         | 
| 1039 | 
            +
             * call-seq:
         | 
| 1040 | 
            +
             *   group.asn1_flag -> Integer
         | 
| 1016 1041 | 
             
             *
         | 
| 1017 | 
            -
             * | 
| 1042 | 
            +
             * Returns the flags set on the group.
         | 
| 1043 | 
            +
             *
         | 
| 1044 | 
            +
             * See also #asn1_flag=.
         | 
| 1018 1045 | 
             
             */
         | 
| 1019 1046 | 
             
            static VALUE ossl_ec_group_get_asn1_flag(VALUE self)
         | 
| 1020 1047 | 
             
            {
         | 
| 1021 1048 | 
             
                EC_GROUP *group = NULL;
         | 
| 1022 1049 | 
             
                int flag;
         | 
| 1023 1050 |  | 
| 1024 | 
            -
                 | 
| 1025 | 
            -
             | 
| 1051 | 
            +
                GetECGroup(self, group);
         | 
| 1026 1052 | 
             
                flag = EC_GROUP_get_asn1_flag(group);
         | 
| 1027 1053 |  | 
| 1028 | 
            -
                return  | 
| 1054 | 
            +
                return INT2NUM(flag);
         | 
| 1029 1055 | 
             
            }
         | 
| 1030 1056 |  | 
| 1031 | 
            -
            /* | 
| 1032 | 
            -
             * | 
| 1057 | 
            +
            /*
         | 
| 1058 | 
            +
             * call-seq:
         | 
| 1059 | 
            +
             *   group.asn1_flag = flags
         | 
| 1060 | 
            +
             *
         | 
| 1061 | 
            +
             * Sets flags on the group. The flag value is used to determine how to encode
         | 
| 1062 | 
            +
             * the group: encode explicit parameters or named curve using an OID.
         | 
| 1063 | 
            +
             *
         | 
| 1064 | 
            +
             * The flag value can be either of:
         | 
| 1033 1065 | 
             
             *
         | 
| 1034 | 
            -
             * | 
| 1066 | 
            +
             * * EC::NAMED_CURVE
         | 
| 1067 | 
            +
             * * EC::EXPLICIT_CURVE
         | 
| 1068 | 
            +
             *
         | 
| 1069 | 
            +
             * See the OpenSSL documentation for EC_GROUP_set_asn1_flag().
         | 
| 1035 1070 | 
             
             */
         | 
| 1036 1071 | 
             
            static VALUE ossl_ec_group_set_asn1_flag(VALUE self, VALUE flag_v)
         | 
| 1037 1072 | 
             
            {
         | 
| 1038 1073 | 
             
                EC_GROUP *group = NULL;
         | 
| 1039 1074 |  | 
| 1040 | 
            -
                 | 
| 1041 | 
            -
             | 
| 1075 | 
            +
                GetECGroup(self, group);
         | 
| 1042 1076 | 
             
                EC_GROUP_set_asn1_flag(group, NUM2INT(flag_v));
         | 
| 1043 1077 |  | 
| 1044 1078 | 
             
                return flag_v;
         | 
| 1045 1079 | 
             
            }
         | 
| 1046 1080 |  | 
| 1047 | 
            -
            /* | 
| 1048 | 
            -
             * | 
| 1081 | 
            +
            /*
         | 
| 1082 | 
            +
             * call-seq:
         | 
| 1083 | 
            +
             *   group.point_conversion_form -> Symbol
         | 
| 1084 | 
            +
             *
         | 
| 1085 | 
            +
             * Returns the form how EC::Point data is encoded as ASN.1.
         | 
| 1049 1086 | 
             
             *
         | 
| 1050 | 
            -
             * | 
| 1087 | 
            +
             * See also #point_conversion_form=.
         | 
| 1051 1088 | 
             
             */
         | 
| 1052 1089 | 
             
            static VALUE ossl_ec_group_get_point_conversion_form(VALUE self)
         | 
| 1053 1090 | 
             
            {
         | 
| @@ -1055,8 +1092,7 @@ static VALUE ossl_ec_group_get_point_conversion_form(VALUE self) | |
| 1055 1092 | 
             
                point_conversion_form_t form;
         | 
| 1056 1093 | 
             
                VALUE ret;
         | 
| 1057 1094 |  | 
| 1058 | 
            -
                 | 
| 1059 | 
            -
             | 
| 1095 | 
            +
                GetECGroup(self, group);
         | 
| 1060 1096 | 
             
                form = EC_GROUP_get_point_conversion_form(group);
         | 
| 1061 1097 |  | 
| 1062 1098 | 
             
                switch (form) {
         | 
| @@ -1069,46 +1105,67 @@ static VALUE ossl_ec_group_get_point_conversion_form(VALUE self) | |
| 1069 1105 | 
             
               return ID2SYM(ret);
         | 
| 1070 1106 | 
             
            }
         | 
| 1071 1107 |  | 
| 1072 | 
            -
             | 
| 1073 | 
            -
              | 
| 1108 | 
            +
            static point_conversion_form_t
         | 
| 1109 | 
            +
            parse_point_conversion_form_symbol(VALUE sym)
         | 
| 1110 | 
            +
            {
         | 
| 1111 | 
            +
                ID id = SYM2ID(sym);
         | 
| 1112 | 
            +
             | 
| 1113 | 
            +
                if (id == ID_uncompressed)
         | 
| 1114 | 
            +
            	return POINT_CONVERSION_UNCOMPRESSED;
         | 
| 1115 | 
            +
                else if (id == ID_compressed)
         | 
| 1116 | 
            +
            	return POINT_CONVERSION_COMPRESSED;
         | 
| 1117 | 
            +
                else if (id == ID_hybrid)
         | 
| 1118 | 
            +
            	return POINT_CONVERSION_HYBRID;
         | 
| 1119 | 
            +
                else
         | 
| 1120 | 
            +
            	ossl_raise(rb_eArgError, "unsupported point conversion form %+"PRIsVALUE
         | 
| 1121 | 
            +
            		   " (expected :compressed, :uncompressed, or :hybrid)", sym);
         | 
| 1122 | 
            +
            }
         | 
| 1123 | 
            +
             | 
| 1124 | 
            +
            /*
         | 
| 1125 | 
            +
             * call-seq:
         | 
| 1126 | 
            +
             *   group.point_conversion_form = form
         | 
| 1127 | 
            +
             *
         | 
| 1128 | 
            +
             * Sets the form how EC::Point data is encoded as ASN.1 as defined in X9.62.
         | 
| 1129 | 
            +
             *
         | 
| 1130 | 
            +
             * +format+ can be one of these:
         | 
| 1131 | 
            +
             *
         | 
| 1132 | 
            +
             * :compressed::
         | 
| 1133 | 
            +
             *   Encoded as z||x, where z is an octet indicating which solution of the
         | 
| 1134 | 
            +
             *   equation y is. z will be 0x02 or 0x03.
         | 
| 1135 | 
            +
             * :uncompressed::
         | 
| 1136 | 
            +
             *   Encoded as z||x||y, where z is an octet 0x04.
         | 
| 1137 | 
            +
             * :hybrid::
         | 
| 1138 | 
            +
             *   Encodes as z||x||y, where z is an octet indicating which solution of the
         | 
| 1139 | 
            +
             *   equation y is. z will be 0x06 or 0x07.
         | 
| 1074 1140 | 
             
             *
         | 
| 1075 | 
            -
             * | 
| 1141 | 
            +
             * See the OpenSSL documentation for EC_GROUP_set_point_conversion_form()
         | 
| 1076 1142 | 
             
             */
         | 
| 1077 | 
            -
            static VALUE | 
| 1143 | 
            +
            static VALUE
         | 
| 1144 | 
            +
            ossl_ec_group_set_point_conversion_form(VALUE self, VALUE form_v)
         | 
| 1078 1145 | 
             
            {
         | 
| 1079 | 
            -
                EC_GROUP *group | 
| 1146 | 
            +
                EC_GROUP *group;
         | 
| 1080 1147 | 
             
                point_conversion_form_t form;
         | 
| 1081 | 
            -
                ID form_id = SYM2ID(form_v);
         | 
| 1082 | 
            -
             | 
| 1083 | 
            -
                Require_EC_GROUP(self, group);
         | 
| 1084 1148 |  | 
| 1085 | 
            -
                 | 
| 1086 | 
            -
             | 
| 1087 | 
            -
                } else if (form_id == ID_compressed) {
         | 
| 1088 | 
            -
                    form = POINT_CONVERSION_COMPRESSED;
         | 
| 1089 | 
            -
                } else if (form_id == ID_hybrid) {
         | 
| 1090 | 
            -
                    form = POINT_CONVERSION_HYBRID;
         | 
| 1091 | 
            -
                } else {
         | 
| 1092 | 
            -
                    ossl_raise(rb_eArgError, "form must be :compressed, :uncompressed, or :hybrid");
         | 
| 1093 | 
            -
                }
         | 
| 1149 | 
            +
                GetECGroup(self, group);
         | 
| 1150 | 
            +
                form = parse_point_conversion_form_symbol(form_v);
         | 
| 1094 1151 |  | 
| 1095 1152 | 
             
                EC_GROUP_set_point_conversion_form(group, form);
         | 
| 1096 1153 |  | 
| 1097 1154 | 
             
                return form_v;
         | 
| 1098 1155 | 
             
            }
         | 
| 1099 1156 |  | 
| 1100 | 
            -
            /* | 
| 1101 | 
            -
             * | 
| 1157 | 
            +
            /*
         | 
| 1158 | 
            +
             * call-seq:
         | 
| 1159 | 
            +
             *   group.seed   => String or nil
         | 
| 1102 1160 | 
             
             *
         | 
| 1103 | 
            -
             * | 
| 1161 | 
            +
             * See the OpenSSL documentation for EC_GROUP_get0_seed()
         | 
| 1104 1162 | 
             
             */
         | 
| 1105 1163 | 
             
            static VALUE ossl_ec_group_get_seed(VALUE self)
         | 
| 1106 1164 | 
             
            {
         | 
| 1107 1165 | 
             
                EC_GROUP *group = NULL;
         | 
| 1108 1166 | 
             
                size_t seed_len;
         | 
| 1109 1167 |  | 
| 1110 | 
            -
                 | 
| 1111 | 
            -
             | 
| 1168 | 
            +
                GetECGroup(self, group);
         | 
| 1112 1169 | 
             
                seed_len = EC_GROUP_get_seed_len(group);
         | 
| 1113 1170 |  | 
| 1114 1171 | 
             
                if (seed_len == 0)
         | 
| @@ -1117,16 +1174,17 @@ static VALUE ossl_ec_group_get_seed(VALUE self) | |
| 1117 1174 | 
             
                return rb_str_new((const char *)EC_GROUP_get0_seed(group), seed_len);
         | 
| 1118 1175 | 
             
            }
         | 
| 1119 1176 |  | 
| 1120 | 
            -
            /* | 
| 1121 | 
            -
             * | 
| 1177 | 
            +
            /*
         | 
| 1178 | 
            +
             * call-seq:
         | 
| 1179 | 
            +
             *   group.seed = seed  => seed
         | 
| 1122 1180 | 
             
             *
         | 
| 1123 | 
            -
             * | 
| 1181 | 
            +
             * See the OpenSSL documentation for EC_GROUP_set_seed()
         | 
| 1124 1182 | 
             
             */
         | 
| 1125 1183 | 
             
            static VALUE ossl_ec_group_set_seed(VALUE self, VALUE seed)
         | 
| 1126 1184 | 
             
            {
         | 
| 1127 1185 | 
             
                EC_GROUP *group = NULL;
         | 
| 1128 1186 |  | 
| 1129 | 
            -
                 | 
| 1187 | 
            +
                GetECGroup(self, group);
         | 
| 1130 1188 | 
             
                StringValue(seed);
         | 
| 1131 1189 |  | 
| 1132 1190 | 
             
                if (EC_GROUP_set_seed(group, (unsigned char *)RSTRING_PTR(seed), RSTRING_LEN(seed)) != (size_t)RSTRING_LEN(seed))
         | 
| @@ -1137,16 +1195,17 @@ static VALUE ossl_ec_group_set_seed(VALUE self, VALUE seed) | |
| 1137 1195 |  | 
| 1138 1196 | 
             
            /* get/set curve GFp, GF2m */
         | 
| 1139 1197 |  | 
| 1140 | 
            -
            /* | 
| 1141 | 
            -
             * | 
| 1198 | 
            +
            /*
         | 
| 1199 | 
            +
             * call-seq:
         | 
| 1200 | 
            +
             *   group.degree   => integer
         | 
| 1142 1201 | 
             
             *
         | 
| 1143 | 
            -
             * | 
| 1202 | 
            +
             * See the OpenSSL documentation for EC_GROUP_get_degree()
         | 
| 1144 1203 | 
             
             */
         | 
| 1145 1204 | 
             
            static VALUE ossl_ec_group_get_degree(VALUE self)
         | 
| 1146 1205 | 
             
            {
         | 
| 1147 1206 | 
             
                EC_GROUP *group = NULL;
         | 
| 1148 1207 |  | 
| 1149 | 
            -
                 | 
| 1208 | 
            +
                GetECGroup(self, group);
         | 
| 1150 1209 |  | 
| 1151 1210 | 
             
                return INT2NUM(EC_GROUP_get_degree(group));
         | 
| 1152 1211 | 
             
            }
         | 
| @@ -1158,7 +1217,7 @@ static VALUE ossl_ec_group_to_string(VALUE self, int format) | |
| 1158 1217 | 
             
                int i = -1;
         | 
| 1159 1218 | 
             
                VALUE str;
         | 
| 1160 1219 |  | 
| 1161 | 
            -
                 | 
| 1220 | 
            +
                GetECGroup(self, group);
         | 
| 1162 1221 |  | 
| 1163 1222 | 
             
                if (!(out = BIO_new(BIO_s_mem())))
         | 
| 1164 1223 | 
             
                    ossl_raise(eEC_GROUP, "BIO_new(BIO_s_mem())");
         | 
| @@ -1185,8 +1244,9 @@ static VALUE ossl_ec_group_to_string(VALUE self, int format) | |
| 1185 1244 | 
             
                return str;
         | 
| 1186 1245 | 
             
            }
         | 
| 1187 1246 |  | 
| 1188 | 
            -
            /* | 
| 1189 | 
            -
             * | 
| 1247 | 
            +
            /*
         | 
| 1248 | 
            +
             * call-seq:
         | 
| 1249 | 
            +
             *   group.to_pem   => String
         | 
| 1190 1250 | 
             
             *
         | 
| 1191 1251 | 
             
             *  See the OpenSSL documentation for PEM_write_bio_ECPKParameters()
         | 
| 1192 1252 | 
             
             */
         | 
| @@ -1195,20 +1255,22 @@ static VALUE ossl_ec_group_to_pem(VALUE self) | |
| 1195 1255 | 
             
                return ossl_ec_group_to_string(self, EXPORT_PEM);
         | 
| 1196 1256 | 
             
            }
         | 
| 1197 1257 |  | 
| 1198 | 
            -
            /* | 
| 1199 | 
            -
             * | 
| 1258 | 
            +
            /*
         | 
| 1259 | 
            +
             * call-seq:
         | 
| 1260 | 
            +
             *   group.to_der   => String
         | 
| 1200 1261 | 
             
             *
         | 
| 1201 | 
            -
             * | 
| 1262 | 
            +
             * See the OpenSSL documentation for i2d_ECPKParameters_bio()
         | 
| 1202 1263 | 
             
             */
         | 
| 1203 1264 | 
             
            static VALUE ossl_ec_group_to_der(VALUE self)
         | 
| 1204 1265 | 
             
            {
         | 
| 1205 1266 | 
             
                return ossl_ec_group_to_string(self, EXPORT_DER);
         | 
| 1206 1267 | 
             
            }
         | 
| 1207 1268 |  | 
| 1208 | 
            -
            /* | 
| 1209 | 
            -
             * | 
| 1269 | 
            +
            /*
         | 
| 1270 | 
            +
             * call-seq:
         | 
| 1271 | 
            +
             *   group.to_text   => String
         | 
| 1210 1272 | 
             
             *
         | 
| 1211 | 
            -
             * | 
| 1273 | 
            +
             * See the OpenSSL documentation for ECPKParameters_print()
         | 
| 1212 1274 | 
             
             */
         | 
| 1213 1275 | 
             
            static VALUE ossl_ec_group_to_text(VALUE self)
         | 
| 1214 1276 | 
             
            {
         | 
| @@ -1216,7 +1278,7 @@ static VALUE ossl_ec_group_to_text(VALUE self) | |
| 1216 1278 | 
             
                BIO *out;
         | 
| 1217 1279 | 
             
                VALUE str;
         | 
| 1218 1280 |  | 
| 1219 | 
            -
                 | 
| 1281 | 
            +
                GetECGroup(self, group);
         | 
| 1220 1282 | 
             
                if (!(out = BIO_new(BIO_s_mem()))) {
         | 
| 1221 1283 | 
             
            	ossl_raise(eEC_GROUP, "BIO_new(BIO_s_mem())");
         | 
| 1222 1284 | 
             
                }
         | 
| @@ -1230,50 +1292,62 @@ static VALUE ossl_ec_group_to_text(VALUE self) | |
| 1230 1292 | 
             
            }
         | 
| 1231 1293 |  | 
| 1232 1294 |  | 
| 1233 | 
            -
             | 
| 1295 | 
            +
            /*
         | 
| 1296 | 
            +
             * OpenSSL::PKey::EC::Point
         | 
| 1297 | 
            +
             */
         | 
| 1298 | 
            +
            static void
         | 
| 1299 | 
            +
            ossl_ec_point_free(void *ptr)
         | 
| 1234 1300 | 
             
            {
         | 
| 1235 | 
            -
                 | 
| 1236 | 
            -
                if (!ec_point->dont_free && ec_point->point)
         | 
| 1237 | 
            -
                    EC_POINT_clear_free(ec_point->point);
         | 
| 1238 | 
            -
                ruby_xfree(ec_point);
         | 
| 1301 | 
            +
                EC_POINT_clear_free(ptr);
         | 
| 1239 1302 | 
             
            }
         | 
| 1240 1303 |  | 
| 1241 1304 | 
             
            static const rb_data_type_t ossl_ec_point_type = {
         | 
| 1242 | 
            -
                "OpenSSL/ | 
| 1305 | 
            +
                "OpenSSL/EC_POINT",
         | 
| 1243 1306 | 
             
                {
         | 
| 1244 1307 | 
             
            	0, ossl_ec_point_free,
         | 
| 1245 1308 | 
             
                },
         | 
| 1246 1309 | 
             
                0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
         | 
| 1247 1310 | 
             
            };
         | 
| 1248 1311 |  | 
| 1249 | 
            -
            static VALUE | 
| 1312 | 
            +
            static VALUE
         | 
| 1313 | 
            +
            ossl_ec_point_alloc(VALUE klass)
         | 
| 1314 | 
            +
            {
         | 
| 1315 | 
            +
                return TypedData_Wrap_Struct(klass, &ossl_ec_point_type, NULL);
         | 
| 1316 | 
            +
            }
         | 
| 1317 | 
            +
             | 
| 1318 | 
            +
            static VALUE
         | 
| 1319 | 
            +
            ec_point_new(const EC_POINT *point, const EC_GROUP *group)
         | 
| 1250 1320 | 
             
            {
         | 
| 1251 | 
            -
                 | 
| 1321 | 
            +
                EC_POINT *point_new;
         | 
| 1252 1322 | 
             
                VALUE obj;
         | 
| 1253 1323 |  | 
| 1254 | 
            -
                obj =  | 
| 1324 | 
            +
                obj = ossl_ec_point_alloc(cEC_POINT);
         | 
| 1325 | 
            +
                point_new = EC_POINT_dup(point, group);
         | 
| 1326 | 
            +
                if (!point_new)
         | 
| 1327 | 
            +
            	ossl_raise(eEC_POINT, "EC_POINT_dup");
         | 
| 1328 | 
            +
                RTYPEDDATA_DATA(obj) = point_new;
         | 
| 1329 | 
            +
                rb_ivar_set(obj, id_i_group, ec_group_new(group));
         | 
| 1255 1330 |  | 
| 1256 1331 | 
             
                return obj;
         | 
| 1257 1332 | 
             
            }
         | 
| 1258 1333 |  | 
| 1259 1334 | 
             
            /*
         | 
| 1260 | 
            -
             * | 
| 1261 | 
            -
             * | 
| 1262 | 
            -
             * | 
| 1263 | 
            -
             * | 
| 1335 | 
            +
             * call-seq:
         | 
| 1336 | 
            +
             *   OpenSSL::PKey::EC::Point.new(point)
         | 
| 1337 | 
            +
             *   OpenSSL::PKey::EC::Point.new(group)
         | 
| 1338 | 
            +
             *   OpenSSL::PKey::EC::Point.new(group, bn)
         | 
| 1264 1339 | 
             
             *
         | 
| 1265 | 
            -
             * | 
| 1340 | 
            +
             * See the OpenSSL documentation for EC_POINT_*
         | 
| 1266 1341 | 
             
             */
         | 
| 1267 1342 | 
             
            static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self)
         | 
| 1268 1343 | 
             
            {
         | 
| 1269 | 
            -
                 | 
| 1270 | 
            -
                EC_POINT *point = NULL;
         | 
| 1344 | 
            +
                EC_POINT *point;
         | 
| 1271 1345 | 
             
                VALUE arg1, arg2;
         | 
| 1272 1346 | 
             
                VALUE group_v = Qnil;
         | 
| 1273 1347 | 
             
                const EC_GROUP *group = NULL;
         | 
| 1274 1348 |  | 
| 1275 | 
            -
                TypedData_Get_Struct(self,  | 
| 1276 | 
            -
                if ( | 
| 1349 | 
            +
                TypedData_Get_Struct(self, EC_POINT, &ossl_ec_point_type, point);
         | 
| 1350 | 
            +
                if (point)
         | 
| 1277 1351 | 
             
                    ossl_raise(eEC_POINT, "EC_POINT already initialized");
         | 
| 1278 1352 |  | 
| 1279 1353 | 
             
                switch (rb_scan_args(argc, argv, "11", &arg1, &arg2)) {
         | 
| @@ -1281,14 +1355,14 @@ static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self) | |
| 1281 1355 | 
             
                    if (rb_obj_is_kind_of(arg1, cEC_POINT)) {
         | 
| 1282 1356 | 
             
                        const EC_POINT *arg_point;
         | 
| 1283 1357 |  | 
| 1284 | 
            -
             | 
| 1285 | 
            -
             | 
| 1286 | 
            -
             | 
| 1358 | 
            +
            	    group_v = rb_attr_get(arg1, id_i_group);
         | 
| 1359 | 
            +
            	    SafeGetECGroup(group_v, group);
         | 
| 1360 | 
            +
            	    SafeGetECPoint(arg1, arg_point);
         | 
| 1287 1361 |  | 
| 1288 1362 | 
             
                        point = EC_POINT_dup(arg_point, group);
         | 
| 1289 1363 | 
             
                    } else if (rb_obj_is_kind_of(arg1, cEC_GROUP)) {
         | 
| 1290 1364 | 
             
                        group_v = arg1;
         | 
| 1291 | 
            -
                         | 
| 1365 | 
            +
                        SafeGetECGroup(group_v, group);
         | 
| 1292 1366 |  | 
| 1293 1367 | 
             
                        point = EC_POINT_new(group);
         | 
| 1294 1368 | 
             
                    } else {
         | 
| @@ -1300,14 +1374,14 @@ static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self) | |
| 1300 1374 | 
             
                    if (!rb_obj_is_kind_of(arg1, cEC_GROUP))
         | 
| 1301 1375 | 
             
                        ossl_raise(rb_eArgError, "1st argument must be OpenSSL::PKey::EC::Group");
         | 
| 1302 1376 | 
             
                    group_v = arg1;
         | 
| 1303 | 
            -
                     | 
| 1377 | 
            +
                    SafeGetECGroup(group_v, group);
         | 
| 1304 1378 |  | 
| 1305 1379 | 
             
                    if (rb_obj_is_kind_of(arg2, cBN)) {
         | 
| 1306 1380 | 
             
                        const BIGNUM *bn = GetBNPtr(arg2);
         | 
| 1307 1381 |  | 
| 1308 1382 | 
             
                        point = EC_POINT_bn2point(group, bn, NULL, ossl_bn_ctx);
         | 
| 1309 1383 | 
             
                    } else {
         | 
| 1310 | 
            -
                        BIO *in = ossl_obj2bio(arg1);
         | 
| 1384 | 
            +
                        BIO *in = ossl_obj2bio(&arg1);
         | 
| 1311 1385 |  | 
| 1312 1386 | 
             
            /* BUG: finish me */
         | 
| 1313 1387 |  | 
| @@ -1328,32 +1402,54 @@ static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self) | |
| 1328 1402 | 
             
                if (NIL_P(group_v))
         | 
| 1329 1403 | 
             
                    ossl_raise(rb_eRuntimeError, "missing group (internal error)");
         | 
| 1330 1404 |  | 
| 1331 | 
            -
                 | 
| 1405 | 
            +
                RTYPEDDATA_DATA(self) = point;
         | 
| 1406 | 
            +
                rb_ivar_set(self, id_i_group, group_v);
         | 
| 1407 | 
            +
             | 
| 1408 | 
            +
                return self;
         | 
| 1409 | 
            +
            }
         | 
| 1410 | 
            +
             | 
| 1411 | 
            +
            static VALUE
         | 
| 1412 | 
            +
            ossl_ec_point_initialize_copy(VALUE self, VALUE other)
         | 
| 1413 | 
            +
            {
         | 
| 1414 | 
            +
                EC_POINT *point, *point_new;
         | 
| 1415 | 
            +
                EC_GROUP *group;
         | 
| 1416 | 
            +
                VALUE group_v;
         | 
| 1332 1417 |  | 
| 1333 | 
            -
                 | 
| 1418 | 
            +
                TypedData_Get_Struct(self, EC_POINT, &ossl_ec_point_type, point_new);
         | 
| 1419 | 
            +
                if (point_new)
         | 
| 1420 | 
            +
            	ossl_raise(eEC_POINT, "EC::Point already initialized");
         | 
| 1421 | 
            +
                SafeGetECPoint(other, point);
         | 
| 1422 | 
            +
             | 
| 1423 | 
            +
                group_v = rb_obj_dup(rb_attr_get(other, id_i_group));
         | 
| 1424 | 
            +
                SafeGetECGroup(group_v, group);
         | 
| 1425 | 
            +
             | 
| 1426 | 
            +
                point_new = EC_POINT_dup(point, group);
         | 
| 1427 | 
            +
                if (!point_new)
         | 
| 1428 | 
            +
            	ossl_raise(eEC_POINT, "EC_POINT_dup");
         | 
| 1429 | 
            +
                RTYPEDDATA_DATA(self) = point_new;
         | 
| 1430 | 
            +
                rb_ivar_set(self, id_i_group, group_v);
         | 
| 1334 1431 |  | 
| 1335 1432 | 
             
                return self;
         | 
| 1336 1433 | 
             
            }
         | 
| 1337 1434 |  | 
| 1338 1435 | 
             
            /*
         | 
| 1339 | 
            -
             * | 
| 1340 | 
            -
             * | 
| 1341 | 
            -
             * | 
| 1342 | 
            -
             *
         | 
| 1436 | 
            +
             * call-seq:
         | 
| 1437 | 
            +
             *   point1.eql?(point2) => true | false
         | 
| 1438 | 
            +
             *   point1 == point2 => true | false
         | 
| 1343 1439 | 
             
             */
         | 
| 1344 1440 | 
             
            static VALUE ossl_ec_point_eql(VALUE a, VALUE b)
         | 
| 1345 1441 | 
             
            {
         | 
| 1346 1442 | 
             
                EC_POINT *point1, *point2;
         | 
| 1347 | 
            -
                VALUE group_v1 =  | 
| 1348 | 
            -
                VALUE group_v2 =  | 
| 1443 | 
            +
                VALUE group_v1 = rb_attr_get(a, id_i_group);
         | 
| 1444 | 
            +
                VALUE group_v2 = rb_attr_get(b, id_i_group);
         | 
| 1349 1445 | 
             
                const EC_GROUP *group;
         | 
| 1350 1446 |  | 
| 1351 1447 | 
             
                if (ossl_ec_group_eql(group_v1, group_v2) == Qfalse)
         | 
| 1352 1448 | 
             
                    return Qfalse;
         | 
| 1353 1449 |  | 
| 1354 | 
            -
                 | 
| 1355 | 
            -
                 | 
| 1356 | 
            -
                 | 
| 1450 | 
            +
                GetECPoint(a, point1);
         | 
| 1451 | 
            +
                SafeGetECPoint(b, point2);
         | 
| 1452 | 
            +
                SafeGetECGroup(group_v1, group);
         | 
| 1357 1453 |  | 
| 1358 1454 | 
             
                if (EC_POINT_cmp(group, point1, point2, ossl_bn_ctx) == 1)
         | 
| 1359 1455 | 
             
                    return Qfalse;
         | 
| @@ -1362,18 +1458,16 @@ static VALUE ossl_ec_point_eql(VALUE a, VALUE b) | |
| 1362 1458 | 
             
            }
         | 
| 1363 1459 |  | 
| 1364 1460 | 
             
            /*
         | 
| 1365 | 
            -
             * | 
| 1366 | 
            -
             * | 
| 1367 | 
            -
             *
         | 
| 1461 | 
            +
             * call-seq:
         | 
| 1462 | 
            +
             *   point.infinity? => true | false
         | 
| 1368 1463 | 
             
             */
         | 
| 1369 1464 | 
             
            static VALUE ossl_ec_point_is_at_infinity(VALUE self)
         | 
| 1370 1465 | 
             
            {
         | 
| 1371 1466 | 
             
                EC_POINT *point;
         | 
| 1372 | 
            -
                VALUE group_v = rb_iv_get(self, "@group");
         | 
| 1373 1467 | 
             
                const EC_GROUP *group;
         | 
| 1374 1468 |  | 
| 1375 | 
            -
                 | 
| 1376 | 
            -
                 | 
| 1469 | 
            +
                GetECPoint(self, point);
         | 
| 1470 | 
            +
                GetECPointGroup(self, group);
         | 
| 1377 1471 |  | 
| 1378 1472 | 
             
                switch (EC_POINT_is_at_infinity(group, point)) {
         | 
| 1379 1473 | 
             
                case 1: return Qtrue;
         | 
| @@ -1385,18 +1479,16 @@ static VALUE ossl_ec_point_is_at_infinity(VALUE self) | |
| 1385 1479 | 
             
            }
         | 
| 1386 1480 |  | 
| 1387 1481 | 
             
            /*
         | 
| 1388 | 
            -
             * | 
| 1389 | 
            -
             * | 
| 1390 | 
            -
             *
         | 
| 1482 | 
            +
             * call-seq:
         | 
| 1483 | 
            +
             *   point.on_curve? => true | false
         | 
| 1391 1484 | 
             
             */
         | 
| 1392 1485 | 
             
            static VALUE ossl_ec_point_is_on_curve(VALUE self)
         | 
| 1393 1486 | 
             
            {
         | 
| 1394 1487 | 
             
                EC_POINT *point;
         | 
| 1395 | 
            -
                VALUE group_v = rb_iv_get(self, "@group");
         | 
| 1396 1488 | 
             
                const EC_GROUP *group;
         | 
| 1397 1489 |  | 
| 1398 | 
            -
                 | 
| 1399 | 
            -
                 | 
| 1490 | 
            +
                GetECPoint(self, point);
         | 
| 1491 | 
            +
                GetECPointGroup(self, group);
         | 
| 1400 1492 |  | 
| 1401 1493 | 
             
                switch (EC_POINT_is_on_curve(group, point, ossl_bn_ctx)) {
         | 
| 1402 1494 | 
             
                case 1: return Qtrue;
         | 
| @@ -1408,18 +1500,16 @@ static VALUE ossl_ec_point_is_on_curve(VALUE self) | |
| 1408 1500 | 
             
            }
         | 
| 1409 1501 |  | 
| 1410 1502 | 
             
            /*
         | 
| 1411 | 
            -
             * | 
| 1412 | 
            -
             * | 
| 1413 | 
            -
             *
         | 
| 1503 | 
            +
             * call-seq:
         | 
| 1504 | 
            +
             *   point.make_affine! => self
         | 
| 1414 1505 | 
             
             */
         | 
| 1415 1506 | 
             
            static VALUE ossl_ec_point_make_affine(VALUE self)
         | 
| 1416 1507 | 
             
            {
         | 
| 1417 1508 | 
             
                EC_POINT *point;
         | 
| 1418 | 
            -
                VALUE group_v = rb_iv_get(self, "@group");
         | 
| 1419 1509 | 
             
                const EC_GROUP *group;
         | 
| 1420 1510 |  | 
| 1421 | 
            -
                 | 
| 1422 | 
            -
                 | 
| 1511 | 
            +
                GetECPoint(self, point);
         | 
| 1512 | 
            +
                GetECPointGroup(self, group);
         | 
| 1423 1513 |  | 
| 1424 1514 | 
             
                if (EC_POINT_make_affine(group, point, ossl_bn_ctx) != 1)
         | 
| 1425 1515 | 
             
                    ossl_raise(cEC_POINT, "EC_POINT_make_affine");
         | 
| @@ -1428,18 +1518,16 @@ static VALUE ossl_ec_point_make_affine(VALUE self) | |
| 1428 1518 | 
             
            }
         | 
| 1429 1519 |  | 
| 1430 1520 | 
             
            /*
         | 
| 1431 | 
            -
             * | 
| 1432 | 
            -
             * | 
| 1433 | 
            -
             *
         | 
| 1521 | 
            +
             * call-seq:
         | 
| 1522 | 
            +
             *   point.invert! => self
         | 
| 1434 1523 | 
             
             */
         | 
| 1435 1524 | 
             
            static VALUE ossl_ec_point_invert(VALUE self)
         | 
| 1436 1525 | 
             
            {
         | 
| 1437 1526 | 
             
                EC_POINT *point;
         | 
| 1438 | 
            -
                VALUE group_v = rb_iv_get(self, "@group");
         | 
| 1439 1527 | 
             
                const EC_GROUP *group;
         | 
| 1440 1528 |  | 
| 1441 | 
            -
                 | 
| 1442 | 
            -
                 | 
| 1529 | 
            +
                GetECPoint(self, point);
         | 
| 1530 | 
            +
                GetECPointGroup(self, group);
         | 
| 1443 1531 |  | 
| 1444 1532 | 
             
                if (EC_POINT_invert(group, point, ossl_bn_ctx) != 1)
         | 
| 1445 1533 | 
             
                    ossl_raise(cEC_POINT, "EC_POINT_invert");
         | 
| @@ -1448,18 +1536,16 @@ static VALUE ossl_ec_point_invert(VALUE self) | |
| 1448 1536 | 
             
            }
         | 
| 1449 1537 |  | 
| 1450 1538 | 
             
            /*
         | 
| 1451 | 
            -
             * | 
| 1452 | 
            -
             * | 
| 1453 | 
            -
             *
         | 
| 1539 | 
            +
             * call-seq:
         | 
| 1540 | 
            +
             *   point.set_to_infinity! => self
         | 
| 1454 1541 | 
             
             */
         | 
| 1455 1542 | 
             
            static VALUE ossl_ec_point_set_to_infinity(VALUE self)
         | 
| 1456 1543 | 
             
            {
         | 
| 1457 1544 | 
             
                EC_POINT *point;
         | 
| 1458 | 
            -
                VALUE group_v = rb_iv_get(self, "@group");
         | 
| 1459 1545 | 
             
                const EC_GROUP *group;
         | 
| 1460 1546 |  | 
| 1461 | 
            -
                 | 
| 1462 | 
            -
                 | 
| 1547 | 
            +
                GetECPoint(self, point);
         | 
| 1548 | 
            +
                GetECPointGroup(self, group);
         | 
| 1463 1549 |  | 
| 1464 1550 | 
             
                if (EC_POINT_set_to_infinity(group, point) != 1)
         | 
| 1465 1551 | 
             
                    ossl_raise(cEC_POINT, "EC_POINT_set_to_infinity");
         | 
| @@ -1468,24 +1554,31 @@ static VALUE ossl_ec_point_set_to_infinity(VALUE self) | |
| 1468 1554 | 
             
            }
         | 
| 1469 1555 |  | 
| 1470 1556 | 
             
            /*
         | 
| 1471 | 
            -
             * | 
| 1472 | 
            -
             * | 
| 1557 | 
            +
             * call-seq:
         | 
| 1558 | 
            +
             *   point.to_bn(conversion_form = nil) => OpenSSL::BN
         | 
| 1473 1559 | 
             
             *
         | 
| 1474 | 
            -
             * | 
| 1560 | 
            +
             * Convert the EC point into an octet string and store in an OpenSSL::BN. If
         | 
| 1561 | 
            +
             * +conversion_form+ is given, the point data is converted using the specified
         | 
| 1562 | 
            +
             * form. If not given, the default form set in the EC::Group object is used.
         | 
| 1563 | 
            +
             *
         | 
| 1564 | 
            +
             * See also EC::Point#point_conversion_form=.
         | 
| 1475 1565 | 
             
             */
         | 
| 1476 | 
            -
            static VALUE | 
| 1566 | 
            +
            static VALUE
         | 
| 1567 | 
            +
            ossl_ec_point_to_bn(int argc, VALUE *argv, VALUE self)
         | 
| 1477 1568 | 
             
            {
         | 
| 1478 1569 | 
             
                EC_POINT *point;
         | 
| 1479 | 
            -
                VALUE bn_obj;
         | 
| 1480 | 
            -
                VALUE group_v = rb_iv_get(self, "@group");
         | 
| 1570 | 
            +
                VALUE form_obj, bn_obj;
         | 
| 1481 1571 | 
             
                const EC_GROUP *group;
         | 
| 1482 1572 | 
             
                point_conversion_form_t form;
         | 
| 1483 1573 | 
             
                BIGNUM *bn;
         | 
| 1484 1574 |  | 
| 1485 | 
            -
                 | 
| 1486 | 
            -
                 | 
| 1487 | 
            -
             | 
| 1488 | 
            -
                 | 
| 1575 | 
            +
                GetECPoint(self, point);
         | 
| 1576 | 
            +
                GetECPointGroup(self, group);
         | 
| 1577 | 
            +
                rb_scan_args(argc, argv, "01", &form_obj);
         | 
| 1578 | 
            +
                if (NIL_P(form_obj))
         | 
| 1579 | 
            +
            	form = EC_GROUP_get_point_conversion_form(group);
         | 
| 1580 | 
            +
                else
         | 
| 1581 | 
            +
            	form = parse_point_conversion_form_symbol(form_obj);
         | 
| 1489 1582 |  | 
| 1490 1583 | 
             
                bn_obj = rb_obj_alloc(cBN);
         | 
| 1491 1584 | 
             
                bn = GetBNPtr(bn_obj);
         | 
| @@ -1497,94 +1590,117 @@ static VALUE ossl_ec_point_to_bn(VALUE self) | |
| 1497 1590 | 
             
            }
         | 
| 1498 1591 |  | 
| 1499 1592 | 
             
            /*
         | 
| 1500 | 
            -
             * | 
| 1501 | 
            -
             * | 
| 1502 | 
            -
             * | 
| 1503 | 
            -
             * | 
| 1504 | 
            -
             * | 
| 1593 | 
            +
             * call-seq:
         | 
| 1594 | 
            +
             *   point.mul(bn1 [, bn2]) => point
         | 
| 1595 | 
            +
             *   point.mul(bns, points [, bn2]) => point
         | 
| 1596 | 
            +
             *
         | 
| 1597 | 
            +
             * Performs elliptic curve point multiplication.
         | 
| 1598 | 
            +
             *
         | 
| 1599 | 
            +
             * The first form calculates <tt>bn1 * point + bn2 * G</tt>, where +G+ is the
         | 
| 1600 | 
            +
             * generator of the group of +point+. +bn2+ may be omitted, and in that case,
         | 
| 1601 | 
            +
             * the result is just <tt>bn1 * point</tt>.
         | 
| 1602 | 
            +
             *
         | 
| 1603 | 
            +
             * The second form calculates <tt>bns[0] * point + bns[1] * points[0] + ...
         | 
| 1604 | 
            +
             * + bns[-1] * points[-1] + bn2 * G</tt>. +bn2+ may be omitted. +bns+ must be
         | 
| 1605 | 
            +
             * an array of OpenSSL::BN. +points+ must be an array of
         | 
| 1606 | 
            +
             * OpenSSL::PKey::EC::Point. Please note that <tt>points[0]</tt> is not
         | 
| 1607 | 
            +
             * multiplied by <tt>bns[0]</tt>, but <tt>bns[1]</tt>.
         | 
| 1505 1608 | 
             
             */
         | 
| 1506 1609 | 
             
            static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self)
         | 
| 1507 1610 | 
             
            {
         | 
| 1508 | 
            -
                EC_POINT * | 
| 1611 | 
            +
                EC_POINT *point_self, *point_result;
         | 
| 1509 1612 | 
             
                const EC_GROUP *group;
         | 
| 1510 | 
            -
                VALUE group_v =  | 
| 1511 | 
            -
                VALUE  | 
| 1512 | 
            -
                BIGNUM * | 
| 1613 | 
            +
                VALUE group_v = rb_attr_get(self, id_i_group);
         | 
| 1614 | 
            +
                VALUE arg1, arg2, arg3, result;
         | 
| 1615 | 
            +
                const BIGNUM *bn_g = NULL;
         | 
| 1513 1616 |  | 
| 1514 | 
            -
                 | 
| 1515 | 
            -
                 | 
| 1617 | 
            +
                GetECPoint(self, point_self);
         | 
| 1618 | 
            +
                SafeGetECGroup(group_v, group);
         | 
| 1516 1619 |  | 
| 1517 | 
            -
                 | 
| 1518 | 
            -
                ossl_ec_point_initialize(1, &group_v,  | 
| 1519 | 
            -
                 | 
| 1620 | 
            +
                result = rb_obj_alloc(cEC_POINT);
         | 
| 1621 | 
            +
                ossl_ec_point_initialize(1, &group_v, result);
         | 
| 1622 | 
            +
                GetECPoint(result, point_result);
         | 
| 1520 1623 |  | 
| 1521 | 
            -
                 | 
| 1624 | 
            +
                rb_scan_args(argc, argv, "12", &arg1, &arg2, &arg3);
         | 
| 1625 | 
            +
                if (!RB_TYPE_P(arg1, T_ARRAY)) {
         | 
| 1626 | 
            +
            	BIGNUM *bn = GetBNPtr(arg1);
         | 
| 1522 1627 |  | 
| 1523 | 
            -
             | 
| 1524 | 
            -
             | 
| 1525 | 
            -
             | 
| 1526 | 
            -
             | 
| 1527 | 
            -
                    }
         | 
| 1528 | 
            -
                    if (EC_POINT_mul(group, point2, bn2, point1, bn1, ossl_bn_ctx) != 1)
         | 
| 1529 | 
            -
                        ossl_raise(eEC_POINT, "Multiplication failed");
         | 
| 1628 | 
            +
            	if (!NIL_P(arg2))
         | 
| 1629 | 
            +
            	    bn_g = GetBNPtr(arg2);
         | 
| 1630 | 
            +
            	if (EC_POINT_mul(group, point_result, bn_g, point_self, bn, ossl_bn_ctx) != 1)
         | 
| 1631 | 
            +
            	    ossl_raise(eEC_POINT, NULL);
         | 
| 1530 1632 | 
             
                } else {
         | 
| 1531 | 
            -
             | 
| 1532 | 
            -
             | 
| 1533 | 
            -
             | 
| 1534 | 
            -
             | 
| 1535 | 
            -
             | 
| 1536 | 
            -
             | 
| 1537 | 
            -
             | 
| 1538 | 
            -
             | 
| 1539 | 
            -
             | 
| 1540 | 
            -
             | 
| 1541 | 
            -
             | 
| 1633 | 
            +
            	/*
         | 
| 1634 | 
            +
            	 * bignums | arg1[0] | arg1[1] | arg1[2] | ...
         | 
| 1635 | 
            +
            	 * points  | self    | arg2[0] | arg2[1] | ...
         | 
| 1636 | 
            +
            	 */
         | 
| 1637 | 
            +
            	long i, num;
         | 
| 1638 | 
            +
            	VALUE bns_tmp, tmp_p, tmp_b;
         | 
| 1639 | 
            +
            	const EC_POINT **points;
         | 
| 1640 | 
            +
            	const BIGNUM **bignums;
         | 
| 1641 | 
            +
             | 
| 1642 | 
            +
            	Check_Type(arg1, T_ARRAY);
         | 
| 1643 | 
            +
            	Check_Type(arg2, T_ARRAY);
         | 
| 1644 | 
            +
            	if (RARRAY_LEN(arg1) != RARRAY_LEN(arg2) + 1) /* arg2 must be 1 larger */
         | 
| 1645 | 
            +
            	    ossl_raise(rb_eArgError, "bns must be 1 longer than points; see the documentation");
         | 
| 1646 | 
            +
             | 
| 1647 | 
            +
            	num = RARRAY_LEN(arg1);
         | 
| 1648 | 
            +
            	bns_tmp = rb_ary_tmp_new(num);
         | 
| 1649 | 
            +
            	bignums = ALLOCV_N(const BIGNUM *, tmp_b, num);
         | 
| 1650 | 
            +
            	for (i = 0; i < num; i++) {
         | 
| 1651 | 
            +
            	    VALUE item = RARRAY_AREF(arg1, i);
         | 
| 1652 | 
            +
            	    bignums[i] = GetBNPtr(item);
         | 
| 1653 | 
            +
            	    rb_ary_push(bns_tmp, item);
         | 
| 1654 | 
            +
            	}
         | 
| 1542 1655 |  | 
| 1543 | 
            -
             | 
| 1544 | 
            -
             | 
| 1545 | 
            -
             | 
| 1546 | 
            -
             | 
| 1656 | 
            +
            	points = ALLOCV_N(const EC_POINT *, tmp_p, num);
         | 
| 1657 | 
            +
            	points[0] = point_self; /* self */
         | 
| 1658 | 
            +
            	for (i = 0; i < num - 1; i++)
         | 
| 1659 | 
            +
            	    SafeGetECPoint(RARRAY_AREF(arg2, i), points[i + 1]);
         | 
| 1547 1660 |  | 
| 1548 | 
            -
             | 
| 1549 | 
            -
             | 
| 1550 | 
            -
                    points = (const EC_POINT **)OPENSSL_malloc(points_len * (int)sizeof(EC_POINT *));
         | 
| 1661 | 
            +
            	if (!NIL_P(arg3))
         | 
| 1662 | 
            +
            	    bn_g = GetBNPtr(arg3);
         | 
| 1551 1663 |  | 
| 1552 | 
            -
             | 
| 1553 | 
            -
             | 
| 1554 | 
            -
             | 
| 1664 | 
            +
            	if (EC_POINTs_mul(group, point_result, bn_g, num, points, bignums, ossl_bn_ctx) != 1) {
         | 
| 1665 | 
            +
            	    ALLOCV_END(tmp_b);
         | 
| 1666 | 
            +
            	    ALLOCV_END(tmp_p);
         | 
| 1667 | 
            +
            	    ossl_raise(eEC_POINT, NULL);
         | 
| 1668 | 
            +
            	}
         | 
| 1555 1669 |  | 
| 1556 | 
            -
             | 
| 1557 | 
            -
             | 
| 1558 | 
            -
                    }
         | 
| 1559 | 
            -
                    if (EC_POINTs_mul(group, point2, bn2, points_len, points, bignums, ossl_bn_ctx) != 1) {
         | 
| 1560 | 
            -
                        OPENSSL_free((void *)bignums);
         | 
| 1561 | 
            -
                        OPENSSL_free((void *)points);
         | 
| 1562 | 
            -
                        ossl_raise(eEC_POINT, "Multiplication failed");
         | 
| 1563 | 
            -
                    }
         | 
| 1564 | 
            -
                    OPENSSL_free((void *)bignums);
         | 
| 1565 | 
            -
                    OPENSSL_free((void *)points);
         | 
| 1670 | 
            +
            	ALLOCV_END(tmp_b);
         | 
| 1671 | 
            +
            	ALLOCV_END(tmp_p);
         | 
| 1566 1672 | 
             
                }
         | 
| 1567 1673 |  | 
| 1568 | 
            -
                return  | 
| 1569 | 
            -
            }
         | 
| 1570 | 
            -
             | 
| 1571 | 
            -
            static void no_copy(VALUE klass)
         | 
| 1572 | 
            -
            {
         | 
| 1573 | 
            -
                rb_undef_method(klass, "copy");
         | 
| 1574 | 
            -
                rb_undef_method(klass, "clone");
         | 
| 1575 | 
            -
                rb_undef_method(klass, "dup");
         | 
| 1576 | 
            -
                rb_undef_method(klass, "initialize_copy");
         | 
| 1674 | 
            +
                return result;
         | 
| 1577 1675 | 
             
            }
         | 
| 1578 1676 |  | 
| 1579 1677 | 
             
            void Init_ossl_ec(void)
         | 
| 1580 1678 | 
             
            {
         | 
| 1581 | 
            -
            # | 
| 1582 | 
            -
             | 
| 1679 | 
            +
            #undef rb_intern
         | 
| 1680 | 
            +
            #if 0
         | 
| 1583 1681 | 
             
                mPKey = rb_define_module_under(mOSSL, "PKey");
         | 
| 1682 | 
            +
                cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject);
         | 
| 1683 | 
            +
                eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
         | 
| 1684 | 
            +
                ePKeyError = rb_define_class_under(mPKey, "PKeyError", eOSSLError);
         | 
| 1584 1685 | 
             
            #endif
         | 
| 1585 1686 |  | 
| 1586 1687 | 
             
                eECError = rb_define_class_under(mPKey, "ECError", ePKeyError);
         | 
| 1587 1688 |  | 
| 1689 | 
            +
                /*
         | 
| 1690 | 
            +
                 * Document-class: OpenSSL::PKey::EC
         | 
| 1691 | 
            +
                 *
         | 
| 1692 | 
            +
                 * OpenSSL::PKey::EC provides access to Elliptic Curve Digital Signature
         | 
| 1693 | 
            +
                 * Algorithm (ECDSA) and Elliptic Curve Diffie-Hellman (ECDH).
         | 
| 1694 | 
            +
                 *
         | 
| 1695 | 
            +
                 * === Key exchange
         | 
| 1696 | 
            +
                 *   ec1 = OpenSSL::PKey::EC.generate("prime256v1")
         | 
| 1697 | 
            +
                 *   ec2 = OpenSSL::PKey::EC.generate("prime256v1")
         | 
| 1698 | 
            +
                 *   # ec1 and ec2 have own private key respectively
         | 
| 1699 | 
            +
                 *   shared_key1 = ec1.dh_compute_key(ec2.public_key)
         | 
| 1700 | 
            +
                 *   shared_key2 = ec2.dh_compute_key(ec1.public_key)
         | 
| 1701 | 
            +
                 *
         | 
| 1702 | 
            +
                 *   p shared_key1 == shared_key2 #=> true
         | 
| 1703 | 
            +
                 */
         | 
| 1588 1704 | 
             
                cEC = rb_define_class_under(mPKey, "EC", cPKey);
         | 
| 1589 1705 | 
             
                cEC_GROUP = rb_define_class_under(cEC, "Group", rb_cObject);
         | 
| 1590 1706 | 
             
                cEC_POINT = rb_define_class_under(cEC, "Point", rb_cObject);
         | 
| @@ -1602,13 +1718,16 @@ void Init_ossl_ec(void) | |
| 1602 1718 | 
             
                ID_compressed = rb_intern("compressed");
         | 
| 1603 1719 | 
             
                ID_hybrid = rb_intern("hybrid");
         | 
| 1604 1720 |  | 
| 1605 | 
            -
             | 
| 1606 | 
            -
             | 
| 1721 | 
            +
                rb_define_const(cEC, "NAMED_CURVE", INT2NUM(OPENSSL_EC_NAMED_CURVE));
         | 
| 1722 | 
            +
            #if defined(OPENSSL_EC_EXPLICIT_CURVE)
         | 
| 1723 | 
            +
                rb_define_const(cEC, "EXPLICIT_CURVE", INT2NUM(OPENSSL_EC_EXPLICIT_CURVE));
         | 
| 1607 1724 | 
             
            #endif
         | 
| 1608 1725 |  | 
| 1609 1726 | 
             
                rb_define_singleton_method(cEC, "builtin_curves", ossl_s_builtin_curves, 0);
         | 
| 1610 1727 |  | 
| 1728 | 
            +
                rb_define_singleton_method(cEC, "generate", ossl_ec_key_s_generate, 1);
         | 
| 1611 1729 | 
             
                rb_define_method(cEC, "initialize", ossl_ec_key_initialize, -1);
         | 
| 1730 | 
            +
                rb_define_copy_func(cEC, ossl_ec_key_initialize_copy);
         | 
| 1612 1731 | 
             
            /* copy/dup/cmp */
         | 
| 1613 1732 |  | 
| 1614 1733 | 
             
                rb_define_method(cEC, "group", ossl_ec_key_get_group, 0);
         | 
| @@ -1617,8 +1736,10 @@ void Init_ossl_ec(void) | |
| 1617 1736 | 
             
                rb_define_method(cEC, "private_key=", ossl_ec_key_set_private_key, 1);
         | 
| 1618 1737 | 
             
                rb_define_method(cEC, "public_key", ossl_ec_key_get_public_key, 0);
         | 
| 1619 1738 | 
             
                rb_define_method(cEC, "public_key=", ossl_ec_key_set_public_key, 1);
         | 
| 1620 | 
            -
                rb_define_method(cEC, " | 
| 1621 | 
            -
                rb_define_method(cEC, " | 
| 1739 | 
            +
                rb_define_method(cEC, "private?", ossl_ec_key_is_private, 0);
         | 
| 1740 | 
            +
                rb_define_method(cEC, "public?", ossl_ec_key_is_public, 0);
         | 
| 1741 | 
            +
                rb_define_alias(cEC, "private_key?", "private?");
         | 
| 1742 | 
            +
                rb_define_alias(cEC, "public_key?", "public?");
         | 
| 1622 1743 | 
             
            /*  rb_define_method(cEC, "", ossl_ec_key_get_, 0);
         | 
| 1623 1744 | 
             
                rb_define_method(cEC, "=", ossl_ec_key_set_ 1);
         | 
| 1624 1745 | 
             
                set/get enc_flags
         | 
| @@ -1626,7 +1747,8 @@ void Init_ossl_ec(void) | |
| 1626 1747 | 
             
                set/get asn1_flag (can use ruby to call self.group.asn1_flag)
         | 
| 1627 1748 | 
             
                set/get precompute_mult
         | 
| 1628 1749 | 
             
            */
         | 
| 1629 | 
            -
                rb_define_method(cEC, "generate_key", ossl_ec_key_generate_key, 0);
         | 
| 1750 | 
            +
                rb_define_method(cEC, "generate_key!", ossl_ec_key_generate_key, 0);
         | 
| 1751 | 
            +
                rb_define_alias(cEC, "generate_key", "generate_key!");
         | 
| 1630 1752 | 
             
                rb_define_method(cEC, "check_key", ossl_ec_key_check_key, 0);
         | 
| 1631 1753 |  | 
| 1632 1754 | 
             
                rb_define_method(cEC, "dh_compute_key", ossl_ec_key_dh_compute_key, 1);
         | 
| @@ -1642,6 +1764,7 @@ void Init_ossl_ec(void) | |
| 1642 1764 |  | 
| 1643 1765 | 
             
                rb_define_alloc_func(cEC_GROUP, ossl_ec_group_alloc);
         | 
| 1644 1766 | 
             
                rb_define_method(cEC_GROUP, "initialize", ossl_ec_group_initialize, -1);
         | 
| 1767 | 
            +
                rb_define_copy_func(cEC_GROUP, ossl_ec_group_initialize_copy);
         | 
| 1645 1768 | 
             
                rb_define_method(cEC_GROUP, "eql?", ossl_ec_group_eql, 1);
         | 
| 1646 1769 | 
             
                rb_define_alias(cEC_GROUP, "==", "eql?");
         | 
| 1647 1770 | 
             
            /* copy/dup/cmp */
         | 
| @@ -1677,6 +1800,7 @@ void Init_ossl_ec(void) | |
| 1677 1800 |  | 
| 1678 1801 | 
             
                rb_define_alloc_func(cEC_POINT, ossl_ec_point_alloc);
         | 
| 1679 1802 | 
             
                rb_define_method(cEC_POINT, "initialize", ossl_ec_point_initialize, -1);
         | 
| 1803 | 
            +
                rb_define_copy_func(cEC_POINT, ossl_ec_point_initialize_copy);
         | 
| 1680 1804 | 
             
                rb_attr(cEC_POINT, rb_intern("group"), 1, 0, 0);
         | 
| 1681 1805 | 
             
                rb_define_method(cEC_POINT, "eql?", ossl_ec_point_eql, 1);
         | 
| 1682 1806 | 
             
                rb_define_alias(cEC_POINT, "==", "eql?");
         | 
| @@ -1688,12 +1812,10 @@ void Init_ossl_ec(void) | |
| 1688 1812 | 
             
                rb_define_method(cEC_POINT, "set_to_infinity!", ossl_ec_point_set_to_infinity, 0);
         | 
| 1689 1813 | 
             
            /* all the other methods */
         | 
| 1690 1814 |  | 
| 1691 | 
            -
                rb_define_method(cEC_POINT, "to_bn", ossl_ec_point_to_bn,  | 
| 1815 | 
            +
                rb_define_method(cEC_POINT, "to_bn", ossl_ec_point_to_bn, -1);
         | 
| 1692 1816 | 
             
                rb_define_method(cEC_POINT, "mul", ossl_ec_point_mul, -1);
         | 
| 1693 1817 |  | 
| 1694 | 
            -
                 | 
| 1695 | 
            -
                no_copy(cEC_GROUP);
         | 
| 1696 | 
            -
                no_copy(cEC_POINT);
         | 
| 1818 | 
            +
                id_i_group = rb_intern("@group");
         | 
| 1697 1819 | 
             
            }
         | 
| 1698 1820 |  | 
| 1699 1821 | 
             
            #else /* defined NO_EC */
         |