/* * SecCmsSignerInfoIncludeCerts - set cert chain inclusion mode for this signer */ OSStatus SecCmsSignerInfoIncludeCerts(SecCmsSignerInfoRef signerinfo, SecCmsCertChainMode cm, SECCertUsage usage) { if (signerinfo->cert == NULL) return SECFailure; /* don't leak if we get called twice */ if (signerinfo->certList != NULL) { CFRelease(signerinfo->certList); signerinfo->certList = NULL; } switch (cm) { case SecCmsCMNone: signerinfo->certList = NULL; break; case SecCmsCMCertOnly: signerinfo->certList = CERT_CertListFromCert(signerinfo->cert); break; case SecCmsCMCertChain: signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, usage, PR_FALSE); break; case SecCmsCMCertChainWithRoot: signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, usage, PR_TRUE); break; } if (cm != SecCmsCMNone && signerinfo->certList == NULL) return SECFailure; return SECSuccess; }
/* * NSS_CMSSignerInfo_IncludeCerts - set cert chain inclusion mode for this signer */ SECStatus NSS_CMSSignerInfo_IncludeCerts(NSSCMSSignerInfo *signerinfo, NSSCMSCertChainMode cm, SECCertUsage usage) { if (signerinfo->cert == NULL) return SECFailure; /* don't leak if we get called twice */ if (signerinfo->certList != NULL) { CERT_DestroyCertificateList(signerinfo->certList); signerinfo->certList = NULL; } switch (cm) { case NSSCMSCM_None: signerinfo->certList = NULL; break; case NSSCMSCM_CertOnly: signerinfo->certList = CERT_CertListFromCert(signerinfo->cert); break; case NSSCMSCM_CertChain: signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, usage, PR_FALSE); break; case NSSCMSCM_CertChainWithRoot: signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, usage, PR_TRUE); break; } if (cm != NSSCMSCM_None && signerinfo->certList == NULL) return SECFailure; return SECSuccess; }
static SECStatus ssl_PopulateServerCert(sslServerCert *sc, CERTCertificate *cert, const CERTCertificateList *certChain) { if (sc->serverCert) { CERT_DestroyCertificate(sc->serverCert); } if (sc->serverCertChain) { CERT_DestroyCertificateList(sc->serverCertChain); } if (!cert) { sc->serverCert = NULL; sc->serverCertChain = NULL; return SECSuccess; } sc->serverCert = CERT_DupCertificate(cert); if (certChain) { sc->serverCertChain = CERT_DupCertList(certChain); } else { sc->serverCertChain = CERT_CertChainFromCert(sc->serverCert, certUsageSSLServer, PR_TRUE); } return sc->serverCertChain ? SECSuccess : SECFailure; }
void dumpCertChain(CERTCertificate *cert, SECCertUsage usage) { CERTCertificateList *certList; unsigned int count = 0; certList = CERT_CertChainFromCert(cert, usage, PR_TRUE); if (certList == NULL) { errWarn("CERT_CertChainFromCert"); return; } for(count = 0; count < (unsigned int)certList->len; count++) { char certFileName[16]; PRFileDesc *cfd; PR_snprintf(certFileName, sizeof certFileName, "cert.%03d", count); cfd = PR_Open(certFileName, PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE, 0664); if (!cfd) { PR_fprintf(PR_STDOUT, "Error: couldn't save cert der in file '%s'\n", certFileName); } else { PR_Write(cfd, certList->certs[count].data, certList->certs[count].len); PR_Close(cfd); PR_fprintf(PR_STDOUT, "Cert file %s was created.\n", certFileName); } } CERT_DestroyCertificateList(certList); }
/* * SecCmsSignedDataAddCertChain - add cert and its entire chain to the set of certs */ OSStatus SecCmsSignedDataAddCertChain(SecCmsSignedDataRef sigd, SecCertificateRef cert) { CFArrayRef certlist; SECCertUsage usage; OSStatus rv; usage = certUsageEmailSigner; /* do not include root */ certlist = CERT_CertChainFromCert(cert, usage, PR_FALSE); if (certlist == NULL) return SECFailure; rv = SecCmsSignedDataAddCertList(sigd, certlist); CFRelease(certlist); return rv; }
/* * NSS_CMSSignedData_AddCertChain - add cert and its entire chain to the set of certs */ SECStatus NSS_CMSSignedData_AddCertChain(NSSCMSSignedData *sigd, CERTCertificate *cert) { CERTCertificateList *certlist; SECCertUsage usage; SECStatus rv; usage = certUsageEmailSigner; if (!sigd || !cert) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } /* do not include root */ certlist = CERT_CertChainFromCert(cert, usage, PR_FALSE); if (certlist == NULL) return SECFailure; rv = NSS_CMSSignedData_AddCertList(sigd, certlist); return rv; }
SECStatus ssl_ConfigSecureServer(sslSocket *ss, CERTCertificate *cert, const CERTCertificateList *certChain, ssl3KeyPair *keyPair, SSLKEAType kea) { CERTCertificateList *localCertChain = NULL; sslServerCerts *sc = ss->serverCerts + kea; /* load the server certificate */ if (sc->serverCert != NULL) { CERT_DestroyCertificate(sc->serverCert); sc->serverCert = NULL; sc->serverKeyBits = 0; } /* load the server cert chain */ if (sc->serverCertChain != NULL) { CERT_DestroyCertificateList(sc->serverCertChain); sc->serverCertChain = NULL; } if (cert) { sc->serverCert = CERT_DupCertificate(cert); /* get the size of the cert's public key, and remember it */ sc->serverKeyBits = SECKEY_PublicKeyStrengthInBits(keyPair->pubKey); if (!certChain) { localCertChain = CERT_CertChainFromCert(sc->serverCert, certUsageSSLServer, PR_TRUE); if (!localCertChain) goto loser; } sc->serverCertChain = (certChain) ? CERT_DupCertList(certChain) : localCertChain; if (!sc->serverCertChain) { goto loser; } localCertChain = NULL; /* consumed */ } /* get keyPair */ if (sc->serverKeyPair != NULL) { ssl3_FreeKeyPair(sc->serverKeyPair); sc->serverKeyPair = NULL; } if (keyPair) { SECKEY_CacheStaticFlags(keyPair->privKey); sc->serverKeyPair = ssl3_GetKeyPairRef(keyPair); } if (kea == kt_rsa && cert && sc->serverKeyBits > 512 && !ss->opt.noStepDown && !ss->stepDownKeyPair) { if (ssl3_CreateRSAStepDownKeys(ss) != SECSuccess) { goto loser; } } return SECSuccess; loser: if (localCertChain) { CERT_DestroyCertificateList(localCertChain); } if (sc->serverCert != NULL) { CERT_DestroyCertificate(sc->serverCert); sc->serverCert = NULL; } if (sc->serverCertChain != NULL) { CERT_DestroyCertificateList(sc->serverCertChain); sc->serverCertChain = NULL; } if (sc->serverKeyPair != NULL) { ssl3_FreeKeyPair(sc->serverKeyPair); sc->serverKeyPair = NULL; } return SECFailure; }
SECStatus NSS_CMSSignedData_ImportCerts(NSSCMSSignedData *sigd, CERTCertDBHandle *certdb, SECCertUsage certusage, PRBool keepcerts) { int certcount; CERTCertificate **certArray = NULL; CERTCertList *certList = NULL; CERTCertListNode *node; SECStatus rv; SECItem **rawArray; int i; PRTime now; if (!sigd) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } certcount = NSS_CMSArray_Count((void **)sigd->rawCerts); /* get the certs in the temp DB */ rv = CERT_ImportCerts(certdb, certusage, certcount, sigd->rawCerts, &certArray, PR_FALSE, PR_FALSE, NULL); if (rv != SECSuccess) { goto loser; } /* save the certs so they don't get destroyed */ for (i = 0; i < certcount; i++) { CERTCertificate *cert = certArray[i]; if (cert) NSS_CMSSignedData_AddTempCertificate(sigd, cert); } if (!keepcerts) { goto done; } /* build a CertList for filtering */ certList = CERT_NewCertList(); if (certList == NULL) { rv = SECFailure; goto loser; } for (i = 0; i < certcount; i++) { CERTCertificate *cert = certArray[i]; if (cert) cert = CERT_DupCertificate(cert); if (cert) CERT_AddCertToListTail(certList, cert); } /* filter out the certs we don't want */ rv = CERT_FilterCertListByUsage(certList, certusage, PR_FALSE); if (rv != SECSuccess) { goto loser; } /* go down the remaining list of certs and verify that they have * valid chains, then import them. */ now = PR_Now(); for (node = CERT_LIST_HEAD(certList); !CERT_LIST_END(node, certList); node = CERT_LIST_NEXT(node)) { CERTCertificateList *certChain; if (CERT_VerifyCert(certdb, node->cert, PR_TRUE, certusage, now, NULL, NULL) != SECSuccess) { continue; } certChain = CERT_CertChainFromCert(node->cert, certusage, PR_FALSE); if (!certChain) { continue; } /* * CertChain returns an array of SECItems, import expects an array of * SECItem pointers. Create the SECItem Pointers from the array of * SECItems. */ rawArray = (SECItem **)PORT_Alloc(certChain->len * sizeof(SECItem *)); if (!rawArray) { CERT_DestroyCertificateList(certChain); continue; } for (i = 0; i < certChain->len; i++) { rawArray[i] = &certChain->certs[i]; } (void)CERT_ImportCerts(certdb, certusage, certChain->len, rawArray, NULL, keepcerts, PR_FALSE, NULL); PORT_Free(rawArray); CERT_DestroyCertificateList(certChain); } rv = SECSuccess; /* XXX CRL handling */ done: if (sigd->signerInfos != NULL) { /* fill in all signerinfo's certs */ for (i = 0; sigd->signerInfos[i] != NULL; i++) (void)NSS_CMSSignerInfo_GetSigningCertificate( sigd->signerInfos[i], certdb); } loser: /* now free everything */ if (certArray) { CERT_DestroyCertArray(certArray, certcount); } if (certList) { CERT_DestroyCertList(certList); } return rv; }
NS_IMETHODIMP nsNSSCertificate::ExportAsCMS(uint32_t chainMode, uint32_t *aLength, uint8_t **aArray) { NS_ENSURE_ARG(aLength); NS_ENSURE_ARG(aArray); nsNSSShutDownPreventionLock locker; if (isAlreadyShutDown()) return NS_ERROR_NOT_AVAILABLE; if (!mCert) return NS_ERROR_FAILURE; switch (chainMode) { case nsIX509Cert3::CMS_CHAIN_MODE_CertOnly: case nsIX509Cert3::CMS_CHAIN_MODE_CertChain: case nsIX509Cert3::CMS_CHAIN_MODE_CertChainWithRoot: break; default: return NS_ERROR_INVALID_ARG; }; PLArenaPool *arena = PORT_NewArena(1024); PLArenaPoolCleanerFalseParam arenaCleaner(arena); if (!arena) { PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsNSSCertificate::ExportAsCMS - out of memory\n")); return NS_ERROR_OUT_OF_MEMORY; } NSSCMSMessage *cmsg = NSS_CMSMessage_Create(nullptr); NSSCMSMessageCleaner cmsgCleaner(cmsg); if (!cmsg) { PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsNSSCertificate::ExportAsCMS - can't create CMS message\n")); return NS_ERROR_OUT_OF_MEMORY; } /* * first, create SignedData with the certificate only (no chain) */ NSSCMSSignedData *sigd = NSS_CMSSignedData_CreateCertsOnly(cmsg, mCert, false); NSSCMSSignedDataCleaner sigdCleaner(sigd); if (!sigd) { PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsNSSCertificate::ExportAsCMS - can't create SignedData\n")); return NS_ERROR_FAILURE; } /* * Calling NSS_CMSSignedData_CreateCertsOnly() will not allow us * to specify the inclusion of the root, but CERT_CertChainFromCert() does. * Since CERT_CertChainFromCert() also includes the certificate itself, * we have to start at the issuing cert (to avoid duplicate certs * in the SignedData). */ if (chainMode == nsIX509Cert3::CMS_CHAIN_MODE_CertChain || chainMode == nsIX509Cert3::CMS_CHAIN_MODE_CertChainWithRoot) { CERTCertificate *issuerCert = CERT_FindCertIssuer(mCert, PR_Now(), certUsageAnyCA); CERTCertificateCleaner issuerCertCleaner(issuerCert); /* * the issuerCert of a self signed root is the cert itself, * so make sure we're not adding duplicates, again */ if (issuerCert && issuerCert != mCert) { bool includeRoot = (chainMode == nsIX509Cert3::CMS_CHAIN_MODE_CertChainWithRoot); CERTCertificateList *certChain = CERT_CertChainFromCert(issuerCert, certUsageAnyCA, includeRoot); CERTCertificateListCleaner certChainCleaner(certChain); if (certChain) { if (NSS_CMSSignedData_AddCertList(sigd, certChain) == SECSuccess) { certChainCleaner.detach(); } else { PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsNSSCertificate::ExportAsCMS - can't add chain\n")); return NS_ERROR_FAILURE; } } else { /* try to add the issuerCert, at least */ if (NSS_CMSSignedData_AddCertificate(sigd, issuerCert) == SECSuccess) { issuerCertCleaner.detach(); } else { PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsNSSCertificate::ExportAsCMS - can't add issuer cert\n")); return NS_ERROR_FAILURE; } } } } NSSCMSContentInfo *cinfo = NSS_CMSMessage_GetContentInfo(cmsg); if (NSS_CMSContentInfo_SetContent_SignedData(cmsg, cinfo, sigd) == SECSuccess) { sigdCleaner.detach(); } else { PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsNSSCertificate::ExportAsCMS - can't attach SignedData\n")); return NS_ERROR_FAILURE; } SECItem certP7 = { siBuffer, nullptr, 0 }; NSSCMSEncoderContext *ecx = NSS_CMSEncoder_Start(cmsg, nullptr, nullptr, &certP7, arena, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); if (!ecx) { PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsNSSCertificate::ExportAsCMS - can't create encoder context\n")); return NS_ERROR_FAILURE; } if (NSS_CMSEncoder_Finish(ecx) != SECSuccess) { PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsNSSCertificate::ExportAsCMS - failed to add encoded data\n")); return NS_ERROR_FAILURE; } *aArray = (uint8_t*)nsMemory::Alloc(certP7.len); if (!*aArray) return NS_ERROR_OUT_OF_MEMORY; memcpy(*aArray, certP7.data, certP7.len); *aLength = certP7.len; return NS_OK; }
nsresult nsNSSCertificateDB::ImportValidCACertsInList(CERTCertList *certList, nsIInterfaceRequestor *ctx) { SECItem **rawArray; /* filter out the certs we don't want */ SECStatus srv = CERT_FilterCertListByUsage(certList, certUsageAnyCA, PR_TRUE); if (srv != SECSuccess) { return NS_ERROR_FAILURE; } /* go down the remaining list of certs and verify that they have * valid chains, if yes, then import. */ PRTime now = PR_Now(); CERTCertListNode *node; for (node = CERT_LIST_HEAD(certList); !CERT_LIST_END(node,certList); node = CERT_LIST_NEXT(node)) { bool alert_and_skip = false; if (CERT_VerifyCert(CERT_GetDefaultCertDB(), node->cert, PR_TRUE, certUsageVerifyCA, now, ctx, NULL) != SECSuccess) { alert_and_skip = true; } CERTCertificateList *certChain = nsnull; CERTCertificateListCleaner chainCleaner(certChain); if (!alert_and_skip) { certChain = CERT_CertChainFromCert(node->cert, certUsageAnyCA, PR_FALSE); if (!certChain) { alert_and_skip = true; } } if (alert_and_skip) { nsCOMPtr<nsIX509Cert> certToShow = new nsNSSCertificate(node->cert); DisplayCertificateAlert(ctx, "NotImportingUnverifiedCert", certToShow); continue; } /* * CertChain returns an array of SECItems, import expects an array of * SECItem pointers. Create the SECItem Pointers from the array of * SECItems. */ rawArray = (SECItem **) PORT_Alloc(certChain->len * sizeof(SECItem *)); if (!rawArray) { continue; } for (int i=0; i < certChain->len; i++) { rawArray[i] = &certChain->certs[i]; } CERT_ImportCerts(CERT_GetDefaultCertDB(), certUsageAnyCA, certChain->len, rawArray, NULL, PR_TRUE, PR_TRUE, NULL); PORT_Free(rawArray); } return NS_OK; }
/* * [noscript] void importEmailCertificates(in charPtr data, in unsigned long length, * in nsIInterfaceRequestor ctx); */ NS_IMETHODIMP nsNSSCertificateDB::ImportEmailCertificate(PRUint8 * data, PRUint32 length, nsIInterfaceRequestor *ctx) { nsNSSShutDownPreventionLock locker; SECStatus srv = SECFailure; nsresult nsrv = NS_OK; CERTCertDBHandle *certdb; CERTCertificate **certArray = NULL; CERTCertList *certList = NULL; CERTCertListNode *node; PRTime now; SECCertUsage certusage; SECItem **rawArray; int numcerts; int i; PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (!arena) return NS_ERROR_OUT_OF_MEMORY; CERTDERCerts *certCollection = getCertsFromPackage(arena, data, length); if (!certCollection) { PORT_FreeArena(arena, PR_FALSE); return NS_ERROR_FAILURE; } certdb = CERT_GetDefaultCertDB(); certusage = certUsageEmailRecipient; numcerts = certCollection->numcerts; rawArray = (SECItem **) PORT_Alloc(sizeof(SECItem *) * numcerts); if ( !rawArray ) { nsrv = NS_ERROR_FAILURE; goto loser; } for (i=0; i < numcerts; i++) { rawArray[i] = &certCollection->rawCerts[i]; } srv = CERT_ImportCerts(certdb, certusage, numcerts, rawArray, &certArray, PR_FALSE, PR_FALSE, NULL); PORT_Free(rawArray); rawArray = NULL; if (srv != SECSuccess) { nsrv = NS_ERROR_FAILURE; goto loser; } // build a CertList for filtering certList = CERT_NewCertList(); if (certList == NULL) { nsrv = NS_ERROR_FAILURE; goto loser; } for (i=0; i < numcerts; i++) { CERTCertificate *cert = certArray[i]; if (cert) cert = CERT_DupCertificate(cert); if (cert) CERT_AddCertToListTail(certList, cert); } /* go down the remaining list of certs and verify that they have * valid chains, then import them. */ now = PR_Now(); for (node = CERT_LIST_HEAD(certList); !CERT_LIST_END(node,certList); node = CERT_LIST_NEXT(node)) { bool alert_and_skip = false; if (!node->cert) { continue; } if (CERT_VerifyCert(certdb, node->cert, PR_TRUE, certusage, now, ctx, NULL) != SECSuccess) { alert_and_skip = true; } CERTCertificateList *certChain = nsnull; CERTCertificateListCleaner chainCleaner(certChain); if (!alert_and_skip) { certChain = CERT_CertChainFromCert(node->cert, certusage, PR_FALSE); if (!certChain) { alert_and_skip = true; } } if (alert_and_skip) { nsCOMPtr<nsIX509Cert> certToShow = new nsNSSCertificate(node->cert); DisplayCertificateAlert(ctx, "NotImportingUnverifiedCert", certToShow); continue; } /* * CertChain returns an array of SECItems, import expects an array of * SECItem pointers. Create the SECItem Pointers from the array of * SECItems. */ rawArray = (SECItem **) PORT_Alloc(certChain->len * sizeof(SECItem *)); if (!rawArray) { continue; } for (i=0; i < certChain->len; i++) { rawArray[i] = &certChain->certs[i]; } CERT_ImportCerts(certdb, certusage, certChain->len, rawArray, NULL, PR_TRUE, PR_FALSE, NULL); CERT_SaveSMimeProfile(node->cert, NULL, NULL); PORT_Free(rawArray); } loser: if (certArray) { CERT_DestroyCertArray(certArray, numcerts); } if (certList) { CERT_DestroyCertList(certList); } if (arena) PORT_FreeArena(arena, PR_TRUE); return nsrv; }
SECStatus SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert, SECKEYPrivateKey *key, SSL3KEAType kea) { SECStatus rv; sslSocket *ss; sslServerCerts *sc; SECKEYPublicKey * pubKey = NULL; ss = ssl_FindSocket(fd); if (!ss) { return SECFailure; } /* Both key and cert must have a value or be NULL */ /* Passing a value of NULL will turn off key exchange algorithms that were * previously turned on */ if (!cert != !key) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } /* make sure the key exchange is recognized */ if ((kea >= kt_kea_size) || (kea < kt_null)) { PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); return SECFailure; } if (kea != ssl_FindCertKEAType(cert)) { PORT_SetError(SSL_ERROR_CERT_KEA_MISMATCH); return SECFailure; } sc = ss->serverCerts + kea; /* load the server certificate */ if (sc->serverCert != NULL) { CERT_DestroyCertificate(sc->serverCert); sc->serverCert = NULL; } if (cert) { sc->serverCert = CERT_DupCertificate(cert); if (!sc->serverCert) goto loser; /* get the size of the cert's public key, and remember it */ pubKey = CERT_ExtractPublicKey(cert); if (!pubKey) goto loser; sc->serverKeyBits = SECKEY_PublicKeyStrengthInBits(pubKey); } /* load the server cert chain */ if (sc->serverCertChain != NULL) { CERT_DestroyCertificateList(sc->serverCertChain); sc->serverCertChain = NULL; } if (cert) { sc->serverCertChain = CERT_CertChainFromCert( sc->serverCert, certUsageSSLServer, PR_TRUE); if (sc->serverCertChain == NULL) goto loser; } /* load the private key */ if (sc->serverKeyPair != NULL) { ssl3_FreeKeyPair(sc->serverKeyPair); sc->serverKeyPair = NULL; } if (key) { SECKEYPrivateKey * keyCopy = NULL; CK_MECHANISM_TYPE keyMech = CKM_INVALID_MECHANISM; if (key->pkcs11Slot) { PK11SlotInfo * bestSlot; bestSlot = PK11_ReferenceSlot(key->pkcs11Slot); if (bestSlot) { keyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key); PK11_FreeSlot(bestSlot); } } if (keyCopy == NULL) keyMech = PK11_MapSignKeyType(key->keyType); if (keyMech != CKM_INVALID_MECHANISM) { PK11SlotInfo * bestSlot; /* XXX Maybe should be bestSlotMultiple? */ bestSlot = PK11_GetBestSlot(keyMech, NULL /* wincx */); if (bestSlot) { keyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key); PK11_FreeSlot(bestSlot); } } if (keyCopy == NULL) keyCopy = SECKEY_CopyPrivateKey(key); if (keyCopy == NULL) goto loser; SECKEY_CacheStaticFlags(keyCopy); sc->serverKeyPair = ssl3_NewKeyPair(keyCopy, pubKey); if (sc->serverKeyPair == NULL) { SECKEY_DestroyPrivateKey(keyCopy); goto loser; } pubKey = NULL; /* adopted by serverKeyPair */ } if (kea == kt_rsa && cert && sc->serverKeyBits > 512) { if (ss->opt.noStepDown) { /* disable all export ciphersuites */ } else { rv = ssl3_CreateRSAStepDownKeys(ss); if (rv != SECSuccess) { return SECFailure; /* err set by ssl3_CreateRSAStepDownKeys */ } } } /* Only do this once because it's global. */ if (PR_SUCCESS == PR_CallOnceWithArg(&setupServerCAListOnce, &serverCAListSetup, (void *)(ss->dbHandle))) { return SECSuccess; } loser: if (pubKey) { SECKEY_DestroyPublicKey(pubKey); pubKey = NULL; } if (sc->serverCert != NULL) { CERT_DestroyCertificate(sc->serverCert); sc->serverCert = NULL; } if (sc->serverCertChain != NULL) { CERT_DestroyCertificateList(sc->serverCertChain); sc->serverCertChain = NULL; } if (sc->serverKeyPair != NULL) { ssl3_FreeKeyPair(sc->serverKeyPair); sc->serverKeyPair = NULL; } return SECFailure; }