summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/catlfish.erl69
-rwxr-xr-xtools/compileconfig.py11
2 files changed, 50 insertions, 30 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},
diff --git a/tools/compileconfig.py b/tools/compileconfig.py
index fd77b90..9973a95 100755
--- a/tools/compileconfig.py
+++ b/tools/compileconfig.py
@@ -257,8 +257,7 @@ def gen_config(nodename, config, localconfig):
if nodetype & set(["frontendnodes", "mergenodes"]):
catlfishconfig.append((Symbol("known_roots_path"), localconfig["paths"]["knownroots"]))
if "frontendnodes" in nodetype:
- if "sctcaching" in options:
- catlfishconfig.append((Symbol("sctcache_root_path"), paths["db"] + "sctcache/"))
+ plopconfig.append((Symbol("sptcache_root_path"), paths["db"] + "sctcache"))
if "ratelimits" in localconfig:
ratelimits = map(parse_ratelimit, localconfig["ratelimits"].items())
catlfishconfig.append((Symbol("ratelimits"), ratelimits))
@@ -312,6 +311,8 @@ def gen_config(nodename, config, localconfig):
(Symbol("sendsth_verified_path"), paths["db"] + "sendsth-verified"),
(Symbol("entryhash_from_entry"),
(Symbol("catlfish"), Symbol("entryhash_from_entry"))),
+ (Symbol("spt_data"),
+ (Symbol("catlfish"), Symbol("spt_data"))),
]
if "storagenodes" in nodetype:
plopconfig += [
@@ -340,12 +341,14 @@ def gen_config(nodename, config, localconfig):
allowed_clients = []
allowed_servers = []
+ storagenodenames = [node["name"] for node in config["storagenodes"]]
services = set()
+ storage_sign_quorum = config.get("storage-sign-quorum-size", 0)
if "frontendnodes" in nodetype:
- storagenodenames = [node["name"] for node in config["storagenodes"]]
reloadableplopconfig.append((Symbol("storage_nodes"), storagenodeaddresses))
reloadableplopconfig.append((Symbol("storage_nodes_quorum"), config["storage-quorum-size"]))
+ reloadableplopconfig.append((Symbol("storage_sign_quorum"), storage_sign_quorum))
services.add(Symbol("ht"))
allowed_clients += allowed_clients_frontend(mergenodenames, primarymergenodename)
allowed_clients += allowed_clients_public()
@@ -353,6 +356,7 @@ def gen_config(nodename, config, localconfig):
if "storagenodes" in nodetype:
allowed_clients += allowed_clients_storage(frontendnodenames, mergenodenames)
if "signingnodes" in nodetype:
+ reloadableplopconfig.append((Symbol("storage_sign_quorum"), storage_sign_quorum))
allowed_clients += allowed_clients_signing(frontendnodenames, primarymergenodename)
services = [Symbol("sign")]
if "mergenodes" in nodetype:
@@ -409,6 +413,7 @@ def gen_config(nodename, config, localconfig):
reloadableplopconfig += [
(Symbol("allowed_clients"), list(allowed_clients)),
(Symbol("allowed_servers"), list(allowed_servers)),
+ (Symbol("storage_node_names"), list(storagenodenames)),
(Symbol("apikeys"), apikeys),
(Symbol("version"), config["version"]),
]