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:
rhe 2017-09-03 12:35:27 +00:00
Родитель b9801bb8b2
Коммит 609103dbb5
98 изменённых файлов: 3893 добавлений и 3511 удалений

Просмотреть файл

@ -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);

221
ext/openssl/ossl_kdf.c Normal file
Просмотреть файл

@ -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
}

6
ext/openssl/ossl_kdf.h Normal file
Просмотреть файл

@ -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

141
test/openssl/test_kdf.rb Normal file
Просмотреть файл

@ -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