ruby/SOURCES/ruby-3.0-support-openssl-3....

2135 lines
71 KiB
Diff

From d963d4e276658d110bcb796722d76efa7fb68efa Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Tue, 13 Jun 2017 23:39:41 +0900
Subject: [PATCH] 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.
---
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
index 7ba7b37..3982b9c 100644
--- a/ext/openssl/ossl_pkey.c
+++ b/ext/openssl/ossl_pkey.c
@@ -140,6 +140,35 @@ ossl_pkey_new(EVP_PKEY *pkey)
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:
* OpenSSL::PKey.read(string [, pwd ]) -> PKey
@@ -164,29 +193,14 @@ ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
VALUE data, pass;
rb_scan_args(argc, argv, "11", &data, &pass);
- pass = ossl_pem_passwd_value(pass);
bio = ossl_obj2bio(&data);
- if ((pkey = d2i_PrivateKey_bio(bio, NULL)))
- 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;
+ pkey = ossl_pkey_read_generic(bio, ossl_pem_passwd_value(pass));
BIO_free(bio);
- ossl_raise(ePKeyError, "Could not parse PKey");
+ if (!pkey)
+ ossl_raise(ePKeyError, "Could not parse PKey");
-ok:
BIO_free(bio);
return ossl_pkey_new(pkey);
}
diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h
index e363a261..895927e3 100644
--- a/ext/openssl/ossl_pkey.h
+++ b/ext/openssl/ossl_pkey.h
@@ -45,6 +45,7 @@ void ossl_generate_cb_stop(void *ptr);
VALUE ossl_pkey_new(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 *DupPKeyPtr(VALUE);
EVP_PKEY *GetPrivPKeyPtr(VALUE);
diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c
index 431c20e..faa3dd6 100644
--- a/ext/openssl/ossl_pkey_dsa.c
+++ b/ext/openssl/ossl_pkey_dsa.c
@@ -213,24 +213,24 @@ static VALUE
ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
{
EVP_PKEY *pkey;
- DSA *dsa;
+ DSA *dsa = NULL;
BIO *in;
VALUE arg, pass;
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();
+ if (!dsa)
+ ossl_raise(eDSAError, "DSA_new");
}
- else if (RB_INTEGER_TYPE_P(arg)) {
- if (!(dsa = dsa_generate(NUM2INT(arg)))) {
- ossl_raise(eDSAError, NULL);
- }
+ else if (argc == 1 && RB_INTEGER_TYPE_P(arg)) {
+ dsa = dsa_generate(NUM2INT(arg));
}
else {
pass = ossl_pem_passwd_value(pass);
arg = ossl_to_der_if_possible(arg);
in = ossl_obj2bio(&arg);
- dsa = PEM_read_bio_DSAPrivateKey(in, NULL, ossl_pem_passwd_cb, (void *)pass);
if (!dsa) {
OSSL_BIO_reset(in);
dsa = PEM_read_bio_DSA_PUBKEY(in, NULL, NULL, NULL);
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c
index aec9d1e6..ca8f5c6e 100644
--- a/ext/openssl/ossl_pkey_ec.c
+++ b/ext/openssl/ossl_pkey_ec.c
@@ -202,24 +202,17 @@ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
} else if (rb_obj_is_kind_of(arg, cEC_GROUP)) {
ec = ec_key_new_from_group(arg);
} else {
- BIO *in;
-
- pass = ossl_pem_passwd_value(pass);
- in = ossl_obj2bio(&arg);
-
- ec = PEM_read_bio_ECPrivateKey(in, NULL, ossl_pem_passwd_cb, (void *)pass);
- if (!ec) {
- OSSL_BIO_reset(in);
- ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, (void *)pass);
- }
- 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 *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) {
diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c
index 6a57238..41844e5 100644
--- a/ext/openssl/ossl_pkey_rsa.c
+++ b/ext/openssl/ossl_pkey_rsa.c
@@ -226,7 +226,8 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
VALUE arg, pass;
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();
}
else if (RB_INTEGER_TYPE_P(arg)) {
@@ -265,6 +266,7 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
}
if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
RSA_free(rsa);
+ ossl_clear_error();
ossl_raise(eRSAError, NULL);
}
From c2bb3f5411441b0dbe3085e1825d8479baef6ee4 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Sat, 22 Feb 2020 05:37:01 +0900
Subject: [PATCH 01/21] ts: use TS_VERIFY_CTX_set_certs instead of
TS_VERIFY_CTS_set_certs
OpenSSL 3.0 fixed the typo in the function name and replaced the
current 'CTS' version with a macro.
---
ext/openssl/extconf.rb | 5 ++++-
ext/openssl/openssl_missing.h | 5 +++++
ext/openssl/ossl_ts.c | 2 +-
3 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
index 5cb28f30..ea384fe9 100644
--- a/ext/openssl/extconf.rb
+++ b/ext/openssl/extconf.rb
@@ -169,13 +169,16 @@ def find_openssl_library
have_func("TS_STATUS_INFO_get0_status")
have_func("TS_STATUS_INFO_get0_text")
have_func("TS_STATUS_INFO_get0_failure_info")
-have_func("TS_VERIFY_CTS_set_certs")
+have_func("TS_VERIFY_CTS_set_certs(NULL, NULL)", "openssl/ts.h") # became a macro in 3.0.0
have_func("TS_VERIFY_CTX_set_store")
have_func("TS_VERIFY_CTX_add_flags")
have_func("TS_RESP_CTX_set_time_cb")
have_func("EVP_PBE_scrypt")
have_func("SSL_CTX_set_post_handshake_auth")
+# added in 3.0.0
+have_func("TS_VERIFY_CTX_set_certs(NULL, NULL)", "openssl/ts.h")
+
Logging::message "=== Checking done. ===\n"
create_header
diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h
index 4d9b8801..1b1a54a8 100644
--- a/ext/openssl/openssl_missing.h
+++ b/ext/openssl/openssl_missing.h
@@ -254,4 +254,9 @@ IMPL_PKEY_GETTER(EC_KEY, ec)
} while (0)
#endif
+/* added in 3.0.0 */
+#if !defined(HAVE_TS_VERIFY_CTX_SET_CERTS)
+# define TS_VERIFY_CTX_set_certs(ctx, crts) TS_VERIFY_CTS_set_certs(ctx, crts)
+#endif
+
#endif /* _OSSL_OPENSSL_MISSING_H_ */
diff --git a/ext/openssl/ossl_ts.c b/ext/openssl/ossl_ts.c
index 4654babf..9d91710a 100644
--- a/ext/openssl/ossl_ts.c
+++ b/ext/openssl/ossl_ts.c
@@ -816,7 +816,7 @@ ossl_ts_resp_verify(int argc, VALUE *argv, VALUE self)
X509_up_ref(cert);
}
- TS_VERIFY_CTS_set_certs(ctx, x509inter);
+ TS_VERIFY_CTX_set_certs(ctx, x509inter);
TS_VERIFY_CTX_add_flags(ctx, TS_VFY_SIGNATURE);
TS_VERIFY_CTX_set_store(ctx, x509st);
From 5780e43ceda843c38dc1493a81d8ef8615b2a42b Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Sat, 22 Feb 2020 05:47:58 +0900
Subject: [PATCH 02/21] ssl: use SSL_CTX_load_verify_{file,dir}() if available
SSL_CTX_load_verify_locations() is deprecated in OpenSSL 3.0 and
replaced with those two separate functions. Use them if they exist.
---
ext/openssl/extconf.rb | 1 +
ext/openssl/ossl_ssl.c | 7 +++++++
2 files changed, 8 insertions(+)
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
index ea384fe9..4b5ffd67 100644
--- a/ext/openssl/extconf.rb
+++ b/ext/openssl/extconf.rb
@@ -178,6 +178,7 @@ def find_openssl_library
# added in 3.0.0
have_func("TS_VERIFY_CTX_set_certs(NULL, NULL)", "openssl/ts.h")
+have_func("SSL_CTX_load_verify_file")
Logging::message "=== Checking done. ===\n"
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index 76db821e..c80c939e 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -886,10 +886,17 @@ ossl_sslctx_setup(VALUE self)
ca_file = NIL_P(val) ? NULL : StringValueCStr(val);
val = rb_attr_get(self, id_i_ca_path);
ca_path = NIL_P(val) ? NULL : StringValueCStr(val);
+#if defined(HAVE_SSL_CTX_LOAD_VERIFY_FILE)
+ if (ca_file && !SSL_CTX_load_verify_file(ctx, ca_file))
+ ossl_raise(eSSLError, "SSL_CTX_load_verify_file");
+ if (ca_path && !SSL_CTX_load_verify_dir(ctx, ca_path))
+ ossl_raise(eSSLError, "SSL_CTX_load_verify_dir");
+#else
if(ca_file || ca_path){
if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
rb_warning("can't set verify locations");
}
+#endif
val = rb_attr_get(self, id_i_verify_mode);
verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val);
From c26272113074bfe3ebbc698741974fce86b1c25a Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Sat, 22 Feb 2020 06:37:00 +0900
Subject: [PATCH 03/21] bn: use BN_check_prime() in
OpenSSL::BN#prime{,_fasttest}?
BN_is_prime_ex() and BN_is_prime_fasttest_ex() are deprecated in OpenSSL
3.0. Instead, BN_check_prime() is added. This is equivalent to
BN_is_prime_fasttest_ex(bn, 0, bn_ctx, 1, cb), which is what
OpenSSL::BN#prime_fasttest? has called.
Let's make both OpenSSL::BN#prime? and #prime_fasttest? use
BN_check_prime() if available. Note that this implies that the
parameters of those two methods are now ignored, which could be used to
tune them to give up the test earlier.
---
ext/openssl/extconf.rb | 1 +
ext/openssl/ossl_bn.c | 71 +++++++++++++-----------------------------
2 files changed, 23 insertions(+), 49 deletions(-)
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
index 4b5ffd67..9fa092f5 100644
--- a/ext/openssl/extconf.rb
+++ b/ext/openssl/extconf.rb
@@ -179,6 +179,7 @@ def find_openssl_library
# added in 3.0.0
have_func("TS_VERIFY_CTX_set_certs(NULL, NULL)", "openssl/ts.h")
have_func("SSL_CTX_load_verify_file")
+have_func("BN_check_prime")
Logging::message "=== Checking done. ===\n"
diff --git a/ext/openssl/ossl_bn.c b/ext/openssl/ossl_bn.c
index 02530789..e0eef4cd 100644
--- a/ext/openssl/ossl_bn.c
+++ b/ext/openssl/ossl_bn.c
@@ -1058,34 +1058,29 @@ ossl_bn_hash(VALUE self)
* bn.prime? => true | false
* bn.prime?(checks) => true | false
*
- * Performs a Miller-Rabin probabilistic primality test with _checks_
- * iterations. If _checks_ is not specified, a number of iterations is used
- * that yields a false positive rate of at most 2^-80 for random input.
+ * Performs Miller-Rabin primality test for _bn_.
*
- * === Parameters
- * * _checks_ - integer
+ * As of Ruby/OpenSSL 2.3.0, the argument _checks_ is ignored.
*/
static VALUE
ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)
{
BIGNUM *bn;
- VALUE vchecks;
- int checks = BN_prime_checks;
+ int ret;
- if (rb_scan_args(argc, argv, "01", &vchecks) == 1) {
- checks = NUM2INT(vchecks);
- }
+ rb_check_arity(argc, 0, 1);
GetBN(self, bn);
- switch (BN_is_prime_ex(bn, checks, ossl_bn_ctx, NULL)) {
- case 1:
- return Qtrue;
- case 0:
- return Qfalse;
- default:
- ossl_raise(eBNError, NULL);
- }
- /* not reachable */
- return Qnil;
+
+#if defined(HAVE_BN_CHECK_PRIME)
+ ret = BN_check_prime(bn, ossl_bn_ctx, NULL);
+ if (ret < 0)
+ ossl_raise(eBNError, "BN_check_prime");
+#else
+ ret = BN_is_prime_fasttest_ex(bn, BN_prime_checks, ossl_bn_ctx, 1, NULL);
+ if (ret < 0)
+ ossl_raise(eBNError, "BN_is_prime_fasttest_ex");
+#endif
+ return ret ? Qtrue : Qfalse;
}
/*
@@ -1094,40 +1089,18 @@ ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)
* bn.prime_fasttest?(checks) => true | false
* bn.prime_fasttest?(checks, trial_div) => true | false
*
- * Performs a Miller-Rabin primality test. This is same as #prime? except this
- * first attempts trial divisions with some small primes.
+ * Performs Miller-Rabin primality test for _bn_. This is an alias of #prime?.
*
- * === Parameters
- * * _checks_ - integer
- * * _trial_div_ - boolean
+ * This method is deprecated. Use #prime? instead.
+ *
+ * As of Ruby/OpenSSL 2.3.0, the arguments _checks_ and _trial\_div_ are
+ * ignored.
*/
static VALUE
ossl_bn_is_prime_fasttest(int argc, VALUE *argv, VALUE self)
{
- BIGNUM *bn;
- VALUE vchecks, vtrivdiv;
- int checks = BN_prime_checks, do_trial_division = 1;
-
- rb_scan_args(argc, argv, "02", &vchecks, &vtrivdiv);
-
- if (!NIL_P(vchecks)) {
- checks = NUM2INT(vchecks);
- }
- GetBN(self, bn);
- /* handle true/false */
- if (vtrivdiv == Qfalse) {
- do_trial_division = 0;
- }
- switch (BN_is_prime_fasttest_ex(bn, checks, ossl_bn_ctx, do_trial_division, NULL)) {
- case 1:
- return Qtrue;
- case 0:
- return Qfalse;
- default:
- ossl_raise(eBNError, NULL);
- }
- /* not reachable */
- return Qnil;
+ rb_check_arity(argc, 0, 2);
+ return ossl_bn_is_prime(0, argv, self);
}
/*
From 1fdea13743e5ee70befdfc79f22473b88ffe2eef Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Sat, 22 Feb 2020 18:58:29 +0900
Subject: [PATCH 04/21] ossl.c: use ERR_get_error_all() if available
OpenSSL 3.0 deprecated ERR_get_error_line_data() in favor of
ERR_get_error_all(), as part of the error queue structure changes.
---
ext/openssl/extconf.rb | 1 +
ext/openssl/ossl.c | 40 +++++++++++++++++++++-------------------
2 files changed, 22 insertions(+), 19 deletions(-)
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
index 9fa092f5..14e599ca 100644
--- a/ext/openssl/extconf.rb
+++ b/ext/openssl/extconf.rb
@@ -180,6 +180,7 @@ def find_openssl_library
have_func("TS_VERIFY_CTX_set_certs(NULL, NULL)", "openssl/ts.h")
have_func("SSL_CTX_load_verify_file")
have_func("BN_check_prime")
+have_func("ERR_get_error_all")
Logging::message "=== Checking done. ===\n"
diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c
index 358b3b29..a040deae 100644
--- a/ext/openssl/ossl.c
+++ b/ext/openssl/ossl.c
@@ -304,27 +304,29 @@ void
ossl_clear_error(void)
{
if (dOSSL == Qtrue) {
- unsigned long e;
- const char *file, *data, *errstr;
- int line, flags;
-
- while ((e = ERR_get_error_line_data(&file, &line, &data, &flags))) {
- errstr = ERR_error_string(e, NULL);
- if (!errstr)
- errstr = "(null)";
-
- if (flags & ERR_TXT_STRING) {
- if (!data)
- data = "(null)";
- rb_warn("error on stack: %s (%s)", errstr, data);
- }
- else {
- rb_warn("error on stack: %s", errstr);
- }
- }
+ unsigned long e;
+ const char *file, *data;
+ int line, flags;
+
+#if defined(HAVE_ERR_GET_ERROR_ALL)
+ const char *func;
+ while ((e = ERR_get_error_all(&file, &line, &func, &data, &flags))) {
+#else
+ while ((e = ERR_get_error_line_data(&file, &line, &data, &flags))) {
+ const char *func = ERR_func_error_string(e);
+#endif
+ const char *lib = ERR_lib_error_string(e),
+ *reason = ERR_reason_error_string(e);
+ char append[256] = "";
+
+ if (flags & ERR_TXT_STRING && data && strlen(data))
+ snprintf(append, sizeof(append), " (%s)", data);
+ rb_warn("error on stack: error:%08lX:%s:%s:%s%s", e, lib ? lib : "",
+ func ? func : "", reason ? reason : "", append);
+ }
}
else {
- ERR_clear_error();
+ ERR_clear_error();
}
}
From ce0bf33dd0c5a2ba3d445ccf00175db91d78b5a7 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Sun, 17 May 2020 18:25:38 +0900
Subject: [PATCH 05/21] pkey: implement #to_text using EVP API
Use EVP_PKEY_print_private() instead of the low level *_print()
functions. Those low level functions are deprecated in OpenSSL 3.0.
Note that it falls back to EVP_PKEY_print_public() and
EVP_PKEY_print_params() as necessary. This is required for EVP_PKEY_DH
type - _private() fails if the private component is not set.
Since the new API works in the same way for all key types, we now
implement #to_text in the base class OpenSSL::PKey::PKey rather than in
each subclass.
---
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
index 0540cd2..e02c84b 100644
--- a/ext/openssl/ossl_pkey.c
+++ b/ext/openssl/ossl_pkey.c
@@ -349,6 +349,42 @@ ossl_pkey_inspect(VALUE self)
OBJ_nid2sn(nid));
}
+/*
+ * call-seq:
+ * pkey.to_text -> string
+ *
+ * THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!!
+ *
+ * Dumps all private, public, and parameter components of the key to a String
+ * in a human readable format.
+ */
+static VALUE
+ossl_pkey_to_text(VALUE self)
+{
+ EVP_PKEY *pkey;
+ BIO *bio;
+
+ GetPKey(self, pkey);
+ if (!(bio = BIO_new(BIO_s_mem())))
+ ossl_raise(ePKeyError, "BIO_new");
+
+ if (EVP_PKEY_print_private(bio, pkey, 0, NULL) == 1)
+ goto out;
+ OSSL_BIO_reset(bio);
+ if (EVP_PKEY_print_public(bio, pkey, 0, NULL) == 1)
+ goto out;
+ OSSL_BIO_reset(bio);
+ if (EVP_PKEY_print_params(bio, pkey, 0, NULL) == 1)
+ goto out;
+
+ BIO_free(bio);
+ ossl_raise(ePKeyError, "EVP_PKEY_print_params");
+
+ out:
+ return ossl_membio2str(bio);
+}
+
+
static VALUE
do_pkcs8_export(int argc, VALUE *argv, VALUE self, int to_der)
{
diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c
index 6b477b07..acd3bf47 100644
--- a/ext/openssl/ossl_pkey_dh.c
+++ b/ext/openssl/ossl_pkey_dh.c
@@ -403,34 +403,6 @@ ossl_dh_get_params(VALUE self)
return hash;
}
-/*
- * call-seq:
- * dh.to_text -> aString
- *
- * Prints all parameters of key to buffer
- * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!
- * Don't use :-)) (I's up to you)
- */
-static VALUE
-ossl_dh_to_text(VALUE self)
-{
- DH *dh;
- BIO *out;
- VALUE str;
-
- GetDH(self, dh);
- if (!(out = BIO_new(BIO_s_mem()))) {
- ossl_raise(eDHError, NULL);
- }
- if (!DHparams_print(out, dh)) {
- BIO_free(out);
- ossl_raise(eDHError, NULL);
- }
- str = ossl_membio2str(out);
-
- return str;
-}
-
/*
* call-seq:
* dh.public_key -> aDH
@@ -621,7 +593,6 @@ Init_ossl_dh(void)
rb_define_method(cDH, "initialize_copy", ossl_dh_initialize_copy, 1);
rb_define_method(cDH, "public?", ossl_dh_is_public, 0);
rb_define_method(cDH, "private?", ossl_dh_is_private, 0);
- rb_define_method(cDH, "to_text", ossl_dh_to_text, 0);
rb_define_method(cDH, "export", ossl_dh_export, 0);
rb_define_alias(cDH, "to_pem", "export");
rb_define_alias(cDH, "to_s", "export");
diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c
index c2b68c32..640a243d 100644
--- a/ext/openssl/ossl_pkey_dsa.c
+++ b/ext/openssl/ossl_pkey_dsa.c
@@ -433,34 +433,6 @@ ossl_dsa_get_params(VALUE self)
return hash;
}
-/*
- * call-seq:
- * dsa.to_text -> aString
- *
- * Prints all parameters of key to buffer
- * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!
- * Don't use :-)) (I's up to you)
- */
-static VALUE
-ossl_dsa_to_text(VALUE self)
-{
- DSA *dsa;
- BIO *out;
- VALUE str;
-
- GetDSA(self, dsa);
- if (!(out = BIO_new(BIO_s_mem()))) {
- ossl_raise(eDSAError, NULL);
- }
- if (!DSA_print(out, dsa, 0)) { /* offset = 0 */
- BIO_free(out);
- ossl_raise(eDSAError, NULL);
- }
- str = ossl_membio2str(out);
-
- return str;
-}
-
/*
* call-seq:
* dsa.public_key -> aDSA
@@ -636,7 +608,6 @@ Init_ossl_dsa(void)
rb_define_method(cDSA, "public?", ossl_dsa_is_public, 0);
rb_define_method(cDSA, "private?", ossl_dsa_is_private, 0);
- rb_define_method(cDSA, "to_text", ossl_dsa_to_text, 0);
rb_define_method(cDSA, "export", ossl_dsa_export, -1);
rb_define_alias(cDSA, "to_pem", "export");
rb_define_alias(cDSA, "to_s", "export");
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c
index 511e728..aa59c68 100644
--- a/ext/openssl/ossl_pkey_ec.c
+++ b/ext/openssl/ossl_pkey_ec.c
@@ -506,31 +506,6 @@ static VALUE ossl_ec_key_to_der(VALUE self)
return ossl_ec_key_to_string(self, Qnil, Qnil, EXPORT_DER);
}
-/*
- * call-seq:
- * key.to_text => String
- *
- * See the OpenSSL documentation for EC_KEY_print()
- */
-static VALUE ossl_ec_key_to_text(VALUE self)
-{
- EC_KEY *ec;
- BIO *out;
- VALUE str;
-
- GetEC(self, ec);
- if (!(out = BIO_new(BIO_s_mem()))) {
- ossl_raise(eECError, "BIO_new(BIO_s_mem())");
- }
- if (!EC_KEY_print(out, ec, 0)) {
- BIO_free(out);
- ossl_raise(eECError, "EC_KEY_print");
- }
- str = ossl_membio2str(out);
-
- return str;
-}
-
/*
* call-seq:
* key.generate_key! => self
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c
index aa59c68..1689200 100644
--- a/ext/openssl/ossl_pkey_ec.c
+++ b/ext/openssl/ossl_pkey_ec.c
@@ -1728,8 +1728,6 @@ void Init_ossl_ec(void)
rb_define_method(cEC, "export", ossl_ec_key_export, -1);
rb_define_alias(cEC, "to_pem", "export");
rb_define_method(cEC, "to_der", ossl_ec_key_to_der, 0);
- rb_define_method(cEC, "to_text", ossl_ec_key_to_text, 0);
-
rb_define_alloc_func(cEC_GROUP, ossl_ec_group_alloc);
rb_define_method(cEC_GROUP, "initialize", ossl_ec_group_initialize, -1);
diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c
index 6d337fe7..a522b819 100644
--- a/ext/openssl/ossl_pkey_rsa.c
+++ b/ext/openssl/ossl_pkey_rsa.c
@@ -772,36 +772,6 @@ ossl_rsa_get_params(VALUE self)
return hash;
}
-/*
- * call-seq:
- * rsa.to_text => String
- *
- * THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!!
- *
- * Dumps all parameters of a keypair to a String
- *
- * Don't use :-)) (It's up to you)
- */
-static VALUE
-ossl_rsa_to_text(VALUE self)
-{
- RSA *rsa;
- BIO *out;
- VALUE str;
-
- GetRSA(self, rsa);
- if (!(out = BIO_new(BIO_s_mem()))) {
- ossl_raise(eRSAError, NULL);
- }
- if (!RSA_print(out, rsa, 0)) { /* offset = 0 */
- BIO_free(out);
- ossl_raise(eRSAError, NULL);
- }
- str = ossl_membio2str(out);
-
- return str;
-}
-
/*
* call-seq:
* rsa.public_key -> RSA
@@ -921,7 +891,6 @@ Init_ossl_rsa(void)
rb_define_method(cRSA, "public?", ossl_rsa_is_public, 0);
rb_define_method(cRSA, "private?", ossl_rsa_is_private, 0);
- rb_define_method(cRSA, "to_text", ossl_rsa_to_text, 0);
rb_define_method(cRSA, "export", ossl_rsa_export, -1);
rb_define_alias(cRSA, "to_pem", "export");
rb_define_alias(cRSA, "to_s", "export");
From 73116c78c715a7277cbace7d8595c823d5ef1934 Mon Sep 17 00:00:00 2001
From: Pavel Valena <pvalena@redhat.com>
Date: Thu, 20 May 2021 19:10:20 +0200
Subject: [PATCH] Compatibiblity with gem version 2.2.0
---
ext/openssl/ossl_pkey_rsa.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c
index a928e92..6a57238 100644
--- a/ext/openssl/ossl_pkey_rsa.c
+++ b/ext/openssl/ossl_pkey_rsa.c
@@ -918,7 +918,6 @@ Init_ossl_rsa(void)
rb_define_method(cRSA, "params", ossl_rsa_get_params, 0);
DefRSAConst(PKCS1_PADDING);
- DefRSAConst(SSLV23_PADDING);
DefRSAConst(NO_PADDING);
DefRSAConst(PKCS1_OAEP_PADDING);
--
2.31.1
From b2e3ddab1c5dcda2003bfa9c06c424ac74e3e198 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Sun, 17 May 2020 21:29:48 +0900
Subject: [PATCH 06/21] [WIP] pkey: try to parse algorithm-specific formats
first
FIXME: NON-RSA NEEDS THIS TOO
RSAPublicKey and DHParameters share the same structure: two INTEGERs in
a SEQUENCE. When parsing a DER- encoded data they are indistinguishable.
With OpenSSL 3.0, OpenSSL::PKey.read will parse DER-encoded
DHParameters. However, OpenSSL::PKey::RSA.new naturally wants the data
to be parsed as RSAPublicKey instead when such a structure is given.
So, try PEM_read_bio_RSAPublicKey() and d2i_RSAPublicKey_bio() before
falling back to ossl_pkey_read_generic().
---
ext/openssl/ossl_pkey_dsa.c | 27 +++++++++++++--------------
ext/openssl/ossl_pkey_rsa.c | 32 ++++++++++++++++----------------
diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c
index 29df5b3..60ded1c 100644
--- a/ext/openssl/ossl_pkey_dh.c
+++ b/ext/openssl/ossl_pkey_dh.c
@@ -202,7 +202,7 @@ ossl_dh_s_generate(int argc, VALUE *argv, VALUE klass)
static VALUE
ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
{
- EVP_PKEY *pkey;
+ EVP_PKEY *pkey, *tmp;
DH *dh;
int g = 2;
BIO *in;
@@ -221,14 +221,22 @@ ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
}
}
else {
- arg = ossl_to_der_if_possible(arg);
- in = ossl_obj2bio(&arg);
- dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
- if (!dh){
- OSSL_BIO_reset(in);
- dh = d2i_DHparams_bio(in, NULL);
- }
- BIO_free(in);
+ arg = ossl_to_der_if_possible(arg);
+ in = ossl_obj2bio(&arg);
+
+ dh = d2i_DHparams_bio(in, NULL);
+ if (!dh) {
+ OSSL_BIO_reset(in);
+ tmp = ossl_pkey_read_generic(in, Qnil);
+ if (tmp) {
+ if (EVP_PKEY_base_id(tmp) != EVP_PKEY_DH)
+ rb_raise(eDHError, "incorrect pkey type: %s",
+ OBJ_nid2sn(EVP_PKEY_base_id(tmp)));
+ dh = EVP_PKEY_get1_DH(tmp);
+ EVP_PKEY_free(tmp);
+ }
+ }
+ BIO_free(in);
if (!dh) {
ossl_raise(eDHError, NULL);
}
diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c
index e5a1f04..da58717 100644
--- a/ext/openssl/ossl_pkey_dsa.c
+++ b/ext/openssl/ossl_pkey_dsa.c
@@ -212,7 +212,7 @@ ossl_dsa_s_generate(VALUE klass, VALUE size)
static VALUE
ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
{
- EVP_PKEY *pkey;
+ EVP_PKEY *pkey, *tmp;
DSA *dsa = NULL;
BIO *in;
VALUE arg, pass;
diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c
index b19441c..804b652 100644
--- a/ext/openssl/ossl_pkey_dsa.c
+++ b/ext/openssl/ossl_pkey_dsa.c
@@ -231,25 +231,20 @@ ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
pass = ossl_pem_passwd_value(pass);
arg = ossl_to_der_if_possible(arg);
in = ossl_obj2bio(&arg);
- if (!dsa) {
- OSSL_BIO_reset(in);
- dsa = PEM_read_bio_DSA_PUBKEY(in, NULL, NULL, NULL);
- }
- if (!dsa) {
- OSSL_BIO_reset(in);
- dsa = d2i_DSAPrivateKey_bio(in, NULL);
- }
- if (!dsa) {
- OSSL_BIO_reset(in);
- dsa = d2i_DSA_PUBKEY_bio(in, NULL);
- }
- if (!dsa) {
- 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
- }
+ dsa = (DSA *)PEM_ASN1_read_bio((d2i_of_void *)d2i_DSAPublicKey,
+ PEM_STRING_DSA_PUBLIC, in,
+ NULL, NULL, NULL);
+ if (!dsa) {
+ OSSL_BIO_reset(in);
+ tmp = ossl_pkey_read_generic(in, pass);
+ if (tmp) {
+ if (EVP_PKEY_base_id(tmp) != EVP_PKEY_DSA)
+ rb_raise(eDSAError, "incorrect pkey type: %s",
+ OBJ_nid2sn(EVP_PKEY_base_id(tmp)));
+ dsa = EVP_PKEY_get1_DSA(tmp);
+ EVP_PKEY_free(tmp);
+ }
+ }
BIO_free(in);
if (!dsa) {
ossl_clear_error();
diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c
index 1a82f22..a928e92 100644
--- a/ext/openssl/ossl_pkey_rsa.c
+++ b/ext/openssl/ossl_pkey_rsa.c
@@ -220,7 +220,7 @@ ossl_rsa_s_generate(int argc, VALUE *argv, VALUE klass)
static VALUE
ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
{
- EVP_PKEY *pkey;
+ EVP_PKEY *pkey, *tmp;
RSA *rsa;
BIO *in;
VALUE arg, pass;
@@ -238,28 +238,24 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
pass = ossl_pem_passwd_value(pass);
arg = ossl_to_der_if_possible(arg);
in = ossl_obj2bio(&arg);
- rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ossl_pem_passwd_cb, (void *)pass);
- if (!rsa) {
- OSSL_BIO_reset(in);
- rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);
- }
- if (!rsa) {
- OSSL_BIO_reset(in);
- rsa = d2i_RSAPrivateKey_bio(in, NULL);
- }
- if (!rsa) {
- OSSL_BIO_reset(in);
- rsa = d2i_RSA_PUBKEY_bio(in, NULL);
- }
- if (!rsa) {
- OSSL_BIO_reset(in);
- rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL);
- }
- if (!rsa) {
- OSSL_BIO_reset(in);
- rsa = d2i_RSAPublicKey_bio(in, NULL);
- }
- BIO_free(in);
+
+ rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL);
+ if (!rsa) {
+ OSSL_BIO_reset(in);
+ rsa = d2i_RSAPublicKey_bio(in, NULL);
+ }
+ if (!rsa) {
+ OSSL_BIO_reset(in);
+ tmp = ossl_pkey_read_generic(in, pass);
+ if (tmp) {
+ if (EVP_PKEY_base_id(tmp) != EVP_PKEY_RSA)
+ rb_raise(eRSAError, "incorrect pkey type: %s",
+ OBJ_nid2sn(EVP_PKEY_base_id(tmp)));
+ rsa = EVP_PKEY_get1_RSA(tmp);
+ EVP_PKEY_free(tmp);
+ }
+ }
+ BIO_free(in);
if (!rsa) {
ossl_raise(eRSAError, "Neither PUB key nor PRIV key");
}
From 9f81a082e9aea407f722388397fd87ca75712ff1 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Tue, 30 Jun 2020 16:12:14 +0900
Subject: [PATCH 07/21] pkey/ec: deprecate PKey::EC::Point#make_affine! and
make it no-op
It forces the internal representation of the point object to the affine
coordinate system. However, as the difference of the internal
representation is not visible from Ruby/OpenSSL at all, it had no real
use case.
EC_POINT_make_affine() is marked as deprecated in OpenSSL 3.0.
---
ext/openssl/ossl_pkey_ec.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c
index c3ed21e0..4ab872ee 100644
--- a/ext/openssl/ossl_pkey_ec.c
+++ b/ext/openssl/ossl_pkey_ec.c
@@ -1443,6 +1443,8 @@ static VALUE ossl_ec_point_is_on_curve(VALUE self)
/*
* call-seq:
* point.make_affine! => self
+ *
+ * This method is deprecated and should not be used.
*/
static VALUE ossl_ec_point_make_affine(VALUE self)
{
@@ -1452,8 +1454,12 @@ static VALUE ossl_ec_point_make_affine(VALUE self)
GetECPoint(self, point);
GetECPointGroup(self, group);
+ rb_warn("OpenSSL::PKey::EC::Point#make_affine! is deprecated; " \
+ "the conversion is automatically performed when necessary");
+#if !(OPENSSL_VERSION_MAJOR+0 >= 3)
if (EC_POINT_make_affine(group, point, ossl_bn_ctx) != 1)
ossl_raise(cEC_POINT, "EC_POINT_make_affine");
+#endif
return self;
}
From 9b2009868c523c02a4d695afcaaedad61f9eaba9 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Sat, 22 Feb 2020 05:52:01 +0900
Subject: [PATCH 08/21] pkey/ec: use EC_GROUP_free() instead of
EC_GROUP_clear_free()
EC_GROUP_clear_free() is deprecated in OpenSSL 3.0.
The EC_GROUP does not include any sensitive data, so we can safely use
EC_GROUP_free() instead.
---
ext/openssl/ossl_pkey_ec.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c
index 4ab872ee..e4e4141c 100644
--- a/ext/openssl/ossl_pkey_ec.c
+++ b/ext/openssl/ossl_pkey_ec.c
@@ -638,7 +638,7 @@ static VALUE ossl_ec_key_check_key(VALUE self)
static void
ossl_ec_group_free(void *ptr)
{
- EC_GROUP_clear_free(ptr);
+ EC_GROUP_free(ptr);
}
static const rb_data_type_t ossl_ec_group_type = {
From 92a5cdd545d32cd66c61614c5975afac620de5f9 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Fri, 10 Jul 2020 14:34:51 +0900
Subject: [PATCH 09/21] pkey/dh: let PKey::DH#params_ok? use
EVP_PKEY_param_check()
Use EVP_PKEY_param_check() instead of DH_check() if available. It is
part of the EVP API and is preferred over the lower level API.
EVP_PKEY_param_check() was added by OpenSSL 1.1.1. It is currently not
provided by LibreSSL.
---
ext/openssl/extconf.rb | 3 +++
ext/openssl/ossl_pkey_dh.c | 27 +++++++++++++++++++++++----
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
index 14e599ca..e5b0fb65 100644
--- a/ext/openssl/extconf.rb
+++ b/ext/openssl/extconf.rb
@@ -176,6 +176,9 @@ def find_openssl_library
have_func("EVP_PBE_scrypt")
have_func("SSL_CTX_set_post_handshake_auth")
+# added in 1.1.1
+have_func("EVP_PKEY_param_check")
+
# added in 3.0.0
have_func("TS_VERIFY_CTX_set_certs(NULL, NULL)", "openssl/ts.h")
have_func("SSL_CTX_load_verify_file")
diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c
index 458721e2..a3628572 100644
--- a/ext/openssl/ossl_pkey_dh.c
+++ b/ext/openssl/ossl_pkey_dh.c
@@ -456,19 +456,38 @@ ossl_dh_to_public_key(VALUE self)
* Validates the Diffie-Hellman parameters associated with this instance.
* It checks whether a safe prime and a suitable generator are used. If this
* is not the case, +false+ is returned.
+ *
+ * See also the man page EVP_PKEY_param_check(3).
*/
static VALUE
ossl_dh_check_params(VALUE self)
{
+ int ret;
+#ifdef HAVE_EVP_PKEY_PARAM_CHECK
+ EVP_PKEY *pkey;
+ EVP_PKEY_CTX *pctx;
+
+ GetPKey(self, pkey);
+ pctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL);
+ if (!pctx)
+ ossl_raise(eDHError, "EVP_PKEY_CTX_new");
+ ret = EVP_PKEY_param_check(pctx);
+ EVP_PKEY_CTX_free(pctx);
+#else
DH *dh;
int codes;
GetDH(self, dh);
- if (!DH_check(dh, &codes)) {
- return Qfalse;
- }
+ ret = DH_check(dh, &codes) == 1 && codes == 0;
+#endif
- return codes == 0 ? Qtrue : Qfalse;
+ if (ret == 1)
+ return Qtrue;
+ else {
+ /* DH_check_ex() will put error entry on failure */
+ ossl_clear_error();
+ return Qfalse;
+ }
}
/*
diff --git a/test/openssl/test_pkey_dh.rb b/test/openssl/test_pkey_dh.rb
index fd2c7a6..21a6dbc 100644
--- a/test/openssl/test_pkey_dh.rb
+++ b/test/openssl/test_pkey_dh.rb
@@ -64,6 +64,14 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
assert_equal(dh.compute_key(dh2.pub_key), dh2.compute_key(dh.pub_key))
end
+ def test_params_ok?
+ dh1 = Fixtures.pkey("dh1024")
+ assert_equal(true, dh1.params_ok?)
+
+ dh2 = Fixtures.pkey("dh1024").tap { |p| p.set_pqg(p.p + 1, p.q, p.g) }
+ assert_equal(false, dh2.params_ok?)
+ end
+
def test_dup
dh = OpenSSL::PKey::DH.new(NEW_KEYLEN)
dh2 = dh.dup
From af7aba5955685987409298e7b351d1dc7588b24e Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Mon, 18 May 2020 02:17:28 +0900
Subject: [PATCH 10/21] test/openssl/test_digest: do not test constants for
legacy algorithms
Do not test availability of MD4 and RIPEMD160 as they are considered
legacy and can be missing. OpenSSL 3.0 by default does not enable it.
---
test/openssl/test_digest.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/openssl/test_digest.rb b/test/openssl/test_digest.rb
index 8d7046e8..84c128c1 100644
--- a/test/openssl/test_digest.rb
+++ b/test/openssl/test_digest.rb
@@ -54,7 +54,7 @@ def test_reset
end
def test_digest_constants
- %w{MD4 MD5 RIPEMD160 SHA1 SHA224 SHA256 SHA384 SHA512}.each do |name|
+ %w{MD5 SHA1 SHA224 SHA256 SHA384 SHA512}.each do |name|
assert_not_nil(OpenSSL::Digest.new(name))
klass = OpenSSL::Digest.const_get(name.tr('-', '_'))
assert_not_nil(klass.new)
From 5b7a1bd78278d6f0527501e34b6453fa004aa281 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Fri, 10 Jul 2020 13:56:38 +0900
Subject: [PATCH 11/21] test/openssl/test_ssl: relax regex to match OpenSSL's
error message
OpenSSL 3.0 has slightly changed the error message for a certificate
verification failure when an untrusted self-signed certificate is found.
---
test/openssl/test_ssl.rb | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb
index f24aabe7..6c9547dc 100644
--- a/test/openssl/test_ssl.rb
+++ b/test/openssl/test_ssl.rb
@@ -955,7 +955,9 @@ def test_connect_certificate_verify_failed_exception_message
start_server(ignore_listener_error: true) { |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.set_params
- assert_raise_with_message(OpenSSL::SSL::SSLError, /self signed/) {
+ # OpenSSL <= 1.1.0: "self signed certificate in certificate chain"
+ # OpenSSL >= 3.0.0: "self-signed certificate in certificate chain"
+ assert_raise_with_message(OpenSSL::SSL::SSLError, /self.signed/) {
server_connect(port, ctx)
}
}
From 9b5d8f9698c2cf5c6ac28d3ccf51557a7cd6aa56 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Fri, 10 Jul 2020 14:06:04 +0900
Subject: [PATCH 12/21] test/openssl/test_engine: relax assertions for the
number of engines
It seems loading a specific engine with ENGINE_by_id() can load another
engine too. Just check that OpenSSL::Engine.load call increases the
counter for the engines which are currently loaded.
---
test/openssl/test_engine.rb | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/test/openssl/test_engine.rb b/test/openssl/test_engine.rb
index 1ede6ed0..3caf1fb8 100644
--- a/test/openssl/test_engine.rb
+++ b/test/openssl/test_engine.rb
@@ -18,7 +18,7 @@ def test_openssl_engine_builtin
pend "'openssl' is already loaded" if orig.any? { |e| e.id == "openssl" }
engine = OpenSSL::Engine.load("openssl")
assert_equal(true, engine)
- assert_equal(1, OpenSSL::Engine.engines.size - orig.size)
+ assert_operator(OpenSSL::Engine.engines.size, :>, orig.size)
end;
end
@@ -28,7 +28,7 @@ def test_openssl_engine_by_id_string
pend "'openssl' is already loaded" if orig.any? { |e| e.id == "openssl" }
engine = get_engine
assert_not_nil(engine)
- assert_equal(1, OpenSSL::Engine.engines.size - orig.size)
+ assert_operator(OpenSSL::Engine.engines.size, :>, orig.size)
end;
end
From 74e5ed30f9bae21240e5e2209346fa91ef463393 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Mon, 18 May 2020 02:35:35 +0900
Subject: [PATCH 13/21] test/openssl/test_pkey: use EC keys for testing
PKey.generate_parameters
OpenSSL 3.0 refuses to generate DSA parameters shorter than 2048 bits,
but generating 2048 bits parameters takes very long. Let's use EC in
those test cases instead.
---
test/openssl/test_pkey.rb | 143 ++++++++++++++++++++++++++++++++++++++
1 file changed, 143 insertions(+)
diff --git a/test/openssl/test_pkey.rb b/test/openssl/test_pkey.rb
index 0bdc979..b4ddcfb 100644
--- a/test/openssl/test_pkey.rb
+++ b/test/openssl/test_pkey.rb
@@ -25,4 +25,147 @@ class OpenSSL::TestPKey < OpenSSL::PKeyTestCase
assert_equal "X25519", x25519.oid
assert_match %r{oid=X25519}, x25519.inspect
end
+
+ def test_s_generate_parameters
+ pend "EC is disabled" unless defined?(OpenSSL::PKey::EC)
+
+ pkey = OpenSSL::PKey.generate_parameters("EC", {
+ "ec_paramgen_curve" => "secp384r1",
+ })
+ assert_instance_of OpenSSL::PKey::EC, pkey
+ assert_equal "secp384r1", pkey.group.curve_name
+ assert_equal nil, pkey.private_key
+
+ # Invalid options are checked
+ assert_raise(OpenSSL::PKey::PKeyError) {
+ OpenSSL::PKey.generate_parameters("EC", "invalid" => "option")
+ }
+
+ # Parameter generation callback is called
+ cb_called = []
+ assert_raise(RuntimeError) {
+ OpenSSL::PKey.generate_parameters("DSA") { |*args|
+ cb_called << args
+ raise "exit!" if cb_called.size == 3
+ }
+ }
+ assert_not_empty cb_called
+ end
+
+ def test_s_generate_key
+ pend "EC is disabled" unless defined?(OpenSSL::PKey::EC)
+
+ assert_raise(OpenSSL::PKey::PKeyError) {
+ # DSA key pair cannot be generated without parameters
+ OpenSSL::PKey.generate_key("DSA")
+ }
+ pkey_params = OpenSSL::PKey.generate_parameters("EC", {
+ "ec_paramgen_curve" => "secp384r1",
+ })
+ pkey = OpenSSL::PKey.generate_key(pkey_params)
+ assert_instance_of OpenSSL::PKey::EC, pkey
+ assert_equal "secp384r1", pkey.group.curve_name
+ assert_not_equal nil, pkey.private_key
+ end
+
+ def test_hmac_sign_verify
+ pkey = OpenSSL::PKey.generate_key("HMAC", { "key" => "abcd" })
+
+ hmac = OpenSSL::HMAC.new("abcd", "SHA256").update("data").digest
+ assert_equal hmac, pkey.sign("SHA256", "data")
+
+ # EVP_PKEY_HMAC does not support verify
+ assert_raise(OpenSSL::PKey::PKeyError) {
+ pkey.verify("SHA256", "data", hmac)
+ }
+ end
+
+ def test_ed25519
+ # Test vector from RFC 8032 Section 7.1 TEST 2
+ priv_pem = <<~EOF
+ -----BEGIN PRIVATE KEY-----
+ MC4CAQAwBQYDK2VwBCIEIEzNCJso/5banbbDRuwRTg9bijGfNaumJNqM9u1PuKb7
+ -----END PRIVATE KEY-----
+ EOF
+ pub_pem = <<~EOF
+ -----BEGIN PUBLIC KEY-----
+ MCowBQYDK2VwAyEAPUAXw+hDiVqStwqnTRt+vJyYLM8uxJaMwM1V8Sr0Zgw=
+ -----END PUBLIC KEY-----
+ EOF
+ begin
+ priv = OpenSSL::PKey.read(priv_pem)
+ pub = OpenSSL::PKey.read(pub_pem)
+ rescue OpenSSL::PKey::PKeyError
+ # OpenSSL < 1.1.1
+ pend "Ed25519 is not implemented"
+ end
+ assert_instance_of OpenSSL::PKey::PKey, priv
+ assert_instance_of OpenSSL::PKey::PKey, pub
+ assert_equal priv_pem, priv.private_to_pem
+ assert_equal pub_pem, priv.public_to_pem
+ assert_equal pub_pem, pub.public_to_pem
+
+ sig = [<<~EOF.gsub(/[^0-9a-f]/, "")].pack("H*")
+ 92a009a9f0d4cab8720e820b5f642540
+ a2b27b5416503f8fb3762223ebdb69da
+ 085ac1e43e15996e458f3613d0f11d8c
+ 387b2eaeb4302aeeb00d291612bb0c00
+ EOF
+ data = ["72"].pack("H*")
+ assert_equal sig, priv.sign(nil, data)
+ assert_equal true, priv.verify(nil, sig, data)
+ assert_equal true, pub.verify(nil, sig, data)
+ assert_equal false, pub.verify(nil, sig, data.succ)
+
+ # PureEdDSA wants nil as the message digest
+ assert_raise(OpenSSL::PKey::PKeyError) { priv.sign("SHA512", data) }
+ assert_raise(OpenSSL::PKey::PKeyError) { pub.verify("SHA512", sig, data) }
+
+ # Ed25519 pkey type does not support key derivation
+ assert_raise(OpenSSL::PKey::PKeyError) { priv.derive(pub) }
+ end
+
+ def test_x25519
+ # Test vector from RFC 7748 Section 6.1
+ alice_pem = <<~EOF
+ -----BEGIN PRIVATE KEY-----
+ MC4CAQAwBQYDK2VuBCIEIHcHbQpzGKV9PBbBclGyZkXfTC+H68CZKrF3+6UduSwq
+ -----END PRIVATE KEY-----
+ EOF
+ bob_pem = <<~EOF
+ -----BEGIN PUBLIC KEY-----
+ MCowBQYDK2VuAyEA3p7bfXt9wbTTW2HC7OQ1Nz+DQ8hbeGdNrfx+FG+IK08=
+ -----END PUBLIC KEY-----
+ EOF
+ shared_secret = "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"
+ begin
+ alice = OpenSSL::PKey.read(alice_pem)
+ bob = OpenSSL::PKey.read(bob_pem)
+ rescue OpenSSL::PKey::PKeyError
+ # OpenSSL < 1.1.0
+ pend "X25519 is not implemented"
+ end
+ assert_instance_of OpenSSL::PKey::PKey, alice
+ assert_equal alice_pem, alice.private_to_pem
+ assert_equal bob_pem, bob.public_to_pem
+ assert_equal [shared_secret].pack("H*"), alice.derive(bob)
+ end
+
+ def test_compare?
+ key1 = Fixtures.pkey("rsa1024")
+ key2 = Fixtures.pkey("rsa1024")
+ key3 = Fixtures.pkey("rsa2048")
+ key4 = Fixtures.pkey("dh-1")
+
+ assert_equal(true, key1.compare?(key2))
+ assert_equal(true, key1.public_key.compare?(key2))
+ assert_equal(true, key2.compare?(key1))
+ assert_equal(true, key2.public_key.compare?(key1))
+
+ assert_equal(false, key1.compare?(key3))
+
+ assert_raise(TypeError) do
+ key1.compare?(key4)
+ end
+ end
end
From 3376d11a39295b67086da4ebc4e5530e780a398d Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Thu, 13 Aug 2020 19:36:31 +0900
Subject: [PATCH 14/21] test/openssl/test_pkey_rsa: fix RSA key generation test
OpenSSL 3.0 checks the public exponent value in a stricter manner and
does no longer allow values less than 65537, with the exception of 3.
---
test/openssl/test_pkey_rsa.rb | 40 +++++++++++++++++------------------
1 file changed, 19 insertions(+), 21 deletions(-)
diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb
index 9dac06e2..544d28dc 100644
--- a/test/openssl/test_pkey_rsa.rb
+++ b/test/openssl/test_pkey_rsa.rb
@@ -68,30 +68,28 @@ def test_private
assert(!key6.private?)
end
- def test_new
- key = OpenSSL::PKey::RSA.new 512
- pem = key.public_key.to_pem
- OpenSSL::PKey::RSA.new pem
- assert_equal([], OpenSSL.errors)
+ def test_new_generate
+ key1 = OpenSSL::PKey::RSA.new(512)
+ assert_equal 512, key1.n.num_bits
+ assert_equal 65537, key1.e
+
+ # Specify public exponent
+ key2 = OpenSSL::PKey::RSA.new(512, 3)
+ assert_equal 512, key2.n.num_bits
+ assert_equal 3, key2.e
+ assert_not_equal 0, key2.d
end
- def test_new_exponent_default
- assert_equal(65537, OpenSSL::PKey::RSA.new(512).e)
- end
-
- def test_new_with_exponent
- 1.upto(30) do |idx|
- e = (2 ** idx) + 1
- key = OpenSSL::PKey::RSA.new(512, e)
- assert_equal(e, key.e)
- end
- end
+ def test_s_generate
+ key1 = OpenSSL::PKey::RSA.generate(512)
+ assert_equal 512, key1.n.num_bits
+ assert_equal 65537, key1.e
- def test_generate
- key = OpenSSL::PKey::RSA.generate(512, 17)
- assert_equal 512, key.n.num_bits
- assert_equal 17, key.e
- assert_not_nil key.d
+ # Specify public exponent
+ key2 = OpenSSL::PKey::RSA.generate(512, 3)
+ assert_equal 512, key2.n.num_bits
+ assert_equal 3, key2.e
+ assert_not_equal 0, key2.d
end
def test_new_break
From 050760bb700a274cb5efe3211dae8f8e078f2f1a Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Thu, 13 Aug 2020 23:20:55 +0900
Subject: [PATCH 15/21] test/openssl/test_pkcs12: fix test failures with
OpenSSL 3.0
OpenSSL's PKCS12_create() by default uses pbewithSHAAnd40BitRC2-CBC for
encryption of the certificates. However, in OpenSSL 3.0, the algorithm
is part of the legacy provider and is not enabled by default.
Specify another algorithm that is still in the default provider in the
test cases.
---
test/openssl/test_pkcs12.rb | 297 ++++++++++++++++++------------------
1 file changed, 149 insertions(+), 148 deletions(-)
diff --git a/test/openssl/test_pkcs12.rb b/test/openssl/test_pkcs12.rb
index fdbe753b..ec676743 100644
--- a/test/openssl/test_pkcs12.rb
+++ b/test/openssl/test_pkcs12.rb
@@ -5,6 +5,9 @@
module OpenSSL
class TestPKCS12 < OpenSSL::TestCase
+ DEFAULT_PBE_PKEYS = "PBE-SHA1-3DES"
+ DEFAULT_PBE_CERTS = "PBE-SHA1-3DES"
+
def setup
super
ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA")
@@ -14,47 +17,41 @@ def setup
["subjectKeyIdentifier","hash",false],
["authorityKeyIdentifier","keyid:always",false],
]
- @cacert = issue_cert(ca, Fixtures.pkey("rsa2048"), 1, ca_exts, nil, nil)
+ ca_key = Fixtures.pkey("rsa-1")
+ @cacert = issue_cert(ca, ca_key, 1, ca_exts, nil, nil)
inter_ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=Intermediate CA")
- inter_ca_key = OpenSSL::PKey.read <<-_EOS_
------BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQDp7hIG0SFMG/VWv1dBUWziAPrNmkMXJgTCAoB7jffzRtyyN04K
-oq/89HAszTMStZoMigQURfokzKsjpUp8OYCAEsBtt9d5zPndWMz/gHN73GrXk3LT
-ZsxEn7Xv5Da+Y9F/Hx2QZUHarV5cdZixq2NbzWGwrToogOQMh2pxN3Z/0wIDAQAB
-AoGBAJysUyx3olpsGzv3OMRJeahASbmsSKTXVLZvoIefxOINosBFpCIhZccAG6UV
-5c/xCvS89xBw8aD15uUfziw3AuT8QPEtHCgfSjeT7aWzBfYswEgOW4XPuWr7EeI9
-iNHGD6z+hCN/IQr7FiEBgTp6A+i/hffcSdR83fHWKyb4M7TRAkEA+y4BNd668HmC
-G5MPRx25n6LixuBxrNp1umfjEI6UZgEFVpYOg4agNuimN6NqM253kcTR94QNTUs5
-Kj3EhG1YWwJBAO5rUjiOyCNVX2WUQrOMYK/c1lU7fvrkdygXkvIGkhsPoNRzLPeA
-HGJszKtrKD8bNihWpWNIyqKRHfKVD7yXT+kCQGCAhVCIGTRoypcDghwljHqLnysf
-ci0h5ZdPcIqc7ODfxYhFsJ/Rql5ONgYsT5Ig/+lOQAkjf+TRYM4c2xKx2/8CQBvG
-jv6dy70qDgIUgqzONtlmHeYyFzn9cdBO5sShdVYHvRHjFSMEXsosqK9zvW2UqvuK
-FJx7d3f29gkzynCLJDkCQGQZlEZJC4vWmWJGRKJ24P6MyQn3VsPfErSKOg4lvyM3
-Li8JsX5yIiuVYaBg/6ha3tOg4TCa5K/3r3tVliRZ2Es=
------END RSA PRIVATE KEY-----
- _EOS_
- @inter_cacert = issue_cert(inter_ca, inter_ca_key, 2, ca_exts, @cacert, Fixtures.pkey("rsa2048"))
+ inter_ca_key = Fixtures.pkey("rsa-2")
+ @inter_cacert = issue_cert(inter_ca, inter_ca_key, 2, ca_exts, @cacert, ca_key)
exts = [
["keyUsage","digitalSignature",true],
["subjectKeyIdentifier","hash",false],
]
ee = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=Ruby PKCS12 Test Certificate")
- @mykey = Fixtures.pkey("rsa1024")
+ @mykey = Fixtures.pkey("rsa-3")
@mycert = issue_cert(ee, @mykey, 3, exts, @inter_cacert, inter_ca_key)
end
- def test_create
+ def test_create_single_key_single_cert
pkcs12 = OpenSSL::PKCS12.create(
"omg",
"hello",
@mykey,
- @mycert
+ @mycert,
+ nil,
+ DEFAULT_PBE_PKEYS,
+ DEFAULT_PBE_CERTS,
)
- assert_equal @mycert.to_der, pkcs12.certificate.to_der
+ assert_equal @mycert, pkcs12.certificate
assert_equal @mykey.to_der, pkcs12.key.to_der
assert_nil pkcs12.ca_certs
+
+ der = pkcs12.to_der
+ decoded = OpenSSL::PKCS12.new(der, "omg")
+ assert_equal @mykey.to_der, decoded.key.to_der
+ assert_equal @mycert, decoded.certificate
+ assert_equal [], Array(decoded.ca_certs)
end
def test_create_no_pass
@@ -62,14 +59,17 @@ def test_create_no_pass
nil,
"hello",
@mykey,
- @mycert
+ @mycert,
+ nil,
+ DEFAULT_PBE_PKEYS,
+ DEFAULT_PBE_CERTS,
)
- assert_equal @mycert.to_der, pkcs12.certificate.to_der
+ assert_equal @mycert, pkcs12.certificate
assert_equal @mykey.to_der, pkcs12.key.to_der
assert_nil pkcs12.ca_certs
decoded = OpenSSL::PKCS12.new(pkcs12.to_der)
- assert_cert @mycert, decoded.certificate
+ assert_equal @mycert, decoded.certificate
end
def test_create_with_chain
@@ -80,7 +80,9 @@ def test_create_with_chain
"hello",
@mykey,
@mycert,
- chain
+ chain,
+ DEFAULT_PBE_PKEYS,
+ DEFAULT_PBE_CERTS,
)
assert_equal chain, pkcs12.ca_certs
end
@@ -95,14 +97,16 @@ def test_create_with_chain_decode
"hello",
@mykey,
@mycert,
- chain
+ chain,
+ DEFAULT_PBE_PKEYS,
+ DEFAULT_PBE_CERTS,
)
decoded = OpenSSL::PKCS12.new(pkcs12.to_der, passwd)
assert_equal chain.size, decoded.ca_certs.size
- assert_include_cert @cacert, decoded.ca_certs
- assert_include_cert @inter_cacert, decoded.ca_certs
- assert_cert @mycert, decoded.certificate
+ assert_include decoded.ca_certs, @cacert
+ assert_include decoded.ca_certs, @inter_cacert
+ assert_equal @mycert, decoded.certificate
assert_equal @mykey.to_der, decoded.key.to_der
end
@@ -126,8 +130,8 @@ def test_create_with_itr
@mykey,
@mycert,
[],
- nil,
- nil,
+ DEFAULT_PBE_PKEYS,
+ DEFAULT_PBE_CERTS,
2048
)
@@ -138,8 +142,8 @@ def test_create_with_itr
@mykey,
@mycert,
[],
- nil,
- nil,
+ DEFAULT_PBE_PKEYS,
+ DEFAULT_PBE_CERTS,
"omg"
)
end
@@ -152,7 +156,8 @@ def test_create_with_mac_itr
@mykey,
@mycert,
[],
- nil,
+ DEFAULT_PBE_PKEYS,
+ DEFAULT_PBE_CERTS,
nil,
nil,
2048
@@ -165,148 +170,144 @@ def test_create_with_mac_itr
@mykey,
@mycert,
[],
- nil,
- nil,
+ DEFAULT_PBE_PKEYS,
+ DEFAULT_PBE_CERTS,
nil,
"omg"
)
end
end
- def test_new_with_one_key_and_one_cert
- # generated with:
- # openssl version #=> OpenSSL 1.0.2h 3 May 2016
- # openssl pkcs12 -in <@mycert> -inkey <RSA1024> -export -out <out>
- str = <<~EOF.unpack("m").first
-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
-vyl2WuMdEwQIMWFFphPkIUICAggA
- EOF
- p12 = OpenSSL::PKCS12.new(str, "abc123")
-
- assert_equal @mykey.to_der, p12.key.to_der
- assert_equal @mycert.subject.to_der, p12.certificate.subject.to_der
- assert_equal [], Array(p12.ca_certs)
- end
-
def test_new_with_no_keys
# generated with:
- # openssl pkcs12 -in <@mycert> -nokeys -export -out <out>
+ # openssl pkcs12 -certpbe PBE-SHA1-3DES -in <@mycert> -nokeys -export
str = <<~EOF.unpack("m").first
-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
+MIIGJAIBAzCCBeoGCSqGSIb3DQEHAaCCBdsEggXXMIIF0zCCBc8GCSqGSIb3
+DQEHBqCCBcAwggW8AgEAMIIFtQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQMw
+DgQIjv5c3OHvnBgCAggAgIIFiMJa8Z/w7errRvCQPXh9dGQz3eJaFq3S2gXD
+rh6oiwsgIRJZvYAWgU6ll9NV7N5SgvS2DDNVuc3tsP8TPWjp+bIxzS9qmGUV
+kYWuURWLMKhpF12ZRDab8jcIwBgKoSGiDJk8xHjx6L613/XcRM6ln3VeQK+C
+hlW5kXniNAUAgTft25Fn61Xa8xnhmsz/fk1ycGnyGjKCnr7Mgy7KV0C1vs23
+18n8+b1ktDWLZPYgpmXuMFVh0o+HJTV3O86mkIhJonMcnOMgKZ+i8KeXaocN
+JQlAPBG4+HOip7FbQT/h6reXv8/J+hgjLfqAb5aV3m03rUX9mXx66nR1tQU0
+Jq+XPfDh5+V4akIczLlMyyo/xZjI1/qupcMjr+giOGnGd8BA3cuXW+ueLQiA
+PpTp+DQLVHRfz9XTZbyqOReNEtEXvO9gOlKSEY5lp65ItXVEs2Oqyf9PfU9y
+DUltN6fCMilwPyyrsIBKXCu2ZLM5h65KVCXAYEX9lNqj9zrQ7vTqvCNN8RhS
+ScYouTX2Eqa4Z+gTZWLHa8RCQFoyP6hd+97/Tg2Gv2UTH0myQxIVcnpdi1wy
+cqb+er7tyKbcO96uSlUjpj/JvjlodtjJcX+oinEqGb/caj4UepbBwiG3vv70
+63bS3jTsOLNjDRsR9if3LxIhLa6DW8zOJiGC+EvMD1o4dzHcGVpQ/pZWCHZC
++YiNJpQOBApiZluE+UZ0m3XrtHFQYk7xblTrh+FJF91wBsok0rZXLAKd8m4p
+OJsc7quCq3cuHRRTzJQ4nSe01uqbwGDAYwLvi6VWy3svU5qa05eDRmgzEFTG
+e84Gp/1LQCtpQFr4txkjFchO2whWS80KoQKqmLPyGm1D9Lv53Q4ZsKMgNihs
+rEepuaOZMKHl4yMAYFoOXZCAYzfbhN6b2phcFAHjMUHUw9e3F0QuDk9D0tsr
+riYTrkocqlOKfK4QTomx27O0ON2J6f1rtEojGgfl9RNykN7iKGzjS3914QjW
+W6gGiZejxHsDPEAa4gUp0WiSUSXtD5WJgoyAzLydR2dKWsQ4WlaUXi01CuGy
++xvncSn2nO3bbot8VD5H6XU1CjREVtnIfbeRYO/uofyLUP3olK5RqN6ne6Xo
+eXnJ/bjYphA8NGuuuvuW1SCITmINkZDLC9cGlER9+K65RR/DR3TigkexXMeN
+aJ70ivZYAl0OuhZt3TGIlAzS64TIoyORe3z7Ta1Pp9PZQarYJpF9BBIZIFor
+757PHHuQKRuugiRkp8B7v4eq1BQ+VeAxCKpyZ7XrgEtbY/AWDiaKcGPKPjc3
+AqQraVeQm7kMBT163wFmZArCphzkDOI3bz2oEO8YArMgLq2Vto9jAZlqKyWr
+pi2bSJxuoP1aoD58CHcWMrf8/j1LVdQhKgHQXSik2ID0H2Wc/XnglhzlVFuJ
+JsNIW/EGJlZh/5WDez9U0bXqnBlu3uasPEOezdoKlcCmQlmTO5+uLHYLEtNA
+EH9MtnGZebi9XS5meTuS6z5LILt8O9IHZxmT3JRPHYj287FEzotlLdcJ4Ee5
+enW41UHjLrfv4OaITO1hVuoLRGdzjESx/fHMWmxroZ1nVClxECOdT42zvIYJ
+J3xBZ0gppzQ5fjoYiKjJpxTflRxUuxshk3ih6VUoKtqj/W18tBQ3g5SOlkgT
+yCW8r74yZlfYmNrPyDMUQYpLUPWj2n71GF0KyPfTU5yOatRgvheh262w5BG3
+omFY7mb3tCv8/U2jdMIoukRKacpZiagofz3SxojOJq52cHnCri+gTHBMX0cO
+j58ygfntHWRzst0pV7Ze2X3fdCAJ4DokH6bNJNthcgmolFJ/y3V1tJjgsdtQ
+7Pjn/vE6xUV0HXE2x4yoVYNirbAMIvkN/X+atxrN0dA4AchN+zGp8TAxMCEw
+CQYFKw4DAhoFAAQUQ+6XXkyhf6uYgtbibILN2IjKnOAECLiqoY45MPCrAgII
+AA==
EOF
p12 = OpenSSL::PKCS12.new(str, "abc123")
assert_equal nil, p12.key
assert_equal nil, p12.certificate
assert_equal 1, p12.ca_certs.size
- assert_equal @mycert.subject.to_der, p12.ca_certs[0].subject.to_der
+ assert_equal @mycert.subject, p12.ca_certs[0].subject
end
def test_new_with_no_certs
# generated with:
- # openssl pkcs12 -inkey <RSA1024> -nocerts -export -out <out>
+ # openssl pkcs12 -inkey fixtures/openssl/pkey/rsa-1.pem -nocerts -export
str = <<~EOF.unpack("m").first
-MIIDJwIBAzCCAu0GCSqGSIb3DQEHAaCCAt4EggLaMIIC1jCCAtIGCSqGSIb3DQEH
-AaCCAsMEggK/MIICuzCCArcGCyqGSIb3DQEMCgECoIICpjCCAqIwHAYKKoZIhvcN
-AQwBAzAOBAg6AaYnJs84SwICCAAEggKAQzZH+fWSpcQYD1J7PsGSune85A++fLCQ
-V7tacp2iv95GJkxwYmfTP176pJdgs00mceB9UJ/u9EX5nD0djdjjQjwo6sgKjY0q
-cpVhZw8CMxw7kBD2dhtui0zT8z5hy03LePxsjEKsGiSbeVeeGbSfw/I6AAYbv+Uh
-O/YPBGumeHj/D2WKnfsHJLQ9GAV3H6dv5VKYNxjciK7f/JEyZCuUQGIN64QFHDhJ
-7fzLqd/ul3FZzJZO6a+dwvcgux09SKVXDRSeFmRCEX4b486iWhJJVspCo9P2KNne
-ORrpybr3ZSwxyoICmjyo8gj0OSnEfdx9790Ej1takPqSA1wIdSdBLekbZqB0RBQg
-DEuPOsXNo3QFi8ji1vu0WBRJZZSNC2hr5NL6lNR+DKxG8yzDll2j4W4BBIp22mAE
-7QRX7kVxu17QJXQhOUac4Dd1qXmzebP8t6xkAxD9L7BWEN5OdiXWwSWGjVjMBneX
-nYObi/3UT/aVc5WHMHK2BhCI1bwH51E6yZh06d5m0TQpYGUTWDJdWGBSrp3A+8jN
-N2PMQkWBFrXP3smHoTEN4oZC4FWiPsIEyAkQsfKRhcV9lGKl2Xgq54ROTFLnwKoj
-Z3zJScnq9qmNzvVZSMmDLkjLyDq0pxRxGKBvgouKkWY7VFFIwwBIJM39iDJ5NbBY
-i1AQFTRsRSsZrNVPasCXrIq7bhMoJZb/YZOGBLNyJVqKUoYXhtwsajzSq54VlWft
-JxsPayEd4Vi6O9EU1ahnj6qFEZiKFzsicgK2J1Rb8cYagrp0XWjHW0SBn5GVUWCg
-GUokSFG/0JTdeYTo/sQuG4qNgJkOolRjpeI48Fciq5VUWLvVdKioXzAxMCEwCQYF
-Kw4DAhoFAAQUYAuwVtGD1TdgbFK4Yal2XBgwUR4ECEawsN3rNaa6AgIIAA==
+MIIJ7wIBAzCCCbUGCSqGSIb3DQEHAaCCCaYEggmiMIIJnjCCCZoGCSqGSIb3
+DQEHAaCCCYsEggmHMIIJgzCCCX8GCyqGSIb3DQEMCgECoIIJbjCCCWowHAYK
+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
+BC8fv38mue8LZVcbHQQIUNrWKEnskCoCAggA
EOF
p12 = OpenSSL::PKCS12.new(str, "abc123")
- assert_equal @mykey.to_der, p12.key.to_der
+ assert_equal Fixtures.pkey("rsa-1").to_der, p12.key.to_der
assert_equal nil, p12.certificate
assert_equal [], Array(p12.ca_certs)
end
def test_dup
- p12 = OpenSSL::PKCS12.create("pass", "name", @mykey, @mycert)
+ p12 = OpenSSL::PKCS12.create(
+ "pass",
+ "name",
+ @mykey,
+ @mycert,
+ nil,
+ DEFAULT_PBE_PKEYS,
+ DEFAULT_PBE_CERTS,
+ )
assert_equal p12.to_der, p12.dup.to_der
end
-
- private
- def assert_cert expected, actual
- [
- :subject,
- :issuer,
- :serial,
- :not_before,
- :not_after,
- ].each do |attribute|
- assert_equal expected.send(attribute), actual.send(attribute)
- end
- assert_equal expected.to_der, actual.to_der
- end
-
- def assert_include_cert cert, ary
- der = cert.to_der
- ary.each do |candidate|
- if candidate.to_der == der
- return true
- end
- end
- false
- end
end
end
From 1fc2fad3a163dc41e4e17dd1096e3e63f8e4f2dd Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Fri, 19 Mar 2021 19:18:25 +0900
Subject: [PATCH 16/21] ssl: use SSL_get_rbio() to check if SSL is started or
not
Use SSL_get_rbio() instead of SSL_get_fd(). SSL_get_rbio() is simpler
and does not need error handling.
---
ext/openssl/ossl_ssl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index c80c939e..06bfd96d 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -1529,8 +1529,8 @@ ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
static inline int
ssl_started(SSL *ssl)
{
- /* the FD is set in ossl_ssl_setup(), called by #connect or #accept */
- return SSL_get_fd(ssl) >= 0;
+ /* BIO is created through ossl_ssl_setup(), called by #connect or #accept */
+ return SSL_get_rbio(ssl) != NULL;
}
static void
From 01e123051d774355bdda1947d77a832216e5b595 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Sat, 20 Mar 2021 23:16:16 +0900
Subject: [PATCH] pkey: use OSSL_STORE to load encrypted PEM on OpenSSL 3.0
---
ext/openssl/ossl_pkey.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
index 3982b9c..f58a4c9 100644
--- a/ext/openssl/ossl_pkey.c
+++ b/ext/openssl/ossl_pkey.c
@@ -140,12 +140,41 @@ ossl_pkey_new(EVP_PKEY *pkey)
return obj;
}
+#if OPENSSL_VERSION_MAJOR+0 >= 3
+# include <openssl/decoder.h>
+static EVP_PKEY *
+ossl_pkey_read_decoder(BIO *bio, const char *input_type, void *ppass)
+{
+ OSSL_DECODER_CTX *dctx;
+ EVP_PKEY *pkey = NULL;
+
+ dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, input_type, NULL, NULL, 0, NULL, NULL);
+ if (!dctx)
+ goto out;
+ if (OSSL_DECODER_CTX_set_pem_password_cb(dctx, ossl_pem_passwd_cb, ppass) != 1)
+ goto out;
+ if (OSSL_DECODER_from_bio(dctx, bio) != 1)
+ goto out;
+
+ out:
+ OSSL_DECODER_CTX_free(dctx);
+ return pkey;
+}
+#endif
+
EVP_PKEY *
ossl_pkey_read_generic(BIO *bio, VALUE pass)
{
void *ppass = (void *)pass;
EVP_PKEY *pkey;
+#if OPENSSL_VERSION_MAJOR+0 >= 3
+ if ((pkey = ossl_pkey_read_decoder(bio, "DER", ppass)))
+ goto out;
+ OSSL_BIO_reset(bio);
+ if ((pkey = ossl_pkey_read_decoder(bio, "PEM", ppass)))
+ goto out;
+#else
if ((pkey = d2i_PrivateKey_bio(bio, NULL)))
goto out;
OSSL_BIO_reset(bio);
@@ -164,8 +193,14 @@ ossl_pkey_read_generic(BIO *bio, VALUE pass)
OSSL_BIO_reset(bio);
if ((pkey = PEM_read_bio_Parameters(bio, NULL)))
goto out;
+#endif
out:
+#if OPENSSL_VERSION_MAJOR+0 >= 3
+ /* FIXME: OpenSSL bug? */
+ if (pkey)
+ ossl_clear_error();
+#endif
return pkey;
}
From 2bfc05abddd80f927e164bfe4545c87f0b30da81 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Sat, 20 Mar 2021 23:16:41 +0900
Subject: [PATCH 18/21] pkey: skip checking if pkey has public key components
on OpenSSL 3.0
---
ext/openssl/ossl_pkey.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
index df6aaa46..aceccb5b 100644
--- a/ext/openssl/ossl_pkey.c
+++ b/ext/openssl/ossl_pkey.c
@@ -251,6 +251,12 @@ ossl_pkey_check_public_key(const EVP_PKEY *pkey)
/* OpenSSL < 1.1.0 takes non-const pointer */
ptr = EVP_PKEY_get0((EVP_PKEY *)pkey);
+ /*
+ * OpenSSL 3.0.0's EVP_PKEY_get0() returns NULL - the lower level object
+ * may not be accesible
+ */
+ if (!ptr)
+ return;
switch (EVP_PKEY_base_id(pkey)) {
case EVP_PKEY_RSA:
RSA_get0_key(ptr, &n, &e, NULL);
From 04a0948ab085ab8452dd2fcb507b1af1ff9e0ab2 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Sun, 21 Mar 2021 00:20:04 +0900
Subject: [PATCH 19/21] bn: make BN.pseudo_rand{,_range} an alias of
BN.rand{,_range}
BN_pseudo_rand() and BN_pseudo_rand_range() are deprecated in
OpenSSL 3.0. Since they are identical to their non-'pseudo' version
anyway, let's make them alias.
---
ext/openssl/ossl_bn.c | 18 ++----------------
test/openssl/test_bn.rb | 4 ++++
2 files changed, 6 insertions(+), 16 deletions(-)
diff --git a/ext/openssl/ossl_bn.c b/ext/openssl/ossl_bn.c
index e0eef4cd..fe62442f 100644
--- a/ext/openssl/ossl_bn.c
+++ b/ext/openssl/ossl_bn.c
@@ -794,12 +794,6 @@ BIGNUM_SELF_SHIFT(rshift)
*/
BIGNUM_RAND(rand)
-/*
- * Document-method: OpenSSL::BN.pseudo_rand
- * BN.pseudo_rand(bits [, fill [, odd]]) -> aBN
- */
-BIGNUM_RAND(pseudo_rand)
-
#define BIGNUM_RAND_RANGE(func) \
static VALUE \
ossl_bn_s_##func##_range(VALUE klass, VALUE range) \
@@ -825,14 +819,6 @@ BIGNUM_RAND(pseudo_rand)
*/
BIGNUM_RAND_RANGE(rand)
-/*
- * Document-method: OpenSSL::BN.pseudo_rand_range
- * call-seq:
- * BN.pseudo_rand_range(range) -> aBN
- *
- */
-BIGNUM_RAND_RANGE(pseudo_rand)
-
/*
* call-seq:
* BN.generate_prime(bits, [, safe [, add [, rem]]]) => bn
@@ -1182,9 +1168,9 @@ Init_ossl_bn(void)
* get_word */
rb_define_singleton_method(cBN, "rand", ossl_bn_s_rand, -1);
- rb_define_singleton_method(cBN, "pseudo_rand", ossl_bn_s_pseudo_rand, -1);
rb_define_singleton_method(cBN, "rand_range", ossl_bn_s_rand_range, 1);
- rb_define_singleton_method(cBN, "pseudo_rand_range", ossl_bn_s_pseudo_rand_range, 1);
+ rb_define_alias(rb_singleton_class(cBN), "pseudo_rand", "rand");
+ rb_define_alias(rb_singleton_class(cBN), "pseudo_rand_range", "rand_range");
rb_define_singleton_method(cBN, "generate_prime", ossl_bn_s_generate_prime, -1);
rb_define_method(cBN, "prime?", ossl_bn_is_prime, -1);
diff --git a/test/openssl/test_bn.rb b/test/openssl/test_bn.rb
index 1ed4bbee..36af9644 100644
--- a/test/openssl/test_bn.rb
+++ b/test/openssl/test_bn.rb
@@ -228,6 +228,10 @@ def test_random
r5 = OpenSSL::BN.rand_range(256)
assert_include(0..255, r5)
}
+
+ # Aliases
+ assert_include(128..255, OpenSSL::BN.pseudo_rand(8))
+ assert_include(0..255, OpenSSL::BN.pseudo_rand_range(256))
end
def test_prime
From a2de5b69f144491426cb393e1fc929af404fda12 Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@rhe.jp>
Date: Sun, 21 Mar 2021 00:23:31 +0900
Subject: [PATCH 20/21] test/openssl/test_ssl.rb: fix illegal SAN extension
A certificate can only have one SubjectAltName extension. OpenSSL 3.0
does a stricter validation and such a certificate is rejected.
---
test/openssl/test_ssl.rb | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb
index 6c9547dc..60520b22 100644
--- a/test/openssl/test_ssl.rb
+++ b/test/openssl/test_ssl.rb
@@ -551,8 +551,7 @@ def test_post_connection_check
exts = [
["keyUsage","keyEncipherment,digitalSignature",true],
- ["subjectAltName","DNS:localhost.localdomain",false],
- ["subjectAltName","IP:127.0.0.1",false],
+ ["subjectAltName","DNS:localhost.localdomain,IP:127.0.0.1",false],
]
@svr_cert = issue_cert(@svr, @svr_key, 4, exts, @ca_cert, @ca_key)
start_server { |port|