summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/openssl/History.md60
-rw-r--r--ext/openssl/extconf.rb2
-rw-r--r--ext/openssl/lib/openssl/buffering.rb17
-rw-r--r--ext/openssl/lib/openssl/ssl.rb1
-rw-r--r--ext/openssl/lib/openssl/version.rb2
-rw-r--r--ext/openssl/lib/openssl/x509.rb10
-rw-r--r--ext/openssl/openssl.gemspec2
-rw-r--r--ext/openssl/ossl_asn1.c43
-rw-r--r--ext/openssl/ossl_cipher.c23
-rw-r--r--ext/openssl/ossl_digest.c1
-rw-r--r--ext/openssl/ossl_pkcs7.c12
-rw-r--r--ext/openssl/ossl_pkey.c1
-rw-r--r--test/openssl/test_asn1.rb17
-rw-r--r--test/openssl/test_bn.rb48
-rw-r--r--test/openssl/test_cipher.rb40
-rw-r--r--test/openssl/test_ossl.rb12
-rw-r--r--test/openssl/test_pkcs7.rb15
-rw-r--r--test/openssl/test_pkey_dsa.rb6
-rw-r--r--test/openssl/test_provider.rb17
-rw-r--r--test/openssl/test_x509cert.rb99
20 files changed, 333 insertions, 95 deletions
diff --git a/ext/openssl/History.md b/ext/openssl/History.md
index 3249f6617a..3a044eecfa 100644
--- a/ext/openssl/History.md
+++ b/ext/openssl/History.md
@@ -1,3 +1,15 @@
+Version 3.2.2
+=============
+
+Merged changes in 3.1.2.
+
+
+Version 3.2.1
+=============
+
+Merged changes in 3.0.3.
+
+
Version 3.2.0
=============
@@ -38,6 +50,29 @@ Notable changes
[[GitHub #141]](https://github.com/ruby/openssl/pull/141)
+Version 3.1.2
+=============
+
+Bug fixes
+---------
+
+* Fix crash when attempting to export an incomplete `OpenSSL::PKey::DSA` key.
+ [[GitHub #845]](https://github.com/ruby/openssl/issues/845)
+ [[GitHub #847]](https://github.com/ruby/openssl/pull/847)
+* Remove the `OpenSSL::X509::V_FLAG_CRL_CHECK_ALL` flag from the default store
+ used by `OpenSSL::SSL::SSLContext#set_params`. It causes certificate
+ verification to fail with OpenSSL 3.6.0. It has no effect with any other
+ OpenSSL versions.
+ [[GitHub #949]](https://github.com/ruby/openssl/issues/949)
+ [[GitHub #950]](https://github.com/ruby/openssl/pull/950)
+
+
+Version 3.1.1
+=============
+
+Merged changes in 3.0.3.
+
+
Version 3.1.0
=============
@@ -74,6 +109,31 @@ Notable changes
LibreSSL 3.6 and Ed25519 support in LibreSSL 3.7.
+Version 3.0.3
+=============
+
+Bug fixes
+---------
+
+* Fix a performance regression introduced in v2.1.3 on a buffered write to
+ `SSLSocket`.
+ [[GitHub #706]](https://github.com/ruby/openssl/pull/706)
+* Fix `OpenSSL::PKCS7` to handle PKCS#7 structures without content.
+ [[GitHub #690]](https://github.com/ruby/openssl/pull/690)
+ [[GitHub #752]](https://github.com/ruby/openssl/pull/752)
+* Fix `OpenSSL::ASN1::ObjectId#==` with OIDs without a known name.
+ [[GitHub #791]](https://github.com/ruby/openssl/issues/791)
+ [[GitHub #792]](https://github.com/ruby/openssl/pull/792)
+* Fix `OpenSSL::X509::Certificate#crl_uris` to handle CDP with multiple CRL
+ URIs.
+ [[GitHub #775]](https://github.com/ruby/openssl/issues/775)
+ [[GitHub #776]](https://github.com/ruby/openssl/pull/776)
+* Fix `OpenSSL::Cipher#update` to always make the output buffer `String`
+ independent.
+ [[Bug #20937]](https://bugs.ruby-lang.org/issues/20937)
+ [[GitHub #824]](https://github.com/ruby/openssl/pull/824)
+
+
Version 3.0.2
=============
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
index 7a768867f8..56f4a1c3ab 100644
--- a/ext/openssl/extconf.rb
+++ b/ext/openssl/extconf.rb
@@ -47,7 +47,7 @@ Logging::message "=== OpenSSL for Ruby configurator ===\n"
$defs.push("-D""OPENSSL_SUPPRESS_DEPRECATED")
-have_func("rb_io_descriptor", "ruby/io.h")
+have_func("rb_io_descriptor")
have_func("rb_io_maybe_wait(0, Qnil, Qnil, Qnil)", "ruby/io.h") # Ruby 3.1
Logging::message "=== Checking for system dependent stuff... ===\n"
diff --git a/ext/openssl/lib/openssl/buffering.rb b/ext/openssl/lib/openssl/buffering.rb
index 9570f14f37..4df90746f4 100644
--- a/ext/openssl/lib/openssl/buffering.rb
+++ b/ext/openssl/lib/openssl/buffering.rb
@@ -345,13 +345,18 @@ module OpenSSL::Buffering
@wbuffer << s
@wbuffer.force_encoding(Encoding::BINARY)
@sync ||= false
- if @sync or @wbuffer.size > BLOCK_SIZE
- until @wbuffer.empty?
- begin
- nwrote = syswrite(@wbuffer)
- rescue Errno::EAGAIN
- retry
+ buffer_size = @wbuffer.size
+ if @sync or buffer_size > BLOCK_SIZE
+ nwrote = 0
+ begin
+ while nwrote < buffer_size do
+ begin
+ nwrote += syswrite(@wbuffer[nwrote, buffer_size - nwrote])
+ rescue Errno::EAGAIN
+ retry
+ end
end
+ ensure
@wbuffer[0, nwrote] = ""
end
end
diff --git a/ext/openssl/lib/openssl/ssl.rb b/ext/openssl/lib/openssl/ssl.rb
index e557b8b483..b69a509b20 100644
--- a/ext/openssl/lib/openssl/ssl.rb
+++ b/ext/openssl/lib/openssl/ssl.rb
@@ -92,7 +92,6 @@ ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
DEFAULT_CERT_STORE = OpenSSL::X509::Store.new # :nodoc:
DEFAULT_CERT_STORE.set_default_paths
- DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
# A callback invoked when DH parameters are required for ephemeral DH key
# exchange.
diff --git a/ext/openssl/lib/openssl/version.rb b/ext/openssl/lib/openssl/version.rb
index 9315a79381..9f23fcc56c 100644
--- a/ext/openssl/lib/openssl/version.rb
+++ b/ext/openssl/lib/openssl/version.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
module OpenSSL
- VERSION = "3.2.0"
+ VERSION = "3.2.2"
end
diff --git a/ext/openssl/lib/openssl/x509.rb b/ext/openssl/lib/openssl/x509.rb
index f973f4f4dc..2fda0d5e2d 100644
--- a/ext/openssl/lib/openssl/x509.rb
+++ b/ext/openssl/lib/openssl/x509.rb
@@ -122,8 +122,8 @@ module OpenSSL
include Helpers
# Get the distributionPoint fullName URI from the certificate's CRL
- # distribution points extension, as described in RFC5280 Section
- # 4.2.1.13
+ # distribution points extension, as described in RFC 5280 Section
+ # 4.2.1.13.
#
# Returns an array of strings or nil or raises ASN1::ASN1Error.
def crl_uris
@@ -135,19 +135,19 @@ module OpenSSL
raise ASN1::ASN1Error, "invalid extension"
end
- crl_uris = cdp_asn1.map do |crl_distribution_point|
+ crl_uris = cdp_asn1.flat_map do |crl_distribution_point|
distribution_point = crl_distribution_point.value.find do |v|
v.tag_class == :CONTEXT_SPECIFIC && v.tag == 0
end
full_name = distribution_point&.value&.find do |v|
v.tag_class == :CONTEXT_SPECIFIC && v.tag == 0
end
- full_name&.value&.find do |v|
+ full_name&.value&.select do |v|
v.tag_class == :CONTEXT_SPECIFIC && v.tag == 6 # uniformResourceIdentifier
end
end
- crl_uris&.map(&:value)
+ crl_uris.empty? ? nil : crl_uris.map(&:value)
end
end
diff --git a/ext/openssl/openssl.gemspec b/ext/openssl/openssl.gemspec
index 2765f55401..08bf2d8c2e 100644
--- a/ext/openssl/openssl.gemspec
+++ b/ext/openssl/openssl.gemspec
@@ -1,6 +1,6 @@
Gem::Specification.new do |spec|
spec.name = "openssl"
- spec.version = "3.2.0"
+ spec.version = "3.2.2"
spec.authors = ["Martin Bosslet", "SHIBATA Hiroshi", "Zachary Scott", "Kazuki Yamaguchi"]
spec.email = ["ruby-core@ruby-lang.org"]
spec.summary = %q{SSL/TLS and general-purpose cryptography for Ruby}
diff --git a/ext/openssl/ossl_asn1.c b/ext/openssl/ossl_asn1.c
index 71c452c88a..f26a4759cf 100644
--- a/ext/openssl/ossl_asn1.c
+++ b/ext/openssl/ossl_asn1.c
@@ -1298,30 +1298,6 @@ ossl_asn1obj_get_ln(VALUE self)
return ret;
}
-/*
- * call-seq:
- * oid == other_oid => true or false
- *
- * Returns +true+ if _other_oid_ is the same as _oid_
- */
-static VALUE
-ossl_asn1obj_eq(VALUE self, VALUE other)
-{
- VALUE valSelf, valOther;
- int nidSelf, nidOther;
-
- valSelf = ossl_asn1_get_value(self);
- valOther = ossl_asn1_get_value(other);
-
- if ((nidSelf = OBJ_txt2nid(StringValueCStr(valSelf))) == NID_undef)
- ossl_raise(eASN1Error, "OBJ_txt2nid");
-
- if ((nidOther = OBJ_txt2nid(StringValueCStr(valOther))) == NID_undef)
- ossl_raise(eASN1Error, "OBJ_txt2nid");
-
- return nidSelf == nidOther ? Qtrue : Qfalse;
-}
-
static VALUE
asn1obj_get_oid_i(VALUE vobj)
{
@@ -1366,6 +1342,25 @@ ossl_asn1obj_get_oid(VALUE self)
return str;
}
+/*
+ * call-seq:
+ * oid == other_oid => true or false
+ *
+ * Returns +true+ if _other_oid_ is the same as _oid_.
+ */
+static VALUE
+ossl_asn1obj_eq(VALUE self, VALUE other)
+{
+ VALUE oid1, oid2;
+
+ if (!rb_obj_is_kind_of(other, cASN1ObjectId))
+ return Qfalse;
+
+ oid1 = ossl_asn1obj_get_oid(self);
+ oid2 = ossl_asn1obj_get_oid(other);
+ return rb_str_equal(oid1, oid2);
+}
+
#define OSSL_ASN1_IMPL_FACTORY_METHOD(klass) \
static VALUE ossl_asn1_##klass(int argc, VALUE *argv, VALUE self)\
{ return rb_funcall3(cASN1##klass, rb_intern("new"), argc, argv); }
diff --git a/ext/openssl/ossl_cipher.c b/ext/openssl/ossl_cipher.c
index 110610e1f9..cf83d08522 100644
--- a/ext/openssl/ossl_cipher.c
+++ b/ext/openssl/ossl_cipher.c
@@ -386,22 +386,37 @@ ossl_cipher_update(int argc, VALUE *argv, VALUE self)
in = (unsigned char *)RSTRING_PTR(data);
in_len = RSTRING_LEN(data);
GetCipher(self, ctx);
- out_len = in_len+EVP_CIPHER_CTX_block_size(ctx);
- if (out_len <= 0) {
+
+ /*
+ * As of OpenSSL 3.2, there is no reliable way to determine the required
+ * output buffer size for arbitrary cipher modes.
+ * https://github.com/openssl/openssl/issues/22628
+ *
+ * in_len+block_size is usually sufficient, but AES key wrap with padding
+ * ciphers require in_len+15 even though they have a block size of 8 bytes.
+ *
+ * Using EVP_MAX_BLOCK_LENGTH (32) as a safe upper bound for ciphers
+ * currently implemented in OpenSSL, but this can change in the future.
+ */
+ if (in_len > LONG_MAX - EVP_MAX_BLOCK_LENGTH) {
ossl_raise(rb_eRangeError,
"data too big to make output buffer: %ld bytes", in_len);
}
+ out_len = in_len + EVP_MAX_BLOCK_LENGTH;
if (NIL_P(str)) {
str = rb_str_new(0, out_len);
} else {
StringValue(str);
- rb_str_resize(str, out_len);
+ if ((long)rb_str_capacity(str) >= out_len)
+ rb_str_modify(str);
+ else
+ rb_str_modify_expand(str, out_len - RSTRING_LEN(str));
}
if (!ossl_cipher_update_long(ctx, (unsigned char *)RSTRING_PTR(str), &out_len, in, in_len))
ossl_raise(eCipherError, NULL);
- assert(out_len < RSTRING_LEN(str));
+ assert(out_len <= RSTRING_LEN(str));
rb_str_set_len(str, out_len);
return str;
diff --git a/ext/openssl/ossl_digest.c b/ext/openssl/ossl_digest.c
index 16aeeb8106..819e3ed852 100644
--- a/ext/openssl/ossl_digest.c
+++ b/ext/openssl/ossl_digest.c
@@ -232,6 +232,7 @@ ossl_digest_finish(int argc, VALUE *argv, VALUE self)
str = rb_str_new(NULL, out_len);
} else {
StringValue(str);
+ rb_str_modify(str);
rb_str_resize(str, out_len);
}
diff --git a/ext/openssl/ossl_pkcs7.c b/ext/openssl/ossl_pkcs7.c
index 78dcbd667a..7e5fb9c1b2 100644
--- a/ext/openssl/ossl_pkcs7.c
+++ b/ext/openssl/ossl_pkcs7.c
@@ -165,7 +165,13 @@ ossl_pkcs7_s_read_smime(VALUE klass, VALUE arg)
out = NULL;
pkcs7 = SMIME_read_PKCS7(in, &out);
BIO_free(in);
- if(!pkcs7) ossl_raise(ePKCS7Error, NULL);
+ if (!pkcs7)
+ ossl_raise(ePKCS7Error, "Could not parse the PKCS7");
+ if (!pkcs7->d.ptr) {
+ PKCS7_free(pkcs7);
+ ossl_raise(ePKCS7Error, "No content in PKCS7");
+ }
+
data = out ? ossl_membio2str(out) : Qnil;
SetPKCS7(ret, pkcs7);
ossl_pkcs7_set_data(ret, data);
@@ -346,6 +352,10 @@ ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self)
BIO_free(in);
if (!p7)
ossl_raise(rb_eArgError, "Could not parse the PKCS7");
+ if (!p7->d.ptr) {
+ PKCS7_free(p7);
+ ossl_raise(rb_eArgError, "No content in PKCS7");
+ }
RTYPEDDATA_DATA(self) = p7;
PKCS7_free(p7_orig);
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
index 013412c27f..9e0835d38c 100644
--- a/ext/openssl/ossl_pkey.c
+++ b/ext/openssl/ossl_pkey.c
@@ -937,6 +937,7 @@ ossl_pkey_export_spki(VALUE self, int to_der)
BIO *bio;
GetPKey(self, pkey);
+ ossl_pkey_check_public_key(pkey);
bio = BIO_new(BIO_s_mem());
if (!bio)
ossl_raise(ePKeyError, "BIO_new");
diff --git a/test/openssl/test_asn1.rb b/test/openssl/test_asn1.rb
index 7b1722e5df..354b587895 100644
--- a/test/openssl/test_asn1.rb
+++ b/test/openssl/test_asn1.rb
@@ -326,7 +326,9 @@ class OpenSSL::TestASN1 < OpenSSL::TestCase
oid = (0...100).to_a.join(".").b
obj = OpenSSL::ASN1::ObjectId.new(oid)
assert_equal oid, obj.oid
+ end
+ def test_object_identifier_equality
aki = [
OpenSSL::ASN1::ObjectId.new("authorityKeyIdentifier"),
OpenSSL::ASN1::ObjectId.new("X509v3 Authority Key Identifier"),
@@ -341,17 +343,22 @@ class OpenSSL::TestASN1 < OpenSSL::TestCase
aki.each do |a|
aki.each do |b|
- assert a == b
+ assert_equal true, a == b
end
ski.each do |b|
- refute a == b
+ assert_equal false, a == b
end
end
- assert_raise(TypeError) {
- OpenSSL::ASN1::ObjectId.new("authorityKeyIdentifier") == nil
- }
+ obj1 = OpenSSL::ASN1::ObjectId.new("1.2.34.56789.10")
+ obj2 = OpenSSL::ASN1::ObjectId.new("1.2.34.56789.10")
+ obj3 = OpenSSL::ASN1::ObjectId.new("1.2.34.56789.11")
+ omit "OID 1.2.34.56789.10 is registered" if obj1.sn
+ assert_equal true, obj1 == obj2
+ assert_equal false, obj1 == obj3
+
+ assert_equal false, OpenSSL::ASN1::ObjectId.new("authorityKeyIdentifier") == nil
end
def test_sequence
diff --git a/test/openssl/test_bn.rb b/test/openssl/test_bn.rb
index ea88ff06ce..3edb69658e 100644
--- a/test/openssl/test_bn.rb
+++ b/test/openssl/test_bn.rb
@@ -343,28 +343,36 @@ class OpenSSL::TestBN < OpenSSL::TestCase
assert_equal(4, e.get_flags(OpenSSL::BN::CONSTTIME))
end
- if respond_to?(:ractor)
+ if defined?(Ractor) && respond_to?(:ractor)
+ unless Ractor.method_defined?(:value) # Ruby 3.4 or earlier
+ using Module.new {
+ refine Ractor do
+ alias value take
+ end
+ }
+ end
+
ractor
def test_ractor
- assert_equal(@e1, Ractor.new { OpenSSL::BN.new("999") }.take)
- assert_equal(@e3, Ractor.new { OpenSSL::BN.new("\a\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 2) }.take)
- assert_equal("999", Ractor.new(@e1) { |e1| e1.to_s }.take)
- assert_equal("07FFFFFFFFFFFFFFFFFFFFFFFFFF", Ractor.new(@e3) { |e3| e3.to_s(16) }.take)
- assert_equal(2**107-1, Ractor.new(@e3) { _1.to_i }.take)
- assert_equal([1000, -999], Ractor.new(@e2) { _1.coerce(1000) }.take)
- assert_equal(false, Ractor.new { 1.to_bn.zero? }.take)
- assert_equal(true, Ractor.new { 1.to_bn.one? }.take)
- assert_equal(true, Ractor.new(@e2) { _1.negative? }.take)
- assert_equal("-03E7", Ractor.new(@e2) { _1.to_s(16) }.take)
- assert_equal(2**107-1, Ractor.new(@e3) { _1.to_i }.take)
- assert_equal([1000, -999], Ractor.new(@e2) { _1.coerce(1000) }.take)
- assert_equal(true, Ractor.new { 0.to_bn.zero? }.take)
- assert_equal(true, Ractor.new { 1.to_bn.one? }.take )
- assert_equal(false,Ractor.new { 2.to_bn.odd? }.take)
- assert_equal(true, Ractor.new(@e2) { _1.negative? }.take)
- assert_include(128..255, Ractor.new { OpenSSL::BN.rand(8)}.take)
- assert_include(0...2**32, Ractor.new { OpenSSL::BN.generate_prime(32) }.take)
- assert_equal(0, Ractor.new { OpenSSL::BN.new(999).get_flags(OpenSSL::BN::CONSTTIME) }.take)
+ assert_equal(@e1, Ractor.new { OpenSSL::BN.new("999") }.value)
+ assert_equal(@e3, Ractor.new { OpenSSL::BN.new("\a\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 2) }.value)
+ assert_equal("999", Ractor.new(@e1) { |e1| e1.to_s }.value)
+ assert_equal("07FFFFFFFFFFFFFFFFFFFFFFFFFF", Ractor.new(@e3) { |e3| e3.to_s(16) }.value)
+ assert_equal(2**107-1, Ractor.new(@e3) { _1.to_i }.value)
+ assert_equal([1000, -999], Ractor.new(@e2) { _1.coerce(1000) }.value)
+ assert_equal(false, Ractor.new { 1.to_bn.zero? }.value)
+ assert_equal(true, Ractor.new { 1.to_bn.one? }.value)
+ assert_equal(true, Ractor.new(@e2) { _1.negative? }.value)
+ assert_equal("-03E7", Ractor.new(@e2) { _1.to_s(16) }.value)
+ assert_equal(2**107-1, Ractor.new(@e3) { _1.to_i }.value)
+ assert_equal([1000, -999], Ractor.new(@e2) { _1.coerce(1000) }.value)
+ assert_equal(true, Ractor.new { 0.to_bn.zero? }.value)
+ assert_equal(true, Ractor.new { 1.to_bn.one? }.value )
+ assert_equal(false,Ractor.new { 2.to_bn.odd? }.value)
+ assert_equal(true, Ractor.new(@e2) { _1.negative? }.value)
+ assert_include(128..255, Ractor.new { OpenSSL::BN.rand(8)}.value)
+ assert_include(0...2**32, Ractor.new { OpenSSL::BN.generate_prime(32) }.value)
+ assert_equal(0, Ractor.new { OpenSSL::BN.new(999).get_flags(OpenSSL::BN::CONSTTIME) }.value)
end
end
end
diff --git a/test/openssl/test_cipher.rb b/test/openssl/test_cipher.rb
index 8faa570648..cd0b3dcb44 100644
--- a/test/openssl/test_cipher.rb
+++ b/test/openssl/test_cipher.rb
@@ -128,6 +128,30 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
assert_equal pt, cipher.update(ct) << cipher.final
end
+ def test_update_with_buffer
+ cipher = OpenSSL::Cipher.new("aes-128-ecb").encrypt
+ cipher.random_key
+ expected = cipher.update("data") << cipher.final
+ assert_equal 16, expected.bytesize
+
+ # Buffer is supplied
+ cipher.reset
+ buf = String.new
+ assert_same buf, cipher.update("data", buf)
+ assert_equal expected, buf + cipher.final
+
+ # Buffer is frozen
+ cipher.reset
+ assert_raise(FrozenError) { cipher.update("data", String.new.freeze) }
+
+ # Buffer is a shared string [ruby-core:120141] [Bug #20937]
+ cipher.reset
+ buf = "x" * 1024
+ shared = buf[-("data".bytesize + 32)..-1]
+ assert_same shared, cipher.update("data", shared)
+ assert_equal expected, shared + cipher.final
+ end
+
def test_ciphers
ciphers = OpenSSL::Cipher.ciphers
assert_kind_of Array, ciphers
@@ -331,6 +355,22 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
assert_equal tag1, tag2
end
+ def test_aes_keywrap_pad
+ # RFC 5649 Section 6; The second example
+ kek = ["5840df6e29b02af1ab493b705bf16ea1ae8338f4dcc176a8"].pack("H*")
+ key = ["466f7250617369"].pack("H*")
+ wrap = ["afbeb0f07dfbf5419200f2ccb50bb24f"].pack("H*")
+
+ begin
+ cipher = OpenSSL::Cipher.new("id-aes192-wrap-pad").encrypt
+ rescue OpenSSL::Cipher::CipherError, RuntimeError
+ omit "id-aes192-wrap-pad is not supported: #$!"
+ end
+ cipher.key = kek
+ ct = cipher.update(key) << cipher.final
+ assert_equal wrap, ct
+ end
+
def test_non_aead_cipher_set_auth_data
assert_raise(OpenSSL::Cipher::CipherError) {
cipher = OpenSSL::Cipher.new("aes-128-cfb").encrypt
diff --git a/test/openssl/test_ossl.rb b/test/openssl/test_ossl.rb
index 979669a003..9f4b39d4f5 100644
--- a/test/openssl/test_ossl.rb
+++ b/test/openssl/test_ossl.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true
require_relative "utils"
-require 'benchmark'
-
if defined?(OpenSSL)
class OpenSSL::OSSL < OpenSSL::SSLTestCase
@@ -54,8 +52,14 @@ class OpenSSL::OSSL < OpenSSL::SSLTestCase
a_b_time = a_c_time = 0
100.times do
- a_b_time += Benchmark.measure { 100.times { OpenSSL.fixed_length_secure_compare(a, b) } }.real
- a_c_time += Benchmark.measure { 100.times { OpenSSL.fixed_length_secure_compare(a, c) } }.real
+ t1 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
+ 100.times { OpenSSL.fixed_length_secure_compare(a, b) }
+ t2 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
+ 100.times { OpenSSL.fixed_length_secure_compare(a, c) }
+ t3 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
+
+ a_b_time += t2 - t1
+ a_c_time += t3 - t2
end
assert_operator(a_b_time, :<, a_c_time * 10, "fixed_length_secure_compare timing test failed")
assert_operator(a_c_time, :<, a_b_time * 10, "fixed_length_secure_compare timing test failed")
diff --git a/test/openssl/test_pkcs7.rb b/test/openssl/test_pkcs7.rb
index ba8b93d034..96f3f1f6be 100644
--- a/test/openssl/test_pkcs7.rb
+++ b/test/openssl/test_pkcs7.rb
@@ -155,6 +155,21 @@ class OpenSSL::TestPKCS7 < OpenSSL::TestCase
assert_equal(data, p7.decrypt(@rsa1024))
end
+ def test_empty_signed_data_ruby_bug_19974
+ data = "-----BEGIN PKCS7-----\nMAsGCSqGSIb3DQEHAg==\n-----END PKCS7-----\n"
+ assert_raise(ArgumentError) { OpenSSL::PKCS7.new(data) }
+
+ data = <<END
+MIME-Version: 1.0
+Content-Disposition: attachment; filename="smime.p7m"
+Content-Type: application/x-pkcs7-mime; smime-type=signed-data; name="smime.p7m"
+Content-Transfer-Encoding: base64
+
+#{data}
+END
+ assert_raise(OpenSSL::PKCS7::PKCS7Error) { OpenSSL::PKCS7.read_smime(data) }
+ end
+
def test_graceful_parsing_failure #[ruby-core:43250]
contents = File.read(__FILE__)
assert_raise(ArgumentError) { OpenSSL::PKCS7.new(contents) }
diff --git a/test/openssl/test_pkey_dsa.rb b/test/openssl/test_pkey_dsa.rb
index 3f64a80e32..35c3945c0d 100644
--- a/test/openssl/test_pkey_dsa.rb
+++ b/test/openssl/test_pkey_dsa.rb
@@ -28,6 +28,12 @@ class OpenSSL::TestPKeyDSA < OpenSSL::PKeyTestCase
end
end
+ def test_new_empty
+ key = OpenSSL::PKey::DSA.new
+ assert_nil(key.p)
+ assert_raise(OpenSSL::PKey::PKeyError) { key.to_der }
+ end
+
def test_generate
# DSA.generate used to call DSA_generate_parameters_ex(), which adjusts the
# size of q according to the size of p
diff --git a/test/openssl/test_provider.rb b/test/openssl/test_provider.rb
index 7361a0e250..b0ffae9ce7 100644
--- a/test/openssl/test_provider.rb
+++ b/test/openssl/test_provider.rb
@@ -12,15 +12,14 @@ class OpenSSL::TestProvider < OpenSSL::TestCase
end
def test_openssl_provider_names
- omit 'not working on freebsd RubyCI' if ENV['RUBYCI_NICKNAME'] =~ /freebsd/
with_openssl <<-'end;'
- legacy_provider = OpenSSL::Provider.load("legacy")
+ base_provider = OpenSSL::Provider.load("base")
assert_equal(2, OpenSSL::Provider.provider_names.size)
- assert_includes(OpenSSL::Provider.provider_names, "legacy")
+ assert_includes(OpenSSL::Provider.provider_names, "base")
- assert_equal(true, legacy_provider.unload)
+ assert_equal(true, base_provider.unload)
assert_equal(1, OpenSSL::Provider.provider_names.size)
- assert_not_includes(OpenSSL::Provider.provider_names, "legacy")
+ assert_not_includes(OpenSSL::Provider.provider_names, "base")
end;
end
@@ -34,9 +33,13 @@ class OpenSSL::TestProvider < OpenSSL::TestCase
end
def test_openssl_legacy_provider
- omit 'not working on freebsd RubyCI' if ENV['RUBYCI_NICKNAME'] =~ /freebsd/
with_openssl(<<-'end;')
- OpenSSL::Provider.load("legacy")
+ begin
+ OpenSSL::Provider.load("legacy")
+ rescue OpenSSL::Provider::ProviderError
+ omit "Only for OpenSSL with legacy provider"
+ end
+
algo = "RC4"
data = "a" * 1000
key = OpenSSL::Random.random_bytes(16)
diff --git a/test/openssl/test_x509cert.rb b/test/openssl/test_x509cert.rb
index 64805504de..e39b6b6a4c 100644
--- a/test/openssl/test_x509cert.rb
+++ b/test/openssl/test_x509cert.rb
@@ -68,7 +68,7 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase
assert_equal(now.getutc, cert.not_after)
end
- def test_extension
+ def test_extension_factory
ca_exts = [
["basicConstraints","CA:TRUE",true],
["keyUsage","keyCertSign, cRLSign",true],
@@ -76,9 +76,6 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase
["authorityKeyIdentifier","issuer:always,keyid:always",false],
]
ca_cert = issue_cert(@ca, @rsa2048, 1, ca_exts, nil, nil)
- keyid = get_subject_key_id(ca_cert.to_der, hex: false)
- assert_equal keyid, ca_cert.authority_key_identifier
- assert_equal keyid, ca_cert.subject_key_identifier
ca_cert.extensions.each_with_index{|ext, i|
assert_equal(ca_exts[i].first, ext.oid)
assert_equal(ca_exts[i].last, ext.critical?)
@@ -90,7 +87,6 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase
["authorityKeyIdentifier","issuer:always,keyid:always",false],
["extendedKeyUsage","clientAuth, emailProtection, codeSigning",false],
["subjectAltName","email:ee1@ruby-lang.org",false],
- ["authorityInfoAccess","caIssuers;URI:http://www.example.com/caIssuers,OCSP;URI:http://www.example.com/ocsp",false],
]
ee1_cert = issue_cert(@ee1, @rsa1024, 2, ee1_exts, ca_cert, @rsa2048)
assert_equal(ca_cert.subject.to_der, ee1_cert.issuer.to_der)
@@ -98,15 +94,54 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase
assert_equal(ee1_exts[i].first, ext.oid)
assert_equal(ee1_exts[i].last, ext.critical?)
}
- assert_nil(ee1_cert.crl_uris)
+ end
+
+ def test_akiski
+ ca_cert = generate_cert(@ca, @rsa2048, 4, nil)
+ ef = OpenSSL::X509::ExtensionFactory.new(ca_cert, ca_cert)
+ ca_cert.add_extension(
+ ef.create_extension("subjectKeyIdentifier", "hash", false))
+ ca_cert.add_extension(
+ ef.create_extension("authorityKeyIdentifier", "issuer:always,keyid:always", false))
+ ca_cert.sign(@rsa2048, "sha256")
+
+ ca_keyid = get_subject_key_id(ca_cert.to_der, hex: false)
+ assert_equal ca_keyid, ca_cert.authority_key_identifier
+ assert_equal ca_keyid, ca_cert.subject_key_identifier
+
+ ee_cert = generate_cert(@ee1, Fixtures.pkey("p256"), 5, ca_cert)
+ ef = OpenSSL::X509::ExtensionFactory.new(ca_cert, ee_cert)
+ ee_cert.add_extension(
+ ef.create_extension("subjectKeyIdentifier", "hash", false))
+ ee_cert.add_extension(
+ ef.create_extension("authorityKeyIdentifier", "issuer:always,keyid:always", false))
+ ee_cert.sign(@rsa2048, "sha256")
+
+ ee_keyid = get_subject_key_id(ee_cert.to_der, hex: false)
+ assert_equal ca_keyid, ee_cert.authority_key_identifier
+ assert_equal ee_keyid, ee_cert.subject_key_identifier
+ end
+
+ def test_akiski_missing
+ cert = issue_cert(@ee1, @rsa2048, 1, [], nil, nil)
+ assert_nil(cert.authority_key_identifier)
+ assert_nil(cert.subject_key_identifier)
+ end
+
+ def test_crl_uris_no_crl_distribution_points
+ cert = issue_cert(@ee1, @rsa2048, 1, [], nil, nil)
+ assert_nil(cert.crl_uris)
+ end
+ def test_crl_uris
+ # Multiple DistributionPoint contains a single general name each
ef = OpenSSL::X509::ExtensionFactory.new
ef.config = OpenSSL::Config.parse(<<~_cnf_)
[crlDistPts]
URI.1 = http://www.example.com/crl
URI.2 = ldap://ldap.example.com/cn=ca?certificateRevocationList;binary
_cnf_
- cdp_cert = generate_cert(@ee1, @rsa1024, 3, ca_cert)
+ cdp_cert = generate_cert(@ee1, @rsa2048, 3, nil)
ef.subject_certificate = cdp_cert
cdp_cert.add_extension(ef.create_extension("crlDistributionPoints", "@crlDistPts"))
cdp_cert.sign(@rsa2048, "sha256")
@@ -114,9 +149,50 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase
["http://www.example.com/crl", "ldap://ldap.example.com/cn=ca?certificateRevocationList;binary"],
cdp_cert.crl_uris
)
+ end
+ def test_crl_uris_multiple_general_names
+ # Single DistributionPoint contains multiple general names of type URI
ef = OpenSSL::X509::ExtensionFactory.new
- aia_cert = generate_cert(@ee1, @rsa1024, 4, ca_cert)
+ ef.config = OpenSSL::Config.parse(<<~_cnf_)
+ [crlDistPts_section]
+ fullname = URI:http://www.example.com/crl, URI:ldap://ldap.example.com/cn=ca?certificateRevocationList;binary
+ _cnf_
+ cdp_cert = generate_cert(@ee1, @rsa2048, 3, nil)
+ ef.subject_certificate = cdp_cert
+ cdp_cert.add_extension(ef.create_extension("crlDistributionPoints", "crlDistPts_section"))
+ cdp_cert.sign(@rsa2048, "sha256")
+ assert_equal(
+ ["http://www.example.com/crl", "ldap://ldap.example.com/cn=ca?certificateRevocationList;binary"],
+ cdp_cert.crl_uris
+ )
+ end
+
+ def test_crl_uris_no_uris
+ # The only DistributionPointName is a directoryName
+ ef = OpenSSL::X509::ExtensionFactory.new
+ ef.config = OpenSSL::Config.parse(<<~_cnf_)
+ [crlDistPts_section]
+ fullname = dirName:dirname_section
+ [dirname_section]
+ CN = dirname
+ _cnf_
+ cdp_cert = generate_cert(@ee1, @rsa2048, 3, nil)
+ ef.subject_certificate = cdp_cert
+ cdp_cert.add_extension(ef.create_extension("crlDistributionPoints", "crlDistPts_section"))
+ cdp_cert.sign(@rsa2048, "sha256")
+ assert_nil(cdp_cert.crl_uris)
+ end
+
+ def test_aia_missing
+ cert = issue_cert(@ee1, @rsa2048, 1, [], nil, nil)
+ assert_nil(cert.ca_issuer_uris)
+ assert_nil(cert.ocsp_uris)
+ end
+
+ def test_aia
+ ef = OpenSSL::X509::ExtensionFactory.new
+ aia_cert = generate_cert(@ee1, @rsa2048, 4, nil)
ef.subject_certificate = aia_cert
aia_cert.add_extension(
ef.create_extension(
@@ -137,13 +213,6 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase
["http://www.example.com/ocsp", "ldap://ldap.example.com/cn=ca?authorityInfoAccessOcsp;binary"],
aia_cert.ocsp_uris
)
-
- no_exts_cert = issue_cert(@ca, @rsa2048, 5, [], nil, nil)
- assert_equal nil, no_exts_cert.authority_key_identifier
- assert_equal nil, no_exts_cert.subject_key_identifier
- assert_equal nil, no_exts_cert.crl_uris
- assert_equal nil, no_exts_cert.ca_issuer_uris
- assert_equal nil, no_exts_cert.ocsp_uris
end
def test_invalid_extension