Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I want to securely connect to an API, but I'm not sure how I should obtain the CA cert for the verification step.

I've seen some people get the certs using e.g.:

openssl s_client -connect graph.facebook.com:443 -showcerts

Is this method for obtaining certs secure? Should I use some other method?

Edit: since there are no bites yet, maybe an example of what I'm worried about will help. Given that the main point of SSL (as I understand it) is to counter MITM attacks, how can certs be obtained in a way that ensures they were not subject to a MITM, thereby making subsequent verification moot?

share|improve this question
    
edit: one question at a time. –  Rook Dec 14 '11 at 7:30
    
Ah okay, my bad. –  norcoo Dec 14 '11 at 7:59
add comment

3 Answers

up vote 3 down vote accepted

I have seen this done with SSH key authentication by phone. The procedure was for me to generate private and public keys and send the public one to the hosting provider via email. They would then phone me, read out half of the fingerprint and require me to read out the other half. If they matched, they would put my public key on the server and I could log in.

This is unlikely to be practical for verifying Facebook's SSL certs, however the key point is that the verification was done using a different method to the original transfer which makes a potential attacker's job much harder.

If you can request the certificate using a different computer on a different internet connection and compare it to the one you have then you can be reasonably certain that you have the correct cert.

SSL has chains of trust which SSH keys don't, so it should be adequate to verify the root CA certs and use those to verify the target cert.

On Ubuntu, there is a ca-certificates package that contains the certificates that the Ubuntu maintainers trust. The certificates themselves can be found in /usr/share/ca-certificates. Other Linux distributions will have similar packages.

share|improve this answer
    
Thanks, that's very helpful. I'm just a little unsure about the last bit. Should I get the root cert from the CA itself, or use the method I showed above (or does it not matter)? –  norcoo Dec 14 '11 at 9:38
    
BTW, reading your story about authentication via phone made me smile; it makes total sense, but being a bit of a security noob, it gives me a hint of the crazy world I'm getting myself into. –  norcoo Dec 14 '11 at 9:39
add comment

A certificate is signed. This means that it comes with its own security. The validity of a certificate comes from its being signed by a certification authority, not from the way you obtain it. During the first steps of a SSL/TLS connection (the "handshake"), the client must gain reliable knowledge of the server's public key; the client can do so in any way it sees fit, but it often involves finding a certificate path, i.e. a set of certificates culminating in a certificate that contains the server name and the server public key. In order to smooth operations, the server includes such a potential path in one of the handshake messages it sends to the client.

Validation of a certificate path involves verifying the signature over each certificate, with regards to the pubic key contained in the previous certificate (there are a lot of other things which are checked, too, see section 6 of RFC 5280 if you are really bored one day). The point of the signature is to protect against alteration and to demonstrate provenance. How you obtained the certificate is irrelevant; for that matter, it could have been delivered to you by the Devil himself, it will not impact security.

However, you still have to being somewhere. As alluded to above, the signature of each certificate in the path is to be verified with the public key contained in the previous certificate. How do we check the signature on the first certificate in the path ? For that, we need a trust anchor: that's a name-and-public-key which is known a priori, e.g. it is embedded in the client software (after all, you trust the software itself for not logging all exchanged data and your key strokes, so you can trust it as well with the storage of some public keys). Trust anchors are traditionally encoded as root certificates: these are not real certificates (their signature is dummy, or often a "self-signature" which has no function except filling the slot for a signature in a certificate format) but they still assume the external format (as a bunch of bytes) of a certificate.

The "root certificates" must be securely obtained, since they cannot be verified in any way; all your trust comes from them. Here is a peek of the (beginning of) the list of root certificates embedded in Firefox (that is, the certificates that Mr Firefox found fit to stuff into his browser and that I, being a lazy user, "trust" by default):

Root certificates in Firefox (screenshot)

share|improve this answer
add comment

I'm just reading this and I see you got an answer that works for you... but the really nerdy answer is "it depends". If you're trying to get an SSL server cert, any hit to the SSL server will get you the cert in the same way - the server will offer it and give proof of possesion as part of the SSL protocol.

The critical decision is deciding whether or not to trust the certificate.

A certificate has several elements: - information about its owner - information about its issuer - a chain of certificates leading to a root issuer - validity information.

An easy check is "is the certificate valid" - if you can look at the data, you can see the validity start and end dates. Depending on what you're doing, you can check by hand or code something to check on each connection.

Next, you may want to figure out if you trust its issuer. Self-signed certs are inherently less trustworthy, because anyone can sign it. Browsers have a trusted certificate store of common "good bets" - certified issuers that commercially produce certificates. But there are other for-pay issuers out there, as well as internal corporate products that may be perfectly trustworthy for your purposes. Step 1 is deciding which issuer certificate to trust - which means configuring a trust store locally. Step 2 is verifying that the certificate presented by the server isn't lying when it claims an issuer - that's a cryptographic check on the digital signature of the certicate. Step 2 should be repeated for each certificate in the chain...

Lastly, for higher assurance, you may want to check that the certificate is not revoked. That's doable through a couple of PKI protocols, or manually on most commercial issuer websites. A certificate may contain information on how to verify its status as part of its packaged information (a CRL Distribution Point, or AIA extension) or you may have to google to find the answer.

How far you go in checking up on a server certificate should be commensurate with the risk of the information you'll be giving to the server.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.