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},
__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)
return enum_name(ssl_alerts, OSSL_NELEM(ssl_alerts), alert);
}
-/************/
-/* Protocol */
-/************/
+/********************/
+/* ExpectedProtocol */
+/********************/
static const test_enum ssl_protocols[] = {
{"TLSv1.2", TLS1_2_VERSION},
__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)
}
/***********************/
-/* CertVerifyCallback. */
+/* VerifyCallback. */
/***********************/
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;
&ret_value, value)) {
return 0;
}
- test_ctx->client_verify_callback = ret_value;
+ client_conf->verify_callback = ret_value;
return 1;
}
{"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;
&ret_value, value)) {
return 0;
}
- test_ctx->servername = ret_value;
+ client_conf->servername = ret_value;
return 1;
}
server);
}
-/***********************/
-/* ServerNameCallback. */
-/***********************/
+/**********************/
+/* ServerNameCallback */
+/**********************/
static const test_enum ssl_servername_callbacks[] = {
{"None", SSL_TEST_SERVERNAME_CB_NONE},
{"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;
}
{"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)
}
/***********************/
-/* Method. */
+/* Method */
/***********************/
static const test_enum ssl_test_methods[] = {
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; \
}
/* 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 */
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);
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 },
};
/*
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;
}
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;
+ }
}
}