<div dir="ltr"><div class="gmail_quote"><div dir="ltr">Hi!<div><br></div><div><div class="gmail_extra"><span style="font-size:13px">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 </span><span style="font-size:13px;background-color:rgb(255,255,255)">partial_</span><span style="font-size:13px">chain to allow path validation on only part of the chain, so that means the server that accepts a </span><span style="font-size:13px;background-color:rgb(255,255,255)">partial</span><span style="font-size:13px"> 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.  </span></div><div class="gmail_extra"><br></div><div class="gmail_extra"><div style="font-size:13px">E.i. the <span>partial</span> <span>chain</span> function lets you  shorten the <span>chain</span> by accepting an intermediate cert sent to you by the peer as trusted. If you want to handle incorrect clients  by building the <span>chain</span> 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 <span>chain</span> that you built. </div><div style="font-size:13px"><br></div><div style="font-size:13px">As the self-signed root cert may be left out of the <span>chain</span> client software will guess that if the signer of a cert is not found it must be the self-signed root, however if</div><div style="font-size:13px">the client is not correctly configured this could be a wrong guess.</div><div style="font-size:13px"><br></div><div style="font-size:13px">See also comment inlined</div></div><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="h5">2015-01-21 18:05 GMT+01:00 Vincent de Phily <span dir="ltr"><<a href="mailto:vincent.dephily@mobile-devices.fr" target="_blank">vincent.dephily@mobile-devices.fr</a>></span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Hi,<br>
<br>
we're trying to upgrade from 17.1 to 17.4 and are hitting authentication<br>
failures, apparently due to the changes that introduced the partial_chain<br>
option.<br>
<br>
First some background:<br>
* We want to authenticate both server and client<br>
* We manage certificate ourselves, and don't care about the OS-supplied CAs.<br>
* The signing hierarchy is<br>
  TopCA -> ServerCA -> Account1ServerCert<br>
                    -> Account2ServerCert<br>
                    -> ...<br>
        -> ClientCA -> Account1ClientCert<br>
                    -> Account1Device1Cert<br>
                    -> Account1Device2Cert<br>
                    -> ...<br>
                    -> Account2ClientCert<br>
                    -> ...<br>
* The server and test client are in erlang, the real clients are in various<br>
  languages (and we can't afford to update them).<br>
<br>
<br>
What we used to do, works fine in 17.1:<br>
  server: {cert, Account1ServerCert}, {cacerts, [ClientCA]}<br>
  client: {cert, Account1Device1Cert}, {cacerts, [ServerCA]}<br>
(in some cases we used the 'file' version of the option, but that doesn't<br>
change the semantics AFAIK).<br>
<br>
But that gives us an "unknown ca" error with 17.4.<br>
<br>
The minimum list of cacerts that seems to work is [ServerCA,TopCA] for the<br>
server and [clientCA,TopCA] for the client, but:<br>
* Having to specify the TopCA is an administration pain (lots of configs to<br>
  change, and need to take the file out of the vault).<br>
* I'd rather not send unnecessary bytes over the wire. Ideally I don't want to<br>
  send any root/intermediate CA, only the leaf cert.<br>
* Huh ? Why does ClientCA not need to be in ther server's cacerts (and vice-<br>
  versa) ?<br>
<br>
I guess some confusion comes from the fact that the cacerts option is used for<br>
two different things (authenticating the cert received by the peer, and<br>
sending intermediate CAs to the peer to help it authenticate me). Maybe the<br>
option could be split in two ?<br>
<br></blockquote><div><br></div></div></div><div>This is documented and you will find the same behaviour in openSSL.</div><div><br></div><div>Client side:</div><div> </div><div><dt style="color:rgb(0,0,0);font-family:Verdana,Arial,Helvetica,sans-serif;font-size:medium"><strong>{cacertfile, path()}</strong></dt><dd style="color:rgb(0,0,0);font-family:Verdana,Arial,Helvetica,sans-serif;font-size:medium">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.</dd></div><div><br></div><div><br></div><div>Sever side:</div><div><br></div><dt style="color:rgb(0,0,0);font-family:Verdana,Arial,Helvetica,sans-serif;font-size:medium"><strong>{cacertfile, path()}</strong></dt><div><span style="color:rgb(0,0,0);font-family:Verdana,Arial,Helvetica,sans-serif;font-size:medium">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.</span> <br></div><span class=""><div><br></div><div><br></div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
AFAIU, the new requirement for TopCA to be present comes from a tightening of<br>
the check mandated by the RFC : the certificate chain (which one ? the one<br>
sent by the client or the one set up locally) needs to end with a self-signed<br>
cert.<br>
<br>
I'll pass on the weirdness of that requirement (I'll trust whichever CA I<br>
decide, wether it's self-signed or not, damnit), as it looks like<br>
partial_chain is expressely designed to bypass it. But I wasn't able to write<br>
one that worked *and* didn't look like a big security hole. Could somebody<br>
write an example partial_chain fun that works for my usecase ?<br>
<br>
Ideally, the docs could do with some clarifications :<br>
* The spec for partial_chain has a typo (at least a missing '}')<br>
  Again, and example in the docs wouldn't go amiss.<br>
* It's not clear which chain it acts uppon<br>
* Is the semantic of cacertfile really different for the server and the<br>
  client ? From my knowledge of TLS, it should be symetrical (even if the<br>
  common real-world case is that the client doesn't authenticate itself), so<br>
  the option should be in the common section (next to cacerts with a note that<br>
  one is equivalent to the other).<br>
<br>
<br>
Thanks in advance.<br></blockquote><div><br></div><div><br></div></span><div>Hope that helps.</div><div><br></div><div>Regards Ingela Erlang/OTP team - Ericsson AB</div><div> </div></div></div></div></div>
</div><br></div>