From da5ab60e604de7c7f22df99fa6f45c0328d48ab6 Mon Sep 17 00:00:00 2001 From: tb <> Date: Sat, 9 Jan 2021 10:34:29 +0000 Subject: Align SSL_get_shared_ciphers() with OpenSSL SSL_get_shared_ciphers() has been quite broken forever (see BUGS). What's maybe even worse than those bugs is that it only ever returned the string representing the client's ciphers which happen to fit into buf. That's kind of odd, given its name. This commit brings it in line with OpenSSL's version which changed behavior almost three years ago. reviewed and stupid bug caught by schwarze ok beck inoguchi jsing commit a216df599a6076147c27acea6c976fb11f505b1a Author: Matt Caswell Date: Fri Apr 27 11:20:52 2018 +0100 Fix SSL_get_shared_ciphers() The function SSL_get_shared_ciphers() is supposed to return ciphers shared by the client and the server. However it only ever returned the client ciphers. Fixes #5317 Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/6113) --- src/lib/libssl/ssl_lib.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'src/lib') diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c index 69628b48df..0537cf0e46 100644 --- a/src/lib/libssl/ssl_lib.c +++ b/src/lib/libssl/ssl_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_lib.c,v 1.239 2020/12/01 07:46:01 tb Exp $ */ +/* $OpenBSD: ssl_lib.c,v 1.240 2021/01/09 10:34:29 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1484,22 +1484,30 @@ SSL_set_ciphersuites(SSL *s, const char *str) char * SSL_get_shared_ciphers(const SSL *s, char *buf, int len) { - STACK_OF(SSL_CIPHER) *ciphers; + STACK_OF(SSL_CIPHER) *client_ciphers, *server_ciphers; const SSL_CIPHER *cipher; size_t curlen = 0; char *end; int i; - if (s->session == NULL || s->session->ciphers == NULL || len < 2) - return (NULL); + if (!s->server || s->session == NULL || len < 2) + return NULL; - ciphers = s->session->ciphers; - if (sk_SSL_CIPHER_num(ciphers) == 0) - return (NULL); + if ((client_ciphers = s->session->ciphers) == NULL) + return NULL; + if ((server_ciphers = SSL_get_ciphers(s)) == NULL) + return NULL; + if (sk_SSL_CIPHER_num(client_ciphers) == 0 || + sk_SSL_CIPHER_num(server_ciphers) == 0) + return NULL; buf[0] = '\0'; - for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { - cipher = sk_SSL_CIPHER_value(ciphers, i); + for (i = 0; i < sk_SSL_CIPHER_num(client_ciphers); i++) { + cipher = sk_SSL_CIPHER_value(client_ciphers, i); + + if (sk_SSL_CIPHER_find(server_ciphers, cipher) < 0) + continue; + end = buf + curlen; if (strlcat(buf, cipher->name, len) >= len || (curlen = strlcat(buf, ":", len)) >= len) { @@ -1511,7 +1519,7 @@ SSL_get_shared_ciphers(const SSL *s, char *buf, int len) /* remove trailing colon */ if ((end = strrchr(buf, ':')) != NULL) *end = '\0'; - return (buf); + return buf; } /* -- cgit v1.2.3-55-g6feb