GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libssl/ssl_versions.c Lines: 97 108 89.8 %
Date: 2017-11-07 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

99336
	if (clamp_min > clamp_max || *min_ver > *max_ver)
25
5
		return 0;
26

66213
	if (clamp_max < *min_ver || clamp_min > *max_ver)
27
1
		return 0;
28
29
33106
	if (*min_ver < clamp_min)
30
14100
		*min_ver = clamp_min;
31
33106
	if (*max_ver > clamp_max)
32
234
		*max_ver = clamp_max;
33
34
33106
	return 1;
35
33112
}
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
70
	uint16_t min_version, max_version;
42
43
35
	if (ver == 0) {
44
18
		*out_ver = meth->internal->min_version;
45
18
		return 1;
46
	}
47
48
17
	min_version = ver;
49
17
	max_version = max_ver;
50
51
17
	if (!ssl_clamp_version_range(&min_version, &max_version,
52
17
	    meth->internal->min_version, meth->internal->max_version))
53
2
		return 0;
54
55
15
	*out_ver = min_version;
56
57
15
	return 1;
58
35
}
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
66
	uint16_t min_version, max_version;
65
66
33
	if (ver == 0) {
67
16
		*out_ver = meth->internal->max_version;
68
16
		return 1;
69
	}
70
71
17
	min_version = min_ver;
72
17
	max_version = ver;
73
74
17
	if (!ssl_clamp_version_range(&min_version, &max_version,
75
17
	    meth->internal->min_version, meth->internal->max_version))
76
3
		return 0;
77
78
14
	*out_ver = max_version;
79
80
14
	return 1;
81
33
}
82
83
int
84
ssl_enabled_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
85
{
86
33102
	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
16551
	min_version = 0;
97
16551
	max_version = TLS1_2_VERSION;
98
99
16551
	if ((s->internal->options & SSL_OP_NO_TLSv1) == 0)
100
16491
		min_version = TLS1_VERSION;
101
60
	else if ((s->internal->options & SSL_OP_NO_TLSv1_1) == 0)
102
4
		min_version = TLS1_1_VERSION;
103
56
	else if ((s->internal->options & SSL_OP_NO_TLSv1_2) == 0)
104
54
		min_version = TLS1_2_VERSION;
105
106

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

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

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

33100
	if (min_version == 0 || max_version == 0)
115
2
		return 0;
116
117
	/* Limit to configured version range. */
118
16549
	if (!ssl_clamp_version_range(&min_version, &max_version,
119
16549
	    s->internal->min_version, s->internal->max_version))
120
		return 0;
121
122
16549
	if (min_ver != NULL)
123
16549
		*min_ver = min_version;
124
16549
	if (max_ver != NULL)
125
16541
		*max_ver = max_version;
126
127
16549
	return 1;
128
16551
}
129
130
int
131
ssl_supported_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
132
{
133
33260
	uint16_t min_version, max_version;
134
135
	/* DTLS cannot currently be disabled... */
136
16630
	if (SSL_IS_DTLS(s)) {
137
100
		min_version = max_version = DTLS1_VERSION;
138
100
		goto done;
139
	}
140
141
16530
	if (!ssl_enabled_version_range(s, &min_version, &max_version))
142
1
		return 0;
143
144
	/* Limit to the versions supported by this method. */
145
16529
	if (!ssl_clamp_version_range(&min_version, &max_version,
146
16529
	    s->method->internal->min_version,
147
16529
	    s->method->internal->max_version))
148
1
		return 0;
149
150
 done:
151
16628
	if (min_ver != NULL)
152
8407
		*min_ver = min_version;
153
16628
	if (max_ver != NULL)
154
16628
		*max_ver = max_version;
155
156
16628
	return 1;
157
16630
}
158
159
int
160
ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver)
161
{
162
568
	uint16_t min_version, max_version, shared_version;
163
164
284
	*max_ver = 0;
165
166
284
	if (SSL_IS_DTLS(s)) {
167
50
		if (peer_ver >= DTLS1_VERSION) {
168
49
			*max_ver = DTLS1_VERSION;
169
49
			return 1;
170
		}
171
1
		return 0;
172
	}
173
174
234
	if (peer_ver >= TLS1_2_VERSION)
175
147
		shared_version = TLS1_2_VERSION;
176
87
	else if (peer_ver >= TLS1_1_VERSION)
177
5
		shared_version = TLS1_1_VERSION;
178
82
	else if (peer_ver >= TLS1_VERSION)
179
		shared_version = TLS1_VERSION;
180
	else
181
2
		return 0;
182
183
232
	if (!ssl_supported_version_range(s, &min_version, &max_version))
184
2
		return 0;
185
186
230
	if (shared_version < min_version)
187
2
		return 0;
188
189
228
	if (shared_version > max_version)
190
5
		shared_version = max_version;
191
192
228
	*max_ver = shared_version;
193
194
228
	return 1;
195
284
}
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
}