int tls_choose_sigalg(SSL *s, int *al)
{
    const SIGALG_LOOKUP *lu = NULL;
    s->s3->tmp.cert = NULL;
    s->s3->tmp.sigalg = NULL;
    if (SSL_IS_TLS13(s)) {
        size_t i;
#ifndef OPENSSL_NO_EC
        int curve = -1, skip_ec = 0;
#endif
        for (i = 0; i < s->cert->shared_sigalgslen; i++) {
            lu = s->cert->shared_sigalgs[i];
            if (lu->hash == NID_sha1
                || lu->hash == NID_sha224
                || lu->sig == EVP_PKEY_DSA
                || lu->sig == EVP_PKEY_RSA)
                continue;
            if (!tls1_lookup_md(lu, NULL))
                continue;
            if (!ssl_has_cert(s, lu->sig_idx))
                    continue;
            if (lu->sig == EVP_PKEY_EC) {
#ifndef OPENSSL_NO_EC
                if (curve == -1) {
                    EC_KEY *ec = EVP_PKEY_get0_EC_KEY(s->cert->pkeys[SSL_PKEY_ECC].privatekey);
                    curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
                    if (EC_KEY_get_conv_form(ec)
                        != POINT_CONVERSION_UNCOMPRESSED)
                        skip_ec = 1;
                }
                if (skip_ec || (lu->curve != NID_undef && curve != lu->curve))
                    continue;
#else
                continue;
#endif
            }
            break;
        }
        if (i == s->cert->shared_sigalgslen) {
            if (al == NULL)
                return 1;
            *al = SSL_AD_HANDSHAKE_FAILURE;
            SSLerr(SSL_F_TLS_CHOOSE_SIGALG,
                   SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM);
            return 0;
        }
    } else {
        if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aCERT))
            return 1;
        if (!s->server && !ssl_has_cert(s, s->cert->key - s->cert->pkeys))
                return 1;
        if (SSL_USE_SIGALGS(s)) {
            if (s->s3->tmp.peer_sigalgs != NULL) {
                size_t i;
#ifndef OPENSSL_NO_EC
                int curve;
                if (tls1_suiteb(s)) {
                    EC_KEY *ec = EVP_PKEY_get0_EC_KEY(s->cert->pkeys[SSL_PKEY_ECC].privatekey);
                    curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
                } else {
                    curve = -1;
                }
#endif
                for (i = 0; i < s->cert->shared_sigalgslen; i++) {
                    lu = s->cert->shared_sigalgs[i];
                    if (s->server) {
                        if (!tls12_check_cert_sigalg(s, lu))
                            continue;
                    } else if (lu->sig_idx != s->cert->key - s->cert->pkeys) {
                            continue;
                    }
#ifndef OPENSSL_NO_EC
                    if (curve == -1 || lu->curve == curve)
#endif
                        break;
                }
                if (i == s->cert->shared_sigalgslen) {
                    if (al == NULL)
                        return 1;
                    *al = SSL_AD_INTERNAL_ERROR;
                    SSLerr(SSL_F_TLS_CHOOSE_SIGALG, ERR_R_INTERNAL_ERROR);
                    return 0;
                }
            } else {
                const uint16_t *sent_sigs;
                size_t sent_sigslen, i;
                if ((lu = tls1_get_legacy_sigalg(s, -1)) == NULL) {
                    if (al == NULL)
                        return 1;
                    *al = SSL_AD_INTERNAL_ERROR;
                    SSLerr(SSL_F_TLS_CHOOSE_SIGALG, ERR_R_INTERNAL_ERROR);
                    return 0;
                }
                sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs);
                for (i = 0; i < sent_sigslen; i++, sent_sigs++) {
                    if (lu->sigalg == *sent_sigs)
                        break;
                }
                if (i == sent_sigslen) {
                    if (al == NULL)
                        return 1;
                    SSLerr(SSL_F_TLS_CHOOSE_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
                    *al = SSL_AD_ILLEGAL_PARAMETER;
                    return 0;
                }
            }
        } else {
            if ((lu = tls1_get_legacy_sigalg(s, -1)) == NULL) {
                if (al == NULL)
                    return 1;
                *al = SSL_AD_INTERNAL_ERROR;
                SSLerr(SSL_F_TLS_CHOOSE_SIGALG, ERR_R_INTERNAL_ERROR);
                return 0;
            }
        }
    }
    s->s3->tmp.cert = &s->cert->pkeys[lu->sig_idx];
    s->cert->key = s->s3->tmp.cert;
    s->s3->tmp.sigalg = lu;
    return 1;
}
['int tls_choose_sigalg(SSL *s, int *al)\n{\n    const SIGALG_LOOKUP *lu = NULL;\n    s->s3->tmp.cert = NULL;\n    s->s3->tmp.sigalg = NULL;\n    if (SSL_IS_TLS13(s)) {\n        size_t i;\n#ifndef OPENSSL_NO_EC\n        int curve = -1, skip_ec = 0;\n#endif\n        for (i = 0; i < s->cert->shared_sigalgslen; i++) {\n            lu = s->cert->shared_sigalgs[i];\n            if (lu->hash == NID_sha1\n                || lu->hash == NID_sha224\n                || lu->sig == EVP_PKEY_DSA\n                || lu->sig == EVP_PKEY_RSA)\n                continue;\n            if (!tls1_lookup_md(lu, NULL))\n                continue;\n            if (!ssl_has_cert(s, lu->sig_idx))\n                    continue;\n            if (lu->sig == EVP_PKEY_EC) {\n#ifndef OPENSSL_NO_EC\n                if (curve == -1) {\n                    EC_KEY *ec = EVP_PKEY_get0_EC_KEY(s->cert->pkeys[SSL_PKEY_ECC].privatekey);\n                    curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));\n                    if (EC_KEY_get_conv_form(ec)\n                        != POINT_CONVERSION_UNCOMPRESSED)\n                        skip_ec = 1;\n                }\n                if (skip_ec || (lu->curve != NID_undef && curve != lu->curve))\n                    continue;\n#else\n                continue;\n#endif\n            }\n            break;\n        }\n        if (i == s->cert->shared_sigalgslen) {\n            if (al == NULL)\n                return 1;\n            *al = SSL_AD_HANDSHAKE_FAILURE;\n            SSLerr(SSL_F_TLS_CHOOSE_SIGALG,\n                   SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM);\n            return 0;\n        }\n    } else {\n        if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aCERT))\n            return 1;\n        if (!s->server && !ssl_has_cert(s, s->cert->key - s->cert->pkeys))\n                return 1;\n        if (SSL_USE_SIGALGS(s)) {\n            if (s->s3->tmp.peer_sigalgs != NULL) {\n                size_t i;\n#ifndef OPENSSL_NO_EC\n                int curve;\n                if (tls1_suiteb(s)) {\n                    EC_KEY *ec = EVP_PKEY_get0_EC_KEY(s->cert->pkeys[SSL_PKEY_ECC].privatekey);\n                    curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));\n                } else {\n                    curve = -1;\n                }\n#endif\n                for (i = 0; i < s->cert->shared_sigalgslen; i++) {\n                    lu = s->cert->shared_sigalgs[i];\n                    if (s->server) {\n                        if (!tls12_check_cert_sigalg(s, lu))\n                            continue;\n                    } else if (lu->sig_idx != s->cert->key - s->cert->pkeys) {\n                            continue;\n                    }\n#ifndef OPENSSL_NO_EC\n                    if (curve == -1 || lu->curve == curve)\n#endif\n                        break;\n                }\n                if (i == s->cert->shared_sigalgslen) {\n                    if (al == NULL)\n                        return 1;\n                    *al = SSL_AD_INTERNAL_ERROR;\n                    SSLerr(SSL_F_TLS_CHOOSE_SIGALG, ERR_R_INTERNAL_ERROR);\n                    return 0;\n                }\n            } else {\n                const uint16_t *sent_sigs;\n                size_t sent_sigslen, i;\n                if ((lu = tls1_get_legacy_sigalg(s, -1)) == NULL) {\n                    if (al == NULL)\n                        return 1;\n                    *al = SSL_AD_INTERNAL_ERROR;\n                    SSLerr(SSL_F_TLS_CHOOSE_SIGALG, ERR_R_INTERNAL_ERROR);\n                    return 0;\n                }\n                sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs);\n                for (i = 0; i < sent_sigslen; i++, sent_sigs++) {\n                    if (lu->sigalg == *sent_sigs)\n                        break;\n                }\n                if (i == sent_sigslen) {\n                    if (al == NULL)\n                        return 1;\n                    SSLerr(SSL_F_TLS_CHOOSE_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);\n                    *al = SSL_AD_ILLEGAL_PARAMETER;\n                    return 0;\n                }\n            }\n        } else {\n            if ((lu = tls1_get_legacy_sigalg(s, -1)) == NULL) {\n                if (al == NULL)\n                    return 1;\n                *al = SSL_AD_INTERNAL_ERROR;\n                SSLerr(SSL_F_TLS_CHOOSE_SIGALG, ERR_R_INTERNAL_ERROR);\n                return 0;\n            }\n        }\n    }\n    s->s3->tmp.cert = &s->cert->pkeys[lu->sig_idx];\n    s->cert->key = s->s3->tmp.cert;\n    s->s3->tmp.sigalg = lu;\n    return 1;\n}', 'static ossl_inline int ssl_has_cert(const SSL *s, int idx)\n{\n    if (idx < 0 || idx >= SSL_PKEY_NUM)\n        return 0;\n    return s->cert->pkeys[idx].x509 != NULL\n        && s->cert->pkeys[idx].privatekey != NULL;\n}', 'EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)\n{\n    if (pkey->type != EVP_PKEY_EC) {\n        EVPerr(EVP_F_EVP_PKEY_GET0_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);\n        return NULL;\n    }\n    return pkey->pkey.ec;\n}', 'const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)\n{\n    return key->group;\n}']