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