Loading test/recipes/80-test_ssl.t +8 −2 Original line number Diff line number Diff line Loading @@ -329,7 +329,7 @@ sub testssl { subtest 'standard SSL tests' => sub { ###################################################################### plan tests => 27; plan tests => 29; SKIP: { skip "SSLv3 is not supported by this OpenSSL build", 4 Loading Loading @@ -410,7 +410,7 @@ sub testssl { } SKIP: { skip "Neither SSLv3 nor any TLS version are supported by this OpenSSL build", 6 skip "Neither SSLv3 nor any TLS version are supported by this OpenSSL build", 8 if $no_anytls; SKIP: { Loading @@ -430,6 +430,12 @@ sub testssl { 'test sslv2/sslv3 with both client and server authentication via BIO pair'); ok(run(test([@ssltest, "-bio_pair", "-server_auth", "-client_auth", "-app_verify", @CA, @extra])), 'test sslv2/sslv3 with both client and server authentication via BIO pair and app verify'); ok(run(test([@ssltest, "-ipv4", @extra])), 'test TLS via IPv4'); ok(run(test([@ssltest, "-ipv6", @extra])), 'test TLS via IPv6'); } }; Loading test/ssltest.c +309 −8 Original line number Diff line number Diff line Loading @@ -732,6 +732,8 @@ static int debug = 0; 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); Loading Loading @@ -800,6 +802,8 @@ static void sv_usage(void) " -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"); Loading Loading @@ -1007,7 +1011,7 @@ int main(int argc, char *argv[]) { 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; Loading Loading @@ -1215,7 +1219,11 @@ int main(int argc, char *argv[]) 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) { Loading Loading @@ -1411,9 +1419,9 @@ int main(int argc, char *argv[]) #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, Loading Loading @@ -1777,10 +1785,22 @@ int main(int argc, char *argv[]) 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); 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; } Loading Loading @@ -1851,6 +1871,287 @@ int main(int argc, char *argv[]) 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; 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) { Loading Loading
test/recipes/80-test_ssl.t +8 −2 Original line number Diff line number Diff line Loading @@ -329,7 +329,7 @@ sub testssl { subtest 'standard SSL tests' => sub { ###################################################################### plan tests => 27; plan tests => 29; SKIP: { skip "SSLv3 is not supported by this OpenSSL build", 4 Loading Loading @@ -410,7 +410,7 @@ sub testssl { } SKIP: { skip "Neither SSLv3 nor any TLS version are supported by this OpenSSL build", 6 skip "Neither SSLv3 nor any TLS version are supported by this OpenSSL build", 8 if $no_anytls; SKIP: { Loading @@ -430,6 +430,12 @@ sub testssl { 'test sslv2/sslv3 with both client and server authentication via BIO pair'); ok(run(test([@ssltest, "-bio_pair", "-server_auth", "-client_auth", "-app_verify", @CA, @extra])), 'test sslv2/sslv3 with both client and server authentication via BIO pair and app verify'); ok(run(test([@ssltest, "-ipv4", @extra])), 'test TLS via IPv4'); ok(run(test([@ssltest, "-ipv6", @extra])), 'test TLS via IPv6'); } }; Loading
test/ssltest.c +309 −8 Original line number Diff line number Diff line Loading @@ -732,6 +732,8 @@ static int debug = 0; 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); Loading Loading @@ -800,6 +802,8 @@ static void sv_usage(void) " -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"); Loading Loading @@ -1007,7 +1011,7 @@ int main(int argc, char *argv[]) { 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; Loading Loading @@ -1215,7 +1219,11 @@ int main(int argc, char *argv[]) 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) { Loading Loading @@ -1411,9 +1419,9 @@ int main(int argc, char *argv[]) #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, Loading Loading @@ -1777,10 +1785,22 @@ int main(int argc, char *argv[]) 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); 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; } Loading Loading @@ -1851,6 +1871,287 @@ int main(int argc, char *argv[]) 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; 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) { Loading