diff options
Diffstat (limited to 'test/ssltest.c')
-rw-r--r-- | test/ssltest.c | 142 |
1 files changed, 137 insertions, 5 deletions
diff --git a/test/ssltest.c b/test/ssltest.c index 01b6058648..58e0f82030 100644 --- a/test/ssltest.c +++ b/test/ssltest.c @@ -367,6 +367,11 @@ static const char *alpn_client; static const char *alpn_server; static const char *alpn_expected; static unsigned char *alpn_selected; +static const char *server_min_proto; +static const char *server_max_proto; +static const char *client_min_proto; +static const char *client_max_proto; +static const char *should_negotiate; /*- * next_protos_parse parses a comma separated list of strings into a string @@ -776,6 +781,7 @@ static void sv_usage(void) #endif fprintf(stderr, " -tls1 - use TLSv1\n"); #ifndef OPENSSL_NO_DTLS + fprintf(stderr, " -dtls - use DTLS\n"); fprintf(stderr, " -dtls1 - use DTLSv1\n"); fprintf(stderr, " -dtls12 - use DTLSv1.2\n"); #endif @@ -818,6 +824,11 @@ static void sv_usage(void) fprintf(stderr, " -alpn_server <string> - have server side offer ALPN\n"); fprintf(stderr, " -alpn_expected <string> - the ALPN protocol that should be negotiated\n"); + fprintf(stderr, " -server_min_proto <string> - Minimum version the server should support\n"); + fprintf(stderr, " -server_max_proto <string> - Maximum version the server should support\n"); + fprintf(stderr, " -client_min_proto <string> - Minimum version the client should support\n"); + fprintf(stderr, " -client_max_proto <string> - Maximum version the client should support\n"); + fprintf(stderr, " -should_negotiate <string> - The version that should be negotiated, fail-client or fail-server\n"); } static void print_key_details(BIO *out, EVP_PKEY *key) @@ -942,13 +953,58 @@ static void lock_dbg_cb(int mode, int type, const char *file, int line) } } +/* + * protocol_from_string - converts a protocol version string to a number + * + * Returns -1 on failure or the version on success + */ +static int protocol_from_string(const char *value) +{ + struct protocol_versions { + const char *name; + int version; + }; + static const struct protocol_versions versions[] = { + {"ssl3", SSL3_VERSION}, + {"tls1", TLS1_VERSION}, + {"tls1.1", TLS1_1_VERSION}, + {"tls1.2", TLS1_2_VERSION}, + {"dtls1", DTLS1_VERSION}, + {"dtls1.2", DTLS1_2_VERSION}}; + size_t i; + size_t n = OSSL_NELEM(versions); + + for (i = 0; i < n; i++) + if (strcmp(versions[i].name, value) == 0) + return versions[i].version; + return -1; +} + +/* + * set_protocol_version - Sets protocol version minimum or maximum + * + * Returns 0 on failure and 1 on success + */ +static int set_protocol_version(const char *version, SSL *ssl, int setting) +{ + if (version != NULL) { + int ver = protocol_from_string(version); + if (ver < 0) { + BIO_printf(bio_err, "Error parsing: %s\n", version); + return 0; + } + return SSL_ctrl(ssl, setting, ver, NULL); + } + return 1; +} + int main(int argc, char *argv[]) { char *CApath = NULL, *CAfile = NULL; int badop = 0; int bio_pair = 0; int force = 0; - int dtls1 = 0, dtls12 = 0, tls1 = 0, ssl3 = 0, ret = 1; + 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 = @@ -1136,6 +1192,11 @@ int main(int argc, char *argv[]) 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; @@ -1225,6 +1286,26 @@ int main(int argc, char *argv[]) if (--argc < 1) goto bad; alpn_expected = *(++argv); + } else if (strcmp(*argv, "-server_min_proto") == 0) { + if (--argc < 1) + goto bad; + server_min_proto = *(++argv); + } else if (strcmp(*argv, "-server_max_proto") == 0) { + if (--argc < 1) + goto bad; + server_max_proto = *(++argv); + } else if (strcmp(*argv, "-client_min_proto") == 0) { + if (--argc < 1) + goto bad; + client_min_proto = *(++argv); + } else if (strcmp(*argv, "-client_max_proto") == 0) { + if (--argc < 1) + goto bad; + client_max_proto = *(++argv); + } else if (strcmp(*argv, "-should_negotiate") == 0) { + if (--argc < 1) + goto bad; + should_negotiate = *(++argv); } else { int rv; arg = argv[0]; @@ -1283,8 +1364,8 @@ int main(int argc, char *argv[]) goto end; } - if (ssl3 + tls1 + dtls1 + dtls12 > 1) { - fprintf(stderr, "At most one of -ssl3, -tls1, -dtls1 or -dtls12 should " + if (ssl3 + tls1 + dtls + dtls1 + dtls12 > 1) { + fprintf(stderr, "At most one of -ssl3, -tls1, -dtls, -dtls1 or -dtls12 should " "be requested.\n"); EXIT(1); } @@ -1301,10 +1382,10 @@ int main(int argc, char *argv[]) goto end; } - if (!ssl3 && !tls1 && !dtls1 && !dtls12 && number > 1 && !reuse && !force) { + if (!ssl3 && !tls1 && !dtls && !dtls1 && !dtls12 && number > 1 && !reuse && !force) { fprintf(stderr, "This case cannot work. Use -f to perform " "the test anyway (and\n-d to see what happens), " - "or add one of -ssl3, -tls1, -dtls1, -dtls12, -reuse\n" + "or add one of -ssl3, -tls1, -dtls, -dtls1, -dtls12, -reuse\n" "to avoid protocol mismatch.\n"); EXIT(1); } @@ -1378,6 +1459,8 @@ int main(int argc, char *argv[]) meth = DTLSv1_method(); else if (dtls12) meth = DTLSv1_2_method(); + else if (dtls) + meth = DTLS_method(); else #endif if (tls1) @@ -1659,6 +1742,15 @@ int main(int argc, char *argv[]) c_ssl = SSL_new(c_ctx); s_ssl = SSL_new(s_ctx); + if (!set_protocol_version(server_min_proto, s_ssl, SSL_CTRL_SET_MIN_PROTO_VERSION)) + goto end; + if (!set_protocol_version(server_max_proto, s_ssl, SSL_CTRL_SET_MAX_PROTO_VERSION)) + goto end; + if (!set_protocol_version(client_min_proto, c_ssl, SSL_CTRL_SET_MIN_PROTO_VERSION)) + goto end; + if (!set_protocol_version(client_max_proto, c_ssl, SSL_CTRL_SET_MAX_PROTO_VERSION)) + goto end; + BIO_printf(bio_stdout, "Doing handshakes=%d bytes=%ld\n", number, bytes); for (i = 0; i < number; i++) { if (!reuse) { @@ -1674,6 +1766,23 @@ int main(int argc, char *argv[]) if (ret) break; } + if (should_negotiate && ret == 0 && + strcmp(should_negotiate, "fail-server") != 0 && + strcmp(should_negotiate, "fail-client") != 0) { + int version = protocol_from_string(should_negotiate); + if (version < 0) { + BIO_printf(bio_err, "Error parsing: %s\n", should_negotiate); + ret = 1; + goto err; + } + if (SSL_version(c_ssl) != version) { + BIO_printf(bio_err, "Unxpected version negotiated. " + "Expected: %s, got %s\n", should_negotiate, SSL_get_version(c_ssl)); + ret = 1; + goto err; + } + } + if (!verbose) { print_details(c_ssl, ""); } @@ -1696,6 +1805,7 @@ int main(int argc, char *argv[]) #endif } + err: SSL_free(s_ssl); SSL_free(c_ssl); @@ -1728,6 +1838,8 @@ int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count, BIO *s_ssl_bio = NULL, *c_ssl_bio = NULL; BIO *server = NULL, *server_io = NULL, *client = NULL, *client_io = NULL; int ret = 1; + int err_in_client = 0; + int err_in_server = 0; size_t bufsiz = 256; /* small buffer for testing */ @@ -1820,6 +1932,7 @@ int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count, if (r < 0) { if (!BIO_should_retry(c_ssl_bio)) { fprintf(stderr, "ERROR in CLIENT\n"); + err_in_client = 1; goto err; } /* @@ -1845,6 +1958,7 @@ int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count, if (r < 0) { if (!BIO_should_retry(c_ssl_bio)) { fprintf(stderr, "ERROR in CLIENT\n"); + err_in_client = 1; goto err; } /* @@ -1897,6 +2011,7 @@ int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count, 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". */ @@ -1917,6 +2032,7 @@ int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count, if (r < 0) { if (!BIO_should_retry(s_ssl_bio)) { fprintf(stderr, "ERROR in SERVER\n"); + err_in_server = 1; goto err; } /* blah, blah */ @@ -2084,6 +2200,11 @@ int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count, 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; } @@ -2109,6 +2230,8 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count) int c_write, s_write; int do_server = 0, do_client = 0; int max_frag = 5 * 1024; + int err_in_client = 0; + int err_in_server = 0; bufsiz = count > 40 * 1024 ? 40 * 1024 : count; @@ -2201,6 +2324,7 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count) c_w = 1; } else { fprintf(stderr, "ERROR in CLIENT\n"); + err_in_client = 1; ERR_print_errors(bio_err); goto err; } @@ -2229,6 +2353,7 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count) c_w = 1; } else { fprintf(stderr, "ERROR in CLIENT\n"); + err_in_client = 1; ERR_print_errors(bio_err); goto err; } @@ -2265,6 +2390,7 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count) s_w = 1; } else { fprintf(stderr, "ERROR in SERVER\n"); + err_in_server = 1; ERR_print_errors(bio_err); goto err; } @@ -2300,6 +2426,7 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count) s_w = 1; } else { fprintf(stderr, "ERROR in SERVER\n"); + err_in_server = 1; ERR_print_errors(bio_err); goto err; } @@ -2370,6 +2497,11 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count) OPENSSL_free(cbuf); OPENSSL_free(sbuf); + 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); } |