1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * PKCS11 token KMF Plugin 23 * 24 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 #pragma ident "%Z%%M% %I% %E% SMI" 29 30 #include <stdio.h> /* debugging only */ 31 #include <errno.h> 32 #include <values.h> 33 34 #include <kmfapiP.h> 35 #include <ber_der.h> 36 #include <algorithm.h> 37 #include <fcntl.h> 38 #include <sha1.h> 39 40 #include <cryptoutil.h> 41 #include <security/cryptoki.h> 42 #include <security/pkcs11.h> 43 44 #define DEV_RANDOM "/dev/random" 45 46 #define SETATTR(t, n, atype, value, size) \ 47 t[n].type = atype; \ 48 t[n].pValue = (CK_BYTE *)value; \ 49 t[n].ulValueLen = (CK_ULONG)size; 50 51 #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; \ 52 h->lasterr.errcode = c; 53 54 typedef struct _objlist { 55 CK_OBJECT_HANDLE handle; 56 struct _objlist *next; 57 } OBJLIST; 58 59 static KMF_RETURN 60 search_certs(KMF_HANDLE_T, char *, char *, char *, KMF_BIGINT *, 61 boolean_t, KMF_CERT_VALIDITY, OBJLIST **, uint32_t *); 62 63 static CK_RV 64 getObjectLabel(KMF_HANDLE_T, CK_OBJECT_HANDLE, char **); 65 66 static KMF_RETURN 67 keyObj2RawKey(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_KEY_DATA **); 68 69 static KMF_RETURN 70 create_generic_secret_key(KMF_HANDLE_T, KMF_CREATESYMKEY_PARAMS *, 71 CK_OBJECT_HANDLE *); 72 73 KMF_RETURN 74 KMFPK11_ConfigureKeystore(KMF_HANDLE_T, KMF_CONFIG_PARAMS *); 75 76 KMF_RETURN 77 KMFPK11_FindCert(KMF_HANDLE_T, 78 KMF_FINDCERT_PARAMS *, 79 KMF_X509_DER_CERT *, 80 uint32_t *); 81 82 void 83 KMFPK11_FreeKMFCert(KMF_HANDLE_T, 84 KMF_X509_DER_CERT *kmf_cert); 85 86 KMF_RETURN 87 KMFPK11_StoreCert(KMF_HANDLE_T, KMF_STORECERT_PARAMS *, KMF_DATA *); 88 89 KMF_RETURN 90 KMFPK11_ImportCert(KMF_HANDLE_T, KMF_IMPORTCERT_PARAMS *); 91 92 KMF_RETURN 93 KMFPK11_DeleteCert(KMF_HANDLE_T, KMF_DELETECERT_PARAMS *); 94 95 KMF_RETURN 96 KMFPK11_CreateKeypair(KMF_HANDLE_T, KMF_CREATEKEYPAIR_PARAMS *, 97 KMF_KEY_HANDLE *, KMF_KEY_HANDLE *); 98 99 KMF_RETURN 100 KMFPK11_DeleteKey(KMF_HANDLE_T, KMF_DELETEKEY_PARAMS *, 101 KMF_KEY_HANDLE *, boolean_t); 102 103 KMF_RETURN 104 KMFPK11_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *); 105 106 KMF_RETURN 107 KMFPK11_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 108 KMF_DATA *, KMF_DATA *); 109 110 KMF_RETURN 111 KMFPK11_GetErrorString(KMF_HANDLE_T, char **); 112 113 KMF_RETURN 114 KMFPK11_GetPrikeyByCert(KMF_HANDLE_T, KMF_CRYPTOWITHCERT_PARAMS *, KMF_DATA *, 115 KMF_KEY_HANDLE *, KMF_KEY_ALG); 116 117 KMF_RETURN 118 KMFPK11_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 119 KMF_DATA *, KMF_DATA *); 120 121 KMF_RETURN 122 KMFPK11_FindKey(KMF_HANDLE_T, KMF_FINDKEY_PARAMS *, 123 KMF_KEY_HANDLE *, uint32_t *); 124 125 KMF_RETURN 126 KMFPK11_StorePrivateKey(KMF_HANDLE_T, KMF_STOREKEY_PARAMS *, 127 KMF_RAW_KEY_DATA *); 128 129 KMF_RETURN 130 KMFPK11_CreateSymKey(KMF_HANDLE_T, KMF_CREATESYMKEY_PARAMS *, 131 KMF_KEY_HANDLE *); 132 133 KMF_RETURN 134 KMFPK11_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *); 135 136 KMF_RETURN 137 KMFPK11_SetTokenPin(KMF_HANDLE_T, KMF_SETPIN_PARAMS *, KMF_CREDENTIAL *); 138 139 KMF_RETURN 140 KMFPK11_VerifyDataWithCert(KMF_HANDLE_T, KMF_ALGORITHM_INDEX, KMF_DATA *, 141 KMF_DATA *, KMF_DATA *); 142 143 static 144 KMF_PLUGIN_FUNCLIST pk11token_plugin_table = 145 { 146 1, /* Version */ 147 KMFPK11_ConfigureKeystore, 148 KMFPK11_FindCert, 149 KMFPK11_FreeKMFCert, 150 KMFPK11_StoreCert, 151 KMFPK11_ImportCert, 152 NULL, /* ImportCRL */ 153 KMFPK11_DeleteCert, 154 NULL, /* DeleteCRL */ 155 KMFPK11_CreateKeypair, 156 KMFPK11_FindKey, 157 KMFPK11_EncodePubKeyData, 158 KMFPK11_SignData, 159 KMFPK11_DeleteKey, 160 NULL, /* ListCRL */ 161 NULL, /* FindCRL */ 162 NULL, /* FindCertInCRL */ 163 KMFPK11_GetErrorString, 164 KMFPK11_GetPrikeyByCert, 165 KMFPK11_DecryptData, 166 NULL, /* ExportP12 */ 167 KMFPK11_StorePrivateKey, 168 KMFPK11_CreateSymKey, 169 KMFPK11_GetSymKeyValue, 170 KMFPK11_SetTokenPin, 171 KMFPK11_VerifyDataWithCert, 172 NULL /* Finalize */ 173 }; 174 175 KMF_PLUGIN_FUNCLIST * 176 KMF_Plugin_Initialize() 177 { 178 return (&pk11token_plugin_table); 179 } 180 181 KMF_RETURN 182 KMFPK11_ConfigureKeystore(KMF_HANDLE_T handle, KMF_CONFIG_PARAMS *params) 183 { 184 KMF_RETURN rv = KMF_OK; 185 186 if (params == NULL || params->pkcs11config.label == NULL) 187 return (KMF_ERR_BAD_PARAMETER); 188 189 rv = KMF_SelectToken(handle, params->pkcs11config.label, 190 params->pkcs11config.readonly); 191 192 return (rv); 193 } 194 195 static KMF_RETURN 196 pk11_authenticate(KMF_HANDLE_T handle, 197 KMF_CREDENTIAL *cred) 198 { 199 200 CK_RV ck_rv = CKR_OK; 201 CK_SESSION_HANDLE hSession = (CK_SESSION_HANDLE)handle->pk11handle; 202 203 if (hSession == NULL) 204 return (KMF_ERR_NO_TOKEN_SELECTED); 205 206 if (cred == NULL || cred->cred == NULL || cred->credlen == 0) { 207 return (KMF_ERR_BAD_PARAMETER); 208 } 209 210 if ((ck_rv = C_Login(hSession, CKU_USER, 211 (uchar_t *)cred->cred, cred->credlen)) != CKR_OK) { 212 if (ck_rv != CKR_USER_ALREADY_LOGGED_IN) { 213 handle->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; 214 handle->lasterr.errcode = ck_rv; 215 return (KMF_ERR_AUTH_FAILED); 216 } 217 } 218 219 return (KMF_OK); 220 } 221 222 static KMF_RETURN 223 PK11Cert2KMFCert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE hObj, 224 KMF_X509_DER_CERT *kmfcert) 225 { 226 KMF_RETURN rv = 0; 227 CK_RV ckrv = CKR_OK; 228 229 CK_CERTIFICATE_TYPE cktype; 230 CK_OBJECT_CLASS class; 231 CK_ULONG subject_len, value_len, issuer_len, serno_len, id_len; 232 CK_BYTE *subject = NULL, *value = NULL; 233 char *label = NULL; 234 CK_ATTRIBUTE templ[10]; 235 236 (void) memset(templ, 0, 10 * sizeof (CK_ATTRIBUTE)); 237 SETATTR(templ, 0, CKA_CLASS, &class, sizeof (class)); 238 239 /* Is this a certificate object ? */ 240 ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, 1); 241 if (ckrv != CKR_OK || class != CKO_CERTIFICATE) { 242 SET_ERROR(kmfh, ckrv); 243 return (KMF_ERR_INTERNAL); 244 } 245 246 SETATTR(templ, 0, CKA_CERTIFICATE_TYPE, &cktype, sizeof (cktype)); 247 ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, 1); 248 249 if (ckrv != CKR_OK || cktype != CKC_X_509) { 250 SET_ERROR(kmfh, ckrv); 251 return (ckrv); 252 } else { 253 int i = 0; 254 /* What attributes are available and how big are they? */ 255 subject_len = issuer_len = serno_len = id_len = value_len = 0; 256 257 SETATTR(templ, i, CKA_SUBJECT, NULL, subject_len); 258 i++; 259 SETATTR(templ, i, CKA_ISSUER, NULL, issuer_len); 260 i++; 261 SETATTR(templ, i, CKA_SERIAL_NUMBER, NULL, serno_len); 262 i++; 263 SETATTR(templ, i, CKA_ID, NULL, id_len); 264 i++; 265 SETATTR(templ, i, CKA_VALUE, NULL, value_len); 266 i++; 267 268 /* 269 * Query the object with NULL values in the pValue spot 270 * so we know how much space to allocate for each field. 271 */ 272 ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, i); 273 if (ckrv != CKR_OK) { 274 SET_ERROR(kmfh, ckrv); 275 return (KMF_ERR_INTERNAL); /* TODO - Error messages ? */ 276 } 277 278 subject_len = templ[0].ulValueLen; 279 issuer_len = templ[1].ulValueLen; 280 serno_len = templ[2].ulValueLen; 281 id_len = templ[3].ulValueLen; 282 value_len = templ[4].ulValueLen; 283 284 /* 285 * For PKCS#11 CKC_X_509 certificate objects, 286 * the following attributes must be defined. 287 * CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER, 288 * CKA_VALUE. 289 */ 290 if (subject_len == 0 || issuer_len == 0 || 291 serno_len == 0 || value_len == 0) { 292 return (KMF_ERR_INTERNAL); 293 } 294 295 /* Only fetch the value field if we are saving the data */ 296 if (kmfcert != NULL) { 297 int i = 0; 298 value = malloc(value_len); 299 if (value == NULL) { 300 rv = KMF_ERR_MEMORY; 301 goto errout; 302 } 303 304 SETATTR(templ, i, CKA_VALUE, value, value_len); 305 i++; 306 307 /* re-query the object with room for the value attr */ 308 ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, 309 templ, i); 310 311 if (ckrv != CKR_OK) { 312 SET_ERROR(kmfh, ckrv); 313 rv = KMF_ERR_INTERNAL; 314 goto errout; 315 } 316 317 kmfcert->certificate.Data = value; 318 kmfcert->certificate.Length = value_len; 319 kmfcert->kmf_private.flags |= KMF_FLAG_CERT_SIGNED; 320 kmfcert->kmf_private.keystore_type = 321 KMF_KEYSTORE_PK11TOKEN; 322 323 ckrv = getObjectLabel(kmfh, hObj, &label); 324 if (ckrv == CKR_OK && label != NULL) { 325 kmfcert->kmf_private.label = (char *)label; 326 } 327 328 rv = KMF_OK; 329 } 330 } 331 332 errout: 333 if (rv != KMF_OK) { 334 if (subject) 335 free(subject); 336 if (value) 337 free(value); 338 339 if (kmfcert) { 340 kmfcert->certificate.Data = NULL; 341 kmfcert->certificate.Length = 0; 342 } 343 } 344 return (rv); 345 } 346 347 static void 348 free_objlist(OBJLIST *head) 349 { 350 OBJLIST *temp = head; 351 352 while (temp != NULL) { 353 head = head->next; 354 free(temp); 355 temp = head; 356 } 357 } 358 359 /* 360 * The caller should make sure that the templ->pValue is NULL since 361 * it will be overwritten below. 362 */ 363 static KMF_RETURN 364 get_attr(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, 365 CK_ATTRIBUTE *templ) 366 { 367 CK_RV rv; 368 369 rv = C_GetAttributeValue(kmfh->pk11handle, obj, templ, 1); 370 if (rv != CKR_OK) { 371 SET_ERROR(kmfh, rv); 372 return (KMF_ERR_INTERNAL); 373 } 374 375 if (templ->ulValueLen > 0) { 376 templ->pValue = malloc(templ->ulValueLen); 377 if (templ->pValue == NULL) 378 return (KMF_ERR_MEMORY); 379 380 rv = C_GetAttributeValue(kmfh->pk11handle, obj, templ, 1); 381 if (rv != CKR_OK) { 382 SET_ERROR(kmfh, rv); 383 return (KMF_ERR_INTERNAL); 384 } 385 } 386 387 return (KMF_OK); 388 } 389 390 /* 391 * Match a certificate with an issuer and/or subject name. 392 * This is tricky because we cannot reliably compare DER encodings 393 * because RDNs may have their AV-pairs in different orders even 394 * if the values are the same. You must compare individual 395 * AV pairs for the RDNs. 396 * 397 * RETURN: 0 for a match, non-zero for a non-match. 398 */ 399 static KMF_RETURN 400 matchcert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, 401 KMF_X509_NAME *issuer, KMF_X509_NAME *subject) 402 { 403 KMF_RETURN rv = KMF_OK; 404 CK_ATTRIBUTE certattr; 405 KMF_DATA name; 406 KMF_X509_NAME dn; 407 408 if (issuer->numberOfRDNs > 0) { 409 certattr.type = CKA_ISSUER; 410 certattr.pValue = NULL; 411 certattr.ulValueLen = 0; 412 413 rv = get_attr(kmfh, obj, &certattr); 414 415 if (rv == KMF_OK) { 416 name.Data = certattr.pValue; 417 name.Length = certattr.ulValueLen; 418 rv = DerDecodeName(&name, &dn); 419 if (rv == KMF_OK) { 420 rv = KMF_CompareRDNs(issuer, &dn); 421 KMF_FreeDN(&dn); 422 } 423 free(certattr.pValue); 424 } 425 426 if (rv != KMF_OK) 427 return (rv); 428 } 429 if (subject->numberOfRDNs > 0) { 430 certattr.type = CKA_SUBJECT; 431 certattr.pValue = NULL; 432 certattr.ulValueLen = 0; 433 434 rv = get_attr(kmfh, obj, &certattr); 435 436 if (rv == KMF_OK) { 437 name.Data = certattr.pValue; 438 name.Length = certattr.ulValueLen; 439 rv = DerDecodeName(&name, &dn); 440 if (rv == KMF_OK) { 441 rv = KMF_CompareRDNs(subject, &dn); 442 KMF_FreeDN(&dn); 443 } 444 free(certattr.pValue); 445 } 446 } 447 448 return (rv); 449 } 450 451 /* 452 * delete "curr" node from the "newlist". 453 */ 454 static void 455 pk11_delete_obj_from_list(OBJLIST **newlist, 456 OBJLIST **prev, OBJLIST **curr) 457 { 458 459 if (*curr == *newlist) { 460 /* first node in the list */ 461 *newlist = (*curr)->next; 462 *prev = (*curr)->next; 463 free(*curr); 464 *curr = *newlist; 465 } else { 466 (*prev)->next = (*curr)->next; 467 free(*curr); 468 *curr = (*prev)->next; 469 } 470 } 471 472 /* 473 * prepare_object_search 474 * 475 * Because this code is shared by the FindCert and 476 * DeleteCert functions, put it in a separate routine 477 * to save some work and make code easier to debug and 478 * read. 479 */ 480 static KMF_RETURN 481 search_certs(KMF_HANDLE_T handle, 482 char *label, char *issuer, char *subject, KMF_BIGINT *serial, 483 boolean_t private, KMF_CERT_VALIDITY validity, 484 OBJLIST **objlist, uint32_t *numobj) 485 { 486 KMF_RETURN rv = KMF_OK; 487 CK_RV ckrv = CKR_OK; 488 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 489 CK_ATTRIBUTE templ[10]; 490 CK_BBOOL true = TRUE; 491 CK_OBJECT_CLASS oclass = CKO_CERTIFICATE; 492 CK_CERTIFICATE_TYPE ctype = CKC_X_509; 493 KMF_X509_NAME subjectDN, issuerDN; 494 int i; 495 OBJLIST *newlist, *tail; 496 CK_ULONG num = 0; 497 uint32_t num_ok_certs = 0; /* number of non-expired or expired certs */ 498 499 (void) memset(&templ, 0, 10 * sizeof (CK_ATTRIBUTE)); 500 (void) memset(&issuerDN, 0, sizeof (KMF_X509_NAME)); 501 (void) memset(&subjectDN, 0, sizeof (KMF_X509_NAME)); 502 i = 0; 503 SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true)); i++; 504 SETATTR(templ, i, CKA_CLASS, &oclass, sizeof (oclass)); i++; 505 SETATTR(templ, i, CKA_CERTIFICATE_TYPE, &ctype, 506 sizeof (ctype)); i++; 507 508 if (label != NULL && strlen(label)) { 509 SETATTR(templ, i, CKA_LABEL, label, strlen(label)); 510 i++; 511 } 512 if (private) { 513 SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true)); i++; 514 } 515 516 if (issuer != NULL && strlen(issuer)) { 517 if ((rv = KMF_DNParser(issuer, &issuerDN)) != KMF_OK) 518 return (rv); 519 } 520 if (subject != NULL && strlen(subject)) { 521 if ((rv = KMF_DNParser(subject, &subjectDN)) != KMF_OK) 522 return (rv); 523 } 524 525 if (serial != NULL && serial->val != NULL && serial->len > 0) { 526 SETATTR(templ, i, CKA_SERIAL_NUMBER, 527 serial->val, serial->len); 528 i++; 529 } 530 531 (*numobj) = 0; 532 *objlist = NULL; 533 newlist = NULL; 534 535 ckrv = C_FindObjectsInit(kmfh->pk11handle, templ, i); 536 if (ckrv != CKR_OK) 537 goto cleanup; 538 539 tail = newlist = NULL; 540 while (ckrv == CKR_OK) { 541 CK_OBJECT_HANDLE tObj; 542 ckrv = C_FindObjects(kmfh->pk11handle, &tObj, 1, &num); 543 if (ckrv != CKR_OK || num == 0) 544 break; 545 546 /* 547 * 'matchcert' returns 0 if subject/issuer match 548 * 549 * If no match, move on to the next one 550 */ 551 if (matchcert(kmfh, tObj, &issuerDN, &subjectDN)) 552 continue; 553 554 if (newlist == NULL) { 555 newlist = malloc(sizeof (OBJLIST)); 556 if (newlist == NULL) { 557 rv = KMF_ERR_MEMORY; 558 break; 559 } 560 newlist->handle = tObj; 561 newlist->next = NULL; 562 tail = newlist; 563 } else { 564 tail->next = malloc(sizeof (OBJLIST)); 565 if (tail->next != NULL) { 566 tail = tail->next; 567 } else { 568 rv = KMF_ERR_MEMORY; 569 break; 570 } 571 tail->handle = tObj; 572 tail->next = NULL; 573 } 574 (*numobj)++; 575 } 576 ckrv = C_FindObjectsFinal(kmfh->pk11handle); 577 578 cleanup: 579 if (ckrv != CKR_OK) { 580 SET_ERROR(kmfh, ckrv); 581 rv = KMF_ERR_INTERNAL; 582 if (newlist != NULL) { 583 free_objlist(newlist); 584 *numobj = 0; 585 newlist = NULL; 586 } 587 } else { 588 if (validity == KMF_ALL_CERTS) { 589 *objlist = newlist; 590 } else { 591 OBJLIST *node, *prev; 592 KMF_X509_DER_CERT tmp_kmf_cert; 593 uint32_t i = 0; 594 595 node = prev = newlist; 596 /* 597 * Now check to see if any found certificate is expired 598 * or valid. 599 */ 600 while (node != NULL && i < (*numobj)) { 601 (void) memset(&tmp_kmf_cert, 0, 602 sizeof (KMF_X509_DER_CERT)); 603 rv = PK11Cert2KMFCert(kmfh, node->handle, 604 &tmp_kmf_cert); 605 if (rv != KMF_OK) { 606 goto cleanup1; 607 } 608 609 rv = KMF_CheckCertDate(handle, 610 &tmp_kmf_cert.certificate); 611 612 if (validity == KMF_NONEXPIRED_CERTS) { 613 if (rv == KMF_OK) { 614 num_ok_certs++; 615 prev = node; 616 node = node->next; 617 } else if (rv == 618 KMF_ERR_VALIDITY_PERIOD) { 619 /* 620 * expired - remove it from list 621 */ 622 pk11_delete_obj_from_list( 623 &newlist, &prev, &node); 624 } else { 625 goto cleanup1; 626 } 627 } 628 629 if (validity == KMF_EXPIRED_CERTS) { 630 if (rv == KMF_ERR_VALIDITY_PERIOD) { 631 num_ok_certs++; 632 prev = node; 633 node = node->next; 634 rv = KMF_OK; 635 } else if (rv == KMF_OK) { 636 /* 637 * valid - remove it from list 638 */ 639 pk11_delete_obj_from_list( 640 &newlist, &prev, &node); 641 } else { 642 goto cleanup1; 643 } 644 } 645 i++; 646 KMF_FreeKMFCert(handle, &tmp_kmf_cert); 647 } 648 *numobj = num_ok_certs; 649 *objlist = newlist; 650 } 651 } 652 653 cleanup1: 654 if (rv != KMF_OK && newlist != NULL) { 655 free_objlist(newlist); 656 *numobj = 0; 657 *objlist = NULL; 658 } 659 660 if (issuer != NULL) 661 KMF_FreeDN(&issuerDN); 662 663 if (subject != NULL) 664 KMF_FreeDN(&subjectDN); 665 666 return (rv); 667 } 668 669 /* 670 * The caller may pass a NULL value for kmf_cert below and the function will 671 * just return the number of certs found (in num_certs). 672 */ 673 KMF_RETURN 674 KMFPK11_FindCert(KMF_HANDLE_T handle, KMF_FINDCERT_PARAMS *params, 675 KMF_X509_DER_CERT *kmf_cert, 676 uint32_t *num_certs) 677 { 678 KMF_RETURN rv = 0; 679 uint32_t want_certs; 680 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 681 OBJLIST *objlist = NULL; 682 683 if (!kmfh) 684 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 685 686 if (kmfh->pk11handle == CK_INVALID_HANDLE) 687 return (KMF_ERR_NO_TOKEN_SELECTED); 688 689 if (params == NULL || num_certs == NULL) 690 return (KMF_ERR_BAD_PARAMETER); 691 692 if (*num_certs > 0) 693 want_certs = *num_certs; 694 else 695 want_certs = MAXINT; /* count them all */ 696 697 *num_certs = 0; 698 699 rv = search_certs(handle, 700 params->certLabel, params->issuer, 701 params->subject, params->serial, 702 params->pkcs11parms.private, 703 params->find_cert_validity, 704 &objlist, num_certs); 705 706 if (rv == KMF_OK && objlist != NULL && kmf_cert != NULL) { 707 OBJLIST *node = objlist; 708 int i = 0; 709 while (node != NULL && i < want_certs) { 710 rv = PK11Cert2KMFCert(kmfh, node->handle, 711 &kmf_cert[i]); 712 i++; 713 node = node->next; 714 } 715 } 716 717 if (objlist != NULL) 718 free_objlist(objlist); 719 720 if (*num_certs == 0) 721 rv = KMF_ERR_CERT_NOT_FOUND; 722 723 return (rv); 724 } 725 726 /*ARGSUSED*/ 727 void 728 KMFPK11_FreeKMFCert(KMF_HANDLE_T handle, 729 KMF_X509_DER_CERT *kmf_cert) 730 { 731 if (kmf_cert != NULL && kmf_cert->certificate.Data != NULL) { 732 free(kmf_cert->certificate.Data); 733 kmf_cert->certificate.Data = NULL; 734 kmf_cert->certificate.Length = 0; 735 736 if (kmf_cert->kmf_private.label != NULL) { 737 free(kmf_cert->kmf_private.label); 738 kmf_cert->kmf_private.label = NULL; 739 } 740 } 741 } 742 743 KMF_RETURN 744 KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey, 745 KMF_DATA *eData) 746 { 747 KMF_RETURN ret = KMF_OK; 748 CK_RV rv; 749 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 750 CK_OBJECT_CLASS ckObjClass = CKO_PUBLIC_KEY; 751 CK_KEY_TYPE ckKeyType; 752 KMF_DATA Modulus, Exponent, Prime, Subprime, Base, Value; 753 KMF_OID *Algorithm; 754 BerElement *asn1 = NULL; 755 BerValue *PubKeyParams = NULL, *EncodedKey = NULL; 756 KMF_X509_SPKI spki; 757 758 CK_ATTRIBUTE rsaTemplate[4]; 759 CK_ATTRIBUTE dsaTemplate[6]; 760 761 if (!kmfh) 762 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 763 764 if (kmfh->pk11handle == CK_INVALID_HANDLE) 765 return (KMF_ERR_NO_TOKEN_SELECTED); 766 767 if (pKey == NULL || pKey->keyp == CK_INVALID_HANDLE) 768 return (KMF_ERR_BAD_PARAMETER); 769 770 (void) memset(&Modulus, 0, sizeof (Modulus)); 771 (void) memset(&Exponent, 0, sizeof (Exponent)); 772 (void) memset(&Prime, 0, sizeof (Prime)); 773 (void) memset(&Subprime, 0, sizeof (Subprime)); 774 (void) memset(&Base, 0, sizeof (Base)); 775 (void) memset(&Value, 0, sizeof (Value)); 776 777 SETATTR(rsaTemplate, 0, CKA_CLASS, &ckObjClass, sizeof (ckObjClass)); 778 SETATTR(rsaTemplate, 1, CKA_KEY_TYPE, &ckKeyType, sizeof (ckKeyType)); 779 SETATTR(rsaTemplate, 2, CKA_MODULUS, Modulus.Data, &Modulus.Length); 780 SETATTR(rsaTemplate, 3, CKA_PUBLIC_EXPONENT, Exponent.Data, 781 &Exponent.Length); 782 783 SETATTR(dsaTemplate, 0, CKA_CLASS, &ckObjClass, sizeof (ckObjClass)); 784 SETATTR(dsaTemplate, 1, CKA_KEY_TYPE, &ckKeyType, sizeof (ckKeyType)); 785 SETATTR(dsaTemplate, 2, CKA_PRIME, Prime.Data, &Prime.Length); 786 SETATTR(dsaTemplate, 3, CKA_SUBPRIME, Subprime.Data, &Subprime.Length); 787 SETATTR(dsaTemplate, 4, CKA_BASE, Base.Data, &Base.Length); 788 SETATTR(dsaTemplate, 5, CKA_VALUE, Value.Data, &Value.Length); 789 790 switch (pKey->keyalg) { 791 case KMF_RSA: 792 /* Get the length of the fields */ 793 rv = C_GetAttributeValue(kmfh->pk11handle, 794 (CK_OBJECT_HANDLE)pKey->keyp, 795 rsaTemplate, 4); 796 if (rv != CKR_OK) { 797 SET_ERROR(kmfh, rv); 798 return (KMF_ERR_BAD_PARAMETER); 799 } 800 801 Modulus.Length = rsaTemplate[2].ulValueLen; 802 Modulus.Data = malloc(Modulus.Length); 803 if (Modulus.Data == NULL) 804 return (KMF_ERR_MEMORY); 805 806 Exponent.Length = rsaTemplate[3].ulValueLen; 807 Exponent.Data = malloc(Exponent.Length); 808 if (Exponent.Data == NULL) { 809 free(Modulus.Data); 810 return (KMF_ERR_MEMORY); 811 } 812 813 SETATTR(rsaTemplate, 2, CKA_MODULUS, Modulus.Data, 814 Modulus.Length); 815 SETATTR(rsaTemplate, 3, CKA_PUBLIC_EXPONENT, 816 Exponent.Data, Exponent.Length); 817 /* Now get the values */ 818 rv = C_GetAttributeValue(kmfh->pk11handle, 819 (CK_OBJECT_HANDLE)pKey->keyp, 820 rsaTemplate, 4); 821 if (rv != CKR_OK) { 822 SET_ERROR(kmfh, rv); 823 free(Modulus.Data); 824 free(Exponent.Data); 825 return (KMF_ERR_BAD_PARAMETER); 826 } 827 828 /* 829 * This is the KEY algorithm, not the 830 * signature algorithm. 831 */ 832 Algorithm = X509_AlgIdToAlgorithmOid(KMF_ALGID_RSA); 833 if (Algorithm != NULL) { 834 835 /* Encode the RSA Key Data */ 836 if ((asn1 = kmfder_alloc()) == NULL) { 837 free(Modulus.Data); 838 free(Exponent.Data); 839 return (KMF_ERR_MEMORY); 840 } 841 if (kmfber_printf(asn1, "{II}", 842 Modulus.Data, Modulus.Length, 843 Exponent.Data, Exponent.Length) == -1) { 844 kmfber_free(asn1, 1); 845 free(Modulus.Data); 846 free(Exponent.Data); 847 return (KMF_ERR_ENCODING); 848 } 849 if (kmfber_flatten(asn1, &EncodedKey) == -1) { 850 kmfber_free(asn1, 1); 851 free(Modulus.Data); 852 free(Exponent.Data); 853 return (KMF_ERR_ENCODING); 854 } 855 kmfber_free(asn1, 1); 856 } 857 858 free(Exponent.Data); 859 free(Modulus.Data); 860 861 break; 862 case KMF_DSA: 863 /* Get the length of the fields */ 864 rv = C_GetAttributeValue(kmfh->pk11handle, 865 (CK_OBJECT_HANDLE)pKey->keyp, 866 dsaTemplate, 6); 867 if (rv != CKR_OK) { 868 SET_ERROR(kmfh, rv); 869 return (KMF_ERR_BAD_PARAMETER); 870 } 871 Prime.Length = dsaTemplate[2].ulValueLen; 872 Prime.Data = malloc(Prime.Length); 873 if (Prime.Data == NULL) { 874 return (KMF_ERR_MEMORY); 875 } 876 877 Subprime.Length = dsaTemplate[3].ulValueLen; 878 Subprime.Data = malloc(Subprime.Length); 879 if (Subprime.Data == NULL) { 880 free(Prime.Data); 881 return (KMF_ERR_MEMORY); 882 } 883 884 Base.Length = dsaTemplate[4].ulValueLen; 885 Base.Data = malloc(Base.Length); 886 if (Base.Data == NULL) { 887 free(Prime.Data); 888 free(Subprime.Data); 889 return (KMF_ERR_MEMORY); 890 } 891 892 Value.Length = dsaTemplate[5].ulValueLen; 893 Value.Data = malloc(Value.Length); 894 if (Value.Data == NULL) { 895 free(Prime.Data); 896 free(Subprime.Data); 897 free(Base.Data); 898 return (KMF_ERR_MEMORY); 899 } 900 SETATTR(dsaTemplate, 2, CKA_PRIME, Prime.Data, 901 Prime.Length); 902 SETATTR(dsaTemplate, 3, CKA_SUBPRIME, Subprime.Data, 903 Subprime.Length); 904 SETATTR(dsaTemplate, 4, CKA_BASE, Base.Data, 905 Base.Length); 906 SETATTR(dsaTemplate, 5, CKA_VALUE, Value.Data, 907 Value.Length); 908 909 /* Now get the values */ 910 rv = C_GetAttributeValue(kmfh->pk11handle, 911 (CK_OBJECT_HANDLE)pKey->keyp, 912 dsaTemplate, 6); 913 if (rv != CKR_OK) { 914 free(Prime.Data); 915 free(Subprime.Data); 916 free(Base.Data); 917 free(Value.Data); 918 SET_ERROR(kmfh, rv); 919 return (KMF_ERR_BAD_PARAMETER); 920 } 921 /* 922 * This is the KEY algorithm, not the 923 * signature algorithm. 924 */ 925 Algorithm = 926 X509_AlgIdToAlgorithmOid(KMF_ALGID_DSA); 927 928 /* Encode the DSA Algorithm Parameters */ 929 if ((asn1 = kmfder_alloc()) == NULL) { 930 free(Prime.Data); 931 free(Subprime.Data); 932 free(Base.Data); 933 free(Value.Data); 934 return (KMF_ERR_MEMORY); 935 } 936 937 if (kmfber_printf(asn1, "{III}", 938 Prime.Data, Prime.Length, 939 Subprime.Data, Subprime.Length, 940 Base.Data, Base.Length) == -1) { 941 942 kmfber_free(asn1, 1); 943 free(Prime.Data); 944 free(Subprime.Data); 945 free(Base.Data); 946 free(Value.Data); 947 return (KMF_ERR_ENCODING); 948 } 949 if (kmfber_flatten(asn1, &PubKeyParams) == -1) { 950 kmfber_free(asn1, 1); 951 free(Prime.Data); 952 free(Subprime.Data); 953 free(Base.Data); 954 free(Value.Data); 955 return (KMF_ERR_ENCODING); 956 } 957 kmfber_free(asn1, 1); 958 free(Prime.Data); 959 free(Subprime.Data); 960 free(Base.Data); 961 962 /* Encode the DSA Key Value */ 963 if ((asn1 = kmfder_alloc()) == NULL) { 964 free(Value.Data); 965 return (KMF_ERR_MEMORY); 966 } 967 968 if (kmfber_printf(asn1, "I", 969 Value.Data, Value.Length) == -1) { 970 kmfber_free(asn1, 1); 971 free(Value.Data); 972 return (KMF_ERR_ENCODING); 973 } 974 if (kmfber_flatten(asn1, &EncodedKey) == -1) { 975 kmfber_free(asn1, 1); 976 free(Value.Data); 977 return (KMF_ERR_ENCODING); 978 } 979 kmfber_free(asn1, 1); 980 free(Value.Data); 981 break; 982 default: 983 return (KMF_ERR_BAD_PARAMETER); 984 } 985 986 /* Now, build an SPKI structure for the final encoding step */ 987 spki.algorithm.algorithm = *Algorithm; 988 if (PubKeyParams != NULL) { 989 spki.algorithm.parameters.Data = 990 (uchar_t *)PubKeyParams->bv_val; 991 spki.algorithm.parameters.Length = PubKeyParams->bv_len; 992 } else { 993 spki.algorithm.parameters.Data = NULL; 994 spki.algorithm.parameters.Length = 0; 995 } 996 997 if (EncodedKey != NULL) { 998 spki.subjectPublicKey.Data = (uchar_t *)EncodedKey->bv_val; 999 spki.subjectPublicKey.Length = EncodedKey->bv_len; 1000 } else { 1001 spki.subjectPublicKey.Data = NULL; 1002 spki.subjectPublicKey.Length = 0; 1003 } 1004 1005 /* Finally, encode the entire SPKI record */ 1006 ret = DerEncodeSPKI(&spki, eData); 1007 1008 cleanup: 1009 if (EncodedKey) { 1010 free(EncodedKey->bv_val); 1011 free(EncodedKey); 1012 } 1013 1014 if (PubKeyParams) { 1015 free(PubKeyParams->bv_val); 1016 free(PubKeyParams); 1017 } 1018 1019 return (ret); 1020 } 1021 1022 1023 static KMF_RETURN 1024 CreateCertObject(KMF_HANDLE_T handle, char *label, KMF_DATA *pcert) 1025 { 1026 KMF_RETURN rv = 0; 1027 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1028 1029 KMF_X509_CERTIFICATE *signed_cert_ptr = NULL; 1030 KMF_DATA data; 1031 KMF_DATA Id; 1032 1033 CK_RV ckrv; 1034 CK_ULONG subject_len, issuer_len, serno_len; 1035 CK_BYTE *subject, *issuer, *serial, nullserno; 1036 CK_BBOOL true = TRUE; 1037 CK_CERTIFICATE_TYPE certtype = CKC_X_509; 1038 CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; 1039 CK_ATTRIBUTE x509templ[11]; 1040 CK_OBJECT_HANDLE hCert = NULL; 1041 int i; 1042 1043 if (!kmfh) 1044 return (KMF_ERR_INTERNAL); /* should not happen */ 1045 1046 if (kmfh->pk11handle == CK_INVALID_HANDLE) 1047 return (KMF_ERR_INTERNAL); /* should not happen */ 1048 1049 if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) 1050 return (KMF_ERR_INTERNAL); /* should not happen */ 1051 1052 /* 1053 * The data *must* be a DER encoded X.509 certificate. 1054 * Convert it to a CSSM cert and then parse the fields so 1055 * the PKCS#11 attributes can be filled in correctly. 1056 */ 1057 rv = DerDecodeSignedCertificate((const KMF_DATA *)pcert, 1058 &signed_cert_ptr); 1059 if (rv != KMF_OK) { 1060 return (KMF_ERR_ENCODING); 1061 } 1062 1063 /* 1064 * Encode fields into PKCS#11 attributes. 1065 */ 1066 1067 /* Get the subject name */ 1068 rv = DerEncodeName(&signed_cert_ptr->certificate.subject, &data); 1069 if (rv == KMF_OK) { 1070 subject = data.Data; 1071 subject_len = data.Length; 1072 } else { 1073 rv = KMF_ERR_ENCODING; 1074 goto cleanup; 1075 } 1076 1077 /* Encode the issuer */ 1078 rv = DerEncodeName(&signed_cert_ptr->certificate.issuer, &data); 1079 if (rv == KMF_OK) { 1080 issuer = data.Data; 1081 issuer_len = data.Length; 1082 } else { 1083 rv = KMF_ERR_ENCODING; 1084 goto cleanup; 1085 } 1086 1087 /* Encode serial number */ 1088 if (signed_cert_ptr->certificate.serialNumber.len > 0 && 1089 signed_cert_ptr->certificate.serialNumber.val != NULL) { 1090 serial = signed_cert_ptr->certificate.serialNumber.val; 1091 serno_len = signed_cert_ptr->certificate.serialNumber.len; 1092 } else { 1093 /* 1094 * RFC3280 says to gracefully handle certs with serial numbers 1095 * of 0. 1096 */ 1097 nullserno = '\0'; 1098 serial = &nullserno; 1099 serno_len = 1; 1100 } 1101 1102 /* Generate an ID from the SPKI data */ 1103 rv = GetIDFromSPKI(&signed_cert_ptr->certificate.subjectPublicKeyInfo, 1104 &Id); 1105 1106 if (rv != KMF_OK) { 1107 SET_ERROR(kmfh, rv); 1108 goto cleanup; 1109 } 1110 1111 i = 0; 1112 SETATTR(x509templ, i, CKA_CLASS, &certClass, 1113 sizeof (certClass)); i++; 1114 SETATTR(x509templ, i, CKA_CERTIFICATE_TYPE, &certtype, 1115 sizeof (certtype)); i++; 1116 SETATTR(x509templ, i, CKA_TOKEN, &true, sizeof (true)); i++; 1117 SETATTR(x509templ, i, CKA_SUBJECT, subject, subject_len); i++; 1118 SETATTR(x509templ, i, CKA_ISSUER, issuer, issuer_len); i++; 1119 SETATTR(x509templ, i, CKA_SERIAL_NUMBER, serial, serno_len); i++; 1120 SETATTR(x509templ, i, CKA_VALUE, pcert->Data, pcert->Length); i++; 1121 SETATTR(x509templ, i, CKA_ID, Id.Data, Id.Length); i++; 1122 if (label != NULL && strlen(label)) { 1123 SETATTR(x509templ, i, CKA_LABEL, label, strlen(label)); 1124 i++; 1125 } 1126 /* 1127 * The cert object handle is actually "leaked" here. If the app 1128 * really wants to clean up the data space, it will have to call 1129 * KMF_DeleteCert and specify the softtoken keystore. 1130 */ 1131 ckrv = C_CreateObject(kmfh->pk11handle, x509templ, i, &hCert); 1132 if (ckrv != CKR_OK) { 1133 SET_ERROR(kmfh, rv); 1134 rv = KMF_ERR_INTERNAL; 1135 } 1136 free(subject); 1137 free(issuer); 1138 1139 cleanup: 1140 if (Id.Data != NULL) 1141 free(Id.Data); 1142 1143 if (signed_cert_ptr) { 1144 KMF_FreeSignedCert(signed_cert_ptr); 1145 free(signed_cert_ptr); 1146 } 1147 return (rv); 1148 } 1149 1150 1151 KMF_RETURN 1152 KMFPK11_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *params, 1153 KMF_DATA *pcert) 1154 { 1155 KMF_RETURN rv = 0; 1156 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1157 1158 if (!kmfh) 1159 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 1160 1161 if (kmfh->pk11handle == CK_INVALID_HANDLE) 1162 return (KMF_ERR_NO_TOKEN_SELECTED); 1163 1164 if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) 1165 return (KMF_ERR_BAD_PARAMETER); 1166 1167 rv = CreateCertObject(handle, params->certLabel, pcert); 1168 return (rv); 1169 } 1170 1171 1172 1173 KMF_RETURN 1174 KMFPK11_ImportCert(KMF_HANDLE_T handle, KMF_IMPORTCERT_PARAMS *params) 1175 { 1176 KMF_RETURN rv = 0; 1177 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1178 KMF_ENCODE_FORMAT format; 1179 KMF_DATA cert1 = { NULL, 0}; 1180 KMF_DATA cert2 = { NULL, 0}; 1181 1182 if (!kmfh) 1183 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 1184 1185 if (kmfh->pk11handle == CK_INVALID_HANDLE) 1186 return (KMF_ERR_NO_TOKEN_SELECTED); 1187 1188 if (params == NULL || params->certfile == NULL) { 1189 return (KMF_ERR_BAD_PARAMETER); 1190 } 1191 1192 /* 1193 * Check if the input cert file is a valid certificate and 1194 * auto-detect the file format of it. 1195 */ 1196 rv = KMF_IsCertFile(handle, params->certfile, &format); 1197 if (rv != KMF_OK) 1198 return (rv); 1199 1200 /* Read in the CERT file */ 1201 rv = KMF_ReadInputFile(handle, params->certfile, &cert1); 1202 if (rv != KMF_OK) { 1203 return (rv); 1204 } 1205 1206 /* 1207 * If the input certificate is in PEM format, we need to convert 1208 * it to DER first. 1209 */ 1210 if (format == KMF_FORMAT_PEM) { 1211 int derlen; 1212 rv = KMF_Pem2Der(cert1.Data, cert1.Length, 1213 &cert2.Data, &derlen); 1214 if (rv != KMF_OK) { 1215 goto out; 1216 } 1217 cert2.Length = (size_t)derlen; 1218 } 1219 1220 rv = CreateCertObject(handle, params->certLabel, 1221 format == KMF_FORMAT_ASN1 ? &cert1 : &cert2); 1222 1223 out: 1224 if (cert1.Data != NULL) { 1225 free(cert1.Data); 1226 } 1227 1228 if (cert2.Data != NULL) { 1229 free(cert2.Data); 1230 } 1231 1232 return (rv); 1233 } 1234 1235 KMF_RETURN 1236 KMFPK11_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params) 1237 { 1238 KMF_RETURN rv = 0; 1239 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1240 OBJLIST *objlist; 1241 uint32_t numObjects = 0; 1242 1243 if (!kmfh) 1244 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 1245 1246 if (kmfh->pk11handle == CK_INVALID_HANDLE) 1247 return (KMF_ERR_NO_TOKEN_SELECTED); 1248 1249 if (params == NULL) 1250 return (KMF_ERR_BAD_PARAMETER); 1251 1252 /* 1253 * Use the same search routine as is used for the FindCert 1254 * operation. 1255 */ 1256 objlist = NULL; 1257 rv = search_certs(handle, 1258 params->certLabel, params->issuer, 1259 params->subject, params->serial, 1260 params->pkcs11parms.private, 1261 params->find_cert_validity, 1262 &objlist, &numObjects); 1263 1264 if (rv == KMF_OK && objlist != NULL) { 1265 OBJLIST *node = objlist; 1266 1267 while (node != NULL) { 1268 CK_RV ckrv; 1269 ckrv = C_DestroyObject(kmfh->pk11handle, 1270 node->handle); 1271 if (ckrv != CKR_OK) { 1272 SET_ERROR(kmfh, ckrv); 1273 rv = KMF_ERR_INTERNAL; 1274 break; 1275 } 1276 node = node->next; 1277 } 1278 free_objlist(objlist); 1279 } 1280 1281 if (rv == KMF_OK && numObjects == 0) 1282 rv = KMF_ERR_CERT_NOT_FOUND; 1283 1284 out: 1285 return (rv); 1286 } 1287 1288 KMF_RETURN 1289 KMFPK11_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, 1290 KMF_KEY_HANDLE *privkey, KMF_KEY_HANDLE *pubkey) 1291 { 1292 KMF_RETURN rv = KMF_OK; 1293 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1294 1295 CK_RV ckrv = 0; 1296 CK_OBJECT_HANDLE pubKey = CK_INVALID_HANDLE; 1297 CK_OBJECT_HANDLE priKey = CK_INVALID_HANDLE; 1298 CK_SESSION_HANDLE hSession = kmfh->pk11handle; 1299 1300 static CK_OBJECT_CLASS priClass = CKO_PRIVATE_KEY; 1301 static CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; 1302 1303 static CK_ULONG rsaKeyType = CKK_RSA; 1304 static CK_ULONG modulusBits = 1024; 1305 static CK_BYTE PubExpo[3] = {0x01, 0x00, 0x01}; 1306 static CK_BBOOL true = TRUE; 1307 static CK_BBOOL ontoken = TRUE; 1308 static CK_BBOOL false = FALSE; 1309 static CK_ULONG dsaKeyType = CKK_DSA; 1310 1311 CK_ATTRIBUTE rsaPubKeyTemplate[8]; 1312 CK_ATTRIBUTE rsaPriKeyTemplate[6]; 1313 1314 static CK_BYTE ckDsaPrime[128] = { 1315 0xb2, 0x6b, 0xc3, 0xfb, 0xe3, 0x26, 0xf4, 0xc2, 1316 0xcf, 0xdd, 0xf9, 0xae, 0x3e, 0x39, 0x7f, 0x9c, 1317 0xa7, 0x73, 0xc3, 0x00, 0xa3, 0x50, 0x67, 0xc3, 1318 0xab, 0x49, 0x2c, 0xea, 0x59, 0x10, 0xa4, 0xbc, 1319 0x09, 0x94, 0xa9, 0x05, 0x3b, 0x0d, 0x35, 0x3c, 1320 0x55, 0x52, 0x47, 0xf0, 0xe3, 0x72, 0x5b, 0xe8, 1321 0x72, 0xa0, 0x71, 0x1c, 0x23, 0x4f, 0x6d, 0xe8, 1322 0xac, 0xe5, 0x21, 0x1b, 0xc0, 0xd8, 0x42, 0xd3, 1323 0x87, 0xae, 0x83, 0x5e, 0x52, 0x7e, 0x46, 0x09, 1324 0xb5, 0xc7, 0x3d, 0xd6, 0x00, 0xf5, 0xf2, 0x9c, 1325 0x84, 0x30, 0x81, 0x7e, 0x7b, 0x30, 0x5b, 0xd5, 1326 0xab, 0xd0, 0x2f, 0x21, 0xb3, 0xd8, 0xed, 0xdb, 1327 0x97, 0x77, 0xe4, 0x7e, 0x6c, 0xcc, 0xb9, 0x6b, 1328 0xdd, 0xaa, 0x96, 0x04, 0xe7, 0xd4, 0x55, 0x11, 1329 0x53, 0xab, 0xba, 0x95, 0x9a, 0xa2, 0x8c, 0x27, 1330 0xd9, 0xcf, 0xad, 0xf3, 0xcf, 0x3a, 0x0c, 0x4b}; 1331 1332 static CK_BYTE ckDsaSubPrime[20] = { 1333 0xa4, 0x5f, 0x2a, 0x27, 0x09, 0x49, 0xb6, 0xfe, 1334 0x73, 0xeb, 0x95, 0x7d, 0x00, 0xf3, 0x42, 0xfc, 1335 0x78, 0x47, 0xb0, 0xd5}; 1336 1337 static CK_BYTE ckDsaBase[128] = { 1338 0x5c, 0x57, 0x16, 0x49, 0xef, 0xc8, 0xfb, 0x4b, 1339 0xee, 0x07, 0x45, 0x3b, 0x6a, 0x1d, 0xf3, 0xe5, 1340 0xeb, 0xee, 0xad, 0x11, 0x13, 0xe3, 0x52, 0xe3, 1341 0x0d, 0xc0, 0x21, 0x25, 0xfa, 0xf0, 0x93, 0x1c, 1342 0x53, 0x4d, 0xdc, 0x0d, 0x76, 0xd2, 0xfe, 0xc2, 1343 0xd7, 0x72, 0x64, 0x69, 0x53, 0x3d, 0x33, 0xbd, 1344 0xe1, 0x34, 0xf2, 0x5a, 0x67, 0x83, 0xe0, 0xd3, 1345 0x1c, 0xd6, 0x41, 0x4d, 0x16, 0xe8, 0x6c, 0x5a, 1346 0x07, 0x95, 0x21, 0x9a, 0xa3, 0xc4, 0xb9, 0x05, 1347 0x9d, 0x11, 0xcb, 0xc8, 0xc4, 0x9d, 0x00, 0x1a, 1348 0xf4, 0x85, 0x2a, 0xa9, 0x20, 0x3c, 0xba, 0x67, 1349 0xe5, 0xed, 0x31, 0xb2, 0x11, 0xfb, 0x1f, 0x73, 1350 0xec, 0x61, 0x29, 0xad, 0xc7, 0x68, 0xb2, 0x3f, 1351 0x38, 0xea, 0xd9, 0x87, 0x83, 0x9e, 0x7e, 0x19, 1352 0x18, 0xdd, 0xc2, 0xc3, 0x5b, 0x16, 0x6d, 0xce, 1353 0xcf, 0x88, 0x91, 0x07, 0xe0, 0x2b, 0xa8, 0x54 }; 1354 1355 static CK_ATTRIBUTE ckDsaPubKeyTemplate[] = { 1356 { CKA_CLASS, &pubClass, sizeof (pubClass) }, 1357 { CKA_KEY_TYPE, &dsaKeyType, sizeof (dsaKeyType) }, 1358 { CKA_TOKEN, &ontoken, sizeof (ontoken)}, 1359 { CKA_PRIVATE, &false, sizeof (false)}, 1360 { CKA_PRIME, &ckDsaPrime, sizeof (ckDsaPrime) }, 1361 { CKA_SUBPRIME, &ckDsaSubPrime, sizeof (ckDsaSubPrime)}, 1362 { CKA_BASE, &ckDsaBase, sizeof (ckDsaBase) }, 1363 { CKA_VERIFY, &true, sizeof (true) }, 1364 }; 1365 1366 #define NUMBER_DSA_PUB_TEMPLATES (sizeof (ckDsaPubKeyTemplate) / \ 1367 sizeof (CK_ATTRIBUTE)) 1368 #define MAX_DSA_PUB_TEMPLATES (sizeof (ckDsaPubKeyTemplate) / \ 1369 sizeof (CK_ATTRIBUTE)) 1370 1371 static CK_ATTRIBUTE ckDsaPriKeyTemplate[] = { 1372 {CKA_CLASS, &priClass, sizeof (priClass)}, 1373 {CKA_KEY_TYPE, &dsaKeyType, sizeof (dsaKeyType)}, 1374 {CKA_TOKEN, &ontoken, sizeof (ontoken)}, 1375 {CKA_PRIVATE, &true, sizeof (true)}, 1376 {CKA_SIGN, &true, sizeof (true)}, 1377 }; 1378 1379 CK_ATTRIBUTE labelattr[1]; 1380 CK_ATTRIBUTE idattr[1]; 1381 char IDHashData[SHA1_HASH_LENGTH]; 1382 KMF_DATA IDInput, IDOutput; 1383 SHA1_CTX ctx; 1384 1385 #define NUMBER_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \ 1386 sizeof (CK_ATTRIBUTE)) 1387 #define MAX_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \ 1388 sizeof (CK_ATTRIBUTE)) 1389 1390 if (!kmfh) 1391 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 1392 1393 if (kmfh->pk11handle == CK_INVALID_HANDLE) 1394 return (KMF_ERR_NO_TOKEN_SELECTED); 1395 1396 if (params == NULL) 1397 return (KMF_ERR_BAD_PARAMETER); 1398 1399 rv = pk11_authenticate(handle, ¶ms->cred); 1400 if (rv != KMF_OK) { 1401 return (rv); 1402 } 1403 1404 if (params->keytype == KMF_RSA) { 1405 CK_MECHANISM keyGenMech = {CKM_RSA_PKCS_KEY_PAIR_GEN, 1406 NULL, 0}; 1407 CK_BYTE *modulus; 1408 CK_ULONG modulusLength; 1409 CK_ATTRIBUTE modattr[1]; 1410 1411 SETATTR(rsaPubKeyTemplate, 0, CKA_CLASS, 1412 &pubClass, sizeof (pubClass)); 1413 SETATTR(rsaPubKeyTemplate, 1, CKA_KEY_TYPE, 1414 &rsaKeyType, sizeof (rsaKeyType)); 1415 SETATTR(rsaPubKeyTemplate, 2, CKA_TOKEN, 1416 &false, sizeof (false)); 1417 SETATTR(rsaPubKeyTemplate, 3, CKA_PRIVATE, 1418 &false, sizeof (false)); 1419 SETATTR(rsaPubKeyTemplate, 4, CKA_MODULUS_BITS, 1420 &modulusBits, sizeof (modulusBits)); 1421 if (params->rsa_exponent.len > 0 && 1422 params->rsa_exponent.val != NULL) { 1423 SETATTR(rsaPubKeyTemplate, 5, 1424 CKA_PUBLIC_EXPONENT, 1425 params->rsa_exponent.val, 1426 params->rsa_exponent.len); 1427 } else { 1428 SETATTR(rsaPubKeyTemplate, 5, 1429 CKA_PUBLIC_EXPONENT, &PubExpo, 1430 sizeof (PubExpo)); 1431 } 1432 SETATTR(rsaPubKeyTemplate, 6, CKA_ENCRYPT, 1433 &true, sizeof (true)); 1434 SETATTR(rsaPubKeyTemplate, 7, CKA_VERIFY, 1435 &true, sizeof (true)); 1436 1437 SETATTR(rsaPriKeyTemplate, 0, CKA_CLASS, &priClass, 1438 sizeof (priClass)); 1439 SETATTR(rsaPriKeyTemplate, 1, CKA_KEY_TYPE, &rsaKeyType, 1440 sizeof (rsaKeyType)); 1441 SETATTR(rsaPriKeyTemplate, 2, CKA_TOKEN, &ontoken, 1442 sizeof (ontoken)); 1443 SETATTR(rsaPriKeyTemplate, 3, CKA_PRIVATE, &true, 1444 sizeof (true)); 1445 SETATTR(rsaPriKeyTemplate, 4, CKA_DECRYPT, &true, 1446 sizeof (true)); 1447 SETATTR(rsaPriKeyTemplate, 5, CKA_SIGN, &true, 1448 sizeof (true)); 1449 1450 SETATTR(modattr, 0, CKA_MODULUS, NULL, &modulusLength); 1451 1452 modulusBits = params->keylength; 1453 1454 pubKey = CK_INVALID_HANDLE; 1455 priKey = CK_INVALID_HANDLE; 1456 ckrv = C_GenerateKeyPair(hSession, &keyGenMech, 1457 rsaPubKeyTemplate, 1458 (sizeof (rsaPubKeyTemplate)/sizeof (CK_ATTRIBUTE)), 1459 rsaPriKeyTemplate, 1460 (sizeof (rsaPriKeyTemplate)/sizeof (CK_ATTRIBUTE)), 1461 &pubKey, &priKey); 1462 if (ckrv != CKR_OK) { 1463 SET_ERROR(kmfh, ckrv); 1464 return (KMF_ERR_KEYGEN_FAILED); 1465 } 1466 1467 if (privkey != NULL) { 1468 privkey->kstype = KMF_KEYSTORE_PK11TOKEN; 1469 privkey->keyalg = KMF_RSA; 1470 privkey->keyclass = KMF_ASYM_PRI; 1471 privkey->keyp = (void *)priKey; 1472 } 1473 if (pubkey != NULL) { 1474 pubkey->kstype = KMF_KEYSTORE_PK11TOKEN; 1475 pubkey->keyalg = KMF_RSA; 1476 pubkey->keyclass = KMF_ASYM_PUB; 1477 pubkey->keyp = (void *)pubKey; 1478 } 1479 1480 /* Get the Modulus field to use as input for creating the ID */ 1481 rv = C_GetAttributeValue(kmfh->pk11handle, 1482 (CK_OBJECT_HANDLE)pubKey, 1483 modattr, 1); 1484 if (rv != CKR_OK) { 1485 SET_ERROR(kmfh, ckrv); 1486 return (KMF_ERR_BAD_PARAMETER); 1487 } 1488 1489 modulusLength = modattr[0].ulValueLen; 1490 modulus = malloc(modulusLength); 1491 if (modulus == NULL) 1492 return (KMF_ERR_MEMORY); 1493 1494 modattr[0].pValue = modulus; 1495 rv = C_GetAttributeValue(kmfh->pk11handle, 1496 (CK_OBJECT_HANDLE)pubKey, 1497 modattr, 1); 1498 if (rv != CKR_OK) { 1499 SET_ERROR(kmfh, ckrv); 1500 free(modulus); 1501 return (KMF_ERR_BAD_PARAMETER); 1502 } 1503 1504 IDInput.Data = modulus; 1505 IDInput.Length = modulusLength; 1506 1507 } else if (params->keytype == KMF_DSA) { 1508 CK_MECHANISM keyGenMech = {CKM_DSA_KEY_PAIR_GEN, NULL, 0}; 1509 CK_BYTE *keyvalue; 1510 CK_ULONG valueLen; 1511 CK_ATTRIBUTE valattr[1]; 1512 1513 SETATTR(ckDsaPriKeyTemplate, 2, CKA_TOKEN, 1514 &ontoken, sizeof (ontoken)); 1515 SETATTR(valattr, 0, CKA_VALUE, NULL, &valueLen); 1516 1517 ckrv = C_GenerateKeyPair(hSession, &keyGenMech, 1518 ckDsaPubKeyTemplate, 1519 (sizeof (ckDsaPubKeyTemplate)/sizeof (CK_ATTRIBUTE)), 1520 ckDsaPriKeyTemplate, 1521 (sizeof (ckDsaPriKeyTemplate)/sizeof (CK_ATTRIBUTE)), 1522 &pubKey, &priKey); 1523 if (ckrv != CKR_OK) { 1524 SET_ERROR(kmfh, ckrv); 1525 return (KMF_ERR_KEYGEN_FAILED); 1526 } 1527 1528 if (privkey != NULL) { 1529 privkey->kstype = KMF_KEYSTORE_PK11TOKEN; 1530 privkey->keyalg = KMF_DSA; 1531 privkey->keyclass = KMF_ASYM_PRI; 1532 privkey->keyp = (void *)priKey; 1533 } 1534 if (pubkey != NULL) { 1535 pubkey->kstype = KMF_KEYSTORE_PK11TOKEN; 1536 pubkey->keyalg = KMF_DSA; 1537 pubkey->keyclass = KMF_ASYM_PUB; 1538 pubkey->keyp = (void *)pubKey; 1539 } 1540 /* Get the Public Value to use as input for creating the ID */ 1541 rv = C_GetAttributeValue(hSession, 1542 (CK_OBJECT_HANDLE)pubKey, 1543 valattr, 1); 1544 if (rv != CKR_OK) { 1545 SET_ERROR(kmfh, ckrv); 1546 return (KMF_ERR_BAD_PARAMETER); 1547 } 1548 1549 valueLen = valattr[0].ulValueLen; 1550 keyvalue = malloc(valueLen); 1551 if (keyvalue == NULL) 1552 return (KMF_ERR_MEMORY); 1553 1554 valattr[0].pValue = keyvalue; 1555 rv = C_GetAttributeValue(hSession, 1556 (CK_OBJECT_HANDLE)pubKey, 1557 valattr, 1); 1558 if (rv != CKR_OK) { 1559 SET_ERROR(kmfh, ckrv); 1560 free(keyvalue); 1561 return (KMF_ERR_BAD_PARAMETER); 1562 } 1563 1564 IDInput.Data = keyvalue; 1565 IDInput.Length = valueLen; 1566 } else { 1567 return (KMF_ERR_BAD_PARAMETER); 1568 } 1569 1570 if (params->keylabel != NULL && 1571 strlen(params->keylabel)) { 1572 1573 SETATTR(labelattr, 0, CKA_LABEL, params->keylabel, 1574 strlen(params->keylabel)); 1575 1576 /* Set the CKA_LABEL if one was indicated */ 1577 if ((ckrv = C_SetAttributeValue(hSession, pubKey, 1578 labelattr, 1)) != CKR_OK) { 1579 SET_ERROR(kmfh, ckrv); 1580 rv = KMF_ERR_INTERNAL; 1581 goto cleanup; 1582 } 1583 if (pubkey != NULL) { 1584 pubkey->keylabel = 1585 (char *)strdup(params->keylabel); 1586 if (pubkey->keylabel == NULL) { 1587 rv = KMF_ERR_MEMORY; 1588 goto cleanup; 1589 } 1590 } 1591 if ((ckrv = C_SetAttributeValue(hSession, priKey, 1592 labelattr, 1)) != CKR_OK) { 1593 SET_ERROR(kmfh, ckrv); 1594 rv = KMF_ERR_INTERNAL; 1595 goto cleanup; 1596 } 1597 if (privkey != NULL) { 1598 privkey->keylabel = 1599 (char *)strdup(params->keylabel); 1600 if (privkey->keylabel == NULL) { 1601 rv = KMF_ERR_MEMORY; 1602 goto cleanup; 1603 } 1604 } 1605 } 1606 1607 /* Now, assign a CKA_ID value so it can be searched */ 1608 /* ID_Input was assigned above in the RSA or DSA keygen section */ 1609 IDOutput.Data = (uchar_t *)IDHashData; 1610 IDOutput.Length = sizeof (IDHashData); 1611 1612 SHA1Init(&ctx); 1613 SHA1Update(&ctx, IDInput.Data, IDInput.Length); 1614 SHA1Final(IDOutput.Data, &ctx); 1615 1616 IDOutput.Length = SHA1_DIGEST_LENGTH; 1617 1618 free(IDInput.Data); 1619 1620 if (rv != CKR_OK) { 1621 SET_ERROR(kmfh, rv); 1622 goto cleanup; 1623 } 1624 SETATTR(idattr, 0, CKA_ID, IDOutput.Data, IDOutput.Length); 1625 if ((ckrv = C_SetAttributeValue(hSession, pubKey, 1626 idattr, 1)) != CKR_OK) { 1627 SET_ERROR(kmfh, ckrv); 1628 rv = KMF_ERR_INTERNAL; 1629 goto cleanup; 1630 } 1631 if ((ckrv = C_SetAttributeValue(hSession, priKey, 1632 idattr, 1)) != CKR_OK) { 1633 SET_ERROR(kmfh, ckrv); 1634 rv = KMF_ERR_INTERNAL; 1635 goto cleanup; 1636 } 1637 1638 cleanup: 1639 if (rv != KMF_OK) { 1640 if (pubKey != CK_INVALID_HANDLE) 1641 (void) C_DestroyObject(hSession, pubKey); 1642 if (priKey != CK_INVALID_HANDLE) 1643 (void) C_DestroyObject(hSession, priKey); 1644 if (privkey) { 1645 privkey->keyp = NULL; 1646 if (privkey->keylabel) 1647 free(privkey->keylabel); 1648 } 1649 if (pubkey) { 1650 pubkey->keyp = NULL; 1651 if (pubkey->keylabel) 1652 free(pubkey->keylabel); 1653 } 1654 } 1655 return (rv); 1656 } 1657 1658 KMF_RETURN 1659 KMFPK11_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params, 1660 KMF_KEY_HANDLE *key, boolean_t destroy) 1661 { 1662 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1663 CK_RV ckrv = CKR_OK; 1664 KMF_RETURN rv = KMF_OK; 1665 1666 if (!kmfh) 1667 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 1668 1669 if (kmfh->pk11handle == CK_INVALID_HANDLE) 1670 return (KMF_ERR_NO_TOKEN_SELECTED); 1671 1672 if (key == NULL || key->keyp == NULL) 1673 return (KMF_ERR_BAD_PARAMETER); 1674 1675 if (key->keyclass != KMF_ASYM_PUB && 1676 key->keyclass != KMF_ASYM_PRI && 1677 key->keyclass != KMF_SYMMETRIC) 1678 return (KMF_ERR_BAD_KEY_CLASS); 1679 1680 if (destroy) { 1681 rv = pk11_authenticate(handle, ¶ms->cred); 1682 if (rv != KMF_OK) { 1683 return (rv); 1684 } 1685 } 1686 1687 if (!key->israw && destroy) 1688 ckrv = C_DestroyObject(kmfh->pk11handle, 1689 (CK_OBJECT_HANDLE)key->keyp); 1690 1691 if (ckrv != CKR_OK) { 1692 SET_ERROR(kmfh, ckrv); 1693 /* Report authentication failures to the caller */ 1694 if (ckrv == CKR_PIN_EXPIRED || 1695 ckrv == CKR_SESSION_READ_ONLY) 1696 rv = KMF_ERR_AUTH_FAILED; 1697 else 1698 rv = KMF_ERR_INTERNAL; 1699 } 1700 return (rv); 1701 1702 } 1703 1704 KMF_RETURN 1705 KMFPK11_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp, 1706 KMF_OID *algOID, 1707 KMF_DATA *tobesigned, 1708 KMF_DATA *output) 1709 { 1710 CK_RV ckrv; 1711 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1712 CK_SESSION_HANDLE hSession = kmfh->pk11handle; 1713 CK_MECHANISM mechanism; 1714 PKCS_ALGORITHM_MAP *pAlgMap; 1715 KMF_ALGORITHM_INDEX AlgId; 1716 1717 if (!kmfh) 1718 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 1719 1720 if (kmfh->pk11handle == CK_INVALID_HANDLE) 1721 return (KMF_ERR_NO_TOKEN_SELECTED); 1722 1723 if (keyp == NULL || algOID == NULL || 1724 tobesigned == NULL || output == NULL) 1725 return (KMF_ERR_BAD_PARAMETER); 1726 1727 /* These functions are available to the plugin from libkmf */ 1728 AlgId = X509_AlgorithmOidToAlgId(algOID); 1729 if (AlgId == KMF_ALGID_NONE) 1730 return (KMF_ERR_BAD_PARAMETER); 1731 1732 /* Map the Algorithm OID to a PKCS#11 mechanism */ 1733 pAlgMap = PKCS_GetAlgorithmMap(KMF_ALGCLASS_SIGNATURE, 1734 AlgId, PKCS_GetDefaultSignatureMode(AlgId)); 1735 1736 if (pAlgMap == NULL) 1737 return (KMF_ERR_BAD_PARAMETER); 1738 1739 mechanism.mechanism = pAlgMap->pkcs_mechanism; 1740 mechanism.pParameter = NULL; 1741 mechanism.ulParameterLen = 0; 1742 1743 ckrv = C_SignInit(hSession, &mechanism, (CK_OBJECT_HANDLE)keyp->keyp); 1744 if (ckrv != CKR_OK) { 1745 SET_ERROR(kmfh, ckrv); 1746 return (KMF_ERR_INTERNAL); 1747 } 1748 1749 ckrv = C_Sign(hSession, 1750 tobesigned->Data, tobesigned->Length, 1751 output->Data, (CK_ULONG *)&output->Length); 1752 1753 if (ckrv != CKR_OK) { 1754 SET_ERROR(kmfh, ckrv); 1755 return (KMF_ERR_INTERNAL); 1756 } 1757 1758 return (KMF_OK); 1759 } 1760 1761 KMF_RETURN 1762 KMFPK11_GetErrorString(KMF_HANDLE_T handle, char **msgstr) 1763 { 1764 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1765 1766 *msgstr = NULL; 1767 if (kmfh->lasterr.errcode != 0) { 1768 char *e = pkcs11_strerror(kmfh->lasterr.errcode); 1769 if (e == NULL || (*msgstr = (char *)strdup(e)) == NULL) { 1770 return (KMF_ERR_MEMORY); 1771 } 1772 } 1773 1774 return (KMF_OK); 1775 } 1776 1777 static CK_RV 1778 getObjectKeytype(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj, 1779 CK_ULONG *keytype) 1780 { 1781 CK_RV rv = CKR_OK; 1782 CK_ATTRIBUTE templ; 1783 CK_ULONG len = sizeof (CK_ULONG); 1784 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1785 1786 templ.type = CKA_KEY_TYPE; 1787 templ.pValue = keytype; 1788 templ.ulValueLen = len; 1789 1790 rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1); 1791 1792 return (rv); 1793 1794 } 1795 static CK_RV 1796 getObjectLabel(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj, 1797 char **outlabel) 1798 { 1799 CK_RV rv = CKR_OK; 1800 CK_ATTRIBUTE templ; 1801 char Label[BUFSIZ]; 1802 CK_ULONG len = sizeof (Label); 1803 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1804 1805 (void) memset(Label, 0, len); 1806 templ.type = CKA_LABEL; 1807 templ.pValue = Label; 1808 templ.ulValueLen = len; 1809 1810 rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1); 1811 if (rv == CKR_OK) { 1812 *outlabel = (char *)strdup(Label); 1813 } else { 1814 *outlabel = NULL; 1815 } 1816 return (rv); 1817 } 1818 1819 KMF_RETURN 1820 KMFPK11_GetPrikeyByCert(KMF_HANDLE_T handle, 1821 KMF_CRYPTOWITHCERT_PARAMS *params, 1822 KMF_DATA *SignerCertData, KMF_KEY_HANDLE *key, 1823 KMF_KEY_ALG keytype) 1824 { 1825 KMF_X509_SPKI *pubkey; 1826 KMF_X509_CERTIFICATE *SignerCert = NULL; 1827 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1828 KMF_RETURN rv = KMF_OK; 1829 CK_RV ckrv = CKR_OK; 1830 CK_ATTRIBUTE templ[4]; 1831 CK_OBJECT_HANDLE pri_obj = CK_INVALID_HANDLE; 1832 CK_ULONG obj_count; 1833 CK_OBJECT_CLASS certClass = CKO_PRIVATE_KEY; 1834 CK_BBOOL true = TRUE; 1835 KMF_DATA Id = { NULL, 0 }; 1836 1837 /* Decode the signer cert so we can get the SPKI data */ 1838 if ((rv = DerDecodeSignedCertificate(SignerCertData, 1839 &SignerCert)) != KMF_OK) 1840 return (rv); 1841 1842 /* Get the public key info from the signer certificate */ 1843 pubkey = &SignerCert->certificate.subjectPublicKeyInfo; 1844 1845 /* Generate an ID from the SPKI data */ 1846 rv = GetIDFromSPKI(pubkey, &Id); 1847 1848 if (rv != KMF_OK) { 1849 SET_ERROR(kmfh, rv); 1850 goto errout; 1851 } 1852 1853 SETATTR(templ, 0, CKA_CLASS, &certClass, sizeof (certClass)); 1854 SETATTR(templ, 1, CKA_TOKEN, &true, sizeof (true)); 1855 SETATTR(templ, 2, CKA_PRIVATE, &true, sizeof (true)); 1856 SETATTR(templ, 3, CKA_ID, Id.Data, Id.Length); 1857 1858 rv = pk11_authenticate(handle, ¶ms->cred); 1859 if (rv != KMF_OK) { 1860 return (rv); 1861 } 1862 1863 if ((ckrv = C_FindObjectsInit(kmfh->pk11handle, templ, 4)) != CKR_OK) { 1864 SET_ERROR(kmfh, ckrv); 1865 rv = KMF_ERR_INTERNAL; 1866 goto errout; 1867 } 1868 1869 if ((rv = C_FindObjects(kmfh->pk11handle, &pri_obj, 1, 1870 &obj_count)) != CKR_OK) { 1871 SET_ERROR(kmfh, ckrv); 1872 rv = KMF_ERR_INTERNAL; 1873 goto errout; 1874 } 1875 1876 if (obj_count == 0) { 1877 SET_ERROR(kmfh, ckrv); 1878 rv = KMF_ERR_INTERNAL; 1879 goto errout; 1880 } 1881 1882 key->kstype = KMF_KEYSTORE_PK11TOKEN; 1883 key->keyclass = KMF_ASYM_PRI; 1884 key->keyalg = keytype; 1885 key->keyp = (void *)pri_obj; 1886 1887 (void) C_FindObjectsFinal(kmfh->pk11handle); 1888 1889 ckrv = getObjectLabel(handle, (CK_OBJECT_HANDLE)key->keyp, 1890 &key->keylabel); 1891 1892 if (ckrv != CKR_OK) { 1893 SET_ERROR(handle, ckrv); 1894 rv = KMF_ERR_INTERNAL; 1895 } else { 1896 rv = KMF_OK; 1897 } 1898 1899 if (rv == KMF_OK && params->format == KMF_FORMAT_RAWKEY) { 1900 KMF_RAW_KEY_DATA *rkey = NULL; 1901 rv = keyObj2RawKey(handle, key, &rkey); 1902 if (rv == KMF_OK) { 1903 key->keyp = rkey; 1904 key->israw = TRUE; 1905 } 1906 } 1907 1908 errout: 1909 if (Id.Data != NULL) 1910 free(Id.Data); 1911 1912 if (SignerCert != NULL) { 1913 KMF_FreeSignedCert(SignerCert); 1914 free(SignerCert); 1915 } 1916 return (rv); 1917 } 1918 1919 KMF_RETURN 1920 KMFPK11_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 1921 KMF_OID *algOID, KMF_DATA *ciphertext, 1922 KMF_DATA *output) 1923 { 1924 CK_RV ckrv; 1925 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1926 CK_SESSION_HANDLE hSession = kmfh->pk11handle; 1927 CK_MECHANISM mechanism; 1928 PKCS_ALGORITHM_MAP *pAlgMap; 1929 KMF_ALGORITHM_INDEX AlgId; 1930 CK_ULONG out_len = 0, block_len = 0, total_decrypted = 0; 1931 uint8_t *in_data, *out_data; 1932 int i, blocks; 1933 CK_ATTRIBUTE ckTemplate[1]; 1934 1935 if (!kmfh) 1936 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 1937 1938 if (kmfh->pk11handle == CK_INVALID_HANDLE) 1939 return (KMF_ERR_NO_TOKEN_SELECTED); 1940 1941 if (key == NULL || algOID == NULL || 1942 ciphertext == NULL || output == NULL) 1943 return (KMF_ERR_BAD_PARAMETER); 1944 1945 AlgId = X509_AlgorithmOidToAlgId(algOID); 1946 if (AlgId == KMF_ALGID_NONE) 1947 return (KMF_ERR_BAD_PARAMETER); 1948 1949 /* Map the Algorithm ID to a PKCS#11 mechanism */ 1950 pAlgMap = PKCS_GetAlgorithmMap(KMF_ALGCLASS_SIGNATURE, 1951 AlgId, PKCS_GetDefaultSignatureMode(AlgId)); 1952 1953 if (pAlgMap == NULL) 1954 return (KMF_ERR_BAD_PARAMETER); 1955 1956 mechanism.mechanism = pAlgMap->pkcs_mechanism; 1957 mechanism.pParameter = NULL; 1958 mechanism.ulParameterLen = 0; 1959 1960 SETATTR(ckTemplate, 0, CKA_MODULUS, (CK_BYTE *)NULL, 1961 sizeof (CK_ULONG)); 1962 1963 /* Get the modulus length */ 1964 ckrv = C_GetAttributeValue(hSession, 1965 (CK_OBJECT_HANDLE)key->keyp, ckTemplate, 1); 1966 1967 if (ckrv != CKR_OK) { 1968 SET_ERROR(kmfh, ckrv); 1969 return (KMF_ERR_INTERNAL); 1970 } 1971 1972 block_len = ckTemplate[0].ulValueLen; 1973 1974 /* Compute the number of times to do single-part decryption */ 1975 blocks = ciphertext->Length/block_len; 1976 1977 out_data = output->Data; 1978 in_data = ciphertext->Data; 1979 out_len = block_len - 11; 1980 1981 for (i = 0; i < blocks; i++) { 1982 ckrv = C_DecryptInit(hSession, &mechanism, 1983 (CK_OBJECT_HANDLE)key->keyp); 1984 1985 if (ckrv != CKR_OK) { 1986 SET_ERROR(kmfh, ckrv); 1987 return (KMF_ERR_INTERNAL); 1988 } 1989 1990 ckrv = C_Decrypt(hSession, in_data, block_len, 1991 out_data, (CK_ULONG *)&out_len); 1992 1993 if (ckrv != CKR_OK) { 1994 SET_ERROR(kmfh, ckrv); 1995 return (KMF_ERR_INTERNAL); 1996 } 1997 1998 out_data += out_len; 1999 total_decrypted += out_len; 2000 in_data += block_len; 2001 2002 } 2003 2004 output->Length = total_decrypted; 2005 return (KMF_OK); 2006 } 2007 2008 static void 2009 attr2bigint(CK_ATTRIBUTE_PTR attr, KMF_BIGINT *big) 2010 { 2011 big->val = attr->pValue; 2012 big->len = attr->ulValueLen; 2013 } 2014 2015 2016 static KMF_RETURN 2017 get_raw_rsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_RSA_KEY *rawrsa) 2018 { 2019 KMF_RETURN rv = KMF_OK; 2020 CK_RV ckrv; 2021 CK_SESSION_HANDLE sess = kmfh->pk11handle; 2022 CK_ATTRIBUTE rsa_pri_attrs[8] = { 2023 { CKA_MODULUS, NULL, 0 }, 2024 { CKA_PUBLIC_EXPONENT, NULL, 0 }, 2025 { CKA_PRIVATE_EXPONENT, NULL, 0 }, /* optional */ 2026 { CKA_PRIME_1, NULL, 0 }, /* | */ 2027 { CKA_PRIME_2, NULL, 0 }, /* | */ 2028 { CKA_EXPONENT_1, NULL, 0 }, /* | */ 2029 { CKA_EXPONENT_2, NULL, 0 }, /* | */ 2030 { CKA_COEFFICIENT, NULL, 0 } /* V */ 2031 }; 2032 CK_ULONG count = sizeof (rsa_pri_attrs) / sizeof (CK_ATTRIBUTE); 2033 int i; 2034 2035 if ((ckrv = C_GetAttributeValue(sess, obj, 2036 rsa_pri_attrs, count)) != CKR_OK) { 2037 SET_ERROR(kmfh, ckrv); 2038 /* Tell the caller know why the key data cannot be retrieved. */ 2039 if (ckrv == CKR_ATTRIBUTE_SENSITIVE) 2040 return (KMF_ERR_SENSITIVE_KEY); 2041 else if (ckrv == CKR_KEY_UNEXTRACTABLE) 2042 return (KMF_ERR_UNEXTRACTABLE_KEY); 2043 else 2044 return (KMF_ERR_INTERNAL); 2045 } 2046 2047 /* Allocate memory for each attribute. */ 2048 for (i = 0; i < count; i++) { 2049 if (rsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 || 2050 rsa_pri_attrs[i].ulValueLen == 0) { 2051 rsa_pri_attrs[i].ulValueLen = 0; 2052 continue; 2053 } 2054 if ((rsa_pri_attrs[i].pValue = 2055 malloc(rsa_pri_attrs[i].ulValueLen)) == NULL) { 2056 rv = KMF_ERR_MEMORY; 2057 goto end; 2058 } 2059 } 2060 /* Now that we have space, really get the attributes */ 2061 if ((rv = C_GetAttributeValue(sess, obj, 2062 rsa_pri_attrs, count)) != CKR_OK) { 2063 SET_ERROR(kmfh, rv); 2064 rv = KMF_ERR_INTERNAL; 2065 goto end; 2066 } 2067 i = 0; 2068 attr2bigint(&(rsa_pri_attrs[i++]), &rawrsa->mod); 2069 attr2bigint(&(rsa_pri_attrs[i++]), &rawrsa->pubexp); 2070 2071 if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 && 2072 rsa_pri_attrs[i].ulValueLen != 0) 2073 attr2bigint(&(rsa_pri_attrs[i]), &rawrsa->priexp); 2074 i++; 2075 2076 if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 && 2077 rsa_pri_attrs[i].ulValueLen != 0) 2078 attr2bigint(&(rsa_pri_attrs[i]), &rawrsa->prime1); 2079 i++; 2080 2081 if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 && 2082 rsa_pri_attrs[i].ulValueLen != 0) 2083 attr2bigint(&(rsa_pri_attrs[i]), &rawrsa->prime2); 2084 i++; 2085 2086 if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 && 2087 rsa_pri_attrs[i].ulValueLen != 0) 2088 attr2bigint(&(rsa_pri_attrs[i]), &rawrsa->exp1); 2089 i++; 2090 2091 if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 && 2092 rsa_pri_attrs[i].ulValueLen != 0) 2093 attr2bigint(&(rsa_pri_attrs[i]), &rawrsa->exp2); 2094 i++; 2095 2096 if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 && 2097 rsa_pri_attrs[i].ulValueLen != 0) 2098 attr2bigint(&(rsa_pri_attrs[i]), &rawrsa->coef); 2099 i++; 2100 2101 end: 2102 if (rv != KMF_OK) { 2103 for (i = 0; i < count; i++) { 2104 if (rsa_pri_attrs[i].pValue != NULL) 2105 free(rsa_pri_attrs[i].pValue); 2106 } 2107 (void) memset(rawrsa, 0, sizeof (KMF_RAW_RSA_KEY)); 2108 } 2109 return (rv); 2110 } 2111 2112 static KMF_RETURN 2113 get_raw_dsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_DSA_KEY *rawdsa) 2114 { 2115 KMF_RETURN rv = KMF_OK; 2116 CK_SESSION_HANDLE sess = kmfh->pk11handle; 2117 CK_ATTRIBUTE dsa_pri_attrs[8] = { 2118 { CKA_PRIME, NULL, 0 }, 2119 { CKA_SUBPRIME, NULL, 0 }, 2120 { CKA_BASE, NULL, 0 }, 2121 { CKA_VALUE, NULL, 0 } 2122 }; 2123 CK_ULONG count = sizeof (dsa_pri_attrs) / sizeof (CK_ATTRIBUTE); 2124 int i; 2125 2126 if ((rv = C_GetAttributeValue(sess, obj, 2127 dsa_pri_attrs, count)) != CKR_OK) { 2128 SET_ERROR(kmfh, rv); 2129 return (KMF_ERR_INTERNAL); 2130 } 2131 2132 /* Allocate memory for each attribute. */ 2133 for (i = 0; i < count; i++) { 2134 if (dsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 || 2135 dsa_pri_attrs[i].ulValueLen == 0) { 2136 dsa_pri_attrs[i].ulValueLen = 0; 2137 continue; 2138 } 2139 if ((dsa_pri_attrs[i].pValue = 2140 malloc(dsa_pri_attrs[i].ulValueLen)) == NULL) { 2141 rv = KMF_ERR_MEMORY; 2142 goto end; 2143 } 2144 } 2145 if ((rv = C_GetAttributeValue(sess, obj, 2146 dsa_pri_attrs, count)) != CKR_OK) { 2147 SET_ERROR(kmfh, rv); 2148 rv = KMF_ERR_INTERNAL; 2149 goto end; 2150 } 2151 2152 /* Fill in all the temp variables. They are all required. */ 2153 i = 0; 2154 attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->prime); 2155 attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->subprime); 2156 attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->base); 2157 attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->value); 2158 2159 end: 2160 if (rv != KMF_OK) { 2161 for (i = 0; i < count; i++) { 2162 if (dsa_pri_attrs[i].pValue != NULL) 2163 free(dsa_pri_attrs[i].pValue); 2164 } 2165 (void) memset(rawdsa, 0, sizeof (KMF_RAW_DSA_KEY)); 2166 } 2167 return (rv); 2168 } 2169 2170 static KMF_RETURN 2171 get_raw_sym(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_SYM_KEY *rawsym) 2172 { 2173 KMF_RETURN rv = KMF_OK; 2174 CK_RV ckrv; 2175 CK_SESSION_HANDLE sess = kmfh->pk11handle; 2176 CK_ATTRIBUTE sym_attr[1]; 2177 CK_ULONG value_len = 0; 2178 2179 /* find the key length first */ 2180 sym_attr[0].type = CKA_VALUE; 2181 sym_attr[0].pValue = NULL; 2182 sym_attr[0].ulValueLen = value_len; 2183 if ((ckrv = C_GetAttributeValue(sess, obj, sym_attr, 1)) != CKR_OK) { 2184 /* 2185 * Don't return error if the key is sensitive, just 2186 * don't return any raw data. Operations like "list" 2187 * need to succeed even if the raw data is not 2188 * available. 2189 */ 2190 if (ckrv == CKR_ATTRIBUTE_SENSITIVE) { 2191 rawsym->keydata.val = NULL; 2192 rawsym->keydata.len = 0; 2193 return (CKR_OK); 2194 } 2195 SET_ERROR(kmfh, ckrv); 2196 return (KMF_ERR_INTERNAL); 2197 } 2198 2199 /* Allocate memory for pValue */ 2200 sym_attr[0].pValue = malloc(sym_attr[0].ulValueLen); 2201 if (sym_attr[0].pValue == NULL) { 2202 return (KMF_ERR_MEMORY); 2203 } 2204 2205 /* get the key data */ 2206 if ((rv = C_GetAttributeValue(sess, obj, sym_attr, 1)) != CKR_OK) { 2207 SET_ERROR(kmfh, rv); 2208 free(sym_attr[0].pValue); 2209 return (KMF_ERR_INTERNAL); 2210 } 2211 2212 rawsym->keydata.val = sym_attr[0].pValue; 2213 rawsym->keydata.len = sym_attr[0].ulValueLen; 2214 return (rv); 2215 } 2216 2217 static KMF_RETURN 2218 keyObj2RawKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *inkey, 2219 KMF_RAW_KEY_DATA **outkey) 2220 { 2221 KMF_RETURN rv = KMF_OK; 2222 KMF_RAW_KEY_DATA *rkey; 2223 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2224 2225 rkey = malloc(sizeof (KMF_RAW_KEY_DATA)); 2226 if (rkey == NULL) 2227 return (KMF_ERR_MEMORY); 2228 2229 (void) memset(rkey, 0, sizeof (KMF_RAW_KEY_DATA)); 2230 2231 rkey->keytype = inkey->keyalg; 2232 2233 if (inkey->keyalg == KMF_RSA) { 2234 rv = get_raw_rsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp, 2235 &rkey->rawdata.rsa); 2236 } else if (inkey->keyalg == KMF_DSA) { 2237 rv = get_raw_dsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp, 2238 &rkey->rawdata.dsa); 2239 } else if (inkey->keyalg == KMF_AES || 2240 inkey->keyalg == KMF_RC4 || 2241 inkey->keyalg == KMF_DES || 2242 inkey->keyalg == KMF_DES3 || 2243 inkey->keyalg == KMF_GENERIC_SECRET) { 2244 rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)inkey->keyp, 2245 &rkey->rawdata.sym); 2246 } else { 2247 rv = KMF_ERR_BAD_PARAMETER; 2248 } 2249 2250 if (rv == KMF_OK) { 2251 *outkey = rkey; 2252 } else if (rkey != NULL) { 2253 free(rkey); 2254 *outkey = NULL; 2255 } 2256 2257 return (rv); 2258 } 2259 2260 2261 static KMF_RETURN 2262 kmf2pk11keytype(KMF_KEY_ALG keyalg, CK_KEY_TYPE *type) 2263 { 2264 switch (keyalg) { 2265 case KMF_RSA: 2266 *type = CKK_RSA; 2267 break; 2268 case KMF_DSA: 2269 *type = CKK_DSA; 2270 break; 2271 case KMF_AES: 2272 *type = CKK_AES; 2273 break; 2274 case KMF_RC4: 2275 *type = CKK_RC4; 2276 break; 2277 case KMF_DES: 2278 *type = CKK_DES; 2279 break; 2280 case KMF_DES3: 2281 *type = CKK_DES3; 2282 break; 2283 case KMF_GENERIC_SECRET: 2284 *type = CKK_GENERIC_SECRET; 2285 break; 2286 default: 2287 return (KMF_ERR_BAD_KEY_TYPE); 2288 } 2289 2290 return (KMF_OK); 2291 } 2292 2293 static int 2294 IDStringToData(char *idstr, KMF_DATA *iddata) 2295 { 2296 int len, i; 2297 char *iddup, *byte; 2298 uint_t lvalue; 2299 2300 if (idstr == NULL || !strlen(idstr)) 2301 return (-1); 2302 2303 iddup = (char *)strdup(idstr); 2304 if (iddup == NULL) 2305 return (KMF_ERR_MEMORY); 2306 2307 len = strlen(iddup) / 3 + 1; 2308 iddata->Data = malloc(len); 2309 if (iddata->Data == NULL) 2310 return (KMF_ERR_MEMORY); 2311 (void) memset(iddata->Data, 0, len); 2312 iddata->Length = len; 2313 2314 byte = strtok(iddup, ":"); 2315 if (byte == NULL) { 2316 free(iddup); 2317 free(iddata->Data); 2318 iddata->Data = NULL; 2319 iddata->Length = 0; 2320 return (-1); 2321 } 2322 2323 i = 0; 2324 do { 2325 (void) sscanf(byte, "%x", &lvalue); 2326 iddata->Data[i++] = (uchar_t)(lvalue & 0x000000FF); 2327 byte = strtok(NULL, ":"); 2328 } while (byte != NULL && i < len); 2329 2330 iddata->Length = i; 2331 free(iddup); 2332 return (0); 2333 } 2334 2335 KMF_RETURN 2336 KMFPK11_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, 2337 KMF_KEY_HANDLE *keys, uint32_t *numkeys) 2338 { 2339 KMF_RETURN rv = KMF_OK; 2340 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2341 uint32_t want_keys, i; 2342 CK_RV ckrv; 2343 CK_ATTRIBUTE pTmpl[10]; 2344 CK_OBJECT_CLASS class; 2345 CK_BBOOL true = TRUE; 2346 CK_ULONG alg; 2347 CK_BBOOL is_token; 2348 2349 if (!kmfh) 2350 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 2351 2352 if (kmfh->pk11handle == CK_INVALID_HANDLE) 2353 return (KMF_ERR_NO_TOKEN_SELECTED); 2354 2355 if (parms == NULL || numkeys == NULL) 2356 return (KMF_ERR_BAD_PARAMETER); 2357 2358 if (numkeys != NULL && *numkeys > 0) 2359 want_keys = *numkeys; 2360 else 2361 want_keys = MAXINT; /* count them all */ 2362 2363 is_token = parms->pkcs11parms.token; 2364 if (parms->keyclass == KMF_ASYM_PUB) { 2365 class = CKO_PUBLIC_KEY; 2366 } else if (parms->keyclass == KMF_ASYM_PRI) { 2367 class = CKO_PRIVATE_KEY; 2368 } else if (parms->keyclass == KMF_SYMMETRIC) { 2369 class = CKO_SECRET_KEY; 2370 } else { 2371 return (KMF_ERR_BAD_KEY_CLASS); 2372 } 2373 2374 i = 0; 2375 pTmpl[i].type = CKA_TOKEN; 2376 pTmpl[i].pValue = &is_token; 2377 pTmpl[i].ulValueLen = sizeof (CK_BBOOL); 2378 i++; 2379 2380 pTmpl[i].type = CKA_CLASS; 2381 pTmpl[i].pValue = &class; 2382 pTmpl[i].ulValueLen = sizeof (class); 2383 i++; 2384 2385 if (parms->findLabel != NULL && strlen(parms->findLabel)) { 2386 pTmpl[i].type = CKA_LABEL; 2387 pTmpl[i].pValue = parms->findLabel; 2388 pTmpl[i].ulValueLen = strlen(parms->findLabel); 2389 i++; 2390 } 2391 2392 if (parms->keytype != 0) { 2393 rv = kmf2pk11keytype(parms->keytype, &alg); 2394 if (rv != KMF_OK) { 2395 return (KMF_ERR_BAD_KEY_TYPE); 2396 } 2397 pTmpl[i].type = CKA_KEY_TYPE; 2398 pTmpl[i].pValue = &alg; 2399 pTmpl[i].ulValueLen = sizeof (alg); 2400 i++; 2401 } 2402 2403 if (parms->idstr != NULL) { 2404 KMF_DATA iddata = { NULL, 0 }; 2405 2406 /* 2407 * ID String parameter is assumed to be of form: 2408 * XX:XX:XX:XX:XX ... :XX 2409 * where XX is a hex number. 2410 * 2411 * We must convert this back to binary in order to 2412 * use it in a search. 2413 */ 2414 rv = IDStringToData(parms->idstr, &iddata); 2415 if (rv == KMF_OK) { 2416 pTmpl[i].type = CKA_ID; 2417 pTmpl[i].pValue = iddata.Data; 2418 pTmpl[i].ulValueLen = iddata.Length; 2419 i++; 2420 } else { 2421 return (rv); 2422 } 2423 } 2424 2425 if (parms->pkcs11parms.private) { 2426 pTmpl[i].type = CKA_PRIVATE; 2427 pTmpl[i].pValue = &true; 2428 pTmpl[i].ulValueLen = sizeof (true); 2429 i++; 2430 } 2431 2432 /* 2433 * Authenticate if the object is a token object, 2434 * a private or secred key, or if the user passed in credentials. 2435 */ 2436 if (parms->cred.credlen > 0) { 2437 rv = pk11_authenticate(handle, &parms->cred); 2438 if (rv != KMF_OK) { 2439 return (rv); 2440 } 2441 } 2442 2443 ckrv = C_FindObjectsInit(kmfh->pk11handle, pTmpl, i); 2444 if (ckrv == CKR_OK) { 2445 CK_ULONG obj_count, n = 0; 2446 while (ckrv == CKR_OK && n < want_keys) { 2447 CK_OBJECT_HANDLE hObj; 2448 2449 ckrv = C_FindObjects(kmfh->pk11handle, &hObj, 2450 1, &obj_count); 2451 if (ckrv == CKR_OK && obj_count == 1) { 2452 if (keys != NULL) { 2453 CK_ULONG keytype; 2454 keys[n].kstype = KMF_KEYSTORE_PK11TOKEN; 2455 keys[n].keyclass = parms->keyclass; 2456 keys[n].israw = FALSE; 2457 keys[n].keyp = (void *)hObj; 2458 2459 ckrv = getObjectKeytype(handle, 2460 (CK_OBJECT_HANDLE)keys[n].keyp, 2461 &keytype); 2462 if (ckrv != CKR_OK) 2463 goto end; 2464 2465 ckrv = getObjectLabel(handle, 2466 (CK_OBJECT_HANDLE)keys[n].keyp, 2467 &(keys[n].keylabel)); 2468 if (ckrv != CKR_OK) 2469 goto end; 2470 2471 if (keytype == CKK_RSA) 2472 keys[n].keyalg = KMF_RSA; 2473 else if (keytype == CKK_DSA) 2474 keys[n].keyalg = KMF_DSA; 2475 else if (keytype == CKK_AES) 2476 keys[n].keyalg = KMF_AES; 2477 else if (keytype == CKK_RC4) 2478 keys[n].keyalg = KMF_RC4; 2479 else if (keytype == CKK_DES) 2480 keys[n].keyalg = KMF_DES; 2481 else if (keytype == CKK_DES3) 2482 keys[n].keyalg = KMF_DES3; 2483 else if (keytype == CKK_GENERIC_SECRET) 2484 keys[n].keyalg = 2485 KMF_GENERIC_SECRET; 2486 2487 } 2488 n++; 2489 } else { 2490 break; 2491 } 2492 } 2493 ckrv = C_FindObjectsFinal(kmfh->pk11handle); 2494 2495 /* "numkeys" indicates the number that were actually found */ 2496 *numkeys = n; 2497 } 2498 if (ckrv == KMF_OK && keys != NULL && (*numkeys) > 0) { 2499 if (parms->format == KMF_FORMAT_RAWKEY) { 2500 /* Convert keys to "rawkey" format */ 2501 for (i = 0; i < (*numkeys); i++) { 2502 KMF_RAW_KEY_DATA *rkey = NULL; 2503 rv = keyObj2RawKey(handle, &keys[i], &rkey); 2504 if (rv == KMF_OK) { 2505 keys[i].keyp = rkey; 2506 keys[i].israw = TRUE; 2507 } else { 2508 break; 2509 } 2510 } 2511 } 2512 } 2513 end: 2514 if (ckrv != CKR_OK) { 2515 SET_ERROR(kmfh, ckrv); 2516 /* Report authentication failures to the caller */ 2517 if (ckrv == CKR_USER_NOT_LOGGED_IN || 2518 ckrv == CKR_PIN_INCORRECT || 2519 ckrv == CKR_PIN_INVALID || 2520 ckrv == CKR_PIN_EXPIRED || 2521 ckrv == CKR_PIN_LOCKED || 2522 ckrv == CKR_SESSION_READ_ONLY) 2523 rv = KMF_ERR_AUTH_FAILED; 2524 else 2525 rv = KMF_ERR_INTERNAL; 2526 } else if ((*numkeys) == 0) { 2527 rv = KMF_ERR_KEY_NOT_FOUND; 2528 } 2529 2530 return (rv); 2531 } 2532 2533 static char * 2534 convertDate(char *fulldate) 2535 { 2536 struct tm tms; 2537 char newtime[9]; 2538 2539 (void) strptime(fulldate, "%b %d %T %Y %Z", &tms); 2540 2541 if (tms.tm_year < 69) 2542 tms.tm_year += 100; 2543 2544 (void) strftime(newtime, sizeof (newtime), "m%d", &tms); 2545 2546 newtime[8] = 0; 2547 2548 /* memory returned must be freed by the caller */ 2549 return ((char *)strdup(newtime)); 2550 } 2551 2552 KMF_RETURN 2553 KMFPK11_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, 2554 KMF_RAW_KEY_DATA *rawkey) 2555 { 2556 KMF_RETURN rv = KMF_OK; 2557 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2558 int i; 2559 CK_RV ckrv = CKR_OK; 2560 CK_ATTRIBUTE templ[32]; 2561 CK_OBJECT_HANDLE keyobj; 2562 CK_KEY_TYPE keytype; 2563 CK_OBJECT_CLASS oClass = CKO_PRIVATE_KEY; 2564 CK_BBOOL cktrue = TRUE; 2565 CK_DATE startdate, enddate; 2566 KMF_DATA id = {NULL, 0}; 2567 KMF_DATA subject = {NULL, 0}; 2568 KMF_X509EXT_KEY_USAGE kuext; 2569 KMF_X509_CERTIFICATE *x509 = NULL; 2570 CK_BBOOL kufound; 2571 char *notbefore = NULL, *start = NULL; 2572 char *notafter = NULL, *end = NULL; 2573 2574 if (!kmfh) 2575 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 2576 2577 if (kmfh->pk11handle == CK_INVALID_HANDLE) 2578 return (KMF_ERR_NO_TOKEN_SELECTED); 2579 2580 if (params == NULL || params->certificate == NULL || 2581 rawkey == NULL) 2582 return (KMF_ERR_BAD_PARAMETER); 2583 2584 if (rawkey->keytype == KMF_RSA) 2585 keytype = CKK_RSA; 2586 else if (rawkey->keytype == KMF_DSA) 2587 keytype = CKK_DSA; 2588 else 2589 return (KMF_ERR_BAD_PARAMETER); 2590 2591 rv = pk11_authenticate(handle, ¶ms->cred); 2592 if (rv != KMF_OK) { 2593 return (rv); 2594 } 2595 2596 id.Data = NULL; 2597 id.Length = 0; 2598 rv = KMF_GetCertIDData(params->certificate, &id); 2599 if (rv != KMF_OK) { 2600 goto cleanup; 2601 } 2602 2603 rv = DerDecodeSignedCertificate( 2604 (const KMF_DATA *)params->certificate, &x509); 2605 if (rv != KMF_OK) { 2606 goto cleanup; 2607 } 2608 2609 rv = DerEncodeName(&x509->certificate.subject, &subject); 2610 if (rv != KMF_OK) { 2611 goto cleanup; 2612 } 2613 2614 rv = KMF_GetCertStartDateString(handle, params->certificate, 2615 ¬before); 2616 if (rv != KMF_OK) { 2617 goto cleanup; 2618 } 2619 start = convertDate(notbefore); 2620 2621 rv = KMF_GetCertEndDateString(handle, params->certificate, 2622 ¬after); 2623 if (rv != KMF_OK) { 2624 goto cleanup; 2625 } 2626 end = convertDate(notafter); 2627 2628 if ((rv = KMF_GetCertKeyUsageExt(params->certificate, &kuext)) 2629 != KMF_OK && rv != KMF_ERR_EXTENSION_NOT_FOUND) 2630 goto cleanup; 2631 2632 kufound = (rv == KMF_OK); 2633 rv = KMF_OK; /* reset if we got KMF_ERR_EXTENSION_NOT_FOUND above */ 2634 2635 i = 0; 2636 SETATTR(templ, i, CKA_CLASS, &oClass, sizeof (CK_OBJECT_CLASS)); i++; 2637 SETATTR(templ, i, CKA_KEY_TYPE, &keytype, sizeof (keytype)); i++; 2638 SETATTR(templ, i, CKA_TOKEN, &cktrue, sizeof (cktrue)); i++; 2639 SETATTR(templ, i, CKA_PRIVATE, &cktrue, sizeof (cktrue)); i++; 2640 SETATTR(templ, i, CKA_SUBJECT, subject.Data, subject.Length); i++; 2641 SETATTR(templ, i, CKA_DECRYPT, &cktrue, sizeof (cktrue)); i++; 2642 2643 /* 2644 * Only set the KeyUsage stuff if the KU extension was present. 2645 */ 2646 if (kufound) { 2647 CK_BBOOL condition; 2648 2649 condition = (kuext.KeyUsageBits & KMF_keyEncipherment) ? 2650 B_TRUE : B_FALSE; 2651 SETATTR(templ, i, CKA_UNWRAP, &condition, 2652 sizeof (CK_BBOOL)); i++; 2653 condition = (kuext.KeyUsageBits & KMF_dataEncipherment) ? 2654 B_TRUE : B_FALSE; 2655 SETATTR(templ, i, CKA_DECRYPT, &condition, 2656 sizeof (CK_BBOOL)); i++; 2657 condition = (kuext.KeyUsageBits & KMF_digitalSignature) ? 2658 B_TRUE : B_FALSE; 2659 SETATTR(templ, i, CKA_SIGN, &condition, 2660 sizeof (CK_BBOOL)); i++; 2661 condition = (kuext.KeyUsageBits & KMF_digitalSignature) ? 2662 B_TRUE : B_FALSE; 2663 SETATTR(templ, i, CKA_SIGN_RECOVER, &condition, 2664 sizeof (CK_BBOOL)); i++; 2665 } 2666 if (params->label != NULL) { 2667 SETATTR(templ, i, CKA_LABEL, params->label, 2668 strlen(params->label)); 2669 i++; 2670 } 2671 if (id.Data != NULL && 2672 id.Data != NULL && id.Length > 0) { 2673 SETATTR(templ, i, CKA_ID, id.Data, id.Length); 2674 i++; 2675 } 2676 if (start != NULL) { 2677 /* 2678 * This make some potentially dangerous assumptions: 2679 * 1. that the startdate in the parameter block is 2680 * properly formatted as YYYYMMDD 2681 * 2. That the CK_DATE structure is always the same. 2682 */ 2683 (void) memcpy(&startdate, start, sizeof (CK_DATE)); 2684 SETATTR(templ, i, CKA_START_DATE, &startdate, 2685 sizeof (startdate)); 2686 i++; 2687 } 2688 if (end != NULL) { 2689 (void) memcpy(&enddate, end, sizeof (CK_DATE)); 2690 SETATTR(templ, i, CKA_END_DATE, &enddate, sizeof (enddate)); 2691 i++; 2692 } 2693 if (keytype == CKK_RSA) { 2694 SETATTR(templ, i, CKA_MODULUS, 2695 rawkey->rawdata.rsa.mod.val, 2696 rawkey->rawdata.rsa.mod.len); 2697 i++; 2698 SETATTR(templ, i, CKA_PUBLIC_EXPONENT, 2699 rawkey->rawdata.rsa.pubexp.val, 2700 rawkey->rawdata.rsa.pubexp.len); 2701 i++; 2702 if (rawkey->rawdata.rsa.priexp.val != NULL) { 2703 SETATTR(templ, i, CKA_PRIVATE_EXPONENT, 2704 rawkey->rawdata.rsa.priexp.val, 2705 rawkey->rawdata.rsa.priexp.len); 2706 i++; 2707 } 2708 if (rawkey->rawdata.rsa.prime1.val != NULL) { 2709 SETATTR(templ, i, CKA_PRIME_1, 2710 rawkey->rawdata.rsa.prime1.val, 2711 rawkey->rawdata.rsa.prime1.len); 2712 i++; 2713 } 2714 if (rawkey->rawdata.rsa.prime2.val != NULL) { 2715 SETATTR(templ, i, CKA_PRIME_2, 2716 rawkey->rawdata.rsa.prime2.val, 2717 rawkey->rawdata.rsa.prime2.len); 2718 i++; 2719 } 2720 if (rawkey->rawdata.rsa.exp1.val != NULL) { 2721 SETATTR(templ, i, CKA_EXPONENT_1, 2722 rawkey->rawdata.rsa.exp1.val, 2723 rawkey->rawdata.rsa.exp1.len); 2724 i++; 2725 } 2726 if (rawkey->rawdata.rsa.exp2.val != NULL) { 2727 SETATTR(templ, i, CKA_EXPONENT_2, 2728 rawkey->rawdata.rsa.exp2.val, 2729 rawkey->rawdata.rsa.exp2.len); 2730 i++; 2731 } 2732 if (rawkey->rawdata.rsa.coef.val != NULL) { 2733 SETATTR(templ, i, CKA_COEFFICIENT, 2734 rawkey->rawdata.rsa.coef.val, 2735 rawkey->rawdata.rsa.coef.len); 2736 i++; 2737 } 2738 } else { 2739 SETATTR(templ, i, CKA_PRIME, 2740 rawkey->rawdata.dsa.prime.val, 2741 rawkey->rawdata.dsa.prime.len); 2742 i++; 2743 SETATTR(templ, i, CKA_SUBPRIME, 2744 rawkey->rawdata.dsa.subprime.val, 2745 rawkey->rawdata.dsa.subprime.len); 2746 i++; 2747 SETATTR(templ, i, CKA_BASE, 2748 rawkey->rawdata.dsa.base.val, 2749 rawkey->rawdata.dsa.base.len); 2750 i++; 2751 SETATTR(templ, i, CKA_VALUE, 2752 rawkey->rawdata.dsa.value.val, 2753 rawkey->rawdata.dsa.value.len); 2754 i++; 2755 } 2756 2757 ckrv = C_CreateObject(kmfh->pk11handle, templ, i, &keyobj); 2758 if (ckrv != CKR_OK) { 2759 SET_ERROR(kmfh, ckrv); 2760 2761 /* Report authentication failures to the caller */ 2762 if (ckrv == CKR_USER_NOT_LOGGED_IN || 2763 ckrv == CKR_PIN_INCORRECT || 2764 ckrv == CKR_PIN_INVALID || 2765 ckrv == CKR_PIN_EXPIRED || 2766 ckrv == CKR_PIN_LOCKED || 2767 ckrv == CKR_SESSION_READ_ONLY) 2768 rv = KMF_ERR_AUTH_FAILED; 2769 else 2770 rv = KMF_ERR_INTERNAL; 2771 } 2772 cleanup: 2773 KMF_FreeData(&id); 2774 KMF_FreeData(&subject); 2775 KMF_FreeSignedCert(x509); 2776 free(x509); 2777 2778 return (rv); 2779 } 2780 2781 KMF_RETURN 2782 KMFPK11_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, 2783 KMF_KEY_HANDLE *symkey) 2784 { 2785 KMF_RETURN rv = KMF_OK; 2786 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2787 CK_RV ckrv; 2788 CK_SESSION_HANDLE hSession = kmfh->pk11handle; 2789 CK_OBJECT_HANDLE keyhandle; 2790 CK_MECHANISM keyGenMech; 2791 CK_OBJECT_CLASS class = CKO_SECRET_KEY; 2792 CK_ULONG secKeyType; 2793 CK_ULONG secKeyLen; /* for RC4 and AES */ 2794 CK_BBOOL true = TRUE; 2795 CK_BBOOL false = FALSE; 2796 CK_ATTRIBUTE templ[15]; 2797 int i; 2798 2799 if (kmfh == NULL) 2800 return (KMF_ERR_UNINITIALIZED); 2801 2802 if (kmfh->pk11handle == CK_INVALID_HANDLE) 2803 return (KMF_ERR_NO_TOKEN_SELECTED); 2804 2805 if (params == NULL) 2806 return (KMF_ERR_BAD_PARAMETER); 2807 /* 2808 * For AES, RC4, DES and 3DES, call C_GenerateKey() to create a key. 2809 * 2810 * For a generic secret key, because it may not be supported in 2811 * C_GenerateKey() for some PKCS11 providers, we will handle it 2812 * differently. 2813 */ 2814 if (params->keytype == KMF_GENERIC_SECRET) { 2815 rv = create_generic_secret_key(handle, params, &keyhandle); 2816 if (rv != KMF_OK) 2817 goto out; 2818 else 2819 goto setup; 2820 } 2821 2822 /* Other keytypes */ 2823 keyGenMech.pParameter = NULL_PTR; 2824 keyGenMech.ulParameterLen = 0; 2825 switch (params->keytype) { 2826 case KMF_AES: 2827 keyGenMech.mechanism = CKM_AES_KEY_GEN; 2828 secKeyType = CKK_AES; 2829 break; 2830 case KMF_RC4: 2831 keyGenMech.mechanism = CKM_RC4_KEY_GEN; 2832 secKeyType = CKK_RC4; 2833 break; 2834 case KMF_DES: 2835 keyGenMech.mechanism = CKM_DES_KEY_GEN; 2836 secKeyType = CKK_DES; 2837 break; 2838 case KMF_DES3: 2839 keyGenMech.mechanism = CKM_DES3_KEY_GEN; 2840 secKeyType = CKK_DES3; 2841 break; 2842 default: 2843 return (KMF_ERR_BAD_KEY_TYPE); 2844 } 2845 2846 i = 0; 2847 SETATTR(templ, i, CKA_CLASS, &class, sizeof (class)); 2848 i++; 2849 SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType)); 2850 i++; 2851 2852 if (params->keytype == KMF_AES || params->keytype == KMF_RC4) { 2853 if ((params->keylength % 8) != 0) { 2854 return (KMF_ERR_BAD_KEY_SIZE); 2855 } 2856 secKeyLen = params->keylength/8; /* in bytes for RC4/AES */ 2857 SETATTR(templ, i, CKA_VALUE_LEN, &secKeyLen, 2858 sizeof (secKeyLen)); 2859 i++; 2860 } 2861 2862 if (params->keylabel != NULL) { 2863 SETATTR(templ, i, CKA_LABEL, params->keylabel, 2864 strlen(params->keylabel)); 2865 i++; 2866 } 2867 2868 if (params->pkcs11parms.sensitive == B_TRUE) { 2869 SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true)); 2870 } else { 2871 SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false)); 2872 } 2873 i++; 2874 2875 if (params->pkcs11parms.not_extractable == B_TRUE) { 2876 SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false)); 2877 } else { 2878 SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true)); 2879 } 2880 i++; 2881 2882 SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true)); 2883 i++; 2884 SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true)); 2885 i++; 2886 SETATTR(templ, i, CKA_ENCRYPT, &true, sizeof (true)); 2887 i++; 2888 SETATTR(templ, i, CKA_DECRYPT, &true, sizeof (true)); 2889 i++; 2890 SETATTR(templ, i, CKA_SIGN, &true, sizeof (true)); 2891 i++; 2892 SETATTR(templ, i, CKA_VERIFY, &true, sizeof (true)); 2893 i++; 2894 2895 rv = pk11_authenticate(handle, ¶ms->cred); 2896 if (rv != KMF_OK) { 2897 return (rv); 2898 } 2899 2900 ckrv = C_GenerateKey(hSession, &keyGenMech, templ, i, &keyhandle); 2901 if (ckrv != CKR_OK) { 2902 SET_ERROR(kmfh, ckrv); 2903 rv = KMF_ERR_KEYGEN_FAILED; 2904 goto out; 2905 } 2906 2907 setup: 2908 symkey->kstype = KMF_KEYSTORE_PK11TOKEN; 2909 symkey->keyalg = params->keytype; 2910 symkey->keyclass = KMF_SYMMETRIC; 2911 symkey->israw = FALSE; 2912 symkey->keyp = (void *)keyhandle; 2913 2914 out: 2915 return (rv); 2916 } 2917 2918 2919 KMF_RETURN 2920 KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, 2921 KMF_RAW_SYM_KEY *rkey) 2922 { 2923 KMF_RETURN rv = KMF_OK; 2924 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2925 2926 if (kmfh == NULL) 2927 return (KMF_ERR_UNINITIALIZED); 2928 2929 if (kmfh->pk11handle == CK_INVALID_HANDLE) 2930 return (KMF_ERR_NO_TOKEN_SELECTED); 2931 2932 if (symkey == NULL || rkey == NULL) 2933 return (KMF_ERR_BAD_PARAMETER); 2934 else if (symkey->keyclass != KMF_SYMMETRIC) 2935 return (KMF_ERR_BAD_KEY_CLASS); 2936 2937 if (symkey->israw) { 2938 KMF_RAW_KEY_DATA *rawkey = (KMF_RAW_KEY_DATA *)symkey->keyp; 2939 2940 if (rawkey == NULL || 2941 rawkey->rawdata.sym.keydata.val == NULL || 2942 rawkey->rawdata.sym.keydata.len == 0) 2943 return (KMF_ERR_BAD_KEYHANDLE); 2944 2945 rkey->keydata.len = rawkey->rawdata.sym.keydata.len; 2946 if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL) 2947 return (KMF_ERR_MEMORY); 2948 (void) memcpy(rkey->keydata.val, 2949 rawkey->rawdata.sym.keydata.val, rkey->keydata.len); 2950 } else { 2951 rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)symkey->keyp, rkey); 2952 } 2953 2954 return (rv); 2955 } 2956 2957 KMF_RETURN 2958 KMFPK11_SetTokenPin(KMF_HANDLE_T handle, KMF_SETPIN_PARAMS *params, 2959 KMF_CREDENTIAL *newpin) 2960 { 2961 KMF_RETURN ret = KMF_OK; 2962 CK_RV rv = CKR_OK; 2963 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2964 CK_SESSION_HANDLE session = NULL; 2965 2966 if (handle == NULL || params == NULL || newpin == NULL) 2967 return (KMF_ERR_BAD_PARAMETER); 2968 2969 rv = C_OpenSession(params->pkcs11parms.slot, 2970 CKF_SERIAL_SESSION | CKF_RW_SESSION, 2971 NULL, NULL, &session); 2972 if (rv != CKR_OK) { 2973 SET_ERROR(kmfh, rv); 2974 ret = KMF_ERR_UNINITIALIZED; 2975 goto end; 2976 } 2977 2978 rv = C_SetPIN(session, 2979 (CK_BYTE *)params->cred.cred, params->cred.credlen, 2980 (CK_BYTE *)newpin->cred, newpin->credlen); 2981 2982 if (rv != CKR_OK) { 2983 SET_ERROR(kmfh, rv); 2984 if (rv == CKR_PIN_INCORRECT || 2985 rv == CKR_PIN_INVALID || 2986 rv == CKR_PIN_EXPIRED || 2987 rv == CKR_PIN_LOCKED) 2988 ret = KMF_ERR_AUTH_FAILED; 2989 else 2990 ret = KMF_ERR_INTERNAL; 2991 } 2992 end: 2993 if (session != NULL) 2994 (void) C_CloseSession(session); 2995 return (ret); 2996 } 2997 2998 static KMF_RETURN 2999 create_pk11_session(CK_SESSION_HANDLE *sessionp, CK_MECHANISM_TYPE wanted_mech, 3000 CK_FLAGS wanted_flags) 3001 { 3002 CK_RV rv; 3003 KMF_RETURN kmf_rv = KMF_OK; 3004 CK_SLOT_ID_PTR pSlotList; 3005 CK_ULONG pulCount; 3006 CK_MECHANISM_INFO info; 3007 int i; 3008 3009 rv = C_Initialize(NULL); 3010 if ((rv != CKR_OK) && 3011 (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) { 3012 kmf_rv = KMF_ERR_UNINITIALIZED; 3013 goto out; 3014 } 3015 3016 rv = C_GetSlotList(0, NULL, &pulCount); 3017 if (rv != CKR_OK) { 3018 kmf_rv = KMF_ERR_UNINITIALIZED; 3019 goto out; 3020 } 3021 3022 pSlotList = (CK_SLOT_ID_PTR) malloc(pulCount * sizeof (CK_SLOT_ID)); 3023 if (pSlotList == NULL) { 3024 kmf_rv = KMF_ERR_MEMORY; 3025 goto out; 3026 } 3027 3028 rv = C_GetSlotList(0, pSlotList, &pulCount); 3029 if (rv != CKR_OK) { 3030 kmf_rv = KMF_ERR_UNINITIALIZED; 3031 goto out; 3032 } 3033 3034 for (i = 0; i < pulCount; i++) { 3035 rv = C_GetMechanismInfo(pSlotList[i], wanted_mech, &info); 3036 if (rv == CKR_OK && (info.flags & wanted_flags)) 3037 break; 3038 } 3039 if (i < pulCount) { 3040 rv = C_OpenSession(pSlotList[i], CKF_SERIAL_SESSION, 3041 NULL, NULL, sessionp); 3042 3043 if (rv != CKR_OK) { 3044 kmf_rv = KMF_ERR_UNINITIALIZED; 3045 } 3046 } else { 3047 kmf_rv = KMF_ERR_UNINITIALIZED; 3048 } 3049 3050 out: 3051 if (pSlotList != NULL) 3052 free(pSlotList); 3053 return (kmf_rv); 3054 3055 } 3056 static KMF_RETURN 3057 verify_data(KMF_HANDLE_T handle, 3058 KMF_ALGORITHM_INDEX AlgorithmId, 3059 KMF_X509_SPKI *keyp, 3060 KMF_DATA *data, 3061 KMF_DATA *signed_data) 3062 { 3063 KMF_RETURN ret; 3064 PKCS_ALGORITHM_MAP *pAlgMap = NULL; 3065 CK_RV ckRv; 3066 CK_MECHANISM ckMechanism; 3067 CK_OBJECT_HANDLE ckKeyHandle; 3068 KMF_BOOL bTempKey; 3069 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3070 CK_SESSION_HANDLE ckSession = NULL; 3071 3072 if (AlgorithmId == KMF_ALGID_NONE) 3073 return (KMF_ERR_BAD_ALGORITHM); 3074 3075 pAlgMap = PKCS_GetAlgorithmMap(KMF_ALGCLASS_SIGNATURE, 3076 AlgorithmId, PKCS_GetDefaultSignatureMode(AlgorithmId)); 3077 3078 if (!pAlgMap) 3079 return (KMF_ERR_BAD_ALGORITHM); 3080 3081 ret = create_pk11_session(&ckSession, pAlgMap->pkcs_mechanism, 3082 CKF_VERIFY); 3083 if (ret != KMF_OK) 3084 return (ret); 3085 3086 /* Fetch the verifying key */ 3087 ret = PKCS_AcquirePublicKeyHandle(ckSession, keyp, 3088 pAlgMap->key_type, &ckKeyHandle, &bTempKey); 3089 3090 if (ret != KMF_OK) { 3091 return (ret); 3092 } 3093 3094 ckMechanism.mechanism = pAlgMap->pkcs_mechanism; 3095 ckMechanism.pParameter = NULL; 3096 ckMechanism.ulParameterLen = 0; 3097 3098 ckRv = C_VerifyInit(ckSession, &ckMechanism, ckKeyHandle); 3099 if (ckRv != CKR_OK) { 3100 if (bTempKey) 3101 (void) C_DestroyObject(ckSession, ckKeyHandle); 3102 SET_ERROR(kmfh, ckRv); 3103 ret = KMF_ERR_INTERNAL; 3104 goto cleanup; 3105 } 3106 3107 ckRv = C_Verify(ckSession, 3108 (CK_BYTE *)data->Data, 3109 (CK_ULONG)data->Length, 3110 (CK_BYTE *)signed_data->Data, 3111 (CK_ULONG)signed_data->Length); 3112 3113 if (ckRv != CKR_OK) { 3114 SET_ERROR(kmfh, ckRv); 3115 ret = KMF_ERR_INTERNAL; 3116 } 3117 3118 cleanup: 3119 if (bTempKey) 3120 (void) C_DestroyObject(ckSession, ckKeyHandle); 3121 3122 (void) C_CloseSession(ckSession); 3123 3124 return (ret); 3125 } 3126 3127 KMF_RETURN 3128 KMFPK11_VerifyDataWithCert(KMF_HANDLE_T handle, 3129 KMF_ALGORITHM_INDEX algid, KMF_DATA *indata, 3130 KMF_DATA *insig, KMF_DATA *SignerCertData) 3131 { 3132 KMF_RETURN ret = KMF_OK; 3133 KMF_X509_CERTIFICATE *SignerCert = NULL; 3134 KMF_X509_SPKI *pubkey; 3135 3136 if (handle == NULL || indata == NULL || 3137 indata->Data == NULL || indata->Length == 0 || 3138 insig == NULL|| insig->Data == NULL || insig->Length == 0 || 3139 SignerCertData == NULL || SignerCertData->Data == NULL || 3140 SignerCertData->Length == 0) 3141 return (KMF_ERR_BAD_PARAMETER); 3142 3143 /* Decode the signer cert so we can get the SPKI data */ 3144 ret = DerDecodeSignedCertificate(SignerCertData, &SignerCert); 3145 if (ret != KMF_OK) 3146 goto cleanup; 3147 3148 /* Get the public key info from the signer certificate */ 3149 pubkey = &SignerCert->certificate.subjectPublicKeyInfo; 3150 3151 /* If no algorithm specified, use the certs signature algorithm */ 3152 if (algid == KMF_ALGID_NONE) { 3153 algid = X509_AlgorithmOidToAlgId(CERT_ALG_OID(SignerCert)); 3154 } 3155 3156 if (algid == KMF_ALGID_NONE) { 3157 ret = KMF_ERR_BAD_ALGORITHM; 3158 } else { 3159 ret = verify_data(handle, algid, pubkey, indata, insig); 3160 } 3161 3162 cleanup: 3163 if (SignerCert) { 3164 KMF_FreeSignedCert(SignerCert); 3165 free(SignerCert); 3166 } 3167 3168 return (ret); 3169 } 3170 3171 static KMF_RETURN 3172 create_generic_secret_key(KMF_HANDLE_T handle, 3173 KMF_CREATESYMKEY_PARAMS *params, CK_OBJECT_HANDLE *key) 3174 { 3175 KMF_RETURN rv = KMF_OK; 3176 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3177 CK_RV ckrv; 3178 CK_SESSION_HANDLE hSession = kmfh->pk11handle; 3179 CK_OBJECT_CLASS class = CKO_SECRET_KEY; 3180 CK_ULONG secKeyType = CKK_GENERIC_SECRET; 3181 CK_ULONG secKeyLen; 3182 CK_BBOOL true = TRUE; 3183 CK_BBOOL false = FALSE; 3184 CK_ATTRIBUTE templ[15]; 3185 int i; 3186 int random_fd = -1; 3187 int nread; 3188 char *buf = NULL; 3189 3190 /* 3191 * Check the key size. 3192 */ 3193 if ((params->keylength % 8) != 0) { 3194 return (KMF_ERR_BAD_KEY_SIZE); 3195 } else { 3196 secKeyLen = params->keylength/8; /* in bytes */ 3197 } 3198 3199 /* 3200 * Generate a random number with the key size first. 3201 */ 3202 buf = malloc(secKeyLen); 3203 if (buf == NULL) 3204 return (KMF_ERR_MEMORY); 3205 3206 while ((random_fd = open(DEV_RANDOM, O_RDONLY)) < 0) { 3207 if (errno != EINTR) 3208 break; 3209 } 3210 3211 if (random_fd < 0) { 3212 rv = KMF_ERR_KEYGEN_FAILED; 3213 goto out; 3214 } 3215 3216 nread = read(random_fd, buf, secKeyLen); 3217 if (nread <= 0 || nread != secKeyLen) { 3218 rv = KMF_ERR_KEYGEN_FAILED; 3219 goto out; 3220 } 3221 3222 /* 3223 * Authenticate into the token and call C_CreateObject to generate 3224 * a generic secret token key. 3225 */ 3226 rv = pk11_authenticate(handle, ¶ms->cred); 3227 if (rv != KMF_OK) { 3228 goto out; 3229 } 3230 3231 i = 0; 3232 SETATTR(templ, i, CKA_CLASS, &class, sizeof (class)); 3233 i++; 3234 SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType)); 3235 i++; 3236 SETATTR(templ, i, CKA_VALUE, buf, secKeyLen); 3237 i++; 3238 3239 if (params->keylabel != NULL) { 3240 SETATTR(templ, i, CKA_LABEL, params->keylabel, 3241 strlen(params->keylabel)); 3242 i++; 3243 } 3244 3245 if (params->pkcs11parms.sensitive == B_TRUE) { 3246 SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true)); 3247 } else { 3248 SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false)); 3249 } 3250 i++; 3251 3252 if (params->pkcs11parms.not_extractable == B_TRUE) { 3253 SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false)); 3254 } else { 3255 SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true)); 3256 } 3257 i++; 3258 3259 SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true)); 3260 i++; 3261 SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true)); 3262 i++; 3263 SETATTR(templ, i, CKA_SIGN, &true, sizeof (true)); 3264 i++; 3265 3266 ckrv = C_CreateObject(hSession, templ, i, key); 3267 if (ckrv != CKR_OK) { 3268 SET_ERROR(kmfh, ckrv); 3269 rv = KMF_ERR_KEYGEN_FAILED; 3270 } 3271 3272 out: 3273 if (buf != NULL) 3274 free(buf); 3275 3276 if (random_fd != -1) 3277 (void) close(random_fd); 3278 3279 return (rv); 3280 } 3281