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;
	}
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;  

	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;

		 
		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

		 
		if (rule == CIPHER_ADD)
			{
			 
			if (!curr->active)
				{
				ll_append_tail(&head, curr, &tail);
				curr->active = 1;
				}
			}
		 
		else if (rule == CIPHER_ORD)
			{
			 
			if (curr->active)
				{
				ll_append_tail(&head, curr, &tail);
				}
			}
		else if	(rule == CIPHER_DEL)
			{
			 
			if (curr->active)
				{
				 
				ll_append_head(&head, curr, &tail);
				curr->active = 0;
				}
			}
		else if (rule == CIPHER_KILL)
			{
			 
			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;
	}