/** * Run SSL handshake and store the resulting time value in the * 'time_map'. * * @param time_map where to store the current time * @param time_is_an_illusion * @param http whether to do an http request and take the date from that * instead. */ static void run_ssl (uint32_t *time_map, int time_is_an_illusion, int http) { BIO *s_bio; SSL_CTX *ctx; SSL *ssl; struct stat statbuf; uint32_t result_time; SSL_load_error_strings(); SSL_library_init(); ctx = NULL; if (0 == strcmp("sslv23", protocol)) { verb ("V: using SSLv23_client_method()"); ctx = SSL_CTX_new(SSLv23_client_method()); } else if (0 == strcmp("sslv3", protocol)) { verb ("V: using SSLv3_client_method()"); ctx = SSL_CTX_new(SSLv3_client_method()); } else if (0 == strcmp("tlsv1", protocol)) { verb ("V: using TLSv1_client_method()"); ctx = SSL_CTX_new(TLSv1_client_method()); } else die("Unsupported protocol `%s'", protocol); if (ctx == NULL) die("OpenSSL failed to support protocol `%s'", protocol); verb("V: Using OpenSSL for SSL"); if (ca_racket) { if (-1 == stat(ca_cert_container, &statbuf)) { die("Unable to stat CA certficate container %s", ca_cert_container); } else { switch (statbuf.st_mode & S_IFMT) { case S_IFREG: if (1 != SSL_CTX_load_verify_locations(ctx, ca_cert_container, NULL)) fprintf(stderr, "SSL_CTX_load_verify_locations failed"); break; case S_IFDIR: if (1 != SSL_CTX_load_verify_locations(ctx, NULL, ca_cert_container)) fprintf(stderr, "SSL_CTX_load_verify_locations failed"); break; default: if (1 != SSL_CTX_load_verify_locations(ctx, NULL, ca_cert_container)) { fprintf(stderr, "SSL_CTX_load_verify_locations failed"); die("Unable to load CA certficate container %s", ca_cert_container); } } } } if (NULL == (s_bio = make_ssl_bio(ctx))) die ("SSL BIO setup failed"); BIO_get_ssl(s_bio, &ssl); if (NULL == ssl) die ("SSL setup failed"); if (time_is_an_illusion) { SSL_set_info_callback(ssl, openssl_time_callback); } SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); verb("V: opening socket to %s:%s", host, port); if ( (1 != BIO_set_conn_hostname(s_bio, host)) || (1 != BIO_set_conn_port(s_bio, port)) ) die ("Failed to initialize connection to `%s:%s'", host, port); if (NULL == BIO_new_fp(stdout, BIO_NOCLOSE)) die ("BIO_new_fp returned error, possibly: %s", strerror(errno)); // This should run in seccomp // eg: prctl(PR_SET_SECCOMP, 1); if (1 != BIO_do_connect(s_bio)) // XXX TODO: BIO_should_retry() later? die ("SSL connection failed"); if (1 != BIO_do_handshake(s_bio)) die ("SSL handshake failed"); // from /usr/include/openssl/ssl3.h // ssl->s3->server_random is an unsigned char of 32 bits memcpy(&result_time, ssl->s3->server_random, sizeof (uint32_t)); verb("V: In TLS response, T=%lu", (unsigned long)ntohl(result_time)); if (http) { char buf[1024]; verb_debug ("V: Starting HTTP"); if (snprintf(buf, sizeof(buf), HTTP_REQUEST, HTTPS_USER_AGENT, hostname_to_verify) >= 1024) die("hostname too long"); buf[1023]='\0'; /* Unneeded. */ verb_debug ("V: Writing HTTP request"); if (1 != write_all_to_bio(s_bio, buf)) die ("write all to bio failed."); verb_debug ("V: Reading HTTP response"); if (1 != read_http_date_from_bio(s_bio, &result_time)) die ("read all from bio failed."); verb ("V: Received HTTP response. T=%lu", (unsigned long)result_time); result_time = htonl(result_time); } // Verify the peer certificate against the CA certs on the local system if (ca_racket) { inspect_key (ssl, hostname_to_verify); } else { verb ("V: Certificate verification skipped!"); } check_key_length(ssl); memcpy(time_map, &result_time, sizeof (uint32_t)); SSL_free(ssl); SSL_CTX_free(ctx); }
/** * Run SSL handshake and store the resulting time value in the * 'time_map'. * * @param time_map where to store the current time */ static void run_ssl (uint32_t *time_map, int time_is_an_illusion) { BIO *s_bio; SSL_CTX *ctx; SSL *ssl; struct stat statbuf; SSL_load_error_strings(); SSL_library_init(); ctx = NULL; if (0 == strcmp("sslv23", protocol)) { verb ("V: using SSLv23_client_method()\n"); ctx = SSL_CTX_new(SSLv23_client_method()); } else if (0 == strcmp("sslv3", protocol)) { verb ("V: using SSLv3_client_method()\n"); ctx = SSL_CTX_new(SSLv3_client_method()); } else if (0 == strcmp("tlsv1", protocol)) { verb ("V: using TLSv1_client_method()\n"); ctx = SSL_CTX_new(TLSv1_client_method()); } else die("Unsupported protocol `%s'\n", protocol); if (ctx == NULL) die("OpenSSL failed to support protocol `%s'\n", protocol); verb("V: Using OpenSSL for SSL\n"); if (ca_racket) { if (-1 == stat(ca_cert_container, &statbuf)) { die("Unable to stat CA certficate container %s\n", ca_cert_container); } else { switch (statbuf.st_mode & S_IFMT) { case S_IFREG: if (1 != SSL_CTX_load_verify_locations(ctx, ca_cert_container, NULL)) fprintf(stderr, "SSL_CTX_load_verify_locations failed\n"); break; case S_IFDIR: if (1 != SSL_CTX_load_verify_locations(ctx, NULL, ca_cert_container)) fprintf(stderr, "SSL_CTX_load_verify_locations failed\n"); break; default: if (1 != SSL_CTX_load_verify_locations(ctx, NULL, ca_cert_container)) { fprintf(stderr, "SSL_CTX_load_verify_locations failed\n"); die("Unable to load CA certficate container %s\n", ca_cert_container); } } } } if (NULL == (s_bio = make_ssl_bio(ctx))) die ("SSL BIO setup failed\n"); BIO_get_ssl(s_bio, &ssl); if (NULL == ssl) die ("SSL setup failed\n"); if (time_is_an_illusion) { SSL_set_info_callback(ssl, openssl_time_callback); } SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); verb("V: opening socket to %s:%s\n", host, port); if ( (1 != BIO_set_conn_hostname(s_bio, host)) || (1 != BIO_set_conn_port(s_bio, port)) ) die ("Failed to initialize connection to `%s:%s'\n", host, port); if (NULL == BIO_new_fp(stdout, BIO_NOCLOSE)) die ("BIO_new_fp returned error, possibly: %s", strerror(errno)); // This should run in seccomp // eg: prctl(PR_SET_SECCOMP, 1); if (1 != BIO_do_connect(s_bio)) // XXX TODO: BIO_should_retry() later? die ("SSL connection failed\n"); if (1 != BIO_do_handshake(s_bio)) die ("SSL handshake failed\n"); // Verify the peer certificate against the CA certs on the local system if (ca_racket) { inspect_key (ssl, hostname_to_verify); } else { verb ("V: Certificate verification skipped!\n"); } check_key_length(ssl); // from /usr/include/openssl/ssl3.h // ssl->s3->server_random is an unsigned char of 32 bits memcpy(time_map, ssl->s3->server_random, sizeof (uint32_t)); SSL_free(ssl); SSL_CTX_free(ctx); }