diff options
79 files changed, 758 insertions, 190 deletions
diff --git a/.github/workflows/github-pages.yml b/.github/workflows/github-pages.yml new file mode 100644 index 00000000..b9028182 --- /dev/null +++ b/.github/workflows/github-pages.yml @@ -0,0 +1,36 @@ +name: GitHub Pages + +on: + push: + branches: + - master + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: ruby + bundler-cache: true # 'bundle install' and cache gems + - run: rake rdoc + - name: Upload GitHub Pages artifact + uses: actions/upload-pages-artifact@v3 + with: + path: html + + deploy: + needs: build + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b4c59d4e..b676a230 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,8 +20,6 @@ jobs: os: [ ubuntu-22.04, ubuntu-20.04, macos-latest, windows-latest ] ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }} exclude: - # uses non-standard MSYS2 OpenSSL 3 package - - { os: windows-latest, ruby: head } - { os: windows-latest, ruby: truffleruby } - { os: windows-latest, ruby: truffleruby-head } - { os: macos-latest, ruby: truffleruby } @@ -38,9 +36,7 @@ jobs: uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} - - - name: depends - run: bundle install + bundler-cache: true # `bundle install` and cache # Enable the verbose option in mkmf.rb to print the compiling commands. - name: enable mkmf verbose @@ -52,10 +48,10 @@ jobs: if: ${{ !matrix.skip-warnings }} - name: compile - run: rake compile + run: bundle exec rake compile - name: test - run: rake test TESTOPTS="-v --no-show-detail-immediately" + run: bundle exec rake test TESTOPTS="-v --no-show-detail-immediately" timeout-minutes: 5 test-openssls: @@ -88,10 +84,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: 'https://github.com/openssl/openssl.git', branch: 'master' } - { os: ubuntu-latest, ruby: "3.0", openssl: openssl-head, git: 'https://github.com/openssl/openssl.git', branch: 'master', fips-enabled: true, append-configure: 'enable-fips', name-extra: 'fips' } + - { os: ubuntu-latest, ruby: "3.0", openssl: openssl-head, git: 'https://github.com/openssl/openssl.git', branch: 'master', append-configure: 'no-legacy', name-extra: 'no-legacy' } steps: - name: repo checkout uses: actions/checkout@v4 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 @@ -18,10 +18,10 @@ included as a default gem in [supported Ruby branches][Ruby Maintenance Branches |Version|Maintenance status |Ruby compatibility|OpenSSL compatibility | |-------|-------------------------------|------------------|--------------------------------------------| -|3.2.x |normal maintenance (Ruby 3.3) |Ruby 2.7+ |OpenSSL 1.0.2-3.1 (current) or LibreSSL 3.1+| -|3.1.x |normal maintenance (Ruby 3.2) |Ruby 2.6+ |OpenSSL 1.0.2-3.1 (current) or LibreSSL 3.1+| -|3.0.x |normal maintenance (Ruby 3.1) |Ruby 2.6+ |OpenSSL 1.0.2-3.1 (current) or LibreSSL 3.1+| -|2.2.x |security maintenance (Ruby 3.0)|Ruby 2.3+ |OpenSSL 1.0.1-1.1.1 or LibreSSL 2.9+ | +|3.2.x |normal maintenance (Ruby 3.3) |Ruby 2.7+ |OpenSSL 1.0.2-3.3 (current) or LibreSSL 3.1+| +|3.1.x |normal maintenance (Ruby 3.2) |Ruby 2.6+ |OpenSSL 1.0.2-3.3 (current) or LibreSSL 3.1+| +|3.0.x |security maintenance (Ruby 3.1)|Ruby 2.6+ |OpenSSL 1.0.2-3.3 (current) or LibreSSL 3.1+| +|2.2.x |end-of-life (Ruby 3.0) |Ruby 2.3+ |OpenSSL 1.0.1-1.1.1 or LibreSSL 2.9+ | |2.1.x |end-of-life (Ruby 2.5-2.7) |Ruby 2.3+ |OpenSSL 1.0.1-1.1.1 or LibreSSL 2.5+ | |2.0.x |end-of-life (Ruby 2.4) |Ruby 2.3+ |OpenSSL 0.9.8-1.1.1 or LibreSSL 2.3+ | @@ -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/ @@ -30,6 +30,7 @@ Rake::TestTask.new(:test_fips_internal) do |t| '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..8d2eac02 100644 --- a/ext/openssl/extconf.rb +++ b/ext/openssl/extconf.rb @@ -8,19 +8,12 @@ = Licence This program is licensed under the same licence as Ruby. - (See the file 'LICENCE'.) + (See the file 'COPYING'.) =end 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") @@ -155,6 +149,9 @@ engines.each { |name| have_func("ENGINE_load_#{name}()", "openssl/engine.h") } +# missing in libressl < 3.5 +have_func("i2d_re_X509_tbs(NULL, NULL)", x509_h) + # added in 1.1.0 if !have_struct_member("SSL", "ctx", "openssl/ssl.h") || is_libressl $defs.push("-DHAVE_OPAQUE_OPENSSL") diff --git a/ext/openssl/openssl_missing.c b/ext/openssl/openssl_missing.c index 4415703d..5a6d23e1 100644 --- a/ext/openssl/openssl_missing.c +++ b/ext/openssl/openssl_missing.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include RUBY_EXTCONF_H diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h index 8629bfe5..0711f924 100644 --- a/ext/openssl/openssl_missing.h +++ b/ext/openssl/openssl_missing.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_OPENSSL_MISSING_H_) #define _OSSL_OPENSSL_MISSING_H_ diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c index 00eded55..59ad7d19 100644 --- a/ext/openssl/ossl.c +++ b/ext/openssl/ossl.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" #include <stdarg.h> /* for ossl_raise */ diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h index 68d42b71..c3140ac3 100644 --- a/ext/openssl/ossl.h +++ b/ext/openssl/ossl.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_H_) #define _OSSL_H_ diff --git a/ext/openssl/ossl_asn1.c b/ext/openssl/ossl_asn1.c index 71c452c8..fb476843 100644 --- a/ext/openssl/ossl_asn1.c +++ b/ext/openssl/ossl_asn1.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -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_asn1.h b/ext/openssl/ossl_asn1.h index 939a96ce..f47e3539 100644 --- a/ext/openssl/ossl_asn1.h +++ b/ext/openssl/ossl_asn1.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_ASN1_H_) #define _OSSL_ASN1_H_ diff --git a/ext/openssl/ossl_bio.c b/ext/openssl/ossl_bio.c index 42833d90..2ef20805 100644 --- a/ext/openssl/ossl_bio.c +++ b/ext/openssl/ossl_bio.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" diff --git a/ext/openssl/ossl_bio.h b/ext/openssl/ossl_bio.h index da68c5e5..1b871f1c 100644 --- a/ext/openssl/ossl_bio.h +++ b/ext/openssl/ossl_bio.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_BIO_H_) #define _OSSL_BIO_H_ diff --git a/ext/openssl/ossl_bn.c b/ext/openssl/ossl_bn.c index ce0d3ec7..7393fdea 100644 --- a/ext/openssl/ossl_bn.c +++ b/ext/openssl/ossl_bn.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ /* modified by Michal Rokos <m.rokos@sh.cvut.cz> */ #include "ossl.h" diff --git a/ext/openssl/ossl_bn.h b/ext/openssl/ossl_bn.h index 1cc041fc..800f84cb 100644 --- a/ext/openssl/ossl_bn.h +++ b/ext/openssl/ossl_bn.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_BN_H_) #define _OSSL_BN_H_ diff --git a/ext/openssl/ossl_cipher.c b/ext/openssl/ossl_cipher.c index 506a0e71..cc0114f5 100644 --- a/ext/openssl/ossl_cipher.c +++ b/ext/openssl/ossl_cipher.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -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_cipher.h b/ext/openssl/ossl_cipher.h index 2392d41c..07b50c3b 100644 --- a/ext/openssl/ossl_cipher.h +++ b/ext/openssl/ossl_cipher.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_CIPHER_H_) #define _OSSL_CIPHER_H_ diff --git a/ext/openssl/ossl_config.c b/ext/openssl/ossl_config.c index 0e598b4d..55875028 100644 --- a/ext/openssl/ossl_config.c +++ b/ext/openssl/ossl_config.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" diff --git a/ext/openssl/ossl_config.h b/ext/openssl/ossl_config.h index 4e604f1a..a254360c 100644 --- a/ext/openssl/ossl_config.h +++ b/ext/openssl/ossl_config.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #ifndef OSSL_CONFIG_H #define OSSL_CONFIG_H diff --git a/ext/openssl/ossl_digest.c b/ext/openssl/ossl_digest.c index 16aeeb81..00ec8931 100644 --- a/ext/openssl/ossl_digest.c +++ b/ext/openssl/ossl_digest.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -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_digest.h b/ext/openssl/ossl_digest.h index 50bf5666..99771b8a 100644 --- a/ext/openssl/ossl_digest.h +++ b/ext/openssl/ossl_digest.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_DIGEST_H_) #define _OSSL_DIGEST_H_ diff --git a/ext/openssl/ossl_engine.c b/ext/openssl/ossl_engine.c index 9e86321d..294d58ad 100644 --- a/ext/openssl/ossl_engine.c +++ b/ext/openssl/ossl_engine.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" diff --git a/ext/openssl/ossl_engine.h b/ext/openssl/ossl_engine.h index cd548bee..f6f4ff4c 100644 --- a/ext/openssl/ossl_engine.h +++ b/ext/openssl/ossl_engine.h @@ -6,7 +6,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(OSSL_ENGINE_H) #define OSSL_ENGINE_H diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c index c485ba7e..b1163f61 100644 --- a/ext/openssl/ossl_hmac.c +++ b/ext/openssl/ossl_hmac.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" diff --git a/ext/openssl/ossl_hmac.h b/ext/openssl/ossl_hmac.h index 7c51f472..17427587 100644 --- a/ext/openssl/ossl_hmac.h +++ b/ext/openssl/ossl_hmac.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_HMAC_H_) #define _OSSL_HMAC_H_ 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..e822d5e0 100644 --- a/ext/openssl/ossl_ns_spki.c +++ b/ext/openssl/ossl_ns_spki.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -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_ns_spki.h b/ext/openssl/ossl_ns_spki.h index 62ba8cb1..20d68576 100644 --- a/ext/openssl/ossl_ns_spki.h +++ b/ext/openssl/ossl_ns_spki.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_NS_SPKI_H_) #define _OSSL_NS_SPKI_H_ diff --git a/ext/openssl/ossl_ocsp.c b/ext/openssl/ossl_ocsp.c index df986bb3..9796d44a 100644 --- a/ext/openssl/ossl_ocsp.c +++ b/ext/openssl/ossl_ocsp.c @@ -6,7 +6,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" diff --git a/ext/openssl/ossl_ocsp.h b/ext/openssl/ossl_ocsp.h index 6d2aac86..07da7d16 100644 --- a/ext/openssl/ossl_ocsp.h +++ b/ext/openssl/ossl_ocsp.h @@ -6,7 +6,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_OCSP_H_) #define _OSSL_OCSP_H_ diff --git a/ext/openssl/ossl_pkcs12.c b/ext/openssl/ossl_pkcs12.c index 164b2da4..1fcb1a88 100644 --- a/ext/openssl/ossl_pkcs12.c +++ b/ext/openssl/ossl_pkcs12.c @@ -1,6 +1,6 @@ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -134,6 +134,10 @@ ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self) if (!NIL_P(keytype)) ktype = NUM2INT(keytype); + if (ktype != 0 && ktype != KEY_SIG && ktype != KEY_EX) { + ossl_raise(rb_eArgError, "Unknown key usage type %"PRIsVALUE, INT2NUM(ktype)); + } + obj = NewPKCS12(cPKCS12); x509s = NIL_P(ca) ? NULL : ossl_x509_ary2sk(ca); p12 = PKCS12_create(passphrase, friendlyname, key, x509, x509s, @@ -272,4 +276,8 @@ Init_ossl_pkcs12(void) rb_attr(cPKCS12, rb_intern("ca_certs"), 1, 0, Qfalse); rb_define_method(cPKCS12, "initialize", ossl_pkcs12_initialize, -1); rb_define_method(cPKCS12, "to_der", ossl_pkcs12_to_der, 0); + + /* MSIE specific PKCS12 key usage extensions */ + rb_define_const(cPKCS12, "KEY_EX", INT2NUM(KEY_EX)); + rb_define_const(cPKCS12, "KEY_SIG", INT2NUM(KEY_SIG)); } diff --git a/ext/openssl/ossl_pkcs12.h b/ext/openssl/ossl_pkcs12.h index fe4f15ef..d4003e81 100644 --- a/ext/openssl/ossl_pkcs12.h +++ b/ext/openssl/ossl_pkcs12.h @@ -1,6 +1,6 @@ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_PKCS12_H_) #define _OSSL_PKCS12_H_ diff --git a/ext/openssl/ossl_pkcs7.c b/ext/openssl/ossl_pkcs7.c index aeeb4bf5..b7e6d330 100644 --- a/ext/openssl/ossl_pkcs7.c +++ b/ext/openssl/ossl_pkcs7.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -848,6 +848,25 @@ ossl_pkcs7_to_der(VALUE self) } static VALUE +ossl_pkcs7_to_text(VALUE self) +{ + PKCS7 *pkcs7; + BIO *out; + VALUE str; + + GetPKCS7(self, pkcs7); + if(!(out = BIO_new(BIO_s_mem()))) + ossl_raise(ePKCS7Error, NULL); + if(!PKCS7_print_ctx(out, pkcs7, 0, NULL)) { + BIO_free(out); + ossl_raise(ePKCS7Error, NULL); + } + str = ossl_membio2str(out); + + return str; +} + +static VALUE ossl_pkcs7_to_pem(VALUE self) { PKCS7 *pkcs7; @@ -1056,6 +1075,7 @@ Init_ossl_pkcs7(void) rb_define_method(cPKCS7, "to_pem", ossl_pkcs7_to_pem, 0); rb_define_alias(cPKCS7, "to_s", "to_pem"); rb_define_method(cPKCS7, "to_der", ossl_pkcs7_to_der, 0); + rb_define_method(cPKCS7, "to_text", ossl_pkcs7_to_text, 0); cPKCS7Signer = rb_define_class_under(cPKCS7, "SignerInfo", rb_cObject); rb_define_const(cPKCS7, "Signer", cPKCS7Signer); diff --git a/ext/openssl/ossl_pkcs7.h b/ext/openssl/ossl_pkcs7.h index 3e1b0946..4cbbc6a1 100644 --- a/ext/openssl/ossl_pkcs7.h +++ b/ext/openssl/ossl_pkcs7.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_PKCS7_H_) #define _OSSL_PKCS7_H_ diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index 013412c2..6af2245f 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h index 10669b82..37d828e0 100644 --- a/ext/openssl/ossl_pkey.h +++ b/ext/openssl/ossl_pkey.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(OSSL_PKEY_H) #define OSSL_PKEY_H diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c index a231814a..00699b9b 100644 --- a/ext/openssl/ossl_pkey_dh.c +++ b/ext/openssl/ossl_pkey_dh.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c index 058ce738..a7598d1e 100644 --- a/ext/openssl/ossl_pkey_dsa.c +++ b/ext/openssl/ossl_pkey_dsa.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c index 389f76f3..7d986989 100644 --- a/ext/openssl/ossl_pkey_rsa.c +++ b/ext/openssl/ossl_pkey_rsa.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" diff --git a/ext/openssl/ossl_provider.c b/ext/openssl/ossl_provider.c index 981c6ccd..d1f6c5d4 100644 --- a/ext/openssl/ossl_provider.c +++ b/ext/openssl/ossl_provider.c @@ -1,6 +1,6 @@ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" diff --git a/ext/openssl/ossl_rand.c b/ext/openssl/ossl_rand.c index 659dc818..774e7836 100644 --- a/ext/openssl/ossl_rand.c +++ b/ext/openssl/ossl_rand.c @@ -5,7 +5,7 @@ * All rights reserved. * * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" diff --git a/ext/openssl/ossl_rand.h b/ext/openssl/ossl_rand.h index 8f77a3b2..874ab539 100644 --- a/ext/openssl/ossl_rand.h +++ b/ext/openssl/ossl_rand.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_RAND_H_) #define _OSSL_RAND_H_ diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index 236d455f..457630dd 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -7,7 +7,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -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); @@ -1947,9 +1958,11 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock) else rb_str_modify_expand(str, ilen - RSTRING_LEN(str)); } - rb_str_set_len(str, 0); - if (ilen == 0) - return str; + + if (ilen == 0) { + rb_str_set_len(str, 0); + return str; + } VALUE io = rb_attr_get(self, id_i_io); diff --git a/ext/openssl/ossl_ssl.h b/ext/openssl/ossl_ssl.h index 535c5609..a92985c6 100644 --- a/ext/openssl/ossl_ssl.h +++ b/ext/openssl/ossl_ssl.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_SSL_H_) #define _OSSL_SSL_H_ diff --git a/ext/openssl/ossl_ts.c b/ext/openssl/ossl_ts.c index f698bdc7..d6a5fc98 100644 --- a/ext/openssl/ossl_ts.c +++ b/ext/openssl/ossl_ts.c @@ -5,7 +5,7 @@ */ /* * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -504,6 +504,25 @@ ossl_ts_req_to_der(VALUE self) } static VALUE +ossl_ts_req_to_text(VALUE self) +{ + TS_REQ *req; + BIO *out; + + GetTSRequest(self, req); + + out = BIO_new(BIO_s_mem()); + if (!out) ossl_raise(eTimestampError, NULL); + + if (!TS_REQ_print_bio(out, req)) { + BIO_free(out); + ossl_raise(eTimestampError, NULL); + } + + return ossl_membio2str(out); +} + +static VALUE ossl_ts_resp_alloc(VALUE klass) { TS_RESP *resp; @@ -757,6 +776,25 @@ ossl_ts_resp_to_der(VALUE self) return asn1_to_der((void *)resp, (int (*)(void *, unsigned char **))i2d_TS_RESP); } +static VALUE +ossl_ts_resp_to_text(VALUE self) +{ + TS_RESP *resp; + BIO *out; + + GetTSResponse(self, resp); + + out = BIO_new(BIO_s_mem()); + if (!out) ossl_raise(eTimestampError, NULL); + + if (!TS_RESP_print_bio(out, resp)) { + BIO_free(out); + ossl_raise(eTimestampError, NULL); + } + + return ossl_membio2str(out); +} + /* * Verifies a timestamp token by checking the signature, validating the * certificate chain implied by tsa_certificate and by checking conformance to @@ -1073,6 +1111,25 @@ ossl_ts_token_info_to_der(VALUE self) return asn1_to_der((void *)info, (int (*)(void *, unsigned char **))i2d_TS_TST_INFO); } +static VALUE +ossl_ts_token_info_to_text(VALUE self) +{ + TS_TST_INFO *info; + BIO *out; + + GetTSTokenInfo(self, info); + + out = BIO_new(BIO_s_mem()); + if (!out) ossl_raise(eTimestampError, NULL); + + if (!TS_TST_INFO_print_bio(out, info)) { + BIO_free(out); + ossl_raise(eTimestampError, NULL); + } + + return ossl_membio2str(out); +} + static ASN1_INTEGER * ossl_tsfac_serial_cb(struct TS_resp_ctx *ctx, void *data) { @@ -1356,6 +1413,7 @@ Init_ossl_ts(void) rb_define_method(cTimestampResponse, "token_info", ossl_ts_resp_get_token_info, 0); rb_define_method(cTimestampResponse, "tsa_certificate", ossl_ts_resp_get_tsa_certificate, 0); rb_define_method(cTimestampResponse, "to_der", ossl_ts_resp_to_der, 0); + rb_define_method(cTimestampResponse, "to_text", ossl_ts_resp_to_text, 0); rb_define_method(cTimestampResponse, "verify", ossl_ts_resp_verify, -1); /* Document-class: OpenSSL::Timestamp::TokenInfo @@ -1374,6 +1432,7 @@ Init_ossl_ts(void) rb_define_method(cTimestampTokenInfo, "ordering", ossl_ts_token_info_get_ordering, 0); rb_define_method(cTimestampTokenInfo, "nonce", ossl_ts_token_info_get_nonce, 0); rb_define_method(cTimestampTokenInfo, "to_der", ossl_ts_token_info_to_der, 0); + rb_define_method(cTimestampTokenInfo, "to_text", ossl_ts_token_info_to_text, 0); /* Document-class: OpenSSL::Timestamp::Request * Allows to create timestamp requests or parse existing ones. A Request is @@ -1399,6 +1458,7 @@ Init_ossl_ts(void) rb_define_method(cTimestampRequest, "cert_requested=", ossl_ts_req_set_cert_requested, 1); rb_define_method(cTimestampRequest, "cert_requested?", ossl_ts_req_get_cert_requested, 0); rb_define_method(cTimestampRequest, "to_der", ossl_ts_req_to_der, 0); + rb_define_method(cTimestampRequest, "to_text", ossl_ts_req_to_text, 0); /* * Indicates a successful response. Equal to +0+. diff --git a/ext/openssl/ossl_ts.h b/ext/openssl/ossl_ts.h index 25fb0e1d..eeca3046 100644 --- a/ext/openssl/ossl_ts.h +++ b/ext/openssl/ossl_ts.h @@ -5,7 +5,7 @@ */ /* * This program is licenced under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_TS_H_) diff --git a/ext/openssl/ossl_x509.c b/ext/openssl/ossl_x509.c index f8470703..9686fc1a 100644 --- a/ext/openssl/ossl_x509.c +++ b/ext/openssl/ossl_x509.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" diff --git a/ext/openssl/ossl_x509.h b/ext/openssl/ossl_x509.h index 4fadfa6b..88e3f16a 100644 --- a/ext/openssl/ossl_x509.h +++ b/ext/openssl/ossl_x509.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_X509_H_) #define _OSSL_X509_H_ diff --git a/ext/openssl/ossl_x509attr.c b/ext/openssl/ossl_x509attr.c index d1d8bb5e..be525c9e 100644 --- a/ext/openssl/ossl_x509attr.c +++ b/ext/openssl/ossl_x509attr.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" diff --git a/ext/openssl/ossl_x509cert.c b/ext/openssl/ossl_x509cert.c index aa6b9bb7..846dd070 100644 --- a/ext/openssl/ossl_x509cert.c +++ b/ext/openssl/ossl_x509cert.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -539,7 +539,11 @@ ossl_x509_sign(VALUE self, VALUE key, VALUE digest) const EVP_MD *md; pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ - md = ossl_evp_get_digestbyname(digest); + if (NIL_P(digest)) { + md = NULL; /* needed for some key types, e.g. Ed25519 */ + } else { + md = ossl_evp_get_digestbyname(digest); + } GetX509(self, x509); if (!X509_sign(x509, pkey, md)) { ossl_raise(eX509CertError, NULL); @@ -707,6 +711,38 @@ ossl_x509_eq(VALUE self, VALUE other) return !X509_cmp(a, b) ? Qtrue : Qfalse; } +#ifdef HAVE_I2D_RE_X509_TBS +/* + * call-seq: + * cert.tbs_bytes => string + * + * Returns the DER-encoded bytes of the certificate's to be signed certificate. + * This is mainly useful for validating embedded certificate transparency signatures. + */ +static VALUE +ossl_x509_tbs_bytes(VALUE self) +{ + X509 *x509; + int len; + unsigned char *p0; + VALUE str; + + GetX509(self, x509); + len = i2d_re_X509_tbs(x509, NULL); + if (len <= 0) { + ossl_raise(eX509CertError, "i2d_re_X509_tbs"); + } + str = rb_str_new(NULL, len); + p0 = (unsigned char *)RSTRING_PTR(str); + if (i2d_re_X509_tbs(x509, &p0) <= 0) { + ossl_raise(eX509CertError, "i2d_re_X509_tbs"); + } + ossl_str_adjust(str, p0); + + return str; +} +#endif + struct load_chained_certificates_arguments { VALUE certificates; X509 *certificate; @@ -999,4 +1035,7 @@ Init_ossl_x509cert(void) rb_define_method(cX509Cert, "add_extension", ossl_x509_add_extension, 1); rb_define_method(cX509Cert, "inspect", ossl_x509_inspect, 0); rb_define_method(cX509Cert, "==", ossl_x509_eq, 1); +#ifdef HAVE_I2D_RE_X509_TBS + rb_define_method(cX509Cert, "tbs_bytes", ossl_x509_tbs_bytes, 0); +#endif } diff --git a/ext/openssl/ossl_x509crl.c b/ext/openssl/ossl_x509crl.c index 80e29f9d..368270ce 100644 --- a/ext/openssl/ossl_x509crl.c +++ b/ext/openssl/ossl_x509crl.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" diff --git a/ext/openssl/ossl_x509ext.c b/ext/openssl/ossl_x509ext.c index 192d09bd..7f47cd7c 100644 --- a/ext/openssl/ossl_x509ext.c +++ b/ext/openssl/ossl_x509ext.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" diff --git a/ext/openssl/ossl_x509name.c b/ext/openssl/ossl_x509name.c index 9591912f..5060be92 100644 --- a/ext/openssl/ossl_x509name.c +++ b/ext/openssl/ossl_x509name.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" diff --git a/ext/openssl/ossl_x509req.c b/ext/openssl/ossl_x509req.c index f0581851..37ba0372 100644 --- a/ext/openssl/ossl_x509req.c +++ b/ext/openssl/ossl_x509req.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" diff --git a/ext/openssl/ossl_x509revoked.c b/ext/openssl/ossl_x509revoked.c index 108447c8..5b82470c 100644 --- a/ext/openssl/ossl_x509revoked.c +++ b/ext/openssl/ossl_x509revoked.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" diff --git a/ext/openssl/ossl_x509store.c b/ext/openssl/ossl_x509store.c index f27381ca..31328ec4 100644 --- a/ext/openssl/ossl_x509store.c +++ b/ext/openssl/ossl_x509store.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" diff --git a/lib/openssl.rb b/lib/openssl.rb index 8a342f15..f5ca956d 100644 --- a/lib/openssl.rb +++ b/lib/openssl.rb @@ -7,7 +7,7 @@ = Licence This program is licensed under the same licence as Ruby. - (See the file 'LICENCE'.) + (See the file 'COPYING'.) =end require 'openssl.so' diff --git a/lib/openssl/bn.rb b/lib/openssl/bn.rb index 0a5e11b4..e4889a14 100644 --- a/lib/openssl/bn.rb +++ b/lib/openssl/bn.rb @@ -10,7 +10,7 @@ # # = Licence # This program is licensed under the same licence as Ruby. -# (See the file 'LICENCE'.) +# (See the file 'COPYING'.) #++ module OpenSSL diff --git a/lib/openssl/buffering.rb b/lib/openssl/buffering.rb index 4df90746..d0b4b180 100644 --- a/lib/openssl/buffering.rb +++ b/lib/openssl/buffering.rb @@ -8,7 +8,7 @@ # #= Licence # This program is licensed under the same licence as Ruby. -# (See the file 'LICENCE'.) +# (See the file 'COPYING'.) #++ ## @@ -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/cipher.rb b/lib/openssl/cipher.rb index 8ad8c35d..ab75ac8e 100644 --- a/lib/openssl/cipher.rb +++ b/lib/openssl/cipher.rb @@ -9,7 +9,7 @@ # # = Licence # This program is licensed under the same licence as Ruby. -# (See the file 'LICENCE'.) +# (See the file 'COPYING'.) #++ module OpenSSL diff --git a/lib/openssl/digest.rb b/lib/openssl/digest.rb index 0f35ddad..5cda1e93 100644 --- a/lib/openssl/digest.rb +++ b/lib/openssl/digest.rb @@ -9,7 +9,7 @@ # # = Licence # This program is licensed under the same licence as Ruby. -# (See the file 'LICENCE'.) +# (See the file 'COPYING'.) #++ module OpenSSL diff --git a/lib/openssl/marshal.rb b/lib/openssl/marshal.rb index af564719..eb8eda47 100644 --- a/lib/openssl/marshal.rb +++ b/lib/openssl/marshal.rb @@ -9,7 +9,7 @@ # # = Licence # This program is licensed under the same licence as Ruby. -# (See the file 'LICENCE'.) +# (See the file 'COPYING'.) #++ module OpenSSL module Marshal diff --git a/lib/openssl/ssl.rb b/lib/openssl/ssl.rb index e557b8b4..2186f5f4 100644 --- a/lib/openssl/ssl.rb +++ b/lib/openssl/ssl.rb @@ -7,7 +7,7 @@ = Licence This program is licensed under the same licence as Ruby. - (See the file 'LICENCE'.) + (See the file 'COPYING'.) =end require "openssl/buffering" @@ -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/lib/openssl/x509.rb b/lib/openssl/x509.rb index f973f4f4..b6672742 100644 --- a/lib/openssl/x509.rb +++ b/lib/openssl/x509.rb @@ -9,7 +9,7 @@ # # = Licence # This program is licensed under the same licence as Ruby. -# (See the file 'LICENCE'.) +# (See the file 'COPYING'.) #++ require_relative 'marshal' diff --git a/openssl.gemspec b/openssl.gemspec index 2765f554..e692e661 100644 --- a/openssl.gemspec +++ b/openssl.gemspec @@ -6,14 +6,14 @@ Gem::Specification.new do |spec| spec.summary = %q{SSL/TLS and general-purpose cryptography for Ruby} spec.description = %q{OpenSSL for Ruby provides access to SSL/TLS and general-purpose cryptography based on the OpenSSL library.} spec.homepage = "https://github.com/ruby/openssl" - spec.license = "Ruby" + spec.licenses = ["Ruby", "BSD-2-Clause"] if Gem::Platform === spec.platform and spec.platform =~ 'java' or RUBY_ENGINE == 'jruby' spec.platform = "java" spec.files = [] spec.add_runtime_dependency('jruby-openssl', '~> 0.14') else - spec.files = Dir["lib/**/*.rb", "ext/**/*.{c,h,rb}", "*.md", "BSDL", "LICENSE.txt"] + spec.files = Dir["lib/**/*.rb", "ext/**/*.{c,h,rb}", "*.md", "BSDL", "COPYING"] spec.require_paths = ["lib"] spec.extensions = ["ext/openssl/extconf.rb"] end 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..66e36a7a 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") @@ -239,12 +250,17 @@ module OpenSSL::TestPairM buf = +"garbage" assert_equal :wait_readable, s2.read_nonblock(100, buf, exception: false) - assert_equal "", buf + assert_equal "garbage", buf s1.close buf = +"garbage" - assert_equal nil, s2.read(100, buf) + assert_nil s2.read(100, buf) assert_equal "", buf + + buf = +"garbage" + ret = s2.read(0, buf) + assert_same buf, ret + assert_equal "", ret } end diff --git a/test/openssl/test_pkcs12.rb b/test/openssl/test_pkcs12.rb index e6b91b52..faf26c9e 100644 --- a/test/openssl/test_pkcs12.rb +++ b/test/openssl/test_pkcs12.rb @@ -159,7 +159,6 @@ module OpenSSL DEFAULT_PBE_PKEYS, DEFAULT_PBE_CERTS, nil, - nil, 2048 ) @@ -178,6 +177,36 @@ module OpenSSL end end + def test_create_with_keytype + OpenSSL::PKCS12.create( + "omg", + "hello", + @mykey, + @mycert, + [], + DEFAULT_PBE_PKEYS, + DEFAULT_PBE_CERTS, + nil, + nil, + OpenSSL::PKCS12::KEY_SIG + ) + + assert_raise(ArgumentError) do + OpenSSL::PKCS12.create( + "omg", + "hello", + @mykey, + @mycert, + [], + DEFAULT_PBE_PKEYS, + DEFAULT_PBE_CERTS, + nil, + nil, + 2048 + ) + end + end + def test_new_with_no_keys # generated with: # openssl pkcs12 -certpbe PBE-SHA1-3DES -in <@mycert> -nokeys -export diff --git a/test/openssl/test_pkcs7.rb b/test/openssl/test_pkcs7.rb index 96f3f1f6..c049ed44 100644 --- a/test/openssl/test_pkcs7.rb +++ b/test/openssl/test_pkcs7.rb @@ -227,6 +227,12 @@ END assert_equal(p7.to_der, OpenSSL::PKCS7.read_smime(smime).to_der) end + def test_to_text + p7 = OpenSSL::PKCS7.new + p7.type = "signed" + assert_match(/signed/, p7.to_text) + end + def test_degenerate_pkcs7 ca_cert_pem = <<END -----BEGIN CERTIFICATE----- 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_ts.rb b/test/openssl/test_ts.rb index 7cb1a1fe..ac0469ad 100644 --- a/test/openssl/test_ts.rb +++ b/test/openssl/test_ts.rb @@ -323,6 +323,8 @@ _end_of_pem_ resp = fac.create_timestamp(ee_key, ts_cert_ee, req) assert_equal(OpenSSL::Timestamp::Response::GRANTED, resp.status) assert_equal("1.2.3.4.6", resp.token_info.policy_id) + + assert_match(/1\.2\.3\.4\.6/, resp.to_text) end def test_response_bad_purpose diff --git a/test/openssl/test_x509cert.rb b/test/openssl/test_x509cert.rb index 64805504..85c978f0 100644 --- a/test/openssl/test_x509cert.rb +++ b/test/openssl/test_x509cert.rb @@ -222,6 +222,29 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase } end + def test_sign_and_verify_ed25519 + # See test_ed25519 in test_pkey.rb + + # Ed25519 is not FIPS-approved. + omit_on_fips + + begin + ed25519 = OpenSSL::PKey::generate_key("ED25519") + rescue OpenSSL::PKey::PKeyError => e + # OpenSSL < 1.1.1 + # + pend "Ed25519 is not implemented" unless openssl?(1, 1, 1) + + raise e + end + + # See ASN1_item_sign_ctx in ChangeLog for 3.8.1: https://github.com/libressl/portable/blob/master/ChangeLog + pend 'ASN1 signing with Ed25519 not yet working' unless openssl? or libressl?(3, 8, 1) + + cert = issue_cert(@ca, ed25519, 1, [], nil, nil, digest: nil) + assert_equal(true, cert.verify(ed25519)) + end + def test_dsa_with_sha2 cert = issue_cert(@ca, @dsa256, 1, [], nil, nil, digest: "sha256") assert_equal("dsa_with_SHA256", cert.signature_algorithm) @@ -322,6 +345,15 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase end end + def test_tbs_precert_bytes + pend "LibreSSL < 3.5 does not have i2d_re_X509_tbs" if libressl? && !libressl?(3, 5, 0) + + cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil) + seq = OpenSSL::ASN1.decode(cert.tbs_bytes) + + assert_equal 7, seq.value.size + end + private def certificate_error_returns_false diff --git a/tool/update-gh-pages b/tool/update-gh-pages deleted file mode 100755 index 8eb546a9..00000000 --- a/tool/update-gh-pages +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh -set -e - -# Generates RDoc HTML and update gh-pages branch. - -HEAD_DESCRIPTION=$(git describe --dirty --always --abbrev=12) - -[ -d html ] && - rm -r html -rake rdoc - -[ ! -d tmp/gh-pages ] && - git worktree add tmp/gh-pages gh-pages -( - cd tmp/gh-pages - - git rm -r . - cp -r ../../html/* . - rm created.rid js/*.gz # to avoid unnecessary change :x - git add . - git commit -m "Sync with $HEAD_DESCRIPTION" -) |