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