[erlang-questions] Erlang SSL and Invalid Certificate Chains

Ben Murphy <>
Tue Aug 12 12:01:11 CEST 2014


I agree that these chains break the spec. The problem is almost
everyone accepts these chains. So if you don't accept these chains
then you are going to run into compatibility issues. I've tested
safari/firefox/chrome/openssl/golang/java and all these
implementations accept these chains.

If you look at the implementations this is a deliberately coded feature:

http://golang.org/src/pkg/crypto/x509/verify.go
func (c *Certificate) Verify(opts VerifyOptions) (chains
[][]*Certificate, err error) {

I think most implementations treat the first certificate as the
clients certificate and the rest of the certificates as possible
intermediaries between the clients certificate and a trusted
certificate and try to build a chain based on that.


On Tue, Aug 12, 2014 at 9:40 AM, Andreas Schultz <> wrote:
> Hi Ben,
>
> ----- Original Message -----
>> Hi Ingela,
>>
>> So the real server I'm having trouble with is not public. But I have a
>> made up server that is configured in a similar fashion.
>>
>> https://test.fonix.io/
>>
>> I've just added an extra cert to the end of the chain. This validates
>> correctly in chrome and with curl on the command line.
>>
>> https://test.fonix.io:444/
>>
>> Where this is an extra cert added to the end of the chain and the
>> order of the chain is broken. This validates correctly in chrome and
>> with curl on the command line.
>>
>> I think some browsers/ssl implementations may also accept chains where
>> the first certificate in chain is not the client certificate but nginx
>> won't let me test this scenario :)
>
> That would violate the standard. from RFC 2246 (TLS 1.0), Section 7.4.2:
>
>    certificate_list
>        This is a sequence (chain) of X.509v3 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 which specifies the
>        root certificate authority may optionally be omitted from the
>        chain, under the assumption that the remote end must already
>        possess it in order to validate it in any case.
>
> RFC 5246 (TLS 1.2) adds this:
>
>    The following rules apply to the certificates sent by the server:
>
>    -  The certificate type MUST be X.509v3, unless explicitly negotiated
>       otherwise (e.g., [TLSPGP]).
>
>    -  The end entity certificate's public key (and associated
>       restrictions) MUST be compatible with the selected key exchange
>       algorithm.
>
> So the ordering is strict, no unrelated certificates are permitted
> within the chain. This wording leaves it open whether a unrelated
> certificated is permitted at the end of the chain. However, I would
> rather choose the stricter interpretation and consider any unrelated
> certificate an error.
>
> The certificates on your server port 443 are:
>
>  0 s:/serialNumber=oVMlbmYif-Pcg7kbO6LFKlAd0LjtU6Uw/C=GB/ST=London/L=London/O=Orca Digital Ltd/OU=IT/CN=*.fonix.io
>    i:/C=US/O=GeoTrust, Inc./CN=GeoTrust SSL CA
>  1 s:/C=US/O=GeoTrust, Inc./CN=GeoTrust SSL CA
>    i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
>  2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
>    i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
>  3 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
>    i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
>
> The chain for Number 0, 1 and 2 seems to be ok. However the Number 3
> certificate is obsolete and IMHO an error.
>
>
> The certificates on your server port 444 are:
>
> Certificate chain
>  0 s:/serialNumber=oVMlbmYif-Pcg7kbO6LFKlAd0LjtU6Uw/C=GB/ST=London/L=London/O=Orca Digital Ltd/OU=IT/CN=*.fonix.io
>    i:/C=US/O=GeoTrust, Inc./CN=GeoTrust SSL CA
>  1 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
>    i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
>  2 s:/C=US/O=GeoTrust, Inc./CN=GeoTrust SSL CA
>    i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
>  3 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
>    i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
>
> So, Number 0 is ok, Number 1 is not the issuer of Number 0, so this IS
> invalid, Number 2 is the issuer of Number 0, and Number 3 is unrelated
> to any of them.
>
> To summarize:
>
> I believe Erlang is correct rejecting those certificate chains and
> Chrome and wget (or probably really OpenSSL) need to be fixed to
> properly reject those.
>
> Andreas
>
>>
>> I don't think I would be able to use verify_fun to safely ignore
>> arbitrary extra certificates while not accepting untrusted chains. I
>> believe I would need a whitelist of extra certificates to ignore which
>> is problematic because things will explode when the server makes
>> changes that they think are 'safe'.
>>
>> On Mon, Aug 11, 2014 at 3:59 PM, Ingela Andin <> wrote:
>> > HI!
>> >
>> > 2014-08-11 16:16 GMT+02:00 Ben Murphy <>:
>> >
>> >> (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
>> >
>> >
>> >
>> > What server is sending such a chain? Could you give me a concrete
>> > example,maybe of list if you do not want to expose
>> > it to the world.
>> >
>> >
>> >
>> >>
>> >>
>> >> 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).
>> >>
>> >
>> > It assumes that the last certificate is the ROOT or the certificate  just
>> > before
>> > the ROOT (as the ROOT cert may be left out as you said above) and if
>> > the ROOT is left out it will try to find the ROOT in its database. If the
>> > ROOT is part
>> > of the chain it will still be looked up to make sure we already have it.
>> >
>> >
>> >> 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.
>> >
>> >
>> >
>> > You can use the verify_fun to accept any path validation errors you want,
>> > at your own risk as you are lowering the security requirements by doing so.
>> >
>> > [...]
>> >
>> >
>> > Regards Ingela Erlang/OTP team - Ericsson AB
>> _______________________________________________
>> erlang-questions mailing list
>> 
>> http://erlang.org/mailman/listinfo/erlang-questions
>>
>
> --
> --
> Dipl. Inform.
> Andreas Schultz
>
> email: 
> phone: +49-391-819099-224
> mobil: +49-170-2226073
>
> ------------------- enabling your networks -------------------
>
> Travelping GmbH               phone:         +49-391-819099229
> Roentgenstr. 13               fax:           +49-391-819099299
> D-39108 Magdeburg             email:       
> GERMANY                       web:   http://www.travelping.com
>
> Company Registration: Amtsgericht Stendal Reg No.:   HRB 10578
> Geschaeftsfuehrer: Holger Winkelmann | VAT ID No.: DE236673780
> --------------------------------------------------------------



More information about the erlang-questions mailing list