Index: mozilla/security/nss/lib/pki/certificate.c |
=================================================================== |
--- mozilla/security/nss/lib/pki/certificate.c (revision 191424) |
+++ mozilla/security/nss/lib/pki/certificate.c (working copy) |
@@ -1,1176 +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: certificate.c,v $ $Revision: 1.70 $ $Date: 2012/05/17 21:39:40 $"; |
-#endif /* DEBUG */ |
- |
-#ifndef NSSPKI_H |
-#include "nsspki.h" |
-#endif /* NSSPKI_H */ |
- |
-#ifndef PKIT_H |
-#include "pkit.h" |
-#endif /* PKIT_H */ |
- |
-#ifndef PKIM_H |
-#include "pkim.h" |
-#endif /* PKIM_H */ |
- |
-#ifndef DEV_H |
-#include "dev.h" |
-#endif /* DEV_H */ |
- |
-#include "pkistore.h" |
- |
-#include "pki3hack.h" |
-#include "pk11func.h" |
-#include "hasht.h" |
- |
-#ifndef BASE_H |
-#include "base.h" |
-#endif /* BASE_H */ |
- |
-extern const NSSError NSS_ERROR_NOT_FOUND; |
- |
-/* Creates a certificate from a base object */ |
-NSS_IMPLEMENT NSSCertificate * |
-nssCertificate_Create ( |
- nssPKIObject *object |
-) |
-{ |
- PRStatus status; |
- NSSCertificate *rvCert; |
- nssArenaMark * mark; |
- NSSArena *arena = object->arena; |
- PR_ASSERT(object->instances != NULL && object->numInstances > 0); |
- PR_ASSERT(object->lockType == nssPKIMonitor); |
- mark = nssArena_Mark(arena); |
- rvCert = nss_ZNEW(arena, NSSCertificate); |
- if (!rvCert) { |
- return (NSSCertificate *)NULL; |
- } |
- rvCert->object = *object; |
- /* XXX should choose instance based on some criteria */ |
- status = nssCryptokiCertificate_GetAttributes(object->instances[0], |
- NULL, /* XXX sessionOpt */ |
- arena, |
- &rvCert->type, |
- &rvCert->id, |
- &rvCert->encoding, |
- &rvCert->issuer, |
- &rvCert->serial, |
- &rvCert->subject); |
- if (status != PR_SUCCESS || |
- !rvCert->encoding.data || |
- !rvCert->encoding.size || |
- !rvCert->issuer.data || |
- !rvCert->issuer.size || |
- !rvCert->serial.data || |
- !rvCert->serial.size) { |
- if (mark) |
- nssArena_Release(arena, mark); |
- return (NSSCertificate *)NULL; |
- } |
- if (mark) |
- nssArena_Unmark(arena, mark); |
- return rvCert; |
-} |
- |
-NSS_IMPLEMENT NSSCertificate * |
-nssCertificate_AddRef ( |
- NSSCertificate *c |
-) |
-{ |
- if (c) { |
- nssPKIObject_AddRef(&c->object); |
- } |
- return c; |
-} |
- |
-NSS_IMPLEMENT PRStatus |
-nssCertificate_Destroy ( |
- NSSCertificate *c |
-) |
-{ |
- nssCertificateStoreTrace lockTrace = {NULL, NULL, PR_FALSE, PR_FALSE}; |
- nssCertificateStoreTrace unlockTrace = {NULL, NULL, PR_FALSE, PR_FALSE}; |
- |
- if (c) { |
- PRUint32 i; |
- nssDecodedCert *dc = c->decoding; |
- NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); |
- NSSCryptoContext *cc = c->object.cryptoContext; |
- |
- PR_ASSERT(c->object.refCount > 0); |
- |
- /* --- LOCK storage --- */ |
- if (cc) { |
- nssCertificateStore_Lock(cc->certStore, &lockTrace); |
- } else { |
- nssTrustDomain_LockCertCache(td); |
- } |
- if (PR_ATOMIC_DECREMENT(&c->object.refCount) == 0) { |
- /* --- remove cert and UNLOCK storage --- */ |
- if (cc) { |
- nssCertificateStore_RemoveCertLOCKED(cc->certStore, c); |
- nssCertificateStore_Unlock(cc->certStore, &lockTrace, |
- &unlockTrace); |
- } else { |
- nssTrustDomain_RemoveCertFromCacheLOCKED(td, c); |
- nssTrustDomain_UnlockCertCache(td); |
- } |
- /* free cert data */ |
- for (i=0; i<c->object.numInstances; i++) { |
- nssCryptokiObject_Destroy(c->object.instances[i]); |
- } |
- nssPKIObject_DestroyLock(&c->object); |
- nssArena_Destroy(c->object.arena); |
- nssDecodedCert_Destroy(dc); |
- } else { |
- /* --- UNLOCK storage --- */ |
- if (cc) { |
- nssCertificateStore_Unlock(cc->certStore, |
- &lockTrace, |
- &unlockTrace); |
- } else { |
- nssTrustDomain_UnlockCertCache(td); |
- } |
- } |
- } |
- return PR_SUCCESS; |
-} |
- |
-NSS_IMPLEMENT PRStatus |
-NSSCertificate_Destroy ( |
- NSSCertificate *c |
-) |
-{ |
- return nssCertificate_Destroy(c); |
-} |
- |
-NSS_IMPLEMENT NSSDER * |
-nssCertificate_GetEncoding ( |
- NSSCertificate *c |
-) |
-{ |
- if (c->encoding.size > 0 && c->encoding.data) { |
- return &c->encoding; |
- } else { |
- return (NSSDER *)NULL; |
- } |
-} |
- |
-NSS_IMPLEMENT NSSDER * |
-nssCertificate_GetIssuer ( |
- NSSCertificate *c |
-) |
-{ |
- if (c->issuer.size > 0 && c->issuer.data) { |
- return &c->issuer; |
- } else { |
- return (NSSDER *)NULL; |
- } |
-} |
- |
-NSS_IMPLEMENT NSSDER * |
-nssCertificate_GetSerialNumber ( |
- NSSCertificate *c |
-) |
-{ |
- if (c->serial.size > 0 && c->serial.data) { |
- return &c->serial; |
- } else { |
- return (NSSDER *)NULL; |
- } |
-} |
- |
-NSS_IMPLEMENT NSSDER * |
-nssCertificate_GetSubject ( |
- NSSCertificate *c |
-) |
-{ |
- if (c->subject.size > 0 && c->subject.data) { |
- return &c->subject; |
- } else { |
- return (NSSDER *)NULL; |
- } |
-} |
- |
-/* Returns a copy, Caller must free using nss_ZFreeIf */ |
-NSS_IMPLEMENT NSSUTF8 * |
-nssCertificate_GetNickname ( |
- NSSCertificate *c, |
- NSSToken *tokenOpt |
-) |
-{ |
- return nssPKIObject_GetNicknameForToken(&c->object, tokenOpt); |
-} |
- |
-NSS_IMPLEMENT NSSASCII7 * |
-nssCertificate_GetEmailAddress ( |
- NSSCertificate *c |
-) |
-{ |
- return c->email; |
-} |
- |
-NSS_IMPLEMENT PRStatus |
-NSSCertificate_DeleteStoredObject ( |
- NSSCertificate *c, |
- NSSCallback *uhh |
-) |
-{ |
- return nssPKIObject_DeleteStoredObject(&c->object, uhh, PR_TRUE); |
-} |
- |
-NSS_IMPLEMENT PRStatus |
-NSSCertificate_Validate ( |
- NSSCertificate *c, |
- NSSTime *timeOpt, /* NULL for "now" */ |
- NSSUsage *usage, |
- NSSPolicies *policiesOpt /* NULL for none */ |
-) |
-{ |
- nss_SetError(NSS_ERROR_NOT_FOUND); |
- return PR_FAILURE; |
-} |
- |
-NSS_IMPLEMENT void ** /* void *[] */ |
-NSSCertificate_ValidateCompletely ( |
- NSSCertificate *c, |
- NSSTime *timeOpt, /* NULL for "now" */ |
- NSSUsage *usage, |
- NSSPolicies *policiesOpt, /* NULL for none */ |
- void **rvOpt, /* NULL for allocate */ |
- PRUint32 rvLimit, /* zero for no limit */ |
- NSSArena *arenaOpt /* NULL for heap */ |
-) |
-{ |
- nss_SetError(NSS_ERROR_NOT_FOUND); |
- return NULL; |
-} |
- |
-NSS_IMPLEMENT PRStatus |
-NSSCertificate_ValidateAndDiscoverUsagesAndPolicies ( |
- NSSCertificate *c, |
- NSSTime **notBeforeOutOpt, |
- NSSTime **notAfterOutOpt, |
- void *allowedUsages, |
- void *disallowedUsages, |
- void *allowedPolicies, |
- void *disallowedPolicies, |
- /* more args.. work on this fgmr */ |
- NSSArena *arenaOpt |
-) |
-{ |
- nss_SetError(NSS_ERROR_NOT_FOUND); |
- return PR_FAILURE; |
-} |
- |
-NSS_IMPLEMENT NSSDER * |
-NSSCertificate_Encode ( |
- NSSCertificate *c, |
- NSSDER *rvOpt, |
- NSSArena *arenaOpt |
-) |
-{ |
- /* Item, DER, BER are all typedefs now... */ |
- return nssItem_Duplicate((NSSItem *)&c->encoding, arenaOpt, rvOpt); |
-} |
- |
-NSS_IMPLEMENT nssDecodedCert * |
-nssCertificate_GetDecoding ( |
- NSSCertificate *c |
-) |
-{ |
- nssDecodedCert* deco = NULL; |
- if (c->type == NSSCertificateType_PKIX) { |
- (void)STAN_GetCERTCertificate(c); |
- } |
- nssPKIObject_Lock(&c->object); |
- if (!c->decoding) { |
- deco = nssDecodedCert_Create(NULL, &c->encoding, c->type); |
- PORT_Assert(!c->decoding); |
- c->decoding = deco; |
- } else { |
- deco = c->decoding; |
- } |
- nssPKIObject_Unlock(&c->object); |
- return deco; |
-} |
- |
-static NSSCertificate ** |
-filter_subject_certs_for_id ( |
- NSSCertificate **subjectCerts, |
- void *id |
-) |
-{ |
- NSSCertificate **si; |
- nssDecodedCert *dcp; |
- int nextOpenSlot = 0; |
- int i; |
- nssCertIDMatch matchLevel = nssCertIDMatch_Unknown; |
- nssCertIDMatch match; |
- |
- /* walk the subject certs */ |
- for (si = subjectCerts; *si; si++) { |
- dcp = nssCertificate_GetDecoding(*si); |
- if (!dcp) { |
- NSSCertificate_Destroy(*si); |
- continue; |
- } |
- match = dcp->matchIdentifier(dcp, id); |
- switch (match) { |
- case nssCertIDMatch_Yes: |
- if (matchLevel == nssCertIDMatch_Unknown) { |
- /* we have non-definitive matches, forget them */ |
- for (i = 0; i < nextOpenSlot; i++) { |
- NSSCertificate_Destroy(subjectCerts[i]); |
- subjectCerts[i] = NULL; |
- } |
- nextOpenSlot = 0; |
- /* only keep definitive matches from now on */ |
- matchLevel = nssCertIDMatch_Yes; |
- } |
- /* keep the cert */ |
- subjectCerts[nextOpenSlot++] = *si; |
- break; |
- case nssCertIDMatch_Unknown: |
- if (matchLevel == nssCertIDMatch_Unknown) { |
- /* only have non-definitive matches so far, keep it */ |
- subjectCerts[nextOpenSlot++] = *si; |
- break; |
- } |
- /* else fall through, we have a definitive match already */ |
- case nssCertIDMatch_No: |
- default: |
- NSSCertificate_Destroy(*si); |
- *si = NULL; |
- } |
- } |
- subjectCerts[nextOpenSlot] = NULL; |
- return subjectCerts; |
-} |
- |
-static NSSCertificate ** |
-filter_certs_for_valid_issuers ( |
- NSSCertificate **certs |
-) |
-{ |
- NSSCertificate **cp; |
- nssDecodedCert *dcp; |
- int nextOpenSlot = 0; |
- |
- for (cp = certs; *cp; cp++) { |
- dcp = nssCertificate_GetDecoding(*cp); |
- if (dcp && dcp->isValidIssuer(dcp)) { |
- certs[nextOpenSlot++] = *cp; |
- } else { |
- NSSCertificate_Destroy(*cp); |
- } |
- } |
- certs[nextOpenSlot] = NULL; |
- return certs; |
-} |
- |
-static NSSCertificate * |
-find_cert_issuer ( |
- NSSCertificate *c, |
- NSSTime *timeOpt, |
- NSSUsage *usage, |
- NSSPolicies *policiesOpt, |
- NSSTrustDomain *td, |
- NSSCryptoContext *cc |
-) |
-{ |
- NSSArena *arena; |
- NSSCertificate **certs = NULL; |
- NSSCertificate **ccIssuers = NULL; |
- NSSCertificate **tdIssuers = NULL; |
- NSSCertificate *issuer = NULL; |
- |
- if (!cc) |
- cc = c->object.cryptoContext; |
- if (!td) |
- td = NSSCertificate_GetTrustDomain(c); |
- arena = nssArena_Create(); |
- if (!arena) { |
- return (NSSCertificate *)NULL; |
- } |
- if (cc) { |
- ccIssuers = nssCryptoContext_FindCertificatesBySubject(cc, |
- &c->issuer, |
- NULL, |
- 0, |
- arena); |
- } |
- if (td) |
- tdIssuers = nssTrustDomain_FindCertificatesBySubject(td, |
- &c->issuer, |
- NULL, |
- 0, |
- arena); |
- certs = nssCertificateArray_Join(ccIssuers, tdIssuers); |
- if (certs) { |
- nssDecodedCert *dc = NULL; |
- void *issuerID = NULL; |
- dc = nssCertificate_GetDecoding(c); |
- if (dc) { |
- issuerID = dc->getIssuerIdentifier(dc); |
- } |
- /* XXX review based on CERT_FindCertIssuer |
- * this function is not using the authCertIssuer field as a fallback |
- * if authority key id does not exist |
- */ |
- if (issuerID) { |
- certs = filter_subject_certs_for_id(certs, issuerID); |
- } |
- certs = filter_certs_for_valid_issuers(certs); |
- issuer = nssCertificateArray_FindBestCertificate(certs, |
- timeOpt, |
- usage, |
- policiesOpt); |
- nssCertificateArray_Destroy(certs); |
- } |
- nssArena_Destroy(arena); |
- return issuer; |
-} |
- |
-/* This function returns the built chain, as far as it gets, |
-** even if/when it fails to find an issuer, and returns PR_FAILURE |
-*/ |
-NSS_IMPLEMENT NSSCertificate ** |
-nssCertificate_BuildChain ( |
- NSSCertificate *c, |
- NSSTime *timeOpt, |
- NSSUsage *usage, |
- NSSPolicies *policiesOpt, |
- NSSCertificate **rvOpt, |
- PRUint32 rvLimit, |
- NSSArena *arenaOpt, |
- PRStatus *statusOpt, |
- NSSTrustDomain *td, |
- NSSCryptoContext *cc |
-) |
-{ |
- NSSCertificate **rvChain = NULL; |
- NSSUsage issuerUsage = *usage; |
- nssPKIObjectCollection *collection = NULL; |
- PRUint32 rvCount = 0; |
- PRStatus st; |
- PRStatus ret = PR_SUCCESS; |
- |
- if (!c || !cc || |
- (!td && (td = NSSCertificate_GetTrustDomain(c)) == NULL)) { |
- goto loser; |
- } |
- /* bump the usage up to CA level */ |
- issuerUsage.nss3lookingForCA = PR_TRUE; |
- collection = nssCertificateCollection_Create(td, NULL); |
- if (!collection) |
- goto loser; |
- st = nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c); |
- if (st != PR_SUCCESS) |
- goto loser; |
- for (rvCount = 1; (!rvLimit || rvCount < rvLimit); ++rvCount) { |
- CERTCertificate *cCert = STAN_GetCERTCertificate(c); |
- if (cCert->isRoot) { |
- /* not including the issuer of the self-signed cert, which is, |
- * of course, itself |
- */ |
- break; |
- } |
- c = find_cert_issuer(c, timeOpt, &issuerUsage, policiesOpt, td, cc); |
- if (!c) { |
- ret = PR_FAILURE; |
- break; |
- } |
- st = nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c); |
- nssCertificate_Destroy(c); /* collection has it */ |
- if (st != PR_SUCCESS) |
- goto loser; |
- } |
- rvChain = nssPKIObjectCollection_GetCertificates(collection, |
- rvOpt, |
- rvLimit, |
- arenaOpt); |
- if (rvChain) { |
- nssPKIObjectCollection_Destroy(collection); |
- if (statusOpt) |
- *statusOpt = ret; |
- if (ret != PR_SUCCESS) |
- nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND); |
- return rvChain; |
- } |
- |
-loser: |
- if (collection) |
- nssPKIObjectCollection_Destroy(collection); |
- if (statusOpt) |
- *statusOpt = PR_FAILURE; |
- nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND); |
- return rvChain; |
-} |
- |
-NSS_IMPLEMENT NSSCertificate ** |
-NSSCertificate_BuildChain ( |
- NSSCertificate *c, |
- NSSTime *timeOpt, |
- NSSUsage *usage, |
- NSSPolicies *policiesOpt, |
- NSSCertificate **rvOpt, |
- PRUint32 rvLimit, /* zero for no limit */ |
- NSSArena *arenaOpt, |
- PRStatus *statusOpt, |
- NSSTrustDomain *td, |
- NSSCryptoContext *cc |
-) |
-{ |
- return nssCertificate_BuildChain(c, timeOpt, usage, policiesOpt, |
- rvOpt, rvLimit, arenaOpt, statusOpt, |
- td, cc); |
-} |
- |
-NSS_IMPLEMENT NSSCryptoContext * |
-nssCertificate_GetCryptoContext ( |
- NSSCertificate *c |
-) |
-{ |
- return c->object.cryptoContext; |
-} |
- |
-NSS_IMPLEMENT NSSTrustDomain * |
-nssCertificate_GetTrustDomain ( |
- NSSCertificate *c |
-) |
-{ |
- return c->object.trustDomain; |
-} |
- |
-NSS_IMPLEMENT NSSTrustDomain * |
-NSSCertificate_GetTrustDomain ( |
- NSSCertificate *c |
-) |
-{ |
- return nssCertificate_GetTrustDomain(c); |
-} |
- |
-NSS_IMPLEMENT NSSToken * |
-NSSCertificate_GetToken ( |
- NSSCertificate *c, |
- PRStatus *statusOpt |
-) |
-{ |
- return (NSSToken *)NULL; |
-} |
- |
-NSS_IMPLEMENT NSSSlot * |
-NSSCertificate_GetSlot ( |
- NSSCertificate *c, |
- PRStatus *statusOpt |
-) |
-{ |
- return (NSSSlot *)NULL; |
-} |
- |
-NSS_IMPLEMENT NSSModule * |
-NSSCertificate_GetModule ( |
- NSSCertificate *c, |
- PRStatus *statusOpt |
-) |
-{ |
- return (NSSModule *)NULL; |
-} |
- |
-NSS_IMPLEMENT NSSItem * |
-NSSCertificate_Encrypt ( |
- NSSCertificate *c, |
- NSSAlgorithmAndParameters *apOpt, |
- NSSItem *data, |
- NSSTime *timeOpt, |
- NSSUsage *usage, |
- NSSPolicies *policiesOpt, |
- NSSCallback *uhh, |
- NSSItem *rvOpt, |
- NSSArena *arenaOpt |
-) |
-{ |
- nss_SetError(NSS_ERROR_NOT_FOUND); |
- return NULL; |
-} |
- |
-NSS_IMPLEMENT PRStatus |
-NSSCertificate_Verify ( |
- NSSCertificate *c, |
- NSSAlgorithmAndParameters *apOpt, |
- NSSItem *data, |
- NSSItem *signature, |
- NSSTime *timeOpt, |
- NSSUsage *usage, |
- NSSPolicies *policiesOpt, |
- NSSCallback *uhh |
-) |
-{ |
- nss_SetError(NSS_ERROR_NOT_FOUND); |
- return PR_FAILURE; |
-} |
- |
-NSS_IMPLEMENT NSSItem * |
-NSSCertificate_VerifyRecover ( |
- NSSCertificate *c, |
- NSSAlgorithmAndParameters *apOpt, |
- NSSItem *signature, |
- NSSTime *timeOpt, |
- NSSUsage *usage, |
- NSSPolicies *policiesOpt, |
- NSSCallback *uhh, |
- NSSItem *rvOpt, |
- NSSArena *arenaOpt |
-) |
-{ |
- nss_SetError(NSS_ERROR_NOT_FOUND); |
- return NULL; |
-} |
- |
-NSS_IMPLEMENT NSSItem * |
-NSSCertificate_WrapSymmetricKey ( |
- NSSCertificate *c, |
- NSSAlgorithmAndParameters *apOpt, |
- NSSSymmetricKey *keyToWrap, |
- NSSTime *timeOpt, |
- NSSUsage *usage, |
- NSSPolicies *policiesOpt, |
- NSSCallback *uhh, |
- NSSItem *rvOpt, |
- NSSArena *arenaOpt |
-) |
-{ |
- nss_SetError(NSS_ERROR_NOT_FOUND); |
- return NULL; |
-} |
- |
-NSS_IMPLEMENT NSSCryptoContext * |
-NSSCertificate_CreateCryptoContext ( |
- NSSCertificate *c, |
- NSSAlgorithmAndParameters *apOpt, |
- NSSTime *timeOpt, |
- NSSUsage *usage, |
- NSSPolicies *policiesOpt, |
- NSSCallback *uhh |
-) |
-{ |
- nss_SetError(NSS_ERROR_NOT_FOUND); |
- return NULL; |
-} |
- |
-NSS_IMPLEMENT NSSPublicKey * |
-NSSCertificate_GetPublicKey ( |
- NSSCertificate *c |
-) |
-{ |
-#if 0 |
- CK_ATTRIBUTE pubktemplate[] = { |
- { CKA_CLASS, NULL, 0 }, |
- { CKA_ID, NULL, 0 }, |
- { CKA_SUBJECT, NULL, 0 } |
- }; |
- PRStatus nssrv; |
- CK_ULONG count = sizeof(pubktemplate) / sizeof(pubktemplate[0]); |
- NSS_CK_SET_ATTRIBUTE_ITEM(pubktemplate, 0, &g_ck_class_pubkey); |
- if (c->id.size > 0) { |
- /* CKA_ID */ |
- NSS_CK_ITEM_TO_ATTRIBUTE(&c->id, &pubktemplate[1]); |
- } else { |
- /* failure, yes? */ |
- return (NSSPublicKey *)NULL; |
- } |
- if (c->subject.size > 0) { |
- /* CKA_SUBJECT */ |
- NSS_CK_ITEM_TO_ATTRIBUTE(&c->subject, &pubktemplate[2]); |
- } else { |
- /* failure, yes? */ |
- return (NSSPublicKey *)NULL; |
- } |
- /* Try the cert's token first */ |
- if (c->token) { |
- nssrv = nssToken_FindObjectByTemplate(c->token, pubktemplate, count); |
- } |
-#endif |
- /* Try all other key tokens */ |
- return (NSSPublicKey *)NULL; |
-} |
- |
-NSS_IMPLEMENT NSSPrivateKey * |
-NSSCertificate_FindPrivateKey ( |
- NSSCertificate *c, |
- NSSCallback *uhh |
-) |
-{ |
- nss_SetError(NSS_ERROR_NOT_FOUND); |
- return NULL; |
-} |
- |
-NSS_IMPLEMENT PRBool |
-NSSCertificate_IsPrivateKeyAvailable ( |
- NSSCertificate *c, |
- NSSCallback *uhh, |
- PRStatus *statusOpt |
-) |
-{ |
- PRBool isUser = PR_FALSE; |
- nssCryptokiObject **ip; |
- nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object); |
- if (!instances) { |
- return PR_FALSE; |
- } |
- for (ip = instances; *ip; ip++) { |
- nssCryptokiObject *instance = *ip; |
- if (nssToken_IsPrivateKeyAvailable(instance->token, c, instance)) { |
- isUser = PR_TRUE; |
- } |
- } |
- nssCryptokiObjectArray_Destroy(instances); |
- return isUser; |
-} |
- |
-/* sort the subject cert list from newest to oldest */ |
-PRIntn |
-nssCertificate_SubjectListSort ( |
- void *v1, |
- void *v2 |
-) |
-{ |
- NSSCertificate *c1 = (NSSCertificate *)v1; |
- NSSCertificate *c2 = (NSSCertificate *)v2; |
- nssDecodedCert *dc1 = nssCertificate_GetDecoding(c1); |
- nssDecodedCert *dc2 = nssCertificate_GetDecoding(c2); |
- if (!dc1) { |
- return dc2 ? 1 : 0; |
- } else if (!dc2) { |
- return -1; |
- } else { |
- return dc1->isNewerThan(dc1, dc2) ? -1 : 1; |
- } |
-} |
- |
-NSS_IMPLEMENT PRBool |
-NSSUserCertificate_IsStillPresent ( |
- NSSUserCertificate *uc, |
- PRStatus *statusOpt |
-) |
-{ |
- nss_SetError(NSS_ERROR_NOT_FOUND); |
- return PR_FALSE; |
-} |
- |
-NSS_IMPLEMENT NSSItem * |
-NSSUserCertificate_Decrypt ( |
- NSSUserCertificate *uc, |
- NSSAlgorithmAndParameters *apOpt, |
- NSSItem *data, |
- NSSTime *timeOpt, |
- NSSUsage *usage, |
- NSSPolicies *policiesOpt, |
- NSSCallback *uhh, |
- NSSItem *rvOpt, |
- NSSArena *arenaOpt |
-) |
-{ |
- nss_SetError(NSS_ERROR_NOT_FOUND); |
- return NULL; |
-} |
- |
-NSS_IMPLEMENT NSSItem * |
-NSSUserCertificate_Sign ( |
- NSSUserCertificate *uc, |
- NSSAlgorithmAndParameters *apOpt, |
- NSSItem *data, |
- NSSTime *timeOpt, |
- NSSUsage *usage, |
- NSSPolicies *policiesOpt, |
- NSSCallback *uhh, |
- NSSItem *rvOpt, |
- NSSArena *arenaOpt |
-) |
-{ |
- nss_SetError(NSS_ERROR_NOT_FOUND); |
- return NULL; |
-} |
- |
-NSS_IMPLEMENT NSSItem * |
-NSSUserCertificate_SignRecover ( |
- NSSUserCertificate *uc, |
- NSSAlgorithmAndParameters *apOpt, |
- NSSItem *data, |
- NSSTime *timeOpt, |
- NSSUsage *usage, |
- NSSPolicies *policiesOpt, |
- NSSCallback *uhh, |
- NSSItem *rvOpt, |
- NSSArena *arenaOpt |
-) |
-{ |
- nss_SetError(NSS_ERROR_NOT_FOUND); |
- return NULL; |
-} |
- |
-NSS_IMPLEMENT NSSSymmetricKey * |
-NSSUserCertificate_UnwrapSymmetricKey ( |
- NSSUserCertificate *uc, |
- NSSAlgorithmAndParameters *apOpt, |
- NSSItem *wrappedKey, |
- NSSTime *timeOpt, |
- NSSUsage *usage, |
- NSSPolicies *policiesOpt, |
- NSSCallback *uhh, |
- NSSItem *rvOpt, |
- NSSArena *arenaOpt |
-) |
-{ |
- nss_SetError(NSS_ERROR_NOT_FOUND); |
- return NULL; |
-} |
- |
-NSS_IMPLEMENT NSSSymmetricKey * |
-NSSUserCertificate_DeriveSymmetricKey ( |
- NSSUserCertificate *uc, /* provides private key */ |
- NSSCertificate *c, /* provides public key */ |
- NSSAlgorithmAndParameters *apOpt, |
- NSSOID *target, |
- PRUint32 keySizeOpt, /* zero for best allowed */ |
- NSSOperations operations, |
- NSSCallback *uhh |
-) |
-{ |
- nss_SetError(NSS_ERROR_NOT_FOUND); |
- return NULL; |
-} |
- |
-NSS_IMPLEMENT nssSMIMEProfile * |
-nssSMIMEProfile_Create ( |
- NSSCertificate *cert, |
- NSSItem *profileTime, |
- NSSItem *profileData |
-) |
-{ |
- NSSArena *arena; |
- nssSMIMEProfile *rvProfile; |
- nssPKIObject *object; |
- NSSTrustDomain *td = nssCertificate_GetTrustDomain(cert); |
- NSSCryptoContext *cc = nssCertificate_GetCryptoContext(cert); |
- arena = nssArena_Create(); |
- if (!arena) { |
- return NULL; |
- } |
- object = nssPKIObject_Create(arena, NULL, td, cc, nssPKILock); |
- if (!object) { |
- goto loser; |
- } |
- rvProfile = nss_ZNEW(arena, nssSMIMEProfile); |
- if (!rvProfile) { |
- goto loser; |
- } |
- rvProfile->object = *object; |
- rvProfile->certificate = cert; |
- rvProfile->email = nssUTF8_Duplicate(cert->email, arena); |
- rvProfile->subject = nssItem_Duplicate(&cert->subject, arena, NULL); |
- if (profileTime) { |
- rvProfile->profileTime = nssItem_Duplicate(profileTime, arena, NULL); |
- } |
- if (profileData) { |
- rvProfile->profileData = nssItem_Duplicate(profileData, arena, NULL); |
- } |
- return rvProfile; |
-loser: |
- if (object) nssPKIObject_Destroy(object); |
- else if (arena) nssArena_Destroy(arena); |
- return (nssSMIMEProfile *)NULL; |
-} |
- |
-/* execute a callback function on all members of a cert list */ |
-NSS_EXTERN PRStatus |
-nssCertificateList_DoCallback ( |
- nssList *certList, |
- PRStatus (* callback)(NSSCertificate *c, void *arg), |
- void *arg |
-) |
-{ |
- nssListIterator *certs; |
- NSSCertificate *cert; |
- PRStatus nssrv; |
- certs = nssList_CreateIterator(certList); |
- if (!certs) { |
- return PR_FAILURE; |
- } |
- for (cert = (NSSCertificate *)nssListIterator_Start(certs); |
- cert != (NSSCertificate *)NULL; |
- cert = (NSSCertificate *)nssListIterator_Next(certs)) |
- { |
- nssrv = (*callback)(cert, arg); |
- } |
- nssListIterator_Finish(certs); |
- nssListIterator_Destroy(certs); |
- return PR_SUCCESS; |
-} |
- |
-static PRStatus add_ref_callback(NSSCertificate *c, void *a) |
-{ |
- nssCertificate_AddRef(c); |
- return PR_SUCCESS; |
-} |
- |
-NSS_IMPLEMENT void |
-nssCertificateList_AddReferences ( |
- nssList *certList |
-) |
-{ |
- (void)nssCertificateList_DoCallback(certList, add_ref_callback, NULL); |
-} |
- |
- |
-/* |
- * Is this trust record safe to apply to all certs of the same issuer/SN |
- * independent of the cert matching the hash. This is only true is the trust |
- * is unknown or distrusted. In general this feature is only useful to |
- * explicitly distrusting certs. It is not safe to use to trust certs, so |
- * only allow unknown and untrusted trust types. |
- */ |
-PRBool |
-nssTrust_IsSafeToIgnoreCertHash(nssTrustLevel serverAuth, |
- nssTrustLevel clientAuth, nssTrustLevel codeSigning, |
- nssTrustLevel email, PRBool stepup) |
-{ |
- /* step up is a trust type, if it's on, we must have a hash for the cert */ |
- if (stepup) { |
- return PR_FALSE; |
- } |
- if ((serverAuth != nssTrustLevel_Unknown) && |
- (serverAuth != nssTrustLevel_NotTrusted)) { |
- return PR_FALSE; |
- } |
- if ((clientAuth != nssTrustLevel_Unknown) && |
- (clientAuth != nssTrustLevel_NotTrusted)) { |
- return PR_FALSE; |
- } |
- if ((codeSigning != nssTrustLevel_Unknown) && |
- (codeSigning != nssTrustLevel_NotTrusted)) { |
- return PR_FALSE; |
- } |
- if ((email != nssTrustLevel_Unknown) && |
- (email != nssTrustLevel_NotTrusted)) { |
- return PR_FALSE; |
- } |
- /* record only has Unknown and Untrusted entries, ok to accept without a |
- * hash */ |
- return PR_TRUE; |
-} |
- |
-NSS_IMPLEMENT NSSTrust * |
-nssTrust_Create ( |
- nssPKIObject *object, |
- NSSItem *certData |
-) |
-{ |
- PRStatus status; |
- PRUint32 i; |
- PRUint32 lastTrustOrder, myTrustOrder; |
- unsigned char sha1_hashcmp[SHA1_LENGTH]; |
- unsigned char sha1_hashin[SHA1_LENGTH]; |
- NSSItem sha1_hash; |
- NSSTrust *rvt; |
- nssCryptokiObject *instance; |
- nssTrustLevel serverAuth, clientAuth, codeSigning, emailProtection; |
- SECStatus rv; /* Should be stan flavor */ |
- PRBool stepUp; |
- |
- lastTrustOrder = 1<<16; /* just make it big */ |
- PR_ASSERT(object->instances != NULL && object->numInstances > 0); |
- rvt = nss_ZNEW(object->arena, NSSTrust); |
- if (!rvt) { |
- return (NSSTrust *)NULL; |
- } |
- rvt->object = *object; |
- |
- /* should be stan flavor of Hashbuf */ |
- rv = PK11_HashBuf(SEC_OID_SHA1,sha1_hashcmp,certData->data,certData->size); |
- if (rv != SECSuccess) { |
- return (NSSTrust *)NULL; |
- } |
- sha1_hash.data = sha1_hashin; |
- sha1_hash.size = sizeof (sha1_hashin); |
- /* trust has to peek into the base object members */ |
- nssPKIObject_Lock(object); |
- for (i=0; i<object->numInstances; i++) { |
- instance = object->instances[i]; |
- myTrustOrder = nssToken_GetTrustOrder(instance->token); |
- status = nssCryptokiTrust_GetAttributes(instance, NULL, |
- &sha1_hash, |
- &serverAuth, |
- &clientAuth, |
- &codeSigning, |
- &emailProtection, |
- &stepUp); |
- if (status != PR_SUCCESS) { |
- nssPKIObject_Unlock(object); |
- return (NSSTrust *)NULL; |
- } |
- /* if no hash is specified, then trust applies to all certs with |
- * this issuer/SN. NOTE: This is only true for entries that |
- * have distrust and unknown record */ |
- if (!( |
- /* we continue if there is no hash, and the trust type is |
- * safe to accept without a hash ... or ... */ |
- ((sha1_hash.size == 0) && |
- nssTrust_IsSafeToIgnoreCertHash(serverAuth,clientAuth, |
- codeSigning, emailProtection,stepUp)) |
- || |
- /* we have a hash of the correct size, and it matches */ |
- ((sha1_hash.size == SHA1_LENGTH) && (PORT_Memcmp(sha1_hashin, |
- sha1_hashcmp,SHA1_LENGTH) == 0)) )) { |
- nssPKIObject_Unlock(object); |
- return (NSSTrust *)NULL; |
- } |
- if (rvt->serverAuth == nssTrustLevel_Unknown || |
- myTrustOrder < lastTrustOrder) |
- { |
- rvt->serverAuth = serverAuth; |
- } |
- if (rvt->clientAuth == nssTrustLevel_Unknown || |
- myTrustOrder < lastTrustOrder) |
- { |
- rvt->clientAuth = clientAuth; |
- } |
- if (rvt->emailProtection == nssTrustLevel_Unknown || |
- myTrustOrder < lastTrustOrder) |
- { |
- rvt->emailProtection = emailProtection; |
- } |
- if (rvt->codeSigning == nssTrustLevel_Unknown || |
- myTrustOrder < lastTrustOrder) |
- { |
- rvt->codeSigning = codeSigning; |
- } |
- rvt->stepUpApproved = stepUp; |
- lastTrustOrder = myTrustOrder; |
- } |
- nssPKIObject_Unlock(object); |
- return rvt; |
-} |
- |
-NSS_IMPLEMENT NSSTrust * |
-nssTrust_AddRef ( |
- NSSTrust *trust |
-) |
-{ |
- if (trust) { |
- nssPKIObject_AddRef(&trust->object); |
- } |
- return trust; |
-} |
- |
-NSS_IMPLEMENT PRStatus |
-nssTrust_Destroy ( |
- NSSTrust *trust |
-) |
-{ |
- if (trust) { |
- (void)nssPKIObject_Destroy(&trust->object); |
- } |
- return PR_SUCCESS; |
-} |
- |
-NSS_IMPLEMENT nssSMIMEProfile * |
-nssSMIMEProfile_AddRef ( |
- nssSMIMEProfile *profile |
-) |
-{ |
- if (profile) { |
- nssPKIObject_AddRef(&profile->object); |
- } |
- return profile; |
-} |
- |
-NSS_IMPLEMENT PRStatus |
-nssSMIMEProfile_Destroy ( |
- nssSMIMEProfile *profile |
-) |
-{ |
- if (profile) { |
- (void)nssPKIObject_Destroy(&profile->object); |
- } |
- return PR_SUCCESS; |
-} |
- |
-NSS_IMPLEMENT NSSCRL * |
-nssCRL_Create ( |
- nssPKIObject *object |
-) |
-{ |
- PRStatus status; |
- NSSCRL *rvCRL; |
- NSSArena *arena = object->arena; |
- PR_ASSERT(object->instances != NULL && object->numInstances > 0); |
- rvCRL = nss_ZNEW(arena, NSSCRL); |
- if (!rvCRL) { |
- return (NSSCRL *)NULL; |
- } |
- rvCRL->object = *object; |
- /* XXX should choose instance based on some criteria */ |
- status = nssCryptokiCRL_GetAttributes(object->instances[0], |
- NULL, /* XXX sessionOpt */ |
- arena, |
- &rvCRL->encoding, |
- NULL, /* subject */ |
- NULL, /* class */ |
- &rvCRL->url, |
- &rvCRL->isKRL); |
- if (status != PR_SUCCESS) { |
- return (NSSCRL *)NULL; |
- } |
- return rvCRL; |
-} |
- |
-NSS_IMPLEMENT NSSCRL * |
-nssCRL_AddRef ( |
- NSSCRL *crl |
-) |
-{ |
- if (crl) { |
- nssPKIObject_AddRef(&crl->object); |
- } |
- return crl; |
-} |
- |
-NSS_IMPLEMENT PRStatus |
-nssCRL_Destroy ( |
- NSSCRL *crl |
-) |
-{ |
- if (crl) { |
- (void)nssPKIObject_Destroy(&crl->object); |
- } |
- return PR_SUCCESS; |
-} |
- |
-NSS_IMPLEMENT PRStatus |
-nssCRL_DeleteStoredObject ( |
- NSSCRL *crl, |
- NSSCallback *uhh |
-) |
-{ |
- return nssPKIObject_DeleteStoredObject(&crl->object, uhh, PR_TRUE); |
-} |
- |
-NSS_IMPLEMENT NSSDER * |
-nssCRL_GetEncoding ( |
- NSSCRL *crl |
-) |
-{ |
- if (crl && crl->encoding.data != NULL && crl->encoding.size > 0) { |
- return &crl->encoding; |
- } else { |
- return (NSSDER *)NULL; |
- } |
-} |