On Sun, Sep 03, 2006 at 08:51:50PM +0200, Vlad W. wrote:

> Working on openssl library upgrade from 0.9.7d to 0.9.8a I found a
> change in explicit cipher name behaviour.
>
> E.g., in version 0.9.7
> "openssl ciphers -v RC4-MD5" gets 2 ciphers named RC4-MD5, for SSLv3 and
> SSLv2,
> and
> "openssl ciphers -v AES128-SHA" gets the single cipher, as was expected.
>
> In 0.9.8a this command in the first case behaves in the same way, but
> in the second case both AES128-SHA and AES256-SHA was returned.
>
> I found a change in the version 0.9.8b (Check-in Number: 15185) which
> has fixed the problem in the case of AES ciphers.
>
> However, the same change affects the case of the same name and
> different protocols, e.g., there is only SSLv3 RC4-MD5 cipher in the
> first example output. The similar problem occur in any case when same
> cipher name exist in both SSLv3 and SSLv2: when first cipher_id is
> found in ssl_cipher_process_rulestr function (from the check-in
> 15185), the function does not continue the searching process.
>
> Thus, both openssl 0.9.8a and 0.9.8b behave differently from 0.9.7
> branch. I'm confused which behaviour is correct, but the both of the
> new ones seem to be problematical. They cause to either wrong cipher
> using (AES128-SHA instead of AES256-SHA in 0.9.8a) or SSLv2 connection
> failure (in 0.9.8b).
>
> Could you comment that and to suggest a solution?


First, clearly you have found a bug.

Question: Are you sure about the 0.9.7 (or 0.9.7d) behavior regarding
"AES128-SHA"? What is the exact OpenSSL version? Given the structure
of the internal tables, code that matches two ciphersuites for
"RC4-MD5" (SSLv2 and SSLv3) should match two ciphersuites for
"AES128-SHA" as well (AES128-SHA and AES256-SHA). This is because
there currently only is a single bit that indicates AES, be it AES128
or AES256, so the AES128-SHA and AES256-SHA ciphersuites are described
through the same bit pattern in the table that is used for ciphersuite
string processing. If "AES128-SHA" or "RC4-MD5" is interpreted as a
rule for ciphersuite matching (where said rule is given by the bit-map
description of a ciphersuite with the respective name), then there
will be multiple ciphersuites found for the respective pattern.

Anyway. The proper way to fix this in OpenSSL is to extend the bit
masks so that we can get two bits for AES128 and AES256 instead of
just a single AES bit (and similarly for Camellia). Then "AES128-SHA"
will give a pattern that matches just the AES128-SHA ciphersuite,
and not AES256-SHA as well.

For now, please try the following patch, play around with various
ciphersuite description strings that you can think of, and let me know
if it appears to work properly. (This patch is for the 0.9.8 branch,
trivial manual editing would be required for applying it to the 0.9.9
branch.)


Index: ssl_ciph.c
================================================== =================
RCS file: /e/openssl/cvs/openssl/ssl/ssl_ciph.c,v
retrieving revision 1.49.2.11
diff -u -r1.49.2.11 ssl_ciph.c
--- ssl_ciph.c 2 Jul 2006 14:43:21 -0000 1.49.2.11
+++ ssl_ciph.c 6 Sep 2006 09:13:31 -0000
@@ -565,7 +565,7 @@
*ca_curr = NULL; /* end of list */
}

-static void ssl_cipher_apply_rule(unsigned long cipher_id,
+static void ssl_cipher_apply_rule(unsigned long cipher_id, unsigned long ssl_version,
unsigned long algorithms, unsigned long mask,
unsigned long algo_strength, unsigned long mask_strength,
int rule, int strength_bits, CIPHER_ORDER *co_list,
@@ -592,9 +592,10 @@

cp = curr->cipher;

- /* If explicit cipher suite match that one only */
+ /* If explicit cipher suite, match only that one for its own protocol version.
+ * Usual selection criteria will be used for similar ciphersuites from other version! */

- if (cipher_id)
+ if (cipher_id && (cp->algorithms & SSL_SSL_MASK) == ssl_version)
{
if (cp->id != cipher_id)
continue;
@@ -731,7 +732,7 @@
*/
for (i = max_strength_bits; i >= 0; i--)
if (number_uses[i] > 0)
- ssl_cipher_apply_rule(0, 0, 0, 0, 0, CIPHER_ORD, i,
+ ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, CIPHER_ORD, i,
co_list, head_p, tail_p);

OPENSSL_free(number_uses);
@@ -745,7 +746,7 @@
unsigned long algorithms, mask, algo_strength, mask_strength;
const char *l, *start, *buf;
int j, multi, found, rule, retval, ok, buflen;
- unsigned long cipher_id = 0;
+ unsigned long cipher_id = 0, ssl_version = 0;
char ch;

retval = 1;
@@ -836,6 +837,7 @@
*/
j = found = 0;
cipher_id = 0;
+ ssl_version = 0;
while (ca_list[j])
{
if (!strncmp(buf, ca_list[j]->name, buflen) &&
@@ -850,12 +852,6 @@
if (!found)
break; /* ignore this entry */

- if (ca_list[j]->valid)
- {
- cipher_id = ca_list[j]->id;
- break;
- }
-
/* New algorithms:
* 1 - any old restrictions apply outside new mask
* 2 - any new restrictions apply outside old mask
@@ -870,6 +866,14 @@
(algo_strength & ca_list[j]->algo_strength);
mask_strength |= ca_list[j]->mask_strength;

+ /* explicit ciphersuite found */
+ if (ca_list[j]->valid)
+ {
+ cipher_id = ca_list[j]->id;
+ ssl_version = ca_list[j]->algorithms & SSL_SSL_MASK;
+ break;
+ }
+
if (!multi) break;
}

@@ -899,7 +903,7 @@
}
else if (found)
{
- ssl_cipher_apply_rule(cipher_id, algorithms, mask,
+ ssl_cipher_apply_rule(cipher_id, ssl_version, algorithms, mask,
algo_strength, mask_strength, rule, -1,
co_list, head_p, tail_p);
}
__________________________________________________ ____________________
OpenSSL Project http://www.openssl.org
Development Mailing List openssl-dev@openssl.org
Automated List Manager majordomo@openssl.org