/*
 * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

/*
 * RSA low level APIs are deprecated for public use, but still ok for
 * internal use.
 */
#include "internal/deprecated.h"

#include <string.h>
#include <openssl/core_names.h>
#include <openssl/params.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#ifndef FIPS_MODULE
# include <openssl/x509.h>
# include "crypto/asn1.h"
#endif
#include "internal/sizes.h"
#include "internal/param_build_set.h"
#include "crypto/rsa.h"
#include "rsa_local.h"

#include "internal/e_os.h"                /* strcasecmp for Windows() */

/*
 * The intention with the "backend" source file is to offer backend support
 * for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider
 * implementations alike.
 */

DEFINE_STACK_OF(BIGNUM)

static int collect_numbers(STACK_OF(BIGNUM) *numbers,
                           const OSSL_PARAM params[], const char *names[])
{
    const OSSL_PARAM *p = NULL;
    int i;

    if (numbers == NULL)
        return 0;

    for (i = 0; names[i] != NULL; i++) {
        p = OSSL_PARAM_locate_const(params, names[i]);
        if (p != NULL) {
            BIGNUM *tmp = NULL;

            if (!OSSL_PARAM_get_BN(p, &tmp)
                || sk_BIGNUM_push(numbers, tmp) == 0)
                return 0;
        }
    }

    return 1;
}

int ossl_rsa_fromdata(RSA *rsa, const OSSL_PARAM params[], int include_private)
{
    const OSSL_PARAM *param_n, *param_e,  *param_d = NULL;
    BIGNUM *n = NULL, *e = NULL, *d = NULL;
    STACK_OF(BIGNUM) *factors = NULL, *exps = NULL, *coeffs = NULL;
    int is_private = 0;

    if (rsa == NULL)
        return 0;

    param_n = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_N);
    param_e = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_E);
    if (include_private)
        param_d = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_D);

    if ((param_n != NULL && !OSSL_PARAM_get_BN(param_n, &n))
        || (param_e != NULL && !OSSL_PARAM_get_BN(param_e, &e))
        || (param_d != NULL && !OSSL_PARAM_get_BN(param_d, &d)))
        goto err;

    is_private = (d != NULL);

    if (!RSA_set0_key(rsa, n, e, d))
        goto err;
    n = e = d = NULL;

    if (is_private) {
        if (!collect_numbers(factors = sk_BIGNUM_new_null(), params,
                             ossl_rsa_mp_factor_names)
            || !collect_numbers(exps = sk_BIGNUM_new_null(), params,
                                ossl_rsa_mp_exp_names)
            || !collect_numbers(coeffs = sk_BIGNUM_new_null(), params,
                                ossl_rsa_mp_coeff_names))
            goto err;

        /* It's ok if this private key just has n, e and d */
        if (sk_BIGNUM_num(factors) != 0
            && !ossl_rsa_set0_all_params(rsa, factors, exps, coeffs))
            goto err;
    }


    sk_BIGNUM_free(factors);
    sk_BIGNUM_free(exps);
    sk_BIGNUM_free(coeffs);
    return 1;

 err:
    BN_free(n);
    BN_free(e);
    BN_free(d);
    sk_BIGNUM_pop_free(factors, BN_free);
    sk_BIGNUM_pop_free(exps, BN_free);
    sk_BIGNUM_pop_free(coeffs, BN_free);
    return 0;
}

DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM)

int ossl_rsa_todata(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[],
                    int include_private)
{
    int ret = 0;
    const BIGNUM *rsa_d = NULL, *rsa_n = NULL, *rsa_e = NULL;
    STACK_OF(BIGNUM_const) *factors = sk_BIGNUM_const_new_null();
    STACK_OF(BIGNUM_const) *exps = sk_BIGNUM_const_new_null();
    STACK_OF(BIGNUM_const) *coeffs = sk_BIGNUM_const_new_null();

    if (rsa == NULL || factors == NULL || exps == NULL || coeffs == NULL)
        goto err;

    RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d);
    ossl_rsa_get0_all_params(rsa, factors, exps, coeffs);

    if (!ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_RSA_N, rsa_n)
        || !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_RSA_E, rsa_e))
        goto err;

    /* Check private key data integrity */
    if (include_private && rsa_d != NULL) {
        int numprimes = sk_BIGNUM_const_num(factors);
        int numexps = sk_BIGNUM_const_num(exps);
        int numcoeffs = sk_BIGNUM_const_num(coeffs);

        /*
         * It's permissible to have zero primes, i.e. no CRT params.
         * Otherwise, there must be at least two, as many exponents,
         * and one coefficient less.
         */
        if (numprimes != 0
            && (numprimes < 2 || numexps < 2 || numcoeffs < 1))
            goto err;

        if (!ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_RSA_D,
                                     rsa_d)
            || !ossl_param_build_set_multi_key_bn(bld, params,
                                                  ossl_rsa_mp_factor_names,
                                                  factors)
            || !ossl_param_build_set_multi_key_bn(bld, params,
                                                  ossl_rsa_mp_exp_names, exps)
            || !ossl_param_build_set_multi_key_bn(bld, params,
                                                  ossl_rsa_mp_coeff_names,
                                                  coeffs))
        goto err;
    }

#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
    /* The acvp test results are not meant for export so check for bld == NULL */
    if (bld == NULL)
        ossl_rsa_acvp_test_get_params(rsa, params);
#endif
    ret = 1;
 err:
    sk_BIGNUM_const_free(factors);
    sk_BIGNUM_const_free(exps);
    sk_BIGNUM_const_free(coeffs);
    return ret;
}

int ossl_rsa_pss_params_30_todata(const RSA_PSS_PARAMS_30 *pss,
                                  OSSL_PARAM_BLD *bld, OSSL_PARAM params[])
{
    if (!ossl_rsa_pss_params_30_is_unrestricted(pss)) {
        int hashalg_nid = ossl_rsa_pss_params_30_hashalg(pss);
        int maskgenalg_nid = ossl_rsa_pss_params_30_maskgenalg(pss);
        int maskgenhashalg_nid = ossl_rsa_pss_params_30_maskgenhashalg(pss);
        int saltlen = ossl_rsa_pss_params_30_saltlen(pss);
        int default_hashalg_nid = ossl_rsa_pss_params_30_hashalg(NULL);
        int default_maskgenalg_nid = ossl_rsa_pss_params_30_maskgenalg(NULL);
        int default_maskgenhashalg_nid =
                ossl_rsa_pss_params_30_maskgenhashalg(NULL);
        const char *mdname =
            (hashalg_nid == default_hashalg_nid
             ? NULL : ossl_rsa_oaeppss_nid2name(hashalg_nid));
        const char *mgfname =
            (maskgenalg_nid == default_maskgenalg_nid
             ? NULL : ossl_rsa_oaeppss_nid2name(maskgenalg_nid));
        const char *mgf1mdname =
            (maskgenhashalg_nid == default_maskgenhashalg_nid
             ? NULL : ossl_rsa_oaeppss_nid2name(maskgenhashalg_nid));
        const char *key_md = OSSL_PKEY_PARAM_RSA_DIGEST;
        const char *key_mgf = OSSL_PKEY_PARAM_RSA_MASKGENFUNC;
        const char *key_mgf1_md = OSSL_PKEY_PARAM_RSA_MGF1_DIGEST;
        const char *key_saltlen = OSSL_PKEY_PARAM_RSA_PSS_SALTLEN;

        /*
         * To ensure that the key isn't seen as unrestricted by the recipient,
         * we make sure that at least one PSS-related parameter is passed, even
         * if it has a default value; saltlen.
         */
        if ((mdname != NULL
             && !ossl_param_build_set_utf8_string(bld, params, key_md, mdname))
            || (mgfname != NULL
                && !ossl_param_build_set_utf8_string(bld, params,
                                                     key_mgf, mgfname))
            || (mgf1mdname != NULL
                && !ossl_param_build_set_utf8_string(bld, params,
                                                     key_mgf1_md, mgf1mdname))
            || (!ossl_param_build_set_int(bld, params, key_saltlen, saltlen)))
            return 0;
    }
    return 1;
}

int ossl_rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params,
                                    int *defaults_set,
                                    const OSSL_PARAM params[],
                                    OSSL_LIB_CTX *libctx)
{
    const OSSL_PARAM *param_md, *param_mgf, *param_mgf1md,  *param_saltlen;
    const OSSL_PARAM *param_propq;
    const char *propq = NULL;
    EVP_MD *md = NULL, *mgf1md = NULL;
    int saltlen;
    int ret = 0;

    if (pss_params == NULL)
        return 0;
    param_propq =
        OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_DIGEST_PROPS);
    param_md =
        OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_DIGEST);
    param_mgf =
        OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_MASKGENFUNC);
    param_mgf1md =
        OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_MGF1_DIGEST);
    param_saltlen =
        OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_PSS_SALTLEN);

    if (param_propq != NULL) {
        if (param_propq->data_type == OSSL_PARAM_UTF8_STRING)
            propq = param_propq->data;
    }
    /*
     * If we get any of the parameters, we know we have at least some
     * restrictions, so we start by setting default values, and let each
     * parameter override their specific restriction data.
     */
    if (!*defaults_set
        && (param_md != NULL || param_mgf != NULL || param_mgf1md != NULL
            || param_saltlen != NULL)) {
        if (!ossl_rsa_pss_params_30_set_defaults(pss_params))
            return 0;
        *defaults_set = 1;
    }

    if (param_mgf != NULL) {
        int default_maskgenalg_nid = ossl_rsa_pss_params_30_maskgenalg(NULL);
        const char *mgfname = NULL;

        if (param_mgf->data_type == OSSL_PARAM_UTF8_STRING)
            mgfname = param_mgf->data;
        else if (!OSSL_PARAM_get_utf8_ptr(param_mgf, &mgfname))
            return 0;

        if (strcasecmp(param_mgf->data,
                       ossl_rsa_mgf_nid2name(default_maskgenalg_nid)) != 0)
            return 0;
    }

    /*
     * We're only interested in the NIDs that correspond to the MDs, so the
     * exact propquery is unimportant in the EVP_MD_fetch() calls below.
     */

    if (param_md != NULL) {
        const char *mdname = NULL;

        if (param_md->data_type == OSSL_PARAM_UTF8_STRING)
            mdname = param_md->data;
        else if (!OSSL_PARAM_get_utf8_ptr(param_mgf, &mdname))
            goto err;

        if ((md = EVP_MD_fetch(libctx, mdname, propq)) == NULL
            || !ossl_rsa_pss_params_30_set_hashalg(pss_params,
                                                   ossl_rsa_oaeppss_md2nid(md)))
            goto err;
    }

    if (param_mgf1md != NULL) {
        const char *mgf1mdname = NULL;

        if (param_mgf1md->data_type == OSSL_PARAM_UTF8_STRING)
            mgf1mdname = param_mgf1md->data;
        else if (!OSSL_PARAM_get_utf8_ptr(param_mgf, &mgf1mdname))
            goto err;

        if ((mgf1md = EVP_MD_fetch(libctx, mgf1mdname, propq)) == NULL
            || !ossl_rsa_pss_params_30_set_maskgenhashalg(
                    pss_params, ossl_rsa_oaeppss_md2nid(mgf1md)))
            goto err;
    }

    if (param_saltlen != NULL) {
        if (!OSSL_PARAM_get_int(param_saltlen, &saltlen)
            || !ossl_rsa_pss_params_30_set_saltlen(pss_params, saltlen))
            goto err;
    }

    ret = 1;

 err:
    EVP_MD_free(md);
    EVP_MD_free(mgf1md);
    return ret;
}

int ossl_rsa_is_foreign(const RSA *rsa)
{
#ifndef FIPS_MODULE
    if (rsa->engine != NULL || RSA_get_method(rsa) != RSA_PKCS1_OpenSSL())
        return 1;
#endif
    return 0;
}

static ossl_inline int rsa_bn_dup_check(BIGNUM **out, const BIGNUM *f)
{
    if (f != NULL && (*out = BN_dup(f)) == NULL)
        return 0;
    return 1;
}

RSA *ossl_rsa_dup(const RSA *rsa, int selection)
{
    RSA *dupkey = NULL;
#ifndef FIPS_MODULE
    int pnum, i;
#endif

    /* Do not try to duplicate foreign RSA keys */
    if (ossl_rsa_is_foreign(rsa))
        return NULL;

    if ((dupkey = ossl_rsa_new_with_ctx(rsa->libctx)) == NULL)
        return NULL;

    /* public key */
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
        if (!rsa_bn_dup_check(&dupkey->n, rsa->n))
            goto err;
        if (!rsa_bn_dup_check(&dupkey->e, rsa->e))
            goto err;
    }

    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {

        /* private key */
        if (!rsa_bn_dup_check(&dupkey->d, rsa->d))
            goto err;

        /* factors and crt params */
        if (!rsa_bn_dup_check(&dupkey->p, rsa->p))
            goto err;
        if (!rsa_bn_dup_check(&dupkey->q, rsa->q))
            goto err;
        if (!rsa_bn_dup_check(&dupkey->dmp1, rsa->dmp1))
            goto err;
        if (!rsa_bn_dup_check(&dupkey->dmq1, rsa->dmq1))
            goto err;
        if (!rsa_bn_dup_check(&dupkey->iqmp, rsa->iqmp))
            goto err;
    }

    dupkey->version = rsa->version;
    dupkey->flags = rsa->flags;
    /* we always copy the PSS parameters regardless of selection */
    dupkey->pss_params = rsa->pss_params;

#ifndef FIPS_MODULE
    /* multiprime */
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0
        && (pnum = sk_RSA_PRIME_INFO_num(rsa->prime_infos)) > 0) {
        dupkey->prime_infos = sk_RSA_PRIME_INFO_new_reserve(NULL, pnum);
        if (dupkey->prime_infos == NULL)
            goto err;
        for (i = 0; i < pnum; i++) {
            const RSA_PRIME_INFO *pinfo = NULL;
            RSA_PRIME_INFO *duppinfo = NULL;

            if ((duppinfo = OPENSSL_zalloc(sizeof(*duppinfo))) == NULL) {
                ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE);
                goto err;
            }
            /* push first so cleanup in error case works */
            (void)sk_RSA_PRIME_INFO_push(dupkey->prime_infos, duppinfo);

            pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i);
            if (!rsa_bn_dup_check(&duppinfo->r, pinfo->r))
                goto err;
            if (!rsa_bn_dup_check(&duppinfo->d, pinfo->d))
                goto err;
            if (!rsa_bn_dup_check(&duppinfo->t, pinfo->t))
                goto err;
        }
        if (!ossl_rsa_multip_calc_product(dupkey))
            goto err;
    }

    if (rsa->pss != NULL) {
        dupkey->pss = RSA_PSS_PARAMS_dup(rsa->pss);
        if (rsa->pss->maskGenAlgorithm != NULL
            && dupkey->pss->maskGenAlgorithm == NULL) {
            dupkey->pss->maskHash = ossl_x509_algor_mgf1_decode(rsa->pss->maskGenAlgorithm);
            if (dupkey->pss->maskHash == NULL)
                goto err;
        }
    }
    if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_RSA,
                            &dupkey->ex_data, &rsa->ex_data))
        goto err;
#endif

    return dupkey;

 err:
    RSA_free(dupkey);
    return NULL;
}

#ifndef FIPS_MODULE
RSA_PSS_PARAMS *ossl_rsa_pss_decode(const X509_ALGOR *alg)
{
    RSA_PSS_PARAMS *pss;

    pss = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(RSA_PSS_PARAMS),
                                    alg->parameter);

    if (pss == NULL)
        return NULL;

    if (pss->maskGenAlgorithm != NULL) {
        pss->maskHash = ossl_x509_algor_mgf1_decode(pss->maskGenAlgorithm);
        if (pss->maskHash == NULL) {
            RSA_PSS_PARAMS_free(pss);
            return NULL;
        }
    }

    return pss;
}

static int ossl_rsa_sync_to_pss_params_30(RSA *rsa)
{
    const RSA_PSS_PARAMS *legacy_pss = NULL;
    RSA_PSS_PARAMS_30 *pss = NULL;

    if (rsa != NULL
        && (legacy_pss = RSA_get0_pss_params(rsa)) != NULL
        && (pss = ossl_rsa_get0_pss_params_30(rsa)) != NULL) {
        const EVP_MD *md = NULL, *mgf1md = NULL;
        int md_nid, mgf1md_nid, saltlen, trailerField;
        RSA_PSS_PARAMS_30 pss_params;

        /*
         * We don't care about the validity of the fields here, we just
         * want to synchronise values.  Verifying here makes it impossible
         * to even read a key with invalid values, making it hard to test
         * a bad situation.
         *
         * Other routines use ossl_rsa_pss_get_param(), so the values will
         * be checked, eventually.
         */
        if (!ossl_rsa_pss_get_param_unverified(legacy_pss, &md, &mgf1md,
                                               &saltlen, &trailerField))
            return 0;
        md_nid = EVP_MD_get_type(md);
        mgf1md_nid = EVP_MD_get_type(mgf1md);
        if (!ossl_rsa_pss_params_30_set_defaults(&pss_params)
            || !ossl_rsa_pss_params_30_set_hashalg(&pss_params, md_nid)
            || !ossl_rsa_pss_params_30_set_maskgenhashalg(&pss_params,
                                                          mgf1md_nid)
            || !ossl_rsa_pss_params_30_set_saltlen(&pss_params, saltlen)
            || !ossl_rsa_pss_params_30_set_trailerfield(&pss_params,
                                                        trailerField))
            return 0;
        *pss = pss_params;
    }
    return 1;
}

int ossl_rsa_pss_get_param_unverified(const RSA_PSS_PARAMS *pss,
                                      const EVP_MD **pmd, const EVP_MD **pmgf1md,
                                      int *psaltlen, int *ptrailerField)
{
    RSA_PSS_PARAMS_30 pss_params;

    /* Get the defaults from the ONE place */
    (void)ossl_rsa_pss_params_30_set_defaults(&pss_params);

    if (pss == NULL)
        return 0;
    *pmd = ossl_x509_algor_get_md(pss->hashAlgorithm);
    if (*pmd == NULL)
        return 0;
    *pmgf1md = ossl_x509_algor_get_md(pss->maskHash);
    if (*pmgf1md == NULL)
        return 0;
    if (pss->saltLength)
        *psaltlen = ASN1_INTEGER_get(pss->saltLength);
    else
        *psaltlen = ossl_rsa_pss_params_30_saltlen(&pss_params);
    if (pss->trailerField)
        *ptrailerField = ASN1_INTEGER_get(pss->trailerField);
    else
        *ptrailerField = ossl_rsa_pss_params_30_trailerfield(&pss_params);

    return 1;
}

int ossl_rsa_param_decode(RSA *rsa, const X509_ALGOR *alg)
{
    RSA_PSS_PARAMS *pss;
    const ASN1_OBJECT *algoid;
    const void *algp;
    int algptype;

    X509_ALGOR_get0(&algoid, &algptype, &algp, alg);
    if (OBJ_obj2nid(algoid) != EVP_PKEY_RSA_PSS)
        return 1;
    if (algptype == V_ASN1_UNDEF)
        return 1;
    if (algptype != V_ASN1_SEQUENCE) {
        ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PSS_PARAMETERS);
        return 0;
    }
    if ((pss = ossl_rsa_pss_decode(alg)) == NULL
        || !ossl_rsa_set0_pss_params(rsa, pss)) {
        RSA_PSS_PARAMS_free(pss);
        return 0;
    }
    if (!ossl_rsa_sync_to_pss_params_30(rsa))
        return 0;
    return 1;
}

RSA *ossl_rsa_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf,
                             OSSL_LIB_CTX *libctx, const char *propq)
{
    const unsigned char *p;
    RSA *rsa;
    int pklen;
    const X509_ALGOR *alg;

    if (!PKCS8_pkey_get0(NULL, &p, &pklen, &alg, p8inf))
        return 0;
    rsa = d2i_RSAPrivateKey(NULL, &p, pklen);
    if (rsa == NULL) {
        ERR_raise(ERR_LIB_RSA, ERR_R_RSA_LIB);
        return NULL;
    }
    if (!ossl_rsa_param_decode(rsa, alg)) {
        RSA_free(rsa);
        return NULL;
    }

    RSA_clear_flags(rsa, RSA_FLAG_TYPE_MASK);
    switch (OBJ_obj2nid(alg->algorithm)) {
    case EVP_PKEY_RSA:
        RSA_set_flags(rsa, RSA_FLAG_TYPE_RSA);
        break;
    case EVP_PKEY_RSA_PSS:
        RSA_set_flags(rsa, RSA_FLAG_TYPE_RSASSAPSS);
        break;
    default:
        /* Leave the type bits zero */
        break;
    }

    return rsa;
}
#endif
