1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
ruby--ruby/test/openssl/test_ocsp.rb
rhe 609103dbb5 openssl: import v2.1.0.beta1
Import Ruby/OpenSSL 2.1.0.beta1. The full commit log since v2.0.5
(imported by r59567) can be found at:

	https://github.com/ruby/openssl/compare/v2.0.5...v2.1.0.beta1

----------------------------------------------------------------
Antonio Terceiro (1):
      test/test_ssl: explicitly accept TLS 1.1 in corresponding test

Colby Swandale (1):
      document using secure protocol to fetch git master in Bundler

Colton Jenkins (1):
      Add fips_mode_get to return fips_mode

Kazuki Yamaguchi (85):
      Start preparing for 2.1.0
      Remove support for OpenSSL 0.9.8 and 1.0.0
      bn: refine tests
      bn: implement unary {plus,minus} operators for OpenSSL::BN
      bn: implement OpenSSL::BN#negative?
      Don't define main() when built with --enable-debug
      test: let OpenSSL::TestCase include OpenSSL::TestUtils
      test: prepare test PKey instances on demand
      Add OpenSSL.print_mem_leaks
      Enable OSSL_MDEBUG on CI builds
      ssl: move default DH parameters from OpenSSL::PKey::DH
      Make exceptions with the same format regardless of OpenSSL.debug
      ssl: show reason of 'certificate verify error' in exception message
      ssl: remove OpenSSL::ExtConfig::TLS_DH_anon_WITH_AES_256_GCM_SHA384
      ssl: do not confuse different ex_data index registries
      ssl: assume SSL/SSL_CTX always have a valid reference to the Ruby object
      Fix RDoc markup
      ssl: suppress compiler warning
      ext/openssl/deprecation.rb: remove broken-apple-openssl
      extconf.rb: print informative message if OpenSSL can't be found
      Rakefile: compile the extension before test
      kdf: introduce OpenSSL::KDF module
      ossl.h: add NUM2UINT64T() macro
      kdf: add scrypt
      Expand rb_define_copy_func() macro
      Expand FPTR_TO_FD() macro
      Remove SafeGet*() macros
      cipher: rename GetCipherPtr() to ossl_evp_get_cipherbyname()
      digest: rename GetDigestPtr() to ossl_evp_get_digestbyname()
      Add ossl_str_new(), an exception-safe rb_str_new()
      bio: simplify ossl_membio2str() using ossl_str_new()
      Remove unused functions and macros
      Drop support for LibreSSL 2.3
      ocsp: add OpenSSL::OCSP::Request#signed?
      asn1: infinite length -> indefinite length
      asn1: rearrange tests
      ssl: remove a needless NULL check in SSL::SSLContext#ciphers
      ssl: return nil in SSL::SSLSocket#cipher if session is not started
      asn1: remove an unnecessary function prototype
      asn1: require tag information when instantiating generic type
      asn1: initialize 'unused_bits' attribute of BitString with 0
      asn1: check for illegal 'unused_bits' value of BitString
      asn1: disallow NULL to be passed to asn1time_to_time()
      asn1: avoid truncating OID in OpenSSL::ASN1::ObjectId#oid
      asn1: allow constructed encoding with definite length form
      asn1: prohibit indefinite length form for primitive encoding
      asn1: allow tag number to be >= 32 for universal tag class
      asn1: use ossl_asn1_tag()
      asn1: clean up OpenSSL::ASN1::Constructive#to_der
      asn1: harmonize OpenSSL::ASN1::*#to_der
      asn1: prevent EOC octets from being in the middle of the content
      asn1: do not treat EOC octets as part of content octets
      x509name: add 'loc' and 'set' kwargs to OpenSSL::X509::Name#add_entry
      ssl: do not call session_remove_cb during GC
      Backport "Merge branch 'topic/test-memory-leak'" to maint
      cipher: update the documentation for Cipher#auth_tag=
      Rakefile: let sync:to_ruby know about test/openssl/fixtures
      test: fix formatting
      test/utils: remove OpenSSL::TestUtils.silent
      test/utils: add SSLTestCase#tls12_supported?
      test/utils: have start_server yield only the port number
      test/utils: do not set ecdh_curves in start_server
      test/utils: let server_loop close socket
      test/utils: improve error handling in start_server
      test/utils: add OpenSSL::TestUtils.openssl? and .libressl?
      test/utils: do not use DSA certificates in SSL tests
      test/test_ssl: remove test_invalid_shutdown_by_gc
      test/test_ssl: move test_multibyte_read_write to test_pair
      test/test_ssl_session: rearrange tests
      test/test_pair, test/test_ssl: fix for TLS 1.3
      ssl: remove useless call to rb_thread_wait_fd()
      ssl: fix NPN support
      ssl: mark OpenSSL::SSL::SSLContext::DEFAULT_{1024,2048} as private
      ssl: use 2048-bit group in the default tmp_dh_cb
      ssl: ensure that SSL option flags are non-negative
      ssl: update OpenSSL::SSL::OP_* flags
      ssl: prefer TLS_method() over SSLv23_method()
      ssl: add SSLContext#min_version= and #max_version=
      ssl: rework SSLContext#ssl_version=
      test/test_x509name: change script encoding to ASCII-8BIT
      x509name: refactor OpenSSL::X509::Name#to_s
      x509name: add OpenSSL::X509::Name#to_utf8
      x509name: add OpenSSL::X509::Name#inspect
      x509name: update regexp in OpenSSL::X509::Name.parse
      Ruby/OpenSSL 2.1.0.beta1

Marcus Stollsteimer (1):
      Fix rdoc for core Integer class

nobu (4):
      [DOC] {read,write}_nonblock with exception: false
      [DOC] keyword argument _exception_
      [DOC] mark up literals
      Revert r57690 except for read_nonblock

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59734 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-09-03 12:35:27 +00:00

313 lines
13 KiB
Ruby

# frozen_string_literal: false
require_relative "utils"
if defined?(OpenSSL)
class OpenSSL::TestOCSP < OpenSSL::TestCase
def setup
super
# @ca_cert
# |
# @cert
# |----------|
# @cert2 @ocsp_cert
ca_subj = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=TestCA")
@ca_key = Fixtures.pkey("rsa1024")
ca_exts = [
["basicConstraints", "CA:TRUE", true],
["keyUsage", "cRLSign,keyCertSign", true],
]
@ca_cert = OpenSSL::TestUtils.issue_cert(
ca_subj, @ca_key, 1, ca_exts, nil, nil)
cert_subj = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=TestCA2")
@cert_key = Fixtures.pkey("rsa1024")
cert_exts = [
["basicConstraints", "CA:TRUE", true],
["keyUsage", "cRLSign,keyCertSign", true],
]
@cert = OpenSSL::TestUtils.issue_cert(
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 = 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 = Fixtures.pkey("rsa2048")
ocsp_exts = [
["extendedKeyUsage", "OCSPSigning", true],
]
@ocsp_cert = OpenSSL::TestUtils.issue_cert(
ocsp_subj, @ocsp_key, 100, ocsp_exts, @cert, @cert_key)
end
def test_new_certificate_id
cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert)
assert_kind_of OpenSSL::OCSP::CertificateId, cid
assert_equal @cert.serial, cid.serial
cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA256.new)
assert_kind_of OpenSSL::OCSP::CertificateId, cid
assert_equal @cert.serial, cid.serial
end
def test_certificate_id_issuer_name_hash
cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert)
assert_equal OpenSSL::Digest::SHA1.hexdigest(@cert.issuer.to_der), cid.issuer_name_hash
assert_equal "d91f736ac4dc3242f0fb9b77a3149bd83c5c43d0", cid.issuer_name_hash
end
def test_certificate_id_issuer_key_hash
cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert)
assert_equal OpenSSL::Digest::SHA1.hexdigest(OpenSSL::ASN1.decode(@ca_cert.to_der).value[0].value[6].value[1].value), cid.issuer_key_hash
assert_equal "d1fef9fbf8ae1bc160cbfa03e2596dd873089213", cid.issuer_key_hash
end
def test_certificate_id_hash_algorithm
cid_sha1 = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA1.new)
cid_sha256 = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA256.new)
assert_equal "sha1", cid_sha1.hash_algorithm
assert_equal "sha256", cid_sha256.hash_algorithm
end
def test_certificate_id_der
cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert)
der = cid.to_der
asn1 = OpenSSL::ASN1.decode(der)
# hash algorithm defaults to SHA-1
assert_equal OpenSSL::ASN1.ObjectId("SHA1").to_der, asn1.value[0].value[0].to_der
assert_equal [cid.issuer_name_hash].pack("H*"), asn1.value[1].value
assert_equal [cid.issuer_key_hash].pack("H*"), asn1.value[2].value
assert_equal @cert.serial, asn1.value[3].value
assert_equal der, OpenSSL::OCSP::CertificateId.new(der).to_der
end
def test_certificate_id_dup
cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert)
assert_equal cid.to_der, cid.dup.to_der
end
def test_request_der
request = OpenSSL::OCSP::Request.new
cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA1.new)
request.add_certid(cid)
request.sign(@cert, @cert_key, [@ca_cert], 0)
asn1 = OpenSSL::ASN1.decode(request.to_der)
assert_equal cid.to_der, asn1.value[0].value.find { |a| a.tag_class == :UNIVERSAL }.value[0].value[0].to_der
assert_equal OpenSSL::ASN1.ObjectId("sha1WithRSAEncryption").to_der, asn1.value[1].value[0].value[0].value[0].to_der
assert_equal @cert.to_der, asn1.value[1].value[0].value[2].value[0].value[0].to_der
assert_equal @ca_cert.to_der, asn1.value[1].value[0].value[2].value[0].value[1].to_der
assert_equal asn1.to_der, OpenSSL::OCSP::Request.new(asn1.to_der).to_der
end
def test_request_sign_verify
cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert)
store = OpenSSL::X509::Store.new.add_cert(@ca_cert)
# with signer cert
req = OpenSSL::OCSP::Request.new.add_certid(cid)
req.sign(@cert, @cert_key, [])
assert_equal true, req.verify([], store)
# without signer cert
req = OpenSSL::OCSP::Request.new.add_certid(cid)
req.sign(@cert, @cert_key, nil)
assert_equal false, req.verify([@cert2], store)
assert_equal false, req.verify([], store) # no signer
assert_equal false, req.verify([], store, OpenSSL::OCSP::NOVERIFY)
assert_equal true, req.verify([@cert], store, OpenSSL::OCSP::NOINTERN)
ret = req.verify([@cert], store)
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
# OCSP_NOINTERN is not specified.
# 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
req0 = OpenSSL::OCSP::Request.new
req1 = OpenSSL::OCSP::Request.new.add_nonce("NONCE")
req2 = OpenSSL::OCSP::Request.new.add_nonce("ABCDE")
bres = OpenSSL::OCSP::BasicResponse.new
assert_equal 2, req0.check_nonce(bres)
bres.copy_nonce(req1)
assert_equal 3, req0.check_nonce(bres)
assert_equal 1, req1.check_nonce(bres)
bres.add_nonce("NONCE")
assert_equal 1, req1.check_nonce(bres)
assert_equal 0, req2.check_nonce(bres)
end
def test_request_dup
request = OpenSSL::OCSP::Request.new
cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA1.new)
request.add_certid(cid)
assert_equal request.to_der, request.dup.to_der
end
def test_basic_response_der
bres = OpenSSL::OCSP::BasicResponse.new
cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA1.new)
bres.add_status(cid, OpenSSL::OCSP::V_CERTSTATUS_GOOD, 0, nil, -300, 500, [])
bres.add_nonce("NONCE")
bres.sign(@ocsp_cert, @ocsp_key, [@ca_cert], 0)
der = bres.to_der
asn1 = OpenSSL::ASN1.decode(der)
assert_equal OpenSSL::ASN1.Sequence([@ocsp_cert, @ca_cert]).to_der, asn1.value[3].value[0].to_der
assert_equal der, OpenSSL::OCSP::BasicResponse.new(der).to_der
rescue TypeError
if /GENERALIZEDTIME/ =~ $!.message
pend "OCSP_basic_sign() is broken"
else
raise
end
end
def test_basic_response_sign_verify
store = OpenSSL::X509::Store.new.add_cert(@ca_cert)
# signed by CA
bres = OpenSSL::OCSP::BasicResponse.new
cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, "SHA256")
bres.add_status(cid, OpenSSL::OCSP::V_CERTSTATUS_GOOD, nil, -400, -300, 500, [])
bres.sign(@ca_cert, @ca_key, nil, 0, "SHA256")
assert_equal false, bres.verify([], store) # signer not found
assert_equal true, bres.verify([@ca_cert], store)
bres.sign(@ca_cert, @ca_key, [], 0, "SHA256")
assert_equal true, bres.verify([], store)
# signed by OCSP signer
bres = OpenSSL::OCSP::BasicResponse.new
cid = OpenSSL::OCSP::CertificateId.new(@cert2, @cert)
bres.add_status(cid, OpenSSL::OCSP::V_CERTSTATUS_GOOD, nil, -400, -300, 500, [])
bres.sign(@ocsp_cert, @ocsp_key, [@cert])
assert_equal true, bres.verify([], store)
assert_equal false, bres.verify([], store, OpenSSL::OCSP::NOCHAIN)
# OpenSSL had a bug on this; test that our workaround works
bres.sign(@ocsp_cert, @ocsp_key, [])
assert_equal true, bres.verify([@cert], store)
end
def test_basic_response_dup
bres = OpenSSL::OCSP::BasicResponse.new
cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA1.new)
bres.add_status(cid, OpenSSL::OCSP::V_CERTSTATUS_GOOD, 0, nil, -300, 500, [])
bres.sign(@ocsp_cert, @ocsp_key, [@ca_cert], 0)
assert_equal bres.to_der, bres.dup.to_der
end
def test_basic_response_response_operations
bres = OpenSSL::OCSP::BasicResponse.new
now = Time.at(Time.now.to_i)
cid1 = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA1.new)
cid2 = OpenSSL::OCSP::CertificateId.new(@ocsp_cert, @ca_cert, OpenSSL::Digest::SHA1.new)
cid3 = OpenSSL::OCSP::CertificateId.new(@ca_cert, @ca_cert, OpenSSL::Digest::SHA1.new)
bres.add_status(cid1, OpenSSL::OCSP::V_CERTSTATUS_REVOKED, OpenSSL::OCSP::REVOKED_STATUS_UNSPECIFIED, now - 400, -300, nil, nil)
bres.add_status(cid2, OpenSSL::OCSP::V_CERTSTATUS_GOOD, nil, nil, -300, 500, [])
assert_equal 2, bres.responses.size
single = bres.responses.first
assert_equal cid1.to_der, single.certid.to_der
assert_equal OpenSSL::OCSP::V_CERTSTATUS_REVOKED, single.cert_status
assert_equal OpenSSL::OCSP::REVOKED_STATUS_UNSPECIFIED, single.revocation_reason
assert_equal now - 400, single.revocation_time
assert_in_delta (now - 301), single.this_update, 1
assert_equal nil, single.next_update
assert_equal [], single.extensions
assert_equal cid2.to_der, bres.find_response(cid2).certid.to_der
assert_equal nil, bres.find_response(cid3)
end
def test_single_response_der
bres = OpenSSL::OCSP::BasicResponse.new
cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert)
bres.add_status(cid, OpenSSL::OCSP::V_CERTSTATUS_GOOD, nil, nil, -300, 500, nil)
single = bres.responses[0]
der = single.to_der
asn1 = OpenSSL::ASN1.decode(der)
assert_equal :CONTEXT_SPECIFIC, asn1.value[1].tag_class
assert_equal 0, asn1.value[1].tag # good
assert_equal der, OpenSSL::OCSP::SingleResponse.new(der).to_der
end
def test_single_response_check_validity
bres = OpenSSL::OCSP::BasicResponse.new
cid1 = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA1.new)
cid2 = OpenSSL::OCSP::CertificateId.new(@ocsp_cert, @ca_cert, OpenSSL::Digest::SHA1.new)
bres.add_status(cid1, OpenSSL::OCSP::V_CERTSTATUS_REVOKED, OpenSSL::OCSP::REVOKED_STATUS_UNSPECIFIED, -400, -300, -50, [])
bres.add_status(cid2, OpenSSL::OCSP::V_CERTSTATUS_REVOKED, OpenSSL::OCSP::REVOKED_STATUS_UNSPECIFIED, -400, -300, nil, [])
bres.add_status(cid2, OpenSSL::OCSP::V_CERTSTATUS_GOOD, nil, nil, Time.now + 100, nil, nil)
if bres.responses[2].check_validity # thisUpdate is in future; must fail
# LibreSSL bug; skip for now
pend "OCSP_check_validity() is broken"
end
single1 = bres.responses[0]
assert_equal false, single1.check_validity
assert_equal false, single1.check_validity(30)
assert_equal true, single1.check_validity(60)
single2 = bres.responses[1]
assert_equal true, single2.check_validity
assert_equal true, single2.check_validity(0, 500)
assert_equal false, single2.check_validity(0, 200)
end
def test_response
bres = OpenSSL::OCSP::BasicResponse.new
cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA1.new)
bres.add_status(cid, OpenSSL::OCSP::V_CERTSTATUS_GOOD, 0, nil, -300, 500, [])
bres.sign(@ocsp_cert, @ocsp_key, [])
res = OpenSSL::OCSP::Response.create(OpenSSL::OCSP::RESPONSE_STATUS_SUCCESSFUL, bres)
assert_equal bres.to_der, res.basic.to_der
assert_equal OpenSSL::OCSP::RESPONSE_STATUS_SUCCESSFUL, res.status
end
def test_response_der
bres = OpenSSL::OCSP::BasicResponse.new
cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA1.new)
bres.add_status(cid, OpenSSL::OCSP::V_CERTSTATUS_GOOD, 0, nil, -300, 500, [])
bres.sign(@ocsp_cert, @ocsp_key, [@ca_cert], 0)
res = OpenSSL::OCSP::Response.create(OpenSSL::OCSP::RESPONSE_STATUS_SUCCESSFUL, bres)
der = res.to_der
asn1 = OpenSSL::ASN1.decode(der)
assert_equal OpenSSL::OCSP::RESPONSE_STATUS_SUCCESSFUL, asn1.value[0].value
assert_equal OpenSSL::ASN1.ObjectId("basicOCSPResponse").to_der, asn1.value[1].value[0].value[0].to_der
assert_equal bres.to_der, asn1.value[1].value[0].value[1].value
assert_equal der, OpenSSL::OCSP::Response.new(der).to_der
end
def test_response_dup
bres = OpenSSL::OCSP::BasicResponse.new
bres.sign(@ocsp_cert, @ocsp_key, [@ca_cert], 0)
res = OpenSSL::OCSP::Response.create(OpenSSL::OCSP::RESPONSE_STATUS_SUCCESSFUL, bres)
assert_equal res.to_der, res.dup.to_der
end
end
end