Esempio n. 1
0
static void ssl_cipher_apply_rule(unsigned long cipher_id,
                unsigned long alg_mkey, unsigned long alg_auth,
                unsigned long alg_enc, unsigned long alg_mac,
                unsigned long alg_ssl,
		unsigned long algo_strength,
		int rule, int strength_bits,
		CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
	{
	CIPHER_ORDER *head, *tail, *curr, *curr2, *last;
	const SSL_CIPHER *cp;
	int reverse = 0;

#ifdef CIPHER_DEBUG
	printf("Applying rule %d with %08lx/%08lx/%08lx/%08lx/%08lx %08lx (%d)\n",
		rule, alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength, strength_bits);
#endif

	if (rule == CIPHER_DEL)
		reverse = 1; /* needed to maintain sorting between currently deleted ciphers */

	head = *head_p;
	tail = *tail_p;

	if (reverse)
		{
		curr = tail;
		last = head;
		}
	else
		{
		curr = head;
		last = tail;
		}

	curr2 = curr;
	for (;;)
		{
		if ((curr == NULL) || (curr == last)) break;
		curr = curr2;
		curr2 = reverse ? curr->prev : curr->next;

		cp = curr->cipher;

		/*
		 * Selection criteria is either the value of strength_bits
		 * or the algorithms used.
		 */
		if (strength_bits >= 0)
			{
			if (strength_bits != cp->strength_bits)
				continue;
			}
		else
			{
#ifdef CIPHER_DEBUG
			printf("\nName: %s:\nAlgo = %08lx/%08lx/%08lx/%08lx/%08lx Algo_strength = %08lx\n", cp->name, cp->algorithm_mkey, cp->algorithm_auth, cp->algorithm_enc, cp->algorithm_mac, cp->algorithm_ssl, cp->algo_strength);
#endif

			if (alg_mkey && !(alg_mkey & cp->algorithm_mkey))
				continue;
			if (alg_auth && !(alg_auth & cp->algorithm_auth))
				continue;
			if (alg_enc && !(alg_enc & cp->algorithm_enc))
				continue;
			if (alg_mac && !(alg_mac & cp->algorithm_mac))
				continue;
			if (alg_ssl && !(alg_ssl & cp->algorithm_ssl))
				continue;
			if ((algo_strength & SSL_EXP_MASK) && !(algo_strength & SSL_EXP_MASK & cp->algo_strength))
				continue;
			if ((algo_strength & SSL_STRONG_MASK) && !(algo_strength & SSL_STRONG_MASK & cp->algo_strength))
				continue;
			}

#ifdef CIPHER_DEBUG
		printf("Action = %d\n", rule);
#endif

		/* add the cipher if it has not been added yet. */
		if (rule == CIPHER_ADD)
			{
			/* reverse == 0 */
			if (!curr->active)
				{
				ll_append_tail(&head, curr, &tail);
				curr->active = 1;
				}
			}
		/* Move the added cipher to this location */
		else if (rule == CIPHER_ORD)
			{
			/* reverse == 0 */
			if (curr->active)
				{
				ll_append_tail(&head, curr, &tail);
				}
			}
		else if	(rule == CIPHER_DEL)
			{
			/* reverse == 1 */
			if (curr->active)
				{
				/* most recently deleted ciphersuites get best positions
				 * for any future CIPHER_ADD (note that the CIPHER_DEL loop
				 * works in reverse to maintain the order) */
				ll_append_head(&head, curr, &tail);
				curr->active = 0;
				}
			}
		else if (rule == CIPHER_KILL)
			{
			/* reverse == 0 */
			if (head == curr)
				head = curr->next;
			else
				curr->prev->next = curr->next;
			if (tail == curr)
				tail = curr->prev;
			curr->active = 0;
			if (curr->next != NULL)
				curr->next->prev = curr->prev;
			if (curr->prev != NULL)
				curr->prev->next = curr->next;
			curr->next = NULL;
			curr->prev = NULL;
			}
		}

	*head_p = head;
	*tail_p = tail;
	}
Esempio n. 2
0
/* ssl_cipher_apply_rule applies the rule type |rule| to ciphers matching its
 * parameters in the linked list from |*head_p| to |*tail_p|. It writes the new
 * head and tail of the list to |*head_p| and |*tail_p|, respectively.
 *
 * - If |cipher_id| is non-zero, only that cipher is selected.
 * - Otherwise, if |strength_bits| is non-negative, it selects ciphers
 *   of that strength.
 * - Otherwise, it selects ciphers that match each bitmasks in |alg_*| and
 *   |algo_strength|. */
static void ssl_cipher_apply_rule(
    uint32_t cipher_id, uint32_t alg_mkey, uint32_t alg_auth,
    uint32_t alg_enc, uint32_t alg_mac, uint32_t alg_ssl,
    uint32_t algo_strength, int rule, int strength_bits, int in_group,
    CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) {
  CIPHER_ORDER *head, *tail, *curr, *next, *last;
  const SSL_CIPHER *cp;
  int reverse = 0;

  if (cipher_id == 0 && strength_bits == -1 &&
      (alg_mkey == 0 || alg_auth == 0 || alg_enc == 0 || alg_mac == 0 ||
       alg_ssl == 0 || algo_strength == 0)) {
    /* The rule matches nothing, so bail early. */
    return;
  }

  if (rule == CIPHER_DEL) {
    /* needed to maintain sorting between currently deleted ciphers */
    reverse = 1;
  }

  head = *head_p;
  tail = *tail_p;

  if (reverse) {
    next = tail;
    last = head;
  } else {
    next = head;
    last = tail;
  }

  curr = NULL;
  for (;;) {
    if (curr == last) {
      break;
    }

    curr = next;
    if (curr == NULL) {
      break;
    }

    next = reverse ? curr->prev : curr->next;
    cp = curr->cipher;

    /* Selection criteria is either a specific cipher, the value of
     * |strength_bits|, or the algorithms used. */
    if (cipher_id != 0) {
      if (cipher_id != cp->id) {
        continue;
      }
    } else if (strength_bits >= 0) {
      if (strength_bits != cp->strength_bits) {
        continue;
      }
    } else if (!(alg_mkey & cp->algorithm_mkey) ||
               !(alg_auth & cp->algorithm_auth) ||
               !(alg_enc & cp->algorithm_enc) ||
               !(alg_mac & cp->algorithm_mac) ||
               !(alg_ssl & cp->algorithm_ssl) ||
               !(algo_strength & cp->algo_strength)) {
      continue;
    }

    /* add the cipher if it has not been added yet. */
    if (rule == CIPHER_ADD) {
      /* reverse == 0 */
      if (!curr->active) {
        ll_append_tail(&head, curr, &tail);
        curr->active = 1;
        curr->in_group = in_group;
      }
    }

    /* Move the added cipher to this location */
    else if (rule == CIPHER_ORD) {
      /* reverse == 0 */
      if (curr->active) {
        ll_append_tail(&head, curr, &tail);
        curr->in_group = 0;
      }
    } else if (rule == CIPHER_DEL) {
      /* reverse == 1 */
      if (curr->active) {
        /* most recently deleted ciphersuites get best positions
         * for any future CIPHER_ADD (note that the CIPHER_DEL loop
         * works in reverse to maintain the order) */
        ll_append_head(&head, curr, &tail);
        curr->active = 0;
        curr->in_group = 0;
      }
    } else if (rule == CIPHER_KILL) {
      /* reverse == 0 */
      if (head == curr) {
        head = curr->next;
      } else {
        curr->prev->next = curr->next;
      }

      if (tail == curr) {
        tail = curr->prev;
      }
      curr->active = 0;
      if (curr->next != NULL) {
        curr->next->prev = curr->prev;
      }
      if (curr->prev != NULL) {
        curr->prev->next = curr->next;
      }
      curr->next = NULL;
      curr->prev = NULL;
    }
  }

  *head_p = head;
  *tail_p = tail;
}