ssl_test_ctx_test.c revision 1.1.1.1
1/*
2 * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License").  You may not use
5 * this file except in compliance with the License.  You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10/*
11 * Ideally, CONF should offer standard parsing methods and cover them
12 * in tests. But since we have no CONF tests, we use a custom test for now.
13 */
14
15#include <stdio.h>
16#include <string.h>
17
18#include "e_os.h"
19#include "ssl_test_ctx.h"
20#include "testutil.h"
21#include <openssl/e_os2.h>
22#include <openssl/err.h>
23#include <openssl/conf.h>
24#include <openssl/ssl.h>
25
26static CONF *conf = NULL;
27
28typedef struct ssl_test_ctx_test_fixture {
29    const char *test_case_name;
30    const char *test_section;
31    /* Expected parsed configuration. */
32    SSL_TEST_CTX *expected_ctx;
33} SSL_TEST_CTX_TEST_FIXTURE;
34
35
36static int SSL_TEST_CLIENT_CONF_equal(SSL_TEST_CLIENT_CONF *client,
37                                      SSL_TEST_CLIENT_CONF *client2)
38{
39    if (client->verify_callback != client2->verify_callback) {
40        fprintf(stderr, "ClientVerifyCallback mismatch: %s vs %s.\n",
41                ssl_verify_callback_name(client->verify_callback),
42                ssl_verify_callback_name(client2->verify_callback));
43        return 0;
44    }
45    if (client->servername != client2->servername) {
46        fprintf(stderr, "ServerName mismatch: %s vs %s.\n",
47                ssl_servername_name(client->servername),
48                ssl_servername_name(client2->servername));
49        return 0;
50    }
51    if (!strings_equal("Client NPNProtocols", client->npn_protocols,
52                       client2->npn_protocols))
53        return 0;
54    if (!strings_equal("Client ALPNProtocols", client->alpn_protocols,
55                       client2->alpn_protocols))
56        return 0;
57    if (client->ct_validation != client2->ct_validation) {
58        fprintf(stderr, "CTValidation mismatch: %s vs %s.\n",
59                ssl_ct_validation_name(client->ct_validation),
60                ssl_ct_validation_name(client2->ct_validation));
61        return 0;
62    }
63    return 1;
64}
65
66static int SSL_TEST_SERVER_CONF_equal(SSL_TEST_SERVER_CONF *server,
67                                      SSL_TEST_SERVER_CONF *server2)
68{
69    if (server->servername_callback != server2->servername_callback) {
70        fprintf(stderr, "ServerNameCallback mismatch: %s vs %s.\n",
71                ssl_servername_callback_name(server->servername_callback),
72                ssl_servername_callback_name(server2->servername_callback));
73        return 0;
74    }
75    if (!strings_equal("Server NPNProtocols", server->npn_protocols,
76                       server2->npn_protocols))
77        return 0;
78    if (!strings_equal("Server ALPNProtocols", server->alpn_protocols,
79                       server2->alpn_protocols))
80        return 0;
81    if (server->broken_session_ticket != server2->broken_session_ticket) {
82        fprintf(stderr, "Broken session ticket mismatch: %d vs %d.\n",
83                server->broken_session_ticket, server2->broken_session_ticket);
84        return 0;
85    }
86    if (server->cert_status != server2->cert_status) {
87        fprintf(stderr, "CertStatus mismatch: %s vs %s.\n",
88                ssl_certstatus_name(server->cert_status),
89                ssl_certstatus_name(server2->cert_status));
90        return 0;
91    }
92    return 1;
93}
94
95static int SSL_TEST_EXTRA_CONF_equal(SSL_TEST_EXTRA_CONF *extra,
96                                     SSL_TEST_EXTRA_CONF *extra2)
97{
98    return SSL_TEST_CLIENT_CONF_equal(&extra->client, &extra2->client)
99        && SSL_TEST_SERVER_CONF_equal(&extra->server, &extra2->server)
100        && SSL_TEST_SERVER_CONF_equal(&extra->server2, &extra2->server2);
101}
102
103/* Returns 1 if the contexts are equal, 0 otherwise. */
104static int SSL_TEST_CTX_equal(SSL_TEST_CTX *ctx, SSL_TEST_CTX *ctx2)
105{
106    if (ctx->method != ctx2->method) {
107        fprintf(stderr, "Method mismatch: %s vs %s.\n",
108                ssl_test_method_name(ctx->method),
109                ssl_test_method_name(ctx2->method));
110        return 0;
111    }
112    if (ctx->handshake_mode != ctx2->handshake_mode) {
113        fprintf(stderr, "HandshakeMode mismatch: %s vs %s.\n",
114                ssl_handshake_mode_name(ctx->handshake_mode),
115                ssl_handshake_mode_name(ctx2->handshake_mode));
116        return 0;
117    }
118    if (ctx->app_data_size != ctx2->app_data_size) {
119        fprintf(stderr, "ApplicationData mismatch: %d vs %d.\n",
120                ctx->app_data_size, ctx2->app_data_size);
121        return 0;
122    }
123
124    if (ctx->max_fragment_size != ctx2->max_fragment_size) {
125        fprintf(stderr, "MaxFragmentSize mismatch: %d vs %d.\n",
126                ctx->max_fragment_size, ctx2->max_fragment_size);
127        return 0;
128    }
129
130    if (!SSL_TEST_EXTRA_CONF_equal(&ctx->extra, &ctx2->extra)) {
131        fprintf(stderr, "Extra conf mismatch.\n");
132        return 0;
133    }
134    if (!SSL_TEST_EXTRA_CONF_equal(&ctx->resume_extra, &ctx2->resume_extra)) {
135        fprintf(stderr, "Resume extra conf mismatch.\n");
136        return 0;
137    }
138
139    if (ctx->expected_result != ctx2->expected_result) {
140        fprintf(stderr, "ExpectedResult mismatch: %s vs %s.\n",
141                ssl_test_result_name(ctx->expected_result),
142                ssl_test_result_name(ctx2->expected_result));
143        return 0;
144    }
145    if (ctx->expected_client_alert != ctx2->expected_client_alert) {
146        fprintf(stderr, "ClientAlert mismatch: %s vs %s.\n",
147                ssl_alert_name(ctx->expected_client_alert),
148                ssl_alert_name(ctx2->expected_client_alert));
149        return 0;
150    }
151    if (ctx->expected_server_alert != ctx2->expected_server_alert) {
152        fprintf(stderr, "ServerAlert mismatch: %s vs %s.\n",
153                ssl_alert_name(ctx->expected_server_alert),
154                ssl_alert_name(ctx2->expected_server_alert));
155        return 0;
156    }
157    if (ctx->expected_protocol != ctx2->expected_protocol) {
158        fprintf(stderr, "ClientAlert mismatch: %s vs %s.\n",
159                ssl_protocol_name(ctx->expected_protocol),
160                ssl_protocol_name(ctx2->expected_protocol));
161        return 0;
162    }
163    if (ctx->expected_servername != ctx2->expected_servername) {
164        fprintf(stderr, "ExpectedServerName mismatch: %s vs %s.\n",
165                ssl_servername_name(ctx->expected_servername),
166                ssl_servername_name(ctx2->expected_servername));
167        return 0;
168    }
169    if (ctx->session_ticket_expected != ctx2->session_ticket_expected) {
170        fprintf(stderr, "SessionTicketExpected mismatch: %s vs %s.\n",
171                ssl_session_ticket_name(ctx->session_ticket_expected),
172                ssl_session_ticket_name(ctx2->session_ticket_expected));
173        return 0;
174    }
175    if (!strings_equal("ExpectedNPNProtocol", ctx->expected_npn_protocol,
176                       ctx2->expected_npn_protocol))
177        return 0;
178    if (!strings_equal("ExpectedALPNProtocol", ctx->expected_alpn_protocol,
179                       ctx2->expected_alpn_protocol))
180        return 0;
181    if (ctx->resumption_expected != ctx2->resumption_expected) {
182        fprintf(stderr, "ResumptionExpected mismatch: %d vs %d.\n",
183                ctx->resumption_expected, ctx2->resumption_expected);
184        return 0;
185    }
186    return 1;
187}
188
189static SSL_TEST_CTX_TEST_FIXTURE set_up(const char *const test_case_name)
190{
191    SSL_TEST_CTX_TEST_FIXTURE fixture;
192    fixture.test_case_name = test_case_name;
193    fixture.expected_ctx = SSL_TEST_CTX_new();
194    TEST_check(fixture.expected_ctx != NULL);
195    return fixture;
196}
197
198static int execute_test(SSL_TEST_CTX_TEST_FIXTURE fixture)
199{
200    int success = 0;
201
202    SSL_TEST_CTX *ctx = SSL_TEST_CTX_create(conf, fixture.test_section);
203
204    if (ctx == NULL) {
205        fprintf(stderr, "Failed to parse good configuration %s.\n",
206                fixture.test_section);
207        goto err;
208    }
209
210    if (!SSL_TEST_CTX_equal(ctx, fixture.expected_ctx))
211        goto err;
212
213    success = 1;
214 err:
215    SSL_TEST_CTX_free(ctx);
216    return success;
217}
218
219static int execute_failure_test(SSL_TEST_CTX_TEST_FIXTURE fixture)
220{
221    SSL_TEST_CTX *ctx = SSL_TEST_CTX_create(conf, fixture.test_section);
222
223    if (ctx != NULL) {
224        fprintf(stderr, "Parsing bad configuration %s succeeded.\n",
225                fixture.test_section);
226        SSL_TEST_CTX_free(ctx);
227        return 0;
228    }
229
230    return 1;
231}
232
233static void tear_down(SSL_TEST_CTX_TEST_FIXTURE fixture)
234{
235    SSL_TEST_CTX_free(fixture.expected_ctx);
236    ERR_print_errors_fp(stderr);
237}
238
239#define SETUP_SSL_TEST_CTX_TEST_FIXTURE()                       \
240    SETUP_TEST_FIXTURE(SSL_TEST_CTX_TEST_FIXTURE, set_up)
241#define EXECUTE_SSL_TEST_CTX_TEST()             \
242    EXECUTE_TEST(execute_test, tear_down)
243#define EXECUTE_SSL_TEST_CTX_FAILURE_TEST()             \
244    EXECUTE_TEST(execute_failure_test, tear_down)
245
246static int test_empty_configuration()
247{
248    SETUP_SSL_TEST_CTX_TEST_FIXTURE();
249    fixture.test_section = "ssltest_default";
250    fixture.expected_ctx->expected_result = SSL_TEST_SUCCESS;
251    EXECUTE_SSL_TEST_CTX_TEST();
252}
253
254static int test_good_configuration()
255{
256    SETUP_SSL_TEST_CTX_TEST_FIXTURE();
257    fixture.test_section = "ssltest_good";
258    fixture.expected_ctx->method = SSL_TEST_METHOD_DTLS;
259    fixture.expected_ctx->handshake_mode = SSL_TEST_HANDSHAKE_RESUME;
260    fixture.expected_ctx->app_data_size = 1024;
261    fixture.expected_ctx->max_fragment_size = 2048;
262
263    fixture.expected_ctx->expected_result = SSL_TEST_SERVER_FAIL;
264    fixture.expected_ctx->expected_client_alert = SSL_AD_UNKNOWN_CA;
265    fixture.expected_ctx->expected_server_alert = 0;  /* No alert. */
266    fixture.expected_ctx->expected_protocol = TLS1_1_VERSION;
267    fixture.expected_ctx->expected_servername = SSL_TEST_SERVERNAME_SERVER2;
268    fixture.expected_ctx->session_ticket_expected = SSL_TEST_SESSION_TICKET_YES;
269    fixture.expected_ctx->resumption_expected = 1;
270
271    fixture.expected_ctx->extra.client.verify_callback =
272        SSL_TEST_VERIFY_REJECT_ALL;
273    fixture.expected_ctx->extra.client.servername = SSL_TEST_SERVERNAME_SERVER2;
274    fixture.expected_ctx->extra.client.npn_protocols =
275        OPENSSL_strdup("foo,bar");
276    TEST_check(fixture.expected_ctx->extra.client.npn_protocols != NULL);
277
278    fixture.expected_ctx->extra.server.servername_callback =
279        SSL_TEST_SERVERNAME_IGNORE_MISMATCH;
280    fixture.expected_ctx->extra.server.broken_session_ticket = 1;
281
282    fixture.expected_ctx->resume_extra.server2.alpn_protocols =
283        OPENSSL_strdup("baz");
284    TEST_check(
285        fixture.expected_ctx->resume_extra.server2.alpn_protocols != NULL);
286
287    fixture.expected_ctx->resume_extra.client.ct_validation =
288        SSL_TEST_CT_VALIDATION_STRICT;
289
290    EXECUTE_SSL_TEST_CTX_TEST();
291}
292
293static const char *bad_configurations[] = {
294    "ssltest_unknown_option",
295    "ssltest_wrong_section",
296    "ssltest_unknown_expected_result",
297    "ssltest_unknown_alert",
298    "ssltest_unknown_protocol",
299    "ssltest_unknown_verify_callback",
300    "ssltest_unknown_servername",
301    "ssltest_unknown_servername_callback",
302    "ssltest_unknown_session_ticket_expected",
303    "ssltest_unknown_method",
304    "ssltest_unknown_handshake_mode",
305    "ssltest_unknown_resumption_expected",
306    "ssltest_unknown_ct_validation",
307};
308
309static int test_bad_configuration(int idx)
310{
311        SETUP_SSL_TEST_CTX_TEST_FIXTURE();
312        fixture.test_section = bad_configurations[idx];
313        EXECUTE_SSL_TEST_CTX_FAILURE_TEST();
314}
315
316int main(int argc, char **argv)
317{
318    int result = 0;
319
320    if (argc != 2)
321        return 1;
322
323    conf = NCONF_new(NULL);
324    TEST_check(conf != NULL);
325
326    /* argv[1] should point to test/ssl_test_ctx_test.conf */
327    TEST_check(NCONF_load(conf, argv[1], NULL) > 0);
328
329    ADD_TEST(test_empty_configuration);
330    ADD_TEST(test_good_configuration);
331    ADD_ALL_TESTS(test_bad_configuration, OSSL_NELEM(bad_configurations));
332
333    result = run_tests(argv[0]);
334
335    NCONF_free(conf);
336
337    return result;
338}
339