Heres the code I'm using to setup the server:
require 'socket'
require 'openssl'
socket = TCPServer.new('127.0.0.1', 4433)
ssl_context = OpenSSL::SSL::SSLContext.new()
ssl_context.cert = OpenSSL::X509::Certificate.new(File.open("ssl/server/server.crt"))
ssl_context.key = OpenSSL::PKey::RSA.new(File.open("ssl/server/server.key"))
ca_cert = OpenSSL::X509::Certificate.new(File.open("ssl/ca/ca.crt"))
ssl_socket = OpenSSL::SSL::SSLServer.new(socket, ssl_context)
Thread.start(ssl_socket.accept) do |s|
puts "Connected to #{s.peeraddr.last}"
if s.peer_cert.verify(ca_cert.public_key)
puts "Certificate verified"
else
puts "Certificate invalid"
end
end
And the client:
require 'socket'
require 'openssl'
socket = TCPSocket.new('127.0.0.1', 4433)
ssl_context = OpenSSL::SSL::SSLContext.new
ssl_context.cert = OpenSSL::X509::Certificate.new(File.open("ssl/client1/client1.crt"))
ssl_context.key = OpenSSL::PKey::RSA.new(File.open("ssl/client1/client1.key"))
ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, ssl_context)
ca_cert = OpenSSL::X509::Certificate.new(File.open("ssl/ca/ca.crt"))
ssl_socket.connect
if ssl_socket.peer_cert.verify(ca_cert.public_key)
puts "Certificate checks out"
else
puts "Certificate not verified"
end
However, the server throws an exception when it tries to get the peer_cert that it cannot find. Is there a way to get the SSLServer to expect a client certificate?
Chrome: Verifying that Your Client Certificate Is InstalledIn Chrome, go to Settings. On the Settings page, below Default browser, click Show advanced settings. Under HTTPS/SSL, click Manage certificates. In the Certificates window, on the Personal tab, you should see your Client Certificate.
Just ask Equifax! Client certificates also use public key infrastructure (PKI) for authentication, just like Server certificates. However, there is one significant difference between the two. Unlike Server certificates, Client certificates don't encrypt any data; they're installed for validation purposes only.
Have a look at test_client_auth and start_server in the tests for OpenSSL::SSL
.
From the top of my head, the only thing I see missing in your code is that you forgot to explicitly require client authentication on the server side - it is important to set the flag combination
flags = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
ctx.verify_mode = flags
so that the server will actually require client authentication and not silently accept requests that come unauthenticated. If you don't set these, the server will be happy without requesting client authentication and as a result there will also be no peer certificate available.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With