Some fixes for ciphersuite string processing:

- add a workaround provided by Victor Duchovni so that 128- and
  256-bit variants of otherwise identical ciphersuites are treated
  correctly;

- also, correctly skip invalid parts of ciphersuite description strings.

Submitted by: Victor Duchovni, Bodo Moeller
This commit is contained in:
Bodo Möller 2007-02-17 06:52:42 +00:00
parent d31a13953c
commit 5f4cc234fb
4 changed files with 51 additions and 15 deletions

12
CHANGES
View File

@ -4,6 +4,13 @@
Changes between 0.9.8d and 0.9.8e [XX xxx XXXX] Changes between 0.9.8d and 0.9.8e [XX xxx XXXX]
*) Since AES128 and AES256 (and similarly Camellia128 and
Camellia256) share a single mask bit in the logic of
ssl/ssl_ciph.c, the code for masking out disabled ciphers needs a
kludge to work properly if AES128 is available and AES256 isn't
(or if Camellia128 is available and Camellia256 isn't).
[Victor Duchovni]
*) Fix the BIT STRING encoding generated by crypto/ec/ec_asn1.c *) Fix the BIT STRING encoding generated by crypto/ec/ec_asn1.c
(within i2d_ECPrivateKey, i2d_ECPKParameters, i2d_ECParameters): (within i2d_ECPrivateKey, i2d_ECPKParameters, i2d_ECParameters):
When a point or a seed is encoded in a BIT STRING, we need to When a point or a seed is encoded in a BIT STRING, we need to
@ -1033,6 +1040,11 @@
Changes between 0.9.7l and 0.9.7m [xx XXX xxxx] Changes between 0.9.7l and 0.9.7m [xx XXX xxxx]
*) Since AES128 and AES256 share a single mask bit in the logic of
ssl/ssl_ciph.c, the code for masking out disabled ciphers needs a
kludge to work properly if AES128 is available and AES256 isn't.
[Victor Duchovni]
*) Have SSL/TLS server implementation tolerate "mismatched" record *) Have SSL/TLS server implementation tolerate "mismatched" record
protocol version while receiving ClientHello even if the protocol version while receiving ClientHello even if the
ClientHello is fragmented. (The server can't insist on the ClientHello is fragmented. (The server can't insist on the

View File

@ -12,7 +12,7 @@
--------------- ---------------
/* ==================================================================== /* ====================================================================
* Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions

2
README
View File

@ -1,7 +1,7 @@
OpenSSL 0.9.8e-dev XX xxx XXXX OpenSSL 0.9.8e-dev XX xxx XXXX
Copyright (c) 1998-2006 The OpenSSL Project Copyright (c) 1998-2007 The OpenSSL Project
Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
All rights reserved. All rights reserved.

View File

@ -432,9 +432,18 @@ static void ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr,
*tail=curr; *tail=curr;
} }
static unsigned long ssl_cipher_get_disabled(void) struct disabled_masks { /* This is a kludge no longer needed with OpenSSL 0.9.9,
* where 128-bit and 256-bit algorithms simply will get
* separate bits. */
unsigned long mask; /* everything except m256 */
unsigned long m256; /* applies to 256-bit algorithms only */
};
struct disabled_masks ssl_cipher_get_disabled(void)
{ {
unsigned long mask; unsigned long mask;
unsigned long m256;
struct disabled_masks ret;
mask = SSL_kFZA; mask = SSL_kFZA;
#ifdef OPENSSL_NO_RSA #ifdef OPENSSL_NO_RSA
@ -462,18 +471,26 @@ static unsigned long ssl_cipher_get_disabled(void)
mask |= (ssl_cipher_methods[SSL_ENC_RC2_IDX ] == NULL) ? SSL_RC2 :0; mask |= (ssl_cipher_methods[SSL_ENC_RC2_IDX ] == NULL) ? SSL_RC2 :0;
mask |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA:0; mask |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA:0;
mask |= (ssl_cipher_methods[SSL_ENC_eFZA_IDX] == NULL) ? SSL_eFZA:0; mask |= (ssl_cipher_methods[SSL_ENC_eFZA_IDX] == NULL) ? SSL_eFZA:0;
mask |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES:0;
mask |= (ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] == NULL) ? SSL_CAMELLIA:0;
mask |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0; mask |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0;
mask |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0; mask |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0;
return(mask); /* finally consider algorithms where mask and m256 differ */
m256 = mask;
mask |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES:0;
mask |= (ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] == NULL) ? SSL_CAMELLIA:0;
m256 |= (ssl_cipher_methods[SSL_ENC_AES256_IDX] == NULL) ? SSL_AES:0;
m256 |= (ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] == NULL) ? SSL_CAMELLIA:0;
ret.mask = mask;
ret.m256 = m256;
return ret;
} }
static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method,
int num_of_ciphers, unsigned long mask, CIPHER_ORDER *co_list, int num_of_ciphers, unsigned long mask, unsigned long m256,
CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) CIPHER_ORDER *co_list, CIPHER_ORDER **head_p,
CIPHER_ORDER **tail_p)
{ {
int i, co_list_num; int i, co_list_num;
SSL_CIPHER *c; SSL_CIPHER *c;
@ -490,8 +507,9 @@ static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method,
for (i = 0; i < num_of_ciphers; i++) for (i = 0; i < num_of_ciphers; i++)
{ {
c = ssl_method->get_cipher(i); c = ssl_method->get_cipher(i);
#define IS_MASKED(c) ((c)->algorithms & (((c)->alg_bits == 256) ? m256 : mask))
/* drop those that use any of that is not available */ /* drop those that use any of that is not available */
if ((c != NULL) && c->valid && !(c->algorithms & mask)) if ((c != NULL) && c->valid && !IS_MASKED(c))
{ {
co_list[co_list_num].cipher = c; co_list[co_list_num].cipher = c;
co_list[co_list_num].next = NULL; co_list[co_list_num].next = NULL;
@ -898,7 +916,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str,
* rest of the command, if any left, until * rest of the command, if any left, until
* end or ':' is found. * end or ':' is found.
*/ */
while ((*l != '\0') && ITEM_SEP(*l)) while ((*l != '\0') && !ITEM_SEP(*l))
l++; l++;
} }
else if (found) else if (found)
@ -909,7 +927,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str,
} }
else else
{ {
while ((*l != '\0') && ITEM_SEP(*l)) while ((*l != '\0') && !ITEM_SEP(*l))
l++; l++;
} }
if (*l == '\0') break; /* done */ if (*l == '\0') break; /* done */
@ -925,6 +943,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
{ {
int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases; int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases;
unsigned long disabled_mask; unsigned long disabled_mask;
unsigned long disabled_m256;
STACK_OF(SSL_CIPHER) *cipherstack, *tmp_cipher_list; STACK_OF(SSL_CIPHER) *cipherstack, *tmp_cipher_list;
const char *rule_p; const char *rule_p;
CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr; CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr;
@ -940,7 +959,12 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
* To reduce the work to do we only want to process the compiled * To reduce the work to do we only want to process the compiled
* in algorithms, so we first get the mask of disabled ciphers. * in algorithms, so we first get the mask of disabled ciphers.
*/ */
disabled_mask = ssl_cipher_get_disabled(); {
struct disabled_masks d;
d = ssl_cipher_get_disabled();
disabled_mask = d.mask;
disabled_m256 = d.m256;
}
/* /*
* Now we have to collect the available ciphers from the compiled * Now we have to collect the available ciphers from the compiled
@ -959,7 +983,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
} }
ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, disabled_mask, ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, disabled_mask,
co_list, &head, &tail); disabled_m256, co_list, &head, &tail);
/* /*
* We also need cipher aliases for selecting based on the rule_str. * We also need cipher aliases for selecting based on the rule_str.
@ -979,8 +1003,8 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE); SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE);
return(NULL); /* Failure */ return(NULL); /* Failure */
} }
ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, disabled_mask, ssl_cipher_collect_aliases(ca_list, num_of_group_aliases,
head); (disabled_mask & disabled_m256), head);
/* /*
* If the rule_string begins with DEFAULT, apply the default rule * If the rule_string begins with DEFAULT, apply the default rule