C++ OpenSSL Fetch SSL Certificate
Any website running SSL on port 443 has a certificate, which can be downloaded and parsed. The certificate is available downloaded through the SSL handshake, but is not a typical file downloaded via HTTP. Included below is C/C++ code for programmatically downloading an SSL certificate.
The easy way to download an SSL certificate on linux is through openssl s_client command.
openssl s_client -connect encrypted.google.com:443
before compiling
sudo apt-get install libssl-dev #debian based yum install openssl-devel #redhat based
compile on linux
g++ main.cpp -lssl
main.cpp (replace 127.0.0.1 with the ip address of the server whose certificate you wish to fetch)
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <openssl/x509.h>
#include <openssl/ssl.h>
int main(int argc, char **argv)
{
struct sockaddr_in sa;
SSL* ssl;
X509* server_cert;
SSLeay_add_ssl_algorithms();
SSL_load_error_strings();
SSL_CTX* ctx = SSL_CTX_new (SSLv23_method());
int sd = ::socket (AF_INET, SOCK_STREAM, 0);//create socket
if (sd!=-1 && ctx!=NULL)
{
memset (&sa, '\0', sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = inet_addr ("127.0.0.1"); /* Server IP */
sa.sin_port = htons (443); /* Server Port number */
int err = ::connect(sd, (struct sockaddr*) &sa, sizeof(sa));
if (err!=-1)
{
ssl = SSL_new (ctx);
if (ssl!=NULL)
{
SSL_set_fd(ssl, sd);
err = SSL_connect(ssl);
if (err!=-1)
{
server_cert = SSL_get_peer_certificate(ssl);
if (server_cert!=NULL)
{
BIO * bio_out = BIO_new_file("output.pem", "w");
if (bio_out)
{
X509_print(bio_out, server_cert);//parsed
PEM_write_bio_X509(bio_out, server_cert);
BIO_free(bio_out);
}
X509_free (server_cert);
}
}
SSL_free (ssl);
}
::close(sd);//close socket
}
}
SSL_CTX_free (ctx);
}code snippets are licensed under Creative Commons CC-By-SA 3.0 (unless otherwise specified)
|