diff options
Diffstat (limited to 'sample/https-client.c')
-rw-r--r-- | sample/https-client.c | 88 |
1 files changed, 65 insertions, 23 deletions
diff --git a/sample/https-client.c b/sample/https-client.c index 748395656b2e..5136acebd79a 100644 --- a/sample/https-client.c +++ b/sample/https-client.c @@ -45,7 +45,6 @@ #include "openssl_hostname_validation.h" -static struct event_base *base; static int ignore_cert = 0; static void @@ -54,7 +53,7 @@ http_request_done(struct evhttp_request *req, void *ctx) char buffer[256]; int nread; - if (req == NULL) { + if (!req || !evhttp_request_get_response_code(req)) { /* If req is NULL, it means an error occurred, but * sadly we are mostly left guessing what the error * might have been. We'll do our best... */ @@ -119,7 +118,6 @@ err_openssl(const char *func) exit(1); } -#ifndef _WIN32 /* See http://archives.seul.org/libevent/users/Jan-2013/msg00039.html */ static int cert_verify_callback(X509_STORE_CTX *x509_ctx, void *arg) { @@ -182,16 +180,45 @@ static int cert_verify_callback(X509_STORE_CTX *x509_ctx, void *arg) return 0; } } + +#ifdef _WIN32 +static int +add_cert_for_store(X509_STORE *store, const char *name) +{ + HCERTSTORE sys_store = NULL; + PCCERT_CONTEXT ctx = NULL; + int r = 0; + + sys_store = CertOpenSystemStore(0, name); + if (!sys_store) { + err("failed to open system certificate store"); + return -1; + } + while ((ctx = CertEnumCertificatesInStore(sys_store, ctx))) { + X509 *x509 = d2i_X509(NULL, (unsigned char const **)&ctx->pbCertEncoded, + ctx->cbCertEncoded); + if (x509) { + X509_STORE_add_cert(store, x509); + X509_free(x509); + } else { + r = -1; + err_openssl("d2i_X509"); + break; + } + } + CertCloseStore(sys_store, 0); + return r; +} #endif int main(int argc, char **argv) { int r; - + struct event_base *base = NULL; struct evhttp_uri *http_uri = NULL; const char *url = NULL, *data_file = NULL; - const char *crt = "/etc/ssl/certs/ca-certificates.crt"; + const char *crt = NULL; const char *scheme, *host, *path, *query; char uri[256]; int port; @@ -312,7 +339,8 @@ main(int argc, char **argv) } uri[sizeof(uri) - 1] = '\0'; -#if OPENSSL_VERSION_NUMBER < 0x10100000L +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \ + (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) // Initialize OpenSSL SSL_library_init(); ERR_load_crypto_strings(); @@ -335,14 +363,27 @@ main(int argc, char **argv) goto error; } -#ifndef _WIN32 - /* TODO: Add certificate loading on Windows as well */ - - /* Attempt to use the system's trusted root certificates. - * (This path is only valid for Debian-based systems.) */ - if (1 != SSL_CTX_load_verify_locations(ssl_ctx, crt, NULL)) { - err_openssl("SSL_CTX_load_verify_locations"); - goto error; + if (crt == NULL) { + X509_STORE *store; + /* Attempt to use the system's trusted root certificates. */ + store = SSL_CTX_get_cert_store(ssl_ctx); +#ifdef _WIN32 + if (add_cert_for_store(store, "CA") < 0 || + add_cert_for_store(store, "AuthRoot") < 0 || + add_cert_for_store(store, "ROOT") < 0) { + goto error; + } +#else // _WIN32 + if (X509_STORE_set_default_paths(store) != 1) { + err_openssl("X509_STORE_set_default_paths"); + goto error; + } +#endif // _WIN32 + } else { + if (SSL_CTX_load_verify_locations(ssl_ctx, crt, NULL) != 1) { + err_openssl("SSL_CTX_load_verify_locations"); + goto error; + } } /* Ask OpenSSL to verify the server certificate. Note that this * does NOT include verifying that the hostname is correct. @@ -368,9 +409,6 @@ main(int argc, char **argv) * "wrapping" OpenSSL's routine, not replacing it. */ SSL_CTX_set_cert_verify_callback(ssl_ctx, cert_verify_callback, (void *) host); -#else // _WIN32 - (void)crt; -#endif // _WIN32 // Create event base base = event_base_new(); @@ -474,25 +512,29 @@ cleanup: evhttp_connection_free(evcon); if (http_uri) evhttp_uri_free(http_uri); - event_base_free(base); + if (base) + event_base_free(base); if (ssl_ctx) SSL_CTX_free(ssl_ctx); if (type == HTTP && ssl) SSL_free(ssl); -#if OPENSSL_VERSION_NUMBER < 0x10100000L +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \ + (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) EVP_cleanup(); ERR_free_strings(); -#ifdef EVENT__HAVE_ERR_REMOVE_THREAD_STATE - ERR_remove_thread_state(NULL); -#else +#if OPENSSL_VERSION_NUMBER < 0x10000000L ERR_remove_state(0); +#else + ERR_remove_thread_state(NULL); #endif + CRYPTO_cleanup_all_ex_data(); sk_SSL_COMP_free(SSL_COMP_get_compression_methods()); -#endif /*OPENSSL_VERSION_NUMBER < 0x10100000L */ +#endif /* (OPENSSL_VERSION_NUMBER < 0x10100000L) || \ + (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) */ #ifdef _WIN32 WSACleanup(); |