2 * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
12 #include <openssl/e_os2.h>
13 #include <openssl/crypto.h>
16 #include "ssl_test_ctx.h"
19 static const int default_app_data_size = 256;
21 static int parse_boolean(const char *value, int *result)
23 if (strcasecmp(value, "Yes") == 0) {
27 else if (strcasecmp(value, "No") == 0) {
34 #define IMPLEMENT_SSL_TEST_BOOL_OPTION(struct_type, name, field) \
35 static int parse_##name##_##field(struct_type *ctx, const char *value) \
37 return parse_boolean(value, &ctx->field); \
40 #define IMPLEMENT_SSL_TEST_STRING_OPTION(struct_type, name, field) \
41 static int parse_##name##_##field(struct_type *ctx, const char *value) \
43 OPENSSL_free(ctx->field); \
44 ctx->field = OPENSSL_strdup(value); \
45 TEST_check(ctx->field != NULL); \
49 #define IMPLEMENT_SSL_TEST_INT_OPTION(struct_type, name, field) \
50 static int parse_##name##_##field(struct_type *ctx, const char *value) \
52 ctx->field = atoi(value); \
56 /* True enums and other test configuration values that map to an int. */
63 __owur static int parse_enum(const test_enum *enums, size_t num_enums,
64 int *value, const char *name)
67 for (i = 0; i < num_enums; i++) {
68 if (strcmp(enums[i].name, name) == 0) {
69 *value = enums[i].value;
76 static const char *enum_name(const test_enum *enums, size_t num_enums,
80 for (i = 0; i < num_enums; i++) {
81 if (enums[i].value == value) {
85 return "InvalidValue";
93 static const test_enum ssl_test_results[] = {
94 {"Success", SSL_TEST_SUCCESS},
95 {"ServerFail", SSL_TEST_SERVER_FAIL},
96 {"ClientFail", SSL_TEST_CLIENT_FAIL},
97 {"InternalError", SSL_TEST_INTERNAL_ERROR},
100 __owur static int parse_expected_result(SSL_TEST_CTX *test_ctx, const char *value)
103 if (!parse_enum(ssl_test_results, OSSL_NELEM(ssl_test_results),
104 &ret_value, value)) {
107 test_ctx->expected_result = ret_value;
111 const char *ssl_test_result_name(ssl_test_result_t result)
113 return enum_name(ssl_test_results, OSSL_NELEM(ssl_test_results), result);
116 /**********************************************/
117 /* ExpectedClientAlert / ExpectedServerAlert. */
118 /**********************************************/
120 static const test_enum ssl_alerts[] = {
121 {"UnknownCA", SSL_AD_UNKNOWN_CA},
122 {"HandshakeFailure", SSL_AD_HANDSHAKE_FAILURE},
123 {"UnrecognizedName", SSL_AD_UNRECOGNIZED_NAME},
124 {"BadCertificate", SSL_AD_BAD_CERTIFICATE},
125 {"NoApplicationProtocol", SSL_AD_NO_APPLICATION_PROTOCOL},
128 __owur static int parse_alert(int *alert, const char *value)
130 return parse_enum(ssl_alerts, OSSL_NELEM(ssl_alerts), alert, value);
133 __owur static int parse_client_alert(SSL_TEST_CTX *test_ctx, const char *value)
135 return parse_alert(&test_ctx->expected_client_alert, value);
138 __owur static int parse_server_alert(SSL_TEST_CTX *test_ctx, const char *value)
140 return parse_alert(&test_ctx->expected_server_alert, value);
143 const char *ssl_alert_name(int alert)
145 return enum_name(ssl_alerts, OSSL_NELEM(ssl_alerts), alert);
148 /********************/
149 /* ExpectedProtocol */
150 /********************/
152 static const test_enum ssl_protocols[] = {
153 {"TLSv1.2", TLS1_2_VERSION},
154 {"TLSv1.1", TLS1_1_VERSION},
155 {"TLSv1", TLS1_VERSION},
156 {"SSLv3", SSL3_VERSION},
157 {"DTLSv1", DTLS1_VERSION},
158 {"DTLSv1.2", DTLS1_2_VERSION},
161 __owur static int parse_protocol(SSL_TEST_CTX *test_ctx, const char *value)
163 return parse_enum(ssl_protocols, OSSL_NELEM(ssl_protocols),
164 &test_ctx->expected_protocol, value);
167 const char *ssl_protocol_name(int protocol)
169 return enum_name(ssl_protocols, OSSL_NELEM(ssl_protocols), protocol);
172 /***********************/
173 /* VerifyCallback. */
174 /***********************/
176 static const test_enum ssl_verify_callbacks[] = {
177 {"None", SSL_TEST_VERIFY_NONE},
178 {"AcceptAll", SSL_TEST_VERIFY_ACCEPT_ALL},
179 {"RejectAll", SSL_TEST_VERIFY_REJECT_ALL},
182 __owur static int parse_client_verify_callback(SSL_TEST_CLIENT_CONF *client_conf,
186 if (!parse_enum(ssl_verify_callbacks, OSSL_NELEM(ssl_verify_callbacks),
187 &ret_value, value)) {
190 client_conf->verify_callback = ret_value;
194 const char *ssl_verify_callback_name(ssl_verify_callback_t callback)
196 return enum_name(ssl_verify_callbacks, OSSL_NELEM(ssl_verify_callbacks),
204 static const test_enum ssl_servername[] = {
205 {"None", SSL_TEST_SERVERNAME_NONE},
206 {"server1", SSL_TEST_SERVERNAME_SERVER1},
207 {"server2", SSL_TEST_SERVERNAME_SERVER2},
208 {"invalid", SSL_TEST_SERVERNAME_INVALID},
211 __owur static int parse_servername(SSL_TEST_CLIENT_CONF *client_conf,
215 if (!parse_enum(ssl_servername, OSSL_NELEM(ssl_servername),
216 &ret_value, value)) {
219 client_conf->servername = ret_value;
223 __owur static int parse_expected_servername(SSL_TEST_CTX *test_ctx,
227 if (!parse_enum(ssl_servername, OSSL_NELEM(ssl_servername),
228 &ret_value, value)) {
231 test_ctx->expected_servername = ret_value;
235 const char *ssl_servername_name(ssl_servername_t server)
237 return enum_name(ssl_servername, OSSL_NELEM(ssl_servername),
241 /**********************/
242 /* ServerNameCallback */
243 /**********************/
245 static const test_enum ssl_servername_callbacks[] = {
246 {"None", SSL_TEST_SERVERNAME_CB_NONE},
247 {"IgnoreMismatch", SSL_TEST_SERVERNAME_IGNORE_MISMATCH},
248 {"RejectMismatch", SSL_TEST_SERVERNAME_REJECT_MISMATCH},
251 __owur static int parse_servername_callback(SSL_TEST_SERVER_CONF *server_conf,
255 if (!parse_enum(ssl_servername_callbacks,
256 OSSL_NELEM(ssl_servername_callbacks), &ret_value, value)) {
259 server_conf->servername_callback = ret_value;
263 const char *ssl_servername_callback_name(ssl_servername_callback_t callback)
265 return enum_name(ssl_servername_callbacks,
266 OSSL_NELEM(ssl_servername_callbacks), callback);
269 /*************************/
270 /* SessionTicketExpected */
271 /*************************/
273 static const test_enum ssl_session_ticket[] = {
274 {"Ignore", SSL_TEST_SESSION_TICKET_IGNORE},
275 {"Yes", SSL_TEST_SESSION_TICKET_YES},
276 {"No", SSL_TEST_SESSION_TICKET_NO},
279 __owur static int parse_session_ticket(SSL_TEST_CTX *test_ctx, const char *value)
282 if (!parse_enum(ssl_session_ticket, OSSL_NELEM(ssl_session_ticket),
283 &ret_value, value)) {
286 test_ctx->session_ticket_expected = ret_value;
290 const char *ssl_session_ticket_name(ssl_session_ticket_t server)
292 return enum_name(ssl_session_ticket,
293 OSSL_NELEM(ssl_session_ticket),
297 /***********************/
299 /***********************/
301 static const test_enum ssl_test_methods[] = {
302 {"TLS", SSL_TEST_METHOD_TLS},
303 {"DTLS", SSL_TEST_METHOD_DTLS},
306 __owur static int parse_test_method(SSL_TEST_CTX *test_ctx, const char *value)
309 if (!parse_enum(ssl_test_methods, OSSL_NELEM(ssl_test_methods),
310 &ret_value, value)) {
313 test_ctx->method = ret_value;
317 const char *ssl_test_method_name(ssl_test_method_t method)
319 return enum_name(ssl_test_methods, OSSL_NELEM(ssl_test_methods), method);
322 /************************************/
323 /* NPN and ALPN options */
324 /************************************/
326 IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CLIENT_CONF, client, npn_protocols)
327 IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_SERVER_CONF, server, npn_protocols)
328 IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CTX, test, expected_npn_protocol)
329 IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CLIENT_CONF, client, alpn_protocols)
330 IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_SERVER_CONF, server, alpn_protocols)
331 IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CTX, test, expected_alpn_protocol)
333 /***********************/
335 /***********************/
337 static const test_enum ssl_handshake_modes[] = {
338 {"Simple", SSL_TEST_HANDSHAKE_SIMPLE},
339 {"Resume", SSL_TEST_HANDSHAKE_RESUME},
340 {"Renegotiate", SSL_TEST_HANDSHAKE_RENEGOTIATE},
343 __owur static int parse_handshake_mode(SSL_TEST_CTX *test_ctx, const char *value)
346 if (!parse_enum(ssl_handshake_modes, OSSL_NELEM(ssl_handshake_modes),
347 &ret_value, value)) {
350 test_ctx->handshake_mode = ret_value;
354 const char *ssl_handshake_mode_name(ssl_handshake_mode_t mode)
356 return enum_name(ssl_handshake_modes, OSSL_NELEM(ssl_handshake_modes),
360 /***********************/
362 /***********************/
364 static const test_enum ssl_ct_validation_modes[] = {
365 {"None", SSL_TEST_CT_VALIDATION_NONE},
366 {"Permissive", SSL_TEST_CT_VALIDATION_PERMISSIVE},
367 {"Strict", SSL_TEST_CT_VALIDATION_STRICT},
370 __owur static int parse_ct_validation(SSL_TEST_CLIENT_CONF *client_conf,
374 if (!parse_enum(ssl_ct_validation_modes, OSSL_NELEM(ssl_ct_validation_modes),
375 &ret_value, value)) {
378 client_conf->ct_validation = ret_value;
382 const char *ssl_ct_validation_name(ssl_ct_validation_t mode)
384 return enum_name(ssl_ct_validation_modes, OSSL_NELEM(ssl_ct_validation_modes),
388 IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_CTX, test, resumption_expected)
389 IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_SERVER_CONF, server, broken_session_ticket)
391 /***********************/
392 /* Applicationdata */
393 /***********************/
395 IMPLEMENT_SSL_TEST_INT_OPTION(SSL_TEST_CTX, test, app_data_size)
397 /*************************************************************/
398 /* Known test options and their corresponding parse methods. */
399 /*************************************************************/
401 /* Top-level options. */
404 int (*parse)(SSL_TEST_CTX *test_ctx, const char *value);
405 } ssl_test_ctx_option;
407 static const ssl_test_ctx_option ssl_test_ctx_options[] = {
408 { "ExpectedResult", &parse_expected_result },
409 { "ExpectedClientAlert", &parse_client_alert },
410 { "ExpectedServerAlert", &parse_server_alert },
411 { "ExpectedProtocol", &parse_protocol },
412 { "ExpectedServerName", &parse_expected_servername },
413 { "SessionTicketExpected", &parse_session_ticket },
414 { "Method", &parse_test_method },
415 { "ExpectedNPNProtocol", &parse_test_expected_npn_protocol },
416 { "ExpectedALPNProtocol", &parse_test_expected_alpn_protocol },
417 { "HandshakeMode", &parse_handshake_mode },
418 { "ResumptionExpected", &parse_test_resumption_expected },
419 { "ApplicationData", &parse_test_app_data_size },
422 /* Nested client options. */
425 int (*parse)(SSL_TEST_CLIENT_CONF *conf, const char *value);
426 } ssl_test_client_option;
428 static const ssl_test_client_option ssl_test_client_options[] = {
429 { "VerifyCallback", &parse_client_verify_callback },
430 { "ServerName", &parse_servername },
431 { "NPNProtocols", &parse_client_npn_protocols },
432 { "ALPNProtocols", &parse_client_alpn_protocols },
433 { "CTValidation", &parse_ct_validation },
436 /* Nested server options. */
439 int (*parse)(SSL_TEST_SERVER_CONF *conf, const char *value);
440 } ssl_test_server_option;
442 static const ssl_test_server_option ssl_test_server_options[] = {
443 { "ServerNameCallback", &parse_servername_callback },
444 { "NPNProtocols", &parse_server_npn_protocols },
445 { "ALPNProtocols", &parse_server_alpn_protocols },
446 { "BrokenSessionTicket", &parse_server_broken_session_ticket },
450 * Since these methods are used to create tests, we use TEST_check liberally
451 * for malloc failures and other internal errors.
453 SSL_TEST_CTX *SSL_TEST_CTX_new()
456 ret = OPENSSL_zalloc(sizeof(*ret));
457 TEST_check(ret != NULL);
458 ret->app_data_size = default_app_data_size;
462 static void ssl_test_extra_conf_free_data(SSL_TEST_EXTRA_CONF *conf)
464 OPENSSL_free(conf->client.npn_protocols);
465 OPENSSL_free(conf->server.npn_protocols);
466 OPENSSL_free(conf->server2.npn_protocols);
467 OPENSSL_free(conf->client.alpn_protocols);
468 OPENSSL_free(conf->server.alpn_protocols);
469 OPENSSL_free(conf->server2.alpn_protocols);
472 static void ssl_test_ctx_free_extra_data(SSL_TEST_CTX *ctx)
474 ssl_test_extra_conf_free_data(&ctx->extra);
475 ssl_test_extra_conf_free_data(&ctx->resume_extra);
478 void SSL_TEST_CTX_free(SSL_TEST_CTX *ctx)
480 ssl_test_ctx_free_extra_data(ctx);
481 OPENSSL_free(ctx->expected_npn_protocol);
482 OPENSSL_free(ctx->expected_alpn_protocol);
486 static int parse_client_options(SSL_TEST_CLIENT_CONF *client, const CONF *conf,
487 const char *client_section)
489 STACK_OF(CONF_VALUE) *sk_conf;
493 sk_conf = NCONF_get_section(conf, client_section);
494 TEST_check(sk_conf != NULL);
496 for (i = 0; i < sk_CONF_VALUE_num(sk_conf); i++) {
498 const CONF_VALUE *option = sk_CONF_VALUE_value(sk_conf, i);
499 for (j = 0; j < OSSL_NELEM(ssl_test_client_options); j++) {
500 if (strcmp(option->name, ssl_test_client_options[j].name) == 0) {
501 if (!ssl_test_client_options[j].parse(client, option->value)) {
502 fprintf(stderr, "Bad value %s for option %s\n",
503 option->value, option->name);
511 fprintf(stderr, "Unknown test option: %s\n", option->name);
519 static int parse_server_options(SSL_TEST_SERVER_CONF *server, const CONF *conf,
520 const char *server_section)
522 STACK_OF(CONF_VALUE) *sk_conf;
526 sk_conf = NCONF_get_section(conf, server_section);
527 TEST_check(sk_conf != NULL);
529 for (i = 0; i < sk_CONF_VALUE_num(sk_conf); i++) {
531 const CONF_VALUE *option = sk_CONF_VALUE_value(sk_conf, i);
532 for (j = 0; j < OSSL_NELEM(ssl_test_server_options); j++) {
533 if (strcmp(option->name, ssl_test_server_options[j].name) == 0) {
534 if (!ssl_test_server_options[j].parse(server, option->value)) {
535 fprintf(stderr, "Bad value %s for option %s\n",
536 option->value, option->name);
544 fprintf(stderr, "Unknown test option: %s\n", option->name);
552 SSL_TEST_CTX *SSL_TEST_CTX_create(const CONF *conf, const char *test_section)
554 STACK_OF(CONF_VALUE) *sk_conf;
559 sk_conf = NCONF_get_section(conf, test_section);
560 TEST_check(sk_conf != NULL);
562 ctx = SSL_TEST_CTX_new();
563 TEST_check(ctx != NULL);
565 for (i = 0; i < sk_CONF_VALUE_num(sk_conf); i++) {
567 const CONF_VALUE *option = sk_CONF_VALUE_value(sk_conf, i);
570 if (strcmp(option->name, "client") == 0) {
571 if (!parse_client_options(&ctx->extra.client, conf,
574 } else if (strcmp(option->name, "server") == 0) {
575 if (!parse_server_options(&ctx->extra.server, conf,
578 } else if (strcmp(option->name, "server2") == 0) {
579 if (!parse_server_options(&ctx->extra.server2, conf,
582 } else if (strcmp(option->name, "resume-client") == 0) {
583 if (!parse_client_options(&ctx->resume_extra.client, conf,
586 } else if (strcmp(option->name, "resume-server") == 0) {
587 if (!parse_server_options(&ctx->resume_extra.server, conf,
590 } else if (strcmp(option->name, "resume-server2") == 0) {
591 if (!parse_server_options(&ctx->resume_extra.server2, conf,
596 for (j = 0; j < OSSL_NELEM(ssl_test_ctx_options); j++) {
597 if (strcmp(option->name, ssl_test_ctx_options[j].name) == 0) {
598 if (!ssl_test_ctx_options[j].parse(ctx, option->value)) {
599 fprintf(stderr, "Bad value %s for option %s\n",
600 option->value, option->name);
608 fprintf(stderr, "Unknown test option: %s\n", option->name);
617 SSL_TEST_CTX_free(ctx);