/* * delete a crl. */ SECStatus SEC_DeletePermCRL(CERTSignedCrl *crl) { PRStatus status; NSSToken *token; nssCryptokiObject *object; PK11SlotInfo *slot = crl->slot; if (slot == NULL) { PORT_Assert(slot); /* shouldn't happen */ PORT_SetError( SEC_ERROR_CRL_INVALID); return SECFailure; } token = PK11Slot_GetNSSToken(slot); object = nss_ZNEW(NULL, nssCryptokiObject); if (!object) { return SECFailure; } object->token = nssToken_AddRef(token); object->handle = crl->pkcs11ID; object->isTokenObject = PR_TRUE; status = nssToken_DeleteStoredObject(object); nssCryptokiObject_Destroy(object); return (status == PR_SUCCESS) ? SECSuccess : SECFailure; }
CK_OBJECT_HANDLE PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, SECItem *name, char *url, int type) { NSSItem derCRL, derSubject; NSSToken *token = PK11Slot_GetNSSToken(slot); nssCryptokiObject *object; PRBool isKRL = (type == SEC_CRL_TYPE) ? PR_FALSE : PR_TRUE; CK_OBJECT_HANDLE rvH; NSSITEM_FROM_SECITEM(&derSubject, name); NSSITEM_FROM_SECITEM(&derCRL, crl); object = nssToken_ImportCRL(token, NULL, &derSubject, &derCRL, isKRL, url, PR_TRUE); if (object) { rvH = object->handle; nssCryptokiObject_Destroy(object); } else { rvH = CK_INVALID_HANDLE; PORT_SetError(SEC_ERROR_CRL_IMPORT_FAILED); } return rvH; }
/* * 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(); for (i = 0; i < module->slotCount; i++) { token = PK11Slot_GetNSSToken(module->slots[i]); if (token) { nssToken_NotifyCertsNotVisible(token); NSSRWLock_LockWrite(td->tokensLock); nssList_Remove(td->tokenList, token); NSSRWLock_UnlockWrite(td->tokensLock); PK11Slot_SetNSSToken(module->slots[i], NULL); nssToken_Destroy(token); } } NSSRWLock_LockWrite(td->tokensLock); nssListIterator_Destroy(td->tokens); td->tokens = nssList_CreateIterator(td->tokenList); NSSRWLock_UnlockWrite(td->tokensLock); return SECSuccess; }
static void md5_hash(NSSItem *input, NSSItem *output) { NSSAlgorithmAndParameters *ap; PK11SlotInfo *internal = PK11_GetInternalSlot(); NSSToken *token = PK11Slot_GetNSSToken(internal); ap = NSSAlgorithmAndParameters_CreateMD5Digest(NULL); (void)nssToken_Digest(token, NULL, ap, input, output, NULL); PK11_FreeSlot(token->pk11slot); nss_ZFreeIf(ap); }
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; }
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; }
/* * return the crl associated with a derSubjectName */ SECItem * PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle, SECItem *name, int type, char **pUrl) { NSSCRL **crls, **crlp, *crl = NULL; NSSDER subject; SECItem *rvItem; NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); char * url = NULL; PORT_SetError(0); NSSITEM_FROM_SECITEM(&subject, name); if (*slot) { nssCryptokiObject **instances; nssPKIObjectCollection *collection; nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; NSSToken *token = PK11Slot_GetNSSToken(*slot); collection = nssCRLCollection_Create(td, NULL); if (!collection) { goto loser; } instances = nssToken_FindCRLsBySubject(token, NULL, &subject, tokenOnly, 0, NULL); nssPKIObjectCollection_AddInstances(collection, instances, 0); nss_ZFreeIf(instances); crls = nssPKIObjectCollection_GetCRLs(collection, NULL, 0, NULL); nssPKIObjectCollection_Destroy(collection); } else { crls = nssTrustDomain_FindCRLsBySubject(td, &subject); } if ((!crls) || (*crls == NULL)) { if (crls) { nssCRLArray_Destroy(crls); } if (NSS_GetError() == NSS_ERROR_NOT_FOUND) { PORT_SetError(SEC_ERROR_CRL_NOT_FOUND); } goto loser; } for (crlp = crls; *crlp; crlp++) { if ((!(*crlp)->isKRL && type == SEC_CRL_TYPE) || ((*crlp)->isKRL && type != SEC_CRL_TYPE)) { crl = nssCRL_AddRef(*crlp); break; } } nssCRLArray_Destroy(crls); if (!crl) { /* CRL collection was found, but no interesting CRL's were on it. * Not an error */ PORT_SetError(SEC_ERROR_CRL_NOT_FOUND); goto loser; } if (crl->url) { url = PORT_Strdup(crl->url); if (!url) { goto loser; } } rvItem = SECITEM_AllocItem(NULL, NULL, crl->encoding.size); if (!rvItem) { goto loser; } memcpy(rvItem->data, crl->encoding.data, crl->encoding.size); *slot = PK11_ReferenceSlot(crl->object.instances[0]->token->pk11slot); *crlHandle = crl->object.instances[0]->handle; *pUrl = url; nssCRL_Destroy(crl); return rvItem; loser: if (url) PORT_Free(url); if (crl) nssCRL_Destroy(crl); if (PORT_GetError() == 0) { PORT_SetError(SEC_ERROR_CRL_NOT_FOUND); } return NULL; }
SECStatus __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, CERTCertTrust *trust) { NSSUTF8 *stanNick; PK11SlotInfo *slot; NSSToken *internal; NSSCryptoContext *context; nssCryptokiObject *permInstance; NSSCertificate *c = STAN_GetNSSCertificate(cert); nssCertificateStoreTrace lockTrace = { NULL, NULL, PR_FALSE, PR_FALSE }; nssCertificateStoreTrace unlockTrace = { NULL, NULL, PR_FALSE, PR_FALSE }; SECStatus rv; PRStatus ret; if (c == NULL) { CERT_MapStanError(); return SECFailure; } context = c->object.cryptoContext; if (!context) { PORT_SetError(SEC_ERROR_ADDING_CERT); return SECFailure; /* wasn't a temp cert */ } stanNick = nssCertificate_GetNickname(c, NULL); if (stanNick && nickname && strcmp(nickname, stanNick) != 0) { /* different: take the new nickname */ cert->nickname = NULL; nss_ZFreeIf(stanNick); stanNick = NULL; } if (!stanNick && nickname) { /* Either there was no nickname yet, or we have a new nickname */ stanNick = nssUTF8_Duplicate((NSSUTF8 *)nickname, NULL); } /* else: old stanNick is identical to new nickname */ /* Delete the temp instance */ nssCertificateStore_Lock(context->certStore, &lockTrace); nssCertificateStore_RemoveCertLOCKED(context->certStore, c); nssCertificateStore_Unlock(context->certStore, &lockTrace, &unlockTrace); c->object.cryptoContext = NULL; /* Import the perm instance onto the internal token */ slot = PK11_GetInternalKeySlot(); internal = PK11Slot_GetNSSToken(slot); permInstance = nssToken_ImportCertificate( internal, NULL, NSSCertificateType_PKIX, &c->id, stanNick, &c->encoding, &c->issuer, &c->subject, &c->serial, cert->emailAddr, PR_TRUE); nss_ZFreeIf(stanNick); stanNick = NULL; PK11_FreeSlot(slot); if (!permInstance) { if (NSS_GetError() == NSS_ERROR_INVALID_CERTIFICATE) { PORT_SetError(SEC_ERROR_REUSED_ISSUER_AND_SERIAL); } return SECFailure; } nssPKIObject_AddInstance(&c->object, permInstance); nssTrustDomain_AddCertsToCache(STAN_GetDefaultTrustDomain(), &c, 1); /* reset the CERTCertificate fields */ cert->nssCertificate = NULL; cert = STAN_GetCERTCertificateOrRelease(c); /* should return same pointer */ if (!cert) { CERT_MapStanError(); return SECFailure; } cert->istemp = PR_FALSE; cert->isperm = PR_TRUE; if (!trust) { return SECSuccess; } ret = STAN_ChangeCertTrust(cert, trust); rv = SECSuccess; if (ret != PR_SUCCESS) { rv = SECFailure; CERT_MapStanError(); } return rv; }