diff options
-rw-r--r-- | src/catlfish.erl | 69 | ||||
-rwxr-xr-x | tools/compileconfig.py | 11 |
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"]), ] |