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