X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=test%2Fssltest.c;h=8451a9e176d0b277e9a846c2e51389139f819984;hp=68d48d1d739b6c4f649689eb0ff03c271b653df7;hb=bc9d9ce27a0c4d525e9c4e145993756fe3a7da23;hpb=fe6ef2472db933f01b59cad82aa925736935984b diff --git a/test/ssltest.c b/test/ssltest.c index 68d48d1d73..8451a9e176 100644 --- a/test/ssltest.c +++ b/test/ssltest.c @@ -1,4 +1,3 @@ -/* ssl/ssltest.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -212,10 +211,6 @@ #define COMP_ZLIB 1 static int verify_callback(int ok, X509_STORE_CTX *ctx); -#ifndef OPENSSL_NO_RSA -static RSA *tmp_rsa_cb(SSL *s, int is_export, int keylength); -static void free_tmp_rsa(void); -#endif static int app_verify_callback(X509_STORE_CTX *ctx, void *arg); #define APP_CALLBACK_STRING "Test Callback Argument" struct app_verify_arg { @@ -257,7 +252,7 @@ typedef struct srp_client_arg_st { static char *ssl_give_srp_client_pwd_cb(SSL *s, void *arg) { SRP_CLIENT_ARG *srp_client_arg = (SRP_CLIENT_ARG *)arg; - return BUF_strdup((char *)srp_client_arg->srppassin); + return OPENSSL_strdup((char *)srp_client_arg->srppassin); } /* SRP server */ @@ -371,6 +366,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 @@ -775,13 +775,20 @@ static void sv_usage(void) 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"); @@ -822,6 +829,11 @@ static void sv_usage(void) fprintf(stderr, " -alpn_server - have server side offer ALPN\n"); fprintf(stderr, " -alpn_expected - the ALPN protocol that should be negotiated\n"); + fprintf(stderr, " -server_min_proto - Minimum version the server should support\n"); + fprintf(stderr, " -server_max_proto - Maximum version the server should support\n"); + fprintf(stderr, " -client_min_proto - Minimum version the client should support\n"); + fprintf(stderr, " -client_max_proto - Maximum version the client should support\n"); + fprintf(stderr, " -should_negotiate - The version that should be negotiated, fail-client or fail-server\n"); } static void print_key_details(BIO *out, EVP_PKEY *key) @@ -946,17 +958,63 @@ 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 = { APP_CALLBACK_STRING, 0, 0, NULL, NULL }; + char *p; #ifndef OPENSSL_NO_EC char *named_curve = NULL; #endif @@ -993,11 +1051,11 @@ int main(int argc, char *argv[]) #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; @@ -1007,15 +1065,9 @@ int main(int argc, char *argv[]) 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); @@ -1126,20 +1178,13 @@ int main(int argc, char *argv[]) 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) { + dtls = 1; } else if (strncmp(*argv, "-num", 4) == 0) { if (--argc < 1) goto bad; @@ -1229,6 +1274,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]; @@ -1287,12 +1352,34 @@ 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); } +#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 @@ -1305,10 +1392,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); } @@ -1372,21 +1459,31 @@ int main(int argc, char *argv[]) * (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 #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); @@ -1483,10 +1580,6 @@ int main(int argc, char *argv[]) (void)no_ecdhe; #endif -#ifndef OPENSSL_NO_RSA - SSL_CTX_set_tmp_rsa_callback(s_ctx, tmp_rsa_cb); -#endif - if ((!SSL_CTX_load_verify_locations(s_ctx, CAfile, CApath)) || (!SSL_CTX_set_default_verify_paths(s_ctx)) || (!SSL_CTX_load_verify_locations(c_ctx, CAfile, CApath)) || @@ -1667,6 +1760,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) { @@ -1682,6 +1784,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, ""); } @@ -1704,6 +1823,7 @@ int main(int argc, char *argv[]) #endif } + err: SSL_free(s_ssl); SSL_free(c_ssl); @@ -1716,17 +1836,17 @@ int main(int argc, char *argv[]) BIO_free(bio_stdout); -#ifndef OPENSSL_NO_RSA - free_tmp_rsa(); -#endif #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(); +#ifndef OPENSSL_NO_CRYPTO_MDEBUG CRYPTO_mem_leaks(bio_err); +#endif BIO_free(bio_err); EXIT(ret); } @@ -1738,6 +1858,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 */ @@ -1830,6 +1952,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; } /* @@ -1855,6 +1978,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; } /* @@ -1907,6 +2031,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". */ @@ -1927,6 +2052,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 */ @@ -2094,6 +2220,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; } @@ -2119,6 +2250,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; @@ -2211,6 +2344,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; } @@ -2239,6 +2373,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; } @@ -2275,6 +2410,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; } @@ -2310,6 +2446,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; } @@ -2380,6 +2517,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); } @@ -2834,39 +2976,6 @@ static int app_verify_callback(X509_STORE_CTX *ctx, void *arg) return (ok); } -#ifndef OPENSSL_NO_RSA -static RSA *rsa_tmp = NULL; - -static RSA *tmp_rsa_cb(SSL *s, int is_export, int keylength) -{ - BIGNUM *bn = NULL; - if (rsa_tmp == NULL) { - bn = BN_new(); - rsa_tmp = RSA_new(); - if (!bn || !rsa_tmp || !BN_set_word(bn, RSA_F4)) { - BIO_printf(bio_err, "Memory error..."); - goto end; - } - printf("Generating temp (%d bit) RSA key...", keylength); - if (!RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL)) { - BIO_printf(bio_err, "Error generating key."); - RSA_free(rsa_tmp); - rsa_tmp = NULL; - } - end: - printf("\n"); - } - BN_free(bn); - return (rsa_tmp); -} - -static void free_tmp_rsa(void) -{ - RSA_free(rsa_tmp); - rsa_tmp = NULL; -} -#endif - #ifndef OPENSSL_NO_DH /*- * These DH parameters have been generated as follows: @@ -3077,9 +3186,11 @@ static unsigned int psk_server_callback(SSL *ssl, const char *identity, 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(); @@ -3094,6 +3205,7 @@ static int do_test_cipherlist(void) tci = ci; } #endif +#ifndef OPENSSL_NO_TLS1 meth = TLSv1_method(); tci = NULL; while ((ci = meth->get_cipher(i++)) != NULL) { @@ -3105,6 +3217,7 @@ static int do_test_cipherlist(void) } tci = ci; } +#endif return 1; }