X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=test%2Fssltest.c;h=c3faad77ea92850803f21fde5e8949ac2c309bad;hp=508fedd613f8f71a2f9d477a63a60fc7b83a7b27;hb=885e601d97ff235615809db832874ff8dad9cb24;hpb=dee502be89e78e2979e3bd1d7724cf79daa6ef61 diff --git a/test/ssltest.c b/test/ssltest.c index 508fedd613..c3faad77ea 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. * @@ -142,6 +141,7 @@ /* Or gethostname won't be declared properly on Linux and GNU platforms. */ #define _BSD_SOURCE 1 +#define _DEFAULT_SOURCE 1 #include #include @@ -187,7 +187,11 @@ # include #endif #include +#ifndef OPENSSL_NO_CT +# include +#endif +#include "internal/threads.h" #include "../ssl/ssl_locl.h" /* @@ -204,32 +208,16 @@ # include OPENSSL_UNISTD #endif -#ifdef OPENSSL_SYS_VMS -# define TEST_SERVER_CERT "SYS$DISK:[-.APPS]SERVER.PEM" -# define TEST_CLIENT_CERT "SYS$DISK:[-.APPS]CLIENT.PEM" -#elif defined(OPENSSL_SYS_WINCE) -# define TEST_SERVER_CERT "\\OpenSSL\\server.pem" -# define TEST_CLIENT_CERT "\\OpenSSL\\client.pem" -#elif defined(OPENSSL_SYS_NETWARE) -# define TEST_SERVER_CERT "\\openssl\\apps\\server.pem" -# define TEST_CLIENT_CERT "\\openssl\\apps\\client.pem" -#else -# define TEST_SERVER_CERT "../apps/server.pem" -# define TEST_CLIENT_CERT "../apps/client.pem" -#endif +static SSL_CTX *s_ctx = NULL; +static SSL_CTX *s_ctx2 = NULL; /* - * There is really no standard for this, so let's assign some tentative - * numbers. In any case, these numbers are only for this test + * There is really no standard for this, so let's assign something + * only for this test */ -#define COMP_RLE 255 #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 { @@ -271,7 +259,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 */ @@ -303,9 +291,9 @@ static BIO *bio_stdout = NULL; #ifndef OPENSSL_NO_NEXTPROTONEG /* Note that this code assumes that this is only a one element list: */ static const char NEXT_PROTO_STRING[] = "\x09testproto"; -int npn_client = 0; -int npn_server = 0; -int npn_server_reject = 0; +static int npn_client = 0; +static int npn_server = 0; +static int npn_server_reject = 0; static int cb_client_npn(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, @@ -382,9 +370,57 @@ static int verify_npn(SSL *client, SSL *server) #endif static const char *alpn_client; -static const char *alpn_server; +static char *alpn_server; +static char *alpn_server2; 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; +static const char *sn_client; +static const char *sn_server1; +static const char *sn_server2; +static int sn_expect = 0; + +static int servername_cb(SSL *s, int *ad, void *arg) +{ + const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name); + if (sn_server2 == NULL) { + BIO_printf(bio_stdout, "Servername 2 is NULL\n"); + return SSL_TLSEXT_ERR_NOACK; + } + + if (servername) { + if (s_ctx2 != NULL && sn_server2 != NULL && + !strcasecmp(servername, sn_server2)) { + BIO_printf(bio_stdout, "Switching server context.\n"); + SSL_set_SSL_CTX(s, s_ctx2); + } + } + return SSL_TLSEXT_ERR_OK; +} +static int verify_servername(SSL *client, SSL *server) +{ + /* just need to see if sn_context is what we expect */ + SSL_CTX* ctx = SSL_get_SSL_CTX(server); + if (sn_expect == 0) + return 0; + if (sn_expect == 1 && ctx == s_ctx) + return 0; + if (sn_expect == 2 && ctx == s_ctx2) + return 0; + BIO_printf(bio_stdout, "Servername: expected context %d\n", sn_expect); + if (ctx == s_ctx2) + BIO_printf(bio_stdout, "Servername: context is 2\n"); + else if (ctx == s_ctx) + BIO_printf(bio_stdout, "Servername: context is 1\n"); + else + BIO_printf(bio_stdout, "Servername: context is unknown\n"); + return -1; +} + /*- * next_protos_parse parses a comma separated list of strings into a string @@ -395,7 +431,7 @@ static unsigned char *alpn_selected; * * returns: a malloced buffer or NULL on failure. */ -static unsigned char *next_protos_parse(unsigned short *outlen, +static unsigned char *next_protos_parse(size_t *outlen, const char *in) { size_t len; @@ -431,12 +467,13 @@ static int cb_server_alpn(SSL *s, const unsigned char **out, unsigned int inlen, void *arg) { unsigned char *protos; - unsigned short protos_len; + size_t protos_len; + char* alpn_str = arg; - protos = next_protos_parse(&protos_len, alpn_server); + protos = next_protos_parse(&protos_len, alpn_str); if (protos == NULL) { fprintf(stderr, "failed to parser ALPN server protocol string: %s\n", - alpn_server); + alpn_str); abort(); } @@ -466,12 +503,15 @@ static int verify_alpn(SSL *client, SSL *server) SSL_get0_alpn_selected(client, &client_proto, &client_proto_len); SSL_get0_alpn_selected(server, &server_proto, &server_proto_len); - if (alpn_selected != NULL) { - OPENSSL_free(alpn_selected); - alpn_selected = NULL; + OPENSSL_free(alpn_selected); + alpn_selected = NULL; + + if (client_proto_len != server_proto_len) { + BIO_printf(bio_stdout, "ALPN selected protocols differ!\n"); + goto err; } - if (client_proto_len != server_proto_len || + if (client_proto != NULL && memcmp(client_proto, server_proto, client_proto_len) != 0) { BIO_printf(bio_stdout, "ALPN selected protocols differ!\n"); goto err; @@ -499,13 +539,18 @@ static int verify_alpn(SSL *client, SSL *server) BIO_printf(bio_stdout, "', server: '"); BIO_write(bio_stdout, server_proto, server_proto_len); BIO_printf(bio_stdout, "'\n"); - BIO_printf(bio_stdout, "ALPN configured: client: '%s', server: '%s'\n", - alpn_client, alpn_server); + BIO_printf(bio_stdout, "ALPN configured: client: '%s', server: '", + alpn_client); + if (SSL_get_SSL_CTX(server) == s_ctx2) { + BIO_printf(bio_stdout, "%s'\n", + alpn_server2); + } else { + BIO_printf(bio_stdout, "%s'\n", + alpn_server); + } return -1; } -#define SCT_EXT_TYPE 18 - /* * WARNING : below extension types are *NOT* IETF assigned, and could * conflict if these types are reassigned and handled specially by OpenSSL @@ -517,30 +562,30 @@ static int verify_alpn(SSL *client, SSL *server) #define CUSTOM_EXT_TYPE_2 1002 #define CUSTOM_EXT_TYPE_3 1003 -const char custom_ext_cli_string[] = "abc"; -const char custom_ext_srv_string[] = "defg"; +static const char custom_ext_cli_string[] = "abc"; +static const char custom_ext_srv_string[] = "defg"; /* These set from cmdline */ -char *serverinfo_file = NULL; -int serverinfo_sct = 0; -int serverinfo_tack = 0; +static char *serverinfo_file = NULL; +static int serverinfo_sct = 0; +static int serverinfo_tack = 0; /* These set based on extension callbacks */ -int serverinfo_sct_seen = 0; -int serverinfo_tack_seen = 0; -int serverinfo_other_seen = 0; +static int serverinfo_sct_seen = 0; +static int serverinfo_tack_seen = 0; +static int serverinfo_other_seen = 0; /* This set from cmdline */ -int custom_ext = 0; +static int custom_ext = 0; /* This set based on extension callbacks */ -int custom_ext_error = 0; +static int custom_ext_error = 0; static int serverinfo_cli_parse_cb(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *arg) { - if (ext_type == SCT_EXT_TYPE) + if (ext_type == TLSEXT_TYPE_signed_certificate_timestamp) serverinfo_sct_seen++; else if (ext_type == TACK_EXT_TYPE) serverinfo_tack_seen++; @@ -743,6 +788,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); @@ -769,28 +816,37 @@ static void sv_usage(void) " -bytes - number of bytes to swap between client/server\n"); #ifndef OPENSSL_NO_DH fprintf(stderr, - " -dhe1024 - use 1024 bit key (safe prime) for DHE\n"); + " -dhe512 - use 512 bit key for DHE (to test failure)\n"); + fprintf(stderr, + " -dhe1024 - use 1024 bit key (safe prime) for DHE (default, no-op)\n"); fprintf(stderr, " -dhe1024dsa - use 1024 bit key (with 160-bit subprime) for DHE\n"); fprintf(stderr, " -no_dhe - disable DHE\n"); #endif #ifndef OPENSSL_NO_EC - fprintf(stderr, " -no_ecdhe - disable ECDHE\n"); + fprintf(stderr, " -no_ecdhe - disable ECDHE\nTODO(openssl-team): no_ecdhe was broken by auto ecdh. Make this work again.\n"); #endif #ifndef OPENSSL_NO_PSK fprintf(stderr, " -psk arg - PSK in hex (without 0x)\n"); #endif #ifndef OPENSSL_NO_SRP - fprintf(stderr, " -srpuser user - SRP username to use\n"); - fprintf(stderr, " -srppass arg - password for 'user'\n"); + 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"); @@ -802,17 +858,12 @@ 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"); fprintf(stderr, " -zlib - use zlib compression\n"); - fprintf(stderr, " -rle - use rle compression\n"); -#ifndef OPENSSL_NO_EC - fprintf(stderr, - " -named_curve arg - Elliptic curve name to use for ephemeral ECDH keys.\n" - " Use \"openssl ecparam -list_curves\" for all names\n" - " (default is sect163r2).\n"); -#endif fprintf(stderr, " -test_cipherlist - Verifies the order of the ssl cipher lists.\n" " When this option is requested, the cipherlist\n" @@ -830,8 +881,25 @@ static void sv_usage(void) " -custom_ext - try various custom extension callbacks\n"); fprintf(stderr, " -alpn_client - have client side offer ALPN\n"); fprintf(stderr, " -alpn_server - have server side offer ALPN\n"); + fprintf(stderr, " -alpn_server1 - alias for -alpn_server\n"); + fprintf(stderr, " -alpn_server2 - have server side context 2 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"); +#ifndef OPENSSL_NO_CT + fprintf(stderr, " -noct - no certificate transparency\n"); + fprintf(stderr, " -requestct - request certificate transparency\n"); + fprintf(stderr, " -requirect - require certificate transparency\n"); +#endif + fprintf(stderr, " -sn_client - have client request this servername\n"); + fprintf(stderr, " -sn_server1 - have server context 1 respond to this servername\n"); + fprintf(stderr, " -sn_server2 - have server context 2 respond to this servername\n"); + fprintf(stderr, " -sn_expect1 - expected server 1\n"); + fprintf(stderr, " -sn_expect2 - expected server 2\n"); } static void print_key_details(BIO *out, EVP_PKEY *key) @@ -902,79 +970,63 @@ static void print_details(SSL *c_ssl, const char *prefix) BIO_printf(bio_stdout, "\n"); } -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) { - static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */ - const char *errstr = NULL; - int rw; - - rw = mode & (CRYPTO_READ | CRYPTO_WRITE); - if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE))) { - errstr = "invalid mode"; - goto err; - } - - if (type < 0 || type >= CRYPTO_NUM_LOCKS) { - errstr = "type out of bounds"; - goto err; - } - - if (mode & CRYPTO_LOCK) { - if (modes[type]) { - errstr = "already locked"; - /* - * must not happen in a single-threaded program (would deadlock) - */ - goto err; - } - - modes[type] = rw; - } else if (mode & CRYPTO_UNLOCK) { - if (!modes[type]) { - errstr = "not locked"; - goto err; - } + 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; +} - if (modes[type] != rw) { - errstr = (rw == CRYPTO_READ) ? - "CRYPTO_r_unlock on write lock" : - "CRYPTO_w_unlock on read lock"; +/* + * 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; } - - modes[type] = 0; - } else { - errstr = "invalid mode"; - goto err; - } - - err: - if (errstr) { - /* we cannot use bio_err here */ - fprintf(stderr, - "openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d\n", - errstr, mode, type, file, line); + 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; + enum { BIO_MEM, BIO_PAIR, BIO_IPV4, BIO_IPV6 } bio_type = BIO_MEM; 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 *server_cert = TEST_SERVER_CERT; - char *server_key = NULL; - char *client_cert = TEST_CLIENT_CERT; - char *client_key = NULL; -#ifndef OPENSSL_NO_EC - char *named_curve = NULL; -#endif - SSL_CTX *s_ctx = NULL; + char *p; SSL_CTX *c_ctx = NULL; const SSL_METHOD *meth = NULL; SSL *c_ssl, *s_ssl; @@ -982,10 +1034,7 @@ int main(int argc, char *argv[]) long bytes = 256L; #ifndef OPENSSL_NO_DH DH *dh; - int dhe1024 = 0, dhe1024dsa = 0; -#endif -#ifndef OPENSSL_NO_EC - EC_KEY *ecdh = NULL; + int dhe512 = 0, dhe1024dsa = 0; #endif #ifndef OPENSSL_NO_SRP /* client */ @@ -994,12 +1043,11 @@ int main(int argc, char *argv[]) SRP_SERVER_ARG srp_server_arg = { NULL, NULL }; #endif int no_dhe = 0; - int no_ecdhe = 0; int no_psk = 0; int print_time = 0; clock_t s_time = 0, c_time = 0; #ifndef OPENSSL_NO_COMP - int comp = 0; + int n, comp = 0; COMP_METHOD *cm = NULL; STACK_OF(SSL_COMP) *ssl_comp_methods = NULL; #endif @@ -1007,11 +1055,20 @@ int main(int argc, char *argv[]) #ifdef OPENSSL_FIPS int fips_mode = 0; #endif - int no_protocol = 0; + int no_protocol; + int min_version = 0, max_version = 0; - SSL_CONF_CTX *s_cctx = NULL, *c_cctx = NULL; +#ifndef OPENSSL_NO_CT + /* + * Disable CT validation by default, because it will interfere with + * anything using custom extension handlers to deal with SCT extensions. + */ + ct_validation_cb ct_validation = NULL; +#endif + + SSL_CONF_CTX *s_cctx = NULL, *c_cctx = NULL, *s_cctx2 = NULL; STACK_OF(OPENSSL_STRING) *conf_args = NULL; - const char *arg = NULL, *argn = NULL; + char *arg = NULL, *argn = NULL; verbose = 0; debug = 0; @@ -1019,17 +1076,9 @@ int main(int argc, char *argv[]) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT); - 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); @@ -1037,22 +1086,35 @@ int main(int argc, char *argv[]) bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE | BIO_FP_TEXT); s_cctx = SSL_CONF_CTX_new(); + s_cctx2 = SSL_CONF_CTX_new(); c_cctx = SSL_CONF_CTX_new(); - if (!s_cctx || !c_cctx) { + if (!s_cctx || !c_cctx || !s_cctx2) { ERR_print_errors(bio_err); goto end; } SSL_CONF_CTX_set_flags(s_cctx, - SSL_CONF_FLAG_CMDLINE | SSL_CONF_FLAG_SERVER); + SSL_CONF_FLAG_CMDLINE | SSL_CONF_FLAG_SERVER | + SSL_CONF_FLAG_CERTIFICATE | + SSL_CONF_FLAG_REQUIRE_PRIVATE); + SSL_CONF_CTX_set_flags(s_cctx2, + SSL_CONF_FLAG_CMDLINE | SSL_CONF_FLAG_SERVER | + SSL_CONF_FLAG_CERTIFICATE | + SSL_CONF_FLAG_REQUIRE_PRIVATE); if (!SSL_CONF_CTX_set1_prefix(s_cctx, "-s_")) { ERR_print_errors(bio_err); goto end; } + if (!SSL_CONF_CTX_set1_prefix(s_cctx2, "-s_")) { + ERR_print_errors(bio_err); + goto end; + } SSL_CONF_CTX_set_flags(c_cctx, - SSL_CONF_FLAG_CMDLINE | SSL_CONF_FLAG_CLIENT); + SSL_CONF_FLAG_CMDLINE | SSL_CONF_FLAG_CLIENT | + SSL_CONF_FLAG_CERTIFICATE | + SSL_CONF_FLAG_REQUIRE_PRIVATE); if (!SSL_CONF_CTX_set1_prefix(c_cctx, "-c_")) { ERR_print_errors(bio_err); goto end; @@ -1062,7 +1124,7 @@ int main(int argc, char *argv[]) argv++; while (argc >= 1) { - if (!strcmp(*argv, "-F")) { + if (strcmp(*argv, "-F") == 0) { #ifdef OPENSSL_FIPS fips_mode = 1; #else @@ -1088,24 +1150,24 @@ int main(int argc, char *argv[]) debug = 1; else if (strcmp(*argv, "-reuse") == 0) reuse = 1; - else if (strcmp(*argv, "-dhe1024") == 0) { + else if (strcmp(*argv, "-dhe512") == 0) { #ifndef OPENSSL_NO_DH - dhe1024 = 1; + dhe512 = 1; #else fprintf(stderr, - "ignoring -dhe1024, since I'm compiled without DH\n"); + "ignoring -dhe512, since I'm compiled without DH\n"); #endif } else if (strcmp(*argv, "-dhe1024dsa") == 0) { #ifndef OPENSSL_NO_DH dhe1024dsa = 1; #else fprintf(stderr, - "ignoring -dhe1024, since I'm compiled without DH\n"); + "ignoring -dhe1024dsa, since I'm compiled without DH\n"); #endif } else if (strcmp(*argv, "-no_dhe") == 0) no_dhe = 1; else if (strcmp(*argv, "-no_ecdhe") == 0) - no_ecdhe = 1; + /* obsolete */; else if (strcmp(*argv, "-psk") == 0) { if (--argc < 1) goto bad; @@ -1125,31 +1187,24 @@ int main(int argc, char *argv[]) goto bad; srp_server_arg.expected_user = srp_client_arg.srplogin = *(++argv); - tls1 = 1; + min_version = TLS1_VERSION; } else if (strcmp(*argv, "-srppass") == 0) { if (--argc < 1) goto bad; srp_server_arg.pass = srp_client_arg.srppassin = *(++argv); - tls1 = 1; + min_version = TLS1_VERSION; } #endif 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; @@ -1167,30 +1222,6 @@ int main(int argc, char *argv[]) bytes *= 1024L; if (argv[0][i - 1] == 'm') bytes *= 1024L * 1024L; - } else if (strcmp(*argv, "-cert") == 0) { - if (--argc < 1) - goto bad; - server_cert = *(++argv); - } else if (strcmp(*argv, "-s_cert") == 0) { - if (--argc < 1) - goto bad; - server_cert = *(++argv); - } else if (strcmp(*argv, "-key") == 0) { - if (--argc < 1) - goto bad; - server_key = *(++argv); - } else if (strcmp(*argv, "-s_key") == 0) { - if (--argc < 1) - goto bad; - server_key = *(++argv); - } else if (strcmp(*argv, "-c_cert") == 0) { - if (--argc < 1) - goto bad; - client_cert = *(++argv); - } else if (strcmp(*argv, "-c_key") == 0) { - if (--argc < 1) - goto bad; - client_key = *(++argv); } else if (strcmp(*argv, "-cipher") == 0) { if (--argc < 1) goto bad; @@ -1204,30 +1235,33 @@ 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) { print_time = 1; } +#ifndef OPENSSL_NO_CT + else if (strcmp(*argv, "-noct") == 0) { + ct_validation = NULL; + } + else if (strcmp(*argv, "-requestct") == 0) { + ct_validation = CT_verify_no_bad_scts; + } + else if (strcmp(*argv, "-requirect") == 0) { + ct_validation = CT_verify_at_least_one_good_sct; + } +#endif #ifndef OPENSSL_NO_COMP else if (strcmp(*argv, "-zlib") == 0) { comp = COMP_ZLIB; - } else if (strcmp(*argv, "-rle") == 0) { - comp = COMP_RLE; } #endif - else if (strcmp(*argv, "-named_curve") == 0) { - if (--argc < 1) - goto bad; -#ifndef OPENSSL_NO_EC - named_curve = *(++argv); -#else - fprintf(stderr, - "ignoring -named_curve, since I'm compiled without ECDH\n"); - ++argv; -#endif - } else if (strcmp(*argv, "-app_verify") == 0) { + else if (strcmp(*argv, "-app_verify") == 0) { app_verify_arg.app_verify = 1; } else if (strcmp(*argv, "-proxy") == 0) { app_verify_arg.allow_proxy_certs = 1; @@ -1257,14 +1291,55 @@ int main(int argc, char *argv[]) if (--argc < 1) goto bad; alpn_client = *(++argv); - } else if (strcmp(*argv, "-alpn_server") == 0) { + } else if (strcmp(*argv, "-alpn_server") == 0 || + strcmp(*argv, "-alpn_server1") == 0) { if (--argc < 1) goto bad; alpn_server = *(++argv); + } else if (strcmp(*argv, "-alpn_server2") == 0) { + if (--argc < 1) + goto bad; + alpn_server2 = *(++argv); } else if (strcmp(*argv, "-alpn_expected") == 0) { 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 if (strcmp(*argv, "-sn_client") == 0) { + if (--argc < 1) + goto bad; + sn_client = *(++argv); + } else if (strcmp(*argv, "-sn_server1") == 0) { + if (--argc < 1) + goto bad; + sn_server1 = *(++argv); + } else if (strcmp(*argv, "-sn_server2") == 0) { + if (--argc < 1) + goto bad; + sn_server2 = *(++argv); + } else if (strcmp(*argv, "-sn_expect1") == 0) { + sn_expect = 1; + } else if (strcmp(*argv, "-sn_expect2") == 0) { + sn_expect = 2; } else { int rv; arg = argv[0]; @@ -1323,12 +1398,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 @@ -1341,18 +1438,17 @@ 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); } #ifdef OPENSSL_FIPS if (fips_mode) { if (!FIPS_mode_set(1)) { - ERR_load_crypto_strings(); - ERR_print_errors(BIO_new_fp(stderr, BIO_NOCLOSE)); + ERR_print_errors(bio_err); EXIT(1); } else fprintf(stderr, "*** IN FIPS MODE ***\n"); @@ -1360,9 +1456,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, @@ -1371,16 +1467,11 @@ int main(int argc, char *argv[]) /* 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(); - if (comp == COMP_RLE) - cm = COMP_rle(); if (cm != NULL) { - if (cm->type != NID_undef) { + if (COMP_get_type(cm) != NID_undef) { if (SSL_COMP_add_compression_method(comp, cm) != 0) { fprintf(stderr, "Failed to add compression method\n"); ERR_print_errors_fp(stderr); @@ -1388,71 +1479,90 @@ int main(int argc, char *argv[]) } else { fprintf(stderr, "Warning: %s compression not supported\n", - (comp == COMP_RLE ? "rle" : - (comp == COMP_ZLIB ? "zlib" : "unknown"))); + comp == COMP_ZLIB ? "zlib" : "unknown"); ERR_print_errors_fp(stderr); } } ssl_comp_methods = SSL_COMP_get_compression_methods(); - fprintf(stderr, "Available compression methods:\n"); - { - int j, n = sk_SSL_COMP_num(ssl_comp_methods); - if (n == 0) - fprintf(stderr, " NONE\n"); - else - for (j = 0; j < n; j++) { - SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j); - fprintf(stderr, " %d: %s\n", c->id, c->name); - } + n = sk_SSL_COMP_num(ssl_comp_methods); + if (n) { + int j; + printf("Available compression methods:"); + for (j = 0; j < n; j++) { + SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j); + printf(" %s:%d", c->name, c->id); + } + printf("\n"); } #endif - /* - * At this point, ssl3/tls1 is only set if the protocol is available. - * (Otherwise we exit early.) However the compiler doesn't know this, so - * we ifdef. - */ -#ifndef OPENSSL_NO_SSL3 - if (ssl3) - meth = SSLv3_method(); - else +#ifndef OPENSSL_NO_TLS + meth = TLS_method(); + if (ssl3) { + min_version = SSL3_VERSION; + max_version = SSL3_VERSION; + } else if (tls1) { + min_version = TLS1_VERSION; + max_version = TLS1_VERSION; + } #endif #ifndef OPENSSL_NO_DTLS - if (dtls1) - meth = DTLSv1_method(); - else if (dtls12) - meth = DTLSv1_2_method(); - else + if (dtls || dtls1 || dtls12) + meth = DTLS_method(); + if (dtls1) { + min_version = DTLS1_VERSION; + max_version = DTLS1_VERSION; + } else if (dtls12) { + min_version = DTLS1_2_VERSION; + max_version = DTLS1_2_VERSION; + } #endif - if (tls1) - meth = TLSv1_method(); - else - meth = SSLv23_method(); c_ctx = SSL_CTX_new(meth); s_ctx = SSL_CTX_new(meth); - if ((c_ctx == NULL) || (s_ctx == NULL)) { + s_ctx2 = SSL_CTX_new(meth); /* no SSL_CTX_dup! */ + if ((c_ctx == NULL) || (s_ctx == NULL) || (s_ctx2 == NULL)) { ERR_print_errors(bio_err); goto end; } /* * Since we will use low security ciphersuites and keys for testing set - * security level to zero. + * security level to zero by default. Tests can override this by adding + * "@SECLEVEL=n" to the cipher string. */ SSL_CTX_set_security_level(c_ctx, 0); SSL_CTX_set_security_level(s_ctx, 0); + SSL_CTX_set_security_level(s_ctx2, 0); + + if (SSL_CTX_set_min_proto_version(c_ctx, min_version) == 0) + goto end; + if (SSL_CTX_set_max_proto_version(c_ctx, max_version) == 0) + goto end; + if (SSL_CTX_set_min_proto_version(s_ctx, min_version) == 0) + goto end; + if (SSL_CTX_set_max_proto_version(s_ctx, max_version) == 0) + goto end; if (cipher != NULL) { - if(!SSL_CTX_set_cipher_list(c_ctx, cipher) - || !SSL_CTX_set_cipher_list(s_ctx, cipher)) { + if (!SSL_CTX_set_cipher_list(c_ctx, cipher) + || !SSL_CTX_set_cipher_list(s_ctx, cipher) + || !SSL_CTX_set_cipher_list(s_ctx2, cipher)) { ERR_print_errors(bio_err); goto end; } } +#ifndef OPENSSL_NO_CT + if (!SSL_CTX_set_ct_validation_callback(c_ctx, ct_validation, NULL)) { + ERR_print_errors(bio_err); + goto end; + } +#endif + /* Process SSL_CONF arguments */ SSL_CONF_CTX_set_ssl_ctx(c_cctx, c_ctx); SSL_CONF_CTX_set_ssl_ctx(s_cctx, s_ctx); + SSL_CONF_CTX_set_ssl_ctx(s_cctx2, s_ctx2); for (i = 0; i < sk_OPENSSL_STRING_num(conf_args); i += 2) { int rv; @@ -1460,8 +1570,11 @@ int main(int argc, char *argv[]) argn = sk_OPENSSL_STRING_value(conf_args, i + 1); rv = SSL_CONF_cmd(c_cctx, arg, argn); /* If not recognised use server context */ - if (rv == -2) - rv = SSL_CONF_cmd(s_cctx, arg, argn); + if (rv == -2) { + rv = SSL_CONF_cmd(s_cctx2, arg, argn); + if (rv > 0) + rv = SSL_CONF_cmd(s_cctx, arg, argn); + } if (rv <= 0) { BIO_printf(bio_err, "Error processing %s %s\n", arg, argn ? argn : ""); @@ -1470,7 +1583,7 @@ int main(int argc, char *argv[]) } } - if (!SSL_CONF_CTX_finish(s_cctx) || !SSL_CONF_CTX_finish(c_cctx)) { + if (!SSL_CONF_CTX_finish(s_cctx) || !SSL_CONF_CTX_finish(c_cctx) || !SSL_CONF_CTX_finish(s_cctx2)) { BIO_puts(bio_err, "Error finishing context\n"); ERR_print_errors(bio_err); goto end; @@ -1478,79 +1591,23 @@ int main(int argc, char *argv[]) #ifndef OPENSSL_NO_DH if (!no_dhe) { if (dhe1024dsa) { - /* - * use SSL_OP_SINGLE_DH_USE to avoid small subgroup attacks - */ - SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE); dh = get_dh1024dsa(); - } else if (dhe1024) - dh = get_dh1024(); - else + } else if (dhe512) dh = get_dh512(); + else + dh = get_dh1024(); SSL_CTX_set_tmp_dh(s_ctx, dh); + SSL_CTX_set_tmp_dh(s_ctx2, dh); DH_free(dh); } #else (void)no_dhe; #endif -#ifndef OPENSSL_NO_EC - if (!no_ecdhe) { - int nid; - - if (named_curve != NULL) { - nid = OBJ_sn2nid(named_curve); - if (nid == 0) { - BIO_printf(bio_err, "unknown curve name (%s)\n", named_curve); - goto end; - } - } else -# ifdef OPENSSL_NO_EC2M - nid = NID_X9_62_prime256v1; -# else - nid = NID_sect163r2; -# endif - - ecdh = EC_KEY_new_by_curve_name(nid); - if (ecdh == NULL) { - BIO_printf(bio_err, "unable to create curve\n"); - goto end; - } - - SSL_CTX_set_tmp_ecdh(s_ctx, ecdh); - SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_ECDH_USE); - EC_KEY_free(ecdh); - } -#else - (void)no_ecdhe; -#endif - -#ifndef OPENSSL_NO_RSA - SSL_CTX_set_tmp_rsa_callback(s_ctx, tmp_rsa_cb); -#endif - - if (!SSL_CTX_use_certificate_file(s_ctx, server_cert, SSL_FILETYPE_PEM)) { - ERR_print_errors(bio_err); - } else if (!SSL_CTX_use_PrivateKey_file(s_ctx, - (server_key ? server_key : - server_cert), - SSL_FILETYPE_PEM)) { - ERR_print_errors(bio_err); - goto end; - } - - if (client_auth) { - if(!SSL_CTX_use_certificate_file(c_ctx, client_cert, SSL_FILETYPE_PEM) - || !SSL_CTX_use_PrivateKey_file(c_ctx, - (client_key ? client_key : client_cert), - SSL_FILETYPE_PEM)) { - ERR_print_errors(bio_err); - goto end; - } - } - if ((!SSL_CTX_load_verify_locations(s_ctx, CAfile, CApath)) || (!SSL_CTX_set_default_verify_paths(s_ctx)) || + (!SSL_CTX_load_verify_locations(s_ctx2, CAfile, CApath)) || + (!SSL_CTX_set_default_verify_paths(s_ctx2)) || (!SSL_CTX_load_verify_locations(c_ctx, CAfile, CApath)) || (!SSL_CTX_set_default_verify_paths(c_ctx))) { /* fprintf(stderr,"SSL_load_verify_locations\n"); */ @@ -1558,16 +1615,27 @@ int main(int argc, char *argv[]) /* goto end; */ } + if (!SSL_CTX_set_default_ctlog_list_file(s_ctx) || + !SSL_CTX_set_default_ctlog_list_file(s_ctx2) || + !SSL_CTX_set_default_ctlog_list_file(c_ctx)) { + ERR_print_errors(bio_err); + } + if (client_auth) { - BIO_printf(bio_err, "client authentication\n"); + printf("client authentication\n"); SSL_CTX_set_verify(s_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback); + SSL_CTX_set_verify(s_ctx2, + SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + verify_callback); SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback, &app_verify_arg); + SSL_CTX_set_cert_verify_callback(s_ctx2, app_verify_callback, + &app_verify_arg); } if (server_auth) { - BIO_printf(bio_err, "server authentication\n"); + printf("server authentication\n"); SSL_CTX_set_verify(c_ctx, SSL_VERIFY_PEER, verify_callback); SSL_CTX_set_cert_verify_callback(c_ctx, app_verify_callback, &app_verify_arg); @@ -1575,8 +1643,10 @@ int main(int argc, char *argv[]) { int session_id_context = 0; - if(!SSL_CTX_set_session_id_context(s_ctx, (void *)&session_id_context, - sizeof session_id_context)) { + if (!SSL_CTX_set_session_id_context(s_ctx, (void *)&session_id_context, + sizeof session_id_context) || + !SSL_CTX_set_session_id_context(s_ctx2, (void *)&session_id_context, + sizeof session_id_context)) { ERR_print_errors(bio_err); goto end; } @@ -1598,9 +1668,11 @@ int main(int argc, char *argv[]) #ifndef OPENSSL_NO_PSK SSL_CTX_set_psk_client_callback(c_ctx, psk_client_callback); SSL_CTX_set_psk_server_callback(s_ctx, psk_server_callback); + SSL_CTX_set_psk_server_callback(s_ctx2, psk_server_callback); if (debug) BIO_printf(bio_err, "setting PSK identity hint to s_ctx\n"); - if (!SSL_CTX_use_psk_identity_hint(s_ctx, "ctx server identity_hint")) { + if (!SSL_CTX_use_psk_identity_hint(s_ctx, "ctx server identity_hint") || + !SSL_CTX_use_psk_identity_hint(s_ctx2, "ctx server identity_hint")) { BIO_printf(bio_err, "error setting PSK identity hint to s_ctx\n"); ERR_print_errors(bio_err); goto end; @@ -1623,8 +1695,11 @@ int main(int argc, char *argv[]) if (srp_server_arg.expected_user != NULL) { SSL_CTX_set_verify(s_ctx, SSL_VERIFY_NONE, verify_callback); + SSL_CTX_set_verify(s_ctx2, SSL_VERIFY_NONE, verify_callback); SSL_CTX_set_srp_cb_arg(s_ctx, &srp_server_arg); + SSL_CTX_set_srp_cb_arg(s_ctx2, &srp_server_arg); SSL_CTX_set_srp_username_callback(s_ctx, ssl_srp_server_param_cb); + SSL_CTX_set_srp_username_callback(s_ctx2, ssl_srp_server_param_cb); } #endif @@ -1639,180 +1714,506 @@ int main(int argc, char *argv[]) goto end; } SSL_CTX_set_next_protos_advertised_cb(s_ctx, cb_server_npn, NULL); + SSL_CTX_set_next_protos_advertised_cb(s_ctx2, cb_server_npn, NULL); } if (npn_server_reject) { SSL_CTX_set_next_protos_advertised_cb(s_ctx, cb_server_rejects_npn, NULL); + SSL_CTX_set_next_protos_advertised_cb(s_ctx2, cb_server_rejects_npn, + NULL); + } +#endif + + if (serverinfo_sct) { + if (!SSL_CTX_add_client_custom_ext(c_ctx, + TLSEXT_TYPE_signed_certificate_timestamp, + NULL, NULL, NULL, + serverinfo_cli_parse_cb, NULL)) { + BIO_printf(bio_err, "Error adding SCT extension\n"); + goto end; + } + } + if (serverinfo_tack) { + if (!SSL_CTX_add_client_custom_ext(c_ctx, TACK_EXT_TYPE, + NULL, NULL, NULL, + serverinfo_cli_parse_cb, NULL)) { + BIO_printf(bio_err, "Error adding TACK extension\n"); + goto end; + } + } + if (serverinfo_file) + if (!SSL_CTX_use_serverinfo_file(s_ctx, serverinfo_file) || + !SSL_CTX_use_serverinfo_file(s_ctx2, serverinfo_file)) { + BIO_printf(bio_err, "missing serverinfo file\n"); + goto end; + } + + if (custom_ext) { + if (!SSL_CTX_add_client_custom_ext(c_ctx, CUSTOM_EXT_TYPE_0, + custom_ext_0_cli_add_cb, + NULL, NULL, + custom_ext_0_cli_parse_cb, NULL) + || !SSL_CTX_add_client_custom_ext(c_ctx, CUSTOM_EXT_TYPE_1, + custom_ext_1_cli_add_cb, + NULL, NULL, + custom_ext_1_cli_parse_cb, NULL) + || !SSL_CTX_add_client_custom_ext(c_ctx, CUSTOM_EXT_TYPE_2, + custom_ext_2_cli_add_cb, + NULL, NULL, + custom_ext_2_cli_parse_cb, NULL) + || !SSL_CTX_add_client_custom_ext(c_ctx, CUSTOM_EXT_TYPE_3, + custom_ext_3_cli_add_cb, + NULL, NULL, + custom_ext_3_cli_parse_cb, NULL) + || !SSL_CTX_add_server_custom_ext(s_ctx, CUSTOM_EXT_TYPE_0, + custom_ext_0_srv_add_cb, + NULL, NULL, + custom_ext_0_srv_parse_cb, NULL) + || !SSL_CTX_add_server_custom_ext(s_ctx2, CUSTOM_EXT_TYPE_0, + custom_ext_0_srv_add_cb, + NULL, NULL, + custom_ext_0_srv_parse_cb, NULL) + || !SSL_CTX_add_server_custom_ext(s_ctx, CUSTOM_EXT_TYPE_1, + custom_ext_1_srv_add_cb, + NULL, NULL, + custom_ext_1_srv_parse_cb, NULL) + || !SSL_CTX_add_server_custom_ext(s_ctx2, CUSTOM_EXT_TYPE_1, + custom_ext_1_srv_add_cb, + NULL, NULL, + custom_ext_1_srv_parse_cb, NULL) + || !SSL_CTX_add_server_custom_ext(s_ctx, CUSTOM_EXT_TYPE_2, + custom_ext_2_srv_add_cb, + NULL, NULL, + custom_ext_2_srv_parse_cb, NULL) + || !SSL_CTX_add_server_custom_ext(s_ctx2, CUSTOM_EXT_TYPE_2, + custom_ext_2_srv_add_cb, + NULL, NULL, + custom_ext_2_srv_parse_cb, NULL) + || !SSL_CTX_add_server_custom_ext(s_ctx, CUSTOM_EXT_TYPE_3, + custom_ext_3_srv_add_cb, + NULL, NULL, + custom_ext_3_srv_parse_cb, NULL) + || !SSL_CTX_add_server_custom_ext(s_ctx2, CUSTOM_EXT_TYPE_3, + custom_ext_3_srv_add_cb, + NULL, NULL, + custom_ext_3_srv_parse_cb, NULL)) { + BIO_printf(bio_err, "Error setting custom extensions\n"); + goto end; + } + } + + if (alpn_server) + SSL_CTX_set_alpn_select_cb(s_ctx, cb_server_alpn, alpn_server); + if (alpn_server2) + SSL_CTX_set_alpn_select_cb(s_ctx2, cb_server_alpn, alpn_server2); + + if (alpn_client) { + size_t alpn_len; + unsigned char *alpn = next_protos_parse(&alpn_len, alpn_client); + + if (alpn == NULL) { + BIO_printf(bio_err, "Error parsing -alpn_client argument\n"); + goto end; + } + /* Returns 0 on success!! */ + if (SSL_CTX_set_alpn_protos(c_ctx, alpn, alpn_len)) { + BIO_printf(bio_err, "Error setting ALPN\n"); + OPENSSL_free(alpn); + goto end; + } + OPENSSL_free(alpn); + } + + if (sn_server1 != NULL || sn_server2 != NULL) + SSL_CTX_set_tlsext_servername_callback(s_ctx, servername_cb); + + c_ssl = SSL_new(c_ctx); + s_ssl = SSL_new(s_ctx); + + if (sn_client) + SSL_set_tlsext_host_name(c_ssl, sn_client); + + 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) { + if (!SSL_set_session(c_ssl, NULL)) { + BIO_printf(bio_err, "Failed to set session\n"); + goto end; + } + } + 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; } + + 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, ""); + } + if (print_time) { +#ifdef CLOCKS_PER_SEC + /* + * "To determine the time in seconds, the value returned by the clock + * function should be divided by the value of the macro + * CLOCKS_PER_SEC." -- ISO/IEC 9899 + */ + BIO_printf(bio_stdout, "Approximate total server time: %6.2f s\n" + "Approximate total client time: %6.2f s\n", + (double)s_time / CLOCKS_PER_SEC, + (double)c_time / CLOCKS_PER_SEC); +#else + BIO_printf(bio_stdout, + "Approximate total server time: %6.2f units\n" + "Approximate total client time: %6.2f units\n", + (double)s_time, (double)c_time); +#endif + } + + err: + SSL_free(s_ssl); + SSL_free(c_ssl); + + end: + SSL_CTX_free(s_ctx); + SSL_CTX_free(s_ctx2); + SSL_CTX_free(c_ctx); + SSL_CONF_CTX_free(s_cctx); + SSL_CONF_CTX_free(s_cctx2); + SSL_CONF_CTX_free(c_cctx); + sk_OPENSSL_STRING_free(conf_args); + + BIO_free(bio_stdout); + +#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. */ - if (serverinfo_sct) { - if(!SSL_CTX_add_client_custom_ext(c_ctx, SCT_EXT_TYPE, - NULL, NULL, NULL, - serverinfo_cli_parse_cb, NULL)) { - BIO_printf(bio_err, "Error adding SCT extension\n"); - goto end; - } - } - if (serverinfo_tack) { - if(!SSL_CTX_add_client_custom_ext(c_ctx, TACK_EXT_TYPE, - NULL, NULL, NULL, - serverinfo_cli_parse_cb, NULL)) { - BIO_printf(bio_err, "Error adding TACK extension\n"); - goto end; - } - } - if (serverinfo_file) - if (!SSL_CTX_use_serverinfo_file(s_ctx, serverinfo_file)) { - BIO_printf(bio_err, "missing serverinfo file\n"); - goto end; - } + 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; + } + } - if (custom_ext) { - if(!SSL_CTX_add_client_custom_ext(c_ctx, CUSTOM_EXT_TYPE_0, - custom_ext_0_cli_add_cb, - NULL, NULL, - custom_ext_0_cli_parse_cb, NULL) - || !SSL_CTX_add_client_custom_ext(c_ctx, CUSTOM_EXT_TYPE_1, - custom_ext_1_cli_add_cb, - NULL, NULL, - custom_ext_1_cli_parse_cb, NULL) - || !SSL_CTX_add_client_custom_ext(c_ctx, CUSTOM_EXT_TYPE_2, - custom_ext_2_cli_add_cb, - NULL, NULL, - custom_ext_2_cli_parse_cb, NULL) - || !SSL_CTX_add_client_custom_ext(c_ctx, CUSTOM_EXT_TYPE_3, - custom_ext_3_cli_add_cb, - NULL, NULL, - custom_ext_3_cli_parse_cb, NULL) - || !SSL_CTX_add_server_custom_ext(s_ctx, CUSTOM_EXT_TYPE_0, - custom_ext_0_srv_add_cb, - NULL, NULL, - custom_ext_0_srv_parse_cb, NULL) - || !SSL_CTX_add_server_custom_ext(s_ctx, CUSTOM_EXT_TYPE_1, - custom_ext_1_srv_add_cb, - NULL, NULL, - custom_ext_1_srv_parse_cb, NULL) - || !SSL_CTX_add_server_custom_ext(s_ctx, CUSTOM_EXT_TYPE_2, - custom_ext_2_srv_add_cb, - NULL, NULL, - custom_ext_2_srv_parse_cb, NULL) - || !SSL_CTX_add_server_custom_ext(s_ctx, CUSTOM_EXT_TYPE_3, - custom_ext_3_srv_add_cb, - NULL, NULL, - custom_ext_3_srv_parse_cb, NULL)) { - BIO_printf(bio_err, "Error setting custom extensions\n"); - goto end; + /* + * 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); } - } - if (alpn_server) - SSL_CTX_set_alpn_select_cb(s_ctx, cb_server_alpn, NULL); + { + /* SERVER */ - if (alpn_client) { - unsigned short alpn_len; - unsigned char *alpn = next_protos_parse(&alpn_len, alpn_client); + char sbuf[1024 * 8]; + int i, r; + clock_t s_clock = clock(); - if (alpn == NULL) { - BIO_printf(bio_err, "Error parsing -alpn_client argument\n"); - goto end; - } - /* Returns 0 on success!! */ - if(SSL_CTX_set_alpn_protos(c_ctx, alpn, alpn_len)) { - BIO_printf(bio_err, "Error setting ALPN\n"); - OPENSSL_free(alpn); - goto end; - } - OPENSSL_free(alpn); - } + memset(sbuf, 0, sizeof(sbuf)); - c_ssl = SSL_new(c_ctx); - s_ssl = SSL_new(s_ctx); + if (debug) + if (SSL_in_init(s_ssl)) + printf("server waiting in SSL_accept - %s\n", + SSL_state_string_long(s_ssl)); -#ifndef OPENSSL_NO_KRB5 - if (c_ssl && c_ssl->kssl_ctx) { - char localhost[MAXHOSTNAMELEN + 2]; + if (sw_num > 0) { + /* Write to client. */ - if (gethostname(localhost, sizeof localhost - 1) == 0) { - localhost[sizeof localhost - 1] = '\0'; - if (strlen(localhost) == sizeof localhost - 1) { - BIO_printf(bio_err, "localhost name too long\n"); - goto end; + 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; + } } - kssl_ctx_setstring(c_ssl->kssl_ctx, KSSL_SERVER, localhost); - } - } -#endif /* OPENSSL_NO_KRB5 */ - for (i = 0; i < number; i++) { - if (!reuse) { - if(!SSL_set_session(c_ssl, NULL)) { - BIO_printf(bio_err, "Failed to set session\n"); - goto end; + 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); } - if (bio_pair) - ret = doit_biopair(s_ssl, c_ssl, bytes, &s_time, &c_time); - else - ret = doit(s_ssl, c_ssl, bytes); - if (ret) break; } + while (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0); - if (!verbose) { - print_details(c_ssl, ""); + 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; } - if ((i > 1) || (bytes > 1L)) - BIO_printf(bio_stdout, "%d handshakes of %ld bytes done\n", i, - bytes); - if (print_time) { -#ifdef CLOCKS_PER_SEC - /* - * "To determine the time in seconds, the value returned by the clock - * function should be divided by the value of the macro - * CLOCKS_PER_SEC." -- ISO/IEC 9899 - */ - BIO_printf(bio_stdout, "Approximate total server time: %6.2f s\n" - "Approximate total client time: %6.2f s\n", - (double)s_time / CLOCKS_PER_SEC, - (double)c_time / CLOCKS_PER_SEC); -#else - BIO_printf(bio_stdout, - "Approximate total server time: %6.2f units\n" - "Approximate total client time: %6.2f units\n", - (double)s_time, (double)c_time); #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 (verify_servername(c_ssl, s_ssl) < 0) { + ret = 1; + goto err; } - SSL_free(s_ssl); - SSL_free(c_ssl); + if (custom_ext_error) { + fprintf(stderr, "Custom extension error\n"); + ret = 1; + goto err; + } end: - if (s_ctx != NULL) - SSL_CTX_free(s_ctx); - if (c_ctx != NULL) - SSL_CTX_free(c_ctx); - - if (s_cctx) - SSL_CONF_CTX_free(s_cctx); - if (c_cctx) - SSL_CONF_CTX_free(c_cctx); - sk_OPENSSL_STRING_free(conf_args); + ret = 0; - BIO_free(bio_stdout); + err: + ERR_print_errors(bio_err); -#ifndef OPENSSL_NO_RSA - free_tmp_rsa(); -#endif -#ifndef OPENSSL_NO_ENGINE - ENGINE_cleanup(); -#endif - CRYPTO_cleanup_all_ex_data(); - ERR_free_strings(); - ERR_remove_thread_state(NULL); - EVP_cleanup(); - CRYPTO_mem_leaks(bio_err); - BIO_free(bio_err); - EXIT(ret); + 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, @@ -1822,6 +2223,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 */ @@ -1914,6 +2317,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; } /* @@ -1939,6 +2343,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; } /* @@ -1991,6 +2396,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". */ @@ -2011,6 +2417,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 */ @@ -2158,6 +2565,10 @@ int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count, ret = 1; goto err; } + if (verify_servername(c_ssl, s_ssl) < 0) { + ret = 1; + goto err; + } if (custom_ext_error) { fprintf(stderr, "Custom extension error\n"); @@ -2178,6 +2589,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; } @@ -2203,17 +2619,16 @@ 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; - if ((cbuf = OPENSSL_malloc(bufsiz)) == NULL) + if ((cbuf = OPENSSL_zalloc(bufsiz)) == NULL) goto err; - if ((sbuf = OPENSSL_malloc(bufsiz)) == NULL) + if ((sbuf = OPENSSL_zalloc(bufsiz)) == NULL) goto err; - memset(cbuf, 0, bufsiz); - memset(sbuf, 0, bufsiz); - c_to_s = BIO_new(BIO_s_mem()); s_to_c = BIO_new(BIO_s_mem()); if ((s_to_c == NULL) || (c_to_s == NULL)) { @@ -2298,6 +2713,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; } @@ -2326,6 +2742,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; } @@ -2362,6 +2779,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; } @@ -2397,6 +2815,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; } @@ -2464,28 +2883,32 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count) BIO_free(s_to_c); BIO_free_all(c_bio); BIO_free_all(s_bio); + OPENSSL_free(cbuf); + OPENSSL_free(sbuf); - if (cbuf) - OPENSSL_free(cbuf); - if (sbuf) - 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); } +static CRYPTO_ONCE proxy_auth_ex_data_once = CRYPTO_ONCE_STATIC_INIT; +static volatile int proxy_auth_ex_data_idx = -1; + +static void do_get_proxy_auth_ex_data_idx(void) +{ + proxy_auth_ex_data_idx = X509_STORE_CTX_get_ex_new_index(0, + "SSLtest for verify callback", + NULL, NULL, NULL); +} + static int get_proxy_auth_ex_data_idx(void) { - static volatile int idx = -1; - if (idx < 0) { - CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); - if (idx < 0) { - idx = X509_STORE_CTX_get_ex_new_index(0, - "SSLtest for verify callback", - NULL, NULL, NULL); - } - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); - } - return idx; + CRYPTO_THREAD_run_once(&proxy_auth_ex_data_once, + do_get_proxy_auth_ex_data_idx); + return proxy_auth_ex_data_idx; } static int verify_callback(int ok, X509_STORE_CTX *ctx) @@ -2496,7 +2919,7 @@ static int verify_callback(int ok, X509_STORE_CTX *ctx) sizeof buf); if (s != NULL) { if (ok) - fprintf(stderr, "depth=%d %s\n", ctx->error_depth, buf); + printf("depth=%d %s\n", ctx->error_depth, buf); else { fprintf(stderr, "depth=%d error=%d %s\n", ctx->error_depth, ctx->error, buf); @@ -2504,20 +2927,21 @@ static int verify_callback(int ok, X509_STORE_CTX *ctx) } if (ok == 0) { - fprintf(stderr, "Error string: %s\n", - X509_verify_cert_error_string(ctx->error)); switch (ctx->error) { + default: + fprintf(stderr, "Error string: %s\n", + X509_verify_cert_error_string(ctx->error)); + break; case X509_V_ERR_CERT_NOT_YET_VALID: case X509_V_ERR_CERT_HAS_EXPIRED: case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: - fprintf(stderr, " ... ignored.\n"); ok = 1; } } if (ok == 1) { X509 *xs = ctx->current_cert; - if (xs->ex_flags & EXFLAG_PROXY) { + if (X509_get_extension_flags(xs) & EXFLAG_PROXY) { unsigned int *letters = X509_STORE_CTX_get_ex_data(ctx, get_proxy_auth_ex_data_idx ()); @@ -2569,7 +2993,7 @@ static int verify_callback(int ok, X509_STORE_CTX *ctx) * others. */ - fprintf(stderr, " Certificate proxy rights = %*.*s", i, + printf(" Certificate proxy rights = %*.*s", i, i, s); while (i-- > 0) { int c = *s++; @@ -2587,15 +3011,15 @@ static int verify_callback(int ok, X509_STORE_CTX *ctx) } found_any = 0; - fprintf(stderr, ", resulting proxy rights = "); + printf(", resulting proxy rights = "); for (i = 0; i < 26; i++) if (letters[i]) { - fprintf(stderr, "%c", i + 'A'); + printf("%c", i + 'A'); found_any = 1; } if (!found_any) - fprintf(stderr, "none"); - fprintf(stderr, "\n"); + printf("none"); + printf("\n"); PROXY_CERT_INFO_EXTENSION_free(pci); } @@ -2854,15 +3278,14 @@ static int app_verify_callback(X509_STORE_CTX *ctx, void *arg) if (cb_arg->app_verify) { char *s = NULL, buf[256]; - fprintf(stderr, "In app_verify_callback, allowing cert. "); - fprintf(stderr, "Arg is: %s\n", cb_arg->string); - fprintf(stderr, - "Finished printing do we have a context? 0x%p a cert? 0x%p\n", + printf("In app_verify_callback, allowing cert. "); + printf("Arg is: %s\n", cb_arg->string); + printf("Finished printing do we have a context? 0x%p a cert? 0x%p\n", (void *)ctx, (void *)ctx->cert); if (ctx->cert) s = X509_NAME_oneline(X509_get_subject_name(ctx->cert), buf, 256); if (s != NULL) { - fprintf(stderr, "cert depth=%d %s\n", ctx->error_depth, buf); + printf("cert depth=%d %s\n", ctx->error_depth, buf); } return (1); } @@ -2881,15 +3304,15 @@ static int app_verify_callback(X509_STORE_CTX *ctx, void *arg) } } - fprintf(stderr, " Initial proxy rights = "); + printf(" Initial proxy rights = "); for (i = 0; i < 26; i++) if (letters[i]) { - fprintf(stderr, "%c", i + 'A'); + printf("%c", i + 'A'); found_any = 1; } if (!found_any) - fprintf(stderr, "none"); - fprintf(stderr, "\n"); + printf("none"); + printf("\n"); X509_STORE_CTX_set_ex_data(ctx, get_proxy_auth_ex_data_idx(), letters); @@ -2914,53 +3337,16 @@ static int app_verify_callback(X509_STORE_CTX *ctx, void *arg) } if (!ok) fprintf(stderr, - "Proxy rights check with condition '%s' proved invalid\n", + "Proxy rights check with condition '%s' invalid\n", cb_arg->proxy_cond); else - fprintf(stderr, - "Proxy rights check with condition '%s' proved valid\n", + printf("Proxy rights check with condition '%s' ok\n", cb_arg->proxy_cond); } } 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; - } - BIO_printf(bio_err, "Generating temp (%d bit) RSA key...", keylength); - (void)BIO_flush(bio_err); - 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: - BIO_printf(bio_err, "\n"); - (void)BIO_flush(bio_err); - } - if (bn) - 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: @@ -3116,8 +3502,7 @@ static int psk_key2bn(const char *pskkey, unsigned char *psk, if (!ret) { BIO_printf(bio_err, "Could not convert PSK key '%s' to BIGNUM\n", pskkey); - if (bn) - BN_free(bn); + BN_free(bn); return 0; } if (BN_num_bytes(bn) > (int)max_psk_len) { @@ -3172,36 +3557,29 @@ static unsigned int psk_server_callback(SSL *ssl, const char *identity, static int do_test_cipherlist(void) { +#ifndef OPENSSL_NO_TLS int i = 0; const SSL_METHOD *meth; const SSL_CIPHER *ci, *tci = NULL; -#ifndef OPENSSL_NO_SSL3 - fprintf(stderr, "testing SSLv3 cipher list order: "); - meth = SSLv3_method(); + /* + * This is required because ssltest "cheats" and uses internal headers to + * call functions, thus avoiding auto-init + */ + OPENSSL_init_crypto(0, NULL); + + meth = TLS_method(); tci = NULL; while ((ci = meth->get_cipher(i++)) != NULL) { if (tci != NULL) if (ci->id >= tci->id) { - fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id); + fprintf(stderr, "testing SSLv3 cipher list order: "); + fprintf(stderr, "failed %x vs. %x\n", ci->id, tci->id); return 0; } tci = ci; } - fprintf(stderr, "ok\n"); #endif - fprintf(stderr, "testing TLSv1 cipher list order: "); - meth = TLSv1_method(); - tci = NULL; - while ((ci = meth->get_cipher(i++)) != NULL) { - if (tci != NULL) - if (ci->id >= tci->id) { - fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id); - return 0; - } - tci = ci; - } - fprintf(stderr, "ok\n"); return 1; }