1 /*
2 * Copyright (C) 2012, Redhat Inc.
3 * Copyright (c) 2011, Collabora Ltd.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above
10 * copyright notice, this list of conditions and the
11 * following disclaimer.
12 * * Redistributions in binary form must reproduce the
13 * above copyright notice, this list of conditions and
14 * the following disclaimer in the documentation and/or
15 * other materials provided with the distribution.
16 * * The names of contributors to this software may not be
17 * used to endorse or promote products derived from this
18 * software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 * DAMAGE.
32 *
33 * Author: Stef Walter <stefw@collabora.co.uk>
34 */
35
36 #include "config.h"
37
38 #include "attrs.h"
39 #include "buffer.h"
40 #include "compat.h"
41 #include "constants.h"
42 #include "debug.h"
43 #include "hash.h"
44 #include "pkcs11.h"
45 #include "pkcs11i.h"
46 #include "pkcs11x.h"
47
48 #include <assert.h>
49 #include <stdarg.h>
50 #include <stdio.h>
51 #include <stdint.h>
52 #include <stdlib.h>
53 #include <string.h>
54
55 #define ELEMS(x) (sizeof (x) / sizeof (x[0]))
56
57 bool
p11_attrs_terminator(const CK_ATTRIBUTE * attrs)58 p11_attrs_terminator (const CK_ATTRIBUTE *attrs)
59 {
60 return (attrs == NULL || attrs->type == CKA_INVALID);
61 }
62
63 CK_ULONG
p11_attrs_count(const CK_ATTRIBUTE * attrs)64 p11_attrs_count (const CK_ATTRIBUTE *attrs)
65 {
66 CK_ULONG count;
67
68 if (attrs == NULL)
69 return 0UL;
70
71 for (count = 0; !p11_attrs_terminator (attrs); count++, attrs++);
72
73 return count;
74 }
75
76 void
p11_attrs_free(void * attrs)77 p11_attrs_free (void *attrs)
78 {
79 CK_ATTRIBUTE *ats = attrs;
80 int i;
81
82 if (!attrs)
83 return;
84
85 for (i = 0; !p11_attrs_terminator (ats + i); i++)
86 free (ats[i].pValue);
87 free (ats);
88 }
89
90 static CK_ATTRIBUTE *
attrs_build(CK_ATTRIBUTE * attrs,CK_ULONG count_to_add,bool take_values,bool override,CK_ATTRIBUTE * (* generator)(void *),void * state)91 attrs_build (CK_ATTRIBUTE *attrs,
92 CK_ULONG count_to_add,
93 bool take_values,
94 bool override,
95 CK_ATTRIBUTE * (*generator) (void *),
96 void *state)
97 {
98 CK_ATTRIBUTE *attr;
99 CK_ATTRIBUTE *add;
100 CK_ULONG current;
101 CK_ULONG at;
102 CK_ULONG j;
103 CK_ULONG i;
104 size_t length;
105 void *new_memory;
106
107 /* How many attributes we already have */
108 current = p11_attrs_count (attrs);
109
110 /* Reallocate for how many we need */
111 length = current + count_to_add;
112 return_val_if_fail (current <= length && length < SIZE_MAX, NULL);
113 new_memory = reallocarray (attrs, length + 1, sizeof (CK_ATTRIBUTE));
114 return_val_if_fail (new_memory != NULL, NULL);
115 attrs = new_memory;
116
117 at = current;
118 for (i = 0; i < count_to_add; i++) {
119 add = (generator) (state);
120
121 /* Skip with invalid type */
122 if (!add || add->type == CKA_INVALID)
123 continue;
124
125 attr = NULL;
126
127 /* Do we have this attribute? */
128 for (j = 0; attr == NULL && j < current; j++) {
129 if (attrs[j].type == add->type) {
130 attr = attrs + j;
131 break;
132 }
133 }
134
135 /* The attribute doesn't exist */
136 if (attr == NULL) {
137 attr = attrs + at;
138 at++;
139
140 /* The attribute exists and we're not overriding */
141 } else if (!override) {
142 if (take_values)
143 free (add->pValue);
144 continue;
145
146 /* The attribute exitss, and we're overriding */
147 } else {
148 free (attr->pValue);
149 }
150
151 memcpy (attr, add, sizeof (CK_ATTRIBUTE));
152 if (!take_values && attr->pValue != NULL) {
153 if (attr->ulValueLen == 0)
154 attr->pValue = malloc (1);
155 else
156 attr->pValue = memdup (attr->pValue, attr->ulValueLen);
157 return_val_if_fail (attr->pValue != NULL, NULL);
158 }
159 }
160
161 /* Mark this as the end */
162 (attrs + at)->type = CKA_INVALID;
163 assert (p11_attrs_terminator (attrs + at));
164 return attrs;
165 }
166
167 static CK_ATTRIBUTE *
vararg_generator(void * state)168 vararg_generator (void *state)
169 {
170 va_list *va = state;
171 return va_arg (*va, CK_ATTRIBUTE *);
172 }
173
174 CK_ATTRIBUTE *
p11_attrs_build(CK_ATTRIBUTE * attrs,...)175 p11_attrs_build (CK_ATTRIBUTE *attrs,
176 ...)
177 {
178 CK_ULONG count;
179 va_list va;
180
181 count = 0UL;
182 va_start (va, attrs);
183 while (va_arg (va, CK_ATTRIBUTE *))
184 count++;
185 va_end (va);
186
187 va_start (va, attrs);
188 attrs = attrs_build (attrs, count, false, true,
189 vararg_generator, &va);
190 va_end (va);
191
192 return attrs;
193 }
194
195 static CK_ATTRIBUTE *
template_generator(void * state)196 template_generator (void *state)
197 {
198 CK_ATTRIBUTE **template = state;
199 return (*template)++;
200 }
201
202 CK_ATTRIBUTE *
p11_attrs_buildn(CK_ATTRIBUTE * attrs,const CK_ATTRIBUTE * add,CK_ULONG count)203 p11_attrs_buildn (CK_ATTRIBUTE *attrs,
204 const CK_ATTRIBUTE *add,
205 CK_ULONG count)
206 {
207 return attrs_build (attrs, count, false, true,
208 template_generator, &add);
209 }
210
211 CK_ATTRIBUTE *
p11_attrs_take(CK_ATTRIBUTE * attrs,CK_ATTRIBUTE_TYPE type,CK_VOID_PTR value,CK_ULONG length)212 p11_attrs_take (CK_ATTRIBUTE *attrs,
213 CK_ATTRIBUTE_TYPE type,
214 CK_VOID_PTR value,
215 CK_ULONG length)
216 {
217 CK_ATTRIBUTE attr = { type, value, length };
218 CK_ATTRIBUTE *add = &attr;
219 return attrs_build (attrs, 1, true, true,
220 template_generator, &add);
221 }
222
223 CK_ATTRIBUTE *
p11_attrs_merge(CK_ATTRIBUTE * attrs,CK_ATTRIBUTE * merge,bool replace)224 p11_attrs_merge (CK_ATTRIBUTE *attrs,
225 CK_ATTRIBUTE *merge,
226 bool replace)
227 {
228 CK_ATTRIBUTE *ptr;
229 CK_ULONG count;
230
231 if (attrs == NULL)
232 return merge;
233
234 ptr = merge;
235 count = p11_attrs_count (merge);
236
237 attrs = attrs_build (attrs, count, true, replace,
238 template_generator, &ptr);
239
240 /*
241 * Since we're supposed to own the merge attributes,
242 * free the container array.
243 */
244 free (merge);
245
246 return attrs;
247 }
248
249 CK_ATTRIBUTE *
p11_attrs_dup(const CK_ATTRIBUTE * attrs)250 p11_attrs_dup (const CK_ATTRIBUTE *attrs)
251 {
252 CK_ULONG count;
253
254 count = p11_attrs_count (attrs);
255 return p11_attrs_buildn (NULL, attrs, count);
256 }
257
258 CK_ATTRIBUTE *
p11_attrs_find(CK_ATTRIBUTE * attrs,CK_ATTRIBUTE_TYPE type)259 p11_attrs_find (CK_ATTRIBUTE *attrs,
260 CK_ATTRIBUTE_TYPE type)
261 {
262 CK_ULONG i;
263
264 for (i = 0; !p11_attrs_terminator (attrs + i); i++) {
265 if (attrs[i].type == type)
266 return attrs + i;
267 }
268
269 return NULL;
270 }
271
272 CK_ATTRIBUTE *
p11_attrs_findn(CK_ATTRIBUTE * attrs,CK_ULONG count,CK_ATTRIBUTE_TYPE type)273 p11_attrs_findn (CK_ATTRIBUTE *attrs,
274 CK_ULONG count,
275 CK_ATTRIBUTE_TYPE type)
276 {
277 CK_ULONG i;
278
279 for (i = 0; i < count; i++) {
280 if (attrs[i].type == type)
281 return attrs + i;
282 }
283
284 return NULL;
285 }
286
287 bool
p11_attrs_find_bool(const CK_ATTRIBUTE * attrs,CK_ATTRIBUTE_TYPE type,CK_BBOOL * value)288 p11_attrs_find_bool (const CK_ATTRIBUTE *attrs,
289 CK_ATTRIBUTE_TYPE type,
290 CK_BBOOL *value)
291 {
292 CK_ULONG i;
293
294 for (i = 0; !p11_attrs_terminator (attrs + i); i++) {
295 if (attrs[i].type == type &&
296 attrs[i].ulValueLen == sizeof (CK_BBOOL) &&
297 attrs[i].pValue != NULL) {
298 *value = *((CK_BBOOL *)attrs[i].pValue);
299 return true;
300 }
301 }
302
303 return false;
304 }
305
306 bool
p11_attrs_findn_bool(const CK_ATTRIBUTE * attrs,CK_ULONG count,CK_ATTRIBUTE_TYPE type,CK_BBOOL * value)307 p11_attrs_findn_bool (const CK_ATTRIBUTE *attrs,
308 CK_ULONG count,
309 CK_ATTRIBUTE_TYPE type,
310 CK_BBOOL *value)
311 {
312 CK_ULONG i;
313
314 for (i = 0; i < count; i++) {
315 if (attrs[i].type == type &&
316 attrs[i].ulValueLen == sizeof (CK_BBOOL) &&
317 attrs[i].pValue != NULL) {
318 *value = *((CK_BBOOL *)attrs[i].pValue);
319 return true;
320 }
321 }
322
323 return false;
324 }
325
326 bool
p11_attrs_find_ulong(const CK_ATTRIBUTE * attrs,CK_ATTRIBUTE_TYPE type,CK_ULONG * value)327 p11_attrs_find_ulong (const CK_ATTRIBUTE *attrs,
328 CK_ATTRIBUTE_TYPE type,
329 CK_ULONG *value)
330 {
331 CK_ULONG i;
332
333 for (i = 0; !p11_attrs_terminator (attrs + i); i++) {
334 if (attrs[i].type == type &&
335 attrs[i].ulValueLen == sizeof (CK_ULONG) &&
336 attrs[i].pValue != NULL) {
337 *value = *((CK_ULONG *)attrs[i].pValue);
338 return true;
339 }
340 }
341
342 return false;
343 }
344
345 bool
p11_attrs_findn_ulong(const CK_ATTRIBUTE * attrs,CK_ULONG count,CK_ATTRIBUTE_TYPE type,CK_ULONG * value)346 p11_attrs_findn_ulong (const CK_ATTRIBUTE *attrs,
347 CK_ULONG count,
348 CK_ATTRIBUTE_TYPE type,
349 CK_ULONG *value)
350 {
351 CK_ULONG i;
352
353 for (i = 0; i < count; i++) {
354 if (attrs[i].type == type &&
355 attrs[i].ulValueLen == sizeof (CK_ULONG) &&
356 attrs[i].pValue != NULL) {
357 *value = *((CK_ULONG *)attrs[i].pValue);
358 return true;
359 }
360 }
361
362 return false;
363 }
364
365 void *
p11_attrs_find_value(CK_ATTRIBUTE * attrs,CK_ATTRIBUTE_TYPE type,size_t * length)366 p11_attrs_find_value (CK_ATTRIBUTE *attrs,
367 CK_ATTRIBUTE_TYPE type,
368 size_t *length)
369 {
370 CK_ULONG i;
371
372 for (i = 0; !p11_attrs_terminator (attrs + i); i++) {
373 if (attrs[i].type == type &&
374 attrs[i].ulValueLen != 0 &&
375 attrs[i].ulValueLen != (CK_ULONG)-1 &&
376 attrs[i].pValue != NULL) {
377 if (length)
378 *length = attrs[i].ulValueLen;
379 return attrs[i].pValue;
380 }
381 }
382
383 return NULL;
384 }
385
386 CK_ATTRIBUTE *
p11_attrs_find_valid(CK_ATTRIBUTE * attrs,CK_ATTRIBUTE_TYPE type)387 p11_attrs_find_valid (CK_ATTRIBUTE *attrs,
388 CK_ATTRIBUTE_TYPE type)
389 {
390 CK_ULONG i;
391
392 for (i = 0; !p11_attrs_terminator (attrs + i); i++) {
393 if (attrs[i].type == type &&
394 attrs[i].pValue != NULL &&
395 attrs[i].ulValueLen != 0 &&
396 attrs[i].ulValueLen != (CK_ULONG)-1)
397 return attrs + i;
398 }
399
400 return NULL;
401 }
402
403 bool
p11_attrs_remove(CK_ATTRIBUTE * attrs,CK_ATTRIBUTE_TYPE type)404 p11_attrs_remove (CK_ATTRIBUTE *attrs,
405 CK_ATTRIBUTE_TYPE type)
406 {
407 CK_ULONG count;
408 CK_ULONG i;
409
410 count = p11_attrs_count (attrs);
411 for (i = 0; i < count; i++) {
412 if (attrs[i].type == type)
413 break;
414 }
415
416 if (i == count)
417 return false;
418
419 if (attrs[i].pValue)
420 free (attrs[i].pValue);
421
422 memmove (attrs + i, attrs + i + 1, (count - (i + 1)) * sizeof (CK_ATTRIBUTE));
423 attrs[count - 1].type = CKA_INVALID;
424 return true;
425 }
426
427 void
p11_attrs_purge(CK_ATTRIBUTE * attrs)428 p11_attrs_purge (CK_ATTRIBUTE *attrs)
429 {
430 int in, out;
431
432 for (in = 0, out = 0; !p11_attrs_terminator (attrs + in); in++) {
433 if (attrs[in].ulValueLen == (CK_ULONG)-1) {
434 free (attrs[in].pValue);
435 attrs[in].pValue = NULL;
436 attrs[in].ulValueLen = 0;
437 } else {
438 if (in != out)
439 memcpy (attrs + out, attrs + in, sizeof (CK_ATTRIBUTE));
440 out++;
441 }
442 }
443
444 attrs[out].type = CKA_INVALID;
445 assert (p11_attrs_terminator (attrs + out));
446
447 }
448
449 bool
p11_attrs_match(const CK_ATTRIBUTE * attrs,const CK_ATTRIBUTE * match)450 p11_attrs_match (const CK_ATTRIBUTE *attrs,
451 const CK_ATTRIBUTE *match)
452 {
453 CK_ATTRIBUTE *attr;
454
455 for (; !p11_attrs_terminator (match); match++) {
456 attr = p11_attrs_find ((CK_ATTRIBUTE *)attrs, match->type);
457 if (!attr)
458 return false;
459 if (!p11_attr_equal (attr, match))
460 return false;
461 }
462
463 return true;
464 }
465
466 bool
p11_attrs_matchn(const CK_ATTRIBUTE * attrs,const CK_ATTRIBUTE * match,CK_ULONG count)467 p11_attrs_matchn (const CK_ATTRIBUTE *attrs,
468 const CK_ATTRIBUTE *match,
469 CK_ULONG count)
470 {
471 CK_ATTRIBUTE *attr;
472 CK_ULONG i;
473
474 for (i = 0; i < count; i++) {
475 attr = p11_attrs_find ((CK_ATTRIBUTE *)attrs, match[i].type);
476 if (!attr)
477 return false;
478 if (!p11_attr_equal (attr, match + i))
479 return false;
480 }
481
482 return true;
483
484 }
485
486
487 bool
p11_attr_match_value(const CK_ATTRIBUTE * attr,const void * value,ssize_t length)488 p11_attr_match_value (const CK_ATTRIBUTE *attr,
489 const void *value,
490 ssize_t length)
491 {
492 if (length < 0)
493 length = strlen (value);
494 return (attr != NULL &&
495 attr->ulValueLen == length &&
496 (attr->pValue == value ||
497 (attr->pValue && value &&
498 memcmp (attr->pValue, value, attr->ulValueLen) == 0)));
499 }
500
501 bool
p11_attr_equal(const void * v1,const void * v2)502 p11_attr_equal (const void *v1,
503 const void *v2)
504 {
505 const CK_ATTRIBUTE *one = v1;
506 const CK_ATTRIBUTE *two = v2;
507
508 return (one == two ||
509 (one && two && one->type == two->type &&
510 p11_attr_match_value (one, two->pValue, two->ulValueLen)));
511 }
512
513 unsigned int
p11_attr_hash(const void * data)514 p11_attr_hash (const void *data)
515 {
516 const CK_ATTRIBUTE *attr = data;
517 uint32_t hash = 0;
518
519 if (attr != NULL) {
520 p11_hash_murmur3 (&hash,
521 &attr->type, sizeof (attr->type),
522 attr->pValue, (size_t)attr->ulValueLen,
523 NULL);
524 }
525
526 return hash;
527 }
528
529 static void
530 buffer_append_printf (p11_buffer *buffer,
531 const char *format,
532 ...) GNUC_PRINTF(2, 3);
533
534 static void
buffer_append_printf(p11_buffer * buffer,const char * format,...)535 buffer_append_printf (p11_buffer *buffer,
536 const char *format,
537 ...)
538 {
539 char *string;
540 va_list va;
541
542 va_start (va, format);
543 if (vasprintf (&string, format, va) < 0) {
544 va_end (va);
545 return_if_reached ();
546 }
547 va_end (va);
548
549 p11_buffer_add (buffer, string, -1);
550 free (string);
551 }
552
553 static bool
attribute_is_ulong_of_type(const CK_ATTRIBUTE * attr,CK_ULONG type)554 attribute_is_ulong_of_type (const CK_ATTRIBUTE *attr,
555 CK_ULONG type)
556 {
557 if (attr->type != type)
558 return false;
559 if (attr->ulValueLen != sizeof (CK_ULONG))
560 return false;
561 if (!attr->pValue)
562 return false;
563 return true;
564 }
565
566 static bool
attribute_is_trust_value(const CK_ATTRIBUTE * attr)567 attribute_is_trust_value (const CK_ATTRIBUTE *attr)
568 {
569 switch (attr->type) {
570 case CKA_TRUST_DIGITAL_SIGNATURE:
571 case CKA_TRUST_NON_REPUDIATION:
572 case CKA_TRUST_KEY_ENCIPHERMENT:
573 case CKA_TRUST_DATA_ENCIPHERMENT:
574 case CKA_TRUST_KEY_AGREEMENT:
575 case CKA_TRUST_KEY_CERT_SIGN:
576 case CKA_TRUST_CRL_SIGN:
577 case CKA_TRUST_SERVER_AUTH:
578 case CKA_TRUST_CLIENT_AUTH:
579 case CKA_TRUST_CODE_SIGNING:
580 case CKA_TRUST_EMAIL_PROTECTION:
581 case CKA_TRUST_IPSEC_END_SYSTEM:
582 case CKA_TRUST_IPSEC_TUNNEL:
583 case CKA_TRUST_IPSEC_USER:
584 case CKA_TRUST_TIME_STAMPING:
585 break;
586 default:
587 return false;
588 }
589
590 return attribute_is_ulong_of_type (attr, attr->type);
591 }
592
593 static bool
attribute_is_sensitive(const CK_ATTRIBUTE * attr,CK_OBJECT_CLASS klass)594 attribute_is_sensitive (const CK_ATTRIBUTE *attr,
595 CK_OBJECT_CLASS klass)
596 {
597 /*
598 * Don't print any just attribute, since they may contain
599 * sensitive data
600 */
601
602 switch (attr->type) {
603 #define X(x) case x: return false;
604 X (CKA_CLASS)
605 X (CKA_TOKEN)
606 X (CKA_PRIVATE)
607 X (CKA_LABEL)
608 X (CKA_APPLICATION)
609 X (CKA_OBJECT_ID)
610 X (CKA_CERTIFICATE_TYPE)
611 X (CKA_ISSUER)
612 X (CKA_SERIAL_NUMBER)
613 X (CKA_AC_ISSUER)
614 X (CKA_OWNER)
615 X (CKA_ATTR_TYPES)
616 X (CKA_TRUSTED)
617 X (CKA_CERTIFICATE_CATEGORY)
618 X (CKA_JAVA_MIDP_SECURITY_DOMAIN)
619 X (CKA_URL)
620 X (CKA_HASH_OF_SUBJECT_PUBLIC_KEY)
621 X (CKA_HASH_OF_ISSUER_PUBLIC_KEY)
622 X (CKA_CHECK_VALUE)
623 X (CKA_KEY_TYPE)
624 X (CKA_SUBJECT)
625 X (CKA_ID)
626 X (CKA_SENSITIVE)
627 X (CKA_ENCRYPT)
628 X (CKA_DECRYPT)
629 X (CKA_WRAP)
630 X (CKA_UNWRAP)
631 X (CKA_SIGN)
632 X (CKA_SIGN_RECOVER)
633 X (CKA_VERIFY)
634 X (CKA_VERIFY_RECOVER)
635 X (CKA_DERIVE)
636 X (CKA_START_DATE)
637 X (CKA_END_DATE)
638 X (CKA_MODULUS_BITS)
639 X (CKA_PRIME_BITS)
640 /* X (CKA_SUBPRIME_BITS) */
641 /* X (CKA_SUB_PRIME_BITS) */
642 X (CKA_VALUE_BITS)
643 X (CKA_VALUE_LEN)
644 X (CKA_EXTRACTABLE)
645 X (CKA_LOCAL)
646 X (CKA_NEVER_EXTRACTABLE)
647 X (CKA_ALWAYS_SENSITIVE)
648 X (CKA_KEY_GEN_MECHANISM)
649 X (CKA_MODIFIABLE)
650 X (CKA_SECONDARY_AUTH)
651 X (CKA_AUTH_PIN_FLAGS)
652 X (CKA_ALWAYS_AUTHENTICATE)
653 X (CKA_WRAP_WITH_TRUSTED)
654 X (CKA_WRAP_TEMPLATE)
655 X (CKA_UNWRAP_TEMPLATE)
656 X (CKA_HW_FEATURE_TYPE)
657 X (CKA_RESET_ON_INIT)
658 X (CKA_HAS_RESET)
659 X (CKA_PIXEL_X)
660 X (CKA_PIXEL_Y)
661 X (CKA_RESOLUTION)
662 X (CKA_CHAR_ROWS)
663 X (CKA_CHAR_COLUMNS)
664 X (CKA_COLOR)
665 X (CKA_BITS_PER_PIXEL)
666 X (CKA_CHAR_SETS)
667 X (CKA_ENCODING_METHODS)
668 X (CKA_MIME_TYPES)
669 X (CKA_MECHANISM_TYPE)
670 X (CKA_REQUIRED_CMS_ATTRIBUTES)
671 X (CKA_DEFAULT_CMS_ATTRIBUTES)
672 X (CKA_SUPPORTED_CMS_ATTRIBUTES)
673 X (CKA_ALLOWED_MECHANISMS)
674 X (CKA_X_ASSERTION_TYPE)
675 X (CKA_X_CERTIFICATE_VALUE)
676 X (CKA_X_PURPOSE)
677 X (CKA_X_PEER)
678 X (CKA_X_DISTRUSTED)
679 X (CKA_X_CRITICAL)
680 X (CKA_PUBLIC_KEY_INFO)
681 X (CKA_NSS_URL)
682 X (CKA_NSS_EMAIL)
683 X (CKA_NSS_SMIME_INFO)
684 X (CKA_NSS_SMIME_TIMESTAMP)
685 X (CKA_NSS_PKCS8_SALT)
686 X (CKA_NSS_PASSWORD_CHECK)
687 X (CKA_NSS_EXPIRES)
688 X (CKA_NSS_KRL)
689 X (CKA_NSS_PQG_COUNTER)
690 X (CKA_NSS_PQG_SEED)
691 X (CKA_NSS_PQG_H)
692 X (CKA_NSS_PQG_SEED_BITS)
693 X (CKA_NSS_MODULE_SPEC)
694 X (CKA_TRUST_DIGITAL_SIGNATURE)
695 X (CKA_TRUST_NON_REPUDIATION)
696 X (CKA_TRUST_KEY_ENCIPHERMENT)
697 X (CKA_TRUST_DATA_ENCIPHERMENT)
698 X (CKA_TRUST_KEY_AGREEMENT)
699 X (CKA_TRUST_KEY_CERT_SIGN)
700 X (CKA_TRUST_CRL_SIGN)
701 X (CKA_TRUST_SERVER_AUTH)
702 X (CKA_TRUST_CLIENT_AUTH)
703 X (CKA_TRUST_CODE_SIGNING)
704 X (CKA_TRUST_EMAIL_PROTECTION)
705 X (CKA_TRUST_IPSEC_END_SYSTEM)
706 X (CKA_TRUST_IPSEC_TUNNEL)
707 X (CKA_TRUST_IPSEC_USER)
708 X (CKA_TRUST_TIME_STAMPING)
709 X (CKA_TRUST_STEP_UP_APPROVED)
710 X (CKA_CERT_SHA1_HASH)
711 X (CKA_CERT_MD5_HASH)
712 case CKA_VALUE:
713 return (klass != CKO_CERTIFICATE &&
714 klass != CKO_X_CERTIFICATE_EXTENSION);
715 #undef X
716 }
717
718 return true;
719 }
720
721 static void
format_class(p11_buffer * buffer,CK_OBJECT_CLASS klass)722 format_class (p11_buffer *buffer,
723 CK_OBJECT_CLASS klass)
724 {
725 const char *string = p11_constant_name (p11_constant_classes, klass);
726 if (string != NULL)
727 p11_buffer_add (buffer, string, -1);
728 else
729 buffer_append_printf (buffer, "0x%08lX", klass);
730 }
731
732 static void
format_assertion_type(p11_buffer * buffer,CK_X_ASSERTION_TYPE type)733 format_assertion_type (p11_buffer *buffer,
734 CK_X_ASSERTION_TYPE type)
735 {
736 const char *string = p11_constant_name (p11_constant_asserts, type);
737 if (string != NULL)
738 p11_buffer_add (buffer, string, -1);
739 else
740 buffer_append_printf (buffer, "0x%08lX", type);
741 }
742
743 static void
format_key_type(p11_buffer * buffer,CK_KEY_TYPE type)744 format_key_type (p11_buffer *buffer,
745 CK_KEY_TYPE type)
746 {
747 const char *string = p11_constant_name (p11_constant_keys, type);
748 if (string != NULL)
749 p11_buffer_add (buffer, string, -1);
750 else
751 buffer_append_printf (buffer, "0x%08lX", type);
752 }
753
754 static void
format_certificate_type(p11_buffer * buffer,CK_CERTIFICATE_TYPE type)755 format_certificate_type (p11_buffer *buffer,
756 CK_CERTIFICATE_TYPE type)
757 {
758 const char *string = p11_constant_name (p11_constant_certs, type);
759 if (string != NULL)
760 p11_buffer_add (buffer, string, -1);
761 else
762 buffer_append_printf (buffer, "0x%08lX", type);
763 }
764
765 static void
format_trust_value(p11_buffer * buffer,CK_TRUST trust)766 format_trust_value (p11_buffer *buffer,
767 CK_TRUST trust)
768 {
769 const char *string = p11_constant_name (p11_constant_trusts, trust);
770 if (string != NULL)
771 p11_buffer_add (buffer, string, -1);
772 else
773 buffer_append_printf (buffer, "0x%08lX", trust);
774 }
775
776 static void
format_certificate_category(p11_buffer * buffer,CK_ULONG category)777 format_certificate_category (p11_buffer *buffer,
778 CK_ULONG category)
779 {
780 const char *string = p11_constant_name (p11_constant_categories, category);
781 if (string != NULL)
782 buffer_append_printf (buffer, "%lu (%s)", category, string);
783 else
784 buffer_append_printf (buffer, "%lu", category);
785 }
786
787 static void
format_attribute_type(p11_buffer * buffer,CK_ULONG type)788 format_attribute_type (p11_buffer *buffer,
789 CK_ULONG type)
790 {
791 const char *string = p11_constant_name (p11_constant_types, type);
792 if (string != NULL)
793 p11_buffer_add (buffer, string, -1);
794 else
795 buffer_append_printf (buffer, "CKA_0x%08lX", type);
796 }
797
798 static void
format_some_bytes(p11_buffer * buffer,void * bytes,CK_ULONG length)799 format_some_bytes (p11_buffer *buffer,
800 void *bytes,
801 CK_ULONG length)
802 {
803 unsigned char ch;
804 const unsigned char *data = bytes;
805 CK_ULONG i;
806
807 if (bytes == NULL) {
808 p11_buffer_add (buffer, "NULL", -1);
809 return;
810 }
811
812 p11_buffer_add (buffer, "\"", 1);
813 for (i = 0; i < length && i < 128; i++) {
814 ch = data[i];
815 if (ch == '\t')
816 p11_buffer_add (buffer, "\\t", -1);
817 else if (ch == '\n')
818 p11_buffer_add (buffer, "\\n", -1);
819 else if (ch == '\r')
820 p11_buffer_add (buffer, "\\r", -1);
821 else if (ch >= 32 && ch < 127)
822 p11_buffer_add (buffer, &ch, 1);
823 else
824 buffer_append_printf (buffer, "\\x%02x", ch);
825 }
826
827 if (i < length)
828 buffer_append_printf (buffer, "...");
829 p11_buffer_add (buffer, "\"", 1);
830 }
831
832 void
p11_attr_format(p11_buffer * buffer,const CK_ATTRIBUTE * attr,CK_OBJECT_CLASS klass)833 p11_attr_format (p11_buffer *buffer,
834 const CK_ATTRIBUTE *attr,
835 CK_OBJECT_CLASS klass)
836 {
837 p11_buffer_add (buffer, "{ ", -1);
838 format_attribute_type (buffer, attr->type);
839 p11_buffer_add (buffer, " = ", -1);
840 if (attr->ulValueLen == CKA_INVALID) {
841 buffer_append_printf (buffer, "(-1) INVALID");
842 } else if (attribute_is_ulong_of_type (attr, CKA_CLASS)) {
843 format_class (buffer, *((CK_OBJECT_CLASS *)attr->pValue));
844 } else if (attribute_is_ulong_of_type (attr, CKA_X_ASSERTION_TYPE)) {
845 format_assertion_type (buffer, *((CK_X_ASSERTION_TYPE *)attr->pValue));
846 } else if (attribute_is_ulong_of_type (attr, CKA_CERTIFICATE_TYPE)) {
847 format_certificate_type (buffer, *((CK_CERTIFICATE_TYPE *)attr->pValue));
848 } else if (attribute_is_ulong_of_type (attr, CKA_CERTIFICATE_CATEGORY)) {
849 format_certificate_category (buffer, *((CK_ULONG *)attr->pValue));
850 } else if (attribute_is_ulong_of_type (attr, CKA_KEY_TYPE)) {
851 format_key_type (buffer, *((CK_KEY_TYPE *)attr->pValue));
852 } else if (attribute_is_trust_value (attr)) {
853 format_trust_value (buffer, *((CK_TRUST *)attr->pValue));
854 } else if (attribute_is_sensitive (attr, klass)) {
855 buffer_append_printf (buffer, "(%lu) NOT-PRINTED", attr->ulValueLen);
856 } else {
857 buffer_append_printf (buffer, "(%lu) ", attr->ulValueLen);
858 format_some_bytes (buffer, attr->pValue, attr->ulValueLen);
859 }
860 p11_buffer_add (buffer, " }", -1);
861 }
862
863 void
p11_attrs_format(p11_buffer * buffer,const CK_ATTRIBUTE * attrs,int count)864 p11_attrs_format (p11_buffer *buffer,
865 const CK_ATTRIBUTE *attrs,
866 int count)
867 {
868 CK_BBOOL first = CK_TRUE;
869 CK_OBJECT_CLASS klass;
870 int i;
871
872 if (count < 0)
873 count = p11_attrs_count (attrs);
874
875 if (!p11_attrs_findn_ulong (attrs, CKA_CLASS, count, &klass))
876 klass = CKA_INVALID;
877
878 buffer_append_printf (buffer, "(%d) [", count);
879 for (i = 0; i < count; i++) {
880 if (first)
881 p11_buffer_add (buffer, " ", 1);
882 else
883 p11_buffer_add (buffer, ", ", 2);
884 first = CK_FALSE;
885 p11_attr_format (buffer, attrs + i, klass);
886 }
887 p11_buffer_add (buffer, " ]", -1);
888 }
889
890 char *
p11_attrs_to_string(const CK_ATTRIBUTE * attrs,int count)891 p11_attrs_to_string (const CK_ATTRIBUTE *attrs,
892 int count)
893 {
894 p11_buffer buffer;
895 if (!p11_buffer_init_null (&buffer, 128))
896 return_val_if_reached (NULL);
897 p11_attrs_format (&buffer, attrs, count);
898 return p11_buffer_steal (&buffer, NULL);
899 }
900
901 char *
p11_attr_to_string(const CK_ATTRIBUTE * attr,CK_OBJECT_CLASS klass)902 p11_attr_to_string (const CK_ATTRIBUTE *attr,
903 CK_OBJECT_CLASS klass)
904 {
905 p11_buffer buffer;
906 if (!p11_buffer_init_null (&buffer, 32))
907 return_val_if_reached (NULL);
908 p11_attr_format (&buffer, attr, klass);
909 return p11_buffer_steal (&buffer, NULL);
910 }
911