summaryrefslogtreecommitdiff
path: root/src/catlfish.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/catlfish.erl')
-rw-r--r--src/catlfish.erl59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/catlfish.erl b/src/catlfish.erl
new file mode 100644
index 0000000..2ba9d58
--- /dev/null
+++ b/src/catlfish.erl
@@ -0,0 +1,59 @@
+%%% Copyright (c) 2014, NORDUnet A/S.
+%%% See LICENSE for licensing information.
+
+-module(catlfish).
+-export([add_chain/2, entries/2, entry_and_proof/2]).
+-include("$CTROOT/plop/include/plop.hrl").
+
+-define(PROTOCOL_VERSION, 0).
+
+-spec add_chain(binary(), list()) -> list().
+add_chain(LeafCert, CertChain) ->
+ Entry = #plop_entry{type = x509, data = LeafCert},
+ EDVectors = [serialise_tls_vector(X, 3) || X <- CertChain],
+ ExtraData = serialise_tls_vector(list_to_binary(EDVectors), 3),
+ SPT = plop:add(#timestamped_entry{entry = Entry}, ExtraData),
+ R = [{sct_version, ?PROTOCOL_VERSION},
+ {id, base64:encode(SPT#spt.logid)},
+ {timestamp, SPT#spt.timestamp},
+ {extensions, base64:encode("")},
+ {signature, base64:encode(plop:serialise(SPT#spt.signature))}],
+ binary_to_list(jiffy:encode({R})).
+
+-spec entries(non_neg_integer(), non_neg_integer()) -> list().
+entries(Start, End) ->
+ encode_entries(plop:get(Start, End)).
+
+-spec entry_and_proof(non_neg_integer(), non_neg_integer()) -> list().
+entry_and_proof(Index, TreeSize) ->
+ binary_to_list(
+ jiffy:encode(
+ case plop:inclusion_and_entry(Index, TreeSize) of
+ {ok, MTL, Extra, Path} ->
+ {[{leaf_input, base64:encode(plop:serialise(MTL))},
+ %% Extra data is already in TLS vector format.
+ {extra_data, base64:encode(Extra)},
+ {audit_path, [base64:encode(X) || X <- Path]}]};
+ {notfound, Msg} ->
+ {[{success, false},
+ {error_message, list_to_binary(Msg)}]}
+ end)).
+
+%% Private functions.
+-spec encode_entries([{mtl(), binary()}]) -> list().
+encode_entries(Entries) ->
+ binary_to_list(jiffy:encode({[{entries, unpack_entries(Entries)}]})).
+
+-spec unpack_entries([{mtl(), binary()}]) -> list().
+unpack_entries([]) ->
+ [];
+unpack_entries([H|T]) ->
+ {MTL, Extra} = H,
+ LeafInput = base64:encode(plop:serialise(MTL)),
+ ExtraData = base64:encode(Extra),
+ [{[{leaf_input, LeafInput}, {extra_data, ExtraData}]} | unpack_entries(T)].
+
+-spec serialise_tls_vector(binary(), non_neg_integer()) -> binary().
+serialise_tls_vector(Binary, LengthLen) ->
+ Length = byte_size(Binary),
+ <<Length:LengthLen/integer-unit:8, Binary/binary>>.