зеркало из https://github.com/github/ruby.git
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
This commit is contained in:
Родитель
b9801bb8b2
Коммит
609103dbb5
|
@ -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
|
||||
=============
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 = ""
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -19,3 +19,4 @@ require 'openssl/config'
|
|||
require 'openssl/digest'
|
||||
require 'openssl/x509'
|
||||
require 'openssl/ssl'
|
||||
require 'openssl/pkcs5'
|
||||
|
|
|
@ -27,8 +27,9 @@ module OpenSSL
|
|||
end # OpenSSL
|
||||
|
||||
##
|
||||
#--
|
||||
# Add double dispatch to Integer
|
||||
#
|
||||
#++
|
||||
class Integer
|
||||
# Casts an Integer as an OpenSSL::BN
|
||||
#
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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"}
|
||||
|
|
|
@ -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'
|
||||
#
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
@ -381,6 +397,23 @@ ossl_debug_set(VALUE self, VALUE val)
|
|||
return 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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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
|
||||
|
|
|
@ -25,33 +25,18 @@ ossl_obj2bio(volatile VALUE *pobj)
|
|||
return bio;
|
||||
}
|
||||
|
||||
VALUE
|
||||
ossl_membio2str0(BIO *bio)
|
||||
{
|
||||
VALUE ret;
|
||||
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;
|
||||
int state;
|
||||
BUF_MEM *buf;
|
||||
|
||||
ret = ossl_protect_membio2str(bio, &status);
|
||||
BIO_get_mem_ptr(bio, &buf);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#if !defined(OSSL_KDF_H)
|
||||
#define OSSL_KDF_H
|
||||
|
||||
void Init_ossl_kdf(void);
|
||||
|
||||
#endif
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
@ -472,6 +455,22 @@ ossl_ocspreq_to_der(VALUE self)
|
|||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
@ -479,7 +478,7 @@ ossl_ocspreq_to_der(VALUE self)
|
|||
/* 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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
#if !defined(_OSSL_PKCS5_H_)
|
||||
#define _OSSL_PKCS5_H_
|
||||
|
||||
void Init_ossl_pkcs5(void);
|
||||
|
||||
#endif /* _OSSL_PKCS5_H_ */
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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?");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
min = parse_proto_version(min_v);
|
||||
max = parse_proto_version(max_v);
|
||||
|
||||
if (SSL_CTX_set_ssl_version(ctx, method) != 1)
|
||||
ossl_raise(eSSLError, "SSL_CTX_set_ssl_version");
|
||||
#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
|
||||
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
|
||||
#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
|
||||
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
|
||||
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
|
||||
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=
|
||||
*/
|
||||
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);
|
||||
/* 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
|
||||
#if defined(SSL_OP_NO_TLSv1_2)
|
||||
ossl_ssl_def_const(OP_NO_TLSv1_2);
|
||||
#endif
|
||||
#if defined(SSL_OP_NO_TICKET)
|
||||
ossl_ssl_def_const(OP_NO_TICKET);
|
||||
#endif
|
||||
#if defined(SSL_OP_NO_COMPRESSION)
|
||||
ossl_ssl_def_const(OP_NO_COMPRESSION);
|
||||
#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);
|
||||
|
||||
|
||||
sym_exception = ID2SYM(rb_intern("exception"));
|
||||
sym_wait_readable = ID2SYM(rb_intern("wait_readable"));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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){
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
-----BEGIN DH PARAMETERS-----
|
||||
MIGHAoGBAKnKQ8MNK6nYZzLrrcuTsLxuiJGXoOO5gT+tljOTbHBuiktdMTITzIY0
|
||||
pFxIvjG05D7HoBZQfrR0c92NGWPkAiCkhQKB8JCbPVzwNLDy6DZ0pmofDKrEsYHG
|
||||
AQjjxMXhwULlmuR/K+WwlaZPiLIBYalLAZQ7ZbOPeVkJ8ePao0eLAgEC
|
||||
-----END DH PARAMETERS-----
|
|
@ -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-----
|
|
@ -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-----
|
|
@ -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-----
|
|
@ -0,0 +1,5 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIID49FDqcf1O1eO8saTgG70UbXQw9Fqwseliit2aWhH1oAoGCCqGSM49
|
||||
AwEHoUQDQgAEFglk2c+oVUIKQ64eZG9bhLNPWB7lSZ/ArK41eGy5wAzU/0G51Xtt
|
||||
CeBUl+MahZtn9fO1JKdF4qJmS39dXnpENg==
|
||||
-----END EC PRIVATE KEY-----
|
|
@ -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-----
|
|
@ -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-----
|
|
@ -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
|
||||
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_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_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_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_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_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_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_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_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_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
|
||||
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_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_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_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
|
||||
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_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)
|
||||
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_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)
|
||||
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_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)
|
||||
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_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)
|
||||
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_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_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 }
|
||||
|
||||
prim = OpenSSL::ASN1::Integer.new(50)
|
||||
assert_equal false, prim.indefinite_length
|
||||
assert_not_respond_to prim, :indefinite_length=
|
||||
end
|
||||
|
||||
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)
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
# 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_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
|
||||
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
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
def test_octet_string_infinite_length_implicit_tagging
|
||||
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
|
||||
|
|
|
@ -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))
|
||||
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_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))
|
||||
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_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)))
|
||||
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_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)
|
||||
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_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))
|
||||
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_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 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
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
# frozen_string_literal: false
|
||||
require_relative 'utils'
|
||||
require 'stringio'
|
||||
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
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, 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
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,61 +1,45 @@
|
|||
# frozen_string_literal: false
|
||||
require_relative 'utils'
|
||||
|
||||
if defined?(OpenSSL::TestUtils)
|
||||
|
||||
require 'socket'
|
||||
require_relative 'ut_eof'
|
||||
|
||||
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
|
||||
end
|
||||
if defined?(OpenSSL)
|
||||
|
||||
def client(port)
|
||||
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
|
||||
module OpenSSL::SSLPairM
|
||||
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 ssl_pair
|
||||
ssls = server
|
||||
host = "127.0.0.1"
|
||||
tcps = create_tcp_server(host, 0)
|
||||
port = tcps.connect_address.ip_port
|
||||
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
|
@ -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)
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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
|
||||
end
|
||||
|
||||
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
|
||||
def test_resumption
|
||||
non_resumable = nil
|
||||
start_server { |port|
|
||||
server_connect_with_session(port, nil, nil) { |ssl|
|
||||
non_resumable = ssl.session
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
}
|
||||
|
||||
str = "x" * 100 + "\n"
|
||||
ssl.puts(str)
|
||||
assert_equal(str, ssl.gets)
|
||||
server_connect_with_session(port, nil, non_resumable) { |ssl|
|
||||
ssl.puts("abc"); assert_equal "abc\n", ssl.gets
|
||||
assert_equal false, ssl.session_reused?
|
||||
}
|
||||
|
||||
ssl.close
|
||||
end
|
||||
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
|
||||
connections = i
|
||||
server_connect_with_session(port, nil, first_session) { |ssl|
|
||||
ssl.puts("abc"); assert_equal "abc\n", ssl.gets
|
||||
first_session ||= ssl.session
|
||||
|
||||
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?)
|
||||
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
|
||||
pend "TLS 1.2 is not supported" unless tls12_supported?
|
||||
|
||||
ctx.session_new_cb = lambda { |ary|
|
||||
sock, sess = ary
|
||||
called[:new] = [sock, sess]
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
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
|
||||
|
||||
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?
|
||||
# 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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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])
|
||||
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"
|
||||
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
|
||||
|
|
|
@ -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) }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
||||
if defined?(OpenSSL)
|
||||
|
||||
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_
|
||||
module Fixtures
|
||||
module_function
|
||||
|
||||
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_
|
||||
def pkey(name)
|
||||
OpenSSL::PKey.read(read_file("pkey", name))
|
||||
end
|
||||
|
||||
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_
|
||||
def pkey_dh(name)
|
||||
# DH parameters can be read by OpenSSL::PKey.read atm
|
||||
OpenSSL::PKey::DH.new(read_file("pkey", name))
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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_
|
||||
|
||||
TEST_KEY_DH1024.set_key(OpenSSL::BN.new("556AF1598AE69899867CEBA9F29CE4862B884C2B43C9019EA0231908F6EFA785E3C462A6ECB16DF676866E997FFB72B487DC7967C58C3CA38CE974473BF19B2AA5DCBF102735572EBA6F353F6F0BBE7FF1DE1B07FE1381A355C275C33405004317F9491B5955F191F6615A63B30E55A027FB88A1A4B25608E09EEE68A7DF32D", 16),
|
||||
OpenSSL::BN.new("48561834C67E65FFD2A9B47F41E5E78FDC95C387428FDB1E4B0188B64D1643C3A8D3455B945B7E8C4D166010C7C2CE23BFB9BEF43D0348FE7FA5284B0225E7FE1537546D114E3D8A4411B9B9351AB451E1A358F50ED61B1F00DA29336EEBBD649980AC86D76AF8BBB065298C2052672EEF3EF13AB47A15275FC2836F3AC74CEA", 16))
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
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::TestCase < Test::Unit::TestCase
|
||||
include OpenSSL::TestUtils
|
||||
extend OpenSSL::TestUtils
|
||||
|
||||
def setup
|
||||
if ENV["OSSL_GC_STRESS"] == "1"
|
||||
GC.stress = true
|
||||
end
|
||||
end
|
||||
|
||||
class OpenSSL::TestCase < Test::Unit::TestCase
|
||||
def setup
|
||||
if ENV["OSSL_GC_STRESS"] == "1"
|
||||
GC.stress = true
|
||||
end
|
||||
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 teardown
|
||||
if ENV["OSSL_GC_STRESS"] == "1"
|
||||
GC.stress = false
|
||||
end
|
||||
# OpenSSL error stack must be empty
|
||||
assert_equal([], OpenSSL.errors)
|
||||
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 tls12_supported?
|
||||
ctx = OpenSSL::SSL::SSLContext.new
|
||||
ctx.min_version = ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
|
||||
true
|
||||
rescue
|
||||
end
|
||||
|
||||
def readwrite_loop(ctx, ssl)
|
||||
while line = ssl.gets
|
||||
ssl.write(line)
|
||||
end
|
||||
end
|
||||
|
||||
class OpenSSL::SSLTestCase < OpenSSL::TestCase
|
||||
RUBY = EnvUtil.rubybin
|
||||
ITERATIONS = ($0 == __FILE__) ? 100 : 10
|
||||
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
|
||||
|
||||
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
|
||||
Socket.do_not_reverse_lookup = true
|
||||
tcps = TCPServer.new("127.0.0.1", 0)
|
||||
port = tcps.connect_address.ip_port
|
||||
|
||||
def issue_cert(*arg)
|
||||
OpenSSL::TestUtils.issue_cert(*arg)
|
||||
end
|
||||
ssls = OpenSSL::SSL::SSLServer.new(tcps, ctx)
|
||||
ssls.start_immediately = start_immediately
|
||||
|
||||
def issue_crl(*arg)
|
||||
OpenSSL::TestUtils.issue_crl(*arg)
|
||||
end
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
|
||||
client = Thread.new do
|
||||
begin
|
||||
block.call(server, port.to_i)
|
||||
ensure
|
||||
stop_pipe_w.close
|
||||
end
|
||||
end
|
||||
threads.unshift client
|
||||
ensure
|
||||
assert_join_threads(threads)
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
client_thread = Thread.new do
|
||||
begin
|
||||
block.call(port)
|
||||
ensure
|
||||
# Stop accepting new connection
|
||||
stop_pipe_w.close
|
||||
server_thread.join
|
||||
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
|
||||
|
|
Загрузка…
Ссылка в новой задаче