static int tls_curve_allowed(SSL *s, const unsigned char *curve, int op)
{
    const tls_curve_info *cinfo;
    if (curve[0])
        return 1;
    if ((curve[1] < 1) || ((size_t)curve[1] > OSSL_NELEM(nid_list)))
        return 0;
    cinfo = &nid_list[curve[1] - 1];
# ifdef OPENSSL_NO_EC2M
    if (cinfo->flags & TLS_CURVE_CHAR2)
        return 0;
# endif
    return ssl_security(s, op, cinfo->secbits, cinfo->nid, (void *)curve);
}
['unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,\n                                          unsigned char *limit, int *al)\n{\n    int extdatalen = 0;\n    unsigned char *orig = buf;\n    unsigned char *ret = buf;\n#ifndef OPENSSL_NO_EC\n    int using_ecc = 0;\n    if (s->version >= TLS1_VERSION || SSL_IS_DTLS(s)) {\n        int i;\n        unsigned long alg_k, alg_a;\n        STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);\n        for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) {\n            const SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);\n            alg_k = c->algorithm_mkey;\n            alg_a = c->algorithm_auth;\n            if ((alg_k & (SSL_kECDHE | SSL_kECDHEPSK))\n                 || (alg_a & SSL_aECDSA)) {\n                using_ecc = 1;\n                break;\n            }\n        }\n    }\n#endif\n    ret += 2;\n    if (ret >= limit)\n        return NULL;\n    if (s->renegotiate) {\n        int el;\n        if (!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0)) {\n            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);\n            return NULL;\n        }\n        if ((limit - ret - 4 - el) < 0)\n            return NULL;\n        s2n(TLSEXT_TYPE_renegotiate, ret);\n        s2n(el, ret);\n        if (!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el)) {\n            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);\n            return NULL;\n        }\n        ret += el;\n    }\n    if (s->client_version == SSL3_VERSION)\n        goto done;\n    if (s->tlsext_hostname != NULL) {\n        unsigned long size_str;\n        long lenmax;\n        if ((lenmax = limit - ret - 9) < 0\n            || (size_str =\n                strlen(s->tlsext_hostname)) > (unsigned long)lenmax)\n            return NULL;\n        s2n(TLSEXT_TYPE_server_name, ret);\n        s2n(size_str + 5, ret);\n        s2n(size_str + 3, ret);\n        *(ret++) = (unsigned char)TLSEXT_NAMETYPE_host_name;\n        s2n(size_str, ret);\n        memcpy(ret, s->tlsext_hostname, size_str);\n        ret += size_str;\n    }\n#ifndef OPENSSL_NO_SRP\n    if (s->srp_ctx.login != NULL) {\n        int login_len = strlen(s->srp_ctx.login);\n        if (login_len > 255 || login_len == 0) {\n            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);\n            return NULL;\n        }\n        if ((limit - ret - 5 - login_len) < 0)\n            return NULL;\n        s2n(TLSEXT_TYPE_srp, ret);\n        s2n(login_len + 1, ret);\n        (*ret++) = (unsigned char)login_len;\n        memcpy(ret, s->srp_ctx.login, login_len);\n        ret += login_len;\n    }\n#endif\n#ifndef OPENSSL_NO_EC\n    if (using_ecc) {\n        long lenmax;\n        const unsigned char *pcurves, *pformats;\n        size_t num_curves, num_formats, curves_list_len;\n        size_t i;\n        unsigned char *etmp;\n        tls1_get_formatlist(s, &pformats, &num_formats);\n        if ((lenmax = limit - ret - 5) < 0)\n            return NULL;\n        if (num_formats > (size_t)lenmax)\n            return NULL;\n        if (num_formats > 255) {\n            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);\n            return NULL;\n        }\n        s2n(TLSEXT_TYPE_ec_point_formats, ret);\n        s2n(num_formats + 1, ret);\n        *(ret++) = (unsigned char)num_formats;\n        memcpy(ret, pformats, num_formats);\n        ret += num_formats;\n        pcurves = s->tlsext_ellipticcurvelist;\n        if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves))\n            return NULL;\n        if ((lenmax = limit - ret - 6) < 0)\n            return NULL;\n        if (num_curves > (size_t)lenmax / 2)\n            return NULL;\n        if (num_curves > 65532 / 2) {\n            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);\n            return NULL;\n        }\n        s2n(TLSEXT_TYPE_elliptic_curves, ret);\n        etmp = ret + 4;\n        for (i = 0; i < num_curves; i++, pcurves += 2) {\n            if (tls_curve_allowed(s, pcurves, SSL_SECOP_CURVE_SUPPORTED)) {\n                *etmp++ = pcurves[0];\n                *etmp++ = pcurves[1];\n            }\n        }\n        curves_list_len = etmp - ret - 4;\n        s2n(curves_list_len + 2, ret);\n        s2n(curves_list_len, ret);\n        ret += curves_list_len;\n    }\n#endif\n    if (tls_use_ticket(s)) {\n        int ticklen;\n        if (!s->new_session && s->session && s->session->tlsext_tick)\n            ticklen = s->session->tlsext_ticklen;\n        else if (s->session && s->tlsext_session_ticket &&\n                 s->tlsext_session_ticket->data) {\n            ticklen = s->tlsext_session_ticket->length;\n            s->session->tlsext_tick = OPENSSL_malloc(ticklen);\n            if (s->session->tlsext_tick == NULL)\n                return NULL;\n            memcpy(s->session->tlsext_tick,\n                   s->tlsext_session_ticket->data, ticklen);\n            s->session->tlsext_ticklen = ticklen;\n        } else\n            ticklen = 0;\n        if (ticklen == 0 && s->tlsext_session_ticket &&\n            s->tlsext_session_ticket->data == NULL)\n            goto skip_ext;\n        if ((long)(limit - ret - 4 - ticklen) < 0)\n            return NULL;\n        s2n(TLSEXT_TYPE_session_ticket, ret);\n        s2n(ticklen, ret);\n        if (ticklen) {\n            memcpy(ret, s->session->tlsext_tick, ticklen);\n            ret += ticklen;\n        }\n    }\n skip_ext:\n    if (SSL_USE_SIGALGS(s)) {\n        size_t salglen;\n        const unsigned char *salg;\n        unsigned char *etmp;\n        salglen = tls12_get_psigalgs(s, &salg);\n        if ((size_t)(limit - ret) < salglen + 6)\n            return NULL;\n        s2n(TLSEXT_TYPE_signature_algorithms, ret);\n        etmp = ret;\n        ret += 4;\n        salglen = tls12_copy_sigalgs(s, ret, salg, salglen);\n        s2n(salglen + 2, etmp);\n        s2n(salglen, etmp);\n        ret += salglen;\n    }\n    if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) {\n        int i;\n        long extlen, idlen, itmp;\n        OCSP_RESPID *id;\n        idlen = 0;\n        for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) {\n            id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);\n            itmp = i2d_OCSP_RESPID(id, NULL);\n            if (itmp <= 0)\n                return NULL;\n            idlen += itmp + 2;\n        }\n        if (s->tlsext_ocsp_exts) {\n            extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);\n            if (extlen < 0)\n                return NULL;\n        } else\n            extlen = 0;\n        if ((long)(limit - ret - 7 - extlen - idlen) < 0)\n            return NULL;\n        s2n(TLSEXT_TYPE_status_request, ret);\n        if (extlen + idlen > 0xFFF0)\n            return NULL;\n        s2n(extlen + idlen + 5, ret);\n        *(ret++) = TLSEXT_STATUSTYPE_ocsp;\n        s2n(idlen, ret);\n        for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) {\n            unsigned char *q = ret;\n            id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);\n            ret += 2;\n            itmp = i2d_OCSP_RESPID(id, &ret);\n            s2n(itmp, q);\n        }\n        s2n(extlen, ret);\n        if (extlen > 0)\n            i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret);\n    }\n#ifndef OPENSSL_NO_HEARTBEATS\n    if (SSL_IS_DTLS(s)) {\n        if ((limit - ret - 4 - 1) < 0)\n            return NULL;\n        s2n(TLSEXT_TYPE_heartbeat, ret);\n        s2n(1, ret);\n        if (s->tlsext_heartbeat & SSL_DTLSEXT_HB_DONT_RECV_REQUESTS)\n            *(ret++) = SSL_DTLSEXT_HB_DONT_SEND_REQUESTS;\n        else\n            *(ret++) = SSL_DTLSEXT_HB_ENABLED;\n    }\n#endif\n#ifndef OPENSSL_NO_NEXTPROTONEG\n    if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len) {\n        if (limit - ret - 4 < 0)\n            return NULL;\n        s2n(TLSEXT_TYPE_next_proto_neg, ret);\n        s2n(0, ret);\n    }\n#endif\n    if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len) {\n        if ((size_t)(limit - ret) < 6 + s->alpn_client_proto_list_len)\n            return NULL;\n        s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);\n        s2n(2 + s->alpn_client_proto_list_len, ret);\n        s2n(s->alpn_client_proto_list_len, ret);\n        memcpy(ret, s->alpn_client_proto_list, s->alpn_client_proto_list_len);\n        ret += s->alpn_client_proto_list_len;\n    }\n#ifndef OPENSSL_NO_SRTP\n    if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) {\n        int el;\n        if (ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0)) {\n            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);\n            return NULL;\n        }\n        if ((limit - ret - 4 - el) < 0)\n            return NULL;\n        s2n(TLSEXT_TYPE_use_srtp, ret);\n        s2n(el, ret);\n        if (ssl_add_clienthello_use_srtp_ext(s, ret, &el, el)) {\n            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);\n            return NULL;\n        }\n        ret += el;\n    }\n#endif\n    custom_ext_init(&s->cert->cli_ext);\n    if (!custom_ext_add(s, 0, &ret, limit, al))\n        return NULL;\n#ifdef TLSEXT_TYPE_encrypt_then_mac\n    s2n(TLSEXT_TYPE_encrypt_then_mac, ret);\n    s2n(0, ret);\n#endif\n    s2n(TLSEXT_TYPE_extended_master_secret, ret);\n    s2n(0, ret);\n    if (s->options & SSL_OP_TLSEXT_PADDING) {\n        int hlen = ret - (unsigned char *)s->init_buf->data;\n        if (hlen > 0xff && hlen < 0x200) {\n            hlen = 0x200 - hlen;\n            if (hlen >= 4)\n                hlen -= 4;\n            else\n                hlen = 0;\n            s2n(TLSEXT_TYPE_padding, ret);\n            s2n(hlen, ret);\n            memset(ret, 0, hlen);\n            ret += hlen;\n        }\n    }\n done:\n    if ((extdatalen = ret - orig - 2) == 0)\n        return orig;\n    s2n(extdatalen, orig);\n    return ret;\n}', 'static int tls_curve_allowed(SSL *s, const unsigned char *curve, int op)\n{\n    const tls_curve_info *cinfo;\n    if (curve[0])\n        return 1;\n    if ((curve[1] < 1) || ((size_t)curve[1] > OSSL_NELEM(nid_list)))\n        return 0;\n    cinfo = &nid_list[curve[1] - 1];\n# ifdef OPENSSL_NO_EC2M\n    if (cinfo->flags & TLS_CURVE_CHAR2)\n        return 0;\n# endif\n    return ssl_security(s, op, cinfo->secbits, cinfo->nid, (void *)curve);\n}']