My experience with the SSL/TLS protocol and then OpenSSL library is very limited. Essentially I started learning about it this week, yet I feel proud of the amount of knowledge I have learned thus far.
I do have a lingering question though and haven’t been able to find the answer. I’ve tried Googling it and looking into other resources available to me but it seems I don’t know how to properly ask my question. It has to do with the handshake procedure and what happens if the client already has the server certificate?
I understand that the initial part of the handshake involves these high-level steps:
- Client sends hello message
- Server responds with its own hello message
- Server sends certificate
- Client verifies the server certificate
- Server sends message indicating that negotiation is done
I just can’t seem to figure out how this procedure would work when the client already has the server certificate. I know that session ids can be used to do a resumed handshake where only the hello messages are sent and then a message stating any data after this message is encrypted, thus avoiding key generation in the asymmetric handshake. But using those session ids doesn’t seem like a good idea to me as essentially they would have to last a very long long time which may pose security issues (I don’t know how but it just seems bad to have a very long persisting session id. Maybe I am wrong through). I figured that the behavior may be similar to that of a web browser but failed to find any information on that road.
I went and looked at the OpenSSL API to do some research and it also left lingering questions. The API method:
int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
when initializing/setting up all my OpenSSL structs made me think that this would be the servers certificate file if it already existed. But I did further research and it can be used for both client and server applications. So in the case where I am a client and DON’T have the server certificate yet would I just forgo using the above API method before calling the SSL_connect() API to do the SSL handshake? I guess if this was the case I would somehow use the OpenSSL APIs to save the server certificate as well?
Thanks for reading my post. I appreciate any help/guidance/pointers you may be able to offer. If my questions/thoughts aren’t clear please let me know and I will try to clarify them.
You seem to be conflating caching the certificate ("client already has the server certificate") with caching the connection state ("avoiding key generation in the asymmetric handshake").
There is certainly no security issue with caching the server certificate. It does not matter how you get that certificate, because it is totally public information; its purpose is to convey the server’s public key to you. The key negotiation will only work if the server has the corresponding private key, regardless of how you obtain the certificate.
However, I do not know whether the OpenSSL API (or the SSL protocol, for that matter) allows you to assume you already have the server’s certificate and skip that part of the handshake. As you already figured out, SSL_CTX_use_certificate_file() is what you invoke on the client to identify the client certificate. And it is what a Web server would invoke to identify its own server certificate. It is not for identifying the server certificate on the client or vice-versa.
As for re-using an existing session ID (to skip key generation entirely), that is also plenty secure. At least, it is no worse than having a long-lived SSL connection. And if anybody discovered a problem with that, the result would be worth a Ph.D. at least.
[update on resuming sessions]
Section 7.3 of RFC 5246 has an overview of the SSL handshake, including the case where you resume a session. Resuming a session means you get to skip exchanging and verifying certificates and jump right into the encrypted session, starting with a ChangeCipherSpec message to negotiate the secret key.
Incidentally, I do not think it is common to resume SSL sessions in practice. The handshake is not that slow, and preserving the state is annoying. To my knowledge, Web browsers and servers do not generally use this feature; they just do the full handshake on every SSL connection.