/**
 * \file pkcs11.c
 *
 * \brief Wrapper for PKCS#11 library libpkcs11-helper
 *
 * \author Adriaan de Jong <dejong@fox-it.com>
 *
 *  Copyright (C) 2006-2013, 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)

#if defined(POLARSSL_MEMORY_C)
#include "polarssl/memory.h"
#else
#define polarssl_malloc     malloc
#define polarssl_free       free
#endif

#include <stdlib.h>

int pkcs11_x509_cert_init( x509_cert *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 != x509parse_crt(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_cert cert;

    memset( &cert, 0, sizeof( cert ) );

    if( priv_key == NULL )
        goto cleanup;

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

    priv_key->len = cert.rsa.len;
    priv_key->pkcs11h_cert = pkcs11_cert;

    ret = 0;

cleanup:
    x509_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_PUBLIC == 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,
                    int hash_id,
                    unsigned int hashlen,
                    const unsigned char *hash,
                    unsigned char *sig )
{
    size_t olen, asn_len;
    unsigned char *p = sig;

    if( NULL == ctx )
        return POLARSSL_ERR_RSA_BAD_INPUT_DATA;

    if( RSA_PUBLIC == mode )
        return POLARSSL_ERR_RSA_BAD_INPUT_DATA;

    olen = ctx->len;

    switch( hash_id )
    {
        case SIG_RSA_RAW:
            asn_len = 0;
            memcpy( p, hash, hashlen );
            break;

        case SIG_RSA_MD2:
            asn_len = OID_SIZE(ASN1_HASH_MDX);
            memcpy( p, ASN1_HASH_MDX, asn_len );
            memcpy( p + asn_len, hash, hashlen );
            p[13] = 2; break;

        case SIG_RSA_MD4:
            asn_len = OID_SIZE(ASN1_HASH_MDX);
            memcpy( p, ASN1_HASH_MDX, asn_len );
            memcpy( p + asn_len, hash, hashlen );
            p[13] = 4; break;

        case SIG_RSA_MD5:
            asn_len = OID_SIZE(ASN1_HASH_MDX);
            memcpy( p, ASN1_HASH_MDX, asn_len );
            memcpy( p + asn_len, hash, hashlen );
            p[13] = 5; break;

        case SIG_RSA_SHA1:
            asn_len = OID_SIZE(ASN1_HASH_SHA1);
            memcpy( p, ASN1_HASH_SHA1, asn_len );
            memcpy( p + 15, hash, hashlen );
            break;

        case SIG_RSA_SHA224:
            asn_len = OID_SIZE(ASN1_HASH_SHA2X);
            memcpy( p, ASN1_HASH_SHA2X, asn_len );
            memcpy( p + asn_len, hash, hashlen );
            p[1] += hashlen; p[14] = 4; p[18] += hashlen; break;

        case SIG_RSA_SHA256:
            asn_len = OID_SIZE(ASN1_HASH_SHA2X);
            memcpy( p, ASN1_HASH_SHA2X, asn_len );
            memcpy( p + asn_len, hash, hashlen );
            p[1] += hashlen; p[14] = 1; p[18] += hashlen; break;

        case SIG_RSA_SHA384:
            asn_len = OID_SIZE(ASN1_HASH_SHA2X);
            memcpy( p, ASN1_HASH_SHA2X, asn_len );
            memcpy( p + asn_len, hash, hashlen );
            p[1] += hashlen; p[14] = 2; p[18] += hashlen; break;

        case SIG_RSA_SHA512:
            asn_len = OID_SIZE(ASN1_HASH_SHA2X);
            memcpy( p, ASN1_HASH_SHA2X, asn_len );
            memcpy( p + asn_len, hash, hashlen );
            p[1] += hashlen; p[14] = 3; p[18] += hashlen; break;

        default:
            return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
    }

    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) */
