diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-03-09 13:19:48 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-03-09 13:20:02 +0000 |
commit | 58daab21cd043e1dc37024a7f99b396788372918 (patch) | |
tree | 96771e43bb69f7c1c2b0b4f7374cb74d7866d0cb /web/server/h2o/libh2o/deps/ssl-conservatory/openssl/test_client.c | |
parent | Releasing debian version 1.43.2-1. (diff) | |
download | netdata-58daab21cd043e1dc37024a7f99b396788372918.tar.xz netdata-58daab21cd043e1dc37024a7f99b396788372918.zip |
Merging upstream version 1.44.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'web/server/h2o/libh2o/deps/ssl-conservatory/openssl/test_client.c')
-rw-r--r-- | web/server/h2o/libh2o/deps/ssl-conservatory/openssl/test_client.c | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/test_client.c b/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/test_client.c new file mode 100644 index 000000000..916a22ed8 --- /dev/null +++ b/web/server/h2o/libh2o/deps/ssl-conservatory/openssl/test_client.c @@ -0,0 +1,142 @@ +/* + * Sample HTTPS client to demonstrate how to do certificate validation using + * OpenSSL. + * This client will securely connect to www.isecpartners.com:443 and print the + * server's response to an HTTP GET request. + * + * Please read "everything-you-wanted-to-know-about-openssl.pdf" before + * attempting to use this code. This whitepaper describes how the code works, + * how it should be used, and what its limitations are. + * + * Author: Alban Diquet + * License: See LICENSE + * + */ + +#include <stdio.h> +#include <openssl/ssl.h> +#include <openssl/err.h> +#include <openssl/rand.h> + +#include "openssl_hostname_validation.h" + + +// Sample SSL client for https://www.isecpartners.com +#define TARGET_HOST "www.isecpartners.com" +#define TARGET_PORT "443" + +// CA certificate that signed www.isecpartners.com's certificate +#define TRUSTED_CA_PATHNAME "DigiCertHighAssuranceEVRootCA.pem" + + + +#define TARGET_SERVER TARGET_HOST":"TARGET_PORT +// 'High' cipher suites minus Anonymous DH and Camellia +#define SECURE_CIPHER_LIST "RC4-SHA:HIGH:!ADH:!AECDH:!CAMELLIA" + +/* Sends an HTTP GET and prints the server's response */ +static void send_http_get_and_print(BIO * sbio) { + int len; + char tmpbuf[1024]; + BIO * out = BIO_new_fp(stdout, BIO_NOCLOSE); + + BIO_puts(sbio, "GET / HTTP/1.0\n\n"); + for(;;) { + len = BIO_read(sbio, tmpbuf, 1024); + if(len <= 0) break; + BIO_write(out, tmpbuf, len); + } + BIO_free(out); +} + + +int main(int argc, char *argv[]) { + BIO *sbio; + SSL_CTX *ssl_ctx; + SSL *ssl; + X509 *server_cert; + + // Initialize OpenSSL + SSL_library_init(); + SSL_load_error_strings(); + + // Check OpenSSL PRNG + if(RAND_status() != 1) { + fprintf(stderr, "OpenSSL PRNG not seeded with enough data."); + goto error_1; + } + + ssl_ctx = SSL_CTX_new(TLSv1_client_method()); + + // Enable certificate validation + SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL); + // Configure the CA trust store to be used + if (SSL_CTX_load_verify_locations(ssl_ctx, TRUSTED_CA_PATHNAME, NULL) != 1) { + fprintf(stderr, "Couldn't load certificate trust store.\n"); + goto error_2; + } + + // Only support secure cipher suites + if (SSL_CTX_set_cipher_list(ssl_ctx, SECURE_CIPHER_LIST) != 1) + goto error_2; + + // Create the SSL connection + sbio = BIO_new_ssl_connect(ssl_ctx); + BIO_get_ssl(sbio, &ssl); + if(!ssl) { + fprintf(stderr, "Can't locate SSL pointer\n"); + goto error_3; + } + + // Do the SSL handshake + BIO_set_conn_hostname(sbio, TARGET_SERVER); + if(SSL_do_handshake(ssl) <= 0) { + // SSL Handshake failed + long verify_err = SSL_get_verify_result(ssl); + if (verify_err != X509_V_OK) { + // It failed because the certificate chain validation failed + fprintf(stderr, "Certificate chain validation failed: %s\n", X509_verify_cert_error_string(verify_err)); + } + else { + // It failed for another reason + ERR_print_errors_fp(stderr); + } + goto error_3; + } + + // Recover the server's certificate + server_cert = SSL_get_peer_certificate(ssl); + if (server_cert == NULL) { + // The handshake was successful although the server did not provide a certificate + // Most likely using an insecure anonymous cipher suite... get out! + goto error_4; + } + + // Validate the hostname + if (validate_hostname(TARGET_HOST, server_cert) != MatchFound) { + fprintf(stderr, "Hostname validation failed.\n"); + goto error_5; + } + + // Hostname validation succeeded; we can start sending data + send_http_get_and_print(sbio); + + +error_5: + X509_free(server_cert); + +error_4: + BIO_ssl_shutdown(sbio); + +error_3: + BIO_free_all(sbio); + +error_2: + SSL_CTX_free(ssl_ctx); + +error_1: // OpenSSL cleanup + EVP_cleanup(); + ERR_free_strings(); + + return 0; +} |