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