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/pkcs11_softtoken/common/softAttributeUtil.c
+++ new/usr/src/lib/pkcs11/pkcs11_softtoken/common/softAttributeUtil.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 2009 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 <stdlib.h>
28 29 #include <string.h>
29 30 #include <security/cryptoki.h>
30 31 #include <sys/crypto/common.h>
31 32 #include <arcfour.h>
32 33 #include <aes_impl.h>
33 34 #include <blowfish_impl.h>
34 35 #include <bignum.h>
35 36 #include <des_impl.h>
36 37 #include <rsa_impl.h>
37 38 #include "softGlobal.h"
38 39 #include "softObject.h"
39 40 #include "softSession.h"
40 41 #include "softKeystore.h"
41 42 #include "softKeystoreUtil.h"
42 43 #include "softCrypt.h"
43 44
44 45
45 46 /*
46 47 * This attribute table is used by the soft_lookup_attr()
47 48 * to validate the attributes.
48 49 */
49 50 CK_ATTRIBUTE_TYPE attr_map[] = {
50 51 CKA_PRIVATE,
51 52 CKA_LABEL,
52 53 CKA_APPLICATION,
53 54 CKA_OBJECT_ID,
54 55 CKA_CERTIFICATE_TYPE,
55 56 CKA_ISSUER,
56 57 CKA_SERIAL_NUMBER,
57 58 CKA_AC_ISSUER,
58 59 CKA_OWNER,
59 60 CKA_ATTR_TYPES,
60 61 CKA_SUBJECT,
61 62 CKA_ID,
62 63 CKA_SENSITIVE,
63 64 CKA_START_DATE,
64 65 CKA_END_DATE,
65 66 CKA_MODULUS,
66 67 CKA_MODULUS_BITS,
67 68 CKA_PUBLIC_EXPONENT,
68 69 CKA_PRIVATE_EXPONENT,
69 70 CKA_PRIME_1,
70 71 CKA_PRIME_2,
71 72 CKA_EXPONENT_1,
72 73 CKA_EXPONENT_2,
73 74 CKA_COEFFICIENT,
74 75 CKA_PRIME,
75 76 CKA_SUBPRIME,
76 77 CKA_BASE,
77 78 CKA_EXTRACTABLE,
78 79 CKA_LOCAL,
79 80 CKA_NEVER_EXTRACTABLE,
80 81 CKA_ALWAYS_SENSITIVE,
81 82 CKA_MODIFIABLE,
82 83 CKA_ECDSA_PARAMS,
83 84 CKA_EC_PARAMS,
84 85 CKA_EC_POINT,
85 86 CKA_SECONDARY_AUTH,
86 87 CKA_AUTH_PIN_FLAGS,
87 88 CKA_HW_FEATURE_TYPE,
88 89 CKA_RESET_ON_INIT,
89 90 CKA_HAS_RESET
90 91 };
91 92
92 93 /*
93 94 * attributes that exists only in public key objects
94 95 * Note: some attributes may also exist in one or two
95 96 * other object classes, but they are also listed
96 97 * because not all object have them.
97 98 */
98 99 CK_ATTRIBUTE_TYPE PUB_KEY_ATTRS[] =
99 100 {
100 101 CKA_SUBJECT,
101 102 CKA_ENCRYPT,
102 103 CKA_WRAP,
103 104 CKA_VERIFY,
104 105 CKA_VERIFY_RECOVER,
105 106 CKA_MODULUS,
106 107 CKA_MODULUS_BITS,
107 108 CKA_PUBLIC_EXPONENT,
108 109 CKA_PRIME,
109 110 CKA_SUBPRIME,
110 111 CKA_BASE,
111 112 CKA_TRUSTED,
112 113 CKA_ECDSA_PARAMS,
113 114 CKA_EC_PARAMS,
114 115 CKA_EC_POINT
115 116 };
116 117
117 118 /*
118 119 * attributes that exists only in private key objects
119 120 * Note: some attributes may also exist in one or two
120 121 * other object classes, but they are also listed
121 122 * because not all object have them.
122 123 */
123 124 CK_ATTRIBUTE_TYPE PRIV_KEY_ATTRS[] =
124 125 {
125 126 CKA_DECRYPT,
126 127 CKA_UNWRAP,
127 128 CKA_SIGN,
128 129 CKA_SIGN_RECOVER,
129 130 CKA_MODULUS,
130 131 CKA_PUBLIC_EXPONENT,
131 132 CKA_PRIVATE_EXPONENT,
132 133 CKA_PRIME,
133 134 CKA_SUBPRIME,
134 135 CKA_BASE,
135 136 CKA_PRIME_1,
136 137 CKA_PRIME_2,
137 138 CKA_EXPONENT_1,
138 139 CKA_EXPONENT_2,
139 140 CKA_COEFFICIENT,
140 141 CKA_VALUE_BITS,
141 142 CKA_SUBJECT,
142 143 CKA_SENSITIVE,
143 144 CKA_EXTRACTABLE,
144 145 CKA_NEVER_EXTRACTABLE,
145 146 CKA_ALWAYS_SENSITIVE,
146 147 CKA_EC_PARAMS
147 148 };
148 149
149 150 /*
150 151 * attributes that exists only in secret key objects
151 152 * Note: some attributes may also exist in one or two
152 153 * other object classes, but they are also listed
153 154 * because not all object have them.
154 155 */
155 156 CK_ATTRIBUTE_TYPE SECRET_KEY_ATTRS[] =
156 157 {
157 158 CKA_VALUE_LEN,
158 159 CKA_ENCRYPT,
159 160 CKA_DECRYPT,
160 161 CKA_WRAP,
161 162 CKA_UNWRAP,
162 163 CKA_SIGN,
163 164 CKA_VERIFY,
164 165 CKA_SENSITIVE,
165 166 CKA_EXTRACTABLE,
166 167 CKA_NEVER_EXTRACTABLE,
167 168 CKA_ALWAYS_SENSITIVE
168 169 };
169 170
170 171 /*
171 172 * attributes that exists only in domain parameter objects
172 173 * Note: some attributes may also exist in one or two
173 174 * other object classes, but they are also listed
174 175 * because not all object have them.
175 176 */
176 177 CK_ATTRIBUTE_TYPE DOMAIN_ATTRS[] =
177 178 {
178 179 CKA_PRIME,
179 180 CKA_SUBPRIME,
180 181 CKA_BASE,
181 182 CKA_PRIME_BITS,
182 183 CKA_SUBPRIME_BITS,
183 184 CKA_SUB_PRIME_BITS
184 185 };
185 186
186 187 /*
187 188 * attributes that exists only in hardware feature objects
188 189 *
189 190 */
190 191 CK_ATTRIBUTE_TYPE HARDWARE_ATTRS[] =
191 192 {
192 193 CKA_HW_FEATURE_TYPE,
193 194 CKA_RESET_ON_INIT,
194 195 CKA_HAS_RESET
195 196 };
196 197
197 198 /*
198 199 * attributes that exists only in certificate objects
199 200 */
200 201 CK_ATTRIBUTE_TYPE CERT_ATTRS[] =
201 202 {
202 203 CKA_CERTIFICATE_TYPE,
203 204 CKA_TRUSTED,
204 205 CKA_SUBJECT,
205 206 CKA_ID,
206 207 CKA_ISSUER,
207 208 CKA_AC_ISSUER,
208 209 CKA_SERIAL_NUMBER,
209 210 CKA_OWNER,
210 211 CKA_ATTR_TYPES
211 212 };
212 213
213 214
214 215 /*
215 216 * Validate the attribute by using binary search algorithm.
216 217 */
217 218 CK_RV
218 219 soft_lookup_attr(CK_ATTRIBUTE_TYPE type)
219 220 {
220 221
221 222 size_t lower, middle, upper;
222 223
223 224 lower = 0;
224 225 upper = (sizeof (attr_map) / sizeof (CK_ATTRIBUTE_TYPE)) - 1;
225 226
226 227 while (lower <= upper) {
227 228 /* Always starts from middle. */
228 229 middle = (lower + upper) / 2;
229 230
230 231 if (type > attr_map[middle]) {
231 232 /* Adjust the lower bound to upper half. */
232 233 lower = middle + 1;
233 234 continue;
234 235 }
235 236
236 237 if (type == attr_map[middle]) {
237 238 /* Found it. */
238 239 return (CKR_OK);
239 240 }
240 241
241 242 if (type < attr_map[middle]) {
242 243 /* Adjust the upper bound to lower half. */
243 244 upper = middle - 1;
244 245 continue;
245 246 }
246 247 }
247 248
248 249 /* Failed to find the matching attribute from the attribute table. */
249 250 return (CKR_ATTRIBUTE_TYPE_INVALID);
250 251 }
251 252
252 253
253 254 /*
254 255 * Validate the attribute by using the following search algorithm:
255 256 *
256 257 * 1) Search for the most frequently used attributes first.
257 258 * 2) If not found, search for the usage-purpose attributes - these
258 259 * attributes have dense set of values, therefore compiler will
259 260 * optimize it with a branch table and branch to the appropriate
260 261 * case.
261 262 * 3) If still not found, use binary search for the rest of the
262 263 * attributes in the attr_map[] table.
263 264 */
264 265 CK_RV
265 266 soft_validate_attr(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
266 267 CK_OBJECT_CLASS *class)
267 268 {
268 269
269 270 CK_ULONG i;
270 271 CK_RV rv = CKR_OK;
271 272
272 273 for (i = 0; i < ulAttrNum; i++) {
273 274 /* First tier search */
274 275 switch (template[i].type) {
275 276 case CKA_CLASS:
276 277 *class = *((CK_OBJECT_CLASS*)template[i].pValue);
277 278 break;
278 279 case CKA_TOKEN:
279 280 break;
280 281 case CKA_KEY_TYPE:
281 282 break;
282 283 case CKA_VALUE:
283 284 break;
284 285 case CKA_VALUE_LEN:
285 286 break;
286 287 case CKA_VALUE_BITS:
287 288 break;
288 289 default:
289 290 /* Second tier search */
290 291 switch (template[i].type) {
291 292 case CKA_ENCRYPT:
292 293 break;
293 294 case CKA_DECRYPT:
294 295 break;
295 296 case CKA_WRAP:
296 297 break;
297 298 case CKA_UNWRAP:
298 299 break;
299 300 case CKA_SIGN:
300 301 break;
301 302 case CKA_SIGN_RECOVER:
302 303 break;
303 304 case CKA_VERIFY:
304 305 break;
305 306 case CKA_VERIFY_RECOVER:
306 307 break;
307 308 case CKA_DERIVE:
308 309 break;
309 310 default:
310 311 /* Third tier search */
311 312 rv = soft_lookup_attr(template[i].type);
312 313 if (rv != CKR_OK)
313 314 return (rv);
314 315 break;
↓ open down ↓ |
280 lines elided |
↑ open up ↑ |
315 316 }
316 317 break;
317 318 }
318 319 }
319 320 return (rv);
320 321 }
321 322
322 323 static void
323 324 cleanup_cert_attr(cert_attr_t *attr)
324 325 {
325 - if (attr) {
326 - if (attr->value) {
327 - (void) memset(attr->value, 0, attr->length);
328 - free(attr->value);
329 - }
326 + if (attr != NULL) {
327 + freezero(attr->value, attr->length);
330 328 attr->value = NULL;
331 329 attr->length = 0;
332 330 }
333 331 }
334 332
335 333 static CK_RV
336 334 copy_cert_attr(cert_attr_t *src_attr, cert_attr_t **dest_attr)
337 335 {
338 336 CK_RV rv = CKR_OK;
339 337
340 338 if (src_attr == NULL || dest_attr == NULL)
341 339 return (CKR_HOST_MEMORY);
342 340
343 341 if (src_attr->value == NULL)
344 342 return (CKR_HOST_MEMORY);
345 343
346 344 /* free memory if its already allocated */
347 345 if (*dest_attr != NULL) {
348 - if ((*dest_attr)->value != (CK_BYTE *)NULL)
349 - free((*dest_attr)->value);
346 + cleanup_cert_attr(*dest_attr);
350 347 } else {
351 348 *dest_attr = malloc(sizeof (cert_attr_t));
352 349 if (*dest_attr == NULL)
353 350 return (CKR_HOST_MEMORY);
354 351 }
355 352
356 353 (*dest_attr)->value = NULL;
357 354 (*dest_attr)->length = 0;
358 355
359 356 if (src_attr->length) {
360 357 (*dest_attr)->value = malloc(src_attr->length);
361 358 if ((*dest_attr)->value == NULL) {
362 359 free(*dest_attr);
363 360 return (CKR_HOST_MEMORY);
364 361 }
365 362
366 363 (void) memcpy((*dest_attr)->value, src_attr->value,
367 364 src_attr->length);
368 365 (*dest_attr)->length = src_attr->length;
369 366 }
370 367
371 368 return (rv);
372 369 }
373 370
374 371 void
375 372 soft_cleanup_cert_object(soft_object_t *object_p)
376 373 {
377 374 CK_CERTIFICATE_TYPE certtype = object_p->cert_type;
378 375
379 376 if (object_p->class != CKO_CERTIFICATE ||
380 377 OBJ_CERT(object_p) == NULL)
381 378 return;
382 379
383 380 if (certtype == CKC_X_509) {
384 381 if (X509_CERT_SUBJECT(object_p) != NULL) {
385 382 cleanup_cert_attr(X509_CERT_SUBJECT(object_p));
386 383 free(X509_CERT_SUBJECT(object_p));
387 384 X509_CERT_SUBJECT(object_p) = NULL;
388 385 }
389 386 if (X509_CERT_VALUE(object_p) != NULL) {
390 387 cleanup_cert_attr(X509_CERT_VALUE(object_p));
391 388 free(X509_CERT_VALUE(object_p));
392 389 X509_CERT_VALUE(object_p) = NULL;
393 390 }
394 391 free(OBJ_CERT(object_p));
395 392 } else if (certtype == CKC_X_509_ATTR_CERT) {
396 393 if (X509_ATTR_CERT_VALUE(object_p) != NULL) {
397 394 cleanup_cert_attr(X509_ATTR_CERT_VALUE(object_p));
398 395 free(X509_ATTR_CERT_VALUE(object_p));
399 396 X509_ATTR_CERT_VALUE(object_p) = NULL;
400 397 }
401 398 if (X509_ATTR_CERT_OWNER(object_p) != NULL) {
402 399 cleanup_cert_attr(X509_ATTR_CERT_OWNER(object_p));
403 400 free(X509_ATTR_CERT_OWNER(object_p));
404 401 X509_ATTR_CERT_OWNER(object_p) = NULL;
405 402 }
406 403 free(OBJ_CERT(object_p));
407 404 }
408 405 }
409 406
410 407 /*
411 408 * Clean up and release all the storage in the extra attribute list
412 409 * of an object.
413 410 */
↓ open down ↓ |
54 lines elided |
↑ open up ↑ |
414 411 void
415 412 soft_cleanup_extra_attr(soft_object_t *object_p)
416 413 {
417 414
418 415 CK_ATTRIBUTE_INFO_PTR extra_attr;
419 416 CK_ATTRIBUTE_INFO_PTR tmp;
420 417
421 418 extra_attr = object_p->extra_attrlistp;
422 419 while (extra_attr) {
423 420 tmp = extra_attr->next;
424 - if (extra_attr->attr.pValue)
421 + if (extra_attr->attr.pValue != NULL) {
425 422 /*
426 423 * All extra attributes in the extra attribute
427 424 * list have pValue points to the value of the
428 425 * attribute (with simple byte array type).
429 426 * Free the storage for the value of the attribute.
430 427 */
431 - free(extra_attr->attr.pValue);
428 + freezero(extra_attr->attr.pValue,
429 + extra_attr->attr.ulValueLen);
430 + }
432 431
433 432 /* Free the storage for the attribute_info struct. */
434 433 free(extra_attr);
435 434 extra_attr = tmp;
436 435 }
437 436
438 437 object_p->extra_attrlistp = NULL;
439 438 }
440 439
441 440
442 441 /*
443 442 * Create the attribute_info struct to hold the object's attribute,
444 443 * and add it to the extra attribute list of an object.
445 444 */
446 445 CK_RV
447 446 soft_add_extra_attr(CK_ATTRIBUTE_PTR template, soft_object_t *object_p)
448 447 {
449 448
450 449 CK_ATTRIBUTE_INFO_PTR attrp;
451 450
452 451 /* Allocate the storage for the attribute_info struct. */
453 452 attrp = calloc(1, sizeof (attribute_info_t));
454 453 if (attrp == NULL) {
455 454 return (CKR_HOST_MEMORY);
456 455 }
457 456
458 457 /* Set up attribute_info struct. */
459 458 attrp->attr.type = template->type;
460 459 attrp->attr.ulValueLen = template->ulValueLen;
461 460
462 461 if ((template->pValue != NULL) &&
463 462 (template->ulValueLen > 0)) {
464 463 /* Allocate storage for the value of the attribute. */
465 464 attrp->attr.pValue = malloc(template->ulValueLen);
466 465 if (attrp->attr.pValue == NULL) {
467 466 free(attrp);
468 467 return (CKR_HOST_MEMORY);
469 468 }
470 469
471 470 (void) memcpy(attrp->attr.pValue, template->pValue,
472 471 template->ulValueLen);
473 472 } else {
474 473 attrp->attr.pValue = NULL;
475 474 }
476 475
477 476 /* Insert the new attribute in front of extra attribute list. */
478 477 if (object_p->extra_attrlistp == NULL) {
479 478 object_p->extra_attrlistp = attrp;
480 479 attrp->next = NULL;
481 480 } else {
482 481 attrp->next = object_p->extra_attrlistp;
483 482 object_p->extra_attrlistp = attrp;
484 483 }
485 484
486 485 return (CKR_OK);
487 486 }
488 487
489 488 CK_RV
490 489 soft_copy_certificate(certificate_obj_t *oldcert, certificate_obj_t **newcert,
491 490 CK_CERTIFICATE_TYPE type)
492 491 {
493 492 CK_RV rv = CKR_OK;
494 493 certificate_obj_t *cert;
495 494 x509_cert_t x509;
496 495 x509_attr_cert_t x509_attr;
497 496
498 497 cert = calloc(1, sizeof (certificate_obj_t));
499 498 if (cert == NULL) {
500 499 return (CKR_HOST_MEMORY);
501 500 }
502 501
503 502 if (type == CKC_X_509) {
504 503 x509 = oldcert->cert_type_u.x509;
505 504 if (x509.subject)
506 505 if ((rv = copy_cert_attr(x509.subject,
507 506 &cert->cert_type_u.x509.subject)))
508 507 return (rv);
509 508 if (x509.value)
510 509 if ((rv = copy_cert_attr(x509.value,
511 510 &cert->cert_type_u.x509.value)))
512 511 return (rv);
513 512 } else if (type == CKC_X_509_ATTR_CERT) {
514 513 x509_attr = oldcert->cert_type_u.x509_attr;
515 514 if (x509_attr.owner)
516 515 if ((rv = copy_cert_attr(x509_attr.owner,
517 516 &cert->cert_type_u.x509_attr.owner)))
518 517 return (rv);
519 518 if (x509_attr.value)
520 519 if ((rv = copy_cert_attr(x509_attr.value,
521 520 &cert->cert_type_u.x509_attr.value)))
522 521 return (rv);
523 522 } else {
524 523 /* wrong certificate type */
525 524 rv = CKR_ATTRIBUTE_TYPE_INVALID;
526 525 }
527 526 if (rv == CKR_OK)
528 527 *newcert = cert;
529 528 return (rv);
530 529 }
531 530
532 531 /*
533 532 * Copy the attribute_info struct from the old object to a new attribute_info
534 533 * struct, and add that new struct to the extra attribute list of the new
535 534 * object.
536 535 */
537 536 CK_RV
538 537 soft_copy_extra_attr(CK_ATTRIBUTE_INFO_PTR old_attrp, soft_object_t *object_p)
539 538 {
540 539 CK_ATTRIBUTE_INFO_PTR attrp;
541 540
542 541 /* Allocate attribute_info struct. */
543 542 attrp = calloc(1, sizeof (attribute_info_t));
544 543 if (attrp == NULL) {
545 544 return (CKR_HOST_MEMORY);
546 545 }
547 546
548 547 attrp->attr.type = old_attrp->attr.type;
549 548 attrp->attr.ulValueLen = old_attrp->attr.ulValueLen;
550 549
551 550 if ((old_attrp->attr.pValue != NULL) &&
552 551 (old_attrp->attr.ulValueLen > 0)) {
553 552 attrp->attr.pValue = malloc(old_attrp->attr.ulValueLen);
554 553 if (attrp->attr.pValue == NULL) {
555 554 free(attrp);
556 555 return (CKR_HOST_MEMORY);
557 556 }
558 557
559 558 (void) memcpy(attrp->attr.pValue, old_attrp->attr.pValue,
560 559 old_attrp->attr.ulValueLen);
561 560 } else {
562 561 attrp->attr.pValue = NULL;
563 562 }
564 563
565 564 /* Insert the new attribute in front of extra attribute list */
566 565 if (object_p->extra_attrlistp == NULL) {
567 566 object_p->extra_attrlistp = attrp;
568 567 attrp->next = NULL;
569 568 } else {
570 569 attrp->next = object_p->extra_attrlistp;
571 570 object_p->extra_attrlistp = attrp;
572 571 }
573 572
574 573 return (CKR_OK);
575 574 }
576 575
577 576
578 577 /*
579 578 * Get the attribute triple from the extra attribute list in the object
580 579 * (if the specified attribute type is found), and copy it to a template.
581 580 * Note the type of the attribute to be copied is specified by the template,
582 581 * and the storage is pre-allocated for the atrribute value in the template
583 582 * for doing the copy.
584 583 */
585 584 CK_RV
586 585 get_extra_attr_from_object(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
587 586 {
588 587
589 588 CK_ATTRIBUTE_INFO_PTR extra_attr;
590 589 CK_ATTRIBUTE_TYPE type = template->type;
591 590
592 591 extra_attr = object_p->extra_attrlistp;
593 592
594 593 while (extra_attr) {
595 594 if (type == extra_attr->attr.type) {
596 595 /* Found it. */
597 596 break;
598 597 } else {
599 598 /* Does not match, try next one. */
600 599 extra_attr = extra_attr->next;
601 600 }
602 601 }
603 602
604 603 if (extra_attr == NULL) {
605 604 /* A valid but un-initialized attribute. */
606 605 template->ulValueLen = 0;
607 606 return (CKR_OK);
608 607 }
609 608
610 609 /*
611 610 * We found the attribute in the extra attribute list.
612 611 */
613 612 if (template->pValue == NULL) {
614 613 template->ulValueLen = extra_attr->attr.ulValueLen;
615 614 return (CKR_OK);
616 615 }
617 616
618 617 if (template->ulValueLen >= extra_attr->attr.ulValueLen) {
619 618 /*
620 619 * The buffer provided by the application is large
621 620 * enough to hold the value of the attribute.
622 621 */
623 622 (void) memcpy(template->pValue, extra_attr->attr.pValue,
624 623 extra_attr->attr.ulValueLen);
625 624 template->ulValueLen = extra_attr->attr.ulValueLen;
626 625 return (CKR_OK);
627 626 } else {
628 627 /*
629 628 * The buffer provided by the application does
630 629 * not have enough space to hold the value.
631 630 */
632 631 template->ulValueLen = (CK_ULONG)-1;
633 632 return (CKR_BUFFER_TOO_SMALL);
634 633 }
635 634 }
636 635
637 636
638 637 /*
639 638 * Modify the attribute triple in the extra attribute list of the object
640 639 * if the specified attribute type is found. Otherwise, just add it to
641 640 * list.
642 641 */
643 642 CK_RV
644 643 set_extra_attr_to_object(soft_object_t *object_p, CK_ATTRIBUTE_TYPE type,
645 644 CK_ATTRIBUTE_PTR template)
646 645 {
647 646
648 647 CK_ATTRIBUTE_INFO_PTR extra_attr;
649 648
650 649 extra_attr = object_p->extra_attrlistp;
651 650
652 651 while (extra_attr) {
653 652 if (type == extra_attr->attr.type) {
654 653 /* Found it. */
655 654 break;
656 655 } else {
657 656 /* Does not match, try next one. */
658 657 extra_attr = extra_attr->next;
659 658 }
660 659 }
661 660
662 661 if (extra_attr == NULL) {
663 662 /*
664 663 * This attribute is a new one, go ahead adding it to
↓ open down ↓ |
223 lines elided |
↑ open up ↑ |
665 664 * the extra attribute list.
666 665 */
667 666 return (soft_add_extra_attr(template, object_p));
668 667 }
669 668
670 669 /* We found the attribute in the extra attribute list. */
671 670 if ((template->pValue != NULL) &&
672 671 (template->ulValueLen > 0)) {
673 672 if (template->ulValueLen > extra_attr->attr.ulValueLen) {
674 673 /* The old buffer is too small to hold the new value. */
675 - if (extra_attr->attr.pValue != NULL)
674 + if (extra_attr->attr.pValue != NULL) {
676 675 /* Free storage for the old attribute value. */
677 - free(extra_attr->attr.pValue);
676 + freezero(extra_attr->attr.pValue,
677 + extra_attr->attr.ulValueLen);
678 + }
678 679
679 680 /* Allocate storage for the new attribute value. */
680 681 extra_attr->attr.pValue = malloc(template->ulValueLen);
681 682 if (extra_attr->attr.pValue == NULL) {
682 683 return (CKR_HOST_MEMORY);
683 684 }
684 685 }
685 686
686 687 /* Replace the attribute with new value. */
687 688 extra_attr->attr.ulValueLen = template->ulValueLen;
688 689 (void) memcpy(extra_attr->attr.pValue, template->pValue,
689 690 template->ulValueLen);
690 691 } else {
691 692 extra_attr->attr.pValue = NULL;
692 693 }
693 694
694 695 return (CKR_OK);
695 696 }
696 697
697 698
698 699 /*
699 700 * Copy the big integer attribute value from template to a biginteger_t struct.
700 701 */
701 702 CK_RV
702 703 get_bigint_attr_from_template(biginteger_t *big, CK_ATTRIBUTE_PTR template)
703 704 {
704 705
705 706 if ((template->pValue != NULL) &&
706 707 (template->ulValueLen > 0)) {
707 708 /* Allocate storage for the value of the attribute. */
708 709 big->big_value = malloc(template->ulValueLen);
709 710 if (big->big_value == NULL) {
710 711 return (CKR_HOST_MEMORY);
711 712 }
712 713
713 714 (void) memcpy(big->big_value, template->pValue,
714 715 template->ulValueLen);
715 716 big->big_value_len = template->ulValueLen;
716 717 } else {
717 718 big->big_value = NULL;
718 719 big->big_value_len = 0;
719 720 }
720 721
721 722 return (CKR_OK);
722 723 }
723 724
724 725
725 726 /*
726 727 * Copy the big integer attribute value from a biginteger_t struct in the
727 728 * object to a template.
728 729 */
729 730 CK_RV
730 731 get_bigint_attr_from_object(biginteger_t *big, CK_ATTRIBUTE_PTR template)
731 732 {
732 733
733 734 if (template->pValue == NULL) {
734 735 template->ulValueLen = big->big_value_len;
735 736 return (CKR_OK);
736 737 }
737 738
738 739 if (big->big_value == NULL) {
739 740 template->ulValueLen = 0;
740 741 return (CKR_OK);
741 742 }
742 743
743 744 if (template->ulValueLen >= big->big_value_len) {
744 745 /*
745 746 * The buffer provided by the application is large
746 747 * enough to hold the value of the attribute.
747 748 */
748 749 (void) memcpy(template->pValue, big->big_value,
749 750 big->big_value_len);
750 751 template->ulValueLen = big->big_value_len;
751 752 return (CKR_OK);
752 753 } else {
753 754 /*
754 755 * The buffer provided by the application does
755 756 * not have enough space to hold the value.
756 757 */
757 758 template->ulValueLen = (CK_ULONG)-1;
758 759 return (CKR_BUFFER_TOO_SMALL);
759 760 }
760 761 }
761 762
762 763
763 764 /*
764 765 * Copy the boolean data type attribute value from an object for the
765 766 * specified attribute to the template.
766 767 */
767 768 CK_RV
768 769 get_bool_attr_from_object(soft_object_t *object_p, CK_ULONG bool_flag,
769 770 CK_ATTRIBUTE_PTR template)
770 771 {
771 772
772 773 if (template->pValue == NULL) {
773 774 template->ulValueLen = sizeof (CK_BBOOL);
774 775 return (CKR_OK);
775 776 }
776 777
777 778 if (template->ulValueLen >= sizeof (CK_BBOOL)) {
778 779 /*
779 780 * The buffer provided by the application is large
780 781 * enough to hold the value of the attribute.
781 782 */
782 783 if (object_p->bool_attr_mask & bool_flag) {
783 784 *((CK_BBOOL *)template->pValue) = B_TRUE;
784 785 } else {
785 786 *((CK_BBOOL *)template->pValue) = B_FALSE;
786 787 }
787 788
788 789 template->ulValueLen = sizeof (CK_BBOOL);
789 790 return (CKR_OK);
790 791 } else {
791 792 /*
792 793 * The buffer provided by the application does
793 794 * not have enough space to hold the value.
794 795 */
795 796 template->ulValueLen = (CK_ULONG)-1;
796 797 return (CKR_BUFFER_TOO_SMALL);
797 798 }
798 799 }
799 800
800 801 /*
801 802 * Set the boolean data type attribute value in the object.
802 803 */
803 804 CK_RV
804 805 set_bool_attr_to_object(soft_object_t *object_p, CK_ULONG bool_flag,
805 806 CK_ATTRIBUTE_PTR template)
806 807 {
807 808
808 809 if (*(CK_BBOOL *)template->pValue)
809 810 object_p->bool_attr_mask |= bool_flag;
810 811 else
811 812 object_p->bool_attr_mask &= ~bool_flag;
812 813
813 814 return (CKR_OK);
814 815 }
815 816
816 817
817 818 /*
818 819 * Copy the CK_ULONG data type attribute value from an object to the
819 820 * template.
820 821 */
821 822 CK_RV
822 823 get_ulong_attr_from_object(CK_ULONG value, CK_ATTRIBUTE_PTR template)
823 824 {
824 825
825 826 if (template->pValue == NULL) {
826 827 template->ulValueLen = sizeof (CK_ULONG);
827 828 return (CKR_OK);
828 829 }
829 830
830 831 if (template->ulValueLen >= sizeof (CK_ULONG)) {
831 832 /*
832 833 * The buffer provided by the application is large
833 834 * enough to hold the value of the attribute.
834 835 * It is also assumed to be correctly aligned.
835 836 */
836 837 *(CK_ULONG_PTR)template->pValue = value;
837 838 template->ulValueLen = sizeof (CK_ULONG);
838 839 return (CKR_OK);
839 840 } else {
840 841 /*
841 842 * The buffer provided by the application does
842 843 * not have enough space to hold the value.
843 844 */
844 845 template->ulValueLen = (CK_ULONG)-1;
845 846 return (CKR_BUFFER_TOO_SMALL);
846 847 }
847 848 }
848 849
849 850
850 851 /*
851 852 * Copy the CK_ULONG data type attribute value from a template to the
852 853 * object.
853 854 */
854 855 static CK_RV
855 856 get_ulong_attr_from_template(CK_ULONG *value, CK_ATTRIBUTE_PTR template)
856 857 {
857 858
858 859 if (template->ulValueLen < sizeof (CK_ULONG))
859 860 return (CKR_ATTRIBUTE_VALUE_INVALID);
860 861
861 862 if (template->pValue != NULL) {
862 863 *value = *(CK_ULONG_PTR)template->pValue;
863 864 } else {
864 865 *value = 0;
865 866 }
866 867
867 868 return (CKR_OK);
868 869 }
869 870
870 871 /*
871 872 * Copy the big integer attribute value from source's biginteger_t to
872 873 * destination's biginteger_t.
873 874 */
874 875 void
875 876 copy_bigint_attr(biginteger_t *src, biginteger_t *dst)
876 877 {
877 878
878 879 if ((src->big_value != NULL) &&
879 880 (src->big_value_len > 0)) {
880 881 /*
881 882 * To do the copy, just have dst's big_value points
882 883 * to src's.
883 884 */
884 885 dst->big_value = src->big_value;
885 886 dst->big_value_len = src->big_value_len;
886 887
887 888 /*
888 889 * After the copy, nullify the src's big_value pointer.
889 890 * It prevents any double freeing the value.
890 891 */
891 892 src->big_value = NULL;
892 893 src->big_value_len = 0;
893 894 } else {
894 895 dst->big_value = NULL;
895 896 dst->big_value_len = 0;
896 897 }
897 898 }
898 899
899 900 CK_RV
900 901 get_string_from_template(CK_ATTRIBUTE_PTR dest, CK_ATTRIBUTE_PTR src)
901 902 {
902 903 if ((src->pValue != NULL) &&
903 904 (src->ulValueLen > 0)) {
904 905 /* Allocate storage for the value of the attribute. */
905 906 dest->pValue = malloc(src->ulValueLen);
906 907 if (dest->pValue == NULL) {
907 908 return (CKR_HOST_MEMORY);
908 909 }
909 910
910 911 (void) memcpy(dest->pValue, src->pValue,
911 912 src->ulValueLen);
912 913 dest->ulValueLen = src->ulValueLen;
913 914 dest->type = src->type;
914 915 } else {
915 916 dest->pValue = NULL;
916 917 dest->ulValueLen = 0;
917 918 dest->type = src->type;
918 919 }
919 920
920 921 return (CKR_OK);
921 922
922 923 }
↓ open down ↓ |
235 lines elided |
↑ open up ↑ |
923 924
924 925 CK_RV
925 926 get_cert_attr_from_template(cert_attr_t **dest, CK_ATTRIBUTE_PTR src)
926 927 {
927 928 if (src->pValue != NULL && src->ulValueLen > 0) {
928 929 /*
929 930 * If the attribute was already set, clear out the
930 931 * existing value and release the memory.
931 932 */
932 933 if (*dest != NULL) {
933 - if ((*dest)->value != NULL) {
934 - (void) memset((*dest)->value, 0,
935 - (*dest)->length);
936 - free((*dest)->value);
937 - }
934 + cleanup_cert_attr(*dest);
938 935 } else {
939 936 *dest = malloc(sizeof (cert_attr_t));
940 937 if (*dest == NULL) {
941 938 return (CKR_HOST_MEMORY);
942 939 }
943 940 (void) memset(*dest, 0, sizeof (cert_attr_t));
944 941 }
945 942 (*dest)->value = malloc(src->ulValueLen);
946 943 if ((*dest)->value == NULL) {
947 944 free(*dest);
948 945 *dest = NULL;
949 946 return (CKR_HOST_MEMORY);
950 947 }
951 948 (void) memcpy((*dest)->value, src->pValue, src->ulValueLen);
952 949 (*dest)->length = src->ulValueLen;
953 950 }
954 951
955 952 return (CKR_OK);
956 953 }
957 954
958 955 /*
959 956 * Copy the certificate attribute information to the template.
960 957 * If the template attribute is not big enough, set the ulValueLen=-1
961 958 * and return CKR_BUFFER_TOO_SMALL.
962 959 */
963 960 static CK_RV
964 961 get_cert_attr_from_object(cert_attr_t *src, CK_ATTRIBUTE_PTR template)
965 962 {
966 963 if (template->pValue == NULL) {
967 964 template->ulValueLen = src->length;
968 965 return (CKR_OK);
969 966 } else if (template->ulValueLen >= src->length) {
970 967 /*
971 968 * The buffer provided by the application is large
972 969 * enough to hold the value of the attribute.
973 970 */
974 971 (void) memcpy(template->pValue, src->value, src->length);
975 972 template->ulValueLen = src->length;
976 973 return (CKR_OK);
977 974 } else {
978 975 /*
979 976 * The buffer provided by the application does
↓ open down ↓ |
32 lines elided |
↑ open up ↑ |
980 977 * not have enough space to hold the value.
981 978 */
982 979 template->ulValueLen = (CK_ULONG)-1;
983 980 return (CKR_BUFFER_TOO_SMALL);
984 981 }
985 982 }
986 983
987 984 void
988 985 string_attr_cleanup(CK_ATTRIBUTE_PTR template)
989 986 {
990 -
991 - if (template->pValue) {
992 - free(template->pValue);
993 - template->pValue = NULL;
994 - template->ulValueLen = 0;
995 - }
987 + freezero(template->pValue, template->ulValueLen);
988 + template->pValue = NULL;
989 + template->ulValueLen = 0;
996 990 }
997 991
998 992 /*
999 993 * Release the storage allocated for object attribute with big integer
1000 994 * value.
1001 995 */
1002 996 void
1003 997 bigint_attr_cleanup(biginteger_t *big)
1004 998 {
1005 999
1006 1000 if (big == NULL)
1007 1001 return;
1008 1002
1009 - if (big->big_value) {
1010 - (void) memset(big->big_value, 0, big->big_value_len);
1011 - free(big->big_value);
1012 - big->big_value = NULL;
1013 - big->big_value_len = 0;
1014 - }
1003 + freezero(big->big_value, big->big_value_len);
1004 + big->big_value = NULL;
1005 + big->big_value_len = 0;
1015 1006 }
1016 1007
1017 1008
1018 1009 /*
1019 1010 * Clean up and release all the storage allocated to hold the big integer
1020 1011 * attributes associated with the type (i.e. class) of the object. Also,
1021 1012 * release the storage allocated to the type of the object.
1022 1013 */
1023 1014 void
1024 1015 soft_cleanup_object_bigint_attrs(soft_object_t *object_p)
1025 1016 {
1026 1017
1027 1018 CK_OBJECT_CLASS class = object_p->class;
1028 1019 CK_KEY_TYPE keytype = object_p->key_type;
1029 1020
1030 1021
1031 1022 switch (class) {
1032 1023 case CKO_PUBLIC_KEY:
1033 1024 if (OBJ_PUB(object_p)) {
1034 1025 switch (keytype) {
1035 1026 case CKK_RSA:
1036 1027 bigint_attr_cleanup(OBJ_PUB_RSA_MOD(
1037 1028 object_p));
1038 1029 bigint_attr_cleanup(OBJ_PUB_RSA_PUBEXPO(
1039 1030 object_p));
1040 1031 break;
1041 1032
1042 1033 case CKK_DSA:
1043 1034 bigint_attr_cleanup(OBJ_PUB_DSA_PRIME(
1044 1035 object_p));
1045 1036 bigint_attr_cleanup(OBJ_PUB_DSA_SUBPRIME(
1046 1037 object_p));
1047 1038 bigint_attr_cleanup(OBJ_PUB_DSA_BASE(
1048 1039 object_p));
1049 1040 bigint_attr_cleanup(OBJ_PUB_DSA_VALUE(
1050 1041 object_p));
1051 1042 break;
1052 1043
1053 1044 case CKK_DH:
1054 1045 bigint_attr_cleanup(OBJ_PUB_DH_PRIME(
1055 1046 object_p));
1056 1047 bigint_attr_cleanup(OBJ_PUB_DH_BASE(
1057 1048 object_p));
1058 1049 bigint_attr_cleanup(OBJ_PUB_DH_VALUE(
1059 1050 object_p));
1060 1051 break;
1061 1052
1062 1053 case CKK_X9_42_DH:
1063 1054 bigint_attr_cleanup(OBJ_PUB_DH942_PRIME(
1064 1055 object_p));
1065 1056 bigint_attr_cleanup(OBJ_PUB_DH942_BASE(
1066 1057 object_p));
1067 1058 bigint_attr_cleanup(OBJ_PUB_DH942_SUBPRIME(
1068 1059 object_p));
1069 1060 bigint_attr_cleanup(OBJ_PUB_DH942_VALUE(
1070 1061 object_p));
1071 1062 break;
1072 1063 case CKK_EC:
1073 1064 bigint_attr_cleanup(OBJ_PUB_EC_POINT(
1074 1065 object_p));
1075 1066 break;
1076 1067 }
1077 1068
1078 1069 /* Release Public Key Object struct */
1079 1070 free(OBJ_PUB(object_p));
1080 1071 OBJ_PUB(object_p) = NULL;
1081 1072 }
1082 1073 break;
1083 1074
1084 1075 case CKO_PRIVATE_KEY:
1085 1076 if (OBJ_PRI(object_p)) {
1086 1077 switch (keytype) {
1087 1078 case CKK_RSA:
1088 1079 bigint_attr_cleanup(OBJ_PRI_RSA_MOD(
1089 1080 object_p));
1090 1081 bigint_attr_cleanup(OBJ_PRI_RSA_PUBEXPO(
1091 1082 object_p));
1092 1083 bigint_attr_cleanup(OBJ_PRI_RSA_PRIEXPO(
1093 1084 object_p));
1094 1085 bigint_attr_cleanup(OBJ_PRI_RSA_PRIME1(
1095 1086 object_p));
1096 1087 bigint_attr_cleanup(OBJ_PRI_RSA_PRIME2(
1097 1088 object_p));
1098 1089 bigint_attr_cleanup(OBJ_PRI_RSA_EXPO1(
1099 1090 object_p));
1100 1091 bigint_attr_cleanup(OBJ_PRI_RSA_EXPO2(
1101 1092 object_p));
1102 1093 bigint_attr_cleanup(OBJ_PRI_RSA_COEF(
1103 1094 object_p));
1104 1095 break;
1105 1096
1106 1097 case CKK_DSA:
1107 1098 bigint_attr_cleanup(OBJ_PRI_DSA_PRIME(
1108 1099 object_p));
1109 1100 bigint_attr_cleanup(OBJ_PRI_DSA_SUBPRIME(
1110 1101 object_p));
1111 1102 bigint_attr_cleanup(OBJ_PRI_DSA_BASE(
1112 1103 object_p));
1113 1104 bigint_attr_cleanup(OBJ_PRI_DSA_VALUE(
1114 1105 object_p));
1115 1106 break;
1116 1107
1117 1108 case CKK_DH:
1118 1109 bigint_attr_cleanup(OBJ_PRI_DH_PRIME(
1119 1110 object_p));
1120 1111 bigint_attr_cleanup(OBJ_PRI_DH_BASE(
1121 1112 object_p));
1122 1113 bigint_attr_cleanup(OBJ_PRI_DH_VALUE(
1123 1114 object_p));
1124 1115 break;
1125 1116
1126 1117 case CKK_X9_42_DH:
1127 1118 bigint_attr_cleanup(OBJ_PRI_DH942_PRIME(
1128 1119 object_p));
1129 1120 bigint_attr_cleanup(OBJ_PRI_DH942_BASE(
1130 1121 object_p));
1131 1122 bigint_attr_cleanup(OBJ_PRI_DH942_SUBPRIME(
1132 1123 object_p));
1133 1124 bigint_attr_cleanup(OBJ_PRI_DH942_VALUE(
1134 1125 object_p));
1135 1126 break;
1136 1127
1137 1128 case CKK_EC:
1138 1129 bigint_attr_cleanup(OBJ_PRI_EC_VALUE(
1139 1130 object_p));
1140 1131 break;
1141 1132 }
1142 1133
1143 1134 /* Release Private Key Object struct. */
↓ open down ↓ |
119 lines elided |
↑ open up ↑ |
1144 1135 free(OBJ_PRI(object_p));
1145 1136 OBJ_PRI(object_p) = NULL;
1146 1137 }
1147 1138 break;
1148 1139
1149 1140 case CKO_SECRET_KEY:
1150 1141 if (OBJ_SEC(object_p)) {
1151 1142 /* cleanup key data area */
1152 1143 if (OBJ_SEC_VALUE(object_p) != NULL &&
1153 1144 OBJ_SEC_VALUE_LEN(object_p) > 0) {
1154 - (void) memset(OBJ_SEC_VALUE(object_p), 0,
1145 + freezero(OBJ_SEC_VALUE(object_p),
1155 1146 OBJ_SEC_VALUE_LEN(object_p));
1156 - free(OBJ_SEC_VALUE(object_p));
1157 1147 }
1158 1148 /* cleanup key schedule data area */
1159 1149 if (OBJ_KEY_SCHED(object_p) != NULL &&
1160 1150 OBJ_KEY_SCHED_LEN(object_p) > 0) {
1161 - (void) memset(OBJ_KEY_SCHED(object_p), 0,
1151 + freezero(OBJ_KEY_SCHED(object_p),
1162 1152 OBJ_KEY_SCHED_LEN(object_p));
1163 - free(OBJ_KEY_SCHED(object_p));
1164 1153 }
1165 1154
1166 1155 /* Release Secret Key Object struct. */
1167 1156 free(OBJ_SEC(object_p));
1168 1157 OBJ_SEC(object_p) = NULL;
1169 1158 }
1170 1159 break;
1171 1160
1172 1161 case CKO_DOMAIN_PARAMETERS:
1173 1162 if (OBJ_DOM(object_p)) {
1174 1163 switch (keytype) {
1175 1164 case CKK_DSA:
1176 1165 bigint_attr_cleanup(OBJ_DOM_DSA_PRIME(
1177 1166 object_p));
1178 1167 bigint_attr_cleanup(OBJ_DOM_DSA_SUBPRIME(
1179 1168 object_p));
1180 1169 bigint_attr_cleanup(OBJ_DOM_DSA_BASE(
1181 1170 object_p));
1182 1171 break;
1183 1172
1184 1173 case CKK_DH:
1185 1174 bigint_attr_cleanup(OBJ_DOM_DH_PRIME(
1186 1175 object_p));
1187 1176 bigint_attr_cleanup(OBJ_DOM_DH_BASE(
1188 1177 object_p));
1189 1178 break;
1190 1179
1191 1180 case CKK_X9_42_DH:
1192 1181 bigint_attr_cleanup(OBJ_DOM_DH942_PRIME(
1193 1182 object_p));
1194 1183 bigint_attr_cleanup(OBJ_DOM_DH942_BASE(
1195 1184 object_p));
1196 1185 bigint_attr_cleanup(OBJ_DOM_DH942_SUBPRIME(
1197 1186 object_p));
1198 1187 break;
1199 1188 }
1200 1189
1201 1190 /* Release Domain Parameters Object struct. */
1202 1191 free(OBJ_DOM(object_p));
1203 1192 OBJ_DOM(object_p) = NULL;
1204 1193 }
1205 1194 break;
1206 1195 }
1207 1196 }
1208 1197
1209 1198
1210 1199 /*
1211 1200 * Parse the common attributes. Return to caller with appropriate return
1212 1201 * value to indicate if the supplied template specifies a valid attribute
1213 1202 * with a valid value.
1214 1203 */
1215 1204 CK_RV
1216 1205 soft_parse_common_attrs(CK_ATTRIBUTE_PTR template, uchar_t *object_type)
1217 1206 {
1218 1207
1219 1208 CK_RV rv = CKR_OK;
1220 1209
1221 1210 switch (template->type) {
1222 1211 case CKA_CLASS:
1223 1212 break;
1224 1213
1225 1214 /* default boolean attributes */
1226 1215 case CKA_TOKEN:
1227 1216 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
1228 1217 if (!soft_keystore_status(KEYSTORE_INITIALIZED))
1229 1218 return (CKR_DEVICE_REMOVED);
1230 1219 *object_type |= TOKEN_OBJECT;
1231 1220 }
1232 1221 break;
1233 1222
1234 1223 case CKA_PRIVATE:
1235 1224 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
1236 1225 (void) pthread_mutex_lock(&soft_giant_mutex);
1237 1226 if (!soft_slot.authenticated) {
1238 1227 /*
1239 1228 * Check if this is the special case when
1240 1229 * the PIN is never initialized in the keystore.
1241 1230 * If true, we will let it pass here and let
1242 1231 * it fail with CKR_PIN_EXPIRED later on.
1243 1232 */
1244 1233 if (!soft_slot.userpin_change_needed) {
1245 1234 (void) pthread_mutex_unlock(
1246 1235 &soft_giant_mutex);
1247 1236 return (CKR_USER_NOT_LOGGED_IN);
1248 1237 }
1249 1238 }
1250 1239 (void) pthread_mutex_unlock(&soft_giant_mutex);
1251 1240 *object_type |= PRIVATE_OBJECT;
1252 1241 }
1253 1242 break;
1254 1243
1255 1244 case CKA_LABEL:
1256 1245 break;
1257 1246
1258 1247 default:
1259 1248 rv = CKR_TEMPLATE_INCONSISTENT;
1260 1249 }
1261 1250
1262 1251 return (rv);
1263 1252 }
1264 1253
1265 1254
1266 1255 /*
1267 1256 * Build a Public Key Object.
1268 1257 *
1269 1258 * - Parse the object's template, and when an error is detected such as
1270 1259 * invalid attribute type, invalid attribute value, etc., return
1271 1260 * with appropriate return value.
1272 1261 * - Set up attribute mask field in the object for the supplied common
1273 1262 * attributes that have boolean type.
1274 1263 * - Build the attribute_info struct to hold the value of each supplied
1275 1264 * attribute that has byte array type. Link attribute_info structs
1276 1265 * together to form the extra attribute list of the object.
1277 1266 * - Allocate storage for the Public Key object.
1278 1267 * - Build the Public Key object according to the key type. Allocate
1279 1268 * storage to hold the big integer value for the supplied attributes
1280 1269 * that are required for a certain key type.
1281 1270 *
1282 1271 */
1283 1272 CK_RV
1284 1273 soft_build_public_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
1285 1274 soft_object_t *new_object, CK_ULONG mode, CK_KEY_TYPE key_type)
1286 1275 {
1287 1276
1288 1277 ulong_t i;
1289 1278 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1290 1279 uint64_t attr_mask = PUBLIC_KEY_DEFAULT;
1291 1280 CK_RV rv = CKR_OK;
1292 1281 int isLabel = 0;
1293 1282 /* Must set flags */
1294 1283 int isModulus = 0;
1295 1284 int isPubExpo = 0;
1296 1285 int isPrime = 0;
1297 1286 int isSubprime = 0;
1298 1287 int isBase = 0;
1299 1288 int isValue = 0;
1300 1289 int isECParam = 0;
1301 1290 int isECPoint = 0;
1302 1291 /* Must not set flags */
1303 1292 int isModulusBits = 0;
1304 1293 CK_ULONG modulus_bits = 0;
1305 1294
1306 1295 biginteger_t modulus;
1307 1296 biginteger_t pubexpo;
1308 1297 biginteger_t prime;
1309 1298 biginteger_t subprime;
1310 1299 biginteger_t base;
1311 1300 biginteger_t value;
1312 1301 biginteger_t point;
1313 1302 CK_ATTRIBUTE string_tmp;
1314 1303 CK_ATTRIBUTE param_tmp;
1315 1304
1316 1305 public_key_obj_t *pbk;
1317 1306 uchar_t object_type = 0;
1318 1307
1319 1308 CK_ATTRIBUTE defpubexpo = { CKA_PUBLIC_EXPONENT,
1320 1309 (CK_BYTE_PTR)DEFAULT_PUB_EXPO, DEFAULT_PUB_EXPO_Len };
1321 1310
1322 1311 BIGNUM n;
1323 1312
1324 1313 /* prevent bigint_attr_cleanup from freeing invalid attr value */
1325 1314 (void) memset(&modulus, 0x0, sizeof (biginteger_t));
1326 1315 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1327 1316 (void) memset(&prime, 0x0, sizeof (biginteger_t));
1328 1317 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
1329 1318 (void) memset(&base, 0x0, sizeof (biginteger_t));
1330 1319 (void) memset(&value, 0x0, sizeof (biginteger_t));
1331 1320 (void) memset(&point, 0x0, sizeof (biginteger_t));
1332 1321 string_tmp.pValue = NULL;
1333 1322 param_tmp.pValue = NULL;
1334 1323
1335 1324 for (i = 0; i < ulAttrNum; i++) {
1336 1325
1337 1326 /* Public Key Object Attributes */
1338 1327 switch (template[i].type) {
1339 1328
1340 1329 /* common key attributes */
1341 1330 case CKA_KEY_TYPE:
1342 1331 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1343 1332 break;
1344 1333
1345 1334 case CKA_ID:
1346 1335 case CKA_START_DATE:
1347 1336 case CKA_END_DATE:
1348 1337
1349 1338 /* common public key attribute */
1350 1339 case CKA_SUBJECT:
1351 1340 /*
1352 1341 * Allocate storage to hold the attribute
1353 1342 * value with byte array type, and add it to
1354 1343 * the extra attribute list of the object.
1355 1344 */
1356 1345 rv = soft_add_extra_attr(&template[i],
1357 1346 new_object);
1358 1347 if (rv != CKR_OK) {
1359 1348 goto fail_cleanup;
1360 1349 }
1361 1350 break;
1362 1351
1363 1352 /*
1364 1353 * The following key related attribute types must
1365 1354 * not be specified by C_CreateObject, C_GenerateKey(Pair).
1366 1355 */
1367 1356 case CKA_LOCAL:
1368 1357 case CKA_KEY_GEN_MECHANISM:
1369 1358 rv = CKR_TEMPLATE_INCONSISTENT;
1370 1359 goto fail_cleanup;
1371 1360
1372 1361 /* Key related boolean attributes */
1373 1362 case CKA_DERIVE:
1374 1363 if (*(CK_BBOOL *)template[i].pValue)
1375 1364 attr_mask |= DERIVE_BOOL_ON;
1376 1365 break;
1377 1366
1378 1367 case CKA_ENCRYPT:
1379 1368 if (*(CK_BBOOL *)template[i].pValue)
1380 1369 attr_mask |= ENCRYPT_BOOL_ON;
1381 1370 else
1382 1371 attr_mask &= ~ENCRYPT_BOOL_ON;
1383 1372 break;
1384 1373
1385 1374 case CKA_VERIFY:
1386 1375 if (*(CK_BBOOL *)template[i].pValue)
1387 1376 attr_mask |= VERIFY_BOOL_ON;
1388 1377 else
1389 1378 attr_mask &= ~VERIFY_BOOL_ON;
1390 1379 break;
1391 1380
1392 1381 case CKA_VERIFY_RECOVER:
1393 1382 if (*(CK_BBOOL *)template[i].pValue)
1394 1383 attr_mask |= VERIFY_RECOVER_BOOL_ON;
1395 1384 else
1396 1385 attr_mask &= ~VERIFY_RECOVER_BOOL_ON;
1397 1386 break;
1398 1387
1399 1388 case CKA_WRAP:
1400 1389 if (*(CK_BBOOL *)template[i].pValue)
1401 1390 attr_mask |= WRAP_BOOL_ON;
1402 1391 else
1403 1392 attr_mask &= ~WRAP_BOOL_ON;
1404 1393 break;
1405 1394
1406 1395 case CKA_TRUSTED:
1407 1396 if (*(CK_BBOOL *)template[i].pValue)
1408 1397 attr_mask |= TRUSTED_BOOL_ON;
1409 1398 break;
1410 1399
1411 1400 case CKA_MODIFIABLE:
1412 1401 if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
1413 1402 attr_mask |= NOT_MODIFIABLE_BOOL_ON;
1414 1403 break;
1415 1404
1416 1405 /*
1417 1406 * The following key related attribute types must
1418 1407 * be specified according to the key type by
1419 1408 * C_CreateObject.
1420 1409 */
1421 1410 case CKA_MODULUS:
1422 1411
1423 1412 isModulus = 1;
1424 1413 /*
1425 1414 * Copyin big integer attribute from template
1426 1415 * to a local variable.
1427 1416 */
1428 1417 rv = get_bigint_attr_from_template(&modulus,
1429 1418 &template[i]);
1430 1419 if (rv != CKR_OK)
1431 1420 goto fail_cleanup;
1432 1421
1433 1422 /*
1434 1423 * Modulus length needs to be between min key length and
1435 1424 * max key length.
1436 1425 */
1437 1426 if ((modulus.big_value_len <
1438 1427 MIN_RSA_KEYLENGTH_IN_BYTES) ||
1439 1428 (modulus.big_value_len >
1440 1429 MAX_RSA_KEYLENGTH_IN_BYTES)) {
1441 1430 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1442 1431 goto fail_cleanup;
1443 1432 }
1444 1433 break;
1445 1434
1446 1435 case CKA_PUBLIC_EXPONENT:
1447 1436 isPubExpo = 1;
1448 1437 rv = get_bigint_attr_from_template(&pubexpo,
1449 1438 &template[i]);
1450 1439 if (rv != CKR_OK)
1451 1440 goto fail_cleanup;
1452 1441 break;
1453 1442
1454 1443 case CKA_PRIME:
1455 1444 isPrime = 1;
1456 1445 rv = get_bigint_attr_from_template(&prime,
1457 1446 &template[i]);
1458 1447 if (rv != CKR_OK)
1459 1448 goto fail_cleanup;
1460 1449 break;
1461 1450
1462 1451 case CKA_SUBPRIME:
1463 1452 isSubprime = 1;
1464 1453 rv = get_bigint_attr_from_template(&subprime,
1465 1454 &template[i]);
1466 1455 if (rv != CKR_OK)
1467 1456 goto fail_cleanup;
1468 1457 break;
1469 1458
1470 1459 case CKA_BASE:
1471 1460 isBase = 1;
1472 1461 rv = get_bigint_attr_from_template(&base,
1473 1462 &template[i]);
1474 1463 if (rv != CKR_OK)
1475 1464 goto fail_cleanup;
1476 1465 break;
1477 1466
1478 1467 case CKA_VALUE:
1479 1468 isValue = 1;
1480 1469 if (mode == SOFT_CREATE_OBJ) {
1481 1470 if ((template[i].ulValueLen == 0) ||
1482 1471 (template[i].pValue == NULL)) {
1483 1472 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1484 1473 goto fail_cleanup;
1485 1474 }
1486 1475 }
1487 1476
1488 1477 rv = get_bigint_attr_from_template(&value,
1489 1478 &template[i]);
1490 1479 if (rv != CKR_OK)
1491 1480 goto fail_cleanup;
1492 1481 break;
1493 1482
1494 1483 case CKA_MODULUS_BITS:
1495 1484 isModulusBits = 1;
1496 1485 rv = get_ulong_attr_from_template(&modulus_bits,
1497 1486 &template[i]);
1498 1487 if (rv != CKR_OK)
1499 1488 goto fail_cleanup;
1500 1489 break;
1501 1490
1502 1491 case CKA_LABEL:
1503 1492 isLabel = 1;
1504 1493 rv = get_string_from_template(&string_tmp,
1505 1494 &template[i]);
1506 1495 if (rv != CKR_OK)
1507 1496 goto fail_cleanup;
1508 1497 break;
1509 1498
1510 1499 case CKA_EC_PARAMS:
1511 1500 isECParam = 1;
1512 1501 rv = get_string_from_template(¶m_tmp, &template[i]);
1513 1502 if (rv != CKR_OK)
1514 1503 goto fail_cleanup;
1515 1504 break;
1516 1505
1517 1506 case CKA_EC_POINT:
1518 1507 isECPoint = 1;
1519 1508 rv = get_bigint_attr_from_template(&point,
1520 1509 &template[i]);
1521 1510 if (rv != CKR_OK)
1522 1511 goto fail_cleanup;
1523 1512 break;
1524 1513
1525 1514 default:
1526 1515 rv = soft_parse_common_attrs(&template[i],
1527 1516 &object_type);
1528 1517 if (rv != CKR_OK)
1529 1518 goto fail_cleanup;
1530 1519 break;
1531 1520 }
1532 1521 } /* For */
1533 1522
1534 1523 /* Allocate storage for Public Key Object. */
1535 1524 pbk = calloc(1, sizeof (public_key_obj_t));
1536 1525 if (pbk == NULL) {
1537 1526 rv = CKR_HOST_MEMORY;
1538 1527 goto fail_cleanup;
1539 1528 }
1540 1529
1541 1530 new_object->object_class_u.public_key = pbk;
1542 1531 new_object->class = CKO_PUBLIC_KEY;
1543 1532
1544 1533 if ((mode == SOFT_CREATE_OBJ) && (keytype == (CK_KEY_TYPE)~0UL)) {
1545 1534 rv = CKR_TEMPLATE_INCOMPLETE;
1546 1535 goto fail_cleanup;
1547 1536 }
1548 1537
1549 1538 if ((mode == SOFT_GEN_KEY) && (keytype == (CK_KEY_TYPE)~0UL)) {
1550 1539 keytype = key_type;
1551 1540 }
1552 1541
1553 1542 if ((mode == SOFT_GEN_KEY) && (keytype != key_type)) {
1554 1543 /*
1555 1544 * The key type specified in the template does not
1556 1545 * match the implied key type based on the mechanism.
1557 1546 */
1558 1547 rv = CKR_TEMPLATE_INCONSISTENT;
1559 1548 goto fail_cleanup;
1560 1549 }
1561 1550
1562 1551 new_object->key_type = keytype;
1563 1552
1564 1553 /* Supported key types of the Public Key Object */
1565 1554 switch (keytype) {
1566 1555
1567 1556 case CKK_RSA:
1568 1557 if (mode == SOFT_CREATE_OBJ) {
1569 1558 if (isModulusBits || isPrime || isSubprime ||
1570 1559 isBase || isValue) {
1571 1560 rv = CKR_TEMPLATE_INCONSISTENT;
1572 1561 goto fail_cleanup;
1573 1562 }
1574 1563
1575 1564 if (isModulus && isPubExpo) {
1576 1565 /*
1577 1566 * Derive modulus_bits attribute from modulus.
1578 1567 * Save modulus_bits integer value to the
1579 1568 * designated place in the public key object.
1580 1569 */
1581 1570 n.malloced = 0;
1582 1571 #ifdef __sparcv9
1583 1572 if (big_init(&n, (int)CHARLEN2BIGNUMLEN(
1584 1573 modulus.big_value_len)) != BIG_OK) {
1585 1574 #else /* !__sparcv9 */
1586 1575 if (big_init(&n, CHARLEN2BIGNUMLEN(
1587 1576 modulus.big_value_len)) != BIG_OK) {
1588 1577 #endif /* __sparcv9 */
1589 1578 rv = CKR_HOST_MEMORY;
1590 1579 big_finish(&n);
1591 1580 goto fail_cleanup;
1592 1581 }
1593 1582 bytestring2bignum(&n, modulus.big_value,
1594 1583 modulus.big_value_len);
1595 1584
1596 1585 modulus_bits = big_bitlength(&n);
1597 1586 KEY_PUB_RSA_MOD_BITS(pbk) = modulus_bits;
1598 1587 big_finish(&n);
1599 1588
1600 1589 /*
1601 1590 * After modulus_bits has been computed,
1602 1591 * it is safe to move modulus and pubexpo
1603 1592 * big integer attribute value to the
1604 1593 * designated place in the public key object.
1605 1594 */
1606 1595 copy_bigint_attr(&modulus,
1607 1596 KEY_PUB_RSA_MOD(pbk));
1608 1597
1609 1598 copy_bigint_attr(&pubexpo,
1610 1599 KEY_PUB_RSA_PUBEXPO(pbk));
1611 1600 } else {
1612 1601 rv = CKR_TEMPLATE_INCOMPLETE;
1613 1602 goto fail_cleanup;
1614 1603 }
1615 1604 } else {
1616 1605 /* mode is SOFT_GEN_KEY */
1617 1606
1618 1607 if (isModulus || isPrime || isSubprime ||
1619 1608 isBase || isValue) {
1620 1609 rv = CKR_TEMPLATE_INCONSISTENT;
1621 1610 goto fail_cleanup;
1622 1611 }
1623 1612
1624 1613
1625 1614 if (isModulusBits) {
1626 1615 /*
1627 1616 * Copy big integer attribute value to the
1628 1617 * designated place in the public key object.
1629 1618 */
1630 1619 KEY_PUB_RSA_MOD_BITS(pbk) = modulus_bits;
1631 1620 } else {
1632 1621 rv = CKR_TEMPLATE_INCOMPLETE;
1633 1622 goto fail_cleanup;
1634 1623 }
1635 1624
1636 1625 /*
1637 1626 * Use PKCS#11 default 0x010001 for public exponent
1638 1627 * if not not specified in attribute template.
1639 1628 */
1640 1629 if (!isPubExpo) {
1641 1630 isPubExpo = 1;
1642 1631 rv = get_bigint_attr_from_template(&pubexpo,
1643 1632 &defpubexpo);
1644 1633 if (rv != CKR_OK)
1645 1634 goto fail_cleanup;
1646 1635 }
1647 1636 /*
1648 1637 * Copy big integer attribute value to the
1649 1638 * designated place in the public key object.
1650 1639 */
1651 1640 copy_bigint_attr(&pubexpo, KEY_PUB_RSA_PUBEXPO(pbk));
1652 1641 }
1653 1642
1654 1643 break;
1655 1644
1656 1645 case CKK_DSA:
1657 1646 if (mode == SOFT_CREATE_OBJ) {
1658 1647 if (isModulusBits || isModulus || isPubExpo) {
1659 1648 rv = CKR_TEMPLATE_INCONSISTENT;
1660 1649 goto fail_cleanup;
1661 1650 }
1662 1651
1663 1652 if (isPrime && isSubprime && isBase && isValue) {
1664 1653 copy_bigint_attr(&value,
1665 1654 KEY_PUB_DSA_VALUE(pbk));
1666 1655 } else {
1667 1656 rv = CKR_TEMPLATE_INCOMPLETE;
1668 1657 goto fail_cleanup;
1669 1658 }
1670 1659 } else {
1671 1660 if (isModulusBits || isModulus || isPubExpo ||
1672 1661 isValue) {
1673 1662 rv = CKR_TEMPLATE_INCONSISTENT;
1674 1663 goto fail_cleanup;
1675 1664 }
1676 1665
1677 1666 if (!(isPrime && isSubprime && isBase)) {
1678 1667 rv = CKR_TEMPLATE_INCOMPLETE;
1679 1668 goto fail_cleanup;
1680 1669 }
1681 1670 }
1682 1671
1683 1672 copy_bigint_attr(&prime, KEY_PUB_DSA_PRIME(pbk));
1684 1673
1685 1674 copy_bigint_attr(&subprime, KEY_PUB_DSA_SUBPRIME(pbk));
1686 1675
1687 1676 copy_bigint_attr(&base, KEY_PUB_DSA_BASE(pbk));
1688 1677
1689 1678 break;
1690 1679
1691 1680 case CKK_DH:
1692 1681 if (mode == SOFT_CREATE_OBJ) {
1693 1682 if (isModulusBits || isModulus || isPubExpo ||
1694 1683 isSubprime) {
1695 1684 rv = CKR_TEMPLATE_INCONSISTENT;
1696 1685 goto fail_cleanup;
1697 1686 }
1698 1687
1699 1688 if (isPrime && isBase && isValue) {
1700 1689 copy_bigint_attr(&value,
1701 1690 KEY_PUB_DH_VALUE(pbk));
1702 1691 } else {
1703 1692 rv = CKR_TEMPLATE_INCOMPLETE;
1704 1693 goto fail_cleanup;
1705 1694 }
1706 1695 } else {
1707 1696 if (isModulusBits || isModulus || isPubExpo ||
1708 1697 isSubprime || isValue) {
1709 1698 rv = CKR_TEMPLATE_INCONSISTENT;
1710 1699 goto fail_cleanup;
1711 1700 }
1712 1701
1713 1702 if (!(isPrime && isBase)) {
1714 1703 rv = CKR_TEMPLATE_INCOMPLETE;
1715 1704 goto fail_cleanup;
1716 1705 }
1717 1706 }
1718 1707
1719 1708 copy_bigint_attr(&prime, KEY_PUB_DH_PRIME(pbk));
1720 1709
1721 1710 copy_bigint_attr(&base, KEY_PUB_DH_BASE(pbk));
1722 1711
1723 1712 break;
1724 1713
1725 1714 case CKK_X9_42_DH:
1726 1715 if (mode == SOFT_CREATE_OBJ) {
1727 1716 if (isModulusBits || isModulus || isPubExpo) {
1728 1717 rv = CKR_TEMPLATE_INCONSISTENT;
1729 1718 goto fail_cleanup;
1730 1719 }
1731 1720
1732 1721 if (isPrime && isSubprime && isBase && isValue) {
1733 1722 copy_bigint_attr(&value,
1734 1723 KEY_PUB_DH942_VALUE(pbk));
1735 1724 } else {
1736 1725 rv = CKR_TEMPLATE_INCOMPLETE;
1737 1726 goto fail_cleanup;
1738 1727 }
1739 1728 } else {
1740 1729 if (isModulusBits || isModulus || isPubExpo ||
1741 1730 isValue) {
1742 1731 rv = CKR_TEMPLATE_INCONSISTENT;
1743 1732 goto fail_cleanup;
1744 1733 }
1745 1734
1746 1735 if (!(isPrime && isSubprime && isBase)) {
1747 1736 rv = CKR_TEMPLATE_INCOMPLETE;
1748 1737 goto fail_cleanup;
1749 1738 }
1750 1739 }
1751 1740
1752 1741 copy_bigint_attr(&prime, KEY_PUB_DH942_PRIME(pbk));
1753 1742
1754 1743 copy_bigint_attr(&base, KEY_PUB_DH942_BASE(pbk));
1755 1744
1756 1745 copy_bigint_attr(&subprime, KEY_PUB_DH942_SUBPRIME(pbk));
1757 1746
1758 1747 break;
1759 1748
1760 1749 case CKK_EC:
1761 1750 if (mode == SOFT_CREATE_OBJ) {
1762 1751 if (isModulusBits || isModulus || isPubExpo ||
1763 1752 isPrime || isSubprime || isBase || isValue) {
1764 1753 rv = CKR_TEMPLATE_INCONSISTENT;
1765 1754 goto fail_cleanup;
1766 1755
1767 1756 } else if (!isECParam || !isECPoint) {
1768 1757 rv = CKR_TEMPLATE_INCOMPLETE;
1769 1758 goto fail_cleanup;
1770 1759 }
1771 1760 } else {
1772 1761 if (isModulusBits || isModulus || isPubExpo ||
1773 1762 isPrime || isSubprime || isBase || isValue) {
1774 1763 rv = CKR_TEMPLATE_INCONSISTENT;
1775 1764 goto fail_cleanup;
1776 1765
1777 1766 } else if (!isECParam) {
1778 1767 rv = CKR_TEMPLATE_INCOMPLETE;
1779 1768 goto fail_cleanup;
1780 1769 }
1781 1770 }
1782 1771
1783 1772 if (isECPoint) {
1784 1773 copy_bigint_attr(&point, KEY_PUB_EC_POINT(pbk));
1785 1774 }
1786 1775 rv = soft_add_extra_attr(¶m_tmp, new_object);
1787 1776 if (rv != CKR_OK)
1788 1777 goto fail_cleanup;
1789 1778 string_attr_cleanup(¶m_tmp);
1790 1779 break;
1791 1780
1792 1781 default:
1793 1782 rv = CKR_TEMPLATE_INCONSISTENT;
1794 1783 goto fail_cleanup;
1795 1784 }
1796 1785
1797 1786 /* Set up object. */
1798 1787 new_object->object_type = object_type;
1799 1788 new_object->bool_attr_mask = attr_mask;
1800 1789 if (isLabel) {
1801 1790 rv = soft_add_extra_attr(&string_tmp, new_object);
1802 1791 if (rv != CKR_OK)
1803 1792 goto fail_cleanup;
1804 1793 string_attr_cleanup(&string_tmp);
1805 1794 }
1806 1795
1807 1796 return (rv);
1808 1797
1809 1798 fail_cleanup:
1810 1799 /*
1811 1800 * cleanup the storage allocated to the local variables.
1812 1801 */
1813 1802 bigint_attr_cleanup(&modulus);
1814 1803 bigint_attr_cleanup(&pubexpo);
1815 1804 bigint_attr_cleanup(&prime);
1816 1805 bigint_attr_cleanup(&subprime);
1817 1806 bigint_attr_cleanup(&base);
1818 1807 bigint_attr_cleanup(&value);
1819 1808 bigint_attr_cleanup(&point);
1820 1809 string_attr_cleanup(&string_tmp);
1821 1810 string_attr_cleanup(¶m_tmp);
1822 1811
1823 1812 /*
1824 1813 * cleanup the storage allocated inside the object itself.
1825 1814 */
1826 1815 soft_cleanup_object(new_object);
1827 1816
1828 1817 return (rv);
1829 1818 }
1830 1819
1831 1820
1832 1821 /*
1833 1822 * Build a Private Key Object.
1834 1823 *
1835 1824 * - Parse the object's template, and when an error is detected such as
1836 1825 * invalid attribute type, invalid attribute value, etc., return
1837 1826 * with appropriate return value.
1838 1827 * - Set up attribute mask field in the object for the supplied common
1839 1828 * attributes that have boolean type.
1840 1829 * - Build the attribute_info struct to hold the value of each supplied
1841 1830 * attribute that has byte array type. Link attribute_info structs
1842 1831 * together to form the extra attribute list of the object.
1843 1832 * - Allocate storage for the Private Key object.
1844 1833 * - Build the Private Key object according to the key type. Allocate
1845 1834 * storage to hold the big integer value for the supplied attributes
1846 1835 * that are required for a certain key type.
1847 1836 *
1848 1837 */
1849 1838 CK_RV
1850 1839 soft_build_private_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
1851 1840 soft_object_t *new_object, CK_ULONG mode, CK_KEY_TYPE key_type)
1852 1841 {
1853 1842 ulong_t i;
1854 1843 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
1855 1844 uint64_t attr_mask = PRIVATE_KEY_DEFAULT;
1856 1845 CK_RV rv = CKR_OK;
1857 1846 int isLabel = 0;
1858 1847 int isECParam = 0;
1859 1848 /* Must set flags unless mode == SOFT_UNWRAP_KEY */
1860 1849 int isModulus = 0;
1861 1850 int isPriExpo = 0;
1862 1851 int isPrime = 0;
1863 1852 int isSubprime = 0;
1864 1853 int isBase = 0;
1865 1854 /* Must set flags if mode == SOFT_GEN_KEY */
1866 1855 int isValue = 0;
1867 1856 /* Must not set flags */
1868 1857 int isValueBits = 0;
1869 1858 CK_ULONG value_bits = 0;
1870 1859
1871 1860 /* Private Key RSA optional */
1872 1861 int isPubExpo = 0;
1873 1862 int isPrime1 = 0;
1874 1863 int isPrime2 = 0;
1875 1864 int isExpo1 = 0;
1876 1865 int isExpo2 = 0;
1877 1866 int isCoef = 0;
1878 1867
1879 1868 biginteger_t modulus;
1880 1869 biginteger_t priexpo;
1881 1870 biginteger_t prime;
1882 1871 biginteger_t subprime;
1883 1872 biginteger_t base;
1884 1873 biginteger_t value;
1885 1874
1886 1875 biginteger_t pubexpo;
1887 1876 biginteger_t prime1;
1888 1877 biginteger_t prime2;
1889 1878 biginteger_t expo1;
1890 1879 biginteger_t expo2;
1891 1880 biginteger_t coef;
1892 1881 CK_ATTRIBUTE string_tmp;
1893 1882 CK_ATTRIBUTE param_tmp;
1894 1883 BIGNUM x, q;
1895 1884
1896 1885 private_key_obj_t *pvk;
1897 1886 uchar_t object_type = 0;
1898 1887
1899 1888 /* prevent bigint_attr_cleanup from freeing invalid attr value */
1900 1889 (void) memset(&modulus, 0x0, sizeof (biginteger_t));
1901 1890 (void) memset(&priexpo, 0x0, sizeof (biginteger_t));
1902 1891 (void) memset(&prime, 0x0, sizeof (biginteger_t));
1903 1892 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
1904 1893 (void) memset(&base, 0x0, sizeof (biginteger_t));
1905 1894 (void) memset(&value, 0x0, sizeof (biginteger_t));
1906 1895 (void) memset(&pubexpo, 0x0, sizeof (biginteger_t));
1907 1896 (void) memset(&prime1, 0x0, sizeof (biginteger_t));
1908 1897 (void) memset(&prime2, 0x0, sizeof (biginteger_t));
1909 1898 (void) memset(&expo1, 0x0, sizeof (biginteger_t));
1910 1899 (void) memset(&expo2, 0x0, sizeof (biginteger_t));
1911 1900 (void) memset(&coef, 0x0, sizeof (biginteger_t));
1912 1901 string_tmp.pValue = NULL;
1913 1902 param_tmp.pValue = NULL;
1914 1903 x.malloced = 0;
1915 1904 q.malloced = 0;
1916 1905
1917 1906 for (i = 0; i < ulAttrNum; i++) {
1918 1907
1919 1908 /* Private Key Object Attributes */
1920 1909 switch (template[i].type) {
1921 1910 /* common key attributes */
1922 1911 case CKA_KEY_TYPE:
1923 1912 keytype = *((CK_KEY_TYPE*)template[i].pValue);
1924 1913 break;
1925 1914
1926 1915 case CKA_ID:
1927 1916 case CKA_START_DATE:
1928 1917 case CKA_END_DATE:
1929 1918
1930 1919 /* common private key attribute */
1931 1920 case CKA_SUBJECT:
1932 1921 /*
1933 1922 * Allocate storage to hold the attribute
1934 1923 * value with byte array type, and add it to
1935 1924 * the extra attribute list of the object.
1936 1925 */
1937 1926 rv = soft_add_extra_attr(&template[i],
1938 1927 new_object);
1939 1928 if (rv != CKR_OK) {
1940 1929 goto fail_cleanup;
1941 1930 }
1942 1931 break;
1943 1932
1944 1933 /*
1945 1934 * The following key related attribute types must
1946 1935 * not be specified by C_CreateObject or C_GenerateKey(Pair).
1947 1936 */
1948 1937 case CKA_LOCAL:
1949 1938 case CKA_KEY_GEN_MECHANISM:
1950 1939 case CKA_AUTH_PIN_FLAGS:
1951 1940 case CKA_ALWAYS_SENSITIVE:
1952 1941 case CKA_NEVER_EXTRACTABLE:
1953 1942 rv = CKR_TEMPLATE_INCONSISTENT;
1954 1943 goto fail_cleanup;
1955 1944
1956 1945 /* Key related boolean attributes */
1957 1946 case CKA_DERIVE:
1958 1947 if (*(CK_BBOOL *)template[i].pValue)
1959 1948 attr_mask |= DERIVE_BOOL_ON;
1960 1949 break;
1961 1950
1962 1951 case CKA_SENSITIVE:
1963 1952 if (*(CK_BBOOL *)template[i].pValue)
1964 1953 attr_mask |= SENSITIVE_BOOL_ON;
1965 1954 break;
1966 1955
1967 1956 case CKA_SECONDARY_AUTH:
1968 1957 if (*(CK_BBOOL *)template[i].pValue) {
1969 1958 rv = CKR_ATTRIBUTE_VALUE_INVALID;
1970 1959 goto fail_cleanup;
1971 1960 }
1972 1961 break;
1973 1962
1974 1963 case CKA_DECRYPT:
1975 1964 if (*(CK_BBOOL *)template[i].pValue)
1976 1965 attr_mask |= DECRYPT_BOOL_ON;
1977 1966 else
1978 1967 attr_mask &= ~DECRYPT_BOOL_ON;
1979 1968 break;
1980 1969
1981 1970 case CKA_SIGN:
1982 1971 if (*(CK_BBOOL *)template[i].pValue)
1983 1972 attr_mask |= SIGN_BOOL_ON;
1984 1973 else
1985 1974 attr_mask &= ~SIGN_BOOL_ON;
1986 1975 break;
1987 1976
1988 1977 case CKA_SIGN_RECOVER:
1989 1978 if (*(CK_BBOOL *)template[i].pValue)
1990 1979 attr_mask |= SIGN_RECOVER_BOOL_ON;
1991 1980 else
1992 1981 attr_mask &= ~SIGN_RECOVER_BOOL_ON;
1993 1982 break;
1994 1983
1995 1984 case CKA_UNWRAP:
1996 1985 if (*(CK_BBOOL *)template[i].pValue)
1997 1986 attr_mask |= UNWRAP_BOOL_ON;
1998 1987 else
1999 1988 attr_mask &= ~UNWRAP_BOOL_ON;
2000 1989 break;
2001 1990
2002 1991 case CKA_EXTRACTABLE:
2003 1992 if (*(CK_BBOOL *)template[i].pValue)
2004 1993 attr_mask |= EXTRACTABLE_BOOL_ON;
2005 1994 else
2006 1995 attr_mask &= ~EXTRACTABLE_BOOL_ON;
2007 1996 break;
2008 1997
2009 1998 case CKA_MODIFIABLE:
2010 1999 if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
2011 2000 attr_mask |= NOT_MODIFIABLE_BOOL_ON;
2012 2001 break;
2013 2002
2014 2003 /*
2015 2004 * The following key related attribute types must
2016 2005 * be specified according to the key type by
2017 2006 * C_CreateObject.
2018 2007 */
2019 2008 case CKA_MODULUS:
2020 2009
2021 2010 isModulus = 1;
2022 2011 /*
2023 2012 * Copyin big integer attribute from template
2024 2013 * to a local variable.
2025 2014 */
2026 2015 rv = get_bigint_attr_from_template(&modulus,
2027 2016 &template[i]);
2028 2017 if (rv != CKR_OK)
2029 2018 goto fail_cleanup;
2030 2019
2031 2020 /*
2032 2021 * Modulus length needs to be between min key length and
2033 2022 * max key length.
2034 2023 */
2035 2024 if ((modulus.big_value_len <
2036 2025 MIN_RSA_KEYLENGTH_IN_BYTES) ||
2037 2026 (modulus.big_value_len >
2038 2027 MAX_RSA_KEYLENGTH_IN_BYTES)) {
2039 2028 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2040 2029 goto fail_cleanup;
2041 2030 }
2042 2031 break;
2043 2032
2044 2033 case CKA_PUBLIC_EXPONENT:
2045 2034
2046 2035 isPubExpo = 1;
2047 2036 rv = get_bigint_attr_from_template(&pubexpo,
2048 2037 &template[i]);
2049 2038 if (rv != CKR_OK)
2050 2039 goto fail_cleanup;
2051 2040 break;
2052 2041
2053 2042 case CKA_PRIVATE_EXPONENT:
2054 2043
2055 2044 isPriExpo = 1;
2056 2045 rv = get_bigint_attr_from_template(&priexpo,
2057 2046 &template[i]);
2058 2047 if (rv != CKR_OK)
2059 2048 goto fail_cleanup;
2060 2049 break;
2061 2050
2062 2051 case CKA_PRIME_1:
2063 2052 isPrime1 = 1;
2064 2053 rv = get_bigint_attr_from_template(&prime1,
2065 2054 &template[i]);
2066 2055 if (rv != CKR_OK)
2067 2056 goto fail_cleanup;
2068 2057 break;
2069 2058
2070 2059 case CKA_PRIME_2:
2071 2060 isPrime2 = 1;
2072 2061 rv = get_bigint_attr_from_template(&prime2,
2073 2062 &template[i]);
2074 2063 if (rv != CKR_OK)
2075 2064 goto fail_cleanup;
2076 2065 break;
2077 2066
2078 2067 case CKA_EXPONENT_1:
2079 2068 isExpo1 = 1;
2080 2069 rv = get_bigint_attr_from_template(&expo1,
2081 2070 &template[i]);
2082 2071 if (rv != CKR_OK)
2083 2072 goto fail_cleanup;
2084 2073 break;
2085 2074
2086 2075 case CKA_EXPONENT_2:
2087 2076 isExpo2 = 1;
2088 2077 rv = get_bigint_attr_from_template(&expo2,
2089 2078 &template[i]);
2090 2079 if (rv != CKR_OK)
2091 2080 goto fail_cleanup;
2092 2081 break;
2093 2082
2094 2083 case CKA_COEFFICIENT:
2095 2084 isCoef = 1;
2096 2085 rv = get_bigint_attr_from_template(&coef,
2097 2086 &template[i]);
2098 2087 if (rv != CKR_OK)
2099 2088 goto fail_cleanup;
2100 2089 break;
2101 2090
2102 2091 case CKA_PRIME:
2103 2092 isPrime = 1;
2104 2093 rv = get_bigint_attr_from_template(&prime,
2105 2094 &template[i]);
2106 2095 if (rv != CKR_OK)
2107 2096 goto fail_cleanup;
2108 2097 break;
2109 2098
2110 2099 case CKA_SUBPRIME:
2111 2100 isSubprime = 1;
2112 2101 rv = get_bigint_attr_from_template(&subprime,
2113 2102 &template[i]);
2114 2103 if (rv != CKR_OK)
2115 2104 goto fail_cleanup;
2116 2105 break;
2117 2106
2118 2107 case CKA_BASE:
2119 2108 isBase = 1;
2120 2109 rv = get_bigint_attr_from_template(&base,
2121 2110 &template[i]);
2122 2111 if (rv != CKR_OK)
2123 2112 goto fail_cleanup;
2124 2113 break;
2125 2114
2126 2115 case CKA_VALUE:
2127 2116 isValue = 1;
2128 2117 if (mode == SOFT_CREATE_OBJ) {
2129 2118 if ((template[i].ulValueLen == 0) ||
2130 2119 (template[i].pValue == NULL)) {
2131 2120 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2132 2121 goto fail_cleanup;
2133 2122 }
2134 2123 }
2135 2124
2136 2125 rv = get_bigint_attr_from_template(&value,
2137 2126 &template[i]);
2138 2127 if (rv != CKR_OK)
2139 2128 goto fail_cleanup;
2140 2129 break;
2141 2130
2142 2131 case CKA_VALUE_BITS:
2143 2132 isValueBits = 1;
2144 2133 rv = get_ulong_attr_from_template(&value_bits,
2145 2134 &template[i]);
2146 2135 if (rv != CKR_OK)
2147 2136 goto fail_cleanup;
2148 2137 break;
2149 2138
2150 2139 case CKA_LABEL:
2151 2140 isLabel = 1;
2152 2141 rv = get_string_from_template(&string_tmp,
2153 2142 &template[i]);
2154 2143 if (rv != CKR_OK)
2155 2144 goto fail_cleanup;
2156 2145 break;
2157 2146
2158 2147 case CKA_EC_PARAMS:
2159 2148 isECParam = 1;
2160 2149 rv = get_string_from_template(¶m_tmp,
2161 2150 &template[i]);
2162 2151 if (rv != CKR_OK)
2163 2152 goto fail_cleanup;
2164 2153 break;
2165 2154
2166 2155 default:
2167 2156 rv = soft_parse_common_attrs(&template[i],
2168 2157 &object_type);
2169 2158 if (rv != CKR_OK)
2170 2159 goto fail_cleanup;
2171 2160 break;
2172 2161
2173 2162 }
2174 2163 } /* For */
2175 2164
2176 2165 /* Allocate storage for Private Key Object. */
2177 2166 pvk = calloc(1, sizeof (private_key_obj_t));
2178 2167 if (pvk == NULL) {
2179 2168 rv = CKR_HOST_MEMORY;
2180 2169 goto fail_cleanup;
2181 2170 }
2182 2171
2183 2172 new_object->object_class_u.private_key = pvk;
2184 2173 new_object->class = CKO_PRIVATE_KEY;
2185 2174
2186 2175 if ((mode == SOFT_CREATE_OBJ) && (keytype == (CK_KEY_TYPE)~0UL)) {
2187 2176 rv = CKR_TEMPLATE_INCOMPLETE;
2188 2177 goto fail_cleanup;
2189 2178 }
2190 2179
2191 2180 if (mode == SOFT_GEN_KEY) {
2192 2181 /*
2193 2182 * The key type is not specified in the application's
2194 2183 * template, so we use the implied key type based on
2195 2184 * the mechanism.
2196 2185 */
2197 2186 if (keytype == (CK_KEY_TYPE)~0UL) {
2198 2187 keytype = key_type;
2199 2188 }
2200 2189
2201 2190 /* If still unspecified, template is incomplete */
2202 2191 if (keytype == (CK_KEY_TYPE)~0UL) {
2203 2192 rv = CKR_TEMPLATE_INCOMPLETE;
2204 2193 goto fail_cleanup;
2205 2194 }
2206 2195
2207 2196 /*
2208 2197 * The key type specified in the template does not
2209 2198 * match the implied key type based on the mechanism.
2210 2199 */
2211 2200 if (keytype != key_type) {
2212 2201 rv = CKR_TEMPLATE_INCONSISTENT;
2213 2202 goto fail_cleanup;
2214 2203 }
2215 2204 }
2216 2205
2217 2206 if (mode == SOFT_UNWRAP_KEY) {
2218 2207 /*
2219 2208 * Note that, for mode SOFT_UNWRAP_KEY, key type is not
2220 2209 * implied by the mechanism (key_type), so if it is not
2221 2210 * specified from the attribute template (keytype), it is
2222 2211 * incomplete.
2223 2212 */
2224 2213 if (keytype == (CK_KEY_TYPE)~0UL) {
2225 2214 rv = CKR_TEMPLATE_INCOMPLETE;
2226 2215 goto fail_cleanup;
2227 2216 }
2228 2217 }
2229 2218
2230 2219 new_object->key_type = keytype;
2231 2220
2232 2221 /* Supported key types of the Private Key Object */
2233 2222 switch (keytype) {
2234 2223 case CKK_RSA:
2235 2224 if (isPrime || isSubprime || isBase || isValue ||
2236 2225 isValueBits) {
2237 2226 rv = CKR_TEMPLATE_INCONSISTENT;
2238 2227 goto fail_cleanup;
2239 2228 }
2240 2229
2241 2230 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2242 2231 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2243 2232 isPrime2 || isExpo1 || isExpo2 || isCoef) {
2244 2233 rv = CKR_TEMPLATE_INCONSISTENT;
2245 2234 goto fail_cleanup;
2246 2235 } else
2247 2236 break;
2248 2237 }
2249 2238
2250 2239 if (isModulus && isPriExpo) {
2251 2240 /*
2252 2241 * Copy big integer attribute value to the
2253 2242 * designated place in the Private Key object.
2254 2243 */
2255 2244 copy_bigint_attr(&modulus, KEY_PRI_RSA_MOD(pvk));
2256 2245
2257 2246 copy_bigint_attr(&priexpo, KEY_PRI_RSA_PRIEXPO(pvk));
2258 2247 } else {
2259 2248 rv = CKR_TEMPLATE_INCOMPLETE;
2260 2249 goto fail_cleanup;
2261 2250 }
2262 2251
2263 2252 /* The following attributes are optional. */
2264 2253 if (isPubExpo) {
2265 2254 copy_bigint_attr(&pubexpo, KEY_PRI_RSA_PUBEXPO(pvk));
2266 2255 }
2267 2256
2268 2257 if (isPrime1) {
2269 2258 copy_bigint_attr(&prime1, KEY_PRI_RSA_PRIME1(pvk));
2270 2259 }
2271 2260
2272 2261 if (isPrime2) {
2273 2262 copy_bigint_attr(&prime2, KEY_PRI_RSA_PRIME2(pvk));
2274 2263 }
2275 2264
2276 2265 if (isExpo1) {
2277 2266 copy_bigint_attr(&expo1, KEY_PRI_RSA_EXPO1(pvk));
2278 2267 }
2279 2268
2280 2269 if (isExpo2) {
2281 2270 copy_bigint_attr(&expo2, KEY_PRI_RSA_EXPO2(pvk));
2282 2271 }
2283 2272
2284 2273 if (isCoef) {
2285 2274 copy_bigint_attr(&coef, KEY_PRI_RSA_COEF(pvk));
2286 2275 }
2287 2276 break;
2288 2277
2289 2278 case CKK_DSA:
2290 2279 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2291 2280 isPrime2 || isExpo1 || isExpo2 || isCoef ||
2292 2281 isValueBits) {
2293 2282 rv = CKR_TEMPLATE_INCONSISTENT;
2294 2283 goto fail_cleanup;
2295 2284 }
2296 2285
2297 2286 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2298 2287 if (isPrime || isSubprime || isBase || isValue) {
2299 2288 rv = CKR_TEMPLATE_INCONSISTENT;
2300 2289 goto fail_cleanup;
2301 2290 } else
2302 2291 break;
2303 2292 }
2304 2293
2305 2294 if (isPrime && isSubprime && isBase && isValue) {
2306 2295 /*
2307 2296 * The private value x must be less than subprime q.
2308 2297 * Size for big_init is in BIG_CHUNK_TYPE words.
2309 2298 */
2310 2299 #ifdef __sparcv9
2311 2300 if (big_init(&x,
2312 2301 (int)CHARLEN2BIGNUMLEN(value.big_value_len))
2313 2302 != BIG_OK) {
2314 2303 #else /* !__sparcv9 */
2315 2304 if (big_init(&x,
2316 2305 CHARLEN2BIGNUMLEN(value.big_value_len))
2317 2306 != BIG_OK) {
2318 2307 #endif /* __sparcv9 */
2319 2308 rv = CKR_HOST_MEMORY;
2320 2309 goto fail_cleanup;
2321 2310 }
2322 2311 #ifdef __sparcv9
2323 2312 if (big_init(&q,
2324 2313 (int)CHARLEN2BIGNUMLEN(subprime.big_value_len))
2325 2314 != BIG_OK) {
2326 2315 #else /* !__sparcv9 */
2327 2316 if (big_init(&q,
2328 2317 CHARLEN2BIGNUMLEN(subprime.big_value_len))
2329 2318 != BIG_OK) {
2330 2319 #endif /* __sparcv9 */
2331 2320 rv = CKR_HOST_MEMORY;
2332 2321 goto fail_cleanup;
2333 2322 }
2334 2323 bytestring2bignum(&x, value.big_value,
2335 2324 value.big_value_len);
2336 2325 bytestring2bignum(&q, subprime.big_value,
2337 2326 subprime.big_value_len);
2338 2327
2339 2328 if (big_cmp_abs(&x, &q) > 0) {
2340 2329 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2341 2330 goto fail_cleanup;
2342 2331 }
2343 2332
2344 2333 copy_bigint_attr(&prime, KEY_PRI_DSA_PRIME(pvk));
2345 2334
2346 2335 copy_bigint_attr(&subprime, KEY_PRI_DSA_SUBPRIME(pvk));
2347 2336
2348 2337 copy_bigint_attr(&base, KEY_PRI_DSA_BASE(pvk));
2349 2338
2350 2339 copy_bigint_attr(&value, KEY_PRI_DSA_VALUE(pvk));
2351 2340 } else {
2352 2341 rv = CKR_TEMPLATE_INCOMPLETE;
2353 2342 goto fail_cleanup;
2354 2343 }
2355 2344 break;
2356 2345
2357 2346 case CKK_DH:
2358 2347 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2359 2348 isPrime2 || isExpo1 || isExpo2 || isCoef ||
2360 2349 isSubprime) {
2361 2350 rv = CKR_TEMPLATE_INCONSISTENT;
2362 2351 goto fail_cleanup;
2363 2352 }
2364 2353
2365 2354 /* CKA_VALUE_BITS is for key gen but not unwrap */
2366 2355 if (mode == SOFT_GEN_KEY)
2367 2356 KEY_PRI_DH_VAL_BITS(pvk) = (isValueBits) ?
2368 2357 value_bits : 0;
2369 2358 else if (mode == SOFT_UNWRAP_KEY) {
2370 2359 if (isValueBits) {
2371 2360 rv = CKR_TEMPLATE_INCONSISTENT;
2372 2361 goto fail_cleanup;
2373 2362 }
2374 2363 }
2375 2364
2376 2365 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2377 2366 if (isPrime || isBase || isValue) {
2378 2367 rv = CKR_TEMPLATE_INCONSISTENT;
2379 2368 goto fail_cleanup;
2380 2369 } else
2381 2370 break;
2382 2371 }
2383 2372
2384 2373 if (isValueBits) {
2385 2374 rv = CKR_TEMPLATE_INCONSISTENT;
2386 2375 goto fail_cleanup;
2387 2376 }
2388 2377
2389 2378 if (isPrime && isBase && isValue) {
2390 2379 copy_bigint_attr(&prime, KEY_PRI_DH_PRIME(pvk));
2391 2380
2392 2381 copy_bigint_attr(&base, KEY_PRI_DH_BASE(pvk));
2393 2382
2394 2383 copy_bigint_attr(&value, KEY_PRI_DH_VALUE(pvk));
2395 2384 } else {
2396 2385 rv = CKR_TEMPLATE_INCOMPLETE;
2397 2386 goto fail_cleanup;
2398 2387 }
2399 2388 break;
2400 2389
2401 2390 case CKK_X9_42_DH:
2402 2391 if (isModulus || isPubExpo || isPriExpo || isPrime1 ||
2403 2392 isPrime2 || isExpo1 || isExpo2 || isCoef ||
2404 2393 isValueBits) {
2405 2394 rv = CKR_TEMPLATE_INCONSISTENT;
2406 2395 goto fail_cleanup;
2407 2396 }
2408 2397
2409 2398 if (mode == SOFT_GEN_KEY || mode == SOFT_UNWRAP_KEY) {
2410 2399 if (isPrime || isSubprime || isBase || isValue) {
2411 2400 rv = CKR_TEMPLATE_INCONSISTENT;
2412 2401 goto fail_cleanup;
2413 2402 } else
2414 2403 break;
2415 2404 }
2416 2405
2417 2406 if (isPrime && isSubprime && isBase && isValue) {
2418 2407 copy_bigint_attr(&prime, KEY_PRI_DH942_PRIME(pvk));
2419 2408
2420 2409 copy_bigint_attr(&base, KEY_PRI_DH942_BASE(pvk));
2421 2410
2422 2411 copy_bigint_attr(&subprime,
2423 2412 KEY_PRI_DH942_SUBPRIME(pvk));
2424 2413
2425 2414 copy_bigint_attr(&value, KEY_PRI_DH942_VALUE(pvk));
2426 2415 } else {
2427 2416 rv = CKR_TEMPLATE_INCOMPLETE;
2428 2417 goto fail_cleanup;
2429 2418 }
2430 2419 break;
2431 2420
2432 2421 case CKK_EC:
2433 2422 if (isModulus || isPubExpo || isPrime ||
2434 2423 isPrime1 || isPrime2 || isExpo1 || isExpo2 || isCoef ||
2435 2424 isValueBits || isBase) {
2436 2425 rv = CKR_TEMPLATE_INCONSISTENT;
2437 2426 goto fail_cleanup;
2438 2427
2439 2428 } else if (isECParam) {
2440 2429 rv = soft_add_extra_attr(¶m_tmp, new_object);
2441 2430 if (rv != CKR_OK)
2442 2431 goto fail_cleanup;
2443 2432 string_attr_cleanup(¶m_tmp);
2444 2433 }
2445 2434 if (isValue) {
2446 2435 copy_bigint_attr(&value, KEY_PRI_EC_VALUE(pvk));
2447 2436 }
2448 2437 break;
2449 2438
2450 2439 default:
2451 2440 rv = CKR_TEMPLATE_INCONSISTENT;
2452 2441 goto fail_cleanup;
2453 2442 }
2454 2443
2455 2444 /* Set up object. */
2456 2445 new_object->object_type = object_type;
2457 2446 new_object->bool_attr_mask = attr_mask;
2458 2447 if (isLabel) {
2459 2448 rv = soft_add_extra_attr(&string_tmp, new_object);
2460 2449 if (rv != CKR_OK)
2461 2450 goto fail_cleanup;
2462 2451 string_attr_cleanup(&string_tmp);
2463 2452 }
2464 2453 big_finish(&x);
2465 2454 big_finish(&q);
2466 2455
2467 2456 return (rv);
2468 2457
2469 2458 fail_cleanup:
2470 2459 /*
2471 2460 * cleanup the storage allocated to the local variables.
2472 2461 */
2473 2462 bigint_attr_cleanup(&modulus);
2474 2463 bigint_attr_cleanup(&priexpo);
2475 2464 bigint_attr_cleanup(&prime);
2476 2465 bigint_attr_cleanup(&subprime);
2477 2466 bigint_attr_cleanup(&base);
2478 2467 bigint_attr_cleanup(&value);
2479 2468 bigint_attr_cleanup(&pubexpo);
2480 2469 bigint_attr_cleanup(&prime1);
2481 2470 bigint_attr_cleanup(&prime2);
2482 2471 bigint_attr_cleanup(&expo1);
2483 2472 bigint_attr_cleanup(&expo2);
2484 2473 bigint_attr_cleanup(&coef);
2485 2474 string_attr_cleanup(&string_tmp);
2486 2475 string_attr_cleanup(¶m_tmp);
2487 2476 big_finish(&x);
2488 2477 big_finish(&q);
2489 2478
2490 2479 /*
2491 2480 * cleanup the storage allocated inside the object itself.
2492 2481 */
2493 2482 soft_cleanup_object(new_object);
2494 2483
2495 2484 return (rv);
2496 2485 }
2497 2486
2498 2487
2499 2488 /*
2500 2489 * Build a Secret Key Object.
2501 2490 *
2502 2491 * - Parse the object's template, and when an error is detected such as
2503 2492 * invalid attribute type, invalid attribute value, etc., return
2504 2493 * with appropriate return value.
2505 2494 * - Set up attribute mask field in the object for the supplied common
2506 2495 * attributes that have boolean type.
2507 2496 * - Build the attribute_info struct to hold the value of each supplied
2508 2497 * attribute that has byte array type. Link attribute_info structs
2509 2498 * together to form the extra attribute list of the object.
2510 2499 * - Allocate storage for the Secret Key object.
2511 2500 * - Build the Secret Key object. Allocate storage to hold the big integer
2512 2501 * value for the attribute CKA_VALUE that is required for all the key
2513 2502 * types supported by secret key object.
2514 2503 * This function is called internally with mode = SOFT_CREATE_OBJ_INT.
2515 2504 *
2516 2505 */
2517 2506 CK_RV
2518 2507 soft_build_secret_key_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
2519 2508 soft_object_t *new_object, CK_ULONG mode, CK_ULONG key_len,
2520 2509 CK_KEY_TYPE key_type)
2521 2510 {
2522 2511
2523 2512 ulong_t i;
2524 2513 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
2525 2514 uint64_t attr_mask = SECRET_KEY_DEFAULT;
2526 2515 CK_RV rv = CKR_OK;
2527 2516 int isLabel = 0;
2528 2517 /* Must set flags if mode != SOFT_UNWRAP_KEY, else must not set */
2529 2518 int isValue = 0;
2530 2519 /* Must not set flags if mode != SOFT_UNWRAP_KEY, else optional */
2531 2520 int isValueLen = 0;
2532 2521
2533 2522 CK_ATTRIBUTE string_tmp;
2534 2523
2535 2524 secret_key_obj_t *sck;
2536 2525 uchar_t object_type = 0;
2537 2526
2538 2527 string_tmp.pValue = NULL;
2539 2528
2540 2529 /* Allocate storage for Secret Key Object. */
2541 2530 sck = calloc(1, sizeof (secret_key_obj_t));
2542 2531 if (sck == NULL) {
2543 2532 rv = CKR_HOST_MEMORY;
2544 2533 goto fail_cleanup;
2545 2534 }
2546 2535
2547 2536 new_object->object_class_u.secret_key = sck;
2548 2537 new_object->class = CKO_SECRET_KEY;
2549 2538
2550 2539 for (i = 0; i < ulAttrNum; i++) {
2551 2540
2552 2541 /* Secret Key Object Attributes */
2553 2542 switch (template[i].type) {
2554 2543
2555 2544 /* common key attributes */
2556 2545 case CKA_KEY_TYPE:
2557 2546 keytype = *((CK_KEY_TYPE*)template[i].pValue);
2558 2547 break;
2559 2548
2560 2549 case CKA_ID:
2561 2550 case CKA_START_DATE:
2562 2551 case CKA_END_DATE:
2563 2552 /*
2564 2553 * Allocate storage to hold the attribute
2565 2554 * value with byte array type, and add it to
2566 2555 * the extra attribute list of the object.
2567 2556 */
2568 2557 rv = soft_add_extra_attr(&template[i],
2569 2558 new_object);
2570 2559 if (rv != CKR_OK) {
2571 2560 goto fail_cleanup;
2572 2561 }
2573 2562 break;
2574 2563
2575 2564 /*
2576 2565 * The following key related attribute types must
2577 2566 * not be specified by C_CreateObject and C_GenerateKey.
2578 2567 */
2579 2568 case CKA_LOCAL:
2580 2569 case CKA_KEY_GEN_MECHANISM:
2581 2570 case CKA_ALWAYS_SENSITIVE:
2582 2571 case CKA_NEVER_EXTRACTABLE:
2583 2572 rv = CKR_TEMPLATE_INCONSISTENT;
2584 2573 goto fail_cleanup;
2585 2574
2586 2575 /* Key related boolean attributes */
2587 2576 case CKA_DERIVE:
2588 2577 if (*(CK_BBOOL *)template[i].pValue)
2589 2578 attr_mask |= DERIVE_BOOL_ON;
2590 2579 break;
2591 2580
2592 2581 case CKA_SENSITIVE:
2593 2582 if (*(CK_BBOOL *)template[i].pValue)
2594 2583 attr_mask |= SENSITIVE_BOOL_ON;
2595 2584 break;
2596 2585
2597 2586 case CKA_ENCRYPT:
2598 2587 if (*(CK_BBOOL *)template[i].pValue)
2599 2588 attr_mask |= ENCRYPT_BOOL_ON;
2600 2589 else
2601 2590 attr_mask &= ~ENCRYPT_BOOL_ON;
2602 2591 break;
2603 2592
2604 2593 case CKA_DECRYPT:
2605 2594 if (*(CK_BBOOL *)template[i].pValue)
2606 2595 attr_mask |= DECRYPT_BOOL_ON;
2607 2596 else
2608 2597 attr_mask &= ~DECRYPT_BOOL_ON;
2609 2598 break;
2610 2599
2611 2600 case CKA_SIGN:
2612 2601 if (*(CK_BBOOL *)template[i].pValue)
2613 2602 attr_mask |= SIGN_BOOL_ON;
2614 2603 else
2615 2604 attr_mask &= ~SIGN_BOOL_ON;
2616 2605 break;
2617 2606
2618 2607 case CKA_VERIFY:
2619 2608 if (*(CK_BBOOL *)template[i].pValue)
2620 2609 attr_mask |= VERIFY_BOOL_ON;
2621 2610 else
2622 2611 attr_mask &= ~VERIFY_BOOL_ON;
2623 2612 break;
2624 2613
2625 2614 case CKA_WRAP:
2626 2615 if (*(CK_BBOOL *)template[i].pValue)
2627 2616 attr_mask |= WRAP_BOOL_ON;
2628 2617 else
2629 2618 attr_mask &= ~WRAP_BOOL_ON;
2630 2619 break;
2631 2620
2632 2621 case CKA_UNWRAP:
2633 2622 if (*(CK_BBOOL *)template[i].pValue)
2634 2623 attr_mask |= UNWRAP_BOOL_ON;
2635 2624 else
2636 2625 attr_mask &= ~UNWRAP_BOOL_ON;
2637 2626 break;
2638 2627
2639 2628 case CKA_EXTRACTABLE:
2640 2629 if (*(CK_BBOOL *)template[i].pValue)
2641 2630 attr_mask |= EXTRACTABLE_BOOL_ON;
2642 2631 else
2643 2632 attr_mask &= ~EXTRACTABLE_BOOL_ON;
2644 2633 break;
2645 2634
2646 2635 case CKA_MODIFIABLE:
2647 2636 if ((*(CK_BBOOL *)template[i].pValue) == B_FALSE)
2648 2637 attr_mask |= NOT_MODIFIABLE_BOOL_ON;
2649 2638 break;
2650 2639
2651 2640 case CKA_VALUE:
2652 2641 isValue = 1;
2653 2642 if (mode == SOFT_CREATE_OBJ) {
2654 2643 if ((template[i].ulValueLen == 0) ||
2655 2644 (template[i].pValue == NULL)) {
2656 2645 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2657 2646 goto fail_cleanup;
2658 2647 }
2659 2648 }
2660 2649
2661 2650 /*
2662 2651 * Copyin attribute from template
2663 2652 * to a local variable.
2664 2653 */
2665 2654 rv = get_bigint_attr_from_template((biginteger_t *)sck,
2666 2655 &template[i]);
2667 2656 if (rv != CKR_OK)
2668 2657 goto fail_cleanup;
2669 2658 break;
2670 2659
2671 2660 case CKA_VALUE_LEN:
2672 2661 isValueLen = 1;
2673 2662 rv = get_ulong_attr_from_template(&sck->sk_value_len,
2674 2663 &template[i]);
2675 2664 if (rv != CKR_OK)
2676 2665 goto fail_cleanup;
2677 2666 break;
2678 2667
2679 2668 case CKA_LABEL:
2680 2669 isLabel = 1;
2681 2670 rv = get_string_from_template(&string_tmp,
2682 2671 &template[i]);
2683 2672 if (rv != CKR_OK)
2684 2673 goto fail_cleanup;
2685 2674 break;
2686 2675
2687 2676 default:
2688 2677 rv = soft_parse_common_attrs(&template[i],
2689 2678 &object_type);
2690 2679 if (rv != CKR_OK)
2691 2680 goto fail_cleanup;
2692 2681 break;
2693 2682
2694 2683 }
2695 2684 } /* For */
2696 2685
2697 2686 switch (mode) {
2698 2687 case SOFT_CREATE_OBJ:
2699 2688 case SOFT_CREATE_OBJ_INT:
2700 2689 case SOFT_DERIVE_KEY_DH:
2701 2690 /*
2702 2691 * The key type must be specified in the application's
2703 2692 * template. Otherwise, returns error.
2704 2693 */
2705 2694 if (keytype == (CK_KEY_TYPE)~0UL) {
2706 2695 rv = CKR_TEMPLATE_INCOMPLETE;
2707 2696 goto fail_cleanup;
2708 2697 }
2709 2698 break;
2710 2699
2711 2700 case SOFT_GEN_KEY:
2712 2701 if (keytype == (CK_KEY_TYPE)~0UL) {
2713 2702 /*
2714 2703 * The key type is not specified in the application's
2715 2704 * template, so we use the implied key type based on
2716 2705 * the mechanism.
2717 2706 */
2718 2707 keytype = key_type;
2719 2708 } else {
2720 2709 if (keytype != key_type) {
2721 2710 /*
2722 2711 * The key type specified in the template
2723 2712 * does not match the implied key type based
2724 2713 * on the mechanism.
2725 2714 */
2726 2715 rv = CKR_TEMPLATE_INCONSISTENT;
2727 2716 goto fail_cleanup;
2728 2717 }
2729 2718 }
2730 2719
2731 2720 /*
2732 2721 * If a key_len is passed as a parameter, it has to
2733 2722 * match the one found in the template.
2734 2723 */
2735 2724 if (key_len > 0) {
2736 2725 if (isValueLen && sck->sk_value_len != key_len) {
2737 2726 rv = CKR_TEMPLATE_INCONSISTENT;
2738 2727 goto fail_cleanup;
2739 2728 }
2740 2729 isValueLen = 1;
2741 2730 sck->sk_value_len = key_len;
2742 2731 }
2743 2732 break;
2744 2733
2745 2734 case SOFT_UNWRAP_KEY:
2746 2735 /*
2747 2736 * Note that, for mode SOFT_UNWRAP_KEY, key type is not
2748 2737 * implied by the mechanism (key_type), so if it is not
2749 2738 * specified from the attribute template (keytype), it is
2750 2739 * incomplete.
2751 2740 */
2752 2741 if (keytype == (CK_KEY_TYPE)~0UL) {
2753 2742 rv = CKR_TEMPLATE_INCOMPLETE;
2754 2743 goto fail_cleanup;
2755 2744 }
2756 2745 break;
2757 2746
2758 2747 case SOFT_DERIVE_KEY_OTHER:
2759 2748 /*
2760 2749 * For CKM_MD5_KEY_DERIVATION & CKM_SHA1_KEY_DERIVATION, the
2761 2750 * key type is optional.
2762 2751 */
2763 2752 if (keytype == (CK_KEY_TYPE)~0UL) {
2764 2753 keytype = key_type;
2765 2754 }
2766 2755 break;
2767 2756 }
2768 2757
2769 2758 switch (mode) {
2770 2759 case SOFT_CREATE_OBJ:
2771 2760 case SOFT_CREATE_OBJ_INT:
2772 2761 switch (keytype) {
2773 2762 case CKK_RC4:
2774 2763 if (!isValue) {
2775 2764 rv = CKR_TEMPLATE_INCOMPLETE;
2776 2765 goto fail_cleanup;
2777 2766 }
2778 2767 if ((sck->sk_value_len < ARCFOUR_MIN_KEY_BYTES) ||
2779 2768 (sck->sk_value_len > ARCFOUR_MAX_KEY_BYTES)) {
2780 2769 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2781 2770 goto fail_cleanup;
2782 2771 }
2783 2772 break;
2784 2773
2785 2774 case CKK_GENERIC_SECRET:
2786 2775 if (!isValue) {
2787 2776 rv = CKR_TEMPLATE_INCOMPLETE;
2788 2777 goto fail_cleanup;
2789 2778 }
2790 2779 break;
2791 2780
2792 2781 case CKK_AES:
2793 2782 if (!isValue) {
2794 2783 rv = CKR_TEMPLATE_INCOMPLETE;
2795 2784 goto fail_cleanup;
2796 2785 }
2797 2786 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
2798 2787 (sck->sk_value_len != AES_192_KEY_BYTES) &&
2799 2788 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
2800 2789 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2801 2790 goto fail_cleanup;
2802 2791 }
2803 2792 break;
2804 2793
2805 2794 case CKK_BLOWFISH:
2806 2795 if (!isValue) {
2807 2796 rv = CKR_TEMPLATE_INCOMPLETE;
2808 2797 goto fail_cleanup;
2809 2798 }
2810 2799 if ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
2811 2800 (sck->sk_value_len > BLOWFISH_MAXBYTES)) {
2812 2801 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2813 2802 goto fail_cleanup;
2814 2803 }
2815 2804
2816 2805 break;
2817 2806
2818 2807 case CKK_DES:
2819 2808 if (!isValue) {
2820 2809 rv = CKR_TEMPLATE_INCOMPLETE;
2821 2810 goto fail_cleanup;
2822 2811 }
2823 2812 if (sck->sk_value_len != DES_KEYSIZE) {
2824 2813 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2825 2814 goto fail_cleanup;
2826 2815 }
2827 2816 break;
2828 2817
2829 2818 case CKK_DES2:
2830 2819 if (!isValue) {
2831 2820 rv = CKR_TEMPLATE_INCOMPLETE;
2832 2821 goto fail_cleanup;
2833 2822 }
2834 2823 if (sck->sk_value_len != DES2_KEYSIZE) {
2835 2824 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2836 2825 goto fail_cleanup;
2837 2826 }
2838 2827 break;
2839 2828
2840 2829 case CKK_DES3:
2841 2830 if (!isValue) {
2842 2831 rv = CKR_TEMPLATE_INCOMPLETE;
2843 2832 goto fail_cleanup;
2844 2833 }
2845 2834 if (sck->sk_value_len != DES3_KEYSIZE) {
2846 2835 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2847 2836 goto fail_cleanup;
2848 2837 }
2849 2838 break;
2850 2839
2851 2840 default:
2852 2841 rv = CKR_TEMPLATE_INCONSISTENT;
2853 2842 goto fail_cleanup;
2854 2843 }
2855 2844
2856 2845 if (isValueLen) {
2857 2846 /*
2858 2847 * Templates for internal object creation come from
2859 2848 * applications calls to C_DeriveKey(), for which it
2860 2849 * is OKey to pass a CKA_VALUE_LEN attribute, as
2861 2850 * long as it does not conflict with the length of the
2862 2851 * CKA_VALUE attribute.
2863 2852 */
2864 2853 if ((mode != SOFT_CREATE_OBJ_INT) ||
2865 2854 ((key_len > 0) && sck->sk_value_len != key_len)) {
2866 2855 rv = CKR_TEMPLATE_INCONSISTENT;
2867 2856 goto fail_cleanup;
2868 2857 }
2869 2858 }
2870 2859 break;
2871 2860
2872 2861 case SOFT_GEN_KEY:
2873 2862 /* CKA_VALUE must not be specified */
2874 2863 if (isValue) {
2875 2864 rv = CKR_TEMPLATE_INCONSISTENT;
2876 2865 goto fail_cleanup;
2877 2866 }
2878 2867
2879 2868 switch (keytype) {
2880 2869 /*
2881 2870 * CKA_VALUE_LEN must be specified by C_GenerateKey
2882 2871 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
2883 2872 */
2884 2873 case CKK_RC4:
2885 2874 if (!isValueLen) {
2886 2875 rv = CKR_TEMPLATE_INCOMPLETE;
2887 2876 goto fail_cleanup;
2888 2877 }
2889 2878 ;
2890 2879 if ((sck->sk_value_len < ARCFOUR_MIN_KEY_BYTES) ||
2891 2880 (sck->sk_value_len > ARCFOUR_MAX_KEY_BYTES)) {
2892 2881 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2893 2882 goto fail_cleanup;
2894 2883 }
2895 2884 break;
2896 2885
2897 2886 case CKK_GENERIC_SECRET:
2898 2887 /* arbitrary key length - no length checking */
2899 2888 if (!isValueLen) {
2900 2889 rv = CKR_TEMPLATE_INCOMPLETE;
2901 2890 goto fail_cleanup;
2902 2891 }
2903 2892 break;
2904 2893
2905 2894 case CKK_AES:
2906 2895 if (!isValueLen) {
2907 2896 rv = CKR_TEMPLATE_INCOMPLETE;
2908 2897 goto fail_cleanup;
2909 2898 }
2910 2899
2911 2900 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
2912 2901 (sck->sk_value_len != AES_192_KEY_BYTES) &&
2913 2902 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
2914 2903 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2915 2904 goto fail_cleanup;
2916 2905 }
2917 2906
2918 2907 break;
2919 2908
2920 2909 case CKK_BLOWFISH:
2921 2910 if (!isValueLen) {
2922 2911 rv = CKR_TEMPLATE_INCOMPLETE;
2923 2912 goto fail_cleanup;
2924 2913 }
2925 2914 if ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
2926 2915 (sck->sk_value_len > BLOWFISH_MAXBYTES)) {
2927 2916 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2928 2917 goto fail_cleanup;
2929 2918 }
2930 2919
2931 2920 break;
2932 2921
2933 2922 case CKK_DES:
2934 2923 case CKK_DES2:
2935 2924 case CKK_DES3:
2936 2925 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
2937 2926 if (isValueLen) {
2938 2927 rv = CKR_TEMPLATE_INCONSISTENT;
2939 2928 goto fail_cleanup;
2940 2929 }
2941 2930 break;
2942 2931
2943 2932 default:
2944 2933 rv = CKR_TEMPLATE_INCONSISTENT;
2945 2934 goto fail_cleanup;
2946 2935 }
2947 2936 break;
2948 2937
2949 2938 case SOFT_UNWRAP_KEY:
2950 2939 /*
2951 2940 * According to v2.11 of PKCS#11 spec, neither CKA_VALUE nor
2952 2941 * CKA_VALUE_LEN can be be specified; however v2.20 has this
2953 2942 * restriction removed, perhaps because it makes it hard to
2954 2943 * determine variable-length key sizes. This case statement
2955 2944 * complied with v2.20.
2956 2945 */
2957 2946 if (isValue) {
2958 2947 rv = CKR_TEMPLATE_INCONSISTENT;
2959 2948 goto fail_cleanup;
2960 2949 }
2961 2950
2962 2951 switch (keytype) {
2963 2952 /*
2964 2953 * CKA_VALUE_LEN is optional
2965 2954 * if key is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET
2966 2955 * and the unwrapping mech is *_CBC_PAD.
2967 2956 *
2968 2957 * CKA_VALUE_LEN is required
2969 2958 * if key is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET
2970 2959 * and the unwrapping mech is *_ECB or *_CBC.
2971 2960 *
2972 2961 * since mech is not known at this point, CKA_VALUE_LEN is
2973 2962 * treated as optional and the caller needs to enforce it.
2974 2963 */
2975 2964 case CKK_RC4:
2976 2965 if (isValueLen) {
2977 2966 if ((sck->sk_value_len <
2978 2967 ARCFOUR_MIN_KEY_BYTES) ||
2979 2968 (sck->sk_value_len >
2980 2969 ARCFOUR_MAX_KEY_BYTES)) {
2981 2970 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2982 2971 goto fail_cleanup;
2983 2972 }
2984 2973 }
2985 2974 break;
2986 2975
2987 2976 case CKK_GENERIC_SECRET:
2988 2977 /* arbitrary key length - no length checking */
2989 2978 break;
2990 2979
2991 2980 case CKK_AES:
2992 2981 if (isValueLen) {
2993 2982 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
2994 2983 (sck->sk_value_len != AES_192_KEY_BYTES) &&
2995 2984 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
2996 2985 rv = CKR_ATTRIBUTE_VALUE_INVALID;
2997 2986 goto fail_cleanup;
2998 2987 }
2999 2988 }
3000 2989 break;
3001 2990
3002 2991 case CKK_BLOWFISH:
3003 2992 if (isValueLen &&
3004 2993 ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
3005 2994 (sck->sk_value_len > BLOWFISH_MAXBYTES))) {
3006 2995 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3007 2996 goto fail_cleanup;
3008 2997 }
3009 2998 break;
3010 2999
3011 3000 case CKK_DES:
3012 3001 case CKK_DES2:
3013 3002 case CKK_DES3:
3014 3003 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
3015 3004 if (isValueLen) {
3016 3005 rv = CKR_TEMPLATE_INCONSISTENT;
3017 3006 goto fail_cleanup;
3018 3007 }
3019 3008 break;
3020 3009
3021 3010 default:
3022 3011 rv = CKR_TEMPLATE_INCONSISTENT;
3023 3012 goto fail_cleanup;
3024 3013 }
3025 3014 break;
3026 3015
3027 3016 case SOFT_DERIVE_KEY_DH:
3028 3017 /* CKA_VALUE must not be specified */
3029 3018 if (isValue) {
3030 3019 rv = CKR_TEMPLATE_INCONSISTENT;
3031 3020 goto fail_cleanup;
3032 3021 }
3033 3022
3034 3023 switch (keytype) {
3035 3024 /*
3036 3025 * CKA_VALUE_LEN is optional
3037 3026 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
3038 3027 */
3039 3028 case CKK_RC4:
3040 3029 if (isValueLen) {
3041 3030 if ((sck->sk_value_len <
3042 3031 ARCFOUR_MIN_KEY_BYTES) ||
3043 3032 (sck->sk_value_len >
3044 3033 ARCFOUR_MAX_KEY_BYTES)) {
3045 3034 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3046 3035 goto fail_cleanup;
3047 3036 }
3048 3037 }
3049 3038 break;
3050 3039
3051 3040 case CKK_GENERIC_SECRET:
3052 3041 /* arbitrary key length - no length checking */
3053 3042 break;
3054 3043
3055 3044 case CKK_AES:
3056 3045 if (isValueLen) {
3057 3046 if ((sck->sk_value_len != AES_MIN_KEY_BYTES) &&
3058 3047 (sck->sk_value_len != AES_192_KEY_BYTES) &&
3059 3048 (sck->sk_value_len != AES_MAX_KEY_BYTES)) {
3060 3049 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3061 3050 goto fail_cleanup;
3062 3051 }
3063 3052 }
3064 3053
3065 3054 break;
3066 3055
3067 3056 case CKK_BLOWFISH:
3068 3057 if (isValueLen &&
3069 3058 ((sck->sk_value_len < BLOWFISH_MINBYTES) ||
3070 3059 (sck->sk_value_len > BLOWFISH_MAXBYTES))) {
3071 3060 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3072 3061 goto fail_cleanup;
3073 3062 }
3074 3063 break;
3075 3064
3076 3065 case CKK_DES:
3077 3066 case CKK_DES2:
3078 3067 case CKK_DES3:
3079 3068 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
3080 3069 if (isValueLen) {
3081 3070 rv = CKR_TEMPLATE_INCONSISTENT;
3082 3071 goto fail_cleanup;
3083 3072 }
3084 3073 break;
3085 3074
3086 3075 default:
3087 3076 rv = CKR_TEMPLATE_INCONSISTENT;
3088 3077 goto fail_cleanup;
3089 3078 }
3090 3079 break;
3091 3080
3092 3081 case SOFT_DERIVE_KEY_OTHER:
3093 3082 /* CKA_VALUE must not be specified */
3094 3083 if (isValue) {
3095 3084 rv = CKR_TEMPLATE_INCONSISTENT;
3096 3085 goto fail_cleanup;
3097 3086 }
3098 3087
3099 3088 switch (keytype) {
3100 3089 /*
3101 3090 * CKA_VALUE_LEN is an optional attribute for
3102 3091 * CKM_SHA1_KEY_DERIVATION and CKM_MD5_KEY_DERIVATION
3103 3092 * if mech is CKK_RC4, CKK_AES, CKK_GENERIC_SECRET.
3104 3093 */
3105 3094 case CKK_RC4:
3106 3095 case CKK_GENERIC_SECRET:
3107 3096 case CKK_AES:
3108 3097 case CKK_BLOWFISH:
3109 3098 /*
3110 3099 * No need to check key length value here, it will be
3111 3100 * validated later in soft_key_derive_check_length().
3112 3101 */
3113 3102 break;
3114 3103
3115 3104 case CKK_DES:
3116 3105 case CKK_DES2:
3117 3106 case CKK_DES3:
3118 3107 /* CKA_VALUE_LEN attribute does not apply to DES<n> */
3119 3108 if (isValueLen) {
3120 3109 rv = CKR_TEMPLATE_INCONSISTENT;
3121 3110 goto fail_cleanup;
3122 3111 }
3123 3112 break;
3124 3113
3125 3114 default:
3126 3115 rv = CKR_TEMPLATE_INCONSISTENT;
3127 3116 goto fail_cleanup;
3128 3117 }
3129 3118 break;
3130 3119 }
3131 3120
3132 3121 /* Set up object. */
3133 3122 new_object->key_type = keytype;
3134 3123 new_object->object_type = object_type;
3135 3124 new_object->bool_attr_mask = attr_mask;
3136 3125 if (isLabel) {
3137 3126 rv = soft_add_extra_attr(&string_tmp, new_object);
3138 3127 if (rv != CKR_OK)
3139 3128 goto fail_cleanup;
3140 3129 string_attr_cleanup(&string_tmp);
3141 3130 }
3142 3131 return (rv);
3143 3132
3144 3133 fail_cleanup:
3145 3134 /*
3146 3135 * cleanup the storage allocated to the local variables.
3147 3136 */
3148 3137 bigint_attr_cleanup((biginteger_t *)sck);
3149 3138 string_attr_cleanup(&string_tmp);
3150 3139
3151 3140 /*
3152 3141 * cleanup the storage allocated inside the object itself.
3153 3142 */
3154 3143 soft_cleanup_object(new_object);
3155 3144
3156 3145 return (rv);
3157 3146 }
3158 3147
3159 3148
3160 3149 /*
3161 3150 * Build a Domain Parameter Object.
3162 3151 *
3163 3152 * - Parse the object's template, and when an error is detected such as
3164 3153 * invalid attribute type, invalid attribute value, etc., return
3165 3154 * with appropriate return value.
3166 3155 * - Allocate storage for the Domain Parameter object.
3167 3156 * - Build the Domain Parameter object according to the key type. Allocate
3168 3157 * storage to hold the big integer value for the supplied attributes
3169 3158 * that are required for a certain key type.
3170 3159 *
3171 3160 */
3172 3161 CK_RV
3173 3162 soft_build_domain_parameters_object(CK_ATTRIBUTE_PTR template,
3174 3163 CK_ULONG ulAttrNum, soft_object_t *new_object)
3175 3164 {
3176 3165
3177 3166 ulong_t i;
3178 3167 CK_KEY_TYPE keytype = (CK_KEY_TYPE)~0UL;
3179 3168 CK_RV rv = CKR_OK;
3180 3169 int isLabel = 0;
3181 3170 /* Must set flags */
3182 3171 int isPrime = 0;
3183 3172 int isSubprime = 0;
3184 3173 int isBase = 0;
3185 3174 /* Must not set flags */
3186 3175 int isPrimeBits = 0;
3187 3176 int isSubPrimeBits = 0;
3188 3177
3189 3178 biginteger_t prime;
3190 3179 biginteger_t subprime;
3191 3180 biginteger_t base;
3192 3181 CK_ATTRIBUTE string_tmp;
3193 3182
3194 3183 domain_obj_t *dom;
3195 3184 uchar_t object_type = 0;
3196 3185
3197 3186 /* prevent bigint_attr_cleanup from freeing invalid attr value */
3198 3187 (void) memset(&prime, 0x0, sizeof (biginteger_t));
3199 3188 (void) memset(&subprime, 0x0, sizeof (biginteger_t));
3200 3189 (void) memset(&base, 0x0, sizeof (biginteger_t));
3201 3190 string_tmp.pValue = NULL;
3202 3191
3203 3192 for (i = 0; i < ulAttrNum; i++) {
3204 3193
3205 3194 /* Domain Parameters Object Attributes */
3206 3195 switch (template[i].type) {
3207 3196
3208 3197 /* common domain parameter attribute */
3209 3198 case CKA_KEY_TYPE:
3210 3199 keytype = *((CK_KEY_TYPE*)template[i].pValue);
3211 3200 break;
3212 3201
3213 3202 /*
3214 3203 * The following common domain parameter attribute
3215 3204 * must not be specified by C_CreateObject.
3216 3205 */
3217 3206 case CKA_LOCAL:
3218 3207 rv = CKR_TEMPLATE_INCONSISTENT;
3219 3208 goto fail_cleanup;
3220 3209
3221 3210 /*
3222 3211 * The following domain parameter attributes must be
3223 3212 * specified according to the key type by
3224 3213 * C_CreateObject.
3225 3214 */
3226 3215 case CKA_PRIME:
3227 3216 isPrime = 1;
3228 3217 /*
3229 3218 * Copyin big integer attribute from template
3230 3219 * to a local variable.
3231 3220 */
3232 3221 rv = get_bigint_attr_from_template(&prime,
3233 3222 &template[i]);
3234 3223 if (rv != CKR_OK)
3235 3224 goto fail_cleanup;
3236 3225 break;
3237 3226
3238 3227 case CKA_SUBPRIME:
3239 3228 isSubprime = 1;
3240 3229 rv = get_bigint_attr_from_template(&subprime,
3241 3230 &template[i]);
3242 3231 if (rv != CKR_OK)
3243 3232 goto fail_cleanup;
3244 3233 break;
3245 3234
3246 3235 case CKA_BASE:
3247 3236 isBase = 1;
3248 3237 rv = get_bigint_attr_from_template(&base,
3249 3238 &template[i]);
3250 3239 if (rv != CKR_OK)
3251 3240 goto fail_cleanup;
3252 3241 break;
3253 3242
3254 3243 case CKA_PRIME_BITS:
3255 3244 isPrimeBits = 1;
3256 3245 break;
3257 3246
3258 3247 case CKA_SUB_PRIME_BITS:
3259 3248 isSubPrimeBits = 1;
3260 3249 break;
3261 3250
3262 3251 case CKA_LABEL:
3263 3252 isLabel = 1;
3264 3253 rv = get_string_from_template(&string_tmp,
3265 3254 &template[i]);
3266 3255 if (rv != CKR_OK)
3267 3256 goto fail_cleanup;
3268 3257 break;
3269 3258
3270 3259 default:
3271 3260 rv = soft_parse_common_attrs(&template[i],
3272 3261 &object_type);
3273 3262 if (rv != CKR_OK)
3274 3263 goto fail_cleanup;
3275 3264 break;
3276 3265
3277 3266 }
3278 3267 } /* For */
3279 3268
3280 3269 /* Allocate storage for Domain Parameters Object. */
3281 3270 dom = calloc(1, sizeof (domain_obj_t));
3282 3271 if (dom == NULL) {
3283 3272 rv = CKR_HOST_MEMORY;
3284 3273 goto fail_cleanup;
3285 3274 }
3286 3275
3287 3276 new_object->object_class_u.domain = dom;
3288 3277 new_object->class = CKO_DOMAIN_PARAMETERS;
3289 3278
3290 3279 if (keytype == (CK_KEY_TYPE)~0UL) {
3291 3280 rv = CKR_TEMPLATE_INCOMPLETE;
3292 3281 goto fail_cleanup;
3293 3282 }
3294 3283
3295 3284 new_object->key_type = keytype;
3296 3285
3297 3286 /* Supported key types of the Domain Parameters Object */
3298 3287 switch (keytype) {
3299 3288 case CKK_DSA:
3300 3289 if (isPrimeBits || isSubPrimeBits) {
3301 3290 rv = CKR_TEMPLATE_INCONSISTENT;
3302 3291 goto fail_cleanup;
3303 3292 }
3304 3293
3305 3294 if (isPrime && isSubprime && isBase) {
3306 3295 /*
3307 3296 * Copy big integer attribute value to the
3308 3297 * designated place in the domain parameter
3309 3298 * object.
3310 3299 */
3311 3300 copy_bigint_attr(&prime, KEY_DOM_DSA_PRIME(dom));
3312 3301
3313 3302 copy_bigint_attr(&subprime, KEY_DOM_DSA_SUBPRIME(dom));
3314 3303
3315 3304 copy_bigint_attr(&base, KEY_DOM_DSA_BASE(dom));
3316 3305 } else {
3317 3306 rv = CKR_TEMPLATE_INCOMPLETE;
3318 3307 goto fail_cleanup;
3319 3308 }
3320 3309 break;
3321 3310
3322 3311 case CKK_DH:
3323 3312 if (isPrimeBits || isSubprime || isSubPrimeBits) {
3324 3313 rv = CKR_TEMPLATE_INCONSISTENT;
3325 3314 goto fail_cleanup;
3326 3315 }
3327 3316
3328 3317 if (isPrime && isBase) {
3329 3318 copy_bigint_attr(&prime, KEY_DOM_DH_PRIME(dom));
3330 3319
3331 3320 copy_bigint_attr(&base, KEY_DOM_DH_BASE(dom));
3332 3321 } else {
3333 3322 rv = CKR_TEMPLATE_INCOMPLETE;
3334 3323 goto fail_cleanup;
3335 3324 }
3336 3325 break;
3337 3326
3338 3327 case CKK_X9_42_DH:
3339 3328 if (isPrimeBits || isSubPrimeBits) {
3340 3329 rv = CKR_TEMPLATE_INCONSISTENT;
3341 3330 goto fail_cleanup;
3342 3331 }
3343 3332
3344 3333 if (isPrime && isSubprime && isBase) {
3345 3334 copy_bigint_attr(&prime, KEY_DOM_DH942_PRIME(dom));
3346 3335
3347 3336 copy_bigint_attr(&base, KEY_DOM_DH942_BASE(dom));
3348 3337
3349 3338 copy_bigint_attr(&subprime,
3350 3339 KEY_DOM_DH942_SUBPRIME(dom));
3351 3340 } else {
3352 3341 rv = CKR_TEMPLATE_INCOMPLETE;
3353 3342 goto fail_cleanup;
3354 3343 }
3355 3344 break;
3356 3345
3357 3346 default:
3358 3347 rv = CKR_TEMPLATE_INCONSISTENT;
3359 3348 goto fail_cleanup;
3360 3349 }
3361 3350
3362 3351 new_object->object_type = object_type;
3363 3352
3364 3353 if (isLabel) {
3365 3354 rv = soft_add_extra_attr(&string_tmp, new_object);
3366 3355 if (rv != CKR_OK)
3367 3356 goto fail_cleanup;
3368 3357 string_attr_cleanup(&string_tmp);
3369 3358 }
3370 3359
3371 3360 return (rv);
3372 3361
3373 3362 fail_cleanup:
3374 3363 /*
3375 3364 * cleanup the storage allocated to the local variables.
3376 3365 */
3377 3366 bigint_attr_cleanup(&prime);
3378 3367 bigint_attr_cleanup(&subprime);
3379 3368 bigint_attr_cleanup(&base);
3380 3369 string_attr_cleanup(&string_tmp);
3381 3370
3382 3371 /*
3383 3372 * cleanup the storage allocated inside the object itself.
3384 3373 */
3385 3374 soft_cleanup_object(new_object);
3386 3375
3387 3376 return (rv);
3388 3377 }
3389 3378
3390 3379 /*
3391 3380 * Build a Certificate Object
3392 3381 *
3393 3382 * - Parse the object's template, and when an error is detected such as
3394 3383 * invalid attribute type, invalid attribute value, etc., return
3395 3384 * with appropriate return value.
3396 3385 * - Allocate storage for the Certificate object
3397 3386 */
3398 3387 static CK_RV
3399 3388 soft_build_certificate_object(CK_ATTRIBUTE_PTR template,
3400 3389 CK_ULONG ulAttrNum, soft_object_t *new_object,
3401 3390 CK_CERTIFICATE_TYPE cert_type)
3402 3391 {
3403 3392 uint64_t attr_mask = 0;
3404 3393 CK_RV rv = CKR_OK;
3405 3394 CK_ULONG i;
3406 3395 int owner_set = 0;
3407 3396 int value_set = 0;
3408 3397 int subject_set = 0;
3409 3398 certificate_obj_t *cert;
3410 3399 /* certificate type defaults to the value given as a parameter */
3411 3400 CK_CERTIFICATE_TYPE certtype = cert_type;
3412 3401 CK_ATTRIBUTE string_tmp;
3413 3402 int isLabel = 0;
3414 3403 uchar_t object_type = 0;
3415 3404
3416 3405 /*
3417 3406 * Look for the certificate type attribute and do some
3418 3407 * sanity checking before creating the structures.
3419 3408 */
3420 3409 for (i = 0; i < ulAttrNum; i++) {
3421 3410 /* Certificate Object Attributes */
3422 3411 switch (template[i].type) {
3423 3412 case CKA_CERTIFICATE_TYPE:
3424 3413 certtype =
3425 3414 *((CK_CERTIFICATE_TYPE*)template[i].pValue);
3426 3415 break;
3427 3416 case CKA_SUBJECT:
3428 3417 subject_set = 1;
3429 3418 break;
3430 3419 case CKA_OWNER:
3431 3420 owner_set = 1;
3432 3421 break;
3433 3422 case CKA_VALUE:
3434 3423 value_set = 1;
3435 3424 break;
3436 3425 }
3437 3426 }
3438 3427
3439 3428 /* The certificate type MUST be specified */
3440 3429 if (certtype != CKC_X_509 && certtype != CKC_X_509_ATTR_CERT)
3441 3430 return (CKR_TEMPLATE_INCOMPLETE);
3442 3431
3443 3432 /*
3444 3433 * For X.509 certs, the CKA_SUBJECT and CKA_VALUE
3445 3434 * must be present at creation time.
3446 3435 */
3447 3436 if (certtype == CKC_X_509 &&
3448 3437 (!subject_set || !value_set))
3449 3438 return (CKR_TEMPLATE_INCOMPLETE);
3450 3439
3451 3440 /*
3452 3441 * For X.509 Attribute certs, the CKA_OWNER and CKA_VALUE
3453 3442 * must be present at creation time.
3454 3443 */
3455 3444 if (certtype == CKC_X_509_ATTR_CERT &&
3456 3445 (!owner_set || !value_set))
3457 3446 return (CKR_TEMPLATE_INCOMPLETE);
3458 3447
3459 3448 string_tmp.pValue = NULL;
3460 3449 cert = calloc(1, sizeof (certificate_obj_t));
3461 3450 if (cert == NULL) {
3462 3451 return (CKR_HOST_MEMORY);
3463 3452 }
3464 3453 cert->certificate_type = certtype;
3465 3454
3466 3455 for (i = 0; i < ulAttrNum; i++) {
3467 3456 /* Certificate Object Attributes */
3468 3457 switch (certtype) {
3469 3458 case CKC_X_509:
3470 3459 switch (template[i].type) {
3471 3460 case CKA_SUBJECT:
3472 3461 rv = get_cert_attr_from_template(
3473 3462 &cert->cert_type_u.x509.subject,
3474 3463 &template[i]);
3475 3464 break;
3476 3465 case CKA_VALUE:
3477 3466 rv = get_cert_attr_from_template(
3478 3467 &cert->cert_type_u.x509.value,
3479 3468 &template[i]);
3480 3469 break;
3481 3470 case CKA_LABEL:
3482 3471 isLabel = 1;
3483 3472 rv = get_string_from_template(
3484 3473 &string_tmp,
3485 3474 &template[i]);
3486 3475 if (rv != CKR_OK)
3487 3476 goto fail_cleanup;
3488 3477 break;
3489 3478 case CKA_ID:
3490 3479 case CKA_ISSUER:
3491 3480 case CKA_SERIAL_NUMBER:
3492 3481 rv = soft_add_extra_attr(&template[i],
3493 3482 new_object);
3494 3483 break;
3495 3484 case CKA_MODIFIABLE:
3496 3485 if ((*(CK_BBOOL *)template[i].pValue) ==
3497 3486 B_FALSE)
3498 3487 attr_mask |=
3499 3488 NOT_MODIFIABLE_BOOL_ON;
3500 3489 break;
3501 3490 case CKA_CERTIFICATE_TYPE:
3502 3491 break;
3503 3492 default:
3504 3493 rv = soft_parse_common_attrs(
3505 3494 &template[i], &object_type);
3506 3495 if (rv != CKR_OK)
3507 3496 goto fail_cleanup;
3508 3497 }
3509 3498 break;
3510 3499 case CKC_X_509_ATTR_CERT:
3511 3500 switch (template[i].type) {
3512 3501 case CKA_OWNER:
3513 3502 rv = get_cert_attr_from_template(
3514 3503 &cert->cert_type_u.x509_attr.owner,
3515 3504 &template[i]);
3516 3505 break;
3517 3506 case CKA_VALUE:
3518 3507 rv = get_cert_attr_from_template(
3519 3508 &cert->cert_type_u.x509_attr.value,
3520 3509 &template[i]);
3521 3510 break;
3522 3511 case CKA_LABEL:
3523 3512 isLabel = 1;
3524 3513 rv = get_string_from_template(
3525 3514 &string_tmp, &template[i]);
3526 3515 if (rv != CKR_OK)
3527 3516 goto fail_cleanup;
3528 3517 break;
3529 3518 case CKA_SERIAL_NUMBER:
3530 3519 case CKA_AC_ISSUER:
3531 3520 case CKA_ATTR_TYPES:
3532 3521 rv = soft_add_extra_attr(&template[i],
3533 3522 new_object);
3534 3523 break;
3535 3524
3536 3525 case CKA_MODIFIABLE:
3537 3526 if ((*(CK_BBOOL *)template[i].pValue) ==
3538 3527 B_FALSE)
3539 3528 attr_mask |=
3540 3529 NOT_MODIFIABLE_BOOL_ON;
3541 3530 break;
3542 3531 case CKA_CERTIFICATE_TYPE:
3543 3532 break;
3544 3533 default:
3545 3534 rv = soft_parse_common_attrs(
3546 3535 &template[i], &object_type);
3547 3536 if (rv != CKR_OK)
3548 3537 goto fail_cleanup;
3549 3538 break;
3550 3539 }
3551 3540 break;
3552 3541 default:
3553 3542 rv = CKR_TEMPLATE_INCOMPLETE;
3554 3543 break;
3555 3544 }
3556 3545 }
3557 3546
3558 3547 if (rv == CKR_OK) {
3559 3548 new_object->object_class_u.certificate = cert;
3560 3549 new_object->class = CKO_CERTIFICATE;
3561 3550 new_object->object_type = object_type;
3562 3551 new_object->cert_type = certtype;
3563 3552 new_object->bool_attr_mask = attr_mask;
3564 3553 if (isLabel) {
3565 3554 rv = soft_add_extra_attr(&string_tmp, new_object);
3566 3555 if (rv != CKR_OK)
3567 3556 goto fail_cleanup;
3568 3557 string_attr_cleanup(&string_tmp);
3569 3558 }
3570 3559 }
3571 3560
3572 3561 fail_cleanup:
3573 3562 if (rv != CKR_OK) {
3574 3563 soft_cleanup_cert_object(new_object);
3575 3564 }
3576 3565 return (rv);
3577 3566 }
3578 3567
3579 3568
3580 3569 /*
3581 3570 * Validate the attribute types in the object's template. Then,
3582 3571 * call the appropriate build function according to the class of
3583 3572 * the object specified in the template.
3584 3573 *
3585 3574 * Note: The following classes of objects are supported:
3586 3575 * - CKO_PUBLIC_KEY
3587 3576 * - CKO_PRIVATE_KEY
3588 3577 * - CKO_SECRET_KEY
3589 3578 * - CKO_DOMAIN_PARAMETERS
3590 3579 * - CKO_CERTIFICATE
3591 3580 *
3592 3581 */
3593 3582 CK_RV
3594 3583 soft_build_object(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
3595 3584 soft_object_t *new_object)
3596 3585 {
3597 3586
3598 3587 CK_OBJECT_CLASS class = (CK_OBJECT_CLASS)~0UL;
3599 3588 CK_RV rv = CKR_OK;
3600 3589
3601 3590 if (template == NULL) {
3602 3591 return (CKR_ARGUMENTS_BAD);
3603 3592 }
3604 3593
3605 3594 /* Validate the attribute type in the template. */
3606 3595 rv = soft_validate_attr(template, ulAttrNum, &class);
3607 3596 if (rv != CKR_OK)
3608 3597 return (rv);
3609 3598 /*
3610 3599 * CKA_CLASS is a mandatory attribute for C_CreateObject
3611 3600 */
3612 3601 if (class == (CK_OBJECT_CLASS)~0UL)
3613 3602 return (CKR_TEMPLATE_INCOMPLETE);
3614 3603
3615 3604 /*
3616 3605 * Call the appropriate function based on the supported class
3617 3606 * of the object.
3618 3607 */
3619 3608 switch (class) {
3620 3609 case CKO_PUBLIC_KEY:
3621 3610 rv = soft_build_public_key_object(template, ulAttrNum,
3622 3611 new_object, SOFT_CREATE_OBJ, (CK_KEY_TYPE)~0UL);
3623 3612 break;
3624 3613
3625 3614 case CKO_PRIVATE_KEY:
3626 3615 rv = soft_build_private_key_object(template, ulAttrNum,
3627 3616 new_object, SOFT_CREATE_OBJ, (CK_KEY_TYPE)~0UL);
3628 3617 break;
3629 3618
3630 3619 case CKO_SECRET_KEY:
3631 3620 rv = soft_build_secret_key_object(template, ulAttrNum,
3632 3621 new_object, SOFT_CREATE_OBJ, 0, (CK_KEY_TYPE)~0UL);
3633 3622 break;
3634 3623
3635 3624 case CKO_DOMAIN_PARAMETERS:
3636 3625 rv = soft_build_domain_parameters_object(template, ulAttrNum,
3637 3626 new_object);
3638 3627 break;
3639 3628
3640 3629 case CKO_CERTIFICATE:
3641 3630 rv = soft_build_certificate_object(template, ulAttrNum,
3642 3631 new_object, (CK_CERTIFICATE_TYPE)~0UL);
3643 3632 break;
3644 3633
3645 3634 case CKO_DATA:
3646 3635 case CKO_HW_FEATURE:
3647 3636 case CKO_VENDOR_DEFINED:
3648 3637 default:
3649 3638 return (CKR_ATTRIBUTE_VALUE_INVALID);
3650 3639 }
3651 3640
3652 3641 return (rv);
3653 3642 }
3654 3643
3655 3644 /*
3656 3645 * Validate the attribute types in the object's template. Then,
3657 3646 * call the appropriate build function according to the class of
3658 3647 * the object specified in the template.
3659 3648 *
3660 3649 */
3661 3650 CK_RV
3662 3651 soft_build_key(CK_ATTRIBUTE_PTR template, CK_ULONG ulAttrNum,
3663 3652 soft_object_t *new_object, CK_OBJECT_CLASS class, CK_KEY_TYPE key_type,
3664 3653 CK_ULONG key_len, CK_ULONG mode)
3665 3654 {
3666 3655
3667 3656 CK_RV rv = CKR_OK;
3668 3657 CK_OBJECT_CLASS temp_class = (CK_OBJECT_CLASS)~0UL;
3669 3658
3670 3659 /* Validate the attribute type in the template. */
3671 3660 if ((template != NULL) && (ulAttrNum != 0)) {
3672 3661 rv = soft_validate_attr(template, ulAttrNum, &temp_class);
3673 3662 if (rv != CKR_OK)
3674 3663 return (rv);
3675 3664 }
3676 3665
3677 3666 /*
3678 3667 * If either the class from the parameter list ("class") or
3679 3668 * the class from the template ("temp_class") is not specified,
3680 3669 * try to use the other one.
3681 3670 */
3682 3671 if (temp_class == (CK_OBJECT_CLASS)~0UL) {
3683 3672 temp_class = class;
3684 3673 } else if (class == (CK_OBJECT_CLASS)~0UL) {
3685 3674 class = temp_class;
3686 3675 }
3687 3676
3688 3677 /* If object class is still not specified, template is incomplete. */
3689 3678 if (class == (CK_OBJECT_CLASS)~0UL)
3690 3679 return (CKR_TEMPLATE_INCOMPLETE);
3691 3680
3692 3681 /* Class should match if specified in both parameters and template. */
3693 3682 if (class != temp_class)
3694 3683 return (CKR_TEMPLATE_INCONSISTENT);
3695 3684
3696 3685 /*
3697 3686 * Call the appropriate function based on the supported class
3698 3687 * of the object.
3699 3688 */
3700 3689 switch (class) {
3701 3690 case CKO_PUBLIC_KEY:
3702 3691
3703 3692 /* Unwrapping public keys is not supported. */
3704 3693 if (mode == SOFT_UNWRAP_KEY) {
3705 3694 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3706 3695 break;
3707 3696 }
3708 3697
3709 3698 rv = soft_build_public_key_object(template, ulAttrNum,
3710 3699 new_object, mode, key_type);
3711 3700 break;
3712 3701
3713 3702 case CKO_PRIVATE_KEY:
3714 3703
3715 3704 rv = soft_build_private_key_object(template, ulAttrNum,
3716 3705 new_object, mode, key_type);
3717 3706 break;
3718 3707
3719 3708 case CKO_SECRET_KEY:
3720 3709
3721 3710 rv = soft_build_secret_key_object(template, ulAttrNum,
3722 3711 new_object, mode, key_len, key_type);
3723 3712 break;
3724 3713
3725 3714 case CKO_DOMAIN_PARAMETERS:
3726 3715
3727 3716 /* Unwrapping domain parameters is not supported. */
3728 3717 if (mode == SOFT_UNWRAP_KEY) {
3729 3718 rv = CKR_ATTRIBUTE_VALUE_INVALID;
3730 3719 break;
3731 3720 }
3732 3721
3733 3722 rv = soft_build_domain_parameters_object(template, ulAttrNum,
3734 3723 new_object);
3735 3724 break;
3736 3725
3737 3726 case CKO_DATA:
3738 3727 case CKO_CERTIFICATE:
3739 3728 case CKO_HW_FEATURE:
3740 3729 case CKO_VENDOR_DEFINED:
3741 3730 default:
3742 3731 return (CKR_ATTRIBUTE_VALUE_INVALID);
3743 3732 }
3744 3733
3745 3734 return (rv);
3746 3735 }
3747 3736
3748 3737
3749 3738 /*
3750 3739 * Get the value of a requested attribute that is common to all supported
3751 3740 * classes (i.e. public key, private key, secret key, domain parameters,
3752 3741 * and certificate classes).
3753 3742 */
3754 3743 CK_RV
3755 3744 soft_get_common_attrs(soft_object_t *object_p, CK_ATTRIBUTE_PTR template,
3756 3745 uchar_t object_type)
3757 3746 {
3758 3747
3759 3748 CK_RV rv = CKR_OK;
3760 3749
3761 3750 switch (template->type) {
3762 3751
3763 3752 case CKA_CLASS:
3764 3753 return (get_ulong_attr_from_object(object_p->class,
3765 3754 template));
3766 3755
3767 3756 /* default boolean attributes */
3768 3757 case CKA_TOKEN:
3769 3758 template->ulValueLen = sizeof (CK_BBOOL);
3770 3759 if (template->pValue == NULL) {
3771 3760 return (CKR_OK);
3772 3761 }
3773 3762 if (object_type & TOKEN_OBJECT)
3774 3763 *((CK_BBOOL *)template->pValue) = B_TRUE;
3775 3764 else
3776 3765 *((CK_BBOOL *)template->pValue) = B_FALSE;
3777 3766 break;
3778 3767
3779 3768 case CKA_PRIVATE:
3780 3769
3781 3770 template->ulValueLen = sizeof (CK_BBOOL);
3782 3771 if (template->pValue == NULL) {
3783 3772 return (CKR_OK);
3784 3773 }
3785 3774 if (object_type & PRIVATE_OBJECT)
3786 3775 *((CK_BBOOL *)template->pValue) = B_TRUE;
3787 3776 else
3788 3777 *((CK_BBOOL *)template->pValue) = B_FALSE;
3789 3778 break;
3790 3779
3791 3780 case CKA_MODIFIABLE:
3792 3781 template->ulValueLen = sizeof (CK_BBOOL);
3793 3782 if (template->pValue == NULL) {
3794 3783 return (CKR_OK);
3795 3784 }
3796 3785 if ((object_p->bool_attr_mask) & NOT_MODIFIABLE_BOOL_ON)
3797 3786 *((CK_BBOOL *)template->pValue) = B_FALSE;
3798 3787 else
3799 3788 *((CK_BBOOL *)template->pValue) = B_TRUE;
3800 3789 break;
3801 3790
3802 3791 case CKA_LABEL:
3803 3792 return (get_extra_attr_from_object(object_p,
3804 3793 template));
3805 3794
3806 3795 default:
3807 3796 /*
3808 3797 * The specified attribute for the object is invalid.
3809 3798 * (the object does not possess such an attribute.)
3810 3799 */
3811 3800 template->ulValueLen = (CK_ULONG)-1;
3812 3801 return (CKR_ATTRIBUTE_TYPE_INVALID);
3813 3802 }
3814 3803
3815 3804 return (rv);
3816 3805 }
3817 3806
3818 3807 /*
3819 3808 * Get the value of a requested attribute that is common to all key objects
3820 3809 * (i.e. public key, private key and secret key).
3821 3810 */
3822 3811 CK_RV
3823 3812 soft_get_common_key_attrs(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
3824 3813 {
3825 3814
3826 3815 switch (template->type) {
3827 3816
3828 3817 case CKA_KEY_TYPE:
3829 3818 return (get_ulong_attr_from_object(object_p->key_type,
3830 3819 template));
3831 3820
3832 3821 case CKA_ID:
3833 3822 case CKA_START_DATE:
3834 3823 case CKA_END_DATE:
3835 3824 /*
3836 3825 * The above extra attributes have byte array type.
3837 3826 */
3838 3827 return (get_extra_attr_from_object(object_p,
3839 3828 template));
3840 3829
3841 3830 /* Key related boolean attributes */
3842 3831 case CKA_LOCAL:
3843 3832 return (get_bool_attr_from_object(object_p,
3844 3833 LOCAL_BOOL_ON, template));
3845 3834
3846 3835 case CKA_DERIVE:
3847 3836 return (get_bool_attr_from_object(object_p,
3848 3837 DERIVE_BOOL_ON, template));
3849 3838
3850 3839 case CKA_KEY_GEN_MECHANISM:
3851 3840 return (get_ulong_attr_from_object(object_p->mechanism,
3852 3841 template));
3853 3842
3854 3843 default:
3855 3844 return (CKR_ATTRIBUTE_TYPE_INVALID);
3856 3845 }
3857 3846 }
3858 3847
3859 3848 /*
3860 3849 * Get the value of a requested attribute of a Public Key Object.
3861 3850 *
3862 3851 * Rule: All the attributes in the public key object can be revealed.
3863 3852 */
3864 3853 CK_RV
3865 3854 soft_get_public_key_attribute(soft_object_t *object_p,
3866 3855 CK_ATTRIBUTE_PTR template)
3867 3856 {
3868 3857
3869 3858 CK_RV rv = CKR_OK;
3870 3859 CK_KEY_TYPE keytype = object_p->key_type;
3871 3860
3872 3861 switch (template->type) {
3873 3862
3874 3863 case CKA_SUBJECT:
3875 3864 case CKA_EC_PARAMS:
3876 3865 /*
3877 3866 * The above extra attributes have byte array type.
3878 3867 */
3879 3868 return (get_extra_attr_from_object(object_p,
3880 3869 template));
3881 3870
3882 3871 /* Key related boolean attributes */
3883 3872 case CKA_ENCRYPT:
3884 3873 return (get_bool_attr_from_object(object_p,
3885 3874 ENCRYPT_BOOL_ON, template));
3886 3875
3887 3876 case CKA_VERIFY:
3888 3877 return (get_bool_attr_from_object(object_p,
3889 3878 VERIFY_BOOL_ON, template));
3890 3879
3891 3880 case CKA_VERIFY_RECOVER:
3892 3881 return (get_bool_attr_from_object(object_p,
3893 3882 VERIFY_RECOVER_BOOL_ON, template));
3894 3883
3895 3884 case CKA_WRAP:
3896 3885 return (get_bool_attr_from_object(object_p,
3897 3886 WRAP_BOOL_ON, template));
3898 3887
3899 3888 case CKA_TRUSTED:
3900 3889 return (get_bool_attr_from_object(object_p,
3901 3890 TRUSTED_BOOL_ON, template));
3902 3891
3903 3892 case CKA_MODULUS:
3904 3893 /*
3905 3894 * This attribute is valid only for RSA public key
3906 3895 * object.
3907 3896 */
3908 3897 if (keytype == CKK_RSA) {
3909 3898 return (get_bigint_attr_from_object(
3910 3899 OBJ_PUB_RSA_MOD(object_p), template));
3911 3900 } else {
3912 3901 template->ulValueLen = (CK_ULONG)-1;
3913 3902 return (CKR_ATTRIBUTE_TYPE_INVALID);
3914 3903 }
3915 3904
3916 3905 case CKA_PUBLIC_EXPONENT:
3917 3906 if (keytype == CKK_RSA) {
3918 3907 return (get_bigint_attr_from_object(
3919 3908 OBJ_PUB_RSA_PUBEXPO(object_p), template));
3920 3909 } else {
3921 3910 template->ulValueLen = (CK_ULONG)-1;
3922 3911 return (CKR_ATTRIBUTE_TYPE_INVALID);
3923 3912 }
3924 3913
3925 3914 case CKA_MODULUS_BITS:
3926 3915 if (keytype == CKK_RSA) {
3927 3916 return (get_ulong_attr_from_object(
3928 3917 OBJ_PUB_RSA_MOD_BITS(object_p), template));
3929 3918 } else {
3930 3919 template->ulValueLen = (CK_ULONG)-1;
3931 3920 return (CKR_ATTRIBUTE_TYPE_INVALID);
3932 3921 }
3933 3922
3934 3923 case CKA_PRIME:
3935 3924 switch (keytype) {
3936 3925 case CKK_DSA:
3937 3926 return (get_bigint_attr_from_object(
3938 3927 OBJ_PUB_DSA_PRIME(object_p), template));
3939 3928
3940 3929 case CKK_DH:
3941 3930 return (get_bigint_attr_from_object(
3942 3931 OBJ_PUB_DH_PRIME(object_p), template));
3943 3932
3944 3933 case CKK_X9_42_DH:
3945 3934 return (get_bigint_attr_from_object(
3946 3935 OBJ_PUB_DH942_PRIME(object_p), template));
3947 3936
3948 3937 default:
3949 3938 template->ulValueLen = (CK_ULONG)-1;
3950 3939 return (CKR_ATTRIBUTE_TYPE_INVALID);
3951 3940 }
3952 3941
3953 3942 case CKA_SUBPRIME:
3954 3943 switch (keytype) {
3955 3944 case CKK_DSA:
3956 3945 return (get_bigint_attr_from_object(
3957 3946 OBJ_PUB_DSA_SUBPRIME(object_p), template));
3958 3947
3959 3948 case CKK_X9_42_DH:
3960 3949 return (get_bigint_attr_from_object(
3961 3950 OBJ_PUB_DH942_SUBPRIME(object_p), template));
3962 3951
3963 3952 default:
3964 3953 template->ulValueLen = (CK_ULONG)-1;
3965 3954 return (CKR_ATTRIBUTE_TYPE_INVALID);
3966 3955 }
3967 3956
3968 3957 case CKA_BASE:
3969 3958 switch (keytype) {
3970 3959 case CKK_DSA:
3971 3960 return (get_bigint_attr_from_object(
3972 3961 OBJ_PUB_DSA_BASE(object_p), template));
3973 3962
3974 3963 case CKK_DH:
3975 3964 return (get_bigint_attr_from_object(
3976 3965 OBJ_PUB_DH_BASE(object_p), template));
3977 3966
3978 3967 case CKK_X9_42_DH:
3979 3968 return (get_bigint_attr_from_object(
3980 3969 OBJ_PUB_DH942_BASE(object_p), template));
3981 3970
3982 3971 default:
3983 3972 template->ulValueLen = (CK_ULONG)-1;
3984 3973 return (CKR_ATTRIBUTE_TYPE_INVALID);
3985 3974 }
3986 3975
3987 3976 case CKA_EC_POINT:
3988 3977 return (get_bigint_attr_from_object(
3989 3978 OBJ_PUB_EC_POINT(object_p), template));
3990 3979
3991 3980 case CKA_VALUE:
3992 3981 switch (keytype) {
3993 3982 case CKK_DSA:
3994 3983 return (get_bigint_attr_from_object(
3995 3984 OBJ_PUB_DSA_VALUE(object_p), template));
3996 3985
3997 3986 case CKK_DH:
3998 3987 return (get_bigint_attr_from_object(
3999 3988 OBJ_PUB_DH_VALUE(object_p), template));
4000 3989
4001 3990 case CKK_X9_42_DH:
4002 3991 return (get_bigint_attr_from_object(
4003 3992 OBJ_PUB_DH942_VALUE(object_p), template));
4004 3993
4005 3994 default:
4006 3995 template->ulValueLen = (CK_ULONG)-1;
4007 3996 return (CKR_ATTRIBUTE_TYPE_INVALID);
4008 3997 }
4009 3998
4010 3999 default:
4011 4000 /*
4012 4001 * First, get the value of the request attribute defined
4013 4002 * in the list of common key attributes. If the request
4014 4003 * attribute is not found in that list, then get the
4015 4004 * attribute from the list of common attributes.
4016 4005 */
4017 4006 rv = soft_get_common_key_attrs(object_p, template);
4018 4007 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
4019 4008 rv = soft_get_common_attrs(object_p, template,
4020 4009 object_p->object_type);
4021 4010 }
4022 4011 break;
4023 4012 }
4024 4013
4025 4014 return (rv);
4026 4015 }
4027 4016
4028 4017
4029 4018 /*
4030 4019 * Get the value of a requested attribute of a Private Key Object.
4031 4020 *
4032 4021 * Rule: All the attributes in the private key object can be revealed
4033 4022 * except those marked with footnote number "7" when the object
4034 4023 * has its CKA_SENSITIVE attribute set to TRUE or its
4035 4024 * CKA_EXTRACTABLE attribute set to FALSE (p.88 in PKCS11 spec.).
4036 4025 */
4037 4026 CK_RV
4038 4027 soft_get_private_key_attribute(soft_object_t *object_p,
4039 4028 CK_ATTRIBUTE_PTR template)
4040 4029 {
4041 4030
4042 4031 CK_RV rv = CKR_OK;
4043 4032 CK_KEY_TYPE keytype = object_p->key_type;
4044 4033
4045 4034
4046 4035 /*
4047 4036 * If the following specified attributes for the private key
4048 4037 * object cannot be revealed because the object is sensitive
4049 4038 * or unextractable, then the ulValueLen is set to -1.
4050 4039 */
4051 4040 if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) ||
4052 4041 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
4053 4042
4054 4043 switch (template->type) {
4055 4044 case CKA_PRIVATE_EXPONENT:
4056 4045 case CKA_PRIME_1:
4057 4046 case CKA_PRIME_2:
4058 4047 case CKA_EXPONENT_1:
4059 4048 case CKA_EXPONENT_2:
4060 4049 case CKA_COEFFICIENT:
4061 4050 case CKA_VALUE:
4062 4051 template->ulValueLen = (CK_ULONG)-1;
4063 4052 return (CKR_ATTRIBUTE_SENSITIVE);
4064 4053 }
4065 4054 }
4066 4055
4067 4056 switch (template->type) {
4068 4057
4069 4058 case CKA_SUBJECT:
4070 4059 case CKA_EC_PARAMS:
4071 4060 /*
4072 4061 * The above extra attributes have byte array type.
4073 4062 */
4074 4063 return (get_extra_attr_from_object(object_p,
4075 4064 template));
4076 4065
4077 4066 /* Key related boolean attributes */
4078 4067 case CKA_SENSITIVE:
4079 4068 return (get_bool_attr_from_object(object_p,
4080 4069 SENSITIVE_BOOL_ON, template));
4081 4070
4082 4071 case CKA_SECONDARY_AUTH:
4083 4072 return (get_bool_attr_from_object(object_p,
4084 4073 SECONDARY_AUTH_BOOL_ON, template));
4085 4074
4086 4075 case CKA_DECRYPT:
4087 4076 return (get_bool_attr_from_object(object_p,
4088 4077 DECRYPT_BOOL_ON, template));
4089 4078
4090 4079 case CKA_SIGN:
4091 4080 return (get_bool_attr_from_object(object_p,
4092 4081 SIGN_BOOL_ON, template));
4093 4082
4094 4083 case CKA_SIGN_RECOVER:
4095 4084 return (get_bool_attr_from_object(object_p,
4096 4085 SIGN_RECOVER_BOOL_ON, template));
4097 4086
4098 4087 case CKA_UNWRAP:
4099 4088 return (get_bool_attr_from_object(object_p,
4100 4089 UNWRAP_BOOL_ON, template));
4101 4090
4102 4091 case CKA_EXTRACTABLE:
4103 4092 return (get_bool_attr_from_object(object_p,
4104 4093 EXTRACTABLE_BOOL_ON, template));
4105 4094
4106 4095 case CKA_ALWAYS_SENSITIVE:
4107 4096 return (get_bool_attr_from_object(object_p,
4108 4097 ALWAYS_SENSITIVE_BOOL_ON, template));
4109 4098
4110 4099 case CKA_NEVER_EXTRACTABLE:
4111 4100 return (get_bool_attr_from_object(object_p,
4112 4101 NEVER_EXTRACTABLE_BOOL_ON, template));
4113 4102
4114 4103 case CKA_MODULUS:
4115 4104 if (keytype == CKK_RSA) {
4116 4105 return (get_bigint_attr_from_object(
4117 4106 OBJ_PRI_RSA_MOD(object_p), template));
4118 4107 } else {
4119 4108 template->ulValueLen = (CK_ULONG)-1;
4120 4109 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4121 4110 break;
4122 4111 }
4123 4112
4124 4113 case CKA_PUBLIC_EXPONENT:
4125 4114 if (keytype == CKK_RSA) {
4126 4115 return (get_bigint_attr_from_object(
4127 4116 OBJ_PRI_RSA_PUBEXPO(object_p), template));
4128 4117 } else {
4129 4118 template->ulValueLen = (CK_ULONG)-1;
4130 4119 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4131 4120 break;
4132 4121 }
4133 4122
4134 4123 case CKA_PRIVATE_EXPONENT:
4135 4124 if (keytype == CKK_RSA) {
4136 4125 return (get_bigint_attr_from_object(
4137 4126 OBJ_PRI_RSA_PRIEXPO(object_p), template));
4138 4127 } else {
4139 4128 template->ulValueLen = (CK_ULONG)-1;
4140 4129 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4141 4130 break;
4142 4131 }
4143 4132
4144 4133 case CKA_PRIME_1:
4145 4134 if (keytype == CKK_RSA) {
4146 4135 return (get_bigint_attr_from_object(
4147 4136 OBJ_PRI_RSA_PRIME1(object_p), template));
4148 4137 } else {
4149 4138 template->ulValueLen = (CK_ULONG)-1;
4150 4139 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4151 4140 break;
4152 4141 }
4153 4142
4154 4143 case CKA_PRIME_2:
4155 4144 if (keytype == CKK_RSA) {
4156 4145 return (get_bigint_attr_from_object(
4157 4146 OBJ_PRI_RSA_PRIME2(object_p), template));
4158 4147 } else {
4159 4148 template->ulValueLen = (CK_ULONG)-1;
4160 4149 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4161 4150 break;
4162 4151 }
4163 4152
4164 4153 case CKA_EXPONENT_1:
4165 4154 if (keytype == CKK_RSA) {
4166 4155 return (get_bigint_attr_from_object(
4167 4156 OBJ_PRI_RSA_EXPO1(object_p), template));
4168 4157 } else {
4169 4158 template->ulValueLen = (CK_ULONG)-1;
4170 4159 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4171 4160 break;
4172 4161 }
4173 4162
4174 4163 case CKA_EXPONENT_2:
4175 4164 if (keytype == CKK_RSA) {
4176 4165 return (get_bigint_attr_from_object(
4177 4166 OBJ_PRI_RSA_EXPO2(object_p), template));
4178 4167 } else {
4179 4168 template->ulValueLen = (CK_ULONG)-1;
4180 4169 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4181 4170 break;
4182 4171 }
4183 4172
4184 4173 case CKA_COEFFICIENT:
4185 4174 if (keytype == CKK_RSA) {
4186 4175 return (get_bigint_attr_from_object(
4187 4176 OBJ_PRI_RSA_COEF(object_p), template));
4188 4177 } else {
4189 4178 template->ulValueLen = (CK_ULONG)-1;
4190 4179 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4191 4180 break;
4192 4181 }
4193 4182
4194 4183 case CKA_VALUE_BITS:
4195 4184 if (keytype == CKK_DH) {
4196 4185 return (get_ulong_attr_from_object(
4197 4186 OBJ_PRI_DH_VAL_BITS(object_p), template));
4198 4187 } else {
4199 4188 template->ulValueLen = (CK_ULONG)-1;
4200 4189 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4201 4190 break;
4202 4191 }
4203 4192
4204 4193 case CKA_PRIME:
4205 4194 switch (keytype) {
4206 4195 case CKK_DSA:
4207 4196 return (get_bigint_attr_from_object(
4208 4197 OBJ_PRI_DSA_PRIME(object_p), template));
4209 4198
4210 4199 case CKK_DH:
4211 4200 return (get_bigint_attr_from_object(
4212 4201 OBJ_PRI_DH_PRIME(object_p), template));
4213 4202
4214 4203 case CKK_X9_42_DH:
4215 4204 return (get_bigint_attr_from_object(
4216 4205 OBJ_PRI_DH942_PRIME(object_p), template));
4217 4206
4218 4207 default:
4219 4208 template->ulValueLen = (CK_ULONG)-1;
4220 4209 return (CKR_ATTRIBUTE_TYPE_INVALID);
4221 4210 }
4222 4211
4223 4212 case CKA_SUBPRIME:
4224 4213 switch (keytype) {
4225 4214 case CKK_DSA:
4226 4215 return (get_bigint_attr_from_object(
4227 4216 OBJ_PRI_DSA_SUBPRIME(object_p), template));
4228 4217
4229 4218 case CKK_X9_42_DH:
4230 4219 return (get_bigint_attr_from_object(
4231 4220 OBJ_PRI_DH942_SUBPRIME(object_p), template));
4232 4221
4233 4222 default:
4234 4223 template->ulValueLen = (CK_ULONG)-1;
4235 4224 return (CKR_ATTRIBUTE_TYPE_INVALID);
4236 4225 }
4237 4226
4238 4227 case CKA_BASE:
4239 4228 switch (keytype) {
4240 4229 case CKK_DSA:
4241 4230 return (get_bigint_attr_from_object(
4242 4231 OBJ_PRI_DSA_BASE(object_p), template));
4243 4232
4244 4233 case CKK_DH:
4245 4234 return (get_bigint_attr_from_object(
4246 4235 OBJ_PRI_DH_BASE(object_p), template));
4247 4236
4248 4237 case CKK_X9_42_DH:
4249 4238 return (get_bigint_attr_from_object(
4250 4239 OBJ_PRI_DH942_BASE(object_p), template));
4251 4240
4252 4241 default:
4253 4242 template->ulValueLen = (CK_ULONG)-1;
4254 4243 return (CKR_ATTRIBUTE_TYPE_INVALID);
4255 4244 }
4256 4245
4257 4246 case CKA_VALUE:
4258 4247 switch (keytype) {
4259 4248 case CKK_DSA:
4260 4249 return (get_bigint_attr_from_object(
4261 4250 OBJ_PRI_DSA_VALUE(object_p), template));
4262 4251
4263 4252 case CKK_DH:
4264 4253 return (get_bigint_attr_from_object(
4265 4254 OBJ_PRI_DH_VALUE(object_p), template));
4266 4255
4267 4256 case CKK_X9_42_DH:
4268 4257 return (get_bigint_attr_from_object(
4269 4258 OBJ_PRI_DH942_VALUE(object_p), template));
4270 4259
4271 4260 case CKK_EC:
4272 4261 return (get_bigint_attr_from_object(
4273 4262 OBJ_PRI_EC_VALUE(object_p), template));
4274 4263
4275 4264 default:
4276 4265 template->ulValueLen = (CK_ULONG)-1;
4277 4266 return (CKR_ATTRIBUTE_TYPE_INVALID);
4278 4267 }
4279 4268
4280 4269 default:
4281 4270 /*
4282 4271 * First, get the value of the request attribute defined
4283 4272 * in the list of common key attributes. If the request
4284 4273 * attribute is not found in that list, then get the
4285 4274 * attribute from the list of common attributes.
4286 4275 */
4287 4276 rv = soft_get_common_key_attrs(object_p, template);
4288 4277 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
4289 4278 rv = soft_get_common_attrs(object_p, template,
4290 4279 object_p->object_type);
4291 4280 }
4292 4281 break;
4293 4282 }
4294 4283
4295 4284 return (rv);
4296 4285 }
4297 4286
4298 4287
4299 4288 /*
4300 4289 * Get the value of a requested attribute of a Secret Key Object.
4301 4290 *
4302 4291 * Rule: All the attributes in the secret key object can be revealed
4303 4292 * except those marked with footnote number "7" when the object
4304 4293 * has its CKA_SENSITIVE attribute set to TRUE or its
4305 4294 * CKA_EXTRACTABLE attribute set to FALSE (p.88 in PKCS11 spec.).
4306 4295 */
4307 4296 CK_RV
4308 4297 soft_get_secret_key_attribute(soft_object_t *object_p,
4309 4298 CK_ATTRIBUTE_PTR template)
4310 4299 {
4311 4300
4312 4301 CK_RV rv = CKR_OK;
4313 4302 CK_KEY_TYPE keytype = object_p->key_type;
4314 4303
4315 4304 switch (template->type) {
4316 4305
4317 4306 /* Key related boolean attributes */
4318 4307 case CKA_SENSITIVE:
4319 4308 return (get_bool_attr_from_object(object_p,
4320 4309 SENSITIVE_BOOL_ON, template));
4321 4310
4322 4311 case CKA_ENCRYPT:
4323 4312 return (get_bool_attr_from_object(object_p,
4324 4313 ENCRYPT_BOOL_ON, template));
4325 4314
4326 4315 case CKA_DECRYPT:
4327 4316 return (get_bool_attr_from_object(object_p,
4328 4317 DECRYPT_BOOL_ON, template));
4329 4318
4330 4319 case CKA_SIGN:
4331 4320 return (get_bool_attr_from_object(object_p,
4332 4321 SIGN_BOOL_ON, template));
4333 4322
4334 4323 case CKA_VERIFY:
4335 4324 return (get_bool_attr_from_object(object_p,
4336 4325 VERIFY_BOOL_ON, template));
4337 4326
4338 4327 case CKA_WRAP:
4339 4328 return (get_bool_attr_from_object(object_p,
4340 4329 WRAP_BOOL_ON, template));
4341 4330
4342 4331 case CKA_UNWRAP:
4343 4332 return (get_bool_attr_from_object(object_p,
4344 4333 UNWRAP_BOOL_ON, template));
4345 4334
4346 4335 case CKA_EXTRACTABLE:
4347 4336 return (get_bool_attr_from_object(object_p,
4348 4337 EXTRACTABLE_BOOL_ON, template));
4349 4338
4350 4339 case CKA_ALWAYS_SENSITIVE:
4351 4340 return (get_bool_attr_from_object(object_p,
4352 4341 ALWAYS_SENSITIVE_BOOL_ON, template));
4353 4342
4354 4343 case CKA_NEVER_EXTRACTABLE:
4355 4344 return (get_bool_attr_from_object(object_p,
4356 4345 NEVER_EXTRACTABLE_BOOL_ON, template));
4357 4346
4358 4347 case CKA_VALUE:
4359 4348 case CKA_VALUE_LEN:
4360 4349 /*
4361 4350 * If the specified attribute for the secret key object
4362 4351 * cannot be revealed because the object is sensitive
4363 4352 * or unextractable, then the ulValueLen is set to -1.
4364 4353 */
4365 4354 if ((object_p->bool_attr_mask & SENSITIVE_BOOL_ON) ||
4366 4355 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
4367 4356 template->ulValueLen = (CK_ULONG)-1;
4368 4357 return (CKR_ATTRIBUTE_SENSITIVE);
4369 4358 }
4370 4359
4371 4360 switch (keytype) {
4372 4361 case CKK_RC4:
4373 4362 case CKK_GENERIC_SECRET:
4374 4363 case CKK_RC5:
4375 4364 case CKK_DES:
4376 4365 case CKK_DES2:
4377 4366 case CKK_DES3:
4378 4367 case CKK_CDMF:
4379 4368 case CKK_AES:
4380 4369 case CKK_BLOWFISH:
4381 4370 if (template->type == CKA_VALUE_LEN) {
4382 4371 return (get_ulong_attr_from_object(
4383 4372 OBJ_SEC_VALUE_LEN(object_p),
4384 4373 template));
4385 4374 } else {
4386 4375 return (get_bigint_attr_from_object(
4387 4376 (biginteger_t *)OBJ_SEC(object_p),
4388 4377 template));
4389 4378 }
4390 4379 default:
4391 4380 template->ulValueLen = (CK_ULONG)-1;
4392 4381 rv = CKR_ATTRIBUTE_TYPE_INVALID;
4393 4382 break;
4394 4383 }
4395 4384 break;
4396 4385
4397 4386 default:
4398 4387 /*
4399 4388 * First, get the value of the request attribute defined
4400 4389 * in the list of common key attributes. If the request
4401 4390 * attribute is not found in that list, then get the
4402 4391 * attribute from the list of common attributes.
4403 4392 */
4404 4393 rv = soft_get_common_key_attrs(object_p, template);
4405 4394 if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
4406 4395 rv = soft_get_common_attrs(object_p, template,
4407 4396 object_p->object_type);
4408 4397 }
4409 4398 break;
4410 4399 }
4411 4400
4412 4401 return (rv);
4413 4402 }
4414 4403
4415 4404
4416 4405 /*
4417 4406 * Get the value of a requested attribute of a Domain Parameters Object.
4418 4407 *
4419 4408 * Rule: All the attributes in the domain parameters object can be revealed.
4420 4409 */
4421 4410 CK_RV
4422 4411 soft_get_domain_parameters_attribute(soft_object_t *object_p,
4423 4412 CK_ATTRIBUTE_PTR template)
4424 4413 {
4425 4414
4426 4415 CK_RV rv = CKR_OK;
4427 4416 CK_KEY_TYPE keytype = object_p->key_type;
4428 4417
4429 4418 switch (template->type) {
4430 4419
4431 4420 case CKA_KEY_TYPE:
4432 4421 return (get_ulong_attr_from_object(keytype,
4433 4422 template));
4434 4423
4435 4424 case CKA_LOCAL:
4436 4425 return (get_bool_attr_from_object(object_p,
4437 4426 LOCAL_BOOL_ON, template));
4438 4427
4439 4428 case CKA_PRIME:
4440 4429 switch (keytype) {
4441 4430 case CKK_DSA:
4442 4431 return (get_bigint_attr_from_object(
4443 4432 OBJ_DOM_DSA_PRIME(object_p), template));
4444 4433
4445 4434 case CKK_DH:
4446 4435 return (get_bigint_attr_from_object(
4447 4436 OBJ_DOM_DH_PRIME(object_p), template));
4448 4437
4449 4438 case CKK_X9_42_DH:
4450 4439 return (get_bigint_attr_from_object(
4451 4440 OBJ_DOM_DH942_PRIME(object_p), template));
4452 4441
4453 4442 default:
4454 4443 template->ulValueLen = (CK_ULONG)-1;
4455 4444 return (CKR_ATTRIBUTE_TYPE_INVALID);
4456 4445 }
4457 4446
4458 4447 case CKA_SUBPRIME:
4459 4448 switch (keytype) {
4460 4449 case CKK_DSA:
4461 4450 return (get_bigint_attr_from_object(
4462 4451 OBJ_DOM_DSA_SUBPRIME(object_p), template));
4463 4452
4464 4453 case CKK_X9_42_DH:
4465 4454 return (get_bigint_attr_from_object(
4466 4455 OBJ_DOM_DH942_SUBPRIME(object_p), template));
4467 4456
4468 4457 default:
4469 4458 template->ulValueLen = (CK_ULONG)-1;
4470 4459 return (CKR_ATTRIBUTE_TYPE_INVALID);
4471 4460 }
4472 4461
4473 4462 case CKA_BASE:
4474 4463 switch (keytype) {
4475 4464 case CKK_DSA:
4476 4465 return (get_bigint_attr_from_object(
4477 4466 OBJ_DOM_DSA_BASE(object_p), template));
4478 4467
4479 4468 case CKK_DH:
4480 4469 return (get_bigint_attr_from_object(
4481 4470 OBJ_DOM_DH_BASE(object_p), template));
4482 4471
4483 4472 case CKK_X9_42_DH:
4484 4473 return (get_bigint_attr_from_object(
4485 4474 OBJ_DOM_DH942_BASE(object_p), template));
4486 4475
4487 4476 default:
4488 4477 template->ulValueLen = (CK_ULONG)-1;
4489 4478 return (CKR_ATTRIBUTE_TYPE_INVALID);
4490 4479 }
4491 4480
4492 4481 case CKA_PRIME_BITS:
4493 4482 switch (keytype) {
4494 4483 case CKK_DSA:
4495 4484 return (get_ulong_attr_from_object(
4496 4485 OBJ_DOM_DSA_PRIME_BITS(object_p), template));
4497 4486
4498 4487 case CKK_DH:
4499 4488 return (get_ulong_attr_from_object(
4500 4489 OBJ_DOM_DH_PRIME_BITS(object_p), template));
4501 4490
4502 4491 case CKK_X9_42_DH:
4503 4492 return (get_ulong_attr_from_object(
4504 4493 OBJ_DOM_DH942_PRIME_BITS(object_p), template));
4505 4494
4506 4495 default:
4507 4496 template->ulValueLen = (CK_ULONG)-1;
4508 4497 return (CKR_ATTRIBUTE_TYPE_INVALID);
4509 4498 }
4510 4499
4511 4500 case CKA_SUB_PRIME_BITS:
4512 4501 switch (keytype) {
4513 4502 case CKK_X9_42_DH:
4514 4503 return (get_ulong_attr_from_object(
4515 4504 OBJ_DOM_DH942_SUBPRIME_BITS(object_p), template));
4516 4505
4517 4506 default:
4518 4507 template->ulValueLen = (CK_ULONG)-1;
4519 4508 return (CKR_ATTRIBUTE_TYPE_INVALID);
4520 4509 }
4521 4510
4522 4511 default:
4523 4512 /*
4524 4513 * Get the value of a common attribute.
4525 4514 */
4526 4515 rv = soft_get_common_attrs(object_p, template,
4527 4516 object_p->object_type);
4528 4517 break;
4529 4518 }
4530 4519
4531 4520 return (rv);
4532 4521 }
4533 4522
4534 4523 /*
4535 4524 * Get certificate attributes from an object.
4536 4525 * return CKR_ATTRIBUTE_TYPE_INVALID if the requested type
4537 4526 * does not exist in the certificate.
4538 4527 */
4539 4528 CK_RV
4540 4529 soft_get_certificate_attribute(soft_object_t *object_p,
4541 4530 CK_ATTRIBUTE_PTR template)
4542 4531 {
4543 4532 CK_CERTIFICATE_TYPE certtype = object_p->cert_type;
4544 4533 cert_attr_t src;
4545 4534
4546 4535 switch (template->type) {
4547 4536 case CKA_SUBJECT:
4548 4537 if (certtype == CKC_X_509) {
4549 4538 return (get_cert_attr_from_object(
4550 4539 X509_CERT_SUBJECT(object_p), template));
4551 4540 }
4552 4541 break;
4553 4542 case CKA_VALUE:
4554 4543 if (certtype == CKC_X_509) {
4555 4544 return (get_cert_attr_from_object(
4556 4545 X509_CERT_VALUE(object_p), template));
4557 4546 } else if (certtype == CKC_X_509_ATTR_CERT) {
4558 4547 return (get_cert_attr_from_object(
4559 4548 X509_ATTR_CERT_VALUE(object_p), template));
4560 4549 }
4561 4550 break;
4562 4551 case CKA_OWNER:
4563 4552 if (certtype == CKC_X_509_ATTR_CERT) {
4564 4553 return (get_cert_attr_from_object(
4565 4554 X509_ATTR_CERT_OWNER(object_p), template));
4566 4555 }
4567 4556 break;
4568 4557 case CKA_CERTIFICATE_TYPE:
4569 4558 src.value = (CK_BYTE *)&certtype;
4570 4559 src.length = sizeof (certtype);
4571 4560 return (get_cert_attr_from_object(&src, template));
4572 4561 case CKA_TRUSTED:
4573 4562 return (get_bool_attr_from_object(object_p,
4574 4563 TRUSTED_BOOL_ON, template));
4575 4564 case CKA_ID:
4576 4565 case CKA_ISSUER:
4577 4566 case CKA_SERIAL_NUMBER:
4578 4567 case CKA_AC_ISSUER:
4579 4568 case CKA_ATTR_TYPES:
4580 4569 return (get_extra_attr_from_object(object_p,
4581 4570 template));
4582 4571 default:
4583 4572 return (soft_get_common_attrs(object_p, template,
4584 4573 object_p->object_type));
4585 4574 }
4586 4575
4587 4576 /*
4588 4577 * If we got this far, then the combination of certificate type
4589 4578 * and requested attribute is invalid.
4590 4579 */
4591 4580 return (CKR_ATTRIBUTE_TYPE_INVALID);
4592 4581 }
4593 4582
4594 4583 CK_RV
4595 4584 soft_set_certificate_attribute(soft_object_t *object_p,
4596 4585 CK_ATTRIBUTE_PTR template, boolean_t copy)
4597 4586 {
4598 4587 CK_CERTIFICATE_TYPE certtype = object_p->cert_type;
4599 4588
4600 4589 switch (template->type) {
4601 4590 case CKA_SUBJECT:
4602 4591 if (certtype == CKC_X_509) {
4603 4592 /* SUBJECT attr cannot be modified. */
4604 4593 return (CKR_ATTRIBUTE_READ_ONLY);
4605 4594 }
4606 4595 break;
4607 4596 case CKA_OWNER:
4608 4597 if (certtype == CKC_X_509_ATTR_CERT) {
4609 4598 /* OWNER attr cannot be modified. */
4610 4599 return (CKR_ATTRIBUTE_READ_ONLY);
4611 4600 }
4612 4601 break;
4613 4602 case CKA_VALUE:
4614 4603 /* VALUE attr cannot be modified. */
4615 4604 return (CKR_ATTRIBUTE_READ_ONLY);
4616 4605 case CKA_ID:
4617 4606 case CKA_ISSUER:
4618 4607 if (certtype == CKC_X_509) {
4619 4608 return (set_extra_attr_to_object(object_p,
4620 4609 template->type, template));
4621 4610 }
4622 4611 break;
4623 4612 case CKA_AC_ISSUER:
4624 4613 case CKA_ATTR_TYPES:
4625 4614 if (certtype == CKC_X_509_ATTR_CERT) {
4626 4615 return (set_extra_attr_to_object(object_p,
4627 4616 template->type, template));
4628 4617 }
4629 4618 break;
4630 4619 case CKA_SERIAL_NUMBER:
4631 4620 case CKA_LABEL:
4632 4621 return (set_extra_attr_to_object(object_p,
4633 4622 template->type, template));
4634 4623 default:
4635 4624 return (soft_set_common_storage_attribute(
4636 4625 object_p, template, copy));
4637 4626 }
4638 4627
4639 4628 /*
4640 4629 * If we got this far, then the combination of certificate type
4641 4630 * and requested attribute is invalid.
4642 4631 */
4643 4632 return (CKR_ATTRIBUTE_TYPE_INVALID);
4644 4633 }
4645 4634
4646 4635 /*
4647 4636 * Call the appropriate get attribute function according to the class
4648 4637 * of object.
4649 4638 *
4650 4639 * The caller of this function holds the lock on the object.
4651 4640 */
4652 4641 CK_RV
4653 4642 soft_get_attribute(soft_object_t *object_p, CK_ATTRIBUTE_PTR template)
4654 4643 {
4655 4644
4656 4645 CK_RV rv = CKR_OK;
4657 4646 CK_OBJECT_CLASS class = object_p->class;
4658 4647
4659 4648 switch (class) {
4660 4649 case CKO_PUBLIC_KEY:
4661 4650 rv = soft_get_public_key_attribute(object_p, template);
4662 4651 break;
4663 4652
4664 4653 case CKO_PRIVATE_KEY:
4665 4654 rv = soft_get_private_key_attribute(object_p, template);
4666 4655 break;
4667 4656
4668 4657 case CKO_SECRET_KEY:
4669 4658 rv = soft_get_secret_key_attribute(object_p, template);
4670 4659 break;
4671 4660
4672 4661 case CKO_DOMAIN_PARAMETERS:
4673 4662 rv = soft_get_domain_parameters_attribute(object_p, template);
4674 4663 break;
4675 4664
4676 4665 case CKO_CERTIFICATE:
4677 4666 rv = soft_get_certificate_attribute(object_p, template);
4678 4667 break;
4679 4668
4680 4669 default:
4681 4670 /*
4682 4671 * If the specified attribute for the object is invalid
4683 4672 * (the object does not possess such as attribute), then
4684 4673 * the ulValueLen is modified to hold the value -1.
4685 4674 */
4686 4675 template->ulValueLen = (CK_ULONG)-1;
4687 4676 return (CKR_ATTRIBUTE_TYPE_INVALID);
4688 4677 }
4689 4678
4690 4679 return (rv);
4691 4680
4692 4681 }
4693 4682
4694 4683 CK_RV
4695 4684 soft_set_common_storage_attribute(soft_object_t *object_p,
4696 4685 CK_ATTRIBUTE_PTR template, boolean_t copy)
4697 4686 {
4698 4687
4699 4688 CK_RV rv = CKR_OK;
4700 4689
4701 4690 switch (template->type) {
4702 4691
4703 4692 case CKA_TOKEN:
4704 4693 if (copy) {
4705 4694 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
4706 4695 if (!soft_keystore_status(KEYSTORE_INITIALIZED))
4707 4696 return (CKR_DEVICE_REMOVED);
4708 4697 object_p->object_type |= TOKEN_OBJECT;
4709 4698 }
4710 4699 } else {
4711 4700 rv = CKR_ATTRIBUTE_READ_ONLY;
4712 4701 }
4713 4702
4714 4703 break;
4715 4704
4716 4705 case CKA_PRIVATE:
4717 4706 if (copy) {
4718 4707 if ((*(CK_BBOOL *)template->pValue) == B_TRUE) {
4719 4708 (void) pthread_mutex_lock(&soft_giant_mutex);
4720 4709 if (!soft_slot.authenticated) {
4721 4710 /*
4722 4711 * Check if this is the special case
4723 4712 * when the PIN is never initialized
4724 4713 * in the keystore. If true, we will
4725 4714 * let it pass here and let it fail
4726 4715 * with CKR_PIN_EXPIRED later on.
4727 4716 */
4728 4717 if (!soft_slot.userpin_change_needed) {
4729 4718 (void) pthread_mutex_unlock(
4730 4719 &soft_giant_mutex);
4731 4720 return (CKR_USER_NOT_LOGGED_IN);
4732 4721 }
4733 4722 }
4734 4723 (void) pthread_mutex_unlock(&soft_giant_mutex);
4735 4724 object_p->object_type |= PRIVATE_OBJECT;
4736 4725 }
4737 4726 } else {
4738 4727 rv = CKR_ATTRIBUTE_READ_ONLY;
4739 4728 }
4740 4729 break;
4741 4730
4742 4731 case CKA_MODIFIABLE:
4743 4732 if (copy) {
4744 4733 if ((*(CK_BBOOL *)template->pValue) == TRUE)
4745 4734 object_p->bool_attr_mask &=
4746 4735 ~NOT_MODIFIABLE_BOOL_ON;
4747 4736 else
4748 4737 object_p->bool_attr_mask |=
4749 4738 NOT_MODIFIABLE_BOOL_ON;
4750 4739 } else {
4751 4740 rv = CKR_ATTRIBUTE_READ_ONLY;
4752 4741 }
4753 4742 break;
4754 4743
4755 4744 case CKA_CLASS:
4756 4745 rv = CKR_ATTRIBUTE_READ_ONLY;
4757 4746 break;
4758 4747
4759 4748 default:
4760 4749 rv = CKR_TEMPLATE_INCONSISTENT;
4761 4750 }
4762 4751
4763 4752 return (rv);
4764 4753 }
4765 4754
4766 4755 /*
4767 4756 * Set the value of an attribute that is common to all key objects
4768 4757 * (i.e. public key, private key and secret key).
4769 4758 */
4770 4759 CK_RV
4771 4760 soft_set_common_key_attribute(soft_object_t *object_p,
4772 4761 CK_ATTRIBUTE_PTR template, boolean_t copy)
4773 4762 {
4774 4763
4775 4764 switch (template->type) {
4776 4765
4777 4766 case CKA_LABEL:
4778 4767 /*
4779 4768 * Only the LABEL can be modified in the common storage
4780 4769 * object attributes after the object is created.
4781 4770 */
4782 4771 return (set_extra_attr_to_object(object_p,
4783 4772 CKA_LABEL, template));
4784 4773
4785 4774 case CKA_ID:
4786 4775 return (set_extra_attr_to_object(object_p,
4787 4776 CKA_ID, template));
4788 4777
4789 4778 case CKA_START_DATE:
4790 4779 return (set_extra_attr_to_object(object_p,
4791 4780 CKA_START_DATE, template));
4792 4781
4793 4782 case CKA_END_DATE:
4794 4783 return (set_extra_attr_to_object(object_p,
4795 4784 CKA_END_DATE, template));
4796 4785
4797 4786 case CKA_DERIVE:
4798 4787 return (set_bool_attr_to_object(object_p,
4799 4788 DERIVE_BOOL_ON, template));
4800 4789
4801 4790 case CKA_KEY_TYPE:
4802 4791 case CKA_LOCAL:
4803 4792 case CKA_KEY_GEN_MECHANISM:
4804 4793 return (CKR_ATTRIBUTE_READ_ONLY);
4805 4794
4806 4795 default:
4807 4796 return (soft_set_common_storage_attribute(object_p,
4808 4797 template, copy));
4809 4798
4810 4799 }
4811 4800
4812 4801 }
4813 4802
4814 4803
4815 4804 /*
4816 4805 * Set the value of an attribute of a Public Key Object.
4817 4806 *
4818 4807 * Rule: The attributes marked with footnote number "8" in the PKCS11
4819 4808 * spec may be modified (p.88 in PKCS11 spec.).
4820 4809 */
4821 4810 CK_RV
4822 4811 soft_set_public_key_attribute(soft_object_t *object_p,
4823 4812 CK_ATTRIBUTE_PTR template, boolean_t copy)
4824 4813 {
4825 4814 CK_KEY_TYPE keytype = object_p->key_type;
4826 4815
4827 4816 switch (template->type) {
4828 4817
4829 4818 case CKA_SUBJECT:
4830 4819 return (set_extra_attr_to_object(object_p,
4831 4820 CKA_SUBJECT, template));
4832 4821
4833 4822 case CKA_ENCRYPT:
4834 4823 return (set_bool_attr_to_object(object_p,
4835 4824 ENCRYPT_BOOL_ON, template));
4836 4825
4837 4826 case CKA_VERIFY:
4838 4827 return (set_bool_attr_to_object(object_p,
4839 4828 VERIFY_BOOL_ON, template));
4840 4829
4841 4830 case CKA_VERIFY_RECOVER:
4842 4831 return (set_bool_attr_to_object(object_p,
4843 4832 VERIFY_RECOVER_BOOL_ON, template));
4844 4833
4845 4834 case CKA_WRAP:
4846 4835 return (set_bool_attr_to_object(object_p,
4847 4836 WRAP_BOOL_ON, template));
4848 4837
4849 4838 case CKA_MODULUS:
4850 4839 case CKA_MODULUS_BITS:
4851 4840 case CKA_PUBLIC_EXPONENT:
4852 4841 if (keytype == CKK_RSA)
4853 4842 return (CKR_ATTRIBUTE_READ_ONLY);
4854 4843 break;
4855 4844
4856 4845 case CKA_SUBPRIME:
4857 4846 if ((keytype == CKK_DSA) ||
4858 4847 (keytype == CKK_X9_42_DH))
4859 4848 return (CKR_ATTRIBUTE_READ_ONLY);
4860 4849 break;
4861 4850
4862 4851 case CKA_PRIME:
4863 4852 case CKA_BASE:
4864 4853 case CKA_VALUE:
4865 4854 if ((keytype == CKK_DSA) ||
4866 4855 (keytype == CKK_DH) ||
4867 4856 (keytype == CKK_X9_42_DH))
4868 4857 return (CKR_ATTRIBUTE_READ_ONLY);
4869 4858 break;
4870 4859
4871 4860 default:
4872 4861 /*
4873 4862 * Set the value of a common key attribute.
4874 4863 */
4875 4864 return (soft_set_common_key_attribute(object_p,
4876 4865 template, copy));
4877 4866
4878 4867 }
4879 4868 /*
4880 4869 * If we got this far, then the combination of key type
4881 4870 * and requested attribute is invalid.
4882 4871 */
4883 4872 return (CKR_ATTRIBUTE_TYPE_INVALID);
4884 4873 }
4885 4874
4886 4875
4887 4876 /*
4888 4877 * Set the value of an attribute of a Private Key Object.
4889 4878 *
4890 4879 * Rule: The attributes marked with footnote number "8" in the PKCS11
4891 4880 * spec may be modified (p.88 in PKCS11 spec.).
4892 4881 */
4893 4882 CK_RV
4894 4883 soft_set_private_key_attribute(soft_object_t *object_p,
4895 4884 CK_ATTRIBUTE_PTR template, boolean_t copy)
4896 4885 {
4897 4886 CK_KEY_TYPE keytype = object_p->key_type;
4898 4887
4899 4888 switch (template->type) {
4900 4889
4901 4890 case CKA_SUBJECT:
4902 4891 return (set_extra_attr_to_object(object_p,
4903 4892 CKA_SUBJECT, template));
4904 4893
4905 4894 case CKA_SENSITIVE:
4906 4895 /*
4907 4896 * Cannot set SENSITIVE to FALSE if it is already ON.
4908 4897 */
4909 4898 if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
4910 4899 (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
4911 4900 return (CKR_ATTRIBUTE_READ_ONLY);
4912 4901 }
4913 4902
4914 4903 if (*(CK_BBOOL *)template->pValue)
4915 4904 object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
4916 4905 return (CKR_OK);
4917 4906
4918 4907 case CKA_DECRYPT:
4919 4908 return (set_bool_attr_to_object(object_p,
4920 4909 DECRYPT_BOOL_ON, template));
4921 4910
4922 4911 case CKA_SIGN:
4923 4912 return (set_bool_attr_to_object(object_p,
4924 4913 SIGN_BOOL_ON, template));
4925 4914
4926 4915 case CKA_SIGN_RECOVER:
4927 4916 return (set_bool_attr_to_object(object_p,
4928 4917 SIGN_RECOVER_BOOL_ON, template));
4929 4918
4930 4919 case CKA_UNWRAP:
4931 4920 return (set_bool_attr_to_object(object_p,
4932 4921 UNWRAP_BOOL_ON, template));
4933 4922
4934 4923 case CKA_EXTRACTABLE:
4935 4924 /*
4936 4925 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
4937 4926 */
4938 4927 if ((*(CK_BBOOL *)template->pValue) &&
4939 4928 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
4940 4929 return (CKR_ATTRIBUTE_READ_ONLY);
4941 4930 }
4942 4931
4943 4932 if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
4944 4933 object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
4945 4934 return (CKR_OK);
4946 4935
4947 4936 case CKA_MODULUS:
4948 4937 case CKA_PUBLIC_EXPONENT:
4949 4938 case CKA_PRIVATE_EXPONENT:
4950 4939 case CKA_PRIME_1:
4951 4940 case CKA_PRIME_2:
4952 4941 case CKA_EXPONENT_1:
4953 4942 case CKA_EXPONENT_2:
4954 4943 case CKA_COEFFICIENT:
4955 4944 if (keytype == CKK_RSA) {
4956 4945 return (CKR_ATTRIBUTE_READ_ONLY);
4957 4946 }
4958 4947 break;
4959 4948
4960 4949 case CKA_SUBPRIME:
4961 4950 if ((keytype == CKK_DSA) ||
4962 4951 (keytype == CKK_X9_42_DH))
4963 4952 return (CKR_ATTRIBUTE_READ_ONLY);
4964 4953 break;
4965 4954
4966 4955 case CKA_PRIME:
4967 4956 case CKA_BASE:
4968 4957 case CKA_VALUE:
4969 4958 if ((keytype == CKK_DSA) ||
4970 4959 (keytype == CKK_DH) ||
4971 4960 (keytype == CKK_X9_42_DH))
4972 4961 return (CKR_ATTRIBUTE_READ_ONLY);
4973 4962 break;
4974 4963
4975 4964 case CKA_VALUE_BITS:
4976 4965 if (keytype == CKK_DH)
4977 4966 return (CKR_ATTRIBUTE_READ_ONLY);
4978 4967 break;
4979 4968
4980 4969 default:
4981 4970 /*
4982 4971 * Set the value of a common key attribute.
4983 4972 */
4984 4973 return (soft_set_common_key_attribute(object_p,
4985 4974 template, copy));
4986 4975 }
4987 4976
4988 4977 /*
4989 4978 * If we got this far, then the combination of key type
4990 4979 * and requested attribute is invalid.
4991 4980 */
4992 4981 return (CKR_ATTRIBUTE_TYPE_INVALID);
4993 4982 }
4994 4983
4995 4984 /*
4996 4985 * Set the value of an attribute of a Secret Key Object.
4997 4986 *
4998 4987 * Rule: The attributes marked with footnote number "8" in the PKCS11
4999 4988 * spec may be modified (p.88 in PKCS11 spec.).
5000 4989 */
5001 4990 CK_RV
5002 4991 soft_set_secret_key_attribute(soft_object_t *object_p,
5003 4992 CK_ATTRIBUTE_PTR template, boolean_t copy)
5004 4993 {
5005 4994 CK_KEY_TYPE keytype = object_p->key_type;
5006 4995
5007 4996 switch (template->type) {
5008 4997
5009 4998 case CKA_SENSITIVE:
5010 4999 /*
5011 5000 * Cannot set SENSITIVE to FALSE if it is already ON.
5012 5001 */
5013 5002 if (((*(CK_BBOOL *)template->pValue) == B_FALSE) &&
5014 5003 (object_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
5015 5004 return (CKR_ATTRIBUTE_READ_ONLY);
5016 5005 }
5017 5006
5018 5007 if (*(CK_BBOOL *)template->pValue)
5019 5008 object_p->bool_attr_mask |= SENSITIVE_BOOL_ON;
5020 5009 return (CKR_OK);
5021 5010
5022 5011 case CKA_ENCRYPT:
5023 5012 return (set_bool_attr_to_object(object_p,
5024 5013 ENCRYPT_BOOL_ON, template));
5025 5014
5026 5015 case CKA_DECRYPT:
5027 5016 return (set_bool_attr_to_object(object_p,
5028 5017 DECRYPT_BOOL_ON, template));
5029 5018
5030 5019 case CKA_SIGN:
5031 5020 return (set_bool_attr_to_object(object_p,
5032 5021 SIGN_BOOL_ON, template));
5033 5022
5034 5023 case CKA_VERIFY:
5035 5024 return (set_bool_attr_to_object(object_p,
5036 5025 VERIFY_BOOL_ON, template));
5037 5026
5038 5027 case CKA_WRAP:
5039 5028 return (set_bool_attr_to_object(object_p,
5040 5029 WRAP_BOOL_ON, template));
5041 5030
5042 5031 case CKA_UNWRAP:
5043 5032 return (set_bool_attr_to_object(object_p,
5044 5033 UNWRAP_BOOL_ON, template));
5045 5034
5046 5035 case CKA_EXTRACTABLE:
5047 5036 /*
5048 5037 * Cannot set EXTRACTABLE to TRUE if it is already OFF.
5049 5038 */
5050 5039 if ((*(CK_BBOOL *)template->pValue) &&
5051 5040 !(object_p->bool_attr_mask & EXTRACTABLE_BOOL_ON)) {
5052 5041 return (CKR_ATTRIBUTE_READ_ONLY);
5053 5042 }
5054 5043
5055 5044 if ((*(CK_BBOOL *)template->pValue) == B_FALSE)
5056 5045 object_p->bool_attr_mask &= ~EXTRACTABLE_BOOL_ON;
5057 5046 return (CKR_OK);
5058 5047
5059 5048 case CKA_VALUE:
5060 5049 return (CKR_ATTRIBUTE_READ_ONLY);
5061 5050
5062 5051 case CKA_VALUE_LEN:
5063 5052 if ((keytype == CKK_RC4) ||
5064 5053 (keytype == CKK_GENERIC_SECRET) ||
5065 5054 (keytype == CKK_AES) ||
5066 5055 (keytype == CKK_BLOWFISH))
5067 5056 return (CKR_ATTRIBUTE_READ_ONLY);
5068 5057 break;
5069 5058
5070 5059 default:
5071 5060 /*
5072 5061 * Set the value of a common key attribute.
5073 5062 */
5074 5063 return (soft_set_common_key_attribute(object_p,
5075 5064 template, copy));
5076 5065
5077 5066 }
5078 5067 /*
5079 5068 * If we got this far, then the combination of key type
5080 5069 * and requested attribute is invalid.
5081 5070 */
5082 5071 return (CKR_ATTRIBUTE_TYPE_INVALID);
5083 5072 }
5084 5073
5085 5074
5086 5075 /*
5087 5076 * Call the appropriate set attribute function according to the class
5088 5077 * of object.
5089 5078 *
5090 5079 * The caller of this function does not hold the lock on the original
5091 5080 * object, since this function is setting the attribute on the new object
5092 5081 * that is being modified.
5093 5082 *
5094 5083 * Argument copy: TRUE when called by C_CopyObject,
5095 5084 * FALSE when called by C_SetAttributeValue.
5096 5085 */
5097 5086 CK_RV
5098 5087 soft_set_attribute(soft_object_t *object_p, CK_ATTRIBUTE_PTR template,
5099 5088 boolean_t copy)
5100 5089 {
5101 5090
5102 5091 CK_RV rv = CKR_OK;
5103 5092 CK_OBJECT_CLASS class = object_p->class;
5104 5093
5105 5094 switch (class) {
5106 5095
5107 5096 case CKO_PUBLIC_KEY:
5108 5097 rv = soft_set_public_key_attribute(object_p, template, copy);
5109 5098 break;
5110 5099
5111 5100 case CKO_PRIVATE_KEY:
5112 5101 rv = soft_set_private_key_attribute(object_p, template, copy);
5113 5102 break;
5114 5103
5115 5104 case CKO_SECRET_KEY:
5116 5105 rv = soft_set_secret_key_attribute(object_p, template, copy);
5117 5106 break;
5118 5107
5119 5108 case CKO_DOMAIN_PARAMETERS:
5120 5109 switch (template->type) {
5121 5110 case CKA_LABEL:
5122 5111 /*
5123 5112 * Only the LABEL can be modified in the common
5124 5113 * storage object attributes after the object is
5125 5114 * created.
5126 5115 */
5127 5116 return (set_extra_attr_to_object(object_p,
5128 5117 CKA_LABEL, template));
5129 5118 default:
5130 5119 return (CKR_TEMPLATE_INCONSISTENT);
5131 5120 }
5132 5121 case CKO_CERTIFICATE:
5133 5122 rv = soft_set_certificate_attribute(object_p, template, copy);
5134 5123 break;
5135 5124
5136 5125 default:
5137 5126 /*
5138 5127 * If the template specifies a value of an attribute
5139 5128 * which is incompatible with other existing attributes
5140 5129 * of the object, then fails with return code
5141 5130 * CKR_TEMPLATE_INCONSISTENT.
5142 5131 */
5143 5132 rv = CKR_TEMPLATE_INCONSISTENT;
5144 5133 break;
5145 5134 }
5146 5135
5147 5136 return (rv);
5148 5137 }
5149 5138
5150 5139 CK_RV
5151 5140 soft_get_public_value(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
5152 5141 uchar_t *value, uint32_t *value_len)
5153 5142 {
5154 5143 uint32_t len = 0;
5155 5144 switch (type) {
5156 5145
5157 5146 /* The following attributes belong to RSA */
5158 5147 case CKA_MODULUS:
5159 5148 #ifdef __sparcv9
5160 5149 len =
5161 5150 /* LINTED */
5162 5151 (uint32_t)
5163 5152 ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value_len;
5164 5153 #else /* !__sparcv9 */
5165 5154 len =
5166 5155 ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value_len;
5167 5156 #endif /* __sparcv9 */
5168 5157
5169 5158 /* This attribute MUST BE set */
5170 5159 if (len == 0 || len > *value_len) {
5171 5160 return (CKR_ATTRIBUTE_VALUE_INVALID);
5172 5161 }
5173 5162 *value_len = len;
5174 5163
5175 5164 (void) memcpy(value,
5176 5165 ((biginteger_t *)OBJ_PUB_RSA_MOD(key))->big_value,
5177 5166 *value_len);
5178 5167
5179 5168 break;
5180 5169
5181 5170 case CKA_PUBLIC_EXPONENT:
5182 5171 #ifdef __sparcv9
5183 5172 len =
5184 5173 /* LINTED */
5185 5174 (uint32_t)
5186 5175 ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value_len;
5187 5176 #else /* !__sparcv9 */
5188 5177 len =
5189 5178 ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value_len;
5190 5179 #endif /* __sparcv9 */
5191 5180
5192 5181 /* This attribute MUST BE set */
5193 5182 if (len == 0 || len > *value_len) {
5194 5183 return (CKR_ATTRIBUTE_VALUE_INVALID);
5195 5184 }
5196 5185 *value_len = len;
5197 5186
5198 5187 (void) memcpy(value,
5199 5188 ((biginteger_t *)OBJ_PUB_RSA_PUBEXPO(key))->big_value,
5200 5189 *value_len);
5201 5190
5202 5191 break;
5203 5192
5204 5193 /* The following attributes belong to DSA and DH */
5205 5194 case CKA_PRIME:
5206 5195
5207 5196 if (key->key_type == CKK_DSA)
5208 5197 #ifdef __sparcv9
5209 5198 len =
5210 5199 /* LINTED */
5211 5200 (uint32_t)
5212 5201 ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->
5213 5202 big_value_len;
5214 5203 #else /* !__sparcv9 */
5215 5204 len =
5216 5205 ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->
5217 5206 big_value_len;
5218 5207 #endif /* __sparcv9 */
5219 5208 else
5220 5209 #ifdef __sparcv9
5221 5210 len =
5222 5211 /* LINTED */
5223 5212 (uint32_t)
5224 5213 ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->
5225 5214 big_value_len;
5226 5215 #else /* !__sparcv9 */
5227 5216 len =
5228 5217 ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->
5229 5218 big_value_len;
5230 5219 #endif /* __sparcv9 */
5231 5220
5232 5221 /* This attribute MUST BE set */
5233 5222 if (len == 0 || len > *value_len) {
5234 5223 return (CKR_ATTRIBUTE_VALUE_INVALID);
5235 5224 }
5236 5225 *value_len = len;
5237 5226
5238 5227 if (key->key_type == CKK_DSA)
5239 5228 (void) memcpy(value,
5240 5229 ((biginteger_t *)OBJ_PUB_DSA_PRIME(key))->big_value,
5241 5230 *value_len);
5242 5231 else
5243 5232 (void) memcpy(value,
5244 5233 ((biginteger_t *)OBJ_PUB_DH_PRIME(key))->big_value,
5245 5234 *value_len);
5246 5235
5247 5236 break;
5248 5237
5249 5238 case CKA_SUBPRIME:
5250 5239 #ifdef __sparcv9
5251 5240 len =
5252 5241 /* LINTED */
5253 5242 (uint32_t)
5254 5243 ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value_len;
5255 5244 #else /* !__sparcv9 */
5256 5245 len =
5257 5246 ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value_len;
5258 5247 #endif /* __sparcv9 */
5259 5248
5260 5249 /* This attribute MUST BE set */
5261 5250 if (len == 0 || len > *value_len) {
5262 5251 return (CKR_ATTRIBUTE_VALUE_INVALID);
5263 5252 }
5264 5253 *value_len = len;
5265 5254
5266 5255 (void) memcpy(value,
5267 5256 ((biginteger_t *)OBJ_PUB_DSA_SUBPRIME(key))->big_value,
5268 5257 *value_len);
5269 5258
5270 5259 break;
5271 5260
5272 5261 case CKA_BASE:
5273 5262
5274 5263 if (key->key_type == CKK_DSA)
5275 5264 #ifdef __sparcv9
5276 5265 len =
5277 5266 /* LINTED */
5278 5267 (uint32_t)
5279 5268 ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->
5280 5269 big_value_len;
5281 5270 #else /* !__sparcv9 */
5282 5271 len =
5283 5272 ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->
5284 5273 big_value_len;
5285 5274 #endif /* __sparcv9 */
5286 5275 else
5287 5276 #ifdef __sparcv9
5288 5277 len =
5289 5278 /* LINTED */
5290 5279 (uint32_t)
5291 5280 ((biginteger_t *)OBJ_PUB_DH_BASE(key))->
5292 5281 big_value_len;
5293 5282 #else /* !__sparcv9 */
5294 5283 len =
5295 5284 ((biginteger_t *)OBJ_PUB_DH_BASE(key))->
5296 5285 big_value_len;
5297 5286 #endif /* __sparcv9 */
5298 5287
5299 5288 /* This attribute MUST BE set */
5300 5289 if (len == 0 || len > *value_len) {
5301 5290 return (CKR_ATTRIBUTE_VALUE_INVALID);
5302 5291 }
5303 5292 *value_len = len;
5304 5293
5305 5294 if (key->key_type == CKK_DSA)
5306 5295 (void) memcpy(value,
5307 5296 ((biginteger_t *)OBJ_PUB_DSA_BASE(key))->big_value,
5308 5297 *value_len);
5309 5298 else
5310 5299 (void) memcpy(value,
5311 5300 ((biginteger_t *)OBJ_PUB_DH_BASE(key))->big_value,
5312 5301 *value_len);
5313 5302 break;
5314 5303
5315 5304 case CKA_VALUE:
5316 5305
5317 5306 if (key->key_type == CKK_DSA)
5318 5307 #ifdef __sparcv9
5319 5308 len =
5320 5309 /* LINTED */
5321 5310 (uint32_t)
5322 5311 ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->
5323 5312 big_value_len;
5324 5313 #else /* !__sparcv9 */
5325 5314 len =
5326 5315 ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->
5327 5316 big_value_len;
5328 5317 #endif /* __sparcv9 */
5329 5318 else
5330 5319 #ifdef __sparcv9
5331 5320 len =
5332 5321 /* LINTED */
5333 5322 (uint32_t)
5334 5323 ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->
5335 5324 big_value_len;
5336 5325 #else /* !__sparcv9 */
5337 5326 len =
5338 5327 ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->
5339 5328 big_value_len;
5340 5329 #endif /* __sparcv9 */
5341 5330
5342 5331 /* This attribute MUST BE set */
5343 5332 if (len == 0 || len > *value_len) {
5344 5333 return (CKR_ATTRIBUTE_VALUE_INVALID);
5345 5334 }
5346 5335 *value_len = len;
5347 5336
5348 5337 if (key->key_type == CKK_DSA)
5349 5338 (void) memcpy(value,
5350 5339 ((biginteger_t *)OBJ_PUB_DSA_VALUE(key))->big_value,
5351 5340 *value_len);
5352 5341 else
5353 5342 (void) memcpy(value,
5354 5343 ((biginteger_t *)OBJ_PUB_DH_VALUE(key))->big_value,
5355 5344 *value_len);
5356 5345
5357 5346 break;
5358 5347 }
5359 5348
5360 5349 return (CKR_OK);
5361 5350 }
5362 5351
5363 5352
5364 5353 CK_RV
5365 5354 soft_get_private_value(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
5366 5355 uchar_t *value, uint32_t *value_len)
5367 5356 {
5368 5357
5369 5358 uint32_t len = 0;
5370 5359
5371 5360 switch (type) {
5372 5361
5373 5362 /* The following attributes belong to RSA */
5374 5363 case CKA_MODULUS:
5375 5364 #ifdef __sparcv9
5376 5365 len =
5377 5366 /* LINTED */
5378 5367 (uint32_t)
5379 5368 ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value_len;
5380 5369 #else /* !__sparcv9 */
5381 5370 len =
5382 5371 ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value_len;
5383 5372 #endif /* __sparcv9 */
5384 5373
5385 5374 /* This attribute MUST BE set */
5386 5375 if (len == 0 || len > *value_len) {
5387 5376 return (CKR_ATTRIBUTE_VALUE_INVALID);
5388 5377 }
5389 5378 *value_len = len;
5390 5379
5391 5380 (void) memcpy(value,
5392 5381 ((biginteger_t *)OBJ_PRI_RSA_MOD(key))->big_value,
5393 5382 *value_len);
5394 5383
5395 5384 break;
5396 5385
5397 5386 case CKA_PRIVATE_EXPONENT:
5398 5387 #ifdef __sparcv9
5399 5388 len =
5400 5389 /* LINTED */
5401 5390 (uint32_t)
5402 5391 ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value_len;
5403 5392 #else /* !__sparcv9 */
5404 5393 len =
5405 5394 ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value_len;
5406 5395 #endif /* __sparcv9 */
5407 5396
5408 5397 /* This attribute MUST BE set */
5409 5398 if (len == 0 || len > *value_len) {
5410 5399 return (CKR_ATTRIBUTE_VALUE_INVALID);
5411 5400 }
5412 5401 *value_len = len;
5413 5402
5414 5403 (void) memcpy(value,
5415 5404 ((biginteger_t *)OBJ_PRI_RSA_PRIEXPO(key))->big_value,
5416 5405 *value_len);
5417 5406
5418 5407 break;
5419 5408
5420 5409 case CKA_PRIME_1:
5421 5410 #ifdef __sparcv9
5422 5411 len =
5423 5412 /* LINTED */
5424 5413 (uint32_t)
5425 5414 ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value_len;
5426 5415 #else /* !__sparcv9 */
5427 5416 len =
5428 5417 ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value_len;
5429 5418 #endif /* __sparcv9 */
5430 5419
5431 5420 if (len > *value_len) {
5432 5421 return (CKR_ATTRIBUTE_VALUE_INVALID);
5433 5422 }
5434 5423 *value_len = len;
5435 5424
5436 5425 if (*value_len == 0) {
5437 5426 return (CKR_OK);
5438 5427 }
5439 5428
5440 5429 (void) memcpy(value,
5441 5430 ((biginteger_t *)OBJ_PRI_RSA_PRIME1(key))->big_value,
5442 5431 *value_len);
5443 5432
5444 5433 break;
5445 5434
5446 5435 case CKA_PRIME_2:
5447 5436 #ifdef __sparcv9
5448 5437 len =
5449 5438 /* LINTED */
5450 5439 (uint32_t)
5451 5440 ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value_len;
5452 5441 #else /* !__sparcv9 */
5453 5442 len =
5454 5443 ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value_len;
5455 5444 #endif /* __sparcv9 */
5456 5445
5457 5446 if (len > *value_len) {
5458 5447 return (CKR_ATTRIBUTE_VALUE_INVALID);
5459 5448 }
5460 5449 *value_len = len;
5461 5450
5462 5451 if (*value_len == 0) {
5463 5452 return (CKR_OK);
5464 5453 }
5465 5454
5466 5455 (void) memcpy(value,
5467 5456 ((biginteger_t *)OBJ_PRI_RSA_PRIME2(key))->big_value,
5468 5457 *value_len);
5469 5458
5470 5459 break;
5471 5460
5472 5461 case CKA_EXPONENT_1:
5473 5462 #ifdef __sparcv9
5474 5463 len =
5475 5464 /* LINTED */
5476 5465 (uint32_t)
5477 5466 ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value_len;
5478 5467 #else /* !__sparcv9 */
5479 5468 len =
5480 5469 ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value_len;
5481 5470 #endif /* __sparcv9 */
5482 5471
5483 5472 if (len > *value_len) {
5484 5473 return (CKR_ATTRIBUTE_VALUE_INVALID);
5485 5474 }
5486 5475 *value_len = len;
5487 5476
5488 5477 if (*value_len == 0) {
5489 5478 return (CKR_OK);
5490 5479 }
5491 5480
5492 5481 (void) memcpy(value,
5493 5482 ((biginteger_t *)OBJ_PRI_RSA_EXPO1(key))->big_value,
5494 5483 *value_len);
5495 5484
5496 5485 break;
5497 5486
5498 5487 case CKA_EXPONENT_2:
5499 5488 #ifdef __sparcv9
5500 5489 len =
5501 5490 /* LINTED */
5502 5491 (uint32_t)
5503 5492 ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value_len;
5504 5493 #else /* !__sparcv9 */
5505 5494 len =
5506 5495 ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value_len;
5507 5496 #endif /* __sparcv9 */
5508 5497
5509 5498 if (len > *value_len) {
5510 5499 return (CKR_ATTRIBUTE_VALUE_INVALID);
5511 5500 }
5512 5501 *value_len = len;
5513 5502
5514 5503 if (*value_len == 0) {
5515 5504 return (CKR_OK);
5516 5505 }
5517 5506
5518 5507 (void) memcpy(value,
5519 5508 ((biginteger_t *)OBJ_PRI_RSA_EXPO2(key))->big_value,
5520 5509 *value_len);
5521 5510
5522 5511 break;
5523 5512
5524 5513 case CKA_COEFFICIENT:
5525 5514 #ifdef __sparcv9
5526 5515 len =
5527 5516 /* LINTED */
5528 5517 (uint32_t)
5529 5518 ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value_len;
5530 5519 #else /* !__sparcv9 */
5531 5520 len =
5532 5521 ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value_len;
5533 5522 #endif /* __sparcv9 */
5534 5523
5535 5524 if (len > *value_len) {
5536 5525 return (CKR_ATTRIBUTE_VALUE_INVALID);
5537 5526 }
5538 5527 *value_len = len;
5539 5528
5540 5529 if (*value_len == 0) {
5541 5530 return (CKR_OK);
5542 5531 }
5543 5532
5544 5533 (void) memcpy(value,
5545 5534 ((biginteger_t *)OBJ_PRI_RSA_COEF(key))->big_value,
5546 5535 *value_len);
5547 5536
5548 5537 break;
5549 5538
5550 5539 /* The following attributes belong to DSA and DH */
5551 5540 case CKA_PRIME:
5552 5541
5553 5542 if (key->key_type == CKK_DSA)
5554 5543 #ifdef __sparcv9
5555 5544 len =
5556 5545 /* LINTED */
5557 5546 (uint32_t)
5558 5547 ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->
5559 5548 big_value_len;
5560 5549 #else /* !__sparcv9 */
5561 5550 len =
5562 5551 ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->
5563 5552 big_value_len;
5564 5553 #endif /* __sparcv9 */
5565 5554 else
5566 5555 #ifdef __sparcv9
5567 5556 len =
5568 5557 /* LINTED */
5569 5558 (uint32_t)
5570 5559 ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->
5571 5560 big_value_len;
5572 5561 #else /* !__sparcv9 */
5573 5562 len =
5574 5563 ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->
5575 5564 big_value_len;
5576 5565 #endif /* __sparcv9 */
5577 5566
5578 5567 /* This attribute MUST BE set */
5579 5568 if (len == 0 || len > *value_len) {
5580 5569 return (CKR_ATTRIBUTE_VALUE_INVALID);
5581 5570 }
5582 5571 *value_len = len;
5583 5572
5584 5573 if (key->key_type == CKK_DSA)
5585 5574 (void) memcpy(value,
5586 5575 ((biginteger_t *)OBJ_PRI_DSA_PRIME(key))->big_value,
5587 5576 *value_len);
5588 5577 else
5589 5578 (void) memcpy(value,
5590 5579 ((biginteger_t *)OBJ_PRI_DH_PRIME(key))->big_value,
5591 5580 *value_len);
5592 5581
5593 5582 break;
5594 5583
5595 5584 case CKA_SUBPRIME:
5596 5585 #ifdef __sparcv9
5597 5586 len =
5598 5587 /* LINTED */
5599 5588 (uint32_t)
5600 5589 ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value_len;
5601 5590 #else /* !__sparcv9 */
5602 5591 len =
5603 5592 ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value_len;
5604 5593 #endif /* __sparcv9 */
5605 5594
5606 5595 /* This attribute MUST BE set */
5607 5596 if (len == 0 || len > *value_len) {
5608 5597 return (CKR_ATTRIBUTE_VALUE_INVALID);
5609 5598 }
5610 5599 *value_len = len;
5611 5600
5612 5601 (void) memcpy(value,
5613 5602 ((biginteger_t *)OBJ_PRI_DSA_SUBPRIME(key))->big_value,
5614 5603 *value_len);
5615 5604
5616 5605 break;
5617 5606
5618 5607 case CKA_BASE:
5619 5608
5620 5609 if (key->key_type == CKK_DSA)
5621 5610 #ifdef __sparcv9
5622 5611 len =
5623 5612 /* LINTED */
5624 5613 (uint32_t)
5625 5614 ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->
5626 5615 big_value_len;
5627 5616 #else /* !__sparcv9 */
5628 5617 len =
5629 5618 ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->
5630 5619 big_value_len;
5631 5620 #endif /* __sparcv9 */
5632 5621 else
5633 5622 #ifdef __sparcv9
5634 5623 len =
5635 5624 /* LINTED */
5636 5625 (uint32_t)
5637 5626 ((biginteger_t *)OBJ_PRI_DH_BASE(key))->
5638 5627 big_value_len;
5639 5628 #else /* !__sparcv9 */
5640 5629 len =
5641 5630 ((biginteger_t *)OBJ_PRI_DH_BASE(key))->
5642 5631 big_value_len;
5643 5632 #endif /* __sparcv9 */
5644 5633
5645 5634 /* This attribute MUST BE set */
5646 5635 if (len == 0 || len > *value_len) {
5647 5636 return (CKR_ATTRIBUTE_VALUE_INVALID);
5648 5637 }
5649 5638 *value_len = len;
5650 5639
5651 5640 if (key->key_type == CKK_DSA)
5652 5641 (void) memcpy(value,
5653 5642 ((biginteger_t *)OBJ_PRI_DSA_BASE(key))->big_value,
5654 5643 *value_len);
5655 5644 else
5656 5645 (void) memcpy(value,
5657 5646 ((biginteger_t *)OBJ_PRI_DH_BASE(key))->big_value,
5658 5647 *value_len);
5659 5648 break;
5660 5649
5661 5650 case CKA_VALUE:
5662 5651
5663 5652 if (key->key_type == CKK_DSA) {
5664 5653 #ifdef __sparcv9
5665 5654 len =
5666 5655 /* LINTED */
5667 5656 (uint32_t)
5668 5657 ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->
5669 5658 big_value_len;
5670 5659 #else /* !__sparcv9 */
5671 5660 len =
5672 5661 ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->
5673 5662 big_value_len;
5674 5663 #endif /* __sparcv9 */
5675 5664 } else if (key->key_type == CKK_DH) {
5676 5665 #ifdef __sparcv9
5677 5666 len =
5678 5667 /* LINTED */
5679 5668 (uint32_t)
5680 5669 ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->
5681 5670 big_value_len;
5682 5671 #else /* !__sparcv9 */
5683 5672 len =
5684 5673 ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->
5685 5674 big_value_len;
5686 5675 #endif /* __sparcv9 */
5687 5676 } else {
5688 5677 #ifdef __sparcv9
5689 5678 len =
5690 5679 /* LINTED */
5691 5680 (uint32_t)
5692 5681 ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->
5693 5682 big_value_len;
5694 5683 #else /* !__sparcv9 */
5695 5684 len =
5696 5685 ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->
5697 5686 big_value_len;
5698 5687 #endif /* __sparcv9 */
5699 5688 }
5700 5689
5701 5690 /* This attribute MUST BE set */
5702 5691 if (len == 0 || len > *value_len) {
5703 5692 return (CKR_ATTRIBUTE_VALUE_INVALID);
5704 5693 }
5705 5694 *value_len = len;
5706 5695
5707 5696 if (key->key_type == CKK_DSA) {
5708 5697 (void) memcpy(value,
5709 5698 ((biginteger_t *)OBJ_PRI_DSA_VALUE(key))->big_value,
5710 5699 *value_len);
5711 5700 } else if (key->key_type == CKK_DH) {
5712 5701 (void) memcpy(value,
5713 5702 ((biginteger_t *)OBJ_PRI_DH_VALUE(key))->big_value,
5714 5703 *value_len);
5715 5704 } else {
5716 5705 (void) memcpy(value,
5717 5706 ((biginteger_t *)OBJ_PRI_EC_VALUE(key))->big_value,
5718 5707 *value_len);
5719 5708 }
5720 5709
5721 5710 break;
5722 5711 }
5723 5712
5724 5713 return (CKR_OK);
5725 5714
5726 5715 }
5727 5716
5728 5717 static CK_RV
5729 5718 copy_bigint(biginteger_t *new_bigint, biginteger_t *old_bigint)
5730 5719 {
5731 5720 new_bigint->big_value =
5732 5721 malloc((sizeof (CK_BYTE) * new_bigint->big_value_len));
5733 5722
5734 5723 if (new_bigint->big_value == NULL) {
5735 5724 return (CKR_HOST_MEMORY);
5736 5725 }
5737 5726
5738 5727 (void) memcpy(new_bigint->big_value, old_bigint->big_value,
5739 5728 (sizeof (CK_BYTE) * new_bigint->big_value_len));
5740 5729
5741 5730 return (CKR_OK);
5742 5731 }
5743 5732
5744 5733 static void
5745 5734 free_public_key_attr(public_key_obj_t *pbk, CK_KEY_TYPE key_type)
5746 5735 {
5747 5736 if (pbk == NULL) {
5748 5737 return;
5749 5738 }
5750 5739
5751 5740 switch (key_type) {
5752 5741 case CKK_RSA:
5753 5742 bigint_attr_cleanup(KEY_PUB_RSA_MOD(pbk));
5754 5743 bigint_attr_cleanup(KEY_PUB_RSA_PUBEXPO(pbk));
5755 5744 break;
5756 5745 case CKK_DSA:
5757 5746 bigint_attr_cleanup(KEY_PUB_DSA_PRIME(pbk));
5758 5747 bigint_attr_cleanup(KEY_PUB_DSA_SUBPRIME(pbk));
5759 5748 bigint_attr_cleanup(KEY_PUB_DSA_BASE(pbk));
5760 5749 bigint_attr_cleanup(KEY_PUB_DSA_VALUE(pbk));
5761 5750 break;
5762 5751 case CKK_DH:
5763 5752 bigint_attr_cleanup(KEY_PUB_DH_PRIME(pbk));
5764 5753 bigint_attr_cleanup(KEY_PUB_DH_BASE(pbk));
5765 5754 bigint_attr_cleanup(KEY_PUB_DH_VALUE(pbk));
5766 5755 break;
5767 5756 case CKK_EC:
5768 5757 bigint_attr_cleanup(KEY_PUB_EC_POINT(pbk));
5769 5758 break;
5770 5759 case CKK_X9_42_DH:
5771 5760 bigint_attr_cleanup(KEY_PUB_DH942_PRIME(pbk));
5772 5761 bigint_attr_cleanup(KEY_PUB_DH942_SUBPRIME(pbk));
5773 5762 bigint_attr_cleanup(KEY_PUB_DH942_BASE(pbk));
5774 5763 bigint_attr_cleanup(KEY_PUB_DH942_VALUE(pbk));
5775 5764 break;
5776 5765 default:
5777 5766 break;
5778 5767 }
5779 5768 free(pbk);
5780 5769 }
5781 5770
5782 5771 CK_RV
5783 5772 soft_copy_public_key_attr(public_key_obj_t *old_pub_key_obj_p,
5784 5773 public_key_obj_t **new_pub_key_obj_p, CK_KEY_TYPE key_type)
5785 5774 {
5786 5775
5787 5776 public_key_obj_t *pbk;
5788 5777 CK_RV rv = CKR_OK;
5789 5778
5790 5779 pbk = calloc(1, sizeof (public_key_obj_t));
5791 5780 if (pbk == NULL) {
5792 5781 return (CKR_HOST_MEMORY);
5793 5782 }
5794 5783
5795 5784 switch (key_type) {
5796 5785 case CKK_RSA:
5797 5786 (void) memcpy(KEY_PUB_RSA(pbk),
5798 5787 KEY_PUB_RSA(old_pub_key_obj_p),
5799 5788 sizeof (rsa_pub_key_t));
5800 5789 /* copy modulus */
5801 5790 rv = copy_bigint(KEY_PUB_RSA_MOD(pbk),
5802 5791 KEY_PUB_RSA_MOD(old_pub_key_obj_p));
5803 5792 if (rv != CKR_OK) {
5804 5793 free_public_key_attr(pbk, key_type);
5805 5794 return (rv);
5806 5795 }
5807 5796 /* copy public exponent */
5808 5797 rv = copy_bigint(KEY_PUB_RSA_PUBEXPO(pbk),
5809 5798 KEY_PUB_RSA_PUBEXPO(old_pub_key_obj_p));
5810 5799 if (rv != CKR_OK) {
5811 5800 free_public_key_attr(pbk, key_type);
5812 5801 return (rv);
5813 5802 }
5814 5803 break;
5815 5804 case CKK_DSA:
5816 5805 (void) memcpy(KEY_PUB_DSA(pbk),
5817 5806 KEY_PUB_DSA(old_pub_key_obj_p),
5818 5807 sizeof (dsa_pub_key_t));
5819 5808
5820 5809 /* copy prime */
5821 5810 rv = copy_bigint(KEY_PUB_DSA_PRIME(pbk),
5822 5811 KEY_PUB_DSA_PRIME(old_pub_key_obj_p));
5823 5812 if (rv != CKR_OK) {
5824 5813 free_public_key_attr(pbk, key_type);
5825 5814 return (rv);
5826 5815 }
5827 5816
5828 5817 /* copy subprime */
5829 5818 rv = copy_bigint(KEY_PUB_DSA_SUBPRIME(pbk),
5830 5819 KEY_PUB_DSA_SUBPRIME(old_pub_key_obj_p));
5831 5820 if (rv != CKR_OK) {
5832 5821 free_public_key_attr(pbk, key_type);
5833 5822 return (rv);
5834 5823 }
5835 5824
5836 5825 /* copy base */
5837 5826 rv = copy_bigint(KEY_PUB_DSA_BASE(pbk),
5838 5827 KEY_PUB_DSA_BASE(old_pub_key_obj_p));
5839 5828 if (rv != CKR_OK) {
5840 5829 free_public_key_attr(pbk, key_type);
5841 5830 return (rv);
5842 5831 }
5843 5832
5844 5833 /* copy value */
5845 5834 rv = copy_bigint(KEY_PUB_DSA_VALUE(pbk),
5846 5835 KEY_PUB_DSA_VALUE(old_pub_key_obj_p));
5847 5836 if (rv != CKR_OK) {
5848 5837 free_public_key_attr(pbk, key_type);
5849 5838 return (rv);
5850 5839 }
5851 5840 break;
5852 5841 case CKK_DH:
5853 5842 (void) memcpy(KEY_PUB_DH(pbk),
5854 5843 KEY_PUB_DH(old_pub_key_obj_p),
5855 5844 sizeof (dh_pub_key_t));
5856 5845
5857 5846 /* copy prime */
5858 5847 rv = copy_bigint(KEY_PUB_DH_PRIME(pbk),
5859 5848 KEY_PUB_DH_PRIME(old_pub_key_obj_p));
5860 5849 if (rv != CKR_OK) {
5861 5850 free_public_key_attr(pbk, key_type);
5862 5851 return (rv);
5863 5852 }
5864 5853
5865 5854 /* copy base */
5866 5855 rv = copy_bigint(KEY_PUB_DH_BASE(pbk),
5867 5856 KEY_PUB_DH_BASE(old_pub_key_obj_p));
5868 5857 if (rv != CKR_OK) {
5869 5858 free_public_key_attr(pbk, key_type);
5870 5859 return (rv);
5871 5860 }
5872 5861
5873 5862 /* copy value */
5874 5863 rv = copy_bigint(KEY_PUB_DH_VALUE(pbk),
5875 5864 KEY_PUB_DH_VALUE(old_pub_key_obj_p));
5876 5865 if (rv != CKR_OK) {
5877 5866 free_public_key_attr(pbk, key_type);
5878 5867 return (rv);
5879 5868 }
5880 5869 break;
5881 5870 case CKK_EC:
5882 5871 (void) memcpy(KEY_PUB_EC(pbk),
5883 5872 KEY_PUB_EC(old_pub_key_obj_p),
5884 5873 sizeof (ec_pub_key_t));
5885 5874
5886 5875 /* copy point */
5887 5876 rv = copy_bigint(KEY_PUB_EC_POINT(pbk),
5888 5877 KEY_PUB_EC_POINT(old_pub_key_obj_p));
5889 5878 if (rv != CKR_OK) {
5890 5879 free_public_key_attr(pbk, key_type);
5891 5880 return (rv);
5892 5881 }
5893 5882 break;
5894 5883 case CKK_X9_42_DH:
5895 5884 (void) memcpy(KEY_PUB_DH942(pbk),
5896 5885 KEY_PUB_DH942(old_pub_key_obj_p),
5897 5886 sizeof (dh942_pub_key_t));
5898 5887
5899 5888 /* copy prime */
5900 5889 rv = copy_bigint(KEY_PUB_DH942_PRIME(pbk),
5901 5890 KEY_PUB_DH942_PRIME(old_pub_key_obj_p));
5902 5891 if (rv != CKR_OK) {
5903 5892 free_public_key_attr(pbk, key_type);
5904 5893 return (rv);
5905 5894 }
5906 5895
5907 5896 /* copy subprime */
5908 5897 rv = copy_bigint(KEY_PUB_DH942_SUBPRIME(pbk),
5909 5898 KEY_PUB_DH942_SUBPRIME(old_pub_key_obj_p));
5910 5899 if (rv != CKR_OK) {
5911 5900 free_public_key_attr(pbk, key_type);
5912 5901 return (rv);
5913 5902 }
5914 5903
5915 5904 /* copy base */
5916 5905 rv = copy_bigint(KEY_PUB_DH942_BASE(pbk),
5917 5906 KEY_PUB_DH942_BASE(old_pub_key_obj_p));
5918 5907 if (rv != CKR_OK) {
5919 5908 free_public_key_attr(pbk, key_type);
5920 5909 return (rv);
5921 5910 }
5922 5911
5923 5912 /* copy value */
5924 5913 rv = copy_bigint(KEY_PUB_DH942_VALUE(pbk),
5925 5914 KEY_PUB_DH942_VALUE(old_pub_key_obj_p));
5926 5915 if (rv != CKR_OK) {
5927 5916 free_public_key_attr(pbk, key_type);
5928 5917 return (rv);
5929 5918 }
5930 5919 break;
5931 5920 default:
5932 5921 break;
5933 5922 }
5934 5923 *new_pub_key_obj_p = pbk;
5935 5924 return (rv);
5936 5925 }
5937 5926
5938 5927 static void
5939 5928 free_private_key_attr(private_key_obj_t *pbk, CK_KEY_TYPE key_type)
5940 5929 {
5941 5930 if (pbk == NULL) {
5942 5931 return;
5943 5932 }
5944 5933
5945 5934 switch (key_type) {
5946 5935 case CKK_RSA:
5947 5936 bigint_attr_cleanup(KEY_PRI_RSA_MOD(pbk));
5948 5937 bigint_attr_cleanup(KEY_PRI_RSA_PUBEXPO(pbk));
5949 5938 bigint_attr_cleanup(KEY_PRI_RSA_PRIEXPO(pbk));
5950 5939 bigint_attr_cleanup(KEY_PRI_RSA_PRIME1(pbk));
5951 5940 bigint_attr_cleanup(KEY_PRI_RSA_PRIME2(pbk));
5952 5941 bigint_attr_cleanup(KEY_PRI_RSA_EXPO1(pbk));
5953 5942 bigint_attr_cleanup(KEY_PRI_RSA_EXPO2(pbk));
5954 5943 bigint_attr_cleanup(KEY_PRI_RSA_COEF(pbk));
5955 5944 break;
5956 5945 case CKK_DSA:
5957 5946 bigint_attr_cleanup(KEY_PRI_DSA_PRIME(pbk));
5958 5947 bigint_attr_cleanup(KEY_PRI_DSA_SUBPRIME(pbk));
5959 5948 bigint_attr_cleanup(KEY_PRI_DSA_BASE(pbk));
5960 5949 bigint_attr_cleanup(KEY_PRI_DSA_VALUE(pbk));
5961 5950 break;
5962 5951 case CKK_DH:
5963 5952 bigint_attr_cleanup(KEY_PRI_DH_PRIME(pbk));
5964 5953 bigint_attr_cleanup(KEY_PRI_DH_BASE(pbk));
5965 5954 bigint_attr_cleanup(KEY_PRI_DH_VALUE(pbk));
5966 5955 break;
5967 5956 case CKK_EC:
5968 5957 bigint_attr_cleanup(KEY_PRI_EC_VALUE(pbk));
5969 5958 break;
5970 5959 case CKK_X9_42_DH:
5971 5960 bigint_attr_cleanup(KEY_PRI_DH942_PRIME(pbk));
5972 5961 bigint_attr_cleanup(KEY_PRI_DH942_SUBPRIME(pbk));
5973 5962 bigint_attr_cleanup(KEY_PRI_DH942_BASE(pbk));
5974 5963 bigint_attr_cleanup(KEY_PRI_DH942_VALUE(pbk));
5975 5964 break;
5976 5965 default:
5977 5966 break;
5978 5967 }
5979 5968 free(pbk);
5980 5969 }
5981 5970
5982 5971 CK_RV
5983 5972 soft_copy_private_key_attr(private_key_obj_t *old_pri_key_obj_p,
5984 5973 private_key_obj_t **new_pri_key_obj_p, CK_KEY_TYPE key_type)
5985 5974 {
5986 5975 CK_RV rv = CKR_OK;
5987 5976 private_key_obj_t *pbk;
5988 5977
5989 5978 pbk = calloc(1, sizeof (private_key_obj_t));
5990 5979 if (pbk == NULL) {
5991 5980 return (CKR_HOST_MEMORY);
5992 5981 }
5993 5982
5994 5983 switch (key_type) {
5995 5984 case CKK_RSA:
5996 5985 (void) memcpy(KEY_PRI_RSA(pbk),
5997 5986 KEY_PRI_RSA(old_pri_key_obj_p),
5998 5987 sizeof (rsa_pri_key_t));
5999 5988 /* copy modulus */
6000 5989 rv = copy_bigint(KEY_PRI_RSA_MOD(pbk),
6001 5990 KEY_PRI_RSA_MOD(old_pri_key_obj_p));
6002 5991 if (rv != CKR_OK) {
6003 5992 free_private_key_attr(pbk, key_type);
6004 5993 return (rv);
6005 5994 }
6006 5995 /* copy public exponent */
6007 5996 rv = copy_bigint(KEY_PRI_RSA_PUBEXPO(pbk),
6008 5997 KEY_PRI_RSA_PUBEXPO(old_pri_key_obj_p));
6009 5998 if (rv != CKR_OK) {
6010 5999 free_private_key_attr(pbk, key_type);
6011 6000 return (rv);
6012 6001 }
6013 6002 /* copy private exponent */
6014 6003 rv = copy_bigint(KEY_PRI_RSA_PRIEXPO(pbk),
6015 6004 KEY_PRI_RSA_PRIEXPO(old_pri_key_obj_p));
6016 6005 if (rv != CKR_OK) {
6017 6006 free_private_key_attr(pbk, key_type);
6018 6007 return (rv);
6019 6008 }
6020 6009 /* copy prime_1 */
6021 6010 rv = copy_bigint(KEY_PRI_RSA_PRIME1(pbk),
6022 6011 KEY_PRI_RSA_PRIME1(old_pri_key_obj_p));
6023 6012 if (rv != CKR_OK) {
6024 6013 free_private_key_attr(pbk, key_type);
6025 6014 return (rv);
6026 6015 }
6027 6016 /* copy prime_2 */
6028 6017 rv = copy_bigint(KEY_PRI_RSA_PRIME2(pbk),
6029 6018 KEY_PRI_RSA_PRIME2(old_pri_key_obj_p));
6030 6019 if (rv != CKR_OK) {
6031 6020 free_private_key_attr(pbk, key_type);
6032 6021 return (rv);
6033 6022 }
6034 6023 /* copy exponent_1 */
6035 6024 rv = copy_bigint(KEY_PRI_RSA_EXPO1(pbk),
6036 6025 KEY_PRI_RSA_EXPO1(old_pri_key_obj_p));
6037 6026 if (rv != CKR_OK) {
6038 6027 free_private_key_attr(pbk, key_type);
6039 6028 return (rv);
6040 6029 }
6041 6030 /* copy exponent_2 */
6042 6031 rv = copy_bigint(KEY_PRI_RSA_EXPO2(pbk),
6043 6032 KEY_PRI_RSA_EXPO2(old_pri_key_obj_p));
6044 6033 if (rv != CKR_OK) {
6045 6034 free_private_key_attr(pbk, key_type);
6046 6035 return (rv);
6047 6036 }
6048 6037 /* copy coefficient */
6049 6038 rv = copy_bigint(KEY_PRI_RSA_COEF(pbk),
6050 6039 KEY_PRI_RSA_COEF(old_pri_key_obj_p));
6051 6040 if (rv != CKR_OK) {
6052 6041 free_private_key_attr(pbk, key_type);
6053 6042 return (rv);
6054 6043 }
6055 6044 break;
6056 6045 case CKK_DSA:
6057 6046 (void) memcpy(KEY_PRI_DSA(pbk),
6058 6047 KEY_PRI_DSA(old_pri_key_obj_p),
6059 6048 sizeof (dsa_pri_key_t));
6060 6049
6061 6050 /* copy prime */
6062 6051 rv = copy_bigint(KEY_PRI_DSA_PRIME(pbk),
6063 6052 KEY_PRI_DSA_PRIME(old_pri_key_obj_p));
6064 6053 if (rv != CKR_OK) {
6065 6054 free_private_key_attr(pbk, key_type);
6066 6055 return (rv);
6067 6056 }
6068 6057
6069 6058 /* copy subprime */
6070 6059 rv = copy_bigint(KEY_PRI_DSA_SUBPRIME(pbk),
6071 6060 KEY_PRI_DSA_SUBPRIME(old_pri_key_obj_p));
6072 6061 if (rv != CKR_OK) {
6073 6062 free_private_key_attr(pbk, key_type);
6074 6063 return (rv);
6075 6064 }
6076 6065
6077 6066 /* copy base */
6078 6067 rv = copy_bigint(KEY_PRI_DSA_BASE(pbk),
6079 6068 KEY_PRI_DSA_BASE(old_pri_key_obj_p));
6080 6069 if (rv != CKR_OK) {
6081 6070 free_private_key_attr(pbk, key_type);
6082 6071 return (rv);
6083 6072 }
6084 6073
6085 6074 /* copy value */
6086 6075 rv = copy_bigint(KEY_PRI_DSA_VALUE(pbk),
6087 6076 KEY_PRI_DSA_VALUE(old_pri_key_obj_p));
6088 6077 if (rv != CKR_OK) {
6089 6078 free_private_key_attr(pbk, key_type);
6090 6079 return (rv);
6091 6080 }
6092 6081 break;
6093 6082 case CKK_DH:
6094 6083 (void) memcpy(KEY_PRI_DH(pbk),
6095 6084 KEY_PRI_DH(old_pri_key_obj_p),
6096 6085 sizeof (dh_pri_key_t));
6097 6086
6098 6087 /* copy prime */
6099 6088 rv = copy_bigint(KEY_PRI_DH_PRIME(pbk),
6100 6089 KEY_PRI_DH_PRIME(old_pri_key_obj_p));
6101 6090 if (rv != CKR_OK) {
6102 6091 free_private_key_attr(pbk, key_type);
6103 6092 return (rv);
6104 6093 }
6105 6094
6106 6095 /* copy base */
6107 6096 rv = copy_bigint(KEY_PRI_DH_BASE(pbk),
6108 6097 KEY_PRI_DH_BASE(old_pri_key_obj_p));
6109 6098 if (rv != CKR_OK) {
6110 6099 free_private_key_attr(pbk, key_type);
6111 6100 return (rv);
6112 6101 }
6113 6102
6114 6103 /* copy value */
6115 6104 rv = copy_bigint(KEY_PRI_DH_VALUE(pbk),
6116 6105 KEY_PRI_DH_VALUE(old_pri_key_obj_p));
6117 6106 if (rv != CKR_OK) {
6118 6107 free_private_key_attr(pbk, key_type);
6119 6108 return (rv);
6120 6109 }
6121 6110 break;
6122 6111 case CKK_EC:
6123 6112 (void) memcpy(KEY_PRI_EC(pbk),
6124 6113 KEY_PRI_EC(old_pri_key_obj_p),
6125 6114 sizeof (ec_pri_key_t));
6126 6115
6127 6116 /* copy value */
6128 6117 rv = copy_bigint(KEY_PRI_EC_VALUE(pbk),
6129 6118 KEY_PRI_EC_VALUE(old_pri_key_obj_p));
6130 6119 if (rv != CKR_OK) {
6131 6120 free_private_key_attr(pbk, key_type);
6132 6121 return (rv);
6133 6122 }
6134 6123 break;
6135 6124 case CKK_X9_42_DH:
6136 6125 (void) memcpy(KEY_PRI_DH942(pbk),
6137 6126 KEY_PRI_DH942(old_pri_key_obj_p),
6138 6127 sizeof (dh942_pri_key_t));
6139 6128
6140 6129 /* copy prime */
6141 6130 rv = copy_bigint(KEY_PRI_DH942_PRIME(pbk),
6142 6131 KEY_PRI_DH942_PRIME(old_pri_key_obj_p));
6143 6132 if (rv != CKR_OK) {
6144 6133 free_private_key_attr(pbk, key_type);
6145 6134 return (rv);
6146 6135 }
6147 6136
6148 6137 /* copy subprime */
6149 6138 rv = copy_bigint(KEY_PRI_DH942_SUBPRIME(pbk),
6150 6139 KEY_PRI_DH942_SUBPRIME(old_pri_key_obj_p));
6151 6140 if (rv != CKR_OK) {
6152 6141 free_private_key_attr(pbk, key_type);
6153 6142 return (rv);
6154 6143 }
6155 6144
6156 6145 /* copy base */
6157 6146 rv = copy_bigint(KEY_PRI_DH942_BASE(pbk),
6158 6147 KEY_PRI_DH942_BASE(old_pri_key_obj_p));
6159 6148 if (rv != CKR_OK) {
6160 6149 free_private_key_attr(pbk, key_type);
6161 6150 return (rv);
6162 6151 }
6163 6152
6164 6153 /* copy value */
6165 6154 rv = copy_bigint(KEY_PRI_DH942_VALUE(pbk),
6166 6155 KEY_PRI_DH942_VALUE(old_pri_key_obj_p));
6167 6156 if (rv != CKR_OK) {
6168 6157 free_private_key_attr(pbk, key_type);
6169 6158 return (rv);
6170 6159 }
6171 6160 break;
6172 6161 default:
6173 6162 break;
6174 6163 }
6175 6164 *new_pri_key_obj_p = pbk;
6176 6165 return (rv);
6177 6166 }
6178 6167
6179 6168 static void
6180 6169 free_domain_attr(domain_obj_t *domain, CK_KEY_TYPE key_type)
6181 6170 {
6182 6171 if (domain == NULL) {
6183 6172 return;
6184 6173 }
6185 6174
6186 6175 switch (key_type) {
6187 6176 case CKK_DSA:
6188 6177 bigint_attr_cleanup(KEY_DOM_DSA_PRIME(domain));
6189 6178 bigint_attr_cleanup(KEY_DOM_DSA_SUBPRIME(domain));
6190 6179 bigint_attr_cleanup(KEY_DOM_DSA_BASE(domain));
6191 6180 break;
6192 6181 case CKK_DH:
6193 6182 bigint_attr_cleanup(KEY_DOM_DH_PRIME(domain));
6194 6183 bigint_attr_cleanup(KEY_DOM_DH_BASE(domain));
6195 6184 break;
6196 6185 case CKK_X9_42_DH:
6197 6186 bigint_attr_cleanup(KEY_DOM_DH942_PRIME(domain));
6198 6187 bigint_attr_cleanup(KEY_DOM_DH942_SUBPRIME(domain));
6199 6188 bigint_attr_cleanup(KEY_DOM_DH942_BASE(domain));
6200 6189 break;
6201 6190 default:
6202 6191 break;
6203 6192 }
6204 6193 free(domain);
6205 6194 }
6206 6195
6207 6196 CK_RV
6208 6197 soft_copy_domain_attr(domain_obj_t *old_domain_obj_p,
6209 6198 domain_obj_t **new_domain_obj_p, CK_KEY_TYPE key_type)
6210 6199 {
6211 6200 CK_RV rv = CKR_OK;
6212 6201 domain_obj_t *domain;
6213 6202
6214 6203 domain = calloc(1, sizeof (domain_obj_t));
6215 6204 if (domain == NULL) {
6216 6205 return (CKR_HOST_MEMORY);
6217 6206 }
6218 6207
6219 6208 switch (key_type) {
6220 6209 case CKK_DSA:
6221 6210 (void) memcpy(KEY_DOM_DSA(domain),
6222 6211 KEY_DOM_DSA(old_domain_obj_p),
6223 6212 sizeof (dsa_dom_key_t));
6224 6213
6225 6214 /* copy prime */
6226 6215 rv = copy_bigint(KEY_DOM_DSA_PRIME(domain),
6227 6216 KEY_DOM_DSA_PRIME(old_domain_obj_p));
6228 6217 if (rv != CKR_OK) {
6229 6218 free_domain_attr(domain, key_type);
6230 6219 return (rv);
6231 6220 }
6232 6221
6233 6222 /* copy subprime */
6234 6223 rv = copy_bigint(KEY_DOM_DSA_SUBPRIME(domain),
6235 6224 KEY_DOM_DSA_SUBPRIME(old_domain_obj_p));
6236 6225 if (rv != CKR_OK) {
6237 6226 free_domain_attr(domain, key_type);
6238 6227 return (rv);
6239 6228 }
6240 6229
6241 6230 /* copy base */
6242 6231 rv = copy_bigint(KEY_DOM_DSA_BASE(domain),
6243 6232 KEY_DOM_DSA_BASE(old_domain_obj_p));
6244 6233 if (rv != CKR_OK) {
6245 6234 free_domain_attr(domain, key_type);
6246 6235 return (rv);
6247 6236 }
6248 6237
6249 6238 break;
6250 6239 case CKK_DH:
6251 6240 (void) memcpy(KEY_DOM_DH(domain),
6252 6241 KEY_DOM_DH(old_domain_obj_p),
6253 6242 sizeof (dh_dom_key_t));
6254 6243
6255 6244 /* copy prime */
6256 6245 rv = copy_bigint(KEY_DOM_DH_PRIME(domain),
6257 6246 KEY_DOM_DH_PRIME(old_domain_obj_p));
6258 6247 if (rv != CKR_OK) {
6259 6248 free_domain_attr(domain, key_type);
6260 6249 return (rv);
6261 6250 }
6262 6251
6263 6252 /* copy base */
6264 6253 rv = copy_bigint(KEY_DOM_DH_BASE(domain),
6265 6254 KEY_DOM_DH_BASE(old_domain_obj_p));
6266 6255 if (rv != CKR_OK) {
6267 6256 free_domain_attr(domain, key_type);
6268 6257 return (rv);
6269 6258 }
6270 6259
6271 6260 break;
6272 6261 case CKK_X9_42_DH:
6273 6262 (void) memcpy(KEY_DOM_DH942(domain),
6274 6263 KEY_DOM_DH942(old_domain_obj_p),
6275 6264 sizeof (dh942_dom_key_t));
6276 6265
6277 6266 /* copy prime */
6278 6267 rv = copy_bigint(KEY_DOM_DH942_PRIME(domain),
6279 6268 KEY_DOM_DH942_PRIME(old_domain_obj_p));
6280 6269 if (rv != CKR_OK) {
6281 6270 free_domain_attr(domain, key_type);
6282 6271 return (rv);
6283 6272 }
6284 6273
6285 6274 /* copy subprime */
6286 6275 rv = copy_bigint(KEY_DOM_DH942_SUBPRIME(domain),
6287 6276 KEY_DOM_DH942_SUBPRIME(old_domain_obj_p));
6288 6277 if (rv != CKR_OK) {
6289 6278 free_domain_attr(domain, key_type);
6290 6279 return (rv);
6291 6280 }
6292 6281
6293 6282 /* copy base */
6294 6283 rv = copy_bigint(KEY_DOM_DH942_BASE(domain),
6295 6284 KEY_DOM_DH942_BASE(old_domain_obj_p));
6296 6285 if (rv != CKR_OK) {
6297 6286 free_domain_attr(domain, key_type);
6298 6287 return (rv);
6299 6288 }
6300 6289
6301 6290 break;
6302 6291 default:
6303 6292 break;
6304 6293 }
6305 6294 *new_domain_obj_p = domain;
6306 6295 return (rv);
6307 6296 }
6308 6297
6309 6298 CK_RV
6310 6299 soft_copy_secret_key_attr(secret_key_obj_t *old_secret_key_obj_p,
6311 6300 secret_key_obj_t **new_secret_key_obj_p)
↓ open down ↓ |
5138 lines elided |
↑ open up ↑ |
6312 6301 {
6313 6302 secret_key_obj_t *sk;
6314 6303
6315 6304 sk = malloc(sizeof (secret_key_obj_t));
6316 6305 if (sk == NULL) {
6317 6306 return (CKR_HOST_MEMORY);
6318 6307 }
6319 6308 (void) memcpy(sk, old_secret_key_obj_p, sizeof (secret_key_obj_t));
6320 6309
6321 6310 /* copy the secret key value */
6322 - sk->sk_value = malloc((sizeof (CK_BYTE) * sk->sk_value_len));
6311 + sk->sk_value = malloc(sk->sk_value_len);
6323 6312 if (sk->sk_value == NULL) {
6324 6313 free(sk);
6325 6314 return (CKR_HOST_MEMORY);
6326 6315 }
6327 6316 (void) memcpy(sk->sk_value, old_secret_key_obj_p->sk_value,
6328 6317 (sizeof (CK_BYTE) * sk->sk_value_len));
6329 6318
6330 6319 /*
6331 6320 * Copy the pre-expanded key schedule.
6332 6321 */
6333 6322 if (old_secret_key_obj_p->key_sched != NULL &&
6334 6323 old_secret_key_obj_p->keysched_len > 0) {
6335 6324 sk->key_sched = malloc(old_secret_key_obj_p->keysched_len);
6336 6325 if (sk->key_sched == NULL) {
6326 + freezero(sk->sk_value, sk->sk_value_len);
6337 6327 free(sk);
6338 6328 return (CKR_HOST_MEMORY);
6339 6329 }
6340 6330 sk->keysched_len = old_secret_key_obj_p->keysched_len;
6341 6331 (void) memcpy(sk->key_sched, old_secret_key_obj_p->key_sched,
6342 6332 sk->keysched_len);
6343 6333 }
6344 6334
6345 6335 *new_secret_key_obj_p = sk;
6346 6336
6347 6337 return (CKR_OK);
6348 6338 }
6349 6339
6350 6340 /*
6351 6341 * If CKA_CLASS not given, guess CKA_CLASS using
6352 6342 * attributes on template .
6353 6343 *
6354 6344 * Some attributes are specific to an object class. If one or more
6355 6345 * of these attributes are in the template, make a list of classes
6356 6346 * that can have these attributes. This would speed up the search later,
6357 6347 * because we can immediately skip an object if the class of that
6358 6348 * object can not possibly contain one of the attributes.
6359 6349 *
6360 6350 */
6361 6351 void
6362 6352 soft_process_find_attr(CK_OBJECT_CLASS *pclasses,
6363 6353 CK_ULONG *num_result_pclasses, CK_ATTRIBUTE_PTR pTemplate,
6364 6354 CK_ULONG ulCount)
6365 6355 {
6366 6356 ulong_t i;
6367 6357 int j;
6368 6358 boolean_t pub_found = B_FALSE,
6369 6359 priv_found = B_FALSE,
6370 6360 secret_found = B_FALSE,
6371 6361 domain_found = B_FALSE,
6372 6362 hardware_found = B_FALSE,
6373 6363 cert_found = B_FALSE;
6374 6364 int num_pub_key_attrs, num_priv_key_attrs,
6375 6365 num_secret_key_attrs, num_domain_attrs,
6376 6366 num_hardware_attrs, num_cert_attrs;
6377 6367 int num_pclasses = 0;
6378 6368
6379 6369 for (i = 0; i < ulCount; i++) {
6380 6370 if (pTemplate[i].type == CKA_CLASS) {
6381 6371 /*
6382 6372 * don't need to guess the class, it is specified.
6383 6373 * Just record the class, and return.
6384 6374 */
6385 6375 pclasses[0] =
6386 6376 (*((CK_OBJECT_CLASS *)pTemplate[i].pValue));
6387 6377 *num_result_pclasses = 1;
6388 6378 return;
6389 6379 }
6390 6380 }
6391 6381
6392 6382 num_pub_key_attrs =
6393 6383 sizeof (PUB_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6394 6384 num_priv_key_attrs =
6395 6385 sizeof (PRIV_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6396 6386 num_secret_key_attrs =
6397 6387 sizeof (SECRET_KEY_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6398 6388 num_domain_attrs =
6399 6389 sizeof (DOMAIN_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6400 6390 num_hardware_attrs =
6401 6391 sizeof (HARDWARE_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6402 6392 num_cert_attrs =
6403 6393 sizeof (CERT_ATTRS) / sizeof (CK_ATTRIBUTE_TYPE);
6404 6394
6405 6395 /*
6406 6396 * Get the list of objects class that might contain
6407 6397 * some attributes.
6408 6398 */
6409 6399 for (i = 0; i < ulCount; i++) {
6410 6400 /*
6411 6401 * only check if this attribute can belong to public key object
6412 6402 * class if public key object isn't already in the list
6413 6403 */
6414 6404 if (!pub_found) {
6415 6405 for (j = 0; j < num_pub_key_attrs; j++) {
6416 6406 if (pTemplate[i].type == PUB_KEY_ATTRS[j]) {
6417 6407 pub_found = B_TRUE;
6418 6408 pclasses[num_pclasses++] =
6419 6409 CKO_PUBLIC_KEY;
6420 6410 break;
6421 6411 }
6422 6412 }
6423 6413 }
6424 6414
6425 6415 if (!priv_found) {
6426 6416 for (j = 0; j < num_priv_key_attrs; j++) {
6427 6417 if (pTemplate[i].type == PRIV_KEY_ATTRS[j]) {
6428 6418 priv_found = B_TRUE;
6429 6419 pclasses[num_pclasses++] =
6430 6420 CKO_PRIVATE_KEY;
6431 6421 break;
6432 6422 }
6433 6423 }
6434 6424 }
6435 6425
6436 6426 if (!secret_found) {
6437 6427 for (j = 0; j < num_secret_key_attrs; j++) {
6438 6428 if (pTemplate[i].type == SECRET_KEY_ATTRS[j]) {
6439 6429 secret_found = B_TRUE;
6440 6430 pclasses[num_pclasses++] =
6441 6431 CKO_SECRET_KEY;
6442 6432 break;
6443 6433 }
6444 6434 }
6445 6435 }
6446 6436
6447 6437 if (!domain_found) {
6448 6438 for (j = 0; j < num_domain_attrs; j++) {
6449 6439 if (pTemplate[i].type == DOMAIN_ATTRS[j]) {
6450 6440 domain_found = B_TRUE;
6451 6441 pclasses[num_pclasses++] =
6452 6442 CKO_DOMAIN_PARAMETERS;
6453 6443 break;
6454 6444 }
6455 6445 }
6456 6446 }
6457 6447
6458 6448 if (!hardware_found) {
6459 6449 for (j = 0; j < num_hardware_attrs; j++) {
6460 6450 if (pTemplate[i].type == HARDWARE_ATTRS[j]) {
6461 6451 hardware_found = B_TRUE;
6462 6452 pclasses[num_pclasses++] =
6463 6453 CKO_HW_FEATURE;
6464 6454 break;
6465 6455 }
6466 6456 }
6467 6457 }
6468 6458
6469 6459 if (!cert_found) {
6470 6460 for (j = 0; j < num_cert_attrs; j++) {
6471 6461 if (pTemplate[i].type == CERT_ATTRS[j]) {
6472 6462 cert_found = B_TRUE;
6473 6463 pclasses[num_pclasses++] =
6474 6464 CKO_CERTIFICATE;
6475 6465 break;
6476 6466 }
6477 6467 }
6478 6468 }
6479 6469 }
6480 6470 *num_result_pclasses = num_pclasses;
6481 6471 }
6482 6472
6483 6473 boolean_t
6484 6474 soft_find_match_attrs(soft_object_t *obj, CK_OBJECT_CLASS *pclasses,
6485 6475 CK_ULONG num_pclasses, CK_ATTRIBUTE *template, CK_ULONG num_attr)
6486 6476 {
6487 6477 ulong_t i;
6488 6478 CK_ATTRIBUTE *tmpl_attr, *obj_attr;
6489 6479 cert_attr_t *cert_attr;
6490 6480 uint64_t attr_mask;
6491 6481 biginteger_t *bigint;
6492 6482 boolean_t compare_attr, compare_bigint, compare_boolean;
6493 6483 boolean_t compare_cert_val, compare_cert_type;
6494 6484
6495 6485 /*
6496 6486 * Check if the class of this object match with any
6497 6487 * of object classes that can possibly contain the
6498 6488 * requested attributes.
6499 6489 */
6500 6490 if (num_pclasses > 0) {
6501 6491 for (i = 0; i < num_pclasses; i++) {
6502 6492 if (obj->class == pclasses[i]) {
6503 6493 break;
6504 6494 }
6505 6495 }
6506 6496 if (i == num_pclasses) {
6507 6497 /*
6508 6498 * this object can't possibly contain one or
6509 6499 * more attributes, don't need to check this object
6510 6500 */
6511 6501 return (B_FALSE);
6512 6502 }
6513 6503 }
6514 6504
6515 6505 /* need to examine everything */
6516 6506 for (i = 0; i < num_attr; i++) {
6517 6507 tmpl_attr = &(template[i]);
6518 6508 compare_attr = B_FALSE;
6519 6509 compare_bigint = B_FALSE;
6520 6510 compare_boolean = B_FALSE;
6521 6511 compare_cert_val = B_FALSE;
6522 6512 compare_cert_type = B_FALSE;
6523 6513 switch (tmpl_attr->type) {
6524 6514 /* First, check the most common attributes */
6525 6515 case CKA_CLASS:
6526 6516 if (*((CK_OBJECT_CLASS *)tmpl_attr->pValue) !=
6527 6517 obj->class) {
6528 6518 return (B_FALSE);
6529 6519 }
6530 6520 break;
6531 6521 case CKA_KEY_TYPE:
6532 6522 if (*((CK_KEY_TYPE *)tmpl_attr->pValue) !=
6533 6523 obj->key_type) {
6534 6524 return (B_FALSE);
6535 6525 }
6536 6526 break;
6537 6527 case CKA_ENCRYPT:
6538 6528 attr_mask = (obj->bool_attr_mask) & ENCRYPT_BOOL_ON;
6539 6529 compare_boolean = B_TRUE;
6540 6530 break;
6541 6531 case CKA_DECRYPT:
6542 6532 attr_mask = (obj->bool_attr_mask) & DECRYPT_BOOL_ON;
6543 6533 compare_boolean = B_TRUE;
6544 6534 break;
6545 6535 case CKA_WRAP:
6546 6536 attr_mask = (obj->bool_attr_mask) & WRAP_BOOL_ON;
6547 6537 compare_boolean = B_TRUE;
6548 6538 break;
6549 6539 case CKA_UNWRAP:
6550 6540 attr_mask = (obj->bool_attr_mask) & UNWRAP_BOOL_ON;
6551 6541 compare_boolean = B_TRUE;
6552 6542 break;
6553 6543 case CKA_SIGN:
6554 6544 attr_mask = (obj->bool_attr_mask) & SIGN_BOOL_ON;
6555 6545 compare_boolean = B_TRUE;
6556 6546 break;
6557 6547 case CKA_SIGN_RECOVER:
6558 6548 attr_mask = (obj->bool_attr_mask) &
6559 6549 SIGN_RECOVER_BOOL_ON;
6560 6550 compare_boolean = B_TRUE;
6561 6551 break;
6562 6552 case CKA_VERIFY:
6563 6553 attr_mask = (obj->bool_attr_mask) & VERIFY_BOOL_ON;
6564 6554 compare_boolean = B_TRUE;
6565 6555 break;
6566 6556 case CKA_VERIFY_RECOVER:
6567 6557 attr_mask = (obj->bool_attr_mask) &
6568 6558 VERIFY_RECOVER_BOOL_ON;
6569 6559 compare_boolean = B_TRUE;
6570 6560 break;
6571 6561 case CKA_DERIVE:
6572 6562 attr_mask = (obj->bool_attr_mask) & DERIVE_BOOL_ON;
6573 6563 compare_boolean = B_TRUE;
6574 6564 break;
6575 6565 case CKA_LOCAL:
6576 6566 attr_mask = (obj->bool_attr_mask) & LOCAL_BOOL_ON;
6577 6567 compare_boolean = B_TRUE;
6578 6568 break;
6579 6569 case CKA_SENSITIVE:
6580 6570 attr_mask = (obj->bool_attr_mask) & SENSITIVE_BOOL_ON;
6581 6571 compare_boolean = B_TRUE;
6582 6572 break;
6583 6573 case CKA_SECONDARY_AUTH:
6584 6574 attr_mask = (obj->bool_attr_mask) &
6585 6575 SECONDARY_AUTH_BOOL_ON;
6586 6576 compare_boolean = B_TRUE;
6587 6577 break;
6588 6578 case CKA_TRUSTED:
6589 6579 attr_mask = (obj->bool_attr_mask) & TRUSTED_BOOL_ON;
6590 6580 compare_boolean = B_TRUE;
6591 6581 break;
6592 6582 case CKA_EXTRACTABLE:
6593 6583 attr_mask = (obj->bool_attr_mask) &
6594 6584 EXTRACTABLE_BOOL_ON;
6595 6585 compare_boolean = B_TRUE;
6596 6586 break;
6597 6587 case CKA_ALWAYS_SENSITIVE:
6598 6588 attr_mask = (obj->bool_attr_mask) &
6599 6589 ALWAYS_SENSITIVE_BOOL_ON;
6600 6590 compare_boolean = B_TRUE;
6601 6591 break;
6602 6592 case CKA_NEVER_EXTRACTABLE:
6603 6593 attr_mask = (obj->bool_attr_mask) &
6604 6594 NEVER_EXTRACTABLE_BOOL_ON;
6605 6595 compare_boolean = B_TRUE;
6606 6596 break;
6607 6597 case CKA_TOKEN:
6608 6598 attr_mask = (obj->object_type) & TOKEN_OBJECT;
6609 6599 compare_boolean = B_TRUE;
6610 6600 break;
6611 6601 case CKA_PRIVATE:
6612 6602 attr_mask = (obj->object_type) & PRIVATE_OBJECT;
6613 6603 compare_boolean = B_TRUE;
6614 6604 break;
6615 6605 case CKA_MODIFIABLE:
6616 6606 {
6617 6607 CK_BBOOL bval;
6618 6608 attr_mask = (obj->bool_attr_mask) &
6619 6609 NOT_MODIFIABLE_BOOL_ON;
6620 6610
6621 6611 if (attr_mask) {
6622 6612 bval = FALSE;
6623 6613 } else {
6624 6614 bval = TRUE;
6625 6615 }
6626 6616 if (bval != *((CK_BBOOL *)tmpl_attr->pValue)) {
6627 6617 return (B_FALSE);
6628 6618 }
6629 6619 break;
6630 6620 }
6631 6621 case CKA_OWNER:
6632 6622 /*
6633 6623 * For X.509 attribute certificate object, get its
6634 6624 * CKA_OWNER attribute from the x509_attr_cert_t struct.
6635 6625 */
6636 6626 if ((obj->class == CKO_CERTIFICATE) &&
6637 6627 (obj->cert_type == CKC_X_509_ATTR_CERT)) {
6638 6628 cert_attr = X509_ATTR_CERT_OWNER(obj);
6639 6629 compare_cert_val = B_TRUE;
6640 6630 }
6641 6631 break;
6642 6632 case CKA_SUBJECT:
6643 6633 /*
6644 6634 * For X.509 certificate object, get its CKA_SUBJECT
6645 6635 * attribute from the x509_cert_t struct (not from
6646 6636 * the extra_attrlistp).
6647 6637 */
6648 6638 if ((obj->class == CKO_CERTIFICATE) &&
6649 6639 (obj->cert_type == CKC_X_509)) {
6650 6640 cert_attr = X509_CERT_SUBJECT(obj);
6651 6641 compare_cert_val = B_TRUE;
6652 6642 break;
6653 6643 }
6654 6644 /*FALLTHRU*/
6655 6645 case CKA_ID:
6656 6646 case CKA_START_DATE:
6657 6647 case CKA_END_DATE:
6658 6648 case CKA_KEY_GEN_MECHANISM:
6659 6649 case CKA_LABEL:
6660 6650 case CKA_ISSUER:
6661 6651 case CKA_SERIAL_NUMBER:
6662 6652 case CKA_AC_ISSUER:
6663 6653 case CKA_ATTR_TYPES:
6664 6654 /* find these attributes from extra_attrlistp */
6665 6655 obj_attr = get_extra_attr(tmpl_attr->type, obj);
6666 6656 compare_attr = B_TRUE;
6667 6657 break;
6668 6658 case CKA_CERTIFICATE_TYPE:
6669 6659 compare_cert_type = B_TRUE;
6670 6660 break;
6671 6661 case CKA_VALUE_LEN:
6672 6662 /* only secret key has this attribute */
6673 6663 if (obj->class == CKO_SECRET_KEY) {
6674 6664 if (*((CK_ULONG *)tmpl_attr->pValue) !=
6675 6665 OBJ_SEC_VALUE_LEN(obj)) {
6676 6666 return (B_FALSE);
6677 6667 }
6678 6668 } else {
6679 6669 return (B_FALSE);
6680 6670 }
6681 6671 break;
6682 6672 case CKA_VALUE:
6683 6673 switch (obj->class) {
6684 6674 case CKO_SECRET_KEY:
6685 6675 /*
6686 6676 * secret_key_obj_t is the same as
6687 6677 * biginteger_t
6688 6678 */
6689 6679 bigint = (biginteger_t *)OBJ_SEC(obj);
6690 6680 compare_bigint = B_TRUE;
6691 6681 break;
6692 6682 case CKO_PRIVATE_KEY:
6693 6683 if (obj->key_type == CKK_DSA) {
6694 6684 bigint = OBJ_PRI_DSA_VALUE(obj);
6695 6685 } else if (obj->key_type == CKK_DH) {
6696 6686 bigint = OBJ_PRI_DH_VALUE(obj);
6697 6687 } else if (obj->key_type == CKK_X9_42_DH) {
6698 6688 bigint = OBJ_PRI_DH942_VALUE(obj);
6699 6689 } else {
6700 6690 return (B_FALSE);
6701 6691 }
6702 6692 compare_bigint = B_TRUE;
6703 6693 break;
6704 6694 case CKO_PUBLIC_KEY:
6705 6695 if (obj->key_type == CKK_DSA) {
6706 6696 bigint = OBJ_PUB_DSA_VALUE(obj);
6707 6697 } else if (obj->key_type == CKK_DH) {
6708 6698 bigint = OBJ_PUB_DH_VALUE(obj);
6709 6699 } else if (obj->key_type == CKK_X9_42_DH) {
6710 6700 bigint = OBJ_PUB_DH942_VALUE(obj);
6711 6701 } else {
6712 6702 return (B_FALSE);
6713 6703 }
6714 6704 compare_bigint = B_TRUE;
6715 6705 break;
6716 6706 case CKO_CERTIFICATE:
6717 6707 if (obj->cert_type == CKC_X_509) {
6718 6708 cert_attr = X509_CERT_VALUE(obj);
6719 6709 } else if (obj->cert_type ==
6720 6710 CKC_X_509_ATTR_CERT) {
6721 6711 cert_attr = X509_ATTR_CERT_VALUE(obj);
6722 6712 }
6723 6713 compare_cert_val = B_TRUE;
6724 6714 break;
6725 6715 default:
6726 6716 return (B_FALSE);
6727 6717 }
6728 6718 break;
6729 6719 case CKA_MODULUS:
6730 6720 /* only RSA public and private key have this attr */
6731 6721 if (obj->key_type == CKK_RSA) {
6732 6722 if (obj->class == CKO_PUBLIC_KEY) {
6733 6723 bigint = OBJ_PUB_RSA_MOD(obj);
6734 6724 } else if (obj->class == CKO_PRIVATE_KEY) {
6735 6725 bigint = OBJ_PRI_RSA_MOD(obj);
6736 6726 } else {
6737 6727 return (B_FALSE);
6738 6728 }
6739 6729 compare_bigint = B_TRUE;
6740 6730 } else {
6741 6731 return (B_FALSE);
6742 6732 }
6743 6733 break;
6744 6734 case CKA_MODULUS_BITS:
6745 6735 /* only RSA public key has this attribute */
6746 6736 if ((obj->key_type == CKK_RSA) &&
6747 6737 (obj->class == CKO_PUBLIC_KEY)) {
6748 6738 CK_ULONG mod_bits = OBJ_PUB_RSA_MOD_BITS(obj);
6749 6739 if (mod_bits !=
6750 6740 *((CK_ULONG *)tmpl_attr->pValue)) {
6751 6741 return (B_FALSE);
6752 6742 }
6753 6743 } else {
6754 6744 return (B_FALSE);
6755 6745 }
6756 6746 break;
6757 6747 case CKA_PUBLIC_EXPONENT:
6758 6748 /* only RSA public and private key have this attr */
6759 6749 if (obj->key_type == CKK_RSA) {
6760 6750 if (obj->class == CKO_PUBLIC_KEY) {
6761 6751 bigint = OBJ_PUB_RSA_PUBEXPO(obj);
6762 6752 } else if (obj->class == CKO_PRIVATE_KEY) {
6763 6753 bigint = OBJ_PRI_RSA_PUBEXPO(obj);
6764 6754 } else {
6765 6755 return (B_FALSE);
6766 6756 }
6767 6757 compare_bigint = B_TRUE;
6768 6758 } else {
6769 6759 return (B_FALSE);
6770 6760 }
6771 6761 break;
6772 6762 case CKA_PRIVATE_EXPONENT:
6773 6763 /* only RSA private key has this attribute */
6774 6764 if ((obj->key_type == CKK_RSA) &&
6775 6765 (obj->class == CKO_PRIVATE_KEY)) {
6776 6766 bigint = OBJ_PRI_RSA_PRIEXPO(obj);
6777 6767 compare_bigint = B_TRUE;
6778 6768 } else {
6779 6769 return (B_FALSE);
6780 6770 }
6781 6771 break;
6782 6772 case CKA_PRIME_1:
6783 6773 /* only RSA private key has this attribute */
6784 6774 if ((obj->key_type == CKK_RSA) &&
6785 6775 (obj->class == CKO_PRIVATE_KEY)) {
6786 6776 bigint = OBJ_PRI_RSA_PRIME1(obj);
6787 6777 compare_bigint = B_TRUE;
6788 6778 } else {
6789 6779 return (B_FALSE);
6790 6780 }
6791 6781 break;
6792 6782 case CKA_PRIME_2:
6793 6783 /* only RSA private key has this attribute */
6794 6784 if ((obj->key_type == CKK_RSA) &&
6795 6785 (obj->class == CKO_PRIVATE_KEY)) {
6796 6786 bigint = OBJ_PRI_RSA_PRIME2(obj);
6797 6787 compare_bigint = B_TRUE;
6798 6788 } else {
6799 6789 return (B_FALSE);
6800 6790 }
6801 6791 break;
6802 6792 case CKA_EXPONENT_1:
6803 6793 /* only RSA private key has this attribute */
6804 6794 if ((obj->key_type == CKK_RSA) &&
6805 6795 (obj->class == CKO_PRIVATE_KEY)) {
6806 6796 bigint = OBJ_PRI_RSA_EXPO1(obj);
6807 6797 compare_bigint = B_TRUE;
6808 6798 } else {
6809 6799 return (B_FALSE);
6810 6800 }
6811 6801 break;
6812 6802 case CKA_EXPONENT_2:
6813 6803 /* only RSA private key has this attribute */
6814 6804 if ((obj->key_type == CKK_RSA) &&
6815 6805 (obj->class == CKO_PRIVATE_KEY)) {
6816 6806 bigint = OBJ_PRI_RSA_EXPO2(obj);
6817 6807 compare_bigint = B_TRUE;
6818 6808 } else {
6819 6809 return (B_FALSE);
6820 6810 }
6821 6811 break;
6822 6812 case CKA_COEFFICIENT:
6823 6813 /* only RSA private key has this attribute */
6824 6814 if ((obj->key_type == CKK_RSA) &&
6825 6815 (obj->class == CKO_PRIVATE_KEY)) {
6826 6816 bigint = OBJ_PRI_RSA_COEF(obj);
6827 6817 compare_bigint = B_TRUE;
6828 6818 } else {
6829 6819 return (B_FALSE);
6830 6820 }
6831 6821 break;
6832 6822 case CKA_VALUE_BITS:
6833 6823 /* only Diffie-Hellman private key has this attr */
6834 6824 if ((obj->key_type == CKK_DH) &&
6835 6825 (obj->class == CKO_PRIVATE_KEY)) {
6836 6826 CK_ULONG val_bits = OBJ_PRI_DH_VAL_BITS(obj);
6837 6827 if (val_bits !=
6838 6828 *((CK_ULONG *)tmpl_attr->pValue)) {
6839 6829 return (B_FALSE);
6840 6830 }
6841 6831 } else {
6842 6832 return (B_FALSE);
6843 6833 }
6844 6834 break;
6845 6835 case CKA_PRIME:
6846 6836 if (obj->class == CKO_PUBLIC_KEY) {
6847 6837 switch (obj->key_type) {
6848 6838 case CKK_DSA:
6849 6839 bigint = OBJ_PUB_DSA_PRIME(obj);
6850 6840 break;
6851 6841 case CKK_DH:
6852 6842 bigint = OBJ_PUB_DH_PRIME(obj);
6853 6843 break;
6854 6844 case CKK_X9_42_DH:
6855 6845 bigint = OBJ_PUB_DH942_PRIME(obj);
6856 6846 break;
6857 6847 default:
6858 6848 return (B_FALSE);
6859 6849 }
6860 6850 } else if (obj->class == CKO_PRIVATE_KEY) {
6861 6851 switch (obj->key_type) {
6862 6852 case CKK_DSA:
6863 6853 bigint = OBJ_PRI_DSA_PRIME(obj);
6864 6854 break;
6865 6855 case CKK_DH:
6866 6856 bigint = OBJ_PRI_DH_PRIME(obj);
6867 6857 break;
6868 6858 case CKK_X9_42_DH:
6869 6859 bigint = OBJ_PRI_DH942_PRIME(obj);
6870 6860 break;
6871 6861 default:
6872 6862 return (B_FALSE);
6873 6863 }
6874 6864 } else if (obj->class == CKO_DOMAIN_PARAMETERS) {
6875 6865 switch (obj->key_type) {
6876 6866 case CKK_DSA:
6877 6867 bigint = OBJ_DOM_DSA_PRIME(obj);
6878 6868 break;
6879 6869 case CKK_DH:
6880 6870 bigint = OBJ_DOM_DH_PRIME(obj);
6881 6871 break;
6882 6872 case CKK_X9_42_DH:
6883 6873 bigint = OBJ_DOM_DH942_PRIME(obj);
6884 6874 break;
6885 6875 default:
6886 6876 return (B_FALSE);
6887 6877 }
6888 6878 } else {
6889 6879 return (B_FALSE);
6890 6880 }
6891 6881 compare_bigint = B_TRUE;
6892 6882 break;
6893 6883 case CKA_SUBPRIME:
6894 6884 if (obj->class == CKO_PUBLIC_KEY) {
6895 6885 switch (obj->key_type) {
6896 6886 case CKK_DSA:
6897 6887 bigint = OBJ_PUB_DSA_SUBPRIME(obj);
6898 6888 break;
6899 6889 case CKK_X9_42_DH:
6900 6890 bigint = OBJ_PUB_DH942_SUBPRIME(obj);
6901 6891 break;
6902 6892 default:
6903 6893 return (B_FALSE);
6904 6894 }
6905 6895 } else if (obj->class == CKO_PRIVATE_KEY) {
6906 6896 switch (obj->key_type) {
6907 6897 case CKK_DSA:
6908 6898 bigint = OBJ_PRI_DSA_SUBPRIME(obj);
6909 6899 break;
6910 6900 case CKK_X9_42_DH:
6911 6901 bigint = OBJ_PRI_DH942_SUBPRIME(obj);
6912 6902 break;
6913 6903 default:
6914 6904 return (B_FALSE);
6915 6905 }
6916 6906 } else if (obj->class == CKO_DOMAIN_PARAMETERS) {
6917 6907 switch (obj->key_type) {
6918 6908 case CKK_DSA:
6919 6909 bigint = OBJ_DOM_DSA_SUBPRIME(obj);
6920 6910 break;
6921 6911 case CKK_X9_42_DH:
6922 6912 bigint = OBJ_DOM_DH942_SUBPRIME(obj);
6923 6913 break;
6924 6914 default:
6925 6915 return (B_FALSE);
6926 6916 }
6927 6917 } else {
6928 6918 return (B_FALSE);
6929 6919 }
6930 6920 compare_bigint = B_TRUE;
6931 6921 break;
6932 6922 case CKA_BASE:
6933 6923 if (obj->class == CKO_PUBLIC_KEY) {
6934 6924 switch (obj->key_type) {
6935 6925 case CKK_DSA:
6936 6926 bigint = OBJ_PUB_DSA_BASE(obj);
6937 6927 break;
6938 6928 case CKK_DH:
6939 6929 bigint = OBJ_PUB_DH_BASE(obj);
6940 6930 break;
6941 6931 case CKK_X9_42_DH:
6942 6932 bigint = OBJ_PUB_DH942_BASE(obj);
6943 6933 break;
6944 6934 default:
6945 6935 return (B_FALSE);
6946 6936 }
6947 6937 } else if (obj->class == CKO_PRIVATE_KEY) {
6948 6938 switch (obj->key_type) {
6949 6939 case CKK_DSA:
6950 6940 bigint = OBJ_PRI_DSA_BASE(obj);
6951 6941 break;
6952 6942 case CKK_DH:
6953 6943 bigint = OBJ_PRI_DH_BASE(obj);
6954 6944 break;
6955 6945 case CKK_X9_42_DH:
6956 6946 bigint = OBJ_PRI_DH942_BASE(obj);
6957 6947 break;
6958 6948 default:
6959 6949 return (B_FALSE);
6960 6950 }
6961 6951 } else if (obj->class == CKO_DOMAIN_PARAMETERS) {
6962 6952 switch (obj->key_type) {
6963 6953 case CKK_DSA:
6964 6954 bigint = OBJ_DOM_DSA_BASE(obj);
6965 6955 break;
6966 6956 case CKK_DH:
6967 6957 bigint = OBJ_DOM_DH_BASE(obj);
6968 6958 break;
6969 6959 case CKK_X9_42_DH:
6970 6960 bigint = OBJ_DOM_DH942_BASE(obj);
6971 6961 break;
6972 6962 default:
6973 6963 return (B_FALSE);
6974 6964 }
6975 6965 } else {
6976 6966 return (B_FALSE);
6977 6967 }
6978 6968 compare_bigint = B_TRUE;
6979 6969 break;
6980 6970 case CKA_PRIME_BITS:
6981 6971 if (obj->class == CKO_DOMAIN_PARAMETERS) {
6982 6972 CK_ULONG prime_bits;
6983 6973 if (obj->key_type == CKK_DSA) {
6984 6974 prime_bits =
6985 6975 OBJ_DOM_DSA_PRIME_BITS(obj);
6986 6976 } else if (obj->key_type == CKK_DH) {
6987 6977 prime_bits =
6988 6978 OBJ_DOM_DH_PRIME_BITS(obj);
6989 6979 } else if (obj->key_type == CKK_X9_42_DH) {
6990 6980 prime_bits =
6991 6981 OBJ_DOM_DH942_PRIME_BITS(obj);
6992 6982 } else {
6993 6983 return (B_FALSE);
6994 6984 }
6995 6985 if (prime_bits !=
6996 6986 *((CK_ULONG *)tmpl_attr->pValue)) {
6997 6987 return (B_FALSE);
6998 6988 }
6999 6989 } else {
7000 6990 return (B_FALSE);
7001 6991 }
7002 6992 break;
7003 6993 case CKA_SUBPRIME_BITS:
7004 6994 if ((obj->class == CKO_DOMAIN_PARAMETERS) &&
7005 6995 (obj->key_type == CKK_X9_42_DH)) {
7006 6996 CK_ULONG subprime_bits =
7007 6997 OBJ_DOM_DH942_SUBPRIME_BITS(obj);
7008 6998 if (subprime_bits !=
7009 6999 *((CK_ULONG *)tmpl_attr->pValue)) {
7010 7000 return (B_FALSE);
7011 7001 }
7012 7002 } else {
7013 7003 return (B_FALSE);
7014 7004 }
7015 7005 break;
7016 7006 default:
7017 7007 /*
7018 7008 * any other attributes are currently not supported.
7019 7009 * so, it's not possible for them to be in the
7020 7010 * object
7021 7011 */
7022 7012 return (B_FALSE);
7023 7013 }
7024 7014 if (compare_boolean) {
7025 7015 CK_BBOOL bval;
7026 7016
7027 7017 if (attr_mask) {
7028 7018 bval = TRUE;
7029 7019 } else {
7030 7020 bval = FALSE;
7031 7021 }
7032 7022 if (bval != *((CK_BBOOL *)tmpl_attr->pValue)) {
7033 7023 return (B_FALSE);
7034 7024 }
7035 7025 } else if (compare_bigint) {
7036 7026 if (bigint == NULL) {
7037 7027 return (B_FALSE);
7038 7028 }
7039 7029 if (tmpl_attr->ulValueLen != bigint->big_value_len) {
7040 7030 return (B_FALSE);
7041 7031 }
7042 7032 if (memcmp(tmpl_attr->pValue, bigint->big_value,
7043 7033 tmpl_attr->ulValueLen) != 0) {
7044 7034 return (B_FALSE);
7045 7035 }
7046 7036 } else if (compare_attr) {
7047 7037 if (obj_attr == NULL) {
7048 7038 /*
7049 7039 * The attribute type is valid, and its value
7050 7040 * has not been initialized in the object. In
7051 7041 * this case, it only matches the template's
7052 7042 * attribute if the template's value length
7053 7043 * is 0.
7054 7044 */
7055 7045 if (tmpl_attr->ulValueLen != 0)
7056 7046 return (B_FALSE);
7057 7047 } else {
7058 7048 if (tmpl_attr->ulValueLen !=
7059 7049 obj_attr->ulValueLen) {
7060 7050 return (B_FALSE);
7061 7051 }
7062 7052 if (memcmp(tmpl_attr->pValue, obj_attr->pValue,
7063 7053 tmpl_attr->ulValueLen) != 0) {
7064 7054 return (B_FALSE);
7065 7055 }
7066 7056 }
7067 7057 } else if (compare_cert_val) {
7068 7058 if (cert_attr == NULL) {
7069 7059 /* specific attribute not found */
7070 7060 return (B_FALSE);
7071 7061 }
7072 7062 if (tmpl_attr->ulValueLen != cert_attr->length) {
7073 7063 return (B_FALSE);
7074 7064 }
7075 7065 if (memcmp(tmpl_attr->pValue, cert_attr->value,
7076 7066 tmpl_attr->ulValueLen) != 0) {
7077 7067 return (B_FALSE);
7078 7068 }
7079 7069 } else if (compare_cert_type) {
7080 7070 if (memcmp(tmpl_attr->pValue, &(obj->cert_type),
7081 7071 tmpl_attr->ulValueLen) != 0) {
7082 7072 return (B_FALSE);
7083 7073 }
7084 7074 }
7085 7075 }
7086 7076 return (B_TRUE);
7087 7077 }
7088 7078
7089 7079 CK_ATTRIBUTE_PTR
7090 7080 get_extra_attr(CK_ATTRIBUTE_TYPE type, soft_object_t *obj)
7091 7081 {
7092 7082 CK_ATTRIBUTE_INFO_PTR tmp;
7093 7083
7094 7084 tmp = obj->extra_attrlistp;
7095 7085 while (tmp != NULL) {
7096 7086 if (tmp->attr.type == type) {
7097 7087 return (&(tmp->attr));
7098 7088 }
7099 7089 tmp = tmp->next;
7100 7090 }
7101 7091 /* if get there, the specified attribute is not found */
7102 7092 return (NULL);
7103 7093 }
↓ open down ↓ |
757 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX