/*
 * QEMU crypto secret support
 *
 * Copyright (c) 2015 Red Hat, Inc.
 *
 * 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 "qemu/osdep.h"
#include "crypto/secret_common.h"
#include "crypto/cipher.h"
#include "qapi/error.h"
#include "qom/object_interfaces.h"
#include "qemu/base64.h"
#include "qemu/module.h"
#include "trace.h"


static void qcrypto_secret_decrypt(QCryptoSecretCommon *secret,
                                   const uint8_t *input,
                                   size_t inputlen,
                                   uint8_t **output,
                                   size_t *outputlen,
                                   Error **errp)
{
    g_autofree uint8_t *iv = NULL;
    g_autofree uint8_t *key = NULL;
    g_autofree uint8_t *ciphertext = NULL;
    size_t keylen, ciphertextlen, ivlen;
    g_autoptr(QCryptoCipher) aes = NULL;
    g_autofree uint8_t *plaintext = NULL;

    *output = NULL;
    *outputlen = 0;

    if (qcrypto_secret_lookup(secret->keyid,
                              &key, &keylen,
                              errp) < 0) {
        return;
    }

    if (keylen != 32) {
        error_setg(errp, "Key should be 32 bytes in length");
        return;
    }

    if (!secret->iv) {
        error_setg(errp, "IV is required to decrypt secret");
        return;
    }

    iv = qbase64_decode(secret->iv, -1, &ivlen, errp);
    if (!iv) {
        return;
    }
    if (ivlen != 16) {
        error_setg(errp, "IV should be 16 bytes in length not %zu",
                   ivlen);
        return;
    }

    aes = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_256,
                             QCRYPTO_CIPHER_MODE_CBC,
                             key, keylen,
                             errp);
    if (!aes) {
        return;
    }

    if (qcrypto_cipher_setiv(aes, iv, ivlen, errp) < 0) {
        return;
    }

    if (secret->format == QCRYPTO_SECRET_FORMAT_BASE64) {
        ciphertext = qbase64_decode((const gchar *)input,
                                    inputlen,
                                    &ciphertextlen,
                                    errp);
        if (!ciphertext) {
            return;
        }
        plaintext = g_new0(uint8_t, ciphertextlen + 1);
    } else {
        ciphertextlen = inputlen;
        plaintext = g_new0(uint8_t, inputlen + 1);
    }
    if (qcrypto_cipher_decrypt(aes,
                               ciphertext ? ciphertext : input,
                               plaintext,
                               ciphertextlen,
                               errp) < 0) {
        return;
    }

    if (plaintext[ciphertextlen - 1] > 16 ||
        plaintext[ciphertextlen - 1] > ciphertextlen) {
        error_setg(errp, "Incorrect number of padding bytes (%d) "
                   "found on decrypted data",
                   (int)plaintext[ciphertextlen - 1]);
        return;
    }

    /*
     *  Even though plaintext may contain arbitrary NUL
     * ensure it is explicitly NUL terminated.
     */
    ciphertextlen -= plaintext[ciphertextlen - 1];
    plaintext[ciphertextlen] = '\0';

    *output = g_steal_pointer(&plaintext);
    *outputlen = ciphertextlen;
}


static void qcrypto_secret_decode(const uint8_t *input,
                                  size_t inputlen,
                                  uint8_t **output,
                                  size_t *outputlen,
                                  Error **errp)
{
    *output = qbase64_decode((const gchar *)input,
                             inputlen,
                             outputlen,
                             errp);
}


static void
qcrypto_secret_prop_set_loaded(Object *obj,
                               bool value,
                               Error **errp)
{
    QCryptoSecretCommon *secret = QCRYPTO_SECRET_COMMON(obj);
    QCryptoSecretCommonClass *sec_class
                                = QCRYPTO_SECRET_COMMON_GET_CLASS(obj);

    if (value) {
        Error *local_err = NULL;
        uint8_t *input = NULL;
        size_t inputlen = 0;
        uint8_t *output = NULL;
        size_t outputlen = 0;

        if (sec_class->load_data) {
            sec_class->load_data(secret, &input, &inputlen, &local_err);
            if (local_err) {
                error_propagate(errp, local_err);
                return;
            }
        } else {
            error_setg(errp, "%s provides no 'load_data' method'",
                             object_get_typename(obj));
            return;
        }

        if (secret->keyid) {
            qcrypto_secret_decrypt(secret, input, inputlen,
                                   &output, &outputlen, &local_err);
            g_free(input);
            if (local_err) {
                error_propagate(errp, local_err);
                return;
            }
            input = output;
            inputlen = outputlen;
        } else {
            if (secret->format == QCRYPTO_SECRET_FORMAT_BASE64) {
                qcrypto_secret_decode(input, inputlen,
                                      &output, &outputlen, &local_err);
                g_free(input);
                if (local_err) {
                    error_propagate(errp, local_err);
                    return;
                }
                input = output;
                inputlen = outputlen;
            }
        }

        secret->rawdata = input;
        secret->rawlen = inputlen;
    } else {
        g_free(secret->rawdata);
        secret->rawlen = 0;
    }
}


static bool
qcrypto_secret_prop_get_loaded(Object *obj,
                               Error **errp G_GNUC_UNUSED)
{
    QCryptoSecretCommon *secret = QCRYPTO_SECRET_COMMON(obj);
    return secret->rawdata != NULL;
}


static void
qcrypto_secret_prop_set_format(Object *obj,
                               int value,
                               Error **errp G_GNUC_UNUSED)
{
    QCryptoSecretCommon *creds = QCRYPTO_SECRET_COMMON(obj);
    creds->format = value;
}


static int
qcrypto_secret_prop_get_format(Object *obj,
                               Error **errp G_GNUC_UNUSED)
{
    QCryptoSecretCommon *creds = QCRYPTO_SECRET_COMMON(obj);
    return creds->format;
}


static void
qcrypto_secret_prop_set_iv(Object *obj,
                           const char *value,
                           Error **errp)
{
    QCryptoSecretCommon *secret = QCRYPTO_SECRET_COMMON(obj);

    g_free(secret->iv);
    secret->iv = g_strdup(value);
}


static char *
qcrypto_secret_prop_get_iv(Object *obj,
                           Error **errp)
{
    QCryptoSecretCommon *secret = QCRYPTO_SECRET_COMMON(obj);
    return g_strdup(secret->iv);
}


static void
qcrypto_secret_prop_set_keyid(Object *obj,
                              const char *value,
                              Error **errp)
{
    QCryptoSecretCommon *secret = QCRYPTO_SECRET_COMMON(obj);

    g_free(secret->keyid);
    secret->keyid = g_strdup(value);
}


static char *
qcrypto_secret_prop_get_keyid(Object *obj,
                              Error **errp)
{
    QCryptoSecretCommon *secret = QCRYPTO_SECRET_COMMON(obj);
    return g_strdup(secret->keyid);
}


static void
qcrypto_secret_finalize(Object *obj)
{
    QCryptoSecretCommon *secret = QCRYPTO_SECRET_COMMON(obj);

    g_free(secret->iv);
    g_free(secret->keyid);
    g_free(secret->rawdata);
}

static void
qcrypto_secret_class_init(ObjectClass *oc, void *data)
{
    object_class_property_add_bool(oc, "loaded",
                                   qcrypto_secret_prop_get_loaded,
                                   qcrypto_secret_prop_set_loaded);
    object_class_property_add_enum(oc, "format",
                                   "QCryptoSecretFormat",
                                   &QCryptoSecretFormat_lookup,
                                   qcrypto_secret_prop_get_format,
                                   qcrypto_secret_prop_set_format);
    object_class_property_add_str(oc, "keyid",
                                  qcrypto_secret_prop_get_keyid,
                                  qcrypto_secret_prop_set_keyid);
    object_class_property_add_str(oc, "iv",
                                  qcrypto_secret_prop_get_iv,
                                  qcrypto_secret_prop_set_iv);
}


int qcrypto_secret_lookup(const char *secretid,
                          uint8_t **data,
                          size_t *datalen,
                          Error **errp)
{
    Object *obj;
    QCryptoSecretCommon *secret;

    obj = object_resolve_path_component(
        object_get_objects_root(), secretid);
    if (!obj) {
        error_setg(errp, "No secret with id '%s'", secretid);
        return -1;
    }

    secret = (QCryptoSecretCommon *)
        object_dynamic_cast(obj,
                            TYPE_QCRYPTO_SECRET_COMMON);
    if (!secret) {
        error_setg(errp, "Object with id '%s' is not a secret",
                   secretid);
        return -1;
    }

    if (!secret->rawdata) {
        error_setg(errp, "Secret with id '%s' has no data",
                   secretid);
        return -1;
    }

    *data = g_new0(uint8_t, secret->rawlen + 1);
    memcpy(*data, secret->rawdata, secret->rawlen);
    (*data)[secret->rawlen] = '\0';
    *datalen = secret->rawlen;

    return 0;
}


char *qcrypto_secret_lookup_as_utf8(const char *secretid,
                                    Error **errp)
{
    uint8_t *data;
    size_t datalen;

    if (qcrypto_secret_lookup(secretid,
                              &data,
                              &datalen,
                              errp) < 0) {
        return NULL;
    }

    if (!g_utf8_validate((const gchar *)data, datalen, NULL)) {
        error_setg(errp,
                   "Data from secret %s is not valid UTF-8",
                   secretid);
        g_free(data);
        return NULL;
    }

    return (char *)data;
}


char *qcrypto_secret_lookup_as_base64(const char *secretid,
                                      Error **errp)
{
    uint8_t *data;
    size_t datalen;
    char *ret;

    if (qcrypto_secret_lookup(secretid,
                              &data,
                              &datalen,
                              errp) < 0) {
        return NULL;
    }

    ret = g_base64_encode(data, datalen);
    g_free(data);
    return ret;
}


static const TypeInfo qcrypto_secret_info = {
    .parent = TYPE_OBJECT,
    .name = TYPE_QCRYPTO_SECRET_COMMON,
    .instance_size = sizeof(QCryptoSecretCommon),
    .instance_finalize = qcrypto_secret_finalize,
    .class_size = sizeof(QCryptoSecretCommonClass),
    .class_init = qcrypto_secret_class_init,
    .abstract = true,
};


static void
qcrypto_secret_register_types(void)
{
    type_register_static(&qcrypto_secret_info);
}


type_init(qcrypto_secret_register_types);
