Skip to content

ssl: add SSLSocket#peer_signature_digest_name, #peer_signature_name, #group_name #908

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions ext/openssl/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,15 @@ def find_openssl_library
have_func("EVP_PKEY_eq(NULL, NULL)", evp_h)
have_func("EVP_PKEY_dup(NULL)", evp_h)

# added in 3.2.0
have_func("SSL_get0_group_name(NULL)", ssl_h)

# added in 3.4.0
have_func("TS_VERIFY_CTX_set0_certs(NULL, NULL)", ts_h)

# added in 3.5.0
have_func("SSL_get0_peer_signature_name(NULL, NULL)", ssl_h)

Logging::message "=== Checking done. ===\n"

# Append flags from environment variables.
Expand Down
2 changes: 2 additions & 0 deletions ext/openssl/ossl.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
#include <openssl/dsa.h>
#include <openssl/evp.h>
#include <openssl/dh.h>
#include <openssl/obj_mac.h>
#include <openssl/objects.h>
#include "openssl_missing.h"

#ifndef LIBRESSL_VERSION_NUMBER
Expand Down
71 changes: 71 additions & 0 deletions ext/openssl/ossl_ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -2644,6 +2644,70 @@ ossl_ssl_tmp_key(VALUE self)
return Qnil;
return ossl_pkey_new(key);
}

/*
* call-seq:
* ssl.peer_signature_digest_name => String
*
* Returns the digest name string used by the peer to sign TLS messages.
*/
static VALUE
ossl_ssl_get_peer_signature_digest_name(VALUE self)
{
SSL *ssl;
const char *name;
int nid;

GetSSL(self, ssl);
if (!SSL_get_peer_signature_nid(ssl, &nid))
return Qnil;
if (nid == NID_undef)
return Qnil;
name = OBJ_nid2sn(nid);
if (!name)
return Qnil;
return rb_str_new2(name);
}

#ifdef HAVE_SSL_GET0_PEER_SIGNATURE_NAME
/*
* call-seq:
* ssl.peer_signature_name => String
*
* Returns the signature algorithms string used by the peer to sign the TLS
* handshake.
*/
static VALUE
ossl_ssl_get_peer_signature_name(VALUE self)
{
SSL *ssl;
const char *name;

GetSSL(self, ssl);
if (!SSL_get0_peer_signature_name(ssl, &name))
return Qnil;
return rb_str_new2(name);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return rb_str_new2(name);
return rb_str_new_cstr(name);

new2 is a soft-deprecated macro for this function.

}
#endif

#ifdef HAVE_SSL_GET0_GROUP_NAME
/*
* call-seq:
* ssl.group_name => String
*
* Returns the name string of the group that was used for the key agreement of
* the current TLS session establishment.
*/
static VALUE
ossl_ssl_get_group_name(VALUE self)
{
SSL *ssl;

GetSSL(self, ssl);
return rb_str_new2(SSL_get0_group_name(ssl));
}
#endif

#endif /* !defined(OPENSSL_NO_SOCK) */

void
Expand Down Expand Up @@ -3067,6 +3131,13 @@ Init_ossl_ssl(void)
# ifdef OSSL_USE_NEXTPROTONEG
rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
# endif
rb_define_method(cSSLSocket, "peer_signature_digest_name", ossl_ssl_get_peer_signature_digest_name, 0);
#ifdef HAVE_SSL_GET0_PEER_SIGNATURE_NAME
rb_define_method(cSSLSocket, "peer_signature_name", ossl_ssl_get_peer_signature_name, 0);
#endif
#ifdef HAVE_SSL_GET0_GROUP_NAME
rb_define_method(cSSLSocket, "group_name", ossl_ssl_get_group_name, 0);
#endif

rb_define_const(mSSL, "VERIFY_NONE", INT2NUM(SSL_VERIFY_NONE));
rb_define_const(mSSL, "VERIFY_PEER", INT2NUM(SSL_VERIFY_PEER));
Expand Down
41 changes: 41 additions & 0 deletions test/openssl/test_ssl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2213,6 +2213,47 @@ def test_export_keying_material
end
end

def test_peer_signature_digest_name
start_server do |port|
cli_ctx = OpenSSL::SSL::SSLContext.new
server_connect(port, cli_ctx) do |ssl|
# Observing the "SHA256" for OpenSSL and "SHA512" for LibreSSL.
assert_match(/^SHA/, ssl.peer_signature_digest_name)
ssl.puts "abc"; ssl.gets
end
end
end

def test_peer_signature_name
# SSL_get0_peer_signature_name() not supported
return unless openssl?(3, 5, 0)

start_server do |port|
cli_ctx = OpenSSL::SSL::SSLContext.new
server_connect(port, cli_ctx) do |ssl|
assert_equal('rsa_pss_rsae_sha256', ssl.peer_signature_name)
ssl.puts "abc"; ssl.gets
end
end
end

def test_group_name
# SSL_get0_group_name() not supported
return unless openssl?(3, 2, 0)

start_server do |port|
cli_ctx = OpenSSL::SSL::SSLContext.new
server_connect(port, cli_ctx) do |ssl|
if openssl?(3, 5, 0)
assert_equal('X25519MLKEM768', ssl.group_name)
else
assert_equal('x25519', ssl.group_name)
end
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note I am investigating which commit between the OpenSSL 3.5 and 3.4 made this change in the SSL_get0_group_name(). I haven't found the change in the OpenSSL documents.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can force one with SSLContext#groups= now. Perhaps you can just add assertions in the existing tests for it?

ssl.puts "abc"; ssl.gets
end
end
end

private

def server_connect(port, ctx = nil)
Expand Down