1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * PKCS11 token KMF Plugin 23 * 24 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 #pragma ident "%Z%%M% %I% %E% SMI" 29 30 #include <stdio.h> /* debugging only */ 31 #include <errno.h> 32 #include <values.h> 33 34 #include <kmfapiP.h> 35 #include <ber_der.h> 36 #include <algorithm.h> 37 #include <fcntl.h> 38 #include <sha1.h> 39 #include <bignum.h> 40 41 #include <cryptoutil.h> 42 #include <security/cryptoki.h> 43 #include <security/pkcs11.h> 44 45 #define DEV_RANDOM "/dev/random" 46 47 #define SETATTR(t, n, atype, value, size) \ 48 t[n].type = atype; \ 49 t[n].pValue = (CK_BYTE *)value; \ 50 t[n].ulValueLen = (CK_ULONG)size; 51 52 #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; \ 53 h->lasterr.errcode = c; 54 55 typedef struct _objlist { 56 CK_OBJECT_HANDLE handle; 57 struct _objlist *next; 58 } OBJLIST; 59 60 static KMF_RETURN 61 search_certs(KMF_HANDLE_T, char *, char *, char *, KMF_BIGINT *, 62 boolean_t, KMF_CERT_VALIDITY, OBJLIST **, uint32_t *); 63 64 static CK_RV 65 getObjectLabel(KMF_HANDLE_T, CK_OBJECT_HANDLE, char **); 66 67 static KMF_RETURN 68 keyObj2RawKey(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_KEY_DATA **); 69 70 static KMF_RETURN 71 create_generic_secret_key(KMF_HANDLE_T, 72 int, KMF_ATTRIBUTE *, CK_OBJECT_HANDLE *); 73 74 KMF_RETURN 75 KMFPK11_ConfigureKeystore(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 76 77 KMF_RETURN 78 KMFPK11_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 79 80 void 81 KMFPK11_FreeKMFCert(KMF_HANDLE_T, 82 KMF_X509_DER_CERT *kmf_cert); 83 84 KMF_RETURN 85 KMFPK11_StoreCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 86 87 KMF_RETURN 88 KMFPK11_ImportCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 89 90 KMF_RETURN 91 KMFPK11_DeleteCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 92 93 KMF_RETURN 94 KMFPK11_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 95 96 KMF_RETURN 97 KMFPK11_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 98 99 KMF_RETURN 100 KMFPK11_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 101 102 KMF_RETURN 103 KMFPK11_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *); 104 105 KMF_RETURN 106 KMFPK11_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 107 KMF_DATA *, KMF_DATA *); 108 109 KMF_RETURN 110 KMFPK11_GetErrorString(KMF_HANDLE_T, char **); 111 112 KMF_RETURN 113 KMFPK11_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 114 115 KMF_RETURN 116 KMFPK11_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 117 KMF_DATA *, KMF_DATA *); 118 119 KMF_RETURN 120 KMFPK11_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 121 122 KMF_RETURN 123 KMFPK11_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 124 125 KMF_RETURN 126 KMFPK11_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *); 127 128 KMF_RETURN 129 KMFPK11_SetTokenPin(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 130 131 KMF_RETURN 132 KMFPK11_VerifyDataWithCert(KMF_HANDLE_T, KMF_ALGORITHM_INDEX, KMF_DATA *, 133 KMF_DATA *, KMF_DATA *); 134 135 KMF_RETURN 136 KMFPK11_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 137 138 139 static 140 KMF_PLUGIN_FUNCLIST pk11token_plugin_table = 141 { 142 1, /* Version */ 143 KMFPK11_ConfigureKeystore, 144 KMFPK11_FindCert, 145 KMFPK11_FreeKMFCert, 146 KMFPK11_StoreCert, 147 KMFPK11_ImportCert, 148 NULL, /* ImportCRL */ 149 KMFPK11_DeleteCert, 150 NULL, /* DeleteCRL */ 151 KMFPK11_CreateKeypair, 152 KMFPK11_FindKey, 153 KMFPK11_EncodePubKeyData, 154 KMFPK11_SignData, 155 KMFPK11_DeleteKey, 156 NULL, /* ListCRL */ 157 NULL, /* FindCRL */ 158 NULL, /* FindCertInCRL */ 159 KMFPK11_GetErrorString, 160 KMFPK11_FindPrikeyByCert, 161 KMFPK11_DecryptData, 162 KMFPK11_ExportPK12, 163 KMFPK11_CreateSymKey, 164 KMFPK11_GetSymKeyValue, 165 KMFPK11_SetTokenPin, 166 KMFPK11_VerifyDataWithCert, 167 KMFPK11_StoreKey, 168 NULL /* Finalize */ 169 }; 170 171 KMF_PLUGIN_FUNCLIST * 172 KMF_Plugin_Initialize() 173 { 174 return (&pk11token_plugin_table); 175 } 176 177 KMF_RETURN 178 KMFPK11_ConfigureKeystore(KMF_HANDLE_T handle, 179 int numattr, KMF_ATTRIBUTE *attrlist) 180 { 181 KMF_RETURN rv = KMF_OK; 182 char *label; 183 boolean_t readonly = B_TRUE; 184 185 label = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, numattr); 186 if (label == NULL) { 187 return (KMF_ERR_BAD_PARAMETER); 188 } 189 190 /* "readonly" is optional. Default is TRUE */ 191 (void) kmf_get_attr(KMF_READONLY_ATTR, attrlist, numattr, 192 (void *)&readonly, NULL); 193 194 rv = kmf_select_token(handle, label, readonly); 195 196 return (rv); 197 } 198 199 static KMF_RETURN 200 pk11_authenticate(KMF_HANDLE_T handle, 201 KMF_CREDENTIAL *cred) 202 { 203 204 CK_RV ck_rv = CKR_OK; 205 CK_SESSION_HANDLE hSession = (CK_SESSION_HANDLE)handle->pk11handle; 206 207 if (hSession == NULL) 208 return (KMF_ERR_NO_TOKEN_SELECTED); 209 210 if (cred == NULL || cred->cred == NULL || 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 1881 static CK_RV 1882 getObjectLabel(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj, 1883 char **outlabel) 1884 { 1885 CK_RV rv = CKR_OK; 1886 CK_ATTRIBUTE templ; 1887 char Label[BUFSIZ]; 1888 CK_ULONG len = sizeof (Label); 1889 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1890 1891 (void) memset(Label, 0, len); 1892 templ.type = CKA_LABEL; 1893 templ.pValue = Label; 1894 templ.ulValueLen = len; 1895 1896 rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1); 1897 if (rv == CKR_OK) { 1898 *outlabel = (char *)strdup(Label); 1899 } else { 1900 *outlabel = NULL; 1901 } 1902 return (rv); 1903 } 1904 1905 static CK_RV 1906 getObjectKeyclass(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj, 1907 KMF_KEY_CLASS *keyclass) 1908 { 1909 CK_RV rv = CKR_OK; 1910 CK_ATTRIBUTE templ; 1911 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1912 CK_OBJECT_CLASS class; 1913 1914 templ.type = CKA_CLASS; 1915 templ.pValue = &class; 1916 templ.ulValueLen = sizeof (CK_OBJECT_CLASS); 1917 1918 rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1); 1919 if (rv == CKR_OK) { 1920 if (class == CKO_PUBLIC_KEY) { 1921 *keyclass = KMF_ASYM_PUB; 1922 } else if (class == CKO_PRIVATE_KEY) { 1923 *keyclass = KMF_ASYM_PRI; 1924 } else if (class == CKO_SECRET_KEY) { 1925 *keyclass = KMF_SYMMETRIC; 1926 } 1927 } else { 1928 *keyclass = KMF_KEYCLASS_NONE; 1929 } 1930 return (rv); 1931 } 1932 1933 KMF_RETURN 1934 KMFPK11_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr, 1935 KMF_ATTRIBUTE *attrlist) 1936 { 1937 KMF_X509_SPKI *pubkey; 1938 KMF_X509_CERTIFICATE *SignerCert = NULL; 1939 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1940 KMF_RETURN rv = KMF_OK; 1941 CK_RV ckrv = CKR_OK; 1942 CK_ATTRIBUTE templ[4]; 1943 CK_OBJECT_HANDLE pri_obj = CK_INVALID_HANDLE; 1944 CK_ULONG obj_count; 1945 CK_OBJECT_CLASS certClass = CKO_PRIVATE_KEY; 1946 CK_BBOOL true = TRUE; 1947 KMF_DATA Id = { NULL, 0 }; 1948 KMF_KEY_HANDLE *key = NULL; 1949 KMF_DATA *cert = NULL; 1950 KMF_CREDENTIAL cred; 1951 KMF_ENCODE_FORMAT format = KMF_FORMAT_UNDEF; 1952 CK_ULONG keytype; 1953 1954 /* Get the key handle */ 1955 key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 1956 if (key == NULL) 1957 return (KMF_ERR_BAD_PARAMETER); 1958 1959 /* Get the optional encoded format */ 1960 (void) kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, 1961 (void *)&format, NULL); 1962 1963 /* Decode the signer cert so we can get the SPKI data */ 1964 cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); 1965 if (cert == NULL || cert->Data == NULL) 1966 return (KMF_ERR_BAD_PARAMETER); 1967 1968 if ((rv = DerDecodeSignedCertificate(cert, 1969 &SignerCert)) != KMF_OK) 1970 return (rv); 1971 1972 /* Get the public key info from the signer certificate */ 1973 pubkey = &SignerCert->certificate.subjectPublicKeyInfo; 1974 1975 /* Generate an ID from the SPKI data */ 1976 rv = GetIDFromSPKI(pubkey, &Id); 1977 if (rv != KMF_OK) { 1978 SET_ERROR(kmfh, rv); 1979 goto errout; 1980 } 1981 1982 /* Get the credential and login */ 1983 rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, 1984 (void *)&cred, NULL); 1985 if (rv != KMF_OK) 1986 return (KMF_ERR_BAD_PARAMETER); 1987 1988 rv = pk11_authenticate(handle, &cred); 1989 if (rv != KMF_OK) { 1990 return (rv); 1991 } 1992 1993 /* Start searching */ 1994 SETATTR(templ, 0, CKA_CLASS, &certClass, sizeof (certClass)); 1995 SETATTR(templ, 1, CKA_TOKEN, &true, sizeof (true)); 1996 SETATTR(templ, 2, CKA_PRIVATE, &true, sizeof (true)); 1997 SETATTR(templ, 3, CKA_ID, Id.Data, Id.Length); 1998 1999 if ((ckrv = C_FindObjectsInit(kmfh->pk11handle, templ, 4)) != CKR_OK) { 2000 SET_ERROR(kmfh, ckrv); 2001 rv = KMF_ERR_INTERNAL; 2002 goto errout; 2003 } 2004 2005 if ((rv = C_FindObjects(kmfh->pk11handle, &pri_obj, 1, 2006 &obj_count)) != CKR_OK) { 2007 SET_ERROR(kmfh, ckrv); 2008 rv = KMF_ERR_INTERNAL; 2009 goto errout; 2010 } 2011 2012 if (obj_count == 0) { 2013 SET_ERROR(kmfh, ckrv); 2014 rv = KMF_ERR_INTERNAL; 2015 goto errout; 2016 } 2017 2018 key->kstype = KMF_KEYSTORE_PK11TOKEN; 2019 key->keyclass = KMF_ASYM_PRI; 2020 key->keyp = (void *)pri_obj; 2021 key->israw = FALSE; 2022 2023 (void) C_FindObjectsFinal(kmfh->pk11handle); 2024 2025 ckrv = getObjectLabel(handle, (CK_OBJECT_HANDLE)key->keyp, 2026 &key->keylabel); 2027 if (ckrv != CKR_OK) { 2028 SET_ERROR(handle, ckrv); 2029 rv = KMF_ERR_INTERNAL; 2030 } else { 2031 rv = KMF_OK; 2032 } 2033 2034 /* 2035 * The key->keyalg value is needed if we need to convert the key 2036 * to raw key. However, the key->keyalg value will not be set if 2037 * this function is not called thru the kmf_find_prikey_by_cert() 2038 * framework function. To be safe, we will get the keytype from 2039 * the key object and set key->keyalg value here. 2040 */ 2041 ckrv = getObjectKeytype(handle, (CK_OBJECT_HANDLE)key->keyp, 2042 &keytype); 2043 if (ckrv != CKR_OK) { 2044 SET_ERROR(handle, ckrv); 2045 rv = KMF_ERR_INTERNAL; 2046 } else { 2047 rv = KMF_OK; 2048 } 2049 2050 if (keytype == CKK_RSA) 2051 key->keyalg = KMF_RSA; 2052 else if (keytype == CKK_DSA) 2053 key->keyalg = KMF_DSA; 2054 else { 2055 /* For asymmetric keys, we only support RSA and DSA */ 2056 rv = KMF_ERR_KEY_NOT_FOUND; 2057 goto errout; 2058 } 2059 2060 if (rv == KMF_OK && format == KMF_FORMAT_RAWKEY) { 2061 KMF_RAW_KEY_DATA *rkey = NULL; 2062 rv = keyObj2RawKey(handle, key, &rkey); 2063 if (rv == KMF_OK) { 2064 key->keyp = rkey; 2065 key->israw = TRUE; 2066 } 2067 } 2068 2069 errout: 2070 if (Id.Data != NULL) 2071 free(Id.Data); 2072 2073 if (SignerCert != NULL) { 2074 kmf_free_signed_cert(SignerCert); 2075 free(SignerCert); 2076 } 2077 return (rv); 2078 } 2079 2080 KMF_RETURN 2081 KMFPK11_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 2082 KMF_OID *algOID, KMF_DATA *ciphertext, 2083 KMF_DATA *output) 2084 { 2085 CK_RV ckrv; 2086 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2087 CK_SESSION_HANDLE hSession = kmfh->pk11handle; 2088 CK_MECHANISM mechanism; 2089 PKCS_ALGORITHM_MAP *pAlgMap; 2090 KMF_ALGORITHM_INDEX AlgId; 2091 CK_ULONG out_len = 0, block_len = 0, total_decrypted = 0; 2092 uint8_t *in_data, *out_data; 2093 int i, blocks; 2094 CK_ATTRIBUTE ckTemplate[1]; 2095 2096 if (kmfh == NULL) 2097 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 2098 2099 if (kmfh->pk11handle == CK_INVALID_HANDLE) 2100 return (KMF_ERR_NO_TOKEN_SELECTED); 2101 2102 if (key == NULL || algOID == NULL || 2103 ciphertext == NULL || output == NULL) 2104 return (KMF_ERR_BAD_PARAMETER); 2105 2106 AlgId = x509_algoid_to_algid(algOID); 2107 if (AlgId == KMF_ALGID_NONE) 2108 return (KMF_ERR_BAD_PARAMETER); 2109 2110 /* Map the Algorithm ID to a PKCS#11 mechanism */ 2111 pAlgMap = pkcs_get_alg_map(KMF_ALGCLASS_SIGNATURE, 2112 AlgId, PKCS_GetDefaultSignatureMode(AlgId)); 2113 2114 if (pAlgMap == NULL) 2115 return (KMF_ERR_BAD_PARAMETER); 2116 2117 mechanism.mechanism = pAlgMap->pkcs_mechanism; 2118 mechanism.pParameter = NULL; 2119 mechanism.ulParameterLen = 0; 2120 2121 SETATTR(ckTemplate, 0, CKA_MODULUS, (CK_BYTE *)NULL, 2122 sizeof (CK_ULONG)); 2123 2124 /* Get the modulus length */ 2125 ckrv = C_GetAttributeValue(hSession, 2126 (CK_OBJECT_HANDLE)key->keyp, ckTemplate, 1); 2127 2128 if (ckrv != CKR_OK) { 2129 SET_ERROR(kmfh, ckrv); 2130 return (KMF_ERR_INTERNAL); 2131 } 2132 2133 block_len = ckTemplate[0].ulValueLen; 2134 2135 /* Compute the number of times to do single-part decryption */ 2136 blocks = ciphertext->Length/block_len; 2137 2138 out_data = output->Data; 2139 in_data = ciphertext->Data; 2140 out_len = block_len - 11; 2141 2142 for (i = 0; i < blocks; i++) { 2143 ckrv = C_DecryptInit(hSession, &mechanism, 2144 (CK_OBJECT_HANDLE)key->keyp); 2145 2146 if (ckrv != CKR_OK) { 2147 SET_ERROR(kmfh, ckrv); 2148 return (KMF_ERR_INTERNAL); 2149 } 2150 2151 ckrv = C_Decrypt(hSession, in_data, block_len, 2152 out_data, (CK_ULONG *)&out_len); 2153 2154 if (ckrv != CKR_OK) { 2155 SET_ERROR(kmfh, ckrv); 2156 return (KMF_ERR_INTERNAL); 2157 } 2158 2159 out_data += out_len; 2160 total_decrypted += out_len; 2161 in_data += block_len; 2162 2163 } 2164 2165 output->Length = total_decrypted; 2166 return (KMF_OK); 2167 } 2168 2169 static void 2170 attr2bigint(CK_ATTRIBUTE_PTR attr, KMF_BIGINT *big) 2171 { 2172 big->val = attr->pValue; 2173 big->len = attr->ulValueLen; 2174 } 2175 2176 static KMF_RETURN 2177 get_bigint_attr(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, 2178 CK_ATTRIBUTE_TYPE attrtype, KMF_BIGINT *bigint) 2179 { 2180 CK_RV ckrv; 2181 CK_ATTRIBUTE attr; 2182 2183 attr.type = attrtype; 2184 attr.pValue = NULL; 2185 attr.ulValueLen = 0; 2186 2187 if ((ckrv = C_GetAttributeValue(sess, obj, 2188 &attr, 1)) != CKR_OK) { 2189 /* Mask this error so the caller can continue */ 2190 if (ckrv == CKR_ATTRIBUTE_TYPE_INVALID) 2191 return (KMF_OK); 2192 else 2193 return (KMF_ERR_INTERNAL); 2194 } 2195 if (attr.ulValueLen > 0 && bigint != NULL) { 2196 attr.pValue = malloc(attr.ulValueLen); 2197 if (attr.pValue == NULL) 2198 return (KMF_ERR_MEMORY); 2199 2200 if ((ckrv = C_GetAttributeValue(sess, obj, 2201 &attr, 1)) != CKR_OK) 2202 if (ckrv != CKR_OK) { 2203 free(attr.pValue); 2204 return (KMF_ERR_INTERNAL); 2205 } 2206 2207 bigint->val = attr.pValue; 2208 bigint->len = attr.ulValueLen; 2209 } 2210 return (KMF_OK); 2211 } 2212 2213 static KMF_RETURN 2214 get_raw_rsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_RSA_KEY *rawrsa) 2215 { 2216 KMF_RETURN rv = KMF_OK; 2217 CK_RV ckrv; 2218 CK_SESSION_HANDLE sess = kmfh->pk11handle; 2219 CK_ATTRIBUTE rsa_pri_attrs[2] = { 2220 { CKA_MODULUS, NULL, 0 }, 2221 { CKA_PUBLIC_EXPONENT, NULL, 0 } 2222 }; 2223 CK_ULONG count = sizeof (rsa_pri_attrs) / sizeof (CK_ATTRIBUTE); 2224 int i; 2225 2226 if (rawrsa == NULL) 2227 return (KMF_ERR_BAD_PARAMETER); 2228 2229 (void) memset(rawrsa, 0, sizeof (KMF_RAW_RSA_KEY)); 2230 if ((ckrv = C_GetAttributeValue(sess, obj, 2231 rsa_pri_attrs, count)) != CKR_OK) { 2232 SET_ERROR(kmfh, ckrv); 2233 /* Tell the caller know why the key data cannot be retrieved. */ 2234 if (ckrv == CKR_ATTRIBUTE_SENSITIVE) 2235 return (KMF_ERR_SENSITIVE_KEY); 2236 else if (ckrv == CKR_KEY_UNEXTRACTABLE) 2237 return (KMF_ERR_UNEXTRACTABLE_KEY); 2238 else 2239 return (KMF_ERR_INTERNAL); 2240 } 2241 2242 /* Allocate memory for each attribute. */ 2243 for (i = 0; i < count; i++) { 2244 if (rsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 || 2245 rsa_pri_attrs[i].ulValueLen == 0) { 2246 rsa_pri_attrs[i].ulValueLen = 0; 2247 continue; 2248 } 2249 if ((rsa_pri_attrs[i].pValue = 2250 malloc(rsa_pri_attrs[i].ulValueLen)) == NULL) { 2251 rv = KMF_ERR_MEMORY; 2252 goto end; 2253 } 2254 } 2255 /* Now that we have space, really get the attributes */ 2256 if ((rv = C_GetAttributeValue(sess, obj, 2257 rsa_pri_attrs, count)) != CKR_OK) { 2258 SET_ERROR(kmfh, rv); 2259 rv = KMF_ERR_INTERNAL; 2260 goto end; 2261 } 2262 i = 0; 2263 attr2bigint(&(rsa_pri_attrs[i++]), &rawrsa->mod); 2264 attr2bigint(&(rsa_pri_attrs[i++]), &rawrsa->pubexp); 2265 2266 /* Now get the optional parameters */ 2267 rv = get_bigint_attr(sess, obj, CKA_PRIVATE_EXPONENT, &rawrsa->priexp); 2268 if (rv != KMF_OK) 2269 goto end; 2270 rv = get_bigint_attr(sess, obj, CKA_PRIME_1, &rawrsa->prime1); 2271 if (rv != KMF_OK) 2272 goto end; 2273 rv = get_bigint_attr(sess, obj, CKA_PRIME_2, &rawrsa->prime2); 2274 if (rv != KMF_OK) 2275 goto end; 2276 rv = get_bigint_attr(sess, obj, CKA_EXPONENT_1, &rawrsa->exp1); 2277 if (rv != KMF_OK) 2278 goto end; 2279 rv = get_bigint_attr(sess, obj, CKA_EXPONENT_2, &rawrsa->exp2); 2280 if (rv != KMF_OK) 2281 goto end; 2282 rv = get_bigint_attr(sess, obj, CKA_COEFFICIENT, &rawrsa->coef); 2283 if (rv != KMF_OK) 2284 goto end; 2285 2286 end: 2287 if (rv != KMF_OK) { 2288 for (i = 0; i < count; i++) { 2289 if (rsa_pri_attrs[i].pValue != NULL) 2290 free(rsa_pri_attrs[i].pValue); 2291 } 2292 if (rawrsa->priexp.val) 2293 free(rawrsa->priexp.val); 2294 if (rawrsa->prime1.val) 2295 free(rawrsa->prime1.val); 2296 if (rawrsa->prime2.val) 2297 free(rawrsa->prime2.val); 2298 if (rawrsa->exp1.val) 2299 free(rawrsa->exp1.val); 2300 if (rawrsa->exp2.val) 2301 free(rawrsa->exp2.val); 2302 if (rawrsa->coef.val) 2303 free(rawrsa->coef.val); 2304 (void) memset(rawrsa, 0, sizeof (KMF_RAW_RSA_KEY)); 2305 } 2306 return (rv); 2307 } 2308 2309 #define DSA_PRIME_BUFSIZE 256 /* 8192 bits */ 2310 #define DSA_PRIVATE_BUFSIZE 5 /* 160 bits */ 2311 2312 /* 2313 * This function calculates the pubkey value from the prime, 2314 * base and private key values of a DSA key. 2315 */ 2316 static KMF_RETURN 2317 compute_dsa_pubvalue(KMF_RAW_DSA_KEY *rawdsa) 2318 { 2319 KMF_RETURN rv = KMF_OK; 2320 BIGNUM p, g, x, y; 2321 BIG_ERR_CODE err; 2322 uchar_t *pubvalue; 2323 uint32_t pubvalue_len; 2324 2325 if ((err = big_init1(&p, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) { 2326 rv = KMF_ERR_MEMORY; 2327 return (rv); 2328 } 2329 bytestring2bignum(&p, rawdsa->prime.val, rawdsa->prime.len); 2330 2331 if ((err = big_init1(&g, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) { 2332 rv = KMF_ERR_MEMORY; 2333 goto ret1; 2334 } 2335 bytestring2bignum(&g, rawdsa->base.val, rawdsa->base.len); 2336 2337 if ((err = big_init1(&x, DSA_PRIVATE_BUFSIZE, NULL, 0)) != BIG_OK) { 2338 rv = KMF_ERR_MEMORY; 2339 goto ret2; 2340 } 2341 bytestring2bignum(&x, rawdsa->value.val, rawdsa->value.len); 2342 2343 if ((err = big_init1(&y, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) { 2344 rv = KMF_ERR_MEMORY; 2345 goto ret3; 2346 } 2347 2348 err = big_modexp(&y, &g, &x, &p, NULL); 2349 if (err != BIG_OK) { 2350 rv = KMF_ERR_INTERNAL; 2351 goto ret3; 2352 } 2353 2354 pubvalue_len = y.len * (int)sizeof (uint32_t); 2355 if ((pubvalue = malloc(pubvalue_len)) == NULL) { 2356 rv = KMF_ERR_MEMORY; 2357 goto ret4; 2358 } 2359 bignum2bytestring(pubvalue, &y, pubvalue_len); 2360 2361 rawdsa->pubvalue.val = pubvalue; 2362 rawdsa->pubvalue.len = pubvalue_len; 2363 2364 ret4: 2365 big_finish(&y); 2366 ret3: 2367 big_finish(&x); 2368 ret2: 2369 big_finish(&g); 2370 ret1: 2371 big_finish(&p); 2372 return (rv); 2373 } 2374 2375 2376 static KMF_RETURN 2377 get_raw_dsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_DSA_KEY *rawdsa) 2378 { 2379 KMF_RETURN rv = KMF_OK; 2380 CK_RV ckrv; 2381 CK_SESSION_HANDLE sess = kmfh->pk11handle; 2382 CK_ATTRIBUTE dsa_pri_attrs[8] = { 2383 { CKA_PRIME, NULL, 0 }, 2384 { CKA_SUBPRIME, NULL, 0 }, 2385 { CKA_BASE, NULL, 0 }, 2386 { CKA_VALUE, NULL, 0 } 2387 }; 2388 CK_ULONG count = sizeof (dsa_pri_attrs) / sizeof (CK_ATTRIBUTE); 2389 int i; 2390 2391 if ((ckrv = C_GetAttributeValue(sess, obj, 2392 dsa_pri_attrs, count)) != CKR_OK) { 2393 SET_ERROR(kmfh, ckrv); 2394 2395 /* Tell the caller know why the key data cannot be retrieved. */ 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 return (KMF_ERR_INTERNAL); 2401 } 2402 2403 /* Allocate memory for each attribute. */ 2404 for (i = 0; i < count; i++) { 2405 if (dsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 || 2406 dsa_pri_attrs[i].ulValueLen == 0) { 2407 dsa_pri_attrs[i].ulValueLen = 0; 2408 continue; 2409 } 2410 if ((dsa_pri_attrs[i].pValue = 2411 malloc(dsa_pri_attrs[i].ulValueLen)) == NULL) { 2412 rv = KMF_ERR_MEMORY; 2413 goto end; 2414 } 2415 } 2416 if ((rv = C_GetAttributeValue(sess, obj, 2417 dsa_pri_attrs, count)) != CKR_OK) { 2418 SET_ERROR(kmfh, rv); 2419 rv = KMF_ERR_INTERNAL; 2420 goto end; 2421 } 2422 2423 /* Fill in all the temp variables. They are all required. */ 2424 i = 0; 2425 attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->prime); 2426 attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->subprime); 2427 attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->base); 2428 attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->value); 2429 2430 /* Compute the public key value and store it */ 2431 rv = compute_dsa_pubvalue(rawdsa); 2432 2433 end: 2434 if (rv != KMF_OK) { 2435 for (i = 0; i < count; i++) { 2436 if (dsa_pri_attrs[i].pValue != NULL) 2437 free(dsa_pri_attrs[i].pValue); 2438 } 2439 (void) memset(rawdsa, 0, sizeof (KMF_RAW_DSA_KEY)); 2440 } 2441 return (rv); 2442 } 2443 2444 static KMF_RETURN 2445 get_raw_sym(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_SYM_KEY *rawsym) 2446 { 2447 KMF_RETURN rv = KMF_OK; 2448 CK_RV ckrv; 2449 CK_SESSION_HANDLE sess = kmfh->pk11handle; 2450 CK_ATTRIBUTE sym_attr[1]; 2451 CK_ULONG value_len = 0; 2452 2453 /* find the key length first */ 2454 sym_attr[0].type = CKA_VALUE; 2455 sym_attr[0].pValue = NULL; 2456 sym_attr[0].ulValueLen = value_len; 2457 if ((ckrv = C_GetAttributeValue(sess, obj, sym_attr, 1)) != CKR_OK) { 2458 rawsym->keydata.val = NULL; 2459 rawsym->keydata.len = 0; 2460 if (ckrv == CKR_ATTRIBUTE_SENSITIVE) { 2461 return (KMF_ERR_SENSITIVE_KEY); 2462 } else if (ckrv == CKR_KEY_UNEXTRACTABLE) { 2463 return (KMF_ERR_UNEXTRACTABLE_KEY); 2464 } else { 2465 SET_ERROR(kmfh, ckrv); 2466 return (KMF_ERR_INTERNAL); 2467 } 2468 } 2469 2470 /* Allocate memory for pValue */ 2471 sym_attr[0].pValue = malloc(sym_attr[0].ulValueLen); 2472 if (sym_attr[0].pValue == NULL) { 2473 return (KMF_ERR_MEMORY); 2474 } 2475 2476 /* get the key data */ 2477 if ((rv = C_GetAttributeValue(sess, obj, sym_attr, 1)) != CKR_OK) { 2478 SET_ERROR(kmfh, rv); 2479 free(sym_attr[0].pValue); 2480 return (KMF_ERR_INTERNAL); 2481 } 2482 2483 rawsym->keydata.val = sym_attr[0].pValue; 2484 rawsym->keydata.len = sym_attr[0].ulValueLen; 2485 return (rv); 2486 } 2487 2488 static KMF_RETURN 2489 keyObj2RawKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *inkey, 2490 KMF_RAW_KEY_DATA **outkey) 2491 { 2492 KMF_RETURN rv = KMF_OK; 2493 KMF_RAW_KEY_DATA *rkey; 2494 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2495 2496 rkey = malloc(sizeof (KMF_RAW_KEY_DATA)); 2497 if (rkey == NULL) 2498 return (KMF_ERR_MEMORY); 2499 2500 (void) memset(rkey, 0, sizeof (KMF_RAW_KEY_DATA)); 2501 2502 rkey->keytype = inkey->keyalg; 2503 2504 if (inkey->keyalg == KMF_RSA) { 2505 rv = get_raw_rsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp, 2506 &rkey->rawdata.rsa); 2507 } else if (inkey->keyalg == KMF_DSA) { 2508 rv = get_raw_dsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp, 2509 &rkey->rawdata.dsa); 2510 } else if (inkey->keyalg == KMF_AES || 2511 inkey->keyalg == KMF_RC4 || 2512 inkey->keyalg == KMF_DES || 2513 inkey->keyalg == KMF_DES3 || 2514 inkey->keyalg == KMF_GENERIC_SECRET) { 2515 rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)inkey->keyp, 2516 &rkey->rawdata.sym); 2517 /* 2518 * If sensitive or non-extractable, mark them as such 2519 * but return "OK" status so the keys get counted 2520 * when doing FindKey operations. 2521 */ 2522 if (rv == KMF_ERR_SENSITIVE_KEY) { 2523 rkey->sensitive = B_TRUE; 2524 rv = KMF_OK; 2525 } else if (rv == KMF_ERR_UNEXTRACTABLE_KEY) { 2526 rkey->not_extractable = B_TRUE; 2527 rv = KMF_OK; 2528 } 2529 } else { 2530 rv = KMF_ERR_BAD_PARAMETER; 2531 } 2532 2533 if (rv == KMF_OK) { 2534 *outkey = rkey; 2535 } else if (rkey != NULL) { 2536 free(rkey); 2537 *outkey = NULL; 2538 } 2539 2540 return (rv); 2541 } 2542 2543 2544 static KMF_RETURN 2545 kmf2pk11keytype(KMF_KEY_ALG keyalg, CK_KEY_TYPE *type) 2546 { 2547 switch (keyalg) { 2548 case KMF_RSA: 2549 *type = CKK_RSA; 2550 break; 2551 case KMF_DSA: 2552 *type = CKK_DSA; 2553 break; 2554 case KMF_AES: 2555 *type = CKK_AES; 2556 break; 2557 case KMF_RC4: 2558 *type = CKK_RC4; 2559 break; 2560 case KMF_DES: 2561 *type = CKK_DES; 2562 break; 2563 case KMF_DES3: 2564 *type = CKK_DES3; 2565 break; 2566 case KMF_GENERIC_SECRET: 2567 *type = CKK_GENERIC_SECRET; 2568 break; 2569 default: 2570 return (KMF_ERR_BAD_KEY_TYPE); 2571 } 2572 2573 return (KMF_OK); 2574 } 2575 2576 static int 2577 IDStringToData(char *idstr, KMF_DATA *iddata) 2578 { 2579 int len, i; 2580 char *iddup, *byte; 2581 uint_t lvalue; 2582 2583 if (idstr == NULL || !strlen(idstr)) 2584 return (-1); 2585 2586 iddup = (char *)strdup(idstr); 2587 if (iddup == NULL) 2588 return (KMF_ERR_MEMORY); 2589 2590 len = strlen(iddup) / 3 + 1; 2591 iddata->Data = malloc(len); 2592 if (iddata->Data == NULL) 2593 return (KMF_ERR_MEMORY); 2594 (void) memset(iddata->Data, 0, len); 2595 iddata->Length = len; 2596 2597 byte = strtok(iddup, ":"); 2598 if (byte == NULL) { 2599 free(iddup); 2600 free(iddata->Data); 2601 iddata->Data = NULL; 2602 iddata->Length = 0; 2603 return (-1); 2604 } 2605 2606 i = 0; 2607 do { 2608 (void) sscanf(byte, "%x", &lvalue); 2609 iddata->Data[i++] = (uchar_t)(lvalue & 0x000000FF); 2610 byte = strtok(NULL, ":"); 2611 } while (byte != NULL && i < len); 2612 2613 iddata->Length = i; 2614 free(iddup); 2615 return (0); 2616 } 2617 2618 KMF_RETURN 2619 KMFPK11_FindKey(KMF_HANDLE_T handle, 2620 int numattr, KMF_ATTRIBUTE *attrlist) 2621 { 2622 KMF_RETURN rv = KMF_OK; 2623 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2624 uint32_t want_keys, i; 2625 CK_RV ckrv; 2626 CK_ATTRIBUTE pTmpl[10]; 2627 CK_OBJECT_CLASS class; 2628 CK_BBOOL true = TRUE; 2629 CK_ULONG alg; 2630 boolean_t is_token = B_TRUE, is_private = B_FALSE; 2631 KMF_KEY_HANDLE *keys; 2632 uint32_t *numkeys; 2633 KMF_CREDENTIAL cred; 2634 KMF_KEY_CLASS keyclass = KMF_KEYCLASS_NONE; 2635 char *findLabel, *idstr; 2636 KMF_KEY_ALG keytype = KMF_KEYALG_NONE; 2637 KMF_ENCODE_FORMAT format; 2638 2639 if (kmfh == NULL) 2640 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 2641 2642 if (kmfh->pk11handle == CK_INVALID_HANDLE) 2643 return (KMF_ERR_NO_TOKEN_SELECTED); 2644 2645 numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr); 2646 if (numkeys == NULL) 2647 return (KMF_ERR_BAD_PARAMETER); 2648 2649 if (*numkeys > 0) 2650 want_keys = *numkeys; 2651 else 2652 want_keys = MAXINT; /* count them all */ 2653 2654 /* keyclass is optional */ 2655 (void) kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr, 2656 (void *)&keyclass, NULL); 2657 2658 if (keyclass == KMF_ASYM_PUB) { 2659 class = CKO_PUBLIC_KEY; 2660 } else if (keyclass == KMF_ASYM_PRI) { 2661 class = CKO_PRIVATE_KEY; 2662 } else if (keyclass == KMF_SYMMETRIC) { 2663 class = CKO_SECRET_KEY; 2664 } 2665 2666 rv = kmf_get_attr(KMF_TOKEN_BOOL_ATTR, attrlist, numattr, 2667 (void *)&is_token, NULL); 2668 if (rv != KMF_OK) 2669 return (rv); 2670 2671 i = 0; 2672 if (is_token) { 2673 SETATTR(pTmpl, i, CKA_TOKEN, &true, sizeof (true)); 2674 i++; 2675 } 2676 2677 if (keyclass != KMF_KEYCLASS_NONE) { 2678 SETATTR(pTmpl, i, CKA_CLASS, &class, sizeof (class)); 2679 i++; 2680 } 2681 2682 findLabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr); 2683 2684 if (findLabel != NULL && strlen(findLabel)) { 2685 SETATTR(pTmpl, i, CKA_LABEL, findLabel, strlen(findLabel)); 2686 i++; 2687 } 2688 /* keytype is optional */ 2689 (void) kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, 2690 (void *)&keytype, NULL); 2691 2692 if (keytype != 0) { 2693 rv = kmf2pk11keytype(keytype, &alg); 2694 if (rv != KMF_OK) { 2695 return (KMF_ERR_BAD_KEY_TYPE); 2696 } 2697 SETATTR(pTmpl, i, CKA_KEY_TYPE, &alg, sizeof (alg)); 2698 i++; 2699 } 2700 2701 idstr = kmf_get_attr_ptr(KMF_IDSTR_ATTR, attrlist, numattr); 2702 2703 if (idstr != NULL) { 2704 KMF_DATA iddata = { NULL, 0 }; 2705 2706 /* 2707 * ID String parameter is assumed to be of form: 2708 * XX:XX:XX:XX:XX ... :XX 2709 * where XX is a hex number. 2710 * 2711 * We must convert this back to binary in order to 2712 * use it in a search. 2713 */ 2714 rv = IDStringToData(idstr, &iddata); 2715 if (rv == KMF_OK) { 2716 SETATTR(pTmpl, i, CKA_ID, iddata.Data, iddata.Length); 2717 i++; 2718 } else { 2719 return (rv); 2720 } 2721 } 2722 2723 /* is_private is optional */ 2724 (void) kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr, 2725 (void *)&is_private, NULL); 2726 2727 if (is_private) { 2728 SETATTR(pTmpl, i, CKA_PRIVATE, &true, sizeof (true)); 2729 i++; 2730 } 2731 2732 /* 2733 * Authenticate if the object is a token object, 2734 * a private or secred key, or if the user passed in credentials. 2735 */ 2736 if ((rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, 2737 (void *)&cred, NULL)) == KMF_OK) { 2738 if (cred.credlen > 0) { 2739 rv = pk11_authenticate(handle, &cred); 2740 if (rv != KMF_OK) 2741 return (rv); 2742 } 2743 } else { 2744 rv = KMF_OK; /* cred is optional */ 2745 } 2746 2747 keys = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 2748 /* it is okay to have "keys" contains NULL */ 2749 2750 ckrv = C_FindObjectsInit(kmfh->pk11handle, pTmpl, i); 2751 if (ckrv == CKR_OK) { 2752 CK_ULONG obj_count, n = 0; 2753 while (ckrv == CKR_OK && n < want_keys) { 2754 CK_OBJECT_HANDLE hObj; 2755 2756 ckrv = C_FindObjects(kmfh->pk11handle, &hObj, 2757 1, &obj_count); 2758 if (ckrv == CKR_OK && obj_count == 1) { 2759 if (keys != NULL) { 2760 CK_ULONG keytype; 2761 keys[n].kstype = KMF_KEYSTORE_PK11TOKEN; 2762 keys[n].israw = FALSE; 2763 keys[n].keyp = (void *)hObj; 2764 2765 ckrv = getObjectKeytype(handle, 2766 (CK_OBJECT_HANDLE)keys[n].keyp, 2767 &keytype); 2768 if (ckrv != CKR_OK) 2769 goto end; 2770 2771 ckrv = getObjectLabel(handle, 2772 (CK_OBJECT_HANDLE)keys[n].keyp, 2773 &(keys[n].keylabel)); 2774 if (ckrv != CKR_OK) 2775 goto end; 2776 2777 if (keyclass == KMF_KEYCLASS_NONE) { 2778 ckrv = getObjectKeyclass(handle, 2779 (CK_OBJECT_HANDLE) 2780 keys[n].keyp, 2781 &(keys[n].keyclass)); 2782 if (ckrv != CKR_OK) 2783 goto end; 2784 } else { 2785 keys[n].keyclass = keyclass; 2786 } 2787 if (keytype == CKK_RSA) { 2788 keys[n].keyalg = KMF_RSA; 2789 } else if (keytype == CKK_DSA) { 2790 keys[n].keyalg = KMF_DSA; 2791 } else if (keytype == CKK_AES) { 2792 keys[n].keyalg = KMF_AES; 2793 keys[n].keyclass = 2794 KMF_SYMMETRIC; 2795 } else if (keytype == CKK_RC4) { 2796 keys[n].keyalg = KMF_RC4; 2797 keys[n].keyclass = 2798 KMF_SYMMETRIC; 2799 } else if (keytype == CKK_DES) { 2800 keys[n].keyalg = KMF_DES; 2801 keys[n].keyclass = 2802 KMF_SYMMETRIC; 2803 } else if (keytype == CKK_DES3) { 2804 keys[n].keyalg = KMF_DES3; 2805 keys[n].keyclass = 2806 KMF_SYMMETRIC; 2807 } else if (keytype == 2808 CKK_GENERIC_SECRET) { 2809 keys[n].keyalg = 2810 KMF_GENERIC_SECRET; 2811 keys[n].keyclass = 2812 KMF_SYMMETRIC; 2813 } 2814 2815 } 2816 n++; 2817 } else { 2818 break; 2819 } 2820 } 2821 ckrv = C_FindObjectsFinal(kmfh->pk11handle); 2822 2823 /* "numkeys" indicates the number that were actually found */ 2824 *numkeys = n; 2825 } 2826 2827 if (ckrv == KMF_OK && keys != NULL && (*numkeys) > 0) { 2828 if ((rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, 2829 numattr, (void *)&format, NULL)) == KMF_OK) { 2830 if (format == KMF_FORMAT_RAWKEY || 2831 format == KMF_FORMAT_PEM) { 2832 /* Convert keys to "rawkey" format */ 2833 for (i = 0; i < (*numkeys); i++) { 2834 KMF_RAW_KEY_DATA *rkey = NULL; 2835 rv = keyObj2RawKey(handle, &keys[i], 2836 &rkey); 2837 if (rv == KMF_OK) { 2838 keys[i].keyp = rkey; 2839 keys[i].israw = TRUE; 2840 } else { 2841 break; 2842 } 2843 } 2844 } 2845 } else { 2846 rv = KMF_OK; /* format is optional */ 2847 } 2848 } 2849 2850 end: 2851 if (ckrv != CKR_OK) { 2852 SET_ERROR(kmfh, ckrv); 2853 /* Report authentication failures to the caller */ 2854 if (ckrv == CKR_USER_NOT_LOGGED_IN || 2855 ckrv == CKR_PIN_INCORRECT || 2856 ckrv == CKR_PIN_INVALID || 2857 ckrv == CKR_PIN_EXPIRED || 2858 ckrv == CKR_PIN_LOCKED || 2859 ckrv == CKR_SESSION_READ_ONLY) 2860 rv = KMF_ERR_AUTH_FAILED; 2861 else 2862 rv = KMF_ERR_INTERNAL; 2863 } else if ((*numkeys) == 0) { 2864 rv = KMF_ERR_KEY_NOT_FOUND; 2865 } 2866 2867 return (rv); 2868 } 2869 2870 static char * 2871 convertDate(char *fulldate) 2872 { 2873 struct tm tms; 2874 char newtime[9]; 2875 2876 (void) strptime(fulldate, "%b %d %T %Y %Z", &tms); 2877 2878 if (tms.tm_year < 69) 2879 tms.tm_year += 100; 2880 2881 (void) strftime(newtime, sizeof (newtime), "m%d", &tms); 2882 2883 newtime[8] = 0; 2884 2885 /* memory returned must be freed by the caller */ 2886 return ((char *)strdup(newtime)); 2887 } 2888 2889 static KMF_RETURN 2890 store_raw_key(KMF_HANDLE_T handle, 2891 KMF_ATTRIBUTE *attrlist, int numattr, 2892 KMF_RAW_KEY_DATA *rawkey) 2893 { 2894 KMF_RETURN rv = KMF_OK; 2895 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2896 int i; 2897 CK_RV ckrv = CKR_OK; 2898 CK_ATTRIBUTE templ[32]; 2899 CK_OBJECT_HANDLE keyobj; 2900 CK_KEY_TYPE keytype; 2901 CK_OBJECT_CLASS oClass = CKO_PRIVATE_KEY; 2902 CK_BBOOL cktrue = TRUE; 2903 CK_DATE startdate, enddate; 2904 KMF_DATA id = {NULL, 0}; 2905 KMF_DATA subject = {NULL, 0}; 2906 KMF_X509EXT_KEY_USAGE kuext; 2907 KMF_X509_CERTIFICATE *x509 = NULL; 2908 CK_BBOOL kufound = B_FALSE; 2909 KMF_DATA *cert = NULL; 2910 char *notbefore = NULL, *start = NULL; 2911 char *notafter = NULL, *end = NULL; 2912 char *keylabel = NULL; 2913 2914 if (kmfh == NULL) 2915 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 2916 2917 if (kmfh->pk11handle == CK_INVALID_HANDLE) 2918 return (KMF_ERR_NO_TOKEN_SELECTED); 2919 2920 if (rawkey->keytype == KMF_RSA) 2921 keytype = CKK_RSA; 2922 else if (rawkey->keytype == KMF_DSA) 2923 keytype = CKK_DSA; 2924 else 2925 return (KMF_ERR_BAD_PARAMETER); 2926 2927 keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr); 2928 /* 2929 * If the caller did not specify a label, see if the raw key 2930 * came with one (possible if it came from a PKCS#12 file). 2931 */ 2932 if (keylabel == NULL) { 2933 keylabel = rawkey->label; 2934 } 2935 2936 i = 0; 2937 SETATTR(templ, i, CKA_CLASS, &oClass, sizeof (CK_OBJECT_CLASS)); i++; 2938 SETATTR(templ, i, CKA_KEY_TYPE, &keytype, sizeof (keytype)); i++; 2939 SETATTR(templ, i, CKA_TOKEN, &cktrue, sizeof (cktrue)); i++; 2940 SETATTR(templ, i, CKA_PRIVATE, &cktrue, sizeof (cktrue)); i++; 2941 SETATTR(templ, i, CKA_DECRYPT, &cktrue, sizeof (cktrue)); i++; 2942 2943 cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); 2944 if (cert != NULL) { 2945 id.Data = NULL; 2946 id.Length = 0; 2947 rv = kmf_get_cert_id_data(cert, &id); 2948 if (rv != KMF_OK) { 2949 goto cleanup; 2950 } 2951 2952 rv = DerDecodeSignedCertificate((const KMF_DATA *)cert, &x509); 2953 if (rv != KMF_OK) { 2954 goto cleanup; 2955 } 2956 2957 rv = DerEncodeName(&x509->certificate.subject, &subject); 2958 if (rv != KMF_OK) { 2959 goto cleanup; 2960 } 2961 SETATTR(templ, i, CKA_SUBJECT, subject.Data, subject.Length); 2962 i++; 2963 2964 rv = kmf_get_cert_start_date_str(handle, cert, ¬before); 2965 if (rv != KMF_OK) { 2966 goto cleanup; 2967 } 2968 start = convertDate(notbefore); 2969 free(notbefore); 2970 2971 rv = kmf_get_cert_end_date_str(handle, cert, ¬after); 2972 if (rv != KMF_OK) { 2973 goto cleanup; 2974 } 2975 end = convertDate(notafter); 2976 free(notafter); 2977 if (id.Data != NULL && id.Data != NULL && id.Length > 0) { 2978 SETATTR(templ, i, CKA_ID, id.Data, id.Length); 2979 i++; 2980 } 2981 if (start != NULL) { 2982 /* 2983 * This makes some potentially dangerous assumptions: 2984 * 1. that the startdate in the parameter block is 2985 * properly formatted as YYYYMMDD 2986 * 2. That the CK_DATE structure is always the same. 2987 */ 2988 (void) memcpy(&startdate, start, sizeof (CK_DATE)); 2989 SETATTR(templ, i, CKA_START_DATE, &startdate, 2990 sizeof (startdate)); 2991 i++; 2992 } 2993 if (end != NULL) { 2994 (void) memcpy(&enddate, end, sizeof (CK_DATE)); 2995 SETATTR(templ, i, CKA_END_DATE, &enddate, 2996 sizeof (enddate)); 2997 i++; 2998 } 2999 3000 if ((rv = kmf_get_cert_ku(cert, &kuext)) != KMF_OK && 3001 rv != KMF_ERR_EXTENSION_NOT_FOUND) 3002 goto cleanup; 3003 3004 kufound = (rv == KMF_OK); 3005 rv = KMF_OK; /* reset if we got KMF_ERR_EXTENSION_NOT_FOUND */ 3006 } 3007 3008 /* 3009 * Only set the KeyUsage stuff if the KU extension was present. 3010 */ 3011 if (kufound) { 3012 CK_BBOOL condition; 3013 3014 condition = (kuext.KeyUsageBits & KMF_keyEncipherment) ? 3015 B_TRUE : B_FALSE; 3016 SETATTR(templ, i, CKA_UNWRAP, &condition, sizeof (CK_BBOOL)); 3017 i++; 3018 condition = (kuext.KeyUsageBits & KMF_dataEncipherment) ? 3019 B_TRUE : B_FALSE; 3020 SETATTR(templ, i, CKA_DECRYPT, &condition, sizeof (CK_BBOOL)); 3021 i++; 3022 condition = (kuext.KeyUsageBits & KMF_digitalSignature) ? 3023 B_TRUE : B_FALSE; 3024 SETATTR(templ, i, CKA_SIGN, &condition, sizeof (CK_BBOOL)); 3025 i++; 3026 condition = (kuext.KeyUsageBits & KMF_digitalSignature) ? 3027 B_TRUE : B_FALSE; 3028 SETATTR(templ, i, CKA_SIGN_RECOVER, &condition, 3029 sizeof (CK_BBOOL)); 3030 i++; 3031 3032 } 3033 3034 if (keylabel != NULL) { 3035 SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel)); 3036 i++; 3037 } 3038 if (id.Data == NULL && rawkey->id.Data != NULL) { 3039 SETATTR(templ, i, CKA_ID, rawkey->id.Data, 3040 rawkey->id.Length); 3041 i++; 3042 } 3043 if (keytype == CKK_RSA) { 3044 SETATTR(templ, i, CKA_MODULUS, 3045 rawkey->rawdata.rsa.mod.val, 3046 rawkey->rawdata.rsa.mod.len); 3047 i++; 3048 SETATTR(templ, i, CKA_PUBLIC_EXPONENT, 3049 rawkey->rawdata.rsa.pubexp.val, 3050 rawkey->rawdata.rsa.pubexp.len); 3051 i++; 3052 if (rawkey->rawdata.rsa.priexp.val != NULL) { 3053 SETATTR(templ, i, CKA_PRIVATE_EXPONENT, 3054 rawkey->rawdata.rsa.priexp.val, 3055 rawkey->rawdata.rsa.priexp.len); 3056 i++; 3057 } 3058 if (rawkey->rawdata.rsa.prime1.val != NULL) { 3059 SETATTR(templ, i, CKA_PRIME_1, 3060 rawkey->rawdata.rsa.prime1.val, 3061 rawkey->rawdata.rsa.prime1.len); 3062 i++; 3063 } 3064 if (rawkey->rawdata.rsa.prime2.val != NULL) { 3065 SETATTR(templ, i, CKA_PRIME_2, 3066 rawkey->rawdata.rsa.prime2.val, 3067 rawkey->rawdata.rsa.prime2.len); 3068 i++; 3069 } 3070 if (rawkey->rawdata.rsa.exp1.val != NULL) { 3071 SETATTR(templ, i, CKA_EXPONENT_1, 3072 rawkey->rawdata.rsa.exp1.val, 3073 rawkey->rawdata.rsa.exp1.len); 3074 i++; 3075 } 3076 if (rawkey->rawdata.rsa.exp2.val != NULL) { 3077 SETATTR(templ, i, CKA_EXPONENT_2, 3078 rawkey->rawdata.rsa.exp2.val, 3079 rawkey->rawdata.rsa.exp2.len); 3080 i++; 3081 } 3082 if (rawkey->rawdata.rsa.coef.val != NULL) { 3083 SETATTR(templ, i, CKA_COEFFICIENT, 3084 rawkey->rawdata.rsa.coef.val, 3085 rawkey->rawdata.rsa.coef.len); 3086 i++; 3087 } 3088 } else { 3089 SETATTR(templ, i, CKA_PRIME, 3090 rawkey->rawdata.dsa.prime.val, 3091 rawkey->rawdata.dsa.prime.len); 3092 i++; 3093 SETATTR(templ, i, CKA_SUBPRIME, 3094 rawkey->rawdata.dsa.subprime.val, 3095 rawkey->rawdata.dsa.subprime.len); 3096 i++; 3097 SETATTR(templ, i, CKA_BASE, 3098 rawkey->rawdata.dsa.base.val, 3099 rawkey->rawdata.dsa.base.len); 3100 i++; 3101 SETATTR(templ, i, CKA_VALUE, 3102 rawkey->rawdata.dsa.value.val, 3103 rawkey->rawdata.dsa.value.len); 3104 i++; 3105 } 3106 3107 ckrv = C_CreateObject(kmfh->pk11handle, templ, i, &keyobj); 3108 if (ckrv != CKR_OK) { 3109 SET_ERROR(kmfh, ckrv); 3110 3111 /* Report authentication failures to the caller */ 3112 if (ckrv == CKR_USER_NOT_LOGGED_IN || 3113 ckrv == CKR_PIN_INCORRECT || 3114 ckrv == CKR_PIN_INVALID || 3115 ckrv == CKR_PIN_EXPIRED || 3116 ckrv == CKR_PIN_LOCKED || 3117 ckrv == CKR_SESSION_READ_ONLY) 3118 rv = KMF_ERR_AUTH_FAILED; 3119 else 3120 rv = KMF_ERR_INTERNAL; 3121 } 3122 cleanup: 3123 if (start != NULL) 3124 free(start); 3125 if (end != NULL) 3126 free(end); 3127 kmf_free_data(&id); 3128 kmf_free_data(&subject); 3129 kmf_free_signed_cert(x509); 3130 free(x509); 3131 3132 return (rv); 3133 } 3134 3135 KMF_RETURN 3136 KMFPK11_CreateSymKey(KMF_HANDLE_T handle, 3137 int numattr, KMF_ATTRIBUTE *attrlist) 3138 { 3139 KMF_RETURN rv = KMF_OK; 3140 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3141 CK_RV ckrv; 3142 CK_SESSION_HANDLE hSession = kmfh->pk11handle; 3143 CK_OBJECT_HANDLE keyhandle; 3144 CK_MECHANISM keyGenMech; 3145 CK_OBJECT_CLASS class = CKO_SECRET_KEY; 3146 CK_ULONG secKeyType; 3147 CK_ULONG secKeyLen; /* for RC4 and AES */ 3148 CK_BBOOL true = TRUE; 3149 CK_BBOOL false = FALSE; 3150 CK_ATTRIBUTE templ[15]; 3151 CK_BYTE *keydata = NULL; 3152 int i = 0; 3153 KMF_KEY_HANDLE *symkey; 3154 KMF_KEY_ALG keytype; 3155 uint32_t keylen = 0; 3156 uint32_t attrkeylen = 0; 3157 uint32_t keylen_size = sizeof (uint32_t); 3158 char *keylabel = NULL; 3159 KMF_CREDENTIAL cred; 3160 uint32_t is_sensitive = B_FALSE; 3161 uint32_t is_not_extractable = B_FALSE; 3162 3163 if (kmfh == NULL) 3164 return (KMF_ERR_UNINITIALIZED); 3165 3166 if (kmfh->pk11handle == CK_INVALID_HANDLE) 3167 return (KMF_ERR_NO_TOKEN_SELECTED); 3168 3169 symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 3170 if (symkey == NULL) 3171 return (KMF_ERR_BAD_PARAMETER); 3172 3173 rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, 3174 (void *)&keytype, NULL); 3175 if (rv != KMF_OK) 3176 return (KMF_ERR_BAD_PARAMETER); 3177 3178 keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr); 3179 if (keylabel == NULL) 3180 return (KMF_ERR_BAD_PARAMETER); 3181 3182 rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr, 3183 (void *)&is_sensitive, NULL); 3184 if (rv != KMF_OK) 3185 return (KMF_ERR_BAD_PARAMETER); 3186 3187 rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr, 3188 (void *)&is_not_extractable, NULL); 3189 if (rv != KMF_OK) 3190 return (KMF_ERR_BAD_PARAMETER); 3191 3192 /* 3193 * For AES, RC4, DES and 3DES, call C_GenerateKey() to create a key. 3194 * 3195 * For a generic secret key, because it may not be supported in 3196 * C_GenerateKey() for some PKCS11 providers, we will handle it 3197 * differently. 3198 */ 3199 if (keytype == KMF_GENERIC_SECRET) { 3200 rv = create_generic_secret_key(handle, numattr, 3201 attrlist, &keyhandle); 3202 if (rv != KMF_OK) 3203 goto out; 3204 else 3205 goto setup; 3206 } 3207 3208 rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr, 3209 NULL, &attrkeylen); 3210 if (rv == KMF_OK && attrkeylen > 0) { 3211 keydata = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist, 3212 numattr); 3213 } else { 3214 keydata = NULL; 3215 attrkeylen = 0; 3216 rv = KMF_OK; 3217 } 3218 if (keydata != NULL) { 3219 if (keytype == KMF_DES && attrkeylen != 8) { 3220 rv = KMF_ERR_BAD_KEY_SIZE; 3221 goto out; 3222 } 3223 if (keytype == KMF_DES3 && attrkeylen != 24) { 3224 rv = KMF_ERR_BAD_KEY_SIZE; 3225 goto out; 3226 } 3227 /* 3228 * This may override what the user gave on the 3229 * command line. 3230 */ 3231 keylen = attrkeylen * 8; /* bytes to bits */ 3232 } else { 3233 /* 3234 * If keydata was not given, key length must be 3235 * provided. 3236 */ 3237 rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, 3238 &keylen, &keylen_size); 3239 if (rv == KMF_ERR_ATTR_NOT_FOUND && 3240 (keytype == KMF_DES || keytype == KMF_DES3)) 3241 /* keylength is not required for DES and 3DES */ 3242 rv = KMF_OK; 3243 if (rv != KMF_OK) 3244 return (KMF_ERR_BAD_PARAMETER); 3245 } 3246 3247 if ((keylen % 8) != 0) { 3248 return (KMF_ERR_BAD_KEY_SIZE); 3249 } 3250 secKeyLen = keylen / 8; /* in bytes for RC4/AES */ 3251 3252 /* 3253 * Only set CKA_VALUE_LEN if the key data was not given and 3254 * we are creating an RC4 or AES key. 3255 */ 3256 if (keydata == NULL && 3257 (keytype == KMF_AES || keytype == KMF_RC4)) { 3258 SETATTR(templ, i, CKA_VALUE_LEN, &secKeyLen, 3259 sizeof (secKeyLen)); 3260 i++; 3261 } 3262 3263 /* Other keytypes */ 3264 keyGenMech.pParameter = NULL_PTR; 3265 keyGenMech.ulParameterLen = 0; 3266 switch (keytype) { 3267 case KMF_AES: 3268 keyGenMech.mechanism = CKM_AES_KEY_GEN; 3269 secKeyType = CKK_AES; 3270 break; 3271 case KMF_RC4: 3272 keyGenMech.mechanism = CKM_RC4_KEY_GEN; 3273 secKeyType = CKK_RC4; 3274 break; 3275 case KMF_DES: 3276 keyGenMech.mechanism = CKM_DES_KEY_GEN; 3277 secKeyType = CKK_DES; 3278 break; 3279 case KMF_DES3: 3280 keyGenMech.mechanism = CKM_DES3_KEY_GEN; 3281 secKeyType = CKK_DES3; 3282 break; 3283 default: 3284 return (KMF_ERR_BAD_KEY_TYPE); 3285 } 3286 if (keydata != NULL) { 3287 SETATTR(templ, i, CKA_VALUE, keydata, secKeyLen); 3288 i++; 3289 } 3290 SETATTR(templ, i, CKA_CLASS, &class, sizeof (class)); 3291 i++; 3292 SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType)); 3293 i++; 3294 3295 if (keylabel != NULL) { 3296 SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel)); 3297 i++; 3298 } 3299 3300 if (is_sensitive == B_TRUE) { 3301 SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true)); 3302 } else { 3303 SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false)); 3304 } 3305 i++; 3306 3307 if (is_not_extractable == B_TRUE) { 3308 SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false)); 3309 } else { 3310 SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true)); 3311 } 3312 i++; 3313 3314 SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true)); 3315 i++; 3316 SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true)); 3317 i++; 3318 SETATTR(templ, i, CKA_ENCRYPT, &true, sizeof (true)); 3319 i++; 3320 SETATTR(templ, i, CKA_DECRYPT, &true, sizeof (true)); 3321 i++; 3322 SETATTR(templ, i, CKA_SIGN, &true, sizeof (true)); 3323 i++; 3324 SETATTR(templ, i, CKA_VERIFY, &true, sizeof (true)); 3325 i++; 3326 3327 rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, 3328 (void *)&cred, NULL); 3329 if (rv != KMF_OK) 3330 return (KMF_ERR_BAD_PARAMETER); 3331 3332 rv = pk11_authenticate(handle, &cred); 3333 if (rv != KMF_OK) { 3334 return (rv); 3335 } 3336 3337 /* If the key data was given, use C_CreateObject */ 3338 if (keydata != NULL) { 3339 ckrv = C_CreateObject(hSession, templ, i, &keyhandle); 3340 } else { 3341 ckrv = C_GenerateKey(hSession, &keyGenMech, templ, i, 3342 &keyhandle); 3343 } 3344 if (ckrv != CKR_OK) { 3345 SET_ERROR(kmfh, ckrv); 3346 rv = KMF_ERR_KEYGEN_FAILED; 3347 goto out; 3348 } 3349 3350 setup: 3351 symkey->kstype = KMF_KEYSTORE_PK11TOKEN; 3352 symkey->keyalg = keytype; 3353 symkey->keyclass = KMF_SYMMETRIC; 3354 symkey->israw = FALSE; 3355 symkey->keyp = (void *)keyhandle; 3356 3357 out: 3358 return (rv); 3359 } 3360 3361 KMF_RETURN 3362 KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, 3363 KMF_RAW_SYM_KEY *rkey) 3364 { 3365 KMF_RETURN rv = KMF_OK; 3366 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3367 3368 if (kmfh == NULL) 3369 return (KMF_ERR_UNINITIALIZED); 3370 3371 if (kmfh->pk11handle == CK_INVALID_HANDLE) 3372 return (KMF_ERR_NO_TOKEN_SELECTED); 3373 3374 if (symkey == NULL || rkey == NULL) 3375 return (KMF_ERR_BAD_PARAMETER); 3376 else if (symkey->keyclass != KMF_SYMMETRIC) 3377 return (KMF_ERR_BAD_KEY_CLASS); 3378 3379 /* 3380 * If the key is already in "raw" format, copy the data 3381 * to the new record if possible. 3382 */ 3383 if (symkey->israw) { 3384 KMF_RAW_KEY_DATA *rawkey = (KMF_RAW_KEY_DATA *)symkey->keyp; 3385 3386 if (rawkey == NULL) 3387 return (KMF_ERR_BAD_KEYHANDLE); 3388 if (rawkey->sensitive) 3389 return (KMF_ERR_SENSITIVE_KEY); 3390 if (rawkey->not_extractable) 3391 return (KMF_ERR_UNEXTRACTABLE_KEY); 3392 3393 if (rawkey->rawdata.sym.keydata.val == NULL || 3394 rawkey->rawdata.sym.keydata.len == 0) 3395 return (KMF_ERR_GETKEYVALUE_FAILED); 3396 3397 rkey->keydata.len = rawkey->rawdata.sym.keydata.len; 3398 if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL) 3399 return (KMF_ERR_MEMORY); 3400 (void) memcpy(rkey->keydata.val, 3401 rawkey->rawdata.sym.keydata.val, rkey->keydata.len); 3402 } else { 3403 rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)symkey->keyp, rkey); 3404 } 3405 3406 return (rv); 3407 } 3408 3409 KMF_RETURN 3410 KMFPK11_SetTokenPin(KMF_HANDLE_T handle, 3411 int numattr, KMF_ATTRIBUTE *attrlist) 3412 { 3413 KMF_RETURN ret = KMF_OK; 3414 CK_RV rv = CKR_OK; 3415 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3416 CK_SESSION_HANDLE session = NULL; 3417 KMF_CREDENTIAL oldcred = {NULL, 0}; 3418 KMF_CREDENTIAL newcred = {NULL, 0}; 3419 CK_SLOT_ID slotid; 3420 3421 if (handle == NULL || attrlist == NULL || numattr == 0) 3422 return (KMF_ERR_BAD_PARAMETER); 3423 3424 rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, 3425 (void *)&oldcred, NULL); 3426 if (rv != KMF_OK) 3427 return (KMF_ERR_BAD_PARAMETER); 3428 3429 rv = kmf_get_attr(KMF_NEWPIN_ATTR, attrlist, numattr, 3430 (void *)&newcred, NULL); 3431 if (rv != KMF_OK) 3432 return (KMF_ERR_BAD_PARAMETER); 3433 3434 rv = kmf_get_attr(KMF_SLOT_ID_ATTR, attrlist, numattr, 3435 (void *)&slotid, NULL); 3436 if (rv != KMF_OK) { 3437 char *tokenlabel = NULL; 3438 /* 3439 * If a slot wasn't given, the user must pass 3440 * a token label so we can find the slot here. 3441 */ 3442 rv = kmf_get_string_attr(KMF_TOKEN_LABEL_ATTR, attrlist, 3443 numattr, &tokenlabel); 3444 if (rv != KMF_OK) 3445 return (rv); 3446 3447 rv = kmf_pk11_token_lookup(handle, tokenlabel, &slotid); 3448 if (rv != KMF_OK) 3449 return (rv); 3450 } 3451 3452 rv = C_OpenSession(slotid, CKF_SERIAL_SESSION | CKF_RW_SESSION, 3453 NULL, NULL, &session); 3454 if (rv != CKR_OK) { 3455 SET_ERROR(kmfh, rv); 3456 ret = KMF_ERR_UNINITIALIZED; 3457 goto end; 3458 } 3459 3460 rv = C_SetPIN(session, 3461 (CK_BYTE *)oldcred.cred, oldcred.credlen, 3462 (CK_BYTE *)newcred.cred, newcred.credlen); 3463 3464 if (rv != CKR_OK) { 3465 SET_ERROR(kmfh, rv); 3466 if (rv == CKR_PIN_INCORRECT || 3467 rv == CKR_PIN_INVALID || 3468 rv == CKR_PIN_EXPIRED || 3469 rv == CKR_PIN_LOCKED) 3470 ret = KMF_ERR_AUTH_FAILED; 3471 else 3472 ret = KMF_ERR_INTERNAL; 3473 } 3474 end: 3475 if (session != NULL) 3476 (void) C_CloseSession(session); 3477 return (ret); 3478 } 3479 3480 static KMF_RETURN 3481 create_pk11_session(CK_SESSION_HANDLE *sessionp, CK_MECHANISM_TYPE wanted_mech, 3482 CK_FLAGS wanted_flags) 3483 { 3484 CK_RV rv; 3485 KMF_RETURN kmf_rv = KMF_OK; 3486 CK_SLOT_ID_PTR pSlotList; 3487 CK_ULONG pulCount; 3488 CK_MECHANISM_INFO info; 3489 int i; 3490 3491 rv = C_Initialize(NULL); 3492 if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) { 3493 kmf_rv = KMF_ERR_UNINITIALIZED; 3494 goto out; 3495 } 3496 3497 rv = C_GetSlotList(0, NULL, &pulCount); 3498 if (rv != CKR_OK) { 3499 kmf_rv = KMF_ERR_UNINITIALIZED; 3500 goto out; 3501 } 3502 3503 pSlotList = (CK_SLOT_ID_PTR) malloc(pulCount * sizeof (CK_SLOT_ID)); 3504 if (pSlotList == NULL) { 3505 kmf_rv = KMF_ERR_MEMORY; 3506 goto out; 3507 } 3508 3509 rv = C_GetSlotList(0, pSlotList, &pulCount); 3510 if (rv != CKR_OK) { 3511 kmf_rv = KMF_ERR_UNINITIALIZED; 3512 goto out; 3513 } 3514 3515 for (i = 0; i < pulCount; i++) { 3516 rv = C_GetMechanismInfo(pSlotList[i], wanted_mech, &info); 3517 if (rv == CKR_OK && (info.flags & wanted_flags)) 3518 break; 3519 } 3520 if (i < pulCount) { 3521 rv = C_OpenSession(pSlotList[i], CKF_SERIAL_SESSION, 3522 NULL, NULL, sessionp); 3523 3524 if (rv != CKR_OK) { 3525 kmf_rv = KMF_ERR_UNINITIALIZED; 3526 } 3527 } else { 3528 kmf_rv = KMF_ERR_UNINITIALIZED; 3529 } 3530 3531 out: 3532 if (pSlotList != NULL) 3533 free(pSlotList); 3534 return (kmf_rv); 3535 3536 } 3537 static KMF_RETURN 3538 verify_data(KMF_HANDLE_T handle, 3539 KMF_ALGORITHM_INDEX AlgorithmId, 3540 KMF_X509_SPKI *keyp, 3541 KMF_DATA *data, 3542 KMF_DATA *signed_data) 3543 { 3544 KMF_RETURN ret; 3545 PKCS_ALGORITHM_MAP *pAlgMap = NULL; 3546 CK_RV ckRv; 3547 CK_MECHANISM ckMechanism; 3548 CK_OBJECT_HANDLE ckKeyHandle; 3549 KMF_BOOL bTempKey; 3550 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3551 CK_SESSION_HANDLE ckSession = NULL; 3552 3553 if (AlgorithmId == KMF_ALGID_NONE) 3554 return (KMF_ERR_BAD_ALGORITHM); 3555 3556 pAlgMap = pkcs_get_alg_map(KMF_ALGCLASS_SIGNATURE, 3557 AlgorithmId, PKCS_GetDefaultSignatureMode(AlgorithmId)); 3558 3559 if (!pAlgMap) 3560 return (KMF_ERR_BAD_ALGORITHM); 3561 3562 ret = create_pk11_session(&ckSession, pAlgMap->pkcs_mechanism, 3563 CKF_VERIFY); 3564 if (ret != KMF_OK) 3565 return (ret); 3566 3567 /* Fetch the verifying key */ 3568 ret = PKCS_AcquirePublicKeyHandle(ckSession, keyp, 3569 pAlgMap->key_type, &ckKeyHandle, &bTempKey); 3570 3571 if (ret != KMF_OK) { 3572 return (ret); 3573 } 3574 3575 ckMechanism.mechanism = pAlgMap->pkcs_mechanism; 3576 ckMechanism.pParameter = NULL; 3577 ckMechanism.ulParameterLen = 0; 3578 3579 ckRv = C_VerifyInit(ckSession, &ckMechanism, ckKeyHandle); 3580 if (ckRv != CKR_OK) { 3581 if (bTempKey) 3582 (void) C_DestroyObject(ckSession, ckKeyHandle); 3583 SET_ERROR(kmfh, ckRv); 3584 ret = KMF_ERR_INTERNAL; 3585 goto cleanup; 3586 } 3587 3588 ckRv = C_Verify(ckSession, (CK_BYTE *)data->Data, 3589 (CK_ULONG)data->Length, (CK_BYTE *)signed_data->Data, 3590 (CK_ULONG)signed_data->Length); 3591 3592 if (ckRv != CKR_OK) { 3593 SET_ERROR(kmfh, ckRv); 3594 ret = KMF_ERR_INTERNAL; 3595 } 3596 3597 cleanup: 3598 if (bTempKey) 3599 (void) C_DestroyObject(ckSession, ckKeyHandle); 3600 3601 (void) C_CloseSession(ckSession); 3602 3603 return (ret); 3604 } 3605 3606 KMF_RETURN 3607 KMFPK11_VerifyDataWithCert(KMF_HANDLE_T handle, 3608 KMF_ALGORITHM_INDEX algid, KMF_DATA *indata, 3609 KMF_DATA *insig, KMF_DATA *SignerCertData) 3610 { 3611 KMF_RETURN ret = KMF_OK; 3612 KMF_X509_CERTIFICATE *SignerCert = NULL; 3613 KMF_X509_SPKI *pubkey; 3614 3615 if (handle == NULL || indata == NULL || 3616 indata->Data == NULL || indata->Length == 0 || 3617 insig == NULL|| insig->Data == NULL || insig->Length == 0 || 3618 SignerCertData == NULL || SignerCertData->Data == NULL || 3619 SignerCertData->Length == 0) 3620 return (KMF_ERR_BAD_PARAMETER); 3621 3622 /* Decode the signer cert so we can get the SPKI data */ 3623 ret = DerDecodeSignedCertificate(SignerCertData, &SignerCert); 3624 if (ret != KMF_OK) 3625 goto cleanup; 3626 3627 /* Get the public key info from the signer certificate */ 3628 pubkey = &SignerCert->certificate.subjectPublicKeyInfo; 3629 3630 /* If no algorithm specified, use the certs signature algorithm */ 3631 if (algid == KMF_ALGID_NONE) { 3632 algid = x509_algoid_to_algid(CERT_ALG_OID(SignerCert)); 3633 } 3634 3635 if (algid == KMF_ALGID_NONE) { 3636 ret = KMF_ERR_BAD_ALGORITHM; 3637 } else { 3638 ret = verify_data(handle, algid, pubkey, indata, insig); 3639 } 3640 3641 cleanup: 3642 if (SignerCert) { 3643 kmf_free_signed_cert(SignerCert); 3644 free(SignerCert); 3645 } 3646 3647 return (ret); 3648 } 3649 3650 static KMF_RETURN 3651 create_generic_secret_key(KMF_HANDLE_T handle, 3652 int numattr, KMF_ATTRIBUTE *attrlist, CK_OBJECT_HANDLE *key) 3653 { 3654 KMF_RETURN rv = KMF_OK; 3655 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3656 CK_RV ckrv; 3657 CK_SESSION_HANDLE hSession = kmfh->pk11handle; 3658 CK_OBJECT_CLASS class = CKO_SECRET_KEY; 3659 CK_ULONG secKeyType = CKK_GENERIC_SECRET; 3660 CK_ULONG secKeyLen; 3661 CK_BBOOL true = TRUE; 3662 CK_BBOOL false = FALSE; 3663 CK_ATTRIBUTE templ[15]; 3664 int i; 3665 int random_fd = -1; 3666 int nread; 3667 int freebuf = 0; 3668 char *buf = NULL; 3669 uint32_t keylen = 0, attrkeylen = 0; 3670 char *keylabel = NULL; 3671 KMF_CREDENTIAL *cred; 3672 uint32_t is_sensitive, is_not_extractable; 3673 3674 keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr); 3675 if (keylabel == NULL) 3676 return (KMF_ERR_BAD_PARAMETER); 3677 3678 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr); 3679 if (cred == NULL) 3680 return (KMF_ERR_BAD_PARAMETER); 3681 3682 rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr, 3683 (void *)&is_sensitive, NULL); 3684 if (rv != KMF_OK) 3685 return (KMF_ERR_BAD_PARAMETER); 3686 3687 rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr, 3688 (void *)&is_not_extractable, NULL); 3689 if (rv != KMF_OK) 3690 return (KMF_ERR_BAD_PARAMETER); 3691 3692 rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr, 3693 NULL, &attrkeylen); 3694 if (rv == KMF_OK && attrkeylen > 0) { 3695 buf = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist, 3696 numattr); 3697 secKeyLen = attrkeylen; 3698 } else { 3699 buf = NULL; 3700 rv = KMF_OK; 3701 } 3702 if (buf == NULL) { 3703 /* 3704 * If the key data was not given, key length must 3705 * be provided. 3706 */ 3707 rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, 3708 &keylen, NULL); 3709 if (rv != KMF_OK) 3710 return (KMF_ERR_BAD_PARAMETER); 3711 3712 /* 3713 * Check the key size. 3714 */ 3715 if ((keylen % 8) != 0) { 3716 return (KMF_ERR_BAD_KEY_SIZE); 3717 } else { 3718 secKeyLen = keylen/8; /* in bytes */ 3719 } 3720 3721 /* 3722 * Generate a random number with the key size first. 3723 */ 3724 buf = malloc(secKeyLen); 3725 if (buf == NULL) 3726 return (KMF_ERR_MEMORY); 3727 3728 freebuf = 1; 3729 while ((random_fd = open(DEV_RANDOM, O_RDONLY)) < 0) { 3730 if (errno != EINTR) 3731 break; 3732 } 3733 3734 if (random_fd < 0) { 3735 rv = KMF_ERR_KEYGEN_FAILED; 3736 goto out; 3737 } 3738 3739 nread = read(random_fd, buf, secKeyLen); 3740 if (nread <= 0 || nread != secKeyLen) { 3741 rv = KMF_ERR_KEYGEN_FAILED; 3742 goto out; 3743 } 3744 } 3745 3746 /* 3747 * Authenticate into the token and call C_CreateObject to generate 3748 * a generic secret token key. 3749 */ 3750 rv = pk11_authenticate(handle, cred); 3751 if (rv != KMF_OK) { 3752 goto out; 3753 } 3754 3755 i = 0; 3756 SETATTR(templ, i, CKA_CLASS, &class, sizeof (class)); 3757 i++; 3758 SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType)); 3759 i++; 3760 SETATTR(templ, i, CKA_VALUE, buf, secKeyLen); 3761 i++; 3762 3763 if (keylabel != NULL) { 3764 SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel)); 3765 i++; 3766 } 3767 3768 if (is_sensitive == B_TRUE) { 3769 SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true)); 3770 } else { 3771 SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false)); 3772 } 3773 i++; 3774 3775 if (is_not_extractable == B_TRUE) { 3776 SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false)); 3777 } else { 3778 SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true)); 3779 } 3780 i++; 3781 3782 SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true)); 3783 i++; 3784 SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true)); 3785 i++; 3786 SETATTR(templ, i, CKA_SIGN, &true, sizeof (true)); 3787 i++; 3788 3789 ckrv = C_CreateObject(hSession, templ, i, key); 3790 if (ckrv != CKR_OK) { 3791 SET_ERROR(kmfh, ckrv); 3792 rv = KMF_ERR_KEYGEN_FAILED; 3793 } 3794 3795 out: 3796 if (buf != NULL && freebuf) 3797 free(buf); 3798 3799 if (random_fd != -1) 3800 (void) close(random_fd); 3801 3802 return (rv); 3803 } 3804 3805 KMF_RETURN 3806 KMFPK11_StoreKey(KMF_HANDLE_T handle, 3807 int numattr, 3808 KMF_ATTRIBUTE *attlist) 3809 { 3810 KMF_RETURN rv = KMF_OK; 3811 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3812 KMF_CREDENTIAL cred = {NULL, 0}; 3813 KMF_KEY_HANDLE *key; 3814 KMF_RAW_KEY_DATA *rawkey = NULL; 3815 CK_BBOOL btrue = TRUE; 3816 CK_ATTRIBUTE tokenattr[1]; 3817 CK_OBJECT_HANDLE newobj; 3818 CK_RV ckrv; 3819 3820 if (kmfh == NULL) 3821 return (KMF_ERR_UNINITIALIZED); 3822 3823 if (kmfh->pk11handle == CK_INVALID_HANDLE) 3824 return (KMF_ERR_NO_TOKEN_SELECTED); 3825 3826 rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attlist, numattr, 3827 (void *)&cred, NULL); 3828 if (rv != KMF_OK) 3829 return (KMF_ERR_BAD_PARAMETER); 3830 3831 rv = pk11_authenticate(handle, &cred); 3832 if (rv != KMF_OK) 3833 return (rv); 3834 3835 key = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr); 3836 if (key == NULL) { 3837 key = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist, 3838 numattr); 3839 if (key == NULL) 3840 rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attlist, 3841 numattr); 3842 } 3843 if (key == NULL && rawkey == NULL) 3844 return (KMF_ERR_ATTR_NOT_FOUND); 3845 3846 if (rawkey != NULL) { 3847 rv = store_raw_key(handle, attlist, numattr, rawkey); 3848 } else if (key && key->kstype == KMF_KEYSTORE_PK11TOKEN) { 3849 3850 SETATTR(tokenattr, 0, CKA_TOKEN, &btrue, sizeof (btrue)); 3851 /* Copy the key object to the token */ 3852 ckrv = C_CopyObject(kmfh->pk11handle, 3853 (CK_OBJECT_HANDLE)key->keyp, tokenattr, 1, &newobj); 3854 if (ckrv != CKR_OK) { 3855 SET_ERROR(kmfh, ckrv); 3856 return (KMF_ERR_INTERNAL); 3857 } 3858 3859 /* Replace the object handle with the new token-based one */ 3860 ckrv = C_DestroyObject(kmfh->pk11handle, 3861 (CK_OBJECT_HANDLE)key->keyp); 3862 if (ckrv != CKR_OK) { 3863 SET_ERROR(kmfh, ckrv); 3864 return (KMF_ERR_INTERNAL); 3865 } 3866 key->keyp = (void *)newobj; 3867 } else { 3868 rv = KMF_ERR_BAD_PARAMETER; 3869 } 3870 3871 return (rv); 3872 } 3873 3874 3875 KMF_RETURN 3876 KMFPK11_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 3877 { 3878 KMF_RETURN rv = KMF_OK; 3879 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3880 KMF_CREDENTIAL *cred = NULL; 3881 KMF_CREDENTIAL *p12cred = NULL; 3882 char *filename = NULL; 3883 KMF_X509_DER_CERT *certlist = NULL; 3884 KMF_KEY_HANDLE *keylist = NULL; 3885 uint32_t numcerts; 3886 uint32_t numkeys; 3887 char *certlabel = NULL; 3888 char *issuer = NULL; 3889 char *subject = NULL; 3890 KMF_BIGINT *serial = NULL; 3891 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 3892 KMF_ATTRIBUTE fc_attrlist[16]; 3893 int i; 3894 3895 if (kmfh == NULL) 3896 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 3897 3898 if (kmfh->pk11handle == CK_INVALID_HANDLE) 3899 return (KMF_ERR_NO_TOKEN_SELECTED); 3900 3901 /* First get the required attributes */ 3902 cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr); 3903 if (cred == NULL) 3904 return (KMF_ERR_BAD_PARAMETER); 3905 3906 p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr); 3907 if (p12cred == NULL) 3908 return (KMF_ERR_BAD_PARAMETER); 3909 3910 filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist, 3911 numattr); 3912 if (filename == NULL) 3913 return (KMF_ERR_BAD_PARAMETER); 3914 3915 /* Find all the certificates that match the searching criteria */ 3916 i = 0; 3917 kmf_set_attr_at_index(fc_attrlist, i, 3918 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 3919 i++; 3920 3921 kmf_set_attr_at_index(fc_attrlist, i, 3922 KMF_COUNT_ATTR, &numcerts, sizeof (uint32_t)); 3923 i++; 3924 3925 certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr); 3926 if (certlabel != NULL) { 3927 kmf_set_attr_at_index(fc_attrlist, i, 3928 KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel)); 3929 i++; 3930 } 3931 3932 issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); 3933 if (issuer != NULL) { 3934 kmf_set_attr_at_index(fc_attrlist, i, 3935 KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer)); 3936 i++; 3937 } 3938 3939 subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); 3940 if (subject != NULL) { 3941 kmf_set_attr_at_index(fc_attrlist, i, 3942 KMF_SUBJECT_NAME_ATTR, subject, strlen(subject)); 3943 i++; 3944 } 3945 3946 serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); 3947 if (serial != NULL) { 3948 kmf_set_attr_at_index(fc_attrlist, i, 3949 KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT)); 3950 i++; 3951 } 3952 3953 rv = KMFPK11_FindCert(handle, i, fc_attrlist); 3954 3955 if (rv == KMF_OK && numcerts > 0) { 3956 certlist = (KMF_X509_DER_CERT *)malloc(numcerts * 3957 sizeof (KMF_X509_DER_CERT)); 3958 if (certlist == NULL) 3959 return (KMF_ERR_MEMORY); 3960 3961 (void) memset(certlist, 0, numcerts * 3962 sizeof (KMF_X509_DER_CERT)); 3963 3964 kmf_set_attr_at_index(fc_attrlist, i, KMF_X509_DER_CERT_ATTR, 3965 certlist, sizeof (KMF_X509_DER_CERT)); 3966 i++; 3967 3968 rv = kmf_find_cert(handle, i, fc_attrlist); 3969 if (rv != KMF_OK) { 3970 free(certlist); 3971 return (rv); 3972 } 3973 } else { 3974 return (rv); 3975 } 3976 3977 /* For each certificate, find the matching private key */ 3978 numkeys = 0; 3979 for (i = 0; i < numcerts; i++) { 3980 KMF_ATTRIBUTE fk_attrlist[16]; 3981 int j = 0; 3982 KMF_KEY_HANDLE newkey; 3983 KMF_ENCODE_FORMAT format = KMF_FORMAT_RAWKEY; 3984 3985 kmf_set_attr_at_index(fk_attrlist, j, 3986 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 3987 j++; 3988 3989 kmf_set_attr_at_index(fk_attrlist, j, 3990 KMF_ENCODE_FORMAT_ATTR, &format, sizeof (format)); 3991 j++; 3992 3993 kmf_set_attr_at_index(fk_attrlist, j, 3994 KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL)); 3995 j++; 3996 3997 kmf_set_attr_at_index(fk_attrlist, j, 3998 KMF_CERT_DATA_ATTR, &certlist[i].certificate, 3999 sizeof (KMF_DATA)); 4000 j++; 4001 4002 kmf_set_attr_at_index(fk_attrlist, j, 4003 KMF_KEY_HANDLE_ATTR, &newkey, sizeof (KMF_KEY_HANDLE)); 4004 j++; 4005 4006 rv = KMFPK11_FindPrikeyByCert(handle, j, fk_attrlist); 4007 if (rv == KMF_OK) { 4008 numkeys++; 4009 keylist = realloc(keylist, 4010 numkeys * sizeof (KMF_KEY_HANDLE)); 4011 if (keylist == NULL) { 4012 rv = KMF_ERR_MEMORY; 4013 goto out; 4014 } 4015 keylist[numkeys - 1] = newkey; 4016 } else if (rv == KMF_ERR_KEY_NOT_FOUND) { 4017 /* it is OK if a key is not found */ 4018 rv = KMF_OK; 4019 } 4020 } 4021 4022 if (rv != KMF_OK) 4023 goto out; 4024 4025 rv = kmf_build_pk12(handle, numcerts, certlist, numkeys, keylist, 4026 p12cred, filename); 4027 4028 out: 4029 if (certlist != NULL) { 4030 for (i = 0; i < numcerts; i++) 4031 kmf_free_kmf_cert(handle, &certlist[i]); 4032 free(certlist); 4033 } 4034 if (keylist != NULL) { 4035 for (i = 0; i < numkeys; i++) 4036 kmf_free_kmf_key(handle, &keylist[i]); 4037 free(keylist); 4038 } 4039 4040 return (rv); 4041 } 4042