Fix another new bug in the cipherstring logic.
[openssl.git] / ssl / ssl_ciph.c
index 0320e372c04dd053a147b111ecf2fe55d8b17bec..4bee00cc6cefe2df837f8560a21c9a1880c8ee89 100644 (file)
@@ -480,7 +480,7 @@ static void ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr,
 
 static unsigned long ssl_cipher_get_disabled(void)
        {
-       unsigned long mask;
+       unsigned long mask = 0;
 
 #ifdef OPENSSL_NO_RSA
        mask |= SSL_aRSA|SSL_kRSA;
@@ -583,6 +583,7 @@ static void ssl_cipher_collect_aliases(SSL_CIPHER **ca_list,
        CIPHER_ORDER *ciph_curr;
        SSL_CIPHER **ca_curr;
        int i;
+       unsigned long enabled_mask = ~mask;
 
        /*
         * First, add the real ciphers as already collected
@@ -598,28 +599,40 @@ static void ssl_cipher_collect_aliases(SSL_CIPHER **ca_list,
 
        /*
         * Now we add the available ones from the cipher_aliases[] table.
-        * They represent either an algorithm, that must be
-        * supported (not disabled through 'mask', i.e. all of the
-        * SSL_MKEY_MASK, SSL_AUTH_MASK, .. bits in the alias are set in 'mask')
+        * They represent either one or more algorithms, some of which
+        * in any affected category must be supported (set in enabled_mask),
         * or represent a cipher strength value (will be added in any case because algorithms=0).
         */
        for (i = 0; i < num_of_group_aliases; i++)
                {
                int algorithms = cipher_aliases[i].algorithms;
 
-               if ((i == 0) /* always fetch "ALL" */ ||
-                   !(((SSL_MKEY_MASK & algorithms) && (SSL_MKEY_MASK & mask)
-                      && ((algorithms & SSL_MKEY_MASK & mask) == (SSL_MKEY_MASK & mask))) ||
-                     ((SSL_AUTH_MASK & algorithms) && (SSL_AUTH_MASK & mask)
-                      && ((algorithms & SSL_AUTH_MASK & mask) == (SSL_AUTH_MASK & mask))) ||
-                     ((SSL_ENC_MASK & algorithms) && (SSL_ENC_MASK & mask)
-                      && ((algorithms & SSL_ENC_MASK & mask) == (SSL_ENC_MASK & mask))) ||
-                     ((SSL_MAC_MASK & algorithms) && (SSL_MAC_MASK & mask)
-                      && ((algorithms & SSL_MAC_MASK & mask) == (SSL_MAC_MASK & mask)))))
+               if (SSL_MKEY_MASK & algorithms)
                        {
-                       *ca_curr = (SSL_CIPHER *)(cipher_aliases + i);
-                       ca_curr++;
+                       if ((SSL_MKEY_MASK & algorithms & enabled_mask) == 0)
+                               continue;
+                       }
+               
+               if (SSL_AUTH_MASK & algorithms)
+                       {
+                       if ((SSL_AUTH_MASK & algorithms & enabled_mask) == 0)
+                               continue;
+                       }
+               
+               if (SSL_ENC_MASK & algorithms)
+                       {
+                       if ((SSL_ENC_MASK & algorithms & enabled_mask) == 0)
+                               continue;
                        }
+               
+               if (SSL_MAC_MASK & algorithms)
+                       {
+                       if ((SSL_MAC_MASK & algorithms & enabled_mask) == 0)
+                               continue;
+                       }
+               
+               *ca_curr = (SSL_CIPHER *)(cipher_aliases + i);
+               ca_curr++;
                }
 
        *ca_curr = NULL;        /* end of list */
@@ -628,7 +641,7 @@ static void ssl_cipher_collect_aliases(SSL_CIPHER **ca_list,
 static void ssl_cipher_apply_rule(unsigned long cipher_id,
                unsigned long algorithms, unsigned long mask,
                unsigned long algo_strength, unsigned long mask_strength,
-               int rule, int strength_bits, CIPHER_ORDER *co_list,
+               int rule, int strength_bits,
                CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
        {
        CIPHER_ORDER *head, *tail, *curr, *curr2, *tail2;
@@ -731,8 +744,7 @@ static void ssl_cipher_apply_rule(unsigned long cipher_id,
        *tail_p = tail;
        }
 
-static int ssl_cipher_strength_sort(CIPHER_ORDER *co_list,
-                                   CIPHER_ORDER **head_p,
+static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p,
                                    CIPHER_ORDER **tail_p)
        {
        int max_strength_bits, i, *number_uses;
@@ -778,15 +790,15 @@ static int ssl_cipher_strength_sort(CIPHER_ORDER *co_list,
        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,
-                                       co_list, head_p, tail_p);
+                                       head_p, tail_p);
 
        OPENSSL_free(number_uses);
        return(1);
        }
 
 static int ssl_cipher_process_rulestr(const char *rule_str,
-               CIPHER_ORDER *co_list, CIPHER_ORDER **head_p,
-               CIPHER_ORDER **tail_p, SSL_CIPHER **ca_list)
+                CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p,
+                SSL_CIPHER **ca_list)
        {
        unsigned long algorithms, mask, algo_strength, mask_strength;
        const char *l, *start, *buf;
@@ -927,8 +939,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str,
                        ok = 0;
                        if ((buflen == 8) &&
                                !strncmp(buf, "STRENGTH", 8))
-                               ok = ssl_cipher_strength_sort(co_list,
-                                       head_p, tail_p);
+                               ok = ssl_cipher_strength_sort(head_p, tail_p);
                        else
                                SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR,
                                        SSL_R_INVALID_COMMAND);
@@ -947,7 +958,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str,
                        {
                        ssl_cipher_apply_rule(cipher_id, algorithms, mask,
                                algo_strength, mask_strength, rule, -1,
-                               co_list, head_p, tail_p);
+                               head_p, tail_p);
                        }
                else
                        {
@@ -1033,15 +1044,14 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
        if (strncmp(rule_str,"DEFAULT",7) == 0)
                {
                ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST,
-                       co_list, &head, &tail, ca_list);
+                       &head, &tail, ca_list);
                rule_p += 7;
                if (*rule_p == ':')
                        rule_p++;
                }
 
        if (ok && (strlen(rule_p) > 0))
-               ok = ssl_cipher_process_rulestr(rule_p, co_list, &head, &tail,
-                                               ca_list);
+               ok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list);
 
        OPENSSL_free(ca_list);  /* Not needed anymore */