Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
816 views
in Technique[技术] by (71.8m points)

ssl - Verify client certificate using SSLServer in Ruby

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...