Last active
May 3, 2016 13:55
-
-
Save nakal/43ebdb0518af8a4e5380876807b8c547 to your computer and use it in GitHub Desktop.
SSL self-made CA verification samples
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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