diff options
Diffstat (limited to 'src/catlfish.erl')
-rw-r--r-- | src/catlfish.erl | 69 |
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}, |