diff options
Diffstat (limited to 'mozilla/security/nss/lib/pki')
23 files changed, 14770 insertions, 0 deletions
diff --git a/mozilla/security/nss/lib/pki/Makefile b/mozilla/security/nss/lib/pki/Makefile new file mode 100644 index 0000000..a60ba0a --- /dev/null +++ b/mozilla/security/nss/lib/pki/Makefile @@ -0,0 +1,44 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is the Netscape security libraries. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1994-2000 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** +MAKEFILE_CVS_ID = "@(#) $RCSfile: Makefile,v $ $Revision: 1.6 $ $Date: 2005/01/20 02:25:48 $" + +include manifest.mn +include $(CORE_DEPTH)/coreconf/config.mk +include config.mk +include $(CORE_DEPTH)/coreconf/rules.mk + +export:: private_export diff --git a/mozilla/security/nss/lib/pki/asymmkey.c b/mozilla/security/nss/lib/pki/asymmkey.c new file mode 100644 index 0000000..717c0df --- /dev/null +++ b/mozilla/security/nss/lib/pki/asymmkey.c @@ -0,0 +1,434 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifdef DEBUG +static const char CVS_ID[] = "@(#) $RCSfile: asymmkey.c,v $ $Revision: 1.6 $ $Date: 2005/01/20 02:25:48 $"; +#endif /* DEBUG */ + +#ifndef NSSPKI_H +#include "nsspki.h" +#endif /* NSSPKI_H */ + +#ifndef BASE_H +#include "base.h" +#endif /* BASE_H */ + +extern const NSSError NSS_ERROR_NOT_FOUND; + +NSS_IMPLEMENT PRStatus +NSSPrivateKey_Destroy ( + NSSPrivateKey *vk +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT PRStatus +NSSPrivateKey_DeleteStoredObject ( + NSSPrivateKey *vk, + NSSCallback *uhh +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT PRUint32 +NSSPrivateKey_GetSignatureLength ( + NSSPrivateKey *vk +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return -1; +} + +NSS_IMPLEMENT PRUint32 +NSSPrivateKey_GetPrivateModulusLength ( + NSSPrivateKey *vk +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return -1; +} + +NSS_IMPLEMENT PRBool +NSSPrivateKey_IsStillPresent ( + NSSPrivateKey *vk, + PRStatus *statusOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FALSE; +} + +NSS_IMPLEMENT NSSItem * +NSSPrivateKey_Encode ( + NSSPrivateKey *vk, + NSSAlgorithmAndParameters *ap, + NSSItem *passwordOpt, /* NULL will cause a callback; "" for no password */ + NSSCallback *uhhOpt, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSTrustDomain * +NSSPrivateKey_GetTrustDomain ( + NSSPrivateKey *vk, + PRStatus *statusOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSToken * +NSSPrivateKey_GetToken ( + NSSPrivateKey *vk +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSSlot * +NSSPrivateKey_GetSlot ( + NSSPrivateKey *vk +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSModule * +NSSPrivateKey_GetModule ( + NSSPrivateKey *vk +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSItem * +NSSPrivateKey_Decrypt ( + NSSPrivateKey *vk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *encryptedData, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSItem * +NSSPrivateKey_Sign ( + NSSPrivateKey *vk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSItem * +NSSPrivateKey_SignRecover ( + NSSPrivateKey *vk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSSymmetricKey * +NSSPrivateKey_UnwrapSymmetricKey ( + NSSPrivateKey *vk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *wrappedKey, + NSSCallback *uhh +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSSymmetricKey * +NSSPrivateKey_DeriveSymmetricKey ( + NSSPrivateKey *vk, + NSSPublicKey *bk, + NSSAlgorithmAndParameters *apOpt, + NSSOID *target, + PRUint32 keySizeOpt, /* zero for best allowed */ + NSSOperations operations, + NSSCallback *uhh +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSPublicKey * +NSSPrivateKey_FindPublicKey ( + NSSPrivateKey *vk + /* { don't need the callback here, right? } */ +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCryptoContext * +NSSPrivateKey_CreateCryptoContext ( + NSSPrivateKey *vk, + NSSAlgorithmAndParameters *apOpt, + NSSCallback *uhh +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCertificate ** +NSSPrivateKey_FindCertificates ( + NSSPrivateKey *vk, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCertificate * +NSSPrivateKey_FindBestCertificate ( + NSSPrivateKey *vk, + NSSTime *timeOpt, + NSSUsage *usageOpt, + NSSPolicies *policiesOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT PRStatus +NSSPublicKey_Destroy ( + NSSPublicKey *bk +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT PRStatus +NSSPublicKey_DeleteStoredObject ( + NSSPublicKey *bk, + NSSCallback *uhh +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT NSSItem * +NSSPublicKey_Encode ( + NSSPublicKey *bk, + NSSAlgorithmAndParameters *ap, + NSSCallback *uhhOpt, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSTrustDomain * +NSSPublicKey_GetTrustDomain ( + NSSPublicKey *bk, + PRStatus *statusOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSToken * +NSSPublicKey_GetToken ( + NSSPublicKey *bk, + PRStatus *statusOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSSlot * +NSSPublicKey_GetSlot ( + NSSPublicKey *bk, + PRStatus *statusOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSModule * +NSSPublicKey_GetModule ( + NSSPublicKey *bk, + PRStatus *statusOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSItem * +NSSPublicKey_Encrypt ( + NSSPublicKey *bk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT PRStatus +NSSPublicKey_Verify ( + NSSPublicKey *bk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSItem *signature, + NSSCallback *uhh +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT NSSItem * +NSSPublicKey_VerifyRecover ( + NSSPublicKey *bk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *signature, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSItem * +NSSPublicKey_WrapSymmetricKey ( + NSSPublicKey *bk, + NSSAlgorithmAndParameters *apOpt, + NSSSymmetricKey *keyToWrap, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCryptoContext * +NSSPublicKey_CreateCryptoContext ( + NSSPublicKey *bk, + NSSAlgorithmAndParameters *apOpt, + NSSCallback *uhh +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCertificate ** +NSSPublicKey_FindCertificates ( + NSSPublicKey *bk, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCertificate * +NSSPublicKey_FindBestCertificate ( + NSSPublicKey *bk, + NSSTime *timeOpt, + NSSUsage *usageOpt, + NSSPolicies *policiesOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSPrivateKey * +NSSPublicKey_FindPrivateKey ( + NSSPublicKey *bk, + NSSCallback *uhh +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + diff --git a/mozilla/security/nss/lib/pki/certdecode.c b/mozilla/security/nss/lib/pki/certdecode.c new file mode 100644 index 0000000..816d705 --- /dev/null +++ b/mozilla/security/nss/lib/pki/certdecode.c @@ -0,0 +1,101 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifdef DEBUG +static const char CVS_ID[] = "@(#) $RCSfile: certdecode.c,v $ $Revision: 1.17 $ $Date: 2007/11/16 05:29:27 $"; +#endif /* DEBUG */ + +#ifndef PKIT_H +#include "pkit.h" +#endif /* PKIT_H */ + +#ifndef PKIM_H +#include "pkim.h" +#endif /* PKIM_H */ + +/* This is defined in pki3hack.c */ +NSS_EXTERN nssDecodedCert * +nssDecodedPKIXCertificate_Create ( + NSSArena *arenaOpt, + NSSDER *encoding +); + +NSS_IMPLEMENT PRStatus +nssDecodedPKIXCertificate_Destroy ( + nssDecodedCert *dc +); + +NSS_IMPLEMENT nssDecodedCert * +nssDecodedCert_Create ( + NSSArena *arenaOpt, + NSSDER *encoding, + NSSCertificateType type +) +{ + nssDecodedCert *rvDC = NULL; + switch(type) { + case NSSCertificateType_PKIX: + rvDC = nssDecodedPKIXCertificate_Create(arenaOpt, encoding); + break; + default: +#if 0 + nss_SetError(NSS_ERROR_INVALID_ARGUMENT); +#endif + return (nssDecodedCert *)NULL; + } + return rvDC; +} + +NSS_IMPLEMENT PRStatus +nssDecodedCert_Destroy ( + nssDecodedCert *dc +) +{ + if (!dc) { + return PR_FAILURE; + } + switch(dc->type) { + case NSSCertificateType_PKIX: + return nssDecodedPKIXCertificate_Destroy(dc); + default: +#if 0 + nss_SetError(NSS_ERROR_INVALID_ARGUMENT); +#endif + break; + } + return PR_FAILURE; +} + diff --git a/mozilla/security/nss/lib/pki/certificate.c b/mozilla/security/nss/lib/pki/certificate.c new file mode 100644 index 0000000..38e17ac --- /dev/null +++ b/mozilla/security/nss/lib/pki/certificate.c @@ -0,0 +1,1157 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifdef DEBUG +static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.67 $ $Date: 2010/04/03 18:27:32 $"; +#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; + } +} + +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); +} + +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 (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; + } +} diff --git a/mozilla/security/nss/lib/pki/config.mk b/mozilla/security/nss/lib/pki/config.mk new file mode 100644 index 0000000..6df4923 --- /dev/null +++ b/mozilla/security/nss/lib/pki/config.mk @@ -0,0 +1,52 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is the Netscape security libraries. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1994-2000 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** +CONFIG_CVS_ID = "@(#) $RCSfile: config.mk,v $ $Revision: 1.6 $ $Date: 2005/01/20 02:25:49 $" + +ifdef BUILD_IDG +DEFINES += -DNSSDEBUG +endif + +# +# Override TARGETS variable so that only static libraries +# are specifed as dependencies within rules.mk. +# + +TARGETS = $(LIBRARY) +SHARED_LIBRARY = +IMPORT_LIBRARY = +PROGRAM = + diff --git a/mozilla/security/nss/lib/pki/cryptocontext.c b/mozilla/security/nss/lib/pki/cryptocontext.c new file mode 100644 index 0000000..05a8479 --- /dev/null +++ b/mozilla/security/nss/lib/pki/cryptocontext.c @@ -0,0 +1,1018 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifdef DEBUG +static const char CVS_ID[] = "@(#) $RCSfile: cryptocontext.c,v $ $Revision: 1.19 $ $Date: 2010/05/21 00:02:48 $"; +#endif /* DEBUG */ + +#ifndef DEV_H +#include "dev.h" +#endif /* DEV_H */ + +#ifndef PKIM_H +#include "pkim.h" +#endif /* PKIM_H */ + +#ifndef PKISTORE_H +#include "pkistore.h" +#endif /* PKISTORE_H */ + +extern const NSSError NSS_ERROR_NOT_FOUND; +extern const NSSError NSS_ERROR_INVALID_ARGUMENT; + +NSS_IMPLEMENT NSSCryptoContext * +nssCryptoContext_Create ( + NSSTrustDomain *td, + NSSCallback *uhhOpt +) +{ + NSSArena *arena; + NSSCryptoContext *rvCC; + arena = NSSArena_Create(); + if (!arena) { + return NULL; + } + rvCC = nss_ZNEW(arena, NSSCryptoContext); + if (!rvCC) { + return NULL; + } + rvCC->td = td; + rvCC->arena = arena; + rvCC->certStore = nssCertificateStore_Create(rvCC->arena); + if (!rvCC->certStore) { + nssArena_Destroy(arena); + return NULL; + } + + return rvCC; +} + +NSS_IMPLEMENT PRStatus +NSSCryptoContext_Destroy ( + NSSCryptoContext *cc +) +{ + PRStatus status = PR_SUCCESS; + PORT_Assert(cc->certStore); + if (cc->certStore) { + status = nssCertificateStore_Destroy(cc->certStore); + if (status == PR_FAILURE) { + return status; + } + } else { + status = PR_FAILURE; + } + nssArena_Destroy(cc->arena); + return status; +} + +NSS_IMPLEMENT PRStatus +NSSCryptoContext_SetDefaultCallback ( + NSSCryptoContext *td, + NSSCallback *newCallback, + NSSCallback **oldCallbackOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT NSSCallback * +NSSCryptoContext_GetDefaultCallback ( + NSSCryptoContext *td, + PRStatus *statusOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSTrustDomain * +NSSCryptoContext_GetTrustDomain ( + NSSCryptoContext *td +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + + +NSS_IMPLEMENT NSSCertificate * +NSSCryptoContext_FindOrImportCertificate ( + NSSCryptoContext *cc, + NSSCertificate *c +) +{ + NSSCertificate *rvCert = NULL; + + PORT_Assert(cc->certStore); + if (!cc->certStore) { + nss_SetError(NSS_ERROR_INVALID_ARGUMENT); + return rvCert; + } + rvCert = nssCertificateStore_FindOrAdd(cc->certStore, c); + if (rvCert == c && c->object.cryptoContext != cc) { + PORT_Assert(!c->object.cryptoContext); + c->object.cryptoContext = cc; + } + if (rvCert) { + /* an NSSCertificate cannot be part of two crypto contexts + ** simultaneously. If this assertion fails, then there is + ** a serious Stan design flaw. + */ + PORT_Assert(cc == c->object.cryptoContext); + } + return rvCert; +} + +NSS_IMPLEMENT NSSCertificate * +NSSCryptoContext_ImportPKIXCertificate ( + NSSCryptoContext *cc, + struct NSSPKIXCertificateStr *pc +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCertificate * +NSSCryptoContext_ImportEncodedCertificate ( + NSSCryptoContext *cc, + NSSBER *ber +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT PRStatus +NSSCryptoContext_ImportEncodedPKIXCertificateChain ( + NSSCryptoContext *cc, + NSSBER *ber +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT PRStatus +nssCryptoContext_ImportTrust ( + NSSCryptoContext *cc, + NSSTrust *trust +) +{ + PRStatus nssrv; + PORT_Assert(cc->certStore); + if (!cc->certStore) { + return PR_FAILURE; + } + nssrv = nssCertificateStore_AddTrust(cc->certStore, trust); +#if 0 + if (nssrv == PR_SUCCESS) { + trust->object.cryptoContext = cc; + } +#endif + return nssrv; +} + +NSS_IMPLEMENT PRStatus +nssCryptoContext_ImportSMIMEProfile ( + NSSCryptoContext *cc, + nssSMIMEProfile *profile +) +{ + PRStatus nssrv; + PORT_Assert(cc->certStore); + if (!cc->certStore) { + return PR_FAILURE; + } + nssrv = nssCertificateStore_AddSMIMEProfile(cc->certStore, profile); +#if 0 + if (nssrv == PR_SUCCESS) { + profile->object.cryptoContext = cc; + } +#endif + return nssrv; +} + +NSS_IMPLEMENT NSSCertificate * +NSSCryptoContext_FindBestCertificateByNickname ( + NSSCryptoContext *cc, + const NSSUTF8 *name, + NSSTime *timeOpt, /* NULL for "now" */ + NSSUsage *usage, + NSSPolicies *policiesOpt /* NULL for none */ +) +{ + NSSCertificate **certs; + NSSCertificate *rvCert = NULL; + PORT_Assert(cc->certStore); + if (!cc->certStore) { + return NULL; + } + certs = nssCertificateStore_FindCertificatesByNickname(cc->certStore, + name, + NULL, 0, NULL); + if (certs) { + rvCert = nssCertificateArray_FindBestCertificate(certs, + timeOpt, + usage, + policiesOpt); + nssCertificateArray_Destroy(certs); + } + return rvCert; +} + +NSS_IMPLEMENT NSSCertificate ** +NSSCryptoContext_FindCertificatesByNickname ( + NSSCryptoContext *cc, + NSSUTF8 *name, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +) +{ + NSSCertificate **rvCerts; + PORT_Assert(cc->certStore); + if (!cc->certStore) { + return NULL; + } + rvCerts = nssCertificateStore_FindCertificatesByNickname(cc->certStore, + name, + rvOpt, + maximumOpt, + arenaOpt); + return rvCerts; +} + +NSS_IMPLEMENT NSSCertificate * +NSSCryptoContext_FindCertificateByIssuerAndSerialNumber ( + NSSCryptoContext *cc, + NSSDER *issuer, + NSSDER *serialNumber +) +{ + PORT_Assert(cc->certStore); + if (!cc->certStore) { + return NULL; + } + return nssCertificateStore_FindCertificateByIssuerAndSerialNumber( + cc->certStore, + issuer, + serialNumber); +} + +NSS_IMPLEMENT NSSCertificate * +NSSCryptoContext_FindBestCertificateBySubject ( + NSSCryptoContext *cc, + NSSDER *subject, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt +) +{ + NSSCertificate **certs; + NSSCertificate *rvCert = NULL; + PORT_Assert(cc->certStore); + if (!cc->certStore) { + return NULL; + } + certs = nssCertificateStore_FindCertificatesBySubject(cc->certStore, + subject, + NULL, 0, NULL); + if (certs) { + rvCert = nssCertificateArray_FindBestCertificate(certs, + timeOpt, + usage, + policiesOpt); + nssCertificateArray_Destroy(certs); + } + return rvCert; +} + +NSS_IMPLEMENT NSSCertificate ** +nssCryptoContext_FindCertificatesBySubject ( + NSSCryptoContext *cc, + NSSDER *subject, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +) +{ + NSSCertificate **rvCerts; + PORT_Assert(cc->certStore); + if (!cc->certStore) { + return NULL; + } + rvCerts = nssCertificateStore_FindCertificatesBySubject(cc->certStore, + subject, + rvOpt, + maximumOpt, + arenaOpt); + return rvCerts; +} + +NSS_IMPLEMENT NSSCertificate ** +NSSCryptoContext_FindCertificatesBySubject ( + NSSCryptoContext *cc, + NSSDER *subject, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +) +{ + return nssCryptoContext_FindCertificatesBySubject(cc, subject, + rvOpt, maximumOpt, + arenaOpt); +} + +NSS_IMPLEMENT NSSCertificate * +NSSCryptoContext_FindBestCertificateByNameComponents ( + NSSCryptoContext *cc, + NSSUTF8 *nameComponents, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCertificate ** +NSSCryptoContext_FindCertificatesByNameComponents ( + NSSCryptoContext *cc, + NSSUTF8 *nameComponents, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCertificate * +NSSCryptoContext_FindCertificateByEncodedCertificate ( + NSSCryptoContext *cc, + NSSBER *encodedCertificate +) +{ + PORT_Assert(cc->certStore); + if (!cc->certStore) { + return NULL; + } + return nssCertificateStore_FindCertificateByEncodedCertificate( + cc->certStore, + encodedCertificate); +} + +NSS_IMPLEMENT NSSCertificate * +NSSCryptoContext_FindBestCertificateByEmail ( + NSSCryptoContext *cc, + NSSASCII7 *email, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt +) +{ + NSSCertificate **certs; + NSSCertificate *rvCert = NULL; + + PORT_Assert(cc->certStore); + if (!cc->certStore) { + return NULL; + } + certs = nssCertificateStore_FindCertificatesByEmail(cc->certStore, + email, + NULL, 0, NULL); + if (certs) { + rvCert = nssCertificateArray_FindBestCertificate(certs, + timeOpt, + usage, + policiesOpt); + nssCertificateArray_Destroy(certs); + } + return rvCert; +} + +NSS_IMPLEMENT NSSCertificate ** +NSSCryptoContext_FindCertificatesByEmail ( + NSSCryptoContext *cc, + NSSASCII7 *email, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +) +{ + NSSCertificate **rvCerts; + PORT_Assert(cc->certStore); + if (!cc->certStore) { + return NULL; + } + rvCerts = nssCertificateStore_FindCertificatesByEmail(cc->certStore, + email, + rvOpt, + maximumOpt, + arenaOpt); + return rvCerts; +} + +NSS_IMPLEMENT NSSCertificate * +NSSCryptoContext_FindCertificateByOCSPHash ( + NSSCryptoContext *cc, + NSSItem *hash +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCertificate * +NSSCryptoContext_FindBestUserCertificate ( + NSSCryptoContext *cc, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCertificate ** +NSSCryptoContext_FindUserCertificates ( + NSSCryptoContext *cc, + NSSTime *timeOpt, + NSSUsage *usageOpt, + NSSPolicies *policiesOpt, + NSSCertificate **rvOpt, + PRUint32 rvLimit, /* zero for no limit */ + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCertificate * +NSSCryptoContext_FindBestUserCertificateForSSLClientAuth ( + NSSCryptoContext *cc, + NSSUTF8 *sslHostOpt, + NSSDER *rootCAsOpt[], /* null pointer for none */ + PRUint32 rootCAsMaxOpt, /* zero means list is null-terminated */ + NSSAlgorithmAndParameters *apOpt, + NSSPolicies *policiesOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCertificate ** +NSSCryptoContext_FindUserCertificatesForSSLClientAuth ( + NSSCryptoContext *cc, + NSSUTF8 *sslHostOpt, + NSSDER *rootCAsOpt[], /* null pointer for none */ + PRUint32 rootCAsMaxOpt, /* zero means list is null-terminated */ + NSSAlgorithmAndParameters *apOpt, + NSSPolicies *policiesOpt, + NSSCertificate **rvOpt, + PRUint32 rvLimit, /* zero for no limit */ + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCertificate * +NSSCryptoContext_FindBestUserCertificateForEmailSigning ( + NSSCryptoContext *cc, + NSSASCII7 *signerOpt, + NSSASCII7 *recipientOpt, + /* anything more here? */ + NSSAlgorithmAndParameters *apOpt, + NSSPolicies *policiesOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCertificate * +NSSCryptoContext_FindUserCertificatesForEmailSigning ( + NSSCryptoContext *cc, + NSSASCII7 *signerOpt, /* fgmr or a more general name? */ + NSSASCII7 *recipientOpt, + /* anything more here? */ + NSSAlgorithmAndParameters *apOpt, + NSSPolicies *policiesOpt, + NSSCertificate **rvOpt, + PRUint32 rvLimit, /* zero for no limit */ + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSTrust * +nssCryptoContext_FindTrustForCertificate ( + NSSCryptoContext *cc, + NSSCertificate *cert +) +{ + PORT_Assert(cc->certStore); + if (!cc->certStore) { + return NULL; + } + return nssCertificateStore_FindTrustForCertificate(cc->certStore, cert); +} + +NSS_IMPLEMENT nssSMIMEProfile * +nssCryptoContext_FindSMIMEProfileForCertificate ( + NSSCryptoContext *cc, + NSSCertificate *cert +) +{ + PORT_Assert(cc->certStore); + if (!cc->certStore) { + return NULL; + } + return nssCertificateStore_FindSMIMEProfileForCertificate(cc->certStore, + cert); +} + +NSS_IMPLEMENT PRStatus +NSSCryptoContext_GenerateKeyPair ( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *ap, + NSSPrivateKey **pvkOpt, + NSSPublicKey **pbkOpt, + PRBool privateKeyIsSensitive, + NSSToken *destination, + NSSCallback *uhhOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT NSSSymmetricKey * +NSSCryptoContext_GenerateSymmetricKey ( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *ap, + PRUint32 keysize, + NSSToken *destination, + NSSCallback *uhhOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSSymmetricKey * +NSSCryptoContext_GenerateSymmetricKeyFromPassword ( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *ap, + NSSUTF8 *passwordOpt, /* if null, prompt */ + NSSToken *destinationOpt, + NSSCallback *uhhOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSSymmetricKey * +NSSCryptoContext_FindSymmetricKeyByAlgorithmAndKeyID ( + NSSCryptoContext *cc, + NSSOID *algorithm, + NSSItem *keyID, + NSSCallback *uhhOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +struct token_session_str { + NSSToken *token; + nssSession *session; +}; + +NSS_IMPLEMENT NSSItem * +NSSCryptoContext_Decrypt ( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSItem *encryptedData, + NSSCallback *uhhOpt, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT PRStatus +NSSCryptoContext_BeginDecrypt ( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSCallback *uhhOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT NSSItem * +NSSCryptoContext_ContinueDecrypt ( + NSSCryptoContext *cc, + NSSItem *data, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSItem * +NSSCryptoContext_FinishDecrypt ( + NSSCryptoContext *cc, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSItem * +NSSCryptoContext_Sign ( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSCallback *uhhOpt, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT PRStatus +NSSCryptoContext_BeginSign ( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSCallback *uhhOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT PRStatus +NSSCryptoContext_ContinueSign ( + NSSCryptoContext *cc, + NSSItem *data +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT NSSItem * +NSSCryptoContext_FinishSign ( + NSSCryptoContext *cc, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSItem * +NSSCryptoContext_SignRecover ( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSCallback *uhhOpt, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT PRStatus +NSSCryptoContext_BeginSignRecover ( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSCallback *uhhOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT NSSItem * +NSSCryptoContext_ContinueSignRecover ( + NSSCryptoContext *cc, + NSSItem *data, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSItem * +NSSCryptoContext_FinishSignRecover ( + NSSCryptoContext *cc, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSSymmetricKey * +NSSCryptoContext_UnwrapSymmetricKey ( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSItem *wrappedKey, + NSSCallback *uhhOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSSymmetricKey * +NSSCryptoContext_DeriveSymmetricKey ( + NSSCryptoContext *cc, + NSSPublicKey *bk, + NSSAlgorithmAndParameters *apOpt, + NSSOID *target, + PRUint32 keySizeOpt, /* zero for best allowed */ + NSSOperations operations, + NSSCallback *uhhOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSItem * +NSSCryptoContext_Encrypt ( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSCallback *uhhOpt, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT PRStatus +NSSCryptoContext_BeginEncrypt ( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSCallback *uhhOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT NSSItem * +NSSCryptoContext_ContinueEncrypt ( + NSSCryptoContext *cc, + NSSItem *data, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSItem * +NSSCryptoContext_FinishEncrypt ( + NSSCryptoContext *cc, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT PRStatus +NSSCryptoContext_Verify ( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSItem *signature, + NSSCallback *uhhOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT PRStatus +NSSCryptoContext_BeginVerify ( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSItem *signature, + NSSCallback *uhhOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT PRStatus +NSSCryptoContext_ContinueVerify ( + NSSCryptoContext *cc, + NSSItem *data +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT PRStatus +NSSCryptoContext_FinishVerify ( + NSSCryptoContext *cc +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT NSSItem * +NSSCryptoContext_VerifyRecover ( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSItem *signature, + NSSCallback *uhhOpt, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT PRStatus +NSSCryptoContext_BeginVerifyRecover ( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSCallback *uhhOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT NSSItem * +NSSCryptoContext_ContinueVerifyRecover ( + NSSCryptoContext *cc, + NSSItem *data, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSItem * +NSSCryptoContext_FinishVerifyRecover ( + NSSCryptoContext *cc, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSItem * +NSSCryptoContext_WrapSymmetricKey ( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSSymmetricKey *keyToWrap, + NSSCallback *uhhOpt, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSItem * +NSSCryptoContext_Digest ( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSCallback *uhhOpt, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + return nssToken_Digest(cc->token, cc->session, apOpt, + data, rvOpt, arenaOpt); +} + +NSS_IMPLEMENT PRStatus +NSSCryptoContext_BeginDigest ( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSCallback *uhhOpt +) +{ + return nssToken_BeginDigest(cc->token, cc->session, apOpt); +} + +NSS_IMPLEMENT PRStatus +NSSCryptoContext_ContinueDigest ( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSItem *item +) +{ + /* + NSSAlgorithmAndParameters *ap; + ap = (apOpt) ? apOpt : cc->ap; + */ + /* why apOpt? can't change it at this point... */ + return nssToken_ContinueDigest(cc->token, cc->session, item); +} + +NSS_IMPLEMENT NSSItem * +NSSCryptoContext_FinishDigest ( + NSSCryptoContext *cc, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + return nssToken_FinishDigest(cc->token, cc->session, rvOpt, arenaOpt); +} + +NSS_IMPLEMENT NSSCryptoContext * +NSSCryptoContext_Clone ( + NSSCryptoContext *cc +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + diff --git a/mozilla/security/nss/lib/pki/doc/standiag.png b/mozilla/security/nss/lib/pki/doc/standiag.png Binary files differnew file mode 100644 index 0000000..fe1aca3 --- /dev/null +++ b/mozilla/security/nss/lib/pki/doc/standiag.png diff --git a/mozilla/security/nss/lib/pki/doc/standoc.html b/mozilla/security/nss/lib/pki/doc/standoc.html new file mode 100644 index 0000000..8cc0675 --- /dev/null +++ b/mozilla/security/nss/lib/pki/doc/standoc.html @@ -0,0 +1,474 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> +<head> +<!-- ***** BEGIN LICENSE BLOCK ***** + - Version: MPL 1.1/GPL 2.0/LGPL 2.1 + - + - The contents of this file are subject to the Mozilla Public License Version + - 1.1 (the "License"); you may not use this file except in compliance with + - the License. You may obtain a copy of the License at + - http://www.mozilla.org/MPL/ + - + - Software distributed under the License is distributed on an "AS IS" basis, + - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + - for the specific language governing rights and limitations under the + - License. + - + - The Original Code is the Netscape security libraries. + - + - The Initial Developer of the Original Code is + - Netscape Communications Corporation. + - Portions created by the Initial Developer are Copyright (C) 1994-2000 + - the Initial Developer. All Rights Reserved. + - + - Contributor(s): + - + - Alternatively, the contents of this file may be used under the terms of + - either the GNU General Public License Version 2 or later (the "GPL"), or + - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + - in which case the provisions of the GPL or the LGPL are applicable instead + - of those above. If you wish to allow use of your version of this file only + - under the terms of either the GPL or the LGPL, and not to allow others to + - use your version of this file under the terms of the MPL, indicate your + - decision by deleting the provisions above and replace them with the notice + - and other provisions required by the GPL or the LGPL. If you do not delete + - the provisions above, a recipient may use your version of this file under + - the terms of any one of the MPL, the GPL or the LGPL. + - + - ***** END LICENSE BLOCK ***** --> + + + <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"> + <title>Stan Design - Work In Progress</title> +</head> + <body> + <br> + This is a working document for progress on Stan design/development.<br> + <br> + Current <a href="#build">build</a> + and <a href="#test">test</a> + instructions.<br> + <br> + The current set of Stan libraries.<br> + <a href="#asn1">asn1</a> + <br> + <a href="#base">base</a> + <br> + <a href="#ckfw">ckfw</a> + <br> + <a href="#dev">dev</a> + <br> + <a href="#pki">pki</a> + <br> + <a href="#pki1">pki1</a> + <br> + <a href="#pkix">pkix</a> + <br> + <br> + "Public" types below (those available to consumers of + NSS) begin with "NSS". "Protected" types (those only available + within NSS) begin with "nss".<br> + <br> + Open issues appears as numbered indents.<br> + <br> + <br> + +<hr width="100%" size="2" align="Left"><br> + +<h3><a name="asn1"></a> + <a href="http://lxr.mozilla.org/mozilla/source/security/nss/lib/asn1/"> + ASN.1</a> + </h3> + ASN.1 encoder/decoder wrapping around the current + ASN.1 implementation.<br> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSASN1EncodingType"> NSSASN1EncodingType</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=nssASN1Item">nssASN1Item</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=nssASN1Template">nssASN1Template</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=nssASN1ChooseTemplateFunction"> + nssASN1ChooseTemplateFunction</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=nssASN1Encoder">nssASN1Encoder</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=nssASN1Decoder">nssASN1Decoder</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=nssASN1EncodingPart"> nssASN1EncodingPart</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=nssASN1NotifyFunction"> + nssASN1NotifyFunction</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=nssASN1EncoderWriteFunction"> + nssASN1EncoderWriteFunction</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=nssASN1DecoderFilterFunction"> + nssASN1DecoderFilterFunction</a> + <br> + <br> + +<hr width="100%" size="2" align="Left"> +<h3><a name="base"></a> + <a href="http://lxr.mozilla.org/mozilla/source/security/nss/lib/base/"> + Base</a> + </h3> + Set of base utilities for Stan implementation. + These are all fairly straightforward, except for nssPointerTracker.<br> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSError">NSSError</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSArena">NSSArena</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSItem">NSSItem</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSBER">NSSBER</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSDER">NSSDER</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSBitString">NSSBitString</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSUTF8">NSSUTF8</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSASCII7">NSSASCII7</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=nssArenaMark">nssArenaMark</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=nssPointerTracker">nssPointerTracker</a> + <br> + This is intended for debug builds only.<br> + +<ol> + <li>Ignored for now.<br> + </li> + +</ol> + <a href="http://lxr.mozilla.org/mozilla/ident?i=nssStringType">nssStringType</a> + <br> + <br> + Suggested additions:<br> + +<ol> + <li>nssList - A list that optionally uses a lock. This list would + manage the currently loaded modules in a trust domain, etc.</li> + + <ul> + <li>SECMODListLock kept track of the number of waiting threads. Will + this be needed in the trust domain?</li> + + </ul> + +</ol> + <br> + +<hr width="100%" size="2" align="Left"> +<h3><a name="ckfw"></a> + <a href="http://lxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/"> + CKFW</a> + </h3> + The cryptoki framework, used for building cryptoki tokens. + This needs to be described in a separate document showing how + to set up a token using CKFW. This code only relates to tokens, + so it is not relevant here.<br> + <br> + <br> + +<hr width="100%" size="2" align="Left"> +<h3><a name="dev"></a> + <a href="http://lxr.mozilla.org/mozilla/source/security/nss/lib/dev/"> + Device</a> + </h3> + Defines cryptoki devices used in NSS. This + is not part of the exposed API. It is a low-level API allowing +NSS to manage cryptoki devices.<br> + <br> + The relationship is like this:<br> + <br> + libpki --> libdev --> cryptoki<br> + <br> + As an example,<br> + <br> + NSSTrustDomain_FindCertificate --> NSSToken_FindCertificate --> + C_FindObjects<br> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSModule">NSSModule</a> + <br> + Replaces the SECMOD API. The module manages a +PRLibrary that holds a cryptoki implementation via a number of slots. + The API should provide the ability to Load and Unload a module, +Login and Logout to the module (through its slots), and to locate a +particular slot/token.<br> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSSlot">NSSSlot</a> + <br> + This and NSSToken combine to replace the PK11 API parts + that relate to slot and token management. The slot API should + provide the ability to Login/Logout to a slot, check the login status, + determine basic configuration information about the slot, and modify + the password settings.<br> + +<ol> + <li>Should slots also maintain a default session? This session would + be used for slot management calls (sections 9.5 and9.6 of PKCS#11). Or + is the token session sufficient (this would not work if C_GetTokenInfo and + C_InitToken need to be wrapped in a threadsafe session).<br> + </li> + +</ol> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSToken">NSSToken</a> + <br> + Fills in the gaps left by NSSSlot. Much of the +cryptoki API is directed towards slots. However, some functionality + clearly belongs with a token type. For example, a certificate + lives on a token, not a slot, so one would expect a function NSSToken_FindCertificate. + Thus functions that deal with importing/exporting an object +and performing actual cryptographic operations belong here.<br> + +<ol> + <li>The distinction between a slot and a token is not clear. Most + functions take a slotID as an argument, even though it is obvious that + the event is intended to occur on a token. That leaves various + possibilities:</li> + + <ol> + <li>Implement the API entirely as NSSToken. If the token is not + present, some calls will simply fail.</li> + <li>Divide the API between NSSToken and NSSSlot, as described above. + NSSSlot would handle cryptoki calls specified as "slot management", + while NSSToken handles actual token operations.</li> + <li>Others?</li> + + </ol> + <li>Session management. Tokens needs a threadsafe session handle + to perform operations. CryptoContexts are meant to provide such sessions, + but other objects will need access to token functions as well (examples: +the TrustDomain_Find functions, _Login, _Logout, and others that do not exist + such as NSSToken_ChangePassword). For those functions, the token could + maintain a default session. Thus all NSSToken API functions would take + sessionOpt as an argument. If the caller is going to provide a session, + it sends an NSSSession there, otherwise it sends NULL and the default session + is utilized.<br> + </li> + +</ol> + Proposed:<br> + NSSSession<br> + Wraps a Cryptoki session. Created from a slot. Used to manage + sessions for crypto contexts. Has a lock field, which locks the session + if the slot is not threadsafe.<br> + <br> + +<hr width="100%" size="2" align="Left"><br> + +<h3><a name="pki"></a> + <a href="http://lxr.mozilla.org/mozilla/source/security/nss/lib/pki/"> + PKI</a> + </h3> + The NSS PKI library.<br> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSCertificate">NSS</a> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSCertificate">Certificate</a> + <br> + +<ol> + <li>The API leaves open the possibility of NSSCertificate meaning various + certificate types, not just X.509. The way to keep open this possibility + is to keep only generally useful information in the NSSCertificate type. + Examples would be the certificate encoding, label, trust (obtained + from cryptoki calls), an email address, etc. Some type of generic +reference should be kept to the decoded certificate, which would then be +accessed by a type-specific API (e.g., NSSX509_GetSubjectName).</li> + +</ol> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSUserCertificate">NSSUserCertificate</a> + <br> + +<ol> + <li>Should this be a typedef of NSSCertificate? This implies that + any function that requires an NSSUserCertificate would fail when called + with a certificate lacking a private key. </li> + +</ol> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSPrivateKey">NSSPrivateKey</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSPublicKey">NSSPublicKey</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSSymmetricKey">NSSSymmetricKey</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSTrustDomain">NSSTrustDomain</a> + <br> + A trust domain is "the field in which certificates may + be validated." It is a collection of modules capable of performing + cryptographic operations and storing certs and keys. This collection + is managed by NSS in a manner opaque to the consumer. The slots + will have various orderings determining which has preference for a +given operation. For example, the trust domain may order the storage + of user certificates one way, and the storage of email certificates in + another way [is that a good example?].<br> + <br> + +<ol> + <li> How will ordering work? We already have the suggestion + that there be two kinds of ordering: storage and search. How +will they be constructed/managed? Do we want to expose access +to a token that overrides this ordering (i.e., the download of updated +root certs may need to override storage order)</li> + <li>How are certs cached? Nelson wonders what it means to Stan + when a cert does not live on a token yet. Bob, Terry, and I discussed + this. My conclusion is that there should be a type, separate +from NSSCertificate, that holds the decoded cert parts (e.g., NSSX509Certificate, + or to avoid confusion, NSSX509DecodedParts). NSSCertificate would + keep a handle to this type, so that it only needs to decode the cert +once. The NSSTrustDomain would keep a hash table of cached certs, +some of which may not live on a token yet (i.e., they are only NSSX509DecodedParts). + This cache could be accessed in the same way the temp db was, +and when the cert is ready to be moved onto a token a call to NSSTrustDomain_ImportCertificate + is made. Note that this is essentially the same as CERT_TempCertToPerm.</li> + + <ul> + <li>The hashtable in lib/base (copied from ckfw/hash.c) uses the identity +hash. Therefore, in a hash of certificates, the key is the certificate +pointer itself. One possibility is to store the decoded cert (NSSX509DecodedParts +above) as the value in the {key, value} pair. When a cert is decoded, +the cert pointer and decoding pointer are added to the hash. Subsequent +lookups have access to one or both of these pointers. This keeps NSSCertificate +separate from its decoding, while providing a way to locate it.</li> + + </ul> + <li>The API is designed to keep token details hidden from the user. However, + it has already been realized that PSM and CMS may need special access to +tokens. Is this part of the TrustDomain API, or should PSM and CMS +be allowed to use "friend" headers from the Token API?</li> + <li>Do we want to allow traversal via NSSTrustDomain_TraverseXXXX?<br> + </li> + +</ol> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSCryptoContext"><br> + NSSCryptoContext</a> + <br> + Analgous to a Cryptoki session. Manages session objects only.<br> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSTime">NSSTime</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSUsage">NSSUsage</a> + <br> + +<ol> + <li> See Fred's <a href="http://lxr.mozilla.org/mozilla/source/security/nss/lib/pki/nsspkit.h#187"> + comments</a> + .</li> + +</ol> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSPolicies">NSSPolicies</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSAlgorithmAndParameters"> + NSSAlgorithmAndParameters</a> + <br> + +<ol> + <li> Again, Fred's <a href="http://lxr.mozilla.org/mozilla/source/security/nss/lib/pki/nsspkit.h#215"> + comments</a> + . The old NSS code had various types related to algorithms + running around in it. We had SECOidTag, SECAlgorithmID, SECItem's + for parameters, CK_MECHANISM for cryptoki, etc. This type should + be able to encapsulate all of those.</li> + +</ol> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSCallback">NSSCallback</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSOperations">NSSOperations</a> + <br> + <br> + <br> + +<hr width="100%" size="2"><br> + <br> + A diagram to suggest a possible TrustDomain architecture.<br> + <br> + <img src="./standiag.png" alt="Trust Domain Diagram" width="748" height="367"> + <br> + +<hr width="100%" size="2" align="Left"><br> + +<h3><a name="pki1"></a> + <a href="http://lxr.mozilla.org/mozilla/source/security/nss/lib/pki1/"> + PKI1</a> + </h3> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSOID">NSSOID</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSATAV">NSSATAV</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSRDN">NSSRDN</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSRDNSeq">NSSRDNSeq</a> + <br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSName">NSSName</a> + <br> + NSSNameChoice<br> + NSSGeneralName<br> + NSSGeneralNameChoice<br> + NSSOtherName<br> + NSSRFC822Name<br> + NSSDNSName<br> + NSSX400Address<br> + NSSEdiParityAddress<br> + NSSURI<br> + NSSIPAddress<br> + NSSRegisteredID<br> + NSSGeneralNameSeq<br> + <a href="http://lxr.mozilla.org/mozilla/ident?i=nssAttributeTypeAliasTable"> + nssAttributeTypeAliasTable</a> + <br> + <br> + <br> + +<hr width="100%" size="2" align="Left"><br> + +<h3><a name="pkix"></a> + <a href="http://lxr.mozilla.org/mozilla/source/security/nss/lib/pkix/"> + PKIX </a> + </h3> + There is a plethora of PKIX related types here.<br> + <br> + +<hr width="100%" size="2" align="Left"><br> + +<h3><a name="build"></a> + Building Stan</h3> + <br> + From nss/lib, run "make BUILD_STAN=1"<br> + <br> + +<hr width="100%" size="2" align="Left"><br> + +<h3><a name="test"></a> + Testing Stan</h3> + A new command line tool, pkiutil, has been created to use only + the Stan API. It depends on a new library, cmdlib, meant to replace + the old secutil library. The old library had code used by products + that needed to be integrated into the main library codebase somehow. The + goal of the new cmdlib is to have functionality needed strictly for NSS + tools.<br> + <br> + How to build:<br> + +<ol> + <li>cd nss/cmd/cmdlib; make</li> + <li>cd ../pkiutil; make</li> + +</ol> + pkiutil will give detailed help with either "pkiutil -?" or "pkiutil + --help".<br> + <br> + So far, the only available test is to list certs on the builtins token. + Copy "libnssckbi.so" (or whatever it is) to cmd/pkiutil. Then + run "pkiutil -L" or "pkiutil --list". The list of certificate nicknames + should be displayed.<br> + <br> + <br> + +</body> +</html> diff --git a/mozilla/security/nss/lib/pki/manifest.mn b/mozilla/security/nss/lib/pki/manifest.mn new file mode 100644 index 0000000..464c3d7 --- /dev/null +++ b/mozilla/security/nss/lib/pki/manifest.mn @@ -0,0 +1,78 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is the Netscape security libraries. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1994-2000 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** +MANIFEST_CVS_ID = "@(#) $RCSfile: manifest.mn,v $ $Revision: 1.17 $ $Date: 2007/11/21 18:02:13 $" + +CORE_DEPTH = ../../.. + +PRIVATE_EXPORTS = \ + pki.h \ + pkit.h \ + nsspkit.h \ + nsspki.h \ + pkistore.h \ + pki3hack.h \ + pkitm.h \ + pkim.h \ + $(NULL) + +EXPORTS = \ + $(NULL) + +MODULE = nss + +CSRCS = \ + asymmkey.c \ + certificate.c \ + cryptocontext.c \ + symmkey.c \ + trustdomain.c \ + tdcache.c \ + certdecode.c \ + pkistore.c \ + pkibase.c \ + pki3hack.c \ + $(NULL) + +#DEFINES = -DDEBUG_CACHE + +REQUIRES = nspr + +LIBRARY_NAME = nsspki +LIBRARY_VERSION = 3 + +# This part of the code, including all sub-dirs, can be optimized for size +export ALLOW_OPT_CODE_SIZE = 1 diff --git a/mozilla/security/nss/lib/pki/nsspki.h b/mozilla/security/nss/lib/pki/nsspki.h new file mode 100644 index 0000000..8c8b3d2 --- /dev/null +++ b/mozilla/security/nss/lib/pki/nsspki.h @@ -0,0 +1,3200 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef NSSPKI_H +#define NSSPKI_H + +#ifdef DEBUG +static const char NSSPKI_CVS_ID[] = "@(#) $RCSfile: nsspki.h,v $ $Revision: 1.13 $ $Date: 2010/05/21 00:02:48 $"; +#endif /* DEBUG */ + +/* + * nsspki.h + * + * This file prototypes the methods of the top-level PKI objects. + */ + +#ifndef NSSDEVT_H +#include "nssdevt.h" +#endif /* NSSDEVT_H */ + +#ifndef NSSPKIT_H +#include "nsspkit.h" +#endif /* NSSPKIT_H */ + +#ifndef BASE_H +#include "base.h" +#endif /* BASE_H */ + +PR_BEGIN_EXTERN_C + +/* + * A note about interfaces + * + * Although these APIs are specified in C, a language which does + * not have fancy support for abstract interfaces, this library + * was designed from an object-oriented perspective. It may be + * useful to consider the standard interfaces which went into + * the writing of these APIs. + * + * Basic operations on all objects: + * Destroy -- free a pointer to an object + * DeleteStoredObject -- delete an object permanently + * + * Public Key cryptographic operations: + * Encrypt + * Verify + * VerifyRecover + * Wrap + * Derive + * + * Private Key cryptographic operations: + * IsStillPresent + * Decrypt + * Sign + * SignRecover + * Unwrap + * Derive + * + * Symmetric Key cryptographic operations: + * IsStillPresent + * Encrypt + * Decrypt + * Sign + * SignRecover + * Verify + * VerifyRecover + * Wrap + * Unwrap + * Derive + * + */ + +/* + * NSSCertificate + * + * These things can do crypto ops like public keys, except that the trust, + * usage, and other constraints are checked. These objects are "high-level," + * so trust, usages, etc. are in the form we throw around (client auth, + * email signing, etc.). Remember that theoretically another implementation + * (think PGP) could be beneath this object. + */ + +/* + * NSSCertificate_Destroy + * + * Free a pointer to a certificate object. + */ + +NSS_EXTERN PRStatus +NSSCertificate_Destroy +( + NSSCertificate *c +); + +/* + * NSSCertificate_DeleteStoredObject + * + * Permanently remove this certificate from storage. If this is the + * only (remaining) certificate corresponding to a private key, + * public key, and/or other object; then that object (those objects) + * are deleted too. + */ + +NSS_EXTERN PRStatus +NSSCertificate_DeleteStoredObject +( + NSSCertificate *c, + NSSCallback *uhh +); + +/* + * NSSCertificate_Validate + * + * Verify that this certificate is trusted, for the specified usage(s), + * at the specified time, {word word} the specified policies. + */ + +NSS_EXTERN PRStatus +NSSCertificate_Validate +( + NSSCertificate *c, + NSSTime *timeOpt, /* NULL for "now" */ + NSSUsage *usage, + NSSPolicies *policiesOpt /* NULL for none */ +); + +/* + * NSSCertificate_ValidateCompletely + * + * Verify that this certificate is trusted. The difference between + * this and the previous call is that NSSCertificate_Validate merely + * returns success or failure with an appropriate error stack. + * However, there may be (and often are) multiple problems with a + * certificate. This routine returns an array of errors, specifying + * every problem. + */ + +/* + * Return value must be an array of objects, each of which has + * an NSSError, and any corresponding certificate (in the chain) + * and/or policy. + */ + +NSS_EXTERN 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 */ +); + +/* + * NSSCertificate_ValidateAndDiscoverUsagesAndPolicies + * + * Returns PR_SUCCESS if the certificate is valid for at least something. + */ + +NSS_EXTERN 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 +); + +/* + * NSSCertificate_Encode + * + */ + +NSS_EXTERN NSSDER * +NSSCertificate_Encode +( + NSSCertificate *c, + NSSDER *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSCertificate_BuildChain + * + * This routine returns NSSCertificate *'s for each certificate + * in the "chain" starting from the specified one up to and + * including the root. The zeroth element in the array is the + * specified ("leaf") certificate. + * + * If statusOpt is supplied, and is returned as PR_FAILURE, possible + * error values are: + * + * NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND - the chain is incomplete + * + */ + +extern const NSSError NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND; + +NSS_EXTERN 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 +); + +/* + * NSSCertificate_GetTrustDomain + * + */ + +NSS_EXTERN NSSTrustDomain * +NSSCertificate_GetTrustDomain +( + NSSCertificate *c +); + +/* + * NSSCertificate_GetToken + * + * There doesn't have to be one. + */ + +NSS_EXTERN NSSToken * +NSSCertificate_GetToken +( + NSSCertificate *c, + PRStatus *statusOpt +); + +/* + * NSSCertificate_GetSlot + * + * There doesn't have to be one. + */ + +NSS_EXTERN NSSSlot * +NSSCertificate_GetSlot +( + NSSCertificate *c, + PRStatus *statusOpt +); + +/* + * NSSCertificate_GetModule + * + * There doesn't have to be one. + */ + +NSS_EXTERN NSSModule * +NSSCertificate_GetModule +( + NSSCertificate *c, + PRStatus *statusOpt +); + +/* + * NSSCertificate_Encrypt + * + * Encrypt a single chunk of data with the public key corresponding to + * this certificate. + */ + +NSS_EXTERN NSSItem * +NSSCertificate_Encrypt +( + NSSCertificate *c, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSCertificate_Verify + * + */ + +NSS_EXTERN PRStatus +NSSCertificate_Verify +( + NSSCertificate *c, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSItem *signature, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt, + NSSCallback *uhh +); + +/* + * NSSCertificate_VerifyRecover + * + */ + +NSS_EXTERN NSSItem * +NSSCertificate_VerifyRecover +( + NSSCertificate *c, + NSSAlgorithmAndParameters *apOpt, + NSSItem *signature, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSCertificate_WrapSymmetricKey + * + * This method tries very hard to to succeed, even in situations + * involving sensitive keys and multiple modules. + * { relyea: want to add verbiage? } + */ + +NSS_EXTERN NSSItem * +NSSCertificate_WrapSymmetricKey +( + NSSCertificate *c, + NSSAlgorithmAndParameters *apOpt, + NSSSymmetricKey *keyToWrap, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSCertificate_CreateCryptoContext + * + * Create a crypto context, in this certificate's trust domain, with this + * as the distinguished certificate. + */ + +NSS_EXTERN NSSCryptoContext * +NSSCertificate_CreateCryptoContext +( + NSSCertificate *c, + NSSAlgorithmAndParameters *apOpt, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt, + NSSCallback *uhh +); + +/* + * NSSCertificate_GetPublicKey + * + * Returns the public key corresponding to this certificate. + */ + +NSS_EXTERN NSSPublicKey * +NSSCertificate_GetPublicKey +( + NSSCertificate *c +); + +/* + * NSSCertificate_FindPrivateKey + * + * Finds and returns the private key corresponding to this certificate, + * if it is available. + * + * { Should this hang off of NSSUserCertificate? } + */ + +NSS_EXTERN NSSPrivateKey * +NSSCertificate_FindPrivateKey +( + NSSCertificate *c, + NSSCallback *uhh +); + +/* + * NSSCertificate_IsPrivateKeyAvailable + * + * Returns success if the private key corresponding to this certificate + * is available to be used. + * + * { Should *this* hang off of NSSUserCertificate?? } + */ + +NSS_EXTERN PRBool +NSSCertificate_IsPrivateKeyAvailable +( + NSSCertificate *c, + NSSCallback *uhh, + PRStatus *statusOpt +); + +/* + * If we make NSSUserCertificate not a typedef of NSSCertificate, + * then we'll need implementations of the following: + * + * NSSUserCertificate_Destroy + * NSSUserCertificate_DeleteStoredObject + * NSSUserCertificate_Validate + * NSSUserCertificate_ValidateCompletely + * NSSUserCertificate_ValidateAndDiscoverUsagesAndPolicies + * NSSUserCertificate_Encode + * NSSUserCertificate_BuildChain + * NSSUserCertificate_GetTrustDomain + * NSSUserCertificate_GetToken + * NSSUserCertificate_GetSlot + * NSSUserCertificate_GetModule + * NSSUserCertificate_GetCryptoContext + * NSSUserCertificate_GetPublicKey + */ + +/* + * NSSUserCertificate_IsStillPresent + * + * Verify that if this certificate lives on a token, that the token + * is still present and the certificate still exists. This is a + * lightweight call which should be used whenever it should be + * verified that the user hasn't perhaps popped out his or her + * token and strolled away. + */ + +NSS_EXTERN PRBool +NSSUserCertificate_IsStillPresent +( + NSSUserCertificate *uc, + PRStatus *statusOpt +); + +/* + * NSSUserCertificate_Decrypt + * + * Decrypt a single chunk of data with the private key corresponding + * to this certificate. + */ + +NSS_EXTERN NSSItem * +NSSUserCertificate_Decrypt +( + NSSUserCertificate *uc, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSUserCertificate_Sign + * + */ + +NSS_EXTERN NSSItem * +NSSUserCertificate_Sign +( + NSSUserCertificate *uc, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSUserCertificate_SignRecover + * + */ + +NSS_EXTERN NSSItem * +NSSUserCertificate_SignRecover +( + NSSUserCertificate *uc, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSUserCertificate_UnwrapSymmetricKey + * + */ + +NSS_EXTERN NSSSymmetricKey * +NSSUserCertificate_UnwrapSymmetricKey +( + NSSUserCertificate *uc, + NSSAlgorithmAndParameters *apOpt, + NSSItem *wrappedKey, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSUserCertificate_DeriveSymmetricKey + * + */ + +NSS_EXTERN 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 +); + +/* filter-certs function(s) */ + +/** + ** fgmr -- trust objects + **/ + +/* + * NSSPrivateKey + * + */ + +/* + * NSSPrivateKey_Destroy + * + * Free a pointer to a private key object. + */ + +NSS_EXTERN PRStatus +NSSPrivateKey_Destroy +( + NSSPrivateKey *vk +); + +/* + * NSSPrivateKey_DeleteStoredObject + * + * Permanently remove this object, and any related objects (such as the + * certificates corresponding to this key). + */ + +NSS_EXTERN PRStatus +NSSPrivateKey_DeleteStoredObject +( + NSSPrivateKey *vk, + NSSCallback *uhh +); + +/* + * NSSPrivateKey_GetSignatureLength + * + */ + +NSS_EXTERN PRUint32 +NSSPrivateKey_GetSignatureLength +( + NSSPrivateKey *vk +); + +/* + * NSSPrivateKey_GetPrivateModulusLength + * + */ + +NSS_EXTERN PRUint32 +NSSPrivateKey_GetPrivateModulusLength +( + NSSPrivateKey *vk +); + +/* + * NSSPrivateKey_IsStillPresent + * + */ + +NSS_EXTERN PRBool +NSSPrivateKey_IsStillPresent +( + NSSPrivateKey *vk, + PRStatus *statusOpt +); + +/* + * NSSPrivateKey_Encode + * + */ + +NSS_EXTERN NSSItem * +NSSPrivateKey_Encode +( + NSSPrivateKey *vk, + NSSAlgorithmAndParameters *ap, + NSSItem *passwordOpt, /* NULL will cause a callback; "" for no password */ + NSSCallback *uhhOpt, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSPrivateKey_GetTrustDomain + * + * There doesn't have to be one. + */ + +NSS_EXTERN NSSTrustDomain * +NSSPrivateKey_GetTrustDomain +( + NSSPrivateKey *vk, + PRStatus *statusOpt +); + +/* + * NSSPrivateKey_GetToken + * + */ + +NSS_EXTERN NSSToken * +NSSPrivateKey_GetToken +( + NSSPrivateKey *vk +); + +/* + * NSSPrivateKey_GetSlot + * + */ + +NSS_EXTERN NSSSlot * +NSSPrivateKey_GetSlot +( + NSSPrivateKey *vk +); + +/* + * NSSPrivateKey_GetModule + * + */ + +NSS_EXTERN NSSModule * +NSSPrivateKey_GetModule +( + NSSPrivateKey *vk +); + +/* + * NSSPrivateKey_Decrypt + * + */ + +NSS_EXTERN NSSItem * +NSSPrivateKey_Decrypt +( + NSSPrivateKey *vk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *encryptedData, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSPrivateKey_Sign + * + */ + +NSS_EXTERN NSSItem * +NSSPrivateKey_Sign +( + NSSPrivateKey *vk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSPrivateKey_SignRecover + * + */ + +NSS_EXTERN NSSItem * +NSSPrivateKey_SignRecover +( + NSSPrivateKey *vk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSPrivateKey_UnwrapSymmetricKey + * + */ + +NSS_EXTERN NSSSymmetricKey * +NSSPrivateKey_UnwrapSymmetricKey +( + NSSPrivateKey *vk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *wrappedKey, + NSSCallback *uhh +); + +/* + * NSSPrivateKey_DeriveSymmetricKey + * + */ + +NSS_EXTERN NSSSymmetricKey * +NSSPrivateKey_DeriveSymmetricKey +( + NSSPrivateKey *vk, + NSSPublicKey *bk, + NSSAlgorithmAndParameters *apOpt, + NSSOID *target, + PRUint32 keySizeOpt, /* zero for best allowed */ + NSSOperations operations, + NSSCallback *uhh +); + +/* + * NSSPrivateKey_FindPublicKey + * + */ + +NSS_EXTERN NSSPublicKey * +NSSPrivateKey_FindPublicKey +( + NSSPrivateKey *vk + /* { don't need the callback here, right? } */ +); + +/* + * NSSPrivateKey_CreateCryptoContext + * + * Create a crypto context, in this key's trust domain, + * with this as the distinguished private key. + */ + +NSS_EXTERN NSSCryptoContext * +NSSPrivateKey_CreateCryptoContext +( + NSSPrivateKey *vk, + NSSAlgorithmAndParameters *apOpt, + NSSCallback *uhh +); + +/* + * NSSPrivateKey_FindCertificates + * + * Note that there may be more than one certificate for this + * private key. { FilterCertificates function to further + * reduce the list. } + */ + +NSS_EXTERN NSSCertificate ** +NSSPrivateKey_FindCertificates +( + NSSPrivateKey *vk, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +); + +/* + * NSSPrivateKey_FindBestCertificate + * + * The parameters for this function will depend on what the users + * need. This is just a starting point. + */ + +NSS_EXTERN NSSCertificate * +NSSPrivateKey_FindBestCertificate +( + NSSPrivateKey *vk, + NSSTime *timeOpt, + NSSUsage *usageOpt, + NSSPolicies *policiesOpt +); + +/* + * NSSPublicKey + * + * Once you generate, find, or derive one of these, you can use it + * to perform (simple) cryptographic operations. Though there may + * be certificates associated with these public keys, they are not + * verified. + */ + +/* + * NSSPublicKey_Destroy + * + * Free a pointer to a public key object. + */ + +NSS_EXTERN PRStatus +NSSPublicKey_Destroy +( + NSSPublicKey *bk +); + +/* + * NSSPublicKey_DeleteStoredObject + * + * Permanently remove this object, and any related objects (such as the + * corresponding private keys and certificates). + */ + +NSS_EXTERN PRStatus +NSSPublicKey_DeleteStoredObject +( + NSSPublicKey *bk, + NSSCallback *uhh +); + +/* + * NSSPublicKey_Encode + * + */ + +NSS_EXTERN NSSItem * +NSSPublicKey_Encode +( + NSSPublicKey *bk, + NSSAlgorithmAndParameters *ap, + NSSCallback *uhhOpt, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSPublicKey_GetTrustDomain + * + * There doesn't have to be one. + */ + +NSS_EXTERN NSSTrustDomain * +NSSPublicKey_GetTrustDomain +( + NSSPublicKey *bk, + PRStatus *statusOpt +); + +/* + * NSSPublicKey_GetToken + * + * There doesn't have to be one. + */ + +NSS_EXTERN NSSToken * +NSSPublicKey_GetToken +( + NSSPublicKey *bk, + PRStatus *statusOpt +); + +/* + * NSSPublicKey_GetSlot + * + * There doesn't have to be one. + */ + +NSS_EXTERN NSSSlot * +NSSPublicKey_GetSlot +( + NSSPublicKey *bk, + PRStatus *statusOpt +); + +/* + * NSSPublicKey_GetModule + * + * There doesn't have to be one. + */ + +NSS_EXTERN NSSModule * +NSSPublicKey_GetModule +( + NSSPublicKey *bk, + PRStatus *statusOpt +); + +/* + * NSSPublicKey_Encrypt + * + * Encrypt a single chunk of data with the public key corresponding to + * this certificate. + */ + +NSS_EXTERN NSSItem * +NSSPublicKey_Encrypt +( + NSSPublicKey *bk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSPublicKey_Verify + * + */ + +NSS_EXTERN PRStatus +NSSPublicKey_Verify +( + NSSPublicKey *bk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSItem *signature, + NSSCallback *uhh +); + +/* + * NSSPublicKey_VerifyRecover + * + */ + +NSS_EXTERN NSSItem * +NSSPublicKey_VerifyRecover +( + NSSPublicKey *bk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *signature, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSPublicKey_WrapSymmetricKey + * + */ + +NSS_EXTERN NSSItem * +NSSPublicKey_WrapSymmetricKey +( + NSSPublicKey *bk, + NSSAlgorithmAndParameters *apOpt, + NSSSymmetricKey *keyToWrap, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSPublicKey_CreateCryptoContext + * + * Create a crypto context, in this key's trust domain, with this + * as the distinguished public key. + */ + +NSS_EXTERN NSSCryptoContext * +NSSPublicKey_CreateCryptoContext +( + NSSPublicKey *bk, + NSSAlgorithmAndParameters *apOpt, + NSSCallback *uhh +); + +/* + * NSSPublicKey_FindCertificates + * + * Note that there may be more than one certificate for this + * public key. The current implementation may not find every + * last certificate available for this public key: that would + * involve trolling e.g. huge ldap databases, which will be + * grossly inefficient and not generally useful. + * { FilterCertificates function to further reduce the list } + */ + +NSS_EXTERN NSSCertificate ** +NSSPublicKey_FindCertificates +( + NSSPublicKey *bk, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +); + +/* + * NSSPrivateKey_FindBestCertificate + * + * The parameters for this function will depend on what the users + * need. This is just a starting point. + */ + +NSS_EXTERN NSSCertificate * +NSSPublicKey_FindBestCertificate +( + NSSPublicKey *bk, + NSSTime *timeOpt, + NSSUsage *usageOpt, + NSSPolicies *policiesOpt +); + +/* + * NSSPublicKey_FindPrivateKey + * + */ + +NSS_EXTERN NSSPrivateKey * +NSSPublicKey_FindPrivateKey +( + NSSPublicKey *bk, + NSSCallback *uhh +); + +/* + * NSSSymmetricKey + * + */ + +/* + * NSSSymmetricKey_Destroy + * + * Free a pointer to a symmetric key object. + */ + +NSS_EXTERN PRStatus +NSSSymmetricKey_Destroy +( + NSSSymmetricKey *mk +); + +/* + * NSSSymmetricKey_DeleteStoredObject + * + * Permanently remove this object. + */ + +NSS_EXTERN PRStatus +NSSSymmetricKey_DeleteStoredObject +( + NSSSymmetricKey *mk, + NSSCallback *uhh +); + +/* + * NSSSymmetricKey_GetKeyLength + * + */ + +NSS_EXTERN PRUint32 +NSSSymmetricKey_GetKeyLength +( + NSSSymmetricKey *mk +); + +/* + * NSSSymmetricKey_GetKeyStrength + * + */ + +NSS_EXTERN PRUint32 +NSSSymmetricKey_GetKeyStrength +( + NSSSymmetricKey *mk +); + +/* + * NSSSymmetricKey_IsStillPresent + * + */ + +NSS_EXTERN PRStatus +NSSSymmetricKey_IsStillPresent +( + NSSSymmetricKey *mk +); + +/* + * NSSSymmetricKey_GetTrustDomain + * + * There doesn't have to be one. + */ + +NSS_EXTERN NSSTrustDomain * +NSSSymmetricKey_GetTrustDomain +( + NSSSymmetricKey *mk, + PRStatus *statusOpt +); + +/* + * NSSSymmetricKey_GetToken + * + * There doesn't have to be one. + */ + +NSS_EXTERN NSSToken * +NSSSymmetricKey_GetToken +( + NSSSymmetricKey *mk, + PRStatus *statusOpt +); + +/* + * NSSSymmetricKey_GetSlot + * + * There doesn't have to be one. + */ + +NSS_EXTERN NSSSlot * +NSSSymmetricKey_GetSlot +( + NSSSymmetricKey *mk, + PRStatus *statusOpt +); + +/* + * NSSSymmetricKey_GetModule + * + * There doesn't have to be one. + */ + +NSS_EXTERN NSSModule * +NSSSymmetricKey_GetModule +( + NSSSymmetricKey *mk, + PRStatus *statusOpt +); + +/* + * NSSSymmetricKey_Encrypt + * + */ + +NSS_EXTERN NSSItem * +NSSSymmetricKey_Encrypt +( + NSSSymmetricKey *mk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSSymmetricKey_Decrypt + * + */ + +NSS_EXTERN NSSItem * +NSSSymmetricKey_Decrypt +( + NSSSymmetricKey *mk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *encryptedData, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSSymmetricKey_Sign + * + */ + +NSS_EXTERN NSSItem * +NSSSymmetricKey_Sign +( + NSSSymmetricKey *mk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSSymmetricKey_SignRecover + * + */ + +NSS_EXTERN NSSItem * +NSSSymmetricKey_SignRecover +( + NSSSymmetricKey *mk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSSymmetricKey_Verify + * + */ + +NSS_EXTERN PRStatus +NSSSymmetricKey_Verify +( + NSSSymmetricKey *mk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSItem *signature, + NSSCallback *uhh +); + +/* + * NSSSymmetricKey_VerifyRecover + * + */ + +NSS_EXTERN NSSItem * +NSSSymmetricKey_VerifyRecover +( + NSSSymmetricKey *mk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *signature, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSSymmetricKey_WrapSymmetricKey + * + */ + +NSS_EXTERN NSSItem * +NSSSymmetricKey_WrapSymmetricKey +( + NSSSymmetricKey *wrappingKey, + NSSAlgorithmAndParameters *apOpt, + NSSSymmetricKey *keyToWrap, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSSymmetricKey_WrapPrivateKey + * + */ + +NSS_EXTERN NSSItem * +NSSSymmetricKey_WrapPrivateKey +( + NSSSymmetricKey *wrappingKey, + NSSAlgorithmAndParameters *apOpt, + NSSPrivateKey *keyToWrap, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSSymmetricKey_UnwrapSymmetricKey + * + */ + +NSS_EXTERN NSSSymmetricKey * +NSSSymmetricKey_UnwrapSymmetricKey +( + NSSSymmetricKey *wrappingKey, + NSSAlgorithmAndParameters *apOpt, + NSSItem *wrappedKey, + NSSOID *target, + PRUint32 keySizeOpt, + NSSOperations operations, + NSSCallback *uhh +); + +/* + * NSSSymmetricKey_UnwrapPrivateKey + * + */ + +NSS_EXTERN NSSPrivateKey * +NSSSymmetricKey_UnwrapPrivateKey +( + NSSSymmetricKey *wrappingKey, + NSSAlgorithmAndParameters *apOpt, + NSSItem *wrappedKey, + NSSUTF8 *labelOpt, + NSSItem *keyIDOpt, + PRBool persistant, + PRBool sensitive, + NSSToken *destinationOpt, + NSSCallback *uhh +); + +/* + * NSSSymmetricKey_DeriveSymmetricKey + * + */ + +NSS_EXTERN NSSSymmetricKey * +NSSSymmetricKey_DeriveSymmetricKey +( + NSSSymmetricKey *originalKey, + NSSAlgorithmAndParameters *apOpt, + NSSOID *target, + PRUint32 keySizeOpt, + NSSOperations operations, + NSSCallback *uhh +); + +/* + * NSSSymmetricKey_CreateCryptoContext + * + * Create a crypto context, in this key's trust domain, + * with this as the distinguished symmetric key. + */ + +NSS_EXTERN NSSCryptoContext * +NSSSymmetricKey_CreateCryptoContext +( + NSSSymmetricKey *mk, + NSSAlgorithmAndParameters *apOpt, + NSSCallback *uhh +); + +/* + * NSSTrustDomain + * + */ + +/* + * NSSTrustDomain_Create + * + * This creates a trust domain, optionally with an initial cryptoki + * module. If the module name is not null, the module is loaded if + * needed (using the uriOpt argument), and initialized with the + * opaqueOpt argument. If mumble mumble priority settings, then + * module-specification objects in the module can cause the loading + * and initialization of further modules. + * + * The uriOpt is defined to take a URI. At present, we only + * support file: URLs pointing to platform-native shared libraries. + * However, by specifying this as a URI, this keeps open the + * possibility of supporting other, possibly remote, resources. + * + * The "reserved" arguments is held for when we figure out the + * module priority stuff. + */ + +NSS_EXTERN NSSTrustDomain * +NSSTrustDomain_Create +( + NSSUTF8 *moduleOpt, + NSSUTF8 *uriOpt, + NSSUTF8 *opaqueOpt, + void *reserved +); + +/* + * NSSTrustDomain_Destroy + * + */ + +NSS_EXTERN PRStatus +NSSTrustDomain_Destroy +( + NSSTrustDomain *td +); + +/* + * NSSTrustDomain_SetDefaultCallback + * + */ + +NSS_EXTERN PRStatus +NSSTrustDomain_SetDefaultCallback +( + NSSTrustDomain *td, + NSSCallback *newCallback, + NSSCallback **oldCallbackOpt +); + +/* + * NSSTrustDomain_GetDefaultCallback + * + */ + +NSS_EXTERN NSSCallback * +NSSTrustDomain_GetDefaultCallback +( + NSSTrustDomain *td, + PRStatus *statusOpt +); + +/* + * Default policies? + * Default usage? + * Default time, for completeness? + */ + +/* + * NSSTrustDomain_LoadModule + * + */ + +NSS_EXTERN PRStatus +NSSTrustDomain_LoadModule +( + NSSTrustDomain *td, + NSSUTF8 *moduleOpt, + NSSUTF8 *uriOpt, + NSSUTF8 *opaqueOpt, + void *reserved +); + +/* + * NSSTrustDomain_AddModule + * NSSTrustDomain_AddSlot + * NSSTrustDomain_UnloadModule + * Managing modules, slots, tokens; priorities; + * Traversing all of the above + * this needs more work + */ + +/* + * NSSTrustDomain_DisableToken + * + */ + +NSS_EXTERN PRStatus +NSSTrustDomain_DisableToken +( + NSSTrustDomain *td, + NSSToken *token, + NSSError why +); + +/* + * NSSTrustDomain_EnableToken + * + */ + +NSS_EXTERN PRStatus +NSSTrustDomain_EnableToken +( + NSSTrustDomain *td, + NSSToken *token +); + +/* + * NSSTrustDomain_IsTokenEnabled + * + * If disabled, "why" is always on the error stack. + * The optional argument is just for convenience. + */ + +NSS_EXTERN PRStatus +NSSTrustDomain_IsTokenEnabled +( + NSSTrustDomain *td, + NSSToken *token, + NSSError *whyOpt +); + +/* + * NSSTrustDomain_FindSlotByName + * + */ + +NSS_EXTERN NSSSlot * +NSSTrustDomain_FindSlotByName +( + NSSTrustDomain *td, + NSSUTF8 *slotName +); + +/* + * NSSTrustDomain_FindTokenByName + * + */ + +NSS_EXTERN NSSToken * +NSSTrustDomain_FindTokenByName +( + NSSTrustDomain *td, + NSSUTF8 *tokenName +); + +/* + * NSSTrustDomain_FindTokenBySlotName + * + */ + +NSS_EXTERN NSSToken * +NSSTrustDomain_FindTokenBySlotName +( + NSSTrustDomain *td, + NSSUTF8 *slotName +); + +/* + * NSSTrustDomain_FindBestTokenForAlgorithm + * + */ + +NSS_EXTERN NSSToken * +NSSTrustDomain_FindTokenForAlgorithm +( + NSSTrustDomain *td, + NSSOID *algorithm +); + +/* + * NSSTrustDomain_FindBestTokenForAlgorithms + * + */ + +NSS_EXTERN NSSToken * +NSSTrustDomain_FindBestTokenForAlgorithms +( + NSSTrustDomain *td, + NSSOID *algorithms[], /* may be null-terminated */ + PRUint32 nAlgorithmsOpt /* limits the array if nonzero */ +); + +/* + * NSSTrustDomain_Login + * + */ + +NSS_EXTERN PRStatus +NSSTrustDomain_Login +( + NSSTrustDomain *td, + NSSCallback *uhhOpt +); + +/* + * NSSTrustDomain_Logout + * + */ + +NSS_EXTERN PRStatus +NSSTrustDomain_Logout +( + NSSTrustDomain *td +); + +/* Importing things */ + +/* + * NSSTrustDomain_ImportCertificate + * + * The implementation will pull some data out of the certificate + * (e.g. e-mail address) for use in pkcs#11 object attributes. + */ + +NSS_EXTERN NSSCertificate * +NSSTrustDomain_ImportCertificate +( + NSSTrustDomain *td, + NSSCertificate *c +); + +/* + * NSSTrustDomain_ImportPKIXCertificate + * + */ + +NSS_EXTERN NSSCertificate * +NSSTrustDomain_ImportPKIXCertificate +( + NSSTrustDomain *td, + /* declared as a struct until these "data types" are defined */ + struct NSSPKIXCertificateStr *pc +); + +/* + * NSSTrustDomain_ImportEncodedCertificate + * + * Imports any type of certificate we support. + */ + +NSS_EXTERN NSSCertificate * +NSSTrustDomain_ImportEncodedCertificate +( + NSSTrustDomain *td, + NSSBER *ber +); + +/* + * NSSTrustDomain_ImportEncodedCertificateChain + * + * If you just want the leaf, pass in a maximum of one. + */ + +NSS_EXTERN NSSCertificate ** +NSSTrustDomain_ImportEncodedCertificateChain +( + NSSTrustDomain *td, + NSSBER *ber, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +); + +/* + * NSSTrustDomain_ImportEncodedPrivateKey + * + */ + +NSS_EXTERN NSSPrivateKey * +NSSTrustDomain_ImportEncodedPrivateKey +( + NSSTrustDomain *td, + NSSBER *ber, + NSSItem *passwordOpt, /* NULL will cause a callback */ + NSSCallback *uhhOpt, + NSSToken *destination +); + +/* + * NSSTrustDomain_ImportEncodedPublicKey + * + */ + +NSS_EXTERN NSSPublicKey * +NSSTrustDomain_ImportEncodedPublicKey +( + NSSTrustDomain *td, + NSSBER *ber +); + +/* Other importations: S/MIME capabilities */ + +/* + * NSSTrustDomain_FindBestCertificateByNickname + * + */ + +NSS_EXTERN NSSCertificate * +NSSTrustDomain_FindBestCertificateByNickname +( + NSSTrustDomain *td, + const NSSUTF8 *name, + NSSTime *timeOpt, /* NULL for "now" */ + NSSUsage *usage, + NSSPolicies *policiesOpt /* NULL for none */ +); + +/* + * NSSTrustDomain_FindCertificatesByNickname + * + */ + +NSS_EXTERN NSSCertificate ** +NSSTrustDomain_FindCertificatesByNickname +( + NSSTrustDomain *td, + NSSUTF8 *name, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +); + +/* + * NSSTrustDomain_FindCertificateByIssuerAndSerialNumber + * + */ + +NSS_EXTERN NSSCertificate * +NSSTrustDomain_FindCertificateByIssuerAndSerialNumber +( + NSSTrustDomain *td, + NSSDER *issuer, + NSSDER *serialNumber +); + +/* + * NSSTrustDomain_FindCertificatesByIssuerAndSerialNumber + * + * Theoretically, this should never happen. However, some companies + * we know have issued duplicate certificates with the same issuer + * and serial number. Do we just ignore them? I'm thinking yes. + */ + +/* + * NSSTrustDomain_FindBestCertificateBySubject + * + * This does not search through alternate names hidden in extensions. + */ + +NSS_EXTERN NSSCertificate * +NSSTrustDomain_FindBestCertificateBySubject +( + NSSTrustDomain *td, + NSSDER /*NSSUTF8*/ *subject, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt +); + +/* + * NSSTrustDomain_FindCertificatesBySubject + * + * This does not search through alternate names hidden in extensions. + */ + +NSS_EXTERN NSSCertificate ** +NSSTrustDomain_FindCertificatesBySubject +( + NSSTrustDomain *td, + NSSDER /*NSSUTF8*/ *subject, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +); + +/* + * NSSTrustDomain_FindBestCertificateByNameComponents + * + * This call does try several tricks, including a pseudo pkcs#11 + * attribute for the ldap module to try as a query. Eventually + * this call falls back to a traversal if that's what's required. + * It will search through alternate names hidden in extensions. + */ + +NSS_EXTERN NSSCertificate * +NSSTrustDomain_FindBestCertificateByNameComponents +( + NSSTrustDomain *td, + NSSUTF8 *nameComponents, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt +); + +/* + * NSSTrustDomain_FindCertificatesByNameComponents + * + * This call, too, tries several tricks. It will stop on the first + * attempt that generates results, so it won't e.g. traverse the + * entire ldap database. + */ + +NSS_EXTERN NSSCertificate ** +NSSTrustDomain_FindCertificatesByNameComponents +( + NSSTrustDomain *td, + NSSUTF8 *nameComponents, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +); + +/* + * NSSTrustDomain_FindCertificateByEncodedCertificate + * + */ + +NSS_EXTERN NSSCertificate * +NSSTrustDomain_FindCertificateByEncodedCertificate +( + NSSTrustDomain *td, + NSSBER *encodedCertificate +); + +/* + * NSSTrustDomain_FindBestCertificateByEmail + * + */ + +NSS_EXTERN NSSCertificate * +NSSTrustDomain_FindCertificateByEmail +( + NSSTrustDomain *td, + NSSASCII7 *email, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt +); + +/* + * NSSTrustDomain_FindCertificatesByEmail + * + */ + +NSS_EXTERN NSSCertificate ** +NSSTrustDomain_FindCertificatesByEmail +( + NSSTrustDomain *td, + NSSASCII7 *email, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +); + +/* + * NSSTrustDomain_FindCertificateByOCSPHash + * + * There can be only one. + */ + +NSS_EXTERN NSSCertificate * +NSSTrustDomain_FindCertificateByOCSPHash +( + NSSTrustDomain *td, + NSSItem *hash +); + +/* + * NSSTrustDomain_TraverseCertificates + * + * This function descends from one in older versions of NSS which + * traverses the certs in the permanent database. That function + * was used to implement selection routines, but was directly + * available too. Trust domains are going to contain a lot more + * certs now (e.g., an ldap server), so we'd really like to + * discourage traversal. Thus for now, this is commented out. + * If it's needed, let's look at the situation more closely to + * find out what the actual requirements are. + */ + +/* For now, adding this function. This may only be for debugging + * purposes. + * Perhaps some equivalent function, on a specified token, will be + * needed in a "friend" header file? + */ +NSS_EXTERN PRStatus * +NSSTrustDomain_TraverseCertificates +( + NSSTrustDomain *td, + PRStatus (*callback)(NSSCertificate *c, void *arg), + void *arg +); + +/* + * NSSTrustDomain_FindBestUserCertificate + * + */ + +NSS_EXTERN NSSCertificate * +NSSTrustDomain_FindBestUserCertificate +( + NSSTrustDomain *td, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt +); + +/* + * NSSTrustDomain_FindUserCertificates + * + */ + +NSS_EXTERN NSSCertificate ** +NSSTrustDomain_FindUserCertificates +( + NSSTrustDomain *td, + NSSTime *timeOpt, + NSSUsage *usageOpt, + NSSPolicies *policiesOpt, + NSSCertificate **rvOpt, + PRUint32 rvLimit, /* zero for no limit */ + NSSArena *arenaOpt +); + +/* + * NSSTrustDomain_FindBestUserCertificateForSSLClientAuth + * + */ + +NSS_EXTERN NSSCertificate * +NSSTrustDomain_FindBestUserCertificateForSSLClientAuth +( + NSSTrustDomain *td, + NSSUTF8 *sslHostOpt, + NSSDER *rootCAsOpt[], /* null pointer for none */ + PRUint32 rootCAsMaxOpt, /* zero means list is null-terminated */ + NSSAlgorithmAndParameters *apOpt, + NSSPolicies *policiesOpt +); + +/* + * NSSTrustDomain_FindUserCertificatesForSSLClientAuth + * + */ + +NSS_EXTERN NSSCertificate ** +NSSTrustDomain_FindUserCertificatesForSSLClientAuth +( + NSSTrustDomain *td, + NSSUTF8 *sslHostOpt, + NSSDER *rootCAsOpt[], /* null pointer for none */ + PRUint32 rootCAsMaxOpt, /* zero means list is null-terminated */ + NSSAlgorithmAndParameters *apOpt, + NSSPolicies *policiesOpt, + NSSCertificate **rvOpt, + PRUint32 rvLimit, /* zero for no limit */ + NSSArena *arenaOpt +); + +/* + * NSSTrustDomain_FindBestUserCertificateForEmailSigning + * + */ + +NSS_EXTERN NSSCertificate * +NSSTrustDomain_FindBestUserCertificateForEmailSigning +( + NSSTrustDomain *td, + NSSASCII7 *signerOpt, + NSSASCII7 *recipientOpt, + /* anything more here? */ + NSSAlgorithmAndParameters *apOpt, + NSSPolicies *policiesOpt +); + +/* + * NSSTrustDomain_FindUserCertificatesForEmailSigning + * + */ + +NSS_EXTERN NSSCertificate ** +NSSTrustDomain_FindUserCertificatesForEmailSigning +( + NSSTrustDomain *td, + NSSASCII7 *signerOpt, + NSSASCII7 *recipientOpt, + /* anything more here? */ + NSSAlgorithmAndParameters *apOpt, + NSSPolicies *policiesOpt, + NSSCertificate **rvOpt, + PRUint32 rvLimit, /* zero for no limit */ + NSSArena *arenaOpt +); + +/* + * Here is where we'd add more Find[Best]UserCertificate[s]For<usage> + * routines. + */ + +/* Private Keys */ + +/* + * NSSTrustDomain_GenerateKeyPair + * + * Creates persistant objects. If you want session objects, use + * NSSCryptoContext_GenerateKeyPair. The destination token is where + * the keys are stored. If that token can do the required math, then + * that's where the keys are generated too. Otherwise, the keys are + * generated elsewhere and moved to that token. + */ + +NSS_EXTERN PRStatus +NSSTrustDomain_GenerateKeyPair +( + NSSTrustDomain *td, + NSSAlgorithmAndParameters *ap, + NSSPrivateKey **pvkOpt, + NSSPublicKey **pbkOpt, + PRBool privateKeyIsSensitive, + NSSToken *destination, + NSSCallback *uhhOpt +); + +/* + * NSSTrustDomain_TraversePrivateKeys + * + * + * NSS_EXTERN PRStatus * + * NSSTrustDomain_TraversePrivateKeys + * ( + * NSSTrustDomain *td, + * PRStatus (*callback)(NSSPrivateKey *vk, void *arg), + * void *arg + * ); + */ + +/* Symmetric Keys */ + +/* + * NSSTrustDomain_GenerateSymmetricKey + * + */ + +NSS_EXTERN NSSSymmetricKey * +NSSTrustDomain_GenerateSymmetricKey +( + NSSTrustDomain *td, + NSSAlgorithmAndParameters *ap, + PRUint32 keysize, + NSSToken *destination, + NSSCallback *uhhOpt +); + +/* + * NSSTrustDomain_GenerateSymmetricKeyFromPassword + * + */ + +NSS_EXTERN NSSSymmetricKey * +NSSTrustDomain_GenerateSymmetricKeyFromPassword +( + NSSTrustDomain *td, + NSSAlgorithmAndParameters *ap, + NSSUTF8 *passwordOpt, /* if null, prompt */ + NSSToken *destinationOpt, + NSSCallback *uhhOpt +); + +/* + * NSSTrustDomain_FindSymmetricKeyByAlgorithm + * + * Is this still needed? + * + * NSS_EXTERN NSSSymmetricKey * + * NSSTrustDomain_FindSymmetricKeyByAlgorithm + * ( + * NSSTrustDomain *td, + * NSSOID *algorithm, + * NSSCallback *uhhOpt + * ); + */ + +/* + * NSSTrustDomain_FindSymmetricKeyByAlgorithmAndKeyID + * + */ + +NSS_EXTERN NSSSymmetricKey * +NSSTrustDomain_FindSymmetricKeyByAlgorithmAndKeyID +( + NSSTrustDomain *td, + NSSOID *algorithm, + NSSItem *keyID, + NSSCallback *uhhOpt +); + +/* + * NSSTrustDomain_TraverseSymmetricKeys + * + * + * NSS_EXTERN PRStatus * + * NSSTrustDomain_TraverseSymmetricKeys + * ( + * NSSTrustDomain *td, + * PRStatus (*callback)(NSSSymmetricKey *mk, void *arg), + * void *arg + * ); + */ + +/* + * NSSTrustDomain_CreateCryptoContext + * + * If a callback object is specified, it becomes the for the crypto + * context; otherwise, this trust domain's default (if any) is + * inherited. + */ + +NSS_EXTERN NSSCryptoContext * +NSSTrustDomain_CreateCryptoContext +( + NSSTrustDomain *td, + NSSCallback *uhhOpt +); + +/* + * NSSTrustDomain_CreateCryptoContextForAlgorithm + * + */ + +NSS_EXTERN NSSCryptoContext * +NSSTrustDomain_CreateCryptoContextForAlgorithm +( + NSSTrustDomain *td, + NSSOID *algorithm +); + +/* + * NSSTrustDomain_CreateCryptoContextForAlgorithmAndParameters + * + */ + +NSS_EXTERN NSSCryptoContext * +NSSTrustDomain_CreateCryptoContextForAlgorithmAndParameters +( + NSSTrustDomain *td, + NSSAlgorithmAndParameters *ap +); + +/* find/traverse other objects, e.g. s/mime profiles */ + +/* + * NSSCryptoContext + * + * A crypto context is sort of a short-term snapshot of a trust domain, + * used for the life of "one crypto operation." You can also think of + * it as a "temporary database." + * + * Just about all of the things you can do with a trust domain -- importing + * or creating certs, keys, etc. -- can be done with a crypto context. + * The difference is that the objects will be temporary ("session") objects. + * + * Also, if the context was created for a key, cert, and/or algorithm; or + * if such objects have been "associated" with the context, then the context + * can do everything the keys can, like crypto operations. + * + * And finally, because it keeps the state of the crypto operations, it + * can do streaming crypto ops. + */ + +/* + * NSSTrustDomain_Destroy + * + */ + +NSS_EXTERN PRStatus +NSSCryptoContext_Destroy +( + NSSCryptoContext *cc +); + +/* establishing a default callback */ + +/* + * NSSCryptoContext_SetDefaultCallback + * + */ + +NSS_EXTERN PRStatus +NSSCryptoContext_SetDefaultCallback +( + NSSCryptoContext *cc, + NSSCallback *newCallback, + NSSCallback **oldCallbackOpt +); + +/* + * NSSCryptoContext_GetDefaultCallback + * + */ + +NSS_EXTERN NSSCallback * +NSSCryptoContext_GetDefaultCallback +( + NSSCryptoContext *cc, + PRStatus *statusOpt +); + +/* + * NSSCryptoContext_GetTrustDomain + * + */ + +NSS_EXTERN NSSTrustDomain * +NSSCryptoContext_GetTrustDomain +( + NSSCryptoContext *cc +); + +/* AddModule, etc: should we allow "temporary" changes here? */ +/* DisableToken, etc: ditto */ +/* Ordering of tokens? */ +/* Finding slots+token etc. */ +/* login+logout */ + +/* Importing things */ + +/* + * NSSCryptoContext_FindOrImportCertificate + * + * If the certificate store already contains this DER cert, return the + * address of the matching NSSCertificate that is already in the store, + * and bump its reference count. + * + * If this DER cert is NOT already in the store, then add the new + * NSSCertificate to the store and bump its reference count, + * then return its address. + * + * if this DER cert is not in the store and cannot be added to it, + * return NULL; + * + * Record the associated crypto context in the certificate. + */ + +NSS_EXTERN NSSCertificate * +NSSCryptoContext_FindOrImportCertificate ( + NSSCryptoContext *cc, + NSSCertificate *c +); + +/* + * NSSCryptoContext_ImportPKIXCertificate + * + */ + +NSS_EXTERN NSSCertificate * +NSSCryptoContext_ImportPKIXCertificate +( + NSSCryptoContext *cc, + struct NSSPKIXCertificateStr *pc +); + +/* + * NSSCryptoContext_ImportEncodedCertificate + * + */ + +NSS_EXTERN NSSCertificate * +NSSCryptoContext_ImportEncodedCertificate +( + NSSCryptoContext *cc, + NSSBER *ber +); + +/* + * NSSCryptoContext_ImportEncodedPKIXCertificateChain + * + */ + +NSS_EXTERN PRStatus +NSSCryptoContext_ImportEncodedPKIXCertificateChain +( + NSSCryptoContext *cc, + NSSBER *ber +); + +/* Other importations: S/MIME capabilities + */ + +/* + * NSSCryptoContext_FindBestCertificateByNickname + * + */ + +NSS_EXTERN NSSCertificate * +NSSCryptoContext_FindBestCertificateByNickname +( + NSSCryptoContext *cc, + const NSSUTF8 *name, + NSSTime *timeOpt, /* NULL for "now" */ + NSSUsage *usage, + NSSPolicies *policiesOpt /* NULL for none */ +); + +/* + * NSSCryptoContext_FindCertificatesByNickname + * + */ + +NSS_EXTERN NSSCertificate ** +NSSCryptoContext_FindCertificatesByNickname +( + NSSCryptoContext *cc, + NSSUTF8 *name, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +); + +/* + * NSSCryptoContext_FindCertificateByIssuerAndSerialNumber + * + */ + +NSS_EXTERN NSSCertificate * +NSSCryptoContext_FindCertificateByIssuerAndSerialNumber +( + NSSCryptoContext *cc, + NSSDER *issuer, + NSSDER *serialNumber +); + +/* + * NSSCryptoContext_FindBestCertificateBySubject + * + * This does not search through alternate names hidden in extensions. + */ + +NSS_EXTERN NSSCertificate * +NSSCryptoContext_FindBestCertificateBySubject +( + NSSCryptoContext *cc, + NSSDER /*NSSUTF8*/ *subject, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt +); + +/* + * NSSCryptoContext_FindCertificatesBySubject + * + * This does not search through alternate names hidden in extensions. + */ + +NSS_EXTERN NSSCertificate ** +NSSCryptoContext_FindCertificatesBySubject +( + NSSCryptoContext *cc, + NSSDER /*NSSUTF8*/ *subject, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +); + +/* + * NSSCryptoContext_FindBestCertificateByNameComponents + * + * This call does try several tricks, including a pseudo pkcs#11 + * attribute for the ldap module to try as a query. Eventually + * this call falls back to a traversal if that's what's required. + * It will search through alternate names hidden in extensions. + */ + +NSS_EXTERN NSSCertificate * +NSSCryptoContext_FindBestCertificateByNameComponents +( + NSSCryptoContext *cc, + NSSUTF8 *nameComponents, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt +); + +/* + * NSSCryptoContext_FindCertificatesByNameComponents + * + * This call, too, tries several tricks. It will stop on the first + * attempt that generates results, so it won't e.g. traverse the + * entire ldap database. + */ + +NSS_EXTERN NSSCertificate ** +NSSCryptoContext_FindCertificatesByNameComponents +( + NSSCryptoContext *cc, + NSSUTF8 *nameComponents, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +); + +/* + * NSSCryptoContext_FindCertificateByEncodedCertificate + * + */ + +NSS_EXTERN NSSCertificate * +NSSCryptoContext_FindCertificateByEncodedCertificate +( + NSSCryptoContext *cc, + NSSBER *encodedCertificate +); + +/* + * NSSCryptoContext_FindBestCertificateByEmail + * + */ + +NSS_EXTERN NSSCertificate * +NSSCryptoContext_FindBestCertificateByEmail +( + NSSCryptoContext *cc, + NSSASCII7 *email, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt +); + +/* + * NSSCryptoContext_FindCertificatesByEmail + * + */ + +NSS_EXTERN NSSCertificate ** +NSSCryptoContext_FindCertificatesByEmail +( + NSSCryptoContext *cc, + NSSASCII7 *email, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +); + +/* + * NSSCryptoContext_FindCertificateByOCSPHash + * + */ + +NSS_EXTERN NSSCertificate * +NSSCryptoContext_FindCertificateByOCSPHash +( + NSSCryptoContext *cc, + NSSItem *hash +); + +/* + * NSSCryptoContext_TraverseCertificates + * + * + * NSS_EXTERN PRStatus * + * NSSCryptoContext_TraverseCertificates + * ( + * NSSCryptoContext *cc, + * PRStatus (*callback)(NSSCertificate *c, void *arg), + * void *arg + * ); + */ + +/* + * NSSCryptoContext_FindBestUserCertificate + * + */ + +NSS_EXTERN NSSCertificate * +NSSCryptoContext_FindBestUserCertificate +( + NSSCryptoContext *cc, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt +); + +/* + * NSSCryptoContext_FindUserCertificates + * + */ + +NSS_EXTERN NSSCertificate ** +NSSCryptoContext_FindUserCertificates +( + NSSCryptoContext *cc, + NSSTime *timeOpt, + NSSUsage *usageOpt, + NSSPolicies *policiesOpt, + NSSCertificate **rvOpt, + PRUint32 rvLimit, /* zero for no limit */ + NSSArena *arenaOpt +); + +/* + * NSSCryptoContext_FindBestUserCertificateForSSLClientAuth + * + */ + +NSS_EXTERN NSSCertificate * +NSSCryptoContext_FindBestUserCertificateForSSLClientAuth +( + NSSCryptoContext *cc, + NSSUTF8 *sslHostOpt, + NSSDER *rootCAsOpt[], /* null pointer for none */ + PRUint32 rootCAsMaxOpt, /* zero means list is null-terminated */ + NSSAlgorithmAndParameters *apOpt, + NSSPolicies *policiesOpt +); + +/* + * NSSCryptoContext_FindUserCertificatesForSSLClientAuth + * + */ + +NSS_EXTERN NSSCertificate ** +NSSCryptoContext_FindUserCertificatesForSSLClientAuth +( + NSSCryptoContext *cc, + NSSUTF8 *sslHostOpt, + NSSDER *rootCAsOpt[], /* null pointer for none */ + PRUint32 rootCAsMaxOpt, /* zero means list is null-terminated */ + NSSAlgorithmAndParameters *apOpt, + NSSPolicies *policiesOpt, + NSSCertificate **rvOpt, + PRUint32 rvLimit, /* zero for no limit */ + NSSArena *arenaOpt +); + +/* + * NSSCryptoContext_FindBestUserCertificateForEmailSigning + * + */ + +NSS_EXTERN NSSCertificate * +NSSCryptoContext_FindBestUserCertificateForEmailSigning +( + NSSCryptoContext *cc, + NSSASCII7 *signerOpt, + NSSASCII7 *recipientOpt, + /* anything more here? */ + NSSAlgorithmAndParameters *apOpt, + NSSPolicies *policiesOpt +); + +/* + * NSSCryptoContext_FindUserCertificatesForEmailSigning + * + */ + +NSS_EXTERN NSSCertificate * +NSSCryptoContext_FindUserCertificatesForEmailSigning +( + NSSCryptoContext *cc, + NSSASCII7 *signerOpt, /* fgmr or a more general name? */ + NSSASCII7 *recipientOpt, + /* anything more here? */ + NSSAlgorithmAndParameters *apOpt, + NSSPolicies *policiesOpt, + NSSCertificate **rvOpt, + PRUint32 rvLimit, /* zero for no limit */ + NSSArena *arenaOpt +); + +/* Private Keys */ + +/* + * NSSCryptoContext_GenerateKeyPair + * + * Creates session objects. If you want persistant objects, use + * NSSTrustDomain_GenerateKeyPair. The destination token is where + * the keys are stored. If that token can do the required math, then + * that's where the keys are generated too. Otherwise, the keys are + * generated elsewhere and moved to that token. + */ + +NSS_EXTERN PRStatus +NSSCryptoContext_GenerateKeyPair +( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *ap, + NSSPrivateKey **pvkOpt, + NSSPublicKey **pbkOpt, + PRBool privateKeyIsSensitive, + NSSToken *destination, + NSSCallback *uhhOpt +); + +/* + * NSSCryptoContext_TraversePrivateKeys + * + * + * NSS_EXTERN PRStatus * + * NSSCryptoContext_TraversePrivateKeys + * ( + * NSSCryptoContext *cc, + * PRStatus (*callback)(NSSPrivateKey *vk, void *arg), + * void *arg + * ); + */ + +/* Symmetric Keys */ + +/* + * NSSCryptoContext_GenerateSymmetricKey + * + */ + +NSS_EXTERN NSSSymmetricKey * +NSSCryptoContext_GenerateSymmetricKey +( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *ap, + PRUint32 keysize, + NSSToken *destination, + NSSCallback *uhhOpt +); + +/* + * NSSCryptoContext_GenerateSymmetricKeyFromPassword + * + */ + +NSS_EXTERN NSSSymmetricKey * +NSSCryptoContext_GenerateSymmetricKeyFromPassword +( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *ap, + NSSUTF8 *passwordOpt, /* if null, prompt */ + NSSToken *destinationOpt, + NSSCallback *uhhOpt +); + +/* + * NSSCryptoContext_FindSymmetricKeyByAlgorithm + * + * + * NSS_EXTERN NSSSymmetricKey * + * NSSCryptoContext_FindSymmetricKeyByType + * ( + * NSSCryptoContext *cc, + * NSSOID *type, + * NSSCallback *uhhOpt + * ); + */ + +/* + * NSSCryptoContext_FindSymmetricKeyByAlgorithmAndKeyID + * + */ + +NSS_EXTERN NSSSymmetricKey * +NSSCryptoContext_FindSymmetricKeyByAlgorithmAndKeyID +( + NSSCryptoContext *cc, + NSSOID *algorithm, + NSSItem *keyID, + NSSCallback *uhhOpt +); + +/* + * NSSCryptoContext_TraverseSymmetricKeys + * + * + * NSS_EXTERN PRStatus * + * NSSCryptoContext_TraverseSymmetricKeys + * ( + * NSSCryptoContext *cc, + * PRStatus (*callback)(NSSSymmetricKey *mk, void *arg), + * void *arg + * ); + */ + +/* Crypto ops on distinguished keys */ + +/* + * NSSCryptoContext_Decrypt + * + */ + +NSS_EXTERN NSSItem * +NSSCryptoContext_Decrypt +( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSItem *encryptedData, + NSSCallback *uhhOpt, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSCryptoContext_BeginDecrypt + * + */ + +NSS_EXTERN PRStatus +NSSCryptoContext_BeginDecrypt +( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSCallback *uhhOpt +); + +/* + * NSSCryptoContext_ContinueDecrypt + * + */ + +/* + * NSSItem semantics: + * + * If rvOpt is NULL, a new NSSItem and buffer are allocated. + * If rvOpt is not null, but the buffer pointer is null, + * then rvOpt is returned but a new buffer is allocated. + * In this case, if the length value is not zero, then + * no more than that much space will be allocated. + * If rvOpt is not null and the buffer pointer is not null, + * then that buffer is re-used. No more than the buffer + * length value will be used; if it's not enough, an + * error is returned. If less is used, the number is + * adjusted downwards. + * + * Note that although this is short of some ideal "Item" + * definition, we can usually tell how big these buffers + * have to be. + * + * Feedback is requested; and earlier is better than later. + */ + +NSS_EXTERN NSSItem * +NSSCryptoContext_ContinueDecrypt +( + NSSCryptoContext *cc, + NSSItem *data, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSCryptoContext_FinishDecrypt + * + */ + +NSS_EXTERN NSSItem * +NSSCryptoContext_FinishDecrypt +( + NSSCryptoContext *cc, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSCryptoContext_Sign + * + */ + +NSS_EXTERN NSSItem * +NSSCryptoContext_Sign +( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSCallback *uhhOpt, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSCryptoContext_BeginSign + * + */ + +NSS_EXTERN PRStatus +NSSCryptoContext_BeginSign +( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSCallback *uhhOpt +); + +/* + * NSSCryptoContext_ContinueSign + * + */ + +NSS_EXTERN PRStatus +NSSCryptoContext_ContinueSign +( + NSSCryptoContext *cc, + NSSItem *data +); + +/* + * NSSCryptoContext_FinishSign + * + */ + +NSS_EXTERN NSSItem * +NSSCryptoContext_FinishSign +( + NSSCryptoContext *cc, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSCryptoContext_SignRecover + * + */ + +NSS_EXTERN NSSItem * +NSSCryptoContext_SignRecover +( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSCallback *uhhOpt, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSCryptoContext_BeginSignRecover + * + */ + +NSS_EXTERN PRStatus +NSSCryptoContext_BeginSignRecover +( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSCallback *uhhOpt +); + +/* + * NSSCryptoContext_ContinueSignRecover + * + */ + +NSS_EXTERN NSSItem * +NSSCryptoContext_ContinueSignRecover +( + NSSCryptoContext *cc, + NSSItem *data, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSCryptoContext_FinishSignRecover + * + */ + +NSS_EXTERN NSSItem * +NSSCryptoContext_FinishSignRecover +( + NSSCryptoContext *cc, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSCryptoContext_UnwrapSymmetricKey + * + */ + +NSS_EXTERN NSSSymmetricKey * +NSSCryptoContext_UnwrapSymmetricKey +( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSItem *wrappedKey, + NSSCallback *uhhOpt +); + +/* + * NSSCryptoContext_DeriveSymmetricKey + * + */ + +NSS_EXTERN NSSSymmetricKey * +NSSCryptoContext_DeriveSymmetricKey +( + NSSCryptoContext *cc, + NSSPublicKey *bk, + NSSAlgorithmAndParameters *apOpt, + NSSOID *target, + PRUint32 keySizeOpt, /* zero for best allowed */ + NSSOperations operations, + NSSCallback *uhhOpt +); + +/* + * NSSCryptoContext_Encrypt + * + * Encrypt a single chunk of data with the distinguished public key + * of this crypto context. + */ + +NSS_EXTERN NSSItem * +NSSCryptoContext_Encrypt +( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSCallback *uhhOpt, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSCryptoContext_BeginEncrypt + * + */ + +NSS_EXTERN PRStatus +NSSCryptoContext_BeginEncrypt +( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSCallback *uhhOpt +); + +/* + * NSSCryptoContext_ContinueEncrypt + * + */ + +NSS_EXTERN NSSItem * +NSSCryptoContext_ContinueEncrypt +( + NSSCryptoContext *cc, + NSSItem *data, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSCryptoContext_FinishEncrypt + * + */ + +NSS_EXTERN NSSItem * +NSSCryptoContext_FinishEncrypt +( + NSSCryptoContext *cc, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSCryptoContext_Verify + * + */ + +NSS_EXTERN PRStatus +NSSCryptoContext_Verify +( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSItem *signature, + NSSCallback *uhhOpt +); + +/* + * NSSCryptoContext_BeginVerify + * + */ + +NSS_EXTERN PRStatus +NSSCryptoContext_BeginVerify +( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSItem *signature, + NSSCallback *uhhOpt +); + +/* + * NSSCryptoContext_ContinueVerify + * + */ + +NSS_EXTERN PRStatus +NSSCryptoContext_ContinueVerify +( + NSSCryptoContext *cc, + NSSItem *data +); + +/* + * NSSCryptoContext_FinishVerify + * + */ + +NSS_EXTERN PRStatus +NSSCryptoContext_FinishVerify +( + NSSCryptoContext *cc +); + +/* + * NSSCryptoContext_VerifyRecover + * + */ + +NSS_EXTERN NSSItem * +NSSCryptoContext_VerifyRecover +( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSItem *signature, + NSSCallback *uhhOpt, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSCryptoContext_BeginVerifyRecover + * + */ + +NSS_EXTERN PRStatus +NSSCryptoContext_BeginVerifyRecover +( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSCallback *uhhOpt +); + +/* + * NSSCryptoContext_ContinueVerifyRecover + * + */ + +NSS_EXTERN NSSItem * +NSSCryptoContext_ContinueVerifyRecover +( + NSSCryptoContext *cc, + NSSItem *data, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSCryptoContext_FinishVerifyRecover + * + */ + +NSS_EXTERN NSSItem * +NSSCryptoContext_FinishVerifyRecover +( + NSSCryptoContext *cc, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSCryptoContext_WrapSymmetricKey + * + */ + +NSS_EXTERN NSSItem * +NSSCryptoContext_WrapSymmetricKey +( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSSymmetricKey *keyToWrap, + NSSCallback *uhhOpt, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSCryptoContext_Digest + * + * Digest a single chunk of data with the distinguished digest key + * of this crypto context. + */ + +NSS_EXTERN NSSItem * +NSSCryptoContext_Digest +( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSCallback *uhhOpt, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * NSSCryptoContext_BeginDigest + * + */ + +NSS_EXTERN PRStatus +NSSCryptoContext_BeginDigest +( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSCallback *uhhOpt +); + +/* + * NSSCryptoContext_ContinueDigest + * + */ + +NSS_EXTERN PRStatus +NSSCryptoContext_ContinueDigest +( + NSSCryptoContext *cc, + NSSAlgorithmAndParameters *apOpt, + NSSItem *item +); + +/* + * NSSCryptoContext_FinishDigest + * + */ + +NSS_EXTERN NSSItem * +NSSCryptoContext_FinishDigest +( + NSSCryptoContext *cc, + NSSItem *rvOpt, + NSSArena *arenaOpt +); + +/* + * tbd: Combination ops + */ + +/* + * NSSCryptoContext_Clone + * + */ + +NSS_EXTERN NSSCryptoContext * +NSSCryptoContext_Clone +( + NSSCryptoContext *cc +); + +/* + * NSSCryptoContext_Save + * NSSCryptoContext_Restore + * + * We need to be able to save and restore the state of contexts. + * Perhaps a mark-and-release mechanism would be better? + */ + +/* + * ..._SignTBSCertificate + * + * This requires feedback from the cert server team. + */ + +/* + * PRBool NSSCertificate_GetIsTrustedFor{xxx}(NSSCertificate *c); + * PRStatus NSSCertificate_SetIsTrustedFor{xxx}(NSSCertificate *c, PRBool trusted); + * + * These will be helper functions which get the trust object for a cert, + * and then call the corresponding function(s) on it. + * + * PKIX trust objects will have methods to manipulate the low-level trust + * bits (which are based on key usage and extended key usage), and also the + * conceptual high-level usages (e.g. ssl client auth, email encryption, etc.) + * + * Other types of trust objects (if any) might have different low-level + * representations, but hopefully high-level concepts would map. + * + * Only these high-level general routines would be promoted to the + * general certificate level here. Hence the {xxx} above would be things + * like "EmailSigning." + * + * + * NSSPKIXTrust *NSSCertificate_GetPKIXTrustObject(NSSCertificate *c); + * PRStatus NSSCertificate_SetPKIXTrustObject(NSSCertificate *c, NSPKIXTrust *t); + * + * I want to hold off on any general trust object until we've investigated + * other models more thoroughly. + */ + +PR_END_EXTERN_C + +#endif /* NSSPKI_H */ diff --git a/mozilla/security/nss/lib/pki/nsspkit.h b/mozilla/security/nss/lib/pki/nsspkit.h new file mode 100644 index 0000000..0487bba --- /dev/null +++ b/mozilla/security/nss/lib/pki/nsspkit.h @@ -0,0 +1,283 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef NSSPKIT_H +#define NSSPKIT_H + +#ifdef DEBUG +static const char NSSPKIT_CVS_ID[] = "@(#) $RCSfile: nsspkit.h,v $ $Revision: 1.8 $ $Date: 2010/05/21 00:02:48 $"; +#endif /* DEBUG */ + +/* + * nsspkit.h + * + * This file defines the types of the top-level PKI objects. + */ + +#ifndef NSSBASET_H +#include "nssbaset.h" +#endif /* NSSBASET_H */ + +PR_BEGIN_EXTERN_C + +/* + * NSSCertificate + * + * This is the public representation of a Certificate. The certificate + * may be one found on a smartcard or other token, one decoded from data + * received as part of a protocol, one constructed from constituent + * parts, etc. Usually it is associated with ("in") a trust domain; as + * it can be verified only within a trust domain. The underlying type + * of certificate may be of any supported standard, e.g. PKIX, PGP, etc. + * + * People speak of "verifying (with) the server's, or correspondant's, + * certificate"; for simple operations we support that simplification + * by implementing public-key crypto operations as methods on this type. + */ + +struct NSSCertificateStr; +typedef struct NSSCertificateStr NSSCertificate; + +/* + * NSSUserCertificate + * + * A ``User'' certificate is one for which the private key is available. + * People speak of "using my certificate to sign my email" and "using + * my certificate to authenticate to (or login to) the server"; for + * simple operations, we support that simplification by implementing + * private-key crypto operations as methods on this type. + * + * The current design only weakly distinguishes between certificates + * and user certificates: as far as the compiler goes they're + * interchangeable; debug libraries only have one common pointer-tracker; + * etc. However, attempts to do private-key operations on a certificate + * for which the private key is not available will fail. + * + * Open design question: should these types be more firmly separated? + */ + +typedef NSSCertificate NSSUserCertificate; + +/* + * NSSPrivateKey + * + * This is the public representation of a Private Key. In general, + * the actual value of the key is not available, but operations may + * be performed with it. + */ + +struct NSSPrivateKeyStr; +typedef struct NSSPrivateKeyStr NSSPrivateKey; + +/* + * NSSPublicKey + * + */ + +struct NSSPublicKeyStr; +typedef struct NSSPublicKeyStr NSSPublicKey; + +/* + * NSSSymmetricKey + * + */ + +struct NSSSymmetricKeyStr; +typedef struct NSSSymmetricKeyStr NSSSymmetricKey; + +/* + * NSSTrustDomain + * + * A Trust Domain is the field in which certificates may be validated. + * A trust domain will generally have one or more cryptographic modules + * open; these modules perform the cryptographic operations, and + * provide the basic "root" trust information from which the trust in + * a specific certificate or key depends. + * + * A client program, or a simple server, would typically have one + * trust domain. A server supporting multiple "virtual servers" might + * have a separate trust domain for each virtual server. The separate + * trust domains might share some modules (e.g., a hardware crypto + * accelerator) but not others (e.g., the tokens storing the different + * servers' private keys, or the databases with each server's trusted + * root certificates). + * + * This object descends from the "permananet database" in the old code. + */ + +struct NSSTrustDomainStr; +typedef struct NSSTrustDomainStr NSSTrustDomain; + +/* + * NSSCryptoContext + * + * A Crypto Context is a short-term, "helper" object which is used + * for the lifetime of one ongoing "crypto operation." Such an + * operation may be the creation of a signed message, the use of an + * TLS socket connection, etc. Each crypto context is "in" a + * specific trust domain, and it may have associated with it a + * distinguished certificate, public key, private key, and/or + * symmetric key. It can also temporarily hold and use temporary + * data (e.g. intermediate certificates) which is not stored + * permanently in the trust domain. + * + * In OO terms, this interface inherits interfaces from the trust + * domain, the certificates, and the keys. It also provides + * streaming crypto operations. + * + * This object descends from the "temporary database" concept in the + * old code, but it has changed a lot as a result of what we've + * learned. + */ + +typedef struct NSSCryptoContextStr NSSCryptoContext; + +/* + * fgmr others + */ + +/* + * OBJECT IDENTIFIER + * + * This is the basic OID that crops up everywhere. + */ + +struct NSSOIDStr; /* unused opaque structure */ +typedef struct NSSOIDStr NSSOID; + +/* + * NSSTime + * + * Unfortunately, we need an "exceptional" value to indicate + * an error upon return, or "no value" on input. Note that zero + * is a perfectly valid value for both time_t and PRTime. + * + * If we were to create a "range" object, with two times for + * Not Before and Not After, we would have an obvious place for + * the somewhat arbitrary logic involved in comparing them. + * + * Failing that, let's have an NSSTime_CompareRanges function. + */ + +struct NSSTimeStr; +typedef struct NSSTimeStr NSSTime; + +struct NSSTrustStr; +typedef struct NSSTrustStr NSSTrust; + +/* + * NSSUsage + * + * This is trickier than originally planned; I'll write up a + * doc on it. + * + * We'd still like nsspki.h to have a list of common usages, + * e.g.: + * + * extern const NSSUsage *NSSUsage_ClientAuth; + * extern const NSSUsage *NSSUsage_ServerAuth; + * extern const NSSUsage *NSSUsage_SignEmail; + * extern const NSSUsage *NSSUsage_EncryptEmail; + * etc. + */ + +struct NSSUsageStr; +typedef struct NSSUsageStr NSSUsage; + +/* + * NSSPolicies + * + * Placeholder, for now. + */ + +struct NSSPoliciesStr; +typedef struct NSSPoliciesStr NSSPolicies; + +/* + * NSSAlgorithmAndParameters + * + * Algorithm is an OID + * Parameters depend on the algorithm + */ + +struct NSSAlgorithmAndParametersStr; +typedef struct NSSAlgorithmAndParametersStr NSSAlgorithmAndParameters; + +/* + * NSSCallback + * + * At minimum, a "challenge" method and a closure argument. + * Usually the challenge will just be prompting for a password. + * How OO do we want to make it? + */ + +typedef struct NSSCallbackStr NSSCallback; + +struct NSSCallbackStr { + /* Prompt for a password to initialize a slot. */ + PRStatus (* getInitPW)(NSSUTF8 *slotName, void *arg, + NSSUTF8 **ssoPW, NSSUTF8 **userPW); + /* Prompt for oldPW and newPW in order to change the + * password on a slot. + */ + PRStatus (* getNewPW)(NSSUTF8 *slotName, PRUint32 *retries, void *arg, + NSSUTF8 **oldPW, NSSUTF8 **newPW); + /* Prompt for slot password. */ + PRStatus (* getPW)(NSSUTF8 *slotName, PRUint32 *retries, void *arg, + NSSUTF8 **password); + void *arg; +}; + +/* set errors - user cancelled, ... */ + +typedef PRUint32 NSSOperations; +/* 1) Do we want these to be preprocessor definitions or constants? */ +/* 2) What is the correct and complete list? */ + +#define NSSOperations_ENCRYPT 0x0001 +#define NSSOperations_DECRYPT 0x0002 +#define NSSOperations_WRAP 0x0004 +#define NSSOperations_UNWRAP 0x0008 +#define NSSOperations_SIGN 0x0010 +#define NSSOperations_SIGN_RECOVER 0x0020 +#define NSSOperations_VERIFY 0x0040 +#define NSSOperations_VERIFY_RECOVER 0x0080 + +struct NSSPKIXCertificateStr; + +PR_END_EXTERN_C + +#endif /* NSSPKIT_H */ diff --git a/mozilla/security/nss/lib/pki/pki.h b/mozilla/security/nss/lib/pki/pki.h new file mode 100644 index 0000000..0ae5de9 --- /dev/null +++ b/mozilla/security/nss/lib/pki/pki.h @@ -0,0 +1,248 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef PKI_H +#define PKI_H + +#ifdef DEBUG +static const char PKI_CVS_ID[] = "@(#) $RCSfile: pki.h,v $ $Revision: 1.13 $ $Date: 2005/01/20 02:25:49 $"; +#endif /* DEBUG */ + +#ifndef NSSDEVT_H +#include "nssdevt.h" +#endif /* NSSDEVT_H */ + +#ifndef NSSPKI_H +#include "nsspki.h" +#endif /* NSSPKI_H */ + +#ifndef PKIT_H +#include "pkit.h" +#endif /* PKIT_H */ + +PR_BEGIN_EXTERN_C + +NSS_EXTERN NSSCallback * +nssTrustDomain_GetDefaultCallback +( + NSSTrustDomain *td, + PRStatus *statusOpt +); + +NSS_EXTERN NSSCertificate ** +nssTrustDomain_FindCertificatesBySubject +( + NSSTrustDomain *td, + NSSDER *subject, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, + NSSArena *arenaOpt +); + +NSS_EXTERN NSSTrust * +nssTrustDomain_FindTrustForCertificate +( + NSSTrustDomain *td, + NSSCertificate *c +); + +NSS_EXTERN NSSCertificate * +nssCertificate_AddRef +( + NSSCertificate *c +); + +NSS_EXTERN PRStatus +nssCertificate_Destroy +( + NSSCertificate *c +); + +NSS_EXTERN NSSDER * +nssCertificate_GetEncoding +( + NSSCertificate *c +); + +NSS_EXTERN NSSDER * +nssCertificate_GetIssuer +( + NSSCertificate *c +); + +NSS_EXTERN NSSDER * +nssCertificate_GetSerialNumber +( + NSSCertificate *c +); + +NSS_EXTERN NSSDER * +nssCertificate_GetSubject +( + NSSCertificate *c +); + +NSS_EXTERN NSSUTF8 * +nssCertificate_GetNickname +( + NSSCertificate *c, + NSSToken *tokenOpt +); + +NSS_EXTERN NSSASCII7 * +nssCertificate_GetEmailAddress +( + NSSCertificate *c +); + +NSS_EXTERN PRBool +nssCertificate_IssuerAndSerialEqual +( + NSSCertificate *c1, + NSSCertificate *c2 +); + +NSS_EXTERN NSSPrivateKey * +nssPrivateKey_AddRef +( + NSSPrivateKey *vk +); + +NSS_EXTERN PRStatus +nssPrivateKey_Destroy +( + NSSPrivateKey *vk +); + +NSS_EXTERN NSSItem * +nssPrivateKey_GetID +( + NSSPrivateKey *vk +); + +NSS_EXTERN NSSUTF8 * +nssPrivateKey_GetNickname +( + NSSPrivateKey *vk, + NSSToken *tokenOpt +); + +NSS_EXTERN PRStatus +nssPublicKey_Destroy +( + NSSPublicKey *bk +); + +NSS_EXTERN NSSItem * +nssPublicKey_GetID +( + NSSPublicKey *vk +); + +NSS_EXTERN NSSCertificate ** +nssCryptoContext_FindCertificatesBySubject +( + NSSCryptoContext *cc, + NSSDER *subject, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +); + +/* putting here for now, needs more thought */ +NSS_EXTERN PRStatus +nssCryptoContext_ImportTrust +( + NSSCryptoContext *cc, + NSSTrust *trust +); + +NSS_EXTERN NSSTrust * +nssCryptoContext_FindTrustForCertificate +( + NSSCryptoContext *cc, + NSSCertificate *cert +); + +NSS_EXTERN PRStatus +nssCryptoContext_ImportSMIMEProfile +( + NSSCryptoContext *cc, + nssSMIMEProfile *profile +); + +NSS_EXTERN nssSMIMEProfile * +nssCryptoContext_FindSMIMEProfileForCertificate +( + NSSCryptoContext *cc, + NSSCertificate *cert +); + +NSS_EXTERN NSSTrust * +nssTrust_AddRef +( + NSSTrust *trust +); + +NSS_EXTERN PRStatus +nssTrust_Destroy +( + NSSTrust *trust +); + +NSS_EXTERN nssSMIMEProfile * +nssSMIMEProfile_AddRef +( + nssSMIMEProfile *profile +); + +NSS_EXTERN PRStatus +nssSMIMEProfile_Destroy +( + nssSMIMEProfile *profile +); + +NSS_EXTERN nssSMIMEProfile * +nssSMIMEProfile_Create +( + NSSCertificate *cert, + NSSItem *profileTime, + NSSItem *profileData +); + +PR_END_EXTERN_C + +#endif /* PKI_H */ diff --git a/mozilla/security/nss/lib/pki/pki3hack.c b/mozilla/security/nss/lib/pki/pki3hack.c new file mode 100644 index 0000000..b13a05e --- /dev/null +++ b/mozilla/security/nss/lib/pki/pki3hack.c @@ -0,0 +1,1391 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifdef DEBUG +static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.100.2.1 $ $Date: 2011/03/26 16:55:01 $"; +#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 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->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->getEmailAddress = nss3certificate_getEmailAddress; + } + 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(CK_TRUST t) +{ + unsigned int rt = 0; + if (t == nssTrustLevel_Trusted) { + rt |= CERTDB_VALID_PEER | CERTDB_TRUSTED; + } + if (t == nssTrustLevel_TrustedDelegator) { + rt |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA /*| CERTDB_NS_TRUSTED_CA*/; + } + if (t == nssTrustLevel_Valid) { + rt |= CERTDB_VALID_PEER; + } + 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); + /* The cert is a valid step-up cert (in addition to/lieu of trust above */ + if (t->stepUpApproved) { + rvTrust->sslFlags |= CERTDB_GOVT_APPROVED_CA; + } + 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) { + 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 */ + cc->trust = trust; + } + 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 */ + cc->trust = trust; + } + 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; + + 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 (!cc->trust && !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); + cc->trust = trust; + } + + 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_VALID_CA) { + return nssTrustLevel_ValidDelegator; + } + if (t & CERTDB_VALID_PEER) { + return nssTrustLevel_Valid; + } + return nssTrustLevel_NotTrusted; +} + +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; + nssListIterator *tokens; + PRBool moving_object; + nssCryptokiObject *newInstance; + nssPKIObject *pkiob; + + if (c == NULL) { + return SECFailure; + } + 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 */ + cc->trust = oldTrust; + } + } else { + cc->trust = PORT_ArenaAlloc(cc->arena, sizeof(CERTCertTrust)); + } + memcpy(cc->trust, trust, sizeof(CERTCertTrust)); + /* 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); + 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); + 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); + } +} + diff --git a/mozilla/security/nss/lib/pki/pki3hack.h b/mozilla/security/nss/lib/pki/pki3hack.h new file mode 100644 index 0000000..b9ce7f7 --- /dev/null +++ b/mozilla/security/nss/lib/pki/pki3hack.h @@ -0,0 +1,200 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef PKINSS3HACK_H +#define PKINSS3HACK_H + +#ifdef DEBUG +static const char PKINSS3HACK_CVS_ID[] = "@(#) $RCSfile: pki3hack.h,v $ $Revision: 1.19.192.1 $ $Date: 2011/03/26 16:55:01 $"; +#endif /* DEBUG */ + +#ifndef NSSDEVT_H +#include "nssdevt.h" +#endif /* NSSDEVT_H */ + +#ifndef DEVT_H +#include "devt.h" +#endif /* DEVT_H */ + +#ifndef NSSPKIT_H +#include "nsspkit.h" +#endif /* NSSPKIT_H */ + +#include "base.h" + +#include "cert.h" + +PR_BEGIN_EXTERN_C + +#define NSSITEM_FROM_SECITEM(nssit, secit) \ + (nssit)->data = (void *)(secit)->data; \ + (nssit)->size = (PRUint32)(secit)->len; + +#define SECITEM_FROM_NSSITEM(secit, nssit) \ + (secit)->data = (unsigned char *)(nssit)->data; \ + (secit)->len = (unsigned int)(nssit)->size; + +NSS_EXTERN NSSTrustDomain * +STAN_GetDefaultTrustDomain(); + +NSS_EXTERN NSSCryptoContext * +STAN_GetDefaultCryptoContext(); + +NSS_EXTERN PRStatus +STAN_InitTokenForSlotInfo(NSSTrustDomain *td, PK11SlotInfo *slot); + +NSS_EXTERN PRStatus +STAN_ResetTokenInterator(NSSTrustDomain *td); + +NSS_EXTERN PRStatus +STAN_LoadDefaultNSS3TrustDomain(void); + +NSS_EXTERN PRStatus +STAN_Shutdown(); + +NSS_EXTERN SECStatus +STAN_AddModuleToDefaultTrustDomain(SECMODModule *module); + +NSS_EXTERN SECStatus +STAN_RemoveModuleFromDefaultTrustDomain(SECMODModule *module); + +NSS_EXTERN CERTCertificate * +STAN_ForceCERTCertificateUpdate(NSSCertificate *c); + +NSS_EXTERN CERTCertificate * +STAN_GetCERTCertificate(NSSCertificate *c); + +NSS_EXTERN CERTCertificate * +STAN_GetCERTCertificateOrRelease(NSSCertificate *c); + +NSS_EXTERN NSSCertificate * +STAN_GetNSSCertificate(CERTCertificate *c); + +NSS_EXTERN CERTCertTrust * +nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc); + +NSS_EXTERN PRStatus +STAN_DeleteCertTrustMatchingSlot(NSSCertificate *c); + +NSS_EXTERN PRStatus +STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust); + +NSS_EXTERN PRStatus +nssPKIX509_GetIssuerAndSerialFromDER(NSSDER *der, NSSArena *arena, + NSSDER *issuer, NSSDER *serial); + +NSS_EXTERN char * +STAN_GetCERTCertificateName(PLArenaPool *arenaOpt, NSSCertificate *c); + +NSS_EXTERN char * +STAN_GetCERTCertificateNameForInstance(PLArenaPool *arenaOpt, + NSSCertificate *c, + nssCryptokiInstance *instance); + +/* exposing this */ +NSS_EXTERN NSSCertificate * +NSSCertificate_Create +( + NSSArena *arenaOpt +); + +/* This function is being put here because it is a hack for + * PK11_FindCertFromNickname. + */ +NSS_EXTERN NSSCertificate * +nssTrustDomain_FindBestCertificateByNicknameForToken +( + NSSTrustDomain *td, + NSSToken *token, + NSSUTF8 *name, + NSSTime *timeOpt, /* NULL for "now" */ + NSSUsage *usage, + NSSPolicies *policiesOpt /* NULL for none */ +); + +/* This function is being put here because it is a hack for + * PK11_FindCertsFromNickname. + */ +NSS_EXTERN NSSCertificate ** +nssTrustDomain_FindCertificatesByNicknameForToken +( + NSSTrustDomain *td, + NSSToken *token, + NSSUTF8 *name, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +); + +/* CERT_TraversePermCertsForSubject */ +NSS_EXTERN PRStatus +nssTrustDomain_TraverseCertificatesBySubject +( + NSSTrustDomain *td, + NSSDER *subject, + PRStatus (*callback)(NSSCertificate *c, void *arg), + void *arg +); + +/* CERT_TraversePermCertsForNickname */ +NSS_EXTERN PRStatus +nssTrustDomain_TraverseCertificatesByNickname +( + NSSTrustDomain *td, + NSSUTF8 *nickname, + PRStatus (*callback)(NSSCertificate *c, void *arg), + void *arg +); + +/* SEC_TraversePermCerts */ +NSS_EXTERN PRStatus +nssTrustDomain_TraverseCertificates +( + NSSTrustDomain *td, + PRStatus (*callback)(NSSCertificate *c, void *arg), + void *arg +); + +/* CERT_AddTempCertToPerm */ +NSS_EXTERN PRStatus +nssTrustDomain_AddTempCertToPerm +( + NSSCertificate *c +); + +PR_END_EXTERN_C + +#endif /* PKINSS3HACK_H */ diff --git a/mozilla/security/nss/lib/pki/pkibase.c b/mozilla/security/nss/lib/pki/pkibase.c new file mode 100644 index 0000000..fbddae5 --- /dev/null +++ b/mozilla/security/nss/lib/pki/pkibase.c @@ -0,0 +1,1268 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifdef DEBUG +static const char CVS_ID[] = "@(#) $RCSfile: pkibase.c,v $ $Revision: 1.33 $ $Date: 2010/04/03 18:27:32 $"; +#endif /* DEBUG */ + +#ifndef DEV_H +#include "dev.h" +#endif /* DEV_H */ + +#ifndef PKIM_H +#include "pkim.h" +#endif /* PKIM_H */ + +#include "pki3hack.h" + +extern const NSSError NSS_ERROR_NOT_FOUND; + +NSS_IMPLEMENT void +nssPKIObject_Lock(nssPKIObject * object) +{ + switch (object->lockType) { + case nssPKIMonitor: + PZ_EnterMonitor(object->sync.mlock); + break; + case nssPKILock: + PZ_Lock(object->sync.lock); + break; + default: + PORT_Assert(0); + } +} + +NSS_IMPLEMENT void +nssPKIObject_Unlock(nssPKIObject * object) +{ + switch (object->lockType) { + case nssPKIMonitor: + PZ_ExitMonitor(object->sync.mlock); + break; + case nssPKILock: + PZ_Unlock(object->sync.lock); + break; + default: + PORT_Assert(0); + } +} + +NSS_IMPLEMENT PRStatus +nssPKIObject_NewLock(nssPKIObject * object, nssPKILockType lockType) +{ + object->lockType = lockType; + switch (lockType) { + case nssPKIMonitor: + object->sync.mlock = PZ_NewMonitor(nssILockSSL); + return (object->sync.mlock ? PR_SUCCESS : PR_FAILURE); + case nssPKILock: + object->sync.lock = PZ_NewLock(nssILockSSL); + return (object->sync.lock ? PR_SUCCESS : PR_FAILURE); + default: + PORT_Assert(0); + return PR_FAILURE; + } +} + +NSS_IMPLEMENT void +nssPKIObject_DestroyLock(nssPKIObject * object) +{ + switch (object->lockType) { + case nssPKIMonitor: + PZ_DestroyMonitor(object->sync.mlock); + object->sync.mlock = NULL; + break; + case nssPKILock: + PZ_DestroyLock(object->sync.lock); + object->sync.lock = NULL; + break; + default: + PORT_Assert(0); + } +} + + + +NSS_IMPLEMENT nssPKIObject * +nssPKIObject_Create ( + NSSArena *arenaOpt, + nssCryptokiObject *instanceOpt, + NSSTrustDomain *td, + NSSCryptoContext *cc, + nssPKILockType lockType +) +{ + NSSArena *arena; + nssArenaMark *mark = NULL; + nssPKIObject *object; + if (arenaOpt) { + arena = arenaOpt; + mark = nssArena_Mark(arena); + } else { + arena = nssArena_Create(); + if (!arena) { + return (nssPKIObject *)NULL; + } + } + object = nss_ZNEW(arena, nssPKIObject); + if (!object) { + goto loser; + } + object->arena = arena; + object->trustDomain = td; /* XXX */ + object->cryptoContext = cc; + if (PR_SUCCESS != nssPKIObject_NewLock(object, lockType)) { + goto loser; + } + if (instanceOpt) { + if (nssPKIObject_AddInstance(object, instanceOpt) != PR_SUCCESS) { + goto loser; + } + } + PR_ATOMIC_INCREMENT(&object->refCount); + if (mark) { + nssArena_Unmark(arena, mark); + } + return object; +loser: + if (mark) { + nssArena_Release(arena, mark); + } else { + nssArena_Destroy(arena); + } + return (nssPKIObject *)NULL; +} + +NSS_IMPLEMENT PRBool +nssPKIObject_Destroy ( + nssPKIObject *object +) +{ + PRUint32 i; + PR_ASSERT(object->refCount > 0); + if (PR_ATOMIC_DECREMENT(&object->refCount) == 0) { + for (i=0; i<object->numInstances; i++) { + nssCryptokiObject_Destroy(object->instances[i]); + } + nssPKIObject_DestroyLock(object); + nssArena_Destroy(object->arena); + return PR_TRUE; + } + return PR_FALSE; +} + +NSS_IMPLEMENT nssPKIObject * +nssPKIObject_AddRef ( + nssPKIObject *object +) +{ + PR_ATOMIC_INCREMENT(&object->refCount); + return object; +} + +NSS_IMPLEMENT PRStatus +nssPKIObject_AddInstance ( + nssPKIObject *object, + nssCryptokiObject *instance +) +{ + nssCryptokiObject **newInstances = NULL; + + nssPKIObject_Lock(object); + if (object->numInstances == 0) { + newInstances = nss_ZNEWARRAY(object->arena, + nssCryptokiObject *, + object->numInstances + 1); + } else { + PRBool found = PR_FALSE; + PRUint32 i; + for (i=0; i<object->numInstances; i++) { + if (nssCryptokiObject_Equal(object->instances[i], instance)) { + found = PR_TRUE; + break; + } + } + if (found) { + /* The new instance is identical to one in the array, except + * perhaps that the label may be different. So replace + * the label in the array instance with the label from the + * new instance, and discard the new instance. + */ + nss_ZFreeIf(object->instances[i]->label); + object->instances[i]->label = instance->label; + nssPKIObject_Unlock(object); + instance->label = NULL; + nssCryptokiObject_Destroy(instance); + return PR_SUCCESS; + } + newInstances = nss_ZREALLOCARRAY(object->instances, + nssCryptokiObject *, + object->numInstances + 1); + } + if (newInstances) { + object->instances = newInstances; + newInstances[object->numInstances++] = instance; + } + nssPKIObject_Unlock(object); + return (newInstances ? PR_SUCCESS : PR_FAILURE); +} + +NSS_IMPLEMENT PRBool +nssPKIObject_HasInstance ( + nssPKIObject *object, + nssCryptokiObject *instance +) +{ + PRUint32 i; + PRBool hasIt = PR_FALSE;; + nssPKIObject_Lock(object); + for (i=0; i<object->numInstances; i++) { + if (nssCryptokiObject_Equal(object->instances[i], instance)) { + hasIt = PR_TRUE; + break; + } + } + nssPKIObject_Unlock(object); + return hasIt; +} + +NSS_IMPLEMENT PRStatus +nssPKIObject_RemoveInstanceForToken ( + nssPKIObject *object, + NSSToken *token +) +{ + PRUint32 i; + nssCryptokiObject *instanceToRemove = NULL; + nssPKIObject_Lock(object); + if (object->numInstances == 0) { + nssPKIObject_Unlock(object); + return PR_SUCCESS; + } + for (i=0; i<object->numInstances; i++) { + if (object->instances[i]->token == token) { + instanceToRemove = object->instances[i]; + object->instances[i] = object->instances[object->numInstances-1]; + object->instances[object->numInstances-1] = NULL; + break; + } + } + if (--object->numInstances > 0) { + nssCryptokiObject **instances = nss_ZREALLOCARRAY(object->instances, + nssCryptokiObject *, + object->numInstances); + if (instances) { + object->instances = instances; + } + } else { + nss_ZFreeIf(object->instances); + } + nssCryptokiObject_Destroy(instanceToRemove); + nssPKIObject_Unlock(object); + return PR_SUCCESS; +} + +/* this needs more thought on what will happen when there are multiple + * instances + */ +NSS_IMPLEMENT PRStatus +nssPKIObject_DeleteStoredObject ( + nssPKIObject *object, + NSSCallback *uhh, + PRBool isFriendly +) +{ + PRUint32 i, numNotDestroyed; + PRStatus status = PR_SUCCESS; + numNotDestroyed = 0; + nssPKIObject_Lock(object); + for (i=0; i<object->numInstances; i++) { + nssCryptokiObject *instance = object->instances[i]; + status = nssToken_DeleteStoredObject(instance); + object->instances[i] = NULL; + if (status == PR_SUCCESS) { + nssCryptokiObject_Destroy(instance); + } else { + object->instances[numNotDestroyed++] = instance; + } + } + if (numNotDestroyed == 0) { + nss_ZFreeIf(object->instances); + object->numInstances = 0; + } else { + object->numInstances = numNotDestroyed; + } + nssPKIObject_Unlock(object); + return status; +} + +NSS_IMPLEMENT NSSToken ** +nssPKIObject_GetTokens ( + nssPKIObject *object, + PRStatus *statusOpt +) +{ + NSSToken **tokens = NULL; + nssPKIObject_Lock(object); + if (object->numInstances > 0) { + tokens = nss_ZNEWARRAY(NULL, NSSToken *, object->numInstances + 1); + if (tokens) { + PRUint32 i; + for (i=0; i<object->numInstances; i++) { + tokens[i] = nssToken_AddRef(object->instances[i]->token); + } + } + } + nssPKIObject_Unlock(object); + if (statusOpt) *statusOpt = PR_SUCCESS; /* until more logic here */ + return tokens; +} + +NSS_IMPLEMENT NSSUTF8 * +nssPKIObject_GetNicknameForToken ( + nssPKIObject *object, + NSSToken *tokenOpt +) +{ + PRUint32 i; + NSSUTF8 *nickname = NULL; + nssPKIObject_Lock(object); + for (i=0; i<object->numInstances; i++) { + if ((!tokenOpt && object->instances[i]->label) || + (object->instances[i]->token == tokenOpt)) + { + /* XXX should be copy? safe as long as caller has reference */ + nickname = object->instances[i]->label; + break; + } + } + nssPKIObject_Unlock(object); + return nickname; +} + +NSS_IMPLEMENT nssCryptokiObject ** +nssPKIObject_GetInstances ( + nssPKIObject *object +) +{ + nssCryptokiObject **instances = NULL; + PRUint32 i; + if (object->numInstances == 0) { + return (nssCryptokiObject **)NULL; + } + nssPKIObject_Lock(object); + instances = nss_ZNEWARRAY(NULL, nssCryptokiObject *, + object->numInstances + 1); + if (instances) { + for (i=0; i<object->numInstances; i++) { + instances[i] = nssCryptokiObject_Clone(object->instances[i]); + } + } + nssPKIObject_Unlock(object); + return instances; +} + +NSS_IMPLEMENT void +nssCertificateArray_Destroy ( + NSSCertificate **certs +) +{ + if (certs) { + NSSCertificate **certp; + for (certp = certs; *certp; certp++) { + if ((*certp)->decoding) { + CERTCertificate *cc = STAN_GetCERTCertificate(*certp); + if (cc) { + CERT_DestroyCertificate(cc); + } + continue; + } + nssCertificate_Destroy(*certp); + } + nss_ZFreeIf(certs); + } +} + +NSS_IMPLEMENT void +NSSCertificateArray_Destroy ( + NSSCertificate **certs +) +{ + nssCertificateArray_Destroy(certs); +} + +NSS_IMPLEMENT NSSCertificate ** +nssCertificateArray_Join ( + NSSCertificate **certs1, + NSSCertificate **certs2 +) +{ + if (certs1 && certs2) { + NSSCertificate **certs, **cp; + PRUint32 count = 0; + PRUint32 count1 = 0; + cp = certs1; + while (*cp++) count1++; + count = count1; + cp = certs2; + while (*cp++) count++; + certs = nss_ZREALLOCARRAY(certs1, NSSCertificate *, count + 1); + if (!certs) { + nss_ZFreeIf(certs1); + nss_ZFreeIf(certs2); + return (NSSCertificate **)NULL; + } + for (cp = certs2; *cp; cp++, count1++) { + certs[count1] = *cp; + } + nss_ZFreeIf(certs2); + return certs; + } else if (certs1) { + return certs1; + } else { + return certs2; + } +} + +NSS_IMPLEMENT NSSCertificate * +nssCertificateArray_FindBestCertificate ( + NSSCertificate **certs, + NSSTime *timeOpt, + const NSSUsage *usage, + NSSPolicies *policiesOpt +) +{ + NSSCertificate *bestCert = NULL; + NSSTime *time, sTime; + PRBool haveUsageMatch = PR_FALSE; + PRBool thisCertMatches; + + if (timeOpt) { + time = timeOpt; + } else { + NSSTime_Now(&sTime); + time = &sTime; + } + if (!certs) { + return (NSSCertificate *)NULL; + } + for (; *certs; certs++) { + nssDecodedCert *dc, *bestdc; + NSSCertificate *c = *certs; + dc = nssCertificate_GetDecoding(c); + if (!dc) continue; + thisCertMatches = dc->matchUsage(dc, usage); + if (!bestCert) { + /* always take the first cert, but remember whether or not + * the usage matched + */ + bestCert = nssCertificate_AddRef(c); + haveUsageMatch = thisCertMatches; + continue; + } else { + if (haveUsageMatch && !thisCertMatches) { + /* if already have a cert for this usage, and if this cert + * doesn't have the correct usage, continue + */ + continue; + } else if (!haveUsageMatch && thisCertMatches) { + /* this one does match usage, replace the other */ + nssCertificate_Destroy(bestCert); + bestCert = nssCertificate_AddRef(c); + haveUsageMatch = PR_TRUE; + continue; + } + /* this cert match as well as any cert we've found so far, + * defer to time/policies + * */ + } + bestdc = nssCertificate_GetDecoding(bestCert); + if (!bestdc) { + nssCertificate_Destroy(bestCert); + bestCert = nssCertificate_AddRef(c); + continue; + } + /* time */ + if (bestdc->isValidAtTime(bestdc, time)) { + /* The current best cert is valid at time */ + if (!dc->isValidAtTime(dc, time)) { + /* If the new cert isn't valid at time, it's not better */ + continue; + } + } else { + /* The current best cert is not valid at time */ + if (dc->isValidAtTime(dc, time)) { + /* If the new cert is valid at time, it's better */ + nssCertificate_Destroy(bestCert); + bestCert = nssCertificate_AddRef(c); + } + } + /* either they are both valid at time, or neither valid; + * take the newer one + */ + if (!bestdc->isNewerThan(bestdc, dc)) { + nssCertificate_Destroy(bestCert); + bestCert = nssCertificate_AddRef(c); + } + /* policies */ + /* XXX later -- defer to policies */ + } + return bestCert; +} + +NSS_IMPLEMENT PRStatus +nssCertificateArray_Traverse ( + NSSCertificate **certs, + PRStatus (* callback)(NSSCertificate *c, void *arg), + void *arg +) +{ + PRStatus status = PR_SUCCESS; + if (certs) { + NSSCertificate **certp; + for (certp = certs; *certp; certp++) { + status = (*callback)(*certp, arg); + if (status != PR_SUCCESS) { + break; + } + } + } + return status; +} + + +NSS_IMPLEMENT void +nssCRLArray_Destroy ( + NSSCRL **crls +) +{ + if (crls) { + NSSCRL **crlp; + for (crlp = crls; *crlp; crlp++) { + nssCRL_Destroy(*crlp); + } + nss_ZFreeIf(crls); + } +} + +/* + * Object collections + */ + +typedef enum +{ + pkiObjectType_Certificate = 0, + pkiObjectType_CRL = 1, + pkiObjectType_PrivateKey = 2, + pkiObjectType_PublicKey = 3 +} pkiObjectType; + +/* Each object is defined by a set of items that uniquely identify it. + * Here are the uid sets: + * + * NSSCertificate ==> { issuer, serial } + * NSSPrivateKey + * (RSA) ==> { modulus, public exponent } + * + */ +#define MAX_ITEMS_FOR_UID 2 + +/* pkiObjectCollectionNode + * + * A node in the collection is the set of unique identifiers for a single + * object, along with either the actual object or a proto-object. + */ +typedef struct +{ + PRCList link; + PRBool haveObject; + nssPKIObject *object; + NSSItem uid[MAX_ITEMS_FOR_UID]; +} +pkiObjectCollectionNode; + +/* nssPKIObjectCollection + * + * The collection is the set of all objects, plus the interfaces needed + * to manage the objects. + * + */ +struct nssPKIObjectCollectionStr +{ + NSSArena *arena; + NSSTrustDomain *td; + NSSCryptoContext *cc; + PRCList head; /* list of pkiObjectCollectionNode's */ + PRUint32 size; + pkiObjectType objectType; + void (* destroyObject)(nssPKIObject *o); + PRStatus (* getUIDFromObject)(nssPKIObject *o, NSSItem *uid); + PRStatus (* getUIDFromInstance)(nssCryptokiObject *co, NSSItem *uid, + NSSArena *arena); + nssPKIObject * (* createObject)(nssPKIObject *o); + nssPKILockType lockType; /* type of lock to use for new proto-objects */ +}; + +static nssPKIObjectCollection * +nssPKIObjectCollection_Create ( + NSSTrustDomain *td, + NSSCryptoContext *ccOpt, + nssPKILockType lockType +) +{ + NSSArena *arena; + nssPKIObjectCollection *rvCollection = NULL; + arena = nssArena_Create(); + if (!arena) { + return (nssPKIObjectCollection *)NULL; + } + rvCollection = nss_ZNEW(arena, nssPKIObjectCollection); + if (!rvCollection) { + goto loser; + } + PR_INIT_CLIST(&rvCollection->head); + rvCollection->arena = arena; + rvCollection->td = td; /* XXX */ + rvCollection->cc = ccOpt; + rvCollection->lockType = lockType; + return rvCollection; +loser: + nssArena_Destroy(arena); + return (nssPKIObjectCollection *)NULL; +} + +NSS_IMPLEMENT void +nssPKIObjectCollection_Destroy ( + nssPKIObjectCollection *collection +) +{ + if (collection) { + PRCList *link; + pkiObjectCollectionNode *node; + /* first destroy any objects in the collection */ + link = PR_NEXT_LINK(&collection->head); + while (link != &collection->head) { + node = (pkiObjectCollectionNode *)link; + if (node->haveObject) { + (*collection->destroyObject)(node->object); + } else { + nssPKIObject_Destroy(node->object); + } + link = PR_NEXT_LINK(link); + } + /* then destroy it */ + nssArena_Destroy(collection->arena); + } +} + +NSS_IMPLEMENT PRUint32 +nssPKIObjectCollection_Count ( + nssPKIObjectCollection *collection +) +{ + return collection->size; +} + +NSS_IMPLEMENT PRStatus +nssPKIObjectCollection_AddObject ( + nssPKIObjectCollection *collection, + nssPKIObject *object +) +{ + pkiObjectCollectionNode *node; + node = nss_ZNEW(collection->arena, pkiObjectCollectionNode); + if (!node) { + return PR_FAILURE; + } + node->haveObject = PR_TRUE; + node->object = nssPKIObject_AddRef(object); + (*collection->getUIDFromObject)(object, node->uid); + PR_INIT_CLIST(&node->link); + PR_INSERT_BEFORE(&node->link, &collection->head); + collection->size++; + return PR_SUCCESS; +} + +static pkiObjectCollectionNode * +find_instance_in_collection ( + nssPKIObjectCollection *collection, + nssCryptokiObject *instance +) +{ + PRCList *link; + pkiObjectCollectionNode *node; + link = PR_NEXT_LINK(&collection->head); + while (link != &collection->head) { + node = (pkiObjectCollectionNode *)link; + if (nssPKIObject_HasInstance(node->object, instance)) { + return node; + } + link = PR_NEXT_LINK(link); + } + return (pkiObjectCollectionNode *)NULL; +} + +static pkiObjectCollectionNode * +find_object_in_collection ( + nssPKIObjectCollection *collection, + NSSItem *uid +) +{ + PRUint32 i; + PRStatus status; + PRCList *link; + pkiObjectCollectionNode *node; + link = PR_NEXT_LINK(&collection->head); + while (link != &collection->head) { + node = (pkiObjectCollectionNode *)link; + for (i=0; i<MAX_ITEMS_FOR_UID; i++) { + if (!nssItem_Equal(&node->uid[i], &uid[i], &status)) { + break; + } + } + if (i == MAX_ITEMS_FOR_UID) { + return node; + } + link = PR_NEXT_LINK(link); + } + return (pkiObjectCollectionNode *)NULL; +} + +static pkiObjectCollectionNode * +add_object_instance ( + nssPKIObjectCollection *collection, + nssCryptokiObject *instance, + PRBool *foundIt +) +{ + PRUint32 i; + PRStatus status; + pkiObjectCollectionNode *node; + nssArenaMark *mark = NULL; + NSSItem uid[MAX_ITEMS_FOR_UID]; + nsslibc_memset(uid, 0, sizeof uid); + /* The list is traversed twice, first (here) looking to match the + * { token, handle } tuple, and if that is not found, below a search + * for unique identifier is done. Here, a match means this exact object + * instance is already in the collection, and we have nothing to do. + */ + *foundIt = PR_FALSE; + node = find_instance_in_collection(collection, instance); + if (node) { + /* The collection is assumed to take over the instance. Since we + * are not using it, it must be destroyed. + */ + nssCryptokiObject_Destroy(instance); + *foundIt = PR_TRUE; + return node; + } + mark = nssArena_Mark(collection->arena); + if (!mark) { + goto loser; + } + status = (*collection->getUIDFromInstance)(instance, uid, + collection->arena); + if (status != PR_SUCCESS) { + goto loser; + } + /* Search for unique identifier. A match here means the object exists + * in the collection, but does not have this instance, so the instance + * needs to be added. + */ + node = find_object_in_collection(collection, uid); + if (node) { + /* This is an object with multiple instances */ + status = nssPKIObject_AddInstance(node->object, instance); + } else { + /* This is a completely new object. Create a node for it. */ + node = nss_ZNEW(collection->arena, pkiObjectCollectionNode); + if (!node) { + goto loser; + } + node->object = nssPKIObject_Create(NULL, instance, + collection->td, collection->cc, + collection->lockType); + if (!node->object) { + goto loser; + } + for (i=0; i<MAX_ITEMS_FOR_UID; i++) { + node->uid[i] = uid[i]; + } + node->haveObject = PR_FALSE; + PR_INIT_CLIST(&node->link); + PR_INSERT_BEFORE(&node->link, &collection->head); + collection->size++; + status = PR_SUCCESS; + } + nssArena_Unmark(collection->arena, mark); + return node; +loser: + if (mark) { + nssArena_Release(collection->arena, mark); + } + nssCryptokiObject_Destroy(instance); + return (pkiObjectCollectionNode *)NULL; +} + +NSS_IMPLEMENT PRStatus +nssPKIObjectCollection_AddInstances ( + nssPKIObjectCollection *collection, + nssCryptokiObject **instances, + PRUint32 numInstances +) +{ + PRStatus status = PR_SUCCESS; + PRUint32 i = 0; + PRBool foundIt; + pkiObjectCollectionNode *node; + if (instances) { + while ((!numInstances || i < numInstances) && *instances) { + if (status == PR_SUCCESS) { + node = add_object_instance(collection, *instances, &foundIt); + if (node == NULL) { + /* add_object_instance freed the current instance */ + /* free the remaining instances */ + status = PR_FAILURE; + } + } else { + nssCryptokiObject_Destroy(*instances); + } + instances++; + i++; + } + } + return status; +} + +static void +nssPKIObjectCollection_RemoveNode ( + nssPKIObjectCollection *collection, + pkiObjectCollectionNode *node +) +{ + PR_REMOVE_LINK(&node->link); + collection->size--; +} + +static PRStatus +nssPKIObjectCollection_GetObjects ( + nssPKIObjectCollection *collection, + nssPKIObject **rvObjects, + PRUint32 rvSize +) +{ + PRUint32 i = 0; + PRCList *link = PR_NEXT_LINK(&collection->head); + pkiObjectCollectionNode *node; + int error=0; + while ((i < rvSize) && (link != &collection->head)) { + node = (pkiObjectCollectionNode *)link; + if (!node->haveObject) { + /* Convert the proto-object to an object */ + node->object = (*collection->createObject)(node->object); + if (!node->object) { + link = PR_NEXT_LINK(link); + /*remove bogus object from list*/ + nssPKIObjectCollection_RemoveNode(collection,node); + error++; + continue; + } + node->haveObject = PR_TRUE; + } + rvObjects[i++] = nssPKIObject_AddRef(node->object); + link = PR_NEXT_LINK(link); + } + if (!error && *rvObjects == NULL) { + nss_SetError(NSS_ERROR_NOT_FOUND); + } + return PR_SUCCESS; +} + +NSS_IMPLEMENT PRStatus +nssPKIObjectCollection_Traverse ( + nssPKIObjectCollection *collection, + nssPKIObjectCallback *callback +) +{ + PRStatus status; + PRCList *link = PR_NEXT_LINK(&collection->head); + pkiObjectCollectionNode *node; + while (link != &collection->head) { + node = (pkiObjectCollectionNode *)link; + if (!node->haveObject) { + node->object = (*collection->createObject)(node->object); + if (!node->object) { + link = PR_NEXT_LINK(link); + /*remove bogus object from list*/ + nssPKIObjectCollection_RemoveNode(collection,node); + continue; + } + node->haveObject = PR_TRUE; + } + switch (collection->objectType) { + case pkiObjectType_Certificate: + status = (*callback->func.cert)((NSSCertificate *)node->object, + callback->arg); + break; + case pkiObjectType_CRL: + status = (*callback->func.crl)((NSSCRL *)node->object, + callback->arg); + break; + case pkiObjectType_PrivateKey: + status = (*callback->func.pvkey)((NSSPrivateKey *)node->object, + callback->arg); + break; + case pkiObjectType_PublicKey: + status = (*callback->func.pbkey)((NSSPublicKey *)node->object, + callback->arg); + break; + } + link = PR_NEXT_LINK(link); + } + return PR_SUCCESS; +} + +NSS_IMPLEMENT PRStatus +nssPKIObjectCollection_AddInstanceAsObject ( + nssPKIObjectCollection *collection, + nssCryptokiObject *instance +) +{ + pkiObjectCollectionNode *node; + PRBool foundIt; + node = add_object_instance(collection, instance, &foundIt); + if (node == NULL) { + return PR_FAILURE; + } + if (!node->haveObject) { + node->object = (*collection->createObject)(node->object); + if (!node->object) { + /*remove bogus object from list*/ + nssPKIObjectCollection_RemoveNode(collection,node); + return PR_FAILURE; + } + node->haveObject = PR_TRUE; + } else if (!foundIt) { + /* The instance was added to a pre-existing node. This + * function is *only* being used for certificates, and having + * multiple instances of certs in 3.X requires updating the + * CERTCertificate. + * But only do it if it was a new instance!!! If the same instance + * is encountered, we set *foundIt to true. Detect that here and + * ignore it. + */ + STAN_ForceCERTCertificateUpdate((NSSCertificate *)node->object); + } + return PR_SUCCESS; +} + +/* + * Certificate collections + */ + +static void +cert_destroyObject(nssPKIObject *o) +{ + NSSCertificate *c = (NSSCertificate *)o; + if (c->decoding) { + CERTCertificate *cc = STAN_GetCERTCertificate(c); + if (cc) { + CERT_DestroyCertificate(cc); + return; + } /* else destroy it as NSSCertificate below */ + } + nssCertificate_Destroy(c); +} + +static PRStatus +cert_getUIDFromObject(nssPKIObject *o, NSSItem *uid) +{ + NSSCertificate *c = (NSSCertificate *)o; + /* The builtins are still returning decoded serial numbers. Until + * this compatibility issue is resolved, use the full DER of the + * cert to uniquely identify it. + */ + NSSDER *derCert; + derCert = nssCertificate_GetEncoding(c); + uid[0].data = NULL; uid[0].size = 0; + uid[1].data = NULL; uid[1].size = 0; + if (derCert != NULL) { + uid[0] = *derCert; + } + return PR_SUCCESS; +} + +static PRStatus +cert_getUIDFromInstance(nssCryptokiObject *instance, NSSItem *uid, + NSSArena *arena) +{ + /* The builtins are still returning decoded serial numbers. Until + * this compatibility issue is resolved, use the full DER of the + * cert to uniquely identify it. + */ + uid[1].data = NULL; uid[1].size = 0; + return nssCryptokiCertificate_GetAttributes(instance, + NULL, /* XXX sessionOpt */ + arena, /* arena */ + NULL, /* type */ + NULL, /* id */ + &uid[0], /* encoding */ + NULL, /* issuer */ + NULL, /* serial */ + NULL); /* subject */ +} + +static nssPKIObject * +cert_createObject(nssPKIObject *o) +{ + NSSCertificate *cert; + cert = nssCertificate_Create(o); +/* if (STAN_GetCERTCertificate(cert) == NULL) { + nssCertificate_Destroy(cert); + return (nssPKIObject *)NULL; + } */ + /* In 3.4, have to maintain uniqueness of cert pointers by caching all + * certs. Cache the cert here, before returning. If it is already + * cached, take the cached entry. + */ + { + NSSTrustDomain *td = o->trustDomain; + nssTrustDomain_AddCertsToCache(td, &cert, 1); + } + return (nssPKIObject *)cert; +} + +NSS_IMPLEMENT nssPKIObjectCollection * +nssCertificateCollection_Create ( + NSSTrustDomain *td, + NSSCertificate **certsOpt +) +{ + PRStatus status; + nssPKIObjectCollection *collection; + collection = nssPKIObjectCollection_Create(td, NULL, nssPKIMonitor); + collection->objectType = pkiObjectType_Certificate; + collection->destroyObject = cert_destroyObject; + collection->getUIDFromObject = cert_getUIDFromObject; + collection->getUIDFromInstance = cert_getUIDFromInstance; + collection->createObject = cert_createObject; + if (certsOpt) { + for (; *certsOpt; certsOpt++) { + nssPKIObject *object = (nssPKIObject *)(*certsOpt); + status = nssPKIObjectCollection_AddObject(collection, object); + } + } + return collection; +} + +NSS_IMPLEMENT NSSCertificate ** +nssPKIObjectCollection_GetCertificates ( + nssPKIObjectCollection *collection, + NSSCertificate **rvOpt, + PRUint32 maximumOpt, + NSSArena *arenaOpt +) +{ + PRStatus status; + PRUint32 rvSize; + PRBool allocated = PR_FALSE; + if (collection->size == 0) { + return (NSSCertificate **)NULL; + } + if (maximumOpt == 0) { + rvSize = collection->size; + } else { + rvSize = PR_MIN(collection->size, maximumOpt); + } + if (!rvOpt) { + rvOpt = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, rvSize + 1); + if (!rvOpt) { + return (NSSCertificate **)NULL; + } + allocated = PR_TRUE; + } + status = nssPKIObjectCollection_GetObjects(collection, + (nssPKIObject **)rvOpt, + rvSize); + if (status != PR_SUCCESS) { + if (allocated) { + nss_ZFreeIf(rvOpt); + } + return (NSSCertificate **)NULL; + } + return rvOpt; +} + +/* + * CRL/KRL collections + */ + +static void +crl_destroyObject(nssPKIObject *o) +{ + NSSCRL *crl = (NSSCRL *)o; + nssCRL_Destroy(crl); +} + +static PRStatus +crl_getUIDFromObject(nssPKIObject *o, NSSItem *uid) +{ + NSSCRL *crl = (NSSCRL *)o; + NSSDER *encoding; + encoding = nssCRL_GetEncoding(crl); + if (!encoding) { + nss_SetError(NSS_ERROR_INVALID_ARGUMENT); + return PR_FALSE; + } + uid[0] = *encoding; + uid[1].data = NULL; uid[1].size = 0; + return PR_SUCCESS; +} + +static PRStatus +crl_getUIDFromInstance(nssCryptokiObject *instance, NSSItem *uid, + NSSArena *arena) +{ + return nssCryptokiCRL_GetAttributes(instance, + NULL, /* XXX sessionOpt */ + arena, /* arena */ + &uid[0], /* encoding */ + NULL, /* subject */ + NULL, /* class */ + NULL, /* url */ + NULL); /* isKRL */ +} + +static nssPKIObject * +crl_createObject(nssPKIObject *o) +{ + return (nssPKIObject *)nssCRL_Create(o); +} + +NSS_IMPLEMENT nssPKIObjectCollection * +nssCRLCollection_Create ( + NSSTrustDomain *td, + NSSCRL **crlsOpt +) +{ + PRStatus status; + nssPKIObjectCollection *collection; + collection = nssPKIObjectCollection_Create(td, NULL, nssPKILock); + collection->objectType = pkiObjectType_CRL; + collection->destroyObject = crl_destroyObject; + collection->getUIDFromObject = crl_getUIDFromObject; + collection->getUIDFromInstance = crl_getUIDFromInstance; + collection->createObject = crl_createObject; + if (crlsOpt) { + for (; *crlsOpt; crlsOpt++) { + nssPKIObject *object = (nssPKIObject *)(*crlsOpt); + status = nssPKIObjectCollection_AddObject(collection, object); + } + } + return collection; +} + +NSS_IMPLEMENT NSSCRL ** +nssPKIObjectCollection_GetCRLs ( + nssPKIObjectCollection *collection, + NSSCRL **rvOpt, + PRUint32 maximumOpt, + NSSArena *arenaOpt +) +{ + PRStatus status; + PRUint32 rvSize; + PRBool allocated = PR_FALSE; + if (collection->size == 0) { + return (NSSCRL **)NULL; + } + if (maximumOpt == 0) { + rvSize = collection->size; + } else { + rvSize = PR_MIN(collection->size, maximumOpt); + } + if (!rvOpt) { + rvOpt = nss_ZNEWARRAY(arenaOpt, NSSCRL *, rvSize + 1); + if (!rvOpt) { + return (NSSCRL **)NULL; + } + allocated = PR_TRUE; + } + status = nssPKIObjectCollection_GetObjects(collection, + (nssPKIObject **)rvOpt, + rvSize); + if (status != PR_SUCCESS) { + if (allocated) { + nss_ZFreeIf(rvOpt); + } + return (NSSCRL **)NULL; + } + return rvOpt; +} + +/* how bad would it be to have a static now sitting around, updated whenever + * this was called? would avoid repeated allocs... + */ +NSS_IMPLEMENT NSSTime * +NSSTime_Now ( + NSSTime *timeOpt +) +{ + return NSSTime_SetPRTime(timeOpt, PR_Now()); +} + +NSS_IMPLEMENT NSSTime * +NSSTime_SetPRTime ( + NSSTime *timeOpt, + PRTime prTime +) +{ + NSSTime *rvTime; + rvTime = (timeOpt) ? timeOpt : nss_ZNEW(NULL, NSSTime); + if (rvTime) { + rvTime->prTime = prTime; + } + return rvTime; +} + +NSS_IMPLEMENT PRTime +NSSTime_GetPRTime ( + NSSTime *time +) +{ + return time->prTime; +} + diff --git a/mozilla/security/nss/lib/pki/pkim.h b/mozilla/security/nss/lib/pki/pkim.h new file mode 100644 index 0000000..419d36a --- /dev/null +++ b/mozilla/security/nss/lib/pki/pkim.h @@ -0,0 +1,731 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef PKIM_H +#define PKIM_H + +#ifdef DEBUG +static const char PKIM_CVS_ID[] = "@(#) $RCSfile: pkim.h,v $ $Revision: 1.30 $ $Date: 2007/11/16 05:29:27 $"; +#endif /* DEBUG */ + +#ifndef BASE_H +#include "base.h" +#endif /* BASE_H */ + +#ifndef PKI_H +#include "pki.h" +#endif /* PKI_H */ + +#ifndef PKITM_H +#include "pkitm.h" +#endif /* PKITM_H */ + +PR_BEGIN_EXTERN_C + +/* nssPKIObject + * + * This is the base object class, common to all PKI objects defined in + * in this module. Each object can be safely 'casted' to an nssPKIObject, + * then passed to these methods. + * + * nssPKIObject_Create + * nssPKIObject_Destroy + * nssPKIObject_AddRef + * nssPKIObject_AddInstance + * nssPKIObject_HasInstance + * nssPKIObject_GetTokens + * nssPKIObject_GetNicknameForToken + * nssPKIObject_RemoveInstanceForToken + * nssPKIObject_DeleteStoredObject + */ + +NSS_EXTERN void nssPKIObject_Lock (nssPKIObject * object); +NSS_EXTERN void nssPKIObject_Unlock (nssPKIObject * object); +NSS_EXTERN PRStatus nssPKIObject_NewLock (nssPKIObject * object, + nssPKILockType lockType); +NSS_EXTERN void nssPKIObject_DestroyLock(nssPKIObject * object); + +/* nssPKIObject_Create + * + * A generic PKI object. It must live in a trust domain. It may be + * initialized with a token instance, or alternatively in a crypto context. + */ +NSS_EXTERN nssPKIObject * +nssPKIObject_Create +( + NSSArena *arenaOpt, + nssCryptokiObject *instanceOpt, + NSSTrustDomain *td, + NSSCryptoContext *ccOpt, + nssPKILockType lockType +); + +/* nssPKIObject_AddRef + */ +NSS_EXTERN nssPKIObject * +nssPKIObject_AddRef +( + nssPKIObject *object +); + +/* nssPKIObject_Destroy + * + * Returns true if object was destroyed. This notifies the subclass that + * all references are gone and it should delete any members it owns. + */ +NSS_EXTERN PRBool +nssPKIObject_Destroy +( + nssPKIObject *object +); + +/* nssPKIObject_AddInstance + * + * Add a token instance to the object, if it does not have it already. + */ +NSS_EXTERN PRStatus +nssPKIObject_AddInstance +( + nssPKIObject *object, + nssCryptokiObject *instance +); + +/* nssPKIObject_HasInstance + * + * Query the object for a token instance. + */ +NSS_EXTERN PRBool +nssPKIObject_HasInstance +( + nssPKIObject *object, + nssCryptokiObject *instance +); + +/* nssPKIObject_GetTokens + * + * Get all tokens which have an instance of the object. + */ +NSS_EXTERN NSSToken ** +nssPKIObject_GetTokens +( + nssPKIObject *object, + PRStatus *statusOpt +); + +/* nssPKIObject_GetNicknameForToken + * + * tokenOpt == NULL means take the first available, otherwise return the + * nickname for the specified token. + */ +NSS_EXTERN NSSUTF8 * +nssPKIObject_GetNicknameForToken +( + nssPKIObject *object, + NSSToken *tokenOpt +); + +/* nssPKIObject_RemoveInstanceForToken + * + * Remove the instance of the object on the specified token. + */ +NSS_EXTERN PRStatus +nssPKIObject_RemoveInstanceForToken +( + nssPKIObject *object, + NSSToken *token +); + +/* nssPKIObject_DeleteStoredObject + * + * Delete all token instances of the object, as well as any crypto context + * instances (TODO). If any of the instances are read-only, or if the + * removal fails, the object will keep those instances. 'isFriendly' refers + * to the object -- can this object be removed from a friendly token without + * login? For example, certificates are friendly, private keys are not. + * Note that if the token is not friendly, authentication will be required + * regardless of the value of 'isFriendly'. + */ +NSS_EXTERN PRStatus +nssPKIObject_DeleteStoredObject +( + nssPKIObject *object, + NSSCallback *uhh, + PRBool isFriendly +); + +NSS_EXTERN nssCryptokiObject ** +nssPKIObject_GetInstances +( + nssPKIObject *object +); + +NSS_EXTERN NSSCertificate ** +nssTrustDomain_FindCertificatesByID +( + NSSTrustDomain *td, + NSSItem *id, + NSSCertificate **rvOpt, + PRUint32 maximumOpt, + NSSArena *arenaOpt +); + +NSS_EXTERN NSSCRL ** +nssTrustDomain_FindCRLsBySubject +( + NSSTrustDomain *td, + NSSDER *subject +); + +/* module-private nsspki methods */ + +NSS_EXTERN NSSCryptoContext * +nssCryptoContext_Create +( + NSSTrustDomain *td, + NSSCallback *uhhOpt +); + +/* XXX for the collection */ +NSS_EXTERN NSSCertificate * +nssCertificate_Create +( + nssPKIObject *object +); + +NSS_EXTERN PRStatus +nssCertificate_SetCertTrust +( + NSSCertificate *c, + NSSTrust *trust +); + +NSS_EXTERN nssDecodedCert * +nssCertificate_GetDecoding +( + NSSCertificate *c +); + +extern PRIntn +nssCertificate_SubjectListSort +( + void *v1, + void *v2 +); + +NSS_EXTERN nssDecodedCert * +nssDecodedCert_Create +( + NSSArena *arenaOpt, + NSSDER *encoding, + NSSCertificateType type +); + +NSS_EXTERN PRStatus +nssDecodedCert_Destroy +( + nssDecodedCert *dc +); + +NSS_EXTERN NSSTrust * +nssTrust_Create +( + nssPKIObject *object, + NSSItem *certData +); + +NSS_EXTERN NSSCRL * +nssCRL_Create +( + nssPKIObject *object +); + +NSS_EXTERN NSSCRL * +nssCRL_AddRef +( + NSSCRL *crl +); + +NSS_EXTERN PRStatus +nssCRL_Destroy +( + NSSCRL *crl +); + +NSS_EXTERN PRStatus +nssCRL_DeleteStoredObject +( + NSSCRL *crl, + NSSCallback *uhh +); + +NSS_EXTERN NSSPrivateKey * +nssPrivateKey_Create +( + nssPKIObject *o +); + +NSS_EXTERN NSSDER * +nssCRL_GetEncoding +( + NSSCRL *crl +); + +NSS_EXTERN NSSPublicKey * +nssPublicKey_Create +( + nssPKIObject *object +); + +/* nssCertificateArray + * + * These are being thrown around a lot, might as well group together some + * functionality. + * + * nssCertificateArray_Destroy + * nssCertificateArray_Join + * nssCertificateArray_FindBestCertificate + * nssCertificateArray_Traverse + */ + +/* nssCertificateArray_Destroy + * + * Will destroy the array and the certs within it. If the array was created + * in an arena, will *not* (of course) destroy the arena. However, is safe + * to call this method on an arena-allocated array. + */ +NSS_EXTERN void +nssCertificateArray_Destroy +( + NSSCertificate **certs +); + +/* nssCertificateArray_Join + * + * Join two arrays into one. The two arrays, certs1 and certs2, should + * be considered invalid after a call to this function (they may be destroyed + * as part of the join). certs1 and/or certs2 may be NULL. Safe to + * call with arrays allocated in an arena, the result will also be in the + * arena. + */ +NSS_EXTERN NSSCertificate ** +nssCertificateArray_Join +( + NSSCertificate **certs1, + NSSCertificate **certs2 +); + +/* nssCertificateArray_FindBestCertificate + * + * Use the usual { time, usage, policies } to find the best cert in the + * array. + */ +NSS_EXTERN NSSCertificate * +nssCertificateArray_FindBestCertificate +( + NSSCertificate **certs, + NSSTime *timeOpt, + const NSSUsage *usage, + NSSPolicies *policiesOpt +); + +/* nssCertificateArray_Traverse + * + * Do the callback for each cert, terminate the traversal if the callback + * fails. + */ +NSS_EXTERN PRStatus +nssCertificateArray_Traverse +( + NSSCertificate **certs, + PRStatus (* callback)(NSSCertificate *c, void *arg), + void *arg +); + +NSS_EXTERN void +nssCRLArray_Destroy +( + NSSCRL **crls +); + +/* nssPKIObjectCollection + * + * This is a handy way to group objects together and perform operations + * on them. It can also handle "proto-objects"-- references to + * objects instances on tokens, where the actual object hasn't + * been formed yet. + * + * nssCertificateCollection_Create + * nssPrivateKeyCollection_Create + * nssPublicKeyCollection_Create + * + * If this was a language that provided for inheritance, each type would + * inherit all of the following methods. Instead, there is only one + * type (nssPKIObjectCollection), shared among all. This may cause + * confusion; an alternative would be to define all of the methods + * for each subtype (nssCertificateCollection_Destroy, ...), but that doesn't + * seem worth the code bloat.. It is left up to the caller to remember + * what type of collection he/she is dealing with. + * + * nssPKIObjectCollection_Destroy + * nssPKIObjectCollection_Count + * nssPKIObjectCollection_AddObject + * nssPKIObjectCollection_AddInstances + * nssPKIObjectCollection_Traverse + * + * Back to type-specific methods. + * + * nssPKIObjectCollection_GetCertificates + * nssPKIObjectCollection_GetCRLs + * nssPKIObjectCollection_GetPrivateKeys + * nssPKIObjectCollection_GetPublicKeys + */ + +/* nssCertificateCollection_Create + * + * Create a collection of certificates in the specified trust domain. + * Optionally provide a starting set of certs. + */ +NSS_EXTERN nssPKIObjectCollection * +nssCertificateCollection_Create +( + NSSTrustDomain *td, + NSSCertificate **certsOpt +); + +/* nssCRLCollection_Create + * + * Create a collection of CRLs/KRLs in the specified trust domain. + * Optionally provide a starting set of CRLs. + */ +NSS_EXTERN nssPKIObjectCollection * +nssCRLCollection_Create +( + NSSTrustDomain *td, + NSSCRL **crlsOpt +); + +/* nssPrivateKeyCollection_Create + * + * Create a collection of private keys in the specified trust domain. + * Optionally provide a starting set of keys. + */ +NSS_EXTERN nssPKIObjectCollection * +nssPrivateKeyCollection_Create +( + NSSTrustDomain *td, + NSSPrivateKey **pvkOpt +); + +/* nssPublicKeyCollection_Create + * + * Create a collection of public keys in the specified trust domain. + * Optionally provide a starting set of keys. + */ +NSS_EXTERN nssPKIObjectCollection * +nssPublicKeyCollection_Create +( + NSSTrustDomain *td, + NSSPublicKey **pvkOpt +); + +/* nssPKIObjectCollection_Destroy + */ +NSS_EXTERN void +nssPKIObjectCollection_Destroy +( + nssPKIObjectCollection *collection +); + +/* nssPKIObjectCollection_Count + */ +NSS_EXTERN PRUint32 +nssPKIObjectCollection_Count +( + nssPKIObjectCollection *collection +); + +NSS_EXTERN PRStatus +nssPKIObjectCollection_AddObject +( + nssPKIObjectCollection *collection, + nssPKIObject *object +); + +/* nssPKIObjectCollection_AddInstances + * + * Add a set of object instances to the collection. The instances + * will be sorted into any existing certs/proto-certs that may be in + * the collection. The instances will be absorbed by the collection, + * the array should not be used after this call (except to free it). + * + * Failure means the collection is in an invalid state. + * + * numInstances = 0 means the array is NULL-terminated + */ +NSS_EXTERN PRStatus +nssPKIObjectCollection_AddInstances +( + nssPKIObjectCollection *collection, + nssCryptokiObject **instances, + PRUint32 numInstances +); + +/* nssPKIObjectCollection_Traverse + */ +NSS_EXTERN PRStatus +nssPKIObjectCollection_Traverse +( + nssPKIObjectCollection *collection, + nssPKIObjectCallback *callback +); + +/* This function is being added for NSS 3.5. It corresponds to the function + * nssToken_TraverseCertificates. The idea is to use the collection during + * a traversal, creating certs each time a new instance is added for which + * a cert does not already exist. + */ +NSS_EXTERN PRStatus +nssPKIObjectCollection_AddInstanceAsObject +( + nssPKIObjectCollection *collection, + nssCryptokiObject *instance +); + +/* nssPKIObjectCollection_GetCertificates + * + * Get all of the certificates in the collection. + */ +NSS_EXTERN NSSCertificate ** +nssPKIObjectCollection_GetCertificates +( + nssPKIObjectCollection *collection, + NSSCertificate **rvOpt, + PRUint32 maximumOpt, + NSSArena *arenaOpt +); + +NSS_EXTERN NSSCRL ** +nssPKIObjectCollection_GetCRLs +( + nssPKIObjectCollection *collection, + NSSCRL **rvOpt, + PRUint32 maximumOpt, + NSSArena *arenaOpt +); + +NSS_EXTERN NSSPrivateKey ** +nssPKIObjectCollection_GetPrivateKeys +( + nssPKIObjectCollection *collection, + NSSPrivateKey **rvOpt, + PRUint32 maximumOpt, + NSSArena *arenaOpt +); + +NSS_EXTERN NSSPublicKey ** +nssPKIObjectCollection_GetPublicKeys +( + nssPKIObjectCollection *collection, + NSSPublicKey **rvOpt, + PRUint32 maximumOpt, + NSSArena *arenaOpt +); + +NSS_EXTERN NSSTime * +NSSTime_Now +( + NSSTime *timeOpt +); + +NSS_EXTERN NSSTime * +NSSTime_SetPRTime +( + NSSTime *timeOpt, + PRTime prTime +); + +NSS_EXTERN PRTime +NSSTime_GetPRTime +( + NSSTime *time +); + +NSS_EXTERN nssHash * +nssHash_CreateCertificate +( + NSSArena *arenaOpt, + PRUint32 numBuckets +); + +/* 3.4 Certificate cache routines */ + +NSS_EXTERN PRStatus +nssTrustDomain_InitializeCache +( + NSSTrustDomain *td, + PRUint32 cacheSize +); + +NSS_EXTERN PRStatus +nssTrustDomain_AddCertsToCache +( + NSSTrustDomain *td, + NSSCertificate **certs, + PRUint32 numCerts +); + +NSS_EXTERN void +nssTrustDomain_RemoveCertFromCacheLOCKED ( + NSSTrustDomain *td, + NSSCertificate *cert +); + +NSS_EXTERN void +nssTrustDomain_LockCertCache ( + NSSTrustDomain *td +); + +NSS_EXTERN void +nssTrustDomain_UnlockCertCache ( + NSSTrustDomain *td +); + +NSS_IMPLEMENT PRStatus +nssTrustDomain_DestroyCache +( + NSSTrustDomain *td +); + +/* + * Remove all certs for the given token from the cache. This is + * needed if the token is removed. + */ +NSS_EXTERN PRStatus +nssTrustDomain_RemoveTokenCertsFromCache +( + NSSTrustDomain *td, + NSSToken *token +); + +NSS_EXTERN PRStatus +nssTrustDomain_UpdateCachedTokenCerts +( + NSSTrustDomain *td, + NSSToken *token +); + +/* + * Find all cached certs with this nickname (label). + */ +NSS_EXTERN NSSCertificate ** +nssTrustDomain_GetCertsForNicknameFromCache +( + NSSTrustDomain *td, + const NSSUTF8 *nickname, + nssList *certListOpt +); + +/* + * Find all cached certs with this email address. + */ +NSS_EXTERN NSSCertificate ** +nssTrustDomain_GetCertsForEmailAddressFromCache +( + NSSTrustDomain *td, + NSSASCII7 *email, + nssList *certListOpt +); + +/* + * Find all cached certs with this subject. + */ +NSS_EXTERN NSSCertificate ** +nssTrustDomain_GetCertsForSubjectFromCache +( + NSSTrustDomain *td, + NSSDER *subject, + nssList *certListOpt +); + +/* + * Look for a specific cert in the cache. + */ +NSS_EXTERN NSSCertificate * +nssTrustDomain_GetCertForIssuerAndSNFromCache +( + NSSTrustDomain *td, + NSSDER *issuer, + NSSDER *serialNum +); + +/* + * Look for a specific cert in the cache. + */ +NSS_EXTERN NSSCertificate * +nssTrustDomain_GetCertByDERFromCache +( + NSSTrustDomain *td, + NSSDER *der +); + +/* Get all certs from the cache */ +/* XXX this is being included to make some old-style calls word, not to + * say we should keep it + */ +NSS_EXTERN NSSCertificate ** +nssTrustDomain_GetCertsFromCache +( + NSSTrustDomain *td, + nssList *certListOpt +); + +NSS_EXTERN void +nssTrustDomain_DumpCacheInfo +( + NSSTrustDomain *td, + void (* cert_dump_iter)(const void *, void *, void *), + void *arg +); + +NSS_EXTERN void +nssCertificateList_AddReferences +( + nssList *certList +); + +PR_END_EXTERN_C + +#endif /* PKIM_H */ diff --git a/mozilla/security/nss/lib/pki/pkistore.c b/mozilla/security/nss/lib/pki/pkistore.c new file mode 100644 index 0000000..3371fdd --- /dev/null +++ b/mozilla/security/nss/lib/pki/pkistore.c @@ -0,0 +1,774 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifdef DEBUG +static const char CVS_ID[] = "@(#) $RCSfile: pkistore.c,v $ $Revision: 1.33.40.1 $ $Date: 2010/12/17 20:14:38 $"; +#endif /* DEBUG */ + +#ifndef PKIM_H +#include "pkim.h" +#endif /* PKIM_H */ + +#ifndef PKI_H +#include "pki.h" +#endif /* PKI_H */ + +#ifndef NSSPKI_H +#include "nsspki.h" +#endif /* NSSPKI_H */ + +#ifndef BASE_H +#include "base.h" +#endif /* BASE_H */ + +#ifndef PKISTORE_H +#include "pkistore.h" +#endif /* PKISTORE_H */ + +#include "cert.h" + +#include "prbit.h" + +/* + * Certificate Store + * + * This differs from the cache in that it is a true storage facility. Items + * stay in until they are explicitly removed. It is only used by crypto + * contexts at this time, but may be more generally useful... + * + */ + +struct nssCertificateStoreStr +{ + PRBool i_alloced_arena; + NSSArena *arena; + PZLock *lock; + nssHash *subject; + nssHash *issuer_and_serial; +}; + +typedef struct certificate_hash_entry_str certificate_hash_entry; + +struct certificate_hash_entry_str +{ + NSSCertificate *cert; + NSSTrust *trust; + nssSMIMEProfile *profile; +}; + +/* forward static declarations */ +static NSSCertificate * +nssCertStore_FindCertByIssuerAndSerialNumberLocked ( + nssCertificateStore *store, + NSSDER *issuer, + NSSDER *serial +); + +NSS_IMPLEMENT nssCertificateStore * +nssCertificateStore_Create ( + NSSArena *arenaOpt +) +{ + NSSArena *arena; + nssCertificateStore *store; + PRBool i_alloced_arena; + if (arenaOpt) { + arena = arenaOpt; + i_alloced_arena = PR_FALSE; + } else { + arena = nssArena_Create(); + if (!arena) { + return NULL; + } + i_alloced_arena = PR_TRUE; + } + store = nss_ZNEW(arena, nssCertificateStore); + if (!store) { + goto loser; + } + store->lock = PZ_NewLock(nssILockOther); + if (!store->lock) { + goto loser; + } + /* Create the issuer/serial --> {cert, trust, S/MIME profile } hash */ + store->issuer_and_serial = nssHash_CreateCertificate(arena, 0); + if (!store->issuer_and_serial) { + goto loser; + } + /* Create the subject DER --> subject list hash */ + store->subject = nssHash_CreateItem(arena, 0); + if (!store->subject) { + goto loser; + } + store->arena = arena; + store->i_alloced_arena = i_alloced_arena; + return store; +loser: + if (store) { + if (store->lock) { + PZ_DestroyLock(store->lock); + } + if (store->issuer_and_serial) { + nssHash_Destroy(store->issuer_and_serial); + } + if (store->subject) { + nssHash_Destroy(store->subject); + } + } + if (i_alloced_arena) { + nssArena_Destroy(arena); + } + return NULL; +} + +extern const NSSError NSS_ERROR_BUSY; + +NSS_IMPLEMENT PRStatus +nssCertificateStore_Destroy ( + nssCertificateStore *store +) +{ + if (nssHash_Count(store->issuer_and_serial) > 0) { + nss_SetError(NSS_ERROR_BUSY); + return PR_FAILURE; + } + PZ_DestroyLock(store->lock); + nssHash_Destroy(store->issuer_and_serial); + nssHash_Destroy(store->subject); + if (store->i_alloced_arena) { + nssArena_Destroy(store->arena); + } else { + nss_ZFreeIf(store); + } + return PR_SUCCESS; +} + +static PRStatus +add_certificate_entry ( + nssCertificateStore *store, + NSSCertificate *cert +) +{ + PRStatus nssrv; + certificate_hash_entry *entry; + entry = nss_ZNEW(cert->object.arena, certificate_hash_entry); + if (!entry) { + return PR_FAILURE; + } + entry->cert = cert; + nssrv = nssHash_Add(store->issuer_and_serial, cert, entry); + if (nssrv != PR_SUCCESS) { + nss_ZFreeIf(entry); + } + return nssrv; +} + +static PRStatus +add_subject_entry ( + nssCertificateStore *store, + NSSCertificate *cert +) +{ + PRStatus nssrv; + nssList *subjectList; + subjectList = (nssList *)nssHash_Lookup(store->subject, &cert->subject); + if (subjectList) { + /* The subject is already in, add this cert to the list */ + nssrv = nssList_AddUnique(subjectList, cert); + } else { + /* Create a new subject list for the subject */ + subjectList = nssList_Create(NULL, PR_FALSE); + if (!subjectList) { + return PR_FAILURE; + } + nssList_SetSortFunction(subjectList, nssCertificate_SubjectListSort); + /* Add the cert entry to this list of subjects */ + nssrv = nssList_Add(subjectList, cert); + if (nssrv != PR_SUCCESS) { + return nssrv; + } + /* Add the subject list to the cache */ + nssrv = nssHash_Add(store->subject, &cert->subject, subjectList); + } + return nssrv; +} + +/* declared below */ +static void +remove_certificate_entry ( + nssCertificateStore *store, + NSSCertificate *cert +); + +/* Caller must hold store->lock */ +static PRStatus +nssCertificateStore_AddLocked ( + nssCertificateStore *store, + NSSCertificate *cert +) +{ + PRStatus nssrv = add_certificate_entry(store, cert); + if (nssrv == PR_SUCCESS) { + nssrv = add_subject_entry(store, cert); + if (nssrv == PR_FAILURE) { + remove_certificate_entry(store, cert); + } + } + return nssrv; +} + + +NSS_IMPLEMENT NSSCertificate * +nssCertificateStore_FindOrAdd ( + nssCertificateStore *store, + NSSCertificate *c +) +{ + PRStatus nssrv; + NSSCertificate *rvCert = NULL; + + PZ_Lock(store->lock); + rvCert = nssCertStore_FindCertByIssuerAndSerialNumberLocked( + store, &c->issuer, &c->serial); + if (!rvCert) { + nssrv = nssCertificateStore_AddLocked(store, c); + if (PR_SUCCESS == nssrv) { + rvCert = nssCertificate_AddRef(c); + } + } + PZ_Unlock(store->lock); + return rvCert; +} + +static void +remove_certificate_entry ( + nssCertificateStore *store, + NSSCertificate *cert +) +{ + certificate_hash_entry *entry; + entry = (certificate_hash_entry *) + nssHash_Lookup(store->issuer_and_serial, cert); + if (entry) { + nssHash_Remove(store->issuer_and_serial, cert); + if (entry->trust) { + nssTrust_Destroy(entry->trust); + } + if (entry->profile) { + nssSMIMEProfile_Destroy(entry->profile); + } + nss_ZFreeIf(entry); + } +} + +static void +remove_subject_entry ( + nssCertificateStore *store, + NSSCertificate *cert +) +{ + nssList *subjectList; + /* Get the subject list for the cert's subject */ + subjectList = (nssList *)nssHash_Lookup(store->subject, &cert->subject); + if (subjectList) { + /* Remove the cert from the subject hash */ + nssList_Remove(subjectList, cert); + nssHash_Remove(store->subject, &cert->subject); + if (nssList_Count(subjectList) == 0) { + nssList_Destroy(subjectList); + } else { + /* The cert being released may have keyed the subject entry. + * Since there are still subject certs around, get another and + * rekey the entry just in case. + */ + NSSCertificate *subjectCert; + (void)nssList_GetArray(subjectList, (void **)&subjectCert, 1); + nssHash_Add(store->subject, &subjectCert->subject, subjectList); + } + } +} + +NSS_IMPLEMENT void +nssCertificateStore_RemoveCertLOCKED ( + nssCertificateStore *store, + NSSCertificate *cert +) +{ + certificate_hash_entry *entry; + entry = (certificate_hash_entry *) + nssHash_Lookup(store->issuer_and_serial, cert); + if (entry && entry->cert == cert) { + remove_certificate_entry(store, cert); + remove_subject_entry(store, cert); + } +} + +NSS_IMPLEMENT void +nssCertificateStore_Lock ( + nssCertificateStore *store, nssCertificateStoreTrace* out +) +{ +#ifdef DEBUG + PORT_Assert(out); + out->store = store; + out->lock = store->lock; + out->locked = PR_TRUE; + PZ_Lock(out->lock); +#else + PZ_Lock(store->lock); +#endif +} + +NSS_IMPLEMENT void +nssCertificateStore_Unlock ( + nssCertificateStore *store, const nssCertificateStoreTrace* in, + nssCertificateStoreTrace* out +) +{ +#ifdef DEBUG + PORT_Assert(in); + PORT_Assert(out); + out->store = store; + out->lock = store->lock; + PORT_Assert(!out->locked); + out->unlocked = PR_TRUE; + + PORT_Assert(in->store == out->store); + PORT_Assert(in->lock == out->lock); + PORT_Assert(in->locked); + PORT_Assert(!in->unlocked); + + PZ_Unlock(out->lock); +#else + PZ_Unlock(store->lock); +#endif +} + +static NSSCertificate ** +get_array_from_list ( + nssList *certList, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, + NSSArena *arenaOpt +) +{ + PRUint32 count; + NSSCertificate **rvArray = NULL; + count = nssList_Count(certList); + if (count == 0) { + return NULL; + } + if (maximumOpt > 0) { + count = PR_MIN(maximumOpt, count); + } + if (rvOpt) { + nssList_GetArray(certList, (void **)rvOpt, count); + } else { + rvArray = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, count + 1); + if (rvArray) { + nssList_GetArray(certList, (void **)rvArray, count); + } + } + return rvArray; +} + +NSS_IMPLEMENT NSSCertificate ** +nssCertificateStore_FindCertificatesBySubject ( + nssCertificateStore *store, + NSSDER *subject, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, + NSSArena *arenaOpt +) +{ + NSSCertificate **rvArray = NULL; + nssList *subjectList; + PZ_Lock(store->lock); + subjectList = (nssList *)nssHash_Lookup(store->subject, subject); + if (subjectList) { + nssCertificateList_AddReferences(subjectList); + rvArray = get_array_from_list(subjectList, + rvOpt, maximumOpt, arenaOpt); + } + PZ_Unlock(store->lock); + return rvArray; +} + +/* Because only subject indexing is implemented, all other lookups require + * full traversal (unfortunately, PLHashTable doesn't allow you to exit + * early from the enumeration). The assumptions are that 1) lookups by + * fields other than subject will be rare, and 2) the hash will not have + * a large number of entries. These assumptions will be tested. + * + * XXX + * For NSS 3.4, it is worth consideration to do all forms of indexing, + * because the only crypto context is global and persistent. + */ + +struct nickname_template_str +{ + NSSUTF8 *nickname; + nssList *subjectList; +}; + +static void match_nickname(const void *k, void *v, void *a) +{ + PRStatus nssrv; + NSSCertificate *c; + NSSUTF8 *nickname; + nssList *subjectList = (nssList *)v; + struct nickname_template_str *nt = (struct nickname_template_str *)a; + nssrv = nssList_GetArray(subjectList, (void **)&c, 1); + nickname = nssCertificate_GetNickname(c, NULL); + if (nssrv == PR_SUCCESS && nickname && + nssUTF8_Equal(nickname, nt->nickname, &nssrv)) + { + nt->subjectList = subjectList; + } +} + +/* + * Find all cached certs with this label. + */ +NSS_IMPLEMENT NSSCertificate ** +nssCertificateStore_FindCertificatesByNickname ( + nssCertificateStore *store, + const NSSUTF8 *nickname, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, + NSSArena *arenaOpt +) +{ + NSSCertificate **rvArray = NULL; + struct nickname_template_str nt; + nt.nickname = (char*) nickname; + nt.subjectList = NULL; + PZ_Lock(store->lock); + nssHash_Iterate(store->subject, match_nickname, &nt); + if (nt.subjectList) { + nssCertificateList_AddReferences(nt.subjectList); + rvArray = get_array_from_list(nt.subjectList, + rvOpt, maximumOpt, arenaOpt); + } + PZ_Unlock(store->lock); + return rvArray; +} + +struct email_template_str +{ + NSSASCII7 *email; + nssList *emailList; +}; + +static void match_email(const void *k, void *v, void *a) +{ + PRStatus nssrv; + NSSCertificate *c; + nssList *subjectList = (nssList *)v; + struct email_template_str *et = (struct email_template_str *)a; + nssrv = nssList_GetArray(subjectList, (void **)&c, 1); + if (nssrv == PR_SUCCESS && + nssUTF8_Equal(c->email, et->email, &nssrv)) + { + nssListIterator *iter = nssList_CreateIterator(subjectList); + if (iter) { + for (c = (NSSCertificate *)nssListIterator_Start(iter); + c != (NSSCertificate *)NULL; + c = (NSSCertificate *)nssListIterator_Next(iter)) + { + nssList_Add(et->emailList, c); + } + nssListIterator_Finish(iter); + nssListIterator_Destroy(iter); + } + } +} + +/* + * Find all cached certs with this email address. + */ +NSS_IMPLEMENT NSSCertificate ** +nssCertificateStore_FindCertificatesByEmail ( + nssCertificateStore *store, + NSSASCII7 *email, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, + NSSArena *arenaOpt +) +{ + NSSCertificate **rvArray = NULL; + struct email_template_str et; + et.email = email; + et.emailList = nssList_Create(NULL, PR_FALSE); + if (!et.emailList) { + return NULL; + } + PZ_Lock(store->lock); + nssHash_Iterate(store->subject, match_email, &et); + if (et.emailList) { + /* get references before leaving the store's lock protection */ + nssCertificateList_AddReferences(et.emailList); + } + PZ_Unlock(store->lock); + if (et.emailList) { + rvArray = get_array_from_list(et.emailList, + rvOpt, maximumOpt, arenaOpt); + nssList_Destroy(et.emailList); + } + return rvArray; +} + +/* Caller holds store->lock */ +static NSSCertificate * +nssCertStore_FindCertByIssuerAndSerialNumberLocked ( + nssCertificateStore *store, + NSSDER *issuer, + NSSDER *serial +) +{ + certificate_hash_entry *entry; + NSSCertificate *rvCert = NULL; + NSSCertificate index; + + index.issuer = *issuer; + index.serial = *serial; + entry = (certificate_hash_entry *) + nssHash_Lookup(store->issuer_and_serial, &index); + if (entry) { + rvCert = nssCertificate_AddRef(entry->cert); + } + return rvCert; +} + +NSS_IMPLEMENT NSSCertificate * +nssCertificateStore_FindCertificateByIssuerAndSerialNumber ( + nssCertificateStore *store, + NSSDER *issuer, + NSSDER *serial +) +{ + NSSCertificate *rvCert = NULL; + + PZ_Lock(store->lock); + rvCert = nssCertStore_FindCertByIssuerAndSerialNumberLocked ( + store, issuer, serial); + PZ_Unlock(store->lock); + return rvCert; +} + +static PRStatus +issuer_and_serial_from_encoding ( + NSSBER *encoding, + NSSDER *issuer, + NSSDER *serial +) +{ + SECItem derCert, derIssuer, derSerial; + SECStatus secrv; + derCert.data = (unsigned char *)encoding->data; + derCert.len = encoding->size; + secrv = CERT_IssuerNameFromDERCert(&derCert, &derIssuer); + if (secrv != SECSuccess) { + return PR_FAILURE; + } + secrv = CERT_SerialNumberFromDERCert(&derCert, &derSerial); + if (secrv != SECSuccess) { + PORT_Free(derIssuer.data); + return PR_FAILURE; + } + issuer->data = derIssuer.data; + issuer->size = derIssuer.len; + serial->data = derSerial.data; + serial->size = derSerial.len; + return PR_SUCCESS; +} + +NSS_IMPLEMENT NSSCertificate * +nssCertificateStore_FindCertificateByEncodedCertificate ( + nssCertificateStore *store, + NSSDER *encoding +) +{ + PRStatus nssrv = PR_FAILURE; + NSSDER issuer, serial; + NSSCertificate *rvCert = NULL; + nssrv = issuer_and_serial_from_encoding(encoding, &issuer, &serial); + if (nssrv != PR_SUCCESS) { + return NULL; + } + rvCert = nssCertificateStore_FindCertificateByIssuerAndSerialNumber(store, + &issuer, + &serial); + PORT_Free(issuer.data); + PORT_Free(serial.data); + return rvCert; +} + +NSS_EXTERN PRStatus +nssCertificateStore_AddTrust ( + nssCertificateStore *store, + NSSTrust *trust +) +{ + NSSCertificate *cert; + certificate_hash_entry *entry; + cert = trust->certificate; + PZ_Lock(store->lock); + entry = (certificate_hash_entry *) + nssHash_Lookup(store->issuer_and_serial, cert); + if (entry) { + NSSTrust* newTrust = nssTrust_AddRef(trust); + if (entry->trust) { + nssTrust_Destroy(entry->trust); + } + entry->trust = newTrust; + } + PZ_Unlock(store->lock); + return (entry) ? PR_SUCCESS : PR_FAILURE; +} + +NSS_IMPLEMENT NSSTrust * +nssCertificateStore_FindTrustForCertificate ( + nssCertificateStore *store, + NSSCertificate *cert +) +{ + certificate_hash_entry *entry; + NSSTrust *rvTrust = NULL; + PZ_Lock(store->lock); + entry = (certificate_hash_entry *) + nssHash_Lookup(store->issuer_and_serial, cert); + if (entry && entry->trust) { + rvTrust = nssTrust_AddRef(entry->trust); + } + PZ_Unlock(store->lock); + return rvTrust; +} + +NSS_EXTERN PRStatus +nssCertificateStore_AddSMIMEProfile ( + nssCertificateStore *store, + nssSMIMEProfile *profile +) +{ + NSSCertificate *cert; + certificate_hash_entry *entry; + cert = profile->certificate; + PZ_Lock(store->lock); + entry = (certificate_hash_entry *) + nssHash_Lookup(store->issuer_and_serial, cert); + if (entry) { + nssSMIMEProfile* newProfile = nssSMIMEProfile_AddRef(profile); + if (entry->profile) { + nssSMIMEProfile_Destroy(entry->profile); + } + entry->profile = newProfile; + } + PZ_Unlock(store->lock); + return (entry) ? PR_SUCCESS : PR_FAILURE; +} + +NSS_IMPLEMENT nssSMIMEProfile * +nssCertificateStore_FindSMIMEProfileForCertificate ( + nssCertificateStore *store, + NSSCertificate *cert +) +{ + certificate_hash_entry *entry; + nssSMIMEProfile *rvProfile = NULL; + PZ_Lock(store->lock); + entry = (certificate_hash_entry *) + nssHash_Lookup(store->issuer_and_serial, cert); + if (entry && entry->profile) { + rvProfile = nssSMIMEProfile_AddRef(entry->profile); + } + PZ_Unlock(store->lock); + return rvProfile; +} + +/* XXX this is also used by cache and should be somewhere else */ + +static PLHashNumber +nss_certificate_hash ( + const void *key +) +{ + unsigned int i; + PLHashNumber h; + NSSCertificate *c = (NSSCertificate *)key; + h = 0; + for (i=0; i<c->issuer.size; i++) + h = PR_ROTATE_LEFT32(h, 4) ^ ((unsigned char *)c->issuer.data)[i]; + for (i=0; i<c->serial.size; i++) + h = PR_ROTATE_LEFT32(h, 4) ^ ((unsigned char *)c->serial.data)[i]; + return h; +} + +static int +nss_compare_certs(const void *v1, const void *v2) +{ + PRStatus ignore; + NSSCertificate *c1 = (NSSCertificate *)v1; + NSSCertificate *c2 = (NSSCertificate *)v2; + return (int)(nssItem_Equal(&c1->issuer, &c2->issuer, &ignore) && + nssItem_Equal(&c1->serial, &c2->serial, &ignore)); +} + +NSS_IMPLEMENT nssHash * +nssHash_CreateCertificate ( + NSSArena *arenaOpt, + PRUint32 numBuckets +) +{ + return nssHash_Create(arenaOpt, + numBuckets, + nss_certificate_hash, + nss_compare_certs, + PL_CompareValues); +} + +NSS_IMPLEMENT void +nssCertificateStore_DumpStoreInfo ( + nssCertificateStore *store, + void (* cert_dump_iter)(const void *, void *, void *), + void *arg +) +{ + PZ_Lock(store->lock); + nssHash_Iterate(store->issuer_and_serial, cert_dump_iter, arg); + PZ_Unlock(store->lock); +} + diff --git a/mozilla/security/nss/lib/pki/pkistore.h b/mozilla/security/nss/lib/pki/pkistore.h new file mode 100644 index 0000000..a45f414 --- /dev/null +++ b/mozilla/security/nss/lib/pki/pkistore.h @@ -0,0 +1,204 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef PKISTORE_H +#define PKISTORE_H + +#ifdef DEBUG +static const char PKISTORE_CVS_ID[] = "@(#) $RCSfile: pkistore.h,v $ $Revision: 1.12 $ $Date: 2008/06/06 01:19:31 $"; +#endif /* DEBUG */ + +#ifndef NSSPKIT_H +#include "nsspkit.h" +#endif /* NSSPKIT_H */ + +#ifndef BASE_H +#include "base.h" +#endif /* BASE_H */ + +PR_BEGIN_EXTERN_C + +/* + * PKI Stores + * + * This is a set of routines for managing local stores of PKI objects. + * Currently, the only application is in crypto contexts, where the + * certificate store is used. In the future, methods should be added + * here for storing local references to keys. + */ + +/* + * nssCertificateStore + * + * Manages local store of certificate, trust, and S/MIME profile objects. + * Within a crypto context, mappings of cert to trust and cert to S/MIME + * profile are always 1-1. Therefore, it is reasonable to store all objects + * in a single collection, indexed by the certificate. + */ + +NSS_EXTERN nssCertificateStore * +nssCertificateStore_Create +( + NSSArena *arenaOpt +); + +NSS_EXTERN PRStatus +nssCertificateStore_Destroy +( + nssCertificateStore *store +); + +/* Atomic Find cert in store, or add this cert to the store. +** Ref counts properly maintained. +*/ +NSS_EXTERN NSSCertificate * +nssCertificateStore_FindOrAdd +( + nssCertificateStore *store, + NSSCertificate *c +); + +NSS_EXTERN void +nssCertificateStore_RemoveCertLOCKED +( + nssCertificateStore *store, + NSSCertificate *cert +); + +struct nssCertificateStoreTraceStr { + nssCertificateStore* store; + PZLock* lock; + PRBool locked; + PRBool unlocked; +}; + +typedef struct nssCertificateStoreTraceStr nssCertificateStoreTrace; + +NSS_EXTERN void +nssCertificateStore_Lock ( + nssCertificateStore *store, nssCertificateStoreTrace* out +); + +NSS_EXTERN void +nssCertificateStore_Unlock ( + nssCertificateStore *store, const nssCertificateStoreTrace* in, + nssCertificateStoreTrace* out +); + +NSS_EXTERN NSSCertificate ** +nssCertificateStore_FindCertificatesBySubject +( + nssCertificateStore *store, + NSSDER *subject, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, + NSSArena *arenaOpt +); + +NSS_EXTERN NSSCertificate ** +nssCertificateStore_FindCertificatesByNickname +( + nssCertificateStore *store, + const NSSUTF8 *nickname, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, + NSSArena *arenaOpt +); + +NSS_EXTERN NSSCertificate ** +nssCertificateStore_FindCertificatesByEmail +( + nssCertificateStore *store, + NSSASCII7 *email, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, + NSSArena *arenaOpt +); + +NSS_EXTERN NSSCertificate * +nssCertificateStore_FindCertificateByIssuerAndSerialNumber +( + nssCertificateStore *store, + NSSDER *issuer, + NSSDER *serial +); + +NSS_EXTERN NSSCertificate * +nssCertificateStore_FindCertificateByEncodedCertificate +( + nssCertificateStore *store, + NSSDER *encoding +); + +NSS_EXTERN PRStatus +nssCertificateStore_AddTrust +( + nssCertificateStore *store, + NSSTrust *trust +); + +NSS_EXTERN NSSTrust * +nssCertificateStore_FindTrustForCertificate +( + nssCertificateStore *store, + NSSCertificate *cert +); + +NSS_EXTERN PRStatus +nssCertificateStore_AddSMIMEProfile +( + nssCertificateStore *store, + nssSMIMEProfile *profile +); + +NSS_EXTERN nssSMIMEProfile * +nssCertificateStore_FindSMIMEProfileForCertificate +( + nssCertificateStore *store, + NSSCertificate *cert +); + +NSS_EXTERN void +nssCertificateStore_DumpStoreInfo +( + nssCertificateStore *store, + void (* cert_dump_iter)(const void *, void *, void *), + void *arg +); + +PR_END_EXTERN_C + +#endif /* PKISTORE_H */ diff --git a/mozilla/security/nss/lib/pki/pkit.h b/mozilla/security/nss/lib/pki/pkit.h new file mode 100644 index 0000000..15d6c16 --- /dev/null +++ b/mozilla/security/nss/lib/pki/pkit.h @@ -0,0 +1,224 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef PKIT_H +#define PKIT_H + +#ifdef DEBUG +static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.19 $ $Date: 2007/11/16 05:29:27 $"; +#endif /* DEBUG */ + +/* + * pkit.h + * + * This file contains definitions for the types of the top-level PKI objects. + */ + +#ifndef NSSBASET_H +#include "nssbaset.h" +#endif /* NSSBASET_H */ + +#ifndef BASET_H +#include "baset.h" +#endif /* BASET_H */ + +#include "certt.h" +#include "pkcs11t.h" + +#ifndef NSSPKIT_H +#include "nsspkit.h" +#endif /* NSSPKIT_H */ + +#ifndef NSSDEVT_H +#include "nssdevt.h" +#endif /* NSSDEVT_H */ + +#ifndef DEVT_H +#include "devt.h" +#endif /* DEVT_H */ + +#ifndef nssrwlkt_h__ +#include "nssrwlkt.h" +#endif /* nssrwlkt_h__ */ + +PR_BEGIN_EXTERN_C + +/* + * A note on ephemeral certs + * + * The key objects defined here can only be created on tokens, and can only + * exist on tokens. Therefore, any instance of a key object must have + * a corresponding cryptoki instance. OTOH, certificates created in + * crypto contexts need not be stored as session objects on the token. + * There are good performance reasons for not doing so. The certificate + * and trust objects have been defined with a cryptoContext field to + * allow for ephemeral certs, which may have a single instance in a crypto + * context along with any number (including zero) of cryptoki instances. + * Since contexts may not share objects, there can be only one context + * for each object. + */ + +typedef enum { + nssPKILock = 1, + nssPKIMonitor = 2 +} nssPKILockType; + +/* nssPKIObject + * + * This is the base object class, common to all PKI objects defined in + * nsspkit.h + */ +struct nssPKIObjectStr +{ + /* The arena for all object memory */ + NSSArena *arena; + /* Atomically incremented/decremented reference counting */ + PRInt32 refCount; + /* lock protects the array of nssCryptokiInstance's of the object */ + union { + PZLock* lock; + PZMonitor *mlock; + } sync; + nssPKILockType lockType; + /* XXX with LRU cache, this cannot be guaranteed up-to-date. It cannot + * be compared against the update level of the trust domain, since it is + * also affected by import/export. Where is this array needed? + */ + nssCryptokiObject **instances; + PRUint32 numInstances; + /* The object must live in a trust domain */ + NSSTrustDomain *trustDomain; + /* The object may live in a crypto context */ + NSSCryptoContext *cryptoContext; + /* XXX added so temp certs can have nickname, think more ... */ + NSSUTF8 *tempName; +}; + +typedef struct nssDecodedCertStr nssDecodedCert; + +typedef struct nssCertificateStoreStr nssCertificateStore; + +/* How wide is the scope of this? */ +typedef struct nssSMIMEProfileStr nssSMIMEProfile; + +typedef struct nssPKIObjectStr nssPKIObject; + +struct NSSTrustStr +{ + nssPKIObject object; + NSSCertificate *certificate; + nssTrustLevel serverAuth; + nssTrustLevel clientAuth; + nssTrustLevel emailProtection; + nssTrustLevel codeSigning; + PRBool stepUpApproved; +}; + +struct nssSMIMEProfileStr +{ + nssPKIObject object; + NSSCertificate *certificate; + NSSASCII7 *email; + NSSDER *subject; + NSSItem *profileTime; + NSSItem *profileData; +}; + +struct NSSCertificateStr +{ + nssPKIObject object; + NSSCertificateType type; + NSSItem id; + NSSBER encoding; + NSSDER issuer; + NSSDER subject; + NSSDER serial; + NSSASCII7 *email; + nssDecodedCert *decoding; +}; + +struct NSSPrivateKeyStr; + +struct NSSPublicKeyStr; + +struct NSSSymmetricKeyStr; + +typedef struct nssTDCertificateCacheStr nssTDCertificateCache; + +struct NSSTrustDomainStr { + PRInt32 refCount; + NSSArena *arena; + NSSCallback *defaultCallback; + nssList *tokenList; + nssListIterator *tokens; + nssTDCertificateCache *cache; + NSSRWLock *tokensLock; + void *spkDigestInfo; + CERTStatusConfig *statusConfig; +}; + +struct NSSCryptoContextStr +{ + PRInt32 refCount; + NSSArena *arena; + NSSTrustDomain *td; + NSSToken *token; + nssSession *session; + nssCertificateStore *certStore; +}; + +struct NSSTimeStr { + PRTime prTime; +}; + +struct NSSCRLStr { + nssPKIObject object; + NSSDER encoding; + NSSUTF8 *url; + PRBool isKRL; +}; + +typedef struct NSSCRLStr NSSCRL; + +struct NSSPoliciesStr; + +struct NSSAlgorithmAndParametersStr; + +struct NSSPKIXCertificateStr; + +PR_END_EXTERN_C + +#endif /* PKIT_H */ diff --git a/mozilla/security/nss/lib/pki/pkitm.h b/mozilla/security/nss/lib/pki/pkitm.h new file mode 100644 index 0000000..a0ebba9 --- /dev/null +++ b/mozilla/security/nss/lib/pki/pkitm.h @@ -0,0 +1,121 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef PKITM_H +#define PKITM_H + +#ifdef DEBUG +static const char PKITM_CVS_ID[] = "@(#) $RCSfile: pkitm.h,v $ $Revision: 1.15 $ $Date: 2007/11/16 05:29:27 $"; +#endif /* DEBUG */ + +/* + * pkitm.h + * + * This file contains PKI-module specific types. + */ + +#ifndef BASET_H +#include "baset.h" +#endif /* BASET_H */ + +#ifndef PKIT_H +#include "pkit.h" +#endif /* PKIT_H */ + +PR_BEGIN_EXTERN_C + +typedef enum nssCertIDMatchEnum { + nssCertIDMatch_Yes = 0, + nssCertIDMatch_No = 1, + nssCertIDMatch_Unknown = 2 +} nssCertIDMatch; + +/* + * nssDecodedCert + * + * This is an interface to allow the PKI module access to certificate + * information that can only be found by decoding. The interface is + * generic, allowing each certificate type its own way of providing + * the information + */ +struct nssDecodedCertStr { + NSSCertificateType type; + void *data; + /* returns the unique identifier for the cert */ + NSSItem * (*getIdentifier)(nssDecodedCert *dc); + /* returns the unique identifier for this cert's issuer */ + void * (*getIssuerIdentifier)(nssDecodedCert *dc); + /* is id the identifier for this cert? */ + nssCertIDMatch (*matchIdentifier)(nssDecodedCert *dc, void *id); + /* is this cert a valid CA cert? */ + PRBool (*isValidIssuer)(nssDecodedCert *dc); + /* returns the cert usage */ + NSSUsage * (*getUsage)(nssDecodedCert *dc); + /* is time within the validity period of the cert? */ + PRBool (*isValidAtTime)(nssDecodedCert *dc, NSSTime *time); + /* is the validity period of this cert newer than cmpdc? */ + PRBool (*isNewerThan)(nssDecodedCert *dc, nssDecodedCert *cmpdc); + /* does the usage for this cert match the requested usage? */ + PRBool (*matchUsage)(nssDecodedCert *dc, const NSSUsage *usage); + /* extract the email address */ + NSSASCII7 *(*getEmailAddress)(nssDecodedCert *dc); + /* extract the DER-encoded serial number */ + PRStatus (*getDERSerialNumber)(nssDecodedCert *dc, + NSSDER *derSerial, NSSArena *arena); +}; + +struct NSSUsageStr { + PRBool anyUsage; + SECCertUsage nss3usage; + PRBool nss3lookingForCA; +}; + +typedef struct nssPKIObjectCollectionStr nssPKIObjectCollection; + +typedef struct +{ + union { + PRStatus (* cert)(NSSCertificate *c, void *arg); + PRStatus (* crl)(NSSCRL *crl, void *arg); + PRStatus (* pvkey)(NSSPrivateKey *vk, void *arg); + PRStatus (* pbkey)(NSSPublicKey *bk, void *arg); + } func; + void *arg; +} nssPKIObjectCallback; + +PR_END_EXTERN_C + +#endif /* PKITM_H */ diff --git a/mozilla/security/nss/lib/pki/symmkey.c b/mozilla/security/nss/lib/pki/symmkey.c new file mode 100644 index 0000000..036a9bd --- /dev/null +++ b/mozilla/security/nss/lib/pki/symmkey.c @@ -0,0 +1,300 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifdef DEBUG +static const char CVS_ID[] = "@(#) $RCSfile: symmkey.c,v $ $Revision: 1.6 $ $Date: 2005/01/20 02:25:49 $"; +#endif /* DEBUG */ + +#ifndef NSSPKI_H +#include "nsspki.h" +#endif /* NSSPKI_H */ + +extern const NSSError NSS_ERROR_NOT_FOUND; + +NSS_IMPLEMENT PRStatus +NSSSymmetricKey_Destroy ( + NSSSymmetricKey *mk +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT PRStatus +NSSSymmetricKey_DeleteStoredObject ( + NSSSymmetricKey *mk, + NSSCallback *uhh +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT PRUint32 +NSSSymmetricKey_GetKeyLength ( + NSSSymmetricKey *mk +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return -1; +} + +NSS_IMPLEMENT PRUint32 +NSSSymmetricKey_GetKeyStrength ( + NSSSymmetricKey *mk +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return -1; +} + +NSS_IMPLEMENT PRStatus +NSSSymmetricKey_IsStillPresent ( + NSSSymmetricKey *mk +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT NSSTrustDomain * +NSSSymmetricKey_GetTrustDomain ( + NSSSymmetricKey *mk, + PRStatus *statusOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSToken * +NSSSymmetricKey_GetToken ( + NSSSymmetricKey *mk, + PRStatus *statusOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSSlot * +NSSSymmetricKey_GetSlot ( + NSSSymmetricKey *mk, + PRStatus *statusOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSModule * +NSSSymmetricKey_GetModule ( + NSSSymmetricKey *mk, + PRStatus *statusOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSItem * +NSSSymmetricKey_Encrypt ( + NSSSymmetricKey *mk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSItem * +NSSSymmetricKey_Decrypt ( + NSSSymmetricKey *mk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *encryptedData, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSItem * +NSSSymmetricKey_Sign ( + NSSSymmetricKey *mk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSItem * +NSSSymmetricKey_SignRecover ( + NSSSymmetricKey *mk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT PRStatus +NSSSymmetricKey_Verify ( + NSSSymmetricKey *mk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *data, + NSSItem *signature, + NSSCallback *uhh +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT NSSItem * +NSSSymmetricKey_VerifyRecover ( + NSSSymmetricKey *mk, + NSSAlgorithmAndParameters *apOpt, + NSSItem *signature, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSItem * +NSSSymmetricKey_WrapSymmetricKey ( + NSSSymmetricKey *wrappingKey, + NSSAlgorithmAndParameters *apOpt, + NSSSymmetricKey *keyToWrap, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSItem * +NSSSymmetricKey_WrapPrivateKey ( + NSSSymmetricKey *wrappingKey, + NSSAlgorithmAndParameters *apOpt, + NSSPrivateKey *keyToWrap, + NSSCallback *uhh, + NSSItem *rvOpt, + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSSymmetricKey * +NSSSymmetricKey_UnwrapSymmetricKey ( + NSSSymmetricKey *wrappingKey, + NSSAlgorithmAndParameters *apOpt, + NSSItem *wrappedKey, + NSSOID *target, + PRUint32 keySizeOpt, + NSSOperations operations, + NSSCallback *uhh +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSPrivateKey * +NSSSymmetricKey_UnwrapPrivateKey ( + NSSSymmetricKey *wrappingKey, + NSSAlgorithmAndParameters *apOpt, + NSSItem *wrappedKey, + NSSUTF8 *labelOpt, + NSSItem *keyIDOpt, + PRBool persistant, + PRBool sensitive, + NSSToken *destinationOpt, + NSSCallback *uhh +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSSymmetricKey * +NSSSymmetricKey_DeriveSymmetricKey ( + NSSSymmetricKey *originalKey, + NSSAlgorithmAndParameters *apOpt, + NSSOID *target, + PRUint32 keySizeOpt, + NSSOperations operations, + NSSCallback *uhh +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCryptoContext * +NSSSymmetricKey_CreateCryptoContext ( + NSSSymmetricKey *mk, + NSSAlgorithmAndParameters *apOpt, + NSSCallback *uhh +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + diff --git a/mozilla/security/nss/lib/pki/tdcache.c b/mozilla/security/nss/lib/pki/tdcache.c new file mode 100644 index 0000000..62cf4b8 --- /dev/null +++ b/mozilla/security/nss/lib/pki/tdcache.c @@ -0,0 +1,1178 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifdef DEBUG +static const char CVS_ID[] = "@(#) $RCSfile: tdcache.c,v $ $Revision: 1.49 $ $Date: 2010/02/10 02:04:32 $"; +#endif /* DEBUG */ + +#ifndef PKIM_H +#include "pkim.h" +#endif /* PKIM_H */ + +#ifndef PKIT_H +#include "pkit.h" +#endif /* PKIT_H */ + +#ifndef NSSPKI_H +#include "nsspki.h" +#endif /* NSSPKI_H */ + +#ifndef PKI_H +#include "pki.h" +#endif /* PKI_H */ + +#ifndef NSSBASE_H +#include "nssbase.h" +#endif /* NSSBASE_H */ + +#ifndef BASE_H +#include "base.h" +#endif /* BASE_H */ + +#include "cert.h" +#include "dev.h" +#include "pki3hack.h" + +#ifdef DEBUG_CACHE +static PRLogModuleInfo *s_log = NULL; +#endif + +#ifdef DEBUG_CACHE +static void log_item_dump(const char *msg, NSSItem *it) +{ + char buf[33]; + int i, j; + for (i=0; i<10 && i<it->size; i++) { + sprintf(&buf[2*i], "%02X", ((PRUint8 *)it->data)[i]); + } + if (it->size>10) { + sprintf(&buf[2*i], ".."); + i += 1; + for (j=it->size-1; i<=16 && j>10; i++, j--) { + sprintf(&buf[2*i], "%02X", ((PRUint8 *)it->data)[j]); + } + } + PR_LOG(s_log, PR_LOG_DEBUG, ("%s: %s", msg, buf)); +} +#endif + +#ifdef DEBUG_CACHE +static void log_cert_ref(const char *msg, NSSCertificate *c) +{ + PR_LOG(s_log, PR_LOG_DEBUG, ("%s: %s", msg, + (c->nickname) ? c->nickname : c->email)); + log_item_dump("\tserial", &c->serial); + log_item_dump("\tsubject", &c->subject); +} +#endif + +/* Certificate cache routines */ + +/* XXX + * Locking is not handled well at all. A single, global lock with sub-locks + * in the collection types. Cleanup needed. + */ + +/* should it live in its own arena? */ +struct nssTDCertificateCacheStr +{ + PZLock *lock; + NSSArena *arena; + nssHash *issuerAndSN; + nssHash *subject; + nssHash *nickname; + nssHash *email; +}; + +struct cache_entry_str +{ + union { + NSSCertificate *cert; + nssList *list; + void *value; + } entry; + PRUint32 hits; + PRTime lastHit; + NSSArena *arena; + NSSUTF8 *nickname; +}; + +typedef struct cache_entry_str cache_entry; + +static cache_entry * +new_cache_entry(NSSArena *arena, void *value, PRBool ownArena) +{ + cache_entry *ce = nss_ZNEW(arena, cache_entry); + if (ce) { + ce->entry.value = value; + ce->hits = 1; + ce->lastHit = PR_Now(); + if (ownArena) { + ce->arena = arena; + } + ce->nickname = NULL; + } + return ce; +} + +/* this should not be exposed in a header, but is here to keep the above + * types/functions static + */ +NSS_IMPLEMENT PRStatus +nssTrustDomain_InitializeCache ( + NSSTrustDomain *td, + PRUint32 cacheSize +) +{ + NSSArena *arena; + nssTDCertificateCache *cache = td->cache; +#ifdef DEBUG_CACHE + s_log = PR_NewLogModule("nss_cache"); + PR_ASSERT(s_log); +#endif + PR_ASSERT(!cache); + arena = nssArena_Create(); + if (!arena) { + return PR_FAILURE; + } + cache = nss_ZNEW(arena, nssTDCertificateCache); + if (!cache) { + nssArena_Destroy(arena); + return PR_FAILURE; + } + cache->lock = PZ_NewLock(nssILockCache); + if (!cache->lock) { + nssArena_Destroy(arena); + return PR_FAILURE; + } + /* Create the issuer and serial DER --> certificate hash */ + cache->issuerAndSN = nssHash_CreateCertificate(arena, cacheSize); + if (!cache->issuerAndSN) { + goto loser; + } + /* Create the subject DER --> subject list hash */ + cache->subject = nssHash_CreateItem(arena, cacheSize); + if (!cache->subject) { + goto loser; + } + /* Create the nickname --> subject list hash */ + cache->nickname = nssHash_CreateString(arena, cacheSize); + if (!cache->nickname) { + goto loser; + } + /* Create the email --> list of subject lists hash */ + cache->email = nssHash_CreateString(arena, cacheSize); + if (!cache->email) { + goto loser; + } + cache->arena = arena; + td->cache = cache; +#ifdef DEBUG_CACHE + PR_LOG(s_log, PR_LOG_DEBUG, ("Cache initialized.")); +#endif + return PR_SUCCESS; +loser: + PZ_DestroyLock(cache->lock); + nssArena_Destroy(arena); + td->cache = NULL; +#ifdef DEBUG_CACHE + PR_LOG(s_log, PR_LOG_DEBUG, ("Cache initialization failed.")); +#endif + return PR_FAILURE; +} + +/* The entries of the hashtable are currently dependent on the certificate(s) + * that produced them. That is, the entries will be freed when the cert is + * released from the cache. If there are certs in the cache at any time, + * including shutdown, the hash table entries will hold memory. In order for + * clean shutdown, it is necessary for there to be no certs in the cache. + */ + +extern const NSSError NSS_ERROR_INTERNAL_ERROR; +extern const NSSError NSS_ERROR_BUSY; + +NSS_IMPLEMENT PRStatus +nssTrustDomain_DestroyCache ( + NSSTrustDomain *td +) +{ + if (!td->cache) { + nss_SetError(NSS_ERROR_INTERNAL_ERROR); + return PR_FAILURE; + } + if (nssHash_Count(td->cache->issuerAndSN) > 0) { + nss_SetError(NSS_ERROR_BUSY); + return PR_FAILURE; + } + PZ_DestroyLock(td->cache->lock); + nssHash_Destroy(td->cache->issuerAndSN); + nssHash_Destroy(td->cache->subject); + nssHash_Destroy(td->cache->nickname); + nssHash_Destroy(td->cache->email); + nssArena_Destroy(td->cache->arena); + td->cache = NULL; +#ifdef DEBUG_CACHE + PR_LOG(s_log, PR_LOG_DEBUG, ("Cache destroyed.")); +#endif + return PR_SUCCESS; +} + +static PRStatus +remove_issuer_and_serial_entry ( + nssTDCertificateCache *cache, + NSSCertificate *cert +) +{ + /* Remove the cert from the issuer/serial hash */ + nssHash_Remove(cache->issuerAndSN, cert); +#ifdef DEBUG_CACHE + log_cert_ref("removed issuer/sn", cert); +#endif + return PR_SUCCESS; +} + +static PRStatus +remove_subject_entry ( + nssTDCertificateCache *cache, + NSSCertificate *cert, + nssList **subjectList, + NSSUTF8 **nickname, + NSSArena **arena +) +{ + PRStatus nssrv; + cache_entry *ce; + *subjectList = NULL; + *arena = NULL; + /* Get the subject list for the cert's subject */ + ce = (cache_entry *)nssHash_Lookup(cache->subject, &cert->subject); + if (ce) { + /* Remove the cert from the subject hash */ + nssList_Remove(ce->entry.list, cert); + *subjectList = ce->entry.list; + *nickname = ce->nickname; + *arena = ce->arena; + nssrv = PR_SUCCESS; +#ifdef DEBUG_CACHE + log_cert_ref("removed cert", cert); + log_item_dump("from subject list", &cert->subject); +#endif + } else { + nssrv = PR_FAILURE; + } + return nssrv; +} + +static PRStatus +remove_nickname_entry ( + nssTDCertificateCache *cache, + NSSUTF8 *nickname, + nssList *subjectList +) +{ + PRStatus nssrv; + if (nickname) { + nssHash_Remove(cache->nickname, nickname); + nssrv = PR_SUCCESS; +#ifdef DEBUG_CACHE + PR_LOG(s_log, PR_LOG_DEBUG, ("removed nickname %s", nickname)); +#endif + } else { + nssrv = PR_FAILURE; + } + return nssrv; +} + +static PRStatus +remove_email_entry ( + nssTDCertificateCache *cache, + NSSCertificate *cert, + nssList *subjectList +) +{ + PRStatus nssrv = PR_FAILURE; + cache_entry *ce; + /* Find the subject list in the email hash */ + if (cert->email) { + ce = (cache_entry *)nssHash_Lookup(cache->email, cert->email); + if (ce) { + nssList *subjects = ce->entry.list; + /* Remove the subject list from the email hash */ + nssList_Remove(subjects, subjectList); +#ifdef DEBUG_CACHE + log_item_dump("removed subject list", &cert->subject); + PR_LOG(s_log, PR_LOG_DEBUG, ("for email %s", cert->email)); +#endif + if (nssList_Count(subjects) == 0) { + /* No more subject lists for email, delete list and + * remove hash entry + */ + (void)nssList_Destroy(subjects); + nssHash_Remove(cache->email, cert->email); + /* there are no entries left for this address, free space + * used for email entries + */ + nssArena_Destroy(ce->arena); +#ifdef DEBUG_CACHE + PR_LOG(s_log, PR_LOG_DEBUG, ("removed email %s", cert->email)); +#endif + } + nssrv = PR_SUCCESS; + } + } + return nssrv; +} + +NSS_IMPLEMENT void +nssTrustDomain_RemoveCertFromCacheLOCKED ( + NSSTrustDomain *td, + NSSCertificate *cert +) +{ + nssList *subjectList; + cache_entry *ce; + NSSArena *arena; + NSSUTF8 *nickname; + +#ifdef DEBUG_CACHE + log_cert_ref("attempt to remove cert", cert); +#endif + ce = (cache_entry *)nssHash_Lookup(td->cache->issuerAndSN, cert); + if (!ce || ce->entry.cert != cert) { + /* If it's not in the cache, or a different cert is (this is really + * for safety reasons, though it shouldn't happen), do nothing + */ +#ifdef DEBUG_CACHE + PR_LOG(s_log, PR_LOG_DEBUG, ("but it wasn't in the cache")); +#endif + return; + } + (void)remove_issuer_and_serial_entry(td->cache, cert); + (void)remove_subject_entry(td->cache, cert, &subjectList, + &nickname, &arena); + if (nssList_Count(subjectList) == 0) { + (void)remove_nickname_entry(td->cache, nickname, subjectList); + (void)remove_email_entry(td->cache, cert, subjectList); + (void)nssList_Destroy(subjectList); + nssHash_Remove(td->cache->subject, &cert->subject); + /* there are no entries left for this subject, free the space used + * for both the nickname and subject entries + */ + if (arena) { + nssArena_Destroy(arena); + } + } +} + +NSS_IMPLEMENT void +nssTrustDomain_LockCertCache ( + NSSTrustDomain *td +) +{ + PZ_Lock(td->cache->lock); +} + +NSS_IMPLEMENT void +nssTrustDomain_UnlockCertCache ( + NSSTrustDomain *td +) +{ + PZ_Unlock(td->cache->lock); +} + +struct token_cert_dtor { + NSSToken *token; + nssTDCertificateCache *cache; + NSSCertificate **certs; + PRUint32 numCerts, arrSize; +}; + +static void +remove_token_certs(const void *k, void *v, void *a) +{ + NSSCertificate *c = (NSSCertificate *)k; + nssPKIObject *object = &c->object; + struct token_cert_dtor *dtor = a; + PRUint32 i; + nssPKIObject_Lock(object); + for (i=0; i<object->numInstances; i++) { + if (object->instances[i]->token == dtor->token) { + nssCryptokiObject_Destroy(object->instances[i]); + object->instances[i] = object->instances[object->numInstances-1]; + object->instances[object->numInstances-1] = NULL; + object->numInstances--; + dtor->certs[dtor->numCerts++] = c; + if (dtor->numCerts == dtor->arrSize) { + dtor->arrSize *= 2; + dtor->certs = nss_ZREALLOCARRAY(dtor->certs, + NSSCertificate *, + dtor->arrSize); + } + break; + } + } + nssPKIObject_Unlock(object); + return; +} + +/* + * Remove all certs for the given token from the cache. This is + * needed if the token is removed. + */ +NSS_IMPLEMENT PRStatus +nssTrustDomain_RemoveTokenCertsFromCache ( + NSSTrustDomain *td, + NSSToken *token +) +{ + NSSCertificate **certs; + PRUint32 i, arrSize = 10; + struct token_cert_dtor dtor; + certs = nss_ZNEWARRAY(NULL, NSSCertificate *, arrSize); + if (!certs) { + return PR_FAILURE; + } + dtor.cache = td->cache; + dtor.token = token; + dtor.certs = certs; + dtor.numCerts = 0; + dtor.arrSize = arrSize; + PZ_Lock(td->cache->lock); + nssHash_Iterate(td->cache->issuerAndSN, remove_token_certs, (void *)&dtor); + for (i=0; i<dtor.numCerts; i++) { + if (dtor.certs[i]->object.numInstances == 0) { + nssTrustDomain_RemoveCertFromCacheLOCKED(td, dtor.certs[i]); + dtor.certs[i] = NULL; /* skip this cert in the second for loop */ + } + } + PZ_Unlock(td->cache->lock); + for (i=0; i<dtor.numCerts; i++) { + if (dtor.certs[i]) { + STAN_ForceCERTCertificateUpdate(dtor.certs[i]); + } + } + nss_ZFreeIf(dtor.certs); + return PR_SUCCESS; +} + +NSS_IMPLEMENT PRStatus +nssTrustDomain_UpdateCachedTokenCerts ( + NSSTrustDomain *td, + NSSToken *token +) +{ + NSSCertificate **cp, **cached = NULL; + nssList *certList; + PRUint32 count; + certList = nssList_Create(NULL, PR_FALSE); + if (!certList) return PR_FAILURE; + (void)nssTrustDomain_GetCertsFromCache(td, certList); + count = nssList_Count(certList); + if (count > 0) { + cached = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1); + if (!cached) { + return PR_FAILURE; + } + nssList_GetArray(certList, (void **)cached, count); + nssList_Destroy(certList); + for (cp = cached; *cp; cp++) { + nssCryptokiObject *instance; + NSSCertificate *c = *cp; + nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; + instance = nssToken_FindCertificateByIssuerAndSerialNumber( + token, + NULL, + &c->issuer, + &c->serial, + tokenOnly, + NULL); + if (instance) { + nssPKIObject_AddInstance(&c->object, instance); + STAN_ForceCERTCertificateUpdate(c); + } + } + nssCertificateArray_Destroy(cached); + } + return PR_SUCCESS; +} + +static PRStatus +add_issuer_and_serial_entry ( + NSSArena *arena, + nssTDCertificateCache *cache, + NSSCertificate *cert +) +{ + cache_entry *ce; + ce = new_cache_entry(arena, (void *)cert, PR_FALSE); +#ifdef DEBUG_CACHE + log_cert_ref("added to issuer/sn", cert); +#endif + return nssHash_Add(cache->issuerAndSN, cert, (void *)ce); +} + +static PRStatus +add_subject_entry ( + NSSArena *arena, + nssTDCertificateCache *cache, + NSSCertificate *cert, + NSSUTF8 *nickname, + nssList **subjectList +) +{ + PRStatus nssrv; + nssList *list; + cache_entry *ce; + *subjectList = NULL; /* this is only set if a new one is created */ + ce = (cache_entry *)nssHash_Lookup(cache->subject, &cert->subject); + if (ce) { + ce->hits++; + ce->lastHit = PR_Now(); + /* The subject is already in, add this cert to the list */ + nssrv = nssList_AddUnique(ce->entry.list, cert); +#ifdef DEBUG_CACHE + log_cert_ref("added to existing subject list", cert); +#endif + } else { + NSSDER *subject; + /* Create a new subject list for the subject */ + list = nssList_Create(arena, PR_FALSE); + if (!list) { + return PR_FAILURE; + } + ce = new_cache_entry(arena, (void *)list, PR_TRUE); + if (!ce) { + return PR_FAILURE; + } + if (nickname) { + ce->nickname = nssUTF8_Duplicate(nickname, arena); + } + nssList_SetSortFunction(list, nssCertificate_SubjectListSort); + /* Add the cert entry to this list of subjects */ + nssrv = nssList_AddUnique(list, cert); + if (nssrv != PR_SUCCESS) { + return nssrv; + } + /* Add the subject list to the cache */ + subject = nssItem_Duplicate(&cert->subject, arena, NULL); + if (!subject) { + return PR_FAILURE; + } + nssrv = nssHash_Add(cache->subject, subject, ce); + if (nssrv != PR_SUCCESS) { + return nssrv; + } + *subjectList = list; +#ifdef DEBUG_CACHE + log_cert_ref("created subject list", cert); +#endif + } + return nssrv; +} + +static PRStatus +add_nickname_entry ( + NSSArena *arena, + nssTDCertificateCache *cache, + NSSUTF8 *certNickname, + nssList *subjectList +) +{ + PRStatus nssrv = PR_SUCCESS; + cache_entry *ce; + ce = (cache_entry *)nssHash_Lookup(cache->nickname, certNickname); + if (ce) { + /* This is a collision. A nickname entry already exists for this + * subject, but a subject entry didn't. This would imply there are + * two subjects using the same nickname, which is not allowed. + */ + return PR_FAILURE; + } else { + NSSUTF8 *nickname; + ce = new_cache_entry(arena, subjectList, PR_FALSE); + if (!ce) { + return PR_FAILURE; + } + nickname = nssUTF8_Duplicate(certNickname, arena); + if (!nickname) { + return PR_FAILURE; + } + nssrv = nssHash_Add(cache->nickname, nickname, ce); +#ifdef DEBUG_CACHE + log_cert_ref("created nickname for", cert); +#endif + } + return nssrv; +} + +static PRStatus +add_email_entry ( + nssTDCertificateCache *cache, + NSSCertificate *cert, + nssList *subjectList +) +{ + PRStatus nssrv = PR_SUCCESS; + nssList *subjects; + cache_entry *ce; + ce = (cache_entry *)nssHash_Lookup(cache->email, cert->email); + if (ce) { + /* Already have an entry for this email address, but not subject */ + subjects = ce->entry.list; + nssrv = nssList_AddUnique(subjects, subjectList); + ce->hits++; + ce->lastHit = PR_Now(); +#ifdef DEBUG_CACHE + log_cert_ref("added subject to email for", cert); +#endif + } else { + NSSASCII7 *email; + NSSArena *arena; + arena = nssArena_Create(); + if (!arena) { + return PR_FAILURE; + } + /* Create a new list of subject lists, add this subject */ + subjects = nssList_Create(arena, PR_TRUE); + if (!subjects) { + nssArena_Destroy(arena); + return PR_FAILURE; + } + /* Add the new subject to the list */ + nssrv = nssList_AddUnique(subjects, subjectList); + if (nssrv != PR_SUCCESS) { + nssArena_Destroy(arena); + return nssrv; + } + /* Add the new entry to the cache */ + ce = new_cache_entry(arena, (void *)subjects, PR_TRUE); + if (!ce) { + nssArena_Destroy(arena); + return PR_FAILURE; + } + email = nssUTF8_Duplicate(cert->email, arena); + if (!email) { + nssArena_Destroy(arena); + return PR_FAILURE; + } + nssrv = nssHash_Add(cache->email, email, ce); + if (nssrv != PR_SUCCESS) { + nssArena_Destroy(arena); + return nssrv; + } +#ifdef DEBUG_CACHE + log_cert_ref("created email for", cert); +#endif + } + return nssrv; +} + +extern const NSSError NSS_ERROR_CERTIFICATE_IN_CACHE; + +static void +remove_object_instances ( + nssPKIObject *object, + nssCryptokiObject **instances, + int numInstances +) +{ + int i; + + for (i = 0; i < numInstances; i++) { + nssPKIObject_RemoveInstanceForToken(object, instances[i]->token); + } +} + +static SECStatus +merge_object_instances ( + nssPKIObject *to, + nssPKIObject *from +) +{ + nssCryptokiObject **instances, **ci; + int i; + SECStatus rv = SECSuccess; + + instances = nssPKIObject_GetInstances(from); + if (instances == NULL) { + return SECFailure; + } + for (ci = instances, i = 0; *ci; ci++, i++) { + nssCryptokiObject *instance = nssCryptokiObject_Clone(*ci); + if (instance) { + if (nssPKIObject_AddInstance(to, instance) == SECSuccess) { + continue; + } + nssCryptokiObject_Destroy(instance); + } + remove_object_instances(to, instances, i); + rv = SECFailure; + break; + } + nssCryptokiObjectArray_Destroy(instances); + return rv; +} + +static NSSCertificate * +add_cert_to_cache ( + NSSTrustDomain *td, + NSSCertificate *cert +) +{ + NSSArena *arena = NULL; + nssList *subjectList = NULL; + PRStatus nssrv; + PRUint32 added = 0; + cache_entry *ce; + NSSCertificate *rvCert = NULL; + NSSUTF8 *certNickname = nssCertificate_GetNickname(cert, NULL); + + PZ_Lock(td->cache->lock); + /* If it exists in the issuer/serial hash, it's already in all */ + ce = (cache_entry *)nssHash_Lookup(td->cache->issuerAndSN, cert); + if (ce) { + ce->hits++; + ce->lastHit = PR_Now(); + rvCert = nssCertificate_AddRef(ce->entry.cert); +#ifdef DEBUG_CACHE + log_cert_ref("attempted to add cert already in cache", cert); +#endif + PZ_Unlock(td->cache->lock); + /* collision - somebody else already added the cert + * to the cache before this thread got around to it. + */ + /* merge the instances of the cert */ + if (merge_object_instances(&rvCert->object, &cert->object) + != SECSuccess) { + nssCertificate_Destroy(rvCert); + return NULL; + } + STAN_ForceCERTCertificateUpdate(rvCert); + nssCertificate_Destroy(cert); + return rvCert; + } + /* create a new cache entry for this cert within the cert's arena*/ + nssrv = add_issuer_and_serial_entry(cert->object.arena, td->cache, cert); + if (nssrv != PR_SUCCESS) { + goto loser; + } + added++; + /* create an arena for the nickname and subject entries */ + arena = nssArena_Create(); + if (!arena) { + goto loser; + } + /* create a new subject list for this cert, or add to existing */ + nssrv = add_subject_entry(arena, td->cache, cert, + certNickname, &subjectList); + if (nssrv != PR_SUCCESS) { + goto loser; + } + added++; + /* If a new subject entry was created, also need nickname and/or email */ + if (subjectList != NULL) { + PRBool handle = PR_FALSE; + if (certNickname) { + nssrv = add_nickname_entry(arena, td->cache, + certNickname, subjectList); + if (nssrv != PR_SUCCESS) { + goto loser; + } + handle = PR_TRUE; + added++; + } + if (cert->email) { + nssrv = add_email_entry(td->cache, cert, subjectList); + if (nssrv != PR_SUCCESS) { + goto loser; + } + handle = PR_TRUE; + added += 2; + } +#ifdef nodef + /* I think either a nickname or email address must be associated + * with the cert. However, certs are passed to NewTemp without + * either. This worked in the old code, so it must work now. + */ + if (!handle) { + /* Require either nickname or email handle */ + nssrv = PR_FAILURE; + goto loser; + } +#endif + } else { + /* A new subject entry was not created. arena is unused. */ + nssArena_Destroy(arena); + } + rvCert = cert; + PZ_Unlock(td->cache->lock); + return rvCert; +loser: + /* Remove any handles that have been created */ + subjectList = NULL; + if (added >= 1) { + (void)remove_issuer_and_serial_entry(td->cache, cert); + } + if (added >= 2) { + (void)remove_subject_entry(td->cache, cert, &subjectList, + &certNickname, &arena); + } + if (added == 3 || added == 5) { + (void)remove_nickname_entry(td->cache, certNickname, subjectList); + } + if (added >= 4) { + (void)remove_email_entry(td->cache, cert, subjectList); + } + if (subjectList) { + nssHash_Remove(td->cache->subject, &cert->subject); + nssList_Destroy(subjectList); + } + if (arena) { + nssArena_Destroy(arena); + } + PZ_Unlock(td->cache->lock); + return NULL; +} + +NSS_IMPLEMENT PRStatus +nssTrustDomain_AddCertsToCache ( + NSSTrustDomain *td, + NSSCertificate **certs, + PRUint32 numCerts +) +{ + PRUint32 i; + NSSCertificate *c; + for (i=0; i<numCerts && certs[i]; i++) { + c = add_cert_to_cache(td, certs[i]); + if (c == NULL) { + return PR_FAILURE; + } else { + certs[i] = c; + } + } + return PR_SUCCESS; +} + +static NSSCertificate ** +collect_subject_certs ( + nssList *subjectList, + nssList *rvCertListOpt +) +{ + NSSCertificate *c; + NSSCertificate **rvArray = NULL; + PRUint32 count; + nssCertificateList_AddReferences(subjectList); + if (rvCertListOpt) { + nssListIterator *iter = nssList_CreateIterator(subjectList); + if (!iter) { + return (NSSCertificate **)NULL; + } + for (c = (NSSCertificate *)nssListIterator_Start(iter); + c != (NSSCertificate *)NULL; + c = (NSSCertificate *)nssListIterator_Next(iter)) { + nssList_Add(rvCertListOpt, c); + } + nssListIterator_Finish(iter); + nssListIterator_Destroy(iter); + } else { + count = nssList_Count(subjectList); + rvArray = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1); + if (!rvArray) { + return (NSSCertificate **)NULL; + } + nssList_GetArray(subjectList, (void **)rvArray, count); + } + return rvArray; +} + +/* + * Find all cached certs with this subject. + */ +NSS_IMPLEMENT NSSCertificate ** +nssTrustDomain_GetCertsForSubjectFromCache ( + NSSTrustDomain *td, + NSSDER *subject, + nssList *certListOpt +) +{ + NSSCertificate **rvArray = NULL; + cache_entry *ce; +#ifdef DEBUG_CACHE + log_item_dump("looking for cert by subject", subject); +#endif + PZ_Lock(td->cache->lock); + ce = (cache_entry *)nssHash_Lookup(td->cache->subject, subject); + if (ce) { + ce->hits++; + ce->lastHit = PR_Now(); +#ifdef DEBUG_CACHE + PR_LOG(s_log, PR_LOG_DEBUG, ("... found, %d hits", ce->hits)); +#endif + rvArray = collect_subject_certs(ce->entry.list, certListOpt); + } + PZ_Unlock(td->cache->lock); + return rvArray; +} + +/* + * Find all cached certs with this label. + */ +NSS_IMPLEMENT NSSCertificate ** +nssTrustDomain_GetCertsForNicknameFromCache ( + NSSTrustDomain *td, + const NSSUTF8 *nickname, + nssList *certListOpt +) +{ + NSSCertificate **rvArray = NULL; + cache_entry *ce; +#ifdef DEBUG_CACHE + PR_LOG(s_log, PR_LOG_DEBUG, ("looking for cert by nick %s", nickname)); +#endif + PZ_Lock(td->cache->lock); + ce = (cache_entry *)nssHash_Lookup(td->cache->nickname, nickname); + if (ce) { + ce->hits++; + ce->lastHit = PR_Now(); +#ifdef DEBUG_CACHE + PR_LOG(s_log, PR_LOG_DEBUG, ("... found, %d hits", ce->hits)); +#endif + rvArray = collect_subject_certs(ce->entry.list, certListOpt); + } + PZ_Unlock(td->cache->lock); + return rvArray; +} + +/* + * Find all cached certs with this email address. + */ +NSS_IMPLEMENT NSSCertificate ** +nssTrustDomain_GetCertsForEmailAddressFromCache ( + NSSTrustDomain *td, + NSSASCII7 *email, + nssList *certListOpt +) +{ + NSSCertificate **rvArray = NULL; + cache_entry *ce; + nssList *collectList = NULL; + nssListIterator *iter = NULL; + nssList *subjectList; +#ifdef DEBUG_CACHE + PR_LOG(s_log, PR_LOG_DEBUG, ("looking for cert by email %s", email)); +#endif + PZ_Lock(td->cache->lock); + ce = (cache_entry *)nssHash_Lookup(td->cache->email, email); + if (ce) { + ce->hits++; + ce->lastHit = PR_Now(); +#ifdef DEBUG_CACHE + PR_LOG(s_log, PR_LOG_DEBUG, ("... found, %d hits", ce->hits)); +#endif + /* loop over subject lists and get refs for certs */ + if (certListOpt) { + collectList = certListOpt; + } else { + collectList = nssList_Create(NULL, PR_FALSE); + if (!collectList) { + PZ_Unlock(td->cache->lock); + return NULL; + } + } + iter = nssList_CreateIterator(ce->entry.list); + if (!iter) { + PZ_Unlock(td->cache->lock); + if (!certListOpt) { + nssList_Destroy(collectList); + } + return NULL; + } + for (subjectList = (nssList *)nssListIterator_Start(iter); + subjectList != (nssList *)NULL; + subjectList = (nssList *)nssListIterator_Next(iter)) { + (void)collect_subject_certs(subjectList, collectList); + } + nssListIterator_Finish(iter); + nssListIterator_Destroy(iter); + } + PZ_Unlock(td->cache->lock); + if (!certListOpt && collectList) { + PRUint32 count = nssList_Count(collectList); + rvArray = nss_ZNEWARRAY(NULL, NSSCertificate *, count); + if (rvArray) { + nssList_GetArray(collectList, (void **)rvArray, count); + } + nssList_Destroy(collectList); + } + return rvArray; +} + +/* + * Look for a specific cert in the cache + */ +NSS_IMPLEMENT NSSCertificate * +nssTrustDomain_GetCertForIssuerAndSNFromCache ( + NSSTrustDomain *td, + NSSDER *issuer, + NSSDER *serial +) +{ + NSSCertificate certkey; + NSSCertificate *rvCert = NULL; + cache_entry *ce; + certkey.issuer.data = issuer->data; + certkey.issuer.size = issuer->size; + certkey.serial.data = serial->data; + certkey.serial.size = serial->size; +#ifdef DEBUG_CACHE + log_item_dump("looking for cert by issuer/sn, issuer", issuer); + log_item_dump(" serial", serial); +#endif + PZ_Lock(td->cache->lock); + ce = (cache_entry *)nssHash_Lookup(td->cache->issuerAndSN, &certkey); + if (ce) { + ce->hits++; + ce->lastHit = PR_Now(); + rvCert = nssCertificate_AddRef(ce->entry.cert); +#ifdef DEBUG_CACHE + PR_LOG(s_log, PR_LOG_DEBUG, ("... found, %d hits", ce->hits)); +#endif + } + PZ_Unlock(td->cache->lock); + return rvCert; +} + +static PRStatus +issuer_and_serial_from_encoding ( + NSSBER *encoding, + NSSDER *issuer, + NSSDER *serial +) +{ + SECItem derCert, derIssuer, derSerial; + SECStatus secrv; + derCert.data = (unsigned char *)encoding->data; + derCert.len = encoding->size; + secrv = CERT_IssuerNameFromDERCert(&derCert, &derIssuer); + if (secrv != SECSuccess) { + return PR_FAILURE; + } + secrv = CERT_SerialNumberFromDERCert(&derCert, &derSerial); + if (secrv != SECSuccess) { + return PR_FAILURE; + } + issuer->data = derIssuer.data; + issuer->size = derIssuer.len; + serial->data = derSerial.data; + serial->size = derSerial.len; + return PR_SUCCESS; +} + +/* + * Look for a specific cert in the cache + */ +NSS_IMPLEMENT NSSCertificate * +nssTrustDomain_GetCertByDERFromCache ( + NSSTrustDomain *td, + NSSDER *der +) +{ + PRStatus nssrv = PR_FAILURE; + NSSDER issuer, serial; + NSSCertificate *rvCert; + nssrv = issuer_and_serial_from_encoding(der, &issuer, &serial); + if (nssrv != PR_SUCCESS) { + return NULL; + } +#ifdef DEBUG_CACHE + log_item_dump("looking for cert by DER", der); +#endif + rvCert = nssTrustDomain_GetCertForIssuerAndSNFromCache(td, + &issuer, &serial); + PORT_Free(issuer.data); + PORT_Free(serial.data); + return rvCert; +} + +static void cert_iter(const void *k, void *v, void *a) +{ + nssList *certList = (nssList *)a; + NSSCertificate *c = (NSSCertificate *)k; + nssList_Add(certList, nssCertificate_AddRef(c)); +} + +NSS_EXTERN NSSCertificate ** +nssTrustDomain_GetCertsFromCache ( + NSSTrustDomain *td, + nssList *certListOpt +) +{ + NSSCertificate **rvArray = NULL; + nssList *certList; + if (certListOpt) { + certList = certListOpt; + } else { + certList = nssList_Create(NULL, PR_FALSE); + if (!certList) { + return NULL; + } + } + PZ_Lock(td->cache->lock); + nssHash_Iterate(td->cache->issuerAndSN, cert_iter, (void *)certList); + PZ_Unlock(td->cache->lock); + if (!certListOpt) { + PRUint32 count = nssList_Count(certList); + rvArray = nss_ZNEWARRAY(NULL, NSSCertificate *, count); + nssList_GetArray(certList, (void **)rvArray, count); + /* array takes the references */ + nssList_Destroy(certList); + } + return rvArray; +} + +NSS_IMPLEMENT void +nssTrustDomain_DumpCacheInfo ( + NSSTrustDomain *td, + void (* cert_dump_iter)(const void *, void *, void *), + void *arg +) +{ + PZ_Lock(td->cache->lock); + nssHash_Iterate(td->cache->issuerAndSN, cert_dump_iter, arg); + PZ_Unlock(td->cache->lock); +} diff --git a/mozilla/security/nss/lib/pki/trustdomain.c b/mozilla/security/nss/lib/pki/trustdomain.c new file mode 100644 index 0000000..049ee03 --- /dev/null +++ b/mozilla/security/nss/lib/pki/trustdomain.c @@ -0,0 +1,1290 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1994-2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifdef DEBUG +static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.62 $ $Date: 2010/05/21 00:02:48 $"; +#endif /* DEBUG */ + +#ifndef DEV_H +#include "dev.h" +#endif /* DEV_H */ + +#ifndef PKIM_H +#include "pkim.h" +#endif /* PKIM_H */ + +#include "cert.h" +#include "pki3hack.h" +#include "pk11pub.h" +#include "nssrwlk.h" + +#define NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE 32 + +extern const NSSError NSS_ERROR_NOT_FOUND; + +typedef PRUint32 nssUpdateLevel; + +NSS_IMPLEMENT NSSTrustDomain * +NSSTrustDomain_Create ( + NSSUTF8 *moduleOpt, + NSSUTF8 *uriOpt, + NSSUTF8 *opaqueOpt, + void *reserved +) +{ + NSSArena *arena; + NSSTrustDomain *rvTD; + arena = NSSArena_Create(); + if(!arena) { + return (NSSTrustDomain *)NULL; + } + rvTD = nss_ZNEW(arena, NSSTrustDomain); + if (!rvTD) { + goto loser; + } + /* protect the token list and the token iterator */ + rvTD->tokensLock = NSSRWLock_New(100, "tokens"); + if (!rvTD->tokensLock) { + goto loser; + } + nssTrustDomain_InitializeCache(rvTD, NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE); + rvTD->arena = arena; + rvTD->refCount = 1; + rvTD->statusConfig = NULL; + return rvTD; +loser: + if (rvTD && rvTD->tokensLock) { + NSSRWLock_Destroy(rvTD->tokensLock); + } + nssArena_Destroy(arena); + return (NSSTrustDomain *)NULL; +} + +static void +token_destructor(void *t) +{ + NSSToken *tok = (NSSToken *)t; + /* The token holds the first/last reference to the slot. + * When the token is actually destroyed (ref count == 0), + * the slot will also be destroyed. + */ + nssToken_Destroy(tok); +} + +NSS_IMPLEMENT PRStatus +NSSTrustDomain_Destroy ( + NSSTrustDomain *td +) +{ + PRStatus status = PR_SUCCESS; + if (--td->refCount == 0) { + /* Destroy each token in the list of tokens */ + if (td->tokens) { + nssListIterator_Destroy(td->tokens); + td->tokens = NULL; + } + if (td->tokenList) { + nssList_Clear(td->tokenList, token_destructor); + nssList_Destroy(td->tokenList); + td->tokenList = NULL; + } + NSSRWLock_Destroy(td->tokensLock); + td->tokensLock = NULL; + status = nssTrustDomain_DestroyCache(td); + if (status == PR_FAILURE) { + return status; + } + if (td->statusConfig) { + td->statusConfig->statusDestroy(td->statusConfig); + td->statusConfig = NULL; + } + /* Destroy the trust domain */ + nssArena_Destroy(td->arena); + } + return status; +} + +/* XXX uses tokens until slot list is in place */ +static NSSSlot ** +nssTrustDomain_GetActiveSlots ( + NSSTrustDomain *td, + nssUpdateLevel *updateLevel +) +{ + PRUint32 count; + NSSSlot **slots = NULL; + NSSToken **tp, **tokens; + *updateLevel = 1; + NSSRWLock_LockRead(td->tokensLock); + count = nssList_Count(td->tokenList); + tokens = nss_ZNEWARRAY(NULL, NSSToken *, count + 1); + if (!tokens) { + NSSRWLock_UnlockRead(td->tokensLock); + return NULL; + } + slots = nss_ZNEWARRAY(NULL, NSSSlot *, count + 1); + if (!slots) { + NSSRWLock_UnlockRead(td->tokensLock); + nss_ZFreeIf(tokens); + return NULL; + } + nssList_GetArray(td->tokenList, (void **)tokens, count); + NSSRWLock_UnlockRead(td->tokensLock); + count = 0; + for (tp = tokens; *tp; tp++) { + NSSSlot * slot = nssToken_GetSlot(*tp); + if (!PK11_IsDisabled(slot->pk11slot)) { + slots[count++] = slot; + } else { + nssSlot_Destroy(slot); + } + } + nss_ZFreeIf(tokens); + if (!count) { + nss_ZFreeIf(slots); + slots = NULL; + } + return slots; +} + +/* XXX */ +static nssSession * +nssTrustDomain_GetSessionForToken ( + NSSTrustDomain *td, + NSSToken *token +) +{ + return nssToken_GetDefaultSession(token); +} + +NSS_IMPLEMENT PRStatus +NSSTrustDomain_SetDefaultCallback ( + NSSTrustDomain *td, + NSSCallback *newCallback, + NSSCallback **oldCallbackOpt +) +{ + if (oldCallbackOpt) { + *oldCallbackOpt = td->defaultCallback; + } + td->defaultCallback = newCallback; + return PR_SUCCESS; +} + +NSS_IMPLEMENT NSSCallback * +nssTrustDomain_GetDefaultCallback ( + NSSTrustDomain *td, + PRStatus *statusOpt +) +{ + if (statusOpt) { + *statusOpt = PR_SUCCESS; + } + return td->defaultCallback; +} + +NSS_IMPLEMENT NSSCallback * +NSSTrustDomain_GetDefaultCallback ( + NSSTrustDomain *td, + PRStatus *statusOpt +) +{ + return nssTrustDomain_GetDefaultCallback(td, statusOpt); +} + +NSS_IMPLEMENT PRStatus +NSSTrustDomain_LoadModule ( + NSSTrustDomain *td, + NSSUTF8 *moduleOpt, + NSSUTF8 *uriOpt, + NSSUTF8 *opaqueOpt, + void *reserved +) +{ + return PR_FAILURE; +} + +NSS_IMPLEMENT PRStatus +NSSTrustDomain_DisableToken ( + NSSTrustDomain *td, + NSSToken *token, + NSSError why +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT PRStatus +NSSTrustDomain_EnableToken ( + NSSTrustDomain *td, + NSSToken *token +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT PRStatus +NSSTrustDomain_IsTokenEnabled ( + NSSTrustDomain *td, + NSSToken *token, + NSSError *whyOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT NSSSlot * +NSSTrustDomain_FindSlotByName ( + NSSTrustDomain *td, + NSSUTF8 *slotName +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSToken * +NSSTrustDomain_FindTokenByName ( + NSSTrustDomain *td, + NSSUTF8 *tokenName +) +{ + PRStatus nssrv; + NSSUTF8 *myName; + NSSToken *tok = NULL; + NSSRWLock_LockRead(td->tokensLock); + for (tok = (NSSToken *)nssListIterator_Start(td->tokens); + tok != (NSSToken *)NULL; + tok = (NSSToken *)nssListIterator_Next(td->tokens)) + { + if (nssToken_IsPresent(tok)) { + myName = nssToken_GetName(tok); + if (nssUTF8_Equal(tokenName, myName, &nssrv)) break; + } + } + nssListIterator_Finish(td->tokens); + NSSRWLock_UnlockRead(td->tokensLock); + return tok; +} + +NSS_IMPLEMENT NSSToken * +NSSTrustDomain_FindTokenBySlotName ( + NSSTrustDomain *td, + NSSUTF8 *slotName +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSToken * +NSSTrustDomain_FindTokenForAlgorithm ( + NSSTrustDomain *td, + NSSOID *algorithm +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSToken * +NSSTrustDomain_FindBestTokenForAlgorithms ( + NSSTrustDomain *td, + NSSOID *algorithms[], /* may be null-terminated */ + PRUint32 nAlgorithmsOpt /* limits the array if nonzero */ +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT PRStatus +NSSTrustDomain_Login ( + NSSTrustDomain *td, + NSSCallback *uhhOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT PRStatus +NSSTrustDomain_Logout ( + NSSTrustDomain *td +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT NSSCertificate * +NSSTrustDomain_ImportCertificate ( + NSSTrustDomain *td, + NSSCertificate *c +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCertificate * +NSSTrustDomain_ImportPKIXCertificate ( + NSSTrustDomain *td, + /* declared as a struct until these "data types" are defined */ + struct NSSPKIXCertificateStr *pc +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCertificate * +NSSTrustDomain_ImportEncodedCertificate ( + NSSTrustDomain *td, + NSSBER *ber +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCertificate ** +NSSTrustDomain_ImportEncodedCertificateChain ( + NSSTrustDomain *td, + NSSBER *ber, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSPrivateKey * +NSSTrustDomain_ImportEncodedPrivateKey ( + NSSTrustDomain *td, + NSSBER *ber, + NSSItem *passwordOpt, /* NULL will cause a callback */ + NSSCallback *uhhOpt, + NSSToken *destination +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSPublicKey * +NSSTrustDomain_ImportEncodedPublicKey ( + NSSTrustDomain *td, + NSSBER *ber +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +static NSSCertificate ** +get_certs_from_list(nssList *list) +{ + PRUint32 count = nssList_Count(list); + NSSCertificate **certs = NULL; + if (count > 0) { + certs = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1); + if (certs) { + nssList_GetArray(list, (void **)certs, count); + } + } + return certs; +} + +NSS_IMPLEMENT NSSCertificate ** +nssTrustDomain_FindCertificatesByNickname ( + NSSTrustDomain *td, + const NSSUTF8 *name, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +) +{ + NSSToken *token = NULL; + NSSSlot **slots = NULL; + NSSSlot **slotp; + NSSCertificate **rvCerts = NULL; + nssPKIObjectCollection *collection = NULL; + nssUpdateLevel updateLevel; + nssList *nameList; + PRUint32 numRemaining = maximumOpt; + PRUint32 collectionCount = 0; + PRUint32 errors = 0; + + /* First, grab from the cache */ + nameList = nssList_Create(NULL, PR_FALSE); + if (!nameList) { + return NULL; + } + (void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nameList); + rvCerts = get_certs_from_list(nameList); + /* initialize the collection of token certificates with the set of + * cached certs (if any). + */ + collection = nssCertificateCollection_Create(td, rvCerts); + nssCertificateArray_Destroy(rvCerts); + nssList_Destroy(nameList); + if (!collection) { + return (NSSCertificate **)NULL; + } + /* obtain the current set of active slots in the trust domain */ + slots = nssTrustDomain_GetActiveSlots(td, &updateLevel); + if (!slots) { + goto loser; + } + /* iterate over the slots */ + for (slotp = slots; *slotp; slotp++) { + token = nssSlot_GetToken(*slotp); + if (token) { + nssSession *session; + nssCryptokiObject **instances = NULL; + nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; + PRStatus status = PR_FAILURE; + + session = nssTrustDomain_GetSessionForToken(td, token); + if (session) { + instances = nssToken_FindCertificatesByNickname(token, + session, + name, + tokenOnly, + numRemaining, + &status); + } + nssToken_Destroy(token); + if (status != PR_SUCCESS) { + errors++; + continue; + } + if (instances) { + status = nssPKIObjectCollection_AddInstances(collection, + instances, 0); + nss_ZFreeIf(instances); + if (status != PR_SUCCESS) { + errors++; + continue; + } + collectionCount = nssPKIObjectCollection_Count(collection); + if (maximumOpt > 0) { + if (collectionCount >= maximumOpt) + break; + numRemaining = maximumOpt - collectionCount; + } + } + } + } + if (!collectionCount && errors) + goto loser; + /* Grab the certs collected in the search. */ + rvCerts = nssPKIObjectCollection_GetCertificates(collection, + rvOpt, maximumOpt, + arenaOpt); + /* clean up */ + nssPKIObjectCollection_Destroy(collection); + nssSlotArray_Destroy(slots); + return rvCerts; +loser: + if (slots) { + nssSlotArray_Destroy(slots); + } + if (collection) { + nssPKIObjectCollection_Destroy(collection); + } + return (NSSCertificate **)NULL; +} + +NSS_IMPLEMENT NSSCertificate ** +NSSTrustDomain_FindCertificatesByNickname ( + NSSTrustDomain *td, + NSSUTF8 *name, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +) +{ + return nssTrustDomain_FindCertificatesByNickname(td, + name, + rvOpt, + maximumOpt, + arenaOpt); +} + +NSS_IMPLEMENT NSSCertificate * +nssTrustDomain_FindBestCertificateByNickname ( + NSSTrustDomain *td, + const NSSUTF8 *name, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt +) +{ + NSSCertificate **nicknameCerts; + NSSCertificate *rvCert = NULL; + nicknameCerts = nssTrustDomain_FindCertificatesByNickname(td, name, + NULL, + 0, + NULL); + if (nicknameCerts) { + rvCert = nssCertificateArray_FindBestCertificate(nicknameCerts, + timeOpt, + usage, + policiesOpt); + nssCertificateArray_Destroy(nicknameCerts); + } + return rvCert; +} + +NSS_IMPLEMENT NSSCertificate * +NSSTrustDomain_FindBestCertificateByNickname ( + NSSTrustDomain *td, + const NSSUTF8 *name, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt +) +{ + return nssTrustDomain_FindBestCertificateByNickname(td, + name, + timeOpt, + usage, + policiesOpt); +} + +NSS_IMPLEMENT NSSCertificate ** +nssTrustDomain_FindCertificatesBySubject ( + NSSTrustDomain *td, + NSSDER *subject, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +) +{ + NSSToken *token = NULL; + NSSSlot **slots = NULL; + NSSSlot **slotp; + NSSCertificate **rvCerts = NULL; + nssPKIObjectCollection *collection = NULL; + nssUpdateLevel updateLevel; + nssList *subjectList; + PRUint32 numRemaining = maximumOpt; + PRUint32 collectionCount = 0; + PRUint32 errors = 0; + + /* look in cache */ + subjectList = nssList_Create(NULL, PR_FALSE); + if (!subjectList) { + return NULL; + } + (void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList); + rvCerts = get_certs_from_list(subjectList); + collection = nssCertificateCollection_Create(td, rvCerts); + nssCertificateArray_Destroy(rvCerts); + nssList_Destroy(subjectList); + if (!collection) { + return (NSSCertificate **)NULL; + } + slots = nssTrustDomain_GetActiveSlots(td, &updateLevel); + if (!slots) { + goto loser; + } + for (slotp = slots; *slotp; slotp++) { + token = nssSlot_GetToken(*slotp); + if (token) { + nssSession *session; + nssCryptokiObject **instances = NULL; + nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; + PRStatus status = PR_FAILURE; + + session = nssTrustDomain_GetSessionForToken(td, token); + if (session) { + instances = nssToken_FindCertificatesBySubject(token, + session, + subject, + tokenOnly, + numRemaining, + &status); + } + nssToken_Destroy(token); + if (status != PR_SUCCESS) { + errors++; + continue; + } + if (instances) { + status = nssPKIObjectCollection_AddInstances(collection, + instances, 0); + nss_ZFreeIf(instances); + if (status != PR_SUCCESS) { + errors++; + continue; + } + collectionCount = nssPKIObjectCollection_Count(collection); + if (maximumOpt > 0) { + if (collectionCount >= maximumOpt) + break; + numRemaining = maximumOpt - collectionCount; + } + } + } + } + if (!collectionCount && errors) + goto loser; + rvCerts = nssPKIObjectCollection_GetCertificates(collection, + rvOpt, maximumOpt, + arenaOpt); + nssPKIObjectCollection_Destroy(collection); + nssSlotArray_Destroy(slots); + return rvCerts; +loser: + if (slots) { + nssSlotArray_Destroy(slots); + } + if (collection) { + nssPKIObjectCollection_Destroy(collection); + } + return (NSSCertificate **)NULL; +} + +NSS_IMPLEMENT NSSCertificate ** +NSSTrustDomain_FindCertificatesBySubject ( + NSSTrustDomain *td, + NSSDER *subject, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, + NSSArena *arenaOpt +) +{ + return nssTrustDomain_FindCertificatesBySubject(td, + subject, + rvOpt, + maximumOpt, + arenaOpt); +} + +NSS_IMPLEMENT NSSCertificate * +nssTrustDomain_FindBestCertificateBySubject ( + NSSTrustDomain *td, + NSSDER *subject, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt +) +{ + NSSCertificate **subjectCerts; + NSSCertificate *rvCert = NULL; + subjectCerts = nssTrustDomain_FindCertificatesBySubject(td, subject, + NULL, + 0, + NULL); + if (subjectCerts) { + rvCert = nssCertificateArray_FindBestCertificate(subjectCerts, + timeOpt, + usage, + policiesOpt); + nssCertificateArray_Destroy(subjectCerts); + } + return rvCert; +} + +NSS_IMPLEMENT NSSCertificate * +NSSTrustDomain_FindBestCertificateBySubject ( + NSSTrustDomain *td, + NSSDER *subject, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt +) +{ + return nssTrustDomain_FindBestCertificateBySubject(td, + subject, + timeOpt, + usage, + policiesOpt); +} + +NSS_IMPLEMENT NSSCertificate * +NSSTrustDomain_FindBestCertificateByNameComponents ( + NSSTrustDomain *td, + NSSUTF8 *nameComponents, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCertificate ** +NSSTrustDomain_FindCertificatesByNameComponents ( + NSSTrustDomain *td, + NSSUTF8 *nameComponents, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +/* This returns at most a single certificate, so it can stop the loop + * when one is found. + */ +NSS_IMPLEMENT NSSCertificate * +nssTrustDomain_FindCertificateByIssuerAndSerialNumber ( + NSSTrustDomain *td, + NSSDER *issuer, + NSSDER *serial +) +{ + NSSSlot **slots = NULL; + NSSSlot **slotp; + NSSCertificate *rvCert = NULL; + nssPKIObjectCollection *collection = NULL; + nssUpdateLevel updateLevel; + + /* see if this search is already cached */ + rvCert = nssTrustDomain_GetCertForIssuerAndSNFromCache(td, + issuer, + serial); + if (rvCert) { + return rvCert; + } + slots = nssTrustDomain_GetActiveSlots(td, &updateLevel); + if (slots) { + for (slotp = slots; *slotp; slotp++) { + NSSToken *token = nssSlot_GetToken(*slotp); + nssSession *session; + nssCryptokiObject *instance; + nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; + PRStatus status = PR_FAILURE; + + if (!token) + continue; + session = nssTrustDomain_GetSessionForToken(td, token); + if (session) { + instance = nssToken_FindCertificateByIssuerAndSerialNumber( + token, + session, + issuer, + serial, + tokenOnly, + &status); + } + nssToken_Destroy(token); + if (status != PR_SUCCESS) { + continue; + } + if (instance) { + if (!collection) { + collection = nssCertificateCollection_Create(td, NULL); + if (!collection) { + break; /* don't keep looping if out if memory */ + } + } + status = nssPKIObjectCollection_AddInstances(collection, + &instance, 1); + if (status == PR_SUCCESS) { + (void)nssPKIObjectCollection_GetCertificates( + collection, &rvCert, 1, NULL); + } + if (rvCert) { + break; /* found one cert, all done */ + } + } + } + } + if (collection) { + nssPKIObjectCollection_Destroy(collection); + } + if (slots) { + nssSlotArray_Destroy(slots); + } + return rvCert; +} + +NSS_IMPLEMENT NSSCertificate * +NSSTrustDomain_FindCertificateByIssuerAndSerialNumber ( + NSSTrustDomain *td, + NSSDER *issuer, + NSSDER *serial +) +{ + return nssTrustDomain_FindCertificateByIssuerAndSerialNumber(td, + issuer, + serial); +} + +NSS_IMPLEMENT NSSCertificate * +nssTrustDomain_FindCertificateByEncodedCertificate ( + NSSTrustDomain *td, + NSSBER *ber +) +{ + PRStatus status; + NSSCertificate *rvCert = NULL; + NSSDER issuer = { 0 }; + NSSDER serial = { 0 }; + NSSArena *arena = nssArena_Create(); + if (!arena) { + return (NSSCertificate *)NULL; + } + /* XXX this is not generic... will any cert crack into issuer/serial? */ + status = nssPKIX509_GetIssuerAndSerialFromDER(ber, arena, &issuer, &serial); + if (status != PR_SUCCESS) { + goto finish; + } + rvCert = nssTrustDomain_FindCertificateByIssuerAndSerialNumber(td, + &issuer, + &serial); +finish: + nssArena_Destroy(arena); + return rvCert; +} + +NSS_IMPLEMENT NSSCertificate * +NSSTrustDomain_FindCertificateByEncodedCertificate ( + NSSTrustDomain *td, + NSSBER *ber +) +{ + return nssTrustDomain_FindCertificateByEncodedCertificate(td, ber); +} + +NSS_IMPLEMENT NSSCertificate * +NSSTrustDomain_FindBestCertificateByEmail ( + NSSTrustDomain *td, + NSSASCII7 *email, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt +) +{ + return 0; +} + +NSS_IMPLEMENT NSSCertificate ** +NSSTrustDomain_FindCertificatesByEmail ( + NSSTrustDomain *td, + NSSASCII7 *email, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCertificate * +NSSTrustDomain_FindCertificateByOCSPHash ( + NSSTrustDomain *td, + NSSItem *hash +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCertificate * +NSSTrustDomain_FindBestUserCertificate ( + NSSTrustDomain *td, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCertificate ** +NSSTrustDomain_FindUserCertificates ( + NSSTrustDomain *td, + NSSTime *timeOpt, + NSSUsage *usageOpt, + NSSPolicies *policiesOpt, + NSSCertificate **rvOpt, + PRUint32 rvLimit, /* zero for no limit */ + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCertificate * +NSSTrustDomain_FindBestUserCertificateForSSLClientAuth ( + NSSTrustDomain *td, + NSSUTF8 *sslHostOpt, + NSSDER *rootCAsOpt[], /* null pointer for none */ + PRUint32 rootCAsMaxOpt, /* zero means list is null-terminated */ + NSSAlgorithmAndParameters *apOpt, + NSSPolicies *policiesOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCertificate ** +NSSTrustDomain_FindUserCertificatesForSSLClientAuth ( + NSSTrustDomain *td, + NSSUTF8 *sslHostOpt, + NSSDER *rootCAsOpt[], /* null pointer for none */ + PRUint32 rootCAsMaxOpt, /* zero means list is null-terminated */ + NSSAlgorithmAndParameters *apOpt, + NSSPolicies *policiesOpt, + NSSCertificate **rvOpt, + PRUint32 rvLimit, /* zero for no limit */ + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCertificate * +NSSTrustDomain_FindBestUserCertificateForEmailSigning ( + NSSTrustDomain *td, + NSSASCII7 *signerOpt, + NSSASCII7 *recipientOpt, + /* anything more here? */ + NSSAlgorithmAndParameters *apOpt, + NSSPolicies *policiesOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCertificate ** +NSSTrustDomain_FindUserCertificatesForEmailSigning ( + NSSTrustDomain *td, + NSSASCII7 *signerOpt, + NSSASCII7 *recipientOpt, + /* anything more here? */ + NSSAlgorithmAndParameters *apOpt, + NSSPolicies *policiesOpt, + NSSCertificate **rvOpt, + PRUint32 rvLimit, /* zero for no limit */ + NSSArena *arenaOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +static PRStatus +collector(nssCryptokiObject *instance, void *arg) +{ + nssPKIObjectCollection *collection = (nssPKIObjectCollection *)arg; + return nssPKIObjectCollection_AddInstanceAsObject(collection, instance); +} + +NSS_IMPLEMENT PRStatus * +NSSTrustDomain_TraverseCertificates ( + NSSTrustDomain *td, + PRStatus (*callback)(NSSCertificate *c, void *arg), + void *arg +) +{ + PRStatus status = PR_FAILURE; + NSSToken *token = NULL; + NSSSlot **slots = NULL; + NSSSlot **slotp; + nssPKIObjectCollection *collection = NULL; + nssPKIObjectCallback pkiCallback; + nssUpdateLevel updateLevel; + NSSCertificate **cached = NULL; + nssList *certList; + + certList = nssList_Create(NULL, PR_FALSE); + if (!certList) + return NULL; + (void)nssTrustDomain_GetCertsFromCache(td, certList); + cached = get_certs_from_list(certList); + collection = nssCertificateCollection_Create(td, cached); + nssCertificateArray_Destroy(cached); + nssList_Destroy(certList); + if (!collection) { + return (PRStatus *)NULL; + } + /* obtain the current set of active slots in the trust domain */ + slots = nssTrustDomain_GetActiveSlots(td, &updateLevel); + if (!slots) { + goto loser; + } + /* iterate over the slots */ + for (slotp = slots; *slotp; slotp++) { + /* get the token for the slot, if present */ + token = nssSlot_GetToken(*slotp); + if (token) { + nssSession *session; + nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; + /* get a session for the token */ + session = nssTrustDomain_GetSessionForToken(td, token); + if (session) { + /* perform the traversal */ + status = nssToken_TraverseCertificates(token, + session, + tokenOnly, + collector, + collection); + } + nssToken_Destroy(token); + } + } + + /* Traverse the collection */ + pkiCallback.func.cert = callback; + pkiCallback.arg = arg; + status = nssPKIObjectCollection_Traverse(collection, &pkiCallback); +loser: + if (slots) { + nssSlotArray_Destroy(slots); + } + if (collection) { + nssPKIObjectCollection_Destroy(collection); + } + return NULL; +} + + +NSS_IMPLEMENT NSSTrust * +nssTrustDomain_FindTrustForCertificate ( + NSSTrustDomain *td, + NSSCertificate *c +) +{ + NSSSlot **slots; + NSSSlot **slotp; + nssCryptokiObject *to = NULL; + nssPKIObject *pkio = NULL; + NSSTrust *rvt = NULL; + nssUpdateLevel updateLevel; + slots = nssTrustDomain_GetActiveSlots(td, &updateLevel); + if (!slots) { + return (NSSTrust *)NULL; + } + for (slotp = slots; *slotp; slotp++) { + NSSToken *token = nssSlot_GetToken(*slotp); + + if (token) { + to = nssToken_FindTrustForCertificate(token, NULL, + &c->encoding, + &c->issuer, + &c->serial, + nssTokenSearchType_TokenOnly); + if (to) { + PRStatus status; + if (!pkio) { + pkio = nssPKIObject_Create(NULL, to, td, NULL, nssPKILock); + status = pkio ? PR_SUCCESS : PR_FAILURE; + } else { + status = nssPKIObject_AddInstance(pkio, to); + } + if (status != PR_SUCCESS) { + nssCryptokiObject_Destroy(to); + } + } + nssToken_Destroy(token); + } + } + if (pkio) { + rvt = nssTrust_Create(pkio, &c->encoding); + if (rvt) { + pkio = NULL; /* rvt object now owns the pkio reference */ + } + } + nssSlotArray_Destroy(slots); + if (pkio) { + nssPKIObject_Destroy(pkio); + } + return rvt; +} + +NSS_IMPLEMENT NSSCRL ** +nssTrustDomain_FindCRLsBySubject ( + NSSTrustDomain *td, + NSSDER *subject +) +{ + NSSSlot **slots; + NSSSlot **slotp; + NSSToken *token; + nssUpdateLevel updateLevel; + nssPKIObjectCollection *collection; + NSSCRL **rvCRLs = NULL; + collection = nssCRLCollection_Create(td, NULL); + if (!collection) { + return (NSSCRL **)NULL; + } + slots = nssTrustDomain_GetActiveSlots(td, &updateLevel); + if (!slots) { + goto loser; + } + for (slotp = slots; *slotp; slotp++) { + token = nssSlot_GetToken(*slotp); + if (token) { + PRStatus status = PR_FAILURE; + nssSession *session; + nssCryptokiObject **instances = NULL; + nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; + + /* get a session for the token */ + session = nssTrustDomain_GetSessionForToken(td, token); + if (session) { + /* perform the traversal */ + instances = nssToken_FindCRLsBySubject(token, session, subject, + tokenOnly, 0, &status); + } + nssToken_Destroy(token); + if (status == PR_SUCCESS) { + /* add the found CRL's to the collection */ + status = nssPKIObjectCollection_AddInstances(collection, + instances, 0); + } + nss_ZFreeIf(instances); + } + } + rvCRLs = nssPKIObjectCollection_GetCRLs(collection, NULL, 0, NULL); +loser: + nssPKIObjectCollection_Destroy(collection); + nssSlotArray_Destroy(slots); + return rvCRLs; +} + +NSS_IMPLEMENT PRStatus +NSSTrustDomain_GenerateKeyPair ( + NSSTrustDomain *td, + NSSAlgorithmAndParameters *ap, + NSSPrivateKey **pvkOpt, + NSSPublicKey **pbkOpt, + PRBool privateKeyIsSensitive, + NSSToken *destination, + NSSCallback *uhhOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return PR_FAILURE; +} + +NSS_IMPLEMENT NSSSymmetricKey * +NSSTrustDomain_GenerateSymmetricKey ( + NSSTrustDomain *td, + NSSAlgorithmAndParameters *ap, + PRUint32 keysize, + NSSToken *destination, + NSSCallback *uhhOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSSymmetricKey * +NSSTrustDomain_GenerateSymmetricKeyFromPassword ( + NSSTrustDomain *td, + NSSAlgorithmAndParameters *ap, + NSSUTF8 *passwordOpt, /* if null, prompt */ + NSSToken *destinationOpt, + NSSCallback *uhhOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSSymmetricKey * +NSSTrustDomain_FindSymmetricKeyByAlgorithmAndKeyID ( + NSSTrustDomain *td, + NSSOID *algorithm, + NSSItem *keyID, + NSSCallback *uhhOpt +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCryptoContext * +nssTrustDomain_CreateCryptoContext ( + NSSTrustDomain *td, + NSSCallback *uhhOpt +) +{ + return nssCryptoContext_Create(td, uhhOpt); +} + +NSS_IMPLEMENT NSSCryptoContext * +NSSTrustDomain_CreateCryptoContext ( + NSSTrustDomain *td, + NSSCallback *uhhOpt +) +{ + return nssTrustDomain_CreateCryptoContext(td, uhhOpt); +} + +NSS_IMPLEMENT NSSCryptoContext * +NSSTrustDomain_CreateCryptoContextForAlgorithm ( + NSSTrustDomain *td, + NSSOID *algorithm +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + +NSS_IMPLEMENT NSSCryptoContext * +NSSTrustDomain_CreateCryptoContextForAlgorithmAndParameters ( + NSSTrustDomain *td, + NSSAlgorithmAndParameters *ap +) +{ + nss_SetError(NSS_ERROR_NOT_FOUND); + return NULL; +} + |