diff options
-rw-r--r-- | src/catlfish.erl | 50 | ||||
-rwxr-xr-x | tools/compileconfig.py | 2 | ||||
-rwxr-xr-x | verifycert.erl | 8 |
3 files changed, 49 insertions, 11 deletions
diff --git a/src/catlfish.erl b/src/catlfish.erl index 5865626..0a14961 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, chain_from_entry/1]). +-export([entryhash_from_entry/1, verify_entry/1, verify_entry/2]). -include_lib("eunit/include/eunit.hrl"). -define(PROTOCOL_VERSION, 0). @@ -249,10 +249,7 @@ deserialise_extra_data(ExtraData) -> {E, Rest} = decode_tls_vector(ExtraData, 3), [E | deserialise_extra_data(Rest)]. -chain_from_entry(Entry) -> - {MTLText, ExtraDataPacked} = unpack_entry(Entry), - {ExtraData, <<>>} = decode_tls_vector(ExtraDataPacked, 3), - MTL = deserialise_mtl(MTLText), +chain_from_mtl_extradata(MTL, ExtraData) -> TimestampedEntry = MTL#mtl.entry, Chain = deserialise_extra_data(ExtraData), Data = @@ -265,8 +262,49 @@ chain_from_entry(Entry) -> end, Data. +mtl_and_extra_from_entry(Entry) -> + {MTLText, ExtraDataPacked} = unpack_entry(Entry), + {ExtraData, <<>>} = decode_tls_vector(ExtraDataPacked, 3), + MTL = deserialise_mtl(MTLText), + {MTL, ExtraData}. + +verify_mtl(MTL, LeafCert, CertChain) -> + Timestamp = MTL#mtl.entry#timestamped_entry.timestamp, + EntryType = MTL#mtl.entry#timestamped_entry.entry_type, + TSE = timestamped_entry(Timestamp, EntryType, LeafCert, CertChain), + case MTL of + #mtl{leaf_version = v1, + leaf_type = timestamped_entry, + entry = TSE} -> + ok; + _ -> + error + end. + +verify_entry(Entry) -> + RootCerts = known_roots(), + verify_entry(Entry, RootCerts). + +verify_entry(Entry, RootCerts) -> + {MTL, ExtraData} = mtl_and_extra_from_entry(Entry), + Chain = chain_from_mtl_extradata(MTL, ExtraData), + + case x509:normalise_chain(RootCerts, Chain) of + {ok, [LeafCert|CertChain]} -> + case verify_mtl(MTL, LeafCert, CertChain) of + ok -> + {ok, ht:leaf_hash(serialise(MTL))}; + error -> + {error, "MTL verification failed"} + end; + {error, Reason} -> + {error, Reason} + end. + entryhash_from_entry(Entry) -> - crypto:hash(sha256, chain_from_entry(Entry)). + {MTL, ExtraData} = mtl_and_extra_from_entry(Entry), + Chain = chain_from_mtl_extradata(MTL, ExtraData), + crypto:hash(sha256, Chain). %% Private functions. -spec unpack_entry(binary()) -> {binary(), binary()}. diff --git a/tools/compileconfig.py b/tools/compileconfig.py index a8fe408..574b158 100755 --- a/tools/compileconfig.py +++ b/tools/compileconfig.py @@ -211,6 +211,8 @@ def gen_config(nodename, config, localconfig): (Symbol("sth_path"), paths["db"] + "sth"), (Symbol("entryhash_from_entry"), (Symbol("catlfish"), Symbol("entryhash_from_entry"))), + (Symbol("verify_entry"), + (Symbol("catlfish"), Symbol("verify_entry"))), ] signingnodes = config["signingnodes"] diff --git a/verifycert.erl b/verifycert.erl index f2f679d..e7cdd86 100755 --- a/verifycert.erl +++ b/verifycert.erl @@ -1,6 +1,6 @@ #!/usr/bin/env escript %% -*- erlang -*- -%%! -pa lib/catlfish-0.8.0-dev.ez/catlfish-0.8.0-dev/ebin -pa lib/lager-2.1.1.ez/lager-2.1.1/ebin +%%! -pa lib/catlfish-0.8.0-dev.ez/catlfish-0.8.0-dev/ebin -pa lib/lager-2.1.1.ez/lager-2.1.1/ebin -pa lib/plop-0.7.0.ez/plop-0.7.0/ebin write_reply(Bin) -> Length = size(Bin), @@ -8,10 +8,8 @@ write_reply(Bin) -> verify(RootCerts, DBEntry) -> try - Chain = catlfish:chain_from_entry(DBEntry), - %% XXX: doesn't verify that MTL is derived from Chain - case x509:normalise_chain(RootCerts, Chain) of - {ok, _} -> + case catlfish:verify_entry(DBEntry, RootCerts) of + {ok, _MTLHash} -> write_reply(<<0:8>>); {error, Reason} -> ReasonBin = list_to_binary(io_lib:format("~p", [Reason])), |