Skip to content

Instantly share code, notes, and snippets.

@nakal
Last active May 3, 2016
Embed
What would you like to do?
SSL self-made CA verification samples
const char * ca_pubkey =
{
"-----BEGIN CERTIFICATE-----\n"
...
"-----END CERTIFICATE-----"
};
void init(void)
{
/* these both are called only once for the entire application */
if (!initialized) {
SSL_library_init();
SSL_load_error_strings();
initialized = true;
}
ctx = SSL_CTX_new(TLSv1_2_client_method());
if (ctx == NULL)
error("Getting TLSv1.2 SSL method context failed.");
/* don't use the default verification mechanism */
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
/* instead use our own CA store */
init_ca_store();
}
void init_ca_store(void)
{
/* load CA certificate from memory */
BIO *bio = BIO_new(BIO_s_mem());
if (bio == NULL)
error("Failed to allocate BIO for reading certificate.");
BIO_puts(bio, ca_pubkey);
X509 *cert = PEM_read_bio_X509(bio, NULL, 0, NULL);
BIO_free_all(bio);
if (cert == NULL)
error("Could not load certificate from memory.\n"
"THIS IS A BUG.\n");
/* put CA certificate in store */
ca_store = X509_STORE_new();
if (ca_store == NULL)
error("Error creating certificate store.");
// X509_STORE_set_flags(ca_store, 0);
if (X509_STORE_add_cert(ca_store, cert) != 1)
error("Error adding CA certificate to store.");
X509_free(cert);
}
void connect(void)
{
web = BIO_new_ssl_connect(ctx);
if (web == NULL)
error("Failed to initialize connection.");
long res = BIO_set_conn_hostname(web, (hostname + ":443").c_str());
if (res != 1)
error("BIO_set_conn_hostname error.");
BIO_get_ssl(web, &ssl);
if (ssl == NULL)
error("BIO_get_ssl error.");
const char* const PREFERRED_CIPHERS =
"HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4";
res = SSL_set_cipher_list(ssl, PREFERRED_CIPHERS);
if (res != 1)
error("SSL_set_cipher_list error.");
res = BIO_do_connect(web);
if (res != 1)
error(ERR_error_string(ERR_get_error(), NULL));
res = BIO_do_handshake(web);
if (res != 1)
error("Error during handshake.");
}
void verify(void)
{
X509* cert = SSL_get_peer_certificate(ssl);
if (cert == NULL)
error("Server has no certificate.");
X509_STORE_CTX *ca_store_ctx = X509_STORE_CTX_new();
if (ca_store_ctx == NULL) {
X509_free(cert);
error("Error creating verification context.");
}
if(X509_STORE_CTX_init(ca_store_ctx, ca_store, cert, NULL) != 1) {
X509_STORE_CTX_free(ca_store_ctx);
X509_free(cert);
error("Error initializing verification context.");
}
if (X509_verify_cert(ca_store_ctx) != 1) {
int err = X509_STORE_CTX_get_error(ca_store_ctx);
X509_STORE_CTX_free(ca_store_ctx);
X509_free(cert);
error(X509_verify_cert_error_string(err));
}
X509_STORE_CTX_free(ca_store_ctx);
X509_free(cert);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment