aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrhe <rhe@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-09-03 12:35:27 +0000
committerrhe <rhe@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-09-03 12:35:27 +0000
commit609103dbb5fb182eec12f052226c43e39b907682 (patch)
tree881cdacc3312e65261ebd34a807c75ee09fdb303
parentb9801bb8b2f5ce91755e0076d79140a72ff94d6a (diff)
downloadruby-609103dbb5fb182eec12f052226c43e39b907682.tar.gz
openssl: import v2.1.0.beta1
Import Ruby/OpenSSL 2.1.0.beta1. The full commit log since v2.0.5 (imported by r59567) can be found at: https://github.com/ruby/openssl/compare/v2.0.5...v2.1.0.beta1 ---------------------------------------------------------------- Antonio Terceiro (1): test/test_ssl: explicitly accept TLS 1.1 in corresponding test Colby Swandale (1): document using secure protocol to fetch git master in Bundler Colton Jenkins (1): Add fips_mode_get to return fips_mode Kazuki Yamaguchi (85): Start preparing for 2.1.0 Remove support for OpenSSL 0.9.8 and 1.0.0 bn: refine tests bn: implement unary {plus,minus} operators for OpenSSL::BN bn: implement OpenSSL::BN#negative? Don't define main() when built with --enable-debug test: let OpenSSL::TestCase include OpenSSL::TestUtils test: prepare test PKey instances on demand Add OpenSSL.print_mem_leaks Enable OSSL_MDEBUG on CI builds ssl: move default DH parameters from OpenSSL::PKey::DH Make exceptions with the same format regardless of OpenSSL.debug ssl: show reason of 'certificate verify error' in exception message ssl: remove OpenSSL::ExtConfig::TLS_DH_anon_WITH_AES_256_GCM_SHA384 ssl: do not confuse different ex_data index registries ssl: assume SSL/SSL_CTX always have a valid reference to the Ruby object Fix RDoc markup ssl: suppress compiler warning ext/openssl/deprecation.rb: remove broken-apple-openssl extconf.rb: print informative message if OpenSSL can't be found Rakefile: compile the extension before test kdf: introduce OpenSSL::KDF module ossl.h: add NUM2UINT64T() macro kdf: add scrypt Expand rb_define_copy_func() macro Expand FPTR_TO_FD() macro Remove SafeGet*() macros cipher: rename GetCipherPtr() to ossl_evp_get_cipherbyname() digest: rename GetDigestPtr() to ossl_evp_get_digestbyname() Add ossl_str_new(), an exception-safe rb_str_new() bio: simplify ossl_membio2str() using ossl_str_new() Remove unused functions and macros Drop support for LibreSSL 2.3 ocsp: add OpenSSL::OCSP::Request#signed? asn1: infinite length -> indefinite length asn1: rearrange tests ssl: remove a needless NULL check in SSL::SSLContext#ciphers ssl: return nil in SSL::SSLSocket#cipher if session is not started asn1: remove an unnecessary function prototype asn1: require tag information when instantiating generic type asn1: initialize 'unused_bits' attribute of BitString with 0 asn1: check for illegal 'unused_bits' value of BitString asn1: disallow NULL to be passed to asn1time_to_time() asn1: avoid truncating OID in OpenSSL::ASN1::ObjectId#oid asn1: allow constructed encoding with definite length form asn1: prohibit indefinite length form for primitive encoding asn1: allow tag number to be >= 32 for universal tag class asn1: use ossl_asn1_tag() asn1: clean up OpenSSL::ASN1::Constructive#to_der asn1: harmonize OpenSSL::ASN1::*#to_der asn1: prevent EOC octets from being in the middle of the content asn1: do not treat EOC octets as part of content octets x509name: add 'loc' and 'set' kwargs to OpenSSL::X509::Name#add_entry ssl: do not call session_remove_cb during GC Backport "Merge branch 'topic/test-memory-leak'" to maint cipher: update the documentation for Cipher#auth_tag= Rakefile: let sync:to_ruby know about test/openssl/fixtures test: fix formatting test/utils: remove OpenSSL::TestUtils.silent test/utils: add SSLTestCase#tls12_supported? test/utils: have start_server yield only the port number test/utils: do not set ecdh_curves in start_server test/utils: let server_loop close socket test/utils: improve error handling in start_server test/utils: add OpenSSL::TestUtils.openssl? and .libressl? test/utils: do not use DSA certificates in SSL tests test/test_ssl: remove test_invalid_shutdown_by_gc test/test_ssl: move test_multibyte_read_write to test_pair test/test_ssl_session: rearrange tests test/test_pair, test/test_ssl: fix for TLS 1.3 ssl: remove useless call to rb_thread_wait_fd() ssl: fix NPN support ssl: mark OpenSSL::SSL::SSLContext::DEFAULT_{1024,2048} as private ssl: use 2048-bit group in the default tmp_dh_cb ssl: ensure that SSL option flags are non-negative ssl: update OpenSSL::SSL::OP_* flags ssl: prefer TLS_method() over SSLv23_method() ssl: add SSLContext#min_version= and #max_version= ssl: rework SSLContext#ssl_version= test/test_x509name: change script encoding to ASCII-8BIT x509name: refactor OpenSSL::X509::Name#to_s x509name: add OpenSSL::X509::Name#to_utf8 x509name: add OpenSSL::X509::Name#inspect x509name: update regexp in OpenSSL::X509::Name.parse Ruby/OpenSSL 2.1.0.beta1 Marcus Stollsteimer (1): Fix rdoc for core Integer class nobu (4): [DOC] {read,write}_nonblock with exception: false [DOC] keyword argument _exception_ [DOC] mark up literals Revert r57690 except for read_nonblock git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59734 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ext/openssl/History.md31
-rw-r--r--ext/openssl/depend134
-rw-r--r--ext/openssl/deprecation.rb3
-rw-r--r--ext/openssl/extconf.rb48
-rw-r--r--ext/openssl/lib/openssl.rb1
-rw-r--r--ext/openssl/lib/openssl/bn.rb3
-rw-r--r--ext/openssl/lib/openssl/buffering.rb38
-rw-r--r--ext/openssl/lib/openssl/config.rb23
-rw-r--r--ext/openssl/lib/openssl/digest.rb9
-rw-r--r--ext/openssl/lib/openssl/pkcs5.rb22
-rw-r--r--ext/openssl/lib/openssl/pkey.rb41
-rw-r--r--ext/openssl/lib/openssl/ssl.rb134
-rw-r--r--ext/openssl/lib/openssl/x509.rb8
-rw-r--r--ext/openssl/openssl.gemspec12
-rw-r--r--ext/openssl/openssl_missing.c67
-rw-r--r--ext/openssl/openssl_missing.h49
-rw-r--r--ext/openssl/ossl.c195
-rw-r--r--ext/openssl/ossl.h41
-rw-r--r--ext/openssl/ossl_asn1.c660
-rw-r--r--ext/openssl/ossl_asn1.h4
-rw-r--r--ext/openssl/ossl_bio.c25
-rw-r--r--ext/openssl/ossl_bio.h2
-rw-r--r--ext/openssl/ossl_bn.c96
-rw-r--r--ext/openssl/ossl_cipher.c68
-rw-r--r--ext/openssl/ossl_cipher.h2
-rw-r--r--ext/openssl/ossl_digest.c20
-rw-r--r--ext/openssl/ossl_digest.h2
-rw-r--r--ext/openssl/ossl_engine.c94
-rw-r--r--ext/openssl/ossl_hmac.c41
-rw-r--r--ext/openssl/ossl_kdf.c221
-rw-r--r--ext/openssl/ossl_kdf.h6
-rw-r--r--ext/openssl/ossl_ns_spki.c14
-rw-r--r--ext/openssl/ossl_ocsp.c165
-rw-r--r--ext/openssl/ossl_pkcs12.c35
-rw-r--r--ext/openssl/ossl_pkcs5.c180
-rw-r--r--ext/openssl/ossl_pkcs5.h6
-rw-r--r--ext/openssl/ossl_pkcs7.c28
-rw-r--r--ext/openssl/ossl_pkey.c34
-rw-r--r--ext/openssl/ossl_pkey.h4
-rw-r--r--ext/openssl/ossl_pkey_dh.c22
-rw-r--r--ext/openssl/ossl_pkey_dsa.c38
-rw-r--r--ext/openssl/ossl_pkey_ec.c98
-rw-r--r--ext/openssl/ossl_pkey_rsa.c38
-rw-r--r--ext/openssl/ossl_rand.c24
-rw-r--r--ext/openssl/ossl_ssl.c506
-rw-r--r--ext/openssl/ossl_ssl.h5
-rw-r--r--ext/openssl/ossl_ssl_session.c16
-rw-r--r--ext/openssl/ossl_version.h2
-rw-r--r--ext/openssl/ossl_x509.c15
-rw-r--r--ext/openssl/ossl_x509.h7
-rw-r--r--ext/openssl/ossl_x509attr.c10
-rw-r--r--ext/openssl/ossl_x509cert.c56
-rw-r--r--ext/openssl/ossl_x509crl.c35
-rw-r--r--ext/openssl/ossl_x509ext.c22
-rw-r--r--ext/openssl/ossl_x509name.c138
-rw-r--r--ext/openssl/ossl_x509req.c45
-rw-r--r--ext/openssl/ossl_x509revoked.c16
-rw-r--r--ext/openssl/ossl_x509store.c59
-rw-r--r--ext/openssl/ruby_missing.h5
-rw-r--r--test/openssl/fixtures/pkey/dh1024.pem5
-rw-r--r--test/openssl/fixtures/pkey/dsa1024.pem12
-rw-r--r--test/openssl/fixtures/pkey/dsa256.pem8
-rw-r--r--test/openssl/fixtures/pkey/dsa512.pem8
-rw-r--r--test/openssl/fixtures/pkey/p256.pem5
-rw-r--r--test/openssl/fixtures/pkey/rsa1024.pem15
-rw-r--r--test/openssl/fixtures/pkey/rsa2048.pem27
-rw-r--r--test/openssl/test_asn1.rb636
-rw-r--r--test/openssl/test_bn.rb319
-rw-r--r--test/openssl/test_buffering.rb7
-rw-r--r--test/openssl/test_cipher.rb17
-rw-r--r--test/openssl/test_config.rb12
-rw-r--r--test/openssl/test_digest.rb67
-rw-r--r--test/openssl/test_engine.rb6
-rw-r--r--test/openssl/test_fips.rb12
-rw-r--r--test/openssl/test_hmac.rb6
-rw-r--r--test/openssl/test_kdf.rb141
-rw-r--r--test/openssl/test_ns_spki.rb6
-rw-r--r--test/openssl/test_ocsp.rb27
-rw-r--r--test/openssl/test_pair.rb133
-rw-r--r--test/openssl/test_pkcs12.rb46
-rw-r--r--test/openssl/test_pkcs5.rb98
-rw-r--r--test/openssl/test_pkcs7.rb10
-rw-r--r--test/openssl/test_pkey_dh.rb39
-rw-r--r--test/openssl/test_pkey_dsa.rb66
-rw-r--r--test/openssl/test_pkey_ec.rb61
-rw-r--r--test/openssl/test_pkey_rsa.rb78
-rw-r--r--test/openssl/test_random.rb6
-rw-r--r--test/openssl/test_ssl.rb694
-rw-r--r--test/openssl/test_ssl_session.rb405
-rw-r--r--test/openssl/test_x509attr.rb2
-rw-r--r--test/openssl/test_x509cert.rb40
-rw-r--r--test/openssl/test_x509crl.rb20
-rw-r--r--test/openssl/test_x509ext.rb2
-rw-r--r--test/openssl/test_x509name.rb111
-rw-r--r--test/openssl/test_x509req.rb26
-rw-r--r--test/openssl/test_x509store.rb34
-rw-r--r--test/openssl/ut_eof.rb4
-rw-r--r--test/openssl/utils.rb474
98 files changed, 3895 insertions, 3513 deletions
diff --git a/ext/openssl/History.md b/ext/openssl/History.md
index 8baa0208ea..6e4baeb3be 100644
--- a/ext/openssl/History.md
+++ b/ext/openssl/History.md
@@ -1,3 +1,34 @@
+Version 2.1.0.beta1
+===================
+
+Notable changes
+---------------
+
+* Support for OpenSSL versions before 1.0.1 is removed.
+ [[GitHub #86]](https://github.com/ruby/openssl/pull/86)
+* OpenSSL::BN#negative?, #+@, and #-@ are added.
+* OpenSSL::SSL::SSLSocket#connect raises a more informative exception when
+ certificate verification fails.
+ [[GitHub #99]](https://github.com/ruby/openssl/pull/99)
+* OpenSSL::KDF module is newly added. Support for scrypt is added.
+ [[GitHub #109]](https://github.com/ruby/openssl/pull/109)
+* OpenSSL.fips_mode is added. We have had the setter, but not the getter.
+ [[GitHub #125]](https://github.com/ruby/openssl/pull/125)
+* OpenSSL::OCSP::Request#signed? is added.
+* OpenSSL::ASN1 handles the indefinite length form better. OpenSSL::ASN1.decode
+ no longer wrongly treats the end-of-contents octets as part of the content.
+ OpenSSL::ASN1::ASN1Data#infinite_length is renamed to #indefinite_length.
+ [[GitHub #98]](https://github.com/ruby/openssl/pull/98)
+* OpenSSL::X509::Name#add_entry now accepts two additional keyword arguments
+ 'loc' and 'set'.
+ [[GitHub #94]](https://github.com/ruby/openssl/issues/94)
+* OpenSSL::SSL::SSLContext#min_version= and #max_version= are added.
+ [[GitHub #142]](https://github.com/ruby/openssl/pull/142)
+* OpenSSL::X509::Name#to_utf8 is added.
+ [[GitHub #26]](https://github.com/ruby/openssl/issues/26)
+ [[GitHub #143]](https://github.com/ruby/openssl/pull/143)
+
+
Version 2.0.5
=============
diff --git a/ext/openssl/depend b/ext/openssl/depend
index 4e98617954..021c6d99a8 100644
--- a/ext/openssl/depend
+++ b/ext/openssl/depend
@@ -30,10 +30,10 @@ ossl.o: ossl_config.h
ossl.o: ossl_digest.h
ossl.o: ossl_engine.h
ossl.o: ossl_hmac.h
+ossl.o: ossl_kdf.h
ossl.o: ossl_ns_spki.h
ossl.o: ossl_ocsp.h
ossl.o: ossl_pkcs12.h
-ossl.o: ossl_pkcs5.h
ossl.o: ossl_pkcs7.h
ossl.o: ossl_pkey.h
ossl.o: ossl_rand.h
@@ -67,10 +67,10 @@ ossl_asn1.o: ossl_config.h
ossl_asn1.o: ossl_digest.h
ossl_asn1.o: ossl_engine.h
ossl_asn1.o: ossl_hmac.h
+ossl_asn1.o: ossl_kdf.h
ossl_asn1.o: ossl_ns_spki.h
ossl_asn1.o: ossl_ocsp.h
ossl_asn1.o: ossl_pkcs12.h
-ossl_asn1.o: ossl_pkcs5.h
ossl_asn1.o: ossl_pkcs7.h
ossl_asn1.o: ossl_pkey.h
ossl_asn1.o: ossl_rand.h
@@ -104,10 +104,10 @@ ossl_bio.o: ossl_config.h
ossl_bio.o: ossl_digest.h
ossl_bio.o: ossl_engine.h
ossl_bio.o: ossl_hmac.h
+ossl_bio.o: ossl_kdf.h
ossl_bio.o: ossl_ns_spki.h
ossl_bio.o: ossl_ocsp.h
ossl_bio.o: ossl_pkcs12.h
-ossl_bio.o: ossl_pkcs5.h
ossl_bio.o: ossl_pkcs7.h
ossl_bio.o: ossl_pkey.h
ossl_bio.o: ossl_rand.h
@@ -141,10 +141,10 @@ ossl_bn.o: ossl_config.h
ossl_bn.o: ossl_digest.h
ossl_bn.o: ossl_engine.h
ossl_bn.o: ossl_hmac.h
+ossl_bn.o: ossl_kdf.h
ossl_bn.o: ossl_ns_spki.h
ossl_bn.o: ossl_ocsp.h
ossl_bn.o: ossl_pkcs12.h
-ossl_bn.o: ossl_pkcs5.h
ossl_bn.o: ossl_pkcs7.h
ossl_bn.o: ossl_pkey.h
ossl_bn.o: ossl_rand.h
@@ -178,10 +178,10 @@ ossl_cipher.o: ossl_config.h
ossl_cipher.o: ossl_digest.h
ossl_cipher.o: ossl_engine.h
ossl_cipher.o: ossl_hmac.h
+ossl_cipher.o: ossl_kdf.h
ossl_cipher.o: ossl_ns_spki.h
ossl_cipher.o: ossl_ocsp.h
ossl_cipher.o: ossl_pkcs12.h
-ossl_cipher.o: ossl_pkcs5.h
ossl_cipher.o: ossl_pkcs7.h
ossl_cipher.o: ossl_pkey.h
ossl_cipher.o: ossl_rand.h
@@ -215,10 +215,10 @@ ossl_config.o: ossl_config.h
ossl_config.o: ossl_digest.h
ossl_config.o: ossl_engine.h
ossl_config.o: ossl_hmac.h
+ossl_config.o: ossl_kdf.h
ossl_config.o: ossl_ns_spki.h
ossl_config.o: ossl_ocsp.h
ossl_config.o: ossl_pkcs12.h
-ossl_config.o: ossl_pkcs5.h
ossl_config.o: ossl_pkcs7.h
ossl_config.o: ossl_pkey.h
ossl_config.o: ossl_rand.h
@@ -252,10 +252,10 @@ ossl_digest.o: ossl_digest.c
ossl_digest.o: ossl_digest.h
ossl_digest.o: ossl_engine.h
ossl_digest.o: ossl_hmac.h
+ossl_digest.o: ossl_kdf.h
ossl_digest.o: ossl_ns_spki.h
ossl_digest.o: ossl_ocsp.h
ossl_digest.o: ossl_pkcs12.h
-ossl_digest.o: ossl_pkcs5.h
ossl_digest.o: ossl_pkcs7.h
ossl_digest.o: ossl_pkey.h
ossl_digest.o: ossl_rand.h
@@ -289,10 +289,10 @@ ossl_engine.o: ossl_digest.h
ossl_engine.o: ossl_engine.c
ossl_engine.o: ossl_engine.h
ossl_engine.o: ossl_hmac.h
+ossl_engine.o: ossl_kdf.h
ossl_engine.o: ossl_ns_spki.h
ossl_engine.o: ossl_ocsp.h
ossl_engine.o: ossl_pkcs12.h
-ossl_engine.o: ossl_pkcs5.h
ossl_engine.o: ossl_pkcs7.h
ossl_engine.o: ossl_pkey.h
ossl_engine.o: ossl_rand.h
@@ -326,10 +326,10 @@ ossl_hmac.o: ossl_digest.h
ossl_hmac.o: ossl_engine.h
ossl_hmac.o: ossl_hmac.c
ossl_hmac.o: ossl_hmac.h
+ossl_hmac.o: ossl_kdf.h
ossl_hmac.o: ossl_ns_spki.h
ossl_hmac.o: ossl_ocsp.h
ossl_hmac.o: ossl_pkcs12.h
-ossl_hmac.o: ossl_pkcs5.h
ossl_hmac.o: ossl_pkcs7.h
ossl_hmac.o: ossl_pkey.h
ossl_hmac.o: ossl_rand.h
@@ -337,6 +337,43 @@ ossl_hmac.o: ossl_ssl.h
ossl_hmac.o: ossl_version.h
ossl_hmac.o: ossl_x509.h
ossl_hmac.o: ruby_missing.h
+ossl_kdf.o: $(RUBY_EXTCONF_H)
+ossl_kdf.o: $(arch_hdrdir)/ruby/config.h
+ossl_kdf.o: $(hdrdir)/ruby/backward.h
+ossl_kdf.o: $(hdrdir)/ruby/defines.h
+ossl_kdf.o: $(hdrdir)/ruby/encoding.h
+ossl_kdf.o: $(hdrdir)/ruby/intern.h
+ossl_kdf.o: $(hdrdir)/ruby/io.h
+ossl_kdf.o: $(hdrdir)/ruby/missing.h
+ossl_kdf.o: $(hdrdir)/ruby/onigmo.h
+ossl_kdf.o: $(hdrdir)/ruby/oniguruma.h
+ossl_kdf.o: $(hdrdir)/ruby/ruby.h
+ossl_kdf.o: $(hdrdir)/ruby/st.h
+ossl_kdf.o: $(hdrdir)/ruby/subst.h
+ossl_kdf.o: $(hdrdir)/ruby/thread.h
+ossl_kdf.o: $(top_srcdir)/include/ruby.h
+ossl_kdf.o: openssl_missing.h
+ossl_kdf.o: ossl.h
+ossl_kdf.o: ossl_asn1.h
+ossl_kdf.o: ossl_bio.h
+ossl_kdf.o: ossl_bn.h
+ossl_kdf.o: ossl_cipher.h
+ossl_kdf.o: ossl_config.h
+ossl_kdf.o: ossl_digest.h
+ossl_kdf.o: ossl_engine.h
+ossl_kdf.o: ossl_hmac.h
+ossl_kdf.o: ossl_kdf.c
+ossl_kdf.o: ossl_kdf.h
+ossl_kdf.o: ossl_ns_spki.h
+ossl_kdf.o: ossl_ocsp.h
+ossl_kdf.o: ossl_pkcs12.h
+ossl_kdf.o: ossl_pkcs7.h
+ossl_kdf.o: ossl_pkey.h
+ossl_kdf.o: ossl_rand.h
+ossl_kdf.o: ossl_ssl.h
+ossl_kdf.o: ossl_version.h
+ossl_kdf.o: ossl_x509.h
+ossl_kdf.o: ruby_missing.h
ossl_ns_spki.o: $(RUBY_EXTCONF_H)
ossl_ns_spki.o: $(arch_hdrdir)/ruby/config.h
ossl_ns_spki.o: $(hdrdir)/ruby/backward.h
@@ -362,11 +399,11 @@ ossl_ns_spki.o: ossl_config.h
ossl_ns_spki.o: ossl_digest.h
ossl_ns_spki.o: ossl_engine.h
ossl_ns_spki.o: ossl_hmac.h
+ossl_ns_spki.o: ossl_kdf.h
ossl_ns_spki.o: ossl_ns_spki.c
ossl_ns_spki.o: ossl_ns_spki.h
ossl_ns_spki.o: ossl_ocsp.h
ossl_ns_spki.o: ossl_pkcs12.h
-ossl_ns_spki.o: ossl_pkcs5.h
ossl_ns_spki.o: ossl_pkcs7.h
ossl_ns_spki.o: ossl_pkey.h
ossl_ns_spki.o: ossl_rand.h
@@ -399,11 +436,11 @@ ossl_ocsp.o: ossl_config.h
ossl_ocsp.o: ossl_digest.h
ossl_ocsp.o: ossl_engine.h
ossl_ocsp.o: ossl_hmac.h
+ossl_ocsp.o: ossl_kdf.h
ossl_ocsp.o: ossl_ns_spki.h
ossl_ocsp.o: ossl_ocsp.c
ossl_ocsp.o: ossl_ocsp.h
ossl_ocsp.o: ossl_pkcs12.h
-ossl_ocsp.o: ossl_pkcs5.h
ossl_ocsp.o: ossl_pkcs7.h
ossl_ocsp.o: ossl_pkey.h
ossl_ocsp.o: ossl_rand.h
@@ -436,11 +473,11 @@ ossl_pkcs12.o: ossl_config.h
ossl_pkcs12.o: ossl_digest.h
ossl_pkcs12.o: ossl_engine.h
ossl_pkcs12.o: ossl_hmac.h
+ossl_pkcs12.o: ossl_kdf.h
ossl_pkcs12.o: ossl_ns_spki.h
ossl_pkcs12.o: ossl_ocsp.h
ossl_pkcs12.o: ossl_pkcs12.c
ossl_pkcs12.o: ossl_pkcs12.h
-ossl_pkcs12.o: ossl_pkcs5.h
ossl_pkcs12.o: ossl_pkcs7.h
ossl_pkcs12.o: ossl_pkey.h
ossl_pkcs12.o: ossl_rand.h
@@ -448,43 +485,6 @@ ossl_pkcs12.o: ossl_ssl.h
ossl_pkcs12.o: ossl_version.h
ossl_pkcs12.o: ossl_x509.h
ossl_pkcs12.o: ruby_missing.h
-ossl_pkcs5.o: $(RUBY_EXTCONF_H)
-ossl_pkcs5.o: $(arch_hdrdir)/ruby/config.h
-ossl_pkcs5.o: $(hdrdir)/ruby/backward.h
-ossl_pkcs5.o: $(hdrdir)/ruby/defines.h
-ossl_pkcs5.o: $(hdrdir)/ruby/encoding.h
-ossl_pkcs5.o: $(hdrdir)/ruby/intern.h
-ossl_pkcs5.o: $(hdrdir)/ruby/io.h
-ossl_pkcs5.o: $(hdrdir)/ruby/missing.h
-ossl_pkcs5.o: $(hdrdir)/ruby/onigmo.h
-ossl_pkcs5.o: $(hdrdir)/ruby/oniguruma.h
-ossl_pkcs5.o: $(hdrdir)/ruby/ruby.h
-ossl_pkcs5.o: $(hdrdir)/ruby/st.h
-ossl_pkcs5.o: $(hdrdir)/ruby/subst.h
-ossl_pkcs5.o: $(hdrdir)/ruby/thread.h
-ossl_pkcs5.o: $(top_srcdir)/include/ruby.h
-ossl_pkcs5.o: openssl_missing.h
-ossl_pkcs5.o: ossl.h
-ossl_pkcs5.o: ossl_asn1.h
-ossl_pkcs5.o: ossl_bio.h
-ossl_pkcs5.o: ossl_bn.h
-ossl_pkcs5.o: ossl_cipher.h
-ossl_pkcs5.o: ossl_config.h
-ossl_pkcs5.o: ossl_digest.h
-ossl_pkcs5.o: ossl_engine.h
-ossl_pkcs5.o: ossl_hmac.h
-ossl_pkcs5.o: ossl_ns_spki.h
-ossl_pkcs5.o: ossl_ocsp.h
-ossl_pkcs5.o: ossl_pkcs12.h
-ossl_pkcs5.o: ossl_pkcs5.c
-ossl_pkcs5.o: ossl_pkcs5.h
-ossl_pkcs5.o: ossl_pkcs7.h
-ossl_pkcs5.o: ossl_pkey.h
-ossl_pkcs5.o: ossl_rand.h
-ossl_pkcs5.o: ossl_ssl.h
-ossl_pkcs5.o: ossl_version.h
-ossl_pkcs5.o: ossl_x509.h
-ossl_pkcs5.o: ruby_missing.h
ossl_pkcs7.o: $(RUBY_EXTCONF_H)
ossl_pkcs7.o: $(arch_hdrdir)/ruby/config.h
ossl_pkcs7.o: $(hdrdir)/ruby/backward.h
@@ -510,10 +510,10 @@ ossl_pkcs7.o: ossl_config.h
ossl_pkcs7.o: ossl_digest.h
ossl_pkcs7.o: ossl_engine.h
ossl_pkcs7.o: ossl_hmac.h
+ossl_pkcs7.o: ossl_kdf.h
ossl_pkcs7.o: ossl_ns_spki.h
ossl_pkcs7.o: ossl_ocsp.h
ossl_pkcs7.o: ossl_pkcs12.h
-ossl_pkcs7.o: ossl_pkcs5.h
ossl_pkcs7.o: ossl_pkcs7.c
ossl_pkcs7.o: ossl_pkcs7.h
ossl_pkcs7.o: ossl_pkey.h
@@ -547,10 +547,10 @@ ossl_pkey.o: ossl_config.h
ossl_pkey.o: ossl_digest.h
ossl_pkey.o: ossl_engine.h
ossl_pkey.o: ossl_hmac.h
+ossl_pkey.o: ossl_kdf.h
ossl_pkey.o: ossl_ns_spki.h
ossl_pkey.o: ossl_ocsp.h
ossl_pkey.o: ossl_pkcs12.h
-ossl_pkey.o: ossl_pkcs5.h
ossl_pkey.o: ossl_pkcs7.h
ossl_pkey.o: ossl_pkey.c
ossl_pkey.o: ossl_pkey.h
@@ -584,10 +584,10 @@ ossl_pkey_dh.o: ossl_config.h
ossl_pkey_dh.o: ossl_digest.h
ossl_pkey_dh.o: ossl_engine.h
ossl_pkey_dh.o: ossl_hmac.h
+ossl_pkey_dh.o: ossl_kdf.h
ossl_pkey_dh.o: ossl_ns_spki.h
ossl_pkey_dh.o: ossl_ocsp.h
ossl_pkey_dh.o: ossl_pkcs12.h
-ossl_pkey_dh.o: ossl_pkcs5.h
ossl_pkey_dh.o: ossl_pkcs7.h
ossl_pkey_dh.o: ossl_pkey.h
ossl_pkey_dh.o: ossl_pkey_dh.c
@@ -621,10 +621,10 @@ ossl_pkey_dsa.o: ossl_config.h
ossl_pkey_dsa.o: ossl_digest.h
ossl_pkey_dsa.o: ossl_engine.h
ossl_pkey_dsa.o: ossl_hmac.h
+ossl_pkey_dsa.o: ossl_kdf.h
ossl_pkey_dsa.o: ossl_ns_spki.h
ossl_pkey_dsa.o: ossl_ocsp.h
ossl_pkey_dsa.o: ossl_pkcs12.h
-ossl_pkey_dsa.o: ossl_pkcs5.h
ossl_pkey_dsa.o: ossl_pkcs7.h
ossl_pkey_dsa.o: ossl_pkey.h
ossl_pkey_dsa.o: ossl_pkey_dsa.c
@@ -658,10 +658,10 @@ ossl_pkey_ec.o: ossl_config.h
ossl_pkey_ec.o: ossl_digest.h
ossl_pkey_ec.o: ossl_engine.h
ossl_pkey_ec.o: ossl_hmac.h
+ossl_pkey_ec.o: ossl_kdf.h
ossl_pkey_ec.o: ossl_ns_spki.h
ossl_pkey_ec.o: ossl_ocsp.h
ossl_pkey_ec.o: ossl_pkcs12.h
-ossl_pkey_ec.o: ossl_pkcs5.h
ossl_pkey_ec.o: ossl_pkcs7.h
ossl_pkey_ec.o: ossl_pkey.h
ossl_pkey_ec.o: ossl_pkey_ec.c
@@ -695,10 +695,10 @@ ossl_pkey_rsa.o: ossl_config.h
ossl_pkey_rsa.o: ossl_digest.h
ossl_pkey_rsa.o: ossl_engine.h
ossl_pkey_rsa.o: ossl_hmac.h
+ossl_pkey_rsa.o: ossl_kdf.h
ossl_pkey_rsa.o: ossl_ns_spki.h
ossl_pkey_rsa.o: ossl_ocsp.h
ossl_pkey_rsa.o: ossl_pkcs12.h
-ossl_pkey_rsa.o: ossl_pkcs5.h
ossl_pkey_rsa.o: ossl_pkcs7.h
ossl_pkey_rsa.o: ossl_pkey.h
ossl_pkey_rsa.o: ossl_pkey_rsa.c
@@ -732,10 +732,10 @@ ossl_rand.o: ossl_config.h
ossl_rand.o: ossl_digest.h
ossl_rand.o: ossl_engine.h
ossl_rand.o: ossl_hmac.h
+ossl_rand.o: ossl_kdf.h
ossl_rand.o: ossl_ns_spki.h
ossl_rand.o: ossl_ocsp.h
ossl_rand.o: ossl_pkcs12.h
-ossl_rand.o: ossl_pkcs5.h
ossl_rand.o: ossl_pkcs7.h
ossl_rand.o: ossl_pkey.h
ossl_rand.o: ossl_rand.c
@@ -769,10 +769,10 @@ ossl_ssl.o: ossl_config.h
ossl_ssl.o: ossl_digest.h
ossl_ssl.o: ossl_engine.h
ossl_ssl.o: ossl_hmac.h
+ossl_ssl.o: ossl_kdf.h
ossl_ssl.o: ossl_ns_spki.h
ossl_ssl.o: ossl_ocsp.h
ossl_ssl.o: ossl_pkcs12.h
-ossl_ssl.o: ossl_pkcs5.h
ossl_ssl.o: ossl_pkcs7.h
ossl_ssl.o: ossl_pkey.h
ossl_ssl.o: ossl_rand.h
@@ -806,10 +806,10 @@ ossl_ssl_session.o: ossl_config.h
ossl_ssl_session.o: ossl_digest.h
ossl_ssl_session.o: ossl_engine.h
ossl_ssl_session.o: ossl_hmac.h
+ossl_ssl_session.o: ossl_kdf.h
ossl_ssl_session.o: ossl_ns_spki.h
ossl_ssl_session.o: ossl_ocsp.h
ossl_ssl_session.o: ossl_pkcs12.h
-ossl_ssl_session.o: ossl_pkcs5.h
ossl_ssl_session.o: ossl_pkcs7.h
ossl_ssl_session.o: ossl_pkey.h
ossl_ssl_session.o: ossl_rand.h
@@ -843,10 +843,10 @@ ossl_x509.o: ossl_config.h
ossl_x509.o: ossl_digest.h
ossl_x509.o: ossl_engine.h
ossl_x509.o: ossl_hmac.h
+ossl_x509.o: ossl_kdf.h
ossl_x509.o: ossl_ns_spki.h
ossl_x509.o: ossl_ocsp.h
ossl_x509.o: ossl_pkcs12.h
-ossl_x509.o: ossl_pkcs5.h
ossl_x509.o: ossl_pkcs7.h
ossl_x509.o: ossl_pkey.h
ossl_x509.o: ossl_rand.h
@@ -880,10 +880,10 @@ ossl_x509attr.o: ossl_config.h
ossl_x509attr.o: ossl_digest.h
ossl_x509attr.o: ossl_engine.h
ossl_x509attr.o: ossl_hmac.h
+ossl_x509attr.o: ossl_kdf.h
ossl_x509attr.o: ossl_ns_spki.h
ossl_x509attr.o: ossl_ocsp.h
ossl_x509attr.o: ossl_pkcs12.h
-ossl_x509attr.o: ossl_pkcs5.h
ossl_x509attr.o: ossl_pkcs7.h
ossl_x509attr.o: ossl_pkey.h
ossl_x509attr.o: ossl_rand.h
@@ -917,10 +917,10 @@ ossl_x509cert.o: ossl_config.h
ossl_x509cert.o: ossl_digest.h
ossl_x509cert.o: ossl_engine.h
ossl_x509cert.o: ossl_hmac.h
+ossl_x509cert.o: ossl_kdf.h
ossl_x509cert.o: ossl_ns_spki.h
ossl_x509cert.o: ossl_ocsp.h
ossl_x509cert.o: ossl_pkcs12.h
-ossl_x509cert.o: ossl_pkcs5.h
ossl_x509cert.o: ossl_pkcs7.h
ossl_x509cert.o: ossl_pkey.h
ossl_x509cert.o: ossl_rand.h
@@ -954,10 +954,10 @@ ossl_x509crl.o: ossl_config.h
ossl_x509crl.o: ossl_digest.h
ossl_x509crl.o: ossl_engine.h
ossl_x509crl.o: ossl_hmac.h
+ossl_x509crl.o: ossl_kdf.h
ossl_x509crl.o: ossl_ns_spki.h
ossl_x509crl.o: ossl_ocsp.h
ossl_x509crl.o: ossl_pkcs12.h
-ossl_x509crl.o: ossl_pkcs5.h
ossl_x509crl.o: ossl_pkcs7.h
ossl_x509crl.o: ossl_pkey.h
ossl_x509crl.o: ossl_rand.h
@@ -991,10 +991,10 @@ ossl_x509ext.o: ossl_config.h
ossl_x509ext.o: ossl_digest.h
ossl_x509ext.o: ossl_engine.h
ossl_x509ext.o: ossl_hmac.h
+ossl_x509ext.o: ossl_kdf.h
ossl_x509ext.o: ossl_ns_spki.h
ossl_x509ext.o: ossl_ocsp.h
ossl_x509ext.o: ossl_pkcs12.h
-ossl_x509ext.o: ossl_pkcs5.h
ossl_x509ext.o: ossl_pkcs7.h
ossl_x509ext.o: ossl_pkey.h
ossl_x509ext.o: ossl_rand.h
@@ -1028,10 +1028,10 @@ ossl_x509name.o: ossl_config.h
ossl_x509name.o: ossl_digest.h
ossl_x509name.o: ossl_engine.h
ossl_x509name.o: ossl_hmac.h
+ossl_x509name.o: ossl_kdf.h
ossl_x509name.o: ossl_ns_spki.h
ossl_x509name.o: ossl_ocsp.h
ossl_x509name.o: ossl_pkcs12.h
-ossl_x509name.o: ossl_pkcs5.h
ossl_x509name.o: ossl_pkcs7.h
ossl_x509name.o: ossl_pkey.h
ossl_x509name.o: ossl_rand.h
@@ -1065,10 +1065,10 @@ ossl_x509req.o: ossl_config.h
ossl_x509req.o: ossl_digest.h
ossl_x509req.o: ossl_engine.h
ossl_x509req.o: ossl_hmac.h
+ossl_x509req.o: ossl_kdf.h
ossl_x509req.o: ossl_ns_spki.h
ossl_x509req.o: ossl_ocsp.h
ossl_x509req.o: ossl_pkcs12.h
-ossl_x509req.o: ossl_pkcs5.h
ossl_x509req.o: ossl_pkcs7.h
ossl_x509req.o: ossl_pkey.h
ossl_x509req.o: ossl_rand.h
@@ -1102,10 +1102,10 @@ ossl_x509revoked.o: ossl_config.h
ossl_x509revoked.o: ossl_digest.h
ossl_x509revoked.o: ossl_engine.h
ossl_x509revoked.o: ossl_hmac.h
+ossl_x509revoked.o: ossl_kdf.h
ossl_x509revoked.o: ossl_ns_spki.h
ossl_x509revoked.o: ossl_ocsp.h
ossl_x509revoked.o: ossl_pkcs12.h
-ossl_x509revoked.o: ossl_pkcs5.h
ossl_x509revoked.o: ossl_pkcs7.h
ossl_x509revoked.o: ossl_pkey.h
ossl_x509revoked.o: ossl_rand.h
@@ -1139,10 +1139,10 @@ ossl_x509store.o: ossl_config.h
ossl_x509store.o: ossl_digest.h
ossl_x509store.o: ossl_engine.h
ossl_x509store.o: ossl_hmac.h
+ossl_x509store.o: ossl_kdf.h
ossl_x509store.o: ossl_ns_spki.h
ossl_x509store.o: ossl_ocsp.h
ossl_x509store.o: ossl_pkcs12.h
-ossl_x509store.o: ossl_pkcs5.h
ossl_x509store.o: ossl_pkcs7.h
ossl_x509store.o: ossl_pkey.h
ossl_x509store.o: ossl_rand.h
diff --git a/ext/openssl/deprecation.rb b/ext/openssl/deprecation.rb
index 0c3ab6287e..1d51d065a9 100644
--- a/ext/openssl/deprecation.rb
+++ b/ext/openssl/deprecation.rb
@@ -3,9 +3,6 @@ module OpenSSL
def self.deprecated_warning_flag
unless flag = (@deprecated_warning_flag ||= nil)
if try_compile("", flag = "-Werror=deprecated-declarations")
- if /darwin/ =~ RUBY_PLATFORM and with_config("broken-apple-openssl")
- flag = "-Wno-deprecated-declarations"
- end
$warnflags << " #{flag}"
else
flag = ""
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
index 75da65cde3..5212903b9a 100644
--- a/ext/openssl/extconf.rb
+++ b/ext/openssl/extconf.rb
@@ -91,30 +91,19 @@ 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"
- exit 1
+ 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
end
-result = checking_for("OpenSSL version is 0.9.8 or later") {
- try_static_assert("OPENSSL_VERSION_NUMBER >= 0x00908000L", "openssl/opensslv.h")
-}
-unless result
- raise "OpenSSL 0.9.8 or later required."
-end
-
-if /darwin/ =~ RUBY_PLATFORM and !OpenSSL.check_func("SSL_library_init()", "openssl/ssl.h")
- raise "Ignore OpenSSL broken by Apple.\nPlease use another openssl. (e.g. using `configure --with-openssl-dir=/path/to/openssl')"
+unless checking_for("OpenSSL version is 1.0.1 or later") {
+ try_static_assert("OPENSSL_VERSION_NUMBER >= 0x10001000L", "openssl/opensslv.h") }
+ raise "OpenSSL >= 1.0.1 or LibreSSL is required"
end
Logging::message "=== Checking for OpenSSL features... ===\n"
# compile options
-
-# SSLv2 and SSLv3 may be removed in future versions of OpenSSL, and even macros
-# like OPENSSL_NO_SSL2 may not be defined.
-have_func("SSLv2_method")
-have_func("SSLv3_method")
-have_func("TLSv1_1_method")
-have_func("TLSv1_2_method")
have_func("RAND_egd")
engines = %w{builtin_engines openbsd_dev_crypto dynamic 4758cca aep atalla chil
cswift nuron sureware ubsec padlock capi gmp gost cryptodev aesni}
@@ -122,30 +111,6 @@ engines.each { |name|
OpenSSL.check_func_or_macro("ENGINE_load_#{name}", "openssl/engine.h")
}
-# added in 0.9.8X
-have_func("EVP_CIPHER_CTX_new")
-have_func("EVP_CIPHER_CTX_free")
-OpenSSL.check_func_or_macro("SSL_CTX_clear_options", "openssl/ssl.h")
-
-# added in 1.0.0
-have_func("ASN1_TIME_adj")
-have_func("EVP_CIPHER_CTX_copy")
-have_func("EVP_PKEY_base_id")
-have_func("HMAC_CTX_copy")
-have_func("PKCS5_PBKDF2_HMAC")
-have_func("X509_NAME_hash_old")
-have_func("X509_STORE_CTX_get0_current_crl")
-have_func("X509_STORE_set_verify_cb")
-have_func("i2d_ASN1_SET_ANY")
-have_func("SSL_SESSION_cmp") # removed
-OpenSSL.check_func_or_macro("SSL_set_tlsext_host_name", "openssl/ssl.h")
-have_struct_member("CRYPTO_THREADID", "ptr", "openssl/crypto.h")
-have_func("EVP_PKEY_get0")
-
-# added in 1.0.1
-have_func("SSL_CTX_set_next_proto_select_cb")
-have_macro("EVP_CTRL_GCM_GET_TAG", ['openssl/evp.h']) && $defs.push("-DHAVE_AUTHENTICATED_ENCRYPTION")
-
# added in 1.0.2
have_func("EC_curve_nist2nid")
have_func("X509_REVOKED_dup")
@@ -189,6 +154,7 @@ OpenSSL.check_func_or_macro("SSL_CTX_set_min_proto_version", "openssl/ssl.h")
have_func("SSL_CTX_get_security_level")
have_func("X509_get0_notBefore")
have_func("SSL_SESSION_get_protocol_version")
+have_func("EVP_PBE_scrypt")
Logging::message "=== Checking done. ===\n"
diff --git a/ext/openssl/lib/openssl.rb b/ext/openssl/lib/openssl.rb
index 26d167a9b4..0914282920 100644
--- a/ext/openssl/lib/openssl.rb
+++ b/ext/openssl/lib/openssl.rb
@@ -19,3 +19,4 @@ require 'openssl/config'
require 'openssl/digest'
require 'openssl/x509'
require 'openssl/ssl'
+require 'openssl/pkcs5'
diff --git a/ext/openssl/lib/openssl/bn.rb b/ext/openssl/lib/openssl/bn.rb
index 6d6c96e42d..8d1ebefb6e 100644
--- a/ext/openssl/lib/openssl/bn.rb
+++ b/ext/openssl/lib/openssl/bn.rb
@@ -27,8 +27,9 @@ module OpenSSL
end # OpenSSL
##
+#--
# Add double dispatch to Integer
-#
+#++
class Integer
# Casts an Integer as an OpenSSL::BN
#
diff --git a/ext/openssl/lib/openssl/buffering.rb b/ext/openssl/lib/openssl/buffering.rb
index d773637c0e..8b5dd9da57 100644
--- a/ext/openssl/lib/openssl/buffering.rb
+++ b/ext/openssl/lib/openssl/buffering.rb
@@ -63,7 +63,7 @@ module OpenSSL::Buffering
end
##
- # Consumes +size+ bytes from the buffer
+ # Consumes _size_ bytes from the buffer
def consume_rbuff(size=nil)
if @rbuffer.empty?
@@ -79,7 +79,7 @@ module OpenSSL::Buffering
public
##
- # Reads +size+ bytes from the stream. If +buf+ is provided it must
+ # Reads _size_ bytes from the stream. If _buf_ is provided it must
# reference a string which will receive the data.
#
# See IO#read for full details.
@@ -106,7 +106,7 @@ module OpenSSL::Buffering
end
##
- # Reads at most +maxlen+ bytes from the stream. If +buf+ is provided it
+ # Reads at most _maxlen_ bytes from the stream. If _buf_ is provided it
# must reference a string which will receive the data.
#
# See IO#readpartial for full details.
@@ -136,7 +136,7 @@ module OpenSSL::Buffering
end
##
- # Reads at most +maxlen+ bytes in the non-blocking manner.
+ # Reads at most _maxlen_ bytes in the non-blocking manner.
#
# When no data can be read without blocking it raises
# OpenSSL::SSL::SSLError extended by IO::WaitReadable or IO::WaitWritable.
@@ -190,11 +190,11 @@ module OpenSSL::Buffering
end
##
- # Reads the next "line" from the stream. Lines are separated by +eol+. If
- # +limit+ is provided the result will not be longer than the given number of
+ # Reads the next "line" from the stream. Lines are separated by _eol_. If
+ # _limit_ is provided the result will not be longer than the given number of
# bytes.
#
- # +eol+ may be a String or Regexp.
+ # _eol_ may be a String or Regexp.
#
# Unlike IO#gets the line read will not be assigned to +$_+.
#
@@ -220,7 +220,7 @@ module OpenSSL::Buffering
##
# Executes the block for every line in the stream where lines are separated
- # by +eol+.
+ # by _eol_.
#
# See also #gets
@@ -232,7 +232,7 @@ module OpenSSL::Buffering
alias each_line each
##
- # Reads lines from the stream which are separated by +eol+.
+ # Reads lines from the stream which are separated by _eol_.
#
# See also #gets
@@ -245,7 +245,7 @@ module OpenSSL::Buffering
end
##
- # Reads a line from the stream which is separated by +eol+.
+ # Reads a line from the stream which is separated by _eol_.
#
# Raises EOFError if at end of file.
@@ -281,7 +281,7 @@ module OpenSSL::Buffering
end
##
- # Pushes character +c+ back onto the stream such that a subsequent buffered
+ # Pushes character _c_ back onto the stream such that a subsequent buffered
# character read will return it.
#
# Unlike IO#getc multiple bytes may be pushed back onto the stream.
@@ -308,7 +308,7 @@ module OpenSSL::Buffering
private
##
- # Writes +s+ to the buffer. When the buffer is full or #sync is true the
+ # Writes _s_ to the buffer. When the buffer is full or #sync is true the
# buffer is flushed to the underlying socket.
def do_write(s)
@@ -336,8 +336,8 @@ module OpenSSL::Buffering
public
##
- # Writes +s+ to the stream. If the argument is not a string it will be
- # converted using String#to_s. Returns the number of bytes written.
+ # Writes _s_ to the stream. If the argument is not a String it will be
+ # converted using +.to_s+ method. Returns the number of bytes written.
def write(s)
do_write(s)
@@ -345,7 +345,7 @@ module OpenSSL::Buffering
end
##
- # Writes +s+ in the non-blocking manner.
+ # Writes _s_ in the non-blocking manner.
#
# If there is buffered data, it is flushed first. This may block.
#
@@ -387,8 +387,8 @@ module OpenSSL::Buffering
end
##
- # Writes +s+ to the stream. +s+ will be converted to a String using
- # String#to_s.
+ # Writes _s_ to the stream. _s_ will be converted to a String using
+ # +.to_s+ method.
def <<(s)
do_write(s)
@@ -396,7 +396,7 @@ module OpenSSL::Buffering
end
##
- # Writes +args+ to the stream along with a record separator.
+ # Writes _args_ to the stream along with a record separator.
#
# See IO#puts for full details.
@@ -416,7 +416,7 @@ module OpenSSL::Buffering
end
##
- # Writes +args+ to the stream.
+ # Writes _args_ to the stream.
#
# See IO#print for full details.
diff --git a/ext/openssl/lib/openssl/config.rb b/ext/openssl/lib/openssl/config.rb
index 8822545192..48d8be0069 100644
--- a/ext/openssl/lib/openssl/config.rb
+++ b/ext/openssl/lib/openssl/config.rb
@@ -30,7 +30,8 @@ module OpenSSL
class << self
##
- # Parses a given +string+ as a blob that contains configuration for openssl.
+ # Parses a given _string_ as a blob that contains configuration for
+ # OpenSSL.
#
# If the source of the IO is a file, then consider using #parse_config.
def parse(string)
@@ -46,7 +47,7 @@ module OpenSSL
alias load new
##
- # Parses the configuration data read from +io+, see also #parse.
+ # Parses the configuration data read from _io_, see also #parse.
#
# Raises a ConfigError on invalid configuration data.
def parse_config(io)
@@ -236,7 +237,7 @@ module OpenSSL
#
# This can be used in contexts like OpenSSL::X509::ExtensionFactory.config=
#
- # If the optional +filename+ parameter is provided, then it is read in and
+ # If the optional _filename_ parameter is provided, then it is read in and
# parsed via #parse_config.
#
# This can raise IO exceptions based on the access, or availability of the
@@ -255,7 +256,7 @@ module OpenSSL
end
##
- # Gets the value of +key+ from the given +section+
+ # Gets the value of _key_ from the given _section_
#
# Given the following configurating file being loaded:
#
@@ -265,8 +266,8 @@ module OpenSSL
# #=> [ default ]
# # foo=bar
#
- # You can get a specific value from the config if you know the +section+
- # and +key+ like so:
+ # You can get a specific value from the config if you know the _section_
+ # and _key_ like so:
#
# config.get_value('default','foo')
# #=> "bar"
@@ -297,7 +298,7 @@ module OpenSSL
end
##
- # Set the target +key+ with a given +value+ under a specific +section+.
+ # Set the target _key_ with a given _value_ under a specific _section_.
#
# Given the following configurating file being loaded:
#
@@ -307,7 +308,7 @@ module OpenSSL
# #=> [ default ]
# # foo=bar
#
- # You can set the value of +foo+ under the +default+ section to a new
+ # You can set the value of _foo_ under the _default_ section to a new
# value:
#
# config.add_value('default', 'foo', 'buzz')
@@ -322,7 +323,7 @@ module OpenSSL
end
##
- # Get a specific +section+ from the current configuration
+ # Get a specific _section_ from the current configuration
#
# Given the following configurating file being loaded:
#
@@ -351,7 +352,7 @@ module OpenSSL
end
##
- # Sets a specific +section+ name with a Hash +pairs+
+ # Sets a specific _section_ name with a Hash _pairs_.
#
# Given the following configuration being created:
#
@@ -365,7 +366,7 @@ module OpenSSL
# # baz=buz
#
# It's important to note that this will essentially merge any of the keys
- # in +pairs+ with the existing +section+. For example:
+ # in _pairs_ with the existing _section_. For example:
#
# config['default']
# #=> {"foo"=>"bar", "baz"=>"buz"}
diff --git a/ext/openssl/lib/openssl/digest.rb b/ext/openssl/lib/openssl/digest.rb
index 97ccbc9569..b6744de6bd 100644
--- a/ext/openssl/lib/openssl/digest.rb
+++ b/ext/openssl/lib/openssl/digest.rb
@@ -15,15 +15,12 @@
module OpenSSL
class Digest
- alg = %w(MD2 MD4 MD5 MDC2 RIPEMD160 SHA1)
+ alg = %w(MD2 MD4 MD5 MDC2 RIPEMD160 SHA1 SHA224 SHA256 SHA384 SHA512)
if OPENSSL_VERSION_NUMBER < 0x10100000
alg += %w(DSS DSS1 SHA)
end
- if OPENSSL_VERSION_NUMBER > 0x00908000
- alg += %w(SHA224 SHA256 SHA384 SHA512)
- end
- # Return the +data+ hash computed with +name+ Digest. +name+ is either the
+ # Return the hash value computed with _name_ Digest. _name_ is either the
# long name or short name of a supported digest algorithm.
#
# === Examples
@@ -59,7 +56,7 @@ module OpenSSL
end # Digest
- # Returns a Digest subclass by +name+.
+ # Returns a Digest subclass by _name_
#
# require 'openssl'
#
diff --git a/ext/openssl/lib/openssl/pkcs5.rb b/ext/openssl/lib/openssl/pkcs5.rb
new file mode 100644
index 0000000000..959447df5e
--- /dev/null
+++ b/ext/openssl/lib/openssl/pkcs5.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: false
+#--
+# Ruby/OpenSSL Project
+# Copyright (C) 2017 Ruby/OpenSSL Project Authors
+#++
+
+module OpenSSL
+ module PKCS5
+ module_function
+
+ # OpenSSL::PKCS5.pbkdf2_hmac has been renamed to OpenSSL::KDF.pbkdf2_hmac.
+ # This method is provided for backwards compatibility.
+ def pbkdf2_hmac(pass, salt, iter, keylen, digest)
+ OpenSSL::KDF.pbkdf2_hmac(pass, salt: salt, iterations: iter,
+ length: keylen, hash: digest)
+ end
+
+ def pbkdf2_hmac_sha1(pass, salt, iter, keylen)
+ pbkdf2_hmac(pass, salt, iter, keylen, "sha1")
+ end
+ end
+end
diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb
index 9af5f781f9..dcedd849a0 100644
--- a/ext/openssl/lib/openssl/pkey.rb
+++ b/ext/openssl/lib/openssl/pkey.rb
@@ -1,44 +1,3 @@
# frozen_string_literal: false
module OpenSSL
- module PKey
- if defined?(OpenSSL::PKey::DH)
-
- class DH
- # :nodoc:
- DEFAULT_1024 = new <<-_end_of_pem_
------BEGIN DH PARAMETERS-----
-MIGHAoGBAJ0lOVy0VIr/JebWn0zDwY2h+rqITFOpdNr6ugsgvkDXuucdcChhYExJ
-AV/ZD2AWPbrTqV76mGRgJg4EddgT1zG0jq3rnFdMj2XzkBYx3BVvfR0Arnby0RHR
-T4h7KZ/2zmjvV+eF8kBUHBJAojUlzxKj4QeO2x20FP9X5xmNUXeDAgEC
------END DH PARAMETERS-----
- _end_of_pem_
-
- # :nodoc:
- DEFAULT_2048 = new <<-_end_of_pem_
------BEGIN DH PARAMETERS-----
-MIIBCAKCAQEA7E6kBrYiyvmKAMzQ7i8WvwVk9Y/+f8S7sCTN712KkK3cqd1jhJDY
-JbrYeNV3kUIKhPxWHhObHKpD1R84UpL+s2b55+iMd6GmL7OYmNIT/FccKhTcveab
-VBmZT86BZKYyf45hUF9FOuUM9xPzuK3Vd8oJQvfYMCd7LPC0taAEljQLR4Edf8E6
-YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
-1bNveX5wInh5GDx1FGhKBZ+s1H+aedudCm7sCgRwv8lKWYGiHzObSma8A86KG+MD
-7Lo5JquQ3DlBodj3IDyPrxIv96lvRPFtAwIBAg==
------END DH PARAMETERS-----
- _end_of_pem_
- end
-
- # :nodoc:
- DEFAULT_TMP_DH_CALLBACK = lambda { |ctx, is_export, keylen|
- warn "using default DH parameters." if $VERBOSE
- case keylen
- when 1024 then OpenSSL::PKey::DH::DEFAULT_1024
- when 2048 then OpenSSL::PKey::DH::DEFAULT_2048
- else
- nil
- end
- }
-
- else
- DEFAULT_TMP_DH_CALLBACK = nil
- end
- end
end
diff --git a/ext/openssl/lib/openssl/ssl.rb b/ext/openssl/lib/openssl/ssl.rb
index f40a451439..a628648e71 100644
--- a/ext/openssl/lib/openssl/ssl.rb
+++ b/ext/openssl/lib/openssl/ssl.rb
@@ -17,18 +17,36 @@ module OpenSSL
module SSL
class SSLContext
DEFAULT_PARAMS = { # :nodoc:
- :ssl_version => "SSLv23",
+ :min_version => OpenSSL::SSL::TLS1_VERSION,
:verify_mode => OpenSSL::SSL::VERIFY_PEER,
:verify_hostname => true,
:options => -> {
opts = OpenSSL::SSL::OP_ALL
opts &= ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS
- opts |= OpenSSL::SSL::OP_NO_COMPRESSION if defined?(OpenSSL::SSL::OP_NO_COMPRESSION)
- opts |= OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3
+ opts |= OpenSSL::SSL::OP_NO_COMPRESSION
opts
}.call
}
+ if defined?(OpenSSL::PKey::DH)
+ DEFAULT_2048 = OpenSSL::PKey::DH.new <<-_end_of_pem_
+-----BEGIN DH PARAMETERS-----
+MIIBCAKCAQEA7E6kBrYiyvmKAMzQ7i8WvwVk9Y/+f8S7sCTN712KkK3cqd1jhJDY
+JbrYeNV3kUIKhPxWHhObHKpD1R84UpL+s2b55+iMd6GmL7OYmNIT/FccKhTcveab
+VBmZT86BZKYyf45hUF9FOuUM9xPzuK3Vd8oJQvfYMCd7LPC0taAEljQLR4Edf8E6
+YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
+1bNveX5wInh5GDx1FGhKBZ+s1H+aedudCm7sCgRwv8lKWYGiHzObSma8A86KG+MD
+7Lo5JquQ3DlBodj3IDyPrxIv96lvRPFtAwIBAg==
+-----END DH PARAMETERS-----
+ _end_of_pem_
+ private_constant :DEFAULT_2048
+
+ DEFAULT_TMP_DH_CALLBACK = lambda { |ctx, is_export, keylen| # :nodoc:
+ warn "using default DH parameters." if $VERBOSE
+ DEFAULT_2048
+ }
+ end
+
if !(OpenSSL::OPENSSL_VERSION.start_with?("OpenSSL") &&
OpenSSL::OPENSSL_VERSION_NUMBER >= 0x10100000)
DEFAULT_PARAMS.merge!(
@@ -87,14 +105,18 @@ module OpenSSL
#
# The callback is invoked with an SSLSocket and a server name. The
# callback must return an SSLContext for the server name or nil.
- attr_accessor :servername_cb if ExtConfig::HAVE_TLSEXT_HOST_NAME
+ attr_accessor :servername_cb
# call-seq:
- # SSLContext.new => ctx
- # SSLContext.new(:TLSv1) => ctx
- # SSLContext.new("SSLv23_client") => ctx
+ # SSLContext.new -> ctx
+ # SSLContext.new(:TLSv1) -> ctx
+ # SSLContext.new("SSLv23") -> ctx
#
- # You can get a list of valid methods with OpenSSL::SSL::SSLContext::METHODS
+ # Creates a new SSL context.
+ #
+ # If an argument is given, #ssl_version= is called with the value. Note
+ # that this form is deprecated. New applications should use #min_version=
+ # and #max_version= as necessary.
def initialize(version = nil)
self.options |= OpenSSL::SSL::OP_ALL
self.ssl_version = version if version
@@ -106,8 +128,8 @@ module OpenSSL
#
# Sets saner defaults optimized for the use with HTTP-like protocols.
#
- # If a Hash +params+ is given, the parameters are overridden with it.
- # The keys in +params+ must be assignment methods on SSLContext.
+ # If a Hash _params_ is given, the parameters are overridden with it.
+ # The keys in _params_ must be assignment methods on SSLContext.
#
# If the verify_mode is not VERIFY_NONE and ca_file, ca_path and
# cert_store are not set then the system default certificate store is
@@ -122,6 +144,88 @@ module OpenSSL
end
return params
end
+
+ # call-seq:
+ # ctx.min_version = OpenSSL::SSL::TLS1_2_VERSION
+ # ctx.min_version = :TLS1_2
+ # ctx.min_version = nil
+ #
+ # Sets the lower bound on the supported SSL/TLS protocol version. The
+ # version may be specified by an integer constant named
+ # OpenSSL::SSL::*_VERSION, a Symbol, or +nil+ which means "any version".
+ #
+ # Be careful that you don't overwrite OpenSSL::SSL::OP_NO_{SSL,TLS}v*
+ # options by #options= once you have called #min_version= or
+ # #max_version=.
+ #
+ # === Example
+ # ctx = OpenSSL::SSL::SSLContext.new
+ # ctx.min_version = OpenSSL::SSL::TLS1_1_VERSION
+ # ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
+ #
+ # sock = OpenSSL::SSL::SSLSocket.new(tcp_sock, ctx)
+ # sock.connect # Initiates a connection using either TLS 1.1 or TLS 1.2
+ def min_version=(version)
+ set_minmax_proto_version(version, @max_proto_version ||= nil)
+ @min_proto_version = version
+ end
+
+ # call-seq:
+ # ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
+ # ctx.max_version = :TLS1_2
+ # ctx.max_version = nil
+ #
+ # Sets the upper bound of the supported SSL/TLS protocol version. See
+ # #min_version= for the possible values.
+ def max_version=(version)
+ set_minmax_proto_version(@min_proto_version ||= nil, version)
+ @max_proto_version = version
+ end
+
+ # call-seq:
+ # ctx.ssl_version = :TLSv1
+ # ctx.ssl_version = "SSLv23"
+ #
+ # Sets the SSL/TLS protocol version for the context. This forces
+ # connections to use only the specified protocol version. This is
+ # deprecated and only provided for backwards compatibility. Use
+ # #min_version= and #max_version= instead.
+ #
+ # === History
+ # As the name hints, this used to call the SSL_CTX_set_ssl_version()
+ # function which sets the SSL method used for connections created from
+ # the context. As of Ruby/OpenSSL 2.1, this accessor method is
+ # implemented to call #min_version= and #max_version= instead.
+ def ssl_version=(meth)
+ meth = meth.to_s if meth.is_a?(Symbol)
+ if /(?<type>_client|_server)\z/ =~ meth
+ meth = $`
+ if $VERBOSE
+ warn "#{caller(1)[0]}: method type #{type.inspect} is ignored"
+ end
+ end
+ version = METHODS_MAP[meth.intern] or
+ raise ArgumentError, "unknown SSL method `%s'" % meth
+ set_minmax_proto_version(version, version)
+ @min_proto_version = @max_proto_version = version
+ end
+
+ METHODS_MAP = {
+ SSLv23: 0,
+ SSLv2: OpenSSL::SSL::SSL2_VERSION,
+ SSLv3: OpenSSL::SSL::SSL3_VERSION,
+ TLSv1: OpenSSL::SSL::TLS1_VERSION,
+ TLSv1_1: OpenSSL::SSL::TLS1_1_VERSION,
+ TLSv1_2: OpenSSL::SSL::TLS1_2_VERSION,
+ }.freeze
+ private_constant :METHODS_MAP
+
+ # The list of available SSL/TLS methods. This constant is only provided
+ # for backwards compatibility.
+ METHODS = METHODS_MAP.flat_map { |name,|
+ [name, :"#{name}_client", :"#{name}_server"]
+ }.freeze
+ deprecate_constant :METHODS
end
module SocketForwarder
@@ -242,9 +346,7 @@ module OpenSSL
include Buffering
include SocketForwarder
- if ExtConfig::HAVE_TLSEXT_HOST_NAME
- attr_reader :hostname
- end
+ attr_reader :hostname
# The underlying IO object.
attr_reader :io
@@ -317,7 +419,7 @@ module OpenSSL
end
def tmp_dh_callback
- @context.tmp_dh_callback || OpenSSL::PKey::DEFAULT_TMP_DH_CALLBACK
+ @context.tmp_dh_callback || OpenSSL::SSL::SSLContext::DEFAULT_TMP_DH_CALLBACK
end
def tmp_ecdh_callback
@@ -341,8 +443,8 @@ module OpenSSL
attr_accessor :start_immediately
# Creates a new instance of SSLServer.
- # * +srv+ is an instance of TCPServer.
- # * +ctx+ is an instance of OpenSSL::SSL::SSLContext.
+ # * _srv_ is an instance of TCPServer.
+ # * _ctx_ is an instance of OpenSSL::SSL::SSLContext.
def initialize(svr, ctx)
@svr = svr
@ctx = ctx
diff --git a/ext/openssl/lib/openssl/x509.rb b/ext/openssl/lib/openssl/x509.rb
index aef3456e0f..6d31b98c68 100644
--- a/ext/openssl/lib/openssl/x509.rb
+++ b/ext/openssl/lib/openssl/x509.rb
@@ -139,7 +139,13 @@ module OpenSSL
end
def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE)
- ary = str.scan(/\s*([^\/,]+)\s*/).collect{|i| i[0].split("=", 2) }
+ if str.start_with?("/")
+ # /A=B/C=D format
+ ary = str[1..-1].split("/").map { |i| i.split("=", 2) }
+ else
+ # Comma-separated
+ ary = str.split(",").map { |i| i.strip.split("=", 2) }
+ end
self.new(ary, template)
end
diff --git a/ext/openssl/openssl.gemspec b/ext/openssl/openssl.gemspec
index 7cbbfeb513..2c2e300bb9 100644
--- a/ext/openssl/openssl.gemspec
+++ b/ext/openssl/openssl.gemspec
@@ -1,26 +1,26 @@
# -*- encoding: utf-8 -*-
-# stub: openssl 2.0.5 ruby lib
+# stub: openssl 2.1.0.beta1 ruby lib
# stub: ext/openssl/extconf.rb
Gem::Specification.new do |s|
s.name = "openssl".freeze
- s.version = "2.0.5"
+ s.version = "2.1.0.beta1"
- s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
+ s.required_rubygems_version = Gem::Requirement.new("> 1.3.1".freeze) if s.respond_to? :required_rubygems_version=
s.metadata = { "msys2_mingw_dependencies" => "openssl" } if s.respond_to? :metadata=
s.require_paths = ["lib".freeze]
s.authors = ["Martin Bosslet".freeze, "SHIBATA Hiroshi".freeze, "Zachary Scott".freeze, "Kazuki Yamaguchi".freeze]
- s.date = "2017-08-08"
+ s.date = "2017-09-03"
s.description = "It wraps the OpenSSL library.".freeze
s.email = ["ruby-core@ruby-lang.org".freeze]
s.extensions = ["ext/openssl/extconf.rb".freeze]
s.extra_rdoc_files = ["CONTRIBUTING.md".freeze, "README.md".freeze, "History.md".freeze]
- s.files = ["BSDL".freeze, "CONTRIBUTING.md".freeze, "History.md".freeze, "LICENSE.txt".freeze, "README.md".freeze, "ext/openssl/deprecation.rb".freeze, "ext/openssl/extconf.rb".freeze, "ext/openssl/openssl_missing.c".freeze, "ext/openssl/openssl_missing.h".freeze, "ext/openssl/ossl.c".freeze, "ext/openssl/ossl.h".freeze, "ext/openssl/ossl_asn1.c".freeze, "ext/openssl/ossl_asn1.h".freeze, "ext/openssl/ossl_bio.c".freeze, "ext/openssl/ossl_bio.h".freeze, "ext/openssl/ossl_bn.c".freeze, "ext/openssl/ossl_bn.h".freeze, "ext/openssl/ossl_cipher.c".freeze, "ext/openssl/ossl_cipher.h".freeze, "ext/openssl/ossl_config.c".freeze, "ext/openssl/ossl_config.h".freeze, "ext/openssl/ossl_digest.c".freeze, "ext/openssl/ossl_digest.h".freeze, "ext/openssl/ossl_engine.c".freeze, "ext/openssl/ossl_engine.h".freeze, "ext/openssl/ossl_hmac.c".freeze, "ext/openssl/ossl_hmac.h".freeze, "ext/openssl/ossl_ns_spki.c".freeze, "ext/openssl/ossl_ns_spki.h".freeze, "ext/openssl/ossl_ocsp.c".freeze, "ext/openssl/ossl_ocsp.h".freeze, "ext/openssl/ossl_pkcs12.c".freeze, "ext/openssl/ossl_pkcs12.h".freeze, "ext/openssl/ossl_pkcs5.c".freeze, "ext/openssl/ossl_pkcs5.h".freeze, "ext/openssl/ossl_pkcs7.c".freeze, "ext/openssl/ossl_pkcs7.h".freeze, "ext/openssl/ossl_pkey.c".freeze, "ext/openssl/ossl_pkey.h".freeze, "ext/openssl/ossl_pkey_dh.c".freeze, "ext/openssl/ossl_pkey_dsa.c".freeze, "ext/openssl/ossl_pkey_ec.c".freeze, "ext/openssl/ossl_pkey_rsa.c".freeze, "ext/openssl/ossl_rand.c".freeze, "ext/openssl/ossl_rand.h".freeze, "ext/openssl/ossl_ssl.c".freeze, "ext/openssl/ossl_ssl.h".freeze, "ext/openssl/ossl_ssl_session.c".freeze, "ext/openssl/ossl_version.h".freeze, "ext/openssl/ossl_x509.c".freeze, "ext/openssl/ossl_x509.h".freeze, "ext/openssl/ossl_x509attr.c".freeze, "ext/openssl/ossl_x509cert.c".freeze, "ext/openssl/ossl_x509crl.c".freeze, "ext/openssl/ossl_x509ext.c".freeze, "ext/openssl/ossl_x509name.c".freeze, "ext/openssl/ossl_x509req.c".freeze, "ext/openssl/ossl_x509revoked.c".freeze, "ext/openssl/ossl_x509store.c".freeze, "ext/openssl/ruby_missing.h".freeze, "lib/openssl.rb".freeze, "lib/openssl/bn.rb".freeze, "lib/openssl/buffering.rb".freeze, "lib/openssl/cipher.rb".freeze, "lib/openssl/config.rb".freeze, "lib/openssl/digest.rb".freeze, "lib/openssl/pkey.rb".freeze, "lib/openssl/ssl.rb".freeze, "lib/openssl/x509.rb".freeze]
+ s.files = ["BSDL".freeze, "CONTRIBUTING.md".freeze, "History.md".freeze, "LICENSE.txt".freeze, "README.md".freeze, "ext/openssl/deprecation.rb".freeze, "ext/openssl/extconf.rb".freeze, "ext/openssl/openssl_missing.c".freeze, "ext/openssl/openssl_missing.h".freeze, "ext/openssl/ossl.c".freeze, "ext/openssl/ossl.h".freeze, "ext/openssl/ossl_asn1.c".freeze, "ext/openssl/ossl_asn1.h".freeze, "ext/openssl/ossl_bio.c".freeze, "ext/openssl/ossl_bio.h".freeze, "ext/openssl/ossl_bn.c".freeze, "ext/openssl/ossl_bn.h".freeze, "ext/openssl/ossl_cipher.c".freeze, "ext/openssl/ossl_cipher.h".freeze, "ext/openssl/ossl_config.c".freeze, "ext/openssl/ossl_config.h".freeze, "ext/openssl/ossl_digest.c".freeze, "ext/openssl/ossl_digest.h".freeze, "ext/openssl/ossl_engine.c".freeze, "ext/openssl/ossl_engine.h".freeze, "ext/openssl/ossl_hmac.c".freeze, "ext/openssl/ossl_hmac.h".freeze, "ext/openssl/ossl_kdf.c".freeze, "ext/openssl/ossl_kdf.h".freeze, "ext/openssl/ossl_ns_spki.c".freeze, "ext/openssl/ossl_ns_spki.h".freeze, "ext/openssl/ossl_ocsp.c".freeze, "ext/openssl/ossl_ocsp.h".freeze, "ext/openssl/ossl_pkcs12.c".freeze, "ext/openssl/ossl_pkcs12.h".freeze, "ext/openssl/ossl_pkcs7.c".freeze, "ext/openssl/ossl_pkcs7.h".freeze, "ext/openssl/ossl_pkey.c".freeze, "ext/openssl/ossl_pkey.h".freeze, "ext/openssl/ossl_pkey_dh.c".freeze, "ext/openssl/ossl_pkey_dsa.c".freeze, "ext/openssl/ossl_pkey_ec.c".freeze, "ext/openssl/ossl_pkey_rsa.c".freeze, "ext/openssl/ossl_rand.c".freeze, "ext/openssl/ossl_rand.h".freeze, "ext/openssl/ossl_ssl.c".freeze, "ext/openssl/ossl_ssl.h".freeze, "ext/openssl/ossl_ssl_session.c".freeze, "ext/openssl/ossl_version.h".freeze, "ext/openssl/ossl_x509.c".freeze, "ext/openssl/ossl_x509.h".freeze, "ext/openssl/ossl_x509attr.c".freeze, "ext/openssl/ossl_x509cert.c".freeze, "ext/openssl/ossl_x509crl.c".freeze, "ext/openssl/ossl_x509ext.c".freeze, "ext/openssl/ossl_x509name.c".freeze, "ext/openssl/ossl_x509req.c".freeze, "ext/openssl/ossl_x509revoked.c".freeze, "ext/openssl/ossl_x509store.c".freeze, "ext/openssl/ruby_missing.h".freeze, "lib/openssl.rb".freeze, "lib/openssl/bn.rb".freeze, "lib/openssl/buffering.rb".freeze, "lib/openssl/cipher.rb".freeze, "lib/openssl/config.rb".freeze, "lib/openssl/digest.rb".freeze, "lib/openssl/pkcs5.rb".freeze, "lib/openssl/pkey.rb".freeze, "lib/openssl/ssl.rb".freeze, "lib/openssl/x509.rb".freeze]
s.homepage = "https://www.ruby-lang.org/".freeze
s.licenses = ["Ruby".freeze]
s.rdoc_options = ["--main".freeze, "README.md".freeze]
s.required_ruby_version = Gem::Requirement.new(">= 2.3.0".freeze)
- s.rubygems_version = "2.6.12".freeze
+ s.rubygems_version = "2.6.13".freeze
s.summary = "OpenSSL provides SSL, TLS and general purpose cryptography.".freeze
if s.respond_to? :specification_version then
diff --git a/ext/openssl/openssl_missing.c b/ext/openssl/openssl_missing.c
index 94ce85aff4..b36ef0288e 100644
--- a/ext/openssl/openssl_missing.c
+++ b/ext/openssl/openssl_missing.c
@@ -20,73 +20,6 @@
#include "openssl_missing.h"
-/* added in 0.9.8X */
-#if !defined(HAVE_EVP_CIPHER_CTX_NEW)
-EVP_CIPHER_CTX *
-ossl_EVP_CIPHER_CTX_new(void)
-{
- EVP_CIPHER_CTX *ctx = OPENSSL_malloc(sizeof(EVP_CIPHER_CTX));
- if (!ctx)
- return NULL;
- EVP_CIPHER_CTX_init(ctx);
- return ctx;
-}
-#endif
-
-#if !defined(HAVE_EVP_CIPHER_CTX_FREE)
-void
-ossl_EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
-{
- if (ctx) {
- EVP_CIPHER_CTX_cleanup(ctx);
- OPENSSL_free(ctx);
- }
-}
-#endif
-
-/* added in 1.0.0 */
-#if !defined(HAVE_EVP_CIPHER_CTX_COPY)
-/*
- * this function does not exist in OpenSSL yet... or ever?.
- * a future version may break this function.
- * tested on 0.9.7d.
- */
-int
-ossl_EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
-{
- memcpy(out, in, sizeof(EVP_CIPHER_CTX));
-
-#if !defined(OPENSSL_NO_ENGINE)
- if (in->engine) ENGINE_add(out->engine);
- if (in->cipher_data) {
- out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size);
- memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size);
- }
-#endif
-
- return 1;
-}
-#endif
-
-#if !defined(OPENSSL_NO_HMAC)
-#if !defined(HAVE_HMAC_CTX_COPY)
-int
-ossl_HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in)
-{
- if (!out || !in)
- return 0;
-
- memcpy(out, in, sizeof(HMAC_CTX));
-
- EVP_MD_CTX_copy(&out->md_ctx, &in->md_ctx);
- EVP_MD_CTX_copy(&out->i_ctx, &in->i_ctx);
- EVP_MD_CTX_copy(&out->o_ctx, &in->o_ctx);
-
- return 1;
-}
-#endif /* HAVE_HMAC_CTX_COPY */
-#endif /* NO_HMAC */
-
/* added in 1.0.2 */
#if !defined(OPENSSL_NO_EC)
#if !defined(HAVE_EC_CURVE_NIST2NID)
diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h
index 3d11aec2d2..cc31f6ace7 100644
--- a/ext/openssl/openssl_missing.h
+++ b/ext/openssl/openssl_missing.h
@@ -12,53 +12,6 @@
#include "ruby/config.h"
-/* added in 0.9.8X */
-#if !defined(HAVE_EVP_CIPHER_CTX_NEW)
-EVP_CIPHER_CTX *ossl_EVP_CIPHER_CTX_new(void);
-# define EVP_CIPHER_CTX_new ossl_EVP_CIPHER_CTX_new
-#endif
-
-#if !defined(HAVE_EVP_CIPHER_CTX_FREE)
-void ossl_EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *);
-# define EVP_CIPHER_CTX_free ossl_EVP_CIPHER_CTX_free
-#endif
-
-#if !defined(HAVE_SSL_CTX_CLEAR_OPTIONS)
-# define SSL_CTX_clear_options(ctx, op) ((ctx)->options &= ~(op))
-#endif
-
-/* added in 1.0.0 */
-#if !defined(HAVE_EVP_PKEY_BASE_ID)
-# define EVP_PKEY_base_id(pkey) EVP_PKEY_type((pkey)->type)
-#endif
-
-#if !defined(HAVE_EVP_CIPHER_CTX_COPY)
-int ossl_EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *, const EVP_CIPHER_CTX *);
-# define EVP_CIPHER_CTX_copy ossl_EVP_CIPHER_CTX_copy
-#endif
-
-#if !defined(HAVE_HMAC_CTX_COPY)
-int ossl_HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in);
-# define HMAC_CTX_copy ossl_HMAC_CTX_copy
-#endif
-
-#if !defined(HAVE_X509_STORE_CTX_GET0_CURRENT_CRL)
-# define X509_STORE_CTX_get0_current_crl(x) ((x)->current_crl)
-#endif
-
-#if !defined(HAVE_X509_STORE_SET_VERIFY_CB)
-# define X509_STORE_set_verify_cb X509_STORE_set_verify_cb_func
-#endif
-
-#if !defined(HAVE_I2D_ASN1_SET_ANY)
-# define i2d_ASN1_SET_ANY(sk, x) i2d_ASN1_SET_OF_ASN1_TYPE((sk), (x), \
- i2d_ASN1_TYPE, V_ASN1_SET, V_ASN1_UNIVERSAL, 0)
-#endif
-
-#if !defined(HAVE_EVP_PKEY_GET0)
-# define EVP_PKEY_get0(pk) (pk->pkey.ptr)
-#endif
-
/* added in 1.0.2 */
#if !defined(OPENSSL_NO_EC)
#if !defined(HAVE_EC_CURVE_NIST2NID)
@@ -245,7 +198,7 @@ IMPL_PKEY_GETTER(EC_KEY, ec)
#undef IMPL_KEY_ACCESSOR3
#endif /* HAVE_OPAQUE_OPENSSL */
-#if defined(HAVE_AUTHENTICATED_ENCRYPTION) && !defined(EVP_CTRL_AEAD_GET_TAG)
+#if !defined(EVP_CTRL_AEAD_GET_TAG)
# define EVP_CTRL_AEAD_GET_TAG EVP_CTRL_GCM_GET_TAG
# define EVP_CTRL_AEAD_SET_TAG EVP_CTRL_GCM_SET_TAG
# define EVP_CTRL_AEAD_SET_IVLEN EVP_CTRL_GCM_SET_IVLEN
diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c
index c22966df5a..6ec5e91c66 100644
--- a/ext/openssl/ossl.c
+++ b/ext/openssl/ossl.c
@@ -92,22 +92,40 @@ OSSL_IMPL_SK2ARY(x509crl, X509_CRL)
OSSL_IMPL_SK2ARY(x509name, X509_NAME)
static VALUE
-ossl_str_new(int size)
+ossl_str_new_i(VALUE size)
{
- return rb_str_new(0, size);
+ return rb_str_new(NULL, (long)size);
+}
+
+VALUE
+ossl_str_new(const char *ptr, long len, int *pstate)
+{
+ VALUE str;
+ int state;
+
+ str = rb_protect(ossl_str_new_i, len, &state);
+ if (pstate)
+ *pstate = state;
+ if (state) {
+ if (!pstate)
+ rb_set_errinfo(Qnil);
+ return Qnil;
+ }
+ if (ptr)
+ memcpy(RSTRING_PTR(str), ptr, len);
+ return str;
}
VALUE
ossl_buf2str(char *buf, int len)
{
VALUE str;
- int status = 0;
+ int state;
- str = rb_protect((VALUE (*)(VALUE))ossl_str_new, len, &status);
- if(!NIL_P(str)) memcpy(RSTRING_PTR(str), buf, len);
+ str = ossl_str_new(buf, len, &state);
OPENSSL_free(buf);
- if(status) rb_jump_tag(status);
-
+ if (state)
+ rb_jump_tag(state);
return str;
}
@@ -220,7 +238,7 @@ VALUE eOSSLError;
/*
* Convert to DER string
*/
-ID ossl_s_to_der;
+static ID ossl_s_to_der;
VALUE
ossl_to_der(VALUE obj)
@@ -248,18 +266,15 @@ static VALUE
ossl_make_error(VALUE exc, const char *fmt, va_list args)
{
VALUE str = Qnil;
- const char *msg;
- long e;
+ unsigned long e;
- e = ERR_peek_last_error();
if (fmt) {
str = rb_vsprintf(fmt, args);
}
+ e = ERR_peek_last_error();
if (e) {
- if (dOSSL == Qtrue) /* FULL INFO */
- msg = ERR_error_string(e, NULL);
- else
- msg = ERR_reason_error_string(e);
+ const char *msg = ERR_reason_error_string(e);
+
if (NIL_P(str)) {
if (msg) str = rb_str_new_cstr(msg);
}
@@ -267,8 +282,8 @@ ossl_make_error(VALUE exc, const char *fmt, va_list args)
if (RSTRING_LEN(str)) rb_str_cat2(str, ": ");
rb_str_cat2(str, msg ? msg : "(null)");
}
+ ossl_clear_error();
}
- ossl_clear_error();
if (NIL_P(str)) str = rb_str_new(0, 0);
return rb_exc_new3(exc, str);
@@ -319,7 +334,8 @@ ossl_clear_error(void)
*
* See any remaining errors held in queue.
*
- * Any errors you see here are probably due to a bug in ruby's OpenSSL implementation.
+ * Any errors you see here are probably due to a bug in Ruby's OpenSSL
+ * implementation.
*/
VALUE
ossl_get_errors(void)
@@ -382,6 +398,23 @@ ossl_debug_set(VALUE self, VALUE val)
}
/*
+ * call-seq
+ * OpenSSL.fips_mode -> true | false
+ */
+static VALUE
+ossl_fips_mode_get(VALUE self)
+{
+
+#ifdef OPENSSL_FIPS
+ VALUE enabled;
+ enabled = FIPS_mode() ? Qtrue : Qfalse;
+ return enabled;
+#else
+ return Qfalse;
+#endif
+}
+
+/*
* call-seq:
* OpenSSL.fips_mode = boolean -> boolean
*
@@ -414,6 +447,72 @@ ossl_fips_mode_set(VALUE self, VALUE enabled)
#endif
}
+#if defined(OSSL_DEBUG)
+#if !defined(LIBRESSL_VERSION_NUMBER) && \
+ (OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_NO_CRYPTO_MDEBUG) || \
+ defined(CRYPTO_malloc_debug_init))
+/*
+ * call-seq:
+ * OpenSSL.mem_check_start -> nil
+ *
+ * Calls CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON). Starts tracking memory
+ * allocations. See also OpenSSL.print_mem_leaks.
+ *
+ * This is available only when built with a capable OpenSSL and --enable-debug
+ * configure option.
+ */
+static VALUE
+mem_check_start(VALUE self)
+{
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * OpenSSL.print_mem_leaks -> true | false
+ *
+ * For debugging the Ruby/OpenSSL library. Calls CRYPTO_mem_leaks_fp(stderr).
+ * Prints detected memory leaks to standard error. This cleans the global state
+ * up thus you cannot use any methods of the library after calling this.
+ *
+ * Returns +true+ if leaks detected, +false+ otherwise.
+ *
+ * This is available only when built with a capable OpenSSL and --enable-debug
+ * configure option.
+ *
+ * === Example
+ * OpenSSL.mem_check_start
+ * NOT_GCED = OpenSSL::PKey::RSA.new(256)
+ *
+ * END {
+ * GC.start
+ * OpenSSL.print_mem_leaks # will print the leakage
+ * }
+ */
+static VALUE
+print_mem_leaks(VALUE self)
+{
+#if OPENSSL_VERSION_NUMBER >= 0x10100000
+ int ret;
+#endif
+
+ BN_CTX_free(ossl_bn_ctx);
+ ossl_bn_ctx = NULL;
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100000
+ ret = CRYPTO_mem_leaks_fp(stderr);
+ if (ret < 0)
+ ossl_raise(eOSSLError, "CRYPTO_mem_leaks_fp");
+ return ret ? Qfalse : Qtrue;
+#else
+ CRYPTO_mem_leaks_fp(stderr);
+ return Qnil;
+#endif
+}
+#endif
+#endif
+
#if !defined(HAVE_OPENSSL_110_THREADING_API)
/**
* Stores locks needed for OpenSSL thread safety
@@ -461,19 +560,11 @@ ossl_dyn_destroy_callback(struct CRYPTO_dynlock_value *l, const char *file, int
OPENSSL_free(l);
}
-#ifdef HAVE_CRYPTO_THREADID_PTR
static void ossl_threadid_func(CRYPTO_THREADID *id)
{
/* register native thread id */
CRYPTO_THREADID_set_pointer(id, (void *)rb_nativethread_self());
}
-#else
-static unsigned long ossl_thread_id(void)
-{
- /* before OpenSSL 1.0, this is 'unsigned long' */
- return (unsigned long)rb_nativethread_self();
-}
-#endif
static void Init_ossl_locks(void)
{
@@ -491,11 +582,7 @@ static void Init_ossl_locks(void)
rb_nativethread_lock_initialize(&ossl_locks[i]);
}
-#ifdef HAVE_CRYPTO_THREADID_PTR
CRYPTO_THREADID_set_callback(ossl_threadid_func);
-#else
- CRYPTO_set_id_callback(ossl_thread_id);
-#endif
CRYPTO_set_locking_callback(ossl_lock_callback);
CRYPTO_set_dynlock_create_callback(ossl_dyn_create_callback);
CRYPTO_set_dynlock_lock_callback(ossl_dyn_lock_callback);
@@ -505,7 +592,7 @@ static void Init_ossl_locks(void)
/*
* OpenSSL provides SSL, TLS and general purpose cryptography. It wraps the
- * OpenSSL[http://www.openssl.org/] library.
+ * OpenSSL[https://www.openssl.org/] library.
*
* = Examples
*
@@ -1057,7 +1144,7 @@ Init_openssl(void)
rb_define_const(mOSSL, "OPENSSL_VERSION_NUMBER", INT2NUM(OPENSSL_VERSION_NUMBER));
/*
- * Boolean indicating whether OpenSSL is FIPS-enabled or not
+ * Boolean indicating whether OpenSSL is FIPS-capable or not
*/
rb_define_const(mOSSL, "OPENSSL_FIPS",
#ifdef OPENSSL_FIPS
@@ -1067,6 +1154,7 @@ Init_openssl(void)
#endif
);
+ rb_define_module_function(mOSSL, "fips_mode", ossl_fips_mode_get, 0);
rb_define_module_function(mOSSL, "fips_mode=", ossl_fips_mode_set, 1);
/*
@@ -1106,7 +1194,6 @@ Init_openssl(void)
Init_ossl_ns_spki();
Init_ossl_pkcs12();
Init_ossl_pkcs7();
- Init_ossl_pkcs5();
Init_ossl_pkey();
Init_ossl_rand();
Init_ossl_ssl();
@@ -1114,15 +1201,41 @@ Init_openssl(void)
Init_ossl_ocsp();
Init_ossl_engine();
Init_ossl_asn1();
-}
+ Init_ossl_kdf();
#if defined(OSSL_DEBUG)
-/*
- * Check if all symbols are OK with 'make LDSHARED=gcc all'
- */
-int
-main(int argc, char *argv[])
-{
- return 0;
+ /*
+ * For debugging Ruby/OpenSSL. Enable only when built with --enable-debug
+ */
+#if !defined(LIBRESSL_VERSION_NUMBER) && \
+ (OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_NO_CRYPTO_MDEBUG) || \
+ defined(CRYPTO_malloc_debug_init))
+ rb_define_module_function(mOSSL, "mem_check_start", mem_check_start, 0);
+ rb_define_module_function(mOSSL, "print_mem_leaks", print_mem_leaks, 0);
+
+#if defined(CRYPTO_malloc_debug_init) /* <= 1.0.2 */
+ CRYPTO_malloc_debug_init();
+#endif
+
+#if defined(V_CRYPTO_MDEBUG_ALL) /* <= 1.0.2 */
+ CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
+#endif
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000 /* <= 1.0.2 */
+ {
+ int i;
+ /*
+ * See crypto/ex_data.c; call def_get_class() immediately to avoid
+ * allocations. 15 is the maximum number that is used as the class index
+ * in OpenSSL 1.0.2.
+ */
+ for (i = 0; i <= 15; i++) {
+ if (CRYPTO_get_ex_new_index(i, 0, (void *)"ossl-mdebug-dummy", 0, 0, 0) < 0)
+ rb_raise(rb_eRuntimeError, "CRYPTO_get_ex_new_index for "
+ "class index %d failed", i);
+ }
+ }
+#endif
+#endif
+#endif
}
-#endif /* OSSL_DEBUG */
diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h
index 78eddd09b4..f08889b22e 100644
--- a/ext/openssl/ossl.h
+++ b/ext/openssl/ossl.h
@@ -56,29 +56,29 @@ extern VALUE eOSSLError;
}\
} while (0)
-#define OSSL_Check_Instance(obj, klass) do {\
- if (!rb_obj_is_instance_of((obj), (klass))) {\
- ossl_raise(rb_eTypeError, "wrong argument (%"PRIsVALUE")! (Expected instance of %"PRIsVALUE")",\
- rb_obj_class(obj), (klass));\
- }\
-} while (0)
-
-#define OSSL_Check_Same_Class(obj1, obj2) do {\
- if (!rb_obj_is_instance_of((obj1), rb_obj_class(obj2))) {\
- ossl_raise(rb_eTypeError, "wrong argument type");\
- }\
-} while (0)
+/*
+ * Type conversions
+ */
+#if !defined(NUM2UINT64T) /* in case Ruby starts to provide */
+# if SIZEOF_LONG == 8
+# define NUM2UINT64T(x) ((uint64_t)NUM2ULONG(x))
+# elif defined(HAVE_LONG_LONG) && SIZEOF_LONG_LONG == 8
+# define NUM2UINT64T(x) ((uint64_t)NUM2ULL(x))
+# else
+# error "unknown platform; no 64-bit width integer"
+# endif
+#endif
/*
* Data Conversion
*/
-STACK_OF(X509) *ossl_x509_ary2sk0(VALUE);
STACK_OF(X509) *ossl_x509_ary2sk(VALUE);
STACK_OF(X509) *ossl_protect_x509_ary2sk(VALUE,int*);
VALUE ossl_x509_sk2ary(const STACK_OF(X509) *certs);
VALUE ossl_x509crl_sk2ary(const STACK_OF(X509_CRL) *crl);
VALUE ossl_x509name_sk2ary(const STACK_OF(X509_NAME) *names);
VALUE ossl_buf2str(char *buf, int len);
+VALUE ossl_str_new(const char *, long, int *);
#define ossl_str_adjust(str, p) \
do{\
long len = RSTRING_LEN(str);\
@@ -115,7 +115,6 @@ int ossl_pem_passwd_cb(char *, int, int, void *);
/*
* ERRor messages
*/
-#define OSSL_ErrMsg() ERR_reason_error_string(ERR_get_error())
NORETURN(void ossl_raise(VALUE, const char *, ...));
/* Clear OpenSSL error queue. If dOSSL is set, rb_warn() them. */
void ossl_clear_error(void);
@@ -123,7 +122,6 @@ void ossl_clear_error(void);
/*
* String to DER String
*/
-extern ID ossl_s_to_der;
VALUE ossl_to_der(VALUE);
VALUE ossl_to_der_if_possible(VALUE);
@@ -141,20 +139,9 @@ extern VALUE dOSSL;
} \
} while (0)
-#define OSSL_Warning(fmt, ...) do { \
- OSSL_Debug((fmt), ##__VA_ARGS__); \
- rb_warning((fmt), ##__VA_ARGS__); \
-} while (0)
-
-#define OSSL_Warn(fmt, ...) do { \
- OSSL_Debug((fmt), ##__VA_ARGS__); \
- rb_warn((fmt), ##__VA_ARGS__); \
-} while (0)
#else
void ossl_debug(const char *, ...);
#define OSSL_Debug ossl_debug
-#define OSSL_Warning rb_warning
-#define OSSL_Warn rb_warn
#endif
/*
@@ -173,13 +160,13 @@ void ossl_debug(const char *, ...);
#include "ossl_ocsp.h"
#include "ossl_pkcs12.h"
#include "ossl_pkcs7.h"
-#include "ossl_pkcs5.h"
#include "ossl_pkey.h"
#include "ossl_rand.h"
#include "ossl_ssl.h"
#include "ossl_version.h"
#include "ossl_x509.h"
#include "ossl_engine.h"
+#include "ossl_kdf.h"
void Init_openssl(void);
diff --git a/ext/openssl/ossl_asn1.c b/ext/openssl/ossl_asn1.c
index 1d3ee4ac18..efa6b78742 100644
--- a/ext/openssl/ossl_asn1.c
+++ b/ext/openssl/ossl_asn1.c
@@ -9,11 +9,9 @@
*/
#include "ossl.h"
-static VALUE join_der(VALUE enumerable);
static VALUE ossl_asn1_decode0(unsigned char **pp, long length, long *offset,
int depth, int yield, long *num_read);
static VALUE ossl_asn1_initialize(int argc, VALUE *argv, VALUE self);
-static VALUE ossl_asn1eoc_initialize(VALUE self);
/*
* DATE conversion
@@ -25,7 +23,6 @@ asn1time_to_time(const ASN1_TIME *time)
VALUE argv[6];
int count;
- if (!time || !time->data) return Qnil;
memset(&tm, 0, sizeof(struct tm));
switch (time->type) {
@@ -72,7 +69,6 @@ asn1time_to_time(const ASN1_TIME *time)
return rb_funcall2(rb_cTime, rb_intern("utc"), 6, argv);
}
-#if defined(HAVE_ASN1_TIME_ADJ)
void
ossl_time_split(VALUE time, time_t *sec, int *days)
{
@@ -88,13 +84,6 @@ ossl_time_split(VALUE time, time_t *sec, int *days)
*sec = NUM2TIMET(rb_funcall(num, rb_intern("%"), 1, INT2FIX(86400)));
}
}
-#else
-time_t
-time_to_time_t(VALUE time)
-{
- return (time_t)NUM2TIMET(rb_Integer(time));
-}
-#endif
/*
* STRING conversion
@@ -155,13 +144,13 @@ num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai)
#define ossl_asn1_get_tag(o) rb_attr_get((o),sivTAG)
#define ossl_asn1_get_tagging(o) rb_attr_get((o),sivTAGGING)
#define ossl_asn1_get_tag_class(o) rb_attr_get((o),sivTAG_CLASS)
-#define ossl_asn1_get_infinite_length(o) rb_attr_get((o),sivINFINITE_LENGTH)
+#define ossl_asn1_get_indefinite_length(o) rb_attr_get((o),sivINDEFINITE_LENGTH)
#define ossl_asn1_set_value(o,v) rb_ivar_set((o),sivVALUE,(v))
#define ossl_asn1_set_tag(o,v) rb_ivar_set((o),sivTAG,(v))
#define ossl_asn1_set_tagging(o,v) rb_ivar_set((o),sivTAGGING,(v))
#define ossl_asn1_set_tag_class(o,v) rb_ivar_set((o),sivTAG_CLASS,(v))
-#define ossl_asn1_set_infinite_length(o,v) rb_ivar_set((o),sivINFINITE_LENGTH,(v))
+#define ossl_asn1_set_indefinite_length(o,v) rb_ivar_set((o),sivINDEFINITE_LENGTH,(v))
VALUE mASN1;
VALUE eASN1Error;
@@ -187,7 +176,7 @@ VALUE cASN1Sequence, cASN1Set; /* CONSTRUCTIVE */
static VALUE sym_IMPLICIT, sym_EXPLICIT;
static VALUE sym_UNIVERSAL, sym_APPLICATION, sym_CONTEXT_SPECIFIC, sym_PRIVATE;
-static ID sivVALUE, sivTAG, sivTAG_CLASS, sivTAGGING, sivINFINITE_LENGTH, sivUNUSED_BITS;
+static ID sivVALUE, sivTAG, sivTAG_CLASS, sivTAGGING, sivINDEFINITE_LENGTH, sivUNUSED_BITS;
static ID id_each;
/*
@@ -213,13 +202,15 @@ obj_to_asn1bstr(VALUE obj, long unused_bits)
{
ASN1_BIT_STRING *bstr;
- if(unused_bits < 0) unused_bits = 0;
+ if (unused_bits < 0 || unused_bits > 7)
+ ossl_raise(eASN1Error, "unused_bits for a bitstring value must be in "\
+ "the range 0 to 7");
StringValue(obj);
if(!(bstr = ASN1_BIT_STRING_new()))
ossl_raise(eASN1Error, NULL);
ASN1_BIT_STRING_set(bstr, (unsigned char *)RSTRING_PTR(obj), RSTRING_LENINT(obj));
bstr->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
- bstr->flags |= ASN1_STRING_FLAG_BITS_LEFT|(unused_bits&0x07);
+ bstr->flags |= ASN1_STRING_FLAG_BITS_LEFT | unused_bits;
return bstr;
}
@@ -269,15 +260,10 @@ obj_to_asn1utime(VALUE time)
time_t sec;
ASN1_UTCTIME *t;
-#if defined(HAVE_ASN1_TIME_ADJ)
int off_days;
ossl_time_split(time, &sec, &off_days);
if (!(t = ASN1_UTCTIME_adj(NULL, sec, off_days, 0)))
-#else
- sec = time_to_time_t(time);
- if (!(t = ASN1_UTCTIME_set(NULL, sec)))
-#endif
ossl_raise(eASN1Error, NULL);
return t;
@@ -289,15 +275,10 @@ obj_to_asn1gtime(VALUE time)
time_t sec;
ASN1_GENERALIZEDTIME *t;
-#if defined(HAVE_ASN1_TIME_ADJ)
int off_days;
ossl_time_split(time, &sec, &off_days);
if (!(t = ASN1_GENERALIZEDTIME_adj(NULL, sec, off_days, 0)))
-#else
- sec = time_to_time_t(time);
- if (!(t = ASN1_GENERALIZEDTIME_set(NULL, sec)))
-#endif
ossl_raise(eASN1Error, NULL);
return t;
@@ -517,7 +498,7 @@ ossl_asn1_get_asn1type(VALUE obj)
VALUE value, rflag;
void *ptr;
void (*free_func)();
- int tag, flag;
+ int tag;
tag = ossl_asn1_default_tag(obj);
value = ossl_asn1_get_value(obj);
@@ -533,8 +514,7 @@ ossl_asn1_get_asn1type(VALUE obj)
break;
case V_ASN1_BIT_STRING:
rflag = rb_attr_get(obj, sivUNUSED_BITS);
- flag = NIL_P(rflag) ? -1 : NUM2INT(rflag);
- ptr = obj_to_asn1bstr(value, flag);
+ ptr = obj_to_asn1bstr(value, NUM2INT(rflag));
free_func = ASN1_BIT_STRING_free;
break;
case V_ASN1_NULL:
@@ -598,8 +578,8 @@ ossl_asn1_default_tag(VALUE obj)
return NUM2INT(tag);
tmp_class = rb_class_superclass(tmp_class);
}
- ossl_raise(eASN1Error, "universal tag for %"PRIsVALUE" not found",
- rb_obj_class(obj));
+
+ return -1;
}
static int
@@ -615,20 +595,6 @@ ossl_asn1_tag(VALUE obj)
}
static int
-ossl_asn1_is_explicit(VALUE obj)
-{
- VALUE s;
-
- s = ossl_asn1_get_tagging(obj);
- if (NIL_P(s) || s == sym_IMPLICIT)
- return 0;
- else if (s == sym_EXPLICIT)
- return 1;
- else
- ossl_raise(eASN1Error, "invalid tag default");
-}
-
-static int
ossl_asn1_tag_class(VALUE obj)
{
VALUE s;
@@ -663,12 +629,12 @@ ossl_asn1_class2sym(int tc)
* call-seq:
* OpenSSL::ASN1::ASN1Data.new(value, tag, tag_class) => ASN1Data
*
- * +value+: Please have a look at Constructive and Primitive to see how Ruby
+ * _value_: Please have a look at Constructive and Primitive to see how Ruby
* types are mapped to ASN.1 types and vice versa.
*
- * +tag+: A +Number+ indicating the tag number.
+ * _tag_: An Integer indicating the tag number.
*
- * +tag_class+: A +Symbol+ indicating the tag class. Please cf. ASN1 for
+ * _tag_class_: A Symbol indicating the tag class. Please cf. ASN1 for
* possible values.
*
* == Example
@@ -680,73 +646,85 @@ ossl_asn1data_initialize(VALUE self, VALUE value, VALUE tag, VALUE tag_class)
{
if(!SYMBOL_P(tag_class))
ossl_raise(eASN1Error, "invalid tag class");
- if (tag_class == sym_UNIVERSAL && NUM2INT(tag) > 31)
- ossl_raise(eASN1Error, "tag number for Universal too large");
ossl_asn1_set_tag(self, tag);
ossl_asn1_set_value(self, value);
ossl_asn1_set_tag_class(self, tag_class);
- ossl_asn1_set_infinite_length(self, Qfalse);
+ ossl_asn1_set_indefinite_length(self, Qfalse);
return self;
}
static VALUE
-join_der_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, str))
+to_der_internal(VALUE self, int constructed, int indef_len, VALUE body)
{
- i = ossl_to_der_if_possible(i);
- StringValue(i);
- rb_str_append(str, i);
- return Qnil;
-}
+ int encoding = constructed ? indef_len ? 2 : 1 : 0;
+ int tag_class = ossl_asn1_tag_class(self);
+ int tag_number = ossl_asn1_tag(self);
+ int default_tag_number = ossl_asn1_default_tag(self);
+ int body_length, total_length;
+ VALUE str;
+ unsigned char *p;
-static VALUE
-join_der(VALUE enumerable)
-{
- VALUE str = rb_str_new(0, 0);
- rb_block_call(enumerable, id_each, 0, 0, join_der_i, str);
+ body_length = RSTRING_LENINT(body);
+ if (ossl_asn1_get_tagging(self) == sym_EXPLICIT) {
+ int inner_length, e_encoding = indef_len ? 2 : 1;
+
+ if (default_tag_number == -1)
+ ossl_raise(eASN1Error, "explicit tagging of unknown tag");
+
+ inner_length = ASN1_object_size(encoding, body_length, default_tag_number);
+ total_length = ASN1_object_size(e_encoding, inner_length, tag_number);
+ str = rb_str_new(NULL, total_length);
+ p = (unsigned char *)RSTRING_PTR(str);
+ /* Put explicit tag */
+ ASN1_put_object(&p, e_encoding, inner_length, tag_number, tag_class);
+ /* Append inner object */
+ ASN1_put_object(&p, encoding, body_length, default_tag_number, V_ASN1_UNIVERSAL);
+ memcpy(p, RSTRING_PTR(body), body_length);
+ p += body_length;
+ if (indef_len) {
+ ASN1_put_eoc(&p); /* For inner object */
+ ASN1_put_eoc(&p); /* For wrapper object */
+ }
+ }
+ else {
+ total_length = ASN1_object_size(encoding, body_length, tag_number);
+ str = rb_str_new(NULL, total_length);
+ p = (unsigned char *)RSTRING_PTR(str);
+ ASN1_put_object(&p, encoding, body_length, tag_number, tag_class);
+ memcpy(p, RSTRING_PTR(body), body_length);
+ p += body_length;
+ if (indef_len)
+ ASN1_put_eoc(&p);
+ }
+ assert(p - (unsigned char *)RSTRING_PTR(str) == total_length);
return str;
}
+static VALUE ossl_asn1prim_to_der(VALUE);
+static VALUE ossl_asn1cons_to_der(VALUE);
/*
* call-seq:
* asn1.to_der => DER-encoded String
*
* Encodes this ASN1Data into a DER-encoded String value. The result is
- * DER-encoded except for the possibility of infinite length encodings.
- * Infinite length encodings are not allowed in strict DER, so strictly
- * speaking the result of such an encoding would be a BER-encoding.
+ * DER-encoded except for the possibility of indefinite length forms.
+ * Indefinite length forms are not allowed in strict DER, so strictly speaking
+ * the result of such an encoding would be a BER-encoding.
*/
static VALUE
ossl_asn1data_to_der(VALUE self)
{
- VALUE value, der, inf_length;
- int tag, tag_class, is_cons = 0;
- long length;
- unsigned char *p;
-
- value = ossl_asn1_get_value(self);
- if(rb_obj_is_kind_of(value, rb_cArray)){
- is_cons = 1;
- value = join_der(value);
- }
- StringValue(value);
+ VALUE value = ossl_asn1_get_value(self);
- tag = ossl_asn1_tag(self);
- tag_class = ossl_asn1_tag_class(self);
- inf_length = ossl_asn1_get_infinite_length(self);
- if (inf_length == Qtrue) {
- is_cons = 2;
+ if (rb_obj_is_kind_of(value, rb_cArray))
+ return ossl_asn1cons_to_der(self);
+ else {
+ if (RTEST(ossl_asn1_get_indefinite_length(self)))
+ ossl_raise(eASN1Error, "indefinite length form cannot be used " \
+ "with primitive encoding");
+ return ossl_asn1prim_to_der(self);
}
- if((length = ASN1_object_size(is_cons, RSTRING_LENINT(value), tag)) <= 0)
- ossl_raise(eASN1Error, NULL);
- der = rb_str_new(0, length);
- p = (unsigned char *)RSTRING_PTR(der);
- ASN1_put_object(&p, is_cons, RSTRING_LENINT(value), tag, tag_class);
- memcpy(p, RSTRING_PTR(value), RSTRING_LEN(value));
- p += RSTRING_LEN(value);
- ossl_str_adjust(der, p);
-
- return der;
}
static VALUE
@@ -829,46 +807,33 @@ int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length,
int tag, VALUE tc, long *num_read)
{
VALUE value, asn1data, ary;
- int infinite;
+ int indefinite;
long available_len, off = *offset;
- infinite = (j == 0x21);
+ indefinite = (j == 0x21);
ary = rb_ary_new();
- available_len = infinite ? max_len : length;
+ available_len = indefinite ? max_len : length;
while (available_len > 0) {
long inner_read = 0;
value = ossl_asn1_decode0(pp, available_len, &off, depth + 1, yield, &inner_read);
*num_read += inner_read;
available_len -= inner_read;
- rb_ary_push(ary, value);
- if (infinite &&
- NUM2INT(ossl_asn1_get_tag(value)) == V_ASN1_EOC &&
+ if (indefinite &&
+ ossl_asn1_tag(value) == V_ASN1_EOC &&
ossl_asn1_get_tag_class(value) == sym_UNIVERSAL) {
break;
}
+ rb_ary_push(ary, value);
}
if (tc == sym_UNIVERSAL) {
VALUE args[4];
- int not_sequence_or_set;
-
- not_sequence_or_set = tag != V_ASN1_SEQUENCE && tag != V_ASN1_SET;
-
- if (not_sequence_or_set) {
- if (infinite) {
- asn1data = rb_obj_alloc(cASN1Constructive);
- }
- else {
- ossl_raise(eASN1Error, "invalid non-infinite tag");
- return Qnil;
- }
- }
- else {
- VALUE klass = *ossl_asn1_info[tag].klass;
- asn1data = rb_obj_alloc(klass);
- }
+ if (tag == V_ASN1_SEQUENCE || tag == V_ASN1_SET)
+ asn1data = rb_obj_alloc(*ossl_asn1_info[tag].klass);
+ else
+ asn1data = rb_obj_alloc(cASN1Constructive);
args[0] = ary;
args[1] = INT2NUM(tag);
args[2] = Qnil;
@@ -880,10 +845,10 @@ int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length,
ossl_asn1data_initialize(asn1data, ary, INT2NUM(tag), tc);
}
- if (infinite)
- ossl_asn1_set_infinite_length(asn1data, Qtrue);
+ if (indefinite)
+ ossl_asn1_set_indefinite_length(asn1data, Qtrue);
else
- ossl_asn1_set_infinite_length(asn1data, Qfalse);
+ ossl_asn1_set_indefinite_length(asn1data, Qfalse);
*offset = off;
return asn1data;
@@ -936,7 +901,8 @@ ossl_asn1_decode0(unsigned char **pp, long length, long *offset, int depth,
inner_read += hlen;
}
else {
- if ((j & 0x01) && (len == 0)) ossl_raise(eASN1Error, "Infinite length for primitive value");
+ if ((j & 0x01) && (len == 0))
+ ossl_raise(eASN1Error, "indefinite length for primitive value");
asn1data = int_ossl_asn1_decode0_prim(pp, len, hlen, tag, tag_class, &inner_read);
off += hlen + len;
}
@@ -968,13 +934,13 @@ int_ossl_decode_sanity_check(long len, long read, long offset)
*
* If a block is given, it prints out each of the elements encountered.
* Block parameters are (in that order):
- * * depth: The recursion depth, plus one with each constructed value being encountered (Number)
- * * offset: Current byte offset (Number)
- * * header length: Combined length in bytes of the Tag and Length headers. (Number)
- * * length: The overall remaining length of the entire data (Number)
+ * * depth: The recursion depth, plus one with each constructed value being encountered (Integer)
+ * * offset: Current byte offset (Integer)
+ * * header length: Combined length in bytes of the Tag and Length headers. (Integer)
+ * * length: The overall remaining length of the entire data (Integer)
* * constructed: Whether this value is constructed or not (Boolean)
* * tag_class: Current tag class (Symbol)
- * * tag: The current tag (Number)
+ * * tag: The current tag number (Integer)
*
* == Example
* der = File.binread('asn1data.der')
@@ -1004,9 +970,9 @@ ossl_asn1_traverse(VALUE self, VALUE obj)
* call-seq:
* OpenSSL::ASN1.decode(der) -> ASN1Data
*
- * Decodes a BER- or DER-encoded value and creates an ASN1Data instance. +der+
- * may be a +String+ or any object that features a +#to_der+ method transforming
- * it into a BER-/DER-encoded +String+.
+ * Decodes a BER- or DER-encoded value and creates an ASN1Data instance. _der_
+ * may be a String or any object that features a +.to_der+ method transforming
+ * it into a BER-/DER-encoded String+
*
* == Example
* der = File.binread('asn1data')
@@ -1034,9 +1000,9 @@ ossl_asn1_decode(VALUE self, VALUE obj)
* call-seq:
* OpenSSL::ASN1.decode_all(der) -> Array of ASN1Data
*
- * Similar to +decode+ with the difference that +decode+ expects one
- * distinct value represented in +der+. +decode_all+ on the contrary
- * decodes a sequence of sequential BER/DER values lined up in +der+
+ * Similar to #decode with the difference that #decode expects one
+ * distinct value represented in _der_. #decode_all on the contrary
+ * decodes a sequence of sequential BER/DER values lined up in _der_
* and returns them as an array.
*
* == Example
@@ -1071,19 +1037,19 @@ ossl_asn1_decode_all(VALUE self, VALUE obj)
/*
* call-seq:
- * OpenSSL::ASN1::Primitive.new( value [, tag, tagging, tag_class ]) => Primitive
+ * OpenSSL::ASN1::Primitive.new(value [, tag, tagging, tag_class ]) => Primitive
*
- * +value+: is mandatory.
+ * _value_: is mandatory.
*
- * +tag+: optional, may be specified for tagged values. If no +tag+ is
+ * _tag_: optional, may be specified for tagged values. If no _tag_ is
* specified, the UNIVERSAL tag corresponding to the Primitive sub-class
* is used by default.
*
- * +tagging+: may be used as an encoding hint to encode a value either
+ * _tagging_: may be used as an encoding hint to encode a value either
* explicitly or implicitly, see ASN1 for possible values.
*
- * +tag_class+: if +tag+ and +tagging+ are +nil+ then this is set to
- * +:UNIVERSAL+ by default. If either +tag+ or +tagging+ are set then
+ * _tag_class_: if _tag_ and _tagging_ are +nil+ then this is set to
+ * +:UNIVERSAL+ by default. If either _tag_ or _tagging_ are set then
* +:CONTEXT_SPECIFIC+ is used as the default. For possible values please
* cf. ASN1.
*
@@ -1096,9 +1062,12 @@ static VALUE
ossl_asn1_initialize(int argc, VALUE *argv, VALUE self)
{
VALUE value, tag, tagging, tag_class;
+ int default_tag;
rb_scan_args(argc, argv, "13", &value, &tag, &tagging, &tag_class);
- if(argc > 1){
+ default_tag = ossl_asn1_default_tag(self);
+
+ if (default_tag == -1 || argc > 1) {
if(NIL_P(tag))
ossl_raise(eASN1Error, "must specify tag number");
if(!NIL_P(tagging) && !SYMBOL_P(tagging))
@@ -1111,11 +1080,9 @@ ossl_asn1_initialize(int argc, VALUE *argv, VALUE self)
}
if(!SYMBOL_P(tag_class))
ossl_raise(eASN1Error, "invalid tag class");
- if (tagging == sym_IMPLICIT && NUM2INT(tag) > 31)
- ossl_raise(eASN1Error, "tag number for Universal too large");
}
else{
- tag = INT2NUM(ossl_asn1_default_tag(self));
+ tag = INT2NUM(default_tag);
tagging = Qnil;
tag_class = sym_UNIVERSAL;
}
@@ -1123,7 +1090,9 @@ ossl_asn1_initialize(int argc, VALUE *argv, VALUE self)
ossl_asn1_set_value(self, value);
ossl_asn1_set_tagging(self, tagging);
ossl_asn1_set_tag_class(self, tag_class);
- ossl_asn1_set_infinite_length(self, Qfalse);
+ ossl_asn1_set_indefinite_length(self, Qfalse);
+ if (default_tag == V_ASN1_BIT_STRING)
+ rb_ivar_set(self, sivUNUSED_BITS, INT2FIX(0));
return self;
}
@@ -1131,7 +1100,7 @@ ossl_asn1_initialize(int argc, VALUE *argv, VALUE self)
static VALUE
ossl_asn1eoc_initialize(VALUE self) {
VALUE tag, tagging, tag_class, value;
- tag = INT2NUM(ossl_asn1_default_tag(self));
+ tag = INT2FIX(0);
tagging = Qnil;
tag_class = sym_UNIVERSAL;
value = rb_str_new("", 0);
@@ -1139,51 +1108,58 @@ ossl_asn1eoc_initialize(VALUE self) {
ossl_asn1_set_value(self, value);
ossl_asn1_set_tagging(self, tagging);
ossl_asn1_set_tag_class(self, tag_class);
- ossl_asn1_set_infinite_length(self, Qfalse);
+ ossl_asn1_set_indefinite_length(self, Qfalse);
return self;
}
+static VALUE
+ossl_asn1eoc_to_der(VALUE self)
+{
+ return rb_str_new("\0\0", 2);
+}
+
/*
* call-seq:
* asn1.to_der => DER-encoded String
*
- * See ASN1Data#to_der for details. *
+ * See ASN1Data#to_der for details.
*/
static VALUE
ossl_asn1prim_to_der(VALUE self)
{
ASN1_TYPE *asn1;
- int tn, tc, explicit;
- long len, reallen;
- unsigned char *buf, *p;
+ long alllen, bodylen;
+ unsigned char *p0, *p1;
+ int j, tag, tc, state;
VALUE str;
- tn = NUM2INT(ossl_asn1_get_tag(self));
- tc = ossl_asn1_tag_class(self);
- explicit = ossl_asn1_is_explicit(self);
- asn1 = ossl_asn1_get_asn1type(self);
+ if (ossl_asn1_default_tag(self) == -1) {
+ str = ossl_asn1_get_value(self);
+ return to_der_internal(self, 0, 0, StringValue(str));
+ }
- len = ASN1_object_size(1, i2d_ASN1_TYPE(asn1, NULL), tn);
- if(!(buf = OPENSSL_malloc(len))){
+ asn1 = ossl_asn1_get_asn1type(self);
+ alllen = i2d_ASN1_TYPE(asn1, NULL);
+ if (alllen < 0) {
ASN1_TYPE_free(asn1);
- ossl_raise(eASN1Error, "cannot alloc buffer");
+ ossl_raise(eASN1Error, "i2d_ASN1_TYPE");
}
- p = buf;
- if (tc == V_ASN1_UNIVERSAL) {
- i2d_ASN1_TYPE(asn1, &p);
- } else if (explicit) {
- ASN1_put_object(&p, 1, i2d_ASN1_TYPE(asn1, NULL), tn, tc);
- i2d_ASN1_TYPE(asn1, &p);
- } else {
- i2d_ASN1_TYPE(asn1, &p);
- *buf = tc | tn | (*buf & V_ASN1_CONSTRUCTED);
+ str = ossl_str_new(NULL, alllen, &state);
+ if (state) {
+ ASN1_TYPE_free(asn1);
+ rb_jump_tag(state);
}
+ p0 = p1 = (unsigned char *)RSTRING_PTR(str);
+ i2d_ASN1_TYPE(asn1, &p0);
ASN1_TYPE_free(asn1);
- reallen = p - buf;
- assert(reallen <= len);
- str = ossl_buf2str((char *)buf, rb_long2int(reallen)); /* buf will be free in ossl_buf2str */
+ assert(p0 - p1 == alllen);
- return str;
+ /* Strip header since to_der_internal() wants only the payload */
+ j = ASN1_get_object((const unsigned char **)&p1, &bodylen, &tag, &tc, alllen);
+ if (j & 0x80)
+ ossl_raise(eASN1Error, "ASN1_get_object"); /* should not happen */
+
+ return to_der_internal(self, 0, 0, rb_str_drop_bytes(str, alllen - bodylen));
}
/*
@@ -1195,92 +1171,41 @@ ossl_asn1prim_to_der(VALUE self)
static VALUE
ossl_asn1cons_to_der(VALUE self)
{
- int tag, tn, tc, explicit, constructed = 1;
- int found_prim = 0, seq_len;
- long length;
- unsigned char *p;
- VALUE value, str, inf_length;
-
- tn = NUM2INT(ossl_asn1_get_tag(self));
- tc = ossl_asn1_tag_class(self);
- inf_length = ossl_asn1_get_infinite_length(self);
- if (inf_length == Qtrue) {
- VALUE ary, example;
- constructed = 2;
- if (rb_obj_class(self) == cASN1Sequence ||
- rb_obj_class(self) == cASN1Set) {
- tag = ossl_asn1_default_tag(self);
- }
- else { /* must be a constructive encoding of a primitive value */
- ary = ossl_asn1_get_value(self);
- if (!rb_obj_is_kind_of(ary, rb_cArray))
- ossl_raise(eASN1Error, "Constructive value must be an Array");
- /* Recursively descend until a primitive value is found.
- The overall value of the entire constructed encoding
- is of the type of the first primitive encoding to be
- found. */
- while (!found_prim){
- example = rb_ary_entry(ary, 0);
- if (rb_obj_is_kind_of(example, cASN1Primitive)){
- found_prim = 1;
- }
- else {
- /* example is another ASN1Constructive */
- if (!rb_obj_is_kind_of(example, cASN1Constructive)){
- ossl_raise(eASN1Error, "invalid constructed encoding");
- return Qnil; /* dummy */
- }
- ary = ossl_asn1_get_value(example);
- }
- }
- tag = ossl_asn1_default_tag(example);
- }
- }
- else {
- if (rb_obj_class(self) == cASN1Constructive)
- ossl_raise(eASN1Error, "Constructive shall only be used with infinite length");
- tag = ossl_asn1_default_tag(self);
- }
- explicit = ossl_asn1_is_explicit(self);
- value = join_der(ossl_asn1_get_value(self));
-
- seq_len = ASN1_object_size(constructed, RSTRING_LENINT(value), tag);
- length = ASN1_object_size(constructed, seq_len, tn);
- str = rb_str_new(0, length);
- p = (unsigned char *)RSTRING_PTR(str);
- if(tc == V_ASN1_UNIVERSAL)
- ASN1_put_object(&p, constructed, RSTRING_LENINT(value), tn, tc);
- else{
- if(explicit){
- ASN1_put_object(&p, constructed, seq_len, tn, tc);
- ASN1_put_object(&p, constructed, RSTRING_LENINT(value), tag, V_ASN1_UNIVERSAL);
- }
- else{
- ASN1_put_object(&p, constructed, RSTRING_LENINT(value), tn, tc);
+ VALUE ary, str;
+ long i;
+ int indef_len;
+
+ indef_len = RTEST(ossl_asn1_get_indefinite_length(self));
+ ary = rb_convert_type(ossl_asn1_get_value(self), T_ARRAY, "Array", "to_a");
+ str = rb_str_new(NULL, 0);
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ VALUE item = RARRAY_AREF(ary, i);
+
+ if (indef_len && rb_obj_is_kind_of(item, cASN1EndOfContent)) {
+ if (i != RARRAY_LEN(ary) - 1)
+ ossl_raise(eASN1Error, "illegal EOC octets in value");
+
+ /*
+ * EOC is not really part of the content, but we required to add one
+ * at the end in the past.
+ */
+ break;
}
- }
- memcpy(p, RSTRING_PTR(value), RSTRING_LEN(value));
- p += RSTRING_LEN(value);
- /* In this case we need an additional EOC (one for the explicit part and
- * one for the Constructive itself. The EOC for the Constructive is
- * supplied by the user, but that for the "explicit wrapper" must be
- * added here.
- */
- if (explicit && inf_length == Qtrue) {
- ASN1_put_eoc(&p);
+ item = ossl_to_der_if_possible(item);
+ StringValue(item);
+ rb_str_append(str, item);
}
- ossl_str_adjust(str, p);
- return str;
+ return to_der_internal(self, 1, indef_len, str);
}
/*
* call-seq:
* asn1_ary.each { |asn1| block } => asn1_ary
*
- * Calls <i>block</i> once for each element in +self+, passing that element
- * as parameter +asn1+. If no block is given, an enumerator is returned
+ * Calls the given block once for each element in self, passing that element
+ * as parameter _asn1_. If no block is given, an enumerator is returned
* instead.
*
* == Example
@@ -1300,8 +1225,8 @@ ossl_asn1cons_each(VALUE self)
* call-seq:
* OpenSSL::ASN1::ObjectId.register(object_id, short_name, long_name)
*
- * This adds a new ObjectId to the internal tables. Where +object_id+ is the
- * numerical form, +short_name+ is the short name, and +long_name+ is the long
+ * This adds a new ObjectId to the internal tables. Where _object_id_ is the
+ * numerical form, _short_name_ is the short name, and _long_name_ is the long
* name.
*
* Returns +true+ if successful. Raises an OpenSSL::ASN1::ASN1Error if it fails.
@@ -1320,14 +1245,13 @@ ossl_asn1obj_s_register(VALUE self, VALUE oid, VALUE sn, VALUE ln)
return Qtrue;
}
-/* Document-method: OpenSSL::ASN1::ObjectId#sn
+/*
+ * call-seq:
+ * oid.sn -> string
+ * oid.short_name -> string
*
* The short name of the ObjectId, as defined in <openssl/objects.h>.
*/
-/* Document-method: OpenSSL::ASN1::ObjectId#short_name
- *
- * +short_name+ is an alias to +sn+
- */
static VALUE
ossl_asn1obj_get_sn(VALUE self)
{
@@ -1341,14 +1265,13 @@ ossl_asn1obj_get_sn(VALUE self)
return ret;
}
-/* Document-method: OpenSSL::ASN1::ObjectId#ln
+/*
+ * call-seq:
+ * oid.ln -> string
+ * oid.long_name -> string
*
* The long name of the ObjectId, as defined in <openssl/objects.h>.
*/
-/* Document-method: OpenSSL::ASN1::ObjectId#long_name
- *
- * +long_name+ is an alias to +ln+
- */
static VALUE
ossl_asn1obj_get_ln(VALUE self)
{
@@ -1362,23 +1285,48 @@ ossl_asn1obj_get_ln(VALUE self)
return ret;
}
-/* Document-method: OpenSSL::ASN1::ObjectId#oid
+static VALUE
+asn1obj_get_oid_i(VALUE vobj)
+{
+ ASN1_OBJECT *a1obj = (void *)vobj;
+ VALUE str;
+ int len;
+
+ str = rb_usascii_str_new(NULL, 127);
+ len = OBJ_obj2txt(RSTRING_PTR(str), RSTRING_LENINT(str), a1obj, 1);
+ if (len <= 0 || len == INT_MAX)
+ ossl_raise(eASN1Error, "OBJ_obj2txt");
+ if (len > RSTRING_LEN(str)) {
+ /* +1 is for the \0 terminator added by OBJ_obj2txt() */
+ rb_str_resize(str, len + 1);
+ len = OBJ_obj2txt(RSTRING_PTR(str), len + 1, a1obj, 1);
+ if (len <= 0)
+ ossl_raise(eASN1Error, "OBJ_obj2txt");
+ }
+ rb_str_set_len(str, len);
+ return str;
+}
+
+/*
+ * call-seq:
+ * oid.oid -> string
*
- * The object identifier as a +String+, e.g. "1.2.3.4.5"
+ * Returns a String representing the Object Identifier in the dot notation,
+ * e.g. "1.2.3.4.5"
*/
static VALUE
ossl_asn1obj_get_oid(VALUE self)
{
- VALUE val;
+ VALUE str;
ASN1_OBJECT *a1obj;
- char buf[128];
+ int state;
- val = ossl_asn1_get_value(self);
- a1obj = obj_to_asn1obj(val);
- OBJ_obj2txt(buf, sizeof(buf), a1obj, 1);
+ a1obj = obj_to_asn1obj(ossl_asn1_get_value(self));
+ str = rb_protect(asn1obj_get_oid_i, (VALUE)a1obj, &state);
ASN1_OBJECT_free(a1obj);
-
- return rb_str_new2(buf);
+ if (state)
+ rb_jump_tag(state);
+ return str;
}
#define OSSL_ASN1_IMPL_FACTORY_METHOD(klass) \
@@ -1431,7 +1379,7 @@ Init_ossl_asn1(void)
sivTAG = rb_intern("@tag");
sivTAGGING = rb_intern("@tagging");
sivTAG_CLASS = rb_intern("@tag_class");
- sivINFINITE_LENGTH = rb_intern("@infinite_length");
+ sivINDEFINITE_LENGTH = rb_intern("@indefinite_length");
sivUNUSED_BITS = rb_intern("@unused_bits");
/*
@@ -1457,24 +1405,21 @@ Init_ossl_asn1(void)
* == ASN.1 class hierarchy
*
* The base class representing ASN.1 structures is ASN1Data. ASN1Data offers
- * attributes to read and set the +tag+, the +tag_class+ and finally the
- * +value+ of a particular ASN.1 item. Upon parsing, any tagged values
+ * attributes to read and set the _tag_, the _tag_class_ and finally the
+ * _value_ of a particular ASN.1 item. Upon parsing, any tagged values
* (implicit or explicit) will be represented by ASN1Data instances because
* their "real type" can only be determined using out-of-band information
* from the ASN.1 type declaration. Since this information is normally
* known when encoding a type, all sub-classes of ASN1Data offer an
- * additional attribute +tagging+ that allows to encode a value implicitly
+ * additional attribute _tagging_ that allows to encode a value implicitly
* (+:IMPLICIT+) or explicitly (+:EXPLICIT+).
*
* === Constructive
*
* Constructive is, as its name implies, the base class for all
* constructed encodings, i.e. those that consist of several values,
- * opposed to "primitive" encodings with just one single value.
- * Primitive values that are encoded with "infinite length" are typically
- * constructed (their values come in multiple chunks) and are therefore
- * represented by instances of Constructive. The value of an Constructive
- * is always an Array.
+ * opposed to "primitive" encodings with just one single value. The value of
+ * an Constructive is always an Array.
*
* ==== ASN1::Set and ASN1::Sequence
*
@@ -1491,18 +1436,18 @@ Init_ossl_asn1(void)
* Please cf. Primitive documentation for details on sub-classes and
* their respective mappings of ASN.1 data types to Ruby objects.
*
- * == Possible values for +tagging+
+ * == Possible values for _tagging_
*
* When constructing an ASN1Data object the ASN.1 type definition may
* require certain elements to be either implicitly or explicitly tagged.
- * This can be achieved by setting the +tagging+ attribute manually for
+ * This can be achieved by setting the _tagging_ attribute manually for
* sub-classes of ASN1Data. Use the symbol +:IMPLICIT+ for implicit
* tagging and +:EXPLICIT+ if the element requires explicit tagging.
*
- * == Possible values for +tag_class+
+ * == Possible values for _tag_class_
*
* It is possible to create arbitrary ASN1Data objects that also support
- * a PRIVATE or APPLICATION tag class. Possible values for the +tag_class+
+ * a PRIVATE or APPLICATION tag class. Possible values for the _tag_class_
* attribute are:
* * +:UNIVERSAL+ (the default for untagged values)
* * +:CONTEXT_SPECIFIC+ (the default for tagged values)
@@ -1604,9 +1549,9 @@ Init_ossl_asn1(void)
*
* An implicitly 1-tagged INTEGER value will be parsed as an
* ASN1Data with
- * * +tag+ equal to 1
- * * +tag_class+ equal to +:CONTEXT_SPECIFIC+
- * * +value+ equal to a +String+ that carries the raw encoding
+ * * _tag_ equal to 1
+ * * _tag_class_ equal to +:CONTEXT_SPECIFIC+
+ * * _value_ equal to a String that carries the raw encoding
* of the INTEGER.
* This implies that a subsequent decoding step is required to
* completely decode implicitly tagged values.
@@ -1615,9 +1560,9 @@ Init_ossl_asn1(void)
*
* An explicitly 1-tagged INTEGER value will be parsed as an
* ASN1Data with
- * * +tag+ equal to 1
- * * +tag_class+ equal to +:CONTEXT_SPECIFIC+
- * * +value+ equal to an +Array+ with one single element, an
+ * * _tag_ equal to 1
+ * * _tag_class_ equal to +:CONTEXT_SPECIFIC+
+ * * _value_ equal to an Array with one single element, an
* instance of OpenSSL::ASN1::Integer, i.e. the inner element
* is the non-tagged primitive value, and the tagging is represented
* in the outer ASN1Data
@@ -1628,13 +1573,13 @@ Init_ossl_asn1(void)
* der = seq.to_der
* asn1 = OpenSSL::ASN1.decode(der)
* # pp asn1 => #<OpenSSL::ASN1::Sequence:0x87326e0
- * # @infinite_length=false,
+ * # @indefinite_length=false,
* # @tag=16,
* # @tag_class=:UNIVERSAL,
* # @tagging=nil,
* # @value=
* # [#<OpenSSL::ASN1::ASN1Data:0x87326f4
- * # @infinite_length=false,
+ * # @indefinite_length=false,
* # @tag=0,
* # @tag_class=:CONTEXT_SPECIFIC,
* # @value="\x01">]>
@@ -1651,18 +1596,18 @@ Init_ossl_asn1(void)
* der = seq.to_der
* asn1 = OpenSSL::ASN1.decode(der)
* # pp asn1 => #<OpenSSL::ASN1::Sequence:0x87326e0
- * # @infinite_length=false,
+ * # @indefinite_length=false,
* # @tag=16,
* # @tag_class=:UNIVERSAL,
* # @tagging=nil,
* # @value=
* # [#<OpenSSL::ASN1::ASN1Data:0x87326f4
- * # @infinite_length=false,
+ * # @indefinite_length=false,
* # @tag=0,
* # @tag_class=:CONTEXT_SPECIFIC,
* # @value=
* # [#<OpenSSL::ASN1::Integer:0x85bf308
- * # @infinite_length=false,
+ * # @indefinite_length=false,
* # @tag=2,
* # @tag_class=:UNIVERSAL
* # @tagging=nil,
@@ -1678,73 +1623,75 @@ Init_ossl_asn1(void)
*/
rb_attr(cASN1Data, rb_intern("value"), 1, 1, 0);
/*
- * A +Number+ representing the tag number of this ASN1Data. Never +nil+.
+ * An Integer representing the tag number of this ASN1Data. Never +nil+.
*/
rb_attr(cASN1Data, rb_intern("tag"), 1, 1, 0);
/*
- * A +Symbol+ representing the tag class of this ASN1Data. Never +nil+.
+ * A Symbol representing the tag class of this ASN1Data. Never +nil+.
* See ASN1Data for possible values.
*/
rb_attr(cASN1Data, rb_intern("tag_class"), 1, 1, 0);
/*
- * Never +nil+. A +Boolean+ indicating whether the encoding was infinite
- * length (in the case of parsing) or whether an infinite length encoding
- * shall be used (in the encoding case).
- * In DER, every value has a finite length associated with it. But in
- * scenarios where large amounts of data need to be transferred it
- * might be desirable to have some kind of streaming support available.
+ * Never +nil+. A boolean value indicating whether the encoding uses
+ * indefinite length (in the case of parsing) or whether an indefinite
+ * length form shall be used (in the encoding case).
+ * In DER, every value uses definite length form. But in scenarios where
+ * large amounts of data need to be transferred it might be desirable to
+ * have some kind of streaming support available.
* For example, huge OCTET STRINGs are preferably sent in smaller-sized
* chunks, each at a time.
* This is possible in BER by setting the length bytes of an encoding
* to zero and by this indicating that the following value will be
- * sent in chunks. Infinite length encodings are always constructed.
+ * sent in chunks. Indefinite length encodings are always constructed.
* The end of such a stream of chunks is indicated by sending a EOC
- * (End of Content) tag. SETs and SEQUENCEs may use an infinite length
+ * (End of Content) tag. SETs and SEQUENCEs may use an indefinite length
* encoding, but also primitive types such as e.g. OCTET STRINGS or
* BIT STRINGS may leverage this functionality (cf. ITU-T X.690).
*/
- rb_attr(cASN1Data, rb_intern("infinite_length"), 1, 1, 0);
+ rb_attr(cASN1Data, rb_intern("indefinite_length"), 1, 1, 0);
+ rb_define_alias(cASN1Data, "infinite_length", "indefinite_length");
+ rb_define_alias(cASN1Data, "infinite_length=", "indefinite_length=");
rb_define_method(cASN1Data, "initialize", ossl_asn1data_initialize, 3);
rb_define_method(cASN1Data, "to_der", ossl_asn1data_to_der, 0);
/* Document-class: OpenSSL::ASN1::Primitive
*
* The parent class for all primitive encodings. Attributes are the same as
- * for ASN1Data, with the addition of +tagging+.
- * Primitive values can never be infinite length encodings, thus it is not
- * possible to set the +infinite_length+ attribute for Primitive and its
- * sub-classes.
+ * for ASN1Data, with the addition of _tagging_.
+ * Primitive values can never be encoded with indefinite length form, thus
+ * it is not possible to set the _indefinite_length_ attribute for Primitive
+ * and its sub-classes.
*
* == Primitive sub-classes and their mapping to Ruby classes
- * * OpenSSL::ASN1::EndOfContent <=> +value+ is always +nil+
- * * OpenSSL::ASN1::Boolean <=> +value+ is a +Boolean+
- * * OpenSSL::ASN1::Integer <=> +value+ is a +Number+
- * * OpenSSL::ASN1::BitString <=> +value+ is a +String+
- * * OpenSSL::ASN1::OctetString <=> +value+ is a +String+
- * * OpenSSL::ASN1::Null <=> +value+ is always +nil+
- * * OpenSSL::ASN1::Object <=> +value+ is a +String+
- * * OpenSSL::ASN1::Enumerated <=> +value+ is a +Number+
- * * OpenSSL::ASN1::UTF8String <=> +value+ is a +String+
- * * OpenSSL::ASN1::NumericString <=> +value+ is a +String+
- * * OpenSSL::ASN1::PrintableString <=> +value+ is a +String+
- * * OpenSSL::ASN1::T61String <=> +value+ is a +String+
- * * OpenSSL::ASN1::VideotexString <=> +value+ is a +String+
- * * OpenSSL::ASN1::IA5String <=> +value+ is a +String+
- * * OpenSSL::ASN1::UTCTime <=> +value+ is a +Time+
- * * OpenSSL::ASN1::GeneralizedTime <=> +value+ is a +Time+
- * * OpenSSL::ASN1::GraphicString <=> +value+ is a +String+
- * * OpenSSL::ASN1::ISO64String <=> +value+ is a +String+
- * * OpenSSL::ASN1::GeneralString <=> +value+ is a +String+
- * * OpenSSL::ASN1::UniversalString <=> +value+ is a +String+
- * * OpenSSL::ASN1::BMPString <=> +value+ is a +String+
+ * * OpenSSL::ASN1::EndOfContent <=> _value_ is always +nil+
+ * * OpenSSL::ASN1::Boolean <=> _value_ is +true+ or +false+
+ * * OpenSSL::ASN1::Integer <=> _value_ is an Integer
+ * * OpenSSL::ASN1::BitString <=> _value_ is a String
+ * * OpenSSL::ASN1::OctetString <=> _value_ is a String
+ * * OpenSSL::ASN1::Null <=> _value_ is always +nil+
+ * * OpenSSL::ASN1::Object <=> _value_ is a String
+ * * OpenSSL::ASN1::Enumerated <=> _value_ is an Integer
+ * * OpenSSL::ASN1::UTF8String <=> _value_ is a String
+ * * OpenSSL::ASN1::NumericString <=> _value_ is a String
+ * * OpenSSL::ASN1::PrintableString <=> _value_ is a String
+ * * OpenSSL::ASN1::T61String <=> _value_ is a String
+ * * OpenSSL::ASN1::VideotexString <=> _value_ is a String
+ * * OpenSSL::ASN1::IA5String <=> _value_ is a String
+ * * OpenSSL::ASN1::UTCTime <=> _value_ is a Time
+ * * OpenSSL::ASN1::GeneralizedTime <=> _value_ is a Time
+ * * OpenSSL::ASN1::GraphicString <=> _value_ is a String
+ * * OpenSSL::ASN1::ISO64String <=> _value_ is a String
+ * * OpenSSL::ASN1::GeneralString <=> _value_ is a String
+ * * OpenSSL::ASN1::UniversalString <=> _value_ is a String
+ * * OpenSSL::ASN1::BMPString <=> _value_ is a String
*
* == OpenSSL::ASN1::BitString
*
* === Additional attributes
- * +unused_bits+: if the underlying BIT STRING's
- * length is a multiple of 8 then +unused_bits+ is 0. Otherwise
- * +unused_bits+ indicates the number of bits that are to be ignored in
- * the final octet of the +BitString+'s +value+.
+ * _unused_bits_: if the underlying BIT STRING's
+ * length is a multiple of 8 then _unused_bits_ is 0. Otherwise
+ * _unused_bits_ indicates the number of bits that are to be ignored in
+ * the final octet of the BitString's _value_.
*
* == OpenSSL::ASN1::ObjectId
*
@@ -1753,15 +1700,15 @@ Init_ossl_asn1(void)
* parsed ASN1 encodings.
*
* === Additional attributes
- * * +sn+: the short name as defined in <openssl/objects.h>.
- * * +ln+: the long name as defined in <openssl/objects.h>.
- * * +oid+: the object identifier as a +String+, e.g. "1.2.3.4.5"
- * * +short_name+: alias for +sn+.
- * * +long_name+: alias for +ln+.
+ * * _sn_: the short name as defined in <openssl/objects.h>.
+ * * _ln_: the long name as defined in <openssl/objects.h>.
+ * * _oid_: the object identifier as a String, e.g. "1.2.3.4.5"
+ * * _short_name_: alias for _sn_.
+ * * _long_name_: alias for _ln_.
*
* == Examples
* With the Exception of OpenSSL::ASN1::EndOfContent, each Primitive class
- * constructor takes at least one parameter, the +value+.
+ * constructor takes at least one parameter, the _value_.
*
* === Creating EndOfContent
* eoc = OpenSSL::ASN1::EndOfContent.new
@@ -1775,19 +1722,20 @@ Init_ossl_asn1(void)
/*
* May be used as a hint for encoding a value either implicitly or
* explicitly by setting it either to +:IMPLICIT+ or to +:EXPLICIT+.
- * +tagging+ is not set when a ASN.1 structure is parsed using
+ * _tagging_ is not set when a ASN.1 structure is parsed using
* OpenSSL::ASN1.decode.
*/
rb_attr(cASN1Primitive, rb_intern("tagging"), 1, 1, Qtrue);
+ rb_undef_method(cASN1Primitive, "indefinite_length=");
rb_undef_method(cASN1Primitive, "infinite_length=");
rb_define_method(cASN1Primitive, "initialize", ossl_asn1_initialize, -1);
rb_define_method(cASN1Primitive, "to_der", ossl_asn1prim_to_der, 0);
/* Document-class: OpenSSL::ASN1::Constructive
*
- * The parent class for all constructed encodings. The +value+ attribute
- * of a Constructive is always an +Array+. Attributes are the same as
- * for ASN1Data, with the addition of +tagging+.
+ * The parent class for all constructed encodings. The _value_ attribute
+ * of a Constructive is always an Array. Attributes are the same as
+ * for ASN1Data, with the addition of _tagging_.
*
* == SET and SEQUENCE
*
@@ -1809,48 +1757,13 @@ Init_ossl_asn1(void)
* int = OpenSSL::ASN1::Integer.new(1)
* str = OpenSSL::ASN1::PrintableString.new('abc')
* set = OpenSSL::ASN1::Set.new( [ int, str ] )
- *
- * == Infinite length primitive values
- *
- * The only case where Constructive is used directly is for infinite
- * length encodings of primitive values. These encodings are always
- * constructed, with the contents of the +value+ +Array+ being either
- * UNIVERSAL non-infinite length partial encodings of the actual value
- * or again constructive encodings with infinite length (i.e. infinite
- * length primitive encodings may be constructed recursively with another
- * infinite length value within an already infinite length value). Each
- * partial encoding must be of the same UNIVERSAL type as the overall
- * encoding. The value of the overall encoding consists of the
- * concatenation of each partial encoding taken in sequence. The +value+
- * array of the outer infinite length value must end with a
- * OpenSSL::ASN1::EndOfContent instance.
- *
- * Please note that it is not possible to encode Constructive without
- * the +infinite_length+ attribute being set to +true+, use
- * OpenSSL::ASN1::Sequence or OpenSSL::ASN1::Set in these cases instead.
- *
- * === Example - Infinite length OCTET STRING
- * partial1 = OpenSSL::ASN1::OctetString.new("\x01")
- * partial2 = OpenSSL::ASN1::OctetString.new("\x02")
- * inf_octets = OpenSSL::ASN1::Constructive.new( [ partial1,
- * partial2,
- * OpenSSL::ASN1::EndOfContent.new ],
- * OpenSSL::ASN1::OCTET_STRING,
- * nil,
- * :UNIVERSAL )
- * # The real value of inf_octets is "\x01\x02", i.e. the concatenation
- * # of partial1 and partial2
- * inf_octets.infinite_length = true
- * der = inf_octets.to_der
- * asn1 = OpenSSL::ASN1.decode(der)
- * puts asn1.infinite_length # => true
*/
cASN1Constructive = rb_define_class_under(mASN1,"Constructive", cASN1Data);
rb_include_module(cASN1Constructive, rb_mEnumerable);
/*
* May be used as a hint for encoding a value either implicitly or
* explicitly by setting it either to +:IMPLICIT+ or to +:EXPLICIT+.
- * +tagging+ is not set when a ASN.1 structure is parsed using
+ * _tagging_ is not set when a ASN.1 structure is parsed using
* OpenSSL::ASN1.decode.
*/
rb_attr(cASN1Constructive, rb_intern("tagging"), 1, 1, Qtrue);
@@ -1907,6 +1820,7 @@ do{\
rb_attr(cASN1BitString, rb_intern("unused_bits"), 1, 1, 0);
rb_define_method(cASN1EndOfContent, "initialize", ossl_asn1eoc_initialize, 0);
+ rb_define_method(cASN1EndOfContent, "to_der", ossl_asn1eoc_to_der, 0);
class_tag_map = rb_hash_new();
rb_hash_aset(class_tag_map, cASN1EndOfContent, INT2NUM(V_ASN1_EOC));
diff --git a/ext/openssl/ossl_asn1.h b/ext/openssl/ossl_asn1.h
index d6a170c86c..939a96ce74 100644
--- a/ext/openssl/ossl_asn1.h
+++ b/ext/openssl/ossl_asn1.h
@@ -14,15 +14,11 @@
* ASN1_DATE conversions
*/
VALUE asn1time_to_time(const ASN1_TIME *);
-#if defined(HAVE_ASN1_TIME_ADJ)
/* Splits VALUE to seconds and offset days. VALUE is typically a Time or an
* Integer. This is used when updating ASN1_*TIME with ASN1_TIME_adj() or
* X509_time_adj_ex(). We can't use ASN1_TIME_set() and X509_time_adj() because
* they have the Year 2038 issue on sizeof(time_t) == 4 environment */
void ossl_time_split(VALUE, time_t *, int *);
-#else
-time_t time_to_time_t(VALUE);
-#endif
/*
* ASN1_STRING conversions
diff --git a/ext/openssl/ossl_bio.c b/ext/openssl/ossl_bio.c
index 8fa0b6966d..42833d901a 100644
--- a/ext/openssl/ossl_bio.c
+++ b/ext/openssl/ossl_bio.c
@@ -26,32 +26,17 @@ ossl_obj2bio(volatile VALUE *pobj)
}
VALUE
-ossl_membio2str0(BIO *bio)
+ossl_membio2str(BIO *bio)
{
VALUE ret;
+ int state;
BUF_MEM *buf;
BIO_get_mem_ptr(bio, &buf);
- ret = rb_str_new(buf->data, buf->length);
-
- return ret;
-}
-
-VALUE
-ossl_protect_membio2str(BIO *bio, int *status)
-{
- return rb_protect((VALUE (*)(VALUE))ossl_membio2str0, (VALUE)bio, status);
-}
-
-VALUE
-ossl_membio2str(BIO *bio)
-{
- VALUE ret;
- int status = 0;
-
- ret = ossl_protect_membio2str(bio, &status);
+ ret = ossl_str_new(buf->data, buf->length, &state);
BIO_free(bio);
- if(status) rb_jump_tag(status);
+ if (state)
+ rb_jump_tag(state);
return ret;
}
diff --git a/ext/openssl/ossl_bio.h b/ext/openssl/ossl_bio.h
index 2c3d952b38..da68c5e5a2 100644
--- a/ext/openssl/ossl_bio.h
+++ b/ext/openssl/ossl_bio.h
@@ -11,8 +11,6 @@
#define _OSSL_BIO_H_
BIO *ossl_obj2bio(volatile VALUE *);
-VALUE ossl_membio2str0(BIO*);
VALUE ossl_membio2str(BIO*);
-VALUE ossl_protect_membio2str(BIO*,int*);
#endif
diff --git a/ext/openssl/ossl_bn.c b/ext/openssl/ossl_bn.c
index aa0f2c605f..94ef6fd6f7 100644
--- a/ext/openssl/ossl_bn.c
+++ b/ext/openssl/ossl_bn.c
@@ -26,11 +26,6 @@
} \
} while (0)
-#define SafeGetBN(obj, bn) do { \
- OSSL_Check_Kind((obj), cBN); \
- GetBN((obj), (bn)); \
-} while (0)
-
static void
ossl_bn_free(void *ptr)
{
@@ -176,8 +171,7 @@ ossl_bn_alloc(VALUE klass)
return obj;
}
-/* Document-method: OpenSSL::BN.new
- *
+/*
* call-seq:
* OpenSSL::BN.new => aBN
* OpenSSL::BN.new(bn) => aBN
@@ -185,7 +179,7 @@ ossl_bn_alloc(VALUE klass)
* OpenSSL::BN.new(string) => aBN
* OpenSSL::BN.new(string, 0 | 2 | 10 | 16) => aBN
*
- * Construct a new OpenSSL BigNum object.
+ * Construct a new OpenSSL BIGNUM object.
*/
static VALUE
ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
@@ -250,7 +244,7 @@ ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
* bn.to_s(base) => string
*
* === Parameters
- * * +base+ - integer
+ * * _base_ - Integer
* Valid values:
* * 0 - MPI
* * 2 - binary
@@ -377,6 +371,21 @@ BIGNUM_BOOL1(is_one)
*/
BIGNUM_BOOL1(is_odd)
+/*
+ * call-seq:
+ * bn.negative? => true | false
+ */
+static VALUE
+ossl_bn_is_negative(VALUE self)
+{
+ BIGNUM *bn;
+
+ GetBN(self, bn);
+ if (BN_is_zero(bn))
+ return Qfalse;
+ return BN_is_negative(bn) ? Qtrue : Qfalse;
+}
+
#define BIGNUM_1c(func) \
static VALUE \
ossl_bn_##func(VALUE self) \
@@ -498,7 +507,6 @@ BIGNUM_2c(mod_sqr)
BIGNUM_2c(mod_inverse)
/*
- * Document-method: OpenSSL::BN#/
* call-seq:
* bn1 / bn2 => [result, remainder]
*
@@ -614,12 +622,11 @@ BIGNUM_BIT(clear_bit)
*/
BIGNUM_BIT(mask_bits)
-/* Document-method: OpenSSL::BN#bit_set?
+/*
* call-seq:
* bn.bit_set?(bit) => true | false
*
- * Returns boolean of whether +bit+ is set.
- * Bitwise operations for openssl BIGNUMs.
+ * Tests bit _bit_ in _bn_ and returns +true+ if set, +false+ if not set.
*/
static VALUE
ossl_bn_is_bit_set(VALUE self, VALUE bit)
@@ -774,15 +781,15 @@ BIGNUM_RAND_RANGE(pseudo_rand)
* call-seq:
* BN.generate_prime(bits, [, safe [, add [, rem]]]) => bn
*
- * Generates a random prime number of bit length +bits+. If +safe+ is true,
- * generates a safe prime. If +add+ is specified, generates a prime that
+ * Generates a random prime number of bit length _bits_. If _safe_ is set to
+ * +true+, generates a safe prime. If _add_ is specified, generates a prime that
* fulfills condition <tt>p % add = rem</tt>.
*
* === Parameters
- * * +bits+ - integer
- * * +safe+ - boolean
- * * +add+ - BN
- * * +rem+ - BN
+ * * _bits_ - integer
+ * * _safe_ - boolean
+ * * _add_ - BN
+ * * _rem_ - BN
*/
static VALUE
ossl_bn_s_generate_prime(int argc, VALUE *argv, VALUE klass)
@@ -856,6 +863,37 @@ ossl_bn_copy(VALUE self, VALUE other)
return self;
}
+/*
+ * call-seq:
+ * +bn -> aBN
+ */
+static VALUE
+ossl_bn_uplus(VALUE self)
+{
+ return self;
+}
+
+/*
+ * call-seq:
+ * -bn -> aBN
+ */
+static VALUE
+ossl_bn_uminus(VALUE self)
+{
+ VALUE obj;
+ BIGNUM *bn1, *bn2;
+
+ GetBN(self, bn1);
+ obj = NewBN(cBN);
+ bn2 = BN_dup(bn1);
+ if (!bn2)
+ ossl_raise(eBNError, "BN_dup");
+ SetBN(obj, bn2);
+ BN_set_negative(bn2, !BN_is_negative(bn2));
+
+ return obj;
+}
+
#define BIGNUM_CMP(func) \
static VALUE \
ossl_bn_##func(VALUE self, VALUE other) \
@@ -888,7 +926,7 @@ BIGNUM_CMP(ucmp)
* call-seq:
* bn == obj => true or false
*
- * Returns +true+ only if +obj+ has the same value as +bn+. Contrast this
+ * Returns +true+ only if _obj_ has the same value as _bn_. Contrast this
* with OpenSSL::BN#eql?, which requires obj to be OpenSSL::BN.
*/
static VALUE
@@ -913,7 +951,7 @@ ossl_bn_eq(VALUE self, VALUE other)
* bn.eql?(obj) => true or false
*
* Returns <code>true</code> only if <i>obj</i> is a
- * <code>OpenSSL::BN</code> with the same value as <i>big</i>. Contrast this
+ * <code>OpenSSL::BN</code> with the same value as <i>bn</i>. Contrast this
* with OpenSSL::BN#==, which performs type conversions.
*/
static VALUE
@@ -964,12 +1002,12 @@ ossl_bn_hash(VALUE self)
* bn.prime? => true | false
* bn.prime?(checks) => true | false
*
- * Performs a Miller-Rabin probabilistic primality test with +checks+
- * iterations. If +nchecks+ is not specified, a number of iterations is used
+ * Performs a Miller-Rabin probabilistic primality test with _checks_
+ * iterations. If _checks_ is not specified, a number of iterations is used
* that yields a false positive rate of at most 2^-80 for random input.
*
* === Parameters
- * * +checks+ - integer
+ * * _checks_ - integer
*/
static VALUE
ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)
@@ -1004,8 +1042,8 @@ ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)
* first attempts trial divisions with some small primes.
*
* === Parameters
- * * +checks+ - integer
- * * +trial_div+ - boolean
+ * * _checks_ - integer
+ * * _trial_div_ - boolean
*/
static VALUE
ossl_bn_is_prime_fasttest(int argc, VALUE *argv, VALUE self)
@@ -1059,7 +1097,7 @@ Init_ossl_bn(void)
rb_define_alloc_func(cBN, ossl_bn_alloc);
rb_define_method(cBN, "initialize", ossl_bn_initialize, -1);
- rb_define_copy_func(cBN, ossl_bn_copy);
+ rb_define_method(cBN, "initialize_copy", ossl_bn_copy, 1);
rb_define_method(cBN, "copy", ossl_bn_copy, 1);
/* swap (=coerce?) */
@@ -1068,6 +1106,9 @@ Init_ossl_bn(void)
rb_define_method(cBN, "num_bits", ossl_bn_num_bits, 0);
/* num_bits_word */
+ rb_define_method(cBN, "+@", ossl_bn_uplus, 0);
+ rb_define_method(cBN, "-@", ossl_bn_uminus, 0);
+
rb_define_method(cBN, "+", ossl_bn_add, 1);
rb_define_method(cBN, "-", ossl_bn_sub, 1);
rb_define_method(cBN, "*", ossl_bn_mul, 1);
@@ -1101,6 +1142,7 @@ Init_ossl_bn(void)
rb_define_method(cBN, "one?", ossl_bn_is_one, 0);
/* is_word */
rb_define_method(cBN, "odd?", ossl_bn_is_odd, 0);
+ rb_define_method(cBN, "negative?", ossl_bn_is_negative, 0);
/* zero
* one
diff --git a/ext/openssl/ossl_cipher.c b/ext/openssl/ossl_cipher.c
index c2f0927a75..bfa76c1aab 100644
--- a/ext/openssl/ossl_cipher.c
+++ b/ext/openssl/ossl_cipher.c
@@ -26,10 +26,6 @@
ossl_raise(rb_eRuntimeError, "Cipher not initialized!"); \
} \
} while (0)
-#define SafeGetCipher(obj, ctx) do { \
- OSSL_Check_Kind((obj), cCipher); \
- GetCipher((obj), (ctx)); \
-} while (0)
/*
* Classes
@@ -53,7 +49,7 @@ static const rb_data_type_t ossl_cipher_type = {
* PUBLIC
*/
const EVP_CIPHER *
-GetCipherPtr(VALUE obj)
+ossl_evp_get_cipherbyname(VALUE obj)
{
if (rb_obj_is_kind_of(obj, cCipher)) {
EVP_CIPHER_CTX *ctx;
@@ -108,7 +104,7 @@ ossl_cipher_alloc(VALUE klass)
* call-seq:
* Cipher.new(string) -> cipher
*
- * The string must contain a valid cipher name like "AES-128-CBC" or "3DES".
+ * The string must be a valid cipher name like "AES-128-CBC" or "3DES".
*
* A list of cipher names is available by calling OpenSSL::Cipher.ciphers.
*/
@@ -146,7 +142,7 @@ ossl_cipher_copy(VALUE self, VALUE other)
if (!ctx1) {
AllocCipher(self, ctx1);
}
- SafeGetCipher(other, ctx2);
+ GetCipher(other, ctx2);
if (EVP_CIPHER_CTX_copy(ctx1, ctx2) != 1)
ossl_raise(eCipherError, NULL);
@@ -296,9 +292,9 @@ ossl_cipher_decrypt(int argc, VALUE *argv, VALUE self)
* OpenSSL::PKCS5 instead.
*
* === Parameters
- * * +salt+ must be an 8 byte string if provided.
- * * +iterations+ is an integer with a default of 2048.
- * * +digest+ is a Digest object that defaults to 'MD5'
+ * * _salt_ must be an 8 byte string if provided.
+ * * _iterations_ is an integer with a default of 2048.
+ * * _digest_ is a Digest object that defaults to 'MD5'
*
* A minimum of 1000 iterations is recommended.
*
@@ -321,7 +317,7 @@ ossl_cipher_pkcs5_keyivgen(int argc, VALUE *argv, VALUE self)
salt = (unsigned char *)RSTRING_PTR(vsalt);
}
iter = NIL_P(viter) ? 2048 : NUM2INT(viter);
- digest = NIL_P(vdigest) ? EVP_md5() : GetDigestPtr(vdigest);
+ digest = NIL_P(vdigest) ? EVP_md5() : ossl_evp_get_digestbyname(vdigest);
GetCipher(self, ctx);
EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), digest, salt,
(unsigned char *)RSTRING_PTR(vpass), RSTRING_LENINT(vpass), iter, key, iv);
@@ -365,12 +361,12 @@ ossl_cipher_update_long(EVP_CIPHER_CTX *ctx, unsigned char *out, long *out_len_p
* cipher.update(data [, buffer]) -> string or buffer
*
* Encrypts data in a streaming fashion. Hand consecutive blocks of data
- * to the +update+ method in order to encrypt it. Returns the encrypted
+ * to the #update method in order to encrypt it. Returns the encrypted
* data chunk. When done, the output of Cipher#final should be additionally
* added to the result.
*
- * If +buffer+ is given, the encryption/decryption result will be written to
- * it. +buffer+ will be resized automatically.
+ * If _buffer_ is given, the encryption/decryption result will be written to
+ * it. _buffer_ will be resized automatically.
*/
static VALUE
ossl_cipher_update(int argc, VALUE *argv, VALUE self)
@@ -512,10 +508,8 @@ ossl_cipher_set_iv(VALUE self, VALUE iv)
StringValue(iv);
GetCipher(self, ctx);
-#if defined(HAVE_AUTHENTICATED_ENCRYPTION)
if (EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER)
iv_len = (int)(VALUE)EVP_CIPHER_CTX_get_app_data(ctx);
-#endif
if (!iv_len)
iv_len = EVP_CIPHER_CTX_iv_length(ctx);
if (RSTRING_LEN(iv) != iv_len)
@@ -541,14 +535,9 @@ ossl_cipher_is_authenticated(VALUE self)
GetCipher(self, ctx);
-#if defined(HAVE_AUTHENTICATED_ENCRYPTION)
return (EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER) ? Qtrue : Qfalse;
-#else
- return Qfalse;
-#endif
}
-#ifdef HAVE_AUTHENTICATED_ENCRYPTION
/*
* call-seq:
* cipher.auth_data = string -> string
@@ -594,8 +583,8 @@ ossl_cipher_set_auth_data(VALUE self, VALUE data)
* Gets the authentication tag generated by Authenticated Encryption Cipher
* modes (GCM for example). This tag may be stored along with the ciphertext,
* then set on the decryption cipher to authenticate the contents of the
- * ciphertext against changes. If the optional integer parameter +tag_len+ is
- * given, the returned tag will be +tag_len+ bytes long. If the parameter is
+ * ciphertext against changes. If the optional integer parameter _tag_len_ is
+ * given, the returned tag will be _tag_len_ bytes long. If the parameter is
* omitted, the default length of 16 bytes or the length previously set by
* #auth_tag_len= will be used. For maximum security, the longest possible
* should be chosen.
@@ -631,13 +620,11 @@ ossl_cipher_get_auth_tag(int argc, VALUE *argv, VALUE self)
* call-seq:
* cipher.auth_tag = string -> string
*
- * Sets the authentication tag to verify the contents of the
- * ciphertext. The tag must be set after calling Cipher#decrypt,
- * Cipher#key= and Cipher#iv=, but before assigning the associated
- * authenticated data using Cipher#auth_data= and of course, before
- * decrypting any of the ciphertext. After all decryption is
- * performed, the tag is verified automatically in the call to
- * Cipher#final.
+ * Sets the authentication tag to verify the integrity of the ciphertext.
+ * This can be called only when the cipher supports AE. The tag must be set
+ * after calling Cipher#decrypt, Cipher#key= and Cipher#iv=, but before
+ * calling Cipher#final. After all decryption is performed, the tag is
+ * verified automatically in the call to Cipher#final.
*
* For OCB mode, the tag length must be supplied with #auth_tag_len=
* beforehand.
@@ -722,13 +709,6 @@ ossl_cipher_set_iv_length(VALUE self, VALUE iv_length)
return iv_length;
}
-#else
-#define ossl_cipher_set_auth_data rb_f_notimplement
-#define ossl_cipher_get_auth_tag rb_f_notimplement
-#define ossl_cipher_set_auth_tag rb_f_notimplement
-#define ossl_cipher_set_auth_tag_len rb_f_notimplement
-#define ossl_cipher_set_iv_length rb_f_notimplement
-#endif
/*
* call-seq:
@@ -806,10 +786,8 @@ ossl_cipher_iv_length(VALUE self)
int len = 0;
GetCipher(self, ctx);
-#if defined(HAVE_AUTHENTICATED_ENCRYPTION)
if (EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER)
len = (int)(VALUE)EVP_CIPHER_CTX_get_app_data(ctx);
-#endif
if (!len)
len = EVP_CIPHER_CTX_iv_length(ctx);
@@ -1020,9 +998,9 @@ Init_ossl_cipher(void)
* encryption and later decryption, the OpenSSL library still requires a
* value to be set - "" may be used in case none is available.
*
- * 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
+ * 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 guarantees of GCM mode.
*
* cipher = OpenSSL::Cipher::AES.new(128, :GCM).encrypt
@@ -1033,8 +1011,8 @@ Init_ossl_cipher(void)
* encrypted = cipher.update(data) + cipher.final
* tag = cipher.auth_tag # produces 16 bytes tag by default
*
- * Now you are the receiver. You know the +key+ and have received +nonce+,
- * +auth_data+, +encrypted+ and +tag+ through an untrusted network. Note
+ * Now you are the receiver. You know the _key_ and have received _nonce_,
+ * _auth_data_, _encrypted_ and _tag_ through an untrusted network. Note
* that GCM accepts an arbitrary length tag between 1 and 16 bytes. You may
* additionally need to check that the received tag has the correct length,
* or you allow attackers to forge a valid single byte tag for the tampered
@@ -1055,7 +1033,7 @@ Init_ossl_cipher(void)
eCipherError = rb_define_class_under(cCipher, "CipherError", eOSSLError);
rb_define_alloc_func(cCipher, ossl_cipher_alloc);
- rb_define_copy_func(cCipher, ossl_cipher_copy);
+ rb_define_method(cCipher, "initialize_copy", ossl_cipher_copy, 1);
rb_define_module_function(cCipher, "ciphers", ossl_s_ciphers, 0);
rb_define_method(cCipher, "initialize", ossl_cipher_initialize, 1);
rb_define_method(cCipher, "reset", ossl_cipher_reset, 0);
diff --git a/ext/openssl/ossl_cipher.h b/ext/openssl/ossl_cipher.h
index c444089fc2..2392d41c6a 100644
--- a/ext/openssl/ossl_cipher.h
+++ b/ext/openssl/ossl_cipher.h
@@ -13,7 +13,7 @@
extern VALUE cCipher;
extern VALUE eCipherError;
-const EVP_CIPHER *GetCipherPtr(VALUE);
+const EVP_CIPHER *ossl_evp_get_cipherbyname(VALUE);
VALUE ossl_cipher_new(const EVP_CIPHER *);
void Init_ossl_cipher(void);
diff --git a/ext/openssl/ossl_digest.c b/ext/openssl/ossl_digest.c
index fdafda0074..112ce33647 100644
--- a/ext/openssl/ossl_digest.c
+++ b/ext/openssl/ossl_digest.c
@@ -15,10 +15,6 @@
ossl_raise(rb_eRuntimeError, "Digest CTX wasn't initialized!"); \
} \
} while (0)
-#define SafeGetDigest(obj, ctx) do { \
- OSSL_Check_Kind((obj), cDigest); \
- GetDigest((obj), (ctx)); \
-} while (0)
/*
* Classes
@@ -46,7 +42,7 @@ static const rb_data_type_t ossl_digest_type = {
* Public
*/
const EVP_MD *
-GetDigestPtr(VALUE obj)
+ossl_evp_get_digestbyname(VALUE obj)
{
const EVP_MD *md;
ASN1_OBJECT *oid = NULL;
@@ -65,7 +61,7 @@ GetDigestPtr(VALUE obj)
} else {
EVP_MD_CTX *ctx;
- SafeGetDigest(obj, ctx);
+ GetDigest(obj, ctx);
md = EVP_MD_CTX_md(ctx);
}
@@ -106,15 +102,15 @@ VALUE ossl_digest_update(VALUE, VALUE);
* call-seq:
* Digest.new(string [, data]) -> Digest
*
- * Creates a Digest instance based on +string+, which is either the ln
+ * Creates a Digest instance based on _string_, which is either the ln
* (long name) or sn (short name) of a supported digest algorithm.
*
- * If +data+ (a +String+) is given, it is used as the initial input to the
+ * If _data_ (a String) is given, it is used as the initial input to the
* Digest instance, i.e.
*
* digest = OpenSSL::Digest.new('sha256', 'digestdata')
*
- * is equal to
+ * is equivalent to
*
* digest = OpenSSL::Digest.new('sha256')
* digest.update('digestdata')
@@ -127,7 +123,7 @@ ossl_digest_initialize(int argc, VALUE *argv, VALUE self)
VALUE type, data;
rb_scan_args(argc, argv, "11", &type, &data);
- md = GetDigestPtr(type);
+ md = ossl_evp_get_digestbyname(type);
if (!NIL_P(data)) StringValue(data);
TypedData_Get_Struct(self, EVP_MD_CTX, &ossl_digest_type, ctx);
@@ -158,7 +154,7 @@ ossl_digest_copy(VALUE self, VALUE other)
if (!ctx1)
ossl_raise(eDigestError, "EVP_MD_CTX_new");
}
- SafeGetDigest(other, ctx2);
+ GetDigest(other, ctx2);
if (!EVP_MD_CTX_copy(ctx1, ctx2)) {
ossl_raise(eDigestError, NULL);
@@ -448,7 +444,7 @@ Init_ossl_digest(void)
rb_define_alloc_func(cDigest, ossl_digest_alloc);
rb_define_method(cDigest, "initialize", ossl_digest_initialize, -1);
- rb_define_copy_func(cDigest, ossl_digest_copy);
+ rb_define_method(cDigest, "initialize_copy", ossl_digest_copy, 1);
rb_define_method(cDigest, "reset", ossl_digest_reset, 0);
rb_define_method(cDigest, "update", ossl_digest_update, 1);
rb_define_alias(cDigest, "<<", "update");
diff --git a/ext/openssl/ossl_digest.h b/ext/openssl/ossl_digest.h
index 512f7d3a39..50bf5666a3 100644
--- a/ext/openssl/ossl_digest.h
+++ b/ext/openssl/ossl_digest.h
@@ -13,7 +13,7 @@
extern VALUE cDigest;
extern VALUE eDigestError;
-const EVP_MD *GetDigestPtr(VALUE);
+const EVP_MD *ossl_evp_get_digestbyname(VALUE);
VALUE ossl_digest_new(const EVP_MD *);
void Init_ossl_digest(void);
diff --git a/ext/openssl/ossl_engine.c b/ext/openssl/ossl_engine.c
index e840bfd92c..d69b5dcac5 100644
--- a/ext/openssl/ossl_engine.c
+++ b/ext/openssl/ossl_engine.c
@@ -25,10 +25,6 @@
ossl_raise(rb_eRuntimeError, "ENGINE wasn't initialized."); \
} \
} while (0)
-#define SafeGetEngine(obj, engine) do { \
- OSSL_Check_Kind((obj), cEngine); \
- GetPKCS7((obj), (engine)); \
-} while (0)
/*
* Classes
@@ -72,14 +68,13 @@ static const rb_data_type_t ossl_engine_type = {
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
-/* Document-method: OpenSSL::Engine.load
- *
+/*
* call-seq:
- * load(enginename = nil)
+ * OpenSSL::Engine.load(name = nil)
*
- * This method loads engines. If +name+ is nil, then all builtin engines are
- * loaded. Otherwise, the given +name+, as a string, is loaded if available to
- * your runtime, and returns true. If +name+ is not found, then nil is
+ * This method loads engines. If _name_ is nil, then all builtin engines are
+ * loaded. Otherwise, the given _name_, as a String, is loaded if available to
+ * your runtime, and returns true. If _name_ is not found, then nil is
* returned.
*
*/
@@ -153,9 +148,9 @@ ossl_engine_s_load(int argc, VALUE *argv, VALUE klass)
#endif /* HAVE_ENGINE_LOAD_BUILTIN_ENGINES */
}
-/* Document-method: OpenSSL::Engine.cleanup
+/*
* call-seq:
- * OpenSSL::Engine.cleanup
+ * OpenSSL::Engine.cleanup
*
* It is only necessary to run cleanup when engines are loaded via
* OpenSSL::Engine.load. However, running cleanup before exit is recommended.
@@ -169,7 +164,9 @@ ossl_engine_s_cleanup(VALUE self)
return Qnil;
}
-/* Document-method: OpenSSL::Engine.engines
+/*
+ * call-seq:
+ * OpenSSL::Engine.engines -> [engine, ...]
*
* Returns an array of currently loaded engines.
*/
@@ -193,17 +190,16 @@ ossl_engine_s_engines(VALUE klass)
return ary;
}
-/* Document-method: OpenSSL::Engine.by_id
- *
+/*
* call-seq:
- * by_id(name) -> engine
+ * OpenSSL::Engine.by_id(name) -> engine
*
- * Fetch the engine as specified by the +id+ String
+ * Fetches the engine as specified by the _id_ String.
*
* OpenSSL::Engine.by_id("openssl")
* => #<OpenSSL::Engine id="openssl" name="Software engine support">
*
- * See OpenSSL::Engine.engines for the currently loaded engines
+ * See OpenSSL::Engine.engines for the currently loaded engines.
*/
static VALUE
ossl_engine_s_by_id(VALUE klass, VALUE id)
@@ -227,9 +223,11 @@ ossl_engine_s_by_id(VALUE klass, VALUE id)
return obj;
}
-/* Document-method: OpenSSL::Engine#id
+/*
+ * call-seq:
+ * engine.id -> string
*
- * Get the id for this engine
+ * Gets the id for this engine.
*
* OpenSSL::Engine.load
* OpenSSL::Engine.engines #=> [#<OpenSSL::Engine#>, ...]
@@ -244,9 +242,11 @@ ossl_engine_get_id(VALUE self)
return rb_str_new2(ENGINE_get_id(e));
}
-/* Document-method: OpenSSL::Engine#name
+/*
+ * call-seq:
+ * engine.name -> string
*
- * Get the descriptive name for this engine
+ * Get the descriptive name for this engine.
*
* OpenSSL::Engine.load
* OpenSSL::Engine.engines #=> [#<OpenSSL::Engine#>, ...]
@@ -262,7 +262,9 @@ ossl_engine_get_name(VALUE self)
return rb_str_new2(ENGINE_get_name(e));
}
-/* Document-method: OpenSSL::Engine#finish
+/*
+ * call-seq:
+ * engine.finish -> nil
*
* Releases all internal structural references for this engine.
*
@@ -279,13 +281,12 @@ ossl_engine_finish(VALUE self)
return Qnil;
}
-/* Document-method: OpenSSL::Engine#cipher
- *
+/*
* call-seq:
* engine.cipher(name) -> OpenSSL::Cipher
*
- * This returns an OpenSSL::Cipher by +name+, if it is available in this
- * engine.
+ * Returns a new instance of OpenSSL::Cipher by _name_, if it is available in
+ * this engine.
*
* An EngineError will be raised if the cipher is unavailable.
*
@@ -312,12 +313,11 @@ ossl_engine_get_cipher(VALUE self, VALUE name)
return ossl_cipher_new(ciph);
}
-/* Document-method: OpenSSL::Engine#digest
- *
+/*
* call-seq:
* engine.digest(name) -> OpenSSL::Digest
*
- * This returns an OpenSSL::Digest by +name+.
+ * Returns a new instance of OpenSSL::Digest by _name_.
*
* Will raise an EngineError if the digest is unavailable.
*
@@ -345,12 +345,11 @@ ossl_engine_get_digest(VALUE self, VALUE name)
return ossl_digest_new(md);
}
-/* Document-method: OpenSSL::Engine#load_private_key
- *
+/*
* call-seq:
* engine.load_private_key(id = nil, data = nil) -> OpenSSL::PKey
*
- * Loads the given private key by +id+ and +data+.
+ * Loads the given private key identified by _id_ and _data_.
*
* An EngineError is raised of the OpenSSL::PKey is unavailable.
*
@@ -375,12 +374,11 @@ ossl_engine_load_privkey(int argc, VALUE *argv, VALUE self)
return obj;
}
-/* Document-method: OpenSSL::Engine#load_public_key
- *
+/*
* call-seq:
* engine.load_public_key(id = nil, data = nil) -> OpenSSL::PKey
*
- * Loads the given private key by +id+ and +data+.
+ * Loads the given public key identified by _id_ and _data_.
*
* An EngineError is raised of the OpenSSL::PKey is unavailable.
*
@@ -403,16 +401,15 @@ ossl_engine_load_pubkey(int argc, VALUE *argv, VALUE self)
return ossl_pkey_new(pkey);
}
-/* Document-method: OpenSSL::Engine#set_default
- *
+/*
* call-seq:
* engine.set_default(flag)
*
- * Set the defaults for this engine with the given +flag+.
+ * Set the defaults for this engine with the given _flag_.
*
* These flags are used to control combinations of algorithm methods.
*
- * +flag+ can be one of the following, other flags are available depending on
+ * _flag_ can be one of the following, other flags are available depending on
* your OS.
*
* [All flags] 0xFFFF
@@ -432,14 +429,13 @@ ossl_engine_set_default(VALUE self, VALUE flag)
return Qtrue;
}
-/* Document-method: OpenSSL::Engine#ctrl_cmd
- *
+/*
* call-seq:
* engine.ctrl_cmd(command, value = nil) -> engine
*
- * Send the given +command+ to this engine.
+ * Sends the given _command_ to this engine.
*
- * Raises an EngineError if the +command+ fails.
+ * Raises an EngineError if the command fails.
*/
static VALUE
ossl_engine_ctrl_cmd(int argc, VALUE *argv, VALUE self)
@@ -469,7 +465,9 @@ ossl_engine_cmd_flag_to_name(int flag)
}
}
-/* Document-method: OpenSSL::Engine#cmds
+/*
+ * call-seq:
+ * engine.cmds -> [["name", "description", "flags"], ...]
*
* Returns an array of command definitions for the current engine
*/
@@ -495,9 +493,11 @@ ossl_engine_get_cmds(VALUE self)
return ary;
}
-/* Document-method: OpenSSL::Engine#inspect
+/*
+ * call-seq:
+ * engine.inspect -> string
*
- * Pretty print this engine
+ * Pretty prints this engine.
*/
static VALUE
ossl_engine_inspect(VALUE self)
diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c
index 270979ed92..564dcab522 100644
--- a/ext/openssl/ossl_hmac.c
+++ b/ext/openssl/ossl_hmac.c
@@ -19,10 +19,6 @@
ossl_raise(rb_eRuntimeError, "HMAC wasn't initialized"); \
} \
} while (0)
-#define SafeGetHMAC(obj, ctx) do { \
- OSSL_Check_Kind((obj), cHMAC); \
- GetHMAC((obj), (ctx)); \
-} while (0)
/*
* Classes
@@ -110,7 +106,7 @@ ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)
StringValue(key);
GetHMAC(self, ctx);
HMAC_Init_ex(ctx, RSTRING_PTR(key), RSTRING_LENINT(key),
- GetDigestPtr(digest), NULL);
+ ossl_evp_get_digestbyname(digest), NULL);
return self;
}
@@ -124,7 +120,7 @@ ossl_hmac_copy(VALUE self, VALUE other)
if (self == other) return self;
GetHMAC(self, ctx1);
- SafeGetHMAC(other, ctx2);
+ GetHMAC(other, ctx2);
if (!HMAC_CTX_copy(ctx1, ctx2))
ossl_raise(eHMACError, "HMAC_CTX_copy");
@@ -135,7 +131,7 @@ ossl_hmac_copy(VALUE self, VALUE other)
* call-seq:
* hmac.update(string) -> self
*
- * Returns +self+ updated with the message to be authenticated.
+ * Returns _hmac_ updated with the message to be authenticated.
* Can be called repeatedly with chunks of the message.
*
* === Example
@@ -234,7 +230,7 @@ ossl_hmac_hexdigest(VALUE self)
* call-seq:
* hmac.reset -> self
*
- * Returns +self+ as it was when it was first initialized, with all processed
+ * Returns _hmac_ as it was when it was first initialized, with all processed
* data cleared from it.
*
* === Example
@@ -264,16 +260,16 @@ ossl_hmac_reset(VALUE self)
* call-seq:
* HMAC.digest(digest, key, data) -> aString
*
- * Returns the authentication code as a binary string. The +digest+ parameter
- * must be an instance of OpenSSL::Digest.
+ * Returns the authentication code as a binary string. The _digest_ parameter
+ * specifies the digest algorithm to use. This may be a String representing
+ * the algorithm name or an instance of OpenSSL::Digest.
*
* === Example
*
* key = 'key'
* data = 'The quick brown fox jumps over the lazy dog'
- * digest = OpenSSL::Digest.new('sha1')
*
- * hmac = OpenSSL::HMAC.digest(digest, key, data)
+ * hmac = OpenSSL::HMAC.digest('sha1', key, data)
* #=> "\xDE|\x9B\x85\xB8\xB7\x8A\xA6\xBC\x8Az6\xF7\n\x90p\x1C\x9D\xB4\xD9"
*
*/
@@ -285,8 +281,9 @@ ossl_hmac_s_digest(VALUE klass, VALUE digest, VALUE key, VALUE data)
StringValue(key);
StringValue(data);
- buf = HMAC(GetDigestPtr(digest), RSTRING_PTR(key), RSTRING_LENINT(key),
- (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data), NULL, &buf_len);
+ buf = HMAC(ossl_evp_get_digestbyname(digest), RSTRING_PTR(key),
+ RSTRING_LENINT(key), (unsigned char *)RSTRING_PTR(data),
+ RSTRING_LEN(data), NULL, &buf_len);
return rb_str_new((const char *)buf, buf_len);
}
@@ -295,16 +292,16 @@ ossl_hmac_s_digest(VALUE klass, VALUE digest, VALUE key, VALUE data)
* call-seq:
* HMAC.hexdigest(digest, key, data) -> aString
*
- * Returns the authentication code as a hex-encoded string. The +digest+
- * parameter must be an instance of OpenSSL::Digest.
+ * Returns the authentication code as a hex-encoded string. The _digest_
+ * parameter specifies the digest algorithm to use. This may be a String
+ * representing the algorithm name or an instance of OpenSSL::Digest.
*
* === Example
*
* key = 'key'
* data = 'The quick brown fox jumps over the lazy dog'
- * digest = OpenSSL::Digest.new('sha1')
*
- * hmac = OpenSSL::HMAC.hexdigest(digest, key, data)
+ * hmac = OpenSSL::HMAC.hexdigest('sha1', key, data)
* #=> "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9"
*
*/
@@ -318,9 +315,9 @@ ossl_hmac_s_hexdigest(VALUE klass, VALUE digest, VALUE key, VALUE data)
StringValue(key);
StringValue(data);
- if (!HMAC(GetDigestPtr(digest), RSTRING_PTR(key), RSTRING_LENINT(key),
- (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data),
- buf, &buf_len))
+ if (!HMAC(ossl_evp_get_digestbyname(digest), RSTRING_PTR(key),
+ RSTRING_LENINT(key), (unsigned char *)RSTRING_PTR(data),
+ RSTRING_LEN(data), buf, &buf_len))
ossl_raise(eHMACError, "HMAC");
ret = rb_str_new(NULL, buf_len * 2);
@@ -377,7 +374,7 @@ Init_ossl_hmac(void)
rb_define_singleton_method(cHMAC, "hexdigest", ossl_hmac_s_hexdigest, 3);
rb_define_method(cHMAC, "initialize", ossl_hmac_initialize, 2);
- rb_define_copy_func(cHMAC, ossl_hmac_copy);
+ rb_define_method(cHMAC, "initialize_copy", ossl_hmac_copy, 1);
rb_define_method(cHMAC, "reset", ossl_hmac_reset, 0);
rb_define_method(cHMAC, "update", ossl_hmac_update, 1);
diff --git a/ext/openssl/ossl_kdf.c b/ext/openssl/ossl_kdf.c
new file mode 100644
index 0000000000..9fa42e174a
--- /dev/null
+++ b/ext/openssl/ossl_kdf.c
@@ -0,0 +1,221 @@
+/*
+ * Ruby/OpenSSL Project
+ * Copyright (C) 2007, 2017 Ruby/OpenSSL Project Authors
+ */
+#include "ossl.h"
+
+static VALUE mKDF, eKDF;
+
+/*
+ * call-seq:
+ * KDF.pbkdf2_hmac(pass, salt:, iterations:, length:, hash:) -> aString
+ *
+ * PKCS #5 PBKDF2 (Password-Based Key Derivation Function 2) in combination
+ * with HMAC. Takes _pass_, _salt_ and _iterations_, and then derives a key
+ * of _length_ bytes.
+ *
+ * For more information about PBKDF2, see RFC 2898 Section 5.2
+ * (https://tools.ietf.org/html/rfc2898#section-5.2).
+ *
+ * === Parameters
+ * pass :: The passphrase.
+ * salt :: The salt. Salts prevent attacks based on dictionaries of common
+ * passwords and attacks based on rainbow tables. It is a public
+ * value that can be safely stored along with the password (e.g.
+ * if the derived value is used for password storage).
+ * iterations :: The iteration count. This provides the ability to tune the
+ * algorithm. It is better to use the highest count possible for
+ * the maximum resistance to brute-force attacks.
+ * length :: The desired length of the derived key in octets.
+ * hash :: The hash algorithm used with HMAC for the PRF. May be a String
+ * representing the algorithm name, or an instance of
+ * OpenSSL::Digest.
+ */
+static VALUE
+kdf_pbkdf2_hmac(int argc, VALUE *argv, VALUE self)
+{
+ VALUE pass, salt, opts, kwargs[4], str;
+ static ID kwargs_ids[4];
+ int iters, len;
+ const EVP_MD *md;
+
+ if (!kwargs_ids[0]) {
+ kwargs_ids[0] = rb_intern_const("salt");
+ kwargs_ids[1] = rb_intern_const("iterations");
+ kwargs_ids[2] = rb_intern_const("length");
+ kwargs_ids[3] = rb_intern_const("hash");
+ }
+ rb_scan_args(argc, argv, "1:", &pass, &opts);
+ rb_get_kwargs(opts, kwargs_ids, 4, 0, kwargs);
+
+ StringValue(pass);
+ salt = StringValue(kwargs[0]);
+ iters = NUM2INT(kwargs[1]);
+ len = NUM2INT(kwargs[2]);
+ md = ossl_evp_get_digestbyname(kwargs[3]);
+
+ str = rb_str_new(0, len);
+ if (!PKCS5_PBKDF2_HMAC(RSTRING_PTR(pass), RSTRING_LENINT(pass),
+ (unsigned char *)RSTRING_PTR(salt),
+ RSTRING_LENINT(salt), iters, md, len,
+ (unsigned char *)RSTRING_PTR(str)))
+ ossl_raise(eKDF, "PKCS5_PBKDF2_HMAC");
+
+ return str;
+}
+
+#if defined(HAVE_EVP_PBE_SCRYPT)
+/*
+ * call-seq:
+ * KDF.scrypt(pass, salt:, N:, r:, p:, length:) -> aString
+ *
+ * Derives a key from _pass_ using given parameters with the scrypt
+ * password-based key derivation function. The result can be used for password
+ * storage.
+ *
+ * scrypt is designed to be memory-hard and more secure against brute-force
+ * attacks using custom hardwares than alternative KDFs such as PBKDF2 or
+ * 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
+ * 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.
+ *
+ * === Parameters
+ * pass :: Passphrase.
+ * salt :: Salt.
+ * N :: CPU/memory cost parameter. This must be a power of 2.
+ * r :: Block size parameter.
+ * p :: Parallelization parameter.
+ * length :: Length in octets of the derived key.
+ *
+ * === Example
+ * pass = "password"
+ * salt = SecureRandom.random_bytes(16)
+ * dk = OpenSSL::KDF.scrypt(pass, salt: salt, N: 2**14, r: 8, p: 1, length: 32)
+ * p dk #=> "\xDA\xE4\xE2...\x7F\xA1\x01T"
+ */
+static VALUE
+kdf_scrypt(int argc, VALUE *argv, VALUE self)
+{
+ VALUE pass, salt, opts, kwargs[5], str;
+ static ID kwargs_ids[5];
+ size_t len;
+ uint64_t N, r, p, maxmem;
+
+ if (!kwargs_ids[0]) {
+ kwargs_ids[0] = rb_intern_const("salt");
+ kwargs_ids[1] = rb_intern_const("N");
+ kwargs_ids[2] = rb_intern_const("r");
+ kwargs_ids[3] = rb_intern_const("p");
+ kwargs_ids[4] = rb_intern_const("length");
+ }
+ rb_scan_args(argc, argv, "1:", &pass, &opts);
+ rb_get_kwargs(opts, kwargs_ids, 5, 0, kwargs);
+
+ StringValue(pass);
+ salt = StringValue(kwargs[0]);
+ N = NUM2UINT64T(kwargs[1]);
+ r = NUM2UINT64T(kwargs[2]);
+ p = NUM2UINT64T(kwargs[3]);
+ len = NUM2LONG(kwargs[4]);
+ /*
+ * OpenSSL uses 32MB by default (if zero is specified), which is too small.
+ * Let's not limit memory consumption but just let malloc() fail inside
+ * OpenSSL. The amount is controllable by other parameters.
+ */
+ maxmem = SIZE_MAX;
+
+ str = rb_str_new(0, len);
+ if (!EVP_PBE_scrypt(RSTRING_PTR(pass), RSTRING_LEN(pass),
+ (unsigned char *)RSTRING_PTR(salt), RSTRING_LEN(salt),
+ N, r, p, maxmem, (unsigned char *)RSTRING_PTR(str), len))
+ ossl_raise(eKDF, "EVP_PBE_scrypt");
+
+ return str;
+}
+#endif
+
+void
+Init_ossl_kdf(void)
+{
+#if 0
+ mOSSL = rb_define_module("OpenSSL");
+ eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
+#endif
+
+ /*
+ * Document-module: OpenSSL::KDF
+ *
+ * Provides functionality of various KDFs (key derivation function).
+ *
+ * KDF is typically used for securely deriving arbitrary length symmetric
+ * keys to be used with an OpenSSL::Cipher from passwords. Another use case
+ * is for storing passwords: Due to the ability to tweak the effort of
+ * computation by increasing the iteration count, computation can be slowed
+ * down artificially in order to render possible attacks infeasible.
+ *
+ * Currently, OpenSSL::KDF provides implementations for the following KDF:
+ *
+ * * PKCS #5 PBKDF2 (Password-Based Key Derivation Function 2) in
+ * combination with HMAC
+ * * scrypt
+ *
+ * == Examples
+ * === Generating a 128 bit key for a Cipher (e.g. AES)
+ * pass = "secret"
+ * salt = OpenSSL::Random.random_bytes(16)
+ * iter = 20_000
+ * key_len = 16
+ * key = OpenSSL::KDF.pbkdf2_hmac(pass, salt: salt, iterations: iter,
+ * length: key_len, hash: "sha1")
+ *
+ * === Storing Passwords
+ * pass = "secret"
+ * # store this with the generated value
+ * salt = OpenSSL::Random.random_bytes(16)
+ * iter = 20_000
+ * hash = OpenSSL::Digest::SHA256.new
+ * len = hash.digest_length
+ * # the final value to be stored
+ * value = OpenSSL::KDF.pbkdf2_hmac(pass, salt: salt, iterations: iter,
+ * length: len, hash: hash)
+ *
+ * == Important Note on Checking Passwords
+ * When comparing passwords provided by the user with previously stored
+ * values, a common mistake made is comparing the two values using "==".
+ * Typically, "==" short-circuits on evaluation, and is therefore
+ * vulnerable to timing attacks. The proper way is to use a method that
+ * always takes the same amount of time when comparing two values, thus
+ * not leaking any information to potential attackers. To compare two
+ * values, the following could be used:
+ *
+ * def eql_time_cmp(a, b)
+ * unless a.length == b.length
+ * return false
+ * end
+ * cmp = b.bytes
+ * result = 0
+ * a.bytes.each_with_index {|c,i|
+ * result |= c ^ cmp[i]
+ * }
+ * result == 0
+ * end
+ *
+ * Please note that the premature return in case of differing lengths
+ * typically does not leak valuable information - when using PBKDF2, the
+ * length of the values to be compared is of fixed size.
+ */
+ mKDF = rb_define_module_under(mOSSL, "KDF");
+ /*
+ * Generic exception class raised if an error occurs in OpenSSL::KDF module.
+ */
+ eKDF = rb_define_class_under(mKDF, "KDFError", eOSSLError);
+
+ rb_define_module_function(mKDF, "pbkdf2_hmac", kdf_pbkdf2_hmac, -1);
+#if defined(HAVE_EVP_PBE_SCRYPT)
+ rb_define_module_function(mKDF, "scrypt", kdf_scrypt, -1);
+#endif
+}
diff --git a/ext/openssl/ossl_kdf.h b/ext/openssl/ossl_kdf.h
new file mode 100644
index 0000000000..b6503f8d9d
--- /dev/null
+++ b/ext/openssl/ossl_kdf.h
@@ -0,0 +1,6 @@
+#if !defined(OSSL_KDF_H)
+#define OSSL_KDF_H
+
+void Init_ossl_kdf(void);
+
+#endif
diff --git a/ext/openssl/ossl_ns_spki.c b/ext/openssl/ossl_ns_spki.c
index 4d978bd009..f17b9509c6 100644
--- a/ext/openssl/ossl_ns_spki.c
+++ b/ext/openssl/ossl_ns_spki.c
@@ -73,7 +73,7 @@ ossl_spki_alloc(VALUE klass)
* SPKI.new([request]) => spki
*
* === Parameters
- * * +request+ - optional raw request, either in PEM or DER format.
+ * * _request_ - optional raw request, either in PEM or DER format.
*/
static VALUE
ossl_spki_initialize(int argc, VALUE *argv, VALUE self)
@@ -198,7 +198,7 @@ ossl_spki_get_public_key(VALUE self)
* spki.public_key = pub => pkey
*
* === Parameters
- * * +pub+ - the public key to be set for this instance
+ * * _pub_ - the public key to be set for this instance
*
* Sets the public key to be associated with the SPKI, an instance of
* OpenSSL::PKey. This should be the public key corresponding to the
@@ -243,7 +243,7 @@ ossl_spki_get_challenge(VALUE self)
* spki.challenge = str => string
*
* === Parameters
- * * +str+ - the challenge string to be set for this instance
+ * * _str_ - the challenge string to be set for this instance
*
* Sets the challenge to be associated with the SPKI. May be used by the
* server, e.g. to prevent replay.
@@ -268,8 +268,8 @@ ossl_spki_set_challenge(VALUE self, VALUE str)
* spki.sign(key, digest) => spki
*
* === Parameters
- * * +key+ - the private key to be used for signing this instance
- * * +digest+ - the digest to be used for signing this instance
+ * * _key_ - the private key to be used for signing this instance
+ * * _digest_ - the digest to be used for signing this instance
*
* To sign an SPKI, the private key corresponding to the public key set
* for this instance should be used, in addition to a digest algorithm in
@@ -284,7 +284,7 @@ ossl_spki_sign(VALUE self, VALUE key, VALUE digest)
const EVP_MD *md;
pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
- md = GetDigestPtr(digest);
+ md = ossl_evp_get_digestbyname(digest);
GetSPKI(self, spki);
if (!NETSCAPE_SPKI_sign(spki, pkey, md)) {
ossl_raise(eSPKIError, NULL);
@@ -298,7 +298,7 @@ ossl_spki_sign(VALUE self, VALUE key, VALUE digest)
* spki.verify(key) => boolean
*
* === Parameters
- * * +key+ - the public key to be used for verifying the SPKI signature
+ * * _key_ - the public key to be used for verifying the SPKI signature
*
* Returns +true+ if the signature is valid, +false+ otherwise. To verify an
* SPKI, the public key contained within the SPKI should be used.
diff --git a/ext/openssl/ossl_ocsp.c b/ext/openssl/ossl_ocsp.c
index a8b3503d2a..c0237791da 100644
--- a/ext/openssl/ossl_ocsp.c
+++ b/ext/openssl/ossl_ocsp.c
@@ -22,10 +22,6 @@
TypedData_Get_Struct((obj), OCSP_REQUEST, &ossl_ocsp_request_type, (req)); \
if(!(req)) ossl_raise(rb_eRuntimeError, "Request wasn't initialized!"); \
} while (0)
-#define SafeGetOCSPReq(obj, req) do { \
- OSSL_Check_Kind((obj), cOCSPReq); \
- GetOCSPReq((obj), (req)); \
-} while (0)
#define NewOCSPRes(klass) \
TypedData_Wrap_Struct((klass), &ossl_ocsp_response_type, 0)
@@ -37,10 +33,6 @@
TypedData_Get_Struct((obj), OCSP_RESPONSE, &ossl_ocsp_response_type, (res)); \
if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
} while (0)
-#define SafeGetOCSPRes(obj, res) do { \
- OSSL_Check_Kind((obj), cOCSPRes); \
- GetOCSPRes((obj), (res)); \
-} while (0)
#define NewOCSPBasicRes(klass) \
TypedData_Wrap_Struct((klass), &ossl_ocsp_basicresp_type, 0)
@@ -52,10 +44,6 @@
TypedData_Get_Struct((obj), OCSP_BASICRESP, &ossl_ocsp_basicresp_type, (res)); \
if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \
} while (0)
-#define SafeGetOCSPBasicRes(obj, res) do { \
- OSSL_Check_Kind((obj), cOCSPBasicRes); \
- GetOCSPBasicRes((obj), (res)); \
-} while (0)
#define NewOCSPSingleRes(klass) \
TypedData_Wrap_Struct((klass), &ossl_ocsp_singleresp_type, 0)
@@ -67,10 +55,6 @@
TypedData_Get_Struct((obj), OCSP_SINGLERESP, &ossl_ocsp_singleresp_type, (res)); \
if(!(res)) ossl_raise(rb_eRuntimeError, "SingleResponse wasn't initialized!"); \
} while (0)
-#define SafeGetOCSPSingleRes(obj, res) do { \
- OSSL_Check_Kind((obj), cOCSPSingleRes); \
- GetOCSPSingleRes((obj), (res)); \
-} while (0)
#define NewOCSPCertId(klass) \
TypedData_Wrap_Struct((klass), &ossl_ocsp_certid_type, 0)
@@ -82,10 +66,6 @@
TypedData_Get_Struct((obj), OCSP_CERTID, &ossl_ocsp_certid_type, (cid)); \
if(!(cid)) ossl_raise(rb_eRuntimeError, "Cert ID wasn't initialized!"); \
} while (0)
-#define SafeGetOCSPCertId(obj, cid) do { \
- OSSL_Check_Kind((obj), cOCSPCertId); \
- GetOCSPCertId((obj), (cid)); \
-} while (0)
VALUE mOCSP;
VALUE eOCSPError;
@@ -200,7 +180,7 @@ ossl_ocspreq_initialize_copy(VALUE self, VALUE other)
rb_check_frozen(self);
GetOCSPReq(self, req_old);
- SafeGetOCSPReq(other, req);
+ GetOCSPReq(other, req);
req_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_REQUEST), req);
if (!req_new)
@@ -218,7 +198,7 @@ ossl_ocspreq_initialize_copy(VALUE self, VALUE other)
* OpenSSL::OCSP::Request.new(request_der) -> request
*
* Creates a new OpenSSL::OCSP::Request. The request may be created empty or
- * from a +request_der+ string.
+ * from a _request_der_ string.
*/
static VALUE
@@ -248,7 +228,7 @@ ossl_ocspreq_initialize(int argc, VALUE *argv, VALUE self)
* call-seq:
* request.add_nonce(nonce = nil) -> request
*
- * Adds a +nonce+ to the OCSP request. If no nonce is given a random one will
+ * Adds a _nonce_ to the OCSP request. If no nonce is given a random one will
* be generated.
*
* The nonce is used to prevent replay attacks but some servers do not support
@@ -281,7 +261,7 @@ ossl_ocspreq_add_nonce(int argc, VALUE *argv, VALUE self)
* call-seq:
* request.check_nonce(response) -> result
*
- * Checks the nonce validity for this request and +response+.
+ * Checks the nonce validity for this request and _response_.
*
* The return value is one of the following:
*
@@ -291,7 +271,7 @@ ossl_ocspreq_add_nonce(int argc, VALUE *argv, VALUE self)
* 2 :: nonces both absent.
* 3 :: nonce present in response only.
*
- * For most responses, clients can check +result+ > 0. If a responder doesn't
+ * For most responses, clients can check _result_ > 0. If a responder doesn't
* handle nonces <code>result.nonzero?</code> may be necessary. A result of
* <code>0</code> is always an error.
*/
@@ -304,7 +284,7 @@ ossl_ocspreq_check_nonce(VALUE self, VALUE basic_resp)
int res;
GetOCSPReq(self, req);
- SafeGetOCSPBasicRes(basic_resp, bs);
+ GetOCSPBasicRes(basic_resp, bs);
res = OCSP_check_nonce(req, bs);
return INT2NUM(res);
@@ -314,7 +294,7 @@ ossl_ocspreq_check_nonce(VALUE self, VALUE basic_resp)
* call-seq:
* request.add_certid(certificate_id) -> request
*
- * Adds +certificate_id+ to the request.
+ * Adds _certificate_id_ to the request.
*/
static VALUE
@@ -371,17 +351,17 @@ ossl_ocspreq_get_certid(VALUE self)
* call-seq:
* request.sign(cert, key, certs = nil, flags = 0, digest = nil) -> self
*
- * Signs this OCSP request using +cert+, +key+ and optional +digest+. If
- * +digest+ is not specified, SHA-1 is used. +certs+ is an optional Array of
+ * Signs this OCSP request using _cert_, _key_ and optional _digest_. If
+ * _digest_ is not specified, SHA-1 is used. _certs_ is an optional Array of
* additional certificates which are included in the request in addition to
- * the signer certificate. Note that if +certs+ is nil or not given, flag
+ * the signer certificate. Note that if _certs_ is +nil+ or not given, flag
* OpenSSL::OCSP::NOCERTS is enabled. Pass an empty array to include only the
* signer certificate.
*
- * +flags+ can be a bitwise OR of the following constants:
+ * _flags_ is a bitwise OR of the following constants:
*
* OpenSSL::OCSP::NOCERTS::
- * Don't include any certificates in the request. +certs+ will be ignored.
+ * Don't include any certificates in the request. _certs_ will be ignored.
*/
static VALUE
ossl_ocspreq_sign(int argc, VALUE *argv, VALUE self)
@@ -404,7 +384,7 @@ ossl_ocspreq_sign(int argc, VALUE *argv, VALUE self)
if (NIL_P(digest))
md = EVP_sha1();
else
- md = GetDigestPtr(digest);
+ md = ossl_evp_get_digestbyname(digest);
if (NIL_P(certs))
flg |= OCSP_NOCERTS;
else
@@ -421,9 +401,12 @@ ossl_ocspreq_sign(int argc, VALUE *argv, VALUE self)
* call-seq:
* request.verify(certificates, store, flags = 0) -> true or false
*
- * Verifies this request using the given +certificates+ and +store+.
- * +certificates+ is an array of OpenSSL::X509::Certificate, +store+ is an
+ * Verifies this request using the given _certificates_ and _store_.
+ * _certificates_ is an array of OpenSSL::X509::Certificate, _store_ is an
* OpenSSL::X509::Store.
+ *
+ * Note that +false+ is returned if the request does not have a signature.
+ * Use #signed? to check whether the request is signed or not.
*/
static VALUE
@@ -473,13 +456,29 @@ ossl_ocspreq_to_der(VALUE self)
}
/*
+ * call-seq:
+ * request.signed? -> true or false
+ *
+ * Returns +true+ if the request is signed, +false+ otherwise. Note that the
+ * validity of the signature is *not* checked. Use #verify to verify that.
+ */
+static VALUE
+ossl_ocspreq_signed_p(VALUE self)
+{
+ OCSP_REQUEST *req;
+
+ GetOCSPReq(self, req);
+ return OCSP_request_is_signed(req) ? Qtrue : Qfalse;
+}
+
+/*
* OCSP::Response
*/
/* call-seq:
* OpenSSL::OCSP::Response.create(status, basic_response = nil) -> response
*
- * Creates an OpenSSL::OCSP::Response from +status+ and +basic_response+.
+ * Creates an OpenSSL::OCSP::Response from _status_ and _basic_response_.
*/
static VALUE
@@ -521,7 +520,7 @@ ossl_ocspres_initialize_copy(VALUE self, VALUE other)
rb_check_frozen(self);
GetOCSPRes(self, res_old);
- SafeGetOCSPRes(other, res);
+ GetOCSPRes(other, res);
res_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_RESPONSE), res);
if (!res_new)
@@ -539,7 +538,7 @@ ossl_ocspres_initialize_copy(VALUE self, VALUE other)
* OpenSSL::OCSP::Response.new(response_der) -> response
*
* Creates a new OpenSSL::OCSP::Response. The response may be created empty or
- * from a +response_der+ string.
+ * from a _response_der_ string.
*/
static VALUE
@@ -677,7 +676,7 @@ ossl_ocspbres_initialize_copy(VALUE self, VALUE other)
rb_check_frozen(self);
GetOCSPBasicRes(self, bs_old);
- SafeGetOCSPBasicRes(other, bs);
+ GetOCSPBasicRes(other, bs);
bs_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_BASICRESP), bs);
if (!bs_new)
@@ -693,7 +692,7 @@ ossl_ocspbres_initialize_copy(VALUE self, VALUE other)
* call-seq:
* OpenSSL::OCSP::BasicResponse.new(der_string = nil) -> basic_response
*
- * Creates a new BasicResponse. If +der_string+ is given, decodes +der_string+
+ * Creates a new BasicResponse. If _der_string_ is given, decodes _der_string_
* as DER.
*/
@@ -724,7 +723,7 @@ ossl_ocspbres_initialize(int argc, VALUE *argv, VALUE self)
* call-seq:
* basic_response.copy_nonce(request) -> Integer
*
- * Copies the nonce from +request+ into this response. Returns 1 on success
+ * Copies the nonce from _request_ into this response. Returns 1 on success
* and 0 on failure.
*/
@@ -736,7 +735,7 @@ ossl_ocspbres_copy_nonce(VALUE self, VALUE request)
int ret;
GetOCSPBasicRes(self, bs);
- SafeGetOCSPReq(request, req);
+ GetOCSPReq(request, req);
ret = OCSP_copy_nonce(bs, req);
return INT2NUM(ret);
@@ -746,7 +745,7 @@ ossl_ocspbres_copy_nonce(VALUE self, VALUE request)
* call-seq:
* basic_response.add_nonce(nonce = nil)
*
- * Adds +nonce+ to this response. If no nonce was provided a random nonce
+ * Adds _nonce_ to this response. If no nonce was provided a random nonce
* will be added.
*/
@@ -792,26 +791,26 @@ add_status_convert_time(VALUE obj)
* call-seq:
* basic_response.add_status(certificate_id, status, reason, revocation_time, this_update, next_update, extensions) -> basic_response
*
- * Adds a certificate status for +certificate_id+. +status+ is the status, and
+ * Adds a certificate status for _certificate_id_. _status_ is the status, and
* must be one of these:
*
* - OpenSSL::OCSP::V_CERTSTATUS_GOOD
* - OpenSSL::OCSP::V_CERTSTATUS_REVOKED
* - OpenSSL::OCSP::V_CERTSTATUS_UNKNOWN
*
- * +reason+ and +revocation_time+ can be given only when +status+ is
- * OpenSSL::OCSP::V_CERTSTATUS_REVOKED. +reason+ describes the reason for the
+ * _reason_ and _revocation_time_ can be given only when _status_ is
+ * OpenSSL::OCSP::V_CERTSTATUS_REVOKED. _reason_ describes the reason for the
* revocation, and must be one of OpenSSL::OCSP::REVOKED_STATUS_* constants.
- * +revocation_time+ is the time when the certificate is revoked.
+ * _revocation_time_ is the time when the certificate is revoked.
*
- * +this_update+ and +next_update+ indicate the time at which ths status is
+ * _this_update_ and _next_update_ indicate the time at which ths status is
* verified to be correct and the time at or before which newer information
- * will be available, respectively. +next_update+ is optional.
+ * will be available, respectively. _next_update_ is optional.
*
- * +extensions+ is an Array of OpenSSL::X509::Extension to be included in the
+ * _extensions_ is an Array of OpenSSL::X509::Extension to be included in the
* SingleResponse. This is also optional.
*
- * Note that the times, +revocation_time+, +this_update+ and +next_update+
+ * Note that the times, _revocation_time_, _this_update_ and _next_update_
* can be specified in either of Integer or Time object. If they are Integer, it
* is treated as the relative seconds from the current time.
*/
@@ -829,7 +828,7 @@ ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status,
VALUE tmp;
GetOCSPBasicRes(self, bs);
- SafeGetOCSPCertId(cid, id);
+ GetOCSPCertId(cid, id);
st = NUM2INT(status);
if (!NIL_P(ext)) { /* All ext's members must be X509::Extension */
ext = rb_check_array_type(ext);
@@ -888,7 +887,7 @@ ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status,
* Returns an Array of statuses for this response. Each status contains a
* CertificateId, the status (0 for good, 1 for revoked, 2 for unknown), the
* reason for the status, the revocation time, the time of this update, the time
- * for the next update and a list of OpenSSL::X509::Extensions.
+ * for the next update and a list of OpenSSL::X509::Extension.
*
* This should be superseded by BasicResponse#responses and #find_response that
* return SingleResponse.
@@ -977,7 +976,7 @@ ossl_ocspbres_get_responses(VALUE self)
* call-seq:
* basic_response.find_response(certificate_id) -> SingleResponse | nil
*
- * Returns a SingleResponse whose CertId matches with +certificate_id+, or nil
+ * Returns a SingleResponse whose CertId matches with _certificate_id_, or +nil+
* if this BasicResponse does not contain it.
*/
static VALUE
@@ -988,7 +987,7 @@ ossl_ocspbres_find_response(VALUE self, VALUE target)
OCSP_CERTID *id;
int n;
- SafeGetOCSPCertId(target, id);
+ GetOCSPCertId(target, id);
GetOCSPBasicRes(self, bs);
if ((n = OCSP_resp_find(bs, id, -1)) == -1)
@@ -1006,10 +1005,10 @@ ossl_ocspbres_find_response(VALUE self, VALUE target)
* call-seq:
* basic_response.sign(cert, key, certs = nil, flags = 0, digest = nil) -> self
*
- * Signs this OCSP response using the +cert+, +key+ and optional +digest+. This
+ * Signs this OCSP response using the _cert_, _key_ and optional _digest_. This
* behaves in the similar way as OpenSSL::OCSP::Request#sign.
*
- * +flags+ can include:
+ * _flags_ can include:
* OpenSSL::OCSP::NOCERTS:: don't include certificates
* OpenSSL::OCSP::NOTIME:: don't set producedAt
* OpenSSL::OCSP::RESPID_KEY:: use signer's public key hash as responderID
@@ -1036,7 +1035,7 @@ ossl_ocspbres_sign(int argc, VALUE *argv, VALUE self)
if (NIL_P(digest))
md = EVP_sha1();
else
- md = GetDigestPtr(digest);
+ md = ossl_evp_get_digestbyname(digest);
if (NIL_P(certs))
flg |= OCSP_NOCERTS;
else
@@ -1053,8 +1052,8 @@ ossl_ocspbres_sign(int argc, VALUE *argv, VALUE self)
* call-seq:
* basic_response.verify(certificates, store, flags = 0) -> true or false
*
- * Verifies the signature of the response using the given +certificates+ and
- * +store+. This works in the similar way as OpenSSL::OCSP::Request#verify.
+ * Verifies the signature of the response using the given _certificates_ and
+ * _store_. This works in the similar way as OpenSSL::OCSP::Request#verify.
*/
static VALUE
ossl_ocspbres_verify(int argc, VALUE *argv, VALUE self)
@@ -1184,7 +1183,7 @@ ossl_ocspsres_alloc(VALUE klass)
* call-seq:
* OpenSSL::OCSP::SingleResponse.new(der_string) -> SingleResponse
*
- * Creates a new SingleResponse from +der_string+.
+ * Creates a new SingleResponse from _der_string_.
*/
static VALUE
ossl_ocspsres_initialize(VALUE self, VALUE arg)
@@ -1213,7 +1212,7 @@ ossl_ocspsres_initialize_copy(VALUE self, VALUE other)
rb_check_frozen(self);
GetOCSPSingleRes(self, sres_old);
- SafeGetOCSPSingleRes(other, sres);
+ GetOCSPSingleRes(other, sres);
sres_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_SINGLERESP), sres);
if (!sres_new)
@@ -1235,10 +1234,10 @@ ossl_ocspsres_initialize_copy(VALUE self, VALUE other)
*
* It is possible that the OCSP request takes a few seconds or the time is not
* accurate. To avoid rejecting a valid response, this method allows the times
- * to be within +nsec+ of the current time.
+ * to be within _nsec_ seconds of the current time.
*
* Some responders don't set the nextUpdate field. This may cause a very old
- * response to be considered valid. The +maxsec+ parameter can be used to limit
+ * response to be considered valid. The _maxsec_ parameter can be used to limit
* the age of responses.
*/
static VALUE
@@ -1329,8 +1328,10 @@ ossl_ocspsres_get_this_update(VALUE self)
status = OCSP_single_get0_status(sres, NULL, NULL, &time, NULL);
if (status < 0)
ossl_raise(eOCSPError, "OCSP_single_get0_status");
+ if (!time)
+ return Qnil;
- return asn1time_to_time(time); /* will handle NULL */
+ return asn1time_to_time(time);
}
/*
@@ -1348,6 +1349,8 @@ ossl_ocspsres_get_next_update(VALUE self)
status = OCSP_single_get0_status(sres, NULL, NULL, NULL, &time);
if (status < 0)
ossl_raise(eOCSPError, "OCSP_single_get0_status");
+ if (!time)
+ return Qnil;
return asn1time_to_time(time);
}
@@ -1369,6 +1372,8 @@ ossl_ocspsres_get_revocation_time(VALUE self)
ossl_raise(eOCSPError, "OCSP_single_get0_status");
if (status != V_OCSP_CERTSTATUS_REVOKED)
ossl_raise(eOCSPError, "certificate is not revoked");
+ if (!time)
+ return Qnil;
return asn1time_to_time(time);
}
@@ -1468,7 +1473,7 @@ ossl_ocspcid_initialize_copy(VALUE self, VALUE other)
rb_check_frozen(self);
GetOCSPCertId(self, cid_old);
- SafeGetOCSPCertId(other, cid);
+ GetOCSPCertId(other, cid);
cid_new = OCSP_CERTID_dup(cid);
if (!cid_new)
@@ -1485,14 +1490,13 @@ ossl_ocspcid_initialize_copy(VALUE self, VALUE other)
* OpenSSL::OCSP::CertificateId.new(subject, issuer, digest = nil) -> certificate_id
* OpenSSL::OCSP::CertificateId.new(der_string) -> certificate_id
*
- * Creates a new OpenSSL::OCSP::CertificateId for the given +subject+ and
- * +issuer+ X509 certificates. The +digest+ is used to compute the
- * certificate ID and must be an OpenSSL::Digest instance.
+ * Creates a new OpenSSL::OCSP::CertificateId for the given _subject_ and
+ * _issuer_ X509 certificates. The _digest_ is a digest algorithm that is used
+ * to compute the hash values. This defaults to SHA-1.
*
* If only one argument is given, decodes it as DER representation of a
* certificate ID.
*/
-
static VALUE
ossl_ocspcid_initialize(int argc, VALUE *argv, VALUE self)
{
@@ -1517,7 +1521,7 @@ ossl_ocspcid_initialize(int argc, VALUE *argv, VALUE self)
x509s = GetX509CertPtr(subject); /* NO NEED TO DUP */
x509i = GetX509CertPtr(issuer); /* NO NEED TO DUP */
- md = !NIL_P(digest) ? GetDigestPtr(digest) : NULL;
+ md = !NIL_P(digest) ? ossl_evp_get_digestbyname(digest) : NULL;
newid = OCSP_cert_to_id(md, x509s, x509i);
if (!newid)
@@ -1534,7 +1538,7 @@ ossl_ocspcid_initialize(int argc, VALUE *argv, VALUE self)
* call-seq:
* certificate_id.cmp(other) -> true or false
*
- * Compares this certificate id with +other+ and returns true if they are the
+ * Compares this certificate id with _other_ and returns +true+ if they are the
* same.
*/
static VALUE
@@ -1544,7 +1548,7 @@ ossl_ocspcid_cmp(VALUE self, VALUE other)
int result;
GetOCSPCertId(self, id);
- SafeGetOCSPCertId(other, id2);
+ GetOCSPCertId(other, id2);
result = OCSP_id_cmp(id, id2);
return (result == 0) ? Qtrue : Qfalse;
@@ -1554,7 +1558,7 @@ ossl_ocspcid_cmp(VALUE self, VALUE other)
* call-seq:
* certificate_id.cmp_issuer(other) -> true or false
*
- * Compares this certificate id's issuer with +other+ and returns true if
+ * Compares this certificate id's issuer with _other_ and returns +true+ if
* they are the same.
*/
@@ -1565,7 +1569,7 @@ ossl_ocspcid_cmp_issuer(VALUE self, VALUE other)
int result;
GetOCSPCertId(self, id);
- SafeGetOCSPCertId(other, id2);
+ GetOCSPCertId(other, id2);
result = OCSP_id_issuer_cmp(id, id2);
return (result == 0) ? Qtrue : Qfalse;
@@ -1824,12 +1828,13 @@ Init_ossl_ocsp(void)
cOCSPReq = rb_define_class_under(mOCSP, "Request", rb_cObject);
rb_define_alloc_func(cOCSPReq, ossl_ocspreq_alloc);
- rb_define_copy_func(cOCSPReq, ossl_ocspreq_initialize_copy);
+ rb_define_method(cOCSPReq, "initialize_copy", ossl_ocspreq_initialize_copy, 1);
rb_define_method(cOCSPReq, "initialize", ossl_ocspreq_initialize, -1);
rb_define_method(cOCSPReq, "add_nonce", ossl_ocspreq_add_nonce, -1);
rb_define_method(cOCSPReq, "check_nonce", ossl_ocspreq_check_nonce, 1);
rb_define_method(cOCSPReq, "add_certid", ossl_ocspreq_add_certid, 1);
rb_define_method(cOCSPReq, "certid", ossl_ocspreq_get_certid, 0);
+ rb_define_method(cOCSPReq, "signed?", ossl_ocspreq_signed_p, 0);
rb_define_method(cOCSPReq, "sign", ossl_ocspreq_sign, -1);
rb_define_method(cOCSPReq, "verify", ossl_ocspreq_verify, -1);
rb_define_method(cOCSPReq, "to_der", ossl_ocspreq_to_der, 0);
@@ -1842,7 +1847,7 @@ Init_ossl_ocsp(void)
cOCSPRes = rb_define_class_under(mOCSP, "Response", rb_cObject);
rb_define_singleton_method(cOCSPRes, "create", ossl_ocspres_s_create, 2);
rb_define_alloc_func(cOCSPRes, ossl_ocspres_alloc);
- rb_define_copy_func(cOCSPRes, ossl_ocspres_initialize_copy);
+ rb_define_method(cOCSPRes, "initialize_copy", ossl_ocspres_initialize_copy, 1);
rb_define_method(cOCSPRes, "initialize", ossl_ocspres_initialize, -1);
rb_define_method(cOCSPRes, "status", ossl_ocspres_status, 0);
rb_define_method(cOCSPRes, "status_string", ossl_ocspres_status_string, 0);
@@ -1857,7 +1862,7 @@ Init_ossl_ocsp(void)
cOCSPBasicRes = rb_define_class_under(mOCSP, "BasicResponse", rb_cObject);
rb_define_alloc_func(cOCSPBasicRes, ossl_ocspbres_alloc);
- rb_define_copy_func(cOCSPBasicRes, ossl_ocspbres_initialize_copy);
+ rb_define_method(cOCSPBasicRes, "initialize_copy", ossl_ocspbres_initialize_copy, 1);
rb_define_method(cOCSPBasicRes, "initialize", ossl_ocspbres_initialize, -1);
rb_define_method(cOCSPBasicRes, "copy_nonce", ossl_ocspbres_copy_nonce, 1);
rb_define_method(cOCSPBasicRes, "add_nonce", ossl_ocspbres_add_nonce, -1);
@@ -1876,7 +1881,7 @@ Init_ossl_ocsp(void)
*/
cOCSPSingleRes = rb_define_class_under(mOCSP, "SingleResponse", rb_cObject);
rb_define_alloc_func(cOCSPSingleRes, ossl_ocspsres_alloc);
- rb_define_copy_func(cOCSPSingleRes, ossl_ocspsres_initialize_copy);
+ rb_define_method(cOCSPSingleRes, "initialize_copy", ossl_ocspsres_initialize_copy, 1);
rb_define_method(cOCSPSingleRes, "initialize", ossl_ocspsres_initialize, 1);
rb_define_method(cOCSPSingleRes, "check_validity", ossl_ocspsres_check_validity, -1);
rb_define_method(cOCSPSingleRes, "certid", ossl_ocspsres_get_certid, 0);
@@ -1895,7 +1900,7 @@ Init_ossl_ocsp(void)
cOCSPCertId = rb_define_class_under(mOCSP, "CertificateId", rb_cObject);
rb_define_alloc_func(cOCSPCertId, ossl_ocspcid_alloc);
- rb_define_copy_func(cOCSPCertId, ossl_ocspcid_initialize_copy);
+ rb_define_method(cOCSPCertId, "initialize_copy", ossl_ocspcid_initialize_copy, 1);
rb_define_method(cOCSPCertId, "initialize", ossl_ocspcid_initialize, -1);
rb_define_method(cOCSPCertId, "cmp", ossl_ocspcid_cmp, 1);
rb_define_method(cOCSPCertId, "cmp_issuer", ossl_ocspcid_cmp_issuer, 1);
diff --git a/ext/openssl/ossl_pkcs12.c b/ext/openssl/ossl_pkcs12.c
index 8502a6de0d..ddb7d939cf 100644
--- a/ext/openssl/ossl_pkcs12.c
+++ b/ext/openssl/ossl_pkcs12.c
@@ -17,11 +17,6 @@
if(!(p12)) ossl_raise(rb_eRuntimeError, "PKCS12 wasn't initialized."); \
} while (0)
-#define SafeGetPKCS12(obj, p12) do { \
- OSSL_Check_Kind((obj), cPKCS12); \
- GetPKCS12((obj), (p12)); \
-} while (0)
-
#define ossl_pkcs12_set_key(o,v) rb_iv_set((o), "@key", (v))
#define ossl_pkcs12_set_cert(o,v) rb_iv_set((o), "@certificate", (v))
#define ossl_pkcs12_set_ca_certs(o,v) rb_iv_set((o), "@ca_certs", (v))
@@ -72,7 +67,7 @@ ossl_pkcs12_initialize_copy(VALUE self, VALUE other)
rb_check_frozen(self);
GetPKCS12(self, p12_old);
- SafeGetPKCS12(other, p12);
+ GetPKCS12(other, p12);
p12_new = ASN1_dup((i2d_of_void *)i2d_PKCS12, (d2i_of_void *)d2i_PKCS12, (char *)p12);
if (!p12_new)
@@ -89,20 +84,20 @@ ossl_pkcs12_initialize_copy(VALUE self, VALUE other)
* PKCS12.create(pass, name, key, cert [, ca, [, key_pbe [, cert_pbe [, key_iter [, mac_iter [, keytype]]]]]])
*
* === Parameters
- * * +pass+ - string
- * * +name+ - A string describing the key.
- * * +key+ - Any PKey.
- * * +cert+ - A X509::Certificate.
+ * * _pass_ - string
+ * * _name_ - A string describing the key.
+ * * _key_ - Any PKey.
+ * * _cert_ - A X509::Certificate.
* * The public_key portion of the certificate must contain a valid public key.
* * The not_before and not_after fields must be filled in.
- * * +ca+ - An optional array of X509::Certificate's.
- * * +key_pbe+ - string
- * * +cert_pbe+ - string
- * * +key_iter+ - integer
- * * +mac_iter+ - integer
- * * +keytype+ - An integer representing an MSIE specific extension.
+ * * _ca_ - An optional array of X509::Certificate's.
+ * * _key_pbe_ - string
+ * * _cert_pbe_ - string
+ * * _key_iter_ - integer
+ * * _mac_iter_ - integer
+ * * _keytype_ - An integer representing an MSIE specific extension.
*
- * Any optional arguments may be supplied as nil to preserve the OpenSSL defaults.
+ * Any optional arguments may be supplied as +nil+ to preserve the OpenSSL defaults.
*
* See the OpenSSL documentation for PKCS12_create().
*/
@@ -161,8 +156,8 @@ ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self)
* PKCS12.new(str, pass) -> pkcs12
*
* === Parameters
- * * +str+ - Must be a DER encoded PKCS12 string.
- * * +pass+ - string
+ * * _str_ - Must be a DER encoded PKCS12 string.
+ * * _pass_ - string
*/
static VALUE
ossl_pkcs12_initialize(int argc, VALUE *argv, VALUE self)
@@ -252,7 +247,7 @@ Init_ossl_pkcs12(void)
rb_define_singleton_method(cPKCS12, "create", ossl_pkcs12_s_create, -1);
rb_define_alloc_func(cPKCS12, ossl_pkcs12_s_allocate);
- rb_define_copy_func(cPKCS12, ossl_pkcs12_initialize_copy);
+ rb_define_method(cPKCS12, "initialize_copy", ossl_pkcs12_initialize_copy, 1);
rb_attr(cPKCS12, rb_intern("key"), 1, 0, Qfalse);
rb_attr(cPKCS12, rb_intern("certificate"), 1, 0, Qfalse);
rb_attr(cPKCS12, rb_intern("ca_certs"), 1, 0, Qfalse);
diff --git a/ext/openssl/ossl_pkcs5.c b/ext/openssl/ossl_pkcs5.c
deleted file mode 100644
index 47c5bfa3b8..0000000000
--- a/ext/openssl/ossl_pkcs5.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2007 Technorama Ltd. <oss-ruby@technorama.net>
- */
-#include "ossl.h"
-
-VALUE mPKCS5;
-VALUE ePKCS5;
-
-#ifdef HAVE_PKCS5_PBKDF2_HMAC
-/*
- * call-seq:
- * PKCS5.pbkdf2_hmac(pass, salt, iter, keylen, digest) => string
- *
- * === Parameters
- * * +pass+ - string
- * * +salt+ - string - should be at least 8 bytes long.
- * * +iter+ - integer - should be greater than 1000. 20000 is better.
- * * +keylen+ - integer
- * * +digest+ - a string or OpenSSL::Digest object.
- *
- * Available in OpenSSL >= 1.0.0.
- *
- * Digests other than SHA1 may not be supported by other cryptography libraries.
- */
-static VALUE
-ossl_pkcs5_pbkdf2_hmac(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE keylen, VALUE digest)
-{
- VALUE str;
- const EVP_MD *md;
- int len = NUM2INT(keylen);
-
- StringValue(pass);
- StringValue(salt);
- md = GetDigestPtr(digest);
-
- str = rb_str_new(0, len);
-
- if (PKCS5_PBKDF2_HMAC(RSTRING_PTR(pass), RSTRING_LENINT(pass),
- (unsigned char *)RSTRING_PTR(salt), RSTRING_LENINT(salt),
- NUM2INT(iter), md, len,
- (unsigned char *)RSTRING_PTR(str)) != 1)
- ossl_raise(ePKCS5, "PKCS5_PBKDF2_HMAC");
-
- return str;
-}
-#else
-#define ossl_pkcs5_pbkdf2_hmac rb_f_notimplement
-#endif
-
-
-/*
- * call-seq:
- * PKCS5.pbkdf2_hmac_sha1(pass, salt, iter, keylen) => string
- *
- * === Parameters
- * * +pass+ - string
- * * +salt+ - string - should be at least 8 bytes long.
- * * +iter+ - integer - should be greater than 1000. 20000 is better.
- * * +keylen+ - integer
- *
- * This method is available in almost any version of OpenSSL.
- *
- * Conforms to RFC 2898.
- */
-static VALUE
-ossl_pkcs5_pbkdf2_hmac_sha1(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE keylen)
-{
- VALUE str;
- int len = NUM2INT(keylen);
-
- StringValue(pass);
- StringValue(salt);
-
- str = rb_str_new(0, len);
-
- if (PKCS5_PBKDF2_HMAC_SHA1(RSTRING_PTR(pass), RSTRING_LENINT(pass),
- (const unsigned char *)RSTRING_PTR(salt), RSTRING_LENINT(salt), NUM2INT(iter),
- len, (unsigned char *)RSTRING_PTR(str)) != 1)
- ossl_raise(ePKCS5, "PKCS5_PBKDF2_HMAC_SHA1");
-
- return str;
-}
-
-void
-Init_ossl_pkcs5(void)
-{
-#if 0
- mOSSL = rb_define_module("OpenSSL");
- eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
-#endif
-
- /* Document-class: OpenSSL::PKCS5
- *
- * Provides password-based encryption functionality based on PKCS#5.
- * Typically used for securely deriving arbitrary length symmetric keys
- * to be used with an OpenSSL::Cipher from passwords. Another use case
- * is for storing passwords: Due to the ability to tweak the effort of
- * computation by increasing the iteration count, computation can be
- * slowed down artificially in order to render possible attacks infeasible.
- *
- * PKCS5 offers support for PBKDF2 with an OpenSSL::Digest::SHA1-based
- * HMAC, or an arbitrary Digest if the underlying version of OpenSSL
- * already supports it (>= 1.0.0).
- *
- * === Parameters
- * ==== Password
- * Typically an arbitrary String that represents the password to be used
- * for deriving a key.
- * ==== Salt
- * Prevents attacks based on dictionaries of common passwords. It is a
- * public value that can be safely stored along with the password (e.g.
- * if PBKDF2 is used for password storage). For maximum security, a fresh,
- * random salt should be generated for each stored password. According
- * to PKCS#5, a salt should be at least 8 bytes long.
- * ==== Iteration Count
- * Allows to tweak the length that the actual computation will take. The
- * larger the iteration count, the longer it will take.
- * ==== Key Length
- * Specifies the length in bytes of the output that will be generated.
- * Typically, the key length should be larger than or equal to the output
- * length of the underlying digest function, otherwise an attacker could
- * simply try to brute-force the key. According to PKCS#5, security is
- * limited by the output length of the underlying digest function, i.e.
- * security is not improved if a key length strictly larger than the
- * digest output length is chosen. Therefore, when using PKCS5 for
- * password storage, it suffices to store values equal to the digest
- * output length, nothing is gained by storing larger values.
- *
- * == Examples
- * === Generating a 128 bit key for a Cipher (e.g. AES)
- * pass = "secret"
- * salt = OpenSSL::Random.random_bytes(16)
- * iter = 20000
- * key_len = 16
- * key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(pass, salt, iter, key_len)
- *
- * === Storing Passwords
- * pass = "secret"
- * salt = OpenSSL::Random.random_bytes(16) #store this with the generated value
- * iter = 20000
- * digest = OpenSSL::Digest::SHA256.new
- * len = digest.digest_length
- * #the final value to be stored
- * value = OpenSSL::PKCS5.pbkdf2_hmac(pass, salt, iter, len, digest)
- *
- * === Important Note on Checking Passwords
- * When comparing passwords provided by the user with previously stored
- * values, a common mistake made is comparing the two values using "==".
- * Typically, "==" short-circuits on evaluation, and is therefore
- * vulnerable to timing attacks. The proper way is to use a method that
- * always takes the same amount of time when comparing two values, thus
- * not leaking any information to potential attackers. To compare two
- * values, the following could be used:
- * def eql_time_cmp(a, b)
- * unless a.length == b.length
- * return false
- * end
- * cmp = b.bytes.to_a
- * result = 0
- * a.bytes.each_with_index {|c,i|
- * result |= c ^ cmp[i]
- * }
- * result == 0
- * end
- * Please note that the premature return in case of differing lengths
- * typically does not leak valuable information - when using PKCS#5, the
- * length of the values to be compared is of fixed size.
- */
-
- mPKCS5 = rb_define_module_under(mOSSL, "PKCS5");
- /* Document-class: OpenSSL::PKCS5::PKCS5Error
- *
- * Generic Exception class that is raised if an error occurs during a
- * computation.
- */
- ePKCS5 = rb_define_class_under(mPKCS5, "PKCS5Error", eOSSLError);
-
- rb_define_module_function(mPKCS5, "pbkdf2_hmac", ossl_pkcs5_pbkdf2_hmac, 5);
- rb_define_module_function(mPKCS5, "pbkdf2_hmac_sha1", ossl_pkcs5_pbkdf2_hmac_sha1, 4);
-}
diff --git a/ext/openssl/ossl_pkcs5.h b/ext/openssl/ossl_pkcs5.h
deleted file mode 100644
index a3b132bc50..0000000000
--- a/ext/openssl/ossl_pkcs5.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#if !defined(_OSSL_PKCS5_H_)
-#define _OSSL_PKCS5_H_
-
-void Init_ossl_pkcs5(void);
-
-#endif /* _OSSL_PKCS5_H_ */
diff --git a/ext/openssl/ossl_pkcs7.c b/ext/openssl/ossl_pkcs7.c
index 40cc5f230e..6395fa6f5c 100644
--- a/ext/openssl/ossl_pkcs7.c
+++ b/ext/openssl/ossl_pkcs7.c
@@ -23,10 +23,6 @@
ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \
} \
} while (0)
-#define SafeGetPKCS7(obj, pkcs7) do { \
- OSSL_Check_Kind((obj), cPKCS7); \
- GetPKCS7((obj), (pkcs7)); \
-} while (0)
#define NewPKCS7si(klass) \
TypedData_Wrap_Struct((klass), &ossl_pkcs7_signer_info_type, 0)
@@ -42,10 +38,6 @@
ossl_raise(rb_eRuntimeError, "PKCS7si wasn't initialized."); \
} \
} while (0)
-#define SafeGetPKCS7si(obj, p7si) do { \
- OSSL_Check_Kind((obj), cPKCS7Signer); \
- GetPKCS7si((obj), (p7si)); \
-} while (0)
#define NewPKCS7ri(klass) \
TypedData_Wrap_Struct((klass), &ossl_pkcs7_recip_info_type, 0)
@@ -61,10 +53,6 @@
ossl_raise(rb_eRuntimeError, "PKCS7ri wasn't initialized."); \
} \
} while (0)
-#define SafeGetPKCS7ri(obj, p7ri) do { \
- OSSL_Check_Kind((obj), cPKCS7Recipient); \
- GetPKCS7ri((obj), (p7ri)); \
-} while (0)
#define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0]))
@@ -162,7 +150,7 @@ DupPKCS7SignerPtr(VALUE obj)
{
PKCS7_SIGNER_INFO *p7si, *pkcs7;
- SafeGetPKCS7si(obj, p7si);
+ GetPKCS7si(obj, p7si);
if (!(pkcs7 = ossl_PKCS7_SIGNER_INFO_dup(p7si))) {
ossl_raise(ePKCS7Error, NULL);
}
@@ -189,7 +177,7 @@ DupPKCS7RecipientPtr(VALUE obj)
{
PKCS7_RECIP_INFO *p7ri, *pkcs7;
- SafeGetPKCS7ri(obj, p7ri);
+ GetPKCS7ri(obj, p7ri);
if (!(pkcs7 = ossl_PKCS7_RECIP_INFO_dup(p7ri))) {
ossl_raise(ePKCS7Error, NULL);
}
@@ -238,7 +226,7 @@ ossl_pkcs7_s_write_smime(int argc, VALUE *argv, VALUE klass)
rb_scan_args(argc, argv, "12", &pkcs7, &data, &flags);
flg = NIL_P(flags) ? 0 : NUM2INT(flags);
if(NIL_P(data)) data = ossl_pkcs7_get_data(pkcs7);
- SafeGetPKCS7(pkcs7, p7);
+ GetPKCS7(pkcs7, p7);
if(!NIL_P(data) && PKCS7_is_detached(p7))
flg |= PKCS7_DETACHED;
in = NIL_P(data) ? NULL : ossl_obj2bio(&data);
@@ -331,7 +319,7 @@ ossl_pkcs7_s_encrypt(int argc, VALUE *argv, VALUE klass)
#endif
}
- else ciph = GetCipherPtr(cipher); /* NO NEED TO DUP */
+ else ciph = ossl_evp_get_cipherbyname(cipher);
flg = NIL_P(flags) ? 0 : NUM2INT(flags);
ret = NewPKCS7(cPKCS7);
in = ossl_obj2bio(&data);
@@ -414,7 +402,7 @@ ossl_pkcs7_copy(VALUE self, VALUE other)
if (self == other) return self;
GetPKCS7(self, a);
- SafeGetPKCS7(other, b);
+ GetPKCS7(other, b);
pkcs7 = PKCS7_dup(b);
if (!pkcs7) {
@@ -537,7 +525,7 @@ ossl_pkcs7_set_cipher(VALUE self, VALUE cipher)
PKCS7 *pkcs7;
GetPKCS7(self, pkcs7);
- if (!PKCS7_set_cipher(pkcs7, GetCipherPtr(cipher))) {
+ if (!PKCS7_set_cipher(pkcs7, ossl_evp_get_cipherbyname(cipher))) {
ossl_raise(ePKCS7Error, NULL);
}
@@ -933,7 +921,7 @@ ossl_pkcs7si_initialize(VALUE self, VALUE cert, VALUE key, VALUE digest)
pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */
- md = GetDigestPtr(digest);
+ md = ossl_evp_get_digestbyname(digest);
GetPKCS7si(self, p7si);
if (!(PKCS7_SIGNER_INFO_set(p7si, x509, pkey, (EVP_MD*)md))) {
ossl_raise(ePKCS7Error, NULL);
@@ -1068,7 +1056,7 @@ Init_ossl_pkcs7(void)
rb_attr(cPKCS7, rb_intern("data"), 1, 0, Qfalse);
rb_attr(cPKCS7, rb_intern("error_string"), 1, 1, Qfalse);
rb_define_alloc_func(cPKCS7, ossl_pkcs7_alloc);
- rb_define_copy_func(cPKCS7, ossl_pkcs7_copy);
+ rb_define_method(cPKCS7, "initialize_copy", ossl_pkcs7_copy, 1);
rb_define_method(cPKCS7, "initialize", ossl_pkcs7_initialize, -1);
rb_define_method(cPKCS7, "type=", ossl_pkcs7_set_type, 1);
rb_define_method(cPKCS7, "type", ossl_pkcs7_get_type, 0);
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
index 314d1d94af..23e2115409 100644
--- a/ext/openssl/ossl_pkey.c
+++ b/ext/openssl/ossl_pkey.c
@@ -92,7 +92,7 @@ pkey_new0(EVP_PKEY *pkey)
case EVP_PKEY_DH:
return ossl_dh_new(pkey);
#endif
-#if !defined(OPENSSL_NO_EC) && (OPENSSL_VERSION_NUMBER >= 0x0090802fL)
+#if !defined(OPENSSL_NO_EC)
case EVP_PKEY_EC:
return ossl_ec_new(pkey);
#endif
@@ -123,15 +123,15 @@ ossl_pkey_new(EVP_PKEY *pkey)
* OpenSSL::PKey.read(string [, pwd ]) -> PKey
* OpenSSL::PKey.read(io [, pwd ]) -> PKey
*
- * Reads a DER or PEM encoded string from +string+ or +io+ and returns an
+ * Reads a DER or PEM encoded string from _string_ or _io_ and returns an
* instance of the appropriate PKey class.
*
* === Parameters
- * * +string+ is a DER- or PEM-encoded string containing an arbitrary private
+ * * _string+ is a DER- or PEM-encoded string containing an arbitrary private
* or public key.
- * * +io+ is an instance of +IO+ containing a DER- or PEM-encoded
+ * * _io_ is an instance of IO containing a DER- or PEM-encoded
* arbitrary private or public key.
- * * +pwd+ is an optional password in case +string+ or +file+ is an encrypted
+ * * _pwd_ is an optional password in case _string_ or _io_ is an encrypted
* PEM resource.
*/
static VALUE
@@ -207,7 +207,7 @@ GetPKeyPtr(VALUE obj)
{
EVP_PKEY *pkey;
- SafeGetPKey(obj, pkey);
+ GetPKey(obj, pkey);
return pkey;
}
@@ -220,7 +220,7 @@ GetPrivPKeyPtr(VALUE obj)
if (rb_funcallv(obj, id_private_q, 0, NULL) != Qtrue) {
ossl_raise(rb_eArgError, "Private key is needed.");
}
- SafeGetPKey(obj, pkey);
+ GetPKey(obj, pkey);
return pkey;
}
@@ -230,7 +230,7 @@ DupPKeyPtr(VALUE obj)
{
EVP_PKEY *pkey;
- SafeGetPKey(obj, pkey);
+ GetPKey(obj, pkey);
EVP_PKEY_up_ref(pkey);
return pkey;
@@ -259,7 +259,7 @@ ossl_pkey_alloc(VALUE klass)
* PKeyClass.new -> self
*
* Because PKey is an abstract class, actually calling this method explicitly
- * will raise a +NotImplementedError+.
+ * will raise a NotImplementedError.
*/
static VALUE
ossl_pkey_initialize(VALUE self)
@@ -274,10 +274,10 @@ ossl_pkey_initialize(VALUE self)
* call-seq:
* pkey.sign(digest, data) -> String
*
- * To sign the +String+ +data+, +digest+, an instance of OpenSSL::Digest, must
- * be provided. The return value is again a +String+ containing the signature.
+ * To sign the String _data_, _digest_, an instance of OpenSSL::Digest, must
+ * be provided. The return value is again a String containing the signature.
* A PKeyError is raised should errors occur.
- * Any previous state of the +Digest+ instance is irrelevant to the signature
+ * Any previous state of the Digest instance is irrelevant to the signature
* outcome, the digest instance is reset to its initial state during the
* operation.
*
@@ -298,7 +298,7 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
int result;
pkey = GetPrivPKeyPtr(self);
- md = GetDigestPtr(digest);
+ md = ossl_evp_get_digestbyname(digest);
StringValue(data);
str = rb_str_new(0, EVP_PKEY_size(pkey));
@@ -326,12 +326,12 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
* call-seq:
* pkey.verify(digest, signature, data) -> String
*
- * To verify the +String+ +signature+, +digest+, an instance of
+ * To verify the String _signature_, _digest_, an instance of
* OpenSSL::Digest, must be provided to re-compute the message digest of the
- * original +data+, also a +String+. The return value is +true+ if the
+ * original _data_, also a String. The return value is +true+ if the
* signature is valid, +false+ otherwise. A PKeyError is raised should errors
* occur.
- * Any previous state of the +Digest+ instance is irrelevant to the validation
+ * Any previous state of the Digest instance is irrelevant to the validation
* outcome, the digest instance is reset to its initial state during the
* operation.
*
@@ -353,7 +353,7 @@ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
GetPKey(self, pkey);
pkey_check_public_key(pkey);
- md = GetDigestPtr(digest);
+ md = ossl_evp_get_digestbyname(digest);
StringValue(sig);
siglen = RSTRING_LENINT(sig);
StringValue(data);
diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h
index e3b723cd68..a87472ad09 100644
--- a/ext/openssl/ossl_pkey.h
+++ b/ext/openssl/ossl_pkey.h
@@ -34,10 +34,6 @@ extern const rb_data_type_t ossl_evp_pkey_type;
rb_raise(rb_eRuntimeError, "PKEY wasn't initialized!");\
} \
} while (0)
-#define SafeGetPKey(obj, pkey) do { \
- OSSL_Check_Kind((obj), cPKey); \
- GetPKey((obj), (pkey)); \
-} while (0)
struct ossl_generate_cb_arg {
int yield;
diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c
index 9283271093..31f3b8e726 100644
--- a/ext/openssl/ossl_pkey_dh.c
+++ b/ext/openssl/ossl_pkey_dh.c
@@ -150,8 +150,8 @@ dh_generate(int size, int gen)
* components alike.
*
* === Parameters
- * * +size+ is an integer representing the desired key size. Keys smaller than 1024 bits should be considered insecure.
- * * +generator+ is a small number > 1, typically 2 or 5.
+ * * _size_ is an integer representing the desired key size. Keys smaller than 1024 bits should be considered insecure.
+ * * _generator_ is a small number > 1, typically 2 or 5.
*
*/
static VALUE
@@ -181,15 +181,15 @@ ossl_dh_s_generate(int argc, VALUE *argv, VALUE klass)
* DH.new(size [, generator]) -> dh
*
* Either generates a DH instance from scratch or by reading already existing
- * DH parameters from +string+. Note that when reading a DH instance from
+ * DH parameters from _string_. Note that when reading a DH instance from
* data that was encoded from a DH instance by using DH#to_pem or DH#to_der
* the result will *not* contain a public/private key pair yet. This needs to
* be generated using DH#generate_key! first.
*
* === Parameters
- * * +size+ is an integer representing the desired key size. Keys smaller than 1024 bits should be considered insecure.
- * * +generator+ is a small number > 1, typically 2 or 5.
- * * +string+ contains the DER or PEM encoded key.
+ * * _size_ is an integer representing the desired key size. Keys smaller than 1024 bits should be considered insecure.
+ * * _generator_ is a small number > 1, typically 2 or 5.
+ * * _string_ contains the DER or PEM encoded key.
*
* === Examples
* DH.new # -> dh
@@ -436,7 +436,7 @@ ossl_dh_to_text(VALUE self)
* dh.public_key -> aDH
*
* Returns a new DH instance that carries just the public information, i.e.
- * the prime +p+ and the generator +g+, but no public/private key yet. Such
+ * the prime _p_ and the generator _g_, but no public/private key yet. Such
* a pair may be generated using DH#generate_key!. The "public key" needed
* for a key exchange with DH#compute_key is considered as per-session
* information and may be retrieved with DH#pub_key once a key pair has
@@ -526,7 +526,7 @@ ossl_dh_generate_key(VALUE self)
* See DH_compute_key() for further information.
*
* === Parameters
- * * +pub_bn+ is a OpenSSL::BN, *not* the DH instance returned by
+ * * _pub_bn_ is a OpenSSL::BN, *not* the DH instance returned by
* DH#public_key as that contains the DH parameters only.
*/
static VALUE
@@ -557,7 +557,7 @@ ossl_dh_compute_key(VALUE self, VALUE pub)
* call-seq:
* dh.set_pqg(p, q, g) -> self
*
- * Sets +p+, +q+, +g+ for the DH instance.
+ * Sets _p_, _q_, _g_ to the DH instance.
*/
OSSL_PKEY_BN_DEF3(dh, DH, pqg, p, q, g)
/*
@@ -565,7 +565,7 @@ OSSL_PKEY_BN_DEF3(dh, DH, pqg, p, q, g)
* call-seq:
* dh.set_key(pub_key, priv_key) -> self
*
- * Sets +pub_key+ and +priv_key+ for the DH instance. +priv_key+ may be nil.
+ * Sets _pub_key_ and _priv_key_ for the DH instance. _priv_key_ may be +nil+.
*/
OSSL_PKEY_BN_DEF2(dh, DH, key, pub_key, priv_key)
@@ -618,7 +618,7 @@ Init_ossl_dh(void)
cDH = rb_define_class_under(mPKey, "DH", cPKey);
rb_define_singleton_method(cDH, "generate", ossl_dh_s_generate, -1);
rb_define_method(cDH, "initialize", ossl_dh_initialize, -1);
- rb_define_copy_func(cDH, ossl_dh_initialize_copy);
+ rb_define_method(cDH, "initialize_copy", ossl_dh_initialize_copy, 1);
rb_define_method(cDH, "public?", ossl_dh_is_public, 0);
rb_define_method(cDH, "private?", ossl_dh_is_private, 0);
rb_define_method(cDH, "to_text", ossl_dh_to_text, 0);
diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c
index cd4313b1ff..56cc9dd4f1 100644
--- a/ext/openssl/ossl_pkey_dsa.c
+++ b/ext/openssl/ossl_pkey_dsa.c
@@ -172,7 +172,7 @@ dsa_generate(int size)
* from scratch.
*
* === Parameters
- * * +size+ is an integer representing the desired key size.
+ * * _size_ is an integer representing the desired key size.
*
*/
static VALUE
@@ -195,12 +195,12 @@ ossl_dsa_s_generate(VALUE klass, VALUE size)
* DSA.new(size) -> dsa
* DSA.new(string [, pass]) -> dsa
*
- * Creates a new DSA instance by reading an existing key from +string+.
+ * Creates a new DSA instance by reading an existing key from _string_.
*
* === Parameters
- * * +size+ is an integer representing the desired key size.
- * * +string+ contains a DER or PEM encoded key.
- * * +pass+ is a string that contains an optional password.
+ * * _size_ is an integer representing the desired key size.
+ * * _string_ contains a DER or PEM encoded key.
+ * * _pass_ is a string that contains an optional password.
*
* === Examples
* DSA.new -> dsa
@@ -329,8 +329,8 @@ ossl_dsa_is_private(VALUE self)
* Encodes this DSA to its PEM encoding.
*
* === Parameters
- * * +cipher+ is an OpenSSL::Cipher.
- * * +password+ is a string containing your password.
+ * * _cipher_ is an OpenSSL::Cipher.
+ * * _password_ is a string containing your password.
*
* === Examples
* DSA.to_pem -> aString
@@ -348,7 +348,7 @@ ossl_dsa_export(int argc, VALUE *argv, VALUE self)
GetDSA(self, dsa);
rb_scan_args(argc, argv, "02", &cipher, &pass);
if (!NIL_P(cipher)) {
- ciph = GetCipherPtr(cipher);
+ ciph = ossl_evp_get_cipherbyname(cipher);
pass = ossl_pem_passwd_value(pass);
}
if (!(out = BIO_new(BIO_s_mem()))) {
@@ -503,12 +503,12 @@ ossl_dsa_to_public_key(VALUE self)
* call-seq:
* dsa.syssign(string) -> aString
*
- * Computes and returns the DSA signature of +string+, where +string+ is
+ * Computes and returns the DSA signature of _string_, where _string_ is
* expected to be an already-computed message digest of the original input
* data. The signature is issued using the private key of this DSA instance.
*
* === Parameters
- * * +string+ is a message digest of the original input data to be signed
+ * * _string_ is a message digest of the original input data to be signed.
*
* === Example
* dsa = OpenSSL::PKey::DSA.new(2048)
@@ -549,11 +549,11 @@ ossl_dsa_sign(VALUE self, VALUE data)
* dsa.sysverify(digest, sig) -> true | false
*
* Verifies whether the signature is valid given the message digest input. It
- * does so by validating +sig+ using the public key of this DSA instance.
+ * does so by validating _sig_ using the public key of this DSA instance.
*
* === Parameters
- * * +digest+ is a message digest of the original input data to be signed
- * * +sig+ is a DSA signature value
+ * * _digest_ is a message digest of the original input data to be signed
+ * * _sig_ is a DSA signature value
*
* === Example
* dsa = OpenSSL::PKey::DSA.new(2048)
@@ -590,7 +590,7 @@ ossl_dsa_verify(VALUE self, VALUE digest, VALUE sig)
* call-seq:
* dsa.set_pqg(p, q, g) -> self
*
- * Sets +p+, +q+, +g+ for the DSA instance.
+ * Sets _p_, _q_, _g_ to the DSA instance.
*/
OSSL_PKEY_BN_DEF3(dsa, DSA, pqg, p, q, g)
/*
@@ -598,7 +598,7 @@ OSSL_PKEY_BN_DEF3(dsa, DSA, pqg, p, q, g)
* call-seq:
* dsa.set_key(pub_key, priv_key) -> self
*
- * Sets +pub_key+ and +priv_key+ for the DSA instance. +priv_key+ may be nil.
+ * Sets _pub_key_ and _priv_key_ for the DSA instance. _priv_key_ may be +nil+.
*/
OSSL_PKEY_BN_DEF2(dsa, DSA, key, pub_key, priv_key)
@@ -627,18 +627,12 @@ Init_ossl_dsa(void)
* DSA, the Digital Signature Algorithm, is specified in NIST's
* FIPS 186-3. It is an asymmetric public key algorithm that may be used
* similar to e.g. RSA.
- * Please note that for OpenSSL versions prior to 1.0.0 the digest
- * algorithms OpenSSL::Digest::DSS (equivalent to SHA) or
- * OpenSSL::Digest::DSS1 (equivalent to SHA-1) must be used for issuing
- * signatures with a DSA key using OpenSSL::PKey#sign.
- * Starting with OpenSSL 1.0.0, digest algorithms are no longer restricted,
- * any Digest may be used for signing.
*/
cDSA = rb_define_class_under(mPKey, "DSA", cPKey);
rb_define_singleton_method(cDSA, "generate", ossl_dsa_s_generate, 1);
rb_define_method(cDSA, "initialize", ossl_dsa_initialize, -1);
- rb_define_copy_func(cDSA, ossl_dsa_initialize_copy);
+ rb_define_method(cDSA, "initialize_copy", ossl_dsa_initialize_copy, 1);
rb_define_method(cDSA, "public?", ossl_dsa_is_public, 0);
rb_define_method(cDSA, "private?", ossl_dsa_is_private, 0);
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c
index 5262d3b206..9c406931a9 100644
--- a/ext/openssl/ossl_pkey_ec.c
+++ b/ext/openssl/ossl_pkey_ec.c
@@ -4,7 +4,7 @@
#include "ossl.h"
-#if !defined(OPENSSL_NO_EC) && (OPENSSL_VERSION_NUMBER >= 0x0090802fL)
+#if !defined(OPENSSL_NO_EC)
#define EXPORT_PEM 0
#define EXPORT_DER 1
@@ -23,33 +23,21 @@ static const rb_data_type_t ossl_ec_point_type;
GetPKeyEC(obj, _pkey); \
(key) = EVP_PKEY_get0_EC_KEY(_pkey); \
} while (0)
-#define SafeGetEC(obj, key) do { \
- OSSL_Check_Kind(obj, cEC); \
- GetEC(obj, key); \
-} while (0)
#define GetECGroup(obj, group) do { \
TypedData_Get_Struct(obj, EC_GROUP, &ossl_ec_group_type, group); \
if ((group) == NULL) \
ossl_raise(eEC_GROUP, "EC_GROUP is not initialized"); \
} while (0)
-#define SafeGetECGroup(obj, group) do { \
- OSSL_Check_Kind((obj), cEC_GROUP); \
- GetECGroup(obj, group); \
-} while (0)
#define GetECPoint(obj, point) do { \
TypedData_Get_Struct(obj, EC_POINT, &ossl_ec_point_type, point); \
if ((point) == NULL) \
ossl_raise(eEC_POINT, "EC_POINT is not initialized"); \
} while (0)
-#define SafeGetECPoint(obj, point) do { \
- OSSL_Check_Kind((obj), cEC_POINT); \
- GetECPoint(obj, point); \
-} while(0)
#define GetECPointGroup(obj, group) do { \
VALUE _group = rb_attr_get(obj, id_i_group); \
- SafeGetECGroup(_group, group); \
+ GetECGroup(_group, group); \
} while (0)
VALUE cEC;
@@ -128,7 +116,7 @@ ec_key_new_from_group(VALUE arg)
if (rb_obj_is_kind_of(arg, cEC_GROUP)) {
EC_GROUP *group;
- SafeGetECGroup(arg, group);
+ GetECGroup(arg, group);
if (!(ec = EC_KEY_new()))
ossl_raise(eECError, NULL);
@@ -208,7 +196,7 @@ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
} else if (rb_obj_is_kind_of(arg, cEC)) {
EC_KEY *other_ec = NULL;
- SafeGetEC(arg, other_ec);
+ GetEC(arg, other_ec);
if (!(ec = EC_KEY_dup(other_ec)))
ossl_raise(eECError, NULL);
} else if (rb_obj_is_kind_of(arg, cEC_GROUP)) {
@@ -257,7 +245,7 @@ ossl_ec_key_initialize_copy(VALUE self, VALUE other)
GetPKey(self, pkey);
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
ossl_raise(eECError, "EC already initialized");
- SafeGetEC(other, ec);
+ GetEC(other, ec);
ec_new = EC_KEY_dup(ec);
if (!ec_new)
@@ -275,7 +263,7 @@ ossl_ec_key_initialize_copy(VALUE self, VALUE other)
* key.group => group
*
* Returns the EC::Group that the key is associated with. Modifying the returned
- * group does not affect +key+.
+ * group does not affect _key_.
*/
static VALUE
ossl_ec_key_get_group(VALUE self)
@@ -296,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
- * modification 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)
@@ -305,7 +293,7 @@ ossl_ec_key_set_group(VALUE self, VALUE group_v)
EC_GROUP *group;
GetEC(self, ec);
- SafeGetECGroup(group_v, group);
+ GetECGroup(group_v, group);
if (EC_KEY_set_group(ec, group) != 1)
ossl_raise(eECError, "EC_KEY_set_group");
@@ -390,7 +378,7 @@ static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key)
GetEC(self, ec);
if (!NIL_P(public_key))
- SafeGetECPoint(public_key, point);
+ GetECPoint(public_key, point);
switch (EC_KEY_set_public_key(ec, point)) {
case 1:
@@ -458,7 +446,7 @@ static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int forma
private = 1;
if (!NIL_P(ciph)) {
- cipher = GetCipherPtr(ciph);
+ cipher = ossl_evp_get_cipherbyname(ciph);
pass = ossl_pem_passwd_value(pass);
}
@@ -502,8 +490,8 @@ static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int forma
* key.export([cipher, pass_phrase]) => String
* key.to_pem([cipher, pass_phrase]) => String
*
- * Outputs the EC key in PEM encoding. If +cipher+ and +pass_phrase+ are given
- * they will be used to encrypt the key. +cipher+ must be an OpenSSL::Cipher
+ * Outputs the EC key in PEM encoding. If _cipher_ and _pass_phrase_ are given
+ * they will be used to encrypt the key. _cipher_ must be an OpenSSL::Cipher
* instance. Note that encryption will only be effective for a private key,
* public keys will always be encoded in plain text.
*/
@@ -608,7 +596,7 @@ static VALUE ossl_ec_key_dh_compute_key(VALUE self, VALUE pubkey)
VALUE str;
GetEC(self, ec);
- SafeGetECPoint(pubkey, point);
+ GetECPoint(pubkey, point);
/* BUG: need a way to figure out the maximum string size */
buf_len = 1024;
@@ -724,7 +712,7 @@ ec_group_new(const EC_GROUP *group)
*
* Creates a new EC::Group object.
*
- * +ec_method+ is a symbol that represents an EC_METHOD. Currently the following
+ * _ec_method_ is a symbol that represents an EC_METHOD. Currently the following
* are supported:
*
* * :GFp_simple
@@ -771,7 +759,7 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self)
} else if (rb_obj_is_kind_of(arg1, cEC_GROUP)) {
const EC_GROUP *arg1_group;
- SafeGetECGroup(arg1, arg1_group);
+ GetECGroup(arg1, arg1_group);
if ((group = EC_GROUP_dup(arg1_group)) == NULL)
ossl_raise(eEC_GROUP, "EC_GROUP_dup");
} else {
@@ -847,7 +835,7 @@ ossl_ec_group_initialize_copy(VALUE self, VALUE other)
TypedData_Get_Struct(self, EC_GROUP, &ossl_ec_group_type, group_new);
if (group_new)
ossl_raise(eEC_GROUP, "EC::Group already initialized");
- SafeGetECGroup(other, group);
+ GetECGroup(other, group);
group_new = EC_GROUP_dup(group);
if (!group_new)
@@ -862,15 +850,15 @@ ossl_ec_group_initialize_copy(VALUE self, VALUE other)
* group1.eql?(group2) => true | false
* group1 == group2 => true | false
*
- * Returns true if the two groups use the same curve and have the same
- * parameters, false otherwise.
+ * Returns +true+ if the two groups use the same curve and have the same
+ * parameters, +false+ otherwise.
*/
static VALUE ossl_ec_group_eql(VALUE a, VALUE b)
{
EC_GROUP *group1 = NULL, *group2 = NULL;
GetECGroup(a, group1);
- SafeGetECGroup(b, group2);
+ GetECGroup(b, group2);
if (EC_GROUP_cmp(group1, group2, ossl_bn_ctx) == 1)
return Qfalse;
@@ -903,8 +891,8 @@ static VALUE ossl_ec_group_get_generator(VALUE self)
* call-seq:
* group.set_generator(generator, order, cofactor) => self
*
- * Sets the curve parameters. +generator+ must be an instance of EC::Point that
- * is on the curve. +order+ and +cofactor+ are integers.
+ * Sets the curve parameters. _generator_ must be an instance of EC::Point that
+ * is on the curve. _order_ and _cofactor_ are integers.
*
* See the OpenSSL documentation for EC_GROUP_set_generator()
*/
@@ -915,7 +903,7 @@ static VALUE ossl_ec_group_set_generator(VALUE self, VALUE generator, VALUE orde
const BIGNUM *o, *co;
GetECGroup(self, group);
- SafeGetECPoint(generator, point);
+ GetECPoint(generator, point);
o = GetBNPtr(order);
co = GetBNPtr(cofactor);
@@ -1127,14 +1115,14 @@ parse_point_conversion_form_symbol(VALUE sym)
*
* Sets the form how EC::Point data is encoded as ASN.1 as defined in X9.62.
*
- * +format+ can be one of these:
+ * _format_ can be one of these:
*
- * :compressed::
+ * +:compressed+::
* Encoded as z||x, where z is an octet indicating which solution of the
* equation y is. z will be 0x02 or 0x03.
- * :uncompressed::
+ * +:uncompressed+::
* Encoded as z||x||y, where z is an octet 0x04.
- * :hybrid::
+ * +:hybrid+::
* Encodes as z||x||y, where z is an octet indicating which solution of the
* equation y is. z will be 0x06 or 0x07.
*
@@ -1356,13 +1344,13 @@ static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self)
const EC_POINT *arg_point;
group_v = rb_attr_get(arg1, id_i_group);
- SafeGetECGroup(group_v, group);
- SafeGetECPoint(arg1, arg_point);
+ GetECGroup(group_v, group);
+ GetECPoint(arg1, arg_point);
point = EC_POINT_dup(arg_point, group);
} else if (rb_obj_is_kind_of(arg1, cEC_GROUP)) {
group_v = arg1;
- SafeGetECGroup(group_v, group);
+ GetECGroup(group_v, group);
point = EC_POINT_new(group);
} else {
@@ -1374,7 +1362,7 @@ static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self)
if (!rb_obj_is_kind_of(arg1, cEC_GROUP))
ossl_raise(rb_eArgError, "1st argument must be OpenSSL::PKey::EC::Group");
group_v = arg1;
- SafeGetECGroup(group_v, group);
+ GetECGroup(group_v, group);
if (rb_obj_is_kind_of(arg2, cBN)) {
const BIGNUM *bn = GetBNPtr(arg2);
@@ -1418,10 +1406,10 @@ ossl_ec_point_initialize_copy(VALUE self, VALUE other)
TypedData_Get_Struct(self, EC_POINT, &ossl_ec_point_type, point_new);
if (point_new)
ossl_raise(eEC_POINT, "EC::Point already initialized");
- SafeGetECPoint(other, point);
+ GetECPoint(other, point);
group_v = rb_obj_dup(rb_attr_get(other, id_i_group));
- SafeGetECGroup(group_v, group);
+ GetECGroup(group_v, group);
point_new = EC_POINT_dup(point, group);
if (!point_new)
@@ -1448,8 +1436,8 @@ static VALUE ossl_ec_point_eql(VALUE a, VALUE b)
return Qfalse;
GetECPoint(a, point1);
- SafeGetECPoint(b, point2);
- SafeGetECGroup(group_v1, group);
+ GetECPoint(b, point2);
+ GetECGroup(group_v1, group);
if (EC_POINT_cmp(group, point1, point2, ossl_bn_ctx) == 1)
return Qfalse;
@@ -1558,7 +1546,7 @@ static VALUE ossl_ec_point_set_to_infinity(VALUE self)
* point.to_bn(conversion_form = nil) => OpenSSL::BN
*
* Convert the EC point into an octet string and store in an OpenSSL::BN. If
- * +conversion_form+ is given, the point data is converted using the specified
+ * _conversion_form_ is given, the point data is converted using the specified
* form. If not given, the default form set in the EC::Group object is used.
*
* See also EC::Point#point_conversion_form=.
@@ -1597,12 +1585,12 @@ 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 omitted, 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 omitted. +bns+ must be
- * an array of OpenSSL::BN. +points+ must be an array of
+ * + 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>.
*/
@@ -1615,7 +1603,7 @@ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self)
const BIGNUM *bn_g = NULL;
GetECPoint(self, point_self);
- SafeGetECGroup(group_v, group);
+ GetECGroup(group_v, group);
result = rb_obj_alloc(cEC_POINT);
ossl_ec_point_initialize(1, &group_v, result);
@@ -1656,7 +1644,7 @@ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self)
points = ALLOCV_N(const EC_POINT *, tmp_p, num);
points[0] = point_self; /* self */
for (i = 0; i < num - 1; i++)
- SafeGetECPoint(RARRAY_AREF(arg2, i), points[i + 1]);
+ GetECPoint(RARRAY_AREF(arg2, i), points[i + 1]);
if (!NIL_P(arg3))
bn_g = GetBNPtr(arg3);
@@ -1726,7 +1714,7 @@ void Init_ossl_ec(void)
rb_define_singleton_method(cEC, "generate", ossl_ec_key_s_generate, 1);
rb_define_method(cEC, "initialize", ossl_ec_key_initialize, -1);
- rb_define_copy_func(cEC, ossl_ec_key_initialize_copy);
+ rb_define_method(cEC, "initialize_copy", ossl_ec_key_initialize_copy, 1);
/* copy/dup/cmp */
rb_define_method(cEC, "group", ossl_ec_key_get_group, 0);
@@ -1763,7 +1751,7 @@ void Init_ossl_ec(void)
rb_define_alloc_func(cEC_GROUP, ossl_ec_group_alloc);
rb_define_method(cEC_GROUP, "initialize", ossl_ec_group_initialize, -1);
- rb_define_copy_func(cEC_GROUP, ossl_ec_group_initialize_copy);
+ rb_define_method(cEC_GROUP, "initialize_copy", ossl_ec_group_initialize_copy, 1);
rb_define_method(cEC_GROUP, "eql?", ossl_ec_group_eql, 1);
rb_define_alias(cEC_GROUP, "==", "eql?");
/* copy/dup/cmp */
@@ -1799,7 +1787,7 @@ void Init_ossl_ec(void)
rb_define_alloc_func(cEC_POINT, ossl_ec_point_alloc);
rb_define_method(cEC_POINT, "initialize", ossl_ec_point_initialize, -1);
- rb_define_copy_func(cEC_POINT, ossl_ec_point_initialize_copy);
+ rb_define_method(cEC_POINT, "initialize_copy", ossl_ec_point_initialize_copy, 1);
rb_attr(cEC_POINT, rb_intern("group"), 1, 0, 0);
rb_define_method(cEC_POINT, "eql?", ossl_ec_point_eql, 1);
rb_define_alias(cEC_POINT, "==", "eql?");
diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c
index 1fcdd52cf4..26397bd021 100644
--- a/ext/openssl/ossl_pkey_rsa.c
+++ b/ext/openssl/ossl_pkey_rsa.c
@@ -172,8 +172,8 @@ rsa_generate(int size, unsigned long exp)
* RSA.generate(size) => RSA instance
* RSA.generate(size, exponent) => RSA instance
*
- * Generates an RSA keypair. +size+ is an integer representing the desired key
- * size. Keys smaller than 1024 should be considered insecure. +exponent+ is
+ * Generates an RSA keypair. _size_ is an integer representing the desired key
+ * size. Keys smaller than 1024 should be considered insecure. _exponent_ is
* an odd number normally 3, 17, or 65537.
*/
static VALUE
@@ -203,12 +203,12 @@ ossl_rsa_s_generate(int argc, VALUE *argv, VALUE klass)
* RSA.new(encoded_key) => RSA instance
* RSA.new(encoded_key, pass_phrase) => RSA instance
*
- * Generates or loads an RSA keypair. If an integer +key_size+ is given it
+ * Generates or loads an RSA keypair. If an integer _key_size_ is given it
* represents the desired key size. Keys less than 1024 bits should be
* considered insecure.
*
- * A key can instead be loaded from an +encoded_key+ which must be PEM or DER
- * encoded. A +pass_phrase+ can be used to decrypt the key. If none is given
+ * A key can instead be loaded from an _encoded_key_ which must be PEM or DER
+ * encoded. A _pass_phrase_ can be used to decrypt the key. If none is given
* OpenSSL will prompt for the pass phrase.
*
* = Examples
@@ -295,7 +295,7 @@ ossl_rsa_initialize_copy(VALUE self, VALUE other)
* call-seq:
* rsa.public? => true
*
- * The return value is always true since every private key is also a public
+ * The return value is always +true+ since every private key is also a public
* key.
*/
static VALUE
@@ -333,8 +333,8 @@ ossl_rsa_is_private(VALUE self)
* rsa.to_pem([cipher, pass_phrase]) => PEM-format String
* rsa.to_s([cipher, pass_phrase]) => PEM-format String
*
- * Outputs this keypair in PEM encoding. If +cipher+ and +pass_phrase+ are
- * given they will be used to encrypt the key. +cipher+ must be an
+ * Outputs this keypair in PEM encoding. If _cipher_ and _pass_phrase_ are
+ * given they will be used to encrypt the key. _cipher_ must be an
* OpenSSL::Cipher instance.
*/
static VALUE
@@ -350,7 +350,7 @@ ossl_rsa_export(int argc, VALUE *argv, VALUE self)
rb_scan_args(argc, argv, "02", &cipher, &pass);
if (!NIL_P(cipher)) {
- ciph = GetCipherPtr(cipher);
+ ciph = ossl_evp_get_cipherbyname(cipher);
pass = ossl_pem_passwd_value(pass);
}
if (!(out = BIO_new(BIO_s_mem()))) {
@@ -409,7 +409,7 @@ ossl_rsa_to_der(VALUE self)
* rsa.public_encrypt(string) => String
* rsa.public_encrypt(string, padding) => String
*
- * Encrypt +string+ with the public key. +padding+ defaults to PKCS1_PADDING.
+ * Encrypt _string_ with the public key. _padding_ defaults to PKCS1_PADDING.
* The encrypted string output can be decrypted using #private_decrypt.
*/
static VALUE
@@ -441,8 +441,8 @@ ossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self)
* rsa.public_decrypt(string) => String
* rsa.public_decrypt(string, padding) => String
*
- * Decrypt +string+, which has been encrypted with the private key, with the
- * public key. +padding+ defaults to PKCS1_PADDING.
+ * Decrypt _string_, which has been encrypted with the private key, with the
+ * public key. _padding_ defaults to PKCS1_PADDING.
*/
static VALUE
ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self)
@@ -473,7 +473,7 @@ ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self)
* rsa.private_encrypt(string) => String
* rsa.private_encrypt(string, padding) => String
*
- * Encrypt +string+ with the private key. +padding+ defaults to PKCS1_PADDING.
+ * Encrypt _string_ with the private key. _padding_ defaults to PKCS1_PADDING.
* The encrypted string output can be decrypted using #public_decrypt.
*/
static VALUE
@@ -507,8 +507,8 @@ ossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self)
* rsa.private_decrypt(string) => String
* rsa.private_decrypt(string, padding) => String
*
- * Decrypt +string+, which has been encrypted with the public key, with the
- * private key. +padding+ defaults to PKCS1_PADDING.
+ * Decrypt _string_, which has been encrypted with the public key, with the
+ * private key. _padding_ defaults to PKCS1_PADDING.
*/
static VALUE
ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self)
@@ -659,7 +659,7 @@ ossl_rsa_blinding_off(VALUE self)
* call-seq:
* rsa.set_key(n, e, d) -> self
*
- * Sets +n+, +e+, +d+ for the RSA instance.
+ * Sets _n_, _e_, _d_ for the RSA instance.
*/
OSSL_PKEY_BN_DEF3(rsa, RSA, key, n, e, d)
/*
@@ -667,7 +667,7 @@ OSSL_PKEY_BN_DEF3(rsa, RSA, key, n, e, d)
* call-seq:
* rsa.set_factors(p, q) -> self
*
- * Sets +p+, +q+ for the RSA instance.
+ * Sets _p_, _q_ for the RSA instance.
*/
OSSL_PKEY_BN_DEF2(rsa, RSA, factors, p, q)
/*
@@ -675,7 +675,7 @@ OSSL_PKEY_BN_DEF2(rsa, RSA, factors, p, q)
* call-seq:
* rsa.set_crt_params(dmp1, dmq1, iqmp) -> self
*
- * Sets +dmp1+, +dmq1+, +iqmp+ for the RSA instance. They are calculated by
+ * Sets _dmp1_, _dmq1_, _iqmp_ for the RSA instance. They are calculated by
* <tt>d mod (p - 1)</tt>, <tt>d mod (q - 1)</tt> and <tt>q^(-1) mod p</tt>
* respectively.
*/
@@ -717,7 +717,7 @@ Init_ossl_rsa(void)
rb_define_singleton_method(cRSA, "generate", ossl_rsa_s_generate, -1);
rb_define_method(cRSA, "initialize", ossl_rsa_initialize, -1);
- rb_define_copy_func(cRSA, ossl_rsa_initialize_copy);
+ rb_define_method(cRSA, "initialize_copy", ossl_rsa_initialize_copy, 1);
rb_define_method(cRSA, "public?", ossl_rsa_is_public, 0);
rb_define_method(cRSA, "private?", ossl_rsa_is_private, 0);
diff --git a/ext/openssl/ossl_rand.c b/ext/openssl/ossl_rand.c
index 688c525afa..c95857060a 100644
--- a/ext/openssl/ossl_rand.c
+++ b/ext/openssl/ossl_rand.c
@@ -16,7 +16,7 @@ VALUE eRandomError;
* call-seq:
* seed(str) -> str
*
- * ::seed is equivalent to ::add where +entropy+ is length of +str+.
+ * ::seed is equivalent to ::add where _entropy_ is length of _str_.
*/
static VALUE
ossl_rand_seed(VALUE self, VALUE str)
@@ -31,15 +31,15 @@ ossl_rand_seed(VALUE self, VALUE str)
* call-seq:
* add(str, entropy) -> self
*
- * Mixes the bytes from +str+ into the Pseudo Random Number Generator(PRNG)
+ * Mixes the bytes from _str_ into the Pseudo Random Number Generator(PRNG)
* state.
*
- * Thus, if the data from +str+ are unpredictable to an adversary, this
+ * Thus, if the data from _str_ are unpredictable to an adversary, this
* increases the uncertainty about the state and makes the PRNG output less
* predictable.
*
- * The +entropy+ argument is (the lower bound of) an estimate of how much
- * randomness is contained in +str+, measured in bytes.
+ * The _entropy_ argument is (the lower bound of) an estimate of how much
+ * randomness is contained in _str_, measured in bytes.
*
* === Example
*
@@ -62,7 +62,7 @@ ossl_rand_add(VALUE self, VALUE str, VALUE entropy)
* call-seq:
* load_random_file(filename) -> true
*
- * Reads bytes from +filename+ and adds them to the PRNG.
+ * Reads bytes from _filename_ and adds them to the PRNG.
*/
static VALUE
ossl_rand_load_file(VALUE self, VALUE filename)
@@ -79,7 +79,7 @@ ossl_rand_load_file(VALUE self, VALUE filename)
* call-seq:
* write_random_file(filename) -> true
*
- * Writes a number of random generated bytes (currently 1024) to +filename+
+ * Writes a number of random generated bytes (currently 1024) to _filename_
* which can be used to initialize the PRNG by calling ::load_random_file in a
* later session.
*/
@@ -98,7 +98,7 @@ ossl_rand_write_file(VALUE self, VALUE filename)
* call-seq:
* random_bytes(length) -> string
*
- * Generates +string+ with +length+ number of cryptographically strong
+ * Generates a String with _length_ number of cryptographically strong
* pseudo-random bytes.
*
* === Example
@@ -129,7 +129,7 @@ ossl_rand_bytes(VALUE self, VALUE len)
* call-seq:
* pseudo_bytes(length) -> string
*
- * Generates +string+ with +length+ number of pseudo-random bytes.
+ * Generates a String with _length_ number of pseudo-random bytes.
*
* Pseudo-random byte sequences generated by ::pseudo_bytes will be unique if
* they are of sufficient length, but are not necessarily unpredictable.
@@ -176,9 +176,9 @@ ossl_rand_egd(VALUE self, VALUE filename)
* call-seq:
* egd_bytes(filename, length) -> true
*
- * Queries the entropy gathering daemon EGD on socket path given by +filename+.
+ * Queries the entropy gathering daemon EGD on socket path given by _filename_.
*
- * Fetches +length+ number of bytes and uses ::add to seed the OpenSSL built-in
+ * Fetches _length_ number of bytes and uses ::add to seed the OpenSSL built-in
* PRNG.
*/
static VALUE
@@ -199,7 +199,7 @@ ossl_rand_egd_bytes(VALUE self, VALUE filename, VALUE len)
* call-seq:
* status? => true | false
*
- * Return true if the PRNG has been seeded with enough data, false otherwise.
+ * Return +true+ if the PRNG has been seeded with enough data, +false+ otherwise.
*/
static VALUE
ossl_rand_status(VALUE self)
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index f9c9d76fc2..18d5f5e9ec 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -46,54 +46,19 @@ static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
id_i_verify_hostname;
static ID id_i_io, id_i_context, id_i_hostname;
-/*
- * SSLContext class
- */
-static const struct {
- const char *name;
- SSL_METHOD *(*func)(void); /* FIXME: constify when dropping 0.9.8 */
- int version;
-} ossl_ssl_method_tab[] = {
-#if defined(HAVE_SSL_CTX_SET_MIN_PROTO_VERSION)
-#define OSSL_SSL_METHOD_ENTRY(name, version) \
- { #name, (SSL_METHOD *(*)(void))TLS_method, version }, \
- { #name"_server", (SSL_METHOD *(*)(void))TLS_server_method, version }, \
- { #name"_client", (SSL_METHOD *(*)(void))TLS_client_method, version }
-#else
-#define OSSL_SSL_METHOD_ENTRY(name, version) \
- { #name, (SSL_METHOD *(*)(void))name##_method, version }, \
- { #name"_server", (SSL_METHOD *(*)(void))name##_server_method, version }, \
- { #name"_client", (SSL_METHOD *(*)(void))name##_client_method, version }
-#endif
-#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL2_METHOD) && defined(HAVE_SSLV2_METHOD)
- OSSL_SSL_METHOD_ENTRY(SSLv2, SSL2_VERSION),
-#endif
-#if !defined(OPENSSL_NO_SSL3) && !defined(OPENSSL_NO_SSL3_METHOD) && defined(HAVE_SSLV3_METHOD)
- OSSL_SSL_METHOD_ENTRY(SSLv3, SSL3_VERSION),
-#endif
-#if !defined(OPENSSL_NO_TLS1) && !defined(OPENSSL_NO_TLS1_METHOD)
- OSSL_SSL_METHOD_ENTRY(TLSv1, TLS1_VERSION),
-#endif
-#if !defined(OPENSSL_NO_TLS1_1) && !defined(OPENSSL_NO_TLS1_1_METHOD) && defined(HAVE_TLSV1_1_METHOD)
- OSSL_SSL_METHOD_ENTRY(TLSv1_1, TLS1_1_VERSION),
-#endif
-#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_TLS1_2_METHOD) && defined(HAVE_TLSV1_2_METHOD)
- OSSL_SSL_METHOD_ENTRY(TLSv1_2, TLS1_2_VERSION),
-#endif
- OSSL_SSL_METHOD_ENTRY(SSLv23, 0),
-#undef OSSL_SSL_METHOD_ENTRY
-};
-
static int ossl_ssl_ex_vcb_idx;
-static int ossl_ssl_ex_store_p;
static int ossl_ssl_ex_ptr_idx;
+static int ossl_sslctx_ex_ptr_idx;
+#if !defined(HAVE_X509_STORE_UP_REF)
+static int ossl_sslctx_ex_store_p;
+#endif
static void
ossl_sslctx_free(void *ptr)
{
SSL_CTX *ctx = ptr;
#if !defined(HAVE_X509_STORE_UP_REF)
- if(ctx && SSL_CTX_get_ex_data(ctx, ossl_ssl_ex_store_p)== (void*)1)
+ if (ctx && SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_store_p))
ctx->cert_store = NULL;
#endif
SSL_CTX_free(ctx);
@@ -111,22 +76,24 @@ static VALUE
ossl_sslctx_s_alloc(VALUE klass)
{
SSL_CTX *ctx;
- long mode = SSL_MODE_ENABLE_PARTIAL_WRITE |
- SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER;
+ long mode = 0 |
+ SSL_MODE_ENABLE_PARTIAL_WRITE |
+ SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
+ SSL_MODE_RELEASE_BUFFERS;
VALUE obj;
-#ifdef SSL_MODE_RELEASE_BUFFERS
- mode |= SSL_MODE_RELEASE_BUFFERS;
-#endif
-
obj = TypedData_Wrap_Struct(klass, &ossl_sslctx_type, 0);
+#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
+ ctx = SSL_CTX_new(TLS_method());
+#else
ctx = SSL_CTX_new(SSLv23_method());
+#endif
if (!ctx) {
ossl_raise(eSSLError, "SSL_CTX_new");
}
SSL_CTX_set_mode(ctx, mode);
RTYPEDDATA_DATA(obj) = ctx;
- SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_ptr_idx, (void*)obj);
+ SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_ptr_idx, (void *)obj);
#if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
/* We use SSL_CTX_set1_curves_list() to specify the curve used in ECDH. It
@@ -143,49 +110,89 @@ ossl_sslctx_s_alloc(VALUE klass)
return obj;
}
+static int
+parse_proto_version(VALUE str)
+{
+ int i;
+ static const struct {
+ const char *name;
+ int version;
+ } map[] = {
+ { "SSL2", SSL2_VERSION },
+ { "SSL3", SSL3_VERSION },
+ { "TLS1", TLS1_VERSION },
+ { "TLS1_1", TLS1_1_VERSION },
+ { "TLS1_2", TLS1_2_VERSION },
+#ifdef TLS1_3_VERSION
+ { "TLS1_3", TLS1_3_VERSION },
+#endif
+ };
+
+ if (NIL_P(str))
+ return 0;
+ if (RB_INTEGER_TYPE_P(str))
+ return NUM2INT(str);
+
+ if (SYMBOL_P(str))
+ str = rb_sym2str(str);
+ StringValue(str);
+ for (i = 0; i < numberof(map); i++)
+ if (!strncmp(map[i].name, RSTRING_PTR(str), RSTRING_LEN(str)))
+ return map[i].version;
+ rb_raise(rb_eArgError, "unrecognized version %+"PRIsVALUE, str);
+}
+
/*
* call-seq:
- * ctx.ssl_version = :TLSv1
- * ctx.ssl_version = "SSLv23_client"
+ * ctx.set_minmax_proto_version(min, max) -> nil
*
- * Sets the SSL/TLS protocol version for the context. This forces connections to
- * use only the specified protocol version.
- *
- * You can get a list of valid versions with OpenSSL::SSL::SSLContext::METHODS
+ * Sets the minimum and maximum supported protocol versions. See #min_version=
+ * and #max_version=.
*/
static VALUE
-ossl_sslctx_set_ssl_version(VALUE self, VALUE ssl_method)
+ossl_sslctx_set_minmax_proto_version(VALUE self, VALUE min_v, VALUE max_v)
{
SSL_CTX *ctx;
- const char *s;
- VALUE m = ssl_method;
- int i;
+ int min, max;
GetSSLCTX(self, ctx);
- if (RB_TYPE_P(ssl_method, T_SYMBOL))
- m = rb_sym2str(ssl_method);
- s = StringValueCStr(m);
- for (i = 0; i < numberof(ossl_ssl_method_tab); i++) {
- if (strcmp(ossl_ssl_method_tab[i].name, s) == 0) {
-#if defined(HAVE_SSL_CTX_SET_MIN_PROTO_VERSION)
- int version = ossl_ssl_method_tab[i].version;
-#endif
- SSL_METHOD *method = ossl_ssl_method_tab[i].func();
-
- if (SSL_CTX_set_ssl_version(ctx, method) != 1)
- ossl_raise(eSSLError, "SSL_CTX_set_ssl_version");
+ min = parse_proto_version(min_v);
+ max = parse_proto_version(max_v);
+
+#ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
+ if (!SSL_CTX_set_min_proto_version(ctx, min))
+ ossl_raise(eSSLError, "SSL_CTX_set_min_proto_version");
+ if (!SSL_CTX_set_max_proto_version(ctx, max))
+ ossl_raise(eSSLError, "SSL_CTX_set_max_proto_version");
+#else
+ {
+ unsigned long sum = 0, opts = 0;
+ int i;
+ static const struct {
+ int ver;
+ unsigned long opts;
+ } options_map[] = {
+ { SSL2_VERSION, SSL_OP_NO_SSLv2 },
+ { SSL3_VERSION, SSL_OP_NO_SSLv3 },
+ { TLS1_VERSION, SSL_OP_NO_TLSv1 },
+ { TLS1_1_VERSION, SSL_OP_NO_TLSv1_1 },
+ { TLS1_2_VERSION, SSL_OP_NO_TLSv1_2 },
+# if defined(TLS1_3_VERSION)
+ { TLS1_3_VERSION, SSL_OP_NO_TLSv1_3 },
+# endif
+ };
-#if defined(HAVE_SSL_CTX_SET_MIN_PROTO_VERSION)
- if (!SSL_CTX_set_min_proto_version(ctx, version))
- ossl_raise(eSSLError, "SSL_CTX_set_min_proto_version");
- if (!SSL_CTX_set_max_proto_version(ctx, version))
- ossl_raise(eSSLError, "SSL_CTX_set_max_proto_version");
-#endif
- return ssl_method;
- }
+ for (i = 0; i < numberof(options_map); i++) {
+ sum |= options_map[i].opts;
+ if (min && min > options_map[i].ver || max && max < options_map[i].ver)
+ opts |= options_map[i].opts;
+ }
+ SSL_CTX_clear_options(ctx, sum);
+ SSL_CTX_set_options(ctx, opts);
}
+#endif
- ossl_raise(rb_eArgError, "unknown SSL method `%"PRIsVALUE"'.", m);
+ return Qnil;
}
static VALUE
@@ -380,13 +387,10 @@ ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
{
VALUE ary, ssl_obj, ret_obj;
SSL_SESSION *sess;
- void *ptr;
int state = 0;
OSSL_Debug("SSL SESSION get callback entered");
- if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL)
- return NULL;
- ssl_obj = (VALUE)ptr;
+ ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
ary = rb_ary_new2(2);
rb_ary_push(ary, ssl_obj);
rb_ary_push(ary, rb_str_new((const char *)buf, len));
@@ -399,7 +403,7 @@ ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
if (!rb_obj_is_instance_of(ret_obj, cSSLSession))
return NULL;
- SafeGetSSLSession(ret_obj, sess);
+ GetSSLSession(ret_obj, sess);
*copy = 1;
return sess;
@@ -424,14 +428,11 @@ static int
ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess)
{
VALUE ary, ssl_obj, sess_obj;
- void *ptr;
int state = 0;
OSSL_Debug("SSL SESSION new callback entered");
- if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL)
- return 1;
- ssl_obj = (VALUE)ptr;
+ ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
sess_obj = rb_obj_alloc(cSSLSession);
SSL_SESSION_up_ref(sess);
DATA_PTR(sess_obj) = sess;
@@ -473,14 +474,18 @@ static void
ossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess)
{
VALUE ary, sslctx_obj, sess_obj;
- void *ptr;
int state = 0;
+ /*
+ * This callback is also called for all sessions in the internal store
+ * when SSL_CTX_free() is called.
+ */
+ if (rb_during_gc())
+ return;
+
OSSL_Debug("SSL SESSION remove callback entered");
- if ((ptr = SSL_CTX_get_ex_data(ctx, ossl_ssl_ex_ptr_idx)) == NULL)
- return;
- sslctx_obj = (VALUE)ptr;
+ sslctx_obj = (VALUE)SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_ptr_idx);
sess_obj = rb_obj_alloc(cSSLSession);
SSL_SESSION_up_ref(sess);
DATA_PTR(sess_obj) = sess;
@@ -516,7 +521,6 @@ ossl_sslctx_add_extra_chain_cert_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, arg))
static VALUE ossl_sslctx_setup(VALUE self);
-#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
static VALUE
ossl_call_servername_cb(VALUE ary)
{
@@ -551,16 +555,13 @@ static int
ssl_servername_cb(SSL *ssl, int *ad, void *arg)
{
VALUE ary, ssl_obj;
- void *ptr;
int state = 0;
const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
if (!servername)
return SSL_TLSEXT_ERR_OK;
- if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL)
- return SSL_TLSEXT_ERR_ALERT_FATAL;
- ssl_obj = (VALUE)ptr;
+ ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
ary = rb_ary_new2(2);
rb_ary_push(ary, ssl_obj);
rb_ary_push(ary, rb_str_new2(servername));
@@ -573,18 +574,13 @@ ssl_servername_cb(SSL *ssl, int *ad, void *arg)
return SSL_TLSEXT_ERR_OK;
}
-#endif
static void
ssl_renegotiation_cb(const SSL *ssl)
{
VALUE ssl_obj, sslctx_obj, cb;
- void *ptr;
-
- if ((ptr = SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)) == NULL)
- ossl_raise(eSSLError, "SSL object could not be retrieved");
- ssl_obj = (VALUE)ptr;
+ ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
sslctx_obj = rb_attr_get(ssl_obj, id_i_context);
cb = rb_attr_get(sslctx_obj, id_i_renegotiation_cb);
if (NIL_P(cb)) return;
@@ -592,7 +588,7 @@ ssl_renegotiation_cb(const SSL *ssl)
(void) rb_funcall(cb, rb_intern("call"), 1, ssl_obj);
}
-#if defined(HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB) || \
+#if !defined(OPENSSL_NO_NEXTPROTONEG) || \
defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB)
static VALUE
ssl_npn_encode_protocol_i(VALUE cur, VALUE encoded)
@@ -677,7 +673,7 @@ ssl_npn_select_cb_common(SSL *ssl, VALUE cb, const unsigned char **out,
}
#endif
-#ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
+#ifndef OPENSSL_NO_NEXTPROTONEG
static int
ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
void *arg)
@@ -737,7 +733,11 @@ ossl_sslctx_get_options(VALUE self)
{
SSL_CTX *ctx;
GetSSLCTX(self, ctx);
- return LONG2NUM(SSL_CTX_get_options(ctx));
+ /*
+ * Do explicit cast because SSL_CTX_get_options() returned (signed) long in
+ * OpenSSL before 1.1.0.
+ */
+ return ULONG2NUM((unsigned long)SSL_CTX_get_options(ctx));
}
/*
@@ -756,7 +756,7 @@ ossl_sslctx_set_options(VALUE self, VALUE options)
if (NIL_P(options)) {
SSL_CTX_set_options(ctx, SSL_OP_ALL);
} else {
- SSL_CTX_set_options(ctx, NUM2LONG(options));
+ SSL_CTX_set_options(ctx, NUM2ULONG(options));
}
return self;
@@ -820,7 +820,7 @@ ossl_sslctx_setup(VALUE self)
* X509_STORE_free() doesn't care it.
* So we won't increment it but mark it by ex_data.
*/
- SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_store_p, (void *)1);
+ SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_store_p, ctx);
#else /* Fixed in OpenSSL 1.0.2; bff9ce4db38b (master), 5b4b9ce976fc (1.0.2) */
X509_STORE_up_ref(store);
#endif
@@ -891,7 +891,7 @@ ossl_sslctx_setup(VALUE self)
val = rb_attr_get(self, id_i_verify_depth);
if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2INT(val));
-#ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
+#ifndef OPENSSL_NO_NEXTPROTONEG
val = rb_attr_get(self, id_i_npn_protocols);
if (!NIL_P(val)) {
VALUE encoded = ssl_encode_npn_protocols(val);
@@ -946,13 +946,11 @@ ossl_sslctx_setup(VALUE self)
OSSL_Debug("SSL SESSION remove callback added");
}
-#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
val = rb_attr_get(self, id_i_servername_cb);
if (!NIL_P(val)) {
SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
OSSL_Debug("SSL TLSEXT servername callback added");
}
-#endif
return Qtrue;
}
@@ -989,12 +987,7 @@ ossl_sslctx_get_ciphers(VALUE self)
int i, num;
GetSSLCTX(self, ctx);
- if(!ctx){
- rb_warning("SSL_CTX is not initialized.");
- return Qnil;
- }
ciphers = SSL_CTX_get_ciphers(ctx);
-
if (!ciphers)
return rb_ary_new();
@@ -1204,7 +1197,7 @@ ossl_sslctx_set_security_level(VALUE self, VALUE value)
* call-seq:
* ctx.session_add(session) -> true | false
*
- * Adds +session+ to the session cache.
+ * Adds _session_ to the session cache.
*/
static VALUE
ossl_sslctx_session_add(VALUE self, VALUE arg)
@@ -1213,7 +1206,7 @@ ossl_sslctx_session_add(VALUE self, VALUE arg)
SSL_SESSION *sess;
GetSSLCTX(self, ctx);
- SafeGetSSLSession(arg, sess);
+ GetSSLSession(arg, sess);
return SSL_CTX_add_session(ctx, sess) == 1 ? Qtrue : Qfalse;
}
@@ -1222,7 +1215,7 @@ ossl_sslctx_session_add(VALUE self, VALUE arg)
* call-seq:
* ctx.session_remove(session) -> true | false
*
- * Removes +session+ from the session cache.
+ * Removes _session_ from the session cache.
*/
static VALUE
ossl_sslctx_session_remove(VALUE self, VALUE arg)
@@ -1231,7 +1224,7 @@ ossl_sslctx_session_remove(VALUE self, VALUE arg)
SSL_SESSION *sess;
GetSSLCTX(self, ctx);
- SafeGetSSLSession(arg, sess);
+ GetSSLSession(arg, sess);
return SSL_CTX_remove_session(ctx, sess) == 1 ? Qtrue : Qfalse;
}
@@ -1358,9 +1351,9 @@ ossl_sslctx_get_session_cache_stats(VALUE self)
/*
* call-seq:
- * ctx.flush_sessions(time | nil) -> self
+ * ctx.flush_sessions(time) -> self
*
- * Removes sessions in the internal cache that have expired at +time+.
+ * Removes sessions in the internal cache that have expired at _time_.
*/
static VALUE
ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
@@ -1422,10 +1415,10 @@ ossl_ssl_s_alloc(VALUE klass)
* SSLSocket.new(io) => aSSLSocket
* SSLSocket.new(io, ctx) => aSSLSocket
*
- * Creates a new SSL socket from +io+ which must be a real IO object (not an
+ * Creates a new SSL socket from _io_ which must be a real IO object (not an
* IO-like object that responds to read/write).
*
- * If +ctx+ is provided the SSL Sockets initial params will be taken from
+ * If _ctx_ is provided the SSL Sockets initial params will be taken from
* the context.
*
* The OpenSSL::Buffering module provides additional IO methods.
@@ -1485,7 +1478,7 @@ ossl_ssl_setup(VALUE self)
GetOpenFile(io, fptr);
rb_io_check_readable(fptr);
rb_io_check_writable(fptr);
- if (!SSL_set_fd(ssl, TO_SOCKET(FPTR_TO_FD(fptr))))
+ if (!SSL_set_fd(ssl, TO_SOCKET(fptr->fd)))
ossl_raise(eSSLError, "SSL_set_fd");
return Qtrue;
@@ -1528,6 +1521,9 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
int ret, ret2;
VALUE cb_state;
int nonblock = opts != Qfalse;
+#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
+ unsigned long err;
+#endif
rb_ivar_set(self, ID_callback_state, Qnil);
@@ -1551,16 +1547,33 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
case SSL_ERROR_WANT_WRITE:
if (no_exception_p(opts)) { return sym_wait_writable; }
write_would_block(nonblock);
- rb_io_wait_writable(FPTR_TO_FD(fptr));
+ rb_io_wait_writable(fptr->fd);
continue;
case SSL_ERROR_WANT_READ:
if (no_exception_p(opts)) { return sym_wait_readable; }
read_would_block(nonblock);
- rb_io_wait_readable(FPTR_TO_FD(fptr));
+ rb_io_wait_readable(fptr->fd);
continue;
case SSL_ERROR_SYSCALL:
if (errno) rb_sys_fail(funcname);
ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
+#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
+ case SSL_ERROR_SSL:
+ err = ERR_peek_last_error();
+ if (ERR_GET_LIB(err) == ERR_LIB_SSL &&
+ ERR_GET_REASON(err) == SSL_R_CERTIFICATE_VERIFY_FAILED) {
+ const char *err_msg = ERR_reason_error_string(err),
+ *verify_msg = X509_verify_cert_error_string(SSL_get_verify_result(ssl));
+ if (!err_msg)
+ err_msg = "(null)";
+ if (!verify_msg)
+ verify_msg = "(null)";
+ ossl_clear_error(); /* let ossl_raise() not append message */
+ ossl_raise(eSSLError, "%s returned=%d errno=%d state=%s: %s (%s)",
+ funcname, ret2, errno, SSL_state_string_long(ssl),
+ err_msg, verify_msg);
+ }
+#endif
default:
ossl_raise(eSSLError, "%s returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
}
@@ -1693,8 +1706,6 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
io = rb_attr_get(self, id_i_io);
GetOpenFile(io, fptr);
if (ssl_started(ssl)) {
- if(!nonblock && SSL_pending(ssl) <= 0)
- rb_thread_wait_fd(FPTR_TO_FD(fptr));
for (;;){
nread = SSL_read(ssl, RSTRING_PTR(str), RSTRING_LENINT(str));
switch(ssl_get_error(ssl, nread)){
@@ -1706,12 +1717,12 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
case SSL_ERROR_WANT_WRITE:
if (no_exception_p(opts)) { return sym_wait_writable; }
write_would_block(nonblock);
- rb_io_wait_writable(FPTR_TO_FD(fptr));
+ rb_io_wait_writable(fptr->fd);
continue;
case SSL_ERROR_WANT_READ:
if (no_exception_p(opts)) { return sym_wait_readable; }
read_would_block(nonblock);
- rb_io_wait_readable(FPTR_TO_FD(fptr));
+ rb_io_wait_readable(fptr->fd);
continue;
case SSL_ERROR_SYSCALL:
if (!ERR_peek_error()) {
@@ -1756,7 +1767,7 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
* ssl.sysread(length) => string
* ssl.sysread(length, buffer) => buffer
*
- * Reads +length+ bytes from the SSL connection. If a pre-allocated +buffer+
+ * Reads _length_ bytes from the SSL connection. If a pre-allocated _buffer_
* is provided the data will be written into it.
*/
static VALUE
@@ -1775,7 +1786,7 @@ ossl_ssl_read(int argc, VALUE *argv, VALUE self)
* block. If "exception: false" is passed, this method returns a symbol of
* :wait_readable, :wait_writable, or nil, rather than raising an exception.
*
- * Reads +length+ bytes from the SSL connection. If a pre-allocated +buffer+
+ * Reads _length_ bytes from the SSL connection. If a pre-allocated _buffer_
* is provided the data will be written into it.
*/
static VALUE
@@ -1812,12 +1823,12 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
case SSL_ERROR_WANT_WRITE:
if (no_exception_p(opts)) { return sym_wait_writable; }
write_would_block(nonblock);
- rb_io_wait_writable(FPTR_TO_FD(fptr));
+ rb_io_wait_writable(fptr->fd);
continue;
case SSL_ERROR_WANT_READ:
if (no_exception_p(opts)) { return sym_wait_readable; }
read_would_block(nonblock);
- rb_io_wait_readable(FPTR_TO_FD(fptr));
+ rb_io_wait_readable(fptr->fd);
continue;
case SSL_ERROR_SYSCALL:
if (errno) rb_sys_fail(0);
@@ -1845,7 +1856,7 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
* call-seq:
* ssl.syswrite(string) => Integer
*
- * Writes +string+ to the SSL connection.
+ * Writes _string_ to the SSL connection.
*/
static VALUE
ossl_ssl_write(VALUE self, VALUE str)
@@ -1857,7 +1868,7 @@ ossl_ssl_write(VALUE self, VALUE str)
* call-seq:
* ssl.syswrite_nonblock(string) => Integer
*
- * Writes +string+ to the SSL connection in a non-blocking manner. Raises an
+ * Writes _string_ to the SSL connection in a non-blocking manner. Raises an
* SSLError if writing would block.
*/
static VALUE
@@ -2001,22 +2012,21 @@ ossl_ssl_get_version(VALUE self)
}
/*
-* call-seq:
-* ssl.cipher => [name, version, bits, alg_bits]
-*
-* The cipher being used for the current connection
-*/
+ * call-seq:
+ * ssl.cipher -> nil or [name, version, bits, alg_bits]
+ *
+ * Returns the cipher suite actually used in the current session, or nil if
+ * no session has been established.
+ */
static VALUE
ossl_ssl_get_cipher(VALUE self)
{
SSL *ssl;
- SSL_CIPHER *cipher;
+ const SSL_CIPHER *cipher;
GetSSL(self, ssl);
-
- cipher = (SSL_CIPHER *)SSL_get_current_cipher(ssl);
-
- return ossl_ssl_cipher_to_ary(cipher);
+ cipher = SSL_get_current_cipher(ssl);
+ return cipher ? ossl_ssl_cipher_to_ary(cipher) : Qnil;
}
/*
@@ -2062,7 +2072,7 @@ ossl_ssl_pending(VALUE self)
* call-seq:
* ssl.session_reused? -> true | false
*
- * Returns true if a reused session was negotiated during the handshake.
+ * Returns +true+ if a reused session was negotiated during the handshake.
*/
static VALUE
ossl_ssl_session_reused(VALUE self)
@@ -2087,7 +2097,7 @@ ossl_ssl_set_session(VALUE self, VALUE arg1)
SSL_SESSION *sess;
GetSSL(self, ssl);
- SafeGetSSLSession(arg1, sess);
+ GetSSLSession(arg1, sess);
if (SSL_set_session(ssl, sess) != 1)
ossl_raise(eSSLError, "SSL_set_session");
@@ -2095,7 +2105,6 @@ ossl_ssl_set_session(VALUE self, VALUE arg1)
return arg1;
}
-#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
/*
* call-seq:
* ssl.hostname = hostname -> hostname
@@ -2122,7 +2131,6 @@ ossl_ssl_set_hostname(VALUE self, VALUE arg)
return arg;
}
-#endif
/*
* call-seq:
@@ -2166,7 +2174,7 @@ ossl_ssl_get_client_ca_list(VALUE self)
return ossl_x509name_sk2ary(ca);
}
-# ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
+# ifndef OPENSSL_NO_NEXTPROTONEG
/*
* call-seq:
* ssl.npn_protocol => String | nil
@@ -2242,9 +2250,6 @@ ossl_ssl_tmp_key(VALUE self)
void
Init_ossl_ssl(void)
{
- int i;
- VALUE ary;
-
#if 0
mOSSL = rb_define_module("OpenSSL");
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
@@ -2254,9 +2259,20 @@ Init_ossl_ssl(void)
ID_callback_state = rb_intern("callback_state");
- ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_vcb_idx",0,0,0);
- ossl_ssl_ex_store_p = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_store_p",0,0,0);
- ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0,(void *)"ossl_ssl_ex_ptr_idx",0,0,0);
+ ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0, (void *)"ossl_ssl_ex_vcb_idx", 0, 0, 0);
+ if (ossl_ssl_ex_vcb_idx < 0)
+ ossl_raise(rb_eRuntimeError, "SSL_get_ex_new_index");
+ ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0, (void *)"ossl_ssl_ex_ptr_idx", 0, 0, 0);
+ if (ossl_ssl_ex_ptr_idx < 0)
+ ossl_raise(rb_eRuntimeError, "SSL_get_ex_new_index");
+ ossl_sslctx_ex_ptr_idx = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_ptr_idx", 0, 0, 0);
+ if (ossl_sslctx_ex_ptr_idx < 0)
+ ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index");
+#if !defined(HAVE_X509_STORE_UP_REF)
+ ossl_sslctx_ex_store_p = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_store_p", 0, 0, 0);
+ if (ossl_sslctx_ex_store_p < 0)
+ ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index");
+#endif
/* Document-module: OpenSSL::SSL
*
@@ -2272,7 +2288,7 @@ Init_ossl_ssl(void)
* This module contains configuration information about the SSL extension,
* for example if socket support is enabled, or the host name TLS extension
* is enabled. Constants in this module will always be defined, but contain
- * `true` or `false` values depending on the configuration of your OpenSSL
+ * +true+ or +false+ values depending on the configuration of your OpenSSL
* installation.
*/
mSSLExtConfig = rb_define_module_under(mOSSL, "ExtConfig");
@@ -2356,12 +2372,12 @@ Init_ossl_ssl(void)
* A callback for additional certificate verification. The callback is
* invoked for each certificate in the chain.
*
- * The callback is invoked with two values. +preverify_ok+ indicates
- * indicates if the verification was passed (true) or not (false).
- * +store_context+ is an OpenSSL::X509::StoreContext containing the
+ * The callback is invoked with two values. _preverify_ok_ indicates
+ * indicates if the verification was passed (+true+) or not (+false+).
+ * _store_context_ is an OpenSSL::X509::StoreContext containing the
* context used for certificate verification.
*
- * If the callback returns false, the chain verification is immediately
+ * If the callback returns +false+, the chain verification is immediately
* stopped and a bad_certificate alert is then sent.
*/
rb_attr(cSSLContext, rb_intern("verify_callback"), 1, 1, Qfalse);
@@ -2428,7 +2444,7 @@ Init_ossl_ssl(void)
/*
* A callback invoked when a new session was negotiated.
*
- * The callback is invoked with an SSLSocket. If false is returned the
+ * The callback is invoked with an SSLSocket. If +false+ is returned the
* session will be removed from the internal cache.
*/
rb_attr(cSSLContext, rb_intern("session_new_cb"), 1, 1, Qfalse);
@@ -2440,17 +2456,7 @@ Init_ossl_ssl(void)
*/
rb_attr(cSSLContext, rb_intern("session_remove_cb"), 1, 1, Qfalse);
-#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
rb_define_const(mSSLExtConfig, "HAVE_TLSEXT_HOST_NAME", Qtrue);
-#else
- rb_define_const(mSSLExtConfig, "HAVE_TLSEXT_HOST_NAME", Qfalse);
-#endif
-
-#ifdef TLS_DH_anon_WITH_AES_256_GCM_SHA384
- rb_define_const(mSSLExtConfig, "TLS_DH_anon_WITH_AES_256_GCM_SHA384", Qtrue);
-#else
- rb_define_const(mSSLExtConfig, "TLS_DH_anon_WITH_AES_256_GCM_SHA384", Qfalse);
-#endif
/*
* A callback invoked whenever a new handshake is initiated. May be used
@@ -2474,7 +2480,7 @@ Init_ossl_ssl(void)
* end
*/
rb_attr(cSSLContext, rb_intern("renegotiation_cb"), 1, 1, Qfalse);
-#ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
+#ifndef OPENSSL_NO_NEXTPROTONEG
/*
* An Enumerable of Strings. Each String represents a protocol to be
* advertised as the list of supported protocols for Next Protocol
@@ -2540,7 +2546,8 @@ Init_ossl_ssl(void)
rb_define_alias(cSSLContext, "ssl_timeout", "timeout");
rb_define_alias(cSSLContext, "ssl_timeout=", "timeout=");
- rb_define_method(cSSLContext, "ssl_version=", ossl_sslctx_set_ssl_version, 1);
+ rb_define_private_method(cSSLContext, "set_minmax_proto_version",
+ ossl_sslctx_set_minmax_proto_version, 2);
rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1);
rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1);
@@ -2608,14 +2615,6 @@ Init_ossl_ssl(void)
rb_define_method(cSSLContext, "options", ossl_sslctx_get_options, 0);
rb_define_method(cSSLContext, "options=", ossl_sslctx_set_options, 1);
- ary = rb_ary_new2(numberof(ossl_ssl_method_tab));
- for (i = 0; i < numberof(ossl_ssl_method_tab); i++) {
- rb_ary_push(ary, ID2SYM(rb_intern(ossl_ssl_method_tab[i].name)));
- }
- rb_obj_freeze(ary);
- /* The list of available SSL/TLS methods */
- rb_define_const(cSSLContext, "METHODS", ary);
-
/*
* Document-class: OpenSSL::SSL::SSLSocket
*/
@@ -2649,67 +2648,120 @@ Init_ossl_ssl(void)
rb_define_method(cSSLSocket, "session=", ossl_ssl_set_session, 1);
rb_define_method(cSSLSocket, "verify_result", ossl_ssl_get_verify_result, 0);
rb_define_method(cSSLSocket, "client_ca", ossl_ssl_get_client_ca_list, 0);
-#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
/* #hostname is defined in lib/openssl/ssl.rb */
rb_define_method(cSSLSocket, "hostname=", ossl_ssl_set_hostname, 1);
-#endif
# ifdef HAVE_SSL_GET_SERVER_TMP_KEY
rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0);
# endif
# ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0);
# endif
-# ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
+# ifndef OPENSSL_NO_NEXTPROTONEG
rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
# endif
#endif
-#define ossl_ssl_def_const(x) rb_define_const(mSSL, #x, LONG2NUM(SSL_##x))
+ rb_define_const(mSSL, "VERIFY_NONE", INT2NUM(SSL_VERIFY_NONE));
+ rb_define_const(mSSL, "VERIFY_PEER", INT2NUM(SSL_VERIFY_PEER));
+ rb_define_const(mSSL, "VERIFY_FAIL_IF_NO_PEER_CERT", INT2NUM(SSL_VERIFY_FAIL_IF_NO_PEER_CERT));
+ rb_define_const(mSSL, "VERIFY_CLIENT_ONCE", INT2NUM(SSL_VERIFY_CLIENT_ONCE));
- ossl_ssl_def_const(VERIFY_NONE);
- ossl_ssl_def_const(VERIFY_PEER);
- ossl_ssl_def_const(VERIFY_FAIL_IF_NO_PEER_CERT);
- ossl_ssl_def_const(VERIFY_CLIENT_ONCE);
- /* Introduce constants included in OP_ALL. These constants are mostly for
- * unset some bits in OP_ALL such as;
- * ctx.options = OP_ALL & ~OP_DONT_INSERT_EMPTY_FRAGMENTS
- */
- ossl_ssl_def_const(OP_MICROSOFT_SESS_ID_BUG);
- ossl_ssl_def_const(OP_NETSCAPE_CHALLENGE_BUG);
- ossl_ssl_def_const(OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG);
- ossl_ssl_def_const(OP_SSLREF2_REUSE_CERT_TYPE_BUG);
- ossl_ssl_def_const(OP_MICROSOFT_BIG_SSLV3_BUFFER);
- ossl_ssl_def_const(OP_MSIE_SSLV2_RSA_PADDING);
- ossl_ssl_def_const(OP_SSLEAY_080_CLIENT_DH_BUG);
- ossl_ssl_def_const(OP_TLS_D5_BUG);
- ossl_ssl_def_const(OP_TLS_BLOCK_PADDING_BUG);
- ossl_ssl_def_const(OP_DONT_INSERT_EMPTY_FRAGMENTS);
- ossl_ssl_def_const(OP_ALL);
- ossl_ssl_def_const(OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
- ossl_ssl_def_const(OP_SINGLE_ECDH_USE);
- ossl_ssl_def_const(OP_SINGLE_DH_USE);
- ossl_ssl_def_const(OP_EPHEMERAL_RSA);
- ossl_ssl_def_const(OP_CIPHER_SERVER_PREFERENCE);
- ossl_ssl_def_const(OP_TLS_ROLLBACK_BUG);
- ossl_ssl_def_const(OP_NO_SSLv2);
- ossl_ssl_def_const(OP_NO_SSLv3);
- ossl_ssl_def_const(OP_NO_TLSv1);
-#if defined(SSL_OP_NO_TLSv1_1)
- ossl_ssl_def_const(OP_NO_TLSv1_1);
+ rb_define_const(mSSL, "OP_ALL", ULONG2NUM(SSL_OP_ALL));
+ rb_define_const(mSSL, "OP_LEGACY_SERVER_CONNECT", ULONG2NUM(SSL_OP_LEGACY_SERVER_CONNECT));
+#ifdef SSL_OP_TLSEXT_PADDING /* OpenSSL 1.0.1h and OpenSSL 1.0.2 */
+ rb_define_const(mSSL, "OP_TLSEXT_PADDING", ULONG2NUM(SSL_OP_TLSEXT_PADDING));
+#endif
+#ifdef SSL_OP_SAFARI_ECDHE_ECDSA_BUG /* OpenSSL 1.0.1f and OpenSSL 1.0.2 */
+ rb_define_const(mSSL, "OP_SAFARI_ECDHE_ECDSA_BUG", ULONG2NUM(SSL_OP_SAFARI_ECDHE_ECDSA_BUG));
#endif
-#if defined(SSL_OP_NO_TLSv1_2)
- ossl_ssl_def_const(OP_NO_TLSv1_2);
+#ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1 */
+ rb_define_const(mSSL, "OP_ALLOW_NO_DHE_KEX", ULONG2NUM(SSL_OP_ALLOW_NO_DHE_KEX));
#endif
-#if defined(SSL_OP_NO_TICKET)
- ossl_ssl_def_const(OP_NO_TICKET);
+ rb_define_const(mSSL, "OP_DONT_INSERT_EMPTY_FRAGMENTS", ULONG2NUM(SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS));
+ rb_define_const(mSSL, "OP_NO_TICKET", ULONG2NUM(SSL_OP_NO_TICKET));
+ rb_define_const(mSSL, "OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION));
+ rb_define_const(mSSL, "OP_NO_COMPRESSION", ULONG2NUM(SSL_OP_NO_COMPRESSION));
+ rb_define_const(mSSL, "OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION", ULONG2NUM(SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION));
+#ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1 */
+ rb_define_const(mSSL, "OP_NO_ENCRYPT_THEN_MAC", ULONG2NUM(SSL_OP_NO_ENCRYPT_THEN_MAC));
#endif
-#if defined(SSL_OP_NO_COMPRESSION)
- ossl_ssl_def_const(OP_NO_COMPRESSION);
+ rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE));
+ rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG));
+#ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1 */
+ rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION));
#endif
- ossl_ssl_def_const(OP_PKCS1_CHECK_1);
- ossl_ssl_def_const(OP_PKCS1_CHECK_2);
- ossl_ssl_def_const(OP_NETSCAPE_CA_DN_BUG);
- ossl_ssl_def_const(OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
+ rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG));
+
+ rb_define_const(mSSL, "OP_NO_SSLv3", ULONG2NUM(SSL_OP_NO_SSLv3));
+ rb_define_const(mSSL, "OP_NO_TLSv1", ULONG2NUM(SSL_OP_NO_TLSv1));
+ rb_define_const(mSSL, "OP_NO_TLSv1_1", ULONG2NUM(SSL_OP_NO_TLSv1_1));
+ rb_define_const(mSSL, "OP_NO_TLSv1_2", ULONG2NUM(SSL_OP_NO_TLSv1_2));
+#ifdef SSL_OP_NO_TLSv1_3 /* OpenSSL 1.1.1 */
+ rb_define_const(mSSL, "OP_NO_TLSv1_3", ULONG2NUM(SSL_OP_NO_TLSv1_3));
+#endif
+
+ /* SSL_OP_* flags for DTLS */
+#if 0
+ rb_define_const(mSSL, "OP_NO_QUERY_MTU", ULONG2NUM(SSL_OP_NO_QUERY_MTU));
+ rb_define_const(mSSL, "OP_COOKIE_EXCHANGE", ULONG2NUM(SSL_OP_COOKIE_EXCHANGE));
+ rb_define_const(mSSL, "OP_CISCO_ANYCONNECT", ULONG2NUM(SSL_OP_CISCO_ANYCONNECT));
+#endif
+
+ /* Deprecated in OpenSSL 1.1.0. */
+ rb_define_const(mSSL, "OP_MICROSOFT_SESS_ID_BUG", ULONG2NUM(SSL_OP_MICROSOFT_SESS_ID_BUG));
+ /* Deprecated in OpenSSL 1.1.0. */
+ rb_define_const(mSSL, "OP_NETSCAPE_CHALLENGE_BUG", ULONG2NUM(SSL_OP_NETSCAPE_CHALLENGE_BUG));
+ /* Deprecated in OpenSSL 0.9.8q and 1.0.0c. */
+ rb_define_const(mSSL, "OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG", ULONG2NUM(SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG));
+ /* Deprecated in OpenSSL 1.0.1h and 1.0.2. */
+ rb_define_const(mSSL, "OP_SSLREF2_REUSE_CERT_TYPE_BUG", ULONG2NUM(SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG));
+ /* Deprecated in OpenSSL 1.1.0. */
+ rb_define_const(mSSL, "OP_MICROSOFT_BIG_SSLV3_BUFFER", ULONG2NUM(SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER));
+ /* Deprecated in OpenSSL 0.9.7h and 0.9.8b. */
+ rb_define_const(mSSL, "OP_MSIE_SSLV2_RSA_PADDING", ULONG2NUM(SSL_OP_MSIE_SSLV2_RSA_PADDING));
+ /* Deprecated in OpenSSL 1.1.0. */
+ rb_define_const(mSSL, "OP_SSLEAY_080_CLIENT_DH_BUG", ULONG2NUM(SSL_OP_SSLEAY_080_CLIENT_DH_BUG));
+ /* Deprecated in OpenSSL 1.1.0. */
+ rb_define_const(mSSL, "OP_TLS_D5_BUG", ULONG2NUM(SSL_OP_TLS_D5_BUG));
+ /* Deprecated in OpenSSL 1.1.0. */
+ rb_define_const(mSSL, "OP_TLS_BLOCK_PADDING_BUG", ULONG2NUM(SSL_OP_TLS_BLOCK_PADDING_BUG));
+ /* Deprecated in OpenSSL 1.1.0. */
+ rb_define_const(mSSL, "OP_SINGLE_ECDH_USE", ULONG2NUM(SSL_OP_SINGLE_ECDH_USE));
+ /* Deprecated in OpenSSL 1.1.0. */
+ rb_define_const(mSSL, "OP_SINGLE_DH_USE", ULONG2NUM(SSL_OP_SINGLE_DH_USE));
+ /* Deprecated in OpenSSL 1.0.1k and 1.0.2. */
+ rb_define_const(mSSL, "OP_EPHEMERAL_RSA", ULONG2NUM(SSL_OP_EPHEMERAL_RSA));
+ /* Deprecated in OpenSSL 1.1.0. */
+ rb_define_const(mSSL, "OP_NO_SSLv2", ULONG2NUM(SSL_OP_NO_SSLv2));
+ /* Deprecated in OpenSSL 1.0.1. */
+ rb_define_const(mSSL, "OP_PKCS1_CHECK_1", ULONG2NUM(SSL_OP_PKCS1_CHECK_1));
+ /* Deprecated in OpenSSL 1.0.1. */
+ rb_define_const(mSSL, "OP_PKCS1_CHECK_2", ULONG2NUM(SSL_OP_PKCS1_CHECK_2));
+ /* Deprecated in OpenSSL 1.1.0. */
+ rb_define_const(mSSL, "OP_NETSCAPE_CA_DN_BUG", ULONG2NUM(SSL_OP_NETSCAPE_CA_DN_BUG));
+ /* Deprecated in OpenSSL 1.1.0. */
+ rb_define_const(mSSL, "OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG", ULONG2NUM(SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG));
+
+
+ /*
+ * SSL/TLS version constants. Used by SSLContext#min_version= and
+ * #max_version=
+ */
+ /* SSL 2.0 */
+ rb_define_const(mSSL, "SSL2_VERSION", INT2NUM(SSL2_VERSION));
+ /* SSL 3.0 */
+ rb_define_const(mSSL, "SSL3_VERSION", INT2NUM(SSL3_VERSION));
+ /* TLS 1.0 */
+ rb_define_const(mSSL, "TLS1_VERSION", INT2NUM(TLS1_VERSION));
+ /* TLS 1.1 */
+ rb_define_const(mSSL, "TLS1_1_VERSION", INT2NUM(TLS1_1_VERSION));
+ /* TLS 1.2 */
+ rb_define_const(mSSL, "TLS1_2_VERSION", INT2NUM(TLS1_2_VERSION));
+#ifdef TLS1_3_VERSION /* OpenSSL 1.1.1 */
+ /* TLS 1.3 */
+ rb_define_const(mSSL, "TLS1_3_VERSION", INT2NUM(TLS1_3_VERSION));
+#endif
+
sym_exception = ID2SYM(rb_intern("exception"));
sym_wait_readable = ID2SYM(rb_intern("wait_readable"));
diff --git a/ext/openssl/ossl_ssl.h b/ext/openssl/ossl_ssl.h
index c1a3cd6c1d..535c56097c 100644
--- a/ext/openssl/ossl_ssl.h
+++ b/ext/openssl/ossl_ssl.h
@@ -24,11 +24,6 @@
} \
} while (0)
-#define SafeGetSSLSession(obj, sess) do { \
- OSSL_Check_Kind((obj), cSSLSession); \
- GetSSLSession((obj), (sess)); \
-} while (0)
-
extern const rb_data_type_t ossl_ssl_type;
extern const rb_data_type_t ossl_ssl_session_type;
extern VALUE mSSL;
diff --git a/ext/openssl/ossl_ssl_session.c b/ext/openssl/ossl_ssl_session.c
index 661f53eefb..5514087387 100644
--- a/ext/openssl/ossl_ssl_session.c
+++ b/ext/openssl/ossl_ssl_session.c
@@ -80,7 +80,7 @@ ossl_ssl_session_initialize_copy(VALUE self, VALUE other)
rb_check_frozen(self);
sess = RTYPEDDATA_DATA(self); /* XXX */
- SafeGetSSLSession(other, sess_other);
+ GetSSLSession(other, sess_other);
sess_new = ASN1_dup((i2d_of_void *)i2d_SSL_SESSION, (d2i_of_void *)d2i_SSL_SESSION,
(char *)sess_other);
@@ -93,8 +93,8 @@ ossl_ssl_session_initialize_copy(VALUE self, VALUE other)
return self;
}
-#if !defined(HAVE_SSL_SESSION_CMP)
-int ossl_SSL_SESSION_cmp(const SSL_SESSION *a, const SSL_SESSION *b)
+static int
+ossl_SSL_SESSION_cmp(const SSL_SESSION *a, const SSL_SESSION *b)
{
unsigned int a_len;
const unsigned char *a_sid = SSL_SESSION_get_id(a, &a_len);
@@ -108,23 +108,21 @@ int ossl_SSL_SESSION_cmp(const SSL_SESSION *a, const SSL_SESSION *b)
return CRYPTO_memcmp(a_sid, b_sid, a_len);
}
-#define SSL_SESSION_cmp(a, b) ossl_SSL_SESSION_cmp(a, b)
-#endif
/*
* call-seq:
* session1 == session2 -> boolean
*
- * Returns true if the two Session is the same, false if not.
+ * Returns +true+ if the two Session is the same, +false+ if not.
*/
static VALUE ossl_ssl_session_eq(VALUE val1, VALUE val2)
{
SSL_SESSION *ctx1, *ctx2;
GetSSLSession(val1, ctx1);
- SafeGetSSLSession(val2, ctx2);
+ GetSSLSession(val2, ctx2);
- switch (SSL_SESSION_cmp(ctx1, ctx2)) {
+ switch (ossl_SSL_SESSION_cmp(ctx1, ctx2)) {
case 0: return Qtrue;
default: return Qfalse;
}
@@ -319,7 +317,7 @@ void Init_ossl_ssl_session(void)
rb_define_alloc_func(cSSLSession, ossl_ssl_session_alloc);
rb_define_method(cSSLSession, "initialize", ossl_ssl_session_initialize, 1);
- rb_define_copy_func(cSSLSession, ossl_ssl_session_initialize_copy);
+ rb_define_method(cSSLSession, "initialize_copy", ossl_ssl_session_initialize_copy, 1);
rb_define_method(cSSLSession, "==", ossl_ssl_session_eq, 1);
diff --git a/ext/openssl/ossl_version.h b/ext/openssl/ossl_version.h
index be3eebe1f2..4167c9c83d 100644
--- a/ext/openssl/ossl_version.h
+++ b/ext/openssl/ossl_version.h
@@ -10,6 +10,6 @@
#if !defined(_OSSL_VERSION_H_)
#define _OSSL_VERSION_H_
-#define OSSL_VERSION "2.0.5"
+#define OSSL_VERSION "2.1.0"
#endif /* _OSSL_VERSION_H_ */
diff --git a/ext/openssl/ossl_x509.c b/ext/openssl/ossl_x509.c
index 19ec274ae1..8a061b0687 100644
--- a/ext/openssl/ossl_x509.c
+++ b/ext/openssl/ossl_x509.c
@@ -20,15 +20,10 @@ ossl_x509_time_adjust(ASN1_TIME *s, VALUE time)
{
time_t sec;
-#if defined(HAVE_ASN1_TIME_ADJ)
int off_days;
ossl_time_split(time, &sec, &off_days);
return X509_time_adj_ex(s, off_days, 0, &sec);
-#else
- sec = time_to_time_t(time);
- return X509_time_adj(s, 0, &sec);
-#endif
}
void
@@ -112,21 +107,15 @@ Init_ossl_x509(void)
DefX509Const(V_FLAG_INHIBIT_MAP);
/* Set by Store#flags= and StoreContext#flags=. */
DefX509Const(V_FLAG_NOTIFY_POLICY);
-#if defined(X509_V_FLAG_EXTENDED_CRL_SUPPORT)
/* Set by Store#flags= and StoreContext#flags=. Enables some additional
* features including support for indirect signed CRLs. */
DefX509Const(V_FLAG_EXTENDED_CRL_SUPPORT);
-#endif
-#if defined(X509_V_FLAG_USE_DELTAS)
/* Set by Store#flags= and StoreContext#flags=. Uses delta CRLs. If not
* specified, deltas are ignored. */
DefX509Const(V_FLAG_USE_DELTAS);
-#endif
-#if defined(X509_V_FLAG_CHECK_SS_SIGNATURE)
/* Set by Store#flags= and StoreContext#flags=. Enables checking of the
* signature of the root self-signed CA. */
DefX509Const(V_FLAG_CHECK_SS_SIGNATURE);
-#endif
#if defined(X509_V_FLAG_TRUSTED_FIRST)
/* Set by Store#flags= and StoreContext#flags=. When constructing a
* certificate chain, search the Store first for the issuer certificate.
@@ -161,10 +150,8 @@ Init_ossl_x509(void)
DefX509Const(PURPOSE_ANY);
/* Set by Store#purpose=. OCSP helper. */
DefX509Const(PURPOSE_OCSP_HELPER);
-#if defined(X509_PURPOSE_TIMESTAMP_SIGN)
/* Set by Store#purpose=. Time stamps signer. */
DefX509Const(PURPOSE_TIMESTAMP_SIGN);
-#endif
DefX509Const(TRUST_COMPAT);
DefX509Const(TRUST_SSL_CLIENT);
@@ -173,9 +160,7 @@ Init_ossl_x509(void)
DefX509Const(TRUST_OBJECT_SIGN);
DefX509Const(TRUST_OCSP_SIGN);
DefX509Const(TRUST_OCSP_REQUEST);
-#if defined(X509_TRUST_TSA)
DefX509Const(TRUST_TSA);
-#endif
DefX509Default(CERT_AREA, cert_area);
DefX509Default(CERT_DIR, cert_dir);
diff --git a/ext/openssl/ossl_x509.h b/ext/openssl/ossl_x509.h
index a60f7c3da3..4fadfa6b82 100644
--- a/ext/openssl/ossl_x509.h
+++ b/ext/openssl/ossl_x509.h
@@ -41,7 +41,6 @@ extern VALUE cX509Cert;
extern VALUE eX509CertError;
VALUE ossl_x509_new(X509 *);
-VALUE ossl_x509_new_from_file(VALUE);
X509 *GetX509CertPtr(VALUE);
X509 *DupX509CertPtr(VALUE);
void Init_ossl_x509cert(void);
@@ -54,7 +53,6 @@ extern VALUE eX509CRLError;
VALUE ossl_x509crl_new(X509_CRL *);
X509_CRL *GetX509CRLPtr(VALUE);
-X509_CRL *DupX509CRLPtr(VALUE);
void Init_ossl_x509crl(void);
/*
@@ -84,9 +82,7 @@ void Init_ossl_x509name(void);
extern VALUE cX509Req;
extern VALUE eX509ReqError;
-VALUE ossl_x509req_new(X509_REQ *);
X509_REQ *GetX509ReqPtr(VALUE);
-X509_REQ *DupX509ReqPtr(VALUE);
void Init_ossl_x509req(void);
/*
@@ -106,11 +102,8 @@ extern VALUE cX509Store;
extern VALUE cX509StoreContext;
extern VALUE eX509StoreError;
-VALUE ossl_x509store_new(X509_STORE *);
X509_STORE *GetX509StorePtr(VALUE);
-X509_STORE *DupX509StorePtr(VALUE);
-X509_STORE_CTX *GetX509StCtxtPtr(VALUE);
void Init_ossl_x509store(void);
/*
diff --git a/ext/openssl/ossl_x509attr.c b/ext/openssl/ossl_x509attr.c
index ae0b347b5f..60846cfe9d 100644
--- a/ext/openssl/ossl_x509attr.c
+++ b/ext/openssl/ossl_x509attr.c
@@ -23,10 +23,6 @@
ossl_raise(rb_eRuntimeError, "ATTR wasn't initialized!"); \
} \
} while (0)
-#define SafeGetX509Attr(obj, attr) do { \
- OSSL_Check_Kind((obj), cX509Attr); \
- GetX509Attr((obj), (attr)); \
-} while (0)
/*
* Classes
@@ -76,7 +72,7 @@ GetX509AttrPtr(VALUE obj)
{
X509_ATTRIBUTE *attr;
- SafeGetX509Attr(obj, attr);
+ GetX509Attr(obj, attr);
return attr;
}
@@ -134,7 +130,7 @@ ossl_x509attr_initialize_copy(VALUE self, VALUE other)
rb_check_frozen(self);
GetX509Attr(self, attr);
- SafeGetX509Attr(other, attr_other);
+ GetX509Attr(other, attr_other);
attr_new = X509_ATTRIBUTE_dup(attr_other);
if (!attr_new)
@@ -319,7 +315,7 @@ Init_ossl_x509attr(void)
cX509Attr = rb_define_class_under(mX509, "Attribute", rb_cObject);
rb_define_alloc_func(cX509Attr, ossl_x509attr_alloc);
rb_define_method(cX509Attr, "initialize", ossl_x509attr_initialize, -1);
- rb_define_copy_func(cX509Attr, ossl_x509attr_initialize_copy);
+ rb_define_method(cX509Attr, "initialize_copy", ossl_x509attr_initialize_copy, 1);
rb_define_method(cX509Attr, "oid=", ossl_x509attr_set_oid, 1);
rb_define_method(cX509Attr, "oid", ossl_x509attr_get_oid, 0);
rb_define_method(cX509Attr, "value=", ossl_x509attr_set_value, 1);
diff --git a/ext/openssl/ossl_x509cert.c b/ext/openssl/ossl_x509cert.c
index 87086a7c59..003a9c1949 100644
--- a/ext/openssl/ossl_x509cert.c
+++ b/ext/openssl/ossl_x509cert.c
@@ -23,10 +23,6 @@
ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \
} \
} while (0)
-#define SafeGetX509(obj, x509) do { \
- OSSL_Check_Kind((obj), cX509Cert); \
- GetX509((obj), (x509)); \
-} while (0)
/*
* Classes
@@ -71,46 +67,12 @@ ossl_x509_new(X509 *x509)
return obj;
}
-VALUE
-ossl_x509_new_from_file(VALUE filename)
-{
- X509 *x509;
- FILE *fp;
- VALUE obj;
-
- rb_check_safe_obj(filename);
- obj = NewX509(cX509Cert);
- if (!(fp = fopen(StringValueCStr(filename), "r"))) {
- ossl_raise(eX509CertError, "%s", strerror(errno));
- }
- rb_fd_fix_cloexec(fileno(fp));
- x509 = PEM_read_X509(fp, NULL, NULL, NULL);
- /*
- * prepare for DER...
-#if !defined(OPENSSL_NO_FP_API)
- if (!x509) {
- (void)ERR_get_error();
- rewind(fp);
-
- x509 = d2i_X509_fp(fp, NULL);
- }
-#endif
- */
- fclose(fp);
- if (!x509) {
- ossl_raise(eX509CertError, NULL);
- }
- SetX509(obj, x509);
-
- return obj;
-}
-
X509 *
GetX509CertPtr(VALUE obj)
{
X509 *x509;
- SafeGetX509(obj, x509);
+ GetX509(obj, x509);
return x509;
}
@@ -120,7 +82,7 @@ DupX509CertPtr(VALUE obj)
{
X509 *x509;
- SafeGetX509(obj, x509);
+ GetX509(obj, x509);
X509_up_ref(x509);
@@ -184,7 +146,7 @@ ossl_x509_copy(VALUE self, VALUE other)
if (self == other) return self;
GetX509(self, a);
- SafeGetX509(other, b);
+ GetX509(other, b);
x509 = X509_dup(b);
if (!x509) ossl_raise(eX509CertError, NULL);
@@ -573,7 +535,7 @@ ossl_x509_sign(VALUE self, VALUE key, VALUE digest)
const EVP_MD *md;
pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
- md = GetDigestPtr(digest);
+ md = ossl_evp_get_digestbyname(digest);
GetX509(self, x509);
if (!X509_sign(x509, pkey, md)) {
ossl_raise(eX509CertError, NULL);
@@ -586,7 +548,8 @@ ossl_x509_sign(VALUE self, VALUE key, VALUE digest)
* call-seq:
* cert.verify(key) => true | false
*
- * Checks that cert signature is made with PRIVversion of this PUBLIC 'key'
+ * Verifies the signature of the certificate, with the public key _key_. _key_
+ * must be an instance of OpenSSL::PKey.
*/
static VALUE
ossl_x509_verify(VALUE self, VALUE key)
@@ -610,9 +573,10 @@ ossl_x509_verify(VALUE self, VALUE key)
/*
* call-seq:
- * cert.check_private_key(key)
+ * cert.check_private_key(key) -> true | false
*
- * Checks if 'key' is PRIV key for this cert
+ * Returns +true+ if _key_ is the corresponding private key to the Subject
+ * Public Key Information, +false+ otherwise.
*/
static VALUE
ossl_x509_check_private_key(VALUE self, VALUE key)
@@ -829,7 +793,7 @@ Init_ossl_x509cert(void)
rb_define_alloc_func(cX509Cert, ossl_x509_alloc);
rb_define_method(cX509Cert, "initialize", ossl_x509_initialize, -1);
- rb_define_copy_func(cX509Cert, ossl_x509_copy);
+ rb_define_method(cX509Cert, "initialize_copy", ossl_x509_copy, 1);
rb_define_method(cX509Cert, "to_der", ossl_x509_to_der, 0);
rb_define_method(cX509Cert, "to_pem", ossl_x509_to_pem, 0);
diff --git a/ext/openssl/ossl_x509crl.c b/ext/openssl/ossl_x509crl.c
index 035025ab69..5ecd7ea0b2 100644
--- a/ext/openssl/ossl_x509crl.c
+++ b/ext/openssl/ossl_x509crl.c
@@ -23,10 +23,6 @@
ossl_raise(rb_eRuntimeError, "CRL wasn't initialized!"); \
} \
} while (0)
-#define SafeGetX509CRL(obj, crl) do { \
- OSSL_Check_Kind((obj), cX509CRL); \
- GetX509CRL((obj), (crl)); \
-} while (0)
/*
* Classes
@@ -56,18 +52,7 @@ GetX509CRLPtr(VALUE obj)
{
X509_CRL *crl;
- SafeGetX509CRL(obj, crl);
-
- return crl;
-}
-
-X509_CRL *
-DupX509CRLPtr(VALUE obj)
-{
- X509_CRL *crl;
-
- SafeGetX509CRL(obj, crl);
- X509_CRL_up_ref(crl);
+ GetX509CRL(obj, crl);
return crl;
}
@@ -137,7 +122,7 @@ ossl_x509crl_copy(VALUE self, VALUE other)
rb_check_frozen(self);
if (self == other) return self;
GetX509CRL(self, a);
- SafeGetX509CRL(other, b);
+ GetX509CRL(other, b);
if (!(crl = X509_CRL_dup(b))) {
ossl_raise(eX509CRLError, NULL);
}
@@ -223,10 +208,14 @@ static VALUE
ossl_x509crl_get_last_update(VALUE self)
{
X509_CRL *crl;
+ const ASN1_TIME *time;
GetX509CRL(self, crl);
+ time = X509_CRL_get0_lastUpdate(crl);
+ if (!time)
+ return Qnil;
- return asn1time_to_time(X509_CRL_get0_lastUpdate(crl));
+ return asn1time_to_time(time);
}
static VALUE
@@ -250,10 +239,14 @@ static VALUE
ossl_x509crl_get_next_update(VALUE self)
{
X509_CRL *crl;
+ const ASN1_TIME *time;
GetX509CRL(self, crl);
+ time = X509_CRL_get0_nextUpdate(crl);
+ if (!time)
+ return Qnil;
- return asn1time_to_time(X509_CRL_get0_nextUpdate(crl));
+ return asn1time_to_time(time);
}
static VALUE
@@ -354,7 +347,7 @@ ossl_x509crl_sign(VALUE self, VALUE key, VALUE digest)
GetX509CRL(self, crl);
pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
- md = GetDigestPtr(digest);
+ md = ossl_evp_get_digestbyname(digest);
if (!X509_CRL_sign(crl, pkey, md)) {
ossl_raise(eX509CRLError, NULL);
}
@@ -520,7 +513,7 @@ Init_ossl_x509crl(void)
rb_define_alloc_func(cX509CRL, ossl_x509crl_alloc);
rb_define_method(cX509CRL, "initialize", ossl_x509crl_initialize, -1);
- rb_define_copy_func(cX509CRL, ossl_x509crl_copy);
+ rb_define_method(cX509CRL, "initialize_copy", ossl_x509crl_copy, 1);
rb_define_method(cX509CRL, "version", ossl_x509crl_get_version, 0);
rb_define_method(cX509CRL, "version=", ossl_x509crl_set_version, 1);
diff --git a/ext/openssl/ossl_x509ext.c b/ext/openssl/ossl_x509ext.c
index b92b0786b2..2d9a7a31e8 100644
--- a/ext/openssl/ossl_x509ext.c
+++ b/ext/openssl/ossl_x509ext.c
@@ -23,10 +23,6 @@
ossl_raise(rb_eRuntimeError, "EXT wasn't initialized!"); \
} \
} while (0)
-#define SafeGetX509Ext(obj, ext) do { \
- OSSL_Check_Kind((obj), cX509Ext); \
- GetX509Ext((obj), (ext)); \
-} while (0)
#define MakeX509ExtFactory(klass, obj, ctx) do { \
(obj) = TypedData_Wrap_Struct((klass), &ossl_x509extfactory_type, 0); \
if (!((ctx) = OPENSSL_malloc(sizeof(X509V3_CTX)))) \
@@ -90,7 +86,7 @@ GetX509ExtPtr(VALUE obj)
{
X509_EXTENSION *ext;
- SafeGetX509Ext(obj, ext);
+ GetX509Ext(obj, ext);
return ext;
}
@@ -263,15 +259,15 @@ ossl_x509ext_alloc(VALUE klass)
/*
* call-seq:
- * OpenSSL::X509::Extension.new asn1
- * OpenSSL::X509::Extension.new name, value
- * OpenSSL::X509::Extension.new name, value, critical
+ * OpenSSL::X509::Extension.new(der)
+ * OpenSSL::X509::Extension.new(oid, value)
+ * OpenSSL::X509::Extension.new(oid, value, critical)
*
* Creates an X509 extension.
*
- * The extension may be created from +asn1+ data or from an extension +name+
- * and +value+. The +name+ may be either an OID or an extension name. If
- * +critical+ is true the extension is marked critical.
+ * The extension may be created from _der_ data or from an extension _oid_
+ * and _value_. The _oid_ may be either an OID or an extension name. If
+ * _critical_ is +true+ the extension is marked critical.
*/
static VALUE
ossl_x509ext_initialize(int argc, VALUE *argv, VALUE self)
@@ -305,7 +301,7 @@ ossl_x509ext_initialize_copy(VALUE self, VALUE other)
rb_check_frozen(self);
GetX509Ext(self, ext);
- SafeGetX509Ext(other, ext_other);
+ GetX509Ext(other, ext_other);
ext_new = X509_EXTENSION_dup(ext_other);
if (!ext_new)
@@ -469,7 +465,7 @@ Init_ossl_x509ext(void)
cX509Ext = rb_define_class_under(mX509, "Extension", rb_cObject);
rb_define_alloc_func(cX509Ext, ossl_x509ext_alloc);
rb_define_method(cX509Ext, "initialize", ossl_x509ext_initialize, -1);
- rb_define_copy_func(cX509Ext, ossl_x509ext_initialize_copy);
+ rb_define_method(cX509Ext, "initialize_copy", ossl_x509ext_initialize_copy, 1);
rb_define_method(cX509Ext, "oid=", ossl_x509ext_set_oid, 1);
rb_define_method(cX509Ext, "value=", ossl_x509ext_set_value, 1);
rb_define_method(cX509Ext, "critical=", ossl_x509ext_set_critical, 1);
diff --git a/ext/openssl/ossl_x509name.c b/ext/openssl/ossl_x509name.c
index ac98c1b94c..b2063954d1 100644
--- a/ext/openssl/ossl_x509name.c
+++ b/ext/openssl/ossl_x509name.c
@@ -23,10 +23,6 @@
ossl_raise(rb_eRuntimeError, "Name wasn't initialized."); \
} \
} while (0)
-#define SafeGetX509Name(obj, name) do { \
- OSSL_Check_Kind((obj), cX509Name); \
- GetX509Name((obj), (name)); \
-} while (0)
#define OBJECT_TYPE_TEMPLATE \
rb_const_get(cX509Name, rb_intern("OBJECT_TYPE_TEMPLATE"))
@@ -81,7 +77,7 @@ GetX509NamePtr(VALUE obj)
{
X509_NAME *name;
- SafeGetX509Name(obj, name);
+ GetX509Name(obj, name);
return name;
}
@@ -135,15 +131,15 @@ ossl_x509name_init_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, args))
*
* Creates a new Name.
*
- * A name may be created from a DER encoded string +der+, an Array
- * representing a +distinguished_name+ or a +distinguished_name+ along with a
- * +template+.
+ * A name may be created from a DER encoded string _der_, an Array
+ * representing a _distinguished_name_ or a _distinguished_name_ along with a
+ * _template_.
*
* name = OpenSSL::X509::Name.new [['CN', 'nobody'], ['DC', 'example']]
*
* name = OpenSSL::X509::Name.new name.to_der
*
- * See add_entry for a description of the +distinguished_name+ Array's
+ * See add_entry for a description of the _distinguished_name_ Array's
* contents
*/
static VALUE
@@ -188,7 +184,7 @@ ossl_x509name_initialize_copy(VALUE self, VALUE other)
rb_check_frozen(self);
GetX509Name(self, name);
- SafeGetX509Name(other, name_other);
+ GetX509Name(other, name_other);
name_new = X509_NAME_dup(name_other);
if (!name_new)
@@ -202,9 +198,9 @@ ossl_x509name_initialize_copy(VALUE self, VALUE other)
/*
* call-seq:
- * name.add_entry(oid, value [, type]) => self
+ * name.add_entry(oid, value [, type], loc: -1, set: 0) => self
*
- * Adds a new entry with the given +oid+ and +value+ to this name. The +oid+
+ * Adds a new entry with the given _oid_ and _value_ to this name. The _oid_
* is an object identifier defined in ASN.1. Some common OIDs are:
*
* C:: Country Name
@@ -213,24 +209,39 @@ ossl_x509name_initialize_copy(VALUE self, VALUE other)
* O:: Organization Name
* OU:: Organizational Unit Name
* ST:: State or Province Name
+ *
+ * The optional keyword parameters _loc_ and _set_ specify where to insert the
+ * new attribute. Refer to the manpage of X509_NAME_add_entry(3) for details.
+ * _loc_ defaults to -1 and _set_ defaults to 0. This appends a single-valued
+ * RDN to the end.
*/
static
VALUE ossl_x509name_add_entry(int argc, VALUE *argv, VALUE self)
{
X509_NAME *name;
- VALUE oid, value, type;
+ VALUE oid, value, type, opts, kwargs[2];
+ static ID kwargs_ids[2];
const char *oid_name;
+ int loc = -1, set = 0;
- rb_scan_args(argc, argv, "21", &oid, &value, &type);
+ if (!kwargs_ids[0]) {
+ kwargs_ids[0] = rb_intern_const("loc");
+ kwargs_ids[1] = rb_intern_const("set");
+ }
+ rb_scan_args(argc, argv, "21:", &oid, &value, &type, &opts);
+ rb_get_kwargs(opts, kwargs_ids, 0, 2, kwargs);
oid_name = StringValueCStr(oid);
StringValue(value);
if(NIL_P(type)) type = rb_aref(OBJECT_TYPE_TEMPLATE, oid);
+ if (kwargs[0] != Qundef)
+ loc = NUM2INT(kwargs[0]);
+ if (kwargs[1] != Qundef)
+ set = NUM2INT(kwargs[1]);
GetX509Name(self, name);
if (!X509_NAME_add_entry_by_txt(name, oid_name, NUM2INT(type),
- (const unsigned char *)RSTRING_PTR(value), RSTRING_LENINT(value), -1, 0)) {
- ossl_raise(eX509NameError, NULL);
- }
-
+ (unsigned char *)RSTRING_PTR(value),
+ RSTRING_LENINT(value), loc, set))
+ ossl_raise(eX509NameError, "X509_NAME_add_entry_by_txt");
return self;
}
@@ -249,42 +260,73 @@ ossl_x509name_to_s_old(VALUE self)
return str;
}
+static VALUE
+x509name_print(VALUE self, unsigned long iflag)
+{
+ X509_NAME *name;
+ BIO *out;
+
+ GetX509Name(self, name);
+ out = BIO_new(BIO_s_mem());
+ if (!out)
+ ossl_raise(eX509NameError, NULL);
+ if (!X509_NAME_print_ex(out, name, 0, iflag)) {
+ BIO_free(out);
+ ossl_raise(eX509NameError, "X509_NAME_print_ex");
+ }
+ return ossl_membio2str(out);
+}
+
/*
* call-seq:
- * name.to_s => string
- * name.to_s(flags) => string
+ * name.to_s -> string
+ * name.to_s(format) -> string
*
- * Returns this name as a Distinguished Name string. +flags+ may be one of:
+ * Returns a String representation of the Distinguished Name. _format_ is
+ * one of:
*
* * OpenSSL::X509::Name::COMPAT
* * OpenSSL::X509::Name::RFC2253
* * OpenSSL::X509::Name::ONELINE
* * OpenSSL::X509::Name::MULTILINE
+ *
+ * If _format_ is omitted, the largely broken and traditional OpenSSL format
+ * is used.
*/
static VALUE
ossl_x509name_to_s(int argc, VALUE *argv, VALUE self)
{
- X509_NAME *name;
- VALUE flag, str;
- BIO *out;
- unsigned long iflag;
-
- rb_scan_args(argc, argv, "01", &flag);
- if (NIL_P(flag))
+ rb_check_arity(argc, 0, 1);
+ /* name.to_s(nil) was allowed */
+ if (!argc || NIL_P(argv[0]))
return ossl_x509name_to_s_old(self);
- else iflag = NUM2ULONG(flag);
- if (!(out = BIO_new(BIO_s_mem())))
- ossl_raise(eX509NameError, NULL);
- GetX509Name(self, name);
- if (!X509_NAME_print_ex(out, name, 0, iflag)){
- BIO_free(out);
- ossl_raise(eX509NameError, NULL);
- }
- str = ossl_membio2str(out);
+ else
+ return x509name_print(self, NUM2ULONG(argv[0]));
+}
+/*
+ * call-seq;
+ * name.to_utf8 -> string
+ *
+ * Returns an UTF-8 representation of the distinguished name, as specified
+ * in {RFC 2253}[https://www.ietf.org/rfc/rfc2253.txt].
+ */
+static VALUE
+ossl_x509name_to_utf8(VALUE self)
+{
+ VALUE str = x509name_print(self, XN_FLAG_RFC2253 & ~ASN1_STRFLGS_ESC_MSB);
+ rb_enc_associate_index(str, rb_utf8_encindex());
return str;
}
+/* :nodoc: */
+static VALUE
+ossl_x509name_inspect(VALUE self)
+{
+ return rb_enc_sprintf(rb_utf8_encoding(), "#<%"PRIsVALUE" %"PRIsVALUE">",
+ rb_obj_class(self), ossl_x509name_to_utf8(self));
+}
+
/*
* call-seq:
* name.to_a => [[name, data, type], ...]
@@ -338,18 +380,18 @@ ossl_x509name_cmp0(VALUE self, VALUE other)
X509_NAME *name1, *name2;
GetX509Name(self, name1);
- SafeGetX509Name(other, name2);
+ GetX509Name(other, name2);
return X509_NAME_cmp(name1, name2);
}
/*
* call-seq:
- * name.cmp other => integer
- * name.<=> other => integer
+ * name.cmp(other) -> -1 | 0 | 1
+ * name <=> other -> -1 | 0 | 1
*
- * Compares this Name with +other+ and returns 0 if they are the same and -1 or
- * +1 if they are greater or less than each other respectively.
+ * Compares this Name with _other_ and returns +0+ if they are the same and +-1+
+ * or ++1+ if they are greater or less than each other respectively.
*/
static VALUE
ossl_x509name_cmp(VALUE self, VALUE other)
@@ -365,9 +407,9 @@ ossl_x509name_cmp(VALUE self, VALUE other)
/*
* call-seq:
- * name.eql? other => boolean
+ * name.eql?(other) -> true | false
*
- * Returns true if +name+ and +other+ refer to the same hash key.
+ * Returns true if _name_ and _other_ refer to the same hash key.
*/
static VALUE
ossl_x509name_eql(VALUE self, VALUE other)
@@ -398,7 +440,6 @@ ossl_x509name_hash(VALUE self)
return ULONG2NUM(hash);
}
-#ifdef HAVE_X509_NAME_HASH_OLD
/*
* call-seq:
* name.hash_old => integer
@@ -417,7 +458,6 @@ ossl_x509name_hash_old(VALUE self)
return ULONG2NUM(hash);
}
-#endif
/*
* call-seq:
@@ -478,17 +518,17 @@ Init_ossl_x509name(void)
rb_define_alloc_func(cX509Name, ossl_x509name_alloc);
rb_define_method(cX509Name, "initialize", ossl_x509name_initialize, -1);
- rb_define_copy_func(cX509Name, ossl_x509name_initialize_copy);
+ rb_define_method(cX509Name, "initialize_copy", ossl_x509name_initialize_copy, 1);
rb_define_method(cX509Name, "add_entry", ossl_x509name_add_entry, -1);
rb_define_method(cX509Name, "to_s", ossl_x509name_to_s, -1);
+ rb_define_method(cX509Name, "to_utf8", ossl_x509name_to_utf8, 0);
+ rb_define_method(cX509Name, "inspect", ossl_x509name_inspect, 0);
rb_define_method(cX509Name, "to_a", ossl_x509name_to_a, 0);
rb_define_method(cX509Name, "cmp", ossl_x509name_cmp, 1);
rb_define_alias(cX509Name, "<=>", "cmp");
rb_define_method(cX509Name, "eql?", ossl_x509name_eql, 1);
rb_define_method(cX509Name, "hash", ossl_x509name_hash, 0);
-#ifdef HAVE_X509_NAME_HASH_OLD
rb_define_method(cX509Name, "hash_old", ossl_x509name_hash_old, 0);
-#endif
rb_define_method(cX509Name, "to_der", ossl_x509name_to_der, 0);
utf8str = INT2NUM(V_ASN1_UTF8STRING);
diff --git a/ext/openssl/ossl_x509req.c b/ext/openssl/ossl_x509req.c
index 15bc7052d3..9f20dba311 100644
--- a/ext/openssl/ossl_x509req.c
+++ b/ext/openssl/ossl_x509req.c
@@ -23,10 +23,6 @@
ossl_raise(rb_eRuntimeError, "Req wasn't initialized!"); \
} \
} while (0)
-#define SafeGetX509Req(obj, req) do { \
- OSSL_Check_Kind((obj), cX509Req); \
- GetX509Req((obj), (req)); \
-} while (0)
/*
* Classes
@@ -51,49 +47,16 @@ static const rb_data_type_t ossl_x509req_type = {
/*
* Public functions
*/
-VALUE
-ossl_x509req_new(X509_REQ *req)
-{
- X509_REQ *new;
- VALUE obj;
-
- obj = NewX509Req(cX509Req);
- if (!req) {
- new = X509_REQ_new();
- } else {
- new = X509_REQ_dup(req);
- }
- if (!new) {
- ossl_raise(eX509ReqError, NULL);
- }
- SetX509Req(obj, new);
-
- return obj;
-}
-
X509_REQ *
GetX509ReqPtr(VALUE obj)
{
X509_REQ *req;
- SafeGetX509Req(obj, req);
+ GetX509Req(obj, req);
return req;
}
-X509_REQ *
-DupX509ReqPtr(VALUE obj)
-{
- X509_REQ *req, *new;
-
- SafeGetX509Req(obj, req);
- if (!(new = X509_REQ_dup(req))) {
- ossl_raise(eX509ReqError, NULL);
- }
-
- return new;
-}
-
/*
* Private functions
*/
@@ -145,7 +108,7 @@ ossl_x509req_copy(VALUE self, VALUE other)
rb_check_frozen(self);
if (self == other) return self;
GetX509Req(self, a);
- SafeGetX509Req(other, b);
+ GetX509Req(other, b);
if (!(req = X509_REQ_dup(b))) {
ossl_raise(eX509ReqError, NULL);
}
@@ -347,7 +310,7 @@ ossl_x509req_sign(VALUE self, VALUE key, VALUE digest)
GetX509Req(self, req);
pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
- md = GetDigestPtr(digest);
+ md = ossl_evp_get_digestbyname(digest);
if (!X509_REQ_sign(req, pkey, md)) {
ossl_raise(eX509ReqError, NULL);
}
@@ -457,7 +420,7 @@ Init_ossl_x509req(void)
rb_define_alloc_func(cX509Req, ossl_x509req_alloc);
rb_define_method(cX509Req, "initialize", ossl_x509req_initialize, -1);
- rb_define_copy_func(cX509Req, ossl_x509req_copy);
+ rb_define_method(cX509Req, "initialize_copy", ossl_x509req_copy, 1);
rb_define_method(cX509Req, "to_pem", ossl_x509req_to_pem, 0);
rb_define_method(cX509Req, "to_der", ossl_x509req_to_der, 0);
diff --git a/ext/openssl/ossl_x509revoked.c b/ext/openssl/ossl_x509revoked.c
index 7960ea349e..85489efdb2 100644
--- a/ext/openssl/ossl_x509revoked.c
+++ b/ext/openssl/ossl_x509revoked.c
@@ -23,10 +23,6 @@
ossl_raise(rb_eRuntimeError, "REV wasn't initialized!"); \
} \
} while (0)
-#define SafeGetX509Rev(obj, rev) do { \
- OSSL_Check_Kind((obj), cX509Rev); \
- GetX509Rev((obj), (rev)); \
-} while (0)
/*
* Classes
@@ -76,7 +72,7 @@ DupX509RevokedPtr(VALUE obj)
{
X509_REVOKED *rev, *new;
- SafeGetX509Rev(obj, rev);
+ GetX509Rev(obj, rev);
if (!(new = X509_REVOKED_dup(rev))) {
ossl_raise(eX509RevError, NULL);
}
@@ -116,7 +112,7 @@ ossl_x509revoked_initialize_copy(VALUE self, VALUE other)
rb_check_frozen(self);
GetX509Rev(self, rev);
- SafeGetX509Rev(other, rev_other);
+ GetX509Rev(other, rev_other);
rev_new = X509_REVOKED_dup(rev_other);
if (!rev_new)
@@ -159,10 +155,14 @@ static VALUE
ossl_x509revoked_get_time(VALUE self)
{
X509_REVOKED *rev;
+ const ASN1_TIME *time;
GetX509Rev(self, rev);
+ time = X509_REVOKED_get0_revocationDate(rev);
+ if (!time)
+ return Qnil;
- return asn1time_to_time(X509_REVOKED_get0_revocationDate(rev));
+ return asn1time_to_time(time);
}
static VALUE
@@ -267,7 +267,7 @@ Init_ossl_x509revoked(void)
rb_define_alloc_func(cX509Rev, ossl_x509revoked_alloc);
rb_define_method(cX509Rev, "initialize", ossl_x509revoked_initialize, -1);
- rb_define_copy_func(cX509Rev, ossl_x509revoked_initialize_copy);
+ rb_define_method(cX509Rev, "initialize_copy", ossl_x509revoked_initialize_copy, 1);
rb_define_method(cX509Rev, "serial", ossl_x509revoked_get_serial, 0);
rb_define_method(cX509Rev, "serial=", ossl_x509revoked_set_serial, 1);
diff --git a/ext/openssl/ossl_x509store.c b/ext/openssl/ossl_x509store.c
index 4becc8e3cd..c6cf67ad5d 100644
--- a/ext/openssl/ossl_x509store.c
+++ b/ext/openssl/ossl_x509store.c
@@ -23,10 +23,6 @@
ossl_raise(rb_eRuntimeError, "STORE wasn't initialized!"); \
} \
} while (0)
-#define SafeGetX509Store(obj, st) do { \
- OSSL_Check_Kind((obj), cX509Store); \
- GetX509Store((obj), (st)); \
-} while (0)
#define NewX509StCtx(klass) \
TypedData_Wrap_Struct((klass), &ossl_x509stctx_type, 0)
@@ -42,10 +38,6 @@
ossl_raise(rb_eRuntimeError, "STORE_CTX is out of scope!"); \
} \
} while (0)
-#define SafeGetX509StCtx(obj, storep) do { \
- OSSL_Check_Kind((obj), cX509StoreContext); \
- GetX509Store((obj), (ctx)); \
-} while (0)
/*
* Verify callback stuff
@@ -130,34 +122,12 @@ static const rb_data_type_t ossl_x509store_type = {
/*
* Public functions
*/
-VALUE
-ossl_x509store_new(X509_STORE *store)
-{
- VALUE obj;
-
- obj = NewX509Store(cX509Store);
- SetX509Store(obj, store);
-
- return obj;
-}
-
X509_STORE *
GetX509StorePtr(VALUE obj)
{
X509_STORE *store;
- SafeGetX509Store(obj, store);
-
- return store;
-}
-
-X509_STORE *
-DupX509StorePtr(VALUE obj)
-{
- X509_STORE *store;
-
- SafeGetX509Store(obj, store);
- X509_STORE_up_ref(store);
+ GetX509Store(obj, store);
return store;
}
@@ -242,9 +212,9 @@ ossl_x509store_initialize(int argc, VALUE *argv, VALUE self)
/*
* call-seq:
- * store.flags = flag
+ * store.flags = flags
*
- * Sets +flag+ to the Store. +flag+ consists of zero or more of the constants
+ * Sets _flags_ to the Store. _flags_ consists of zero or more of the constants
* defined in with name V_FLAG_* or'ed together.
*/
static VALUE
@@ -263,7 +233,7 @@ ossl_x509store_set_flags(VALUE self, VALUE flags)
* call-seq:
* store.purpose = purpose
*
- * Sets the store's purpose to +purpose+. If specified, the verifications on
+ * Sets the store's purpose to _purpose_. If specified, the verifications on
* the store will check every untrusted certificate's extensions are consistent
* with the purpose. The purpose is specified by constants:
*
@@ -322,8 +292,9 @@ ossl_x509store_set_time(VALUE self, VALUE time)
* call-seq:
* store.add_file(file) -> self
*
- * Adds the certificates in +file+ to the certificate store. The +file+ can
- * contain multiple PEM-encoded certificates.
+ * Adds the certificates in _file_ to the certificate store. _file_ is the path
+ * to the file, and the file contains one or more certificates in PEM format
+ * concatenated together.
*/
static VALUE
ossl_x509store_add_file(VALUE self, VALUE file)
@@ -359,7 +330,7 @@ ossl_x509store_add_file(VALUE self, VALUE file)
* call-seq:
* store.add_path(path) -> self
*
- * Adds +path+ as the hash dir to be looked up by the store.
+ * Adds _path_ as the hash dir to be looked up by the store.
*/
static VALUE
ossl_x509store_add_path(VALUE self, VALUE dir)
@@ -386,7 +357,7 @@ ossl_x509store_add_path(VALUE self, VALUE dir)
* call-seq:
* store.set_default_paths
*
- * Configures +store+ to look up CA certificates from the system default
+ * Configures _store_ to look up CA certificates from the system default
* certificate store as needed basis. The location of the store can usually be
* determined by:
*
@@ -410,7 +381,7 @@ ossl_x509store_set_default_paths(VALUE self)
* call-seq:
* store.add_cert(cert)
*
- * Adds the OpenSSL::X509::Certificate +cert+ to the certificate store.
+ * Adds the OpenSSL::X509::Certificate _cert_ to the certificate store.
*/
static VALUE
ossl_x509store_add_cert(VALUE self, VALUE arg)
@@ -431,7 +402,7 @@ ossl_x509store_add_cert(VALUE self, VALUE arg)
* call-seq:
* store.add_crl(crl) -> self
*
- * Adds the OpenSSL::X509::CRL +crl+ to the store.
+ * Adds the OpenSSL::X509::CRL _crl_ to the store.
*/
static VALUE
ossl_x509store_add_crl(VALUE self, VALUE arg)
@@ -456,15 +427,15 @@ static VALUE ossl_x509stctx_get_chain(VALUE);
* call-seq:
* store.verify(cert, chain = nil) -> true | false
*
- * Performs a certificate verification on the OpenSSL::X509::Certificate +cert+.
+ * Performs a certificate verification on the OpenSSL::X509::Certificate _cert_.
*
- * +chain+ can be an array of OpenSSL::X509::Certificate that is used to
+ * _chain_ can be an array of OpenSSL::X509::Certificate that is used to
* construct the certificate chain.
*
* If a block is given, it overrides the callback set by #verify_callback=.
*
* After finishing the verification, the error information can be retrieved by
- * #error, #error_string, and the resuting complete certificate chain can be
+ * #error, #error_string, and the resulting complete certificate chain can be
* retrieved by #chain.
*/
static VALUE
@@ -561,7 +532,7 @@ ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self)
rb_scan_args(argc, argv, "12", &store, &cert, &chain);
GetX509StCtx(self, ctx);
- SafeGetX509Store(store, x509st);
+ GetX509Store(store, x509st);
if(!NIL_P(cert)) x509 = DupX509CertPtr(cert); /* NEED TO DUP */
if(!NIL_P(chain)) x509s = ossl_x509_ary2sk(chain);
if(X509_STORE_CTX_init(ctx, x509st, x509, x509s) != 1){
diff --git a/ext/openssl/ruby_missing.h b/ext/openssl/ruby_missing.h
index 8dacc8266e..b8a0a0c180 100644
--- a/ext/openssl/ruby_missing.h
+++ b/ext/openssl/ruby_missing.h
@@ -10,11 +10,6 @@
#if !defined(_OSSL_RUBY_MISSING_H_)
#define _OSSL_RUBY_MISSING_H_
-#define rb_define_copy_func(klass, func) \
- rb_define_method((klass), "initialize_copy", (func), 1)
-
-#define FPTR_TO_FD(fptr) ((fptr)->fd)
-
#ifndef RB_INTEGER_TYPE_P
/* for Ruby 2.3 compatibility */
#define RB_INTEGER_TYPE_P(obj) (RB_FIXNUM_P(obj) || RB_TYPE_P(obj, T_BIGNUM))
diff --git a/test/openssl/fixtures/pkey/dh1024.pem b/test/openssl/fixtures/pkey/dh1024.pem
new file mode 100644
index 0000000000..f99c757f21
--- /dev/null
+++ b/test/openssl/fixtures/pkey/dh1024.pem
@@ -0,0 +1,5 @@
+-----BEGIN DH PARAMETERS-----
+MIGHAoGBAKnKQ8MNK6nYZzLrrcuTsLxuiJGXoOO5gT+tljOTbHBuiktdMTITzIY0
+pFxIvjG05D7HoBZQfrR0c92NGWPkAiCkhQKB8JCbPVzwNLDy6DZ0pmofDKrEsYHG
+AQjjxMXhwULlmuR/K+WwlaZPiLIBYalLAZQ7ZbOPeVkJ8ePao0eLAgEC
+-----END DH PARAMETERS-----
diff --git a/test/openssl/fixtures/pkey/dsa1024.pem b/test/openssl/fixtures/pkey/dsa1024.pem
new file mode 100644
index 0000000000..1bf498895e
--- /dev/null
+++ b/test/openssl/fixtures/pkey/dsa1024.pem
@@ -0,0 +1,12 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBugIBAAKBgQCH9aAoXvWWThIjkA6D+nI1F9ksF9iDq594rkiGNOT9sPDOdB+n
+D+qeeeeloRlj19ymCSADPI0ZLRgkchkAEnY2RnqnhHOjVf/roGgRbW+iQDMbQ9wa
+/pvc6/fAbsu1goE1hBYjm98/sZEeXavj8tR56IXnjF1b6Nx0+sgeUKFKEQIVAMiz
+4BJUFeTtddyM4uadBM7HKLPRAoGAZdLBSYNGiij7vAjesF5mGUKTIgPd+JKuBEDx
+OaBclsgfdoyoF/TMOkIty+PVlYD+//Vl2xnoUEIRaMXHwHfm0r2xUX++oeRaSScg
+YizJdUxe5jvBuBszGPRc/mGpb9YvP0sB+FL1KmuxYmdODfCe51zl8uM/CVhouJ3w
+DjmRGscCgYAuFlfC7p+e8huCKydfcv/beftqjewiOPpQ3u5uI6KPCtCJPpDhs3+4
+IihH2cPsAlqwGF4tlibW1+/z/OZ1AZinPK3y7b2jSJASEaPeEltVzB92hcd1khk2
+jTYcmSsV4VddplOPK9czytR/GbbibxsrhhgZUbd8LPbvIgaiadJ1PgIUBnJ/5vN2
+CVArsEzlPUCbohPvZnE=
+-----END DSA PRIVATE KEY-----
diff --git a/test/openssl/fixtures/pkey/dsa256.pem b/test/openssl/fixtures/pkey/dsa256.pem
new file mode 100644
index 0000000000..d9a407f736
--- /dev/null
+++ b/test/openssl/fixtures/pkey/dsa256.pem
@@ -0,0 +1,8 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIH3AgEAAkEAhk2libbY2a8y2Pt21+YPYGZeW6wzaW2yfj5oiClXro9XMR7XWLkE
+9B7XxLNFCS2gmCCdMsMW1HulaHtLFQmB2wIVAM43JZrcgpu6ajZ01VkLc93gu/Ed
+AkAOhujZrrKV5CzBKutKLb0GVyVWmdC7InoNSMZEeGU72rT96IjM59YzoqmD0pGM
+3I1o4cGqg1D1DfM1rQlnN1eSAkBq6xXfEDwJ1mLNxF6q8Zm/ugFYWR5xcX/3wFiT
+b4+EjHP/DbNh9Vm5wcfnDBJ1zKvrMEf2xqngYdrV/3CiGJeKAhRvL57QvJZcQGvn
+ISNX5cMzFHRW3Q==
+-----END DSA PRIVATE KEY-----
diff --git a/test/openssl/fixtures/pkey/dsa512.pem b/test/openssl/fixtures/pkey/dsa512.pem
new file mode 100644
index 0000000000..962c41cc67
--- /dev/null
+++ b/test/openssl/fixtures/pkey/dsa512.pem
@@ -0,0 +1,8 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIH4AgEAAkEA5lB4GvEwjrsMlGDqGsxrbqeFRh6o9OWt6FgTYiEEHaOYhkIxv0Ok
+RZPDNwOG997mDjBnvDJ1i56OmS3MbTnovwIVAJgub/aDrSDB4DZGH7UyarcaGy6D
+AkB9HdFw/3td8K4l1FZHv7TCZeJ3ZLb7dF3TWoGUP003RCqoji3/lHdKoVdTQNuR
+S/m6DlCwhjRjiQ/lBRgCLCcaAkEAjN891JBjzpMj4bWgsACmMggFf57DS0Ti+5++
+Q1VB8qkJN7rA7/2HrCR3gTsWNb1YhAsnFsoeRscC+LxXoXi9OAIUBG98h4tilg6S
+55jreJD3Se3slps=
+-----END DSA PRIVATE KEY-----
diff --git a/test/openssl/fixtures/pkey/p256.pem b/test/openssl/fixtures/pkey/p256.pem
new file mode 100644
index 0000000000..97c97d9f9d
--- /dev/null
+++ b/test/openssl/fixtures/pkey/p256.pem
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIID49FDqcf1O1eO8saTgG70UbXQw9Fqwseliit2aWhH1oAoGCCqGSM49
+AwEHoUQDQgAEFglk2c+oVUIKQ64eZG9bhLNPWB7lSZ/ArK41eGy5wAzU/0G51Xtt
+CeBUl+MahZtn9fO1JKdF4qJmS39dXnpENg==
+-----END EC PRIVATE KEY-----
diff --git a/test/openssl/fixtures/pkey/rsa1024.pem b/test/openssl/fixtures/pkey/rsa1024.pem
new file mode 100644
index 0000000000..464de074be
--- /dev/null
+++ b/test/openssl/fixtures/pkey/rsa1024.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQDLwsSw1ECnPtT+PkOgHhcGA71nwC2/nL85VBGnRqDxOqjVh7Cx
+aKPERYHsk4BPCkE3brtThPWc9kjHEQQ7uf9Y1rbCz0layNqHyywQEVLFmp1cpIt/
+Q3geLv8ZD9pihowKJDyMDiN6ArYUmZczvW4976MU3+l54E6lF/JfFEU5hwIDAQAB
+AoGBAKSl/MQarye1yOysqX6P8fDFQt68VvtXkNmlSiKOGuzyho0M+UVSFcs6k1L0
+maDE25AMZUiGzuWHyaU55d7RXDgeskDMakD1v6ZejYtxJkSXbETOTLDwUWTn618T
+gnb17tU1jktUtU67xK/08i/XodlgnQhs6VoHTuCh3Hu77O6RAkEA7+gxqBuZR572
+74/akiW/SuXm0SXPEviyO1MuSRwtI87B02D0qgV8D1UHRm4AhMnJ8MCs1809kMQE
+JiQUCrp9mQJBANlt2ngBO14us6NnhuAseFDTBzCHXwUUu1YKHpMMmxpnGqaldGgX
+sOZB3lgJsT9VlGf3YGYdkLTNVbogQKlKpB8CQQDiSwkb4vyQfDe8/NpU5Not0fII
+8jsDUCb+opWUTMmfbxWRR3FBNu8wnym/m19N4fFj8LqYzHX4KY0oVPu6qvJxAkEA
+wa5snNekFcqONLIE4G5cosrIrb74sqL8GbGb+KuTAprzj5z1K8Bm0UW9lTjVDjDi
+qRYgZfZSL+x1P/54+xTFSwJAY1FxA/N3QPCXCjPh5YqFxAMQs2VVYTfg+t0MEcJD
+dPMQD5JX6g5HKnHFg2mZtoXQrWmJSn7p8GJK8yNTopEErA==
+-----END RSA PRIVATE KEY-----
diff --git a/test/openssl/fixtures/pkey/rsa2048.pem b/test/openssl/fixtures/pkey/rsa2048.pem
new file mode 100644
index 0000000000..ac89cd88ed
--- /dev/null
+++ b/test/openssl/fixtures/pkey/rsa2048.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAuV9ht9J7k4NBs38jOXvvTKY9gW8nLICSno5EETR1cuF7i4pN
+s9I1QJGAFAX0BEO4KbzXmuOvfCpD3CU+Slp1enenfzq/t/e/1IRW0wkJUJUFQign
+4CtrkJL+P07yx18UjyPlBXb81ApEmAB5mrJVSrWmqbjs07JbuS4QQGGXLc+Su96D
+kYKmSNVjBiLxVVSpyZfAY3hD37d60uG+X8xdW5v68JkRFIhdGlb6JL8fllf/A/bl
+NwdJOhVr9mESHhwGjwfSeTDPfd8ZLE027E5lyAVX9KZYcU00mOX+fdxOSnGqS/8J
+DRh0EPHDL15RcJjV2J6vZjPb0rOYGDoMcH+94wIDAQABAoIBAAzsamqfYQAqwXTb
+I0CJtGg6msUgU7HVkOM+9d3hM2L791oGHV6xBAdpXW2H8LgvZHJ8eOeSghR8+dgq
+PIqAffo4x1Oma+FOg3A0fb0evyiACyrOk+EcBdbBeLo/LcvahBtqnDfiUMQTpy6V
+seSoFCwuN91TSCeGIsDpRjbG1vxZgtx+uI+oH5+ytqJOmfCksRDCkMglGkzyfcl0
+Xc5CUhIJ0my53xijEUQl19rtWdMnNnnkdbG8PT3LZlOta5Do86BElzUYka0C6dUc
+VsBDQ0Nup0P6rEQgy7tephHoRlUGTYamsajGJaAo1F3IQVIrRSuagi7+YpSpCqsW
+wORqorkCgYEA7RdX6MDVrbw7LePnhyuaqTiMK+055/R1TqhB1JvvxJ1CXk2rDL6G
+0TLHQ7oGofd5LYiemg4ZVtWdJe43BPZlVgT6lvL/iGo8JnrncB9Da6L7nrq/+Rvj
+XGjf1qODCK+LmreZWEsaLPURIoR/Ewwxb9J2zd0CaMjeTwafJo1CZvcCgYEAyCgb
+aqoWvUecX8VvARfuA593Lsi50t4MEArnOXXcd1RnXoZWhbx5rgO8/ATKfXr0BK/n
+h2GF9PfKzHFm/4V6e82OL7gu/kLy2u9bXN74vOvWFL5NOrOKPM7Kg+9I131kNYOw
+Ivnr/VtHE5s0dY7JChYWE1F3vArrOw3T00a4CXUCgYEA0SqY+dS2LvIzW4cHCe9k
+IQqsT0yYm5TFsUEr4sA3xcPfe4cV8sZb9k/QEGYb1+SWWZ+AHPV3UW5fl8kTbSNb
+v4ng8i8rVVQ0ANbJO9e5CUrepein2MPL0AkOATR8M7t7dGGpvYV0cFk8ZrFx0oId
+U0PgYDotF/iueBWlbsOM430CgYEAqYI95dFyPI5/AiSkY5queeb8+mQH62sdcCCr
+vd/w/CZA/K5sbAo4SoTj8dLk4evU6HtIa0DOP63y071eaxvRpTNqLUOgmLh+D6gS
+Cc7TfLuFrD+WDBatBd5jZ+SoHccVrLR/4L8jeodo5FPW05A+9gnKXEXsTxY4LOUC
+9bS4e1kCgYAqVXZh63JsMwoaxCYmQ66eJojKa47VNrOeIZDZvd2BPVf30glBOT41
+gBoDG3WMPZoQj9pb7uMcrnvs4APj2FIhMU8U15LcPAj59cD6S6rWnAxO8NFK7HQG
+4Jxg3JNNf8ErQoCHb1B3oVdXJkmbJkARoDpBKmTCgKtP8ADYLmVPQw==
+-----END RSA PRIVATE KEY-----
diff --git a/test/openssl/test_asn1.rb b/test/openssl/test_asn1.rb
index 91ae2cfd0c..3e7f8c13ce 100644
--- a/test/openssl/test_asn1.rb
+++ b/test/openssl/test_asn1.rb
@@ -1,10 +1,12 @@
# frozen_string_literal: false
require_relative 'utils'
+if defined?(OpenSSL)
+
class OpenSSL::TestASN1 < OpenSSL::TestCase
- def test_decode
+ def test_decode_x509_certificate
subj = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=TestCA")
- key = OpenSSL::TestUtils::TEST_KEY_RSA1024
+ key = Fixtures.pkey("rsa1024")
now = Time.at(Time.now.to_i) # suppress usec
s = 0xdeadbeafdeadbeafdeadbeafdeadbeaf
exts = [
@@ -128,9 +130,9 @@ class OpenSSL::TestASN1 < OpenSSL::TestCase
assert_equal(OpenSSL::ASN1::Sequence, spkey.class)
assert_equal(2, spkey.value.size)
assert_equal(OpenSSL::ASN1::Integer, spkey.value[0].class)
- assert_equal(143085709396403084580358323862163416700436550432664688288860593156058579474547937626086626045206357324274536445865308750491138538454154232826011964045825759324933943290377903384882276841880081931690695505836279972214003660451338124170055999155993192881685495391496854691199517389593073052473319331505702779271, spkey.value[0].value)
+ assert_equal(cert.public_key.n, spkey.value[0].value)
assert_equal(OpenSSL::ASN1::Integer, spkey.value[1].class)
- assert_equal(65537, spkey.value[1].value)
+ assert_equal(cert.public_key.e, spkey.value[1].value)
extensions = tbs_cert.value[7]
assert_equal(:CONTEXT_SPECIFIC, extensions.tag_class)
@@ -191,66 +193,8 @@ class OpenSSL::TestASN1 < OpenSSL::TestCase
assert_equal(cululated_sig, sig_val.value)
end
- def test_encode_boolean
- encode_decode_test(OpenSSL::ASN1::Boolean, [true, false])
- end
-
- def test_encode_integer
- encode_decode_test(OpenSSL::ASN1::Integer, [72, -127, -128, 128, -1, 0, 1, -(2**12345), 2**12345])
- end
-
- def test_encode_nil
- m = OpenSSL::ASN1
- [
- m::Boolean, m::Integer, m::BitString, m::OctetString,
- m::ObjectId, m::Enumerated, m::UTF8String, m::UTCTime,
- m::GeneralizedTime, m::Sequence, m::Set
- ].each do |klass|
- #Primitives raise TypeError, Constructives NoMethodError
- assert_raise(TypeError, NoMethodError) { klass.send(:new, nil).to_der }
- end
- end
-
- def encode_decode_test(type, values)
- values.each do |v|
- assert_equal(v, OpenSSL::ASN1.decode(type.new(v).to_der).value)
- end
- end
-
- def test_decode_pem #should fail gracefully (cf. [ruby-dev:44542])
- pem = <<-_EOS_
------BEGIN CERTIFICATE-----
-MIIC8zCCAdugAwIBAgIBATANBgkqhkiG9w0BAQUFADA9MRMwEQYKCZImiZPyLGQB
-GRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVieS1sYW5nMQswCQYDVQQDDAJDQTAe
-Fw0xMTA5MjUxMzQ4MjZaFw0xMTA5MjUxNDQ4MjZaMD0xEzARBgoJkiaJk/IsZAEZ
-FgNvcmcxGTAXBgoJkiaJk/IsZAEZFglydWJ5LWxhbmcxCzAJBgNVBAMMAkNBMIIB
-IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuV9ht9J7k4NBs38jOXvvTKY9
-gW8nLICSno5EETR1cuF7i4pNs9I1QJGAFAX0BEO4KbzXmuOvfCpD3CU+Slp1enen
-fzq/t/e/1IRW0wkJUJUFQign4CtrkJL+P07yx18UjyPlBXb81ApEmAB5mrJVSrWm
-qbjs07JbuS4QQGGXLc+Su96DkYKmSNVjBiLxVVSpyZfAY3hD37d60uG+X8xdW5v6
-8JkRFIhdGlb6JL8fllf/A/blNwdJOhVr9mESHhwGjwfSeTDPfd8ZLE027E5lyAVX
-9KZYcU00mOX+fdxOSnGqS/8JDRh0EPHDL15RcJjV2J6vZjPb0rOYGDoMcH+94wID
-AQABMA0GCSqGSIb3DQEBBQUAA4IBAQAiAtrIr1pLX4GYN5klviWKb8HC9ICYuAFI
-NfE3FwqzErEVXotuMe3yPVyB3Bv6rjYY/x5EtS5+WPTbHlvHZTkfcsnTpizcn4mW
-dJ6dDRaFCHt1YKKjUxqBt9lvvrc3nReYZN/P+s1mrDhWzGf8iPZgf8sFUHgnaK7W
-CXRVXmPFgCDRNpDDVQ0MQkr509yYfTH+dujNzqTCwSvkyZFyQ7Oe8Yj0VR6kquG3
-rEzBQ0F9dUyqQ9gyRg8KHhDfv9HzT1d/rnUZMkoombwYBRIUChGCYV0GnJcan2Zm
-/93PnPG1IvPjYNd5VlV+sXSnaxQn974HRCsMv7jA8BD6IgSaX6WK
------END CERTIFICATE-----
- _EOS_
- assert_raise(OpenSSL::ASN1::ASN1Error) { OpenSSL::ASN1.decode(pem) }
- assert_raise(OpenSSL::ASN1::ASN1Error) { OpenSSL::ASN1.decode_all(pem) }
- end
-
- def test_primitive_cannot_set_infinite_length
- prim = OpenSSL::ASN1::Integer.new(50)
- assert_equal false, prim.infinite_length
- assert_not_respond_to prim, :infinite_length=
- end
-
def test_decode_all
- expected = %w{ 02 01 01 02 01 02 02 01 03 }
- raw = [expected.join('')].pack('H*')
+ raw = B(%w{ 02 01 01 02 01 02 02 01 03 })
ary = OpenSSL::ASN1.decode_all(raw)
assert_equal(3, ary.size)
ary.each_with_index do |asn1, i|
@@ -259,288 +203,401 @@ rEzBQ0F9dUyqQ9gyRg8KHhDfv9HzT1d/rnUZMkoombwYBRIUChGCYV0GnJcan2Zm
end
end
- def test_decode_utctime
- expected = Time.at 1374535380
- assert_equal expected, OpenSSL::ASN1.decode("\x17\v1307222323Z").value
-
- expected += 17
- assert_equal expected, OpenSSL::ASN1.decode("\x17\r130722232317Z").value
- end
-
- def test_encode_utctime_2k38
- encoded = OpenSSL::ASN1::UTCTime(2 ** 31 - 1).to_der
- assert_equal 2 ** 31 - 1, OpenSSL::ASN1.decode(encoded).value.to_i
-
- encoded = OpenSSL::ASN1::UTCTime(2 ** 31).to_der
- assert_equal 2 ** 31, OpenSSL::ASN1.decode(encoded).value.to_i
+ def test_object_id_register
+ oid = "1.2.34.56789"
+ pend "OID 1.2.34.56789 is already registered" if OpenSSL::ASN1::ObjectId(oid).sn
+ assert_equal true, OpenSSL::ASN1::ObjectId.register(oid, "ossl-test-sn", "ossl-test-ln")
+ obj = OpenSSL::ASN1::ObjectId(oid)
+ assert_equal oid, obj.oid
+ assert_equal "ossl-test-sn", obj.sn
+ assert_equal "ossl-test-ln", obj.ln
+ obj = encode_decode_test B(%w{ 06 05 2A 22 83 BB 55 }), OpenSSL::ASN1::ObjectId("ossl-test-ln")
+ assert_equal "ossl-test-sn", obj.value
end
- def test_decode_generalisedtime
- expected = Time.at 1481225640
- assert_equal expected, OpenSSL::ASN1.decode("\x18\x0D201612081934Z").value
-
- expected += 29
- assert_equal expected, OpenSSL::ASN1.decode("\x18\x0F20161208193429Z").value
+ def test_end_of_content
+ encode_decode_test B(%w{ 00 00 }), OpenSSL::ASN1::EndOfContent.new
+ assert_raise(OpenSSL::ASN1::ASN1Error) {
+ OpenSSL::ASN1.decode(B(%w{ 00 01 00 }))
+ }
end
- def test_decode_enumerated
- encoded = OpenSSL::ASN1.Enumerated(0).to_der
- assert_equal "\x0a\x01\x00".b, encoded
- assert_equal encoded, OpenSSL::ASN1.decode(encoded).to_der
+ def test_boolean
+ encode_decode_test B(%w{ 01 01 00 }), OpenSSL::ASN1::Boolean.new(false)
+ encode_decode_test B(%w{ 01 01 FF }), OpenSSL::ASN1::Boolean.new(true)
+ decode_test B(%w{ 01 01 01 }), OpenSSL::ASN1::Boolean.new(true)
+ assert_raise(OpenSSL::ASN1::ASN1Error) {
+ OpenSSL::ASN1.decode(B(%w{ 01 02 00 00 }))
+ }
end
- def test_create_inf_length_primitive
- expected = %w{ 24 80 04 01 61 00 00 }
- raw = [expected.join('')].pack('H*')
- content = [OpenSSL::ASN1::OctetString.new("a"), OpenSSL::ASN1::EndOfContent.new]
- cons = OpenSSL::ASN1::Constructive.new(content, OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL)
- cons.infinite_length = true
- assert_equal(nil, cons.tagging)
- assert_equal(raw, cons.to_der)
- asn1 = OpenSSL::ASN1.decode(raw)
- assert(asn1.infinite_length)
- assert_equal(raw, asn1.to_der)
+ def test_integer
+ encode_decode_test B(%w{ 02 01 00 }), OpenSSL::ASN1::Integer.new(0)
+ encode_decode_test B(%w{ 02 01 48 }), OpenSSL::ASN1::Integer.new(72)
+ encode_decode_test B(%w{ 02 02 00 80 }), OpenSSL::ASN1::Integer.new(128)
+ encode_decode_test B(%w{ 02 01 81 }), OpenSSL::ASN1::Integer.new(-127)
+ encode_decode_test B(%w{ 02 01 80 }), OpenSSL::ASN1::Integer.new(-128)
+ encode_decode_test B(%w{ 02 01 FF }), OpenSSL::ASN1::Integer.new(-1)
+ encode_decode_test B(%w{ 02 09 01 00 00 00 00 00 00 00 00 }), OpenSSL::ASN1::Integer.new(2 ** 64)
+ encode_decode_test B(%w{ 02 09 FF 00 00 00 00 00 00 00 00 }), OpenSSL::ASN1::Integer.new(-(2 ** 64))
+ # FIXME: OpenSSL < 1.1.0 does not fail
+ # assert_raise(OpenSSL::ASN1::ASN1Error) {
+ # OpenSSL::ASN1.decode(B(%w{ 02 02 00 7F }))
+ # }
+ # assert_raise(OpenSSL::ASN1::ASN1Error) {
+ # OpenSSL::ASN1.decode(B(%w{ 02 02 FF 80 }))
+ # }
+ end
+
+ def test_enumerated
+ encode_decode_test B(%w{ 0A 01 00 }), OpenSSL::ASN1::Enumerated.new(0)
+ encode_decode_test B(%w{ 0A 01 48 }), OpenSSL::ASN1::Enumerated.new(72)
+ encode_decode_test B(%w{ 0A 02 00 80 }), OpenSSL::ASN1::Enumerated.new(128)
+ encode_decode_test B(%w{ 0A 09 01 00 00 00 00 00 00 00 00 }), OpenSSL::ASN1::Enumerated.new(2 ** 64)
+ end
+
+ def test_bitstring
+ encode_decode_test B(%w{ 03 01 00 }), OpenSSL::ASN1::BitString.new(B(%w{}))
+ encode_decode_test B(%w{ 03 02 00 01 }), OpenSSL::ASN1::BitString.new(B(%w{ 01 }))
+ obj = OpenSSL::ASN1::BitString.new(B(%w{ F0 }))
+ obj.unused_bits = 4
+ encode_decode_test B(%w{ 03 02 04 F0 }), obj
+ assert_raise(OpenSSL::ASN1::ASN1Error) {
+ OpenSSL::ASN1.decode(B(%w{ 03 00 }))
+ }
+ # OpenSSL < OpenSSL_1_0_1k and LibreSSL ignore the error
+ # assert_raise(OpenSSL::ASN1::ASN1Error) {
+ # OpenSSL::ASN1.decode(B(%w{ 03 03 08 FF 00 }))
+ # }
+ # OpenSSL does not seem to prohibit this, though X.690 8.6.2.3 (15/08) does
+ # assert_raise(OpenSSL::ASN1::ASN1Error) {
+ # OpenSSL::ASN1.decode(B(%w{ 03 01 04 }))
+ # }
+ assert_raise(OpenSSL::ASN1::ASN1Error) {
+ obj = OpenSSL::ASN1::BitString.new(B(%w{ FF FF }))
+ obj.unused_bits = 8
+ obj.to_der
+ }
end
- def test_cons_without_inf_length_forbidden
- assert_raise(OpenSSL::ASN1::ASN1Error) do
- val = OpenSSL::ASN1::OctetString.new('a')
- cons = OpenSSL::ASN1::Constructive.new([val], OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL)
- cons.to_der
- end
+ def test_string_basic
+ test = -> (tag, klass) {
+ encode_decode_test tag.chr + B(%w{ 00 }), klass.new(B(%w{}))
+ encode_decode_test tag.chr + B(%w{ 02 00 01 }), klass.new(B(%w{ 00 01 }))
+ }
+ test.(4, OpenSSL::ASN1::OctetString)
+ test.(12, OpenSSL::ASN1::UTF8String)
+ test.(18, OpenSSL::ASN1::NumericString)
+ test.(19, OpenSSL::ASN1::PrintableString)
+ test.(20, OpenSSL::ASN1::T61String)
+ test.(21, OpenSSL::ASN1::VideotexString)
+ test.(22, OpenSSL::ASN1::IA5String)
+ test.(25, OpenSSL::ASN1::GraphicString)
+ test.(26, OpenSSL::ASN1::ISO64String)
+ test.(27, OpenSSL::ASN1::GeneralString)
+ test.(28, OpenSSL::ASN1::UniversalString)
+ test.(30, OpenSSL::ASN1::BMPString)
+ end
+
+ def test_null
+ encode_decode_test B(%w{ 05 00 }), OpenSSL::ASN1::Null.new(nil)
+ assert_raise(OpenSSL::ASN1::ASN1Error) {
+ OpenSSL::ASN1.decode(B(%w{ 05 01 00 }))
+ }
end
- def test_cons_without_array_forbidden
- assert_raise(OpenSSL::ASN1::ASN1Error) do
- val = OpenSSL::ASN1::OctetString.new('a')
- cons = OpenSSL::ASN1::Constructive.new(val, OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL)
- cons.infinite_length = true
- cons.to_der
+ def test_object_identifier
+ encode_decode_test B(%w{ 06 01 00 }), OpenSSL::ASN1::ObjectId.new("0.0".b)
+ encode_decode_test B(%w{ 06 01 28 }), OpenSSL::ASN1::ObjectId.new("1.0".b)
+ encode_decode_test B(%w{ 06 03 88 37 03 }), OpenSSL::ASN1::ObjectId.new("2.999.3".b)
+ encode_decode_test B(%w{ 06 05 2A 22 83 BB 55 }), OpenSSL::ASN1::ObjectId.new("1.2.34.56789".b)
+ obj = encode_decode_test B(%w{ 06 09 60 86 48 01 65 03 04 02 01 }), OpenSSL::ASN1::ObjectId.new("sha256")
+ assert_equal "2.16.840.1.101.3.4.2.1", obj.oid
+ assert_equal "SHA256", obj.sn
+ assert_equal "sha256", obj.ln
+ assert_raise(OpenSSL::ASN1::ASN1Error) {
+ OpenSSL::ASN1.decode(B(%w{ 06 00 }))
+ }
+ assert_raise(OpenSSL::ASN1::ASN1Error) {
+ OpenSSL::ASN1.decode(B(%w{ 06 01 80 }))
+ }
+ assert_raise(OpenSSL::ASN1::ASN1Error) { OpenSSL::ASN1::ObjectId.new("3.0".b).to_der }
+ assert_raise(OpenSSL::ASN1::ASN1Error) { OpenSSL::ASN1::ObjectId.new("0.40".b).to_der }
+
+ begin
+ oid = (0...100).to_a.join(".").b
+ obj = OpenSSL::ASN1::ObjectId.new(oid)
+ assert_equal oid, obj.oid
+ rescue OpenSSL::ASN1::ASN1Error
+ pend "OBJ_obj2txt() not working (LibreSSL?)" if $!.message =~ /OBJ_obj2txt/
+ raise
end
end
- def test_parse_empty_sequence
- expected = %w{ A0 07 30 02 30 00 02 01 00 }
- raw = [expected.join('')].pack('H*')
- asn1 = OpenSSL::ASN1.decode(raw)
- assert_equal(raw, asn1.to_der)
- assert_equal(2, asn1.value.size)
- seq = asn1.value[0]
- assert_equal(1, seq.value.size)
- inner_seq = seq.value[0]
- assert_equal(0, inner_seq.value.size)
- end
+ def test_sequence
+ encode_decode_test B(%w{ 30 00 }), OpenSSL::ASN1::Sequence.new([])
+ encode_decode_test B(%w{ 30 07 05 00 30 00 04 01 00 }), OpenSSL::ASN1::Sequence.new([
+ OpenSSL::ASN1::Null.new(nil),
+ OpenSSL::ASN1::Sequence.new([]),
+ OpenSSL::ASN1::OctetString.new(B(%w{ 00 }))
+ ])
+
+ expected = OpenSSL::ASN1::Sequence.new([OpenSSL::ASN1::OctetString.new(B(%w{ 00 }))])
+ expected.indefinite_length = true
+ encode_decode_test B(%w{ 30 80 04 01 00 00 00 }), expected
+
+ # OpenSSL::ASN1::EndOfContent can only be at the end
+ obj = OpenSSL::ASN1::Sequence.new([
+ OpenSSL::ASN1::EndOfContent.new,
+ OpenSSL::ASN1::OctetString.new(B(%w{ 00 })),
+ OpenSSL::ASN1::EndOfContent.new,
+ ])
+ obj.indefinite_length = true
+ assert_raise(OpenSSL::ASN1::ASN1Error) { obj.to_der }
+
+ # The last EOC in value is ignored if indefinite length form is used
+ expected = OpenSSL::ASN1::Sequence.new([
+ OpenSSL::ASN1::OctetString.new(B(%w{ 00 })),
+ OpenSSL::ASN1::EndOfContent.new
+ ])
+ expected.indefinite_length = true
+ encode_test B(%w{ 30 80 04 01 00 00 00 }), expected
+ end
+
+ def test_set
+ encode_decode_test B(%w{ 31 00 }), OpenSSL::ASN1::Set.new([])
+ encode_decode_test B(%w{ 31 07 05 00 30 00 04 01 00 }), OpenSSL::ASN1::Set.new([
+ OpenSSL::ASN1::Null.new(nil),
+ OpenSSL::ASN1::Sequence.new([]),
+ OpenSSL::ASN1::OctetString.new(B(%w{ 00 }))
+ ])
+ expected = OpenSSL::ASN1::Set.new([OpenSSL::ASN1::OctetString.new(B(%w{ 00 }))])
+ expected.indefinite_length = true
+ encode_decode_test B(%w{ 31 80 04 01 00 00 00 }), expected
+ end
+
+ def test_utctime
+ encode_decode_test B(%w{ 17 0D }) + "160908234339Z".b,
+ OpenSSL::ASN1::UTCTime.new(Time.utc(2016, 9, 8, 23, 43, 39))
+ # possible range of UTCTime is 1969-2068 currently
+ encode_decode_test B(%w{ 17 0D }) + "690908234339Z".b,
+ OpenSSL::ASN1::UTCTime.new(Time.utc(1969, 9, 8, 23, 43, 39))
+ decode_test B(%w{ 17 0B }) + "6909082343Z".b,
+ OpenSSL::ASN1::UTCTime.new(Time.utc(1969, 9, 8, 23, 43, 0))
+ # not implemented
+ # decode_test B(%w{ 17 11 }) + "500908234339+0930".b,
+ # OpenSSL::ASN1::UTCTime.new(Time.new(1950, 9, 8, 23, 43, 39, "+09:30"))
+ # decode_test B(%w{ 17 0F }) + "5009082343-0930".b,
+ # OpenSSL::ASN1::UTCTime.new(Time.new(1950, 9, 8, 23, 43, 0, "-09:30"))
+ # assert_raise(OpenSSL::ASN1::ASN1Error) {
+ # OpenSSL::ASN1.decode(B(%w{ 17 0C }) + "500908234339".b)
+ # }
+ # assert_raise(OpenSSL::ASN1::ASN1Error) {
+ # OpenSSL::ASN1.decode(B(%w{ 17 0D }) + "500908234339Y".b)
+ # }
+ end
+
+ def test_generalizedtime
+ encode_decode_test B(%w{ 18 0F }) + "20161208193429Z".b,
+ OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 34, 29))
+ encode_decode_test B(%w{ 18 0F }) + "99990908234339Z".b,
+ OpenSSL::ASN1::GeneralizedTime.new(Time.utc(9999, 9, 8, 23, 43, 39))
+ decode_test B(%w{ 18 0D }) + "201612081934Z".b,
+ OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 34, 0))
+ # not implemented
+ # decode_test B(%w{ 18 13 }) + "20161208193439+0930".b,
+ # OpenSSL::ASN1::GeneralizedTime.new(Time.new(2016, 12, 8, 19, 34, 39, "+09:30"))
+ # decode_test B(%w{ 18 11 }) + "201612081934-0930".b,
+ # OpenSSL::ASN1::GeneralizedTime.new(Time.new(2016, 12, 8, 19, 34, 0, "-09:30"))
+ # decode_test B(%w{ 18 11 }) + "201612081934-09".b,
+ # OpenSSL::ASN1::GeneralizedTime.new(Time.new(2016, 12, 8, 19, 34, 0, "-09:00"))
+ # decode_test B(%w{ 18 0D }) + "2016120819.5Z".b,
+ # OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 30, 0))
+ # decode_test B(%w{ 18 0D }) + "2016120819,5Z".b,
+ # OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 30, 0))
+ # decode_test B(%w{ 18 0F }) + "201612081934.5Z".b,
+ # OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 34, 30))
+ # decode_test B(%w{ 18 11 }) + "20161208193439.5Z".b,
+ # OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 34, 39.5))
+ # assert_raise(OpenSSL::ASN1::ASN1Error) {
+ # OpenSSL::ASN1.decode(B(%w{ 18 0D }) + "201612081934Y".b)
+ # }
+ end
+
+ def test_basic_asn1data
+ encode_test B(%w{ 00 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 0, :UNIVERSAL)
+ encode_test B(%w{ 01 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 1, :UNIVERSAL)
+ encode_decode_test B(%w{ 41 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 1, :APPLICATION)
+ encode_decode_test B(%w{ 81 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 1, :CONTEXT_SPECIFIC)
+ encode_decode_test B(%w{ C1 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 1, :PRIVATE)
+ encode_decode_test B(%w{ 1F 20 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 32, :UNIVERSAL)
+ encode_decode_test B(%w{ 1F C0 20 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 8224, :UNIVERSAL)
+ encode_decode_test B(%w{ 41 02 AB CD }), OpenSSL::ASN1::ASN1Data.new(B(%w{ AB CD }), 1, :APPLICATION)
+ encode_decode_test B(%w{ 41 81 80 } + %w{ AB CD } * 64), OpenSSL::ASN1::ASN1Data.new(B(%w{ AB CD } * 64), 1, :APPLICATION)
+ encode_decode_test B(%w{ 41 82 01 00 } + %w{ AB CD } * 128), OpenSSL::ASN1::ASN1Data.new(B(%w{ AB CD } * 128), 1, :APPLICATION)
+ encode_decode_test B(%w{ 61 00 }), OpenSSL::ASN1::ASN1Data.new([], 1, :APPLICATION)
+ obj = OpenSSL::ASN1::ASN1Data.new([OpenSSL::ASN1::ASN1Data.new(B(%w{ AB CD }), 2, :PRIVATE)], 1, :APPLICATION)
+ obj.indefinite_length = true
+ encode_decode_test B(%w{ 61 80 C2 02 AB CD 00 00 }), obj
+ obj = OpenSSL::ASN1::ASN1Data.new([
+ OpenSSL::ASN1::ASN1Data.new(B(%w{ AB CD }), 2, :PRIVATE),
+ OpenSSL::ASN1::EndOfContent.new
+ ], 1, :APPLICATION)
+ obj.indefinite_length = true
+ encode_test B(%w{ 61 80 C2 02 AB CD 00 00 }), obj
+ obj = OpenSSL::ASN1::ASN1Data.new(B(%w{ AB CD }), 1, :UNIVERSAL)
+ obj.indefinite_length = true
+ assert_raise(OpenSSL::ASN1::ASN1Error) { obj.to_der }
+ end
+
+ def test_basic_primitive
+ encode_test B(%w{ 00 00 }), OpenSSL::ASN1::Primitive.new(B(%w{}), 0)
+ encode_test B(%w{ 01 00 }), OpenSSL::ASN1::Primitive.new(B(%w{}), 1, nil, :UNIVERSAL)
+ encode_test B(%w{ 81 00 }), OpenSSL::ASN1::Primitive.new(B(%w{}), 1, nil, :CONTEXT_SPECIFIC)
+ encode_test B(%w{ 01 02 AB CD }), OpenSSL::ASN1::Primitive.new(B(%w{ AB CD }), 1)
+ assert_raise(TypeError) { OpenSSL::ASN1::Primitive.new([], 1).to_der }
- def test_parse_tagged_0_infinite
- expected = %w{ 30 80 02 01 01 80 01 02 00 00 }
- raw = [expected.join('')].pack('H*')
- asn1 = OpenSSL::ASN1.decode(raw)
- assert_equal(3, asn1.value.size)
- int = asn1.value[0]
- assert_universal(OpenSSL::ASN1::INTEGER, int)
- tagged = asn1.value[1]
- assert_equal(0, tagged.tag)
- assert_universal(OpenSSL::ASN1::EOC, asn1.value[2])
- assert_equal(raw, asn1.to_der)
- end
-
- def test_seq_infinite_length
- content = [ OpenSSL::ASN1::Null.new(nil),
- OpenSSL::ASN1::EndOfContent.new ]
- cons = OpenSSL::ASN1::Sequence.new(content)
- cons.infinite_length = true
- expected = %w{ 30 80 05 00 00 00 }
- raw = [expected.join('')].pack('H*')
- assert_equal(raw, cons.to_der)
- assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
- end
-
- def test_set_infinite_length
- content = [ OpenSSL::ASN1::Null.new(nil),
- OpenSSL::ASN1::EndOfContent.new() ]
- cons = OpenSSL::ASN1::Set.new(content)
- cons.infinite_length = true
- expected = %w{ 31 80 05 00 00 00 }
- raw = [expected.join('')].pack('H*')
- assert_equal(raw, cons.to_der)
- assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
+ prim = OpenSSL::ASN1::Integer.new(50)
+ assert_equal false, prim.indefinite_length
+ assert_not_respond_to prim, :indefinite_length=
end
- def test_octet_string_infinite_length
- octets = [ OpenSSL::ASN1::OctetString.new('aaa'),
- OpenSSL::ASN1::EndOfContent.new() ]
- cons = OpenSSL::ASN1::Constructive.new(octets, OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL)
- cons.infinite_length = true
- expected = %w{ 24 80 04 03 61 61 61 00 00 }
- raw = [expected.join('')].pack('H*')
- assert_equal(raw, cons.to_der)
- assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
+ def test_basic_constructed
+ octet_string = OpenSSL::ASN1::OctetString.new(B(%w{ AB CD }))
+ encode_test B(%w{ 20 00 }), OpenSSL::ASN1::Constructive.new([], 0)
+ encode_test B(%w{ 21 00 }), OpenSSL::ASN1::Constructive.new([], 1, nil, :UNIVERSAL)
+ encode_test B(%w{ A1 00 }), OpenSSL::ASN1::Constructive.new([], 1, nil, :CONTEXT_SPECIFIC)
+ encode_test B(%w{ 21 04 04 02 AB CD }), OpenSSL::ASN1::Constructive.new([octet_string], 1)
+ obj = OpenSSL::ASN1::Constructive.new([octet_string], 1)
+ obj.indefinite_length = true
+ encode_decode_test B(%w{ 21 80 04 02 AB CD 00 00 }), obj
+ obj = OpenSSL::ASN1::Constructive.new([octet_string, OpenSSL::ASN1::EndOfContent.new], 1)
+ obj.indefinite_length = true
+ encode_test B(%w{ 21 80 04 02 AB CD 00 00 }), obj
end
def test_prim_explicit_tagging
oct_str = OpenSSL::ASN1::OctetString.new("a", 0, :EXPLICIT)
- expected = %w{ A0 03 04 01 61 }
- raw = [expected.join('')].pack('H*')
- assert_equal(raw, oct_str.to_der)
- assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
- end
+ encode_test B(%w{ A0 03 04 01 61 }), oct_str
+ oct_str2 = OpenSSL::ASN1::OctetString.new("a", 1, :EXPLICIT, :APPLICATION)
+ encode_test B(%w{ 61 03 04 01 61 }), oct_str2
- def test_prim_explicit_tagging_tag_class
- oct_str = OpenSSL::ASN1::OctetString.new("a", 0, :EXPLICIT)
- oct_str2 = OpenSSL::ASN1::OctetString.new("a", 0, :EXPLICIT, :CONTEXT_SPECIFIC)
- assert_equal(oct_str.to_der, oct_str2.to_der)
+ decoded = OpenSSL::ASN1.decode(oct_str2.to_der)
+ assert_equal :APPLICATION, decoded.tag_class
+ assert_equal 1, decoded.tag
+ assert_equal 1, decoded.value.size
+ inner = decoded.value[0]
+ assert_equal OpenSSL::ASN1::OctetString, inner.class
+ assert_equal B(%w{ 61 }), inner.value
end
def test_prim_implicit_tagging
int = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT)
- expected = %w{ 80 01 01 }
- raw = [expected.join('')].pack('H*')
- assert_equal(raw, int.to_der)
- assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
- end
+ encode_test B(%w{ 80 01 01 }), int
+ int2 = OpenSSL::ASN1::Integer.new(1, 1, :IMPLICIT, :APPLICATION)
+ encode_test B(%w{ 41 01 01 }), int2
+ decoded = OpenSSL::ASN1.decode(int2.to_der)
+ assert_equal :APPLICATION, decoded.tag_class
+ assert_equal 1, decoded.tag
+ assert_equal B(%w{ 01 }), decoded.value
- def test_prim_implicit_tagging_tag_class
- int = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT)
- int2 = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT, :CONTEXT_SPECIFIC);
- assert_equal(int.to_der, int2.to_der)
+ # Special behavior: Encoding universal types with non-default 'tag'
+ # attribute and nil tagging method.
+ int3 = OpenSSL::ASN1::Integer.new(1, 1)
+ encode_test B(%w{ 01 01 01 }), int3
end
def test_cons_explicit_tagging
content = [ OpenSSL::ASN1::PrintableString.new('abc') ]
seq = OpenSSL::ASN1::Sequence.new(content, 2, :EXPLICIT)
- expected = %w{ A2 07 30 05 13 03 61 62 63 }
- raw = [expected.join('')].pack('H*')
- assert_equal(raw, seq.to_der)
- assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
- end
+ encode_test B(%w{ A2 07 30 05 13 03 61 62 63 }), seq
+ seq2 = OpenSSL::ASN1::Sequence.new(content, 3, :EXPLICIT, :APPLICATION)
+ encode_test B(%w{ 63 07 30 05 13 03 61 62 63 }), seq2
- def test_cons_explicit_tagging_inf_length
- content = [ OpenSSL::ASN1::PrintableString.new('abc') ,
- OpenSSL::ASN1::EndOfContent.new() ]
- seq = OpenSSL::ASN1::Sequence.new(content, 2, :EXPLICIT)
- seq.infinite_length = true
- expected = %w{ A2 80 30 80 13 03 61 62 63 00 00 00 00 }
- raw = [expected.join('')].pack('H*')
- assert_equal(raw, seq.to_der)
- assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
+ content3 = [ OpenSSL::ASN1::PrintableString.new('abc'),
+ OpenSSL::ASN1::EndOfContent.new() ]
+ seq3 = OpenSSL::ASN1::Sequence.new(content3, 2, :EXPLICIT)
+ seq3.indefinite_length = true
+ encode_test B(%w{ A2 80 30 80 13 03 61 62 63 00 00 00 00 }), seq3
end
def test_cons_implicit_tagging
content = [ OpenSSL::ASN1::Null.new(nil) ]
seq = OpenSSL::ASN1::Sequence.new(content, 1, :IMPLICIT)
- expected = %w{ A1 02 05 00 }
- raw = [expected.join('')].pack('H*')
- assert_equal(raw, seq.to_der)
- assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
- end
+ encode_test B(%w{ A1 02 05 00 }), seq
+ seq2 = OpenSSL::ASN1::Sequence.new(content, 1, :IMPLICIT, :APPLICATION)
+ encode_test B(%w{ 61 02 05 00 }), seq2
- def test_cons_implicit_tagging_inf_length
- content = [ OpenSSL::ASN1::Null.new(nil),
- OpenSSL::ASN1::EndOfContent.new() ]
- seq = OpenSSL::ASN1::Sequence.new(content, 1, :IMPLICIT)
- seq.infinite_length = true
- expected = %w{ A1 80 05 00 00 00 }
- raw = [expected.join('')].pack('H*')
- assert_equal(raw, seq.to_der)
- assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
- end
+ content3 = [ OpenSSL::ASN1::Null.new(nil),
+ OpenSSL::ASN1::EndOfContent.new() ]
+ seq3 = OpenSSL::ASN1::Sequence.new(content3, 1, :IMPLICIT)
+ seq3.indefinite_length = true
+ encode_test B(%w{ A1 80 05 00 00 00 }), seq3
- def test_octet_string_infinite_length_explicit_tagging
- octets = [ OpenSSL::ASN1::OctetString.new('aaa'),
- OpenSSL::ASN1::EndOfContent.new() ]
- cons = OpenSSL::ASN1::Constructive.new(octets, 1, :EXPLICIT)
- cons.infinite_length = true
- expected = %w{ A1 80 24 80 04 03 61 61 61 00 00 00 00 }
- raw = [expected.join('')].pack('H*')
- assert_equal(raw, cons.to_der)
- assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
+ # Special behavior: Encoding universal types with non-default 'tag'
+ # attribute and nil tagging method.
+ seq4 = OpenSSL::ASN1::Sequence.new([], 1)
+ encode_test B(%w{ 21 00 }), seq4
end
- def test_octet_string_infinite_length_implicit_tagging
+ def test_octet_string_constructed_tagging
+ octets = [ OpenSSL::ASN1::OctetString.new('aaa') ]
+ cons = OpenSSL::ASN1::Constructive.new(octets, 0, :IMPLICIT)
+ encode_test B(%w{ A0 05 04 03 61 61 61 }), cons
+
octets = [ OpenSSL::ASN1::OctetString.new('aaa'),
OpenSSL::ASN1::EndOfContent.new() ]
cons = OpenSSL::ASN1::Constructive.new(octets, 0, :IMPLICIT)
- cons.infinite_length = true
- expected = %w{ A0 80 04 03 61 61 61 00 00 }
- raw = [expected.join('')].pack('H*')
- assert_equal(raw, cons.to_der)
- assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
+ cons.indefinite_length = true
+ encode_test B(%w{ A0 80 04 03 61 61 61 00 00 }), cons
end
- def test_recursive_octet_string_infinite_length
+ def test_recursive_octet_string_indefinite_length
octets_sub1 = [ OpenSSL::ASN1::OctetString.new("\x01"),
OpenSSL::ASN1::EndOfContent.new() ]
octets_sub2 = [ OpenSSL::ASN1::OctetString.new("\x02"),
OpenSSL::ASN1::EndOfContent.new() ]
container1 = OpenSSL::ASN1::Constructive.new(octets_sub1, OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL)
- container1.infinite_length = true
+ container1.indefinite_length = true
container2 = OpenSSL::ASN1::Constructive.new(octets_sub2, OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL)
- container2.infinite_length = true
+ container2.indefinite_length = true
octets3 = OpenSSL::ASN1::OctetString.new("\x03")
octets = [ container1, container2, octets3,
OpenSSL::ASN1::EndOfContent.new() ]
cons = OpenSSL::ASN1::Constructive.new(octets, OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL)
- cons.infinite_length = true
- expected = %w{ 24 80 24 80 04 01 01 00 00 24 80 04 01 02 00 00 04 01 03 00 00 }
- raw = [expected.join('')].pack('H*')
+ cons.indefinite_length = true
+ raw = B(%w{ 24 80 24 80 04 01 01 00 00 24 80 04 01 02 00 00 04 01 03 00 00 })
assert_equal(raw, cons.to_der)
assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
end
- def test_bit_string_infinite_length
- content = [ OpenSSL::ASN1::BitString.new("\x01"),
- OpenSSL::ASN1::EndOfContent.new() ]
- cons = OpenSSL::ASN1::Constructive.new(content, OpenSSL::ASN1::BIT_STRING, nil, :UNIVERSAL)
- cons.infinite_length = true
- expected = %w{ 23 80 03 02 00 01 00 00 }
- raw = [expected.join('')].pack('H*')
- assert_equal(raw, cons.to_der)
- assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der)
- end
-
- def test_primitive_inf_length
- assert_raise(OpenSSL::ASN1::ASN1Error) do
- spec = %w{ 02 80 02 01 01 00 00 }
- raw = [spec.join('')].pack('H*')
- OpenSSL::ASN1.decode(raw)
- OpenSSL::ASN1.decode_all(raw)
- end
- end
-
def test_recursive_octet_string_parse
- test = %w{ 24 80 24 80 04 01 01 00 00 24 80 04 01 02 00 00 04 01 03 00 00 }
- raw = [test.join('')].pack('H*')
+ raw = B(%w{ 24 80 24 80 04 01 01 00 00 24 80 04 01 02 00 00 04 01 03 00 00 })
asn1 = OpenSSL::ASN1.decode(raw)
assert_equal(OpenSSL::ASN1::Constructive, asn1.class)
assert_universal(OpenSSL::ASN1::OCTET_STRING, asn1)
- assert_equal(true, asn1.infinite_length)
- assert_equal(4, asn1.value.size)
+ assert_equal(true, asn1.indefinite_length)
+ assert_equal(3, asn1.value.size)
nested1 = asn1.value[0]
assert_equal(OpenSSL::ASN1::Constructive, nested1.class)
assert_universal(OpenSSL::ASN1::OCTET_STRING, nested1)
- assert_equal(true, nested1.infinite_length)
- assert_equal(2, nested1.value.size)
+ assert_equal(true, nested1.indefinite_length)
+ assert_equal(1, nested1.value.size)
oct1 = nested1.value[0]
assert_universal(OpenSSL::ASN1::OCTET_STRING, oct1)
- assert_equal(false, oct1.infinite_length)
- assert_universal(OpenSSL::ASN1::EOC, nested1.value[1])
- assert_equal(false, nested1.value[1].infinite_length)
+ assert_equal(false, oct1.indefinite_length)
nested2 = asn1.value[1]
assert_equal(OpenSSL::ASN1::Constructive, nested2.class)
assert_universal(OpenSSL::ASN1::OCTET_STRING, nested2)
- assert_equal(true, nested2.infinite_length)
- assert_equal(2, nested2.value.size)
+ assert_equal(true, nested2.indefinite_length)
+ assert_equal(1, nested2.value.size)
oct2 = nested2.value[0]
assert_universal(OpenSSL::ASN1::OCTET_STRING, oct2)
- assert_equal(false, oct2.infinite_length)
- assert_universal(OpenSSL::ASN1::EOC, nested2.value[1])
- assert_equal(false, nested2.value[1].infinite_length)
+ assert_equal(false, oct2.indefinite_length)
oct3 = asn1.value[2]
assert_universal(OpenSSL::ASN1::OCTET_STRING, oct3)
- assert_equal(false, oct3.infinite_length)
- assert_universal(OpenSSL::ASN1::EOC, asn1.value[3])
- assert_equal(false, asn1.value[3].infinite_length)
+ assert_equal(false, oct3.indefinite_length)
end
def test_decode_constructed_overread
@@ -575,6 +632,46 @@ rEzBQ0F9dUyqQ9gyRg8KHhDfv9HzT1d/rnUZMkoombwYBRIUChGCYV0GnJcan2Zm
private
+ def B(ary)
+ [ary.join].pack("H*")
+ end
+
+ def assert_asn1_equal(a, b)
+ assert_equal a.class, b.class
+ assert_equal a.tag, b.tag
+ assert_equal a.tag_class, b.tag_class
+ assert_equal a.indefinite_length, b.indefinite_length
+ assert_equal a.unused_bits, b.unused_bits if a.respond_to?(:unused_bits)
+ case a.value
+ when Array
+ a.value.each_with_index { |ai, i|
+ assert_asn1_equal ai, b.value[i]
+ }
+ else
+ if OpenSSL::ASN1::ObjectId === a
+ assert_equal a.oid, b.oid
+ else
+ assert_equal a.value, b.value
+ end
+ end
+ assert_equal a.to_der, b.to_der
+ end
+
+ def encode_test(der, obj)
+ assert_equal der, obj.to_der
+ end
+
+ def decode_test(der, obj)
+ decoded = OpenSSL::ASN1.decode(der)
+ assert_asn1_equal obj, decoded
+ decoded
+ end
+
+ def encode_decode_test(der, obj)
+ encode_test(der, obj)
+ decode_test(der, obj)
+ end
+
def assert_universal(tag, asn1)
assert_equal(tag, asn1.tag)
if asn1.respond_to?(:tagging)
@@ -582,5 +679,6 @@ rEzBQ0F9dUyqQ9gyRg8KHhDfv9HzT1d/rnUZMkoombwYBRIUChGCYV0GnJcan2Zm
end
assert_equal(:UNIVERSAL, asn1.tag_class)
end
+end
-end if defined?(OpenSSL::TestUtils)
+end
diff --git a/test/openssl/test_bn.rb b/test/openssl/test_bn.rb
index 37ba5e5595..7739028611 100644
--- a/test/openssl/test_bn.rb
+++ b/test/openssl/test_bn.rb
@@ -1,60 +1,275 @@
+# coding: us-ascii
# frozen_string_literal: false
require_relative 'utils'
+require "prime"
-if defined?(OpenSSL::TestUtils)
+if defined?(OpenSSL)
class OpenSSL::TestBN < OpenSSL::TestCase
- def test_new_str
- e1 = OpenSSL::BN.new(999.to_s(16), 16) # OpenSSL::BN.new(str, 16) must be most stable
- e2 = OpenSSL::BN.new((2**107-1).to_s(16), 16)
- assert_equal(e1, OpenSSL::BN.new("999"))
- assert_equal(e2, OpenSSL::BN.new((2**107-1).to_s))
- assert_equal(e1, OpenSSL::BN.new("999", 10))
- assert_equal(e2, OpenSSL::BN.new((2**107-1).to_s, 10))
- assert_equal(e1, OpenSSL::BN.new("\x03\xE7", 2))
- assert_equal(e2, OpenSSL::BN.new("\a\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 2))
- assert_equal(e1, OpenSSL::BN.new("\x00\x00\x00\x02\x03\xE7", 0))
- assert_equal(e2, OpenSSL::BN.new("\x00\x00\x00\x0E\a\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 0))
- end
-
- def test_new_bn
- e1 = OpenSSL::BN.new(999.to_s(16), 16)
- e2 = OpenSSL::BN.new((2**107-1).to_s(16), 16)
- assert_equal(e1, OpenSSL::BN.new(e1))
- assert_equal(e2, OpenSSL::BN.new(e2))
- end
-
- def test_new_integer
- assert_equal(999.to_bn, OpenSSL::BN.new(999))
- assert_equal((2 ** 107 - 1).to_bn, OpenSSL::BN.new(2 ** 107 - 1))
- assert_equal(-999.to_bn, OpenSSL::BN.new(-999))
- assert_equal((-(2 ** 107 - 1)).to_bn, OpenSSL::BN.new(-(2 ** 107 - 1)))
- end
-
- def test_to_bn
- e1 = OpenSSL::BN.new(999.to_s(16), 16)
- e2 = OpenSSL::BN.new((2**107-1).to_s(16), 16)
- assert_equal(e1, 999.to_bn)
- assert_equal(e2, (2**107-1).to_bn)
- end
-
- def test_prime_p
- assert_equal(true, OpenSSL::BN.new((2 ** 107 - 1).to_s(16), 16).prime?)
- assert_equal(true, OpenSSL::BN.new((2 ** 127 - 1).to_s(16), 16).prime?(1))
- end
-
- def test_cmp
- bn1 = OpenSSL::BN.new('1')
- bn2 = OpenSSL::BN.new('1')
- bn3 = OpenSSL::BN.new('2')
- assert_equal(false, bn1 == nil)
- assert_equal(true, bn1 != nil)
- assert_equal(true, bn1 == bn2)
- assert_equal(false, bn1 == bn3)
- assert_equal(true, bn1.eql?(bn2))
- assert_equal(false, bn1.eql?(bn3))
- assert_equal(bn1.hash, bn2.hash)
- assert_not_equal(bn3.hash, bn1.hash)
+ def setup
+ super
+ @e1 = OpenSSL::BN.new(999.to_s(16), 16) # OpenSSL::BN.new(str, 16) must be most stable
+ @e2 = OpenSSL::BN.new("-" + 999.to_s(16), 16)
+ @e3 = OpenSSL::BN.new((2**107-1).to_s(16), 16)
+ @e4 = OpenSSL::BN.new("-" + (2**107-1).to_s(16), 16)
+ end
+
+ def test_new
+ assert_equal(@e1, OpenSSL::BN.new("999"))
+ assert_equal(@e1, OpenSSL::BN.new("999", 10))
+ assert_equal(@e1, OpenSSL::BN.new("\x03\xE7", 2))
+ assert_equal(@e1, OpenSSL::BN.new("\x00\x00\x00\x02\x03\xE7", 0))
+ assert_equal(@e2, OpenSSL::BN.new("-999"))
+ assert_equal(@e2, OpenSSL::BN.new("-999", 10))
+ assert_equal(@e2, OpenSSL::BN.new("\x00\x00\x00\x02\x83\xE7", 0))
+ assert_equal(@e3, OpenSSL::BN.new((2**107-1).to_s))
+ assert_equal(@e3, OpenSSL::BN.new((2**107-1).to_s, 10))
+ assert_equal(@e3, OpenSSL::BN.new("\a\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 2))
+ assert_equal(@e3, OpenSSL::BN.new("\x00\x00\x00\x0E\a\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 0))
+ assert_equal(@e4, OpenSSL::BN.new("-" + (2**107-1).to_s))
+ assert_equal(@e4, OpenSSL::BN.new("-" + (2**107-1).to_s, 10))
+ assert_equal(@e4, OpenSSL::BN.new("\x00\x00\x00\x0E\x87\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 0))
+
+ e1copy = OpenSSL::BN.new(@e1)
+ assert_equal(@e1, e1copy)
+ e1copy.clear_bit!(0) #=> 998
+ assert_not_equal(@e1, e1copy)
+
+ assert_equal(@e1, OpenSSL::BN.new(999))
+ assert_equal(@e2, OpenSSL::BN.new(-999))
+ assert_equal(@e3, OpenSSL::BN.new(2**107-1))
+ assert_equal(@e4, OpenSSL::BN.new(-(2**107-1)))
+
+ assert_equal(@e1, 999.to_bn)
+ assert_equal(@e2, -999.to_bn)
+ assert_equal(@e3, (2**107-1).to_bn)
+ assert_equal(@e4, (-(2**107-1)).to_bn)
+ end
+
+ def test_to_str
+ assert_equal("999", @e1.to_s(10))
+ assert_equal("-999", @e2.to_s(10))
+ assert_equal((2**107-1).to_s, @e3.to_s(10))
+ assert_equal((-(2**107-1)).to_s, @e4.to_s(10))
+ assert_equal("999", @e1.to_s)
+
+ assert_equal("03E7", @e1.to_s(16))
+ assert_equal("-03E7", @e2.to_s(16))
+ assert_equal("07FFFFFFFFFFFFFFFFFFFFFFFFFF", @e3.to_s(16))
+ assert_equal("-07FFFFFFFFFFFFFFFFFFFFFFFFFF", @e4.to_s(16))
+
+ assert_equal("\x03\xe7", @e1.to_s(2))
+ assert_equal("\x03\xe7", @e2.to_s(2))
+ assert_equal("\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", @e3.to_s(2))
+ assert_equal("\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", @e4.to_s(2))
+
+ assert_equal("\x00\x00\x00\x02\x03\xe7", @e1.to_s(0))
+ assert_equal("\x00\x00\x00\x02\x83\xe7", @e2.to_s(0))
+ assert_equal("\x00\x00\x00\x0e\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", @e3.to_s(0))
+ assert_equal("\x00\x00\x00\x0e\x87\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", @e4.to_s(0))
+ end
+
+ def test_to_int
+ assert_equal(999, @e1.to_i)
+ assert_equal(-999, @e2.to_i)
+ assert_equal(2**107-1, @e3.to_i)
+ assert_equal(-(2**107-1), @e4.to_i)
+
+ assert_equal(999, @e1.to_int)
+ end
+
+ def test_coerce
+ assert_equal(["", "-999"], @e2.coerce(""))
+ assert_equal([1000, -999], @e2.coerce(1000))
+ assert_raise(TypeError) { @e2.coerce(Class.new.new) }
+ end
+
+ def test_zero_p
+ assert_equal(true, 0.to_bn.zero?)
+ assert_equal(false, 1.to_bn.zero?)
+ end
+
+ def test_one_p
+ assert_equal(true, 1.to_bn.one?)
+ assert_equal(false, 2.to_bn.one?)
+ end
+
+ def test_odd_p
+ assert_equal(true, 1.to_bn.odd?)
+ assert_equal(false, 2.to_bn.odd?)
+ end
+
+ def test_negative_p
+ assert_equal(false, 0.to_bn.negative?)
+ assert_equal(false, @e1.negative?)
+ assert_equal(true, @e2.negative?)
+ end
+
+ def test_sqr
+ assert_equal(1, 1.to_bn.sqr)
+ assert_equal(100, 10.to_bn.sqr)
+ end
+
+ def test_four_ops
+ assert_equal(3, 1.to_bn + 2)
+ assert_equal(-1, 1.to_bn + -2)
+ assert_equal(-1, 1.to_bn - 2)
+ assert_equal(3, 1.to_bn - -2)
+ assert_equal(2, 1.to_bn * 2)
+ assert_equal(-2, 1.to_bn * -2)
+ assert_equal([0, 1], 1.to_bn / 2)
+ assert_equal([2, 0], 2.to_bn / 1)
+ assert_raise(OpenSSL::BNError) { 1.to_bn / 0 }
+ end
+
+ def test_unary_plus_minus
+ assert_equal(999, +@e1)
+ assert_equal(-999, +@e2)
+ assert_equal(-999, -@e1)
+ assert_equal(+999, -@e2)
+ end
+
+ def test_mod
+ assert_equal(1, 1.to_bn % 2)
+ assert_equal(0, 2.to_bn % 1)
+ assert_equal(-2, -2.to_bn % 7)
+ end
+
+ def test_exp
+ assert_equal(1, 1.to_bn ** 5)
+ assert_equal(32, 2.to_bn ** 5)
+ end
+
+ def test_gcd
+ assert_equal(1, 7.to_bn.gcd(5))
+ assert_equal(8, 24.to_bn.gcd(16))
+ end
+
+ def test_mod_sqr
+ assert_equal(4, 3.to_bn.mod_sqr(5))
+ assert_equal(0, 59.to_bn.mod_sqr(59))
+ end
+
+ def test_mod_inverse
+ assert_equal(2, 3.to_bn.mod_inverse(5))
+ assert_raise(OpenSSL::BNError) { 3.to_bn.mod_inverse(6) }
+ end
+
+ def test_mod_add
+ assert_equal(1, 3.to_bn.mod_add(5, 7))
+ assert_equal(2, 3.to_bn.mod_add(5, 3))
+ assert_equal(5, 3.to_bn.mod_add(-5, 7))
+ end
+
+ def test_mod_sub
+ assert_equal(1, 11.to_bn.mod_sub(3, 7))
+ assert_equal(2, 11.to_bn.mod_sub(3, 3))
+ assert_equal(5, 3.to_bn.mod_sub(5, 7))
+ end
+
+ def test_mod_mul
+ assert_equal(1, 2.to_bn.mod_mul(4, 7))
+ assert_equal(5, 2.to_bn.mod_mul(-1, 7))
+ end
+
+ def test_mod_exp
+ assert_equal(1, 3.to_bn.mod_exp(2, 8))
+ assert_equal(4, 2.to_bn.mod_exp(5, 7))
+ end
+
+ def test_bit_operations
+ e = 0b10010010.to_bn
+ assert_equal(0b10010011, e.set_bit!(0))
+ assert_equal(0b10010011, e.set_bit!(1))
+ assert_equal(0b1010010011, e.set_bit!(9))
+
+ e = 0b10010010.to_bn
+ assert_equal(0b10010010, e.clear_bit!(0))
+ assert_equal(0b10010000, e.clear_bit!(1))
+
+ e = 0b10010010.to_bn
+ assert_equal(0b10010010, e.mask_bits!(8))
+ assert_equal(0b10, e.mask_bits!(3))
+
+ e = 0b10010010.to_bn
+ assert_equal(false, e.bit_set?(0))
+ assert_equal(true, e.bit_set?(1))
+ assert_equal(false, e.bit_set?(1000))
+
+ e = 0b10010010.to_bn
+ assert_equal(0b1001001000, e << 2)
+ assert_equal(0b10010010, e)
+ assert_equal(0b1001001000, e.lshift!(2))
+ assert_equal(0b1001001000, e)
+
+ e = 0b10010010.to_bn
+ assert_equal(0b100100, e >> 2)
+ assert_equal(0b10010010, e)
+ assert_equal(0b100100, e.rshift!(2))
+ assert_equal(0b100100, e)
+ end
+
+ def test_random
+ 10.times {
+ r1 = OpenSSL::BN.rand(8)
+ assert_include(128..255, r1)
+ r2 = OpenSSL::BN.rand(8, -1)
+ assert_include(0..255, r2)
+ r3 = OpenSSL::BN.rand(8, 1)
+ assert_include(192..255, r3)
+ r4 = OpenSSL::BN.rand(8, 1, true)
+ assert_include(192..255, r4)
+ assert_equal(true, r4.odd?)
+
+ r5 = OpenSSL::BN.rand_range(256)
+ assert_include(0..255, r5)
+ }
+ end
+
+ def test_prime
+ p1 = OpenSSL::BN.generate_prime(32)
+ assert_include(0...2**32, p1)
+ assert_equal(true, Prime.prime?(p1.to_i))
+ p2 = OpenSSL::BN.generate_prime(32, true)
+ assert_equal(true, Prime.prime?((p2.to_i - 1) / 2))
+ p3 = OpenSSL::BN.generate_prime(32, false, 4)
+ assert_equal(1, p3 % 4)
+ p4 = OpenSSL::BN.generate_prime(32, false, 4, 3)
+ assert_equal(3, p4 % 4)
+
+ assert_equal(true, p1.prime?)
+ assert_equal(true, p2.prime?)
+ assert_equal(true, p3.prime?)
+ assert_equal(true, p4.prime?)
+ assert_equal(true, @e3.prime?)
+ assert_equal(true, @e3.prime_fasttest?)
+ end
+
+ def test_num_bits_bytes
+ assert_equal(10, @e1.num_bits)
+ assert_equal(2, @e1.num_bytes)
+ assert_equal(107, @e3.num_bits)
+ assert_equal(14, @e3.num_bytes)
+ assert_equal(0, 0.to_bn.num_bits)
+ assert_equal(0, 0.to_bn.num_bytes)
+ assert_equal(9, -256.to_bn.num_bits)
+ assert_equal(2, -256.to_bn.num_bytes)
+ end
+
+ def test_comparison
+ assert_equal(false, @e1 == nil)
+ assert_equal(false, @e1 == -999)
+ assert_equal(true, @e1 == 999)
+ assert_equal(true, @e1 == 999.to_bn)
+ assert_equal(false, @e1.eql?(nil))
+ assert_equal(false, @e1.eql?(999))
+ assert_equal(true, @e1.eql?(999.to_bn))
+ assert_equal(@e1.hash, 999.to_bn.hash)
+ assert_not_equal(@e1.hash, @e3.hash)
+ assert_equal(0, @e1.cmp(999))
+ assert_equal(1, @e1.cmp(-999))
+ assert_equal(0, @e1.ucmp(999))
+ assert_equal(0, @e1.ucmp(-999))
end
end
diff --git a/test/openssl/test_buffering.rb b/test/openssl/test_buffering.rb
index f85353fc67..c85a6f020b 100644
--- a/test/openssl/test_buffering.rb
+++ b/test/openssl/test_buffering.rb
@@ -1,9 +1,9 @@
# frozen_string_literal: false
require_relative 'utils'
-require 'stringio'
-class OpenSSL::TestBuffering < OpenSSL::TestCase
+if defined?(OpenSSL)
+class OpenSSL::TestBuffering < OpenSSL::TestCase
class IO
include OpenSSL::Buffering
@@ -85,5 +85,6 @@ class OpenSSL::TestBuffering < OpenSSL::TestCase
end
assert_equal([97, 98, 99], res)
end
+end
-end if defined?(OpenSSL::TestUtils)
+end
diff --git a/test/openssl/test_cipher.rb b/test/openssl/test_cipher.rb
index ad0e87b441..d87dedf73c 100644
--- a/test/openssl/test_cipher.rb
+++ b/test/openssl/test_cipher.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
require_relative 'utils'
-if defined?(OpenSSL::TestUtils)
+if defined?(OpenSSL)
class OpenSSL::TestCipher < OpenSSL::TestCase
module Helper
@@ -129,7 +129,7 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
assert_equal ct, cipher.update(pt) << cipher.final
cipher = new_decryptor("aes-128-ctr", key: key, iv: iv, padding: 0)
assert_equal pt, cipher.update(ct) << cipher.final
- end if has_cipher?('aes-128-ctr')
+ end
def test_ciphers
OpenSSL::Cipher.ciphers.each{|name|
@@ -165,10 +165,8 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
end
def test_authenticated
- if has_cipher?('aes-128-gcm')
- cipher = OpenSSL::Cipher.new('aes-128-gcm')
- assert_predicate(cipher, :authenticated?)
- end
+ cipher = OpenSSL::Cipher.new('aes-128-gcm')
+ assert_predicate(cipher, :authenticated?)
cipher = OpenSSL::Cipher.new('aes-128-cbc')
assert_not_predicate(cipher, :authenticated?)
end
@@ -220,7 +218,7 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
cipher = new_decryptor("aes-128-gcm", key: key, iv: iv, auth_tag: tag, auth_data: aad)
cipher.update(ct2)
assert_raise(OpenSSL::Cipher::CipherError) { cipher.final }
- end if has_cipher?("aes-128-gcm")
+ end
def test_aes_gcm_variable_iv_len
# GCM spec Appendix B Test Case 5
@@ -243,7 +241,7 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
assert_equal tag, cipher.auth_tag
cipher = new_decryptor("aes-128-gcm", key: key, iv_len: 8, iv: iv, auth_tag: tag, auth_data: aad)
assert_equal pt, cipher.update(ct) << cipher.final
- end if has_cipher?("aes-128-gcm")
+ end
def test_aes_ocb_tag_len
# RFC 7253 Appendix A; the second sample
@@ -295,7 +293,7 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
assert_equal ct1, ct2
assert_equal tag1, tag2
- end if has_cipher?("aes-128-gcm")
+ end
private
@@ -312,7 +310,6 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
kwargs.each {|k, v| cipher.send(:"#{k}=", v) }
end
end
-
end
end
diff --git a/test/openssl/test_config.rb b/test/openssl/test_config.rb
index 786bce9d2f..8096375c07 100644
--- a/test/openssl/test_config.rb
+++ b/test/openssl/test_config.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: false
require_relative 'utils'
+if defined?(OpenSSL)
+
class OpenSSL::TestConfig < OpenSSL::TestCase
def setup
super
@@ -171,7 +173,7 @@ __EOC__
def test_value
# suppress deprecation warnings
- OpenSSL::TestUtils.silent do
+ EnvUtil.suppress_warning do
assert_equal('CA_default', @it.value('ca', 'default_ca'))
assert_equal(nil, @it.value('ca', 'no such key'))
assert_equal(nil, @it.value('no such section', 'no such key'))
@@ -184,7 +186,7 @@ __EOC__
end
def test_value_ENV
- OpenSSL::TestUtils.silent do
+ EnvUtil.suppress_warning do
key = ENV.keys.first
assert_not_nil(key) # make sure we have at least one ENV var.
assert_equal(ENV[key], @it.value('ENV', key))
@@ -199,7 +201,7 @@ __EOC__
end
def test_section
- OpenSSL::TestUtils.silent do
+ EnvUtil.suppress_warning do
assert_equal({'HOME' => '.'}, @it.section('default'))
assert_equal({'dir' => './demoCA', 'certs' => './certs'}, @it.section('CA_default'))
assert_equal({}, @it.section('no_such_section'))
@@ -297,4 +299,6 @@ __EOC__
@it['newsection'] = {'a' => 'b'}
assert_not_equal(@it.sections.sort, c.sections.sort)
end
-end if defined?(OpenSSL::TestUtils)
+end
+
+end
diff --git a/test/openssl/test_digest.rb b/test/openssl/test_digest.rb
index 9891d99ae3..2cb878b6fa 100644
--- a/test/openssl/test_digest.rb
+++ b/test/openssl/test_digest.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
require_relative 'utils'
-if defined?(OpenSSL::TestUtils)
+if defined?(OpenSSL)
class OpenSSL::TestDigest < OpenSSL::TestCase
def setup
@@ -54,13 +54,10 @@ class OpenSSL::TestDigest < OpenSSL::TestCase
end
def test_digest_constants
- algs = %w(MD4 MD5 RIPEMD160 SHA1)
- if OpenSSL::OPENSSL_VERSION_NUMBER < 0x10100000
+ algs = %w(MD4 MD5 RIPEMD160 SHA1 SHA224 SHA256 SHA384 SHA512)
+ if !libressl? && !openssl?(1, 1, 0)
algs += %w(DSS1 SHA)
end
- if OpenSSL::OPENSSL_VERSION_NUMBER > 0x00908000
- algs += %w(SHA224 SHA256 SHA384 SHA512)
- end
algs.each do |alg|
assert_not_nil(OpenSSL::Digest.new(alg))
klass = OpenSSL::Digest.const_get(alg)
@@ -73,34 +70,32 @@ class OpenSSL::TestDigest < OpenSSL::TestCase
check_digest(OpenSSL::ASN1::ObjectId.new("SHA1"))
end
- if OpenSSL::OPENSSL_VERSION_NUMBER > 0x00908000
- def encode16(str)
- str.unpack("H*").first
- end
+ def encode16(str)
+ str.unpack("H*").first
+ end
- def test_098_features
- sha224_a = "abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5"
- sha256_a = "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"
- sha384_a = "54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31"
- sha512_a = "1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75"
-
- assert_equal(sha224_a, OpenSSL::Digest::SHA224.hexdigest("a"))
- assert_equal(sha256_a, OpenSSL::Digest::SHA256.hexdigest("a"))
- assert_equal(sha384_a, OpenSSL::Digest::SHA384.hexdigest("a"))
- assert_equal(sha512_a, OpenSSL::Digest::SHA512.hexdigest("a"))
-
- assert_equal(sha224_a, encode16(OpenSSL::Digest::SHA224.digest("a")))
- assert_equal(sha256_a, encode16(OpenSSL::Digest::SHA256.digest("a")))
- assert_equal(sha384_a, encode16(OpenSSL::Digest::SHA384.digest("a")))
- assert_equal(sha512_a, encode16(OpenSSL::Digest::SHA512.digest("a")))
- end
+ def test_sha2
+ sha224_a = "abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5"
+ sha256_a = "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"
+ sha384_a = "54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31"
+ sha512_a = "1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75"
+
+ assert_equal(sha224_a, OpenSSL::Digest::SHA224.hexdigest("a"))
+ assert_equal(sha256_a, OpenSSL::Digest::SHA256.hexdigest("a"))
+ assert_equal(sha384_a, OpenSSL::Digest::SHA384.hexdigest("a"))
+ assert_equal(sha512_a, OpenSSL::Digest::SHA512.hexdigest("a"))
+
+ assert_equal(sha224_a, encode16(OpenSSL::Digest::SHA224.digest("a")))
+ assert_equal(sha256_a, encode16(OpenSSL::Digest::SHA256.digest("a")))
+ assert_equal(sha384_a, encode16(OpenSSL::Digest::SHA384.digest("a")))
+ assert_equal(sha512_a, encode16(OpenSSL::Digest::SHA512.digest("a")))
+ end
- def test_digest_by_oid_and_name_sha2
- check_digest(OpenSSL::ASN1::ObjectId.new("SHA224"))
- check_digest(OpenSSL::ASN1::ObjectId.new("SHA256"))
- check_digest(OpenSSL::ASN1::ObjectId.new("SHA384"))
- check_digest(OpenSSL::ASN1::ObjectId.new("SHA512"))
- end
+ def test_digest_by_oid_and_name_sha2
+ check_digest(OpenSSL::ASN1::ObjectId.new("SHA224"))
+ check_digest(OpenSSL::ASN1::ObjectId.new("SHA256"))
+ check_digest(OpenSSL::ASN1::ObjectId.new("SHA384"))
+ check_digest(OpenSSL::ASN1::ObjectId.new("SHA512"))
end
def test_openssl_digest
@@ -121,14 +116,6 @@ class OpenSSL::TestDigest < OpenSSL::TestCase
d = OpenSSL::Digest.new(oid.oid)
assert_not_nil(d)
end
-
- def libressl?
- OpenSSL::OPENSSL_VERSION.include?('LibreSSL')
- end
-
- def version_since(verary)
- (OpenSSL::OPENSSL_LIBRARY_VERSION.scan(/\d+/).map(&:to_i) <=> verary) != -1
- end
end
end
diff --git a/test/openssl/test_engine.rb b/test/openssl/test_engine.rb
index 75e45eb7f0..4f3973a7c6 100644
--- a/test/openssl/test_engine.rb
+++ b/test/openssl/test_engine.rb
@@ -1,8 +1,9 @@
# frozen_string_literal: false
require_relative 'utils'
-class OpenSSL::TestEngine < OpenSSL::TestCase
+if defined?(OpenSSL) && defined?(OpenSSL::Engine)
+class OpenSSL::TestEngine < OpenSSL::TestCase
def test_engines_free # [ruby-dev:44173]
with_openssl <<-'end;'
OpenSSL::Engine.load("openssl")
@@ -95,5 +96,6 @@ class OpenSSL::TestEngine < OpenSSL::TestCase
cipher.update(data) + cipher.final
end
end
+end
-end if defined?(OpenSSL::TestUtils) && defined?(OpenSSL::Engine)
+end
diff --git a/test/openssl/test_fips.rb b/test/openssl/test_fips.rb
index 534dade02b..a4ab87f384 100644
--- a/test/openssl/test_fips.rb
+++ b/test/openssl/test_fips.rb
@@ -1,15 +1,23 @@
# frozen_string_literal: false
require_relative 'utils'
-if defined?(OpenSSL::TestUtils)
+if defined?(OpenSSL)
class OpenSSL::TestFIPS < OpenSSL::TestCase
-
def test_fips_mode_is_reentrant
OpenSSL.fips_mode = false
OpenSSL.fips_mode = false
end
+ def test_fips_mode_get
+ if OpenSSL::OPENSSL_FIPS
+ OpenSSL.fips_mode = true
+ assert OpenSSL.fips_mode == true, ".fips_mode returns true when .fips_mode=true"
+
+ OpenSSL.fips_mode = false
+ assert OpenSSL.fips_mode == false, ".fips_mode returns false when .fips_mode=false"
+ end
+ end
end
end
diff --git a/test/openssl/test_hmac.rb b/test/openssl/test_hmac.rb
index dbde97d9c9..831a5b6b37 100644
--- a/test/openssl/test_hmac.rb
+++ b/test/openssl/test_hmac.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: false
require_relative 'utils'
+if defined?(OpenSSL)
+
class OpenSSL::TestHMAC < OpenSSL::TestCase
def test_hmac
# RFC 2202 2. Test Cases for HMAC-MD5
@@ -37,4 +39,6 @@ class OpenSSL::TestHMAC < OpenSSL::TestCase
second = h1.update("test").hexdigest
assert_equal first, second
end
-end if defined?(OpenSSL::TestUtils)
+end
+
+end
diff --git a/test/openssl/test_kdf.rb b/test/openssl/test_kdf.rb
new file mode 100644
index 0000000000..d91fa3cf5d
--- /dev/null
+++ b/test/openssl/test_kdf.rb
@@ -0,0 +1,141 @@
+# frozen_string_literal: false
+require_relative 'utils'
+
+if defined?(OpenSSL)
+
+class OpenSSL::TestKDF < OpenSSL::TestCase
+ def test_pkcs5_pbkdf2_hmac_compatibility
+ expected = OpenSSL::KDF.pbkdf2_hmac("password", salt: "salt", iterations: 1, length: 20, hash: "sha1")
+ assert_equal(expected, OpenSSL::PKCS5.pbkdf2_hmac("password", "salt", 1, 20, "sha1"))
+ assert_equal(expected, OpenSSL::PKCS5.pbkdf2_hmac_sha1("password", "salt", 1, 20))
+ end
+
+ def test_pbkdf2_hmac_sha1_rfc6070_c_1_len_20
+ p ="password"
+ s = "salt"
+ c = 1
+ dk_len = 20
+ raw = %w{ 0c 60 c8 0f 96 1f 0e 71
+ f3 a9 b5 24 af 60 12 06
+ 2f e0 37 a6 }
+ expected = [raw.join('')].pack('H*')
+ value = OpenSSL::KDF.pbkdf2_hmac(p, salt: s, iterations: c, length: dk_len, hash: "sha1")
+ assert_equal(expected, value)
+ end
+
+ def test_pbkdf2_hmac_sha1_rfc6070_c_2_len_20
+ p ="password"
+ s = "salt"
+ c = 2
+ dk_len = 20
+ raw = %w{ ea 6c 01 4d c7 2d 6f 8c
+ cd 1e d9 2a ce 1d 41 f0
+ d8 de 89 57 }
+ expected = [raw.join('')].pack('H*')
+ value = OpenSSL::KDF.pbkdf2_hmac(p, salt: s, iterations: c, length: dk_len, hash: "sha1")
+ assert_equal(expected, value)
+ end
+
+ def test_pbkdf2_hmac_sha1_rfc6070_c_4096_len_20
+ p ="password"
+ s = "salt"
+ c = 4096
+ dk_len = 20
+ raw = %w{ 4b 00 79 01 b7 65 48 9a
+ be ad 49 d9 26 f7 21 d0
+ 65 a4 29 c1 }
+ expected = [raw.join('')].pack('H*')
+ value = OpenSSL::KDF.pbkdf2_hmac(p, salt: s, iterations: c, length: dk_len, hash: "sha1")
+ assert_equal(expected, value)
+ end
+
+# takes too long!
+# def test_pbkdf2_hmac_sha1_rfc6070_c_16777216_len_20
+# p ="password"
+# s = "salt"
+# c = 16777216
+# dk_len = 20
+# raw = %w{ ee fe 3d 61 cd 4d a4 e4
+# e9 94 5b 3d 6b a2 15 8c
+# 26 34 e9 84 }
+# expected = [raw.join('')].pack('H*')
+# value = OpenSSL::KDF.pbkdf2_hmac(p, salt: s, iterations: c, length: dk_len, hash: "sha1")
+# assert_equal(expected, value)
+# end
+
+ def test_pbkdf2_hmac_sha1_rfc6070_c_4096_len_25
+ p ="passwordPASSWORDpassword"
+ s = "saltSALTsaltSALTsaltSALTsaltSALTsalt"
+ c = 4096
+ dk_len = 25
+
+ raw = %w{ 3d 2e ec 4f e4 1c 84 9b
+ 80 c8 d8 36 62 c0 e4 4a
+ 8b 29 1a 96 4c f2 f0 70
+ 38 }
+ expected = [raw.join('')].pack('H*')
+ value = OpenSSL::KDF.pbkdf2_hmac(p, salt: s, iterations: c, length: dk_len, hash: "sha1")
+ assert_equal(expected, value)
+ end
+
+ def test_pbkdf2_hmac_sha1_rfc6070_c_4096_len_16
+ p ="pass\0word"
+ s = "sa\0lt"
+ c = 4096
+ dk_len = 16
+ raw = %w{ 56 fa 6a a7 55 48 09 9d
+ cc 37 d7 f0 34 25 e0 c3 }
+ expected = [raw.join('')].pack('H*')
+ value = OpenSSL::KDF.pbkdf2_hmac(p, salt: s, iterations: c, length: dk_len, hash: "sha1")
+ assert_equal(expected, value)
+ end
+
+ def test_pbkdf2_hmac_sha256_c_20000_len_32
+ #unfortunately no official test vectors available yet for SHA-2
+ p ="password"
+ s = OpenSSL::Random.random_bytes(16)
+ c = 20000
+ dk_len = 32
+ value1 = OpenSSL::KDF.pbkdf2_hmac(p, salt: s, iterations: c, length: dk_len, hash: "sha256")
+ value2 = OpenSSL::KDF.pbkdf2_hmac(p, salt: s, iterations: c, length: dk_len, hash: "sha256")
+ assert_equal(value1, value2)
+ end
+
+ def test_scrypt_rfc7914_first
+ pend "scrypt is not implemented" unless OpenSSL::KDF.respond_to?(:scrypt) # OpenSSL >= 1.1.0
+ pass = ""
+ salt = ""
+ n = 16
+ r = 1
+ p = 1
+ dklen = 64
+ expected = B(%w{ 77 d6 57 62 38 65 7b 20 3b 19 ca 42 c1 8a 04 97
+ f1 6b 48 44 e3 07 4a e8 df df fa 3f ed e2 14 42
+ fc d0 06 9d ed 09 48 f8 32 6a 75 3a 0f c8 1f 17
+ e8 d3 e0 fb 2e 0d 36 28 cf 35 e2 0c 38 d1 89 06 })
+ assert_equal(expected, OpenSSL::KDF.scrypt(pass, salt: salt, N: n, r: r, p: p, length: dklen))
+ end
+
+ def test_scrypt_rfc7914_second
+ pend "scrypt is not implemented" unless OpenSSL::KDF.respond_to?(:scrypt) # OpenSSL >= 1.1.0
+ pass = "password"
+ salt = "NaCl"
+ n = 1024
+ r = 8
+ p = 16
+ dklen = 64
+ expected = B(%w{ fd ba be 1c 9d 34 72 00 78 56 e7 19 0d 01 e9 fe
+ 7c 6a d7 cb c8 23 78 30 e7 73 76 63 4b 37 31 62
+ 2e af 30 d9 2e 22 a3 88 6f f1 09 27 9d 98 30 da
+ c7 27 af b9 4a 83 ee 6d 83 60 cb df a2 cc 06 40 })
+ assert_equal(expected, OpenSSL::KDF.scrypt(pass, salt: salt, N: n, r: r, p: p, length: dklen))
+ end
+
+ private
+
+ def B(ary)
+ [Array(ary).join].pack("H*")
+ end
+end
+
+end
diff --git a/test/openssl/test_ns_spki.rb b/test/openssl/test_ns_spki.rb
index ac34613fc2..aa1e61824f 100644
--- a/test/openssl/test_ns_spki.rb
+++ b/test/openssl/test_ns_spki.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
require_relative 'utils'
-if defined?(OpenSSL::TestUtils)
+if defined?(OpenSSL)
class OpenSSL::TestNSSPI < OpenSSL::TestCase
def setup
@@ -17,8 +17,8 @@ class OpenSSL::TestNSSPI < OpenSSL::TestCase
end
def test_build_data
- key1 = OpenSSL::TestUtils::TEST_KEY_RSA1024
- key2 = OpenSSL::TestUtils::TEST_KEY_RSA2048
+ key1 = Fixtures.pkey("rsa1024")
+ key2 = Fixtures.pkey("rsa2048")
spki = OpenSSL::Netscape::SPKI.new
spki.challenge = "RandomString"
spki.public_key = key1.public_key
diff --git a/test/openssl/test_ocsp.rb b/test/openssl/test_ocsp.rb
index 8881f25dd9..9d48496de5 100644
--- a/test/openssl/test_ocsp.rb
+++ b/test/openssl/test_ocsp.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
require_relative "utils"
-if defined?(OpenSSL::TestUtils)
+if defined?(OpenSSL)
class OpenSSL::TestOCSP < OpenSSL::TestCase
def setup
@@ -13,7 +13,7 @@ class OpenSSL::TestOCSP < OpenSSL::TestCase
# @cert2 @ocsp_cert
ca_subj = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=TestCA")
- @ca_key = OpenSSL::TestUtils::TEST_KEY_RSA1024
+ @ca_key = Fixtures.pkey("rsa1024")
ca_exts = [
["basicConstraints", "CA:TRUE", true],
["keyUsage", "cRLSign,keyCertSign", true],
@@ -22,7 +22,7 @@ class OpenSSL::TestOCSP < OpenSSL::TestCase
ca_subj, @ca_key, 1, ca_exts, nil, nil)
cert_subj = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=TestCA2")
- @cert_key = OpenSSL::TestUtils::TEST_KEY_RSA1024
+ @cert_key = Fixtures.pkey("rsa1024")
cert_exts = [
["basicConstraints", "CA:TRUE", true],
["keyUsage", "cRLSign,keyCertSign", true],
@@ -31,14 +31,14 @@ class OpenSSL::TestOCSP < OpenSSL::TestCase
cert_subj, @cert_key, 5, cert_exts, @ca_cert, @ca_key)
cert2_subj = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=TestCert")
- @cert2_key = OpenSSL::TestUtils::TEST_KEY_RSA1024
+ @cert2_key = Fixtures.pkey("rsa1024")
cert2_exts = [
]
@cert2 = OpenSSL::TestUtils.issue_cert(
cert2_subj, @cert2_key, 10, cert2_exts, @cert, @cert_key)
ocsp_subj = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=TestCAOCSP")
- @ocsp_key = OpenSSL::TestUtils::TEST_KEY_RSA2048
+ @ocsp_key = Fixtures.pkey("rsa2048")
ocsp_exts = [
["extendedKeyUsage", "OCSPSigning", true],
]
@@ -122,7 +122,7 @@ class OpenSSL::TestOCSP < OpenSSL::TestCase
assert_equal true, req.verify([@cert], store, OpenSSL::OCSP::NOINTERN)
ret = req.verify([@cert], store)
- if ret || OpenSSL::OPENSSL_VERSION =~ /OpenSSL/ && OpenSSL::OPENSSL_VERSION_NUMBER >= 0x10002000
+ if ret || openssl?(1, 0, 2) || libressl?(2, 4, 2)
assert_equal true, ret
else
# RT2560; OCSP_request_verify() does not find signer cert from 'certs' when
@@ -130,6 +130,21 @@ class OpenSSL::TestOCSP < OpenSSL::TestCase
# fixed by OpenSSL 1.0.1j, 1.0.2 and LibreSSL 2.4.2
pend "RT2560: ocsp_req_find_signer"
end
+
+ # not signed
+ req = OpenSSL::OCSP::Request.new.add_certid(cid)
+ assert_equal false, req.verify([], store)
+ end
+
+ def test_request_is_signed
+ cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert)
+ req = OpenSSL::OCSP::Request.new
+ req.add_certid(cid)
+ assert_equal false, req.signed?
+ assert_equal false, OpenSSL::OCSP::Request.new(req.to_der).signed?
+ req.sign(@cert, @cert_key, [])
+ assert_equal true, req.signed?
+ assert_equal true, OpenSSL::OCSP::Request.new(req.to_der).signed?
end
def test_request_nonce
diff --git a/test/openssl/test_pair.rb b/test/openssl/test_pair.rb
index 9a5205f81c..89cf41a86b 100644
--- a/test/openssl/test_pair.rb
+++ b/test/openssl/test_pair.rb
@@ -1,61 +1,45 @@
# frozen_string_literal: false
require_relative 'utils'
-
-if defined?(OpenSSL::TestUtils)
-
-require 'socket'
require_relative 'ut_eof'
+if defined?(OpenSSL)
+
module OpenSSL::SSLPairM
- def server
- host = "127.0.0.1"
- port = 0
- ctx = OpenSSL::SSL::SSLContext.new()
- ctx.ciphers = "ADH"
- ctx.security_level = 0
- ctx.tmp_dh_callback = proc { OpenSSL::TestUtils::TEST_KEY_DH1024 }
- tcps = create_tcp_server(host, port)
- ssls = OpenSSL::SSL::SSLServer.new(tcps, ctx)
- return ssls
+ def setup
+ svr_dn = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost")
+ ee_exts = [
+ ["keyUsage", "keyEncipherment,digitalSignature", true],
+ ]
+ @svr_key = OpenSSL::TestUtils::Fixtures.pkey("rsa1024")
+ @svr_cert = issue_cert(svr_dn, @svr_key, 1, ee_exts, nil, nil)
end
- def client(port)
+ def ssl_pair
host = "127.0.0.1"
- ctx = OpenSSL::SSL::SSLContext.new()
- ctx.ciphers = "ADH"
- ctx.security_level = 0
- s = create_tcp_client(host, port)
- ssl = OpenSSL::SSL::SSLSocket.new(s, ctx)
- ssl.connect
- ssl.sync_close = true
- ssl
- end
+ tcps = create_tcp_server(host, 0)
+ port = tcps.connect_address.ip_port
- def ssl_pair
- ssls = server
th = Thread.new {
+ sctx = OpenSSL::SSL::SSLContext.new
+ sctx.cert = @svr_cert
+ sctx.key = @svr_key
+ sctx.tmp_dh_callback = proc { OpenSSL::TestUtils::Fixtures.pkey_dh("dh1024") }
+ ssls = OpenSSL::SSL::SSLServer.new(tcps, sctx)
ns = ssls.accept
ssls.close
ns
}
- port = ssls.to_io.local_address.ip_port
- c = client(port)
+
+ tcpc = create_tcp_client(host, port)
+ c = OpenSSL::SSL::SSLSocket.new(tcpc)
+ c.connect
s = th.value
- if block_given?
- begin
- yield c, s
- ensure
- c.close unless c.closed?
- s.close unless s.closed?
- end
- else
- return c, s
- end
+
+ yield c, s
ensure
- if th&.alive?
- th.kill
- th.join
- end
+ tcpc&.close
+ tcps&.close
+ s&.close
end
end
@@ -85,23 +69,27 @@ end
module OpenSSL::TestEOF1M
def open_file(content)
- s1, s2 = ssl_pair
- th = Thread.new { s2 << content; s2.close }
- yield s1
- ensure
- th.join if th
- s1.close
+ ssl_pair { |s1, s2|
+ begin
+ th = Thread.new { s2 << content; s2.close }
+ yield s1
+ ensure
+ th&.join
+ end
+ }
end
end
module OpenSSL::TestEOF2M
def open_file(content)
- s1, s2 = ssl_pair
- th = Thread.new { s1 << content; s1.close }
- yield s2
- ensure
- th.join if th
- s2.close
+ ssl_pair { |s1, s2|
+ begin
+ th = Thread.new { s1 << content; s1.close }
+ yield s2
+ ensure
+ th&.join
+ end
+ }
end
end
@@ -189,6 +177,27 @@ module OpenSSL::TestPairM
}
end
+ def test_multibyte_read_write
+ # German a umlaut
+ auml = [%w{ C3 A4 }.join('')].pack('H*')
+ auml.force_encoding(Encoding::UTF_8)
+ bsize = auml.bytesize
+
+ ssl_pair { |s1, s2|
+ assert_equal bsize, s1.write(auml)
+ read = s2.read(bsize)
+ assert_equal Encoding::ASCII_8BIT, read.encoding
+ assert_equal bsize, read.bytesize
+ assert_equal auml, read.force_encoding(Encoding::UTF_8)
+
+ s1.puts(auml)
+ read = s2.gets
+ assert_equal Encoding::ASCII_8BIT, read.encoding
+ assert_equal bsize + 1, read.bytesize
+ assert_equal auml + "\n", read.force_encoding(Encoding::UTF_8)
+ }
+ end
+
def test_read_nonblock
ssl_pair {|s1, s2|
err = nil
@@ -354,9 +363,9 @@ module OpenSSL::TestPairM
def test_connect_accept_nonblock_no_exception
ctx2 = OpenSSL::SSL::SSLContext.new
- ctx2.ciphers = "ADH"
- ctx2.security_level = 0
- ctx2.tmp_dh_callback = proc { OpenSSL::TestUtils::TEST_KEY_DH1024 }
+ ctx2.cert = @svr_cert
+ ctx2.key = @svr_key
+ ctx2.tmp_dh_callback = proc { OpenSSL::TestUtils::Fixtures.pkey_dh("dh1024") }
sock1, sock2 = tcp_pair
@@ -365,8 +374,6 @@ module OpenSSL::TestPairM
assert_equal :wait_readable, accepted
ctx1 = OpenSSL::SSL::SSLContext.new
- ctx1.ciphers = "ADH"
- ctx1.security_level = 0
s1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx1)
th = Thread.new do
rets = []
@@ -404,9 +411,9 @@ module OpenSSL::TestPairM
def test_connect_accept_nonblock
ctx = OpenSSL::SSL::SSLContext.new()
- ctx.ciphers = "ADH"
- ctx.security_level = 0
- ctx.tmp_dh_callback = proc { OpenSSL::TestUtils::TEST_KEY_DH1024 }
+ ctx.cert = @svr_cert
+ ctx.key = @svr_key
+ ctx.tmp_dh_callback = proc { OpenSSL::TestUtils::Fixtures.pkey_dh("dh1024") }
sock1, sock2 = tcp_pair
@@ -428,8 +435,6 @@ module OpenSSL::TestPairM
sleep 0.1
ctx = OpenSSL::SSL::SSLContext.new()
- ctx.ciphers = "ADH"
- ctx.security_level = 0
s1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx)
begin
sleep 0.2
diff --git a/test/openssl/test_pkcs12.rb b/test/openssl/test_pkcs12.rb
index 403718b94f..de8e35ed79 100644
--- a/test/openssl/test_pkcs12.rb
+++ b/test/openssl/test_pkcs12.rb
@@ -1,12 +1,10 @@
# frozen_string_literal: false
require_relative "utils"
-if defined?(OpenSSL::TestUtils)
+if defined?(OpenSSL)
module OpenSSL
class TestPKCS12 < OpenSSL::TestCase
- include OpenSSL::TestUtils
-
def setup
super
ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA")
@@ -16,7 +14,7 @@ module OpenSSL
["subjectKeyIdentifier","hash",false],
["authorityKeyIdentifier","keyid:always",false],
]
- @cacert = issue_cert(ca, TEST_KEY_RSA2048, 1, ca_exts, nil, nil)
+ @cacert = issue_cert(ca, Fixtures.pkey("rsa2048"), 1, ca_exts, nil, nil)
inter_ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=Intermediate CA")
inter_ca_key = OpenSSL::PKey.read <<-_EOS_
@@ -36,25 +34,26 @@ FJx7d3f29gkzynCLJDkCQGQZlEZJC4vWmWJGRKJ24P6MyQn3VsPfErSKOg4lvyM3
Li8JsX5yIiuVYaBg/6ha3tOg4TCa5K/3r3tVliRZ2Es=
-----END RSA PRIVATE KEY-----
_EOS_
- @inter_cacert = issue_cert(inter_ca, inter_ca_key, 2, ca_exts, @cacert, TEST_KEY_RSA2048)
+ @inter_cacert = issue_cert(inter_ca, inter_ca_key, 2, ca_exts, @cacert, Fixtures.pkey("rsa2048"))
exts = [
["keyUsage","digitalSignature",true],
["subjectKeyIdentifier","hash",false],
]
ee = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=Ruby PKCS12 Test Certificate")
- @mycert = issue_cert(ee, TEST_KEY_RSA1024, 3, exts, @inter_cacert, inter_ca_key)
+ @mykey = Fixtures.pkey("rsa1024")
+ @mycert = issue_cert(ee, @mykey, 3, exts, @inter_cacert, inter_ca_key)
end
def test_create
pkcs12 = OpenSSL::PKCS12.create(
"omg",
"hello",
- TEST_KEY_RSA1024,
+ @mykey,
@mycert
)
- assert_equal @mycert, pkcs12.certificate
- assert_equal TEST_KEY_RSA1024, pkcs12.key
+ assert_equal @mycert.to_der, pkcs12.certificate.to_der
+ assert_equal @mykey.to_der, pkcs12.key.to_der
assert_nil pkcs12.ca_certs
end
@@ -62,11 +61,11 @@ Li8JsX5yIiuVYaBg/6ha3tOg4TCa5K/3r3tVliRZ2Es=
pkcs12 = OpenSSL::PKCS12.create(
nil,
"hello",
- TEST_KEY_RSA1024,
+ @mykey,
@mycert
)
- assert_equal @mycert, pkcs12.certificate
- assert_equal TEST_KEY_RSA1024, pkcs12.key
+ assert_equal @mycert.to_der, pkcs12.certificate.to_der
+ assert_equal @mykey.to_der, pkcs12.key.to_der
assert_nil pkcs12.ca_certs
decoded = OpenSSL::PKCS12.new(pkcs12.to_der)
@@ -79,7 +78,7 @@ Li8JsX5yIiuVYaBg/6ha3tOg4TCa5K/3r3tVliRZ2Es=
pkcs12 = OpenSSL::PKCS12.create(
"omg",
"hello",
- TEST_KEY_RSA1024,
+ @mykey,
@mycert,
chain
)
@@ -94,7 +93,7 @@ Li8JsX5yIiuVYaBg/6ha3tOg4TCa5K/3r3tVliRZ2Es=
pkcs12 = OpenSSL::PKCS12.create(
passwd,
"hello",
- TEST_KEY_RSA1024,
+ @mykey,
@mycert,
chain
)
@@ -104,7 +103,7 @@ Li8JsX5yIiuVYaBg/6ha3tOg4TCa5K/3r3tVliRZ2Es=
assert_include_cert @cacert, decoded.ca_certs
assert_include_cert @inter_cacert, decoded.ca_certs
assert_cert @mycert, decoded.certificate
- assert_equal TEST_KEY_RSA1024.to_der, decoded.key.to_der
+ assert_equal @mykey.to_der, decoded.key.to_der
end
def test_create_with_bad_nid
@@ -112,7 +111,7 @@ Li8JsX5yIiuVYaBg/6ha3tOg4TCa5K/3r3tVliRZ2Es=
OpenSSL::PKCS12.create(
"omg",
"hello",
- TEST_KEY_RSA1024,
+ @mykey,
@mycert,
[],
"foo"
@@ -124,7 +123,7 @@ Li8JsX5yIiuVYaBg/6ha3tOg4TCa5K/3r3tVliRZ2Es=
OpenSSL::PKCS12.create(
"omg",
"hello",
- TEST_KEY_RSA1024,
+ @mykey,
@mycert,
[],
nil,
@@ -136,7 +135,7 @@ Li8JsX5yIiuVYaBg/6ha3tOg4TCa5K/3r3tVliRZ2Es=
OpenSSL::PKCS12.create(
"omg",
"hello",
- TEST_KEY_RSA1024,
+ @mykey,
@mycert,
[],
nil,
@@ -150,7 +149,7 @@ Li8JsX5yIiuVYaBg/6ha3tOg4TCa5K/3r3tVliRZ2Es=
OpenSSL::PKCS12.create(
"omg",
"hello",
- TEST_KEY_RSA1024,
+ @mykey,
@mycert,
[],
nil,
@@ -163,7 +162,7 @@ Li8JsX5yIiuVYaBg/6ha3tOg4TCa5K/3r3tVliRZ2Es=
OpenSSL::PKCS12.create(
"omg",
"hello",
- TEST_KEY_RSA1024,
+ @mykey,
@mycert,
[],
nil,
@@ -216,7 +215,7 @@ vyl2WuMdEwQIMWFFphPkIUICAggA
EOF
p12 = OpenSSL::PKCS12.new(str, "abc123")
- assert_equal TEST_KEY_RSA1024.to_der, p12.key.to_der
+ assert_equal @mykey.to_der, p12.key.to_der
assert_equal @mycert.subject.to_der, p12.certificate.subject.to_der
assert_equal [], Array(p12.ca_certs)
end
@@ -275,13 +274,13 @@ Kw4DAhoFAAQUYAuwVtGD1TdgbFK4Yal2XBgwUR4ECEawsN3rNaa6AgIIAA==
EOF
p12 = OpenSSL::PKCS12.new(str, "abc123")
- assert_equal TEST_KEY_RSA1024.to_der, p12.key.to_der
+ assert_equal @mykey.to_der, p12.key.to_der
assert_equal nil, p12.certificate
assert_equal [], Array(p12.ca_certs)
end
def test_dup
- p12 = OpenSSL::PKCS12.create("pass", "name", TEST_KEY_RSA1024, @mycert)
+ p12 = OpenSSL::PKCS12.create("pass", "name", @mykey, @mycert)
assert_equal p12.to_der, p12.dup.to_der
end
@@ -308,7 +307,6 @@ Kw4DAhoFAAQUYAuwVtGD1TdgbFK4Yal2XBgwUR4ECEawsN3rNaa6AgIIAA==
end
false
end
-
end
end
diff --git a/test/openssl/test_pkcs5.rb b/test/openssl/test_pkcs5.rb
deleted file mode 100644
index ad8132c263..0000000000
--- a/test/openssl/test_pkcs5.rb
+++ /dev/null
@@ -1,98 +0,0 @@
-# frozen_string_literal: false
-require_relative 'utils'
-
-class OpenSSL::TestPKCS5 < OpenSSL::TestCase
-
- def test_pbkdf2_hmac_sha1_rfc6070_c_1_len_20
- p ="password"
- s = "salt"
- c = 1
- dk_len = 20
- raw = %w{ 0c 60 c8 0f 96 1f 0e 71
- f3 a9 b5 24 af 60 12 06
- 2f e0 37 a6 }
- expected = [raw.join('')].pack('H*')
- value = OpenSSL::PKCS5.pbkdf2_hmac_sha1(p, s, c, dk_len)
- assert_equal(expected, value)
- end
-
- def test_pbkdf2_hmac_sha1_rfc6070_c_2_len_20
- p ="password"
- s = "salt"
- c = 2
- dk_len = 20
- raw = %w{ ea 6c 01 4d c7 2d 6f 8c
- cd 1e d9 2a ce 1d 41 f0
- d8 de 89 57 }
- expected = [raw.join('')].pack('H*')
- value = OpenSSL::PKCS5.pbkdf2_hmac_sha1(p, s, c, dk_len)
- assert_equal(expected, value)
- end
-
- def test_pbkdf2_hmac_sha1_rfc6070_c_4096_len_20
- p ="password"
- s = "salt"
- c = 4096
- dk_len = 20
- raw = %w{ 4b 00 79 01 b7 65 48 9a
- be ad 49 d9 26 f7 21 d0
- 65 a4 29 c1 }
- expected = [raw.join('')].pack('H*')
- value = OpenSSL::PKCS5.pbkdf2_hmac_sha1(p, s, c, dk_len)
- assert_equal(expected, value)
- end
-
-# takes too long!
-# def test_pbkdf2_hmac_sha1_rfc6070_c_16777216_len_20
-# p ="password"
-# s = "salt"
-# c = 16777216
-# dk_len = 20
-# raw = %w{ ee fe 3d 61 cd 4d a4 e4
-# e9 94 5b 3d 6b a2 15 8c
-# 26 34 e9 84 }
-# expected = [raw.join('')].pack('H*')
-# value = OpenSSL::PKCS5.pbkdf2_hmac_sha1(p, s, c, dk_len)
-# assert_equal(expected, value)
-# end
-
- def test_pbkdf2_hmac_sha1_rfc6070_c_4096_len_25
- p ="passwordPASSWORDpassword"
- s = "saltSALTsaltSALTsaltSALTsaltSALTsalt"
- c = 4096
- dk_len = 25
-
- raw = %w{ 3d 2e ec 4f e4 1c 84 9b
- 80 c8 d8 36 62 c0 e4 4a
- 8b 29 1a 96 4c f2 f0 70
- 38 }
- expected = [raw.join('')].pack('H*')
- value = OpenSSL::PKCS5.pbkdf2_hmac_sha1(p, s, c, dk_len)
- assert_equal(expected, value)
- end
-
- def test_pbkdf2_hmac_sha1_rfc6070_c_4096_len_16
- p ="pass\0word"
- s = "sa\0lt"
- c = 4096
- dk_len = 16
- raw = %w{ 56 fa 6a a7 55 48 09 9d
- cc 37 d7 f0 34 25 e0 c3 }
- expected = [raw.join('')].pack('H*')
- value = OpenSSL::PKCS5.pbkdf2_hmac_sha1(p, s, c, dk_len)
- assert_equal(expected, value)
- end
-
- def test_pbkdf2_hmac_sha256_c_20000_len_32
- #unfortunately no official test vectors available yet for SHA-2
- p ="password"
- s = OpenSSL::Random.random_bytes(16)
- c = 20000
- dk_len = 32
- digest = OpenSSL::Digest::SHA256.new
- value1 = OpenSSL::PKCS5.pbkdf2_hmac(p, s, c, dk_len, digest)
- value2 = OpenSSL::PKCS5.pbkdf2_hmac(p, s, c, dk_len, digest)
- assert_equal(value1, value2)
- end if OpenSSL::PKCS5.respond_to?(:pbkdf2_hmac)
-
-end if defined?(OpenSSL::TestUtils)
diff --git a/test/openssl/test_pkcs7.rb b/test/openssl/test_pkcs7.rb
index 3219155462..149d3b9b5d 100644
--- a/test/openssl/test_pkcs7.rb
+++ b/test/openssl/test_pkcs7.rb
@@ -1,13 +1,13 @@
# frozen_string_literal: false
require_relative 'utils'
-if defined?(OpenSSL::TestUtils)
+if defined?(OpenSSL)
class OpenSSL::TestPKCS7 < OpenSSL::TestCase
def setup
super
- @rsa1024 = OpenSSL::TestUtils::TEST_KEY_RSA1024
- @rsa2048 = OpenSSL::TestUtils::TEST_KEY_RSA2048
+ @rsa1024 = Fixtures.pkey("rsa1024")
+ @rsa2048 = Fixtures.pkey("rsa2048")
ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA")
ee1 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE1")
ee2 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE2")
@@ -28,10 +28,6 @@ class OpenSSL::TestPKCS7 < OpenSSL::TestCase
@ee2_cert = issue_cert(ee2, @rsa1024, 3, ee_exts, @ca_cert, @rsa2048)
end
- def issue_cert(*args)
- OpenSSL::TestUtils.issue_cert(*args)
- end
-
def test_signed
store = OpenSSL::X509::Store.new
store.add_cert(@ca_cert)
diff --git a/test/openssl/test_pkey_dh.rb b/test/openssl/test_pkey_dh.rb
index 470c952e21..77cdb0ab84 100644
--- a/test/openssl/test_pkey_dh.rb
+++ b/test/openssl/test_pkey_dh.rb
@@ -1,29 +1,11 @@
# frozen_string_literal: false
require_relative 'utils'
-if defined?(OpenSSL::TestUtils)
+if defined?(OpenSSL) && defined?(OpenSSL::PKey::DH)
class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
- DH1024 = OpenSSL::TestUtils::TEST_KEY_DH1024
-
NEW_KEYLEN = 256
- def test_DEFAULT_parameters
- list = {
- 1024 => OpenSSL::PKey::DH::DEFAULT_1024,
- 2048 => OpenSSL::PKey::DH::DEFAULT_2048,
- }
-
- list.each do |expected_size, dh|
- assert_equal expected_size, dh.p.num_bits
- assert_predicate dh.p, :prime?
- result, remainder = (dh.p - 1) / 2
- assert_predicate result, :prime?
- assert_equal 0, remainder
- assert_no_key dh
- end
- end
-
def test_new
dh = OpenSSL::PKey::DH.new(NEW_KEYLEN)
assert_key(dh)
@@ -37,12 +19,13 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
end
def test_DHparams
+ dh1024 = Fixtures.pkey_dh("dh1024")
asn1 = OpenSSL::ASN1::Sequence([
- OpenSSL::ASN1::Integer(DH1024.p),
- OpenSSL::ASN1::Integer(DH1024.g)
+ OpenSSL::ASN1::Integer(dh1024.p),
+ OpenSSL::ASN1::Integer(dh1024.g)
])
key = OpenSSL::PKey::DH.new(asn1.to_der)
- assert_same_dh dup_public(DH1024), key
+ assert_same_dh dup_public(dh1024), key
pem = <<~EOF
-----BEGIN DH PARAMETERS-----
@@ -52,14 +35,14 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
-----END DH PARAMETERS-----
EOF
key = OpenSSL::PKey::DH.new(pem)
- assert_same_dh dup_public(DH1024), key
+ assert_same_dh dup_public(dh1024), key
- assert_equal asn1.to_der, DH1024.to_der
- assert_equal pem, DH1024.export
+ assert_equal asn1.to_der, dh1024.to_der
+ assert_equal pem, dh1024.export
end
def test_public_key
- dh = OpenSSL::TestUtils::TEST_KEY_DH1024
+ dh = Fixtures.pkey_dh("dh1024")
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)
@@ -67,14 +50,14 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
end
def test_generate_key
- dh = OpenSSL::TestUtils::TEST_KEY_DH1024.public_key # creates a copy
+ dh = Fixtures.pkey_dh("dh1024").public_key # creates a copy
assert_no_key(dh)
dh.generate_key!
assert_key(dh)
end
def test_key_exchange
- dh = OpenSSL::TestUtils::TEST_KEY_DH1024
+ dh = Fixtures.pkey_dh("dh1024")
dh2 = dh.public_key
dh.generate_key!
dh2.generate_key!
diff --git a/test/openssl/test_pkey_dsa.rb b/test/openssl/test_pkey_dsa.rb
index a4ccd1d8f9..d651949842 100644
--- a/test/openssl/test_pkey_dsa.rb
+++ b/test/openssl/test_pkey_dsa.rb
@@ -1,12 +1,9 @@
# frozen_string_literal: false
require_relative 'utils'
-require 'base64'
-if defined?(OpenSSL::TestUtils)
+if defined?(OpenSSL) && defined?(OpenSSL::PKey::DSA)
class OpenSSL::TestPKeyDSA < OpenSSL::PKeyTestCase
- DSA512 = OpenSSL::TestUtils::TEST_KEY_DSA512
-
def test_private
key = OpenSSL::PKey::DSA.new(256)
assert(key.private?)
@@ -37,27 +34,27 @@ class OpenSSL::TestPKeyDSA < OpenSSL::PKeyTestCase
end
def test_sign_verify
+ dsa512 = Fixtures.pkey("dsa512")
data = "Sign me!"
if defined?(OpenSSL::Digest::DSS1)
- signature = DSA512.sign(OpenSSL::Digest::DSS1.new, data)
- assert_equal true, DSA512.verify(OpenSSL::Digest::DSS1.new, signature, data)
+ signature = dsa512.sign(OpenSSL::Digest::DSS1.new, data)
+ assert_equal true, dsa512.verify(OpenSSL::Digest::DSS1.new, signature, data)
end
- return if OpenSSL::OPENSSL_VERSION_NUMBER <= 0x010000000
- signature = DSA512.sign("SHA1", data)
- assert_equal true, DSA512.verify("SHA1", signature, data)
+ signature = dsa512.sign("SHA1", data)
+ assert_equal true, dsa512.verify("SHA1", signature, data)
signature0 = (<<~'end;').unpack("m")[0]
MCwCFH5h40plgU5Fh0Z4wvEEpz0eE9SnAhRPbkRB8ggsN/vsSEYMXvJwjGg/
6g==
end;
- assert_equal true, DSA512.verify("SHA256", signature0, data)
+ assert_equal true, dsa512.verify("SHA256", signature0, data)
signature1 = signature0.succ
- assert_equal false, DSA512.verify("SHA256", signature1, data)
+ assert_equal false, dsa512.verify("SHA256", signature1, data)
end
def test_sys_sign_verify
- key = OpenSSL::TestUtils::TEST_KEY_DSA256
+ key = Fixtures.pkey("dsa256")
data = 'Sign me!'
digest = OpenSSL::Digest::SHA1.digest(data)
sig = key.syssign(digest)
@@ -66,17 +63,18 @@ class OpenSSL::TestPKeyDSA < OpenSSL::PKeyTestCase
def test_DSAPrivateKey
# OpenSSL DSAPrivateKey format; similar to RSAPrivateKey
+ dsa512 = Fixtures.pkey("dsa512")
asn1 = OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::Integer(0),
- OpenSSL::ASN1::Integer(DSA512.p),
- OpenSSL::ASN1::Integer(DSA512.q),
- OpenSSL::ASN1::Integer(DSA512.g),
- OpenSSL::ASN1::Integer(DSA512.pub_key),
- OpenSSL::ASN1::Integer(DSA512.priv_key)
+ OpenSSL::ASN1::Integer(dsa512.p),
+ OpenSSL::ASN1::Integer(dsa512.q),
+ OpenSSL::ASN1::Integer(dsa512.g),
+ OpenSSL::ASN1::Integer(dsa512.pub_key),
+ OpenSSL::ASN1::Integer(dsa512.priv_key)
])
key = OpenSSL::PKey::DSA.new(asn1.to_der)
assert_predicate key, :private?
- assert_same_dsa DSA512, key
+ assert_same_dsa dsa512, key
pem = <<~EOF
-----BEGIN DSA PRIVATE KEY-----
@@ -89,14 +87,15 @@ class OpenSSL::TestPKeyDSA < OpenSSL::PKeyTestCase
-----END DSA PRIVATE KEY-----
EOF
key = OpenSSL::PKey::DSA.new(pem)
- assert_same_dsa DSA512, key
+ assert_same_dsa dsa512, key
- assert_equal asn1.to_der, DSA512.to_der
- assert_equal pem, DSA512.export
+ assert_equal asn1.to_der, dsa512.to_der
+ assert_equal pem, dsa512.export
end
def test_DSAPrivateKey_encrypted
# key = abcdef
+ dsa512 = Fixtures.pkey("dsa512")
pem = <<~EOF
-----BEGIN DSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
@@ -111,35 +110,36 @@ class OpenSSL::TestPKeyDSA < OpenSSL::PKeyTestCase
-----END DSA PRIVATE KEY-----
EOF
key = OpenSSL::PKey::DSA.new(pem, "abcdef")
- assert_same_dsa DSA512, key
+ assert_same_dsa dsa512, key
key = OpenSSL::PKey::DSA.new(pem) { "abcdef" }
- assert_same_dsa DSA512, key
+ assert_same_dsa dsa512, key
cipher = OpenSSL::Cipher.new("aes-128-cbc")
- exported = DSA512.to_pem(cipher, "abcdef\0\1")
- assert_same_dsa DSA512, OpenSSL::PKey::DSA.new(exported, "abcdef\0\1")
+ exported = dsa512.to_pem(cipher, "abcdef\0\1")
+ assert_same_dsa dsa512, OpenSSL::PKey::DSA.new(exported, "abcdef\0\1")
assert_raise(OpenSSL::PKey::DSAError) {
OpenSSL::PKey::DSA.new(exported, "abcdef")
}
end
def test_PUBKEY
+ dsa512 = Fixtures.pkey("dsa512")
asn1 = OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::ObjectId("DSA"),
OpenSSL::ASN1::Sequence([
- OpenSSL::ASN1::Integer(DSA512.p),
- OpenSSL::ASN1::Integer(DSA512.q),
- OpenSSL::ASN1::Integer(DSA512.g)
+ OpenSSL::ASN1::Integer(dsa512.p),
+ OpenSSL::ASN1::Integer(dsa512.q),
+ OpenSSL::ASN1::Integer(dsa512.g)
])
]),
OpenSSL::ASN1::BitString(
- OpenSSL::ASN1::Integer(DSA512.pub_key).to_der
+ OpenSSL::ASN1::Integer(dsa512.pub_key).to_der
)
])
key = OpenSSL::PKey::DSA.new(asn1.to_der)
assert_not_predicate key, :private?
- assert_same_dsa dup_public(DSA512), key
+ assert_same_dsa dup_public(dsa512), key
pem = <<~EOF
-----BEGIN PUBLIC KEY-----
@@ -152,10 +152,10 @@ class OpenSSL::TestPKeyDSA < OpenSSL::PKeyTestCase
-----END PUBLIC KEY-----
EOF
key = OpenSSL::PKey::DSA.new(pem)
- assert_same_dsa dup_public(DSA512), key
+ assert_same_dsa dup_public(dsa512), key
- assert_equal asn1.to_der, dup_public(DSA512).to_der
- assert_equal pem, dup_public(DSA512).export
+ assert_equal asn1.to_der, dup_public(dsa512).to_der
+ assert_equal pem, dup_public(dsa512).export
end
def test_read_DSAPublicKey_pem
diff --git a/test/openssl/test_pkey_ec.rb b/test/openssl/test_pkey_ec.rb
index c549d9c674..713c649a1e 100644
--- a/test/openssl/test_pkey_ec.rb
+++ b/test/openssl/test_pkey_ec.rb
@@ -1,11 +1,9 @@
# frozen_string_literal: false
require_relative 'utils'
-if defined?(OpenSSL::TestUtils) && defined?(OpenSSL::PKey::EC)
+if defined?(OpenSSL) && defined?(OpenSSL::PKey::EC)
class OpenSSL::TestEC < OpenSSL::PKeyTestCase
- P256 = OpenSSL::TestUtils::TEST_KEY_EC_P256V1
-
def test_ec_key
builtin_curves = OpenSSL::PKey::EC.builtin_curves
assert_not_empty builtin_curves
@@ -74,17 +72,18 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
end
def test_sign_verify
+ p256 = Fixtures.pkey("p256")
data = "Sign me!"
- signature = P256.sign("SHA1", data)
- assert_equal true, P256.verify("SHA1", signature, data)
+ signature = p256.sign("SHA1", data)
+ assert_equal true, p256.verify("SHA1", signature, data)
signature0 = (<<~'end;').unpack("m")[0]
MEQCIEOTY/hD7eI8a0qlzxkIt8LLZ8uwiaSfVbjX2dPAvN11AiAQdCYx56Fq
QdBp1B4sxJoA8jvODMMklMyBKVmudboA6A==
end;
- assert_equal true, P256.verify("SHA256", signature0, data)
+ assert_equal true, p256.verify("SHA256", signature0, data)
signature1 = signature0.succ
- assert_equal false, P256.verify("SHA256", signature1, data)
+ assert_equal false, p256.verify("SHA256", signature1, data)
end
def test_dsa_sign_verify
@@ -100,16 +99,9 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
key = OpenSSL::PKey::EC.new("prime256v1").generate_key!
size = key.group.order.num_bits / 8 + 1
dgst = (1..size).to_a.pack('C*')
- begin
- sig = key.dsa_sign_asn1(dgst)
- # dgst is auto-truncated according to FIPS186-3 after openssl-0.9.8m
- assert(key.dsa_verify_asn1(dgst + "garbage", sig))
- rescue OpenSSL::PKey::ECError => e
- # just an exception for longer dgst before openssl-0.9.8m
- assert_equal('ECDSA_sign: data too large for key size', e.message)
- # no need to do following tests
- return
- end
+ sig = key.dsa_sign_asn1(dgst)
+ # dgst is auto-truncated according to FIPS186-3 after openssl-0.9.8m
+ assert(key.dsa_verify_asn1(dgst + "garbage", sig))
end
def test_dh_compute_key
@@ -124,21 +116,22 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
end
def test_ECPrivateKey
+ p256 = Fixtures.pkey("p256")
asn1 = OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::Integer(1),
- OpenSSL::ASN1::OctetString(P256.private_key.to_s(2)),
+ OpenSSL::ASN1::OctetString(p256.private_key.to_s(2)),
OpenSSL::ASN1::ASN1Data.new(
[OpenSSL::ASN1::ObjectId("prime256v1")],
0, :CONTEXT_SPECIFIC
),
OpenSSL::ASN1::ASN1Data.new(
- [OpenSSL::ASN1::BitString(P256.public_key.to_bn.to_s(2))],
+ [OpenSSL::ASN1::BitString(p256.public_key.to_bn.to_s(2))],
1, :CONTEXT_SPECIFIC
)
])
key = OpenSSL::PKey::EC.new(asn1.to_der)
assert_predicate key, :private?
- assert_same_ec P256, key
+ assert_same_ec p256, key
pem = <<~EOF
-----BEGIN EC PRIVATE KEY-----
@@ -148,13 +141,14 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
-----END EC PRIVATE KEY-----
EOF
key = OpenSSL::PKey::EC.new(pem)
- assert_same_ec P256, key
+ assert_same_ec p256, key
- assert_equal asn1.to_der, P256.to_der
- assert_equal pem, P256.export
+ assert_equal asn1.to_der, p256.to_der
+ assert_equal pem, p256.export
end
def test_ECPrivateKey_encrypted
+ p256 = Fixtures.pkey("p256")
# key = abcdef
pem = <<~EOF
-----BEGIN EC PRIVATE KEY-----
@@ -167,31 +161,32 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
-----END EC PRIVATE KEY-----
EOF
key = OpenSSL::PKey::EC.new(pem, "abcdef")
- assert_same_ec P256, key
+ assert_same_ec p256, key
key = OpenSSL::PKey::EC.new(pem) { "abcdef" }
- assert_same_ec P256, key
+ assert_same_ec p256, key
cipher = OpenSSL::Cipher.new("aes-128-cbc")
- exported = P256.to_pem(cipher, "abcdef\0\1")
- assert_same_ec P256, OpenSSL::PKey::EC.new(exported, "abcdef\0\1")
+ exported = p256.to_pem(cipher, "abcdef\0\1")
+ assert_same_ec p256, OpenSSL::PKey::EC.new(exported, "abcdef\0\1")
assert_raise(OpenSSL::PKey::ECError) {
OpenSSL::PKey::EC.new(exported, "abcdef")
}
end
def test_PUBKEY
+ p256 = Fixtures.pkey("p256")
asn1 = OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::ObjectId("id-ecPublicKey"),
OpenSSL::ASN1::ObjectId("prime256v1")
]),
OpenSSL::ASN1::BitString(
- P256.public_key.to_bn.to_s(2)
+ p256.public_key.to_bn.to_s(2)
)
])
key = OpenSSL::PKey::EC.new(asn1.to_der)
assert_not_predicate key, :private?
- assert_same_ec dup_public(P256), key
+ assert_same_ec dup_public(p256), key
pem = <<~EOF
-----BEGIN PUBLIC KEY-----
@@ -200,10 +195,10 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
-----END PUBLIC KEY-----
EOF
key = OpenSSL::PKey::EC.new(pem)
- assert_same_ec dup_public(P256), key
+ assert_same_ec dup_public(p256), key
- assert_equal asn1.to_der, dup_public(P256).to_der
- assert_equal pem, dup_public(P256).export
+ assert_equal asn1.to_der, dup_public(p256).to_der
+ assert_equal pem, dup_public(p256).export
end
def test_ec_group
@@ -305,7 +300,7 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
raise if $!.message !~ /unsupported field/
end
- p256_key = P256
+ p256_key = Fixtures.pkey("p256")
p256_g = p256_key.group
assert_equal(p256_key.public_key, p256_g.generator.mul(p256_key.private_key))
diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb
index 93760f747e..49ab379251 100644
--- a/test/openssl/test_pkey_rsa.rb
+++ b/test/openssl/test_pkey_rsa.rb
@@ -1,12 +1,9 @@
# frozen_string_literal: false
-require_relative 'utils'
-require 'base64'
+require_relative "utils"
-if defined?(OpenSSL::TestUtils)
+if defined?(OpenSSL)
class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase
- RSA1024 = OpenSSL::TestUtils::TEST_KEY_RSA1024
-
def test_padding
key = OpenSSL::PKey::RSA.new(512, 3)
@@ -71,22 +68,23 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase
end
def test_sign_verify
+ rsa1024 = Fixtures.pkey("rsa1024")
data = "Sign me!"
- signature = RSA1024.sign("SHA1", data)
- assert_equal true, RSA1024.verify("SHA1", signature, data)
+ signature = rsa1024.sign("SHA1", data)
+ assert_equal true, rsa1024.verify("SHA1", signature, data)
signature0 = (<<~'end;').unpack("m")[0]
oLCgbprPvfhM4pjFQiDTFeWI9Sk+Og7Nh9TmIZ/xSxf2CGXQrptlwo7NQ28+
WA6YQo8jPH4hSuyWIM4Gz4qRYiYRkl5TDMUYob94zm8Si1HxEiS9354tzvqS
zS8MLW2BtNPuTubMxTItHGTnOzo9sUg0LAHVFt8kHG2NfKAw/gQ=
end;
- assert_equal true, RSA1024.verify("SHA256", signature0, data)
+ assert_equal true, rsa1024.verify("SHA256", signature0, data)
signature1 = signature0.succ
- assert_equal false, RSA1024.verify("SHA256", signature1, data)
+ assert_equal false, rsa1024.verify("SHA256", signature1, data)
end
def test_digest_state_irrelevant_sign
- key = RSA1024
+ key = Fixtures.pkey("rsa1024")
digest1 = OpenSSL::Digest::SHA1.new
digest2 = OpenSSL::Digest::SHA1.new
data = 'Sign me!'
@@ -97,7 +95,7 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase
end
def test_digest_state_irrelevant_verify
- key = RSA1024
+ key = Fixtures.pkey("rsa1024")
digest1 = OpenSSL::Digest::SHA1.new
digest2 = OpenSSL::Digest::SHA1.new
data = 'Sign me!'
@@ -116,20 +114,21 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase
end
def test_RSAPrivateKey
+ rsa1024 = Fixtures.pkey("rsa1024")
asn1 = OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::Integer(0),
- OpenSSL::ASN1::Integer(RSA1024.n),
- OpenSSL::ASN1::Integer(RSA1024.e),
- OpenSSL::ASN1::Integer(RSA1024.d),
- OpenSSL::ASN1::Integer(RSA1024.p),
- OpenSSL::ASN1::Integer(RSA1024.q),
- OpenSSL::ASN1::Integer(RSA1024.dmp1),
- OpenSSL::ASN1::Integer(RSA1024.dmq1),
- OpenSSL::ASN1::Integer(RSA1024.iqmp)
+ OpenSSL::ASN1::Integer(rsa1024.n),
+ OpenSSL::ASN1::Integer(rsa1024.e),
+ OpenSSL::ASN1::Integer(rsa1024.d),
+ OpenSSL::ASN1::Integer(rsa1024.p),
+ OpenSSL::ASN1::Integer(rsa1024.q),
+ OpenSSL::ASN1::Integer(rsa1024.dmp1),
+ OpenSSL::ASN1::Integer(rsa1024.dmq1),
+ OpenSSL::ASN1::Integer(rsa1024.iqmp)
])
key = OpenSSL::PKey::RSA.new(asn1.to_der)
assert_predicate key, :private?
- assert_same_rsa RSA1024, key
+ assert_same_rsa rsa1024, key
pem = <<~EOF
-----BEGIN RSA PRIVATE KEY-----
@@ -149,13 +148,14 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase
-----END RSA PRIVATE KEY-----
EOF
key = OpenSSL::PKey::RSA.new(pem)
- assert_same_rsa RSA1024, key
+ assert_same_rsa rsa1024, key
- assert_equal asn1.to_der, RSA1024.to_der
- assert_equal pem, RSA1024.export
+ assert_equal asn1.to_der, rsa1024.to_der
+ assert_equal pem, rsa1024.export
end
def test_RSAPrivateKey_encrypted
+ rsa1024 = Fixtures.pkey("rsa1024")
# key = abcdef
pem = <<~EOF
-----BEGIN RSA PRIVATE KEY-----
@@ -178,26 +178,27 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase
-----END RSA PRIVATE KEY-----
EOF
key = OpenSSL::PKey::RSA.new(pem, "abcdef")
- assert_same_rsa RSA1024, key
+ assert_same_rsa rsa1024, key
key = OpenSSL::PKey::RSA.new(pem) { "abcdef" }
- assert_same_rsa RSA1024, key
+ assert_same_rsa rsa1024, key
cipher = OpenSSL::Cipher.new("aes-128-cbc")
- exported = RSA1024.to_pem(cipher, "abcdef\0\1")
- assert_same_rsa RSA1024, OpenSSL::PKey::RSA.new(exported, "abcdef\0\1")
+ exported = rsa1024.to_pem(cipher, "abcdef\0\1")
+ assert_same_rsa rsa1024, OpenSSL::PKey::RSA.new(exported, "abcdef\0\1")
assert_raise(OpenSSL::PKey::RSAError) {
OpenSSL::PKey::RSA.new(exported, "abcdef")
}
end
def test_RSAPublicKey
+ rsa1024 = Fixtures.pkey("rsa1024")
asn1 = OpenSSL::ASN1::Sequence([
- OpenSSL::ASN1::Integer(RSA1024.n),
- OpenSSL::ASN1::Integer(RSA1024.e)
+ OpenSSL::ASN1::Integer(rsa1024.n),
+ OpenSSL::ASN1::Integer(rsa1024.e)
])
key = OpenSSL::PKey::RSA.new(asn1.to_der)
assert_not_predicate key, :private?
- assert_same_rsa dup_public(RSA1024), key
+ assert_same_rsa dup_public(rsa1024), key
pem = <<~EOF
-----BEGIN RSA PUBLIC KEY-----
@@ -207,10 +208,11 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase
-----END RSA PUBLIC KEY-----
EOF
key = OpenSSL::PKey::RSA.new(pem)
- assert_same_rsa dup_public(RSA1024), key
+ assert_same_rsa dup_public(rsa1024), key
end
def test_PUBKEY
+ rsa1024 = Fixtures.pkey("rsa1024")
asn1 = OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::ObjectId("rsaEncryption"),
@@ -218,14 +220,14 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase
]),
OpenSSL::ASN1::BitString(
OpenSSL::ASN1::Sequence([
- OpenSSL::ASN1::Integer(RSA1024.n),
- OpenSSL::ASN1::Integer(RSA1024.e)
+ OpenSSL::ASN1::Integer(rsa1024.n),
+ OpenSSL::ASN1::Integer(rsa1024.e)
]).to_der
)
])
key = OpenSSL::PKey::RSA.new(asn1.to_der)
assert_not_predicate key, :private?
- assert_same_rsa dup_public(RSA1024), key
+ assert_same_rsa dup_public(rsa1024), key
pem = <<~EOF
-----BEGIN PUBLIC KEY-----
@@ -236,14 +238,14 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase
-----END PUBLIC KEY-----
EOF
key = OpenSSL::PKey::RSA.new(pem)
- assert_same_rsa dup_public(RSA1024), key
+ assert_same_rsa dup_public(rsa1024), key
- assert_equal asn1.to_der, dup_public(RSA1024).to_der
- assert_equal pem, dup_public(RSA1024).export
+ assert_equal asn1.to_der, dup_public(rsa1024).to_der
+ assert_equal pem, dup_public(rsa1024).export
end
def test_pem_passwd
- key = RSA1024
+ key = Fixtures.pkey("rsa1024")
pem3c = key.to_pem("aes-128-cbc", "key")
assert_match (/ENCRYPTED/), pem3c
assert_equal key.to_der, OpenSSL::PKey.read(pem3c, "key").to_der
diff --git a/test/openssl/test_random.rb b/test/openssl/test_random.rb
index 6079461920..d5a374540d 100644
--- a/test/openssl/test_random.rb
+++ b/test/openssl/test_random.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: false
require_relative "utils"
+if defined?(OpenSSL)
+
class OpenSSL::TestRandom < OpenSSL::TestCase
def test_random_bytes
assert_equal("", OpenSSL::Random.random_bytes(0))
@@ -12,4 +14,6 @@ class OpenSSL::TestRandom < OpenSSL::TestCase
assert_equal("", OpenSSL::Random.pseudo_bytes(0))
assert_equal(12, OpenSSL::Random.pseudo_bytes(12).bytesize)
end if OpenSSL::Random.methods.include?(:pseudo_bytes)
-end if defined?(OpenSSL::TestCase)
+end
+
+end
diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb
index 8c65df953d..3f17ab0d38 100644
--- a/test/openssl/test_ssl.rb
+++ b/test/openssl/test_ssl.rb
@@ -1,10 +1,9 @@
# frozen_string_literal: false
require_relative "utils"
-if defined?(OpenSSL::TestUtils)
+if defined?(OpenSSL)
class OpenSSL::TestSSL < OpenSSL::SSLTestCase
-
def test_ctx_options
ctx = OpenSSL::SSL::SSLContext.new
@@ -35,7 +34,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
readwrite_loop(ctx, ssl)
}
- start_server(ctx_proc: ctx_proc, server_proc: server_proc) { |server, port|
+ start_server(ctx_proc: ctx_proc, server_proc: server_proc) { |port|
begin
sock = TCPSocket.new("127.0.0.1", port)
ctx = OpenSSL::SSL::SSLContext.new
@@ -56,7 +55,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
end
def test_sysread_and_syswrite
- start_server { |server, port|
+ start_server { |port|
server_connect(port) { |ssl|
str = "x" * 100 + "\n"
ssl.syswrite(str)
@@ -72,7 +71,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
end
def test_sync_close
- start_server { |server, port|
+ start_server { |port|
begin
sock = TCPSocket.new("127.0.0.1", port)
ssl = OpenSSL::SSL::SSLSocket.new(sock)
@@ -97,7 +96,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
end
def test_copy_stream
- start_server do |server, port|
+ start_server do |port|
server_connect(port) do |ssl|
IO.pipe do |r, w|
str = "hello world\n"
@@ -112,21 +111,16 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
def test_client_auth_failure
vflag = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
- start_server(verify_mode: vflag, ignore_listener_error: true) { |server, port|
- sock = TCPSocket.new("127.0.0.1", port)
- ssl = OpenSSL::SSL::SSLSocket.new(sock)
- ssl.sync_close = true
- begin
- assert_handshake_error { ssl.connect }
- ensure
- ssl.close
- end
+ start_server(verify_mode: vflag, ignore_listener_error: true) { |port|
+ assert_handshake_error {
+ server_connect(port) { |ssl| ssl.puts("abc"); ssl.gets }
+ }
}
end
def test_client_auth_success
vflag = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
- start_server(verify_mode: vflag) { |server, port|
+ start_server(verify_mode: vflag) { |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.key = @cli_key
ctx.cert = @cli_cert
@@ -153,19 +147,21 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
def test_client_auth_public_key
vflag = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
- start_server(verify_mode: vflag, ignore_listener_error: true) do |server, port|
+ start_server(verify_mode: vflag, ignore_listener_error: true) do |port|
assert_raise(ArgumentError) {
ctx = OpenSSL::SSL::SSLContext.new
ctx.key = @cli_key.public_key
ctx.cert = @cli_cert
- server_connect(port, ctx) { }
+ server_connect(port, ctx) { |ssl| ssl.puts("abc"); ssl.gets }
}
ctx = OpenSSL::SSL::SSLContext.new
ctx.client_cert_cb = Proc.new{ |ssl|
[@cli_cert, @cli_key.public_key]
}
- assert_handshake_error { server_connect(port, ctx) }
+ assert_handshake_error {
+ server_connect(port, ctx) { |ssl| ssl.puts("abc"); ssl.gets }
+ }
end
end
@@ -175,7 +171,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
end
vflag = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
- start_server(verify_mode: vflag, ctx_proc: ctx_proc) { |server, port|
+ start_server(verify_mode: vflag, ctx_proc: ctx_proc) { |port|
ctx = OpenSSL::SSL::SSLContext.new
client_ca_from_server = nil
ctx.client_cert_cb = Proc.new do |sslconn|
@@ -187,8 +183,8 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
end
def test_read_nonblock_without_session
- OpenSSL::TestUtils.silent do
- start_server(start_immediately: false) { |server, port|
+ EnvUtil.suppress_warning do
+ start_server(start_immediately: false) { |port|
sock = TCPSocket.new("127.0.0.1", port)
ssl = OpenSSL::SSL::SSLSocket.new(sock)
ssl.sync_close = true
@@ -206,26 +202,21 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
def test_starttls
server_proc = -> (ctx, ssl) {
- begin
- while line = ssl.gets
- if line =~ /^STARTTLS$/
- ssl.write("x")
- ssl.flush
- ssl.accept
- next
- end
- ssl.write(line)
+ while line = ssl.gets
+ if line =~ /^STARTTLS$/
+ ssl.write("x")
+ ssl.flush
+ ssl.accept
+ break
end
- rescue OpenSSL::SSL::SSLError
- rescue IOError
- ensure
- ssl.close rescue nil
+ ssl.write(line)
end
+ readwrite_loop(ctx, ssl)
}
EnvUtil.suppress_warning do # read/write on not started session
start_server(start_immediately: false,
- server_proc: server_proc) { |server, port|
+ server_proc: server_proc) { |port|
begin
sock = TCPSocket.new("127.0.0.1", port)
ssl = OpenSSL::SSL::SSLSocket.new(sock)
@@ -248,7 +239,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
end
def test_parallel
- start_server { |server, port|
+ start_server { |port|
ssls = []
10.times{
sock = TCPSocket.new("127.0.0.1", port)
@@ -269,7 +260,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
end
def test_verify_result
- start_server(ignore_listener_error: true) { |server, port|
+ start_server(ignore_listener_error: true) { |port|
sock = TCPSocket.new("127.0.0.1", port)
ctx = OpenSSL::SSL::SSLContext.new
ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
@@ -283,7 +274,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
end
}
- start_server { |server, port|
+ start_server { |port|
sock = TCPSocket.new("127.0.0.1", port)
ctx = OpenSSL::SSL::SSLContext.new
ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
@@ -301,7 +292,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
end
}
- start_server(ignore_listener_error: true) { |server, port|
+ start_server(ignore_listener_error: true) { |port|
sock = TCPSocket.new("127.0.0.1", port)
ctx = OpenSSL::SSL::SSLContext.new
ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
@@ -321,7 +312,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
end
def test_exception_in_verify_callback_is_ignored
- start_server(ignore_listener_error: true) { |server, port|
+ start_server(ignore_listener_error: true) { |port|
sock = TCPSocket.new("127.0.0.1", port)
ctx = OpenSSL::SSL::SSLContext.new
ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
@@ -332,7 +323,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
ssl.sync_close = true
begin
- OpenSSL::TestUtils.silent do
+ EnvUtil.suppress_warning do
# SSLError, not RuntimeError
assert_raise(OpenSSL::SSL::SSLError) { ssl.connect }
end
@@ -352,20 +343,22 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
assert ciphers_names.all?{|v| /A(EC)?DH/ !~ v }, "anon ciphers are disabled"
assert ciphers_names.all?{|v| /(RC4|MD5|EXP|DES(?!-EDE|-CBC3))/ !~ v }, "weak ciphers are disabled"
assert_equal 0, ctx.options & OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS
- if defined?(OpenSSL::SSL::OP_NO_COMPRESSION) # >= 1.0.0
- assert_equal OpenSSL::SSL::OP_NO_COMPRESSION,
- ctx.options & OpenSSL::SSL::OP_NO_COMPRESSION
- end
+ assert_equal OpenSSL::SSL::OP_NO_COMPRESSION,
+ ctx.options & OpenSSL::SSL::OP_NO_COMPRESSION
end
def test_post_connect_check_with_anon_ciphers
+ pend "TLS 1.2 is not supported" unless tls12_supported?
+
ctx_proc = -> ctx {
+ ctx.ssl_version = :TLSv1_2
ctx.ciphers = "aNULL"
ctx.security_level = 0
}
- start_server(ctx_proc: ctx_proc) { |server, port|
+ start_server(ctx_proc: ctx_proc) { |port|
ctx = OpenSSL::SSL::SSLContext.new
+ ctx.ssl_version = :TLSv1_2
ctx.ciphers = "aNULL"
ctx.security_level = 0
server_connect(port, ctx) { |ssl|
@@ -379,7 +372,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
def test_post_connection_check
sslerr = OpenSSL::SSL::SSLError
- start_server { |server, port|
+ start_server { |port|
server_connect(port) { |ssl|
assert_raise(sslerr){ssl.post_connection_check("localhost.localdomain")}
assert_raise(sslerr){ssl.post_connection_check("127.0.0.1")}
@@ -400,7 +393,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
["subjectAltName","IP:127.0.0.1",false],
]
@svr_cert = issue_cert(@svr, @svr_key, 4, exts, @ca_cert, @ca_key)
- start_server { |server, port|
+ start_server { |port|
server_connect(port) { |ssl|
assert(ssl.post_connection_check("localhost.localdomain"))
assert(ssl.post_connection_check("127.0.0.1"))
@@ -420,7 +413,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
["subjectAltName","DNS:*.localdomain",false],
]
@svr_cert = issue_cert(@svr, @svr_key, 5, exts, @ca_cert, @ca_key)
- start_server { |server, port|
+ start_server { |port|
server_connect(port) { |ssl|
assert(ssl.post_connection_check("localhost.localdomain"))
assert_raise(sslerr){ssl.post_connection_check("127.0.0.1")}
@@ -623,48 +616,44 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
end
def test_tlsext_hostname
- ctx3 = OpenSSL::SSL::SSLContext.new
- ctx3.ciphers = "ADH"
- ctx3.tmp_dh_callback = proc { OpenSSL::TestUtils::TEST_KEY_DH1024 }
- ctx3.security_level = 0
- assert_not_predicate ctx3, :frozen?
+ fooctx = OpenSSL::SSL::SSLContext.new
+ fooctx.tmp_dh_callback = proc { Fixtures.pkey_dh("dh1024") }
+ fooctx.cert = @cli_cert
+ fooctx.key = @cli_key
- ctx_proc = -> ctx {
- ctx.ciphers = "ALL:!aNULL"
+ ctx_proc = proc { |ctx|
ctx.servername_cb = proc { |ssl, servername|
case servername
when "foo.example.com"
- ctx3
+ fooctx
when "bar.example.com"
nil
else
- raise "unknown hostname"
+ raise "unreachable"
end
}
}
- start_server(ctx_proc: ctx_proc) do |server, port|
- ctx = OpenSSL::SSL::SSLContext.new
- ctx.ciphers = "ALL"
- ctx.security_level = 0
-
+ start_server(ctx_proc: ctx_proc) do |port|
sock = TCPSocket.new("127.0.0.1", port)
begin
- ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
ssl.hostname = "foo.example.com"
ssl.connect
- assert_match (/^ADH-/), ssl.cipher[0], "the context returned by servername_cb is used"
- assert_predicate ctx3, :frozen?
+ assert_equal @cli_cert.serial, ssl.peer_cert.serial
+ assert_predicate fooctx, :frozen?
ensure
+ ssl&.close
sock.close
end
sock = TCPSocket.new("127.0.0.1", port)
begin
- ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
ssl.hostname = "bar.example.com"
ssl.connect
- assert_not_match (/^A(EC)?DH-/), ssl.cipher[0], "the original context is used"
+ assert_equal @svr_cert.serial, ssl.peer_cert.serial
ensure
+ ssl&.close
sock.close
end
end
@@ -674,9 +663,9 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
hostname = 'example.org'
ctx2 = OpenSSL::SSL::SSLContext.new
- ctx2.ciphers = "aNULL"
- ctx2.tmp_dh_callback = proc { OpenSSL::TestUtils::TEST_KEY_DH1024 }
- ctx2.security_level = 0
+ ctx2.cert = @svr_cert
+ ctx2.key = @svr_key
+ ctx2.tmp_dh_callback = proc { Fixtures.pkey_dh("dh1024") }
ctx2.servername_cb = lambda { |args| Object.new }
sock1, sock2 = socketpair
@@ -684,8 +673,6 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
s2 = OpenSSL::SSL::SSLSocket.new(sock2, ctx2)
ctx1 = OpenSSL::SSL::SSLContext.new
- ctx1.ciphers = "aNULL"
- ctx1.security_level = 0
s1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx1)
s1.hostname = hostname
@@ -716,7 +703,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
ctx.key = @svr_key
}
- start_server(ctx_proc: ctx_proc, ignore_listener_error: true) do |server, port|
+ start_server(ctx_proc: ctx_proc, ignore_listener_error: true) do |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.verify_hostname = true
ctx.cert_store = OpenSSL::X509::Store.new
@@ -749,27 +736,26 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
end
end
- def test_multibyte_read_write
- #German a umlaut
- auml = [%w{ C3 A4 }.join('')].pack('H*')
- auml.force_encoding(Encoding::UTF_8)
-
- [10, 1000, 100000].each {|i|
- str = nil
- num_written = nil
- server_proc = Proc.new {|ctx, ssl|
- cmp = ssl.read
- raw_size = cmp.size
- cmp.force_encoding(Encoding::UTF_8)
- assert_equal(str, cmp)
- assert_equal(num_written, raw_size)
- ssl.close
+ def test_connect_certificate_verify_failed_exception_message
+ start_server(ignore_listener_error: true) { |port|
+ ctx = OpenSSL::SSL::SSLContext.new
+ ctx.set_params
+ assert_raise_with_message(OpenSSL::SSL::SSLError, /self signed/) {
+ server_connect(port, ctx)
}
- start_server(server_proc: server_proc) { |server, port|
- server_connect(port) { |ssl|
- str = auml * i
- num_written = ssl.write(str)
- }
+ }
+
+ ctx_proc = proc { |ctx|
+ ctx.cert = issue_cert(@svr, @svr_key, 30, [], @ca_cert, @ca_key,
+ not_before: Time.now-100, not_after: Time.now-10)
+ }
+ start_server(ignore_listener_error: true, ctx_proc: ctx_proc) { |port|
+ store = OpenSSL::X509::Store.new
+ store.add_cert(@ca_cert)
+ ctx = OpenSSL::SSL::SSLContext.new
+ ctx.set_params(cert_store: store)
+ assert_raise_with_message(OpenSSL::SSL::SSLError, /expired/) {
+ server_connect(port, ctx)
}
}
end
@@ -781,7 +767,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
# But it also degrades gracefully, so keep it
ctx.options = OpenSSL::SSL::OP_ALL
}
- start_server(ctx_proc: ctx_proc) { |server, port|
+ start_server(ctx_proc: ctx_proc) { |port|
server_connect(port) { |ssl|
ssl.puts('hello')
assert_equal("hello\n", ssl.gets)
@@ -789,112 +775,223 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
}
end
-if OpenSSL::SSL::SSLContext::METHODS.include?(:TLSv1) && OpenSSL::SSL::SSLContext::METHODS.include?(:SSLv3)
+ def check_supported_protocol_versions
+ possible_versions = [
+ OpenSSL::SSL::SSL3_VERSION,
+ OpenSSL::SSL::TLS1_VERSION,
+ OpenSSL::SSL::TLS1_1_VERSION,
+ OpenSSL::SSL::TLS1_2_VERSION,
+ # OpenSSL 1.1.1
+ defined?(OpenSSL::SSL::TLS1_3_VERSION) && OpenSSL::SSL::TLS1_3_VERSION,
+ ].compact
+
+ # Prepare for testing & do sanity check
+ supported = []
+ possible_versions.each do |ver|
+ catch(:unsupported) {
+ ctx_proc = proc { |ctx|
+ begin
+ ctx.min_version = ctx.max_version = ver
+ rescue ArgumentError, OpenSSL::SSL::SSLError
+ throw :unsupported
+ end
+ }
+ start_server(ctx_proc: ctx_proc, ignore_listener_error: true) do |port|
+ begin
+ server_connect(port) { }
+ rescue OpenSSL::SSL::SSLError, Errno::ECONNRESET
+ else
+ supported << ver
+ end
+ end
+ }
+ end
+ assert_not_empty supported
- def test_forbid_ssl_v3_for_client
- ctx_proc = Proc.new { |ctx| ctx.options = OpenSSL::SSL::OP_ALL | OpenSSL::SSL::OP_NO_SSLv3 }
- start_server_version(:SSLv23, ctx_proc) { |server, port|
- ctx = OpenSSL::SSL::SSLContext.new
- ctx.ssl_version = :SSLv3
- assert_handshake_error { server_connect(port, ctx) }
- }
+ supported
end
- def test_forbid_ssl_v3_from_server
- start_server_version(:SSLv3) { |server, port|
- ctx = OpenSSL::SSL::SSLContext.new
- ctx.options = OpenSSL::SSL::OP_ALL | OpenSSL::SSL::OP_NO_SSLv3
- assert_handshake_error { server_connect(port, ctx) }
+ def test_minmax_version
+ supported = check_supported_protocol_versions
+
+ # name: The string that would be returned by SSL_get_version()
+ # method: The version-specific method name (if any)
+ vmap = {
+ OpenSSL::SSL::SSL3_VERSION => { name: "SSLv3", method: "SSLv3" },
+ OpenSSL::SSL::SSL3_VERSION => { name: "SSLv3", method: "SSLv3" },
+ OpenSSL::SSL::TLS1_VERSION => { name: "TLSv1", method: "TLSv1" },
+ OpenSSL::SSL::TLS1_1_VERSION => { name: "TLSv1.1", method: "TLSv1_1" },
+ OpenSSL::SSL::TLS1_2_VERSION => { name: "TLSv1.2", method: "TLSv1_2" },
+ # OpenSSL 1.1.1
+ defined?(OpenSSL::SSL::TLS1_3_VERSION) && OpenSSL::SSL::TLS1_3_VERSION =>
+ { name: "TLSv1.3", method: nil },
}
- end
-end
+ # Server enables a single version
+ supported.each do |ver|
+ ctx_proc = proc { |ctx| ctx.min_version = ctx.max_version = ver }
+ start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port|
+ supported.each do |cver|
+ # Client enables a single version
+ ctx1 = OpenSSL::SSL::SSLContext.new
+ ctx1.min_version = ctx1.max_version = cver
+ if ver == cver
+ server_connect(port, ctx1) { |ssl|
+ assert_equal vmap[cver][:name], ssl.ssl_version
+ }
+ else
+ assert_handshake_error { server_connect(port, ctx1) { } }
+ end
-if OpenSSL::SSL::SSLContext::METHODS.include?(:TLSv1_1) && OpenSSL::SSL::SSLContext::METHODS.include?(:TLSv1)
+ # There is no version-specific SSL methods for TLS 1.3
+ if cver <= OpenSSL::SSL::TLS1_2_VERSION
+ # Client enables a single version using #ssl_version=
+ ctx2 = OpenSSL::SSL::SSLContext.new
+ ctx2.ssl_version = vmap[cver][:method]
+ if ver == cver
+ server_connect(port, ctx2) { |ssl|
+ assert_equal vmap[cver][:name], ssl.ssl_version
+ }
+ else
+ assert_handshake_error { server_connect(port, ctx2) { } }
+ end
+ end
+ end
- def test_tls_v1_1
- start_server_version(:TLSv1_1) { |server, port|
- server_connect(port) { |ssl| assert_equal("TLSv1.1", ssl.ssl_version) }
- }
- end
+ # Client enables all supported versions
+ ctx3 = OpenSSL::SSL::SSLContext.new
+ ctx3.min_version = ctx3.max_version = nil
+ server_connect(port, ctx3) { |ssl|
+ assert_equal vmap[ver][:name], ssl.ssl_version
+ }
+ }
+ end
- def test_forbid_tls_v1_for_client
- ctx_proc = Proc.new { |ctx| ctx.options = OpenSSL::SSL::OP_ALL | OpenSSL::SSL::OP_NO_TLSv1 }
- start_server_version(:SSLv23, ctx_proc) { |server, port|
- ctx = OpenSSL::SSL::SSLContext.new
- ctx.ssl_version = :TLSv1
- assert_handshake_error { server_connect(port, ctx) }
+ if supported.size == 1
+ pend "More than one protocol version must be supported"
+ end
+
+ # Server sets min_version (earliest is disabled)
+ sver = supported[1]
+ ctx_proc = proc { |ctx| ctx.min_version = sver }
+ start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port|
+ supported.each do |cver|
+ # Client sets min_version
+ ctx1 = OpenSSL::SSL::SSLContext.new
+ ctx1.min_version = cver
+ server_connect(port, ctx1) { |ssl|
+ assert_equal vmap[supported.last][:name], ssl.ssl_version
+ }
+
+ # Client sets max_version
+ ctx2 = OpenSSL::SSL::SSLContext.new
+ ctx2.max_version = cver
+ if cver >= sver
+ server_connect(port, ctx2) { |ssl|
+ assert_equal vmap[cver][:name], ssl.ssl_version
+ }
+ else
+ assert_handshake_error { server_connect(port, ctx2) { } }
+ end
+ end
}
- end
- def test_forbid_tls_v1_from_server
- start_server_version(:TLSv1) { |server, port|
- ctx = OpenSSL::SSL::SSLContext.new
- ctx.options = OpenSSL::SSL::OP_ALL | OpenSSL::SSL::OP_NO_TLSv1
- assert_handshake_error { server_connect(port, ctx) }
+ # Server sets max_version (latest is disabled)
+ sver = supported[-2]
+ ctx_proc = proc { |ctx| ctx.max_version = sver }
+ start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port|
+ supported.each do |cver|
+ # Client sets min_version
+ ctx1 = OpenSSL::SSL::SSLContext.new
+ ctx1.min_version = cver
+ if cver <= sver
+ server_connect(port, ctx1) { |ssl|
+ assert_equal vmap[sver][:name], ssl.ssl_version
+ }
+ else
+ assert_handshake_error { server_connect(port, ctx1) { } }
+ end
+
+ # Client sets max_version
+ ctx2 = OpenSSL::SSL::SSLContext.new
+ ctx2.max_version = cver
+ server_connect(port, ctx2) { |ssl|
+ if cver >= sver
+ assert_equal vmap[sver][:name], ssl.ssl_version
+ else
+ assert_equal vmap[cver][:name], ssl.ssl_version
+ end
+ }
+ end
}
end
-end
-
-if OpenSSL::SSL::SSLContext::METHODS.include?(:TLSv1_2) && OpenSSL::SSL::SSLContext::METHODS.include?(:TLSv1_1)
+ def test_options_disable_versions
+ # Note: Use of these OP_* flags has been deprecated since OpenSSL 1.1.0.
+ supported = check_supported_protocol_versions
- def test_tls_v1_2
- start_server_version(:TLSv1_2) { |server, port|
- ctx = OpenSSL::SSL::SSLContext.new
- ctx.ssl_version = :TLSv1_2_client
- server_connect(port, ctx) { |ssl| assert_equal("TLSv1.2", ssl.ssl_version) }
- }
- end if OpenSSL::OPENSSL_VERSION_NUMBER > 0x10001000
+ if supported.include?(OpenSSL::SSL::TLS1_1_VERSION) &&
+ supported.include?(OpenSSL::SSL::TLS1_2_VERSION)
+ # Server disables ~ TLS 1.1
+ ctx_proc = proc { |ctx|
+ ctx.options |= OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3 |
+ OpenSSL::SSL::OP_NO_TLSv1 | OpenSSL::SSL::OP_NO_TLSv1_1
+ }
+ start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port|
+ # Client only supports TLS 1.1
+ ctx1 = OpenSSL::SSL::SSLContext.new
+ ctx1.min_version = ctx1.max_version = OpenSSL::SSL::TLS1_1_VERSION
+ assert_handshake_error { server_connect(port, ctx1) { } }
- def test_forbid_tls_v1_1_for_client
- ctx_proc = Proc.new { |ctx| ctx.options = OpenSSL::SSL::OP_ALL | OpenSSL::SSL::OP_NO_TLSv1_1 }
- start_server_version(:SSLv23, ctx_proc) { |server, port|
- ctx = OpenSSL::SSL::SSLContext.new
- ctx.ssl_version = :TLSv1_1
- assert_handshake_error { server_connect(port, ctx) }
- }
- end if defined?(OpenSSL::SSL::OP_NO_TLSv1_1)
+ # Client only supports TLS 1.2
+ ctx2 = OpenSSL::SSL::SSLContext.new
+ ctx2.min_version = ctx2.max_version = OpenSSL::SSL::TLS1_2_VERSION
+ assert_nothing_raised { server_connect(port, ctx2) { } }
+ }
- def test_forbid_tls_v1_1_from_server
- start_server_version(:TLSv1_1) { |server, port|
- ctx = OpenSSL::SSL::SSLContext.new
- ctx.options = OpenSSL::SSL::OP_ALL | OpenSSL::SSL::OP_NO_TLSv1_1
- assert_handshake_error { server_connect(port, ctx) }
- }
- end if defined?(OpenSSL::SSL::OP_NO_TLSv1_1)
+ # Server only supports TLS 1.1
+ ctx_proc = proc { |ctx|
+ ctx.min_version = ctx.max_version = OpenSSL::SSL::TLS1_1_VERSION
+ }
+ start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port|
+ # Client disables TLS 1.1
+ ctx1 = OpenSSL::SSL::SSLContext.new
+ ctx1.options |= OpenSSL::SSL::OP_NO_TLSv1_1
+ assert_handshake_error { server_connect(port, ctx1) { } }
- def test_forbid_tls_v1_2_for_client
- ctx_proc = Proc.new { |ctx| ctx.options = OpenSSL::SSL::OP_ALL | OpenSSL::SSL::OP_NO_TLSv1_2 }
- start_server_version(:SSLv23, ctx_proc) { |server, port|
- ctx = OpenSSL::SSL::SSLContext.new
- ctx.ssl_version = :TLSv1_2
- assert_handshake_error { server_connect(port, ctx) }
- }
- end if defined?(OpenSSL::SSL::OP_NO_TLSv1_2)
+ # Client disables TLS 1.2
+ ctx2 = OpenSSL::SSL::SSLContext.new
+ ctx2.options |= OpenSSL::SSL::OP_NO_TLSv1_2
+ assert_nothing_raised { server_connect(port, ctx2) { } }
+ }
+ else
+ pend "TLS 1.1 and TLS 1.2 must be supported; skipping"
+ end
+ end
- def test_forbid_tls_v1_2_from_server
- start_server_version(:TLSv1_2) { |server, port|
- ctx = OpenSSL::SSL::SSLContext.new
- ctx.options = OpenSSL::SSL::OP_ALL | OpenSSL::SSL::OP_NO_TLSv1_2
- assert_handshake_error { server_connect(port, ctx) }
+ def test_ssl_methods_constant
+ EnvUtil.suppress_warning { # Deprecated in v2.1.0
+ base = [:TLSv1_2, :TLSv1_1, :TLSv1, :SSLv3, :SSLv2, :SSLv23]
+ base.each do |name|
+ assert_include OpenSSL::SSL::SSLContext::METHODS, name
+ assert_include OpenSSL::SSL::SSLContext::METHODS, :"#{name}_client"
+ assert_include OpenSSL::SSL::SSLContext::METHODS, :"#{name}_server"
+ end
}
- end if defined?(OpenSSL::SSL::OP_NO_TLSv1_2)
-
-end
+ end
def test_renegotiation_cb
num_handshakes = 0
renegotiation_cb = Proc.new { |ssl| num_handshakes += 1 }
ctx_proc = Proc.new { |ctx| ctx.renegotiation_cb = renegotiation_cb }
- start_server_version(:SSLv23, ctx_proc) { |server, port|
+ start_server_version(:SSLv23, ctx_proc) { |port|
server_connect(port) { |ssl|
assert_equal(1, num_handshakes)
}
}
end
-if OpenSSL::OPENSSL_VERSION_NUMBER >= 0x10002000
+if openssl?(1, 0, 2) || libressl?
def test_alpn_protocol_selection_ary
advertised = ["http/1.1", "spdy/2"]
ctx_proc = Proc.new { |ctx|
@@ -903,7 +1000,7 @@ if OpenSSL::OPENSSL_VERSION_NUMBER >= 0x10002000
}
ctx.alpn_protocols = advertised
}
- start_server_version(:SSLv23, ctx_proc) { |server, port|
+ start_server_version(:SSLv23, ctx_proc) { |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.alpn_protocols = advertised
server_connect(port, ctx) { |ssl|
@@ -916,14 +1013,12 @@ if OpenSSL::OPENSSL_VERSION_NUMBER >= 0x10002000
sock1, sock2 = socketpair
ctx1 = OpenSSL::SSL::SSLContext.new
- ctx1.ciphers = "aNULL"
- ctx1.security_level = 0
+ ctx1.cert = @svr_cert
+ ctx1.key = @svr_key
ctx1.alpn_select_cb = -> (protocols) { nil }
ssl1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx1)
ctx2 = OpenSSL::SSL::SSLContext.new
- ctx2.ciphers = "aNULL"
- ctx2.security_level = 0
ctx2.alpn_protocols = ["http/1.1"]
ssl2 = OpenSSL::SSL::SSLSocket.new(sock2, ctx2)
@@ -942,14 +1037,14 @@ if OpenSSL::OPENSSL_VERSION_NUMBER >= 0x10002000
end
end
-if OpenSSL::OPENSSL_VERSION_NUMBER > 0x10001000 &&
- OpenSSL::SSL::SSLContext.method_defined?(:npn_select_cb)
- # NPN may be disabled by OpenSSL configure option
-
def test_npn_protocol_selection_ary
+ pend "TLS 1.2 is not supported" unless tls12_supported?
+ pend "NPN is not supported" unless \
+ OpenSSL::SSL::SSLContext.method_defined?(:npn_select_cb)
+
advertised = ["http/1.1", "spdy/2"]
- ctx_proc = Proc.new { |ctx| ctx.npn_protocols = advertised }
- start_server_version(:SSLv23, ctx_proc) { |server, port|
+ ctx_proc = proc { |ctx| ctx.npn_protocols = advertised }
+ start_server_version(:TLSv1_2, ctx_proc) { |port|
selector = lambda { |which|
ctx = OpenSSL::SSL::SSLContext.new
ctx.npn_select_cb = -> (protocols) { protocols.send(which) }
@@ -963,13 +1058,17 @@ if OpenSSL::OPENSSL_VERSION_NUMBER > 0x10001000 &&
end
def test_npn_protocol_selection_enum
+ pend "TLS 1.2 is not supported" unless tls12_supported?
+ pend "NPN is not supported" unless \
+ OpenSSL::SSL::SSLContext.method_defined?(:npn_select_cb)
+
advertised = Object.new
def advertised.each
yield "http/1.1"
yield "spdy/2"
end
ctx_proc = Proc.new { |ctx| ctx.npn_protocols = advertised }
- start_server_version(:SSLv23, ctx_proc) { |server, port|
+ start_server_version(:TLSv1_2, ctx_proc) { |port|
selector = lambda { |selected, which|
ctx = OpenSSL::SSL::SSLContext.new
ctx.npn_select_cb = -> (protocols) { protocols.to_a.send(which) }
@@ -983,8 +1082,12 @@ if OpenSSL::OPENSSL_VERSION_NUMBER > 0x10001000 &&
end
def test_npn_protocol_selection_cancel
+ pend "TLS 1.2 is not supported" unless tls12_supported?
+ pend "NPN is not supported" unless \
+ OpenSSL::SSL::SSLContext.method_defined?(:npn_select_cb)
+
ctx_proc = Proc.new { |ctx| ctx.npn_protocols = ["http/1.1"] }
- start_server_version(:SSLv23, ctx_proc) { |server, port|
+ start_server_version(:TLSv1_2, ctx_proc) { |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.npn_select_cb = -> (protocols) { raise RuntimeError.new }
assert_raise(RuntimeError) { server_connect(port, ctx) }
@@ -992,8 +1095,12 @@ if OpenSSL::OPENSSL_VERSION_NUMBER > 0x10001000 &&
end
def test_npn_advertised_protocol_too_long
+ pend "TLS 1.2 is not supported" unless tls12_supported?
+ pend "NPN is not supported" unless \
+ OpenSSL::SSL::SSLContext.method_defined?(:npn_select_cb)
+
ctx_proc = Proc.new { |ctx| ctx.npn_protocols = ["a" * 256] }
- start_server_version(:SSLv23, ctx_proc) { |server, port|
+ start_server_version(:TLSv1_2, ctx_proc) { |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.npn_select_cb = -> (protocols) { protocols.first }
assert_handshake_error { server_connect(port, ctx) }
@@ -1001,32 +1108,23 @@ if OpenSSL::OPENSSL_VERSION_NUMBER > 0x10001000 &&
end
def test_npn_selected_protocol_too_long
+ pend "TLS 1.2 is not supported" unless tls12_supported?
+ pend "NPN is not supported" unless \
+ OpenSSL::SSL::SSLContext.method_defined?(:npn_select_cb)
+
ctx_proc = Proc.new { |ctx| ctx.npn_protocols = ["http/1.1"] }
- start_server_version(:SSLv23, ctx_proc) { |server, port|
+ start_server_version(:TLSv1_2, ctx_proc) { |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.npn_select_cb = -> (protocols) { "a" * 256 }
assert_handshake_error { server_connect(port, ctx) }
}
end
-end
-
- def test_invalid_shutdown_by_gc
- assert_nothing_raised {
- start_server { |server, port|
- 10.times {
- sock = TCPSocket.new("127.0.0.1", port)
- ssl = OpenSSL::SSL::SSLSocket.new(sock)
- GC.start
- ssl.connect
- sock.close
- }
- }
- }
- end
-
def test_close_after_socket_close
- start_server { |server, port|
+ server_proc = proc { |ctx, ssl|
+ # Do nothing
+ }
+ start_server(server_proc: server_proc) { |port|
sock = TCPSocket.new("127.0.0.1", port)
ssl = OpenSSL::SSL::SSLSocket.new(sock)
ssl.sync_close = true
@@ -1047,84 +1145,90 @@ end
}
end
- def test_close_and_socket_close_while_connecting
- # test it doesn't cause a segmentation fault
- ctx = OpenSSL::SSL::SSLContext.new
- ctx.ciphers = "aNULL"
- ctx.tmp_dh_callback = proc { OpenSSL::TestUtils::TEST_KEY_DH1024 }
- ctx.security_level = 0
-
- sock1, sock2 = socketpair
- ssl1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx)
- ssl2 = OpenSSL::SSL::SSLSocket.new(sock2, ctx)
+ def test_get_ephemeral_key
+ # OpenSSL >= 1.0.2
+ unless OpenSSL::SSL::SSLSocket.method_defined?(:tmp_key)
+ pend "SSL_get_server_tmp_key() is not supported"
+ end
- t = Thread.new { ssl1.connect }
- ssl2.accept
+ if tls12_supported?
+ # kRSA
+ ctx_proc1 = proc { |ctx|
+ ctx.ssl_version = :TLSv1_2
+ ctx.ciphers = "kRSA"
+ }
+ start_server(ctx_proc: ctx_proc1) do |port|
+ ctx = OpenSSL::SSL::SSLContext.new
+ ctx.ssl_version = :TLSv1_2
+ ctx.ciphers = "kRSA"
+ server_connect(port, ctx) { |ssl| assert_nil ssl.tmp_key }
+ end
+ end
- ssl1.close
- sock1.close
- t.value rescue nil
- ensure
- ssl1.close if ssl1
- ssl2.close if ssl2
- sock1.close if sock1
- sock2.close if sock2
- end
+ if defined?(OpenSSL::PKey::DH) && tls12_supported?
+ # DHE
+ # TODO: How to test this with TLS 1.3?
+ ctx_proc2 = proc { |ctx|
+ ctx.ssl_version = :TLSv1_2
+ ctx.ciphers = "EDH"
+ }
+ start_server(ctx_proc: ctx_proc2) do |port|
+ ctx = OpenSSL::SSL::SSLContext.new
+ ctx.ssl_version = :TLSv1_2
+ ctx.ciphers = "EDH"
+ server_connect(port, ctx) { |ssl|
+ assert_instance_of OpenSSL::PKey::DH, ssl.tmp_key
+ }
+ end
+ end
- def test_get_ephemeral_key
- return unless OpenSSL::SSL::SSLSocket.method_defined?(:tmp_key)
- pkey = OpenSSL::PKey
- ciphers = {
- 'ECDHE-RSA-AES128-SHA' => (pkey::EC if defined?(pkey::EC)),
- 'DHE-RSA-AES128-SHA' => (pkey::DH if defined?(pkey::DH)),
- 'AES128-SHA' => nil
- }
- conf_proc = Proc.new { |ctx| ctx.ciphers = 'ALL' }
- start_server(ctx_proc: conf_proc) do |server, port|
- ciphers.each do |cipher, ephemeral|
+ if defined?(OpenSSL::PKey::EC)
+ # ECDHE
+ ctx_proc3 = proc { |ctx|
+ ctx.ciphers = "DEFAULT:!kRSA:!kEDH"
+ ctx.ecdh_curves = "P-256"
+ }
+ start_server(ctx_proc: ctx_proc3) do |port|
ctx = OpenSSL::SSL::SSLContext.new
- begin
- ctx.ciphers = cipher
- rescue OpenSSL::SSL::SSLError => e
- next if /no cipher match/ =~ e.message
- raise
- end
- server_connect(port, ctx) do |ssl|
- if ephemeral
- assert_instance_of(ephemeral, ssl.tmp_key)
- else
- assert_nil(ssl.tmp_key)
- end
- end
+ ctx.ciphers = "DEFAULT:!kRSA:!kEDH"
+ server_connect(port, ctx) { |ssl|
+ assert_instance_of OpenSSL::PKey::EC, ssl.tmp_key
+ }
end
end
end
def test_dh_callback
+ pend "TLS 1.2 is not supported" unless tls12_supported?
+
called = false
ctx_proc = -> ctx {
+ ctx.ssl_version = :TLSv1_2
ctx.ciphers = "DH:!NULL"
ctx.tmp_dh_callback = ->(*args) {
called = true
- OpenSSL::TestUtils::TEST_KEY_DH1024
+ Fixtures.pkey_dh("dh1024")
}
}
- start_server(ctx_proc: ctx_proc) do |server, port|
+ start_server(ctx_proc: ctx_proc) do |port|
server_connect(port) { |ssl|
assert called, "dh callback should be called"
if ssl.respond_to?(:tmp_key)
- assert_equal OpenSSL::TestUtils::TEST_KEY_DH1024.to_der, ssl.tmp_key.to_der
+ assert_equal Fixtures.pkey_dh("dh1024").to_der, ssl.tmp_key.to_der
end
}
end
end
def test_connect_works_when_setting_dh_callback_to_nil
+ pend "TLS 1.2 is not supported" unless tls12_supported?
+
ctx_proc = -> ctx {
+ ctx.ssl_version = :TLSv1_2
ctx.ciphers = "DH:!NULL" # use DH
ctx.tmp_dh_callback = nil
}
- start_server(ctx_proc: ctx_proc) do |server, port|
+ start_server(ctx_proc: ctx_proc) do |port|
EnvUtil.suppress_warning { # uses default callback
assert_nothing_raised {
server_connect(port) { }
@@ -1133,73 +1237,53 @@ end
end
end
- def test_ecdh_callback
- return unless OpenSSL::SSL::SSLContext.instance_methods.include?(:tmp_ecdh_callback)
+ def test_tmp_ecdh_callback
+ pend "EC is disabled" unless defined?(OpenSSL::PKey::EC)
+ pend "tmp_ecdh_callback is not supported" unless \
+ OpenSSL::SSL::SSLContext.method_defined?(:tmp_ecdh_callback)
+
EnvUtil.suppress_warning do # tmp_ecdh_callback is deprecated (2016-05)
- begin
- called = false
- ctx2 = OpenSSL::SSL::SSLContext.new
- ctx2.ciphers = "ECDH"
- # OpenSSL 1.1.0 doesn't have tmp_ecdh_callback so this shouldn't be required
- ctx2.security_level = 0
- ctx2.tmp_ecdh_callback = ->(*args) {
+ called = false
+ ctx_proc = -> ctx {
+ ctx.ciphers = "DEFAULT:!kRSA:!kEDH"
+ ctx.tmp_ecdh_callback = -> (*args) {
called = true
OpenSSL::PKey::EC.new "prime256v1"
}
-
- sock1, sock2 = socketpair
-
- s2 = OpenSSL::SSL::SSLSocket.new(sock2, ctx2)
- ctx1 = OpenSSL::SSL::SSLContext.new
- ctx1.ciphers = "ECDH"
- ctx1.security_level = 0
-
- s1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx1)
- th = Thread.new do
- s1.connect
- end
-
- s2.accept
- assert called, 'ecdh callback should be called'
- rescue OpenSSL::SSL::SSLError => e
- if e.message =~ /no cipher match/
- pend "ECDH cipher not supported."
- else
- raise e
- end
- ensure
- th.join if th
- s1.close if s1
- s2.close if s2
- sock1.close if sock1
- sock2.close if sock2
+ }
+ start_server(ctx_proc: ctx_proc) do |port|
+ server_connect(port) { |s|
+ assert called, "tmp_ecdh_callback should be called"
+ }
end
end
end
def test_ecdh_curves
+ pend "EC is disabled" unless defined?(OpenSSL::PKey::EC)
+
ctx_proc = -> ctx {
- begin
- ctx.ciphers = "ECDH:!NULL"
- rescue OpenSSL::SSL::SSLError
- pend "ECDH is not enabled in this OpenSSL" if $!.message =~ /no cipher match/
- raise
- end
+ # Enable both ECDHE (~ TLS 1.2) cipher suites and TLS 1.3
+ ctx.ciphers = "DEFAULT:!kRSA:!kEDH"
ctx.ecdh_curves = "P-384:P-521"
}
- start_server(ctx_proc: ctx_proc, ignore_listener_error: true) do |server, port|
+ start_server(ctx_proc: ctx_proc, ignore_listener_error: true) do |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.ecdh_curves = "P-256:P-384" # disable P-521 for OpenSSL >= 1.0.2
server_connect(port, ctx) { |ssl|
- assert ssl.cipher[0].start_with?("ECDH"), "ECDH should be used"
- if ssl.respond_to?(:tmp_key)
+ cs = ssl.cipher[0]
+ if /\ATLS/ =~ cs # Is TLS 1.3 is used?
assert_equal "secp384r1", ssl.tmp_key.group.curve_name
+ else
+ assert_match (/\AECDH/), cs
+ if ssl.respond_to?(:tmp_key)
+ assert_equal "secp384r1", ssl.tmp_key.group.curve_name
+ end
end
}
- if OpenSSL::OPENSSL_VERSION_NUMBER >= 0x10002000 &&
- !OpenSSL::OPENSSL_VERSION.include?("LibreSSL")
+ if openssl?(1, 0, 2) || libressl?(2, 5, 1)
ctx = OpenSSL::SSL::SSLContext.new
ctx.ecdh_curves = "P-256"
@@ -1226,10 +1310,10 @@ end
return
end
assert_equal(1, ctx.security_level)
- # assert_raise(OpenSSL::SSL::SSLError) { ctx.key = OpenSSL::TestUtils::TEST_KEY_DSA512 }
- # ctx.key = OpenSSL::TestUtils::TEST_KEY_RSA1024
+ # assert_raise(OpenSSL::SSL::SSLError) { ctx.key = Fixtures.pkey("dsa512") }
+ # ctx.key = Fixtures.pkey("rsa1024")
# ctx.security_level = 2
- # assert_raise(OpenSSL::SSL::SSLError) { ctx.key = OpenSSL::TestUtils::TEST_KEY_RSA1024 }
+ # assert_raise(OpenSSL::SSL::SSLError) { ctx.key = Fixtures.pkey("rsa1024") }
pend "FIXME: SSLContext#key= currently does not raise because SSL_CTX_use_certificate() is delayed"
end
@@ -1248,7 +1332,7 @@ end
def test_freeze_calls_setup
bug = "[ruby/openssl#85]"
- start_server(ignore_listener_error: true) { |server, port|
+ start_server(ignore_listener_error: true) { |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
ctx.freeze
@@ -1274,7 +1358,7 @@ end
)
end
- def server_connect(port, ctx=nil)
+ def server_connect(port, ctx = nil)
sock = TCPSocket.new("127.0.0.1", port)
ssl = ctx ? OpenSSL::SSL::SSLSocket.new(sock, ctx) : OpenSSL::SSL::SSLSocket.new(sock)
ssl.sync_close = true
diff --git a/test/openssl/test_ssl_session.rb b/test/openssl/test_ssl_session.rb
index 7a99dca5ed..199f722e8d 100644
--- a/test/openssl/test_ssl_session.rb
+++ b/test/openssl/test_ssl_session.rb
@@ -1,57 +1,15 @@
# frozen_string_literal: false
require_relative "utils"
-if defined?(OpenSSL::TestUtils)
+if defined?(OpenSSL)
class OpenSSL::TestSSLSession < OpenSSL::SSLTestCase
- def test_session_equals
- session = OpenSSL::SSL::Session.new <<-SESSION
------BEGIN SSL SESSION PARAMETERS-----
-MIIDFgIBAQICAwEEAgA5BCCY3pW6iTkPoD5SENuztz/gZjhvey6XnHbsxd22k0Ol
-dgQw8uaN3hCRnlhoIKPWInCFzrp/tQsDRFs9jDjc9pwpy/oKHmJdQQMQA1g8FYnO
-gpdVoQYCBE52ikKiBAICASyjggKOMIICijCCAXKgAwIBAgIBAjANBgkqhkiG9w0B
-AQUFADA9MRMwEQYKCZImiZPyLGQBGRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVi
-eS1sYW5nMQswCQYDVQQDDAJDQTAeFw0xMTA5MTkwMDE4MTBaFw0xMTA5MTkwMDQ4
-MTBaMEQxEzARBgoJkiaJk/IsZAEZFgNvcmcxGTAXBgoJkiaJk/IsZAEZFglydWJ5
-LWxhbmcxEjAQBgNVBAMMCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
-gYkCgYEAy8LEsNRApz7U/j5DoB4XBgO9Z8Atv5y/OVQRp0ag8Tqo1YewsWijxEWB
-7JOATwpBN267U4T1nPZIxxEEO7n/WNa2ws9JWsjah8ssEBFSxZqdXKSLf0N4Hi7/
-GQ/aYoaMCiQ8jA4jegK2FJmXM71uPe+jFN/peeBOpRfyXxRFOYcCAwEAAaMSMBAw
-DgYDVR0PAQH/BAQDAgWgMA0GCSqGSIb3DQEBBQUAA4IBAQARC7GP7InX1t7VEXz2
-I8RI57S0/HSJL4fDIYP3zFpitHX1PZeo+7XuzMilvPjjBo/ky9Jzo8TYiY+N+JEz
-mY/A/zPA4ZsJ7KYj6/FEdIc/vRlS0CvsbClbNjw1jl/PoB2FLr2b3uuBcZEsyZeP
-yq154ijq37Ajf8K5Mi5FgshoP41BPtRPj+VVf61rv1IcEnNWdDCS6DR4XsaNC+zt
-G6AqCqkytIXWRuDw6n6vYLF3A/tn2sldLo7/scY0PMDNbo63O/LTxkDHmPhSkD68
-8m9SsMeTR+RCiDEZWFPVcAH/8mDfi+5k8uN3qS+gOU/PPrmHGgl5ykiSFgqs4v61
-tddwpBAEDjcwMzA5NTYzMTU1MzAwpQMCARM=
------END SSL SESSION PARAMETERS-----
- SESSION
-
- start_server(ignore_listener_error: true) { |_, port|
- ctx = OpenSSL::SSL::SSLContext.new
- ctx.session_cache_mode = OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT
- ctx.session_id_context = self.object_id.to_s
-
- sock = TCPSocket.new '127.0.0.1', port
- begin
- ssl = OpenSSL::SSL::SSLSocket.new sock, ctx
- ssl.session = session
-
- assert_equal session, ssl.session
- ensure
- sock.close
- end
- }
- end
-
def test_session
- Timeout.timeout(5) do
- start_server do |server, port|
- sock = TCPSocket.new("127.0.0.1", port)
- ctx = OpenSSL::SSL::SSLContext.new
- ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
- ssl.sync_close = true
- ssl.connect
+ pend "TLS 1.2 is not supported" unless tls12_supported?
+
+ ctx_proc = proc { |ctx| ctx.ssl_version = :TLSv1_2 }
+ start_server(ctx_proc: ctx_proc) do |port|
+ server_connect_with_session(port, nil, nil) { |ssl|
session = ssl.session
assert(session == OpenSSL::SSL::Session.new(session.to_pem))
assert(session == OpenSSL::SSL::Session.new(ssl))
@@ -68,8 +26,7 @@ tddwpBAEDjcwMzA5NTYzMTU1MzAwpQMCARM=
pem.gsub!(/-----(BEGIN|END) SSL SESSION PARAMETERS-----/, '').gsub!(/[\r\n]+/m, '')
assert_equal(session.to_der, pem.unpack('m*')[0])
assert_not_nil(session.to_text)
- ssl.close
- end
+ }
end
end
@@ -150,222 +107,245 @@ __EOS__
def test_session_exts_read
assert(OpenSSL::SSL::Session.new(DUMMY_SESSION))
- end if OpenSSL::OPENSSL_VERSION_NUMBER >= 0x009080bf
-
- def test_client_session
- last_session = nil
- start_server do |server, port|
- 2.times do
- sock = TCPSocket.new("127.0.0.1", port)
- ctx = OpenSSL::SSL::SSLContext.new
- ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
- ssl.sync_close = true
- ssl.session = last_session if last_session
- ssl.connect
+ end
- session = ssl.session
- if last_session
- assert(ssl.session_reused?)
- assert_equal(session.id, last_session.id)
- assert_equal(session.to_pem, last_session.to_pem)
- assert_equal(session.to_der, last_session.to_der)
- # Older version of OpenSSL may not be consistent. Look up which versions later.
- assert_equal(session.to_text, last_session.to_text)
- else
- assert(!ssl.session_reused?)
- end
- last_session = session
+ def test_resumption
+ non_resumable = nil
+ start_server { |port|
+ server_connect_with_session(port, nil, nil) { |ssl|
+ non_resumable = ssl.session
+ }
+ }
- str = "x" * 100 + "\n"
- ssl.puts(str)
- assert_equal(str, ssl.gets)
+ ctx_proc = proc { |ctx|
+ ctx.options &= ~OpenSSL::SSL::OP_NO_TICKET
+ # Disable server-side session cache which is enabled by default
+ ctx.session_cache_mode = OpenSSL::SSL::SSLContext::SESSION_CACHE_OFF
+ }
+ start_server(ctx_proc: ctx_proc) do |port|
+ sess1 = server_connect_with_session(port, nil, nil) { |ssl|
+ ssl.puts("abc"); assert_equal "abc\n", ssl.gets
+ assert_equal false, ssl.session_reused?
+ ssl.session
+ }
- ssl.close
- end
+ server_connect_with_session(port, nil, non_resumable) { |ssl|
+ ssl.puts("abc"); assert_equal "abc\n", ssl.gets
+ assert_equal false, ssl.session_reused?
+ }
+
+ server_connect_with_session(port, nil, sess1) { |ssl|
+ ssl.puts("abc"); assert_equal "abc\n", ssl.gets
+ assert_equal true, ssl.session_reused?
+ }
end
end
- def test_server_session
- connections = 0
- saved_session = nil
+ def test_server_session_cache
+ pend "TLS 1.2 is not supported" unless tls12_supported?
- ctx_proc = Proc.new do |ctx, ssl|
-# add test for session callbacks here
+ ctx_proc = Proc.new do |ctx|
+ ctx.ssl_version = :TLSv1_2
+ ctx.options |= OpenSSL::SSL::OP_NO_TICKET
end
+ connections = nil
+ saved_session = nil
server_proc = Proc.new do |ctx, ssl|
- session = ssl.session
stats = ctx.session_cache_stats
case connections
when 0
- assert_equal(stats[:cache_num], 1)
- assert_equal(stats[:cache_hits], 0)
- assert_equal(stats[:cache_misses], 0)
- assert(!ssl.session_reused?)
+ assert_equal false, ssl.session_reused?
+ assert_equal 1, stats[:cache_num]
+ assert_equal 0, stats[:cache_hits]
+ assert_equal 0, stats[:cache_misses]
when 1
- assert_equal(stats[:cache_num], 1)
- assert_equal(stats[:cache_hits], 1)
- assert_equal(stats[:cache_misses], 0)
- assert(ssl.session_reused?)
- ctx.session_remove(session)
- saved_session = session.to_der
+ assert_equal true, ssl.session_reused?
+ assert_equal 1, stats[:cache_num]
+ assert_equal 1, stats[:cache_hits]
+ assert_equal 0, stats[:cache_misses]
+
+ saved_session = ssl.session
+ assert_equal true, ctx.session_remove(ssl.session)
when 2
- assert_equal(stats[:cache_num], 1)
- assert_equal(stats[:cache_hits], 1)
- assert_equal(stats[:cache_misses], 1)
- assert(!ssl.session_reused?)
- ctx.session_add(OpenSSL::SSL::Session.new(saved_session))
+ assert_equal false, ssl.session_reused?
+ assert_equal 1, stats[:cache_num]
+ assert_equal 1, stats[:cache_hits]
+ assert_equal 1, stats[:cache_misses]
+
+ assert_equal true, ctx.session_add(saved_session.dup)
when 3
- assert_equal(stats[:cache_num], 2)
- assert_equal(stats[:cache_hits], 2)
- assert_equal(stats[:cache_misses], 1)
- assert(ssl.session_reused?)
+ assert_equal true, ssl.session_reused?
+ assert_equal 2, stats[:cache_num]
+ assert_equal 2, stats[:cache_hits]
+ assert_equal 1, stats[:cache_misses]
+
ctx.flush_sessions(Time.now + 10000)
when 4
- assert_equal(stats[:cache_num], 1)
- assert_equal(stats[:cache_hits], 2)
- assert_equal(stats[:cache_misses], 2)
- assert(!ssl.session_reused?)
- ctx.session_add(OpenSSL::SSL::Session.new(saved_session))
+ assert_equal false, ssl.session_reused?
+ assert_equal 1, stats[:cache_num]
+ assert_equal 2, stats[:cache_hits]
+ assert_equal 2, stats[:cache_misses]
+
+ assert_equal true, ctx.session_add(saved_session.dup)
end
- connections += 1
readwrite_loop(ctx, ssl)
end
- first_session = nil
- start_server(ctx_proc: ctx_proc, server_proc: server_proc) do |server, port|
+ start_server(ctx_proc: ctx_proc, server_proc: server_proc) do |port|
+ first_session = nil
10.times do |i|
- sock = TCPSocket.new("127.0.0.1", port)
- ctx = OpenSSL::SSL::SSLContext.new
- # disable RFC4507 support
- ctx.options = OpenSSL::SSL::OP_NO_TICKET
- ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
- ssl.sync_close = true
- ssl.session = first_session if first_session
- ssl.connect
-
- session = ssl.session
- if first_session
- case i
- when 1; assert(ssl.session_reused?)
- when 2; assert(!ssl.session_reused?)
- when 3; assert(ssl.session_reused?)
- when 4; assert(!ssl.session_reused?)
- when 5..10; assert(ssl.session_reused?)
+ connections = i
+ server_connect_with_session(port, nil, first_session) { |ssl|
+ ssl.puts("abc"); assert_equal "abc\n", ssl.gets
+ first_session ||= ssl.session
+
+ case connections
+ when 0;
+ when 1; assert_equal true, ssl.session_reused?
+ when 2; assert_equal false, ssl.session_reused?
+ when 3; assert_equal true, ssl.session_reused?
+ when 4; assert_equal false, ssl.session_reused?
+ when 5..9; assert_equal true, ssl.session_reused?
end
- end
- first_session ||= session
-
- str = "x" * 100 + "\n"
- ssl.puts(str)
- assert_equal(str, ssl.gets)
-
- ssl.close
+ }
end
end
end
def test_ctx_client_session_cb
- called = {}
- ctx = OpenSSL::SSL::SSLContext.new
- ctx.session_cache_mode = OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT
-
- ctx.session_new_cb = lambda { |ary|
- sock, sess = ary
- called[:new] = [sock, sess]
- }
+ pend "TLS 1.2 is not supported" unless tls12_supported?
- ctx.session_remove_cb = lambda { |ary|
- ctx, sess = ary
- called[:remove] = [ctx, sess]
- # any resulting value is OK (ignored)
- }
+ ctx_proc = proc { |ctx| ctx.ssl_version = :TLSv1_2 }
+ start_server(ctx_proc: ctx_proc) do |port|
+ called = {}
+ ctx = OpenSSL::SSL::SSLContext.new
+ ctx.session_cache_mode = OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT
+ ctx.session_new_cb = lambda { |ary|
+ sock, sess = ary
+ called[:new] = [sock, sess]
+ }
+ ctx.session_remove_cb = lambda { |ary|
+ ctx, sess = ary
+ called[:remove] = [ctx, sess]
+ # any resulting value is OK (ignored)
+ }
- start_server do |server, port|
- sock = TCPSocket.new("127.0.0.1", port)
- begin
- ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
- ssl.sync_close = true
- ssl.connect
+ server_connect_with_session(port, ctx, nil) { |ssl|
assert_equal(1, ctx.session_cache_stats[:cache_num])
assert_equal(1, ctx.session_cache_stats[:connect_good])
assert_equal([ssl, ssl.session], called[:new])
assert(ctx.session_remove(ssl.session))
assert(!ctx.session_remove(ssl.session))
assert_equal([ctx, ssl.session], called[:remove])
- ssl.close
- ensure
- sock.close if !sock.closed?
- end
+ }
end
end
def test_ctx_server_session_cb
- called = {}
+ pend "TLS 1.2 is not supported" unless tls12_supported?
- ctx_proc = Proc.new { |ctx, ssl|
- ctx.session_cache_mode = OpenSSL::SSL::SSLContext::SESSION_CACHE_SERVER
- ctx.options = OpenSSL::SSL::OP_NO_TICKET
- last_server_session = nil
+ connections = nil
+ called = {}
+ sctx = nil
+ ctx_proc = Proc.new { |ctx|
+ sctx = ctx
+ ctx.ssl_version = :TLSv1_2
+ ctx.options |= OpenSSL::SSL::OP_NO_TICKET
# get_cb is called whenever a client proposed to resume a session but
# the session could not be found in the internal session cache.
+ last_server_session = nil
ctx.session_get_cb = lambda { |ary|
- sess, data = ary
- if last_server_session
- called[:get2] = [sess, data]
- last_server_session
+ _sess, data = ary
+ called[:get] = data
+
+ if connections == 2
+ last_server_session.dup
else
- called[:get1] = [sess, data]
- last_server_session = sess
nil
end
}
ctx.session_new_cb = lambda { |ary|
- sock, sess = ary
- called[:new] = [sock, sess]
- # SSL server doesn't cache sessions so get_cb is called next time.
- ctx.session_remove(sess)
+ _sock, sess = ary
+ called[:new] = sess
+ last_server_session = sess
}
ctx.session_remove_cb = lambda { |ary|
- ctx, sess = ary
- called[:remove] = [ctx, sess]
+ _ctx, sess = ary
+ called[:remove] = sess
}
}
-
- server_proc = Proc.new { |c, ssl|
- ssl.session
- c.session_cache_stats
- readwrite_loop(c, ssl)
- }
- start_server(ctx_proc: ctx_proc, server_proc: server_proc) do |server, port|
- last_client_session = nil
- 3.times do
- sock = TCPSocket.new("127.0.0.1", port)
- begin
- ssl = OpenSSL::SSL::SSLSocket.new(sock, OpenSSL::SSL::SSLContext.new())
- ssl.sync_close = true
- ssl.session = last_client_session if last_client_session
- ssl.connect
- last_client_session = ssl.session
- ssl.close
- Timeout.timeout(5) do
- Thread.pass until called.key?(:new)
- assert(called.delete(:new))
- Thread.pass until called.key?(:remove)
- assert(called.delete(:remove))
- end
- ensure
- sock.close if !sock.closed?
+ start_server(ctx_proc: ctx_proc) do |port|
+ connections = 0
+ sess0 = server_connect_with_session(port, nil, nil) { |ssl|
+ ssl.puts("abc"); assert_equal "abc\n", ssl.gets
+ assert_equal false, ssl.session_reused?
+ ssl.session
+ }
+ assert_nil called[:get]
+ assert_not_nil called[:new]
+ assert_equal sess0.id, called[:new].id
+ assert_nil called[:remove]
+ called.clear
+
+ # Internal cache hit
+ connections = 1
+ server_connect_with_session(port, nil, sess0.dup) { |ssl|
+ ssl.puts("abc"); assert_equal "abc\n", ssl.gets
+ assert_equal true, ssl.session_reused?
+ ssl.session
+ }
+ assert_nil called[:get]
+ assert_nil called[:new]
+ assert_nil called[:remove]
+ called.clear
+
+ sctx.flush_sessions(Time.now + 10000)
+ assert_not_nil called[:remove]
+ assert_equal sess0.id, called[:remove].id
+ called.clear
+
+ # External cache hit
+ connections = 2
+ sess2 = server_connect_with_session(port, nil, sess0.dup) { |ssl|
+ ssl.puts("abc"); assert_equal "abc\n", ssl.gets
+ if !ssl.session_reused? && openssl?(1, 1, 0) && !openssl?(1, 1, 0, 7)
+ # OpenSSL >= 1.1.0, < 1.1.0g
+ pend "External session cache is not working; " \
+ "see https://github.com/openssl/openssl/pull/4014"
end
- end
+ assert_equal true, ssl.session_reused?
+ ssl.session
+ }
+ assert_equal sess0.id, sess2.id
+ assert_equal sess0.id, called[:get]
+ assert_nil called[:new]
+ assert_nil called[:remove]
+ called.clear
+
+ sctx.flush_sessions(Time.now + 10000)
+ assert_not_nil called[:remove]
+ assert_equal sess0.id, called[:remove].id
+ called.clear
+
+ # Cache miss
+ connections = 3
+ sess3 = server_connect_with_session(port, nil, sess0.dup) { |ssl|
+ ssl.puts("abc"); assert_equal "abc\n", ssl.gets
+ assert_equal false, ssl.session_reused?
+ ssl.session
+ }
+ assert_not_equal sess0.id, sess3.id
+ assert_equal sess0.id, called[:get]
+ assert_not_nil called[:new]
+ assert_equal sess3.id, called[:new].id
+ assert_nil called[:remove]
end
- assert(called[:get1])
- assert(called[:get2])
end
def test_dup
@@ -373,6 +353,21 @@ __EOS__
sess_dup = sess_orig.dup
assert_equal(sess_orig.to_der, sess_dup.to_der)
end
+
+ private
+
+ def server_connect_with_session(port, ctx = nil, sess = nil)
+ sock = TCPSocket.new("127.0.0.1", port)
+ ctx ||= OpenSSL::SSL::SSLContext.new
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
+ ssl.session = sess if sess
+ ssl.sync_close = true
+ ssl.connect
+ yield ssl if block_given?
+ ensure
+ ssl&.close
+ sock&.close
+ end
end
end
diff --git a/test/openssl/test_x509attr.rb b/test/openssl/test_x509attr.rb
index d7473f1a29..108162f407 100644
--- a/test/openssl/test_x509attr.rb
+++ b/test/openssl/test_x509attr.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
require_relative "utils"
-if defined?(OpenSSL::TestUtils)
+if defined?(OpenSSL)
class OpenSSL::TestX509Attribute < OpenSSL::TestCase
def test_new
diff --git a/test/openssl/test_x509cert.rb b/test/openssl/test_x509cert.rb
index 5b2e712d2a..289994d17b 100644
--- a/test/openssl/test_x509cert.rb
+++ b/test/openssl/test_x509cert.rb
@@ -1,23 +1,19 @@
# frozen_string_literal: false
require_relative "utils"
-if defined?(OpenSSL::TestUtils)
+if defined?(OpenSSL)
class OpenSSL::TestX509Certificate < OpenSSL::TestCase
def setup
super
- @rsa1024 = OpenSSL::TestUtils::TEST_KEY_RSA1024
- @rsa2048 = OpenSSL::TestUtils::TEST_KEY_RSA2048
- @dsa256 = OpenSSL::TestUtils::TEST_KEY_DSA256
- @dsa512 = OpenSSL::TestUtils::TEST_KEY_DSA512
+ @rsa1024 = Fixtures.pkey("rsa1024")
+ @rsa2048 = Fixtures.pkey("rsa2048")
+ @dsa256 = Fixtures.pkey("dsa256")
+ @dsa512 = Fixtures.pkey("dsa512")
@ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA")
@ee1 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE1")
end
- def issue_cert(*args)
- OpenSSL::TestUtils.issue_cert(*args)
- end
-
def test_serial
[1, 2**32, 2**100].each{|s|
cert = issue_cert(@ca, @rsa2048, s, [], nil, nil)
@@ -34,13 +30,10 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase
["authorityKeyIdentifier","keyid:always",false],
]
- sha1 = OpenSSL::Digest::SHA1.new
- dsa_digest = OpenSSL::TestUtils::DSA_SIGNATURE_DIGEST.new
-
[
- [@rsa1024, sha1], [@rsa2048, sha1], [@dsa256, dsa_digest], [@dsa512, dsa_digest]
- ].each{|pk, digest|
- cert = issue_cert(@ca, pk, 1, exts, nil, nil, digest: digest)
+ @rsa1024, @rsa2048, @dsa256, @dsa512,
+ ].each{|pk|
+ cert = issue_cert(@ca, pk, 1, exts, nil, nil)
assert_equal(cert.extensions.sort_by(&:to_s)[2].value,
OpenSSL::TestUtils.get_subject_key_id(cert))
cert = OpenSSL::X509::Certificate.new(cert.to_der)
@@ -152,26 +145,15 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase
}
end
- def test_dsig_algorithm_mismatch
- assert_raise(OpenSSL::X509::CertificateError) do
- issue_cert(@ca, @rsa2048, 1, [], nil, nil, digest: OpenSSL::Digest::DSS1.new)
- end if OpenSSL::OPENSSL_VERSION_NUMBER < 0x10001000 # [ruby-core:42949]
- end
-
def test_dsa_with_sha2
- begin
- cert = issue_cert(@ca, @dsa256, 1, [], nil, nil, digest: "sha256")
- assert_equal("dsa_with_SHA256", cert.signature_algorithm)
- rescue OpenSSL::X509::CertificateError
- # dsa_with_sha2 not supported. skip following test.
- return
- end
+ cert = issue_cert(@ca, @dsa256, 1, [], nil, nil, digest: "sha256")
+ assert_equal("dsa_with_SHA256", cert.signature_algorithm)
# TODO: need more tests for dsa + sha2
# SHA1 is allowed from OpenSSL 1.0.0 (0.9.8 requires DSS1)
cert = issue_cert(@ca, @dsa256, 1, [], nil, nil, digest: "sha1")
assert_equal("dsaWithSHA1", cert.signature_algorithm)
- end if defined?(OpenSSL::Digest::SHA256)
+ end
def test_check_private_key
cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil)
diff --git a/test/openssl/test_x509crl.rb b/test/openssl/test_x509crl.rb
index 44dfffc952..1914a651cf 100644
--- a/test/openssl/test_x509crl.rb
+++ b/test/openssl/test_x509crl.rb
@@ -1,28 +1,20 @@
# frozen_string_literal: false
require_relative "utils"
-if defined?(OpenSSL::TestUtils)
+if defined?(OpenSSL)
class OpenSSL::TestX509CRL < OpenSSL::TestCase
def setup
super
- @rsa1024 = OpenSSL::TestUtils::TEST_KEY_RSA1024
- @rsa2048 = OpenSSL::TestUtils::TEST_KEY_RSA2048
- @dsa256 = OpenSSL::TestUtils::TEST_KEY_DSA256
- @dsa512 = OpenSSL::TestUtils::TEST_KEY_DSA512
+ @rsa1024 = Fixtures.pkey("rsa1024")
+ @rsa2048 = Fixtures.pkey("rsa2048")
+ @dsa256 = Fixtures.pkey("dsa256")
+ @dsa512 = Fixtures.pkey("dsa512")
@ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA")
@ee1 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE1")
@ee2 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE2")
end
- def issue_crl(*args)
- OpenSSL::TestUtils.issue_crl(*args)
- end
-
- def issue_cert(*args)
- OpenSSL::TestUtils.issue_cert(*args)
- end
-
def test_basic
now = Time.at(Time.now.to_i)
@@ -196,7 +188,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase
cert = issue_cert(@ca, @dsa512, 1, [], nil, nil)
crl = issue_crl([], 1, Time.now, Time.now+1600, [],
- cert, @dsa512, OpenSSL::TestUtils::DSA_SIGNATURE_DIGEST.new)
+ cert, @dsa512, OpenSSL::Digest::SHA1.new)
assert_equal(false, crl_error_returns_false { crl.verify(@rsa1024) })
assert_equal(false, crl_error_returns_false { crl.verify(@rsa2048) })
assert_equal(false, crl.verify(@dsa256))
diff --git a/test/openssl/test_x509ext.rb b/test/openssl/test_x509ext.rb
index 58f03168bc..f384a25e8c 100644
--- a/test/openssl/test_x509ext.rb
+++ b/test/openssl/test_x509ext.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
require_relative 'utils'
-if defined?(OpenSSL::TestUtils)
+if defined?(OpenSSL)
class OpenSSL::TestX509Extension < OpenSSL::TestCase
def setup
diff --git a/test/openssl/test_x509name.rb b/test/openssl/test_x509name.rb
index 60e8ddb8ac..2d92e645be 100644
--- a/test/openssl/test_x509name.rb
+++ b/test/openssl/test_x509name.rb
@@ -1,8 +1,8 @@
-# coding: US-ASCII
+# coding: ASCII-8BIT
# frozen_string_literal: false
require_relative 'utils'
-if defined?(OpenSSL::TestUtils)
+if defined?(OpenSSL)
class OpenSSL::TestX509Name < OpenSSL::TestCase
def setup
@@ -148,33 +148,28 @@ class OpenSSL::TestX509Name < OpenSSL::TestCase
end
def test_s_parse
- dn = "/DC=org/DC=ruby-lang/CN=www.ruby-lang.org"
+ dn = "/DC=org/DC=ruby-lang/CN=www.ruby-lang.org/1.2.3.4.5.6=A=BCD"
name = OpenSSL::X509::Name.parse(dn)
assert_equal(dn, name.to_s)
ary = name.to_a
- assert_equal("DC", ary[0][0])
- assert_equal("DC", ary[1][0])
- assert_equal("CN", ary[2][0])
- assert_equal("org", ary[0][1])
- assert_equal("ruby-lang", ary[1][1])
- assert_equal("www.ruby-lang.org", ary[2][1])
- assert_equal(OpenSSL::ASN1::IA5STRING, ary[0][2])
- assert_equal(OpenSSL::ASN1::IA5STRING, ary[1][2])
- assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2])
-
- dn2 = "DC=org, DC=ruby-lang, CN=www.ruby-lang.org"
+ assert_equal [
+ ["DC", "org", OpenSSL::ASN1::IA5STRING],
+ ["DC", "ruby-lang", OpenSSL::ASN1::IA5STRING],
+ ["CN", "www.ruby-lang.org", OpenSSL::ASN1::UTF8STRING],
+ ["1.2.3.4.5.6", "A=BCD", OpenSSL::ASN1::UTF8STRING],
+ ], ary
+
+ dn2 = "DC=org, DC=ruby-lang, CN=www.ruby-lang.org, 1.2.3.4.5.6=A=BCD"
name = OpenSSL::X509::Name.parse(dn2)
- ary = name.to_a
assert_equal(dn, name.to_s)
- assert_equal("org", ary[0][1])
- assert_equal("ruby-lang", ary[1][1])
- assert_equal("www.ruby-lang.org", ary[2][1])
+ assert_equal ary, name.to_a
name = OpenSSL::X509::Name.parse(dn2, @obj_type_tmpl)
ary = name.to_a
assert_equal(OpenSSL::ASN1::IA5STRING, ary[0][2])
assert_equal(OpenSSL::ASN1::IA5STRING, ary[1][2])
assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[2][2])
+ assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[3][2])
end
def test_s_parse_rfc2253
@@ -306,7 +301,6 @@ class OpenSSL::TestX509Name < OpenSSL::TestCase
end
def test_add_entry_street
- return if OpenSSL::OPENSSL_VERSION_NUMBER < 0x009080df # 0.9.8m
# openssl/crypto/objects/obj_mac.h 1.83
dn = [
["DC", "org"],
@@ -323,16 +317,87 @@ class OpenSSL::TestX509Name < OpenSSL::TestCase
assert_equal("Namiki", ary[5][1])
end
+ def test_add_entry_placing
+ der = %w{ 30 2A
+ 31 12
+ 30 10 06 03 55 04 0A 0C 09 72 75 62 79 2D 6C 61 6E 67
+ 31 14
+ 30 08 06 03 55 04 0B 0C 01 61
+ 30 08 06 03 55 04 0B 0C 01 62 }
+ orig = OpenSSL::X509::Name.new([der.join].pack("H*"))
+ assert_equal("OU=b+OU=a,O=ruby-lang", orig.to_s(OpenSSL::X509::Name::RFC2253))
+ # Skip for now; they do not work
+ #
+ # dn = orig.dup
+ # dn.add_entry("CN", "unya", loc: 0, set: 0)
+ # assert_equal("OU=b+OU=a,O=ruby-lang,CN=unya", dn.dup.to_s(OpenSSL::X509::Name::RFC2253))
+ # dn = orig.dup
+ # dn.add_entry("CN", "unya", loc: 0, set: 1)
+ # assert_equal("OU=b+OU=a,O=ruby-lang+CN=unya", dn.dup.to_s(OpenSSL::X509::Name::RFC2253))
+ dn = orig.dup
+ dn.add_entry("CN", "unya", loc: 1, set: -1)
+ assert_equal("OU=b+OU=a,O=ruby-lang+CN=unya", dn.dup.to_s(OpenSSL::X509::Name::RFC2253))
+ # dn = orig.dup
+ # dn.add_entry("CN", "unya", loc: 1, set: 0)
+ # assert_equal("OU=b+OU=a,CN=unya,O=ruby-lang", dn.dup.to_s(OpenSSL::X509::Name::RFC2253))
+ dn = orig.dup
+ dn.add_entry("CN", "unya", loc: 1, set: 1)
+ assert_equal("CN=unya+OU=b+OU=a,O=ruby-lang", dn.dup.to_s(OpenSSL::X509::Name::RFC2253))
+ dn = orig.dup
+ dn.add_entry("CN", "unya", loc: -1, set: -1)
+ assert_equal("CN=unya+OU=b+OU=a,O=ruby-lang", dn.dup.to_s(OpenSSL::X509::Name::RFC2253))
+ dn = orig.dup
+ dn.add_entry("CN", "unya", loc: -1, set: 0)
+ assert_equal("CN=unya,OU=b+OU=a,O=ruby-lang", dn.dup.to_s(OpenSSL::X509::Name::RFC2253))
+ end
+
+ def test_to_s
+ dn = [
+ ["DC", "org"],
+ ["DC", "ruby-lang"],
+ ["CN", "フー, バー"],
+ ]
+ name = OpenSSL::X509::Name.new
+ dn.each { |x| name.add_entry(*x) }
+
+ assert_equal "/DC=org/DC=ruby-lang/" \
+ "CN=\\xE3\\x83\\x95\\xE3\\x83\\xBC, \\xE3\\x83\\x90\\xE3\\x83\\xBC",
+ name.to_s
+ # OpenSSL escapes characters with MSB by default
+ assert_equal \
+ "CN=\\E3\\83\\95\\E3\\83\\BC\\, \\E3\\83\\90\\E3\\83\\BC," \
+ "DC=ruby-lang,DC=org",
+ name.to_s(OpenSSL::X509::Name::RFC2253)
+ assert_equal "DC = org, DC = ruby-lang, " \
+ "CN = \"\\E3\\83\\95\\E3\\83\\BC, \\E3\\83\\90\\E3\\83\\BC\"",
+ name.to_s(OpenSSL::X509::Name::ONELINE)
+ end
+
+ def test_to_utf8
+ dn = [
+ ["DC", "org"],
+ ["DC", "ruby-lang"],
+ ["CN", "フー, バー"],
+ ]
+ name = OpenSSL::X509::Name.new
+ dn.each { |x| name.add_entry(*x) }
+
+ str = name.to_utf8
+ expected = "CN=フー\\, バー,DC=ruby-lang,DC=org".force_encoding("UTF-8")
+ assert_equal expected, str
+ assert_equal Encoding.find("UTF-8"), str.encoding
+ end
+
def test_equals2
- n1 = OpenSSL::X509::Name.parse 'CN=a'
- n2 = OpenSSL::X509::Name.parse 'CN=a'
+ n1 = OpenSSL::X509::Name.parse_rfc2253 'CN=a'
+ n2 = OpenSSL::X509::Name.parse_rfc2253 'CN=a'
assert_equal n1, n2
end
def test_spaceship
- n1 = OpenSSL::X509::Name.parse 'CN=a'
- n2 = OpenSSL::X509::Name.parse 'CN=b'
+ n1 = OpenSSL::X509::Name.parse_rfc2253 'CN=a'
+ n2 = OpenSSL::X509::Name.parse_rfc2253 'CN=b'
assert_equal(-1, n1 <=> n2)
end
diff --git a/test/openssl/test_x509req.rb b/test/openssl/test_x509req.rb
index 585dda1bc6..a21d45da19 100644
--- a/test/openssl/test_x509req.rb
+++ b/test/openssl/test_x509req.rb
@@ -1,15 +1,15 @@
# frozen_string_literal: false
require_relative "utils"
-if defined?(OpenSSL::TestUtils)
+if defined?(OpenSSL)
class OpenSSL::TestX509Request < OpenSSL::TestCase
def setup
super
- @rsa1024 = OpenSSL::TestUtils::TEST_KEY_RSA1024
- @rsa2048 = OpenSSL::TestUtils::TEST_KEY_RSA2048
- @dsa256 = OpenSSL::TestUtils::TEST_KEY_DSA256
- @dsa512 = OpenSSL::TestUtils::TEST_KEY_DSA512
+ @rsa1024 = Fixtures.pkey("rsa1024")
+ @rsa2048 = Fixtures.pkey("rsa2048")
+ @dsa256 = Fixtures.pkey("dsa256")
+ @dsa512 = Fixtures.pkey("dsa512")
@dn = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=GOTOU Yuuzou")
end
@@ -28,7 +28,7 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase
req = OpenSSL::X509::Request.new(req.to_der)
assert_equal(@rsa1024.public_key.to_der, req.public_key.to_der)
- req = issue_csr(0, @dn, @dsa512, OpenSSL::TestUtils::DSA_SIGNATURE_DIGEST.new)
+ req = issue_csr(0, @dn, @dsa512, OpenSSL::Digest::SHA1.new)
assert_equal(@dsa512.public_key.to_der, req.public_key.to_der)
req = OpenSSL::X509::Request.new(req.to_der)
assert_equal(@dsa512.public_key.to_der, req.public_key.to_der)
@@ -122,7 +122,7 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase
end
def test_sign_and_verify_dsa
- req = issue_csr(0, @dn, @dsa512, OpenSSL::TestUtils::DSA_SIGNATURE_DIGEST.new)
+ req = issue_csr(0, @dn, @dsa512, OpenSSL::Digest::SHA1.new)
assert_equal(false, request_error_returns_false { req.verify(@rsa1024) })
assert_equal(false, request_error_returns_false { req.verify(@rsa2048) })
assert_equal(false, req.verify(@dsa256))
@@ -131,18 +131,6 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase
assert_equal(false, req.verify(@dsa512))
end
- def test_sign_and_verify_rsa_dss1
- req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::DSS1.new)
- assert_equal(true, req.verify(@rsa1024))
- assert_equal(false, req.verify(@rsa2048))
- assert_equal(false, request_error_returns_false { req.verify(@dsa256) })
- assert_equal(false, request_error_returns_false { req.verify(@dsa512) })
- req.version = 1
- assert_equal(false, req.verify(@rsa1024))
- rescue OpenSSL::X509::RequestError
- pend
- end if defined?(OpenSSL::Digest::DSS1)
-
def test_sign_and_verify_dsa_md5
assert_raise(OpenSSL::X509::RequestError){
issue_csr(0, @dn, @dsa512, OpenSSL::Digest::MD5.new) }
diff --git a/test/openssl/test_x509store.rb b/test/openssl/test_x509store.rb
index c45233aaec..6412249b93 100644
--- a/test/openssl/test_x509store.rb
+++ b/test/openssl/test_x509store.rb
@@ -1,15 +1,15 @@
# frozen_string_literal: false
require_relative "utils"
-if defined?(OpenSSL::TestUtils)
+if defined?(OpenSSL)
class OpenSSL::TestX509Store < OpenSSL::TestCase
def setup
super
- @rsa1024 = OpenSSL::TestUtils::TEST_KEY_RSA1024
- @rsa2048 = OpenSSL::TestUtils::TEST_KEY_RSA2048
- @dsa256 = OpenSSL::TestUtils::TEST_KEY_DSA256
- @dsa512 = OpenSSL::TestUtils::TEST_KEY_DSA512
+ @rsa1024 = Fixtures.pkey("rsa1024")
+ @rsa2048 = Fixtures.pkey("rsa2048")
+ @dsa256 = Fixtures.pkey("dsa256")
+ @dsa512 = Fixtures.pkey("dsa512")
@ca1 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA1")
@ca2 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA2")
@ee1 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE1")
@@ -26,14 +26,6 @@ class OpenSSL::TestX509Store < OpenSSL::TestCase
ctx.verify
end
- def issue_cert(*args)
- OpenSSL::TestUtils.issue_cert(*args)
- end
-
- def issue_crl(*args)
- OpenSSL::TestUtils.issue_crl(*args)
- end
-
def test_add_file
ca_exts = [
["basicConstraints", "CA:TRUE", true],
@@ -217,7 +209,7 @@ class OpenSSL::TestX509Store < OpenSSL::TestCase
end
def test_set_errors
- return if OpenSSL::OPENSSL_VERSION_NUMBER >= 0x10100000
+ return if openssl?(1, 1, 0) || libressl?
now = Time.now
ca1_cert = issue_cert(@ca1, @rsa2048, 1, [], nil, nil)
store = OpenSSL::X509::Store.new
@@ -233,17 +225,9 @@ class OpenSSL::TestX509Store < OpenSSL::TestCase
crl2 = issue_crl(revoke_info, 2, now+1800, now+3600, [],
ca1_cert, @rsa2048, OpenSSL::Digest::SHA1.new)
store.add_crl(crl1)
- if /0\.9\.8.*-rhel/ =~ OpenSSL::OPENSSL_VERSION
- # RedHat is distributing a patched version of OpenSSL that allows
- # multiple CRL for a key (multi-crl.patch)
- assert_nothing_raised do
- store.add_crl(crl2) # add CRL issued by same CA twice.
- end
- else
- assert_raise(OpenSSL::X509::StoreError){
- store.add_crl(crl2) # add CRL issued by same CA twice.
- }
- end
+ assert_raise(OpenSSL::X509::StoreError){
+ store.add_crl(crl2) # add CRL issued by same CA twice.
+ }
end
def test_dup
diff --git a/test/openssl/ut_eof.rb b/test/openssl/ut_eof.rb
index 6de41c4a70..bd62fd50f9 100644
--- a/test/openssl/ut_eof.rb
+++ b/test/openssl/ut_eof.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: false
require 'test/unit'
+if defined?(OpenSSL)
+
module OpenSSL::TestEOF
def test_eof_0
open_file("") {|f|
@@ -127,3 +129,5 @@ module OpenSSL::TestEOF
end
end
end
+
+end
diff --git a/test/openssl/utils.rb b/test/openssl/utils.rb
index bbc9c7efc2..f59d53b0d1 100644
--- a/test/openssl/utils.rb
+++ b/test/openssl/utils.rb
@@ -9,129 +9,57 @@ begin
rescue LoadError
end
+# Compile OpenSSL with crypto-mdebug and run this test suite with OSSL_MDEBUG=1
+# environment variable to enable memory leak check.
+if ENV["OSSL_MDEBUG"] == "1"
+ if OpenSSL.respond_to?(:print_mem_leaks)
+ OpenSSL.mem_check_start
+
+ END {
+ GC.start
+ case OpenSSL.print_mem_leaks
+ when nil
+ warn "mdebug: check what is printed"
+ when true
+ raise "mdebug: memory leaks detected"
+ end
+ }
+ else
+ warn "OSSL_MDEBUG=1 is specified but OpenSSL is not built with crypto-mdebug"
+ end
+end
+
require "test/unit"
-require 'tempfile'
-require "rbconfig"
+require "tempfile"
require "socket"
require "envutil"
-module OpenSSL::TestUtils
- TEST_KEY_RSA1024 = OpenSSL::PKey::RSA.new <<-_end_of_pem_
------BEGIN RSA PRIVATE KEY-----
-MIICXgIBAAKBgQDLwsSw1ECnPtT+PkOgHhcGA71nwC2/nL85VBGnRqDxOqjVh7Cx
-aKPERYHsk4BPCkE3brtThPWc9kjHEQQ7uf9Y1rbCz0layNqHyywQEVLFmp1cpIt/
-Q3geLv8ZD9pihowKJDyMDiN6ArYUmZczvW4976MU3+l54E6lF/JfFEU5hwIDAQAB
-AoGBAKSl/MQarye1yOysqX6P8fDFQt68VvtXkNmlSiKOGuzyho0M+UVSFcs6k1L0
-maDE25AMZUiGzuWHyaU55d7RXDgeskDMakD1v6ZejYtxJkSXbETOTLDwUWTn618T
-gnb17tU1jktUtU67xK/08i/XodlgnQhs6VoHTuCh3Hu77O6RAkEA7+gxqBuZR572
-74/akiW/SuXm0SXPEviyO1MuSRwtI87B02D0qgV8D1UHRm4AhMnJ8MCs1809kMQE
-JiQUCrp9mQJBANlt2ngBO14us6NnhuAseFDTBzCHXwUUu1YKHpMMmxpnGqaldGgX
-sOZB3lgJsT9VlGf3YGYdkLTNVbogQKlKpB8CQQDiSwkb4vyQfDe8/NpU5Not0fII
-8jsDUCb+opWUTMmfbxWRR3FBNu8wnym/m19N4fFj8LqYzHX4KY0oVPu6qvJxAkEA
-wa5snNekFcqONLIE4G5cosrIrb74sqL8GbGb+KuTAprzj5z1K8Bm0UW9lTjVDjDi
-qRYgZfZSL+x1P/54+xTFSwJAY1FxA/N3QPCXCjPh5YqFxAMQs2VVYTfg+t0MEcJD
-dPMQD5JX6g5HKnHFg2mZtoXQrWmJSn7p8GJK8yNTopEErA==
------END RSA PRIVATE KEY-----
- _end_of_pem_
-
- TEST_KEY_RSA2048 = OpenSSL::PKey::RSA.new <<-_end_of_pem_
------BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEAuV9ht9J7k4NBs38jOXvvTKY9gW8nLICSno5EETR1cuF7i4pN
-s9I1QJGAFAX0BEO4KbzXmuOvfCpD3CU+Slp1enenfzq/t/e/1IRW0wkJUJUFQign
-4CtrkJL+P07yx18UjyPlBXb81ApEmAB5mrJVSrWmqbjs07JbuS4QQGGXLc+Su96D
-kYKmSNVjBiLxVVSpyZfAY3hD37d60uG+X8xdW5v68JkRFIhdGlb6JL8fllf/A/bl
-NwdJOhVr9mESHhwGjwfSeTDPfd8ZLE027E5lyAVX9KZYcU00mOX+fdxOSnGqS/8J
-DRh0EPHDL15RcJjV2J6vZjPb0rOYGDoMcH+94wIDAQABAoIBAAzsamqfYQAqwXTb
-I0CJtGg6msUgU7HVkOM+9d3hM2L791oGHV6xBAdpXW2H8LgvZHJ8eOeSghR8+dgq
-PIqAffo4x1Oma+FOg3A0fb0evyiACyrOk+EcBdbBeLo/LcvahBtqnDfiUMQTpy6V
-seSoFCwuN91TSCeGIsDpRjbG1vxZgtx+uI+oH5+ytqJOmfCksRDCkMglGkzyfcl0
-Xc5CUhIJ0my53xijEUQl19rtWdMnNnnkdbG8PT3LZlOta5Do86BElzUYka0C6dUc
-VsBDQ0Nup0P6rEQgy7tephHoRlUGTYamsajGJaAo1F3IQVIrRSuagi7+YpSpCqsW
-wORqorkCgYEA7RdX6MDVrbw7LePnhyuaqTiMK+055/R1TqhB1JvvxJ1CXk2rDL6G
-0TLHQ7oGofd5LYiemg4ZVtWdJe43BPZlVgT6lvL/iGo8JnrncB9Da6L7nrq/+Rvj
-XGjf1qODCK+LmreZWEsaLPURIoR/Ewwxb9J2zd0CaMjeTwafJo1CZvcCgYEAyCgb
-aqoWvUecX8VvARfuA593Lsi50t4MEArnOXXcd1RnXoZWhbx5rgO8/ATKfXr0BK/n
-h2GF9PfKzHFm/4V6e82OL7gu/kLy2u9bXN74vOvWFL5NOrOKPM7Kg+9I131kNYOw
-Ivnr/VtHE5s0dY7JChYWE1F3vArrOw3T00a4CXUCgYEA0SqY+dS2LvIzW4cHCe9k
-IQqsT0yYm5TFsUEr4sA3xcPfe4cV8sZb9k/QEGYb1+SWWZ+AHPV3UW5fl8kTbSNb
-v4ng8i8rVVQ0ANbJO9e5CUrepein2MPL0AkOATR8M7t7dGGpvYV0cFk8ZrFx0oId
-U0PgYDotF/iueBWlbsOM430CgYEAqYI95dFyPI5/AiSkY5queeb8+mQH62sdcCCr
-vd/w/CZA/K5sbAo4SoTj8dLk4evU6HtIa0DOP63y071eaxvRpTNqLUOgmLh+D6gS
-Cc7TfLuFrD+WDBatBd5jZ+SoHccVrLR/4L8jeodo5FPW05A+9gnKXEXsTxY4LOUC
-9bS4e1kCgYAqVXZh63JsMwoaxCYmQ66eJojKa47VNrOeIZDZvd2BPVf30glBOT41
-gBoDG3WMPZoQj9pb7uMcrnvs4APj2FIhMU8U15LcPAj59cD6S6rWnAxO8NFK7HQG
-4Jxg3JNNf8ErQoCHb1B3oVdXJkmbJkARoDpBKmTCgKtP8ADYLmVPQw==
------END RSA PRIVATE KEY-----
- _end_of_pem_
-
- TEST_KEY_DSA256 = OpenSSL::PKey::DSA.new <<-_end_of_pem_
------BEGIN DSA PRIVATE KEY-----
-MIH3AgEAAkEAhk2libbY2a8y2Pt21+YPYGZeW6wzaW2yfj5oiClXro9XMR7XWLkE
-9B7XxLNFCS2gmCCdMsMW1HulaHtLFQmB2wIVAM43JZrcgpu6ajZ01VkLc93gu/Ed
-AkAOhujZrrKV5CzBKutKLb0GVyVWmdC7InoNSMZEeGU72rT96IjM59YzoqmD0pGM
-3I1o4cGqg1D1DfM1rQlnN1eSAkBq6xXfEDwJ1mLNxF6q8Zm/ugFYWR5xcX/3wFiT
-b4+EjHP/DbNh9Vm5wcfnDBJ1zKvrMEf2xqngYdrV/3CiGJeKAhRvL57QvJZcQGvn
-ISNX5cMzFHRW3Q==
------END DSA PRIVATE KEY-----
- _end_of_pem_
+if defined?(OpenSSL)
- TEST_KEY_DSA512 = OpenSSL::PKey::DSA.new <<-_end_of_pem_
------BEGIN DSA PRIVATE KEY-----
-MIH4AgEAAkEA5lB4GvEwjrsMlGDqGsxrbqeFRh6o9OWt6FgTYiEEHaOYhkIxv0Ok
-RZPDNwOG997mDjBnvDJ1i56OmS3MbTnovwIVAJgub/aDrSDB4DZGH7UyarcaGy6D
-AkB9HdFw/3td8K4l1FZHv7TCZeJ3ZLb7dF3TWoGUP003RCqoji3/lHdKoVdTQNuR
-S/m6DlCwhjRjiQ/lBRgCLCcaAkEAjN891JBjzpMj4bWgsACmMggFf57DS0Ti+5++
-Q1VB8qkJN7rA7/2HrCR3gTsWNb1YhAsnFsoeRscC+LxXoXi9OAIUBG98h4tilg6S
-55jreJD3Se3slps=
------END DSA PRIVATE KEY-----
- _end_of_pem_
-
- TEST_KEY_DSA1024 = OpenSSL::PKey::DSA.new <<-_end_of_pem_
------BEGIN DSA PRIVATE KEY-----
-MIIBugIBAAKBgQCH9aAoXvWWThIjkA6D+nI1F9ksF9iDq594rkiGNOT9sPDOdB+n
-D+qeeeeloRlj19ymCSADPI0ZLRgkchkAEnY2RnqnhHOjVf/roGgRbW+iQDMbQ9wa
-/pvc6/fAbsu1goE1hBYjm98/sZEeXavj8tR56IXnjF1b6Nx0+sgeUKFKEQIVAMiz
-4BJUFeTtddyM4uadBM7HKLPRAoGAZdLBSYNGiij7vAjesF5mGUKTIgPd+JKuBEDx
-OaBclsgfdoyoF/TMOkIty+PVlYD+//Vl2xnoUEIRaMXHwHfm0r2xUX++oeRaSScg
-YizJdUxe5jvBuBszGPRc/mGpb9YvP0sB+FL1KmuxYmdODfCe51zl8uM/CVhouJ3w
-DjmRGscCgYAuFlfC7p+e8huCKydfcv/beftqjewiOPpQ3u5uI6KPCtCJPpDhs3+4
-IihH2cPsAlqwGF4tlibW1+/z/OZ1AZinPK3y7b2jSJASEaPeEltVzB92hcd1khk2
-jTYcmSsV4VddplOPK9czytR/GbbibxsrhhgZUbd8LPbvIgaiadJ1PgIUBnJ/5vN2
-CVArsEzlPUCbohPvZnE=
------END DSA PRIVATE KEY-----
- _end_of_pem_
-
-if defined?(OpenSSL::PKey::EC)
-
- TEST_KEY_EC_P256V1 = OpenSSL::PKey::EC.new <<-_end_of_pem_
------BEGIN EC PRIVATE KEY-----
-MHcCAQEEIID49FDqcf1O1eO8saTgG70UbXQw9Fqwseliit2aWhH1oAoGCCqGSM49
-AwEHoUQDQgAEFglk2c+oVUIKQ64eZG9bhLNPWB7lSZ/ArK41eGy5wAzU/0G51Xtt
-CeBUl+MahZtn9fO1JKdF4qJmS39dXnpENg==
------END EC PRIVATE KEY-----
- _end_of_pem_
-
-end
+module OpenSSL::TestUtils
+ module Fixtures
+ module_function
- TEST_KEY_DH1024 = OpenSSL::PKey::DH.new <<-_end_of_pem_
------BEGIN DH PARAMETERS-----
-MIGHAoGBAKnKQ8MNK6nYZzLrrcuTsLxuiJGXoOO5gT+tljOTbHBuiktdMTITzIY0
-pFxIvjG05D7HoBZQfrR0c92NGWPkAiCkhQKB8JCbPVzwNLDy6DZ0pmofDKrEsYHG
-AQjjxMXhwULlmuR/K+WwlaZPiLIBYalLAZQ7ZbOPeVkJ8ePao0eLAgEC
------END DH PARAMETERS-----
- _end_of_pem_
+ def pkey(name)
+ OpenSSL::PKey.read(read_file("pkey", name))
+ end
- TEST_KEY_DH1024.set_key(OpenSSL::BN.new("556AF1598AE69899867CEBA9F29CE4862B884C2B43C9019EA0231908F6EFA785E3C462A6ECB16DF676866E997FFB72B487DC7967C58C3CA38CE974473BF19B2AA5DCBF102735572EBA6F353F6F0BBE7FF1DE1B07FE1381A355C275C33405004317F9491B5955F191F6615A63B30E55A027FB88A1A4B25608E09EEE68A7DF32D", 16),
- OpenSSL::BN.new("48561834C67E65FFD2A9B47F41E5E78FDC95C387428FDB1E4B0188B64D1643C3A8D3455B945B7E8C4D166010C7C2CE23BFB9BEF43D0348FE7FA5284B0225E7FE1537546D114E3D8A4411B9B9351AB451E1A358F50ED61B1F00DA29336EEBBD649980AC86D76AF8BBB065298C2052672EEF3EF13AB47A15275FC2836F3AC74CEA", 16))
+ def pkey_dh(name)
+ # DH parameters can be read by OpenSSL::PKey.read atm
+ OpenSSL::PKey::DH.new(read_file("pkey", name))
+ end
- DSA_SIGNATURE_DIGEST = OpenSSL::OPENSSL_VERSION_NUMBER > 0x10000000 ?
- OpenSSL::Digest::SHA1 :
- OpenSSL::Digest::DSS1
+ def read_file(category, name)
+ @file_cache ||= {}
+ @file_cache[[category, name]] ||=
+ File.read(File.join(__dir__, "fixtures", category, name + ".pem"))
+ end
+ end
module_function
def issue_cert(dn, key, serial, extensions, issuer, issuer_key,
- not_before: nil, not_after: nil, digest: nil)
+ not_before: nil, not_after: nil, digest: "sha256")
cert = OpenSSL::X509::Certificate.new
issuer = cert unless issuer
issuer_key = key unless issuer_key
@@ -149,7 +77,6 @@ AQjjxMXhwULlmuR/K+WwlaZPiLIBYalLAZQ7ZbOPeVkJ8ePao0eLAgEC
extensions.each{|oid, value, critical|
cert.add_extension(ef.create_extension(oid, value, critical))
}
- digest ||= OpenSSL::PKey::DSA === issuer_key ? DSA_SIGNATURE_DIGEST.new : "sha256"
cert.sign(issuer_key, digest)
cert
end
@@ -191,190 +118,191 @@ AQjjxMXhwULlmuR/K+WwlaZPiLIBYalLAZQ7ZbOPeVkJ8ePao0eLAgEC
OpenSSL::Digest::SHA1.hexdigest(pkvalue).scan(/../).join(":").upcase
end
- def silent
- begin
- back, $VERBOSE = $VERBOSE, nil
- yield
- ensure
- $VERBOSE = back
- end
+ def openssl?(major = nil, minor = nil, fix = nil, patch = 0)
+ return false if OpenSSL::OPENSSL_VERSION.include?("LibreSSL")
+ return true unless major
+ OpenSSL::OPENSSL_VERSION_NUMBER >=
+ major * 0x10000000 + minor * 0x100000 + fix * 0x1000 + patch * 0x10
end
- class OpenSSL::TestCase < Test::Unit::TestCase
- def setup
- if ENV["OSSL_GC_STRESS"] == "1"
- GC.stress = true
- end
- end
-
- def teardown
- if ENV["OSSL_GC_STRESS"] == "1"
- GC.stress = false
- end
- # OpenSSL error stack must be empty
- assert_equal([], OpenSSL.errors)
- end
+ def libressl?(major = nil, minor = nil, fix = nil)
+ version = OpenSSL::OPENSSL_VERSION.scan(/LibreSSL (\d+)\.(\d+)\.(\d+).*/)[0]
+ return false unless version
+ !major || (version.map(&:to_i) <=> [major, minor, fix]) >= 0
end
+end
- class OpenSSL::SSLTestCase < OpenSSL::TestCase
- RUBY = EnvUtil.rubybin
- ITERATIONS = ($0 == __FILE__) ? 100 : 10
-
- def setup
- super
- @ca_key = OpenSSL::TestUtils::TEST_KEY_RSA2048
- @svr_key = OpenSSL::TestUtils::TEST_KEY_RSA1024
- @cli_key = OpenSSL::TestUtils::TEST_KEY_DSA1024
- @ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA")
- @svr = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost")
- @cli = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost")
- ca_exts = [
- ["basicConstraints","CA:TRUE",true],
- ["keyUsage","cRLSign,keyCertSign",true],
- ]
- ee_exts = [
- ["keyUsage","keyEncipherment,digitalSignature",true],
- ]
- @ca_cert = issue_cert(@ca, @ca_key, 1, ca_exts, nil, nil)
- @svr_cert = issue_cert(@svr, @svr_key, 2, ee_exts, @ca_cert, @ca_key)
- @cli_cert = issue_cert(@cli, @cli_key, 3, ee_exts, @ca_cert, @ca_key)
- @server = nil
- end
+class OpenSSL::TestCase < Test::Unit::TestCase
+ include OpenSSL::TestUtils
+ extend OpenSSL::TestUtils
- def issue_cert(*arg)
- OpenSSL::TestUtils.issue_cert(*arg)
+ def setup
+ if ENV["OSSL_GC_STRESS"] == "1"
+ GC.stress = true
end
+ end
- def issue_crl(*arg)
- OpenSSL::TestUtils.issue_crl(*arg)
+ def teardown
+ if ENV["OSSL_GC_STRESS"] == "1"
+ GC.stress = false
end
+ # OpenSSL error stack must be empty
+ assert_equal([], OpenSSL.errors)
+ end
+end
- def readwrite_loop(ctx, ssl)
- while line = ssl.gets
- ssl.write(line)
- end
- rescue OpenSSL::SSL::SSLError
- rescue IOError
- ensure
- ssl.close rescue nil
- end
+class OpenSSL::SSLTestCase < OpenSSL::TestCase
+ RUBY = EnvUtil.rubybin
+ ITERATIONS = ($0 == __FILE__) ? 100 : 10
+
+ def setup
+ super
+ @ca_key = Fixtures.pkey("rsa2048")
+ @svr_key = Fixtures.pkey("rsa1024")
+ @cli_key = Fixtures.pkey("rsa2048")
+ @ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA")
+ @svr = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost")
+ @cli = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost")
+ ca_exts = [
+ ["basicConstraints","CA:TRUE",true],
+ ["keyUsage","cRLSign,keyCertSign",true],
+ ]
+ ee_exts = [
+ ["keyUsage","keyEncipherment,digitalSignature",true],
+ ]
+ @ca_cert = issue_cert(@ca, @ca_key, 1, ca_exts, nil, nil)
+ @svr_cert = issue_cert(@svr, @svr_key, 2, ee_exts, @ca_cert, @ca_key)
+ @cli_cert = issue_cert(@cli, @cli_key, 3, ee_exts, @ca_cert, @ca_key)
+ @server = nil
+ end
- def server_loop(ctx, ssls, stop_pipe_r, ignore_listener_error, server_proc, threads)
- loop do
- ssl = nil
- begin
- readable, = IO.select([ssls, stop_pipe_r])
- if readable.include? stop_pipe_r
- return
- end
- ssl = ssls.accept
- rescue OpenSSL::SSL::SSLError, Errno::ECONNRESET
- if ignore_listener_error
- retry
- else
- raise
- end
- end
+ def tls12_supported?
+ ctx = OpenSSL::SSL::SSLContext.new
+ ctx.min_version = ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
+ true
+ rescue
+ end
- th = Thread.start do
- server_proc.call(ctx, ssl)
- end
- threads << th
- end
- rescue Errno::EBADF, IOError, Errno::EINVAL, Errno::ECONNABORTED, Errno::ENOTSOCK, Errno::ECONNRESET
- if !ignore_listener_error
- raise
- end
+ def readwrite_loop(ctx, ssl)
+ while line = ssl.gets
+ ssl.write(line)
end
+ end
- def start_server(verify_mode: OpenSSL::SSL::VERIFY_NONE, start_immediately: true,
- ctx_proc: nil, server_proc: method(:readwrite_loop),
- ignore_listener_error: false, &block)
- IO.pipe {|stop_pipe_r, stop_pipe_w|
- store = OpenSSL::X509::Store.new
- store.add_cert(@ca_cert)
- store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
- ctx = OpenSSL::SSL::SSLContext.new
- ctx.cert_store = store
- ctx.cert = @svr_cert
- ctx.key = @svr_key
- ctx.tmp_dh_callback = proc { OpenSSL::TestUtils::TEST_KEY_DH1024 }
- begin
- ctx.ecdh_curves = "P-256"
- rescue NotImplementedError
- end
- ctx.verify_mode = verify_mode
- ctx_proc.call(ctx) if ctx_proc
-
- Socket.do_not_reverse_lookup = true
- tcps = nil
- tcps = TCPServer.new("127.0.0.1", 0)
- port = tcps.connect_address.ip_port
-
- ssls = OpenSSL::SSL::SSLServer.new(tcps, ctx)
- ssls.start_immediately = start_immediately
-
- threads = []
- begin
- server = Thread.new do
- begin
- server_loop(ctx, ssls, stop_pipe_r, ignore_listener_error, server_proc, threads)
- ensure
- tcps.close
+ def start_server(verify_mode: OpenSSL::SSL::VERIFY_NONE, start_immediately: true,
+ ctx_proc: nil, server_proc: method(:readwrite_loop),
+ ignore_listener_error: false, &block)
+ IO.pipe {|stop_pipe_r, stop_pipe_w|
+ store = OpenSSL::X509::Store.new
+ store.add_cert(@ca_cert)
+ store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
+ ctx = OpenSSL::SSL::SSLContext.new
+ ctx.cert_store = store
+ ctx.cert = @svr_cert
+ ctx.key = @svr_key
+ ctx.tmp_dh_callback = proc { Fixtures.pkey_dh("dh1024") }
+ ctx.verify_mode = verify_mode
+ ctx_proc.call(ctx) if ctx_proc
+
+ Socket.do_not_reverse_lookup = true
+ tcps = TCPServer.new("127.0.0.1", 0)
+ port = tcps.connect_address.ip_port
+
+ ssls = OpenSSL::SSL::SSLServer.new(tcps, ctx)
+ ssls.start_immediately = start_immediately
+
+ threads = []
+ begin
+ server_thread = Thread.new do
+ begin
+ loop do
+ begin
+ readable, = IO.select([ssls, stop_pipe_r])
+ break if readable.include? stop_pipe_r
+ ssl = ssls.accept
+ rescue OpenSSL::SSL::SSLError, IOError, Errno::EBADF, Errno::EINVAL,
+ Errno::ECONNABORTED, Errno::ENOTSOCK, Errno::ECONNRESET
+ retry if ignore_listener_error
+ raise
+ end
+
+ th = Thread.new do
+ begin
+ server_proc.call(ctx, ssl)
+ ensure
+ ssl.close
+ end
+ true
+ end
+ threads << th
end
+ ensure
+ tcps.close
end
- threads.unshift server
-
- $stderr.printf("SSL server started: pid=%d port=%d\n", $$, port) if $DEBUG
+ end
- client = Thread.new do
- begin
- block.call(server, port.to_i)
- ensure
- stop_pipe_w.close
- end
+ client_thread = Thread.new do
+ begin
+ block.call(port)
+ ensure
+ # Stop accepting new connection
+ stop_pipe_w.close
+ server_thread.join
end
- threads.unshift client
- ensure
- assert_join_threads(threads)
end
- }
- end
+ threads.unshift client_thread
+ ensure
+ # Terminate existing connections. If a thread did 'pend', re-raise it.
+ pend = nil
+ threads.each { |th|
+ begin
+ th.join(10) or
+ th.raise(RuntimeError, "[start_server] thread did not exit in 10 secs")
+ rescue (defined?(MiniTest::Skip) ? MiniTest::Skip : Test::Unit::PendedError)
+ # MiniTest::Skip is for the Ruby tree
+ pend = $!
+ rescue Exception
+ end
+ }
+ raise pend if pend
+ assert_join_threads(threads)
+ end
+ }
end
+end
- class OpenSSL::PKeyTestCase < OpenSSL::TestCase
- def check_component(base, test, keys)
- keys.each { |comp|
- assert_equal base.send(comp), test.send(comp)
- }
- end
+class OpenSSL::PKeyTestCase < OpenSSL::TestCase
+ def check_component(base, test, keys)
+ keys.each { |comp|
+ assert_equal base.send(comp), test.send(comp)
+ }
+ end
- def dup_public(key)
- case key
- when OpenSSL::PKey::RSA
- rsa = OpenSSL::PKey::RSA.new
- rsa.set_key(key.n, key.e, nil)
- rsa
- when OpenSSL::PKey::DSA
- dsa = OpenSSL::PKey::DSA.new
- dsa.set_pqg(key.p, key.q, key.g)
- dsa.set_key(key.pub_key, nil)
- dsa
- when OpenSSL::PKey::DH
- dh = OpenSSL::PKey::DH.new
- dh.set_pqg(key.p, nil, key.g)
- dh
+ def dup_public(key)
+ case key
+ when OpenSSL::PKey::RSA
+ rsa = OpenSSL::PKey::RSA.new
+ rsa.set_key(key.n, key.e, nil)
+ rsa
+ when OpenSSL::PKey::DSA
+ dsa = OpenSSL::PKey::DSA.new
+ dsa.set_pqg(key.p, key.q, key.g)
+ dsa.set_key(key.pub_key, nil)
+ dsa
+ when OpenSSL::PKey::DH
+ dh = OpenSSL::PKey::DH.new
+ dh.set_pqg(key.p, nil, key.g)
+ dh
+ else
+ if defined?(OpenSSL::PKey::EC) && OpenSSL::PKey::EC === key
+ ec = OpenSSL::PKey::EC.new(key.group)
+ ec.public_key = key.public_key
+ ec
else
- if defined?(OpenSSL::PKey::EC) && OpenSSL::PKey::EC === key
- ec = OpenSSL::PKey::EC.new(key.group)
- ec.public_key = key.public_key
- ec
- else
- raise "unknown key type"
- end
+ raise "unknown key type"
end
end
end
+end
-end if defined?(OpenSSL::OPENSSL_LIBRARY_VERSION) and
- /\AOpenSSL +0\./ !~ OpenSSL::OPENSSL_LIBRARY_VERSION
+end