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