diff options
author | Magnus Ahltorp <map@kth.se> | 2017-02-18 00:41:07 +0100 |
---|---|---|
committer | Magnus Ahltorp <map@kth.se> | 2017-02-18 00:41:07 +0100 |
commit | 8ecfbfa2a57708366763d7adbfcb87f9b0df7d03 (patch) | |
tree | c73012f287783d061a6bbf015dfe09b5dee1604d /src/sign.erl | |
parent | 8feab15047ea459eba1653b77157192f28ae5183 (diff) |
Require that storage servers sign stored entries
Diffstat (limited to 'src/sign.erl')
-rw-r--r-- | src/sign.erl | 58 |
1 files changed, 48 insertions, 10 deletions
diff --git a/src/sign.erl b/src/sign.erl index 6e0e0bd..f7c7194 100644 --- a/src/sign.erl +++ b/src/sign.erl @@ -8,7 +8,7 @@ %% API. -export([start_link/0, stop/0]). --export([sign_sct/1, sign_sth/1, get_pubkey/0, get_logid/0, verify_sth/2]). +-export([sign_sct/2, sign_sth/1, get_pubkey/0, get_logid/0, verify_sth/2]). -export([read_keyfile_ec/1, pem_entry_decode/1]). %% API for tests. -export([read_keyfile_rsa/2]). @@ -145,20 +145,58 @@ remote_sign_request([URL|RestURLs], Request) -> remote_sign_request(RestURLs, Request) end. +verify_storage_signature(Data, Signature) -> + case string:tokens(Signature, ":") of + [Nodename, Sig] -> + case http_auth:verify_stored(Nodename, Data, base64:decode(Sig)) of + true -> + {ok, Nodename}; + _ -> + error + end; + _ -> + error + end. + +verify_storage_signatures(Data, Signatures) -> + Nodenames = sets:from_list(verify_storage_signatures(Data, Signatures, [])), + AllowedStorageNodes = sets:from_list(plopconfig:get_env(storage_node_names, [])), + sets:intersection(Nodenames, AllowedStorageNodes). + +verify_storage_signatures(_Data, [], Nodes) -> + Nodes; +verify_storage_signatures(Data, [Signature | Rest], Nodes) -> + case verify_storage_signature(Data, Signature) of + {ok, Node} -> + verify_storage_signatures(Data, Rest, [Node | Nodes]); + _ -> + [] + end. + %%%%%%%%%%%%%%%%%%%% %% Public API. sign_sct(Data = <<_Version:8, ?CERTIFICATE_TIMESTAMP:8, - _/binary>>) -> - case plopconfig:get_env(signing_nodes) of - {ok, URLBases} -> - Request = {[{plop_version, 1}, - {data, base64:encode(Data)} - ]}, - remote_sign_request([URLBase ++ "sct" || URLBase <- URLBases], Request); - undefined -> - call(?MODULE, {sign, Data}) + _/binary>>, Signatures) -> + Nodenames = verify_storage_signatures(Data, Signatures), + lager:debug("sign_sct: signatures ~p ~p", [Signatures, sets:to_list(Nodenames)]), + {ok, Quorum} = plopconfig:get_env(storage_sign_quorum), + case sets:size(Nodenames) >= Quorum of + true -> + case plopconfig:get_env(signing_nodes) of + {ok, URLBases} -> + Request = {[{plop_version, 1}, + {data, base64:encode(Data)}, + {signatures, Signatures} + ]}, + remote_sign_request([URLBase ++ "sct" || URLBase <- URLBases], Request); + undefined -> + call(?MODULE, {sign, Data}) + end; + _ -> + lager:error("signatures (~p) less than quorum (~p)", [sets:size(Nodenames), Quorum]), + error end. sign_sth(Data = <<_Version:8, |