4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 * Copyright 2012 Milan Jurik. All rights reserved.
30 #include "metaGlobal.h"
31 #include "metaAttrMasters.h"
34 find_attribute(CK_ATTRIBUTE_TYPE attrtype
, generic_attr_t
*attributes
,
35 size_t num_attributes
, generic_attr_t
**found_attribute
);
38 * get_master_attributes_by_object
40 * Returns an (statically allocated) set of object attributes, as determined by
41 * class and keytype of the supplied object. The attributes are only
42 * initialized to default values.
45 get_master_attributes_by_object(slot_session_t
*session
,
46 slot_object_t
*slot_object
, generic_attr_t
**attributes
,
47 size_t *num_attributes
)
51 CK_OBJECT_CLASS
class;
52 CK_ULONG subtype
= CK_UNAVAILABLE_INFORMATION
;
54 /* first get the class */
55 attr
.type
= CKA_CLASS
;
57 attr
.ulValueLen
= sizeof (class);
58 rv
= FUNCLIST(session
->fw_st_id
)->C_GetAttributeValue(
59 session
->hSession
, slot_object
->hObject
, &attr
, 1);
64 attr
.pValue
= &subtype
;
65 attr
.ulValueLen
= sizeof (subtype
);
68 attr
.type
= CKA_CERTIFICATE_TYPE
;
71 attr
.type
= CKA_HW_FEATURE_TYPE
;
76 case CKO_DOMAIN_PARAMETERS
:
77 attr
.type
= CKA_KEY_TYPE
;
82 /* should never be here */
83 return (CKR_ATTRIBUTE_VALUE_INVALID
);
85 rv
= FUNCLIST(session
->fw_st_id
)->C_GetAttributeValue(
86 session
->hSession
, slot_object
->hObject
, &attr
, 1);
92 rv
= get_master_attributes_by_type(class, subtype
,
93 attributes
, num_attributes
);
99 * get_master_attributes_by_template
101 * Returns an (statically allocated) set of object attributes, as determined by
102 * the supplied object template. The template is only used to determine the
103 * class/subclass of the object. The attributes are only initialized to
107 get_master_attributes_by_template(
108 CK_ATTRIBUTE
*template, CK_ULONG template_size
,
109 generic_attr_t
**attributes
, size_t *num_attributes
)
111 CK_OBJECT_CLASS
class;
112 CK_ULONG subtype
= CK_UNAVAILABLE_INFORMATION
;
115 found
= get_template_ulong(CKA_CLASS
, template, template_size
, &class);
117 return (CKR_TEMPLATE_INCOMPLETE
);
121 case CKO_CERTIFICATE
:
122 found
= get_template_ulong(CKA_CERTIFICATE_TYPE
,
123 template, template_size
, &subtype
);
126 found
= get_template_ulong(CKA_HW_FEATURE_TYPE
,
127 template, template_size
, &subtype
);
130 case CKO_PRIVATE_KEY
:
132 case CKO_DOMAIN_PARAMETERS
:
133 found
= get_template_ulong(CKA_KEY_TYPE
,
134 template, template_size
, &subtype
);
137 /* CKO_DATA has no subtype, just pretend it is found */
140 /* unknown object class */
141 return (CKR_ATTRIBUTE_VALUE_INVALID
);
145 return (CKR_TEMPLATE_INCOMPLETE
);
148 return (get_master_attributes_by_type(class, subtype
,
149 attributes
, num_attributes
));
153 * get_master_template_by_type
155 * Returns an (statically allocated) set of object attributes, as determined
156 * by the specified class and subtype. The attributes are initialized to default
160 get_master_template_by_type(CK_OBJECT_CLASS
class, CK_ULONG subtype
,
161 generic_attr_t
**attributes
, size_t *num_attributes
)
163 generic_attr_t
*master_template
= NULL
;
164 size_t master_template_size
= 0;
170 master_template
= (generic_attr_t
*)OBJ_HW_CLOCK
;
171 master_template_size
= sizeof (OBJ_HW_CLOCK
);
174 case CKH_MONOTONIC_COUNTER
:
175 master_template
= (generic_attr_t
*)OBJ_HW_MONOTONIC
;
176 master_template_size
= sizeof (OBJ_HW_MONOTONIC
);
186 /* Objects of this class have no subtype. */
187 master_template
= (generic_attr_t
*)OBJ_DATA
;
188 master_template_size
= sizeof (OBJ_DATA
);
191 case CKO_CERTIFICATE
:
194 master_template
= (generic_attr_t
*)OBJ_CERT_X509
;
195 master_template_size
= sizeof (OBJ_CERT_X509
);
198 case CKC_X_509_ATTR_CERT
:
199 master_template
= (generic_attr_t
*)OBJ_CERT_X509ATTR
;
200 master_template_size
= sizeof (OBJ_CERT_X509ATTR
);
212 master_template
= (generic_attr_t
*)OBJ_PUBKEY_RSA
;
213 master_template_size
= sizeof (OBJ_PUBKEY_RSA
);
217 master_template
= (generic_attr_t
*)OBJ_PUBKEY_DSA
;
218 master_template_size
= sizeof (OBJ_PUBKEY_DSA
);
222 master_template
= (generic_attr_t
*)OBJ_PUBKEY_EC
;
223 master_template_size
= sizeof (OBJ_PUBKEY_EC
);
227 master_template
= (generic_attr_t
*)OBJ_PUBKEY_DH
;
228 master_template_size
= sizeof (OBJ_PUBKEY_DH
);
232 master_template
= (generic_attr_t
*)OBJ_PUBKEY_X942DH
;
233 master_template_size
= sizeof (OBJ_PUBKEY_X942DH
);
237 master_template
= (generic_attr_t
*)OBJ_PUBKEY_KEA
;
238 master_template_size
= sizeof (OBJ_PUBKEY_KEA
);
247 case CKO_PRIVATE_KEY
:
250 master_template
= (generic_attr_t
*)OBJ_PRIVKEY_RSA
;
251 master_template_size
= sizeof (OBJ_PRIVKEY_RSA
);
255 master_template
= (generic_attr_t
*)OBJ_PRIVKEY_DSA
;
256 master_template_size
= sizeof (OBJ_PRIVKEY_DSA
);
260 master_template
= (generic_attr_t
*)OBJ_PRIVKEY_EC
;
261 master_template_size
= sizeof (OBJ_PRIVKEY_EC
);
265 master_template
= (generic_attr_t
*)OBJ_PRIVKEY_DH
;
266 master_template_size
= sizeof (OBJ_PRIVKEY_DH
);
270 master_template
= (generic_attr_t
*)OBJ_PRIVKEY_X942DH
;
271 master_template_size
= sizeof (OBJ_PRIVKEY_X942DH
);
275 master_template
= (generic_attr_t
*)OBJ_PRIVKEY_KEA
;
276 master_template_size
= sizeof (OBJ_PRIVKEY_KEA
);
287 * The only difference between secret keys is that some
288 * are valiable length (eg CKK_AES), while others are not
289 * (eg CKK_DES) -- and do not have a CKA_VALUE_LEN attribute.
291 * FUTURE(?): Consider using obj_seckey_withlen for unknown
292 * keytypes. This is the most likely choice, as new algorithms
293 * seem to support variable length keys. That's not the default
294 * now, because if people have implemented new key types with
295 * different attribute sets (like the mess of public/private
296 * key types), then incorrect behaviour would result. It's
297 * easier to relax this restriction than to tighten it (which
298 * would introduce a regression to anyone relying on this
299 * working for unknown key types).
311 master_template
= (generic_attr_t
*)OBJ_SECKEY
;
312 master_template_size
= sizeof (OBJ_SECKEY
);
315 case CKK_GENERIC_SECRET
:
324 master_template
= (generic_attr_t
*)OBJ_SECKEY_WITHLEN
;
325 master_template_size
= sizeof (OBJ_SECKEY_WITHLEN
);
334 case CKO_DOMAIN_PARAMETERS
:
337 master_template
= (generic_attr_t
*)OBJ_DOM_DSA
;
338 master_template_size
= sizeof (OBJ_DOM_DSA
);
342 master_template
= (generic_attr_t
*)OBJ_DOM_DH
;
343 master_template_size
= sizeof (OBJ_DOM_DH
);
347 master_template
= (generic_attr_t
*)OBJ_DOM_X942DH
;
348 master_template_size
= sizeof (OBJ_DOM_X942DH
);
362 /* Requested object is unknown or invalid. */
363 if (master_template
== NULL
)
364 return (CKR_ATTRIBUTE_VALUE_INVALID
);
366 *attributes
= master_template
;
367 *num_attributes
= master_template_size
;
374 * get_master_attributes_by_type
376 * Returns an (statically allocated) set of object attributes, as determined by
377 * the specified class and subtype. The attributes are initialized to default
381 get_master_attributes_by_type(CK_OBJECT_CLASS
class, CK_ULONG subtype
,
382 generic_attr_t
**attributes
, size_t *num_attributes
)
385 generic_attr_t
*master_template
= NULL
;
386 generic_attr_t
*new_attributes
;
387 size_t i
, num_new_attributes
, master_template_size
= 0;
389 /* Determine the appropriate master template needed. */
390 rv
= get_master_template_by_type(class, subtype
,
391 &master_template
, &master_template_size
);
395 /* Duplicate the master template. */
396 new_attributes
= malloc(master_template_size
);
397 if (new_attributes
== NULL
)
398 return (CKR_HOST_MEMORY
);
400 (void) memcpy(new_attributes
, master_template
, master_template_size
);
401 num_new_attributes
= master_template_size
/ sizeof (generic_attr_t
);
403 /* Set the pointer in the appropriate storage area. */
404 for (i
= 0; i
< num_new_attributes
; i
++) {
405 generic_attr_t
*attr
;
407 attr
= new_attributes
+ i
;
409 switch (attr
->attribute
.ulValueLen
) {
410 case (sizeof (CK_ULONG
)):
411 attr
->attribute
.pValue
= &attr
->generic_ulong
;
413 case (sizeof (CK_BBOOL
)):
414 attr
->attribute
.pValue
= &attr
->generic_bbool
;
417 attr
->attribute
.pValue
= attr
->generic_data
;
423 /* Secret keys share a common template, so set the key type here. */
424 if (class == CKO_SECRET_KEY
) {
425 /* Keytype / subtype is always the second attribute. */
426 new_attributes
[1].generic_ulong
= subtype
;
429 *attributes
= new_attributes
;
430 *num_attributes
= num_new_attributes
;
437 * get_master_attributes_by_duplication
439 * Returns an (statically allocated) set of object attributes, as copied from an
440 * existing set of attributes. The new attributes inherit the values from
441 * the old attributes.
444 get_master_attributes_by_duplication(
445 generic_attr_t
*src_attrs
, size_t num_src_attrs
,
446 generic_attr_t
**dst_attrs
, size_t *num_dst_attrs
)
449 generic_attr_t
*new_attrs
, *src
, *dst
;
452 new_attrs
= malloc(sizeof (generic_attr_t
) * num_src_attrs
);
453 if (new_attrs
== NULL
)
454 return (CKR_HOST_MEMORY
);
456 for (i
= 0; i
< num_src_attrs
; i
++) {
462 /* Adjust pointers in dst so that they don't point to src. */
464 if (src
->isMalloced
) {
465 dst
->attribute
.pValue
=
466 malloc(src
->attribute
.ulValueLen
);
468 if (dst
->attribute
.pValue
== NULL
) {
470 * Continue on error, so that the cleanup
471 * routine doesn't see pointers to src_attrs.
473 dst
->attribute
.ulValueLen
= 0;
474 rv
= CKR_HOST_MEMORY
;
477 } else if (src
->attribute
.pValue
== &src
->generic_bbool
) {
478 dst
->attribute
.pValue
= &dst
->generic_bbool
;
479 } else if (src
->attribute
.pValue
== &src
->generic_ulong
) {
480 dst
->attribute
.pValue
= &dst
->generic_ulong
;
481 } else if (src
->attribute
.pValue
== &src
->generic_data
) {
482 dst
->attribute
.pValue
= &dst
->generic_data
;
484 /* This shouldn't happen. */
485 dst
->attribute
.pValue
= NULL
;
486 dst
->attribute
.ulValueLen
= 0;
487 rv
= CKR_GENERAL_ERROR
;
488 num_src_attrs
= i
+ 1;
492 (void) memcpy(dst
->attribute
.pValue
, src
->attribute
.pValue
,
493 src
->attribute
.ulValueLen
);
497 dealloc_attributes(new_attrs
, num_src_attrs
);
499 *dst_attrs
= new_attrs
;
500 *num_dst_attrs
= num_src_attrs
;
510 * Deallocates the storage used for a set of attributes. The attribute
511 * values are zeroed out before being free'd.
514 dealloc_attributes(generic_attr_t
*attributes
, size_t num_attributes
)
517 generic_attr_t
*attr
;
519 for (i
= 0; i
< num_attributes
; i
++) {
520 attr
= attributes
+ i
;
523 * Zero-out any attribute values. We could do this just for
524 * attributes with isSensitive == True, but it's not much
525 * extra work to just do them all. [Most attributes are just
528 bzero(attr
->attribute
.pValue
, attr
->attribute
.ulValueLen
);
530 if (attr
->isMalloced
)
531 free(attr
->attribute
.pValue
);
539 * attribute_set_value
541 * Sets the value of the specified attribute. Any portion of the old value
542 * which will not be overwritten by the new value is zeroed out.
545 attribute_set_value(CK_ATTRIBUTE
*new_attr
,
546 generic_attr_t
*attributes
, size_t num_attributes
)
548 generic_attr_t
*attr
= NULL
;
550 if (new_attr
== NULL
)
551 return (CKR_TEMPLATE_INCOMPLETE
);
552 else if (new_attr
->pValue
== NULL
) {
553 return (CKR_ATTRIBUTE_VALUE_INVALID
);
556 find_attribute(new_attr
->type
, attributes
, num_attributes
, &attr
);
558 return (CKR_ATTRIBUTE_TYPE_INVALID
);
561 /* Store the new value. */
562 if (attr
->attribute
.ulValueLen
>= new_attr
->ulValueLen
) {
563 /* Existing storage is sufficient to store new value. */
565 /* bzero() out any data that won't be overwritten. */
566 bzero((char *)attr
->attribute
.pValue
+ new_attr
->ulValueLen
,
567 attr
->attribute
.ulValueLen
- new_attr
->ulValueLen
);
569 } else if (new_attr
->ulValueLen
<= sizeof (attr
->generic_data
)) {
570 /* Use generic storage to avoid a malloc. */
572 bzero(attr
->attribute
.pValue
, attr
->attribute
.ulValueLen
);
573 if (attr
->isMalloced
) {
575 * If app sets a large value (triggering a malloc),
576 * then sets a tiny value, and finally again sets
577 * a large value (phew!) we could end up here.
579 * FUTURE?: Store the original malloc size, so that
580 * we can regrow the value up to the original size.
581 * This might avoid some heap churn for pathalogic
584 free(attr
->attribute
.pValue
);
585 attr
->isMalloced
= B_FALSE
;
588 attr
->attribute
.pValue
= attr
->generic_data
;
591 /* Need to allocate storage for the new value. */
594 newStorage
= malloc(new_attr
->ulValueLen
);
595 if (newStorage
== NULL
)
596 return (CKR_HOST_MEMORY
);
597 bzero(attr
->attribute
.pValue
, attr
->attribute
.ulValueLen
);
598 attr
->attribute
.pValue
= newStorage
;
599 attr
->isMalloced
= B_TRUE
;
602 (void) memcpy(attr
->attribute
.pValue
, new_attr
->pValue
,
603 new_attr
->ulValueLen
);
604 attr
->attribute
.ulValueLen
= new_attr
->ulValueLen
;
605 attr
->hasValueForClone
= B_TRUE
;
614 * Passes a pointer to the requested attribute, or NULL if not found.
617 find_attribute(CK_ATTRIBUTE_TYPE attrtype
, generic_attr_t
*attributes
,
618 size_t num_attributes
, generic_attr_t
**found_attribute
)
620 generic_attr_t
*attr
;
621 boolean_t found
= B_FALSE
;
624 /* Find the requested attribute. */
625 for (i
= 0, attr
= attributes
; i
< num_attributes
; i
++, attr
++) {
626 if (attr
->attribute
.type
== attrtype
) {
632 *found_attribute
= found
? attr
: NULL
;
639 * Look for the specified ulong-size attribute, and retrieve its value. The
640 * return value specifies if the attribute was found (or not).
643 get_template_ulong(CK_ATTRIBUTE_TYPE type
, CK_ATTRIBUTE
*attributes
,
644 CK_ULONG num_attributes
, CK_ULONG
*result
)
646 boolean_t found
= B_FALSE
;
649 for (i
= 0; i
< num_attributes
; i
++) {
650 if (attributes
[i
].type
== type
) {
651 CK_ULONG
*value
= attributes
[i
].pValue
;
664 * get_template_boolean
666 * Look for the specified boolean attribute, and retrieve its value. The
667 * return value specifies if the attribute was found (or not).
670 get_template_boolean(CK_ATTRIBUTE_TYPE type
, CK_ATTRIBUTE
*attributes
,
671 CK_ULONG num_attributes
, boolean_t
*result
)
673 boolean_t found
= B_FALSE
;
676 for (i
= 0; i
< num_attributes
; i
++) {
677 if (attributes
[i
].type
== type
) {
678 CK_BBOOL
*value
= attributes
[i
].pValue
;
680 if (*value
== CK_FALSE
)
694 * set_template_boolean
696 * Look for the specified boolean attribute, and set its value.
698 * if 'local' is true, it sets the pointer to the value in the template a new
699 * location. There should be no memory leak created by this because we are
700 * only doing this to booleans which should not be malloc'ed.
702 * if 'local' is false, it sets its value.
704 * The return value specifies if the attribute was found (or not).
707 set_template_boolean(CK_ATTRIBUTE_TYPE type
, CK_ATTRIBUTE
*attributes
,
708 CK_ULONG num_attributes
, boolean_t local
, CK_BBOOL
*value
)
712 for (i
= 0; i
< num_attributes
; i
++) {
713 if (attributes
[i
].type
== type
) {
715 attributes
[i
].pValue
= value
;
717 *((CK_BBOOL
*)attributes
[i
].pValue
) = *value
;