]>
Commit | Line | Data |
---|---|---|
453dfd8d | 1 | /* |
6738bf14 | 2 | * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. |
453dfd8d | 3 | * |
440e5d80 RS |
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 | |
453dfd8d | 7 | * https://www.openssl.org/source/license.html |
453dfd8d EK |
8 | */ |
9 | ||
10 | #include <string.h> | |
11 | ||
12 | #include <openssl/e_os2.h> | |
13 | #include <openssl/crypto.h> | |
14 | ||
176db6dc | 15 | #include "internal/nelem.h" |
453dfd8d | 16 | #include "ssl_test_ctx.h" |
d61f0078 | 17 | #include "testutil.h" |
453dfd8d | 18 | |
2b1aa198 RL |
19 | #ifdef OPENSSL_SYS_WINDOWS |
20 | # define strcasecmp _stricmp | |
21 | #endif | |
22 | ||
e0421bd8 | 23 | static const int default_app_data_size = 256; |
6dc99745 EK |
24 | /* Default set to be as small as possible to exercise fragmentation. */ |
25 | static const int default_max_fragment_size = 512; | |
e0421bd8 EK |
26 | |
27 | static int parse_boolean(const char *value, int *result) | |
28 | { | |
29 | if (strcasecmp(value, "Yes") == 0) { | |
30 | *result = 1; | |
31 | return 1; | |
32 | } | |
33 | else if (strcasecmp(value, "No") == 0) { | |
34 | *result = 0; | |
35 | return 1; | |
36 | } | |
019e47ce | 37 | TEST_error("parse_boolean given: '%s'", value); |
e0421bd8 EK |
38 | return 0; |
39 | } | |
40 | ||
41 | #define IMPLEMENT_SSL_TEST_BOOL_OPTION(struct_type, name, field) \ | |
42 | static int parse_##name##_##field(struct_type *ctx, const char *value) \ | |
43 | { \ | |
44 | return parse_boolean(value, &ctx->field); \ | |
45 | } | |
46 | ||
47 | #define IMPLEMENT_SSL_TEST_STRING_OPTION(struct_type, name, field) \ | |
48 | static int parse_##name##_##field(struct_type *ctx, const char *value) \ | |
49 | { \ | |
50 | OPENSSL_free(ctx->field); \ | |
51 | ctx->field = OPENSSL_strdup(value); \ | |
019e47ce | 52 | return TEST_ptr(ctx->field); \ |
e0421bd8 EK |
53 | } |
54 | ||
55 | #define IMPLEMENT_SSL_TEST_INT_OPTION(struct_type, name, field) \ | |
56 | static int parse_##name##_##field(struct_type *ctx, const char *value) \ | |
57 | { \ | |
58 | ctx->field = atoi(value); \ | |
59 | return 1; \ | |
60 | } | |
61 | ||
453dfd8d EK |
62 | /* True enums and other test configuration values that map to an int. */ |
63 | typedef struct { | |
64 | const char *name; | |
65 | int value; | |
66 | } test_enum; | |
67 | ||
68 | ||
69 | __owur static int parse_enum(const test_enum *enums, size_t num_enums, | |
70 | int *value, const char *name) | |
71 | { | |
72 | size_t i; | |
73 | for (i = 0; i < num_enums; i++) { | |
74 | if (strcmp(enums[i].name, name) == 0) { | |
75 | *value = enums[i].value; | |
76 | return 1; | |
77 | } | |
78 | } | |
79 | return 0; | |
80 | } | |
81 | ||
82 | static const char *enum_name(const test_enum *enums, size_t num_enums, | |
83 | int value) | |
84 | { | |
85 | size_t i; | |
86 | for (i = 0; i < num_enums; i++) { | |
87 | if (enums[i].value == value) { | |
88 | return enums[i].name; | |
89 | } | |
90 | } | |
91 | return "InvalidValue"; | |
92 | } | |
93 | ||
94 | ||
cc22cd54 | 95 | /* ExpectedResult */ |
453dfd8d EK |
96 | |
97 | static const test_enum ssl_test_results[] = { | |
98 | {"Success", SSL_TEST_SUCCESS}, | |
99 | {"ServerFail", SSL_TEST_SERVER_FAIL}, | |
100 | {"ClientFail", SSL_TEST_CLIENT_FAIL}, | |
101 | {"InternalError", SSL_TEST_INTERNAL_ERROR}, | |
df0fed9a | 102 | {"FirstHandshakeFailed", SSL_TEST_FIRST_HANDSHAKE_FAILED}, |
453dfd8d EK |
103 | }; |
104 | ||
105 | __owur static int parse_expected_result(SSL_TEST_CTX *test_ctx, const char *value) | |
106 | { | |
107 | int ret_value; | |
108 | if (!parse_enum(ssl_test_results, OSSL_NELEM(ssl_test_results), | |
109 | &ret_value, value)) { | |
110 | return 0; | |
111 | } | |
112 | test_ctx->expected_result = ret_value; | |
113 | return 1; | |
114 | } | |
115 | ||
a263f320 | 116 | const char *ssl_test_result_name(ssl_test_result_t result) |
453dfd8d EK |
117 | { |
118 | return enum_name(ssl_test_results, OSSL_NELEM(ssl_test_results), result); | |
119 | } | |
120 | ||
cc22cd54 | 121 | /* ExpectedClientAlert / ExpectedServerAlert */ |
453dfd8d EK |
122 | |
123 | static const test_enum ssl_alerts[] = { | |
124 | {"UnknownCA", SSL_AD_UNKNOWN_CA}, | |
a263f320 | 125 | {"HandshakeFailure", SSL_AD_HANDSHAKE_FAILURE}, |
d2b23cd2 | 126 | {"UnrecognizedName", SSL_AD_UNRECOGNIZED_NAME}, |
ce2cdac2 EK |
127 | {"BadCertificate", SSL_AD_BAD_CERTIFICATE}, |
128 | {"NoApplicationProtocol", SSL_AD_NO_APPLICATION_PROTOCOL}, | |
43a0f273 | 129 | {"CertificateRequired", SSL_AD_CERTIFICATE_REQUIRED}, |
453dfd8d EK |
130 | }; |
131 | ||
132 | __owur static int parse_alert(int *alert, const char *value) | |
133 | { | |
134 | return parse_enum(ssl_alerts, OSSL_NELEM(ssl_alerts), alert, value); | |
135 | } | |
136 | ||
137 | __owur static int parse_client_alert(SSL_TEST_CTX *test_ctx, const char *value) | |
138 | { | |
9f48bbac | 139 | return parse_alert(&test_ctx->expected_client_alert, value); |
453dfd8d EK |
140 | } |
141 | ||
142 | __owur static int parse_server_alert(SSL_TEST_CTX *test_ctx, const char *value) | |
143 | { | |
9f48bbac | 144 | return parse_alert(&test_ctx->expected_server_alert, value); |
453dfd8d EK |
145 | } |
146 | ||
147 | const char *ssl_alert_name(int alert) | |
148 | { | |
149 | return enum_name(ssl_alerts, OSSL_NELEM(ssl_alerts), alert); | |
150 | } | |
151 | ||
9f48bbac | 152 | /* ExpectedProtocol */ |
453dfd8d EK |
153 | |
154 | static const test_enum ssl_protocols[] = { | |
582a17d6 | 155 | {"TLSv1.3", TLS1_3_VERSION}, |
453dfd8d EK |
156 | {"TLSv1.2", TLS1_2_VERSION}, |
157 | {"TLSv1.1", TLS1_1_VERSION}, | |
158 | {"TLSv1", TLS1_VERSION}, | |
159 | {"SSLv3", SSL3_VERSION}, | |
74726750 EK |
160 | {"DTLSv1", DTLS1_VERSION}, |
161 | {"DTLSv1.2", DTLS1_2_VERSION}, | |
453dfd8d EK |
162 | }; |
163 | ||
164 | __owur static int parse_protocol(SSL_TEST_CTX *test_ctx, const char *value) | |
165 | { | |
166 | return parse_enum(ssl_protocols, OSSL_NELEM(ssl_protocols), | |
9f48bbac | 167 | &test_ctx->expected_protocol, value); |
453dfd8d EK |
168 | } |
169 | ||
170 | const char *ssl_protocol_name(int protocol) | |
171 | { | |
172 | return enum_name(ssl_protocols, OSSL_NELEM(ssl_protocols), protocol); | |
173 | } | |
174 | ||
cc22cd54 | 175 | /* VerifyCallback */ |
a263f320 EK |
176 | |
177 | static const test_enum ssl_verify_callbacks[] = { | |
178 | {"None", SSL_TEST_VERIFY_NONE}, | |
179 | {"AcceptAll", SSL_TEST_VERIFY_ACCEPT_ALL}, | |
180 | {"RejectAll", SSL_TEST_VERIFY_REJECT_ALL}, | |
181 | }; | |
182 | ||
9f48bbac | 183 | __owur static int parse_client_verify_callback(SSL_TEST_CLIENT_CONF *client_conf, |
da085d27 | 184 | const char *value) |
a263f320 EK |
185 | { |
186 | int ret_value; | |
187 | if (!parse_enum(ssl_verify_callbacks, OSSL_NELEM(ssl_verify_callbacks), | |
188 | &ret_value, value)) { | |
189 | return 0; | |
190 | } | |
9f48bbac | 191 | client_conf->verify_callback = ret_value; |
a263f320 EK |
192 | return 1; |
193 | } | |
194 | ||
195 | const char *ssl_verify_callback_name(ssl_verify_callback_t callback) | |
196 | { | |
197 | return enum_name(ssl_verify_callbacks, OSSL_NELEM(ssl_verify_callbacks), | |
198 | callback); | |
199 | } | |
200 | ||
5c753de6 | 201 | /* ServerName */ |
5c753de6 TS |
202 | |
203 | static const test_enum ssl_servername[] = { | |
81fc33c9 | 204 | {"None", SSL_TEST_SERVERNAME_NONE}, |
5c753de6 TS |
205 | {"server1", SSL_TEST_SERVERNAME_SERVER1}, |
206 | {"server2", SSL_TEST_SERVERNAME_SERVER2}, | |
d2b23cd2 | 207 | {"invalid", SSL_TEST_SERVERNAME_INVALID}, |
5c753de6 TS |
208 | }; |
209 | ||
9f48bbac | 210 | __owur static int parse_servername(SSL_TEST_CLIENT_CONF *client_conf, |
5c753de6 TS |
211 | const char *value) |
212 | { | |
213 | int ret_value; | |
214 | if (!parse_enum(ssl_servername, OSSL_NELEM(ssl_servername), | |
215 | &ret_value, value)) { | |
216 | return 0; | |
217 | } | |
9f48bbac | 218 | client_conf->servername = ret_value; |
5c753de6 TS |
219 | return 1; |
220 | } | |
221 | ||
d2b23cd2 EK |
222 | __owur static int parse_expected_servername(SSL_TEST_CTX *test_ctx, |
223 | const char *value) | |
224 | { | |
225 | int ret_value; | |
226 | if (!parse_enum(ssl_servername, OSSL_NELEM(ssl_servername), | |
227 | &ret_value, value)) { | |
228 | return 0; | |
229 | } | |
230 | test_ctx->expected_servername = ret_value; | |
231 | return 1; | |
232 | } | |
233 | ||
5c753de6 TS |
234 | const char *ssl_servername_name(ssl_servername_t server) |
235 | { | |
236 | return enum_name(ssl_servername, OSSL_NELEM(ssl_servername), | |
237 | server); | |
238 | } | |
239 | ||
9f48bbac | 240 | /* ServerNameCallback */ |
d2b23cd2 EK |
241 | |
242 | static const test_enum ssl_servername_callbacks[] = { | |
243 | {"None", SSL_TEST_SERVERNAME_CB_NONE}, | |
244 | {"IgnoreMismatch", SSL_TEST_SERVERNAME_IGNORE_MISMATCH}, | |
245 | {"RejectMismatch", SSL_TEST_SERVERNAME_REJECT_MISMATCH}, | |
a9c0d8be DB |
246 | {"ClientHelloIgnoreMismatch", |
247 | SSL_TEST_SERVERNAME_CLIENT_HELLO_IGNORE_MISMATCH}, | |
248 | {"ClientHelloRejectMismatch", | |
249 | SSL_TEST_SERVERNAME_CLIENT_HELLO_REJECT_MISMATCH}, | |
250 | {"ClientHelloNoV12", SSL_TEST_SERVERNAME_CLIENT_HELLO_NO_V12}, | |
d2b23cd2 EK |
251 | }; |
252 | ||
9f48bbac EK |
253 | __owur static int parse_servername_callback(SSL_TEST_SERVER_CONF *server_conf, |
254 | const char *value) | |
d2b23cd2 EK |
255 | { |
256 | int ret_value; | |
257 | if (!parse_enum(ssl_servername_callbacks, | |
258 | OSSL_NELEM(ssl_servername_callbacks), &ret_value, value)) { | |
259 | return 0; | |
260 | } | |
9f48bbac | 261 | server_conf->servername_callback = ret_value; |
d2b23cd2 EK |
262 | return 1; |
263 | } | |
264 | ||
265 | const char *ssl_servername_callback_name(ssl_servername_callback_t callback) | |
266 | { | |
267 | return enum_name(ssl_servername_callbacks, | |
268 | OSSL_NELEM(ssl_servername_callbacks), callback); | |
269 | } | |
270 | ||
5c753de6 | 271 | /* SessionTicketExpected */ |
5c753de6 | 272 | |
81fc33c9 | 273 | static const test_enum ssl_session_ticket[] = { |
5c753de6 TS |
274 | {"Ignore", SSL_TEST_SESSION_TICKET_IGNORE}, |
275 | {"Yes", SSL_TEST_SESSION_TICKET_YES}, | |
276 | {"No", SSL_TEST_SESSION_TICKET_NO}, | |
5c753de6 TS |
277 | }; |
278 | ||
81fc33c9 | 279 | __owur static int parse_session_ticket(SSL_TEST_CTX *test_ctx, const char *value) |
5c753de6 TS |
280 | { |
281 | int ret_value; | |
81fc33c9 | 282 | if (!parse_enum(ssl_session_ticket, OSSL_NELEM(ssl_session_ticket), |
5c753de6 TS |
283 | &ret_value, value)) { |
284 | return 0; | |
285 | } | |
286 | test_ctx->session_ticket_expected = ret_value; | |
287 | return 1; | |
288 | } | |
289 | ||
81fc33c9 | 290 | const char *ssl_session_ticket_name(ssl_session_ticket_t server) |
5c753de6 | 291 | { |
81fc33c9 EK |
292 | return enum_name(ssl_session_ticket, |
293 | OSSL_NELEM(ssl_session_ticket), | |
5c753de6 TS |
294 | server); |
295 | } | |
453dfd8d | 296 | |
439db0c9 MC |
297 | /* CompressionExpected */ |
298 | ||
b6611753 | 299 | IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_CTX, test, compression_expected) |
439db0c9 | 300 | |
a84e5c9a TS |
301 | /* SessionIdExpected */ |
302 | ||
303 | static const test_enum ssl_session_id[] = { | |
304 | {"Ignore", SSL_TEST_SESSION_ID_IGNORE}, | |
305 | {"Yes", SSL_TEST_SESSION_ID_YES}, | |
306 | {"No", SSL_TEST_SESSION_ID_NO}, | |
307 | }; | |
308 | ||
309 | __owur static int parse_session_id(SSL_TEST_CTX *test_ctx, const char *value) | |
310 | { | |
311 | int ret_value; | |
312 | if (!parse_enum(ssl_session_id, OSSL_NELEM(ssl_session_id), | |
313 | &ret_value, value)) { | |
314 | return 0; | |
315 | } | |
316 | test_ctx->session_id_expected = ret_value; | |
317 | return 1; | |
318 | } | |
319 | ||
320 | const char *ssl_session_id_name(ssl_session_id_t server) | |
321 | { | |
322 | return enum_name(ssl_session_id, | |
323 | OSSL_NELEM(ssl_session_id), | |
324 | server); | |
325 | } | |
326 | ||
cc22cd54 | 327 | /* Method */ |
74726750 EK |
328 | |
329 | static const test_enum ssl_test_methods[] = { | |
330 | {"TLS", SSL_TEST_METHOD_TLS}, | |
331 | {"DTLS", SSL_TEST_METHOD_DTLS}, | |
332 | }; | |
333 | ||
334 | __owur static int parse_test_method(SSL_TEST_CTX *test_ctx, const char *value) | |
335 | { | |
336 | int ret_value; | |
337 | if (!parse_enum(ssl_test_methods, OSSL_NELEM(ssl_test_methods), | |
338 | &ret_value, value)) { | |
339 | return 0; | |
340 | } | |
341 | test_ctx->method = ret_value; | |
342 | return 1; | |
343 | } | |
344 | ||
345 | const char *ssl_test_method_name(ssl_test_method_t method) | |
346 | { | |
347 | return enum_name(ssl_test_methods, OSSL_NELEM(ssl_test_methods), method); | |
348 | } | |
349 | ||
cc22cd54 | 350 | /* NPN and ALPN options */ |
ce2cdac2 | 351 | |
9f48bbac EK |
352 | IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CLIENT_CONF, client, npn_protocols) |
353 | IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_SERVER_CONF, server, npn_protocols) | |
354 | IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CTX, test, expected_npn_protocol) | |
355 | IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CLIENT_CONF, client, alpn_protocols) | |
356 | IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_SERVER_CONF, server, alpn_protocols) | |
357 | IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CTX, test, expected_alpn_protocol) | |
ce2cdac2 | 358 | |
ea1ecd98 EK |
359 | /* SRP options */ |
360 | IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CLIENT_CONF, client, srp_user) | |
361 | IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_SERVER_CONF, server, srp_user) | |
362 | IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CLIENT_CONF, client, srp_password) | |
363 | IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_SERVER_CONF, server, srp_password) | |
364 | ||
df0fed9a TS |
365 | /* Session Ticket App Data options */ |
366 | IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CTX, test, expected_session_ticket_app_data) | |
367 | IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_SERVER_CONF, server, session_ticket_app_data) | |
368 | ||
cc22cd54 | 369 | /* Handshake mode */ |
590ed3d7 EK |
370 | |
371 | static const test_enum ssl_handshake_modes[] = { | |
372 | {"Simple", SSL_TEST_HANDSHAKE_SIMPLE}, | |
373 | {"Resume", SSL_TEST_HANDSHAKE_RESUME}, | |
fe7dd553 MC |
374 | {"RenegotiateServer", SSL_TEST_HANDSHAKE_RENEG_SERVER}, |
375 | {"RenegotiateClient", SSL_TEST_HANDSHAKE_RENEG_CLIENT}, | |
9b92f161 MC |
376 | {"KeyUpdateServer", SSL_TEST_HANDSHAKE_KEY_UPDATE_SERVER}, |
377 | {"KeyUpdateClient", SSL_TEST_HANDSHAKE_KEY_UPDATE_CLIENT}, | |
9d75dce3 | 378 | {"PostHandshakeAuth", SSL_TEST_HANDSHAKE_POST_HANDSHAKE_AUTH}, |
590ed3d7 EK |
379 | }; |
380 | ||
381 | __owur static int parse_handshake_mode(SSL_TEST_CTX *test_ctx, const char *value) | |
382 | { | |
383 | int ret_value; | |
384 | if (!parse_enum(ssl_handshake_modes, OSSL_NELEM(ssl_handshake_modes), | |
385 | &ret_value, value)) { | |
386 | return 0; | |
387 | } | |
388 | test_ctx->handshake_mode = ret_value; | |
389 | return 1; | |
390 | } | |
391 | ||
392 | const char *ssl_handshake_mode_name(ssl_handshake_mode_t mode) | |
393 | { | |
394 | return enum_name(ssl_handshake_modes, OSSL_NELEM(ssl_handshake_modes), | |
395 | mode); | |
396 | } | |
397 | ||
cc22cd54 MC |
398 | /* Renegotiation Ciphersuites */ |
399 | ||
400 | IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CLIENT_CONF, client, reneg_ciphers) | |
401 | ||
9b92f161 MC |
402 | /* KeyUpdateType */ |
403 | ||
404 | static const test_enum ssl_key_update_types[] = { | |
405 | {"KeyUpdateRequested", SSL_KEY_UPDATE_REQUESTED}, | |
406 | {"KeyUpdateNotRequested", SSL_KEY_UPDATE_NOT_REQUESTED}, | |
407 | }; | |
408 | ||
409 | __owur static int parse_key_update_type(SSL_TEST_CTX *test_ctx, const char *value) | |
410 | { | |
411 | int ret_value; | |
412 | if (!parse_enum(ssl_key_update_types, OSSL_NELEM(ssl_key_update_types), | |
413 | &ret_value, value)) { | |
414 | return 0; | |
415 | } | |
416 | test_ctx->key_update_type = ret_value; | |
417 | return 1; | |
418 | } | |
419 | ||
cc22cd54 | 420 | /* CT Validation */ |
da085d27 EK |
421 | |
422 | static const test_enum ssl_ct_validation_modes[] = { | |
423 | {"None", SSL_TEST_CT_VALIDATION_NONE}, | |
424 | {"Permissive", SSL_TEST_CT_VALIDATION_PERMISSIVE}, | |
425 | {"Strict", SSL_TEST_CT_VALIDATION_STRICT}, | |
426 | }; | |
427 | ||
428 | __owur static int parse_ct_validation(SSL_TEST_CLIENT_CONF *client_conf, | |
429 | const char *value) | |
430 | { | |
431 | int ret_value; | |
432 | if (!parse_enum(ssl_ct_validation_modes, OSSL_NELEM(ssl_ct_validation_modes), | |
433 | &ret_value, value)) { | |
434 | return 0; | |
435 | } | |
436 | client_conf->ct_validation = ret_value; | |
437 | return 1; | |
438 | } | |
439 | ||
440 | const char *ssl_ct_validation_name(ssl_ct_validation_t mode) | |
441 | { | |
442 | return enum_name(ssl_ct_validation_modes, OSSL_NELEM(ssl_ct_validation_modes), | |
443 | mode); | |
444 | } | |
445 | ||
9f48bbac EK |
446 | IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_CTX, test, resumption_expected) |
447 | IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_SERVER_CONF, server, broken_session_ticket) | |
83964ca0 | 448 | IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_CTX, test, use_sctp) |
243ff51c MT |
449 | IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_CTX, test, enable_client_sctp_label_bug) |
450 | IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_CTX, test, enable_server_sctp_label_bug) | |
590ed3d7 | 451 | |
767ccc3b | 452 | /* CertStatus */ |
767ccc3b MC |
453 | |
454 | static const test_enum ssl_certstatus[] = { | |
455 | {"None", SSL_TEST_CERT_STATUS_NONE}, | |
456 | {"GoodResponse", SSL_TEST_CERT_STATUS_GOOD_RESPONSE}, | |
457 | {"BadResponse", SSL_TEST_CERT_STATUS_BAD_RESPONSE} | |
458 | }; | |
459 | ||
460 | __owur static int parse_certstatus(SSL_TEST_SERVER_CONF *server_conf, | |
461 | const char *value) | |
462 | { | |
463 | int ret_value; | |
464 | if (!parse_enum(ssl_certstatus, OSSL_NELEM(ssl_certstatus), &ret_value, | |
465 | value)) { | |
466 | return 0; | |
467 | } | |
468 | server_conf->cert_status = ret_value; | |
469 | return 1; | |
470 | } | |
471 | ||
472 | const char *ssl_certstatus_name(ssl_cert_status_t cert_status) | |
473 | { | |
474 | return enum_name(ssl_certstatus, | |
475 | OSSL_NELEM(ssl_certstatus), cert_status); | |
476 | } | |
477 | ||
cc22cd54 | 478 | /* ApplicationData */ |
e0421bd8 EK |
479 | |
480 | IMPLEMENT_SSL_TEST_INT_OPTION(SSL_TEST_CTX, test, app_data_size) | |
481 | ||
cc22cd54 MC |
482 | |
483 | /* MaxFragmentSize */ | |
6dc99745 EK |
484 | |
485 | IMPLEMENT_SSL_TEST_INT_OPTION(SSL_TEST_CTX, test, max_fragment_size) | |
486 | ||
cf72c757 F |
487 | /* Maximum-Fragment-Length TLS extension mode */ |
488 | static const test_enum ssl_max_fragment_len_mode[] = { | |
489 | {"None", TLSEXT_max_fragment_length_DISABLED}, | |
490 | { "512", TLSEXT_max_fragment_length_512}, | |
491 | {"1024", TLSEXT_max_fragment_length_1024}, | |
492 | {"2048", TLSEXT_max_fragment_length_2048}, | |
493 | {"4096", TLSEXT_max_fragment_length_4096} | |
494 | }; | |
495 | ||
496 | __owur static int parse_max_fragment_len_mode(SSL_TEST_CLIENT_CONF *client_conf, | |
497 | const char *value) | |
498 | { | |
499 | int ret_value; | |
500 | ||
501 | if (!parse_enum(ssl_max_fragment_len_mode, | |
502 | OSSL_NELEM(ssl_max_fragment_len_mode), &ret_value, value)) { | |
503 | return 0; | |
504 | } | |
505 | client_conf->max_fragment_len_mode = ret_value; | |
506 | return 1; | |
507 | } | |
508 | ||
509 | const char *ssl_max_fragment_len_name(int MFL_mode) | |
510 | { | |
511 | return enum_name(ssl_max_fragment_len_mode, | |
512 | OSSL_NELEM(ssl_max_fragment_len_mode), MFL_mode); | |
513 | } | |
514 | ||
cc22cd54 MC |
515 | |
516 | /* Expected key and signature types */ | |
b93ad05d | 517 | |
7f5f35af | 518 | __owur static int parse_expected_key_type(int *ptype, const char *value) |
b93ad05d DSH |
519 | { |
520 | int nid; | |
7f5f35af | 521 | const EVP_PKEY_ASN1_METHOD *ameth; |
b93ad05d DSH |
522 | |
523 | if (value == NULL) | |
524 | return 0; | |
7f5f35af DSH |
525 | ameth = EVP_PKEY_asn1_find_str(NULL, value, -1); |
526 | if (ameth != NULL) | |
527 | EVP_PKEY_asn1_get0_info(&nid, NULL, NULL, NULL, NULL, ameth); | |
528 | else | |
529 | nid = OBJ_sn2nid(value); | |
b93ad05d DSH |
530 | if (nid == NID_undef) |
531 | nid = OBJ_ln2nid(value); | |
532 | #ifndef OPENSSL_NO_EC | |
533 | if (nid == NID_undef) | |
534 | nid = EC_curve_nist2nid(value); | |
535 | #endif | |
536 | if (nid == NID_undef) | |
537 | return 0; | |
7f5f35af | 538 | *ptype = nid; |
b93ad05d DSH |
539 | return 1; |
540 | } | |
541 | ||
7f5f35af DSH |
542 | __owur static int parse_expected_tmp_key_type(SSL_TEST_CTX *test_ctx, |
543 | const char *value) | |
544 | { | |
545 | return parse_expected_key_type(&test_ctx->expected_tmp_key_type, value); | |
546 | } | |
547 | ||
548 | __owur static int parse_expected_server_cert_type(SSL_TEST_CTX *test_ctx, | |
549 | const char *value) | |
550 | { | |
551 | return parse_expected_key_type(&test_ctx->expected_server_cert_type, | |
552 | value); | |
553 | } | |
554 | ||
54b7f2a5 DSH |
555 | __owur static int parse_expected_server_sign_type(SSL_TEST_CTX *test_ctx, |
556 | const char *value) | |
557 | { | |
558 | return parse_expected_key_type(&test_ctx->expected_server_sign_type, | |
559 | value); | |
560 | } | |
561 | ||
7f5f35af DSH |
562 | __owur static int parse_expected_client_cert_type(SSL_TEST_CTX *test_ctx, |
563 | const char *value) | |
564 | { | |
565 | return parse_expected_key_type(&test_ctx->expected_client_cert_type, | |
566 | value); | |
567 | } | |
568 | ||
54b7f2a5 DSH |
569 | __owur static int parse_expected_client_sign_type(SSL_TEST_CTX *test_ctx, |
570 | const char *value) | |
571 | { | |
572 | return parse_expected_key_type(&test_ctx->expected_client_sign_type, | |
573 | value); | |
574 | } | |
575 | ||
cc22cd54 | 576 | |
ee5b6a42 | 577 | /* Expected signing hash */ |
ee5b6a42 DSH |
578 | |
579 | __owur static int parse_expected_sign_hash(int *ptype, const char *value) | |
580 | { | |
581 | int nid; | |
582 | ||
583 | if (value == NULL) | |
584 | return 0; | |
585 | nid = OBJ_sn2nid(value); | |
586 | if (nid == NID_undef) | |
587 | nid = OBJ_ln2nid(value); | |
588 | if (nid == NID_undef) | |
589 | return 0; | |
590 | *ptype = nid; | |
591 | return 1; | |
592 | } | |
593 | ||
594 | __owur static int parse_expected_server_sign_hash(SSL_TEST_CTX *test_ctx, | |
595 | const char *value) | |
596 | { | |
597 | return parse_expected_sign_hash(&test_ctx->expected_server_sign_hash, | |
598 | value); | |
599 | } | |
600 | ||
601 | __owur static int parse_expected_client_sign_hash(SSL_TEST_CTX *test_ctx, | |
602 | const char *value) | |
603 | { | |
4bb0b438 | 604 | return parse_expected_sign_hash(&test_ctx->expected_client_sign_hash, |
ee5b6a42 DSH |
605 | value); |
606 | } | |
607 | ||
2e21539b DSH |
608 | __owur static int parse_expected_ca_names(STACK_OF(X509_NAME) **pnames, |
609 | const char *value) | |
610 | { | |
611 | if (value == NULL) | |
612 | return 0; | |
613 | if (!strcmp(value, "empty")) | |
614 | *pnames = sk_X509_NAME_new_null(); | |
615 | else | |
616 | *pnames = SSL_load_client_CA_file(value); | |
617 | return *pnames != NULL; | |
618 | } | |
f15b50c4 DSH |
619 | __owur static int parse_expected_server_ca_names(SSL_TEST_CTX *test_ctx, |
620 | const char *value) | |
621 | { | |
622 | return parse_expected_ca_names(&test_ctx->expected_server_ca_names, value); | |
623 | } | |
2e21539b DSH |
624 | __owur static int parse_expected_client_ca_names(SSL_TEST_CTX *test_ctx, |
625 | const char *value) | |
626 | { | |
627 | return parse_expected_ca_names(&test_ctx->expected_client_ca_names, value); | |
628 | } | |
cc22cd54 | 629 | |
e1c7871d TS |
630 | /* ExpectedCipher */ |
631 | ||
632 | IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CTX, test, expected_cipher) | |
633 | ||
32097b33 | 634 | /* Client and Server PHA */ |
9d75dce3 | 635 | |
32097b33 | 636 | IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_CLIENT_CONF, client, enable_pha) |
9d75dce3 TS |
637 | IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_SERVER_CONF, server, force_pha) |
638 | ||
453dfd8d | 639 | /* Known test options and their corresponding parse methods. */ |
453dfd8d | 640 | |
9f48bbac | 641 | /* Top-level options. */ |
453dfd8d EK |
642 | typedef struct { |
643 | const char *name; | |
644 | int (*parse)(SSL_TEST_CTX *test_ctx, const char *value); | |
645 | } ssl_test_ctx_option; | |
646 | ||
647 | static const ssl_test_ctx_option ssl_test_ctx_options[] = { | |
648 | { "ExpectedResult", &parse_expected_result }, | |
9f48bbac EK |
649 | { "ExpectedClientAlert", &parse_client_alert }, |
650 | { "ExpectedServerAlert", &parse_server_alert }, | |
651 | { "ExpectedProtocol", &parse_protocol }, | |
d2b23cd2 | 652 | { "ExpectedServerName", &parse_expected_servername }, |
81fc33c9 | 653 | { "SessionTicketExpected", &parse_session_ticket }, |
b6611753 | 654 | { "CompressionExpected", &parse_test_compression_expected }, |
a84e5c9a | 655 | { "SessionIdExpected", &parse_session_id }, |
74726750 | 656 | { "Method", &parse_test_method }, |
9f48bbac EK |
657 | { "ExpectedNPNProtocol", &parse_test_expected_npn_protocol }, |
658 | { "ExpectedALPNProtocol", &parse_test_expected_alpn_protocol }, | |
590ed3d7 | 659 | { "HandshakeMode", &parse_handshake_mode }, |
9b92f161 | 660 | { "KeyUpdateType", &parse_key_update_type }, |
9f48bbac | 661 | { "ResumptionExpected", &parse_test_resumption_expected }, |
e0421bd8 | 662 | { "ApplicationData", &parse_test_app_data_size }, |
6dc99745 | 663 | { "MaxFragmentSize", &parse_test_max_fragment_size }, |
b93ad05d | 664 | { "ExpectedTmpKeyType", &parse_expected_tmp_key_type }, |
7f5f35af | 665 | { "ExpectedServerCertType", &parse_expected_server_cert_type }, |
ee5b6a42 | 666 | { "ExpectedServerSignHash", &parse_expected_server_sign_hash }, |
54b7f2a5 | 667 | { "ExpectedServerSignType", &parse_expected_server_sign_type }, |
f15b50c4 | 668 | { "ExpectedServerCANames", &parse_expected_server_ca_names }, |
7f5f35af | 669 | { "ExpectedClientCertType", &parse_expected_client_cert_type }, |
ee5b6a42 | 670 | { "ExpectedClientSignHash", &parse_expected_client_sign_hash }, |
54b7f2a5 | 671 | { "ExpectedClientSignType", &parse_expected_client_sign_type }, |
2e21539b | 672 | { "ExpectedClientCANames", &parse_expected_client_ca_names }, |
83964ca0 | 673 | { "UseSCTP", &parse_test_use_sctp }, |
243ff51c MT |
674 | { "EnableClientSCTPLabelBug", &parse_test_enable_client_sctp_label_bug }, |
675 | { "EnableServerSCTPLabelBug", &parse_test_enable_server_sctp_label_bug }, | |
e1c7871d | 676 | { "ExpectedCipher", &parse_test_expected_cipher }, |
df0fed9a | 677 | { "ExpectedSessionTicketAppData", &parse_test_expected_session_ticket_app_data }, |
9f48bbac EK |
678 | }; |
679 | ||
680 | /* Nested client options. */ | |
681 | typedef struct { | |
682 | const char *name; | |
683 | int (*parse)(SSL_TEST_CLIENT_CONF *conf, const char *value); | |
684 | } ssl_test_client_option; | |
685 | ||
686 | static const ssl_test_client_option ssl_test_client_options[] = { | |
687 | { "VerifyCallback", &parse_client_verify_callback }, | |
688 | { "ServerName", &parse_servername }, | |
689 | { "NPNProtocols", &parse_client_npn_protocols }, | |
690 | { "ALPNProtocols", &parse_client_alpn_protocols }, | |
da085d27 | 691 | { "CTValidation", &parse_ct_validation }, |
cc22cd54 | 692 | { "RenegotiateCiphers", &parse_client_reneg_ciphers}, |
ea1ecd98 EK |
693 | { "SRPUser", &parse_client_srp_user }, |
694 | { "SRPPassword", &parse_client_srp_password }, | |
cf72c757 | 695 | { "MaxFragmentLenExt", &parse_max_fragment_len_mode }, |
32097b33 | 696 | { "EnablePHA", &parse_client_enable_pha }, |
9f48bbac EK |
697 | }; |
698 | ||
699 | /* Nested server options. */ | |
700 | typedef struct { | |
701 | const char *name; | |
702 | int (*parse)(SSL_TEST_SERVER_CONF *conf, const char *value); | |
703 | } ssl_test_server_option; | |
704 | ||
705 | static const ssl_test_server_option ssl_test_server_options[] = { | |
706 | { "ServerNameCallback", &parse_servername_callback }, | |
707 | { "NPNProtocols", &parse_server_npn_protocols }, | |
708 | { "ALPNProtocols", &parse_server_alpn_protocols }, | |
709 | { "BrokenSessionTicket", &parse_server_broken_session_ticket }, | |
767ccc3b | 710 | { "CertStatus", &parse_certstatus }, |
ea1ecd98 EK |
711 | { "SRPUser", &parse_server_srp_user }, |
712 | { "SRPPassword", &parse_server_srp_password }, | |
9d75dce3 | 713 | { "ForcePHA", &parse_server_force_pha }, |
df0fed9a | 714 | { "SessionTicketAppData", &parse_server_session_ticket_app_data }, |
453dfd8d EK |
715 | }; |
716 | ||
3cb7c5cf | 717 | SSL_TEST_CTX *SSL_TEST_CTX_new(void) |
453dfd8d EK |
718 | { |
719 | SSL_TEST_CTX *ret; | |
019e47ce P |
720 | |
721 | /* The return code is checked by caller */ | |
722 | if ((ret = OPENSSL_zalloc(sizeof(*ret))) != NULL) { | |
723 | ret->app_data_size = default_app_data_size; | |
724 | ret->max_fragment_size = default_max_fragment_size; | |
725 | } | |
453dfd8d EK |
726 | return ret; |
727 | } | |
728 | ||
9f48bbac EK |
729 | static void ssl_test_extra_conf_free_data(SSL_TEST_EXTRA_CONF *conf) |
730 | { | |
731 | OPENSSL_free(conf->client.npn_protocols); | |
732 | OPENSSL_free(conf->server.npn_protocols); | |
733 | OPENSSL_free(conf->server2.npn_protocols); | |
734 | OPENSSL_free(conf->client.alpn_protocols); | |
735 | OPENSSL_free(conf->server.alpn_protocols); | |
736 | OPENSSL_free(conf->server2.alpn_protocols); | |
d605fc3a | 737 | OPENSSL_free(conf->client.reneg_ciphers); |
ea1ecd98 EK |
738 | OPENSSL_free(conf->server.srp_user); |
739 | OPENSSL_free(conf->server.srp_password); | |
740 | OPENSSL_free(conf->server2.srp_user); | |
741 | OPENSSL_free(conf->server2.srp_password); | |
742 | OPENSSL_free(conf->client.srp_user); | |
743 | OPENSSL_free(conf->client.srp_password); | |
df0fed9a TS |
744 | OPENSSL_free(conf->server.session_ticket_app_data); |
745 | OPENSSL_free(conf->server2.session_ticket_app_data); | |
9f48bbac EK |
746 | } |
747 | ||
748 | static void ssl_test_ctx_free_extra_data(SSL_TEST_CTX *ctx) | |
453dfd8d | 749 | { |
9f48bbac EK |
750 | ssl_test_extra_conf_free_data(&ctx->extra); |
751 | ssl_test_extra_conf_free_data(&ctx->resume_extra); | |
752 | } | |
ce2cdac2 | 753 | |
9f48bbac EK |
754 | void SSL_TEST_CTX_free(SSL_TEST_CTX *ctx) |
755 | { | |
756 | ssl_test_ctx_free_extra_data(ctx); | |
ce2cdac2 EK |
757 | OPENSSL_free(ctx->expected_npn_protocol); |
758 | OPENSSL_free(ctx->expected_alpn_protocol); | |
df0fed9a | 759 | OPENSSL_free(ctx->expected_session_ticket_app_data); |
f15b50c4 | 760 | sk_X509_NAME_pop_free(ctx->expected_server_ca_names, X509_NAME_free); |
2e21539b | 761 | sk_X509_NAME_pop_free(ctx->expected_client_ca_names, X509_NAME_free); |
e1c7871d | 762 | OPENSSL_free(ctx->expected_cipher); |
453dfd8d EK |
763 | OPENSSL_free(ctx); |
764 | } | |
765 | ||
9f48bbac EK |
766 | static int parse_client_options(SSL_TEST_CLIENT_CONF *client, const CONF *conf, |
767 | const char *client_section) | |
453dfd8d EK |
768 | { |
769 | STACK_OF(CONF_VALUE) *sk_conf; | |
453dfd8d EK |
770 | int i; |
771 | size_t j; | |
772 | ||
019e47ce P |
773 | if (!TEST_ptr(sk_conf = NCONF_get_section(conf, client_section))) |
774 | return 0; | |
453dfd8d | 775 | |
9f48bbac EK |
776 | for (i = 0; i < sk_CONF_VALUE_num(sk_conf); i++) { |
777 | int found = 0; | |
778 | const CONF_VALUE *option = sk_CONF_VALUE_value(sk_conf, i); | |
779 | for (j = 0; j < OSSL_NELEM(ssl_test_client_options); j++) { | |
780 | if (strcmp(option->name, ssl_test_client_options[j].name) == 0) { | |
781 | if (!ssl_test_client_options[j].parse(client, option->value)) { | |
8fe3127c P |
782 | TEST_info("Bad value %s for option %s", |
783 | option->value, option->name); | |
9f48bbac EK |
784 | return 0; |
785 | } | |
786 | found = 1; | |
787 | break; | |
788 | } | |
789 | } | |
790 | if (!found) { | |
8fe3127c | 791 | TEST_info("Unknown test option: %s", option->name); |
9f48bbac EK |
792 | return 0; |
793 | } | |
794 | } | |
795 | ||
796 | return 1; | |
797 | } | |
798 | ||
799 | static int parse_server_options(SSL_TEST_SERVER_CONF *server, const CONF *conf, | |
800 | const char *server_section) | |
801 | { | |
802 | STACK_OF(CONF_VALUE) *sk_conf; | |
803 | int i; | |
804 | size_t j; | |
805 | ||
019e47ce P |
806 | if (!TEST_ptr(sk_conf = NCONF_get_section(conf, server_section))) |
807 | return 0; | |
453dfd8d EK |
808 | |
809 | for (i = 0; i < sk_CONF_VALUE_num(sk_conf); i++) { | |
810 | int found = 0; | |
811 | const CONF_VALUE *option = sk_CONF_VALUE_value(sk_conf, i); | |
9f48bbac EK |
812 | for (j = 0; j < OSSL_NELEM(ssl_test_server_options); j++) { |
813 | if (strcmp(option->name, ssl_test_server_options[j].name) == 0) { | |
814 | if (!ssl_test_server_options[j].parse(server, option->value)) { | |
8fe3127c P |
815 | TEST_info("Bad value %s for option %s", |
816 | option->value, option->name); | |
9f48bbac | 817 | return 0; |
453dfd8d EK |
818 | } |
819 | found = 1; | |
820 | break; | |
821 | } | |
822 | } | |
823 | if (!found) { | |
8fe3127c | 824 | TEST_info("Unknown test option: %s", option->name); |
9f48bbac EK |
825 | return 0; |
826 | } | |
827 | } | |
828 | ||
829 | return 1; | |
830 | } | |
831 | ||
832 | SSL_TEST_CTX *SSL_TEST_CTX_create(const CONF *conf, const char *test_section) | |
833 | { | |
019e47ce P |
834 | STACK_OF(CONF_VALUE) *sk_conf = NULL; |
835 | SSL_TEST_CTX *ctx = NULL; | |
9f48bbac EK |
836 | int i; |
837 | size_t j; | |
838 | ||
019e47ce P |
839 | if (!TEST_ptr(sk_conf = NCONF_get_section(conf, test_section)) |
840 | || !TEST_ptr(ctx = SSL_TEST_CTX_new())) | |
841 | goto err; | |
9f48bbac EK |
842 | |
843 | for (i = 0; i < sk_CONF_VALUE_num(sk_conf); i++) { | |
844 | int found = 0; | |
845 | const CONF_VALUE *option = sk_CONF_VALUE_value(sk_conf, i); | |
846 | ||
847 | /* Subsections */ | |
848 | if (strcmp(option->name, "client") == 0) { | |
045fe731 | 849 | if (!parse_client_options(&ctx->extra.client, conf, option->value)) |
9f48bbac EK |
850 | goto err; |
851 | } else if (strcmp(option->name, "server") == 0) { | |
045fe731 | 852 | if (!parse_server_options(&ctx->extra.server, conf, option->value)) |
9f48bbac EK |
853 | goto err; |
854 | } else if (strcmp(option->name, "server2") == 0) { | |
045fe731 | 855 | if (!parse_server_options(&ctx->extra.server2, conf, option->value)) |
9f48bbac EK |
856 | goto err; |
857 | } else if (strcmp(option->name, "resume-client") == 0) { | |
045fe731 P |
858 | if (!parse_client_options(&ctx->resume_extra.client, conf, |
859 | option->value)) | |
9f48bbac EK |
860 | goto err; |
861 | } else if (strcmp(option->name, "resume-server") == 0) { | |
045fe731 P |
862 | if (!parse_server_options(&ctx->resume_extra.server, conf, |
863 | option->value)) | |
9f48bbac EK |
864 | goto err; |
865 | } else if (strcmp(option->name, "resume-server2") == 0) { | |
866 | if (!parse_server_options(&ctx->resume_extra.server2, conf, | |
867 | option->value)) | |
868 | goto err; | |
9f48bbac EK |
869 | } else { |
870 | for (j = 0; j < OSSL_NELEM(ssl_test_ctx_options); j++) { | |
871 | if (strcmp(option->name, ssl_test_ctx_options[j].name) == 0) { | |
872 | if (!ssl_test_ctx_options[j].parse(ctx, option->value)) { | |
8fe3127c P |
873 | TEST_info("Bad value %s for option %s", |
874 | option->value, option->name); | |
9f48bbac EK |
875 | goto err; |
876 | } | |
877 | found = 1; | |
878 | break; | |
879 | } | |
880 | } | |
881 | if (!found) { | |
8fe3127c | 882 | TEST_info("Unknown test option: %s", option->name); |
9f48bbac EK |
883 | goto err; |
884 | } | |
453dfd8d EK |
885 | } |
886 | } | |
887 | ||
888 | goto done; | |
889 | ||
890 | err: | |
891 | SSL_TEST_CTX_free(ctx); | |
892 | ctx = NULL; | |
893 | done: | |
894 | return ctx; | |
895 | } |