Example program to test AES-GCM functionality. Used for a workshop

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pkcs11.c Source File

pkcs11.c

Go to the documentation of this file.
00001 /**
00002  * \file pkcs11.c
00003  *
00004  * \brief Wrapper for PKCS#11 library libpkcs11-helper
00005  *
00006  * \author Adriaan de Jong <dejong@fox-it.com>
00007  *
00008  *  Copyright (C) 2006-2014, Brainspark B.V.
00009  *
00010  *  This file is part of PolarSSL (http://www.polarssl.org)
00011  *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
00012  *
00013  *  All rights reserved.
00014  *
00015  *  This program is free software; you can redistribute it and/or modify
00016  *  it under the terms of the GNU General Public License as published by
00017  *  the Free Software Foundation; either version 2 of the License, or
00018  *  (at your option) any later version.
00019  *
00020  *  This program is distributed in the hope that it will be useful,
00021  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  *  GNU General Public License for more details.
00024  *
00025  *  You should have received a copy of the GNU General Public License along
00026  *  with this program; if not, write to the Free Software Foundation, Inc.,
00027  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00028  */
00029 
00030 #include "polarssl/pkcs11.h"
00031 
00032 #if defined(POLARSSL_PKCS11_C)
00033 #include "polarssl/md.h"
00034 #include "polarssl/oid.h"
00035 #include "polarssl/x509_crt.h"
00036 
00037 #if defined(POLARSSL_PLATFORM_C)
00038 #include "polarssl/platform.h"
00039 #else
00040 #include <stdlib.h>
00041 #define polarssl_malloc     malloc
00042 #define polarssl_free       free
00043 #endif
00044 
00045 int pkcs11_x509_cert_init( x509_crt *cert, pkcs11h_certificate_t pkcs11_cert )
00046 {
00047     int ret = 1;
00048     unsigned char *cert_blob = NULL;
00049     size_t cert_blob_size = 0;
00050 
00051     if( cert == NULL )
00052     {
00053         ret = 2;
00054         goto cleanup;
00055     }
00056 
00057     if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, NULL,
00058                                                 &cert_blob_size ) != CKR_OK )
00059     {
00060         ret = 3;
00061         goto cleanup;
00062     }
00063 
00064     cert_blob = polarssl_malloc( cert_blob_size );
00065     if( NULL == cert_blob )
00066     {
00067         ret = 4;
00068         goto cleanup;
00069     }
00070 
00071     if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, cert_blob,
00072                                                 &cert_blob_size ) != CKR_OK )
00073     {
00074         ret = 5;
00075         goto cleanup;
00076     }
00077 
00078     if( 0 != x509_crt_parse(cert, cert_blob, cert_blob_size ) )
00079     {
00080         ret = 6;
00081         goto cleanup;
00082     }
00083 
00084     ret = 0;
00085 
00086 cleanup:
00087     if( NULL != cert_blob )
00088         polarssl_free( cert_blob );
00089 
00090     return ret;
00091 }
00092 
00093 
00094 int pkcs11_priv_key_init( pkcs11_context *priv_key,
00095         pkcs11h_certificate_t pkcs11_cert )
00096 {
00097     int ret = 1;
00098     x509_crt cert;
00099 
00100     x509_crt_init( &cert );
00101 
00102     if( priv_key == NULL )
00103         goto cleanup;
00104 
00105     if( 0 != pkcs11_x509_cert_init( &cert, pkcs11_cert ) )
00106         goto cleanup;
00107 
00108     priv_key->len = pk_get_len(&cert.pk);
00109     priv_key->pkcs11h_cert = pkcs11_cert;
00110 
00111     ret = 0;
00112 
00113 cleanup:
00114     x509_crt_free( &cert );
00115 
00116     return ret;
00117 }
00118 
00119 void pkcs11_priv_key_free( pkcs11_context *priv_key )
00120 {
00121     if( NULL != priv_key )
00122         pkcs11h_certificate_freeCertificate( priv_key->pkcs11h_cert );
00123 }
00124 
00125 int pkcs11_decrypt( pkcs11_context *ctx,
00126                        int mode, size_t *olen,
00127                        const unsigned char *input,
00128                        unsigned char *output,
00129                        size_t output_max_len )
00130 {
00131     size_t input_len, output_len;
00132 
00133     if( NULL == ctx )
00134         return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
00135 
00136     if( RSA_PRIVATE != mode )
00137         return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
00138 
00139     output_len = input_len = ctx->len;
00140 
00141     if( input_len < 16 || input_len > output_max_len )
00142         return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
00143 
00144     /* Determine size of output buffer */
00145     if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input,
00146             input_len, NULL, &output_len ) != CKR_OK )
00147     {
00148         return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
00149     }
00150 
00151     if( output_len > output_max_len )
00152         return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );
00153 
00154     if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input,
00155             input_len, output, &output_len ) != CKR_OK )
00156     {
00157         return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
00158     }
00159     *olen = output_len;
00160     return( 0 );
00161 }
00162 
00163 int pkcs11_sign( pkcs11_context *ctx,
00164                     int mode,
00165                     md_type_t md_alg,
00166                     unsigned int hashlen,
00167                     const unsigned char *hash,
00168                     unsigned char *sig )
00169 {
00170     size_t sig_len = 0, asn_len = 0, oid_size = 0;
00171     unsigned char *p = sig;
00172     const char *oid;
00173 
00174     if( NULL == ctx )
00175         return POLARSSL_ERR_RSA_BAD_INPUT_DATA;
00176 
00177     if( RSA_PRIVATE != mode )
00178         return POLARSSL_ERR_RSA_BAD_INPUT_DATA;
00179 
00180     if( md_alg != POLARSSL_MD_NONE )
00181     {
00182         const md_info_t *md_info = md_info_from_type( md_alg );
00183         if( md_info == NULL )
00184             return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
00185 
00186         if( oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
00187             return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
00188 
00189         hashlen = md_get_size( md_info );
00190         asn_len = 10 + oid_size;
00191     }
00192 
00193     sig_len = ctx->len;
00194     if ( hashlen > sig_len || asn_len > sig_len ||
00195          hashlen + asn_len > sig_len )
00196     {
00197         return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
00198     }
00199 
00200     if( md_alg != POLARSSL_MD_NONE)
00201     {
00202         /*
00203          * DigestInfo ::= SEQUENCE {
00204          *   digestAlgorithm DigestAlgorithmIdentifier,
00205          *   digest Digest }
00206          *
00207          * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
00208          *
00209          * Digest ::= OCTET STRING
00210          */
00211         *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED;
00212         *p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
00213         *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED;
00214         *p++ = (unsigned char) ( 0x04 + oid_size );
00215         *p++ = ASN1_OID;
00216         *p++ = oid_size & 0xFF;
00217         memcpy( p, oid, oid_size );
00218         p += oid_size;
00219         *p++ = ASN1_NULL;
00220         *p++ = 0x00;
00221         *p++ = ASN1_OCTET_STRING;
00222         *p++ = hashlen;
00223     }
00224 
00225     memcpy( p, hash, hashlen );
00226 
00227     if( pkcs11h_certificate_signAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, sig,
00228             asn_len + hashlen, sig, &sig_len ) != CKR_OK )
00229     {
00230         return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
00231     }
00232 
00233     return( 0 );
00234 }
00235 
00236 #endif /* defined(POLARSSL_PKCS11_C) */
00237 
00238