/src/libressl/ssl/ssl_ciphers.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* $OpenBSD: ssl_ciphers.c,v 1.15 2022/07/02 16:31:04 tb Exp $ */ |
2 | | /* |
3 | | * Copyright (c) 2015-2017 Doug Hogan <doug@openbsd.org> |
4 | | * Copyright (c) 2015-2018, 2020 Joel Sing <jsing@openbsd.org> |
5 | | * Copyright (c) 2019 Theo Buehler <tb@openbsd.org> |
6 | | * |
7 | | * Permission to use, copy, modify, and distribute this software for any |
8 | | * purpose with or without fee is hereby granted, provided that the above |
9 | | * copyright notice and this permission notice appear in all copies. |
10 | | * |
11 | | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
12 | | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
13 | | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
14 | | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
15 | | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
16 | | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
17 | | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
18 | | */ |
19 | | |
20 | | #include <openssl/safestack.h> |
21 | | |
22 | | #include "bytestring.h" |
23 | | #include "ssl_locl.h" |
24 | | |
25 | | int |
26 | | ssl_cipher_in_list(STACK_OF(SSL_CIPHER) *ciphers, const SSL_CIPHER *cipher) |
27 | 6.19k | { |
28 | 6.19k | int i; |
29 | | |
30 | 209k | for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { |
31 | 209k | if (sk_SSL_CIPHER_value(ciphers, i)->id == cipher->id) |
32 | 6.19k | return 1; |
33 | 209k | } |
34 | | |
35 | 0 | return 0; |
36 | 6.19k | } |
37 | | |
38 | | int |
39 | | ssl_cipher_allowed_in_tls_version_range(const SSL_CIPHER *cipher, uint16_t min_ver, |
40 | | uint16_t max_ver) |
41 | 487k | { |
42 | 487k | switch(cipher->algorithm_ssl) { |
43 | 263k | case SSL_SSLV3: |
44 | 263k | return (min_ver <= TLS1_2_VERSION); |
45 | 202k | case SSL_TLSV1_2: |
46 | 202k | return (min_ver <= TLS1_2_VERSION && TLS1_2_VERSION <= max_ver); |
47 | 20.2k | case SSL_TLSV1_3: |
48 | 20.2k | return (min_ver <= TLS1_3_VERSION && TLS1_3_VERSION <= max_ver); |
49 | 487k | } |
50 | 0 | return 0; |
51 | 487k | } |
52 | | |
53 | | int |
54 | | ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *ciphers, CBB *cbb) |
55 | 6.76k | { |
56 | 6.76k | SSL_CIPHER *cipher; |
57 | 6.76k | int num_ciphers = 0; |
58 | 6.76k | uint16_t min_vers, max_vers; |
59 | 6.76k | int i; |
60 | | |
61 | 6.76k | if (ciphers == NULL) |
62 | 0 | return 0; |
63 | | |
64 | 6.76k | if (!ssl_supported_tls_version_range(s, &min_vers, &max_vers)) |
65 | 0 | return 0; |
66 | | |
67 | 493k | for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { |
68 | 487k | if ((cipher = sk_SSL_CIPHER_value(ciphers, i)) == NULL) |
69 | 0 | return 0; |
70 | 487k | if (!ssl_cipher_allowed_in_tls_version_range(cipher, min_vers, |
71 | 487k | max_vers)) |
72 | 0 | continue; |
73 | 487k | if (!ssl_security_cipher_check(s, cipher)) |
74 | 169k | continue; |
75 | 317k | if (!CBB_add_u16(cbb, ssl3_cipher_get_value(cipher))) |
76 | 0 | return 0; |
77 | | |
78 | 317k | num_ciphers++; |
79 | 317k | } |
80 | | |
81 | | /* Add SCSV if there are other ciphers and we're not renegotiating. */ |
82 | 6.76k | if (num_ciphers > 0 && !s->internal->renegotiate) { |
83 | 6.76k | if (!CBB_add_u16(cbb, SSL3_CK_SCSV & SSL3_CK_VALUE_MASK)) |
84 | 0 | return 0; |
85 | 6.76k | } |
86 | | |
87 | 6.76k | if (!CBB_flush(cbb)) |
88 | 0 | return 0; |
89 | | |
90 | 6.76k | return 1; |
91 | 6.76k | } |
92 | | |
93 | | STACK_OF(SSL_CIPHER) * |
94 | | ssl_bytes_to_cipher_list(SSL *s, CBS *cbs) |
95 | 5.40k | { |
96 | 5.40k | STACK_OF(SSL_CIPHER) *ciphers = NULL; |
97 | 5.40k | const SSL_CIPHER *cipher; |
98 | 5.40k | uint16_t cipher_value; |
99 | 5.40k | unsigned long cipher_id; |
100 | | |
101 | 5.40k | s->s3->send_connection_binding = 0; |
102 | | |
103 | 5.40k | if ((ciphers = sk_SSL_CIPHER_new_null()) == NULL) { |
104 | 0 | SSLerror(s, ERR_R_MALLOC_FAILURE); |
105 | 0 | goto err; |
106 | 0 | } |
107 | | |
108 | 64.6k | while (CBS_len(cbs) > 0) { |
109 | 59.2k | if (!CBS_get_u16(cbs, &cipher_value)) { |
110 | 21 | SSLerror(s, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); |
111 | 21 | goto err; |
112 | 21 | } |
113 | | |
114 | 59.2k | cipher_id = SSL3_CK_ID | cipher_value; |
115 | | |
116 | 59.2k | if (cipher_id == SSL3_CK_SCSV) { |
117 | | /* |
118 | | * TLS_EMPTY_RENEGOTIATION_INFO_SCSV is fatal if |
119 | | * renegotiating. |
120 | | */ |
121 | 478 | if (s->internal->renegotiate) { |
122 | 0 | SSLerror(s, SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING); |
123 | 0 | ssl3_send_alert(s, SSL3_AL_FATAL, |
124 | 0 | SSL_AD_HANDSHAKE_FAILURE); |
125 | |
|
126 | 0 | goto err; |
127 | 0 | } |
128 | 478 | s->s3->send_connection_binding = 1; |
129 | 478 | continue; |
130 | 478 | } |
131 | | |
132 | 58.7k | if (cipher_id == SSL3_CK_FALLBACK_SCSV) { |
133 | | /* |
134 | | * TLS_FALLBACK_SCSV indicates that the client |
135 | | * previously tried a higher protocol version. |
136 | | * Fail if the current version is an unexpected |
137 | | * downgrade. |
138 | | */ |
139 | 76 | if (s->s3->hs.negotiated_tls_version < |
140 | 76 | s->s3->hs.our_max_tls_version) { |
141 | 2 | SSLerror(s, SSL_R_INAPPROPRIATE_FALLBACK); |
142 | 2 | ssl3_send_alert(s, SSL3_AL_FATAL, |
143 | 2 | SSL_AD_INAPPROPRIATE_FALLBACK); |
144 | 2 | goto err; |
145 | 2 | } |
146 | 74 | continue; |
147 | 76 | } |
148 | | |
149 | 58.6k | if ((cipher = ssl3_get_cipher_by_value(cipher_value)) != NULL) { |
150 | 15.2k | if (!sk_SSL_CIPHER_push(ciphers, cipher)) { |
151 | 0 | SSLerror(s, ERR_R_MALLOC_FAILURE); |
152 | 0 | goto err; |
153 | 0 | } |
154 | 15.2k | } |
155 | 58.6k | } |
156 | | |
157 | 5.38k | return (ciphers); |
158 | | |
159 | 23 | err: |
160 | 23 | sk_SSL_CIPHER_free(ciphers); |
161 | | |
162 | 23 | return (NULL); |
163 | 5.40k | } |
164 | | |
165 | | struct ssl_tls13_ciphersuite { |
166 | | const char *name; |
167 | | const char *alias; |
168 | | unsigned long cid; |
169 | | }; |
170 | | |
171 | | static const struct ssl_tls13_ciphersuite ssl_tls13_ciphersuites[] = { |
172 | | { |
173 | | .name = TLS1_3_RFC_AES_128_GCM_SHA256, |
174 | | .alias = TLS1_3_TXT_AES_128_GCM_SHA256, |
175 | | .cid = TLS1_3_CK_AES_128_GCM_SHA256, |
176 | | }, |
177 | | { |
178 | | .name = TLS1_3_RFC_AES_256_GCM_SHA384, |
179 | | .alias = TLS1_3_TXT_AES_256_GCM_SHA384, |
180 | | .cid = TLS1_3_CK_AES_256_GCM_SHA384, |
181 | | }, |
182 | | { |
183 | | .name = TLS1_3_RFC_CHACHA20_POLY1305_SHA256, |
184 | | .alias = TLS1_3_TXT_CHACHA20_POLY1305_SHA256, |
185 | | .cid = TLS1_3_CK_CHACHA20_POLY1305_SHA256, |
186 | | }, |
187 | | { |
188 | | .name = TLS1_3_RFC_AES_128_CCM_SHA256, |
189 | | .alias = TLS1_3_TXT_AES_128_CCM_SHA256, |
190 | | .cid = TLS1_3_CK_AES_128_CCM_SHA256, |
191 | | }, |
192 | | { |
193 | | .name = TLS1_3_RFC_AES_128_CCM_8_SHA256, |
194 | | .alias = TLS1_3_TXT_AES_128_CCM_8_SHA256, |
195 | | .cid = TLS1_3_CK_AES_128_CCM_8_SHA256, |
196 | | }, |
197 | | { |
198 | | .name = NULL, |
199 | | }, |
200 | | }; |
201 | | |
202 | | int |
203 | | ssl_parse_ciphersuites(STACK_OF(SSL_CIPHER) **out_ciphers, const char *str) |
204 | 0 | { |
205 | 0 | const struct ssl_tls13_ciphersuite *ciphersuite; |
206 | 0 | STACK_OF(SSL_CIPHER) *ciphers; |
207 | 0 | const SSL_CIPHER *cipher; |
208 | 0 | char *s = NULL; |
209 | 0 | char *p, *q; |
210 | 0 | int i; |
211 | 0 | int ret = 0; |
212 | |
|
213 | 0 | if ((ciphers = sk_SSL_CIPHER_new_null()) == NULL) |
214 | 0 | goto err; |
215 | | |
216 | | /* An empty string is valid and means no ciphers. */ |
217 | 0 | if (strcmp(str, "") == 0) |
218 | 0 | goto done; |
219 | | |
220 | 0 | if ((s = strdup(str)) == NULL) |
221 | 0 | goto err; |
222 | | |
223 | 0 | q = s; |
224 | 0 | while ((p = strsep(&q, ":")) != NULL) { |
225 | 0 | ciphersuite = &ssl_tls13_ciphersuites[0]; |
226 | 0 | for (i = 0; ciphersuite->name != NULL; i++) { |
227 | 0 | if (strcmp(p, ciphersuite->name) == 0) |
228 | 0 | break; |
229 | 0 | if (strcmp(p, ciphersuite->alias) == 0) |
230 | 0 | break; |
231 | 0 | ciphersuite = &ssl_tls13_ciphersuites[i]; |
232 | 0 | } |
233 | 0 | if (ciphersuite->name == NULL) |
234 | 0 | goto err; |
235 | | |
236 | | /* We know about the cipher suite, but it is not supported. */ |
237 | 0 | if ((cipher = ssl3_get_cipher_by_id(ciphersuite->cid)) == NULL) |
238 | 0 | continue; |
239 | | |
240 | 0 | if (!sk_SSL_CIPHER_push(ciphers, cipher)) |
241 | 0 | goto err; |
242 | 0 | } |
243 | | |
244 | 0 | done: |
245 | 0 | sk_SSL_CIPHER_free(*out_ciphers); |
246 | 0 | *out_ciphers = ciphers; |
247 | 0 | ciphers = NULL; |
248 | 0 | ret = 1; |
249 | |
|
250 | 0 | err: |
251 | 0 | sk_SSL_CIPHER_free(ciphers); |
252 | 0 | free(s); |
253 | |
|
254 | 0 | return ret; |
255 | 0 | } |
256 | | |
257 | | int |
258 | | ssl_merge_cipherlists(STACK_OF(SSL_CIPHER) *cipherlist, |
259 | | STACK_OF(SSL_CIPHER) *cipherlist_tls13, |
260 | | STACK_OF(SSL_CIPHER) **out_cipherlist) |
261 | 0 | { |
262 | 0 | STACK_OF(SSL_CIPHER) *ciphers = NULL; |
263 | 0 | const SSL_CIPHER *cipher; |
264 | 0 | int i, ret = 0; |
265 | |
|
266 | 0 | if ((ciphers = sk_SSL_CIPHER_dup(cipherlist_tls13)) == NULL) |
267 | 0 | goto err; |
268 | 0 | for (i = 0; i < sk_SSL_CIPHER_num(cipherlist); i++) { |
269 | 0 | cipher = sk_SSL_CIPHER_value(cipherlist, i); |
270 | 0 | if (cipher->algorithm_ssl == SSL_TLSV1_3) |
271 | 0 | continue; |
272 | 0 | if (!sk_SSL_CIPHER_push(ciphers, cipher)) |
273 | 0 | goto err; |
274 | 0 | } |
275 | | |
276 | 0 | sk_SSL_CIPHER_free(*out_cipherlist); |
277 | 0 | *out_cipherlist = ciphers; |
278 | 0 | ciphers = NULL; |
279 | |
|
280 | 0 | ret = 1; |
281 | |
|
282 | 0 | err: |
283 | 0 | sk_SSL_CIPHER_free(ciphers); |
284 | |
|
285 | 0 | return ret; |
286 | 0 | } |