/*
 * QEMU Crypto akcipher algorithms
 *
 * Copyright (c) 2022 Bytedance
 * Author: lei he <helei.sig11@bytedance.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "der.h"
#include "rsakey.h"

static int extract_mpi(void *ctx, const uint8_t *value,
                       size_t vlen, Error **errp)
{
    QCryptoAkCipherMPI *mpi = (QCryptoAkCipherMPI *)ctx;
    if (vlen == 0) {
        error_setg(errp, "Empty mpi field");
        return -1;
    }
    mpi->data = g_memdup2(value, vlen);
    mpi->len = vlen;
    return 0;
}

static int extract_version(void *ctx, const uint8_t *value,
                           size_t vlen, Error **errp)
{
    uint8_t *version = (uint8_t *)ctx;
    if (vlen != 1 || *value > 1) {
        error_setg(errp, "Invalid rsakey version");
        return -1;
    }
    *version = *value;
    return 0;
}

static int extract_seq_content(void *ctx, const uint8_t *value,
                               size_t vlen, Error **errp)
{
    const uint8_t **content = (const uint8_t **)ctx;
    if (vlen == 0) {
        error_setg(errp, "Empty sequence");
        return -1;
    }
    *content = value;
    return 0;
}

/**
 *
 *        RsaPubKey ::= SEQUENCE {
 *             n           INTEGER
 *             e           INTEGER
 *         }
 */
static QCryptoAkCipherRSAKey *qcrypto_builtin_rsa_public_key_parse(
    const uint8_t *key, size_t keylen, Error **errp)
{
    QCryptoAkCipherRSAKey *rsa = g_new0(QCryptoAkCipherRSAKey, 1);
    const uint8_t *seq;
    size_t seq_length;
    int decode_ret;

    decode_ret = qcrypto_der_decode_seq(&key, &keylen,
                                        extract_seq_content, &seq, errp);
    if (decode_ret < 0 || keylen != 0) {
        goto error;
    }
    seq_length = decode_ret;

    if (qcrypto_der_decode_int(&seq, &seq_length, extract_mpi,
                               &rsa->n, errp) < 0 ||
        qcrypto_der_decode_int(&seq, &seq_length, extract_mpi,
                               &rsa->e, errp) < 0) {
        goto error;
    }
    if (seq_length != 0) {
        error_setg(errp, "Invalid RSA public key");
        goto error;
    }

    return rsa;

error:
    qcrypto_akcipher_rsakey_free(rsa);
    return NULL;
}

/**
 *        RsaPrivKey ::= SEQUENCE {
 *             version     INTEGER
 *             n           INTEGER
 *             e           INTEGER
 *             d           INTEGER
 *             p           INTEGER
 *             q           INTEGER
 *             dp          INTEGER
 *             dq          INTEGER
 *             u           INTEGER
 *       otherPrimeInfos   OtherPrimeInfos OPTIONAL
 *         }
 */
static QCryptoAkCipherRSAKey *qcrypto_builtin_rsa_private_key_parse(
    const uint8_t *key, size_t keylen, Error **errp)
{
    QCryptoAkCipherRSAKey *rsa = g_new0(QCryptoAkCipherRSAKey, 1);
    uint8_t version;
    const uint8_t *seq;
    int decode_ret;
    size_t seq_length;

    decode_ret = qcrypto_der_decode_seq(&key, &keylen, extract_seq_content,
                                        &seq, errp);
    if (decode_ret < 0 || keylen != 0) {
        goto error;
    }
    seq_length = decode_ret;

    decode_ret = qcrypto_der_decode_int(&seq, &seq_length, extract_version,
                                        &version, errp);

    if (qcrypto_der_decode_int(&seq, &seq_length, extract_mpi,
                               &rsa->n, errp) < 0 ||
        qcrypto_der_decode_int(&seq, &seq_length, extract_mpi,
                               &rsa->e, errp) < 0 ||
        qcrypto_der_decode_int(&seq, &seq_length, extract_mpi,
                               &rsa->d, errp) < 0 ||
        qcrypto_der_decode_int(&seq, &seq_length, extract_mpi, &rsa->p,
                               errp) < 0 ||
        qcrypto_der_decode_int(&seq, &seq_length, extract_mpi, &rsa->q,
                               errp) < 0 ||
        qcrypto_der_decode_int(&seq, &seq_length, extract_mpi, &rsa->dp,
                               errp) < 0 ||
        qcrypto_der_decode_int(&seq, &seq_length, extract_mpi, &rsa->dq,
                               errp) < 0 ||
        qcrypto_der_decode_int(&seq, &seq_length, extract_mpi, &rsa->u,
                               errp) < 0) {
        goto error;
    }

    /**
     * According to the standard, otherPrimeInfos must be present for version 1.
     * There is no strict verification here, this is to be compatible with
     * the unit test of the kernel. TODO: remove this until linux kernel's
     * unit-test is fixed.
     */
    if (version == 1 && seq_length != 0) {
        if (qcrypto_der_decode_seq(&seq, &seq_length, NULL, NULL, errp) < 0) {
            goto error;
        }
        if (seq_length != 0) {
            goto error;
        }
        return rsa;
    }
    if (seq_length != 0) {
        error_setg(errp, "Invalid RSA private key");
        goto error;
    }

    return rsa;

error:
    qcrypto_akcipher_rsakey_free(rsa);
    return NULL;
}

QCryptoAkCipherRSAKey *qcrypto_akcipher_rsakey_parse(
    QCryptoAkCipherKeyType type, const uint8_t *key,
    size_t keylen, Error **errp)
{
    switch (type) {
    case QCRYPTO_AK_CIPHER_KEY_TYPE_PRIVATE:
        return qcrypto_builtin_rsa_private_key_parse(key, keylen, errp);

    case QCRYPTO_AK_CIPHER_KEY_TYPE_PUBLIC:
        return qcrypto_builtin_rsa_public_key_parse(key, keylen, errp);

    default:
        error_setg(errp, "Unknown key type: %d", type);
        return NULL;
    }
}
