Allow return of supported ciphers.
authorDr. Stephen Henson <steve@openssl.org>
Tue, 14 Jan 2014 14:55:21 +0000 (14:55 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Fri, 28 Mar 2014 14:49:04 +0000 (14:49 +0000)
New function ssl_cipher_disabled.

Check for disabled client ciphers using ssl_cipher_disabled.

New function to return only supported ciphers.

New option to ciphers utility to print only supported ciphers.

apps/ciphers.c
ssl/s3_clnt.c
ssl/ssl.h
ssl/ssl_lib.c
ssl/ssl_locl.h
ssl/t1_lib.c

index c9abf1a05a78c609735aa7ac8f78dc96a7fe768d..52da70245a89d9ad3aec6a3f65900ed216519cd3 100644 (file)
@@ -85,6 +85,7 @@ int MAIN(int argc, char **argv)
        {
        int ret=1,i;
        int verbose=0,Verbose=0;
+       int use_supported = 0;
 #ifndef OPENSSL_NO_SSL_TRACE
        int stdname = 0;
 #endif
@@ -129,6 +130,8 @@ int MAIN(int argc, char **argv)
                        verbose=1;
                else if (strcmp(*argv,"-V") == 0)
                        verbose=Verbose=1;
+               else if (strcmp(*argv,"-s") == 0)
+                       use_supported = 1;
 #ifndef OPENSSL_NO_SSL_TRACE
                else if (strcmp(*argv,"-stdname") == 0)
                        stdname=verbose=1;
@@ -179,12 +182,17 @@ int MAIN(int argc, char **argv)
        ssl=SSL_new(ctx);
        if (ssl == NULL) goto err;
 
+       if (use_supported)
+               sk=SSL_get1_supported_ciphers(ssl);
+       else
+               sk=SSL_get_ciphers(ssl);
 
        if (!verbose)
                {
-               for (i=0; ; i++)
+               for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
                        {
-                       p=SSL_get_cipher_list(ssl,i);
+                       SSL_CIPHER *c = sk_SSL_CIPHER_value(sk,i);
+                       p = SSL_CIPHER_get_name(c);
                        if (p == NULL) break;
                        if (i != 0) BIO_printf(STDout,":");
                        BIO_printf(STDout,"%s",p);
@@ -193,7 +201,6 @@ int MAIN(int argc, char **argv)
                }
        else /* verbose */
                {
-               sk=SSL_get_ciphers(ssl);
 
                for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
                        {
@@ -237,6 +244,8 @@ err:
                ERR_print_errors(bio_err);
                }
 end:
+       if (use_supported && sk)
+               sk_SSL_CIPHER_free(sk);
        if (ctx != NULL) SSL_CTX_free(ctx);
        if (ssl != NULL) SSL_free(ssl);
        if (STDout != NULL) BIO_free_all(STDout);
index 9755a0feb2ee58ac40b3b47f7a0f0b798dec317a..70c6533268a0ab26e2f8c954c41daebdab0136db 100644 (file)
@@ -1079,9 +1079,7 @@ int ssl3_get_server_hello(SSL *s)
        /* If it is a disabled cipher we didn't send it in client hello,
         * so return an error.
         */
-       if (c->algorithm_ssl & ct->mask_ssl ||
-               c->algorithm_mkey & ct->mask_k ||
-               c->algorithm_auth & ct->mask_a)
+       if (ssl_cipher_disabled(s, c))
                {
                al=SSL_AD_ILLEGAL_PARAMETER;
                SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_WRONG_CIPHER_RETURNED);
index c6b1ac35f91863036cfa26c490d9305f321cc76e..9c200b798e69865447592b4631ebb588e86da73a 100644 (file)
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -2378,6 +2378,7 @@ const SSL_METHOD *DTLS_server_method(void);       /* DTLS 1.0 and 1.2 */
 const SSL_METHOD *DTLS_client_method(void);    /* DTLS 1.0 and 1.2 */
 
 STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s);
+STACK_OF(SSL_CIPHER) *SSL_get1_supported_ciphers(SSL *s);
 
 int SSL_do_handshake(SSL *s);
 int SSL_renegotiate(SSL *s);
index cc9b965778e5bcf4e13e1930823d1dfa394d038f..1b8c0f42bc7955417c82a14af58e5ab4ca311a5c 100644 (file)
@@ -1342,6 +1342,33 @@ STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s)
        return(NULL);
        }
 
+STACK_OF(SSL_CIPHER) *SSL_get1_supported_ciphers(SSL *s)
+       {
+       STACK_OF(SSL_CIPHER) *sk = NULL, *ciphers;
+       int i;
+       ciphers = SSL_get_ciphers(s);
+       if (!ciphers)
+               return NULL;
+       ssl_set_client_disabled(s);
+       for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++)
+               {
+               const SSL_CIPHER *c = sk_SSL_CIPHER_value(ciphers, i);
+               if (!ssl_cipher_disabled(s, c))
+                       {
+                       if (!sk)
+                               sk = sk_SSL_CIPHER_new_null();
+                       if (!sk)
+                               return NULL;
+                       if (!sk_SSL_CIPHER_push(sk, c))
+                               {
+                               sk_SSL_CIPHER_free(sk);
+                               return NULL;
+                               }
+                       }
+               }
+       return sk;
+       }
+
 /** return a STACK of the ciphers available for the SSL and in order of
  * algorithm id */
 STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s)
@@ -1459,7 +1486,6 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
        {
        int i,j=0;
        SSL_CIPHER *c;
-       CERT *ct = s->cert;
        unsigned char *q;
        int no_scsv = s->renegotiate;
        /* Set disabled masks for this session */
@@ -1472,9 +1498,7 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
                {
                c=sk_SSL_CIPHER_value(sk,i);
                /* Skip disabled ciphers */
-               if (c->algorithm_ssl & ct->mask_ssl ||
-                       c->algorithm_mkey & ct->mask_k ||
-                       c->algorithm_auth & ct->mask_a)
+               if (ssl_cipher_disabled(s, c))
                        continue;
 #ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
                if (c->id == SSL3_CK_SCSV)
index cd397f45d2526818627ce24014bd8b3db614046e..07ea0d297204b69ea6cd20a14de146bc9c0f25c6 100644 (file)
@@ -1331,6 +1331,7 @@ size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs);
 int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s,
                                const unsigned char *sig, EVP_PKEY *pkey);
 void ssl_set_client_disabled(SSL *s);
+int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c);
 
 int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen);
 int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al);
index c9e489898a4060bb0982a23027f37d7c2fe80d7d..37cc6f6abfe01546371c1b3530606b76ecf8b1d5 100644 (file)
@@ -1093,6 +1093,14 @@ void ssl_set_client_disabled(SSL *s)
        c->valid = 1;
        }
 
+int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c)
+       {
+       CERT *ct = s->cert;
+       if (c->algorithm_ssl & ct->mask_ssl || c->algorithm_mkey & ct->mask_k || c->algorithm_auth & ct->mask_a)
+               return 1;
+       return 0;
+       }
+
 unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit, int *al)
        {
        int extdatalen=0;