/*
 * QEMU TLS Cipher Suites
 *
 * Copyright (c) 2018-2020 Red Hat, Inc.
 *
 * Author: Philippe Mathieu-Daudé <philmd@redhat.com>
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qom/object_interfaces.h"
#include "crypto/tlscreds.h"
#include "crypto/tls-cipher-suites.h"
#include "hw/nvram/fw_cfg.h"
#include "trace.h"

/*
 * IANA registered TLS ciphers:
 * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4
 */
typedef struct {
    uint8_t data[2];
} QEMU_PACKED IANA_TLS_CIPHER;

GByteArray *qcrypto_tls_cipher_suites_get_data(QCryptoTLSCipherSuites *obj,
                                               Error **errp)
{
    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);
    gnutls_priority_t pcache;
    GByteArray *byte_array;
    const char *err;
    size_t i;
    int ret;

    trace_qcrypto_tls_cipher_suite_priority(creds->priority);
    ret = gnutls_priority_init(&pcache, creds->priority, &err);
    if (ret < 0) {
        error_setg(errp, "Syntax error using priority '%s': %s",
                   creds->priority, gnutls_strerror(ret));
        return NULL;
    }

    byte_array = g_byte_array_new();

    for (i = 0;; i++) {
        int ret;
        unsigned idx;
        const char *name;
        IANA_TLS_CIPHER cipher;
        gnutls_protocol_t protocol;
        const char *version;

        ret = gnutls_priority_get_cipher_suite_index(pcache, i, &idx);
        if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
            break;
        }
        if (ret == GNUTLS_E_UNKNOWN_CIPHER_SUITE) {
            continue;
        }

        name = gnutls_cipher_suite_info(idx, (unsigned char *)&cipher,
                                        NULL, NULL, NULL, &protocol);
        if (name == NULL) {
            continue;
        }

        version = gnutls_protocol_get_name(protocol);
        g_byte_array_append(byte_array, cipher.data, 2);
        trace_qcrypto_tls_cipher_suite_info(cipher.data[0],
                                            cipher.data[1],
                                            version, name);
    }
    trace_qcrypto_tls_cipher_suite_count(byte_array->len);
    gnutls_priority_deinit(pcache);

    return byte_array;
}

static void qcrypto_tls_cipher_suites_complete(UserCreatable *uc,
                                               Error **errp)
{
    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(uc);

    if (!creds->priority) {
        error_setg(errp, "'priority' property is not set");
        return;
    }
}

static GByteArray *qcrypto_tls_cipher_suites_fw_cfg_gen_data(Object *obj,
                                                             Error **errp)
{
    return qcrypto_tls_cipher_suites_get_data(QCRYPTO_TLS_CIPHER_SUITES(obj),
                                              errp);
}

static void qcrypto_tls_cipher_suites_class_init(ObjectClass *oc, void *data)
{
    UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
    FWCfgDataGeneratorClass *fwgc = FW_CFG_DATA_GENERATOR_CLASS(oc);

    ucc->complete = qcrypto_tls_cipher_suites_complete;
    fwgc->get_data = qcrypto_tls_cipher_suites_fw_cfg_gen_data;
}

static const TypeInfo qcrypto_tls_cipher_suites_info = {
    .parent = TYPE_QCRYPTO_TLS_CREDS,
    .name = TYPE_QCRYPTO_TLS_CIPHER_SUITES,
    .instance_size = sizeof(QCryptoTLSCreds),
    .class_size = sizeof(QCryptoTLSCredsClass),
    .class_init = qcrypto_tls_cipher_suites_class_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_USER_CREATABLE },
        { TYPE_FW_CFG_DATA_GENERATOR_INTERFACE },
        { }
    }
};

static void qcrypto_tls_cipher_suites_register_types(void)
{
    type_register_static(&qcrypto_tls_cipher_suites_info);
}

type_init(qcrypto_tls_cipher_suites_register_types);
