1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /* gck-attribute.c - the GObject PKCS#11 wrapper library
3 
4    Copyright (C) 2008, Stefan Walter
5 
6    The Gnome Keyring Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Library General Public License as
8    published by the Free Software Foundation; either version 2 of the
9    License, or (at your option) any later version.
10 
11    The Gnome Keyring Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Library General Public License for more details.
15 
16    You should have received a copy of the GNU Library General Public
17    License along with the Gnome Library; see the file COPYING.LIB.  If not,
18    see <http://www.gnu.org/licenses/>.
19 
20    Author: Stef Walter <nielsen@memberwebs.com>
21 */
22 
23 #include "config.h"
24 
25 #include "gck.h"
26 #include "gck-private.h"
27 #include "pkcs11-trust-assertions.h"
28 
29 #include "egg/egg-secure-memory.h"
30 
31 #include <stdlib.h>
32 #include <string.h>
33 
34 /**
35  * SECTION:gck-attribute
36  * @title: GckAttribute
37  * @short_description: A PKCS11 attribute.
38  *
39  * This structure represents a PKCS11 CK_ATTRIBUTE. These attributes contain i
40  * about a PKCS11 object. Use gck_object_get() or gck_object_set() to set and
41  * attributes on an object.
42  *
43  * Although you are free to allocate a #GckAttribute in your own code, no functions in
44  * this library will operate on such an attribute.
45  */
46 
47 G_STATIC_ASSERT (sizeof (GckAttribute) == sizeof (CK_ATTRIBUTE));
48 
49 #define STATE_LOCKED     1
50 #define STATE_FLOATING   8
51 
52 struct _GckAttributes {
53 	GckAttribute *data;
54 	gulong count;
55 	gint refs;
56 	gint state;
57 };
58 
59 typedef struct {
60 	GArray *array;
61 	gboolean secure;
62 	gint refs;
63 } GckRealBuilder;
64 
65 G_STATIC_ASSERT (sizeof (GckRealBuilder) <= sizeof (GckBuilder));
66 
67 EGG_SECURE_DECLARE (attributes);
68 
69 #define MAX_ALIGN 16
70 
71 static guchar *
value_take(gpointer data,gsize length,gboolean secure)72 value_take (gpointer data,
73             gsize length,
74             gboolean secure)
75 {
76 	gsize len = length + MAX_ALIGN;
77 	guchar *value;
78 
79 	if (secure)
80 		value = egg_secure_realloc (data, len);
81 	else
82 		value = g_realloc (data, len);
83 	g_assert (value != NULL);
84 
85 	memmove (value + MAX_ALIGN, value, length);
86 	g_atomic_int_set ((gint *)value, 1);
87 	return value + MAX_ALIGN;
88 }
89 
90 static guchar *
value_blank(gsize length,gboolean secure)91 value_blank (gsize length,
92              gboolean secure)
93 {
94 	gsize len = length + MAX_ALIGN;
95 	guchar *value;
96 
97 	if (secure)
98 		value = egg_secure_alloc (len);
99 	else
100 		value = g_malloc (len);
101 	g_assert (value != NULL);
102 
103 	g_atomic_int_set ((gint *)value, 1);
104 	return value + MAX_ALIGN;
105 }
106 
107 static guchar *
value_new(gconstpointer data,gsize length,gboolean secure)108 value_new (gconstpointer data,
109            gsize length,
110            gboolean secure)
111 {
112 	guchar *result;
113 
114 	result = value_blank (length, secure);
115 	memcpy (result, data, length);
116 	return result;
117 }
118 
119 static guchar *
value_ref(guchar * data)120 value_ref (guchar *data)
121 {
122 	guchar *value = data - MAX_ALIGN;
123 	gint previous;
124 
125 	g_assert (data != NULL);
126 
127 	previous = g_atomic_int_add ((gint *)value, 1);
128 	if (G_UNLIKELY (previous <= 0)) {
129 		g_warning ("An owned GckAttribute value has been modified outside of the "
130 		           "gck library or an invalid attribute was passed to gck_builder_add_attribute()");
131 		return NULL;
132 	}
133 
134 	return data;
135 }
136 
137 static void
value_unref(guchar * data)138 value_unref (guchar *data)
139 {
140 	guchar *value = data - MAX_ALIGN;
141 
142 	g_assert (data != NULL);
143 
144 	if (g_atomic_int_dec_and_test ((gint *)value)) {
145 		if (egg_secure_check (value))
146 			egg_secure_free (value);
147 		else
148 			g_free (value);
149 	}
150 }
151 
G_DEFINE_BOXED_TYPE(GckBuilder,gck_builder,gck_builder_ref,gck_builder_unref)152 G_DEFINE_BOXED_TYPE (GckBuilder, gck_builder,
153                      gck_builder_ref, gck_builder_unref)
154 
155 /**
156  * GckBuilder:
157  *
158  * A builder for a set of attributes. Add attributes to a builder, and then use
159  * gck_builder_end() to get the completed #GckAttributes.
160  *
161  * The fields of #GckBuilder are private and not to be accessed directly.
162  */
163 
164 /**
165  * GckBuilderFlags:
166  * @GCK_BUILDER_NONE: no special flags
167  * @GCK_BUILDER_SECURE_MEMORY: use non-pageable memory for the values of the attributes
168  *
169  * Flags to be used with a gck_builder_init_full() and gck_builder_new().
170  */
171 
172 /**
173  * GCK_BUILDER_INIT:
174  *
175  * Values that can be assigned to a #GckBuilder allocated on the stack.
176  *
177  * <informalexample><programlisting>
178  * GckBuilder builder = GCK_BUILDER_INIT;
179  * </programlisting></informalexample>
180  */
181 
182 /**
183  * gck_builder_new:
184  * @flags: flags for the new builder
185  *
186  * Create a new #GckBuilder not allocated on the stack, so it can be shared
187  * across a single scope, and referenced / unreferenced.
188  *
189  * Normally a #GckBuilder is created on the stack, and simply initialized.
190  *
191  * If the %GCK_BUILDER_SECURE_MEMORY flag is specified then non-pageable memory
192  * will be used for the various values of the attributes in the builder
193  *
194  * Returns: (transfer full): a new builder, to be freed with gck_builder_unref()
195  */
196 GckBuilder *
197 gck_builder_new (GckBuilderFlags flags)
198 {
199 	GckBuilder *builder;
200 	GckRealBuilder *real;
201 	builder = g_slice_new (GckBuilder);
202 	gck_builder_init_full (builder, flags);
203 	real = (GckRealBuilder *)builder;
204 	real->refs = 1;
205 	return builder;
206 }
207 
208 /**
209  * gck_builder_ref:
210  * @builder: the builder
211  *
212  * Add a reference to a builder that was created with gck_builder_new(). The
213  * builder must later be unreferenced again with gck_builder_unref().
214  *
215  * It is an error to use this function on builders that were allocated on the
216  * stack.
217  *
218  * Returns: the builder
219  */
220 GckBuilder *
gck_builder_ref(GckBuilder * builder)221 gck_builder_ref (GckBuilder *builder)
222 {
223 	GckRealBuilder *real = (GckRealBuilder *)builder;
224 	gboolean stack;
225 
226 	g_return_val_if_fail (builder != NULL, NULL);
227 
228 	stack = g_atomic_int_add (&real->refs, 1) == 0;
229 	if G_UNLIKELY (stack) {
230 		g_warning ("Never call gck_builder_ref() on a stack allocated GckBuilder structure");
231 		return NULL;
232 	}
233 
234 	return builder;
235 }
236 
237 /**
238  * gck_builder_unref:
239  * @builder: the builder
240  *
241  * Unreferences a builder. If this was the last reference then the builder
242  * is freed.
243  *
244  * It is an error to use this function on builders that were allocated on the
245  * stack.
246  */
247 void
gck_builder_unref(gpointer builder)248 gck_builder_unref (gpointer builder)
249 {
250 	GckRealBuilder *real = (GckRealBuilder *)builder;
251 
252 	if (builder == NULL)
253 		return;
254 
255 	if (g_atomic_int_dec_and_test (&real->refs)) {
256 		gck_builder_clear (builder);
257 		g_slice_free (GckBuilder, builder);
258 	}
259 }
260 
261 /**
262  * gck_builder_init_full:
263  * @builder: the builder
264  * @flags: the flags for the new builder
265  *
266  * Initialize a stack allocated builder, with the appropriate flags.
267  *
268  * If the %GCK_BUILDER_SECURE_MEMORY flag is specified then non-pageable memory
269  * will be used for the various values of the attributes in the builder
270  */
271 void
gck_builder_init_full(GckBuilder * builder,GckBuilderFlags flags)272 gck_builder_init_full (GckBuilder *builder,
273                        GckBuilderFlags flags)
274 {
275 	GckRealBuilder *real = (GckRealBuilder *)builder;
276 
277 	g_return_if_fail (builder != NULL);
278 
279 	memset (builder, 0, sizeof (GckBuilder));
280 	real->secure = flags & GCK_BUILDER_SECURE_MEMORY;
281 }
282 
283 /**
284  * gck_builder_init:
285  * @builder: the builder
286  *
287  * Initialize a stack allocated builder, with the default flags.
288  *
289  * This is equivalent to initializing a builder variable with the
290  * %GCK_BUILDER_INIT constant, or setting it to zeroed memory.
291  *
292  * <informalexample><programlisting>
293  * /<!-- -->* Equivalent ways of initializing a GckBuilder *<!-- -->/
294  * GckBuilder builder = GCK_BUILDER_INIT;
295  * GckBuilder builder2;
296  * GckBuilder builder3;
297  *
298  * gck_builder_init (&builder2);
299  *
300  * memset (&builder3, 0, sizeof (builder3));
301  * </programlisting></informalexample>
302  */
303 void
gck_builder_init(GckBuilder * builder)304 gck_builder_init (GckBuilder *builder)
305 {
306 	gck_builder_init_full (builder, GCK_BUILDER_NONE);
307 }
308 
309 static GckAttribute *
builder_push(GckBuilder * builder,gulong attr_type)310 builder_push (GckBuilder *builder,
311               gulong attr_type)
312 {
313 	GckAttribute attr = { attr_type, NULL, 0 };
314 	GckRealBuilder *real = (GckRealBuilder *)builder;
315 	if (real->array == NULL)
316 		real->array = g_array_new (FALSE, TRUE, sizeof (GckAttribute));
317 	g_array_append_val (real->array, attr);
318 	return &g_array_index (real->array, GckAttribute, real->array->len - 1);
319 }
320 
321 static void
builder_clear(GckAttribute * attr)322 builder_clear (GckAttribute *attr)
323 {
324 	attr->length = 0;
325 	if (attr->value)
326 		value_unref (attr->value);
327 	attr->value = NULL;
328 }
329 
330 static GckAttribute *
find_attribute(GckAttribute * attrs,gsize n_attrs,gulong attr_type)331 find_attribute (GckAttribute *attrs,
332                 gsize n_attrs,
333                 gulong attr_type)
334 {
335 	guint i;
336 
337 	for (i = 0; i < n_attrs; ++i) {
338 		if (attrs[i].type == attr_type)
339 			return attrs + i;
340 	}
341 
342 	return NULL;
343 }
344 
345 static GckAttribute *
builder_clear_or_push(GckBuilder * builder,gulong attr_type)346 builder_clear_or_push (GckBuilder *builder,
347                        gulong attr_type)
348 {
349 	GckRealBuilder *real = (GckRealBuilder *)builder;
350 	GckAttribute *attr = NULL;
351 
352 	if (real->array)
353 		attr = find_attribute ((GckAttribute *)real->array->data,
354 		                       real->array->len, attr_type);
355 	if (attr == NULL)
356 		attr = builder_push (builder, attr_type);
357 	else
358 		builder_clear (attr);
359 	return attr;
360 }
361 
362 static void
builder_copy(GckBuilder * builder,const GckAttribute * attr,gboolean performing_set)363 builder_copy (GckBuilder *builder,
364               const GckAttribute *attr,
365               gboolean performing_set)
366 {
367 	GckAttribute *copy;
368 
369 	if (performing_set)
370 		copy = builder_clear_or_push (builder, attr->type);
371 	else
372 		copy = builder_push (builder, attr->type);
373 	if (attr->length == G_MAXULONG) {
374 		copy->value = NULL;
375 		copy->length = G_MAXULONG;
376 	} else if (attr->value == NULL) {
377 		copy->value = NULL;
378 		copy->length = 0;
379 	} else {
380 		copy->value = value_ref (attr->value);
381 		copy->length = attr->length;
382 	}
383 }
384 
385 /**
386  * gck_builder_copy:
387  * @builder: the builder to copy
388  *
389  * Make a copy of the builder and its state. The new builder is allocated
390  * with gck_builder_new() and should be freed with gck_builder_unref().
391  *
392  * Attribute value memory is automatically shared between the two builders,
393  * and is only freed when both are gone.
394  *
395  * Returns: (transfer full): the builder copy, which should be freed with
396  *          gck_builder_unref().
397  */
398 GckBuilder *
gck_builder_copy(GckBuilder * builder)399 gck_builder_copy (GckBuilder *builder)
400 {
401 	GckRealBuilder *real = (GckRealBuilder *)builder;
402 	GckBuilder *copy;
403 	guint i;
404 
405 	if (builder == NULL)
406 		return NULL;
407 
408 	copy = gck_builder_new (real->secure ? GCK_BUILDER_SECURE_MEMORY : GCK_BUILDER_NONE);
409 	for (i = 0; real->array && i < real->array->len; i++)
410 		builder_copy (copy, &g_array_index (real->array, GckAttribute, i), FALSE);
411 
412 	return copy;
413 }
414 
415 /**
416  * gck_builder_take_data:
417  * @builder: the builder
418  * @attr_type: the new attribute type
419  * @value: (transfer full) (array length=length) (nullable): the new
420  *         attribute memory
421  * @length: the length of the memory
422  *
423  * Add a new attribute to the builder with an arbitrary value. Unconditionally
424  * adds a new attribute, even if one with the same @attr_type already exists.
425  *
426  * Ownership of the @value memory is taken by the builder, may be reallocated,
427  * and is eventually freed with g_free(). The memory must have been allocated
428  * using the standard GLib memory allocation routines.
429  *
430  * %NULL may be specified for the @value argument, in which case an empty
431  * attribute is created. GCK_INVALID may be specified for the length, in
432  * which case an invalid attribute is created in the PKCS\#11 style.
433  */
434 void
gck_builder_take_data(GckBuilder * builder,gulong attr_type,guchar * value,gsize length)435 gck_builder_take_data (GckBuilder *builder,
436                        gulong attr_type,
437                        guchar *value,
438                        gsize length)
439 {
440 	GckAttribute *attr;
441 	gboolean secure;
442 
443 	g_return_if_fail (builder != NULL);
444 
445 	secure = value && egg_secure_check (value);
446 
447 	attr = builder_push (builder, attr_type);
448 	if (length == G_MAXULONG) {
449 		if (secure)
450 			egg_secure_free (value);
451 		else
452 			g_free (value);
453 		attr->value = NULL;
454 		attr->length = G_MAXULONG;
455 	} else if (value == NULL) {
456 		attr->value = NULL;
457 		attr->length = 0;
458 	} else {
459 		attr->value = value_take (value, length, secure);
460 		attr->length = length;
461 	}
462 }
463 
464 /**
465  * gck_builder_add_data:
466  * @builder: the builder
467  * @attr_type: the new attribute type
468  * @value: (array length=length) (nullable): the new attribute memory
469  * @length: the length of the memory
470  *
471  * Add a new attribute to the builder with an arbitrary value. Unconditionally
472  * adds a new attribute, even if one with the same @attr_type already exists.
473  *
474  * The memory in @value is copied by the builder.
475  *
476  * %NULL may be specified for the @value argument, in which case an empty
477  * attribute is created. GCK_INVALID may be specified for the length, in
478  * which case an invalid attribute is created in the PKCS\#11 style.
479  */
480 void
gck_builder_add_data(GckBuilder * builder,gulong attr_type,const guchar * value,gsize length)481 gck_builder_add_data (GckBuilder *builder,
482                       gulong attr_type,
483                       const guchar *value,
484                       gsize length)
485 {
486 	GckRealBuilder *real = (GckRealBuilder *)builder;
487 	GckAttribute *attr;
488 
489 	g_return_if_fail (builder != NULL);
490 
491 	attr = builder_push (builder, attr_type);
492 	if (length == G_MAXULONG) {
493 		attr->value = NULL;
494 		attr->length = G_MAXULONG;
495 	} else if (value == NULL) {
496 		attr->value = NULL;
497 		attr->length = 0;
498 	} else {
499 		attr->value = value_new (value, length,
500 		                         real->secure || egg_secure_check (value));
501 		attr->length = length;
502 	}
503 }
504 
505 /**
506  * gck_builder_set_data:
507  * @builder: the builder
508  * @attr_type: the attribute type
509  * @value: (array length=length) (nullable): the new attribute memory
510  * @length: the length of the memory
511  *
512  * Set a new attribute to the builder with an arbitrary value. If an attribute
513  * with @attr_type already exists in the builder then it is changed to the new
514  * value, otherwise an attribute is added.
515  *
516  * The memory in @value is copied by the builder.
517  *
518  * %NULL may be specified for the @value argument, in which case an empty
519  * attribute is created. GCK_INVALID may be specified for the length, in
520  * which case an invalid attribute is created in the PKCS\#11 style.
521  */
522 void
gck_builder_set_data(GckBuilder * builder,gulong attr_type,const guchar * value,gsize length)523 gck_builder_set_data (GckBuilder *builder,
524                       gulong attr_type,
525                       const guchar *value,
526                       gsize length)
527 {
528 	GckRealBuilder *real = (GckRealBuilder *)builder;
529 	GckAttribute *attr;
530 
531 	g_return_if_fail (builder != NULL);
532 
533 	attr = builder_clear_or_push (builder, attr_type);
534 	if (length == G_MAXULONG) {
535 		attr->value = NULL;
536 		attr->length = G_MAXULONG;
537 	} else if (value == NULL) {
538 		attr->value = NULL;
539 		attr->length = 0;
540 	} else {
541 		attr->value = value_new (value, length,
542 		                         real->secure || egg_secure_check (value));
543 		attr->length = length;
544 	}
545 }
546 
547 /**
548  * gck_builder_add_empty:
549  * @builder: the builder
550  * @attr_type: the new attribute type
551  *
552  * Add a new attribute to the builder that is empty. Unconditionally
553  * adds a new attribute, even if one with the same @attr_type already exists.
554  */
555 void
gck_builder_add_empty(GckBuilder * builder,gulong attr_type)556 gck_builder_add_empty (GckBuilder *builder,
557                        gulong attr_type)
558 {
559 	g_return_if_fail (builder != NULL);
560 
561 	builder_push (builder, attr_type);
562 }
563 
564 /**
565  * gck_builder_set_empty:
566  * @builder: the builder
567  * @attr_type: the attribute type
568  *
569  * Set an attribute on the builder that is empty. If an attribute
570  * with @attr_type already exists in the builder then it is changed to the new
571  * value, otherwise an attribute is added.
572  */
573 void
gck_builder_set_empty(GckBuilder * builder,gulong attr_type)574 gck_builder_set_empty (GckBuilder *builder,
575                        gulong attr_type)
576 {
577 	g_return_if_fail (builder != NULL);
578 
579 	builder_clear_or_push (builder, attr_type);
580 }
581 
582 /**
583  * gck_builder_add_invalid:
584  * @builder: the builder
585  * @attr_type: the new attribute type
586  *
587  * Add a new attribute to the builder that is invalid in the PKCS\#11 sense.
588  * Unconditionally adds a new attribute, even if one with the same @attr_type
589  * already exists.
590  */
591 void
gck_builder_add_invalid(GckBuilder * builder,gulong attr_type)592 gck_builder_add_invalid (GckBuilder *builder,
593                          gulong attr_type)
594 {
595 	GckAttribute *attr;
596 
597 	g_return_if_fail (builder != NULL);
598 
599 	attr = builder_push (builder, attr_type);
600 	attr->length = (gulong)-1;
601 }
602 
603 /**
604  * gck_builder_set_invalid:
605  * @builder: the builder
606  * @attr_type: the attribute type
607  *
608  * Set an attribute on the builder that is invalid in the PKCS\#11 sense.
609  * If an attribute with @attr_type already exists in the builder then it is
610  * changed to the new value, otherwise an attribute is added.
611  */
612 void
gck_builder_set_invalid(GckBuilder * builder,gulong attr_type)613 gck_builder_set_invalid (GckBuilder *builder,
614                          gulong attr_type)
615 {
616 	GckAttribute *attr;
617 
618 	g_return_if_fail (builder != NULL);
619 
620 	attr = builder_clear_or_push (builder, attr_type);
621 	attr->length = (gulong)-1;
622 }
623 
624 /**
625  * gck_builder_add_ulong:
626  * @builder: the builder
627  * @attr_type: the new attribute type
628  * @value: the attribute value
629  *
630  * Add a new attribute to the builder for the unsigned long @value.
631  * Unconditionally adds a new attribute, even if one with the same @attr_type
632  * already exists.
633  */
634 void
gck_builder_add_ulong(GckBuilder * builder,gulong attr_type,gulong value)635 gck_builder_add_ulong (GckBuilder *builder,
636                        gulong attr_type,
637                        gulong value)
638 {
639 	CK_ULONG uval = value;
640 	gck_builder_add_data (builder, attr_type,
641 	                      (const guchar *)&uval, sizeof (uval));
642 }
643 
644 /**
645  * gck_builder_set_ulong:
646  * @builder: the builder
647  * @attr_type: the new attribute type
648  * @value: the attribute value
649  *
650  * Set an attribute on the builder for the unsigned long @value.
651  * If an attribute with @attr_type already exists in the builder then it is
652  * changed to the new value, otherwise an attribute is added.
653  */
654 void
gck_builder_set_ulong(GckBuilder * builder,gulong attr_type,gulong value)655 gck_builder_set_ulong (GckBuilder *builder,
656                        gulong attr_type,
657                        gulong value)
658 {
659 	CK_ULONG uval = value;
660 	gck_builder_set_data (builder, attr_type,
661 	                      (const guchar *)&uval, sizeof (uval));
662 }
663 
664 /**
665  * gck_builder_add_boolean:
666  * @builder: the builder
667  * @attr_type: the new attribute type
668  * @value: the attribute value
669  *
670  * Add a new attribute to the builder for the boolean @value.
671  * Unconditionally adds a new attribute, even if one with the same @attr_type
672  * already exists.
673  */
674 void
gck_builder_add_boolean(GckBuilder * builder,gulong attr_type,gboolean value)675 gck_builder_add_boolean (GckBuilder *builder,
676                          gulong attr_type,
677                          gboolean value)
678 {
679 	CK_BBOOL bval = value ? CK_TRUE : CK_FALSE;
680 	gck_builder_add_data (builder, attr_type,
681 	                      (const guchar *)&bval, sizeof (bval));
682 }
683 
684 /**
685  * gck_builder_set_boolean:
686  * @builder: the builder
687  * @attr_type: the new attribute type
688  * @value: the attribute value
689  *
690  * Set an attribute on the builder for the boolean @value.
691  * If an attribute with @attr_type already exists in the builder then it is
692  * changed to the new value, otherwise an attribute is added.
693  */
694 void
gck_builder_set_boolean(GckBuilder * builder,gulong attr_type,gboolean value)695 gck_builder_set_boolean (GckBuilder *builder,
696                          gulong attr_type,
697                          gboolean value)
698 {
699 	CK_BBOOL bval = value ? CK_TRUE : CK_FALSE;
700 	gck_builder_set_data (builder, attr_type,
701 	                      (const guchar *)&bval, sizeof (bval));
702 }
703 
704 static void
convert_gdate_to_ckdate(const GDate * value,CK_DATE * date)705 convert_gdate_to_ckdate (const GDate *value,
706                          CK_DATE *date)
707 {
708 	gchar buffer[9];
709 	g_snprintf (buffer, sizeof (buffer), "%04d%02d%02d",
710 	            (int)g_date_get_year (value),
711 	            (int)g_date_get_month (value),
712 	            (int)g_date_get_day (value));
713 	memcpy (&date->year, buffer + 0, 4);
714 	memcpy (&date->month, buffer + 4, 2);
715 	memcpy (&date->day, buffer + 6, 2);
716 }
717 
718 /**
719  * gck_builder_add_date:
720  * @builder: the builder
721  * @attr_type: the new attribute type
722  * @value: the attribute value
723  *
724  * Add a new attribute to the builder for the date @value.
725  * Unconditionally adds a new attribute, even if one with the same @attr_type
726  * already exists.
727  */
728 void
gck_builder_add_date(GckBuilder * builder,gulong attr_type,const GDate * value)729 gck_builder_add_date (GckBuilder *builder,
730                       gulong attr_type,
731                       const GDate *value)
732 {
733 	CK_DATE date;
734 
735 	g_return_if_fail (value != NULL);
736 
737 	convert_gdate_to_ckdate (value, &date);
738 	gck_builder_add_data (builder, attr_type,
739 	                      (const guchar *)&date, sizeof (CK_DATE));
740 }
741 
742 /**
743  * gck_builder_set_date:
744  * @builder: the builder
745  * @attr_type: the new attribute type
746  * @value: the attribute value
747  *
748  * Set an attribute on the builder for the date @value.
749  * If an attribute with @attr_type already exists in the builder then it is
750  * changed to the new value, otherwise an attribute is added.
751  */
752 void
gck_builder_set_date(GckBuilder * builder,gulong attr_type,const GDate * value)753 gck_builder_set_date (GckBuilder *builder,
754                       gulong attr_type,
755                       const GDate *value)
756 {
757 	CK_DATE date;
758 
759 	g_return_if_fail (value != NULL);
760 
761 	convert_gdate_to_ckdate (value, &date);
762 	gck_builder_set_data (builder, attr_type,
763 	                      (const guchar *)&date, sizeof (CK_DATE));
764 }
765 
766 /**
767  * gck_builder_add_string:
768  * @builder: the builder
769  * @attr_type: the new attribute type
770  * @value: (nullable): the attribute value
771  *
772  * Add a new attribute to the builder for the string @value or %NULL.
773  * Unconditionally adds a new attribute, even if one with the same @attr_type
774  * already exists.
775  */
776 void
gck_builder_add_string(GckBuilder * builder,gulong attr_type,const gchar * value)777 gck_builder_add_string (GckBuilder *builder,
778                         gulong attr_type,
779                         const gchar *value)
780 {
781 	gck_builder_add_data (builder, attr_type,
782 	                      (const guchar *)value, value ? strlen (value) : 0);
783 }
784 
785 /**
786  * gck_builder_set_string:
787  * @builder: the builder
788  * @attr_type: the new attribute type
789  * @value: the attribute value
790  *
791  * Set an attribute on the builder for the string @value or %NULL.
792  * If an attribute with @attr_type already exists in the builder then it is
793  * changed to the new value, otherwise an attribute is added.
794  */
795 void
gck_builder_set_string(GckBuilder * builder,gulong attr_type,const gchar * value)796 gck_builder_set_string (GckBuilder *builder,
797                         gulong attr_type,
798                         const gchar *value)
799 {
800 	gck_builder_set_data (builder, attr_type,
801 	                      (const guchar *)value, value ? strlen (value) : 0);
802 }
803 
804 /**
805  * gck_builder_add_attribute:
806  * @builder: the builder
807  * @attr: the attribute to add
808  *
809  * Add an attribute to the builder. The attribute is added unconditionally whether
810  * or not an attribute with the same type already exists on the builder.
811  *
812  * The @attr attribute must have been created or owned by the Gck library.
813  * If you call this function on an arbitrary #GckAttribute that is allocated on
814  * the stack or elsewhere, then this will result in undefined behavior.
815  *
816  * As an optimization, the attribute memory value is automatically shared
817  * between the attribute and the builder.
818  */
819 void
gck_builder_add_attribute(GckBuilder * builder,const GckAttribute * attr)820 gck_builder_add_attribute (GckBuilder *builder,
821                            const GckAttribute *attr)
822 {
823 	g_return_if_fail (builder != NULL);
824 	g_return_if_fail (attr != NULL);
825 
826 	builder_copy (builder, attr, FALSE);
827 }
828 
829 /**
830  * gck_builder_add_all:
831  * @builder: the builder
832  * @attrs: the attributes to add
833  *
834  * Add all the @attrs attributes to the builder. The attributes are added
835  * uncondititionally whether or not attributes with the same types already
836  * exist in the builder.
837  *
838  * As an optimization, the attribute memory values are automatically shared
839  * between the attributes and the builder.
840  */
841 void
gck_builder_add_all(GckBuilder * builder,GckAttributes * attrs)842 gck_builder_add_all (GckBuilder *builder,
843                      GckAttributes *attrs)
844 {
845 	gulong i;
846 
847 	g_return_if_fail (builder != NULL);
848 	g_return_if_fail (attrs != NULL);
849 
850 	for (i = 0; i < attrs->count; i++)
851 		builder_copy (builder, &attrs->data[i], FALSE);
852 }
853 
854 /**
855  * gck_builder_add_only: (skip)
856  * @builder: the builder
857  * @attrs: the attributes to add
858  * @only_type: the first type of attribute to add
859  * @...: the remaining attribute types to add, ending with %GCK_INVALID
860  *
861  * Add the attributes specified in the argument list from @attrs to the
862  * builder. The attributes are added uncondititionally whether or not
863  * attributes with the same types already exist in the builder.
864  *
865  * The variable arguments must be unsigned longs.
866  *
867  * <informalexample><programlisting>
868  * /<!-- -->* Add the CKA_ID and CKA_CLASS attributes from attrs to builder *<!-- -->/
869  * gck_builder_add_only (builder, attrs, CKA_ID, CKA_CLASS, GCK_INVALID);
870  * </programlisting></informalexample>
871  *
872  * As an optimization, the attribute memory values are automatically shared
873  * between the attributes and the builder.
874  */
875 void
gck_builder_add_only(GckBuilder * builder,GckAttributes * attrs,gulong only_type,...)876 gck_builder_add_only (GckBuilder *builder,
877                       GckAttributes *attrs,
878                       gulong only_type,
879                       ...)
880 {
881 	GArray *types;
882 	va_list va;
883 
884 	g_return_if_fail (builder != NULL);
885 	g_return_if_fail (attrs != NULL);
886 
887 	types = g_array_new (FALSE, FALSE, sizeof (gulong));
888 
889 	va_start (va, only_type);
890 	while (only_type != GCK_INVALID) {
891 		g_array_append_val (types, only_type);
892 		only_type = va_arg (va, gulong);
893 	}
894 	va_end (va);
895 
896 	gck_builder_add_onlyv (builder, attrs, (gulong *)types->data, types->len);
897 	g_array_free (types, TRUE);
898 }
899 
900 /**
901  * gck_builder_add_onlyv: (rename-to gck_builder_add_only)
902  * @builder: the builder
903  * @attrs: the attributes to add
904  * @only_types: (array length=n_only_types): the types of attributes to add
905  * @n_only_types: the number of attributes
906  *
907  * Add the attributes with the types in @only_types from @attrs to the
908  * builder. The attributes are added uncondititionally whether or not
909  * attributes with the same types already exist in the builder.
910  *
911  * <informalexample><programlisting>
912  * /<!-- -->* Add the CKA_ID and CKA_CLASS attributes from attrs to builder *<!-- -->/
913  * gulong only[] = { CKA_ID, CKA_CLASS };
914  * gck_builder_add_onlyv (builder, attrs, only, 2);
915  * </programlisting></informalexample>
916  *
917  * As an optimization, the attribute memory values are automatically shared
918  * between the attributes and the builder.
919  */
920 void
gck_builder_add_onlyv(GckBuilder * builder,GckAttributes * attrs,const gulong * only_types,guint n_only_types)921 gck_builder_add_onlyv (GckBuilder *builder,
922                        GckAttributes *attrs,
923                        const gulong *only_types,
924                        guint n_only_types)
925 {
926 	gulong i;
927 	guint j;
928 
929 	g_return_if_fail (builder != NULL);
930 	g_return_if_fail (attrs != NULL);
931 
932 	for (i = 0; i < attrs->count; i++) {
933 		for (j = 0; j < n_only_types; j++) {
934 			if (attrs->data[i].type == only_types[j])
935 				builder_copy (builder, &attrs->data[i], FALSE);
936 		}
937 	}
938 }
939 
940 /**
941  * gck_builder_add_except: (skip)
942  * @builder: the builder
943  * @attrs: the attributes to add
944  * @except_type: the first type of attribute to to exclude
945  * @...: the remaining attribute types to exclude, ending with %GCK_INVALID
946  *
947  * Add the attributes in @attrs to the builder, with the exception of those
948  * in the argument list. The attributes are added uncondititionally whether or
949  * not attributes with the same types already exist in the builder.
950  *
951  * The variable arguments must be unsigned longs.
952  *
953  * <informalexample><programlisting>
954  * /<!-- -->* Add all attributes in attrs except CKA_CLASS to the builder *<!-- -->/
955  * gck_builder_add_except (builder, attrs, CKA_CLASS, GCK_INVALID);
956  * </programlisting></informalexample>
957  *
958  * As an optimization, the attribute memory values are automatically shared
959  * between the attributes and the builder.
960  */
961 void
gck_builder_add_except(GckBuilder * builder,GckAttributes * attrs,gulong except_type,...)962 gck_builder_add_except (GckBuilder *builder,
963                         GckAttributes *attrs,
964                         gulong except_type,
965                         ...)
966 {
967 	GArray *types;
968 	va_list va;
969 
970 	g_return_if_fail (builder != NULL);
971 	g_return_if_fail (attrs != NULL);
972 
973 	types = g_array_new (FALSE, FALSE, sizeof (gulong));
974 
975 	va_start (va, except_type);
976 	while (except_type != GCK_INVALID) {
977 		g_array_append_val (types, except_type);
978 		except_type = va_arg (va, gulong);
979 	}
980 	va_end (va);
981 
982 	gck_builder_add_exceptv (builder, attrs, (gulong *)types->data, types->len);
983 	g_array_free (types, TRUE);
984 }
985 
986 /**
987  * gck_builder_add_exceptv: (skip)
988  * @builder: the builder
989  * @attrs: the attributes to add
990  * @except_types: (array length=n_except_types): the except types
991  * @n_except_types: the number of except types
992  *
993  * Add the attributes in @attrs to the builder, with the exception of those
994  * whose types are specified in @except_types. The attributes are added
995  * uncondititionally whether or not attributes with the same types already
996  * exist in the builder.
997  *
998  * <informalexample><programlisting>
999  * /<!-- -->* Add all attributes in attrs except CKA_CLASS to the builder *<!-- -->/
1000  * gulong except_types[] = { CKA_CLASS };
1001  * gck_builder_add_exceptv (builder, attrs, except_types, 1);
1002  * </programlisting></informalexample>
1003  *
1004  * As an optimization, the attribute memory values are automatically shared
1005  * between the attributes and the builder.
1006  */
1007 void
gck_builder_add_exceptv(GckBuilder * builder,GckAttributes * attrs,const gulong * except_types,guint n_except_types)1008 gck_builder_add_exceptv (GckBuilder *builder,
1009                          GckAttributes *attrs,
1010                          const gulong *except_types,
1011                          guint n_except_types)
1012 {
1013 	gulong i;
1014 	guint j;
1015 
1016 	g_return_if_fail (builder != NULL);
1017 	g_return_if_fail (attrs != NULL);
1018 
1019 	for (i = 0; i < attrs->count; i++) {
1020 		for (j = 0; j < n_except_types; j++) {
1021 			if (attrs->data[i].type == except_types[j])
1022 				break;
1023 		}
1024 		if (j == n_except_types)
1025 			builder_copy (builder, &attrs->data[i], FALSE);
1026 	}
1027 }
1028 
1029 /**
1030  * gck_builder_set_all:
1031  * @builder: the builder
1032  * @attrs: the attributes to set
1033  *
1034  * Set all the @attrs attributes to the builder. If any attributes with the
1035  * same types are already present in the builder, then those attributes are
1036  * changed to the new values.
1037  *
1038  * As an optimization, the attribute memory values are automatically shared
1039  * between the attributes and the builder.
1040  */
1041 void
gck_builder_set_all(GckBuilder * builder,GckAttributes * attrs)1042 gck_builder_set_all (GckBuilder *builder,
1043                      GckAttributes *attrs)
1044 {
1045 	gulong i;
1046 
1047 	g_return_if_fail (builder != NULL);
1048 	g_return_if_fail (attrs != NULL);
1049 
1050 	for (i = 0; i < attrs->count; i++)
1051 		builder_copy (builder, &attrs->data[i], TRUE);
1052 }
1053 
1054 /**
1055  * gck_builder_find:
1056  * @builder: the builder
1057  * @attr_type: the type of attribute to find
1058  *
1059  * Find an attribute in the builder. Both valid and invalid attributes (in
1060  * the PKCS\#11 sense) are returned. If multiple attributes exist for the given
1061  * attribute type, then the first one is returned.
1062  *
1063  * The returned #GckAttribute is owned by the builder and may not be modified
1064  * in any way. It is only valid until another attribute is added to or set on
1065  * the builder, or until the builder is cleared or unreferenced.
1066  *
1067  * Returns: the attribute or %NULL if not found
1068  */
1069 const GckAttribute *
gck_builder_find(GckBuilder * builder,gulong attr_type)1070 gck_builder_find (GckBuilder *builder,
1071                   gulong attr_type)
1072 {
1073 	GckRealBuilder *real = (GckRealBuilder *)builder;
1074 
1075 	g_return_val_if_fail (builder != NULL, NULL);
1076 
1077 	if (real->array == NULL)
1078 		return NULL;
1079 
1080 	return find_attribute ((GckAttribute *)real->array->data,
1081 	                       real->array->len, attr_type);
1082 }
1083 
1084 static gboolean
find_attribute_boolean(GckAttribute * attrs,gsize n_attrs,gulong attr_type,gboolean * value)1085 find_attribute_boolean (GckAttribute *attrs,
1086                         gsize n_attrs,
1087                         gulong attr_type,
1088                         gboolean *value)
1089 {
1090 	GckAttribute *attr;
1091 
1092 	attr = find_attribute (attrs, n_attrs, attr_type);
1093 	if (!attr || gck_attribute_is_invalid (attr))
1094 		return FALSE;
1095 	return gck_value_to_boolean (attr->value, attr->length, value);
1096 }
1097 
1098 /**
1099  * gck_builder_find_boolean:
1100  * @builder: the builder
1101  * @attr_type: the type of attribute to find
1102  * @value: (out): the location to place the found value
1103  *
1104  * Find a boolean attribute in the builder that has the type @attr_type, is
1105  * of the correct boolean size, and is not invalid in the PKCS\#11 sense.
1106  * If multiple attributes exist for the given attribute type, then the first\
1107  * one is returned.
1108  *
1109  * Returns: whether a valid boolean attribute was found
1110  */
1111 gboolean
gck_builder_find_boolean(GckBuilder * builder,gulong attr_type,gboolean * value)1112 gck_builder_find_boolean (GckBuilder *builder,
1113                           gulong attr_type,
1114                           gboolean *value)
1115 {
1116 	GckRealBuilder *real = (GckRealBuilder *)builder;
1117 
1118 	g_return_val_if_fail (builder != NULL, FALSE);
1119 	g_return_val_if_fail (value != NULL, FALSE);
1120 
1121 	if (real->array == NULL)
1122 		return FALSE;
1123 
1124 	return find_attribute_boolean ((GckAttribute *)real->array->data,
1125 	                               real->array->len, attr_type, value);
1126 }
1127 
1128 static gboolean
find_attribute_ulong(GckAttribute * attrs,gsize n_attrs,gulong attr_type,gulong * value)1129 find_attribute_ulong (GckAttribute *attrs,
1130                       gsize n_attrs,
1131                       gulong attr_type,
1132                       gulong *value)
1133 {
1134 	GckAttribute *attr;
1135 
1136 	attr = find_attribute (attrs, n_attrs, attr_type);
1137 	if (!attr || gck_attribute_is_invalid (attr))
1138 		return FALSE;
1139 	return gck_value_to_ulong (attr->value, attr->length, value);
1140 }
1141 
1142 /**
1143  * gck_builder_find_ulong:
1144  * @builder: the builder
1145  * @attr_type: the type of attribute to find
1146  * @value: (out): the location to place the found value
1147  *
1148  * Find a unsigned long attribute in the builder that has the type @attr_type,
1149  * is of the correct unsigned long size, and is not invalid in the PKCS\#11 sense.
1150  * If multiple attributes exist for the given attribute type, then the first\
1151  * one is returned.
1152  *
1153  * Returns: whether a valid unsigned long attribute was found
1154  */
1155 gboolean
gck_builder_find_ulong(GckBuilder * builder,gulong attr_type,gulong * value)1156 gck_builder_find_ulong (GckBuilder *builder,
1157                         gulong attr_type,
1158                         gulong *value)
1159 {
1160 	GckRealBuilder *real = (GckRealBuilder *)builder;
1161 
1162 	g_return_val_if_fail (builder != NULL, FALSE);
1163 	g_return_val_if_fail (value != NULL, FALSE);
1164 
1165 	if (real->array == NULL)
1166 		return FALSE;
1167 
1168 	return find_attribute_ulong ((GckAttribute *)real->array->data,
1169 	                             real->array->len, attr_type, value);
1170 }
1171 
1172 static gboolean
find_attribute_string(GckAttribute * attrs,gsize n_attrs,gulong attr_type,gchar ** value)1173 find_attribute_string (GckAttribute *attrs,
1174                        gsize n_attrs,
1175                        gulong attr_type,
1176                        gchar **value)
1177 {
1178 	GckAttribute *attr;
1179 	gchar *string;
1180 
1181 	attr = find_attribute (attrs, n_attrs, attr_type);
1182 	if (!attr || gck_attribute_is_invalid (attr))
1183 		return FALSE;
1184 	string = gck_attribute_get_string (attr);
1185 	if (string == NULL)
1186 		return FALSE;
1187 	*value = string;
1188 	return TRUE;
1189 }
1190 
1191 /**
1192  * gck_builder_find_string:
1193  * @builder: the builder
1194  * @attr_type: the type of attribute to find
1195  * @value: (out): the location to place the found value
1196  *
1197  * Find a string attribute in the builder that has the type @attr_type, has a
1198  * non %NULL value pointer, and is not invalid in the PKCS\#11 sense.
1199  * If multiple attributes exist for the given attribute type, then the first
1200  * one is returned.
1201  *
1202  * Returns: whether a valid string attribute was found
1203  */
1204 gboolean
gck_builder_find_string(GckBuilder * builder,gulong attr_type,gchar ** value)1205 gck_builder_find_string (GckBuilder *builder,
1206                          gulong attr_type,
1207                          gchar **value)
1208 {
1209 	GckRealBuilder *real = (GckRealBuilder *)builder;
1210 
1211 	g_return_val_if_fail (builder != NULL, FALSE);
1212 	g_return_val_if_fail (value != NULL, FALSE);
1213 
1214 	if (real->array == NULL)
1215 		return FALSE;
1216 
1217 	return find_attribute_string ((GckAttribute *)real->array->data,
1218 	                              real->array->len, attr_type, value);
1219 }
1220 
1221 static gboolean
find_attribute_date(GckAttribute * attrs,gsize n_attrs,gulong attr_type,GDate * value)1222 find_attribute_date (GckAttribute *attrs,
1223                      gsize n_attrs,
1224                      gulong attr_type,
1225                      GDate *value)
1226 {
1227 	GckAttribute *attr;
1228 
1229 	attr = find_attribute (attrs, n_attrs, attr_type);
1230 	if (!attr || gck_attribute_is_invalid (attr))
1231 		return FALSE;
1232 	gck_attribute_get_date (attr, value);
1233 	return TRUE;
1234 }
1235 
1236 /**
1237  * gck_builder_find_date:
1238  * @builder: the builder
1239  * @attr_type: the type of attribute to find
1240  * @value: (out): the location to place the found value
1241  *
1242  * Find a date attribute in the builder that has the type @attr_type, is of
1243  * the correct date size, and is not invalid in the PKCS\#11 sense.
1244  * If multiple attributes exist for the given attribute type, then the first
1245  * one is returned.
1246  *
1247  * Returns: whether a valid date attribute was found
1248  */
1249 gboolean
gck_builder_find_date(GckBuilder * builder,gulong attr_type,GDate * value)1250 gck_builder_find_date (GckBuilder *builder,
1251                        gulong attr_type,
1252                        GDate *value)
1253 {
1254 	GckRealBuilder *real = (GckRealBuilder *)builder;
1255 
1256 	g_return_val_if_fail (builder != NULL, FALSE);
1257 	g_return_val_if_fail (value != NULL, FALSE);
1258 
1259 	if (real->array == NULL)
1260 		return FALSE;
1261 
1262 	return find_attribute_date ((GckAttribute *)real->array->data,
1263 	                            real->array->len, attr_type, value);
1264 }
1265 
1266 /**
1267  * gck_builder_steal:
1268  * @builder: the builder
1269  *
1270  * Take the attributes that have been built in the #GckBuilder. The builder
1271  * will no longer contain any attributes after this function call.
1272  *
1273  * The returned set of attributes is a full reference, not floating.
1274  *
1275  * Returns: (transfer full): the stolen attributes, which should be freed with
1276  *          gck_attributes_unref()
1277  */
1278 GckAttributes *
gck_builder_steal(GckBuilder * builder)1279 gck_builder_steal (GckBuilder *builder)
1280 {
1281 	GckRealBuilder *real = (GckRealBuilder *)builder;
1282 	GckAttributes *attrs;
1283 	gpointer data;
1284 	gulong length;
1285 
1286 	g_return_val_if_fail (builder != NULL, NULL);
1287 
1288 	if (real->array) {
1289 		length = real->array->len;
1290 		data = g_array_free (real->array, FALSE);
1291 		real->array = NULL;
1292 	} else {
1293 		length = 0;
1294 		data = NULL;
1295 	}
1296 
1297 	attrs = g_slice_new0 (GckAttributes);
1298 	attrs->count = length;
1299 	attrs->data = data;
1300 	attrs->refs = 1;
1301 
1302 	return attrs;
1303 }
1304 
1305 /**
1306  * gck_builder_end:
1307  * @builder: the builder
1308  *
1309  * Complete the #GckBuilder, and return the attributes contained in the builder.
1310  * The #GckBuilder will be cleared after this function call, and it is no
1311  * longer necessary to use gck_builder_clear() on it, although it is also
1312  * permitted. The builder may be used again to build another set of attributes
1313  * after this function call.
1314  *
1315  * The returned set of attributes is floating, and should either be passed to
1316  * another gck library function which consumes this floating reference, or if
1317  * you wish to keep these attributes around you should ref them with
1318  * gck_attributes_ref_sink() and unref them later with gck_attributes_unref().
1319  *
1320  * Returns: (transfer none): a floating reference to the attributes created
1321  *          in the builder
1322  */
1323 GckAttributes *
gck_builder_end(GckBuilder * builder)1324 gck_builder_end (GckBuilder *builder)
1325 {
1326 	GckRealBuilder *real = (GckRealBuilder *)builder;
1327 	GckAttributes *attrs;
1328 
1329 	g_return_val_if_fail (builder != NULL, NULL);
1330 
1331 	attrs = gck_builder_steal (builder);
1332 	attrs->state |= STATE_FLOATING;
1333 
1334 	g_assert (real->array == NULL);
1335 	return attrs;
1336 }
1337 
1338 /**
1339  * gck_builder_clear:
1340  * @builder: the builder
1341  *
1342  * Clear the builder and release all allocated memory. The builder may be used
1343  * again to build another set of attributes after this function call.
1344  *
1345  * If memory is shared between this builder and other attributes, then that
1346  * memory is only freed when both of them are cleared or unreferenced.
1347  */
1348 void
gck_builder_clear(GckBuilder * builder)1349 gck_builder_clear (GckBuilder *builder)
1350 {
1351 	GckRealBuilder *real = (GckRealBuilder *)builder;
1352 	GckAttribute *attr;
1353 	guint i;
1354 
1355 	g_return_if_fail (builder != NULL);
1356 
1357 	if (real->array == NULL)
1358 		return;
1359 
1360 	for (i = 0; i < real->array->len; i++) {
1361 		attr = &g_array_index (real->array, GckAttribute, i);
1362 		builder_clear (attr);
1363 	}
1364 
1365 	g_array_free (real->array, TRUE);
1366 	real->array = NULL;
1367 }
1368 
1369 /**
1370  * GckAttribute:
1371  * @type: The attribute type, such as CKA_LABEL.
1372  * @value: (array length=length): The value of the attribute. May be %NULL.
1373  * @length: The length of the attribute. May be GCK_INVALID if the attribute is invalid.
1374  *
1375  * This structure represents a PKCS11 CK_ATTRIBUTE.
1376  */
1377 
1378 /**
1379  * gck_attribute_is_invalid:
1380  * @attr: The attribute to check.
1381  *
1382  * Check if the PKCS\#11 attribute represents 'invalid' or 'not found'
1383  * according to the PKCS\#11 spec. That is, having length
1384  * of (CK_ULONG)-1.
1385  *
1386  * Return value: Whether the attribute represents invalid or not.
1387  */
1388 gboolean
gck_attribute_is_invalid(const GckAttribute * attr)1389 gck_attribute_is_invalid (const GckAttribute *attr)
1390 {
1391 	g_return_val_if_fail (attr, TRUE);
1392 	return attr->length == (gulong)-1;
1393 }
1394 
1395 /**
1396  * gck_attribute_get_boolean:
1397  * @attr: The attribute to retrieve value from.
1398  *
1399  * Get the CK_BBOOL of a PKCS\#11 attribute. No conversion
1400  * is performed. It is an error to pass an attribute to this
1401  * function unless you're know it's supposed to contain a
1402  * boolean value.
1403  *
1404  * Return value: The boolean value of the attribute.
1405  */
1406 gboolean
gck_attribute_get_boolean(const GckAttribute * attr)1407 gck_attribute_get_boolean (const GckAttribute *attr)
1408 {
1409 	gboolean value;
1410 
1411 	g_return_val_if_fail (attr, FALSE);
1412 	if (gck_attribute_is_invalid (attr))
1413 		return FALSE;
1414 	if (!gck_value_to_boolean (attr->value, attr->length, &value))
1415 		g_return_val_if_reached (FALSE);
1416 	return value;
1417 }
1418 
1419 /**
1420  * gck_attribute_get_ulong:
1421  * @attr: The attribute to retrieve value from.
1422  *
1423  * Get the CK_ULONG value of a PKCS\#11 attribute. No
1424  * conversion is performed. It is an error to pass an attribute
1425  * to this function unless you're know it's supposed to contain
1426  * a value of the right type.
1427  *
1428  * Return value: The ulong value of the attribute.
1429  */
1430 gulong
gck_attribute_get_ulong(const GckAttribute * attr)1431 gck_attribute_get_ulong (const GckAttribute *attr)
1432 {
1433 	gulong value;
1434 
1435 	g_return_val_if_fail (attr, FALSE);
1436 	if (gck_attribute_is_invalid (attr))
1437 		return 0;
1438 	if (!gck_value_to_ulong (attr->value, attr->length, &value))
1439 		g_return_val_if_reached ((gulong)-1);
1440 	return value;
1441 }
1442 
1443 /**
1444  * gck_attribute_get_string:
1445  * @attr: The attribute to retrieve value from.
1446  *
1447  * Get the string value of a PKCS\#11 attribute. No
1448  * conversion is performed. It is an error to pass an attribute
1449  * to this function unless you're know it's supposed to contain
1450  * a value of the right type.
1451  *
1452  * Return value: (nullable): a null terminated string, to be freed with
1453  *               g_free(), or %NULL if the value was invalid
1454  */
1455 gchar*
gck_attribute_get_string(const GckAttribute * attr)1456 gck_attribute_get_string (const GckAttribute *attr)
1457 {
1458 	g_return_val_if_fail (attr, NULL);
1459 
1460 	if (gck_attribute_is_invalid (attr))
1461 		return NULL;
1462 	if (!attr->value)
1463 		return NULL;
1464 
1465 	return g_strndup ((gchar*)attr->value, attr->length);
1466 }
1467 
1468 /**
1469  * gck_attribute_get_date:
1470  * @attr: The attribute to retrieve value from.
1471  * @value: The date value to fill in with the parsed date.
1472  *
1473  * Get the CK_DATE of a PKCS\#11 attribute. No
1474  * conversion is performed. It is an error to pass an attribute
1475  * to this function unless you're know it's supposed to contain
1476  * a value of the right type.
1477  */
1478 void
gck_attribute_get_date(const GckAttribute * attr,GDate * value)1479 gck_attribute_get_date (const GckAttribute *attr,
1480                         GDate *value)
1481 {
1482 	guint year, month, day;
1483 	gchar buffer[5];
1484 	CK_DATE *date;
1485 	gchar *end;
1486 
1487 	g_return_if_fail (attr);
1488 
1489 	if (gck_attribute_is_invalid (attr)) {
1490 		g_date_clear (value, 1);
1491 		return;
1492 	}
1493 
1494 	g_return_if_fail (attr->length == sizeof (CK_DATE));
1495 	g_return_if_fail (attr->value);
1496 	date = (CK_DATE*)attr->value;
1497 
1498 	memset (&buffer, 0, sizeof (buffer));
1499 	memcpy (buffer, date->year, 4);
1500 	year = strtol (buffer, &end, 10);
1501 	g_return_if_fail (end != buffer && !*end);
1502 
1503 	memset (&buffer, 0, sizeof (buffer));
1504 	memcpy (buffer, date->month, 2);
1505 	month = strtol (buffer, &end, 10);
1506 	g_return_if_fail (end != buffer && !*end);
1507 
1508 	memset (&buffer, 0, sizeof (buffer));
1509 	memcpy (buffer, date->day, 2);
1510 	day = strtol (buffer, &end, 10);
1511 	g_return_if_fail (end != buffer && !*end);
1512 
1513 	g_date_set_dmy (value, day, month, year);
1514 }
1515 
1516 /**
1517  * gck_attribute_get_data:
1518  * @attr: an attribute
1519  * @length: the length of the returned data
1520  *
1521  * Get the raw value in the attribute.
1522  *
1523  * This is useful from scripting languages. C callers will generally
1524  * access the #GckAttribute struct directly.
1525  *
1526  * This function will %NULL if the attribute contains empty or invalid
1527  * data. The returned data must not be modified and is only valid
1528  * as long as this @attribute.
1529  *
1530  * Returns: (transfer none) (array length=length): the value data or %NULL
1531  */
1532 const guchar *
gck_attribute_get_data(const GckAttribute * attr,gsize * length)1533 gck_attribute_get_data (const GckAttribute *attr,
1534                         gsize *length)
1535 {
1536 	g_return_val_if_fail (attr != NULL, NULL);
1537 
1538 	if (attr->length == G_MAXULONG) {
1539 		*length = 0;
1540 		return NULL;
1541 	}
1542 	*length = attr->length;
1543 	return attr->value;
1544 }
1545 
1546 /**
1547  * gck_attribute_init: (skip)
1548  * @attr: an uninitialized attribute
1549  * @attr_type: the PKCS\#11 attribute type to set on the attribute
1550  * @value: (array length=length): The raw value of the attribute.
1551  * @length: The length of the raw value.
1552  *
1553  * Initialize a PKCS\#11 attribute. This copies the value memory
1554  * into an internal buffer.
1555  *
1556  * When done with the attribute you should use gck_attribute_clear()
1557  * to free the internal memory.
1558  **/
1559 void
gck_attribute_init(GckAttribute * attr,gulong attr_type,const guchar * value,gsize length)1560 gck_attribute_init (GckAttribute *attr,
1561                     gulong attr_type,
1562                     const guchar *value,
1563                     gsize length)
1564 {
1565 	g_return_if_fail (attr != NULL);
1566 
1567 	attr->type = attr_type;
1568 	if (length == G_MAXULONG) {
1569 		attr->value = NULL;
1570 		attr->length = G_MAXULONG;
1571 	} else if (value == NULL) {
1572 		attr->value = NULL;
1573 		attr->length = 0;
1574 	} else {
1575 		attr->value = value_new (value, length, egg_secure_check (value));
1576 		attr->length = length;
1577 	}
1578 }
1579 
1580 /**
1581  * gck_attribute_init_invalid: (skip)
1582  * @attr: an uninitialized attribute
1583  * @attr_type: the PKCS\#11 attribute type to set on the attribute
1584  *
1585  * Initialize a PKCS\#11 attribute to an 'invalid' or 'not found'
1586  * state. Specifically this sets the value length to (CK_ULONG)-1
1587  * as specified in the PKCS\#11 specification.
1588  *
1589  * When done with the attribute you should use gck_attribute_clear()
1590  * to free the internal memory.
1591  **/
1592 void
gck_attribute_init_invalid(GckAttribute * attr,gulong attr_type)1593 gck_attribute_init_invalid (GckAttribute *attr,
1594                             gulong attr_type)
1595 {
1596 	g_return_if_fail (attr != NULL);
1597 	attr->type = attr_type;
1598 	attr->value = NULL;
1599 	attr->length = G_MAXULONG;
1600 }
1601 
1602 /**
1603  * gck_attribute_init_empty: (skip)
1604  * @attr: an uninitialized attribute
1605  * @attr_type: the PKCS\#11 attribute type to set on the attribute
1606  *
1607  * Initialize a PKCS\#11 attribute to an empty state. The attribute
1608  * type will be set, but no data will be set.
1609  *
1610  * When done with the attribute you should use gck_attribute_clear()
1611  * to free the internal memory.
1612  **/
1613 void
gck_attribute_init_empty(GckAttribute * attr,gulong attr_type)1614 gck_attribute_init_empty (GckAttribute *attr, gulong attr_type)
1615 {
1616 	g_return_if_fail (attr != NULL);
1617 
1618 	attr->type = attr_type;
1619 	attr->length = 0;
1620 	attr->value = 0;
1621 }
1622 
1623 /**
1624  * gck_attribute_init_boolean: (skip)
1625  * @attr: an uninitialized attribute
1626  * @attr_type: the PKCS\#11 attribute type to set on the attribute
1627  * @value: the boolean value of the attribute
1628  *
1629  * Initialize a PKCS\#11 attribute to boolean. This will result
1630  * in a CK_BBOOL attribute from the PKCS\#11 specs.
1631  *
1632  * When done with the attribute you should use gck_attribute_clear()
1633  * to free the internal memory.
1634  **/
1635 void
gck_attribute_init_boolean(GckAttribute * attr,gulong attr_type,gboolean value)1636 gck_attribute_init_boolean (GckAttribute *attr,
1637                             gulong attr_type,
1638                             gboolean value)
1639 {
1640 	CK_BBOOL val = value ? CK_TRUE : CK_FALSE;
1641 	g_return_if_fail (attr != NULL);
1642 	gck_attribute_init (attr, attr_type, &val, sizeof (val));
1643 }
1644 
1645 /**
1646  * gck_attribute_init_date: (skip)
1647  * @attr: an uninitialized attribute
1648  * @attr_type: the PKCS\#11 attribute type to set on the attribute
1649  * @value: the date value of the attribute
1650  *
1651  * Initialize a PKCS\#11 attribute to a date. This will result
1652  * in a CK_DATE attribute from the PKCS\#11 specs.
1653  *
1654  * When done with the attribute you should use gck_attribute_clear()
1655  * to free the internal memory.
1656  **/
1657 void
gck_attribute_init_date(GckAttribute * attr,gulong attr_type,const GDate * value)1658 gck_attribute_init_date (GckAttribute *attr,
1659                          gulong attr_type,
1660                          const GDate *value)
1661 {
1662 	CK_DATE date;
1663 
1664 	g_return_if_fail (attr != NULL);
1665 	g_return_if_fail (value != NULL);
1666 
1667 	convert_gdate_to_ckdate (value, &date);
1668 	gck_attribute_init (attr, attr_type, (const guchar *)&date, sizeof (CK_DATE));
1669 }
1670 
1671 /**
1672  * gck_attribute_init_ulong: (skip)
1673  * @attr: an uninitialized attribute
1674  * @attr_type: the PKCS\#11 attribute type to set on the attribute
1675  * @value: the ulong value of the attribute
1676  *
1677  * Initialize a PKCS\#11 attribute to a unsigned long. This will result
1678  * in a CK_ULONG attribute from the PKCS\#11 specs.
1679  *
1680  * When done with the attribute you should use gck_attribute_clear()
1681  * to free the internal memory.
1682  **/
1683 void
gck_attribute_init_ulong(GckAttribute * attr,gulong attr_type,gulong value)1684 gck_attribute_init_ulong (GckAttribute *attr,
1685                           gulong attr_type,
1686                           gulong value)
1687 {
1688 	CK_ULONG val = value;
1689 	g_return_if_fail (attr != NULL);
1690 	gck_attribute_init (attr, attr_type, (const guchar *)&val, sizeof (val));
1691 }
1692 
1693 /**
1694  * gck_attribute_init_string: (skip)
1695  * @attr: an uninitialized attribute
1696  * @attr_type: the PKCS\#11 attribute type to set on the attribute
1697  * @value: the null terminated string value of the attribute
1698  *
1699  * Initialize a PKCS\#11 attribute to a string. This will result
1700  * in an attribute containing the text, but not the null terminator.
1701  * The text in the attribute will be of the same encoding as you pass
1702  * to this function.
1703  *
1704  * When done with the attribute you should use gck_attribute_clear()
1705  * to free the internal memory.
1706  **/
1707 void
gck_attribute_init_string(GckAttribute * attr,gulong attr_type,const gchar * value)1708 gck_attribute_init_string (GckAttribute *attr,
1709                            gulong attr_type,
1710                            const gchar *value)
1711 {
1712 	g_return_if_fail (attr != NULL);
1713 	gck_attribute_init (attr, attr_type, (const guchar *)value,
1714 	                    value ? strlen (value) : 0);
1715 }
1716 
G_DEFINE_BOXED_TYPE(GckAttribute,gck_attribute,gck_attribute_dup,gck_attribute_free)1717 G_DEFINE_BOXED_TYPE (GckAttribute, gck_attribute,
1718                      gck_attribute_dup, gck_attribute_free)
1719 
1720 /**
1721  * gck_attribute_new:
1722  * @attr_type: the PKCS\#11 attribute type to set on the attribute
1723  * @value: the raw value of the attribute
1724  * @length: the length of the attribute
1725  *
1726  * Create a new PKCS\#11 attribute. The value will be copied
1727  * into the new attribute.
1728  *
1729  * Returns: (transfer full): the new attribute; when done with the attribute
1730  *          use gck_attribute_free() to free it
1731  **/
1732 GckAttribute *
1733 gck_attribute_new (gulong attr_type,
1734                    const guchar *value,
1735                    gsize length)
1736 {
1737 	GckAttribute *attr = g_slice_new0 (GckAttribute);
1738 	gck_attribute_init (attr, attr_type, value, length);
1739 	return attr;
1740 }
1741 
1742 /**
1743  * gck_attribute_new_invalid:
1744  * @attr_type: the PKCS\#11 attribute type to set on the attribute
1745  *
1746  * Create a new PKCS\#11 attribute as 'invalid' or 'not found'
1747  * state. Specifically this sets the value length to (CK_ULONG)-1
1748  * as specified in the PKCS\#11 specification.
1749  *
1750  * Returns: (transfer full): the new attribute; when done with the attribute
1751  *          use gck_attribute_free() to free it
1752  **/
1753 GckAttribute *
gck_attribute_new_invalid(gulong attr_type)1754 gck_attribute_new_invalid (gulong attr_type)
1755 {
1756 	GckAttribute *attr = g_slice_new0 (GckAttribute);
1757 	gck_attribute_init_invalid (attr, attr_type);
1758 	return attr;
1759 }
1760 
1761 /**
1762  * gck_attribute_new_empty:
1763  * @attr_type: the PKCS\#11 attribute type to set on the attribute
1764  *
1765  * Create a new PKCS\#11 attribute with empty data.
1766  *
1767  * Returns: (transfer full): the new attribute; when done with the attribute
1768  *          use gck_attribute_free() to free it
1769  */
1770 GckAttribute *
gck_attribute_new_empty(gulong attr_type)1771 gck_attribute_new_empty (gulong attr_type)
1772 {
1773 	GckAttribute *attr = g_slice_new0 (GckAttribute);
1774 	gck_attribute_init_empty (attr, attr_type);
1775 	return attr;
1776 }
1777 
1778 /**
1779  * gck_attribute_new_boolean:
1780  * @attr_type: the PKCS\#11 attribute type to set on the attribute
1781  * @value: the boolean value of the attribute
1782  *
1783  * Initialize a PKCS\#11 attribute to boolean. This will result
1784  * in a CK_BBOOL attribute from the PKCS\#11 specs.
1785  *
1786  * Returns: (transfer full): the new attribute; when done with the attribute u
1787  *          gck_attribute_free() to free it
1788  **/
1789 GckAttribute *
gck_attribute_new_boolean(gulong attr_type,gboolean value)1790 gck_attribute_new_boolean (gulong attr_type,
1791                            gboolean value)
1792 {
1793 	GckAttribute *attr = g_slice_new0 (GckAttribute);
1794 	gck_attribute_init_boolean (attr, attr_type, value);
1795 	return attr;
1796 }
1797 
1798 /**
1799  * gck_attribute_new_date:
1800  * @attr_type: the PKCS\#11 attribute type to set on the attribute
1801  * @value: the date value of the attribute
1802  *
1803  * Initialize a PKCS\#11 attribute to a date. This will result
1804  * in a CK_DATE attribute from the PKCS\#11 specs.
1805  *
1806  * Returns: (transfer full): the new attribute; when done with the attribute u
1807  *          gck_attribute_free() to free it
1808  **/
1809 GckAttribute *
gck_attribute_new_date(gulong attr_type,const GDate * value)1810 gck_attribute_new_date (gulong attr_type,
1811                         const GDate *value)
1812 {
1813 	GckAttribute *attr = g_slice_new0 (GckAttribute);
1814 	gck_attribute_init_date (attr, attr_type, value);
1815 	return attr;
1816 }
1817 
1818 /**
1819  * gck_attribute_new_ulong:
1820  * @attr_type: the PKCS\#11 attribute type to set on the attribute
1821  * @value: the ulong value of the attribute
1822  *
1823  * Initialize a PKCS\#11 attribute to a unsigned long. This will result
1824  * in a CK_ULONG attribute from the PKCS\#11 specs.
1825  *
1826  * Returns: (transfer full): the new attribute; when done with the attribute u
1827  *          gck_attribute_free() to free it
1828  **/
1829 GckAttribute *
gck_attribute_new_ulong(gulong attr_type,gulong value)1830 gck_attribute_new_ulong (gulong attr_type,
1831                          gulong value)
1832 {
1833 	GckAttribute *attr = g_slice_new0 (GckAttribute);
1834 	gck_attribute_init_ulong (attr, attr_type, value);
1835 	return attr;
1836 }
1837 
1838 /**
1839  * gck_attribute_new_string:
1840  * @attr_type: the PKCS\#11 attribute type to set on the attribute
1841  * @value: the null-terminated string value of the attribute
1842  *
1843  * Initialize a PKCS\#11 attribute to a string. This will result
1844  * in an attribute containing the text, but not the null terminator.
1845  * The text in the attribute will be of the same encoding as you pass
1846  * to this function.
1847  *
1848  * Returns: (transfer full): the new attribute; when done with the attribute u
1849  *          gck_attribute_free() to free it
1850  **/
1851 GckAttribute *
gck_attribute_new_string(gulong attr_type,const gchar * value)1852 gck_attribute_new_string (gulong attr_type,
1853                           const gchar *value)
1854 {
1855 	GckAttribute *attr = g_slice_new0 (GckAttribute);
1856 	gck_attribute_init_string (attr, attr_type, value);
1857 	return attr;
1858 }
1859 
1860 /**
1861  * gck_attribute_dup:
1862  * @attr: the attribute to duplicate
1863  *
1864  * Duplicate the PKCS\#11 attribute. All value memory is
1865  * also copied.
1866  *
1867  * The @attr must have been allocated or initialized by a Gck function or
1868  * the results of this function are undefined.
1869  *
1870  * Returns: (transfer full): the duplicated attribute; use gck_attribute_free()
1871  *          to free it
1872  */
1873 GckAttribute *
gck_attribute_dup(const GckAttribute * attr)1874 gck_attribute_dup (const GckAttribute *attr)
1875 {
1876 	GckAttribute *copy;
1877 
1878 	if (!attr)
1879 		return NULL;
1880 
1881 	copy = g_slice_new0 (GckAttribute);
1882 	gck_attribute_init_copy (copy, attr);
1883 	return copy;
1884 }
1885 
1886 /**
1887  * gck_attribute_init_copy:
1888  * @dest: An uninitialized attribute.
1889  * @src: An attribute to copy.
1890  *
1891  * Initialize a PKCS\#11 attribute as a copy of another attribute.
1892  * This copies the value memory as well.
1893  *
1894  * When done with the copied attribute you should use
1895  * gck_attribute_clear() to free the internal memory.
1896  **/
1897 void
gck_attribute_init_copy(GckAttribute * dest,const GckAttribute * src)1898 gck_attribute_init_copy (GckAttribute *dest,
1899                          const GckAttribute *src)
1900 {
1901 	g_return_if_fail (dest != NULL);
1902 	g_return_if_fail (src != NULL);
1903 
1904 	dest->type = src->type;
1905 	if (src->length == G_MAXULONG) {
1906 		dest->value = NULL;
1907 		dest->length = G_MAXULONG;
1908 	} else if (src->value == NULL) {
1909 		dest->value = NULL;
1910 		dest->length = 0;
1911 	} else {
1912 		dest->value = value_ref (src->value);
1913 		dest->length = src->length;
1914 	}
1915 }
1916 
1917 /**
1918  * gck_attribute_clear:
1919  * @attr: Attribute to clear.
1920  *
1921  * Clear allocated memory held by a #GckAttribute.
1922  *
1923  * This attribute must have been allocated by a Gck library function, or
1924  * the results of this method are undefined.
1925  *
1926  * The type of the attribute will remain set.
1927  **/
1928 void
gck_attribute_clear(GckAttribute * attr)1929 gck_attribute_clear (GckAttribute *attr)
1930 {
1931 	g_return_if_fail (attr != NULL);
1932 
1933 	if (attr->value != NULL)
1934 		value_unref (attr->value);
1935 	attr->value = NULL;
1936 	attr->length = 0;
1937 }
1938 
1939 /**
1940  * gck_attribute_free:
1941  * @attr: (type Gck.Attribute): attribute to free
1942  *
1943  * Free an attribute and its allocated memory. These is usually
1944  * used with attributes that are allocated by gck_attribute_new()
1945  * or a similar function.
1946  **/
1947 void
gck_attribute_free(gpointer attr)1948 gck_attribute_free (gpointer attr)
1949 {
1950 	GckAttribute *a = attr;
1951 	if (attr) {
1952 		gck_attribute_clear (a);
1953 		g_slice_free (GckAttribute, a);
1954 	}
1955 }
1956 
1957 /**
1958  * gck_attribute_equal:
1959  * @attr1: (type Gck.Attribute): first attribute to compare
1960  * @attr2: (type Gck.Attribute): second attribute to compare
1961  *
1962  * Compare two attributes. Useful with <code>GHashTable</code>.
1963  *
1964  * Returns: %TRUE if the attributes are equal.
1965  */
1966 gboolean
gck_attribute_equal(gconstpointer attr1,gconstpointer attr2)1967 gck_attribute_equal (gconstpointer attr1,
1968                      gconstpointer attr2)
1969 {
1970 	const GckAttribute *aa = attr1;
1971 	const GckAttribute *ab = attr2;
1972 
1973 	if (!aa && !ab)
1974 		return TRUE;
1975 	if (!aa || !ab)
1976 		return FALSE;
1977 
1978 	if (aa->type != ab->type)
1979 		return FALSE;
1980 	if (aa->length != ab->length)
1981 		return FALSE;
1982 	if (!aa->value && !ab->value)
1983 		return TRUE;
1984 	if (!aa->value || !ab->value)
1985 		return FALSE;
1986 	return memcmp (aa->value, ab->value, aa->length) == 0;
1987 }
1988 
1989 /**
1990  * gck_attribute_hash:
1991  * @attr: (type Gck.Attribute): attribute to hash
1992  *
1993  * Hash an attribute for use in <code>GHashTable</code> keys.
1994  *
1995  * Returns: the hash code
1996  */
1997 guint
gck_attribute_hash(gconstpointer attr)1998 gck_attribute_hash (gconstpointer attr)
1999 {
2000 	const GckAttribute *a = attr;
2001 	const signed char *p, *e;
2002 	guint32 h = 5381;
2003 
2004 	h ^= _gck_ulong_hash (&a->type);
2005 
2006 	if (a->value) {
2007 		for (p = (signed char *)a->value, e = p + a->length; p != e; p++)
2008 			h = (h << 5) + h + *p;
2009 	}
2010 
2011 	return h;
2012 }
2013 
2014 /**
2015  * SECTION:gck-attributes
2016  * @title: GckAttributes
2017  * @short_description: A set of PKCS11 attributes.
2018  *
2019  * A set of GckAttribute structures. These attributes contain information
2020  * about a PKCS11 object. Use gck_object_get() or gck_object_set() to set and retrieve
2021  * attributes on an object.
2022  */
2023 
2024 /**
2025  * GckAttributes:
2026  *
2027  * A set of GckAttribute structures.
2028  */
2029 
2030 /**
2031  * GckAllocator:
2032  * @data: Memory to allocate or deallocate.
2033  * @length: New length of memory.
2034  *
2035  * An allocator used to allocate data for the attributes in this GckAttributes set.
2036  *
2037  * This is a function that acts like g_realloc. Specifically it frees when length is
2038  * set to zero, it allocates when data is set to %NULL, and it reallocates when both
2039  * are valid.
2040  *
2041  * Returns: The allocated memory, or %NULL when freeing.
2042  **/
2043 
G_DEFINE_BOXED_TYPE(GckAttributes,gck_attributes,gck_attributes_ref,gck_attributes_unref)2044 G_DEFINE_BOXED_TYPE (GckAttributes, gck_attributes,
2045                      gck_attributes_ref, gck_attributes_unref)
2046 
2047 GType
2048 gck_attributes_get_boxed_type (void)
2049 {
2050 	/* Deprecated version */
2051 	return gck_attributes_get_type ();
2052 }
2053 
2054 /**
2055  * gck_attributes_new_empty:
2056  * @first_type: the first empty attribute type
2057  * @...: the other empty attribute types
2058  *
2059  * Creates an GckAttributes array with empty attributes
2060  *
2061  * Terminate the argument list with %GCK_INVALID.
2062  *
2063  * The returned set of attributes is floating, and should either be passed to
2064  * another gck library function which consumes this floating reference, or if
2065  * you wish to keep these attributes around you should ref them with
2066  * gck_attributes_ref_sink() and unref them later with gck_attributes_unref().
2067  *
2068  * Returns: (transfer none): a floating reference to an empty set of attributes
2069  **/
2070 GckAttributes *
gck_attributes_new_empty(gulong first_type,...)2071 gck_attributes_new_empty (gulong first_type,
2072                           ...)
2073 {
2074 	GckBuilder builder = GCK_BUILDER_INIT;
2075 	va_list va;
2076 
2077 	va_start (va, first_type);
2078 
2079 	while (first_type != GCK_INVALID) {
2080 		gck_builder_add_empty (&builder, first_type);
2081 		first_type = va_arg (va, gulong);
2082 	}
2083 
2084 	va_end (va);
2085 	return gck_builder_end (&builder);
2086 }
2087 
2088 /**
2089  * gck_attributes_at:
2090  * @attrs: The attributes array.
2091  * @index: The attribute index to retrieve.
2092  *
2093  * Get attribute at the specified index in the attribute array.
2094  *
2095  * Use gck_attributes_count() to determine how many attributes are
2096  * in the array.
2097  *
2098  * Returns: (transfer none): the specified attribute
2099  **/
2100 const GckAttribute *
gck_attributes_at(GckAttributes * attrs,guint index)2101 gck_attributes_at (GckAttributes *attrs,
2102                    guint index)
2103 {
2104 	g_return_val_if_fail (attrs != NULL, NULL);
2105 	g_return_val_if_fail (index < attrs->count, NULL);
2106 	return attrs->data + index;
2107 }
2108 
2109 /**
2110  * gck_attributes_count:
2111  * @attrs: The attributes array to count.
2112  *
2113  * Get the number of attributes in this attribute array.
2114  *
2115  * Return value: The number of contained attributes.
2116  **/
2117 gulong
gck_attributes_count(GckAttributes * attrs)2118 gck_attributes_count (GckAttributes *attrs)
2119 {
2120 	g_return_val_if_fail (attrs != NULL, 0);
2121 	return attrs->count;
2122 }
2123 
2124 /**
2125  * gck_attributes_find:
2126  * @attrs: The attributes array to search.
2127  * @attr_type: The type of attribute to find.
2128  *
2129  * Find an attribute with the specified type in the array.
2130  *
2131  * Returns: (transfer none): the first attribute found with the specified type,
2132  *          or %NULL
2133  **/
2134 const GckAttribute *
gck_attributes_find(GckAttributes * attrs,gulong attr_type)2135 gck_attributes_find (GckAttributes *attrs,
2136                      gulong attr_type)
2137 {
2138 	g_return_val_if_fail (attrs != NULL, NULL);
2139 
2140 	return find_attribute (attrs->data, attrs->count, attr_type);
2141 }
2142 
2143 /**
2144  * gck_attributes_find_boolean:
2145  * @attrs: The attributes array to search.
2146  * @attr_type: The type of attribute to find.
2147  * @value: (out): The resulting gboolean value.
2148  *
2149  * Find an attribute with the specified type in the array.
2150  *
2151  * The attribute (if found) must be of the right size to store
2152  * a boolean value (ie: CK_BBOOL). If the attribute is marked invalid
2153  * then it will be treated as not found.
2154  *
2155  * Return value: Whether a value was found or not.
2156  **/
2157 gboolean
gck_attributes_find_boolean(GckAttributes * attrs,gulong attr_type,gboolean * value)2158 gck_attributes_find_boolean (GckAttributes *attrs, gulong attr_type, gboolean *value)
2159 {
2160 	g_return_val_if_fail (attrs != NULL, FALSE);
2161 	g_return_val_if_fail (value, FALSE);
2162 
2163 	return find_attribute_boolean (attrs->data, attrs->count, attr_type, value);
2164 }
2165 
2166 /**
2167  * gck_attributes_find_ulong:
2168  * @attrs: The attributes array to search.
2169  * @attr_type: The type of attribute to find.
2170  * @value: (out): The resulting gulong value.
2171  *
2172  * Find an attribute with the specified type in the array.
2173  *
2174  * The attribute (if found) must be of the right size to store
2175  * a unsigned long value (ie: CK_ULONG). If the attribute is marked invalid
2176  * then it will be treated as not found.
2177  *
2178  * Return value: Whether a value was found or not.
2179  **/
2180 gboolean
gck_attributes_find_ulong(GckAttributes * attrs,gulong attr_type,gulong * value)2181 gck_attributes_find_ulong (GckAttributes *attrs, gulong attr_type, gulong *value)
2182 {
2183 	g_return_val_if_fail (attrs != NULL, FALSE);
2184 	g_return_val_if_fail (value, FALSE);
2185 
2186 	return find_attribute_ulong (attrs->data, attrs->count, attr_type, value);
2187 }
2188 
2189 /**
2190  * gck_attributes_find_string:
2191  * @attrs: The attributes array to search.
2192  * @attr_type: The type of attribute to find.
2193  * @value: (out): The resulting string value.
2194  *
2195  * Find an attribute with the specified type in the array.
2196  *
2197  * If the attribute is marked invalid then it will be treated as not found.
2198  * The resulting string will be null-terminated, and must be freed by the caller
2199  * using g_free().
2200  *
2201  * Return value: Whether a value was found or not.
2202  **/
2203 gboolean
gck_attributes_find_string(GckAttributes * attrs,gulong attr_type,gchar ** value)2204 gck_attributes_find_string (GckAttributes *attrs, gulong attr_type, gchar **value)
2205 {
2206 	g_return_val_if_fail (attrs != NULL, FALSE);
2207 	g_return_val_if_fail (value, FALSE);
2208 
2209 	return find_attribute_string (attrs->data, attrs->count, attr_type, value);
2210 }
2211 
2212 /**
2213  * gck_attributes_find_date:
2214  * @attrs: The attributes array to search.
2215  * @attr_type: The type of attribute to find.
2216  * @value: (out): The resulting GDate value.
2217  *
2218  * Find an attribute with the specified type in the array.
2219  *
2220  * The attribute (if found) must be of the right size to store
2221  * a date value (ie: CK_DATE). If the attribute is marked invalid
2222  * then it will be treated as not found.
2223  *
2224  * Return value: Whether a value was found or not.
2225  **/
2226 gboolean
gck_attributes_find_date(GckAttributes * attrs,gulong attr_type,GDate * value)2227 gck_attributes_find_date (GckAttributes *attrs, gulong attr_type, GDate *value)
2228 {
2229 	g_return_val_if_fail (attrs != NULL, FALSE);
2230 	g_return_val_if_fail (value, FALSE);
2231 
2232 	return find_attribute_date (attrs->data, attrs->count, attr_type, value);
2233 }
2234 
2235 /**
2236  * gck_attributes_ref:
2237  * @attrs: An attribute array
2238  *
2239  * Reference this attributes array.
2240  *
2241  * Returns: the attributes
2242  **/
2243 GckAttributes *
gck_attributes_ref(GckAttributes * attrs)2244 gck_attributes_ref (GckAttributes *attrs)
2245 {
2246 	g_return_val_if_fail (attrs, NULL);
2247 	g_atomic_int_inc (&attrs->refs);
2248 	return attrs;
2249 }
2250 
2251 /**
2252  * gck_attributes_ref_sink:
2253  * @attrs: an attribute array
2254  *
2255  * #GckAttributes uses a floating reference count system. gck_builder_end()
2256  * and gck_attributes_new_empty() both return floating references.
2257  *
2258  * Calling gck_attributes_ref_sink() on a #GckAttributes with a floating
2259  * reference will convert the floating reference into a full reference.
2260  * Calling gck_attributes_ref_sink() on a non-floating #GckAttributes results
2261  * in an additional normal reference being added.
2262  *
2263  * In other words, if the @attrs is floating, then this call "assumes
2264  * ownership" of the floating reference, converting it to a normal
2265  * reference.  If the @attrs is not floating, then this call adds a
2266  * new normal reference increasing the reference count by one.
2267  *
2268  * All Gck library functions that assume ownership of floating references
2269  * are documented as such. Essentially any Gck function that performs
2270  * an operation using a #GckAttributes argument rather than operating on the
2271  * atributes themselves, will accept a floating reference.
2272  *
2273  * Returns: the referenced attributes
2274  */
2275 GckAttributes *
gck_attributes_ref_sink(GckAttributes * attrs)2276 gck_attributes_ref_sink (GckAttributes *attrs)
2277 {
2278 	g_return_val_if_fail (attrs, NULL);
2279 	g_bit_lock (&attrs->state, STATE_LOCKED);
2280 
2281 	if (~attrs->state & STATE_FLOATING)
2282 		gck_attributes_ref (attrs);
2283 	else
2284 		attrs->state &= ~STATE_FLOATING;
2285 
2286 	g_bit_unlock (&attrs->state, STATE_LOCKED);
2287 	return attrs;
2288 }
2289 
2290 /**
2291  * gck_attributes_unref:
2292  * @attrs: (nullable) (type Gck.Attributes): An attribute array
2293  *
2294  * Unreference this attribute array.
2295  *
2296  * When all outstanding references are gone, the array will be freed.
2297  */
2298 void
gck_attributes_unref(gpointer attrs)2299 gck_attributes_unref (gpointer attrs)
2300 {
2301 	GckAttributes *attrs_ = attrs;
2302 	const GckAttribute *attr;
2303 	guint i;
2304 
2305 	if (!attrs_)
2306 		return;
2307 
2308 	if (g_atomic_int_dec_and_test (&attrs_->refs)) {
2309 		for (i = 0; i < attrs_->count; ++i) {
2310 			attr = gck_attributes_at (attrs_, i);
2311 			if (attr->value)
2312 				value_unref (attr->value);
2313 		}
2314 		g_free (attrs_->data);
2315 		g_slice_free (GckAttributes, attrs_);
2316 	}
2317 }
2318 
2319 /**
2320  * gck_attributes_contains:
2321  * @attrs: The attributes to check
2322  * @match: The attribute to find
2323  *
2324  * Check whether the attributes contain a certain attribute.
2325  *
2326  * Returns: %TRUE if the attributes contain the attribute.
2327  */
2328 gboolean
gck_attributes_contains(GckAttributes * attrs,const GckAttribute * match)2329 gck_attributes_contains (GckAttributes *attrs,
2330                          const GckAttribute *match)
2331 {
2332 	const GckAttribute *attr;
2333 	guint i;
2334 
2335 	g_return_val_if_fail (attrs != NULL, FALSE);
2336 
2337 	for (i = 0; i < attrs->count; ++i) {
2338 		attr = gck_attributes_at (attrs, i);
2339 		if (gck_attribute_equal (attr, match))
2340 			return TRUE;
2341 	}
2342 
2343 	return FALSE;
2344 }
2345 
2346 CK_ATTRIBUTE_PTR
_gck_builder_prepare_in(GckBuilder * builder,CK_ULONG_PTR n_attrs)2347 _gck_builder_prepare_in (GckBuilder *builder,
2348                          CK_ULONG_PTR n_attrs)
2349 {
2350 	GckRealBuilder *real = (GckRealBuilder *)builder;
2351 	GckAttribute *attr;
2352 	guint i;
2353 
2354 	g_return_val_if_fail (builder != NULL, NULL);
2355 	g_return_val_if_fail (n_attrs != NULL, NULL);
2356 
2357 	if (real->array == NULL) {
2358 		*n_attrs = 0;
2359 		return NULL;
2360 	}
2361 
2362 	/* Prepare the attributes to receive their length */
2363 
2364 	for (i = 0; i < real->array->len; ++i) {
2365 		attr = &g_array_index (real->array, GckAttribute, i);
2366 		if (attr->value != NULL) {
2367 			value_unref (attr->value);
2368 			attr->value = NULL;
2369 		}
2370 		attr->length = 0;
2371 	}
2372 
2373 	*n_attrs = real->array->len;
2374 	return (CK_ATTRIBUTE_PTR)real->array->data;
2375 }
2376 
2377 CK_ATTRIBUTE_PTR
_gck_builder_commit_in(GckBuilder * builder,CK_ULONG_PTR n_attrs)2378 _gck_builder_commit_in (GckBuilder *builder,
2379                         CK_ULONG_PTR n_attrs)
2380 {
2381 	GckRealBuilder *real = (GckRealBuilder *)builder;
2382 	GckAttribute *attr;
2383 	guint i;
2384 
2385 	g_return_val_if_fail (builder != NULL, NULL);
2386 	g_return_val_if_fail (n_attrs != NULL, NULL);
2387 
2388 	if (real->array == NULL) {
2389 		*n_attrs = 0;
2390 		return NULL;
2391 	}
2392 
2393 	/* Allocate each attribute with the length that was set */
2394 
2395 	for (i = 0; i < real->array->len; ++i) {
2396 		attr = &g_array_index (real->array, GckAttribute, i);
2397 		if (attr->length != 0 && attr->length != (gulong)-1)
2398 			attr->value = value_blank (attr->length, real->secure);
2399 		else
2400 			attr->value = NULL;
2401 	}
2402 
2403 	*n_attrs = real->array->len;
2404 	return (CK_ATTRIBUTE_PTR)real->array->data;
2405 }
2406 
2407 CK_ATTRIBUTE_PTR
_gck_attributes_commit_out(GckAttributes * attrs,CK_ULONG_PTR n_attrs)2408 _gck_attributes_commit_out (GckAttributes *attrs,
2409                             CK_ULONG_PTR n_attrs)
2410 {
2411 	g_return_val_if_fail (attrs != NULL, NULL);
2412 	g_return_val_if_fail (n_attrs != NULL, NULL);
2413 
2414 	*n_attrs = attrs->count;
2415 	return (CK_ATTRIBUTE_PTR)attrs->data;
2416 }
2417 
2418 static gboolean
_gck_attribute_is_ulong_of_type(GckAttribute * attr,gulong attr_type)2419 _gck_attribute_is_ulong_of_type (GckAttribute *attr,
2420                                  gulong attr_type)
2421 {
2422 	if (attr->type != attr_type)
2423 		return FALSE;
2424 	if (attr->length != sizeof (gulong))
2425 		return FALSE;
2426 	if (!attr->value)
2427 		return FALSE;
2428 	return TRUE;
2429 }
2430 
2431 static gboolean
_gck_attribute_is_sensitive(GckAttribute * attr)2432 _gck_attribute_is_sensitive (GckAttribute *attr)
2433 {
2434 	/*
2435 	 * Don't print any just attribute, since they may contain
2436 	 * sensitive data
2437 	 */
2438 
2439 	switch (attr->type) {
2440 	#define X(x) case x: return FALSE;
2441 	X (CKA_CLASS)
2442 	X (CKA_TOKEN)
2443 	X (CKA_PRIVATE)
2444 	X (CKA_LABEL)
2445 	X (CKA_APPLICATION)
2446 	X (CKA_OBJECT_ID)
2447 	X (CKA_CERTIFICATE_TYPE)
2448 	X (CKA_ISSUER)
2449 	X (CKA_SERIAL_NUMBER)
2450 	X (CKA_AC_ISSUER)
2451 	X (CKA_OWNER)
2452 	X (CKA_ATTR_TYPES)
2453 	X (CKA_TRUSTED)
2454 	X (CKA_CERTIFICATE_CATEGORY)
2455 	X (CKA_JAVA_MIDP_SECURITY_DOMAIN)
2456 	X (CKA_URL)
2457 	X (CKA_HASH_OF_SUBJECT_PUBLIC_KEY)
2458 	X (CKA_HASH_OF_ISSUER_PUBLIC_KEY)
2459 	X (CKA_CHECK_VALUE)
2460 	X (CKA_KEY_TYPE)
2461 	X (CKA_SUBJECT)
2462 	X (CKA_ID)
2463 	X (CKA_SENSITIVE)
2464 	X (CKA_ENCRYPT)
2465 	X (CKA_DECRYPT)
2466 	X (CKA_WRAP)
2467 	X (CKA_UNWRAP)
2468 	X (CKA_SIGN)
2469 	X (CKA_SIGN_RECOVER)
2470 	X (CKA_VERIFY)
2471 	X (CKA_VERIFY_RECOVER)
2472 	X (CKA_DERIVE)
2473 	X (CKA_START_DATE)
2474 	X (CKA_END_DATE)
2475 	X (CKA_MODULUS_BITS)
2476 	X (CKA_PRIME_BITS)
2477 	/* X (CKA_SUBPRIME_BITS) */
2478 	/* X (CKA_SUB_PRIME_BITS) */
2479 	X (CKA_VALUE_BITS)
2480 	X (CKA_VALUE_LEN)
2481 	X (CKA_EXTRACTABLE)
2482 	X (CKA_LOCAL)
2483 	X (CKA_NEVER_EXTRACTABLE)
2484 	X (CKA_ALWAYS_SENSITIVE)
2485 	X (CKA_KEY_GEN_MECHANISM)
2486 	X (CKA_MODIFIABLE)
2487 	X (CKA_SECONDARY_AUTH)
2488 	X (CKA_AUTH_PIN_FLAGS)
2489 	X (CKA_ALWAYS_AUTHENTICATE)
2490 	X (CKA_WRAP_WITH_TRUSTED)
2491 	X (CKA_WRAP_TEMPLATE)
2492 	X (CKA_UNWRAP_TEMPLATE)
2493 	X (CKA_HW_FEATURE_TYPE)
2494 	X (CKA_RESET_ON_INIT)
2495 	X (CKA_HAS_RESET)
2496 	X (CKA_PIXEL_X)
2497 	X (CKA_PIXEL_Y)
2498 	X (CKA_RESOLUTION)
2499 	X (CKA_CHAR_ROWS)
2500 	X (CKA_CHAR_COLUMNS)
2501 	X (CKA_COLOR)
2502 	X (CKA_BITS_PER_PIXEL)
2503 	X (CKA_CHAR_SETS)
2504 	X (CKA_ENCODING_METHODS)
2505 	X (CKA_MIME_TYPES)
2506 	X (CKA_MECHANISM_TYPE)
2507 	X (CKA_REQUIRED_CMS_ATTRIBUTES)
2508 	X (CKA_DEFAULT_CMS_ATTRIBUTES)
2509 	X (CKA_SUPPORTED_CMS_ATTRIBUTES)
2510 	X (CKA_ALLOWED_MECHANISMS)
2511 	X (CKA_X_ASSERTION_TYPE)
2512 	X (CKA_X_CERTIFICATE_VALUE)
2513 	X (CKA_X_PURPOSE)
2514 	X (CKA_X_PEER)
2515 	#undef X
2516 	}
2517 
2518 	return TRUE;
2519 }
2520 
2521 static void
_gck_format_class(GString * output,CK_OBJECT_CLASS klass)2522 _gck_format_class (GString *output,
2523                    CK_OBJECT_CLASS klass)
2524 {
2525 	const gchar *string = NULL;
2526 
2527 	switch (klass) {
2528 	#define X(x) case x: string = #x; break;
2529 	X (CKO_DATA)
2530 	X (CKO_CERTIFICATE)
2531 	X (CKO_PUBLIC_KEY)
2532 	X (CKO_PRIVATE_KEY)
2533 	X (CKO_SECRET_KEY)
2534 	X (CKO_HW_FEATURE)
2535 	X (CKO_DOMAIN_PARAMETERS)
2536 	X (CKO_MECHANISM)
2537 	X (CKO_X_TRUST_ASSERTION)
2538 	}
2539 
2540 	if (string != NULL)
2541 		g_string_append (output, string);
2542 	else
2543 		g_string_append_printf (output, "0x%08lX", klass);
2544 }
2545 
2546 static void
_gck_format_assertion_type(GString * output,CK_X_ASSERTION_TYPE type)2547 _gck_format_assertion_type (GString *output,
2548                             CK_X_ASSERTION_TYPE type)
2549 {
2550 	const gchar *string = NULL;
2551 
2552 	switch (type) {
2553 	#define X(x) case x: string = #x; break;
2554 	X (CKT_X_UNTRUSTED_CERTIFICATE)
2555 	X (CKT_X_PINNED_CERTIFICATE)
2556 	X (CKT_X_ANCHORED_CERTIFICATE)
2557 	#undef X
2558 	}
2559 
2560 	if (string != NULL)
2561 		g_string_append (output, string);
2562 	else
2563 		g_string_append_printf (output, "0x%08lX", type);
2564 }
2565 
2566 static void
_gck_format_key_type(GString * output,CK_KEY_TYPE type)2567 _gck_format_key_type (GString *output,
2568                       CK_KEY_TYPE type)
2569 {
2570 	const gchar *string = NULL;
2571 
2572 	switch (type) {
2573 	#define X(x) case x: string = #x; break;
2574 	X (CKK_RSA)
2575 	X (CKK_DSA)
2576 	X (CKK_DH)
2577 	/* X (CKK_ECDSA) */
2578 	X (CKK_EC)
2579 	X (CKK_X9_42_DH)
2580 	X (CKK_KEA)
2581 	X (CKK_GENERIC_SECRET)
2582 	X (CKK_RC2)
2583 	X (CKK_RC4)
2584 	X (CKK_DES)
2585 	X (CKK_DES2)
2586 	X (CKK_DES3)
2587 	X (CKK_CAST)
2588 	X (CKK_CAST3)
2589 	X (CKK_CAST128)
2590 	X (CKK_RC5)
2591 	X (CKK_IDEA)
2592 	X (CKK_SKIPJACK)
2593 	X (CKK_BATON)
2594 	X (CKK_JUNIPER)
2595 	X (CKK_CDMF)
2596 	X (CKK_AES)
2597 	X (CKK_BLOWFISH)
2598 	X (CKK_TWOFISH)
2599 	#undef X
2600 	}
2601 
2602 	if (string != NULL)
2603 		g_string_append (output, string);
2604 	else
2605 		g_string_append_printf (output, "0x%08lX", type);
2606 }
2607 
2608 static void
_gck_format_certificate_type(GString * output,CK_CERTIFICATE_TYPE type)2609 _gck_format_certificate_type (GString *output,
2610                               CK_CERTIFICATE_TYPE type)
2611 {
2612 	const gchar *string = NULL;
2613 
2614 	switch (type) {
2615 	#define X(x) case x: string = #x; break;
2616 	X (CKC_X_509)
2617 	X (CKC_X_509_ATTR_CERT)
2618 	X (CKC_WTLS)
2619 	}
2620 
2621 	if (string != NULL)
2622 		g_string_append (output, string);
2623 	else
2624 		g_string_append_printf (output, "0x%08lX", type);
2625 }
2626 
2627 static void
_gck_format_attribute_type(GString * output,gulong type)2628 _gck_format_attribute_type (GString *output,
2629                             gulong type)
2630 {
2631 	const gchar *string = NULL;
2632 
2633 	switch (type) {
2634 	#define X(x) case x: string = #x; break;
2635 	X (CKA_CLASS)
2636 	X (CKA_TOKEN)
2637 	X (CKA_PRIVATE)
2638 	X (CKA_LABEL)
2639 	X (CKA_APPLICATION)
2640 	X (CKA_VALUE)
2641 	X (CKA_OBJECT_ID)
2642 	X (CKA_CERTIFICATE_TYPE)
2643 	X (CKA_ISSUER)
2644 	X (CKA_SERIAL_NUMBER)
2645 	X (CKA_AC_ISSUER)
2646 	X (CKA_OWNER)
2647 	X (CKA_ATTR_TYPES)
2648 	X (CKA_TRUSTED)
2649 	X (CKA_CERTIFICATE_CATEGORY)
2650 	X (CKA_JAVA_MIDP_SECURITY_DOMAIN)
2651 	X (CKA_URL)
2652 	X (CKA_HASH_OF_SUBJECT_PUBLIC_KEY)
2653 	X (CKA_HASH_OF_ISSUER_PUBLIC_KEY)
2654 	X (CKA_CHECK_VALUE)
2655 	X (CKA_KEY_TYPE)
2656 	X (CKA_SUBJECT)
2657 	X (CKA_ID)
2658 	X (CKA_SENSITIVE)
2659 	X (CKA_ENCRYPT)
2660 	X (CKA_DECRYPT)
2661 	X (CKA_WRAP)
2662 	X (CKA_UNWRAP)
2663 	X (CKA_SIGN)
2664 	X (CKA_SIGN_RECOVER)
2665 	X (CKA_VERIFY)
2666 	X (CKA_VERIFY_RECOVER)
2667 	X (CKA_DERIVE)
2668 	X (CKA_START_DATE)
2669 	X (CKA_END_DATE)
2670 	X (CKA_MODULUS)
2671 	X (CKA_MODULUS_BITS)
2672 	X (CKA_PUBLIC_EXPONENT)
2673 	X (CKA_PRIVATE_EXPONENT)
2674 	X (CKA_PRIME_1)
2675 	X (CKA_PRIME_2)
2676 	X (CKA_EXPONENT_1)
2677 	X (CKA_EXPONENT_2)
2678 	X (CKA_COEFFICIENT)
2679 	X (CKA_PRIME)
2680 	X (CKA_SUBPRIME)
2681 	X (CKA_BASE)
2682 	X (CKA_PRIME_BITS)
2683 	/* X (CKA_SUBPRIME_BITS) */
2684 	/* X (CKA_SUB_PRIME_BITS) */
2685 	X (CKA_VALUE_BITS)
2686 	X (CKA_VALUE_LEN)
2687 	X (CKA_EXTRACTABLE)
2688 	X (CKA_LOCAL)
2689 	X (CKA_NEVER_EXTRACTABLE)
2690 	X (CKA_ALWAYS_SENSITIVE)
2691 	X (CKA_KEY_GEN_MECHANISM)
2692 	X (CKA_MODIFIABLE)
2693 	X (CKA_ECDSA_PARAMS)
2694 	/* X (CKA_EC_PARAMS) */
2695 	X (CKA_EC_POINT)
2696 	X (CKA_SECONDARY_AUTH)
2697 	X (CKA_AUTH_PIN_FLAGS)
2698 	X (CKA_ALWAYS_AUTHENTICATE)
2699 	X (CKA_WRAP_WITH_TRUSTED)
2700 	X (CKA_WRAP_TEMPLATE)
2701 	X (CKA_UNWRAP_TEMPLATE)
2702 	X (CKA_HW_FEATURE_TYPE)
2703 	X (CKA_RESET_ON_INIT)
2704 	X (CKA_HAS_RESET)
2705 	X (CKA_PIXEL_X)
2706 	X (CKA_PIXEL_Y)
2707 	X (CKA_RESOLUTION)
2708 	X (CKA_CHAR_ROWS)
2709 	X (CKA_CHAR_COLUMNS)
2710 	X (CKA_COLOR)
2711 	X (CKA_BITS_PER_PIXEL)
2712 	X (CKA_CHAR_SETS)
2713 	X (CKA_ENCODING_METHODS)
2714 	X (CKA_MIME_TYPES)
2715 	X (CKA_MECHANISM_TYPE)
2716 	X (CKA_REQUIRED_CMS_ATTRIBUTES)
2717 	X (CKA_DEFAULT_CMS_ATTRIBUTES)
2718 	X (CKA_SUPPORTED_CMS_ATTRIBUTES)
2719 	X (CKA_ALLOWED_MECHANISMS)
2720 	X (CKA_X_ASSERTION_TYPE)
2721 	X (CKA_X_CERTIFICATE_VALUE)
2722 	X (CKA_X_PURPOSE)
2723 	X (CKA_X_PEER)
2724 	#undef X
2725 	}
2726 
2727 	if (string != NULL)
2728 		g_string_append (output, string);
2729 	else
2730 		g_string_append_printf (output, "CKA_0x%08lX", type);
2731 }
2732 
2733 static void
_gck_format_some_bytes(GString * output,gconstpointer bytes,gulong length)2734 _gck_format_some_bytes (GString *output,
2735                         gconstpointer bytes,
2736                         gulong length)
2737 {
2738 	guchar ch;
2739 	const guchar *data = bytes;
2740 	gulong i;
2741 
2742 	if (bytes == NULL) {
2743 		g_string_append (output, "NULL");
2744 		return;
2745 	}
2746 
2747 	g_string_append_c (output, '\"');
2748 	for (i = 0; i < length && i < 128; i++) {
2749 		ch = data[i];
2750 		if (ch == '\t')
2751 			g_string_append (output, "\\t");
2752 		else if (ch == '\n')
2753 			g_string_append (output, "\\n");
2754 		else if (ch == '\r')
2755 			g_string_append (output, "\\r");
2756 		else if (ch >= 32 && ch < 127)
2757 			g_string_append_c (output, ch);
2758 		else
2759 			g_string_append_printf (output, "\\x%02x", ch);
2760 	}
2761 
2762 	if (i < length)
2763 		g_string_append_printf (output, "...");
2764 	g_string_append_c (output, '\"');
2765 }
2766 
2767 static void
_gck_format_attributes(GString * output,GckAttributes * attrs)2768 _gck_format_attributes (GString *output,
2769                         GckAttributes *attrs)
2770 {
2771 	GckAttribute *attr;
2772 	guint count, i;
2773 
2774 	count = attrs->count;
2775 	g_string_append_printf (output, "(%d) [", count);
2776 	for (i = 0; i < count; i++) {
2777 		attr = attrs->data + i;
2778 		if (i > 0)
2779 			g_string_append_c (output, ',');
2780 		g_string_append (output, " { ");
2781 		_gck_format_attribute_type (output, attr->type);
2782 		g_string_append (output, " = ");
2783 		if (attr->length == GCK_INVALID) {
2784 			g_string_append_printf (output, " (-1) INVALID");
2785 		} else if (_gck_attribute_is_ulong_of_type (attr, CKA_CLASS)) {
2786 			_gck_format_class (output, (CK_OBJECT_CLASS) gck_attribute_get_ulong(attr));
2787 		} else if (_gck_attribute_is_ulong_of_type (attr, CKA_X_ASSERTION_TYPE)) {
2788 			_gck_format_assertion_type (output, (CK_X_ASSERTION_TYPE) gck_attribute_get_ulong(attr));
2789 		} else if (_gck_attribute_is_ulong_of_type (attr, CKA_CERTIFICATE_TYPE)) {
2790 			_gck_format_certificate_type (output, (CK_CERTIFICATE_TYPE) gck_attribute_get_ulong(attr));
2791 		} else if (_gck_attribute_is_ulong_of_type (attr, CKA_KEY_TYPE)) {
2792 			_gck_format_key_type (output, (CK_KEY_TYPE) gck_attribute_get_ulong(attr));
2793 		} else if (_gck_attribute_is_sensitive (attr)) {
2794 			g_string_append_printf (output, " (%lu) NOT-PRINTED", attr->length);
2795 		} else {
2796 			g_string_append_printf (output, " (%lu) ", attr->length);
2797 			_gck_format_some_bytes (output, attr->value, attr->length);
2798 		}
2799 		g_string_append (output, " }");
2800 	}
2801 	g_string_append (output, " ]");
2802 }
2803 
2804 /**
2805  * gck_attributes_to_string:
2806  * @attrs: the attributes
2807  *
2808  * Print out attributes to a string in aform that's useful for debugging
2809  * or logging.
2810  *
2811  * The format of the string returned may change in the future.
2812  *
2813  * Returns: a newly allocated string
2814  */
2815 gchar *
gck_attributes_to_string(GckAttributes * attrs)2816 gck_attributes_to_string (GckAttributes *attrs)
2817 {
2818 	GString *output = g_string_sized_new (128);
2819 	_gck_format_attributes (output, attrs);
2820 	return g_string_free (output, FALSE);
2821 }
2822 
2823 /**
2824  * gck_attributes_new:
2825  * @reserved: Should be set to always be GCK_INVALID
2826  *
2827  * Create a new empty GckAttributes array.
2828  *
2829  * The returned set of attributes is floating, and should either be passed to
2830  * another gck library function which consumes this floating reference, or if
2831  * you wish to keep these attributes around you should ref them with
2832  * gck_attributes_ref_sink() and unref them later with gck_attributes_unref().
2833  *
2834  * Returns: (transfer none): a floating reference to the new attributes array;
2835  *          when done with the array release it with gck_attributes_unref().
2836  **/
2837 GckAttributes *
gck_attributes_new(gulong reserved)2838 gck_attributes_new (gulong reserved)
2839 {
2840 	GckBuilder builder = GCK_BUILDER_INIT;
2841 	return gck_builder_end (&builder);
2842 }
2843 
2844 /**
2845  * gck_attributes_new_full: (skip)
2846  * @allocator: memory allocator for attribute data, or %NULL for default
2847  *
2848  * #GckAttributes are now immutable. This method no longer does anything.
2849  *
2850  * Deprecated: 3.4: Use gck_builder_set_all() instead.
2851  *
2852  * Returns: returns %NULL
2853  **/
2854 GckAttributes *
gck_attributes_new_full(GckAllocator allocator)2855 gck_attributes_new_full (GckAllocator allocator)
2856 {
2857 	g_warning ("gck_attributes_new_full() is no no longer supported");
2858 	return NULL;
2859 }
2860 
2861 /**
2862  * gck_attributes_add:
2863  * @attrs: the attributes array to add to
2864  * @attr: the attribute to add
2865  *
2866  * #GckAttributes are now immutable. This method no longer does anything.
2867  *
2868  * Deprecated: 3.4: Use gck_builder_set_all() instead.
2869  *
2870  * Returns: (transfer none): returns %NULL
2871  **/
2872 GckAttribute *
gck_attributes_add(GckAttributes * attrs,GckAttribute * attr)2873 gck_attributes_add (GckAttributes *attrs,
2874                     GckAttribute *attr)
2875 {
2876 	g_warning ("gck_attributes_add() is no no longer supported");
2877 	return NULL;
2878 }
2879 
2880 /**
2881  * gck_attributes_set:
2882  * @attrs: attributes array to add to
2883  * @attr: attribute to set
2884  *
2885  * #GckAttributes are now immutable. This method no longer does anything.
2886  *
2887  * Deprecated: 3.4: Use gck_builder_set_data() instead.
2888  **/
2889 void
gck_attributes_set(GckAttributes * attrs,GckAttribute * attr)2890 gck_attributes_set (GckAttributes *attrs,
2891                     GckAttribute *attr)
2892 {
2893 	g_warning ("gck_attributes_set() is no no longer supported");
2894 }
2895 
2896 /**
2897  * gck_attributes_add_data:
2898  * @attrs: The attributes array to add to.
2899  * @attr_type: The type of attribute to add.
2900  * @value: (array length=length): the raw memory of the attribute value
2901  * @length: The length of the attribute value.
2902  *
2903  * #GckAttributes are now immutable. This method no longer does anything.
2904  *
2905  * Deprecated: 3.4: Use gck_builder_add_data() instead.
2906  *
2907  * Returns: (transfer none): returns %NULL
2908  **/
2909 GckAttribute *
gck_attributes_add_data(GckAttributes * attrs,gulong attr_type,const guchar * value,gsize length)2910 gck_attributes_add_data (GckAttributes *attrs,
2911                          gulong attr_type,
2912                          const guchar *value,
2913                          gsize length)
2914 {
2915 	g_warning ("gck_attributes_add_data() is no no longer supported");
2916 	return NULL;
2917 }
2918 
2919 /**
2920  * gck_attributes_add_invalid:
2921  * @attrs: The attributes array to add to.
2922  * @attr_type: The type of attribute to add.
2923  *
2924  * #GckAttributes are now immutable. This method no longer does anything.
2925  *
2926  * Deprecated: 3.4: Use gck_builder_add_invalid() instead
2927  *
2928  * Returns: (transfer none): returns %NULL
2929  **/
2930 GckAttribute *
gck_attributes_add_invalid(GckAttributes * attrs,gulong attr_type)2931 gck_attributes_add_invalid (GckAttributes *attrs,
2932                             gulong attr_type)
2933 {
2934 	g_warning ("gck_attributes_add_invalid() is no no longer supported");
2935 	return NULL;
2936 }
2937 
2938 /**
2939  * gck_attributes_add_empty:
2940  * @attrs: The attributes array to add.
2941  * @attr_type: The type of attribute to add.
2942  *
2943  * #GckAttributes are now immutable. This method no longer does anything.
2944  *
2945  * Deprecated: 3.4: Use gck_builder_add_empty() instead.
2946  *
2947  * Returns: (transfer none): returns %NULL
2948  **/
2949 GckAttribute *
gck_attributes_add_empty(GckAttributes * attrs,gulong attr_type)2950 gck_attributes_add_empty (GckAttributes *attrs,
2951                           gulong attr_type)
2952 {
2953 	g_warning ("gck_attributes_add_empty() is no no longer supported");
2954 	return NULL;
2955 }
2956 
2957 /**
2958  * gck_attributes_add_boolean:
2959  * @attrs: the attributes array to add to
2960  * @attr_type: the type of attribute to add
2961  * @value: the boolean value to add
2962  *
2963  * #GckAttributes are now immutable. This method no longer does anything.
2964  *
2965  * Deprecated: 3.4: Use gck_builder_add_boolean() instead.
2966  *
2967  * Returns: (transfer none): returns %NULL
2968  **/
2969 GckAttribute *
gck_attributes_add_boolean(GckAttributes * attrs,gulong attr_type,gboolean value)2970 gck_attributes_add_boolean (GckAttributes *attrs,
2971                             gulong attr_type,
2972                             gboolean value)
2973 {
2974 	g_warning ("gck_attributes_add_boolean() is no no longer supported");
2975 	return NULL;
2976 }
2977 
2978 /**
2979  * gck_attributes_set_boolean:
2980  * @attrs: the attributes
2981  * @attr_type: the type of attribute to set
2982  * @value: boolean value to set
2983  *
2984  * #GckAttributes are now immutable. This method no longer does anything.
2985  *
2986  * Deprecated: 3.4: Use gck_builder_set_boolean() instead.
2987  */
2988 void
gck_attributes_set_boolean(GckAttributes * attrs,gulong attr_type,gboolean value)2989 gck_attributes_set_boolean (GckAttributes *attrs,
2990                             gulong attr_type,
2991                             gboolean value)
2992 {
2993 	g_warning ("gck_attributes_set_boolean() is no no longer supported");
2994 
2995 }
2996 
2997 /**
2998  * gck_attributes_add_string:
2999  * @attrs: the attributes array to add to
3000  * @attr_type: the type of attribute to add
3001  * @value: the null terminated string value to add
3002  *
3003  * #GckAttributes are now immutable. This method no longer does anything.
3004  *
3005  * Deprecated: 3.4: Use gck_builder_add_string() instead.
3006  *
3007  * Returns: (transfer none): returns %NULL
3008  **/
3009 GckAttribute *
gck_attributes_add_string(GckAttributes * attrs,gulong attr_type,const gchar * value)3010 gck_attributes_add_string (GckAttributes *attrs,
3011                            gulong attr_type,
3012                            const gchar *value)
3013 {
3014 	g_warning ("gck_attributes_add_string() is no no longer supported");
3015 	return NULL;
3016 }
3017 
3018 /**
3019  * gck_attributes_set_string:
3020  * @attrs: the attributes
3021  * @attr_type: the type of attribute to set
3022  * @value: null terminated string value to set
3023  *
3024  * #GckAttributes are now immutable. This method no longer does anything.
3025  *
3026  * Deprecated: 3.4: Use gck_builder_set_string() instead.
3027  */
3028 void
gck_attributes_set_string(GckAttributes * attrs,gulong attr_type,const gchar * value)3029 gck_attributes_set_string (GckAttributes *attrs,
3030                            gulong attr_type,
3031                            const gchar *value)
3032 {
3033 	g_warning ("gck_attributes_set_string() is no no longer supported");
3034 }
3035 
3036 /**
3037  * gck_attributes_add_date:
3038  * @attrs: the attributes array to add to
3039  * @attr_type: the type of attribute to add
3040  * @value: the GDate value to add
3041  *
3042  * #GckAttributes are now immutable. This method no longer does anything.
3043  *
3044  * Deprecated: 3.4: Use gck_builder_add_date() instead.
3045  *
3046  * Returns: (transfer none): returns %NULL
3047  **/
3048 GckAttribute *
gck_attributes_add_date(GckAttributes * attrs,gulong attr_type,const GDate * value)3049 gck_attributes_add_date (GckAttributes *attrs,
3050                          gulong attr_type,
3051                          const GDate *value)
3052 {
3053 	g_warning ("gck_attributes_add_date() is no no longer supported");
3054 	return NULL;
3055 }
3056 
3057 /**
3058  * gck_attributes_set_date:
3059  * @attrs: the attributes
3060  * @attr_type: the type of attribute to set
3061  * @value: date value to set
3062  *
3063  * #GckAttributes are now immutable. This method no longer does anything.
3064  *
3065  * Deprecated: 3.4: Use gck_builder_set_date() instead.
3066  */
3067 void
gck_attributes_set_date(GckAttributes * attrs,gulong attr_type,const GDate * value)3068 gck_attributes_set_date (GckAttributes *attrs,
3069                          gulong attr_type,
3070                          const GDate *value)
3071 {
3072 	g_warning ("gck_attributes_set_date() is no no longer supported");
3073 }
3074 
3075 /**
3076  * gck_attributes_add_ulong:
3077  * @attrs: the attributes array to add to
3078  * @attr_type: the type of attribute to add
3079  * @value: the gulong value to add
3080  *
3081  * #GckAttributes are now immutable. This method no longer does anything.
3082  *
3083  * Deprecated: 3.4: Use gck_builder_add_ulong() instead.
3084  *
3085  * Returns: (transfer none): returns %NULL
3086  **/
3087 GckAttribute *
gck_attributes_add_ulong(GckAttributes * attrs,gulong attr_type,gulong value)3088 gck_attributes_add_ulong (GckAttributes *attrs,
3089                           gulong attr_type,
3090                           gulong value)
3091 {
3092 	g_warning ("gck_attributes_add_ulong() is no no longer supported");
3093 	return NULL;
3094 }
3095 
3096 /**
3097  * gck_attributes_set_ulong:
3098  * @attrs: the attributes
3099  * @attr_type: the type of attribute to set
3100  * @value: gulong value to set
3101  *
3102  * #GckAttributes are now immutable. This method no longer does anything.
3103  *
3104  * Deprecated: 3.4: Use gck_builder_set_ulong() instead.
3105  */
3106 void
gck_attributes_set_ulong(GckAttributes * attrs,gulong attr_type,gulong value)3107 gck_attributes_set_ulong (GckAttributes *attrs,
3108                           gulong attr_type,
3109                           gulong value)
3110 {
3111 	g_warning ("gck_attributes_set_ulong() is no no longer supported");
3112 }
3113 
3114 /**
3115  * gck_attributes_add_all:
3116  * @attrs: a set of attributes
3117  * @from: attributes to add
3118  *
3119  * #GckAttributes are now immutable. This method no longer does anything.
3120  *
3121  * Deprecated: 3.4: Use gck_builder_add_all() instead.
3122  */
3123 void
gck_attributes_add_all(GckAttributes * attrs,GckAttributes * from)3124 gck_attributes_add_all (GckAttributes *attrs,
3125                         GckAttributes *from)
3126 {
3127 	g_warning ("gck_attributes_add_all() is no no longer supported");
3128 }
3129 
3130 /**
3131  * gck_attributes_set_all:
3132  * @attrs: set of attributes
3133  * @from: attributes to add
3134  *
3135  * #GckAttributes are now immutable. This method no longer does anything.
3136  *
3137  * Deprecated: 3.4: Use gck_builder_set_all() instead.
3138  */
3139 void
gck_attributes_set_all(GckAttributes * attrs,GckAttributes * from)3140 gck_attributes_set_all (GckAttributes *attrs,
3141                         GckAttributes *from)
3142 {
3143 	g_warning ("gck_attributes_set_all() is no no longer supported");
3144 }
3145 
3146 /**
3147  * gck_attributes_dup:
3148  * @attrs: set of attributes to copy
3149  *
3150  * #GckAttributes are now immutable, and can be used in mulitple places.
3151  *
3152  * Deprecated: 3.4: Use gck_attributes_ref() or gck_builder_add_all() instead.
3153  *
3154  * Returns: (transfer none): a new floating #GckAttributes
3155  */
3156 GckAttributes *
gck_attributes_dup(GckAttributes * attrs)3157 gck_attributes_dup (GckAttributes *attrs)
3158 {
3159 	GckBuilder builder = GCK_BUILDER_INIT;
3160 
3161 	if (attrs == NULL)
3162 		return NULL;
3163 
3164 	gck_builder_add_all (&builder, attrs);
3165 	return gck_builder_end (&builder);
3166 }
3167