diff options
-rw-r--r-- | ext/openssl/ossl_x509store.c | 9 | ||||
-rw-r--r-- | test/test_x509store.rb | 23 |
2 files changed, 32 insertions, 0 deletions
diff --git a/ext/openssl/ossl_x509store.c b/ext/openssl/ossl_x509store.c index eb81e0d4..4becc8e3 100644 --- a/ext/openssl/ossl_x509store.c +++ b/ext/openssl/ossl_x509store.c @@ -342,6 +342,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_x509store.rb b/test/test_x509store.rb index a5dfa206..c45233aa 100644 --- a/test/test_x509store.rb +++ b/test/test_x509store.rb @@ -34,6 +34,29 @@ class OpenSSL::TestX509Store < OpenSSL::TestCase OpenSSL::TestUtils.issue_crl(*args) 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. |