1 /* -*- mode: c; c-file-style:"stroustrup"; -*- */
2
3 /*
4 * Copyright (c) 2018 Mastercard
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #include <config.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <stdbool.h>
24 #include <ctype.h>
25 #include <time.h>
26 #include <unistd.h>
27 #include <search.h>
28
29 #include <openssl/bio.h>
30 #include <openssl/pem.h>
31 #include <openssl/x509.h>
32
33 #include "pkcs11lib.h"
34 #include "wrappedkey_lexer.h"
35 #include "wrappedkey_parser.h"
36
37 #define INDENTATION_OFFSET 4
38
39 typedef enum {
40 meth_label,
41 meth_keyhandle
42 } wrap_source_method_t;
43
44 typedef struct {
45 CK_ATTRIBUTE_TYPE attr_type;
46 void (*func_ptr) (FILE *, char *, CK_ATTRIBUTE_PTR, bool, int);
47 char *name;
48 bool commented;
49 } attr_printer ;
50
51
52 /* private funcs prototypes */
53 static char const *_get_str_for_wrapping_algorithm(enum wrappingmethod w, CK_MECHANISM_TYPE m);
54 static char const *get_wrapping_algorithm_short(wrappedKeyCtx *wctx);
55 static func_rc fprintf_wrapping_algorithm_full(FILE *fp, wrappedKeyCtx *wctx, char *buffer, size_t buffer_len, int keyindex);
56 static void fprintf_template_attr_member(FILE *fp, CK_ATTRIBUTE_PTR attr, int offset);
57
58 static void fprintf_key_type(FILE *fp, char *unused, CK_ATTRIBUTE_PTR attr, bool unused2, int offset);
59 static void fprintf_object_class(FILE *fp, char *unused, CK_ATTRIBUTE_PTR attr, bool unused2, int offset);
60 static void fprintf_boolean_attr(FILE *fp, char *name, CK_ATTRIBUTE_PTR attr, bool commented, int offset);
61 static void fprintf_hex_attr(FILE *fp, char *name, CK_ATTRIBUTE_PTR attr, bool commented, int offset);
62 static void _fprintf_str_attr(FILE *fp, char *name, CK_ATTRIBUTE_PTR attr, bool commented, int offset);
63 static void fprintf_str_attr(FILE *fp, char *name, CK_ATTRIBUTE_PTR attr, bool commented, int offset);
64 static void fprintf_date_attr(FILE *fp, char *name, CK_ATTRIBUTE_PTR attr, bool commented, int offset);
65 static void fprintf_template_attr(FILE *fp, char *name, CK_ATTRIBUTE_PTR attr, bool commented, int offset);
66 static void fprintf_mechanism_type_array(FILE *fp, char *name, CK_ATTRIBUTE_PTR attr, bool commented, int offset);
67
68 static char * sprintf_hex_buffer(CK_BYTE_PTR buffer, CK_ULONG len);
69 static char * _sprintf_str_buffer(CK_BYTE_PTR buffer, CK_ULONG len);
70 static char * sprintf_str_buffer_safe(CK_BYTE_PTR buffer, CK_ULONG len);
71 static void free_sprintf_str_buffer_safe_buf(char *ptr);
72 static char * const _mgfstring(CK_RSA_PKCS_MGF_TYPE mgf);
73 static char * const _hashstring(CK_MECHANISM_TYPE hash);
74
75 static func_rc _output_wrapped_key_header(wrappedKeyCtx *wctx, FILE *fp);
76 static func_rc _output_wrapped_key_attributes(wrappedKeyCtx *wctx, FILE *fp);
77 static func_rc _output_wrapped_keys_b64(wrappedKeyCtx *wctx, FILE *fp);
78 static func_rc _output_public_key_attributes(wrappedKeyCtx *wctx, FILE *fp);
79 static func_rc _output_public_key_b64(wrappedKeyCtx *wctx, FILE *fp);
80
81 static func_rc _wrap_aes_key_wrap_mech(wrappedKeyCtx *wctx, CK_MECHANISM_TYPE mech[], CK_ULONG mech_size);
82 static func_rc _wrap_rfc3394(wrappedKeyCtx *wctx);
83 static func_rc _wrap_rfc5649(wrappedKeyCtx *wctx);
84 static func_rc _wrap_pkcs1_15(wrappedKeyCtx *wctx);
85 static func_rc _wrap_pkcs1_oaep(wrappedKeyCtx *wctx);
86 static func_rc _wrap_cbcpad(wrappedKeyCtx *wctx);
87 static func_rc _wrap_envelope(wrappedKeyCtx *wctx);
88
_wrap_rfc3394(wrappedKeyCtx * wctx)89 static inline func_rc _wrap_rfc3394(wrappedKeyCtx *wctx)
90 {
91 return _wrap_aes_key_wrap_mech(wctx, wctx->p11Context->rfc3394_mech, wctx->p11Context->rfc3394_mech_size);
92 }
93
_wrap_rfc5649(wrappedKeyCtx * wctx)94 static inline func_rc _wrap_rfc5649(wrappedKeyCtx *wctx)
95 {
96 return _wrap_aes_key_wrap_mech(wctx, wctx->p11Context->rfc5649_mech, wctx->p11Context->rfc5649_mech_size);
97 }
98
99 static func_rc _wrap(wrappedKeyCtx *wctx,
100 wrap_source_method_t wrap_source_method,
101 char *wrappedkeylabel,
102 CK_OBJECT_HANDLE wrappedkeyhandle,
103 CK_OBJECT_HANDLE pubkhandle);
104
pkcs11_wrap_from_label(wrappedKeyCtx * wctx,char * wrappedkeylabel)105 inline func_rc pkcs11_wrap_from_label(wrappedKeyCtx *wctx, char *wrappedkeylabel)
106 {
107 return _wrap(wctx, meth_label, wrappedkeylabel, 0, 0);
108 }
109
pkcs11_wrap_from_handle(wrappedKeyCtx * wctx,CK_OBJECT_HANDLE wrappedkeyhandle,CK_OBJECT_HANDLE pubkhandle)110 inline func_rc pkcs11_wrap_from_handle(wrappedKeyCtx *wctx, CK_OBJECT_HANDLE wrappedkeyhandle, CK_OBJECT_HANDLE pubkhandle)
111 {
112 return _wrap(wctx, meth_keyhandle, NULL, wrappedkeyhandle, pubkhandle);
113 }
114
115
_get_str_for_wrapping_algorithm(enum wrappingmethod w,CK_MECHANISM_TYPE m)116 static char const *_get_str_for_wrapping_algorithm(enum wrappingmethod w, CK_MECHANISM_TYPE m)
117 {
118 char *rc;
119 switch(w) {
120 case w_pkcs1_15:
121 rc = "PKCS#1 1.5";
122 break;
123
124 case w_pkcs1_oaep:
125 rc = "PKCS#1 OAEP";
126 break;
127
128 case w_cbcpad:
129 rc = "PKCS#11 CKM_xxx_CBC_PAD, with PKCS#7 padding";
130 break;
131
132 case w_rfc3394:
133 switch(m) {
134 case CKM_AES_KEY_WRAP:
135 rc = "PKCS#11 CKM_AES_KEY_WRAP (RFC3394)";
136 break;
137
138 case CKM_NSS_AES_KEY_WRAP:
139 rc = "NSS CKM_NSS_AES_KEY_WRAP (RFC3394)";
140 break;
141
142 #if defined(HAVE_LUNA)
143 case CKM_LUNA_AES_KW:
144 rc = "Gemalto Safenet Luna CKM_AES_KW (RFC3394)";
145 break;
146 #endif
147
148 default:
149 rc = "Unknown???";
150 }
151 break;
152
153 case w_rfc5649:
154 switch(m) {
155 case CKM_AES_KEY_WRAP_PAD:
156 rc = "PKCS#11 v2.40 CKM_AES_KEY_WRAP_PAD (RFC5649)";
157 break;
158
159 case CKM_NSS_AES_KEY_WRAP_PAD:
160 rc = "NSS CKM_NSS_AES_KEY_WRAP_PAD (!!<>RFC5649)";
161 break;
162
163 #if defined(HAVE_LUNA)
164 case CKM_LUNA_AES_KWP:
165 rc = "Gemalto Safenet Luna CKM_AES_KWP (RFC5649)";
166 break;
167 #endif
168
169 default:
170 rc = "Unknown???";
171 }
172 break;
173
174 default:
175 rc = "Unknown???";
176 }
177
178 return rc;
179 }
180
get_wrapping_algorithm_short(wrappedKeyCtx * wctx)181 static char const *get_wrapping_algorithm_short(wrappedKeyCtx *wctx)
182 {
183 if(wctx->is_envelope) {
184 return "Envelope"; /* TODO: recursive content */
185 } else {
186 return _get_str_for_wrapping_algorithm(wctx->key[WRAPPEDKEYCTX_LONE_KEY_INDEX].wrapping_meth, wctx->aes_params.aes_wrapping_mech);
187 }
188 }
189
fprintf_wrapping_algorithm_full(FILE * fp,wrappedKeyCtx * wctx,char * buffer,size_t buffer_len,int keyindex)190 static func_rc fprintf_wrapping_algorithm_full(FILE *fp, wrappedKeyCtx *wctx, char *buffer, size_t buffer_len, int keyindex)
191 {
192
193 func_rc rc;
194 /* when fp is non null, we try to write to the file system. Otherwise, it means we are re-entered recursively */
195 /* in which case we fill the received buffer */
196
197 if(fp) {
198 if(wctx->is_envelope) {
199 char inner[256];
200 char outer[256];
201
202 rc = fprintf_wrapping_algorithm_full(NULL, wctx, inner, sizeof inner, WRAPPEDKEYCTX_INNER_KEY_INDEX);
203 if(rc!=rc_ok) { return rc; }
204 rc = fprintf_wrapping_algorithm_full(NULL, wctx, outer, sizeof outer, WRAPPEDKEYCTX_OUTER_KEY_INDEX);
205 if(rc!=rc_ok) { return rc; }
206 fprintf(fp, "Wrapping-Algorithm: %s/1.0(inner=%s,outer=%s)\n", "envelope", inner, outer);
207 } else { /* standalone */
208 char alone[256];
209
210 if( (rc = fprintf_wrapping_algorithm_full(NULL, wctx, alone, sizeof alone, WRAPPEDKEYCTX_LONE_KEY_INDEX )) != rc_ok ) {
211 return rc;
212 } /* exit prematurely */
213 fprintf(fp, "Wrapping-Algorithm: %s\n", alone );
214 }
215 } else {
216 /* we have re-entered the function and need to deal with actual algoritm. We use snprintf here */
217 switch(wctx->key[keyindex].wrapping_meth) {
218 case w_pkcs1_15:
219 snprintf(buffer, buffer_len, "%s/1.0", "pkcs1");
220 break;
221
222 /* we have one additional parameter for oaep: the label (in PKCS#1), referred as source in PKCS#11 */
223 case w_pkcs1_oaep: {
224 int nchar;
225 char *labelstring=sprintf_str_buffer_safe( wctx->oaep_params->pSourceData, wctx->oaep_params->ulSourceDataLen);
226
227 nchar = snprintf(buffer,
228 buffer_len,
229 "%s/1.0(hash=%s,mgf=%s,label=%s)",
230 "oaep",
231 _hashstring(wctx->oaep_params->hashAlg),
232 _mgfstring(wctx->oaep_params->mgf),
233 wctx->oaep_params->pSourceData==NULL ? "\"\"" : labelstring );
234
235 free_sprintf_str_buffer_safe_buf(labelstring);
236
237 if(nchar>=buffer_len) {
238 fprintf(stderr, "Error: algorithm string (%d) too long for buffer size (%zu)\n", nchar, buffer_len);
239 return rc_error_memory;
240 }
241 }
242 break;
243
244 case w_cbcpad: {
245 char *labelstring=sprintf_str_buffer_safe( wctx->aes_params.iv, wctx->aes_params.iv_len );
246
247 snprintf(buffer,
248 buffer_len,
249 "%s/1.0(iv=%s)",
250 "cbcpad",
251 labelstring );
252
253 free_sprintf_str_buffer_safe_buf(labelstring);
254 }
255 break;
256
257 case w_rfc3394:
258 snprintf(buffer,
259 buffer_len,
260 "%s/1.0",
261 "rfc3394");
262 break;
263
264 case w_rfc5649:
265 /* Because CKM_NSS_AES_KEY_WRAP_PAD is NOT fully compliant with RFC5649, */
266 /* we want to flag it as is, to prevent hairy cases when someone */
267 /* wants to unwrap it on a true RFC5649 compliant token */
268 snprintf(buffer,
269 buffer_len,
270 "%s/1.0%s",
271 "rfc5649",
272 wctx->aes_params.aes_wrapping_mech==CKM_NSS_AES_KEY_WRAP_PAD ? "(flavour=nss)" : "");
273 break;
274
275 default:
276 fprintf(stderr, "Error: unsupported wrapping algorithm.\n");
277 return rc_error_unknown_wrapping_alg;
278 }
279 }
280 return rc_ok;
281 }
282
283
284
285
fprintf_key_type(FILE * fp,char * unused,CK_ATTRIBUTE_PTR attr,bool unused2,int offset)286 static void fprintf_key_type(FILE *fp, char *unused, CK_ATTRIBUTE_PTR attr, bool unused2, int offset)
287 {
288
289 char *value;
290 switch( *(CK_KEY_TYPE *)attr->pValue) {
291
292 case CKK_GENERIC_SECRET:
293 value = "CKK_GENERIC_SECRET";
294 break;
295
296 case CKK_DES:
297 value = "CKK_DES";
298 break;
299
300 case CKK_DES2:
301 value = "CKK_DES2";
302 break;
303
304 case CKK_DES3:
305 value = "CKK_DES3";
306 break;
307
308 case CKK_AES:
309 value = "CKK_AES";
310 break;
311
312 case CKK_MD5_HMAC:
313 value = "CKK_MD5_HMAC";
314 break;
315
316 case CKK_SHA_1_HMAC:
317 value = "CKK_SHA_1_HMAC";
318 break;
319
320 case CKK_RIPEMD128_HMAC:
321 value = "CKK_RIPEMD128_HMAC";
322 break;
323
324 case CKK_RIPEMD160_HMAC:
325 value = "CKK_RIPEMD160_HMAC";
326 break;
327
328 case CKK_SHA256_HMAC:
329 value = "CKK_SHA256_HMAC";
330 break;
331
332 case CKK_SHA384_HMAC:
333 value = "CKK_SHA384_HMAC";
334 break;
335
336 case CKK_SHA512_HMAC:
337 value = "CKK_SHA512_HMAC";
338 break;
339
340 case CKK_SHA224_HMAC:
341 value = "CKK_SHA224_HMAC";
342 break;
343
344 case CKK_RSA:
345 value = "CKK_RSA";
346 break;
347
348 case CKK_DSA:
349 value = "CKK_RSA";
350 break;
351
352 case CKK_DH:
353 value = "CKK_DH";
354 break;
355
356 case CKK_EC:
357 value = "CKK_EC";
358 break;
359
360 case CKK_EC_EDWARDS:
361 value = "CKK_EC_EDWARDS";
362 break;
363
364 default:
365 value = "unsupported";
366 }
367
368 fprintf(fp, "%*sCKA_KEY_TYPE: %s\n", offset, "", value);
369
370 }
371
372
fprintf_object_class(FILE * fp,char * unused,CK_ATTRIBUTE_PTR attr,bool unused2,int offset)373 static void fprintf_object_class(FILE *fp, char *unused, CK_ATTRIBUTE_PTR attr, bool unused2, int offset)
374 {
375
376 char *value;
377
378 switch( *(CK_OBJECT_CLASS *)attr->pValue ) {
379 case CKO_DATA:
380 value = "CKO_DATA";
381 break;
382
383 case CKO_CERTIFICATE:
384 value = "CKO_CERTIFICATE";
385 break;
386
387 case CKO_PUBLIC_KEY:
388 value = "CKO_PUBLIC_KEY";
389 break;
390
391 case CKO_PRIVATE_KEY:
392 value = "CKO_PRIVATE_KEY";
393 break;
394
395 case CKO_SECRET_KEY:
396 value = "CKO_SECRET_KEY";
397 break;
398
399 case CKO_HW_FEATURE:
400 value = "CKO_HW_FEATURE";
401 break;
402
403 case CKO_DOMAIN_PARAMETERS:
404 value = "CKO_DOMAIN_PARAMETERS";
405 break;
406
407 case CKO_MECHANISM:
408 value = "CKO_MECHANISM";
409 break;
410
411 case CKO_OTP_KEY:
412 value = "CKO_OTP_KEY";
413 break;
414
415 default:
416 value = (*(CK_OBJECT_CLASS *)attr->pValue) & CKO_VENDOR_DEFINED ? "CKO_VENDOR_DEFINED" : "??unknown object type??" ;
417 break;
418 }
419
420 fprintf(fp, "%*sCKA_CLASS: %s\n", offset, "", value);
421 }
422
423
fprintf_boolean_attr(FILE * fp,char * name,CK_ATTRIBUTE_PTR attr,bool commented,int offset)424 static void fprintf_boolean_attr(FILE *fp, char *name, CK_ATTRIBUTE_PTR attr, bool commented, int offset)
425 {
426 fprintf (fp, "%s%*s%s: %s\n", commented ? "# " : "", offset, "", name, *((CK_BBOOL *)(attr->pValue))== CK_TRUE ? "true" : "false");
427 }
428
fprintf_hex_attr(FILE * fp,char * name,CK_ATTRIBUTE_PTR attr,bool commented,int offset)429 static void fprintf_hex_attr(FILE *fp, char *name, CK_ATTRIBUTE_PTR attr, bool commented, int offset)
430 {
431 int i;
432
433 fprintf(fp, "%s%*s%s: 0x", commented ? "# " : "", offset, "", name);
434 for(i=0; i<attr->ulValueLen; i++) {
435 fprintf(fp, "%02x", ((unsigned char* )(attr->pValue))[i] );
436 }
437
438 fprintf(fp, "\n");
439 }
440
441 /* _fprintf_str_attr not meant to be used directly, as there is no check about printability */
442 /* use fprintf_str_attr or fprintf_date_attr instead */
_fprintf_str_attr(FILE * fp,char * name,CK_ATTRIBUTE_PTR attr,bool commented,int offset)443 static void _fprintf_str_attr(FILE *fp, char *name, CK_ATTRIBUTE_PTR attr, bool commented, int offset)
444 {
445 fprintf(fp, "%s%*s%s: \"%.*s\"\n", commented ? "# " : "", offset, "", name, (int)(attr->ulValueLen), (unsigned char* )(attr->pValue));
446 }
447
448
449 /* check if we can print it as a string (i.e. no special character) */
450 /* otherwise, print as hex. */
451
fprintf_str_attr(FILE * fp,char * name,CK_ATTRIBUTE_PTR attr,bool commented,int offset)452 static void fprintf_str_attr(FILE *fp, char *name, CK_ATTRIBUTE_PTR attr, bool commented, int offset)
453 {
454 bool seems_printable = false;
455 int i;
456
457 /* simple check: verify all can be printed */
458 for(i=0; i<attr->ulValueLen; i++) {
459 if(!isprint(((unsigned char *)(attr->pValue))[i])) {
460 goto not_printable; /* exit loop prematurely */
461 }
462 }
463 seems_printable = true;
464
465 not_printable:
466 /* do nothing, seems_printable worths 0 */
467
468 seems_printable ? _fprintf_str_attr(fp,name,attr,commented,offset) : fprintf_hex_attr(fp,name,attr,commented,offset);
469
470 }
471
472 /* date is a special case. If it looks like a date, print it in plain characters */
473 /* otherwise take no risk and print as hex value */
474
fprintf_date_attr(FILE * fp,char * name,CK_ATTRIBUTE_PTR attr,bool commented,int offset)475 static void fprintf_date_attr(FILE *fp, char *name, CK_ATTRIBUTE_PTR attr, bool commented, int offset)
476 {
477 bool looks_like_a_date = false;
478
479 if(attr->ulValueLen==8) {
480 int i;
481 /* simple check: verify we have digits everywhere */
482 /* a more sophisticated one would check if it looks like a REAL date... */
483 for(i=0; i<8; i++) {
484 if(!isdigit(((unsigned char *)(attr->pValue))[i])) {
485 goto not_a_date; /* exit loop prematurely */
486 }
487 }
488 looks_like_a_date = true;
489 }
490
491 not_a_date:
492 /* do nothing, looks_like_a_date worths false */
493
494 looks_like_a_date ? _fprintf_str_attr(fp,name,attr,commented,offset) : fprintf_hex_attr(fp,name,attr,commented,offset);
495 }
496
497 /* fprintf_template_attr() function and support functions */
498
compare_attr(const void * a,const void * b)499 static int compare_attr( const void *a, const void *b)
500 {
501 return ((CK_ATTRIBUTE_PTR)a)->type == ((CK_ATTRIBUTE_PTR)b)->type ? 0 : -1;
502 }
503
504
505
fprintf_mechanism_type_array(FILE * fp,char * name,CK_ATTRIBUTE_PTR attr,bool commented,int offset)506 static void fprintf_mechanism_type_array(FILE *fp, char *name, CK_ATTRIBUTE_PTR attr, bool commented, int offset)
507 {
508 int i;
509 CK_MECHANISM_TYPE_PTR mech_array = attr->pValue; /* attr_array will be used as the array to walk mechanisms */
510 size_t mech_arrayitems = attr->ulValueLen / sizeof(CK_MECHANISM_TYPE);
511
512 fprintf(fp, "%s%*s%s: {\n", commented ? "# " : "", offset, "", name);
513
514 for(i=0; i<mech_arrayitems; i++) {
515 fprintf(fp, "%s%*s%s\n", commented ? "# " : "", offset+INDENTATION_OFFSET, "", pkcs11_get_mechanism_name_from_type(mech_array[i]));
516 }
517
518 fprintf(fp, "%s%*s}\n", commented ? "# " : "", offset, "");
519 }
520
fprintf_template_attr_member(FILE * fp,CK_ATTRIBUTE_PTR attr,int offset)521 static void fprintf_template_attr_member(FILE *fp, CK_ATTRIBUTE_PTR attr, int offset)
522 {
523
524 /* a collection of possible values found in templates */
525 /* all attributes are uncommented */
526 static const attr_printer attriblist[] = {
527 { CKA_ALLOWED_MECHANISMS, fprintf_mechanism_type_array, "CKA_ALLOWED_MECHANISMS", false },
528 { CKA_CHECK_VALUE, fprintf_hex_attr, "CKA_CHECK_VALUE", true },
529 { CKA_CLASS, fprintf_object_class, "CKA_CLASS", false },
530 { CKA_DECRYPT, fprintf_boolean_attr, "CKA_DECRYPT", false },
531 { CKA_DERIVE, fprintf_boolean_attr, "CKA_DERIVE", false },
532 { CKA_EC_PARAMS, fprintf_hex_attr, "CKA_EC_PARAMS", true },
533 { CKA_ENCRYPT, fprintf_boolean_attr, "CKA_ENCRYPT", false },
534 { CKA_END_DATE, fprintf_date_attr, "CKA_END_DATE", false },
535 { CKA_EXTRACTABLE, fprintf_boolean_attr, "CKA_EXTRACTABLE", false },
536 { CKA_ID, fprintf_str_attr, "CKA_ID", false },
537 { CKA_KEY_TYPE, fprintf_key_type, "CKA_KEY_TYPE", false },
538 { CKA_LABEL, fprintf_str_attr, "CKA_LABEL", false },
539 { CKA_MODIFIABLE, fprintf_boolean_attr, "CKA_MODIFIABLE", false },
540 { CKA_PRIVATE, fprintf_boolean_attr, "CKA_PRIVATE", false },
541 { CKA_SENSITIVE, fprintf_boolean_attr, "CKA_SENSITIVE", false },
542 { CKA_SIGN, fprintf_boolean_attr, "CKA_SIGN", false },
543 { CKA_SIGN_RECOVER, fprintf_boolean_attr, "CKA_SIGN_RECOVER", false },
544 { CKA_START_DATE, fprintf_date_attr, "CKA_START_DATE", false },
545 { CKA_SUBJECT, fprintf_hex_attr, "CKA_SUBJECT", false },
546 { CKA_TOKEN, fprintf_boolean_attr, "CKA_TOKEN", false },
547 { CKA_UNWRAP, fprintf_boolean_attr, "CKA_UNWRAP", false },
548 { CKA_VERIFY, fprintf_boolean_attr, "CKA_VERIFY", false },
549 { CKA_VERIFY_RECOVER, fprintf_boolean_attr, "CKA_VERIFY_RECOVER", false },
550 { CKA_WRAP, fprintf_boolean_attr, "CKA_WRAP", false },
551 };
552
553 size_t nelem = sizeof attriblist / sizeof(attr_printer);
554 attr_printer key = { attr->type, NULL, NULL, false };
555 attr_printer *match = lfind(&key, attriblist, &nelem, sizeof(attr_printer), compare_attr);
556
557 if(match) {
558 match->func_ptr(fp, match->name, attr, false, offset ); /* we ignore the comment argument */
559 }
560
561 }
562
fprintf_template_attr(FILE * fp,char * name,CK_ATTRIBUTE_PTR attr,bool commented,int offset)563 static void fprintf_template_attr(FILE *fp, char *name, CK_ATTRIBUTE_PTR attr, bool commented, int offset)
564 {
565 int i;
566 CK_ATTRIBUTE_PTR attr_array = attr->pValue; /* attr_array will be used as the array to walk template */
567 size_t attr_arrayitems = attr->ulValueLen / sizeof(CK_ATTRIBUTE);
568
569 fprintf(fp, "%s%*s%s: {\n", commented ? "# " : "", offset, "", name);
570
571 for(i=0; i<attr_arrayitems; i++) {
572 fprintf(fp, "%s", commented ? "# " : "");
573 fprintf_template_attr_member(fp, &attr_array[i], offset+INDENTATION_OFFSET);
574 }
575
576 fprintf(fp, "%s%*s}\n", commented ? "# " : "", offset, "");
577 }
578
579 /*------------------------------------------------------------------------*/
580
581
sprintf_hex_buffer(CK_BYTE_PTR buffer,CK_ULONG len)582 static char * sprintf_hex_buffer(CK_BYTE_PTR buffer, CK_ULONG len)
583 {
584
585 char *allocated = malloc(len*2+3);
586
587 if(allocated==NULL) {
588 fprintf(stderr, "***Error: memory allocation\n");
589 } else {
590
591 int i;
592
593 allocated[0]='0';
594 allocated[1]='x';
595
596 for(i=0; i<len; i++) {
597 snprintf(&allocated[2+i*2], 3, "%02x", buffer[i] );
598 }
599 }
600
601 return allocated;
602 }
603
604 /* _sprintf_str_buffer not meant to be used directly, as there is no check about printability */
605 /* use sprintf_str_buffer_safe instead */
_sprintf_str_buffer(CK_BYTE_PTR buffer,CK_ULONG len)606 static char * _sprintf_str_buffer(CK_BYTE_PTR buffer, CK_ULONG len)
607 {
608 char *allocated = malloc(len+3);
609
610 if(allocated==NULL) {
611 fprintf(stderr, "***Error: memory allocation\n");
612 } else {
613 snprintf(allocated,len+3, "\"%.*s\"", (int)len, buffer);
614 }
615 return allocated;
616 }
617
618
619 /* check if we can print the buffer as a string (i.e. no special character) */
620 /* otherwise, print as hex. */
621
sprintf_str_buffer_safe(CK_BYTE_PTR buffer,CK_ULONG len)622 static char * sprintf_str_buffer_safe(CK_BYTE_PTR buffer, CK_ULONG len)
623 {
624 int seems_printable = 0;
625 int i;
626
627 /* simple check: verify all can be printed */
628 for(i=0; i<len; i++) {
629 if(!isprint(buffer[i])) {
630 goto not_printable; /* exit loop prematurely */
631 }
632 }
633 seems_printable = 1;
634
635 not_printable:
636 /* do nothing, seems_printable worths 0 */
637
638 return seems_printable ? _sprintf_str_buffer(buffer,len) : sprintf_hex_buffer(buffer,len);
639
640 }
641
free_sprintf_str_buffer_safe_buf(char * ptr)642 static void free_sprintf_str_buffer_safe_buf(char *ptr)
643 {
644 if(ptr) { free(ptr); }
645 }
646
647 /*------------------------------------------------------------------------*/
648
649
_mgfstring(CK_RSA_PKCS_MGF_TYPE mgf)650 static char * const _mgfstring(CK_RSA_PKCS_MGF_TYPE mgf)
651 {
652 char *retval = NULL;
653
654 switch(mgf) {
655 case CKG_MGF1_SHA1:
656 retval = "CKG_MGF1_SHA1";
657 break;
658
659 case CKG_MGF1_SHA256:
660 retval = "CKG_MGF1_SHA256";
661 break;
662
663 case CKG_MGF1_SHA384:
664 retval = "CKG_MGF1_SHA384";
665 break;
666
667 case CKG_MGF1_SHA512:
668 retval = "CKG_MGF1_SHA512";
669 break;
670
671 case CKG_MGF1_SHA224:
672 retval = "CKG_MGF1_SHA224";
673 break;
674
675 }
676
677 return retval;
678 }
679
_hashstring(CK_MECHANISM_TYPE hash)680 static char * const _hashstring(CK_MECHANISM_TYPE hash)
681 {
682 char *retval = NULL;
683
684 switch(hash) {
685 case CKM_MD2:
686 retval = "CKM_MD2";
687 break;
688
689 case CKM_MD5:
690 retval = "CKM_MD5";
691 break;
692
693 case CKM_SHA_1:
694 retval = "CKM_SHA_1";
695 break;
696
697 case CKM_RIPEMD128:
698 retval = "CKM_RIPEMD128";
699 break;
700
701 case CKM_RIPEMD160:
702 retval = "CKM_RIPEMD160";
703 break;
704
705 case CKM_SHA256:
706 retval = "CKM_SHA256";
707 break;
708
709 case CKM_SHA224:
710 retval = "CKM_SHA224";
711 break;
712
713 case CKM_SHA384:
714 retval = "CKM_SHA384";
715 break;
716
717 case CKM_SHA512:
718 retval = "CKM_SHA512";
719 break;
720 }
721
722 return retval;
723
724 }
725
_output_wrapped_key_header(wrappedKeyCtx * wctx,FILE * fp)726 static func_rc _output_wrapped_key_header(wrappedKeyCtx *wctx, FILE *fp)
727 {
728
729 time_t now = time(NULL);
730 char hostname[255];
731
732 /* keyindex: in case of envelope wrapping, the index shall always be the outer */
733 int keyindex = wctx->is_envelope ? WRAPPEDKEYCTX_INNER_KEY_INDEX : WRAPPEDKEYCTX_LONE_KEY_INDEX;
734
735 char *wctxlabel = wctx->wrappedkeylabel;
736 char *handlelabel = pkcs11_alloclabelforhandle(wctx->p11Context, wctx->key[keyindex].wrappedkeyhandle);
737 char *wrappedkeylabel = wctxlabel ? wctxlabel : handlelabel ? handlelabel : "-no label found-";
738
739 gethostname(hostname, 255);
740 hostname[254]=0; /* just to be sure... */
741
742 fprintf(fp, \
743 "########################################################################\n"
744 "#\n"
745 "# key <%s> wrapped by key <%s>\n"
746 "# wrapped on host <%s>\n"
747 "# operation date and time (UTC): %s"
748 "# wrapping algorithm: %s\n"
749 "#\n"
750 "# use p11unwrap from pkcs11-tools to unwrap key on dest. PKCS#11 token\n"
751 "#\n"
752 "# grammar for this file:\n"
753 "# ----------------------\n"
754 "#\n"
755 "# - lines starting with '#' are ignored\n"
756 "#\n"
757 "# - [ATTRIBUTE] : [VALUE]\n"
758 "# where [ATTRIBUTE] is any of the following:\n"
759 "# Content-Type ( value is application/pkcs11-tools)\n"
760 "# Wrapping-Algorithm: execute p11wrap -h for syntax\n"
761 "# CKA_LABEL\n"
762 "# CKA_ID\n"
763 "# CKA_CLASS\n"
764 "# CKA_TOKEN\n"
765 "# CKA_KEY_TYPE\n"
766 "# CKA_ENCRYPT\n"
767 "# CKA_DECRYPT\n"
768 "# CKA_WRAP\n"
769 "# CKA_UNWRAP\n"
770 "# CKA_SIGN\n"
771 "# CKA_VERIFY\n"
772 "# CKA_DERIVE\n"
773 "# CKA_PRIVATE\n"
774 "# CKA_SENSITIVE\n"
775 "# CKA_EXTRACTABLE\n"
776 "# CKA_MODIFIABLE\n"
777 "# CKA_START_DATE\n"
778 "# CKA_END_DATE\n"
779 "# CKA_CHECK_VALUE\n"
780 "# CKA_WRAP_TEMPLATE\n"
781 "# CKA_UNWRAP_TEMPLATE\n"
782 "# CKA_ALLOWED_MECHANISMS\n"
783 "# where, depending on the attribute, [VALUE] can be one of the following:\n"
784 "# \"Hello world\" (printable string)\n"
785 "# 0x1A2B3C4D (hex bytes)\n"
786 "# 20150630 (date)\n"
787 "# true/false/CK_TRUE/CK_FALSE/yes/no (boolean)\n"
788 "# { attribute=value attribute=value ... }"
789 "# { mechanism mechanism ... }"
790 "#\n"
791 "# - wrapped key is contained between -----BEGIN WRAPPED KEY-----\n"
792 "# and -----END WRAPPED KEY----- marks and is Base64 encoded\n"
793 "#\n"
794 "########################################################################\n"
795 "Content-Type: application/pkcs11-tools\n"
796 "Grammar-Version: " SUPPORTED_GRAMMAR_VERSION "\n"
797 "Wrapping-Key: \"%s\"\n",
798 wrappedkeylabel,
799 wctx->wrappingkeylabel,
800 hostname,
801 asctime(gmtime(&now)),
802 get_wrapping_algorithm_short(wctx),
803 wctx->wrappingkeylabel );
804
805 free(handlelabel); /* we must free this structure */
806
807 if(fprintf_wrapping_algorithm_full(fp, wctx, NULL, 0, WRAPPEDKEYCTX_NO_INDEX) != rc_ok) {
808 fprintf(stderr, "Error: unsupported wrapping algorithm.\n");
809 return rc_error_unknown_wrapping_alg;
810 }
811
812 return rc_ok;
813 }
814
_output_wrapped_keys_b64(wrappedKeyCtx * wctx,FILE * fp)815 static func_rc _output_wrapped_keys_b64(wrappedKeyCtx *wctx, FILE *fp)
816 {
817 func_rc rc = rc_ok;
818 BIO *bio_stdout = NULL, *bio_b64 = NULL;
819
820 bio_b64 = BIO_new( BIO_f_base64() );
821 if(bio_b64==NULL) {
822 P_ERR();
823 rc = rc_error_openssl_api;
824 goto err;
825 }
826
827 bio_stdout = BIO_new( BIO_s_file() );
828 if(bio_stdout==NULL) {
829 P_ERR();
830 rc = rc_error_openssl_api;
831 goto err;
832 }
833
834 BIO_set_fp(bio_stdout, fp, BIO_NOCLOSE);
835
836 if(wctx->is_envelope) {
837 BIO_puts(bio_stdout, "-----BEGIN OUTER WRAPPED KEY-----\n");
838 BIO_flush(bio_stdout);
839 BIO_push(bio_b64, bio_stdout);
840 BIO_write(bio_b64,
841 wctx->key[WRAPPEDKEYCTX_OUTER_KEY_INDEX].wrapped_key_buffer,
842 wctx->key[WRAPPEDKEYCTX_OUTER_KEY_INDEX].wrapped_key_len);
843 BIO_flush(bio_b64);
844 BIO_puts(bio_stdout, "-----END OUTER WRAPPED KEY-----\n");
845 BIO_flush(bio_stdout);
846 }
847
848 BIO_puts(bio_stdout, wctx->is_envelope ? "-----BEGIN INNER WRAPPED KEY-----\n" : "-----BEGIN WRAPPED KEY-----\n");
849 BIO_flush(bio_stdout);
850 BIO_push(bio_b64, bio_stdout);
851 BIO_write(bio_b64,
852 wctx->key[WRAPPEDKEYCTX_INNER_OR_LONE_KEY_INDEX].wrapped_key_buffer,
853 wctx->key[WRAPPEDKEYCTX_INNER_OR_LONE_KEY_INDEX].wrapped_key_len);
854 BIO_flush(bio_b64);
855 BIO_puts(bio_stdout, wctx->is_envelope ? "-----END INNER WRAPPED KEY-----\n" : "-----END WRAPPED KEY-----\n");
856 BIO_flush(bio_stdout);
857
858 err:
859 if(bio_stdout) BIO_free(bio_stdout);
860 if(bio_b64) BIO_free(bio_b64);
861
862 return rc;
863 }
864
865
_output_wrapped_key_attributes(wrappedKeyCtx * wctx,FILE * fp)866 static func_rc _output_wrapped_key_attributes(wrappedKeyCtx *wctx, FILE *fp)
867 {
868 func_rc rc = rc_ok;
869
870 pkcs11AttrList *wrappedkey_attrs = NULL;
871 CK_ATTRIBUTE_PTR o_attr = NULL;
872 size_t alist_len=0;
873
874 static attr_printer seckalist[] = {
875 { CKA_LABEL, fprintf_str_attr, "CKA_LABEL", false },
876 { CKA_ID, fprintf_str_attr, "CKA_ID", false },
877 { CKA_CLASS, fprintf_object_class, "CKA_CLASS", false },
878 { CKA_TOKEN, fprintf_boolean_attr, "CKA_TOKEN", false },
879 { CKA_KEY_TYPE, fprintf_key_type, "CKA_KEY_TYPE", false },
880 { CKA_ALLOWED_MECHANISMS, fprintf_mechanism_type_array, "CKA_ALLOWED_MECHANISMS", false },
881 { CKA_ENCRYPT, fprintf_boolean_attr, "CKA_ENCRYPT", false },
882 { CKA_DECRYPT, fprintf_boolean_attr, "CKA_DECRYPT", false },
883 { CKA_WRAP, fprintf_boolean_attr, "CKA_WRAP", false },
884 { CKA_WRAP_TEMPLATE, fprintf_template_attr, "CKA_WRAP_TEMPLATE", false },
885 { CKA_UNWRAP, fprintf_boolean_attr, "CKA_UNWRAP", false },
886 { CKA_UNWRAP_TEMPLATE, fprintf_template_attr, "CKA_UNWRAP_TEMPLATE", false },
887 { CKA_SIGN, fprintf_boolean_attr, "CKA_SIGN", false },
888 { CKA_VERIFY, fprintf_boolean_attr, "CKA_VERIFY", false },
889 { CKA_DERIVE, fprintf_boolean_attr, "CKA_DERIVE", false },
890 { CKA_DERIVE_TEMPLATE, fprintf_template_attr, "CKA_DERIVE_TEMPLATE", false },
891 { CKA_PRIVATE, fprintf_boolean_attr, "CKA_PRIVATE", false },
892 { CKA_SENSITIVE, fprintf_boolean_attr, "CKA_SENSITIVE", false },
893 { CKA_EXTRACTABLE, fprintf_boolean_attr, "CKA_EXTRACTABLE", false },
894 { CKA_MODIFIABLE, fprintf_boolean_attr, "CKA_MODIFIABLE", false },
895 { CKA_START_DATE, fprintf_date_attr, "CKA_START_DATE", false },
896 { CKA_END_DATE, fprintf_date_attr, "CKA_END_DATE", false },
897 { CKA_CHECK_VALUE, fprintf_hex_attr, "CKA_CHECK_VALUE", true }, /* Not valid in C_Unwrap() template */
898 };
899
900 static attr_printer prvkalist[] = {
901 { CKA_LABEL, fprintf_str_attr, "CKA_LABEL", false },
902 { CKA_ID, fprintf_str_attr, "CKA_ID", false },
903 { CKA_CLASS, fprintf_object_class, "CKA_CLASS", false },
904 { CKA_TOKEN, fprintf_boolean_attr, "CKA_TOKEN", false },
905 { CKA_KEY_TYPE, fprintf_key_type, "CKA_KEY_TYPE", false },
906 { CKA_ALLOWED_MECHANISMS, fprintf_mechanism_type_array, "CKA_ALLOWED_MECHANISMS", false },
907 { CKA_EC_PARAMS, fprintf_hex_attr, "CKA_EC_PARAMS", true }, /* Not valid in C_Unwrap() template */
908 { CKA_SUBJECT, fprintf_hex_attr, "CKA_SUBJECT", false },
909 { CKA_DECRYPT, fprintf_boolean_attr, "CKA_DECRYPT", false },
910 { CKA_UNWRAP, fprintf_boolean_attr, "CKA_UNWRAP", false },
911 { CKA_UNWRAP_TEMPLATE, fprintf_template_attr, "CKA_UNWRAP_TEMPLATE", false },
912 { CKA_SIGN, fprintf_boolean_attr, "CKA_SIGN", false },
913 { CKA_SIGN_RECOVER, fprintf_boolean_attr, "CKA_SIGN_RECOVER", false },
914 { CKA_DERIVE, fprintf_boolean_attr, "CKA_DERIVE", false },
915 { CKA_DERIVE_TEMPLATE, fprintf_template_attr, "CKA_DERIVE_TEMPLATE", false },
916 { CKA_PRIVATE, fprintf_boolean_attr, "CKA_PRIVATE", false },
917 { CKA_SENSITIVE, fprintf_boolean_attr, "CKA_SENSITIVE", false },
918 { CKA_EXTRACTABLE, fprintf_boolean_attr, "CKA_EXTRACTABLE", false },
919 { CKA_MODIFIABLE, fprintf_boolean_attr, "CKA_MODIFIABLE", false },
920 { CKA_START_DATE, fprintf_date_attr, "CKA_START_DATE", false },
921 { CKA_END_DATE, fprintf_date_attr, "CKA_END_DATE", false },
922 };
923
924 attr_printer *alist=NULL;
925
926 switch(wctx->key[WRAPPEDKEYCTX_INNER_OR_LONE_KEY_INDEX].wrappedkeyobjclass) {
927 case CKO_SECRET_KEY:
928 alist = seckalist;
929 alist_len = sizeof(seckalist)/sizeof(attr_printer);
930 wrappedkey_attrs = pkcs11_new_attrlist(wctx->p11Context,
931 _ATTR(CKA_LABEL),
932 _ATTR(CKA_ID),
933 _ATTR(CKA_CLASS),
934 _ATTR(CKA_TOKEN),
935 _ATTR(CKA_KEY_TYPE),
936 _ATTR(CKA_ALLOWED_MECHANISMS),
937 _ATTR(CKA_ENCRYPT),
938 _ATTR(CKA_DECRYPT),
939 _ATTR(CKA_WRAP),
940 _ATTR(CKA_WRAP_TEMPLATE),
941 _ATTR(CKA_UNWRAP),
942 _ATTR(CKA_UNWRAP_TEMPLATE),
943 _ATTR(CKA_SIGN),
944 _ATTR(CKA_VERIFY),
945 _ATTR(CKA_DERIVE_TEMPLATE),
946 _ATTR(CKA_DERIVE),
947 _ATTR(CKA_PRIVATE),
948 _ATTR(CKA_SENSITIVE),
949 _ATTR(CKA_EXTRACTABLE),
950 _ATTR(CKA_MODIFIABLE),
951 _ATTR(CKA_START_DATE),
952 _ATTR(CKA_END_DATE),
953 _ATTR(CKA_CHECK_VALUE),
954 _ATTR_END );
955 break;
956
957 case CKO_PRIVATE_KEY:
958 alist = prvkalist;
959 alist_len = sizeof(prvkalist)/sizeof(attr_printer);
960 wrappedkey_attrs = pkcs11_new_attrlist(wctx->p11Context,
961 _ATTR(CKA_LABEL),
962 _ATTR(CKA_ID),
963 _ATTR(CKA_CLASS),
964 _ATTR(CKA_TOKEN),
965 _ATTR(CKA_KEY_TYPE),
966 _ATTR(CKA_ALLOWED_MECHANISMS),
967 _ATTR(CKA_EC_PARAMS),
968 _ATTR(CKA_SUBJECT),
969 _ATTR(CKA_DECRYPT),
970 _ATTR(CKA_UNWRAP),
971 _ATTR(CKA_UNWRAP_TEMPLATE),
972 _ATTR(CKA_SIGN),
973 _ATTR(CKA_SIGN_RECOVER),
974 _ATTR(CKA_DERIVE),
975 _ATTR(CKA_DERIVE_TEMPLATE),
976 _ATTR(CKA_PRIVATE),
977 _ATTR(CKA_SENSITIVE),
978 _ATTR(CKA_EXTRACTABLE),
979 _ATTR(CKA_MODIFIABLE),
980 _ATTR(CKA_START_DATE),
981 _ATTR(CKA_END_DATE),
982 _ATTR_END );
983 break;
984
985 default:
986 fprintf(stderr,"***Error: Oops... invalid object type, bailing out\n");
987 rc = rc_error_oops;
988 goto error;
989 }
990
991
992 if( pkcs11_read_attr_from_handle (wrappedkey_attrs, wctx->key[WRAPPEDKEYCTX_INNER_OR_LONE_KEY_INDEX].wrappedkeyhandle) == false) {
993 fprintf(stderr,"Error: could not read attributes from key with label '%s'\n", wctx->wrappedkeylabel);
994 rc = rc_error_pkcs11_api;
995 goto error;
996 }
997
998 {
999 size_t i;
1000
1001 for(i=0;i<alist_len;i++) {
1002 o_attr = pkcs11_get_attr_in_attrlist(wrappedkey_attrs, alist[i].attr_type);
1003
1004 if(o_attr == NULL) {
1005 fprintf(fp, "# %s attribute not found\n", alist[i].name);
1006 } else if (o_attr->type == CKA_EXTRACTABLE) {
1007 /* security feature: unwrapped keys should not have CKA_EXTRACTABLE set to true */
1008 fprintf(fp, "CKA_EXTRACTABLE: false\n");
1009 } else if (o_attr->type == CKA_TOKEN) {
1010 /* unwrapped keys always have CKA_TOKEN set to true */
1011 fprintf(fp, "CKA_TOKEN: true\n");
1012 } else if (o_attr->ulValueLen == 0) {
1013 fprintf(fp, "# %s attribute is empty\n", alist[i].name);
1014 } else if ( ( o_attr->type==CKA_UNWRAP_TEMPLATE ||
1015 o_attr->type==CKA_DERIVE_TEMPLATE ||
1016 o_attr->type==CKA_WRAP_TEMPLATE) &&
1017 o_attr->ulValueLen % sizeof(CK_ATTRIBUTE) != 0 ) {
1018 /* on Safenet Luna, private keys have, by default, templates that are 1 byte long */
1019 /* which is not a valid content for templates */
1020 fprintf(fp, "# %s attribute invalid on the source token\n", alist[i].name);
1021 } else {
1022 alist[i].func_ptr(fp, alist[i].name, o_attr, alist[i].commented, 0 );
1023 }
1024 }
1025 }
1026
1027
1028 error:
1029
1030 pkcs11_delete_attrlist(wrappedkey_attrs);
1031
1032 return rc;
1033
1034 }
1035
_output_public_key_b64(wrappedKeyCtx * wctx,FILE * fp)1036 static func_rc _output_public_key_b64(wrappedKeyCtx *wctx, FILE *fp)
1037 {
1038 func_rc rc = rc_ok;
1039 BIO *bio_stdout = NULL;
1040
1041 bio_stdout = BIO_new( BIO_s_file() );
1042 if(bio_stdout==NULL) {
1043 P_ERR();
1044 rc = rc_error_openssl_api;
1045 goto err;
1046 }
1047
1048 BIO_set_fp(bio_stdout, fp, BIO_NOCLOSE);
1049 rc = pkcs11_cat_object_with_handle(wctx->p11Context, wctx->pubkhandle, 0, bio_stdout);
1050
1051 err:
1052 if(bio_stdout) BIO_free(bio_stdout);
1053
1054 return rc;
1055 }
1056
_output_public_key_attributes(wrappedKeyCtx * wctx,FILE * fp)1057 static func_rc _output_public_key_attributes(wrappedKeyCtx *wctx, FILE *fp)
1058 {
1059 func_rc rc = rc_ok;
1060
1061 pkcs11AttrList *wrappedkey_attrs = NULL;
1062 CK_ATTRIBUTE_PTR o_attr = NULL;
1063 size_t alist_len=0;
1064
1065 static attr_printer alist[] = {
1066 { CKA_LABEL, fprintf_str_attr, "CKA_LABEL", false },
1067 { CKA_ID, fprintf_str_attr, "CKA_ID", false },
1068 { CKA_CLASS, fprintf_object_class, "CKA_CLASS", false },
1069 { CKA_TOKEN, fprintf_boolean_attr, "CKA_TOKEN", false },
1070 { CKA_KEY_TYPE, fprintf_key_type, "CKA_KEY_TYPE", false },
1071 { CKA_ALLOWED_MECHANISMS, fprintf_mechanism_type_array, "CKA_ALLOWED_MECHANISMS", false },
1072 { CKA_EC_PARAMS, fprintf_hex_attr, "CKA_EC_PARAMS", true },
1073 { CKA_SUBJECT, fprintf_hex_attr, "CKA_SUBJECT", false },
1074 { CKA_ENCRYPT, fprintf_boolean_attr, "CKA_ENCRYPT", false },
1075 { CKA_WRAP, fprintf_boolean_attr, "CKA_WRAP", false },
1076 { CKA_WRAP_TEMPLATE, fprintf_template_attr, "CKA_WRAP_TEMPLATE", false },
1077 { CKA_VERIFY, fprintf_boolean_attr, "CKA_VERIFY", false },
1078 { CKA_VERIFY_RECOVER, fprintf_boolean_attr, "CKA_VERIFY_RECOVER", false },
1079 { CKA_DERIVE, fprintf_boolean_attr, "CKA_DERIVE", false },
1080 { CKA_PRIVATE, fprintf_boolean_attr, "CKA_PRIVATE", false },
1081 { CKA_MODIFIABLE, fprintf_boolean_attr, "CKA_MODIFIABLE", false },
1082 { CKA_START_DATE, fprintf_date_attr, "CKA_START_DATE", false },
1083 { CKA_END_DATE, fprintf_date_attr, "CKA_END_DATE", false },
1084 };
1085
1086 alist_len = sizeof(alist)/sizeof(attr_printer);
1087 wrappedkey_attrs = pkcs11_new_attrlist(wctx->p11Context,
1088 _ATTR(CKA_LABEL),
1089 _ATTR(CKA_ID),
1090 _ATTR(CKA_CLASS),
1091 _ATTR(CKA_TOKEN),
1092 _ATTR(CKA_KEY_TYPE),
1093 _ATTR(CKA_ALLOWED_MECHANISMS),
1094 _ATTR(CKA_EC_PARAMS),
1095 _ATTR(CKA_SUBJECT),
1096 _ATTR(CKA_ENCRYPT),
1097 _ATTR(CKA_WRAP),
1098 _ATTR(CKA_WRAP_TEMPLATE),
1099 _ATTR(CKA_VERIFY),
1100 _ATTR(CKA_VERIFY_RECOVER),
1101 _ATTR(CKA_DERIVE),
1102 _ATTR(CKA_PRIVATE),
1103 _ATTR(CKA_MODIFIABLE),
1104 _ATTR(CKA_START_DATE),
1105 _ATTR(CKA_END_DATE),
1106 _ATTR_END );
1107
1108 if( pkcs11_read_attr_from_handle (wrappedkey_attrs, wctx->pubkhandle) == false) {
1109 fprintf(stderr,"Error: could not read attributes from key with label '%s'\n", wctx->wrappedkeylabel);
1110 rc = rc_error_pkcs11_api;
1111 goto error;
1112 }
1113
1114 size_t i;
1115
1116 for(i=0;i<alist_len;i++) {
1117 o_attr = pkcs11_get_attr_in_attrlist(wrappedkey_attrs, alist[i].attr_type);
1118
1119 if(o_attr == NULL) {
1120 fprintf(fp, "# %s attribute not found\n", alist[i].name);
1121 } else if (o_attr->type == CKA_EXTRACTABLE) {
1122 /* security feature: unwrapped keys should not have CKA_EXTRACTABLE set to true */
1123 fprintf(fp, "CKA_EXTRACTABLE: false\n");
1124 } else if (o_attr->type == CKA_TOKEN) {
1125 /* unwrapped keys always have CKA_TOKEN set to true */
1126 fprintf(fp, "CKA_TOKEN: true\n");
1127 } else if (o_attr->ulValueLen == 0) {
1128 fprintf(fp, "# %s attribute is empty\n", alist[i].name);
1129 } else {
1130 alist[i].func_ptr(fp, alist[i].name, o_attr, alist[i].commented, 0 );
1131 }
1132 }
1133
1134 error:
1135 pkcs11_delete_attrlist(wrappedkey_attrs);
1136 return rc;
1137 }
1138
_wrap_pkcs1_15(wrappedKeyCtx * wctx)1139 static func_rc _wrap_pkcs1_15(wrappedKeyCtx *wctx)
1140 {
1141 func_rc rc = rc_ok;
1142
1143 CK_OBJECT_HANDLE wrappingkeyhandle=NULL_PTR;
1144 CK_OBJECT_HANDLE wrappedkeyhandle=NULL_PTR;
1145 CK_OBJECT_CLASS wrappedkeyobjclass;
1146 pkcs11AttrList *wrappedkey_attrs = NULL, *wrappingkey_attrs = NULL;
1147 CK_ATTRIBUTE_PTR o_wrappedkey_bytes, o_modulus, o_keytype;
1148 BIGNUM *bn_wrappingkey_bytes = NULL;
1149 BIGNUM *bn_wrappedkey_bytes = NULL;
1150 int bytelen;
1151 unsigned long keysizeinbytes;
1152
1153 /* keyindex: in case of envelope wrapping, the index shall always be the outer */
1154 int keyindex = wctx->is_envelope ? WRAPPEDKEYCTX_OUTER_KEY_INDEX : WRAPPEDKEYCTX_LONE_KEY_INDEX;
1155
1156 /* retrieve keys */
1157
1158 if(wctx->is_envelope) {
1159 /* if envelope encryption, keys have been already found by _wrap_envelope() */
1160 /* and wctx structure has been populated. */
1161 wrappedkeyhandle = wctx->key[keyindex].wrappedkeyhandle;
1162 wrappingkeyhandle = wctx->key[keyindex].wrappingkeyhandle;
1163 } else {
1164 if (!pkcs11_findpublickey(wctx->p11Context, wctx->wrappingkeylabel, &wrappingkeyhandle)) {
1165 fprintf(stderr,"Error: could not find a public key with label '%s'\n", wctx->wrappingkeylabel);
1166 rc = rc_error_object_not_found;
1167 goto error;
1168 }
1169
1170 /* if we called _wrap() with meth_keyhandle, then the wrappedkeylabel is NULL */
1171 /* and we can directly use the value in wrappedkeyhabndle */
1172 if(wctx->wrappedkeylabel==NULL) {
1173 wrappedkeyhandle = wctx->key[keyindex].wrappedkeyhandle;
1174 /* we need to retrieve the object class */
1175 wrappedkeyobjclass = pkcs11_get_object_class(wctx->p11Context, wrappedkeyhandle);
1176
1177 if(wrappedkeyobjclass != CKO_SECRET_KEY) {
1178 fprintf(stderr,"***Error: PKCS#1 1.5 wrapping algorithm can only wrap secret keys, not private keys\n");
1179 rc = rc_error_wrong_object_class;
1180 goto error;
1181 }
1182 } else {
1183 if(!pkcs11_findsecretkey(wctx->p11Context, wctx->wrappedkeylabel, &wrappedkeyhandle)) {
1184 fprintf(stderr,"Error: secret key with label '%s' does not exists\n", wctx->wrappedkeylabel);
1185 rc = rc_error_object_not_found;
1186 goto error;
1187 }
1188 }
1189 }
1190
1191 /* retrieve length of wrapping key */
1192 wrappingkey_attrs = pkcs11_new_attrlist(wctx->p11Context,
1193 _ATTR(CKA_MODULUS),
1194 _ATTR_END );
1195
1196 if( pkcs11_read_attr_from_handle (wrappingkey_attrs, wrappingkeyhandle) == false) {
1197 fprintf(stderr,"Error: could not read CKA_MODULUS_BITS attribute from public key with label '%s'\n", wctx->wrappingkeylabel);
1198 rc = rc_error_pkcs11_api;
1199 goto error;
1200 }
1201
1202 o_modulus = pkcs11_get_attr_in_attrlist(wrappingkey_attrs, CKA_MODULUS);
1203
1204 /* overwrite existing value */
1205 if ( (bn_wrappingkey_bytes = BN_bin2bn(o_modulus->pValue, o_modulus->ulValueLen, NULL)) == NULL ) {
1206 P_ERR();
1207 goto error;
1208 }
1209
1210 /* extract number of bytes */
1211 bytelen = BN_num_bytes(bn_wrappingkey_bytes);
1212
1213 /* and adjust value */
1214 BN_set_word(bn_wrappingkey_bytes, (unsigned long)bytelen);
1215
1216 /* retrieve length of wrapped key */
1217 wrappedkey_attrs = pkcs11_new_attrlist(wctx->p11Context,
1218 _ATTR(CKA_KEY_TYPE), /* for DES/DES2/DES3 */
1219 _ATTR(CKA_VALUE_LEN), /* caution: value in bytes */
1220 _ATTR_END );
1221
1222 if( pkcs11_read_attr_from_handle (wrappedkey_attrs, wrappedkeyhandle) == false) {
1223 fprintf(stderr,"Error: could not read CKA_VALUE_LEN attribute from secret key with label '%s'\n", wctx->wrappedkeylabel);
1224 rc = rc_error_pkcs11_api;
1225 goto error;
1226 }
1227
1228 o_wrappedkey_bytes = pkcs11_get_attr_in_attrlist(wrappedkey_attrs, CKA_VALUE_LEN);
1229 /* pkcs11_get_attr_in_attrlist returns the attribute, but we need to check */
1230 /* if there is actually a value attached to it */
1231
1232 if(o_wrappedkey_bytes && o_wrappedkey_bytes->pValue) {
1233
1234
1235 /* BN_bin2bn works only with big endian, so we must alter data */
1236 /* if architecture is LE */
1237
1238 *((CK_ULONG *)o_wrappedkey_bytes->pValue) = pkcs11_ll_bigendian_ul( *((CK_ULONG *)(o_wrappedkey_bytes->pValue))); /* transform if required */
1239
1240 if ( (bn_wrappedkey_bytes = BN_bin2bn( o_wrappedkey_bytes->pValue, o_wrappedkey_bytes->ulValueLen, NULL) ) == NULL ) {
1241 P_ERR();
1242 goto error;
1243 }
1244 } else { /* can be the case for CKK_DES, CKK_DES2 and CKK_DES3 family */
1245 /* as these keys have no CKA_VALUE_LEN attribute */
1246
1247 o_keytype = pkcs11_get_attr_in_attrlist(wrappedkey_attrs, CKA_KEY_TYPE);
1248
1249 switch(*(CK_KEY_TYPE *)(o_keytype->pValue)) {
1250 case CKK_DES:
1251 keysizeinbytes=8;
1252 break;
1253
1254 case CKK_DES2:
1255 keysizeinbytes=16;
1256 break;
1257
1258 case CKK_DES3:
1259 keysizeinbytes=24;
1260 break;
1261
1262 default:
1263 fprintf(stderr,"***Error: unsupported key type for wrapping key\n");
1264 rc = rc_error_unsupported;
1265 goto error;}
1266
1267 /* allocate BN */
1268 if ( (bn_wrappedkey_bytes = BN_new()) == NULL ) {
1269 P_ERR();
1270 goto error;
1271 }
1272
1273 if ( BN_set_word(bn_wrappedkey_bytes, keysizeinbytes) == 0) {
1274 P_ERR();
1275 goto error;
1276 }
1277 }
1278
1279
1280 /* now check that len(wrapped_key) < len(wrapping_key) - 11 */
1281 /* !! lengths being expressed in bytes */
1282
1283 if(! BN_add_word( bn_wrappedkey_bytes, 11L) ) {
1284 P_ERR();
1285 goto error;
1286 }
1287
1288 /* if bn_wrapped_key + 11 > bn_wrapping_key, then the wrapping key is too short. */
1289
1290 if( BN_cmp( bn_wrappedkey_bytes, bn_wrappingkey_bytes) > 0 ) {
1291 fprintf(stderr, "Error: wrapping key '%s' is too short to wrap key '%s'\n", wctx->wrappingkeylabel, wctx->wrappedkeylabel);
1292 rc = rc_error_wrapping_key_too_short;
1293 goto error;
1294 }
1295
1296
1297 /* we are good, let's allocate the memory and wrap */
1298 /* trick: we use now the CKA_MODULUS attribute to size the target buffer */
1299
1300 wctx->key[keyindex].wrapped_key_buffer = calloc ( o_modulus->ulValueLen, sizeof(unsigned char) );
1301
1302 if(wctx->key[keyindex].wrapped_key_buffer == NULL) {
1303 fprintf(stderr,"Error: memory\n");
1304 rc = rc_error_memory;
1305 goto error;
1306 }
1307
1308 wctx->key[keyindex].wrapped_key_len = o_modulus->ulValueLen;
1309
1310 /* now wrap */
1311
1312 {
1313 CK_RV rv;
1314 CK_MECHANISM mechanism = { CKM_RSA_PKCS, NULL_PTR, 0 };/* PKCS #1 1.5 wrap */
1315
1316 rv = wctx->p11Context->FunctionList.C_WrapKey ( wctx->p11Context->Session,
1317 &mechanism,
1318 wrappingkeyhandle,
1319 wrappedkeyhandle,
1320 wctx->key[keyindex].wrapped_key_buffer,
1321 &(wctx->key[keyindex].wrapped_key_len) );
1322
1323 if(rv!=CKR_OK) {
1324 pkcs11_error(rv, "C_WrapKey");
1325 rc = rc_error_pkcs11_api;
1326 goto error;
1327 }
1328 wctx->key[keyindex].wrappedkeyhandle = wrappedkeyhandle;
1329 wctx->key[keyindex].wrappedkeyobjclass = CKO_SECRET_KEY;
1330
1331 }
1332
1333 error:
1334 if(bn_wrappingkey_bytes != NULL) { BN_free(bn_wrappingkey_bytes); bn_wrappingkey_bytes=NULL; }
1335 if(bn_wrappedkey_bytes != NULL) { BN_free(bn_wrappedkey_bytes); bn_wrappedkey_bytes=NULL; }
1336 pkcs11_delete_attrlist(wrappingkey_attrs);
1337 pkcs11_delete_attrlist(wrappedkey_attrs);
1338
1339 return rc;
1340 }
1341
1342
1343
_wrap_cbcpad(wrappedKeyCtx * wctx)1344 static func_rc _wrap_cbcpad(wrappedKeyCtx *wctx)
1345 {
1346 func_rc rc = rc_ok;
1347
1348 CK_OBJECT_HANDLE wrappingkeyhandle=NULL_PTR;
1349 CK_OBJECT_HANDLE wrappedkeyhandle=NULL_PTR;
1350 key_type_t keytype;
1351 CK_OBJECT_CLASS wrappedkeyobjclass;
1352 int blocklength;
1353
1354 /* keyindex: in case of envelope wrapping, the index shall always be the outer */
1355 int keyindex = wctx->is_envelope ? WRAPPEDKEYCTX_INNER_KEY_INDEX : WRAPPEDKEYCTX_LONE_KEY_INDEX;
1356
1357 /* retrieve keys */
1358
1359 /* wrapping key is a secret key */
1360
1361 if(wctx->is_envelope) {
1362 /* if envelope encryption, keys have been already found by _wrap_envelope() */
1363 /* and wctx structure has been populated. */
1364 wrappedkeyhandle = wctx->key[keyindex].wrappedkeyhandle;
1365 wrappedkeyobjclass = wctx->key[keyindex].wrappedkeyobjclass;
1366 wrappingkeyhandle = wctx->key[keyindex].wrappingkeyhandle;
1367 } else {
1368 if (!pkcs11_findsecretkey(wctx->p11Context, wctx->wrappingkeylabel, &wrappingkeyhandle)) {
1369 fprintf(stderr, "***Error: could not find a secret key with label '%s'\n", wctx->wrappingkeylabel);
1370 rc = rc_error_object_not_found;
1371 goto error;
1372 }
1373
1374 /* if we called _wrap() with meth_keyhandle, then the wrappedkeylabel is NULL */
1375 /* and we can directly use the value in wrappedkeyhabndle */
1376 /* however we are still lacking the object class, so we retrieve it from the handle */
1377 if(wctx->wrappedkeylabel==NULL) {
1378 wrappedkeyhandle = wctx->key[keyindex].wrappedkeyhandle;
1379 wrappedkeyobjclass = pkcs11_get_object_class(wctx->p11Context, wrappedkeyhandle);
1380
1381 if(wrappedkeyobjclass != CKO_SECRET_KEY && wrappedkeyobjclass != CKO_PRIVATE_KEY) {
1382 rc = rc_error_oops;
1383 goto error;
1384 }
1385 } else {
1386 /* we have a label, just retrieve handle and object class from label */
1387 if(!pkcs11_findprivateorsecretkey(wctx->p11Context, wctx->wrappedkeylabel, &wrappedkeyhandle, &wrappedkeyobjclass)) {
1388 fprintf(stderr, "***Error: key with label '%s' does not exists\n", wctx->wrappedkeylabel);
1389 rc = rc_error_object_not_found;
1390 goto error;
1391 }
1392 }
1393 }
1394
1395 /* in case of private key, see if we have a match for a public key as well (valid only for token keys) */
1396 if(wrappedkeyobjclass==CKO_PRIVATE_KEY && wctx->wrappedkeylabel) {
1397 if(!pkcs11_findpublickey(wctx->p11Context, wctx->wrappedkeylabel, &wctx->pubkhandle)) {
1398 fprintf(stderr, "***Warning: private key with label '%s' found, but there is no associated public key found with the same label\n", wctx->wrappedkeylabel);
1399 }
1400 }
1401
1402 /* determining block size of the block cipher. */
1403 /* retrieve length of wrapping key */
1404 keytype = pkcs11_get_key_type(wctx->p11Context, wrappingkeyhandle);
1405
1406 switch(keytype) {
1407 case aes:
1408 blocklength=16;
1409 break;
1410
1411 case des:
1412 case des2:
1413 case des3:
1414 blocklength=8;
1415 break;
1416
1417 default:
1418 fprintf(stderr,"***Error: unsupported key type for wrapping key\n");
1419 rc = rc_error_unsupported;
1420 goto error;
1421 }
1422
1423 /* check length of iv */
1424
1425 if(wctx->aes_params.iv_len==0) {
1426 /* special case: no IV was given - We do one of our own */
1427 wctx->aes_params.iv=malloc(blocklength);
1428 if(wctx->aes_params.iv==NULL) {
1429 fprintf(stderr,"***Error: memory allocation\n");
1430 rc = rc_error_memory;
1431 goto error;
1432 }
1433 wctx->aes_params.iv_len = blocklength;
1434
1435 /* randomize it */
1436 pkcs11_getrandombytes(wctx->p11Context, wctx->aes_params.iv,blocklength);
1437
1438 } else {
1439 if(wctx->aes_params.iv_len != blocklength) {
1440 fprintf(stderr, "***Error: IV vector length(%d) mismatch - %d bytes are required\n", (int)(wctx->aes_params.iv_len), (int)blocklength);
1441 rc = rc_error_invalid_parameter_for_method;
1442 goto error;
1443 }
1444 }
1445
1446 /* now wrap */
1447
1448 {
1449 CK_RV rv;
1450 CK_MECHANISM mechanism = { 0L, wctx->aes_params.iv, wctx->aes_params.iv_len };
1451 CK_ULONG wrappedkeybuffersize;
1452
1453 switch(keytype) {
1454 case aes:
1455 mechanism.mechanism = CKM_AES_CBC_PAD;
1456 break;
1457
1458 case des:
1459 mechanism.mechanism = CKM_DES_CBC_PAD;
1460 break;
1461
1462 case des2: /* DES2 and DES3 both use the same mechanism */
1463 case des3:
1464 mechanism.mechanism = CKM_DES3_CBC_PAD;
1465 break;
1466
1467 default:
1468 fprintf(stderr,"***Error: unsupported key type for wrapping key\n");
1469 rc = rc_error_unsupported;
1470 goto error;
1471 }
1472
1473 /* first call to know what will be the size output buffer */
1474 rv = wctx->p11Context->FunctionList.C_WrapKey ( wctx->p11Context->Session,
1475 &mechanism,
1476 wrappingkeyhandle,
1477 wrappedkeyhandle,
1478 NULL,
1479 &wrappedkeybuffersize );
1480
1481 if(rv!=CKR_OK) {
1482 pkcs11_error(rv, "C_WrapKey");
1483 rc = rc_error_pkcs11_api;
1484 goto error;
1485 }
1486
1487 wctx->key[keyindex].wrapped_key_buffer = malloc( wrappedkeybuffersize );
1488 if(wctx->key[keyindex].wrapped_key_buffer==NULL) {
1489 fprintf(stderr,"***Error: memory allocation\n");
1490 rc = rc_error_memory;
1491 goto error;
1492 }
1493 wctx->key[keyindex].wrapped_key_len = wrappedkeybuffersize;
1494
1495 /* now we can do the real call, with the real buffer */
1496 rv = wctx->p11Context->FunctionList.C_WrapKey ( wctx->p11Context->Session,
1497 &mechanism,
1498 wrappingkeyhandle,
1499 wrappedkeyhandle,
1500 wctx->key[keyindex].wrapped_key_buffer,
1501 &(wctx->key[keyindex].wrapped_key_len) );
1502
1503
1504 if(rv!=CKR_OK) {
1505 pkcs11_error(rv, "C_WrapKey");
1506 rc = rc_error_pkcs11_api;
1507 goto error;
1508 }
1509
1510 wctx->key[keyindex].wrappedkeyobjclass = wrappedkeyobjclass;
1511 wctx->key[keyindex].wrappedkeyhandle = wrappedkeyhandle;
1512 }
1513
1514 error:
1515
1516 return rc;
1517 }
1518
1519
1520
1521 /*------------------------------------------------------------------------*/
1522 /* wrap a key using CKM_AES_KEY_WRAP or equivalent mechanism */
1523 /*------------------------------------------------------------------------*/
1524
_wrap_aes_key_wrap_mech(wrappedKeyCtx * wctx,CK_MECHANISM_TYPE mech[],CK_ULONG mech_size)1525 static func_rc _wrap_aes_key_wrap_mech(wrappedKeyCtx *wctx, CK_MECHANISM_TYPE mech[], CK_ULONG mech_size)
1526 {
1527 func_rc rc = rc_ok;
1528
1529 CK_OBJECT_HANDLE wrappingkeyhandle=0;
1530 CK_OBJECT_HANDLE wrappedkeyhandle=0;
1531 CK_OBJECT_CLASS wrappedkeyobjclass;
1532 key_type_t keytype;
1533
1534 /* keyindex: in case of envelope wrapping, the index shall always be the outer */
1535 int keyindex = wctx->is_envelope ? WRAPPEDKEYCTX_INNER_KEY_INDEX : WRAPPEDKEYCTX_LONE_KEY_INDEX;
1536
1537 /* sanity check */
1538 if(wctx==NULL) {
1539 fprintf(stderr, "***Error: invalid argument to _wrap_aes_key_wrap_mech()\n");
1540 rc =rc_error_invalid_parameter_for_method;
1541 goto error;
1542 }
1543
1544 if(mech_size==0 || mech_size>AES_WRAP_MECH_SIZE_MAX) {
1545 fprintf(stderr, "***Error: invalid wrapping mechanism table size\n");
1546 rc = rc_error_invalid_parameter_for_method;
1547 goto error;
1548 }
1549
1550 /* retrieve keys */
1551
1552 /* wrapping key is a secret key */
1553
1554 if(wctx->is_envelope) {
1555 /* if envelope encryption, keys have been already found by _wrap_envelope() */
1556 /* and wctx structure has been populated. */
1557 wrappedkeyhandle = wctx->key[keyindex].wrappedkeyhandle;
1558 wrappedkeyobjclass = wctx->key[keyindex].wrappedkeyobjclass;
1559 wrappingkeyhandle = wctx->key[keyindex].wrappingkeyhandle;
1560 } else {
1561 if (!pkcs11_findsecretkey(wctx->p11Context, wctx->wrappingkeylabel, &wrappingkeyhandle)) {
1562 fprintf(stderr,"***Error: could not find a secret key with label '%s'\n", wctx->wrappingkeylabel);
1563 rc = rc_error_object_not_found;
1564 goto error;
1565 }
1566
1567 /* if we called _wrap() with meth_keyhandle, then the wrappedkeylabel is NULL */
1568 /* and we can directly use the value in wrappedkeyhabndle */
1569 /* however we are still lacking the object class, so we retrieve it from the handle */
1570 if(wctx->wrappedkeylabel==NULL) {
1571 wrappedkeyhandle = wctx->key[keyindex].wrappedkeyhandle;
1572 wrappedkeyobjclass = pkcs11_get_object_class(wctx->p11Context, wrappedkeyhandle);
1573
1574 if(wrappedkeyobjclass != CKO_SECRET_KEY && wrappedkeyobjclass != CKO_PRIVATE_KEY) {
1575 rc = rc_error_oops;
1576 goto error;
1577 }
1578 } else {
1579 /* we have a label, just retrieve handle and object class from label */
1580 if(!pkcs11_findprivateorsecretkey(wctx->p11Context, wctx->wrappedkeylabel, &wrappedkeyhandle, &wrappedkeyobjclass)) {
1581 fprintf(stderr, "***Error: key with label '%s' does not exists\n", wctx->wrappedkeylabel);
1582 rc = rc_error_object_not_found;
1583 goto error;
1584 }
1585 }
1586 }
1587
1588 /* in case of private key, see if we have a match for a public key as well (valid only for token keys) */
1589 if(wrappedkeyobjclass==CKO_PRIVATE_KEY && wctx->wrappedkeylabel) {
1590 if(!pkcs11_findpublickey(wctx->p11Context, wctx->wrappedkeylabel, &wctx->pubkhandle)) {
1591 fprintf(stderr, "***Warning: private key with label '%s' found, but there is no associated public key found with the same label\n", wctx->wrappedkeylabel);
1592 }
1593 }
1594
1595 /* determining block size of the block cipher. */
1596 /* retrieve length of wrapping key */
1597 keytype = pkcs11_get_key_type(wctx->p11Context, wrappingkeyhandle);
1598
1599 if(keytype != aes ) {
1600 fprintf(stderr, "Error: secret key with label '%s' is not an AES key\n", wctx->wrappingkeylabel);
1601 rc = rc_error_wrong_key_type;
1602 goto error;
1603
1604 }
1605
1606 /* now wrap */
1607
1608 {
1609 CK_RV rv;
1610 CK_MECHANISM mechanism = { 0L, wctx->aes_params.iv, wctx->aes_params.iv_len };
1611 CK_ULONG wrappedkeybuffersize;
1612 CK_ULONG i;
1613
1614 /* first call to know what will be the size output buffer */
1615 for(i=0;i< mech_size; i++) {
1616 /* let's try mechanisms one by one, unless the mechanism is already supplied */
1617 /* i.e. if wctx->aes_wrapping_mech != 0 */
1618 mechanism.mechanism = wctx->aes_params.aes_wrapping_mech != 0 ? wctx->aes_params.aes_wrapping_mech : mech[i];
1619 rv = wctx->p11Context->FunctionList.C_WrapKey ( wctx->p11Context->Session,
1620 &mechanism,
1621 wrappingkeyhandle,
1622 wrappedkeyhandle,
1623 NULL,
1624 &wrappedkeybuffersize );
1625 if(rv!=CKR_OK) {
1626 pkcs11_error(rv, "C_WrapKey");
1627 fprintf(stderr, "***Warning: It didn't work with %s\n", pkcs11_get_mechanism_name_from_type(mechanism.mechanism));
1628 } else {
1629 /* it worked, let's remember in wctx the actual mechanism used */
1630 /* unless it was already supplied */
1631 if(wctx->aes_params.aes_wrapping_mech==0) {
1632 wctx->aes_params.aes_wrapping_mech = mech[i];
1633 }
1634 /* and escape loop */
1635 break;
1636 }
1637
1638 if(wctx->aes_params.aes_wrapping_mech != 0) {
1639 /* special case: if the wrapping mechanism was set by the parser */
1640 /* through option field, we will not try other mechanisms than the one */
1641 /* specified. */
1642 break;
1643 }
1644 }
1645
1646 if(rv!=CKR_OK) { /* we couldn't find a suitable mech */
1647 fprintf(stderr, "***Error: tried all mechanisms, no one worked\n");
1648 rc = rc_error_pkcs11_api;
1649 goto error;
1650 }
1651
1652 wctx->key[keyindex].wrapped_key_buffer = malloc( wrappedkeybuffersize );
1653 if(wctx->key[keyindex].wrapped_key_buffer==NULL) {
1654 fprintf(stderr,"***Error: memory allocation\n");
1655 rc = rc_error_memory;
1656 goto error;
1657 }
1658 wctx->key[keyindex].wrapped_key_len = wrappedkeybuffersize;
1659
1660 /* now we can do the real call, with the real buffer */
1661 rv = wctx->p11Context->FunctionList.C_WrapKey ( wctx->p11Context->Session,
1662 &mechanism,
1663 wrappingkeyhandle,
1664 wrappedkeyhandle,
1665 wctx->key[keyindex].wrapped_key_buffer,
1666 &(wctx->key[keyindex].wrapped_key_len) );
1667
1668
1669 if(rv!=CKR_OK) {
1670 pkcs11_error(rv, "C_WrapKey");
1671 rc = rc_error_pkcs11_api;
1672 goto error;
1673 }
1674
1675 wctx->key[keyindex].wrappedkeyobjclass = wrappedkeyobjclass;
1676 wctx->key[keyindex].wrappedkeyhandle = wrappedkeyhandle;
1677 }
1678
1679 error:
1680 return rc;
1681 }
1682
1683
1684 /*------------------------------------------------------------------------*/
_wrap_pkcs1_oaep(wrappedKeyCtx * wctx)1685 static func_rc _wrap_pkcs1_oaep(wrappedKeyCtx *wctx)
1686 {
1687 func_rc rc = rc_ok;
1688
1689 CK_OBJECT_HANDLE wrappingkeyhandle=NULL_PTR;
1690 CK_OBJECT_HANDLE wrappedkeyhandle=NULL_PTR;
1691 CK_OBJECT_CLASS wrappedkeyobjclass;
1692 pkcs11AttrList *wrappedkey_attrs = NULL, *wrappingkey_attrs = NULL;
1693 CK_ATTRIBUTE_PTR o_wrappedkey_bytes, o_modulus, o_keytype;
1694 BIGNUM *bn_wrappingkey_bytes = NULL;
1695 BIGNUM *bn_wrappedkey_bytes = NULL;
1696 int bytelen;
1697 int sizeoverhead;
1698 unsigned long keysizeinbytes;
1699
1700 /* keyindex: in case of envelope wrapping, the index shall always be the outer */
1701 int keyindex = wctx->is_envelope ? WRAPPEDKEYCTX_OUTER_KEY_INDEX : WRAPPEDKEYCTX_LONE_KEY_INDEX;
1702
1703 /* retrieve keys */
1704
1705 if(wctx->is_envelope) {
1706 /* if envelope encryption, keys have been already found by _wrap_envelope() */
1707 /* and wctx structure has been populated. */
1708 wrappedkeyhandle = wctx->key[keyindex].wrappedkeyhandle;
1709 wrappingkeyhandle = wctx->key[keyindex].wrappingkeyhandle;
1710 } else {
1711 if (!pkcs11_findpublickey(wctx->p11Context, wctx->wrappingkeylabel, &wrappingkeyhandle)) {
1712 fprintf(stderr,"Error: could not find a public key with label '%s'\n", wctx->wrappingkeylabel);
1713 rc = rc_error_object_not_found;
1714 goto error;
1715 }
1716
1717 /* if we called _wrap() with meth_keyhandle, then the wrappedkeylabel is NULL */
1718 /* and we can directly use the value in wrappedkeyhabndle */
1719 if(wctx->wrappedkeylabel==NULL) {
1720 wrappedkeyhandle = wctx->key[keyindex].wrappedkeyhandle;
1721 /* we need to retrieve the object class */
1722 wrappedkeyobjclass = pkcs11_get_object_class(wctx->p11Context, wrappedkeyhandle);
1723
1724 if(wrappedkeyobjclass != CKO_SECRET_KEY) {
1725 fprintf(stderr,"***Error: PKCS#1 OAEP wrapping algorithm can only wrap secret keys, not private keys\n");
1726 rc = rc_error_wrong_object_class;
1727 goto error;
1728 }
1729 } else {
1730 if(!pkcs11_findsecretkey(wctx->p11Context, wctx->wrappedkeylabel, &wrappedkeyhandle)) {
1731 fprintf(stderr,"Error: secret key with label '%s' does not exists\n", wctx->wrappedkeylabel);
1732 rc = rc_error_object_not_found;
1733 goto error;
1734 }
1735 }
1736 }
1737
1738 /* retrieve length of wrapping key */
1739 wrappingkey_attrs = pkcs11_new_attrlist(wctx->p11Context,
1740 _ATTR(CKA_MODULUS),
1741 _ATTR_END );
1742
1743 if( pkcs11_read_attr_from_handle (wrappingkey_attrs, wrappingkeyhandle) == false) {
1744 fprintf(stderr,"Error: could not read CKA_MODULUS_BITS attribute from public key with label '%s'\n", wctx->wrappingkeylabel);
1745 rc = rc_error_pkcs11_api;
1746 goto error;
1747 }
1748
1749 o_modulus = pkcs11_get_attr_in_attrlist(wrappingkey_attrs, CKA_MODULUS);
1750
1751 /* overwrite existing value */
1752 if ( (bn_wrappingkey_bytes = BN_bin2bn(o_modulus->pValue, o_modulus->ulValueLen, NULL)) == NULL ) {
1753 P_ERR();
1754 goto error;
1755 }
1756
1757 /* extract number of bytes */
1758 bytelen = BN_num_bytes(bn_wrappingkey_bytes);
1759
1760 /* and adjust value */
1761 BN_set_word(bn_wrappingkey_bytes, (unsigned long)bytelen);
1762
1763 /* retrieve length of wrapped key */
1764 wrappedkey_attrs = pkcs11_new_attrlist(wctx->p11Context,
1765 _ATTR(CKA_KEY_TYPE), /* needed as CKA_VALUE_LEN might not always be present */
1766 _ATTR(CKA_VALUE_LEN), /* caution: value in bytes */
1767 _ATTR_END );
1768
1769 if( pkcs11_read_attr_from_handle (wrappedkey_attrs, wrappedkeyhandle) == false) {
1770 fprintf(stderr,"Error: could not read attributes from secret key with label '%s'\n", wctx->wrappedkeylabel);
1771 rc = rc_error_pkcs11_api;
1772 goto error;
1773 }
1774
1775 o_wrappedkey_bytes = pkcs11_get_attr_in_attrlist(wrappedkey_attrs, CKA_VALUE_LEN);
1776 /* pkcs11_get_attr_in_attrlist returns the attribute, but we need to check */
1777 /* if there is actually a value attached to it */
1778
1779 if(o_wrappedkey_bytes && o_wrappedkey_bytes->pValue) {
1780
1781
1782 /* BN_bin2bn works only with big endian, so we must alter data */
1783 /* if architecture is LE */
1784
1785 *((CK_ULONG *)o_wrappedkey_bytes->pValue) = pkcs11_ll_bigendian_ul( *((CK_ULONG *)(o_wrappedkey_bytes->pValue))); /* transform if required */
1786
1787 if ( (bn_wrappedkey_bytes = BN_bin2bn( o_wrappedkey_bytes->pValue, o_wrappedkey_bytes->ulValueLen, NULL) ) == NULL ) {
1788 P_ERR();
1789 goto error;
1790 }
1791 } else { /* can be the case for CKK_DES, CKK_DES2 and CKK_DES3 family */
1792 /* as these keys have no CKA_VALUE_LEN attribute */
1793
1794 o_keytype = pkcs11_get_attr_in_attrlist(wrappedkey_attrs, CKA_KEY_TYPE);
1795
1796 switch(*(CK_KEY_TYPE *)(o_keytype->pValue)) {
1797 case CKK_DES:
1798 keysizeinbytes=8;
1799 break;
1800
1801 case CKK_DES2:
1802 keysizeinbytes=16;
1803 break;
1804
1805 case CKK_DES3:
1806 keysizeinbytes=24;
1807 break;
1808
1809 default:
1810 fprintf(stderr,"***Error: unsupported key type for wrapping key\n");
1811 rc = rc_error_unsupported;
1812 goto error;}
1813
1814 /* allocate BN */
1815 if ( (bn_wrappedkey_bytes = BN_new()) == NULL ) {
1816 P_ERR();
1817 goto error;
1818 }
1819
1820 if ( BN_set_word(bn_wrappedkey_bytes, keysizeinbytes) == 0) {
1821 P_ERR();
1822 goto error;
1823 }
1824 }
1825
1826 /* now check that len(wrapped_key) < len(wrapping_key) - 2 - 2 * hlen */
1827 /* !! lengths being expressed in bytes */
1828 /* in this version, Hash Algorithm set to SHA-1 and hardcoded */
1829
1830 /* when SHA1, hlen=20, 2 * hlen + 2 = 42 */
1831 /* when SHA256, hlen=32, 2 * hlen + 2 = 66 */
1832 /* when SHA384, hlen=48, 2 * hlen + 2 = 98 */
1833 /* when SHA512, hlen=64, 2 * hlen + 2 = 130 */
1834
1835 switch(wctx->oaep_params->hashAlg) {
1836 case CKM_SHA_1:
1837 sizeoverhead=42;
1838 break;
1839
1840 case CKM_SHA256:
1841 sizeoverhead=66;
1842 break;
1843
1844 case CKM_SHA384:
1845 sizeoverhead=98;
1846 break;
1847
1848 case CKM_SHA512:
1849 sizeoverhead=130;
1850 break;
1851
1852 default:
1853 fprintf(stderr,"***Error: unsupported hashing algorithm for OAEP wrapping\n");
1854 rc = rc_error_unsupported;
1855 goto error;
1856 }
1857
1858
1859 if(! BN_add_word( bn_wrappedkey_bytes, sizeoverhead) ) {
1860 P_ERR();
1861 goto error;
1862 }
1863
1864 /* if bn_wrapped_key + sizeoverhead > bn_wrapping_key, then the wrapping key is too short. */
1865
1866 if( BN_cmp( bn_wrappedkey_bytes, bn_wrappingkey_bytes) > 0 ) {
1867 fprintf(stderr, "Error: wrapping key '%s' is too short to wrap key '%s'\n", wctx->wrappingkeylabel, wctx->wrappedkeylabel);
1868 rc = rc_error_wrapping_key_too_short;
1869 goto error;
1870 }
1871
1872
1873 /* we are good, let's allocate the memory and wrap */
1874 /* trick: we use now the CKA_MODULUS attribute to size the target buffer */
1875
1876 wctx->key[keyindex].wrapped_key_buffer = calloc ( o_modulus->ulValueLen, sizeof(unsigned char) );
1877
1878 if(wctx->key[keyindex].wrapped_key_buffer == NULL) {
1879 fprintf(stderr,"Error: memory\n");
1880 rc = rc_error_memory;
1881 goto error;
1882 }
1883
1884 wctx->key[keyindex].wrapped_key_len = o_modulus->ulValueLen;
1885
1886 /* now wrap */
1887
1888 {
1889 CK_RV rv;
1890 CK_MECHANISM mechanism = { CKM_RSA_PKCS_OAEP, wctx->oaep_params, sizeof(CK_RSA_PKCS_OAEP_PARAMS) };/* PKCS #1 OAEP wrap */
1891
1892 rv = wctx->p11Context->FunctionList.C_WrapKey ( wctx->p11Context->Session,
1893 &mechanism,
1894 wrappingkeyhandle,
1895 wrappedkeyhandle,
1896 wctx->key[keyindex].wrapped_key_buffer,
1897 &(wctx->key[keyindex].wrapped_key_len) );
1898
1899 if(rv!=CKR_OK) {
1900 pkcs11_error(rv, "C_WrapKey");
1901 rc = rc_error_pkcs11_api;
1902 goto error;
1903 }
1904
1905 wctx->key[keyindex].wrappedkeyhandle = wrappedkeyhandle; /* keep a copy, for the output */
1906 wctx->key[keyindex].wrappedkeyobjclass = CKO_SECRET_KEY; /* same story */
1907 }
1908
1909 error:
1910 if(bn_wrappingkey_bytes != NULL) { BN_free(bn_wrappingkey_bytes); bn_wrappingkey_bytes=NULL; }
1911 if(bn_wrappedkey_bytes != NULL) { BN_free(bn_wrappedkey_bytes); bn_wrappedkey_bytes=NULL; }
1912 pkcs11_delete_attrlist(wrappingkey_attrs);
1913 pkcs11_delete_attrlist(wrappedkey_attrs);
1914
1915 return rc;
1916 }
1917
1918
1919 /*------------------------------------------------------------------------*/
_wrap_envelope(wrappedKeyCtx * wctx)1920 static func_rc _wrap_envelope(wrappedKeyCtx *wctx)
1921 {
1922 func_rc rc = rc_ok;
1923 CK_OBJECT_HANDLE wrappingkeyhandle=NULL_PTR;
1924 CK_OBJECT_HANDLE wrappedkeyhandle=NULL_PTR;
1925 CK_OBJECT_CLASS wrappedkeyobjclass;
1926 CK_OBJECT_HANDLE tempaes_handle=0;
1927 CK_BBOOL ck_true = CK_TRUE;
1928
1929 CK_ATTRIBUTE tempaes_attrs[] = {
1930 { CKA_WRAP, &ck_true, sizeof(ck_true) },
1931 { CKA_EXTRACTABLE, &ck_true, sizeof(ck_true) }
1932 };
1933
1934 char tempaes_label[32];
1935
1936 if (!pkcs11_findpublickey(wctx->p11Context, wctx->wrappingkeylabel, &wrappingkeyhandle)) {
1937 fprintf(stderr,"Error: could not find a public key with label '%s'\n", wctx->wrappingkeylabel);
1938 rc = rc_error_object_not_found;
1939 goto error;
1940 }
1941
1942 /* if we called _wrap() with meth_keyhandle, then the wrappedkeylabel is NULL */
1943 /* and we can directly use the value in wrappedkeyhabndle */
1944 /* however we are still lacking the object class, so we retrieve it from the handle */
1945 if(wctx->wrappedkeylabel==NULL) {
1946 wrappedkeyhandle = wctx->key[WRAPPEDKEYCTX_INNER_KEY_INDEX].wrappedkeyhandle;
1947
1948 /* extract object class from provided handle */
1949 wrappedkeyobjclass = pkcs11_get_object_class(wctx->p11Context, wrappedkeyhandle);
1950
1951 if(wrappedkeyobjclass != CKO_SECRET_KEY && wrappedkeyobjclass != CKO_PRIVATE_KEY) {
1952 rc = rc_error_oops;
1953 goto error;
1954 }
1955 } else {
1956 /* we have a label, just retrieve handle and object class from label */
1957 if(!pkcs11_findprivateorsecretkey(wctx->p11Context, wctx->wrappedkeylabel, &wrappedkeyhandle, &wrappedkeyobjclass)) {
1958 fprintf(stderr, "***Error: key with label '%s' does not exists\n", wctx->wrappedkeylabel);
1959 rc = rc_error_object_not_found;
1960 goto error;
1961 }
1962 }
1963
1964 /* step 1: setup wctx structure to remember the key handles */
1965 wctx->key[WRAPPEDKEYCTX_OUTER_KEY_INDEX].wrappingkeyhandle = wrappingkeyhandle;
1966 wctx->key[WRAPPEDKEYCTX_INNER_KEY_INDEX].wrappedkeyhandle = wrappedkeyhandle;
1967 wctx->key[WRAPPEDKEYCTX_INNER_KEY_INDEX].wrappedkeyobjclass = wrappedkeyobjclass;
1968
1969 /* step 2: generate the intermediate temporary key */
1970 /* will be an AES for now */
1971
1972 snprintf((char *)tempaes_label, sizeof tempaes_label, "tempaes-%ld", time(NULL));
1973
1974 /* TODO - adapt to support other symmetric types - detect on wrapping alg */
1975 rc = pkcs11_genAES(wctx->p11Context,
1976 tempaes_label,
1977 256,
1978 tempaes_attrs,
1979 sizeof tempaes_attrs / sizeof(CK_ATTRIBUTE),
1980 &tempaes_handle,
1981 kg_session_for_wrapping);
1982
1983 if(rc != rc_ok ) {
1984 fprintf(stderr, "Unable to generate temporary wrapping key\n");
1985 goto error;
1986 }
1987
1988 /* step 3: remember our temporary key in wctx structure */
1989 wctx->key[WRAPPEDKEYCTX_OUTER_KEY_INDEX].wrappedkeyhandle = tempaes_handle;
1990 wctx->key[WRAPPEDKEYCTX_OUTER_KEY_INDEX].wrappedkeyobjclass = CKO_SECRET_KEY;
1991 wctx->key[WRAPPEDKEYCTX_INNER_KEY_INDEX].wrappingkeyhandle = tempaes_handle;
1992
1993 /* step 4: wrap the inner key */
1994 switch(wctx->key[WRAPPEDKEYCTX_INNER_KEY_INDEX].wrapping_meth) {
1995 case w_cbcpad:
1996 rc = _wrap_cbcpad(wctx);
1997 break;
1998
1999 case w_rfc3394:
2000 rc = _wrap_rfc3394(wctx);
2001 break;
2002
2003 case w_rfc5649:
2004 rc = _wrap_rfc5649(wctx);
2005 break;
2006
2007 default:
2008 rc = rc_error_oops;
2009 }
2010
2011 if(rc!=rc_ok) {
2012 goto error;
2013 }
2014
2015 /* step 5: wrap the outer key */
2016 switch(wctx->key[WRAPPEDKEYCTX_OUTER_KEY_INDEX].wrapping_meth) {
2017 case w_pkcs1_15:
2018 rc = _wrap_pkcs1_15(wctx);
2019 break;
2020
2021 case w_pkcs1_oaep:
2022 rc = _wrap_pkcs1_oaep(wctx);
2023 break;
2024
2025 default:
2026 rc = rc_error_oops;
2027 }
2028
2029 if(rc!=rc_ok) {
2030 goto error;
2031 }
2032
2033 error:
2034 if(tempaes_handle!=0) {
2035 CK_RV rv = wctx->p11Context->FunctionList.C_DestroyObject(wctx->p11Context->Session, tempaes_handle);
2036 if(rv != CKR_OK) {
2037 pkcs11_error( rv, "C_DestroyObject" );
2038 }
2039 }
2040 return rc;
2041
2042 }
2043
2044
2045 /*--------------------------------------------------------------------------------*/
2046 /* PUBLIC INTERFACE */
2047 /*--------------------------------------------------------------------------------*/
pkcs11_prepare_wrappingctx(wrappedKeyCtx * wctx,char * wrapjob)2048 func_rc pkcs11_prepare_wrappingctx(wrappedKeyCtx *wctx, char *wrapjob)
2049 {
2050
2051 func_rc rc=rc_ok;
2052
2053 if(wctx!=NULL && wrapjob!=NULL) {
2054 int parserc;
2055
2056 /* http://stackoverflow.com/questions/1907847/how-to-use-yy-scan-string-in-lex */
2057 /* copy string into new buffer and Switch buffers*/
2058 YY_BUFFER_STATE yybufstate = yy_scan_string(wrapjob);
2059
2060 /* parse string */
2061 parserc = yyparse(wctx);
2062
2063 if(parserc!=0) {
2064 fprintf(stderr, "***Error scanning wrapping job string '%s'\n", wrapjob);
2065 rc =rc_error_invalid_argument;
2066 }
2067
2068 /*Delete the new buffer*/
2069 yy_delete_buffer(yybufstate);
2070 } else {
2071 rc = rc_error_invalid_parameter_for_method;
2072 }
2073
2074 return rc;
2075 }
2076
_wrap(wrappedKeyCtx * wctx,wrap_source_method_t wrap_source_method,char * wrappedkeylabel,CK_OBJECT_HANDLE wrappedkeyhandle,CK_OBJECT_HANDLE pubkhandle)2077 static func_rc _wrap(wrappedKeyCtx *wctx,
2078 wrap_source_method_t wrap_source_method,
2079 char *wrappedkeylabel,
2080 CK_OBJECT_HANDLE wrappedkeyhandle,
2081 CK_OBJECT_HANDLE pubkhandle )
2082 {
2083 func_rc rc = rc_ok;
2084
2085 /* keyindex: in case of envelope wrapping, the index shall always be the outer */
2086 int keyindex = wctx->is_envelope ? WRAPPEDKEYCTX_INNER_KEY_INDEX : WRAPPEDKEYCTX_LONE_KEY_INDEX;
2087
2088 switch(wrap_source_method) {
2089 case meth_label:
2090 wctx->wrappedkeylabel = strdup(wrappedkeylabel);
2091 wctx->key[keyindex].wrappedkeyhandle = 0;
2092 break;
2093
2094 case meth_keyhandle:
2095 wctx->wrappedkeylabel = NULL;
2096 wctx->key[keyindex].wrappedkeyhandle = wrappedkeyhandle;
2097 wctx->pubkhandle = pubkhandle;
2098 break;
2099 }
2100
2101 if(wctx->is_envelope) {
2102 /* envelope wrapping */
2103 rc = _wrap_envelope(wctx);
2104 } else {
2105 switch(wctx->key[keyindex].wrapping_meth) {
2106 case w_pkcs1_15:
2107 /* TODO: check if I can wrap */
2108 rc = _wrap_pkcs1_15(wctx);
2109 break;
2110
2111 case w_pkcs1_oaep:
2112 /* TODO: check if I can wrap */
2113 rc = _wrap_pkcs1_oaep(wctx);
2114 break;
2115
2116 case w_cbcpad:
2117 rc = _wrap_cbcpad(wctx);
2118 break;
2119
2120 case w_rfc3394:
2121 rc = _wrap_rfc3394(wctx);
2122 break;
2123
2124 case w_rfc5649:
2125 rc = _wrap_rfc5649(wctx);
2126 break;
2127
2128 default:
2129 rc = rc_error_unknown_wrapping_alg;
2130 fprintf(stderr, "Error: unsupported wrapping algorithm.\n");
2131 }
2132 }
2133
2134 return rc;
2135 }
2136
2137
pkcs11_output_wrapped_key(wrappedKeyCtx * wctx)2138 func_rc pkcs11_output_wrapped_key(wrappedKeyCtx *wctx)
2139 {
2140 func_rc rc = rc_ok;
2141 FILE *fp=stdout;
2142
2143 if(wctx->filename) {
2144 fp = fopen(wctx->filename, "w");
2145 if(fp==NULL) {
2146 perror("***Warning: cannot write to file - will output to standard output");
2147 fp=stdout;
2148 }
2149 }
2150
2151 rc = _output_wrapped_key_header(wctx,fp);
2152 if(rc!=rc_ok) {
2153 fprintf(stderr, "***Error: during wrapped key header creation\n");
2154 goto error;
2155 }
2156
2157 rc = _output_wrapped_key_attributes(wctx,fp);
2158 if(rc!=rc_ok) {
2159 fprintf(stderr, "***Error: when outputing wrapped key attributes\n");
2160 goto error;
2161 }
2162
2163 rc = _output_wrapped_keys_b64(wctx,fp);
2164 if(rc!=rc_ok) {
2165 fprintf(stderr, "***Error: when outputing wrapped key\n");
2166 goto error;
2167 }
2168
2169 /* do we have a handle to a public key? if so, output it as well */
2170 if(wctx->pubkhandle) {
2171 rc = _output_public_key_attributes(wctx,fp);
2172 if(rc!=rc_ok) {
2173 fprintf(stderr, "***Error: when outputing public key attributes\n");
2174 goto error;
2175 }
2176
2177 rc = _output_public_key_b64(wctx,fp);
2178 if(rc!=rc_ok) {
2179 fprintf(stderr, "***Error: when outputing public key\n");
2180 goto error;
2181 }
2182 }
2183
2184 error:
2185 if(fp && fp!=stdout) {
2186 fclose(fp);
2187 }
2188 return rc;
2189 }
2190
2191
2192
2193