In the Web browser context, there are two kinds of SSL connections: the ones that the browser manages, and the ones that your code (be it Java, Javascript...) manages itself.
For the first kind, you are mostly out of luck, because the browser will not give you details about the server certificate chain. The browser tells you "this is all dandy" but gives you no way to check that the browser is not being led astray.
For the second kind, well, this means that your code will open the connection to the server and run the complete SSL handshake itself. At that point, of course, the code will see the certificate chain from the server, and will be able to validate it in arbitrary ways, which includes "direct trust" (the client code already "knows" the server public key) or at least using a specific, expected root CA. This approach has several practical issues which can be dealt with at a cost:
- You have to embed a complete SSL implementation. This is not necessarily huge, but it can be tricky. You can make it smaller since you control both client and server code, so you can concentrate on the exact protocol version and algorithms that you intend to use.
- Performance can be an issue if using an interpreter without a JIT compiler.
- All of this makes sense only if you can make sure that the client code has not been altered. It is useless to check anything with Javascript about the SSL connection through which the Javascript code itself has been downloaded: a Man-in-the-Middle can change the Javascript code to remove the check.
- Opening a raw connection to the server from the client code is tricky in some networks, especially with regards to proxies.
For performance, you will want to use Java ME. Most Java ME implementation use basic interpreters so this will not be faster than Javascript or Flash, except that the Java ME standard library includes java.math.BigInteger
, an implementation of arithmetics on arbitrarily large integers, which will be typically implemented as native code, thus very fast. You will need this for the RSA or DH computations involved by the SSL handshake.
For make sure that the right code is running on the client, there again Java ME can come to the rescue, because Java ME applets can be signed. This does not really solves your problem, because an attacker who can run Fiddler is an attacker who could insert his own fake CA in the local trust store; the same attacker could have added his own fake CA to the other local trust store, the one for validating applet-signing certificates. Yet this adds a nice twist: if the client connection is intercepted, then, after-the-fact forensics examinations may uncover the cached signed applet, and then it will be made evident that the applet is fake and you, as the server maintainer, is not the bad guy. You cannot have that kind of legal protection from authentication, but signatures can help. This, of course, depends a lot on the context.
The problem with proxies is serious. A lot of local networks, especially corporate, don't do NAT; instead, all external traffic must go through some proxies. The user's Web browser knows where the proxies are, but not your Javascript or Java code. Moreover, the proxies may require some authentication, which may be linked with the local session credentials; there again, the browser gets through transparently, not your code. To cope with that kind of problem, you might envision tunnelling your SSL traffic through HTTP requests, which will be handed over to the HTTP code provided by the framework. This is possible (I have done it about one decade ago) but not easy.
Yet, this all smells bad. MitM attacks of the kind you are talking about work only if the attacker could pierce through the X.509 trust model, e.g. by installing his own rogue CA as a trusted CA in the client's system. Since OS software updates also use this trust model, it must be assumed that the client system is, at that time, under complete control of the attacker, at least potentially. In a way, Fiddler is not something which is used by evil people, because the conditions which allow Fiddler to operate also allow the aforementioned evil people to enact evilness of a much larger and more thorough scale.
Which can be summarized as: checking things on SSL connections from Javascript or Java ME client-side code is as useless as a nice note on your living-room table, requesting potential burglars to kindly phone the Police themselves.
(Might work in Canada, though.)