xref: /third_party/openssl/test/ssl_test.c (revision e1051a39)
1/*
2 * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License").  You may not use
5 * this file except in compliance with the License.  You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include <stdio.h>
11#include <string.h>
12
13#include <openssl/conf.h>
14#include <openssl/err.h>
15#include <openssl/ssl.h>
16#include <openssl/provider.h>
17
18#include "helpers/handshake.h"
19#include "helpers/ssl_test_ctx.h"
20#include "testutil.h"
21
22static CONF *conf = NULL;
23static OSSL_PROVIDER *defctxnull = NULL, *thisprov = NULL;
24static OSSL_LIB_CTX *libctx = NULL;
25
26/* Currently the section names are of the form test-<number>, e.g. test-15. */
27#define MAX_TESTCASE_NAME_LENGTH 100
28
29static const char *print_alert(int alert)
30{
31    return alert ? SSL_alert_desc_string_long(alert) : "no alert";
32}
33
34static int check_result(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
35{
36    if (!TEST_int_eq(result->result, test_ctx->expected_result)) {
37        TEST_info("ExpectedResult mismatch: expected %s, got %s.",
38                  ssl_test_result_name(test_ctx->expected_result),
39                  ssl_test_result_name(result->result));
40        return 0;
41    }
42    return 1;
43}
44
45static int check_alerts(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
46{
47    if (!TEST_int_eq(result->client_alert_sent,
48                     result->client_alert_received)) {
49        TEST_info("Client sent alert %s but server received %s.",
50                  print_alert(result->client_alert_sent),
51                  print_alert(result->client_alert_received));
52        /*
53         * We can't bail here because the peer doesn't always get far enough
54         * to process a received alert. Specifically, in protocol version
55         * negotiation tests, we have the following scenario.
56         * Client supports TLS v1.2 only; Server supports TLS v1.1.
57         * Client proposes TLS v1.2; server responds with 1.1;
58         * Client now sends a protocol alert, using TLS v1.2 in the header.
59         * The server, however, rejects the alert because of version mismatch
60         * in the record layer; therefore, the server appears to never
61         * receive the alert.
62         */
63        /* return 0; */
64    }
65
66    if (!TEST_int_eq(result->server_alert_sent,
67                     result->server_alert_received)) {
68        TEST_info("Server sent alert %s but client received %s.",
69                  print_alert(result->server_alert_sent),
70                  print_alert(result->server_alert_received));
71        /* return 0; */
72    }
73
74    /* Tolerate an alert if one wasn't explicitly specified in the test. */
75    if (test_ctx->expected_client_alert
76        /*
77         * The info callback alert value is computed as
78         * (s->s3->send_alert[0] << 8) | s->s3->send_alert[1]
79         * where the low byte is the alert code and the high byte is other stuff.
80         */
81        && (result->client_alert_sent & 0xff) != test_ctx->expected_client_alert) {
82        TEST_error("ClientAlert mismatch: expected %s, got %s.",
83                   print_alert(test_ctx->expected_client_alert),
84                   print_alert(result->client_alert_sent));
85        return 0;
86    }
87
88    if (test_ctx->expected_server_alert
89        && (result->server_alert_sent & 0xff) != test_ctx->expected_server_alert) {
90        TEST_error("ServerAlert mismatch: expected %s, got %s.",
91                   print_alert(test_ctx->expected_server_alert),
92                   print_alert(result->server_alert_sent));
93        return 0;
94    }
95
96    if (!TEST_int_le(result->client_num_fatal_alerts_sent, 1))
97        return 0;
98    if (!TEST_int_le(result->server_num_fatal_alerts_sent, 1))
99        return 0;
100    return 1;
101}
102
103static int check_protocol(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
104{
105    if (!TEST_int_eq(result->client_protocol, result->server_protocol)) {
106        TEST_info("Client has protocol %s but server has %s.",
107                  ssl_protocol_name(result->client_protocol),
108                  ssl_protocol_name(result->server_protocol));
109        return 0;
110    }
111
112    if (test_ctx->expected_protocol) {
113        if (!TEST_int_eq(result->client_protocol,
114                         test_ctx->expected_protocol)) {
115            TEST_info("Protocol mismatch: expected %s, got %s.\n",
116                      ssl_protocol_name(test_ctx->expected_protocol),
117                      ssl_protocol_name(result->client_protocol));
118            return 0;
119        }
120    }
121    return 1;
122}
123
124static int check_servername(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
125{
126    if (!TEST_int_eq(result->servername, test_ctx->expected_servername)) {
127      TEST_info("Client ServerName mismatch, expected %s, got %s.",
128                ssl_servername_name(test_ctx->expected_servername),
129                ssl_servername_name(result->servername));
130      return 0;
131    }
132  return 1;
133}
134
135static int check_session_ticket(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
136{
137    if (test_ctx->session_ticket_expected == SSL_TEST_SESSION_TICKET_IGNORE)
138        return 1;
139    if (!TEST_int_eq(result->session_ticket,
140                     test_ctx->session_ticket_expected)) {
141        TEST_info("Client SessionTicketExpected mismatch, expected %s, got %s.",
142                  ssl_session_ticket_name(test_ctx->session_ticket_expected),
143                  ssl_session_ticket_name(result->session_ticket));
144        return 0;
145    }
146    return 1;
147}
148
149static int check_session_id(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
150{
151    if (test_ctx->session_id_expected == SSL_TEST_SESSION_ID_IGNORE)
152        return 1;
153    if (!TEST_int_eq(result->session_id, test_ctx->session_id_expected)) {
154        TEST_info("Client SessionIdExpected mismatch, expected %s, got %s\n.",
155                ssl_session_id_name(test_ctx->session_id_expected),
156                ssl_session_id_name(result->session_id));
157        return 0;
158    }
159    return 1;
160}
161
162static int check_compression(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
163{
164    if (!TEST_int_eq(result->compression, test_ctx->compression_expected))
165        return 0;
166    return 1;
167}
168#ifndef OPENSSL_NO_NEXTPROTONEG
169static int check_npn(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
170{
171    int ret = 1;
172    if (!TEST_str_eq(result->client_npn_negotiated,
173                     result->server_npn_negotiated))
174        ret = 0;
175    if (!TEST_str_eq(test_ctx->expected_npn_protocol,
176                     result->client_npn_negotiated))
177        ret = 0;
178    return ret;
179}
180#endif
181
182static int check_alpn(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
183{
184    int ret = 1;
185    if (!TEST_str_eq(result->client_alpn_negotiated,
186                     result->server_alpn_negotiated))
187        ret = 0;
188    if (!TEST_str_eq(test_ctx->expected_alpn_protocol,
189                     result->client_alpn_negotiated))
190        ret = 0;
191    return ret;
192}
193
194static int check_session_ticket_app_data(HANDSHAKE_RESULT *result,
195                                         SSL_TEST_CTX *test_ctx)
196{
197    size_t result_len = 0;
198    size_t expected_len = 0;
199
200    /* consider empty and NULL strings to be the same */
201    if (result->result_session_ticket_app_data != NULL)
202        result_len = strlen(result->result_session_ticket_app_data);
203    if (test_ctx->expected_session_ticket_app_data != NULL)
204        expected_len = strlen(test_ctx->expected_session_ticket_app_data);
205    if (result_len == 0 && expected_len == 0)
206        return 1;
207
208    if (!TEST_str_eq(result->result_session_ticket_app_data,
209                     test_ctx->expected_session_ticket_app_data))
210        return 0;
211
212    return 1;
213}
214
215static int check_resumption(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
216{
217    if (!TEST_int_eq(result->client_resumed, result->server_resumed))
218        return 0;
219    if (!TEST_int_eq(result->client_resumed, test_ctx->resumption_expected))
220        return 0;
221    return 1;
222}
223
224static int check_nid(const char *name, int expected_nid, int nid)
225{
226    if (expected_nid == 0 || expected_nid == nid)
227        return 1;
228    TEST_error("%s type mismatch, %s vs %s\n",
229               name, OBJ_nid2ln(expected_nid),
230               nid == NID_undef ? "absent" : OBJ_nid2ln(nid));
231    return 0;
232}
233
234static void print_ca_names(STACK_OF(X509_NAME) *names)
235{
236    int i;
237
238    if (names == NULL || sk_X509_NAME_num(names) == 0) {
239        TEST_note("    <empty>");
240        return;
241    }
242    for (i = 0; i < sk_X509_NAME_num(names); i++) {
243        X509_NAME_print_ex(bio_err, sk_X509_NAME_value(names, i), 4,
244                           XN_FLAG_ONELINE);
245        BIO_puts(bio_err, "\n");
246    }
247}
248
249static int check_ca_names(const char *name,
250                          STACK_OF(X509_NAME) *expected_names,
251                          STACK_OF(X509_NAME) *names)
252{
253    int i;
254
255    if (expected_names == NULL)
256        return 1;
257    if (names == NULL || sk_X509_NAME_num(names) == 0) {
258        if (TEST_int_eq(sk_X509_NAME_num(expected_names), 0))
259            return 1;
260        goto err;
261    }
262    if (sk_X509_NAME_num(names) != sk_X509_NAME_num(expected_names))
263        goto err;
264    for (i = 0; i < sk_X509_NAME_num(names); i++) {
265        if (!TEST_int_eq(X509_NAME_cmp(sk_X509_NAME_value(names, i),
266                                       sk_X509_NAME_value(expected_names, i)),
267                         0)) {
268            goto err;
269        }
270    }
271    return 1;
272err:
273    TEST_info("%s: list mismatch", name);
274    TEST_note("Expected Names:");
275    print_ca_names(expected_names);
276    TEST_note("Received Names:");
277    print_ca_names(names);
278    return 0;
279}
280
281static int check_tmp_key(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
282{
283    return check_nid("Tmp key", test_ctx->expected_tmp_key_type,
284                     result->tmp_key_type);
285}
286
287static int check_server_cert_type(HANDSHAKE_RESULT *result,
288                                  SSL_TEST_CTX *test_ctx)
289{
290    return check_nid("Server certificate", test_ctx->expected_server_cert_type,
291                     result->server_cert_type);
292}
293
294static int check_server_sign_hash(HANDSHAKE_RESULT *result,
295                                  SSL_TEST_CTX *test_ctx)
296{
297    return check_nid("Server signing hash", test_ctx->expected_server_sign_hash,
298                     result->server_sign_hash);
299}
300
301static int check_server_sign_type(HANDSHAKE_RESULT *result,
302                                  SSL_TEST_CTX *test_ctx)
303{
304    return check_nid("Server signing", test_ctx->expected_server_sign_type,
305                     result->server_sign_type);
306}
307
308static int check_server_ca_names(HANDSHAKE_RESULT *result,
309                                 SSL_TEST_CTX *test_ctx)
310{
311    return check_ca_names("Server CA names",
312                          test_ctx->expected_server_ca_names,
313                          result->server_ca_names);
314}
315
316static int check_client_cert_type(HANDSHAKE_RESULT *result,
317                                  SSL_TEST_CTX *test_ctx)
318{
319    return check_nid("Client certificate", test_ctx->expected_client_cert_type,
320                     result->client_cert_type);
321}
322
323static int check_client_sign_hash(HANDSHAKE_RESULT *result,
324                                  SSL_TEST_CTX *test_ctx)
325{
326    return check_nid("Client signing hash", test_ctx->expected_client_sign_hash,
327                     result->client_sign_hash);
328}
329
330static int check_client_sign_type(HANDSHAKE_RESULT *result,
331                                  SSL_TEST_CTX *test_ctx)
332{
333    return check_nid("Client signing", test_ctx->expected_client_sign_type,
334                     result->client_sign_type);
335}
336
337static int check_client_ca_names(HANDSHAKE_RESULT *result,
338                                 SSL_TEST_CTX *test_ctx)
339{
340    return check_ca_names("Client CA names",
341                          test_ctx->expected_client_ca_names,
342                          result->client_ca_names);
343}
344
345static int check_cipher(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
346{
347    if (test_ctx->expected_cipher == NULL)
348        return 1;
349    if (!TEST_ptr(result->cipher))
350        return 0;
351    if (!TEST_str_eq(test_ctx->expected_cipher,
352                     result->cipher))
353        return 0;
354    return 1;
355}
356
357/*
358 * This could be further simplified by constructing an expected
359 * HANDSHAKE_RESULT, and implementing comparison methods for
360 * its fields.
361 */
362static int check_test(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
363{
364    int ret = 1;
365    ret &= check_result(result, test_ctx);
366    ret &= check_alerts(result, test_ctx);
367    if (result->result == SSL_TEST_SUCCESS) {
368        ret &= check_protocol(result, test_ctx);
369        ret &= check_servername(result, test_ctx);
370        ret &= check_session_ticket(result, test_ctx);
371        ret &= check_compression(result, test_ctx);
372        ret &= check_session_id(result, test_ctx);
373        ret &= (result->session_ticket_do_not_call == 0);
374#ifndef OPENSSL_NO_NEXTPROTONEG
375        ret &= check_npn(result, test_ctx);
376#endif
377        ret &= check_cipher(result, test_ctx);
378        ret &= check_alpn(result, test_ctx);
379        ret &= check_session_ticket_app_data(result, test_ctx);
380        ret &= check_resumption(result, test_ctx);
381        ret &= check_tmp_key(result, test_ctx);
382        ret &= check_server_cert_type(result, test_ctx);
383        ret &= check_server_sign_hash(result, test_ctx);
384        ret &= check_server_sign_type(result, test_ctx);
385        ret &= check_server_ca_names(result, test_ctx);
386        ret &= check_client_cert_type(result, test_ctx);
387        ret &= check_client_sign_hash(result, test_ctx);
388        ret &= check_client_sign_type(result, test_ctx);
389        ret &= check_client_ca_names(result, test_ctx);
390    }
391    return ret;
392}
393
394static int test_handshake(int idx)
395{
396    int ret = 0;
397    SSL_CTX *server_ctx = NULL, *server2_ctx = NULL, *client_ctx = NULL,
398        *resume_server_ctx = NULL, *resume_client_ctx = NULL;
399    SSL_TEST_CTX *test_ctx = NULL;
400    HANDSHAKE_RESULT *result = NULL;
401    char test_app[MAX_TESTCASE_NAME_LENGTH];
402
403    BIO_snprintf(test_app, sizeof(test_app), "test-%d", idx);
404
405    test_ctx = SSL_TEST_CTX_create(conf, test_app, libctx);
406    if (!TEST_ptr(test_ctx))
407        goto err;
408
409#ifndef OPENSSL_NO_DTLS
410    if (test_ctx->method == SSL_TEST_METHOD_DTLS) {
411        server_ctx = SSL_CTX_new_ex(libctx, NULL, DTLS_server_method());
412        if (!TEST_true(SSL_CTX_set_options(server_ctx,
413                        SSL_OP_ALLOW_CLIENT_RENEGOTIATION))
414                || !TEST_true(SSL_CTX_set_max_proto_version(server_ctx, 0)))
415            goto err;
416        if (test_ctx->extra.server.servername_callback !=
417            SSL_TEST_SERVERNAME_CB_NONE) {
418            if (!TEST_ptr(server2_ctx =
419                            SSL_CTX_new_ex(libctx, NULL, DTLS_server_method()))
420                    || !TEST_true(SSL_CTX_set_options(server2_ctx,
421                            SSL_OP_ALLOW_CLIENT_RENEGOTIATION)))
422                goto err;
423        }
424        client_ctx = SSL_CTX_new_ex(libctx, NULL, DTLS_client_method());
425        if (!TEST_true(SSL_CTX_set_max_proto_version(client_ctx, 0)))
426            goto err;
427        if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RESUME) {
428            resume_server_ctx = SSL_CTX_new_ex(libctx, NULL,
429                                               DTLS_server_method());
430            if (!TEST_true(SSL_CTX_set_max_proto_version(resume_server_ctx, 0))
431                    || !TEST_true(SSL_CTX_set_options(resume_server_ctx,
432                            SSL_OP_ALLOW_CLIENT_RENEGOTIATION)))
433                goto err;
434            resume_client_ctx = SSL_CTX_new_ex(libctx, NULL,
435                                               DTLS_client_method());
436            if (!TEST_true(SSL_CTX_set_max_proto_version(resume_client_ctx, 0)))
437                goto err;
438            if (!TEST_ptr(resume_server_ctx)
439                    || !TEST_ptr(resume_client_ctx))
440                goto err;
441        }
442    }
443#endif
444    if (test_ctx->method == SSL_TEST_METHOD_TLS) {
445#if !defined(OPENSSL_NO_TLS1_3) \
446    && defined(OPENSSL_NO_EC) \
447    && defined(OPENSSL_NO_DH)
448        /* Without ec or dh there are no built-in groups for TLSv1.3 */
449        int maxversion = TLS1_2_VERSION;
450#else
451        int maxversion = 0;
452#endif
453
454        server_ctx = SSL_CTX_new_ex(libctx, NULL, TLS_server_method());
455        if (!TEST_true(SSL_CTX_set_max_proto_version(server_ctx, maxversion))
456                || !TEST_true(SSL_CTX_set_options(server_ctx,
457                            SSL_OP_ALLOW_CLIENT_RENEGOTIATION)))
458            goto err;
459        /* SNI on resumption isn't supported/tested yet. */
460        if (test_ctx->extra.server.servername_callback !=
461            SSL_TEST_SERVERNAME_CB_NONE) {
462            if (!TEST_ptr(server2_ctx =
463                            SSL_CTX_new_ex(libctx, NULL, TLS_server_method()))
464                    || !TEST_true(SSL_CTX_set_options(server2_ctx,
465                            SSL_OP_ALLOW_CLIENT_RENEGOTIATION)))
466                goto err;
467            if (!TEST_true(SSL_CTX_set_max_proto_version(server2_ctx,
468                                                         maxversion)))
469                goto err;
470        }
471        client_ctx = SSL_CTX_new_ex(libctx, NULL, TLS_client_method());
472        if (!TEST_true(SSL_CTX_set_max_proto_version(client_ctx, maxversion)))
473            goto err;
474
475        if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RESUME) {
476            resume_server_ctx = SSL_CTX_new_ex(libctx, NULL,
477                                               TLS_server_method());
478            if (!TEST_true(SSL_CTX_set_max_proto_version(resume_server_ctx,
479                                                         maxversion))
480                    || !TEST_true(SSL_CTX_set_options(resume_server_ctx,
481                            SSL_OP_ALLOW_CLIENT_RENEGOTIATION)))
482                goto err;
483            resume_client_ctx = SSL_CTX_new_ex(libctx, NULL,
484                                               TLS_client_method());
485            if (!TEST_true(SSL_CTX_set_max_proto_version(resume_client_ctx,
486                                                         maxversion)))
487                goto err;
488            if (!TEST_ptr(resume_server_ctx)
489                    || !TEST_ptr(resume_client_ctx))
490                goto err;
491        }
492    }
493
494#ifdef OPENSSL_NO_AUTOLOAD_CONFIG
495    if (!TEST_true(OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL)))
496        goto err;
497#endif
498
499    if (!TEST_ptr(server_ctx)
500            || !TEST_ptr(client_ctx)
501            || !TEST_int_gt(CONF_modules_load(conf, test_app, 0),  0))
502        goto err;
503
504    if (!SSL_CTX_config(server_ctx, "server")
505        || !SSL_CTX_config(client_ctx, "client")) {
506        goto err;
507    }
508
509    if (server2_ctx != NULL && !SSL_CTX_config(server2_ctx, "server2"))
510        goto err;
511    if (resume_server_ctx != NULL
512        && !SSL_CTX_config(resume_server_ctx, "resume-server"))
513        goto err;
514    if (resume_client_ctx != NULL
515        && !SSL_CTX_config(resume_client_ctx, "resume-client"))
516        goto err;
517
518    result = do_handshake(server_ctx, server2_ctx, client_ctx,
519                          resume_server_ctx, resume_client_ctx, test_ctx);
520
521    if (result != NULL)
522        ret = check_test(result, test_ctx);
523
524err:
525    CONF_modules_unload(0);
526    SSL_CTX_free(server_ctx);
527    SSL_CTX_free(server2_ctx);
528    SSL_CTX_free(client_ctx);
529    SSL_CTX_free(resume_server_ctx);
530    SSL_CTX_free(resume_client_ctx);
531    SSL_TEST_CTX_free(test_ctx);
532    HANDSHAKE_RESULT_free(result);
533    return ret;
534}
535
536#define USAGE "conf_file module_name [module_conf_file]\n"
537OPT_TEST_DECLARE_USAGE(USAGE)
538
539int setup_tests(void)
540{
541    long num_tests;
542
543    if (!test_skip_common_options()) {
544        TEST_error("Error parsing test options\n");
545        return 0;
546    }
547
548    if (!TEST_ptr(conf = NCONF_new(NULL))
549            /* argv[1] should point to the test conf file */
550            || !TEST_int_gt(NCONF_load(conf, test_get_argument(0), NULL), 0)
551            || !TEST_int_ne(NCONF_get_number_e(conf, NULL, "num_tests",
552                                               &num_tests), 0)) {
553        TEST_error("usage: ssl_test %s", USAGE);
554        return 0;
555    }
556
557    if (!test_arg_libctx(&libctx, &defctxnull, &thisprov, 1, USAGE))
558        return 0;
559
560    ADD_ALL_TESTS(test_handshake, (int)num_tests);
561    return 1;
562}
563
564void cleanup_tests(void)
565{
566    NCONF_free(conf);
567    OSSL_PROVIDER_unload(defctxnull);
568    OSSL_PROVIDER_unload(thisprov);
569    OSSL_LIB_CTX_free(libctx);
570}
571