From 874050cb72f70206df81eecb3ac5435ff99d639d Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Sat, 26 Apr 2014 08:44:21 +0200 Subject: Make plop a gen_server. --- src/plop.erl | 104 +++++++++++++++++++++++++++---------------------- src/test/plop_test.erl | 19 +++------ 2 files changed, 63 insertions(+), 60 deletions(-) diff --git a/src/plop.erl b/src/plop.erl index 13bad30..90a5249 100644 --- a/src/plop.erl +++ b/src/plop.erl @@ -7,46 +7,77 @@ %%% to prove that your entry is indeed present in the log. -module('plop'). +-behaviour(gen_server). + +%% API. +-export([start_link/0, start_link/2, stop/0]). +-export([add/1, sth/0]). +%% gen_server callbacks. +-export([init/1, handle_call/3, terminate/2, handle_cast/2, handle_info/2, code_change/3]). + -include("plop.hrl"). -include_lib("public_key/include/public_key.hrl"). -include_lib("eunit/include/eunit.hrl"). --export([start/2, loop/1]). - -define(PLOPVERSION, 1). - -record(plop, {pubkey :: public_key:rsa_public_key(), privkey :: public_key:rsa_private_key(), logid :: binary(), hashtree :: ht:head()}). --spec start(string(), string()) -> pid(). -start(Keyfile, Passphrase) -> +start_link() -> + start_link("test/rsakey.pem", "sikrit"). +start_link(Keyfile, Passphrase) -> + gen_server:start_link({local, ?MODULE}, ?MODULE, [Keyfile, Passphrase], []). + +stop() -> + gen_server:call(?MODULE, stop). + +%%%%%%%%%%%%%%%%%%%% +init([Keyfile, Passphrase]) -> {Private_key, Public_key} = read_keyfile(Keyfile, Passphrase), LogID = crypto:hash(sha256, public_key:der_encode('RSAPublicKey', Public_key)), - Plop = #plop{pubkey = Public_key, - privkey = Private_key, - logid = LogID, - hashtree = ht:create()}, - Pid = spawn_link(plop, loop, [Plop]), - register(plop, Pid), - Pid. - -log(Format, Data) -> - io:format(Format, Data). - -loop(Plop) -> - receive - {From, quit} -> - From ! {ok, quit}; - {From, Data} -> - handle_req(From, Plop, Data), - loop(Plop); - Unknown -> - log("DEBUG: Received malformed command: ~p~n", [Unknown]), - loop(Plop) - end. + {ok, #plop{pubkey = Public_key, + privkey = Private_key, + logid = LogID, + hashtree = ht:create()}}. + +handle_cast(_Request, State) -> + {noreply, State}. + +handle_info(_Info, State) -> + {noreply, State}. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +terminate(_Reason, _State) -> + ok. + +%%%%%%%%%%%%%%%%%%%% +add(Data) when is_record(Data, plop_data) -> + gen_server:call(?MODULE, {add, Data}). + +sth() -> + gen_server:call(?MODULE, sth). +%%%%%%%%%%%%%%%%%%%% + +handle_call(stop, _From, State) -> + {stop, normal, stopped, State}; +handle_call({add, Data = #plop_data{entry = Entry}}, + _From, + Plop = #plop{privkey = Privkey, + logid = LogID, + hashtree = Tree}) -> + %% fixme: add Entry to db, + ht:append(Tree, serialise(Entry)), + SPT = spt(LogID, Privkey, Data), + {reply, SPT, Plop}; +handle_call(sth, _From, Plop = #plop{hashtree = Tree}) -> + {reply, sth(Tree), Plop}. + +%%%%%%%%%%%%%%%%%%%% -spec serialise(plop_entry() | plop_data()) -> iolist(). serialise(#plop_entry{type = EntryType, entry = Entry}) -> @@ -57,25 +88,6 @@ serialise(#plop_data{version = Version, entry = Entry}) -> [<>, serialise(Entry)]. -handle_req(From, - #plop{privkey = Privkey, - logid = LogID, - hashtree = Tree}, - Arg) -> - case Arg of - {add, PlopData = #plop_data{entry = Entry}} - when is_record(Entry, plop_entry) -> - %% fixme: add Entry to db, - ht:append(Tree, serialise(Entry)), - SPT = spt(LogID, Privkey, PlopData), - %% io:format("adding ~p to ~p -> H: ~p, SPT: ~p~n", [Entry, Tree, H, SPT]), - From ! {ok, SPT}; - sth -> % Signed tree head. - From ! {ok, sth(Tree)}; - Unknown -> - From ! {error, Unknown} - end. - %% @doc Signed Plop Timestamp according to RFC6962 3.2 and RFC5246 4.7. spt(LogID, PrivKey, diff --git a/src/test/plop_test.erl b/src/test/plop_test.erl index 6b612dd..83b5240 100644 --- a/src/test/plop_test.erl +++ b/src/test/plop_test.erl @@ -12,16 +12,12 @@ adding_test_() -> end}}. start() -> - plop:start("test/rsakey.pem", "sikrit"). + plop:start_link("test/rsakey.pem", "sikrit"). -stop(Pid) -> - Pid ! {self(), quit}, - [?_assert(receive - {ok, quit} -> true - after 500 -> false - end)]. +stop(_Pid) -> + [?_assertEqual({ok, plop}, plop:stop())]. -test_add(Pid) -> +test_add(_Pid) -> TestVector = <<1,247,141,118,3,148,171,128,29,143,106,97,200,179,204,166,242,98,70,185, 231,78,193,39,12,245,82,254,230,136,69,69,0,0,0,0,0,0,0,18,103,71,39,45, @@ -43,11 +39,6 @@ test_add(Pid) -> PlopData = #plop_data{signature_type = ?PLOP_SIGTYPE_TEST, timestamp = 4711, entry = Entry}, - Pid ! {self(), {add, PlopData}}, - Res = receive M -> M end, - %% {ok, Dev} = file:open("d", write), - %% io:format(Dev, "~p~n", [Res]), - %% file:close(Dev), - [?_assertEqual({ok, TestVector}, Res)]. + [?_assertEqual(TestVector, plop:add(PlopData))]. % Helpers. -- cgit v1.1