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