GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libssl/ssl_versions.c Lines: 97 108 89.8 %
Date: 2017-11-13 Branches: 67 80 83.8 %

Line Branch Exec Source
1
/* $OpenBSD: ssl_versions.c,v 1.3 2017/05/06 20:37:25 jsing Exp $ */
2
/*
3
 * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
4
 *
5
 * Permission to use, copy, modify, and distribute this software for any
6
 * purpose with or without fee is hereby granted, provided that the above
7
 * copyright notice and this permission notice appear in all copies.
8
 *
9
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
 */
17
18
#include "ssl_locl.h"
19
20
static int
21
ssl_clamp_version_range(uint16_t *min_ver, uint16_t *max_ver,
22
    uint16_t clamp_min, uint16_t clamp_max)
23
{
24

191874
	if (clamp_min > clamp_max || *min_ver > *max_ver)
25
15
		return 0;
26

127883
	if (clamp_max < *min_ver || clamp_min > *max_ver)
27
3
		return 0;
28
29
63940
	if (*min_ver < clamp_min)
30
29172
		*min_ver = clamp_min;
31
63940
	if (*max_ver > clamp_max)
32
198
		*max_ver = clamp_max;
33
34
63940
	return 1;
35
63958
}
36
37
int
38
ssl_version_set_min(const SSL_METHOD *meth, uint16_t ver, uint16_t max_ver,
39
    uint16_t *out_ver)
40
{
41
210
	uint16_t min_version, max_version;
42
43
105
	if (ver == 0) {
44
54
		*out_ver = meth->internal->min_version;
45
54
		return 1;
46
	}
47
48
51
	min_version = ver;
49
51
	max_version = max_ver;
50
51
51
	if (!ssl_clamp_version_range(&min_version, &max_version,
52
51
	    meth->internal->min_version, meth->internal->max_version))
53
6
		return 0;
54
55
45
	*out_ver = min_version;
56
57
45
	return 1;
58
105
}
59
60
int
61
ssl_version_set_max(const SSL_METHOD *meth, uint16_t ver, uint16_t min_ver,
62
    uint16_t *out_ver)
63
{
64
198
	uint16_t min_version, max_version;
65
66
99
	if (ver == 0) {
67
48
		*out_ver = meth->internal->max_version;
68
48
		return 1;
69
	}
70
71
51
	min_version = min_ver;
72
51
	max_version = ver;
73
74
51
	if (!ssl_clamp_version_range(&min_version, &max_version,
75
51
	    meth->internal->min_version, meth->internal->max_version))
76
9
		return 0;
77
78
42
	*out_ver = max_version;
79
80
42
	return 1;
81
99
}
82
83
int
84
ssl_enabled_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
85
{
86
63910
	uint16_t min_version, max_version;
87
88
	/*
89
	 * The enabled versions have to be a contiguous range, which means we
90
	 * cannot enable and disable single versions at our whim, even though
91
	 * this is what the OpenSSL flags allow. The historical way this has
92
	 * been handled is by making a flag mean that all higher versions
93
	 * are disabled, if any version lower than the flag is enabled.
94
	 */
95
96
31955
	min_version = 0;
97
31955
	max_version = TLS1_2_VERSION;
98
99
31955
	if ((s->internal->options & SSL_OP_NO_TLSv1) == 0)
100
31892
		min_version = TLS1_VERSION;
101
63
	else if ((s->internal->options & SSL_OP_NO_TLSv1_1) == 0)
102
12
		min_version = TLS1_1_VERSION;
103
51
	else if ((s->internal->options & SSL_OP_NO_TLSv1_2) == 0)
104
45
		min_version = TLS1_2_VERSION;
105
106

31985
	if ((s->internal->options & SSL_OP_NO_TLSv1_2) && min_version < TLS1_2_VERSION)
107
30
		max_version = TLS1_1_VERSION;
108

32024
	if ((s->internal->options & SSL_OP_NO_TLSv1_1) && min_version < TLS1_1_VERSION)
109
24
		max_version = TLS1_VERSION;
110

32018
	if ((s->internal->options & SSL_OP_NO_TLSv1) && min_version < TLS1_VERSION)
111
6
		max_version = 0;
112
113
	/* Everything has been disabled... */
114

63904
	if (min_version == 0 || max_version == 0)
115
6
		return 0;
116
117
	/* Limit to configured version range. */
118
31949
	if (!ssl_clamp_version_range(&min_version, &max_version,
119
31949
	    s->internal->min_version, s->internal->max_version))
120
		return 0;
121
122
31949
	if (min_ver != NULL)
123
31949
		*min_ver = min_version;
124
31949
	if (max_ver != NULL)
125
31943
		*max_ver = max_version;
126
127
31949
	return 1;
128
31955
}
129
130
int
131
ssl_supported_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
132
{
133
63970
	uint16_t min_version, max_version;
134
135
	/* DTLS cannot currently be disabled... */
136
31985
	if (SSL_IS_DTLS(s)) {
137
75
		min_version = max_version = DTLS1_VERSION;
138
75
		goto done;
139
	}
140
141
31910
	if (!ssl_enabled_version_range(s, &min_version, &max_version))
142
3
		return 0;
143
144
	/* Limit to the versions supported by this method. */
145
31907
	if (!ssl_clamp_version_range(&min_version, &max_version,
146
31907
	    s->method->internal->min_version,
147
31907
	    s->method->internal->max_version))
148
3
		return 0;
149
150
 done:
151
31979
	if (min_ver != NULL)
152
16075
		*min_ver = min_version;
153
31979
	if (max_ver != NULL)
154
31979
		*max_ver = max_version;
155
156
31979
	return 1;
157
31985
}
158
159
int
160
ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver)
161
{
162
516
	uint16_t min_version, max_version, shared_version;
163
164
258
	*max_ver = 0;
165
166
258
	if (SSL_IS_DTLS(s)) {
167
42
		if (peer_ver >= DTLS1_VERSION) {
168
39
			*max_ver = DTLS1_VERSION;
169
39
			return 1;
170
		}
171
3
		return 0;
172
	}
173
174
216
	if (peer_ver >= TLS1_2_VERSION)
175
126
		shared_version = TLS1_2_VERSION;
176
90
	else if (peer_ver >= TLS1_1_VERSION)
177
15
		shared_version = TLS1_1_VERSION;
178
75
	else if (peer_ver >= TLS1_VERSION)
179
		shared_version = TLS1_VERSION;
180
	else
181
6
		return 0;
182
183
210
	if (!ssl_supported_version_range(s, &min_version, &max_version))
184
6
		return 0;
185
186
204
	if (shared_version < min_version)
187
6
		return 0;
188
189
198
	if (shared_version > max_version)
190
15
		shared_version = max_version;
191
192
198
	*max_ver = shared_version;
193
194
198
	return 1;
195
258
}
196
197
uint16_t
198
ssl_max_server_version(SSL *s)
199
{
200
	uint16_t max_version, min_version = 0;
201
202
	if (SSL_IS_DTLS(s))
203
		return (DTLS1_VERSION);
204
205
	if (!ssl_enabled_version_range(s, &min_version, &max_version))
206
		return 0;
207
208
	/*
209
	 * Limit to the versions supported by this method. The SSL method
210
	 * will be changed during version negotiation, as such we want to
211
	 * use the SSL method from the context.
212
	 */
213
	if (!ssl_clamp_version_range(&min_version, &max_version,
214
	    s->ctx->method->internal->min_version,
215
	    s->ctx->method->internal->max_version))
216
		return 0;
217
218
	return (max_version);
219
}