/* * call-seq: * key.group = group => group * * Returns the same object passed, not the group object associated with the key. * If you wish to access the group object tied to the key call key.group after setting * the group. * * Setting the group will immediately destroy any previously assigned group object. * The group is internally copied by OpenSSL. Modifying the original group after * assignment will not effect the internal key structure. * (your changes may be lost). BE CAREFUL. * * EC_KEY_set_group calls EC_GROUP_free(key->group) then EC_GROUP_dup(), not EC_GROUP_copy. * This documentation is accurate for OpenSSL 0.9.8b. */ static VALUE ossl_ec_key_set_group(VALUE self, VALUE group_v) { VALUE old_group_v; EC_KEY *ec; EC_GROUP *group; Require_EC_KEY(self, ec); SafeRequire_EC_GROUP(group_v, group); old_group_v = rb_iv_get(self, "@group"); if (!NIL_P(old_group_v)) { ossl_ec_group *old_ec_group; SafeGet_ec_group(old_group_v, old_ec_group); old_ec_group->group = NULL; old_ec_group->dont_free = 0; rb_iv_set(old_group_v, "@key", Qnil); } rb_iv_set(self, "@group", Qnil); if (EC_KEY_set_group(ec, group) != 1) ossl_raise(eECError, "EC_KEY_set_group"); return group_v; }
/* * call-seq: * key.group => group * * Returns a constant <code>OpenSSL::EC::Group</code> that is tied to the key. * Modifying the returned group can make the key invalid. */ static VALUE ossl_ec_key_get_group(VALUE self) { VALUE group_v; EC_KEY *ec; ossl_ec_group *ec_group; EC_GROUP *group; Require_EC_KEY(self, ec); group_v = rb_iv_get(self, "@group"); if (!NIL_P(group_v)) return group_v; if ((group = (EC_GROUP *)EC_KEY_get0_group(ec)) != NULL) { group_v = rb_obj_alloc(cEC_GROUP); SafeGet_ec_group(group_v, ec_group); ec_group->group = group; ec_group->dont_free = 1; rb_iv_set(group_v, "@key", self); rb_iv_set(self, "@group", group_v); return group_v; } return Qnil; }
/* * call-seq: * key.private_key? => true or false * * Both public_key? and private_key? may return false at the same time unlike other PKey classes. */ static VALUE ossl_ec_key_is_private_key(VALUE self) { EC_KEY *ec; Require_EC_KEY(self, ec); return (EC_KEY_get0_private_key(ec) ? Qtrue : Qfalse); }
/* * call-seq: * key.public? => true or false * * Returns whether this EC instance has a public key. The public key * (EC::Point) can be retrieved with EC#public_key. */ static VALUE ossl_ec_key_is_public(VALUE self) { EC_KEY *ec; Require_EC_KEY(self, ec); return EC_KEY_get0_public_key(ec) ? Qtrue : Qfalse; }
static VALUE ossl_ec_key_to_string(VALUE self, int format) { EC_KEY *ec; BIO *out; int i = -1; int private = 0; #if 0 /* unused now */ EVP_CIPHER *cipher = NULL; char *password = NULL; #endif VALUE str; Require_EC_KEY(self, ec); if (EC_KEY_get0_public_key(ec) == NULL) rb_raise(eECError, "can't export - no public key set"); if (EC_KEY_check_key(ec) != 1) ossl_raise(eECError, "can't export - EC_KEY_check_key failed"); if (EC_KEY_get0_private_key(ec)) private = 1; if (!(out = BIO_new(BIO_s_mem()))) ossl_raise(eECError, "BIO_new(BIO_s_mem())"); switch(format) { case EXPORT_PEM: if (private) { #if 0 /* unused now */ if (cipher || password) /* BUG: finish cipher/password key export */ rb_notimplement(); i = PEM_write_bio_ECPrivateKey(out, ec, cipher, NULL, 0, NULL, password); #endif i = PEM_write_bio_ECPrivateKey(out, ec, NULL, NULL, 0, NULL, NULL); } else { #if 0 /* unused now */ if (cipher || password) rb_raise(rb_eArgError, "encryption is not supported when exporting this key type"); #endif i = PEM_write_bio_EC_PUBKEY(out, ec); } break; case EXPORT_DER: if (private) { #if 0 /* unused now */ if (cipher || password) rb_raise(rb_eArgError, "encryption is not supported when exporting this key type"); #endif i = i2d_ECPrivateKey_bio(out, ec); } else { #if 0 /* unused now */ if (cipher || password)
/* * call-seq: * key.private_key => OpenSSL::BN * * See the OpenSSL documentation for EC_KEY_get0_private_key() */ static VALUE ossl_ec_key_get_private_key(VALUE self) { EC_KEY *ec; const BIGNUM *bn; Require_EC_KEY(self, ec); if ((bn = EC_KEY_get0_private_key(ec)) == NULL) return Qnil; return ossl_bn_new(bn); }
static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int format) { EC_KEY *ec; BIO *out; int i = -1; int private = 0; char *password = NULL; VALUE str; Require_EC_KEY(self, ec); if (EC_KEY_get0_public_key(ec) == NULL) ossl_raise(eECError, "can't export - no public key set"); if (EC_KEY_check_key(ec) != 1) ossl_raise(eECError, "can't export - EC_KEY_check_key failed"); if (EC_KEY_get0_private_key(ec)) private = 1; if (!(out = BIO_new(BIO_s_mem()))) ossl_raise(eECError, "BIO_new(BIO_s_mem())"); switch(format) { case EXPORT_PEM: if (private) { const EVP_CIPHER *cipher; if (!NIL_P(ciph)) { cipher = GetCipherPtr(ciph); if (!NIL_P(pass)) { StringValue(pass); if (RSTRING_LENINT(pass) < OSSL_MIN_PWD_LEN) ossl_raise(eOSSLError, "OpenSSL requires passwords to be at least four characters long"); password = RSTRING_PTR(pass); } } else { cipher = NULL; } i = PEM_write_bio_ECPrivateKey(out, ec, cipher, NULL, 0, NULL, password); } else { i = PEM_write_bio_EC_PUBKEY(out, ec); } break; case EXPORT_DER: if (private) { i = i2d_ECPrivateKey_bio(out, ec); } else {
/* * call-seq: * key.public_key => OpenSSL::PKey::EC::Point * * See the OpenSSL documentation for EC_KEY_get0_public_key() */ static VALUE ossl_ec_key_get_public_key(VALUE self) { EC_KEY *ec; const EC_POINT *point; VALUE group; Require_EC_KEY(self, ec); if ((point = EC_KEY_get0_public_key(ec)) == NULL) return Qnil; group = rb_funcall(self, rb_intern("group"), 0); if (NIL_P(group)) ossl_raise(eECError, "EC_KEY_get0_get0_group (has public_key but no group???"); return ossl_ec_point_dup(point, group); }
/* * call-seq: * key.public_key = ec_point * * See the OpenSSL documentation for EC_KEY_set_public_key() */ static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key) { EC_KEY *ec; EC_POINT *point = NULL; Require_EC_KEY(self, ec); if (!NIL_P(public_key)) SafeRequire_EC_POINT(public_key, point); switch (EC_KEY_set_public_key(ec, point)) { case 1: break; case 0: if (point == NULL) break; default: ossl_raise(eECError, "EC_KEY_set_public_key"); } return public_key; }
/* * call-seq: * key.private_key = openssl_bn * * See the OpenSSL documentation for EC_KEY_set_private_key() */ static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key) { EC_KEY *ec; BIGNUM *bn = NULL; Require_EC_KEY(self, ec); if (!NIL_P(private_key)) bn = GetBNPtr(private_key); switch (EC_KEY_set_private_key(ec, bn)) { case 1: break; case 0: if (bn == NULL) break; default: ossl_raise(eECError, "EC_KEY_set_private_key"); } return private_key; }
static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int format) { EC_KEY *ec; BIO *out; int i = -1; int private = 0; VALUE str; Require_EC_KEY(self, ec); if (EC_KEY_get0_public_key(ec) == NULL) ossl_raise(eECError, "can't export - no public key set"); if (EC_KEY_check_key(ec) != 1) ossl_raise(eECError, "can't export - EC_KEY_check_key failed"); if (EC_KEY_get0_private_key(ec)) private = 1; if (!(out = BIO_new(BIO_s_mem()))) ossl_raise(eECError, "BIO_new(BIO_s_mem())"); switch(format) { case EXPORT_PEM: if (private) { const EVP_CIPHER *cipher = NULL; if (!NIL_P(ciph)) { cipher = GetCipherPtr(ciph); pass = ossl_pem_passwd_value(pass); } i = PEM_write_bio_ECPrivateKey(out, ec, cipher, NULL, 0, ossl_pem_passwd_cb, (void *)pass); } else { i = PEM_write_bio_EC_PUBKEY(out, ec); } break; case EXPORT_DER: if (private) { i = i2d_ECPrivateKey_bio(out, ec); } else {