blob: 70cc0de9aac887d2d6fe4bae08f0c596ca657d10 [file] [log] [blame]
Andrzej Kurekc53dee32018-01-23 05:44:20 -05001/*
2 * Generic wrapper for Cryptoki (PKCS#11) support
3 *
4 * Copyright (C) 2017, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22#if !defined(MBEDTLS_CONFIG_FILE)
23#include "mbedtls/config.h"
24#else
25#include MBEDTLS_CONFIG_FILE
26#endif
27
28#if defined(MBEDTLS_PKCS11_CLIENT_C)
29
30#include <stdint.h>
31#include <string.h>
32#include <pkcs11.h>
33
34#include "mbedtls/pkcs11_client.h"
35
36#if defined(MBEDTLS_PLATFORM_C)
37#include "mbedtls/platform.h"
38#else
39#include <stdlib.h>
40#define mbedtls_calloc calloc
41#define mbedtls_free free
42#endif
43
44
45
46#if defined(MBEDTLS_PK_C)
47#include "mbedtls/pk.h"
48#include "mbedtls/pk_info.h"
49
50#if defined(MBEDTLS_ECDSA_C)
51#include "mbedtls/asn1.h"
52#include "mbedtls/asn1write.h"
53#include "mbedtls/bignum.h"
54#include "mbedtls/ecdsa.h"
55#include "mbedtls/ecp.h"
56#include "mbedtls/oid.h"
57#endif
58
59#define ARRAY_LENGTH( a ) ( sizeof( a ) / sizeof( *( a ) ) )
60
61typedef struct {
62 mbedtls_pk_type_t key_type; /**< key type */
63 CK_SESSION_HANDLE hSession; /**< session handle */
64 CK_OBJECT_HANDLE hPublicKey; /**< public key handle (must not be null) */
65 CK_OBJECT_HANDLE hPrivateKey; /**< private key handle (may be null) */
66 uint16_t bit_length; /**< key length in bits */
67} mbedtls_pk_pkcs11_context_t;
68
69static int pkcs11_err_to_mbedtls_pk_err( CK_RV rv )
70{
71 switch( rv )
72 {
73 case CKR_OK:
74 return( 0 );
75 case CKR_HOST_MEMORY:
76 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
77 case CKR_ARGUMENTS_BAD:
78 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
79 case CKR_KEY_FUNCTION_NOT_PERMITTED:
80 return( MBEDTLS_ERR_PK_NOT_PERMITTED );
81 case CKR_MECHANISM_INVALID:
82 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
83 case CKR_MECHANISM_PARAM_INVALID:
84 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
85 case CKR_OBJECT_HANDLE_INVALID:
86 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
87 case CKR_SIGNATURE_INVALID:
88 return( MBEDTLS_ERR_PK_INVALID_SIGNATURE );
89 case CKR_SIGNATURE_LEN_RANGE:
90 return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
91 case CKR_TEMPLATE_INCOMPLETE:
92 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
93 case CKR_BUFFER_TOO_SMALL:
94 return( MBEDTLS_ERR_PK_BUFFER_TOO_SMALL );
95 default:
96 return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
97 }
98}
99
100static size_t pkcs11_pk_get_bitlen( const void *ctx_arg )
101{
102 const mbedtls_pk_pkcs11_context_t *ctx = ctx_arg;
103 return( ctx->bit_length );
104}
105
106static int pkcs11_pk_can_do( const void *ctx_arg, mbedtls_pk_type_t type )
107{
108 const mbedtls_pk_pkcs11_context_t *ctx = ctx_arg;
109 return ctx->key_type == mbedtls_pk_representation_type( type );
110}
111
112static void *pkcs11_pk_alloc( )
113{
114 return( mbedtls_calloc( 1, sizeof( mbedtls_pk_pkcs11_context_t ) ) );
115}
116
117static void pkcs11_pk_free( void *ctx )
118{
119 mbedtls_free( ctx );
120}
121
122static size_t pkcs11_pk_signature_size( const void *ctx_arg )
123{
124 const mbedtls_pk_pkcs11_context_t *ctx = ctx_arg;
125 switch( ctx->key_type )
126 {
127 case MBEDTLS_PK_RSA:
128 return( ( ctx->bit_length + 7 ) / 8 );
129 case MBEDTLS_PK_ECKEY:
130 return( MBEDTLS_ECDSA_MAX_SIG_LEN( ctx->bit_length ) );
131 default:
132 return( 0 );
133 }
134}
135
136static int pkcs11_sign( void *ctx_arg,
137 mbedtls_md_type_t md_alg,
138 const unsigned char *hash, size_t hash_len,
139 unsigned char *sig, size_t *sig_len,
140 int (*f_rng)(void *, unsigned char *, size_t),
141 void *p_rng )
142{
143 mbedtls_pk_pkcs11_context_t *ctx = ctx_arg;
144 CK_RV rv;
145 CK_MECHANISM mechanism = {0, NULL_PTR, 0};
146 CK_ULONG ck_sig_len;
147
148 /* This function takes size_t arguments but the underlying layer
149 takes unsigned long. Either type may be smaller than the other.
150 Legitimate values won't overflow either type but we still need
151 to check for overflow for robustness. */
152 if( hash_len > (CK_ULONG)( -1 ) )
153 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
154 (void) f_rng;
155 (void) p_rng;
156
157 switch( ctx->key_type )
158 {
159#if defined(MBEDTLS_ECDSA_C)
160 case MBEDTLS_PK_ECKEY:
161 ck_sig_len = MBEDTLS_ECDSA_MAX_SIG_LEN( ctx->bit_length );
162 mechanism.mechanism = CKM_ECDSA;
163 break;
164#endif /* MBEDTLS_ECDSA_C */
165 default:
166 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
167 }
168
169 rv = C_SignInit( ctx->hSession, &mechanism, ctx->hPrivateKey );
170 if( rv != CKR_OK )
171 goto exit;
172 rv = C_Sign( ctx->hSession, (CK_BYTE_PTR) hash, hash_len,
173 sig, &ck_sig_len );
174 if( rv != CKR_OK )
175 goto exit;
176
177 if( mechanism.mechanism == CKM_ECDSA )
178 {
179 /* The signature from the token contains r and s concatenated,
180 * each in the form of a big-endian byte sequence, with r and s
181 * having the same length as the base point.
182 *
183 * A standard ECDSA signature is encoded in ASN.1:
184 * SEQUENCE {
185 * r INTEGER,
186 * s INTEGER
187 * }
188 *
189 * Perform the conversion using existing utility functions,
190 * with temporary bignums.
191 */
192 uint16_t byte_len = ( ( ctx->bit_length + 7 ) / 8 );
193 size_t sig_size = MBEDTLS_ECDSA_MAX_SIG_LEN( ctx->bit_length );
194 mbedtls_mpi r, s;
195 mbedtls_mpi_init( &r );
196 mbedtls_mpi_init( &s );
197 rv = CKR_OK;
198 if( ck_sig_len != 2 * byte_len )
199 {
200 /* Bad data from the token */
201 rv = CKR_GENERAL_ERROR;
202 goto ecdsa_exit;
203 }
204 if( mbedtls_mpi_read_binary( &r, sig, byte_len ) != 0 ||
205 mbedtls_mpi_read_binary( &s, sig + byte_len, byte_len ) != 0 )
206 {
207 rv = CKR_HOST_MEMORY;
208 goto ecdsa_exit;
209 }
210 /* The signature buffer is guaranteed to have enough room for
211 the encoded signature by the pk_sign interface. */
Andrzej Kurekc289bf12018-01-23 06:10:53 -0500212 if( mbedtls_ecdsa_signature_to_asn1( &r, &s, sig, sig_len, sig_size ) != 0 )
Andrzej Kurekc53dee32018-01-23 05:44:20 -0500213 {
214 rv = CKR_GENERAL_ERROR;
215 goto ecdsa_exit;
216 }
217 ecdsa_exit:
218 mbedtls_mpi_free( &r );
219 mbedtls_mpi_free( &s );
220 if( rv != CKR_OK )
221 goto exit;
222 }
223 else
224 {
225 *sig_len = ck_sig_len;
226 }
227
228exit:
229 if( rv != CKR_OK )
230 memset( sig, 0, ck_sig_len );
231 return( pkcs11_err_to_mbedtls_pk_err( rv ) );
232}
233
Andrzej Kurekc289bf12018-01-23 06:10:53 -0500234static int pkcs11_verify( void *ctx_arg,
235 mbedtls_md_type_t md_alg,
236 const unsigned char *hash, size_t hash_len,
237 const unsigned char *sig, size_t sig_len)
238{
239 mbedtls_pk_pkcs11_context_t *ctx = ctx_arg;
240 CK_RV rv;
241 CK_MECHANISM mechanism = {0, NULL_PTR, 0};
242 unsigned char *decoded_sig = NULL_PTR;
243 size_t decoded_sig_len;
244
245 /* This function takes size_t arguments but the underlying layer
246 takes unsigned long. Either type may be smaller than the other.
247 Legitimate values won't overflow either type but we still need
248 to check for overflow for robustness. */
249 if( hash_len > (CK_ULONG)( -1 ) )
250 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
251
252 switch( ctx->key_type )
253 {
254#if defined(MBEDTLS_RSA_C)
255 case MBEDTLS_PK_RSA:
256 switch( md_alg )
257 {
258 case MBEDTLS_MD_MD5:
259 mechanism.mechanism = CKM_MD5_RSA_PKCS;
260 break;
261 case MBEDTLS_MD_SHA1:
262 mechanism.mechanism = CKM_SHA1_RSA_PKCS;
263 break;
264 case MBEDTLS_MD_SHA256:
265 mechanism.mechanism = CKM_SHA256_RSA_PKCS;
266 break;
267 case MBEDTLS_MD_SHA384:
268 mechanism.mechanism = CKM_SHA384_RSA_PKCS;
269 break;
270 case MBEDTLS_MD_SHA512:
271 mechanism.mechanism = CKM_SHA512_RSA_PKCS;
272 break;
273 default:
274 return( MBEDTLS_ERR_PK_INVALID_ALG );
275 }
276 break;
277#endif /* MBEDTLS_RSA_C */
278#if defined(MBEDTLS_ECDSA_C)
279 case MBEDTLS_PK_ECKEY:
280 mechanism.mechanism = CKM_ECDSA;
281 break;
282#endif /* MBEDTLS_ECDSA_C */
283 default:
284 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
285 }
286 if( mechanism.mechanism == CKM_ECDSA )
287 {
288 uint16_t byte_len = ( ( ctx->bit_length + 7 ) / 8 );
289 decoded_sig = malloc( 2 * byte_len );
290 if( mbedtls_ecdsa_signature_to_raw( sig, sig_len, byte_len,
291 decoded_sig, &decoded_sig_len ) != 0 )
292 {
293 rv = CKR_GENERAL_ERROR;
294 goto exit;
295 }
296 }
297 rv = C_VerifyInit( ctx->hSession, &mechanism, ctx->hPublicKey );
298 if( rv != CKR_OK )
299 goto exit;
300 rv = C_Verify( ctx->hSession, (CK_BYTE_PTR) hash, hash_len,
301 decoded_sig, decoded_sig_len );
302 if( rv != CKR_OK )
303 goto exit;
304
305exit:
306 free(decoded_sig);
307 return( pkcs11_err_to_mbedtls_pk_err( rv ) );
308}
309
Andrzej Kurekc53dee32018-01-23 05:44:20 -0500310static const mbedtls_pk_info_t mbedtls_pk_pkcs11_info =
311 MBEDTLS_PK_OPAQUE_INFO_1( "pkcs11"
312 , pkcs11_pk_get_bitlen
313 , pkcs11_pk_can_do //can_do
314 , pkcs11_pk_signature_size
Andrzej Kurekc289bf12018-01-23 06:10:53 -0500315 , pkcs11_verify
Andrzej Kurekc53dee32018-01-23 05:44:20 -0500316 , pkcs11_sign
317 , NULL //pkcs11_decrypt
318 , NULL //pkcs11_encrypt
319 , NULL //check_pair_func
320 , pkcs11_pk_alloc
321 , pkcs11_pk_free
322 , NULL //debug_func
323 );
324
325int mbedtls_pk_setup_pkcs11( mbedtls_pk_context *ctx,
326 CK_SESSION_HANDLE hSession,
327 CK_OBJECT_HANDLE hPublicKey,
328 CK_OBJECT_HANDLE hPrivateKey )
329{
330 CK_OBJECT_CLASS public_key_class = -1, private_key_class = -1;
331 CK_KEY_TYPE public_key_type = -1, private_key_type = -1;
332 mbedtls_pk_type_t can_do;
333 CK_ATTRIBUTE attributes[] = {
334 {CKA_CLASS, &public_key_class, sizeof( public_key_class )},
335 {CKA_KEY_TYPE, &public_key_type, sizeof( public_key_type )},
336 };
337 CK_RV rv;
338 uint16_t key_size = 0;
339
340 rv = C_GetAttributeValue( hSession, hPublicKey,
341 attributes, ARRAY_LENGTH( attributes ) );
342 if( rv != CKR_OK )
343 return( pkcs11_err_to_mbedtls_pk_err( rv ) );
344 if( public_key_class != CKO_PUBLIC_KEY )
345 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
346
347 if( hPrivateKey != CK_INVALID_HANDLE )
348 {
349 attributes[0].pValue = &private_key_class;
350 attributes[1].pValue = &private_key_type;
351 rv = C_GetAttributeValue( hSession, hPrivateKey,
352 attributes, ARRAY_LENGTH( attributes ) );
353 if( rv != CKR_OK )
354 return( pkcs11_err_to_mbedtls_pk_err( rv ) );
355 if( private_key_class != CKO_PRIVATE_KEY )
356 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
357 if( public_key_type != private_key_type )
358 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
359 }
360
361 switch( public_key_type ) {
362#if defined(MBEDTLS_ECDSA_C)
363 case CKK_ECDSA:
364 can_do = MBEDTLS_PK_ECKEY;
365 {
366 unsigned char ecParams[16];
367 mbedtls_asn1_buf params_asn1;
368 mbedtls_ecp_group_id grp_id;
369 const mbedtls_ecp_curve_info *curve_info;
370 attributes[0].type = CKA_EC_PARAMS;
371 attributes[0].pValue = ecParams;
372 attributes[0].ulValueLen = sizeof( ecParams );
373 rv = C_GetAttributeValue( hSession, hPrivateKey, attributes, 1 );
374 if( rv != CKR_OK )
375 return( pkcs11_err_to_mbedtls_pk_err( rv ) );
376 params_asn1.tag = ecParams[0];
377 params_asn1.len = ecParams[1];
378 params_asn1.p = ecParams + 2;
379 if( mbedtls_oid_get_ec_grp( &params_asn1, &grp_id ) != 0 )
380 return( MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE );
381 curve_info = mbedtls_ecp_curve_info_from_grp_id( grp_id );
382 if( curve_info == NULL )
383 return( MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE );
384 key_size = curve_info->bit_size;
385 }
386 break;
387#endif /* MBEDTLS_ECDSA_C */
388 default:
389 can_do = MBEDTLS_PK_OPAQUE;
390 break;
391 }
392
393 {
394 int ret = mbedtls_pk_setup( ctx, &mbedtls_pk_pkcs11_info );
395 if( ret != 0 )
396 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
397 }
398 {
399 mbedtls_pk_pkcs11_context_t *pkcs11_ctx = ctx->pk_ctx;
400 pkcs11_ctx->key_type = can_do;
401 pkcs11_ctx->bit_length = key_size;
402 pkcs11_ctx->hSession = hSession;
403 pkcs11_ctx->hPublicKey = hPublicKey;
404 pkcs11_ctx->hPrivateKey = hPrivateKey;
405 }
406 return( 0 );
407}
408
409#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C)
410static int mpi_to_ck( const mbedtls_mpi *mpi,
411 CK_ATTRIBUTE *attr, CK_ATTRIBUTE_TYPE at,
412 unsigned char **p, size_t len )
413{
414 if( mbedtls_mpi_write_binary( mpi, *p, len ) != 0 )
415 return( 0 );
416 attr->type = at;
417 attr->pValue = *p;
418 attr->ulValueLen = len;
419 *p += len;
420 return( 1 );
421}
422#define MPI_TO_CK( mpi, attr, at, p, len ) \
423 do \
424 { \
425 if( !mpi_to_ck( ( mpi ), ( attr ), ( at ), ( p ), ( len ) ) ) \
426 { \
427 rv = CKR_ARGUMENTS_BAD; \
428 goto exit; \
429 } \
430 } \
431 while( 0 )
432#endif /* defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) */
433
434#define CK_BOOL( x ) ( ( x ) ? CK_TRUE : CK_FALSE )
435
436int mbedtls_pk_import_to_pkcs11( const mbedtls_pk_context *ctx,
437 uint32_t flags,
438 CK_SESSION_HANDLE hSession,
439 CK_OBJECT_HANDLE *hPublicKey,
440 CK_OBJECT_HANDLE *hPrivateKey )
441{
442 CK_OBJECT_CLASS cko_private_key = CKO_PRIVATE_KEY;
443 CK_OBJECT_CLASS cko_public_key = CKO_PUBLIC_KEY;
444 CK_KEY_TYPE ck_key_type;
445 CK_BBOOL ck_sensitive = CK_BOOL( flags & MBEDTLS_PK_FLAG_SENSITIVE );
446 CK_BBOOL ck_extractable = CK_BOOL( flags & MBEDTLS_PK_FLAG_EXTRACTABLE );
447 CK_BBOOL ck_sign = CK_BOOL( flags & MBEDTLS_PK_FLAG_SIGN );
448 CK_BBOOL ck_verify = CK_BOOL( flags & MBEDTLS_PK_FLAG_VERIFY );
449 CK_BBOOL ck_decrypt = CK_BOOL( flags & MBEDTLS_PK_FLAG_DECRYPT );
450 CK_BBOOL ck_encrypt = CK_BOOL( flags & MBEDTLS_PK_FLAG_ENCRYPT );
451 CK_BBOOL ck_token = CK_BOOL( flags & MBEDTLS_PKCS11_FLAG_TOKEN );
452 CK_ATTRIBUTE public_attributes[] = {
453 {CKA_CLASS, &cko_public_key, sizeof( cko_public_key )},
454 {CKA_KEY_TYPE, &ck_key_type, sizeof( ck_key_type )},
455 {CKA_TOKEN, &ck_token, sizeof( ck_token )},
456 {CKA_ENCRYPT, &ck_encrypt, sizeof( ck_encrypt )},
457 {CKA_VERIFY, &ck_verify, sizeof( ck_verify )},
458#define COMMON_PUBLIC_ATTRIBUTES 5 // number of attributes above
459 {-1, NULL, 0},
460 {-1, NULL, 0},
461 };
462 CK_ATTRIBUTE private_attributes[] = {
463 {CKA_CLASS, &cko_private_key, sizeof( cko_private_key )},
464 {CKA_KEY_TYPE, &ck_key_type, sizeof( ck_key_type )},
465 {CKA_TOKEN, &ck_token, sizeof( ck_token )},
466 {CKA_DECRYPT, &ck_decrypt, sizeof( ck_decrypt )},
467 {CKA_SIGN, &ck_sign, sizeof( ck_sign )},
468 {CKA_SENSITIVE, &ck_sensitive, sizeof( ck_sensitive )},
469 {CKA_EXTRACTABLE, &ck_extractable, sizeof( ck_extractable )},
470#define COMMON_PRIVATE_ATTRIBUTES 7 // number of attributes above
471 {-1, NULL, 0},
472 {-1, NULL, 0},
473 {-1, NULL, 0},
474 {-1, NULL, 0},
475 {-1, NULL, 0},
476 {-1, NULL, 0},
477 {-1, NULL, 0},
478 {-1, NULL, 0},
479 };
480 CK_ATTRIBUTE *public_end = public_attributes + COMMON_PUBLIC_ATTRIBUTES;
481 CK_ATTRIBUTE *private_end = private_attributes + COMMON_PRIVATE_ATTRIBUTES;
482#undef COMMON_PUBLIC_ATTRIBUTES
483#undef COMMON_PRIVATE_ATTRIBUTES
484 unsigned char *data = NULL;
485 CK_RV rv;
486
487 if( hPublicKey != NULL )
488 *hPublicKey = CK_INVALID_HANDLE;
489 if( hPrivateKey != NULL )
490 *hPrivateKey = CK_INVALID_HANDLE;
491
492 /* Prepare the data-dependent key attributes */
493 switch( mbedtls_pk_representation_type( mbedtls_pk_get_type( ctx ) ) )
494 {
495#if defined(MBEDTLS_ECDSA_C)
496 case MBEDTLS_PK_ECKEY:
497 {
498 const mbedtls_ecp_keypair *ec = mbedtls_pk_ec( *ctx );
499 unsigned char *p;
500 size_t curve_bytes = ( ec->grp.pbits + 7 ) / 8;
501 size_t point_bytes = 4 + 2 * curve_bytes; // overapproximation
502 int format = MBEDTLS_ECP_PF_UNCOMPRESSED;
503 int ret;
504 data = mbedtls_calloc( 1,
505 MBEDTLS_OID_EC_GRP_MAX_SIZE +
506 ( hPublicKey == NULL ? 0 : point_bytes ) +
507 ( hPrivateKey == NULL ? 0 : curve_bytes ) );
508 if( data == NULL )
509 {
510 rv = CKR_HOST_MEMORY;
511 goto exit;
512 }
513 p = data;
514 ck_key_type = CKK_ECDSA;
515 /* Convert the group identifier */
516 ret = mbedtls_ecp_ansi_write_group( &ec->grp, p,
517 MBEDTLS_OID_EC_GRP_MAX_SIZE );
518 if( ret < 0 )
519 {
520 rv = CKR_GENERAL_ERROR;
521 goto exit;
522 }
523 public_end->type = CKA_EC_PARAMS;
524 public_end->pValue = p;
525 public_end->ulValueLen = ret;
526 p += ret;
527 *private_end++ = *public_end++;
528 if( hPublicKey != NULL )
529 {
530 /* Convert the public point */
531 ret = mbedtls_ecp_ansi_write_point( ec, format, p, point_bytes );
532 if( ret < 0 )
533 {
534 rv = CKR_GENERAL_ERROR;
535 goto exit;
536 }
537 public_end->type = CKA_EC_POINT;
538 public_end->pValue = p;
539 public_end->ulValueLen = ret;
540 p += ret;
541 public_end++;
542 }
543 if( hPrivateKey != NULL )
544 {
545 /* Convert the private value */
546 MPI_TO_CK( &ec->d, private_end++, CKA_VALUE, &p, curve_bytes );
547 }
548 }
549 break;
550#endif /* MBEDTLS_ECDSA_C */
551 default:
552 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
553 }
554
555 if( hPublicKey != NULL )
556 {
557 *hPublicKey = CK_INVALID_HANDLE;
558 rv = C_CreateObject( hSession,
559 public_attributes,
560 public_end - public_attributes,
561 hPublicKey );
562 if( rv != CKR_OK )
563 goto exit;
564 }
565
566 if( hPrivateKey != NULL )
567 {
568 rv = C_CreateObject( hSession,
569 private_attributes,
570 private_end - private_attributes,
571 hPrivateKey );
572 if( rv != CKR_OK )
573 goto exit;
574 }
575
576exit:
577 if( rv != CKR_OK )
578 {
579 /* In case an error happened, destroy any object that we
580 created. In case C_DestroyObject failed, we report the original
581 error, but *hPublicKey may contain a valid handle if
582 creating the private key failed and then destroying the public key
583 also failed (e.g. because the token disconnected). */
584 if( hPublicKey != NULL && *hPublicKey != CK_INVALID_HANDLE )
585 {
586 if( C_DestroyObject( hSession, *hPublicKey ) == CKR_OK )
587 *hPublicKey = CK_INVALID_HANDLE;
588 }
589 if( hPrivateKey != NULL && *hPrivateKey != CK_INVALID_HANDLE )
590 {
591 if( C_DestroyObject( hSession, *hPrivateKey ) == CKR_OK )
592 *hPrivateKey = CK_INVALID_HANDLE;
593 }
594 }
595 mbedtls_free( data );
596 return( pkcs11_err_to_mbedtls_pk_err( rv ) );
597}
598
599#endif /* MBEDTLS_PK_C */
600
601
602
603#endif /* MBEDTLS_PKCS11_CLIENT_C */