Skip to content

Instantly share code, notes, and snippets.

@so0k
Created May 5, 2019 04:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save so0k/46b280ae81c9a652b0f0ade0e384ee70 to your computer and use it in GitHub Desktop.
Save so0k/46b280ae81c9a652b0f0ade0e384ee70 to your computer and use it in GitHub Desktop.
Ssl rspec SNI test
require 'openssl'
require 'socket'
def ssl_peek(host)
ip = ENV['TIP_HOST'] || '0.0.0.0'
port = ENV['TIP_PORT'] || '8121'
tcp_client = TCPSocket.new(ip, port)
ssl_client = OpenSSL::SSL::SSLSocket.new(tcp_client)
ssl_client.hostname = host
ssl_client.connect
cert = OpenSSL::X509::Certificate.new(ssl_client.peer_cert)
ssl_client.sysclose
tcp_client.close
cert
end
def cert_value(cert, kind, key)
values = cert.send(kind).to_a.select do |k, _, _|
k.to_s == key.to_s
end
values.first ? values.first[1] : ''
end
def expect_subject(cert, field, value)
expect(cert_value(cert, :subject, field)).to eq(value)
end
describe 'Ssl' do
it "serves foo wildcard for test.foo.com" do
cert = ssl_peek('test.foo.com')
expect_subject(cert,'CN','*.foo.com')
end
it "serves bar wildcard for test.bar.com" do
cert = ssl_peek('test.bar.com')
expect_subject(cert,'CN','*.bar.com')
end
end
@so0k
Copy link
Author

so0k commented May 5, 2019

@so0k
Copy link
Author

so0k commented May 5, 2019

rspec_ssltls did not allow me to specify the server name ip / port separately from the server_name we wish to send (think curl --resolve flag)

(or I didn't figure out how to do it) - if your hostname and ip/port are resolved properly (you may use /etc/hosts or dnsmasq to force this) - then it is much easier to use the existing library:

require 'rspec_ssltls'

describe 'Cert' do
  it "Serves host-1 certificate for host-1" do
    expect("0.0.0.0:8121").to have_certificate.subject(CN: 'host-1')
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment