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