<div dir="ltr"><div class="gmail_default" style="font-size:small">All,<br></div><div class="gmail_quote"><div dir="ltr"><div style="font-size:small"><br></div><div style="font-size:small">I have been looking at various ways to protect the TLS handshake including the domain name of the site being accessed. To do this, it is necessary to put 'some form' of key into the DNS record for the host.</div><div style="font-size:small"><br></div><div style="font-size:small">While many people have suggested schemes in the past, these have all been based on the legacy RSA exchanges and in ways I find unconvincing. Not least because TLS is a protocol with 25 years history and has been patched and repatched many times. </div><div style="font-size:small"><br></div><div style="font-size:small">I would prefer to use a scheme that has the following properties</div><div style="font-size:small"><br></div><div style="font-size:small">1) Only use DH/ECDH key exchange.</div><div style="font-size:small">2) Enables use of hardware host keys</div><div style="font-size:small">3) Provides perfect forward secrecy by default.</div><div style="font-size:small">4) Has integrated support for client auth.</div><div style="font-size:small"><br></div><div style="font-size:small">The type of approach I like best is the one used in the noise protocol which underpins Signal, etc. The wonderful thing about DH is that it is composable to as many keys as you need. So the basic idea is to have each of the parties identified by a key:</div><div style="font-size:small"><br></div><div style="font-size:small">* KH - The Host is identified by a host key that is distributed through a DNS TXT record.</div><div style="font-size:small">* KS - The Service is identified by a WebPKI certificate (EV / OV or DV)</div><div style="font-size:small">* KC - The Client SHOULD be identified by a client key.</div><div style="font-size:small">* EC - An ephemeral mix-in is supplied by the client.</div><div style="font-size:small">* ES - An ephemeral mix-in is supplied by the service.</div><div style="font-size:small"><br></div><div style="font-size:small">Let A(k1, k2...) be a function that creates an agreed key from k1, k2, etc.</div><div style="font-size:small">Let KDF (x,p) be a key derivation function for purpose p.</div><div style="font-size:small"><br></div><div style="font-size:small">A brief sketch of the protocol would be:</div><div style="font-size:small"><br></div><div style="font-size:small">Client obtains KH from the DNS, creates A(KH, EC)</div><div style="font-size:small"><br></div><div style="font-size:small">Client encrypts initial contact message under KDF (A (KH, EC),p1) this contains</div><div style="font-size:small">   * Client cert (if used) (contains KC)</div><div style="font-size:small">   * DNS name of Service to be contacted</div><div style="font-size:small">   * sundry flags<br></div><div style="font-size:small"><br></div><div style="font-size:small">Service reply is encrypted under KDF (A (KH, EC), p2). This contains</div><div style="font-size:small">   * Service certificate + chain (contains KS)</div><div style="font-size:small">   * ES</div><div style="font-size:small">   * Opaque identifier (for fast restart)</div><div style="font-size:small">   * sundry flags</div><div style="font-size:small"><br></div><div style="font-size:small">The rest of the conversation is encrypted under KDF (A(KH, EC) + A (KS, KC, ES),p) where p = p1 or p2 depending on the direction.</div><div style="font-size:small"><br></div><div style="font-size:small">The reason for not using a quintuple exchange for the service exchange is that this approach allows different curves to be used for the host and service level agreement. It is very likely that 25519 is sufficient for the host level but there are definitely cases where 448 is needed for the service level.</div><div style="font-size:small"><br></div><div style="font-size:small">I have not looked into how to squeeze this into TLS data frames but that is just bit shuffling.</div><div style="font-size:small"><br></div><div style="font-size:small"><br></div><div style="font-size:small">While I can't see a case for moving away from X.509 for the service cert, it might well be that we would want to use a different cert for the client part. In particular, I can see the use of some form of blinding or annonymization being layered in. </div><div style="font-size:small"><br></div><div style="font-size:small">Note that with EC, multi-key exchanges don't actually take more time than two key. The private keys add and the public keys multiply. So there is only one modular exponentiation or other costly operation.</div><div style="font-size:small"><br></div><div style="font-size:small">One odd feature of this exchange is that practically every part of it is already specified by IETF docs. I built it from code I already had to implement KDFs etc.</div><div style="font-size:small"><br></div><div style="font-size:small"><br></div><div style="font-size:small">One possibility that I like a lot is that we can have client authentication at the transport level for free. Which is useful for SMTPS / IMAPS / etc. That does not do away with the need for application level authentication of course, but we have the option of a transport binding.</div><div style="font-size:small"><br></div><div style="font-size:small">I would like to see an option that allows a client to prove that they are the same client that contacted earlier and that this be unlinkable across DNS domains. Easy enough in DH//ECDH. If x is a device bound key, we can use KDF (x + H(Domain), p3).</div><div style="font-size:small"><br></div><div style="font-size:small"><br></div><div style="font-size:small">Thoughts?</div></div>
</div><br></div>