diff options
Diffstat (limited to 'crypto/openssl/ssl/ssltest.c')
-rw-r--r-- | crypto/openssl/ssl/ssltest.c | 181 |
1 files changed, 167 insertions, 14 deletions
diff --git a/crypto/openssl/ssl/ssltest.c b/crypto/openssl/ssl/ssltest.c index aaf6c6b..1db84ad 100644 --- a/crypto/openssl/ssl/ssltest.c +++ b/crypto/openssl/ssl/ssltest.c @@ -217,6 +217,9 @@ # 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 @@ -300,9 +303,51 @@ static BIO *bio_err = NULL; static BIO *bio_stdout = NULL; 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 *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 != NULL) { + 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 @@ -350,11 +395,12 @@ static int cb_server_alpn(SSL *s, const unsigned char **out, { unsigned char *protos; unsigned short 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(); } @@ -417,8 +463,17 @@ 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 if (SSL_get_SSL_CTX(server) == s_ctx){ + BIO_printf(bio_stdout, "'%s'\n", + alpn_server); + } else { + BIO_printf(bio_stdout, "unknown\n"); + } return -1; } @@ -756,8 +811,15 @@ static void sv_usage(void) " -custom_ext - try various custom extension callbacks\n"); fprintf(stderr, " -alpn_client <string> - have client side offer ALPN\n"); fprintf(stderr, " -alpn_server <string> - have server side offer ALPN\n"); + fprintf(stderr, " -alpn_server1 <string> - alias for -alpn_server\n"); + fprintf(stderr, " -alpn_server2 <string> - have server side context 2 offer ALPN\n"); fprintf(stderr, " -alpn_expected <string> - the ALPN protocol that should be negotiated\n"); + fprintf(stderr, " -sn_client <string> - have client request this servername\n"); + fprintf(stderr, " -sn_server1 <string> - have server context 1 respond to this servername\n"); + fprintf(stderr, " -sn_server2 <string> - 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_details(SSL *c_ssl, const char *prefix) @@ -896,7 +958,6 @@ int main(int argc, char *argv[]) #ifndef OPENSSL_NO_ECDH char *named_curve = NULL; #endif - SSL_CTX *s_ctx = NULL; SSL_CTX *c_ctx = NULL; const SSL_METHOD *meth = NULL; SSL *c_ssl, *s_ssl; @@ -1151,14 +1212,35 @@ 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, "-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 { fprintf(stderr, "unknown option %s\n", *argv); badop = 1; @@ -1304,7 +1386,8 @@ int main(int argc, char *argv[]) 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; } @@ -1312,7 +1395,9 @@ int main(int argc, char *argv[]) if (cipher != NULL) { SSL_CTX_set_cipher_list(c_ctx, cipher); SSL_CTX_set_cipher_list(s_ctx, cipher); + SSL_CTX_set_cipher_list(s_ctx2, cipher); } + #ifndef OPENSSL_NO_DH if (!no_dhe) { if (dhe1024dsa) { @@ -1320,12 +1405,14 @@ int main(int argc, char *argv[]) * use SSL_OP_SINGLE_DH_USE to avoid small subgroup attacks */ SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE); + SSL_CTX_set_options(s_ctx2, SSL_OP_SINGLE_DH_USE); dh = get_dh1024dsa(); } 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 @@ -1353,7 +1440,9 @@ int main(int argc, char *argv[]) } SSL_CTX_set_tmp_ecdh(s_ctx, ecdh); + SSL_CTX_set_tmp_ecdh(s_ctx2, ecdh); SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_ECDH_USE); + SSL_CTX_set_options(s_ctx2, SSL_OP_SINGLE_ECDH_USE); EC_KEY_free(ecdh); } #else @@ -1362,15 +1451,18 @@ int main(int argc, char *argv[]) #ifndef OPENSSL_NO_RSA SSL_CTX_set_tmp_rsa_callback(s_ctx, tmp_rsa_cb); + SSL_CTX_set_tmp_rsa_callback(s_ctx2, tmp_rsa_cb); #endif #ifdef TLSEXT_TYPE_opaque_prf_input SSL_CTX_set_tlsext_opaque_prf_input_callback(c_ctx, opaque_prf_input_cb); SSL_CTX_set_tlsext_opaque_prf_input_callback(s_ctx, opaque_prf_input_cb); + SSL_CTX_set_tlsext_opaque_prf_input_callback(s_ctx2, opaque_prf_input_cb); /* or &co2 or NULL */ SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(c_ctx, &co1); /* or &so2 or NULL */ SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(s_ctx, &so1); + SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(s_ctx2, &so1); #endif if (!SSL_CTX_use_certificate_file(s_ctx, server_cert, SSL_FILETYPE_PEM)) { @@ -1383,6 +1475,16 @@ int main(int argc, char *argv[]) goto end; } + if (!SSL_CTX_use_certificate_file(s_ctx2, server_cert, SSL_FILETYPE_PEM)) { + ERR_print_errors(bio_err); + } else if (!SSL_CTX_use_PrivateKey_file(s_ctx2, + (server_key ? server_key : + server_cert), + SSL_FILETYPE_PEM)) { + ERR_print_errors(bio_err); + goto end; + } + if (client_auth) { SSL_CTX_use_certificate_file(c_ctx, client_cert, SSL_FILETYPE_PEM); SSL_CTX_use_PrivateKey_file(c_ctx, @@ -1392,6 +1494,8 @@ int main(int argc, char *argv[]) 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"); */ @@ -1406,6 +1510,11 @@ int main(int argc, char *argv[]) verify_callback); SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback, &app_verify_arg); + 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_ctx2, app_verify_callback, + &app_verify_arg); } if (server_auth) { BIO_printf(bio_err, "server authentication\n"); @@ -1418,6 +1527,8 @@ int main(int argc, char *argv[]) int session_id_context = 0; 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); } /* Use PSK only if PSK key is given */ @@ -1436,6 +1547,7 @@ 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")) { @@ -1443,6 +1555,11 @@ int main(int argc, char *argv[]) ERR_print_errors(bio_err); goto end; } + if (!SSL_CTX_use_psk_identity_hint(s_ctx2, "ctx server identity_hint")) { + BIO_printf(bio_err, "error setting PSK identity hint to s_ctx2\n"); + ERR_print_errors(bio_err); + goto end; + } #endif } #ifndef OPENSSL_NO_SRP @@ -1461,8 +1578,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 @@ -1475,11 +1595,16 @@ int main(int argc, char *argv[]) NULL, NULL, NULL, serverinfo_cli_parse_cb, NULL); - if (serverinfo_file) + if (serverinfo_file) { if (!SSL_CTX_use_serverinfo_file(s_ctx, serverinfo_file)) { BIO_printf(bio_err, "missing serverinfo file\n"); goto end; } + if (!SSL_CTX_use_serverinfo_file(s_ctx2, serverinfo_file)) { + BIO_printf(bio_err, "missing serverinfo file\n"); + goto end; + } + } if (custom_ext) { SSL_CTX_add_client_custom_ext(c_ctx, CUSTOM_EXT_TYPE_0, @@ -1515,10 +1640,29 @@ int main(int argc, char *argv[]) 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_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_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_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_3, + custom_ext_3_srv_add_cb, + NULL, NULL, + custom_ext_3_srv_parse_cb, NULL); } if (alpn_server) - SSL_CTX_set_alpn_select_cb(s_ctx, cb_server_alpn, NULL); + 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) { unsigned short alpn_len; @@ -1532,9 +1676,15 @@ int main(int argc, char *argv[]) OPENSSL_free(alpn); } + if (sn_server1 || sn_server2) + 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); + #ifndef OPENSSL_NO_KRB5 if (c_ssl && c_ssl->kssl_ctx) { char localhost[MAXHOSTNAMELEN + 2]; @@ -1588,12 +1738,19 @@ int main(int argc, char *argv[]) #endif } + if (verify_alpn(c_ssl, s_ssl) < 0) + ret = 1; + if (verify_servername(c_ssl, s_ssl) < 0) + ret = 1; + SSL_free(s_ssl); SSL_free(c_ssl); end: if (s_ctx != NULL) SSL_CTX_free(s_ctx); + if (s_ctx2 != NULL) + SSL_CTX_free(s_ctx2); if (c_ctx != NULL) SSL_CTX_free(c_ctx); @@ -1961,10 +2118,6 @@ int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count, ret = 1; goto err; } - if (verify_alpn(c_ssl, s_ssl) < 0) { - ret = 1; - goto err; - } if (custom_ext_error) { ret = 1; |