STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
		STACK_OF(SSL_CIPHER) **cipher_list,
		STACK_OF(SSL_CIPHER) **cipher_list_by_id,
		const char *rule_str, CERT *c)
	{
	int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases;
	unsigned long disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl;
	STACK_OF(SSL_CIPHER) *cipherstack, *tmp_cipher_list;
	const char *rule_p;
	CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr;
	const SSL_CIPHER **ca_list = NULL;
	if (rule_str == NULL || cipher_list == NULL || cipher_list_by_id == NULL)
		return NULL;
#ifndef OPENSSL_NO_EC
	if (!check_suiteb_cipher_list(ssl_method, c, &rule_str))
		return NULL;
#endif
	ssl_cipher_get_disabled(&disabled_mkey, &disabled_auth, &disabled_enc, &disabled_mac, &disabled_ssl);
	num_of_ciphers = ssl_method->num_ciphers();
#ifdef KSSL_DEBUG
	printf("ssl_create_cipher_list() for %d ciphers\n", num_of_ciphers);
#endif
	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);
		}
	ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers,
	                           disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl,
	                           co_list, &head, &tail);
	ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail);
	ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail);
	ssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0, CIPHER_ADD, -1, &head, &tail);
	ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail);
	ssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, &head, &tail);
	ssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
	ssl_cipher_apply_rule(0, 0, SSL_aECDH, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
	ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
	ssl_cipher_apply_rule(0, SSL_kPSK, 0,0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
	ssl_cipher_apply_rule(0, SSL_kKRB5, 0,0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
	ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
	if (!ssl_cipher_strength_sort(&head, &tail))
		{
		OPENSSL_free(co_list);
		return NULL;
		}
	ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail);
	num_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER);
	num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1;
	ca_list = OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max);
	if (ca_list == NULL)
		{
		OPENSSL_free(co_list);
		SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE);
		return(NULL);
		}
	ssl_cipher_collect_aliases(ca_list, num_of_group_aliases,
	                           disabled_mkey, disabled_auth, disabled_enc,
				   disabled_mac, disabled_ssl, head);
	ok = 1;
	rule_p = rule_str;
	if (strncmp(rule_str,"DEFAULT",7) == 0)
		{
		ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST,
			&head, &tail, ca_list, c);
		rule_p += 7;
		if (*rule_p == ':')
			rule_p++;
		}
	if (ok && (strlen(rule_p) > 0))
		ok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list, c);
	OPENSSL_free((void *)ca_list);
	if (!ok)
		{
		OPENSSL_free(co_list);
		return(NULL);
		}
	if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL)
		{
		OPENSSL_free(co_list);
		return(NULL);
		}
	for (curr = head; curr != NULL; curr = curr->next)
		{
#ifdef OPENSSL_FIPS
		if (curr->active && (!FIPS_mode() || curr->cipher->algo_strength & SSL_FIPS))
#else
		if (curr->active)
#endif
			{
			sk_SSL_CIPHER_push(cipherstack, curr->cipher);
#ifdef CIPHER_DEBUG
			printf("<%s>\n",curr->cipher->name);
#endif
			}
		}
	OPENSSL_free(co_list);
	tmp_cipher_list = sk_SSL_CIPHER_dup(cipherstack);
	if (tmp_cipher_list == NULL)
		{
		sk_SSL_CIPHER_free(cipherstack);
		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;
	(void)sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id,ssl_cipher_ptr_id_cmp);
	sk_SSL_CIPHER_sort(*cipher_list_by_id);
	return(cipherstack);
	}
['int SSL_CTX_set_ssl_version(SSL_CTX *ctx,const SSL_METHOD *meth)\n\t{\n\tSTACK_OF(SSL_CIPHER) *sk;\n\tctx->method=meth;\n\tsk=ssl_create_cipher_list(ctx->method,&(ctx->cipher_list),\n\t\t&(ctx->cipher_list_by_id),\n\t\tmeth->version == SSL2_VERSION ? "SSLv2" : SSL_DEFAULT_CIPHER_LIST, ctx->cert);\n\tif ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= 0))\n\t\t{\n\t\tSSLerr(SSL_F_SSL_CTX_SET_SSL_VERSION,SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS);\n\t\treturn(0);\n\t\t}\n\treturn(1);\n\t}', 'STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,\n\t\tSTACK_OF(SSL_CIPHER) **cipher_list,\n\t\tSTACK_OF(SSL_CIPHER) **cipher_list_by_id,\n\t\tconst char *rule_str, CERT *c)\n\t{\n\tint ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases;\n\tunsigned long disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl;\n\tSTACK_OF(SSL_CIPHER) *cipherstack, *tmp_cipher_list;\n\tconst char *rule_p;\n\tCIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr;\n\tconst SSL_CIPHER **ca_list = NULL;\n\tif (rule_str == NULL || cipher_list == NULL || cipher_list_by_id == NULL)\n\t\treturn NULL;\n#ifndef OPENSSL_NO_EC\n\tif (!check_suiteb_cipher_list(ssl_method, c, &rule_str))\n\t\treturn NULL;\n#endif\n\tssl_cipher_get_disabled(&disabled_mkey, &disabled_auth, &disabled_enc, &disabled_mac, &disabled_ssl);\n\tnum_of_ciphers = ssl_method->num_ciphers();\n#ifdef KSSL_DEBUG\n\tprintf("ssl_create_cipher_list() for %d ciphers\\n", num_of_ciphers);\n#endif\n\tco_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * num_of_ciphers);\n\tif (co_list == NULL)\n\t\t{\n\t\tSSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE);\n\t\treturn(NULL);\n\t\t}\n\tssl_cipher_collect_ciphers(ssl_method, num_of_ciphers,\n\t                           disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl,\n\t                           co_list, &head, &tail);\n\tssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail);\n\tssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail);\n\tssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0, CIPHER_ADD, -1, &head, &tail);\n\tssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail);\n\tssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, &head, &tail);\n\tssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);\n\tssl_cipher_apply_rule(0, 0, SSL_aECDH, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);\n\tssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);\n\tssl_cipher_apply_rule(0, SSL_kPSK, 0,0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);\n\tssl_cipher_apply_rule(0, SSL_kKRB5, 0,0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);\n\tssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);\n\tif (!ssl_cipher_strength_sort(&head, &tail))\n\t\t{\n\t\tOPENSSL_free(co_list);\n\t\treturn NULL;\n\t\t}\n\tssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail);\n\tnum_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER);\n\tnum_of_alias_max = num_of_ciphers + num_of_group_aliases + 1;\n\tca_list = OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max);\n\tif (ca_list == NULL)\n\t\t{\n\t\tOPENSSL_free(co_list);\n\t\tSSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE);\n\t\treturn(NULL);\n\t\t}\n\tssl_cipher_collect_aliases(ca_list, num_of_group_aliases,\n\t                           disabled_mkey, disabled_auth, disabled_enc,\n\t\t\t\t   disabled_mac, disabled_ssl, head);\n\tok = 1;\n\trule_p = rule_str;\n\tif (strncmp(rule_str,"DEFAULT",7) == 0)\n\t\t{\n\t\tok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST,\n\t\t\t&head, &tail, ca_list, c);\n\t\trule_p += 7;\n\t\tif (*rule_p == \':\')\n\t\t\trule_p++;\n\t\t}\n\tif (ok && (strlen(rule_p) > 0))\n\t\tok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list, c);\n\tOPENSSL_free((void *)ca_list);\n\tif (!ok)\n\t\t{\n\t\tOPENSSL_free(co_list);\n\t\treturn(NULL);\n\t\t}\n\tif ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL)\n\t\t{\n\t\tOPENSSL_free(co_list);\n\t\treturn(NULL);\n\t\t}\n\tfor (curr = head; curr != NULL; curr = curr->next)\n\t\t{\n#ifdef OPENSSL_FIPS\n\t\tif (curr->active && (!FIPS_mode() || curr->cipher->algo_strength & SSL_FIPS))\n#else\n\t\tif (curr->active)\n#endif\n\t\t\t{\n\t\t\tsk_SSL_CIPHER_push(cipherstack, curr->cipher);\n#ifdef CIPHER_DEBUG\n\t\t\tprintf("<%s>\\n",curr->cipher->name);\n#endif\n\t\t\t}\n\t\t}\n\tOPENSSL_free(co_list);\n\ttmp_cipher_list = sk_SSL_CIPHER_dup(cipherstack);\n\tif (tmp_cipher_list == NULL)\n\t\t{\n\t\tsk_SSL_CIPHER_free(cipherstack);\n\t\treturn NULL;\n\t\t}\n\tif (*cipher_list != NULL)\n\t\tsk_SSL_CIPHER_free(*cipher_list);\n\t*cipher_list = cipherstack;\n\tif (*cipher_list_by_id != NULL)\n\t\tsk_SSL_CIPHER_free(*cipher_list_by_id);\n\t*cipher_list_by_id = tmp_cipher_list;\n\t(void)sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id,ssl_cipher_ptr_id_cmp);\n\tsk_SSL_CIPHER_sort(*cipher_list_by_id);\n\treturn(cipherstack);\n\t}', 'static int check_suiteb_cipher_list(const SSL_METHOD *meth, CERT *c,\n\t\t\t\t\tconst char **prule_str)\n\t{\n\tunsigned int suiteb_flags = 0, suiteb_comb2 = 0;\n\tif (!strcmp(*prule_str, "SUITEB128"))\n\t\tsuiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS;\n\telse if (!strcmp(*prule_str, "SUITEB128ONLY"))\n\t\tsuiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS_ONLY;\n\telse if (!strcmp(*prule_str, "SUITEB128C2"))\n\t\t{\n\t\tsuiteb_comb2 = 1;\n\t\tsuiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS;\n\t\t}\n\telse if (!strcmp(*prule_str, "SUITEB192"))\n\t\tsuiteb_flags = SSL_CERT_FLAG_SUITEB_192_LOS;\n\tif (suiteb_flags)\n\t\t{\n\t\tc->cert_flags &= ~SSL_CERT_FLAG_SUITEB_128_LOS;\n\t\tc->cert_flags |= suiteb_flags;\n\t\t}\n\telse\n\t\tsuiteb_flags = c->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS;\n\tif (!suiteb_flags)\n\t\treturn 1;\n\tif (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS))\n\t\t{\n\t\tif (meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS)\n\t\t\tSSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST,\n\t\t\t\tSSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE);\n\t\telse\n\t\t\tSSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST,\n\t\t\t\tSSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE);\n\t\treturn 0;\n\t\t}\n\tswitch(suiteb_flags)\n\t\t{\n\tcase SSL_CERT_FLAG_SUITEB_128_LOS:\n\t\tif (suiteb_comb2)\n\t\t\t*prule_str = "ECDHE-ECDSA-AES256-GCM-SHA384";\n\t\telse\n\t\t\t*prule_str = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384";\n\t\tbreak;\n\tcase SSL_CERT_FLAG_SUITEB_128_LOS_ONLY:\n\t\t*prule_str = "ECDHE-ECDSA-AES128-GCM-SHA256";\n\t\tbreak;\n\tcase SSL_CERT_FLAG_SUITEB_192_LOS:\n\t\t*prule_str = "ECDHE-ECDSA-AES256-GCM-SHA384";\n\t\tbreak;\n\t\t}\n\tc->ecdh_tmp_auto = 1;\n\treturn 1;\n\t}']