From 3f5b23403cfa893f51b8def07a430a25ec607fc8 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/6115) --- ssl/ssl.h | 2 +- ssl/ssl_lib.c | 29 +++++++++++++++++++---------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/ssl/ssl.h b/ssl/ssl.h index 3cf96a239b..bd545f65be 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -2149,7 +2149,7 @@ int SSL_get_fd(const SSL *s); int SSL_get_rfd(const SSL *s); int SSL_get_wfd(const SSL *s); const char *SSL_get_cipher_list(const SSL *s, int n); -char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len); +char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size); int SSL_get_read_ahead(const SSL *s); int SSL_pending(const SSL *s); # ifndef OPENSSL_NO_SOCK diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 3a6c1b14d4..3956dce317 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -1404,28 +1404,37 @@ int SSL_set_cipher_list(SSL *s, const char *str) } /* works well for SSLv2, not so good for SSLv3 */ -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; SSL_CIPHER *c; int i; - if ((s->session == NULL) || (s->session->ciphers == NULL) || (len < 2)) - return (NULL); + if (!s->server + || s->session == NULL + || s->session->ciphers == NULL + || size < 2) + return NULL; p = buf; - sk = s->session->ciphers; + clntsk = s->session->ciphers; + srvrsk = SSL_get_ciphers(s); + if (clntsk == NULL || srvrsk == NULL) + return NULL; - if (sk_SSL_CIPHER_num(sk) == 0) + if (sk_SSL_CIPHER_num(clntsk) == 0 || sk_SSL_CIPHER_num(srvrsk) == 0) return NULL; - for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { + 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'; @@ -1434,7 +1443,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); -- 2.25.1