SSL tests: port CT tests, add a few more
[openssl.git] / test / ssl_test_ctx.c
1 /*
2  * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
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
8  */
9
10 #include <string.h>
11
12 #include <openssl/e_os2.h>
13 #include <openssl/crypto.h>
14
15 #include "e_os.h"
16 #include "ssl_test_ctx.h"
17
18 /* True enums and other test configuration values that map to an int. */
19 typedef struct {
20     const char *name;
21     int value;
22 } test_enum;
23
24
25 __owur static int parse_enum(const test_enum *enums, size_t num_enums,
26                              int *value, const char *name)
27 {
28     size_t i;
29     for (i = 0; i < num_enums; i++) {
30         if (strcmp(enums[i].name, name) == 0) {
31             *value = enums[i].value;
32             return 1;
33         }
34     }
35     return 0;
36 }
37
38 static const char *enum_name(const test_enum *enums, size_t num_enums,
39                              int value)
40 {
41     size_t i;
42     for (i = 0; i < num_enums; i++) {
43         if (enums[i].value == value) {
44             return enums[i].name;
45         }
46     }
47     return "InvalidValue";
48 }
49
50
51 /*******************/
52 /* ExpectedResult. */
53 /*******************/
54
55 static const test_enum ssl_test_results[] = {
56     {"Success", SSL_TEST_SUCCESS},
57     {"ServerFail", SSL_TEST_SERVER_FAIL},
58     {"ClientFail", SSL_TEST_CLIENT_FAIL},
59     {"InternalError", SSL_TEST_INTERNAL_ERROR},
60 };
61
62 __owur static int parse_expected_result(SSL_TEST_CTX *test_ctx, const char *value)
63 {
64     int ret_value;
65     if (!parse_enum(ssl_test_results, OSSL_NELEM(ssl_test_results),
66                     &ret_value, value)) {
67         return 0;
68     }
69     test_ctx->expected_result = ret_value;
70     return 1;
71 }
72
73 const char *ssl_test_result_name(ssl_test_result_t result)
74 {
75     return enum_name(ssl_test_results, OSSL_NELEM(ssl_test_results), result);
76 }
77
78 /**********************************************/
79 /* ExpectedClientAlert / ExpectedServerAlert. */
80 /**********************************************/
81
82 static const test_enum ssl_alerts[] = {
83     {"UnknownCA", SSL_AD_UNKNOWN_CA},
84     {"HandshakeFailure", SSL_AD_HANDSHAKE_FAILURE},
85     {"UnrecognizedName", SSL_AD_UNRECOGNIZED_NAME},
86     {"BadCertificate", SSL_AD_BAD_CERTIFICATE},
87     {"NoApplicationProtocol", SSL_AD_NO_APPLICATION_PROTOCOL},
88 };
89
90 __owur static int parse_alert(int *alert, const char *value)
91 {
92     return parse_enum(ssl_alerts, OSSL_NELEM(ssl_alerts), alert, value);
93 }
94
95 __owur static int parse_client_alert(SSL_TEST_CTX *test_ctx, const char *value)
96 {
97     return parse_alert(&test_ctx->expected_client_alert, value);
98 }
99
100 __owur static int parse_server_alert(SSL_TEST_CTX *test_ctx, const char *value)
101 {
102     return parse_alert(&test_ctx->expected_server_alert, value);
103 }
104
105 const char *ssl_alert_name(int alert)
106 {
107     return enum_name(ssl_alerts, OSSL_NELEM(ssl_alerts), alert);
108 }
109
110 /********************/
111 /* ExpectedProtocol */
112 /********************/
113
114 static const test_enum ssl_protocols[] = {
115      {"TLSv1.2", TLS1_2_VERSION},
116      {"TLSv1.1", TLS1_1_VERSION},
117      {"TLSv1", TLS1_VERSION},
118      {"SSLv3", SSL3_VERSION},
119      {"DTLSv1", DTLS1_VERSION},
120      {"DTLSv1.2", DTLS1_2_VERSION},
121 };
122
123 __owur static int parse_protocol(SSL_TEST_CTX *test_ctx, const char *value)
124 {
125     return parse_enum(ssl_protocols, OSSL_NELEM(ssl_protocols),
126                       &test_ctx->expected_protocol, value);
127 }
128
129 const char *ssl_protocol_name(int protocol)
130 {
131     return enum_name(ssl_protocols, OSSL_NELEM(ssl_protocols), protocol);
132 }
133
134 /***********************/
135 /* VerifyCallback. */
136 /***********************/
137
138 static const test_enum ssl_verify_callbacks[] = {
139     {"None", SSL_TEST_VERIFY_NONE},
140     {"AcceptAll", SSL_TEST_VERIFY_ACCEPT_ALL},
141     {"RejectAll", SSL_TEST_VERIFY_REJECT_ALL},
142 };
143
144 __owur static int parse_client_verify_callback(SSL_TEST_CLIENT_CONF *client_conf,
145                                                const char *value)
146 {
147     int ret_value;
148     if (!parse_enum(ssl_verify_callbacks, OSSL_NELEM(ssl_verify_callbacks),
149                     &ret_value, value)) {
150         return 0;
151     }
152     client_conf->verify_callback = ret_value;
153     return 1;
154 }
155
156 const char *ssl_verify_callback_name(ssl_verify_callback_t callback)
157 {
158     return enum_name(ssl_verify_callbacks, OSSL_NELEM(ssl_verify_callbacks),
159                      callback);
160 }
161
162 /**************/
163 /* ServerName */
164 /**************/
165
166 static const test_enum ssl_servername[] = {
167     {"None", SSL_TEST_SERVERNAME_NONE},
168     {"server1", SSL_TEST_SERVERNAME_SERVER1},
169     {"server2", SSL_TEST_SERVERNAME_SERVER2},
170     {"invalid", SSL_TEST_SERVERNAME_INVALID},
171 };
172
173 __owur static int parse_servername(SSL_TEST_CLIENT_CONF *client_conf,
174                                    const char *value)
175 {
176     int ret_value;
177     if (!parse_enum(ssl_servername, OSSL_NELEM(ssl_servername),
178                     &ret_value, value)) {
179         return 0;
180     }
181     client_conf->servername = ret_value;
182     return 1;
183 }
184
185 __owur static int parse_expected_servername(SSL_TEST_CTX *test_ctx,
186                                             const char *value)
187 {
188     int ret_value;
189     if (!parse_enum(ssl_servername, OSSL_NELEM(ssl_servername),
190                     &ret_value, value)) {
191         return 0;
192     }
193     test_ctx->expected_servername = ret_value;
194     return 1;
195 }
196
197 const char *ssl_servername_name(ssl_servername_t server)
198 {
199     return enum_name(ssl_servername, OSSL_NELEM(ssl_servername),
200                      server);
201 }
202
203 /**********************/
204 /* ServerNameCallback */
205 /**********************/
206
207 static const test_enum ssl_servername_callbacks[] = {
208     {"None", SSL_TEST_SERVERNAME_CB_NONE},
209     {"IgnoreMismatch", SSL_TEST_SERVERNAME_IGNORE_MISMATCH},
210     {"RejectMismatch", SSL_TEST_SERVERNAME_REJECT_MISMATCH},
211 };
212
213 __owur static int parse_servername_callback(SSL_TEST_SERVER_CONF *server_conf,
214                                             const char *value)
215 {
216     int ret_value;
217     if (!parse_enum(ssl_servername_callbacks,
218                     OSSL_NELEM(ssl_servername_callbacks), &ret_value, value)) {
219         return 0;
220     }
221     server_conf->servername_callback = ret_value;
222     return 1;
223 }
224
225 const char *ssl_servername_callback_name(ssl_servername_callback_t callback)
226 {
227     return enum_name(ssl_servername_callbacks,
228                      OSSL_NELEM(ssl_servername_callbacks), callback);
229 }
230
231 /*************************/
232 /* SessionTicketExpected */
233 /*************************/
234
235 static const test_enum ssl_session_ticket[] = {
236     {"Ignore", SSL_TEST_SESSION_TICKET_IGNORE},
237     {"Yes", SSL_TEST_SESSION_TICKET_YES},
238     {"No", SSL_TEST_SESSION_TICKET_NO},
239 };
240
241 __owur static int parse_session_ticket(SSL_TEST_CTX *test_ctx, const char *value)
242 {
243     int ret_value;
244     if (!parse_enum(ssl_session_ticket, OSSL_NELEM(ssl_session_ticket),
245                     &ret_value, value)) {
246         return 0;
247     }
248     test_ctx->session_ticket_expected = ret_value;
249     return 1;
250 }
251
252 const char *ssl_session_ticket_name(ssl_session_ticket_t server)
253 {
254     return enum_name(ssl_session_ticket,
255                      OSSL_NELEM(ssl_session_ticket),
256                      server);
257 }
258
259 /***********************/
260 /* Method              */
261 /***********************/
262
263 static const test_enum ssl_test_methods[] = {
264     {"TLS", SSL_TEST_METHOD_TLS},
265     {"DTLS", SSL_TEST_METHOD_DTLS},
266 };
267
268 __owur static int parse_test_method(SSL_TEST_CTX *test_ctx, const char *value)
269 {
270     int ret_value;
271     if (!parse_enum(ssl_test_methods, OSSL_NELEM(ssl_test_methods),
272                     &ret_value, value)) {
273         return 0;
274     }
275     test_ctx->method = ret_value;
276     return 1;
277 }
278
279 const char *ssl_test_method_name(ssl_test_method_t method)
280 {
281     return enum_name(ssl_test_methods, OSSL_NELEM(ssl_test_methods), method);
282 }
283
284 #define IMPLEMENT_SSL_TEST_STRING_OPTION(struct_type, name, field)      \
285     static int parse_##name##_##field(struct_type *ctx, const char *value) \
286     {                                                                   \
287         OPENSSL_free(ctx->field);                                       \
288         ctx->field = OPENSSL_strdup(value);                             \
289         OPENSSL_assert(ctx->field != NULL);                             \
290         return 1;                                                       \
291     }
292
293 /************************************/
294 /* NPN and ALPN options             */
295 /************************************/
296
297 IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CLIENT_CONF, client, npn_protocols)
298 IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_SERVER_CONF, server, npn_protocols)
299 IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CTX, test, expected_npn_protocol)
300 IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CLIENT_CONF, client, alpn_protocols)
301 IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_SERVER_CONF, server, alpn_protocols)
302 IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CTX, test, expected_alpn_protocol)
303
304 /***********************/
305 /* Handshake mode      */
306 /***********************/
307
308 static const test_enum ssl_handshake_modes[] = {
309     {"Simple", SSL_TEST_HANDSHAKE_SIMPLE},
310     {"Resume", SSL_TEST_HANDSHAKE_RESUME},
311     {"Renegotiate", SSL_TEST_HANDSHAKE_RENEGOTIATE},
312 };
313
314 __owur static int parse_handshake_mode(SSL_TEST_CTX *test_ctx, const char *value)
315 {
316     int ret_value;
317     if (!parse_enum(ssl_handshake_modes, OSSL_NELEM(ssl_handshake_modes),
318                     &ret_value, value)) {
319         return 0;
320     }
321     test_ctx->handshake_mode = ret_value;
322     return 1;
323 }
324
325 const char *ssl_handshake_mode_name(ssl_handshake_mode_t mode)
326 {
327     return enum_name(ssl_handshake_modes, OSSL_NELEM(ssl_handshake_modes),
328                      mode);
329 }
330
331 /***********************/
332 /* CT Validation       */
333 /***********************/
334
335 static const test_enum ssl_ct_validation_modes[] = {
336     {"None", SSL_TEST_CT_VALIDATION_NONE},
337     {"Permissive", SSL_TEST_CT_VALIDATION_PERMISSIVE},
338     {"Strict", SSL_TEST_CT_VALIDATION_STRICT},
339 };
340
341 __owur static int parse_ct_validation(SSL_TEST_CLIENT_CONF *client_conf,
342                                       const char *value)
343 {
344     int ret_value;
345     if (!parse_enum(ssl_ct_validation_modes, OSSL_NELEM(ssl_ct_validation_modes),
346                     &ret_value, value)) {
347         return 0;
348     }
349     client_conf->ct_validation = ret_value;
350     return 1;
351 }
352
353 const char *ssl_ct_validation_name(ssl_ct_validation_t mode)
354 {
355     return enum_name(ssl_ct_validation_modes, OSSL_NELEM(ssl_ct_validation_modes),
356                      mode);
357 }
358
359 static int parse_boolean(const char *value, int *result)
360 {
361     if (strcasecmp(value, "Yes") == 0) {
362         *result = 1;
363         return 1;
364     }
365     else if (strcasecmp(value, "No") == 0) {
366         *result = 0;
367         return 1;
368     }
369     return 0;
370 }
371
372 #define IMPLEMENT_SSL_TEST_BOOL_OPTION(struct_type, name, field)        \
373     static int parse_##name##_##field(struct_type *ctx, const char *value) \
374     {                                                                   \
375         return parse_boolean(value, &ctx->field);                       \
376     }
377
378 IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_CTX, test, resumption_expected)
379 IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_SERVER_CONF, server, broken_session_ticket)
380
381 /*************************************************************/
382 /* Known test options and their corresponding parse methods. */
383 /*************************************************************/
384
385 /* Top-level options. */
386 typedef struct {
387     const char *name;
388     int (*parse)(SSL_TEST_CTX *test_ctx, const char *value);
389 } ssl_test_ctx_option;
390
391 static const ssl_test_ctx_option ssl_test_ctx_options[] = {
392     { "ExpectedResult", &parse_expected_result },
393     { "ExpectedClientAlert", &parse_client_alert },
394     { "ExpectedServerAlert", &parse_server_alert },
395     { "ExpectedProtocol", &parse_protocol },
396     { "ExpectedServerName", &parse_expected_servername },
397     { "SessionTicketExpected", &parse_session_ticket },
398     { "Method", &parse_test_method },
399     { "ExpectedNPNProtocol", &parse_test_expected_npn_protocol },
400     { "ExpectedALPNProtocol", &parse_test_expected_alpn_protocol },
401     { "HandshakeMode", &parse_handshake_mode },
402     { "ResumptionExpected", &parse_test_resumption_expected },
403 };
404
405 /* Nested client options. */
406 typedef struct {
407     const char *name;
408     int (*parse)(SSL_TEST_CLIENT_CONF *conf, const char *value);
409 } ssl_test_client_option;
410
411 static const ssl_test_client_option ssl_test_client_options[] = {
412     { "VerifyCallback", &parse_client_verify_callback },
413     { "ServerName", &parse_servername },
414     { "NPNProtocols", &parse_client_npn_protocols },
415     { "ALPNProtocols", &parse_client_alpn_protocols },
416     { "CTValidation", &parse_ct_validation },
417 };
418
419 /* Nested server options. */
420 typedef struct {
421     const char *name;
422     int (*parse)(SSL_TEST_SERVER_CONF *conf, const char *value);
423 } ssl_test_server_option;
424
425 static const ssl_test_server_option ssl_test_server_options[] = {
426     { "ServerNameCallback", &parse_servername_callback },
427     { "NPNProtocols", &parse_server_npn_protocols },
428     { "ALPNProtocols", &parse_server_alpn_protocols },
429     { "BrokenSessionTicket", &parse_server_broken_session_ticket },
430 };
431
432 /*
433  * Since these methods are used to create tests, we use OPENSSL_assert liberally
434  * for malloc failures and other internal errors.
435  */
436 SSL_TEST_CTX *SSL_TEST_CTX_new()
437 {
438     SSL_TEST_CTX *ret;
439     ret = OPENSSL_zalloc(sizeof(*ret));
440     OPENSSL_assert(ret != NULL);
441     return ret;
442 }
443
444 static void ssl_test_extra_conf_free_data(SSL_TEST_EXTRA_CONF *conf)
445 {
446     OPENSSL_free(conf->client.npn_protocols);
447     OPENSSL_free(conf->server.npn_protocols);
448     OPENSSL_free(conf->server2.npn_protocols);
449     OPENSSL_free(conf->client.alpn_protocols);
450     OPENSSL_free(conf->server.alpn_protocols);
451     OPENSSL_free(conf->server2.alpn_protocols);
452 }
453
454 static void ssl_test_ctx_free_extra_data(SSL_TEST_CTX *ctx)
455 {
456     ssl_test_extra_conf_free_data(&ctx->extra);
457     ssl_test_extra_conf_free_data(&ctx->resume_extra);
458 }
459
460 void SSL_TEST_CTX_free(SSL_TEST_CTX *ctx)
461 {
462     ssl_test_ctx_free_extra_data(ctx);
463     OPENSSL_free(ctx->expected_npn_protocol);
464     OPENSSL_free(ctx->expected_alpn_protocol);
465     OPENSSL_free(ctx);
466 }
467
468 static int parse_client_options(SSL_TEST_CLIENT_CONF *client, const CONF *conf,
469                                 const char *client_section)
470 {
471     STACK_OF(CONF_VALUE) *sk_conf;
472     int i;
473     size_t j;
474
475     sk_conf = NCONF_get_section(conf, client_section);
476     OPENSSL_assert(sk_conf != NULL);
477
478     for (i = 0; i < sk_CONF_VALUE_num(sk_conf); i++) {
479         int found = 0;
480         const CONF_VALUE *option = sk_CONF_VALUE_value(sk_conf, i);
481         for (j = 0; j < OSSL_NELEM(ssl_test_client_options); j++) {
482             if (strcmp(option->name, ssl_test_client_options[j].name) == 0) {
483                 if (!ssl_test_client_options[j].parse(client, option->value)) {
484                     fprintf(stderr, "Bad value %s for option %s\n",
485                             option->value, option->name);
486                     return 0;
487                 }
488                 found = 1;
489                 break;
490             }
491         }
492         if (!found) {
493             fprintf(stderr, "Unknown test option: %s\n", option->name);
494             return 0;
495         }
496     }
497
498     return 1;
499 }
500
501 static int parse_server_options(SSL_TEST_SERVER_CONF *server, const CONF *conf,
502                                 const char *server_section)
503 {
504     STACK_OF(CONF_VALUE) *sk_conf;
505     int i;
506     size_t j;
507
508     sk_conf = NCONF_get_section(conf, server_section);
509     OPENSSL_assert(sk_conf != NULL);
510
511     for (i = 0; i < sk_CONF_VALUE_num(sk_conf); i++) {
512         int found = 0;
513         const CONF_VALUE *option = sk_CONF_VALUE_value(sk_conf, i);
514         for (j = 0; j < OSSL_NELEM(ssl_test_server_options); j++) {
515             if (strcmp(option->name, ssl_test_server_options[j].name) == 0) {
516                 if (!ssl_test_server_options[j].parse(server, option->value)) {
517                     fprintf(stderr, "Bad value %s for option %s\n",
518                             option->value, option->name);
519                     return 0;
520                 }
521                 found = 1;
522                 break;
523             }
524         }
525         if (!found) {
526             fprintf(stderr, "Unknown test option: %s\n", option->name);
527             return 0;
528         }
529     }
530
531     return 1;
532 }
533
534 SSL_TEST_CTX *SSL_TEST_CTX_create(const CONF *conf, const char *test_section)
535 {
536     STACK_OF(CONF_VALUE) *sk_conf;
537     SSL_TEST_CTX *ctx;
538     int i;
539     size_t j;
540
541     sk_conf = NCONF_get_section(conf, test_section);
542     OPENSSL_assert(sk_conf != NULL);
543
544     ctx = SSL_TEST_CTX_new();
545     OPENSSL_assert(ctx != NULL);
546
547     for (i = 0; i < sk_CONF_VALUE_num(sk_conf); i++) {
548         int found = 0;
549         const CONF_VALUE *option = sk_CONF_VALUE_value(sk_conf, i);
550
551         /* Subsections */
552         if (strcmp(option->name, "client") == 0) {
553             if (!parse_client_options(&ctx->extra.client, conf,
554                                       option->value))
555                 goto err;
556         } else if (strcmp(option->name, "server") == 0) {
557             if (!parse_server_options(&ctx->extra.server, conf,
558                                       option->value))
559                 goto err;
560         } else if (strcmp(option->name, "server2") == 0) {
561             if (!parse_server_options(&ctx->extra.server2, conf,
562                                       option->value))
563                 goto err;
564         } else if (strcmp(option->name, "resume-client") == 0) {
565             if (!parse_client_options(&ctx->resume_extra.client, conf,
566                                       option->value))
567                 goto err;
568         } else if (strcmp(option->name, "resume-server") == 0) {
569             if (!parse_server_options(&ctx->resume_extra.server, conf,
570                                       option->value))
571                 goto err;
572         } else if (strcmp(option->name, "resume-server2") == 0) {
573             if (!parse_server_options(&ctx->resume_extra.server2, conf,
574                                       option->value))
575                 goto err;
576
577         } else {
578             for (j = 0; j < OSSL_NELEM(ssl_test_ctx_options); j++) {
579                 if (strcmp(option->name, ssl_test_ctx_options[j].name) == 0) {
580                     if (!ssl_test_ctx_options[j].parse(ctx, option->value)) {
581                         fprintf(stderr, "Bad value %s for option %s\n",
582                                 option->value, option->name);
583                         goto err;
584                     }
585                     found = 1;
586                     break;
587                 }
588             }
589             if (!found) {
590                 fprintf(stderr, "Unknown test option: %s\n", option->name);
591                 goto err;
592             }
593         }
594     }
595
596     goto done;
597
598  err:
599     SSL_TEST_CTX_free(ctx);
600     ctx = NULL;
601  done:
602     return ctx;
603 }