Skip to content

Commit dda32ae

Browse files
authored
Merge pull request #908 from junaruga/wip/ssl-client-data
ssl: add SSLSocket#sigalg, #peer_sigalg, #group
2 parents 6956a7b + 434ef74 commit dda32ae

File tree

3 files changed

+100
-0
lines changed

3 files changed

+100
-0
lines changed

ext/openssl/extconf.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,15 @@ def find_openssl_library
156156
have_func("EVP_PKEY_eq(NULL, NULL)", evp_h)
157157
have_func("EVP_PKEY_dup(NULL)", evp_h)
158158

159+
# added in 3.2.0
160+
have_func("SSL_get0_group_name(NULL)", ssl_h)
161+
159162
# added in 3.4.0
160163
have_func("TS_VERIFY_CTX_set0_certs(NULL, NULL)", ts_h)
161164

165+
# added in 3.5.0
166+
have_func("SSL_get0_peer_signature_name(NULL, NULL)", ssl_h)
167+
162168
Logging::message "=== Checking done. ===\n"
163169

164170
# Append flags from environment variables.

ext/openssl/ossl_ssl.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2644,6 +2644,68 @@ ossl_ssl_tmp_key(VALUE self)
26442644
return Qnil;
26452645
return ossl_pkey_new(key);
26462646
}
2647+
2648+
#ifdef HAVE_SSL_GET0_PEER_SIGNATURE_NAME
2649+
/*
2650+
* call-seq:
2651+
* ssl.sigalg => String or nil
2652+
*
2653+
* Returns the signature algorithm name, the IANA name of the signature scheme
2654+
* used by the local to sign the TLS handshake.
2655+
*/
2656+
static VALUE
2657+
ossl_ssl_get_sigalg(VALUE self)
2658+
{
2659+
SSL *ssl;
2660+
const char *name;
2661+
2662+
GetSSL(self, ssl);
2663+
if (!SSL_get0_signature_name(ssl, &name))
2664+
return Qnil;
2665+
return rb_str_new_cstr(name);
2666+
}
2667+
2668+
/*
2669+
* call-seq:
2670+
* ssl.peer_sigalg => String or nil
2671+
*
2672+
* Returns the signature algorithm name, the IANA name of the signature scheme
2673+
* used by the peer to sign the TLS handshake.
2674+
*/
2675+
static VALUE
2676+
ossl_ssl_get_peer_sigalg(VALUE self)
2677+
{
2678+
SSL *ssl;
2679+
const char *name;
2680+
2681+
GetSSL(self, ssl);
2682+
if (!SSL_get0_peer_signature_name(ssl, &name))
2683+
return Qnil;
2684+
return rb_str_new_cstr(name);
2685+
}
2686+
#endif
2687+
2688+
#ifdef HAVE_SSL_GET0_GROUP_NAME
2689+
/*
2690+
* call-seq:
2691+
* ssl.group => String or nil
2692+
*
2693+
* Returns the name of the group that was used for the key agreement of the
2694+
* current TLS session establishment.
2695+
*/
2696+
static VALUE
2697+
ossl_ssl_get_group(VALUE self)
2698+
{
2699+
SSL *ssl;
2700+
const char *name;
2701+
2702+
GetSSL(self, ssl);
2703+
if (!(name = SSL_get0_group_name(ssl)))
2704+
return Qnil;
2705+
return rb_str_new_cstr(name);
2706+
}
2707+
#endif
2708+
26472709
#endif /* !defined(OPENSSL_NO_SOCK) */
26482710

26492711
void
@@ -3067,6 +3129,13 @@ Init_ossl_ssl(void)
30673129
# ifdef OSSL_USE_NEXTPROTONEG
30683130
rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
30693131
# endif
3132+
#ifdef HAVE_SSL_GET0_PEER_SIGNATURE_NAME
3133+
rb_define_method(cSSLSocket, "sigalg", ossl_ssl_get_sigalg, 0);
3134+
rb_define_method(cSSLSocket, "peer_sigalg", ossl_ssl_get_peer_sigalg, 0);
3135+
#endif
3136+
#ifdef HAVE_SSL_GET0_GROUP_NAME
3137+
rb_define_method(cSSLSocket, "group", ossl_ssl_get_group, 0);
3138+
#endif
30703139

30713140
rb_define_const(mSSL, "VERIFY_NONE", INT2NUM(SSL_VERIFY_NONE));
30723141
rb_define_const(mSSL, "VERIFY_PEER", INT2NUM(SSL_VERIFY_PEER));

test/openssl/test_ssl.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2041,6 +2041,27 @@ def test_client_sigalgs
20412041
end
20422042
end
20432043

2044+
def test_get_sigalg
2045+
# SSL_get0_signature_name() not supported
2046+
# SSL_get0_peer_signature_name() not supported
2047+
return unless openssl?(3, 5, 0)
2048+
2049+
server_proc = -> (ctx, ssl) {
2050+
assert_equal('rsa_pss_rsae_sha256', ssl.sigalg)
2051+
assert_nil(ssl.peer_sigalg)
2052+
2053+
readwrite_loop(ctx, ssl)
2054+
}
2055+
start_server(server_proc: server_proc) do |port|
2056+
cli_ctx = OpenSSL::SSL::SSLContext.new
2057+
server_connect(port, cli_ctx) do |ssl|
2058+
assert_nil(ssl.sigalg)
2059+
assert_equal('rsa_pss_rsae_sha256', ssl.peer_sigalg)
2060+
ssl.puts "abc"; ssl.gets
2061+
end
2062+
end
2063+
end
2064+
20442065
def test_connect_works_when_setting_dh_callback_to_nil
20452066
omit "AWS-LC does not support DHE ciphersuites" if aws_lc?
20462067

@@ -2088,6 +2109,8 @@ def test_set_groups_tls12
20882109
server_connect(port, ctx) { |ssl|
20892110
cs = ssl.cipher[0]
20902111
assert_match (/\AECDH/), cs
2112+
# SSL_get0_group_name() is supported on OpenSSL 3.2 or later.
2113+
assert_equal "secp384r1", ssl.group if openssl?(3, 2, 0)
20912114
assert_equal "secp384r1", ssl.tmp_key.group.curve_name
20922115
ssl.puts "abc"; assert_equal "abc\n", ssl.gets
20932116
}
@@ -2127,6 +2150,8 @@ def test_set_groups_tls13
21272150

21282151
server_connect(port, ctx) { |ssl|
21292152
assert_equal "TLSv1.3", ssl.ssl_version
2153+
# SSL_get0_group_name() is supported on OpenSSL 3.2 or later.
2154+
assert_equal "secp384r1", ssl.group if openssl?(3, 2, 0)
21302155
assert_equal "secp384r1", ssl.tmp_key.group.curve_name
21312156
ssl.puts "abc"; assert_equal "abc\n", ssl.gets
21322157
}

0 commit comments

Comments
 (0)