summaryrefslogtreecommitdiff
path: root/src/catlfish.erl
diff options
context:
space:
mode:
authorMagnus Ahltorp <map@kth.se>2017-02-17 23:31:02 +0100
committerMagnus Ahltorp <map@kth.se>2017-02-17 23:31:02 +0100
commit88a9c02a19a9dabc375a40da8c8ed36c44807b65 (patch)
tree61a8c34bd16bf06ef7561f1093a2f0fe68d9634c /src/catlfish.erl
parent320e7346ab80feb58a75703e2fa79fb31887394d (diff)
Support requirement that storage servers sign stored entries
Make SCT cache mandatory. The signature server now requires signatures from the storage nodes, so if SCT is not present in the cache, always send entries to storage servers to collect signatures. Also send SCT when committing entry to storage servers.
Diffstat (limited to 'src/catlfish.erl')
-rw-r--r--src/catlfish.erl69
1 files changed, 42 insertions, 27 deletions
diff --git a/src/catlfish.erl b/src/catlfish.erl
index 4bf1cdf..04b3332 100644
--- a/src/catlfish.erl
+++ b/src/catlfish.erl
@@ -5,7 +5,7 @@
-export([add_chain/3, entries/2, entry_and_proof/2]).
-export([known_roots/0, update_known_roots/0]).
-export([init_cache_table/0]).
--export([entryhash_from_entry/1, verify_entry/1, verify_entry/2]).
+-export([entryhash_from_entry/1, verify_entry/1, verify_entry/2, spt_data/1]).
-include_lib("eunit/include/eunit.hrl").
-define(PROTOCOL_VERSION, 0).
@@ -92,28 +92,22 @@ deserialise_entry_type(<<1:16>>) ->
serialise_signature_type(certificate_timestamp) ->
<<0:8>>.
-calc_sct(TimestampedEntry) ->
+spt_data(DBEntry) ->
+ {_Type, MTLText, _Cert, _Chain} = unpack_entry(DBEntry),
+ MTL = deserialise_mtl(MTLText),
+ TSE = MTL#mtl.entry,
+ sct_data(TSE).
+
+sct_data(TimestampedEntry) ->
+ list_to_binary([<<?PROTOCOL_VERSION:8>>,
+ serialise_signature_type(certificate_timestamp),
+ serialise(TimestampedEntry)]).
+
+calc_sct(TimestampedEntry, Signatures) ->
plop:serialise(
- plop:spt(list_to_binary([<<?PROTOCOL_VERSION:8>>,
- serialise_signature_type(certificate_timestamp),
- serialise(TimestampedEntry)]))).
-
-get_sct(Hash, TimestampedEntry) ->
- case application:get_env(catlfish, sctcache_root_path) of
- {ok, RootPath} ->
- case perm:readfile(RootPath, Hash) of
- Contents when is_binary(Contents) ->
- Contents;
- noentry ->
- SCT = calc_sct(TimestampedEntry),
- ok = perm:ensurefile_nosync(RootPath, Hash, SCT),
- SCT
- end;
- _ ->
- calc_sct(TimestampedEntry)
- end.
+ plop:spt(sct_data(TimestampedEntry), Signatures)).
-add_to_db(Type, LeafCert, CertChain, EntryHash) ->
+create_logentry(Type, LeafCert, CertChain) ->
EntryType = case Type of
normal -> x509_entry;
precert -> precert_entry
@@ -125,21 +119,34 @@ add_to_db(Type, LeafCert, CertChain, EntryHash) ->
entry = TSE}),
MTLHash = ht:leaf_hash(MTLText),
LogEntry = pack_entry(Type, MTLText, LeafCert, CertChain),
- ok = plop:add(LogEntry, MTLHash, EntryHash),
- {TSE, MTLHash}.
+ {TSE, MTLHash, LogEntry}.
get_ratelimit_token(Type) ->
ratelimit:get_token(Type).
+
+maybe_add_to_db(Hash, LogEntry, TimestampedEntry, HasEntry) ->
+ CachedSCTSig = plop:get_spt(Hash),
+
+ case {HasEntry, CachedSCTSig} of
+ {true, SCT} when is_binary(SCT) ->
+ SCT;
+ _ ->
+ {ok, Signatures} = plop:add(LogEntry, Hash),
+ SCT = calc_sct(TimestampedEntry, Signatures),
+ plop:add_spt(Hash, SCT),
+ SCT
+ end.
+
-spec add_chain(binary(), [binary()], normal|precert) -> {[{_,_},...]}.
add_chain(LeafCert, CertChain, Type) ->
EntryHash = crypto:hash(sha256, [LeafCert | CertChain]),
- {TimestampedEntry, Hash} =
+ {{TimestampedEntry, Hash, LogEntry}, HasEntry} =
case plop:get(EntryHash) of
notfound ->
case get_ratelimit_token(add_chain) of
ok ->
- add_to_db(Type, LeafCert, CertChain, EntryHash);
+ {create_logentry(Type, LeafCert, CertChain), false};
_ ->
exit({internalerror, "Rate limiting"})
end;
@@ -147,10 +154,18 @@ add_chain(LeafCert, CertChain, Type) ->
{_Type, MTLText, _Cert, _Chain} = unpack_entry(DBEntry),
MTL = deserialise_mtl(MTLText),
MTLText = serialise(MTL), % verify FIXME: remove
- {MTL#mtl.entry, MTLHash}
+ {{MTL#mtl.entry, MTLHash, DBEntry}, true}
end,
- SCT_sig = get_sct(Hash, TimestampedEntry),
+ SCT_sig = maybe_add_to_db(Hash, LogEntry, TimestampedEntry, HasEntry),
+
+ case HasEntry of
+ false ->
+ plop:commit(Hash, EntryHash, SCT_sig);
+ _ ->
+ none
+ end,
+
{[{sct_version, ?PROTOCOL_VERSION},
{id, base64:encode(plop:get_logid())},
{timestamp, TimestampedEntry#timestamped_entry.timestamp},