diff options
27 files changed, 510 insertions, 129 deletions
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 075bac8e..2ad0f455 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -88,10 +88,13 @@ jobs: - libressl-3.9.1 fips-enabled: [ false ] include: - - { os: ubuntu-latest, ruby: "3.0", openssl: openssl-3.0.10, fips-enabled: true, append-configure: 'enable-fips', name-extra: 'fips' } - - { os: ubuntu-latest, ruby: "3.0", openssl: openssl-3.1.2, fips-enabled: true, append-configure: 'enable-fips', name-extra: 'fips' } + - { os: ubuntu-latest, ruby: "3.0", openssl: openssl-3.0.13, fips-enabled: true, append-configure: 'enable-fips', name-extra: 'fips' } + - { os: ubuntu-latest, ruby: "3.0", openssl: openssl-3.1.5, fips-enabled: true, append-configure: 'enable-fips', name-extra: 'fips' } + - { os: ubuntu-latest, ruby: "3.0", openssl: openssl-3.2.1, fips-enabled: true, append-configure: 'enable-fips', name-extra: 'fips' } + - { os: ubuntu-latest, ruby: "3.0", openssl: openssl-3.3.0, fips-enabled: true, append-configure: 'enable-fips', name-extra: 'fips' } - { os: ubuntu-latest, ruby: "3.0", openssl: openssl-head, git: 'git://git.openssl.org/openssl.git', branch: 'master' } - { os: ubuntu-latest, ruby: "3.0", openssl: openssl-head, git: 'git://git.openssl.org/openssl.git', branch: 'master', fips-enabled: true, append-configure: 'enable-fips', name-extra: 'fips' } + - { os: ubuntu-latest, ruby: "3.0", openssl: openssl-head, git: 'git://git.openssl.org/openssl.git', branch: 'master', append-configure: 'no-legacy', name-extra: 'no-legacy' } steps: - name: repo checkout uses: actions/checkout@v4 @@ -137,12 +140,11 @@ jobs: - name: set the open installed directory run: > sed -e "s|OPENSSL_DIR|$HOME/.openssl/${{ matrix.openssl }}|" - test/openssl/fixtures/ssl/openssl_fips.cnf.tmpl > - test/openssl/fixtures/ssl/openssl_fips.cnf + tool/openssl_fips.cnf.tmpl > tmp/openssl_fips.cnf if: matrix.fips-enabled - name: set openssl config file path for fips. - run: echo "OPENSSL_CONF=$(pwd)/test/openssl/fixtures/ssl/openssl_fips.cnf" >> $GITHUB_ENV + run: echo "OPENSSL_CONF=$(pwd)/tmp/openssl_fips.cnf" >> $GITHUB_ENV if: matrix.fips-enabled - name: load ruby diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e9e3b550..fa68de65 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,7 +10,7 @@ Bugs and feature requests are tracked on [GitHub]. If you think you found a bug, file a ticket on GitHub. Please DO NOT report security issues here, there is a separate procedure which is described on -["Security at ruby-lang.org"](https://www.ruby-lang.org/en/security/). +["Security at ruby-lang.org"][Ruby Security]. When reporting a bug, please make sure you include: @@ -22,26 +22,25 @@ When reporting a bug, please make sure you include: There are a number of unresolved issues and feature requests for openssl that need review. Before submitting a new ticket, it is recommended to check -[known issues]. +[known issues][Issues]. ## Submitting patches Patches are also very welcome! -Please submit a [pull request] with your changes. +Please submit a [pull request][Compare changes] with your changes. Make sure that your branch does: * Have good commit messages -* Follow Ruby's coding style ([DeveloperHowTo]) +* Follow Ruby's coding style ([Developer-How-To][Ruby Developer-How-To]) * Pass the test suite successfully (see "Testing") ## Testing We have a test suite! -Test cases are located under the -[`test/openssl`](https://github.com/ruby/openssl/tree/master/test/openssl) +Test cases are located under the [`test/openssl`][GitHub test/openssl] directory. You can run it with the following three commands: @@ -54,31 +53,176 @@ $ bundle exec rake test ### With different versions of OpenSSL -Ruby OpenSSL supports various versions of OpenSSL library. The test suite needs -to pass on all supported combinations. +Ruby OpenSSL supports various versions of the OpenSSL library. The test suite +needs to pass on all supported combinations. -Similarly to when installing `openssl` gem via the `gem` command, -you can pass a `--with-openssl-dir` argument to `rake compile` -to specify the OpenSSL library to build against. +If you want to test, debug, report an issue, or contribute to the Ruby OpenSSL +or [the OpenSSL project][OpenSSL] in the non-FIPS or the +[FIPS][OpenSSL README-FIPS] case, compiling OpenSSL from the source by yourself +is a good practice. + +The following steps are tested in Linux and GCC environment. You can adjust the +commands in the steps for a different environment. + +To download the OpenSSL source from the Git repository, you can run the following +commands: + +``` +$ git clone https://github.com/openssl/openssl.git +$ cd openssl +``` + +You see the `master` branch used as a development branch. Testing against the +latest OpenSSL master branch is a good practice to report an issue to the +OpenSSL project. + +``` +$ git branch | grep '^*' +* master +``` + +If you test against the latest stable branch, you can run the following command. +In this example, the `openssl-3.1` branch is the stable branch of OpenSSL 3.1 +series. + +``` +$ git checkout openssl-3.1 +``` + +To configure OpenSSL, you can run the following commands. + +In this example, we use the `OPENSSL_DIR` environment variable to specify the +OpenSSL installed directory for convenience. Including the commit hash in the +directory name is a good practice. + +``` +$ git rev-parse --short HEAD +0bf18140f4 + +$ OPENSSL_DIR=$HOME/.openssl/openssl-fips-debug-0bf18140f4 +``` + +The following configuration options are useful in this case. +You can check [OpenSSL installation document][OpenSSL INSTALL] for details. + +* `enable-fips`: Add an option to run with the OpenSSL FIPS module. +* `enable-trace`: Add an option to enabling tracing log. You can trace logs by + implementing a code. See the man page [OSSL_TRACE(3)][OpenSSL OSSL_TRACE] for + details. +* compiler flags + * `-Wl,-rpath,$(LIBRPATH)`: Set the runtime shared library path to run the + `openssl` command without the `LD_LIBRARY_PATH`. You can check + [this document][OpenSSL NOTES-UNIX] for details. + * `-O0 -g3 -ggdb3 -gdwarf-5`: You can set debugging compiler flags. ``` -$ ( curl -OL https://ftp.openssl.org/source/openssl-3.0.1.tar.gz && - tar xf openssl-3.0.1.tar.gz && - cd openssl-3.0.1 && - ./config --prefix=$HOME/.openssl/openssl-3.0.1 --libdir=lib && - make -j4 && - make install ) +$ ./Configure \ + --prefix=$OPENSSL_DIR \ + --libdir=lib \ + enable-fips \ + enable-trace \ + '-Wl,-rpath,$(LIBRPATH)' \ + -O0 -g3 -ggdb3 -gdwarf-5 +$ make -j4 +$ make install +``` + +To print installed OpenSSL version, you can run the following command: + +``` +$ $OPENSSL_DIR/bin/openssl version +OpenSSL 3.2.0-alpha3-dev (Library: OpenSSL 3.2.0-alpha3-dev ) +``` + +Change the current working directory into Ruby OpenSSL's source directory. + +To compile Ruby OpenSSL, you can run the following commands: -$ # in Ruby/OpenSSL's source directory +Similarly to when installing `openssl` gem via the `gem` command, you can pass a +`--with-openssl-dir` argument to `rake compile` to specify the OpenSSL library + to build against. + +* `MAKEFLAGS="V=1"`: Enable the compiler command lines to print in + the log. +* `RUBY_OPENSSL_EXTCFLAGS`: Set extra compiler flags to compile Ruby OpenSSL. + +``` $ bundle exec rake clean -$ bundle exec rake compile -- --with-openssl-dir=$HOME/.openssl/openssl-3.0.1 +$ MAKEFLAGS="V=1" \ + RUBY_OPENSSL_EXTCFLAGS="-O0 -g3 -ggdb3 -gdwarf-5" \ + bundle exec rake compile -- --with-openssl-dir=$OPENSSL_DIR +``` + +#### Testing normally in non-FIPS case + +To test Ruby OpenSSL, you can run the following command: + +``` $ bundle exec rake test ``` -The GitHub Actions workflow file -[`test.yml`](https://github.com/ruby/openssl/tree/master/.github/workflows/test.yml) -contains useful information for building OpenSSL/LibreSSL and testing against -them. +#### Testing in FIPS case + +To use OpenSSL 3.0 or later versions in a FIPS-approved manner, you must load the +`fips` and `base` providers, and also use the property query `fips=yes`. The +property query is used when fetching cryptographic algorithm implementations. +This must be done at the startup of a process to avoid implicitly loading the +`default` provider which has the non-FIPS cryptographic algorithm +implementations. See also the man page [fips_module(7)][OpenSSL fips_module]. + +You can set this in your OpenSSL configuration file by either appropriately +modifying the default OpenSSL configuration file located at +`OpenSSL::Config::DEFAULT_CONFIG_FILE` or temporarily overriding it with the +`OPENSSL_CONF` environment variable. + +In this example, we explain on the latter way. + +You can create a OpenSSL FIPS config `openssl_fips.cnf` file based on the +`openssl_fips.cnf.tmpl` file in this repository, and replacing the placeholder +`OPENSSL_DIR` with your OpenSSL installed directory. + +``` +$ sed -e "s|OPENSSL_DIR|$OPENSSL_DIR|" tool/openssl_fips.cnf.tmpl | \ + tee $OPENSSL_DIR/ssl/openssl_fips.cnf +``` + +You can see the base and fips providers by running the following command if you +setup the OpenSSL FIPS config file properly. + +``` +$ OPENSSL_CONF=$OPENSSL_DIR/ssl/openssl_fips.cnf \ + $OPENSSL_DIR/bin/openssl list -providers +Providers: + base + name: OpenSSL Base Provider + version: 3.2.0 + status: active + fips + name: OpenSSL FIPS Provider + version: 3.2.0 + status: active +``` + +You can run the current tests in the FIPS module case used in the GitHub +Actions file `test.yml` explained in a later sentence. + +``` +$ OPENSSL_CONF=$OPENSSL_DIR/ssl/openssl_fips.cnf \ + bundle exec rake test_fips +``` + +You can also run the all the tests in the FIPS module case. You see many +failures. We are working in progress to fix the failures. Your contribution is +welcome. + +``` +$ OPENSSL_CONF=$OPENSSL_DIR/ssl/openssl_fips.cnf \ + TEST_RUBY_OPENSSL_FIPS_ENABLED=true \ + bundle exec rake test +``` + +The GitHub Actions workflow file [`test.yml`][GitHub test.yml] contains useful +information for building OpenSSL/LibreSSL and testing against them. ## Relation with Ruby source tree @@ -103,7 +247,7 @@ security issue handling procedure for Ruby core. You can either use [HackerOne] or send an email to security@ruby-lang.org. -Please see [Security] page on ruby-lang.org website for details. +Please see [Security][Ruby Security] page on ruby-lang.org website for details. Reported problems will be published after a fix is released. @@ -112,9 +256,16 @@ _Thanks for your contributions!_ _\- The Ruby OpenSSL team_ [GitHub]: https://github.com/ruby/openssl -[known issues]: https://github.com/ruby/openssl/issues -[DeveloperHowTo]: https://bugs.ruby-lang.org/projects/ruby/wiki/DeveloperHowto +[Issues]: https://github.com/ruby/openssl/issues +[Compare changes]: https://github.com/ruby/openssl/compare +[GitHub test/openssl]: https://github.com/ruby/openssl/tree/master/test/openssl +[GitHub test.yml]: https://github.com/ruby/openssl/tree/master/.github/workflows/test.yml +[Ruby Developer-How-To]: https://github.com/ruby/ruby/wiki/Developer-How-To +[Ruby Security]: https://www.ruby-lang.org/en/security/ [HackerOne]: https://hackerone.com/ruby -[Security]: https://www.ruby-lang.org/en/security/ -[pull request]: https://github.com/ruby/openssl/compare -[History.md]: https://github.com/ruby/openssl/tree/master/History.md +[OpenSSL]: https://www.openssl.org/ +[OpenSSL INSTALL]: https://github.com/openssl/openssl/blob/master/INSTALL.md +[OpenSSL README-FIPS]: https://github.com/openssl/openssl/blob/master/README-FIPS.md +[OpenSSL NOTES-UNIX]: https://github.com/openssl/openssl/blob/master/NOTES-UNIX.md +[OpenSSL OSSL_TRACE]: https://www.openssl.org/docs/manmaster/man3/OSSL_TRACE.html +[OpenSSL fips_module]: https://www.openssl.org/docs/manmaster/man7/fips_module.html @@ -457,7 +457,7 @@ Security fixes Bug fixes --------- -* Fixed OpenSSL::PKey::*.{new,generate} immediately aborting if the thread is +* Fixed OpenSSL::PKey::\*.{new,generate} immediately aborting if the thread is interrupted. [[Bug #14882]](https://bugs.ruby-lang.org/issues/14882) [[GitHub #205]](https://github.com/ruby/openssl/pull/205) @@ -32,8 +32,7 @@ included as a default gem in [supported Ruby branches][Ruby Maintenance Branches > **Note** > The openssl gem is included with Ruby by default, but you may wish to upgrade -> it to a newer version available at -> [rubygems.org](https://rubygems.org/gems/openssl). +> it to a newer version available at [rubygems.org][RubyGems.org openssl]. To upgrade it, you can use RubyGems: @@ -59,6 +58,8 @@ gem 'openssl', git: 'https://github.com/ruby/openssl' After running `bundle install`, you should have the gem installed in your bundle. +[RubyGems.org openssl]: https://rubygems.org/gems/openssl + ## Usage Once installed, you can require "openssl" in your application. @@ -80,4 +81,6 @@ Please read our [CONTRIBUTING.md] for instructions. ## Security Security issues should be reported to ruby-core by following the process -described on ["Security at ruby-lang.org"](https://www.ruby-lang.org/en/security/). +described on ["Security at ruby-lang.org"][Security]. + +[Security]: https://www.ruby-lang.org/en/security/ @@ -29,6 +29,8 @@ Rake::TestTask.new(:test_fips_internal) do |t| t.test_files = FileList[ 'test/openssl/test_fips.rb', 'test/openssl/test_pkey.rb', + 'test/openssl/test_pkey_dh.rb', + 'test/openssl/test_pkey_dsa.rb', 'test/openssl/test_pkey_ec.rb', ] t.warning = true diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb index 56f4a1c3..dd3732d0 100644 --- a/ext/openssl/extconf.rb +++ b/ext/openssl/extconf.rb @@ -13,14 +13,7 @@ require "mkmf" -ssl_dirs = nil -if defined?(::TruffleRuby) - # Always respect the openssl prefix chosen by truffle/openssl-prefix - require 'truffle/openssl-prefix' - ssl_dirs = dir_config("openssl", ENV["OPENSSL_PREFIX"]) -else - ssl_dirs = dir_config("openssl") -end +ssl_dirs = dir_config("openssl") dir_config_given = ssl_dirs.any? _, ssl_ldir = ssl_dirs @@ -49,6 +42,7 @@ $defs.push("-D""OPENSSL_SUPPRESS_DEPRECATED") have_func("rb_io_descriptor") have_func("rb_io_maybe_wait(0, Qnil, Qnil, Qnil)", "ruby/io.h") # Ruby 3.1 +have_func("rb_io_timeout", "ruby/io.h") Logging::message "=== Checking for system dependent stuff... ===\n" have_library("nsl", "t_open") diff --git a/ext/openssl/ossl_asn1.c b/ext/openssl/ossl_asn1.c index 71c452c8..05333420 100644 --- a/ext/openssl/ossl_asn1.c +++ b/ext/openssl/ossl_asn1.c @@ -1163,9 +1163,12 @@ ossl_asn1prim_to_der(VALUE self) rb_jump_tag(state); } p0 = p1 = (unsigned char *)RSTRING_PTR(str); - i2d_ASN1_TYPE(asn1, &p0); + if (i2d_ASN1_TYPE(asn1, &p0) < 0) { + ASN1_TYPE_free(asn1); + ossl_raise(eASN1Error, "i2d_ASN1_TYPE"); + } ASN1_TYPE_free(asn1); - assert(p0 - p1 == alllen); + ossl_str_adjust(str, p0); /* Strip header since to_der_internal() wants only the payload */ j = ASN1_get_object((const unsigned char **)&p1, &bodylen, &tag, &tc, alllen); diff --git a/ext/openssl/ossl_cipher.c b/ext/openssl/ossl_cipher.c index 506a0e71..6f74c925 100644 --- a/ext/openssl/ossl_cipher.c +++ b/ext/openssl/ossl_cipher.c @@ -454,8 +454,8 @@ ossl_cipher_final(VALUE self) * call-seq: * cipher.name -> string * - * Returns the name of the cipher which may differ slightly from the original - * name provided. + * Returns the short name of the cipher which may differ slightly from the + * original name provided. */ static VALUE ossl_cipher_name(VALUE self) diff --git a/ext/openssl/ossl_digest.c b/ext/openssl/ossl_digest.c index 16aeeb81..1ae26a23 100644 --- a/ext/openssl/ossl_digest.c +++ b/ext/openssl/ossl_digest.c @@ -103,7 +103,8 @@ VALUE ossl_digest_update(VALUE, VALUE); * Digest.new(string [, data]) -> Digest * * Creates a Digest instance based on _string_, which is either the ln - * (long name) or sn (short name) of a supported digest algorithm. + * (long name) or sn (short name) of a supported digest algorithm. A list of + * supported algorithms can be obtained by calling OpenSSL::Digest.digests. * * If _data_ (a String) is given, it is used as the initial input to the * Digest instance, i.e. @@ -162,6 +163,32 @@ ossl_digest_copy(VALUE self, VALUE other) return self; } +static void +add_digest_name_to_ary(const OBJ_NAME *name, void *arg) +{ + VALUE ary = (VALUE)arg; + rb_ary_push(ary, rb_str_new2(name->name)); +} + +/* + * call-seq: + * OpenSSL::Digest.digests -> array[string...] + * + * Returns the names of all available digests in an array. + */ +static VALUE +ossl_s_digests(VALUE self) +{ + VALUE ary; + + ary = rb_ary_new(); + OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, + add_digest_name_to_ary, + (void*)ary); + + return ary; +} + /* * call-seq: * digest.reset -> self @@ -245,7 +272,8 @@ ossl_digest_finish(int argc, VALUE *argv, VALUE self) * call-seq: * digest.name -> string * - * Returns the sn of this Digest algorithm. + * Returns the short name of this Digest algorithm which may differ slightly + * from the original name provided. * * === Example * digest = OpenSSL::Digest.new('SHA512') @@ -412,6 +440,7 @@ Init_ossl_digest(void) rb_define_alloc_func(cDigest, ossl_digest_alloc); + rb_define_module_function(cDigest, "digests", ossl_s_digests, 0); rb_define_method(cDigest, "initialize", ossl_digest_initialize, -1); rb_define_method(cDigest, "initialize_copy", ossl_digest_copy, 1); rb_define_method(cDigest, "reset", ossl_digest_reset, 0); diff --git a/ext/openssl/ossl_kdf.c b/ext/openssl/ossl_kdf.c index 48b161d4..ba197a65 100644 --- a/ext/openssl/ossl_kdf.c +++ b/ext/openssl/ossl_kdf.c @@ -18,7 +18,7 @@ static VALUE mKDF, eKDF; * of _length_ bytes. * * For more information about PBKDF2, see RFC 2898 Section 5.2 - * (https://tools.ietf.org/html/rfc2898#section-5.2). + * (https://www.rfc-editor.org/rfc/rfc2898#section-5.2). * * === Parameters * pass :: The password. @@ -81,10 +81,10 @@ kdf_pbkdf2_hmac(int argc, VALUE *argv, VALUE self) * bcrypt. * * The keyword arguments _N_, _r_ and _p_ can be used to tune scrypt. RFC 7914 - * (published on 2016-08, https://tools.ietf.org/html/rfc7914#section-2) states + * (published on 2016-08, https://www.rfc-editor.org/rfc/rfc7914#section-2) states * that using values r=8 and p=1 appears to yield good results. * - * See RFC 7914 (https://tools.ietf.org/html/rfc7914) for more information. + * See RFC 7914 (https://www.rfc-editor.org/rfc/rfc7914) for more information. * * === Parameters * pass :: Passphrase. @@ -147,7 +147,7 @@ kdf_scrypt(int argc, VALUE *argv, VALUE self) * KDF.hkdf(ikm, salt:, info:, length:, hash:) -> String * * HMAC-based Extract-and-Expand Key Derivation Function (HKDF) as specified in - * {RFC 5869}[https://tools.ietf.org/html/rfc5869]. + * {RFC 5869}[https://www.rfc-editor.org/rfc/rfc5869]. * * New in OpenSSL 1.1.0. * @@ -165,7 +165,7 @@ kdf_scrypt(int argc, VALUE *argv, VALUE self) * The hash function. * * === Example - * # The values from https://datatracker.ietf.org/doc/html/rfc5869#appendix-A.1 + * # The values from https://www.rfc-editor.org/rfc/rfc5869#appendix-A.1 * ikm = ["0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"].pack("H*") * salt = ["000102030405060708090a0b0c"].pack("H*") * info = ["f0f1f2f3f4f5f6f7f8f9"].pack("H*") diff --git a/ext/openssl/ossl_ns_spki.c b/ext/openssl/ossl_ns_spki.c index 9bed1f33..9d70b5d8 100644 --- a/ext/openssl/ossl_ns_spki.c +++ b/ext/openssl/ossl_ns_spki.c @@ -365,8 +365,8 @@ ossl_spki_verify(VALUE self, VALUE key) * * OpenSSL::Netscape is a namespace for SPKI (Simple Public Key * Infrastructure) which implements Signed Public Key and Challenge. - * See {RFC 2692}[http://tools.ietf.org/html/rfc2692] and {RFC - * 2693}[http://tools.ietf.org/html/rfc2692] for details. + * See {RFC 2692}[https://www.rfc-editor.org/rfc/rfc2692] and {RFC + * 2693}[https://www.rfc-editor.org/rfc/rfc2692] for details. */ /* Document-class: OpenSSL::Netscape::SPKIError diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index 236d455f..9f374b65 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -1725,11 +1725,20 @@ no_exception_p(VALUE opts) #define RUBY_IO_TIMEOUT_DEFAULT Qnil #endif +#ifdef HAVE_RB_IO_TIMEOUT +#define IO_TIMEOUT_ERROR rb_eIOTimeoutError +#else +#define IO_TIMEOUT_ERROR rb_eIOError +#endif + + static void io_wait_writable(VALUE io) { #ifdef HAVE_RB_IO_MAYBE_WAIT - rb_io_maybe_wait_writable(errno, io, RUBY_IO_TIMEOUT_DEFAULT); + if (!rb_io_maybe_wait_writable(errno, io, RUBY_IO_TIMEOUT_DEFAULT)) { + rb_raise(IO_TIMEOUT_ERROR, "Timed out while waiting to become writable!"); + } #else rb_io_t *fptr; GetOpenFile(io, fptr); @@ -1741,7 +1750,9 @@ static void io_wait_readable(VALUE io) { #ifdef HAVE_RB_IO_MAYBE_WAIT - rb_io_maybe_wait_readable(errno, io, RUBY_IO_TIMEOUT_DEFAULT); + if (!rb_io_maybe_wait_readable(errno, io, RUBY_IO_TIMEOUT_DEFAULT)) { + rb_raise(IO_TIMEOUT_ERROR, "Timed out while waiting to become readable!"); + } #else rb_io_t *fptr; GetOpenFile(io, fptr); diff --git a/lib/openssl/buffering.rb b/lib/openssl/buffering.rb index 4df90746..216c51e3 100644 --- a/lib/openssl/buffering.rb +++ b/lib/openssl/buffering.rb @@ -229,7 +229,7 @@ module OpenSSL::Buffering # # Unlike IO#gets the separator must be provided if a limit is provided. - def gets(eol=$/, limit=nil) + def gets(eol=$/, limit=nil, chomp: false) idx = @rbuffer.index(eol) until @eof break if idx @@ -244,7 +244,11 @@ module OpenSSL::Buffering if size && limit && limit >= 0 size = [size, limit].min end - consume_rbuff(size) + line = consume_rbuff(size) + if chomp && line + line.chomp!(eol) + end + line end ## diff --git a/lib/openssl/ssl.rb b/lib/openssl/ssl.rb index e557b8b4..d28bf1a3 100644 --- a/lib/openssl/ssl.rb +++ b/lib/openssl/ssl.rb @@ -22,7 +22,6 @@ module OpenSSL module SSL class SSLContext DEFAULT_PARAMS = { # :nodoc: - :min_version => OpenSSL::SSL::TLS1_VERSION, :verify_mode => OpenSSL::SSL::VERIFY_PEER, :verify_hostname => true, :options => -> { @@ -55,6 +54,7 @@ ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg== if !(OpenSSL::OPENSSL_VERSION.start_with?("OpenSSL") && OpenSSL::OPENSSL_VERSION_NUMBER >= 0x10100000) DEFAULT_PARAMS.merge!( + min_version: OpenSSL::SSL::TLS1_VERSION, ciphers: %w{ ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-GCM-SHA256 @@ -252,6 +252,14 @@ ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg== to_io.peeraddr end + def local_address + to_io.local_address + end + + def remote_address + to_io.remote_address + end + def setsockopt(level, optname, optval) to_io.setsockopt(level, optname, optval) end @@ -271,6 +279,36 @@ ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg== def do_not_reverse_lookup=(flag) to_io.do_not_reverse_lookup = flag end + + def close_on_exec=(value) + to_io.close_on_exec = value + end + + def close_on_exec? + to_io.close_on_exec? + end + + def wait(*args) + to_io.wait(*args) + end + + def wait_readable(*args) + to_io.wait_readable(*args) + end + + def wait_writable(*args) + to_io.wait_writable(*args) + end + + if IO.method_defined?(:timeout) + def timeout + to_io.timeout + end + + def timeout=(value) + to_io.timeout=(value) + end + end end def verify_certificate_identity(cert, hostname) @@ -421,6 +459,32 @@ ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg== nil end + # Close the stream for reading. + # This method is ignored by OpenSSL as there is no reasonable way to + # implement it, but exists for compatibility with IO. + def close_read + # Unsupported and ignored. + # Just don't read any more. + end + + # Closes the stream for writing. The behavior of this method depends on + # the version of OpenSSL and the TLS protocol in use. + # + # - Sends a 'close_notify' alert to the peer. + # - Does not wait for the peer's 'close_notify' alert in response. + # + # In TLS 1.2 and earlier: + # - On receipt of a 'close_notify' alert, responds with a 'close_notify' + # alert of its own and close down the connection immediately, + # discarding any pending writes. + # + # Therefore, on TLS 1.2, this method will cause the connection to be + # completely shut down. On TLS 1.3, the connection will remain open for + # reading only. + def close_write + stop + end + private def using_anon_cipher? diff --git a/test/openssl/fixtures/pkey/dh1024.pem b/test/openssl/fixtures/pkey/dh1024.pem deleted file mode 100644 index f99c757f..00000000 --- a/test/openssl/fixtures/pkey/dh1024.pem +++ /dev/null @@ -1,5 +0,0 @@ ------BEGIN DH PARAMETERS----- -MIGHAoGBAKnKQ8MNK6nYZzLrrcuTsLxuiJGXoOO5gT+tljOTbHBuiktdMTITzIY0 -pFxIvjG05D7HoBZQfrR0c92NGWPkAiCkhQKB8JCbPVzwNLDy6DZ0pmofDKrEsYHG -AQjjxMXhwULlmuR/K+WwlaZPiLIBYalLAZQ7ZbOPeVkJ8ePao0eLAgEC ------END DH PARAMETERS----- diff --git a/test/openssl/fixtures/pkey/dh2048_ffdhe2048.pem b/test/openssl/fixtures/pkey/dh2048_ffdhe2048.pem new file mode 100644 index 00000000..9b182b72 --- /dev/null +++ b/test/openssl/fixtures/pkey/dh2048_ffdhe2048.pem @@ -0,0 +1,8 @@ +-----BEGIN DH PARAMETERS----- +MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz ++8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a +87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7 +YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi +7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD +ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg== +-----END DH PARAMETERS----- diff --git a/test/openssl/fixtures/pkey/dsa2048.pem b/test/openssl/fixtures/pkey/dsa2048.pem new file mode 100644 index 00000000..3f22b22b --- /dev/null +++ b/test/openssl/fixtures/pkey/dsa2048.pem @@ -0,0 +1,15 @@ +-----BEGIN PRIVATE KEY----- +MIICXgIBADCCAjYGByqGSM44BAEwggIpAoIBAQDXZhJ/dQoWkQELzjzlx8FtIp96 +voCYe5NY0H8j0jz7GyHpXt41+MteqkZK3/Ah+cNR9uG8iEYArAZ71LcWotfee2Gz +xdxozr9bRt0POYhO2YIsfMpBrEskPsDH2g/2nFV8l4OJgxU2qZUrF4PN5ha+Mu6u +sVtN8hjvAvnbf4Pxn0b8NN9f4PJncroUa8acv5WsV85E1RW7NYCefggU4LytYIHg +euRF9eY9gVCX5MkUgW2xODHIYJhwk/+5lJxG7qUsSahD/nPHO/yoWgdVHq2DkdTq +KYXkAxx2PJcTBOHTglhE6mgCbEKp8vcfElnBWyCT6QykclZiPXXD2JV829J/Ah0A +vYa+/G/gUZiomyejVje6UsGoCc+vInxmovOL8QKCAQEAhnKEigYPw6u8JY7v5iGo +Ylz8qiMFYmaJCwevf3KCjWeEXuNO4OrKdfzkQl1tPuGLioYFfP1A2yGosjdUdLEB +0JqnzlKxUp+G6RfBj+WYzbgc5hr7t0M+reAJh09/hDzqfxjcgiHstq7mpRXBP8Y7 +iu27s7TRYJNSAYRvWcXNSBEUym3mHBBbZn7VszYooSrn60/iZ8I+VY1UF/fgqhbj +JfaaZNQCDO9K3Vb3rsXoYd8+bOZIen9uHB+pNjMqhpl4waysqrlpGFeeqdxivH6S +vkrHLs6/eWVMnS08RdcryoCrI3Bm8mMBKQglDwKLnWLfzG565qEhslzyCd/l9k9a +cwQfAh0Ao8/g72fSFmo04FizM7DZJSIPqDLjfZu9hLvUFA== +-----END PRIVATE KEY----- diff --git a/test/openssl/test_digest.rb b/test/openssl/test_digest.rb index b0b5b9be..988330e4 100644 --- a/test/openssl/test_digest.rb +++ b/test/openssl/test_digest.rb @@ -88,7 +88,7 @@ class OpenSSL::TestDigest < OpenSSL::TestCase end def test_sha512_truncate - pend "SHA512_224 is not implemented" unless digest_available?('SHA512-224') + pend "SHA512_224 is not implemented" unless digest_available?('sha512-224') sha512_224_a = "d5cdb9ccc769a5121d4175f2bfdd13d6310e0d3d361ea75d82108327" sha512_256_a = "455e518824bc0601f9fb858ff5c37d417d67c2f8e0df2babe4808858aea830f8" @@ -100,7 +100,7 @@ class OpenSSL::TestDigest < OpenSSL::TestCase end def test_sha3 - pend "SHA3 is not implemented" unless digest_available?('SHA3-224') + pend "SHA3 is not implemented" unless digest_available?('sha3-224') s224 = '6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7' s256 = 'a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a' s384 = '0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004' @@ -126,6 +126,15 @@ class OpenSSL::TestDigest < OpenSSL::TestCase end end + def test_digests + digests = OpenSSL::Digest.digests + assert_kind_of Array, digests + assert_include digests, "md5" + assert_include digests, "sha1" + assert_include digests, "sha256" + assert_include digests, "sha512" + end + private def check_digest(oid) @@ -138,11 +147,8 @@ class OpenSSL::TestDigest < OpenSSL::TestCase end def digest_available?(name) - begin - OpenSSL::Digest.new(name) - rescue RuntimeError - false - end + @digests ||= OpenSSL::Digest.digests + @digests.include?(name) end end diff --git a/test/openssl/test_ocsp.rb b/test/openssl/test_ocsp.rb index 85f13375..cf96fc22 100644 --- a/test/openssl/test_ocsp.rb +++ b/test/openssl/test_ocsp.rb @@ -228,7 +228,7 @@ class OpenSSL::TestOCSP < OpenSSL::TestCase assert_equal OpenSSL::OCSP::V_CERTSTATUS_REVOKED, single.cert_status assert_equal OpenSSL::OCSP::REVOKED_STATUS_UNSPECIFIED, single.revocation_reason assert_equal now - 400, single.revocation_time - assert_in_delta (now - 301), single.this_update, 1 + assert_in_delta (now - 300), single.this_update, 1 assert_equal nil, single.next_update assert_equal [], single.extensions diff --git a/test/openssl/test_pair.rb b/test/openssl/test_pair.rb index 14786100..b6168839 100644 --- a/test/openssl/test_pair.rb +++ b/test/openssl/test_pair.rb @@ -115,6 +115,17 @@ module OpenSSL::TestPairM } end + def test_gets_chomp + ssl_pair {|s1, s2| + s1 << "line1\r\nline2\r\nline3\r\n" + s1.close + + assert_equal("line1", s2.gets("\r\n", chomp: true)) + assert_equal("line2\r\n", s2.gets("\r\n", chomp: false)) + assert_equal("line3", s2.gets(chomp: true)) + } + end + def test_gets_eof_limit ssl_pair {|s1, s2| s1.write("hello") diff --git a/test/openssl/test_pkey_dh.rb b/test/openssl/test_pkey_dh.rb index 161af189..d32ffaf6 100644 --- a/test/openssl/test_pkey_dh.rb +++ b/test/openssl/test_pkey_dh.rb @@ -18,15 +18,26 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase assert_key(dh) end if ENV["OSSL_TEST_ALL"] - def test_new_break + def test_new_break_on_non_fips + omit_on_fips + assert_nil(OpenSSL::PKey::DH.new(NEW_KEYLEN) { break }) assert_raise(RuntimeError) do OpenSSL::PKey::DH.new(NEW_KEYLEN) { raise } end end + def test_new_break_on_fips + omit_on_non_fips + + # The block argument is not executed in FIPS case. + # See https://github.com/ruby/openssl/issues/692 for details. + assert(OpenSSL::PKey::DH.new(NEW_KEYLEN) { break }) + assert(OpenSSL::PKey::DH.new(NEW_KEYLEN) { raise }) + end + def test_derive_key - params = Fixtures.pkey("dh1024") + params = Fixtures.pkey("dh2048_ffdhe2048") dh1 = OpenSSL::PKey.generate_key(params) dh2 = OpenSSL::PKey.generate_key(params) dh1_pub = OpenSSL::PKey.read(dh1.public_to_der) @@ -44,34 +55,38 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase end def test_DHparams - dh1024 = Fixtures.pkey("dh1024") - dh1024params = dh1024.public_key + dh = Fixtures.pkey("dh2048_ffdhe2048") + dh_params = dh.public_key asn1 = OpenSSL::ASN1::Sequence([ - OpenSSL::ASN1::Integer(dh1024.p), - OpenSSL::ASN1::Integer(dh1024.g) + OpenSSL::ASN1::Integer(dh.p), + OpenSSL::ASN1::Integer(dh.g) ]) key = OpenSSL::PKey::DH.new(asn1.to_der) - assert_same_dh dh1024params, key + assert_same_dh dh_params, key pem = <<~EOF -----BEGIN DH PARAMETERS----- - MIGHAoGBAKnKQ8MNK6nYZzLrrcuTsLxuiJGXoOO5gT+tljOTbHBuiktdMTITzIY0 - pFxIvjG05D7HoBZQfrR0c92NGWPkAiCkhQKB8JCbPVzwNLDy6DZ0pmofDKrEsYHG - AQjjxMXhwULlmuR/K+WwlaZPiLIBYalLAZQ7ZbOPeVkJ8ePao0eLAgEC + MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz + +8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a + 87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7 + YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi + 7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD + ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg== -----END DH PARAMETERS----- EOF + key = OpenSSL::PKey::DH.new(pem) - assert_same_dh dh1024params, key + assert_same_dh dh_params, key key = OpenSSL::PKey.read(pem) - assert_same_dh dh1024params, key + assert_same_dh dh_params, key - assert_equal asn1.to_der, dh1024.to_der - assert_equal pem, dh1024.export + assert_equal asn1.to_der, dh.to_der + assert_equal pem, dh.export end def test_public_key - dh = Fixtures.pkey("dh1024") + dh = Fixtures.pkey("dh2048_ffdhe2048") public_key = dh.public_key assert_no_key(public_key) #implies public_key.public? is false! assert_equal(dh.to_der, public_key.to_der) @@ -80,7 +95,8 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase def test_generate_key # Deprecated in v3.0.0; incompatible with OpenSSL 3.0 - dh = Fixtures.pkey("dh1024").public_key # creates a copy with params only + # Creates a copy with params only + dh = Fixtures.pkey("dh2048_ffdhe2048").public_key assert_no_key(dh) dh.generate_key! assert_key(dh) @@ -91,7 +107,15 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase end if !openssl?(3, 0, 0) def test_params_ok? - dh0 = Fixtures.pkey("dh1024") + # Skip the tests in old OpenSSL version 1.1.1c or early versions before + # applying the following commits in OpenSSL 1.1.1d to make `DH_check` + # function pass the RFC 7919 FFDHE group texts. + # https://github.com/openssl/openssl/pull/9435 + unless openssl?(1, 1, 1, 4) + pend 'DH check for RFC 7919 FFDHE group texts is not implemented' + end + + dh0 = Fixtures.pkey("dh2048_ffdhe2048") dh1 = OpenSSL::PKey::DH.new(OpenSSL::ASN1::Sequence([ OpenSSL::ASN1::Integer(dh0.p), @@ -108,7 +132,7 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase def test_dup # Parameters only - dh1 = Fixtures.pkey("dh1024") + dh1 = Fixtures.pkey("dh2048_ffdhe2048") dh2 = dh1.dup assert_equal dh1.to_der, dh2.to_der assert_not_equal nil, dh1.p @@ -125,7 +149,7 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase end # With a key pair - dh3 = OpenSSL::PKey.generate_key(Fixtures.pkey("dh1024")) + dh3 = OpenSSL::PKey.generate_key(Fixtures.pkey("dh2048_ffdhe2048")) dh4 = dh3.dup assert_equal dh3.to_der, dh4.to_der assert_equal dh1.to_der, dh4.to_der # encodes parameters only @@ -136,7 +160,7 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase end def test_marshal - dh = Fixtures.pkey("dh1024") + dh = Fixtures.pkey("dh2048_ffdhe2048") deserialized = Marshal.load(Marshal.dump(dh)) assert_equal dh.to_der, deserialized.to_der diff --git a/test/openssl/test_pkey_dsa.rb b/test/openssl/test_pkey_dsa.rb index 3f64a80e..4c93f286 100644 --- a/test/openssl/test_pkey_dsa.rb +++ b/test/openssl/test_pkey_dsa.rb @@ -31,11 +31,6 @@ class OpenSSL::TestPKeyDSA < OpenSSL::PKeyTestCase def test_generate # DSA.generate used to call DSA_generate_parameters_ex(), which adjusts the # size of q according to the size of p - key1024 = OpenSSL::PKey::DSA.generate(1024) - assert_predicate key1024, :private? - assert_equal 1024, key1024.p.num_bits - assert_equal 160, key1024.q.num_bits - key2048 = OpenSSL::PKey::DSA.generate(2048) assert_equal 2048, key2048.p.num_bits assert_equal 256, key2048.q.num_bits @@ -47,28 +42,41 @@ class OpenSSL::TestPKeyDSA < OpenSSL::PKeyTestCase end end + def test_generate_on_non_fips + # DSA with 1024 bits is invalid on FIPS 186-4. + # https://github.com/openssl/openssl/commit/49ed5ba8f62875074f04417189147fd3dda072ab + omit_on_fips + + key1024 = OpenSSL::PKey::DSA.generate(1024) + assert_predicate key1024, :private? + assert_equal 1024, key1024.p.num_bits + assert_equal 160, key1024.q.num_bits + end + def test_sign_verify - dsa512 = Fixtures.pkey("dsa512") + # The DSA valid size is 2048 or 3072 on FIPS. + # https://github.com/openssl/openssl/blob/7649b5548e5c0352b91d9d3ed695e42a2ac1e99c/providers/common/securitycheck.c#L185-L188 + dsa = Fixtures.pkey("dsa2048") data = "Sign me!" if defined?(OpenSSL::Digest::DSS1) - signature = dsa512.sign(OpenSSL::Digest.new('DSS1'), data) - assert_equal true, dsa512.verify(OpenSSL::Digest.new('DSS1'), signature, data) + signature = dsa.sign(OpenSSL::Digest.new('DSS1'), data) + assert_equal true, dsa.verify(OpenSSL::Digest.new('DSS1'), signature, data) end - signature = dsa512.sign("SHA256", data) - assert_equal true, dsa512.verify("SHA256", signature, data) + signature = dsa.sign("SHA256", data) + assert_equal true, dsa.verify("SHA256", signature, data) signature0 = (<<~'end;').unpack1("m") - MCwCFH5h40plgU5Fh0Z4wvEEpz0eE9SnAhRPbkRB8ggsN/vsSEYMXvJwjGg/ - 6g== + MD4CHQC0zmRkVOAHJTm28fS5PVUv+4LtBeNaKqr/yfmVAh0AsTcLqofWHoW8X5oWu8AOvngOcFVZ + cLTvhY3XNw== end; - assert_equal true, dsa512.verify("SHA256", signature0, data) + assert_equal true, dsa.verify("SHA256", signature0, data) signature1 = signature0.succ - assert_equal false, dsa512.verify("SHA256", signature1, data) + assert_equal false, dsa.verify("SHA256", signature1, data) end def test_sign_verify_raw - key = Fixtures.pkey("dsa512") + key = Fixtures.pkey("dsa2048") data = 'Sign me!' digest = OpenSSL::Digest.digest('SHA1', data) @@ -127,6 +135,8 @@ class OpenSSL::TestPKeyDSA < OpenSSL::PKeyTestCase end def test_DSAPrivateKey_encrypted + omit_on_fips + # key = abcdef dsa512 = Fixtures.pkey("dsa512") pem = <<~EOF diff --git a/test/openssl/test_provider.rb b/test/openssl/test_provider.rb index d0e66785..b0ffae9c 100644 --- a/test/openssl/test_provider.rb +++ b/test/openssl/test_provider.rb @@ -13,13 +13,13 @@ class OpenSSL::TestProvider < OpenSSL::TestCase def test_openssl_provider_names 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,7 +34,12 @@ class OpenSSL::TestProvider < OpenSSL::TestCase def test_openssl_legacy_provider 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_ssl.rb b/test/openssl/test_ssl.rb index 07dc9a34..1471b0cb 100644 --- a/test/openssl/test_ssl.rb +++ b/test/openssl/test_ssl.rb @@ -117,6 +117,30 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase } end + def test_socket_close_write + server_proc = proc do |ctx, ssl| + message = ssl.read + ssl.write(message) + ssl.close_write + ensure + ssl.close + end + + start_server(server_proc: server_proc) do |port| + ctx = OpenSSL::SSL::SSLContext.new + ssl = OpenSSL::SSL::SSLSocket.open("127.0.0.1", port, context: ctx) + ssl.sync_close = true + ssl.connect + + message = "abc"*1024 + ssl.write message + ssl.close_write + assert_equal message, ssl.read + ensure + ssl&.close + end + end + def test_add_certificate ctx_proc = -> ctx { # Unset values set by start_server @@ -193,6 +217,24 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase } end + def test_read_with_timeout + omit "does not support timeout" unless IO.method_defined?(:timeout) + + start_server do |port| + server_connect(port) do |ssl| + str = +("x" * 100 + "\n") + ssl.syswrite(str) + assert_equal(str, ssl.sysread(str.bytesize)) + + ssl.timeout = 1 + assert_raise(IO::TimeoutError) {ssl.read(1)} + + ssl.syswrite(str) + assert_equal(str, ssl.sysread(str.bytesize)) + end + end + end + def test_getbyte start_server { |port| server_connect(port) { |ssl| @@ -673,7 +715,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase assert_equal(true, OpenSSL::SSL.verify_wildcard("xn--qdk4b9b", "xn--qdk4b9b")) end - # Comments in this test is excerpted from http://tools.ietf.org/html/rfc6125#page-27 + # Comments in this test is excerpted from https://www.rfc-editor.org/rfc/rfc6125#page-27 def test_post_connection_check_wildcard_san # case-insensitive ASCII comparison # RFC 6125, section 6.4.1 diff --git a/test/openssl/test_x509ext.rb b/test/openssl/test_x509ext.rb index 838780d3..59a41ed7 100644 --- a/test/openssl/test_x509ext.rb +++ b/test/openssl/test_x509ext.rb @@ -50,24 +50,22 @@ class OpenSSL::TestX509Extension < OpenSSL::TestCase cdp = ef.create_extension("crlDistributionPoints", "@crlDistPts") assert_equal(false, cdp.critical?) assert_equal("crlDistributionPoints", cdp.oid) - assert_match(%{URI:http://www\.example\.com/crl}, cdp.value) - assert_match( - %r{URI:ldap://ldap\.example\.com/cn=ca\?certificateRevocationList;binary}, - cdp.value) + assert_include(cdp.value, "URI:http://www.example.com/crl") + assert_include(cdp.value, + "URI:ldap://ldap.example.com/cn=ca?certificateRevocationList;binary") cdp = ef.create_extension("crlDistributionPoints", "critical, @crlDistPts") assert_equal(true, cdp.critical?) assert_equal("crlDistributionPoints", cdp.oid) - assert_match(%{URI:http://www.example.com/crl}, cdp.value) - assert_match( - %r{URI:ldap://ldap.example.com/cn=ca\?certificateRevocationList;binary}, - cdp.value) + assert_include(cdp.value, "URI:http://www.example.com/crl") + assert_include(cdp.value, + "URI:ldap://ldap.example.com/cn=ca?certificateRevocationList;binary") cp = ef.create_extension("certificatePolicies", "@certPolicies") assert_equal(false, cp.critical?) assert_equal("certificatePolicies", cp.oid) - assert_match(%r{2.23.140.1.2.1}, cp.value) - assert_match(%r{http://cps.example.com}, cp.value) + assert_include(cp.value, "2.23.140.1.2.1") + assert_include(cp.value, "http://cps.example.com") end def test_factory_create_extension_sn_ln diff --git a/test/openssl/utils.rb b/test/openssl/utils.rb index cd70d488..f6c84eef 100644 --- a/test/openssl/utils.rb +++ b/test/openssl/utils.rb @@ -151,7 +151,11 @@ class OpenSSL::TestCase < Test::Unit::TestCase def omit_on_fips return unless OpenSSL.fips_mode - omit 'An encryption used in the test is not FIPS-approved' + omit <<~MESSAGE + Only for OpenSSL non-FIPS with the following possible reasons: + * A testing logic is non-FIPS specific. + * An encryption used in the test is not FIPS-approved. + MESSAGE end def omit_on_non_fips diff --git a/test/openssl/fixtures/ssl/openssl_fips.cnf.tmpl b/tool/openssl_fips.cnf.tmpl index be0768d5..be0768d5 100644 --- a/test/openssl/fixtures/ssl/openssl_fips.cnf.tmpl +++ b/tool/openssl_fips.cnf.tmpl |