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