mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
openssl: import v2.1.3
Bring the local copy of ruby/openssl in sync with the upstream gem release v2.1.3. The commits happened in the upstream repository can be found at: https://github.com/ruby/openssl/compare/v2.1.2...v2.1.3 Note that many of these have already been applied to ruby.git and don't appear in the file changes of this commit.
This commit is contained in:
parent
8737878248
commit
e0b323632f
19 changed files with 439 additions and 160 deletions
|
|
@ -1,3 +1,39 @@
|
||||||
|
Version 2.1.3
|
||||||
|
=============
|
||||||
|
|
||||||
|
Bug fixes
|
||||||
|
---------
|
||||||
|
|
||||||
|
* Fix deprecation warnings on Ruby 3.0.
|
||||||
|
* Add ".include" directive support in `OpenSSL::Config`.
|
||||||
|
[[GitHub #216]](https://github.com/ruby/openssl/pull/216)
|
||||||
|
* Fix handling of IPv6 address SANs.
|
||||||
|
[[GitHub #185]](https://github.com/ruby/openssl/pull/185)
|
||||||
|
* Hostname verification failure with `OpenSSL::SSL::SSLContext#verify_hostname=`
|
||||||
|
sets a proper error code.
|
||||||
|
[[GitHub #350]](https://github.com/ruby/openssl/pull/350)
|
||||||
|
* Fix crash with `OpenSSL::BN.new(nil, 2)`.
|
||||||
|
[[Bug #15760]](https://bugs.ruby-lang.org/issues/15760)
|
||||||
|
* `OpenSSL::SSL::SSLSocket#sys{read,write}` prevent internal string buffers from
|
||||||
|
being modified by another thread.
|
||||||
|
[[GitHub #453]](https://github.com/ruby/openssl/pull/453)
|
||||||
|
* Fix misuse of input record separator in `OpenSSL::Buffering` where it was
|
||||||
|
for output.
|
||||||
|
* Fix wrong interger casting in `OpenSSL::PKey::EC#dsa_verify_asn1`.
|
||||||
|
[[GitHub #460]](https://github.com/ruby/openssl/pull/460)
|
||||||
|
* `extconf.rb` explicitly checks that OpenSSL's version number is 1.0.1 or
|
||||||
|
newer but also less than 3.0. Ruby/OpenSSL v2.1.x and v2.2.x will not support
|
||||||
|
OpenSSL 3.0 API.
|
||||||
|
[[GitHub #458]](https://github.com/ruby/openssl/pull/458)
|
||||||
|
* Activate `digest` gem correctly. `digest` library could go into an
|
||||||
|
inconsistent state if there are multiple versions of `digest` is installed
|
||||||
|
and `openssl` is `require`d before `digest`.
|
||||||
|
[[GitHub #463]](https://github.com/ruby/openssl/pull/463)
|
||||||
|
* Fix GC.compact compatibility.
|
||||||
|
[[GitHub #464]](https://github.com/ruby/openssl/issues/464)
|
||||||
|
[[GitHub #465]](https://github.com/ruby/openssl/pull/465)
|
||||||
|
|
||||||
|
|
||||||
Version 2.1.2
|
Version 2.1.2
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,9 +37,6 @@ if $mswin || $mingw
|
||||||
have_library("ws2_32")
|
have_library("ws2_32")
|
||||||
end
|
end
|
||||||
|
|
||||||
Logging::message "=== Checking for required stuff... ===\n"
|
|
||||||
result = pkg_config("openssl") && have_header("openssl/ssl.h")
|
|
||||||
|
|
||||||
def find_openssl_library
|
def find_openssl_library
|
||||||
if $mswin || $mingw
|
if $mswin || $mingw
|
||||||
# required for static OpenSSL libraries
|
# required for static OpenSSL libraries
|
||||||
|
|
@ -90,19 +87,33 @@ def find_openssl_library
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
unless result
|
Logging::message "=== Checking for required stuff... ===\n"
|
||||||
unless find_openssl_library
|
pkg_config_found = pkg_config("openssl") && have_header("openssl/ssl.h")
|
||||||
Logging::message "=== Checking for required stuff failed. ===\n"
|
|
||||||
Logging::message "Makefile wasn't created. Fix the errors above.\n"
|
if !pkg_config_found && !find_openssl_library
|
||||||
raise "OpenSSL library could not be found. You might want to use " \
|
Logging::message "=== Checking for required stuff failed. ===\n"
|
||||||
"--with-openssl-dir=<dir> option to specify the prefix where OpenSSL " \
|
Logging::message "Makefile wasn't created. Fix the errors above.\n"
|
||||||
"is installed."
|
raise "OpenSSL library could not be found. You might want to use " \
|
||||||
end
|
"--with-openssl-dir=<dir> option to specify the prefix where OpenSSL " \
|
||||||
|
"is installed."
|
||||||
end
|
end
|
||||||
|
|
||||||
unless checking_for("OpenSSL version is 1.0.1 or later") {
|
version_ok = if have_macro("LIBRESSL_VERSION_NUMBER", "openssl/opensslv.h")
|
||||||
try_static_assert("OPENSSL_VERSION_NUMBER >= 0x10001000L", "openssl/opensslv.h") }
|
is_libressl = true
|
||||||
raise "OpenSSL >= 1.0.1 or LibreSSL is required"
|
checking_for("LibreSSL version >= 2.5.0") {
|
||||||
|
try_static_assert("LIBRESSL_VERSION_NUMBER >= 0x20500000L", "openssl/opensslv.h") }
|
||||||
|
else
|
||||||
|
checking_for("OpenSSL version >= 1.0.1 and < 3.0.0") {
|
||||||
|
try_static_assert("OPENSSL_VERSION_NUMBER >= 0x10001000L", "openssl/opensslv.h") &&
|
||||||
|
!try_static_assert("OPENSSL_VERSION_MAJOR >= 3", "openssl/opensslv.h") }
|
||||||
|
end
|
||||||
|
unless version_ok
|
||||||
|
raise "OpenSSL >= 1.0.1, < 3.0.0 or LibreSSL >= 2.5.0 is required"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Prevent wincrypt.h from being included, which defines conflicting macro with openssl/x509.h
|
||||||
|
if is_libressl && ($mswin || $mingw)
|
||||||
|
$defs.push("-DNOCRYPT")
|
||||||
end
|
end
|
||||||
|
|
||||||
Logging::message "=== Checking for OpenSSL features... ===\n"
|
Logging::message "=== Checking for OpenSSL features... ===\n"
|
||||||
|
|
@ -114,10 +125,6 @@ engines.each { |name|
|
||||||
OpenSSL.check_func_or_macro("ENGINE_load_#{name}", "openssl/engine.h")
|
OpenSSL.check_func_or_macro("ENGINE_load_#{name}", "openssl/engine.h")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($mswin || $mingw) && have_macro("LIBRESSL_VERSION_NUMBER", "openssl/opensslv.h")
|
|
||||||
$defs.push("-DNOCRYPT")
|
|
||||||
end
|
|
||||||
|
|
||||||
# added in 1.0.2
|
# added in 1.0.2
|
||||||
have_func("EC_curve_nist2nid")
|
have_func("EC_curve_nist2nid")
|
||||||
have_func("X509_REVOKED_dup")
|
have_func("X509_REVOKED_dup")
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,27 @@
|
||||||
# -*- encoding: utf-8 -*-
|
Gem::Specification.new do |spec|
|
||||||
|
spec.name = "openssl"
|
||||||
|
spec.version = "2.1.3"
|
||||||
|
spec.authors = ["Martin Bosslet", "SHIBATA Hiroshi", "Zachary Scott", "Kazuki Yamaguchi"]
|
||||||
|
spec.email = ["ruby-core@ruby-lang.org"]
|
||||||
|
spec.summary = %q{OpenSSL provides SSL, TLS and general purpose cryptography.}
|
||||||
|
spec.description = %q{It wraps the OpenSSL library.}
|
||||||
|
spec.homepage = "https://github.com/ruby/openssl"
|
||||||
|
spec.license = "Ruby"
|
||||||
|
|
||||||
Gem::Specification.new do |s|
|
spec.files = Dir["lib/**/*.rb", "ext/**/*.{c,h,rb}", "*.md", "BSDL", "LICENSE.txt"]
|
||||||
s.name = "openssl"
|
spec.require_paths = ["lib"]
|
||||||
s.version = "2.1.2"
|
spec.extensions = ["ext/openssl/extconf.rb"]
|
||||||
|
|
||||||
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
spec.extra_rdoc_files = Dir["*.md"]
|
||||||
s.metadata = { "msys2_mingw_dependencies" => "openssl" } if s.respond_to? :metadata=
|
spec.rdoc_options = ["--main", "README.md"]
|
||||||
s.require_paths = ["lib"]
|
|
||||||
s.authors = ["Martin Bosslet", "SHIBATA Hiroshi", "Zachary Scott", "Kazuki Yamaguchi"]
|
|
||||||
s.date = "2018-10-17"
|
|
||||||
s.description = "It wraps the OpenSSL library."
|
|
||||||
s.email = ["ruby-core@ruby-lang.org"]
|
|
||||||
s.extensions = ["ext/openssl/extconf.rb"]
|
|
||||||
s.extra_rdoc_files = ["README.md", "CONTRIBUTING.md", "History.md"]
|
|
||||||
s.files = ["BSDL", "CONTRIBUTING.md", "History.md", "LICENSE.txt", "README.md", "ext/openssl/deprecation.rb", "ext/openssl/extconf.rb", "ext/openssl/openssl_missing.c", "ext/openssl/openssl_missing.h", "ext/openssl/ossl.c", "ext/openssl/ossl.h", "ext/openssl/ossl_asn1.c", "ext/openssl/ossl_asn1.h", "ext/openssl/ossl_bio.c", "ext/openssl/ossl_bio.h", "ext/openssl/ossl_bn.c", "ext/openssl/ossl_bn.h", "ext/openssl/ossl_cipher.c", "ext/openssl/ossl_cipher.h", "ext/openssl/ossl_config.c", "ext/openssl/ossl_config.h", "ext/openssl/ossl_digest.c", "ext/openssl/ossl_digest.h", "ext/openssl/ossl_engine.c", "ext/openssl/ossl_engine.h", "ext/openssl/ossl_hmac.c", "ext/openssl/ossl_hmac.h", "ext/openssl/ossl_kdf.c", "ext/openssl/ossl_kdf.h", "ext/openssl/ossl_ns_spki.c", "ext/openssl/ossl_ns_spki.h", "ext/openssl/ossl_ocsp.c", "ext/openssl/ossl_ocsp.h", "ext/openssl/ossl_pkcs12.c", "ext/openssl/ossl_pkcs12.h", "ext/openssl/ossl_pkcs7.c", "ext/openssl/ossl_pkcs7.h", "ext/openssl/ossl_pkey.c", "ext/openssl/ossl_pkey.h", "ext/openssl/ossl_pkey_dh.c", "ext/openssl/ossl_pkey_dsa.c", "ext/openssl/ossl_pkey_ec.c", "ext/openssl/ossl_pkey_rsa.c", "ext/openssl/ossl_rand.c", "ext/openssl/ossl_rand.h", "ext/openssl/ossl_ssl.c", "ext/openssl/ossl_ssl.h", "ext/openssl/ossl_ssl_session.c", "ext/openssl/ossl_version.h", "ext/openssl/ossl_x509.c", "ext/openssl/ossl_x509.h", "ext/openssl/ossl_x509attr.c", "ext/openssl/ossl_x509cert.c", "ext/openssl/ossl_x509crl.c", "ext/openssl/ossl_x509ext.c", "ext/openssl/ossl_x509name.c", "ext/openssl/ossl_x509req.c", "ext/openssl/ossl_x509revoked.c", "ext/openssl/ossl_x509store.c", "ext/openssl/ruby_missing.h", "lib/openssl.rb", "lib/openssl/bn.rb", "lib/openssl/buffering.rb", "lib/openssl/cipher.rb", "lib/openssl/config.rb", "lib/openssl/digest.rb", "lib/openssl/pkcs5.rb", "lib/openssl/pkey.rb", "lib/openssl/ssl.rb", "lib/openssl/x509.rb"]
|
|
||||||
s.homepage = "https://github.com/ruby/openssl"
|
|
||||||
s.licenses = ["Ruby"]
|
|
||||||
s.rdoc_options = ["--main", "README.md"]
|
|
||||||
s.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
|
||||||
s.rubygems_version = "3.0.0.beta1"
|
|
||||||
s.summary = "OpenSSL provides SSL, TLS and general purpose cryptography."
|
|
||||||
|
|
||||||
s.add_runtime_dependency("ipaddr", [">= 0"])
|
spec.required_ruby_version = ">= 2.3.0"
|
||||||
s.add_development_dependency("rake", [">= 0"])
|
|
||||||
s.add_development_dependency("rake-compiler", [">= 0"])
|
spec.add_runtime_dependency "ipaddr"
|
||||||
s.add_development_dependency("test-unit", ["~> 3.0"])
|
spec.add_development_dependency "rake"
|
||||||
s.add_development_dependency("rdoc", [">= 0"])
|
spec.add_development_dependency "rake-compiler"
|
||||||
|
spec.add_development_dependency "test-unit", "~> 3.0"
|
||||||
|
spec.add_development_dependency "rdoc"
|
||||||
|
|
||||||
|
spec.metadata["msys2_mingw_dependencies"] = "openssl"
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
#include <openssl/hmac.h>
|
#include <openssl/hmac.h>
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
#include <openssl/conf.h>
|
#include <openssl/conf.h>
|
||||||
|
#include <openssl/conf_api.h>
|
||||||
#include <openssl/crypto.h>
|
#include <openssl/crypto.h>
|
||||||
#if !defined(OPENSSL_NO_ENGINE)
|
#if !defined(OPENSSL_NO_ENGINE)
|
||||||
# include <openssl/engine.h>
|
# include <openssl/engine.h>
|
||||||
|
|
|
||||||
|
|
@ -400,7 +400,7 @@ ossl_bn_is_negative(VALUE self)
|
||||||
if (!(result = BN_new())) { \
|
if (!(result = BN_new())) { \
|
||||||
ossl_raise(eBNError, NULL); \
|
ossl_raise(eBNError, NULL); \
|
||||||
} \
|
} \
|
||||||
if (!BN_##func(result, bn, ossl_bn_ctx)) { \
|
if (BN_##func(result, bn, ossl_bn_ctx) <= 0) { \
|
||||||
BN_free(result); \
|
BN_free(result); \
|
||||||
ossl_raise(eBNError, NULL); \
|
ossl_raise(eBNError, NULL); \
|
||||||
} \
|
} \
|
||||||
|
|
@ -426,7 +426,7 @@ BIGNUM_1c(sqr)
|
||||||
if (!(result = BN_new())) { \
|
if (!(result = BN_new())) { \
|
||||||
ossl_raise(eBNError, NULL); \
|
ossl_raise(eBNError, NULL); \
|
||||||
} \
|
} \
|
||||||
if (!BN_##func(result, bn1, bn2)) { \
|
if (BN_##func(result, bn1, bn2) <= 0) { \
|
||||||
BN_free(result); \
|
BN_free(result); \
|
||||||
ossl_raise(eBNError, NULL); \
|
ossl_raise(eBNError, NULL); \
|
||||||
} \
|
} \
|
||||||
|
|
@ -459,7 +459,7 @@ BIGNUM_2(sub)
|
||||||
if (!(result = BN_new())) { \
|
if (!(result = BN_new())) { \
|
||||||
ossl_raise(eBNError, NULL); \
|
ossl_raise(eBNError, NULL); \
|
||||||
} \
|
} \
|
||||||
if (!BN_##func(result, bn1, bn2, ossl_bn_ctx)) { \
|
if (BN_##func(result, bn1, bn2, ossl_bn_ctx) <= 0) { \
|
||||||
BN_free(result); \
|
BN_free(result); \
|
||||||
ossl_raise(eBNError, NULL); \
|
ossl_raise(eBNError, NULL); \
|
||||||
} \
|
} \
|
||||||
|
|
@ -503,11 +503,21 @@ BIGNUM_2c(gcd)
|
||||||
BIGNUM_2c(mod_sqr)
|
BIGNUM_2c(mod_sqr)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Document-method: OpenSSL::BN#mod_inverse
|
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* bn.mod_inverse(bn2) => aBN
|
* bn.mod_inverse(bn2) => aBN
|
||||||
*/
|
*/
|
||||||
BIGNUM_2c(mod_inverse)
|
static VALUE
|
||||||
|
ossl_bn_mod_inverse(VALUE self, VALUE other)
|
||||||
|
{
|
||||||
|
BIGNUM *bn1, *bn2 = GetBNPtr(other), *result;
|
||||||
|
VALUE obj;
|
||||||
|
GetBN(self, bn1);
|
||||||
|
obj = NewBN(rb_obj_class(self));
|
||||||
|
if (!(result = BN_mod_inverse(NULL, bn1, bn2, ossl_bn_ctx)))
|
||||||
|
ossl_raise(eBNError, "BN_mod_inverse");
|
||||||
|
SetBN(obj, result);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
|
|
@ -556,7 +566,7 @@ ossl_bn_div(VALUE self, VALUE other)
|
||||||
if (!(result = BN_new())) { \
|
if (!(result = BN_new())) { \
|
||||||
ossl_raise(eBNError, NULL); \
|
ossl_raise(eBNError, NULL); \
|
||||||
} \
|
} \
|
||||||
if (!BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx)) { \
|
if (BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx) <= 0) { \
|
||||||
BN_free(result); \
|
BN_free(result); \
|
||||||
ossl_raise(eBNError, NULL); \
|
ossl_raise(eBNError, NULL); \
|
||||||
} \
|
} \
|
||||||
|
|
@ -598,7 +608,7 @@ BIGNUM_3c(mod_exp)
|
||||||
{ \
|
{ \
|
||||||
BIGNUM *bn; \
|
BIGNUM *bn; \
|
||||||
GetBN(self, bn); \
|
GetBN(self, bn); \
|
||||||
if (!BN_##func(bn, NUM2INT(bit))) { \
|
if (BN_##func(bn, NUM2INT(bit)) <= 0) { \
|
||||||
ossl_raise(eBNError, NULL); \
|
ossl_raise(eBNError, NULL); \
|
||||||
} \
|
} \
|
||||||
return self; \
|
return self; \
|
||||||
|
|
@ -658,7 +668,7 @@ ossl_bn_is_bit_set(VALUE self, VALUE bit)
|
||||||
if (!(result = BN_new())) { \
|
if (!(result = BN_new())) { \
|
||||||
ossl_raise(eBNError, NULL); \
|
ossl_raise(eBNError, NULL); \
|
||||||
} \
|
} \
|
||||||
if (!BN_##func(result, bn, b)) { \
|
if (BN_##func(result, bn, b) <= 0) { \
|
||||||
BN_free(result); \
|
BN_free(result); \
|
||||||
ossl_raise(eBNError, NULL); \
|
ossl_raise(eBNError, NULL); \
|
||||||
} \
|
} \
|
||||||
|
|
@ -688,7 +698,7 @@ BIGNUM_SHIFT(rshift)
|
||||||
int b; \
|
int b; \
|
||||||
b = NUM2INT(bits); \
|
b = NUM2INT(bits); \
|
||||||
GetBN(self, bn); \
|
GetBN(self, bn); \
|
||||||
if (!BN_##func(bn, bn, b)) \
|
if (BN_##func(bn, bn, b) <= 0) \
|
||||||
ossl_raise(eBNError, NULL); \
|
ossl_raise(eBNError, NULL); \
|
||||||
return self; \
|
return self; \
|
||||||
}
|
}
|
||||||
|
|
@ -727,7 +737,7 @@ BIGNUM_SELF_SHIFT(rshift)
|
||||||
if (!(result = BN_new())) { \
|
if (!(result = BN_new())) { \
|
||||||
ossl_raise(eBNError, NULL); \
|
ossl_raise(eBNError, NULL); \
|
||||||
} \
|
} \
|
||||||
if (!BN_##func(result, b, top, bottom)) { \
|
if (BN_##func(result, b, top, bottom) <= 0) { \
|
||||||
BN_free(result); \
|
BN_free(result); \
|
||||||
ossl_raise(eBNError, NULL); \
|
ossl_raise(eBNError, NULL); \
|
||||||
} \
|
} \
|
||||||
|
|
@ -756,7 +766,7 @@ BIGNUM_RAND(pseudo_rand)
|
||||||
if (!(result = BN_new())) { \
|
if (!(result = BN_new())) { \
|
||||||
ossl_raise(eBNError, NULL); \
|
ossl_raise(eBNError, NULL); \
|
||||||
} \
|
} \
|
||||||
if (!BN_##func##_range(result, bn)) { \
|
if (BN_##func##_range(result, bn) <= 0) { \
|
||||||
BN_free(result); \
|
BN_free(result); \
|
||||||
ossl_raise(eBNError, NULL); \
|
ossl_raise(eBNError, NULL); \
|
||||||
} \
|
} \
|
||||||
|
|
|
||||||
|
|
@ -313,8 +313,6 @@ ossl_digest_block_length(VALUE self)
|
||||||
void
|
void
|
||||||
Init_ossl_digest(void)
|
Init_ossl_digest(void)
|
||||||
{
|
{
|
||||||
rb_require("digest");
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
mOSSL = rb_define_module("OpenSSL");
|
mOSSL = rb_define_module("OpenSSL");
|
||||||
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
|
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
|
||||||
|
|
@ -433,6 +431,12 @@ Init_ossl_digest(void)
|
||||||
* digest2 = sha256.digest(data2)
|
* digest2 = sha256.digest(data2)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Digest::Class is defined by the digest library. rb_require() cannot be
|
||||||
|
* used here because it bypasses RubyGems.
|
||||||
|
*/
|
||||||
|
rb_funcall(Qnil, rb_intern_const("require"), 1, rb_str_new_cstr("digest"));
|
||||||
cDigest = rb_define_class_under(mOSSL, "Digest", rb_path2class("Digest::Class"));
|
cDigest = rb_define_class_under(mOSSL, "Digest", rb_path2class("Digest::Class"));
|
||||||
/* Document-class: OpenSSL::Digest::DigestError
|
/* Document-class: OpenSSL::Digest::DigestError
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -803,9 +803,9 @@ ossl_pkcs7_decrypt(int argc, VALUE *argv, VALUE self)
|
||||||
BIO *out;
|
BIO *out;
|
||||||
VALUE str;
|
VALUE str;
|
||||||
|
|
||||||
rb_scan_args(argc, argv, "12", &pkey, &cert, &flags);
|
rb_scan_args(argc, argv, "21", &pkey, &cert, &flags);
|
||||||
key = GetPrivPKeyPtr(pkey); /* NO NEED TO DUP */
|
key = GetPrivPKeyPtr(pkey); /* NO NEED TO DUP */
|
||||||
x509 = NIL_P(cert) ? NULL : GetX509CertPtr(cert); /* NO NEED TO DUP */
|
x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */
|
||||||
flg = NIL_P(flags) ? 0 : NUM2INT(flags);
|
flg = NIL_P(flags) ? 0 : NUM2INT(flags);
|
||||||
GetPKCS7(self, p7);
|
GetPKCS7(self, p7);
|
||||||
if(!(out = BIO_new(BIO_s_mem())))
|
if(!(out = BIO_new(BIO_s_mem())))
|
||||||
|
|
|
||||||
|
|
@ -653,15 +653,15 @@ static VALUE ossl_ec_key_dsa_verify_asn1(VALUE self, VALUE data, VALUE sig)
|
||||||
StringValue(data);
|
StringValue(data);
|
||||||
StringValue(sig);
|
StringValue(sig);
|
||||||
|
|
||||||
switch (ECDSA_verify(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LENINT(data), (unsigned char *) RSTRING_PTR(sig), (int)RSTRING_LEN(sig), ec)) {
|
switch (ECDSA_verify(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LENINT(data),
|
||||||
case 1: return Qtrue;
|
(unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), ec)) {
|
||||||
case 0: return Qfalse;
|
case 1:
|
||||||
default: break;
|
return Qtrue;
|
||||||
|
case 0:
|
||||||
|
return Qfalse;
|
||||||
|
default:
|
||||||
|
ossl_raise(eECError, "ECDSA_verify");
|
||||||
}
|
}
|
||||||
|
|
||||||
ossl_raise(eECError, "ECDSA_verify");
|
|
||||||
|
|
||||||
UNREACHABLE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,12 @@
|
||||||
|
|
||||||
#define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0]))
|
#define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0]))
|
||||||
|
|
||||||
|
#if !defined(TLS1_3_VERSION) && \
|
||||||
|
defined(LIBRESSL_VERSION_NUMBER) && \
|
||||||
|
LIBRESSL_VERSION_NUMBER >= 0x3020000fL
|
||||||
|
# define TLS1_3_VERSION 0x0304
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# define TO_SOCKET(s) _get_osfhandle(s)
|
# define TO_SOCKET(s) _get_osfhandle(s)
|
||||||
#else
|
#else
|
||||||
|
|
@ -33,7 +39,7 @@ static VALUE eSSLErrorWaitReadable;
|
||||||
static VALUE eSSLErrorWaitWritable;
|
static VALUE eSSLErrorWaitWritable;
|
||||||
|
|
||||||
static ID id_call, ID_callback_state, id_tmp_dh_callback, id_tmp_ecdh_callback,
|
static ID id_call, ID_callback_state, id_tmp_dh_callback, id_tmp_ecdh_callback,
|
||||||
id_npn_protocols_encoded;
|
id_npn_protocols_encoded, id_each;
|
||||||
static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
|
static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
|
||||||
|
|
||||||
static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
|
static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
|
||||||
|
|
@ -53,6 +59,13 @@ static int ossl_sslctx_ex_ptr_idx;
|
||||||
static int ossl_sslctx_ex_store_p;
|
static int ossl_sslctx_ex_store_p;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
ossl_sslctx_mark(void *ptr)
|
||||||
|
{
|
||||||
|
SSL_CTX *ctx = ptr;
|
||||||
|
rb_gc_mark((VALUE)SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_ptr_idx));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ossl_sslctx_free(void *ptr)
|
ossl_sslctx_free(void *ptr)
|
||||||
{
|
{
|
||||||
|
|
@ -67,7 +80,7 @@ ossl_sslctx_free(void *ptr)
|
||||||
static const rb_data_type_t ossl_sslctx_type = {
|
static const rb_data_type_t ossl_sslctx_type = {
|
||||||
"OpenSSL/SSL/CTX",
|
"OpenSSL/SSL/CTX",
|
||||||
{
|
{
|
||||||
0, ossl_sslctx_free,
|
ossl_sslctx_mark, ossl_sslctx_free,
|
||||||
},
|
},
|
||||||
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
||||||
};
|
};
|
||||||
|
|
@ -359,7 +372,14 @@ ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
|
||||||
rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status));
|
rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
preverify_ok = ret == Qtrue;
|
if (ret != Qtrue) {
|
||||||
|
preverify_ok = 0;
|
||||||
|
#if defined(X509_V_ERR_HOSTNAME_MISMATCH)
|
||||||
|
X509_STORE_CTX_set_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH);
|
||||||
|
#else
|
||||||
|
X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ossl_verify_cb_call(cb, preverify_ok, ctx);
|
return ossl_verify_cb_call(cb, preverify_ok, ctx);
|
||||||
|
|
@ -609,7 +629,7 @@ static VALUE
|
||||||
ssl_encode_npn_protocols(VALUE protocols)
|
ssl_encode_npn_protocols(VALUE protocols)
|
||||||
{
|
{
|
||||||
VALUE encoded = rb_str_new(NULL, 0);
|
VALUE encoded = rb_str_new(NULL, 0);
|
||||||
rb_iterate(rb_each, protocols, ssl_npn_encode_protocol_i, encoded);
|
rb_block_call(protocols, id_each, 0, 0, ssl_npn_encode_protocol_i, encoded);
|
||||||
return encoded;
|
return encoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -679,7 +699,7 @@ static int
|
||||||
ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
|
ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
|
||||||
void *arg)
|
void *arg)
|
||||||
{
|
{
|
||||||
VALUE protocols = (VALUE)arg;
|
VALUE protocols = rb_attr_get((VALUE)arg, id_npn_protocols_encoded);
|
||||||
|
|
||||||
*out = (const unsigned char *) RSTRING_PTR(protocols);
|
*out = (const unsigned char *) RSTRING_PTR(protocols);
|
||||||
*outlen = RSTRING_LENINT(protocols);
|
*outlen = RSTRING_LENINT(protocols);
|
||||||
|
|
@ -897,7 +917,7 @@ ossl_sslctx_setup(VALUE self)
|
||||||
if (!NIL_P(val)) {
|
if (!NIL_P(val)) {
|
||||||
VALUE encoded = ssl_encode_npn_protocols(val);
|
VALUE encoded = ssl_encode_npn_protocols(val);
|
||||||
rb_ivar_set(self, id_npn_protocols_encoded, encoded);
|
rb_ivar_set(self, id_npn_protocols_encoded, encoded);
|
||||||
SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)encoded);
|
SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)self);
|
||||||
OSSL_Debug("SSL NPN advertise callback added");
|
OSSL_Debug("SSL NPN advertise callback added");
|
||||||
}
|
}
|
||||||
if (RTEST(rb_attr_get(self, id_i_npn_select_cb))) {
|
if (RTEST(rb_attr_get(self, id_i_npn_select_cb))) {
|
||||||
|
|
@ -1515,6 +1535,14 @@ ssl_started(SSL *ssl)
|
||||||
return SSL_get_fd(ssl) >= 0;
|
return SSL_get_fd(ssl) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ossl_ssl_mark(void *ptr)
|
||||||
|
{
|
||||||
|
SSL *ssl = ptr;
|
||||||
|
rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx));
|
||||||
|
rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ossl_ssl_free(void *ssl)
|
ossl_ssl_free(void *ssl)
|
||||||
{
|
{
|
||||||
|
|
@ -1524,7 +1552,7 @@ ossl_ssl_free(void *ssl)
|
||||||
const rb_data_type_t ossl_ssl_type = {
|
const rb_data_type_t ossl_ssl_type = {
|
||||||
"OpenSSL/SSL",
|
"OpenSSL/SSL",
|
||||||
{
|
{
|
||||||
0, ossl_ssl_free,
|
ossl_ssl_mark, ossl_ssl_free,
|
||||||
},
|
},
|
||||||
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
||||||
};
|
};
|
||||||
|
|
@ -1680,6 +1708,11 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
|
||||||
rb_io_wait_readable(fptr->fd);
|
rb_io_wait_readable(fptr->fd);
|
||||||
continue;
|
continue;
|
||||||
case SSL_ERROR_SYSCALL:
|
case SSL_ERROR_SYSCALL:
|
||||||
|
#ifdef __APPLE__
|
||||||
|
/* See ossl_ssl_write_internal() */
|
||||||
|
if (errno == EPROTOTYPE)
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
if (errno) rb_sys_fail(funcname);
|
if (errno) rb_sys_fail(funcname);
|
||||||
ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
|
ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
|
||||||
#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
|
#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
|
||||||
|
|
@ -1836,26 +1869,36 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
||||||
io = rb_attr_get(self, id_i_io);
|
io = rb_attr_get(self, id_i_io);
|
||||||
GetOpenFile(io, fptr);
|
GetOpenFile(io, fptr);
|
||||||
if (ssl_started(ssl)) {
|
if (ssl_started(ssl)) {
|
||||||
for (;;){
|
rb_str_locktmp(str);
|
||||||
|
for (;;) {
|
||||||
nread = SSL_read(ssl, RSTRING_PTR(str), ilen);
|
nread = SSL_read(ssl, RSTRING_PTR(str), ilen);
|
||||||
switch(ssl_get_error(ssl, nread)){
|
switch(ssl_get_error(ssl, nread)){
|
||||||
case SSL_ERROR_NONE:
|
case SSL_ERROR_NONE:
|
||||||
|
rb_str_unlocktmp(str);
|
||||||
goto end;
|
goto end;
|
||||||
case SSL_ERROR_ZERO_RETURN:
|
case SSL_ERROR_ZERO_RETURN:
|
||||||
|
rb_str_unlocktmp(str);
|
||||||
if (no_exception_p(opts)) { return Qnil; }
|
if (no_exception_p(opts)) { return Qnil; }
|
||||||
rb_eof_error();
|
rb_eof_error();
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
if (no_exception_p(opts)) { return sym_wait_writable; }
|
if (nonblock) {
|
||||||
write_would_block(nonblock);
|
rb_str_unlocktmp(str);
|
||||||
|
if (no_exception_p(opts)) { return sym_wait_writable; }
|
||||||
|
write_would_block(nonblock);
|
||||||
|
}
|
||||||
rb_io_wait_writable(fptr->fd);
|
rb_io_wait_writable(fptr->fd);
|
||||||
continue;
|
continue;
|
||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
if (no_exception_p(opts)) { return sym_wait_readable; }
|
if (nonblock) {
|
||||||
read_would_block(nonblock);
|
rb_str_unlocktmp(str);
|
||||||
|
if (no_exception_p(opts)) { return sym_wait_readable; }
|
||||||
|
read_would_block(nonblock);
|
||||||
|
}
|
||||||
rb_io_wait_readable(fptr->fd);
|
rb_io_wait_readable(fptr->fd);
|
||||||
continue;
|
continue;
|
||||||
case SSL_ERROR_SYSCALL:
|
case SSL_ERROR_SYSCALL:
|
||||||
if (!ERR_peek_error()) {
|
if (!ERR_peek_error()) {
|
||||||
|
rb_str_unlocktmp(str);
|
||||||
if (errno)
|
if (errno)
|
||||||
rb_sys_fail(0);
|
rb_sys_fail(0);
|
||||||
else {
|
else {
|
||||||
|
|
@ -1872,23 +1915,30 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
|
||||||
}
|
}
|
||||||
/* fall through */
|
/* fall through */
|
||||||
default:
|
default:
|
||||||
|
rb_str_unlocktmp(str);
|
||||||
ossl_raise(eSSLError, "SSL_read");
|
ossl_raise(eSSLError, "SSL_read");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread");
|
ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread");
|
||||||
|
|
||||||
rb_warning("SSL session is not started yet.");
|
rb_warning("SSL session is not started yet.");
|
||||||
if (nonblock) {
|
#if defined(RB_PASS_KEYWORDS)
|
||||||
|
if (nonblock) {
|
||||||
VALUE argv[3];
|
VALUE argv[3];
|
||||||
argv[0] = len;
|
argv[0] = len;
|
||||||
argv[1] = str;
|
argv[1] = str;
|
||||||
argv[2] = opts;
|
argv[2] = opts;
|
||||||
return rb_funcallv_kw(io, meth, 3, argv, RB_PASS_KEYWORDS);
|
return rb_funcallv_kw(io, meth, 3, argv, RB_PASS_KEYWORDS);
|
||||||
}
|
}
|
||||||
else
|
#else
|
||||||
return rb_funcall(io, meth, 2, len, str);
|
if (nonblock) {
|
||||||
|
return rb_funcall(io, meth, 3, len, str, opts);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
return rb_funcall(io, meth, 2, len, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
|
@ -1936,21 +1986,21 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
|
||||||
int nwrite = 0;
|
int nwrite = 0;
|
||||||
rb_io_t *fptr;
|
rb_io_t *fptr;
|
||||||
int nonblock = opts != Qfalse;
|
int nonblock = opts != Qfalse;
|
||||||
VALUE io;
|
VALUE tmp, io;
|
||||||
|
|
||||||
StringValue(str);
|
tmp = rb_str_new_frozen(StringValue(str));
|
||||||
GetSSL(self, ssl);
|
GetSSL(self, ssl);
|
||||||
io = rb_attr_get(self, id_i_io);
|
io = rb_attr_get(self, id_i_io);
|
||||||
GetOpenFile(io, fptr);
|
GetOpenFile(io, fptr);
|
||||||
if (ssl_started(ssl)) {
|
if (ssl_started(ssl)) {
|
||||||
for (;;){
|
for (;;) {
|
||||||
int num = RSTRING_LENINT(str);
|
int num = RSTRING_LENINT(tmp);
|
||||||
|
|
||||||
/* SSL_write(3ssl) manpage states num == 0 is undefined */
|
/* SSL_write(3ssl) manpage states num == 0 is undefined */
|
||||||
if (num == 0)
|
if (num == 0)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
nwrite = SSL_write(ssl, RSTRING_PTR(str), num);
|
nwrite = SSL_write(ssl, RSTRING_PTR(tmp), num);
|
||||||
switch(ssl_get_error(ssl, nwrite)){
|
switch(ssl_get_error(ssl, nwrite)){
|
||||||
case SSL_ERROR_NONE:
|
case SSL_ERROR_NONE:
|
||||||
goto end;
|
goto end;
|
||||||
|
|
@ -1965,6 +2015,16 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
|
||||||
rb_io_wait_readable(fptr->fd);
|
rb_io_wait_readable(fptr->fd);
|
||||||
continue;
|
continue;
|
||||||
case SSL_ERROR_SYSCALL:
|
case SSL_ERROR_SYSCALL:
|
||||||
|
#ifdef __APPLE__
|
||||||
|
/*
|
||||||
|
* It appears that send syscall can return EPROTOTYPE if the
|
||||||
|
* socket is being torn down. Retry to get a proper errno to
|
||||||
|
* make the error handling in line with the socket library.
|
||||||
|
* [Bug #14713] https://bugs.ruby-lang.org/issues/14713
|
||||||
|
*/
|
||||||
|
if (errno == EPROTOTYPE)
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
if (errno) rb_sys_fail(0);
|
if (errno) rb_sys_fail(0);
|
||||||
default:
|
default:
|
||||||
ossl_raise(eSSLError, "SSL_write");
|
ossl_raise(eSSLError, "SSL_write");
|
||||||
|
|
@ -1975,15 +2035,21 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
|
||||||
ID meth = nonblock ?
|
ID meth = nonblock ?
|
||||||
rb_intern("write_nonblock") : rb_intern("syswrite");
|
rb_intern("write_nonblock") : rb_intern("syswrite");
|
||||||
|
|
||||||
rb_warning("SSL session is not started yet.");
|
rb_warning("SSL session is not started yet.");
|
||||||
if (nonblock) {
|
#if defined(RB_PASS_KEYWORDS)
|
||||||
|
if (nonblock) {
|
||||||
VALUE argv[2];
|
VALUE argv[2];
|
||||||
argv[0] = str;
|
argv[0] = str;
|
||||||
argv[1] = opts;
|
argv[1] = opts;
|
||||||
return rb_funcallv_kw(io, meth, 2, argv, RB_PASS_KEYWORDS);
|
return rb_funcallv_kw(io, meth, 2, argv, RB_PASS_KEYWORDS);
|
||||||
}
|
}
|
||||||
else
|
#else
|
||||||
return rb_funcall(io, meth, 1, str);
|
if (nonblock) {
|
||||||
|
return rb_funcall(io, meth, 2, str, opts);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
return rb_funcall(io, meth, 1, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
|
@ -2926,6 +2992,7 @@ Init_ossl_ssl(void)
|
||||||
id_tmp_dh_callback = rb_intern("tmp_dh_callback");
|
id_tmp_dh_callback = rb_intern("tmp_dh_callback");
|
||||||
id_tmp_ecdh_callback = rb_intern("tmp_ecdh_callback");
|
id_tmp_ecdh_callback = rb_intern("tmp_ecdh_callback");
|
||||||
id_npn_protocols_encoded = rb_intern("npn_protocols_encoded");
|
id_npn_protocols_encoded = rb_intern("npn_protocols_encoded");
|
||||||
|
id_each = rb_intern_const("each");
|
||||||
|
|
||||||
#define DefIVarID(name) do \
|
#define DefIVarID(name) do \
|
||||||
id_i_##name = rb_intern("@"#name); while (0)
|
id_i_##name = rb_intern("@"#name); while (0)
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,6 @@
|
||||||
#if !defined(_OSSL_VERSION_H_)
|
#if !defined(_OSSL_VERSION_H_)
|
||||||
#define _OSSL_VERSION_H_
|
#define _OSSL_VERSION_H_
|
||||||
|
|
||||||
#define OSSL_VERSION "2.1.2"
|
#define OSSL_VERSION "2.1.3"
|
||||||
|
|
||||||
#endif /* _OSSL_VERSION_H_ */
|
#endif /* _OSSL_VERSION_H_ */
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,13 @@ Init_ossl_x509(void)
|
||||||
Init_ossl_x509revoked();
|
Init_ossl_x509revoked();
|
||||||
Init_ossl_x509store();
|
Init_ossl_x509store();
|
||||||
|
|
||||||
|
/* Constants are up-to-date with 1.1.1. */
|
||||||
|
|
||||||
|
/* Certificate verification error code */
|
||||||
DefX509Const(V_OK);
|
DefX509Const(V_OK);
|
||||||
|
#if defined(X509_V_ERR_UNSPECIFIED) /* 1.0.1r, 1.0.2f, 1.1.0 */
|
||||||
|
DefX509Const(V_ERR_UNSPECIFIED);
|
||||||
|
#endif
|
||||||
DefX509Const(V_ERR_UNABLE_TO_GET_ISSUER_CERT);
|
DefX509Const(V_ERR_UNABLE_TO_GET_ISSUER_CERT);
|
||||||
DefX509Const(V_ERR_UNABLE_TO_GET_CRL);
|
DefX509Const(V_ERR_UNABLE_TO_GET_CRL);
|
||||||
DefX509Const(V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE);
|
DefX509Const(V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE);
|
||||||
|
|
@ -76,8 +82,73 @@ Init_ossl_x509(void)
|
||||||
DefX509Const(V_ERR_AKID_SKID_MISMATCH);
|
DefX509Const(V_ERR_AKID_SKID_MISMATCH);
|
||||||
DefX509Const(V_ERR_AKID_ISSUER_SERIAL_MISMATCH);
|
DefX509Const(V_ERR_AKID_ISSUER_SERIAL_MISMATCH);
|
||||||
DefX509Const(V_ERR_KEYUSAGE_NO_CERTSIGN);
|
DefX509Const(V_ERR_KEYUSAGE_NO_CERTSIGN);
|
||||||
|
DefX509Const(V_ERR_UNABLE_TO_GET_CRL_ISSUER);
|
||||||
|
DefX509Const(V_ERR_UNHANDLED_CRITICAL_EXTENSION);
|
||||||
|
DefX509Const(V_ERR_KEYUSAGE_NO_CRL_SIGN);
|
||||||
|
DefX509Const(V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION);
|
||||||
|
DefX509Const(V_ERR_INVALID_NON_CA);
|
||||||
|
DefX509Const(V_ERR_PROXY_PATH_LENGTH_EXCEEDED);
|
||||||
|
DefX509Const(V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE);
|
||||||
|
DefX509Const(V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED);
|
||||||
|
DefX509Const(V_ERR_INVALID_EXTENSION);
|
||||||
|
DefX509Const(V_ERR_INVALID_POLICY_EXTENSION);
|
||||||
|
DefX509Const(V_ERR_NO_EXPLICIT_POLICY);
|
||||||
|
DefX509Const(V_ERR_DIFFERENT_CRL_SCOPE);
|
||||||
|
DefX509Const(V_ERR_UNSUPPORTED_EXTENSION_FEATURE);
|
||||||
|
DefX509Const(V_ERR_UNNESTED_RESOURCE);
|
||||||
|
DefX509Const(V_ERR_PERMITTED_VIOLATION);
|
||||||
|
DefX509Const(V_ERR_EXCLUDED_VIOLATION);
|
||||||
|
DefX509Const(V_ERR_SUBTREE_MINMAX);
|
||||||
DefX509Const(V_ERR_APPLICATION_VERIFICATION);
|
DefX509Const(V_ERR_APPLICATION_VERIFICATION);
|
||||||
|
DefX509Const(V_ERR_UNSUPPORTED_CONSTRAINT_TYPE);
|
||||||
|
DefX509Const(V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX);
|
||||||
|
DefX509Const(V_ERR_UNSUPPORTED_NAME_SYNTAX);
|
||||||
|
DefX509Const(V_ERR_CRL_PATH_VALIDATION_ERROR);
|
||||||
|
#if defined(X509_V_ERR_PATH_LOOP)
|
||||||
|
DefX509Const(V_ERR_PATH_LOOP);
|
||||||
|
#endif
|
||||||
|
#if defined(X509_V_ERR_SUITE_B_INVALID_VERSION)
|
||||||
|
DefX509Const(V_ERR_SUITE_B_INVALID_VERSION);
|
||||||
|
DefX509Const(V_ERR_SUITE_B_INVALID_ALGORITHM);
|
||||||
|
DefX509Const(V_ERR_SUITE_B_INVALID_CURVE);
|
||||||
|
DefX509Const(V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM);
|
||||||
|
DefX509Const(V_ERR_SUITE_B_LOS_NOT_ALLOWED);
|
||||||
|
DefX509Const(V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256);
|
||||||
|
#endif
|
||||||
|
#if defined(X509_V_ERR_HOSTNAME_MISMATCH)
|
||||||
|
DefX509Const(V_ERR_HOSTNAME_MISMATCH);
|
||||||
|
DefX509Const(V_ERR_EMAIL_MISMATCH);
|
||||||
|
DefX509Const(V_ERR_IP_ADDRESS_MISMATCH);
|
||||||
|
#endif
|
||||||
|
#if defined(X509_V_ERR_DANE_NO_MATCH)
|
||||||
|
DefX509Const(V_ERR_DANE_NO_MATCH);
|
||||||
|
#endif
|
||||||
|
#if defined(X509_V_ERR_EE_KEY_TOO_SMALL)
|
||||||
|
DefX509Const(V_ERR_EE_KEY_TOO_SMALL);
|
||||||
|
DefX509Const(V_ERR_CA_KEY_TOO_SMALL);
|
||||||
|
DefX509Const(V_ERR_CA_MD_TOO_WEAK);
|
||||||
|
#endif
|
||||||
|
#if defined(X509_V_ERR_INVALID_CALL)
|
||||||
|
DefX509Const(V_ERR_INVALID_CALL);
|
||||||
|
#endif
|
||||||
|
#if defined(X509_V_ERR_STORE_LOOKUP)
|
||||||
|
DefX509Const(V_ERR_STORE_LOOKUP);
|
||||||
|
#endif
|
||||||
|
#if defined(X509_V_ERR_NO_VALID_SCTS)
|
||||||
|
DefX509Const(V_ERR_NO_VALID_SCTS);
|
||||||
|
#endif
|
||||||
|
#if defined(X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION)
|
||||||
|
DefX509Const(V_ERR_PROXY_SUBJECT_NAME_VIOLATION);
|
||||||
|
#endif
|
||||||
|
#if defined(X509_V_ERR_OCSP_VERIFY_NEEDED)
|
||||||
|
DefX509Const(V_ERR_OCSP_VERIFY_NEEDED);
|
||||||
|
DefX509Const(V_ERR_OCSP_VERIFY_FAILED);
|
||||||
|
DefX509Const(V_ERR_OCSP_CERT_UNKNOWN);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Certificate verify flags */
|
||||||
|
/* Set by Store#flags= and StoreContext#flags=. */
|
||||||
|
DefX509Const(V_FLAG_USE_CHECK_TIME);
|
||||||
/* Set by Store#flags= and StoreContext#flags=. Enables CRL checking for the
|
/* Set by Store#flags= and StoreContext#flags=. Enables CRL checking for the
|
||||||
* certificate chain leaf. */
|
* certificate chain leaf. */
|
||||||
DefX509Const(V_FLAG_CRL_CHECK);
|
DefX509Const(V_FLAG_CRL_CHECK);
|
||||||
|
|
@ -122,6 +193,26 @@ Init_ossl_x509(void)
|
||||||
* Enabled by default in OpenSSL >= 1.1.0. */
|
* Enabled by default in OpenSSL >= 1.1.0. */
|
||||||
DefX509Const(V_FLAG_TRUSTED_FIRST);
|
DefX509Const(V_FLAG_TRUSTED_FIRST);
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(X509_V_FLAG_SUITEB_128_LOS_ONLY)
|
||||||
|
/* Set by Store#flags= and StoreContext#flags=.
|
||||||
|
* Enables Suite B 128 bit only mode. */
|
||||||
|
DefX509Const(V_FLAG_SUITEB_128_LOS_ONLY);
|
||||||
|
#endif
|
||||||
|
#if defined(X509_V_FLAG_SUITEB_192_LOS)
|
||||||
|
/* Set by Store#flags= and StoreContext#flags=.
|
||||||
|
* Enables Suite B 192 bit only mode. */
|
||||||
|
DefX509Const(V_FLAG_SUITEB_192_LOS);
|
||||||
|
#endif
|
||||||
|
#if defined(X509_V_FLAG_SUITEB_128_LOS)
|
||||||
|
/* Set by Store#flags= and StoreContext#flags=.
|
||||||
|
* Enables Suite B 128 bit mode allowing 192 bit algorithms. */
|
||||||
|
DefX509Const(V_FLAG_SUITEB_128_LOS);
|
||||||
|
#endif
|
||||||
|
#if defined(X509_V_FLAG_PARTIAL_CHAIN)
|
||||||
|
/* Set by Store#flags= and StoreContext#flags=.
|
||||||
|
* Allows partial chains if at least one certificate is in trusted store. */
|
||||||
|
DefX509Const(V_FLAG_PARTIAL_CHAIN);
|
||||||
|
#endif
|
||||||
#if defined(X509_V_FLAG_NO_ALT_CHAINS)
|
#if defined(X509_V_FLAG_NO_ALT_CHAINS)
|
||||||
/* Set by Store#flags= and StoreContext#flags=. Suppresses searching for
|
/* Set by Store#flags= and StoreContext#flags=. Suppresses searching for
|
||||||
* a alternative chain. No effect in OpenSSL >= 1.1.0. */
|
* a alternative chain. No effect in OpenSSL >= 1.1.0. */
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,13 @@ VALUE cX509Store;
|
||||||
VALUE cX509StoreContext;
|
VALUE cX509StoreContext;
|
||||||
VALUE eX509StoreError;
|
VALUE eX509StoreError;
|
||||||
|
|
||||||
|
static void
|
||||||
|
ossl_x509store_mark(void *ptr)
|
||||||
|
{
|
||||||
|
X509_STORE *store = ptr;
|
||||||
|
rb_gc_mark((VALUE)X509_STORE_get_ex_data(store, store_ex_verify_cb_idx));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ossl_x509store_free(void *ptr)
|
ossl_x509store_free(void *ptr)
|
||||||
{
|
{
|
||||||
|
|
@ -114,7 +121,7 @@ ossl_x509store_free(void *ptr)
|
||||||
static const rb_data_type_t ossl_x509store_type = {
|
static const rb_data_type_t ossl_x509store_type = {
|
||||||
"OpenSSL/X509/STORE",
|
"OpenSSL/X509/STORE",
|
||||||
{
|
{
|
||||||
0, ossl_x509store_free,
|
ossl_x509store_mark, ossl_x509store_free,
|
||||||
},
|
},
|
||||||
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
||||||
};
|
};
|
||||||
|
|
@ -456,23 +463,16 @@ ossl_x509store_verify(int argc, VALUE *argv, VALUE self)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Public Functions
|
|
||||||
*/
|
|
||||||
static void ossl_x509stctx_free(void*);
|
|
||||||
|
|
||||||
|
|
||||||
static const rb_data_type_t ossl_x509stctx_type = {
|
|
||||||
"OpenSSL/X509/STORE_CTX",
|
|
||||||
{
|
|
||||||
0, ossl_x509stctx_free,
|
|
||||||
},
|
|
||||||
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Private functions
|
* Private functions
|
||||||
*/
|
*/
|
||||||
|
static void
|
||||||
|
ossl_x509stctx_mark(void *ptr)
|
||||||
|
{
|
||||||
|
X509_STORE_CTX *ctx = ptr;
|
||||||
|
rb_gc_mark((VALUE)X509_STORE_CTX_get_ex_data(ctx, stctx_ex_verify_cb_idx));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ossl_x509stctx_free(void *ptr)
|
ossl_x509stctx_free(void *ptr)
|
||||||
{
|
{
|
||||||
|
|
@ -484,6 +484,14 @@ ossl_x509stctx_free(void *ptr)
|
||||||
X509_STORE_CTX_free(ctx);
|
X509_STORE_CTX_free(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const rb_data_type_t ossl_x509stctx_type = {
|
||||||
|
"OpenSSL/X509/STORE_CTX",
|
||||||
|
{
|
||||||
|
ossl_x509stctx_mark, ossl_x509stctx_free,
|
||||||
|
},
|
||||||
|
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
||||||
|
};
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
ossl_x509stctx_alloc(VALUE klass)
|
ossl_x509stctx_alloc(VALUE klass)
|
||||||
{
|
{
|
||||||
|
|
@ -517,7 +525,9 @@ static VALUE ossl_x509stctx_set_time(VALUE, VALUE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* StoreContext.new(store, cert = nil, chain = nil)
|
* StoreContext.new(store, cert = nil, untrusted = nil)
|
||||||
|
*
|
||||||
|
* Sets up a StoreContext for a verification of the X.509 certificate _cert_.
|
||||||
*/
|
*/
|
||||||
static VALUE
|
static VALUE
|
||||||
ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self)
|
ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self)
|
||||||
|
|
@ -527,15 +537,24 @@ ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self)
|
||||||
X509_STORE *x509st;
|
X509_STORE *x509st;
|
||||||
X509 *x509 = NULL;
|
X509 *x509 = NULL;
|
||||||
STACK_OF(X509) *x509s = NULL;
|
STACK_OF(X509) *x509s = NULL;
|
||||||
|
int state;
|
||||||
|
|
||||||
rb_scan_args(argc, argv, "12", &store, &cert, &chain);
|
rb_scan_args(argc, argv, "12", &store, &cert, &chain);
|
||||||
GetX509StCtx(self, ctx);
|
GetX509StCtx(self, ctx);
|
||||||
GetX509Store(store, x509st);
|
GetX509Store(store, x509st);
|
||||||
if(!NIL_P(cert)) x509 = DupX509CertPtr(cert); /* NEED TO DUP */
|
if (!NIL_P(cert))
|
||||||
if(!NIL_P(chain)) x509s = ossl_x509_ary2sk(chain);
|
x509 = DupX509CertPtr(cert); /* NEED TO DUP */
|
||||||
if(X509_STORE_CTX_init(ctx, x509st, x509, x509s) != 1){
|
if (!NIL_P(chain)) {
|
||||||
|
x509s = ossl_protect_x509_ary2sk(chain, &state);
|
||||||
|
if (state) {
|
||||||
|
X509_free(x509);
|
||||||
|
rb_jump_tag(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (X509_STORE_CTX_init(ctx, x509st, x509, x509s) != 1){
|
||||||
|
X509_free(x509);
|
||||||
sk_X509_pop_free(x509s, X509_free);
|
sk_X509_pop_free(x509s, X509_free);
|
||||||
ossl_raise(eX509StoreError, NULL);
|
ossl_raise(eX509StoreError, "X509_STORE_CTX_init");
|
||||||
}
|
}
|
||||||
if (!NIL_P(t = rb_iv_get(store, "@time")))
|
if (!NIL_P(t = rb_iv_get(store, "@time")))
|
||||||
ossl_x509stctx_set_time(self, t);
|
ossl_x509stctx_set_time(self, t);
|
||||||
|
|
|
||||||
|
|
@ -635,11 +635,6 @@ class OpenSSL::TestASN1 < OpenSSL::TestCase
|
||||||
assert_equal data, seq.entries
|
assert_equal data, seq.entries
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_gc_stress
|
|
||||||
skip "very time consuming test"
|
|
||||||
assert_ruby_status(['--disable-gems', '-eGC.stress=true', '-erequire "openssl.so"'])
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def B(ary)
|
def B(ary)
|
||||||
|
|
|
||||||
|
|
@ -272,11 +272,6 @@ class OpenSSL::TestBN < OpenSSL::TestCase
|
||||||
assert_equal(0, @e1.ucmp(-999))
|
assert_equal(0, @e1.ucmp(-999))
|
||||||
assert_instance_of(String, @e1.hash.to_s)
|
assert_instance_of(String, @e1.hash.to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_type_error
|
|
||||||
bug15760 = '[ruby-core:92231] [Bug #15760]'
|
|
||||||
assert_raise(TypeError, bug15760) { OpenSSL::BN.new(nil, 2) }
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -133,8 +133,6 @@ class OpenSSL::TestPKCS7 < OpenSSL::TestCase
|
||||||
assert_equal(@ca_cert.subject.to_s, recip[1].issuer.to_s)
|
assert_equal(@ca_cert.subject.to_s, recip[1].issuer.to_s)
|
||||||
assert_equal(3, recip[1].serial)
|
assert_equal(3, recip[1].serial)
|
||||||
assert_equal(data, p7.decrypt(@rsa1024, @ee2_cert))
|
assert_equal(data, p7.decrypt(@rsa1024, @ee2_cert))
|
||||||
|
|
||||||
assert_equal(data, p7.decrypt(@rsa1024))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_graceful_parsing_failure #[ruby-core:43250]
|
def test_graceful_parsing_failure #[ruby-core:43250]
|
||||||
|
|
|
||||||
|
|
@ -155,21 +155,6 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_sysread_nonblock_and_syswrite_nonblock_keywords
|
|
||||||
start_server(ignore_listener_error: true) do |port|
|
|
||||||
sock = TCPSocket.new("127.0.0.1", port)
|
|
||||||
ssl = OpenSSL::SSL::SSLSocket.new(sock)
|
|
||||||
|
|
||||||
assert_warn ("") do
|
|
||||||
ssl.send(:syswrite_nonblock, "1", exception: false)
|
|
||||||
ssl.send(:sysread_nonblock, 1, exception: false) rescue nil
|
|
||||||
ssl.send(:sysread_nonblock, 1, String.new, exception: false) rescue nil
|
|
||||||
end
|
|
||||||
ensure
|
|
||||||
sock&.close
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_sync_close
|
def test_sync_close
|
||||||
start_server { |port|
|
start_server { |port|
|
||||||
begin
|
begin
|
||||||
|
|
@ -222,7 +207,10 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
|
||||||
|
|
||||||
def test_client_auth_success
|
def test_client_auth_success
|
||||||
vflag = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
|
vflag = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
|
||||||
start_server(verify_mode: vflag) { |port|
|
start_server(verify_mode: vflag,
|
||||||
|
ctx_proc: proc { |ctx|
|
||||||
|
ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION if libressl?(3, 2, 0)
|
||||||
|
}) { |port|
|
||||||
ctx = OpenSSL::SSL::SSLContext.new
|
ctx = OpenSSL::SSL::SSLContext.new
|
||||||
ctx.key = @cli_key
|
ctx.key = @cli_key
|
||||||
ctx.cert = @cli_cert
|
ctx.cert = @cli_cert
|
||||||
|
|
@ -268,6 +256,8 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_client_ca
|
def test_client_ca
|
||||||
|
pend "LibreSSL 3.2 has broken client CA support" if libressl?(3, 2, 0)
|
||||||
|
|
||||||
ctx_proc = Proc.new do |ctx|
|
ctx_proc = Proc.new do |ctx|
|
||||||
ctx.client_ca = [@ca_cert]
|
ctx.client_ca = [@ca_cert]
|
||||||
end
|
end
|
||||||
|
|
@ -808,11 +798,13 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
|
||||||
|
|
||||||
def test_verify_hostname_on_connect
|
def test_verify_hostname_on_connect
|
||||||
ctx_proc = proc { |ctx|
|
ctx_proc = proc { |ctx|
|
||||||
|
san = "DNS:a.example.com,DNS:*.b.example.com"
|
||||||
|
san += ",DNS:c*.example.com,DNS:d.*.example.com" unless libressl?(3, 2, 2)
|
||||||
exts = [
|
exts = [
|
||||||
["keyUsage", "keyEncipherment,digitalSignature", true],
|
["keyUsage", "keyEncipherment,digitalSignature", true],
|
||||||
["subjectAltName", "DNS:a.example.com,DNS:*.b.example.com," \
|
["subjectAltName", san],
|
||||||
"DNS:c*.example.com,DNS:d.*.example.com"],
|
|
||||||
]
|
]
|
||||||
|
|
||||||
ctx.cert = issue_cert(@svr, @svr_key, 4, exts, @ca_cert, @ca_key)
|
ctx.cert = issue_cert(@svr, @svr_key, 4, exts, @ca_cert, @ca_key)
|
||||||
ctx.key = @svr_key
|
ctx.key = @svr_key
|
||||||
}
|
}
|
||||||
|
|
@ -833,6 +825,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
|
||||||
["cx.example.com", true],
|
["cx.example.com", true],
|
||||||
["d.x.example.com", false],
|
["d.x.example.com", false],
|
||||||
].each do |name, expected_ok|
|
].each do |name, expected_ok|
|
||||||
|
next if name.start_with?('cx') if libressl?(3, 2, 2)
|
||||||
begin
|
begin
|
||||||
sock = TCPSocket.new("127.0.0.1", port)
|
sock = TCPSocket.new("127.0.0.1", port)
|
||||||
ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
|
ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
|
||||||
|
|
@ -851,6 +844,46 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_verify_hostname_failure_error_code
|
||||||
|
ctx_proc = proc { |ctx|
|
||||||
|
exts = [
|
||||||
|
["keyUsage", "keyEncipherment,digitalSignature", true],
|
||||||
|
["subjectAltName", "DNS:a.example.com"],
|
||||||
|
]
|
||||||
|
ctx.cert = issue_cert(@svr, @svr_key, 4, exts, @ca_cert, @ca_key)
|
||||||
|
ctx.key = @svr_key
|
||||||
|
}
|
||||||
|
|
||||||
|
start_server(ctx_proc: ctx_proc, ignore_listener_error: true) do |port|
|
||||||
|
verify_callback_ok = verify_callback_err = nil
|
||||||
|
|
||||||
|
ctx = OpenSSL::SSL::SSLContext.new
|
||||||
|
ctx.verify_hostname = true
|
||||||
|
ctx.cert_store = OpenSSL::X509::Store.new
|
||||||
|
ctx.cert_store.add_cert(@ca_cert)
|
||||||
|
ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
||||||
|
ctx.verify_callback = -> (preverify_ok, store_ctx) {
|
||||||
|
verify_callback_ok = preverify_ok
|
||||||
|
verify_callback_err = store_ctx.error
|
||||||
|
preverify_ok
|
||||||
|
}
|
||||||
|
|
||||||
|
begin
|
||||||
|
sock = TCPSocket.new("127.0.0.1", port)
|
||||||
|
ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
|
||||||
|
ssl.hostname = "b.example.com"
|
||||||
|
assert_handshake_error { ssl.connect }
|
||||||
|
assert_equal false, verify_callback_ok
|
||||||
|
code_expected = openssl?(1, 0, 2) || defined?(OpenSSL::X509::V_ERR_HOSTNAME_MISMATCH) ?
|
||||||
|
OpenSSL::X509::V_ERR_HOSTNAME_MISMATCH :
|
||||||
|
OpenSSL::X509::V_ERR_CERT_REJECTED
|
||||||
|
assert_equal code_expected, verify_callback_err
|
||||||
|
ensure
|
||||||
|
sock&.close
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_connect_certificate_verify_failed_exception_message
|
def test_connect_certificate_verify_failed_exception_message
|
||||||
start_server(ignore_listener_error: true) { |port|
|
start_server(ignore_listener_error: true) { |port|
|
||||||
ctx = OpenSSL::SSL::SSLContext.new
|
ctx = OpenSSL::SSL::SSLContext.new
|
||||||
|
|
@ -1476,12 +1509,13 @@ end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_ecdh_curves
|
def test_ecdh_curves_tls12
|
||||||
pend "EC is disabled" unless defined?(OpenSSL::PKey::EC)
|
pend "EC is disabled" unless defined?(OpenSSL::PKey::EC)
|
||||||
|
|
||||||
ctx_proc = -> ctx {
|
ctx_proc = -> ctx {
|
||||||
# Enable both ECDHE (~ TLS 1.2) cipher suites and TLS 1.3
|
# Enable both ECDHE (~ TLS 1.2) cipher suites and TLS 1.3
|
||||||
ctx.ciphers = "DEFAULT:!kRSA:!kEDH"
|
ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
|
||||||
|
ctx.ciphers = "kEECDH"
|
||||||
ctx.ecdh_curves = "P-384:P-521"
|
ctx.ecdh_curves = "P-384:P-521"
|
||||||
}
|
}
|
||||||
start_server(ctx_proc: ctx_proc, ignore_listener_error: true) do |port|
|
start_server(ctx_proc: ctx_proc, ignore_listener_error: true) do |port|
|
||||||
|
|
@ -1490,13 +1524,9 @@ end
|
||||||
|
|
||||||
server_connect(port, ctx) { |ssl|
|
server_connect(port, ctx) { |ssl|
|
||||||
cs = ssl.cipher[0]
|
cs = ssl.cipher[0]
|
||||||
if /\ATLS/ =~ cs # Is TLS 1.3 is used?
|
assert_match (/\AECDH/), cs
|
||||||
|
if ssl.respond_to?(:tmp_key)
|
||||||
assert_equal "secp384r1", ssl.tmp_key.group.curve_name
|
assert_equal "secp384r1", ssl.tmp_key.group.curve_name
|
||||||
else
|
|
||||||
assert_match (/\AECDH/), cs
|
|
||||||
if ssl.respond_to?(:tmp_key)
|
|
||||||
assert_equal "secp384r1", ssl.tmp_key.group.curve_name
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
ssl.puts "abc"; assert_equal "abc\n", ssl.gets
|
ssl.puts "abc"; assert_equal "abc\n", ssl.gets
|
||||||
}
|
}
|
||||||
|
|
@ -1520,6 +1550,26 @@ end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_ecdh_curves_tls13
|
||||||
|
pend "EC is disabled" unless defined?(OpenSSL::PKey::EC)
|
||||||
|
pend "TLS 1.3 not supported" unless tls13_supported?
|
||||||
|
|
||||||
|
ctx_proc = -> ctx {
|
||||||
|
# Assume TLS 1.3 is enabled and chosen by default
|
||||||
|
ctx.ecdh_curves = "P-384:P-521"
|
||||||
|
}
|
||||||
|
start_server(ctx_proc: ctx_proc, ignore_listener_error: true) do |port|
|
||||||
|
ctx = OpenSSL::SSL::SSLContext.new
|
||||||
|
ctx.ecdh_curves = "P-256:P-384" # disable P-521
|
||||||
|
|
||||||
|
server_connect(port, ctx) { |ssl|
|
||||||
|
assert_equal "TLSv1.3", ssl.ssl_version
|
||||||
|
assert_equal "secp384r1", ssl.tmp_key.group.curve_name
|
||||||
|
ssl.puts "abc"; assert_equal "abc\n", ssl.gets
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_security_level
|
def test_security_level
|
||||||
ctx = OpenSSL::SSL::SSLContext.new
|
ctx = OpenSSL::SSL::SSLContext.new
|
||||||
begin
|
begin
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,7 @@ __EOS__
|
||||||
ctx.options &= ~OpenSSL::SSL::OP_NO_TICKET
|
ctx.options &= ~OpenSSL::SSL::OP_NO_TICKET
|
||||||
# Disable server-side session cache which is enabled by default
|
# Disable server-side session cache which is enabled by default
|
||||||
ctx.session_cache_mode = OpenSSL::SSL::SSLContext::SESSION_CACHE_OFF
|
ctx.session_cache_mode = OpenSSL::SSL::SSLContext::SESSION_CACHE_OFF
|
||||||
|
ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION if libressl?(3, 2, 0)
|
||||||
}
|
}
|
||||||
start_server(ctx_proc: ctx_proc) do |port|
|
start_server(ctx_proc: ctx_proc) do |port|
|
||||||
sess1 = server_connect_with_session(port, nil, nil) { |ssl|
|
sess1 = server_connect_with_session(port, nil, nil) { |ssl|
|
||||||
|
|
|
||||||
|
|
@ -242,16 +242,15 @@ class OpenSSL::TestX509Name < OpenSSL::TestCase
|
||||||
assert_match(/^multi-valued RDN is not supported: #{dn_r}/, ex.message)
|
assert_match(/^multi-valued RDN is not supported: #{dn_r}/, ex.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
bad_dc = "exa#{"pm"}le" # <- typo of "example"
|
|
||||||
[
|
[
|
||||||
["DC=org,DC=#{bad_dc},CN", "CN"],
|
["DC=org,DC=exapmle,CN", "CN"],
|
||||||
["DC=org,DC=example,", ""],
|
["DC=org,DC=example,", ""],
|
||||||
["DC=org,DC=#{bad_dc},CN=www.example.org;", "CN=www.example.org;"],
|
["DC=org,DC=exapmle,CN=www.example.org;", "CN=www.example.org;"],
|
||||||
["DC=org,DC=#{bad_dc},CN=#www.example.org", "CN=#www.example.org"],
|
["DC=org,DC=exapmle,CN=#www.example.org", "CN=#www.example.org"],
|
||||||
["DC=org,DC=#{bad_dc},CN=#777777.example.org", "CN=#777777.example.org"],
|
["DC=org,DC=exapmle,CN=#777777.example.org", "CN=#777777.example.org"],
|
||||||
["DC=org,DC=#{bad_dc},CN=\"www.example\".org", "CN=\"www.example\".org"],
|
["DC=org,DC=exapmle,CN=\"www.example\".org", "CN=\"www.example\".org"],
|
||||||
["DC=org,DC=#{bad_dc},CN=www.\"example.org\"", "CN=www.\"example.org\""],
|
["DC=org,DC=exapmle,CN=www.\"example.org\"", "CN=www.\"example.org\""],
|
||||||
["DC=org,DC=#{bad_dc},CN=www.\"example\".org", "CN=www.\"example\".org"],
|
["DC=org,DC=exapmle,CN=www.\"example\".org", "CN=www.\"example\".org"],
|
||||||
].each{|dn, msg|
|
].each{|dn, msg|
|
||||||
ex = scanner.call(dn) rescue $!
|
ex = scanner.call(dn) rescue $!
|
||||||
assert_match(/^malformed RDN: .*=>#{Regexp.escape(msg)}/, ex.message)
|
assert_match(/^malformed RDN: .*=>#{Regexp.escape(msg)}/, ex.message)
|
||||||
|
|
|
||||||
|
|
@ -181,6 +181,14 @@ class OpenSSL::SSLTestCase < OpenSSL::TestCase
|
||||||
rescue
|
rescue
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def tls13_supported?
|
||||||
|
return false unless defined?(OpenSSL::SSL::TLS1_3_VERSION)
|
||||||
|
ctx = OpenSSL::SSL::SSLContext.new
|
||||||
|
ctx.min_version = ctx.max_version = OpenSSL::SSL::TLS1_3_VERSION
|
||||||
|
true
|
||||||
|
rescue
|
||||||
|
end
|
||||||
|
|
||||||
def readwrite_loop(ctx, ssl)
|
def readwrite_loop(ctx, ssl)
|
||||||
while line = ssl.gets
|
while line = ssl.gets
|
||||||
ssl.write(line)
|
ssl.write(line)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue