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