/**
 * \file pkcs11.c
 *
 * \brief Wrapper for PKCS#11 library libpkcs11-helper
 *
 * \author Adriaan de Jong <dejong@fox-it.com>
 *
 *  Copyright (C) 2006-2014, Brainspark B.V.
 *
 *  This file is part of PolarSSL (http://www.polarssl.org)
 *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
 *
 *  All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  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.
 */

#include "polarssl/pkcs11.h"

#if defined(POLARSSL_PKCS11_C)
#include "polarssl/md.h"
#include "polarssl/oid.h"
#include "polarssl/x509_crt.h"

#if defined(POLARSSL_PLATFORM_C)
#include "polarssl/platform.h"
#else
#include <stdlib.h>
#define polarssl_malloc     malloc
#define polarssl_free       free
#endif

int pkcs11_x509_cert_init( x509_crt *cert, pkcs11h_certificate_t pkcs11_cert )
{
    int ret = 1;
    unsigned char *cert_blob = NULL;
    size_t cert_blob_size = 0;

    if( cert == NULL )
    {
        ret = 2;
        goto cleanup;
    }

    if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, NULL, &cert_blob_size ) != CKR_OK )
    {
        ret = 3;
        goto cleanup;
    }

    cert_blob = polarssl_malloc( cert_blob_size );
    if( NULL == cert_blob )
    {
        ret = 4;
        goto cleanup;
    }

    if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, cert_blob, &cert_blob_size ) != CKR_OK )
    {
        ret = 5;
        goto cleanup;
    }

    if( 0 != x509_crt_parse(cert, cert_blob, cert_blob_size ) )
    {
        ret = 6;
        goto cleanup;
    }

    ret = 0;

cleanup:
    if( NULL != cert_blob )
        polarssl_free( cert_blob );

    return ret;
}


int pkcs11_priv_key_init( pkcs11_context *priv_key,
        pkcs11h_certificate_t pkcs11_cert )
{
    int ret = 1;
    x509_crt cert;

    x509_crt_init( &cert );

    if( priv_key == NULL )
        goto cleanup;

    if( 0 != pkcs11_x509_cert_init( &cert, pkcs11_cert ) )
        goto cleanup;

    priv_key->len = pk_get_len(&cert.pk);
    priv_key->pkcs11h_cert = pkcs11_cert;

    ret = 0;

cleanup:
    x509_crt_free( &cert );

    return ret;
}

void pkcs11_priv_key_free( pkcs11_context *priv_key )
{
    if( NULL != priv_key )
        pkcs11h_certificate_freeCertificate( priv_key->pkcs11h_cert );
}

int pkcs11_decrypt( pkcs11_context *ctx,
                       int mode, size_t *olen,
                       const unsigned char *input,
                       unsigned char *output,
                       size_t output_max_len )
{
    size_t input_len, output_len;

    if( NULL == ctx )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    if( RSA_PRIVATE != mode )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    output_len = input_len = ctx->len;

    if( input_len < 16 || input_len > output_max_len )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    /* Determine size of output buffer */
    if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input,
            input_len, NULL, &output_len ) != CKR_OK )
    {
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
    }

    if( output_len > output_max_len )
        return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );

    if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input,
            input_len, output, &output_len ) != CKR_OK )
    {
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
    }
    *olen = output_len;
    return( 0 );
}

int pkcs11_sign( pkcs11_context *ctx,
                    int mode,
                    md_type_t md_alg,
                    unsigned int hashlen,
                    const unsigned char *hash,
                    unsigned char *sig )
{
    size_t olen, asn_len = 0, oid_size = 0;
    unsigned char *p = sig;
    const char *oid;

    if( NULL == ctx )
        return POLARSSL_ERR_RSA_BAD_INPUT_DATA;

    if( RSA_PRIVATE != mode )
        return POLARSSL_ERR_RSA_BAD_INPUT_DATA;

    olen = ctx->len;

    if( md_alg != POLARSSL_MD_NONE )
    {
        const md_info_t *md_info = md_info_from_type( md_alg );
        if( md_info == NULL )
            return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

        if( oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
            return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

        hashlen = md_get_size( md_info );
    }

    if( md_alg == POLARSSL_MD_NONE )
    {
        memcpy( p, hash, hashlen );
    }
    else
    {
        /*
         * DigestInfo ::= SEQUENCE {
         *   digestAlgorithm DigestAlgorithmIdentifier,
         *   digest Digest }
         *
         * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
         *
         * Digest ::= OCTET STRING
         */
        *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED;
        *p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
        *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED;
        *p++ = (unsigned char) ( 0x04 + oid_size );
        *p++ = ASN1_OID;
        *p++ = oid_size & 0xFF;
        memcpy( p, oid, oid_size );
        p += oid_size;
        *p++ = ASN1_NULL;
        *p++ = 0x00;
        *p++ = ASN1_OCTET_STRING;
        *p++ = hashlen;

        /* Determine added ASN length */
        asn_len = p - sig;

        memcpy( p, hash, hashlen );
    }

    if( pkcs11h_certificate_signAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, sig,
            asn_len + hashlen, sig, &olen ) != CKR_OK )
    {
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
    }

    return( 0 );
}

#endif /* defined(POLARSSL_PKCS11_C) */
