mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
[ruby/openssl] pkey: allocate EVP_PKEY on #initialize
Allocate an EVP_PKEY when the content is ready: when #initialize or #initialize_copy is called, rather than when a T_DATA is allocated. This is more natural because the lower level API has been deprecated and an EVP_PKEY is becoming the minimum unit of handling keys. https://github.com/ruby/openssl/commit/74f6c61756
This commit is contained in:
parent
02a58fbfd1
commit
c1a36ebfda
6 changed files with 222 additions and 167 deletions
|
@ -55,8 +55,8 @@ pkey_new0(VALUE arg)
|
||||||
#endif
|
#endif
|
||||||
default: klass = cPKey; break;
|
default: klass = cPKey; break;
|
||||||
}
|
}
|
||||||
obj = NewPKey(klass);
|
obj = rb_obj_alloc(klass);
|
||||||
SetPKey(obj, pkey);
|
RTYPEDDATA_DATA(obj) = pkey;
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,16 +512,7 @@ DupPKeyPtr(VALUE obj)
|
||||||
static VALUE
|
static VALUE
|
||||||
ossl_pkey_alloc(VALUE klass)
|
ossl_pkey_alloc(VALUE klass)
|
||||||
{
|
{
|
||||||
EVP_PKEY *pkey;
|
return TypedData_Wrap_Struct(klass, &ossl_evp_pkey_type, NULL);
|
||||||
VALUE obj;
|
|
||||||
|
|
||||||
obj = NewPKey(klass);
|
|
||||||
if (!(pkey = EVP_PKEY_new())) {
|
|
||||||
ossl_raise(ePKeyError, NULL);
|
|
||||||
}
|
|
||||||
SetPKey(obj, pkey);
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -15,19 +15,10 @@ extern VALUE cPKey;
|
||||||
extern VALUE ePKeyError;
|
extern VALUE ePKeyError;
|
||||||
extern const rb_data_type_t ossl_evp_pkey_type;
|
extern const rb_data_type_t ossl_evp_pkey_type;
|
||||||
|
|
||||||
#define OSSL_PKEY_SET_PRIVATE(obj) rb_iv_set((obj), "private", Qtrue)
|
/* For ENGINE */
|
||||||
#define OSSL_PKEY_SET_PUBLIC(obj) rb_iv_set((obj), "private", Qfalse)
|
#define OSSL_PKEY_SET_PRIVATE(obj) rb_ivar_set((obj), rb_intern("private"), Qtrue)
|
||||||
#define OSSL_PKEY_IS_PRIVATE(obj) (rb_iv_get((obj), "private") == Qtrue)
|
#define OSSL_PKEY_IS_PRIVATE(obj) (rb_attr_get((obj), rb_intern("private")) == Qtrue)
|
||||||
|
|
||||||
#define NewPKey(klass) \
|
|
||||||
TypedData_Wrap_Struct((klass), &ossl_evp_pkey_type, 0)
|
|
||||||
#define SetPKey(obj, pkey) do { \
|
|
||||||
if (!(pkey)) { \
|
|
||||||
rb_raise(rb_eRuntimeError, "PKEY wasn't initialized!"); \
|
|
||||||
} \
|
|
||||||
RTYPEDDATA_DATA(obj) = (pkey); \
|
|
||||||
OSSL_PKEY_SET_PUBLIC(obj); \
|
|
||||||
} while (0)
|
|
||||||
#define GetPKey(obj, pkey) do {\
|
#define GetPKey(obj, pkey) do {\
|
||||||
TypedData_Get_Struct((obj), EVP_PKEY, &ossl_evp_pkey_type, (pkey)); \
|
TypedData_Get_Struct((obj), EVP_PKEY, &ossl_evp_pkey_type, (pkey)); \
|
||||||
if (!(pkey)) { \
|
if (!(pkey)) { \
|
||||||
|
|
|
@ -72,34 +72,57 @@ static VALUE
|
||||||
ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
|
ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
|
||||||
{
|
{
|
||||||
EVP_PKEY *pkey;
|
EVP_PKEY *pkey;
|
||||||
|
int type;
|
||||||
DH *dh;
|
DH *dh;
|
||||||
BIO *in;
|
BIO *in = NULL;
|
||||||
VALUE arg;
|
VALUE arg;
|
||||||
|
|
||||||
GetPKey(self, pkey);
|
TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
|
||||||
|
if (pkey)
|
||||||
|
rb_raise(rb_eTypeError, "pkey already initialized");
|
||||||
|
|
||||||
/* The DH.new(size, generator) form is handled by lib/openssl/pkey.rb */
|
/* The DH.new(size, generator) form is handled by lib/openssl/pkey.rb */
|
||||||
if (rb_scan_args(argc, argv, "01", &arg) == 0) {
|
if (rb_scan_args(argc, argv, "01", &arg) == 0) {
|
||||||
dh = DH_new();
|
dh = DH_new();
|
||||||
if (!dh)
|
if (!dh)
|
||||||
ossl_raise(eDHError, "DH_new");
|
ossl_raise(eDHError, "DH_new");
|
||||||
|
goto legacy;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
arg = ossl_to_der_if_possible(arg);
|
arg = ossl_to_der_if_possible(arg);
|
||||||
in = ossl_obj2bio(&arg);
|
in = ossl_obj2bio(&arg);
|
||||||
dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
|
|
||||||
if (!dh){
|
/*
|
||||||
OSSL_BIO_reset(in);
|
* On OpenSSL <= 1.1.1 and current versions of LibreSSL, the generic
|
||||||
|
* routine does not support DER-encoded parameters
|
||||||
|
*/
|
||||||
dh = d2i_DHparams_bio(in, NULL);
|
dh = d2i_DHparams_bio(in, NULL);
|
||||||
}
|
if (dh)
|
||||||
|
goto legacy;
|
||||||
|
OSSL_BIO_reset(in);
|
||||||
|
|
||||||
|
pkey = ossl_pkey_read_generic(in, Qnil);
|
||||||
BIO_free(in);
|
BIO_free(in);
|
||||||
if (!dh) {
|
if (!pkey)
|
||||||
ossl_raise(eDHError, NULL);
|
ossl_raise(eDHError, "could not parse pkey");
|
||||||
|
|
||||||
|
type = EVP_PKEY_base_id(pkey);
|
||||||
|
if (type != EVP_PKEY_DH) {
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
|
rb_raise(eDHError, "incorrect pkey type: %s", OBJ_nid2sn(type));
|
||||||
}
|
}
|
||||||
}
|
RTYPEDDATA_DATA(self) = pkey;
|
||||||
if (!EVP_PKEY_assign_DH(pkey, dh)) {
|
return self;
|
||||||
|
|
||||||
|
legacy:
|
||||||
|
BIO_free(in);
|
||||||
|
pkey = EVP_PKEY_new();
|
||||||
|
if (!pkey || EVP_PKEY_assign_DH(pkey, dh) != 1) {
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
DH_free(dh);
|
DH_free(dh);
|
||||||
ossl_raise(eDHError, NULL);
|
ossl_raise(eDHError, "EVP_PKEY_assign_DH");
|
||||||
}
|
}
|
||||||
|
RTYPEDDATA_DATA(self) = pkey;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,15 +133,14 @@ ossl_dh_initialize_copy(VALUE self, VALUE other)
|
||||||
DH *dh, *dh_other;
|
DH *dh, *dh_other;
|
||||||
const BIGNUM *pub, *priv;
|
const BIGNUM *pub, *priv;
|
||||||
|
|
||||||
GetPKey(self, pkey);
|
TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
|
||||||
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
|
if (pkey)
|
||||||
ossl_raise(eDHError, "DH already initialized");
|
rb_raise(rb_eTypeError, "pkey already initialized");
|
||||||
GetDH(other, dh_other);
|
GetDH(other, dh_other);
|
||||||
|
|
||||||
dh = DHparams_dup(dh_other);
|
dh = DHparams_dup(dh_other);
|
||||||
if (!dh)
|
if (!dh)
|
||||||
ossl_raise(eDHError, "DHparams_dup");
|
ossl_raise(eDHError, "DHparams_dup");
|
||||||
EVP_PKEY_assign_DH(pkey, dh);
|
|
||||||
|
|
||||||
DH_get0_key(dh_other, &pub, &priv);
|
DH_get0_key(dh_other, &pub, &priv);
|
||||||
if (pub) {
|
if (pub) {
|
||||||
|
@ -133,6 +155,13 @@ ossl_dh_initialize_copy(VALUE self, VALUE other)
|
||||||
DH_set0_key(dh, pub2, priv2);
|
DH_set0_key(dh, pub2, priv2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pkey = EVP_PKEY_new();
|
||||||
|
if (!pkey || EVP_PKEY_assign_DH(pkey, dh) != 1) {
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
|
DH_free(dh);
|
||||||
|
ossl_raise(eDHError, "EVP_PKEY_assign_DH");
|
||||||
|
}
|
||||||
|
RTYPEDDATA_DATA(self) = pkey;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,50 +83,59 @@ VALUE eDSAError;
|
||||||
static VALUE
|
static VALUE
|
||||||
ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
|
ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
|
||||||
{
|
{
|
||||||
EVP_PKEY *pkey, *tmp;
|
EVP_PKEY *pkey;
|
||||||
DSA *dsa = NULL;
|
DSA *dsa;
|
||||||
BIO *in;
|
BIO *in = NULL;
|
||||||
VALUE arg, pass;
|
VALUE arg, pass;
|
||||||
|
int type;
|
||||||
|
|
||||||
|
TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
|
||||||
|
if (pkey)
|
||||||
|
rb_raise(rb_eTypeError, "pkey already initialized");
|
||||||
|
|
||||||
GetPKey(self, pkey);
|
|
||||||
/* The DSA.new(size, generator) form is handled by lib/openssl/pkey.rb */
|
/* The DSA.new(size, generator) form is handled by lib/openssl/pkey.rb */
|
||||||
rb_scan_args(argc, argv, "02", &arg, &pass);
|
rb_scan_args(argc, argv, "02", &arg, &pass);
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
dsa = DSA_new();
|
dsa = DSA_new();
|
||||||
if (!dsa)
|
if (!dsa)
|
||||||
ossl_raise(eDSAError, "DSA_new");
|
ossl_raise(eDSAError, "DSA_new");
|
||||||
|
goto legacy;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
pass = ossl_pem_passwd_value(pass);
|
pass = ossl_pem_passwd_value(pass);
|
||||||
arg = ossl_to_der_if_possible(arg);
|
arg = ossl_to_der_if_possible(arg);
|
||||||
in = ossl_obj2bio(&arg);
|
in = ossl_obj2bio(&arg);
|
||||||
|
|
||||||
tmp = ossl_pkey_read_generic(in, pass);
|
/* DER-encoded DSAPublicKey format isn't supported by the generic routine */
|
||||||
if (tmp) {
|
dsa = (DSA *)PEM_ASN1_read_bio((d2i_of_void *)d2i_DSAPublicKey,
|
||||||
if (EVP_PKEY_base_id(tmp) != EVP_PKEY_DSA)
|
PEM_STRING_DSA_PUBLIC,
|
||||||
rb_raise(eDSAError, "incorrect pkey type: %s",
|
in, NULL, NULL, NULL);
|
||||||
OBJ_nid2sn(EVP_PKEY_base_id(tmp)));
|
if (dsa)
|
||||||
dsa = EVP_PKEY_get1_DSA(tmp);
|
goto legacy;
|
||||||
EVP_PKEY_free(tmp);
|
|
||||||
}
|
|
||||||
if (!dsa) {
|
|
||||||
OSSL_BIO_reset(in);
|
OSSL_BIO_reset(in);
|
||||||
#define PEM_read_bio_DSAPublicKey(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \
|
|
||||||
(d2i_of_void *)d2i_DSAPublicKey, PEM_STRING_DSA_PUBLIC, (bp), (void **)(x), (cb), (u))
|
|
||||||
dsa = PEM_read_bio_DSAPublicKey(in, NULL, NULL, NULL);
|
|
||||||
#undef PEM_read_bio_DSAPublicKey
|
|
||||||
}
|
|
||||||
BIO_free(in);
|
|
||||||
if (!dsa) {
|
|
||||||
ossl_clear_error();
|
|
||||||
ossl_raise(eDSAError, "Neither PUB key nor PRIV key");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!EVP_PKEY_assign_DSA(pkey, dsa)) {
|
|
||||||
DSA_free(dsa);
|
|
||||||
ossl_raise(eDSAError, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
pkey = ossl_pkey_read_generic(in, pass);
|
||||||
|
BIO_free(in);
|
||||||
|
if (!pkey)
|
||||||
|
ossl_raise(eDSAError, "Neither PUB key nor PRIV key");
|
||||||
|
|
||||||
|
type = EVP_PKEY_base_id(pkey);
|
||||||
|
if (type != EVP_PKEY_DSA) {
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
|
rb_raise(eDSAError, "incorrect pkey type: %s", OBJ_nid2sn(type));
|
||||||
|
}
|
||||||
|
RTYPEDDATA_DATA(self) = pkey;
|
||||||
|
return self;
|
||||||
|
|
||||||
|
legacy:
|
||||||
|
BIO_free(in);
|
||||||
|
pkey = EVP_PKEY_new();
|
||||||
|
if (!pkey || EVP_PKEY_assign_DSA(pkey, dsa) != 1) {
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
|
DSA_free(dsa);
|
||||||
|
ossl_raise(eDSAError, "EVP_PKEY_assign_DSA");
|
||||||
|
}
|
||||||
|
RTYPEDDATA_DATA(self) = pkey;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,16 +145,24 @@ ossl_dsa_initialize_copy(VALUE self, VALUE other)
|
||||||
EVP_PKEY *pkey;
|
EVP_PKEY *pkey;
|
||||||
DSA *dsa, *dsa_new;
|
DSA *dsa, *dsa_new;
|
||||||
|
|
||||||
GetPKey(self, pkey);
|
TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
|
||||||
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
|
if (pkey)
|
||||||
ossl_raise(eDSAError, "DSA already initialized");
|
rb_raise(rb_eTypeError, "pkey already initialized");
|
||||||
GetDSA(other, dsa);
|
GetDSA(other, dsa);
|
||||||
|
|
||||||
dsa_new = ASN1_dup((i2d_of_void *)i2d_DSAPrivateKey, (d2i_of_void *)d2i_DSAPrivateKey, (char *)dsa);
|
dsa_new = (DSA *)ASN1_dup((i2d_of_void *)i2d_DSAPrivateKey,
|
||||||
|
(d2i_of_void *)d2i_DSAPrivateKey,
|
||||||
|
(char *)dsa);
|
||||||
if (!dsa_new)
|
if (!dsa_new)
|
||||||
ossl_raise(eDSAError, "ASN1_dup");
|
ossl_raise(eDSAError, "ASN1_dup");
|
||||||
|
|
||||||
EVP_PKEY_assign_DSA(pkey, dsa_new);
|
pkey = EVP_PKEY_new();
|
||||||
|
if (!pkey || EVP_PKEY_assign_DSA(pkey, dsa_new) != 1) {
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
|
DSA_free(dsa_new);
|
||||||
|
ossl_raise(eDSAError, "EVP_PKEY_assign_DSA");
|
||||||
|
}
|
||||||
|
RTYPEDDATA_DATA(self) = pkey;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,13 +109,16 @@ ossl_ec_key_s_generate(VALUE klass, VALUE arg)
|
||||||
VALUE obj;
|
VALUE obj;
|
||||||
|
|
||||||
obj = rb_obj_alloc(klass);
|
obj = rb_obj_alloc(klass);
|
||||||
GetPKey(obj, pkey);
|
|
||||||
|
|
||||||
ec = ec_key_new_from_group(arg);
|
ec = ec_key_new_from_group(arg);
|
||||||
if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) {
|
pkey = EVP_PKEY_new();
|
||||||
|
if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec) != 1) {
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
EC_KEY_free(ec);
|
EC_KEY_free(ec);
|
||||||
ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
|
ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
|
||||||
}
|
}
|
||||||
|
RTYPEDDATA_DATA(obj) = pkey;
|
||||||
|
|
||||||
if (!EC_KEY_generate_key(ec))
|
if (!EC_KEY_generate_key(ec))
|
||||||
ossl_raise(eECError, "EC_KEY_generate_key");
|
ossl_raise(eECError, "EC_KEY_generate_key");
|
||||||
|
|
||||||
|
@ -136,51 +139,54 @@ ossl_ec_key_s_generate(VALUE klass, VALUE arg)
|
||||||
static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
|
static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
|
||||||
{
|
{
|
||||||
EVP_PKEY *pkey;
|
EVP_PKEY *pkey;
|
||||||
EC_KEY *ec = NULL;
|
EC_KEY *ec;
|
||||||
|
BIO *in;
|
||||||
VALUE arg, pass;
|
VALUE arg, pass;
|
||||||
|
int type;
|
||||||
|
|
||||||
GetPKey(self, pkey);
|
TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
|
||||||
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
|
if (pkey)
|
||||||
ossl_raise(eECError, "EC_KEY already initialized");
|
rb_raise(rb_eTypeError, "pkey already initialized");
|
||||||
|
|
||||||
rb_scan_args(argc, argv, "02", &arg, &pass);
|
rb_scan_args(argc, argv, "02", &arg, &pass);
|
||||||
|
|
||||||
if (NIL_P(arg)) {
|
if (NIL_P(arg)) {
|
||||||
if (!(ec = EC_KEY_new()))
|
if (!(ec = EC_KEY_new()))
|
||||||
ossl_raise(eECError, NULL);
|
ossl_raise(eECError, "EC_KEY_new");
|
||||||
} else if (rb_obj_is_kind_of(arg, cEC)) {
|
goto legacy;
|
||||||
EC_KEY *other_ec = NULL;
|
}
|
||||||
|
else if (rb_obj_is_kind_of(arg, cEC_GROUP)) {
|
||||||
GetEC(arg, other_ec);
|
ec = ec_key_new_from_group(arg);
|
||||||
if (!(ec = EC_KEY_dup(other_ec)))
|
goto legacy;
|
||||||
ossl_raise(eECError, NULL);
|
|
||||||
} else if (rb_obj_is_kind_of(arg, cEC_GROUP)) {
|
|
||||||
ec = ec_key_new_from_group(arg);
|
|
||||||
} else {
|
|
||||||
BIO *in = ossl_obj2bio(&arg);
|
|
||||||
EVP_PKEY *tmp;
|
|
||||||
pass = ossl_pem_passwd_value(pass);
|
|
||||||
tmp = ossl_pkey_read_generic(in, pass);
|
|
||||||
if (tmp) {
|
|
||||||
if (EVP_PKEY_base_id(tmp) != EVP_PKEY_EC)
|
|
||||||
rb_raise(eECError, "incorrect pkey type: %s",
|
|
||||||
OBJ_nid2sn(EVP_PKEY_base_id(tmp)));
|
|
||||||
ec = EVP_PKEY_get1_EC_KEY(tmp);
|
|
||||||
EVP_PKEY_free(tmp);
|
|
||||||
}
|
}
|
||||||
BIO_free(in);
|
|
||||||
|
|
||||||
if (!ec) {
|
pass = ossl_pem_passwd_value(pass);
|
||||||
|
arg = ossl_to_der_if_possible(arg);
|
||||||
|
in = ossl_obj2bio(&arg);
|
||||||
|
|
||||||
|
pkey = ossl_pkey_read_generic(in, pass);
|
||||||
|
BIO_free(in);
|
||||||
|
if (!pkey) {
|
||||||
ossl_clear_error();
|
ossl_clear_error();
|
||||||
ec = ec_key_new_from_group(arg);
|
ec = ec_key_new_from_group(arg);
|
||||||
}
|
goto legacy;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) {
|
type = EVP_PKEY_base_id(pkey);
|
||||||
|
if (type != EVP_PKEY_EC) {
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
|
rb_raise(eDSAError, "incorrect pkey type: %s", OBJ_nid2sn(type));
|
||||||
|
}
|
||||||
|
RTYPEDDATA_DATA(self) = pkey;
|
||||||
|
return self;
|
||||||
|
|
||||||
|
legacy:
|
||||||
|
pkey = EVP_PKEY_new();
|
||||||
|
if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec) != 1) {
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
EC_KEY_free(ec);
|
EC_KEY_free(ec);
|
||||||
ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
|
ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
|
||||||
}
|
}
|
||||||
|
RTYPEDDATA_DATA(self) = pkey;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,18 +196,21 @@ ossl_ec_key_initialize_copy(VALUE self, VALUE other)
|
||||||
EVP_PKEY *pkey;
|
EVP_PKEY *pkey;
|
||||||
EC_KEY *ec, *ec_new;
|
EC_KEY *ec, *ec_new;
|
||||||
|
|
||||||
GetPKey(self, pkey);
|
TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
|
||||||
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
|
if (pkey)
|
||||||
ossl_raise(eECError, "EC already initialized");
|
rb_raise(rb_eTypeError, "pkey already initialized");
|
||||||
GetEC(other, ec);
|
GetEC(other, ec);
|
||||||
|
|
||||||
ec_new = EC_KEY_dup(ec);
|
ec_new = EC_KEY_dup(ec);
|
||||||
if (!ec_new)
|
if (!ec_new)
|
||||||
ossl_raise(eECError, "EC_KEY_dup");
|
ossl_raise(eECError, "EC_KEY_dup");
|
||||||
if (!EVP_PKEY_assign_EC_KEY(pkey, ec_new)) {
|
|
||||||
|
pkey = EVP_PKEY_new();
|
||||||
|
if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec_new) != 1) {
|
||||||
EC_KEY_free(ec_new);
|
EC_KEY_free(ec_new);
|
||||||
ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
|
ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
|
||||||
}
|
}
|
||||||
|
RTYPEDDATA_DATA(self) = pkey;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,51 +76,62 @@ VALUE eRSAError;
|
||||||
static VALUE
|
static VALUE
|
||||||
ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
|
ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
|
||||||
{
|
{
|
||||||
EVP_PKEY *pkey, *tmp;
|
EVP_PKEY *pkey;
|
||||||
RSA *rsa = NULL;
|
RSA *rsa;
|
||||||
BIO *in;
|
BIO *in = NULL;
|
||||||
VALUE arg, pass;
|
VALUE arg, pass;
|
||||||
|
int type;
|
||||||
|
|
||||||
|
TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
|
||||||
|
if (pkey)
|
||||||
|
rb_raise(rb_eTypeError, "pkey already initialized");
|
||||||
|
|
||||||
GetPKey(self, pkey);
|
|
||||||
/* The RSA.new(size, generator) form is handled by lib/openssl/pkey.rb */
|
/* The RSA.new(size, generator) form is handled by lib/openssl/pkey.rb */
|
||||||
rb_scan_args(argc, argv, "02", &arg, &pass);
|
rb_scan_args(argc, argv, "02", &arg, &pass);
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
rsa = RSA_new();
|
rsa = RSA_new();
|
||||||
if (!rsa)
|
if (!rsa)
|
||||||
ossl_raise(eRSAError, "RSA_new");
|
ossl_raise(eRSAError, "RSA_new");
|
||||||
|
goto legacy;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
pass = ossl_pem_passwd_value(pass);
|
pass = ossl_pem_passwd_value(pass);
|
||||||
arg = ossl_to_der_if_possible(arg);
|
arg = ossl_to_der_if_possible(arg);
|
||||||
in = ossl_obj2bio(&arg);
|
in = ossl_obj2bio(&arg);
|
||||||
|
|
||||||
tmp = ossl_pkey_read_generic(in, pass);
|
/* First try RSAPublicKey format */
|
||||||
if (tmp) {
|
rsa = d2i_RSAPublicKey_bio(in, NULL);
|
||||||
if (EVP_PKEY_base_id(tmp) != EVP_PKEY_RSA)
|
if (rsa)
|
||||||
rb_raise(eRSAError, "incorrect pkey type: %s",
|
goto legacy;
|
||||||
OBJ_nid2sn(EVP_PKEY_base_id(tmp)));
|
|
||||||
rsa = EVP_PKEY_get1_RSA(tmp);
|
|
||||||
EVP_PKEY_free(tmp);
|
|
||||||
}
|
|
||||||
if (!rsa) {
|
|
||||||
OSSL_BIO_reset(in);
|
OSSL_BIO_reset(in);
|
||||||
rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL);
|
rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL);
|
||||||
}
|
if (rsa)
|
||||||
if (!rsa) {
|
goto legacy;
|
||||||
OSSL_BIO_reset(in);
|
OSSL_BIO_reset(in);
|
||||||
rsa = d2i_RSAPublicKey_bio(in, NULL);
|
|
||||||
}
|
/* Use the generic routine */
|
||||||
|
pkey = ossl_pkey_read_generic(in, pass);
|
||||||
BIO_free(in);
|
BIO_free(in);
|
||||||
if (!rsa) {
|
if (!pkey)
|
||||||
ossl_clear_error();
|
|
||||||
ossl_raise(eRSAError, "Neither PUB key nor PRIV key");
|
ossl_raise(eRSAError, "Neither PUB key nor PRIV key");
|
||||||
|
|
||||||
|
type = EVP_PKEY_base_id(pkey);
|
||||||
|
if (type != EVP_PKEY_RSA) {
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
|
rb_raise(eRSAError, "incorrect pkey type: %s", OBJ_nid2sn(type));
|
||||||
}
|
}
|
||||||
}
|
RTYPEDDATA_DATA(self) = pkey;
|
||||||
if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
|
return self;
|
||||||
|
|
||||||
|
legacy:
|
||||||
|
BIO_free(in);
|
||||||
|
pkey = EVP_PKEY_new();
|
||||||
|
if (!pkey || EVP_PKEY_assign_RSA(pkey, rsa) != 1) {
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
RSA_free(rsa);
|
RSA_free(rsa);
|
||||||
ossl_raise(eRSAError, "EVP_PKEY_assign_RSA");
|
ossl_raise(eRSAError, "EVP_PKEY_assign_RSA");
|
||||||
}
|
}
|
||||||
|
RTYPEDDATA_DATA(self) = pkey;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,16 +141,23 @@ ossl_rsa_initialize_copy(VALUE self, VALUE other)
|
||||||
EVP_PKEY *pkey;
|
EVP_PKEY *pkey;
|
||||||
RSA *rsa, *rsa_new;
|
RSA *rsa, *rsa_new;
|
||||||
|
|
||||||
GetPKey(self, pkey);
|
TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
|
||||||
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
|
if (pkey)
|
||||||
ossl_raise(eRSAError, "RSA already initialized");
|
rb_raise(rb_eTypeError, "pkey already initialized");
|
||||||
GetRSA(other, rsa);
|
GetRSA(other, rsa);
|
||||||
|
|
||||||
rsa_new = ASN1_dup((i2d_of_void *)i2d_RSAPrivateKey, (d2i_of_void *)d2i_RSAPrivateKey, (char *)rsa);
|
rsa_new = (RSA *)ASN1_dup((i2d_of_void *)i2d_RSAPrivateKey,
|
||||||
|
(d2i_of_void *)d2i_RSAPrivateKey,
|
||||||
|
(char *)rsa);
|
||||||
if (!rsa_new)
|
if (!rsa_new)
|
||||||
ossl_raise(eRSAError, "ASN1_dup");
|
ossl_raise(eRSAError, "ASN1_dup");
|
||||||
|
|
||||||
EVP_PKEY_assign_RSA(pkey, rsa_new);
|
pkey = EVP_PKEY_new();
|
||||||
|
if (!pkey || EVP_PKEY_assign_RSA(pkey, rsa_new) != 1) {
|
||||||
|
RSA_free(rsa_new);
|
||||||
|
ossl_raise(eRSAError, "EVP_PKEY_assign_RSA");
|
||||||
|
}
|
||||||
|
RTYPEDDATA_DATA(self) = pkey;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue