mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
[ruby/openssl] ssl: add SSLContext#sigalgs= and #client_sigalgs=
Add methods for setting supported signature algorithms, corresponding
to SSL_CTX_set1_sigalgs_list() and SSL_CTX_set1_client_sigalgs_list(),
respectively.
6bbe58c492
Co-authored-by: Markus Jung <markus.jung@vivavis.com>
This commit is contained in:
parent
0d75dd1f47
commit
112ba70647
3 changed files with 146 additions and 0 deletions
|
@ -135,6 +135,11 @@ ssl_h = "openssl/ssl.h".freeze
|
||||||
# compile options
|
# compile options
|
||||||
have_func("RAND_egd()", "openssl/rand.h")
|
have_func("RAND_egd()", "openssl/rand.h")
|
||||||
|
|
||||||
|
# added in OpenSSL 1.0.2, not in LibreSSL yet
|
||||||
|
have_func("SSL_CTX_set1_sigalgs_list(NULL, NULL)", ssl_h)
|
||||||
|
# added in OpenSSL 1.0.2, not in LibreSSL or AWS-LC yet
|
||||||
|
have_func("SSL_CTX_set1_client_sigalgs_list(NULL, NULL)", ssl_h)
|
||||||
|
|
||||||
# added in 1.1.0, currently not in LibreSSL
|
# added in 1.1.0, currently not in LibreSSL
|
||||||
have_func("EVP_PBE_scrypt(\"\", 0, (unsigned char *)\"\", 0, 0, 0, 0, 0, NULL, 0)", evp_h)
|
have_func("EVP_PBE_scrypt(\"\", 0, (unsigned char *)\"\", 0, 0, 0, 0, 0, NULL, 0)", evp_h)
|
||||||
|
|
||||||
|
|
|
@ -1079,6 +1079,63 @@ ossl_sslctx_set_ciphersuites(VALUE self, VALUE v)
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_SSL_CTX_SET1_SIGALGS_LIST
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* ctx.sigalgs = "sigalg1:sigalg2:..."
|
||||||
|
*
|
||||||
|
* Sets the list of "supported signature algorithms" for this context.
|
||||||
|
*
|
||||||
|
* For a TLS client, the list is used in the "signature_algorithms" extension
|
||||||
|
* in the ClientHello message. For a server, the list is used by OpenSSL to
|
||||||
|
* determine the set of shared signature algorithms. OpenSSL will pick the most
|
||||||
|
* appropriate one from it.
|
||||||
|
*
|
||||||
|
* See also #client_sigalgs= for the client authentication equivalent.
|
||||||
|
*/
|
||||||
|
static VALUE
|
||||||
|
ossl_sslctx_set_sigalgs(VALUE self, VALUE v)
|
||||||
|
{
|
||||||
|
SSL_CTX *ctx;
|
||||||
|
|
||||||
|
rb_check_frozen(self);
|
||||||
|
GetSSLCTX(self, ctx);
|
||||||
|
|
||||||
|
if (!SSL_CTX_set1_sigalgs_list(ctx, StringValueCStr(v)))
|
||||||
|
ossl_raise(eSSLError, "SSL_CTX_set1_sigalgs_list");
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SSL_CTX_SET1_CLIENT_SIGALGS_LIST
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* ctx.client_sigalgs = "sigalg1:sigalg2:..."
|
||||||
|
*
|
||||||
|
* Sets the list of "supported signature algorithms" for client authentication
|
||||||
|
* for this context.
|
||||||
|
*
|
||||||
|
* For a TLS server, the list is sent to the client as part of the
|
||||||
|
* CertificateRequest message.
|
||||||
|
*
|
||||||
|
* See also #sigalgs= for the server authentication equivalent.
|
||||||
|
*/
|
||||||
|
static VALUE
|
||||||
|
ossl_sslctx_set_client_sigalgs(VALUE self, VALUE v)
|
||||||
|
{
|
||||||
|
SSL_CTX *ctx;
|
||||||
|
|
||||||
|
rb_check_frozen(self);
|
||||||
|
GetSSLCTX(self, ctx);
|
||||||
|
|
||||||
|
if (!SSL_CTX_set1_client_sigalgs_list(ctx, StringValueCStr(v)))
|
||||||
|
ossl_raise(eSSLError, "SSL_CTX_set1_client_sigalgs_list");
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef OPENSSL_NO_DH
|
#ifndef OPENSSL_NO_DH
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
|
@ -2892,6 +2949,12 @@ Init_ossl_ssl(void)
|
||||||
rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
|
rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
|
||||||
rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1);
|
rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1);
|
||||||
rb_define_method(cSSLContext, "ciphersuites=", ossl_sslctx_set_ciphersuites, 1);
|
rb_define_method(cSSLContext, "ciphersuites=", ossl_sslctx_set_ciphersuites, 1);
|
||||||
|
#ifdef HAVE_SSL_CTX_SET1_SIGALGS_LIST // Not in LibreSSL yet
|
||||||
|
rb_define_method(cSSLContext, "sigalgs=", ossl_sslctx_set_sigalgs, 1);
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SSL_CTX_SET1_CLIENT_SIGALGS_LIST // Not in LibreSSL or AWS-LC yet
|
||||||
|
rb_define_method(cSSLContext, "client_sigalgs=", ossl_sslctx_set_client_sigalgs, 1);
|
||||||
|
#endif
|
||||||
#ifndef OPENSSL_NO_DH
|
#ifndef OPENSSL_NO_DH
|
||||||
rb_define_method(cSSLContext, "tmp_dh=", ossl_sslctx_set_tmp_dh, 1);
|
rb_define_method(cSSLContext, "tmp_dh=", ossl_sslctx_set_tmp_dh, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1968,6 +1968,84 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
|
||||||
) { ssl_ctx.ciphers = 'BOGUS' }
|
) { ssl_ctx.ciphers = 'BOGUS' }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_sigalgs
|
||||||
|
omit "SSL_CTX_set1_sigalgs_list() not supported" if libressl?
|
||||||
|
|
||||||
|
svr_exts = [
|
||||||
|
["keyUsage", "keyEncipherment,digitalSignature", true],
|
||||||
|
["subjectAltName", "DNS:localhost", false],
|
||||||
|
]
|
||||||
|
ecdsa_key = Fixtures.pkey("p256")
|
||||||
|
ecdsa_cert = issue_cert(@svr, ecdsa_key, 10, svr_exts, @ca_cert, @ca_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, [@ca_cert]) # ECDSA
|
||||||
|
}
|
||||||
|
start_server(ctx_proc: ctx_proc) do |port|
|
||||||
|
ctx1 = OpenSSL::SSL::SSLContext.new
|
||||||
|
ctx1.sigalgs = "rsa_pss_rsae_sha256"
|
||||||
|
server_connect(port, ctx1) { |ssl|
|
||||||
|
assert_kind_of(OpenSSL::PKey::RSA, ssl.peer_cert.public_key)
|
||||||
|
ssl.puts("abc"); ssl.gets
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx2 = OpenSSL::SSL::SSLContext.new
|
||||||
|
ctx2.sigalgs = "ed25519:ecdsa_secp256r1_sha256"
|
||||||
|
server_connect(port, ctx2) { |ssl|
|
||||||
|
assert_kind_of(OpenSSL::PKey::EC, ssl.peer_cert.public_key)
|
||||||
|
ssl.puts("abc"); ssl.gets
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Frozen
|
||||||
|
ssl_ctx = OpenSSL::SSL::SSLContext.new
|
||||||
|
ssl_ctx.freeze
|
||||||
|
assert_raise(FrozenError) { ssl_ctx.sigalgs = "ECDSA+SHA256:RSA+SHA256" }
|
||||||
|
|
||||||
|
# Bogus
|
||||||
|
ssl_ctx = OpenSSL::SSL::SSLContext.new
|
||||||
|
assert_raise(TypeError) { ssl_ctx.sigalgs = nil }
|
||||||
|
assert_raise(OpenSSL::SSL::SSLError) { ssl_ctx.sigalgs = "BOGUS" }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_client_sigalgs
|
||||||
|
omit "SSL_CTX_set1_client_sigalgs_list() not supported" if libressl? || aws_lc?
|
||||||
|
|
||||||
|
cli_exts = [
|
||||||
|
["keyUsage", "keyEncipherment,digitalSignature", true],
|
||||||
|
["subjectAltName", "DNS:localhost", false],
|
||||||
|
]
|
||||||
|
ecdsa_key = Fixtures.pkey("p256")
|
||||||
|
ecdsa_cert = issue_cert(@cli, ecdsa_key, 10, cli_exts, @ca_cert, @ca_key)
|
||||||
|
|
||||||
|
ctx_proc = -> ctx {
|
||||||
|
store = OpenSSL::X509::Store.new
|
||||||
|
store.add_cert(@ca_cert)
|
||||||
|
store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
|
||||||
|
ctx.cert_store = store
|
||||||
|
ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
|
||||||
|
ctx.client_sigalgs = "ECDSA+SHA256"
|
||||||
|
}
|
||||||
|
start_server(ctx_proc: ctx_proc, ignore_listener_error: true) do |port|
|
||||||
|
ctx1 = OpenSSL::SSL::SSLContext.new
|
||||||
|
ctx1.add_certificate(@cli_cert, @cli_key) # RSA
|
||||||
|
assert_handshake_error {
|
||||||
|
server_connect(port, ctx1) { |ssl|
|
||||||
|
ssl.puts("abc"); ssl.gets
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx2 = OpenSSL::SSL::SSLContext.new
|
||||||
|
ctx2.add_certificate(ecdsa_cert, ecdsa_key) # ECDSA
|
||||||
|
server_connect(port, ctx2) { |ssl|
|
||||||
|
ssl.puts("abc"); ssl.gets
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_connect_works_when_setting_dh_callback_to_nil
|
def test_connect_works_when_setting_dh_callback_to_nil
|
||||||
omit "AWS-LC does not support DHE ciphersuites" if aws_lc?
|
omit "AWS-LC does not support DHE ciphersuites" if aws_lc?
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue