summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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},