Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to test OpenSSL::SSL::SSLContext#add_certificate? #516

Open
postmodern opened this issue Jun 3, 2022 · 1 comment
Open

How to test OpenSSL::SSL::SSLContext#add_certificate? #516

postmodern opened this issue Jun 3, 2022 · 1 comment

Comments

@postmodern
Copy link
Member

postmodern commented Jun 3, 2022

The documentation for SSLContext states that the #key= and #cert= writer methods are deprecated and to instead use #add_certificate. However, I noticed there does not seem to be a way to inspect the added key and cert objects? Both #key and #cert both return nil after calling #add_certificate.

Steps To Reproduce

key = OpenSSL::PKey::RSA.new(File.read('ssl.key'))
cert = OpenSSL::X509::Certificate.new(File.read('ssl.crt'))

context = OpenSSL::SSL::SSLContext.new
context.add_certificate(cert,key)
p context.key
p context.cert

Expected Results

#<OpenSSL::PKey::RSA: ...>
#<OpenSSL::X509::Certificate: ...>

Actual Results

nil
nil

Version

  • ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
  • openssl (default: 3.0.0)
@rhenium
Copy link
Member

rhenium commented Jul 27, 2022

There's currently no way to retrieve them from SSLContext. SSLContext#add_certificate is intended to support parallel ECDSA+RSA certificates, so it will be tricky to provide the exact state.

The internal state looks like { rsa => [privkey, rsacert, ca-certs], ecdsa => [privkey, eccert, ca-certs], ... }.

Once a session is established, SSLSocket#cert can return the local certificate actually in use.

def test_add_certificate_multiple_certs
ca2_key = Fixtures.pkey("rsa-3")
ca2_exts = [
["basicConstraints", "CA:TRUE", true],
["keyUsage", "cRLSign, keyCertSign", true],
]
ca2_dn = OpenSSL::X509::Name.parse_rfc2253("CN=CA2")
ca2_cert = issue_cert(ca2_dn, ca2_key, 123, ca2_exts, nil, nil)
ecdsa_key = Fixtures.pkey("p256")
exts = [
["keyUsage", "digitalSignature", false],
]
ecdsa_dn = OpenSSL::X509::Name.parse_rfc2253("CN=localhost2")
ecdsa_cert = issue_cert(ecdsa_dn, ecdsa_key, 456, exts, ca2_cert, ca2_key)
ctx_proc = -> ctx {
# Unset values set by start_server
ctx.cert = ctx.key = ctx.extra_chain_cert = nil
ctx.add_certificate(@svr_cert, @svr_key, [@ca_cert]) # RSA
ctx.add_certificate(ecdsa_cert, ecdsa_key, [ca2_cert])
}
start_server(ctx_proc: ctx_proc) do |port|
ctx = OpenSSL::SSL::SSLContext.new
ctx.max_version = :TLS1_2 # TODO: We need this to force certificate type
ctx.ciphers = "aECDSA"
server_connect(port, ctx) { |ssl|
assert_equal ecdsa_cert.subject, ssl.peer_cert.subject
assert_equal [ecdsa_cert.subject, ca2_cert.subject],
ssl.peer_cert_chain.map(&:subject)
}
ctx = OpenSSL::SSL::SSLContext.new
ctx.max_version = :TLS1_2
ctx.ciphers = "aRSA"
server_connect(port, ctx) { |ssl|
assert_equal @svr_cert.subject, ssl.peer_cert.subject
assert_equal [@svr_cert.subject, @ca_cert.subject],
ssl.peer_cert_chain.map(&:subject)
}
end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants