As it turns out when running an SSLServer in ruby the openssl doesn't automatically request the peer certificate through the SSL socket. The main reason for this is `ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE` and can be circumvented by verifying the peer, but do not let a failure terminate the socket.
require "openssl"
cert_file = "cert.crt"
key_file = "pkey.key"
config = {
port: 1965,
bind: "127.0.0.1",
cert: OpenSSL::X509::Certificate.new(File.read(cert_file)),
pkey: OpenSSL::PKey::RSA.new(File.read(key_file)),
ssl_context: OpenSSL::SSL::SSLContext.new,
public_path: check_option_path_exist(nil, './public_gemini')
}
Dir.chdir(config[:public_path])
config[:ssl_context].min_version = OpenSSL::SSL::TLS1_2_VERSION
config[:ssl_context].add_certificate(config[:cert], config[:pkey])
config[:ssl_context].verify_mode = OpenSSL::SSL::VERIFY_PEER
config[:ssl_context].verify_callback = proc { |_, _| true }
def handle(socket, cfg)
puts socket.peer_cert&.to_pem
socket.puts("20 text/gemini\r\n")
end
begin
tcp_serv = TCPServer.new(config[:bind], config[:port])
ssl_serv = OpenSSL::SSL::SSLServer.new(tcp_serv, config[:ssl_context])
loop do
Thread.new(ssl_serv.accept) do |socket|
handle(socket, config)
socket.close
end
rescue OpenSSL::SSL::SSLError => e
p e
rescue Interrupt
break
end
ensure
ssl_serv&.shutdown
end