Skip to content

Commit d1aa05a

Browse files
committed
ssl: add SSLSocket#sigalg, #peer_sigalg, #group
These new methods are useful to test post-quantum cryptography (PQC) cases.
1 parent 6956a7b commit d1aa05a

File tree

3 files changed

+117
-0
lines changed

3 files changed

+117
-0
lines changed

ext/openssl/extconf.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,16 @@ 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_signature_name(NULL, NULL)", ssl_h)
167+
have_func("SSL_get0_peer_signature_name(NULL, NULL)", ssl_h)
168+
162169
Logging::message "=== Checking done. ===\n"
163170

164171
# Append flags from environment variables.

ext/openssl/ossl_ssl.c

Lines changed: 71 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_SIGNATURE_NAME
2649+
/*
2650+
* call-seq:
2651+
* ssl.sigalg => String
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+
#endif
2669+
2670+
#ifdef HAVE_SSL_GET0_PEER_SIGNATURE_NAME
2671+
/*
2672+
* call-seq:
2673+
* ssl.peer_sigalg => String
2674+
*
2675+
* Returns the signature algorithm name, the IANA name of the signature scheme
2676+
* used by the peer to sign the TLS handshake.
2677+
*/
2678+
static VALUE
2679+
ossl_ssl_get_peer_sigalg(VALUE self)
2680+
{
2681+
SSL *ssl;
2682+
const char *name;
2683+
2684+
GetSSL(self, ssl);
2685+
if (!SSL_get0_peer_signature_name(ssl, &name))
2686+
return Qnil;
2687+
return rb_str_new_cstr(name);
2688+
}
2689+
#endif
2690+
2691+
#ifdef HAVE_SSL_GET0_GROUP_NAME
2692+
/*
2693+
* call-seq:
2694+
* ssl.group => String
2695+
*
2696+
* Returns the name of the group that was used for the key agreement of the
2697+
* current TLS session establishment.
2698+
*/
2699+
static VALUE
2700+
ossl_ssl_get_group(VALUE self)
2701+
{
2702+
SSL *ssl;
2703+
2704+
GetSSL(self, ssl);
2705+
return rb_str_new_cstr(SSL_get0_group_name(ssl));
2706+
}
2707+
#endif
2708+
26472709
#endif /* !defined(OPENSSL_NO_SOCK) */
26482710

26492711
void
@@ -3067,6 +3129,15 @@ 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_SIGNATURE_NAME
3133+
rb_define_method(cSSLSocket, "sigalg", ossl_ssl_get_sigalg, 0);
3134+
#endif
3135+
#ifdef HAVE_SSL_GET0_PEER_SIGNATURE_NAME
3136+
rb_define_method(cSSLSocket, "peer_sigalg", ossl_ssl_get_peer_sigalg, 0);
3137+
#endif
3138+
#ifdef HAVE_SSL_GET0_GROUP_NAME
3139+
rb_define_method(cSSLSocket, "group", ossl_ssl_get_group, 0);
3140+
#endif
30703141

30713142
rb_define_const(mSSL, "VERIFY_NONE", INT2NUM(SSL_VERIFY_NONE));
30723143
rb_define_const(mSSL, "VERIFY_PEER", INT2NUM(SSL_VERIFY_PEER));

test/openssl/test_ssl.rb

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2088,6 +2088,8 @@ def test_set_groups_tls12
20882088
server_connect(port, ctx) { |ssl|
20892089
cs = ssl.cipher[0]
20902090
assert_match (/\AECDH/), cs
2091+
# SSL_get0_group_name() is supported on OpenSSL 3.2 or later.
2092+
assert_equal "secp384r1", ssl.group if openssl?(3, 2, 0)
20912093
assert_equal "secp384r1", ssl.tmp_key.group.curve_name
20922094
ssl.puts "abc"; assert_equal "abc\n", ssl.gets
20932095
}
@@ -2127,6 +2129,8 @@ def test_set_groups_tls13
21272129

21282130
server_connect(port, ctx) { |ssl|
21292131
assert_equal "TLSv1.3", ssl.ssl_version
2132+
# SSL_get0_group_name() is supported on OpenSSL 3.2 or later.
2133+
assert_equal "secp384r1", ssl.group if openssl?(3, 2, 0)
21302134
assert_equal "secp384r1", ssl.tmp_key.group.curve_name
21312135
ssl.puts "abc"; assert_equal "abc\n", ssl.gets
21322136
}
@@ -2213,6 +2217,41 @@ def test_export_keying_material
22132217
end
22142218
end
22152219

2220+
def test_get_sigalg
2221+
# SSL_get0_signature_name() not supported
2222+
# SSL_get0_peer_signature_name() not supported
2223+
return unless openssl?(3, 5, 0)
2224+
2225+
server_proc = -> (ctx, ssl) {
2226+
assert_equal('rsa_pss_rsae_sha256', ssl.sigalg)
2227+
assert_nil(ssl.peer_sigalg)
2228+
2229+
readwrite_loop(ctx, ssl)
2230+
}
2231+
start_server(server_proc: server_proc) do |port|
2232+
cli_ctx = OpenSSL::SSL::SSLContext.new
2233+
server_connect(port, cli_ctx) do |ssl|
2234+
assert_nil(ssl.sigalg)
2235+
assert_equal('rsa_pss_rsae_sha256', ssl.peer_sigalg)
2236+
ssl.puts "abc"; ssl.gets
2237+
end
2238+
end
2239+
end
2240+
2241+
def test_group
2242+
# SSL_get0_group_name() not supported
2243+
return unless openssl?(3, 2, 0)
2244+
2245+
start_server do |port|
2246+
cli_ctx = OpenSSL::SSL::SSLContext.new
2247+
cli_ctx.groups = "X25519"
2248+
server_connect(port, cli_ctx) do |ssl|
2249+
assert_equal('x25519', ssl.group)
2250+
ssl.puts "abc"; ssl.gets
2251+
end
2252+
end
2253+
end
2254+
22162255
private
22172256

22182257
def server_connect(port, ctx = nil)

0 commit comments

Comments
 (0)