{0,SSL_TXT_3DES,0,SSL_3DES, 0,0,0,0,SSL_ENC_MASK,0},
{0,SSL_TXT_RC4, 0,SSL_RC4, 0,0,0,0,SSL_ENC_MASK,0},
{0,SSL_TXT_RC2, 0,SSL_RC2, 0,0,0,0,SSL_ENC_MASK,0},
+#ifndef OPENSSL_NO_IDEA
{0,SSL_TXT_IDEA,0,SSL_IDEA, 0,0,0,0,SSL_ENC_MASK,0},
+#endif
{0,SSL_TXT_eNULL,0,SSL_eNULL,0,0,0,0,SSL_ENC_MASK,0},
{0,SSL_TXT_eFZA,0,SSL_eFZA, 0,0,0,0,SSL_ENC_MASK,0},
{0,SSL_TXT_AES, 0,SSL_AES, 0,0,0,0,SSL_ENC_MASK,0},
{0,SSL_TXT_HIGH, 0, 0, SSL_HIGH, 0,0,0,0,SSL_STRONG_MASK},
};
-static int init_ciphers=1;
-
-static void load_ciphers(void)
+void ssl_load_ciphers(void)
{
- init_ciphers=0;
ssl_cipher_methods[SSL_ENC_DES_IDX]=
EVP_get_cipherbyname(SN_des_cbc);
ssl_cipher_methods[SSL_ENC_3DES_IDX]=
EVP_get_cipherbyname(SN_rc4);
ssl_cipher_methods[SSL_ENC_RC2_IDX]=
EVP_get_cipherbyname(SN_rc2_cbc);
+#ifndef OPENSSL_NO_IDEA
ssl_cipher_methods[SSL_ENC_IDEA_IDX]=
EVP_get_cipherbyname(SN_idea_cbc);
+#else
+ ssl_cipher_methods[SSL_ENC_IDEA_IDX]= NULL;
+#endif
ssl_cipher_methods[SSL_ENC_AES128_IDX]=
EVP_get_cipherbyname(SN_aes_128_cbc);
ssl_cipher_methods[SSL_ENC_AES256_IDX]=
EVP_get_digestbyname(SN_sha1);
}
+
+#ifndef OPENSSL_NO_COMP
+
static int sk_comp_cmp(const SSL_COMP * const *a,
const SSL_COMP * const *b)
{
}
CRYPTO_w_unlock(CRYPTO_LOCK_SSL);
}
+#endif
-int ssl_cipher_get_evp(SSL_SESSION *s, const EVP_CIPHER **enc,
+int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
const EVP_MD **md, SSL_COMP **comp)
{
int i;
if (comp != NULL)
{
SSL_COMP ctmp;
-
+#ifndef OPENSSL_NO_COMP
load_builtin_compressions();
+#endif
*comp=NULL;
ctmp.id=s->compress_meth;
}
static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method,
- int num_of_ciphers, unsigned long mask, CIPHER_ORDER *list,
+ int num_of_ciphers, unsigned long mask, CIPHER_ORDER *co_list,
CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
{
- int i, list_num;
+ int i, co_list_num;
SSL_CIPHER *c;
/*
*/
/* Get the initial list of ciphers */
- list_num = 0; /* actual count of ciphers */
+ co_list_num = 0; /* actual count of ciphers */
for (i = 0; i < num_of_ciphers; i++)
{
c = ssl_method->get_cipher(i);
/* drop those that use any of that is not available */
if ((c != NULL) && c->valid && !(c->algorithms & mask))
{
- list[list_num].cipher = c;
- list[list_num].next = NULL;
- list[list_num].prev = NULL;
- list[list_num].active = 0;
- list_num++;
+ co_list[co_list_num].cipher = c;
+ co_list[co_list_num].next = NULL;
+ co_list[co_list_num].prev = NULL;
+ co_list[co_list_num].active = 0;
+ co_list_num++;
#ifdef KSSL_DEBUG
printf("\t%d: %s %lx %lx\n",i,c->name,c->id,c->algorithms);
#endif /* KSSL_DEBUG */
/*
* Prepare linked list from list entries
*/
- for (i = 1; i < list_num - 1; i++)
+ for (i = 1; i < co_list_num - 1; i++)
{
- list[i].prev = &(list[i-1]);
- list[i].next = &(list[i+1]);
+ co_list[i].prev = &(co_list[i-1]);
+ co_list[i].next = &(co_list[i+1]);
}
- if (list_num > 0)
+ if (co_list_num > 0)
{
- (*head_p) = &(list[0]);
+ (*head_p) = &(co_list[0]);
(*head_p)->prev = NULL;
- (*head_p)->next = &(list[1]);
- (*tail_p) = &(list[list_num - 1]);
- (*tail_p)->prev = &(list[list_num - 2]);
+ (*head_p)->next = &(co_list[1]);
+ (*tail_p) = &(co_list[co_list_num - 1]);
+ (*tail_p)->prev = &(co_list[co_list_num - 2]);
(*tail_p)->next = NULL;
}
}
*ca_curr = NULL; /* end of list */
}
-static void ssl_cipher_apply_rule(unsigned long algorithms, unsigned long mask,
+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 *list,
+ int rule, int strength_bits, CIPHER_ORDER *co_list,
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 (cipher_id)
+ {
+ if (cp->id != cipher_id)
+ continue;
+ }
+
/*
* Selection criteria is either the number of strength_bits
* or the algorithm used.
*/
- if (strength_bits == -1)
+ else if (strength_bits == -1)
{
ma = mask & cp->algorithms;
ma_s = mask_strength & cp->algo_strength;
*tail_p = tail;
}
-static int ssl_cipher_strength_sort(CIPHER_ORDER *list, CIPHER_ORDER **head_p,
- CIPHER_ORDER **tail_p)
+static int ssl_cipher_strength_sort(CIPHER_ORDER *co_list,
+ CIPHER_ORDER **head_p,
+ CIPHER_ORDER **tail_p)
{
int max_strength_bits, i, *number_uses;
CIPHER_ORDER *curr;
*/
for (i = max_strength_bits; i >= 0; i--)
if (number_uses[i] > 0)
- ssl_cipher_apply_rule(0, 0, 0, 0, CIPHER_ORD, i,
- list, head_p, tail_p);
+ ssl_cipher_apply_rule(0, 0, 0, 0, 0, CIPHER_ORD, i,
+ co_list, head_p, tail_p);
OPENSSL_free(number_uses);
return(1);
}
static int ssl_cipher_process_rulestr(const char *rule_str,
- CIPHER_ORDER *list, CIPHER_ORDER **head_p,
+ CIPHER_ORDER *co_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;
char ch;
retval = 1;
* use strcmp(), because buf is not '\0' terminated.)
*/
j = found = 0;
+ cipher_id = 0;
while (ca_list[j])
{
if (!strncmp(buf, ca_list[j]->name, buflen) &&
if (!found)
break; /* ignore this entry */
- algorithms |= ca_list[j]->algorithms;
+ 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
+ * 3 - enforce old & new where masks intersect
+ */
+ algorithms = (algorithms & ~ca_list[j]->mask) | /* 1 */
+ (ca_list[j]->algorithms & ~mask) | /* 2 */
+ (algorithms & ca_list[j]->algorithms); /* 3 */
mask |= ca_list[j]->mask;
- algo_strength |= ca_list[j]->algo_strength;
+ algo_strength = (algo_strength & ~ca_list[j]->mask_strength) |
+ (ca_list[j]->algo_strength & ~mask_strength) |
+ (algo_strength & ca_list[j]->algo_strength);
mask_strength |= ca_list[j]->mask_strength;
if (!multi) break;
ok = 0;
if ((buflen == 8) &&
!strncmp(buf, "STRENGTH", 8))
- ok = ssl_cipher_strength_sort(list,
+ ok = ssl_cipher_strength_sort(co_list,
head_p, tail_p);
else
SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR,
}
else if (found)
{
- ssl_cipher_apply_rule(algorithms, mask,
+ ssl_cipher_apply_rule(cipher_id, algorithms, mask,
algo_strength, mask_strength, rule, -1,
- list, head_p, tail_p);
+ co_list, head_p, tail_p);
}
else
{
{
int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases;
unsigned long disabled_mask;
- STACK_OF(SSL_CIPHER) *cipherstack;
+ STACK_OF(SSL_CIPHER) *cipherstack, *tmp_cipher_list;
const char *rule_p;
- CIPHER_ORDER *list = NULL, *head = NULL, *tail = NULL, *curr;
+ CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr;
SSL_CIPHER **ca_list = NULL;
/*
* Return with error if nothing to do.
*/
- if (rule_str == NULL) return(NULL);
-
- if (init_ciphers)
- {
- CRYPTO_w_lock(CRYPTO_LOCK_SSL);
- if (init_ciphers) load_ciphers();
- CRYPTO_w_unlock(CRYPTO_LOCK_SSL);
- }
+ if (rule_str == NULL || cipher_list == NULL || cipher_list_by_id == NULL)
+ return NULL;
/*
* To reduce the work to do we only want to process the compiled
#ifdef KSSL_DEBUG
printf("ssl_create_cipher_list() for %d ciphers\n", num_of_ciphers);
#endif /* KSSL_DEBUG */
- list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * num_of_ciphers);
- if (list == NULL)
+ co_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * num_of_ciphers);
+ if (co_list == NULL)
{
SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE);
return(NULL); /* Failure */
}
ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, disabled_mask,
- list, &head, &tail);
+ co_list, &head, &tail);
/*
* We also need cipher aliases for selecting based on the rule_str.
(SSL_CIPHER **)OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max);
if (ca_list == NULL)
{
- OPENSSL_free(list);
+ OPENSSL_free(co_list);
SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE);
return(NULL); /* Failure */
}
if (strncmp(rule_str,"DEFAULT",7) == 0)
{
ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST,
- list, &head, &tail, ca_list);
+ co_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, list, &head, &tail,
+ ok = ssl_cipher_process_rulestr(rule_p, co_list, &head, &tail,
ca_list);
OPENSSL_free(ca_list); /* Not needed anymore */
if (!ok)
{ /* Rule processing failure */
- OPENSSL_free(list);
+ OPENSSL_free(co_list);
return(NULL);
}
/*
*/
if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL)
{
- OPENSSL_free(list);
+ OPENSSL_free(co_list);
return(NULL);
}
#endif
}
}
- OPENSSL_free(list); /* Not needed any longer */
-
- /*
- * The following passage is a little bit odd. If pointer variables
- * were supplied to hold STACK_OF(SSL_CIPHER) return information,
- * the old memory pointed to is free()ed. Then, however, the
- * cipher_list entry will be assigned just a copy of the returned
- * cipher stack. For cipher_list_by_id a copy of the cipher stack
- * will be created. See next comment...
- */
- if (cipher_list != NULL)
- {
- if (*cipher_list != NULL)
- sk_SSL_CIPHER_free(*cipher_list);
- *cipher_list = cipherstack;
- }
+ OPENSSL_free(co_list); /* Not needed any longer */
- if (cipher_list_by_id != NULL)
- {
- if (*cipher_list_by_id != NULL)
- sk_SSL_CIPHER_free(*cipher_list_by_id);
- *cipher_list_by_id = sk_SSL_CIPHER_dup(cipherstack);
- }
-
- /*
- * Now it is getting really strange. If something failed during
- * the previous pointer assignment or if one of the pointers was
- * not requested, the error condition is met. That might be
- * discussable. The strange thing is however that in this case
- * the memory "ret" pointed to is "free()ed" and hence the pointer
- * cipher_list becomes wild. The memory reserved for
- * cipher_list_by_id however is not "free()ed" and stays intact.
- */
- if ( (cipher_list_by_id == NULL) ||
- (*cipher_list_by_id == NULL) ||
- (cipher_list == NULL) ||
- (*cipher_list == NULL))
+ tmp_cipher_list = sk_SSL_CIPHER_dup(cipherstack);
+ if (tmp_cipher_list == NULL)
{
sk_SSL_CIPHER_free(cipherstack);
- return(NULL);
+ return NULL;
}
-
+ if (*cipher_list != NULL)
+ sk_SSL_CIPHER_free(*cipher_list);
+ *cipher_list = cipherstack;
+ if (*cipher_list_by_id != NULL)
+ sk_SSL_CIPHER_free(*cipher_list_by_id);
+ *cipher_list_by_id = tmp_cipher_list;
sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id,ssl_cipher_ptr_id_cmp);
return(cipherstack);
char *SSL_CIPHER_description(SSL_CIPHER *cipher, char *buf, int len)
{
int is_export,pkl,kl;
- char *ver,*exp_str;
- char *kx,*au,*enc,*mac;
+ const char *ver,*exp_str;
+ const char *kx,*au,*enc,*mac;
unsigned long alg,alg2,alg_s;
#ifdef KSSL_DEBUG
- static char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s AL=%lx\n";
+ static const char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s AL=%lx\n";
#else
- static char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s\n";
+ static const char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s\n";
#endif /* KSSL_DEBUG */
alg=cipher->algorithms;
return(buf);
}
-char *SSL_CIPHER_get_version(SSL_CIPHER *c)
+char *SSL_CIPHER_get_version(const SSL_CIPHER *c)
{
int i;
}
/* return the actual cipher being used */
-const char *SSL_CIPHER_get_name(SSL_CIPHER *c)
+const char *SSL_CIPHER_get_name(const SSL_CIPHER *c)
{
if (c != NULL)
return(c->name);
}
/* number of bits for symmetric cipher */
-int SSL_CIPHER_get_bits(SSL_CIPHER *c, int *alg_bits)
+int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits)
{
int ret=0;
return(NULL);
}
+#ifdef OPENSSL_NO_COMP
+void *SSL_COMP_get_compression_methods(void)
+ {
+ return NULL;
+ }
+int SSL_COMP_add_compression_method(int id, void *cm)
+ {
+ return 1;
+ }
+
+const char *SSL_COMP_get_name(const void *comp)
+ {
+ return NULL;
+ }
+#else
STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void)
{
load_builtin_compressions();
return NULL;
}
+#endif