diff options
Diffstat (limited to 'src/lib/libssl/ssl_ciphers.c')
-rw-r--r-- | src/lib/libssl/ssl_ciphers.c | 129 |
1 files changed, 127 insertions, 2 deletions
diff --git a/src/lib/libssl/ssl_ciphers.c b/src/lib/libssl/ssl_ciphers.c index 478238bd10..d84e4c6154 100644 --- a/src/lib/libssl/ssl_ciphers.c +++ b/src/lib/libssl/ssl_ciphers.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* $OpenBSD: ssl_ciphers.c,v 1.6 2020/09/11 17:36:27 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_ciphers.c,v 1.7 2020/09/13 16:49:05 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2015-2017 Doug Hogan <doug@openbsd.org> | 3 | * Copyright (c) 2015-2017 Doug Hogan <doug@openbsd.org> |
4 | * Copyright (c) 2015-2018 Joel Sing <jsing@openbsd.org> | 4 | * Copyright (c) 2015-2018, 2020 Joel Sing <jsing@openbsd.org> |
5 | * Copyright (c) 2019 Theo Buehler <tb@openbsd.org> | 5 | * Copyright (c) 2019 Theo Buehler <tb@openbsd.org> |
6 | * | 6 | * |
7 | * Permission to use, copy, modify, and distribute this software for any | 7 | * Permission to use, copy, modify, and distribute this software for any |
@@ -171,3 +171,128 @@ ssl_bytes_to_cipher_list(SSL *s, CBS *cbs) | |||
171 | 171 | ||
172 | return (NULL); | 172 | return (NULL); |
173 | } | 173 | } |
174 | |||
175 | struct ssl_tls13_ciphersuite { | ||
176 | const char *name; | ||
177 | const char *alias; | ||
178 | unsigned long cid; | ||
179 | }; | ||
180 | |||
181 | static const struct ssl_tls13_ciphersuite ssl_tls13_ciphersuites[] = { | ||
182 | { | ||
183 | .name = TLS1_3_TXT_AES_128_GCM_SHA256, | ||
184 | .alias = "TLS_AES_128_GCM_SHA256", | ||
185 | .cid = TLS1_3_CK_AES_128_GCM_SHA256, | ||
186 | }, | ||
187 | { | ||
188 | .name = TLS1_3_TXT_AES_256_GCM_SHA384, | ||
189 | .alias = "TLS_AES_256_GCM_SHA384", | ||
190 | .cid = TLS1_3_CK_AES_256_GCM_SHA384, | ||
191 | }, | ||
192 | { | ||
193 | .name = TLS1_3_TXT_CHACHA20_POLY1305_SHA256, | ||
194 | .alias = "TLS_CHACHA20_POLY1305_SHA256", | ||
195 | .cid = TLS1_3_CK_CHACHA20_POLY1305_SHA256, | ||
196 | }, | ||
197 | { | ||
198 | .name = TLS1_3_TXT_AES_128_CCM_SHA256, | ||
199 | .alias = "TLS_AES_128_CCM_SHA256", | ||
200 | .cid = TLS1_3_CK_AES_128_CCM_SHA256, | ||
201 | }, | ||
202 | { | ||
203 | .name = TLS1_3_TXT_AES_128_CCM_8_SHA256, | ||
204 | .alias = "TLS_AES_128_CCM_8_SHA256", | ||
205 | .cid = TLS1_3_CK_AES_128_CCM_8_SHA256, | ||
206 | }, | ||
207 | { | ||
208 | .name = NULL, | ||
209 | }, | ||
210 | }; | ||
211 | |||
212 | int | ||
213 | ssl_parse_ciphersuites(STACK_OF(SSL_CIPHER) **out_ciphers, const char *str) | ||
214 | { | ||
215 | const struct ssl_tls13_ciphersuite *ciphersuite; | ||
216 | STACK_OF(SSL_CIPHER) *ciphers; | ||
217 | const SSL_CIPHER *cipher; | ||
218 | char *s = NULL; | ||
219 | char *p, *q; | ||
220 | int i; | ||
221 | int ret = 0; | ||
222 | |||
223 | sk_SSL_CIPHER_free(*out_ciphers); | ||
224 | *out_ciphers = NULL; | ||
225 | |||
226 | if ((ciphers = sk_SSL_CIPHER_new_null()) == NULL) | ||
227 | goto err; | ||
228 | |||
229 | /* An empty string is valid and means no ciphers. */ | ||
230 | if (strcmp(str, "") == 0) | ||
231 | goto done; | ||
232 | |||
233 | if ((s = strdup(str)) == NULL) | ||
234 | goto err; | ||
235 | |||
236 | q = s; | ||
237 | while ((p = strsep(&q, ":")) != NULL) { | ||
238 | ciphersuite = &ssl_tls13_ciphersuites[0]; | ||
239 | for (i = 0; ciphersuite->name != NULL; i++) { | ||
240 | ciphersuite = &ssl_tls13_ciphersuites[i]; | ||
241 | if (strcmp(p, ciphersuite->name) == 0) | ||
242 | break; | ||
243 | if (strcmp(p, ciphersuite->alias) == 0) | ||
244 | break; | ||
245 | } | ||
246 | if (ciphersuite->name == NULL) | ||
247 | goto err; | ||
248 | |||
249 | /* We know about the cipher suite, but it is not supported. */ | ||
250 | if ((cipher = ssl3_get_cipher_by_id(ciphersuite->cid)) == NULL) | ||
251 | continue; | ||
252 | |||
253 | if (!sk_SSL_CIPHER_push(ciphers, cipher)) | ||
254 | goto err; | ||
255 | } | ||
256 | |||
257 | done: | ||
258 | *out_ciphers = ciphers; | ||
259 | ciphers = NULL; | ||
260 | ret = 1; | ||
261 | |||
262 | err: | ||
263 | sk_SSL_CIPHER_free(ciphers); | ||
264 | free(s); | ||
265 | |||
266 | return ret; | ||
267 | } | ||
268 | |||
269 | int | ||
270 | ssl_merge_cipherlists(STACK_OF(SSL_CIPHER) *cipherlist, | ||
271 | STACK_OF(SSL_CIPHER) *cipherlist_tls13, | ||
272 | STACK_OF(SSL_CIPHER) **out_cipherlist) | ||
273 | { | ||
274 | STACK_OF(SSL_CIPHER) *ciphers = NULL; | ||
275 | const SSL_CIPHER *cipher; | ||
276 | int i, ret = 0; | ||
277 | |||
278 | if ((ciphers = sk_SSL_CIPHER_dup(cipherlist_tls13)) == NULL) | ||
279 | goto err; | ||
280 | for (i = 0; i < sk_SSL_CIPHER_num(cipherlist); i++) { | ||
281 | cipher = sk_SSL_CIPHER_value(cipherlist, i); | ||
282 | if (cipher->algorithm_ssl == SSL_TLSV1_3) | ||
283 | continue; | ||
284 | if (!sk_SSL_CIPHER_push(ciphers, cipher)) | ||
285 | goto err; | ||
286 | } | ||
287 | |||
288 | sk_SSL_CIPHER_free(*out_cipherlist); | ||
289 | *out_cipherlist = ciphers; | ||
290 | ciphers = NULL; | ||
291 | |||
292 | ret = 1; | ||
293 | |||
294 | err: | ||
295 | sk_SSL_CIPHER_free(ciphers); | ||
296 | |||
297 | return ret; | ||
298 | } | ||