STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
                                             STACK_OF(SSL_CIPHER) *tls13_ciphersuites,
                                             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, i;
    uint32_t disabled_mkey, disabled_auth, disabled_enc, disabled_mac;
    STACK_OF(SSL_CIPHER) *cipherstack;
    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
    disabled_mkey = disabled_mkey_mask;
    disabled_auth = disabled_auth_mask;
    disabled_enc = disabled_enc_mask;
    disabled_mac = disabled_mac_mask;
    num_of_ciphers = ssl_method->num_ciphers();
    co_list = OPENSSL_malloc(sizeof(*co_list) * 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, co_list, &head, &tail);
    ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, 0, 0, 0, 0, CIPHER_ADD,
                          -1, &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_AESGCM, 0, 0, 0, CIPHER_ADD, -1,
                          &head, &tail);
    ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20, 0, 0, 0, CIPHER_ADD, -1,
                          &head, &tail);
    ssl_cipher_apply_rule(0, 0, 0, SSL_AES ^ SSL_AESGCM, 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, 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, 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, TLS1_2_VERSION, 0, CIPHER_BUMP, -1,
                          &head, &tail);
    ssl_cipher_apply_rule(0, 0, 0, 0, SSL_AEAD, 0, 0, CIPHER_BUMP, -1,
                          &head, &tail);
    ssl_cipher_apply_rule(0, SSL_kDHE | SSL_kECDHE, 0, 0, 0, 0, 0,
                          CIPHER_BUMP, -1, &head, &tail);
    ssl_cipher_apply_rule(0, SSL_kDHE | SSL_kECDHE, 0, 0, SSL_AEAD, 0, 0,
                          CIPHER_BUMP, -1, &head, &tail);
    ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail);
    num_of_group_aliases = OSSL_NELEM(cipher_aliases);
    num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1;
    ca_list = OPENSSL_malloc(sizeof(*ca_list) * 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, 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(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 (i = 0; i < sk_SSL_CIPHER_num(tls13_ciphersuites); i++) {
        if (!sk_SSL_CIPHER_push(cipherstack,
                                sk_SSL_CIPHER_value(tls13_ciphersuites, i))) {
            sk_SSL_CIPHER_free(cipherstack);
            return NULL;
        }
    }
    for (curr = head; curr != NULL; curr = curr->next) {
        if (curr->active) {
            if (!sk_SSL_CIPHER_push(cipherstack, curr->cipher)) {
                OPENSSL_free(co_list);
                sk_SSL_CIPHER_free(cipherstack);
                return NULL;
            }
#ifdef CIPHER_DEBUG
            fprintf(stderr, "<%s>\n", curr->cipher->name);
#endif
        }
    }
    OPENSSL_free(co_list);
    if (!update_cipher_list_by_id(cipher_list_by_id, cipherstack)) {
        sk_SSL_CIPHER_free(cipherstack);
        return NULL;
    }
    sk_SSL_CIPHER_free(*cipher_list);
    *cipher_list = cipherstack;
    return cipherstack;
}
['static int test_client_hello(int currtest)\n{\n    SSL_CTX *ctx;\n    SSL *con = NULL;\n    BIO *rbio;\n    BIO *wbio;\n    long len;\n    unsigned char *data;\n    PACKET pkt = {0}, pkt2 = {0}, pkt3 = {0};\n    char *dummytick = "Hello World!";\n    unsigned int type = 0;\n    int testresult = 0;\n    size_t msglen;\n    BIO *sessbio = NULL;\n    SSL_SESSION *sess = NULL;\n#ifdef OPENSSL_NO_TLS1_3\n    if (currtest == TEST_ADD_PADDING_AND_PSK)\n        return 1;\n#endif\n    ctx = SSL_CTX_new(TLS_method());\n    if (!TEST_ptr(ctx))\n        goto end;\n    if (!TEST_true(SSL_CTX_set_max_proto_version(ctx, 0)))\n        goto end;\n    switch(currtest) {\n    case TEST_SET_SESSION_TICK_DATA_VER_NEG:\n#if !defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_TLS1_2)\n        return 1;\n#else\n        if (!TEST_true(SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION)))\n            goto end;\n#endif\n        break;\n    case TEST_ADD_PADDING_AND_PSK:\n        if (!TEST_false(SSL_CTX_set_cipher_list(ctx, "")))\n            goto end;\n        ERR_clear_error();\n    case TEST_ADD_PADDING:\n    case TEST_PADDING_NOT_NEEDED:\n        SSL_CTX_set_options(ctx, SSL_OP_TLSEXT_PADDING);\n        SSL_CTX_clear_options(ctx, SSL_OP_ENABLE_MIDDLEBOX_COMPAT);\n        if (currtest == TEST_ADD_PADDING) {\n             if (!TEST_false(SSL_CTX_set_alpn_protos(ctx,\n                                    (unsigned char *)alpn_prots,\n                                    sizeof(alpn_prots) - 1)))\n                goto end;\n        } else if (!TEST_true(SSL_CTX_set_cipher_list(ctx,\n                              "AES128-SHA"))\n                   || !TEST_true(SSL_CTX_set_ciphersuites(ctx,\n                                 "TLS_AES_128_GCM_SHA256"))) {\n            goto end;\n        }\n        break;\n    default:\n        goto end;\n    }\n    con = SSL_new(ctx);\n    if (!TEST_ptr(con))\n        goto end;\n    if (currtest == TEST_ADD_PADDING_AND_PSK) {\n        sessbio = BIO_new_file(sessionfile, "r");\n        if (!TEST_ptr(sessbio)) {\n            TEST_info("Unable to open session.pem");\n            goto end;\n        }\n        sess = PEM_read_bio_SSL_SESSION(sessbio, NULL, NULL, NULL);\n        if (!TEST_ptr(sess)) {\n            TEST_info("Unable to load SSL_SESSION");\n            goto end;\n        }\n        if (!TEST_true(SSL_SESSION_set_time(sess, (long)time(NULL)))\n                || !TEST_true(SSL_set_session(con, sess)))\n            goto end;\n    }\n    rbio = BIO_new(BIO_s_mem());\n    wbio = BIO_new(BIO_s_mem());\n    if (!TEST_ptr(rbio)|| !TEST_ptr(wbio)) {\n        BIO_free(rbio);\n        BIO_free(wbio);\n        goto end;\n    }\n    SSL_set_bio(con, rbio, wbio);\n    SSL_set_connect_state(con);\n    if (currtest == TEST_SET_SESSION_TICK_DATA_VER_NEG) {\n        if (!TEST_true(SSL_set_session_ticket_ext(con, dummytick,\n                                                  strlen(dummytick))))\n            goto end;\n    }\n    if (!TEST_int_le(SSL_connect(con), 0)) {\n        goto end;\n    }\n    len = BIO_get_mem_data(wbio, (char **)&data);\n    if (!TEST_true(PACKET_buf_init(&pkt, data, len))\n            || !PACKET_forward(&pkt, SSL3_RT_HEADER_LENGTH))\n        goto end;\n    msglen = PACKET_remaining(&pkt);\n    if (!TEST_true(PACKET_forward(&pkt, SSL3_HM_HEADER_LENGTH))\n            || !TEST_true(PACKET_forward(&pkt, CLIENT_VERSION_LEN\n                                               + SSL3_RANDOM_SIZE))\n            || !TEST_true(PACKET_get_length_prefixed_1(&pkt, &pkt2))\n            || !TEST_true(PACKET_get_length_prefixed_2(&pkt, &pkt2))\n            || !TEST_true(PACKET_get_length_prefixed_1(&pkt, &pkt2))\n            || !TEST_true(PACKET_as_length_prefixed_2(&pkt, &pkt2)))\n        goto end;\n    while (PACKET_remaining(&pkt2)) {\n        if (!TEST_true(PACKET_get_net_2(&pkt2, &type))\n                || !TEST_true(PACKET_get_length_prefixed_2(&pkt2, &pkt3)))\n            goto end;\n        if (type == TLSEXT_TYPE_session_ticket) {\n            if (currtest == TEST_SET_SESSION_TICK_DATA_VER_NEG) {\n                if (TEST_true(PACKET_equal(&pkt3, dummytick,\n                                           strlen(dummytick)))) {\n                    testresult = 1;\n                }\n                goto end;\n            }\n        }\n        if (type == TLSEXT_TYPE_padding) {\n            if (!TEST_false(currtest == TEST_PADDING_NOT_NEEDED))\n                goto end;\n            else if (TEST_true(currtest == TEST_ADD_PADDING\n                    || currtest == TEST_ADD_PADDING_AND_PSK))\n                testresult = TEST_true(msglen == F5_WORKAROUND_MAX_MSG_LEN);\n        }\n    }\n    if (currtest == TEST_PADDING_NOT_NEEDED)\n        testresult = 1;\nend:\n    SSL_free(con);\n    SSL_CTX_free(ctx);\n    SSL_SESSION_free(sess);\n    BIO_free(sessbio);\n    return testresult;\n}', 'int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str)\n{\n    STACK_OF(SSL_CIPHER) *sk;\n    sk = ssl_create_cipher_list(ctx->method, ctx->tls13_ciphersuites,\n                                &ctx->cipher_list, &ctx->cipher_list_by_id, str,\n                                ctx->cert);\n    if (sk == NULL)\n        return 0;\n    else if (cipher_list_tls12_num(sk) == 0) {\n        SSLerr(SSL_F_SSL_CTX_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH);\n        return 0;\n    }\n    return 1;\n}', 'STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,\n                                             STACK_OF(SSL_CIPHER) *tls13_ciphersuites,\n                                             STACK_OF(SSL_CIPHER) **cipher_list,\n                                             STACK_OF(SSL_CIPHER) **cipher_list_by_id,\n                                             const char *rule_str,\n                                             CERT *c)\n{\n    int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases, i;\n    uint32_t disabled_mkey, disabled_auth, disabled_enc, disabled_mac;\n    STACK_OF(SSL_CIPHER) *cipherstack;\n    const char *rule_p;\n    CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr;\n    const SSL_CIPHER **ca_list = NULL;\n    if (rule_str == NULL || cipher_list == NULL || cipher_list_by_id == NULL)\n        return NULL;\n#ifndef OPENSSL_NO_EC\n    if (!check_suiteb_cipher_list(ssl_method, c, &rule_str))\n        return NULL;\n#endif\n    disabled_mkey = disabled_mkey_mask;\n    disabled_auth = disabled_auth_mask;\n    disabled_enc = disabled_enc_mask;\n    disabled_mac = disabled_mac_mask;\n    num_of_ciphers = ssl_method->num_ciphers();\n    co_list = OPENSSL_malloc(sizeof(*co_list) * num_of_ciphers);\n    if (co_list == NULL) {\n        SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST, ERR_R_MALLOC_FAILURE);\n        return NULL;\n    }\n    ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers,\n                               disabled_mkey, disabled_auth, disabled_enc,\n                               disabled_mac, co_list, &head, &tail);\n    ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, 0, 0, 0, 0, CIPHER_ADD,\n                          -1, &head, &tail);\n    ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head,\n                          &tail);\n    ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head,\n                          &tail);\n    ssl_cipher_apply_rule(0, 0, 0, SSL_AESGCM, 0, 0, 0, CIPHER_ADD, -1,\n                          &head, &tail);\n    ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20, 0, 0, 0, CIPHER_ADD, -1,\n                          &head, &tail);\n    ssl_cipher_apply_rule(0, 0, 0, SSL_AES ^ SSL_AESGCM, 0, 0, 0, CIPHER_ADD,\n                          -1, &head, &tail);\n    ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail);\n    ssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, &head,\n                          &tail);\n    ssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, &head,\n                          &tail);\n    ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head,\n                          &tail);\n    ssl_cipher_apply_rule(0, SSL_kPSK, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head,\n                          &tail);\n    ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, &head,\n                          &tail);\n    if (!ssl_cipher_strength_sort(&head, &tail)) {\n        OPENSSL_free(co_list);\n        return NULL;\n    }\n    ssl_cipher_apply_rule(0, 0, 0, 0, 0, TLS1_2_VERSION, 0, CIPHER_BUMP, -1,\n                          &head, &tail);\n    ssl_cipher_apply_rule(0, 0, 0, 0, SSL_AEAD, 0, 0, CIPHER_BUMP, -1,\n                          &head, &tail);\n    ssl_cipher_apply_rule(0, SSL_kDHE | SSL_kECDHE, 0, 0, 0, 0, 0,\n                          CIPHER_BUMP, -1, &head, &tail);\n    ssl_cipher_apply_rule(0, SSL_kDHE | SSL_kECDHE, 0, 0, SSL_AEAD, 0, 0,\n                          CIPHER_BUMP, -1, &head, &tail);\n    ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail);\n    num_of_group_aliases = OSSL_NELEM(cipher_aliases);\n    num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1;\n    ca_list = OPENSSL_malloc(sizeof(*ca_list) * num_of_alias_max);\n    if (ca_list == NULL) {\n        OPENSSL_free(co_list);\n        SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST, ERR_R_MALLOC_FAILURE);\n        return NULL;\n    }\n    ssl_cipher_collect_aliases(ca_list, num_of_group_aliases,\n                               disabled_mkey, disabled_auth, disabled_enc,\n                               disabled_mac, head);\n    ok = 1;\n    rule_p = rule_str;\n    if (strncmp(rule_str, "DEFAULT", 7) == 0) {\n        ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST,\n                                        &head, &tail, ca_list, c);\n        rule_p += 7;\n        if (*rule_p == \':\')\n            rule_p++;\n    }\n    if (ok && (strlen(rule_p) > 0))\n        ok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list, c);\n    OPENSSL_free(ca_list);\n    if (!ok) {\n        OPENSSL_free(co_list);\n        return NULL;\n    }\n    if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL) {\n        OPENSSL_free(co_list);\n        return NULL;\n    }\n    for (i = 0; i < sk_SSL_CIPHER_num(tls13_ciphersuites); i++) {\n        if (!sk_SSL_CIPHER_push(cipherstack,\n                                sk_SSL_CIPHER_value(tls13_ciphersuites, i))) {\n            sk_SSL_CIPHER_free(cipherstack);\n            return NULL;\n        }\n    }\n    for (curr = head; curr != NULL; curr = curr->next) {\n        if (curr->active) {\n            if (!sk_SSL_CIPHER_push(cipherstack, curr->cipher)) {\n                OPENSSL_free(co_list);\n                sk_SSL_CIPHER_free(cipherstack);\n                return NULL;\n            }\n#ifdef CIPHER_DEBUG\n            fprintf(stderr, "<%s>\\n", curr->cipher->name);\n#endif\n        }\n    }\n    OPENSSL_free(co_list);\n    if (!update_cipher_list_by_id(cipher_list_by_id, cipherstack)) {\n        sk_SSL_CIPHER_free(cipherstack);\n        return NULL;\n    }\n    sk_SSL_CIPHER_free(*cipher_list);\n    *cipher_list = cipherstack;\n    return cipherstack;\n}', 'static int check_suiteb_cipher_list(const SSL_METHOD *meth, CERT *c,\n                                    const char **prule_str)\n{\n    unsigned int suiteb_flags = 0, suiteb_comb2 = 0;\n    if (strncmp(*prule_str, "SUITEB128ONLY", 13) == 0) {\n        suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS_ONLY;\n    } else if (strncmp(*prule_str, "SUITEB128C2", 11) == 0) {\n        suiteb_comb2 = 1;\n        suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS;\n    } else if (strncmp(*prule_str, "SUITEB128", 9) == 0) {\n        suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS;\n    } else if (strncmp(*prule_str, "SUITEB192", 9) == 0) {\n        suiteb_flags = SSL_CERT_FLAG_SUITEB_192_LOS;\n    }\n    if (suiteb_flags) {\n        c->cert_flags &= ~SSL_CERT_FLAG_SUITEB_128_LOS;\n        c->cert_flags |= suiteb_flags;\n    } else {\n        suiteb_flags = c->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS;\n    }\n    if (!suiteb_flags)\n        return 1;\n    if (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS)) {\n        SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST,\n               SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE);\n        return 0;\n    }\n# ifndef OPENSSL_NO_EC\n    switch (suiteb_flags) {\n    case SSL_CERT_FLAG_SUITEB_128_LOS:\n        if (suiteb_comb2)\n            *prule_str = "ECDHE-ECDSA-AES256-GCM-SHA384";\n        else\n            *prule_str =\n                "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384";\n        break;\n    case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY:\n        *prule_str = "ECDHE-ECDSA-AES128-GCM-SHA256";\n        break;\n    case SSL_CERT_FLAG_SUITEB_192_LOS:\n        *prule_str = "ECDHE-ECDSA-AES256-GCM-SHA384";\n        break;\n    }\n    return 1;\n# else\n    SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST, SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE);\n    return 0;\n# endif\n}']