From a216df599a6076147c27acea6c976fb11f505b1a Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Fri, 27 Apr 2018 11:20:52 +0100 Subject: [PATCH] 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) --- include/openssl/ssl.h | 2 +- ssl/ssl_lib.c | 29 +++++++++++++++++++---------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 4b45ae7e54..4bd53fc24c 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -1497,7 +1497,7 @@ __owur int SSL_get_fd(const SSL *s); __owur int SSL_get_rfd(const SSL *s); __owur int SSL_get_wfd(const SSL *s); __owur const char *SSL_get_cipher_list(const SSL *s, int n); -__owur char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len); +__owur char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size); __owur int SSL_get_read_ahead(const SSL *s); __owur int SSL_pending(const SSL *s); __owur int SSL_has_pending(const SSL *s); diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 2a57831bc7..3aefa34ab2 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -2549,28 +2549,37 @@ int SSL_set_cipher_list(SSL *s, const char *str) return 1; } -char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len) +char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size) { char *p; - STACK_OF(SSL_CIPHER) *sk; + STACK_OF(SSL_CIPHER) *clntsk, *srvrsk; const SSL_CIPHER *c; int i; - if ((s->session == NULL) || (s->session->ciphers == NULL) || (len < 2)) + if (!s->server + || s->session == NULL + || s->session->ciphers == NULL + || size < 2) return NULL; p = buf; - sk = s->session->ciphers; - - if (sk_SSL_CIPHER_num(sk) == 0) + clntsk = s->session->ciphers; + srvrsk = SSL_get_ciphers(s); + if (clntsk == NULL || srvrsk == NULL) return NULL; - for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { + if (sk_SSL_CIPHER_num(clntsk) == 0 || sk_SSL_CIPHER_num(srvrsk) == 0) + return NULL; + + for (i = 0; i < sk_SSL_CIPHER_num(clntsk); i++) { int n; - c = sk_SSL_CIPHER_value(sk, i); + c = sk_SSL_CIPHER_value(clntsk, i); + if (sk_SSL_CIPHER_find(srvrsk, c) < 0) + continue; + n = strlen(c->name); - if (n + 1 > len) { + if (n + 1 > size) { if (p != buf) --p; *p = '\0'; @@ -2579,7 +2588,7 @@ char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len) strcpy(p, c->name); p += n; *(p++) = ':'; - len -= n + 1; + size -= n + 1; } p[-1] = '\0'; return buf;