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