} CIPHER_ORDER;
static const SSL_CIPHER cipher_aliases[]={
- /* "ALL" must be first; it doesn't include eNULL (must be specifically enabled) */
+ /* "ALL" doesn't include eNULL (must be specifically enabled) */
{0,SSL_TXT_ALL, 0,SSL_ALL & ~SSL_eNULL, SSL_ALL ,0,0,0,SSL_ALL,SSL_ALL},
/* "COMPLEMENTOFALL" */
{0,SSL_TXT_CMPALL,0,SSL_eNULL,0,0,0,0,SSL_ENC_MASK,0},
static unsigned long ssl_cipher_get_disabled(void)
{
- unsigned long mask;
+ unsigned long mask = 0;
#ifdef OPENSSL_NO_RSA
mask |= SSL_aRSA|SSL_kRSA;
CIPHER_ORDER *ciph_curr;
SSL_CIPHER **ca_curr;
int i;
+ unsigned long enabled_mask = ~mask;
/*
* First, add the real ciphers as already collected
/*
* 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 */
}
-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,
+ int rule, int strength_bits,
CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
{
CIPHER_ORDER *head, *tail, *curr, *curr2, *tail2;
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;
*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;
*/
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);
+ ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, CIPHER_ORD, i,
+ 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;
int j, multi, found, rule, retval, ok, buflen;
- unsigned long cipher_id;
+ unsigned long cipher_id = 0, ssl_version = 0;
char ch;
retval = 1;
*/
j = found = 0;
cipher_id = 0;
+ ssl_version = 0;
while (ca_list[j])
{
if (!strncmp(buf, ca_list[j]->name, buflen) &&
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
(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;
}
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);
}
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);
+ head_p, tail_p);
}
else
{
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 */