Print this page
9642 PKCS#11 softtoken should use explicit_bzero
Reviewed by: Dan McDonald <danmcd@joyent.com>
Reviewed by: Alex Wilson <alex.wilson@joyent.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/pkcs11/libpkcs11/common/metaAttrManager.c
+++ new/usr/src/lib/pkcs11/libpkcs11/common/metaAttrManager.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 * Copyright 2012 Milan Jurik. All rights reserved.
25 + * Copyright (c) 2018, Joyent, Inc.
25 26 */
26 27
27 28 #include <string.h>
28 29 #include <stdlib.h>
29 30 #include <strings.h>
30 31 #include "metaGlobal.h"
31 32 #include "metaAttrMasters.h"
32 33
33 34 static void
34 35 find_attribute(CK_ATTRIBUTE_TYPE attrtype, generic_attr_t *attributes,
35 36 size_t num_attributes, generic_attr_t **found_attribute);
36 37
37 38 /*
38 39 * get_master_attributes_by_object
39 40 *
40 41 * Returns an (statically allocated) set of object attributes, as determined by
41 42 * class and keytype of the supplied object. The attributes are only
42 43 * initialized to default values.
43 44 */
44 45 CK_RV
45 46 get_master_attributes_by_object(slot_session_t *session,
46 47 slot_object_t *slot_object, generic_attr_t **attributes,
47 48 size_t *num_attributes)
48 49 {
49 50 CK_RV rv;
50 51 CK_ATTRIBUTE attr;
51 52 CK_OBJECT_CLASS class;
52 53 CK_ULONG subtype = CK_UNAVAILABLE_INFORMATION;
53 54
54 55 /* first get the class */
55 56 attr.type = CKA_CLASS;
56 57 attr.pValue = &class;
57 58 attr.ulValueLen = sizeof (class);
58 59 rv = FUNCLIST(session->fw_st_id)->C_GetAttributeValue(
59 60 session->hSession, slot_object->hObject, &attr, 1);
60 61 if (rv != CKR_OK) {
61 62 return (rv);
62 63 }
63 64
64 65 attr.pValue = &subtype;
65 66 attr.ulValueLen = sizeof (subtype);
66 67 switch (class) {
67 68 case CKO_CERTIFICATE:
68 69 attr.type = CKA_CERTIFICATE_TYPE;
69 70 break;
70 71 case CKO_HW_FEATURE:
71 72 attr.type = CKA_HW_FEATURE_TYPE;
72 73 break;
73 74 case CKO_PUBLIC_KEY:
74 75 case CKO_PRIVATE_KEY:
75 76 case CKO_SECRET_KEY:
76 77 case CKO_DOMAIN_PARAMETERS:
77 78 attr.type = CKA_KEY_TYPE;
78 79 break;
79 80 case CKO_DATA:
80 81 goto get_attr;
81 82 default:
82 83 /* should never be here */
83 84 return (CKR_ATTRIBUTE_VALUE_INVALID);
84 85 }
85 86 rv = FUNCLIST(session->fw_st_id)->C_GetAttributeValue(
86 87 session->hSession, slot_object->hObject, &attr, 1);
87 88 if (rv != CKR_OK) {
88 89 return (rv);
89 90 }
90 91
91 92 get_attr:
92 93 rv = get_master_attributes_by_type(class, subtype,
93 94 attributes, num_attributes);
94 95
95 96 return (rv);
96 97 }
97 98
98 99 /*
99 100 * get_master_attributes_by_template
100 101 *
101 102 * Returns an (statically allocated) set of object attributes, as determined by
102 103 * the supplied object template. The template is only used to determine the
103 104 * class/subclass of the object. The attributes are only initialized to
104 105 * default values.
105 106 */
106 107 CK_RV
107 108 get_master_attributes_by_template(
108 109 CK_ATTRIBUTE *template, CK_ULONG template_size,
109 110 generic_attr_t **attributes, size_t *num_attributes)
110 111 {
111 112 CK_OBJECT_CLASS class;
112 113 CK_ULONG subtype = CK_UNAVAILABLE_INFORMATION;
113 114 boolean_t found;
114 115
115 116 found = get_template_ulong(CKA_CLASS, template, template_size, &class);
116 117 if (!found) {
117 118 return (CKR_TEMPLATE_INCOMPLETE);
118 119 }
119 120
120 121 switch (class) {
121 122 case CKO_CERTIFICATE:
122 123 found = get_template_ulong(CKA_CERTIFICATE_TYPE,
123 124 template, template_size, &subtype);
124 125 break;
125 126 case CKO_HW_FEATURE:
126 127 found = get_template_ulong(CKA_HW_FEATURE_TYPE,
127 128 template, template_size, &subtype);
128 129 break;
129 130 case CKO_PUBLIC_KEY:
130 131 case CKO_PRIVATE_KEY:
131 132 case CKO_SECRET_KEY:
132 133 case CKO_DOMAIN_PARAMETERS:
133 134 found = get_template_ulong(CKA_KEY_TYPE,
134 135 template, template_size, &subtype);
135 136 break;
136 137 case CKO_DATA:
137 138 /* CKO_DATA has no subtype, just pretend it is found */
138 139 found = B_TRUE;
139 140 break;
140 141 default:
141 142 /* unknown object class */
142 143 return (CKR_ATTRIBUTE_VALUE_INVALID);
143 144 }
144 145
145 146 if (!found) {
146 147 return (CKR_TEMPLATE_INCOMPLETE);
147 148 }
148 149
149 150 return (get_master_attributes_by_type(class, subtype,
150 151 attributes, num_attributes));
151 152 }
152 153
153 154 /*
154 155 * get_master_template_by_type
155 156 *
156 157 * Returns an (statically allocated) set of object attributes, as determined
157 158 * by the specified class and subtype. The attributes are initialized to default
158 159 * values.
159 160 */
160 161 CK_RV
161 162 get_master_template_by_type(CK_OBJECT_CLASS class, CK_ULONG subtype,
162 163 generic_attr_t **attributes, size_t *num_attributes)
163 164 {
164 165 generic_attr_t *master_template = NULL;
165 166 size_t master_template_size = 0;
166 167
167 168 switch (class) {
168 169 case CKO_HW_FEATURE:
169 170 switch (subtype) {
170 171 case CKO_HW_FEATURE:
171 172 master_template = (generic_attr_t *)OBJ_HW_CLOCK;
172 173 master_template_size = sizeof (OBJ_HW_CLOCK);
173 174 break;
174 175
175 176 case CKH_MONOTONIC_COUNTER:
176 177 master_template = (generic_attr_t *)OBJ_HW_MONOTONIC;
177 178 master_template_size = sizeof (OBJ_HW_MONOTONIC);
178 179 break;
179 180
180 181 default:
181 182 /* Unsupported. */
182 183 break;
183 184 }
184 185 break;
185 186
186 187 case CKO_DATA:
187 188 /* Objects of this class have no subtype. */
188 189 master_template = (generic_attr_t *)OBJ_DATA;
189 190 master_template_size = sizeof (OBJ_DATA);
190 191 break;
191 192
192 193 case CKO_CERTIFICATE:
193 194 switch (subtype) {
194 195 case CKC_X_509:
195 196 master_template = (generic_attr_t *)OBJ_CERT_X509;
196 197 master_template_size = sizeof (OBJ_CERT_X509);
197 198 break;
198 199
199 200 case CKC_X_509_ATTR_CERT:
200 201 master_template = (generic_attr_t *)OBJ_CERT_X509ATTR;
201 202 master_template_size = sizeof (OBJ_CERT_X509ATTR);
202 203 break;
203 204
204 205 default:
205 206 /* Unsupported. */
206 207 break;
207 208 }
208 209 break;
209 210
210 211 case CKO_PUBLIC_KEY:
211 212 switch (subtype) {
212 213 case CKK_RSA:
213 214 master_template = (generic_attr_t *)OBJ_PUBKEY_RSA;
214 215 master_template_size = sizeof (OBJ_PUBKEY_RSA);
215 216 break;
216 217
217 218 case CKK_DSA:
218 219 master_template = (generic_attr_t *)OBJ_PUBKEY_DSA;
219 220 master_template_size = sizeof (OBJ_PUBKEY_DSA);
220 221 break;
221 222
222 223 case CKK_EC:
223 224 master_template = (generic_attr_t *)OBJ_PUBKEY_EC;
224 225 master_template_size = sizeof (OBJ_PUBKEY_EC);
225 226 break;
226 227
227 228 case CKK_DH:
228 229 master_template = (generic_attr_t *)OBJ_PUBKEY_DH;
229 230 master_template_size = sizeof (OBJ_PUBKEY_DH);
230 231 break;
231 232
232 233 case CKK_X9_42_DH:
233 234 master_template = (generic_attr_t *)OBJ_PUBKEY_X942DH;
234 235 master_template_size = sizeof (OBJ_PUBKEY_X942DH);
235 236 break;
236 237
237 238 case CKK_KEA:
238 239 master_template = (generic_attr_t *)OBJ_PUBKEY_KEA;
239 240 master_template_size = sizeof (OBJ_PUBKEY_KEA);
240 241 break;
241 242
242 243 default:
243 244 /* Unsupported. */
244 245 break;
245 246 }
246 247 break;
247 248
248 249 case CKO_PRIVATE_KEY:
249 250 switch (subtype) {
250 251 case CKK_RSA:
251 252 master_template = (generic_attr_t *)OBJ_PRIVKEY_RSA;
252 253 master_template_size = sizeof (OBJ_PRIVKEY_RSA);
253 254 break;
254 255
255 256 case CKK_DSA:
256 257 master_template = (generic_attr_t *)OBJ_PRIVKEY_DSA;
257 258 master_template_size = sizeof (OBJ_PRIVKEY_DSA);
258 259 break;
259 260
260 261 case CKK_EC:
261 262 master_template = (generic_attr_t *)OBJ_PRIVKEY_EC;
262 263 master_template_size = sizeof (OBJ_PRIVKEY_EC);
263 264 break;
264 265
265 266 case CKK_DH:
266 267 master_template = (generic_attr_t *)OBJ_PRIVKEY_DH;
267 268 master_template_size = sizeof (OBJ_PRIVKEY_DH);
268 269 break;
269 270
270 271 case CKK_X9_42_DH:
271 272 master_template = (generic_attr_t *)OBJ_PRIVKEY_X942DH;
272 273 master_template_size = sizeof (OBJ_PRIVKEY_X942DH);
273 274 break;
274 275
275 276 case CKK_KEA:
276 277 master_template = (generic_attr_t *)OBJ_PRIVKEY_KEA;
277 278 master_template_size = sizeof (OBJ_PRIVKEY_KEA);
278 279 break;
279 280
280 281 default:
281 282 /* Unsupported. */
282 283 break;
283 284 }
284 285 break;
285 286
286 287 case CKO_SECRET_KEY:
287 288 /*
288 289 * The only difference between secret keys is that some
289 290 * are valiable length (eg CKK_AES), while others are not
290 291 * (eg CKK_DES) -- and do not have a CKA_VALUE_LEN attribute.
291 292 *
292 293 * FUTURE(?): Consider using obj_seckey_withlen for unknown
293 294 * keytypes. This is the most likely choice, as new algorithms
294 295 * seem to support variable length keys. That's not the default
295 296 * now, because if people have implemented new key types with
296 297 * different attribute sets (like the mess of public/private
297 298 * key types), then incorrect behaviour would result. It's
298 299 * easier to relax this restriction than to tighten it (which
299 300 * would introduce a regression to anyone relying on this
300 301 * working for unknown key types).
301 302 *
302 303 */
303 304 switch (subtype) {
304 305 case CKK_DES:
305 306 case CKK_DES2:
306 307 case CKK_DES3:
307 308 case CKK_IDEA:
308 309 case CKK_CDMF:
309 310 case CKK_SKIPJACK:
310 311 case CKK_BATON:
311 312 case CKK_JUNIPER:
312 313 master_template = (generic_attr_t *)OBJ_SECKEY;
313 314 master_template_size = sizeof (OBJ_SECKEY);
314 315 break;
315 316
316 317 case CKK_GENERIC_SECRET:
317 318 case CKK_RC2:
318 319 case CKK_RC4:
319 320 case CKK_RC5:
320 321 case CKK_AES:
321 322 case CKK_BLOWFISH:
322 323 case CKK_CAST:
323 324 case CKK_CAST3:
324 325 case CKK_CAST128:
325 326 master_template = (generic_attr_t *)OBJ_SECKEY_WITHLEN;
326 327 master_template_size = sizeof (OBJ_SECKEY_WITHLEN);
327 328 break;
328 329
329 330 default:
330 331 /* Unsupported. */
331 332 break;
332 333 }
333 334 break;
334 335
335 336 case CKO_DOMAIN_PARAMETERS:
336 337 switch (subtype) {
337 338 case CKK_DSA:
338 339 master_template = (generic_attr_t *)OBJ_DOM_DSA;
339 340 master_template_size = sizeof (OBJ_DOM_DSA);
340 341 break;
341 342
342 343 case CKK_DH:
343 344 master_template = (generic_attr_t *)OBJ_DOM_DH;
344 345 master_template_size = sizeof (OBJ_DOM_DH);
345 346 break;
346 347
347 348 case CKK_X9_42_DH:
348 349 master_template = (generic_attr_t *)OBJ_DOM_X942DH;
349 350 master_template_size = sizeof (OBJ_DOM_X942DH);
350 351 break;
351 352
352 353 default:
353 354 /* Unsupported. */
354 355 break;
355 356 }
356 357 break;
357 358
358 359 default:
359 360 /* Unsupported. */
360 361 break;
361 362 }
362 363
363 364 /* Requested object is unknown or invalid. */
364 365 if (master_template == NULL)
365 366 return (CKR_ATTRIBUTE_VALUE_INVALID);
366 367 else {
367 368 *attributes = master_template;
368 369 *num_attributes = master_template_size;
369 370 return (CKR_OK);
370 371 }
371 372 }
372 373
373 374
374 375 /*
375 376 * get_master_attributes_by_type
376 377 *
377 378 * Returns an (statically allocated) set of object attributes, as determined by
378 379 * the specified class and subtype. The attributes are initialized to default
379 380 * values.
380 381 */
381 382 CK_RV
382 383 get_master_attributes_by_type(CK_OBJECT_CLASS class, CK_ULONG subtype,
383 384 generic_attr_t **attributes, size_t *num_attributes)
384 385 {
385 386 CK_RV rv;
386 387 generic_attr_t *master_template = NULL;
387 388 generic_attr_t *new_attributes;
388 389 size_t i, num_new_attributes, master_template_size = 0;
389 390
390 391 /* Determine the appropriate master template needed. */
391 392 rv = get_master_template_by_type(class, subtype,
392 393 &master_template, &master_template_size);
393 394 if (rv != CKR_OK)
394 395 return (rv);
395 396
396 397 /* Duplicate the master template. */
397 398 new_attributes = malloc(master_template_size);
398 399 if (new_attributes == NULL)
399 400 return (CKR_HOST_MEMORY);
400 401
401 402 (void) memcpy(new_attributes, master_template, master_template_size);
402 403 num_new_attributes = master_template_size / sizeof (generic_attr_t);
403 404
404 405 /* Set the pointer in the appropriate storage area. */
405 406 for (i = 0; i < num_new_attributes; i++) {
406 407 generic_attr_t *attr;
407 408
408 409 attr = new_attributes + i;
409 410
410 411 switch (attr->attribute.ulValueLen) {
411 412 case (sizeof (CK_ULONG)):
412 413 attr->attribute.pValue = &attr->generic_ulong;
413 414 break;
414 415 case (sizeof (CK_BBOOL)):
415 416 attr->attribute.pValue = &attr->generic_bbool;
416 417 break;
417 418 default:
418 419 attr->attribute.pValue = attr->generic_data;
419 420 break;
420 421 }
421 422
422 423 }
423 424
424 425 /* Secret keys share a common template, so set the key type here. */
425 426 if (class == CKO_SECRET_KEY) {
426 427 /* Keytype / subtype is always the second attribute. */
427 428 new_attributes[1].generic_ulong = subtype;
428 429 }
429 430
430 431 *attributes = new_attributes;
431 432 *num_attributes = num_new_attributes;
432 433
433 434 return (CKR_OK);
434 435 }
435 436
436 437
437 438 /*
438 439 * get_master_attributes_by_duplication
439 440 *
440 441 * Returns an (statically allocated) set of object attributes, as copied from an
441 442 * existing set of attributes. The new attributes inherit the values from
442 443 * the old attributes.
443 444 */
444 445 CK_RV
445 446 get_master_attributes_by_duplication(
446 447 generic_attr_t *src_attrs, size_t num_src_attrs,
447 448 generic_attr_t **dst_attrs, size_t *num_dst_attrs)
448 449 {
449 450 CK_RV rv = CKR_OK;
450 451 generic_attr_t *new_attrs, *src, *dst;
451 452 size_t i;
452 453
453 454 new_attrs = malloc(sizeof (generic_attr_t) * num_src_attrs);
454 455 if (new_attrs == NULL)
455 456 return (CKR_HOST_MEMORY);
456 457
457 458 for (i = 0; i < num_src_attrs; i++) {
458 459 src = src_attrs + i;
459 460 dst = new_attrs + i;
460 461
461 462 *dst = *src;
462 463
463 464 /* Adjust pointers in dst so that they don't point to src. */
464 465
465 466 if (src->isMalloced) {
466 467 dst->attribute.pValue =
467 468 malloc(src->attribute.ulValueLen);
468 469
469 470 if (dst->attribute.pValue == NULL) {
470 471 /*
471 472 * Continue on error, so that the cleanup
472 473 * routine doesn't see pointers to src_attrs.
473 474 */
474 475 dst->attribute.ulValueLen = 0;
475 476 rv = CKR_HOST_MEMORY;
476 477 continue;
477 478 }
478 479 } else if (src->attribute.pValue == &src->generic_bbool) {
479 480 dst->attribute.pValue = &dst->generic_bbool;
480 481 } else if (src->attribute.pValue == &src->generic_ulong) {
481 482 dst->attribute.pValue = &dst->generic_ulong;
482 483 } else if (src->attribute.pValue == &src->generic_data) {
483 484 dst->attribute.pValue = &dst->generic_data;
484 485 } else {
485 486 /* This shouldn't happen. */
486 487 dst->attribute.pValue = NULL;
487 488 dst->attribute.ulValueLen = 0;
488 489 rv = CKR_GENERAL_ERROR;
489 490 num_src_attrs = i + 1;
490 491 break;
491 492 }
492 493
493 494 (void) memcpy(dst->attribute.pValue, src->attribute.pValue,
494 495 src->attribute.ulValueLen);
495 496 }
496 497
497 498 if (rv != CKR_OK) {
498 499 dealloc_attributes(new_attrs, num_src_attrs);
499 500 } else {
500 501 *dst_attrs = new_attrs;
501 502 *num_dst_attrs = num_src_attrs;
502 503 }
503 504
504 505 return (rv);
505 506 }
506 507
507 508
508 509 /*
509 510 * dealloc_attributes
510 511 *
511 512 * Deallocates the storage used for a set of attributes. The attribute
512 513 * values are zeroed out before being free'd.
513 514 */
514 515 void
515 516 dealloc_attributes(generic_attr_t *attributes, size_t num_attributes)
516 517 {
517 518 size_t i;
518 519 generic_attr_t *attr;
↓ open down ↓ |
484 lines elided |
↑ open up ↑ |
519 520
520 521 for (i = 0; i < num_attributes; i++) {
521 522 attr = attributes + i;
522 523
523 524 /*
524 525 * Zero-out any attribute values. We could do this just for
525 526 * attributes with isSensitive == True, but it's not much
526 527 * extra work to just do them all. [Most attributes are just
527 528 * 1 or 4 bytes]
528 529 */
529 - bzero(attr->attribute.pValue, attr->attribute.ulValueLen);
530 + explicit_bzero(attr->attribute.pValue,
531 + attr->attribute.ulValueLen);
530 532
531 533 if (attr->isMalloced)
532 534 free(attr->attribute.pValue);
533 535 }
534 536
535 537 free(attributes);
536 538 }
537 539
538 540
539 541 /*
540 542 * attribute_set_value
541 543 *
542 544 * Sets the value of the specified attribute. Any portion of the old value
543 545 * which will not be overwritten by the new value is zeroed out.
544 546 */
545 547 CK_RV
546 548 attribute_set_value(CK_ATTRIBUTE *new_attr,
547 549 generic_attr_t *attributes, size_t num_attributes)
548 550 {
549 551 generic_attr_t *attr = NULL;
550 552
551 553 if (new_attr == NULL)
552 554 return (CKR_TEMPLATE_INCOMPLETE);
553 555 else if (new_attr->pValue == NULL) {
554 556 return (CKR_ATTRIBUTE_VALUE_INVALID);
555 557 }
556 558
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
557 559 find_attribute(new_attr->type, attributes, num_attributes, &attr);
558 560 if (attr == NULL) {
559 561 return (CKR_ATTRIBUTE_TYPE_INVALID);
560 562 }
561 563
562 564 /* Store the new value. */
563 565 if (attr->attribute.ulValueLen >= new_attr->ulValueLen) {
564 566 /* Existing storage is sufficient to store new value. */
565 567
566 568 /* bzero() out any data that won't be overwritten. */
567 - bzero((char *)attr->attribute.pValue + new_attr->ulValueLen,
569 + explicit_bzero((char *)attr->attribute.pValue +
570 + new_attr->ulValueLen,
568 571 attr->attribute.ulValueLen - new_attr->ulValueLen);
569 572
570 573 } else if (new_attr->ulValueLen <= sizeof (attr->generic_data)) {
571 574 /* Use generic storage to avoid a malloc. */
572 575
573 - bzero(attr->attribute.pValue, attr->attribute.ulValueLen);
576 + explicit_bzero(attr->attribute.pValue,
577 + attr->attribute.ulValueLen);
574 578 if (attr->isMalloced) {
575 579 /*
576 580 * If app sets a large value (triggering a malloc),
577 581 * then sets a tiny value, and finally again sets
578 582 * a large value (phew!) we could end up here.
579 583 *
580 584 * FUTURE?: Store the original malloc size, so that
581 585 * we can regrow the value up to the original size.
582 586 * This might avoid some heap churn for pathalogic
583 587 * applications.
584 588 */
585 589 free(attr->attribute.pValue);
586 590 attr->isMalloced = B_FALSE;
587 591 }
588 592
589 593 attr->attribute.pValue = attr->generic_data;
590 594
591 595 } else {
592 596 /* Need to allocate storage for the new value. */
593 597 void *newStorage;
594 598
595 599 newStorage = malloc(new_attr->ulValueLen);
596 600 if (newStorage == NULL)
597 601 return (CKR_HOST_MEMORY);
598 602 bzero(attr->attribute.pValue, attr->attribute.ulValueLen);
599 603 attr->attribute.pValue = newStorage;
600 604 attr->isMalloced = B_TRUE;
601 605 }
602 606
603 607 (void) memcpy(attr->attribute.pValue, new_attr->pValue,
604 608 new_attr->ulValueLen);
605 609 attr->attribute.ulValueLen = new_attr->ulValueLen;
606 610 attr->hasValueForClone = B_TRUE;
607 611
608 612 return (CKR_OK);
609 613 }
610 614
611 615
612 616 /*
613 617 * find_attribute
614 618 *
615 619 * Passes a pointer to the requested attribute, or NULL if not found.
616 620 */
617 621 static void
618 622 find_attribute(CK_ATTRIBUTE_TYPE attrtype, generic_attr_t *attributes,
619 623 size_t num_attributes, generic_attr_t **found_attribute)
620 624 {
621 625 generic_attr_t *attr;
622 626 boolean_t found = B_FALSE;
623 627 size_t i;
624 628
625 629 /* Find the requested attribute. */
626 630 for (i = 0, attr = attributes; i < num_attributes; i++, attr++) {
627 631 if (attr->attribute.type == attrtype) {
628 632 found = B_TRUE;
629 633 break;
630 634 }
631 635 }
632 636
633 637 *found_attribute = found ? attr : NULL;
634 638 }
635 639
636 640
637 641 /*
638 642 * get_template_ulong
639 643 *
640 644 * Look for the specified ulong-size attribute, and retrieve its value. The
641 645 * return value specifies if the attribute was found (or not).
642 646 */
643 647 boolean_t
644 648 get_template_ulong(CK_ATTRIBUTE_TYPE type, CK_ATTRIBUTE *attributes,
645 649 CK_ULONG num_attributes, CK_ULONG *result)
646 650 {
647 651 boolean_t found = B_FALSE;
648 652 CK_ULONG i;
649 653
650 654 for (i = 0; i < num_attributes; i++) {
651 655 if (attributes[i].type == type) {
652 656 CK_ULONG *value = attributes[i].pValue;
653 657
654 658 *result = *value;
655 659 found = B_TRUE;
656 660 break;
657 661 }
658 662 }
659 663
660 664 return (found);
661 665 }
662 666
663 667
664 668 /*
665 669 * get_template_boolean
666 670 *
667 671 * Look for the specified boolean attribute, and retrieve its value. The
668 672 * return value specifies if the attribute was found (or not).
669 673 */
670 674 boolean_t
671 675 get_template_boolean(CK_ATTRIBUTE_TYPE type, CK_ATTRIBUTE *attributes,
672 676 CK_ULONG num_attributes, boolean_t *result)
673 677 {
674 678 boolean_t found = B_FALSE;
675 679 CK_ULONG i;
676 680
677 681 for (i = 0; i < num_attributes; i++) {
678 682 if (attributes[i].type == type) {
679 683 CK_BBOOL *value = attributes[i].pValue;
680 684
681 685 if (*value == CK_FALSE)
682 686 *result = B_FALSE;
683 687 else
684 688 *result = B_TRUE;
685 689
686 690 found = B_TRUE;
687 691 break;
688 692 }
689 693 }
690 694
691 695 return (found);
692 696 }
693 697
694 698 /*
695 699 * set_template_boolean
696 700 *
697 701 * Look for the specified boolean attribute, and set its value.
698 702 *
699 703 * if 'local' is true, it sets the pointer to the value in the template a new
700 704 * location. There should be no memory leak created by this because we are
701 705 * only doing this to booleans which should not be malloc'ed.
702 706 *
703 707 * if 'local' is false, it sets its value.
704 708 *
705 709 * The return value specifies if the attribute was found (or not).
706 710 */
707 711 int
708 712 set_template_boolean(CK_ATTRIBUTE_TYPE type, CK_ATTRIBUTE *attributes,
709 713 CK_ULONG num_attributes, boolean_t local, CK_BBOOL *value)
710 714 {
711 715 int i;
712 716
713 717 for (i = 0; i < num_attributes; i++) {
714 718 if (attributes[i].type == type) {
715 719 if (local)
716 720 attributes[i].pValue = value;
717 721 else
718 722 *((CK_BBOOL *)attributes[i].pValue) = *value;
719 723
720 724 return (i);
721 725 }
722 726 }
723 727
724 728 return (-1);
725 729 }
↓ open down ↓ |
142 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX