From ea1ecd9831cfe8de9dbeafdfec344b8c944c9b84 Mon Sep 17 00:00:00 2001 From: Emilia Kasper Date: Tue, 14 Mar 2017 13:48:54 +0100 Subject: [PATCH] Port SRP tests to the new test framework Also add negative tests for password mismatch. Reviewed-by: Richard Levitte --- test/README.ssltest.md | 3 + test/handshake_helper.c | 52 ++++++++++++ test/recipes/80-test_ssl_new.t | 4 +- test/recipes/80-test_ssl_old.t | 28 +------ test/ssl-tests/23-srp.conf | 144 +++++++++++++++++++++++++++++++++ test/ssl-tests/23-srp.conf.in | 103 +++++++++++++++++++++++ test/ssl_test_ctx.c | 16 ++++ test/ssl_test_ctx.h | 6 ++ test/ssltest_old.c | 89 -------------------- 9 files changed, 330 insertions(+), 115 deletions(-) create mode 100644 test/ssl-tests/23-srp.conf create mode 100644 test/ssl-tests/23-srp.conf.in diff --git a/test/README.ssltest.md b/test/README.ssltest.md index 3d0fe91f55..a32696723d 100644 --- a/test/README.ssltest.md +++ b/test/README.ssltest.md @@ -179,6 +179,9 @@ client => { protocols can be specified as a comma-separated list, and a callback with the recommended behaviour will be installed automatically. +* SRPUser, SRPPassword - SRP settings. For client, this is the SRP user to + connect as; for server, this is a known SRP user. + ### Default server and client configurations The default server certificate and CA files are added to the configurations diff --git a/test/handshake_helper.c b/test/handshake_helper.c index 99b6ad1941..30fd479837 100644 --- a/test/handshake_helper.c +++ b/test/handshake_helper.c @@ -12,6 +12,9 @@ #include #include #include +#ifndef OPENSSL_NO_SRP +#include +#endif #include "handshake_helper.h" #include "testutil.h" @@ -52,6 +55,8 @@ typedef struct ctx_data_st { size_t npn_protocols_len; unsigned char *alpn_protocols; size_t alpn_protocols_len; + char *srp_user; + char *srp_password; } CTX_DATA; /* |ctx_data| itself is stack-allocated. */ @@ -61,6 +66,10 @@ static void ctx_data_free_data(CTX_DATA *ctx_data) ctx_data->npn_protocols = NULL; OPENSSL_free(ctx_data->alpn_protocols); ctx_data->alpn_protocols = NULL; + OPENSSL_free(ctx_data->srp_user); + ctx_data->srp_user = NULL; + OPENSSL_free(ctx_data->srp_password); + ctx_data->srp_password = NULL; } static int ex_data_idx; @@ -405,6 +414,28 @@ static int server_alpn_cb(SSL *s, const unsigned char **out, : SSL_TLSEXT_ERR_NOACK; } +#ifndef OPENSSL_NO_SRP +static char *client_srp_cb(SSL *s, void *arg) +{ + CTX_DATA *ctx_data = (CTX_DATA*)(arg); + return OPENSSL_strdup(ctx_data->srp_password); +} + +static int server_srp_cb(SSL *s, int *ad, void *arg) +{ + CTX_DATA *ctx_data = (CTX_DATA*)(arg); + if (strcmp(ctx_data->srp_user, SSL_get_srp_username(s)) != 0) + return SSL3_AL_FATAL; + if (SSL_set_srp_server_param_pw(s, ctx_data->srp_user, + ctx_data->srp_password, + "2048" /* known group */) < 0) { + *ad = SSL_AD_INTERNAL_ERROR; + return SSL3_AL_FATAL; + } + return SSL_ERROR_NONE; +} +#endif /* !OPENSSL_NO_SRP */ + /* * Configure callbacks and other properties that can't be set directly * in the server/client CONF. @@ -562,6 +593,27 @@ static void configure_handshake_ctx(SSL_CTX *server_ctx, SSL_CTX *server2_ctx, break; } #endif +#ifndef OPENSSL_NO_SRP + if (extra->server.srp_user != NULL) { + SSL_CTX_set_srp_username_callback(server_ctx, server_srp_cb); + server_ctx_data->srp_user = OPENSSL_strdup(extra->server.srp_user); + server_ctx_data->srp_password = OPENSSL_strdup(extra->server.srp_password); + SSL_CTX_set_srp_cb_arg(server_ctx, server_ctx_data); + } + if (extra->server2.srp_user != NULL) { + TEST_check(server2_ctx != NULL); + SSL_CTX_set_srp_username_callback(server2_ctx, server_srp_cb); + server2_ctx_data->srp_user = OPENSSL_strdup(extra->server2.srp_user); + server2_ctx_data->srp_password = OPENSSL_strdup(extra->server2.srp_password); + SSL_CTX_set_srp_cb_arg(server2_ctx, server2_ctx_data); + } + if (extra->client.srp_user != NULL) { + TEST_check(SSL_CTX_set_srp_username(client_ctx, extra->client.srp_user)); + SSL_CTX_set_srp_client_pwd_callback(client_ctx, client_srp_cb); + client_ctx_data->srp_password = OPENSSL_strdup(extra->client.srp_password); + SSL_CTX_set_srp_cb_arg(client_ctx, client_ctx_data); + } +#endif /* !OPENSSL_NO_SRP */ } /* Configure per-SSL callbacks and other properties. */ diff --git a/test/recipes/80-test_ssl_new.t b/test/recipes/80-test_ssl_new.t index 4173157153..903dc91c52 100644 --- a/test/recipes/80-test_ssl_new.t +++ b/test/recipes/80-test_ssl_new.t @@ -29,7 +29,7 @@ map { s/\^// } @conf_files if $^O eq "VMS"; # We hard-code the number of tests to double-check that the globbing above # finds all files as expected. -plan tests => 22; # = scalar @conf_srcs +plan tests => 23; # = scalar @conf_srcs # Some test results depend on the configuration of enabled protocols. We only # verify generated sources in the default configuration. @@ -90,6 +90,8 @@ my %skip = ( "20-cert-select.conf" => disabled("tls1_2") || $no_ec, "21-key-update.conf" => disabled("tls1_3"), "22-compression.conf" => disabled("zlib") || $no_tls, + "23-srp.conf" => (disabled("tls1") && disabled ("tls1_1") + && disabled("tls1_2")) || disabled("srp"), ); foreach my $conf (@conf_files) { diff --git a/test/recipes/80-test_ssl_old.t b/test/recipes/80-test_ssl_old.t index ec09bb848e..05cc794693 100644 --- a/test/recipes/80-test_ssl_old.t +++ b/test/recipes/80-test_ssl_old.t @@ -20,10 +20,10 @@ setup("test_ssl"); $ENV{CTLOG_FILE} = srctop_file("test", "ct", "log_list.conf"); -my ($no_rsa, $no_dsa, $no_dh, $no_ec, $no_srp, $no_psk, +my ($no_rsa, $no_dsa, $no_dh, $no_ec, $no_psk, $no_ssl3, $no_tls1, $no_tls1_1, $no_tls1_2, $no_tls1_3, $no_dtls, $no_dtls1, $no_dtls1_2, $no_ct) = - anydisabled qw/rsa dsa dh ec srp psk + anydisabled qw/rsa dsa dh ec psk ssl3 tls1 tls1_1 tls1_2 tls1_3 dtls dtls1 dtls1_2 ct/; my $no_anytls = alldisabled(available_protocols("tls")); @@ -79,7 +79,7 @@ my $client_sess="client.ss"; # new format in ssl_test.c and add recipes to 80-test_ssl_new.t instead. plan tests => 1 # For testss - +6 # For the first testssl + +5 # For the first testssl ; subtest 'test_ss' => sub { @@ -568,28 +568,6 @@ sub testssl { ok(run(test([@ssltest, "-bio_pair", "-tls1", "-custom_ext", "-serverinfo_file", $serverinfo, "-serverinfo_sct", "-serverinfo_tack"]))); } }; - - subtest 'SRP tests' => sub { - - plan tests => 4; - - SKIP: { - skip "skipping SRP tests", 4 - if $no_srp || alldisabled(grep !/^ssl3/, available_protocols("tls")); - - ok(run(test([@ssltest, "-tls1", "-cipher", "SRP", "-srpuser", "test", "-srppass", "abc123"])), - 'test tls1 with SRP'); - - ok(run(test([@ssltest, "-bio_pair", "-tls1", "-cipher", "SRP", "-srpuser", "test", "-srppass", "abc123"])), - 'test tls1 with SRP via BIO pair'); - - ok(run(test([@ssltest, "-tls1", "-cipher", "aSRP", "-srpuser", "test", "-srppass", "abc123"])), - 'test tls1 with SRP auth'); - - ok(run(test([@ssltest, "-bio_pair", "-tls1", "-cipher", "aSRP", "-srpuser", "test", "-srppass", "abc123"])), - 'test tls1 with SRP auth via BIO pair'); - } - }; } unlink $CAkey; diff --git a/test/ssl-tests/23-srp.conf b/test/ssl-tests/23-srp.conf new file mode 100644 index 0000000000..6ae49e6814 --- /dev/null +++ b/test/ssl-tests/23-srp.conf @@ -0,0 +1,144 @@ +# Generated with generate_ssl_tests.pl + +num_tests = 4 + +test-0 = 0-srp +test-1 = 1-srp-bad-password +test-2 = 2-srp-auth +test-3 = 3-srp-auth-bad-password +# =========================================================== + +[0-srp] +ssl_conf = 0-srp-ssl + +[0-srp-ssl] +server = 0-srp-server +client = 0-srp-client + +[0-srp-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = SRP +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[0-srp-client] +CipherString = SRP +MaxProtocol = TLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-0] +ExpectedResult = Success +server = 0-srp-server-extra +client = 0-srp-client-extra + +[0-srp-server-extra] +SRPPassword = password +SRPUser = user + +[0-srp-client-extra] +SRPPassword = password +SRPUser = user + + +# =========================================================== + +[1-srp-bad-password] +ssl_conf = 1-srp-bad-password-ssl + +[1-srp-bad-password-ssl] +server = 1-srp-bad-password-server +client = 1-srp-bad-password-client + +[1-srp-bad-password-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = SRP +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[1-srp-bad-password-client] +CipherString = SRP +MaxProtocol = TLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-1] +ExpectedResult = ServerFail +server = 1-srp-bad-password-server-extra +client = 1-srp-bad-password-client-extra + +[1-srp-bad-password-server-extra] +SRPPassword = password +SRPUser = user + +[1-srp-bad-password-client-extra] +SRPPassword = passw0rd +SRPUser = user + + +# =========================================================== + +[2-srp-auth] +ssl_conf = 2-srp-auth-ssl + +[2-srp-auth-ssl] +server = 2-srp-auth-server +client = 2-srp-auth-client + +[2-srp-auth-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = aSRP +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[2-srp-auth-client] +CipherString = aSRP +MaxProtocol = TLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-2] +ExpectedResult = Success +server = 2-srp-auth-server-extra +client = 2-srp-auth-client-extra + +[2-srp-auth-server-extra] +SRPPassword = password +SRPUser = user + +[2-srp-auth-client-extra] +SRPPassword = password +SRPUser = user + + +# =========================================================== + +[3-srp-auth-bad-password] +ssl_conf = 3-srp-auth-bad-password-ssl + +[3-srp-auth-bad-password-ssl] +server = 3-srp-auth-bad-password-server +client = 3-srp-auth-bad-password-client + +[3-srp-auth-bad-password-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = aSRP +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[3-srp-auth-bad-password-client] +CipherString = aSRP +MaxProtocol = TLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-3] +ExpectedResult = ServerFail +server = 3-srp-auth-bad-password-server-extra +client = 3-srp-auth-bad-password-client-extra + +[3-srp-auth-bad-password-server-extra] +SRPPassword = password +SRPUser = user + +[3-srp-auth-bad-password-client-extra] +SRPPassword = passw0rd +SRPUser = user + + diff --git a/test/ssl-tests/23-srp.conf.in b/test/ssl-tests/23-srp.conf.in new file mode 100644 index 0000000000..b7601fc3e5 --- /dev/null +++ b/test/ssl-tests/23-srp.conf.in @@ -0,0 +1,103 @@ +# -*- mode: perl; -*- +# Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the OpenSSL license (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; +use warnings; + +package ssltests; + +# SRP is only supported up to TLSv1.2 + +our @tests = ( + { + name => "srp", + server => { + "CipherString" => "SRP", + extra => { + "SRPUser" => "user", + "SRPPassword" => "password", + }, + }, + client => { + "CipherString" => "SRP", + "MaxProtocol" => "TLSv1.2", + extra => { + "SRPUser" => "user", + "SRPPassword" => "password", + }, + }, + test => { + "ExpectedResult" => "Success" + }, + }, + { + name => "srp-bad-password", + server => { + "CipherString" => "SRP", + extra => { + "SRPUser" => "user", + "SRPPassword" => "password", + }, + }, + client => { + "CipherString" => "SRP", + "MaxProtocol" => "TLSv1.2", + extra => { + "SRPUser" => "user", + "SRPPassword" => "passw0rd", + }, + }, + test => { + # Server fails first with bad client Finished. + "ExpectedResult" => "ServerFail" + }, + }, + { + name => "srp-auth", + server => { + "CipherString" => "aSRP", + extra => { + "SRPUser" => "user", + "SRPPassword" => "password", + }, + }, + client => { + "CipherString" => "aSRP", + "MaxProtocol" => "TLSv1.2", + extra => { + "SRPUser" => "user", + "SRPPassword" => "password", + }, + }, + test => { + "ExpectedResult" => "Success" + }, + }, + { + name => "srp-auth-bad-password", + server => { + "CipherString" => "aSRP", + extra => { + "SRPUser" => "user", + "SRPPassword" => "password", + }, + }, + client => { + "CipherString" => "aSRP", + "MaxProtocol" => "TLSv1.2", + extra => { + "SRPUser" => "user", + "SRPPassword" => "passw0rd", + }, + }, + test => { + # Server fails first with bad client Finished. + "ExpectedResult" => "ServerFail" + }, + }, +); \ No newline at end of file diff --git a/test/ssl_test_ctx.c b/test/ssl_test_ctx.c index d668f51f51..3e3be9e058 100644 --- a/test/ssl_test_ctx.c +++ b/test/ssl_test_ctx.c @@ -322,6 +322,12 @@ IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CLIENT_CONF, client, alpn_protocols) IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_SERVER_CONF, server, alpn_protocols) IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CTX, test, expected_alpn_protocol) +/* SRP options */ +IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CLIENT_CONF, client, srp_user) +IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_SERVER_CONF, server, srp_user) +IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CLIENT_CONF, client, srp_password) +IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_SERVER_CONF, server, srp_password) + /* Handshake mode */ static const test_enum ssl_handshake_modes[] = { @@ -576,6 +582,8 @@ static const ssl_test_client_option ssl_test_client_options[] = { { "ALPNProtocols", &parse_client_alpn_protocols }, { "CTValidation", &parse_ct_validation }, { "RenegotiateCiphers", &parse_client_reneg_ciphers}, + { "SRPUser", &parse_client_srp_user }, + { "SRPPassword", &parse_client_srp_password }, }; /* Nested server options. */ @@ -590,6 +598,8 @@ static const ssl_test_server_option ssl_test_server_options[] = { { "ALPNProtocols", &parse_server_alpn_protocols }, { "BrokenSessionTicket", &parse_server_broken_session_ticket }, { "CertStatus", &parse_certstatus }, + { "SRPUser", &parse_server_srp_user }, + { "SRPPassword", &parse_server_srp_password }, }; /* @@ -615,6 +625,12 @@ static void ssl_test_extra_conf_free_data(SSL_TEST_EXTRA_CONF *conf) OPENSSL_free(conf->server.alpn_protocols); OPENSSL_free(conf->server2.alpn_protocols); OPENSSL_free(conf->client.reneg_ciphers); + OPENSSL_free(conf->server.srp_user); + OPENSSL_free(conf->server.srp_password); + OPENSSL_free(conf->server2.srp_user); + OPENSSL_free(conf->server2.srp_password); + OPENSSL_free(conf->client.srp_user); + OPENSSL_free(conf->client.srp_password); } static void ssl_test_ctx_free_extra_data(SSL_TEST_CTX *ctx) diff --git a/test/ssl_test_ctx.h b/test/ssl_test_ctx.h index 300a557880..3d8f72bbe5 100644 --- a/test/ssl_test_ctx.h +++ b/test/ssl_test_ctx.h @@ -81,6 +81,7 @@ typedef enum { SSL_TEST_CERT_STATUS_GOOD_RESPONSE, SSL_TEST_CERT_STATUS_BAD_RESPONSE } ssl_cert_status_t; + /* * Server/client settings that aren't supported by the SSL CONF library, * such as callbacks. @@ -96,6 +97,8 @@ typedef struct { ssl_ct_validation_t ct_validation; /* Ciphersuites to set on a renegotiation */ char *reneg_ciphers; + char *srp_user; + char *srp_password; } SSL_TEST_CLIENT_CONF; typedef struct { @@ -108,6 +111,9 @@ typedef struct { int broken_session_ticket; /* Should we send a CertStatus message? */ ssl_cert_status_t cert_status; + /* An SRP user known to the server. */ + char *srp_user; + char *srp_password; } SSL_TEST_SERVER_CONF; typedef struct { diff --git a/test/ssltest_old.c b/test/ssltest_old.c index 055014bb12..00fb1a88c7 100644 --- a/test/ssltest_old.c +++ b/test/ssltest_old.c @@ -84,9 +84,6 @@ #ifndef OPENSSL_NO_DH # include #endif -#ifndef OPENSSL_NO_SRP -# include -#endif #include #ifndef OPENSSL_NO_CT # include @@ -141,45 +138,6 @@ static unsigned int psk_server_callback(SSL *ssl, const char *identity, unsigned int max_psk_len); #endif -#ifndef OPENSSL_NO_SRP -/* SRP client */ -/* This is a context that we pass to all callbacks */ -typedef struct srp_client_arg_st { - char *srppassin; - char *srplogin; -} SRP_CLIENT_ARG; - -# define PWD_STRLEN 1024 - -static char *ssl_give_srp_client_pwd_cb(SSL *s, void *arg) -{ - SRP_CLIENT_ARG *srp_client_arg = (SRP_CLIENT_ARG *)arg; - return OPENSSL_strdup((char *)srp_client_arg->srppassin); -} - -/* SRP server */ -/* This is a context that we pass to SRP server callbacks */ -typedef struct srp_server_arg_st { - char *expected_user; - char *pass; -} SRP_SERVER_ARG; - -static int ssl_srp_server_param_cb(SSL *s, int *ad, void *arg) -{ - SRP_SERVER_ARG *p = (SRP_SERVER_ARG *)arg; - - if (strcmp(p->expected_user, SSL_get_srp_username(s)) != 0) { - fprintf(stderr, "User %s doesn't exist\n", SSL_get_srp_username(s)); - return SSL3_AL_FATAL; - } - if (SSL_set_srp_server_param_pw(s, p->expected_user, p->pass, "1024") < 0) { - *ad = SSL_AD_INTERNAL_ERROR; - return SSL3_AL_FATAL; - } - return SSL_ERROR_NONE; -} -#endif - static BIO *bio_err = NULL; static BIO *bio_stdout = NULL; @@ -722,10 +680,6 @@ static void sv_usage(void) #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"); -#endif #ifndef OPENSSL_NO_SSL3 fprintf(stderr, " -ssl3 - use SSLv3\n"); #endif @@ -970,12 +924,6 @@ int main(int argc, char *argv[]) #ifndef OPENSSL_NO_DH DH *dh; int dhe512 = 0, dhe1024dsa = 0; -#endif -#ifndef OPENSSL_NO_SRP - /* client */ - SRP_CLIENT_ARG srp_client_arg = { NULL, NULL }; - /* server */ - SRP_SERVER_ARG srp_server_arg = { NULL, NULL }; #endif int no_dhe = 0; int no_psk = 0; @@ -1098,20 +1046,6 @@ int main(int argc, char *argv[]) no_psk = 1; #endif } -#ifndef OPENSSL_NO_SRP - else if (strcmp(*argv, "-srpuser") == 0) { - if (--argc < 1) - goto bad; - srp_server_arg.expected_user = srp_client_arg.srplogin = - *(++argv); - min_version = TLS1_VERSION; - } else if (strcmp(*argv, "-srppass") == 0) { - if (--argc < 1) - goto bad; - srp_server_arg.pass = srp_client_arg.srppassin = *(++argv); - min_version = TLS1_VERSION; - } -#endif else if (strcmp(*argv, "-tls1_2") == 0) { tls1_2 = 1; } else if (strcmp(*argv, "-tls1") == 0) { @@ -1605,29 +1539,6 @@ int main(int argc, char *argv[]) } #endif } -#ifndef OPENSSL_NO_SRP - if (srp_client_arg.srplogin) { - if (!SSL_CTX_set_srp_username(c_ctx, srp_client_arg.srplogin)) { - BIO_printf(bio_err, "Unable to set SRP username\n"); - goto end; - } - SSL_CTX_set_srp_cb_arg(c_ctx, &srp_client_arg); - SSL_CTX_set_srp_client_pwd_callback(c_ctx, - ssl_give_srp_client_pwd_cb); - /* - * SSL_CTX_set_srp_strength(c_ctx, srp_client_arg.strength); - */ - } - - 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 #ifndef OPENSSL_NO_NEXTPROTONEG if (npn_client) { -- 2.25.1