/*
 * 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 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/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_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);
}


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);
}


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);
