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 uint32_t maxcerts = *numcerts; 561 562 *numcerts = 0; 563 564 for (node = CERT_LIST_HEAD(nsscerts); 565 !CERT_LIST_END(node, nsscerts) && rv == KMF_OK && 566 (*numcerts) < maxcerts; 567 node = CERT_LIST_NEXT(node), (*numcerts)++) { 568 if (kmfcerts != NULL) 569 rv = nss2kmf_cert(node->cert, &kmfcerts[*numcerts]); 570 } 571 572 /* 573 * If we failed, delete any certs allocated so far. 574 */ 575 if (rv != KMF_OK) { 576 int i; 577 for (i = 0; i < *numcerts; i++) 578 KMF_FreeKMFCert(kmfhandle, &kmfcerts[i]); 579 *numcerts = 0; 580 } 581 return (rv); 582 } 583 584 KMF_RETURN 585 NSS_FindCert(KMF_HANDLE_T handle, KMF_FINDCERT_PARAMS *params, 586 KMF_X509_DER_CERT *kmfcerts, 587 uint32_t *num_certs) 588 { 589 KMF_RETURN rv = KMF_OK; 590 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 591 PK11SlotInfo *nss_slot = NULL; 592 CERTCertList *certlist = NULL; 593 uint32_t maxcerts; 594 595 rv = Do_NSS_Init(handle, 596 params->ks_opt_u.nss_opts, FALSE, &nss_slot); 597 if (rv != KMF_OK) { 598 return (rv); 599 } 600 601 if (*num_certs == 0) 602 maxcerts = 0xFFFFFFFF; 603 else 604 maxcerts = *num_certs; 605 606 *num_certs = 0; 607 if (params->certLabel) { 608 /* This will only find 1 certificate */ 609 rv = nss_getcert_by_label(kmfh, 610 params->certLabel, 611 kmfcerts, num_certs, params->find_cert_validity); 612 } else { 613 /* 614 * Build a list of matching certs. 615 */ 616 rv = nss_find_matching_certs(nss_slot, 617 params->issuer, params->subject, params->serial, 618 &certlist, params->find_cert_validity); 619 620 /* 621 * If the caller supplied a pointer to storage for 622 * a list of certs, convert up to 'maxcerts' of the 623 * matching certs. 624 */ 625 if (rv == KMF_OK && certlist != NULL) { 626 rv = convertCertList(handle, 627 certlist, kmfcerts, &maxcerts); 628 CERT_DestroyCertList(certlist); 629 if (rv == KMF_OK) 630 *num_certs = maxcerts; 631 } 632 } 633 634 if (nss_slot != NULL) { 635 PK11_FreeSlot(nss_slot); 636 } 637 638 if (rv == KMF_OK && *num_certs == 0) 639 rv = KMF_ERR_CERT_NOT_FOUND; 640 641 return (rv); 642 } 643 644 void 645 /*ARGSUSED*/ 646 NSS_FreeKMFCert(KMF_HANDLE_T handle, 647 KMF_X509_DER_CERT *kmf_cert) 648 { 649 if (kmf_cert != NULL) { 650 if (kmf_cert->certificate.Data != NULL) { 651 free(kmf_cert->certificate.Data); 652 kmf_cert->certificate.Data = NULL; 653 kmf_cert->certificate.Length = 0; 654 } 655 if (kmf_cert->kmf_private.label != NULL) { 656 free(kmf_cert->kmf_private.label); 657 kmf_cert->kmf_private.label = NULL; 658 } 659 } 660 } 661 662 KMF_RETURN 663 NSS_StoreCert(KMF_HANDLE_T handle, KMF_STORECERT_PARAMS *params, 664 KMF_DATA *pcert) 665 { 666 KMF_RETURN ret = KMF_OK; 667 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 668 SECStatus nss_rv; 669 CERTCertificate *nss_cert = NULL; 670 CERTCertTrust *nss_trust = NULL; 671 PK11SlotInfo *nss_slot = NULL; 672 CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); 673 674 if (pcert == NULL) { 675 return (KMF_ERR_BAD_PARAMETER); 676 } 677 678 /* NSS only support DER format */ 679 if (params == NULL) { 680 return (KMF_ERR_BAD_PARAMETER); 681 } 682 683 ret = Do_NSS_Init(handle, 684 params->ks_opt_u.nss_opts, FALSE, &nss_slot); 685 if (ret != KMF_OK) { 686 return (ret); 687 } 688 689 nss_cert = CERT_DecodeCertFromPackage((char *)pcert->Data, 690 pcert->Length); 691 if (nss_cert == NULL) { 692 SET_ERROR(kmfh, PORT_GetError()); 693 ret = KMF_ERR_BAD_CERT_FORMAT; 694 goto out; 695 } 696 697 nss_rv = PK11_ImportCert(nss_slot, nss_cert, CK_INVALID_HANDLE, 698 params->certLabel, 0); 699 if (nss_rv) { 700 SET_ERROR(kmfh, nss_rv); 701 ret = KMF_ERR_BAD_CERT_FORMAT; 702 goto out; 703 } 704 705 if (params->ks_opt_u.nss_opts.trustflag != NULL && 706 strlen(params->ks_opt_u.nss_opts.trustflag)) { 707 nss_trust = (CERTCertTrust *) malloc(sizeof (CERTCertTrust)); 708 if (nss_trust == NULL) { 709 ret = KMF_ERR_MEMORY; 710 goto out; 711 } 712 nss_rv = CERT_DecodeTrustString(nss_trust, 713 params->ks_opt_u.nss_opts.trustflag); 714 if (nss_rv) { 715 SET_ERROR(kmfh, nss_rv); 716 ret = KMF_ERR_BAD_PARAMETER; 717 goto out; 718 } 719 720 nss_rv = CERT_ChangeCertTrust(certHandle, nss_cert, nss_trust); 721 if (nss_rv) { 722 SET_ERROR(kmfh, nss_rv); 723 ret = KMF_ERR_BAD_PARAMETER; 724 } 725 } 726 727 out: 728 if (nss_trust != NULL) { 729 free(nss_trust); 730 } 731 732 if (nss_cert != NULL) { 733 CERT_DestroyCertificate(nss_cert); 734 } 735 736 if (nss_slot != NULL) { 737 PK11_FreeSlot(nss_slot); 738 } 739 740 return (ret); 741 } 742 743 744 KMF_RETURN 745 NSS_ImportCert(KMF_HANDLE_T handle, KMF_IMPORTCERT_PARAMS *params) 746 { 747 KMF_RETURN ret = KMF_OK; 748 KMF_STORECERT_PARAMS scparams; 749 KMF_DATA cert = {NULL, 0}; 750 KMF_DATA cert_der = {NULL, 0}; 751 KMF_DATA *cptr = NULL; 752 KMF_ENCODE_FORMAT format; 753 754 if (params == NULL || params->certfile == NULL) { 755 return (KMF_ERR_BAD_PARAMETER); 756 } 757 758 /* 759 * Check if the input cert file is a valid certificate and 760 * auto-detect the file format of it. 761 */ 762 ret = KMF_IsCertFile(handle, params->certfile, &format); 763 if (ret != KMF_OK) 764 return (ret); 765 766 ret = KMF_ReadInputFile(handle, params->certfile, &cert); 767 if (ret != KMF_OK) { 768 return (ret); 769 } 770 771 /* 772 * If the imported cert is in PEM format, convert it to 773 * DER format in order to store it in NSS token. 774 */ 775 if (format == KMF_FORMAT_PEM) { 776 int derlen; 777 ret = KMF_Pem2Der(cert.Data, cert.Length, 778 &cert_der.Data, &derlen); 779 if (ret != KMF_OK) { 780 goto cleanup; 781 } 782 cert_der.Length = (size_t)derlen; 783 cptr = &cert_der; 784 } else { 785 cptr = &cert; 786 } 787 788 (void) memset(&scparams, 0, sizeof (scparams)); 789 scparams.kstype = params->kstype; 790 scparams.certLabel = params->certLabel; 791 scparams.nssparms = params->nssparms; 792 793 ret = NSS_StoreCert(handle, &scparams, cptr); 794 795 if (format == KMF_FORMAT_PEM) { 796 KMF_FreeData(&cert_der); 797 } 798 799 cleanup: 800 KMF_FreeData(&cert); 801 802 return (ret); 803 } 804 805 KMF_RETURN 806 NSS_DeleteCert(KMF_HANDLE_T handle, KMF_DELETECERT_PARAMS *params) 807 { 808 KMF_RETURN rv = KMF_OK; 809 int nssrv; 810 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 811 CERTCertificate *cert = NULL; 812 PK11SlotInfo *nss_slot = NULL; 813 814 /* check params */ 815 if (params == NULL) { 816 return (KMF_ERR_BAD_PARAMETER); 817 } 818 819 rv = Do_NSS_Init(handle, 820 params->ks_opt_u.nss_opts, 821 FALSE, &nss_slot); 822 if (rv != KMF_OK) { 823 return (rv); 824 } 825 826 if (params->certLabel) { 827 cert = PK11_FindCertFromNickname(params->certLabel, NULL); 828 if (cert == NULL) { 829 return (KMF_ERR_CERT_NOT_FOUND); 830 } 831 832 switch (params->find_cert_validity) { 833 case KMF_ALL_CERTS: 834 break; 835 case KMF_NONEXPIRED_CERTS: 836 nssrv = CERT_CertTimesValid(cert); 837 if (nssrv == SECFailure) { 838 /* this is an invalid cert - skip it */ 839 goto out; 840 } 841 break; 842 case KMF_EXPIRED_CERTS: 843 nssrv = CERT_CertTimesValid(cert); 844 if (nssrv != SECFailure) { 845 /* this is a valid cert - skip it */ 846 goto out; 847 } 848 break; 849 } 850 /* delete it from database */ 851 nssrv = SEC_DeletePermCertificate(cert); 852 if (nssrv) { 853 SET_ERROR(kmfh, nssrv); 854 rv = KMF_ERR_INTERNAL; 855 } 856 } else { 857 CERTCertListNode *node; 858 CERTCertList *certlist = NULL; 859 860 rv = nss_find_matching_certs(nss_slot, 861 params->issuer, params->subject, params->serial, 862 &certlist, params->find_cert_validity); 863 864 for (node = CERT_LIST_HEAD(certlist); 865 !CERT_LIST_END(node, certlist) && rv == KMF_OK; 866 node = CERT_LIST_NEXT(node)) { 867 868 nssrv = SEC_DeletePermCertificate(node->cert); 869 if (nssrv) { 870 SET_ERROR(kmfh, nssrv); 871 rv = KMF_ERR_INTERNAL; 872 } 873 } 874 875 if (rv == KMF_OK && certlist != NULL) { 876 CERT_DestroyCertList(certlist); 877 } else if (rv == KMF_OK && certlist == NULL) { 878 rv = KMF_ERR_CERT_NOT_FOUND; 879 } 880 } 881 out: 882 if (nss_slot != NULL) { 883 PK11_FreeSlot(nss_slot); 884 } 885 886 if (cert != NULL) { 887 CERT_DestroyCertificate(cert); 888 } 889 890 return (rv); 891 } 892 893 static void 894 InitRandom(char *filename) 895 { 896 char buf[2048]; 897 int fd; 898 PRInt32 count; 899 900 fd = open(filename, O_RDONLY); 901 if (!fd) 902 return; 903 904 count = read(fd, buf, sizeof (buf)); 905 if (count > 0) { 906 PK11_RandomUpdate(buf, count); 907 } 908 909 (void) close(fd); 910 } 911 912 KMF_RETURN 913 NSS_CreateKeypair(KMF_HANDLE_T handle, 914 KMF_CREATEKEYPAIR_PARAMS *params, 915 KMF_KEY_HANDLE *privkey, 916 KMF_KEY_HANDLE *pubkey) 917 { 918 KMF_RETURN rv = KMF_OK; 919 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 920 PK11RSAGenParams rsaparams; 921 void *nssparams; 922 CK_MECHANISM_TYPE mechanism; 923 ulong_t publicExponent = 0x010001; 924 PK11SlotInfo *nss_slot = NULL; 925 SECKEYPrivateKey *NSSprivkey = NULL; 926 SECKEYPublicKey *NSSpubkey = NULL; 927 PQGParams *pqgParams = NULL; 928 929 930 if (params == NULL) { 931 return (KMF_ERR_BAD_PARAMETER); 932 } 933 934 rv = Do_NSS_Init(handle, 935 params->ks_opt_u.nss_opts, FALSE, &nss_slot); 936 if (rv != KMF_OK) { 937 return (rv); 938 } 939 940 rv = nss_authenticate(handle, nss_slot, ¶ms->cred); 941 if (rv != KMF_OK) { 942 return (rv); 943 } 944 945 /* Get some random bits */ 946 InitRandom("/dev/urandom"); 947 if (params->keytype == KMF_RSA) { 948 rsaparams.keySizeInBits = params->keylength; 949 /* 950 * NSS only allows for a 4 byte exponent. 951 * Ignore the exponent parameter if it is too big. 952 */ 953 if (params->rsa_exponent.len > 0 && 954 params->rsa_exponent.len <= sizeof (publicExponent) && 955 params->rsa_exponent.val != NULL) { 956 (void) memcpy(&publicExponent, 957 params->rsa_exponent.val, 958 params->rsa_exponent.len); 959 } 960 rsaparams.pe = publicExponent; 961 mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN; 962 nssparams = &rsaparams; 963 } else if (params->keytype == KMF_DSA) { 964 PQGVerify *pqgVerify = NULL; 965 int ks; 966 SECStatus nssrv, passed; 967 968 mechanism = CKM_DSA_KEY_PAIR_GEN; 969 970 ks = PQG_PBITS_TO_INDEX(params->keylength); 971 nssrv = PK11_PQG_ParamGen(ks, &pqgParams, &pqgVerify); 972 if (nssrv != SECSuccess) { 973 SET_ERROR(kmfh, rv); 974 PK11_PQG_DestroyVerify(pqgVerify); 975 rv = KMF_ERR_KEYGEN_FAILED; 976 goto cleanup; 977 } 978 979 nssrv = PK11_PQG_VerifyParams(pqgParams, pqgVerify, &passed); 980 if (nssrv != SECSuccess || passed != SECSuccess) { 981 SET_ERROR(kmfh, rv); 982 rv = KMF_ERR_KEYGEN_FAILED; 983 } 984 985 PK11_PQG_DestroyVerify(pqgVerify); 986 987 if (rv != KMF_OK) { 988 SET_ERROR(kmfh, PORT_GetError()); 989 goto cleanup; 990 } 991 992 nssparams = pqgParams; 993 } else { 994 rv = KMF_ERR_BAD_PARAMETER; 995 goto cleanup; 996 } 997 998 NSSprivkey = PK11_GenerateKeyPair(nss_slot, 999 mechanism, nssparams, &NSSpubkey, 1000 PR_TRUE, /* isPermanent */ 1001 PR_TRUE, /* isSensitive */ 1002 (void *)params->cred.cred); 1003 1004 if (NSSprivkey == NULL || NSSpubkey == NULL) { 1005 SET_ERROR(kmfh, PORT_GetError()); 1006 rv = KMF_ERR_KEYGEN_FAILED; 1007 } else { 1008 if (params->keylabel != NULL && 1009 strlen(params->keylabel)) { 1010 (void) PK11_SetPrivateKeyNickname(NSSprivkey, 1011 params->keylabel); 1012 (void) PK11_SetPublicKeyNickname(NSSpubkey, 1013 params->keylabel); 1014 } 1015 /* Now, convert it to a KMF_KEY object for the framework */ 1016 if (privkey != NULL) { 1017 privkey->kstype = KMF_KEYSTORE_NSS; 1018 privkey->keyalg = params->keytype; 1019 privkey->keyclass = KMF_ASYM_PRI; 1020 privkey->keylabel = 1021 PK11_GetPrivateKeyNickname(NSSprivkey); 1022 privkey->keyp = (void *)NSSprivkey; 1023 } 1024 if (pubkey != NULL) { 1025 pubkey->kstype = KMF_KEYSTORE_NSS; 1026 pubkey->keyalg = params->keytype; 1027 pubkey->keyp = (void *)NSSpubkey; 1028 pubkey->keyclass = KMF_ASYM_PUB; 1029 pubkey->keylabel = 1030 PK11_GetPublicKeyNickname(NSSpubkey); 1031 } 1032 rv = KMF_OK; 1033 } 1034 cleanup: 1035 if (rv != KMF_OK) { 1036 if (NSSpubkey) 1037 PK11_DeleteTokenPublicKey(NSSpubkey); 1038 if (NSSprivkey) 1039 PK11_DeleteTokenPrivateKey(NSSprivkey, PR_TRUE); 1040 1041 privkey->keyp = NULL; 1042 pubkey->keyp = NULL; 1043 } 1044 1045 if (pqgParams != NULL) 1046 PK11_PQG_DestroyParams(pqgParams); 1047 1048 1049 if (nss_slot != NULL) 1050 PK11_FreeSlot(nss_slot); 1051 1052 return (rv); 1053 } 1054 1055 KMF_RETURN 1056 NSS_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 1057 KMF_OID *AlgOID, KMF_DATA *tobesigned, 1058 KMF_DATA *output) 1059 { 1060 KMF_RETURN ret = KMF_OK; 1061 KMF_ALGORITHM_INDEX AlgId; 1062 SECOidTag signAlgTag; 1063 SECKEYPrivateKey *NSSprivkey = NULL; 1064 SECStatus rv; 1065 SECItem signed_data; 1066 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1067 1068 signed_data.data = 0; 1069 if (key == NULL || AlgOID == NULL || 1070 tobesigned == NULL || output == NULL || 1071 tobesigned->Data == NULL || 1072 output->Data == NULL) 1073 return (KMF_ERR_BAD_PARAMETER); 1074 1075 /* Map the OID to a NSS algorithm */ 1076 AlgId = X509_AlgorithmOidToAlgId(AlgOID); 1077 if (AlgId == KMF_ALGID_NONE) 1078 return (KMF_ERR_BAD_PARAMETER); 1079 1080 NSSprivkey = (SECKEYPrivateKey *)key->keyp; 1081 1082 if (AlgId == KMF_ALGID_MD5WithRSA) 1083 signAlgTag = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION; 1084 else if (AlgId == KMF_ALGID_MD2WithRSA) 1085 signAlgTag = SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION; 1086 else if (AlgId == KMF_ALGID_SHA1WithRSA) 1087 signAlgTag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; 1088 else if (AlgId == KMF_ALGID_SHA1WithDSA) 1089 signAlgTag = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; 1090 else 1091 return (KMF_ERR_BAD_PARAMETER); 1092 1093 rv = SEC_SignData(&signed_data, tobesigned->Data, 1094 tobesigned->Length, NSSprivkey, signAlgTag); 1095 1096 if (rv != 0) { 1097 SET_ERROR(kmfh, rv); 1098 return (KMF_ERR_INTERNAL); 1099 } 1100 1101 if (signed_data.len <= output->Length) { 1102 (void) memcpy(output->Data, signed_data.data, signed_data.len); 1103 output->Length = signed_data.len; 1104 } else { 1105 output->Length = 0; 1106 ret = KMF_ERR_BAD_PARAMETER; 1107 } 1108 free(signed_data.data); 1109 1110 return (ret); 1111 } 1112 1113 KMF_RETURN 1114 NSS_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp, 1115 KMF_DATA *encoded) 1116 { 1117 KMF_RETURN ret = KMF_OK; 1118 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1119 SECItem *rvitem; 1120 CERTSubjectPublicKeyInfo *spki = NULL; 1121 1122 if (keyp == NULL || encoded == NULL || keyp->keyp == NULL) 1123 return (KMF_ERR_BAD_PARAMETER); 1124 1125 spki = SECKEY_CreateSubjectPublicKeyInfo(keyp->keyp); 1126 if (spki == NULL) { 1127 SET_ERROR(kmfh, PORT_GetError()); 1128 return (KMF_ERR_MEMORY); 1129 } 1130 1131 rvitem = SEC_ASN1EncodeItem(NULL, NULL, spki, 1132 CERT_SubjectPublicKeyInfoTemplate); 1133 1134 if (rvitem != NULL) { 1135 encoded->Data = malloc(rvitem->len); 1136 if (encoded->Data == NULL) { 1137 ret = KMF_ERR_MEMORY; 1138 } else { 1139 (void) memcpy(encoded->Data, rvitem->data, rvitem->len); 1140 encoded->Length = rvitem->len; 1141 } 1142 SECITEM_FreeItem(rvitem, TRUE); 1143 } else { 1144 SET_ERROR(kmfh, PORT_GetError()); 1145 encoded->Data = NULL; 1146 encoded->Length = 0; 1147 ret = KMF_ERR_ENCODING; 1148 } 1149 SECKEY_DestroySubjectPublicKeyInfo(spki); 1150 1151 return (ret); 1152 } 1153 1154 KMF_RETURN 1155 NSS_DeleteKey(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params, 1156 KMF_KEY_HANDLE *key, boolean_t delete_token) 1157 { 1158 KMF_RETURN rv = KMF_OK; 1159 PK11SlotInfo *nss_slot = NULL; 1160 1161 /* 1162 * "delete_token" means to clear it from the token storage as well 1163 * as from memory. 1164 */ 1165 if (key == NULL || key->keyp == NULL) 1166 return (KMF_ERR_BAD_PARAMETER); 1167 1168 if (delete_token) { 1169 SECStatus nssrv = SECSuccess; 1170 if (key->keyclass != KMF_ASYM_PUB && 1171 key->keyclass != KMF_ASYM_PRI && 1172 key->keyclass != KMF_SYMMETRIC) 1173 return (KMF_ERR_BAD_KEY_CLASS); 1174 1175 if (params == NULL) 1176 return (KMF_ERR_BAD_PARAMETER); 1177 rv = Do_NSS_Init(handle, 1178 params->ks_opt_u.nss_opts, FALSE, &nss_slot); 1179 if (rv != KMF_OK) { 1180 return (rv); 1181 } 1182 rv = nss_authenticate(handle, nss_slot, ¶ms->cred); 1183 if (rv != KMF_OK) { 1184 return (rv); 1185 } 1186 1187 if (key->keyclass == KMF_ASYM_PUB) { 1188 nssrv = PK11_DeleteTokenPublicKey( 1189 (SECKEYPublicKey *)key->keyp); 1190 } else if (key->keyclass == KMF_ASYM_PRI) { 1191 nssrv = PK11_DeleteTokenPrivateKey( 1192 (SECKEYPrivateKey *)key->keyp, PR_TRUE); 1193 } else if (key->keyclass == KMF_SYMMETRIC) { 1194 nssrv = PK11_DeleteTokenSymKey( 1195 (PK11SymKey *) key->keyp); 1196 if (nssrv == SECSuccess) 1197 PK11_FreeSymKey( 1198 (PK11SymKey *) key->keyp); 1199 } 1200 if (nssrv != SECSuccess) { 1201 SET_ERROR(handle, PORT_GetError()); 1202 rv = KMF_ERR_INTERNAL; 1203 } 1204 } else { 1205 if (key->keyclass == KMF_ASYM_PUB) { 1206 SECKEY_DestroyPublicKey((SECKEYPublicKey *)key->keyp); 1207 } else if (key->keyclass == KMF_ASYM_PRI) { 1208 SECKEY_DestroyPrivateKey((SECKEYPrivateKey *)key->keyp); 1209 } else if (key->keyclass == KMF_SYMMETRIC) { 1210 PK11_FreeSymKey((PK11SymKey *) key->keyp); 1211 } else { 1212 return (KMF_ERR_BAD_KEY_CLASS); 1213 } 1214 } 1215 key->keyp = NULL; 1216 1217 return (rv); 1218 } 1219 1220 KMF_RETURN 1221 NSS_ImportCRL(KMF_HANDLE_T handle, KMF_IMPORTCRL_PARAMS *params) 1222 { 1223 KMF_RETURN ret = KMF_OK; 1224 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1225 PK11SlotInfo *nss_slot = NULL; 1226 CERTSignedCrl *nss_crl = NULL; 1227 KMF_ENCODE_FORMAT format; 1228 int importOptions; 1229 SECItem crlDER; 1230 KMF_DATA crl1; 1231 KMF_DATA crl2; 1232 1233 if (params == NULL || params->ks_opt_u.nss_opts.crlfile == NULL) { 1234 return (KMF_ERR_BAD_PARAMETER); 1235 } 1236 1237 /* 1238 * Check if the input CRL file is a valid CRL file and auto-detect 1239 * the encoded format of the file. 1240 */ 1241 ret = KMF_IsCRLFile(handle, params->ks_opt_u.nss_opts.crlfile, 1242 &format); 1243 if (ret != KMF_OK) 1244 return (ret); 1245 1246 ret = Do_NSS_Init(handle, 1247 params->ks_opt_u.nss_opts, TRUE, &nss_slot); 1248 if (ret != KMF_OK) { 1249 return (ret); 1250 } 1251 1252 /* set importOptions */ 1253 if (params->ks_opt_u.nss_opts.crl_check == B_FALSE) { 1254 importOptions = CRL_IMPORT_DEFAULT_OPTIONS | 1255 CRL_IMPORT_BYPASS_CHECKS; 1256 } else { 1257 importOptions = CRL_IMPORT_DEFAULT_OPTIONS; 1258 } 1259 1260 1261 /* Read in the CRL file */ 1262 crl1.Data = NULL; 1263 crl2.Data = NULL; 1264 ret = KMF_ReadInputFile(handle, params->ks_opt_u.nss_opts.crlfile, 1265 &crl1); 1266 if (ret != KMF_OK) { 1267 return (ret); 1268 } 1269 1270 /* If the input CRL is in PEM format, convert it to DER first. */ 1271 if (format == KMF_FORMAT_PEM) { 1272 int len; 1273 ret = KMF_Pem2Der(crl1.Data, crl1.Length, 1274 &crl2.Data, &len); 1275 if (ret != KMF_OK) { 1276 goto out; 1277 } 1278 crl2.Length = (size_t)len; 1279 } 1280 1281 crlDER.data = format == KMF_FORMAT_ASN1 ? crl1.Data : crl2.Data; 1282 crlDER.len = format == KMF_FORMAT_ASN1 ? crl1.Length : crl2.Length; 1283 1284 nss_crl = PK11_ImportCRL(nss_slot, &crlDER, NULL, SEC_CRL_TYPE, 1285 NULL, importOptions, NULL, CRL_DECODE_DEFAULT_OPTIONS); 1286 1287 if (nss_crl == NULL) { 1288 SET_ERROR(kmfh, PORT_GetError()); 1289 ret = KMF_ERR_BAD_CRLFILE; 1290 goto out; 1291 } 1292 1293 out: 1294 if (nss_slot != NULL) { 1295 PK11_FreeSlot(nss_slot); 1296 } 1297 1298 if (crl1.Data != NULL) { 1299 free(crl1.Data); 1300 } 1301 1302 if (crl2.Data != NULL) { 1303 free(crl2.Data); 1304 } 1305 1306 if (nss_crl != NULL) { 1307 SEC_DestroyCrl(nss_crl); 1308 } 1309 1310 return (ret); 1311 } 1312 1313 KMF_RETURN 1314 NSS_DeleteCRL(KMF_HANDLE_T handle, KMF_DELETECRL_PARAMS *params) 1315 { 1316 KMF_RETURN rv = KMF_OK; 1317 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1318 CERTSignedCrl *crl = NULL; 1319 CERTCertificate *cert = NULL; 1320 PK11SlotInfo *nss_slot = NULL; 1321 CERTCrlHeadNode *crlList = NULL; 1322 CERTCrlNode *crlNode = NULL; 1323 PRArenaPool *arena = NULL; 1324 CERTName *name = NULL; 1325 CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); 1326 1327 /* check params */ 1328 if (params == NULL || 1329 (params->ks_opt_u.nss_opts.crl_issuerName == NULL && 1330 params->ks_opt_u.nss_opts.crl_subjName == NULL) || 1331 (params->ks_opt_u.nss_opts.crl_issuerName != NULL && 1332 params->ks_opt_u.nss_opts.crl_subjName != NULL)) { 1333 return (KMF_ERR_BAD_PARAMETER); 1334 } 1335 1336 rv = Do_NSS_Init(handle, 1337 params->ks_opt_u.nss_opts, TRUE, 1338 &nss_slot); 1339 if (rv != KMF_OK) { 1340 return (rv); 1341 } 1342 1343 /* Find the CRL based on the deletion criteria. */ 1344 if (params->ks_opt_u.nss_opts.crl_issuerName != NULL) { 1345 /* 1346 * If the deletion is based on the issuer's certificate 1347 * nickname, we will get the issuer's cert first, then 1348 * get the CRL from the cert. 1349 */ 1350 cert = CERT_FindCertByNicknameOrEmailAddr(certHandle, 1351 params->ks_opt_u.nss_opts.crl_issuerName); 1352 if (!cert) { 1353 SET_ERROR(kmfh, PORT_GetError()); 1354 rv = KMF_ERR_CERT_NOT_FOUND; 1355 goto out; 1356 } 1357 1358 crl = SEC_FindCrlByName(certHandle, &cert->derSubject, 1359 SEC_CRL_TYPE); 1360 if (crl == NULL) { 1361 SET_ERROR(kmfh, PORT_GetError()); 1362 rv = KMF_ERR_CRL_NOT_FOUND; 1363 goto out; 1364 } 1365 } else { 1366 /* 1367 * If the deletion is based on the CRL's subject name, we will 1368 * get all the CRLs from the internal database and search 1369 * for the CRL with the same subject name. 1370 */ 1371 boolean_t found = B_FALSE; 1372 int nssrv; 1373 1374 nssrv = SEC_LookupCrls(certHandle, &crlList, SEC_CRL_TYPE); 1375 if (nssrv) { 1376 SET_ERROR(kmfh, nssrv); 1377 rv = KMF_ERR_CRL_NOT_FOUND; 1378 goto out; 1379 } 1380 1381 if (crlList == NULL) { 1382 SET_ERROR(kmfh, PORT_GetError()); 1383 rv = KMF_ERR_CRL_NOT_FOUND; 1384 goto out; 1385 } 1386 1387 /* Allocate space for name */ 1388 arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); 1389 if (arena == NULL) { 1390 rv = KMF_ERR_MEMORY; 1391 goto out; 1392 } 1393 1394 name = PORT_ArenaZAlloc(arena, sizeof (*name)); 1395 if (name == NULL) { 1396 rv = KMF_ERR_MEMORY; 1397 goto out; 1398 } 1399 name->arena = arena; 1400 1401 crlNode = crlList->first; 1402 while (crlNode && !found) { 1403 char *asciiname = NULL; 1404 SECItem* issuer; 1405 1406 name = &crlNode->crl->crl.name; 1407 if (!name) { 1408 SET_ERROR(kmfh, PORT_GetError()); 1409 rv = KMF_ERR_CRL_NOT_FOUND; 1410 break; 1411 } 1412 1413 asciiname = CERT_NameToAscii(name); 1414 if (asciiname == NULL) { 1415 SET_ERROR(kmfh, PORT_GetError()); 1416 rv = KMF_ERR_CRL_NOT_FOUND; 1417 break; 1418 } 1419 1420 if (strcmp(params->ks_opt_u.nss_opts.crl_subjName, 1421 asciiname) == 0) { 1422 found = B_TRUE; 1423 issuer = &crlNode->crl->crl.derName; 1424 crl = SEC_FindCrlByName(certHandle, issuer, 1425 SEC_CRL_TYPE); 1426 if (crl == NULL) { 1427 /* We found a cert but no CRL */ 1428 SET_ERROR(kmfh, PORT_GetError()); 1429 rv = KMF_ERR_CRL_NOT_FOUND; 1430 } 1431 } 1432 PORT_Free(asciiname); 1433 crlNode = crlNode->next; 1434 } 1435 1436 if (rv) { 1437 goto out; 1438 } 1439 } 1440 1441 if (crl) { 1442 (void) SEC_DeletePermCRL(crl); 1443 } 1444 1445 out: 1446 if (nss_slot != NULL) { 1447 PK11_FreeSlot(nss_slot); 1448 } 1449 1450 if (crlList != NULL) { 1451 PORT_FreeArena(crlList->arena, PR_FALSE); 1452 } 1453 1454 if (arena != NULL) { 1455 PORT_FreeArena(arena, PR_FALSE); 1456 } 1457 1458 if (cert != NULL) { 1459 CERT_DestroyCertificate(cert); 1460 } 1461 1462 if (crl != NULL) { 1463 SEC_DestroyCrl(crl); 1464 } 1465 1466 return (rv); 1467 } 1468 1469 1470 KMF_RETURN 1471 NSS_FindCRL(KMF_HANDLE_T handle, KMF_FINDCRL_PARAMS *params, 1472 char **CRLNameList, int *CRLCount) 1473 { 1474 KMF_RETURN rv = KMF_OK; 1475 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1476 PK11SlotInfo *nss_slot = NULL; 1477 CERTCrlHeadNode *crlList = NULL; 1478 CERTCrlNode *crlNode = NULL; 1479 PRArenaPool *arena = NULL; 1480 CERTName *name = NULL; 1481 SECStatus nssrv; 1482 char *asciiname = NULL; 1483 int crl_num; 1484 int i; 1485 CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); 1486 1487 if (CRLCount == NULL || params == NULL) { 1488 return (KMF_ERR_BAD_PARAMETER); 1489 } 1490 1491 *CRLCount = 0; 1492 1493 rv = Do_NSS_Init(handle, 1494 params->ks_opt_u.nss_opts, TRUE, &nss_slot); 1495 if (rv != KMF_OK) { 1496 return (rv); 1497 } 1498 1499 /* Look up Crls */ 1500 nssrv = SEC_LookupCrls(certHandle, &crlList, SEC_CRL_TYPE); 1501 if (nssrv) { 1502 SET_ERROR(kmfh, rv); 1503 rv = KMF_ERR_CRL_NOT_FOUND; 1504 goto out; 1505 } 1506 1507 /* Allocate space for name first */ 1508 arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); 1509 if (arena == NULL) { 1510 rv = KMF_ERR_MEMORY; 1511 goto out; 1512 } 1513 1514 name = PORT_ArenaZAlloc(arena, sizeof (*name)); 1515 if (name == NULL) { 1516 rv = KMF_ERR_MEMORY; 1517 goto out; 1518 } 1519 name->arena = arena; 1520 1521 /* 1522 * Loop thru the crlList and create a crl list with CRL's subject name. 1523 */ 1524 crlNode = crlList->first; 1525 crl_num = 0; 1526 while (crlNode) { 1527 char *subj_name; 1528 1529 /* Get the CRL subject name */ 1530 name = &crlNode->crl->crl.name; 1531 if (!name) { 1532 SET_ERROR(kmfh, PORT_GetError()); 1533 rv = KMF_ERR_CRL_NOT_FOUND; 1534 break; 1535 } 1536 1537 1538 if (CRLNameList != NULL) { 1539 asciiname = CERT_NameToAscii(name); 1540 if (asciiname == NULL) { 1541 SET_ERROR(kmfh, PORT_GetError()); 1542 rv = KMF_ERR_CRL_NOT_FOUND; 1543 break; 1544 } 1545 subj_name = strdup(asciiname); 1546 PORT_Free(asciiname); 1547 if (subj_name == NULL) { 1548 rv = KMF_ERR_MEMORY; 1549 break; 1550 } 1551 CRLNameList[crl_num] = subj_name; 1552 } 1553 1554 crl_num++; 1555 crlNode = crlNode->next; 1556 } 1557 1558 if (rv == KMF_OK) { 1559 /* success */ 1560 *CRLCount = crl_num; 1561 } 1562 1563 out: 1564 if (nss_slot != NULL) { 1565 PK11_FreeSlot(nss_slot); 1566 } 1567 1568 if (crlList != NULL) { 1569 PORT_FreeArena(crlList->arena, PR_FALSE); 1570 } 1571 1572 if (arena != NULL) { 1573 PORT_FreeArena(arena, PR_FALSE); 1574 } 1575 1576 /* If failed, free memory allocated for the returning rlist */ 1577 if (rv && (CRLNameList != NULL)) { 1578 for (i = 0; i < crl_num; i++) { 1579 free(CRLNameList[i]); 1580 } 1581 } 1582 1583 return (rv); 1584 } 1585 1586 1587 KMF_RETURN 1588 NSS_FindCertInCRL(KMF_HANDLE_T handle, KMF_FINDCERTINCRL_PARAMS *params) 1589 { 1590 KMF_RETURN rv = KMF_OK; 1591 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1592 PK11SlotInfo *nss_slot = NULL; 1593 CERTCertificate *cert = NULL; 1594 CERTSignedCrl *crl = NULL; 1595 CERTCrlEntry *entry; 1596 boolean_t match = B_FALSE; 1597 int i; 1598 CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB(); 1599 1600 /* check params */ 1601 if (params == NULL || 1602 (params->ks_opt_u.nss_opts.certLabel == NULL && 1603 params->ks_opt_u.nss_opts.certificate == NULL)) { 1604 return (KMF_ERR_BAD_PARAMETER); 1605 } 1606 1607 rv = Do_NSS_Init(handle, 1608 params->ks_opt_u.nss_opts, TRUE, &nss_slot); 1609 if (rv != KMF_OK) { 1610 return (rv); 1611 } 1612 1613 /* Find the certificate first */ 1614 if (params->ks_opt_u.nss_opts.certLabel != NULL) { 1615 cert = CERT_FindCertByNicknameOrEmailAddr(certHandle, 1616 params->ks_opt_u.nss_opts.certLabel); 1617 } else { 1618 SECItem derCert = { NULL, 0}; 1619 1620 derCert.data = params->ks_opt_u.nss_opts.certificate->Data; 1621 derCert.len = params->ks_opt_u.nss_opts.certificate->Length; 1622 cert = CERT_FindCertByDERCert(certHandle, &derCert); 1623 } 1624 1625 if (!cert) { 1626 SET_ERROR(kmfh, PORT_GetError()); 1627 rv = KMF_ERR_CERT_NOT_FOUND; 1628 goto out; 1629 } 1630 1631 /* Find the CRL with the same issuer as the given certificate. */ 1632 crl = SEC_FindCrlByName(certHandle, &cert->derIssuer, SEC_CRL_TYPE); 1633 if (crl == NULL) { 1634 /* 1635 * Could not find the CRL issued by the same issuer. This 1636 * usually means that the CRL is not installed in the DB. 1637 */ 1638 SET_ERROR(kmfh, PORT_GetError()); 1639 rv = KMF_ERR_CRL_NOT_FOUND; 1640 goto out; 1641 1642 } 1643 1644 /* Check if the certificate's serialNumber is revoked in the CRL */ 1645 i = 0; 1646 while ((entry = (crl->crl).entries[i++]) != NULL) { 1647 if (SECITEM_CompareItem(&(cert->serialNumber), 1648 &(entry->serialNumber)) == SECEqual) { 1649 match = B_TRUE; 1650 break; 1651 } 1652 } 1653 1654 if (!match) { 1655 rv = KMF_ERR_NOT_REVOKED; 1656 } 1657 1658 out: 1659 if (nss_slot != NULL) { 1660 PK11_FreeSlot(nss_slot); 1661 } 1662 1663 if (cert != NULL) { 1664 CERT_DestroyCertificate(cert); 1665 } 1666 1667 if (crl != NULL) { 1668 SEC_DestroyCrl(crl); 1669 } 1670 1671 return (rv); 1672 } 1673 1674 KMF_RETURN 1675 NSS_GetErrorString(KMF_HANDLE_T handle, char **msgstr) 1676 { 1677 KMF_RETURN ret = KMF_OK; 1678 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1679 char *str; 1680 1681 /* Get the error string in the default language */ 1682 str = (char *)PR_ErrorToName((PRErrorCode)kmfh->lasterr.errcode); 1683 1684 if (str != NULL) { 1685 *msgstr = (char *)strdup(str); 1686 if ((*msgstr) == NULL) 1687 ret = KMF_ERR_MEMORY; 1688 } else { 1689 *msgstr = NULL; 1690 } 1691 1692 return (ret); 1693 } 1694 1695 KMF_RETURN 1696 NSS_GetPrikeyByCert(KMF_HANDLE_T handle, KMF_CRYPTOWITHCERT_PARAMS *params, 1697 KMF_DATA *SignerCertData, KMF_KEY_HANDLE *key, 1698 KMF_KEY_ALG keytype) 1699 { 1700 CERTCertificate *nss_cert = NULL; 1701 SECKEYPrivateKey* privkey = NULL; 1702 PK11SlotInfo *nss_slot = NULL; 1703 KMF_RETURN rv = KMF_OK; 1704 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1705 1706 rv = Do_NSS_Init(handle, 1707 params->nssparms, FALSE, &nss_slot); 1708 if (rv != KMF_OK) { 1709 return (rv); 1710 } 1711 1712 rv = nss_authenticate(handle, nss_slot, ¶ms->cred); 1713 if (rv != KMF_OK) { 1714 return (rv); 1715 } 1716 1717 nss_cert = CERT_DecodeCertFromPackage((char *)SignerCertData->Data, 1718 SignerCertData->Length); 1719 1720 if (nss_cert == NULL) { 1721 SET_ERROR(kmfh, PORT_GetError()); 1722 return (KMF_ERR_BAD_CERT_FORMAT); 1723 } 1724 1725 privkey = PK11_FindPrivateKeyFromCert(nss_slot, nss_cert, NULL); 1726 if (privkey == NULL) { 1727 SET_ERROR(kmfh, PORT_GetError()); 1728 return (KMF_ERR_KEY_NOT_FOUND); 1729 } 1730 1731 key->kstype = KMF_KEYSTORE_NSS; 1732 key->keyclass = KMF_ASYM_PRI; 1733 key->keyalg = keytype; 1734 key->keyp = (void *)privkey; 1735 key->keylabel = PK11_GetPrivateKeyNickname(privkey); 1736 1737 CERT_DestroyCertificate(nss_cert); 1738 1739 return (KMF_OK); 1740 1741 } 1742 1743 KMF_RETURN 1744 NSS_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 1745 KMF_OID *AlgOID, KMF_DATA *ciphertext, 1746 KMF_DATA *output) 1747 { 1748 KMF_RETURN ret = KMF_OK; 1749 SECKEYPrivateKey *NSSprivkey = NULL; 1750 SECStatus rv; 1751 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1752 unsigned int in_len = 0, out_len = 0; 1753 unsigned int total_decrypted = 0, modulus_len = 0; 1754 uint8_t *in_data, *out_data; 1755 int i, blocks; 1756 1757 1758 if (key == NULL || AlgOID == NULL || 1759 ciphertext == NULL || output == NULL || 1760 ciphertext->Data == NULL || 1761 output->Data == NULL) 1762 return (KMF_ERR_BAD_PARAMETER); 1763 1764 NSSprivkey = (SECKEYPrivateKey *)key->keyp; 1765 modulus_len = PK11_GetPrivateModulusLen(NSSprivkey); 1766 1767 blocks = ciphertext->Length/modulus_len; 1768 out_data = output->Data; 1769 in_data = ciphertext->Data; 1770 out_len = modulus_len - 11; 1771 in_len = modulus_len; 1772 1773 for (i = 0; i < blocks; i++) { 1774 rv = PK11_PrivDecryptPKCS1(NSSprivkey, out_data, 1775 &out_len, ciphertext->Length, in_data, in_len); 1776 1777 if (rv != 0) { 1778 SET_ERROR(kmfh, rv); 1779 return (KMF_ERR_INTERNAL); 1780 } 1781 1782 out_data += out_len; 1783 total_decrypted += out_len; 1784 in_data += in_len; 1785 } 1786 1787 output->Length = total_decrypted; 1788 1789 return (ret); 1790 } 1791 1792 static KMF_KEY_ALG 1793 pk11keytype2kmf(CK_KEY_TYPE type) 1794 { 1795 switch (type) { 1796 case CKK_RSA: 1797 return (KMF_RSA); 1798 case CKK_DSA: 1799 return (KMF_RSA); 1800 case CKK_AES: 1801 return (KMF_AES); 1802 case CKK_RC4: 1803 return (KMF_RC4); 1804 case CKK_DES: 1805 return (KMF_DES); 1806 case CKK_DES3: 1807 return (KMF_DES3); 1808 default: 1809 /* not supported */ 1810 return (KMF_KEYALG_NONE); 1811 } 1812 } 1813 1814 KMF_RETURN 1815 NSS_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, 1816 KMF_KEY_HANDLE *keys, uint32_t *numkeys) 1817 { 1818 KMF_RETURN rv; 1819 SECKEYPrivateKeyList *prilist; 1820 SECKEYPrivateKeyListNode *prinode; 1821 SECKEYPublicKeyList *publist; 1822 SECKEYPublicKeyListNode *pubnode; 1823 PK11SlotInfo *nss_slot = NULL; 1824 PK11SymKey *symlist = NULL; 1825 int count; 1826 uint32_t maxkeys; 1827 1828 rv = Do_NSS_Init(handle, 1829 parms->ks_opt_u.nss_opts, FALSE, &nss_slot); 1830 if (rv != KMF_OK) { 1831 return (rv); 1832 } 1833 1834 rv = nss_authenticate(handle, nss_slot, &parms->cred); 1835 if (rv != KMF_OK) { 1836 return (rv); 1837 } 1838 1839 maxkeys = *numkeys; 1840 if (maxkeys == 0) 1841 maxkeys = 0xFFFFFFFF; 1842 1843 *numkeys = 0; 1844 if (parms->keyclass == KMF_ASYM_PUB) { 1845 publist = PK11_ListPublicKeysInSlot(nss_slot, parms->findLabel); 1846 if (publist == NULL) { 1847 rv = KMF_ERR_KEY_NOT_FOUND; 1848 goto cleanup; 1849 } 1850 } else if (parms->keyclass == KMF_ASYM_PRI) { 1851 prilist = PK11_ListPrivKeysInSlot(nss_slot, 1852 parms->findLabel, NULL); 1853 if (prilist == NULL) { 1854 rv = KMF_ERR_KEY_NOT_FOUND; 1855 goto cleanup; 1856 } 1857 } else if (parms->keyclass == KMF_SYMMETRIC) { 1858 symlist = PK11_ListFixedKeysInSlot(nss_slot, parms->findLabel, 1859 NULL); 1860 if (symlist == NULL) { 1861 rv = KMF_ERR_KEY_NOT_FOUND; 1862 goto cleanup; 1863 } 1864 } else { 1865 rv = KMF_ERR_BAD_KEY_CLASS; 1866 goto cleanup; 1867 } 1868 1869 if (parms->keyclass == KMF_ASYM_PUB) { 1870 for (count = 0, pubnode = PUBKEY_LIST_HEAD(publist); 1871 !PUBKEY_LIST_END(pubnode, publist) && 1872 count < maxkeys; 1873 pubnode = PUBKEY_LIST_NEXT(pubnode), count++) { 1874 if (keys != NULL) { 1875 keys[count].kstype = KMF_KEYSTORE_NSS; 1876 keys[count].keyclass = KMF_ASYM_PUB; 1877 keys[count].keyp = (void *)pubnode->key; 1878 keys[count].keylabel = 1879 PK11_GetPublicKeyNickname( 1880 pubnode->key); 1881 1882 if (pubnode->key->keyType == rsaKey) 1883 keys[count].keyalg = KMF_RSA; 1884 else if (pubnode->key->keyType == dsaKey) 1885 keys[count].keyalg = KMF_DSA; 1886 } 1887 } 1888 *numkeys = count; 1889 } else if (parms->keyclass == KMF_ASYM_PRI) { 1890 for (count = 0, prinode = PRIVKEY_LIST_HEAD(prilist); 1891 !PRIVKEY_LIST_END(prinode, prilist) && 1892 count < maxkeys; 1893 prinode = PRIVKEY_LIST_NEXT(prinode), count++) { 1894 if (keys != NULL) { 1895 keys[count].kstype = KMF_KEYSTORE_NSS; 1896 keys[count].keyclass = KMF_ASYM_PRI; 1897 keys[count].keyp = (void *)prinode->key; 1898 keys[count].keylabel = 1899 PK11_GetPrivateKeyNickname( 1900 prinode->key); 1901 1902 if (prinode->key->keyType == rsaKey) 1903 keys[count].keyalg = KMF_RSA; 1904 else if (prinode->key->keyType == dsaKey) 1905 keys[count].keyalg = KMF_DSA; 1906 } 1907 } 1908 *numkeys = count; 1909 } else if (parms->keyclass == KMF_SYMMETRIC) { 1910 count = 0; 1911 while (symlist && count < maxkeys) { 1912 PK11SymKey *symkey = symlist; 1913 CK_KEY_TYPE type; 1914 KMF_KEY_ALG keyalg; 1915 1916 type = PK11_GetSymKeyType(symkey); 1917 keyalg = pk11keytype2kmf(type); 1918 1919 /* 1920 * If keytype is specified in the searching parameter, 1921 * check the keytype and skip the key if its keytype 1922 * doesn't match. 1923 */ 1924 symlist = PK11_GetNextSymKey(symkey); 1925 if (parms->keytype != KMF_KEYALG_NONE && 1926 parms->keytype != keyalg) { 1927 /* free that key since we aren't using it */ 1928 PK11_FreeSymKey(symkey); 1929 continue; 1930 } 1931 1932 if (keys != NULL) { 1933 keys[count].kstype = KMF_KEYSTORE_NSS; 1934 keys[count].keyclass = KMF_SYMMETRIC; 1935 keys[count].keyp = (void *) symkey; 1936 keys[count].keylabel = 1937 PK11_GetSymKeyNickname(symkey); 1938 keys[count].keyalg = keyalg; 1939 } else { 1940 PK11_FreeSymKey(symkey); 1941 } 1942 count++; 1943 } 1944 /* 1945 * Cleanup memory for unused keys. 1946 */ 1947 while (symlist != NULL) { 1948 PK11SymKey *symkey = symlist; 1949 PK11_FreeSymKey(symkey); 1950 symlist = PK11_GetNextSymKey(symkey); 1951 } 1952 } 1953 1954 *numkeys = count; 1955 cleanup: 1956 if (nss_slot != NULL) { 1957 PK11_FreeSlot(nss_slot); 1958 } 1959 1960 return (rv); 1961 } 1962 1963 static SECStatus 1964 p12u_SwapUnicodeBytes(SECItem *uniItem) 1965 { 1966 unsigned int i; 1967 unsigned char a; 1968 if ((uniItem == NULL) || (uniItem->len % 2)) { 1969 return (SECFailure); 1970 } 1971 for (i = 0; i < uniItem->len; i += 2) { 1972 a = uniItem->data[i]; 1973 uniItem->data[i] = uniItem->data[i+1]; 1974 uniItem->data[i+1] = a; 1975 } 1976 return (SECSuccess); 1977 } 1978 1979 static PRBool 1980 p12u_ucs2_ascii_conversion_function( 1981 PRBool toUnicode, 1982 unsigned char *inBuf, 1983 unsigned int inBufLen, 1984 unsigned char *outBuf, 1985 unsigned int maxOutBufLen, 1986 unsigned int *outBufLen, 1987 PRBool swapBytes) 1988 { 1989 SECItem it = { 0 }; 1990 SECItem *dup = NULL; 1991 PRBool ret; 1992 1993 it.data = inBuf; 1994 it.len = inBufLen; 1995 dup = SECITEM_DupItem(&it); 1996 /* 1997 * If converting Unicode to ASCII, swap bytes before conversion 1998 * as neccessary. 1999 */ 2000 if (!toUnicode && swapBytes) { 2001 if (p12u_SwapUnicodeBytes(dup) != SECSuccess) { 2002 SECITEM_ZfreeItem(dup, PR_TRUE); 2003 return (PR_FALSE); 2004 } 2005 } 2006 /* Perform the conversion. */ 2007 ret = PORT_UCS2_UTF8Conversion(toUnicode, dup->data, dup->len, 2008 outBuf, maxOutBufLen, outBufLen); 2009 if (dup) 2010 SECITEM_ZfreeItem(dup, PR_TRUE); 2011 2012 return (ret); 2013 } 2014 2015 static PRBool 2016 p12u_OpenFile(p12uContext *p12ctx, PRBool fileRead) 2017 { 2018 if (!p12ctx || !p12ctx->filename) { 2019 return (PR_FALSE); 2020 } 2021 2022 if (fileRead) { 2023 p12ctx->file = PR_Open(p12ctx->filename, 2024 PR_RDONLY, 0400); 2025 } else { 2026 p12ctx->file = PR_Open(p12ctx->filename, 2027 PR_CREATE_FILE | PR_RDWR | PR_TRUNCATE, 0600); 2028 } 2029 2030 if (!p12ctx->file) { 2031 p12ctx->error = PR_TRUE; 2032 return (PR_FALSE); 2033 } 2034 2035 return (PR_TRUE); 2036 } 2037 2038 static void 2039 p12u_DestroyContext(p12uContext **ppCtx, PRBool removeFile) 2040 { 2041 if (!ppCtx || !(*ppCtx)) { 2042 return; 2043 } 2044 2045 if ((*ppCtx)->file != NULL) { 2046 PR_Close((*ppCtx)->file); 2047 } 2048 2049 if ((*ppCtx)->filename != NULL) { 2050 if (removeFile) { 2051 PR_Delete((*ppCtx)->filename); 2052 } 2053 free((*ppCtx)->filename); 2054 } 2055 2056 free(*ppCtx); 2057 *ppCtx = NULL; 2058 } 2059 2060 static p12uContext * 2061 p12u_InitContext(PRBool fileImport, char *filename) 2062 { 2063 p12uContext *p12ctx; 2064 2065 p12ctx = PORT_ZNew(p12uContext); 2066 if (!p12ctx) { 2067 return (NULL); 2068 } 2069 2070 p12ctx->error = PR_FALSE; 2071 p12ctx->errorValue = 0; 2072 p12ctx->filename = strdup(filename); 2073 2074 if (!p12u_OpenFile(p12ctx, fileImport)) { 2075 p12u_DestroyContext(&p12ctx, PR_FALSE); 2076 return (NULL); 2077 } 2078 2079 return (p12ctx); 2080 } 2081 2082 static void 2083 p12u_WriteToExportFile(void *arg, const char *buf, unsigned long len) 2084 { 2085 p12uContext *p12cxt = arg; 2086 int writeLen; 2087 2088 if (!p12cxt || (p12cxt->error == PR_TRUE)) { 2089 return; 2090 } 2091 2092 if (p12cxt->file == NULL) { 2093 p12cxt->errorValue = SEC_ERROR_PKCS12_UNABLE_TO_WRITE; 2094 p12cxt->error = PR_TRUE; 2095 return; 2096 } 2097 2098 writeLen = PR_Write(p12cxt->file, (unsigned char *)buf, (int32)len); 2099 2100 if (writeLen != (int)len) { 2101 PR_Close(p12cxt->file); 2102 free(p12cxt->filename); 2103 p12cxt->filename = NULL; 2104 p12cxt->file = NULL; 2105 p12cxt->errorValue = SEC_ERROR_PKCS12_UNABLE_TO_WRITE; 2106 p12cxt->error = PR_TRUE; 2107 } 2108 } 2109 2110 #define HANDLE_NSS_ERROR(r) {\ 2111 SET_ERROR(kmfh, PORT_GetError()); \ 2112 rv = r; \ 2113 goto out; } 2114 2115 static KMF_RETURN 2116 add_cert_to_bag(SEC_PKCS12ExportContext *p12ecx, 2117 CERTCertificate *cert, SECItem *pwitem) 2118 { 2119 KMF_RETURN rv = KMF_OK; 2120 SEC_PKCS12SafeInfo *keySafe = NULL, *certSafe = NULL; 2121 2122 keySafe = SEC_PKCS12CreateUnencryptedSafe(p12ecx); 2123 if (PK11_IsFIPS()) { 2124 certSafe = keySafe; 2125 } else { 2126 certSafe = SEC_PKCS12CreatePasswordPrivSafe(p12ecx, pwitem, 2127 SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC); 2128 } 2129 2130 if (!certSafe || !keySafe) { 2131 rv = KMF_ERR_INTERNAL; 2132 goto out; 2133 } 2134 2135 if (SEC_PKCS12AddCertAndKey(p12ecx, certSafe, NULL, cert, 2136 CERT_GetDefaultCertDB(), keySafe, NULL, PR_TRUE, pwitem, 2137 SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC) 2138 != SECSuccess) { 2139 rv = KMF_ERR_INTERNAL; 2140 } 2141 out: 2142 return (rv); 2143 } 2144 2145 /*ARGSUSED*/ 2146 KMF_RETURN 2147 NSS_ExportP12(KMF_HANDLE_T handle, 2148 KMF_EXPORTP12_PARAMS *params, 2149 int numcerts, KMF_X509_DER_CERT *certs, 2150 int numkeys, KMF_KEY_HANDLE *keylist, 2151 char *filename) 2152 { 2153 KMF_RETURN rv; 2154 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2155 SEC_PKCS12ExportContext *p12ecx = NULL; 2156 p12uContext *p12ctx = NULL; 2157 CERTCertList *certlist = NULL; 2158 CERTCertificate *nsscert = NULL; 2159 CERTCertListNode* node = NULL; 2160 PK11SlotInfo *slot = NULL; 2161 SECItem pwitem = {NULL, 0}; 2162 2163 rv = Do_NSS_Init(handle, 2164 params->nssparms, FALSE, &slot); 2165 if (rv != KMF_OK) { 2166 return (rv); 2167 } 2168 2169 rv = nss_authenticate(handle, slot, ¶ms->cred); 2170 if (rv != KMF_OK) { 2171 return (rv); 2172 } 2173 2174 /* 2175 * Find the certificate(s) first. 2176 */ 2177 if (params->certLabel) { 2178 nsscert = PK11_FindCertFromNickname(params->certLabel, 2179 NULL); 2180 if (nsscert == NULL) { 2181 HANDLE_NSS_ERROR(KMF_ERR_CERT_NOT_FOUND) 2182 } 2183 } else { 2184 rv = nss_find_matching_certs(slot, 2185 params->issuer, 2186 params->subject, 2187 params->serial, 2188 &certlist, 0); 2189 2190 if (rv == KMF_OK && certlist == NULL) { 2191 return (KMF_ERR_CERT_NOT_FOUND); 2192 } 2193 if (rv != KMF_OK) 2194 return (rv); 2195 } 2196 2197 /* 2198 * The KMF_CREDENTIAL holds the password to use for 2199 * encrypting the PKCS12 key information. 2200 */ 2201 pwitem.data = (uchar_t *)params->p12cred.cred; 2202 pwitem.len = params->p12cred.credlen; 2203 2204 p12ctx = p12u_InitContext(PR_FALSE, filename); 2205 if (!p12ctx) { 2206 HANDLE_NSS_ERROR(KMF_ERR_OPEN_FILE) 2207 } 2208 2209 PORT_SetUCS2_ASCIIConversionFunction( 2210 p12u_ucs2_ascii_conversion_function); 2211 2212 p12ecx = SEC_PKCS12CreateExportContext(NULL, NULL, 2213 slot, NULL); 2214 if (!p12ecx) { 2215 HANDLE_NSS_ERROR(KMF_ERR_OPEN_FILE) 2216 } 2217 2218 if (SEC_PKCS12AddPasswordIntegrity(p12ecx, &pwitem, SEC_OID_SHA1) 2219 != SECSuccess) { 2220 HANDLE_NSS_ERROR(KMF_ERR_INTERNAL) 2221 } 2222 2223 /* 2224 * NSS actually supports storing a list of keys and certs 2225 * in the PKCS#12 PDU. Nice feature. 2226 */ 2227 if (certlist != NULL) { 2228 for (node = CERT_LIST_HEAD(certlist); 2229 !CERT_LIST_END(node, certlist) && rv == KMF_OK; 2230 node = CERT_LIST_NEXT(node)) { 2231 2232 rv = add_cert_to_bag(p12ecx, node->cert, &pwitem); 2233 } 2234 } else if (nsscert != NULL) { 2235 rv = add_cert_to_bag(p12ecx, nsscert, &pwitem); 2236 } 2237 2238 if (SEC_PKCS12Encode(p12ecx, p12u_WriteToExportFile, p12ctx) 2239 != SECSuccess) { 2240 HANDLE_NSS_ERROR(KMF_ERR_ENCODING) 2241 } 2242 out: 2243 if (nsscert) 2244 CERT_DestroyCertificate(nsscert); 2245 2246 if (certlist) 2247 CERT_DestroyCertList(certlist); 2248 2249 if (p12ctx) 2250 p12u_DestroyContext(&p12ctx, PR_FALSE); 2251 2252 if (p12ecx) 2253 SEC_PKCS12DestroyExportContext(p12ecx); 2254 2255 return (rv); 2256 } 2257 2258 #define SETATTR(t, n, atype, value, size) \ 2259 t[n].type = atype; \ 2260 t[n].pValue = (CK_BYTE *)value; \ 2261 t[n].ulValueLen = (CK_ULONG)size; 2262 2263 KMF_RETURN 2264 NSS_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, 2265 KMF_RAW_KEY_DATA *rawkey) 2266 { 2267 KMF_RETURN rv = KMF_OK; 2268 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2269 SECStatus ckrv = SECSuccess; 2270 PK11SlotInfo *slot = NULL; 2271 CERTCertificate *nss_cert = NULL; 2272 SECKEYPrivateKeyInfo rpk; 2273 SECItem nickname; 2274 KMF_DATA derkey = { NULL, 0 }; 2275 uchar_t ver = 0; 2276 2277 if (!kmfh) 2278 return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */ 2279 2280 if (params == NULL || params->certificate == NULL || rawkey == NULL) 2281 return (KMF_ERR_BAD_PARAMETER); 2282 2283 rv = Do_NSS_Init(handle, 2284 params->nssparms, FALSE, &slot); 2285 2286 if (rv != KMF_OK) 2287 return (rv); 2288 2289 rv = nss_authenticate(handle, slot, ¶ms->cred); 2290 if (rv != KMF_OK) { 2291 return (rv); 2292 } 2293 2294 /* 2295 * Decode the cert into an NSS CERT object so we can access the 2296 * SPKI and KeyUsage data later. 2297 */ 2298 nss_cert = CERT_DecodeCertFromPackage((char *)params->certificate->Data, 2299 params->certificate->Length); 2300 2301 if (nss_cert == NULL) { 2302 SET_ERROR(kmfh, PORT_GetError()); 2303 rv = KMF_ERR_BAD_CERT_FORMAT; 2304 goto cleanup; 2305 } 2306 2307 (void) memset(&rpk, 0, sizeof (rpk)); 2308 2309 rpk.arena = NULL; 2310 rpk.version.type = siUnsignedInteger; 2311 rpk.version.data = &ver; 2312 rpk.version.len = 1; 2313 if (rawkey->keytype == KMF_RSA) { 2314 2315 rv = DerEncodeRSAPrivateKey(&derkey, &rawkey->rawdata.rsa); 2316 if (rv != KMF_OK) 2317 goto cleanup; 2318 2319 rpk.algorithm = nss_cert->subjectPublicKeyInfo.algorithm; 2320 rpk.privateKey.data = derkey.Data; 2321 rpk.privateKey.len = derkey.Length; 2322 rpk.attributes = NULL; 2323 2324 2325 } else if (rawkey->keytype == KMF_DSA) { 2326 rv = DerEncodeDSAPrivateKey(&derkey, &rawkey->rawdata.dsa); 2327 if (rv != KMF_OK) 2328 goto cleanup; 2329 2330 rpk.algorithm = nss_cert->subjectPublicKeyInfo.algorithm; 2331 rpk.privateKey.data = derkey.Data; 2332 rpk.privateKey.len = derkey.Length; 2333 rpk.attributes = NULL; 2334 2335 } else { 2336 return (KMF_ERR_BAD_PARAMETER); 2337 } 2338 2339 nickname.data = (uchar_t *)params->label; 2340 nickname.len = (params->label ? strlen(params->label) : 0); 2341 2342 ckrv = PK11_ImportPrivateKeyInfo(slot, &rpk, 2343 &nickname, &nss_cert->subjectPublicKeyInfo.subjectPublicKey, 2344 TRUE, TRUE, nss_cert->keyUsage, NULL); 2345 2346 if (ckrv != CKR_OK) { 2347 SET_ERROR(kmfh, PORT_GetError()); 2348 rv = KMF_ERR_INTERNAL; 2349 } 2350 2351 cleanup: 2352 if (nss_cert != NULL) { 2353 CERT_DestroyCertificate(nss_cert); 2354 } 2355 KMF_FreeData(&derkey); 2356 return (rv); 2357 } 2358 2359 KMF_RETURN 2360 NSS_CreateSymKey(KMF_HANDLE_T handle, 2361 KMF_CREATESYMKEY_PARAMS *params, 2362 KMF_KEY_HANDLE *symkey) 2363 { 2364 KMF_RETURN rv = KMF_OK; 2365 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2366 PK11SlotInfo *nss_slot = NULL; 2367 PK11SymKey *nsskey = NULL; 2368 CK_MECHANISM_TYPE keyType; 2369 SECStatus nssrv; 2370 int keySize; 2371 2372 if (params == NULL || symkey == NULL) { 2373 return (KMF_ERR_BAD_PARAMETER); 2374 } 2375 2376 switch (params->keytype) { 2377 case KMF_AES: 2378 keyType = CKM_AES_KEY_GEN; 2379 keySize = params->keylength; 2380 if (keySize == 0 || (keySize % 8) != 0) 2381 return (KMF_ERR_BAD_KEY_SIZE); 2382 break; 2383 case KMF_RC4: 2384 keyType = CKM_RC4_KEY_GEN; 2385 keySize = params->keylength; 2386 if (keySize == 0 || (keySize % 8) != 0) 2387 return (KMF_ERR_BAD_KEY_SIZE); 2388 break; 2389 case KMF_DES: 2390 keyType = CKM_DES_KEY_GEN; 2391 keySize = 0; /* required by PK11_TokenKeyGen() */ 2392 break; 2393 case KMF_DES3: 2394 keyType = CKM_DES3_KEY_GEN; 2395 keySize = 0; /* required by PK11_TokenKeyGen() */ 2396 break; 2397 case KMF_GENERIC_SECRET: 2398 keyType = CKM_GENERIC_SECRET_KEY_GEN; 2399 keySize = params->keylength; 2400 if (keySize == 0 || (keySize % 8) != 0) 2401 return (KMF_ERR_BAD_KEY_SIZE); 2402 break; 2403 default: 2404 rv = KMF_ERR_BAD_KEY_TYPE; 2405 goto out; 2406 } 2407 2408 rv = Do_NSS_Init(handle, 2409 params->ks_opt_u.nss_opts, FALSE, &nss_slot); 2410 if (rv != KMF_OK) { 2411 return (rv); 2412 } 2413 2414 rv = nss_authenticate(handle, nss_slot, ¶ms->cred); 2415 if (rv != KMF_OK) { 2416 return (rv); 2417 } 2418 2419 nsskey = PK11_TokenKeyGen(nss_slot, keyType, NULL, keySize, NULL, 2420 PR_TRUE, (void *)params->cred.cred); 2421 if (nsskey == NULL) { 2422 SET_ERROR(kmfh, PORT_GetError()); 2423 rv = KMF_ERR_KEYGEN_FAILED; 2424 goto out; 2425 } 2426 2427 nssrv = PK11_SetSymKeyNickname(nsskey, params->keylabel); 2428 if (nssrv != SECSuccess) { 2429 SET_ERROR(kmfh, PORT_GetError()); 2430 rv = KMF_ERR_KEYGEN_FAILED; 2431 goto out; 2432 } 2433 2434 symkey->kstype = KMF_KEYSTORE_NSS; 2435 symkey->keyalg = params->keytype; 2436 symkey->keyclass = KMF_SYMMETRIC; 2437 symkey->israw = FALSE; 2438 symkey->keyp = (void *)nsskey; 2439 2440 out: 2441 if (nss_slot != NULL) 2442 PK11_FreeSlot(nss_slot); 2443 2444 if (rv != KMF_OK && nsskey != NULL) { 2445 PK11_DeleteTokenSymKey(nsskey); 2446 PK11_FreeSymKey(nsskey); 2447 } 2448 return (rv); 2449 } 2450 2451 KMF_RETURN 2452 NSS_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, 2453 KMF_RAW_SYM_KEY *rkey) 2454 { 2455 KMF_RETURN rv = KMF_OK; 2456 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2457 SECItem *value = NULL; 2458 PK11SymKey *nsskey; 2459 SECStatus nss_rv; 2460 2461 if (kmfh == NULL) 2462 return (KMF_ERR_UNINITIALIZED); 2463 2464 if (symkey == NULL || rkey == NULL) 2465 return (KMF_ERR_BAD_PARAMETER); 2466 else if (symkey->keyclass != KMF_SYMMETRIC) 2467 return (KMF_ERR_BAD_KEY_CLASS); 2468 2469 if (symkey->israw) { 2470 KMF_RAW_KEY_DATA *rawkey = (KMF_RAW_KEY_DATA *)symkey->keyp; 2471 2472 if (rawkey == NULL || 2473 rawkey->rawdata.sym.keydata.val == NULL || 2474 rawkey->rawdata.sym.keydata.len == 0) 2475 return (KMF_ERR_BAD_KEYHANDLE); 2476 2477 rkey->keydata.len = rawkey->rawdata.sym.keydata.len; 2478 if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL) 2479 return (KMF_ERR_MEMORY); 2480 (void) memcpy(rkey->keydata.val, 2481 rawkey->rawdata.sym.keydata.val, rkey->keydata.len); 2482 } else { 2483 nsskey = (PK11SymKey *)(symkey->keyp); 2484 if (nsskey == NULL) 2485 return (KMF_ERR_BAD_KEYHANDLE); 2486 2487 nss_rv = PK11_ExtractKeyValue(nsskey); 2488 if (nss_rv != SECSuccess) { 2489 SET_ERROR(kmfh, PORT_GetError()); 2490 rv = KMF_ERR_GETKEYVALUE_FAILED; 2491 goto out; 2492 } 2493 2494 value = PK11_GetKeyData(nsskey); 2495 if (value == NULL) { 2496 SET_ERROR(kmfh, PORT_GetError()); 2497 rv = KMF_ERR_GETKEYVALUE_FAILED; 2498 goto out; 2499 } 2500 2501 if (value->len == 0 || value->data == NULL) { 2502 rv = KMF_ERR_GETKEYVALUE_FAILED; 2503 goto out; 2504 } 2505 2506 rkey->keydata.val = malloc(value->len); 2507 if (rkey->keydata.val == NULL) { 2508 rv = KMF_ERR_MEMORY; 2509 goto out; 2510 } 2511 (void) memcpy(rkey->keydata.val, value->data, value->len); 2512 rkey->keydata.len = value->len; 2513 (void) memset(value->data, 0, value->len); 2514 } 2515 out: 2516 if (value != NULL) 2517 SECITEM_FreeItem(value, PR_TRUE); 2518 return (rv); 2519 } 2520 2521 KMF_RETURN 2522 NSS_SetTokenPin(KMF_HANDLE_T handle, KMF_SETPIN_PARAMS *params, 2523 KMF_CREDENTIAL *newpin) 2524 { 2525 KMF_RETURN ret = KMF_OK; 2526 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2527 int rv; 2528 PK11SlotInfo *nss_slot = NULL; 2529 2530 if (handle == NULL || params == NULL || newpin == NULL) { 2531 return (KMF_ERR_BAD_PARAMETER); 2532 } 2533 2534 ret = Do_NSS_Init(handle, 2535 params->ks_opt_u.nss_opts, 2536 FALSE, &nss_slot); 2537 /* If it was uninitialized, set it */ 2538 if (ret == KMF_ERR_UNINITIALIZED_TOKEN) { 2539 rv = PK11_InitPin(nss_slot, NULL, newpin->cred); 2540 if (rv != SECSuccess) { 2541 SET_ERROR(kmfh, PORT_GetError()); 2542 ret = KMF_ERR_AUTH_FAILED; 2543 } else { 2544 ret = KMF_OK; 2545 } 2546 } else if (ret == KMF_OK) { 2547 ret = nss_authenticate(handle, nss_slot, ¶ms->cred); 2548 if (ret != KMF_OK) { 2549 return (ret); 2550 } 2551 rv = PK11_ChangePW(nss_slot, 2552 params->cred.cred, newpin->cred); 2553 if (rv != SECSuccess) { 2554 SET_ERROR(kmfh, PORT_GetError()); 2555 ret = KMF_ERR_AUTH_FAILED; 2556 } 2557 } 2558 2559 return (ret); 2560 } 2561