summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLinus Nordberg <linus@nordu.net>2017-03-01 09:53:28 +0100
committerLinus Nordberg <linus@nordu.net>2017-03-01 09:53:28 +0100
commit163fdaeaf8fc1bc43923420309ba4a6b3ef51e11 (patch)
tree9cc294be742eedc5a506c03279bd3d4a6726b91c /src
parenteb3f705c39e022bf3d07c27d6e5b8ddfed638992 (diff)
parent088ef3596d44b5c4bd5eec03296ca78fd86b7a88 (diff)
Merge branch 'map-storage-signature'
Conflicts: NEWS.md
Diffstat (limited to 'src')
-rw-r--r--src/catlfish.erl74
1 files changed, 47 insertions, 27 deletions
diff --git a/src/catlfish.erl b/src/catlfish.erl
index 4bf1cdf..6d8d430 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_sig(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_sig(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,39 @@ 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_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_sig = calc_sct_sig(TimestampedEntry, Signatures),
+ ok = plop:add_spt_sig(Hash, SCT_sig),
+ SCT_sig
+ 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 +159,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},