summaryrefslogtreecommitdiff
path: root/src/lib/libssl/ssl_ciphers.c
diff options
context:
space:
mode:
authorjsing <>2020-09-13 16:49:05 +0000
committerjsing <>2020-09-13 16:49:05 +0000
commit0aa52b54c9a57f9625af2c4445b991cfdd4ad228 (patch)
treee245dcd6ff9d7a9822feff50c7792c76ecfa9dba /src/lib/libssl/ssl_ciphers.c
parenta328631fddec2556ad8af08ce4de240790c537c9 (diff)
downloadopenbsd-0aa52b54c9a57f9625af2c4445b991cfdd4ad228.tar.gz
openbsd-0aa52b54c9a57f9625af2c4445b991cfdd4ad228.tar.bz2
openbsd-0aa52b54c9a57f9625af2c4445b991cfdd4ad228.zip
Implement SSL_{CTX_,}set_ciphersuites().
OpenSSL added a separate API for configuring TLSv1.3 ciphersuites. Provide this API, while retaining the current behaviour of being able to configure TLSv1.3 via the existing interface. Note that this is not currently exposed in the headers/exported symbols. ok beck@ inoguchi@ tb@
Diffstat (limited to 'src/lib/libssl/ssl_ciphers.c')
-rw-r--r--src/lib/libssl/ssl_ciphers.c129
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
175struct ssl_tls13_ciphersuite {
176 const char *name;
177 const char *alias;
178 unsigned long cid;
179};
180
181static 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
212int
213ssl_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
269int
270ssl_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}