Client program to validate server certificate returned by SSL_get_peer_certificate?

我只是一个虾纸丫 提交于 2019-12-04 19:48:32
Steffen Ullrich

Proper certificate verification is a complex thing and OpenSSL is only slightly helpful there. If you expect full code for each step I would consider the question as too broad. Therefore I'll focus on the essential parts needed in verification and mainly point out other resources for the details of the implementation of the specific parts.


The first step for validating a server certificate is building the trust chain to a trusted root CA certificate. This is implicitly done by openssl inside the TLS handshake if you've set a trusted root (i.e. call of SSL_CTX_load_verify_locations in your code) and also set the verification mode with SSL_CTX_set_verify to SSL_VERIFY_PEER. This built-in validation also includes checks if the leaf and chain certificates are already valid and not yet expired.

The next step is to validate if the subject of the certificate matches the expected one. For server certificates this usually means that the target hostname is somehow included in the common name or the subject alternative names of the certificate. The actual requirements depend on the application layer protocol, i.e. HTTP, SMTP, LDAP ... all have slightly different rules especially if wildcards are involved. Since OpenSSL 1.0.2 a a X509_check_host function is available and can be used to check against the rules in most cases. With earlier versions of OpenSSL you are on your own to implement such a function. Note that you explicitly need to validate the hostname, i.e. OpenSSL will not do this for you and omitting this step will make man in the middle attacks against your application easy.

At this point that you know that the certificate is directly or indirectly issued by a trusted root CA and that the certificate matches the expected hostname. You now need to check if the certificate is revoked. One way is to use a certificate revocation list (CRL) which you got somewhere, another is to use the the Online Certificate Status Protocol (OCSP).

For CRL see Does OpenSSL automatically handle CRLs (Certificate Revocation Lists) now? which hows how to use a CRL you've downloaded already. But OpenSSL will not help you with downloading the CRL in the first place. Instead you would need to extract the CRL distribution point from the leaf certificate, download the CRL yourself and then you can use it.

As for OCSP OpenSSL provides the necessary API to build OCSP requests and validate OCSP responses. You are still on your own to figure out where to sent this OCSP request to. This needs to be done again by parsing the leaf certificate and extracting the OCSP URL from the Authority Information Access field. And while there is API for the rest it is not easy to use and was mostly or fully undocumented at least before OpenSSL version 1.1.0. I don't know of a good and easy to understand example where OCSP validation is implemented using this API but you might have a look at the openssl ocsp command and its implementation.


In case you write a client application and want to accept only a single certificate anyway you can omit all the complex steps of validating against a PKI but only check if the certificate is exactly the expected one, i.e. certificate pinning. See OWASP: Certificate and Public Key Pinning for more information about this and for sample code.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!