1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * PKCS11 token KMF Plugin 23 * 24 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 #include <stdio.h> /* debugging only */ 29 #include <errno.h> 30 #include <values.h> 31 32 #include <kmfapiP.h> 33 #include <ber_der.h> 34 #include <algorithm.h> 35 #include <fcntl.h> 36 #include <sha1.h> 37 #include <bignum.h> 38 39 #include <cryptoutil.h> 40 #include <security/cryptoki.h> 41 #include <security/pkcs11.h> 42 43 #define DEV_RANDOM "/dev/random" 44 45 #define SETATTR(t, n, atype, value, size) \ 46 t[n].type = atype; \ 47 t[n].pValue = (CK_BYTE *)value; \ 48 t[n].ulValueLen = (CK_ULONG)size; 49 50 #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; \ 51 h->lasterr.errcode = c; 52 53 typedef struct _objlist { 54 CK_OBJECT_HANDLE handle; 55 struct _objlist *next; 56 } OBJLIST; 57 58 static KMF_RETURN 59 search_certs(KMF_HANDLE_T, char *, char *, char *, KMF_BIGINT *, 60 boolean_t, KMF_CERT_VALIDITY, OBJLIST **, uint32_t *); 61 62 static CK_RV 63 getObjectLabel(KMF_HANDLE_T, CK_OBJECT_HANDLE, char **); 64 65 static KMF_RETURN 66 keyObj2RawKey(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_KEY_DATA **); 67 68 static KMF_RETURN 69 create_generic_secret_key(KMF_HANDLE_T, 70 int, KMF_ATTRIBUTE *, CK_OBJECT_HANDLE *); 71 72 KMF_RETURN 73 KMFPK11_ConfigureKeystore(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 74 75 KMF_RETURN 76 KMFPK11_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 77 78 void 79 KMFPK11_FreeKMFCert(KMF_HANDLE_T, 80 KMF_X509_DER_CERT *kmf_cert); 81 82 KMF_RETURN 83 KMFPK11_StoreCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 84 85 KMF_RETURN 86 KMFPK11_ImportCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 87 88 KMF_RETURN 89 KMFPK11_DeleteCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 90 91 KMF_RETURN 92 KMFPK11_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 93 94 KMF_RETURN 95 KMFPK11_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 96 97 KMF_RETURN 98 KMFPK11_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 99 100 KMF_RETURN 101 KMFPK11_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *); 102 103 KMF_RETURN 104 KMFPK11_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 105 KMF_DATA *, KMF_DATA *); 106 107 KMF_RETURN 108 KMFPK11_GetErrorString(KMF_HANDLE_T, char **); 109 110 KMF_RETURN 111 KMFPK11_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 112 113 KMF_RETURN 114 KMFPK11_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 115 KMF_DATA *, KMF_DATA *); 116 117 KMF_RETURN 118 KMFPK11_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 119 120 KMF_RETURN 121 KMFPK11_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 122 123 KMF_RETURN 124 KMFPK11_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *); 125 126 KMF_RETURN 127 KMFPK11_SetTokenPin(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 128 129 KMF_RETURN 130 KMFPK11_VerifyDataWithCert(KMF_HANDLE_T, KMF_ALGORITHM_INDEX, KMF_DATA *, 131 KMF_DATA *, KMF_DATA *); 132 133 KMF_RETURN 134 KMFPK11_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 135 136 137 static 138 KMF_PLUGIN_FUNCLIST pk11token_plugin_table = 139 { 140 1, /* Version */ 141 KMFPK11_ConfigureKeystore, 142 KMFPK11_FindCert, 143 KMFPK11_FreeKMFCert, 144 KMFPK11_StoreCert, 145 KMFPK11_ImportCert, 146 NULL, /* ImportCRL */ 147 KMFPK11_DeleteCert, 148 NULL, /* DeleteCRL */ 149 KMFPK11_CreateKeypair, 150 KMFPK11_FindKey, 151 KMFPK11_EncodePubKeyData, 152 KMFPK11_SignData, 153 KMFPK11_DeleteKey, 154 NULL, /* ListCRL */ 155 NULL, /* FindCRL */ 156 NULL, /* FindCertInCRL */ 157 KMFPK11_GetErrorString, 158 KMFPK11_FindPrikeyByCert, 159 KMFPK11_DecryptData, 160 KMFPK11_ExportPK12, 161 KMFPK11_CreateSymKey, 162 KMFPK11_GetSymKeyValue, 163 KMFPK11_SetTokenPin, 164 KMFPK11_VerifyDataWithCert, 165 KMFPK11_StoreKey, 166 NULL /* Finalize */ 167 }; 168 169 KMF_PLUGIN_FUNCLIST * 170 KMF_Plugin_Initialize() 171 { 172 return (&pk11token_plugin_table); 173 } 174 175 KMF_RETURN 176 KMFPK11_ConfigureKeystore(KMF_HANDLE_T handle, 177 int numattr, KMF_ATTRIBUTE *attrlist) 178 { 179 KMF_RETURN rv = KMF_OK; 180 char *label; 181 boolean_t readonly = B_TRUE; 182 183 label = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, numattr); 184 if (label == NULL) { 185 return (KMF_ERR_BAD_PARAMETER); 186 } 187 188 /* "readonly" is optional. Default is TRUE */ 189 (void) kmf_get_attr(KMF_READONLY_ATTR, attrlist, numattr, 190 (void *)&readonly, NULL); 191 192 rv = kmf_select_token(handle, label, readonly); 193 194 return (rv); 195 } 196 197 static KMF_RETURN 198 pk11_authenticate(KMF_HANDLE_T handle, 199 KMF_CREDENTIAL *cred) 200 { 201 202 CK_RV ck_rv = CKR_OK; 203 CK_SESSION_HANDLE hSession = (CK_SESSION_HANDLE)handle->pk11handle; 204 205 if (hSession == NULL) 206 return (KMF_ERR_NO_TOKEN_SELECTED); 207 208 if (cred == NULL || cred->cred == NULL) { 209 return (KMF_ERR_BAD_PARAMETER); 210 } 211 212 if ((ck_rv = C_Login(hSession, CKU_USER, (uchar_t *)cred->cred, 213 cred->credlen)) != CKR_OK) { 214 if (ck_rv != CKR_USER_ALREADY_LOGGED_IN) { 215 handle->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; 216 handle->lasterr.errcode = ck_rv; 217 return (KMF_ERR_AUTH_FAILED); 218 } 219 } 220 221 return (KMF_OK); 222 } 223 224 static KMF_RETURN 225 PK11Cert2KMFCert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE hObj, 226 KMF_X509_DER_CERT *kmfcert) 227 { 228 KMF_RETURN rv = 0; 229 CK_RV ckrv = CKR_OK; 230 231 CK_CERTIFICATE_TYPE cktype; 232 CK_OBJECT_CLASS class; 233 CK_ULONG subject_len, value_len, issuer_len, serno_len, id_len; 234 CK_BYTE *subject = NULL, *value = NULL; 235 char *label = NULL; 236 CK_ATTRIBUTE templ[10]; 237 238 (void) memset(templ, 0, 10 * sizeof (CK_ATTRIBUTE)); 239 SETATTR(templ, 0, CKA_CLASS, &class, sizeof (class)); 240 241 /* Is this a certificate object ? */ 242 ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, 1); 243 if (ckrv != CKR_OK || class != CKO_CERTIFICATE) { 244 SET_ERROR(kmfh, ckrv); 245 return (KMF_ERR_INTERNAL); 246 } 247 248 SETATTR(templ, 0, CKA_CERTIFICATE_TYPE, &cktype, sizeof (cktype)); 249 ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, 1); 250 251 if (ckrv != CKR_OK || cktype != CKC_X_509) { 252 SET_ERROR(kmfh, ckrv); 253 return (ckrv); 254 } else { 255 int i = 0; 256 /* What attributes are available and how big are they? */ 257 subject_len = issuer_len = serno_len = id_len = value_len = 0; 258 259 SETATTR(templ, i, CKA_SUBJECT, NULL, subject_len); 260 i++; 261 SETATTR(templ, i, CKA_ISSUER, NULL, issuer_len); 262 i++; 263 SETATTR(templ, i, CKA_SERIAL_NUMBER, NULL, serno_len); 264 i++; 265 SETATTR(templ, i, CKA_ID, NULL, id_len); 266 i++; 267 SETATTR(templ, i, CKA_VALUE, NULL, value_len); 268 i++; 269 270 /* 271 * Query the object with NULL values in the pValue spot 272 * so we know how much space to allocate for each field. 273 */ 274 ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, i); 275 if (ckrv != CKR_OK) { 276 SET_ERROR(kmfh, ckrv); 277 return (KMF_ERR_INTERNAL); /* TODO - Error messages ? */ 278 } 279 280 subject_len = templ[0].ulValueLen; 281 issuer_len = templ[1].ulValueLen; 282 serno_len = templ[2].ulValueLen; 283 id_len = templ[3].ulValueLen; 284 value_len = templ[4].ulValueLen; 285 286 /* 287 * For PKCS#11 CKC_X_509 certificate objects, 288 * the following attributes must be defined. 289 * CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER, 290 * CKA_VALUE. 291 */ 292 if (subject_len == 0 || issuer_len == 0 || 293 serno_len == 0 || value_len == 0) { 294 return (KMF_ERR_INTERNAL); 295 } 296 297 /* Only fetch the value field if we are saving the data */ 298 if (kmfcert != NULL) { 299 int i = 0; 300 value = malloc(value_len); 301 if (value == NULL) { 302 rv = KMF_ERR_MEMORY; 303 goto errout; 304 } 305 306 SETATTR(templ, i, CKA_VALUE, value, value_len); 307 i++; 308 309 /* re-query the object with room for the value attr */ 310 ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, 311 templ, i); 312 313 if (ckrv != CKR_OK) { 314 SET_ERROR(kmfh, ckrv); 315 rv = KMF_ERR_INTERNAL; 316 goto errout; 317 } 318 319 kmfcert->certificate.Data = value; 320 kmfcert->certificate.Length = value_len; 321 kmfcert->kmf_private.flags |= KMF_FLAG_CERT_SIGNED; 322 kmfcert->kmf_private.keystore_type = 323 KMF_KEYSTORE_PK11TOKEN; 324 325 ckrv = getObjectLabel(kmfh, hObj, &label); 326 if (ckrv == CKR_OK && label != NULL) { 327 kmfcert->kmf_private.label = (char *)label; 328 } 329 330 rv = KMF_OK; 331 } 332 } 333 334 errout: 335 if (rv != KMF_OK) { 336 if (subject) 337 free(subject); 338 if (value) 339 free(value); 340 341 if (kmfcert) { 342 kmfcert->certificate.Data = NULL; 343 kmfcert->certificate.Length = 0; 344 } 345 } 346 return (rv); 347 } 348 349 static void 350 free_objlist(OBJLIST *head) 351 { 352 OBJLIST *temp = head; 353 354 while (temp != NULL) { 355 head = head->next; 356 free(temp); 357 temp = head; 358 } 359 } 360 361 /* 362 * The caller should make sure that the templ->pValue is NULL since 363 * it will be overwritten below. 364 */ 365 static KMF_RETURN 366 get_attr(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, 367 CK_ATTRIBUTE *templ) 368 { 369 CK_RV rv; 370 371 rv = C_GetAttributeValue(kmfh->pk11handle, obj, templ, 1); 372 if (rv != CKR_OK) { 373 SET_ERROR(kmfh, rv); 374 return (KMF_ERR_INTERNAL); 375 } 376 377 if (templ->ulValueLen > 0) { 378 templ->pValue = malloc(templ->ulValueLen); 379 if (templ->pValue == NULL) 380 return (KMF_ERR_MEMORY); 381 382 rv = C_GetAttributeValue(kmfh->pk11handle, obj, templ, 1); 383 if (rv != CKR_OK) { 384 SET_ERROR(kmfh, rv); 385 return (KMF_ERR_INTERNAL); 386 } 387 } 388 389 return (KMF_OK); 390 } 391 392 /* 393 * Match a certificate with an issuer and/or subject name. 394 * This is tricky because we cannot reliably compare DER encodings 395 * because RDNs may have their AV-pairs in different orders even 396 * if the values are the same. You must compare individual 397 * AV pairs for the RDNs. 398 * 399 * RETURN: 0 for a match, non-zero for a non-match. 400 */ 401 static KMF_RETURN 402 matchcert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, 403 KMF_X509_NAME *issuer, KMF_X509_NAME *subject) 404 { 405 KMF_RETURN rv = KMF_OK; 406 CK_ATTRIBUTE certattr; 407 KMF_DATA name; 408 KMF_X509_NAME dn; 409 410 if (issuer->numberOfRDNs > 0) { 411 certattr.type = CKA_ISSUER; 412 certattr.pValue = NULL; 413 certattr.ulValueLen = 0; 414 415 rv = get_attr(kmfh, obj, &certattr); 416 417 if (rv == KMF_OK) { 418 name.Data = certattr.pValue; 419 name.Length = certattr.ulValueLen; 420 rv = DerDecodeName(&name, &dn); 421 if (rv == KMF_OK) { 422 rv = kmf_compare_rdns(issuer, &dn); 423 kmf_free_dn(&dn); 424 } 425 free(certattr.pValue); 426 } 427 428 if (rv != KMF_OK) 429 return (rv); 430 } 431 if (subject->numberOfRDNs > 0) { 432 certattr.type = CKA_SUBJECT; 433 certattr.pValue = NULL; 434 certattr.ulValueLen = 0; 435 436 rv = get_attr(kmfh, obj, &certattr); 437 438 if (rv == KMF_OK) { 439 name.Data = certattr.pValue; 440 name.Length = certattr.ulValueLen; 441 rv = DerDecodeName(&name, &dn); 442 if (rv == KMF_OK) { 443 rv = kmf_compare_rdns(subject, &dn); 444 kmf_free_dn(&dn); 445 } 446 free(certattr.pValue); 447 } 448 } 449 450 return (rv); 451 } 452 453 /* 454 * delete "curr" node from the "newlist". 455 */ 456 static void 457 pk11_delete_obj_from_list(OBJLIST **newlist, 458 OBJLIST **prev, OBJLIST **curr) 459 { 460 461 if (*curr == *newlist) { 462 /* first node in the list */ 463 *newlist = (*curr)->next; 464 *prev = (*curr)->next; 465 free(*curr); 466 *curr = *newlist; 467 } else { 468 (*prev)->next = (*curr)->next; 469 free(*curr); 470 *curr = (*prev)->next; 471 } 472 } 473 474 /* 475 * search_certs 476 * 477 * Because this code is shared by the FindCert and 478 * DeleteCert functions, put it in a separate routine 479 * to save some work and make code easier to debug and 480 * read. 481 */ 482 static KMF_RETURN 483 search_certs(KMF_HANDLE_T handle, 484 char *label, char *issuer, char *subject, KMF_BIGINT *serial, 485 boolean_t private, KMF_CERT_VALIDITY validity, 486 OBJLIST **objlist, uint32_t *numobj) 487 { 488 KMF_RETURN rv = KMF_OK; 489 CK_RV ckrv = CKR_OK; 490 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 491 CK_ATTRIBUTE templ[10]; 492 CK_BBOOL true = TRUE; 493 CK_OBJECT_CLASS oclass = CKO_CERTIFICATE; 494 CK_CERTIFICATE_TYPE ctype = CKC_X_509; 495 KMF_X509_NAME subjectDN, issuerDN; 496 int i; 497 OBJLIST *newlist, *tail; 498 CK_ULONG num = 0; 499 uint32_t num_ok_certs = 0; /* number of non-expired or expired certs */ 500 501 (void) memset(&templ, 0, 10 * sizeof (CK_ATTRIBUTE)); 502 (void) memset(&issuerDN, 0, sizeof (KMF_X509_NAME)); 503 (void) memset(&subjectDN, 0, sizeof (KMF_X509_NAME)); 504 i = 0; 505 SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true)); i++; 506 SETATTR(templ, i, CKA_CLASS, &oclass, sizeof (oclass)); i++; 507 SETATTR(templ, i, CKA_CERTIFICATE_TYPE, &ctype, sizeof (ctype)); i++; 508 509 if (label != NULL && strlen(label)) { 510 SETATTR(templ, i, CKA_LABEL, label, strlen(label)); 511 i++; 512 } 513 if (private) { 514 SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true)); i++; 515 } 516 517 if (issuer != NULL && strlen(issuer)) { 518 if ((rv = kmf_dn_parser(issuer, &issuerDN)) != KMF_OK) 519 return (rv); 520 } 521 if (subject != NULL && strlen(subject)) { 522 if ((rv = kmf_dn_parser(subject, &subjectDN)) != KMF_OK) 523 return (rv); 524 } 525 526 if (serial != NULL && serial->val != NULL && serial->len > 0) { 527 SETATTR(templ, i, CKA_SERIAL_NUMBER, serial->val, serial->len); 528 i++; 529 } 530 531 (*numobj) = 0; 532 *objlist = NULL; 533 newlist = NULL; 534 535 ckrv = C_FindObjectsInit(kmfh->pk11handle, templ, i); 536 if (ckrv != CKR_OK) 537 goto cleanup; 538 539 tail = newlist = NULL; 540 while (ckrv == CKR_OK) { 541 CK_OBJECT_HANDLE tObj; 542 ckrv = C_FindObjects(kmfh->pk11handle, &tObj, 1, &num); 543 if (ckrv != CKR_OK || num == 0) 544 break; 545 546 /* 547 * 'matchcert' returns 0 if subject/issuer match 548 * 549 * If no match, move on to the next one 550 */ 551 if (matchcert(kmfh, tObj, &issuerDN, &subjectDN)) 552 continue; 553 554 if (newlist == NULL) { 555 newlist = malloc(sizeof (OBJLIST)); 556 if (newlist == NULL) { 557 rv = KMF_ERR_MEMORY; 558 break; 559 } 560 newlist->handle = tObj; 561 newlist->next = NULL; 562 tail = newlist; 563 } else { 564 tail->next = malloc(sizeof (OBJLIST)); 565 if (tail->next != NULL) { 566 tail = tail->next; 567 } else { 568 rv = KMF_ERR_MEMORY; 569 break; 570 } 571 tail->handle = tObj; 572 tail->next = NULL; 573 } 574 (*numobj)++; 575 } 576 ckrv = C_FindObjectsFinal(kmfh->pk11handle); 577 578 cleanup: 579 if (ckrv != CKR_OK) { 580 SET_ERROR(kmfh, ckrv); 581 rv = KMF_ERR_INTERNAL; 582 if (newlist != NULL) { 583 free_objlist(newlist); 584 *numobj = 0; 585 newlist = NULL; 586 } 587 } else { 588 if (validity == KMF_ALL_CERTS) { 589 *objlist = newlist; 590 } else { 591 OBJLIST *node, *prev; 592 KMF_X509_DER_CERT tmp_kmf_cert; 593 uint32_t i = 0; 594 595 node = prev = newlist; 596 /* 597 * Now check to see if any found certificate is expired 598 * or valid. 599 */ 600 while (node != NULL && i < (*numobj)) { 601 (void) memset(&tmp_kmf_cert, 0, 602 sizeof (KMF_X509_DER_CERT)); 603 rv = PK11Cert2KMFCert(kmfh, node->handle, 604 &tmp_kmf_cert); 605 if (rv != KMF_OK) { 606 goto cleanup1; 607 } 608 609 rv = kmf_check_cert_date(handle, 610 &tmp_kmf_cert.certificate); 611 612 if (validity == KMF_NONEXPIRED_CERTS) { 613 if (rv == KMF_OK) { 614 num_ok_certs++; 615 prev = node; 616 node = node->next; 617 } else if (rv == 618 KMF_ERR_VALIDITY_PERIOD) { 619 /* 620 * expired - remove it from list 621 */ 622 pk11_delete_obj_from_list( 623 &newlist, &prev, &node); 624 } else { 625 goto cleanup1; 626 } 627 } 628 629 if (validity == KMF_EXPIRED_CERTS) { 630 if (rv == KMF_ERR_VALIDITY_PERIOD) { 631 num_ok_certs++; 632 prev = node; 633 node = node->next; 634 rv = KMF_OK; 635 } else if (rv == KMF_OK) { 636 /* 637 * valid - remove it from list 638 */ 639 pk11_delete_obj_from_list( 640 &newlist, &prev, &node); 641 } else { 642 goto cleanup1; 643 } 644 } 645 i++; 646 kmf_free_kmf_cert(handle, &tmp_kmf_cert); 647 } 648 *numobj = num_ok_certs; 649 *objlist = newlist; 650 } 651 } 652 653 cleanup1: 654 if (rv != KMF_OK && newlist != NULL) { 655 free_objlist(newlist); 656 *numobj = 0; 657 *objlist = NULL; 658 } 659 660 if (issuer != NULL) 661 kmf_free_dn(&issuerDN); 662 663 if (subject != NULL) 664 kmf_free_dn(&subjectDN); 665 666 return (rv); 667 } 668 669 /* 670 * The caller may pass a NULL value for kmf_cert below and the function will 671 * just return the number of certs found (in num_certs). 672 */ 673 KMF_RETURN 674 KMFPK11_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 675 { 676 KMF_RETURN rv = 0; 677 uint32_t want_certs; 678 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 679 OBJLIST *objlist = NULL; 680 uint32_t *num_certs; 681 KMF_X509_DER_CERT *kmf_cert = NULL; 682 char *certlabel = NULL; 683 char *issuer = NULL; 684 char *subject = NULL; 685 KMF_BIGINT *serial = NULL; 686 KMF_CERT_VALIDITY validity; 687 KMF_CREDENTIAL *cred = NULL; 688 boolean_t private; 689 690 if (kmfh == NULL) 691 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 692 693 if (kmfh->pk11handle == CK_INVALID_HANDLE) 694 return (KMF_ERR_NO_TOKEN_SELECTED); 695 696 num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr); 697 if (num_certs == NULL) 698 return (KMF_ERR_BAD_PARAMETER); 699 700 if (*num_certs > 0) 701 want_certs = *num_certs; 702 else 703 want_certs = MAXINT; /* count them all */ 704 705 *num_certs = 0; 706 707 /* Get the optional returned certificate list */ 708 kmf_cert = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist, 709 numattr); 710 711 /* Get optional search criteria attributes */ 712 certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); 713 issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); 714 subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); 715 serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); 716 717 rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr, 718 &validity, NULL); 719 if (rv != KMF_OK) { 720 validity = KMF_ALL_CERTS; 721 rv = KMF_OK; 722 } 723 724 rv = kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr, 725 (void *)&private, NULL); 726 if (rv != KMF_OK) { 727 private = B_FALSE; 728 rv = KMF_OK; 729 } 730 731 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr); 732 if (cred != NULL) { 733 rv = pk11_authenticate(handle, cred); 734 if (rv != KMF_OK) 735 return (rv); 736 } 737 738 /* Start searching */ 739 rv = search_certs(handle, certlabel, issuer, subject, serial, private, 740 validity, &objlist, num_certs); 741 742 if (rv == KMF_OK && objlist != NULL && kmf_cert != NULL) { 743 OBJLIST *node = objlist; 744 int i = 0; 745 while (node != NULL && i < want_certs) { 746 rv = PK11Cert2KMFCert(kmfh, node->handle, 747 &kmf_cert[i]); 748 i++; 749 node = node->next; 750 } 751 } 752 753 if (objlist != NULL) 754 free_objlist(objlist); 755 756 if (*num_certs == 0) 757 rv = KMF_ERR_CERT_NOT_FOUND; 758 759 return (rv); 760 } 761 762 /*ARGSUSED*/ 763 void 764 KMFPK11_FreeKMFCert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert) 765 { 766 if (kmf_cert != NULL && kmf_cert->certificate.Data != NULL) { 767 free(kmf_cert->certificate.Data); 768 kmf_cert->certificate.Data = NULL; 769 kmf_cert->certificate.Length = 0; 770 771 if (kmf_cert->kmf_private.label != NULL) { 772 free(kmf_cert->kmf_private.label); 773 kmf_cert->kmf_private.label = NULL; 774 } 775 } 776 } 777 778 KMF_RETURN 779 KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, 780 KMF_DATA *eData) 781 { 782 KMF_RETURN ret = KMF_OK; 783 CK_RV rv; 784 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 785 CK_OBJECT_CLASS ckObjClass = CKO_PUBLIC_KEY; 786 CK_KEY_TYPE ckKeyType; 787 KMF_DATA Modulus, Exponent, Prime, Subprime, Base, Value; 788 KMF_OID *Algorithm; 789 BerElement *asn1 = NULL; 790 BerValue *PubKeyParams = NULL, *EncodedKey = NULL; 791 KMF_X509_SPKI spki; 792 793 CK_ATTRIBUTE rsaTemplate[4]; 794 CK_ATTRIBUTE dsaTemplate[6]; 795 796 if (kmfh == NULL) 797 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 798 799 if (kmfh->pk11handle == CK_INVALID_HANDLE) 800 return (KMF_ERR_NO_TOKEN_SELECTED); 801 802 if (pKey == NULL || pKey->keyp == CK_INVALID_HANDLE) 803 return (KMF_ERR_BAD_PARAMETER); 804 805 (void) memset(&Modulus, 0, sizeof (Modulus)); 806 (void) memset(&Exponent, 0, sizeof (Exponent)); 807 (void) memset(&Prime, 0, sizeof (Prime)); 808 (void) memset(&Subprime, 0, sizeof (Subprime)); 809 (void) memset(&Base, 0, sizeof (Base)); 810 (void) memset(&Value, 0, sizeof (Value)); 811 812 SETATTR(rsaTemplate, 0, CKA_CLASS, &ckObjClass, sizeof (ckObjClass)); 813 SETATTR(rsaTemplate, 1, CKA_KEY_TYPE, &ckKeyType, sizeof (ckKeyType)); 814 SETATTR(rsaTemplate, 2, CKA_MODULUS, Modulus.Data, Modulus.Length); 815 SETATTR(rsaTemplate, 3, CKA_PUBLIC_EXPONENT, Exponent.Data, 816 Exponent.Length); 817 818 SETATTR(dsaTemplate, 0, CKA_CLASS, &ckObjClass, sizeof (ckObjClass)); 819 SETATTR(dsaTemplate, 1, CKA_KEY_TYPE, &ckKeyType, sizeof (ckKeyType)); 820 SETATTR(dsaTemplate, 2, CKA_PRIME, Prime.Data, Prime.Length); 821 SETATTR(dsaTemplate, 3, CKA_SUBPRIME, Subprime.Data, Subprime.Length); 822 SETATTR(dsaTemplate, 4, CKA_BASE, Base.Data, Base.Length); 823 SETATTR(dsaTemplate, 5, CKA_VALUE, Value.Data, Value.Length); 824 825 switch (pKey->keyalg) { 826 case KMF_RSA: 827 /* Get the length of the fields */ 828 rv = C_GetAttributeValue(kmfh->pk11handle, 829 (CK_OBJECT_HANDLE)pKey->keyp, rsaTemplate, 4); 830 if (rv != CKR_OK) { 831 SET_ERROR(kmfh, rv); 832 return (KMF_ERR_BAD_PARAMETER); 833 } 834 835 Modulus.Length = rsaTemplate[2].ulValueLen; 836 Modulus.Data = malloc(Modulus.Length); 837 if (Modulus.Data == NULL) 838 return (KMF_ERR_MEMORY); 839 840 Exponent.Length = rsaTemplate[3].ulValueLen; 841 Exponent.Data = malloc(Exponent.Length); 842 if (Exponent.Data == NULL) { 843 free(Modulus.Data); 844 return (KMF_ERR_MEMORY); 845 } 846 847 SETATTR(rsaTemplate, 2, CKA_MODULUS, Modulus.Data, 848 Modulus.Length); 849 SETATTR(rsaTemplate, 3, CKA_PUBLIC_EXPONENT, 850 Exponent.Data, Exponent.Length); 851 /* Now get the values */ 852 rv = C_GetAttributeValue(kmfh->pk11handle, 853 (CK_OBJECT_HANDLE)pKey->keyp, rsaTemplate, 4); 854 if (rv != CKR_OK) { 855 SET_ERROR(kmfh, rv); 856 free(Modulus.Data); 857 free(Exponent.Data); 858 return (KMF_ERR_BAD_PARAMETER); 859 } 860 861 /* 862 * This is the KEY algorithm, not the 863 * signature algorithm. 864 */ 865 Algorithm = x509_algid_to_algoid(KMF_ALGID_RSA); 866 if (Algorithm != NULL) { 867 868 /* Encode the RSA Key Data */ 869 if ((asn1 = kmfder_alloc()) == NULL) { 870 free(Modulus.Data); 871 free(Exponent.Data); 872 return (KMF_ERR_MEMORY); 873 } 874 if (kmfber_printf(asn1, "{II}", Modulus.Data, 875 Modulus.Length, Exponent.Data, 876 Exponent.Length) == -1) { 877 kmfber_free(asn1, 1); 878 free(Modulus.Data); 879 free(Exponent.Data); 880 return (KMF_ERR_ENCODING); 881 } 882 if (kmfber_flatten(asn1, &EncodedKey) == -1) { 883 kmfber_free(asn1, 1); 884 free(Modulus.Data); 885 free(Exponent.Data); 886 return (KMF_ERR_ENCODING); 887 } 888 kmfber_free(asn1, 1); 889 } 890 891 free(Exponent.Data); 892 free(Modulus.Data); 893 894 break; 895 case KMF_DSA: 896 /* Get the length of the fields */ 897 rv = C_GetAttributeValue(kmfh->pk11handle, 898 (CK_OBJECT_HANDLE)pKey->keyp, dsaTemplate, 6); 899 if (rv != CKR_OK) { 900 SET_ERROR(kmfh, rv); 901 return (KMF_ERR_BAD_PARAMETER); 902 } 903 Prime.Length = dsaTemplate[2].ulValueLen; 904 Prime.Data = malloc(Prime.Length); 905 if (Prime.Data == NULL) { 906 return (KMF_ERR_MEMORY); 907 } 908 909 Subprime.Length = dsaTemplate[3].ulValueLen; 910 Subprime.Data = malloc(Subprime.Length); 911 if (Subprime.Data == NULL) { 912 free(Prime.Data); 913 return (KMF_ERR_MEMORY); 914 } 915 916 Base.Length = dsaTemplate[4].ulValueLen; 917 Base.Data = malloc(Base.Length); 918 if (Base.Data == NULL) { 919 free(Prime.Data); 920 free(Subprime.Data); 921 return (KMF_ERR_MEMORY); 922 } 923 924 Value.Length = dsaTemplate[5].ulValueLen; 925 Value.Data = malloc(Value.Length); 926 if (Value.Data == NULL) { 927 free(Prime.Data); 928 free(Subprime.Data); 929 free(Base.Data); 930 return (KMF_ERR_MEMORY); 931 } 932 SETATTR(dsaTemplate, 2, CKA_PRIME, Prime.Data, 933 Prime.Length); 934 SETATTR(dsaTemplate, 3, CKA_SUBPRIME, Subprime.Data, 935 Subprime.Length); 936 SETATTR(dsaTemplate, 4, CKA_BASE, Base.Data, 937 Base.Length); 938 SETATTR(dsaTemplate, 5, CKA_VALUE, Value.Data, 939 Value.Length); 940 941 /* Now get the values */ 942 rv = C_GetAttributeValue(kmfh->pk11handle, 943 (CK_OBJECT_HANDLE)pKey->keyp, dsaTemplate, 6); 944 if (rv != CKR_OK) { 945 free(Prime.Data); 946 free(Subprime.Data); 947 free(Base.Data); 948 free(Value.Data); 949 SET_ERROR(kmfh, rv); 950 return (KMF_ERR_BAD_PARAMETER); 951 } 952 /* 953 * This is the KEY algorithm, not the 954 * signature algorithm. 955 */ 956 Algorithm = x509_algid_to_algoid(KMF_ALGID_DSA); 957 958 /* Encode the DSA Algorithm Parameters */ 959 if ((asn1 = kmfder_alloc()) == NULL) { 960 free(Prime.Data); 961 free(Subprime.Data); 962 free(Base.Data); 963 free(Value.Data); 964 return (KMF_ERR_MEMORY); 965 } 966 967 if (kmfber_printf(asn1, "{III}", Prime.Data, 968 Prime.Length, Subprime.Data, Subprime.Length, 969 Base.Data, Base.Length) == -1) { 970 971 kmfber_free(asn1, 1); 972 free(Prime.Data); 973 free(Subprime.Data); 974 free(Base.Data); 975 free(Value.Data); 976 return (KMF_ERR_ENCODING); 977 } 978 if (kmfber_flatten(asn1, &PubKeyParams) == -1) { 979 kmfber_free(asn1, 1); 980 free(Prime.Data); 981 free(Subprime.Data); 982 free(Base.Data); 983 free(Value.Data); 984 return (KMF_ERR_ENCODING); 985 } 986 kmfber_free(asn1, 1); 987 free(Prime.Data); 988 free(Subprime.Data); 989 free(Base.Data); 990 991 /* Encode the DSA Key Value */ 992 if ((asn1 = kmfder_alloc()) == NULL) { 993 free(Value.Data); 994 return (KMF_ERR_MEMORY); 995 } 996 997 if (kmfber_printf(asn1, "I", 998 Value.Data, Value.Length) == -1) { 999 kmfber_free(asn1, 1); 1000 free(Value.Data); 1001 return (KMF_ERR_ENCODING); 1002 } 1003 if (kmfber_flatten(asn1, &EncodedKey) == -1) { 1004 kmfber_free(asn1, 1); 1005 free(Value.Data); 1006 return (KMF_ERR_ENCODING); 1007 } 1008 kmfber_free(asn1, 1); 1009 free(Value.Data); 1010 break; 1011 default: 1012 return (KMF_ERR_BAD_PARAMETER); 1013 } 1014 1015 /* Now, build an SPKI structure for the final encoding step */ 1016 spki.algorithm.algorithm = *Algorithm; 1017 if (PubKeyParams != NULL) { 1018 spki.algorithm.parameters.Data = 1019 (uchar_t *)PubKeyParams->bv_val; 1020 spki.algorithm.parameters.Length = PubKeyParams->bv_len; 1021 } else { 1022 spki.algorithm.parameters.Data = NULL; 1023 spki.algorithm.parameters.Length = 0; 1024 } 1025 1026 if (EncodedKey != NULL) { 1027 spki.subjectPublicKey.Data = (uchar_t *)EncodedKey->bv_val; 1028 spki.subjectPublicKey.Length = EncodedKey->bv_len; 1029 } else { 1030 spki.subjectPublicKey.Data = NULL; 1031 spki.subjectPublicKey.Length = 0; 1032 } 1033 1034 /* Finally, encode the entire SPKI record */ 1035 ret = DerEncodeSPKI(&spki, eData); 1036 1037 cleanup: 1038 if (EncodedKey) { 1039 free(EncodedKey->bv_val); 1040 free(EncodedKey); 1041 } 1042 1043 if (PubKeyParams) { 1044 free(PubKeyParams->bv_val); 1045 free(PubKeyParams); 1046 } 1047 1048 return (ret); 1049 } 1050 1051 static KMF_RETURN 1052 CreateCertObject(KMF_HANDLE_T handle, char *label, KMF_DATA *pcert) 1053 { 1054 KMF_RETURN rv = 0; 1055 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1056 1057 KMF_X509_CERTIFICATE *signed_cert_ptr = NULL; 1058 KMF_DATA data; 1059 KMF_DATA Id; 1060 1061 CK_RV ckrv; 1062 CK_ULONG subject_len, issuer_len, serno_len; 1063 CK_BYTE *subject, *issuer, *serial, nullserno; 1064 CK_BBOOL true = TRUE; 1065 CK_CERTIFICATE_TYPE certtype = CKC_X_509; 1066 CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; 1067 CK_ATTRIBUTE x509templ[11]; 1068 CK_OBJECT_HANDLE hCert = NULL; 1069 int i; 1070 1071 if (kmfh == NULL) 1072 return (KMF_ERR_INTERNAL); /* should not happen */ 1073 1074 if (kmfh->pk11handle == CK_INVALID_HANDLE) 1075 return (KMF_ERR_INTERNAL); /* should not happen */ 1076 1077 if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) 1078 return (KMF_ERR_INTERNAL); /* should not happen */ 1079 1080 /* 1081 * The data *must* be a DER encoded X.509 certificate. 1082 * Convert it to a CSSM cert and then parse the fields so 1083 * the PKCS#11 attributes can be filled in correctly. 1084 */ 1085 rv = DerDecodeSignedCertificate((const KMF_DATA *)pcert, 1086 &signed_cert_ptr); 1087 if (rv != KMF_OK) { 1088 return (KMF_ERR_ENCODING); 1089 } 1090 1091 /* 1092 * Encode fields into PKCS#11 attributes. 1093 */ 1094 1095 /* Get the subject name */ 1096 rv = DerEncodeName(&signed_cert_ptr->certificate.subject, &data); 1097 if (rv == KMF_OK) { 1098 subject = data.Data; 1099 subject_len = data.Length; 1100 } else { 1101 rv = KMF_ERR_ENCODING; 1102 goto cleanup; 1103 } 1104 1105 /* Encode the issuer */ 1106 rv = DerEncodeName(&signed_cert_ptr->certificate.issuer, &data); 1107 if (rv == KMF_OK) { 1108 issuer = data.Data; 1109 issuer_len = data.Length; 1110 } else { 1111 rv = KMF_ERR_ENCODING; 1112 goto cleanup; 1113 } 1114 1115 /* Encode serial number */ 1116 if (signed_cert_ptr->certificate.serialNumber.len > 0 && 1117 signed_cert_ptr->certificate.serialNumber.val != NULL) { 1118 serial = signed_cert_ptr->certificate.serialNumber.val; 1119 serno_len = signed_cert_ptr->certificate.serialNumber.len; 1120 } else { 1121 /* 1122 * RFC3280 says to gracefully handle certs with serial numbers 1123 * of 0. 1124 */ 1125 nullserno = '\0'; 1126 serial = &nullserno; 1127 serno_len = 1; 1128 } 1129 1130 /* Generate an ID from the SPKI data */ 1131 rv = GetIDFromSPKI(&signed_cert_ptr->certificate.subjectPublicKeyInfo, 1132 &Id); 1133 1134 if (rv != KMF_OK) { 1135 goto cleanup; 1136 } 1137 1138 i = 0; 1139 SETATTR(x509templ, i, CKA_CLASS, &certClass, sizeof (certClass)); i++; 1140 SETATTR(x509templ, i, CKA_CERTIFICATE_TYPE, &certtype, 1141 sizeof (certtype)); 1142 i++; 1143 SETATTR(x509templ, i, CKA_TOKEN, &true, sizeof (true)); i++; 1144 SETATTR(x509templ, i, CKA_SUBJECT, subject, subject_len); i++; 1145 SETATTR(x509templ, i, CKA_ISSUER, issuer, issuer_len); i++; 1146 SETATTR(x509templ, i, CKA_SERIAL_NUMBER, serial, serno_len); i++; 1147 SETATTR(x509templ, i, CKA_VALUE, pcert->Data, pcert->Length); i++; 1148 SETATTR(x509templ, i, CKA_ID, Id.Data, Id.Length); i++; 1149 if (label != NULL && strlen(label)) { 1150 SETATTR(x509templ, i, CKA_LABEL, label, strlen(label)); i++; 1151 } 1152 /* 1153 * The cert object handle is actually "leaked" here. If the app 1154 * really wants to clean up the data space, it will have to call 1155 * KMF_DeleteCert and specify the softtoken keystore. 1156 */ 1157 ckrv = C_CreateObject(kmfh->pk11handle, x509templ, i, &hCert); 1158 if (ckrv != CKR_OK) { 1159 /* Report authentication failures to the caller */ 1160 if (ckrv == CKR_USER_NOT_LOGGED_IN || 1161 ckrv == CKR_PIN_INCORRECT || 1162 ckrv == CKR_PIN_INVALID || 1163 ckrv == CKR_PIN_EXPIRED || 1164 ckrv == CKR_PIN_LOCKED || 1165 ckrv == CKR_SESSION_READ_ONLY) 1166 rv = KMF_ERR_AUTH_FAILED; 1167 else 1168 rv = KMF_ERR_INTERNAL; 1169 SET_ERROR(kmfh, ckrv); 1170 } 1171 free(subject); 1172 free(issuer); 1173 1174 cleanup: 1175 if (Id.Data != NULL) 1176 free(Id.Data); 1177 1178 if (signed_cert_ptr) { 1179 kmf_free_signed_cert(signed_cert_ptr); 1180 free(signed_cert_ptr); 1181 } 1182 return (rv); 1183 } 1184 1185 1186 KMF_RETURN 1187 KMFPK11_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 1188 { 1189 KMF_RETURN rv = 0; 1190 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1191 KMF_DATA *cert = NULL; 1192 KMF_CREDENTIAL *cred = NULL; 1193 char *label = NULL; 1194 1195 if (kmfh == NULL) 1196 return (KMF_ERR_UNINITIALIZED); 1197 1198 if (kmfh->pk11handle == CK_INVALID_HANDLE) 1199 return (KMF_ERR_NO_TOKEN_SELECTED); 1200 1201 cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); 1202 if (cert == NULL || cert->Data == NULL || cert->Length == 0) 1203 return (KMF_ERR_BAD_PARAMETER); 1204 1205 /* label attribute is optional */ 1206 label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); 1207 1208 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr); 1209 if (cred != NULL) { 1210 rv = pk11_authenticate(handle, cred); 1211 if (rv != KMF_OK) 1212 return (rv); 1213 } 1214 1215 rv = CreateCertObject(handle, label, cert); 1216 return (rv); 1217 } 1218 1219 KMF_RETURN 1220 KMFPK11_ImportCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 1221 { 1222 KMF_RETURN rv = 0; 1223 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1224 char *certfile = NULL; 1225 char *label = NULL; 1226 KMF_ENCODE_FORMAT format; 1227 KMF_CREDENTIAL *cred = NULL; 1228 KMF_DATA cert1 = { NULL, 0}; 1229 KMF_DATA cert2 = { NULL, 0}; 1230 1231 if (kmfh == NULL) 1232 return (KMF_ERR_UNINITIALIZED); 1233 1234 if (kmfh->pk11handle == CK_INVALID_HANDLE) 1235 return (KMF_ERR_NO_TOKEN_SELECTED); 1236 1237 /* 1238 * Get the input cert filename attribute, check if it is a valid 1239 * certificate and auto-detect the file format of it. 1240 */ 1241 certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr); 1242 if (certfile == NULL) 1243 return (KMF_ERR_BAD_PARAMETER); 1244 1245 rv = kmf_is_cert_file(handle, certfile, &format); 1246 if (rv != KMF_OK) 1247 return (rv); 1248 1249 /* Read in the CERT file */ 1250 rv = kmf_read_input_file(handle, certfile, &cert1); 1251 if (rv != KMF_OK) { 1252 return (rv); 1253 } 1254 1255 /* The label attribute is optional */ 1256 label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); 1257 1258 /* 1259 * If the input certificate is in PEM format, we need to convert 1260 * it to DER first. 1261 */ 1262 if (format == KMF_FORMAT_PEM) { 1263 int derlen; 1264 rv = kmf_pem_to_der(cert1.Data, cert1.Length, 1265 &cert2.Data, &derlen); 1266 if (rv != KMF_OK) { 1267 goto out; 1268 } 1269 cert2.Length = (size_t)derlen; 1270 } 1271 1272 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr); 1273 if (cred != NULL) { 1274 rv = pk11_authenticate(handle, cred); 1275 if (rv != KMF_OK) 1276 return (rv); 1277 } 1278 1279 rv = CreateCertObject(handle, label, 1280 format == KMF_FORMAT_ASN1 ? &cert1 : &cert2); 1281 1282 out: 1283 if (cert1.Data != NULL) { 1284 free(cert1.Data); 1285 } 1286 1287 if (cert2.Data != NULL) { 1288 free(cert2.Data); 1289 } 1290 1291 return (rv); 1292 } 1293 1294 KMF_RETURN 1295 KMFPK11_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 1296 { 1297 KMF_RETURN rv = 0; 1298 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1299 OBJLIST *objlist; 1300 uint32_t numObjects = 0; 1301 char *certlabel = NULL; 1302 char *issuer = NULL; 1303 char *subject = NULL; 1304 KMF_BIGINT *serial = NULL; 1305 KMF_CERT_VALIDITY validity; 1306 boolean_t private; 1307 1308 if (kmfh == NULL) 1309 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 1310 1311 if (kmfh->pk11handle == CK_INVALID_HANDLE) 1312 return (KMF_ERR_NO_TOKEN_SELECTED); 1313 1314 1315 /* Get the search criteria attributes. They are all optional. */ 1316 certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); 1317 issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); 1318 subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); 1319 serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); 1320 1321 rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr, 1322 &validity, NULL); 1323 if (rv != KMF_OK) { 1324 validity = KMF_ALL_CERTS; 1325 rv = KMF_OK; 1326 } 1327 1328 rv = kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr, 1329 (void *)&private, NULL); 1330 if (rv != KMF_OK) { 1331 private = B_FALSE; 1332 rv = KMF_OK; 1333 } 1334 1335 /* 1336 * Start searching for certificates that match the criteria and 1337 * delete them. 1338 */ 1339 objlist = NULL; 1340 rv = search_certs(handle, certlabel, issuer, subject, serial, 1341 private, validity, &objlist, &numObjects); 1342 1343 if (rv == KMF_OK && objlist != NULL) { 1344 OBJLIST *node = objlist; 1345 1346 while (node != NULL) { 1347 CK_RV ckrv; 1348 ckrv = C_DestroyObject(kmfh->pk11handle, node->handle); 1349 if (ckrv != CKR_OK) { 1350 SET_ERROR(kmfh, ckrv); 1351 rv = KMF_ERR_INTERNAL; 1352 break; 1353 } 1354 node = node->next; 1355 } 1356 free_objlist(objlist); 1357 } 1358 1359 if (rv == KMF_OK && numObjects == 0) 1360 rv = KMF_ERR_CERT_NOT_FOUND; 1361 1362 out: 1363 return (rv); 1364 } 1365 1366 KMF_RETURN 1367 KMFPK11_CreateKeypair(KMF_HANDLE_T handle, 1368 int numattr, 1369 KMF_ATTRIBUTE *attlist) 1370 { 1371 KMF_RETURN rv = KMF_OK; 1372 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1373 1374 CK_RV ckrv = 0; 1375 CK_OBJECT_HANDLE pubKey = CK_INVALID_HANDLE; 1376 CK_OBJECT_HANDLE priKey = CK_INVALID_HANDLE; 1377 CK_SESSION_HANDLE hSession = kmfh->pk11handle; 1378 1379 static CK_OBJECT_CLASS priClass = CKO_PRIVATE_KEY; 1380 static CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; 1381 1382 static CK_ULONG modulusBits = 1024; 1383 uint32_t modulusBits_size = sizeof (CK_ULONG); 1384 static CK_BYTE PubExpo[3] = {0x01, 0x00, 0x01}; 1385 static CK_BBOOL true = TRUE; 1386 static CK_BBOOL ontoken = TRUE; 1387 static CK_BBOOL false = FALSE; 1388 static CK_ULONG dsaKeyType = CKK_DSA; 1389 1390 CK_ATTRIBUTE rsaPubKeyTemplate[16]; 1391 CK_ATTRIBUTE rsaPriKeyTemplate[16]; 1392 1393 static CK_BYTE ckDsaPrime[128] = { 1394 0xb2, 0x6b, 0xc3, 0xfb, 0xe3, 0x26, 0xf4, 0xc2, 1395 0xcf, 0xdd, 0xf9, 0xae, 0x3e, 0x39, 0x7f, 0x9c, 1396 0xa7, 0x73, 0xc3, 0x00, 0xa3, 0x50, 0x67, 0xc3, 1397 0xab, 0x49, 0x2c, 0xea, 0x59, 0x10, 0xa4, 0xbc, 1398 0x09, 0x94, 0xa9, 0x05, 0x3b, 0x0d, 0x35, 0x3c, 1399 0x55, 0x52, 0x47, 0xf0, 0xe3, 0x72, 0x5b, 0xe8, 1400 0x72, 0xa0, 0x71, 0x1c, 0x23, 0x4f, 0x6d, 0xe8, 1401 0xac, 0xe5, 0x21, 0x1b, 0xc0, 0xd8, 0x42, 0xd3, 1402 0x87, 0xae, 0x83, 0x5e, 0x52, 0x7e, 0x46, 0x09, 1403 0xb5, 0xc7, 0x3d, 0xd6, 0x00, 0xf5, 0xf2, 0x9c, 1404 0x84, 0x30, 0x81, 0x7e, 0x7b, 0x30, 0x5b, 0xd5, 1405 0xab, 0xd0, 0x2f, 0x21, 0xb3, 0xd8, 0xed, 0xdb, 1406 0x97, 0x77, 0xe4, 0x7e, 0x6c, 0xcc, 0xb9, 0x6b, 1407 0xdd, 0xaa, 0x96, 0x04, 0xe7, 0xd4, 0x55, 0x11, 1408 0x53, 0xab, 0xba, 0x95, 0x9a, 0xa2, 0x8c, 0x27, 1409 0xd9, 0xcf, 0xad, 0xf3, 0xcf, 0x3a, 0x0c, 0x4b}; 1410 1411 static CK_BYTE ckDsaSubPrime[20] = { 1412 0xa4, 0x5f, 0x2a, 0x27, 0x09, 0x49, 0xb6, 0xfe, 1413 0x73, 0xeb, 0x95, 0x7d, 0x00, 0xf3, 0x42, 0xfc, 1414 0x78, 0x47, 0xb0, 0xd5}; 1415 1416 static CK_BYTE ckDsaBase[128] = { 1417 0x5c, 0x57, 0x16, 0x49, 0xef, 0xc8, 0xfb, 0x4b, 1418 0xee, 0x07, 0x45, 0x3b, 0x6a, 0x1d, 0xf3, 0xe5, 1419 0xeb, 0xee, 0xad, 0x11, 0x13, 0xe3, 0x52, 0xe3, 1420 0x0d, 0xc0, 0x21, 0x25, 0xfa, 0xf0, 0x93, 0x1c, 1421 0x53, 0x4d, 0xdc, 0x0d, 0x76, 0xd2, 0xfe, 0xc2, 1422 0xd7, 0x72, 0x64, 0x69, 0x53, 0x3d, 0x33, 0xbd, 1423 0xe1, 0x34, 0xf2, 0x5a, 0x67, 0x83, 0xe0, 0xd3, 1424 0x1c, 0xd6, 0x41, 0x4d, 0x16, 0xe8, 0x6c, 0x5a, 1425 0x07, 0x95, 0x21, 0x9a, 0xa3, 0xc4, 0xb9, 0x05, 1426 0x9d, 0x11, 0xcb, 0xc8, 0xc4, 0x9d, 0x00, 0x1a, 1427 0xf4, 0x85, 0x2a, 0xa9, 0x20, 0x3c, 0xba, 0x67, 1428 0xe5, 0xed, 0x31, 0xb2, 0x11, 0xfb, 0x1f, 0x73, 1429 0xec, 0x61, 0x29, 0xad, 0xc7, 0x68, 0xb2, 0x3f, 1430 0x38, 0xea, 0xd9, 0x87, 0x83, 0x9e, 0x7e, 0x19, 1431 0x18, 0xdd, 0xc2, 0xc3, 0x5b, 0x16, 0x6d, 0xce, 1432 0xcf, 0x88, 0x91, 0x07, 0xe0, 0x2b, 0xa8, 0x54 }; 1433 1434 static CK_ATTRIBUTE ckDsaPubKeyTemplate[] = { 1435 { CKA_CLASS, &pubClass, sizeof (pubClass) }, 1436 { CKA_KEY_TYPE, &dsaKeyType, sizeof (dsaKeyType) }, 1437 { CKA_TOKEN, &ontoken, sizeof (ontoken)}, 1438 { CKA_PRIVATE, &false, sizeof (false)}, 1439 { CKA_PRIME, &ckDsaPrime, sizeof (ckDsaPrime) }, 1440 { CKA_SUBPRIME, &ckDsaSubPrime, sizeof (ckDsaSubPrime)}, 1441 { CKA_BASE, &ckDsaBase, sizeof (ckDsaBase) }, 1442 { CKA_VERIFY, &true, sizeof (true) }, 1443 }; 1444 1445 #define NUMBER_DSA_PUB_TEMPLATES (sizeof (ckDsaPubKeyTemplate) / \ 1446 sizeof (CK_ATTRIBUTE)) 1447 #define MAX_DSA_PUB_TEMPLATES (sizeof (ckDsaPubKeyTemplate) / \ 1448 sizeof (CK_ATTRIBUTE)) 1449 1450 static CK_ATTRIBUTE ckDsaPriKeyTemplate[] = { 1451 {CKA_CLASS, &priClass, sizeof (priClass)}, 1452 {CKA_KEY_TYPE, &dsaKeyType, sizeof (dsaKeyType)}, 1453 {CKA_TOKEN, &ontoken, sizeof (ontoken)}, 1454 {CKA_PRIVATE, &true, sizeof (true)}, 1455 {CKA_SIGN, &true, sizeof (true)}, 1456 }; 1457 1458 CK_ATTRIBUTE labelattr[1]; 1459 CK_ATTRIBUTE idattr[1]; 1460 char IDHashData[SHA1_HASH_LENGTH]; 1461 KMF_DATA IDInput, IDOutput; 1462 SHA1_CTX ctx; 1463 KMF_CREDENTIAL *cred; 1464 KMF_KEY_ALG keytype = KMF_RSA; 1465 boolean_t storekey = TRUE; 1466 char *keylabel = NULL; 1467 KMF_KEY_HANDLE *pubkey, *privkey; 1468 1469 #define NUMBER_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \ 1470 sizeof (CK_ATTRIBUTE)) 1471 #define MAX_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \ 1472 sizeof (CK_ATTRIBUTE)) 1473 1474 if (kmfh == NULL) 1475 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 1476 1477 if (kmfh->pk11handle == CK_INVALID_HANDLE) 1478 return (KMF_ERR_NO_TOKEN_SELECTED); 1479 1480 /* "storekey" is optional. Default is TRUE */ 1481 (void) kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attlist, numattr, 1482 &storekey, NULL); 1483 1484 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attlist, numattr); 1485 if (cred == NULL) 1486 return (KMF_ERR_BAD_PARAMETER); 1487 1488 rv = pk11_authenticate(handle, cred); 1489 if (rv != KMF_OK) 1490 return (rv); 1491 1492 /* keytype is optional. KMF_RSA is default */ 1493 (void) kmf_get_attr(KMF_KEYALG_ATTR, attlist, numattr, 1494 (void *)&keytype, NULL); 1495 1496 pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr); 1497 if (pubkey == NULL) 1498 return (KMF_ERR_BAD_PARAMETER); 1499 1500 privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist, numattr); 1501 if (privkey == NULL) 1502 return (KMF_ERR_BAD_PARAMETER); 1503 1504 (void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE)); 1505 (void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE)); 1506 if (keytype == KMF_RSA) { 1507 CK_MECHANISM keyGenMech = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0}; 1508 CK_BYTE *modulus; 1509 CK_ULONG modulusLength = 0; 1510 CK_ATTRIBUTE modattr[1]; 1511 KMF_BIGINT *rsaexp = NULL; 1512 int numpubattr = 0, numpriattr = 0; 1513 1514 rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attlist, numattr, 1515 &modulusBits, &modulusBits_size); 1516 if (rv == KMF_ERR_ATTR_NOT_FOUND) 1517 /* Default modulusBits = 1024 */ 1518 rv = KMF_OK; 1519 if (rv != KMF_OK) 1520 return (KMF_ERR_BAD_PARAMETER); 1521 1522 SETATTR(rsaPubKeyTemplate, numpubattr, CKA_TOKEN, 1523 (storekey ? &true : &false), sizeof (CK_BBOOL)); 1524 numpubattr++; 1525 1526 SETATTR(rsaPubKeyTemplate, numpubattr, CKA_MODULUS_BITS, 1527 &modulusBits, sizeof (modulusBits)); 1528 numpubattr++; 1529 1530 if ((rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attlist, 1531 numattr)) != NULL && 1532 (rsaexp->len > 0 && rsaexp->val != NULL)) { 1533 SETATTR(rsaPubKeyTemplate, numpubattr, 1534 CKA_PUBLIC_EXPONENT, 1535 rsaexp->val, rsaexp->len); 1536 numpubattr++; 1537 } else { 1538 rv = KMF_OK; 1539 SETATTR(rsaPubKeyTemplate, numpubattr, 1540 CKA_PUBLIC_EXPONENT, &PubExpo, sizeof (PubExpo)); 1541 numpubattr++; 1542 } 1543 SETATTR(rsaPubKeyTemplate, numpubattr, CKA_ENCRYPT, 1544 &true, sizeof (true)); 1545 numpubattr++; 1546 SETATTR(rsaPubKeyTemplate, numpubattr, CKA_VERIFY, 1547 &true, sizeof (true)); 1548 numpubattr++; 1549 SETATTR(rsaPubKeyTemplate, numpubattr, CKA_WRAP, 1550 &true, sizeof (true)); 1551 numpubattr++; 1552 1553 SETATTR(rsaPriKeyTemplate, numpriattr, CKA_TOKEN, 1554 (storekey ? &true : &false), sizeof (CK_BBOOL)); 1555 numpriattr++; 1556 SETATTR(rsaPriKeyTemplate, numpriattr, CKA_PRIVATE, &true, 1557 sizeof (true)); 1558 numpriattr++; 1559 SETATTR(rsaPriKeyTemplate, numpriattr, CKA_DECRYPT, &true, 1560 sizeof (true)); 1561 numpriattr++; 1562 SETATTR(rsaPriKeyTemplate, numpriattr, CKA_SIGN, &true, 1563 sizeof (true)); 1564 numpriattr++; 1565 SETATTR(rsaPriKeyTemplate, numpriattr, CKA_UNWRAP, &true, 1566 sizeof (true)); 1567 numpriattr++; 1568 1569 1570 pubKey = CK_INVALID_HANDLE; 1571 priKey = CK_INVALID_HANDLE; 1572 ckrv = C_GenerateKeyPair(hSession, &keyGenMech, 1573 rsaPubKeyTemplate, numpubattr, 1574 rsaPriKeyTemplate, numpriattr, 1575 &pubKey, &priKey); 1576 if (ckrv != CKR_OK) { 1577 SET_ERROR(kmfh, ckrv); 1578 return (KMF_ERR_KEYGEN_FAILED); 1579 } 1580 1581 privkey->kstype = KMF_KEYSTORE_PK11TOKEN; 1582 privkey->keyalg = KMF_RSA; 1583 privkey->keyclass = KMF_ASYM_PRI; 1584 privkey->keyp = (void *)priKey; 1585 1586 pubkey->kstype = KMF_KEYSTORE_PK11TOKEN; 1587 pubkey->keyalg = KMF_RSA; 1588 pubkey->keyclass = KMF_ASYM_PUB; 1589 pubkey->keyp = (void *)pubKey; 1590 1591 SETATTR(modattr, 0, CKA_MODULUS, NULL, modulusLength); 1592 /* Get the Modulus field to use as input for creating the ID */ 1593 ckrv = C_GetAttributeValue(kmfh->pk11handle, 1594 (CK_OBJECT_HANDLE)pubKey, modattr, 1); 1595 if (ckrv != CKR_OK) { 1596 SET_ERROR(kmfh, ckrv); 1597 return (KMF_ERR_BAD_PARAMETER); 1598 } 1599 1600 modulusLength = modattr[0].ulValueLen; 1601 modulus = malloc(modulusLength); 1602 if (modulus == NULL) 1603 return (KMF_ERR_MEMORY); 1604 1605 modattr[0].pValue = modulus; 1606 ckrv = C_GetAttributeValue(kmfh->pk11handle, 1607 (CK_OBJECT_HANDLE)pubKey, modattr, 1); 1608 if (ckrv != CKR_OK) { 1609 SET_ERROR(kmfh, ckrv); 1610 free(modulus); 1611 return (KMF_ERR_BAD_PARAMETER); 1612 } 1613 1614 IDInput.Data = modulus; 1615 IDInput.Length = modulusLength; 1616 1617 } else if (keytype == KMF_DSA) { 1618 CK_MECHANISM keyGenMech = {CKM_DSA_KEY_PAIR_GEN, NULL, 0}; 1619 CK_BYTE *keyvalue; 1620 CK_ULONG valueLen; 1621 CK_ATTRIBUTE valattr[1]; 1622 1623 SETATTR(ckDsaPriKeyTemplate, 2, CKA_TOKEN, 1624 (storekey ? &true : &false), sizeof (CK_BBOOL)); 1625 SETATTR(valattr, 0, CKA_VALUE, NULL, &valueLen); 1626 1627 ckrv = C_GenerateKeyPair(hSession, &keyGenMech, 1628 ckDsaPubKeyTemplate, 1629 (sizeof (ckDsaPubKeyTemplate)/sizeof (CK_ATTRIBUTE)), 1630 ckDsaPriKeyTemplate, 1631 (sizeof (ckDsaPriKeyTemplate)/sizeof (CK_ATTRIBUTE)), 1632 &pubKey, &priKey); 1633 if (ckrv != CKR_OK) { 1634 SET_ERROR(kmfh, ckrv); 1635 return (KMF_ERR_KEYGEN_FAILED); 1636 } 1637 1638 privkey->kstype = KMF_KEYSTORE_PK11TOKEN; 1639 privkey->keyalg = KMF_DSA; 1640 privkey->keyclass = KMF_ASYM_PRI; 1641 privkey->keyp = (void *)priKey; 1642 1643 pubkey->kstype = KMF_KEYSTORE_PK11TOKEN; 1644 pubkey->keyalg = KMF_DSA; 1645 pubkey->keyclass = KMF_ASYM_PUB; 1646 pubkey->keyp = (void *)pubKey; 1647 1648 /* Get the Public Value to use as input for creating the ID */ 1649 ckrv = C_GetAttributeValue(hSession, 1650 (CK_OBJECT_HANDLE)pubKey, valattr, 1); 1651 if (ckrv != CKR_OK) { 1652 SET_ERROR(kmfh, ckrv); 1653 return (KMF_ERR_BAD_PARAMETER); 1654 } 1655 1656 valueLen = valattr[0].ulValueLen; 1657 keyvalue = malloc(valueLen); 1658 if (keyvalue == NULL) 1659 return (KMF_ERR_MEMORY); 1660 1661 valattr[0].pValue = keyvalue; 1662 ckrv = C_GetAttributeValue(hSession, 1663 (CK_OBJECT_HANDLE)pubKey, valattr, 1); 1664 if (ckrv != CKR_OK) { 1665 SET_ERROR(kmfh, ckrv); 1666 free(keyvalue); 1667 return (KMF_ERR_BAD_PARAMETER); 1668 } 1669 1670 IDInput.Data = keyvalue; 1671 IDInput.Length = valueLen; 1672 } else { 1673 return (KMF_ERR_BAD_PARAMETER); 1674 } 1675 1676 keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attlist, numattr); 1677 if (keylabel != NULL && strlen(keylabel)) { 1678 SETATTR(labelattr, 0, CKA_LABEL, keylabel, strlen(keylabel)); 1679 1680 /* Set the CKA_LABEL if one was indicated */ 1681 if ((ckrv = C_SetAttributeValue(hSession, pubKey, 1682 labelattr, 1)) != CKR_OK) { 1683 SET_ERROR(kmfh, ckrv); 1684 rv = KMF_ERR_INTERNAL; 1685 goto cleanup; 1686 } 1687 pubkey->keylabel = (char *)strdup(keylabel); 1688 if (pubkey->keylabel == NULL) { 1689 rv = KMF_ERR_MEMORY; 1690 goto cleanup; 1691 } 1692 if ((ckrv = C_SetAttributeValue(hSession, priKey, 1693 labelattr, 1)) != CKR_OK) { 1694 SET_ERROR(kmfh, ckrv); 1695 rv = KMF_ERR_INTERNAL; 1696 goto cleanup; 1697 } 1698 privkey->keylabel = (char *)strdup(keylabel); 1699 if (privkey->keylabel == NULL) { 1700 rv = KMF_ERR_MEMORY; 1701 goto cleanup; 1702 } 1703 } else { 1704 rv = KMF_OK; 1705 } 1706 1707 /* Now, assign a CKA_ID value so it can be searched */ 1708 /* ID_Input was assigned above in the RSA or DSA keygen section */ 1709 IDOutput.Data = (uchar_t *)IDHashData; 1710 IDOutput.Length = sizeof (IDHashData); 1711 1712 SHA1Init(&ctx); 1713 SHA1Update(&ctx, IDInput.Data, IDInput.Length); 1714 SHA1Final(IDOutput.Data, &ctx); 1715 1716 IDOutput.Length = SHA1_DIGEST_LENGTH; 1717 1718 free(IDInput.Data); 1719 1720 if (rv != CKR_OK) { 1721 goto cleanup; 1722 } 1723 SETATTR(idattr, 0, CKA_ID, IDOutput.Data, IDOutput.Length); 1724 if ((ckrv = C_SetAttributeValue(hSession, pubKey, 1725 idattr, 1)) != CKR_OK) { 1726 SET_ERROR(kmfh, ckrv); 1727 rv = KMF_ERR_INTERNAL; 1728 goto cleanup; 1729 } 1730 if ((ckrv = C_SetAttributeValue(hSession, priKey, 1731 idattr, 1)) != CKR_OK) { 1732 SET_ERROR(kmfh, ckrv); 1733 rv = KMF_ERR_INTERNAL; 1734 goto cleanup; 1735 } 1736 1737 cleanup: 1738 if (rv != KMF_OK) { 1739 if (pubKey != CK_INVALID_HANDLE) 1740 (void) C_DestroyObject(hSession, pubKey); 1741 if (priKey != CK_INVALID_HANDLE) 1742 (void) C_DestroyObject(hSession, priKey); 1743 1744 if (privkey->keylabel) 1745 free(privkey->keylabel); 1746 if (pubkey->keylabel) 1747 free(pubkey->keylabel); 1748 } 1749 return (rv); 1750 } 1751 1752 KMF_RETURN 1753 KMFPK11_DeleteKey(KMF_HANDLE_T handle, 1754 int numattr, KMF_ATTRIBUTE *attrlist) 1755 { 1756 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1757 CK_RV ckrv = CKR_OK; 1758 KMF_RETURN rv = KMF_OK; 1759 KMF_KEY_HANDLE *key; 1760 KMF_CREDENTIAL cred; 1761 boolean_t destroy = B_TRUE; 1762 1763 if (kmfh == NULL) 1764 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 1765 1766 if (kmfh->pk11handle == CK_INVALID_HANDLE) 1767 return (KMF_ERR_NO_TOKEN_SELECTED); 1768 1769 key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 1770 if (key == NULL || key->keyp == NULL) 1771 return (KMF_ERR_BAD_PARAMETER); 1772 1773 if (key->keyclass != KMF_ASYM_PUB && 1774 key->keyclass != KMF_ASYM_PRI && 1775 key->keyclass != KMF_SYMMETRIC) 1776 return (KMF_ERR_BAD_KEY_CLASS); 1777 1778 /* "destroy" is optional. Default is TRUE */ 1779 (void) kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr, 1780 (void *)&destroy, NULL); 1781 1782 if (destroy) { 1783 rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, 1784 (void *)&cred, NULL); 1785 if (rv != KMF_OK) 1786 return (KMF_ERR_BAD_PARAMETER); 1787 1788 rv = pk11_authenticate(handle, &cred); 1789 if (rv != KMF_OK) { 1790 return (rv); 1791 } 1792 } 1793 1794 if (!key->israw && destroy) 1795 ckrv = C_DestroyObject(kmfh->pk11handle, 1796 (CK_OBJECT_HANDLE)key->keyp); 1797 1798 if (ckrv != CKR_OK) { 1799 SET_ERROR(kmfh, ckrv); 1800 /* Report authentication failures to the caller */ 1801 if (ckrv == CKR_PIN_EXPIRED || ckrv == CKR_SESSION_READ_ONLY) 1802 rv = KMF_ERR_AUTH_FAILED; 1803 else 1804 rv = KMF_ERR_INTERNAL; 1805 } 1806 return (rv); 1807 } 1808 1809 KMF_RETURN 1810 KMFPK11_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp, 1811 KMF_OID *algOID, 1812 KMF_DATA *tobesigned, 1813 KMF_DATA *output) 1814 { 1815 CK_RV ckrv; 1816 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1817 CK_SESSION_HANDLE hSession = kmfh->pk11handle; 1818 CK_MECHANISM mechanism; 1819 PKCS_ALGORITHM_MAP *pAlgMap; 1820 KMF_ALGORITHM_INDEX AlgId; 1821 1822 if (kmfh == NULL) 1823 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 1824 1825 if (kmfh->pk11handle == CK_INVALID_HANDLE) 1826 return (KMF_ERR_NO_TOKEN_SELECTED); 1827 1828 if (keyp == NULL || algOID == NULL || 1829 tobesigned == NULL || output == NULL) 1830 return (KMF_ERR_BAD_PARAMETER); 1831 1832 /* These functions are available to the plugin from libkmf */ 1833 AlgId = x509_algoid_to_algid(algOID); 1834 if (AlgId == KMF_ALGID_NONE) 1835 return (KMF_ERR_BAD_PARAMETER); 1836 1837 /* Map the Algorithm OID to a PKCS#11 mechanism */ 1838 pAlgMap = pkcs_get_alg_map(KMF_ALGCLASS_SIGNATURE, 1839 AlgId, PKCS_GetDefaultSignatureMode(AlgId)); 1840 1841 if (pAlgMap == NULL) 1842 return (KMF_ERR_BAD_PARAMETER); 1843 1844 mechanism.mechanism = pAlgMap->pkcs_mechanism; 1845 mechanism.pParameter = NULL; 1846 mechanism.ulParameterLen = 0; 1847 1848 ckrv = C_SignInit(hSession, &mechanism, (CK_OBJECT_HANDLE)keyp->keyp); 1849 if (ckrv != CKR_OK) { 1850 SET_ERROR(kmfh, ckrv); 1851 return (KMF_ERR_INTERNAL); 1852 } 1853 1854 ckrv = C_Sign(hSession, tobesigned->Data, tobesigned->Length, 1855 output->Data, (CK_ULONG *)&output->Length); 1856 1857 if (ckrv != CKR_OK) { 1858 SET_ERROR(kmfh, ckrv); 1859 return (KMF_ERR_INTERNAL); 1860 } 1861 1862 return (KMF_OK); 1863 } 1864 1865 KMF_RETURN 1866 KMFPK11_GetErrorString(KMF_HANDLE_T handle, char **msgstr) 1867 { 1868 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1869 1870 *msgstr = NULL; 1871 if (kmfh->lasterr.errcode != 0) { 1872 char *e = pkcs11_strerror(kmfh->lasterr.errcode); 1873 if (e == NULL || (*msgstr = (char *)strdup(e)) == NULL) { 1874 return (KMF_ERR_MEMORY); 1875 } 1876 } 1877 1878 return (KMF_OK); 1879 } 1880 1881 static CK_RV 1882 getObjectKeytype(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj, 1883 CK_ULONG *keytype) 1884 { 1885 CK_RV rv = CKR_OK; 1886 CK_ATTRIBUTE templ; 1887 CK_ULONG len = sizeof (CK_ULONG); 1888 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1889 1890 templ.type = CKA_KEY_TYPE; 1891 templ.pValue = keytype; 1892 templ.ulValueLen = len; 1893 1894 rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1); 1895 1896 return (rv); 1897 1898 } 1899 1900 static CK_RV 1901 getObjectLabel(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj, 1902 char **outlabel) 1903 { 1904 CK_RV rv = CKR_OK; 1905 CK_ATTRIBUTE templ; 1906 char Label[BUFSIZ]; 1907 CK_ULONG len = sizeof (Label); 1908 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1909 1910 (void) memset(Label, 0, len); 1911 templ.type = CKA_LABEL; 1912 templ.pValue = Label; 1913 templ.ulValueLen = len; 1914 1915 rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1); 1916 if (rv == CKR_OK) { 1917 *outlabel = (char *)strdup(Label); 1918 } else { 1919 *outlabel = NULL; 1920 } 1921 return (rv); 1922 } 1923 1924 static CK_RV 1925 getObjectKeyclass(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj, 1926 KMF_KEY_CLASS *keyclass) 1927 { 1928 CK_RV rv = CKR_OK; 1929 CK_ATTRIBUTE templ; 1930 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1931 CK_OBJECT_CLASS class; 1932 1933 templ.type = CKA_CLASS; 1934 templ.pValue = &class; 1935 templ.ulValueLen = sizeof (CK_OBJECT_CLASS); 1936 1937 rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1); 1938 if (rv == CKR_OK) { 1939 if (class == CKO_PUBLIC_KEY) { 1940 *keyclass = KMF_ASYM_PUB; 1941 } else if (class == CKO_PRIVATE_KEY) { 1942 *keyclass = KMF_ASYM_PRI; 1943 } else if (class == CKO_SECRET_KEY) { 1944 *keyclass = KMF_SYMMETRIC; 1945 } 1946 } else { 1947 *keyclass = KMF_KEYCLASS_NONE; 1948 } 1949 return (rv); 1950 } 1951 1952 KMF_RETURN 1953 KMFPK11_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr, 1954 KMF_ATTRIBUTE *attrlist) 1955 { 1956 KMF_X509_SPKI *pubkey; 1957 KMF_X509_CERTIFICATE *SignerCert = NULL; 1958 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1959 KMF_RETURN rv = KMF_OK; 1960 CK_RV ckrv = CKR_OK; 1961 CK_ATTRIBUTE templ[4]; 1962 CK_OBJECT_HANDLE pri_obj = CK_INVALID_HANDLE; 1963 CK_ULONG obj_count; 1964 CK_OBJECT_CLASS certClass = CKO_PRIVATE_KEY; 1965 CK_BBOOL true = TRUE; 1966 KMF_DATA Id = { NULL, 0 }; 1967 KMF_KEY_HANDLE *key = NULL; 1968 KMF_DATA *cert = NULL; 1969 KMF_CREDENTIAL cred; 1970 KMF_ENCODE_FORMAT format = KMF_FORMAT_UNDEF; 1971 CK_ULONG keytype; 1972 1973 /* Get the key handle */ 1974 key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 1975 if (key == NULL) 1976 return (KMF_ERR_BAD_PARAMETER); 1977 1978 /* Get the optional encoded format */ 1979 (void) kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, 1980 (void *)&format, NULL); 1981 1982 /* Decode the signer cert so we can get the SPKI data */ 1983 cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); 1984 if (cert == NULL || cert->Data == NULL) 1985 return (KMF_ERR_BAD_PARAMETER); 1986 1987 if ((rv = DerDecodeSignedCertificate(cert, 1988 &SignerCert)) != KMF_OK) 1989 return (rv); 1990 1991 /* Get the public key info from the signer certificate */ 1992 pubkey = &SignerCert->certificate.subjectPublicKeyInfo; 1993 1994 /* Generate an ID from the SPKI data */ 1995 rv = GetIDFromSPKI(pubkey, &Id); 1996 if (rv != KMF_OK) { 1997 goto errout; 1998 } 1999 2000 /* Get the credential and login */ 2001 rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, 2002 (void *)&cred, NULL); 2003 if (rv != KMF_OK) 2004 return (KMF_ERR_BAD_PARAMETER); 2005 2006 rv = pk11_authenticate(handle, &cred); 2007 if (rv != KMF_OK) { 2008 return (rv); 2009 } 2010 2011 /* Start searching */ 2012 SETATTR(templ, 0, CKA_CLASS, &certClass, sizeof (certClass)); 2013 SETATTR(templ, 1, CKA_TOKEN, &true, sizeof (true)); 2014 SETATTR(templ, 2, CKA_PRIVATE, &true, sizeof (true)); 2015 SETATTR(templ, 3, CKA_ID, Id.Data, Id.Length); 2016 2017 if ((ckrv = C_FindObjectsInit(kmfh->pk11handle, templ, 4)) != CKR_OK) { 2018 SET_ERROR(kmfh, ckrv); 2019 rv = KMF_ERR_INTERNAL; 2020 goto errout; 2021 } 2022 2023 if ((ckrv = C_FindObjects(kmfh->pk11handle, &pri_obj, 1, 2024 &obj_count)) != CKR_OK) { 2025 SET_ERROR(kmfh, ckrv); 2026 rv = KMF_ERR_INTERNAL; 2027 goto errout; 2028 } 2029 2030 if (obj_count == 0) { 2031 SET_ERROR(kmfh, ckrv); 2032 rv = KMF_ERR_INTERNAL; 2033 goto errout; 2034 } 2035 2036 key->kstype = KMF_KEYSTORE_PK11TOKEN; 2037 key->keyclass = KMF_ASYM_PRI; 2038 key->keyp = (void *)pri_obj; 2039 key->israw = FALSE; 2040 2041 (void) C_FindObjectsFinal(kmfh->pk11handle); 2042 2043 ckrv = getObjectLabel(handle, (CK_OBJECT_HANDLE)key->keyp, 2044 &key->keylabel); 2045 if (ckrv != CKR_OK) { 2046 SET_ERROR(handle, ckrv); 2047 rv = KMF_ERR_INTERNAL; 2048 } else { 2049 rv = KMF_OK; 2050 } 2051 2052 /* 2053 * The key->keyalg value is needed if we need to convert the key 2054 * to raw key. However, the key->keyalg value will not be set if 2055 * this function is not called thru the kmf_find_prikey_by_cert() 2056 * framework function. To be safe, we will get the keytype from 2057 * the key object and set key->keyalg value here. 2058 */ 2059 ckrv = getObjectKeytype(handle, (CK_OBJECT_HANDLE)key->keyp, 2060 &keytype); 2061 if (ckrv != CKR_OK) { 2062 SET_ERROR(handle, ckrv); 2063 rv = KMF_ERR_INTERNAL; 2064 } else { 2065 rv = KMF_OK; 2066 } 2067 2068 if (keytype == CKK_RSA) 2069 key->keyalg = KMF_RSA; 2070 else if (keytype == CKK_DSA) 2071 key->keyalg = KMF_DSA; 2072 else { 2073 /* For asymmetric keys, we only support RSA and DSA */ 2074 rv = KMF_ERR_KEY_NOT_FOUND; 2075 goto errout; 2076 } 2077 2078 if (rv == KMF_OK && format == KMF_FORMAT_RAWKEY) { 2079 KMF_RAW_KEY_DATA *rkey = NULL; 2080 rv = keyObj2RawKey(handle, key, &rkey); 2081 if (rv == KMF_OK) { 2082 key->keyp = rkey; 2083 key->israw = TRUE; 2084 } 2085 } 2086 2087 errout: 2088 if (Id.Data != NULL) 2089 free(Id.Data); 2090 2091 if (SignerCert != NULL) { 2092 kmf_free_signed_cert(SignerCert); 2093 free(SignerCert); 2094 } 2095 return (rv); 2096 } 2097 2098 KMF_RETURN 2099 KMFPK11_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 2100 KMF_OID *algOID, KMF_DATA *ciphertext, 2101 KMF_DATA *output) 2102 { 2103 CK_RV ckrv; 2104 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2105 CK_SESSION_HANDLE hSession = kmfh->pk11handle; 2106 CK_MECHANISM mechanism; 2107 PKCS_ALGORITHM_MAP *pAlgMap; 2108 KMF_ALGORITHM_INDEX AlgId; 2109 CK_ULONG out_len = 0, block_len = 0, total_decrypted = 0; 2110 uint8_t *in_data, *out_data; 2111 int i, blocks; 2112 CK_ATTRIBUTE ckTemplate[1]; 2113 2114 if (kmfh == NULL) 2115 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 2116 2117 if (kmfh->pk11handle == CK_INVALID_HANDLE) 2118 return (KMF_ERR_NO_TOKEN_SELECTED); 2119 2120 if (key == NULL || algOID == NULL || 2121 ciphertext == NULL || output == NULL) 2122 return (KMF_ERR_BAD_PARAMETER); 2123 2124 AlgId = x509_algoid_to_algid(algOID); 2125 if (AlgId == KMF_ALGID_NONE) 2126 return (KMF_ERR_BAD_PARAMETER); 2127 2128 /* Map the Algorithm ID to a PKCS#11 mechanism */ 2129 pAlgMap = pkcs_get_alg_map(KMF_ALGCLASS_SIGNATURE, 2130 AlgId, PKCS_GetDefaultSignatureMode(AlgId)); 2131 2132 if (pAlgMap == NULL) 2133 return (KMF_ERR_BAD_PARAMETER); 2134 2135 mechanism.mechanism = pAlgMap->pkcs_mechanism; 2136 mechanism.pParameter = NULL; 2137 mechanism.ulParameterLen = 0; 2138 2139 SETATTR(ckTemplate, 0, CKA_MODULUS, (CK_BYTE *)NULL, 2140 sizeof (CK_ULONG)); 2141 2142 /* Get the modulus length */ 2143 ckrv = C_GetAttributeValue(hSession, 2144 (CK_OBJECT_HANDLE)key->keyp, ckTemplate, 1); 2145 2146 if (ckrv != CKR_OK) { 2147 SET_ERROR(kmfh, ckrv); 2148 return (KMF_ERR_INTERNAL); 2149 } 2150 2151 block_len = ckTemplate[0].ulValueLen; 2152 2153 /* Compute the number of times to do single-part decryption */ 2154 blocks = ciphertext->Length/block_len; 2155 2156 out_data = output->Data; 2157 in_data = ciphertext->Data; 2158 out_len = block_len - 11; 2159 2160 for (i = 0; i < blocks; i++) { 2161 ckrv = C_DecryptInit(hSession, &mechanism, 2162 (CK_OBJECT_HANDLE)key->keyp); 2163 2164 if (ckrv != CKR_OK) { 2165 SET_ERROR(kmfh, ckrv); 2166 return (KMF_ERR_INTERNAL); 2167 } 2168 2169 ckrv = C_Decrypt(hSession, in_data, block_len, 2170 out_data, (CK_ULONG *)&out_len); 2171 2172 if (ckrv != CKR_OK) { 2173 SET_ERROR(kmfh, ckrv); 2174 return (KMF_ERR_INTERNAL); 2175 } 2176 2177 out_data += out_len; 2178 total_decrypted += out_len; 2179 in_data += block_len; 2180 2181 } 2182 2183 output->Length = total_decrypted; 2184 return (KMF_OK); 2185 } 2186 2187 static void 2188 attr2bigint(CK_ATTRIBUTE_PTR attr, KMF_BIGINT *big) 2189 { 2190 big->val = attr->pValue; 2191 big->len = attr->ulValueLen; 2192 } 2193 2194 static KMF_RETURN 2195 get_bigint_attr(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, 2196 CK_ATTRIBUTE_TYPE attrtype, KMF_BIGINT *bigint) 2197 { 2198 CK_RV ckrv; 2199 CK_ATTRIBUTE attr; 2200 2201 attr.type = attrtype; 2202 attr.pValue = NULL; 2203 attr.ulValueLen = 0; 2204 2205 if ((ckrv = C_GetAttributeValue(sess, obj, 2206 &attr, 1)) != CKR_OK) { 2207 /* Mask this error so the caller can continue */ 2208 if (ckrv == CKR_ATTRIBUTE_TYPE_INVALID) 2209 return (KMF_OK); 2210 else 2211 return (KMF_ERR_INTERNAL); 2212 } 2213 if (attr.ulValueLen > 0 && bigint != NULL) { 2214 attr.pValue = malloc(attr.ulValueLen); 2215 if (attr.pValue == NULL) 2216 return (KMF_ERR_MEMORY); 2217 2218 if ((ckrv = C_GetAttributeValue(sess, obj, 2219 &attr, 1)) != CKR_OK) 2220 if (ckrv != CKR_OK) { 2221 free(attr.pValue); 2222 return (KMF_ERR_INTERNAL); 2223 } 2224 2225 bigint->val = attr.pValue; 2226 bigint->len = attr.ulValueLen; 2227 } 2228 return (KMF_OK); 2229 } 2230 2231 static KMF_RETURN 2232 get_raw_rsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_RSA_KEY *rawrsa) 2233 { 2234 KMF_RETURN rv = KMF_OK; 2235 CK_RV ckrv; 2236 CK_SESSION_HANDLE sess = kmfh->pk11handle; 2237 CK_ATTRIBUTE rsa_pri_attrs[2] = { 2238 { CKA_MODULUS, NULL, 0 }, 2239 { CKA_PUBLIC_EXPONENT, NULL, 0 } 2240 }; 2241 CK_ULONG count = sizeof (rsa_pri_attrs) / sizeof (CK_ATTRIBUTE); 2242 int i; 2243 2244 if (rawrsa == NULL) 2245 return (KMF_ERR_BAD_PARAMETER); 2246 2247 (void) memset(rawrsa, 0, sizeof (KMF_RAW_RSA_KEY)); 2248 if ((ckrv = C_GetAttributeValue(sess, obj, 2249 rsa_pri_attrs, count)) != CKR_OK) { 2250 SET_ERROR(kmfh, ckrv); 2251 /* Tell the caller know why the key data cannot be retrieved. */ 2252 if (ckrv == CKR_ATTRIBUTE_SENSITIVE) 2253 return (KMF_ERR_SENSITIVE_KEY); 2254 else if (ckrv == CKR_KEY_UNEXTRACTABLE) 2255 return (KMF_ERR_UNEXTRACTABLE_KEY); 2256 else 2257 return (KMF_ERR_INTERNAL); 2258 } 2259 2260 /* Allocate memory for each attribute. */ 2261 for (i = 0; i < count; i++) { 2262 if (rsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 || 2263 rsa_pri_attrs[i].ulValueLen == 0) { 2264 rsa_pri_attrs[i].ulValueLen = 0; 2265 continue; 2266 } 2267 if ((rsa_pri_attrs[i].pValue = 2268 malloc(rsa_pri_attrs[i].ulValueLen)) == NULL) { 2269 rv = KMF_ERR_MEMORY; 2270 goto end; 2271 } 2272 } 2273 /* Now that we have space, really get the attributes */ 2274 if ((ckrv = C_GetAttributeValue(sess, obj, 2275 rsa_pri_attrs, count)) != CKR_OK) { 2276 SET_ERROR(kmfh, ckrv); 2277 rv = KMF_ERR_INTERNAL; 2278 goto end; 2279 } 2280 i = 0; 2281 attr2bigint(&(rsa_pri_attrs[i++]), &rawrsa->mod); 2282 attr2bigint(&(rsa_pri_attrs[i++]), &rawrsa->pubexp); 2283 2284 /* Now get the optional parameters */ 2285 rv = get_bigint_attr(sess, obj, CKA_PRIVATE_EXPONENT, &rawrsa->priexp); 2286 if (rv != KMF_OK) 2287 goto end; 2288 rv = get_bigint_attr(sess, obj, CKA_PRIME_1, &rawrsa->prime1); 2289 if (rv != KMF_OK) 2290 goto end; 2291 rv = get_bigint_attr(sess, obj, CKA_PRIME_2, &rawrsa->prime2); 2292 if (rv != KMF_OK) 2293 goto end; 2294 rv = get_bigint_attr(sess, obj, CKA_EXPONENT_1, &rawrsa->exp1); 2295 if (rv != KMF_OK) 2296 goto end; 2297 rv = get_bigint_attr(sess, obj, CKA_EXPONENT_2, &rawrsa->exp2); 2298 if (rv != KMF_OK) 2299 goto end; 2300 rv = get_bigint_attr(sess, obj, CKA_COEFFICIENT, &rawrsa->coef); 2301 if (rv != KMF_OK) 2302 goto end; 2303 2304 end: 2305 if (rv != KMF_OK) { 2306 for (i = 0; i < count; i++) { 2307 if (rsa_pri_attrs[i].pValue != NULL) 2308 free(rsa_pri_attrs[i].pValue); 2309 } 2310 if (rawrsa->priexp.val) 2311 free(rawrsa->priexp.val); 2312 if (rawrsa->prime1.val) 2313 free(rawrsa->prime1.val); 2314 if (rawrsa->prime2.val) 2315 free(rawrsa->prime2.val); 2316 if (rawrsa->exp1.val) 2317 free(rawrsa->exp1.val); 2318 if (rawrsa->exp2.val) 2319 free(rawrsa->exp2.val); 2320 if (rawrsa->coef.val) 2321 free(rawrsa->coef.val); 2322 (void) memset(rawrsa, 0, sizeof (KMF_RAW_RSA_KEY)); 2323 } 2324 return (rv); 2325 } 2326 2327 #define DSA_PRIME_BUFSIZE CHARLEN2BIGNUMLEN(1024) /* 8192 bits */ 2328 #define DSA_PRIVATE_BUFSIZE BIG_CHUNKS_FOR_160BITS /* 160 bits */ 2329 2330 /* 2331 * This function calculates the pubkey value from the prime, 2332 * base and private key values of a DSA key. 2333 */ 2334 static KMF_RETURN 2335 compute_dsa_pubvalue(KMF_RAW_DSA_KEY *rawdsa) 2336 { 2337 KMF_RETURN rv = KMF_OK; 2338 BIGNUM p, g, x, y; 2339 BIG_ERR_CODE err; 2340 uchar_t *pubvalue; 2341 uint32_t pubvalue_len; 2342 2343 if ((err = big_init1(&p, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) { 2344 rv = KMF_ERR_MEMORY; 2345 return (rv); 2346 } 2347 bytestring2bignum(&p, rawdsa->prime.val, rawdsa->prime.len); 2348 2349 if ((err = big_init1(&g, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) { 2350 rv = KMF_ERR_MEMORY; 2351 goto ret1; 2352 } 2353 bytestring2bignum(&g, rawdsa->base.val, rawdsa->base.len); 2354 2355 if ((err = big_init1(&x, DSA_PRIVATE_BUFSIZE, NULL, 0)) != BIG_OK) { 2356 rv = KMF_ERR_MEMORY; 2357 goto ret2; 2358 } 2359 bytestring2bignum(&x, rawdsa->value.val, rawdsa->value.len); 2360 2361 if ((err = big_init1(&y, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) { 2362 rv = KMF_ERR_MEMORY; 2363 goto ret3; 2364 } 2365 2366 err = big_modexp(&y, &g, &x, &p, NULL); 2367 if (err != BIG_OK) { 2368 rv = KMF_ERR_INTERNAL; 2369 goto ret3; 2370 } 2371 2372 pubvalue_len = y.len * (int)sizeof (uint32_t); 2373 if ((pubvalue = malloc(pubvalue_len)) == NULL) { 2374 rv = KMF_ERR_MEMORY; 2375 goto ret4; 2376 } 2377 bignum2bytestring(pubvalue, &y, pubvalue_len); 2378 2379 rawdsa->pubvalue.val = pubvalue; 2380 rawdsa->pubvalue.len = pubvalue_len; 2381 2382 ret4: 2383 big_finish(&y); 2384 ret3: 2385 big_finish(&x); 2386 ret2: 2387 big_finish(&g); 2388 ret1: 2389 big_finish(&p); 2390 return (rv); 2391 } 2392 2393 2394 static KMF_RETURN 2395 get_raw_dsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_DSA_KEY *rawdsa) 2396 { 2397 KMF_RETURN rv = KMF_OK; 2398 CK_RV ckrv; 2399 CK_SESSION_HANDLE sess = kmfh->pk11handle; 2400 CK_ATTRIBUTE dsa_pri_attrs[8] = { 2401 { CKA_PRIME, NULL, 0 }, 2402 { CKA_SUBPRIME, NULL, 0 }, 2403 { CKA_BASE, NULL, 0 }, 2404 { CKA_VALUE, NULL, 0 } 2405 }; 2406 CK_ULONG count = sizeof (dsa_pri_attrs) / sizeof (CK_ATTRIBUTE); 2407 int i; 2408 2409 if ((ckrv = C_GetAttributeValue(sess, obj, 2410 dsa_pri_attrs, count)) != CKR_OK) { 2411 SET_ERROR(kmfh, ckrv); 2412 2413 /* Tell the caller know why the key data cannot be retrieved. */ 2414 if (ckrv == CKR_ATTRIBUTE_SENSITIVE) 2415 return (KMF_ERR_SENSITIVE_KEY); 2416 else if (ckrv == CKR_KEY_UNEXTRACTABLE) 2417 return (KMF_ERR_UNEXTRACTABLE_KEY); 2418 return (KMF_ERR_INTERNAL); 2419 } 2420 2421 /* Allocate memory for each attribute. */ 2422 for (i = 0; i < count; i++) { 2423 if (dsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 || 2424 dsa_pri_attrs[i].ulValueLen == 0) { 2425 dsa_pri_attrs[i].ulValueLen = 0; 2426 continue; 2427 } 2428 if ((dsa_pri_attrs[i].pValue = 2429 malloc(dsa_pri_attrs[i].ulValueLen)) == NULL) { 2430 rv = KMF_ERR_MEMORY; 2431 goto end; 2432 } 2433 } 2434 if ((ckrv = C_GetAttributeValue(sess, obj, 2435 dsa_pri_attrs, count)) != CKR_OK) { 2436 SET_ERROR(kmfh, ckrv); 2437 rv = KMF_ERR_INTERNAL; 2438 goto end; 2439 } 2440 2441 /* Fill in all the temp variables. They are all required. */ 2442 i = 0; 2443 attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->prime); 2444 attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->subprime); 2445 attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->base); 2446 attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->value); 2447 2448 /* Compute the public key value and store it */ 2449 rv = compute_dsa_pubvalue(rawdsa); 2450 2451 end: 2452 if (rv != KMF_OK) { 2453 for (i = 0; i < count; i++) { 2454 if (dsa_pri_attrs[i].pValue != NULL) 2455 free(dsa_pri_attrs[i].pValue); 2456 } 2457 (void) memset(rawdsa, 0, sizeof (KMF_RAW_DSA_KEY)); 2458 } 2459 return (rv); 2460 } 2461 2462 static KMF_RETURN 2463 get_raw_sym(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_SYM_KEY *rawsym) 2464 { 2465 KMF_RETURN rv = KMF_OK; 2466 CK_RV ckrv; 2467 CK_SESSION_HANDLE sess = kmfh->pk11handle; 2468 CK_ATTRIBUTE sym_attr[1]; 2469 CK_ULONG value_len = 0; 2470 2471 /* find the key length first */ 2472 sym_attr[0].type = CKA_VALUE; 2473 sym_attr[0].pValue = NULL; 2474 sym_attr[0].ulValueLen = value_len; 2475 if ((ckrv = C_GetAttributeValue(sess, obj, sym_attr, 1)) != CKR_OK) { 2476 rawsym->keydata.val = NULL; 2477 rawsym->keydata.len = 0; 2478 if (ckrv == CKR_ATTRIBUTE_SENSITIVE) { 2479 return (KMF_ERR_SENSITIVE_KEY); 2480 } else if (ckrv == CKR_KEY_UNEXTRACTABLE) { 2481 return (KMF_ERR_UNEXTRACTABLE_KEY); 2482 } else { 2483 SET_ERROR(kmfh, ckrv); 2484 return (KMF_ERR_INTERNAL); 2485 } 2486 } 2487 2488 /* Allocate memory for pValue */ 2489 sym_attr[0].pValue = malloc(sym_attr[0].ulValueLen); 2490 if (sym_attr[0].pValue == NULL) { 2491 return (KMF_ERR_MEMORY); 2492 } 2493 2494 /* get the key data */ 2495 if ((ckrv = C_GetAttributeValue(sess, obj, sym_attr, 1)) != CKR_OK) { 2496 SET_ERROR(kmfh, ckrv); 2497 free(sym_attr[0].pValue); 2498 return (KMF_ERR_INTERNAL); 2499 } 2500 2501 rawsym->keydata.val = sym_attr[0].pValue; 2502 rawsym->keydata.len = sym_attr[0].ulValueLen; 2503 return (rv); 2504 } 2505 2506 static KMF_RETURN 2507 keyObj2RawKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *inkey, 2508 KMF_RAW_KEY_DATA **outkey) 2509 { 2510 KMF_RETURN rv = KMF_OK; 2511 KMF_RAW_KEY_DATA *rkey; 2512 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2513 2514 rkey = malloc(sizeof (KMF_RAW_KEY_DATA)); 2515 if (rkey == NULL) 2516 return (KMF_ERR_MEMORY); 2517 2518 (void) memset(rkey, 0, sizeof (KMF_RAW_KEY_DATA)); 2519 2520 rkey->keytype = inkey->keyalg; 2521 2522 if (inkey->keyalg == KMF_RSA) { 2523 rv = get_raw_rsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp, 2524 &rkey->rawdata.rsa); 2525 } else if (inkey->keyalg == KMF_DSA) { 2526 rv = get_raw_dsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp, 2527 &rkey->rawdata.dsa); 2528 } else if (inkey->keyalg == KMF_AES || 2529 inkey->keyalg == KMF_RC4 || 2530 inkey->keyalg == KMF_DES || 2531 inkey->keyalg == KMF_DES3 || 2532 inkey->keyalg == KMF_GENERIC_SECRET) { 2533 rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)inkey->keyp, 2534 &rkey->rawdata.sym); 2535 /* 2536 * If sensitive or non-extractable, mark them as such 2537 * but return "OK" status so the keys get counted 2538 * when doing FindKey operations. 2539 */ 2540 if (rv == KMF_ERR_SENSITIVE_KEY) { 2541 rkey->sensitive = B_TRUE; 2542 rv = KMF_OK; 2543 } else if (rv == KMF_ERR_UNEXTRACTABLE_KEY) { 2544 rkey->not_extractable = B_TRUE; 2545 rv = KMF_OK; 2546 } 2547 } else { 2548 rv = KMF_ERR_BAD_PARAMETER; 2549 } 2550 2551 if (rv == KMF_OK) { 2552 *outkey = rkey; 2553 } else if (rkey != NULL) { 2554 free(rkey); 2555 *outkey = NULL; 2556 } 2557 2558 return (rv); 2559 } 2560 2561 2562 static KMF_RETURN 2563 kmf2pk11keytype(KMF_KEY_ALG keyalg, CK_KEY_TYPE *type) 2564 { 2565 switch (keyalg) { 2566 case KMF_RSA: 2567 *type = CKK_RSA; 2568 break; 2569 case KMF_DSA: 2570 *type = CKK_DSA; 2571 break; 2572 case KMF_AES: 2573 *type = CKK_AES; 2574 break; 2575 case KMF_RC4: 2576 *type = CKK_RC4; 2577 break; 2578 case KMF_DES: 2579 *type = CKK_DES; 2580 break; 2581 case KMF_DES3: 2582 *type = CKK_DES3; 2583 break; 2584 case KMF_GENERIC_SECRET: 2585 *type = CKK_GENERIC_SECRET; 2586 break; 2587 default: 2588 return (KMF_ERR_BAD_KEY_TYPE); 2589 } 2590 2591 return (KMF_OK); 2592 } 2593 2594 static int 2595 IDStringToData(char *idstr, KMF_DATA *iddata) 2596 { 2597 int len, i; 2598 char *iddup, *byte; 2599 uint_t lvalue; 2600 2601 if (idstr == NULL || !strlen(idstr)) 2602 return (-1); 2603 2604 iddup = (char *)strdup(idstr); 2605 if (iddup == NULL) 2606 return (KMF_ERR_MEMORY); 2607 2608 len = strlen(iddup) / 3 + 1; 2609 iddata->Data = malloc(len); 2610 if (iddata->Data == NULL) 2611 return (KMF_ERR_MEMORY); 2612 (void) memset(iddata->Data, 0, len); 2613 iddata->Length = len; 2614 2615 byte = strtok(iddup, ":"); 2616 if (byte == NULL) { 2617 free(iddup); 2618 free(iddata->Data); 2619 iddata->Data = NULL; 2620 iddata->Length = 0; 2621 return (-1); 2622 } 2623 2624 i = 0; 2625 do { 2626 (void) sscanf(byte, "%x", &lvalue); 2627 iddata->Data[i++] = (uchar_t)(lvalue & 0x000000FF); 2628 byte = strtok(NULL, ":"); 2629 } while (byte != NULL && i < len); 2630 2631 iddata->Length = i; 2632 free(iddup); 2633 return (0); 2634 } 2635 2636 KMF_RETURN 2637 KMFPK11_FindKey(KMF_HANDLE_T handle, 2638 int numattr, KMF_ATTRIBUTE *attrlist) 2639 { 2640 KMF_RETURN rv = KMF_OK; 2641 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2642 uint32_t want_keys, i; 2643 CK_RV ckrv; 2644 CK_ATTRIBUTE pTmpl[10]; 2645 CK_OBJECT_CLASS class; 2646 CK_BBOOL true = TRUE; 2647 CK_ULONG alg; 2648 boolean_t is_token = B_TRUE, is_private = B_FALSE; 2649 KMF_KEY_HANDLE *keys; 2650 uint32_t *numkeys; 2651 KMF_CREDENTIAL *cred = NULL; 2652 KMF_KEY_CLASS keyclass = KMF_KEYCLASS_NONE; 2653 char *findLabel, *idstr; 2654 KMF_KEY_ALG keytype = KMF_KEYALG_NONE; 2655 KMF_ENCODE_FORMAT format; 2656 2657 if (kmfh == NULL) 2658 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 2659 2660 if (kmfh->pk11handle == CK_INVALID_HANDLE) 2661 return (KMF_ERR_NO_TOKEN_SELECTED); 2662 2663 numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr); 2664 if (numkeys == NULL) 2665 return (KMF_ERR_BAD_PARAMETER); 2666 2667 if (*numkeys > 0) 2668 want_keys = *numkeys; 2669 else 2670 want_keys = MAXINT; /* count them all */ 2671 2672 /* keyclass is optional */ 2673 (void) kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr, 2674 (void *)&keyclass, NULL); 2675 2676 if (keyclass == KMF_ASYM_PUB) { 2677 class = CKO_PUBLIC_KEY; 2678 } else if (keyclass == KMF_ASYM_PRI) { 2679 class = CKO_PRIVATE_KEY; 2680 } else if (keyclass == KMF_SYMMETRIC) { 2681 class = CKO_SECRET_KEY; 2682 } 2683 2684 rv = kmf_get_attr(KMF_TOKEN_BOOL_ATTR, attrlist, numattr, 2685 (void *)&is_token, NULL); 2686 if (rv != KMF_OK) 2687 return (rv); 2688 2689 i = 0; 2690 if (is_token) { 2691 SETATTR(pTmpl, i, CKA_TOKEN, &true, sizeof (true)); 2692 i++; 2693 } 2694 2695 if (keyclass != KMF_KEYCLASS_NONE) { 2696 SETATTR(pTmpl, i, CKA_CLASS, &class, sizeof (class)); 2697 i++; 2698 } 2699 2700 findLabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr); 2701 2702 if (findLabel != NULL && strlen(findLabel)) { 2703 SETATTR(pTmpl, i, CKA_LABEL, findLabel, strlen(findLabel)); 2704 i++; 2705 } 2706 /* keytype is optional */ 2707 (void) kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, 2708 (void *)&keytype, NULL); 2709 2710 if (keytype != 0) { 2711 rv = kmf2pk11keytype(keytype, &alg); 2712 if (rv != KMF_OK) { 2713 return (KMF_ERR_BAD_KEY_TYPE); 2714 } 2715 SETATTR(pTmpl, i, CKA_KEY_TYPE, &alg, sizeof (alg)); 2716 i++; 2717 } 2718 2719 idstr = kmf_get_attr_ptr(KMF_IDSTR_ATTR, attrlist, numattr); 2720 2721 if (idstr != NULL) { 2722 KMF_DATA iddata = { NULL, 0 }; 2723 2724 /* 2725 * ID String parameter is assumed to be of form: 2726 * XX:XX:XX:XX:XX ... :XX 2727 * where XX is a hex number. 2728 * 2729 * We must convert this back to binary in order to 2730 * use it in a search. 2731 */ 2732 rv = IDStringToData(idstr, &iddata); 2733 if (rv == KMF_OK) { 2734 SETATTR(pTmpl, i, CKA_ID, iddata.Data, iddata.Length); 2735 i++; 2736 } else { 2737 return (rv); 2738 } 2739 } 2740 2741 /* is_private is optional */ 2742 (void) kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr, 2743 (void *)&is_private, NULL); 2744 2745 if (is_private) { 2746 SETATTR(pTmpl, i, CKA_PRIVATE, &true, sizeof (true)); 2747 i++; 2748 } 2749 2750 /* 2751 * Authenticate if the object is a token object, 2752 * a private or secred key, or if the user passed in credentials. 2753 */ 2754 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr); 2755 if (cred != NULL) { 2756 rv = pk11_authenticate(handle, cred); 2757 if (rv != KMF_OK) 2758 return (rv); 2759 } 2760 2761 keys = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 2762 /* it is okay to have "keys" contains NULL */ 2763 2764 ckrv = C_FindObjectsInit(kmfh->pk11handle, pTmpl, i); 2765 if (ckrv == CKR_OK) { 2766 CK_ULONG obj_count, n = 0; 2767 while (ckrv == CKR_OK && n < want_keys) { 2768 CK_OBJECT_HANDLE hObj; 2769 2770 ckrv = C_FindObjects(kmfh->pk11handle, &hObj, 2771 1, &obj_count); 2772 if (ckrv == CKR_OK && obj_count == 1) { 2773 if (keys != NULL) { 2774 CK_ULONG keytype; 2775 keys[n].kstype = KMF_KEYSTORE_PK11TOKEN; 2776 keys[n].israw = FALSE; 2777 keys[n].keyp = (void *)hObj; 2778 2779 ckrv = getObjectKeytype(handle, 2780 (CK_OBJECT_HANDLE)keys[n].keyp, 2781 &keytype); 2782 if (ckrv != CKR_OK) 2783 goto end; 2784 2785 ckrv = getObjectLabel(handle, 2786 (CK_OBJECT_HANDLE)keys[n].keyp, 2787 &(keys[n].keylabel)); 2788 if (ckrv != CKR_OK) 2789 goto end; 2790 2791 if (keyclass == KMF_KEYCLASS_NONE) { 2792 ckrv = getObjectKeyclass(handle, 2793 (CK_OBJECT_HANDLE) 2794 keys[n].keyp, 2795 &(keys[n].keyclass)); 2796 if (ckrv != CKR_OK) 2797 goto end; 2798 } else { 2799 keys[n].keyclass = keyclass; 2800 } 2801 if (keytype == CKK_RSA) { 2802 keys[n].keyalg = KMF_RSA; 2803 } else if (keytype == CKK_DSA) { 2804 keys[n].keyalg = KMF_DSA; 2805 } else if (keytype == CKK_AES) { 2806 keys[n].keyalg = KMF_AES; 2807 keys[n].keyclass = 2808 KMF_SYMMETRIC; 2809 } else if (keytype == CKK_RC4) { 2810 keys[n].keyalg = KMF_RC4; 2811 keys[n].keyclass = 2812 KMF_SYMMETRIC; 2813 } else if (keytype == CKK_DES) { 2814 keys[n].keyalg = KMF_DES; 2815 keys[n].keyclass = 2816 KMF_SYMMETRIC; 2817 } else if (keytype == CKK_DES3) { 2818 keys[n].keyalg = KMF_DES3; 2819 keys[n].keyclass = 2820 KMF_SYMMETRIC; 2821 } else if (keytype == 2822 CKK_GENERIC_SECRET) { 2823 keys[n].keyalg = 2824 KMF_GENERIC_SECRET; 2825 keys[n].keyclass = 2826 KMF_SYMMETRIC; 2827 } 2828 2829 } 2830 n++; 2831 } else { 2832 break; 2833 } 2834 } 2835 ckrv = C_FindObjectsFinal(kmfh->pk11handle); 2836 2837 /* "numkeys" indicates the number that were actually found */ 2838 *numkeys = n; 2839 } 2840 2841 if (ckrv == KMF_OK && keys != NULL && (*numkeys) > 0) { 2842 if ((rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, 2843 numattr, (void *)&format, NULL)) == KMF_OK) { 2844 if (format == KMF_FORMAT_RAWKEY || 2845 format == KMF_FORMAT_PEM) { 2846 /* Convert keys to "rawkey" format */ 2847 for (i = 0; i < (*numkeys); i++) { 2848 KMF_RAW_KEY_DATA *rkey = NULL; 2849 rv = keyObj2RawKey(handle, &keys[i], 2850 &rkey); 2851 if (rv == KMF_OK) { 2852 keys[i].keyp = rkey; 2853 keys[i].israw = TRUE; 2854 } else { 2855 break; 2856 } 2857 } 2858 } 2859 } else { 2860 rv = KMF_OK; /* format is optional */ 2861 } 2862 } 2863 2864 end: 2865 if (ckrv != CKR_OK) { 2866 SET_ERROR(kmfh, ckrv); 2867 /* Report authentication failures to the caller */ 2868 if (ckrv == CKR_USER_NOT_LOGGED_IN || 2869 ckrv == CKR_PIN_INCORRECT || 2870 ckrv == CKR_PIN_INVALID || 2871 ckrv == CKR_PIN_EXPIRED || 2872 ckrv == CKR_PIN_LOCKED || 2873 ckrv == CKR_SESSION_READ_ONLY) 2874 rv = KMF_ERR_AUTH_FAILED; 2875 else 2876 rv = KMF_ERR_INTERNAL; 2877 } else if ((*numkeys) == 0) { 2878 rv = KMF_ERR_KEY_NOT_FOUND; 2879 } 2880 2881 return (rv); 2882 } 2883 2884 static char * 2885 convertDate(char *fulldate) 2886 { 2887 struct tm tms; 2888 char newtime[9]; 2889 2890 (void) strptime(fulldate, "%b %d %T %Y %Z", &tms); 2891 2892 if (tms.tm_year < 69) 2893 tms.tm_year += 100; 2894 2895 (void) strftime(newtime, sizeof (newtime), "m%d", &tms); 2896 2897 newtime[8] = 0; 2898 2899 /* memory returned must be freed by the caller */ 2900 return ((char *)strdup(newtime)); 2901 } 2902 2903 static KMF_RETURN 2904 store_raw_key(KMF_HANDLE_T handle, 2905 KMF_ATTRIBUTE *attrlist, int numattr, 2906 KMF_RAW_KEY_DATA *rawkey) 2907 { 2908 KMF_RETURN rv = KMF_OK; 2909 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2910 int i; 2911 CK_RV ckrv = CKR_OK; 2912 CK_ATTRIBUTE templ[32]; 2913 CK_OBJECT_HANDLE keyobj; 2914 CK_KEY_TYPE keytype; 2915 CK_OBJECT_CLASS oClass = CKO_PRIVATE_KEY; 2916 CK_BBOOL cktrue = TRUE; 2917 CK_DATE startdate, enddate; 2918 KMF_DATA id = {NULL, 0}; 2919 KMF_DATA subject = {NULL, 0}; 2920 KMF_X509EXT_KEY_USAGE kuext; 2921 KMF_X509_CERTIFICATE *x509 = NULL; 2922 CK_BBOOL kufound = B_FALSE; 2923 KMF_DATA *cert = NULL; 2924 char *notbefore = NULL, *start = NULL; 2925 char *notafter = NULL, *end = NULL; 2926 char *keylabel = NULL; 2927 KMF_CREDENTIAL *cred = NULL; 2928 2929 if (kmfh == NULL) 2930 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 2931 2932 if (kmfh->pk11handle == CK_INVALID_HANDLE) 2933 return (KMF_ERR_NO_TOKEN_SELECTED); 2934 2935 if (rawkey->keytype == KMF_RSA) 2936 keytype = CKK_RSA; 2937 else if (rawkey->keytype == KMF_DSA) 2938 keytype = CKK_DSA; 2939 else 2940 return (KMF_ERR_BAD_PARAMETER); 2941 2942 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr); 2943 if (cred != NULL) { 2944 rv = pk11_authenticate(handle, cred); 2945 if (rv != KMF_OK) 2946 return (rv); 2947 } 2948 2949 keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr); 2950 /* 2951 * If the caller did not specify a label, see if the raw key 2952 * came with one (possible if it came from a PKCS#12 file). 2953 */ 2954 if (keylabel == NULL) { 2955 keylabel = rawkey->label; 2956 } 2957 2958 i = 0; 2959 SETATTR(templ, i, CKA_CLASS, &oClass, sizeof (CK_OBJECT_CLASS)); i++; 2960 SETATTR(templ, i, CKA_KEY_TYPE, &keytype, sizeof (keytype)); i++; 2961 SETATTR(templ, i, CKA_TOKEN, &cktrue, sizeof (cktrue)); i++; 2962 SETATTR(templ, i, CKA_PRIVATE, &cktrue, sizeof (cktrue)); i++; 2963 SETATTR(templ, i, CKA_DECRYPT, &cktrue, sizeof (cktrue)); i++; 2964 2965 cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); 2966 if (cert != NULL) { 2967 id.Data = NULL; 2968 id.Length = 0; 2969 rv = kmf_get_cert_id_data(cert, &id); 2970 if (rv != KMF_OK) { 2971 goto cleanup; 2972 } 2973 2974 rv = DerDecodeSignedCertificate((const KMF_DATA *)cert, &x509); 2975 if (rv != KMF_OK) { 2976 goto cleanup; 2977 } 2978 2979 rv = DerEncodeName(&x509->certificate.subject, &subject); 2980 if (rv != KMF_OK) { 2981 goto cleanup; 2982 } 2983 SETATTR(templ, i, CKA_SUBJECT, subject.Data, subject.Length); 2984 i++; 2985 2986 rv = kmf_get_cert_start_date_str(handle, cert, ¬before); 2987 if (rv != KMF_OK) { 2988 goto cleanup; 2989 } 2990 start = convertDate(notbefore); 2991 free(notbefore); 2992 2993 rv = kmf_get_cert_end_date_str(handle, cert, ¬after); 2994 if (rv != KMF_OK) { 2995 goto cleanup; 2996 } 2997 end = convertDate(notafter); 2998 free(notafter); 2999 if (id.Data != NULL && id.Data != NULL && id.Length > 0) { 3000 SETATTR(templ, i, CKA_ID, id.Data, id.Length); 3001 i++; 3002 } 3003 if (start != NULL) { 3004 /* 3005 * This makes some potentially dangerous assumptions: 3006 * 1. that the startdate in the parameter block is 3007 * properly formatted as YYYYMMDD 3008 * 2. That the CK_DATE structure is always the same. 3009 */ 3010 (void) memcpy(&startdate, start, sizeof (CK_DATE)); 3011 SETATTR(templ, i, CKA_START_DATE, &startdate, 3012 sizeof (startdate)); 3013 i++; 3014 } 3015 if (end != NULL) { 3016 (void) memcpy(&enddate, end, sizeof (CK_DATE)); 3017 SETATTR(templ, i, CKA_END_DATE, &enddate, 3018 sizeof (enddate)); 3019 i++; 3020 } 3021 3022 if ((rv = kmf_get_cert_ku(cert, &kuext)) != KMF_OK && 3023 rv != KMF_ERR_EXTENSION_NOT_FOUND) 3024 goto cleanup; 3025 3026 kufound = (rv == KMF_OK); 3027 rv = KMF_OK; /* reset if we got KMF_ERR_EXTENSION_NOT_FOUND */ 3028 } 3029 3030 /* 3031 * Only set the KeyUsage stuff if the KU extension was present. 3032 */ 3033 if (kufound) { 3034 CK_BBOOL condition; 3035 3036 condition = (kuext.KeyUsageBits & KMF_keyEncipherment) ? 3037 B_TRUE : B_FALSE; 3038 SETATTR(templ, i, CKA_UNWRAP, &condition, sizeof (CK_BBOOL)); 3039 i++; 3040 condition = (kuext.KeyUsageBits & KMF_dataEncipherment) ? 3041 B_TRUE : B_FALSE; 3042 SETATTR(templ, i, CKA_DECRYPT, &condition, sizeof (CK_BBOOL)); 3043 i++; 3044 condition = (kuext.KeyUsageBits & KMF_digitalSignature) ? 3045 B_TRUE : B_FALSE; 3046 SETATTR(templ, i, CKA_SIGN, &condition, sizeof (CK_BBOOL)); 3047 i++; 3048 condition = (kuext.KeyUsageBits & KMF_digitalSignature) ? 3049 B_TRUE : B_FALSE; 3050 SETATTR(templ, i, CKA_SIGN_RECOVER, &condition, 3051 sizeof (CK_BBOOL)); 3052 i++; 3053 3054 } 3055 3056 if (keylabel != NULL) { 3057 SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel)); 3058 i++; 3059 } 3060 if (id.Data == NULL && rawkey->id.Data != NULL) { 3061 SETATTR(templ, i, CKA_ID, rawkey->id.Data, 3062 rawkey->id.Length); 3063 i++; 3064 } 3065 if (keytype == CKK_RSA) { 3066 SETATTR(templ, i, CKA_MODULUS, 3067 rawkey->rawdata.rsa.mod.val, 3068 rawkey->rawdata.rsa.mod.len); 3069 i++; 3070 SETATTR(templ, i, CKA_PUBLIC_EXPONENT, 3071 rawkey->rawdata.rsa.pubexp.val, 3072 rawkey->rawdata.rsa.pubexp.len); 3073 i++; 3074 if (rawkey->rawdata.rsa.priexp.val != NULL) { 3075 SETATTR(templ, i, CKA_PRIVATE_EXPONENT, 3076 rawkey->rawdata.rsa.priexp.val, 3077 rawkey->rawdata.rsa.priexp.len); 3078 i++; 3079 } 3080 if (rawkey->rawdata.rsa.prime1.val != NULL) { 3081 SETATTR(templ, i, CKA_PRIME_1, 3082 rawkey->rawdata.rsa.prime1.val, 3083 rawkey->rawdata.rsa.prime1.len); 3084 i++; 3085 } 3086 if (rawkey->rawdata.rsa.prime2.val != NULL) { 3087 SETATTR(templ, i, CKA_PRIME_2, 3088 rawkey->rawdata.rsa.prime2.val, 3089 rawkey->rawdata.rsa.prime2.len); 3090 i++; 3091 } 3092 if (rawkey->rawdata.rsa.exp1.val != NULL) { 3093 SETATTR(templ, i, CKA_EXPONENT_1, 3094 rawkey->rawdata.rsa.exp1.val, 3095 rawkey->rawdata.rsa.exp1.len); 3096 i++; 3097 } 3098 if (rawkey->rawdata.rsa.exp2.val != NULL) { 3099 SETATTR(templ, i, CKA_EXPONENT_2, 3100 rawkey->rawdata.rsa.exp2.val, 3101 rawkey->rawdata.rsa.exp2.len); 3102 i++; 3103 } 3104 if (rawkey->rawdata.rsa.coef.val != NULL) { 3105 SETATTR(templ, i, CKA_COEFFICIENT, 3106 rawkey->rawdata.rsa.coef.val, 3107 rawkey->rawdata.rsa.coef.len); 3108 i++; 3109 } 3110 } else { 3111 SETATTR(templ, i, CKA_PRIME, 3112 rawkey->rawdata.dsa.prime.val, 3113 rawkey->rawdata.dsa.prime.len); 3114 i++; 3115 SETATTR(templ, i, CKA_SUBPRIME, 3116 rawkey->rawdata.dsa.subprime.val, 3117 rawkey->rawdata.dsa.subprime.len); 3118 i++; 3119 SETATTR(templ, i, CKA_BASE, 3120 rawkey->rawdata.dsa.base.val, 3121 rawkey->rawdata.dsa.base.len); 3122 i++; 3123 SETATTR(templ, i, CKA_VALUE, 3124 rawkey->rawdata.dsa.value.val, 3125 rawkey->rawdata.dsa.value.len); 3126 i++; 3127 } 3128 3129 ckrv = C_CreateObject(kmfh->pk11handle, templ, i, &keyobj); 3130 if (ckrv != CKR_OK) { 3131 SET_ERROR(kmfh, ckrv); 3132 3133 /* Report authentication failures to the caller */ 3134 if (ckrv == CKR_USER_NOT_LOGGED_IN || 3135 ckrv == CKR_PIN_INCORRECT || 3136 ckrv == CKR_PIN_INVALID || 3137 ckrv == CKR_PIN_EXPIRED || 3138 ckrv == CKR_PIN_LOCKED || 3139 ckrv == CKR_SESSION_READ_ONLY) 3140 rv = KMF_ERR_AUTH_FAILED; 3141 else 3142 rv = KMF_ERR_INTERNAL; 3143 } 3144 cleanup: 3145 if (start != NULL) 3146 free(start); 3147 if (end != NULL) 3148 free(end); 3149 kmf_free_data(&id); 3150 kmf_free_data(&subject); 3151 kmf_free_signed_cert(x509); 3152 free(x509); 3153 3154 return (rv); 3155 } 3156 3157 KMF_RETURN 3158 KMFPK11_CreateSymKey(KMF_HANDLE_T handle, 3159 int numattr, KMF_ATTRIBUTE *attrlist) 3160 { 3161 KMF_RETURN rv = KMF_OK; 3162 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3163 CK_RV ckrv; 3164 CK_SESSION_HANDLE hSession = kmfh->pk11handle; 3165 CK_OBJECT_HANDLE keyhandle; 3166 CK_MECHANISM keyGenMech; 3167 CK_OBJECT_CLASS class = CKO_SECRET_KEY; 3168 CK_ULONG secKeyType; 3169 CK_ULONG secKeyLen; /* for RC4 and AES */ 3170 CK_BBOOL true = TRUE; 3171 CK_BBOOL false = FALSE; 3172 CK_ATTRIBUTE templ[15]; 3173 CK_BYTE *keydata = NULL; 3174 int i = 0; 3175 KMF_KEY_HANDLE *symkey; 3176 KMF_KEY_ALG keytype; 3177 uint32_t keylen = 0; 3178 uint32_t attrkeylen = 0; 3179 uint32_t keylen_size = sizeof (uint32_t); 3180 char *keylabel = NULL; 3181 KMF_CREDENTIAL *cred = NULL; 3182 uint32_t is_sensitive = B_FALSE; 3183 uint32_t is_not_extractable = B_FALSE; 3184 3185 if (kmfh == NULL) 3186 return (KMF_ERR_UNINITIALIZED); 3187 3188 if (kmfh->pk11handle == CK_INVALID_HANDLE) 3189 return (KMF_ERR_NO_TOKEN_SELECTED); 3190 3191 symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 3192 if (symkey == NULL) 3193 return (KMF_ERR_BAD_PARAMETER); 3194 3195 rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, 3196 (void *)&keytype, NULL); 3197 if (rv != KMF_OK) 3198 return (KMF_ERR_BAD_PARAMETER); 3199 3200 keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr); 3201 if (keylabel == NULL) 3202 return (KMF_ERR_BAD_PARAMETER); 3203 3204 rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr, 3205 (void *)&is_sensitive, NULL); 3206 if (rv != KMF_OK) 3207 return (KMF_ERR_BAD_PARAMETER); 3208 3209 rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr, 3210 (void *)&is_not_extractable, NULL); 3211 if (rv != KMF_OK) 3212 return (KMF_ERR_BAD_PARAMETER); 3213 3214 /* 3215 * For AES, RC4, DES and 3DES, call C_GenerateKey() to create a key. 3216 * 3217 * For a generic secret key, because it may not be supported in 3218 * C_GenerateKey() for some PKCS11 providers, we will handle it 3219 * differently. 3220 */ 3221 if (keytype == KMF_GENERIC_SECRET) { 3222 rv = create_generic_secret_key(handle, numattr, 3223 attrlist, &keyhandle); 3224 if (rv != KMF_OK) 3225 goto out; 3226 else 3227 goto setup; 3228 } 3229 3230 rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr, 3231 NULL, &attrkeylen); 3232 if (rv == KMF_OK && attrkeylen > 0) { 3233 keydata = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist, 3234 numattr); 3235 } else { 3236 keydata = NULL; 3237 attrkeylen = 0; 3238 rv = KMF_OK; 3239 } 3240 if (keydata != NULL) { 3241 if (keytype == KMF_DES && attrkeylen != 8) { 3242 rv = KMF_ERR_BAD_KEY_SIZE; 3243 goto out; 3244 } 3245 if (keytype == KMF_DES3 && attrkeylen != 24) { 3246 rv = KMF_ERR_BAD_KEY_SIZE; 3247 goto out; 3248 } 3249 /* 3250 * This may override what the user gave on the 3251 * command line. 3252 */ 3253 keylen = attrkeylen * 8; /* bytes to bits */ 3254 } else { 3255 /* 3256 * If keydata was not given, key length must be 3257 * provided. 3258 */ 3259 rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, 3260 &keylen, &keylen_size); 3261 if (rv == KMF_ERR_ATTR_NOT_FOUND && 3262 (keytype == KMF_DES || keytype == KMF_DES3)) 3263 /* keylength is not required for DES and 3DES */ 3264 rv = KMF_OK; 3265 if (rv != KMF_OK) 3266 return (KMF_ERR_BAD_PARAMETER); 3267 } 3268 3269 if ((keylen % 8) != 0) { 3270 return (KMF_ERR_BAD_KEY_SIZE); 3271 } 3272 secKeyLen = keylen / 8; /* in bytes for RC4/AES */ 3273 3274 /* 3275 * Only set CKA_VALUE_LEN if the key data was not given and 3276 * we are creating an RC4 or AES key. 3277 */ 3278 if (keydata == NULL && 3279 (keytype == KMF_AES || keytype == KMF_RC4)) { 3280 SETATTR(templ, i, CKA_VALUE_LEN, &secKeyLen, 3281 sizeof (secKeyLen)); 3282 i++; 3283 } 3284 3285 /* Other keytypes */ 3286 keyGenMech.pParameter = NULL_PTR; 3287 keyGenMech.ulParameterLen = 0; 3288 switch (keytype) { 3289 case KMF_AES: 3290 keyGenMech.mechanism = CKM_AES_KEY_GEN; 3291 secKeyType = CKK_AES; 3292 break; 3293 case KMF_RC4: 3294 keyGenMech.mechanism = CKM_RC4_KEY_GEN; 3295 secKeyType = CKK_RC4; 3296 break; 3297 case KMF_DES: 3298 keyGenMech.mechanism = CKM_DES_KEY_GEN; 3299 secKeyType = CKK_DES; 3300 break; 3301 case KMF_DES3: 3302 keyGenMech.mechanism = CKM_DES3_KEY_GEN; 3303 secKeyType = CKK_DES3; 3304 break; 3305 default: 3306 return (KMF_ERR_BAD_KEY_TYPE); 3307 } 3308 if (keydata != NULL) { 3309 SETATTR(templ, i, CKA_VALUE, keydata, secKeyLen); 3310 i++; 3311 } 3312 SETATTR(templ, i, CKA_CLASS, &class, sizeof (class)); 3313 i++; 3314 SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType)); 3315 i++; 3316 3317 if (keylabel != NULL) { 3318 SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel)); 3319 i++; 3320 } 3321 3322 if (is_sensitive == B_TRUE) { 3323 SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true)); 3324 } else { 3325 SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false)); 3326 } 3327 i++; 3328 3329 if (is_not_extractable == B_TRUE) { 3330 SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false)); 3331 } else { 3332 SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true)); 3333 } 3334 i++; 3335 3336 SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true)); 3337 i++; 3338 SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true)); 3339 i++; 3340 SETATTR(templ, i, CKA_ENCRYPT, &true, sizeof (true)); 3341 i++; 3342 SETATTR(templ, i, CKA_DECRYPT, &true, sizeof (true)); 3343 i++; 3344 SETATTR(templ, i, CKA_SIGN, &true, sizeof (true)); 3345 i++; 3346 SETATTR(templ, i, CKA_VERIFY, &true, sizeof (true)); 3347 i++; 3348 3349 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr); 3350 if (cred == NULL) 3351 return (KMF_ERR_BAD_PARAMETER); 3352 3353 rv = pk11_authenticate(handle, cred); 3354 if (rv != KMF_OK) { 3355 return (rv); 3356 } 3357 3358 /* If the key data was given, use C_CreateObject */ 3359 if (keydata != NULL) { 3360 ckrv = C_CreateObject(hSession, templ, i, &keyhandle); 3361 } else { 3362 ckrv = C_GenerateKey(hSession, &keyGenMech, templ, i, 3363 &keyhandle); 3364 } 3365 if (ckrv != CKR_OK) { 3366 if (ckrv == CKR_USER_NOT_LOGGED_IN || 3367 ckrv == CKR_PIN_INCORRECT || 3368 ckrv == CKR_PIN_INVALID || 3369 ckrv == CKR_PIN_EXPIRED || 3370 ckrv == CKR_PIN_LOCKED || 3371 ckrv == CKR_SESSION_READ_ONLY) 3372 rv = KMF_ERR_AUTH_FAILED; 3373 else 3374 rv = KMF_ERR_KEYGEN_FAILED; 3375 SET_ERROR(kmfh, ckrv); 3376 goto out; 3377 } 3378 3379 setup: 3380 symkey->kstype = KMF_KEYSTORE_PK11TOKEN; 3381 symkey->keyalg = keytype; 3382 symkey->keyclass = KMF_SYMMETRIC; 3383 symkey->israw = FALSE; 3384 symkey->keyp = (void *)keyhandle; 3385 3386 out: 3387 return (rv); 3388 } 3389 3390 KMF_RETURN 3391 KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, 3392 KMF_RAW_SYM_KEY *rkey) 3393 { 3394 KMF_RETURN rv = KMF_OK; 3395 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3396 3397 if (kmfh == NULL) 3398 return (KMF_ERR_UNINITIALIZED); 3399 3400 if (kmfh->pk11handle == CK_INVALID_HANDLE) 3401 return (KMF_ERR_NO_TOKEN_SELECTED); 3402 3403 if (symkey == NULL || rkey == NULL) 3404 return (KMF_ERR_BAD_PARAMETER); 3405 else if (symkey->keyclass != KMF_SYMMETRIC) 3406 return (KMF_ERR_BAD_KEY_CLASS); 3407 3408 /* 3409 * If the key is already in "raw" format, copy the data 3410 * to the new record if possible. 3411 */ 3412 if (symkey->israw) { 3413 KMF_RAW_KEY_DATA *rawkey = (KMF_RAW_KEY_DATA *)symkey->keyp; 3414 3415 if (rawkey == NULL) 3416 return (KMF_ERR_BAD_KEYHANDLE); 3417 if (rawkey->sensitive) 3418 return (KMF_ERR_SENSITIVE_KEY); 3419 if (rawkey->not_extractable) 3420 return (KMF_ERR_UNEXTRACTABLE_KEY); 3421 3422 if (rawkey->rawdata.sym.keydata.val == NULL || 3423 rawkey->rawdata.sym.keydata.len == 0) 3424 return (KMF_ERR_GETKEYVALUE_FAILED); 3425 3426 rkey->keydata.len = rawkey->rawdata.sym.keydata.len; 3427 if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL) 3428 return (KMF_ERR_MEMORY); 3429 (void) memcpy(rkey->keydata.val, 3430 rawkey->rawdata.sym.keydata.val, rkey->keydata.len); 3431 } else { 3432 rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)symkey->keyp, rkey); 3433 } 3434 3435 return (rv); 3436 } 3437 3438 KMF_RETURN 3439 KMFPK11_SetTokenPin(KMF_HANDLE_T handle, 3440 int numattr, KMF_ATTRIBUTE *attrlist) 3441 { 3442 KMF_RETURN ret = KMF_OK; 3443 CK_RV rv = CKR_OK; 3444 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3445 CK_SESSION_HANDLE session = NULL; 3446 KMF_CREDENTIAL *oldcred; 3447 KMF_CREDENTIAL *newcred; 3448 CK_SLOT_ID slotid; 3449 CK_USER_TYPE user = CKU_USER; 3450 3451 if (handle == NULL || attrlist == NULL || numattr == 0) 3452 return (KMF_ERR_BAD_PARAMETER); 3453 3454 oldcred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr); 3455 if (oldcred == NULL) 3456 return (KMF_ERR_BAD_PARAMETER); 3457 3458 newcred = kmf_get_attr_ptr(KMF_NEWPIN_ATTR, attrlist, numattr); 3459 if (newcred == NULL) 3460 return (KMF_ERR_BAD_PARAMETER); 3461 3462 rv = kmf_get_attr(KMF_SLOT_ID_ATTR, attrlist, numattr, 3463 (void *)&slotid, NULL); 3464 if (rv != KMF_OK) { 3465 char *tokenlabel = NULL; 3466 /* 3467 * If a slot wasn't given, the user must pass 3468 * a token label so we can find the slot here. 3469 */ 3470 tokenlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, 3471 numattr); 3472 if (tokenlabel == NULL) 3473 return (KMF_ERR_BAD_PARAMETER); 3474 3475 rv = kmf_pk11_token_lookup(handle, tokenlabel, &slotid); 3476 if (rv != KMF_OK) 3477 return (rv); 3478 } 3479 rv = kmf_get_attr(KMF_PK11_USER_TYPE_ATTR, attrlist, numattr, 3480 (void *)&user, NULL); 3481 if (rv != CKR_OK) 3482 user = CKU_USER; 3483 3484 rv = C_OpenSession(slotid, CKF_SERIAL_SESSION | CKF_RW_SESSION, 3485 NULL, NULL, &session); 3486 if (rv != CKR_OK) { 3487 SET_ERROR(kmfh, rv); 3488 ret = KMF_ERR_UNINITIALIZED; 3489 goto end; 3490 } 3491 3492 rv = C_Login(session, user, (CK_BYTE *)oldcred->cred, 3493 oldcred->credlen); 3494 if (rv != CKR_OK) { 3495 SET_ERROR(kmfh, rv); 3496 if (rv == CKR_PIN_INCORRECT || 3497 rv == CKR_PIN_INVALID || 3498 rv == CKR_PIN_EXPIRED || 3499 rv == CKR_PIN_LOCKED) 3500 ret = KMF_ERR_AUTH_FAILED; 3501 else 3502 ret = KMF_ERR_INTERNAL; 3503 3504 goto end; 3505 } 3506 3507 rv = C_SetPIN(session, 3508 (CK_BYTE *)oldcred->cred, oldcred->credlen, 3509 (CK_BYTE *)newcred->cred, newcred->credlen); 3510 3511 if (rv != CKR_OK) { 3512 SET_ERROR(kmfh, rv); 3513 if (rv == CKR_PIN_INCORRECT || 3514 rv == CKR_PIN_INVALID || 3515 rv == CKR_PIN_EXPIRED || 3516 rv == CKR_PIN_LOCKED) 3517 ret = KMF_ERR_AUTH_FAILED; 3518 else 3519 ret = KMF_ERR_INTERNAL; 3520 } 3521 end: 3522 if (session != NULL) 3523 (void) C_CloseSession(session); 3524 return (ret); 3525 } 3526 3527 static KMF_RETURN 3528 create_pk11_session(CK_SESSION_HANDLE *sessionp, CK_MECHANISM_TYPE wanted_mech, 3529 CK_FLAGS wanted_flags) 3530 { 3531 CK_RV rv; 3532 KMF_RETURN kmf_rv = KMF_OK; 3533 CK_SLOT_ID_PTR pSlotList; 3534 CK_ULONG pulCount; 3535 CK_MECHANISM_INFO info; 3536 int i; 3537 3538 rv = C_Initialize(NULL); 3539 if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) { 3540 kmf_rv = KMF_ERR_UNINITIALIZED; 3541 goto out; 3542 } 3543 3544 rv = C_GetSlotList(0, NULL, &pulCount); 3545 if (rv != CKR_OK) { 3546 kmf_rv = KMF_ERR_UNINITIALIZED; 3547 goto out; 3548 } 3549 3550 pSlotList = (CK_SLOT_ID_PTR) malloc(pulCount * sizeof (CK_SLOT_ID)); 3551 if (pSlotList == NULL) { 3552 kmf_rv = KMF_ERR_MEMORY; 3553 goto out; 3554 } 3555 3556 rv = C_GetSlotList(0, pSlotList, &pulCount); 3557 if (rv != CKR_OK) { 3558 kmf_rv = KMF_ERR_UNINITIALIZED; 3559 goto out; 3560 } 3561 3562 for (i = 0; i < pulCount; i++) { 3563 rv = C_GetMechanismInfo(pSlotList[i], wanted_mech, &info); 3564 if (rv == CKR_OK && (info.flags & wanted_flags)) 3565 break; 3566 } 3567 if (i < pulCount) { 3568 rv = C_OpenSession(pSlotList[i], CKF_SERIAL_SESSION, 3569 NULL, NULL, sessionp); 3570 3571 if (rv != CKR_OK) { 3572 kmf_rv = KMF_ERR_UNINITIALIZED; 3573 } 3574 } else { 3575 kmf_rv = KMF_ERR_UNINITIALIZED; 3576 } 3577 3578 out: 3579 if (pSlotList != NULL) 3580 free(pSlotList); 3581 return (kmf_rv); 3582 3583 } 3584 static KMF_RETURN 3585 verify_data(KMF_HANDLE_T handle, 3586 KMF_ALGORITHM_INDEX AlgorithmId, 3587 KMF_X509_SPKI *keyp, 3588 KMF_DATA *data, 3589 KMF_DATA *signed_data) 3590 { 3591 KMF_RETURN ret; 3592 PKCS_ALGORITHM_MAP *pAlgMap = NULL; 3593 CK_RV ckRv; 3594 CK_MECHANISM ckMechanism; 3595 CK_OBJECT_HANDLE ckKeyHandle; 3596 KMF_BOOL bTempKey; 3597 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3598 CK_SESSION_HANDLE ckSession = NULL; 3599 3600 if (AlgorithmId == KMF_ALGID_NONE) 3601 return (KMF_ERR_BAD_ALGORITHM); 3602 3603 pAlgMap = pkcs_get_alg_map(KMF_ALGCLASS_SIGNATURE, 3604 AlgorithmId, PKCS_GetDefaultSignatureMode(AlgorithmId)); 3605 3606 if (!pAlgMap) 3607 return (KMF_ERR_BAD_ALGORITHM); 3608 3609 ret = create_pk11_session(&ckSession, pAlgMap->pkcs_mechanism, 3610 CKF_VERIFY); 3611 if (ret != KMF_OK) 3612 return (ret); 3613 3614 /* Fetch the verifying key */ 3615 ret = PKCS_AcquirePublicKeyHandle(ckSession, keyp, 3616 pAlgMap->key_type, &ckKeyHandle, &bTempKey); 3617 3618 if (ret != KMF_OK) { 3619 return (ret); 3620 } 3621 3622 ckMechanism.mechanism = pAlgMap->pkcs_mechanism; 3623 ckMechanism.pParameter = NULL; 3624 ckMechanism.ulParameterLen = 0; 3625 3626 ckRv = C_VerifyInit(ckSession, &ckMechanism, ckKeyHandle); 3627 if (ckRv != CKR_OK) { 3628 if (bTempKey) 3629 (void) C_DestroyObject(ckSession, ckKeyHandle); 3630 SET_ERROR(kmfh, ckRv); 3631 ret = KMF_ERR_INTERNAL; 3632 goto cleanup; 3633 } 3634 3635 ckRv = C_Verify(ckSession, (CK_BYTE *)data->Data, 3636 (CK_ULONG)data->Length, (CK_BYTE *)signed_data->Data, 3637 (CK_ULONG)signed_data->Length); 3638 3639 if (ckRv != CKR_OK) { 3640 SET_ERROR(kmfh, ckRv); 3641 ret = KMF_ERR_INTERNAL; 3642 } 3643 3644 cleanup: 3645 if (bTempKey) 3646 (void) C_DestroyObject(ckSession, ckKeyHandle); 3647 3648 (void) C_CloseSession(ckSession); 3649 3650 return (ret); 3651 } 3652 3653 KMF_RETURN 3654 KMFPK11_VerifyDataWithCert(KMF_HANDLE_T handle, 3655 KMF_ALGORITHM_INDEX algid, KMF_DATA *indata, 3656 KMF_DATA *insig, KMF_DATA *SignerCertData) 3657 { 3658 KMF_RETURN ret = KMF_OK; 3659 KMF_X509_CERTIFICATE *SignerCert = NULL; 3660 KMF_X509_SPKI *pubkey; 3661 3662 if (handle == NULL || indata == NULL || 3663 indata->Data == NULL || indata->Length == 0 || 3664 insig == NULL|| insig->Data == NULL || insig->Length == 0 || 3665 SignerCertData == NULL || SignerCertData->Data == NULL || 3666 SignerCertData->Length == 0) 3667 return (KMF_ERR_BAD_PARAMETER); 3668 3669 /* Decode the signer cert so we can get the SPKI data */ 3670 ret = DerDecodeSignedCertificate(SignerCertData, &SignerCert); 3671 if (ret != KMF_OK) 3672 goto cleanup; 3673 3674 /* Get the public key info from the signer certificate */ 3675 pubkey = &SignerCert->certificate.subjectPublicKeyInfo; 3676 3677 /* If no algorithm specified, use the certs signature algorithm */ 3678 if (algid == KMF_ALGID_NONE) { 3679 algid = x509_algoid_to_algid(CERT_ALG_OID(SignerCert)); 3680 } 3681 3682 if (algid == KMF_ALGID_NONE) { 3683 ret = KMF_ERR_BAD_ALGORITHM; 3684 } else { 3685 ret = verify_data(handle, algid, pubkey, indata, insig); 3686 } 3687 3688 cleanup: 3689 if (SignerCert) { 3690 kmf_free_signed_cert(SignerCert); 3691 free(SignerCert); 3692 } 3693 3694 return (ret); 3695 } 3696 3697 static KMF_RETURN 3698 create_generic_secret_key(KMF_HANDLE_T handle, 3699 int numattr, KMF_ATTRIBUTE *attrlist, CK_OBJECT_HANDLE *key) 3700 { 3701 KMF_RETURN rv = KMF_OK; 3702 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3703 CK_RV ckrv; 3704 CK_SESSION_HANDLE hSession = kmfh->pk11handle; 3705 CK_OBJECT_CLASS class = CKO_SECRET_KEY; 3706 CK_ULONG secKeyType = CKK_GENERIC_SECRET; 3707 CK_ULONG secKeyLen; 3708 CK_BBOOL true = TRUE; 3709 CK_BBOOL false = FALSE; 3710 CK_ATTRIBUTE templ[15]; 3711 int i; 3712 int random_fd = -1; 3713 int nread; 3714 int freebuf = 0; 3715 char *buf = NULL; 3716 uint32_t keylen = 0, attrkeylen = 0; 3717 char *keylabel = NULL; 3718 KMF_CREDENTIAL *cred; 3719 uint32_t is_sensitive, is_not_extractable; 3720 3721 keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr); 3722 if (keylabel == NULL) 3723 return (KMF_ERR_BAD_PARAMETER); 3724 3725 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr); 3726 if (cred == NULL) 3727 return (KMF_ERR_BAD_PARAMETER); 3728 3729 rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr, 3730 (void *)&is_sensitive, NULL); 3731 if (rv != KMF_OK) 3732 return (KMF_ERR_BAD_PARAMETER); 3733 3734 rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr, 3735 (void *)&is_not_extractable, NULL); 3736 if (rv != KMF_OK) 3737 return (KMF_ERR_BAD_PARAMETER); 3738 3739 rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr, 3740 NULL, &attrkeylen); 3741 if (rv == KMF_OK && attrkeylen > 0) { 3742 buf = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist, 3743 numattr); 3744 secKeyLen = attrkeylen; 3745 } else { 3746 buf = NULL; 3747 rv = KMF_OK; 3748 } 3749 if (buf == NULL) { 3750 /* 3751 * If the key data was not given, key length must 3752 * be provided. 3753 */ 3754 rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, 3755 &keylen, NULL); 3756 if (rv != KMF_OK) 3757 return (KMF_ERR_BAD_PARAMETER); 3758 3759 /* 3760 * Check the key size. 3761 */ 3762 if ((keylen % 8) != 0) { 3763 return (KMF_ERR_BAD_KEY_SIZE); 3764 } else { 3765 secKeyLen = keylen/8; /* in bytes */ 3766 } 3767 3768 /* 3769 * Generate a random number with the key size first. 3770 */ 3771 buf = malloc(secKeyLen); 3772 if (buf == NULL) 3773 return (KMF_ERR_MEMORY); 3774 3775 freebuf = 1; 3776 while ((random_fd = open(DEV_RANDOM, O_RDONLY)) < 0) { 3777 if (errno != EINTR) 3778 break; 3779 } 3780 3781 if (random_fd < 0) { 3782 rv = KMF_ERR_KEYGEN_FAILED; 3783 goto out; 3784 } 3785 3786 nread = read(random_fd, buf, secKeyLen); 3787 if (nread <= 0 || nread != secKeyLen) { 3788 rv = KMF_ERR_KEYGEN_FAILED; 3789 goto out; 3790 } 3791 } 3792 3793 /* 3794 * Authenticate into the token and call C_CreateObject to generate 3795 * a generic secret token key. 3796 */ 3797 rv = pk11_authenticate(handle, cred); 3798 if (rv != KMF_OK) { 3799 goto out; 3800 } 3801 3802 i = 0; 3803 SETATTR(templ, i, CKA_CLASS, &class, sizeof (class)); 3804 i++; 3805 SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType)); 3806 i++; 3807 SETATTR(templ, i, CKA_VALUE, buf, secKeyLen); 3808 i++; 3809 3810 if (keylabel != NULL) { 3811 SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel)); 3812 i++; 3813 } 3814 3815 if (is_sensitive == B_TRUE) { 3816 SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true)); 3817 } else { 3818 SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false)); 3819 } 3820 i++; 3821 3822 if (is_not_extractable == B_TRUE) { 3823 SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false)); 3824 } else { 3825 SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true)); 3826 } 3827 i++; 3828 3829 SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true)); 3830 i++; 3831 SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true)); 3832 i++; 3833 SETATTR(templ, i, CKA_SIGN, &true, sizeof (true)); 3834 i++; 3835 3836 ckrv = C_CreateObject(hSession, templ, i, key); 3837 if (ckrv != CKR_OK) { 3838 if (ckrv == CKR_USER_NOT_LOGGED_IN || 3839 ckrv == CKR_PIN_INCORRECT || 3840 ckrv == CKR_PIN_INVALID || 3841 ckrv == CKR_PIN_EXPIRED || 3842 ckrv == CKR_PIN_LOCKED || 3843 ckrv == CKR_SESSION_READ_ONLY) 3844 rv = KMF_ERR_AUTH_FAILED; 3845 else 3846 rv = KMF_ERR_KEYGEN_FAILED; 3847 SET_ERROR(kmfh, ckrv); 3848 } 3849 3850 out: 3851 if (buf != NULL && freebuf) 3852 free(buf); 3853 3854 if (random_fd != -1) 3855 (void) close(random_fd); 3856 3857 return (rv); 3858 } 3859 3860 KMF_RETURN 3861 KMFPK11_StoreKey(KMF_HANDLE_T handle, 3862 int numattr, 3863 KMF_ATTRIBUTE *attlist) 3864 { 3865 KMF_RETURN rv = KMF_OK; 3866 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3867 KMF_CREDENTIAL cred = {NULL, 0}; 3868 KMF_KEY_HANDLE *key; 3869 KMF_RAW_KEY_DATA *rawkey = NULL; 3870 CK_BBOOL btrue = TRUE; 3871 CK_ATTRIBUTE tokenattr[1]; 3872 CK_OBJECT_HANDLE newobj; 3873 CK_RV ckrv; 3874 3875 if (kmfh == NULL) 3876 return (KMF_ERR_UNINITIALIZED); 3877 3878 if (kmfh->pk11handle == CK_INVALID_HANDLE) 3879 return (KMF_ERR_NO_TOKEN_SELECTED); 3880 3881 rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attlist, numattr, 3882 (void *)&cred, NULL); 3883 if (rv != KMF_OK) 3884 return (KMF_ERR_BAD_PARAMETER); 3885 3886 rv = pk11_authenticate(handle, &cred); 3887 if (rv != KMF_OK) 3888 return (rv); 3889 3890 key = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr); 3891 if (key == NULL) { 3892 key = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist, 3893 numattr); 3894 if (key == NULL) 3895 rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attlist, 3896 numattr); 3897 } 3898 if (key == NULL && rawkey == NULL) 3899 return (KMF_ERR_ATTR_NOT_FOUND); 3900 3901 if (rawkey != NULL) { 3902 rv = store_raw_key(handle, attlist, numattr, rawkey); 3903 } else if (key && key->kstype == KMF_KEYSTORE_PK11TOKEN) { 3904 3905 SETATTR(tokenattr, 0, CKA_TOKEN, &btrue, sizeof (btrue)); 3906 /* Copy the key object to the token */ 3907 ckrv = C_CopyObject(kmfh->pk11handle, 3908 (CK_OBJECT_HANDLE)key->keyp, tokenattr, 1, &newobj); 3909 if (ckrv != CKR_OK) { 3910 SET_ERROR(kmfh, ckrv); 3911 return (KMF_ERR_INTERNAL); 3912 } 3913 3914 /* Replace the object handle with the new token-based one */ 3915 ckrv = C_DestroyObject(kmfh->pk11handle, 3916 (CK_OBJECT_HANDLE)key->keyp); 3917 if (ckrv != CKR_OK) { 3918 SET_ERROR(kmfh, ckrv); 3919 return (KMF_ERR_INTERNAL); 3920 } 3921 key->keyp = (void *)newobj; 3922 } else { 3923 rv = KMF_ERR_BAD_PARAMETER; 3924 } 3925 3926 return (rv); 3927 } 3928 3929 3930 KMF_RETURN 3931 KMFPK11_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 3932 { 3933 KMF_RETURN rv = KMF_OK; 3934 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3935 KMF_CREDENTIAL *cred = NULL; 3936 KMF_CREDENTIAL *p12cred = NULL; 3937 char *filename = NULL; 3938 KMF_X509_DER_CERT *certlist = NULL; 3939 KMF_KEY_HANDLE *keylist = NULL; 3940 uint32_t numcerts; 3941 uint32_t numkeys; 3942 char *certlabel = NULL; 3943 char *issuer = NULL; 3944 char *subject = NULL; 3945 KMF_BIGINT *serial = NULL; 3946 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 3947 KMF_ATTRIBUTE fc_attrlist[16]; 3948 int i; 3949 3950 if (kmfh == NULL) 3951 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 3952 3953 if (kmfh->pk11handle == CK_INVALID_HANDLE) 3954 return (KMF_ERR_NO_TOKEN_SELECTED); 3955 3956 /* First get the required attributes */ 3957 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr); 3958 if (cred == NULL) 3959 return (KMF_ERR_BAD_PARAMETER); 3960 3961 p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr); 3962 if (p12cred == NULL) 3963 return (KMF_ERR_BAD_PARAMETER); 3964 3965 filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist, 3966 numattr); 3967 if (filename == NULL) 3968 return (KMF_ERR_BAD_PARAMETER); 3969 3970 /* Find all the certificates that match the searching criteria */ 3971 i = 0; 3972 kmf_set_attr_at_index(fc_attrlist, i, 3973 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 3974 i++; 3975 3976 kmf_set_attr_at_index(fc_attrlist, i, 3977 KMF_COUNT_ATTR, &numcerts, sizeof (uint32_t)); 3978 i++; 3979 3980 certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); 3981 if (certlabel != NULL) { 3982 kmf_set_attr_at_index(fc_attrlist, i, 3983 KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel)); 3984 i++; 3985 } 3986 3987 issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); 3988 if (issuer != NULL) { 3989 kmf_set_attr_at_index(fc_attrlist, i, 3990 KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer)); 3991 i++; 3992 } 3993 3994 subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); 3995 if (subject != NULL) { 3996 kmf_set_attr_at_index(fc_attrlist, i, 3997 KMF_SUBJECT_NAME_ATTR, subject, strlen(subject)); 3998 i++; 3999 } 4000 4001 serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); 4002 if (serial != NULL) { 4003 kmf_set_attr_at_index(fc_attrlist, i, 4004 KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT)); 4005 i++; 4006 } 4007 4008 rv = KMFPK11_FindCert(handle, i, fc_attrlist); 4009 4010 if (rv == KMF_OK && numcerts > 0) { 4011 certlist = (KMF_X509_DER_CERT *)malloc(numcerts * 4012 sizeof (KMF_X509_DER_CERT)); 4013 if (certlist == NULL) 4014 return (KMF_ERR_MEMORY); 4015 4016 (void) memset(certlist, 0, numcerts * 4017 sizeof (KMF_X509_DER_CERT)); 4018 4019 kmf_set_attr_at_index(fc_attrlist, i, KMF_X509_DER_CERT_ATTR, 4020 certlist, sizeof (KMF_X509_DER_CERT)); 4021 i++; 4022 4023 rv = kmf_find_cert(handle, i, fc_attrlist); 4024 if (rv != KMF_OK) { 4025 free(certlist); 4026 return (rv); 4027 } 4028 } else { 4029 return (rv); 4030 } 4031 4032 /* For each certificate, find the matching private key */ 4033 numkeys = 0; 4034 for (i = 0; i < numcerts; i++) { 4035 KMF_ATTRIBUTE fk_attrlist[16]; 4036 int j = 0; 4037 KMF_KEY_HANDLE newkey; 4038 KMF_ENCODE_FORMAT format = KMF_FORMAT_RAWKEY; 4039 4040 kmf_set_attr_at_index(fk_attrlist, j, 4041 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 4042 j++; 4043 4044 kmf_set_attr_at_index(fk_attrlist, j, 4045 KMF_ENCODE_FORMAT_ATTR, &format, sizeof (format)); 4046 j++; 4047 4048 kmf_set_attr_at_index(fk_attrlist, j, 4049 KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL)); 4050 j++; 4051 4052 kmf_set_attr_at_index(fk_attrlist, j, 4053 KMF_CERT_DATA_ATTR, &certlist[i].certificate, 4054 sizeof (KMF_DATA)); 4055 j++; 4056 4057 kmf_set_attr_at_index(fk_attrlist, j, 4058 KMF_KEY_HANDLE_ATTR, &newkey, sizeof (KMF_KEY_HANDLE)); 4059 j++; 4060 4061 rv = KMFPK11_FindPrikeyByCert(handle, j, fk_attrlist); 4062 if (rv == KMF_OK) { 4063 numkeys++; 4064 keylist = realloc(keylist, 4065 numkeys * sizeof (KMF_KEY_HANDLE)); 4066 if (keylist == NULL) { 4067 rv = KMF_ERR_MEMORY; 4068 goto out; 4069 } 4070 keylist[numkeys - 1] = newkey; 4071 } else if (rv == KMF_ERR_KEY_NOT_FOUND) { 4072 /* it is OK if a key is not found */ 4073 rv = KMF_OK; 4074 } 4075 } 4076 4077 if (rv != KMF_OK) 4078 goto out; 4079 4080 rv = kmf_build_pk12(handle, numcerts, certlist, numkeys, keylist, 4081 p12cred, filename); 4082 4083 out: 4084 if (certlist != NULL) { 4085 for (i = 0; i < numcerts; i++) 4086 kmf_free_kmf_cert(handle, &certlist[i]); 4087 free(certlist); 4088 } 4089 if (keylist != NULL) { 4090 for (i = 0; i < numkeys; i++) 4091 kmf_free_kmf_key(handle, &keylist[i]); 4092 free(keylist); 4093 } 4094 4095 return (rv); 4096 } 4097