/*
 * QEMU crypto TLS credential 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 "qapi/error.h"
#include "qemu/module.h"
#include "tlscredspriv.h"
#include "trace.h"

#define DH_BITS 2048

#ifdef CONFIG_GNUTLS
int
qcrypto_tls_creds_get_dh_params_file(QCryptoTLSCreds *creds,
                                     const char *filename,
                                     gnutls_dh_params_t *dh_params,
                                     Error **errp)
{
    int ret;

    trace_qcrypto_tls_creds_load_dh(creds, filename ? filename : "<generated>");

    if (filename == NULL) {
        ret = gnutls_dh_params_init(dh_params);
        if (ret < 0) {
            error_setg(errp, "Unable to initialize DH parameters: %s",
                       gnutls_strerror(ret));
            return -1;
        }
        ret = gnutls_dh_params_generate2(*dh_params, DH_BITS);
        if (ret < 0) {
            gnutls_dh_params_deinit(*dh_params);
            *dh_params = NULL;
            error_setg(errp, "Unable to generate DH parameters: %s",
                       gnutls_strerror(ret));
            return -1;
        }
    } else {
        GError *gerr = NULL;
        gchar *contents;
        gsize len;
        gnutls_datum_t data;
        if (!g_file_get_contents(filename,
                                 &contents,
                                 &len,
                                 &gerr)) {

            error_setg(errp, "%s", gerr->message);
            g_error_free(gerr);
            return -1;
        }
        data.data = (unsigned char *)contents;
        data.size = len;
        ret = gnutls_dh_params_init(dh_params);
        if (ret < 0) {
            g_free(contents);
            error_setg(errp, "Unable to initialize DH parameters: %s",
                       gnutls_strerror(ret));
            return -1;
        }
        ret = gnutls_dh_params_import_pkcs3(*dh_params,
                                            &data,
                                            GNUTLS_X509_FMT_PEM);
        g_free(contents);
        if (ret < 0) {
            gnutls_dh_params_deinit(*dh_params);
            *dh_params = NULL;
            error_setg(errp, "Unable to load DH parameters from %s: %s",
                       filename, gnutls_strerror(ret));
            return -1;
        }
    }

    return 0;
}


int
qcrypto_tls_creds_get_path(QCryptoTLSCreds *creds,
                           const char *filename,
                           bool required,
                           char **cred,
                           Error **errp)
{
    struct stat sb;
    int ret = -1;

    if (!creds->dir) {
        if (required) {
            error_setg(errp, "Missing 'dir' property value");
            return -1;
        } else {
            return 0;
        }
    }

    *cred = g_strdup_printf("%s/%s", creds->dir, filename);

    if (stat(*cred, &sb) < 0) {
        if (errno == ENOENT && !required) {
            ret = 0;
        } else {
            error_setg_errno(errp, errno,
                             "Unable to access credentials %s",
                             *cred);
        }
        g_free(*cred);
        *cred = NULL;
        goto cleanup;
    }

    ret = 0;
 cleanup:
    trace_qcrypto_tls_creds_get_path(creds, filename,
                                     *cred ? *cred : "<none>");
    return ret;
}


#endif /* ! CONFIG_GNUTLS */


static void
qcrypto_tls_creds_prop_set_verify(Object *obj,
                                  bool value,
                                  Error **errp G_GNUC_UNUSED)
{
    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);

    creds->verifyPeer = value;
}


static bool
qcrypto_tls_creds_prop_get_verify(Object *obj,
                                  Error **errp G_GNUC_UNUSED)
{
    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);

    return creds->verifyPeer;
}


static void
qcrypto_tls_creds_prop_set_dir(Object *obj,
                               const char *value,
                               Error **errp G_GNUC_UNUSED)
{
    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);

    creds->dir = g_strdup(value);
}


static char *
qcrypto_tls_creds_prop_get_dir(Object *obj,
                               Error **errp G_GNUC_UNUSED)
{
    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);

    return g_strdup(creds->dir);
}


static void
qcrypto_tls_creds_prop_set_priority(Object *obj,
                                    const char *value,
                                    Error **errp G_GNUC_UNUSED)
{
    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);

    creds->priority = g_strdup(value);
}


static char *
qcrypto_tls_creds_prop_get_priority(Object *obj,
                                    Error **errp G_GNUC_UNUSED)
{
    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);

    return g_strdup(creds->priority);
}


static void
qcrypto_tls_creds_prop_set_endpoint(Object *obj,
                                    int value,
                                    Error **errp G_GNUC_UNUSED)
{
    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);

    creds->endpoint = value;
}


static int
qcrypto_tls_creds_prop_get_endpoint(Object *obj,
                                    Error **errp G_GNUC_UNUSED)
{
    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);

    return creds->endpoint;
}


static void
qcrypto_tls_creds_class_init(ObjectClass *oc, void *data)
{
    object_class_property_add_bool(oc, "verify-peer",
                                   qcrypto_tls_creds_prop_get_verify,
                                   qcrypto_tls_creds_prop_set_verify,
                                   NULL);
    object_class_property_add_str(oc, "dir",
                                  qcrypto_tls_creds_prop_get_dir,
                                  qcrypto_tls_creds_prop_set_dir,
                                  NULL);
    object_class_property_add_enum(oc, "endpoint",
                                   "QCryptoTLSCredsEndpoint",
                                   &QCryptoTLSCredsEndpoint_lookup,
                                   qcrypto_tls_creds_prop_get_endpoint,
                                   qcrypto_tls_creds_prop_set_endpoint,
                                   NULL);
    object_class_property_add_str(oc, "priority",
                                  qcrypto_tls_creds_prop_get_priority,
                                  qcrypto_tls_creds_prop_set_priority,
                                  NULL);
}


static void
qcrypto_tls_creds_init(Object *obj)
{
    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);

    creds->verifyPeer = true;
}


static void
qcrypto_tls_creds_finalize(Object *obj)
{
    QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);

    g_free(creds->dir);
    g_free(creds->priority);
}


static const TypeInfo qcrypto_tls_creds_info = {
    .parent = TYPE_OBJECT,
    .name = TYPE_QCRYPTO_TLS_CREDS,
    .instance_size = sizeof(QCryptoTLSCreds),
    .instance_init = qcrypto_tls_creds_init,
    .instance_finalize = qcrypto_tls_creds_finalize,
    .class_init = qcrypto_tls_creds_class_init,
    .class_size = sizeof(QCryptoTLSCredsClass),
    .abstract = true,
};


static void
qcrypto_tls_creds_register_types(void)
{
    type_register_static(&qcrypto_tls_creds_info);
}


type_init(qcrypto_tls_creds_register_types);
