diff options
-rw-r--r-- | .travis.yml | 9 | ||||
-rw-r--r-- | History.md | 50 | ||||
-rw-r--r-- | ext/openssl/extconf.rb | 58 | ||||
-rw-r--r-- | ext/openssl/ossl_bn.c | 2 | ||||
-rw-r--r-- | ext/openssl/ossl_cipher.c | 8 | ||||
-rw-r--r-- | ext/openssl/ossl_ns_spki.c | 4 | ||||
-rw-r--r-- | ext/openssl/ossl_pkey_ec.c | 6 | ||||
-rw-r--r-- | ext/openssl/ossl_pkey_rsa.c | 2 | ||||
-rw-r--r-- | ext/openssl/ossl_ssl.c | 3 | ||||
-rw-r--r-- | ext/openssl/ossl_x509store.c | 9 | ||||
-rw-r--r-- | test/test_pkcs7.rb | 2 | ||||
-rw-r--r-- | test/test_pkey_ec.rb | 2 | ||||
-rw-r--r-- | test/test_ssl.rb | 2 | ||||
-rw-r--r-- | test/test_x509store.rb | 24 | ||||
-rw-r--r-- | tool/ruby-openssl-docker/Dockerfile | 24 | ||||
-rwxr-xr-x | tool/sync-with-trunk | 8 |
16 files changed, 172 insertions, 41 deletions
diff --git a/.travis.yml b/.travis.yml index 68b8cc4a..fed2e839 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,4 +24,13 @@ matrix: - env: RUBY_VERSION=ruby-2.4 OPENSSL_VERSION=libressl-2.3 - env: RUBY_VERSION=ruby-2.4 OPENSSL_VERSION=libressl-2.4 - env: RUBY_VERSION=ruby-2.4 OPENSSL_VERSION=libressl-2.5 + - language: ruby + rvm: ruby-head + before_install: + - "rake install_dependencies" + script: + - "rake compile -- --enable-debug" + - "rake test" allow_failures: + - language: ruby + rvm: ruby-head @@ -23,6 +23,53 @@ Deprecations ------------ +Version 2.0.4 +============= + +Bug fixes +--------- + +* It now compiles with LibreSSL without renaming on Windows (mswin). +* A workaround for the error queue leak of X509_load_cert_crl_file() that + causes random errors is added. + [[Bug #11033]](https://bugs.ruby-lang.org/issues/11033) + + +Version 2.0.3 +============= + +Bug fixes +--------- + +* OpenSSL::ASN1::Constructive#each which was broken by 2.0.0 is fixed. + [[ruby/openssl#96]](https://github.com/ruby/openssl/pull/96) +* Fixed build with static OpenSSL libraries on Windows. + [[Bug #13080]](https://bugs.ruby-lang.org/issues/13080) +* OpenSSL::X509::Name#eql? which was broken by 2.0.0 is fixed. + + +Version 2.0.2 +============= + +Bug fixes +--------- + +* Fix build with early 0.9.8 series which did not have SSL_CTX_clear_options(). + [ruby-core:78693] + + +Version 2.0.1 +============= + +Bug fixes +--------- + +* A GC issue around OpenSSL::BN is fixed. + [[ruby/openssl#87]](https://github.com/ruby/openssl/issues/87) +* OpenSSL::ASN1 now parses BER encoding of GeneralizedTime without seconds. + [[ruby/openssl#88]](https://github.com/ruby/openssl/pull/88) + + Version 2.0.0 ============= @@ -48,7 +95,8 @@ Supported platforms Notable changes --------------- -* Add support for OpenSSL 1.1.0. [[Feature #12324]](https://bugs.ruby-lang.org/issues/12324) +* Add support for OpenSSL 1.1.0. + [[Feature #12324]](https://bugs.ruby-lang.org/issues/12324) * Add support for LibreSSL * OpenSSL::Cipher diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb index b887d922..0f099fc3 100644 --- a/ext/openssl/extconf.rb +++ b/ext/openssl/extconf.rb @@ -36,25 +36,65 @@ have_library("socket", "socket") Logging::message "=== Checking for required stuff... ===\n" result = pkg_config("openssl") && have_header("openssl/ssl.h") -unless result + +def find_openssl_library if $mswin || $mingw # required for static OpenSSL libraries have_library("gdi32") # OpenSSL <= 1.0.2 (for RAND_screen()) have_library("crypt32") end - result = %w[crypto libeay32].any? {|lib| have_library(lib, "CRYPTO_malloc")} - result &&= %w[ssl ssleay32].any? {|lib| have_library(lib, "SSL_new")} - unless result + return false unless have_header("openssl/ssl.h") + + ret = have_library("crypto", "CRYPTO_malloc") && + have_library("ssl", "SSL_new") + return ret if ret + + if $mswin + # OpenSSL >= 1.1.0: libcrypto.lib and libssl.lib. + if have_library("libcrypto", "CRYPTO_malloc") && + have_library("libssl", "SSL_new") + return true + end + + # OpenSSL <= 1.0.2: libeay32.lib and ssleay32.lib. + if have_library("libeay32", "CRYPTO_malloc") && + have_library("ssleay32", "SSL_new") + return true + end + + # LibreSSL: libcrypto-##.lib and libssl-##.lib, where ## is the ABI version + # number. We have to find the version number out by scanning libpath. + libpath = $LIBPATH.dup + libpath |= ENV["LIB"].split(File::PATH_SEPARATOR) + libpath.map! { |d| d.tr(File::ALT_SEPARATOR, File::SEPARATOR) } + + ret = [ + ["crypto", "CRYPTO_malloc"], + ["ssl", "SSL_new"] + ].all? do |base, func| + result = false + libs = ["lib#{base}-[0-9][0-9]", "lib#{base}-[0-9][0-9][0-9]"] + libs = Dir.glob(libs.map{|l| libpath.map{|d| File.join(d, l + ".*")}}.flatten).map{|path| File.basename(path, ".*")}.uniq + libs.each do |lib| + result = have_library(lib, func) + break if result + end + result + end + return ret if ret + end + return false +end + +unless result + unless find_openssl_library + Logging::message "=== Checking for required stuff failed. ===\n" + Logging::message "Makefile wasn't created. Fix the errors above.\n" raise "OpenSSL library could not be found. You might want to use " \ "--with-openssl-dir=<dir> option to specify the prefix where OpenSSL " \ "is installed." end - unless have_header("openssl/ssl.h") - raise "OpenSSL library itself was found, but the necessary header files " \ - "are missing. Installing \"development package\" of OpenSSL on your " \ - "system might help." - end end unless checking_for("OpenSSL version is 1.0.1 or later") { diff --git a/ext/openssl/ossl_bn.c b/ext/openssl/ossl_bn.c index b3c86d72..94ef6fd6 100644 --- a/ext/openssl/ossl_bn.c +++ b/ext/openssl/ossl_bn.c @@ -124,7 +124,7 @@ try_convert_to_bn(VALUE obj) if (rb_obj_is_kind_of(obj, cBN)) return obj; if (RB_INTEGER_TYPE_P(obj)) { - newobj = NewBN(cBN); /* Handle potencial mem leaks */ + newobj = NewBN(cBN); /* Handle potential mem leaks */ bn = integer_to_bnptr(obj, NULL); SetBN(newobj, bn); } diff --git a/ext/openssl/ossl_cipher.c b/ext/openssl/ossl_cipher.c index e7801f7e..21fcb1b6 100644 --- a/ext/openssl/ossl_cipher.c +++ b/ext/openssl/ossl_cipher.c @@ -23,7 +23,7 @@ #define GetCipher(obj, ctx) do { \ GetCipherInit((obj), (ctx)); \ if (!(ctx)) { \ - ossl_raise(rb_eRuntimeError, "Cipher not inititalized!"); \ + ossl_raise(rb_eRuntimeError, "Cipher not initialized!"); \ } \ } while (0) @@ -118,7 +118,7 @@ ossl_cipher_initialize(VALUE self, VALUE str) name = StringValueCStr(str); GetCipherInit(self, ctx); if (ctx) { - ossl_raise(rb_eRuntimeError, "Cipher already inititalized!"); + ossl_raise(rb_eRuntimeError, "Cipher already initialized!"); } AllocCipher(self, ctx); if (!(cipher = EVP_get_cipherbyname(name))) { @@ -414,7 +414,7 @@ ossl_cipher_update(int argc, VALUE *argv, VALUE self) * Returns the remaining data held in the cipher object. Further calls to * Cipher#update or Cipher#final will return garbage. This call should always * be made as the last call of an encryption or decryption operation, after - * after having fed the entire plaintext or ciphertext to the Cipher instance. + * having fed the entire plaintext or ciphertext to the Cipher instance. * * If an authenticated cipher was used, a CipherError is raised if the tag * could not be authenticated successfully. Only call this method after @@ -1003,7 +1003,7 @@ Init_ossl_cipher(void) * An example using the GCM (Galois/Counter Mode). You have 16 bytes _key_, * 12 bytes (96 bits) _nonce_ and the associated data _auth_data_. Be sure * not to reuse the _key_ and _nonce_ pair. Reusing an nonce ruins the - * security gurantees of GCM mode. + * security guarantees of GCM mode. * * cipher = OpenSSL::Cipher::AES.new(128, :GCM).encrypt * cipher.key = key diff --git a/ext/openssl/ossl_ns_spki.c b/ext/openssl/ossl_ns_spki.c index 15d40810..f17b9509 100644 --- a/ext/openssl/ossl_ns_spki.c +++ b/ext/openssl/ossl_ns_spki.c @@ -322,7 +322,7 @@ ossl_spki_verify(VALUE self, VALUE key) /* Document-class: OpenSSL::Netscape::SPKI * - * A Simple Public Key Infrastructure implementation (pronounced "spookey"). + * A Simple Public Key Infrastructure implementation (pronounced "spooky"). * The structure is defined as * PublicKeyAndChallenge ::= SEQUENCE { * spki SubjectPublicKeyInfo, @@ -348,7 +348,7 @@ ossl_spki_verify(VALUE self, VALUE key) * spki.public_key = key.public_key * spki.sign(key, OpenSSL::Digest::SHA256.new) * #send a request containing this to a server generating a certificate - * === Verifiying an SPKI request + * === Verifying an SPKI request * request = #... * spki = OpenSSL::Netscape::SPKI.new request * unless spki.verify(spki.public_key) diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c index eb841fb7..d1515306 100644 --- a/ext/openssl/ossl_pkey_ec.c +++ b/ext/openssl/ossl_pkey_ec.c @@ -284,7 +284,7 @@ ossl_ec_key_get_group(VALUE self) * key.group = group * * Sets the EC::Group for the key. The group structure is internally copied so - * modifition to _group_ after assigning to a key has no effect on the key. + * modification to _group_ after assigning to a key has no effect on the key. */ static VALUE ossl_ec_key_set_group(VALUE self, VALUE group_v) @@ -1585,11 +1585,11 @@ ossl_ec_point_to_bn(int argc, VALUE *argv, VALUE self) * Performs elliptic curve point multiplication. * * The first form calculates <tt>bn1 * point + bn2 * G</tt>, where +G+ is the - * generator of the group of _point_. _bn2_ may be ommitted, and in that case, + * generator of the group of _point_. _bn2_ may be omitted, and in that case, * the result is just <tt>bn1 * point</tt>. * * The second form calculates <tt>bns[0] * point + bns[1] * points[0] + ... - * + bns[-1] * points[-1] + bn2 * G</tt>. _bn2_ may be ommitted. _bns_ must be + * + bns[-1] * points[-1] + bn2 * G</tt>. _bn2_ may be omitted. _bns_ must be * an array of OpenSSL::BN. _points_ must be an array of * OpenSSL::PKey::EC::Point. Please note that <tt>points[0]</tt> is not * multiplied by <tt>bns[0]</tt>, but <tt>bns[1]</tt>. diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c index b3c2915f..5122a77e 100644 --- a/ext/openssl/ossl_pkey_rsa.c +++ b/ext/openssl/ossl_pkey_rsa.c @@ -706,7 +706,7 @@ Init_ossl_rsa(void) /* Document-class: OpenSSL::PKey::RSA * * RSA is an asymmetric public key algorithm that has been formalized in - * RFC 3447. It is in widespread use in public key infrastuctures (PKI) + * RFC 3447. It is in widespread use in public key infrastructures (PKI) * where certificates (cf. OpenSSL::X509::Certificate) often are issued * on the basis of a public/private RSA key pair. RSA is used in a wide * field of applications such as secure (symmetric) key exchange, e.g. diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index 2a7793c2..ae03c164 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -1466,7 +1466,8 @@ ossl_ssl_setup(VALUE self) GetOpenFile(io, fptr); rb_io_check_readable(fptr); rb_io_check_writable(fptr); - SSL_set_fd(ssl, TO_SOCKET(fptr->fd)); + if (!SSL_set_fd(ssl, TO_SOCKET(fptr->fd))) + ossl_raise(eSSLError, "SSL_set_fd"); return Qtrue; } diff --git a/ext/openssl/ossl_x509store.c b/ext/openssl/ossl_x509store.c index 46d3552f..c6cf67ad 100644 --- a/ext/openssl/ossl_x509store.c +++ b/ext/openssl/ossl_x509store.c @@ -313,6 +313,15 @@ ossl_x509store_add_file(VALUE self, VALUE file) if(X509_LOOKUP_load_file(lookup, path, X509_FILETYPE_PEM) != 1){ ossl_raise(eX509StoreError, NULL); } +#if OPENSSL_VERSION_NUMBER < 0x10101000 || defined(LIBRESSL_VERSION_NUMBER) + /* + * X509_load_cert_crl_file() which is called from X509_LOOKUP_load_file() + * did not check the return value of X509_STORE_add_{cert,crl}(), leaking + * "cert already in hash table" errors on the error queue, if duplicate + * certificates are found. This will be fixed by OpenSSL 1.1.1. + */ + ossl_clear_error(); +#endif return self; } diff --git a/test/test_pkcs7.rb b/test/test_pkcs7.rb index c0a04acd..5320cc38 100644 --- a/test/test_pkcs7.rb +++ b/test/test_pkcs7.rb @@ -45,7 +45,7 @@ class OpenSSL::TestPKCS7 < OpenSSL::TestCase assert_equal(@ee1_cert.serial, signers[0].serial) assert_equal(@ee1_cert.issuer.to_s, signers[0].issuer.to_s) - # Normaly OpenSSL tries to translate the supplied content into canonical + # Normally OpenSSL tries to translate the supplied content into canonical # MIME format (e.g. a newline character is converted into CR+LF). # If the content is a binary, PKCS7::BINARY flag should be used. diff --git a/test/test_pkey_ec.rb b/test/test_pkey_ec.rb index e1d1e942..2944f5c2 100644 --- a/test/test_pkey_ec.rb +++ b/test/test_pkey_ec.rb @@ -277,7 +277,7 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase group = OpenSSL::PKey::EC::Group.new(:GFp, 17, 2, 2) group.point_conversion_form = :uncompressed gen = OpenSSL::PKey::EC::Point.new(group, OpenSSL::BN.new("040501", 16)) - group.set_generator(gen, 0, 0) + group.set_generator(gen, 19, 1) # 3 * (6, 3) = (16, 13) point_a = OpenSSL::PKey::EC::Point.new(group, OpenSSL::BN.new("040603", 16)) diff --git a/test/test_ssl.rb b/test/test_ssl.rb index 8bf0c214..9a28b5dd 100644 --- a/test/test_ssl.rb +++ b/test/test_ssl.rb @@ -64,7 +64,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase buf = "" ssl.syswrite(str) assert_same buf, ssl.sysread(str.size, buf) - assert_equal(str, newstr) + assert_equal(str, buf) } } end diff --git a/test/test_x509store.rb b/test/test_x509store.rb index dbab6424..0009813d 100644 --- a/test/test_x509store.rb +++ b/test/test_x509store.rb @@ -24,6 +24,29 @@ class OpenSSL::TestX509Store < OpenSSL::TestCase ctx.verify end + def test_add_file + ca_exts = [ + ["basicConstraints", "CA:TRUE", true], + ["keyUsage", "cRLSign,keyCertSign", true], + ] + cert1 = issue_cert(@ca1, @rsa1024, 1, ca_exts, nil, nil) + cert2 = issue_cert(@ca2, @rsa2048, 1, ca_exts, nil, nil) + tmpfile = Tempfile.open { |f| f << cert1.to_pem << cert2.to_pem; f } + + store = OpenSSL::X509::Store.new + assert_equal false, store.verify(cert1) + assert_equal false, store.verify(cert2) + store.add_file(tmpfile.path) + assert_equal true, store.verify(cert1) + assert_equal true, store.verify(cert2) + + # OpenSSL < 1.1.1 leaks an error on a duplicate certificate + assert_nothing_raised { store.add_file(tmpfile.path) } + assert_equal [], OpenSSL.errors + ensure + tmpfile and tmpfile.close! + end + def test_verify # OpenSSL uses time(2) while Time.now uses clock_gettime(CLOCK_REALTIME), # and there may be difference. @@ -184,6 +207,7 @@ class OpenSSL::TestX509Store < OpenSSL::TestCase end def test_set_errors + return if OpenSSL::OPENSSL_VERSION_NUMBER >= 0x10100000 now = Time.now ca1_cert = issue_cert(@ca1, @rsa2048, 1, [], nil, nil) store = OpenSSL::X509::Store.new diff --git a/tool/ruby-openssl-docker/Dockerfile b/tool/ruby-openssl-docker/Dockerfile index d22a7e43..0bafbaae 100644 --- a/tool/ruby-openssl-docker/Dockerfile +++ b/tool/ruby-openssl-docker/Dockerfile @@ -42,8 +42,8 @@ RUN curl -s https://www.openssl.org/source/openssl-1.0.2k.tar.gz | tar -C /build shared linux-x86_64 && \ make && make install_sw -RUN curl -s https://www.openssl.org/source/openssl-1.1.0d.tar.gz | tar -C /build/openssl -xzf - && \ - cd /build/openssl/openssl-1.1.0d && \ +RUN curl -s https://www.openssl.org/source/openssl-1.1.0e.tar.gz | tar -C /build/openssl -xzf - && \ + cd /build/openssl/openssl-1.1.0e && \ ./Configure \ --prefix=/opt/openssl/openssl-1.1.0 \ enable-crypto-mdebug enable-crypto-mdebug-backtrace \ @@ -51,36 +51,36 @@ RUN curl -s https://www.openssl.org/source/openssl-1.1.0d.tar.gz | tar -C /build make && make install_sw # Supported libressl versions: 2.3- -RUN curl -s http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-2.3.9.tar.gz | tar -C /build/openssl -xzf - -RUN cd /build/openssl/libressl-2.3.9 && \ +RUN curl -s http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-2.3.10.tar.gz | tar -C /build/openssl -xzf - +RUN cd /build/openssl/libressl-2.3.10 && \ ./configure \ --prefix=/opt/openssl/libressl-2.3 && \ make && make install -RUN curl -s http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-2.4.4.tar.gz | tar -C /build/openssl -xzf - -RUN cd /build/openssl/libressl-2.4.4 && \ +RUN curl -s http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-2.4.5.tar.gz | tar -C /build/openssl -xzf - +RUN cd /build/openssl/libressl-2.4.5 && \ ./configure \ --prefix=/opt/openssl/libressl-2.4 && \ make && make install -RUN curl -s http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-2.5.0.tar.gz | tar -C /build/openssl -xzf - -RUN cd /build/openssl/libressl-2.5.0 && \ +RUN curl -s http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-2.5.4.tar.gz | tar -C /build/openssl -xzf - +RUN cd /build/openssl/libressl-2.5.4 && \ ./configure \ --prefix=/opt/openssl/libressl-2.5 && \ make && make install # Supported Ruby versions: 2.3- RUN mkdir -p /build/ruby -RUN curl -s https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.3.tar.gz | tar -C /build/ruby -xzf - && \ - cd /build/ruby/ruby-2.3.3 && \ +RUN curl -s https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.4.tar.gz | tar -C /build/ruby -xzf - && \ + cd /build/ruby/ruby-2.3.4 && \ autoconf && ./configure \ --without-openssl \ --prefix=/opt/ruby/ruby-2.3 \ --disable-install-doc && \ make && make install -RUN curl -s https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.0.tar.gz | tar -C /build/ruby -xzf - && \ - cd /build/ruby/ruby-2.4.0 && \ +RUN curl -s https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.1.tar.gz | tar -C /build/ruby -xzf - && \ + cd /build/ruby/ruby-2.4.1 && \ autoconf && ./configure \ --without-openssl \ --prefix=/opt/ruby/ruby-2.4 \ diff --git a/tool/sync-with-trunk b/tool/sync-with-trunk index 00b80c00..d721d2ec 100755 --- a/tool/sync-with-trunk +++ b/tool/sync-with-trunk @@ -61,8 +61,8 @@ echo "#### Step 1. Sync '$BRANCH_EXTRACT' with 'ruby/trunk'" sed -ie "/^$graftpoint$/d" $(git rev-parse --git-common-dir)/info/grafts ) -LASY_SYNC_COMMIT=$(git log --format=format:%H -n1 --grep '^Sync-with-trunk: r') -LAST_SYNC_REV=$(git show --format=format:%B $LASY_SYNC_COMMIT | grep -Po '(?<=^Sync-with-trunk: r)[0-9]+$' | tail -n1) +LAST_SYNC_COMMIT=$(git log --format=format:%H -n1 --grep '^Sync-with-trunk: r') +LAST_SYNC_REV=$(git show --format=format:%B $LAST_SYNC_COMMIT | grep -Po '(?<=^Sync-with-trunk: r)[0-9]+$' | tail -n1) NEXT_SYNC_REV=$(sha1_to_rev $BRANCH_EXTRACT) [ "$LAST_SYNC_REV" = "$NEXT_SYNC_REV" ] && ( @@ -78,12 +78,12 @@ echo "#### Step 2. Rebase '$BRANCH_EXTRACT' on the last sync commit" cd tmp/sync-merge git checkout $BRANCH_MERGE git reset -q --hard $BRANCH_EXTRACT - git rebase --onto $LASY_SYNC_COMMIT $(rev_to_sha1 $BRANCH_EXTRACT $LAST_SYNC_REV) $BRANCH_MERGE + git rebase --onto $LAST_SYNC_COMMIT $(rev_to_sha1 $BRANCH_EXTRACT $LAST_SYNC_REV) $BRANCH_MERGE ) echo "#### Step 3. Merge '$BRANCH_MERGE' into '$(git rev-parse --abbrev-ref HEAD)'" commit_message=$( - commits=$(git log --oneline --format='%H %<(61,trunc)%s' $LASY_SYNC_COMMIT..$BRANCH_MERGE) + commits=$(git log --oneline --format='%H %<(61,trunc)%s' $LAST_SYNC_COMMIT..$BRANCH_MERGE) echo "Merge changes from Ruby trunk r$LAST_SYNC_REV..r$NEXT_SYNC_REV" echo "" echo "* ruby-trunk r$LAST_SYNC_REV..r$NEXT_SYNC_REV: ($(echo "$commits" | wc -l) commits)" |