/*
 * QEMU VNC display driver: TLS helpers
 *
 * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
 * Copyright (C) 2006 Fabrice Bellard
 * Copyright (C) 2009 Red Hat, Inc
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu-x509.h"
#include "vnc.h"
#include "qemu_socket.h"

#if defined(_VNC_DEBUG) && _VNC_DEBUG >= 2
/* Very verbose, so only enabled for _VNC_DEBUG >= 2 */
static void vnc_debug_gnutls_log(int level, const char* str) {
    VNC_DEBUG("%d %s", level, str);
}
#endif /* defined(_VNC_DEBUG) && _VNC_DEBUG >= 2 */


#define DH_BITS 1024
static gnutls_dh_params_t dh_params;

static int vnc_tls_initialize(void)
{
    static int tlsinitialized = 0;

    if (tlsinitialized)
        return 1;

    if (gnutls_global_init () < 0)
        return 0;

    /* XXX ought to re-generate diffie-hellmen params periodically */
    if (gnutls_dh_params_init (&dh_params) < 0)
        return 0;
    if (gnutls_dh_params_generate2 (dh_params, DH_BITS) < 0)
        return 0;

#if defined(_VNC_DEBUG) && _VNC_DEBUG >= 2
    gnutls_global_set_log_level(10);
    gnutls_global_set_log_function(vnc_debug_gnutls_log);
#endif

    tlsinitialized = 1;

    return 1;
}

static ssize_t vnc_tls_push(gnutls_transport_ptr_t transport,
                            const void *data,
                            size_t len) {
    struct VncState *vs = (struct VncState *)transport;
    int ret;

 retry:
    ret = send(vs->csock, data, len, 0);
    if (ret < 0) {
        if (errno == EINTR)
            goto retry;
        return -1;
    }
    return ret;
}


static ssize_t vnc_tls_pull(gnutls_transport_ptr_t transport,
                            void *data,
                            size_t len) {
    struct VncState *vs = (struct VncState *)transport;
    int ret;

 retry:
    ret = qemu_recv(vs->csock, data, len, 0);
    if (ret < 0) {
        if (errno == EINTR)
            goto retry;
        return -1;
    }
    return ret;
}


static gnutls_anon_server_credentials vnc_tls_initialize_anon_cred(void)
{
    gnutls_anon_server_credentials anon_cred;
    int ret;

    if ((ret = gnutls_anon_allocate_server_credentials(&anon_cred)) < 0) {
        VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
        return NULL;
    }

    gnutls_anon_set_server_dh_params(anon_cred, dh_params);

    return anon_cred;
}


static gnutls_certificate_credentials_t vnc_tls_initialize_x509_cred(VncDisplay *vd)
{
    gnutls_certificate_credentials_t x509_cred;
    int ret;

    if (!vd->tls.x509cacert) {
        VNC_DEBUG("No CA x509 certificate specified\n");
        return NULL;
    }
    if (!vd->tls.x509cert) {
        VNC_DEBUG("No server x509 certificate specified\n");
        return NULL;
    }
    if (!vd->tls.x509key) {
        VNC_DEBUG("No server private key specified\n");
        return NULL;
    }

    if ((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) {
        VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));
        return NULL;
    }
    if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred,
                                                      vd->tls.x509cacert,
                                                      GNUTLS_X509_FMT_PEM)) < 0) {
        VNC_DEBUG("Cannot load CA certificate %s\n", gnutls_strerror(ret));
        gnutls_certificate_free_credentials(x509_cred);
        return NULL;
    }

    if ((ret = gnutls_certificate_set_x509_key_file (x509_cred,
                                                     vd->tls.x509cert,
                                                     vd->tls.x509key,
                                                     GNUTLS_X509_FMT_PEM)) < 0) {
        VNC_DEBUG("Cannot load certificate & key %s\n", gnutls_strerror(ret));
        gnutls_certificate_free_credentials(x509_cred);
        return NULL;
    }

    if (vd->tls.x509cacrl) {
        if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred,
                                                        vd->tls.x509cacrl,
                                                        GNUTLS_X509_FMT_PEM)) < 0) {
            VNC_DEBUG("Cannot load CRL %s\n", gnutls_strerror(ret));
            gnutls_certificate_free_credentials(x509_cred);
            return NULL;
        }
    }

    gnutls_certificate_set_dh_params (x509_cred, dh_params);

    return x509_cred;
}


int vnc_tls_validate_certificate(struct VncState *vs)
{
    int ret;
    unsigned int status;
    const gnutls_datum_t *certs;
    unsigned int nCerts, i;
    time_t now;

    VNC_DEBUG("Validating client certificate\n");
    if ((ret = gnutls_certificate_verify_peers2 (vs->tls.session, &status)) < 0) {
        VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret));
        return -1;
    }

    if ((now = time(NULL)) == ((time_t)-1)) {
        return -1;
    }

    if (status != 0) {
        if (status & GNUTLS_CERT_INVALID)
            VNC_DEBUG("The certificate is not trusted.\n");

        if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
            VNC_DEBUG("The certificate hasn't got a known issuer.\n");

        if (status & GNUTLS_CERT_REVOKED)
            VNC_DEBUG("The certificate has been revoked.\n");

        if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
            VNC_DEBUG("The certificate uses an insecure algorithm\n");

        return -1;
    } else {
        VNC_DEBUG("Certificate is valid!\n");
    }

    /* Only support x509 for now */
    if (gnutls_certificate_type_get(vs->tls.session) != GNUTLS_CRT_X509)
        return -1;

    if (!(certs = gnutls_certificate_get_peers(vs->tls.session, &nCerts)))
        return -1;

    for (i = 0 ; i < nCerts ; i++) {
        gnutls_x509_crt_t cert;
        VNC_DEBUG ("Checking certificate chain %d\n", i);
        if (gnutls_x509_crt_init (&cert) < 0)
            return -1;

        if (gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER) < 0) {
            gnutls_x509_crt_deinit (cert);
            return -1;
        }

        if (gnutls_x509_crt_get_expiration_time (cert) < now) {
            VNC_DEBUG("The certificate has expired\n");
            gnutls_x509_crt_deinit (cert);
            return -1;
        }

        if (gnutls_x509_crt_get_activation_time (cert) > now) {
            VNC_DEBUG("The certificate is not yet activated\n");
            gnutls_x509_crt_deinit (cert);
            return -1;
        }

        if (gnutls_x509_crt_get_activation_time (cert) > now) {
            VNC_DEBUG("The certificate is not yet activated\n");
            gnutls_x509_crt_deinit (cert);
            return -1;
        }

        if (i == 0) {
            size_t dnameSize = 1024;
            vs->tls.dname = qemu_malloc(dnameSize);
        requery:
            if ((ret = gnutls_x509_crt_get_dn (cert, vs->tls.dname, &dnameSize)) != 0) {
                if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
                    vs->tls.dname = qemu_realloc(vs->tls.dname, dnameSize);
                    goto requery;
                }
                gnutls_x509_crt_deinit (cert);
                VNC_DEBUG("Cannot get client distinguished name: %s",
                          gnutls_strerror (ret));
                return -1;
            }

            if (vs->vd->tls.x509verify) {
                int allow;
                if (!vs->vd->tls.acl) {
                    VNC_DEBUG("no ACL activated, allowing access");
                    gnutls_x509_crt_deinit (cert);
                    continue;
                }

                allow = qemu_acl_party_is_allowed(vs->vd->tls.acl,
                                                  vs->tls.dname);

                VNC_DEBUG("TLS x509 ACL check for %s is %s\n",
                          vs->tls.dname, allow ? "allowed" : "denied");
                if (!allow) {
                    gnutls_x509_crt_deinit (cert);
                    return -1;
                }
            }
        }

        gnutls_x509_crt_deinit (cert);
    }

    return 0;
}


int vnc_tls_client_setup(struct VncState *vs,
                         int needX509Creds) {
    static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
    static const int protocol_priority[]= { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };
    static const int kx_anon[] = {GNUTLS_KX_ANON_DH, 0};
    static const int kx_x509[] = {GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0};

    VNC_DEBUG("Do TLS setup\n");
    if (vnc_tls_initialize() < 0) {
        VNC_DEBUG("Failed to init TLS\n");
        vnc_client_error(vs);
        return -1;
    }
    if (vs->tls.session == NULL) {
        if (gnutls_init(&vs->tls.session, GNUTLS_SERVER) < 0) {
            vnc_client_error(vs);
            return -1;
        }

        if (gnutls_set_default_priority(vs->tls.session) < 0) {
            gnutls_deinit(vs->tls.session);
            vs->tls.session = NULL;
            vnc_client_error(vs);
            return -1;
        }

        if (gnutls_kx_set_priority(vs->tls.session, needX509Creds ? kx_x509 : kx_anon) < 0) {
            gnutls_deinit(vs->tls.session);
            vs->tls.session = NULL;
            vnc_client_error(vs);
            return -1;
        }

        if (gnutls_certificate_type_set_priority(vs->tls.session, cert_type_priority) < 0) {
            gnutls_deinit(vs->tls.session);
            vs->tls.session = NULL;
            vnc_client_error(vs);
            return -1;
        }

        if (gnutls_protocol_set_priority(vs->tls.session, protocol_priority) < 0) {
            gnutls_deinit(vs->tls.session);
            vs->tls.session = NULL;
            vnc_client_error(vs);
            return -1;
        }

        if (needX509Creds) {
            gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs->vd);
            if (!x509_cred) {
                gnutls_deinit(vs->tls.session);
                vs->tls.session = NULL;
                vnc_client_error(vs);
                return -1;
            }
            if (gnutls_credentials_set(vs->tls.session, GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) {
                gnutls_deinit(vs->tls.session);
                vs->tls.session = NULL;
                gnutls_certificate_free_credentials(x509_cred);
                vnc_client_error(vs);
                return -1;
            }
            if (vs->vd->tls.x509verify) {
                VNC_DEBUG("Requesting a client certificate\n");
                gnutls_certificate_server_set_request (vs->tls.session, GNUTLS_CERT_REQUEST);
            }

        } else {
            gnutls_anon_server_credentials anon_cred = vnc_tls_initialize_anon_cred();
            if (!anon_cred) {
                gnutls_deinit(vs->tls.session);
                vs->tls.session = NULL;
                vnc_client_error(vs);
                return -1;
            }
            if (gnutls_credentials_set(vs->tls.session, GNUTLS_CRD_ANON, anon_cred) < 0) {
                gnutls_deinit(vs->tls.session);
                vs->tls.session = NULL;
                gnutls_anon_free_server_credentials(anon_cred);
                vnc_client_error(vs);
                return -1;
            }
        }

        gnutls_transport_set_ptr(vs->tls.session, (gnutls_transport_ptr_t)vs);
        gnutls_transport_set_push_function(vs->tls.session, vnc_tls_push);
        gnutls_transport_set_pull_function(vs->tls.session, vnc_tls_pull);
    }
    return 0;
}


void vnc_tls_client_cleanup(struct VncState *vs)
{
    if (vs->tls.session) {
        gnutls_deinit(vs->tls.session);
        vs->tls.session = NULL;
    }
    vs->tls.wiremode = VNC_WIREMODE_CLEAR;
    free(vs->tls.dname);
}



static int vnc_set_x509_credential(VncDisplay *vd,
                                   const char *certdir,
                                   const char *filename,
                                   char **cred,
                                   int ignoreMissing)
{
    struct stat sb;

    if (*cred) {
        qemu_free(*cred);
        *cred = NULL;
    }

    *cred = qemu_malloc(strlen(certdir) + strlen(filename) + 2);

    strcpy(*cred, certdir);
    strcat(*cred, "/");
    strcat(*cred, filename);

    VNC_DEBUG("Check %s\n", *cred);
    if (stat(*cred, &sb) < 0) {
        qemu_free(*cred);
        *cred = NULL;
        if (ignoreMissing && errno == ENOENT)
            return 0;
        return -1;
    }

    return 0;
}


int vnc_tls_set_x509_creds_dir(VncDisplay *vd,
                               const char *certdir)
{
    if (vnc_set_x509_credential(vd, certdir, X509_CA_CERT_FILE, &vd->tls.x509cacert, 0) < 0)
        goto cleanup;
    if (vnc_set_x509_credential(vd, certdir, X509_CA_CRL_FILE, &vd->tls.x509cacrl, 1) < 0)
        goto cleanup;
    if (vnc_set_x509_credential(vd, certdir, X509_SERVER_CERT_FILE, &vd->tls.x509cert, 0) < 0)
        goto cleanup;
    if (vnc_set_x509_credential(vd, certdir, X509_SERVER_KEY_FILE, &vd->tls.x509key, 0) < 0)
        goto cleanup;

    return 0;

 cleanup:
    qemu_free(vd->tls.x509cacert);
    qemu_free(vd->tls.x509cacrl);
    qemu_free(vd->tls.x509cert);
    qemu_free(vd->tls.x509key);
    vd->tls.x509cacert = vd->tls.x509cacrl = vd->tls.x509cert = vd->tls.x509key = NULL;
    return -1;
}

