Skip to content

Commit 51de9c3

Browse files
committed
ssl: let SSLServer accept frozen SSLContext
Do not raise FrozenError in SSLServer.new when SSLContext#session_id_context cannot be updated. session_id_context is only necessary for session resumption, so its absence is not critical. Fixes #742
1 parent 21c0ef5 commit 51de9c3

2 files changed

Lines changed: 68 additions & 1 deletion

File tree

‎lib/openssl/ssl.rb‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ class SSLServer
486486
def initialize(svr, ctx)
487487
@svr = svr
488488
@ctx = ctx
489-
unless ctx.session_id_context
489+
if !ctx.frozen? && !ctx.session_id_context
490490
# see #6137 - session id may not exceed 32 bytes
491491
prng = ::Random.new($0.hash)
492492
session_id = prng.bytes(16).unpack1('H*')

‎test/openssl/test_ssl_server.rb‎

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# frozen_string_literal: true
2+
require_relative "utils"
3+
4+
return unless defined?(OpenSSL::SSL)
5+
6+
class OpenSSL::TestSSLServer < OpenSSL::SSLTestCase
7+
def test_tcpserver
8+
tcps = TCPServer.new("127.0.0.1", 0)
9+
sctx = OpenSSL::SSL::SSLContext.new
10+
sctx.add_certificate(@svr_cert, @svr_key)
11+
server = OpenSSL::SSL::SSLServer.new(tcps, sctx)
12+
assert_same(tcps, server.to_io)
13+
assert_kind_of(String, sctx.session_id_context)
14+
th = Thread.start do
15+
sssl = server.accept
16+
sssl.puts(sssl.gets)
17+
ensure
18+
sssl&.close
19+
end
20+
server_connect(tcps.local_address.ip_port) do |ssl|
21+
assert_equal(@svr_cert.to_der, ssl.peer_cert.to_der)
22+
ssl.puts("abc")
23+
assert_equal("abc\n", ssl.gets)
24+
end
25+
th.join
26+
server.close
27+
assert_predicate(tcps, :closed?)
28+
end
29+
30+
def test_ctx_frozen
31+
tcps = TCPServer.new("127.0.0.1", 0)
32+
sctx = OpenSSL::SSL::SSLContext.new
33+
sctx.add_certificate(@svr_cert, @svr_key)
34+
sctx.setup
35+
server = OpenSSL::SSL::SSLServer.new(tcps, sctx)
36+
assert_nil(sctx.session_id_context)
37+
th = Thread.start do
38+
sssl = server.accept
39+
sssl.puts(sssl.gets)
40+
ensure
41+
sssl&.close
42+
end
43+
server_connect(tcps.local_address.ip_port) do |ssl|
44+
assert_equal(@svr_cert.to_der, ssl.peer_cert.to_der)
45+
ssl.puts("abc")
46+
assert_equal("abc\n", ssl.gets)
47+
end
48+
th.join
49+
server.close
50+
end
51+
52+
private
53+
54+
def server_connect(port, ctx = nil)
55+
sock = TCPSocket.new("127.0.0.1", port)
56+
ssl = ctx ? OpenSSL::SSL::SSLSocket.new(sock, ctx) : OpenSSL::SSL::SSLSocket.new(sock)
57+
ssl.sync_close = true
58+
ssl.connect
59+
yield ssl if block_given?
60+
ensure
61+
if ssl
62+
ssl.close
63+
elsif sock
64+
sock.close
65+
end
66+
end
67+
end

0 commit comments

Comments
 (0)