diff options
-rw-r--r-- | src/v1.erl | 64 |
1 files changed, 44 insertions, 20 deletions
@@ -1,15 +1,20 @@ +%%% @doc Certificate Transparency (RFC 6962) + -module(v1). --export([add_chain/3, add_pre_chain/3, get_sth/3, - get_sth_consistency/3, get_proof_by_hash/3, get_entries/3, - get_roots/3, get_entry_and_proof/3]). +%% API (URL) +-export(['add-chain'/3, 'add-pre-chain'/3, 'get-sth'/3, + 'get-sth-consistency'/3, 'get-proof-by-hash'/3, 'get-entries'/3, + 'get-roots'/3, 'get-entry-and-proof'/3]). +%% Testing -- FIXME: remove -export([hello/3]). + -include("$CTROOT/plop/include/plop.hrl"). -define(PROTOCOL_VERSION, 0). -%% Public functions. -add_chain(SessionID, _Env, Input) -> +%% Public functions, i.e. part of URL. +'add-chain'(SessionID, _Env, Input) -> Res = case (catch jiffy:decode(Input)) of - {error, E} -> html("add-chain: bad input; see RFC 6962", E); + {error, E} -> html("add-chain: bad input:", E); {[{<<"chain">>, Chain}]} -> Entry = #plop_entry{type = x509, data = list_to_binary(Chain)}, @@ -18,18 +23,17 @@ add_chain(SessionID, _Env, Input) -> {id, base64:encode(SPT#spt.logid)}, {timestamp, SPT#spt.timestamp}, {extensions, base64:encode("")}, - {signature, - base64:encode( - list_to_binary(plop:serialise(SPT#spt.signature)))}], + {signature, base64:encode( + plop:serialise(SPT#spt.signature))}], binary_to_list(jiffy:encode({R})); - _ -> html("add-chain: missing input: chain; see RFC 6962", Input) + _ -> html("add-chain: missing input: chain", Input) end, deliver(SessionID, Res). -add_pre_chain(SessionID, _Env, _Input) -> +'add-pre-chain'(SessionID, _Env, _Input) -> niy(SessionID). -get_sth(SessionID, _Env, _Input) -> +'get-sth'(SessionID, _Env, _Input) -> #sth{ treesize = Treesize, timestamp = Timestamp, @@ -39,19 +43,29 @@ get_sth(SessionID, _Env, _Input) -> {timestamp, Timestamp}, {sha256_root_hash, base64:encode(Roothash)}, {tree_head_signature, base64:encode( - list_to_binary(plop:serialise(Signature)))}], + plop:serialise(Signature))}], deliver(SessionID, binary_to_list(jiffy:encode({R}))). -get_sth_consistency(SessionID, _Env, _Input) -> +'get-sth-consistency'(SessionID, _Env, _Input) -> niy(SessionID). -get_proof_by_hash(SessionID, _Env, _Input) -> +'get-proof-by-hash'(SessionID, _Env, _Input) -> niy(SessionID). -get_entries(SessionID, _Env, _Input) -> - niy(SessionID). -get_entry_and_proof(SessionID, _Env, _Input) -> +'get-entries'(SessionID, _Env, Input) -> + R = case lists:sort(httpd:parse_query(Input)) of + [{"end", EndInput}, {"start", StartInput}] -> + {Start, _} = string:to_integer(StartInput), + {End, _} = string:to_integer(EndInput), + case lists:member(error, [Start, End]) of + true -> html("get-entries: bad input:", [Start, End]); + _ -> encode_entries(plop:get(Start, End)) + end; + _ -> html("get-entries: bad input:", Input) + end, + deliver(SessionID, R). +'get-entry-and-proof'(SessionID, _Env, _Input) -> niy(SessionID). -get_roots(SessionID, _Env, _Input) -> +'get-roots'(SessionID, _Env, _Input) -> R = [{certificates, []}], % NIY. deliver(SessionID, binary_to_list(jiffy:encode({R}))). @@ -65,9 +79,19 @@ hello(SessionID, Env, Input) -> "<p>Env: ~p~n" ++ "<p>Input, raw: ~p~n" ++ "<p>Input, parsed: ~p~n" ++ - "</body></html>", [SessionID, Env, Input, Query])). + "</body></html>", + [SessionID, Env, Input, Query])). %% Private functions. +encode_entries(Entries) -> + binary_to_list(jiffy:encode({[{entries, encode_entries2(Entries)}]})). +encode_entries2([H|T]) -> + LeafInput = base64:encode(plop:serialise(H)), + ExtraData = "", + [{[{leaf_input, LeafInput}, {extra_data, ExtraData}]} | encode_entries2(T)]; +encode_entries2([]) -> + []. + html(Text, Input) -> io_lib:format( "Content-Type: text/html\r\n\r\n" ++ |