2011-10-12 12 views
8

Herezje kod używam do konfiguracji serwera:Zweryfikuj certyfikat klienta przy użyciu SSLServer w Ruby

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 

a klient:

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 

Jednak serwer zgłasza wyjątek podczas próby aby uzyskać peer_cert, którego nie może znaleźć. Czy istnieje sposób, aby serwer SSL oczekiwał certyfikatu klienta?

Odpowiedz

7

Spójrz na test_client_auth i start_server w testach dla OpenSSL::SSL.

Ze szczytu głowy, jedyne co widzę brakuje w kodzie jest to, że zapomniał wyraźnie wymaga uwierzytelnienia klienta po stronie serwera - ważne jest, aby ustawić kombinacji

flags = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT 
ctx.verify_mode = flags 

SO bander że serwer rzeczywiście będzie wymagał uwierzytelnienia klienta i nie będzie milcząco akceptował żądań, które są nieuwierzytelnione. Jeśli ich nie ustawisz, serwer będzie zadowolony bez żądania uwierzytelnienia klienta, w wyniku czego nie będzie dostępny żaden certyfikat równorzędny.

+1

To się udało, dzięki! – chrisbdaemon

+1

Czy VERIFY_PEER oznacza również, że ręczna weryfikacja w pytaniu jest teraz niepotrzebna? – Peeja