Originally Posted By: Firoball
In the end you will have your own certificate, and if you setup your webserver to use it, wou'll get a warning because it's not registered.


It's not because it's not registered but because no sane browser will trust it. Certificates rely on trust, which means that your browser and OS have a couple of certificates they trust, these are called root certificates. Now, normally you get a certificate from a CA (certificate authority) which either has one of these root certificates or a certificate that is signed by a root certificate, they will sign your certificate with their certificate. In the end, you will end up with a chain of trust. Your browser will trust your certificate because it trusts who signed it, or it trusts who signed their certificate, or who signed their certificate. In theory it can be arbitrary long, but for example if you receive a certificate from a CA it won't have the right to sign other certificates.

The idea behind this is that no one can run around and just generate a certificate for let's say google.com. Google has a certificate which was signed by the Google Internet Authority G2, which is an intermediate CA. Their certificate comes from GeoTrust, one of the largest root CAs. If you want a regular certificate, you will have to prove to the CA that you own the domain, only then they will issue you a certificate (and take quite a buck for it).

Now, all this is well and good, the only issue is that is a huge clusterfuck since it relies on trust and trust alone. If you break into a CA and steal their certificate, you can generate your own valid certificate for google.com. So the idea is to limit the amount of CAs that are trusted, but for example both Windows and OS X ship trusting the chinese government and various intelligence agencies who may or may not have an interest in creating fake certificates so your browser trusts their man in the middle attack. Of course, if you were to actually break into a CA, you can be damn sure that their certificate would be revoked and you may actually end up achieving getting their certificate kicked out of the trust store of browsers and operating systems

And this finally is where certificate pinning comes into play. Certificate pinning means that you know what certificate the other end has, and when the server presents you their certificate, instead of just using the chain of trust to verify that the certificate is legit, you also check wether the certificate is the one you would expect it to be. Google does that in Chrome with google.com domains and a couple of others (in fact, there is a registry for that, where companies can register their certificates). If you visit google.com and someone in the middle presents a certificate that is valid but not the correct one, Chrome will give you a warning.

Of course, this is perfect for you! You don't want to rely on trust, because then you would also need to sleep with a CA, you know exactly what server you expect to see and how the certificate will look like. So, you pin it. Doesn't matter if a browser doesn't trust it, all that matters is that you trust it.

How to implement that... Well, since I'm far from being a Windows developer and haven't seriously touched a Windows machine in ages, I have no idea whatsoever. But I would be surprised if C# wouldn't have high level constructs for doing that and I would also be surprised if there wasn't a way to write a C wrapper over that.


Edit: Also, looking at your printf, it already looked like it was working fine? That was exactly the output to expect, or am I missing something?

Last edited by WretchedSid; 04/27/15 22:31.

Shitlord by trade and passion. Graphics programmer at Laminar Research.
I write blog posts at feresignum.com