From 88a9c02a19a9dabc375a40da8c8ed36c44807b65 Mon Sep 17 00:00:00 2001 From: Magnus Ahltorp Date: Fri, 17 Feb 2017 23:31:02 +0100 Subject: 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. --- src/catlfish.erl | 69 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 27 deletions(-) (limited to 'src') 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([<>, + serialise_signature_type(certificate_timestamp), + serialise(TimestampedEntry)]). + +calc_sct(TimestampedEntry, Signatures) -> plop:serialise( - plop:spt(list_to_binary([<>, - 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}, -- cgit v1.1 From bfdce2f5ca404c0c7c5dec43c22fa62b1bd4583f Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Tue, 28 Feb 2017 17:06:08 +0100 Subject: Rename a couple functions and variables; add two comments. --- src/catlfish.erl | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/catlfish.erl b/src/catlfish.erl index 04b3332..6d8d430 100644 --- a/src/catlfish.erl +++ b/src/catlfish.erl @@ -103,9 +103,9 @@ sct_data(TimestampedEntry) -> serialise_signature_type(certificate_timestamp), serialise(TimestampedEntry)]). -calc_sct(TimestampedEntry, Signatures) -> +calc_sct_sig(TimestampedEntry, Signatures) -> plop:serialise( - plop:spt(sct_data(TimestampedEntry), Signatures)). + plop:spt_sig(sct_data(TimestampedEntry), Signatures)). create_logentry(Type, LeafCert, CertChain) -> EntryType = case Type of @@ -126,16 +126,21 @@ get_ratelimit_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; + CachedSCTSig = plop:get_spt_sig(Hash), + HasSig = is_binary(CachedSCTSig), + + case {HasEntry, HasSig} of + {true, true} -> + %% Entry is present in the database and a signature was + %% found in the SCT cache. + CachedSCTSig; _ -> + %% We don't have the entry or we don't have the SCT in the + %% cache. {ok, Signatures} = plop:add(LogEntry, Hash), - SCT = calc_sct(TimestampedEntry, Signatures), - plop:add_spt(Hash, SCT), - SCT + SCT_sig = calc_sct_sig(TimestampedEntry, Signatures), + ok = plop:add_spt_sig(Hash, SCT_sig), + SCT_sig end. -spec add_chain(binary(), [binary()], normal|precert) -> {[{_,_},...]}. -- cgit v1.1