summaryrefslogtreecommitdiffstats
path: root/test/ssl_test_ctx.c
diff options
context:
space:
mode:
authorEmilia Kasper <emilia@openssl.org>2016-07-21 16:29:48 +0200
committerEmilia Kasper <emilia@openssl.org>2016-08-08 12:06:26 +0200
commit9f48bbacd8cac8d08dff146db438ab3e19908a7a (patch)
tree7650dbd3d696d895c53b153a3d2b8c3881bade88 /test/ssl_test_ctx.c
parenta4a18b2f891c59fd78ad520da79146af13063892 (diff)
Reorganize SSL test structures
Move custom server and client options from the test dictionary to an "extra" section of each server/client. Rename test expectations to say "Expected". This is a big but straightforward change. Primarily, this allows us to specify multiple server and client contexts without redefining the custom options for each of them. For example, instead of "ServerNPNProtocols", "Server2NPNProtocols", "ResumeServerNPNProtocols", we now have, "NPNProtocols". This simplifies writing resumption and SNI tests. The first application will be resumption tests for NPN and ALPN. Regrouping the options also makes it clearer which options apply to the server, which apply to the client, which configure the test, and which are test expectations. Reviewed-by: Richard Levitte <levitte@openssl.org>
Diffstat (limited to 'test/ssl_test_ctx.c')
-rw-r--r--test/ssl_test_ctx.c265
1 files changed, 192 insertions, 73 deletions
diff --git a/test/ssl_test_ctx.c b/test/ssl_test_ctx.c
index 4d2bdba470..d4a7c8ba59 100644
--- a/test/ssl_test_ctx.c
+++ b/test/ssl_test_ctx.c
@@ -75,9 +75,9 @@ const char *ssl_test_result_name(ssl_test_result_t result)
return enum_name(ssl_test_results, OSSL_NELEM(ssl_test_results), result);
}
-/******************************/
-/* ClientAlert / ServerAlert. */
-/******************************/
+/**********************************************/
+/* ExpectedClientAlert / ExpectedServerAlert. */
+/**********************************************/
static const test_enum ssl_alerts[] = {
{"UnknownCA", SSL_AD_UNKNOWN_CA},
@@ -94,12 +94,12 @@ __owur static int parse_alert(int *alert, const char *value)
__owur static int parse_client_alert(SSL_TEST_CTX *test_ctx, const char *value)
{
- return parse_alert(&test_ctx->client_alert, value);
+ return parse_alert(&test_ctx->expected_client_alert, value);
}
__owur static int parse_server_alert(SSL_TEST_CTX *test_ctx, const char *value)
{
- return parse_alert(&test_ctx->server_alert, value);
+ return parse_alert(&test_ctx->expected_server_alert, value);
}
const char *ssl_alert_name(int alert)
@@ -107,9 +107,9 @@ const char *ssl_alert_name(int alert)
return enum_name(ssl_alerts, OSSL_NELEM(ssl_alerts), alert);
}
-/************/
-/* Protocol */
-/************/
+/********************/
+/* ExpectedProtocol */
+/********************/
static const test_enum ssl_protocols[] = {
{"TLSv1.2", TLS1_2_VERSION},
@@ -123,7 +123,7 @@ static const test_enum ssl_protocols[] = {
__owur static int parse_protocol(SSL_TEST_CTX *test_ctx, const char *value)
{
return parse_enum(ssl_protocols, OSSL_NELEM(ssl_protocols),
- &test_ctx->protocol, value);
+ &test_ctx->expected_protocol, value);
}
const char *ssl_protocol_name(int protocol)
@@ -132,7 +132,7 @@ const char *ssl_protocol_name(int protocol)
}
/***********************/
-/* CertVerifyCallback. */
+/* VerifyCallback. */
/***********************/
static const test_enum ssl_verify_callbacks[] = {
@@ -141,7 +141,7 @@ static const test_enum ssl_verify_callbacks[] = {
{"RejectAll", SSL_TEST_VERIFY_REJECT_ALL},
};
-__owur static int parse_client_verify_callback(SSL_TEST_CTX *test_ctx,
+__owur static int parse_client_verify_callback(SSL_TEST_CLIENT_CONF *client_conf,
const char *value)
{
int ret_value;
@@ -149,7 +149,7 @@ __owur static int parse_client_verify_callback(SSL_TEST_CTX *test_ctx,
&ret_value, value)) {
return 0;
}
- test_ctx->client_verify_callback = ret_value;
+ client_conf->verify_callback = ret_value;
return 1;
}
@@ -170,7 +170,7 @@ static const test_enum ssl_servername[] = {
{"invalid", SSL_TEST_SERVERNAME_INVALID},
};
-__owur static int parse_servername(SSL_TEST_CTX *test_ctx,
+__owur static int parse_servername(SSL_TEST_CLIENT_CONF *client_conf,
const char *value)
{
int ret_value;
@@ -178,7 +178,7 @@ __owur static int parse_servername(SSL_TEST_CTX *test_ctx,
&ret_value, value)) {
return 0;
}
- test_ctx->servername = ret_value;
+ client_conf->servername = ret_value;
return 1;
}
@@ -200,9 +200,9 @@ const char *ssl_servername_name(ssl_servername_t server)
server);
}
-/***********************/
-/* ServerNameCallback. */
-/***********************/
+/**********************/
+/* ServerNameCallback */
+/**********************/
static const test_enum ssl_servername_callbacks[] = {
{"None", SSL_TEST_SERVERNAME_CB_NONE},
@@ -210,15 +210,15 @@ static const test_enum ssl_servername_callbacks[] = {
{"RejectMismatch", SSL_TEST_SERVERNAME_REJECT_MISMATCH},
};
-__owur static int parse_servername_callback(SSL_TEST_CTX *test_ctx,
- const char *value)
+__owur static int parse_servername_callback(SSL_TEST_SERVER_CONF *server_conf,
+ const char *value)
{
int ret_value;
if (!parse_enum(ssl_servername_callbacks,
OSSL_NELEM(ssl_servername_callbacks), &ret_value, value)) {
return 0;
}
- test_ctx->servername_callback = ret_value;
+ server_conf->servername_callback = ret_value;
return 1;
}
@@ -236,7 +236,6 @@ static const test_enum ssl_session_ticket[] = {
{"Ignore", SSL_TEST_SESSION_TICKET_IGNORE},
{"Yes", SSL_TEST_SESSION_TICKET_YES},
{"No", SSL_TEST_SESSION_TICKET_NO},
- {"Broken", SSL_TEST_SESSION_TICKET_BROKEN},
};
__owur static int parse_session_ticket(SSL_TEST_CTX *test_ctx, const char *value)
@@ -258,7 +257,7 @@ const char *ssl_session_ticket_name(ssl_session_ticket_t server)
}
/***********************/
-/* Method. */
+/* Method */
/***********************/
static const test_enum ssl_test_methods[] = {
@@ -282,12 +281,12 @@ const char *ssl_test_method_name(ssl_test_method_t method)
return enum_name(ssl_test_methods, OSSL_NELEM(ssl_test_methods), method);
}
-#define IMPLEMENT_SSL_TEST_CTX_STRING_OPTION(field) \
- static int parse_##field(SSL_TEST_CTX *test_ctx, const char *value) \
+#define IMPLEMENT_SSL_TEST_STRING_OPTION(struct_type, name, field) \
+ static int parse_##name##_##field(struct_type *ctx, const char *value) \
{ \
- OPENSSL_free(test_ctx->field); \
- test_ctx->field = OPENSSL_strdup(value); \
- OPENSSL_assert(test_ctx->field != NULL); \
+ OPENSSL_free(ctx->field); \
+ ctx->field = OPENSSL_strdup(value); \
+ OPENSSL_assert(ctx->field != NULL); \
return 1; \
}
@@ -295,14 +294,12 @@ const char *ssl_test_method_name(ssl_test_method_t method)
/* NPN and ALPN options */
/************************************/
-IMPLEMENT_SSL_TEST_CTX_STRING_OPTION(client_npn_protocols)
-IMPLEMENT_SSL_TEST_CTX_STRING_OPTION(server_npn_protocols)
-IMPLEMENT_SSL_TEST_CTX_STRING_OPTION(server2_npn_protocols)
-IMPLEMENT_SSL_TEST_CTX_STRING_OPTION(expected_npn_protocol)
-IMPLEMENT_SSL_TEST_CTX_STRING_OPTION(client_alpn_protocols)
-IMPLEMENT_SSL_TEST_CTX_STRING_OPTION(server_alpn_protocols)
-IMPLEMENT_SSL_TEST_CTX_STRING_OPTION(server2_alpn_protocols)
-IMPLEMENT_SSL_TEST_CTX_STRING_OPTION(expected_alpn_protocol)
+IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CLIENT_CONF, client, npn_protocols)
+IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_SERVER_CONF, server, npn_protocols)
+IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CTX, test, expected_npn_protocol)
+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)
/***********************/
/* Handshake mode */
@@ -344,18 +341,20 @@ static int parse_boolean(const char *value, int *result)
return 0;
}
-#define IMPLEMENT_SSL_TEST_CTX_BOOL_OPTION(field) \
- static int parse_##field(SSL_TEST_CTX *test_ctx, const char *value) \
+#define IMPLEMENT_SSL_TEST_BOOL_OPTION(struct_type, name, field) \
+ static int parse_##name##_##field(struct_type *ctx, const char *value) \
{ \
- return parse_boolean(value, &test_ctx->field); \
+ return parse_boolean(value, &ctx->field); \
}
-IMPLEMENT_SSL_TEST_CTX_BOOL_OPTION(resumption_expected)
+IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_CTX, test, resumption_expected)
+IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_SERVER_CONF, server, broken_session_ticket)
/*************************************************************/
/* Known test options and their corresponding parse methods. */
/*************************************************************/
+/* Top-level options. */
typedef struct {
const char *name;
int (*parse)(SSL_TEST_CTX *test_ctx, const char *value);
@@ -363,25 +362,42 @@ typedef struct {
static const ssl_test_ctx_option ssl_test_ctx_options[] = {
{ "ExpectedResult", &parse_expected_result },
- { "ClientAlert", &parse_client_alert },
- { "ServerAlert", &parse_server_alert },
- { "Protocol", &parse_protocol },
- { "ClientVerifyCallback", &parse_client_verify_callback },
- { "ServerName", &parse_servername },
+ { "ExpectedClientAlert", &parse_client_alert },
+ { "ExpectedServerAlert", &parse_server_alert },
+ { "ExpectedProtocol", &parse_protocol },
{ "ExpectedServerName", &parse_expected_servername },
- { "ServerNameCallback", &parse_servername_callback },
{ "SessionTicketExpected", &parse_session_ticket },
{ "Method", &parse_test_method },
- { "ClientNPNProtocols", &parse_client_npn_protocols },
- { "ServerNPNProtocols", &parse_server_npn_protocols },
- { "Server2NPNProtocols", &parse_server2_npn_protocols },
- { "ExpectedNPNProtocol", &parse_expected_npn_protocol },
- { "ClientALPNProtocols", &parse_client_alpn_protocols },
- { "ServerALPNProtocols", &parse_server_alpn_protocols },
- { "Server2ALPNProtocols", &parse_server2_alpn_protocols },
- { "ExpectedALPNProtocol", &parse_expected_alpn_protocol },
+ { "ExpectedNPNProtocol", &parse_test_expected_npn_protocol },
+ { "ExpectedALPNProtocol", &parse_test_expected_alpn_protocol },
{ "HandshakeMode", &parse_handshake_mode },
- { "ResumptionExpected", &parse_resumption_expected },
+ { "ResumptionExpected", &parse_test_resumption_expected },
+};
+
+/* Nested client options. */
+typedef struct {
+ const char *name;
+ int (*parse)(SSL_TEST_CLIENT_CONF *conf, const char *value);
+} ssl_test_client_option;
+
+static const ssl_test_client_option ssl_test_client_options[] = {
+ { "VerifyCallback", &parse_client_verify_callback },
+ { "ServerName", &parse_servername },
+ { "NPNProtocols", &parse_client_npn_protocols },
+ { "ALPNProtocols", &parse_client_alpn_protocols },
+};
+
+/* Nested server options. */
+typedef struct {
+ const char *name;
+ int (*parse)(SSL_TEST_SERVER_CONF *conf, const char *value);
+} ssl_test_server_option;
+
+static const ssl_test_server_option ssl_test_server_options[] = {
+ { "ServerNameCallback", &parse_servername_callback },
+ { "NPNProtocols", &parse_server_npn_protocols },
+ { "ALPNProtocols", &parse_server_alpn_protocols },
+ { "BrokenSessionTicket", &parse_server_broken_session_ticket },
};
/*
@@ -396,44 +412,82 @@ SSL_TEST_CTX *SSL_TEST_CTX_new()
return ret;
}
-void SSL_TEST_CTX_free(SSL_TEST_CTX *ctx)
+static void ssl_test_extra_conf_free_data(SSL_TEST_EXTRA_CONF *conf)
+{
+ OPENSSL_free(conf->client.npn_protocols);
+ OPENSSL_free(conf->server.npn_protocols);
+ OPENSSL_free(conf->server2.npn_protocols);
+ OPENSSL_free(conf->client.alpn_protocols);
+ OPENSSL_free(conf->server.alpn_protocols);
+ OPENSSL_free(conf->server2.alpn_protocols);
+}
+
+static void ssl_test_ctx_free_extra_data(SSL_TEST_CTX *ctx)
{
+ ssl_test_extra_conf_free_data(&ctx->extra);
+ ssl_test_extra_conf_free_data(&ctx->resume_extra);
+}
-#ifndef OPENSSL_NO_NEXTPROTONEG
- OPENSSL_free(ctx->client_npn_protocols);
- OPENSSL_free(ctx->server_npn_protocols);
- OPENSSL_free(ctx->server2_npn_protocols);
- OPENSSL_free(ctx->client_alpn_protocols);
- OPENSSL_free(ctx->server_alpn_protocols);
- OPENSSL_free(ctx->server2_alpn_protocols);
+void SSL_TEST_CTX_free(SSL_TEST_CTX *ctx)
+{
+ ssl_test_ctx_free_extra_data(ctx);
OPENSSL_free(ctx->expected_npn_protocol);
OPENSSL_free(ctx->expected_alpn_protocol);
-#endif
OPENSSL_free(ctx);
}
-SSL_TEST_CTX *SSL_TEST_CTX_create(const CONF *conf, const char *test_section)
+static int parse_client_options(SSL_TEST_CLIENT_CONF *client, const CONF *conf,
+ const char *client_section)
{
STACK_OF(CONF_VALUE) *sk_conf;
- SSL_TEST_CTX *ctx;
int i;
size_t j;
- sk_conf = NCONF_get_section(conf, test_section);
+ sk_conf = NCONF_get_section(conf, client_section);
OPENSSL_assert(sk_conf != NULL);
- ctx = SSL_TEST_CTX_new();
- OPENSSL_assert(ctx != NULL);
+ for (i = 0; i < sk_CONF_VALUE_num(sk_conf); i++) {
+ int found = 0;
+ const CONF_VALUE *option = sk_CONF_VALUE_value(sk_conf, i);
+ for (j = 0; j < OSSL_NELEM(ssl_test_client_options); j++) {
+ if (strcmp(option->name, ssl_test_client_options[j].name) == 0) {
+ if (!ssl_test_client_options[j].parse(client, option->value)) {
+ fprintf(stderr, "Bad value %s for option %s\n",
+ option->value, option->name);
+ return 0;
+ }
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ fprintf(stderr, "Unknown test option: %s\n", option->name);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static int parse_server_options(SSL_TEST_SERVER_CONF *server, const CONF *conf,
+ const char *server_section)
+{
+ STACK_OF(CONF_VALUE) *sk_conf;
+ int i;
+ size_t j;
+
+ sk_conf = NCONF_get_section(conf, server_section);
+ OPENSSL_assert(sk_conf != NULL);
for (i = 0; i < sk_CONF_VALUE_num(sk_conf); i++) {
int found = 0;
const CONF_VALUE *option = sk_CONF_VALUE_value(sk_conf, i);
- for (j = 0; j < OSSL_NELEM(ssl_test_ctx_options); j++) {
- if (strcmp(option->name, ssl_test_ctx_options[j].name) == 0) {
- if (!ssl_test_ctx_options[j].parse(ctx, option->value)) {
+ for (j = 0; j < OSSL_NELEM(ssl_test_server_options); j++) {
+ if (strcmp(option->name, ssl_test_server_options[j].name) == 0) {
+ if (!ssl_test_server_options[j].parse(server, option->value)) {
fprintf(stderr, "Bad value %s for option %s\n",
option->value, option->name);
- goto err;
+ return 0;
}
found = 1;
break;
@@ -441,7 +495,72 @@ SSL_TEST_CTX *SSL_TEST_CTX_create(const CONF *conf, const char *test_section)
}
if (!found) {
fprintf(stderr, "Unknown test option: %s\n", option->name);
- goto err;
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+SSL_TEST_CTX *SSL_TEST_CTX_create(const CONF *conf, const char *test_section)
+{
+ STACK_OF(CONF_VALUE) *sk_conf;
+ SSL_TEST_CTX *ctx;
+ int i;
+ size_t j;
+
+ sk_conf = NCONF_get_section(conf, test_section);
+ OPENSSL_assert(sk_conf != NULL);
+
+ ctx = SSL_TEST_CTX_new();
+ OPENSSL_assert(ctx != NULL);
+
+ for (i = 0; i < sk_CONF_VALUE_num(sk_conf); i++) {
+ int found = 0;
+ const CONF_VALUE *option = sk_CONF_VALUE_value(sk_conf, i);
+
+ /* Subsections */
+ if (strcmp(option->name, "client") == 0) {
+ if (!parse_client_options(&ctx->extra.client, conf,
+ option->value))
+ goto err;
+ } else if (strcmp(option->name, "server") == 0) {
+ if (!parse_server_options(&ctx->extra.server, conf,
+ option->value))
+ goto err;
+ } else if (strcmp(option->name, "server2") == 0) {
+ if (!parse_server_options(&ctx->extra.server2, conf,
+ option->value))
+ goto err;
+ } else if (strcmp(option->name, "resume-client") == 0) {
+ if (!parse_client_options(&ctx->resume_extra.client, conf,
+ option->value))
+ goto err;
+ } else if (strcmp(option->name, "resume-server") == 0) {
+ if (!parse_server_options(&ctx->resume_extra.server, conf,
+ option->value))
+ goto err;
+ } else if (strcmp(option->name, "resume-server2") == 0) {
+ if (!parse_server_options(&ctx->resume_extra.server2, conf,
+ option->value))
+ goto err;
+
+ } else {
+ for (j = 0; j < OSSL_NELEM(ssl_test_ctx_options); j++) {
+ if (strcmp(option->name, ssl_test_ctx_options[j].name) == 0) {
+ if (!ssl_test_ctx_options[j].parse(ctx, option->value)) {
+ fprintf(stderr, "Bad value %s for option %s\n",
+ option->value, option->name);
+ goto err;
+ }
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ fprintf(stderr, "Unknown test option: %s\n", option->name);
+ goto err;
+ }
}
}