Re: Exposing TLS & Certificate Information in Javascript

On Wed, May 29, 2013 at 1:17 AM, Douglas Stebila <stebila@qut.edu.au> wrote:
> We have been doing some research on building application-level cryptography on TLS connections.  In one of our recent projects, we wanted to cryptographically bind from the application layer to the TLS connection.  There are several ways of theoretically doing so, but the seemingly simplest would be to get (the hash of) the server's X.509 certificate from the TLS connection (this is one of the mechanisms specified in RFC 5929, TLS channel binding).  In our application, only the Firefox extension API allowed us to access that information (via XPCOM).  It would be nice to have a standardized way of doing this, and it seems like this may fall under the category of secondary features in the Web Cryptography API charter.
>
> Ryan Sleevi kindly pointed out a discussion thread on this mailing list from February 2013 that discusses things related to this issue, where an API exposing a variety of information on the TLS connection was proposed.  The subsequent discussion in the thread pointed out the subtleties of what is "the" TLS connection (http://lists.w3.org/Archives/Public/public-webcrypto-comments/2013Feb/0006.html; portions reproduced below).  I apologize for being late to the discussion and reopening a dormant conversation, but it did not seem to come to a resolution, beyond that there are subtleties.
>
> While it is true that there are subtleties, getting at least some information about the TLS connection would be a very useful thing to have available, and it may be possible to identify a canonical set of TLS parameters.  In fact, browsers effectively do so: when you click on the lock icon, you get a single certificate and a single explanation for the properties of the TLS connection.  I'm not sure which canonicalization browsers use, but two potentially reasonable choices include "the first certificate used on the main document", or "the most recent certificate used on the main document".  Yes, a single snapshot doesn't capture the whole history of the security context, but it does capture the security parameters at that canonical point in time, and that's enough to enable some interesting applications.
>
> In summary: can we have an API that gives the same information about the TLS connection as what would be obtained by clicking on the lock icon in the web browser?
>
Yes, agreed. Right now, the client does not know who it is
communicating with in practice (in theory, all this works fine). We
need an API to allow us to query the underlying connection. Since
WebCrypto deals with storage, handling and transformations of secrets,
it would be the perfect place for such an API.

The Internet PKI specification, RFC5280 (Internet X.509 Public Key
Infrastructure Certificate and Certificate Revocation List (CRL)
Profile) confers too much trust. Its hard to pin down a useful
definition of trust, but one of the better ones I've seen is "X trust
Y to do Z".

Unfortunately, "Relying Party trusts CA to Confirm Identity" is not
one of the available selections when crafting "X trust Y to do Z". In
fact, a Certification Practice Statement (CPS) typically sheds all
liability and warranties (or attempts to do so), so even if identity
assurances were stated or implied it would be questionable since the
CPS disclaims it.

Because the client (or relying party) must perform identity
verification of the server, there are three choices. Two are shared
secret, and one is public key. The two shared secret are Secure Remote
Password (SRP) and Pre-Shared Key (PSK). Both properly bind the outer
encryption tunnel with the inner authentication without exposing the
password to the attacker. While IANA has 80+ cipher suites reserved,
SRP and PSK has nearly no deployment in SSL/TLS.

For public/private key pairs, a client (or relying party) would need
access to the underlying certificate or public key. This was first
suggested by the SSH folks in a system called Perspectives and is
essentially pinning. Its better to pin the public key rather than the
certificate because the certificate can change (in fact, Google
rotates some of its certificates every 30 days or so while
re-certifying the same public key).

I am aware of initiatives like Public Key Pinning Extension for HTTP
(http://tools.ietf.org/html/draft-ietf-websec-key-pinning-04).
Unfortunately, this solution confers trust to the browsers - we need
them to do the right thing. And we've seen plenty of problems there
too. For example, no browser dropped Trustwave after the company
violated inclusion policies and issued MitM certificates; Nokia and
Opera colluded to break the secure channel and intercept (err,
accelerate) traffic; and a browser will "repair" a damaged certificate
store by restoring certs for Diginotar, CNNIC and the like. The
problems go on and on, its not worth conferring the trust - even to
the browser.

Developers need something to add assurances and reduce risk because
(1) JavaScript does not provide an API to query information about the
underlying connection; and (2) WebSockets does not provide an API to
query information about the underlying connection. I did take time to
write to the authors of WebSockets and ask for the API. I got no
reply. I also tried to contact the RFC Editor for the same - again, no
reply. Additionally, I was not able to find any popular third party
web based libraries offering the similar.

This problem (of identifying who the client is actually communicating
with)  is one of the reasons why I often deny browser based apps from
entering the enterprise. It simply can't handle higher data security
needs.

Related: "clicking on the lock icon in the web browser...". That's
broken in practice (and so is the missing lock for non-HTTPS). I can't
wander to far here, but for those who would like to read more, please
refer to Gutmann's Engineering  Security
(www.cs.auckland.ac.nz/~pgut001/pubs/book.pdf‎) and his discussion of
Biases, Psychology, and Usability.

Jeff

Received on Wednesday, 29 May 2013 17:22:17 UTC