2015-08-24 37 views
4

我對Erlang比較陌生,想編寫一個使用客戶端證書來識別客戶端的小型服務器。客戶端應該能夠使用任何公鑰/私鑰對,而不必將其作爲證書鏈的一部分。我查看了OTP源代碼中的SSL示例,並使用make_certs.erl創建了密鑰對。我可以使用創建的客戶端證書進行連接,但不能使用自簽名證書。使用Erlang獲取未經驗證的客戶端證書

如何獲取客戶端證書而不驗證它?

我的代碼示例是目前:

-module(simple_server). 

-export([start/0]). 

keep_alive() -> 
    receive 
     Any -> io:format("Listening socket: ~p~n",[Any]) 
    end. 


start() -> 
    ssl:start(), 
    spawn(fun() -> 
     start_parallel_server(3333), 
     keep_alive() 
    end). 


start_parallel_server(Port) -> 
    case ssl:listen(Port, [ 
     binary, 
     {packet, 0}, 
     {reuseaddr, true}, 
     {active, true}, 
     {certfile,"../etc/server/cert.pem"}, 
     {keyfile,"../etc/server/key.pem"}, 
     {cacertfile,"../etc/server/cacerts.pem"}, 
     {verify,verify_peer}, 
     {fail_if_no_peer_cert,true} 
    ]) of 
     {ok,Listen} -> 
      spawn(fun() -> par_connect(Listen) end); 
     {error,Reason} -> 
      io:format("error ~p~n",[Reason]) 
    end. 



par_connect(Listen) -> 
    case ssl:transport_accept(Listen) of 
     {ok,Socket} -> 
      spawn(fun() -> par_connect(Listen) end), 
      ssl:ssl_accept(Socket), 
      print_cert(Socket), 
      get_request(Socket,[]); 
     {error,Reason} -> 
      io:format("Listening stopped (~p)~n",[Reason]) 
    end. 

print_cert(Socket) -> 
    case ssl:peercert(Socket) of 
     {ok,Cert} -> 
      io:format("Certificate: ~p~n",[Cert]); 
     {error,Reason} -> 
      io:format("Certificate error ~p~n",[Reason]) 
    end. 


get_request(Socket,L) -> 
    receive 
     {ssl, Socket, Bin} -> 
      io:format("Server received: ~p~n",[Bin]), 
      get_request(Socket,L); 
     {ssl_closed, Socket} -> 
      io:format("Socket did disconnect~n"); 
     Reason -> 
      io:format("Client error: ~p~n",[Reason]) 
    end. 

回答

4

您需要提供自定義路徑驗證功能ssl:listen,允許自簽名的證書。

verify_fun選項(see the docs)允許您指定在遇到認證驗證錯誤時調用的函數。 我們可以採取默認實現(在文檔中給出)並確保selfsigned_peer大小寫返回成功:

{verify_fun, {fun(_, {bad_cert, selfsigned_peer}, UserState) -> 
        {valid, UserState}; %% Allow self-signed certificates 

       (_,{bad_cert, _} = Reason, _) -> 
        {fail, Reason}; 

       (_,{extension, _}, UserState) -> 
        {unknown, UserState}; 

       (_, valid, UserState) -> 
        {valid, UserState}; 

       (_, valid_peer, UserState) -> 
        {valid, UserState} 
       end, []}} 
相關問題