summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/catlfish.erl19
-rw-r--r--src/v1.erl18
-rw-r--r--src/x509.erl6
3 files changed, 23 insertions, 20 deletions
diff --git a/src/catlfish.erl b/src/catlfish.erl
index 4410203..d1f4425 100644
--- a/src/catlfish.erl
+++ b/src/catlfish.erl
@@ -10,7 +10,7 @@
-define(PROTOCOL_VERSION, 0).
-%%-type signature_type() :: certificate_timestamp | tree_hash | test. % uint8
+-type signature_type() :: certificate_timestamp | tree_hash | test. % uint8
-type entry_type() :: x509_entry | precert_entry | test. % uint16
-type leaf_type() :: timestamped_entry | test. % uint8
-type leaf_version() :: v1 | v2. % uint8
@@ -88,11 +88,9 @@ deserialise_entry_type(<<0:16>>) ->
deserialise_entry_type(<<1:16>>) ->
precert_entry.
--spec serialise_signature_type(certificate_timestamp|tree_hash) -> binary().
+-spec serialise_signature_type(signature_type()) -> binary().
serialise_signature_type(certificate_timestamp) ->
- <<0:8>>;
-serialise_signature_type(tree_hash) ->
- <<1:8>>.
+ <<0:8>>.
calc_sct(TimestampedEntry) ->
plop:serialise(
@@ -115,9 +113,10 @@ get_sct(Hash, TimestampedEntry) ->
calc_sct(TimestampedEntry)
end.
--spec add_chain(binary(), [binary()], normal|precert) -> nonempty_string().
+-spec add_chain(binary(), [binary()], normal|precert) -> {[{_,_},...]}.
add_chain(LeafCert, CertChain, Type) ->
- EntryHash = crypto:hash(sha256, [LeafCert | CertChain]),
+ CombinedChain = [LeafCert | CertChain],
+ EntryHash = crypto:hash(sha256, CombinedChain),
EntryType = case Type of
normal -> x509_entry;
precert -> precert_entry
@@ -134,7 +133,7 @@ add_chain(LeafCert, CertChain, Type) ->
ExtraData =
case Type of
normal -> CertChain;
- precert -> [LeafCert | CertChain]
+ precert -> CombinedChain
end,
LogEntry =
list_to_binary(
@@ -219,11 +218,11 @@ deserialise_signed_precert_entry(Data) ->
tbs_certificate = TBSCertificate},
RestData2}.
--spec entries(non_neg_integer(), non_neg_integer()) -> list().
+-spec entries(non_neg_integer(), non_neg_integer()) -> {[{entries, list()},...]}.
entries(Start, End) ->
{[{entries, x_entries(plop:get(Start, End))}]}.
--spec entry_and_proof(non_neg_integer(), non_neg_integer()) -> list().
+-spec entry_and_proof(non_neg_integer(), non_neg_integer()) -> {[{_,_},...]}.
entry_and_proof(Index, TreeSize) ->
case plop:inclusion_and_entry(Index, TreeSize) of
{ok, Entry, Path} ->
diff --git a/src/v1.erl b/src/v1.erl
index 29ccd41..2581804 100644
--- a/src/v1.erl
+++ b/src/v1.erl
@@ -126,11 +126,8 @@ add_chain(Input, Type) ->
case (catch mochijson2:decode(Input)) of
{error, E} ->
html("add-chain: bad input:", E);
- {struct, [{<<"chain">>, ChainBase64}]} ->
- case (catch [base64:decode(X) || X <- ChainBase64]) of
- {'EXIT', _} ->
- html("add-chain: invalid base64-encoded chain: ",
- [ChainBase64]);
+ {struct, [{<<"chain">>, ChainB64List}]} ->
+ case decode_chain(ChainB64List) of
[LeafCert | CertChain] ->
case x509:normalise_chain(catlfish:known_roots(),
[LeafCert|CertChain]) of
@@ -143,8 +140,15 @@ add_chain(Input, Type) ->
[x509:cert_string(LeafCert), Reason]),
html("add-chain: invalid chain", Reason)
end;
- Invalid ->
- html("add-chain: chain is not a list: ", [Invalid])
+ {invalid, ErrText} ->
+ html(io:format("add-chain: ~p", [ErrText]), [ChainB64List])
end;
_ -> html("add-chain: missing input: chain", Input)
end.
+
+-spec decode_chain(string()) -> {invalid, string()} | [binary()].
+decode_chain(B64List) ->
+ case (catch [base64:decode(X) || X <- B64List]) of
+ {'EXIT', _} -> {invalid, "invalid base64-encoded chain"};
+ L -> L
+ end.
diff --git a/src/x509.erl b/src/x509.erl
index 87d9c0c..7bbfb8e 100644
--- a/src/x509.erl
+++ b/src/x509.erl
@@ -56,7 +56,7 @@ self_signed(L) ->
lists:filter(fun(Cert) -> signed_by_p(Cert, Cert) end, L).
-spec detox(binary(), [binary()]) -> {binary(), binary()}.
-%% @doc Return the detoxed cet in LeafDer and the issuer leaf hash.
+%% @doc Return a detoxed LeafDer and its issuer.
detox(LeafDer, ChainDer) ->
detox_precert(LeafDer, nth(1, ChainDer), nth(2, ChainDer)).
@@ -64,7 +64,7 @@ detox(LeafDer, ChainDer) ->
%% Private functions.
-spec normalise_chain([binary()], [binary()], integer()) ->
- {false, reason()} | {true, list()}.
+ {false, reason()} | {true, [binary()]}.
%% @doc Verify that the leaf cert or precert has a valid chain back to
%% an acceptable root cert. The order of certificates in the second
%% argument is: leaf cert in head, chain in tail. Order of first
@@ -312,7 +312,7 @@ is_precert_signer(#'Certificate'{tbsCertificate = TBSCert}) ->
_ -> false
end.
--spec is_ca(#'TBSCertificate'{}) -> binary().
+-spec is_ca(#'TBSCertificate'{}) -> boolean().
is_ca(#'TBSCertificate'{extensions = Extensions}) ->
case pubkey_cert:select_extension(?'id-ce-basicConstraints', Extensions) of
#'Extension'{critical = true, extnValue = Val} ->