Index: mozilla/security/nss/lib/pki/pki3hack.c |
=================================================================== |
--- mozilla/security/nss/lib/pki/pki3hack.c (revision 191424) |
+++ mozilla/security/nss/lib/pki/pki3hack.c (working copy) |
@@ -1,1435 +0,0 @@ |
-/* This Source Code Form is subject to the terms of the Mozilla Public |
- * License, v. 2.0. If a copy of the MPL was not distributed with this |
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
- |
-#ifdef DEBUG |
-static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.111 $ $Date: 2013/01/07 04:11:51 $"; |
-#endif /* DEBUG */ |
- |
-/* |
- * Hacks to integrate NSS 3.4 and NSS 4.0 certificates. |
- */ |
- |
-#ifndef NSSPKI_H |
-#include "nsspki.h" |
-#endif /* NSSPKI_H */ |
- |
-#ifndef PKI_H |
-#include "pki.h" |
-#endif /* PKI_H */ |
- |
-#ifndef PKIM_H |
-#include "pkim.h" |
-#endif /* PKIM_H */ |
- |
-#ifndef DEV_H |
-#include "dev.h" |
-#endif /* DEV_H */ |
- |
-#ifndef DEVNSS3HACK_H |
-#include "dev3hack.h" |
-#endif /* DEVNSS3HACK_H */ |
- |
-#ifndef PKINSS3HACK_H |
-#include "pki3hack.h" |
-#endif /* PKINSS3HACK_H */ |
- |
-#include "secitem.h" |
-#include "certdb.h" |
-#include "certt.h" |
-#include "cert.h" |
-#include "certi.h" |
-#include "pk11func.h" |
-#include "pkistore.h" |
-#include "secmod.h" |
-#include "nssrwlk.h" |
- |
-NSSTrustDomain *g_default_trust_domain = NULL; |
- |
-NSSCryptoContext *g_default_crypto_context = NULL; |
- |
-NSSTrustDomain * |
-STAN_GetDefaultTrustDomain() |
-{ |
- return g_default_trust_domain; |
-} |
- |
-NSSCryptoContext * |
-STAN_GetDefaultCryptoContext() |
-{ |
- return g_default_crypto_context; |
-} |
- |
-extern const NSSError NSS_ERROR_ALREADY_INITIALIZED; |
-extern const NSSError NSS_ERROR_INTERNAL_ERROR; |
- |
-NSS_IMPLEMENT PRStatus |
-STAN_InitTokenForSlotInfo(NSSTrustDomain *td, PK11SlotInfo *slot) |
-{ |
- NSSToken *token; |
- if (!td) { |
- td = g_default_trust_domain; |
- if (!td) { |
- /* we're called while still initting. slot will get added |
- * appropriately through normal init processes */ |
- return PR_SUCCESS; |
- } |
- } |
- token = nssToken_CreateFromPK11SlotInfo(td, slot); |
- PK11Slot_SetNSSToken(slot, token); |
- /* Don't add nonexistent token to TD's token list */ |
- if (token) { |
- NSSRWLock_LockWrite(td->tokensLock); |
- nssList_Add(td->tokenList, token); |
- NSSRWLock_UnlockWrite(td->tokensLock); |
- } |
- return PR_SUCCESS; |
-} |
- |
-NSS_IMPLEMENT PRStatus |
-STAN_ResetTokenInterator(NSSTrustDomain *td) |
-{ |
- if (!td) { |
- td = g_default_trust_domain; |
- if (!td) { |
- /* we're called while still initting. slot will get added |
- * appropriately through normal init processes */ |
- return PR_SUCCESS; |
- } |
- } |
- NSSRWLock_LockWrite(td->tokensLock); |
- nssListIterator_Destroy(td->tokens); |
- td->tokens = nssList_CreateIterator(td->tokenList); |
- NSSRWLock_UnlockWrite(td->tokensLock); |
- return PR_SUCCESS; |
-} |
- |
-NSS_IMPLEMENT PRStatus |
-STAN_LoadDefaultNSS3TrustDomain ( |
- void |
-) |
-{ |
- NSSTrustDomain *td; |
- SECMODModuleList *mlp; |
- SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock(); |
- int i; |
- |
- if (g_default_trust_domain || g_default_crypto_context) { |
- /* Stan is already initialized or a previous shutdown failed. */ |
- nss_SetError(NSS_ERROR_ALREADY_INITIALIZED); |
- return PR_FAILURE; |
- } |
- td = NSSTrustDomain_Create(NULL, NULL, NULL, NULL); |
- if (!td) { |
- return PR_FAILURE; |
- } |
- /* |
- * Deadlock warning: we should never acquire the moduleLock while |
- * we hold the tokensLock. We can use the NSSRWLock Rank feature to |
- * guarrentee this. tokensLock have a higher rank than module lock. |
- */ |
- td->tokenList = nssList_Create(td->arena, PR_TRUE); |
- if (!td->tokenList) { |
- goto loser; |
- } |
- SECMOD_GetReadLock(moduleLock); |
- NSSRWLock_LockWrite(td->tokensLock); |
- for (mlp = SECMOD_GetDefaultModuleList(); mlp != NULL; mlp=mlp->next) { |
- for (i=0; i < mlp->module->slotCount; i++) { |
- STAN_InitTokenForSlotInfo(td, mlp->module->slots[i]); |
- } |
- } |
- td->tokens = nssList_CreateIterator(td->tokenList); |
- NSSRWLock_UnlockWrite(td->tokensLock); |
- SECMOD_ReleaseReadLock(moduleLock); |
- if (!td->tokens) { |
- goto loser; |
- } |
- g_default_crypto_context = NSSTrustDomain_CreateCryptoContext(td, NULL); |
- if (!g_default_crypto_context) { |
- goto loser; |
- } |
- g_default_trust_domain = td; |
- return PR_SUCCESS; |
- |
- loser: |
- NSSTrustDomain_Destroy(td); |
- return PR_FAILURE; |
-} |
- |
-/* |
- * must be called holding the ModuleListLock (either read or write). |
- */ |
-NSS_IMPLEMENT SECStatus |
-STAN_AddModuleToDefaultTrustDomain ( |
- SECMODModule *module |
-) |
-{ |
- NSSTrustDomain *td; |
- int i; |
- td = STAN_GetDefaultTrustDomain(); |
- for (i=0; i<module->slotCount; i++) { |
- STAN_InitTokenForSlotInfo(td, module->slots[i]); |
- } |
- STAN_ResetTokenInterator(td); |
- return SECSuccess; |
-} |
- |
-/* |
- * must be called holding the ModuleListLock (either read or write). |
- */ |
-NSS_IMPLEMENT SECStatus |
-STAN_RemoveModuleFromDefaultTrustDomain ( |
- SECMODModule *module |
-) |
-{ |
- NSSToken *token; |
- NSSTrustDomain *td; |
- int i; |
- td = STAN_GetDefaultTrustDomain(); |
- NSSRWLock_LockWrite(td->tokensLock); |
- for (i=0; i<module->slotCount; i++) { |
- token = PK11Slot_GetNSSToken(module->slots[i]); |
- if (token) { |
- nssToken_NotifyCertsNotVisible(token); |
- nssList_Remove(td->tokenList, token); |
- PK11Slot_SetNSSToken(module->slots[i], NULL); |
- nssToken_Destroy(token); |
- } |
- } |
- nssListIterator_Destroy(td->tokens); |
- td->tokens = nssList_CreateIterator(td->tokenList); |
- NSSRWLock_UnlockWrite(td->tokensLock); |
- return SECSuccess; |
-} |
- |
-NSS_IMPLEMENT PRStatus |
-STAN_Shutdown() |
-{ |
- PRStatus status = PR_SUCCESS; |
- if (g_default_trust_domain) { |
- if (NSSTrustDomain_Destroy(g_default_trust_domain) == PR_SUCCESS) { |
- g_default_trust_domain = NULL; |
- } else { |
- status = PR_FAILURE; |
- } |
- } |
- if (g_default_crypto_context) { |
- if (NSSCryptoContext_Destroy(g_default_crypto_context) == PR_SUCCESS) { |
- g_default_crypto_context = NULL; |
- } else { |
- status = PR_FAILURE; |
- } |
- } |
- return status; |
-} |
- |
-/* this function should not be a hack; it will be needed in 4.0 (rename) */ |
-NSS_IMPLEMENT NSSItem * |
-STAN_GetCertIdentifierFromDER(NSSArena *arenaOpt, NSSDER *der) |
-{ |
- NSSItem *rvKey; |
- SECItem secDER; |
- SECItem secKey = { 0 }; |
- SECStatus secrv; |
- PRArenaPool *arena; |
- |
- SECITEM_FROM_NSSITEM(&secDER, der); |
- |
- /* nss3 call uses nss3 arena's */ |
- arena = PORT_NewArena(256); |
- if (!arena) { |
- return NULL; |
- } |
- secrv = CERT_KeyFromDERCert(arena, &secDER, &secKey); |
- if (secrv != SECSuccess) { |
- return NULL; |
- } |
- rvKey = nssItem_Create(arenaOpt, NULL, secKey.len, (void *)secKey.data); |
- PORT_FreeArena(arena,PR_FALSE); |
- return rvKey; |
-} |
- |
-NSS_IMPLEMENT PRStatus |
-nssPKIX509_GetIssuerAndSerialFromDER(NSSDER *der, NSSArena *arena, |
- NSSDER *issuer, NSSDER *serial) |
-{ |
- SECStatus secrv; |
- SECItem derCert; |
- SECItem derIssuer = { 0 }; |
- SECItem derSerial = { 0 }; |
- SECITEM_FROM_NSSITEM(&derCert, der); |
- secrv = CERT_SerialNumberFromDERCert(&derCert, &derSerial); |
- if (secrv != SECSuccess) { |
- return PR_FAILURE; |
- } |
- (void)nssItem_Create(arena, serial, derSerial.len, derSerial.data); |
- secrv = CERT_IssuerNameFromDERCert(&derCert, &derIssuer); |
- if (secrv != SECSuccess) { |
- PORT_Free(derSerial.data); |
- return PR_FAILURE; |
- } |
- (void)nssItem_Create(arena, issuer, derIssuer.len, derIssuer.data); |
- PORT_Free(derSerial.data); |
- PORT_Free(derIssuer.data); |
- return PR_SUCCESS; |
-} |
- |
-static NSSItem * |
-nss3certificate_getIdentifier(nssDecodedCert *dc) |
-{ |
- NSSItem *rvID; |
- CERTCertificate *c = (CERTCertificate *)dc->data; |
- rvID = nssItem_Create(NULL, NULL, c->certKey.len, c->certKey.data); |
- return rvID; |
-} |
- |
-static void * |
-nss3certificate_getIssuerIdentifier(nssDecodedCert *dc) |
-{ |
- CERTCertificate *c = (CERTCertificate *)dc->data; |
- return (void *)c->authKeyID; |
-} |
- |
-static nssCertIDMatch |
-nss3certificate_matchIdentifier(nssDecodedCert *dc, void *id) |
-{ |
- CERTCertificate *c = (CERTCertificate *)dc->data; |
- CERTAuthKeyID *authKeyID = (CERTAuthKeyID *)id; |
- SECItem skid; |
- nssCertIDMatch match = nssCertIDMatch_Unknown; |
- |
- /* keyIdentifier */ |
- if (authKeyID->keyID.len > 0 && |
- CERT_FindSubjectKeyIDExtension(c, &skid) == SECSuccess) { |
- PRBool skiEqual; |
- skiEqual = SECITEM_ItemsAreEqual(&authKeyID->keyID, &skid); |
- PORT_Free(skid.data); |
- if (skiEqual) { |
- /* change the state to positive match, but keep going */ |
- match = nssCertIDMatch_Yes; |
- } else { |
- /* exit immediately on failure */ |
- return nssCertIDMatch_No; |
- } |
- } |
- |
- /* issuer/serial (treated as pair) */ |
- if (authKeyID->authCertIssuer) { |
- SECItem *caName = NULL; |
- SECItem *caSN = &authKeyID->authCertSerialNumber; |
- |
- caName = (SECItem *)CERT_GetGeneralNameByType( |
- authKeyID->authCertIssuer, |
- certDirectoryName, PR_TRUE); |
- if (caName != NULL && |
- SECITEM_ItemsAreEqual(&c->derIssuer, caName) && |
- SECITEM_ItemsAreEqual(&c->serialNumber, caSN)) |
- { |
- match = nssCertIDMatch_Yes; |
- } else { |
- match = nssCertIDMatch_Unknown; |
- } |
- } |
- return match; |
-} |
- |
-static PRBool |
-nss3certificate_isValidIssuer(nssDecodedCert *dc) |
-{ |
- CERTCertificate *c = (CERTCertificate *)dc->data; |
- unsigned int ignore; |
- return CERT_IsCACert(c, &ignore); |
-} |
- |
-static NSSUsage * |
-nss3certificate_getUsage(nssDecodedCert *dc) |
-{ |
- /* CERTCertificate *c = (CERTCertificate *)dc->data; */ |
- return NULL; |
-} |
- |
-static PRBool |
-nss3certificate_isValidAtTime(nssDecodedCert *dc, NSSTime *time) |
-{ |
- SECCertTimeValidity validity; |
- CERTCertificate *c = (CERTCertificate *)dc->data; |
- validity = CERT_CheckCertValidTimes(c, NSSTime_GetPRTime(time), PR_TRUE); |
- if (validity == secCertTimeValid) { |
- return PR_TRUE; |
- } |
- return PR_FALSE; |
-} |
- |
-static PRBool |
-nss3certificate_isNewerThan(nssDecodedCert *dc, nssDecodedCert *cmpdc) |
-{ |
- /* I know this isn't right, but this is glue code anyway */ |
- if (cmpdc->type == dc->type) { |
- CERTCertificate *certa = (CERTCertificate *)dc->data; |
- CERTCertificate *certb = (CERTCertificate *)cmpdc->data; |
- return CERT_IsNewer(certa, certb); |
- } |
- return PR_FALSE; |
-} |
- |
-/* CERT_FilterCertListByUsage */ |
-static PRBool |
-nss3certificate_matchUsage(nssDecodedCert *dc, const NSSUsage *usage) |
-{ |
- CERTCertificate *cc; |
- unsigned int requiredKeyUsage = 0; |
- unsigned int requiredCertType = 0; |
- SECStatus secrv; |
- PRBool match; |
- PRBool ca; |
- |
- /* This is for NSS 3.3 functions that do not specify a usage */ |
- if (usage->anyUsage) { |
- return PR_TRUE; |
- } |
- ca = usage->nss3lookingForCA; |
- secrv = CERT_KeyUsageAndTypeForCertUsage(usage->nss3usage, ca, |
- &requiredKeyUsage, |
- &requiredCertType); |
- if (secrv != SECSuccess) { |
- return PR_FALSE; |
- } |
- cc = (CERTCertificate *)dc->data; |
- secrv = CERT_CheckKeyUsage(cc, requiredKeyUsage); |
- match = (PRBool)(secrv == SECSuccess); |
- if (match) { |
- unsigned int certType = 0; |
- if (ca) { |
- (void)CERT_IsCACert(cc, &certType); |
- } else { |
- certType = cc->nsCertType; |
- } |
- if (!(certType & requiredCertType)) { |
- match = PR_FALSE; |
- } |
- } |
- return match; |
-} |
- |
-static PRBool |
-nss3certificate_isTrustedForUsage(nssDecodedCert *dc, const NSSUsage *usage) |
-{ |
- CERTCertificate *cc; |
- PRBool ca; |
- SECStatus secrv; |
- unsigned int requiredFlags; |
- unsigned int trustFlags; |
- SECTrustType trustType; |
- CERTCertTrust trust; |
- |
- /* This is for NSS 3.3 functions that do not specify a usage */ |
- if (usage->anyUsage) { |
- return PR_FALSE; /* XXX is this right? */ |
- } |
- cc = (CERTCertificate *)dc->data; |
- ca = usage->nss3lookingForCA; |
- if (!ca) { |
- PRBool trusted; |
- unsigned int failedFlags; |
- secrv = cert_CheckLeafTrust(cc, usage->nss3usage, |
- &failedFlags, &trusted); |
- return secrv == SECSuccess && trusted; |
- } |
- secrv = CERT_TrustFlagsForCACertUsage(usage->nss3usage, &requiredFlags, |
- &trustType); |
- if (secrv != SECSuccess) { |
- return PR_FALSE; |
- } |
- secrv = CERT_GetCertTrust(cc, &trust); |
- if (secrv != SECSuccess) { |
- return PR_FALSE; |
- } |
- if (trustType == trustTypeNone) { |
- /* normally trustTypeNone usages accept any of the given trust bits |
- * being on as acceptable. */ |
- trustFlags = trust.sslFlags | trust.emailFlags | |
- trust.objectSigningFlags; |
- } else { |
- trustFlags = SEC_GET_TRUST_FLAGS(&trust, trustType); |
- } |
- return (trustFlags & requiredFlags) == requiredFlags; |
-} |
- |
-static NSSASCII7 * |
-nss3certificate_getEmailAddress(nssDecodedCert *dc) |
-{ |
- CERTCertificate *cc = (CERTCertificate *)dc->data; |
- return (cc && cc->emailAddr && cc->emailAddr[0]) |
- ? (NSSASCII7 *)cc->emailAddr : NULL; |
-} |
- |
-static PRStatus |
-nss3certificate_getDERSerialNumber(nssDecodedCert *dc, |
- NSSDER *serial, NSSArena *arena) |
-{ |
- CERTCertificate *cc = (CERTCertificate *)dc->data; |
- SECItem derSerial = { 0 }; |
- SECStatus secrv; |
- secrv = CERT_SerialNumberFromDERCert(&cc->derCert, &derSerial); |
- if (secrv == SECSuccess) { |
- (void)nssItem_Create(arena, serial, derSerial.len, derSerial.data); |
- PORT_Free(derSerial.data); |
- return PR_SUCCESS; |
- } |
- return PR_FAILURE; |
-} |
- |
-/* Returns NULL if "encoding" cannot be decoded. */ |
-NSS_IMPLEMENT nssDecodedCert * |
-nssDecodedPKIXCertificate_Create ( |
- NSSArena *arenaOpt, |
- NSSDER *encoding |
-) |
-{ |
- nssDecodedCert *rvDC = NULL; |
- CERTCertificate *cert; |
- SECItem secDER; |
- |
- SECITEM_FROM_NSSITEM(&secDER, encoding); |
- cert = CERT_DecodeDERCertificate(&secDER, PR_TRUE, NULL); |
- if (cert) { |
- rvDC = nss_ZNEW(arenaOpt, nssDecodedCert); |
- if (rvDC) { |
- rvDC->type = NSSCertificateType_PKIX; |
- rvDC->data = (void *)cert; |
- rvDC->getIdentifier = nss3certificate_getIdentifier; |
- rvDC->getIssuerIdentifier = nss3certificate_getIssuerIdentifier; |
- rvDC->matchIdentifier = nss3certificate_matchIdentifier; |
- rvDC->isValidIssuer = nss3certificate_isValidIssuer; |
- rvDC->getUsage = nss3certificate_getUsage; |
- rvDC->isValidAtTime = nss3certificate_isValidAtTime; |
- rvDC->isNewerThan = nss3certificate_isNewerThan; |
- rvDC->matchUsage = nss3certificate_matchUsage; |
- rvDC->isTrustedForUsage = nss3certificate_isTrustedForUsage; |
- rvDC->getEmailAddress = nss3certificate_getEmailAddress; |
- rvDC->getDERSerialNumber = nss3certificate_getDERSerialNumber; |
- } else { |
- CERT_DestroyCertificate(cert); |
- } |
- } |
- return rvDC; |
-} |
- |
-static nssDecodedCert * |
-create_decoded_pkix_cert_from_nss3cert ( |
- NSSArena *arenaOpt, |
- CERTCertificate *cc |
-) |
-{ |
- nssDecodedCert *rvDC = nss_ZNEW(arenaOpt, nssDecodedCert); |
- if (rvDC) { |
- rvDC->type = NSSCertificateType_PKIX; |
- rvDC->data = (void *)cc; |
- rvDC->getIdentifier = nss3certificate_getIdentifier; |
- rvDC->getIssuerIdentifier = nss3certificate_getIssuerIdentifier; |
- rvDC->matchIdentifier = nss3certificate_matchIdentifier; |
- rvDC->isValidIssuer = nss3certificate_isValidIssuer; |
- rvDC->getUsage = nss3certificate_getUsage; |
- rvDC->isValidAtTime = nss3certificate_isValidAtTime; |
- rvDC->isNewerThan = nss3certificate_isNewerThan; |
- rvDC->matchUsage = nss3certificate_matchUsage; |
- rvDC->isTrustedForUsage = nss3certificate_isTrustedForUsage; |
- rvDC->getEmailAddress = nss3certificate_getEmailAddress; |
- rvDC->getDERSerialNumber = nss3certificate_getDERSerialNumber; |
- } |
- return rvDC; |
-} |
- |
-NSS_IMPLEMENT PRStatus |
-nssDecodedPKIXCertificate_Destroy ( |
- nssDecodedCert *dc |
-) |
-{ |
- CERTCertificate *cert = (CERTCertificate *)dc->data; |
- |
- /* The decoder may only be half initialized (the case where we find we |
- * could not decode the certificate). In this case, there is not cert to |
- * free, just free the dc structure. */ |
- if (cert) { |
- PRBool freeSlot = cert->ownSlot; |
- PK11SlotInfo *slot = cert->slot; |
- PRArenaPool *arena = cert->arena; |
- /* zero cert before freeing. Any stale references to this cert |
- * after this point will probably cause an exception. */ |
- PORT_Memset(cert, 0, sizeof *cert); |
- /* free the arena that contains the cert. */ |
- PORT_FreeArena(arena, PR_FALSE); |
- if (slot && freeSlot) { |
- PK11_FreeSlot(slot); |
- } |
- } |
- nss_ZFreeIf(dc); |
- return PR_SUCCESS; |
-} |
- |
-/* see pk11cert.c:pk11_HandleTrustObject */ |
-static unsigned int |
-get_nss3trust_from_nss4trust(nssTrustLevel t) |
-{ |
- unsigned int rt = 0; |
- if (t == nssTrustLevel_Trusted) { |
- rt |= CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED; |
- } |
- if (t == nssTrustLevel_TrustedDelegator) { |
- rt |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA; |
- } |
- if (t == nssTrustLevel_NotTrusted) { |
- rt |= CERTDB_TERMINAL_RECORD; |
- } |
- if (t == nssTrustLevel_ValidDelegator) { |
- rt |= CERTDB_VALID_CA; |
- } |
- return rt; |
-} |
- |
-static CERTCertTrust * |
-cert_trust_from_stan_trust(NSSTrust *t, PRArenaPool *arena) |
-{ |
- CERTCertTrust *rvTrust; |
- unsigned int client; |
- if (!t) { |
- return NULL; |
- } |
- rvTrust = PORT_ArenaAlloc(arena, sizeof(CERTCertTrust)); |
- if (!rvTrust) return NULL; |
- rvTrust->sslFlags = get_nss3trust_from_nss4trust(t->serverAuth); |
- client = get_nss3trust_from_nss4trust(t->clientAuth); |
- if (client & (CERTDB_TRUSTED_CA|CERTDB_NS_TRUSTED_CA)) { |
- client &= ~(CERTDB_TRUSTED_CA|CERTDB_NS_TRUSTED_CA); |
- rvTrust->sslFlags |= CERTDB_TRUSTED_CLIENT_CA; |
- } |
- rvTrust->sslFlags |= client; |
- rvTrust->emailFlags = get_nss3trust_from_nss4trust(t->emailProtection); |
- rvTrust->objectSigningFlags = get_nss3trust_from_nss4trust(t->codeSigning); |
- return rvTrust; |
-} |
- |
-CERTCertTrust * |
-nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc) |
-{ |
- CERTCertTrust *rvTrust = NULL; |
- NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); |
- NSSTrust *t; |
- t = nssTrustDomain_FindTrustForCertificate(td, c); |
- if (t) { |
- rvTrust = cert_trust_from_stan_trust(t, cc->arena); |
- if (!rvTrust) { |
- nssTrust_Destroy(t); |
- return NULL; |
- } |
- nssTrust_Destroy(t); |
- } else { |
- rvTrust = PORT_ArenaAlloc(cc->arena, sizeof(CERTCertTrust)); |
- if (!rvTrust) { |
- return NULL; |
- } |
- memset(rvTrust, 0, sizeof(*rvTrust)); |
- } |
- if (NSSCertificate_IsPrivateKeyAvailable(c, NULL, NULL)) { |
- rvTrust->sslFlags |= CERTDB_USER; |
- rvTrust->emailFlags |= CERTDB_USER; |
- rvTrust->objectSigningFlags |= CERTDB_USER; |
- } |
- return rvTrust; |
-} |
- |
-static nssCryptokiInstance * |
-get_cert_instance(NSSCertificate *c) |
-{ |
- nssCryptokiObject *instance, **ci; |
- nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object); |
- if (!instances) { |
- return NULL; |
- } |
- instance = NULL; |
- for (ci = instances; *ci; ci++) { |
- if (!instance) { |
- instance = nssCryptokiObject_Clone(*ci); |
- } else { |
- /* This only really works for two instances... But 3.4 can't |
- * handle more anyway. The logic is, if there are multiple |
- * instances, prefer the one that is not internal (e.g., on |
- * a hardware device. |
- */ |
- if (PK11_IsInternal(instance->token->pk11slot)) { |
- nssCryptokiObject_Destroy(instance); |
- instance = nssCryptokiObject_Clone(*ci); |
- } |
- } |
- } |
- nssCryptokiObjectArray_Destroy(instances); |
- return instance; |
-} |
- |
-char * |
-STAN_GetCERTCertificateNameForInstance ( |
- PLArenaPool *arenaOpt, |
- NSSCertificate *c, |
- nssCryptokiInstance *instance |
-) |
-{ |
- NSSCryptoContext *context = c->object.cryptoContext; |
- PRStatus nssrv; |
- int nicklen, tokenlen, len; |
- NSSUTF8 *tokenName = NULL; |
- NSSUTF8 *stanNick = NULL; |
- char *nickname = NULL; |
- char *nick; |
- |
- if (instance) { |
- stanNick = instance->label; |
- } else if (context) { |
- stanNick = c->object.tempName; |
- } |
- if (stanNick) { |
- /* fill other fields needed by NSS3 functions using CERTCertificate */ |
- if (instance && (!PK11_IsInternalKeySlot(instance->token->pk11slot) || |
- PORT_Strchr(stanNick, ':') != NULL) ) { |
- tokenName = nssToken_GetName(instance->token); |
- tokenlen = nssUTF8_Size(tokenName, &nssrv); |
- } else { |
- /* don't use token name for internal slot; 3.3 didn't */ |
- tokenlen = 0; |
- } |
- nicklen = nssUTF8_Size(stanNick, &nssrv); |
- len = tokenlen + nicklen; |
- if (arenaOpt) { |
- nickname = PORT_ArenaAlloc(arenaOpt, len); |
- } else { |
- nickname = PORT_Alloc(len); |
- } |
- nick = nickname; |
- if (tokenName) { |
- memcpy(nick, tokenName, tokenlen-1); |
- nick += tokenlen-1; |
- *nick++ = ':'; |
- } |
- memcpy(nick, stanNick, nicklen-1); |
- nickname[len-1] = '\0'; |
- } |
- return nickname; |
-} |
- |
-char * |
-STAN_GetCERTCertificateName(PLArenaPool *arenaOpt, NSSCertificate *c) |
-{ |
- char * result; |
- nssCryptokiInstance *instance = get_cert_instance(c); |
- /* It's OK to call this function, even if instance is NULL */ |
- result = STAN_GetCERTCertificateNameForInstance(arenaOpt, c, instance); |
- if (instance) |
- nssCryptokiObject_Destroy(instance); |
- return result; |
-} |
- |
-static void |
-fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced) |
-{ |
- CERTCertTrust* trust = NULL; |
- NSSTrust *nssTrust; |
- NSSCryptoContext *context = c->object.cryptoContext; |
- nssCryptokiInstance *instance; |
- NSSUTF8 *stanNick = NULL; |
- |
- /* We are holding the base class object's lock on entry of this function |
- * This lock protects writes to fields of the CERTCertificate . |
- * It is also needed by some functions to compute values such as trust. |
- */ |
- instance = get_cert_instance(c); |
- |
- if (instance) { |
- stanNick = instance->label; |
- } else if (context) { |
- stanNick = c->object.tempName; |
- } |
- /* fill other fields needed by NSS3 functions using CERTCertificate */ |
- if ((!cc->nickname && stanNick) || forced) { |
- PRStatus nssrv; |
- int nicklen, tokenlen, len; |
- NSSUTF8 *tokenName = NULL; |
- char *nick; |
- if (instance && |
- (!PK11_IsInternalKeySlot(instance->token->pk11slot) || |
- (stanNick && PORT_Strchr(stanNick, ':') != NULL))) { |
- tokenName = nssToken_GetName(instance->token); |
- tokenlen = nssUTF8_Size(tokenName, &nssrv); |
- } else { |
- /* don't use token name for internal slot; 3.3 didn't */ |
- tokenlen = 0; |
- } |
- if (stanNick) { |
- nicklen = nssUTF8_Size(stanNick, &nssrv); |
- len = tokenlen + nicklen; |
- nick = PORT_ArenaAlloc(cc->arena, len); |
- if (tokenName) { |
- memcpy(nick, tokenName, tokenlen-1); |
- nick[tokenlen-1] = ':'; |
- memcpy(nick+tokenlen, stanNick, nicklen-1); |
- } else { |
- memcpy(nick, stanNick, nicklen-1); |
- } |
- nick[len-1] = '\0'; |
- cc->nickname = nick; |
- } else { |
- cc->nickname = NULL; |
- } |
- } |
- if (context) { |
- /* trust */ |
- nssTrust = nssCryptoContext_FindTrustForCertificate(context, c); |
- if (!nssTrust) { |
- /* chicken and egg issue: |
- * |
- * c->issuer and c->serial are empty at this point, but |
- * nssTrustDomain_FindTrustForCertificate use them to look up |
- * up the trust object, so we point them to cc->derIssuer and |
- * cc->serialNumber. |
- * |
- * Our caller will fill these in with proper arena copies when we |
- * return. */ |
- c->issuer.data = cc->derIssuer.data; |
- c->issuer.size = cc->derIssuer.len; |
- c->serial.data = cc->serialNumber.data; |
- c->serial.size = cc->serialNumber.len; |
- nssTrust = nssTrustDomain_FindTrustForCertificate(context->td, c); |
- } |
- if (nssTrust) { |
- trust = cert_trust_from_stan_trust(nssTrust, cc->arena); |
- if (trust) { |
- /* we should destroy cc->trust before replacing it, but it's |
- allocated in cc->arena, so memory growth will occur on each |
- refresh */ |
- CERT_LockCertTrust(cc); |
- cc->trust = trust; |
- CERT_UnlockCertTrust(cc); |
- } |
- nssTrust_Destroy(nssTrust); |
- } |
- } else if (instance) { |
- /* slot */ |
- if (cc->slot != instance->token->pk11slot) { |
- if (cc->slot) { |
- PK11_FreeSlot(cc->slot); |
- } |
- cc->slot = PK11_ReferenceSlot(instance->token->pk11slot); |
- } |
- cc->ownSlot = PR_TRUE; |
- /* pkcs11ID */ |
- cc->pkcs11ID = instance->handle; |
- /* trust */ |
- trust = nssTrust_GetCERTCertTrustForCert(c, cc); |
- if (trust) { |
- /* we should destroy cc->trust before replacing it, but it's |
- allocated in cc->arena, so memory growth will occur on each |
- refresh */ |
- CERT_LockCertTrust(cc); |
- cc->trust = trust; |
- CERT_UnlockCertTrust(cc); |
- } |
- nssCryptokiObject_Destroy(instance); |
- } |
- /* database handle is now the trust domain */ |
- cc->dbhandle = c->object.trustDomain; |
- /* subjectList ? */ |
- /* istemp and isperm are supported in NSS 3.4 */ |
- cc->istemp = PR_FALSE; /* CERT_NewTemp will override this */ |
- cc->isperm = PR_TRUE; /* by default */ |
- /* pointer back */ |
- cc->nssCertificate = c; |
- if (trust) { |
- /* force the cert type to be recomputed to include trust info */ |
- PRUint32 nsCertType = cert_ComputeCertType(cc); |
- |
- /* Assert that it is safe to cast &cc->nsCertType to "PRInt32 *" */ |
- PORT_Assert(sizeof(cc->nsCertType) == sizeof(PRInt32)); |
- PR_ATOMIC_SET((PRInt32 *)&cc->nsCertType, nsCertType); |
- } |
-} |
- |
-static CERTCertificate * |
-stan_GetCERTCertificate(NSSCertificate *c, PRBool forceUpdate) |
-{ |
- nssDecodedCert *dc = NULL; |
- CERTCertificate *cc = NULL; |
- CERTCertTrust certTrust; |
- |
- nssPKIObject_Lock(&c->object); |
- |
- dc = c->decoding; |
- if (!dc) { |
- dc = nssDecodedPKIXCertificate_Create(NULL, &c->encoding); |
- if (!dc) { |
- goto loser; |
- } |
- cc = (CERTCertificate *)dc->data; |
- PORT_Assert(cc); /* software error */ |
- if (!cc) { |
- nssDecodedPKIXCertificate_Destroy(dc); |
- nss_SetError(NSS_ERROR_INTERNAL_ERROR); |
- goto loser; |
- } |
- PORT_Assert(!c->decoding); |
- if (!c->decoding) { |
- c->decoding = dc; |
- } else { |
- /* this should never happen. Fail. */ |
- nssDecodedPKIXCertificate_Destroy(dc); |
- nss_SetError(NSS_ERROR_INTERNAL_ERROR); |
- goto loser; |
- } |
- } |
- cc = (CERTCertificate *)dc->data; |
- PORT_Assert(cc); |
- if (!cc) { |
- nss_SetError(NSS_ERROR_INTERNAL_ERROR); |
- goto loser; |
- } |
- if (!cc->nssCertificate || forceUpdate) { |
- fill_CERTCertificateFields(c, cc, forceUpdate); |
- } else if (CERT_GetCertTrust(cc, &certTrust) != SECSuccess && |
- !c->object.cryptoContext) { |
- /* if it's a perm cert, it might have been stored before the |
- * trust, so look for the trust again. But a temp cert can be |
- * ignored. |
- */ |
- CERTCertTrust* trust = NULL; |
- trust = nssTrust_GetCERTCertTrustForCert(c, cc); |
- |
- CERT_LockCertTrust(cc); |
- cc->trust = trust; |
- CERT_UnlockCertTrust(cc); |
- } |
- |
- loser: |
- nssPKIObject_Unlock(&c->object); |
- return cc; |
-} |
- |
-NSS_IMPLEMENT CERTCertificate * |
-STAN_ForceCERTCertificateUpdate(NSSCertificate *c) |
-{ |
- if (c->decoding) { |
- return stan_GetCERTCertificate(c, PR_TRUE); |
- } |
- return NULL; |
-} |
- |
-NSS_IMPLEMENT CERTCertificate * |
-STAN_GetCERTCertificate(NSSCertificate *c) |
-{ |
- return stan_GetCERTCertificate(c, PR_FALSE); |
-} |
-/* |
- * many callers of STAN_GetCERTCertificate() intend that |
- * the CERTCertificate returned inherits the reference to the |
- * NSSCertificate. For these callers it's convenient to have |
- * this function 'own' the reference and either return a valid |
- * CERTCertificate structure which inherits the reference or |
- * destroy the reference to NSSCertificate and returns NULL. |
- */ |
-NSS_IMPLEMENT CERTCertificate * |
-STAN_GetCERTCertificateOrRelease(NSSCertificate *c) |
-{ |
- CERTCertificate *nss3cert = stan_GetCERTCertificate(c, PR_FALSE); |
- if (!nss3cert) { |
- nssCertificate_Destroy(c); |
- } |
- return nss3cert; |
-} |
- |
-static nssTrustLevel |
-get_stan_trust(unsigned int t, PRBool isClientAuth) |
-{ |
- if (isClientAuth) { |
- if (t & CERTDB_TRUSTED_CLIENT_CA) { |
- return nssTrustLevel_TrustedDelegator; |
- } |
- } else { |
- if (t & CERTDB_TRUSTED_CA || t & CERTDB_NS_TRUSTED_CA) { |
- return nssTrustLevel_TrustedDelegator; |
- } |
- } |
- if (t & CERTDB_TRUSTED) { |
- return nssTrustLevel_Trusted; |
- } |
- if (t & CERTDB_TERMINAL_RECORD) { |
- return nssTrustLevel_NotTrusted; |
- } |
- if (t & CERTDB_VALID_CA) { |
- return nssTrustLevel_ValidDelegator; |
- } |
- return nssTrustLevel_MustVerify; |
-} |
- |
-NSS_EXTERN NSSCertificate * |
-STAN_GetNSSCertificate(CERTCertificate *cc) |
-{ |
- NSSCertificate *c; |
- nssCryptokiInstance *instance; |
- nssPKIObject *pkiob; |
- NSSArena *arena; |
- c = cc->nssCertificate; |
- if (c) { |
- return c; |
- } |
- /* i don't think this should happen. but if it can, need to create |
- * NSSCertificate from CERTCertificate values here. */ |
- /* Yup, it can happen. */ |
- arena = NSSArena_Create(); |
- if (!arena) { |
- return NULL; |
- } |
- c = nss_ZNEW(arena, NSSCertificate); |
- if (!c) { |
- nssArena_Destroy(arena); |
- return NULL; |
- } |
- NSSITEM_FROM_SECITEM(&c->encoding, &cc->derCert); |
- c->type = NSSCertificateType_PKIX; |
- pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL, nssPKIMonitor); |
- if (!pkiob) { |
- nssArena_Destroy(arena); |
- return NULL; |
- } |
- c->object = *pkiob; |
- nssItem_Create(arena, |
- &c->issuer, cc->derIssuer.len, cc->derIssuer.data); |
- nssItem_Create(arena, |
- &c->subject, cc->derSubject.len, cc->derSubject.data); |
- if (PR_TRUE) { |
- /* CERTCertificate stores serial numbers decoded. I need the DER |
- * here. sigh. |
- */ |
- SECItem derSerial; |
- SECStatus secrv; |
- secrv = CERT_SerialNumberFromDERCert(&cc->derCert, &derSerial); |
- if (secrv == SECFailure) { |
- nssArena_Destroy(arena); |
- return NULL; |
- } |
- nssItem_Create(arena, &c->serial, derSerial.len, derSerial.data); |
- PORT_Free(derSerial.data); |
- } |
- if (cc->emailAddr && cc->emailAddr[0]) { |
- c->email = nssUTF8_Create(arena, |
- nssStringType_PrintableString, |
- (NSSUTF8 *)cc->emailAddr, |
- PORT_Strlen(cc->emailAddr)); |
- } |
- if (cc->slot) { |
- instance = nss_ZNEW(arena, nssCryptokiInstance); |
- if (!instance) { |
- nssArena_Destroy(arena); |
- return NULL; |
- } |
- instance->token = nssToken_AddRef(PK11Slot_GetNSSToken(cc->slot)); |
- instance->handle = cc->pkcs11ID; |
- instance->isTokenObject = PR_TRUE; |
- if (cc->nickname) { |
- instance->label = nssUTF8_Create(arena, |
- nssStringType_UTF8String, |
- (NSSUTF8 *)cc->nickname, |
- PORT_Strlen(cc->nickname)); |
- } |
- nssPKIObject_AddInstance(&c->object, instance); |
- } |
- c->decoding = create_decoded_pkix_cert_from_nss3cert(NULL, cc); |
- cc->nssCertificate = c; |
- return c; |
-} |
- |
-static NSSToken* |
-stan_GetTrustToken ( |
- NSSCertificate *c |
-) |
-{ |
- NSSToken *ttok = NULL; |
- NSSToken *rtok = NULL; |
- NSSToken *tok = NULL; |
- nssCryptokiObject **ip; |
- nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object); |
- if (!instances) { |
- return PR_FALSE; |
- } |
- for (ip = instances; *ip; ip++) { |
- nssCryptokiObject *instance = *ip; |
- nssCryptokiObject *to = |
- nssToken_FindTrustForCertificate(instance->token, NULL, |
- &c->encoding, &c->issuer, &c->serial, |
- nssTokenSearchType_TokenOnly); |
- NSSToken *ctok = instance->token; |
- PRBool ro = PK11_IsReadOnly(ctok->pk11slot); |
- |
- if (to) { |
- nssCryptokiObject_Destroy(to); |
- ttok = ctok; |
- if (!ro) { |
- break; |
- } |
- } else { |
- if (!rtok && ro) { |
- rtok = ctok; |
- } |
- if (!tok && !ro) { |
- tok = ctok; |
- } |
- } |
- } |
- nssCryptokiObjectArray_Destroy(instances); |
- return ttok ? ttok : (tok ? tok : rtok); |
-} |
- |
-NSS_EXTERN PRStatus |
-STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust) |
-{ |
- PRStatus nssrv; |
- NSSCertificate *c = STAN_GetNSSCertificate(cc); |
- NSSToken *tok; |
- NSSTrustDomain *td; |
- NSSTrust *nssTrust; |
- NSSArena *arena; |
- CERTCertTrust *oldTrust; |
- CERTCertTrust *newTrust; |
- nssListIterator *tokens; |
- PRBool moving_object; |
- nssCryptokiObject *newInstance; |
- nssPKIObject *pkiob; |
- |
- if (c == NULL) { |
- return PR_FAILURE; |
- } |
- oldTrust = nssTrust_GetCERTCertTrustForCert(c, cc); |
- if (oldTrust) { |
- if (memcmp(oldTrust, trust, sizeof (CERTCertTrust)) == 0) { |
- /* ... and the new trust is no different, done) */ |
- return PR_SUCCESS; |
- } else { |
- /* take over memory already allocated in cc's arena */ |
- newTrust = oldTrust; |
- } |
- } else { |
- newTrust = PORT_ArenaAlloc(cc->arena, sizeof(CERTCertTrust)); |
- } |
- memcpy(newTrust, trust, sizeof(CERTCertTrust)); |
- CERT_LockCertTrust(cc); |
- cc->trust = newTrust; |
- CERT_UnlockCertTrust(cc); |
- /* Set the NSSCerticate's trust */ |
- arena = nssArena_Create(); |
- if (!arena) return PR_FAILURE; |
- nssTrust = nss_ZNEW(arena, NSSTrust); |
- if (!nssTrust) { |
- nssArena_Destroy(arena); |
- return PR_FAILURE; |
- } |
- pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL, nssPKILock); |
- if (!pkiob) { |
- nssArena_Destroy(arena); |
- return PR_FAILURE; |
- } |
- nssTrust->object = *pkiob; |
- nssTrust->certificate = c; |
- nssTrust->serverAuth = get_stan_trust(trust->sslFlags, PR_FALSE); |
- nssTrust->clientAuth = get_stan_trust(trust->sslFlags, PR_TRUE); |
- nssTrust->emailProtection = get_stan_trust(trust->emailFlags, PR_FALSE); |
- nssTrust->codeSigning = get_stan_trust(trust->objectSigningFlags, PR_FALSE); |
- nssTrust->stepUpApproved = |
- (PRBool)(trust->sslFlags & CERTDB_GOVT_APPROVED_CA); |
- if (c->object.cryptoContext != NULL) { |
- /* The cert is in a context, set the trust there */ |
- NSSCryptoContext *cc = c->object.cryptoContext; |
- nssrv = nssCryptoContext_ImportTrust(cc, nssTrust); |
- if (nssrv != PR_SUCCESS) { |
- goto done; |
- } |
- if (c->object.numInstances == 0) { |
- /* The context is the only instance, finished */ |
- goto done; |
- } |
- } |
- td = STAN_GetDefaultTrustDomain(); |
- tok = stan_GetTrustToken(c); |
- moving_object = PR_FALSE; |
- if (tok && PK11_IsReadOnly(tok->pk11slot)) { |
- NSSRWLock_LockRead(td->tokensLock); |
- tokens = nssList_CreateIterator(td->tokenList); |
- if (!tokens) { |
- nssrv = PR_FAILURE; |
- NSSRWLock_UnlockRead(td->tokensLock); |
- goto done; |
- } |
- for (tok = (NSSToken *)nssListIterator_Start(tokens); |
- tok != (NSSToken *)NULL; |
- tok = (NSSToken *)nssListIterator_Next(tokens)) |
- { |
- if (!PK11_IsReadOnly(tok->pk11slot)) break; |
- } |
- nssListIterator_Finish(tokens); |
- nssListIterator_Destroy(tokens); |
- NSSRWLock_UnlockRead(td->tokensLock); |
- moving_object = PR_TRUE; |
- } |
- if (tok) { |
- if (moving_object) { |
- /* this is kind of hacky. the softoken needs the cert |
- * object in order to store trust. forcing it to be perm |
- */ |
- NSSUTF8 *nickname = nssCertificate_GetNickname(c, NULL); |
- NSSASCII7 *email = NULL; |
- |
- if (PK11_IsInternal(tok->pk11slot)) { |
- email = c->email; |
- } |
- newInstance = nssToken_ImportCertificate(tok, NULL, |
- NSSCertificateType_PKIX, |
- &c->id, |
- nickname, |
- &c->encoding, |
- &c->issuer, |
- &c->subject, |
- &c->serial, |
- email, |
- PR_TRUE); |
- nss_ZFreeIf(nickname); |
- nickname = NULL; |
- if (!newInstance) { |
- nssrv = PR_FAILURE; |
- goto done; |
- } |
- nssPKIObject_AddInstance(&c->object, newInstance); |
- } |
- newInstance = nssToken_ImportTrust(tok, NULL, &c->encoding, |
- &c->issuer, &c->serial, |
- nssTrust->serverAuth, |
- nssTrust->clientAuth, |
- nssTrust->codeSigning, |
- nssTrust->emailProtection, |
- nssTrust->stepUpApproved, PR_TRUE); |
- /* If the selected token can't handle trust, dump the trust on |
- * the internal token */ |
- if (!newInstance && !PK11_IsInternalKeySlot(tok->pk11slot)) { |
- PK11SlotInfo *slot = PK11_GetInternalKeySlot(); |
- NSSUTF8 *nickname = nssCertificate_GetNickname(c, NULL); |
- NSSASCII7 *email = c->email; |
- tok = PK11Slot_GetNSSToken(slot); |
- PK11_FreeSlot(slot); |
- |
- newInstance = nssToken_ImportCertificate(tok, NULL, |
- NSSCertificateType_PKIX, |
- &c->id, |
- nickname, |
- &c->encoding, |
- &c->issuer, |
- &c->subject, |
- &c->serial, |
- email, |
- PR_TRUE); |
- nss_ZFreeIf(nickname); |
- nickname = NULL; |
- if (!newInstance) { |
- nssrv = PR_FAILURE; |
- goto done; |
- } |
- nssPKIObject_AddInstance(&c->object, newInstance); |
- newInstance = nssToken_ImportTrust(tok, NULL, &c->encoding, |
- &c->issuer, &c->serial, |
- nssTrust->serverAuth, |
- nssTrust->clientAuth, |
- nssTrust->codeSigning, |
- nssTrust->emailProtection, |
- nssTrust->stepUpApproved, PR_TRUE); |
- } |
- if (newInstance) { |
- nssCryptokiObject_Destroy(newInstance); |
- nssrv = PR_SUCCESS; |
- } else { |
- nssrv = PR_FAILURE; |
- } |
- } else { |
- nssrv = PR_FAILURE; |
- } |
-done: |
- (void)nssTrust_Destroy(nssTrust); |
- return nssrv; |
-} |
- |
-/* |
-** Delete trust objects matching the given slot. |
-** Returns error if a device fails to delete. |
-** |
-** This function has the side effect of moving the |
-** surviving entries to the front of the object list |
-** and nullifying the rest. |
-*/ |
-static PRStatus |
-DeleteCertTrustMatchingSlot(PK11SlotInfo *pk11slot, nssPKIObject *tObject) |
-{ |
- int numNotDestroyed = 0; /* the ones skipped plus the failures */ |
- int failureCount = 0; /* actual deletion failures by devices */ |
- int index; |
- |
- nssPKIObject_Lock(tObject); |
- /* Keep going even if a module fails to delete. */ |
- for (index = 0; index < tObject->numInstances; index++) { |
- nssCryptokiObject *instance = tObject->instances[index]; |
- if (!instance) { |
- continue; |
- } |
- |
- /* ReadOnly and not matched treated the same */ |
- if (PK11_IsReadOnly(instance->token->pk11slot) || |
- pk11slot != instance->token->pk11slot) { |
- tObject->instances[numNotDestroyed++] = instance; |
- continue; |
- } |
- |
- /* Here we have found a matching one */ |
- tObject->instances[index] = NULL; |
- if (nssToken_DeleteStoredObject(instance) == PR_SUCCESS) { |
- nssCryptokiObject_Destroy(instance); |
- } else { |
- tObject->instances[numNotDestroyed++] = instance; |
- failureCount++; |
- } |
- |
- } |
- if (numNotDestroyed == 0) { |
- nss_ZFreeIf(tObject->instances); |
- tObject->numInstances = 0; |
- } else { |
- tObject->numInstances = numNotDestroyed; |
- } |
- |
- nssPKIObject_Unlock(tObject); |
- |
- return failureCount == 0 ? PR_SUCCESS : PR_FAILURE; |
-} |
- |
-/* |
-** Delete trust objects matching the slot of the given certificate. |
-** Returns an error if any device fails to delete. |
-*/ |
-NSS_EXTERN PRStatus |
-STAN_DeleteCertTrustMatchingSlot(NSSCertificate *c) |
-{ |
- PRStatus nssrv = PR_SUCCESS; |
- |
- NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); |
- NSSTrust *nssTrust = nssTrustDomain_FindTrustForCertificate(td, c); |
- /* caller made sure nssTrust isn't NULL */ |
- nssPKIObject *tobject = &nssTrust->object; |
- nssPKIObject *cobject = &c->object; |
- int i; |
- |
- /* Iterate through the cert and trust object instances looking for |
- * those with matching pk11 slots to delete. Even if some device |
- * can't delete we keep going. Keeping a status variable for the |
- * loop so that once it's failed the other gets set. |
- */ |
- NSSRWLock_LockRead(td->tokensLock); |
- nssPKIObject_Lock(cobject); |
- for (i = 0; i < cobject->numInstances; i++) { |
- nssCryptokiObject *cInstance = cobject->instances[i]; |
- if (cInstance && !PK11_IsReadOnly(cInstance->token->pk11slot)) { |
- PRStatus status; |
- if (!tobject->numInstances || !tobject->instances) continue; |
- status = DeleteCertTrustMatchingSlot(cInstance->token->pk11slot, tobject); |
- if (status == PR_FAILURE) { |
- /* set the outer one but keep going */ |
- nssrv = PR_FAILURE; |
- } |
- } |
- } |
- nssPKIObject_Unlock(cobject); |
- NSSRWLock_UnlockRead(td->tokensLock); |
- return nssrv; |
-} |
- |
-/* CERT_TraversePermCertsForSubject */ |
-NSS_IMPLEMENT PRStatus |
-nssTrustDomain_TraverseCertificatesBySubject ( |
- NSSTrustDomain *td, |
- NSSDER *subject, |
- PRStatus (*callback)(NSSCertificate *c, void *arg), |
- void *arg |
-) |
-{ |
- PRStatus nssrv = PR_SUCCESS; |
- NSSArena *tmpArena; |
- NSSCertificate **subjectCerts; |
- NSSCertificate *c; |
- PRIntn i; |
- tmpArena = NSSArena_Create(); |
- if (!tmpArena) { |
- return PR_FAILURE; |
- } |
- subjectCerts = NSSTrustDomain_FindCertificatesBySubject(td, subject, NULL, |
- 0, tmpArena); |
- if (subjectCerts) { |
- for (i=0, c = subjectCerts[i]; c; i++) { |
- nssrv = callback(c, arg); |
- if (nssrv != PR_SUCCESS) break; |
- } |
- } |
- nssArena_Destroy(tmpArena); |
- return nssrv; |
-} |
- |
-/* CERT_TraversePermCertsForNickname */ |
-NSS_IMPLEMENT PRStatus |
-nssTrustDomain_TraverseCertificatesByNickname ( |
- NSSTrustDomain *td, |
- NSSUTF8 *nickname, |
- PRStatus (*callback)(NSSCertificate *c, void *arg), |
- void *arg |
-) |
-{ |
- PRStatus nssrv = PR_SUCCESS; |
- NSSArena *tmpArena; |
- NSSCertificate **nickCerts; |
- NSSCertificate *c; |
- PRIntn i; |
- tmpArena = NSSArena_Create(); |
- if (!tmpArena) { |
- return PR_FAILURE; |
- } |
- nickCerts = NSSTrustDomain_FindCertificatesByNickname(td, nickname, NULL, |
- 0, tmpArena); |
- if (nickCerts) { |
- for (i=0, c = nickCerts[i]; c; i++) { |
- nssrv = callback(c, arg); |
- if (nssrv != PR_SUCCESS) break; |
- } |
- } |
- nssArena_Destroy(tmpArena); |
- return nssrv; |
-} |
- |
-static void cert_dump_iter(const void *k, void *v, void *a) |
-{ |
- NSSCertificate *c = (NSSCertificate *)k; |
- CERTCertificate *cert = STAN_GetCERTCertificate(c); |
- printf("[%2d] \"%s\"\n", c->object.refCount, cert->subjectName); |
-} |
- |
-void |
-nss_DumpCertificateCacheInfo() |
-{ |
- NSSTrustDomain *td; |
- NSSCryptoContext *cc; |
- td = STAN_GetDefaultTrustDomain(); |
- cc = STAN_GetDefaultCryptoContext(); |
- printf("\n\nCertificates in the cache:\n"); |
- nssTrustDomain_DumpCacheInfo(td, cert_dump_iter, NULL); |
- printf("\n\nCertificates in the temporary store:\n"); |
- if (cc->certStore) { |
- nssCertificateStore_DumpStoreInfo(cc->certStore, cert_dump_iter, NULL); |
- } |
-} |
- |