summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorian.mcgreer%sun.com <devnull@localhost>2003-02-28 20:18:36 +0000
committerian.mcgreer%sun.com <devnull@localhost>2003-02-28 20:18:36 +0000
commit66a2bc68e203a5e56e823fd02578cd586f495e5f (patch)
tree1a675b06bd160932a52c8b95f2b1425f05dedacb
parent64950c885de2409fea47c291bba2126330f15a0e (diff)
downloadnss-hg-66a2bc68e203a5e56e823fd02578cd586f495e5f.tar.gz
implement pki object table and above-PKCS#11 db
-rw-r--r--security/nss/cmd/pkiutil/pkiobject.c9
-rw-r--r--security/nss/cmd/selfserv/selfserv.c2
-rw-r--r--security/nss/cmd/strsclnt/strsclnt.c2
-rw-r--r--security/nss/lib/base/baset.h19
-rw-r--r--security/nss/lib/ckfw/nsprstub.c2
-rw-r--r--security/nss/lib/dev/algparam.c6
-rw-r--r--security/nss/lib/dev/ckhelper.c74
-rw-r--r--security/nss/lib/dev/dev.h91
-rw-r--r--security/nss/lib/dev/devt.h16
-rw-r--r--security/nss/lib/dev/devtoken.c224
-rw-r--r--security/nss/lib/nss/config.mk4
-rw-r--r--security/nss/lib/nss/nssinit.c6
-rw-r--r--security/nss/lib/pki/asymmkey.c213
-rw-r--r--security/nss/lib/pki/cert.c576
-rw-r--r--security/nss/lib/pki/cryptocontext.c6
-rw-r--r--security/nss/lib/pki/manifest.mn5
-rw-r--r--security/nss/lib/pki/pki.h86
-rw-r--r--security/nss/lib/pki/pkibase.c991
-rw-r--r--security/nss/lib/pki/pkidb.c924
-rw-r--r--security/nss/lib/pki/pkim.h444
-rw-r--r--security/nss/lib/pki/pkistore.c412
-rw-r--r--security/nss/lib/pki/pkit.h2
-rw-r--r--security/nss/lib/pki/pkitm.h78
-rw-r--r--security/nss/lib/pki/symkey.c52
-rw-r--r--security/nss/lib/pki/trustdomain.c447
-rw-r--r--security/nss/lib/pki/volatiledomain.c15
-rw-r--r--security/nss/lib/ssl/authcert.c2
-rw-r--r--security/nss/tests/stan/stan.sh2
28 files changed, 2310 insertions, 2400 deletions
diff --git a/security/nss/cmd/pkiutil/pkiobject.c b/security/nss/cmd/pkiutil/pkiobject.c
index b9e8f3016..b19d60c3f 100644
--- a/security/nss/cmd/pkiutil/pkiobject.c
+++ b/security/nss/cmd/pkiutil/pkiobject.c
@@ -723,21 +723,18 @@ ImportObject
{
PRStatus status;
PKIObjectType objectKind;
- NSSToken *token;
-
- /* XXX */
- token = tokenOpt ? tokenOpt : nss_GetDefaultDatabaseToken();
objectKind = get_object_class(objectTypeOpt);
switch (objectKind) {
case PKIAny: /* default to certificate */
case PKICert:
- status = import_certificate(td, token, nickname, rtData);
+ status = import_certificate(td, tokenOpt, nickname, rtData);
break;
case PKIPublicKey:
break;
case PKIPrivateKey:
- status = import_private_key(td, token, nickname, keyTypeOpt,
+ tokenOpt = tokenOpt ? tokenOpt : nss_GetDefaultDatabaseToken();
+ status = import_private_key(td, tokenOpt, nickname, keyTypeOpt,
keypass, rtData);
break;
case PKIUnknown:
diff --git a/security/nss/cmd/selfserv/selfserv.c b/security/nss/cmd/selfserv/selfserv.c
index d5034cd0b..34c128168 100644
--- a/security/nss/cmd/selfserv/selfserv.c
+++ b/security/nss/cmd/selfserv/selfserv.c
@@ -1674,6 +1674,8 @@ main(int argc, char **argv)
fprintf(stderr, "selfserv: Can't find certificate %s\n", nickName);
exit(10);
}
+ /* XXX */
+ NSSTrustDomain_Login(td, NULL);
privKey[ssl_kea_rsa] = NSSCert_FindPrivateKey(cert[ssl_kea_rsa], NULL);
if (privKey[ssl_kea_rsa] == NULL) {
fprintf(stderr, "selfserv: Can't find Private Key for cert %s\n",
diff --git a/security/nss/cmd/strsclnt/strsclnt.c b/security/nss/cmd/strsclnt/strsclnt.c
index 014dbaafb..29de449db 100644
--- a/security/nss/cmd/strsclnt/strsclnt.c
+++ b/security/nss/cmd/strsclnt/strsclnt.c
@@ -1067,6 +1067,8 @@ main(int argc, char **argv)
exit(1);
}
+ /* XXX */
+ NSSTrustDomain_Login(td, NULL);
privKey[ssl_kea_rsa] = NSSCert_FindPrivateKey(cert[ssl_kea_rsa], NULL);
if (privKey[ssl_kea_rsa] == NULL) {
fprintf(stderr, "strsclnt: Can't find Private Key for cert %s\n",
diff --git a/security/nss/lib/base/baset.h b/security/nss/lib/base/baset.h
index 4fe186c0d..65a6988e9 100644
--- a/security/nss/lib/base/baset.h
+++ b/security/nss/lib/base/baset.h
@@ -106,25 +106,6 @@ typedef void (PR_CALLBACK *nssHashIterator)(const void *key,
void *arg);
/*
- * nssPointerTracker
- *
- * This type is used in debug builds (both external and internal) to
- * track our object pointers. Objects of this type must be statically
- * allocated, which means the structure size must be available to the
- * compiler. Therefore we must expose the contents of this structure.
- * But please don't access elements directly; use the accessors.
- */
-
-#ifdef DEBUG
-struct nssPointerTrackerStr {
- PRCallOnceType once;
- PZLock *lock;
- PLHashTable *table;
-};
-typedef struct nssPointerTrackerStr nssPointerTracker;
-#endif /* DEBUG */
-
-/*
* nssStringType
*
* There are several types of strings in the real world. We try to
diff --git a/security/nss/lib/ckfw/nsprstub.c b/security/nss/lib/ckfw/nsprstub.c
index 24ecd507a..110c990d3 100644
--- a/security/nss/lib/ckfw/nsprstub.c
+++ b/security/nss/lib/ckfw/nsprstub.c
@@ -255,8 +255,6 @@ PR_GetCurrentThread(void)
return (PRThread *)1;
}
-
-
PR_IMPLEMENT(void)
PR_Assert(const char *expr, const char *file, int line) {
return;
diff --git a/security/nss/lib/dev/algparam.c b/security/nss/lib/dev/algparam.c
index 50f9bb583..452f66a01 100644
--- a/security/nss/lib/dev/algparam.c
+++ b/security/nss/lib/dev/algparam.c
@@ -182,6 +182,7 @@ null_settor (
* Decoding IV parameters
*/
+/* XXX
static PRStatus
decode_iv(NSSAlgNParam *ap, const NSSItem *params)
{
@@ -196,6 +197,7 @@ decode_iv(NSSAlgNParam *ap, const NSSItem *params)
}
return status;
}
+*/
/*
* RSA key generation
@@ -303,6 +305,7 @@ set_dsa_mechanism (
*/
/* set template parameters for Diffie-Hellman key generation */
+#if 0
static PRIntn
dh_keygen_settor (
const NSSAlgNParam *ap,
@@ -325,6 +328,7 @@ dh_keygen_settor (
}
return attr - aTemplate;
}
+#endif
/*
* Diffie-Hellman key derivation
@@ -428,6 +432,7 @@ set_des3_mechanism (
return PR_SUCCESS;
}
+#if 0
/*
* AES
*/
@@ -464,6 +469,7 @@ set_aes_mechanism (
}
return PR_SUCCESS;
}
+#endif
/*
* RC2
diff --git a/security/nss/lib/dev/ckhelper.c b/security/nss/lib/dev/ckhelper.c
index 6288c2ea5..b14187dbc 100644
--- a/security/nss/lib/dev/ckhelper.c
+++ b/security/nss/lib/dev/ckhelper.c
@@ -386,8 +386,7 @@ nssCryptokiCert_GetAttributes (
NSSDER *encodingOpt,
NSSDER *issuerOpt,
NSSDER *serialOpt,
- NSSDER *subjectOpt,
- NSSASCII7 **emailOpt
+ NSSDER *subjectOpt
)
{
PRStatus status;
@@ -417,9 +416,6 @@ nssCryptokiCert_GetAttributes (
if (subjectOpt) {
NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SUBJECT);
}
- if (emailOpt) {
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NETSCAPE_EMAIL);
- }
NSS_CK_TEMPLATE_FINISH(cert_template, attr, template_size);
if (template_size == 0) {
/* caller didn't want anything */
@@ -457,9 +453,6 @@ nssCryptokiCert_GetAttributes (
if (subjectOpt) {
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], subjectOpt); i++;
}
- if (emailOpt) {
- NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[i], *emailOpt); i++;
- }
return PR_SUCCESS;
}
@@ -624,71 +617,6 @@ nssCryptokiPublicKey_GetAttributes (
return status;
}
-static nssTrustLevel
-get_nss_trust (
- CK_TRUST ckt
-)
-{
- nssTrustLevel t;
- switch (ckt) {
- case CKT_NETSCAPE_UNTRUSTED: t = nssTrustLevel_NotTrusted; break;
- case CKT_NETSCAPE_TRUSTED_DELEGATOR: t = nssTrustLevel_TrustedDelegator;
- break;
- case CKT_NETSCAPE_VALID_DELEGATOR: t = nssTrustLevel_ValidDelegator; break;
- case CKT_NETSCAPE_TRUSTED: t = nssTrustLevel_Trusted; break;
- case CKT_NETSCAPE_VALID: t = nssTrustLevel_Valid; break;
- case CKT_NETSCAPE_MUST_VERIFY:
- case CKT_NETSCAPE_TRUST_UNKNOWN:
- default:
- t = nssTrustLevel_Unknown; break;
- }
- return t;
-}
-
-NSS_IMPLEMENT PRStatus
-nssCryptokiTrust_GetAttributes (
- nssCryptokiObject *trustObject,
- nssTrustLevel *serverAuth,
- nssTrustLevel *clientAuth,
- nssTrustLevel *codeSigning,
- nssTrustLevel *emailProtection
-)
-{
- PRStatus status;
- NSSSlot *slot;
- CK_BBOOL isToken;
- CK_TRUST saTrust, caTrust, epTrust, csTrust;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE trust_template[5];
- CK_ULONG trust_size;
-
- /* Use the trust object to find the trust settings */
- NSS_CK_TEMPLATE_START(trust_template, attr, trust_size);
- NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TOKEN, isToken);
- NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_SERVER_AUTH, saTrust);
- NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CLIENT_AUTH, caTrust);
- NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_EMAIL_PROTECTION, epTrust);
- NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, csTrust);
- NSS_CK_TEMPLATE_FINISH(trust_template, attr, trust_size);
-
- {
- slot = nssToken_GetSlot(trustObject->token);
- status = nssCKObject_GetAttributes(trustObject->handle,
- trust_template, trust_size,
- NULL, trustObject->session, slot);
- nssSlot_Destroy(slot);
- if (status != PR_SUCCESS) {
- return status;
- }
- }
-
- *serverAuth = get_nss_trust(saTrust);
- *clientAuth = get_nss_trust(caTrust);
- *emailProtection = get_nss_trust(epTrust);
- *codeSigning = get_nss_trust(csTrust);
- return PR_SUCCESS;
-}
-
NSS_IMPLEMENT PRStatus
nssCryptokiCRL_GetAttributes (
nssCryptokiObject *crlObject,
diff --git a/security/nss/lib/dev/dev.h b/security/nss/lib/dev/dev.h
index b4888012b..7580f7718 100644
--- a/security/nss/lib/dev/dev.h
+++ b/security/nss/lib/dev/dev.h
@@ -302,19 +302,15 @@ nssSlot_CreateSession (
* nssToken_ImportCert
* nssToken_FindCerts
*
- * ------ trust objects --------
- * nssToken_ImportTrust
- * nssToken_FindTrustObjects
- * nssToken_FindTrustForCert
- *
* ------ public/private key objects --------
* nssToken_GenerateKeyPair
* nssToken_FindPrivateKeys
- * nssToken_FindPrivateKeyByID
- * nssToken_FindPublicKeyByID
+ * nssToken_FindPublicKeys
*
* ------ secret key objects --------
+ * nssToken_ImportRawSymKey
* nssToken_GenerateSymKey
+ * nssToken_FindSymKeys
*
* ------ generic key stuff -------
* nssToken_UnwrapPrivateKey
@@ -420,44 +416,10 @@ NSS_EXTERN nssCryptokiObject **
nssToken_FindCerts (
NSSToken *token,
nssSession *session,
- nssTokenSearchType searchType,
PRUint32 maximumOpt,
PRStatus *statusOpt
);
-NSS_EXTERN nssCryptokiObject *
-nssToken_ImportTrust (
- NSSToken *tok,
- nssSession *session,
- NSSDER *certEncoding,
- NSSDER *certIssuer,
- NSSDER *certSerial,
- nssTrustLevel serverAuth,
- nssTrustLevel clientAuth,
- nssTrustLevel codeSigning,
- nssTrustLevel emailProtection,
- PRBool asTokenObject
-);
-
-NSS_EXTERN nssCryptokiObject **
-nssToken_FindTrustObjects (
- NSSToken *token,
- nssSession *session,
- nssTokenSearchType searchType,
- PRUint32 maximumOpt,
- PRStatus *statusOpt
-);
-
-NSS_EXTERN nssCryptokiObject *
-nssToken_FindTrustForCert (
- NSSToken *token,
- nssSession *session,
- NSSDER *certEncoding,
- NSSDER *certIssuer,
- NSSDER *certSerial,
- nssTokenSearchType searchType
-);
-
NSS_EXTERN PRStatus
nssToken_GenerateKeyPair (
NSSToken *tok,
@@ -480,26 +442,19 @@ nssToken_ImportPublicKey (
);
NSS_EXTERN nssCryptokiObject **
-nssToken_FindPrivateKeys (
+nssToken_FindPublicKeys (
NSSToken *token,
nssSession *session,
- nssTokenSearchType searchType,
PRUint32 maximumOpt,
PRStatus *statusOpt
);
-NSS_EXTERN nssCryptokiObject *
-nssToken_FindPrivateKeyByID (
- NSSToken *token,
- nssSession *session,
- NSSItem *keyID
-);
-
-NSS_EXTERN nssCryptokiObject *
-nssToken_FindPublicKeyByID (
+NSS_EXTERN nssCryptokiObject **
+nssToken_FindPrivateKeys (
NSSToken *token,
nssSession *session,
- NSSItem *keyID
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
);
NSS_EXTERN nssCryptokiObject *
@@ -514,6 +469,14 @@ nssToken_GenerateSymKey (
NSSProperties properties
);
+NSS_EXTERN nssCryptokiObject **
+nssToken_FindSymKeys (
+ NSSToken *token,
+ nssSession *session,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
+);
+
NSS_EXTERN nssCryptokiObject *
nssToken_ImportRawSymKey (
NSSToken *token,
@@ -934,7 +897,6 @@ nssSession_Clone (
* nssCryptokiCert_GetAttributes
* nssCryptokiPrivateKey_GetAttributes
* nssCryptokiPublicKey_GetAttributes
- * nssCryptokiTrust_GetAttributes
* nssCryptokiCRL_GetAttributes
* nssCryptokiSymKey_GetAttributes
*/
@@ -989,8 +951,7 @@ nssCryptokiCert_GetAttributes (
NSSDER *encodingOpt,
NSSDER *issuerOpt,
NSSDER *serialOpt,
- NSSDER *subjectOpt,
- NSSASCII7 **emailOpt
+ NSSDER *subjectOpt
);
NSS_EXTERN PRStatus
@@ -1010,15 +971,6 @@ nssCryptokiPublicKey_GetAttributes (
);
NSS_EXTERN PRStatus
-nssCryptokiTrust_GetAttributes (
- nssCryptokiObject *trustObject,
- nssTrustLevel *serverAuth,
- nssTrustLevel *clientAuth,
- nssTrustLevel *codeSigning,
- nssTrustLevel *emailProtection
-);
-
-NSS_EXTERN PRStatus
nssCryptokiCRL_GetAttributes (
nssCryptokiObject *crlObject,
NSSArena *arenaOpt,
@@ -1215,15 +1167,6 @@ nssSlotList_GetBestTokenForAlgorithm (
NSSOIDTag alg
);
-NSS_EXTERN PRStatus
-nssToken_TraverseCerts (
- NSSToken *token,
- nssSession *session,
- nssTokenSearchType searchType,
- PRStatus (* callback)(nssCryptokiObject *instance, void *arg),
- void *arg
-);
-
PR_END_EXTERN_C
#endif /* DEV_H */
diff --git a/security/nss/lib/dev/devt.h b/security/nss/lib/dev/devt.h
index b8d23c574..73f27fde7 100644
--- a/security/nss/lib/dev/devt.h
+++ b/security/nss/lib/dev/devt.h
@@ -81,22 +81,6 @@ typedef struct nssSessionStr nssSession;
typedef struct nssSlotListStr nssSlotList;
-typedef enum {
- nssTrustLevel_Unknown = 0,
- nssTrustLevel_NotTrusted = 1,
- nssTrustLevel_Trusted = 2,
- nssTrustLevel_TrustedDelegator = 3,
- nssTrustLevel_Valid = 4,
- nssTrustLevel_ValidDelegator = 5
-} nssTrustLevel;
-
-typedef enum {
- nssTokenSearchType_AllObjects = 0,
- nssTokenSearchType_SessionOnly = 1,
- nssTokenSearchType_TokenOnly = 2,
- nssTokenSearchType_PrivateTokenOnly = 3
-} nssTokenSearchType;
-
struct nssCryptokiObjectStr
{
CK_OBJECT_HANDLE handle;
diff --git a/security/nss/lib/dev/devtoken.c b/security/nss/lib/dev/devtoken.c
index 9bc13519b..0ac665195 100644
--- a/security/nss/lib/dev/devtoken.c
+++ b/security/nss/lib/dev/devtoken.c
@@ -47,6 +47,10 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#include "ckhelper.h"
#endif /* CKHELPER_H */
+#ifndef PKI1_H
+#include "pki1.h"
+#endif /* PKI1_H */
+
/* The number of object handles to grab during each call to C_FindObjects */
#define OBJECT_STACK_SIZE 16
@@ -550,7 +554,6 @@ nssToken_ImportCert (
CK_ATTRIBUTE_PTR attr;
CK_ATTRIBUTE cert_tmpl[10];
CK_ULONG ctsize;
- nssTokenSearchType searchType;
nssCryptokiObject *rvObject = NULL, **objs;
if (certType == NSSCertType_PKIX) {
@@ -561,10 +564,8 @@ nssToken_ImportCert (
NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize);
if (asTokenObject) {
NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- searchType = nssTokenSearchType_TokenOnly;
} else {
NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
- searchType = nssTokenSearchType_SessionOnly;
}
/* required attributes */
NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
@@ -625,7 +626,6 @@ NSS_IMPLEMENT nssCryptokiObject **
nssToken_FindCerts (
NSSToken *token,
nssSession *session,
- nssTokenSearchType searchType,
PRUint32 maximumOpt,
PRStatus *statusOpt
)
@@ -635,12 +635,7 @@ nssToken_FindCerts (
CK_ULONG ctsize;
NSS_CK_TEMPLATE_START(cert_template, attr, ctsize);
- /* Set the search to token/session only if provided */
- if (searchType == nssTokenSearchType_SessionOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
- } else if (searchType == nssTokenSearchType_TokenOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- }
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize);
@@ -702,10 +697,9 @@ nssToken_ImportPublicKey (
}
NSS_IMPLEMENT nssCryptokiObject **
-nssToken_FindPrivateKeys (
+nssToken_FindPublicKeys (
NSSToken *token,
nssSession *session,
- nssTokenSearchType searchType,
PRUint32 maximumOpt,
PRStatus *statusOpt
)
@@ -716,12 +710,8 @@ nssToken_FindPrivateKeys (
nssCryptokiObject **objects;
NSS_CK_TEMPLATE_START(key_template, attr, ktsize);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_privkey);
- if (searchType == nssTokenSearchType_SessionOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
- } else if (searchType == nssTokenSearchType_TokenOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- }
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_pubkey);
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize);
objects = find_objects_by_template(token, session,
@@ -730,216 +720,30 @@ nssToken_FindPrivateKeys (
return objects;
}
-/* XXX ?there are no session cert objects, so only search token objects */
-NSS_IMPLEMENT nssCryptokiObject *
-nssToken_FindPrivateKeyByID (
+NSS_IMPLEMENT nssCryptokiObject **
+nssToken_FindPrivateKeys (
NSSToken *token,
nssSession *session,
- NSSItem *keyID
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
)
{
CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE key_template[3];
+ CK_ATTRIBUTE key_template[2];
CK_ULONG ktsize;
nssCryptokiObject **objects;
- nssCryptokiObject *rvKey = NULL;
NSS_CK_TEMPLATE_START(key_template, attr, ktsize);
NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_privkey);
NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, keyID);
NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize);
objects = find_objects_by_template(token, session,
key_template, ktsize,
- 1, NULL);
- if (objects) {
- rvKey = objects[0];
- nss_ZFreeIf(objects);
- }
- return rvKey;
-}
-
-/* XXX ?there are no session cert objects, so only search token objects */
-NSS_IMPLEMENT nssCryptokiObject *
-nssToken_FindPublicKeyByID (
- NSSToken *token,
- nssSession *session,
- NSSItem *keyID
-)
-{
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE key_template[3];
- CK_ULONG ktsize;
- nssCryptokiObject **objects;
- nssCryptokiObject *rvKey = NULL;
-
- NSS_CK_TEMPLATE_START(key_template, attr, ktsize);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_pubkey);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, keyID);
- NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize);
-
- objects = find_objects_by_template(token, session,
- key_template, ktsize,
- 1, NULL);
- if (objects) {
- rvKey = objects[0];
-#ifndef SOFTOKEN_RETURNS_PUBKEY_BUG
- {
- /* XXX the softoken will return a valid key handle when it
- * only has the cert, not the pubkey
- */
- PRStatus status;
- NSSPublicKeyInfo keyInfo;
- NSSArena *tmparena = nssArena_Create();
- if (tmparena) {
- status = nssCryptokiPublicKey_GetAttributes(rvKey, tmparena,
- &keyInfo, NULL);
- nssArena_Destroy(tmparena);
- } else {
- status = PR_FAILURE;
- }
- if (status == PR_FAILURE) {
- nssCryptokiObject_Destroy(rvKey);
- rvKey = NULL;
- }
- }
-#endif /* SOFTOKEN_RETURNS_PUBKEY_BUG */
- nss_ZFreeIf(objects);
- }
- return rvKey;
-}
-
-static CK_TRUST
-get_ck_trust (
- nssTrustLevel nssTrust
-)
-{
- CK_TRUST t;
- switch (nssTrust) {
- case nssTrustLevel_Unknown: t = CKT_NETSCAPE_TRUST_UNKNOWN; break;
- case nssTrustLevel_NotTrusted: t = CKT_NETSCAPE_UNTRUSTED; break;
- case nssTrustLevel_TrustedDelegator: t = CKT_NETSCAPE_TRUSTED_DELEGATOR;
- break;
- case nssTrustLevel_ValidDelegator: t = CKT_NETSCAPE_VALID_DELEGATOR; break;
- case nssTrustLevel_Trusted: t = CKT_NETSCAPE_TRUSTED; break;
- case nssTrustLevel_Valid: t = CKT_NETSCAPE_VALID; break;
- }
- return t;
-}
-
-NSS_IMPLEMENT nssCryptokiObject *
-nssToken_ImportTrust (
- NSSToken *tok,
- nssSession *session,
- NSSDER *certEncoding,
- NSSDER *certIssuer,
- NSSDER *certSerial,
- nssTrustLevel serverAuth,
- nssTrustLevel clientAuth,
- nssTrustLevel codeSigning,
- nssTrustLevel emailProtection,
- PRBool asTokenObject
-)
-{
- nssCryptokiObject *object;
- CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST;
- CK_TRUST ckSA, ckCA, ckCS, ckEP;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE trust_tmpl[10];
- CK_ULONG tsize;
- ckSA = get_ck_trust(serverAuth);
- ckCA = get_ck_trust(clientAuth);
- ckCS = get_ck_trust(codeSigning);
- ckEP = get_ck_trust(emailProtection);
- NSS_CK_TEMPLATE_START(trust_tmpl, attr, tsize);
- if (asTokenObject) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- } else {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
- }
- NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, tobjc);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, certIssuer);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, certSerial);
- /* now set the trust values */
- NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_SERVER_AUTH, ckSA);
- NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CLIENT_AUTH, ckCA);
- NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, ckCS);
- NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_EMAIL_PROTECTION, ckEP);
- NSS_CK_TEMPLATE_FINISH(trust_tmpl, attr, tsize);
- /* import the trust object onto the token */
- object = import_object(tok, session, trust_tmpl, tsize);
- return object;
-}
-
-NSS_IMPLEMENT nssCryptokiObject **
-nssToken_FindTrustObjects (
- NSSToken *token,
- nssSession *session,
- nssTokenSearchType searchType,
- PRUint32 maximumOpt,
- PRStatus *statusOpt
-)
-{
- CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE tobj_template[2];
- CK_ULONG tobj_size;
- nssCryptokiObject **objects;
-
- NSS_CK_TEMPLATE_START(tobj_template, attr, tobj_size);
- if (searchType == nssTokenSearchType_SessionOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
- } else if (searchType == nssTokenSearchType_TokenOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- }
- NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, tobjc);
- NSS_CK_TEMPLATE_FINISH(tobj_template, attr, tobj_size);
-
- objects = find_objects_by_template(token, session,
- tobj_template, tobj_size,
maximumOpt, statusOpt);
return objects;
}
-NSS_IMPLEMENT nssCryptokiObject *
-nssToken_FindTrustForCert (
- NSSToken *token,
- nssSession *session,
- NSSDER *certEncoding,
- NSSDER *certIssuer,
- NSSDER *certSerial,
- nssTokenSearchType searchType
-)
-{
- CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE tobj_template[5];
- CK_ULONG tobj_size;
- nssCryptokiObject *object, **objects;
-
- NSS_CK_TEMPLATE_START(tobj_template, attr, tobj_size);
- if (searchType == nssTokenSearchType_SessionOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
- } else if (searchType == nssTokenSearchType_TokenOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- }
- NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, tobjc);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, certIssuer);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER , certSerial);
- NSS_CK_TEMPLATE_FINISH(tobj_template, attr, tobj_size);
- object = NULL;
- objects = find_objects_by_template(token, session,
- tobj_template, tobj_size,
- 1, NULL);
- if (objects) {
- object = objects[0];
- nss_ZFreeIf(objects);
- }
- return object;
-}
-
NSS_IMPLEMENT PRStatus
nssToken_SeedRandom (
NSSToken *token,
@@ -1680,7 +1484,6 @@ nssToken_ContinueEncrypt (
)
{
CK_RV ckrv;
- CK_ULONG bufLen;
PRBool freeit = PR_FALSE;
void *epv = nssToken_GetCryptokiEPV(token);
@@ -1850,7 +1653,6 @@ nssToken_ContinueDecrypt (
)
{
CK_RV ckrv;
- CK_ULONG bufLen;
PRBool freeit = PR_FALSE;
void *epv = nssToken_GetCryptokiEPV(token);
diff --git a/security/nss/lib/nss/config.mk b/security/nss/lib/nss/config.mk
index 771e5398a..2aabcf2c3 100644
--- a/security/nss/lib/nss/config.mk
+++ b/security/nss/lib/nss/config.mk
@@ -38,6 +38,10 @@
# are specifed as dependencies within rules.mk.
#
+EXTRA_LIBS += \
+ $(DIST)/lib/$(LIB_PREFIX)dbm.$(LIB_SUFFIX) \
+ $(NULL)
+
# can't do this in manifest.mn because OS_TARGET isn't defined there.
ifeq (,$(filter-out WIN%,$(OS_TARGET)))
diff --git a/security/nss/lib/nss/nssinit.c b/security/nss/lib/nss/nssinit.c
index 22f6071ac..aa2ad46ae 100644
--- a/security/nss/lib/nss/nssinit.c
+++ b/security/nss/lib/nss/nssinit.c
@@ -455,7 +455,7 @@ loser:
}
}
- g_default_trust_domain = NSSTrustDomain_Create(NULL, NULL, NULL, NULL);
+ g_default_trust_domain = nssTrustDomain_Create(configdir, NULL, NULL, NULL);
modules = nss_GetLoadedModules();
if (!modules) {
@@ -463,7 +463,7 @@ loser:
}
for (mp = modules; *mp; mp++) {
- nssrv = NSSTrustDomain_AddModule(g_default_trust_domain, *mp);
+ nssrv = nssTrustDomain_AddModule(g_default_trust_domain, *mp);
}
nssModuleArray_Destroy(modules);
@@ -554,7 +554,7 @@ NSS_Shutdown(void)
PRStatus rv = PR_SUCCESS;
nss_DumpModuleLog();
nss_FreeOIDTable();
- NSSTrustDomain_Destroy(g_default_trust_domain);
+ nssTrustDomain_Destroy(g_default_trust_domain);
nss_DestroyGlobalModuleList();
nss_IsInitted = PR_FALSE;
return rv;
diff --git a/security/nss/lib/pki/asymmkey.c b/security/nss/lib/pki/asymmkey.c
index b5ced552e..04a8c67c0 100644
--- a/security/nss/lib/pki/asymmkey.c
+++ b/security/nss/lib/pki/asymmkey.c
@@ -81,31 +81,6 @@ struct NSSPrivateKeyStr
};
NSS_IMPLEMENT NSSPrivateKey *
-nssPrivateKey_Create (
- nssPKIObject *object
-)
-{
- PRStatus status;
- NSSPrivateKey *rvKey;
- NSSArena *arena = object->arena;
- PR_ASSERT(object->instances != NULL && object->numInstances > 0);
- rvKey = nss_ZNEW(arena, NSSPrivateKey);
- if (!rvKey) {
- return (NSSPrivateKey *)NULL;
- }
- rvKey->object = *object;
- /* XXX should choose instance based on some criteria */
- status = nssCryptokiPrivateKey_GetAttributes(object->instances[0],
- arena,
- &rvKey->kind,
- &rvKey->id);
- if (status != PR_SUCCESS) {
- return (NSSPrivateKey *)NULL;
- }
- return rvKey;
-}
-
-NSS_IMPLEMENT NSSPrivateKey *
nssPrivateKey_CreateFromInstance (
nssCryptokiObject *instance,
NSSTrustDomain *td,
@@ -115,12 +90,29 @@ nssPrivateKey_CreateFromInstance (
PRStatus status;
nssPKIObject *pkio;
NSSPrivateKey *rvKey = NULL;
+ nssPKIObjectTable *objectTable = nssTrustDomain_GetObjectTable(td);
- pkio = nssPKIObject_Create(NULL, instance, td, vdOpt);
- if (!pkio) {
- return (NSSPrivateKey *)NULL;
+ rvKey = nssPKIObject_CREATE(td, instance, NSSPrivateKey);
+ if (!rvKey) {
+ goto loser;
+ }
+ pkio = &rvKey->object;
+ status = nssCryptokiPrivateKey_GetAttributes(instance, pkio->arena,
+ &rvKey->kind,
+ &rvKey->id);
+ if (status != PR_SUCCESS) {
+ goto loser;
+ }
+ pkio->objectType = pkiObjectType_PrivateKey;
+ pkio->numIDs = 1;
+ pkio->uid[0] = &rvKey->id;
+ rvKey = (NSSPrivateKey *)nssPKIObjectTable_Add(objectTable, pkio);
+ if (!rvKey) {
+ rvKey = (NSSPrivateKey *)pkio;
+ goto loser;
+ } else if ((nssPKIObject *)rvKey != pkio) {
+ nssPrivateKey_Destroy((NSSPrivateKey *)pkio);
}
- rvKey = nssPrivateKey_Create(pkio);
if (rvKey && vdOpt) {
status = nssVolatileDomain_ImportPrivateKey(vdOpt, rvKey);
if (status == PR_FAILURE) {
@@ -129,6 +121,9 @@ nssPrivateKey_CreateFromInstance (
}
}
return rvKey;
+loser:
+ nssPrivateKey_Destroy(rvKey);
+ return (NSSPrivateKey *)NULL;
}
NSS_IMPLEMENT NSSPrivateKey *
@@ -188,12 +183,12 @@ nssPrivateKey_GetNickname (
}
NSS_IMPLEMENT PRBool
-nssPrivateKey_IsOnToken (
+nssPrivateKey_HasInstanceOnToken (
NSSPrivateKey *vk,
NSSToken *token
)
{
- return nssPKIObject_IsOnToken(&vk->object, token);
+ return nssPKIObject_HasInstanceOnToken(&vk->object, token);
}
NSS_IMPLEMENT nssCryptokiObject *
@@ -214,6 +209,23 @@ nssPrivateKey_FindInstanceForAlgorithm (
return nssPKIObject_FindInstanceForAlgorithm(&vk->object, ap);
}
+NSS_IMPLEMENT PRStatus
+nssPrivateKey_RemoveInstanceForToken (
+ NSSPrivateKey *vk,
+ NSSToken *token
+)
+{
+ return nssPKIObject_RemoveInstanceForToken(&vk->object, token);
+}
+
+NSS_IMPLEMENT PRIntn
+nssPrivateKey_CountInstances (
+ NSSPrivateKey *vk
+)
+{
+ return nssPKIObject_CountInstances(&vk->object);
+}
+
NSS_IMPLEMENT void
nssPrivateKey_SetVolatileDomain (
NSSPrivateKey *vk,
@@ -427,6 +439,7 @@ NSSPrivateKey_Encode (
rvOpt, arenaOpt);
}
+#if 0
/* XXX move to a lower layer to avoid extra translation? */
/* or keep data with oid? */
static NSSKeyPairType
@@ -449,6 +462,7 @@ get_key_pair_type(NSSOID *kpAlg)
return NSSKeyPairType_Unknown;
}
}
+#endif
NSS_IMPLEMENT NSSPrivateKey *
nssPrivateKey_Decode (
@@ -642,7 +656,7 @@ nssPrivateKey_Decrypt (
NSSItem *rvIt = NULL;
if (apOpt) {
- ap = apOpt;
+ ap = (NSSAlgNParam *)apOpt;
} else {
NSSOIDTag alg;
/* XXX are these defaults reasonable? */
@@ -823,56 +837,8 @@ nssPrivateKey_FindPublicKey (
NSSPrivateKey *vk
)
{
- PRStatus status;
- NSSItem *id;
- NSSPublicKey *rvPubKey = NULL;
- nssPKIObjectCollection *collection = NULL;
- id = nssPrivateKey_GetID(vk);
- if (id) {
- /* XXX
- * This would ostensibly search the trust domain. However, that
- * means searching every active token for the key, when it is
- * almost assuredly only on the token with the private key. Even
- * if not, the token that has the pair is the most desirable.
- * In general, this is another place where multiple instances
- * can be confusing/non-optimal, so needs to be handled correctly.
- * For now, restricting the search to the private key's tokens.
- */
- NSSToken **tokens, **tp;
- nssCryptokiObject *instance;
- NSSTrustDomain *td = nssPrivateKey_GetTrustDomain(vk, NULL);
- tokens = nssPKIObject_GetTokens(&vk->object, NULL, 0, &status);
- if (!tokens) {
- return (NSSPublicKey *)NULL; /* defer to trust domain ??? */
- }
- for (tp = tokens; *tp; tp++) {
- /* XXX think of something better */
- nssCryptokiObject *vko;
- vko = nssPKIObject_GetInstance(&vk->object, *tp);
- if (!vko) {
- continue;
- }
- instance = nssToken_FindPublicKeyByID(*tp, vko->session, id);
- nssCryptokiObject_Destroy(vko);
- if (instance) {
- if (!collection) {
- collection = nssPublicKeyCollection_Create(td, NULL);
- if (!collection) {
- nssCryptokiObject_Destroy(instance);
- return (NSSPublicKey *)NULL;
- }
- }
- status = nssPKIObjectCollection_AddInstances(collection,
- &instance, 1);
- }
- }
- }
- if (collection) {
- (void)nssPKIObjectCollection_GetPublicKeys(collection,
- &rvPubKey, 1, NULL);
- nssPKIObjectCollection_Destroy(collection);
- }
- return rvPubKey;
+ NSSTrustDomain *td = nssPrivateKey_GetTrustDomain(vk, NULL);
+ return nssTrustDomain_FindPublicKeyByID(td, &vk->id);
}
NSS_IMPLEMENT NSSPublicKey *
@@ -955,48 +921,38 @@ struct NSSPublicKeyStr
};
NSS_IMPLEMENT NSSPublicKey *
-nssPublicKey_Create (
- nssPKIObject *object
-)
-{
- PRStatus status;
- NSSPublicKey *rvKey;
- NSSArena *arena = object->arena;
- PR_ASSERT(object->instances != NULL && object->numInstances > 0);
- rvKey = nss_ZNEW(arena, NSSPublicKey);
- if (!rvKey) {
- return (NSSPublicKey *)NULL;
- }
- rvKey->object = *object;
- /* XXX should choose instance based on some criteria */
- status = nssCryptokiPublicKey_GetAttributes(object->instances[0],
- arena,
- &rvKey->info,
- &rvKey->id);
- if (status != PR_SUCCESS) {
- nssPublicKey_Destroy(rvKey);
- return (NSSPublicKey *)NULL;
- }
- return rvKey;
-}
-
-NSS_IMPLEMENT NSSPublicKey *
nssPublicKey_CreateFromInstance (
nssCryptokiObject *instance,
NSSTrustDomain *td,
- NSSVolatileDomain *vdOpt,
- NSSArena *arenaOpt
+ NSSVolatileDomain *vdOpt
)
{
PRStatus status;
nssPKIObject *pkio;
NSSPublicKey *rvKey = NULL;
+ nssPKIObjectTable *objectTable = nssTrustDomain_GetObjectTable(td);
- pkio = nssPKIObject_Create(arenaOpt, instance, td, vdOpt);
- if (!pkio) {
- return (NSSPublicKey *)NULL;
+ rvKey = nssPKIObject_CREATE(td, instance, NSSPublicKey);
+ if (!rvKey) {
+ goto loser;
+ }
+ pkio = &rvKey->object;
+ status = nssCryptokiPublicKey_GetAttributes(instance, pkio->arena,
+ &rvKey->info,
+ &rvKey->id);
+ if (status != PR_SUCCESS) {
+ goto loser;
+ }
+ pkio->objectType = pkiObjectType_PublicKey;
+ pkio->numIDs = 1;
+ pkio->uid[0] = &rvKey->id;
+ rvKey = (NSSPublicKey *)nssPKIObjectTable_Add(objectTable, pkio);
+ if (!rvKey) {
+ rvKey = (NSSPublicKey *)pkio;
+ goto loser;
+ } else if ((nssPKIObject *)rvKey != pkio) {
+ nssPublicKey_Destroy((NSSPublicKey *)pkio);
}
- rvKey = nssPublicKey_Create(pkio);
if (rvKey && vdOpt) {
status = nssVolatileDomain_ImportPublicKey(vdOpt, rvKey);
if (status == PR_FAILURE) {
@@ -1005,6 +961,9 @@ nssPublicKey_CreateFromInstance (
}
}
return rvKey;
+loser:
+ nssPublicKey_Destroy(rvKey);
+ return (NSSPublicKey *)NULL;
}
/* XXX same here */
@@ -1068,12 +1027,13 @@ nssPublicKey_CreateFromInfo (
bko = nssToken_ImportPublicKey(token, session, &bki, PR_FALSE);
if (bko) {
- rvbk = nssPublicKey_CreateFromInstance(bko, td, vd, arena);
+ rvbk = nssPublicKey_CreateFromInstance(bko, td, vd);
if (!rvbk) {
nssCryptokiObject_Destroy(bko);
}
}
+ /* XXX leak arena */
nssSession_Destroy(session);
nssToken_Destroy(token);
return rvbk;
@@ -1139,12 +1099,12 @@ nssPublicKey_GetID (
}
NSS_IMPLEMENT PRBool
-nssPublicKey_IsOnToken (
+nssPublicKey_HasInstanceOnToken (
NSSPublicKey *bk,
NSSToken *token
)
{
- return nssPKIObject_IsOnToken(&bk->object, token);
+ return nssPKIObject_HasInstanceOnToken(&bk->object, token);
}
NSS_IMPLEMENT nssCryptokiObject *
@@ -1165,6 +1125,23 @@ nssPublicKey_FindInstanceForAlgorithm (
return nssPKIObject_FindInstanceForAlgorithm(&bk->object, ap);
}
+NSS_IMPLEMENT PRStatus
+nssPublicKey_RemoveInstanceForToken (
+ NSSPublicKey *bk,
+ NSSToken *token
+)
+{
+ return nssPKIObject_RemoveInstanceForToken(&bk->object, token);
+}
+
+NSS_IMPLEMENT PRIntn
+nssPublicKey_CountInstances (
+ NSSPublicKey *bk
+)
+{
+ return nssPKIObject_CountInstances(&bk->object);
+}
+
NSS_IMPLEMENT void
nssPublicKey_SetVolatileDomain (
NSSPublicKey *bk,
@@ -1587,7 +1564,7 @@ nssPublicKey_FindCerts (
{
NSSTrustDomain *td = nssPublicKey_GetTrustDomain(bk, NULL);
return nssTrustDomain_FindCertsByID(td, &bk->id,
- rvOpt, maximumOpt, arenaOpt);
+ rvOpt, maximumOpt, arenaOpt);
}
NSS_IMPLEMENT NSSCert **
diff --git a/security/nss/lib/pki/cert.c b/security/nss/lib/pki/cert.c
index ce6fae498..f965b2f9b 100644
--- a/security/nss/lib/pki/cert.c
+++ b/security/nss/lib/pki/cert.c
@@ -73,6 +73,7 @@ struct NSSCertStr
NSSDER serial;
NSSASCII7 *email;
NSSPublicKey *bk; /* for ephemeral decoded pubkeys */
+ nssTrust trust;
nssCertDecoding decoding;
};
@@ -82,106 +83,91 @@ nss_GetMethodsForType (
NSSCertType certType
);
-/* Creates a certificate from a base object */
NSS_IMPLEMENT NSSCert *
-nssCert_Create (
- nssPKIObject *object
+nssCert_CreateFromInstance (
+ nssCryptokiObject *instance,
+ NSSTrustDomain *td,
+ NSSVolatileDomain *vdOpt
)
{
PRStatus status;
- NSSCert *rvCert;
- /* mark? */
- NSSArena *arena = object->arena;
- PR_ASSERT(object->instances != NULL && object->numInstances > 0);
- rvCert = nss_ZNEW(arena, NSSCert);
+ nssPKIObject *pkio;
+ NSSCert *rvCert = NULL;
+ nssPKIObjectTable *objectTable = nssTrustDomain_GetObjectTable(td);
+
+ rvCert = nssPKIObject_CREATE(td, instance, NSSCert);
if (!rvCert) {
return (NSSCert *)NULL;
}
- rvCert->object = *object;
- /* XXX should choose instance based on some criteria */
- status = nssCryptokiCert_GetAttributes(object->instances[0],
- arena,
+ pkio = &rvCert->object;
+ status = nssCryptokiCert_GetAttributes(instance, pkio->arena,
&rvCert->kind,
&rvCert->id,
&rvCert->encoding,
&rvCert->issuer,
&rvCert->serial,
- &rvCert->subject,
- &rvCert->email);
+ &rvCert->subject);
if (status != PR_SUCCESS) {
- return (NSSCert *)NULL;
+ goto loser;
}
- /* all certs need an encoding value */
- if (rvCert->encoding.data == NULL) {
- return (NSSCert *)NULL;
+ pkio->objectType = pkiObjectType_Cert;
+ pkio->numIDs = 2;
+ pkio->uid[0] = &rvCert->issuer;
+ pkio->uid[1] = &rvCert->serial;
+ rvCert = (NSSCert *)nssPKIObjectTable_Add(objectTable, pkio);
+ if (!rvCert) {
+ rvCert = (NSSCert *)pkio;
+ goto loser;
+ } else if ((nssPKIObject *)rvCert != pkio) {
+ nssCert_Destroy((NSSCert *)pkio);
}
rvCert->decoding.methods = nss_GetMethodsForType(rvCert->kind);
if (!rvCert->decoding.methods) {
- return (NSSCert *)NULL;
- }
- return rvCert;
-}
-
-NSS_IMPLEMENT NSSCert *
-nssCert_CreateFromInstance (
- nssCryptokiObject *instance,
- NSSTrustDomain *td,
- NSSVolatileDomain *vdOpt,
- NSSArena *arenaOpt
-)
-{
- PRStatus status;
- nssPKIObject *pkio;
- NSSCert *rvCert = NULL;
-
- pkio = nssPKIObject_Create(arenaOpt, instance, td, vdOpt);
- if (!pkio) {
- return (NSSCert *)NULL;
+ goto loser;
}
- rvCert = nssCert_Create(pkio);
if (rvCert && vdOpt) {
status = nssVolatileDomain_ImportCert(vdOpt, rvCert);
if (status == PR_FAILURE) {
- nssCert_Destroy(rvCert);
- rvCert = NULL;
+ goto loser;
}
}
+ /* token certs trusted by default */
+ rvCert->trust.trustedUsages.ca = rvCert->trust.trustedUsages.peer = ~0;
+ /* XXX or check trust here by looking at db? */
return rvCert;
+loser:
+ nssCert_Destroy(rvCert);
+ return (NSSCert *)NULL;
}
NSS_IMPLEMENT NSSCert *
nssCert_Decode (
- NSSBER *ber
+ NSSBER *ber,
+ NSSItem *nicknameOpt,
+ nssTrust *trustOpt,
+ NSSTrustDomain *td,
+ NSSVolatileDomain *vdOpt
)
{
- NSSArena *arena;
+ nssPKIObject *pkio;
NSSCert *rvCert;
NSSCertMethods *decoder;
void *decoding;
NSSItem *it;
+ nssPKIObjectTable *objectTable = nssTrustDomain_GetObjectTable(td);
- /* create the PKIObject */
- arena = nssArena_Create();
- if (!arena) {
- return (NSSCert *)NULL;
- }
- rvCert = nss_ZNEW(arena, NSSCert);
+ rvCert = nssPKIObject_CREATE(td, NULL, NSSCert);
if (!rvCert) {
- goto loser;
- }
- rvCert->object.arena = arena;
- rvCert->object.refCount = 1;
- rvCert->object.lock = PZ_NewLock(nssILockOther);
- if (!rvCert->object.lock) {
- goto loser;
+ return (NSSCert *)NULL;
}
+ pkio = &rvCert->object;
/* try to decode it */
decoder = nss_GetMethodsForType(NSSCertType_PKIX);
if (!decoder) {
/* nss_SetError(UNKNOWN_CERT_TYPE); */
goto loser;
}
- decoding = decoder->decode(arena, ber);
+ decoding = decoder->decode(pkio->arena, ber);
if (decoding) {
/* it's a PKIX cert */
rvCert->decoding.methods = decoder;
@@ -191,7 +177,7 @@ nssCert_Decode (
goto loser;
}
/* copy the BER encoding */
- it = nssItem_Duplicate(ber, arena, &rvCert->encoding);
+ it = nssItem_Duplicate(ber, pkio->arena, &rvCert->encoding);
if (!it) {
goto loser;
}
@@ -215,9 +201,28 @@ nssCert_Decode (
rvCert->subject = *it;
/* obtain the email address from the decoding */
rvCert->email = decoder->getEmailAddress(decoding);
+ /* set the nickname to the supplied one */
+ if (nicknameOpt) {
+ pkio->nickname = nssUTF8_Create(pkio->arena, nssStringType_UTF8String,
+ nicknameOpt->data, nicknameOpt->size);
+ }
+ if (trustOpt) {
+ rvCert->trust = *trustOpt;
+ }
+ pkio->objectType = pkiObjectType_Cert;
+ pkio->numIDs = 2;
+ pkio->uid[0] = &rvCert->issuer;
+ pkio->uid[1] = &rvCert->serial;
+ rvCert = (NSSCert *)nssPKIObjectTable_Add(objectTable, pkio);
+ if (!rvCert) {
+ rvCert = (NSSCert *)pkio;
+ goto loser;
+ } else if ((nssPKIObject *)rvCert != pkio) {
+ nssCert_Destroy((NSSCert *)pkio);
+ }
return rvCert;
loser:
- nssArena_Destroy(arena);
+ nssCert_Destroy(rvCert);
return (NSSCert *)NULL;
}
@@ -809,47 +814,6 @@ nssCert_CopyToToken (
return PR_SUCCESS;
}
-static NSSUsage
-get_trusted_usage (
- NSSCert *c,
- PRBool asCA,
- PRStatus *status
-)
-{
- nssTrust *trust;
- nssTrustLevel checkLevel;
- NSSUsage usage = 0;
-
- *status = PR_SUCCESS;
- checkLevel = asCA ? nssTrustLevel_TrustedDelegator :
- nssTrustLevel_Trusted;
- /* XXX needs to be cached with cert */
- trust = nssTrustDomain_FindTrustForCert(c->object.td, c);
- if (!trust) {
- if (NSS_GetError() == NSS_ERROR_NO_ERROR) {
- *status = PR_SUCCESS;
- } else {
- *status = PR_FAILURE;
- }
- return 0;
- }
- if (trust->clientAuth == checkLevel) {
- usage |= NSSUsage_SSLClient;
- }
- if (trust->serverAuth == checkLevel) {
- usage |= NSSUsage_SSLServer;
- }
- if (trust->emailProtection == checkLevel) {
- usage |= NSSUsage_EmailSigner | NSSUsage_EmailRecipient;
- }
- if (trust->codeSigning == checkLevel) {
- usage |= NSSUsage_CodeSigner;
- }
- nssTrust_Destroy(trust);
- /* XXX should check user cert */
- return usage;
-}
-
static PRStatus
validate_and_discover_trust (
NSSCert *c,
@@ -861,7 +825,6 @@ validate_and_discover_trust (
)
{
PRStatus status;
- NSSUsage trustedUsage;
NSSUsages *certUsages;
PRBool valid;
@@ -877,8 +840,9 @@ validate_and_discover_trust (
}
/* See if the cert is trusted, overrides cert's usage */
- trustedUsage = get_trusted_usage(c, asCA, &status);
- if (trustedUsage && (trustedUsage & usage) == usage) {
+ if ((asCA && c->trust.trustedUsages.ca & usage) ||
+ c->trust.trustedUsages.peer & usage)
+ {
*trusted = PR_TRUE;
return PR_SUCCESS;
}
@@ -1108,7 +1072,6 @@ nssCert_GetTrustedUsages (
NSSUsages *usagesOpt
)
{
- PRStatus status;
PRBool freeIt = PR_FALSE;
if (!usagesOpt) {
usagesOpt = nss_ZNEW(NULL, NSSUsages);
@@ -1117,16 +1080,7 @@ nssCert_GetTrustedUsages (
}
freeIt = PR_TRUE;
}
- usagesOpt->ca = get_trusted_usage(c, PR_TRUE, &status);
- if (status == PR_FAILURE) {
- if (freeIt) nss_ZFreeIf(usagesOpt);
- return (NSSUsages *)NULL;
- }
- usagesOpt->peer = get_trusted_usage(c, PR_FALSE, &status);
- if (status == PR_FAILURE) {
- if (freeIt) nss_ZFreeIf(usagesOpt);
- return (NSSUsages *)NULL;
- }
+ *usagesOpt = c->trust.trustedUsages;
return usagesOpt;
}
@@ -1146,76 +1100,13 @@ nssCert_IsTrustedForUsages (
PRStatus *statusOpt
)
{
- NSSUsages certUsages;
- if (nssCert_GetTrustedUsages(c, &certUsages) == NULL) {
- if (statusOpt) *statusOpt = PR_FAILURE;
+ if (c->trust.trustedUsages.ca == usages->ca &&
+ c->trust.trustedUsages.peer == usages->peer)
+ {
+ return PR_TRUE;
+ } else {
return PR_FALSE;
}
- return nssUsages_Match(usages, &certUsages);
-}
-
-static void
-set_trust_for_usage (
- NSSUsage usage,
- nssTrust *trust,
- nssTrustLevel setLevel
-)
-{
- if (usage & NSSUsage_SSLClient) {
- trust->clientAuth = setLevel;
- }
- if (usage & NSSUsage_SSLServer) {
- trust->serverAuth = setLevel;
- }
- if (usage & (NSSUsage_EmailSigner | NSSUsage_EmailRecipient)) {
- trust->emailProtection = setLevel;
- }
- if (usage & NSSUsage_CodeSigner) {
- trust->codeSigning = setLevel;
- }
-}
-
-/* XXX move */
-NSS_IMPLEMENT NSSToken *
-nssTrust_GetWriteToken (
- nssTrust *t,
- nssSession **rvSessionOpt
-)
-{
- return nssPKIObject_GetWriteToken(&t->object, rvSessionOpt);
-}
-
-/* XXX move */
-NSS_IMPLEMENT void
-nssTrust_Clear (
- nssTrust *trust
-)
-{
- trust->clientAuth = nssTrustLevel_NotTrusted;
- trust->serverAuth = nssTrustLevel_NotTrusted;
- trust->emailProtection = nssTrustLevel_NotTrusted;
- trust->codeSigning = nssTrustLevel_NotTrusted;
-}
-
-/* XXX move */
-NSS_IMPLEMENT nssTrust *
-nssTrust_CreateNull (
- NSSTrustDomain *td
-)
-{
- nssPKIObject *pkio;
- nssTrust *trust = NULL;
- pkio = nssPKIObject_Create(NULL, NULL, td, NULL);
- if (pkio) {
- trust = nss_ZNEW(pkio->arena, nssTrust);
- if (trust) {
- trust->object = *pkio;
- nssTrust_Clear(trust);
- } else {
- nssPKIObject_Destroy(pkio);
- }
- }
- return trust;
}
NSS_IMPLEMENT PRStatus
@@ -1224,56 +1115,22 @@ nssCert_SetTrustedUsages (
NSSUsages *usages
)
{
- PRStatus status;
- nssTrust *trust;
- NSSToken *token;
- nssSession *session;
- nssCryptokiObject *instance;
-
- /* XXX needs to be cached with cert */
- trust = nssTrustDomain_FindTrustForCert(c->object.td, c);
- if (trust) {
- token = nssTrust_GetWriteToken(trust, &session);
- nssTrust_Clear(trust);
- } else {
- if (NSS_GetError() != NSS_ERROR_NO_ERROR) {
- return PR_FAILURE;
- }
- /* XXX something better */
- /* create a new trust object */
- trust = nssTrust_CreateNull(c->object.td);
- if (!trust) {
- return PR_FAILURE;
- }
- token = nssCert_GetWriteToken(c, &session);
- if (!token) {
- /* XXX should extract from trust domain */
- PR_ASSERT(0);
- return PR_FAILURE;
- }
- }
- /* set the new trust values */
- set_trust_for_usage(usages->ca, trust, nssTrustLevel_TrustedDelegator);
- set_trust_for_usage(usages->peer, trust, nssTrustLevel_Trusted);
- /* import (set) the trust values on the token */
- instance = nssToken_ImportTrust(token, session, &c->encoding,
- &c->issuer, &c->serial,
- trust->serverAuth,
- trust->clientAuth,
- trust->codeSigning,
- trust->emailProtection,
- PR_TRUE);
- /* clean up */
- nssSession_Destroy(session);
- nssToken_Destroy(token);
- if (instance) {
- nssCryptokiObject_Destroy(instance);
- status = PR_SUCCESS;
- } else {
- status = PR_FAILURE;
+ NSSTrustDomain *td;
+ if (c->trust.trustedUsages.ca == usages->ca &&
+ c->trust.trustedUsages.peer == usages->peer)
+ {
+ /* already set to desired value */
+ return PR_SUCCESS;
}
- nssTrust_Destroy(trust);
- return status;
+ /* XXX lock here? */
+ /* set the new trusted usages */
+ c->trust.trustedUsages = *usages;
+ /* clear the not trusted usages of all bits from the new trust */
+ c->trust.notTrustedUsages.ca &= usages->ca;
+ c->trust.notTrustedUsages.peer &= usages->peer;
+ /* reflect the change in the db */
+ td = nssCert_GetTrustDomain(c);
+ return nssTrustDomain_SetCertTrust(td, c, &c->trust);
}
NSS_IMPLEMENT PRStatus
@@ -1383,24 +1240,26 @@ nssCert_BuildChain (
)
{
PRStatus status;
+ PRUint32 i, size;
NSSCert **rvChain;
NSSTrustDomain *td;
- nssPKIObjectCollection *collection;
NSSUsages usages = { 0 };
td = NSSCert_GetTrustDomain(c);
if (statusOpt) *statusOpt = PR_SUCCESS;
- /* initialize the collection with the current cert */
- collection = nssCertCollection_Create(td, NULL);
- if (!collection) {
+ if (rvLimit) {
+ size = rvLimit;
+ } else {
+ size = 4;
+ }
+ rvChain = nss_ZNEWARRAY(arenaOpt, NSSCert *, size + 1);
+ if (!rvChain) {
if (statusOpt) *statusOpt = PR_FAILURE;
return (NSSCert **)NULL;
}
- nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c);
- if (rvLimit == 1) {
- goto finish;
- }
+ i = 0; /* begin the chain with the cert passed in */
+ rvChain[i++] = nssCert_AddRef(c);
/* going from peer to CA */
if (usagesOpt) {
usages.ca = usagesOpt->peer;
@@ -1410,25 +1269,29 @@ nssCert_BuildChain (
while (!nssItem_Equal(&c->subject, &c->issuer, &status)) {
c = find_cert_issuer(c, time, usagesOpt, policiesOpt);
if (c) {
- nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c);
- nssCert_Destroy(c); /* collection has it */
- if (rvLimit > 0 &&
- nssPKIObjectCollection_Count(collection) == rvLimit)
- {
+ rvChain[i++] = c;
+ if (rvLimit > 0 && i == rvLimit) {
+ /* reached the limit of certs asked for */
break;
}
+ if (i == size) {
+ /* unlimited search, but array is full */
+ NSSCert **test;
+ size *= 2;
+ test = nss_ZREALLOCARRAY(rvChain, NSSCert *, size + 1);
+ if (!test) {
+ nssCertArray_Destroy(rvChain);
+ if (statusOpt) *statusOpt = PR_FAILURE;
+ return (NSSCert **)NULL;
+ }
+ rvChain = test;
+ }
} else {
nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);
if (statusOpt) *statusOpt = PR_FAILURE;
break;
}
}
-finish:
- rvChain = nssPKIObjectCollection_GetCerts(collection,
- rvOpt,
- rvLimit,
- arenaOpt);
- nssPKIObjectCollection_Destroy(collection);
return rvChain;
}
@@ -1565,44 +1428,17 @@ nssCert_GetPublicKey (
)
{
PRStatus status;
- NSSToken **tokens, **tp;
- nssCryptokiObject *instance = NULL;
NSSTrustDomain *td = nssCert_GetTrustDomain(c);
NSSVolatileDomain *vd = nssCert_GetVolatileDomain(c, NULL);
- /* first look for a persistent object in the trust domain */
- tokens = nssPKIObject_GetTokens(&c->object, NULL, 0, &status);
- if (tokens) {
- for (tp = tokens; *tp; tp++) {
- /* XXX need to iterate over cert instances to have session */
- nssSession *session = nssToken_CreateSession(*tp, PR_FALSE);
- if (!session) {
- break;
- }
- instance = nssToken_FindPublicKeyByID(*tp, session, &c->id);
- nssSession_Destroy(session);
- if (instance) {
- break;
- }
- }
- /* also search on other tokens? */
- nssTokenArray_Destroy(tokens);
- }
- if (instance) {
- NSSPublicKey *bk = NULL;
- /* found a persistent instance of the pubkey, return it */
- bk = nssPublicKey_CreateFromInstance(instance, td, vd, NULL);
- if (!bk) {
- nssCryptokiObject_Destroy(instance);
- nssVolatileDomain_Destroy(vd);
- return (NSSPublicKey *)NULL;
- }
- return bk;
- } else {
+ if (!c->bk && c->id.size > 0) {
+ /* first try looking for a persistent object */
+ c->bk = nssTrustDomain_FindPublicKeyByID(td, &c->id);
+ }
+ if (!c->bk) {
NSSOIDTag keyAlg;
NSSBitString keyBits;
nssCertDecoding *dc = nssCert_GetDecoding(c);
-
/* create an ephemeral pubkey object, either in the cert's
* volatile domain (if it exists), or as a standalone object
* that will be destroyed with the cert
@@ -1610,11 +1446,12 @@ nssCert_GetPublicKey (
status = dc->methods->getPublicKeyInfo(dc->data, &keyAlg, &keyBits);
if (status == PR_SUCCESS) {
c->bk = nssPublicKey_CreateFromInfo(td, vd, keyAlg, &keyBits);
- nssVolatileDomain_Destroy(vd);
- return c->bk;
}
}
nssVolatileDomain_Destroy(vd);
+ if (c->bk) {
+ return nssPublicKey_AddRef(c->bk);
+ }
return (NSSPublicKey *)NULL;
}
@@ -1632,53 +1469,12 @@ nssCert_FindPrivateKey (
NSSCallback *uhh
)
{
- PRStatus status;
- NSSToken **tokens, **tp;
- nssCryptokiObject *instance;
NSSTrustDomain *td = nssCert_GetTrustDomain(c);
-
- tokens = nssPKIObject_GetTokens(&c->object, NULL, 0, &status);
- if (!tokens) {
- return PR_FALSE; /* actually, should defer to crypto context */
- }
- for (tp = tokens; *tp; tp++) {
- NSSSlot *slot = nssToken_GetSlot(*tp);
- NSSCallback *pwcb = uhh ?
- uhh :
- nssTrustDomain_GetDefaultCallback(td, NULL);
- status = nssSlot_Login(slot, pwcb);
- nssSlot_Destroy(slot);
- if (status != PR_SUCCESS) {
- break;
- }
- /* XXX need to iterate over cert instances to have session */
- {
- nssSession *session = nssToken_CreateSession(*tp, PR_FALSE);
- instance = nssToken_FindPrivateKeyByID(*tp, session, &c->id);
- nssSession_Destroy(session);
- if (instance) {
- break;
- }
- }
- }
- /* also search on other tokens? */
- nssTokenArray_Destroy(tokens);
- if (instance) {
- nssPKIObject *pkio;
- NSSPrivateKey *vk = NULL;
- pkio = nssPKIObject_Create(NULL, instance, td, /* XXX cc */ NULL);
- if (!pkio) {
- nssCryptokiObject_Destroy(instance);
- return (NSSPrivateKey *)NULL;
- }
- vk = nssPrivateKey_Create(pkio);
- if (!vk) {
- nssPKIObject_Destroy(pkio);
- return (NSSPrivateKey *)NULL;
- }
- return vk;
+ if (c->id.size > 0) {
+ return nssTrustDomain_FindPrivateKeyByID(td, &c->id);
+ } else {
+ return (NSSPrivateKey *)NULL;
}
- return (NSSPrivateKey *)NULL;
}
NSS_IMPLEMENT NSSPrivateKey *
@@ -1697,38 +1493,11 @@ nssCert_IsPrivateKeyAvailable (
PRStatus *statusOpt
)
{
- PRStatus status;
- NSSToken **tokens, **tp;
- nssCryptokiObject *instance = NULL;
- NSSTrustDomain *td = nssCert_GetTrustDomain(c);
- PRBool isLoggedIn;
- tokens = nssPKIObject_GetTokens(&c->object, NULL, 0, &status);
- if (!tokens) {
- return PR_FALSE; /* can't have private key w/o a token instance */
- }
- for (tp = tokens; *tp; tp++) {
- NSSSlot *slot;
- /* XXX need to iterate over cert instances to have session */
- nssSession *session = nssToken_CreateSession(*tp, PR_FALSE);
- if (!session) {
- break;
- }
- slot = nssToken_GetSlot(*tp);
- isLoggedIn = nssSlot_IsLoggedIn(slot);
- nssSlot_Destroy(slot);
- if (isLoggedIn) {
- instance = nssToken_FindPrivateKeyByID(*tp, session, &c->id);
- } else {
- instance = nssToken_FindPublicKeyByID(*tp, session, &c->id);
- }
- nssSession_Destroy(session);
- if (instance) {
- break;
- }
- }
- nssTokenArray_Destroy(tokens);
- if (instance) {
- nssCryptokiObject_Destroy(instance);
+ NSSPrivateKey *vk;
+ /* XXX would be nice to "ping" the tokens w/o actually building the key */
+ vk = nssCert_FindPrivateKey(c, uhh);
+ if (vk) {
+ nssPrivateKey_Destroy(vk);
return PR_TRUE;
} else {
return PR_FALSE;
@@ -1838,91 +1607,6 @@ NSSUserCert_DeriveSymKey (
return NULL;
}
-NSS_IMPLEMENT nssTrust *
-nssTrust_Create (
- nssPKIObject *object
-)
-{
- PRStatus status;
- PRUint32 i;
- PRUint32 lastTrustOrder, myTrustOrder;
- NSSModule *module;
- nssTrust *rvt;
- nssCryptokiObject *instance;
- nssTrustLevel serverAuth, clientAuth, codeSigning, emailProtection;
- 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;
- /* trust has to peek into the base object members */
- PZ_Lock(object->lock);
- for (i=0; i<object->numInstances; i++) {
- /* get the trust order from the token's module */
- instance = object->instances[i];
- module = nssToken_GetModule(instance->token);
- myTrustOrder = nssModule_GetTrustOrder(module);
- nssModule_Destroy(module);
- /* get the trust values from this token */
- status = nssCryptokiTrust_GetAttributes(instance,
- &serverAuth,
- &clientAuth,
- &codeSigning,
- &emailProtection);
- if (status != PR_SUCCESS) {
- PZ_Unlock(object->lock);
- 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;
- }
- lastTrustOrder = myTrustOrder;
- }
- PZ_Unlock(object->lock);
- 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;
-}
-
struct nssSMIMEProfileStr
{
nssPKIObject object;
diff --git a/security/nss/lib/pki/cryptocontext.c b/security/nss/lib/pki/cryptocontext.c
index 7b11de350..7888b8957 100644
--- a/security/nss/lib/pki/cryptocontext.c
+++ b/security/nss/lib/pki/cryptocontext.c
@@ -775,10 +775,10 @@ nssCryptoContext_Sign (
}
if (cc->which == a_symkey) {
if (prepare_context_symmetric_key(cc, ap) == PR_FAILURE)
- return PR_FAILURE;
+ return (NSSItem *)NULL;
} else {
if (prepare_context_private_key(cc, ap) == PR_FAILURE)
- return PR_FAILURE;
+ return (NSSItem *)NULL;
}
return nssToken_Sign(cc->token, cc->session, ap, cc->key,
data, rvOpt, arenaOpt);
@@ -1468,7 +1468,7 @@ nssCryptoContext_Unmark (
NSSCryptoContextMark *mark
)
{
- nssArena_Destroy(mark->arena);
+ return nssArena_Destroy(mark->arena);
}
NSS_IMPLEMENT PRStatus
diff --git a/security/nss/lib/pki/manifest.mn b/security/nss/lib/pki/manifest.mn
index 2ba5eb790..a8b62aa56 100644
--- a/security/nss/lib/pki/manifest.mn
+++ b/security/nss/lib/pki/manifest.mn
@@ -34,7 +34,7 @@ MANIFEST_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$ $Name$"
CORE_DEPTH = ../../..
-PRIVATE_EXPORTS = \
+PRIVATE_EXPORTS = \
pki.h \
pkit.h \
$(NULL)
@@ -49,6 +49,7 @@ MODULE = nss
CSRCS = \
pkibase.c \
pkistore.c \
+ pkidb.c \
asymmkey.c \
cert.c \
cryptocontext.c \
@@ -58,6 +59,6 @@ CSRCS = \
volatiledomain.c \
$(NULL)
-REQUIRES = security nspr
+REQUIRES = security nspr dbm
LIBRARY_NAME = nsspki
diff --git a/security/nss/lib/pki/pki.h b/security/nss/lib/pki/pki.h
index 47e1bc07a..54e35d6b8 100644
--- a/security/nss/lib/pki/pki.h
+++ b/security/nss/lib/pki/pki.h
@@ -117,15 +117,19 @@ nssTrustDomain_TraverseCerts (
void *arg
);
-NSS_EXTERN nssTrust *
-nssTrustDomain_FindTrustForCert (
+NSS_EXTERN NSSPublicKey *
+nssTrustDomain_FindPublicKeyByID (
NSSTrustDomain *td,
- NSSCert *c
+ NSSItem *keyID
);
NSS_EXTERN NSSCert *
nssCert_Decode (
- NSSBER *ber
+ NSSBER *ber,
+ NSSItem *nicknameOpt,
+ nssTrust *trustOpt,
+ NSSTrustDomain *td,
+ NSSVolatileDomain *vdOpt
);
NSS_EXTERN NSSCert *
@@ -271,6 +275,18 @@ nssPrivateKey_GetNickname (
NSSToken *tokenOpt
);
+NSS_EXTERN NSSTrustDomain *
+nssPrivateKey_GetTrustDomain (
+ NSSPrivateKey *vk,
+ PRStatus *statusOpt
+);
+
+NSS_EXTERN NSSVolatileDomain *
+nssPrivateKey_GetVolatileDomain (
+ NSSPrivateKey *vk,
+ PRStatus *statusOpt
+);
+
NSS_EXTERN NSSPublicKey *
nssPublicKey_AddRef (
NSSPublicKey *bk
@@ -286,6 +302,11 @@ nssPublicKey_GetID (
NSSPublicKey *vk
);
+NSS_EXTERN NSSKeyPairType
+nssPublicKey_GetKeyType (
+ NSSPublicKey *bk
+);
+
NSS_EXTERN NSSItem *
nssPublicKey_WrapSymKey (
NSSPublicKey *bk,
@@ -302,11 +323,44 @@ nssSymKey_AddRef (
);
NSS_EXTERN NSSVolatileDomain *
+nssSymKey_GetVolatileDomain (
+ NSSSymKey *mk,
+ PRStatus *statusOpt
+);
+
+NSS_EXTERN NSSVolatileDomain *
nssVolatileDomain_Create (
NSSTrustDomain *td,
NSSCallback *uhhOpt
);
+NSS_EXTERN NSSVolatileDomain *
+nssVolatileDomain_AddRef (
+ NSSVolatileDomain *vd
+);
+
+NSS_EXTERN PRStatus
+nssVolatileDomain_Destroy (
+ NSSVolatileDomain *vd
+);
+
+NSS_EXTERN NSSTrustDomain *
+nssVolatileDomain_GetTrustDomain (
+ NSSVolatileDomain *vd
+);
+
+NSS_EXTERN PRStatus
+nssVolatileDomain_ImportCert (
+ NSSVolatileDomain *vd,
+ NSSCert *c
+);
+
+NSS_EXTERN PRStatus
+nssVolatileDomain_ImportPrivateKey (
+ NSSVolatileDomain *vd,
+ NSSPrivateKey *vk
+);
+
NSS_EXTERN NSSCert **
nssVolatileDomain_FindCertsBySubject (
NSSVolatileDomain *vd,
@@ -316,6 +370,30 @@ nssVolatileDomain_FindCertsBySubject (
NSSArena *arenaOpt
);
+NSS_EXTERN PRStatus
+nssVolatileDomain_ImportPublicKey (
+ NSSVolatileDomain *vd,
+ NSSPublicKey *bk
+);
+
+NSS_EXTERN PRStatus
+nssVolatileDomain_ImportSymKey (
+ NSSVolatileDomain *vd,
+ NSSSymKey *mk
+);
+
+NSS_EXTERN NSSSymKey *
+nssVolatileDomain_UnwrapSymKey (
+ NSSVolatileDomain *vd,
+ const NSSAlgNParam *ap,
+ NSSPrivateKey *wrapKey,
+ NSSItem *wrappedKey,
+ NSSSymKeyType targetSymKeyType,
+ NSSCallback *uhhOpt,
+ NSSOperations operations,
+ NSSProperties properties
+);
+
NSS_EXTERN void
nssPublicKeyArray_Destroy (
NSSPublicKey **bkeys
diff --git a/security/nss/lib/pki/pkibase.c b/security/nss/lib/pki/pkibase.c
index 1a30da02c..e3e240547 100644
--- a/security/nss/lib/pki/pkibase.c
+++ b/security/nss/lib/pki/pkibase.c
@@ -45,25 +45,19 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
NSS_IMPLEMENT nssPKIObject *
nssPKIObject_Create (
- NSSArena *arenaOpt,
- nssCryptokiObject *instanceOpt,
NSSTrustDomain *td,
- NSSVolatileDomain *vdOpt /* XXX remove */
+ nssCryptokiObject *instanceOpt,
+ PRUint32 size
)
{
NSSArena *arena;
- nssArenaMark *mark = NULL;
nssPKIObject *object;
- if (arenaOpt) {
- arena = arenaOpt;
- mark = nssArena_Mark(arena);
- } else {
- arena = nssArena_Create();
- if (!arena) {
- return (nssPKIObject *)NULL;
- }
+
+ arena = nssArena_Create();
+ if (!arena) {
+ return (nssPKIObject *)NULL;
}
- object = nss_ZNEW(arena, nssPKIObject);
+ object = (nssPKIObject *)nss_ZAlloc(arena, size);
if (!object) {
goto loser;
}
@@ -77,18 +71,14 @@ nssPKIObject_Create (
if (nssPKIObject_AddInstance(object, instanceOpt) != PR_SUCCESS) {
goto loser;
}
+ if (instanceOpt->label) {
+ object->nickname = nssUTF8_Duplicate(instanceOpt->label, NULL);
+ }
}
PR_AtomicIncrement(&object->refCount);
- if (mark) {
- nssArena_Unmark(arena, mark);
- }
return object;
loser:
- if (mark) {
- nssArena_Release(arena, mark);
- } else {
- nssArena_Destroy(arena);
- }
+ nssArena_Destroy(arena);
return (nssPKIObject *)NULL;
}
@@ -106,6 +96,7 @@ nssPKIObject_Destroy (
}
/*nssVolatileDomain_Destroy(object->vd);*/
PZ_DestroyLock(object->lock);
+ nssUTF8_Destroy(object->nickname);
nssArena_Destroy(object->arena);
return PR_TRUE;
}
@@ -259,6 +250,26 @@ nssPKIObject_RemoveInstanceForToken (
return PR_SUCCESS;
}
+static nssPKIObject *
+nssPKIObject_Merge (
+ nssPKIObject *object1,
+ nssPKIObject *object2
+)
+{
+ PRUint32 i;
+ PZ_Lock(object2->lock);
+ for (i = 0; i < object2->numInstances; i++) {
+ if (!nssPKIObject_HasInstanceOnToken(object1,
+ object2->instances[i]->token))
+ {
+ (void)nssPKIObject_AddInstance(object1, object2->instances[i]);
+ }
+ }
+ PZ_Unlock(object2->lock);
+ return object1;
+}
+
+
/* this needs more thought on what will happen when there are multiple
* instances
*/
@@ -357,10 +368,7 @@ nssPKIObject_SetNickname (
PRUint32 i;
PRStatus status;
PZ_Lock(object->lock);
- if (object->vd) {
- object->tempName = nssUTF8_Duplicate(nickname, object->arena);
- status = object->tempName ? PR_SUCCESS : PR_FAILURE;
- } else {
+ if (tokenOpt) {
nssCryptokiObject *instance = NULL;
if (tokenOpt) {
for (i=0; i<object->numInstances; i++) {
@@ -378,6 +386,9 @@ nssPKIObject_SetNickname (
status = PR_FAILURE;
}
}
+ if (!object->nickname) {
+ object->nickname = nssUTF8_Duplicate(nickname, NULL);
+ }
PZ_Unlock(object->lock);
return status;
}
@@ -391,9 +402,7 @@ nssPKIObject_GetNickname (
PRUint32 i;
NSSUTF8 *nickname = NULL;
PZ_Lock(object->lock);
- if (object->vd) {
- return object->tempName;
- } else {
+ if (tokenOpt) {
for (i=0; i<object->numInstances; i++) {
if ((!tokenOpt && object->instances[i]->label) ||
(object->instances[i]->token == tokenOpt))
@@ -403,6 +412,8 @@ nssPKIObject_GetNickname (
break;
}
}
+ } else {
+ nickname = object->nickname;
}
PZ_Unlock(object->lock);
return nickname;
@@ -468,25 +479,6 @@ nssPKIObject_FindInstanceForAlgorithm (
return instance;
}
-NSS_IMPLEMENT PRBool
-nssPKIObject_IsOnToken (
- nssPKIObject *object,
- NSSToken *token
-)
-{
- PRUint32 i;
- PRBool foundIt = PR_FALSE;
- PZ_Lock(object->lock);
- for (i=0; i<object->numInstances; i++) {
- if (object->instances[i]->token == token) {
- foundIt = PR_TRUE;
- break;
- }
- }
- PZ_Unlock(object->lock);
- return foundIt;
-}
-
NSS_IMPLEMENT NSSTrustDomain *
nssPKIObject_GetTrustDomain (
nssPKIObject *object,
@@ -562,8 +554,7 @@ nssCertArray_CreateFromInstances (
return (NSSCert **)NULL;
}
for (i = 0; i < count; i++) {
- rvCerts[i] = nssCert_CreateFromInstance(instances[i], td,
- vdOpt, NULL);
+ rvCerts[i] = nssCert_CreateFromInstance(instances[i], td, vdOpt);
if (!rvCerts[i]) {
nssCertArray_Destroy(rvCerts); /* it's NULL-terminated */
return (NSSCert **)NULL;
@@ -594,6 +585,17 @@ NSSCertArray_Destroy (
nssCertArray_Destroy(certs);
}
+NSS_IMPLEMENT PRIntn
+nssObjectArray_Count (
+ void **objects
+)
+{
+ PRIntn n;
+ void **p;
+ for (p = objects, n = 0; p && *p; p++, n++);
+ return n;
+}
+
NSS_IMPLEMENT NSSCert **
nssCertArray_Duplicate (
NSSCert **certs,
@@ -668,7 +670,10 @@ nssCertArray_FindBestCert (
}
if (!bestCert) {
/* take the first cert with matching usage (if provided) */
- if (!usagesOpt || nssUsages_Match(usagesOpt, certUsages)) {
+ if (!usagesOpt ||
+ ((usagesOpt->ca & certUsages->ca) == usagesOpt->ca &&
+ (usagesOpt->peer & certUsages->peer) == usagesOpt->peer))
+ {
bestCert = nssCert_AddRef(c);
}
continue;
@@ -677,7 +682,10 @@ nssCertArray_FindBestCert (
* the correct usage, continue
* if ths cert does match usage, defer to time/policies
*/
- if (usagesOpt && !nssUsages_Match(usagesOpt, certUsages)) {
+ if (usagesOpt &&
+ ((usagesOpt->ca & certUsages->ca) != usagesOpt->ca ||
+ (usagesOpt->peer & certUsages->peer) != usagesOpt->peer))
+ {
continue;
}
}
@@ -777,6 +785,33 @@ nssPrivateKeyArray_Destroy (
nss_ZFreeIf(vkeys);
}
+NSS_IMPLEMENT NSSPublicKey **
+nssPublicKeyArray_CreateFromInstances (
+ nssCryptokiObject **instances,
+ NSSTrustDomain *td,
+ NSSVolatileDomain *vdOpt,
+ NSSArena *arenaOpt
+)
+{
+ PRIntn i, count;
+ nssCryptokiObject **ip;
+ NSSPublicKey **rvBKeys;
+
+ for (ip = instances, count = 0; *ip; ip++, count++);
+ rvBKeys = nss_ZNEWARRAY(arenaOpt, NSSPublicKey *, count + 1);
+ if (!rvBKeys) {
+ return (NSSPublicKey **)NULL;
+ }
+ for (i = 0; i < count; i++) {
+ rvBKeys[i] = nssPublicKey_CreateFromInstance(instances[i], td, vdOpt);
+ if (!rvBKeys[i]) {
+ nssPublicKeyArray_Destroy(rvBKeys); /* it's NULL-terminated */
+ return (NSSPublicKey **)NULL;
+ }
+ }
+ return rvBKeys;
+}
+
NSS_IMPLEMENT void
nssPublicKeyArray_Destroy (
NSSPublicKey **bkeys
@@ -791,809 +826,159 @@ nssPublicKeyArray_Destroy (
nss_ZFreeIf(bkeys);
}
-NSS_IMPLEMENT PRBool
-nssUsages_Match (
- const NSSUsages *usages,
- const NSSUsages *testUsages
+NSS_IMPLEMENT NSSPrivateKey **
+nssPrivateKeyArray_CreateFromInstances (
+ nssCryptokiObject **instances,
+ NSSTrustDomain *td,
+ NSSVolatileDomain *vdOpt,
+ NSSArena *arenaOpt
)
{
- return (((usages->ca & testUsages->ca) == usages->ca) &&
- ((usages->peer & testUsages->peer) == usages->peer));
-}
-
-/*
- * Object collections
- */
-
-typedef enum
-{
- pkiObjectType_Cert = 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:
- *
- * NSSCert ==> { 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;
- 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);
-};
+ PRIntn i, count;
+ nssCryptokiObject **ip;
+ NSSPrivateKey **rvVKeys;
-static nssPKIObjectCollection *
-nssPKIObjectCollection_Create (
- NSSTrustDomain *td
-)
-{
- NSSArena *arena;
- nssPKIObjectCollection *rvCollection = NULL;
- arena = nssArena_Create();
- if (!arena) {
- return (nssPKIObjectCollection *)NULL;
- }
- rvCollection = nss_ZNEW(arena, nssPKIObjectCollection);
- if (!rvCollection) {
- goto loser;
+ for (ip = instances, count = 0; *ip; ip++, count++);
+ rvVKeys = nss_ZNEWARRAY(arenaOpt, NSSPrivateKey *, count + 1);
+ if (!rvVKeys) {
+ return (NSSPrivateKey **)NULL;
}
- PR_INIT_CLIST(&rvCollection->head);
- rvCollection->arena = arena;
- rvCollection->td = td; /* XXX */
- 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);
+ for (i = 0; i < count; i++) {
+ rvVKeys[i] = nssPrivateKey_CreateFromInstance(instances[i], td, vdOpt);
+ if (!rvVKeys[i]) {
+ nssPrivateKeyArray_Destroy(rvVKeys); /* it's NULL-terminated */
+ return (NSSPrivateKey **)NULL;
}
- /* 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;
+ return rvVKeys;
}
-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;
-}
+/*
+ * Object table
+ */
-static pkiObjectCollectionNode *
-find_object_in_collection (
- nssPKIObjectCollection *collection,
- NSSItem *uid
-)
+struct nssPKIObjectTableStr
{
- 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;
-}
+ PZLock *lock;
+ PLHashTable *hash;
+};
-static pkiObjectCollectionNode *
-add_object_instance (
- nssPKIObjectCollection *collection,
- nssCryptokiObject *instance
+static PLHashNumber
+nss_pkiobject_hash (
+ const void *key
)
{
- 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.
- */
- 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);
- 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 a 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;
+ int i, j;
+ PLHashNumber h;
+ nssPKIObject *pkio = (nssPKIObject *)key;
+ h = 0;
+ for (i = 0; i < pkio->numIDs; i++) {
+ for (j=0; j < pkio->uid[i]->size; j++) {
+ h = (h >> 28) ^ (h << 4) ^
+ ((unsigned char *)pkio->uid[i]->data)[i];
}
- node->object = nssPKIObject_Create(NULL, instance,
- collection->td, NULL);
- 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;
+ return h;
}
-NSS_IMPLEMENT PRStatus
-nssPKIObjectCollection_AddInstances (
- nssPKIObjectCollection *collection,
- nssCryptokiObject **instances,
- PRUint32 numInstances
-)
+static int
+nss_compare_pkiobjects(const void *v1, const void *v2)
{
- PRStatus status = PR_SUCCESS;
- PRUint32 i = 0;
- pkiObjectCollectionNode *node;
- if (instances) {
- for (; *instances; instances++, i++) {
- if (numInstances > 0 && i == numInstances) {
- break;
- }
- node = add_object_instance(collection, *instances);
- if (node == NULL) {
- goto loser;
- }
- }
+ int i;
+ int rv = 0;
+ nssPKIObject *pkio1 = (nssPKIObject *)v1;
+ nssPKIObject *pkio2 = (nssPKIObject *)v2;
+ if (pkio1->objectType != pkio2->objectType) {
+ return 1;
}
- return status;
-loser:
- /* free the remaining instances */
- for (; *instances; instances++, i++) {
- if (numInstances > 0 && i == numInstances) {
+ for (i = 0; i < pkio1->numIDs; i++) {
+ if (!nssItem_Equal(pkio1->uid[i], pkio1->uid[i], NULL)) {
+ rv = 1;
break;
}
- nssCryptokiObject_Destroy(*instances);
}
- return PR_FAILURE;
+ return rv;
}
-static void
-nssPKIObjectCollection_RemoveNode (
- nssPKIObjectCollection *collection,
- pkiObjectCollectionNode *node
+NSS_IMPLEMENT nssPKIObjectTable *
+nssPKIObjectTable_Create (
+ NSSArena *arena
)
{
- PR_REMOVE_LINK(&node->link);
- collection->size--;
-}
+ nssPKIObjectTable *rvTable;
-static PRStatus
-nssPKIObjectCollection_GetObjects (
- nssPKIObjectCollection *collection,
- nssPKIObject **rvObjects,
- PRUint32 rvSize
-)
-{
- PRUint32 i = 0;
- PRCList *link = PR_NEXT_LINK(&collection->head);
- pkiObjectCollectionNode *node;
- 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);
- continue;
- }
- node->haveObject = PR_TRUE;
- }
- rvObjects[i++] = nssPKIObject_AddRef(node->object);
- link = PR_NEXT_LINK(link);
+ rvTable = nss_ZNEW(arena, nssPKIObjectTable);
+ if (rvTable == NULL) {
+ return (nssPKIObjectTable *)NULL;
}
- 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_Cert:
- status = (*callback->func.cert)((NSSCert *)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);
+ rvTable->lock = PZ_NewLock(nssILockOther);
+ if (rvTable->lock == NULL) {
+ return (nssPKIObjectTable *)NULL;
}
- return PR_SUCCESS;
-}
-NSS_IMPLEMENT PRStatus
-nssPKIObjectCollection_AddInstanceAsObject (
- nssPKIObjectCollection *collection,
- nssCryptokiObject *instance
-)
-{
- pkiObjectCollectionNode *node;
- node = add_object_instance(collection, instance);
- 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;
+ rvTable->hash = PL_NewHashTable(0,
+ nss_pkiobject_hash,
+ nss_compare_pkiobjects,
+ PL_CompareValues,
+ NULL, NULL);
+ if (rvTable->hash == NULL) {
+ PZ_DestroyLock(rvTable->lock);
+ return (nssPKIObjectTable *)NULL;
}
- return PR_SUCCESS;
-}
-
-/*
- * Cert collections
- */
-
-static void
-cert_destroyObject(nssPKIObject *o)
-{
- NSSCert *c = (NSSCert *)o;
- nssCert_Destroy(c);
-}
-
-static PRStatus
-cert_getUIDFromObject(nssPKIObject *o, NSSItem *uid)
-{
- NSSCert *c = (NSSCert *)o;
- NSSDER *issuer, *serial;
- issuer = nssCert_GetIssuer(c);
- serial = nssCert_GetSerialNumber(c);
- uid[0] = *issuer;
- uid[1] = *serial;
- return PR_SUCCESS;
-}
-
-static PRStatus
-cert_getUIDFromInstance(nssCryptokiObject *instance, NSSItem *uid,
- NSSArena *arena)
-{
- return nssCryptokiCert_GetAttributes(instance,
- arena, /* arena */
- NULL, /* type */
- NULL, /* id */
- NULL, /* encoding */
- &uid[0], /* issuer */
- &uid[1], /* serial */
- NULL, /* subject */
- NULL); /* email */
-}
-
-static nssPKIObject *
-cert_createObject(nssPKIObject *o)
-{
- NSSCert *cert;
- cert = nssCert_Create(o);
- return (nssPKIObject *)cert;
+ return rvTable;
}
-NSS_IMPLEMENT nssPKIObjectCollection *
-nssCertCollection_Create (
- NSSTrustDomain *td,
- NSSCert **certsOpt
-)
-{
- PRStatus status;
- nssPKIObjectCollection *collection;
- collection = nssPKIObjectCollection_Create(td);
- collection->objectType = pkiObjectType_Cert;
- 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 NSSCert **
-nssPKIObjectCollection_GetCerts (
- nssPKIObjectCollection *collection,
- NSSCert **rvOpt,
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-)
-{
- PRStatus status;
- PRUint32 rvSize;
- PRBool allocated = PR_FALSE;
- if (collection->size == 0) {
- return (NSSCert **)NULL;
- }
- if (maximumOpt == 0) {
- rvSize = collection->size;
- } else {
- rvSize = PR_MIN(collection->size, maximumOpt);
- }
- if (!rvOpt) {
- rvOpt = nss_ZNEWARRAY(arenaOpt, NSSCert *, rvSize + 1);
- if (!rvOpt) {
- return (NSSCert **)NULL;
- }
- allocated = PR_TRUE;
- }
- status = nssPKIObjectCollection_GetObjects(collection,
- (nssPKIObject **)rvOpt,
- rvSize);
- if (status != PR_SUCCESS) {
- if (allocated) {
- nss_ZFreeIf(rvOpt);
- }
- return (NSSCert **)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);
- 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,
- arena, /* arena */
- &uid[0], /* encoding */
- NULL, /* url */
- NULL); /* isKRL */
-}
-
-static nssPKIObject *
-crl_createObject(nssPKIObject *o)
-{
- return (nssPKIObject *)nssCRL_Create(o);
-}
-
-NSS_IMPLEMENT nssPKIObjectCollection *
-nssCRLCollection_Create (
- NSSTrustDomain *td,
- NSSCRL **crlsOpt
+NSS_IMPLEMENT void
+nssPKIObjectTable_Destroy (
+ nssPKIObjectTable *table
)
{
- PRStatus status;
- nssPKIObjectCollection *collection;
- collection = nssPKIObjectCollection_Create(td);
- 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;
+ PZ_DestroyLock(table->lock);
+ PL_HashTableDestroy(table->hash);
}
-NSS_IMPLEMENT NSSCRL **
-nssPKIObjectCollection_GetCRLs (
- nssPKIObjectCollection *collection,
- NSSCRL **rvOpt,
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
+NSS_IMPLEMENT nssPKIObject *
+nssPKIObjectTable_Add (
+ nssPKIObjectTable *table,
+ nssPKIObject *object
)
{
- 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;
-}
-
-/*
- * PrivateKey collections
- */
-
-static void
-privkey_destroyObject(nssPKIObject *o)
-{
- NSSPrivateKey *pvk = (NSSPrivateKey *)o;
- nssPrivateKey_Destroy(pvk);
-}
-
-static PRStatus
-privkey_getUIDFromObject(nssPKIObject *o, NSSItem *uid)
-{
- NSSPrivateKey *pvk = (NSSPrivateKey *)o;
- NSSItem *id;
- id = nssPrivateKey_GetID(pvk);
- uid[0] = *id;
- return PR_SUCCESS;
-}
-
-static PRStatus
-privkey_getUIDFromInstance(nssCryptokiObject *instance, NSSItem *uid,
- NSSArena *arena)
-{
- return nssCryptokiPrivateKey_GetAttributes(instance,
- arena,
- NULL, /* type */
- &uid[0]);
-}
+ PLHashEntry *he;
+ nssPKIObject *pkio;
-static nssPKIObject *
-privkey_createObject(nssPKIObject *o)
-{
- NSSPrivateKey *pvk;
- pvk = nssPrivateKey_Create(o);
- return (nssPKIObject *)pvk;
-}
-
-NSS_IMPLEMENT nssPKIObjectCollection *
-nssPrivateKeyCollection_Create (
- NSSTrustDomain *td,
- NSSPrivateKey **pvkOpt
-)
-{
- PRStatus status;
- nssPKIObjectCollection *collection;
- collection = nssPKIObjectCollection_Create(td);
- collection->objectType = pkiObjectType_PrivateKey;
- collection->destroyObject = privkey_destroyObject;
- collection->getUIDFromObject = privkey_getUIDFromObject;
- collection->getUIDFromInstance = privkey_getUIDFromInstance;
- collection->createObject = privkey_createObject;
- if (pvkOpt) {
- for (; *pvkOpt; pvkOpt++) {
- nssPKIObject *o = (nssPKIObject *)(*pvkOpt);
- status = nssPKIObjectCollection_AddObject(collection, o);
- }
- }
- return collection;
-}
+ PZ_Lock(table->lock);
-NSS_IMPLEMENT NSSPrivateKey **
-nssPKIObjectCollection_GetPrivateKeys (
- nssPKIObjectCollection *collection,
- NSSPrivateKey **rvOpt,
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-)
-{
- PRStatus status;
- PRUint32 rvSize;
- PRBool allocated = PR_FALSE;
- if (collection->size == 0) {
- return (NSSPrivateKey **)NULL;
- }
- if (maximumOpt == 0) {
- rvSize = collection->size;
+ pkio = (nssPKIObject *)PL_HashTableLookup(table->hash, object);
+ if (pkio) {
+ pkio = nssPKIObject_Merge(pkio, object);
} else {
- rvSize = PR_MIN(collection->size, maximumOpt);
- }
- if (!rvOpt) {
- rvOpt = nss_ZNEWARRAY(arenaOpt, NSSPrivateKey *, rvSize + 1);
- if (!rvOpt) {
- return (NSSPrivateKey **)NULL;
- }
- allocated = PR_TRUE;
- }
- status = nssPKIObjectCollection_GetObjects(collection,
- (nssPKIObject **)rvOpt,
- rvSize);
- if (status != PR_SUCCESS) {
- if (allocated) {
- nss_ZFreeIf(rvOpt);
+ he = PL_HashTableAdd(table->hash, object, object);
+ if( (PLHashEntry *)NULL == he ) {
+ nss_SetError(NSS_ERROR_NO_MEMORY);
+ pkio = NULL;
+ } else {
+ pkio = object;
}
- return (NSSPrivateKey **)NULL;
}
- return rvOpt;
-}
-
-/*
- * PublicKey collections
- */
-static void
-pubkey_destroyObject(nssPKIObject *o)
-{
- NSSPublicKey *pubk = (NSSPublicKey *)o;
- nssPublicKey_Destroy(pubk);
-}
-
-static PRStatus
-pubkey_getUIDFromObject(nssPKIObject *o, NSSItem *uid)
-{
- NSSPublicKey *pubk = (NSSPublicKey *)o;
- NSSItem *id;
- id = nssPublicKey_GetID(pubk);
- uid[0] = *id;
- return PR_SUCCESS;
-}
+ PZ_Unlock(table->lock);
-static PRStatus
-pubkey_getUIDFromInstance(nssCryptokiObject *instance, NSSItem *uid,
- NSSArena *arena)
-{
- return nssCryptokiPublicKey_GetAttributes(instance,
- arena,
- NULL, /* type */
- &uid[0]);
-}
-
-static nssPKIObject *
-pubkey_createObject(nssPKIObject *o)
-{
- NSSPublicKey *pubk;
- pubk = nssPublicKey_Create(o);
- return (nssPKIObject *)pubk;
+ return pkio;
}
-NSS_IMPLEMENT nssPKIObjectCollection *
-nssPublicKeyCollection_Create (
- NSSTrustDomain *td,
- NSSPublicKey **pubkOpt
+NSS_IMPLEMENT PRStatus
+nssPKIObjectTable_Remove (
+ nssPKIObjectTable *table,
+ nssPKIObject *object
)
{
- PRStatus status;
- nssPKIObjectCollection *collection;
- collection = nssPKIObjectCollection_Create(td);
- collection->objectType = pkiObjectType_PublicKey;
- collection->destroyObject = pubkey_destroyObject;
- collection->getUIDFromObject = pubkey_getUIDFromObject;
- collection->getUIDFromInstance = pubkey_getUIDFromInstance;
- collection->createObject = pubkey_createObject;
- if (pubkOpt) {
- for (; *pubkOpt; pubkOpt++) {
- nssPKIObject *o = (nssPKIObject *)(*pubkOpt);
- status = nssPKIObjectCollection_AddObject(collection, o);
- }
- }
- return collection;
-}
-NSS_IMPLEMENT NSSPublicKey **
-nssPKIObjectCollection_GetPublicKeys (
- nssPKIObjectCollection *collection,
- NSSPublicKey **rvOpt,
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-)
-{
PRStatus status;
- PRUint32 rvSize;
- PRBool allocated = PR_FALSE;
- if (collection->size == 0) {
- return (NSSPublicKey **)NULL;
- }
- if (maximumOpt == 0) {
- rvSize = collection->size;
- } else {
- rvSize = PR_MIN(collection->size, maximumOpt);
- }
- if (!rvOpt) {
- rvOpt = nss_ZNEWARRAY(arenaOpt, NSSPublicKey *, rvSize + 1);
- if (!rvOpt) {
- return (NSSPublicKey **)NULL;
- }
- allocated = PR_TRUE;
- }
- status = nssPKIObjectCollection_GetObjects(collection,
- (nssPKIObject **)rvOpt,
- rvSize);
- if (status != PR_SUCCESS) {
- if (allocated) {
- nss_ZFreeIf(rvOpt);
- }
- return (NSSPublicKey **)NULL;
- }
- return rvOpt;
+ PZ_Lock(table->lock);
+ status = PL_HashTableRemove(table->hash, object);
+ PZ_Unlock(table->lock);
+ return status;
}
NSS_IMPLEMENT PRStatus
@@ -1682,11 +1067,11 @@ nssPKIObjectCreator_GenerateKeyPair (
}
#endif
- *pbkOpt = nssPublicKey_CreateFromInstance(bkey, creator->td, NULL, NULL);
+ *pbkOpt = nssPublicKey_CreateFromInstance(bkey, creator->td, NULL);
if (!*pbkOpt) {
goto loser;
}
- *pvkOpt = nssPrivateKey_CreateFromInstance(vkey, creator->td, NULL, NULL);
+ *pvkOpt = nssPrivateKey_CreateFromInstance(vkey, creator->td, NULL);
if (!*pvkOpt) {
goto loser;
}
diff --git a/security/nss/lib/pki/pkidb.c b/security/nss/lib/pki/pkidb.c
new file mode 100644
index 000000000..814c16a22
--- /dev/null
+++ b/security/nss/lib/pki/pkidb.c
@@ -0,0 +1,924 @@
+/*
+ * 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 Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+#include "mcom_db.h"
+
+#ifndef BASE_H
+#include "base.h"
+#endif /* BASE_H */
+
+#ifndef PKIM_H
+#include "pkim.h"
+#endif /* PKIM_H */
+
+#define DBM_DEFAULT 0
+#define DBS_BLOCK_SIZE (16*1024) /* XXX not doing blobbing yet */
+#define DBS_CACHE_SIZE (DBS_BLOCK_SIZE * 8)
+
+static const HASHINFO s_db_hash_info = {
+ DBS_BLOCK_SIZE, /* bucket size, must be greater than = to
+ * or maximum record size (+ header)
+ * we allow before blobing
+ */
+ DBM_DEFAULT, /* Fill Factor */
+ DBM_DEFAULT, /* number of elements */
+ DBS_CACHE_SIZE, /* cache size */
+ DBM_DEFAULT, /* hash function */
+ DBM_DEFAULT, /* byte order */
+};
+
+struct nssPKIDatabaseStr
+{
+ NSSTrustDomain *td;
+ PZLock *lock;
+ DB *db;
+};
+
+#define PKIDB_VERSION 10
+
+#define ROWID_CERT_HEADER 1
+#define ROWID_SUBJECT_HEADER 2
+#define ROWID_NICKNAME_HEADER 3
+#define ROWID_EMAIL_HEADER 4
+
+#define PKIDB_IS_CERT_RECORD(rowID) \
+ (((unsigned char *)(rowID)->data)[0] == ROWID_CERT_HEADER)
+
+#define PAYLOAD_HEADER_LENGTH 3
+#define PAYLOAD_CERT_HEADER 1
+#define PAYLOAD_SUBJECT_HEADER 2
+#define PAYLOAD_NICKNAME_HEADER 3
+#define PAYLOAD_EMAIL_HEADER 4
+
+#define CERT_PAYLOAD_TRUST_OFFSET PAYLOAD_HEADER_LENGTH
+#define TRUST_RECORD_LENGTH 16
+
+#define SET_DBT_BYTE(dbt, index, val) \
+ ((unsigned char *)(dbt)->data)[index] = val
+
+#define SET_DBT_INT(dbt, index, num) \
+ nsslibc_memcpy(((unsigned char *)(dbt)->data) + index, &num, sizeof(num))
+
+#define SET_DBT_BUF(dbt, index, buf, len) \
+ nsslibc_memcpy(((unsigned char *)(dbt)->data) + index, buf, len)
+
+#define SET_DBT_ITEM(dbt, index, it) \
+ nsslibc_memcpy(((unsigned char *)(dbt)->data) + index, \
+ (it)->data, (it)->size)
+
+#define GET_DBT_INT(dbt, index, num) \
+ num = *(PRUint32 *)(((unsigned char *)(dbt)->data) + index)
+
+#define GET_DBT_BUF(dbt, index, buf) \
+ buf = ((unsigned char *)(dbt)->data) + index
+
+static PRStatus
+write_record(nssPKIDatabase *pkidb, DBT *rowID, DBT *payload)
+{
+ int dberr;
+ PZ_Lock(pkidb->lock);
+ dberr = pkidb->db->put(pkidb->db, rowID, payload, 0);
+ PZ_Unlock(pkidb->lock);
+ return (dberr == 0) ? PR_SUCCESS : PR_FAILURE;
+}
+
+static PRStatus
+delete_record(nssPKIDatabase *pkidb, DBT *rowID)
+{
+ int dberr;
+ PZ_Lock(pkidb->lock);
+ dberr = pkidb->db->del(pkidb->db, rowID, 0);
+ PZ_Unlock(pkidb->lock);
+ return (dberr == 0) ? PR_SUCCESS : PR_FAILURE;
+}
+
+static PRStatus
+make_cert_rowid_from_issuer_serial(DBT *rowID,
+ NSSBER *issuer, NSSBER *serial,
+ NSSArena *arenaOpt)
+{
+ int i;
+ rowID->size = 1 + issuer->size + serial->size;
+ rowID->data = nss_ZAlloc(arenaOpt, rowID->size);
+ if (!rowID->data) {
+ return PR_FAILURE;
+ }
+ i = 0;
+ SET_DBT_BYTE(rowID, 0, ROWID_CERT_HEADER); i++;
+ SET_DBT_ITEM(rowID, i, issuer); i += issuer->size;
+ SET_DBT_ITEM(rowID, i, serial); i += serial->size;
+ return PR_SUCCESS;
+}
+
+static PRStatus
+make_cert_rowid(DBT *rowID, NSSCert *cert, NSSArena *arenaOpt)
+{
+ NSSBER *issuer, *serial;
+ issuer = nssCert_GetIssuer(cert);
+ serial = nssCert_GetSerialNumber(cert);
+ return make_cert_rowid_from_issuer_serial(rowID, issuer, serial, arenaOpt);
+}
+
+static PRStatus
+write_cert_record(nssPKIDatabase *pkidb, DBT *rowID, NSSCert *certOpt,
+ NSSUTF8 *nicknameOpt, nssTrust *trustOpt,
+ NSSArena *arena)
+{
+ DBT payload;
+ NSSBER *ber;
+ PRUint32 size;
+ PRUint32 berSize;
+ PRUint32 nicknameLen;
+ int i;
+
+ if (certOpt) {
+ ber = nssCert_GetEncoding(certOpt);
+ berSize = ber->size;
+ } else {
+ berSize = 0;
+ }
+ nicknameLen = nicknameOpt ? nssUTF8_Length(nicknameOpt, NULL) : 0;
+
+ payload.size = PAYLOAD_HEADER_LENGTH +
+ TRUST_RECORD_LENGTH +
+ 4 + berSize +
+ 4 + nicknameLen;
+
+ payload.data = nss_ZAlloc(arena, payload.size);
+ if (!payload.data) {
+ return PR_FAILURE;
+ }
+
+ /* HEADER */
+ i = 0;
+ SET_DBT_BYTE(&payload, i, PKIDB_VERSION); i++;
+ SET_DBT_BYTE(&payload, i, PAYLOAD_CERT_HEADER); i++;
+ SET_DBT_BYTE(&payload, i, 0); i++; /* flags */
+ /* TRUST */
+ if (trustOpt) {
+ SET_DBT_INT(&payload, i, trustOpt->trustedUsages.ca); i += 4;
+ SET_DBT_INT(&payload, i, trustOpt->trustedUsages.peer); i += 4;
+ SET_DBT_INT(&payload, i, trustOpt->notTrustedUsages.ca); i += 4;
+ SET_DBT_INT(&payload, i, trustOpt->notTrustedUsages.peer); i += 4;
+ } else {
+ i += TRUST_RECORD_LENGTH; /* skip it */
+ }
+ /* BER size */
+ size = PR_htonl(berSize);
+ SET_DBT_INT(&payload, i, size); i += 4;
+ /* nickname length */
+ size = PR_htonl(nicknameLen);
+ SET_DBT_INT(&payload, i, size); i += 4;
+ /* BER data */
+ if (certOpt) {
+ SET_DBT_ITEM(&payload, i, ber); i += berSize;
+ }
+ /* nickname */
+ if (nicknameOpt) {
+ SET_DBT_BUF(&payload, i, nicknameOpt, nicknameLen); i += nicknameLen;
+ }
+ /* always overwrite? */
+ return write_record(pkidb, rowID, &payload);
+}
+
+static PRStatus
+decode_cert_payload(DBT *payload, NSSBER *ber, NSSItem *nick,
+ nssTrust *trustOpt)
+{
+ int i;
+ PRUint32 size;
+
+ i = PAYLOAD_HEADER_LENGTH; /* skip the header */
+ if (trustOpt) {
+ GET_DBT_INT(payload, i, trustOpt->trustedUsages.ca); i += 4;
+ GET_DBT_INT(payload, i, trustOpt->trustedUsages.peer); i += 4;
+ GET_DBT_INT(payload, i, trustOpt->notTrustedUsages.ca); i += 4;
+ GET_DBT_INT(payload, i, trustOpt->notTrustedUsages.peer); i += 4;
+ } else {
+ i += TRUST_RECORD_LENGTH; /* skip it */
+ }
+ GET_DBT_INT(payload, i, size); i += 4;
+ ber->size = PR_ntohl(size);
+ GET_DBT_INT(payload, i, size); i += 4;
+ nick->size = PR_ntohl(size);
+ if (ber->size > 0) {
+ GET_DBT_BUF(payload, i, ber->data); i += ber->size;
+ }
+ if (nick->size > 0) {
+ GET_DBT_BUF(payload, i, nick->data); i += nick->size;
+ }
+ return PR_SUCCESS;
+}
+
+static PRStatus
+make_subject_rowid(DBT *rowID, NSSBER *subject, NSSArena *arenaOpt)
+{
+ int i;
+ rowID->size = 1 + subject->size;
+ rowID->data = nss_ZAlloc(arenaOpt, rowID->size);
+ if (!rowID->data) {
+ return PR_FAILURE;
+ }
+ i = 0;
+ SET_DBT_BYTE(rowID, 0, ROWID_SUBJECT_HEADER); i++;
+ SET_DBT_ITEM(rowID, i, subject); i += subject->size;
+ return PR_SUCCESS;
+}
+
+static PRStatus
+write_subject_record(nssPKIDatabase *pkidb, DBT *rowID,
+ NSSCert *cert, NSSArena *arena)
+{
+ DBT certRowID, payload, oldPayload;
+ int dberr;
+ PRUint32 size;
+ PRBool haveRecord;
+ int i, j, numCerts, numOldCerts;
+
+ PZ_Lock(pkidb->lock);
+ dberr = pkidb->db->get(pkidb->db, rowID, &payload, 0);
+ PZ_Unlock(pkidb->lock);
+ if (dberr < 0) {
+ return PR_FAILURE;
+ }
+ haveRecord = (dberr == 0) ? PR_TRUE : PR_FALSE;
+
+ /* XXX redundant */
+ make_cert_rowid(&certRowID, cert, arena);
+ if (haveRecord) {
+ payload.size = 4 + certRowID.size + oldPayload.size;
+ } else {
+ payload.size = PAYLOAD_HEADER_LENGTH +
+ 4 +
+ 4 + certRowID.size;
+ }
+
+ payload.data = nss_ZAlloc(arena, payload.size);
+ if (!payload.data) {
+ nss_ZFreeIf(certRowID.data);
+ return PR_FAILURE;
+ }
+
+ /* HEADER */
+ i = 0;
+ SET_DBT_BYTE(&payload, i, PKIDB_VERSION); i++;
+ SET_DBT_BYTE(&payload, i, PAYLOAD_SUBJECT_HEADER); i++;
+ SET_DBT_BYTE(&payload, i, 0); i++; /* flags */
+ /* # of cert rowIDs */
+ if (haveRecord) {
+ GET_DBT_INT(&payload, i, numOldCerts); j += 4;
+ } else {
+ numOldCerts = 0;
+ }
+ numCerts = PR_htonl(numOldCerts + 1);
+ SET_DBT_INT(&payload, i, numCerts); i += 4;
+ /* lengths of cert rowIDs */
+ if (haveRecord) {
+ unsigned char *oldLengths;
+ GET_DBT_BUF(&oldPayload, i, oldLengths);
+ SET_DBT_BUF(&payload, i, oldLengths, 4 * numOldCerts);
+ i += 4 * numOldCerts;
+ }
+ size = PR_htonl(certRowID.size);
+ SET_DBT_INT(&payload, i, size); i += 4;
+ /* cert rowIDs */
+ if (haveRecord) {
+ unsigned char *oldCertRowIDs;
+ int j = i - 4; /* -4 because we added one length */
+ int remaining = oldPayload.size - j;
+ GET_DBT_BUF(&oldPayload, j, oldCertRowIDs);
+ SET_DBT_BUF(&payload, i, oldCertRowIDs, remaining);
+ i += remaining;
+ }
+ SET_DBT_ITEM(&payload, i, &certRowID); i += certRowID.size;
+ nss_ZFreeIf(certRowID.data);
+ return write_record(pkidb, rowID, &payload);
+}
+
+static NSSCert *
+get_cert_from_rowid(nssPKIDatabase *pkidb, DBT *rowID)
+{
+ DBT payload;
+ int dberr;
+ PRStatus status;
+ NSSBER ber, nick;
+ nssTrust trust;
+ NSSCert *cert = NULL;
+
+ PZ_Lock(pkidb->lock);
+ dberr = pkidb->db->get(pkidb->db, rowID, &payload, 0);
+ PZ_Unlock(pkidb->lock);
+
+ if (dberr == 0) {
+ status = decode_cert_payload(&payload, &ber, &nick, &trust);
+ if (status == PR_SUCCESS) {
+ cert = nssCert_Decode(&ber, &nick, &trust, pkidb->td, NULL);
+ }
+ }
+ return cert;
+}
+
+static PRUint32
+get_num_certs_from_subject_payload(DBT *payload)
+{
+ PRUint32 numCerts;
+ GET_DBT_INT(payload, PAYLOAD_HEADER_LENGTH, numCerts);
+ numCerts = PR_ntohl(numCerts);
+ return numCerts;
+}
+
+static PRStatus
+get_cert_rowid_from_subject_payload(DBT *payload, int i, int *last,
+ int numCerts, DBT *rowID)
+{
+ int offset = PAYLOAD_HEADER_LENGTH + 4 + 4 * i;
+ GET_DBT_INT(payload, offset, rowID->size);
+ rowID->size = PR_ntohl(rowID->size);
+ if (*last == 0) {
+ offset = PAYLOAD_HEADER_LENGTH + 4 + 4 * numCerts;
+ } else {
+ offset = *last;
+ }
+ GET_DBT_BUF(payload, offset, rowID->data);
+ *last += rowID->size;
+ return PR_SUCCESS;
+}
+
+static NSSCert **
+get_certs_from_subject_record(nssPKIDatabase *pkidb, DBT *subjectRowID,
+ NSSArena *arenaOpt)
+{
+ DBT payload, certRowID;
+ int dberr;
+ PRStatus status;
+ NSSCert **certs = NULL;
+ int i, last = 0;
+ int numCerts;
+
+ PZ_Lock(pkidb->lock);
+ dberr = pkidb->db->get(pkidb->db, subjectRowID, &payload, 0);
+ PZ_Unlock(pkidb->lock);
+
+ if (dberr == 0) {
+ numCerts = get_num_certs_from_subject_payload(&payload);
+ if (numCerts == 0) {
+ return (NSSCert **)NULL;
+ }
+ certs = nss_ZNEWARRAY(arenaOpt, NSSCert *, numCerts + 1);
+ if (!certs) {
+ return (NSSCert **)NULL;
+ }
+ for (i = 0; i < numCerts; i++) {
+ status = get_cert_rowid_from_subject_payload(&payload, i,
+ &last, numCerts,
+ &certRowID);
+ if (status == PR_SUCCESS) {
+ certs[i] = get_cert_from_rowid(pkidb, &certRowID);
+ if (!certs[i]) {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ }
+ return certs;
+}
+
+static PRStatus
+make_nickname_rowid(DBT *rowID, NSSUTF8 *nickname, NSSArena *arenaOpt)
+{
+ int i;
+ PRUint32 nickLen = nssUTF8_Length(nickname, NULL);
+ rowID->size = 1 + nickLen;
+ rowID->data = nss_ZAlloc(arenaOpt, rowID->size);
+ if (!rowID->data) {
+ return PR_FAILURE;
+ }
+ i = 0;
+ SET_DBT_BYTE(rowID, 0, ROWID_NICKNAME_HEADER); i++;
+ SET_DBT_BUF( rowID, i, nickname, nickLen); i += nickLen;
+ return PR_SUCCESS;
+}
+
+static PRStatus
+write_nickname_record(nssPKIDatabase *pkidb, DBT *rowID, NSSCert *cert,
+ NSSArena *arena)
+{
+ DBT payload;
+ DBT subjectRowID;
+ PRStatus status;
+ NSSBER *berSubject;
+ PRUint32 size;
+ int i;
+
+ berSubject = nssCert_GetSubject(cert);
+ status = make_subject_rowid(&subjectRowID, berSubject, arena);
+ if (status == PR_FAILURE) {
+ return status;
+ }
+
+ payload.size = PAYLOAD_HEADER_LENGTH + 4 + 1 + berSubject->size;
+
+ payload.data = nss_ZAlloc(arena, payload.size);
+ if (!payload.data) {
+ return PR_FAILURE;
+ }
+
+ /* HEADER */
+ i = 0;
+ SET_DBT_BYTE(&payload, i, PKIDB_VERSION); i++;
+ SET_DBT_BYTE(&payload, i, PAYLOAD_NICKNAME_HEADER); i++;
+ SET_DBT_BYTE(&payload, i, 0); i++; /* flags */
+ /* BER subject size */
+ size = PR_htonl(subjectRowID.size);
+ SET_DBT_INT(&payload, i, size); i += 4;
+ /* BER subject data */
+ SET_DBT_ITEM(&payload, i, &subjectRowID); i += subjectRowID.size;
+ /* always overwrite? */
+ return write_record(pkidb, rowID, &payload);
+}
+
+static NSSCert **
+get_certs_from_nickname_record(nssPKIDatabase *pkidb, DBT *rowID,
+ NSSArena *arenaOpt)
+{
+ DBT payload;
+ DBT subjectRowID;
+ int dberr;
+
+ PZ_Lock(pkidb->lock);
+ dberr = pkidb->db->get(pkidb->db, rowID, &payload, 0);
+ PZ_Unlock(pkidb->lock);
+
+ if (dberr == 0) {
+ int i = 0;
+ i += PAYLOAD_HEADER_LENGTH;
+ GET_DBT_INT(&payload, i, subjectRowID.size); i += 4;
+ subjectRowID.size = PR_ntohl(subjectRowID.size);
+ GET_DBT_BUF(&payload, i, subjectRowID.data); i += subjectRowID.size;
+ return get_certs_from_subject_record(pkidb, &subjectRowID, arenaOpt);
+ }
+ return (NSSCert **)NULL;
+}
+
+/* XXX needs nickname fixes above */
+static PRStatus
+make_email_rowid(DBT *rowID, NSSASCII7 *email, NSSArena *arenaOpt)
+{
+ int i;
+ PRUint32 emailLen = nssUTF8_Length(email, NULL);
+ rowID->size = 1 + emailLen;
+ rowID->data = nss_ZAlloc(arenaOpt, rowID->size);
+ if (!rowID->data) {
+ return PR_FAILURE;
+ }
+ i = 0;
+ SET_DBT_BYTE(rowID, 0, ROWID_EMAIL_HEADER); i++;
+ SET_DBT_BUF( rowID, i, email, emailLen); i += emailLen;
+ return PR_SUCCESS;
+}
+
+static NSSCert **
+get_certs_from_email_record(nssPKIDatabase *pkidb, DBT *rowID,
+ NSSArena *arenaOpt)
+{
+ DBT payload;
+ int dberr;
+
+ PZ_Lock(pkidb->lock);
+ dberr = pkidb->db->get(pkidb->db, rowID, &payload, 0);
+ PZ_Unlock(pkidb->lock);
+
+ if (dberr == 0) {
+ return get_certs_from_subject_record(pkidb, &payload, arenaOpt);
+ }
+ return (NSSCert **)NULL;
+}
+
+#define DB_RDONLY O_RDONLY
+#define DB_RDWR O_RDWR
+#define DB_CREATE O_CREAT
+#define PKIDB_FLAGS_READ_ONLY 1
+
+NSS_IMPLEMENT nssPKIDatabase *
+nssPKIDatabase_Open (
+ NSSTrustDomain *td,
+ const NSSUTF8 *path,
+ PRUint32 flags
+)
+{
+ nssPKIDatabase *rvDB;
+ PRIntn dbFlags;
+ const char *dbName = "certX.db"; /* XXX */
+ char *filename;
+ PRUint32 pathLen, dbNameLen;
+
+ pathLen = nssUTF8_Length(path, NULL);
+ dbNameLen = nssUTF8_Length(dbName, NULL);
+ filename = nss_ZAlloc(NULL, pathLen + dbNameLen + 2);
+ if (!filename) {
+ return (nssPKIDatabase *)NULL;
+ }
+ nsslibc_memcpy(filename, path, pathLen);
+ filename[pathLen] = '/';
+ nsslibc_memcpy(filename + pathLen + 1, dbName, dbNameLen);
+ filename[pathLen + 1 + dbNameLen] = '\0';
+
+ rvDB = nss_ZNEW(NULL, nssPKIDatabase);
+ if (!rvDB) {
+ nssUTF8_Destroy(filename);
+ return (nssPKIDatabase *)NULL;
+ }
+
+ rvDB->lock = PZ_NewLock(nssILockOther);
+ if (!rvDB) {
+ nssUTF8_Destroy(filename);
+ nss_ZFreeIf(rvDB);
+ return (nssPKIDatabase *)NULL;
+ }
+
+ dbFlags = (flags & PKIDB_FLAGS_READ_ONLY) ? DB_RDONLY : DB_RDWR;
+ dbFlags |= DB_CREATE; /* always? */
+
+ rvDB->db = dbopen(filename, dbFlags, 0600, DB_HASH, &s_db_hash_info);
+ if (!rvDB->db) {
+ nssUTF8_Destroy(filename);
+ PZ_DestroyLock(rvDB->lock);
+ nss_ZFreeIf(rvDB);
+ return (nssPKIDatabase *)NULL;
+ }
+ rvDB->td = td;
+ return rvDB;
+}
+
+NSS_IMPLEMENT PRStatus
+nssPKIDatabase_Close (
+ nssPKIDatabase *pkidb
+)
+{
+ pkidb->db->close(pkidb->db);
+ PZ_DestroyLock(pkidb->lock);
+ nss_ZFreeIf(pkidb);
+ return PR_SUCCESS;
+}
+
+NSS_IMPLEMENT PRStatus
+nssPKIDatabase_ImportCert (
+ nssPKIDatabase *pkidb,
+ NSSCert *cert,
+ NSSUTF8 *nicknameOpt,
+ nssTrust *trustOpt
+)
+{
+ DBT rowID;
+ PRStatus status;
+ NSSArena *tmparena;
+ NSSBER *subject;
+ NSSUTF8 *nickname;
+
+ tmparena = nssArena_Create();
+ if (!tmparena) {
+ return PR_FAILURE;
+ }
+
+ status = make_cert_rowid(&rowID, cert, tmparena);
+ if (status == PR_FAILURE) {
+ goto cleanup;
+ }
+ status = write_cert_record(pkidb, &rowID, cert,
+ nicknameOpt, trustOpt, tmparena);
+ if (status == PR_FAILURE) {
+ goto cleanup;
+ }
+
+ subject = nssCert_GetSubject(cert);
+ status = make_subject_rowid(&rowID, subject, tmparena);
+ if (status == PR_FAILURE) {
+ goto cleanup;
+ }
+ status = write_subject_record(pkidb, &rowID, cert, tmparena);
+ if (status == PR_FAILURE) {
+ goto cleanup;
+ }
+
+ nickname = nicknameOpt ? nicknameOpt : nssCert_GetNickname(cert, NULL);
+ if (nickname) {
+ status = make_nickname_rowid(&rowID, nickname, tmparena);
+ if (status == PR_FAILURE) {
+ goto cleanup;
+ }
+ status = write_nickname_record(pkidb, &rowID, cert, tmparena);
+ if (status == PR_FAILURE) {
+ goto cleanup;
+ }
+ }
+
+cleanup:
+ nssArena_Destroy(tmparena);
+ return status;
+}
+
+NSS_IMPLEMENT PRStatus
+nssPKIDatabase_DeleteCert (
+ nssPKIDatabase *pkidb,
+ NSSCert *cert
+)
+{
+ DBT rowID;
+ PRStatus status;
+
+ status = make_cert_rowid(&rowID, cert, NULL);
+ if (status == PR_FAILURE) {
+ return PR_FAILURE;
+ }
+
+ status = delete_record(pkidb, &rowID);
+
+ nss_ZFreeIf(rowID.data);
+ return status;
+}
+
+NSS_IMPLEMENT PRStatus
+nssPKIDatabase_SetCertTrust (
+ nssPKIDatabase *pkidb,
+ NSSCert *cert,
+ nssTrust *trust
+)
+{
+ DBT rowID, payload;
+ int dberr;
+ PRStatus status;
+ NSSArena *tmparena;
+
+ tmparena = nssArena_Create();
+ if (!tmparena) {
+ return PR_FAILURE;
+ }
+
+ status = make_cert_rowid(&rowID, cert, tmparena);
+ if (status == PR_FAILURE) {
+ nssArena_Destroy(tmparena);
+ return PR_FAILURE;
+ }
+
+ /* look up the cert record */
+ PZ_Lock(pkidb->lock);
+ dberr = pkidb->db->get(pkidb->db, &rowID, &payload, 0);
+ PZ_Unlock(pkidb->lock);
+
+ if (dberr == 0) {
+ /* cert already present, set the new trust value */
+ PRUint32 i = CERT_PAYLOAD_TRUST_OFFSET;
+ DBT tmp;
+ /* XXX apparently, I must copy the dbt before writing. how lame. */
+ tmp.data = nss_ZAlloc(NULL, payload.size);
+ nsslibc_memcpy(tmp.data, payload.data, payload.size);
+ tmp.size = payload.size;
+ payload = tmp;
+ SET_DBT_INT(&payload, i, trust->trustedUsages.ca); i += 4;
+ SET_DBT_INT(&payload, i, trust->trustedUsages.peer); i += 4;
+ SET_DBT_INT(&payload, i, trust->notTrustedUsages.ca); i += 4;
+ SET_DBT_INT(&payload, i, trust->notTrustedUsages.peer); i += 4;
+ status = write_record(pkidb, &rowID, &payload);
+ nss_ZFreeIf(tmp.data);
+ } else if (dberr == 1) {
+ /* cert is not present, create a new record */
+ NSSUTF8 *nickname = nssCert_GetNickname(cert, NULL);
+ status = write_cert_record(pkidb, &rowID, cert,
+ nickname, trust, tmparena);
+ } else {
+ /* db failed */
+ status = PR_FAILURE;
+ }
+ nssArena_Destroy(tmparena);
+ return status;
+}
+
+/*
+NSS_IMPLEMENT PRStatus
+nssPKIDatabase_DeleteCertTrust (
+ nssPKIDatabase *pkidb,
+ NSSCert *cert
+)
+{
+}
+*/
+
+NSS_IMPLEMENT NSSCert **
+nssPKIDatabase_FindCertsBySubject (
+ nssPKIDatabase *pkidb,
+ NSSBER *subject,
+ NSSCert **rvOpt,
+ PRUint32 maximumOpt,
+ NSSArena *arenaOpt
+)
+{
+ DBT rowID;
+ PRStatus status;
+ NSSCert **certs;
+
+ status = make_subject_rowid(&rowID, subject, NULL);
+ if (status == PR_SUCCESS) {
+ certs = get_certs_from_subject_record(pkidb, &rowID, arenaOpt);
+ nss_ZFreeIf(rowID.data);
+ }
+ return certs;
+}
+
+NSS_IMPLEMENT NSSCert **
+nssPKIDatabase_FindCertsByNickname (
+ nssPKIDatabase *pkidb,
+ NSSUTF8 *nickname,
+ NSSCert **rvOpt,
+ PRUint32 maximumOpt,
+ NSSArena *arenaOpt
+)
+{
+ DBT rowID;
+ PRStatus status;
+ NSSCert **certs;
+
+ status = make_nickname_rowid(&rowID, nickname, NULL);
+ if (status == PR_SUCCESS) {
+ certs = get_certs_from_nickname_record(pkidb, &rowID, arenaOpt);
+ nss_ZFreeIf(rowID.data);
+ }
+ return certs;
+}
+
+NSS_IMPLEMENT NSSCert **
+nssPKIDatabase_FindCertsByEmail (
+ nssPKIDatabase *pkidb,
+ NSSASCII7 *email,
+ NSSCert **rvOpt,
+ PRUint32 maximumOpt,
+ NSSArena *arenaOpt
+)
+{
+ DBT rowID;
+ PRStatus status;
+ NSSCert **certs;
+
+ status = make_email_rowid(&rowID, email, NULL);
+ if (status == PR_SUCCESS) {
+ certs = get_certs_from_email_record(pkidb, &rowID, arenaOpt);
+ nss_ZFreeIf(rowID.data);
+ }
+ return certs;
+}
+
+NSS_IMPLEMENT NSSCert *
+nssPKIDatabase_FindCertByIssuerAndSerialNumber (
+ nssPKIDatabase *pkidb,
+ NSSBER *issuer,
+ NSSBER *serial
+)
+{
+ DBT rowID;
+ PRStatus status;
+ NSSCert *cert = NULL;
+
+ status = make_cert_rowid_from_issuer_serial(&rowID, issuer, serial, NULL);
+ if (status == PR_SUCCESS) {
+ cert = get_cert_from_rowid(pkidb, &rowID);
+ nss_ZFreeIf(rowID.data);
+ }
+ return cert;
+}
+
+/* d'oh! */
+struct match_encoded_cert_str { NSSCert *cert; NSSBER *ber; };
+
+static PRStatus match_encoded_cert(NSSCert *cert, void *arg)
+{
+ struct match_encoded_cert_str *me = (struct match_encoded_cert_str *)arg;
+ NSSBER *certBER = nssCert_GetEncoding(cert);
+ if (nssItem_Equal(me->ber, certBER, NULL)) {
+ me->cert = nssCert_AddRef(cert);
+ }
+ return PR_SUCCESS;
+}
+
+NSS_IMPLEMENT NSSCert *
+nssPKIDatabase_FindCertByEncodedCert (
+ nssPKIDatabase *pkidb,
+ NSSBER *ber
+)
+{
+ struct match_encoded_cert_str me;
+ me.cert = NULL;
+ me.ber = ber;
+ nssPKIDatabase_TraverseCerts(pkidb, match_encoded_cert, &me);
+ return me.cert;
+}
+
+NSS_IMPLEMENT PRStatus
+nssPKIDatabase_FindTrustForCert (
+ nssPKIDatabase *pkidb,
+ NSSCert *cert,
+ nssTrust *rvTrust
+)
+{
+ DBT rowID, payload;
+ int dberr;
+ PRStatus status;
+
+ status = make_cert_rowid(&rowID, cert, NULL);
+ if (status == PR_FAILURE) {
+ return PR_FAILURE;
+ }
+
+ /* look up the cert record */
+ PZ_Lock(pkidb->lock);
+ dberr = pkidb->db->get(pkidb->db, &rowID, &payload, 0);
+ PZ_Unlock(pkidb->lock);
+
+ if (dberr == 0) {
+ /* cert already present, set the new trust value */
+ PRUint32 i = CERT_PAYLOAD_TRUST_OFFSET;
+ GET_DBT_INT(&payload, i, rvTrust->trustedUsages.ca); i += 4;
+ GET_DBT_INT(&payload, i, rvTrust->trustedUsages.peer); i += 4;
+ GET_DBT_INT(&payload, i, rvTrust->notTrustedUsages.ca); i += 4;
+ GET_DBT_INT(&payload, i, rvTrust->notTrustedUsages.peer); i += 4;
+ status = PR_SUCCESS;
+ } else {
+ nsslibc_memset(rvTrust, 0, sizeof(*rvTrust));
+ status = PR_FAILURE;
+ }
+ nss_ZFreeIf(rowID.data);
+ return status;
+}
+
+NSS_IMPLEMENT PRStatus
+nssPKIDatabase_TraverseCerts (
+ nssPKIDatabase *pkidb,
+ PRStatus (*callback)(NSSCert *c, void *arg),
+ void *arg
+)
+{
+ DBT rowID, payload;
+ int dberr;
+ PRStatus status = PR_SUCCESS;
+ NSSBER ber, nick;
+ nssTrust trust;
+ NSSCert *cert;
+
+ PZ_Lock(pkidb->lock);
+ dberr = pkidb->db->seq(pkidb->db, &rowID, &payload, R_FIRST);
+ while (dberr == 0) {
+ if (PKIDB_IS_CERT_RECORD(&rowID)) {
+ status = decode_cert_payload(&payload, &ber, &nick, &trust);
+ if (status == PR_SUCCESS) {
+ cert = nssCert_Decode(&ber, &nick, &trust, pkidb->td, NULL);
+ if (cert) {
+ status = (*callback)(cert, arg);
+ if (status == PR_FAILURE) {
+ break; /* allow for early termination */
+ }
+ } /* else ? */
+ } /* else ? */
+ }
+ dberr = pkidb->db->seq(pkidb->db, &rowID, &payload, R_NEXT);
+ }
+ PZ_Unlock(pkidb->lock);
+
+ return status;
+}
+
diff --git a/security/nss/lib/pki/pkim.h b/security/nss/lib/pki/pkim.h
index a2248df6d..f3047db8d 100644
--- a/security/nss/lib/pki/pkim.h
+++ b/security/nss/lib/pki/pkim.h
@@ -64,7 +64,7 @@ PR_BEGIN_EXTERN_C
* nssPKIObject_AddInstance
* nssPKIObject_HasInstance
* nssPKIObject_GetTokens
- * nssPKIObject_IsOnToken
+ * nssPKIObject_HasInstanceOnToken
* nssPKIObject_SetNickname
* nssPKIObject_GetNickname
* nssPKIObject_RemoveInstanceForToken
@@ -78,12 +78,14 @@ PR_BEGIN_EXTERN_C
*/
NSS_EXTERN nssPKIObject *
nssPKIObject_Create (
- NSSArena *arenaOpt,
- nssCryptokiObject *instanceOpt,
NSSTrustDomain *td,
- NSSVolatileDomain *vdOpt
+ nssCryptokiObject *instanceOpt,
+ PRUint32 size
);
+#define nssPKIObject_CREATE(td, instanceOpt, type) \
+ (type *)nssPKIObject_Create(td, instanceOpt, sizeof(type))
+
/* nssPKIObject_AddRef
*/
NSS_EXTERN nssPKIObject *
@@ -139,7 +141,7 @@ nssPKIObject_GetTokens (
);
NSS_EXTERN PRBool
-nssPKIObject_IsOnToken (
+nssPKIObject_HasInstanceOnToken (
nssPKIObject *object,
NSSToken *token
);
@@ -237,6 +239,26 @@ nssTrustDomain_FindSourceToken (
NSSToken *candidate
);
+/* XXX */
+NSS_EXTERN nssSession *
+nssTrustDomain_GetSessionForToken (
+ NSSTrustDomain *td,
+ NSSToken *token,
+ PRBool readWrite
+);
+
+/* XXX */
+NSS_EXTERN NSSSlot **
+nssTrustDomain_GetActiveSlots (
+ NSSTrustDomain *td,
+ nssUpdateLevel *updateLevel
+);
+
+NSS_EXTERN nssPKIObjectTable *
+nssTrustDomain_GetObjectTable (
+ NSSTrustDomain *td
+);
+
NSS_EXTERN NSSCert **
nssTrustDomain_FindCertsByID (
NSSTrustDomain *td,
@@ -246,12 +268,25 @@ nssTrustDomain_FindCertsByID (
NSSArena *arenaOpt
);
+NSS_EXTERN NSSPrivateKey *
+nssTrustDomain_FindPrivateKeyByID (
+ NSSTrustDomain *td,
+ NSSItem *keyID
+);
+
NSS_EXTERN NSSCRL **
nssTrustDomain_FindCRLsBySubject (
NSSTrustDomain *td,
NSSDER *subject
);
+NSS_EXTERN PRStatus
+nssTrustDomain_SetCertTrust (
+ NSSTrustDomain *td,
+ NSSCert *c,
+ nssTrust *trust
+);
+
/* module-private nsspki methods */
NSS_EXTERN NSSCryptoContext *
@@ -276,18 +311,11 @@ nssCryptoContext_CreateForPrivateKey (
NSSCallback *uhhOpt
);
-/* XXX for the collection */
-NSS_EXTERN NSSCert *
-nssCert_Create (
- nssPKIObject *object
-);
-
NSS_EXTERN NSSCert *
nssCert_CreateFromInstance (
nssCryptokiObject *instance,
NSSTrustDomain *td,
- NSSVolatileDomain *vdOpt,
- NSSArena *arenaOpt
+ NSSVolatileDomain *vdOpt
);
/* XXX XXX most of these belong in pki.h */
@@ -338,16 +366,6 @@ nssCert_HasCANameInChain (
NSSPolicies *policiesOpt
);
-NSS_EXTERN nssTrust *
-nssTrust_Create (
- nssPKIObject *object
-);
-
-NSS_EXTERN NSSCRL *
-nssCRL_Create (
- nssPKIObject *object
-);
-
NSS_EXTERN NSSCRL *
nssCRL_AddRef (
NSSCRL *crl
@@ -365,11 +383,6 @@ nssCRL_DeleteStoredObject (
);
NSS_EXTERN NSSSymKey *
-nssSymKey_Create (
- nssPKIObject *object
-);
-
-NSS_EXTERN NSSSymKey *
nssSymKey_CreateFromInstance (
nssCryptokiObject *instance,
NSSTrustDomain *td,
@@ -381,6 +394,12 @@ nssSymKey_Destroy (
NSSSymKey *mk
);
+NSS_EXTERN void
+nssSymKey_SetVolatileDomain (
+ NSSSymKey *mk,
+ NSSVolatileDomain *vd
+);
+
NSS_IMPLEMENT nssCryptokiObject *
nssSymKey_CopyToToken (
NSSSymKey *mk,
@@ -403,7 +422,7 @@ nssSymKey_GetTrustDomain (
);
NSS_EXTERN PRBool
-nssSymKey_IsOnToken (
+nssSymKey_HasInstanceOnToken (
NSSSymKey *mk,
NSSToken *token
);
@@ -426,11 +445,6 @@ nssCRL_GetEncoding (
);
NSS_EXTERN NSSPublicKey *
-nssPublicKey_Create (
- nssPKIObject *object
-);
-
-NSS_EXTERN NSSPublicKey *
nssPublicKey_CreateFromInfo (
NSSTrustDomain *td,
NSSVolatileDomain *vdOpt,
@@ -442,12 +456,17 @@ NSS_EXTERN NSSPublicKey *
nssPublicKey_CreateFromInstance (
nssCryptokiObject *instance,
NSSTrustDomain *td,
- NSSVolatileDomain *vdOpt,
- NSSArena *arenaOpt
+ NSSVolatileDomain *vdOpt
+);
+
+NSS_EXTERN void
+nssPublicKey_SetVolatileDomain (
+ NSSPublicKey *bk,
+ NSSVolatileDomain *vd
);
NSS_EXTERN PRBool
-nssPublicKey_IsOnToken (
+nssPublicKey_HasInstanceOnToken (
NSSPublicKey *bk,
NSSToken *token
);
@@ -464,6 +483,17 @@ nssPublicKey_FindInstanceForAlgorithm (
const NSSAlgNParam *ap
);
+NSS_EXTERN PRStatus
+nssPublicKey_RemoveInstanceForToken (
+ NSSPublicKey *bk,
+ NSSToken *token
+);
+
+NSS_EXTERN PRIntn
+nssPublicKey_CountInstances (
+ NSSPublicKey *bk
+);
+
NSS_EXTERN nssCryptokiObject *
nssPublicKey_CopyToToken (
NSSPublicKey *bk,
@@ -472,12 +502,20 @@ nssPublicKey_CopyToToken (
);
NSS_EXTERN NSSPrivateKey *
-nssPrivateKey_Create (
- nssPKIObject *o
+nssPrivateKey_CreateFromInstance (
+ nssCryptokiObject *instance,
+ NSSTrustDomain *td,
+ NSSVolatileDomain *vdOpt
+);
+
+NSS_EXTERN void
+nssPrivateKey_SetVolatileDomain (
+ NSSPrivateKey *vk,
+ NSSVolatileDomain *vd
);
NSS_EXTERN PRBool
-nssPrivateKey_IsOnToken (
+nssPrivateKey_HasInstanceOnToken (
NSSPrivateKey *vk,
NSSToken *token
);
@@ -494,16 +532,26 @@ nssPrivateKey_FindInstanceForAlgorithm (
const NSSAlgNParam *ap
);
+NSS_EXTERN PRStatus
+nssPrivateKey_RemoveInstanceForToken (
+ NSSPrivateKey *vk,
+ NSSToken *token
+);
+
+NSS_EXTERN PRIntn
+nssPrivateKey_CountInstances (
+ NSSPrivateKey *vk
+);
+
NSS_EXTERN nssCryptokiObject *
nssPrivateKey_CopyToToken (
NSSPrivateKey *vk,
NSSToken *destination
);
-NSS_EXTERN PRBool
-nssUsages_Match (
- const NSSUsages *usages,
- const NSSUsages *testUsages
+NSS_EXTERN PRIntn
+nssObjectArray_Count (
+ void **objects
);
/* nssCertArray
@@ -586,173 +634,19 @@ 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.
- *
- * nssCertCollection_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 (nssCertCollection_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_GetCerts
- * nssPKIObjectCollection_GetCRLs
- * nssPKIObjectCollection_GetPrivateKeys
- * nssPKIObjectCollection_GetPublicKeys
- */
-
-/* nssCertCollection_Create
- *
- * Create a collection of certificates in the specified trust domain.
- * Optionally provide a starting set of certs.
- */
-NSS_EXTERN nssPKIObjectCollection *
-nssCertCollection_Create (
- NSSTrustDomain *td,
- NSSCert **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,
+NSS_EXTERN NSSPublicKey **
+nssPublicKeyArray_CreateFromInstances (
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_TraverseCerts. 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_GetCerts
- *
- * Get all of the certificates in the collection.
- */
-NSS_EXTERN NSSCert **
-nssPKIObjectCollection_GetCerts (
- nssPKIObjectCollection *collection,
- NSSCert **rvOpt,
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-);
-
-NSS_EXTERN NSSCRL **
-nssPKIObjectCollection_GetCRLs (
- nssPKIObjectCollection *collection,
- NSSCRL **rvOpt,
- PRUint32 maximumOpt,
+ NSSTrustDomain *td,
+ NSSVolatileDomain *vdOpt,
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,
+nssPrivateKeyArray_CreateFromInstances (
+ nssCryptokiObject **instances,
+ NSSTrustDomain *td,
+ NSSVolatileDomain *vdOpt,
NSSArena *arenaOpt
);
@@ -793,7 +687,8 @@ nssTokenSessionHash_GetSession (
);
NSS_EXTERN nssTokenStore *
-nssTokenObjectStore_Create (
+nssTokenStore_Create (
+ NSSTrustDomain *td,
NSSToken **tokens
);
@@ -808,6 +703,12 @@ nssTokenStore_Refresh (
);
NSS_EXTERN PRStatus
+nssTokenStore_AddToken (
+ nssTokenStore *store,
+ NSSToken *token
+);
+
+NSS_EXTERN PRStatus
nssTokenStore_ImportCert (
nssTokenStore *store,
NSSCert *cert,
@@ -897,6 +798,135 @@ nssTokenStore_TraverseCerts (
void *arg
);
+NSS_EXTERN NSSPublicKey *
+nssTokenStore_FindPublicKeyByID (
+ nssTokenStore *store,
+ NSSItem *id
+);
+
+NSS_EXTERN NSSPrivateKey *
+nssTokenStore_FindPrivateKeyByID (
+ nssTokenStore *store,
+ NSSItem *id
+);
+
+NSS_EXTERN PRStatus *
+nssTokenStore_TraversePrivateKeys (
+ nssTokenStore *store,
+ PRStatus (*callback)(NSSPrivateKey *vk, void *arg),
+ void *arg
+);
+
+NSS_EXTERN nssPKIDatabase *
+nssPKIDatabase_Open (
+ NSSTrustDomain *td,
+ const char *path,
+ PRUint32 flags
+);
+
+NSS_EXTERN PRStatus
+nssPKIDatabase_Close (
+ nssPKIDatabase *pkidb
+);
+
+NSS_EXTERN PRStatus
+nssPKIDatabase_ImportCert (
+ nssPKIDatabase *pkidb,
+ NSSCert *cert,
+ NSSUTF8 *nicknameOpt,
+ nssTrust *trustOpt
+);
+
+NSS_EXTERN PRStatus
+nssPKIDatabase_ImportCertTrust (
+ nssPKIDatabase *pkidb,
+ NSSCert *cert,
+ nssTrust *trust
+);
+
+NSS_EXTERN PRStatus
+nssPKIDatabase_DeleteCert (
+ nssPKIDatabase *pkidb,
+ NSSCert *cert
+);
+
+NSS_EXTERN PRStatus
+nssPKIDatabase_SetCertTrust (
+ nssPKIDatabase *pkidb,
+ NSSCert *cert,
+ nssTrust *trust
+);
+
+NSS_EXTERN NSSCert **
+nssPKIDatabase_FindCertsByNickname (
+ nssPKIDatabase *pkidb,
+ NSSUTF8 *nickname,
+ NSSCert **rvOpt,
+ PRUint32 maximumOpt,
+ NSSArena *arenaOpt
+);
+
+NSS_EXTERN NSSCert **
+nssPKIDatabase_FindCertsBySubject (
+ nssPKIDatabase *pkidb,
+ NSSBER *subject,
+ NSSCert **rvOpt,
+ PRUint32 maximumOpt,
+ NSSArena *arenaOpt
+);
+
+NSS_EXTERN NSSCert **
+nssPKIDatabase_FindCertsByEmail (
+ nssPKIDatabase *pkidb,
+ NSSASCII7 *email,
+ NSSCert **rvOpt,
+ PRUint32 maximumOpt,
+ NSSArena *arenaOpt
+);
+
+NSS_EXTERN NSSCert *
+nssPKIDatabase_FindCertByIssuerAndSerialNumber (
+ nssPKIDatabase *pkidb,
+ NSSBER *issuer,
+ NSSBER *serial
+);
+
+NSS_EXTERN NSSCert *
+nssPKIDatabase_FindCertByEncodedCert (
+ nssPKIDatabase *pkidb,
+ NSSBER *ber
+);
+
+NSS_EXTERN PRStatus
+nssPKIDatabase_FindTrustForCert (
+ nssPKIDatabase *pkidb,
+ NSSCert *cert,
+ nssTrust *rvTrust
+);
+
+NSS_EXTERN PRStatus
+nssPKIDatabase_TraverseCerts (
+ nssPKIDatabase *pkidb,
+ PRStatus (*callback)(NSSCert *c, void *arg),
+ void *arg
+);
+
+NSS_EXTERN nssPKIObjectTable *
+nssPKIObjectTable_Create (
+ NSSArena *arena
+);
+
+NSS_EXTERN void
+nssPKIObjectTable_Destroy (
+ nssPKIObjectTable *table
+);
+
+NSS_EXTERN nssPKIObject *
+nssPKIObjectTable_Add (
+ nssPKIObjectTable *table,
+ nssPKIObject *object
+);
+
PR_END_EXTERN_C
#endif /* PKIM_H */
diff --git a/security/nss/lib/pki/pkistore.c b/security/nss/lib/pki/pkistore.c
index a9a43870e..1550fedc5 100644
--- a/security/nss/lib/pki/pkistore.c
+++ b/security/nss/lib/pki/pkistore.c
@@ -700,6 +700,8 @@ struct nssTokenObjectStoreStr
PRBool isFriendly;
PZLock *lock; /* protects everything below */
NSSCert **certs; /* token certs */
+ NSSPublicKey **bkeys; /* token public keys */
+ NSSPrivateKey **vkeys; /* token private keys */
PRBool wasLoggedIn; /* token was authenticated last time
* we accessed it
*/
@@ -715,12 +717,109 @@ struct nssTokenStoreStr
{
NSSTrustDomain *td;
nssCertStore *certs;
+ NSSPublicKey **bkeys;
+ NSSPrivateKey **vkeys;
+ NSSSymKey **mkeys;
PZLock *lock; /* protects the arena, array, and counter */
NSSArena *arena;
nssTokenObjectStore **tokens;
PRUint32 numTokens;
};
+static PRStatus
+add_pubkey_to_store(nssTokenStore *store, NSSPublicKey *bk)
+{
+ PRIntn count;
+ PZ_Lock(store->lock);
+ if (!store->bkeys) {
+ store->bkeys = nss_ZNEWARRAY(NULL, NSSPublicKey *, 5);
+ count = 0;
+ } else {
+ count = nssObjectArray_Count((void **)store->bkeys);
+ if (count > 0 && count % 4 == 0) {
+ NSSPublicKey **test;
+ test = nss_ZREALLOCARRAY(store->bkeys, NSSPublicKey *, count + 5);
+ if (!test) {
+ PZ_Unlock(store->lock);
+ return PR_FAILURE;
+ }
+ store->bkeys = test;
+ }
+ }
+ store->bkeys[count] = nssPublicKey_AddRef(bk);
+ PZ_Unlock(store->lock);
+ return PR_SUCCESS;
+}
+
+static PRStatus
+add_privkey_to_store(nssTokenStore *store, NSSPrivateKey *vk)
+{
+ PRIntn count;
+ PZ_Lock(store->lock);
+ if (!store->vkeys) {
+ store->vkeys = nss_ZNEWARRAY(NULL, NSSPrivateKey *, 5);
+ count = 0;
+ } else {
+ count = nssObjectArray_Count((void **)store->bkeys);
+ if (count > 0 && count % 4 == 0) {
+ NSSPrivateKey **test;
+ test = nss_ZREALLOCARRAY(store->vkeys, NSSPrivateKey *, count + 5);
+ if (!test) {
+ PZ_Unlock(store->lock);
+ return PR_FAILURE;
+ }
+ store->vkeys = test;
+ }
+ }
+ store->vkeys[count] = nssPrivateKey_AddRef(vk);
+ PZ_Unlock(store->lock);
+ return PR_SUCCESS;
+}
+
+static void
+remove_pubkey_from_store(nssTokenStore *store, NSSPublicKey *bk)
+{
+ PRBool foundIt = PR_FALSE;
+ NSSPublicKey **bkp;
+ PZ_Lock(store->lock);
+ for (bkp = store->bkeys; bkp && *bkp; bkp++) {
+ if (*bkp == bk) {
+ nssPublicKey_Destroy(*bkp);
+ foundIt = PR_TRUE;
+ break;
+ }
+ }
+ if (foundIt) {
+ NSSPublicKey **removed = bkp;
+ for (; bkp[1]; bkp++);
+ *removed = *bkp;
+ *bkp = NULL;
+ }
+ PZ_Unlock(store->lock);
+}
+
+static void
+remove_privkey_from_store(nssTokenStore *store, NSSPrivateKey *vk)
+{
+ PRBool foundIt = PR_FALSE;
+ NSSPrivateKey **vkp;
+ PZ_Lock(store->lock);
+ for (vkp = store->vkeys; vkp && *vkp; vkp++) {
+ if (*vkp == vk) {
+ nssPrivateKey_Destroy(*vkp);
+ foundIt = PR_TRUE;
+ break;
+ }
+ }
+ if (foundIt) {
+ NSSPrivateKey **removed = vkp;
+ for (; vkp[1]; vkp++);
+ *removed = *vkp;
+ *vkp = NULL;
+ }
+ PZ_Unlock(store->lock);
+}
+
static void
unload_token_certs(nssTokenObjectStore *objectStore, nssTokenStore *store)
{
@@ -758,7 +857,7 @@ load_token_certs(nssTokenObjectStore *objectStore, nssTokenStore *store)
* on the token
*/
tokenCerts = nssToken_FindCerts(objectStore->token, objectStore->session,
- nssTokenSearchType_TokenOnly, 0, &status);
+ 0, &status);
if (status == PR_FAILURE) {
return PR_FAILURE;
}
@@ -767,7 +866,7 @@ load_token_certs(nssTokenObjectStore *objectStore, nssTokenStore *store)
store->td,
NULL, NULL);
if (!objectStore->certs) {
- nssCryptokiObjectArray_Destroy(tokenCerts);
+ /* XXX nssCryptokiObjectArray_Destroy(tokenCerts); */
return PR_FAILURE;
}
nss_ZFreeIf(tokenCerts);
@@ -781,6 +880,130 @@ load_token_certs(nssTokenObjectStore *objectStore, nssTokenStore *store)
return PR_SUCCESS;
}
+static void
+unload_token_bkeys(nssTokenObjectStore *objectStore, nssTokenStore *store)
+{
+ NSSPublicKey **bkp;
+ if (objectStore->bkeys) {
+ /* notify the objects that the token is removed */
+ for (bkp = objectStore->bkeys; *bkp; bkp++) {
+ nssPublicKey_RemoveInstanceForToken(*bkp, objectStore->token);
+ if (nssPublicKey_CountInstances(*bkp) == 0) {
+ /* the key now has no token instances, remove it from
+ * the token store
+ */
+ remove_pubkey_from_store(store, *bkp);
+ }
+ }
+ /* clear the array of token certs */
+ nssPublicKeyArray_Destroy(objectStore->bkeys);
+ objectStore->bkeys = NULL;
+ }
+}
+
+static PRStatus
+load_token_bkeys(nssTokenObjectStore *objectStore, nssTokenStore *store)
+{
+ PRStatus status;
+ nssCryptokiObject **tokenBKeys;
+ NSSPublicKey **bkp;
+
+ if (objectStore->bkeys) {
+ /* clear the existing array of token bkeys */
+ nssPublicKeyArray_Destroy(objectStore->bkeys);
+ objectStore->bkeys = NULL;
+ }
+ /* find all peristent cert instances (PKCS #11 "token objects")
+ * on the token
+ */
+ tokenBKeys = nssToken_FindPublicKeys(objectStore->token,
+ objectStore->session,
+ 0, &status);
+ if (status == PR_FAILURE) {
+ return PR_FAILURE;
+ }
+ if (tokenBKeys) {
+ objectStore->bkeys = nssPublicKeyArray_CreateFromInstances(tokenBKeys,
+ store->td,
+ NULL, NULL);
+ if (!objectStore->bkeys) {
+ /* XXX nssCryptokiObjectArray_Destroy(tokenBKeys); */
+ return PR_FAILURE;
+ }
+ for (bkp = objectStore->bkeys; *bkp; bkp++) {
+ status = add_pubkey_to_store(store, *bkp);
+ if (status == PR_FAILURE) {
+ unload_token_bkeys(objectStore, store);
+ }
+ }
+ }
+ return PR_SUCCESS;
+}
+
+static void
+unload_token_vkeys(nssTokenObjectStore *objectStore, nssTokenStore *store)
+{
+ NSSPrivateKey **vkp;
+ if (objectStore->vkeys) {
+ /* notify the objects that the token is removed */
+ for (vkp = objectStore->vkeys; *vkp; vkp++) {
+ nssPrivateKey_RemoveInstanceForToken(*vkp, objectStore->token);
+ if (nssPrivateKey_CountInstances(*vkp) == 0) {
+ /* the key now has no token instances, remove it from
+ * the token store
+ */
+ remove_privkey_from_store(store, *vkp);
+ }
+ }
+ /* clear the array of token certs */
+ nssPrivateKeyArray_Destroy(objectStore->vkeys);
+ objectStore->vkeys = NULL;
+ }
+}
+
+static PRStatus
+load_token_vkeys(nssTokenObjectStore *objectStore, nssTokenStore *store)
+{
+ PRStatus status;
+ nssCryptokiObject **tokenVKeys;
+ NSSPrivateKey **vkp;
+
+ if (objectStore->vkeys) {
+ /* clear the existing array of token bkeys */
+ nssPrivateKeyArray_Destroy(objectStore->vkeys);
+ objectStore->vkeys = NULL;
+ }
+ /* find all peristent cert instances (PKCS #11 "token objects")
+ * on the token
+ */
+ tokenVKeys = nssToken_FindPrivateKeys(objectStore->token,
+ objectStore->session,
+ 0, &status);
+ if (status == PR_FAILURE) {
+ return PR_FAILURE;
+ }
+ if (tokenVKeys) {
+ objectStore->vkeys = nssPrivateKeyArray_CreateFromInstances(tokenVKeys,
+ store->td,
+ NULL, NULL);
+ if (!objectStore->vkeys) {
+ /* XXX nssCryptokiObjectArray_Destroy(tokenVKeys); */
+ return PR_FAILURE;
+ }
+ for (vkp = objectStore->vkeys; *vkp; vkp++) {
+ status = add_privkey_to_store(store, *vkp);
+ if (status == PR_FAILURE) {
+ unload_token_vkeys(objectStore, store);
+ }
+ }
+ }
+ return PR_SUCCESS;
+}
+
+static void
+refresh_token_object_store(nssTokenObjectStore *objectStore,
+ nssTokenStore *store);
+
static nssTokenObjectStore *
create_token_object_store(nssTokenStore *store, NSSToken *token)
{
@@ -803,18 +1026,9 @@ create_token_object_store(nssTokenStore *store, NSSToken *token)
rvObjectStore->token = nssToken_AddRef(token);
rvObjectStore->slot = nssToken_GetSlot(token);
rvObjectStore->isFriendly = nssSlot_IsFriendly(rvObjectStore->slot);
- if (load_token_certs(rvObjectStore, store) == PR_SUCCESS) {
- rvObjectStore->wasPresent = PR_TRUE;
- } else {
- NSSError e = NSS_GetError();
- if (e == NSS_ERROR_DEVICE_REMOVED) {
- rvObjectStore->wasPresent = PR_FALSE;
- } else if (e == NSS_ERROR_LOGIN_REQUIRED) {
- rvObjectStore->wasLoggedIn = PR_FALSE;
- } else {
- rvObjectStore->error = e;
- }
- }
+ rvObjectStore->wasPresent = PR_FALSE;
+ rvObjectStore->wasLoggedIn = PR_FALSE;
+ refresh_token_object_store(rvObjectStore, store);
return rvObjectStore;
}
@@ -847,6 +1061,8 @@ refresh_token_object_store(nssTokenObjectStore *objectStore,
if (objectStore->wasPresent) {
/* token has been removed since the last search */
unload_token_certs(objectStore, store);
+ unload_token_bkeys(objectStore, store);
+ unload_token_vkeys(objectStore, store);
} /* else it wasn't present before, so do nothing */
} else if (!objectStore->wasPresent) {
/* token has been inserted since the last search */
@@ -855,18 +1071,30 @@ refresh_token_object_store(nssTokenObjectStore *objectStore,
* be available
*/
status = load_token_certs(objectStore, store);
+ status = load_token_bkeys(objectStore, store);
+ if (isLoggedIn) {
+ status = load_token_vkeys(objectStore, store);
+ }
}
} else if (!isLoggedIn) {
/* token is present but not authenticated */
- if (!objectStore->isFriendly && objectStore->wasLoggedIn) {
- /* it is not friendly, and was previously authenticated, so
+ if (objectStore->wasLoggedIn) {
+ /* it was previously authenticated, so
* we have private objects that need to be unloaded
*/
- unload_token_certs(objectStore, store);
+ unload_token_vkeys(objectStore, store);
+ if (!objectStore->isFriendly) {
+ unload_token_certs(objectStore, store);
+ unload_token_bkeys(objectStore, store);
+ }
} /* else it wasn't authenticated before, so do nothing */
- } else if (!objectStore->isFriendly && !objectStore->wasLoggedIn) {
- /* token is present and authenticated, load private objects */
- status = load_token_certs(objectStore, store);
+ } else if (!objectStore->wasLoggedIn) {
+ /* token is present and (now) authenticated, load private objects */
+ status = load_token_vkeys(objectStore, store);
+ if (!objectStore->isFriendly) {
+ status = load_token_certs(objectStore, store);
+ status = load_token_bkeys(objectStore, store);
+ }
}
if (status == PR_FAILURE) {
e = NSS_GetError();
@@ -876,6 +1104,8 @@ refresh_token_object_store(nssTokenObjectStore *objectStore,
* move on.
*/
unload_token_certs(objectStore, store);
+ unload_token_bkeys(objectStore, store);
+ unload_token_vkeys(objectStore, store);
e = NSS_ERROR_NO_ERROR; /* override the error */
}
}
@@ -919,38 +1149,6 @@ find_store_for_token(nssTokenStore *store, NSSToken *token)
return objectStore;
}
-NSS_IMPLEMENT PRStatus
-nssTokenStore_AddToken (
- nssTokenStore *store,
- NSSToken *token
-)
-{
- PRStatus status = PR_SUCCESS;
- PZ_Lock(store->lock);
- if (store->numTokens == 0) {
- store->tokens = nss_ZNEWARRAY(NULL,
- nssTokenObjectStore *,
- store->numTokens + 1);
- } else {
- store->tokens = nss_ZREALLOCARRAY(store->tokens,
- nssTokenObjectStore *,
- store->numTokens + 1);
- }
- if (store->tokens) {
- store->tokens[store->numTokens] = create_token_object_store(store,
- token);
- if (!store->tokens[store->numTokens]) {
- status = PR_FAILURE;
- } else {
- store->numTokens++;
- }
- } else {
- status = PR_FAILURE;
- }
- PZ_Unlock(store->lock);
- return status;
-}
-
NSS_IMPLEMENT nssTokenStore *
nssTokenStore_Create (
NSSTrustDomain *td,
@@ -1024,6 +1222,38 @@ nssTokenStore_Destroy (
}
NSS_IMPLEMENT PRStatus
+nssTokenStore_AddToken (
+ nssTokenStore *store,
+ NSSToken *token
+)
+{
+ PRStatus status = PR_SUCCESS;
+ PZ_Lock(store->lock);
+ if (store->numTokens == 0) {
+ store->tokens = nss_ZNEWARRAY(NULL,
+ nssTokenObjectStore *,
+ store->numTokens + 1);
+ } else {
+ store->tokens = nss_ZREALLOCARRAY(store->tokens,
+ nssTokenObjectStore *,
+ store->numTokens + 1);
+ }
+ if (store->tokens) {
+ store->tokens[store->numTokens] = create_token_object_store(store,
+ token);
+ if (!store->tokens[store->numTokens]) {
+ status = PR_FAILURE;
+ } else {
+ store->numTokens++;
+ }
+ } else {
+ status = PR_FAILURE;
+ }
+ PZ_Unlock(store->lock);
+ return status;
+}
+
+NSS_IMPLEMENT PRStatus
nssTokenStore_EnableToken (
nssTokenStore *store,
NSSToken *token
@@ -1103,6 +1333,7 @@ nssTokenStore_ImportCert (
return PR_SUCCESS;
}
/* copy it onto the token and add it to the store */
+ /* XXX use session */
status = nssCert_CopyToToken(cert, destination, nicknameOpt);
if (status == PR_SUCCESS) {
status = nssCertStore_AddCert(store->certs, cert);
@@ -1130,6 +1361,7 @@ nssTokenStore_RemoveCert (
NSSCert *cert
)
{
+ /* XXX destroy session objects */
(void)nssCertStore_RemoveCert(store->certs, cert);
}
@@ -1222,3 +1454,79 @@ nssTokenStore_TraverseCerts (
return nssCertStore_TraverseCerts(store->certs, callback, arg);
}
+NSS_IMPLEMENT NSSPublicKey *
+nssTokenStore_FindPublicKeyByID (
+ nssTokenStore *store,
+ NSSItem *id
+)
+{
+ NSSPublicKey **bkp;
+ NSSPublicKey *rvBK = NULL;
+ NSSItem *bkID;
+
+ nssTokenStore_Refresh(store);
+ PZ_Lock(store->lock);
+ for (bkp = store->bkeys; bkp && *bkp; bkp++) {
+ bkID = nssPublicKey_GetID(*bkp);
+ if (nssItem_Equal(bkID, id, NULL)) {
+ rvBK = nssPublicKey_AddRef(*bkp);
+ break;
+ }
+ }
+ PZ_Unlock(store->lock);
+ return rvBK;
+}
+
+NSS_IMPLEMENT NSSPrivateKey *
+nssTokenStore_FindPrivateKeyByID (
+ nssTokenStore *store,
+ NSSItem *id
+)
+{
+ NSSPrivateKey **vkp;
+ NSSPrivateKey *rvVK = NULL;
+ NSSItem *vkID;
+
+ nssTokenStore_Refresh(store);
+ PZ_Lock(store->lock);
+ for (vkp = store->vkeys; vkp && *vkp; vkp++) {
+ vkID = nssPrivateKey_GetID(*vkp);
+ if (nssItem_Equal(vkID, id, NULL)) {
+ rvVK = nssPrivateKey_AddRef(*vkp);
+ break;
+ }
+ }
+ PZ_Unlock(store->lock);
+ return rvVK;
+}
+
+NSS_IMPLEMENT PRStatus *
+nssTokenStore_TraversePrivateKeys (
+ nssTokenStore *store,
+ PRStatus (*callback)(NSSPrivateKey *vk, void *arg),
+ void *arg
+)
+{
+ NSSPrivateKey **vkp;
+ NSSPrivateKey **vkeys;
+ PRUint32 count;
+
+ nssTokenStore_Refresh(store);
+ /* XXX ugly */
+ PZ_Lock(store->lock);
+ for (vkp = store->vkeys, count = 0; vkp && *vkp; vkp++, count++);
+ if (count > 0) {
+ vkeys = nss_ZNEWARRAY(NULL, NSSPrivateKey *, count + 1);
+ if (vkeys) {
+ for (vkp = store->vkeys, count = 0; *vkp; vkp++, count++)
+ vkeys[count++] = nssPrivateKey_AddRef(*vkp);
+ }
+ }
+ PZ_Unlock(store->lock);
+ for (vkp = vkeys; vkp && *vkp; vkp++) {
+ (*callback)(*vkp, arg);
+ }
+ nssPrivateKeyArray_Destroy(vkeys);
+ return NULL;
+}
+
diff --git a/security/nss/lib/pki/pkit.h b/security/nss/lib/pki/pkit.h
index d95ef3a67..182f16087 100644
--- a/security/nss/lib/pki/pkit.h
+++ b/security/nss/lib/pki/pkit.h
@@ -70,8 +70,6 @@ struct NSSSymKeyStr;
struct NSSPoliciesStr;
-struct NSSPKIXCertStr;
-
typedef struct nssTrustStr nssTrust;
PR_END_EXTERN_C
diff --git a/security/nss/lib/pki/pkitm.h b/security/nss/lib/pki/pkitm.h
index b8618aad9..4c44c5f84 100644
--- a/security/nss/lib/pki/pkitm.h
+++ b/security/nss/lib/pki/pkitm.h
@@ -58,20 +58,16 @@ static const char PKITM_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
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
+{
+ pkiObjectType_Cert = 0,
+ pkiObjectType_CRL = 1,
+ pkiObjectType_PrivateKey = 2,
+ pkiObjectType_PublicKey = 3,
+ pkiObjectType_SymKey = 4
+} pkiObjectType;
+
+#define MAX_ITEMS_FOR_UID 2
/* nssPKIObject
*
@@ -86,51 +82,27 @@ struct nssPKIObjectStr
PRInt32 refCount;
/* lock protects the array of nssCryptokiInstance's of the object */
PZLock *lock;
- /* 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?
- */
+ /* the set of token instances (if any) for the object */
nssCryptokiObject **instances;
PRUint32 numInstances;
/* The object must live in a trust domain */
NSSTrustDomain *td;
/* The object may live in a volatile domain */
NSSVolatileDomain *vd;
- /* XXX added so temp certs can have nickname, think more ... */
- NSSUTF8 *tempName;
+ /* The "meta"-name of the object (token instance labels may differ) */
+ NSSUTF8 *nickname;
+ /* The following data index the UID for the object. The UID is used
+ * in the table of active token objects, to ensure that the same object
+ * never appears as two different objects.
+ */
+ pkiObjectType objectType;
+ NSSItem *uid[MAX_ITEMS_FOR_UID];
+ PRUint32 numIDs;
};
typedef struct nssPKIObjectStr nssPKIObject;
-/* nssCertCollection
- *
- * You guessed it; a collection of certs. Each entry may be either an
- * NSSCert or an nssProtoCert.
- */
-
-typedef struct nssPKIObjectCollectionStr nssPKIObjectCollection;
-
-typedef struct
-{
- union {
- PRStatus (* cert)(NSSCert *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;
-
-/* XXX */
-struct nssTrustStr
-{
- nssPKIObject object;
- NSSCert *certificate;
- nssTrustLevel serverAuth;
- nssTrustLevel clientAuth;
- nssTrustLevel emailProtection;
- nssTrustLevel codeSigning;
-};
+typedef struct nssPKIObjectTableStr nssPKIObjectTable;
typedef struct nssPKIObjectCreatorStr
{
@@ -146,10 +118,18 @@ typedef struct nssPKIObjectCreatorStr
NSSOperations operations;
} nssPKIObjectCreator;
+struct nssTrustStr
+{
+ NSSUsages trustedUsages;
+ NSSUsages notTrustedUsages;
+};
+
typedef struct nssTokenSessionHashStr nssTokenSessionHash;
typedef struct nssTokenStoreStr nssTokenStore;
+typedef struct nssPKIDatabaseStr nssPKIDatabase;
+
PR_END_EXTERN_C
#endif /* PKITM_H */
diff --git a/security/nss/lib/pki/symkey.c b/security/nss/lib/pki/symkey.c
index 9e0400e7d..cb67a6c2e 100644
--- a/security/nss/lib/pki/symkey.c
+++ b/security/nss/lib/pki/symkey.c
@@ -53,32 +53,6 @@ struct NSSSymKeyStr
};
NSS_IMPLEMENT NSSSymKey *
-nssSymKey_Create (
- nssPKIObject *object
-)
-{
- PRStatus status;
- NSSSymKey *rvKey;
- NSSArena *arena = object->arena;
- PR_ASSERT(object->instances != NULL && object->numInstances > 0);
- rvKey = nss_ZNEW(arena, NSSSymKey);
- if (!rvKey) {
- return (NSSSymKey *)NULL;
- }
- rvKey->object = *object;
- /* XXX should choose instance based on some criteria */
- status = nssCryptokiSymKey_GetAttributes(object->instances[0],
- arena,
- &rvKey->kind,
- &rvKey->length,
- &rvKey->operations);
- if (status != PR_SUCCESS) {
- return (NSSSymKey *)NULL;
- }
- return rvKey;
-}
-
-NSS_IMPLEMENT NSSSymKey *
nssSymKey_CreateFromInstance (
nssCryptokiObject *instance,
NSSTrustDomain *td,
@@ -89,19 +63,31 @@ nssSymKey_CreateFromInstance (
nssPKIObject *pkio;
NSSSymKey *rvKey = NULL;
- pkio = nssPKIObject_Create(NULL, instance, td, vdOpt);
- if (!pkio) {
+ rvKey = nssPKIObject_CREATE(td, instance, NSSSymKey);
+ if (!rvKey) {
return (NSSSymKey *)NULL;
}
- rvKey = nssSymKey_Create(pkio);
+ pkio = &rvKey->object;
+ status = nssCryptokiSymKey_GetAttributes(instance, pkio->arena,
+ &rvKey->kind,
+ &rvKey->length,
+ &rvKey->operations);
+ if (status != PR_SUCCESS) {
+ goto loser;
+ }
+ pkio->objectType = pkiObjectType_SymKey;
+ pkio->numIDs = 0; /* XXX */
+ /* XXX not adding to table w/o uid... */
if (rvKey && vdOpt) {
status = nssVolatileDomain_ImportSymKey(vdOpt, rvKey);
if (status == PR_FAILURE) {
- nssSymKey_Destroy(rvKey);
- rvKey = NULL;
+ goto loser;
}
}
return rvKey;
+loser:
+ nssSymKey_Destroy(rvKey);
+ return (NSSSymKey *)NULL;
}
NSS_IMPLEMENT NSSSymKey *
@@ -184,12 +170,12 @@ nssSymKey_FindInstanceForAlgorithm (
}
NSS_IMPLEMENT PRBool
-nssSymKey_IsOnToken (
+nssSymKey_HasInstanceOnToken (
NSSSymKey *mk,
NSSToken *token
)
{
- return nssPKIObject_IsOnToken(&mk->object, token);
+ return nssPKIObject_HasInstanceOnToken(&mk->object, token);
}
NSS_IMPLEMENT PRStatus
diff --git a/security/nss/lib/pki/trustdomain.c b/security/nss/lib/pki/trustdomain.c
index 298abd7cf..036b1eff7 100644
--- a/security/nss/lib/pki/trustdomain.c
+++ b/security/nss/lib/pki/trustdomain.c
@@ -47,12 +47,6 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#include "pki1.h"
#endif /* PKI1_H */
-#ifdef CERT_CACHE
-#ifndef CERTCACHE_H
-#include "certcache.h"
-#endif /* CERTCACHE_H */
-#endif /* CERT_CACHE */
-
struct NSSTrustDomainStr {
PRInt32 refCount;
NSSArena *arena;
@@ -62,16 +56,15 @@ struct NSSTrustDomainStr {
nssSlotList *forCiphers;
nssSlotList *forTrust;
} slots;
+ nssPKIObjectTable *objectTable;
nssTokenStore *tokenStore;
-#ifdef CERT_CACHE
- nssCertCache *cache;
-#endif /* CERT_CACHE */
+ nssPKIDatabase *pkidb;
};
NSS_IMPLEMENT NSSTrustDomain *
-NSSTrustDomain_Create (
- NSSUTF8 *moduleOpt,
+nssTrustDomain_Create (
+ NSSUTF8 *dbPath,
NSSUTF8 *uriOpt,
NSSUTF8 *opaqueOpt,
void *reserved
@@ -99,26 +92,48 @@ NSSTrustDomain_Create (
if (!rvTD->slots.forTrust) {
goto loser;
}
+ rvTD->objectTable = nssPKIObjectTable_Create(arena);
+ if (!rvTD->objectTable) {
+ goto loser;
+ }
rvTD->tokenStore = nssTokenStore_Create(rvTD, NULL);
if (!rvTD->tokenStore) {
goto loser;
}
-#ifdef CERT_CACHE
- rvTD->cache = nssCertCache_Create();
- if (!rvTD->cache) {
+ rvTD->pkidb = nssPKIDatabase_Open(rvTD, dbPath, 0);
+ if (!rvTD->pkidb) {
goto loser;
}
-#endif /* CERT_CACHE */
rvTD->arena = arena;
rvTD->refCount = 1;
return rvTD;
loser:
+ if (rvTD->objectTable) {
+ nssPKIObjectTable_Destroy(rvTD->objectTable);
+ }
+ if (rvTD->tokenStore) {
+ nssTokenStore_Destroy(rvTD->tokenStore);
+ }
+ if (rvTD->pkidb) {
+ nssPKIDatabase_Close(rvTD->pkidb);
+ }
nssArena_Destroy(arena);
return (NSSTrustDomain *)NULL;
}
+NSS_IMPLEMENT NSSTrustDomain *
+NSSTrustDomain_Create (
+ NSSUTF8 *dbPath,
+ NSSUTF8 *uriOpt,
+ NSSUTF8 *opaqueOpt,
+ void *reserved
+)
+{
+ return nssTrustDomain_Create(dbPath, uriOpt, opaqueOpt, reserved);
+}
+
NSS_IMPLEMENT PRStatus
-NSSTrustDomain_Destroy (
+nssTrustDomain_Destroy (
NSSTrustDomain *td
)
{
@@ -126,16 +141,23 @@ NSSTrustDomain_Destroy (
nssSlotList_Destroy(td->slots.forCerts);
nssSlotList_Destroy(td->slots.forCiphers);
nssSlotList_Destroy(td->slots.forTrust);
-#ifdef CERT_CACHE
- nssCertCache_Destroy(td->cache);
-#endif /* CERT_CACHE */
+ nssPKIObjectTable_Destroy(td->objectTable);
nssTokenStore_Destroy(td->tokenStore);
+ nssPKIDatabase_Close(td->pkidb);
/* Destroy the trust domain */
nssArena_Destroy(td->arena);
}
return PR_SUCCESS;
}
+NSS_IMPLEMENT PRStatus
+NSSTrustDomain_Destroy (
+ NSSTrustDomain *td
+)
+{
+ return nssTrustDomain_Destroy(td);
+}
+
/* XXX */
NSS_IMPLEMENT NSSSlot **
nssTrustDomain_GetActiveSlots (
@@ -163,17 +185,13 @@ nssTrustDomain_GetSessionForToken (
return rvSession;
}
-/* XXX */
-#ifdef CERT_CACHE
-static PRBool
-nssTrustDomain_IsUpToDate (
- NSSTrustDomain *td,
- nssUpdateLevel updateLevel
+NSS_IMPLEMENT nssPKIObjectTable *
+nssTrustDomain_GetObjectTable (
+ NSSTrustDomain *td
)
{
- return (updateLevel > 0);
+ return td->objectTable;
}
-#endif /* CERT_CACHE */
NSS_IMPLEMENT PRStatus
NSSTrustDomain_SetDefaultCallback (
@@ -223,7 +241,7 @@ NSSTrustDomain_LoadModule (
}
NSS_IMPLEMENT PRStatus
-NSSTrustDomain_AddModule (
+nssTrustDomain_AddModule (
NSSTrustDomain *td,
NSSModule *module
)
@@ -385,7 +403,7 @@ NSSTrustDomain_FindTokenForAlgNParam (
}
NSS_IMPLEMENT PRStatus
-NSSTrustDomain_Login (
+nssTrustDomain_Login (
NSSTrustDomain *td,
NSSCallback *uhhOpt
)
@@ -412,6 +430,15 @@ NSSTrustDomain_Login (
}
NSS_IMPLEMENT PRStatus
+NSSTrustDomain_Login (
+ NSSTrustDomain *td,
+ NSSCallback *uhhOpt
+)
+{
+ return nssTrustDomain_Login(td, uhhOpt);
+}
+
+NSS_IMPLEMENT PRStatus
NSSTrustDomain_Logout (
NSSTrustDomain *td
)
@@ -442,13 +469,21 @@ nssTrustDomain_ImportEncodedCert (
PRStatus status;
NSSCert *c = NULL;
NSSToken *destination = destinationOpt; /* XXX */
+ NSSItem nickIt;
+
+ nickIt.data = nicknameOpt;
+ nickIt.size = nicknameOpt ? nssUTF8_Length(nicknameOpt, NULL) : 0;
- c = nssCert_Decode(ber);
+ c = nssCert_Decode(ber, &nickIt, NULL, td, NULL);
if (!c) {
goto loser;
}
- status = nssTokenStore_ImportCert(td->tokenStore, c,
- nicknameOpt, destination);
+ if (destinationOpt) { /* ja vohl? */
+ status = nssTokenStore_ImportCert(td->tokenStore, c,
+ nicknameOpt, destination);
+ } else {
+ status = nssPKIDatabase_ImportCert(td->pkidb, c, nicknameOpt, NULL);
+ }
if (status == PR_FAILURE) {
goto loser;
}
@@ -529,6 +564,7 @@ NSSTrustDomain_ImportEncodedPublicKey (
return NULL;
}
+/* XXX do all token certs need to by synched with db certs first? */
NSS_IMPLEMENT NSSCert **
nssTrustDomain_FindCertsByNickname (
NSSTrustDomain *td,
@@ -538,37 +574,21 @@ nssTrustDomain_FindCertsByNickname (
NSSArena *arenaOpt
)
{
- NSSCert **rvCerts = NULL;
-#ifdef CERT_CACHE
- PRStatus status;
- nssUpdateLevel updateLevel;
- /* see if this search is already cached */
- rvCerts = nssCertCache_FindCertsByNickname(td->cache,
- name,
- rvOpt,
- maximumOpt,
- arenaOpt,
- &updateLevel);
- if (nssTrustDomain_IsUpToDate(td, updateLevel)) {
- /* The search was cached, and up-to-date with respect to token
- * insertion/removal. Thus, it is complete, and we can return
- * the cached search.
- */
- return rvCerts;
- }
-#endif /* CERT_CACHE */
+ NSSCert **rvCerts, **dbCerts;
/* Locate all token certs */
rvCerts = nssTokenStore_FindCertsByNickname(td->tokenStore, name,
rvOpt, maximumOpt, arenaOpt);
-#ifdef CERT_CACHE
- /* Cache this search. It is up-to-date w.r.t. the time when it grabbed
- * the slots to search.
- */
- status = nssCertCache_AddCertsForNickname(td->cache,
- name,
- rvCerts,
- updateLevel);
-#endif /* CERT_CACHE */
+ if (rvOpt || maximumOpt > 0) {
+ PRIntn count = nssObjectArray_Count((void **)rvCerts);
+ maximumOpt -= count;
+ if (maximumOpt == 0) return rvCerts;
+ if (rvOpt) rvOpt += count;
+ }
+ dbCerts = nssPKIDatabase_FindCertsByNickname(td->pkidb, name,
+ rvOpt, maximumOpt, arenaOpt);
+ if (!rvOpt) {
+ rvCerts = nssCertArray_Join(rvCerts, dbCerts);
+ }
return rvCerts;
}
@@ -630,29 +650,20 @@ nssTrustDomain_FindCertsBySubject (
NSSArena *arenaOpt
)
{
- NSSCert **rvCerts = NULL;
-#ifdef CERT_CACHE
- PRStatus status;
- nssUpdateLevel updateLevel;
- /* see if this search is already cached */
- rvCerts = nssCertCache_FindCertsBySubject(td->cache,
- subject,
- rvOpt,
- maximumOpt,
- arenaOpt,
- &updateLevel);
- if (nssTrustDomain_IsUpToDate(td, updateLevel)) {
- return rvCerts;
- }
-#endif /* CERT_CACHE */
+ NSSCert **rvCerts, **dbCerts;
rvCerts = nssTokenStore_FindCertsBySubject(td->tokenStore, subject,
rvOpt, maximumOpt, arenaOpt);
-#ifdef CERT_CACHE
- status = nssCertCache_AddCertsForSubject(td->cache,
- subject,
- rvCerts,
- updateLevel);
-#endif /* CERT_CACHE */
+ if (rvOpt || maximumOpt > 0) {
+ PRIntn count = nssObjectArray_Count((void **)rvCerts);
+ maximumOpt -= count;
+ if (maximumOpt == 0) return rvCerts;
+ if (rvOpt) rvOpt += count;
+ }
+ dbCerts = nssPKIDatabase_FindCertsBySubject(td->pkidb, subject,
+ rvOpt, maximumOpt, arenaOpt);
+ if (!rvOpt) {
+ rvCerts = nssCertArray_Join(rvCerts, dbCerts);
+ }
return rvCerts;
}
@@ -704,32 +715,6 @@ NSSTrustDomain_FindBestCertBySubject (
}
NSS_IMPLEMENT NSSCert *
-NSSTrustDomain_FindBestCertByNameComponents (
- NSSTrustDomain *td,
- NSSUTF8 *nameComponents,
- NSSTime time,
- NSSUsages *usages,
- NSSPolicies *policiesOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCert **
-NSSTrustDomain_FindCertsByNameComponents (
- NSSTrustDomain *td,
- NSSUTF8 *nameComponents,
- NSSCert *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCert *
nssTrustDomain_FindCertByIssuerAndSerialNumber (
NSSTrustDomain *td,
NSSDER *issuer,
@@ -737,26 +722,14 @@ nssTrustDomain_FindCertByIssuerAndSerialNumber (
)
{
NSSCert *rvCert = NULL;
-#ifdef CERT_CACHE
- PRStatus status;
- nssUpdateLevel updateLevel;
- /* see if this search is already cached */
- rvCert = nssCertCache_FindCertByIssuerAndSerialNumber(
- td->cache,
- issuer,
- serial,
- &updateLevel);
- if (nssTrustDomain_IsUpToDate(td, updateLevel)) {
- return rvCert;
- }
-#endif /* CERT_CACHE */
rvCert = nssTokenStore_FindCertByIssuerAndSerialNumber(td->tokenStore,
issuer,
serial);
-#ifdef CERT_CACHE
- status = nssCertCache_AddCert(td->cache, rvCert,
- issuer, serial, updateLevel);
-#endif /* CERT_CACHE */
+ if (!rvCert) {
+ rvCert = nssPKIDatabase_FindCertByIssuerAndSerialNumber(td->pkidb,
+ issuer,
+ serial);
+ }
return rvCert;
}
@@ -778,6 +751,9 @@ nssTrustDomain_FindCertByEncodedCert (
{
NSSCert *rvCert = NULL;
rvCert = nssTokenStore_FindCertByEncodedCert(td->tokenStore, ber);
+ if (!rvCert) {
+ rvCert = nssPKIDatabase_FindCertByEncodedCert(td->pkidb, ber);
+ }
return rvCert;
}
@@ -802,6 +778,7 @@ nssTrustDomain_FindCertsByID (
NSSCert **rvCerts = NULL;
rvCerts = nssTokenStore_FindCertsByID(td->tokenStore, id,
rvOpt, maximumOpt, arenaOpt);
+ /* XXX bother with db? */
return rvCerts;
}
@@ -814,9 +791,20 @@ nssTrustDomain_FindCertsByEmail (
NSSArena *arenaOpt
)
{
- NSSCert **rvCerts = NULL;
+ NSSCert **rvCerts, **dbCerts;
rvCerts = nssTokenStore_FindCertsByEmail(td->tokenStore, email,
rvOpt, maximumOpt, arenaOpt);
+ if (rvOpt || maximumOpt > 0) {
+ PRIntn count = nssObjectArray_Count((void **)rvCerts);
+ maximumOpt -= count;
+ if (maximumOpt == 0) return rvCerts;
+ if (rvOpt) rvOpt += count;
+ }
+ dbCerts = nssPKIDatabase_FindCertsByEmail(td->pkidb, email,
+ rvOpt, maximumOpt, arenaOpt);
+ if (!rvOpt) {
+ rvCerts = nssCertArray_Join(rvCerts, dbCerts);
+ }
return rvCerts;
}
@@ -854,16 +842,6 @@ NSSTrustDomain_FindBestCertByEmail (
return rvCert;
}
-NSS_IMPLEMENT NSSCert *
-NSSTrustDomain_FindCertByOCSPHash (
- NSSTrustDomain *td,
- NSSItem *hash
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
/* XXX don't keep this */
struct stuff_str {
NSSCert **rv;
@@ -904,7 +882,7 @@ nssTrustDomain_FindUserCerts (
NSSArena *arenaOpt
)
{
- PRStatus *status;
+ PRStatus status;
/* XXX need something more efficient */
struct stuff_str stuff;
stuff.rv = rvOpt;
@@ -912,8 +890,8 @@ nssTrustDomain_FindUserCerts (
stuff.rvSize = rvOpt ? rvLimit : 0;
stuff.rvLimit = rvLimit;
stuff.arenaOpt = arenaOpt;
- status = nssTrustDomain_TraverseCerts(td, get_user, &stuff);
- if (status && *status == PR_FAILURE) {
+ status = nssTokenStore_TraverseCerts(td->tokenStore, get_user, &stuff);
+ if (status == PR_FAILURE) {
nssCertArray_Destroy(stuff.rv);
stuff.rv = NULL;
}
@@ -1066,6 +1044,21 @@ NSSTrustDomain_FindUserCertsForEmailSigning (
return NULL;
}
+struct token_cert_filter_str {
+ PRStatus (*callback)(NSSCert *c, void *arg);
+ void *arg;
+};
+
+static PRStatus
+filter_out_token_certs(NSSCert *c, void *arg)
+{
+ struct token_cert_filter_str *cbarg = (struct token_cert_filter_str *)arg;
+ if (nssCert_CountInstances(c) == 0) {
+ return cbarg->callback(c, cbarg->arg);
+ }
+ return PR_SUCCESS;
+}
+
NSS_IMPLEMENT PRStatus *
nssTrustDomain_TraverseCerts (
NSSTrustDomain *td,
@@ -1074,7 +1067,12 @@ nssTrustDomain_TraverseCerts (
)
{
PRStatus status;
+ /* XXX this is mighty ugly */
+ struct token_cert_filter_str cbarg;
+ cbarg.callback = callback;
+ cbarg.arg = arg;
status = nssTokenStore_TraverseCerts(td->tokenStore, callback, arg);
+ nssPKIDatabase_TraverseCerts(td->pkidb, filter_out_token_certs, &cbarg);
return NULL;
}
@@ -1088,77 +1086,6 @@ NSSTrustDomain_TraverseCerts (
return nssTrustDomain_TraverseCerts(td, callback, arg);
}
-NSS_IMPLEMENT nssTrust *
-nssTrustDomain_FindTrustForCert (
- NSSTrustDomain *td,
- NSSCert *c
-)
-{
- PRStatus status;
- NSSSlot **slots;
- NSSSlot **slotp;
- NSSToken *token;
- NSSDER *encoding = nssCert_GetEncoding(c);
- NSSDER *issuer = nssCert_GetIssuer(c);
- NSSDER *serial = nssCert_GetSerialNumber(c);
- nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
- 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++) {
- token = nssSlot_GetToken(*slotp);
- if (token) {
- /* XXX */
- nssSession *session = nssToken_CreateSession(token, PR_FALSE);
- if (!session) {
- continue;
- }
- to = nssToken_FindTrustForCert(token, session,
- encoding,
- issuer,
- serial,
- tokenOnly);
- nssSession_Destroy(session);
- if (to) {
- if (!pkio) {
- pkio = nssPKIObject_Create(NULL, to, td, NULL);
- if (!pkio) {
- goto loser;
- }
- } else {
- status = nssPKIObject_AddInstance(pkio, to);
- if (status != PR_SUCCESS) {
- goto loser;
- }
- }
- }
- nssToken_Destroy(token);
- }
- }
- if (pkio) {
- rvt = nssTrust_Create(pkio);
- if (!rvt) {
- goto loser;
- }
- }
- nssSlotArray_Destroy(slots);
- return rvt;
-loser:
- nssSlotArray_Destroy(slots);
- if (to) {
- nssCryptokiObject_Destroy(to);
- }
- if (pkio) {
- nssPKIObject_Destroy(pkio);
- }
- return (nssTrust *)NULL;
-}
-
NSS_IMPLEMENT NSSCRL **
nssTrustDomain_FindCRLsBySubject (
NSSTrustDomain *td,
@@ -1270,7 +1197,7 @@ NSSTrustDomain_GenerateSymKey (
)
{
return nssTrustDomain_GenerateSymKey(td, ap, keysize,
- destination, uhhOpt);
+ destination, uhhOpt);
}
NSS_IMPLEMENT NSSSymKey *
@@ -1298,6 +1225,34 @@ NSSTrustDomain_FindSymKeyByAlgorithmAndKeyID (
return NULL;
}
+NSS_IMPLEMENT NSSPublicKey *
+nssTrustDomain_FindPublicKeyByID (
+ NSSTrustDomain *td,
+ NSSItem *keyID
+)
+{
+ return nssTokenStore_FindPublicKeyByID(td->tokenStore, keyID);
+}
+
+NSS_IMPLEMENT NSSPrivateKey *
+nssTrustDomain_FindPrivateKeyByID (
+ NSSTrustDomain *td,
+ NSSItem *keyID
+)
+{
+ return nssTokenStore_FindPrivateKeyByID(td->tokenStore, keyID);
+}
+
+NSS_IMPLEMENT PRStatus *
+nssTrustDomain_TraversePrivateKeys (
+ NSSTrustDomain *td,
+ PRStatus (*callback)(NSSPrivateKey *vk, void *arg),
+ void *arg
+)
+{
+ return nssTokenStore_TraversePrivateKeys(td->tokenStore, callback, arg);
+}
+
NSS_IMPLEMENT PRStatus *
NSSTrustDomain_TraversePrivateKeys (
NSSTrustDomain *td,
@@ -1305,67 +1260,7 @@ NSSTrustDomain_TraversePrivateKeys (
void *arg
)
{
- PRStatus status;
- NSSToken *token = NULL;
- NSSSlot **slots = NULL;
- NSSSlot **slotp;
- nssPKIObjectCollection *collection = NULL;
- nssPKIObjectCallback pkiCallback;
- nssUpdateLevel updateLevel;
- collection = nssPrivateKeyCollection_Create(td, NULL);
- 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;
- nssCryptokiObject **instances;
- nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
- /* get a session for the token */
- session = nssTrustDomain_GetSessionForToken(td, token, PR_FALSE);
- if (!session) {
- nssToken_Destroy(token);
- goto loser;
- }
- /* perform the traversal */
- instances = nssToken_FindPrivateKeys(token,
- session,
- tokenOnly,
- 0, &status);
- nssToken_Destroy(token);
- status = nssPKIObjectCollection_AddInstances(collection,
- instances, 0);
- nss_ZFreeIf(instances);
- if (status != PR_SUCCESS) {
- goto loser;
- }
- }
- slotp++;
- }
- /* Traverse the collection */
- pkiCallback.func.pvkey = callback;
- pkiCallback.arg = arg;
- status = nssPKIObjectCollection_Traverse(collection, &pkiCallback);
- /* clean up */
- nssPKIObjectCollection_Destroy(collection);
- NSSSlotArray_Destroy(slots);
- return NULL;
-loser:
- if (collection) {
- nssPKIObjectCollection_Destroy(collection);
- }
- if (slots) {
- NSSSlotArray_Destroy(slots);
- }
- return NULL;
+ return nssTrustDomain_TraversePrivateKeys(td, callback, arg);
}
NSS_IMPLEMENT NSSVolatileDomain *
@@ -1422,3 +1317,13 @@ NSSTrustDomain_CreateCryptoContextForAlgorithm (
return NULL;
}
+NSS_IMPLEMENT PRStatus
+nssTrustDomain_SetCertTrust (
+ NSSTrustDomain *td,
+ NSSCert *c,
+ nssTrust *trust
+)
+{
+ return nssPKIDatabase_SetCertTrust(td->pkidb, c, trust);
+}
+
diff --git a/security/nss/lib/pki/volatiledomain.c b/security/nss/lib/pki/volatiledomain.c
index 7ddef1fc9..f07a52688 100644
--- a/security/nss/lib/pki/volatiledomain.c
+++ b/security/nss/lib/pki/volatiledomain.c
@@ -267,14 +267,19 @@ nssVolatileDomain_ImportEncodedCert (
)
{
NSSCert *c;
+ NSSItem nickIt;
+ NSSItem *pNick = NULL;
- c = nssCert_Decode(ber);
+ if (nickOpt) {
+ nickIt.data = nickOpt;
+ nickIt.size = nickOpt ? nssUTF8_Length(nickOpt, NULL) : 0;
+ pNick = &nickIt;
+ }
+
+ c = nssCert_Decode(ber, pNick, NULL, vd->td, vd);
if (!c) {
return (NSSCert *)NULL;
}
- if (nickOpt) {
- nssCert_SetNickname(c, NULL, nickOpt);
- }
if (nssVolatileDomain_ImportCert(vd, c) == PR_FAILURE) {
nssCert_Destroy(c);
return (NSSCert *)NULL;
@@ -369,7 +374,7 @@ nssVolatileDomain_ImportPublicKeyByInfo (
bko = nssToken_ImportPublicKey(token, session, keyInfo, PR_FALSE);
if (bko) {
- rvbk = nssPublicKey_CreateFromInstance(bko, vd->td, vd, NULL);
+ rvbk = nssPublicKey_CreateFromInstance(bko, vd->td, vd);
if (!rvbk) {
nssCryptokiObject_Destroy(bko);
}
diff --git a/security/nss/lib/ssl/authcert.c b/security/nss/lib/ssl/authcert.c
index 97681e737..249aa390b 100644
--- a/security/nss/lib/ssl/authcert.c
+++ b/security/nss/lib/ssl/authcert.c
@@ -73,6 +73,8 @@ SSL_GetClientAuthData(void * arg,
NULL, NULL);
}
if (cert) {
+ /* XXX */
+ NSSTrustDomain_Login(td, NULL);
privkey = NSSCert_FindPrivateKey(cert, NULL /*XXX pinCallback*/);
if (privkey) {
*pRetCert = cert;
diff --git a/security/nss/tests/stan/stan.sh b/security/nss/tests/stan/stan.sh
index 5fc352bf4..7a9b52623 100644
--- a/security/nss/tests/stan/stan.sh
+++ b/security/nss/tests/stan/stan.sh
@@ -158,7 +158,7 @@ ciph()
{
echo ""
echo ">>>>>>>>>>>>>> ${CIPHER_ACTION} <<<<<<<<<<<<<<"
- echo "pkiutil $*"
+ echo "cipher $*"
cipher $*
RET=$?
if [ "$RET" -ne 0 ]; then