diff --git a/apps/ciphers.c b/apps/ciphers.c index c9abf1a05a78c609735aa7ac8f78dc96a7fe768d..52da70245a89d9ad3aec6a3f65900ed216519cd3 100644 --- a/apps/ciphers.c +++ b/apps/ciphers.c @@ -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); diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 9755a0feb2ee58ac40b3b47f7a0f0b798dec317a..70c6533268a0ab26e2f8c954c41daebdab0136db 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -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); diff --git a/ssl/ssl.h b/ssl/ssl.h index c6b1ac35f91863036cfa26c490d9305f321cc76e..9c200b798e69865447592b4631ebb588e86da73a 100644 --- 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); diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index cc9b965778e5bcf4e13e1930823d1dfa394d038f..1b8c0f42bc7955417c82a14af58e5ab4ca311a5c 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -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) diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index cd397f45d2526818627ce24014bd8b3db614046e..07ea0d297204b69ea6cd20a14de146bc9c0f25c6 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -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); diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index c9e489898a4060bb0982a23027f37d7c2fe80d7d..37cc6f6abfe01546371c1b3530606b76ecf8b1d5 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -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;