Skip to content

Instantly share code, notes, and snippets.

@bosky101
Last active December 18, 2015 20:59
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 bosky101/5844535 to your computer and use it in GitHub Desktop.
Save bosky101/5844535 to your computer and use it in GitHub Desktop.
Testing a simple https get request. R16A, R16B,R16B01 seems to fail, while for the same configuration R15B03 works. Change USE_VERIFY_PEER, ?USE_SSL_TIMEOUT, and location of ?home, ?CERT,?KEY,?CA accordingly while testing ~@bhaskerkode, Last updated: June 25, 2013
-module(test_ssl).
-author('Bhasker Kode').
-compile([export_all]).
-define(USE_ACCEPT_TIMEOUT,false). %% ssl:ssl_accept is passed a timeout
-define(USE_VERIFY_PEER,false). %% ssl:listen is passed {verify,verify_peer}
%% R15B02 => Works with/without ?USE_VERIFY_PEER Fails when ?USE_SSL_TIMEOUT
%% R15B03 => Works with/without ?USE_VERIFY_PEER Fails when ?USE_SSL_TIMEOUT
%% R16A => Fails* with/without ?USE_VERIFY_PEER Fails with/without ?USE_SSL_TIMEOUT
%% R16B => Fails* with/without ?USE_VERIFY_PEER Fails with/without ?USE_SSL_TIMEOUT
%% R16B01 => Fails* with/without ?USE_VERIFY_PEER Fails with/without ?USE_SSL_TIMEOUT
%% where [*] is, Chrome gives "Error 141 (net::ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED): Unknown error."
%% Tested on Ubuntu 11.04
%% Tested similiar results, with openssl versions
%% OpenSSL 0.9.8o 01 Jun 2010 through
%% OpenSSL 1.0.1e 11 Feb 2013
-define(PORT,8443).
-define(home,os:getenv("KEYS_HOME")).
-define(CERT,?home++"/certificate.crt").
-define(KEY ,?home++"/privatekey.pem").
-define(CA ,?home++"/ca.crt").
%% Choose your preferred paradigm
%% ssl:recv or a receive block
-define(USE_SSL_RECV,false).
%%%-------------------------------------------------------------------
%%% SSL SERVER
%%%-------------------------------------------------------------------
init()->
application:start(crypto),
application:start(asn1), %% Required
application:start(public_key),
application:start(ssl).
start()->
init(),
?MODULE:start(?PORT).
start(Port)->
ToggleOpts = case ?USE_VERIFY_PEER of
true -> [{verify, verify_peer}];
false -> []
end,
spawn(fun()->
{ok,TlsSocket} =
ssl:listen(Port,
ToggleOpts ++
[
{active, false},
{certfile,?CERT},{keyfile,?KEY},{cacertfile,?CA},
{mode,binary}
%% The following had no effect
%% ,{exit_on_close, false}
%% ,{fail_if_no_peer_cert,false}
%% ,{reuseaddr, true}
%% ,{verify_fun,{fun verify_peer/3,[]}},{depth,3}
]),
io:format("~n ~p listening on ~w use_verify_peer:~p use_accept_timeout:~p~n",
[self(),Port,?USE_VERIFY_PEER,?USE_ACCEPT_TIMEOUT]),
server_loop(TlsSocket)
end).
server_loop(Socket)->
{ok,NextSocket} = ssl:transport_accept(Socket),
spawn(fun()->
ssl_accept(NextSocket)
end),
server_loop(Socket).
ssl_accept(Socket)->
io:format("~nNew connection",[]),
Accept = case ?USE_ACCEPT_TIMEOUT of
true ->
io:format("~nUsing ssl_accept timeout"),
ssl:ssl_accept(Socket,1000);
_ ->
ssl:ssl_accept(Socket)
end,
case catch Accept of
ok ->
case ?USE_SSL_RECV of
true ->
%%Use ssl:recv
spawn(fun() -> sslrecv(Socket) end);
_ ->
%% Use receive block
_Controller = spawn(fun() -> loopdata(Socket) end),
%% Note to self: Rightly wont work without passing on control
ssl:controlling_process(Socket,_Controller),
_Controller
end;
AcceptErr ->
Msg = ssl:format_error(AcceptErr),
error_logger:error_msg(Msg), %% [*]"TLS connection is closed" on R16+*
io:format("~nssl socket info ~p",[ssl:connection_info(Socket)]) %% [*}"{error,closed}" on R16+
end.
loopdata(Socket)->
ssl:setopts(Socket,[{active,once}]),
io:format("~nloopdata Accepted! Ready to receive data",[]),
receive
{ssl_closed,_S} ->
io:format("~nSocket closed."),
ok;
{ssl,_,Data} ->
format(Socket,Data),
loopdata(Socket)
end.
% Echo back whatever data we receive on Socket.
sslrecv(Socket) ->
io:format("~nsslrecv Accepted! Ready to receive data",[]),
case ssl:recv(Socket, 0) of
{ok, Data} ->
format(Socket,Data),
sslrecv(Socket);
{error, closed} ->
io:format("~nSocket closed."),
ok
end.
format(Socket,Data)->
io:format("~nSocket received data...~n~p~n", [Data]),
ssl:send(Socket,<<"{\"ok\":true}">>),
ssl:close(Socket).
%%%-------------------------------------------------------------------
%%% SSL CLIENT to the above server
%%%-------------------------------------------------------------------
client(Host)->
HostBin = it_utils:atob(Host),
PortBin = it_utils:itob(?PORT),
client(Host,?PORT,<<"GET / HTTP/1.1\r\nHost: ",HostBin/binary,":",PortBin/binary," \r\n">>).
client(Host,Port,Data)->
{ok,Socket} = ssl:connect(Host,Port,[{mode,binary}]),
ssl:send(Socket,Data),
client_loop(<<>>).
client_loop(Data)->
receive
{ssl_closed,_}->
io:format("~nclient got back ~n",[]),
Data;
{ssl,_,Chunk} ->
client_loop(<<Data/binary,Chunk/binary>>)
after 5000 ->
io:format("client timed out",[])
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment