/*
 * 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 "tlscredspriv.h"
#include "trace.h"

struct QCryptoTLSCipherSuites {
    /* <private> */
    QCryptoTLSCreds parent_obj;
    /* <public> */
};

/*
 * 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++) {
        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(QCryptoTLSCipherSuites),
    .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);
