summaryrefslogtreecommitdiff
path: root/test/ssl_ctx_test.c
blob: ea7aadc2f69fe606cc69aa7ddaee5d94af918375 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
 * Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include "testutil.h"
#include <openssl/ssl.h>

typedef struct {
    int proto;
    int min_version;
    int max_version;
    int min_ok;
    int max_ok;
    int expected_min;
    int expected_max;
} version_test;

#define PROTO_TLS  0
#define PROTO_DTLS 1
#define PROTO_QUIC 2

/*
 * If a version is valid for *any* protocol then setting the min/max protocol is
 * expected to return success, even if that version is not valid for *this*
 * protocol. However it only has an effect if it is valid for *this* protocol -
 * otherwise it is ignored.
 */
static const version_test version_testdata[] = {
    /* proto     min                     max                     ok    expected min        expected max */
    {PROTO_TLS,  0,                      0,                      1, 1, 0,                  0},
    {PROTO_TLS,  SSL3_VERSION,           TLS1_3_VERSION,         1, 1, SSL3_VERSION,       TLS1_3_VERSION},
    {PROTO_TLS,  TLS1_VERSION,           TLS1_3_VERSION,         1, 1, TLS1_VERSION,       TLS1_3_VERSION},
    {PROTO_TLS,  TLS1_VERSION,           TLS1_2_VERSION,         1, 1, TLS1_VERSION,       TLS1_2_VERSION},
    {PROTO_TLS,  TLS1_2_VERSION,         TLS1_2_VERSION,         1, 1, TLS1_2_VERSION,     TLS1_2_VERSION},
    {PROTO_TLS,  TLS1_2_VERSION,         TLS1_1_VERSION,         1, 1, TLS1_2_VERSION,     TLS1_1_VERSION},
    {PROTO_TLS,  SSL3_VERSION - 1,       TLS1_3_VERSION,         0, 1, 0,                  TLS1_3_VERSION},
    {PROTO_TLS,  SSL3_VERSION,           TLS1_3_VERSION + 1,     1, 0, SSL3_VERSION,       0},
#ifndef OPENSSL_NO_DTLS
    {PROTO_TLS,  DTLS1_VERSION,          DTLS1_2_VERSION,        1, 1, 0,                  0},
#endif
    {PROTO_TLS,  OSSL_QUIC1_VERSION,     OSSL_QUIC1_VERSION,     0, 0, 0,                  0},
    {PROTO_TLS,  7,                      42,                     0, 0, 0,                  0},
    {PROTO_DTLS, 0,                      0,                      1, 1, 0,                  0},
    {PROTO_DTLS, DTLS1_VERSION,          DTLS1_2_VERSION,        1, 1, DTLS1_VERSION,      DTLS1_2_VERSION},
#ifndef OPENSSL_NO_DTLS1_2
    {PROTO_DTLS, DTLS1_2_VERSION,        DTLS1_2_VERSION,        1, 1, DTLS1_2_VERSION,    DTLS1_2_VERSION},
#endif
#ifndef OPENSSL_NO_DTLS1
    {PROTO_DTLS, DTLS1_VERSION,          DTLS1_VERSION,          1, 1, DTLS1_VERSION,      DTLS1_VERSION},
#endif
#if !defined(OPENSSL_NO_DTLS1) && !defined(OPENSSL_NO_DTLS1_2)
    {PROTO_DTLS, DTLS1_2_VERSION,        DTLS1_VERSION,          1, 1, DTLS1_2_VERSION,    DTLS1_VERSION},
#endif
    {PROTO_DTLS, DTLS1_VERSION + 1,      DTLS1_2_VERSION,        0, 1, 0,                  DTLS1_2_VERSION},
    {PROTO_DTLS, DTLS1_VERSION,          DTLS1_2_VERSION - 1,    1, 0, DTLS1_VERSION,      0},
    {PROTO_DTLS, TLS1_VERSION,           TLS1_3_VERSION,         1, 1, 0,                  0},
    {PROTO_DTLS, OSSL_QUIC1_VERSION,     OSSL_QUIC1_VERSION,     0, 0, 0,                  0},
    /* These functions never have an effect when called on a QUIC object */
    {PROTO_QUIC, 0,                      0,                      1, 1, 0,                  0},
    {PROTO_QUIC, OSSL_QUIC1_VERSION,     OSSL_QUIC1_VERSION,     0, 0, 0,                  0},
    {PROTO_QUIC, OSSL_QUIC1_VERSION,     OSSL_QUIC1_VERSION + 1, 0, 0, 0,                  0},
    {PROTO_QUIC, TLS1_VERSION,           TLS1_3_VERSION,         1, 1, 0,                  0},
#ifndef OPENSSL_NO_DTLS
    {PROTO_QUIC, DTLS1_VERSION,          DTLS1_2_VERSION,        1, 1, 0,                  0},
#endif
};

static int test_set_min_max_version(int idx_tst)
{
    SSL_CTX *ctx = NULL;
    SSL *ssl = NULL;
    int testresult = 0;
    version_test t = version_testdata[idx_tst];
    const SSL_METHOD *meth = NULL;

    switch (t.proto) {
    case PROTO_TLS:
        meth = TLS_client_method();
        break;

#ifndef OPENSSL_NO_DTLS
    case PROTO_DTLS:
        meth = DTLS_client_method();
        break;
#endif

#ifndef OPENSSL_NO_QUIC
    case PROTO_QUIC:
        meth = OSSL_QUIC_client_method();
        break;
#endif
    }

    if (meth == NULL)
        return TEST_skip("Protocol not supported");

    ctx = SSL_CTX_new(meth);
    if (ctx == NULL)
        goto end;

    ssl = SSL_new(ctx);
    if (ssl == NULL)
        goto end;

    if (!TEST_int_eq(SSL_CTX_set_min_proto_version(ctx, t.min_version), t.min_ok))
        goto end;
    if (!TEST_int_eq(SSL_CTX_set_max_proto_version(ctx, t.max_version), t.max_ok))
        goto end;
    if (!TEST_int_eq(SSL_CTX_get_min_proto_version(ctx), t.expected_min))
        goto end;
    if (!TEST_int_eq(SSL_CTX_get_max_proto_version(ctx), t.expected_max))
        goto end;

    if (!TEST_int_eq(SSL_set_min_proto_version(ssl, t.min_version), t.min_ok))
        goto end;
    if (!TEST_int_eq(SSL_set_max_proto_version(ssl, t.max_version), t.max_ok))
        goto end;
    if (!TEST_int_eq(SSL_get_min_proto_version(ssl), t.expected_min))
        goto end;
    if (!TEST_int_eq(SSL_get_max_proto_version(ssl), t.expected_max))
        goto end;

    testresult = 1;

  end:
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    return testresult;
}

int setup_tests(void)
{
    ADD_ALL_TESTS(test_set_min_max_version, sizeof(version_testdata) / sizeof(version_test));
    return 1;
}