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 == 0) 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 = 0; 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 3252 cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); 3253 if (cert != NULL) { 3254 id.Data = NULL; 3255 id.Length = 0; 3256 rv = kmf_get_cert_id_data(cert, &id); 3257 if (rv != KMF_OK) { 3258 goto cleanup; 3259 } 3260 3261 rv = DerDecodeSignedCertificate((const KMF_DATA *)cert, &x509); 3262 if (rv != KMF_OK) { 3263 goto cleanup; 3264 } 3265 3266 rv = DerEncodeName(&x509->certificate.subject, &subject); 3267 if (rv != KMF_OK) { 3268 goto cleanup; 3269 } 3270 SETATTR(templ, i, CKA_SUBJECT, subject.Data, subject.Length); 3271 i++; 3272 3273 rv = kmf_get_cert_start_date_str(handle, cert, ¬before); 3274 if (rv != KMF_OK) { 3275 goto cleanup; 3276 } 3277 start = convertDate(notbefore); 3278 free(notbefore); 3279 3280 rv = kmf_get_cert_end_date_str(handle, cert, ¬after); 3281 if (rv != KMF_OK) { 3282 goto cleanup; 3283 } 3284 end = convertDate(notafter); 3285 free(notafter); 3286 if (id.Data != NULL && id.Data != NULL && id.Length > 0) { 3287 SETATTR(templ, i, CKA_ID, id.Data, id.Length); 3288 i++; 3289 } 3290 if (start != NULL) { 3291 /* 3292 * This makes some potentially dangerous assumptions: 3293 * 1. that the startdate in the parameter block is 3294 * properly formatted as YYYYMMDD 3295 * 2. That the CK_DATE structure is always the same. 3296 */ 3297 (void) memcpy(&startdate, start, sizeof (CK_DATE)); 3298 SETATTR(templ, i, CKA_START_DATE, &startdate, 3299 sizeof (startdate)); 3300 i++; 3301 } 3302 if (end != NULL) { 3303 (void) memcpy(&enddate, end, sizeof (CK_DATE)); 3304 SETATTR(templ, i, CKA_END_DATE, &enddate, 3305 sizeof (enddate)); 3306 i++; 3307 } 3308 3309 if ((rv = kmf_get_cert_ku(cert, &kuext)) != KMF_OK && 3310 rv != KMF_ERR_EXTENSION_NOT_FOUND) 3311 goto cleanup; 3312 3313 kufound = (rv == KMF_OK); 3314 rv = KMF_OK; /* reset if we got KMF_ERR_EXTENSION_NOT_FOUND */ 3315 } 3316 3317 /* 3318 * Only set the KeyUsage stuff if the KU extension was present. 3319 */ 3320 if (kufound) { 3321 CK_BBOOL condition; 3322 3323 condition = (kuext.KeyUsageBits & KMF_keyEncipherment) ? 3324 B_TRUE : B_FALSE; 3325 SETATTR(templ, i, CKA_UNWRAP, &condition, sizeof (CK_BBOOL)); 3326 i++; 3327 condition = (kuext.KeyUsageBits & KMF_dataEncipherment) ? 3328 B_TRUE : B_FALSE; 3329 SETATTR(templ, i, CKA_DECRYPT, &condition, sizeof (CK_BBOOL)); 3330 i++; 3331 condition = (kuext.KeyUsageBits & KMF_digitalSignature) ? 3332 B_TRUE : B_FALSE; 3333 SETATTR(templ, i, CKA_SIGN, &condition, sizeof (CK_BBOOL)); 3334 i++; 3335 condition = (kuext.KeyUsageBits & KMF_digitalSignature) ? 3336 B_TRUE : B_FALSE; 3337 SETATTR(templ, i, CKA_SIGN_RECOVER, &condition, 3338 sizeof (CK_BBOOL)); 3339 i++; 3340 3341 } 3342 3343 if (keylabel != NULL) { 3344 SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel)); 3345 i++; 3346 } 3347 if (id.Data == NULL && rawkey->id.Data != NULL) { 3348 SETATTR(templ, i, CKA_ID, rawkey->id.Data, 3349 rawkey->id.Length); 3350 i++; 3351 } 3352 if (keytype == CKK_RSA) { 3353 SETATTR(templ, i, CKA_MODULUS, 3354 rawkey->rawdata.rsa.mod.val, 3355 rawkey->rawdata.rsa.mod.len); 3356 i++; 3357 SETATTR(templ, i, CKA_PUBLIC_EXPONENT, 3358 rawkey->rawdata.rsa.pubexp.val, 3359 rawkey->rawdata.rsa.pubexp.len); 3360 i++; 3361 if (rawkey->rawdata.rsa.priexp.val != NULL) { 3362 SETATTR(templ, i, CKA_PRIVATE_EXPONENT, 3363 rawkey->rawdata.rsa.priexp.val, 3364 rawkey->rawdata.rsa.priexp.len); 3365 i++; 3366 } 3367 if (rawkey->rawdata.rsa.prime1.val != NULL) { 3368 SETATTR(templ, i, CKA_PRIME_1, 3369 rawkey->rawdata.rsa.prime1.val, 3370 rawkey->rawdata.rsa.prime1.len); 3371 i++; 3372 } 3373 if (rawkey->rawdata.rsa.prime2.val != NULL) { 3374 SETATTR(templ, i, CKA_PRIME_2, 3375 rawkey->rawdata.rsa.prime2.val, 3376 rawkey->rawdata.rsa.prime2.len); 3377 i++; 3378 } 3379 if (rawkey->rawdata.rsa.exp1.val != NULL) { 3380 SETATTR(templ, i, CKA_EXPONENT_1, 3381 rawkey->rawdata.rsa.exp1.val, 3382 rawkey->rawdata.rsa.exp1.len); 3383 i++; 3384 } 3385 if (rawkey->rawdata.rsa.exp2.val != NULL) { 3386 SETATTR(templ, i, CKA_EXPONENT_2, 3387 rawkey->rawdata.rsa.exp2.val, 3388 rawkey->rawdata.rsa.exp2.len); 3389 i++; 3390 } 3391 if (rawkey->rawdata.rsa.coef.val != NULL) { 3392 SETATTR(templ, i, CKA_COEFFICIENT, 3393 rawkey->rawdata.rsa.coef.val, 3394 rawkey->rawdata.rsa.coef.len); 3395 i++; 3396 } 3397 } else if (keytype == CKK_DSA) { 3398 SETATTR(templ, i, CKA_PRIME, 3399 rawkey->rawdata.dsa.prime.val, 3400 rawkey->rawdata.dsa.prime.len); 3401 i++; 3402 SETATTR(templ, i, CKA_SUBPRIME, 3403 rawkey->rawdata.dsa.subprime.val, 3404 rawkey->rawdata.dsa.subprime.len); 3405 i++; 3406 SETATTR(templ, i, CKA_BASE, 3407 rawkey->rawdata.dsa.base.val, 3408 rawkey->rawdata.dsa.base.len); 3409 i++; 3410 SETATTR(templ, i, CKA_VALUE, 3411 rawkey->rawdata.dsa.value.val, 3412 rawkey->rawdata.dsa.value.len); 3413 i++; 3414 } else if (keytype == CKK_EC) { 3415 SETATTR(templ, i, CKA_SIGN, &cktrue, sizeof (cktrue)); 3416 i++; 3417 SETATTR(templ, i, CKA_DERIVE, &cktrue, sizeof (cktrue)); 3418 i++; 3419 SETATTR(templ, i, CKA_VALUE, 3420 rawkey->rawdata.ec.value.val, 3421 rawkey->rawdata.ec.value.len); 3422 i++; 3423 SETATTR(templ, i, CKA_EC_PARAMS, 3424 rawkey->rawdata.ec.params.Data, 3425 rawkey->rawdata.ec.params.Length); 3426 i++; 3427 } 3428 3429 ckrv = C_CreateObject(kmfh->pk11handle, templ, i, &keyobj); 3430 if (ckrv != CKR_OK) { 3431 SET_ERROR(kmfh, ckrv); 3432 3433 /* Report authentication failures to the caller */ 3434 if (ckrv == CKR_USER_NOT_LOGGED_IN || 3435 ckrv == CKR_PIN_INCORRECT || 3436 ckrv == CKR_PIN_INVALID || 3437 ckrv == CKR_PIN_EXPIRED || 3438 ckrv == CKR_PIN_LOCKED || 3439 ckrv == CKR_SESSION_READ_ONLY) 3440 rv = KMF_ERR_AUTH_FAILED; 3441 else 3442 rv = KMF_ERR_INTERNAL; 3443 } 3444 cleanup: 3445 if (start != NULL) 3446 free(start); 3447 if (end != NULL) 3448 free(end); 3449 kmf_free_data(&id); 3450 kmf_free_data(&subject); 3451 kmf_free_signed_cert(x509); 3452 free(x509); 3453 3454 return (rv); 3455 } 3456 3457 KMF_RETURN 3458 KMFPK11_CreateSymKey(KMF_HANDLE_T handle, 3459 int numattr, KMF_ATTRIBUTE *attrlist) 3460 { 3461 KMF_RETURN rv = KMF_OK; 3462 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3463 CK_RV ckrv; 3464 CK_SESSION_HANDLE hSession = kmfh->pk11handle; 3465 CK_OBJECT_HANDLE keyhandle; 3466 CK_MECHANISM keyGenMech; 3467 CK_OBJECT_CLASS class = CKO_SECRET_KEY; 3468 CK_ULONG secKeyType; 3469 CK_ULONG secKeyLen; /* for RC4 and AES */ 3470 CK_BBOOL true = TRUE; 3471 CK_BBOOL false = FALSE; 3472 CK_ATTRIBUTE templ[15]; 3473 CK_BYTE *keydata = NULL; 3474 int i = 0; 3475 KMF_KEY_HANDLE *symkey; 3476 KMF_KEY_ALG keytype; 3477 uint32_t keylen = 0; 3478 uint32_t attrkeylen = 0; 3479 uint32_t keylen_size = sizeof (uint32_t); 3480 char *keylabel = NULL; 3481 KMF_CREDENTIAL *cred = NULL; 3482 uint32_t is_sensitive = B_FALSE; 3483 uint32_t is_not_extractable = B_FALSE; 3484 3485 if (kmfh == NULL) 3486 return (KMF_ERR_UNINITIALIZED); 3487 3488 if (kmfh->pk11handle == CK_INVALID_HANDLE) 3489 return (KMF_ERR_NO_TOKEN_SELECTED); 3490 3491 symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 3492 if (symkey == NULL) 3493 return (KMF_ERR_BAD_PARAMETER); 3494 3495 rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, 3496 (void *)&keytype, NULL); 3497 if (rv != KMF_OK) 3498 return (KMF_ERR_BAD_PARAMETER); 3499 3500 keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr); 3501 if (keylabel == NULL) 3502 return (KMF_ERR_BAD_PARAMETER); 3503 3504 rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr, 3505 (void *)&is_sensitive, NULL); 3506 if (rv != KMF_OK) 3507 return (KMF_ERR_BAD_PARAMETER); 3508 3509 rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr, 3510 (void *)&is_not_extractable, NULL); 3511 if (rv != KMF_OK) 3512 return (KMF_ERR_BAD_PARAMETER); 3513 3514 /* 3515 * For AES, RC4, DES and 3DES, call C_GenerateKey() to create a key. 3516 * 3517 * For a generic secret key, because it may not be supported in 3518 * C_GenerateKey() for some PKCS11 providers, we will handle it 3519 * differently. 3520 */ 3521 if (keytype == KMF_GENERIC_SECRET) { 3522 rv = create_generic_secret_key(handle, numattr, 3523 attrlist, &keyhandle); 3524 if (rv != KMF_OK) 3525 goto out; 3526 else 3527 goto setup; 3528 } 3529 3530 rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr, 3531 NULL, &attrkeylen); 3532 if (rv == KMF_OK && attrkeylen > 0) { 3533 keydata = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist, 3534 numattr); 3535 } else { 3536 keydata = NULL; 3537 attrkeylen = 0; 3538 rv = KMF_OK; 3539 } 3540 if (keydata != NULL) { 3541 if (keytype == KMF_DES && attrkeylen != 8) { 3542 rv = KMF_ERR_BAD_KEY_SIZE; 3543 goto out; 3544 } 3545 if (keytype == KMF_DES3 && attrkeylen != 24) { 3546 rv = KMF_ERR_BAD_KEY_SIZE; 3547 goto out; 3548 } 3549 /* 3550 * This may override what the user gave on the 3551 * command line. 3552 */ 3553 keylen = attrkeylen * 8; /* bytes to bits */ 3554 } else { 3555 /* 3556 * If keydata was not given, key length must be 3557 * provided. 3558 */ 3559 rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, 3560 &keylen, &keylen_size); 3561 if (rv == KMF_ERR_ATTR_NOT_FOUND && 3562 (keytype == KMF_DES || keytype == KMF_DES3)) 3563 /* keylength is not required for DES and 3DES */ 3564 rv = KMF_OK; 3565 if (rv != KMF_OK) 3566 return (KMF_ERR_BAD_PARAMETER); 3567 } 3568 3569 if ((keylen % 8) != 0) { 3570 return (KMF_ERR_BAD_KEY_SIZE); 3571 } 3572 secKeyLen = keylen / 8; /* in bytes for RC4/AES */ 3573 3574 /* 3575 * Only set CKA_VALUE_LEN if the key data was not given and 3576 * we are creating an RC4 or AES key. 3577 */ 3578 if (keydata == NULL && 3579 (keytype == KMF_AES || keytype == KMF_RC4)) { 3580 SETATTR(templ, i, CKA_VALUE_LEN, &secKeyLen, 3581 sizeof (secKeyLen)); 3582 i++; 3583 } 3584 3585 /* Other keytypes */ 3586 keyGenMech.pParameter = NULL_PTR; 3587 keyGenMech.ulParameterLen = 0; 3588 switch (keytype) { 3589 case KMF_AES: 3590 keyGenMech.mechanism = CKM_AES_KEY_GEN; 3591 secKeyType = CKK_AES; 3592 break; 3593 case KMF_RC4: 3594 keyGenMech.mechanism = CKM_RC4_KEY_GEN; 3595 secKeyType = CKK_RC4; 3596 break; 3597 case KMF_DES: 3598 keyGenMech.mechanism = CKM_DES_KEY_GEN; 3599 secKeyType = CKK_DES; 3600 break; 3601 case KMF_DES3: 3602 keyGenMech.mechanism = CKM_DES3_KEY_GEN; 3603 secKeyType = CKK_DES3; 3604 break; 3605 default: 3606 return (KMF_ERR_BAD_KEY_TYPE); 3607 } 3608 if (keydata != NULL) { 3609 SETATTR(templ, i, CKA_VALUE, keydata, secKeyLen); 3610 i++; 3611 } 3612 SETATTR(templ, i, CKA_CLASS, &class, sizeof (class)); 3613 i++; 3614 SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType)); 3615 i++; 3616 3617 if (keylabel != NULL) { 3618 SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel)); 3619 i++; 3620 } 3621 3622 if (is_sensitive == B_TRUE) { 3623 SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true)); 3624 } else { 3625 SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false)); 3626 } 3627 i++; 3628 3629 if (is_not_extractable == B_TRUE) { 3630 SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false)); 3631 } else { 3632 SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true)); 3633 } 3634 i++; 3635 3636 SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true)); 3637 i++; 3638 SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true)); 3639 i++; 3640 SETATTR(templ, i, CKA_ENCRYPT, &true, sizeof (true)); 3641 i++; 3642 SETATTR(templ, i, CKA_DECRYPT, &true, sizeof (true)); 3643 i++; 3644 SETATTR(templ, i, CKA_SIGN, &true, sizeof (true)); 3645 i++; 3646 SETATTR(templ, i, CKA_VERIFY, &true, sizeof (true)); 3647 i++; 3648 3649 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr); 3650 if (cred == NULL) 3651 return (KMF_ERR_BAD_PARAMETER); 3652 3653 rv = pk11_authenticate(handle, cred); 3654 if (rv != KMF_OK) { 3655 return (rv); 3656 } 3657 3658 /* If the key data was given, use C_CreateObject */ 3659 if (keydata != NULL) { 3660 ckrv = C_CreateObject(hSession, templ, i, &keyhandle); 3661 } else { 3662 ckrv = C_GenerateKey(hSession, &keyGenMech, templ, i, 3663 &keyhandle); 3664 } 3665 if (ckrv != CKR_OK) { 3666 if (ckrv == CKR_USER_NOT_LOGGED_IN || 3667 ckrv == CKR_PIN_INCORRECT || 3668 ckrv == CKR_PIN_INVALID || 3669 ckrv == CKR_PIN_EXPIRED || 3670 ckrv == CKR_PIN_LOCKED || 3671 ckrv == CKR_SESSION_READ_ONLY) 3672 rv = KMF_ERR_AUTH_FAILED; 3673 else 3674 rv = KMF_ERR_KEYGEN_FAILED; 3675 SET_ERROR(kmfh, ckrv); 3676 goto out; 3677 } 3678 3679 setup: 3680 symkey->kstype = KMF_KEYSTORE_PK11TOKEN; 3681 symkey->keyalg = keytype; 3682 symkey->keyclass = KMF_SYMMETRIC; 3683 symkey->israw = FALSE; 3684 symkey->keyp = (void *)keyhandle; 3685 3686 out: 3687 return (rv); 3688 } 3689 3690 KMF_RETURN 3691 KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, 3692 KMF_RAW_SYM_KEY *rkey) 3693 { 3694 KMF_RETURN rv = KMF_OK; 3695 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3696 3697 if (kmfh == NULL) 3698 return (KMF_ERR_UNINITIALIZED); 3699 3700 if (kmfh->pk11handle == CK_INVALID_HANDLE) 3701 return (KMF_ERR_NO_TOKEN_SELECTED); 3702 3703 if (symkey == NULL || rkey == NULL) 3704 return (KMF_ERR_BAD_PARAMETER); 3705 else if (symkey->keyclass != KMF_SYMMETRIC) 3706 return (KMF_ERR_BAD_KEY_CLASS); 3707 3708 /* 3709 * If the key is already in "raw" format, copy the data 3710 * to the new record if possible. 3711 */ 3712 if (symkey->israw) { 3713 KMF_RAW_KEY_DATA *rawkey = (KMF_RAW_KEY_DATA *)symkey->keyp; 3714 3715 if (rawkey == NULL) 3716 return (KMF_ERR_BAD_KEYHANDLE); 3717 if (rawkey->sensitive) 3718 return (KMF_ERR_SENSITIVE_KEY); 3719 if (rawkey->not_extractable) 3720 return (KMF_ERR_UNEXTRACTABLE_KEY); 3721 3722 if (rawkey->rawdata.sym.keydata.val == NULL || 3723 rawkey->rawdata.sym.keydata.len == 0) 3724 return (KMF_ERR_GETKEYVALUE_FAILED); 3725 3726 rkey->keydata.len = rawkey->rawdata.sym.keydata.len; 3727 if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL) 3728 return (KMF_ERR_MEMORY); 3729 (void) memcpy(rkey->keydata.val, 3730 rawkey->rawdata.sym.keydata.val, rkey->keydata.len); 3731 } else { 3732 rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)symkey->keyp, rkey); 3733 } 3734 3735 return (rv); 3736 } 3737 3738 KMF_RETURN 3739 KMFPK11_SetTokenPin(KMF_HANDLE_T handle, 3740 int numattr, KMF_ATTRIBUTE *attrlist) 3741 { 3742 KMF_RETURN ret = KMF_OK; 3743 CK_RV rv = CKR_OK; 3744 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3745 CK_SESSION_HANDLE session = 0; 3746 KMF_CREDENTIAL *oldcred; 3747 KMF_CREDENTIAL *newcred; 3748 CK_SLOT_ID slotid; 3749 CK_USER_TYPE user = CKU_USER; 3750 3751 if (handle == NULL || attrlist == NULL || numattr == 0) 3752 return (KMF_ERR_BAD_PARAMETER); 3753 3754 oldcred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr); 3755 if (oldcred == NULL) 3756 return (KMF_ERR_BAD_PARAMETER); 3757 3758 newcred = kmf_get_attr_ptr(KMF_NEWPIN_ATTR, attrlist, numattr); 3759 if (newcred == NULL) 3760 return (KMF_ERR_BAD_PARAMETER); 3761 3762 rv = kmf_get_attr(KMF_SLOT_ID_ATTR, attrlist, numattr, 3763 (void *)&slotid, NULL); 3764 if (rv != KMF_OK) { 3765 char *tokenlabel = NULL; 3766 /* 3767 * If a slot wasn't given, the user must pass 3768 * a token label so we can find the slot here. 3769 */ 3770 tokenlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, 3771 numattr); 3772 if (tokenlabel == NULL) 3773 return (KMF_ERR_BAD_PARAMETER); 3774 3775 rv = kmf_pk11_token_lookup(handle, tokenlabel, &slotid); 3776 if (rv != KMF_OK) 3777 return (rv); 3778 } 3779 rv = kmf_get_attr(KMF_PK11_USER_TYPE_ATTR, attrlist, numattr, 3780 (void *)&user, NULL); 3781 if (rv != CKR_OK) 3782 user = CKU_USER; 3783 3784 rv = C_OpenSession(slotid, CKF_SERIAL_SESSION | CKF_RW_SESSION, 3785 NULL, NULL, &session); 3786 if (rv != CKR_OK) { 3787 SET_ERROR(kmfh, rv); 3788 ret = KMF_ERR_UNINITIALIZED; 3789 goto end; 3790 } 3791 3792 rv = C_Login(session, user, (CK_BYTE *)oldcred->cred, 3793 oldcred->credlen); 3794 if (rv != CKR_OK) { 3795 SET_ERROR(kmfh, rv); 3796 if (rv == CKR_PIN_INCORRECT || 3797 rv == CKR_PIN_INVALID || 3798 rv == CKR_PIN_EXPIRED || 3799 rv == CKR_PIN_LOCKED) 3800 ret = KMF_ERR_AUTH_FAILED; 3801 else 3802 ret = KMF_ERR_INTERNAL; 3803 3804 goto end; 3805 } 3806 3807 rv = C_SetPIN(session, 3808 (CK_BYTE *)oldcred->cred, oldcred->credlen, 3809 (CK_BYTE *)newcred->cred, newcred->credlen); 3810 3811 if (rv != CKR_OK) { 3812 SET_ERROR(kmfh, rv); 3813 if (rv == CKR_PIN_INCORRECT || 3814 rv == CKR_PIN_INVALID || 3815 rv == CKR_PIN_EXPIRED || 3816 rv == CKR_PIN_LOCKED) 3817 ret = KMF_ERR_AUTH_FAILED; 3818 else 3819 ret = KMF_ERR_INTERNAL; 3820 } 3821 end: 3822 if (session != 0) 3823 (void) C_CloseSession(session); 3824 return (ret); 3825 } 3826 3827 static KMF_RETURN 3828 create_generic_secret_key(KMF_HANDLE_T handle, 3829 int numattr, KMF_ATTRIBUTE *attrlist, CK_OBJECT_HANDLE *key) 3830 { 3831 KMF_RETURN rv = KMF_OK; 3832 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3833 CK_RV ckrv; 3834 CK_SESSION_HANDLE hSession = kmfh->pk11handle; 3835 CK_OBJECT_CLASS class = CKO_SECRET_KEY; 3836 CK_ULONG secKeyType = CKK_GENERIC_SECRET; 3837 CK_ULONG secKeyLen; 3838 CK_BBOOL true = TRUE; 3839 CK_BBOOL false = FALSE; 3840 CK_ATTRIBUTE templ[15]; 3841 int i; 3842 int random_fd = -1; 3843 int nread; 3844 int freebuf = 0; 3845 char *buf = NULL; 3846 uint32_t keylen = 0, attrkeylen = 0; 3847 char *keylabel = NULL; 3848 KMF_CREDENTIAL *cred; 3849 uint32_t is_sensitive, is_not_extractable; 3850 3851 keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr); 3852 if (keylabel == NULL) 3853 return (KMF_ERR_BAD_PARAMETER); 3854 3855 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr); 3856 if (cred == NULL) 3857 return (KMF_ERR_BAD_PARAMETER); 3858 3859 rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr, 3860 (void *)&is_sensitive, NULL); 3861 if (rv != KMF_OK) 3862 return (KMF_ERR_BAD_PARAMETER); 3863 3864 rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr, 3865 (void *)&is_not_extractable, NULL); 3866 if (rv != KMF_OK) 3867 return (KMF_ERR_BAD_PARAMETER); 3868 3869 rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr, 3870 NULL, &attrkeylen); 3871 if (rv == KMF_OK && attrkeylen > 0) { 3872 buf = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist, 3873 numattr); 3874 secKeyLen = attrkeylen; 3875 } else { 3876 buf = NULL; 3877 rv = KMF_OK; 3878 } 3879 if (buf == NULL) { 3880 /* 3881 * If the key data was not given, key length must 3882 * be provided. 3883 */ 3884 rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, 3885 &keylen, NULL); 3886 if (rv != KMF_OK) 3887 return (KMF_ERR_BAD_PARAMETER); 3888 3889 /* 3890 * Check the key size. 3891 */ 3892 if ((keylen % 8) != 0) { 3893 return (KMF_ERR_BAD_KEY_SIZE); 3894 } else { 3895 secKeyLen = keylen/8; /* in bytes */ 3896 } 3897 3898 /* 3899 * Generate a random number with the key size first. 3900 */ 3901 buf = malloc(secKeyLen); 3902 if (buf == NULL) 3903 return (KMF_ERR_MEMORY); 3904 3905 freebuf = 1; 3906 while ((random_fd = open(DEV_RANDOM, O_RDONLY)) < 0) { 3907 if (errno != EINTR) 3908 break; 3909 } 3910 3911 if (random_fd < 0) { 3912 rv = KMF_ERR_KEYGEN_FAILED; 3913 goto out; 3914 } 3915 3916 nread = read(random_fd, buf, secKeyLen); 3917 if (nread <= 0 || nread != secKeyLen) { 3918 rv = KMF_ERR_KEYGEN_FAILED; 3919 goto out; 3920 } 3921 } 3922 3923 /* 3924 * Authenticate into the token and call C_CreateObject to generate 3925 * a generic secret token key. 3926 */ 3927 rv = pk11_authenticate(handle, cred); 3928 if (rv != KMF_OK) { 3929 goto out; 3930 } 3931 3932 i = 0; 3933 SETATTR(templ, i, CKA_CLASS, &class, sizeof (class)); 3934 i++; 3935 SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType)); 3936 i++; 3937 SETATTR(templ, i, CKA_VALUE, buf, secKeyLen); 3938 i++; 3939 3940 if (keylabel != NULL) { 3941 SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel)); 3942 i++; 3943 } 3944 3945 if (is_sensitive == B_TRUE) { 3946 SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true)); 3947 } else { 3948 SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false)); 3949 } 3950 i++; 3951 3952 if (is_not_extractable == B_TRUE) { 3953 SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false)); 3954 } else { 3955 SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true)); 3956 } 3957 i++; 3958 3959 SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true)); 3960 i++; 3961 SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true)); 3962 i++; 3963 SETATTR(templ, i, CKA_SIGN, &true, sizeof (true)); 3964 i++; 3965 3966 ckrv = C_CreateObject(hSession, templ, i, key); 3967 if (ckrv != CKR_OK) { 3968 if (ckrv == CKR_USER_NOT_LOGGED_IN || 3969 ckrv == CKR_PIN_INCORRECT || 3970 ckrv == CKR_PIN_INVALID || 3971 ckrv == CKR_PIN_EXPIRED || 3972 ckrv == CKR_PIN_LOCKED || 3973 ckrv == CKR_SESSION_READ_ONLY) 3974 rv = KMF_ERR_AUTH_FAILED; 3975 else 3976 rv = KMF_ERR_KEYGEN_FAILED; 3977 SET_ERROR(kmfh, ckrv); 3978 } 3979 3980 out: 3981 if (buf != NULL && freebuf) 3982 free(buf); 3983 3984 if (random_fd != -1) 3985 (void) close(random_fd); 3986 3987 return (rv); 3988 } 3989 3990 KMF_RETURN 3991 KMFPK11_StoreKey(KMF_HANDLE_T handle, 3992 int numattr, 3993 KMF_ATTRIBUTE *attlist) 3994 { 3995 KMF_RETURN rv = KMF_OK; 3996 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3997 KMF_CREDENTIAL cred = { NULL, 0 }; 3998 KMF_KEY_HANDLE *key; 3999 KMF_RAW_KEY_DATA *rawkey = NULL; 4000 CK_BBOOL btrue = TRUE; 4001 CK_ATTRIBUTE tokenattr[1]; 4002 CK_OBJECT_HANDLE newobj; 4003 CK_RV ckrv; 4004 4005 if (kmfh == NULL) 4006 return (KMF_ERR_UNINITIALIZED); 4007 4008 if (kmfh->pk11handle == CK_INVALID_HANDLE) 4009 return (KMF_ERR_NO_TOKEN_SELECTED); 4010 4011 rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attlist, numattr, 4012 (void *)&cred, NULL); 4013 if (rv != KMF_OK) 4014 return (KMF_ERR_BAD_PARAMETER); 4015 4016 rv = pk11_authenticate(handle, &cred); 4017 if (rv != KMF_OK) 4018 return (rv); 4019 4020 key = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr); 4021 if (key == NULL) { 4022 key = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist, 4023 numattr); 4024 if (key == NULL) 4025 rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attlist, 4026 numattr); 4027 } 4028 if (key == NULL && rawkey == NULL) 4029 return (KMF_ERR_ATTR_NOT_FOUND); 4030 4031 if (rawkey != NULL) { 4032 rv = store_raw_key(handle, attlist, numattr, rawkey); 4033 } else if (key && key->kstype == KMF_KEYSTORE_PK11TOKEN) { 4034 4035 SETATTR(tokenattr, 0, CKA_TOKEN, &btrue, sizeof (btrue)); 4036 /* Copy the key object to the token */ 4037 ckrv = C_CopyObject(kmfh->pk11handle, 4038 (CK_OBJECT_HANDLE)key->keyp, tokenattr, 1, &newobj); 4039 if (ckrv != CKR_OK) { 4040 SET_ERROR(kmfh, ckrv); 4041 return (KMF_ERR_INTERNAL); 4042 } 4043 4044 /* Replace the object handle with the new token-based one */ 4045 ckrv = C_DestroyObject(kmfh->pk11handle, 4046 (CK_OBJECT_HANDLE)key->keyp); 4047 if (ckrv != CKR_OK) { 4048 SET_ERROR(kmfh, ckrv); 4049 return (KMF_ERR_INTERNAL); 4050 } 4051 key->keyp = (void *)newobj; 4052 } else { 4053 rv = KMF_ERR_BAD_PARAMETER; 4054 } 4055 4056 return (rv); 4057 } 4058 4059 4060 KMF_RETURN 4061 KMFPK11_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 4062 { 4063 KMF_RETURN rv = KMF_OK; 4064 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4065 KMF_CREDENTIAL *cred = NULL; 4066 KMF_CREDENTIAL *p12cred = NULL; 4067 char *filename = NULL; 4068 KMF_X509_DER_CERT *certlist = NULL; 4069 KMF_KEY_HANDLE *keylist = NULL; 4070 uint32_t numcerts; 4071 uint32_t numkeys; 4072 char *certlabel = NULL; 4073 char *issuer = NULL; 4074 char *subject = NULL; 4075 KMF_BIGINT *serial = NULL; 4076 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 4077 KMF_ATTRIBUTE fc_attrlist[16]; 4078 int i; 4079 4080 if (kmfh == NULL) 4081 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 4082 4083 if (kmfh->pk11handle == CK_INVALID_HANDLE) 4084 return (KMF_ERR_NO_TOKEN_SELECTED); 4085 4086 /* First get the required attributes */ 4087 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr); 4088 if (cred == NULL) 4089 return (KMF_ERR_BAD_PARAMETER); 4090 4091 p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr); 4092 if (p12cred == NULL) 4093 return (KMF_ERR_BAD_PARAMETER); 4094 4095 filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist, 4096 numattr); 4097 if (filename == NULL) 4098 return (KMF_ERR_BAD_PARAMETER); 4099 4100 /* Find all the certificates that match the searching criteria */ 4101 i = 0; 4102 kmf_set_attr_at_index(fc_attrlist, i, 4103 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 4104 i++; 4105 4106 kmf_set_attr_at_index(fc_attrlist, i, 4107 KMF_COUNT_ATTR, &numcerts, sizeof (uint32_t)); 4108 i++; 4109 4110 certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); 4111 if (certlabel != NULL) { 4112 kmf_set_attr_at_index(fc_attrlist, i, 4113 KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel)); 4114 i++; 4115 } 4116 4117 issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); 4118 if (issuer != NULL) { 4119 kmf_set_attr_at_index(fc_attrlist, i, 4120 KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer)); 4121 i++; 4122 } 4123 4124 subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); 4125 if (subject != NULL) { 4126 kmf_set_attr_at_index(fc_attrlist, i, 4127 KMF_SUBJECT_NAME_ATTR, subject, strlen(subject)); 4128 i++; 4129 } 4130 4131 serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); 4132 if (serial != NULL) { 4133 kmf_set_attr_at_index(fc_attrlist, i, 4134 KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT)); 4135 i++; 4136 } 4137 4138 rv = KMFPK11_FindCert(handle, i, fc_attrlist); 4139 4140 if (rv == KMF_OK && numcerts > 0) { 4141 certlist = (KMF_X509_DER_CERT *)malloc(numcerts * 4142 sizeof (KMF_X509_DER_CERT)); 4143 if (certlist == NULL) 4144 return (KMF_ERR_MEMORY); 4145 4146 (void) memset(certlist, 0, numcerts * 4147 sizeof (KMF_X509_DER_CERT)); 4148 4149 kmf_set_attr_at_index(fc_attrlist, i, KMF_X509_DER_CERT_ATTR, 4150 certlist, sizeof (KMF_X509_DER_CERT)); 4151 i++; 4152 4153 rv = kmf_find_cert(handle, i, fc_attrlist); 4154 if (rv != KMF_OK) { 4155 free(certlist); 4156 return (rv); 4157 } 4158 } else { 4159 return (rv); 4160 } 4161 4162 /* For each certificate, find the matching private key */ 4163 numkeys = 0; 4164 for (i = 0; i < numcerts; i++) { 4165 KMF_ATTRIBUTE fk_attrlist[16]; 4166 int j = 0; 4167 KMF_KEY_HANDLE newkey; 4168 KMF_ENCODE_FORMAT format = KMF_FORMAT_RAWKEY; 4169 4170 kmf_set_attr_at_index(fk_attrlist, j, 4171 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 4172 j++; 4173 4174 kmf_set_attr_at_index(fk_attrlist, j, 4175 KMF_ENCODE_FORMAT_ATTR, &format, sizeof (format)); 4176 j++; 4177 4178 kmf_set_attr_at_index(fk_attrlist, j, 4179 KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL)); 4180 j++; 4181 4182 kmf_set_attr_at_index(fk_attrlist, j, 4183 KMF_CERT_DATA_ATTR, &certlist[i].certificate, 4184 sizeof (KMF_DATA)); 4185 j++; 4186 4187 kmf_set_attr_at_index(fk_attrlist, j, 4188 KMF_KEY_HANDLE_ATTR, &newkey, sizeof (KMF_KEY_HANDLE)); 4189 j++; 4190 4191 rv = KMFPK11_FindPrikeyByCert(handle, j, fk_attrlist); 4192 if (rv == KMF_OK) { 4193 numkeys++; 4194 keylist = realloc(keylist, 4195 numkeys * sizeof (KMF_KEY_HANDLE)); 4196 if (keylist == NULL) { 4197 rv = KMF_ERR_MEMORY; 4198 goto out; 4199 } 4200 keylist[numkeys - 1] = newkey; 4201 } else if (rv == KMF_ERR_KEY_NOT_FOUND) { 4202 /* it is OK if a key is not found */ 4203 rv = KMF_OK; 4204 } 4205 } 4206 4207 if (rv != KMF_OK) 4208 goto out; 4209 4210 rv = kmf_build_pk12(handle, numcerts, certlist, numkeys, keylist, 4211 p12cred, filename); 4212 4213 out: 4214 if (certlist != NULL) { 4215 for (i = 0; i < numcerts; i++) 4216 kmf_free_kmf_cert(handle, &certlist[i]); 4217 free(certlist); 4218 } 4219 if (keylist != NULL) { 4220 for (i = 0; i < numkeys; i++) 4221 kmf_free_kmf_key(handle, &keylist[i]); 4222 free(keylist); 4223 } 4224 4225 return (rv); 4226 } 4227