summaryrefslogtreecommitdiff
path: root/src/sign.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/sign.erl')
-rw-r--r--src/sign.erl58
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,