1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

openssl: adapt OpenSSL::PKey to OpenSSL 1.1.0 opaque structs

* ext/openssl/openssl_missing.[ch]: Implement EVP_PKEY_get0_*() and
  {RSA,DSA,EC_KEY,DH}_get0_*() functions.
  OpenSSL 1.1.0 makes EVP_PKEY/RSA/DSA/DH opaque. We used to provide
  setter methods for each parameter of each PKey type, for example
  PKey::RSA#e=, but this is no longer possible because the new API
  RSA_set0_key() requires the 'n' at the same time. This commit adds
  deprecation warning to them and adds PKey::*#set_* methods as direct
  wrapper for those new APIs. For example, 'rsa.e = 3' now needs to be
  rewritten as 'rsa.set_key(rsa.n, 3, rsa.d)'.
  [ruby-core:75225] [Feature #12324]

* ext/openssl/ossl_pkey*.[ch]: Use the new accessor functions. Implement
  RSA#set_{key,factors,crt_params}, DSA#set_{key,pqg}, DH#set_{key,pqg}.
  Emit a warning with rb_warning() when old setter methods are used.

* test/drb/ut_array_drbssl.rb, test/drb/ut_drb_drbssl.rb,
  test/rubygems/test_gem_remote_fetcher.rb: Don't set a priv_key for DH
  object that are used in tmp_dh_callback. Generating a new key pair
  every time should be fine - actually the private exponent is ignored
  in OpenSSL >= 1.0.2f/1.0.1r even if we explicitly set.
  https://www.openssl.org/news/secadv/20160128.txt

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55285 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
rhe 2016-06-05 15:00:47 +00:00
parent 3cb77c4b03
commit 63abe00785
14 changed files with 447 additions and 233 deletions

View file

@ -1,3 +1,27 @@
Mon Jun 6 00:00:13 2016 Kazuki Yamaguchi <k@rhe.jp>
* ext/openssl/openssl_missing.[ch]: Implement EVP_PKEY_get0_*() and
{RSA,DSA,EC_KEY,DH}_get0_*() functions.
OpenSSL 1.1.0 makes EVP_PKEY/RSA/DSA/DH opaque. We used to provide
setter methods for each parameter of each PKey type, for example
PKey::RSA#e=, but this is no longer possible because the new API
RSA_set0_key() requires the 'n' at the same time. This commit adds
deprecation warning to them and adds PKey::*#set_* methods as direct
wrapper for those new APIs. For example, 'rsa.e = 3' now needs to be
rewritten as 'rsa.set_key(rsa.n, 3, rsa.d)'.
[ruby-core:75225] [Feature #12324]
* ext/openssl/ossl_pkey*.[ch]: Use the new accessor functions. Implement
RSA#set_{key,factors,crt_params}, DSA#set_{key,pqg}, DH#set_{key,pqg}.
Emit a warning with rb_warning() when old setter methods are used.
* test/drb/ut_array_drbssl.rb, test/drb/ut_drb_drbssl.rb,
test/rubygems/test_gem_remote_fetcher.rb: Don't set a priv_key for DH
object that are used in tmp_dh_callback. Generating a new key pair
every time should be fine - actually the private exponent is ignored
in OpenSSL >= 1.0.2f/1.0.1r even if we explicitly set.
https://www.openssl.org/news/secadv/20160128.txt
Sun Jun 5 22:06:00 2016 Kenta Murata <mrkn@mrkn.jp>
* configure.in: Fix the timing to detect the appropriate C++ compiler

View file

@ -87,6 +87,7 @@ engines.each { |name|
# added in 1.0.0
have_func("ASN1_TIME_adj")
have_func("EVP_CIPHER_CTX_copy")
have_func("EVP_PKEY_base_id")
have_func("HMAC_CTX_copy")
have_func("PKCS5_PBKDF2_HMAC")
have_func("X509_NAME_hash_old")

View file

@ -11,6 +11,10 @@
#define _OSSL_OPENSSL_MISSING_H_
/* added in 1.0.0 */
#if !defined(HAVE_EVP_PKEY_BASE_ID)
# define EVP_PKEY_base_id(pkey) EVP_PKEY_type((pkey)->type)
#endif
#if !defined(HAVE_EVP_CIPHER_CTX_COPY)
int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in);
#endif
@ -70,4 +74,58 @@ int EC_curve_nist2nid(const char *);
CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_EVP_PKEY);
#endif
#if !defined(HAVE_OPAQUE_OPENSSL)
#define IMPL_PKEY_GETTER(_type, _name) \
static inline _type *EVP_PKEY_get0_##_type(EVP_PKEY *pkey) { \
return pkey->pkey._name; }
#define IMPL_KEY_ACCESSOR2(_type, _group, a1, a2, _fail_cond) \
static inline void _type##_get0_##_group(_type *obj, BIGNUM **a1, BIGNUM **a2) { \
if (a1) *a1 = obj->a1; \
if (a2) *a2 = obj->a2; } \
static inline int _type##_set0_##_group(_type *obj, BIGNUM *a1, BIGNUM *a2) { \
if (_fail_cond) return 0; \
BN_clear_free(obj->a1); obj->a1 = a1; \
BN_clear_free(obj->a2); obj->a2 = a2; \
return 1; }
#define IMPL_KEY_ACCESSOR3(_type, _group, a1, a2, a3, _fail_cond) \
static inline void _type##_get0_##_group(_type *obj, BIGNUM **a1, BIGNUM **a2, BIGNUM **a3) { \
if (a1) *a1 = obj->a1; \
if (a2) *a2 = obj->a2; \
if (a3) *a3 = obj->a3; } \
static inline int _type##_set0_##_group(_type *obj, BIGNUM *a1, BIGNUM *a2, BIGNUM *a3) { \
if (_fail_cond) return 0; \
BN_clear_free(obj->a1); obj->a1 = a1; \
BN_clear_free(obj->a2); obj->a2 = a2; \
BN_clear_free(obj->a3); obj->a3 = a3; \
return 1; }
#if !defined(OPENSSL_NO_RSA)
IMPL_PKEY_GETTER(RSA, rsa)
IMPL_KEY_ACCESSOR3(RSA, key, n, e, d, (n == obj->n || e == obj->e || (obj->d && e == obj->d)))
IMPL_KEY_ACCESSOR2(RSA, factors, p, q, (p == obj->p || q == obj->q))
IMPL_KEY_ACCESSOR3(RSA, crt_params, dmp1, dmq1, iqmp, (dmp1 == obj->dmp1 || dmq1 == obj->dmq1 || iqmp == obj->iqmp))
#endif
#if !defined(OPENSSL_NO_DSA)
IMPL_PKEY_GETTER(DSA, dsa)
IMPL_KEY_ACCESSOR2(DSA, key, pub_key, priv_key, (pub_key == obj->pub_key || (obj->priv_key && priv_key == obj->priv_key)))
IMPL_KEY_ACCESSOR3(DSA, pqg, p, q, g, (p == obj->p || q == obj->q || g == obj->g))
#endif
#if !defined(OPENSSL_NO_DH)
IMPL_PKEY_GETTER(DH, dh)
IMPL_KEY_ACCESSOR2(DH, key, pub_key, priv_key, (pub_key == obj->pub_key || (obj->priv_key && priv_key == obj->priv_key)))
IMPL_KEY_ACCESSOR3(DH, pqg, p, q, g, (p == obj->p || q == obj->q || g == obj->g))
static inline ENGINE *DH_get0_engine(DH *dh) { return dh->engine; }
#endif
#if !defined(OPENSSL_NO_EC)
IMPL_PKEY_GETTER(EC_KEY, ec)
#endif
#undef IMPL_PKEY_GETTER
#undef IMPL_KEY_ACCESSOR2
#undef IMPL_KEY_ACCESSOR3
#endif /* HAVE_OPAQUE_OPENSSL */
#endif /* _OSSL_OPENSSL_MISSING_H_ */

View file

@ -76,7 +76,7 @@ ossl_pkey_new(EVP_PKEY *pkey)
if (!pkey) {
ossl_raise(ePKeyError, "Cannot make new key from NULL.");
}
switch (EVP_PKEY_type(pkey->type)) {
switch (EVP_PKEY_base_id(pkey)) {
#if !defined(OPENSSL_NO_RSA)
case EVP_PKEY_RSA:
return ossl_rsa_new(pkey);

View file

@ -95,53 +95,153 @@ extern VALUE eEC_POINT;
VALUE ossl_ec_new(EVP_PKEY *);
void Init_ossl_ec(void);
#define OSSL_PKEY_BN(keytype, name) \
#define OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, _name, _get) \
/* \
* call-seq: \
* key.##name -> aBN \
* _keytype##.##_name -> aBN \
*/ \
static VALUE ossl_##keytype##_get_##name(VALUE self) \
static VALUE ossl_##_keytype##_get_##_name(VALUE self) \
{ \
EVP_PKEY *pkey; \
_type *obj; \
BIGNUM *bn; \
\
GetPKey(self, pkey); \
bn = pkey->pkey.keytype->name; \
Get##_type(self, obj); \
_get; \
if (bn == NULL) \
return Qnil; \
return ossl_bn_new(bn); \
} \
}
#define OSSL_PKEY_BN_DEF_GETTER3(_keytype, _type, _group, a1, a2, a3) \
OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a1, \
_type##_get0_##_group(obj, &bn, NULL, NULL)) \
OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a2, \
_type##_get0_##_group(obj, NULL, &bn, NULL)) \
OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a3, \
_type##_get0_##_group(obj, NULL, NULL, &bn))
#define OSSL_PKEY_BN_DEF_GETTER2(_keytype, _type, _group, a1, a2) \
OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a1, \
_type##_get0_##_group(obj, &bn, NULL)) \
OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a2, \
_type##_get0_##_group(obj, NULL, &bn))
#define OSSL_PKEY_BN_DEF_SETTER3(_keytype, _type, _group, a1, a2, a3) \
/* \
* call-seq: \
* key.##name = bn -> bn \
* _keytype##.set_##_group(a1, a2, a3) -> self \
*/ \
static VALUE ossl_##keytype##_set_##name(VALUE self, VALUE bignum) \
static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2, VALUE v3) \
{ \
EVP_PKEY *pkey; \
_type *obj; \
BIGNUM *bn1 = NULL, *orig_bn1 = NIL_P(v1) ? NULL : GetBNPtr(v1);\
BIGNUM *bn2 = NULL, *orig_bn2 = NIL_P(v2) ? NULL : GetBNPtr(v2);\
BIGNUM *bn3 = NULL, *orig_bn3 = NIL_P(v3) ? NULL : GetBNPtr(v3);\
\
Get##_type(self, obj); \
if (orig_bn1 && !(bn1 = BN_dup(orig_bn1)) || \
orig_bn2 && !(bn2 = BN_dup(orig_bn2)) || \
orig_bn3 && !(bn3 = BN_dup(orig_bn3))) { \
BN_clear_free(bn1); \
BN_clear_free(bn2); \
BN_clear_free(bn3); \
ossl_raise(eBNError, NULL); \
} \
\
if (!_type##_set0_##_group(obj, bn1, bn2, bn3)) { \
BN_clear_free(bn1); \
BN_clear_free(bn2); \
BN_clear_free(bn3); \
ossl_raise(ePKeyError, #_type"_set0_"#_group); \
} \
return self; \
}
#define OSSL_PKEY_BN_DEF_SETTER2(_keytype, _type, _group, a1, a2) \
/* \
* call-seq: \
* _keytype##.set_##_group(a1, a2) -> self \
*/ \
static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2) \
{ \
_type *obj; \
BIGNUM *bn1 = NULL, *orig_bn1 = NIL_P(v1) ? NULL : GetBNPtr(v1);\
BIGNUM *bn2 = NULL, *orig_bn2 = NIL_P(v2) ? NULL : GetBNPtr(v2);\
\
Get##_type(self, obj); \
if (orig_bn1 && !(bn1 = BN_dup(orig_bn1)) || \
orig_bn2 && !(bn2 = BN_dup(orig_bn2))) { \
BN_clear_free(bn1); \
BN_clear_free(bn2); \
ossl_raise(eBNError, NULL); \
} \
\
if (!_type##_set0_##_group(obj, bn1, bn2)) { \
BN_clear_free(bn1); \
BN_clear_free(bn2); \
ossl_raise(ePKeyError, #_type"_set0_"#_group); \
} \
return self; \
}
#define OSSL_PKEY_BN_DEF_SETTER_OLD(_keytype, _type, _group, _name) \
/* \
* call-seq: \
* _keytype##.##_name = bn -> bn \
*/ \
static VALUE ossl_##_keytype##_set_##_name(VALUE self, VALUE bignum) \
{ \
_type *obj; \
BIGNUM *bn; \
\
GetPKey(self, pkey); \
rb_warning("#"#_name"= is deprecated; use #set_"#_group); \
Get##_type(self, obj); \
if (NIL_P(bignum)) { \
BN_clear_free(pkey->pkey.keytype->name); \
pkey->pkey.keytype->name = NULL; \
BN_clear_free(obj->_name); \
obj->_name = NULL; \
return Qnil; \
} \
\
bn = GetBNPtr(bignum); \
if (pkey->pkey.keytype->name == NULL) \
pkey->pkey.keytype->name = BN_new(); \
if (pkey->pkey.keytype->name == NULL) \
if (obj->_name == NULL) \
obj->_name = BN_new(); \
if (obj->_name == NULL) \
ossl_raise(eBNError, NULL); \
if (BN_copy(pkey->pkey.keytype->name, bn) == NULL) \
if (BN_copy(obj->_name, bn) == NULL) \
ossl_raise(eBNError, NULL); \
return bignum; \
}
#if defined(HAVE_OPAQUE_OPENSSL) /* OpenSSL 1.1.0 */
#define OSSL_PKEY_BN_DEF3(_keytype, _type, _group, a1, a2, a3) \
OSSL_PKEY_BN_DEF_GETTER3(_keytype, _type, _group, a1, a2, a3) \
OSSL_PKEY_BN_DEF_SETTER3(_keytype, _type, _group, a1, a2, a3)
#define OSSL_PKEY_BN_DEF2(_keytype, _type, _group, a1, a2) \
OSSL_PKEY_BN_DEF_GETTER2(_keytype, _type, _group, a1, a2) \
OSSL_PKEY_BN_DEF_SETTER2(_keytype, _type, _group, a1, a2)
#define DEF_OSSL_PKEY_BN(class, keytype, name) \
do { \
rb_define_method((class), #name, ossl_##keytype##_get_##name, 0); \
rb_define_method((class), #name, ossl_##keytype##_get_##name, 0)
#else
#define OSSL_PKEY_BN_DEF3(_keytype, _type, _group, a1, a2, a3) \
OSSL_PKEY_BN_DEF_GETTER3(_keytype, _type, _group, a1, a2, a3) \
OSSL_PKEY_BN_DEF_SETTER3(_keytype, _type, _group, a1, a2, a3) \
OSSL_PKEY_BN_DEF_SETTER_OLD(_keytype, _type, _group, a1) \
OSSL_PKEY_BN_DEF_SETTER_OLD(_keytype, _type, _group, a2) \
OSSL_PKEY_BN_DEF_SETTER_OLD(_keytype, _type, _group, a3)
#define OSSL_PKEY_BN_DEF2(_keytype, _type, _group, a1, a2) \
OSSL_PKEY_BN_DEF_GETTER2(_keytype, _type, _group, a1, a2) \
OSSL_PKEY_BN_DEF_SETTER2(_keytype, _type, _group, a1, a2) \
OSSL_PKEY_BN_DEF_SETTER_OLD(_keytype, _type, _group, a1) \
OSSL_PKEY_BN_DEF_SETTER_OLD(_keytype, _type, _group, a2)
#define DEF_OSSL_PKEY_BN(class, keytype, name) do { \
rb_define_method((class), #name, ossl_##keytype##_get_##name, 0);\
rb_define_method((class), #name "=", ossl_##keytype##_set_##name, 1);\
} while (0)
#endif /* HAVE_OPAQUE_OPENSSL */
#endif /* _OSSL_PKEY_H_ */

View file

@ -7,25 +7,21 @@
* This program is licensed under the same licence as Ruby.
* (See the file 'LICENCE'.)
*/
#if !defined(OPENSSL_NO_DH)
#include "ossl.h"
#if !defined(OPENSSL_NO_DH)
#define GetPKeyDH(obj, pkey) do { \
GetPKey((obj), (pkey)); \
if (EVP_PKEY_type((pkey)->type) != EVP_PKEY_DH) { /* PARANOIA? */ \
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) { /* PARANOIA? */ \
ossl_raise(rb_eRuntimeError, "THIS IS NOT A DH!") ; \
} \
} while (0)
#define DH_HAS_PRIVATE(dh) ((dh)->priv_key)
#if !defined(OPENSSL_NO_ENGINE)
# define DH_PRIVATE(dh) (DH_HAS_PRIVATE(dh) || (dh)->engine)
#else
# define DH_PRIVATE(dh) DH_HAS_PRIVATE(dh)
#endif
#define GetDH(obj, dh) do { \
EVP_PKEY *_pkey; \
GetPKeyDH((obj), _pkey); \
(dh) = EVP_PKEY_get0_DH(_pkey); \
} while (0)
/*
* Classes
@ -67,7 +63,7 @@ ossl_dh_new(EVP_PKEY *pkey)
obj = dh_instance(cDH, DH_new());
} else {
obj = NewPKey(cDH);
if (EVP_PKEY_type(pkey->type) != EVP_PKEY_DH) {
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) {
ossl_raise(rb_eTypeError, "Not a DH key!");
}
SetPKey(obj, pkey);
@ -248,11 +244,13 @@ ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
static VALUE
ossl_dh_is_public(VALUE self)
{
EVP_PKEY *pkey;
DH *dh;
BIGNUM *bn;
GetPKeyDH(self, pkey);
GetDH(self, dh);
DH_get0_key(dh, &bn, NULL);
return (pkey->pkey.dh->pub_key) ? Qtrue : Qfalse;
return bn ? Qtrue : Qfalse;
}
/*
@ -265,11 +263,17 @@ ossl_dh_is_public(VALUE self)
static VALUE
ossl_dh_is_private(VALUE self)
{
EVP_PKEY *pkey;
DH *dh;
BIGNUM *bn;
GetPKeyDH(self, pkey);
GetDH(self, dh);
DH_get0_key(dh, NULL, &bn);
return (DH_PRIVATE(pkey->pkey.dh)) ? Qtrue : Qfalse;
#if !defined(OPENSSL_NO_ENGINE)
return (bn || DH_get0_engine(dh)) ? Qtrue : Qfalse;
#else
return bn ? Qtrue : Qfalse;
#endif
}
/*
@ -285,15 +289,15 @@ ossl_dh_is_private(VALUE self)
static VALUE
ossl_dh_export(VALUE self)
{
EVP_PKEY *pkey;
DH *dh;
BIO *out;
VALUE str;
GetPKeyDH(self, pkey);
GetDH(self, dh);
if (!(out = BIO_new(BIO_s_mem()))) {
ossl_raise(eDHError, NULL);
}
if (!PEM_write_bio_DHparams(out, pkey->pkey.dh)) {
if (!PEM_write_bio_DHparams(out, dh)) {
BIO_free(out);
ossl_raise(eDHError, NULL);
}
@ -314,17 +318,17 @@ ossl_dh_export(VALUE self)
static VALUE
ossl_dh_to_der(VALUE self)
{
EVP_PKEY *pkey;
DH *dh;
unsigned char *p;
long len;
VALUE str;
GetPKeyDH(self, pkey);
if((len = i2d_DHparams(pkey->pkey.dh, NULL)) <= 0)
GetDH(self, dh);
if((len = i2d_DHparams(dh, NULL)) <= 0)
ossl_raise(eDHError, NULL);
str = rb_str_new(0, len);
p = (unsigned char *)RSTRING_PTR(str);
if(i2d_DHparams(pkey->pkey.dh, &p) < 0)
if(i2d_DHparams(dh, &p) < 0)
ossl_raise(eDHError, NULL);
ossl_str_adjust(str, p);
@ -342,17 +346,20 @@ ossl_dh_to_der(VALUE self)
static VALUE
ossl_dh_get_params(VALUE self)
{
EVP_PKEY *pkey;
DH *dh;
VALUE hash;
BIGNUM *p, *q, *g, *pub_key, *priv_key;
GetPKeyDH(self, pkey);
GetDH(self, dh);
DH_get0_pqg(dh, &p, &q, &g);
DH_get0_key(dh, &pub_key, &priv_key);
hash = rb_hash_new();
rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(pkey->pkey.dh->p));
rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(pkey->pkey.dh->g));
rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pkey->pkey.dh->pub_key));
rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(pkey->pkey.dh->priv_key));
rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(p));
rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(q));
rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(g));
rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pub_key));
rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(priv_key));
return hash;
}
@ -368,15 +375,15 @@ ossl_dh_get_params(VALUE self)
static VALUE
ossl_dh_to_text(VALUE self)
{
EVP_PKEY *pkey;
DH *dh;
BIO *out;
VALUE str;
GetPKeyDH(self, pkey);
GetDH(self, dh);
if (!(out = BIO_new(BIO_s_mem()))) {
ossl_raise(eDHError, NULL);
}
if (!DHparams_print(out, pkey->pkey.dh)) {
if (!DHparams_print(out, dh)) {
BIO_free(out);
ossl_raise(eDHError, NULL);
}
@ -409,12 +416,11 @@ ossl_dh_to_text(VALUE self)
static VALUE
ossl_dh_to_public_key(VALUE self)
{
EVP_PKEY *pkey;
DH *dh;
DH *orig_dh, *dh;
VALUE obj;
GetPKeyDH(self, pkey);
dh = DHparams_dup(pkey->pkey.dh); /* err check perfomed by dh_instance */
GetDH(self, orig_dh);
dh = DHparams_dup(orig_dh); /* err check perfomed by dh_instance */
obj = dh_instance(CLASS_OF(self), dh);
if (obj == Qfalse) {
DH_free(dh);
@ -436,12 +442,9 @@ static VALUE
ossl_dh_check_params(VALUE self)
{
DH *dh;
EVP_PKEY *pkey;
int codes;
GetPKeyDH(self, pkey);
dh = pkey->pkey.dh;
GetDH(self, dh);
if (!DH_check(dh, &codes)) {
return Qfalse;
}
@ -469,11 +472,8 @@ static VALUE
ossl_dh_generate_key(VALUE self)
{
DH *dh;
EVP_PKEY *pkey;
GetPKeyDH(self, pkey);
dh = pkey->pkey.dh;
GetDH(self, dh);
if (!DH_generate_key(dh))
ossl_raise(eDHError, "Failed to generate key");
return self;
@ -494,14 +494,13 @@ static VALUE
ossl_dh_compute_key(VALUE self, VALUE pub)
{
DH *dh;
EVP_PKEY *pkey;
BIGNUM *pub_key;
BIGNUM *pub_key, *dh_p;
VALUE str;
int len;
GetPKeyDH(self, pkey);
dh = pkey->pkey.dh;
if (!dh->p)
GetDH(self, dh);
DH_get0_pqg(dh, &dh_p, NULL, NULL);
if (!dh_p)
ossl_raise(eDHError, "incomplete DH");
pub_key = GetBNPtr(pub);
len = DH_size(dh);
@ -514,10 +513,8 @@ ossl_dh_compute_key(VALUE self, VALUE pub)
return str;
}
OSSL_PKEY_BN(dh, p)
OSSL_PKEY_BN(dh, g)
OSSL_PKEY_BN(dh, pub_key)
OSSL_PKEY_BN(dh, priv_key)
OSSL_PKEY_BN_DEF3(dh, DH, pqg, p, q, g)
OSSL_PKEY_BN_DEF2(dh, DH, key, pub_key, priv_key)
/*
* INIT
@ -580,9 +577,13 @@ Init_ossl_dh(void)
rb_define_method(cDH, "compute_key", ossl_dh_compute_key, 1);
DEF_OSSL_PKEY_BN(cDH, dh, p);
DEF_OSSL_PKEY_BN(cDH, dh, q);
DEF_OSSL_PKEY_BN(cDH, dh, g);
DEF_OSSL_PKEY_BN(cDH, dh, pub_key);
DEF_OSSL_PKEY_BN(cDH, dh, priv_key);
rb_define_method(cDH, "set_pqg", ossl_dh_set_pqg, 3);
rb_define_method(cDH, "set_key", ossl_dh_set_key, 2);
rb_define_method(cDH, "params", ossl_dh_get_params, 0);
}

View file

@ -7,19 +7,35 @@
* This program is licensed under the same licence as Ruby.
* (See the file 'LICENCE'.)
*/
#if !defined(OPENSSL_NO_DSA)
#include "ossl.h"
#if !defined(OPENSSL_NO_DSA)
#define GetPKeyDSA(obj, pkey) do { \
GetPKey((obj), (pkey)); \
if (EVP_PKEY_type((pkey)->type) != EVP_PKEY_DSA) { /* PARANOIA? */ \
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DSA) { /* PARANOIA? */ \
ossl_raise(rb_eRuntimeError, "THIS IS NOT A DSA!"); \
} \
} while (0)
#define GetDSA(obj, dsa) do { \
EVP_PKEY *_pkey; \
GetPKeyDSA((obj), _pkey); \
(dsa) = EVP_PKEY_get0_DSA(_pkey); \
} while (0)
#define DSA_HAS_PRIVATE(dsa) ((dsa)->priv_key)
#define DSA_PRIVATE(obj,dsa) (DSA_HAS_PRIVATE(dsa)||OSSL_PKEY_IS_PRIVATE(obj))
static inline int
DSA_HAS_PRIVATE(DSA *dsa)
{
BIGNUM *bn;
DSA_get0_key(dsa, NULL, &bn);
return !!bn;
}
static inline int
DSA_PRIVATE(VALUE obj, DSA *dsa)
{
return DSA_HAS_PRIVATE(dsa) || OSSL_PKEY_IS_PRIVATE(obj);
}
/*
* Classes
@ -61,7 +77,7 @@ ossl_dsa_new(EVP_PKEY *pkey)
obj = dsa_instance(cDSA, DSA_new());
} else {
obj = NewPKey(cDSA);
if (EVP_PKEY_type(pkey->type) != EVP_PKEY_DSA) {
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DSA) {
ossl_raise(rb_eTypeError, "Not a DSA key!");
}
SetPKey(obj, pkey);
@ -259,11 +275,13 @@ ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
static VALUE
ossl_dsa_is_public(VALUE self)
{
EVP_PKEY *pkey;
DSA *dsa;
BIGNUM *bn;
GetPKeyDSA(self, pkey);
GetDSA(self, dsa);
DSA_get0_key(dsa, &bn, NULL);
return (pkey->pkey.dsa->pub_key) ? Qtrue : Qfalse;
return bn ? Qtrue : Qfalse;
}
/*
@ -276,11 +294,11 @@ ossl_dsa_is_public(VALUE self)
static VALUE
ossl_dsa_is_private(VALUE self)
{
EVP_PKEY *pkey;
DSA *dsa;
GetPKeyDSA(self, pkey);
GetDSA(self, dsa);
return (DSA_PRIVATE(self, pkey->pkey.dsa)) ? Qtrue : Qfalse;
return DSA_PRIVATE(self, dsa) ? Qtrue : Qfalse;
}
/*
@ -303,12 +321,12 @@ ossl_dsa_is_private(VALUE self)
static VALUE
ossl_dsa_export(int argc, VALUE *argv, VALUE self)
{
EVP_PKEY *pkey;
DSA *dsa;
BIO *out;
const EVP_CIPHER *ciph = NULL;
VALUE cipher, pass, str;
GetPKeyDSA(self, pkey);
GetDSA(self, dsa);
rb_scan_args(argc, argv, "02", &cipher, &pass);
if (!NIL_P(cipher)) {
ciph = GetCipherPtr(cipher);
@ -317,14 +335,14 @@ ossl_dsa_export(int argc, VALUE *argv, VALUE self)
if (!(out = BIO_new(BIO_s_mem()))) {
ossl_raise(eDSAError, NULL);
}
if (DSA_HAS_PRIVATE(pkey->pkey.dsa)) {
if (!PEM_write_bio_DSAPrivateKey(out, pkey->pkey.dsa, ciph,
NULL, 0, ossl_pem_passwd_cb, (void *)pass)){
if (DSA_HAS_PRIVATE(dsa)) {
if (!PEM_write_bio_DSAPrivateKey(out, dsa, ciph, NULL, 0,
ossl_pem_passwd_cb, (void *)pass)){
BIO_free(out);
ossl_raise(eDSAError, NULL);
}
} else {
if (!PEM_write_bio_DSA_PUBKEY(out, pkey->pkey.dsa)) {
if (!PEM_write_bio_DSA_PUBKEY(out, dsa)) {
BIO_free(out);
ossl_raise(eDSAError, NULL);
}
@ -344,28 +362,29 @@ ossl_dsa_export(int argc, VALUE *argv, VALUE self)
static VALUE
ossl_dsa_to_der(VALUE self)
{
EVP_PKEY *pkey;
DSA *dsa;
int (*i2d_func)_((DSA*, unsigned char**));
unsigned char *p;
long len;
VALUE str;
GetPKeyDSA(self, pkey);
if(DSA_HAS_PRIVATE(pkey->pkey.dsa))
GetDSA(self, dsa);
if(DSA_HAS_PRIVATE(dsa))
i2d_func = (int(*)_((DSA*,unsigned char**)))i2d_DSAPrivateKey;
else
i2d_func = i2d_DSA_PUBKEY;
if((len = i2d_func(pkey->pkey.dsa, NULL)) <= 0)
if((len = i2d_func(dsa, NULL)) <= 0)
ossl_raise(eDSAError, NULL);
str = rb_str_new(0, len);
p = (unsigned char *)RSTRING_PTR(str);
if(i2d_func(pkey->pkey.dsa, &p) < 0)
if(i2d_func(dsa, &p) < 0)
ossl_raise(eDSAError, NULL);
ossl_str_adjust(str, p);
return str;
}
/*
* call-seq:
* dsa.params -> hash
@ -377,18 +396,20 @@ ossl_dsa_to_der(VALUE self)
static VALUE
ossl_dsa_get_params(VALUE self)
{
EVP_PKEY *pkey;
DSA *dsa;
VALUE hash;
BIGNUM *p, *q, *g, *pub_key, *priv_key;
GetPKeyDSA(self, pkey);
GetDSA(self, dsa);
DSA_get0_pqg(dsa, &p, &q, &g);
DSA_get0_key(dsa, &pub_key, &priv_key);
hash = rb_hash_new();
rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(pkey->pkey.dsa->p));
rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(pkey->pkey.dsa->q));
rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(pkey->pkey.dsa->g));
rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pkey->pkey.dsa->pub_key));
rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(pkey->pkey.dsa->priv_key));
rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(p));
rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(q));
rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(g));
rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pub_key));
rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(priv_key));
return hash;
}
@ -404,15 +425,15 @@ ossl_dsa_get_params(VALUE self)
static VALUE
ossl_dsa_to_text(VALUE self)
{
EVP_PKEY *pkey;
DSA *dsa;
BIO *out;
VALUE str;
GetPKeyDSA(self, pkey);
GetDSA(self, dsa);
if (!(out = BIO_new(BIO_s_mem()))) {
ossl_raise(eDSAError, NULL);
}
if (!DSA_print(out, pkey->pkey.dsa, 0)) { /* offset = 0 */
if (!DSA_print(out, dsa, 0)) { /* offset = 0 */
BIO_free(out);
ossl_raise(eDSAError, NULL);
}
@ -449,7 +470,7 @@ ossl_dsa_to_public_key(VALUE self)
/* err check performed by dsa_instance */
#define DSAPublicKey_dup(dsa) (DSA *)ASN1_dup( \
(i2d_of_void *)i2d_DSAPublicKey, (d2i_of_void *)d2i_DSAPublicKey, (char *)(dsa))
dsa = DSAPublicKey_dup(pkey->pkey.dsa);
dsa = DSAPublicKey_dup(EVP_PKEY_get0_DSA(pkey));
#undef DSAPublicKey_dup
obj = dsa_instance(CLASS_OF(self), dsa);
if (obj == Qfalse) {
@ -459,7 +480,7 @@ ossl_dsa_to_public_key(VALUE self)
return obj;
}
#define ossl_dsa_buf_size(pkey) (DSA_size((pkey)->pkey.dsa)+16)
#define ossl_dsa_buf_size(dsa) (DSA_size(dsa) + 16)
/*
* call-seq:
@ -483,20 +504,22 @@ ossl_dsa_to_public_key(VALUE self)
static VALUE
ossl_dsa_sign(VALUE self, VALUE data)
{
EVP_PKEY *pkey;
DSA *dsa;
BIGNUM *dsa_q;
unsigned int buf_len;
VALUE str;
GetPKeyDSA(self, pkey);
if (!pkey->pkey.dsa->q)
GetDSA(self, dsa);
DSA_get0_pqg(dsa, NULL, &dsa_q, NULL);
if (!dsa_q)
ossl_raise(eDSAError, "incomplete DSA");
if (!DSA_PRIVATE(self, pkey->pkey.dsa))
if (!DSA_PRIVATE(self, dsa))
ossl_raise(eDSAError, "Private DSA key needed!");
StringValue(data);
str = rb_str_new(0, ossl_dsa_buf_size(pkey));
str = rb_str_new(0, ossl_dsa_buf_size(dsa));
if (!DSA_sign(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LENINT(data),
(unsigned char *)RSTRING_PTR(str),
&buf_len, pkey->pkey.dsa)) { /* type is ignored (0) */
&buf_len, dsa)) { /* type is ignored (0) */
ossl_raise(eDSAError, NULL);
}
rb_str_set_len(str, buf_len);
@ -526,15 +549,15 @@ ossl_dsa_sign(VALUE self, VALUE data)
static VALUE
ossl_dsa_verify(VALUE self, VALUE digest, VALUE sig)
{
EVP_PKEY *pkey;
DSA *dsa;
int ret;
GetPKeyDSA(self, pkey);
GetDSA(self, dsa);
StringValue(digest);
StringValue(sig);
/* type is ignored (0) */
ret = DSA_verify(0, (unsigned char *)RSTRING_PTR(digest), RSTRING_LENINT(digest),
(unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), pkey->pkey.dsa);
(unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), dsa);
if (ret < 0) {
ossl_raise(eDSAError, NULL);
}
@ -545,11 +568,8 @@ ossl_dsa_verify(VALUE self, VALUE digest, VALUE sig)
return Qfalse;
}
OSSL_PKEY_BN(dsa, p)
OSSL_PKEY_BN(dsa, q)
OSSL_PKEY_BN(dsa, g)
OSSL_PKEY_BN(dsa, pub_key)
OSSL_PKEY_BN(dsa, priv_key)
OSSL_PKEY_BN_DEF3(dsa, DSA, pqg, p, q, g)
OSSL_PKEY_BN_DEF2(dsa, DSA, key, pub_key, priv_key)
/*
* INIT
@ -603,6 +623,8 @@ Init_ossl_dsa(void)
DEF_OSSL_PKEY_BN(cDSA, dsa, g);
DEF_OSSL_PKEY_BN(cDSA, dsa, pub_key);
DEF_OSSL_PKEY_BN(cDSA, dsa, priv_key);
rb_define_method(cDSA, "set_pqg", ossl_dsa_set_pqg, 3);
rb_define_method(cDSA, "set_key", ossl_dsa_set_key, 2);
rb_define_method(cDSA, "params", ossl_dsa_get_params, 0);
}

View file

@ -25,7 +25,7 @@ static const rb_data_type_t ossl_ec_point_type;
#define GetPKeyEC(obj, pkey) do { \
GetPKey((obj), (pkey)); \
if (EVP_PKEY_type((pkey)->type) != EVP_PKEY_EC) { \
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) { \
ossl_raise(rb_eRuntimeError, "THIS IS NOT A EC PKEY!"); \
} \
} while (0)
@ -38,7 +38,7 @@ static const rb_data_type_t ossl_ec_point_type;
#define Get_EC_KEY(obj, key) do { \
EVP_PKEY *pkey; \
GetPKeyEC((obj), pkey); \
(key) = pkey->pkey.ec; \
(key) = EVP_PKEY_get0_EC_KEY(pkey); \
} while(0)
#define Require_EC_KEY(obj, key) do { \
@ -137,7 +137,7 @@ VALUE ossl_ec_new(EVP_PKEY *pkey)
obj = ec_instance(cEC, EC_KEY_new());
} else {
obj = NewPKey(cEC);
if (EVP_PKEY_type(pkey->type) != EVP_PKEY_EC) {
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) {
ossl_raise(rb_eTypeError, "Not a EC key!");
}
SetPKey(obj, pkey);
@ -232,7 +232,7 @@ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
VALUE arg, pass;
GetPKey(self, pkey);
if (pkey->pkey.ec)
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
ossl_raise(eECError, "EC_KEY already initialized");
rb_scan_args(argc, argv, "02", &arg, &pass);

View file

@ -7,19 +7,36 @@
* This program is licensed under the same licence as Ruby.
* (See the file 'LICENCE'.)
*/
#if !defined(OPENSSL_NO_RSA)
#include "ossl.h"
#if !defined(OPENSSL_NO_RSA)
#define GetPKeyRSA(obj, pkey) do { \
GetPKey((obj), (pkey)); \
if (EVP_PKEY_type((pkey)->type) != EVP_PKEY_RSA) { /* PARANOIA? */ \
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA) { /* PARANOIA? */ \
ossl_raise(rb_eRuntimeError, "THIS IS NOT A RSA!") ; \
} \
} while (0)
#define GetRSA(obj, rsa) do { \
EVP_PKEY *_pkey; \
GetPKeyRSA((obj), _pkey); \
(rsa) = EVP_PKEY_get0_RSA(_pkey); \
} while (0)
#define RSA_HAS_PRIVATE(rsa) ((rsa)->p && (rsa)->q)
#define RSA_PRIVATE(obj,rsa) (RSA_HAS_PRIVATE(rsa)||OSSL_PKEY_IS_PRIVATE(obj))
static inline int
RSA_HAS_PRIVATE(RSA *rsa)
{
BIGNUM *p, *q;
RSA_get0_factors(rsa, &p, &q);
return p && q; /* d? why? */
}
static inline int
RSA_PRIVATE(VALUE obj, RSA *rsa)
{
return RSA_HAS_PRIVATE(rsa) || OSSL_PKEY_IS_PRIVATE(obj);
}
/*
* Classes
@ -62,7 +79,7 @@ ossl_rsa_new(EVP_PKEY *pkey)
}
else {
obj = NewPKey(cRSA);
if (EVP_PKEY_type(pkey->type) != EVP_PKEY_RSA) {
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA) {
ossl_raise(rb_eTypeError, "Not a RSA key!");
}
SetPKey(obj, pkey);
@ -262,12 +279,13 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
static VALUE
ossl_rsa_is_public(VALUE self)
{
EVP_PKEY *pkey;
RSA *rsa;
GetPKeyRSA(self, pkey);
GetRSA(self, rsa);
/*
* This method should check for n and e. BUG.
*/
(void)rsa;
return Qtrue;
}
@ -280,11 +298,11 @@ ossl_rsa_is_public(VALUE self)
static VALUE
ossl_rsa_is_private(VALUE self)
{
EVP_PKEY *pkey;
RSA *rsa;
GetPKeyRSA(self, pkey);
GetRSA(self, rsa);
return (RSA_PRIVATE(self, pkey->pkey.rsa)) ? Qtrue : Qfalse;
return RSA_PRIVATE(self, rsa) ? Qtrue : Qfalse;
}
/*
@ -300,12 +318,12 @@ ossl_rsa_is_private(VALUE self)
static VALUE
ossl_rsa_export(int argc, VALUE *argv, VALUE self)
{
EVP_PKEY *pkey;
RSA *rsa;
BIO *out;
const EVP_CIPHER *ciph = NULL;
VALUE cipher, pass, str;
GetPKeyRSA(self, pkey);
GetRSA(self, rsa);
rb_scan_args(argc, argv, "02", &cipher, &pass);
@ -316,14 +334,14 @@ ossl_rsa_export(int argc, VALUE *argv, VALUE self)
if (!(out = BIO_new(BIO_s_mem()))) {
ossl_raise(eRSAError, NULL);
}
if (RSA_HAS_PRIVATE(pkey->pkey.rsa)) {
if (!PEM_write_bio_RSAPrivateKey(out, pkey->pkey.rsa, ciph,
NULL, 0, ossl_pem_passwd_cb, (void *)pass)) {
if (RSA_HAS_PRIVATE(rsa)) {
if (!PEM_write_bio_RSAPrivateKey(out, rsa, ciph, NULL, 0,
ossl_pem_passwd_cb, (void *)pass)) {
BIO_free(out);
ossl_raise(eRSAError, NULL);
}
} else {
if (!PEM_write_bio_RSA_PUBKEY(out, pkey->pkey.rsa)) {
if (!PEM_write_bio_RSA_PUBKEY(out, rsa)) {
BIO_free(out);
ossl_raise(eRSAError, NULL);
}
@ -342,29 +360,29 @@ ossl_rsa_export(int argc, VALUE *argv, VALUE self)
static VALUE
ossl_rsa_to_der(VALUE self)
{
EVP_PKEY *pkey;
RSA *rsa;
int (*i2d_func)_((const RSA*, unsigned char**));
unsigned char *p;
long len;
VALUE str;
GetPKeyRSA(self, pkey);
if(RSA_HAS_PRIVATE(pkey->pkey.rsa))
GetRSA(self, rsa);
if (RSA_HAS_PRIVATE(rsa))
i2d_func = i2d_RSAPrivateKey;
else
i2d_func = (int (*)(const RSA*, unsigned char**))i2d_RSA_PUBKEY;
if((len = i2d_func(pkey->pkey.rsa, NULL)) <= 0)
if((len = i2d_func(rsa, NULL)) <= 0)
ossl_raise(eRSAError, NULL);
str = rb_str_new(0, len);
p = (unsigned char *)RSTRING_PTR(str);
if(i2d_func(pkey->pkey.rsa, &p) < 0)
if(i2d_func(rsa, &p) < 0)
ossl_raise(eRSAError, NULL);
ossl_str_adjust(str, p);
return str;
}
#define ossl_rsa_buf_size(pkey) (RSA_size((pkey)->pkey.rsa)+16)
#define ossl_rsa_buf_size(rsa) (RSA_size(rsa)+16)
/*
* call-seq:
@ -377,20 +395,21 @@ ossl_rsa_to_der(VALUE self)
static VALUE
ossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self)
{
EVP_PKEY *pkey;
RSA *rsa;
BIGNUM *rsa_n;
int buf_len, pad;
VALUE str, buffer, padding;
GetPKeyRSA(self, pkey);
if (!pkey->pkey.rsa->n)
GetRSA(self, rsa);
RSA_get0_key(rsa, &rsa_n, NULL, NULL);
if (!rsa_n)
ossl_raise(eRSAError, "incomplete RSA");
rb_scan_args(argc, argv, "11", &buffer, &padding);
pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
StringValue(buffer);
str = rb_str_new(0, ossl_rsa_buf_size(pkey));
str = rb_str_new(0, ossl_rsa_buf_size(rsa));
buf_len = RSA_public_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
(unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
pad);
(unsigned char *)RSTRING_PTR(str), rsa, pad);
if (buf_len < 0) ossl_raise(eRSAError, NULL);
rb_str_set_len(str, buf_len);
@ -408,20 +427,21 @@ ossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self)
static VALUE
ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self)
{
EVP_PKEY *pkey;
RSA *rsa;
BIGNUM *rsa_n;
int buf_len, pad;
VALUE str, buffer, padding;
GetPKeyRSA(self, pkey);
if (!pkey->pkey.rsa->n)
GetRSA(self, rsa);
RSA_get0_key(rsa, &rsa_n, NULL, NULL);
if (!rsa_n)
ossl_raise(eRSAError, "incomplete RSA");
rb_scan_args(argc, argv, "11", &buffer, &padding);
pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
StringValue(buffer);
str = rb_str_new(0, ossl_rsa_buf_size(pkey));
str = rb_str_new(0, ossl_rsa_buf_size(rsa));
buf_len = RSA_public_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
(unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
pad);
(unsigned char *)RSTRING_PTR(str), rsa, pad);
if (buf_len < 0) ossl_raise(eRSAError, NULL);
rb_str_set_len(str, buf_len);
@ -439,22 +459,23 @@ ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self)
static VALUE
ossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self)
{
EVP_PKEY *pkey;
RSA *rsa;
BIGNUM *rsa_n;
int buf_len, pad;
VALUE str, buffer, padding;
GetPKeyRSA(self, pkey);
if (!pkey->pkey.rsa->n)
GetRSA(self, rsa);
RSA_get0_key(rsa, &rsa_n, NULL, NULL);
if (!rsa_n)
ossl_raise(eRSAError, "incomplete RSA");
if (!RSA_PRIVATE(self, pkey->pkey.rsa))
ossl_raise(eRSAError, "private key needed");
if (!RSA_PRIVATE(self, rsa))
ossl_raise(eRSAError, "private key needed.");
rb_scan_args(argc, argv, "11", &buffer, &padding);
pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
StringValue(buffer);
str = rb_str_new(0, ossl_rsa_buf_size(pkey));
str = rb_str_new(0, ossl_rsa_buf_size(rsa));
buf_len = RSA_private_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
(unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
pad);
(unsigned char *)RSTRING_PTR(str), rsa, pad);
if (buf_len < 0) ossl_raise(eRSAError, NULL);
rb_str_set_len(str, buf_len);
@ -472,22 +493,23 @@ ossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self)
static VALUE
ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self)
{
EVP_PKEY *pkey;
RSA *rsa;
BIGNUM *rsa_n;
int buf_len, pad;
VALUE str, buffer, padding;
GetPKeyRSA(self, pkey);
if (!pkey->pkey.rsa->n)
GetRSA(self, rsa);
RSA_get0_key(rsa, &rsa_n, NULL, NULL);
if (!rsa_n)
ossl_raise(eRSAError, "incomplete RSA");
if (!RSA_PRIVATE(self, pkey->pkey.rsa))
ossl_raise(eRSAError, "private key needed");
if (!RSA_PRIVATE(self, rsa))
ossl_raise(eRSAError, "private key needed.");
rb_scan_args(argc, argv, "11", &buffer, &padding);
pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
StringValue(buffer);
str = rb_str_new(0, ossl_rsa_buf_size(pkey));
str = rb_str_new(0, ossl_rsa_buf_size(rsa));
buf_len = RSA_private_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
(unsigned char *)RSTRING_PTR(str), pkey->pkey.rsa,
pad);
(unsigned char *)RSTRING_PTR(str), rsa, pad);
if (buf_len < 0) ossl_raise(eRSAError, NULL);
rb_str_set_len(str, buf_len);
@ -508,21 +530,24 @@ ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self)
static VALUE
ossl_rsa_get_params(VALUE self)
{
EVP_PKEY *pkey;
RSA *rsa;
VALUE hash;
BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
GetPKeyRSA(self, pkey);
GetRSA(self, rsa);
RSA_get0_key(rsa, &n, &e, &d);
RSA_get0_factors(rsa, &p, &q);
RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
hash = rb_hash_new();
rb_hash_aset(hash, rb_str_new2("n"), ossl_bn_new(pkey->pkey.rsa->n));
rb_hash_aset(hash, rb_str_new2("e"), ossl_bn_new(pkey->pkey.rsa->e));
rb_hash_aset(hash, rb_str_new2("d"), ossl_bn_new(pkey->pkey.rsa->d));
rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(pkey->pkey.rsa->p));
rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(pkey->pkey.rsa->q));
rb_hash_aset(hash, rb_str_new2("dmp1"), ossl_bn_new(pkey->pkey.rsa->dmp1));
rb_hash_aset(hash, rb_str_new2("dmq1"), ossl_bn_new(pkey->pkey.rsa->dmq1));
rb_hash_aset(hash, rb_str_new2("iqmp"), ossl_bn_new(pkey->pkey.rsa->iqmp));
rb_hash_aset(hash, rb_str_new2("n"), ossl_bn_new(n));
rb_hash_aset(hash, rb_str_new2("e"), ossl_bn_new(e));
rb_hash_aset(hash, rb_str_new2("d"), ossl_bn_new(d));
rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(p));
rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(q));
rb_hash_aset(hash, rb_str_new2("dmp1"), ossl_bn_new(dmp1));
rb_hash_aset(hash, rb_str_new2("dmq1"), ossl_bn_new(dmq1));
rb_hash_aset(hash, rb_str_new2("iqmp"), ossl_bn_new(iqmp));
return hash;
}
@ -540,15 +565,15 @@ ossl_rsa_get_params(VALUE self)
static VALUE
ossl_rsa_to_text(VALUE self)
{
EVP_PKEY *pkey;
RSA *rsa;
BIO *out;
VALUE str;
GetPKeyRSA(self, pkey);
GetRSA(self, rsa);
if (!(out = BIO_new(BIO_s_mem()))) {
ossl_raise(eRSAError, NULL);
}
if (!RSA_print(out, pkey->pkey.rsa, 0)) { /* offset = 0 */
if (!RSA_print(out, rsa, 0)) { /* offset = 0 */
BIO_free(out);
ossl_raise(eRSAError, NULL);
}
@ -572,7 +597,7 @@ ossl_rsa_to_public_key(VALUE self)
GetPKeyRSA(self, pkey);
/* err check performed by rsa_instance */
rsa = RSAPublicKey_dup(pkey->pkey.rsa);
rsa = RSAPublicKey_dup(EVP_PKEY_get0_RSA(pkey));
obj = rsa_instance(CLASS_OF(self), rsa);
if (obj == Qfalse) {
RSA_free(rsa);
@ -587,11 +612,11 @@ ossl_rsa_to_public_key(VALUE self)
static VALUE
ossl_rsa_blinding_on(VALUE self)
{
EVP_PKEY *pkey;
RSA *rsa;
GetPKeyRSA(self, pkey);
GetRSA(self, rsa);
if (RSA_blinding_on(pkey->pkey.rsa, ossl_bn_ctx) != 1) {
if (RSA_blinding_on(rsa, ossl_bn_ctx) != 1) {
ossl_raise(eRSAError, NULL);
}
return self;
@ -600,23 +625,18 @@ ossl_rsa_blinding_on(VALUE self)
static VALUE
ossl_rsa_blinding_off(VALUE self)
{
EVP_PKEY *pkey;
RSA *rsa;
GetPKeyRSA(self, pkey);
RSA_blinding_off(pkey->pkey.rsa);
GetRSA(self, rsa);
RSA_blinding_off(rsa);
return self;
}
*/
OSSL_PKEY_BN(rsa, n)
OSSL_PKEY_BN(rsa, e)
OSSL_PKEY_BN(rsa, d)
OSSL_PKEY_BN(rsa, p)
OSSL_PKEY_BN(rsa, q)
OSSL_PKEY_BN(rsa, dmp1)
OSSL_PKEY_BN(rsa, dmq1)
OSSL_PKEY_BN(rsa, iqmp)
OSSL_PKEY_BN_DEF3(rsa, RSA, key, n, e, d);
OSSL_PKEY_BN_DEF2(rsa, RSA, factors, p, q);
OSSL_PKEY_BN_DEF3(rsa, RSA, crt_params, dmp1, dmq1, iqmp);
/*
* INIT
@ -675,6 +695,9 @@ Init_ossl_rsa(void)
DEF_OSSL_PKEY_BN(cRSA, rsa, dmp1);
DEF_OSSL_PKEY_BN(cRSA, rsa, dmq1);
DEF_OSSL_PKEY_BN(cRSA, rsa, iqmp);
rb_define_method(cRSA, "set_key", ossl_rsa_set_key, 3);
rb_define_method(cRSA, "set_factors", ossl_rsa_set_factors, 2);
rb_define_method(cRSA, "set_crt_params", ossl_rsa_set_crt_params, 3);
rb_define_method(cRSA, "params", ossl_rsa_get_params, 0);

View file

@ -258,7 +258,7 @@ ossl_call_tmp_dh_callback(VALUE args)
if (NIL_P(cb)) return Qfalse;
dh = rb_apply(cb, rb_intern("call"), args);
pkey = GetPKeyPtr(dh);
if (EVP_PKEY_type(pkey->type) != EVP_PKEY_DH) return Qfalse;
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) return Qfalse;
return dh;
}
@ -276,7 +276,7 @@ ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength)
if (!RTEST(dh)) return NULL;
ossl_ssl_set_tmp_dh(rb_ssl, dh);
return GetPKeyPtr(dh)->pkey.dh;
return EVP_PKEY_get0_DH(GetPKeyPtr(dh));
}
#endif /* OPENSSL_NO_DH */
@ -292,7 +292,7 @@ ossl_call_tmp_ecdh_callback(VALUE args)
if (NIL_P(cb)) return Qfalse;
ecdh = rb_apply(cb, rb_intern("call"), args);
pkey = GetPKeyPtr(ecdh);
if (EVP_PKEY_type(pkey->type) != EVP_PKEY_EC) return Qfalse;
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) return Qfalse;
return ecdh;
}
@ -310,7 +310,7 @@ ossl_tmp_ecdh_callback(SSL *ssl, int is_export, int keylength)
if (!RTEST(ecdh)) return NULL;
ossl_ssl_set_tmp_ecdh(rb_ssl, ecdh);
return GetPKeyPtr(ecdh)->pkey.ec;
return EVP_PKEY_get0_EC_KEY(GetPKeyPtr(ecdh));
}
#endif

View file

@ -20,8 +20,6 @@ AQjjxMXhwULlmuR/K+WwlaZPiLIBYalLAZQ7ZbOPeVkJ8ePao0eLAgEC
-----END DH PARAMETERS-----
_end_of_pem_
TEST_KEY_DH1024.priv_key = OpenSSL::BN.new("48561834C67E65FFD2A9B47F41E5E78FDC95C387428FDB1E4B0188B64D1643C3A8D3455B945B7E8C4D166010C7C2CE23BFB9BEF43D0348FE7FA5284B0225E7FE1537546D114E3D8A4411B9B9351AB451E1A358F50ED61B1F00DA29336EEBBD649980AC86D76AF8BBB065298C2052672EEF3EF13AB47A15275FC2836F3AC74CEA", 16)
end
config = Hash.new

View file

@ -19,8 +19,6 @@ AQjjxMXhwULlmuR/K+WwlaZPiLIBYalLAZQ7ZbOPeVkJ8ePao0eLAgEC
-----END DH PARAMETERS-----
_end_of_pem_
TEST_KEY_DH1024.priv_key = OpenSSL::BN.new("48561834C67E65FFD2A9B47F41E5E78FDC95C387428FDB1E4B0188B64D1643C3A8D3455B945B7E8C4D166010C7C2CE23BFB9BEF43D0348FE7FA5284B0225E7FE1537546D114E3D8A4411B9B9351AB451E1A358F50ED61B1F00DA29336EEBBD649980AC86D76AF8BBB065298C2052672EEF3EF13AB47A15275FC2836F3AC74CEA", 16)
end
config = Hash.new

View file

@ -105,7 +105,8 @@ AQjjxMXhwULlmuR/K+WwlaZPiLIBYalLAZQ7ZbOPeVkJ8ePao0eLAgEC
-----END DH PARAMETERS-----
_end_of_pem_
TEST_KEY_DH1024.priv_key = OpenSSL::BN.new("48561834C67E65FFD2A9B47F41E5E78FDC95C387428FDB1E4B0188B64D1643C3A8D3455B945B7E8C4D166010C7C2CE23BFB9BEF43D0348FE7FA5284B0225E7FE1537546D114E3D8A4411B9B9351AB451E1A358F50ED61B1F00DA29336EEBBD649980AC86D76AF8BBB065298C2052672EEF3EF13AB47A15275FC2836F3AC74CEA", 16)
TEST_KEY_DH1024.set_key(OpenSSL::BN.new("556AF1598AE69899867CEBA9F29CE4862B884C2B43C9019EA0231908F6EFA785E3C462A6ECB16DF676866E997FFB72B487DC7967C58C3CA38CE974473BF19B2AA5DCBF102735572EBA6F353F6F0BBE7FF1DE1B07FE1381A355C275C33405004317F9491B5955F191F6615A63B30E55A027FB88A1A4B25608E09EEE68A7DF32D", 16),
OpenSSL::BN.new("48561834C67E65FFD2A9B47F41E5E78FDC95C387428FDB1E4B0188B64D1643C3A8D3455B945B7E8C4D166010C7C2CE23BFB9BEF43D0348FE7FA5284B0225E7FE1537546D114E3D8A4411B9B9351AB451E1A358F50ED61B1F00DA29336EEBBD649980AC86D76AF8BBB065298C2052672EEF3EF13AB47A15275FC2836F3AC74CEA", 16))
DSA_SIGNATURE_DIGEST = OpenSSL::OPENSSL_VERSION_NUMBER > 0x10000000 ?
OpenSSL::Digest::SHA1 :

View file

@ -81,7 +81,6 @@ gems:
# Generated via:
# x = OpenSSL::PKey::DH.new(2048) # wait a while...
# x.to_s => pem
# x.priv_key.to_s => hex for OpenSSL::BN.new
TEST_KEY_DH2048 = OpenSSL::PKey::DH.new <<-_end_of_pem_
-----BEGIN DH PARAMETERS-----
MIIBCAKCAQEA3Ze2EHSfYkZLUn557torAmjBgPsqzbodaRaGZtgK1gEU+9nNJaFV
@ -93,17 +92,6 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
-----END DH PARAMETERS-----
_end_of_pem_
TEST_KEY_DH2048.priv_key = OpenSSL::BN.new("108911488509734781344423639" \
"5585749502236089033416160524030987005037540379474123441273555416835" \
"4725688238369352738266590757370603937618499698665047757588998555345" \
"3446251978586372525530219375408331096098220027413238477359960428372" \
"0195464393332338164504352015535549496585792320286513563739305843396" \
"9294344974028713065472959376197728193162272314514335882399554394661" \
"5306385003430991221886779612878793446851681835397455333989268503748" \
"7862488679178398716189205737442996155432191656080664090596502674943" \
"7902481557157485795980326766117882761941455140582265347052939604724" \
"964857770053363840471912215799994973597613931991572884", 16)
def setup
@proxies = %w[https_proxy http_proxy HTTP_PROXY http_proxy_user HTTP_PROXY_USER http_proxy_pass HTTP_PROXY_PASS no_proxy NO_PROXY]
@old_proxies = @proxies.map {|k| ENV[k] }