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