From dc6b383aa4a9cc1e2793c4d9f3be81bd676b7a20 Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Sat, 27 Sep 2014 15:45:14 +0200 Subject: wip --- src/db.erl | 126 +++++++++++++++----------- src/db.hrl | 19 ++-- src/ht.erl | 26 +++--- src/plop.erl | 283 +++++++++++++++-------------------------------------------- 4 files changed, 166 insertions(+), 288 deletions(-) (limited to 'src') diff --git a/src/db.erl b/src/db.erl index 3ab2d1b..ddebbeb 100644 --- a/src/db.erl +++ b/src/db.erl @@ -7,7 +7,8 @@ %% API. -export([start_link/0, stop/0]). -export([init_db/0, init_db/1, init_tables/0, init_tables/1]). --export([add/1, find/2, get_by_index/2, get_by_index_sorted/2, size/0]). +-export([add/4, size/0]). +-export([get_by_index/1, get_by_indices/3, get_by_leaf_hash/1, get_by_entry_hash/1]). %% API for testing. -export([dump/1, destroy_tables/0, info_tables/0, dump_to_file/1]). %% gen_server callbacks. @@ -72,24 +73,31 @@ stop() -> %%%%%%%%%%%%%%%%%%%% %% Public API. --spec add(plop()) -> {atomic, ok}. -add(Entry) -> - gen_server:call(?MODULE, {add, Entry}). +-spec add(binary(), binary(), binary(), non_neg_integer()) -> ok. +add(LeafHash, EntryHash, Data, Index) -> + gen_server:call(?MODULE, {add, {LeafHash, EntryHash, Data, Index}}). -%% @doc Find one entry. --spec find(entryhash | mtlhash | index, binary()) -> - [] | plop() | duplicate_hash_in_db. -find(Type, Hash) -> - gen_server:call(?MODULE, {find, Type, Hash}). +-spec get_by_indices(non_neg_integer(), + non_neg_integer(), + {sorted, true|false}) -> + [{non_neg_integer(), binary(), binary()}]. +get_by_indices(Start, End, {sorted, Sorted}) -> + gen_server:call(?MODULE, {get_by_indices, {Start, End, Sorted}}). --spec get_by_index(non_neg_integer(), non_neg_integer()) -> [{mtl(), binary()}]. -get_by_index(Start, End) -> - gen_server:call(?MODULE, {get_by_index, {Start, End}}). +-spec get_by_index(binary()) -> notfound | + {non_neg_integer(), binary(), binary()}. +get_by_index(Index) -> + gen_server:call(?MODULE, {get_by_index, Index}). --spec get_by_index_sorted(non_neg_integer(), non_neg_integer()) -> - [{mtl(), binary()}]. -get_by_index_sorted(Start, End) -> - gen_server:call(?MODULE, {get_by_index_sorted, {Start, End}}). +-spec get_by_leaf_hash(binary()) -> notfound | + {non_neg_integer(), binary(), binary()}. +get_by_leaf_hash(LeafHash) -> + gen_server:call(?MODULE, {get_by_leaf_hash, LeafHash}). + +-spec get_by_entry_hash(binary()) -> notfound | + {non_neg_integer(), binary(), binary()}. +get_by_entry_hash(EntryHash) -> + gen_server:call(?MODULE, {get_by_entry_hash, EntryHash}). %% Testing and debugging. dump(Table) -> @@ -117,50 +125,64 @@ terminate(_Reason, _State) -> handle_call(stop, _From, State) -> {stop, normal, stopped, State}; -handle_call({add, Entry}, _From, State) -> - F = fun() -> - mnesia:write(Entry) - end, - Res = mnesia:transaction(F), - {reply, Res, State}; - -handle_call({dump, Table}, _From, State) -> - F = fun() -> - Q = qlc:q([E || E <- mnesia:table(Table)]), - qlc:e(Q) +handle_call({add, {LeafHash, EntryHash, Data, Index}}, _From, State) -> + R = mnesia:transaction( + fun() -> + mnesia:write( + #plop{ + index = Index, + mtlhash = LeafHash, + entryhash = EntryHash, + logentry = Data}) + end), + {reply, R, State}; + +handle_call({get_by_indices, {Start, End, Sorted}}, _From, State) -> + R = case Sorted of + false -> + select_index(Start, End); + true -> + %% FIXME: RAM hog -- how bad is it? + lists:sort(select_index(Start, End)) end, - Res = mnesia:transaction(F), - {reply, Res, State}; + {reply, R, State}; -handle_call({find, entryhash, Hash}, _From, State) -> +handle_call({get_by_index, Index}, _From, State) -> {reply, - find_entry(fun() -> mnesia:index_read(plop, Hash, #plop.entryhash) end), - State}; -handle_call({find, mtlhash, Hash}, _From, State) -> - {reply, - find_entry(fun() -> mnesia:index_read(plop, Hash, #plop.mtlhash) end), + find_entry(fun() -> mnesia:read(plop, Index) end), State}; -handle_call({find, index, Index}, _From, State) -> + +handle_call({get_by_leaf_hash, LeafHash}, _From, State) -> {reply, - find_entry(fun() -> mnesia:read(plop, Index) end), + find_entry(fun() -> + mnesia:index_read(plop, LeafHash, #plop.mtlhash) + end), State}; -handle_call({get_by_index, {Start, End}}, _From, State) -> - Res = [{MTL, Extra} || [_Index, MTL, Extra] <- select_index(Start, End)], - {reply, Res, State}; +handle_call({get_by_entry_hash, EntryHash}, _From, State) -> + {reply, + find_entry(fun() -> + mnesia:index_read(plop, EntryHash, #plop.entryhash) + end), + State}; -handle_call({get_by_index_sorted, {Start, End}}, _From, State) -> - %% FIXME: RAM hog -- how bad is it? - Res = [{MTL, Extra} || [_Index, MTL, Extra] <- lists:sort(select_index(Start, End))], - {reply, Res, State}. +handle_call({dump, Table}, _From, State) -> + R = mnesia:transaction( + fun() -> + Q = qlc:q([E || E <- mnesia:table(Table)]), + qlc:e(Q) + end), + {reply, R, State}. %%%%%%%%%%%%%%%%%%%% %% Helper functions. +-spec select_index(non_neg_integer(), non_neg_integer()) -> + [{non_neg_integer(), binary(), binary()}]. select_index(Start, End) -> F = fun() -> - %% Get index, mtl and extra_data. - MatchHead = {plop, '$1', '_', '_', '$2', '$3', '_'}, + %% Get index, mtlhash and logentry. + MatchHead = {plop, '$1', '$2', '_', '$3'}, Guard = [{'>=', '$1', Start}, {'=<', '$1', End}], Result = ['$$'], mnesia:select(plop, [{MatchHead, Guard, Result}]) @@ -168,11 +190,13 @@ select_index(Start, End) -> {atomic, Res} = mnesia:transaction(F), Res. --spec find_entry(fun()) -> [] | plop() | duplicate_hash_in_db. +-spec find_entry(fun()) -> notfound | + {non_neg_integer(), binary(), binary()} | + duplicate. find_entry(Fun) -> {atomic, Result} = mnesia:transaction(Fun), - case length(Result) of - 0 -> []; - 1 -> hd(Result); - _ -> duplicate_hash_in_db % FIXME: log an error? + case Result of + [] -> notfound; + [#plop{index = I, mtlhash = H, logentry = E}] -> {I, H, E}; + _ -> duplicate end. diff --git a/src/db.hrl b/src/db.hrl index bea9131..9e09b66 100644 --- a/src/db.hrl +++ b/src/db.hrl @@ -1,17 +1,10 @@ %%% Copyright (c) 2014, NORDUnet A/S. %%% See LICENSE for licensing information. -%% @doc What's stored in the database. -%% 'index' is the primary key, 'entryhash' and 'mtlhash' are also -%% indexed, see init_tables/1. -%% NOTE: Don't change anything here without also fixing -%% select_index/2, which depends on the order of fields. +%% @doc What's stored in the database. +%% 'mtlhash' and 'entryhash' are also indexed, see init_tables/1. -record(plop, { - index :: non_neg_integer(), % Primary key. - entryhash :: binary(), % Hash over #plop_entry{} in mtl. - mtlhash :: binary(), % Merkle Tree Leaf hash. - mtl :: mtl(), % Merkle Tree Leaf. - extra_data :: binary(), % Data not part of mtl. - spt :: spt() % Signed Plop Timestamp. - }). --type plop() :: #plop{}. + index :: non_neg_integer(), % Primary key. + mtlhash :: binary(), % Merkle Tree Leaf hash. + entryhash :: binary(), % Hash for duplicate detection. + logentry :: binary()}). % Data. diff --git a/src/ht.erl b/src/ht.erl index 74f8ab4..cd4e57c 100644 --- a/src/ht.erl +++ b/src/ht.erl @@ -51,8 +51,8 @@ stop() -> gen_server:call(?MODULE, stop). size() -> gen_server:call(?MODULE, size). -add(Entry) -> - gen_server:call(?MODULE, {add, Entry}). +add(Hash) -> + gen_server:call(?MODULE, {add, Hash}). root() -> gen_server:call(?MODULE, root). root(Version) -> @@ -91,8 +91,8 @@ handle_call(stop, _From, State) -> {stop, normal, stopped, State}; handle_call(size, _From, State) -> {reply, State#tree.version + 1, State}; -handle_call({add, Entry}, _From, State) -> - {reply, ok, add(State, Entry)}; +handle_call({add, Hash}, _From, State) -> + {reply, ok, add(State, Hash)}; handle_call(root, _From, State) -> {NewState, Hash} = head(State, State#tree.version), {reply, Hash, NewState}; @@ -245,11 +245,10 @@ first_left_node(Layer, Index, BAL) -> false -> {Layer, Index} end. -%% @doc Add an entry but don't update the tree. +%% @doc Add a hash but don't update the tree. -spec add(tree(), binary()) -> tree(). -add(Tree = #tree{version = V, store = Store}, Entry) -> - Tree#tree{version = V + 1, - store = ts:add(Store, 0, mkleafhash(Entry))}. +add(Tree = #tree{version = V, store = Store}, Hash) -> + Tree#tree{version = V + 1, store = ts:add(Store, 0, Hash)}. %% @doc Return a new tree. -spec new(list()) -> tree(). @@ -261,13 +260,14 @@ new([-1]) -> new([]); %% Initialise tree from db. new([Version]) when is_integer(Version) -> - foldl(fun(MTL, Tree) -> + foldl(fun(Hash, Tree) -> %% Return value becomes Tree in next invocation. - add(Tree, plop:serialise(MTL)) - end, new([]), [X || {X, _} <- db:get_by_index_sorted(0, Version)]); -%% Initialise tree from List. + add(Tree, Hash) + end, new([]), [H || {_I, H, _E} <- + db:get_by_indices(0, Version, {sorted, true})]); +%% Initialise tree from List with hashes. new([List]) when is_list(List) -> - foldl(fun(SerialisedMTL, Tree) -> add(Tree, SerialisedMTL) end, + foldl(fun(Hash, Tree) -> add(Tree, Hash) end, new([]), List). update(Tree) -> diff --git a/src/plop.erl b/src/plop.erl index 5443183..b59e19b 100644 --- a/src/plop.erl +++ b/src/plop.erl @@ -26,7 +26,8 @@ %% API. -export([start_link/2, stop/0]). -export([get_logid/0, serialise/1]). --export([add/2, sth/0, get/2, consistency/2, inclusion/2, inclusion_and_entry/2]). +-export([add/4, sth/0, get/1, get/2, spt/2, consistency/2, inclusion/2, inclusion_and_entry/2]). +-export([generate_timestamp/0]). %% API for tests. -export([read_keyfile_rsa/2, read_keyfiles_ec/2]). -export([testing_get_pubkey/0]). @@ -35,7 +36,7 @@ handle_cast/2, handle_info/2, code_change/3]). -include("$CTROOT/plop/include/plop.hrl"). --include("db.hrl"). +%%-include("db.hrl"). -include_lib("public_key/include/public_key.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -46,6 +47,12 @@ privkey :: public_key:rsa_private_key(), logid :: binary()}). +%%%%% moved from plop.hrl, maybe remove +-define(PLOPVERSION, 0). +-type signature_type() :: certificate_timestamp | tree_hash | test. % uint8 +%%%%% + + %% @doc The parts of an STH which is to be signed. Used as the %% interface to plop:sth/1, for testing. -record(sth_signed, { @@ -57,17 +64,6 @@ }). -type sth_signed() :: #sth_signed{}. -%% @doc What's signed in an SPT. Used for serialisation before hasning -%% and signing. FIXME: Overlapping #spt{} -- merge somehow? --record(spt_signed, { - version = ?PLOPVERSION :: non_neg_integer(), - signature_type :: signature_type(), - timestamp :: integer(), - entry_type :: entry_type(), - signed_entry :: binary() - }). --type spt_signed() :: #spt_signed{}. - start_link(Keyfile, Passphrase) -> gen_server:start_link({local, ?MODULE}, ?MODULE, [Keyfile, Passphrase], []). @@ -101,22 +97,31 @@ terminate(_Reason, _State) -> ok. %%%%%%%%%%%%%%%%%%%% --spec add(timestamped_entry(), binary()) -> spt(). -add(Entry, ExtraData) -> - gen_server:call(?MODULE, {add, {Entry, ExtraData}}). +-spec add(binary(), binary(), binary(), binary()) -> ok. +add(LogEntry, TreeLeafHash, EntryHash, DataToSign) -> + gen_server:call(?MODULE, + {add, {LogEntry, TreeLeafHash, EntryHash, DataToSign}}). + sth() -> gen_server:call(?MODULE, {sth, []}). --spec get(non_neg_integer(), non_neg_integer()) -> [{mtl(), binary()}]. + +-spec get(non_neg_integer(), non_neg_integer()) -> + [{non_neg_integer(), binary(), binary()}]. get(Start, End) -> - gen_server:call(?MODULE, {get, {Start, End}}). + gen_server:call(?MODULE, {get, {index, Start, End}}). + +get(Hash) -> + gen_server:call(?MODULE, {get, {hash, Hash}}). + consistency(TreeSizeFirst, TreeSizeSecond) -> gen_server:call(?MODULE, {consistency, {TreeSizeFirst, TreeSizeSecond}}). -spec inclusion(binary(), non_neg_integer()) -> - {ok, mtl()} | {notfound, string()}. + {ok, {binary(), binary()}} | {notfound, string()}. inclusion(Hash, TreeSize) -> gen_server:call(?MODULE, {inclusion, {Hash, TreeSize}}). -spec inclusion_and_entry(non_neg_integer(), non_neg_integer()) -> - {ok, {mtl(), binary()}} | {notfound, string()}. + {ok, {binary(), binary()}} | + {notfound, string()}. inclusion_and_entry(Index, TreeSize) -> gen_server:call(?MODULE, {inclusion_and_entry, {Index, TreeSize}}). get_logid() -> @@ -124,118 +129,61 @@ get_logid() -> testing_get_pubkey() -> gen_server:call(?MODULE, {test, pubkey}). %%%%%%%%%%%%%%%%%%%% -handle_call(stop, _From, State) -> - {stop, normal, stopped, State}; - -%% FIXME: What's the right interface for add()? Need to be able to set -%% version and signature type, at least. That's missing from -%% #timestamped_entry, so add it somehow. -handle_call({add, - {#timestamped_entry{timestamp = Timestamp_in, entry = Entry}, - ExtraData}}, - _From, - State = #state{privkey = Privkey, logid = LogID}) -> - TimestampedEntry = #timestamped_entry{ - timestamp = timestamp(Timestamp_in), - entry = Entry}, - {ok, SPT} = do_add(TimestampedEntry, ExtraData, Privkey, LogID), - {reply, SPT, State}; +handle_call(stop, _From, Plop) -> + {stop, normal, stopped, Plop}; -handle_call({sth, Data}, _From, - Plop = #state{privkey = PrivKey}) -> - {reply, sth(PrivKey, Data), Plop}; +handle_call({get, {index, Start, End}}, _From, Plop) -> + {reply, db:get_by_indices(Start, End, {sorted, false}), Plop}; -handle_call({get, {Start, End}}, _From, Plop) -> - {reply, db:get_by_index(Start, End), Plop}; +handle_call({get, {hash, EntryHash}}, _From, Plop) -> + {reply, db:get_by_entry_hash(EntryHash), Plop}; handle_call({get, logid}, _From, Plop = #state{logid = LogID}) -> {reply, LogID, Plop}; +handle_call({add, {LogEntry, TreeLeafHash, EntryHash}}, _From, Plop) -> + ok = ht:add(TreeLeafHash), + ok = db:add(TreeLeafHash, EntryHash, LogEntry, ht:size()), + {reply, ok, Plop}; + +handle_call({sth, Data}, _From, + Plop = #state{privkey = PrivKey}) -> + {reply, sth(PrivKey, Data), Plop}; + handle_call({consistency, {First, Second}}, _From, Plop) -> {reply, ht:consistency(First - 1, Second - 1), Plop}; handle_call({inclusion, {Hash, TreeSize}}, _From, Plop) -> - R = case db:find(mtlhash, Hash) of - [] -> + R = case db:get_by_entry_hash(Hash) of + notfound -> {notfound, "Unknown hash"}; % FIXME: include Hash - {plop, I, _EntryHash, _MTLHash, _MTL, _ExtraData, _SPT} -> + {I, _MTLHash, _Entry} -> {ok, I, ht:path(I, TreeSize - 1)} end, {reply, R, Plop}; handle_call({inclusion_and_entry, {Index, TreeSize}}, _From, Plop) -> - R = case db:find(index, Index) of - [] -> + R = case db:get_by_index(Index) of + notfound -> {notfound, "Unknown index"}; % FIXME: include Index - {plop, I, _EntryHash, _MTLHash, MTL, ExtraData, _SPT} -> - {ok, MTL, ExtraData, ht:path(I, TreeSize - 1)} - end, + {I, _MTLHash, Entry} -> + {ok, Entry, ht:path(I, TreeSize - 1)} + end, {reply, R, Plop}; handle_call({test, pubkey}, _From, Plop = #state{pubkey = PK}) -> {reply, PK, Plop}. -%%%%%%%%%%%%%%%%%%%% -%% db_get_single_entry(N) -> -%% [#mtl{entry = #timestamped_entry{entry = #plop_entry{data = Data}}}] = -%% db:get_by_index(N, N), -%% Data. - --spec do_add(timestamped_entry(), - binary(), - public_key:rsa_private_key(), - binary()) -> {ok, spt()} | {error, any()}. -do_add(TimestampedEntry, ExtraData, Privkey, LogID) -> - DB_hash = crypto:hash(sha256, - serialise(TimestampedEntry#timestamped_entry.entry)), - Record = db:find(entryhash, DB_hash), - case Record of - #plop{index = _I, mtl = MTL, spt = SPT} -> - %% Costly database consistency checking. FIXME: Remove. - Record = Record#plop{ - entryhash = DB_hash, - mtlhash = ht:leaf_hash(serialise(MTL)), - mtl = MTL}, - {ok, SPT}; - [] -> - NewSPT = spt(LogID, Privkey, TimestampedEntry), - MTL = #mtl{entry = TimestampedEntry}, - MTLtext = serialise(MTL), - DB_data = #plop{index = ht:size(), - entryhash = DB_hash, - mtlhash = ht:leaf_hash(MTLtext), - mtl = MTL, - extra_data = ExtraData, - spt = NewSPT}, - {atomic, ok} = db:add(DB_data), - {ht:add(MTLtext), NewSPT}; - Err -> {error, Err} - end. - %% @doc Signed Plop Timestamp, conformant to an SCT in RFC6962 3.2 and %% RFC5246 4.7. --spec spt(binary(), public_key:rsa_private_key(), timestamped_entry()) -> spt(). -spt(LogID, PrivKey, #timestamped_entry{ - timestamp = Timestamp, - entry = #plop_entry{type = EntryType, data = EntryData} - }) -> - BinToSign = serialise(#spt_signed{ - signature_type = certificate_timestamp, - timestamp = Timestamp, - entry_type = EntryType, - signed_entry = EntryData}), - Signature = #signature{ - algorithm = #sig_and_hash_alg{ - hash_alg = sha256, - signature_alg = ecdsa}, - signature = signhash(BinToSign, PrivKey)}, - #spt{ - version = ?PLOPVERSION, - logid = LogID, - timestamp = Timestamp, - signature = Signature}. +-spec spt(public_key:ec_private_key(), binary()) -> signature(). +spt(PrivKey, SerialisedData) -> + #signature{algorithm = #sig_and_hash_alg{ + hash_alg = sha256, + signature_alg = ecdsa}, + signature = signhash(SerialisedData, PrivKey)}. %% @doc Signed Tree Head as specified in RFC6962 section 3.2. -spec sth(#'ECPrivateKey'{}, sth_signed() | list()) -> sth(). @@ -336,15 +284,6 @@ signature_type(certificate_timestamp) -> 0; signature_type(tree_hash) -> 1; signature_type(test) -> 2. --spec entry_type(entry_type()) -> integer(). -entry_type(x509) -> 0; -entry_type(precert) -> 1; -entry_type(test) -> 2. - --spec leaf_type(leaf_type()) -> integer(). -leaf_type(timestamped_entry) -> 0; -leaf_type(test) -> 1. - -spec hash_alg_type(hash_alg_type()) -> integer(). hash_alg_type(none) -> 0; hash_alg_type(md5) -> 1; @@ -360,6 +299,7 @@ signature_alg_type(rsa) -> 1; signature_alg_type(dsa) -> 2; signature_alg_type(ecdsa) -> 3. +%% TODO: Remove. -spec timestamp(now | integer()) -> integer(). timestamp(Timestamp) -> case Timestamp of @@ -371,58 +311,15 @@ timestamp(Timestamp) -> _ -> Timestamp end. -serialise_tls_vector(Binary, LengthLen) -> - Length = byte_size(Binary), - <>. +-spec generate_timestamp() -> integer(). +generate_timestamp() -> + {NowMegaSec, NowSec, NowMicroSec} = now(), + trunc(NowMegaSec * 1.0e9 + + NowSec * 1.0e3 + + NowMicroSec / 1.0e3). --spec serialise(plop_entry() | timestamped_entry() | mtl() | - spt() | spt_signed() | sth() | sth_signed() | - sig_and_hash_alg() | signature()) -> binary(). -serialise(#plop_entry{ - type = TypeAtom, - data = Data - }) -> - EntryType = entry_type(TypeAtom), - DataVector = serialise_tls_vector(Data, 3), - <>; -serialise(#timestamped_entry{ - timestamp = Timestamp, - entry = PlopEntry - }) -> - Extensions = <<>>, - list_to_binary([<>, serialise(PlopEntry), serialise_tls_vector(Extensions, 2)]); -serialise(#spt{ - version = Version, - logid = LogID, - timestamp = Timestamp, - signature = Signature - }) -> - list_to_binary([<>, - serialise(Signature)]); -serialise(#spt_signed{ - version = Version, - signature_type = SigtypeAtom, - timestamp = Timestamp, - entry_type = EntrytypeAtom, - signed_entry = Entry - }) -> - Sigtype = signature_type(SigtypeAtom), - Entrytype = entry_type(EntrytypeAtom), - Extensions = <<>>, - list_to_binary( - [<>, - serialise_tls_vector(Entry, 3), - serialise_tls_vector(Extensions, 2)]); -serialise(#mtl{ % Merkle Tree Leaf. - version = Version, - leaf_type = TypeAtom, - entry = TimestampedEntry - }) -> - LeafType = leaf_type(TypeAtom), - list_to_binary([<>, serialise(TimestampedEntry)]); +-spec serialise(sth() | sth_signed() | sig_and_hash_alg() | signature()) -> + binary(). serialise(#sth_signed{ % Signed Tree Head. version = Version, signature_type = SigtypeAtom, @@ -456,48 +353,12 @@ serialise(#signature{ %%%%%%%%%%%%%%%%%%%% %% Internal tests. For more tests see ../test/. -serialise_test_() -> - [?_assertEqual( - <<0:8, 0:8, 0:64, 0:16, "foo">>, - serialise(#spt_signed{ - version = 0, - signature_type = certificate_timestamp, - timestamp = 0, - entry_type = x509, - signed_entry = <<"foo">>}))]. -add_test() -> - {ok, S} = init([?TESTPRIVKEYFILE, ?TESTPUBKEYFILE]), - - Data1 = <<"some data">>, - ExtraData1 = <<"some extra data">>, - {_Tree, SPT} = - do_add(#timestamped_entry{ - timestamp = 4711, - entry = #plop_entry{type = test, data = Data1}}, - ExtraData1, - S#state.privkey, - S#state.logid), - {_Tree1, SPT1} = - do_add(#timestamped_entry{ - timestamp = 4712, - entry = #plop_entry{type = test, data = Data1}}, - ExtraData1, - S#state.privkey, - S#state.logid), - ?assertEqual(SPT, SPT1), - - TE = #timestamped_entry{ - timestamp = 0, - entry = #plop_entry{type = test, data = <<"some data">>}}, - SPTeq1 = spt(S#state.logid, S#state.privkey, TE), - SPTeq2 = spt(S#state.logid, S#state.privkey, TE), - ?assertNotEqual(SPTeq1, SPTeq2), % DSA signatures differ! - ok. - -%% add_random_data(N, Size) -> -%% lists:foreach( -%% fun(_) -> plop:add(#timestamped_entry -%% {entry = #plop_entry -%% {type = test, -%% data = crypto:rand_bytes(Size)}}) end, -%% lists:seq(1, N)). +%% serialise_test_() -> +%% [?_assertEqual( +%% <<0:8, 0:8, 0:64, 0:16, "foo">>, +%% serialise(#spt_signed{ +%% version = 0, +%% signature_type = certificate_timestamp, +%% timestamp = 0, +%% entry_type = x509, +%% signed_entry = <<"foo">>}))]. -- cgit v1.1