[ruby/openssl] pkey: refactor DER/PEM-encoded string parsing code
Export the flow used by OpenSSL::PKey.read and let the subclasses call it before attempting other formats. https://github.com/ruby/openssl/commit/d963d4e276
This commit is contained in:
parent
10d360847b
commit
707e3d49cb
Notes:
git
2021-03-16 20:38:54 +09:00
@ -136,6 +136,35 @@ ossl_pkey_new(EVP_PKEY *pkey)
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EVP_PKEY *
|
||||||
|
ossl_pkey_read_generic(BIO *bio, VALUE pass)
|
||||||
|
{
|
||||||
|
void *ppass = (void *)pass;
|
||||||
|
EVP_PKEY *pkey;
|
||||||
|
|
||||||
|
if ((pkey = d2i_PrivateKey_bio(bio, NULL)))
|
||||||
|
goto out;
|
||||||
|
OSSL_BIO_reset(bio);
|
||||||
|
if ((pkey = d2i_PKCS8PrivateKey_bio(bio, NULL, ossl_pem_passwd_cb, ppass)))
|
||||||
|
goto out;
|
||||||
|
OSSL_BIO_reset(bio);
|
||||||
|
if ((pkey = d2i_PUBKEY_bio(bio, NULL)))
|
||||||
|
goto out;
|
||||||
|
OSSL_BIO_reset(bio);
|
||||||
|
/* PEM_read_bio_PrivateKey() also parses PKCS #8 formats */
|
||||||
|
if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, ppass)))
|
||||||
|
goto out;
|
||||||
|
OSSL_BIO_reset(bio);
|
||||||
|
if ((pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL)))
|
||||||
|
goto out;
|
||||||
|
OSSL_BIO_reset(bio);
|
||||||
|
if ((pkey = PEM_read_bio_Parameters(bio, NULL)))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
out:
|
||||||
|
return pkey;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* OpenSSL::PKey.read(string [, pwd ]) -> PKey
|
* OpenSSL::PKey.read(string [, pwd ]) -> PKey
|
||||||
@ -160,33 +189,11 @@ ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
|
|||||||
VALUE data, pass;
|
VALUE data, pass;
|
||||||
|
|
||||||
rb_scan_args(argc, argv, "11", &data, &pass);
|
rb_scan_args(argc, argv, "11", &data, &pass);
|
||||||
pass = ossl_pem_passwd_value(pass);
|
|
||||||
|
|
||||||
bio = ossl_obj2bio(&data);
|
bio = ossl_obj2bio(&data);
|
||||||
if ((pkey = d2i_PrivateKey_bio(bio, NULL)))
|
pkey = ossl_pkey_read_generic(bio, ossl_pem_passwd_value(pass));
|
||||||
goto ok;
|
|
||||||
OSSL_BIO_reset(bio);
|
|
||||||
if ((pkey = d2i_PKCS8PrivateKey_bio(bio, NULL, ossl_pem_passwd_cb, (void *)pass)))
|
|
||||||
goto ok;
|
|
||||||
OSSL_BIO_reset(bio);
|
|
||||||
if ((pkey = d2i_PUBKEY_bio(bio, NULL)))
|
|
||||||
goto ok;
|
|
||||||
OSSL_BIO_reset(bio);
|
|
||||||
/* PEM_read_bio_PrivateKey() also parses PKCS #8 formats */
|
|
||||||
if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, (void *)pass)))
|
|
||||||
goto ok;
|
|
||||||
OSSL_BIO_reset(bio);
|
|
||||||
if ((pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL)))
|
|
||||||
goto ok;
|
|
||||||
OSSL_BIO_reset(bio);
|
|
||||||
if ((pkey = PEM_read_bio_Parameters(bio, NULL)))
|
|
||||||
goto ok;
|
|
||||||
|
|
||||||
BIO_free(bio);
|
|
||||||
ossl_raise(ePKeyError, "Could not parse PKey");
|
|
||||||
|
|
||||||
ok:
|
|
||||||
BIO_free(bio);
|
BIO_free(bio);
|
||||||
|
if (!pkey)
|
||||||
|
ossl_raise(ePKeyError, "Could not parse PKey");
|
||||||
return ossl_pkey_new(pkey);
|
return ossl_pkey_new(pkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ void ossl_generate_cb_stop(void *ptr);
|
|||||||
|
|
||||||
VALUE ossl_pkey_new(EVP_PKEY *);
|
VALUE ossl_pkey_new(EVP_PKEY *);
|
||||||
void ossl_pkey_check_public_key(const EVP_PKEY *);
|
void ossl_pkey_check_public_key(const EVP_PKEY *);
|
||||||
|
EVP_PKEY *ossl_pkey_read_generic(BIO *, VALUE);
|
||||||
EVP_PKEY *GetPKeyPtr(VALUE);
|
EVP_PKEY *GetPKeyPtr(VALUE);
|
||||||
EVP_PKEY *DupPKeyPtr(VALUE);
|
EVP_PKEY *DupPKeyPtr(VALUE);
|
||||||
EVP_PKEY *GetPrivPKeyPtr(VALUE);
|
EVP_PKEY *GetPrivPKeyPtr(VALUE);
|
||||||
|
@ -170,37 +170,34 @@ ossl_dsa_s_generate(VALUE klass, VALUE size)
|
|||||||
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;
|
EVP_PKEY *pkey, *tmp;
|
||||||
DSA *dsa;
|
DSA *dsa = NULL;
|
||||||
BIO *in;
|
BIO *in;
|
||||||
VALUE arg, pass;
|
VALUE arg, pass;
|
||||||
|
|
||||||
GetPKey(self, pkey);
|
GetPKey(self, pkey);
|
||||||
if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) {
|
rb_scan_args(argc, argv, "02", &arg, &pass);
|
||||||
|
if (argc == 0) {
|
||||||
dsa = DSA_new();
|
dsa = DSA_new();
|
||||||
|
if (!dsa)
|
||||||
|
ossl_raise(eDSAError, "DSA_new");
|
||||||
}
|
}
|
||||||
else if (RB_INTEGER_TYPE_P(arg)) {
|
else if (argc == 1 && RB_INTEGER_TYPE_P(arg)) {
|
||||||
if (!(dsa = dsa_generate(NUM2INT(arg)))) {
|
dsa = dsa_generate(NUM2INT(arg));
|
||||||
ossl_raise(eDSAError, NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
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);
|
||||||
dsa = PEM_read_bio_DSAPrivateKey(in, NULL, ossl_pem_passwd_cb, (void *)pass);
|
|
||||||
if (!dsa) {
|
tmp = ossl_pkey_read_generic(in, pass);
|
||||||
OSSL_BIO_reset(in);
|
if (tmp) {
|
||||||
dsa = PEM_read_bio_DSA_PUBKEY(in, NULL, NULL, NULL);
|
if (EVP_PKEY_base_id(tmp) != EVP_PKEY_DSA)
|
||||||
}
|
rb_raise(eDSAError, "incorrect pkey type: %s",
|
||||||
if (!dsa) {
|
OBJ_nid2sn(EVP_PKEY_base_id(tmp)));
|
||||||
OSSL_BIO_reset(in);
|
dsa = EVP_PKEY_get1_DSA(tmp);
|
||||||
dsa = d2i_DSAPrivateKey_bio(in, NULL);
|
EVP_PKEY_free(tmp);
|
||||||
}
|
}
|
||||||
if (!dsa) {
|
|
||||||
OSSL_BIO_reset(in);
|
|
||||||
dsa = d2i_DSA_PUBKEY_bio(in, NULL);
|
|
||||||
}
|
|
||||||
if (!dsa) {
|
if (!dsa) {
|
||||||
OSSL_BIO_reset(in);
|
OSSL_BIO_reset(in);
|
||||||
#define PEM_read_bio_DSAPublicKey(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \
|
#define PEM_read_bio_DSAPublicKey(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \
|
||||||
|
@ -162,24 +162,17 @@ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
|
|||||||
} else if (rb_obj_is_kind_of(arg, cEC_GROUP)) {
|
} else if (rb_obj_is_kind_of(arg, cEC_GROUP)) {
|
||||||
ec = ec_key_new_from_group(arg);
|
ec = ec_key_new_from_group(arg);
|
||||||
} else {
|
} else {
|
||||||
BIO *in;
|
BIO *in = ossl_obj2bio(&arg);
|
||||||
|
EVP_PKEY *tmp;
|
||||||
pass = ossl_pem_passwd_value(pass);
|
pass = ossl_pem_passwd_value(pass);
|
||||||
in = ossl_obj2bio(&arg);
|
tmp = ossl_pkey_read_generic(in, pass);
|
||||||
|
if (tmp) {
|
||||||
ec = PEM_read_bio_ECPrivateKey(in, NULL, ossl_pem_passwd_cb, (void *)pass);
|
if (EVP_PKEY_base_id(tmp) != EVP_PKEY_EC)
|
||||||
if (!ec) {
|
rb_raise(eECError, "incorrect pkey type: %s",
|
||||||
OSSL_BIO_reset(in);
|
OBJ_nid2sn(EVP_PKEY_base_id(tmp)));
|
||||||
ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, (void *)pass);
|
ec = EVP_PKEY_get1_EC_KEY(tmp);
|
||||||
}
|
EVP_PKEY_free(tmp);
|
||||||
if (!ec) {
|
}
|
||||||
OSSL_BIO_reset(in);
|
|
||||||
ec = d2i_ECPrivateKey_bio(in, NULL);
|
|
||||||
}
|
|
||||||
if (!ec) {
|
|
||||||
OSSL_BIO_reset(in);
|
|
||||||
ec = d2i_EC_PUBKEY_bio(in, NULL);
|
|
||||||
}
|
|
||||||
BIO_free(in);
|
BIO_free(in);
|
||||||
|
|
||||||
if (!ec) {
|
if (!ec) {
|
||||||
|
@ -179,7 +179,8 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
|
|||||||
VALUE arg, pass;
|
VALUE arg, pass;
|
||||||
|
|
||||||
GetPKey(self, pkey);
|
GetPKey(self, pkey);
|
||||||
if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) {
|
rb_scan_args(argc, argv, "02", &arg, &pass);
|
||||||
|
if (argc == 0) {
|
||||||
rsa = RSA_new();
|
rsa = RSA_new();
|
||||||
if (!rsa)
|
if (!rsa)
|
||||||
ossl_raise(eRSAError, "RSA_new");
|
ossl_raise(eRSAError, "RSA_new");
|
||||||
@ -191,19 +192,15 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
|
|||||||
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);
|
||||||
rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ossl_pem_passwd_cb, (void *)pass);
|
|
||||||
if (!rsa) {
|
tmp = ossl_pkey_read_generic(in, pass);
|
||||||
OSSL_BIO_reset(in);
|
if (tmp) {
|
||||||
rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);
|
if (EVP_PKEY_base_id(tmp) != EVP_PKEY_RSA)
|
||||||
}
|
rb_raise(eRSAError, "incorrect pkey type: %s",
|
||||||
if (!rsa) {
|
OBJ_nid2sn(EVP_PKEY_base_id(tmp)));
|
||||||
OSSL_BIO_reset(in);
|
rsa = EVP_PKEY_get1_RSA(tmp);
|
||||||
rsa = d2i_RSAPrivateKey_bio(in, NULL);
|
EVP_PKEY_free(tmp);
|
||||||
}
|
}
|
||||||
if (!rsa) {
|
|
||||||
OSSL_BIO_reset(in);
|
|
||||||
rsa = d2i_RSA_PUBKEY_bio(in, NULL);
|
|
||||||
}
|
|
||||||
if (!rsa) {
|
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);
|
||||||
@ -214,6 +211,7 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
|
|||||||
}
|
}
|
||||||
BIO_free(in);
|
BIO_free(in);
|
||||||
if (!rsa) {
|
if (!rsa) {
|
||||||
|
ossl_clear_error();
|
||||||
ossl_raise(eRSAError, "Neither PUB key nor PRIV key");
|
ossl_raise(eRSAError, "Neither PUB key nor PRIV key");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user