[erlang-questions] Erlang SSL and Invalid Certificate Chains
Dmitry Kolesnikov
dmkolesnikov@REDACTED
Mon Aug 11 16:22:18 CEST 2014
Hello,
Have you tried to bypass an issue with custom verify_fun ?
- Dmitry
On 11 Aug 2014, at 17:16, Ben Murphy <benmmurphy@REDACTED> wrote:
> (I originally sent this to erlang-bugs but it doesn't look like it
> made it there)
>
> We have a problem where an SSL server sends back a certificate chain
> that is invalid according to the TLS 1.2 specification and erlang
> rejects this chain with an unknown ca error. However, openssl and
> browsers will accept this chain because they are less strict about
> validation.
>
> The chain looks something like:
>
> 0. Server Cert issued by Intermediate Cert
> 1. Intermediate Cert issued by Root Cert
> 2. Root Cert issued by Root Cert
> 3. Unrelated certificate
> 4. Unrelated certificate
>
> Which is invalid according to: http://www.ietf.org/rfc/rfc5246.txt
>
> certificate_list
> This is a sequence (chain) of certificates. The sender's
> certificate MUST come first in the list. Each following
> certificate MUST directly certify the one preceding it. Because
> certificate validation requires that root keys be distributed
> independently, the self-signed certificate that specifies the root
> certificate authority MAY be omitted from the chain, under the
> assumption that the remote end must already possess it in order to
> validate it in any case
>
> Looking at the openssl code they start at the beginning of the chain
> then recursively find the issuer in order to build up a chain. While
> the erlang ssl code assumes the last certificate in the chain is the
> root CA (ssl_certificate:trusted_cert_and_path).
>
> Maybe this is more of a feature request than a bug. But I was
> wondering if it would be possible for erlang to either accept these
> dodgy chains, provide an option when connecting to accept these dodgy
> chains or allow users to supply a function to modify the certificate
> chain before validation takes place.
>
> I have some code that I've been mucking around with to fix up chains
> but I haven't done thorough testing of it.
>
> fix_path(CertChain) ->
> DecodedCerts = [ {public_key:pkix_decode_cert(Cert, otp), Cert} ||
> Cert <- CertChain ],
> [Peer | RestOfChain] = DecodedCerts,
> lists:reverse(make_chain(Peer, RestOfChain, [])).
>
> make_chain({OtpCert, Cert}, CertChain, ResultChain) ->
> case public_key:pkix_is_self_signed(OtpCert) of
> true ->
> [Cert | ResultChain ];
> false ->
> case find_issuer(OtpCert, CertChain) of
> {ok, NewCert, NewCertChain} ->
> % we remove the cert that was found from the chain
> % to prevent infinite loops where a chain becomes
> % a loop
> make_chain(NewCert, NewCertChain, [Cert | ResultChain]);
> {error, issuer_not_found} ->
> % assume it is the 'trusted' certificate
> [Cert | ResultChain]
> end
> end.
>
> find_issuer(OtpCert, CertChain) ->
> {Not, Maybe} = lists:splitwith(fun({Candidate, _}) ->
> not public_key:pkix_is_issuer(OtpCert, Candidate)
> end, CertChain),
>
> case Maybe of
> [Issuer | Rest] ->
> {ok, Issuer, Not ++ Rest};
> [] ->
> {error, issuer_not_found}
> end.
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
More information about the erlang-questions
mailing list