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