[erlang-questions] Fwd: Figuring out proper ssl certificate settings with 17.3

Ingela Andin ingela.andin@REDACTED
Thu Jan 22 21:45:08 CET 2015


There was a bug in R16 that if the client sends only its peer-cert and the
server happens to own the intermediate CA cert that signed the client cert
it concludes that the intermediate CA cert is the trusted cert and
everything works. But according to the TLS protocol the client must send
the whole chain only the self signed ROOT may be excluded from the chain.
However  pkix-X509 certificate path validation says it should be possible
to put the trust in an intermediate cert, and that is why we have the
partial_chain to allow path validation on only part of the chain, so that
means the server that accepts a partial chain could know of the
intermediate cert but not own the ROOT, as it has decided to trust the
intermediate CA. So a TLS client that can not build its whole chain is
 incorrectly configured.

E.i. the partial chain function lets you  shorten the chain by accepting an
intermediate cert sent to you by the peer as trusted. If you want to handle
incorrect clients  by building the chain to the client certificate on the
server side , if possible, you need to do that in the verify_fun when it
fails and then call public_key:pkix_path_validation again with the chain that
you built.

As the self-signed root cert may be left out of the chain client software
will guess that if the signer of a cert is not found it must be the
self-signed root, however if
the client is not correctly configured this could be a wrong guess.

See also comment inlined

2015-01-21 18:05 GMT+01:00 Vincent de Phily <

> Hi,
> we're trying to upgrade from 17.1 to 17.4 and are hitting authentication
> failures, apparently due to the changes that introduced the partial_chain
> option.
> First some background:
> * We want to authenticate both server and client
> * We manage certificate ourselves, and don't care about the OS-supplied
> CAs.
> * The signing hierarchy is
>   TopCA -> ServerCA -> Account1ServerCert
>                     -> Account2ServerCert
>                     -> ...
>         -> ClientCA -> Account1ClientCert
>                     -> Account1Device1Cert
>                     -> Account1Device2Cert
>                     -> ...
>                     -> Account2ClientCert
>                     -> ...
> * The server and test client are in erlang, the real clients are in various
>   languages (and we can't afford to update them).
> What we used to do, works fine in 17.1:
>   server: {cert, Account1ServerCert}, {cacerts, [ClientCA]}
>   client: {cert, Account1Device1Cert}, {cacerts, [ServerCA]}
> (in some cases we used the 'file' version of the option, but that doesn't
> change the semantics AFAIK).
> But that gives us an "unknown ca" error with 17.4.
> The minimum list of cacerts that seems to work is [ServerCA,TopCA] for the
> server and [clientCA,TopCA] for the client, but:
> * Having to specify the TopCA is an administration pain (lots of configs to
>   change, and need to take the file out of the vault).
> * I'd rather not send unnecessary bytes over the wire. Ideally I don't
> want to
>   send any root/intermediate CA, only the leaf cert.
> * Huh ? Why does ClientCA not need to be in ther server's cacerts (and
> vice-
>   versa) ?
> I guess some confusion comes from the fact that the cacerts option is used
> for
> two different things (authenticating the cert received by the peer, and
> sending intermediate CAs to the peer to help it authenticate me). Maybe the
> option could be split in two ?
This is documented and you will find the same behaviour in openSSL.

Client side:

*{cacertfile, path()}*The path to a file containing PEM encoded CA
certificates. The CA certificates are used during server authentication and
when building the client certificate chain.

Sever side:

*{cacertfile, path()}*
The path to a file containing PEM encoded CA certificates. The CA
certificates are used to build the server certificate chain, and for client
authentication. Also the CAs are used in the list of acceptable client CAs
passed to the client when a certificate is requested. May be omitted if
there is no need to verify the client and if there are not any intermediate
CAs for the server certificate.

AFAIU, the new requirement for TopCA to be present comes from a tightening
> of
> the check mandated by the RFC : the certificate chain (which one ? the one
> sent by the client or the one set up locally) needs to end with a
> self-signed
> cert.
> I'll pass on the weirdness of that requirement (I'll trust whichever CA I
> decide, wether it's self-signed or not, damnit), as it looks like
> partial_chain is expressely designed to bypass it. But I wasn't able to
> write
> one that worked *and* didn't look like a big security hole. Could somebody
> write an example partial_chain fun that works for my usecase ?
> Ideally, the docs could do with some clarifications :
> * The spec for partial_chain has a typo (at least a missing '}')
>   Again, and example in the docs wouldn't go amiss.
> * It's not clear which chain it acts uppon
> * Is the semantic of cacertfile really different for the server and the
>   client ? From my knowledge of TLS, it should be symetrical (even if the
>   common real-world case is that the client doesn't authenticate itself),
> so
>   the option should be in the common section (next to cacerts with a note
> that
>   one is equivalent to the other).
> Thanks in advance.

Hope that helps.

Regards Ingela Erlang/OTP team - Ericsson AB
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20150122/3ed1d87f/attachment.htm>

More information about the erlang-questions mailing list