-/* ssl/ssltest.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
static const char rnd_seed[] =
"string to make the random number generator think it has entropy";
+int doit_localhost(SSL *s_ssl, SSL *c_ssl, int family,
+ long bytes, clock_t *s_time, clock_t *c_time);
int doit_biopair(SSL *s_ssl, SSL *c_ssl, long bytes, clock_t *s_time,
clock_t *c_time);
int doit(SSL *s_ssl, SSL *c_ssl, long bytes);
fprintf(stderr, " -srpuser user - SRP username to use\n");
fprintf(stderr, " -srppass arg - password for 'user'\n");
#endif
-#ifndef OPENSSL_NO_SSL3_METHOD
+#ifndef OPENSSL_NO_SSL3
fprintf(stderr, " -ssl3 - use SSLv3\n");
#endif
+#ifndef OPENSSL_NO_TLS1
fprintf(stderr, " -tls1 - use TLSv1\n");
+#endif
#ifndef OPENSSL_NO_DTLS
fprintf(stderr, " -dtls - use DTLS\n");
+#ifndef OPENSSL_NO_DTLS1
fprintf(stderr, " -dtls1 - use DTLSv1\n");
+#endif
+#ifndef OPENSSL_NO_DTLS1_2
fprintf(stderr, " -dtls12 - use DTLSv1.2\n");
+#endif
#endif
fprintf(stderr, " -CApath arg - PEM format directory of CA's\n");
fprintf(stderr, " -CAfile arg - PEM format file of CA's\n");
" -c_key arg - Client key file (default: same as -c_cert)\n");
fprintf(stderr, " -cipher arg - The cipher list\n");
fprintf(stderr, " -bio_pair - Use BIO pairs\n");
+ fprintf(stderr, " -ipv4 - Use IPv4 connection on localhost\n");
+ fprintf(stderr, " -ipv6 - Use IPv6 connection on localhost\n");
fprintf(stderr, " -f - Test even cases that can't work\n");
fprintf(stderr,
" -time - measure processor time used by client and server\n");
{
char *CApath = NULL, *CAfile = NULL;
int badop = 0;
- int bio_pair = 0;
+ enum { BIO_MEM, BIO_PAIR, BIO_IPV4, BIO_IPV6 } bio_type = BIO_MEM;
int force = 0;
int dtls1 = 0, dtls12 = 0, dtls = 0, tls1 = 0, ssl3 = 0, ret = 1;
int client_auth = 0;
int server_auth = 0, i;
struct app_verify_arg app_verify_arg =
{ APP_CALLBACK_STRING, 0, 0, NULL, NULL };
+ char *p;
#ifndef OPENSSL_NO_EC
char *named_curve = NULL;
#endif
#ifdef OPENSSL_FIPS
int fips_mode = 0;
#endif
- int no_protocol = 0;
+ int no_protocol;
SSL_CONF_CTX *s_cctx = NULL, *c_cctx = NULL;
STACK_OF(OPENSSL_STRING) *conf_args = NULL;
- const char *arg = NULL, *argn = NULL;
+ char *arg = NULL, *argn = NULL;
verbose = 0;
debug = 0;
CRYPTO_set_locking_callback(lock_dbg_cb);
- /* enable memory leak checking unless explicitly disabled */
- if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL)
- && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))) {
- CRYPTO_malloc_debug_init();
- CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
- } else {
- /* OPENSSL_DEBUG_MEMORY=off */
- CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
- }
+ p = getenv("OPENSSL_DEBUG_MEMORY");
+ if (p != NULL && strcmp(p, "on") == 0)
+ CRYPTO_set_mem_debug(1);
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
RAND_seed(rnd_seed, sizeof rnd_seed);
else if (strcmp(*argv, "-tls1") == 0) {
tls1 = 1;
} else if (strcmp(*argv, "-ssl3") == 0) {
-#ifdef OPENSSL_NO_SSL3_METHOD
- no_protocol = 1;
-#endif
ssl3 = 1;
} else if (strcmp(*argv, "-dtls1") == 0) {
-#ifdef OPENSSL_NO_DTLS
- no_protocol = 1;
-#endif
dtls1 = 1;
} else if (strcmp(*argv, "-dtls12") == 0) {
-#ifdef OPENSSL_NO_DTLS
- no_protocol = 1;
-#endif
dtls12 = 1;
} else if (strcmp(*argv, "-dtls") == 0) {
-#ifdef OPENSSL_NO_DTLS
- no_protocol = 1;
-#endif
dtls = 1;
} else if (strncmp(*argv, "-num", 4) == 0) {
if (--argc < 1)
goto bad;
CAfile = *(++argv);
} else if (strcmp(*argv, "-bio_pair") == 0) {
- bio_pair = 1;
+ bio_type = BIO_PAIR;
+ } else if (strcmp(*argv, "-ipv4") == 0) {
+ bio_type = BIO_IPV4;
+ } else if (strcmp(*argv, "-ipv6") == 0) {
+ bio_type = BIO_IPV6;
} else if (strcmp(*argv, "-f") == 0) {
force = 1;
} else if (strcmp(*argv, "-time") == 0) {
EXIT(1);
}
+#ifdef OPENSSL_NO_SSL3
+ if (ssl3)
+ no_protocol = 1;
+ else
+#endif
+#ifdef OPENSSL_NO_TLS1
+ if (tls1)
+ no_protocol = 1;
+ else
+#endif
+#if defined(OPENSSL_NO_DTLS) || defined(OPENSSL_NO_DTLS1)
+ if (dtls1)
+ no_protocol = 1;
+ else
+#endif
+#if defined(OPENSSL_NO_DTLS) || defined(OPENSSL_NO_DTLS1_2)
+ if (dtls12)
+ no_protocol = 1;
+ else
+#endif
+ no_protocol = 0;
+
/*
* Testing was requested for a compiled-out protocol (e.g. SSLv3).
* Ideally, we would error out, but the generic test wrapper can't know
#ifdef OPENSSL_FIPS
if (fips_mode) {
if (!FIPS_mode_set(1)) {
- ERR_load_crypto_strings();
ERR_print_errors(bio_err);
EXIT(1);
} else
#endif
if (print_time) {
- if (!bio_pair) {
+ if (bio_type != BIO_PAIR) {
fprintf(stderr, "Using BIO pair (-bio_pair)\n");
- bio_pair = 1;
+ bio_type = BIO_PAIR;
}
if (number < 50 && !force)
fprintf(stderr,
/* if (cipher == NULL) cipher=getenv("SSL_CIPHER"); */
- SSL_library_init();
- SSL_load_error_strings();
-
#ifndef OPENSSL_NO_COMP
if (comp == COMP_ZLIB)
cm = COMP_zlib();
* (Otherwise we exit early.) However the compiler doesn't know this, so
* we ifdef.
*/
-#ifndef OPENSSL_NO_SSL3
- if (ssl3)
- meth = SSLv3_method();
- else
-#endif
#ifndef OPENSSL_NO_DTLS
+#ifndef OPENSSL_NO_DTLS1
if (dtls1)
meth = DTLSv1_method();
- else if (dtls12)
+ else
+#endif
+#ifndef OPENSSL_NO_DTLS1_2
+ if (dtls12)
meth = DTLSv1_2_method();
- else if (dtls)
+ else
+#endif
+ if (dtls)
meth = DTLS_method();
else
#endif
+#ifndef OPENSSL_NO_SSL3
+ if (ssl3)
+ meth = SSLv3_method();
+ else
+#endif
+#ifndef OPENSSL_NO_TLS1
if (tls1)
meth = TLSv1_method();
else
+#endif
meth = TLS_method();
c_ctx = SSL_CTX_new(meth);
goto end;
}
}
- if (bio_pair)
- ret = doit_biopair(s_ssl, c_ssl, bytes, &s_time, &c_time);
- else
+ switch (bio_type) {
+ case BIO_MEM:
ret = doit(s_ssl, c_ssl, bytes);
- if (ret) break;
+ break;
+ case BIO_PAIR:
+ ret = doit_biopair(s_ssl, c_ssl, bytes, &s_time, &c_time);
+ break;
+ case BIO_IPV4:
+ ret = doit_localhost(s_ssl, c_ssl, BIO_FAMILY_IPV4,
+ bytes, &s_time, &c_time);
+ break;
+ case BIO_IPV6:
+ ret = doit_localhost(s_ssl, c_ssl, BIO_FAMILY_IPV6,
+ bytes, &s_time, &c_time);
+ break;
+ }
+ if (ret) break;
}
if (should_negotiate && ret == 0 &&
BIO_free(bio_stdout);
-#ifndef OPENSSL_NO_ENGINE
- ENGINE_cleanup();
-#endif
- CONF_modules_unload(1);
- CRYPTO_cleanup_all_ex_data();
- ERR_free_strings();
- ERR_remove_thread_state(NULL);
- EVP_cleanup();
- CRYPTO_mem_leaks(bio_err);
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+ if (CRYPTO_mem_leaks(bio_err) <= 0)
+ ret = 1;
+#endif
BIO_free(bio_err);
EXIT(ret);
}
+int doit_localhost(SSL *s_ssl, SSL *c_ssl, int family, long count,
+ clock_t *s_time, clock_t *c_time)
+{
+ long cw_num = count, cr_num = count, sw_num = count, sr_num = count;
+ BIO *s_ssl_bio = NULL, *c_ssl_bio = NULL;
+ BIO *acpt = NULL, *server = NULL, *client = NULL;
+ char addr_str[40];
+ int ret = 1;
+ int err_in_client = 0;
+ int err_in_server = 0;
+
+ acpt = BIO_new_accept("0");
+ if (acpt == NULL)
+ goto err;
+ BIO_set_accept_ip_family(acpt, family);
+ BIO_set_bind_mode(acpt, BIO_SOCK_NONBLOCK | BIO_SOCK_REUSEADDR);
+ if (BIO_do_accept(acpt) <= 0)
+ goto err;
+
+ BIO_snprintf(addr_str, sizeof(addr_str), ":%s", BIO_get_accept_port(acpt));
+
+ client = BIO_new_connect(addr_str);
+ BIO_set_conn_ip_family(client, family);
+ if (!client)
+ goto err;
+
+ if (BIO_set_nbio(client, 1) <= 0)
+ goto err;
+ if (BIO_set_nbio(acpt, 1) <= 0)
+ goto err;
+
+ {
+ int st_connect = 0, st_accept = 0;
+
+ while(!st_connect || !st_accept) {
+ if (!st_connect) {
+ if (BIO_do_connect(client) <= 0) {
+ if (!BIO_should_retry(client))
+ goto err;
+ } else {
+ st_connect = 1;
+ }
+ }
+ if (!st_accept) {
+ if (BIO_do_accept(acpt) <= 0) {
+ if (!BIO_should_retry(acpt))
+ goto err;
+ } else {
+ st_accept = 1;
+ }
+ }
+ }
+ }
+ /* We're not interested in accepting further connects */
+ server = BIO_pop(acpt);
+ BIO_free_all(acpt);
+ acpt = NULL;
+
+ s_ssl_bio = BIO_new(BIO_f_ssl());
+ if (!s_ssl_bio)
+ goto err;
+
+ c_ssl_bio = BIO_new(BIO_f_ssl());
+ if (!c_ssl_bio)
+ goto err;
+
+ SSL_set_connect_state(c_ssl);
+ SSL_set_bio(c_ssl, client, client);
+ (void)BIO_set_ssl(c_ssl_bio, c_ssl, BIO_NOCLOSE);
+
+ SSL_set_accept_state(s_ssl);
+ SSL_set_bio(s_ssl, server, server);
+ (void)BIO_set_ssl(s_ssl_bio, s_ssl, BIO_NOCLOSE);
+
+ do {
+ /*-
+ * c_ssl_bio: SSL filter BIO
+ *
+ * client: I/O for SSL library
+ *
+ *
+ * server: I/O for SSL library
+ *
+ * s_ssl_bio: SSL filter BIO
+ */
+
+ /*
+ * We have non-blocking behaviour throughout this test program, but
+ * can be sure that there is *some* progress in each iteration; so we
+ * don't have to worry about ..._SHOULD_READ or ..._SHOULD_WRITE --
+ * we just try everything in each iteration
+ */
+
+ {
+ /* CLIENT */
+
+ char cbuf[1024 * 8];
+ int i, r;
+ clock_t c_clock = clock();
+
+ memset(cbuf, 0, sizeof(cbuf));
+
+ if (debug)
+ if (SSL_in_init(c_ssl))
+ printf("client waiting in SSL_connect - %s\n",
+ SSL_state_string_long(c_ssl));
+
+ if (cw_num > 0) {
+ /* Write to server. */
+
+ if (cw_num > (long)sizeof cbuf)
+ i = sizeof cbuf;
+ else
+ i = (int)cw_num;
+ r = BIO_write(c_ssl_bio, cbuf, i);
+ if (r < 0) {
+ if (!BIO_should_retry(c_ssl_bio)) {
+ fprintf(stderr, "ERROR in CLIENT\n");
+ err_in_client = 1;
+ goto err;
+ }
+ /*
+ * BIO_should_retry(...) can just be ignored here. The
+ * library expects us to call BIO_write with the same
+ * arguments again, and that's what we will do in the
+ * next iteration.
+ */
+ } else if (r == 0) {
+ fprintf(stderr, "SSL CLIENT STARTUP FAILED\n");
+ goto err;
+ } else {
+ if (debug)
+ printf("client wrote %d\n", r);
+ cw_num -= r;
+ }
+ }
+
+ if (cr_num > 0) {
+ /* Read from server. */
+
+ r = BIO_read(c_ssl_bio, cbuf, sizeof(cbuf));
+ if (r < 0) {
+ if (!BIO_should_retry(c_ssl_bio)) {
+ fprintf(stderr, "ERROR in CLIENT\n");
+ err_in_client = 1;
+ goto err;
+ }
+ /*
+ * Again, "BIO_should_retry" can be ignored.
+ */
+ } else if (r == 0) {
+ fprintf(stderr, "SSL CLIENT STARTUP FAILED\n");
+ goto err;
+ } else {
+ if (debug)
+ printf("client read %d\n", r);
+ cr_num -= r;
+ }
+ }
+
+ /*
+ * c_time and s_time increments will typically be very small
+ * (depending on machine speed and clock tick intervals), but
+ * sampling over a large number of connections should result in
+ * fairly accurate figures. We cannot guarantee a lot, however
+ * -- if each connection lasts for exactly one clock tick, it
+ * will be counted only for the client or only for the server or
+ * even not at all.
+ */
+ *c_time += (clock() - c_clock);
+ }
+
+ {
+ /* SERVER */
+
+ char sbuf[1024 * 8];
+ int i, r;
+ clock_t s_clock = clock();
+
+ memset(sbuf, 0, sizeof(sbuf));
+
+ if (debug)
+ if (SSL_in_init(s_ssl))
+ printf("server waiting in SSL_accept - %s\n",
+ SSL_state_string_long(s_ssl));
+
+ if (sw_num > 0) {
+ /* Write to client. */
+
+ if (sw_num > (long)sizeof sbuf)
+ i = sizeof sbuf;
+ else
+ i = (int)sw_num;
+ r = BIO_write(s_ssl_bio, sbuf, i);
+ if (r < 0) {
+ if (!BIO_should_retry(s_ssl_bio)) {
+ fprintf(stderr, "ERROR in SERVER\n");
+ err_in_server = 1;
+ goto err;
+ }
+ /* Ignore "BIO_should_retry". */
+ } else if (r == 0) {
+ fprintf(stderr, "SSL SERVER STARTUP FAILED\n");
+ goto err;
+ } else {
+ if (debug)
+ printf("server wrote %d\n", r);
+ sw_num -= r;
+ }
+ }
+
+ if (sr_num > 0) {
+ /* Read from client. */
+
+ r = BIO_read(s_ssl_bio, sbuf, sizeof(sbuf));
+ if (r < 0) {
+ if (!BIO_should_retry(s_ssl_bio)) {
+ fprintf(stderr, "ERROR in SERVER\n");
+ err_in_server = 1;
+ goto err;
+ }
+ /* blah, blah */
+ } else if (r == 0) {
+ fprintf(stderr, "SSL SERVER STARTUP FAILED\n");
+ goto err;
+ } else {
+ if (debug)
+ printf("server read %d\n", r);
+ sr_num -= r;
+ }
+ }
+
+ *s_time += (clock() - s_clock);
+ }
+ }
+ while (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0);
+
+ if (verbose)
+ print_details(c_ssl, "DONE via TCP connect: ");
+#ifndef OPENSSL_NO_NEXTPROTONEG
+ if (verify_npn(c_ssl, s_ssl) < 0) {
+ ret = 1;
+ goto end;
+ }
+#endif
+ if (verify_serverinfo() < 0) {
+ fprintf(stderr, "Server info verify error\n");
+ ret = 1;
+ goto err;
+ }
+ if (verify_alpn(c_ssl, s_ssl) < 0) {
+ ret = 1;
+ goto err;
+ }
+
+ if (custom_ext_error) {
+ fprintf(stderr, "Custom extension error\n");
+ ret = 1;
+ goto err;
+ }
+
+ end:
+ ret = 0;
+
+ err:
+ ERR_print_errors(bio_err);
+
+ BIO_free_all(acpt);
+ BIO_free(server);
+ BIO_free(client);
+ BIO_free(s_ssl_bio);
+ BIO_free(c_ssl_bio);
+
+ if (should_negotiate != NULL && strcmp(should_negotiate, "fail-client") == 0)
+ ret = (err_in_client != 0) ? 0 : 1;
+ else if (should_negotiate != NULL && strcmp(should_negotiate, "fail-server") == 0)
+ ret = (err_in_server != 0) ? 0 : 1;
+
+ return ret;
+}
+
int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count,
clock_t *s_time, clock_t *c_time)
{
static int do_test_cipherlist(void)
{
+#if !defined(OPENSSL_NO_SSL3) || !defined(OPENSSL_NO_TLS1)
int i = 0;
const SSL_METHOD *meth;
const SSL_CIPHER *ci, *tci = NULL;
+#endif
#ifndef OPENSSL_NO_SSL3
meth = SSLv3_method();
tci = ci;
}
#endif
+#ifndef OPENSSL_NO_TLS1
meth = TLSv1_method();
tci = NULL;
while ((ci = meth->get_cipher(i++)) != NULL) {
}
tci = ci;
}
+#endif
return 1;
}