/*
 *  OpenVPN -- An application to securely tunnel IP networks
 *             over a single TCP/UDP port, with support for SSL/TLS-based
 *             session authentication and key exchange,
 *             packet encryption, packet authentication, and
 *             packet compression.
 *
 *  Copyright (C) 2002-2021 OpenVPN Inc <sales@openvpn.net>
 *  Copyright (C) 2010-2021 Fox Crypto B.V. <openvpn@foxcrypto.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2
 *  as published by the Free Software Foundation.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

/**
 * @file PKCS #11 OpenSSL backend
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#elif defined(_MSC_VER)
#include "config-msvc.h"
#endif

#include "syshead.h"

#if defined(ENABLE_PKCS11) && defined(ENABLE_CRYPTO_OPENSSL)

#include "errlevel.h"
#include "pkcs11_backend.h"
#include "ssl_verify.h"
#include <pkcs11-helper-1.0/pkcs11h-openssl.h>

int
pkcs11_init_tls_session(pkcs11h_certificate_t certificate,
                        struct tls_root_ctx *const ssl_ctx)
{
    int ret = 1;

    X509 *x509 = NULL;
    EVP_PKEY *evp = NULL;
    pkcs11h_openssl_session_t openssl_session = NULL;

    if ((openssl_session = pkcs11h_openssl_createSession(certificate)) == NULL)
    {
        msg(M_WARN, "PKCS#11: Cannot initialize openssl session");
        goto cleanup;
    }

    /*
     * Will be released by openssl_session
     */
    certificate = NULL;

    if ((evp = pkcs11h_openssl_session_getEVP(openssl_session)) == NULL)
    {
        msg(M_WARN, "PKCS#11: Unable get evp object");
        goto cleanup;
    }

    if ((x509 = pkcs11h_openssl_session_getX509(openssl_session)) == NULL)
    {
        msg(M_WARN, "PKCS#11: Unable get certificate object");
        goto cleanup;
    }

    if (!SSL_CTX_use_PrivateKey(ssl_ctx->ctx, evp))
    {
        msg(M_WARN, "PKCS#11: Cannot set private key for openssl");
        goto cleanup;
    }

    if (!SSL_CTX_use_certificate(ssl_ctx->ctx, x509))
    {
        msg(M_WARN, "PKCS#11: Cannot set certificate for openssl");
        goto cleanup;
    }
    ret = 0;

cleanup:
    /*
     * Certificate freeing is usually handled by openssl_session.
     * If something went wrong, creating the session we have to do it manually.
     */
    if (certificate != NULL)
    {
        pkcs11h_certificate_freeCertificate(certificate);
        certificate = NULL;
    }

    /*
     * openssl objects have reference
     * count, so release them
     */
    if (x509 != NULL)
    {
        X509_free(x509);
        x509 = NULL;
    }

    if (evp != NULL)
    {
        EVP_PKEY_free(evp);
        evp = NULL;
    }

    if (openssl_session != NULL)
    {
        pkcs11h_openssl_freeSession(openssl_session);
        openssl_session = NULL;
    }
    return ret;
}

char *
pkcs11_certificate_dn(pkcs11h_certificate_t certificate, struct gc_arena *gc)
{
    X509 *x509 = NULL;

    char *dn = NULL;

    if ((x509 = pkcs11h_openssl_getX509(certificate)) == NULL)
    {
        msg(M_FATAL, "PKCS#11: Cannot get X509");
        goto cleanup;
    }

    dn = x509_get_subject(x509, gc);

cleanup:
    if (x509 != NULL)
    {
        X509_free(x509);
        x509 = NULL;
    }

    return dn;
}

int
pkcs11_certificate_serial(pkcs11h_certificate_t certificate, char *serial,
                          size_t serial_len)
{
    X509 *x509 = NULL;
    BIO *bio = NULL;
    int ret = 1;
    int n;

    if ((x509 = pkcs11h_openssl_getX509(certificate)) == NULL)
    {
        msg(M_FATAL, "PKCS#11: Cannot get X509");
        goto cleanup;
    }

    if ((bio = BIO_new(BIO_s_mem())) == NULL)
    {
        msg(M_FATAL, "PKCS#11: Cannot create BIO");
        goto cleanup;
    }

    i2a_ASN1_INTEGER(bio, X509_get_serialNumber(x509));
    n = BIO_read(bio, serial, serial_len-1);

    if (n<0)
    {
        serial[0] = '\x0';
    }
    else
    {
        serial[n] = 0;
    }

    ret = 0;

cleanup:

    if (x509 != NULL)
    {
        X509_free(x509);
        x509 = NULL;
    }
    return ret;
}
#endif /* defined(ENABLE_PKCS11) && defined(ENABLE_OPENSSL) */
