aboutsummaryrefslogtreecommitdiffstats
path: root/ssl/s3_lib.c
diff options
context:
space:
mode:
authorLutz Jänicke <jaenicke@openssl.org>2001-02-09 19:56:31 +0000
committerLutz Jänicke <jaenicke@openssl.org>2001-02-09 19:56:31 +0000
commit836f996010d6a5f38d9a13279c37e84a42819966 (patch)
treee5188ce6a43977577a5efb7884da010b9805c993 /ssl/s3_lib.c
parent1613c4d3bff02bd2715e0e8a61356e82f9c0e147 (diff)
downloadopenssl-836f996010d6a5f38d9a13279c37e84a42819966.tar.gz
New Option SSL_OP_CIPHER_SERVER_PREFERENCE allows TLS/SSLv3 server to override
the clients choice; in SSLv2 the client uses the server's preferences.
Diffstat (limited to 'ssl/s3_lib.c')
-rw-r--r--ssl/s3_lib.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 700a4ddbbf..76c499e67a 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -1364,10 +1364,11 @@ int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p)
return(2);
}
-SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *have,
- STACK_OF(SSL_CIPHER) *pref)
+SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
+ STACK_OF(SSL_CIPHER) *srvr)
{
SSL_CIPHER *c,*ret=NULL;
+ STACK_OF(SSL_CIPHER) *prio, *allow;
int i,j,ok;
CERT *cert;
unsigned long alg,mask,emask;
@@ -1375,20 +1376,45 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *have,
/* Let's see which ciphers we can support */
cert=s->cert;
- sk_SSL_CIPHER_set_cmp_func(pref,ssl_cipher_ptr_id_cmp);
+#if 0
+ /* Do not set the compare functions, because this may lead to a
+ * reordering by "id". We want to keep the original ordering.
+ * We may pay a price in performance during sk_SSL_CIPHER_find(),
+ * but would have to pay with the price of sk_SSL_CIPHER_dup().
+ */
+ sk_SSL_CIPHER_set_cmp_func(srvr, ssl_cipher_ptr_id_cmp);
+ sk_SSL_CIPHER_set_cmp_func(clnt, ssl_cipher_ptr_id_cmp);
+#endif
#ifdef CIPHER_DEBUG
- printf("Have %d from %p:\n", sk_SSL_CIPHER_num(pref), pref);
- for(i=0 ; i < sk_SSL_CIPHER_num(pref) ; ++i)
+ printf("Server has %d from %p:\n", sk_SSL_CIPHER_num(srvr), srvr);
+ for(i=0 ; i < sk_SSL_CIPHER_num(srvr) ; ++i)
+ {
+ c=sk_SSL_CIPHER_value(srvr,i);
+ printf("%p:%s\n",c,c->name);
+ }
+ printf("Client sent %d from %p:\n", sk_SSL_CIPHER_num(clnt), clnt);
+ for(i=0 ; i < sk_SSL_CIPHER_num(clnt) ; ++i)
{
- c=sk_SSL_CIPHER_value(pref,i);
+ c=sk_SSL_CIPHER_value(clnt,i);
printf("%p:%s\n",c,c->name);
}
#endif
- for (i=0; i<sk_SSL_CIPHER_num(have); i++)
+ if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
+ {
+ prio = srvr;
+ allow = clnt;
+ }
+ else
+ {
+ prio = clnt;
+ allow = srvr;
+ }
+
+ for (i=0; i<sk_SSL_CIPHER_num(prio); i++)
{
- c=sk_SSL_CIPHER_value(have,i);
+ c=sk_SSL_CIPHER_value(prio,i);
ssl_set_cert_masks(cert,c);
mask=cert->mask;
@@ -1418,10 +1444,10 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *have,
if (!ok) continue;
- j=sk_SSL_CIPHER_find(pref,c);
+ j=sk_SSL_CIPHER_find(allow,c);
if (j >= 0)
{
- ret=sk_SSL_CIPHER_value(pref,j);
+ ret=sk_SSL_CIPHER_value(allow,j);
break;
}
}