1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * NSS keystore wrapper 23 * 24 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 #pragma ident "%Z%%M% %I% %E% SMI" 29 30 #include <sys/types.h> 31 #include <sys/stat.h> 32 #include <errno.h> 33 #include <fcntl.h> 34 #include <synch.h> 35 36 #include <kmfapiP.h> 37 #include <ber_der.h> 38 /* NSS related headers */ 39 40 #include <mps/nss.h> 41 #include <mps/cert.h> 42 #include <mps/certdb.h> 43 #include <mps/secoid.h> 44 #include <mps/secder.h> 45 #include <mps/secerr.h> 46 #include <mps/cryptohi.h> 47 #include <mps/keyhi.h> 48 #include <mps/keythi.h> 49 #include <mps/pk11func.h> 50 #include <mps/pk11pqg.h> 51 #include <mps/pkcs12.h> 52 #include <mps/p12plcy.h> 53 #include <mps/prerror.h> 54 55 #define NSS_OK 0 56 57 mutex_t init_lock = DEFAULTMUTEX; 58 static int nss_initialized = 0; 59 60 KMF_RETURN 61 NSS_ConfigureKeystore(KMF_HANDLE_T, KMF_CONFIG_PARAMS *); 62 63 KMF_RETURN 64 NSS_FindCert(KMF_HANDLE_T, 65 KMF_FINDCERT_PARAMS *params, 66 KMF_X509_DER_CERT *kmf_cert, 67 uint32_t *num_certs); 68 69 void 70 NSS_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *); 71 72 KMF_RETURN 73 NSS_StoreCert(KMF_HANDLE_T, KMF_STORECERT_PARAMS *params, 74 KMF_DATA * pcert); 75 76 KMF_RETURN 77 NSS_ImportCert(KMF_HANDLE_T, KMF_IMPORTCERT_PARAMS *params); 78 79 KMF_RETURN 80 NSS_DeleteCert(KMF_HANDLE_T, KMF_DELETECERT_PARAMS *params); 81 82 KMF_RETURN 83 NSS_CreateKeypair(KMF_HANDLE_T, KMF_CREATEKEYPAIR_PARAMS *, 84 KMF_KEY_HANDLE *, KMF_KEY_HANDLE *); 85 86 KMF_RETURN 87 NSS_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *); 88 89 KMF_RETURN 90 NSS_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 91 KMF_DATA *, KMF_DATA *); 92 93 KMF_RETURN 94 NSS_ImportCRL(KMF_HANDLE_T, KMF_IMPORTCRL_PARAMS *params); 95 96 KMF_RETURN 97 NSS_DeleteCRL(KMF_HANDLE_T, KMF_DELETECRL_PARAMS *params); 98 99 KMF_RETURN 100 NSS_FindCRL(KMF_HANDLE_T, KMF_FINDCRL_PARAMS *params, 101 char **CRLNameList, int *CRLCount); 102 103 KMF_RETURN 104 NSS_FindKey(KMF_HANDLE_T, KMF_FINDKEY_PARAMS *, 105 KMF_KEY_HANDLE *, uint32_t *); 106 107 KMF_RETURN 108 NSS_FindCertInCRL(KMF_HANDLE_T, KMF_FINDCERTINCRL_PARAMS *params); 109 110 KMF_RETURN 111 NSS_GetErrorString(KMF_HANDLE_T, char **); 112 113 KMF_RETURN 114 NSS_DeleteKey(KMF_HANDLE_T, KMF_DELETEKEY_PARAMS *, 115 KMF_KEY_HANDLE *, boolean_t); 116 117 KMF_RETURN 118 NSS_GetPrikeyByCert(KMF_HANDLE_T, KMF_CRYPTOWITHCERT_PARAMS *, KMF_DATA *, 119 KMF_KEY_HANDLE *, KMF_KEY_ALG); 120 121 KMF_RETURN 122 NSS_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 123 KMF_DATA *, KMF_DATA *); 124 125 KMF_RETURN 126 NSS_ExportP12(KMF_HANDLE_T, 127 KMF_EXPORTP12_PARAMS *, 128 int, KMF_X509_DER_CERT *, 129 int, KMF_KEY_HANDLE *, 130 char *); 131 132 KMF_RETURN 133 NSS_StorePrivateKey(KMF_HANDLE_T, KMF_STOREKEY_PARAMS *, KMF_RAW_KEY_DATA *); 134 135 KMF_RETURN 136 NSS_CreateSymKey(KMF_HANDLE_T, KMF_CREATESYMKEY_PARAMS *, KMF_KEY_HANDLE *); 137 138 KMF_RETURN 139 NSS_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *); 140 141 KMF_RETURN 142 NSS_SetTokenPin(KMF_HANDLE_T, KMF_SETPIN_PARAMS *, KMF_CREDENTIAL *); 143 144 static 145 KMF_PLUGIN_FUNCLIST nss_plugin_table = 146 { 147 1, /* Version */ 148 NSS_ConfigureKeystore, 149 NSS_FindCert, 150 NSS_FreeKMFCert, 151 NSS_StoreCert, 152 NSS_ImportCert, 153 NSS_ImportCRL, 154 NSS_DeleteCert, 155 NSS_DeleteCRL, 156 NSS_CreateKeypair, 157 NSS_FindKey, 158 NSS_EncodePubKeyData, 159 NSS_SignData, 160 NSS_DeleteKey, 161 NULL /* ListCRL */, 162 NSS_FindCRL, 163 NSS_FindCertInCRL, 164 NSS_GetErrorString, 165 NSS_GetPrikeyByCert, 166 NSS_DecryptData, 167 NSS_ExportP12, 168 NSS_StorePrivateKey, 169 NSS_CreateSymKey, 170 NSS_GetSymKeyValue, 171 NSS_SetTokenPin, 172 NULL, /* VerifyData */ 173 NULL /* Finalize */ 174 }; 175 176 /* additions for importing and exporting PKCS 12 files */ 177 typedef struct p12uContextStr { 178 char *filename; /* name of file */ 179 PRFileDesc *file; /* pointer to file */ 180 PRBool error; /* error occurred? */ 181 int errorValue; /* which error occurred? */ 182 } p12uContext; 183 184 #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_NSS; \ 185 h->lasterr.errcode = c; 186 187 KMF_PLUGIN_FUNCLIST * 188 KMF_Plugin_Initialize() 189 { 190 SEC_PKCS12EnableCipher(PKCS12_RC4_40, 1); 191 SEC_PKCS12EnableCipher(PKCS12_RC4_128, 1); 192 SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_40, 1); 193 SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_128, 1); 194 SEC_PKCS12EnableCipher(PKCS12_DES_56, 1); 195 SEC_PKCS12EnableCipher(PKCS12_DES_EDE3_168, 1); 196 SEC_PKCS12SetPreferredCipher(PKCS12_DES_EDE3_168, 1); 197 198 return (&nss_plugin_table); 199 } 200 201 static char * 202 /*ARGSUSED*/ 203 nss_getpassword(PK11SlotInfo *slot, PRBool retry, void *arg) 204 { 205 if (retry) 206 return (NULL); 207 if (arg != NULL) 208 return ((char *)strdup(arg)); 209 else 210 return (NULL); 211 } 212 213 static KMF_RETURN 214 nss_authenticate(KMF_HANDLE_T handle, 215 PK11SlotInfo *nss_slot, KMF_CREDENTIAL *cred) 216 { 217 218 SECStatus nssrv = SECSuccess; 219 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 220 221 /* If a password was given, try to login to the slot */ 222 if (cred == NULL || cred->cred == NULL || cred->credlen == 0 || 223 nss_slot == NULL) { 224 return (KMF_ERR_BAD_PARAMETER); 225 } 226 227 if (PK11_IsLoggedIn(nss_slot, NULL)) { 228 return (KMF_OK); 229 } 230 231 PK11_SetPasswordFunc(nss_getpassword); 232 nssrv = PK11_Authenticate(nss_slot, PR_TRUE, 233 (void *)cred->cred); 234 235 if (nssrv != SECSuccess) { 236 SET_ERROR(kmfh, nssrv); 237 PK11_FreeSlot(nss_slot); 238 return (KMF_ERR_AUTH_FAILED); 239 } 240 241 return (KMF_OK); 242 } 243 244 static SECStatus 245 Init_NSS_DBs(const char *configdir, 246 const char *certPrefix, 247 const char *keyPrefix, 248 const char *secmodName) 249 { 250 SECStatus rv = NSS_OK; 251 252 (void) mutex_lock(&init_lock); 253 254 /* If another thread already did it, return OK. */ 255 if (nss_initialized) { 256 (void) mutex_unlock(&init_lock); 257 return (SECSuccess); 258 } 259 260 rv = NSS_Initialize((configdir && strlen(configdir)) ? 261 configdir : "./", certPrefix, 262 keyPrefix, secmodName ? secmodName : "secmod.db", 263 NSS_INIT_COOPERATE); 264 if (rv != SECSuccess) { 265 goto end; 266 } 267 268 nss_initialized++; 269 end: 270 (void) mutex_unlock(&init_lock); 271 return (rv); 272 } 273 274 /* 275 * When it is called the first time, it will intialize NSS. Once the NSS 276 * is initialized, this function returns KMF_KEYSTORE_ALREADY_INITIALIZED 277 * if it is called again. 278 */ 279 KMF_RETURN 280 NSS_ConfigureKeystore(KMF_HANDLE_T handle, KMF_CONFIG_PARAMS *params) 281 { 282 KMF_RETURN rv = KMF_OK; 283 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 284 285 if (params == NULL) 286 return (KMF_ERR_BAD_PARAMETER); 287 288 (void) mutex_lock(&init_lock); 289 if (nss_initialized == 0) { 290 SECStatus err; 291 292 (void) mutex_unlock(&init_lock); 293 err = Init_NSS_DBs(params->nssconfig.configdir, 294 params->nssconfig.certPrefix, 295 params->nssconfig.keyPrefix, 296 params->nssconfig.secModName); 297 if (err != SECSuccess) { 298 SET_ERROR(kmfh, err); 299 return (KMF_ERR_INTERNAL); 300 } 301 } else { 302 rv = KMF_KEYSTORE_ALREADY_INITIALIZED; 303 (void) mutex_unlock(&init_lock); 304 } 305 306 return (rv); 307 } 308 309 310 /* 311 * This function sets up the slot to be used for other operations. 312 * This function is basically called by every NSS SPI function. 313 * For those functions that can only be performed in the internal slot, the 314 * boolean "internal_slot_only" argument needs to be TRUE. 315 * A slot pointer will be returned when this function is executed successfully. 316 */ 317 static KMF_RETURN 318 Do_NSS_Init( 319 void *handle, 320 KMF_NSS_PARAMS nss_opts, 321 boolean_t internal_slot_only, 322 PK11SlotInfo **nss_slot) 323 { 324 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 325 326 if (!nss_initialized) 327 return (KMF_ERR_PLUGIN_INIT); 328 329 /* 330 * NSS Is already initialized, but we need to find 331 * the right slot. 332 */ 333 if (nss_opts.slotlabel == NULL || 334 strcmp(nss_opts.slotlabel, "internal") == 0) { 335 *nss_slot = PK11_GetInternalKeySlot(); 336 } else if (internal_slot_only == TRUE) { 337 return (KMF_ERR_SLOTNAME); 338 } else { 339 *nss_slot = PK11_FindSlotByName(nss_opts.slotlabel); 340 } 341 342 if (*nss_slot == NULL) { 343 SET_ERROR(kmfh, PORT_GetError()); 344 return (KMF_ERR_SLOTNAME); 345 } 346 347 /* 348 * If the token was not yet initialized, return an error. 349 */ 350 if (PK11_NeedUserInit(*nss_slot)) { 351 return (KMF_ERR_UNINITIALIZED_TOKEN); 352 } 353 354 return (KMF_OK); 355 } 356 357 static KMF_RETURN 358 nss2kmf_cert(CERTCertificate *nss_cert, KMF_X509_DER_CERT *kmf_cert) 359 { 360 kmf_cert->kmf_private.keystore_type = KMF_KEYSTORE_NSS; 361 kmf_cert->kmf_private.flags = KMF_FLAG_CERT_VALID; 362 363 kmf_cert->certificate.Length = nss_cert->derCert.len; 364 365 if ((kmf_cert->certificate.Data = malloc(nss_cert->derCert.len)) == 366 NULL) { 367 kmf_cert->certificate.Length = 0; 368 return (KMF_ERR_MEMORY); 369 } 370 (void) memcpy(kmf_cert->certificate.Data, nss_cert->derCert.data, 371 nss_cert->derCert.len); 372 if (nss_cert->nickname != NULL) 373 kmf_cert->kmf_private.label = 374 (char *)strdup(nss_cert->nickname); 375 return (KMF_OK); 376 } 377 378 static KMF_RETURN 379 nss_getcert_by_label(KMF_HANDLE *kmfh, 380 char *name, KMF_X509_DER_CERT *kmf_cert, 381 uint32_t *num_certs, KMF_CERT_VALIDITY find_criteria) 382 { 383 KMF_RETURN rv = KMF_OK; 384 CERTCertificate *nss_cert; 385 SECCertTimeValidity validity; 386 387 nss_cert = PK11_FindCertFromNickname(name, NULL); 388 if (nss_cert == NULL) { 389 *num_certs = 0; 390 SET_ERROR(kmfh, PORT_GetError()); 391 *num_certs = 0; 392 return (KMF_ERR_CERT_NOT_FOUND); 393 } else { 394 *num_certs = 1; 395 } 396 397 switch (find_criteria) { 398 case KMF_ALL_CERTS: 399 break; 400 case KMF_NONEXPIRED_CERTS: 401 validity = CERT_CheckCertValidTimes(nss_cert, PR_Now(), 402 PR_FALSE); 403 if (validity != secCertTimeValid) { 404 /* this is an invalid cert, reject it */ 405 *num_certs = 0; 406 CERT_DestroyCertificate(nss_cert); 407 return (KMF_OK); 408 } 409 break; 410 case KMF_EXPIRED_CERTS: 411 validity = CERT_CheckCertValidTimes(nss_cert, PR_Now(), 412 PR_FALSE); 413 if (validity == secCertTimeValid) { 414 /* this is a valid cert, reject it in this case. */ 415 *num_certs = 0; 416 CERT_DestroyCertificate(nss_cert); 417 return (KMF_OK); 418 } 419 break; 420 default: 421 return (KMF_ERR_BAD_PARAMETER); 422 } 423 424 if (kmf_cert != NULL) 425 rv = nss2kmf_cert(nss_cert, kmf_cert); 426 427 /* We copied the data we need, so cleanup the internal record */ 428 CERT_DestroyCertificate(nss_cert); 429 430 if (rv != KMF_OK) 431 *num_certs = 0; 432 433 return (rv); 434 } 435 436 static KMF_RETURN 437 nss_find_matching_certs(PK11SlotInfo *slot, 438 char *issuer, char *subject, KMF_BIGINT *serial, 439 CERTCertList **certlist, KMF_CERT_VALIDITY find_criteria) 440 { 441 KMF_RETURN rv = KMF_OK; 442 SECStatus ret; 443 CERTCertList *list; 444 CERTCertListNode *node; 445 KMF_X509_NAME issuerDN, subjectDN; 446 boolean_t findIssuer = FALSE; 447 boolean_t findSubject = FALSE; 448 boolean_t findSerial = FALSE; 449 450 if (issuer != NULL && strlen(issuer)) { 451 rv = KMF_DNParser(issuer, &issuerDN); 452 if (rv != KMF_OK) 453 return (rv); 454 findIssuer = TRUE; 455 } 456 if (subject != NULL && strlen(subject)) { 457 rv = KMF_DNParser(subject, &subjectDN); 458 if (rv != KMF_OK) 459 return (rv); 460 findSubject = TRUE; 461 } 462 if (serial != 0 && serial->val != NULL && serial->len > 0) 463 findSerial = TRUE; 464 465 list = PK11_ListCertsInSlot(slot); 466 if (list) { 467 node = CERT_LIST_HEAD(list); 468 while (!CERT_LIST_END(node, list)) { 469 KMF_X509_NAME cmpDN; 470 KMF_DATA der; 471 boolean_t match; 472 CERTCertListNode *freenode; 473 474 if (findIssuer) { 475 der.Data = node->cert->derIssuer.data; 476 der.Length = node->cert->derIssuer.len; 477 rv = DerDecodeName(&der, &cmpDN); 478 if (rv == KMF_OK) { 479 match = !KMF_CompareRDNs(&issuerDN, 480 &cmpDN); 481 KMF_FreeDN(&cmpDN); 482 if (!match) 483 goto delete_and_cont; 484 } else { 485 goto delete_and_cont; 486 } 487 } 488 if (findSubject) { 489 der.Data = node->cert->derSubject.data; 490 der.Length = node->cert->derSubject.len; 491 rv = DerDecodeName(&der, &cmpDN); 492 if (rv == KMF_OK) { 493 match = !KMF_CompareRDNs(&subjectDN, 494 &cmpDN); 495 KMF_FreeDN(&cmpDN); 496 if (!match) 497 goto delete_and_cont; 498 } else { 499 goto delete_and_cont; 500 } 501 } 502 if (findSerial) { 503 SECItem *sernum; 504 505 sernum = &node->cert->serialNumber; 506 507 if (serial->len != sernum->len) 508 goto delete_and_cont; 509 510 if (memcmp(sernum->data, serial->val, 511 serial->len)) 512 goto delete_and_cont; 513 } 514 515 /* select the certs using find criteria */ 516 switch (find_criteria) { 517 case KMF_ALL_CERTS: 518 break; 519 case KMF_NONEXPIRED_CERTS: 520 ret = CERT_CertTimesValid(node->cert); 521 if (ret == SECFailure) { 522 /* this is an invalid cert */ 523 goto skip; 524 } 525 break; 526 527 case KMF_EXPIRED_CERTS: 528 ret = CERT_CertTimesValid(node->cert); 529 if (ret != SECFailure) { 530 /* this is a valid cert */ 531 goto skip; 532 } 533 break; 534 } 535 skip: 536 node = CERT_LIST_NEXT(node); 537 continue; 538 delete_and_cont: 539 freenode = node; 540 node = CERT_LIST_NEXT(node); 541 CERT_RemoveCertListNode(freenode); 542 } 543 } 544 545 if (rv == KMF_OK && certlist != NULL) { 546 *certlist = list; 547 } else { 548 CERT_DestroyCertList(list); 549 } 550 return (rv); 551 } 552 553 static KMF_RETURN 554 convertCertList(void *kmfhandle, 555 CERTCertList *nsscerts, KMF_X509_DER_CERT *kmfcerts, 556 uint32_t *numcerts) 557 { 558 KMF_RETURN rv = KMF_OK; 559 CERTCertListNode *node; 560 561 *numcerts = 0; 562 563 for (node = CERT_LIST_HEAD(nsscerts); 564 !CERT_LIST_END(node, nsscerts) && rv == KMF_OK; 565 node = CERT_LIST_NEXT(node), (*numcerts)++) { 566 if (kmfcerts != NULL) 567 rv = nss2kmf_cert(node->cert, &kmfcerts[*numcerts]); 568 } 569 570 /* 571 * If we failed, delete any certs allocated so far. 572 */ 573 if (rv != KMF_OK) { 574 int i; 575 for (i = 0; i < *numcerts; i++) 576 KMF_FreeKMFCert(kmfhandle, &kmfcerts[i]); 577 } 578 return (rv); 579 } 580 581 KMF_RETURN 582 NSS_FindCert(KMF_HANDLE_T handle, KMF_FINDCERT_PARAMS *params, 583 KMF_X509_DER_CERT *kmfcerts, 584 uint32_t *num_certs) 585 { 586 KMF_RETURN rv = KMF_OK; 587 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 588 PK11SlotInfo *nss_slot = NULL; 589 CERTCertList *certlist = NULL; 590 591 rv = Do_NSS_Init(handle, 592 params->ks_opt_u.nss_opts, FALSE, &nss_slot); 593 if (rv != KMF_OK) { 594 return (rv); 595 } 596 597 *num_certs = 0; 598 if (params->certLabel) { 599 rv = nss_getcert_by_label(kmfh, 600 params->certLabel, 601 kmfcerts, num_certs, params->find_cert_validity); 602 } else { 603 rv = nss_find_matching_certs(nss_slot, 604 params->issuer, params->subject, params->serial, 605 &certlist, params->find_cert_validity); 606 607 if (rv == KMF_OK && certlist != NULL) { 608 rv = convertCertList(handle, 609 certlist, kmfcerts, num_certs); 610 CERT_DestroyCertList(certlist); 611 } 612 } 613 614 if (nss_slot != NULL) { 615 PK11_FreeSlot(nss_slot); 616 } 617 618 if (rv == KMF_OK && *num_certs == 0) 619 rv = KMF_ERR_CERT_NOT_FOUND; 620 621 return (rv); 622 } 623 624 void 625 /*ARGSUSED*/ 626 NSS_FreeKMFCert(KMF_HANDLE_T handle, 627 KMF_X509_DER_CERT *kmf_cert) 628 { 629 if (kmf_cert != NULL) { 630 if (kmf_cert->certificate.Data != NULL) { 631 free(kmf_cert->certificate.Data); 632 kmf_cert->certificate.Data = NULL; 633 kmf_cert->certificate.Length = 0; 634 } 635 if (kmf_cert->kmf_private.label != NULL) { 636 free(kmf_cert->kmf_private.label); 637 kmf_cert->kmf_private.label = NULL; 638 } 639 } 640 } 641 642 KMF_RETURN 643 NSS_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *params, 644 KMF_DATA *pcert) 645 { 646 KMF_RETURN ret = KMF_OK; 647 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 648 SECStatus nss_rv; 649 CERTCertificate *nss_cert = NULL; 650 CERTCertTrust *nss_trust = NULL; 651 PK11SlotInfo *nss_slot = NULL; 652 CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); 653 654 if (pcert == NULL) { 655 return (KMF_ERR_BAD_PARAMETER); 656 } 657 658 /* NSS only support DER format */ 659 if (params == NULL) { 660 return (KMF_ERR_BAD_PARAMETER); 661 } 662 663 ret = Do_NSS_Init(handle, 664 params->ks_opt_u.nss_opts, FALSE, &nss_slot); 665 if (ret != KMF_OK) { 666 return (ret); 667 } 668 669 nss_cert = CERT_DecodeCertFromPackage((char *)pcert->Data, 670 pcert->Length); 671 if (nss_cert == NULL) { 672 SET_ERROR(kmfh, PORT_GetError()); 673 ret = KMF_ERR_BAD_CERT_FORMAT; 674 goto out; 675 } 676 677 nss_rv = PK11_ImportCert(nss_slot, nss_cert, CK_INVALID_HANDLE, 678 params->certLabel, 0); 679 if (nss_rv) { 680 SET_ERROR(kmfh, nss_rv); 681 ret = KMF_ERR_BAD_CERT_FORMAT; 682 goto out; 683 } 684 685 if (params->ks_opt_u.nss_opts.trustflag != NULL && 686 strlen(params->ks_opt_u.nss_opts.trustflag)) { 687 nss_trust = (CERTCertTrust *) malloc(sizeof (CERTCertTrust)); 688 if (nss_trust == NULL) { 689 ret = KMF_ERR_MEMORY; 690 goto out; 691 } 692 nss_rv = CERT_DecodeTrustString(nss_trust, 693 params->ks_opt_u.nss_opts.trustflag); 694 if (nss_rv) { 695 SET_ERROR(kmfh, nss_rv); 696 ret = KMF_ERR_BAD_PARAMETER; 697 goto out; 698 } 699 700 nss_rv = CERT_ChangeCertTrust(certHandle, nss_cert, nss_trust); 701 if (nss_rv) { 702 SET_ERROR(kmfh, nss_rv); 703 ret = KMF_ERR_BAD_PARAMETER; 704 } 705 } 706 707 out: 708 if (nss_trust != NULL) { 709 free(nss_trust); 710 } 711 712 if (nss_cert != NULL) { 713 CERT_DestroyCertificate(nss_cert); 714 } 715 716 if (nss_slot != NULL) { 717 PK11_FreeSlot(nss_slot); 718 } 719 720 return (ret); 721 } 722 723 724 KMF_RETURN 725 NSS_ImportCert(KMF_HANDLE_T handle, KMF_IMPORTCERT_PARAMS *params) 726 { 727 KMF_RETURN ret = KMF_OK; 728 KMF_STORECERT_PARAMS scparams; 729 KMF_DATA cert = {NULL, 0}; 730 KMF_DATA cert_der = {NULL, 0}; 731 KMF_DATA *cptr = NULL; 732 KMF_ENCODE_FORMAT format; 733 734 if (params == NULL || params->certfile == NULL) { 735 return (KMF_ERR_BAD_PARAMETER); 736 } 737 738 /* 739 * Check if the input cert file is a valid certificate and 740 * auto-detect the file format of it. 741 */ 742 ret = KMF_IsCertFile(handle, params->certfile, &format); 743 if (ret != KMF_OK) 744 return (ret); 745 746 ret = KMF_ReadInputFile(handle, params->certfile, &cert); 747 if (ret != KMF_OK) { 748 return (ret); 749 } 750 751 /* 752 * If the imported cert is in PEM format, convert it to 753 * DER format in order to store it in NSS token. 754 */ 755 if (format == KMF_FORMAT_PEM) { 756 int derlen; 757 ret = KMF_Pem2Der(cert.Data, cert.Length, 758 &cert_der.Data, &derlen); 759 if (ret != KMF_OK) { 760 goto cleanup; 761 } 762 cert_der.Length = (size_t)derlen; 763 cptr = &cert_der; 764 } else { 765 cptr = &cert; 766 } 767 768 (void) memset(&scparams, 0, sizeof (scparams)); 769 scparams.kstype = params->kstype; 770 scparams.certLabel = params->certLabel; 771 scparams.nssparms = params->nssparms; 772 773 ret = NSS_StoreCert(handle, &scparams, cptr); 774 775 if (format == KMF_FORMAT_PEM) { 776 KMF_FreeData(&cert_der); 777 } 778 779 cleanup: 780 KMF_FreeData(&cert); 781 782 return (ret); 783 } 784 785 KMF_RETURN 786 NSS_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params) 787 { 788 KMF_RETURN rv = KMF_OK; 789 int nssrv; 790 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 791 CERTCertificate *cert = NULL; 792 PK11SlotInfo *nss_slot = NULL; 793 794 /* check params */ 795 if (params == NULL) { 796 return (KMF_ERR_BAD_PARAMETER); 797 } 798 799 rv = Do_NSS_Init(handle, 800 params->ks_opt_u.nss_opts, 801 FALSE, &nss_slot); 802 if (rv != KMF_OK) { 803 return (rv); 804 } 805 806 if (params->certLabel) { 807 cert = PK11_FindCertFromNickname(params->certLabel, NULL); 808 if (cert == NULL) { 809 return (KMF_ERR_CERT_NOT_FOUND); 810 } 811 812 switch (params->find_cert_validity) { 813 case KMF_ALL_CERTS: 814 break; 815 case KMF_NONEXPIRED_CERTS: 816 nssrv = CERT_CertTimesValid(cert); 817 if (nssrv == SECFailure) { 818 /* this is an invalid cert - skip it */ 819 goto out; 820 } 821 break; 822 case KMF_EXPIRED_CERTS: 823 nssrv = CERT_CertTimesValid(cert); 824 if (nssrv != SECFailure) { 825 /* this is a valid cert - skip it */ 826 goto out; 827 } 828 break; 829 } 830 /* delete it from database */ 831 nssrv = SEC_DeletePermCertificate(cert); 832 if (nssrv) { 833 SET_ERROR(kmfh, nssrv); 834 rv = KMF_ERR_INTERNAL; 835 } 836 } else { 837 CERTCertListNode *node; 838 CERTCertList *certlist = NULL; 839 840 rv = nss_find_matching_certs(nss_slot, 841 params->issuer, params->subject, params->serial, 842 &certlist, params->find_cert_validity); 843 844 for (node = CERT_LIST_HEAD(certlist); 845 !CERT_LIST_END(node, certlist) && rv == KMF_OK; 846 node = CERT_LIST_NEXT(node)) { 847 848 nssrv = SEC_DeletePermCertificate(node->cert); 849 if (nssrv) { 850 SET_ERROR(kmfh, nssrv); 851 rv = KMF_ERR_INTERNAL; 852 } 853 } 854 855 if (rv == KMF_OK && certlist != NULL) { 856 CERT_DestroyCertList(certlist); 857 } else if (rv == KMF_OK && certlist == NULL) { 858 rv = KMF_ERR_CERT_NOT_FOUND; 859 } 860 } 861 out: 862 if (nss_slot != NULL) { 863 PK11_FreeSlot(nss_slot); 864 } 865 866 if (cert != NULL) { 867 CERT_DestroyCertificate(cert); 868 } 869 870 return (rv); 871 } 872 873 static void 874 InitRandom(char *filename) 875 { 876 char buf[2048]; 877 int fd; 878 PRInt32 count; 879 880 fd = open(filename, O_RDONLY); 881 if (!fd) 882 return; 883 884 count = read(fd, buf, sizeof (buf)); 885 if (count > 0) { 886 PK11_RandomUpdate(buf, count); 887 } 888 889 (void) close(fd); 890 } 891 892 KMF_RETURN 893 NSS_CreateKeypair(KMF_HANDLE_T handle, 894 KMF_CREATEKEYPAIR_PARAMS *params, 895 KMF_KEY_HANDLE *privkey, 896 KMF_KEY_HANDLE *pubkey) 897 { 898 KMF_RETURN rv = KMF_OK; 899 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 900 PK11RSAGenParams rsaparams; 901 void *nssparams; 902 CK_MECHANISM_TYPE mechanism; 903 ulong_t publicExponent = 0x010001; 904 PK11SlotInfo *nss_slot = NULL; 905 SECKEYPrivateKey *NSSprivkey = NULL; 906 SECKEYPublicKey *NSSpubkey = NULL; 907 PQGParams *pqgParams = NULL; 908 909 910 if (params == NULL) { 911 return (KMF_ERR_BAD_PARAMETER); 912 } 913 914 rv = Do_NSS_Init(handle, 915 params->ks_opt_u.nss_opts, FALSE, &nss_slot); 916 if (rv != KMF_OK) { 917 return (rv); 918 } 919 920 rv = nss_authenticate(handle, nss_slot, ¶ms->cred); 921 if (rv != KMF_OK) { 922 return (rv); 923 } 924 925 /* Get some random bits */ 926 InitRandom("/dev/urandom"); 927 if (params->keytype == KMF_RSA) { 928 rsaparams.keySizeInBits = params->keylength; 929 /* 930 * NSS only allows for a 4 byte exponent. 931 * Ignore the exponent parameter if it is too big. 932 */ 933 if (params->rsa_exponent.len > 0 && 934 params->rsa_exponent.len <= sizeof (publicExponent) && 935 params->rsa_exponent.val != NULL) { 936 (void) memcpy(&publicExponent, 937 params->rsa_exponent.val, 938 params->rsa_exponent.len); 939 } 940 rsaparams.pe = publicExponent; 941 mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN; 942 nssparams = &rsaparams; 943 } else if (params->keytype == KMF_DSA) { 944 PQGVerify *pqgVerify = NULL; 945 int ks; 946 SECStatus nssrv, passed; 947 948 mechanism = CKM_DSA_KEY_PAIR_GEN; 949 950 ks = PQG_PBITS_TO_INDEX(params->keylength); 951 nssrv = PK11_PQG_ParamGen(ks, &pqgParams, &pqgVerify); 952 if (nssrv != SECSuccess) { 953 SET_ERROR(kmfh, rv); 954 PK11_PQG_DestroyVerify(pqgVerify); 955 rv = KMF_ERR_KEYGEN_FAILED; 956 goto cleanup; 957 } 958 959 nssrv = PK11_PQG_VerifyParams(pqgParams, pqgVerify, &passed); 960 if (nssrv != SECSuccess || passed != SECSuccess) { 961 SET_ERROR(kmfh, rv); 962 rv = KMF_ERR_KEYGEN_FAILED; 963 } 964 965 PK11_PQG_DestroyVerify(pqgVerify); 966 967 if (rv != KMF_OK) { 968 SET_ERROR(kmfh, PORT_GetError()); 969 goto cleanup; 970 } 971 972 nssparams = pqgParams; 973 } else { 974 rv = KMF_ERR_BAD_PARAMETER; 975 goto cleanup; 976 } 977 978 NSSprivkey = PK11_GenerateKeyPair(nss_slot, 979 mechanism, nssparams, &NSSpubkey, 980 PR_TRUE, /* isPermanent */ 981 PR_TRUE, /* isSensitive */ 982 (void *)params->cred.cred); 983 984 if (NSSprivkey == NULL || NSSpubkey == NULL) { 985 SET_ERROR(kmfh, PORT_GetError()); 986 rv = KMF_ERR_KEYGEN_FAILED; 987 } else { 988 if (params->keylabel != NULL && 989 strlen(params->keylabel)) { 990 (void) PK11_SetPrivateKeyNickname(NSSprivkey, 991 params->keylabel); 992 (void) PK11_SetPublicKeyNickname(NSSpubkey, 993 params->keylabel); 994 } 995 /* Now, convert it to a KMF_KEY object for the framework */ 996 if (privkey != NULL) { 997 privkey->kstype = KMF_KEYSTORE_NSS; 998 privkey->keyalg = params->keytype; 999 privkey->keyclass = KMF_ASYM_PRI; 1000 privkey->keylabel = 1001 PK11_GetPrivateKeyNickname(NSSprivkey); 1002 privkey->keyp = (void *)NSSprivkey; 1003 } 1004 if (pubkey != NULL) { 1005 pubkey->kstype = KMF_KEYSTORE_NSS; 1006 pubkey->keyalg = params->keytype; 1007 pubkey->keyp = (void *)NSSpubkey; 1008 pubkey->keyclass = KMF_ASYM_PUB; 1009 pubkey->keylabel = 1010 PK11_GetPublicKeyNickname(NSSpubkey); 1011 } 1012 rv = KMF_OK; 1013 } 1014 cleanup: 1015 if (rv != KMF_OK) { 1016 if (NSSpubkey) 1017 PK11_DeleteTokenPublicKey(NSSpubkey); 1018 if (NSSprivkey) 1019 PK11_DeleteTokenPrivateKey(NSSprivkey, PR_TRUE); 1020 1021 privkey->keyp = NULL; 1022 pubkey->keyp = NULL; 1023 } 1024 1025 if (pqgParams != NULL) 1026 PK11_PQG_DestroyParams(pqgParams); 1027 1028 1029 if (nss_slot != NULL) 1030 PK11_FreeSlot(nss_slot); 1031 1032 return (rv); 1033 } 1034 1035 KMF_RETURN 1036 NSS_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 1037 KMF_OID *AlgOID, KMF_DATA *tobesigned, 1038 KMF_DATA *output) 1039 { 1040 KMF_RETURN ret = KMF_OK; 1041 KMF_ALGORITHM_INDEX AlgId; 1042 SECOidTag signAlgTag; 1043 SECKEYPrivateKey *NSSprivkey = NULL; 1044 SECStatus rv; 1045 SECItem signed_data; 1046 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1047 1048 signed_data.data = 0; 1049 if (key == NULL || AlgOID == NULL || 1050 tobesigned == NULL || output == NULL || 1051 tobesigned->Data == NULL || 1052 output->Data == NULL) 1053 return (KMF_ERR_BAD_PARAMETER); 1054 1055 /* Map the OID to a NSS algorithm */ 1056 AlgId = X509_AlgorithmOidToAlgId(AlgOID); 1057 if (AlgId == KMF_ALGID_NONE) 1058 return (KMF_ERR_BAD_PARAMETER); 1059 1060 NSSprivkey = (SECKEYPrivateKey *)key->keyp; 1061 1062 if (AlgId == KMF_ALGID_MD5WithRSA) 1063 signAlgTag = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION; 1064 else if (AlgId == KMF_ALGID_MD2WithRSA) 1065 signAlgTag = SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION; 1066 else if (AlgId == KMF_ALGID_SHA1WithRSA) 1067 signAlgTag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; 1068 else if (AlgId == KMF_ALGID_SHA1WithDSA) 1069 signAlgTag = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; 1070 else 1071 return (KMF_ERR_BAD_PARAMETER); 1072 1073 rv = SEC_SignData(&signed_data, tobesigned->Data, 1074 tobesigned->Length, NSSprivkey, signAlgTag); 1075 1076 if (rv != 0) { 1077 SET_ERROR(kmfh, rv); 1078 return (KMF_ERR_INTERNAL); 1079 } 1080 1081 if (signed_data.len <= output->Length) { 1082 (void) memcpy(output->Data, signed_data.data, signed_data.len); 1083 output->Length = signed_data.len; 1084 } else { 1085 output->Length = 0; 1086 ret = KMF_ERR_BAD_PARAMETER; 1087 } 1088 free(signed_data.data); 1089 1090 return (ret); 1091 } 1092 1093 KMF_RETURN 1094 NSS_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp, 1095 KMF_DATA *encoded) 1096 { 1097 KMF_RETURN ret = KMF_OK; 1098 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1099 SECItem *rvitem; 1100 CERTSubjectPublicKeyInfo *spki = NULL; 1101 1102 if (keyp == NULL || encoded == NULL || keyp->keyp == NULL) 1103 return (KMF_ERR_BAD_PARAMETER); 1104 1105 spki = SECKEY_CreateSubjectPublicKeyInfo(keyp->keyp); 1106 if (spki == NULL) { 1107 SET_ERROR(kmfh, PORT_GetError()); 1108 return (KMF_ERR_MEMORY); 1109 } 1110 1111 rvitem = SEC_ASN1EncodeItem(NULL, NULL, spki, 1112 CERT_SubjectPublicKeyInfoTemplate); 1113 1114 if (rvitem != NULL) { 1115 encoded->Data = malloc(rvitem->len); 1116 if (encoded->Data == NULL) { 1117 ret = KMF_ERR_MEMORY; 1118 } else { 1119 (void) memcpy(encoded->Data, rvitem->data, rvitem->len); 1120 encoded->Length = rvitem->len; 1121 } 1122 SECITEM_FreeItem(rvitem, TRUE); 1123 } else { 1124 SET_ERROR(kmfh, PORT_GetError()); 1125 encoded->Data = NULL; 1126 encoded->Length = 0; 1127 ret = KMF_ERR_ENCODING; 1128 } 1129 SECKEY_DestroySubjectPublicKeyInfo(spki); 1130 1131 return (ret); 1132 } 1133 1134 KMF_RETURN 1135 NSS_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params, 1136 KMF_KEY_HANDLE *key, boolean_t delete_token) 1137 { 1138 KMF_RETURN rv = KMF_OK; 1139 PK11SlotInfo *nss_slot = NULL; 1140 1141 /* 1142 * "delete_token" means to clear it from the token storage as well 1143 * as from memory. 1144 */ 1145 if (key == NULL || key->keyp == NULL) 1146 return (KMF_ERR_BAD_PARAMETER); 1147 1148 if (delete_token) { 1149 SECStatus nssrv = SECSuccess; 1150 if (key->keyclass != KMF_ASYM_PUB && 1151 key->keyclass != KMF_ASYM_PRI && 1152 key->keyclass != KMF_SYMMETRIC) 1153 return (KMF_ERR_BAD_KEY_CLASS); 1154 1155 if (params == NULL) 1156 return (KMF_ERR_BAD_PARAMETER); 1157 rv = Do_NSS_Init(handle, 1158 params->ks_opt_u.nss_opts, FALSE, &nss_slot); 1159 if (rv != KMF_OK) { 1160 return (rv); 1161 } 1162 rv = nss_authenticate(handle, nss_slot, ¶ms->cred); 1163 if (rv != KMF_OK) { 1164 return (rv); 1165 } 1166 1167 if (key->keyclass == KMF_ASYM_PUB) { 1168 nssrv = PK11_DeleteTokenPublicKey( 1169 (SECKEYPublicKey *)key->keyp); 1170 } else if (key->keyclass == KMF_ASYM_PRI) { 1171 nssrv = PK11_DeleteTokenPrivateKey( 1172 (SECKEYPrivateKey *)key->keyp, PR_TRUE); 1173 } else if (key->keyclass == KMF_SYMMETRIC) { 1174 nssrv = PK11_DeleteTokenSymKey( 1175 (PK11SymKey *) key->keyp); 1176 if (nssrv == SECSuccess) 1177 PK11_FreeSymKey( 1178 (PK11SymKey *) key->keyp); 1179 } 1180 if (nssrv != SECSuccess) { 1181 SET_ERROR(handle, PORT_GetError()); 1182 rv = KMF_ERR_INTERNAL; 1183 } 1184 } else { 1185 if (key->keyclass == KMF_ASYM_PUB) { 1186 SECKEY_DestroyPublicKey((SECKEYPublicKey *)key->keyp); 1187 } else if (key->keyclass == KMF_ASYM_PRI) { 1188 SECKEY_DestroyPrivateKey((SECKEYPrivateKey *)key->keyp); 1189 } else if (key->keyclass == KMF_SYMMETRIC) { 1190 PK11_FreeSymKey((PK11SymKey *) key->keyp); 1191 } else { 1192 return (KMF_ERR_BAD_KEY_CLASS); 1193 } 1194 } 1195 key->keyp = NULL; 1196 1197 return (rv); 1198 } 1199 1200 KMF_RETURN 1201 NSS_ImportCRL(KMF_HANDLE_T handle, KMF_IMPORTCRL_PARAMS *params) 1202 { 1203 KMF_RETURN ret = KMF_OK; 1204 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1205 PK11SlotInfo *nss_slot = NULL; 1206 CERTSignedCrl *nss_crl = NULL; 1207 KMF_ENCODE_FORMAT format; 1208 int importOptions; 1209 SECItem crlDER; 1210 KMF_DATA crl1; 1211 KMF_DATA crl2; 1212 1213 if (params == NULL || params->ks_opt_u.nss_opts.crlfile == NULL) { 1214 return (KMF_ERR_BAD_PARAMETER); 1215 } 1216 1217 /* 1218 * Check if the input CRL file is a valid CRL file and auto-detect 1219 * the encoded format of the file. 1220 */ 1221 ret = KMF_IsCRLFile(handle, params->ks_opt_u.nss_opts.crlfile, 1222 &format); 1223 if (ret != KMF_OK) 1224 return (ret); 1225 1226 ret = Do_NSS_Init(handle, 1227 params->ks_opt_u.nss_opts, TRUE, &nss_slot); 1228 if (ret != KMF_OK) { 1229 return (ret); 1230 } 1231 1232 /* set importOptions */ 1233 if (params->ks_opt_u.nss_opts.crl_check == B_FALSE) { 1234 importOptions = CRL_IMPORT_DEFAULT_OPTIONS | 1235 CRL_IMPORT_BYPASS_CHECKS; 1236 } else { 1237 importOptions = CRL_IMPORT_DEFAULT_OPTIONS; 1238 } 1239 1240 1241 /* Read in the CRL file */ 1242 crl1.Data = NULL; 1243 crl2.Data = NULL; 1244 ret = KMF_ReadInputFile(handle, params->ks_opt_u.nss_opts.crlfile, 1245 &crl1); 1246 if (ret != KMF_OK) { 1247 return (ret); 1248 } 1249 1250 /* If the input CRL is in PEM format, convert it to DER first. */ 1251 if (format == KMF_FORMAT_PEM) { 1252 int len; 1253 ret = KMF_Pem2Der(crl1.Data, crl1.Length, 1254 &crl2.Data, &len); 1255 if (ret != KMF_OK) { 1256 goto out; 1257 } 1258 crl2.Length = (size_t)len; 1259 } 1260 1261 crlDER.data = format == KMF_FORMAT_ASN1 ? crl1.Data : crl2.Data; 1262 crlDER.len = format == KMF_FORMAT_ASN1 ? crl1.Length : crl2.Length; 1263 1264 nss_crl = PK11_ImportCRL(nss_slot, &crlDER, NULL, SEC_CRL_TYPE, 1265 NULL, importOptions, NULL, CRL_DECODE_DEFAULT_OPTIONS); 1266 1267 if (nss_crl == NULL) { 1268 SET_ERROR(kmfh, PORT_GetError()); 1269 ret = KMF_ERR_BAD_CRLFILE; 1270 goto out; 1271 } 1272 1273 out: 1274 if (nss_slot != NULL) { 1275 PK11_FreeSlot(nss_slot); 1276 } 1277 1278 if (crl1.Data != NULL) { 1279 free(crl1.Data); 1280 } 1281 1282 if (crl2.Data != NULL) { 1283 free(crl2.Data); 1284 } 1285 1286 if (nss_crl != NULL) { 1287 SEC_DestroyCrl(nss_crl); 1288 } 1289 1290 return (ret); 1291 } 1292 1293 KMF_RETURN 1294 NSS_DeleteCRL(KMF_HANDLE_T handle, KMF_DELETECRL_PARAMS *params) 1295 { 1296 KMF_RETURN rv = KMF_OK; 1297 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1298 CERTSignedCrl *crl = NULL; 1299 CERTCertificate *cert = NULL; 1300 PK11SlotInfo *nss_slot = NULL; 1301 CERTCrlHeadNode *crlList = NULL; 1302 CERTCrlNode *crlNode = NULL; 1303 PRArenaPool *arena = NULL; 1304 CERTName *name = NULL; 1305 CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); 1306 1307 /* check params */ 1308 if (params == NULL || 1309 (params->ks_opt_u.nss_opts.crl_issuerName == NULL && 1310 params->ks_opt_u.nss_opts.crl_subjName == NULL) || 1311 (params->ks_opt_u.nss_opts.crl_issuerName != NULL && 1312 params->ks_opt_u.nss_opts.crl_subjName != NULL)) { 1313 return (KMF_ERR_BAD_PARAMETER); 1314 } 1315 1316 rv = Do_NSS_Init(handle, 1317 params->ks_opt_u.nss_opts, TRUE, 1318 &nss_slot); 1319 if (rv != KMF_OK) { 1320 return (rv); 1321 } 1322 1323 /* Find the CRL based on the deletion criteria. */ 1324 if (params->ks_opt_u.nss_opts.crl_issuerName != NULL) { 1325 /* 1326 * If the deletion is based on the issuer's certificate 1327 * nickname, we will get the issuer's cert first, then 1328 * get the CRL from the cert. 1329 */ 1330 cert = CERT_FindCertByNicknameOrEmailAddr(certHandle, 1331 params->ks_opt_u.nss_opts.crl_issuerName); 1332 if (!cert) { 1333 SET_ERROR(kmfh, PORT_GetError()); 1334 rv = KMF_ERR_CERT_NOT_FOUND; 1335 goto out; 1336 } 1337 1338 crl = SEC_FindCrlByName(certHandle, &cert->derSubject, 1339 SEC_CRL_TYPE); 1340 if (crl == NULL) { 1341 SET_ERROR(kmfh, PORT_GetError()); 1342 rv = KMF_ERR_CRL_NOT_FOUND; 1343 goto out; 1344 } 1345 } else { 1346 /* 1347 * If the deletion is based on the CRL's subject name, we will 1348 * get all the CRLs from the internal database and search 1349 * for the CRL with the same subject name. 1350 */ 1351 boolean_t found = B_FALSE; 1352 int nssrv; 1353 1354 nssrv = SEC_LookupCrls(certHandle, &crlList, SEC_CRL_TYPE); 1355 if (nssrv) { 1356 SET_ERROR(kmfh, nssrv); 1357 rv = KMF_ERR_CRL_NOT_FOUND; 1358 goto out; 1359 } 1360 1361 if (crlList == NULL) { 1362 SET_ERROR(kmfh, PORT_GetError()); 1363 rv = KMF_ERR_CRL_NOT_FOUND; 1364 goto out; 1365 } 1366 1367 /* Allocate space for name */ 1368 arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); 1369 if (arena == NULL) { 1370 rv = KMF_ERR_MEMORY; 1371 goto out; 1372 } 1373 1374 name = PORT_ArenaZAlloc(arena, sizeof (*name)); 1375 if (name == NULL) { 1376 rv = KMF_ERR_MEMORY; 1377 goto out; 1378 } 1379 name->arena = arena; 1380 1381 crlNode = crlList->first; 1382 while (crlNode && !found) { 1383 char *asciiname = NULL; 1384 SECItem* issuer; 1385 1386 name = &crlNode->crl->crl.name; 1387 if (!name) { 1388 SET_ERROR(kmfh, PORT_GetError()); 1389 rv = KMF_ERR_CRL_NOT_FOUND; 1390 break; 1391 } 1392 1393 asciiname = CERT_NameToAscii(name); 1394 if (asciiname == NULL) { 1395 SET_ERROR(kmfh, PORT_GetError()); 1396 rv = KMF_ERR_CRL_NOT_FOUND; 1397 break; 1398 } 1399 1400 if (strcmp(params->ks_opt_u.nss_opts.crl_subjName, 1401 asciiname) == 0) { 1402 found = B_TRUE; 1403 issuer = &crlNode->crl->crl.derName; 1404 crl = SEC_FindCrlByName(certHandle, issuer, 1405 SEC_CRL_TYPE); 1406 if (crl == NULL) { 1407 /* We found a cert but no CRL */ 1408 SET_ERROR(kmfh, PORT_GetError()); 1409 rv = KMF_ERR_CRL_NOT_FOUND; 1410 } 1411 } 1412 PORT_Free(asciiname); 1413 crlNode = crlNode->next; 1414 } 1415 1416 if (rv) { 1417 goto out; 1418 } 1419 } 1420 1421 if (crl) { 1422 (void) SEC_DeletePermCRL(crl); 1423 } 1424 1425 out: 1426 if (nss_slot != NULL) { 1427 PK11_FreeSlot(nss_slot); 1428 } 1429 1430 if (crlList != NULL) { 1431 PORT_FreeArena(crlList->arena, PR_FALSE); 1432 } 1433 1434 if (arena != NULL) { 1435 PORT_FreeArena(arena, PR_FALSE); 1436 } 1437 1438 if (cert != NULL) { 1439 CERT_DestroyCertificate(cert); 1440 } 1441 1442 if (crl != NULL) { 1443 SEC_DestroyCrl(crl); 1444 } 1445 1446 return (rv); 1447 } 1448 1449 1450 KMF_RETURN 1451 NSS_FindCRL(KMF_HANDLE_T handle, KMF_FINDCRL_PARAMS *params, 1452 char **CRLNameList, int *CRLCount) 1453 { 1454 KMF_RETURN rv = KMF_OK; 1455 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1456 PK11SlotInfo *nss_slot = NULL; 1457 CERTCrlHeadNode *crlList = NULL; 1458 CERTCrlNode *crlNode = NULL; 1459 PRArenaPool *arena = NULL; 1460 CERTName *name = NULL; 1461 SECStatus nssrv; 1462 char *asciiname = NULL; 1463 int crl_num; 1464 int i; 1465 CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); 1466 1467 if (CRLCount == NULL || params == NULL) { 1468 return (KMF_ERR_BAD_PARAMETER); 1469 } 1470 1471 *CRLCount = 0; 1472 1473 rv = Do_NSS_Init(handle, 1474 params->ks_opt_u.nss_opts, TRUE, &nss_slot); 1475 if (rv != KMF_OK) { 1476 return (rv); 1477 } 1478 1479 /* Look up Crls */ 1480 nssrv = SEC_LookupCrls(certHandle, &crlList, SEC_CRL_TYPE); 1481 if (nssrv) { 1482 SET_ERROR(kmfh, rv); 1483 rv = KMF_ERR_CRL_NOT_FOUND; 1484 goto out; 1485 } 1486 1487 /* Allocate space for name first */ 1488 arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); 1489 if (arena == NULL) { 1490 rv = KMF_ERR_MEMORY; 1491 goto out; 1492 } 1493 1494 name = PORT_ArenaZAlloc(arena, sizeof (*name)); 1495 if (name == NULL) { 1496 rv = KMF_ERR_MEMORY; 1497 goto out; 1498 } 1499 name->arena = arena; 1500 1501 /* 1502 * Loop thru the crlList and create a crl list with CRL's subject name. 1503 */ 1504 crlNode = crlList->first; 1505 crl_num = 0; 1506 while (crlNode) { 1507 char *subj_name; 1508 1509 /* Get the CRL subject name */ 1510 name = &crlNode->crl->crl.name; 1511 if (!name) { 1512 SET_ERROR(kmfh, PORT_GetError()); 1513 rv = KMF_ERR_CRL_NOT_FOUND; 1514 break; 1515 } 1516 1517 1518 if (CRLNameList != NULL) { 1519 asciiname = CERT_NameToAscii(name); 1520 if (asciiname == NULL) { 1521 SET_ERROR(kmfh, PORT_GetError()); 1522 rv = KMF_ERR_CRL_NOT_FOUND; 1523 break; 1524 } 1525 subj_name = strdup(asciiname); 1526 PORT_Free(asciiname); 1527 if (subj_name == NULL) { 1528 rv = KMF_ERR_MEMORY; 1529 break; 1530 } 1531 CRLNameList[crl_num] = subj_name; 1532 } 1533 1534 crl_num++; 1535 crlNode = crlNode->next; 1536 } 1537 1538 if (rv == KMF_OK) { 1539 /* success */ 1540 *CRLCount = crl_num; 1541 } 1542 1543 out: 1544 if (nss_slot != NULL) { 1545 PK11_FreeSlot(nss_slot); 1546 } 1547 1548 if (crlList != NULL) { 1549 PORT_FreeArena(crlList->arena, PR_FALSE); 1550 } 1551 1552 if (arena != NULL) { 1553 PORT_FreeArena(arena, PR_FALSE); 1554 } 1555 1556 /* If failed, free memory allocated for the returning rlist */ 1557 if (rv && (CRLNameList != NULL)) { 1558 for (i = 0; i < crl_num; i++) { 1559 free(CRLNameList[i]); 1560 } 1561 } 1562 1563 return (rv); 1564 } 1565 1566 1567 KMF_RETURN 1568 NSS_FindCertInCRL(KMF_HANDLE_T handle, KMF_FINDCERTINCRL_PARAMS *params) 1569 { 1570 KMF_RETURN rv = KMF_OK; 1571 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1572 PK11SlotInfo *nss_slot = NULL; 1573 CERTCertificate *cert = NULL; 1574 CERTSignedCrl *crl = NULL; 1575 CERTCrlEntry *entry; 1576 boolean_t match = B_FALSE; 1577 int i; 1578 CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); 1579 1580 /* check params */ 1581 if (params == NULL || 1582 (params->ks_opt_u.nss_opts.certLabel == NULL && 1583 params->ks_opt_u.nss_opts.certificate == NULL)) { 1584 return (KMF_ERR_BAD_PARAMETER); 1585 } 1586 1587 rv = Do_NSS_Init(handle, 1588 params->ks_opt_u.nss_opts, TRUE, &nss_slot); 1589 if (rv != KMF_OK) { 1590 return (rv); 1591 } 1592 1593 /* Find the certificate first */ 1594 if (params->ks_opt_u.nss_opts.certLabel != NULL) { 1595 cert = CERT_FindCertByNicknameOrEmailAddr(certHandle, 1596 params->ks_opt_u.nss_opts.certLabel); 1597 } else { 1598 SECItem derCert = { NULL, 0}; 1599 1600 derCert.data = params->ks_opt_u.nss_opts.certificate->Data; 1601 derCert.len = params->ks_opt_u.nss_opts.certificate->Length; 1602 cert = CERT_FindCertByDERCert(certHandle, &derCert); 1603 } 1604 1605 if (!cert) { 1606 SET_ERROR(kmfh, PORT_GetError()); 1607 rv = KMF_ERR_CERT_NOT_FOUND; 1608 goto out; 1609 } 1610 1611 /* Find the CRL with the same issuer as the given certificate. */ 1612 crl = SEC_FindCrlByName(certHandle, &cert->derIssuer, SEC_CRL_TYPE); 1613 if (crl == NULL) { 1614 /* 1615 * Could not find the CRL issued by the same issuer. This 1616 * usually means that the CRL is not installed in the DB. 1617 */ 1618 SET_ERROR(kmfh, PORT_GetError()); 1619 rv = KMF_ERR_CRL_NOT_FOUND; 1620 goto out; 1621 1622 } 1623 1624 /* Check if the certificate's serialNumber is revoked in the CRL */ 1625 i = 0; 1626 while ((entry = (crl->crl).entries[i++]) != NULL) { 1627 if (SECITEM_CompareItem(&(cert->serialNumber), 1628 &(entry->serialNumber)) == SECEqual) { 1629 match = B_TRUE; 1630 break; 1631 } 1632 } 1633 1634 if (!match) { 1635 rv = KMF_ERR_NOT_REVOKED; 1636 } 1637 1638 out: 1639 if (nss_slot != NULL) { 1640 PK11_FreeSlot(nss_slot); 1641 } 1642 1643 if (cert != NULL) { 1644 CERT_DestroyCertificate(cert); 1645 } 1646 1647 if (crl != NULL) { 1648 SEC_DestroyCrl(crl); 1649 } 1650 1651 return (rv); 1652 } 1653 1654 KMF_RETURN 1655 NSS_GetErrorString(KMF_HANDLE_T handle, char **msgstr) 1656 { 1657 KMF_RETURN ret = KMF_OK; 1658 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1659 char *str; 1660 1661 /* Get the error string in the default language */ 1662 str = (char *)PR_ErrorToName((PRErrorCode)kmfh->lasterr.errcode); 1663 1664 if (str != NULL) { 1665 *msgstr = (char *)strdup(str); 1666 if ((*msgstr) == NULL) 1667 ret = KMF_ERR_MEMORY; 1668 } else { 1669 *msgstr = NULL; 1670 } 1671 1672 return (ret); 1673 } 1674 1675 KMF_RETURN 1676 NSS_GetPrikeyByCert(KMF_HANDLE_T handle, KMF_CRYPTOWITHCERT_PARAMS *params, 1677 KMF_DATA *SignerCertData, KMF_KEY_HANDLE *key, 1678 KMF_KEY_ALG keytype) 1679 { 1680 CERTCertificate *nss_cert = NULL; 1681 SECKEYPrivateKey* privkey = NULL; 1682 PK11SlotInfo *nss_slot = NULL; 1683 KMF_RETURN rv = KMF_OK; 1684 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1685 1686 rv = Do_NSS_Init(handle, 1687 params->nssparms, FALSE, &nss_slot); 1688 if (rv != KMF_OK) { 1689 return (rv); 1690 } 1691 1692 rv = nss_authenticate(handle, nss_slot, ¶ms->cred); 1693 if (rv != KMF_OK) { 1694 return (rv); 1695 } 1696 1697 nss_cert = CERT_DecodeCertFromPackage((char *)SignerCertData->Data, 1698 SignerCertData->Length); 1699 1700 if (nss_cert == NULL) { 1701 SET_ERROR(kmfh, PORT_GetError()); 1702 return (KMF_ERR_BAD_CERT_FORMAT); 1703 } 1704 1705 privkey = PK11_FindPrivateKeyFromCert(nss_slot, nss_cert, NULL); 1706 if (privkey == NULL) { 1707 SET_ERROR(kmfh, PORT_GetError()); 1708 return (KMF_ERR_KEY_NOT_FOUND); 1709 } 1710 1711 key->kstype = KMF_KEYSTORE_NSS; 1712 key->keyclass = KMF_ASYM_PRI; 1713 key->keyalg = keytype; 1714 key->keyp = (void *)privkey; 1715 key->keylabel = PK11_GetPrivateKeyNickname(privkey); 1716 1717 CERT_DestroyCertificate(nss_cert); 1718 1719 return (KMF_OK); 1720 1721 } 1722 1723 KMF_RETURN 1724 NSS_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 1725 KMF_OID *AlgOID, KMF_DATA *ciphertext, 1726 KMF_DATA *output) 1727 { 1728 KMF_RETURN ret = KMF_OK; 1729 SECKEYPrivateKey *NSSprivkey = NULL; 1730 SECStatus rv; 1731 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1732 unsigned int in_len = 0, out_len = 0; 1733 unsigned int total_decrypted = 0, modulus_len = 0; 1734 uint8_t *in_data, *out_data; 1735 int i, blocks; 1736 1737 1738 if (key == NULL || AlgOID == NULL || 1739 ciphertext == NULL || output == NULL || 1740 ciphertext->Data == NULL || 1741 output->Data == NULL) 1742 return (KMF_ERR_BAD_PARAMETER); 1743 1744 NSSprivkey = (SECKEYPrivateKey *)key->keyp; 1745 modulus_len = PK11_GetPrivateModulusLen(NSSprivkey); 1746 1747 blocks = ciphertext->Length/modulus_len; 1748 out_data = output->Data; 1749 in_data = ciphertext->Data; 1750 out_len = modulus_len - 11; 1751 in_len = modulus_len; 1752 1753 for (i = 0; i < blocks; i++) { 1754 rv = PK11_PrivDecryptPKCS1(NSSprivkey, out_data, 1755 &out_len, ciphertext->Length, in_data, in_len); 1756 1757 if (rv != 0) { 1758 SET_ERROR(kmfh, rv); 1759 return (KMF_ERR_INTERNAL); 1760 } 1761 1762 out_data += out_len; 1763 total_decrypted += out_len; 1764 in_data += in_len; 1765 } 1766 1767 output->Length = total_decrypted; 1768 1769 return (ret); 1770 } 1771 1772 static KMF_KEY_ALG 1773 pk11keytype2kmf(CK_KEY_TYPE type) 1774 { 1775 switch (type) { 1776 case CKK_RSA: 1777 return (KMF_RSA); 1778 case CKK_DSA: 1779 return (KMF_RSA); 1780 case CKK_AES: 1781 return (KMF_AES); 1782 case CKK_RC4: 1783 return (KMF_RC4); 1784 case CKK_DES: 1785 return (KMF_DES); 1786 case CKK_DES3: 1787 return (KMF_DES3); 1788 default: 1789 /* not supported */ 1790 return (KMF_KEYALG_NONE); 1791 } 1792 } 1793 1794 KMF_RETURN 1795 NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, 1796 KMF_KEY_HANDLE *keys, uint32_t *numkeys) 1797 { 1798 KMF_RETURN rv; 1799 SECKEYPrivateKeyList *prilist; 1800 SECKEYPrivateKeyListNode *prinode; 1801 SECKEYPublicKeyList *publist; 1802 SECKEYPublicKeyListNode *pubnode; 1803 PK11SlotInfo *nss_slot = NULL; 1804 PK11SymKey *symlist; 1805 int count; 1806 1807 if (handle == NULL || parms == NULL || numkeys == NULL) 1808 return (KMF_ERR_BAD_PARAMETER); 1809 1810 rv = Do_NSS_Init(handle, 1811 parms->ks_opt_u.nss_opts, FALSE, &nss_slot); 1812 if (rv != KMF_OK) { 1813 return (rv); 1814 } 1815 1816 rv = nss_authenticate(handle, nss_slot, &parms->cred); 1817 if (rv != KMF_OK) { 1818 return (rv); 1819 } 1820 1821 *numkeys = 0; 1822 if (parms->keyclass == KMF_ASYM_PUB) { 1823 publist = PK11_ListPublicKeysInSlot(nss_slot, parms->findLabel); 1824 if (publist == NULL) { 1825 rv = KMF_ERR_KEY_NOT_FOUND; 1826 goto cleanup; 1827 } 1828 } else if (parms->keyclass == KMF_ASYM_PRI) { 1829 prilist = PK11_ListPrivKeysInSlot(nss_slot, 1830 parms->findLabel, NULL); 1831 if (prilist == NULL) { 1832 rv = KMF_ERR_KEY_NOT_FOUND; 1833 goto cleanup; 1834 } 1835 } else if (parms->keyclass == KMF_SYMMETRIC) { 1836 symlist = PK11_ListFixedKeysInSlot(nss_slot, parms->findLabel, 1837 NULL); 1838 if (symlist == NULL) { 1839 rv = KMF_ERR_KEY_NOT_FOUND; 1840 goto cleanup; 1841 } 1842 } else { 1843 rv = KMF_ERR_BAD_KEY_CLASS; 1844 goto cleanup; 1845 } 1846 1847 if (parms->keyclass == KMF_ASYM_PUB) { 1848 for (count = 0, pubnode = PUBKEY_LIST_HEAD(publist); 1849 !PUBKEY_LIST_END(pubnode, publist); 1850 pubnode = PUBKEY_LIST_NEXT(pubnode), count++) { 1851 if (keys != NULL) { 1852 keys[count].kstype = KMF_KEYSTORE_NSS; 1853 keys[count].keyclass = KMF_ASYM_PUB; 1854 keys[count].keyp = (void *)pubnode->key; 1855 keys[count].keylabel = 1856 PK11_GetPublicKeyNickname( 1857 pubnode->key); 1858 1859 if (pubnode->key->keyType == rsaKey) 1860 keys[count].keyalg = KMF_RSA; 1861 else if (pubnode->key->keyType == dsaKey) 1862 keys[count].keyalg = KMF_DSA; 1863 } 1864 } 1865 *numkeys = count; 1866 } else if (parms->keyclass == KMF_ASYM_PRI) { 1867 for (count = 0, prinode = PRIVKEY_LIST_HEAD(prilist); 1868 !PRIVKEY_LIST_END(prinode, prilist); 1869 prinode = PRIVKEY_LIST_NEXT(prinode), count++) { 1870 if (keys != NULL) { 1871 keys[count].kstype = KMF_KEYSTORE_NSS; 1872 keys[count].keyclass = KMF_ASYM_PRI; 1873 keys[count].keyp = (void *)prinode->key; 1874 keys[count].keylabel = 1875 PK11_GetPrivateKeyNickname( 1876 prinode->key); 1877 1878 if (prinode->key->keyType == rsaKey) 1879 keys[count].keyalg = KMF_RSA; 1880 else if (prinode->key->keyType == dsaKey) 1881 keys[count].keyalg = KMF_DSA; 1882 } 1883 } 1884 *numkeys = count; 1885 } else if (parms->keyclass == KMF_SYMMETRIC) { 1886 count = 0; 1887 while (symlist) { 1888 PK11SymKey *symkey = symlist; 1889 CK_KEY_TYPE type; 1890 KMF_KEY_ALG keyalg; 1891 1892 type = PK11_GetSymKeyType(symkey); 1893 keyalg = pk11keytype2kmf(type); 1894 1895 /* 1896 * If keytype is specified in the searching parameter, 1897 * check the keytype and skip the key if its keytype 1898 * doesn't match. 1899 */ 1900 symlist = PK11_GetNextSymKey(symkey); 1901 if (parms->keytype != KMF_KEYALG_NONE && 1902 parms->keytype != keyalg) { 1903 continue; 1904 } 1905 1906 if (keys != NULL) { 1907 keys[count].kstype = KMF_KEYSTORE_NSS; 1908 keys[count].keyclass = KMF_SYMMETRIC; 1909 keys[count].keyp = (void *) symkey; 1910 keys[count].keylabel = 1911 PK11_GetSymKeyNickname(symkey); 1912 keys[count].keyalg = keyalg; 1913 } else { 1914 PK11_FreeSymKey(symkey); 1915 } 1916 count++; 1917 } 1918 *numkeys = count; 1919 } 1920 1921 cleanup: 1922 if (nss_slot != NULL) { 1923 PK11_FreeSlot(nss_slot); 1924 } 1925 1926 return (rv); 1927 } 1928 1929 static SECStatus 1930 p12u_SwapUnicodeBytes(SECItem *uniItem) 1931 { 1932 unsigned int i; 1933 unsigned char a; 1934 if ((uniItem == NULL) || (uniItem->len % 2)) { 1935 return (SECFailure); 1936 } 1937 for (i = 0; i < uniItem->len; i += 2) { 1938 a = uniItem->data[i]; 1939 uniItem->data[i] = uniItem->data[i+1]; 1940 uniItem->data[i+1] = a; 1941 } 1942 return (SECSuccess); 1943 } 1944 1945 static PRBool 1946 p12u_ucs2_ascii_conversion_function( 1947 PRBool toUnicode, 1948 unsigned char *inBuf, 1949 unsigned int inBufLen, 1950 unsigned char *outBuf, 1951 unsigned int maxOutBufLen, 1952 unsigned int *outBufLen, 1953 PRBool swapBytes) 1954 { 1955 SECItem it = { 0 }; 1956 SECItem *dup = NULL; 1957 PRBool ret; 1958 1959 it.data = inBuf; 1960 it.len = inBufLen; 1961 dup = SECITEM_DupItem(&it); 1962 /* 1963 * If converting Unicode to ASCII, swap bytes before conversion 1964 * as neccessary. 1965 */ 1966 if (!toUnicode && swapBytes) { 1967 if (p12u_SwapUnicodeBytes(dup) != SECSuccess) { 1968 SECITEM_ZfreeItem(dup, PR_TRUE); 1969 return (PR_FALSE); 1970 } 1971 } 1972 /* Perform the conversion. */ 1973 ret = PORT_UCS2_UTF8Conversion(toUnicode, dup->data, dup->len, 1974 outBuf, maxOutBufLen, outBufLen); 1975 if (dup) 1976 SECITEM_ZfreeItem(dup, PR_TRUE); 1977 1978 return (ret); 1979 } 1980 1981 static PRBool 1982 p12u_OpenFile(p12uContext *p12ctx, PRBool fileRead) 1983 { 1984 if (!p12ctx || !p12ctx->filename) { 1985 return (PR_FALSE); 1986 } 1987 1988 if (fileRead) { 1989 p12ctx->file = PR_Open(p12ctx->filename, 1990 PR_RDONLY, 0400); 1991 } else { 1992 p12ctx->file = PR_Open(p12ctx->filename, 1993 PR_CREATE_FILE | PR_RDWR | PR_TRUNCATE, 0600); 1994 } 1995 1996 if (!p12ctx->file) { 1997 p12ctx->error = PR_TRUE; 1998 return (PR_FALSE); 1999 } 2000 2001 return (PR_TRUE); 2002 } 2003 2004 static void 2005 p12u_DestroyContext(p12uContext **ppCtx, PRBool removeFile) 2006 { 2007 if (!ppCtx || !(*ppCtx)) { 2008 return; 2009 } 2010 2011 if ((*ppCtx)->file != NULL) { 2012 PR_Close((*ppCtx)->file); 2013 } 2014 2015 if ((*ppCtx)->filename != NULL) { 2016 if (removeFile) { 2017 PR_Delete((*ppCtx)->filename); 2018 } 2019 free((*ppCtx)->filename); 2020 } 2021 2022 free(*ppCtx); 2023 *ppCtx = NULL; 2024 } 2025 2026 static p12uContext * 2027 p12u_InitContext(PRBool fileImport, char *filename) 2028 { 2029 p12uContext *p12ctx; 2030 2031 p12ctx = PORT_ZNew(p12uContext); 2032 if (!p12ctx) { 2033 return (NULL); 2034 } 2035 2036 p12ctx->error = PR_FALSE; 2037 p12ctx->errorValue = 0; 2038 p12ctx->filename = strdup(filename); 2039 2040 if (!p12u_OpenFile(p12ctx, fileImport)) { 2041 p12u_DestroyContext(&p12ctx, PR_FALSE); 2042 return (NULL); 2043 } 2044 2045 return (p12ctx); 2046 } 2047 2048 static void 2049 p12u_WriteToExportFile(void *arg, const char *buf, unsigned long len) 2050 { 2051 p12uContext *p12cxt = arg; 2052 int writeLen; 2053 2054 if (!p12cxt || (p12cxt->error == PR_TRUE)) { 2055 return; 2056 } 2057 2058 if (p12cxt->file == NULL) { 2059 p12cxt->errorValue = SEC_ERROR_PKCS12_UNABLE_TO_WRITE; 2060 p12cxt->error = PR_TRUE; 2061 return; 2062 } 2063 2064 writeLen = PR_Write(p12cxt->file, (unsigned char *)buf, (int32)len); 2065 2066 if (writeLen != (int)len) { 2067 PR_Close(p12cxt->file); 2068 free(p12cxt->filename); 2069 p12cxt->filename = NULL; 2070 p12cxt->file = NULL; 2071 p12cxt->errorValue = SEC_ERROR_PKCS12_UNABLE_TO_WRITE; 2072 p12cxt->error = PR_TRUE; 2073 } 2074 } 2075 2076 #define HANDLE_NSS_ERROR(r) {\ 2077 SET_ERROR(kmfh, PORT_GetError()); \ 2078 rv = r; \ 2079 goto out; } 2080 2081 static KMF_RETURN 2082 add_cert_to_bag(SEC_PKCS12ExportContext *p12ecx, 2083 CERTCertificate *cert, SECItem *pwitem) 2084 { 2085 KMF_RETURN rv = KMF_OK; 2086 SEC_PKCS12SafeInfo *keySafe = NULL, *certSafe = NULL; 2087 2088 keySafe = SEC_PKCS12CreateUnencryptedSafe(p12ecx); 2089 if (PK11_IsFIPS()) { 2090 certSafe = keySafe; 2091 } else { 2092 certSafe = SEC_PKCS12CreatePasswordPrivSafe(p12ecx, pwitem, 2093 SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC); 2094 } 2095 2096 if (!certSafe || !keySafe) { 2097 rv = KMF_ERR_INTERNAL; 2098 goto out; 2099 } 2100 2101 if (SEC_PKCS12AddCertAndKey(p12ecx, certSafe, NULL, cert, 2102 CERT_GetDefaultCertDB(), keySafe, NULL, PR_TRUE, pwitem, 2103 SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC) 2104 != SECSuccess) { 2105 rv = KMF_ERR_INTERNAL; 2106 } 2107 out: 2108 return (rv); 2109 } 2110 2111 /*ARGSUSED*/ 2112 KMF_RETURN 2113 NSS_ExportP12(KMF_HANDLE_T handle, 2114 KMF_EXPORTP12_PARAMS *params, 2115 int numcerts, KMF_X509_DER_CERT *certs, 2116 int numkeys, KMF_KEY_HANDLE *keylist, 2117 char *filename) 2118 { 2119 KMF_RETURN rv; 2120 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2121 SEC_PKCS12ExportContext *p12ecx = NULL; 2122 p12uContext *p12ctx = NULL; 2123 CERTCertList *certlist = NULL; 2124 CERTCertificate *nsscert = NULL; 2125 CERTCertListNode* node = NULL; 2126 PK11SlotInfo *slot = NULL; 2127 SECItem pwitem = {NULL, 0}; 2128 2129 rv = Do_NSS_Init(handle, 2130 params->nssparms, FALSE, &slot); 2131 if (rv != KMF_OK) { 2132 return (rv); 2133 } 2134 2135 rv = nss_authenticate(handle, slot, ¶ms->cred); 2136 if (rv != KMF_OK) { 2137 return (rv); 2138 } 2139 2140 /* 2141 * Find the certificate(s) first. 2142 */ 2143 if (params->certLabel) { 2144 nsscert = PK11_FindCertFromNickname(params->certLabel, 2145 NULL); 2146 if (nsscert == NULL) { 2147 HANDLE_NSS_ERROR(KMF_ERR_CERT_NOT_FOUND) 2148 } 2149 } else { 2150 rv = nss_find_matching_certs(slot, 2151 params->issuer, 2152 params->subject, 2153 params->serial, 2154 &certlist, 0); 2155 2156 if (rv == KMF_OK && certlist == NULL) { 2157 return (KMF_ERR_CERT_NOT_FOUND); 2158 } 2159 if (rv != KMF_OK) 2160 return (rv); 2161 } 2162 2163 /* 2164 * The KMF_CREDENTIAL holds the password to use for 2165 * encrypting the PKCS12 key information. 2166 */ 2167 pwitem.data = (uchar_t *)params->p12cred.cred; 2168 pwitem.len = params->p12cred.credlen; 2169 2170 p12ctx = p12u_InitContext(PR_FALSE, filename); 2171 if (!p12ctx) { 2172 HANDLE_NSS_ERROR(KMF_ERR_OPEN_FILE) 2173 } 2174 2175 PORT_SetUCS2_ASCIIConversionFunction( 2176 p12u_ucs2_ascii_conversion_function); 2177 2178 p12ecx = SEC_PKCS12CreateExportContext(NULL, NULL, 2179 slot, NULL); 2180 if (!p12ecx) { 2181 HANDLE_NSS_ERROR(KMF_ERR_OPEN_FILE) 2182 } 2183 2184 if (SEC_PKCS12AddPasswordIntegrity(p12ecx, &pwitem, SEC_OID_SHA1) 2185 != SECSuccess) { 2186 HANDLE_NSS_ERROR(KMF_ERR_INTERNAL) 2187 } 2188 2189 /* 2190 * NSS actually supports storing a list of keys and certs 2191 * in the PKCS#12 PDU. Nice feature. 2192 */ 2193 if (certlist != NULL) { 2194 for (node = CERT_LIST_HEAD(certlist); 2195 !CERT_LIST_END(node, certlist) && rv == KMF_OK; 2196 node = CERT_LIST_NEXT(node)) { 2197 2198 rv = add_cert_to_bag(p12ecx, node->cert, &pwitem); 2199 } 2200 } else if (nsscert != NULL) { 2201 rv = add_cert_to_bag(p12ecx, nsscert, &pwitem); 2202 } 2203 2204 if (SEC_PKCS12Encode(p12ecx, p12u_WriteToExportFile, p12ctx) 2205 != SECSuccess) { 2206 HANDLE_NSS_ERROR(KMF_ERR_ENCODING) 2207 } 2208 out: 2209 if (nsscert) 2210 CERT_DestroyCertificate(nsscert); 2211 2212 if (certlist) 2213 CERT_DestroyCertList(certlist); 2214 2215 if (p12ctx) 2216 p12u_DestroyContext(&p12ctx, PR_FALSE); 2217 2218 if (p12ecx) 2219 SEC_PKCS12DestroyExportContext(p12ecx); 2220 2221 return (rv); 2222 } 2223 2224 #define SETATTR(t, n, atype, value, size) \ 2225 t[n].type = atype; \ 2226 t[n].pValue = (CK_BYTE *)value; \ 2227 t[n].ulValueLen = (CK_ULONG)size; 2228 2229 KMF_RETURN 2230 NSS_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, 2231 KMF_RAW_KEY_DATA *rawkey) 2232 { 2233 KMF_RETURN rv = KMF_OK; 2234 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2235 SECStatus ckrv = SECSuccess; 2236 PK11SlotInfo *slot = NULL; 2237 CERTCertificate *nss_cert = NULL; 2238 SECKEYPrivateKeyInfo rpk; 2239 SECItem nickname; 2240 KMF_DATA derkey = { NULL, 0 }; 2241 uchar_t ver = 0; 2242 2243 if (!kmfh) 2244 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 2245 2246 if (params == NULL || params->certificate == NULL || rawkey == NULL) 2247 return (KMF_ERR_BAD_PARAMETER); 2248 2249 rv = Do_NSS_Init(handle, 2250 params->nssparms, FALSE, &slot); 2251 2252 if (rv != KMF_OK) 2253 return (rv); 2254 2255 rv = nss_authenticate(handle, slot, ¶ms->cred); 2256 if (rv != KMF_OK) { 2257 return (rv); 2258 } 2259 2260 /* 2261 * Decode the cert into an NSS CERT object so we can access the 2262 * SPKI and KeyUsage data later. 2263 */ 2264 nss_cert = CERT_DecodeCertFromPackage((char *)params->certificate->Data, 2265 params->certificate->Length); 2266 2267 if (nss_cert == NULL) { 2268 SET_ERROR(kmfh, PORT_GetError()); 2269 rv = KMF_ERR_BAD_CERT_FORMAT; 2270 goto cleanup; 2271 } 2272 2273 (void) memset(&rpk, 0, sizeof (rpk)); 2274 2275 rpk.arena = NULL; 2276 rpk.version.type = siUnsignedInteger; 2277 rpk.version.data = &ver; 2278 rpk.version.len = 1; 2279 if (rawkey->keytype == KMF_RSA) { 2280 2281 rv = DerEncodeRSAPrivateKey(&derkey, &rawkey->rawdata.rsa); 2282 if (rv != KMF_OK) 2283 goto cleanup; 2284 2285 rpk.algorithm = nss_cert->subjectPublicKeyInfo.algorithm; 2286 rpk.privateKey.data = derkey.Data; 2287 rpk.privateKey.len = derkey.Length; 2288 rpk.attributes = NULL; 2289 2290 2291 } else if (rawkey->keytype == KMF_DSA) { 2292 rv = DerEncodeDSAPrivateKey(&derkey, &rawkey->rawdata.dsa); 2293 if (rv != KMF_OK) 2294 goto cleanup; 2295 2296 rpk.algorithm = nss_cert->subjectPublicKeyInfo.algorithm; 2297 rpk.privateKey.data = derkey.Data; 2298 rpk.privateKey.len = derkey.Length; 2299 rpk.attributes = NULL; 2300 2301 } else { 2302 return (KMF_ERR_BAD_PARAMETER); 2303 } 2304 2305 nickname.data = (uchar_t *)params->label; 2306 nickname.len = (params->label ? strlen(params->label) : 0); 2307 2308 ckrv = PK11_ImportPrivateKeyInfo(slot, &rpk, 2309 &nickname, &nss_cert->subjectPublicKeyInfo.subjectPublicKey, 2310 TRUE, TRUE, nss_cert->keyUsage, NULL); 2311 2312 if (ckrv != CKR_OK) { 2313 SET_ERROR(kmfh, PORT_GetError()); 2314 rv = KMF_ERR_INTERNAL; 2315 } 2316 2317 cleanup: 2318 if (nss_cert != NULL) { 2319 CERT_DestroyCertificate(nss_cert); 2320 } 2321 KMF_FreeData(&derkey); 2322 return (rv); 2323 } 2324 2325 KMF_RETURN 2326 NSS_CreateSymKey(KMF_HANDLE_T handle, 2327 KMF_CREATESYMKEY_PARAMS *params, 2328 KMF_KEY_HANDLE *symkey) 2329 { 2330 KMF_RETURN rv = KMF_OK; 2331 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2332 PK11SlotInfo *nss_slot = NULL; 2333 PK11SymKey *nsskey = NULL; 2334 CK_MECHANISM_TYPE keyType; 2335 SECStatus nssrv; 2336 int keySize; 2337 2338 if (params == NULL || symkey == NULL) { 2339 return (KMF_ERR_BAD_PARAMETER); 2340 } 2341 2342 switch (params->keytype) { 2343 case KMF_AES: 2344 keyType = CKM_AES_KEY_GEN; 2345 keySize = params->keylength; 2346 if (keySize == 0 || (keySize % 8) != 0) 2347 return (KMF_ERR_BAD_KEY_SIZE); 2348 break; 2349 case KMF_RC4: 2350 keyType = CKM_RC4_KEY_GEN; 2351 keySize = params->keylength; 2352 if (keySize == 0 || (keySize % 8) != 0) 2353 return (KMF_ERR_BAD_KEY_SIZE); 2354 break; 2355 case KMF_DES: 2356 keyType = CKM_DES_KEY_GEN; 2357 keySize = 0; /* required by PK11_TokenKeyGen() */ 2358 break; 2359 case KMF_DES3: 2360 keyType = CKM_DES3_KEY_GEN; 2361 keySize = 0; /* required by PK11_TokenKeyGen() */ 2362 break; 2363 case KMF_GENERIC_SECRET: 2364 keyType = CKM_GENERIC_SECRET_KEY_GEN; 2365 keySize = params->keylength; 2366 if (keySize == 0 || (keySize % 8) != 0) 2367 return (KMF_ERR_BAD_KEY_SIZE); 2368 break; 2369 default: 2370 rv = KMF_ERR_BAD_KEY_TYPE; 2371 goto out; 2372 } 2373 2374 rv = Do_NSS_Init(handle, 2375 params->ks_opt_u.nss_opts, FALSE, &nss_slot); 2376 if (rv != KMF_OK) { 2377 return (rv); 2378 } 2379 2380 rv = nss_authenticate(handle, nss_slot, ¶ms->cred); 2381 if (rv != KMF_OK) { 2382 return (rv); 2383 } 2384 2385 nsskey = PK11_TokenKeyGen(nss_slot, keyType, NULL, keySize, NULL, 2386 PR_TRUE, (void *)params->cred.cred); 2387 if (nsskey == NULL) { 2388 SET_ERROR(kmfh, PORT_GetError()); 2389 rv = KMF_ERR_KEYGEN_FAILED; 2390 goto out; 2391 } 2392 2393 nssrv = PK11_SetSymKeyNickname(nsskey, params->keylabel); 2394 if (nssrv != SECSuccess) { 2395 SET_ERROR(kmfh, PORT_GetError()); 2396 rv = KMF_ERR_KEYGEN_FAILED; 2397 goto out; 2398 } 2399 2400 symkey->kstype = KMF_KEYSTORE_NSS; 2401 symkey->keyalg = params->keytype; 2402 symkey->keyclass = KMF_SYMMETRIC; 2403 symkey->israw = FALSE; 2404 symkey->keyp = (void *)nsskey; 2405 2406 out: 2407 if (nss_slot != NULL) 2408 PK11_FreeSlot(nss_slot); 2409 2410 if (rv != KMF_OK && nsskey != NULL) { 2411 PK11_DeleteTokenSymKey(nsskey); 2412 PK11_FreeSymKey(nsskey); 2413 } 2414 return (rv); 2415 } 2416 2417 KMF_RETURN 2418 NSS_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, 2419 KMF_RAW_SYM_KEY *rkey) 2420 { 2421 KMF_RETURN rv = KMF_OK; 2422 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2423 SECItem *value = NULL; 2424 PK11SymKey *nsskey; 2425 SECStatus nss_rv; 2426 2427 if (kmfh == NULL) 2428 return (KMF_ERR_UNINITIALIZED); 2429 2430 if (symkey == NULL || rkey == NULL) 2431 return (KMF_ERR_BAD_PARAMETER); 2432 else if (symkey->keyclass != KMF_SYMMETRIC) 2433 return (KMF_ERR_BAD_KEY_CLASS); 2434 2435 if (symkey->israw) { 2436 KMF_RAW_KEY_DATA *rawkey = (KMF_RAW_KEY_DATA *)symkey->keyp; 2437 2438 if (rawkey == NULL || 2439 rawkey->rawdata.sym.keydata.val == NULL || 2440 rawkey->rawdata.sym.keydata.len == 0) 2441 return (KMF_ERR_BAD_KEYHANDLE); 2442 2443 rkey->keydata.len = rawkey->rawdata.sym.keydata.len; 2444 if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL) 2445 return (KMF_ERR_MEMORY); 2446 (void) memcpy(rkey->keydata.val, 2447 rawkey->rawdata.sym.keydata.val, rkey->keydata.len); 2448 } else { 2449 nsskey = (PK11SymKey *)(symkey->keyp); 2450 if (nsskey == NULL) 2451 return (KMF_ERR_BAD_KEYHANDLE); 2452 2453 nss_rv = PK11_ExtractKeyValue(nsskey); 2454 if (nss_rv != SECSuccess) { 2455 SET_ERROR(kmfh, PORT_GetError()); 2456 rv = KMF_ERR_GETKEYVALUE_FAILED; 2457 goto out; 2458 } 2459 2460 value = PK11_GetKeyData(nsskey); 2461 if (value == NULL) { 2462 SET_ERROR(kmfh, PORT_GetError()); 2463 rv = KMF_ERR_GETKEYVALUE_FAILED; 2464 goto out; 2465 } 2466 2467 if (value->len == 0 || value->data == NULL) { 2468 rv = KMF_ERR_GETKEYVALUE_FAILED; 2469 goto out; 2470 } 2471 2472 rkey->keydata.val = malloc(value->len); 2473 if (rkey->keydata.val == NULL) { 2474 rv = KMF_ERR_MEMORY; 2475 goto out; 2476 } 2477 (void) memcpy(rkey->keydata.val, value->data, value->len); 2478 rkey->keydata.len = value->len; 2479 (void) memset(value->data, 0, value->len); 2480 } 2481 out: 2482 if (value != NULL) 2483 SECITEM_FreeItem(value, PR_TRUE); 2484 return (rv); 2485 } 2486 2487 KMF_RETURN 2488 NSS_SetTokenPin(KMF_HANDLE_T handle, KMF_SETPIN_PARAMS *params, 2489 KMF_CREDENTIAL *newpin) 2490 { 2491 KMF_RETURN ret = KMF_OK; 2492 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2493 int rv; 2494 PK11SlotInfo *nss_slot = NULL; 2495 2496 if (handle == NULL || params == NULL || newpin == NULL) { 2497 return (KMF_ERR_BAD_PARAMETER); 2498 } 2499 2500 ret = Do_NSS_Init(handle, 2501 params->ks_opt_u.nss_opts, 2502 FALSE, &nss_slot); 2503 /* If it was uninitialized, set it */ 2504 if (ret == KMF_ERR_UNINITIALIZED_TOKEN) { 2505 rv = PK11_InitPin(nss_slot, NULL, newpin->cred); 2506 if (rv != SECSuccess) { 2507 SET_ERROR(kmfh, PORT_GetError()); 2508 ret = KMF_ERR_AUTH_FAILED; 2509 } else { 2510 ret = KMF_OK; 2511 } 2512 } else if (ret == KMF_OK) { 2513 ret = nss_authenticate(handle, nss_slot, ¶ms->cred); 2514 if (ret != KMF_OK) { 2515 return (ret); 2516 } 2517 rv = PK11_ChangePW(nss_slot, 2518 params->cred.cred, newpin->cred); 2519 if (rv != SECSuccess) { 2520 SET_ERROR(kmfh, PORT_GetError()); 2521 ret = KMF_ERR_AUTH_FAILED; 2522 } 2523 } 2524 2525 return (ret); 2526 } 2527