aboutsummaryrefslogtreecommitdiff
path: root/sample/https-client.c
diff options
context:
space:
mode:
Diffstat (limited to 'sample/https-client.c')
-rw-r--r--sample/https-client.c88
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();