Allow return of supported ciphers. 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.
diff --git a/apps/ciphers.c b/apps/ciphers.c index c9abf1a..52da702 100644 --- a/apps/ciphers.c +++ b/apps/ciphers.c
@@ -85,6 +85,7 @@ { 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 @@ 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 @@ 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 @@ } else /* verbose */ { - sk=SSL_get_ciphers(ssl); for (i=0; i<sk_SSL_CIPHER_num(sk); i++) { @@ -237,6 +244,8 @@ 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);
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 9755a0f..70c6533 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c
@@ -1079,9 +1079,7 @@ /* 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);
diff --git a/ssl/ssl.h b/ssl/ssl.h index c6b1ac3..9c200b7 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h
@@ -2378,6 +2378,7 @@ 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);
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index cc9b965..1b8c0f4 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c
@@ -1342,6 +1342,33 @@ 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 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 @@ { 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)
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index cd397f4..07ea0d2 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h
@@ -1331,6 +1331,7 @@ 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);
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index c9e4898..37cc6f6 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c
@@ -1093,6 +1093,14 @@ 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;