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