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