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