pkcs11_spi.c revision 3754:79eeec53e95c
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21/* 22 * PKCS11 token KMF Plugin 23 * 24 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28#pragma ident "%Z%%M% %I% %E% SMI" 29 30#include <stdio.h> /* debugging only */ 31#include <errno.h> 32#include <values.h> 33 34#include <kmfapiP.h> 35#include <ber_der.h> 36#include <algorithm.h> 37 38#include <cryptoutil.h> 39#include <security/cryptoki.h> 40#include <security/pkcs11.h> 41 42#define SETATTR(t, n, atype, value, size) \ 43 t[n].type = atype; \ 44 t[n].pValue = (CK_BYTE *)value; \ 45 t[n].ulValueLen = (CK_ULONG)size; 46 47#define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; \ 48 h->lasterr.errcode = c; 49 50typedef struct _objlist { 51 CK_OBJECT_HANDLE handle; 52 struct _objlist *next; 53} OBJLIST; 54 55static KMF_RETURN 56search_certs(KMF_HANDLE_T, char *, char *, char *, KMF_BIGINT *, 57 boolean_t, KMF_CERT_VALIDITY, OBJLIST **, uint32_t *); 58 59static CK_RV 60getObjectLabel(KMF_HANDLE_T, CK_OBJECT_HANDLE, char **); 61 62static KMF_RETURN 63keyObj2RawKey(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_KEY_DATA **); 64 65KMF_RETURN 66KMFPK11_ConfigureKeystore(KMF_HANDLE_T, KMF_CONFIG_PARAMS *); 67 68KMF_RETURN 69KMFPK11_FindCert(KMF_HANDLE_T, 70 KMF_FINDCERT_PARAMS *, 71 KMF_X509_DER_CERT *, 72 uint32_t *); 73 74void 75KMFPK11_FreeKMFCert(KMF_HANDLE_T, 76 KMF_X509_DER_CERT *kmf_cert); 77 78KMF_RETURN 79KMFPK11_StoreCert(KMF_HANDLE_T, KMF_STORECERT_PARAMS *, KMF_DATA *); 80 81KMF_RETURN 82KMFPK11_ImportCert(KMF_HANDLE_T, KMF_IMPORTCERT_PARAMS *); 83 84KMF_RETURN 85KMFPK11_DeleteCert(KMF_HANDLE_T, KMF_DELETECERT_PARAMS *); 86 87KMF_RETURN 88KMFPK11_CreateKeypair(KMF_HANDLE_T, KMF_CREATEKEYPAIR_PARAMS *, 89 KMF_KEY_HANDLE *, KMF_KEY_HANDLE *); 90 91KMF_RETURN 92KMFPK11_DeleteKey(KMF_HANDLE_T, KMF_DELETEKEY_PARAMS *, 93 KMF_KEY_HANDLE *, boolean_t); 94 95KMF_RETURN 96KMFPK11_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *); 97 98KMF_RETURN 99KMFPK11_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 100 KMF_DATA *, KMF_DATA *); 101 102KMF_RETURN 103KMFPK11_GetErrorString(KMF_HANDLE_T, char **); 104 105KMF_RETURN 106KMFPK11_GetPrikeyByCert(KMF_HANDLE_T, KMF_CRYPTOWITHCERT_PARAMS *, KMF_DATA *, 107 KMF_KEY_HANDLE *, KMF_KEY_ALG); 108 109KMF_RETURN 110KMFPK11_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 111 KMF_DATA *, KMF_DATA *); 112 113KMF_RETURN 114KMFPK11_FindKey(KMF_HANDLE_T, KMF_FINDKEY_PARAMS *, 115 KMF_KEY_HANDLE *, uint32_t *); 116 117KMF_RETURN 118KMFPK11_StorePrivateKey(KMF_HANDLE_T, KMF_STOREKEY_PARAMS *, 119 KMF_RAW_KEY_DATA *); 120 121KMF_RETURN 122KMFPK11_CreateSymKey(KMF_HANDLE_T, KMF_CREATESYMKEY_PARAMS *, 123 KMF_KEY_HANDLE *); 124 125KMF_RETURN 126KMFPK11_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *); 127 128KMF_RETURN 129KMFPK11_SetTokenPin(KMF_HANDLE_T, KMF_SETPIN_PARAMS *, KMF_CREDENTIAL *); 130 131KMF_RETURN 132KMFPK11_VerifyDataWithCert(KMF_HANDLE_T, KMF_ALGORITHM_INDEX, KMF_DATA *, 133 KMF_DATA *, KMF_DATA *); 134 135static 136KMF_PLUGIN_FUNCLIST pk11token_plugin_table = 137{ 138 1, /* Version */ 139 KMFPK11_ConfigureKeystore, 140 KMFPK11_FindCert, 141 KMFPK11_FreeKMFCert, 142 KMFPK11_StoreCert, 143 KMFPK11_ImportCert, 144 NULL, /* ImportCRL */ 145 KMFPK11_DeleteCert, 146 NULL, /* DeleteCRL */ 147 KMFPK11_CreateKeypair, 148 KMFPK11_FindKey, 149 KMFPK11_EncodePubKeyData, 150 KMFPK11_SignData, 151 KMFPK11_DeleteKey, 152 NULL, /* ListCRL */ 153 NULL, /* FindCRL */ 154 NULL, /* FindCertInCRL */ 155 KMFPK11_GetErrorString, 156 KMFPK11_GetPrikeyByCert, 157 KMFPK11_DecryptData, 158 NULL, /* ExportP12 */ 159 KMFPK11_StorePrivateKey, 160 KMFPK11_CreateSymKey, 161 KMFPK11_GetSymKeyValue, 162 KMFPK11_SetTokenPin, 163 KMFPK11_VerifyDataWithCert, 164 NULL /* Finalize */ 165}; 166 167KMF_PLUGIN_FUNCLIST * 168KMF_Plugin_Initialize() 169{ 170 return (&pk11token_plugin_table); 171} 172 173KMF_RETURN 174KMFPK11_ConfigureKeystore(KMF_HANDLE_T handle, KMF_CONFIG_PARAMS *params) 175{ 176 KMF_RETURN rv = KMF_OK; 177 178 if (params == NULL || params->pkcs11config.label == NULL) 179 return (KMF_ERR_BAD_PARAMETER); 180 181 rv = KMF_SelectToken(handle, params->pkcs11config.label, 182 params->pkcs11config.readonly); 183 184 return (rv); 185} 186 187static KMF_RETURN 188pk11_authenticate(KMF_HANDLE_T handle, 189 KMF_CREDENTIAL *cred) 190{ 191 192 CK_RV ck_rv = CKR_OK; 193 CK_SESSION_HANDLE hSession = (CK_SESSION_HANDLE)handle->pk11handle; 194 195 if (hSession == NULL) 196 return (KMF_ERR_NO_TOKEN_SELECTED); 197 198 if (cred == NULL || cred->cred == NULL || cred->credlen == 0) { 199 return (KMF_ERR_BAD_PARAMETER); 200 } 201 202 if ((ck_rv = C_Login(hSession, CKU_USER, 203 (uchar_t *)cred->cred, cred->credlen)) != CKR_OK) { 204 if (ck_rv != CKR_USER_ALREADY_LOGGED_IN) { 205 handle->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; 206 handle->lasterr.errcode = ck_rv; 207 return (KMF_ERR_AUTH_FAILED); 208 } 209 } 210 211 return (KMF_OK); 212} 213 214static KMF_RETURN 215PK11Cert2KMFCert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE hObj, 216 KMF_X509_DER_CERT *kmfcert) 217{ 218 KMF_RETURN rv = 0; 219 CK_RV ckrv = CKR_OK; 220 221 CK_CERTIFICATE_TYPE cktype; 222 CK_OBJECT_CLASS class; 223 CK_ULONG subject_len, value_len, issuer_len, serno_len, id_len; 224 CK_BYTE *subject = NULL, *value = NULL; 225 char *label = NULL; 226 CK_ATTRIBUTE templ[10]; 227 228 (void) memset(templ, 0, 10 * sizeof (CK_ATTRIBUTE)); 229 SETATTR(templ, 0, CKA_CLASS, &class, sizeof (class)); 230 231 /* Is this a certificate object ? */ 232 ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, 1); 233 if (ckrv != CKR_OK || class != CKO_CERTIFICATE) { 234 SET_ERROR(kmfh, ckrv); 235 return (KMF_ERR_INTERNAL); 236 } 237 238 SETATTR(templ, 0, CKA_CERTIFICATE_TYPE, &cktype, sizeof (cktype)); 239 ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, 1); 240 241 if (ckrv != CKR_OK || cktype != CKC_X_509) { 242 SET_ERROR(kmfh, ckrv); 243 return (ckrv); 244 } else { 245 int i = 0; 246 /* What attributes are available and how big are they? */ 247 subject_len = issuer_len = serno_len = id_len = value_len = 0; 248 249 SETATTR(templ, i, CKA_SUBJECT, NULL, subject_len); 250 i++; 251 SETATTR(templ, i, CKA_ISSUER, NULL, issuer_len); 252 i++; 253 SETATTR(templ, i, CKA_SERIAL_NUMBER, NULL, serno_len); 254 i++; 255 SETATTR(templ, i, CKA_ID, NULL, id_len); 256 i++; 257 SETATTR(templ, i, CKA_VALUE, NULL, value_len); 258 i++; 259 260 /* 261 * Query the object with NULL values in the pValue spot 262 * so we know how much space to allocate for each field. 263 */ 264 ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, i); 265 if (ckrv != CKR_OK) { 266 SET_ERROR(kmfh, ckrv); 267 return (KMF_ERR_INTERNAL); /* TODO - Error messages ? */ 268 } 269 270 subject_len = templ[0].ulValueLen; 271 issuer_len = templ[1].ulValueLen; 272 serno_len = templ[2].ulValueLen; 273 id_len = templ[3].ulValueLen; 274 value_len = templ[4].ulValueLen; 275 276 /* 277 * For PKCS#11 CKC_X_509 certificate objects, 278 * the following attributes must be defined. 279 * CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER, 280 * CKA_VALUE. 281 */ 282 if (subject_len == 0 || issuer_len == 0 || 283 serno_len == 0 || value_len == 0) { 284 return (KMF_ERR_INTERNAL); 285 } 286 287 /* Only fetch the value field if we are saving the data */ 288 if (kmfcert != NULL) { 289 int i = 0; 290 value = malloc(value_len); 291 if (value == NULL) { 292 rv = KMF_ERR_MEMORY; 293 goto errout; 294 } 295 296 SETATTR(templ, i, CKA_VALUE, value, value_len); 297 i++; 298 299 /* re-query the object with room for the value attr */ 300 ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, 301 templ, i); 302 303 if (ckrv != CKR_OK) { 304 SET_ERROR(kmfh, ckrv); 305 rv = KMF_ERR_INTERNAL; 306 goto errout; 307 } 308 309 kmfcert->certificate.Data = value; 310 kmfcert->certificate.Length = value_len; 311 kmfcert->kmf_private.flags |= KMF_FLAG_CERT_SIGNED; 312 kmfcert->kmf_private.keystore_type = 313 KMF_KEYSTORE_PK11TOKEN; 314 315 ckrv = getObjectLabel(kmfh, hObj, &label); 316 if (ckrv == CKR_OK && label != NULL) { 317 kmfcert->kmf_private.label = (char *)label; 318 } 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, nullserno; 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 /* 1086 * RFC3280 says to gracefully handle certs with serial numbers 1087 * of 0. 1088 */ 1089 nullserno = '\0'; 1090 serial = &nullserno; 1091 serno_len = 1; 1092 } 1093 1094 /* Generate an ID from the SPKI data */ 1095 rv = GetIDFromSPKI(&signed_cert_ptr->certificate.subjectPublicKeyInfo, 1096 &Id); 1097 1098 if (rv != KMF_OK) { 1099 SET_ERROR(kmfh, rv); 1100 goto cleanup; 1101 } 1102 1103 i = 0; 1104 SETATTR(x509templ, i, CKA_CLASS, &certClass, 1105 sizeof (certClass)); i++; 1106 SETATTR(x509templ, i, CKA_CERTIFICATE_TYPE, &certtype, 1107 sizeof (certtype)); i++; 1108 SETATTR(x509templ, i, CKA_TOKEN, &true, sizeof (true)); i++; 1109 SETATTR(x509templ, i, CKA_SUBJECT, subject, subject_len); i++; 1110 SETATTR(x509templ, i, CKA_ISSUER, issuer, issuer_len); i++; 1111 SETATTR(x509templ, i, CKA_SERIAL_NUMBER, serial, serno_len); i++; 1112 SETATTR(x509templ, i, CKA_VALUE, pcert->Data, pcert->Length); i++; 1113 SETATTR(x509templ, i, CKA_ID, Id.Data, Id.Length); i++; 1114 if (label != NULL && strlen(label)) { 1115 SETATTR(x509templ, i, CKA_LABEL, label, strlen(label)); 1116 i++; 1117 } 1118 /* 1119 * The cert object handle is actually "leaked" here. If the app 1120 * really wants to clean up the data space, it will have to call 1121 * KMF_DeleteCert and specify the softtoken keystore. 1122 */ 1123 ckrv = C_CreateObject(kmfh->pk11handle, x509templ, i, &hCert); 1124 if (ckrv != CKR_OK) { 1125 SET_ERROR(kmfh, rv); 1126 rv = KMF_ERR_INTERNAL; 1127 } 1128 free(subject); 1129 free(issuer); 1130 1131cleanup: 1132 if (Id.Data != NULL) 1133 free(Id.Data); 1134 1135 if (signed_cert_ptr) { 1136 KMF_FreeSignedCert(signed_cert_ptr); 1137 free(signed_cert_ptr); 1138 } 1139 return (rv); 1140} 1141 1142 1143KMF_RETURN 1144KMFPK11_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *params, 1145 KMF_DATA *pcert) 1146{ 1147 KMF_RETURN rv = 0; 1148 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1149 1150 if (!kmfh) 1151 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 1152 1153 if (kmfh->pk11handle == CK_INVALID_HANDLE) 1154 return (KMF_ERR_NO_TOKEN_SELECTED); 1155 1156 if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) 1157 return (KMF_ERR_BAD_PARAMETER); 1158 1159 rv = CreateCertObject(handle, params->certLabel, pcert); 1160 return (rv); 1161} 1162 1163 1164 1165KMF_RETURN 1166KMFPK11_ImportCert(KMF_HANDLE_T handle, KMF_IMPORTCERT_PARAMS *params) 1167{ 1168 KMF_RETURN rv = 0; 1169 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1170 KMF_ENCODE_FORMAT format; 1171 KMF_DATA cert1 = { NULL, 0}; 1172 KMF_DATA cert2 = { NULL, 0}; 1173 1174 if (!kmfh) 1175 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 1176 1177 if (kmfh->pk11handle == CK_INVALID_HANDLE) 1178 return (KMF_ERR_NO_TOKEN_SELECTED); 1179 1180 if (params == NULL || params->certfile == NULL) { 1181 return (KMF_ERR_BAD_PARAMETER); 1182 } 1183 1184 /* 1185 * Check if the input cert file is a valid certificate and 1186 * auto-detect the file format of it. 1187 */ 1188 rv = KMF_IsCertFile(handle, params->certfile, &format); 1189 if (rv != KMF_OK) 1190 return (rv); 1191 1192 /* Read in the CERT file */ 1193 rv = KMF_ReadInputFile(handle, params->certfile, &cert1); 1194 if (rv != KMF_OK) { 1195 return (rv); 1196 } 1197 1198 /* 1199 * If the input certificate is in PEM format, we need to convert 1200 * it to DER first. 1201 */ 1202 if (format == KMF_FORMAT_PEM) { 1203 int derlen; 1204 rv = KMF_Pem2Der(cert1.Data, cert1.Length, 1205 &cert2.Data, &derlen); 1206 if (rv != KMF_OK) { 1207 goto out; 1208 } 1209 cert2.Length = (size_t)derlen; 1210 } 1211 1212 rv = CreateCertObject(handle, params->certLabel, 1213 format == KMF_FORMAT_ASN1 ? &cert1 : &cert2); 1214 1215out: 1216 if (cert1.Data != NULL) { 1217 free(cert1.Data); 1218 } 1219 1220 if (cert2.Data != NULL) { 1221 free(cert2.Data); 1222 } 1223 1224 return (rv); 1225} 1226 1227KMF_RETURN 1228KMFPK11_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params) 1229{ 1230 KMF_RETURN rv = 0; 1231 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1232 OBJLIST *objlist; 1233 uint32_t numObjects = 0; 1234 1235 if (!kmfh) 1236 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 1237 1238 if (kmfh->pk11handle == CK_INVALID_HANDLE) 1239 return (KMF_ERR_NO_TOKEN_SELECTED); 1240 1241 if (params == NULL) 1242 return (KMF_ERR_BAD_PARAMETER); 1243 1244 /* 1245 * Use the same search routine as is used for the FindCert 1246 * operation. 1247 */ 1248 objlist = NULL; 1249 rv = search_certs(handle, 1250 params->certLabel, params->issuer, 1251 params->subject, params->serial, 1252 params->pkcs11parms.private, 1253 params->find_cert_validity, 1254 &objlist, &numObjects); 1255 1256 if (rv == KMF_OK && objlist != NULL) { 1257 OBJLIST *node = objlist; 1258 1259 while (node != NULL) { 1260 CK_RV ckrv; 1261 ckrv = C_DestroyObject(kmfh->pk11handle, 1262 node->handle); 1263 if (ckrv != CKR_OK) { 1264 SET_ERROR(kmfh, ckrv); 1265 rv = KMF_ERR_INTERNAL; 1266 break; 1267 } 1268 node = node->next; 1269 } 1270 free_objlist(objlist); 1271 } 1272 1273 if (rv == KMF_OK && numObjects == 0) 1274 rv = KMF_ERR_CERT_NOT_FOUND; 1275 1276out: 1277 return (rv); 1278} 1279 1280KMF_RETURN 1281KMFPK11_CreateKeypair(KMF_HANDLE_T handle, KMF_CREATEKEYPAIR_PARAMS *params, 1282 KMF_KEY_HANDLE *privkey, KMF_KEY_HANDLE *pubkey) 1283{ 1284 KMF_RETURN rv = KMF_OK; 1285 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1286 1287 CK_RV ckrv = 0; 1288 CK_OBJECT_HANDLE pubKey = CK_INVALID_HANDLE; 1289 CK_OBJECT_HANDLE priKey = CK_INVALID_HANDLE; 1290 CK_SESSION_HANDLE hSession = kmfh->pk11handle; 1291 1292 static CK_OBJECT_CLASS priClass = CKO_PRIVATE_KEY; 1293 static CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; 1294 1295 static CK_ULONG rsaKeyType = CKK_RSA; 1296 static CK_ULONG modulusBits = 1024; 1297 static CK_BYTE PubExpo[3] = {0x01, 0x00, 0x01}; 1298 static CK_BBOOL true = TRUE; 1299 static CK_BBOOL ontoken = TRUE; 1300 static CK_BBOOL false = FALSE; 1301 static CK_ULONG dsaKeyType = CKK_DSA; 1302 1303 CK_ATTRIBUTE rsaPubKeyTemplate[8]; 1304 CK_ATTRIBUTE rsaPriKeyTemplate[6]; 1305 1306 static CK_BYTE ckDsaPrime[128] = { 1307 0xb2, 0x6b, 0xc3, 0xfb, 0xe3, 0x26, 0xf4, 0xc2, 1308 0xcf, 0xdd, 0xf9, 0xae, 0x3e, 0x39, 0x7f, 0x9c, 1309 0xa7, 0x73, 0xc3, 0x00, 0xa3, 0x50, 0x67, 0xc3, 1310 0xab, 0x49, 0x2c, 0xea, 0x59, 0x10, 0xa4, 0xbc, 1311 0x09, 0x94, 0xa9, 0x05, 0x3b, 0x0d, 0x35, 0x3c, 1312 0x55, 0x52, 0x47, 0xf0, 0xe3, 0x72, 0x5b, 0xe8, 1313 0x72, 0xa0, 0x71, 0x1c, 0x23, 0x4f, 0x6d, 0xe8, 1314 0xac, 0xe5, 0x21, 0x1b, 0xc0, 0xd8, 0x42, 0xd3, 1315 0x87, 0xae, 0x83, 0x5e, 0x52, 0x7e, 0x46, 0x09, 1316 0xb5, 0xc7, 0x3d, 0xd6, 0x00, 0xf5, 0xf2, 0x9c, 1317 0x84, 0x30, 0x81, 0x7e, 0x7b, 0x30, 0x5b, 0xd5, 1318 0xab, 0xd0, 0x2f, 0x21, 0xb3, 0xd8, 0xed, 0xdb, 1319 0x97, 0x77, 0xe4, 0x7e, 0x6c, 0xcc, 0xb9, 0x6b, 1320 0xdd, 0xaa, 0x96, 0x04, 0xe7, 0xd4, 0x55, 0x11, 1321 0x53, 0xab, 0xba, 0x95, 0x9a, 0xa2, 0x8c, 0x27, 1322 0xd9, 0xcf, 0xad, 0xf3, 0xcf, 0x3a, 0x0c, 0x4b}; 1323 1324 static CK_BYTE ckDsaSubPrime[20] = { 1325 0xa4, 0x5f, 0x2a, 0x27, 0x09, 0x49, 0xb6, 0xfe, 1326 0x73, 0xeb, 0x95, 0x7d, 0x00, 0xf3, 0x42, 0xfc, 1327 0x78, 0x47, 0xb0, 0xd5}; 1328 1329 static CK_BYTE ckDsaBase[128] = { 1330 0x5c, 0x57, 0x16, 0x49, 0xef, 0xc8, 0xfb, 0x4b, 1331 0xee, 0x07, 0x45, 0x3b, 0x6a, 0x1d, 0xf3, 0xe5, 1332 0xeb, 0xee, 0xad, 0x11, 0x13, 0xe3, 0x52, 0xe3, 1333 0x0d, 0xc0, 0x21, 0x25, 0xfa, 0xf0, 0x93, 0x1c, 1334 0x53, 0x4d, 0xdc, 0x0d, 0x76, 0xd2, 0xfe, 0xc2, 1335 0xd7, 0x72, 0x64, 0x69, 0x53, 0x3d, 0x33, 0xbd, 1336 0xe1, 0x34, 0xf2, 0x5a, 0x67, 0x83, 0xe0, 0xd3, 1337 0x1c, 0xd6, 0x41, 0x4d, 0x16, 0xe8, 0x6c, 0x5a, 1338 0x07, 0x95, 0x21, 0x9a, 0xa3, 0xc4, 0xb9, 0x05, 1339 0x9d, 0x11, 0xcb, 0xc8, 0xc4, 0x9d, 0x00, 0x1a, 1340 0xf4, 0x85, 0x2a, 0xa9, 0x20, 0x3c, 0xba, 0x67, 1341 0xe5, 0xed, 0x31, 0xb2, 0x11, 0xfb, 0x1f, 0x73, 1342 0xec, 0x61, 0x29, 0xad, 0xc7, 0x68, 0xb2, 0x3f, 1343 0x38, 0xea, 0xd9, 0x87, 0x83, 0x9e, 0x7e, 0x19, 1344 0x18, 0xdd, 0xc2, 0xc3, 0x5b, 0x16, 0x6d, 0xce, 1345 0xcf, 0x88, 0x91, 0x07, 0xe0, 0x2b, 0xa8, 0x54 }; 1346 1347 static CK_ATTRIBUTE ckDsaPubKeyTemplate[] = { 1348 { CKA_CLASS, &pubClass, sizeof (pubClass) }, 1349 { CKA_KEY_TYPE, &dsaKeyType, sizeof (dsaKeyType) }, 1350 { CKA_TOKEN, &ontoken, sizeof (ontoken)}, 1351 { CKA_PRIVATE, &false, sizeof (false)}, 1352 { CKA_PRIME, &ckDsaPrime, sizeof (ckDsaPrime) }, 1353 { CKA_SUBPRIME, &ckDsaSubPrime, sizeof (ckDsaSubPrime)}, 1354 { CKA_BASE, &ckDsaBase, sizeof (ckDsaBase) }, 1355 { CKA_VERIFY, &true, sizeof (true) }, 1356}; 1357 1358#define NUMBER_DSA_PUB_TEMPLATES (sizeof (ckDsaPubKeyTemplate) / \ 1359 sizeof (CK_ATTRIBUTE)) 1360#define MAX_DSA_PUB_TEMPLATES (sizeof (ckDsaPubKeyTemplate) / \ 1361 sizeof (CK_ATTRIBUTE)) 1362 1363 static CK_ATTRIBUTE ckDsaPriKeyTemplate[] = { 1364 {CKA_CLASS, &priClass, sizeof (priClass)}, 1365 {CKA_KEY_TYPE, &dsaKeyType, sizeof (dsaKeyType)}, 1366 {CKA_TOKEN, &ontoken, sizeof (ontoken)}, 1367 {CKA_PRIVATE, &true, sizeof (true)}, 1368 {CKA_SIGN, &true, sizeof (true)}, 1369 }; 1370 1371 CK_ATTRIBUTE labelattr[1]; 1372 CK_ATTRIBUTE idattr[1]; 1373 char IDHashData[SHA1_HASH_LENGTH]; 1374 KMF_DATA IDInput, IDOutput; 1375 1376#define NUMBER_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \ 1377 sizeof (CK_ATTRIBUTE)) 1378#define MAX_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \ 1379 sizeof (CK_ATTRIBUTE)) 1380 1381 if (!kmfh) 1382 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 1383 1384 if (kmfh->pk11handle == CK_INVALID_HANDLE) 1385 return (KMF_ERR_NO_TOKEN_SELECTED); 1386 1387 if (params == NULL) 1388 return (KMF_ERR_BAD_PARAMETER); 1389 1390 rv = pk11_authenticate(handle, ¶ms->cred); 1391 if (rv != KMF_OK) { 1392 return (rv); 1393 } 1394 1395 if (params->keytype == KMF_RSA) { 1396 CK_MECHANISM keyGenMech = {CKM_RSA_PKCS_KEY_PAIR_GEN, 1397 NULL, 0}; 1398 CK_BYTE *modulus; 1399 CK_ULONG modulusLength; 1400 CK_ATTRIBUTE modattr[1]; 1401 1402 SETATTR(rsaPubKeyTemplate, 0, CKA_CLASS, 1403 &pubClass, sizeof (pubClass)); 1404 SETATTR(rsaPubKeyTemplate, 1, CKA_KEY_TYPE, 1405 &rsaKeyType, sizeof (rsaKeyType)); 1406 SETATTR(rsaPubKeyTemplate, 2, CKA_TOKEN, 1407 &false, sizeof (false)); 1408 SETATTR(rsaPubKeyTemplate, 3, CKA_PRIVATE, 1409 &false, sizeof (false)); 1410 SETATTR(rsaPubKeyTemplate, 4, CKA_MODULUS_BITS, 1411 &modulusBits, sizeof (modulusBits)); 1412 if (params->rsa_exponent.len > 0 && 1413 params->rsa_exponent.val != NULL) { 1414 SETATTR(rsaPubKeyTemplate, 5, 1415 CKA_PUBLIC_EXPONENT, 1416 params->rsa_exponent.val, 1417 params->rsa_exponent.len); 1418 } else { 1419 SETATTR(rsaPubKeyTemplate, 5, 1420 CKA_PUBLIC_EXPONENT, &PubExpo, 1421 sizeof (PubExpo)); 1422 } 1423 SETATTR(rsaPubKeyTemplate, 6, CKA_ENCRYPT, 1424 &true, sizeof (true)); 1425 SETATTR(rsaPubKeyTemplate, 7, CKA_VERIFY, 1426 &true, sizeof (true)); 1427 1428 SETATTR(rsaPriKeyTemplate, 0, CKA_CLASS, &priClass, 1429 sizeof (priClass)); 1430 SETATTR(rsaPriKeyTemplate, 1, CKA_KEY_TYPE, &rsaKeyType, 1431 sizeof (rsaKeyType)); 1432 SETATTR(rsaPriKeyTemplate, 2, CKA_TOKEN, &ontoken, 1433 sizeof (ontoken)); 1434 SETATTR(rsaPriKeyTemplate, 3, CKA_PRIVATE, &true, 1435 sizeof (true)); 1436 SETATTR(rsaPriKeyTemplate, 4, CKA_DECRYPT, &true, 1437 sizeof (true)); 1438 SETATTR(rsaPriKeyTemplate, 5, CKA_SIGN, &true, 1439 sizeof (true)); 1440 1441 SETATTR(modattr, 0, CKA_MODULUS, NULL, &modulusLength); 1442 1443 modulusBits = params->keylength; 1444 1445 pubKey = CK_INVALID_HANDLE; 1446 priKey = CK_INVALID_HANDLE; 1447 ckrv = C_GenerateKeyPair(hSession, &keyGenMech, 1448 rsaPubKeyTemplate, 1449 (sizeof (rsaPubKeyTemplate)/sizeof (CK_ATTRIBUTE)), 1450 rsaPriKeyTemplate, 1451 (sizeof (rsaPriKeyTemplate)/sizeof (CK_ATTRIBUTE)), 1452 &pubKey, &priKey); 1453 if (ckrv != CKR_OK) { 1454 SET_ERROR(kmfh, ckrv); 1455 return (KMF_ERR_KEYGEN_FAILED); 1456 } 1457 1458 if (privkey != NULL) { 1459 privkey->kstype = KMF_KEYSTORE_PK11TOKEN; 1460 privkey->keyalg = KMF_RSA; 1461 privkey->keyclass = KMF_ASYM_PRI; 1462 privkey->keyp = (void *)priKey; 1463 } 1464 if (pubkey != NULL) { 1465 pubkey->kstype = KMF_KEYSTORE_PK11TOKEN; 1466 pubkey->keyalg = KMF_RSA; 1467 pubkey->keyclass = KMF_ASYM_PUB; 1468 pubkey->keyp = (void *)pubKey; 1469 } 1470 1471 /* Get the Modulus field to use as input for creating the ID */ 1472 rv = C_GetAttributeValue(kmfh->pk11handle, 1473 (CK_OBJECT_HANDLE)pubKey, 1474 modattr, 1); 1475 if (rv != CKR_OK) { 1476 SET_ERROR(kmfh, ckrv); 1477 return (KMF_ERR_BAD_PARAMETER); 1478 } 1479 1480 modulusLength = modattr[0].ulValueLen; 1481 modulus = malloc(modulusLength); 1482 if (modulus == NULL) 1483 return (KMF_ERR_MEMORY); 1484 1485 modattr[0].pValue = modulus; 1486 rv = C_GetAttributeValue(kmfh->pk11handle, 1487 (CK_OBJECT_HANDLE)pubKey, 1488 modattr, 1); 1489 if (rv != CKR_OK) { 1490 SET_ERROR(kmfh, ckrv); 1491 free(modulus); 1492 return (KMF_ERR_BAD_PARAMETER); 1493 } 1494 1495 IDInput.Data = modulus; 1496 IDInput.Length = modulusLength; 1497 1498 } else if (params->keytype == KMF_DSA) { 1499 CK_MECHANISM keyGenMech = {CKM_DSA_KEY_PAIR_GEN, NULL, 0}; 1500 CK_BYTE *keyvalue; 1501 CK_ULONG valueLen; 1502 CK_ATTRIBUTE valattr[1]; 1503 1504 SETATTR(ckDsaPriKeyTemplate, 2, CKA_TOKEN, 1505 &ontoken, sizeof (ontoken)); 1506 SETATTR(valattr, 0, CKA_VALUE, NULL, &valueLen); 1507 1508 ckrv = C_GenerateKeyPair(hSession, &keyGenMech, 1509 ckDsaPubKeyTemplate, 1510 (sizeof (ckDsaPubKeyTemplate)/sizeof (CK_ATTRIBUTE)), 1511 ckDsaPriKeyTemplate, 1512 (sizeof (ckDsaPriKeyTemplate)/sizeof (CK_ATTRIBUTE)), 1513 &pubKey, &priKey); 1514 if (ckrv != CKR_OK) { 1515 SET_ERROR(kmfh, ckrv); 1516 return (KMF_ERR_KEYGEN_FAILED); 1517 } 1518 1519 if (privkey != NULL) { 1520 privkey->kstype = KMF_KEYSTORE_PK11TOKEN; 1521 privkey->keyalg = KMF_DSA; 1522 privkey->keyclass = KMF_ASYM_PRI; 1523 privkey->keyp = (void *)priKey; 1524 } 1525 if (pubkey != NULL) { 1526 pubkey->kstype = KMF_KEYSTORE_PK11TOKEN; 1527 pubkey->keyalg = KMF_DSA; 1528 pubkey->keyclass = KMF_ASYM_PUB; 1529 pubkey->keyp = (void *)pubKey; 1530 } 1531 /* Get the Public Value to use as input for creating the ID */ 1532 rv = C_GetAttributeValue(hSession, 1533 (CK_OBJECT_HANDLE)pubKey, 1534 valattr, 1); 1535 if (rv != CKR_OK) { 1536 SET_ERROR(kmfh, ckrv); 1537 return (KMF_ERR_BAD_PARAMETER); 1538 } 1539 1540 valueLen = valattr[0].ulValueLen; 1541 keyvalue = malloc(valueLen); 1542 if (keyvalue == NULL) 1543 return (KMF_ERR_MEMORY); 1544 1545 valattr[0].pValue = keyvalue; 1546 rv = C_GetAttributeValue(hSession, 1547 (CK_OBJECT_HANDLE)pubKey, 1548 valattr, 1); 1549 if (rv != CKR_OK) { 1550 SET_ERROR(kmfh, ckrv); 1551 free(keyvalue); 1552 return (KMF_ERR_BAD_PARAMETER); 1553 } 1554 1555 IDInput.Data = keyvalue; 1556 IDInput.Length = valueLen; 1557 } else { 1558 return (KMF_ERR_BAD_PARAMETER); 1559 } 1560 1561 if (params->keylabel != NULL && 1562 strlen(params->keylabel)) { 1563 1564 SETATTR(labelattr, 0, CKA_LABEL, params->keylabel, 1565 strlen(params->keylabel)); 1566 1567 /* Set the CKA_LABEL if one was indicated */ 1568 if ((ckrv = C_SetAttributeValue(hSession, pubKey, 1569 labelattr, 1)) != CKR_OK) { 1570 SET_ERROR(kmfh, ckrv); 1571 rv = KMF_ERR_INTERNAL; 1572 goto cleanup; 1573 } 1574 if (pubkey != NULL) { 1575 pubkey->keylabel = 1576 (char *)strdup(params->keylabel); 1577 if (pubkey->keylabel == NULL) { 1578 rv = KMF_ERR_MEMORY; 1579 goto cleanup; 1580 } 1581 } 1582 if ((ckrv = C_SetAttributeValue(hSession, priKey, 1583 labelattr, 1)) != CKR_OK) { 1584 SET_ERROR(kmfh, ckrv); 1585 rv = KMF_ERR_INTERNAL; 1586 goto cleanup; 1587 } 1588 if (privkey != NULL) { 1589 privkey->keylabel = 1590 (char *)strdup(params->keylabel); 1591 if (privkey->keylabel == NULL) { 1592 rv = KMF_ERR_MEMORY; 1593 goto cleanup; 1594 } 1595 } 1596 } 1597 1598 /* Now, assign a CKA_ID value so it can be searched */ 1599 /* ID_Input was assigned above in the RSA or DSA keygen section */ 1600 IDOutput.Data = (uchar_t *)IDHashData; 1601 IDOutput.Length = sizeof (IDHashData); 1602 1603 rv = DigestData(hSession, &IDInput, &IDOutput); 1604 free(IDInput.Data); 1605 1606 if (rv != CKR_OK) { 1607 SET_ERROR(kmfh, rv); 1608 goto cleanup; 1609 } 1610 SETATTR(idattr, 0, CKA_ID, IDOutput.Data, IDOutput.Length); 1611 if ((ckrv = C_SetAttributeValue(hSession, pubKey, 1612 idattr, 1)) != CKR_OK) { 1613 SET_ERROR(kmfh, ckrv); 1614 rv = KMF_ERR_INTERNAL; 1615 goto cleanup; 1616 } 1617 if ((ckrv = C_SetAttributeValue(hSession, priKey, 1618 idattr, 1)) != CKR_OK) { 1619 SET_ERROR(kmfh, ckrv); 1620 rv = KMF_ERR_INTERNAL; 1621 goto cleanup; 1622 } 1623 1624cleanup: 1625 if (rv != KMF_OK) { 1626 if (pubKey != CK_INVALID_HANDLE) 1627 (void) C_DestroyObject(hSession, pubKey); 1628 if (priKey != CK_INVALID_HANDLE) 1629 (void) C_DestroyObject(hSession, priKey); 1630 if (privkey) { 1631 privkey->keyp = NULL; 1632 if (privkey->keylabel) 1633 free(privkey->keylabel); 1634 } 1635 if (pubkey) { 1636 pubkey->keyp = NULL; 1637 if (pubkey->keylabel) 1638 free(pubkey->keylabel); 1639 } 1640 } 1641 return (rv); 1642} 1643 1644KMF_RETURN 1645KMFPK11_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params, 1646 KMF_KEY_HANDLE *key, boolean_t destroy) 1647{ 1648 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1649 CK_RV ckrv = CKR_OK; 1650 KMF_RETURN rv = KMF_OK; 1651 1652 if (!kmfh) 1653 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 1654 1655 if (kmfh->pk11handle == CK_INVALID_HANDLE) 1656 return (KMF_ERR_NO_TOKEN_SELECTED); 1657 1658 if (key == NULL || key->keyp == NULL) 1659 return (KMF_ERR_BAD_PARAMETER); 1660 1661 if (key->keyclass != KMF_ASYM_PUB && 1662 key->keyclass != KMF_ASYM_PRI && 1663 key->keyclass != KMF_SYMMETRIC) 1664 return (KMF_ERR_BAD_KEY_CLASS); 1665 1666 if (destroy) { 1667 rv = pk11_authenticate(handle, ¶ms->cred); 1668 if (rv != KMF_OK) { 1669 return (rv); 1670 } 1671 } 1672 1673 if (!key->israw && destroy) 1674 ckrv = C_DestroyObject(kmfh->pk11handle, 1675 (CK_OBJECT_HANDLE)key->keyp); 1676 1677 if (ckrv != CKR_OK) { 1678 SET_ERROR(kmfh, ckrv); 1679 /* Report authentication failures to the caller */ 1680 if (ckrv == CKR_PIN_EXPIRED || 1681 ckrv == CKR_SESSION_READ_ONLY) 1682 rv = KMF_ERR_AUTH_FAILED; 1683 else 1684 rv = KMF_ERR_INTERNAL; 1685 } 1686 return (rv); 1687 1688} 1689 1690KMF_RETURN 1691KMFPK11_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp, 1692 KMF_OID *algOID, 1693 KMF_DATA *tobesigned, 1694 KMF_DATA *output) 1695{ 1696 CK_RV ckrv; 1697 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1698 CK_SESSION_HANDLE hSession = kmfh->pk11handle; 1699 CK_MECHANISM mechanism; 1700 PKCS_ALGORITHM_MAP *pAlgMap; 1701 KMF_ALGORITHM_INDEX AlgId; 1702 1703 if (!kmfh) 1704 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 1705 1706 if (kmfh->pk11handle == CK_INVALID_HANDLE) 1707 return (KMF_ERR_NO_TOKEN_SELECTED); 1708 1709 if (keyp == NULL || algOID == NULL || 1710 tobesigned == NULL || output == NULL) 1711 return (KMF_ERR_BAD_PARAMETER); 1712 1713 /* These functions are available to the plugin from libkmf */ 1714 AlgId = X509_AlgorithmOidToAlgId(algOID); 1715 if (AlgId == KMF_ALGID_NONE) 1716 return (KMF_ERR_BAD_PARAMETER); 1717 1718 /* Map the Algorithm OID to a PKCS#11 mechanism */ 1719 pAlgMap = PKCS_GetAlgorithmMap(KMF_ALGCLASS_SIGNATURE, 1720 AlgId, PKCS_GetDefaultSignatureMode(AlgId)); 1721 1722 if (pAlgMap == NULL) 1723 return (KMF_ERR_BAD_PARAMETER); 1724 1725 mechanism.mechanism = pAlgMap->pkcs_mechanism; 1726 mechanism.pParameter = NULL; 1727 mechanism.ulParameterLen = 0; 1728 1729 ckrv = C_SignInit(hSession, &mechanism, (CK_OBJECT_HANDLE)keyp->keyp); 1730 if (ckrv != CKR_OK) { 1731 SET_ERROR(kmfh, ckrv); 1732 return (KMF_ERR_INTERNAL); 1733 } 1734 1735 ckrv = C_Sign(hSession, 1736 tobesigned->Data, tobesigned->Length, 1737 output->Data, (CK_ULONG *)&output->Length); 1738 1739 if (ckrv != CKR_OK) { 1740 SET_ERROR(kmfh, ckrv); 1741 return (KMF_ERR_INTERNAL); 1742 } 1743 1744 return (KMF_OK); 1745} 1746 1747KMF_RETURN 1748KMFPK11_GetErrorString(KMF_HANDLE_T handle, char **msgstr) 1749{ 1750 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1751 1752 *msgstr = NULL; 1753 if (kmfh->lasterr.errcode != 0) { 1754 char *e = pkcs11_strerror(kmfh->lasterr.errcode); 1755 if (e == NULL || (*msgstr = (char *)strdup(e)) == NULL) { 1756 return (KMF_ERR_MEMORY); 1757 } 1758 } 1759 1760 return (KMF_OK); 1761} 1762 1763static CK_RV 1764getObjectKeytype(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj, 1765 CK_ULONG *keytype) 1766{ 1767 CK_RV rv = CKR_OK; 1768 CK_ATTRIBUTE templ; 1769 CK_ULONG len = sizeof (CK_ULONG); 1770 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1771 1772 templ.type = CKA_KEY_TYPE; 1773 templ.pValue = keytype; 1774 templ.ulValueLen = len; 1775 1776 rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1); 1777 1778 return (rv); 1779 1780} 1781static CK_RV 1782getObjectLabel(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj, 1783 char **outlabel) 1784{ 1785 CK_RV rv = CKR_OK; 1786 CK_ATTRIBUTE templ; 1787 char Label[BUFSIZ]; 1788 CK_ULONG len = sizeof (Label); 1789 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1790 1791 (void) memset(Label, 0, len); 1792 templ.type = CKA_LABEL; 1793 templ.pValue = Label; 1794 templ.ulValueLen = len; 1795 1796 rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1); 1797 if (rv == CKR_OK) { 1798 *outlabel = (char *)strdup(Label); 1799 } else { 1800 *outlabel = NULL; 1801 } 1802 return (rv); 1803} 1804 1805KMF_RETURN 1806KMFPK11_GetPrikeyByCert(KMF_HANDLE_T handle, 1807 KMF_CRYPTOWITHCERT_PARAMS *params, 1808 KMF_DATA *SignerCertData, KMF_KEY_HANDLE *key, 1809 KMF_KEY_ALG keytype) 1810{ 1811 KMF_X509_SPKI *pubkey; 1812 KMF_X509_CERTIFICATE *SignerCert = NULL; 1813 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1814 KMF_RETURN rv = KMF_OK; 1815 CK_RV ckrv = CKR_OK; 1816 CK_ATTRIBUTE templ[4]; 1817 CK_OBJECT_HANDLE pri_obj = CK_INVALID_HANDLE; 1818 CK_ULONG obj_count; 1819 CK_OBJECT_CLASS certClass = CKO_PRIVATE_KEY; 1820 CK_BBOOL true = TRUE; 1821 KMF_DATA Id = { NULL, 0 }; 1822 1823 /* Decode the signer cert so we can get the SPKI data */ 1824 if ((rv = DerDecodeSignedCertificate(SignerCertData, 1825 &SignerCert)) != KMF_OK) 1826 return (rv); 1827 1828 /* Get the public key info from the signer certificate */ 1829 pubkey = &SignerCert->certificate.subjectPublicKeyInfo; 1830 1831 /* Generate an ID from the SPKI data */ 1832 rv = GetIDFromSPKI(pubkey, &Id); 1833 1834 if (rv != KMF_OK) { 1835 SET_ERROR(kmfh, rv); 1836 goto errout; 1837 } 1838 1839 SETATTR(templ, 0, CKA_CLASS, &certClass, sizeof (certClass)); 1840 SETATTR(templ, 1, CKA_TOKEN, &true, sizeof (true)); 1841 SETATTR(templ, 2, CKA_PRIVATE, &true, sizeof (true)); 1842 SETATTR(templ, 3, CKA_ID, Id.Data, Id.Length); 1843 1844 rv = pk11_authenticate(handle, ¶ms->cred); 1845 if (rv != KMF_OK) { 1846 return (rv); 1847 } 1848 1849 if ((ckrv = C_FindObjectsInit(kmfh->pk11handle, templ, 4)) != CKR_OK) { 1850 SET_ERROR(kmfh, ckrv); 1851 rv = KMF_ERR_INTERNAL; 1852 goto errout; 1853 } 1854 1855 if ((rv = C_FindObjects(kmfh->pk11handle, &pri_obj, 1, 1856 &obj_count)) != CKR_OK) { 1857 SET_ERROR(kmfh, ckrv); 1858 rv = KMF_ERR_INTERNAL; 1859 goto errout; 1860 } 1861 1862 if (obj_count == 0) { 1863 SET_ERROR(kmfh, ckrv); 1864 rv = KMF_ERR_INTERNAL; 1865 goto errout; 1866 } 1867 1868 key->kstype = KMF_KEYSTORE_PK11TOKEN; 1869 key->keyclass = KMF_ASYM_PRI; 1870 key->keyalg = keytype; 1871 key->keyp = (void *)pri_obj; 1872 1873 (void) C_FindObjectsFinal(kmfh->pk11handle); 1874 1875 ckrv = getObjectLabel(handle, (CK_OBJECT_HANDLE)key->keyp, 1876 &key->keylabel); 1877 1878 if (ckrv != CKR_OK) { 1879 SET_ERROR(handle, ckrv); 1880 rv = KMF_ERR_INTERNAL; 1881 } else { 1882 rv = KMF_OK; 1883 } 1884 1885 if (rv == KMF_OK && params->format == KMF_FORMAT_RAWKEY) { 1886 KMF_RAW_KEY_DATA *rkey = NULL; 1887 rv = keyObj2RawKey(handle, key, &rkey); 1888 if (rv == KMF_OK) { 1889 key->keyp = rkey; 1890 key->israw = TRUE; 1891 } 1892 } 1893 1894errout: 1895 if (Id.Data != NULL) 1896 free(Id.Data); 1897 1898 if (SignerCert != NULL) { 1899 KMF_FreeSignedCert(SignerCert); 1900 free(SignerCert); 1901 } 1902 return (rv); 1903} 1904 1905KMF_RETURN 1906KMFPK11_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 1907 KMF_OID *algOID, KMF_DATA *ciphertext, 1908 KMF_DATA *output) 1909{ 1910 CK_RV ckrv; 1911 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1912 CK_SESSION_HANDLE hSession = kmfh->pk11handle; 1913 CK_MECHANISM mechanism; 1914 PKCS_ALGORITHM_MAP *pAlgMap; 1915 KMF_ALGORITHM_INDEX AlgId; 1916 CK_ULONG out_len = 0, block_len = 0, total_decrypted = 0; 1917 uint8_t *in_data, *out_data; 1918 int i, blocks; 1919 CK_ATTRIBUTE ckTemplate[1]; 1920 1921 if (!kmfh) 1922 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 1923 1924 if (kmfh->pk11handle == CK_INVALID_HANDLE) 1925 return (KMF_ERR_NO_TOKEN_SELECTED); 1926 1927 if (key == NULL || algOID == NULL || 1928 ciphertext == NULL || output == NULL) 1929 return (KMF_ERR_BAD_PARAMETER); 1930 1931 AlgId = X509_AlgorithmOidToAlgId(algOID); 1932 if (AlgId == KMF_ALGID_NONE) 1933 return (KMF_ERR_BAD_PARAMETER); 1934 1935 /* Map the Algorithm ID to a PKCS#11 mechanism */ 1936 pAlgMap = PKCS_GetAlgorithmMap(KMF_ALGCLASS_SIGNATURE, 1937 AlgId, PKCS_GetDefaultSignatureMode(AlgId)); 1938 1939 if (pAlgMap == NULL) 1940 return (KMF_ERR_BAD_PARAMETER); 1941 1942 mechanism.mechanism = pAlgMap->pkcs_mechanism; 1943 mechanism.pParameter = NULL; 1944 mechanism.ulParameterLen = 0; 1945 1946 SETATTR(ckTemplate, 0, CKA_MODULUS, (CK_BYTE *)NULL, 1947 sizeof (CK_ULONG)); 1948 1949 /* Get the modulus length */ 1950 ckrv = C_GetAttributeValue(hSession, 1951 (CK_OBJECT_HANDLE)key->keyp, ckTemplate, 1); 1952 1953 if (ckrv != CKR_OK) { 1954 SET_ERROR(kmfh, ckrv); 1955 return (KMF_ERR_INTERNAL); 1956 } 1957 1958 block_len = ckTemplate[0].ulValueLen; 1959 1960 /* Compute the number of times to do single-part decryption */ 1961 blocks = ciphertext->Length/block_len; 1962 1963 out_data = output->Data; 1964 in_data = ciphertext->Data; 1965 out_len = block_len - 11; 1966 1967 for (i = 0; i < blocks; i++) { 1968 ckrv = C_DecryptInit(hSession, &mechanism, 1969 (CK_OBJECT_HANDLE)key->keyp); 1970 1971 if (ckrv != CKR_OK) { 1972 SET_ERROR(kmfh, ckrv); 1973 return (KMF_ERR_INTERNAL); 1974 } 1975 1976 ckrv = C_Decrypt(hSession, in_data, block_len, 1977 out_data, (CK_ULONG *)&out_len); 1978 1979 if (ckrv != CKR_OK) { 1980 SET_ERROR(kmfh, ckrv); 1981 return (KMF_ERR_INTERNAL); 1982 } 1983 1984 out_data += out_len; 1985 total_decrypted += out_len; 1986 in_data += block_len; 1987 1988 } 1989 1990 output->Length = total_decrypted; 1991 return (KMF_OK); 1992} 1993 1994static void 1995attr2bigint(CK_ATTRIBUTE_PTR attr, KMF_BIGINT *big) 1996{ 1997 big->val = attr->pValue; 1998 big->len = attr->ulValueLen; 1999} 2000 2001 2002static KMF_RETURN 2003get_raw_rsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_RSA_KEY *rawrsa) 2004{ 2005 KMF_RETURN rv = KMF_OK; 2006 CK_RV ckrv; 2007 CK_SESSION_HANDLE sess = kmfh->pk11handle; 2008 CK_ATTRIBUTE rsa_pri_attrs[8] = { 2009 { CKA_MODULUS, NULL, 0 }, 2010 { CKA_PUBLIC_EXPONENT, NULL, 0 }, 2011 { CKA_PRIVATE_EXPONENT, NULL, 0 }, /* optional */ 2012 { CKA_PRIME_1, NULL, 0 }, /* | */ 2013 { CKA_PRIME_2, NULL, 0 }, /* | */ 2014 { CKA_EXPONENT_1, NULL, 0 }, /* | */ 2015 { CKA_EXPONENT_2, NULL, 0 }, /* | */ 2016 { CKA_COEFFICIENT, NULL, 0 } /* V */ 2017 }; 2018 CK_ULONG count = sizeof (rsa_pri_attrs) / sizeof (CK_ATTRIBUTE); 2019 int i; 2020 2021 if ((ckrv = C_GetAttributeValue(sess, obj, 2022 rsa_pri_attrs, count)) != CKR_OK) { 2023 SET_ERROR(kmfh, ckrv); 2024 /* Tell the caller know why the key data cannot be retrieved. */ 2025 if (ckrv == CKR_ATTRIBUTE_SENSITIVE) 2026 return (KMF_ERR_SENSITIVE_KEY); 2027 else if (ckrv == CKR_KEY_UNEXTRACTABLE) 2028 return (KMF_ERR_UNEXTRACTABLE_KEY); 2029 else 2030 return (KMF_ERR_INTERNAL); 2031 } 2032 2033 /* Allocate memory for each attribute. */ 2034 for (i = 0; i < count; i++) { 2035 if (rsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 || 2036 rsa_pri_attrs[i].ulValueLen == 0) { 2037 rsa_pri_attrs[i].ulValueLen = 0; 2038 continue; 2039 } 2040 if ((rsa_pri_attrs[i].pValue = 2041 malloc(rsa_pri_attrs[i].ulValueLen)) == NULL) { 2042 rv = KMF_ERR_MEMORY; 2043 goto end; 2044 } 2045 } 2046 /* Now that we have space, really get the attributes */ 2047 if ((rv = C_GetAttributeValue(sess, obj, 2048 rsa_pri_attrs, count)) != CKR_OK) { 2049 SET_ERROR(kmfh, rv); 2050 rv = KMF_ERR_INTERNAL; 2051 goto end; 2052 } 2053 i = 0; 2054 attr2bigint(&(rsa_pri_attrs[i++]), &rawrsa->mod); 2055 attr2bigint(&(rsa_pri_attrs[i++]), &rawrsa->pubexp); 2056 2057 if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 && 2058 rsa_pri_attrs[i].ulValueLen != 0) 2059 attr2bigint(&(rsa_pri_attrs[i]), &rawrsa->priexp); 2060 i++; 2061 2062 if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 && 2063 rsa_pri_attrs[i].ulValueLen != 0) 2064 attr2bigint(&(rsa_pri_attrs[i]), &rawrsa->prime1); 2065 i++; 2066 2067 if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 && 2068 rsa_pri_attrs[i].ulValueLen != 0) 2069 attr2bigint(&(rsa_pri_attrs[i]), &rawrsa->prime2); 2070 i++; 2071 2072 if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 && 2073 rsa_pri_attrs[i].ulValueLen != 0) 2074 attr2bigint(&(rsa_pri_attrs[i]), &rawrsa->exp1); 2075 i++; 2076 2077 if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 && 2078 rsa_pri_attrs[i].ulValueLen != 0) 2079 attr2bigint(&(rsa_pri_attrs[i]), &rawrsa->exp2); 2080 i++; 2081 2082 if (rsa_pri_attrs[i].ulValueLen != (CK_ULONG)-1 && 2083 rsa_pri_attrs[i].ulValueLen != 0) 2084 attr2bigint(&(rsa_pri_attrs[i]), &rawrsa->coef); 2085 i++; 2086 2087end: 2088 if (rv != KMF_OK) { 2089 for (i = 0; i < count; i++) { 2090 if (rsa_pri_attrs[i].pValue != NULL) 2091 free(rsa_pri_attrs[i].pValue); 2092 } 2093 (void) memset(rawrsa, 0, sizeof (KMF_RAW_RSA_KEY)); 2094 } 2095 return (rv); 2096} 2097 2098static KMF_RETURN 2099get_raw_dsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_DSA_KEY *rawdsa) 2100{ 2101 KMF_RETURN rv = KMF_OK; 2102 CK_SESSION_HANDLE sess = kmfh->pk11handle; 2103 CK_ATTRIBUTE dsa_pri_attrs[8] = { 2104 { CKA_PRIME, NULL, 0 }, 2105 { CKA_SUBPRIME, NULL, 0 }, 2106 { CKA_BASE, NULL, 0 }, 2107 { CKA_VALUE, NULL, 0 } 2108 }; 2109 CK_ULONG count = sizeof (dsa_pri_attrs) / sizeof (CK_ATTRIBUTE); 2110 int i; 2111 2112 if ((rv = C_GetAttributeValue(sess, obj, 2113 dsa_pri_attrs, count)) != CKR_OK) { 2114 SET_ERROR(kmfh, rv); 2115 return (KMF_ERR_INTERNAL); 2116 } 2117 2118 /* Allocate memory for each attribute. */ 2119 for (i = 0; i < count; i++) { 2120 if (dsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 || 2121 dsa_pri_attrs[i].ulValueLen == 0) { 2122 dsa_pri_attrs[i].ulValueLen = 0; 2123 continue; 2124 } 2125 if ((dsa_pri_attrs[i].pValue = 2126 malloc(dsa_pri_attrs[i].ulValueLen)) == NULL) { 2127 rv = KMF_ERR_MEMORY; 2128 goto end; 2129 } 2130 } 2131 if ((rv = C_GetAttributeValue(sess, obj, 2132 dsa_pri_attrs, count)) != CKR_OK) { 2133 SET_ERROR(kmfh, rv); 2134 rv = KMF_ERR_INTERNAL; 2135 goto end; 2136 } 2137 2138 /* Fill in all the temp variables. They are all required. */ 2139 i = 0; 2140 attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->prime); 2141 attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->subprime); 2142 attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->base); 2143 attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->value); 2144 2145end: 2146 if (rv != KMF_OK) { 2147 for (i = 0; i < count; i++) { 2148 if (dsa_pri_attrs[i].pValue != NULL) 2149 free(dsa_pri_attrs[i].pValue); 2150 } 2151 (void) memset(rawdsa, 0, sizeof (KMF_RAW_DSA_KEY)); 2152 } 2153 return (rv); 2154} 2155 2156static KMF_RETURN 2157get_raw_sym(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_SYM_KEY *rawsym) 2158{ 2159 KMF_RETURN rv = KMF_OK; 2160 CK_RV ckrv; 2161 CK_SESSION_HANDLE sess = kmfh->pk11handle; 2162 CK_ATTRIBUTE sym_attr[1]; 2163 CK_ULONG value_len = 0; 2164 2165 /* find the key length first */ 2166 sym_attr[0].type = CKA_VALUE; 2167 sym_attr[0].pValue = NULL; 2168 sym_attr[0].ulValueLen = value_len; 2169 if ((ckrv = C_GetAttributeValue(sess, obj, sym_attr, 1)) != CKR_OK) { 2170 /* 2171 * Don't return error if the key is sensitive, just 2172 * don't return any raw data. Operations like "list" 2173 * need to succeed even if the raw data is not 2174 * available. 2175 */ 2176 if (ckrv == CKR_ATTRIBUTE_SENSITIVE) { 2177 rawsym->keydata.val = NULL; 2178 rawsym->keydata.len = 0; 2179 return (CKR_OK); 2180 } 2181 SET_ERROR(kmfh, ckrv); 2182 return (KMF_ERR_INTERNAL); 2183 } 2184 2185 /* Allocate memory for pValue */ 2186 sym_attr[0].pValue = malloc(sym_attr[0].ulValueLen); 2187 if (sym_attr[0].pValue == NULL) { 2188 return (KMF_ERR_MEMORY); 2189 } 2190 2191 /* get the key data */ 2192 if ((rv = C_GetAttributeValue(sess, obj, sym_attr, 1)) != CKR_OK) { 2193 SET_ERROR(kmfh, rv); 2194 free(sym_attr[0].pValue); 2195 return (KMF_ERR_INTERNAL); 2196 } 2197 2198 rawsym->keydata.val = sym_attr[0].pValue; 2199 rawsym->keydata.len = sym_attr[0].ulValueLen; 2200 return (rv); 2201} 2202 2203static KMF_RETURN 2204keyObj2RawKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *inkey, 2205 KMF_RAW_KEY_DATA **outkey) 2206{ 2207 KMF_RETURN rv = KMF_OK; 2208 KMF_RAW_KEY_DATA *rkey; 2209 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2210 2211 rkey = malloc(sizeof (KMF_RAW_KEY_DATA)); 2212 if (rkey == NULL) 2213 return (KMF_ERR_MEMORY); 2214 2215 (void) memset(rkey, 0, sizeof (KMF_RAW_KEY_DATA)); 2216 2217 rkey->keytype = inkey->keyalg; 2218 2219 if (inkey->keyalg == KMF_RSA) { 2220 rv = get_raw_rsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp, 2221 &rkey->rawdata.rsa); 2222 } else if (inkey->keyalg == KMF_DSA) { 2223 rv = get_raw_dsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp, 2224 &rkey->rawdata.dsa); 2225 } else if (inkey->keyalg == KMF_AES || 2226 inkey->keyalg == KMF_RC4 || 2227 inkey->keyalg == KMF_DES || 2228 inkey->keyalg == KMF_DES3) { 2229 rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)inkey->keyp, 2230 &rkey->rawdata.sym); 2231 } else { 2232 rv = KMF_ERR_BAD_PARAMETER; 2233 } 2234 2235 if (rv == KMF_OK) { 2236 *outkey = rkey; 2237 } else if (rkey != NULL) { 2238 free(rkey); 2239 *outkey = NULL; 2240 } 2241 2242 return (rv); 2243} 2244 2245 2246static KMF_RETURN 2247kmf2pk11keytype(KMF_KEY_ALG keyalg, CK_KEY_TYPE *type) 2248{ 2249 switch (keyalg) { 2250 case KMF_RSA: 2251 *type = CKK_RSA; 2252 break; 2253 case KMF_DSA: 2254 *type = CKK_DSA; 2255 break; 2256 case KMF_AES: 2257 *type = CKK_AES; 2258 break; 2259 case KMF_RC4: 2260 *type = CKK_RC4; 2261 break; 2262 case KMF_DES: 2263 *type = CKK_DES; 2264 break; 2265 case KMF_DES3: 2266 *type = CKK_DES3; 2267 break; 2268 default: 2269 return (KMF_ERR_BAD_KEY_TYPE); 2270 } 2271 2272 return (KMF_OK); 2273} 2274 2275static int 2276IDStringToData(char *idstr, KMF_DATA *iddata) 2277{ 2278 int len, i; 2279 char *iddup, *byte; 2280 uint_t lvalue; 2281 2282 if (idstr == NULL || !strlen(idstr)) 2283 return (-1); 2284 2285 iddup = (char *)strdup(idstr); 2286 if (iddup == NULL) 2287 return (KMF_ERR_MEMORY); 2288 2289 len = strlen(iddup) / 3 + 1; 2290 iddata->Data = malloc(len); 2291 if (iddata->Data == NULL) 2292 return (KMF_ERR_MEMORY); 2293 (void) memset(iddata->Data, 0, len); 2294 iddata->Length = len; 2295 2296 byte = strtok(iddup, ":"); 2297 if (byte == NULL) { 2298 free(iddup); 2299 free(iddata->Data); 2300 iddata->Data = NULL; 2301 iddata->Length = 0; 2302 return (-1); 2303 } 2304 2305 i = 0; 2306 do { 2307 (void) sscanf(byte, "%x", &lvalue); 2308 iddata->Data[i++] = (uchar_t)(lvalue & 0x000000FF); 2309 byte = strtok(NULL, ":"); 2310 } while (byte != NULL && i < len); 2311 2312 iddata->Length = i; 2313 free(iddup); 2314 return (0); 2315} 2316 2317KMF_RETURN 2318KMFPK11_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, 2319 KMF_KEY_HANDLE *keys, uint32_t *numkeys) 2320{ 2321 KMF_RETURN rv = KMF_OK; 2322 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2323 uint32_t want_keys, i; 2324 CK_RV ckrv; 2325 CK_ATTRIBUTE pTmpl[10]; 2326 CK_OBJECT_CLASS class; 2327 CK_BBOOL true = TRUE; 2328 CK_ULONG alg; 2329 CK_BBOOL is_token; 2330 2331 if (!kmfh) 2332 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 2333 2334 if (kmfh->pk11handle == CK_INVALID_HANDLE) 2335 return (KMF_ERR_NO_TOKEN_SELECTED); 2336 2337 if (parms == NULL || numkeys == NULL) 2338 return (KMF_ERR_BAD_PARAMETER); 2339 2340 if (numkeys != NULL && *numkeys > 0) 2341 want_keys = *numkeys; 2342 else 2343 want_keys = MAXINT; /* count them all */ 2344 2345 is_token = parms->pkcs11parms.token; 2346 if (parms->keyclass == KMF_ASYM_PUB) { 2347 class = CKO_PUBLIC_KEY; 2348 } else if (parms->keyclass == KMF_ASYM_PRI) { 2349 class = CKO_PRIVATE_KEY; 2350 } else if (parms->keyclass == KMF_SYMMETRIC) { 2351 class = CKO_SECRET_KEY; 2352 } else { 2353 return (KMF_ERR_BAD_KEY_CLASS); 2354 } 2355 2356 i = 0; 2357 pTmpl[i].type = CKA_TOKEN; 2358 pTmpl[i].pValue = &is_token; 2359 pTmpl[i].ulValueLen = sizeof (CK_BBOOL); 2360 i++; 2361 2362 pTmpl[i].type = CKA_CLASS; 2363 pTmpl[i].pValue = &class; 2364 pTmpl[i].ulValueLen = sizeof (class); 2365 i++; 2366 2367 if (parms->findLabel != NULL && strlen(parms->findLabel)) { 2368 pTmpl[i].type = CKA_LABEL; 2369 pTmpl[i].pValue = parms->findLabel; 2370 pTmpl[i].ulValueLen = strlen(parms->findLabel); 2371 i++; 2372 } 2373 2374 if (parms->keytype != 0) { 2375 rv = kmf2pk11keytype(parms->keytype, &alg); 2376 if (rv != KMF_OK) { 2377 return (KMF_ERR_BAD_KEY_TYPE); 2378 } 2379 pTmpl[i].type = CKA_KEY_TYPE; 2380 pTmpl[i].pValue = &alg; 2381 pTmpl[i].ulValueLen = sizeof (alg); 2382 i++; 2383 } 2384 2385 if (parms->idstr != NULL) { 2386 KMF_DATA iddata = { NULL, 0 }; 2387 2388 /* 2389 * ID String parameter is assumed to be of form: 2390 * XX:XX:XX:XX:XX ... :XX 2391 * where XX is a hex number. 2392 * 2393 * We must convert this back to binary in order to 2394 * use it in a search. 2395 */ 2396 rv = IDStringToData(parms->idstr, &iddata); 2397 if (rv == KMF_OK) { 2398 pTmpl[i].type = CKA_ID; 2399 pTmpl[i].pValue = iddata.Data; 2400 pTmpl[i].ulValueLen = iddata.Length; 2401 i++; 2402 } else { 2403 return (rv); 2404 } 2405 } 2406 2407 if (parms->pkcs11parms.private) { 2408 pTmpl[i].type = CKA_PRIVATE; 2409 pTmpl[i].pValue = &true; 2410 pTmpl[i].ulValueLen = sizeof (true); 2411 i++; 2412 } 2413 2414 /* 2415 * Authenticate if the object is a token object, 2416 * a private or secred key, or if the user passed in credentials. 2417 */ 2418 if (parms->cred.credlen > 0) { 2419 rv = pk11_authenticate(handle, &parms->cred); 2420 if (rv != KMF_OK) { 2421 return (rv); 2422 } 2423 } 2424 2425 ckrv = C_FindObjectsInit(kmfh->pk11handle, pTmpl, i); 2426 if (ckrv == CKR_OK) { 2427 CK_ULONG obj_count, n = 0; 2428 while (ckrv == CKR_OK && n < want_keys) { 2429 CK_OBJECT_HANDLE hObj; 2430 2431 ckrv = C_FindObjects(kmfh->pk11handle, &hObj, 2432 1, &obj_count); 2433 if (ckrv == CKR_OK && obj_count == 1) { 2434 if (keys != NULL) { 2435 CK_ULONG keytype; 2436 keys[n].kstype = KMF_KEYSTORE_PK11TOKEN; 2437 keys[n].keyclass = parms->keyclass; 2438 keys[n].israw = FALSE; 2439 keys[n].keyp = (void *)hObj; 2440 2441 ckrv = getObjectKeytype(handle, 2442 (CK_OBJECT_HANDLE)keys[n].keyp, 2443 &keytype); 2444 if (ckrv != CKR_OK) 2445 goto end; 2446 2447 ckrv = getObjectLabel(handle, 2448 (CK_OBJECT_HANDLE)keys[n].keyp, 2449 &(keys[n].keylabel)); 2450 if (ckrv != CKR_OK) 2451 goto end; 2452 2453 if (keytype == CKK_RSA) 2454 keys[n].keyalg = KMF_RSA; 2455 else if (keytype == CKK_DSA) 2456 keys[n].keyalg = KMF_DSA; 2457 else if (keytype == CKK_AES) 2458 keys[n].keyalg = KMF_AES; 2459 else if (keytype == CKK_RC4) 2460 keys[n].keyalg = KMF_RC4; 2461 else if (keytype == CKK_DES) 2462 keys[n].keyalg = KMF_DES; 2463 else if (keytype == CKK_DES3) 2464 keys[n].keyalg = KMF_DES3; 2465 2466 } 2467 n++; 2468 } else { 2469 break; 2470 } 2471 } 2472 ckrv = C_FindObjectsFinal(kmfh->pk11handle); 2473 2474 /* "numkeys" indicates the number that were actually found */ 2475 *numkeys = n; 2476 } 2477 if (ckrv == KMF_OK && keys != NULL && (*numkeys) > 0) { 2478 if (parms->format == KMF_FORMAT_RAWKEY) { 2479 /* Convert keys to "rawkey" format */ 2480 for (i = 0; i < (*numkeys); i++) { 2481 KMF_RAW_KEY_DATA *rkey = NULL; 2482 rv = keyObj2RawKey(handle, &keys[i], &rkey); 2483 if (rv == KMF_OK) { 2484 keys[i].keyp = rkey; 2485 keys[i].israw = TRUE; 2486 } else { 2487 break; 2488 } 2489 } 2490 } 2491 } 2492end: 2493 if (ckrv != CKR_OK) { 2494 SET_ERROR(kmfh, ckrv); 2495 /* Report authentication failures to the caller */ 2496 if (ckrv == CKR_USER_NOT_LOGGED_IN || 2497 ckrv == CKR_PIN_INCORRECT || 2498 ckrv == CKR_PIN_INVALID || 2499 ckrv == CKR_PIN_EXPIRED || 2500 ckrv == CKR_PIN_LOCKED || 2501 ckrv == CKR_SESSION_READ_ONLY) 2502 rv = KMF_ERR_AUTH_FAILED; 2503 else 2504 rv = KMF_ERR_INTERNAL; 2505 } else if ((*numkeys) == 0) { 2506 rv = KMF_ERR_KEY_NOT_FOUND; 2507 } 2508 2509 return (rv); 2510} 2511 2512static char * 2513convertDate(char *fulldate) 2514{ 2515 struct tm tms; 2516 char newtime[9]; 2517 2518 (void) strptime(fulldate, "%b %d %T %Y %Z", &tms); 2519 2520 if (tms.tm_year < 69) 2521 tms.tm_year += 100; 2522 2523 (void) strftime(newtime, sizeof (newtime), "m%d", &tms); 2524 2525 newtime[8] = 0; 2526 2527 /* memory returned must be freed by the caller */ 2528 return ((char *)strdup(newtime)); 2529} 2530 2531KMF_RETURN 2532KMFPK11_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, 2533 KMF_RAW_KEY_DATA *rawkey) 2534{ 2535 KMF_RETURN rv = KMF_OK; 2536 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2537 int i; 2538 CK_RV ckrv = CKR_OK; 2539 CK_ATTRIBUTE templ[32]; 2540 CK_OBJECT_HANDLE keyobj; 2541 CK_KEY_TYPE keytype; 2542 CK_OBJECT_CLASS oClass = CKO_PRIVATE_KEY; 2543 CK_BBOOL cktrue = TRUE; 2544 CK_DATE startdate, enddate; 2545 KMF_DATA id = {NULL, 0}; 2546 KMF_DATA subject = {NULL, 0}; 2547 KMF_X509EXT_KEY_USAGE kuext; 2548 KMF_X509_CERTIFICATE *x509 = NULL; 2549 CK_BBOOL kufound; 2550 char *notbefore = NULL, *start = NULL; 2551 char *notafter = NULL, *end = NULL; 2552 2553 if (!kmfh) 2554 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 2555 2556 if (kmfh->pk11handle == CK_INVALID_HANDLE) 2557 return (KMF_ERR_NO_TOKEN_SELECTED); 2558 2559 if (params == NULL || params->certificate == NULL || 2560 rawkey == NULL) 2561 return (KMF_ERR_BAD_PARAMETER); 2562 2563 if (rawkey->keytype == KMF_RSA) 2564 keytype = CKK_RSA; 2565 else if (rawkey->keytype == KMF_DSA) 2566 keytype = CKK_DSA; 2567 else 2568 return (KMF_ERR_BAD_PARAMETER); 2569 2570 rv = pk11_authenticate(handle, ¶ms->cred); 2571 if (rv != KMF_OK) { 2572 return (rv); 2573 } 2574 2575 id.Data = NULL; 2576 id.Length = 0; 2577 rv = KMF_GetCertIDData(params->certificate, &id); 2578 if (rv != KMF_OK) { 2579 goto cleanup; 2580 } 2581 2582 rv = DerDecodeSignedCertificate( 2583 (const KMF_DATA *)params->certificate, &x509); 2584 if (rv != KMF_OK) { 2585 goto cleanup; 2586 } 2587 2588 rv = DerEncodeName(&x509->certificate.subject, &subject); 2589 if (rv != KMF_OK) { 2590 goto cleanup; 2591 } 2592 2593 rv = KMF_GetCertStartDateString(handle, params->certificate, 2594 ¬before); 2595 if (rv != KMF_OK) { 2596 goto cleanup; 2597 } 2598 start = convertDate(notbefore); 2599 2600 rv = KMF_GetCertEndDateString(handle, params->certificate, 2601 ¬after); 2602 if (rv != KMF_OK) { 2603 goto cleanup; 2604 } 2605 end = convertDate(notafter); 2606 2607 if ((rv = KMF_GetCertKeyUsageExt(params->certificate, &kuext)) 2608 != KMF_OK && rv != KMF_ERR_EXTENSION_NOT_FOUND) 2609 goto cleanup; 2610 2611 kufound = (rv == KMF_OK); 2612 rv = KMF_OK; /* reset if we got KMF_ERR_EXTENSION_NOT_FOUND above */ 2613 2614 i = 0; 2615 SETATTR(templ, i, CKA_CLASS, &oClass, sizeof (CK_OBJECT_CLASS)); i++; 2616 SETATTR(templ, i, CKA_KEY_TYPE, &keytype, sizeof (keytype)); i++; 2617 SETATTR(templ, i, CKA_TOKEN, &cktrue, sizeof (cktrue)); i++; 2618 SETATTR(templ, i, CKA_PRIVATE, &cktrue, sizeof (cktrue)); i++; 2619 SETATTR(templ, i, CKA_SUBJECT, subject.Data, subject.Length); i++; 2620 SETATTR(templ, i, CKA_DECRYPT, &cktrue, sizeof (cktrue)); i++; 2621 2622 /* 2623 * Only set the KeyUsage stuff if the KU extension was present. 2624 */ 2625 if (kufound) { 2626 CK_BBOOL condition; 2627 2628 condition = (kuext.KeyUsageBits & KMF_keyEncipherment) ? 2629 B_TRUE : B_FALSE; 2630 SETATTR(templ, i, CKA_UNWRAP, &condition, 2631 sizeof (CK_BBOOL)); i++; 2632 condition = (kuext.KeyUsageBits & KMF_dataEncipherment) ? 2633 B_TRUE : B_FALSE; 2634 SETATTR(templ, i, CKA_DECRYPT, &condition, 2635 sizeof (CK_BBOOL)); i++; 2636 condition = (kuext.KeyUsageBits & KMF_digitalSignature) ? 2637 B_TRUE : B_FALSE; 2638 SETATTR(templ, i, CKA_SIGN, &condition, 2639 sizeof (CK_BBOOL)); i++; 2640 condition = (kuext.KeyUsageBits & KMF_digitalSignature) ? 2641 B_TRUE : B_FALSE; 2642 SETATTR(templ, i, CKA_SIGN_RECOVER, &condition, 2643 sizeof (CK_BBOOL)); i++; 2644 } 2645 if (params->label != NULL) { 2646 SETATTR(templ, i, CKA_LABEL, params->label, 2647 strlen(params->label)); 2648 i++; 2649 } 2650 if (id.Data != NULL && 2651 id.Data != NULL && id.Length > 0) { 2652 SETATTR(templ, i, CKA_ID, id.Data, id.Length); 2653 i++; 2654 } 2655 if (start != NULL) { 2656 /* 2657 * This make some potentially dangerous assumptions: 2658 * 1. that the startdate in the parameter block is 2659 * properly formatted as YYYYMMDD 2660 * 2. That the CK_DATE structure is always the same. 2661 */ 2662 (void) memcpy(&startdate, start, sizeof (CK_DATE)); 2663 SETATTR(templ, i, CKA_START_DATE, &startdate, 2664 sizeof (startdate)); 2665 i++; 2666 } 2667 if (end != NULL) { 2668 (void) memcpy(&enddate, end, sizeof (CK_DATE)); 2669 SETATTR(templ, i, CKA_END_DATE, &enddate, sizeof (enddate)); 2670 i++; 2671 } 2672 if (keytype == CKK_RSA) { 2673 SETATTR(templ, i, CKA_MODULUS, 2674 rawkey->rawdata.rsa.mod.val, 2675 rawkey->rawdata.rsa.mod.len); 2676 i++; 2677 SETATTR(templ, i, CKA_PUBLIC_EXPONENT, 2678 rawkey->rawdata.rsa.pubexp.val, 2679 rawkey->rawdata.rsa.pubexp.len); 2680 i++; 2681 if (rawkey->rawdata.rsa.priexp.val != NULL) { 2682 SETATTR(templ, i, CKA_PRIVATE_EXPONENT, 2683 rawkey->rawdata.rsa.priexp.val, 2684 rawkey->rawdata.rsa.priexp.len); 2685 i++; 2686 } 2687 if (rawkey->rawdata.rsa.prime1.val != NULL) { 2688 SETATTR(templ, i, CKA_PRIME_1, 2689 rawkey->rawdata.rsa.prime1.val, 2690 rawkey->rawdata.rsa.prime1.len); 2691 i++; 2692 } 2693 if (rawkey->rawdata.rsa.prime2.val != NULL) { 2694 SETATTR(templ, i, CKA_PRIME_2, 2695 rawkey->rawdata.rsa.prime2.val, 2696 rawkey->rawdata.rsa.prime2.len); 2697 i++; 2698 } 2699 if (rawkey->rawdata.rsa.exp1.val != NULL) { 2700 SETATTR(templ, i, CKA_EXPONENT_1, 2701 rawkey->rawdata.rsa.exp1.val, 2702 rawkey->rawdata.rsa.exp1.len); 2703 i++; 2704 } 2705 if (rawkey->rawdata.rsa.exp2.val != NULL) { 2706 SETATTR(templ, i, CKA_EXPONENT_2, 2707 rawkey->rawdata.rsa.exp2.val, 2708 rawkey->rawdata.rsa.exp2.len); 2709 i++; 2710 } 2711 if (rawkey->rawdata.rsa.coef.val != NULL) { 2712 SETATTR(templ, i, CKA_COEFFICIENT, 2713 rawkey->rawdata.rsa.coef.val, 2714 rawkey->rawdata.rsa.coef.len); 2715 i++; 2716 } 2717 } else { 2718 SETATTR(templ, i, CKA_PRIME, 2719 rawkey->rawdata.dsa.prime.val, 2720 rawkey->rawdata.dsa.prime.len); 2721 i++; 2722 SETATTR(templ, i, CKA_SUBPRIME, 2723 rawkey->rawdata.dsa.subprime.val, 2724 rawkey->rawdata.dsa.subprime.len); 2725 i++; 2726 SETATTR(templ, i, CKA_BASE, 2727 rawkey->rawdata.dsa.base.val, 2728 rawkey->rawdata.dsa.base.len); 2729 i++; 2730 SETATTR(templ, i, CKA_VALUE, 2731 rawkey->rawdata.dsa.value.val, 2732 rawkey->rawdata.dsa.value.len); 2733 i++; 2734 } 2735 2736 ckrv = C_CreateObject(kmfh->pk11handle, templ, i, &keyobj); 2737 if (ckrv != CKR_OK) { 2738 SET_ERROR(kmfh, ckrv); 2739 2740 /* Report authentication failures to the caller */ 2741 if (ckrv == CKR_USER_NOT_LOGGED_IN || 2742 ckrv == CKR_PIN_INCORRECT || 2743 ckrv == CKR_PIN_INVALID || 2744 ckrv == CKR_PIN_EXPIRED || 2745 ckrv == CKR_PIN_LOCKED || 2746 ckrv == CKR_SESSION_READ_ONLY) 2747 rv = KMF_ERR_AUTH_FAILED; 2748 else 2749 rv = KMF_ERR_INTERNAL; 2750 } 2751cleanup: 2752 KMF_FreeData(&id); 2753 KMF_FreeData(&subject); 2754 KMF_FreeSignedCert(x509); 2755 free(x509); 2756 2757 return (rv); 2758} 2759 2760KMF_RETURN 2761KMFPK11_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, 2762 KMF_KEY_HANDLE *symkey) 2763{ 2764 KMF_RETURN rv = KMF_OK; 2765 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2766 CK_RV ckrv; 2767 CK_SESSION_HANDLE hSession = kmfh->pk11handle; 2768 CK_OBJECT_HANDLE keyhandle; 2769 CK_MECHANISM keyGenMech; 2770 CK_OBJECT_CLASS class = CKO_SECRET_KEY; 2771 CK_ULONG secKeyType; 2772 CK_ULONG secKeyLen; /* for RC4 and AES */ 2773 CK_BBOOL true = TRUE; 2774 CK_BBOOL false = FALSE; 2775 CK_ATTRIBUTE templ[15]; 2776 int i; 2777 2778 if (kmfh == NULL) 2779 return (KMF_ERR_UNINITIALIZED); 2780 2781 if (kmfh->pk11handle == CK_INVALID_HANDLE) 2782 return (KMF_ERR_NO_TOKEN_SELECTED); 2783 2784 if (params == NULL) 2785 return (KMF_ERR_BAD_PARAMETER); 2786 2787 keyGenMech.pParameter = NULL_PTR; 2788 keyGenMech.ulParameterLen = 0; 2789 switch (params->keytype) { 2790 case KMF_AES: 2791 keyGenMech.mechanism = CKM_AES_KEY_GEN; 2792 secKeyType = CKK_AES; 2793 break; 2794 case KMF_RC4: 2795 keyGenMech.mechanism = CKM_RC4_KEY_GEN; 2796 secKeyType = CKK_RC4; 2797 break; 2798 case KMF_DES: 2799 keyGenMech.mechanism = CKM_DES_KEY_GEN; 2800 secKeyType = CKK_DES; 2801 break; 2802 case KMF_DES3: 2803 keyGenMech.mechanism = CKM_DES3_KEY_GEN; 2804 secKeyType = CKK_DES3; 2805 break; 2806 default: 2807 return (KMF_ERR_BAD_KEY_TYPE); 2808 } 2809 2810 i = 0; 2811 SETATTR(templ, i, CKA_CLASS, &class, sizeof (class)); 2812 i++; 2813 SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType)); 2814 i++; 2815 2816 if (params->keytype == KMF_AES || params->keytype == KMF_RC4) { 2817 if ((params->keylength % 8) != 0) { 2818 return (KMF_ERR_BAD_KEY_SIZE); 2819 } 2820 secKeyLen = params->keylength/8; /* in bytes for RC4/AES */ 2821 SETATTR(templ, i, CKA_VALUE_LEN, &secKeyLen, 2822 sizeof (secKeyLen)); 2823 i++; 2824 } 2825 2826 if (params->keylabel != NULL) { 2827 SETATTR(templ, i, CKA_LABEL, params->keylabel, 2828 strlen(params->keylabel)); 2829 i++; 2830 } 2831 2832 if (params->pkcs11parms.sensitive == B_TRUE) { 2833 SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true)); 2834 } else { 2835 SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false)); 2836 } 2837 i++; 2838 2839 if (params->pkcs11parms.not_extractable == B_TRUE) { 2840 SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false)); 2841 } else { 2842 SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true)); 2843 } 2844 i++; 2845 2846 SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true)); 2847 i++; 2848 SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true)); 2849 i++; 2850 SETATTR(templ, i, CKA_ENCRYPT, &true, sizeof (true)); 2851 i++; 2852 SETATTR(templ, i, CKA_DECRYPT, &true, sizeof (true)); 2853 i++; 2854 SETATTR(templ, i, CKA_SIGN, &true, sizeof (true)); 2855 i++; 2856 SETATTR(templ, i, CKA_VERIFY, &true, sizeof (true)); 2857 i++; 2858 2859 rv = pk11_authenticate(handle, ¶ms->cred); 2860 if (rv != KMF_OK) { 2861 return (rv); 2862 } 2863 2864 ckrv = C_GenerateKey(hSession, &keyGenMech, templ, i, &keyhandle); 2865 if (ckrv != CKR_OK) { 2866 SET_ERROR(kmfh, ckrv); 2867 rv = KMF_ERR_KEYGEN_FAILED; 2868 goto out; 2869 } 2870 2871 symkey->kstype = KMF_KEYSTORE_PK11TOKEN; 2872 symkey->keyalg = params->keytype; 2873 symkey->keyclass = KMF_SYMMETRIC; 2874 symkey->israw = FALSE; 2875 symkey->keyp = (void *)keyhandle; 2876 2877out: 2878 return (rv); 2879} 2880 2881 2882KMF_RETURN 2883KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, 2884 KMF_RAW_SYM_KEY *rkey) 2885{ 2886 KMF_RETURN rv = KMF_OK; 2887 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2888 2889 if (kmfh == NULL) 2890 return (KMF_ERR_UNINITIALIZED); 2891 2892 if (kmfh->pk11handle == CK_INVALID_HANDLE) 2893 return (KMF_ERR_NO_TOKEN_SELECTED); 2894 2895 if (symkey == NULL || rkey == NULL) 2896 return (KMF_ERR_BAD_PARAMETER); 2897 else if (symkey->keyclass != KMF_SYMMETRIC) 2898 return (KMF_ERR_BAD_KEY_CLASS); 2899 2900 if (symkey->israw) { 2901 KMF_RAW_KEY_DATA *rawkey = (KMF_RAW_KEY_DATA *)symkey->keyp; 2902 2903 if (rawkey == NULL || 2904 rawkey->rawdata.sym.keydata.val == NULL || 2905 rawkey->rawdata.sym.keydata.len == 0) 2906 return (KMF_ERR_BAD_KEYHANDLE); 2907 2908 rkey->keydata.len = rawkey->rawdata.sym.keydata.len; 2909 if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL) 2910 return (KMF_ERR_MEMORY); 2911 (void) memcpy(rkey->keydata.val, 2912 rawkey->rawdata.sym.keydata.val, rkey->keydata.len); 2913 } else { 2914 rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)symkey->keyp, rkey); 2915 } 2916 2917 return (rv); 2918} 2919 2920KMF_RETURN 2921KMFPK11_SetTokenPin(KMF_HANDLE_T handle, KMF_SETPIN_PARAMS *params, 2922 KMF_CREDENTIAL *newpin) 2923{ 2924 KMF_RETURN ret = KMF_OK; 2925 CK_RV rv = CKR_OK; 2926 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2927 CK_SESSION_HANDLE session = NULL; 2928 2929 if (handle == NULL || params == NULL || newpin == NULL) 2930 return (KMF_ERR_BAD_PARAMETER); 2931 2932 rv = C_OpenSession(params->pkcs11parms.slot, 2933 CKF_SERIAL_SESSION | CKF_RW_SESSION, 2934 NULL, NULL, &session); 2935 if (rv != CKR_OK) { 2936 SET_ERROR(kmfh, rv); 2937 ret = KMF_ERR_UNINITIALIZED; 2938 goto end; 2939 } 2940 2941 rv = C_SetPIN(session, 2942 (CK_BYTE *)params->cred.cred, params->cred.credlen, 2943 (CK_BYTE *)newpin->cred, newpin->credlen); 2944 2945 if (rv != CKR_OK) { 2946 SET_ERROR(kmfh, rv); 2947 if (rv == CKR_PIN_INCORRECT || 2948 rv == CKR_PIN_INVALID || 2949 rv == CKR_PIN_EXPIRED || 2950 rv == CKR_PIN_LOCKED) 2951 ret = KMF_ERR_AUTH_FAILED; 2952 else 2953 ret = KMF_ERR_INTERNAL; 2954 } 2955end: 2956 if (session != NULL) 2957 (void) C_CloseSession(session); 2958 return (ret); 2959} 2960 2961static KMF_RETURN 2962create_pk11_session(CK_SESSION_HANDLE *sessionp, CK_MECHANISM_TYPE wanted_mech, 2963 CK_FLAGS wanted_flags) 2964{ 2965 CK_RV rv; 2966 KMF_RETURN kmf_rv = KMF_OK; 2967 CK_SLOT_ID_PTR pSlotList; 2968 CK_ULONG pulCount; 2969 CK_MECHANISM_INFO info; 2970 int i; 2971 2972 rv = C_Initialize(NULL); 2973 if ((rv != CKR_OK) && 2974 (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) { 2975 kmf_rv = KMF_ERR_UNINITIALIZED; 2976 goto out; 2977 } 2978 2979 rv = C_GetSlotList(0, NULL, &pulCount); 2980 if (rv != CKR_OK) { 2981 kmf_rv = KMF_ERR_UNINITIALIZED; 2982 goto out; 2983 } 2984 2985 pSlotList = (CK_SLOT_ID_PTR) malloc(pulCount * sizeof (CK_SLOT_ID)); 2986 if (pSlotList == NULL) { 2987 kmf_rv = KMF_ERR_MEMORY; 2988 goto out; 2989 } 2990 2991 rv = C_GetSlotList(0, pSlotList, &pulCount); 2992 if (rv != CKR_OK) { 2993 kmf_rv = KMF_ERR_UNINITIALIZED; 2994 goto out; 2995 } 2996 2997 for (i = 0; i < pulCount; i++) { 2998 rv = C_GetMechanismInfo(pSlotList[i], wanted_mech, &info); 2999 if (rv == CKR_OK && (info.flags & wanted_flags)) 3000 break; 3001 } 3002 if (i < pulCount) { 3003 rv = C_OpenSession(pSlotList[i], CKF_SERIAL_SESSION, 3004 NULL, NULL, sessionp); 3005 3006 if (rv != CKR_OK) { 3007 kmf_rv = KMF_ERR_UNINITIALIZED; 3008 } 3009 } else { 3010 kmf_rv = KMF_ERR_UNINITIALIZED; 3011 } 3012 3013out: 3014 if (pSlotList != NULL) 3015 free(pSlotList); 3016 return (kmf_rv); 3017 3018} 3019static KMF_RETURN 3020verify_data(KMF_HANDLE_T handle, 3021 KMF_ALGORITHM_INDEX AlgorithmId, 3022 KMF_X509_SPKI *keyp, 3023 KMF_DATA *data, 3024 KMF_DATA *signed_data) 3025{ 3026 KMF_RETURN ret; 3027 PKCS_ALGORITHM_MAP *pAlgMap = NULL; 3028 CK_RV ckRv; 3029 CK_MECHANISM ckMechanism; 3030 CK_OBJECT_HANDLE ckKeyHandle; 3031 KMF_BOOL bTempKey; 3032 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3033 CK_SESSION_HANDLE ckSession = NULL; 3034 3035 if (AlgorithmId == KMF_ALGID_NONE) 3036 return (KMF_ERR_BAD_ALGORITHM); 3037 3038 pAlgMap = PKCS_GetAlgorithmMap(KMF_ALGCLASS_SIGNATURE, 3039 AlgorithmId, PKCS_GetDefaultSignatureMode(AlgorithmId)); 3040 3041 if (!pAlgMap) 3042 return (KMF_ERR_BAD_ALGORITHM); 3043 3044 ret = create_pk11_session(&ckSession, pAlgMap->pkcs_mechanism, 3045 CKF_VERIFY); 3046 if (ret != KMF_OK) 3047 return (ret); 3048 3049 /* Fetch the verifying key */ 3050 ret = PKCS_AcquirePublicKeyHandle(ckSession, keyp, 3051 pAlgMap->key_type, &ckKeyHandle, &bTempKey); 3052 3053 if (ret != KMF_OK) { 3054 return (ret); 3055 } 3056 3057 ckMechanism.mechanism = pAlgMap->pkcs_mechanism; 3058 ckMechanism.pParameter = NULL; 3059 ckMechanism.ulParameterLen = 0; 3060 3061 ckRv = C_VerifyInit(ckSession, &ckMechanism, ckKeyHandle); 3062 if (ckRv != CKR_OK) { 3063 if (bTempKey) 3064 (void) C_DestroyObject(ckSession, ckKeyHandle); 3065 SET_ERROR(kmfh, ckRv); 3066 ret = KMF_ERR_INTERNAL; 3067 goto cleanup; 3068 } 3069 3070 ckRv = C_Verify(ckSession, 3071 (CK_BYTE *)data->Data, 3072 (CK_ULONG)data->Length, 3073 (CK_BYTE *)signed_data->Data, 3074 (CK_ULONG)signed_data->Length); 3075 3076 if (ckRv != CKR_OK) { 3077 SET_ERROR(kmfh, ckRv); 3078 ret = KMF_ERR_INTERNAL; 3079 } 3080 3081cleanup: 3082 if (bTempKey) 3083 (void) C_DestroyObject(ckSession, ckKeyHandle); 3084 3085 (void) C_CloseSession(ckSession); 3086 3087 return (ret); 3088} 3089 3090KMF_RETURN 3091KMFPK11_VerifyDataWithCert(KMF_HANDLE_T handle, 3092 KMF_ALGORITHM_INDEX algid, KMF_DATA *indata, 3093 KMF_DATA *insig, KMF_DATA *SignerCertData) 3094{ 3095 KMF_RETURN ret = KMF_OK; 3096 KMF_X509_CERTIFICATE *SignerCert = NULL; 3097 KMF_X509_SPKI *pubkey; 3098 3099 if (handle == NULL || indata == NULL || 3100 indata->Data == NULL || indata->Length == 0 || 3101 insig == NULL|| insig->Data == NULL || insig->Length == 0 || 3102 SignerCertData == NULL || SignerCertData->Data == NULL || 3103 SignerCertData->Length == 0) 3104 return (KMF_ERR_BAD_PARAMETER); 3105 3106 /* Decode the signer cert so we can get the SPKI data */ 3107 ret = DerDecodeSignedCertificate(SignerCertData, &SignerCert); 3108 if (ret != KMF_OK) 3109 goto cleanup; 3110 3111 /* Get the public key info from the signer certificate */ 3112 pubkey = &SignerCert->certificate.subjectPublicKeyInfo; 3113 3114 /* If no algorithm specified, use the certs signature algorithm */ 3115 if (algid == KMF_ALGID_NONE) { 3116 algid = X509_AlgorithmOidToAlgId(CERT_ALG_OID(SignerCert)); 3117 } 3118 3119 if (algid == KMF_ALGID_NONE) { 3120 ret = KMF_ERR_BAD_ALGORITHM; 3121 } else { 3122 ret = verify_data(handle, algid, pubkey, indata, insig); 3123 } 3124 3125cleanup: 3126 if (SignerCert) { 3127 KMF_FreeSignedCert(SignerCert); 3128 free(SignerCert); 3129 } 3130 3131 return (ret); 3132} 3133