summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/x509.erl21
1 files changed, 12 insertions, 9 deletions
diff --git a/src/x509.erl b/src/x509.erl
index 4eb9755..0b32c4e 100644
--- a/src/x509.erl
+++ b/src/x509.erl
@@ -25,7 +25,12 @@ normalise_chain(AcceptableRootCerts, CertChain) ->
{false, Reason} ->
{error, Reason};
{true, Root} ->
- {ok, CertChain ++ Root}
+ case lists:member(Root, CertChain) of
+ true ->
+ {ok, CertChain};
+ false ->
+ {ok, CertChain ++ [Root]}
+ end
end.
-spec cert_string(binary()) -> string().
@@ -70,10 +75,8 @@ detox(LeafDer, ChainDer) ->
%% argument is: leaf cert in head, chain in tail. Order of certs in first
%% argument is irrelevant.
%%
-%% Return {false, Reason} or {true, ListWithRoot}. Note that
-%% ListWithRoot allways contain exactly one element -- a CA cert from
-%% first argument (AcceptableRootCerts) signing the root of the
-%% chain. FIXME: Any point in returning this as a list?
+%% Return {false, Reason} or {true, Root} where Root is a CA cert from
+%% AcceptableRootCerts signing the root of the chain.
normalise_chain(_, _, MaxChainLength) when MaxChainLength =< 0 ->
%% Chain too long.
{false, chain_too_long};
@@ -82,7 +85,7 @@ normalise_chain(AcceptableRootCerts, [TopCert], MaxChainLength) ->
case lists:member(TopCert, AcceptableRootCerts) of
true ->
%% Top cert is part of chain.
- {true, [TopCert]};
+ {true, TopCert};
false when MaxChainLength =< 1 ->
%% Chain too long.
{false, chain_too_long};
@@ -90,11 +93,11 @@ normalise_chain(AcceptableRootCerts, [TopCert], MaxChainLength) ->
%% Top cert _might_ be signed by a cert in truststore.
case signer(TopCert, AcceptableRootCerts) of
notfound -> {false, root_unknown};
- Root -> {true, [Root]}
+ Root -> {true, Root}
end
end;
-normalise_chain(AcceptableRootCerts, [BottomCert|Rest], MaxChainLength) ->
- case signed_by_p(BottomCert, hd(Rest)) of
+normalise_chain(AcceptableRootCerts, [Cert|Rest], MaxChainLength) ->
+ case signed_by_p(Cert, hd(Rest)) of
true -> normalise_chain(AcceptableRootCerts, Rest, MaxChainLength - 1);
false -> {false, signature_mismatch}
end.