/*
 * QEMU crypto TLS session 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 "crypto/tlssession.h"
#include "crypto/tlscredsanon.h"
#include "crypto/tlscredsx509.h"
#include "qemu/acl.h"
#include "trace.h"

#ifdef CONFIG_GNUTLS


#include <gnutls/x509.h>


struct QCryptoTLSSession {
    QCryptoTLSCreds *creds;
    gnutls_session_t handle;
    char *hostname;
    char *aclname;
    bool handshakeComplete;
    QCryptoTLSSessionWriteFunc writeFunc;
    QCryptoTLSSessionReadFunc readFunc;
    void *opaque;
    char *peername;
};


void
qcrypto_tls_session_free(QCryptoTLSSession *session)
{
    if (!session) {
        return;
    }

    gnutls_deinit(session->handle);
    g_free(session->hostname);
    g_free(session->peername);
    g_free(session->aclname);
    object_unref(OBJECT(session->creds));
    g_free(session);
}


static ssize_t
qcrypto_tls_session_push(void *opaque, const void *buf, size_t len)
{
    QCryptoTLSSession *session = opaque;

    if (!session->writeFunc) {
        errno = EIO;
        return -1;
    };

    return session->writeFunc(buf, len, session->opaque);
}


static ssize_t
qcrypto_tls_session_pull(void *opaque, void *buf, size_t len)
{
    QCryptoTLSSession *session = opaque;

    if (!session->readFunc) {
        errno = EIO;
        return -1;
    };

    return session->readFunc(buf, len, session->opaque);
}


QCryptoTLSSession *
qcrypto_tls_session_new(QCryptoTLSCreds *creds,
                        const char *hostname,
                        const char *aclname,
                        QCryptoTLSCredsEndpoint endpoint,
                        Error **errp)
{
    QCryptoTLSSession *session;
    int ret;

    session = g_new0(QCryptoTLSSession, 1);
    trace_qcrypto_tls_session_new(
        session, creds, hostname ? hostname : "<none>",
        aclname ? aclname : "<none>", endpoint);

    if (hostname) {
        session->hostname = g_strdup(hostname);
    }
    if (aclname) {
        session->aclname = g_strdup(aclname);
    }
    session->creds = creds;
    object_ref(OBJECT(creds));

    if (creds->endpoint != endpoint) {
        error_setg(errp, "Credentials endpoint doesn't match session");
        goto error;
    }

    if (endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
        ret = gnutls_init(&session->handle, GNUTLS_SERVER);
    } else {
        ret = gnutls_init(&session->handle, GNUTLS_CLIENT);
    }
    if (ret < 0) {
        error_setg(errp, "Cannot initialize TLS session: %s",
                   gnutls_strerror(ret));
        goto error;
    }

    if (object_dynamic_cast(OBJECT(creds),
                            TYPE_QCRYPTO_TLS_CREDS_ANON)) {
        QCryptoTLSCredsAnon *acreds = QCRYPTO_TLS_CREDS_ANON(creds);

        ret = gnutls_priority_set_direct(session->handle,
                                         "NORMAL:+ANON-DH", NULL);
        if (ret < 0) {
            error_setg(errp, "Unable to set TLS session priority: %s",
                       gnutls_strerror(ret));
            goto error;
        }
        if (creds->endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
            ret = gnutls_credentials_set(session->handle,
                                         GNUTLS_CRD_ANON,
                                         acreds->data.server);
        } else {
            ret = gnutls_credentials_set(session->handle,
                                         GNUTLS_CRD_ANON,
                                         acreds->data.client);
        }
        if (ret < 0) {
            error_setg(errp, "Cannot set session credentials: %s",
                       gnutls_strerror(ret));
            goto error;
        }
    } else if (object_dynamic_cast(OBJECT(creds),
                                   TYPE_QCRYPTO_TLS_CREDS_X509)) {
        QCryptoTLSCredsX509 *tcreds = QCRYPTO_TLS_CREDS_X509(creds);

        ret = gnutls_set_default_priority(session->handle);
        if (ret < 0) {
            error_setg(errp, "Cannot set default TLS session priority: %s",
                       gnutls_strerror(ret));
            goto error;
        }
        ret = gnutls_credentials_set(session->handle,
                                     GNUTLS_CRD_CERTIFICATE,
                                     tcreds->data);
        if (ret < 0) {
            error_setg(errp, "Cannot set session credentials: %s",
                       gnutls_strerror(ret));
            goto error;
        }

        if (creds->endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
            /* This requests, but does not enforce a client cert.
             * The cert checking code later does enforcement */
            gnutls_certificate_server_set_request(session->handle,
                                                  GNUTLS_CERT_REQUEST);
        }
    } else {
        error_setg(errp, "Unsupported TLS credentials type %s",
                   object_get_typename(OBJECT(creds)));
        goto error;
    }

    gnutls_transport_set_ptr(session->handle, session);
    gnutls_transport_set_push_function(session->handle,
                                       qcrypto_tls_session_push);
    gnutls_transport_set_pull_function(session->handle,
                                       qcrypto_tls_session_pull);

    return session;

 error:
    qcrypto_tls_session_free(session);
    return NULL;
}

static int
qcrypto_tls_session_check_certificate(QCryptoTLSSession *session,
                                      Error **errp)
{
    int ret;
    unsigned int status;
    const gnutls_datum_t *certs;
    unsigned int nCerts, i;
    time_t now;
    gnutls_x509_crt_t cert = NULL;

    now = time(NULL);
    if (now == ((time_t)-1)) {
        error_setg_errno(errp, errno, "Cannot get current time");
        return -1;
    }

    ret = gnutls_certificate_verify_peers2(session->handle, &status);
    if (ret < 0) {
        error_setg(errp, "Verify failed: %s", gnutls_strerror(ret));
        return -1;
    }

    if (status != 0) {
        const char *reason = "Invalid certificate";

        if (status & GNUTLS_CERT_INVALID) {
            reason = "The certificate is not trusted";
        }

        if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) {
            reason = "The certificate hasn't got a known issuer";
        }

        if (status & GNUTLS_CERT_REVOKED) {
            reason = "The certificate has been revoked";
        }

        if (status & GNUTLS_CERT_INSECURE_ALGORITHM) {
            reason = "The certificate uses an insecure algorithm";
        }

        error_setg(errp, "%s", reason);
        return -1;
    }

    certs = gnutls_certificate_get_peers(session->handle, &nCerts);
    if (!certs) {
        error_setg(errp, "No certificate peers");
        return -1;
    }

    for (i = 0; i < nCerts; i++) {
        ret = gnutls_x509_crt_init(&cert);
        if (ret < 0) {
            error_setg(errp, "Cannot initialize certificate: %s",
                       gnutls_strerror(ret));
            return -1;
        }

        ret = gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER);
        if (ret < 0) {
            error_setg(errp, "Cannot import certificate: %s",
                       gnutls_strerror(ret));
            goto error;
        }

        if (gnutls_x509_crt_get_expiration_time(cert) < now) {
            error_setg(errp, "The certificate has expired");
            goto error;
        }

        if (gnutls_x509_crt_get_activation_time(cert) > now) {
            error_setg(errp, "The certificate is not yet activated");
            goto error;
        }

        if (gnutls_x509_crt_get_activation_time(cert) > now) {
            error_setg(errp, "The certificate is not yet activated");
            goto error;
        }

        if (i == 0) {
            size_t dnameSize = 1024;
            session->peername = g_malloc(dnameSize);
        requery:
            ret = gnutls_x509_crt_get_dn(cert, session->peername, &dnameSize);
            if (ret < 0) {
                if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
                    session->peername = g_realloc(session->peername,
                                                  dnameSize);
                    goto requery;
                }
                error_setg(errp, "Cannot get client distinguished name: %s",
                           gnutls_strerror(ret));
                goto error;
            }
            if (session->aclname) {
                qemu_acl *acl = qemu_acl_find(session->aclname);
                int allow;
                if (!acl) {
                    error_setg(errp, "Cannot find ACL %s",
                               session->aclname);
                    goto error;
                }

                allow = qemu_acl_party_is_allowed(acl, session->peername);

                if (!allow) {
                    error_setg(errp, "TLS x509 ACL check for %s is denied",
                               session->peername);
                    goto error;
                }
            }
            if (session->hostname) {
                if (!gnutls_x509_crt_check_hostname(cert, session->hostname)) {
                    error_setg(errp,
                               "Certificate does not match the hostname %s",
                               session->hostname);
                    goto error;
                }
            }
        }

        gnutls_x509_crt_deinit(cert);
    }

    return 0;

 error:
    gnutls_x509_crt_deinit(cert);
    return -1;
}


int
qcrypto_tls_session_check_credentials(QCryptoTLSSession *session,
                                      Error **errp)
{
    if (object_dynamic_cast(OBJECT(session->creds),
                            TYPE_QCRYPTO_TLS_CREDS_ANON)) {
        return 0;
    } else if (object_dynamic_cast(OBJECT(session->creds),
                            TYPE_QCRYPTO_TLS_CREDS_X509)) {
        if (session->creds->verifyPeer) {
            return qcrypto_tls_session_check_certificate(session,
                                                         errp);
        } else {
            return 0;
        }
    } else {
        error_setg(errp, "Unexpected credential type %s",
                   object_get_typename(OBJECT(session->creds)));
        return -1;
    }
}


void
qcrypto_tls_session_set_callbacks(QCryptoTLSSession *session,
                                  QCryptoTLSSessionWriteFunc writeFunc,
                                  QCryptoTLSSessionReadFunc readFunc,
                                  void *opaque)
{
    session->writeFunc = writeFunc;
    session->readFunc = readFunc;
    session->opaque = opaque;
}


ssize_t
qcrypto_tls_session_write(QCryptoTLSSession *session,
                          const char *buf,
                          size_t len)
{
    ssize_t ret = gnutls_record_send(session->handle, buf, len);

    if (ret < 0) {
        switch (ret) {
        case GNUTLS_E_AGAIN:
            errno = EAGAIN;
            break;
        case GNUTLS_E_INTERRUPTED:
            errno = EINTR;
            break;
        default:
            errno = EIO;
            break;
        }
        ret = -1;
    }

    return ret;
}


ssize_t
qcrypto_tls_session_read(QCryptoTLSSession *session,
                         char *buf,
                         size_t len)
{
    ssize_t ret = gnutls_record_recv(session->handle, buf, len);

    if (ret < 0) {
        switch (ret) {
        case GNUTLS_E_AGAIN:
            errno = EAGAIN;
            break;
        case GNUTLS_E_INTERRUPTED:
            errno = EINTR;
            break;
        default:
            errno = EIO;
            break;
        }
        ret = -1;
    }

    return ret;
}


int
qcrypto_tls_session_handshake(QCryptoTLSSession *session,
                              Error **errp)
{
    int ret = gnutls_handshake(session->handle);
    if (ret == 0) {
        session->handshakeComplete = true;
    } else {
        if (ret == GNUTLS_E_INTERRUPTED ||
            ret == GNUTLS_E_AGAIN) {
            ret = 1;
        } else {
            error_setg(errp, "TLS handshake failed: %s",
                       gnutls_strerror(ret));
            ret = -1;
        }
    }

    return ret;
}


QCryptoTLSSessionHandshakeStatus
qcrypto_tls_session_get_handshake_status(QCryptoTLSSession *session)
{
    if (session->handshakeComplete) {
        return QCRYPTO_TLS_HANDSHAKE_COMPLETE;
    } else if (gnutls_record_get_direction(session->handle) == 0) {
        return QCRYPTO_TLS_HANDSHAKE_RECVING;
    } else {
        return QCRYPTO_TLS_HANDSHAKE_SENDING;
    }
}


int
qcrypto_tls_session_get_key_size(QCryptoTLSSession *session,
                                 Error **errp)
{
    gnutls_cipher_algorithm_t cipher;
    int ssf;

    cipher = gnutls_cipher_get(session->handle);
    ssf = gnutls_cipher_get_key_size(cipher);
    if (!ssf) {
        error_setg(errp, "Cannot get TLS cipher key size");
        return -1;
    }
    return ssf;
}


char *
qcrypto_tls_session_get_peer_name(QCryptoTLSSession *session)
{
    if (session->peername) {
        return g_strdup(session->peername);
    }
    return NULL;
}


#else /* ! CONFIG_GNUTLS */


QCryptoTLSSession *
qcrypto_tls_session_new(QCryptoTLSCreds *creds G_GNUC_UNUSED,
                        const char *hostname G_GNUC_UNUSED,
                        const char *aclname G_GNUC_UNUSED,
                        QCryptoTLSCredsEndpoint endpoint G_GNUC_UNUSED,
                        Error **errp)
{
    error_setg(errp, "TLS requires GNUTLS support");
    return NULL;
}


void
qcrypto_tls_session_free(QCryptoTLSSession *sess G_GNUC_UNUSED)
{
}


int
qcrypto_tls_session_check_credentials(QCryptoTLSSession *sess G_GNUC_UNUSED,
                                      Error **errp)
{
    error_setg(errp, "TLS requires GNUTLS support");
    return -1;
}


void
qcrypto_tls_session_set_callbacks(
    QCryptoTLSSession *sess G_GNUC_UNUSED,
    QCryptoTLSSessionWriteFunc writeFunc G_GNUC_UNUSED,
    QCryptoTLSSessionReadFunc readFunc G_GNUC_UNUSED,
    void *opaque G_GNUC_UNUSED)
{
}


ssize_t
qcrypto_tls_session_write(QCryptoTLSSession *sess,
                          const char *buf,
                          size_t len)
{
    errno = -EIO;
    return -1;
}


ssize_t
qcrypto_tls_session_read(QCryptoTLSSession *sess,
                         char *buf,
                         size_t len)
{
    errno = -EIO;
    return -1;
}


int
qcrypto_tls_session_handshake(QCryptoTLSSession *sess,
                              Error **errp)
{
    error_setg(errp, "TLS requires GNUTLS support");
    return -1;
}


QCryptoTLSSessionHandshakeStatus
qcrypto_tls_session_get_handshake_status(QCryptoTLSSession *sess)
{
    return QCRYPTO_TLS_HANDSHAKE_COMPLETE;
}


int
qcrypto_tls_session_get_key_size(QCryptoTLSSession *sess,
                                 Error **errp)
{
    error_setg(errp, "TLS requires GNUTLS support");
    return -1;
}


char *
qcrypto_tls_session_get_peer_name(QCryptoTLSSession *sess)
{
    return NULL;
}

#endif
