From 5d24384cd1e4d16ff970708c814820e397cb8faf Mon Sep 17 00:00:00 2001 From: Evgeni Golov Date: Fri, 6 Feb 2026 09:44:13 +0100 Subject: [PATCH 1/2] Correct the doc for peer_cert, it returns a single cert, not an array Also, the cert is an OpenSSL::X509::Certificate not a string. Fixes: 22c0d340026570d2a8fad1b371044ee1ef892001 Fixes: 1c99dd95b897d9f555aabb4668808e8e9ce1a391 --- lib/net/http.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/net/http.rb b/lib/net/http.rb index b33275a..c618799 100644 --- a/lib/net/http.rb +++ b/lib/net/http.rb @@ -659,7 +659,7 @@ class HTTPHeaderSyntaxError < StandardError; end # - {:min_version=}[rdoc-ref:Net::HTTP#min_version=]: # Sets the minimum SSL version. # - {#peer_cert}[rdoc-ref:Net::HTTP#peer_cert]: - # Returns the X509 certificate chain for the session's socket peer. + # Returns the X509 certificate for the session's socket peer. # - {:ssl_version}[rdoc-ref:Net::HTTP#ssl_version]: # Returns the SSL version. # - {:ssl_version=}[rdoc-ref:Net::HTTP#ssl_version=]: @@ -1591,7 +1591,7 @@ def use_ssl=(flag) # See {OpenSSL::SSL::SSLContext#verify_hostname=}[OpenSSL::SSL::SSL::Context#verify_hostname=]. attr_accessor :verify_hostname - # Returns the X509 certificate chain (an array of strings) + # Returns the X509 certificate (an OpenSSL::X509::Certificate) # for the session's socket peer, # or +nil+ if none. def peer_cert From 643718114216a4565a2c95e275599a00f11ec046 Mon Sep 17 00:00:00 2001 From: Evgeni Golov Date: Fri, 6 Feb 2026 09:47:35 +0100 Subject: [PATCH 2/2] Add peer_cert_chain to return the whole certificate chain --- lib/net/http.rb | 12 ++++++++++++ test/net/http/test_https.rb | 2 ++ 2 files changed, 14 insertions(+) diff --git a/lib/net/http.rb b/lib/net/http.rb index c618799..6f0c72e 100644 --- a/lib/net/http.rb +++ b/lib/net/http.rb @@ -660,6 +660,8 @@ class HTTPHeaderSyntaxError < StandardError; end # Sets the minimum SSL version. # - {#peer_cert}[rdoc-ref:Net::HTTP#peer_cert]: # Returns the X509 certificate for the session's socket peer. + # - {#peer_cert_chain}[rdoc-ref:Net::HTTP#peer_cert_chain]: + # Returns the X509 certificate chain for the session's socket peer. # - {:ssl_version}[rdoc-ref:Net::HTTP#ssl_version]: # Returns the SSL version. # - {:ssl_version=}[rdoc-ref:Net::HTTP#ssl_version=]: @@ -1601,6 +1603,16 @@ def peer_cert @socket.io.peer_cert end + # Returns the X509 certificate chain (an array of OpenSSL::X509::Certificate) + # for the session's socket peer, + # or +nil+ if none. + def peer_cert_chain + if not use_ssl? or not @socket + return nil + end + @socket.io.peer_cert_chain + end + # Starts an \HTTP session. # # Without a block, returns +self+: diff --git a/test/net/http/test_https.rb b/test/net/http/test_https.rb index f5b21b9..be01e36 100644 --- a/test/net/http/test_https.rb +++ b/test/net/http/test_https.rb @@ -39,6 +39,7 @@ def test_get http.request_get("/") {|res| assert_equal($test_net_http_data, res.body) assert_equal(SERVER_CERT.to_der, http.peer_cert.to_der) + assert_equal(SERVER_CERT.to_der, http.peer_cert_chain.first.to_der) } end @@ -50,6 +51,7 @@ def test_get_SNI http.request_get("/") {|res| assert_equal($test_net_http_data, res.body) assert_equal(SERVER_CERT.to_der, http.peer_cert.to_der) + assert_equal(SERVER_CERT.to_der, http.peer_cert_chain.first.to_der) } end