summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwtc%netscape.com <devnull@localhost>2002-06-04 20:36:22 +0000
committerwtc%netscape.com <devnull@localhost>2002-06-04 20:36:22 +0000
commit302a99e6fc9ac2a118a7d2ee0ab90c82fdb22036 (patch)
tree17b7a3a50c5107e801c6da41498d7568fb39917d
parent43341b5c97b80aab89f6281c29352d7c26bfd107 (diff)
downloadnss-hg-302a99e6fc9ac2a118a7d2ee0ab90c82fdb22036.tar.gz
Tracking bug 145836: check in NSS bug fixes for Mozilla 1.0.1. Approved by
drivers@mozilla.org and Netscape's ADT. (Tag: MOZILLA_1_0_BRANCH)
-rw-r--r--security/coreconf/HP-UXB.11.mk16
-rw-r--r--security/coreconf/config.mk2
-rw-r--r--security/coreconf/jdk.mk31
-rw-r--r--security/nss/cmd/certutil/certutil.c409
-rw-r--r--security/nss/cmd/certutil/keystuff.c62
-rw-r--r--security/nss/cmd/certutil/manifest.mn2
-rw-r--r--security/nss/cmd/crmf-cgi/crmfcgi.c1
-rw-r--r--security/nss/cmd/crmftest/testcrmf.c7
-rw-r--r--security/nss/cmd/lib/seccnames.c2
-rw-r--r--security/nss/cmd/lib/secpwd.c16
-rw-r--r--security/nss/cmd/lib/secutil.c16
-rw-r--r--security/nss/cmd/modutil/modutil.c1
-rw-r--r--security/nss/cmd/pk12util/pk12util.c3
-rw-r--r--security/nss/cmd/platlibs.mk4
-rw-r--r--security/nss/cmd/rsaperf/defkey.c1
-rw-r--r--security/nss/cmd/sdrtest/sdrtest.c3
-rw-r--r--security/nss/cmd/signtool/certgen.c33
-rw-r--r--security/nss/cmd/signtool/util.c9
-rw-r--r--security/nss/cmd/smimetools/cmsutil.c46
-rw-r--r--security/nss/cmd/strsclnt/strsclnt.c4
-rw-r--r--security/nss/cmd/tstclnt/tstclnt.c1
-rw-r--r--security/nss/cmd/zlib/zutil.h3
-rw-r--r--security/nss/lib/Makefile4
-rw-r--r--security/nss/lib/base/arena.c13
-rw-r--r--security/nss/lib/base/base.h19
-rw-r--r--security/nss/lib/base/list.c22
-rw-r--r--security/nss/lib/certdb/certdb.c34
-rw-r--r--security/nss/lib/certdb/certt.h14
-rw-r--r--security/nss/lib/certdb/stanpcertdb.c131
-rw-r--r--security/nss/lib/certhigh/certhigh.c44
-rw-r--r--security/nss/lib/certhigh/ocsp.c28
-rw-r--r--security/nss/lib/ckfw/builtins/Makefile2
-rw-r--r--security/nss/lib/ckfw/nsprstub.c2
-rw-r--r--security/nss/lib/ckfw/sessobj.c16
-rw-r--r--security/nss/lib/crmf/asn1cmn.c5
-rw-r--r--security/nss/lib/crmf/respcmn.c3
-rw-r--r--security/nss/lib/dev/Makefile13
-rw-r--r--security/nss/lib/dev/ckhelper.c472
-rw-r--r--security/nss/lib/dev/ckhelper.h21
-rw-r--r--security/nss/lib/dev/dev.h770
-rw-r--r--security/nss/lib/dev/devm.h190
-rw-r--r--security/nss/lib/dev/devmod.c820
-rw-r--r--security/nss/lib/dev/devobject.c1093
-rw-r--r--security/nss/lib/dev/devslot.c671
-rw-r--r--security/nss/lib/dev/devt.h115
-rw-r--r--security/nss/lib/dev/devtoken.c1512
-rw-r--r--security/nss/lib/dev/devutil.c1397
-rw-r--r--security/nss/lib/dev/manifest.mn3
-rw-r--r--security/nss/lib/fortcrypt/swfort/pkcs11/stub.c15
-rw-r--r--security/nss/lib/freebl/Makefile3
-rw-r--r--security/nss/lib/freebl/arcfour.c5
-rw-r--r--security/nss/lib/freebl/config.mk4
-rw-r--r--security/nss/lib/freebl/mpi/mpi.h4
-rw-r--r--security/nss/lib/freebl/mpi/mpmontg.c22
-rw-r--r--security/nss/lib/freebl/rsa.c3
-rw-r--r--security/nss/lib/freebl/unix_rand.c13
-rw-r--r--security/nss/lib/freebl/win_rand.c160
-rw-r--r--security/nss/lib/nss/Makefile2
-rw-r--r--security/nss/lib/nss/config.mk7
-rw-r--r--security/nss/lib/nss/nss.def20
-rw-r--r--security/nss/lib/nss/nss.h6
-rw-r--r--security/nss/lib/nss/nssinit.c113
-rw-r--r--security/nss/lib/pk11wrap/dev3hack.c118
-rw-r--r--security/nss/lib/pk11wrap/dev3hack.h6
-rw-r--r--security/nss/lib/pk11wrap/pk11cert.c1062
-rw-r--r--security/nss/lib/pk11wrap/pk11pars.c18
-rw-r--r--security/nss/lib/pk11wrap/pk11pbe.c10
-rw-r--r--security/nss/lib/pk11wrap/pk11skey.c46
-rw-r--r--security/nss/lib/pk11wrap/pk11slot.c34
-rw-r--r--security/nss/lib/pk11wrap/pk11util.c57
-rw-r--r--security/nss/lib/pk11wrap/secmod.h3
-rw-r--r--security/nss/lib/pk11wrap/secmodi.h2
-rw-r--r--security/nss/lib/pk11wrap/secmodti.h4
-rw-r--r--security/nss/lib/pkcs12/p12d.c147
-rw-r--r--security/nss/lib/pkcs12/p12e.c28
-rw-r--r--security/nss/lib/pkcs12/p12t.h2
-rw-r--r--security/nss/lib/pkcs7/certread.c7
-rw-r--r--security/nss/lib/pki/Makefile4
-rw-r--r--security/nss/lib/pki/certdecode.c108
-rw-r--r--security/nss/lib/pki/certificate.c610
-rw-r--r--security/nss/lib/pki/config.mk116
-rw-r--r--security/nss/lib/pki/config34.mk48
-rw-r--r--security/nss/lib/pki/cryptocontext.c262
-rw-r--r--security/nss/lib/pki/manifest.mn1
-rw-r--r--security/nss/lib/pki/nsspki.def249
-rw-r--r--security/nss/lib/pki/nsspki.rc98
-rw-r--r--security/nss/lib/pki/pki.h128
-rw-r--r--security/nss/lib/pki/pki3hack.c629
-rw-r--r--security/nss/lib/pki/pki3hack.h30
-rw-r--r--security/nss/lib/pki/pkim.h647
-rw-r--r--security/nss/lib/pki/pkistore.c4
-rw-r--r--security/nss/lib/pki/pkit.h55
-rw-r--r--security/nss/lib/pki/pkitm.h13
-rw-r--r--security/nss/lib/pki/tdcache.c195
-rw-r--r--security/nss/lib/pki/trustdomain.c1238
-rw-r--r--security/nss/lib/smime/cmscinfo.c5
-rw-r--r--security/nss/lib/smime/cmsencdata.c9
-rw-r--r--security/nss/lib/smime/cmssigdata.c3
-rw-r--r--security/nss/lib/softoken/cdbhdl.h17
-rw-r--r--security/nss/lib/softoken/config.mk4
-rw-r--r--security/nss/lib/softoken/dbinit.c90
-rw-r--r--security/nss/lib/softoken/fipstokn.c20
-rw-r--r--security/nss/lib/softoken/keydb.c244
-rw-r--r--security/nss/lib/softoken/lowkeyi.h4
-rw-r--r--security/nss/lib/softoken/lowpbe.c6
-rw-r--r--security/nss/lib/softoken/manifest.mn10
-rw-r--r--security/nss/lib/softoken/pcert.h1
-rw-r--r--security/nss/lib/softoken/pcertdb.c83
-rw-r--r--security/nss/lib/softoken/pk11db.c117
-rw-r--r--security/nss/lib/softoken/pk11pars.h2
-rw-r--r--security/nss/lib/softoken/pkcs11.c302
-rw-r--r--security/nss/lib/softoken/pkcs11i.h28
-rw-r--r--security/nss/lib/softoken/pkcs11n.h4
-rw-r--r--security/nss/lib/softoken/pkcs11u.c45
-rw-r--r--security/nss/lib/softoken/softokn.rc14
-rw-r--r--security/nss/lib/ssl/sslimpl.h8
-rw-r--r--security/nss/lib/ssl/sslmutex.c10
-rw-r--r--security/nss/lib/ssl/sslmutex.h2
-rw-r--r--security/nss/lib/ssl/sslnonce.c4
-rw-r--r--security/nss/lib/ssl/sslsecur.c14
-rw-r--r--security/nss/lib/ssl/sslsnce.c2
-rw-r--r--security/nss/lib/ssl/sslsock.c2
-rw-r--r--security/nss/lib/ssl/win32err.c3
-rw-r--r--security/nss/lib/util/Makefile2
-rw-r--r--security/nss/lib/util/dersubr.c8
-rw-r--r--security/nss/lib/util/manifest.mn7
-rw-r--r--security/nss/lib/util/secder.h4
-rw-r--r--security/nss/lib/util/secerr.h3
-rw-r--r--security/nss/lib/util/secoid.c5
-rw-r--r--security/nss/lib/util/secport.c23
-rw-r--r--security/nss/lib/util/secport.h15
-rw-r--r--security/nss/macbuild/NSS.xml60
-rwxr-xr-xsecurity/nss/macbuild/NSSCommon.h3
-rw-r--r--security/nss/manifest.mn4
-rwxr-xr-xsecurity/nss/tests/cert/cert.sh155
-rwxr-xr-xsecurity/nss/tests/cipher/cipher.sh9
-rwxr-xr-xsecurity/nss/tests/clean_tbx10
-rw-r--r--security/nss/tests/common/init.sh40
-rwxr-xr-xsecurity/nss/tests/fips/fips.sh57
-rw-r--r--security/nss/tests/header49
-rwxr-xr-xsecurity/nss/tests/jssdir2
-rwxr-xr-xsecurity/nss/tests/nssdir2
-rwxr-xr-xsecurity/nss/tests/qa_stage10
-rwxr-xr-xsecurity/nss/tests/qa_stat2
-rwxr-xr-xsecurity/nss/tests/sdr/sdr.sh22
-rw-r--r--security/nss/tests/set_environment13
-rwxr-xr-xsecurity/nss/tests/smime/smime.sh52
-rwxr-xr-xsecurity/nss/tests/ssl/ssl.sh37
-rwxr-xr-xsecurity/nss/tests/ssl/ssl_dist_stress.sh6
-rw-r--r--security/nss/tests/tools/tools.sh29
150 files changed, 10174 insertions, 5950 deletions
diff --git a/security/coreconf/HP-UXB.11.mk b/security/coreconf/HP-UXB.11.mk
index 08463214d..5b489014f 100644
--- a/security/coreconf/HP-UXB.11.mk
+++ b/security/coreconf/HP-UXB.11.mk
@@ -41,14 +41,22 @@ endif
ifndef NS_USE_GCC
CCC = /opt/aCC/bin/aCC -ext
ifeq ($(USE_64), 1)
- OS_CFLAGS += -Aa +e +DA2.0W +DS2.0 +DChpux
+ ifeq ($(OS_TEST), ia64)
+ OS_CFLAGS += -Aa +e +p +DD64
+ else
+ OS_CFLAGS += -Aa +e +DA2.0W +DS2.0 +DChpux
+ endif
# Next line replaced by generic name handling in arch.mk
# COMPILER_TAG = _64
else
- ifdef USE_HYBRID
- OS_CFLAGS += -Aa +e +DA2.0 +DS2.0
+ ifeq ($(OS_TEST), ia64)
+ OS_CFLAGS += -Aa +e +p +DD32
else
- OS_CFLAGS += +DAportable +DS2.0
+ ifdef USE_HYBRID
+ OS_CFLAGS += -Aa +e +DA2.0 +DS2.0
+ else
+ OS_CFLAGS += +DAportable +DS2.0
+ endif
endif
endif
else
diff --git a/security/coreconf/config.mk b/security/coreconf/config.mk
index 7ad0d1e16..01b633be8 100644
--- a/security/coreconf/config.mk
+++ b/security/coreconf/config.mk
@@ -58,7 +58,7 @@ endif
# one for each OS release. #
#######################################################################
-TARGET_OSES = FreeBSD BSD_OS NetBSD OpenUNIX OS2 QNX Darwin BeOS
+TARGET_OSES = FreeBSD BSD_OS NetBSD OpenUNIX OS2 QNX Darwin BeOS OpenBSD
ifeq (,$(filter-out $(TARGET_OSES),$(OS_TARGET)))
include $(CORE_DEPTH)/coreconf/$(OS_TARGET).mk
diff --git a/security/coreconf/jdk.mk b/security/coreconf/jdk.mk
index 9e0151023..8189808c8 100644
--- a/security/coreconf/jdk.mk
+++ b/security/coreconf/jdk.mk
@@ -118,7 +118,7 @@ ifeq ($(OS_ARCH), WINNT)
endif
# set [Sun Solaris] platforms
-ifeq ($(OS_TARGET), SunOS)
+ifeq ($(OS_ARCH), SunOS)
JAVA_CLASSES = $(JAVA_HOME)/lib/classes.zip
ifeq ($(JRE_HOME),)
@@ -139,7 +139,11 @@ ifeq ($(OS_TARGET), SunOS)
INCLUDES += -I$(JAVA_HOME)/include/$(JAVA_ARCH)
# (3) specify "linker" information
+ifeq ($(USE_64), 1)
+ JAVA_CPU = $(shell uname -p)v9
+else
JAVA_CPU = $(shell uname -p)
+endif
ifeq ($(JDK_VERSION), 1.1)
JAVA_LIBDIR = lib/$(JAVA_CPU)
@@ -153,7 +157,11 @@ endif
JAVA_CLIBS = -lthread
ifneq ($(JDK_VERSION), 1.1)
+ifeq ($(USE_64), 1)
+ JAVA_LIBS += -L$(JAVA_HOME)/$(JAVA_LIBDIR)/server
+else
JAVA_LIBS += -L$(JAVA_HOME)/$(JAVA_LIBDIR)/classic
+endif
JAVA_LIBS += -L$(JAVA_HOME)/$(JAVA_LIBDIR)
JAVA_LIBS += -ljvm -ljava
else
@@ -168,7 +176,7 @@ endif
endif
# set [Hewlett Packard HP-UX] platforms
-ifeq ($(OS_TARGET), HP-UX)
+ifeq ($(OS_ARCH), HP-UX)
JAVA_CLASSES = $(JAVA_HOME)/lib/classes.zip
ifeq ($(JRE_HOME),)
@@ -207,7 +215,7 @@ ifeq ($(OS_TARGET), HP-UX)
endif
# set [Redhat Linux] platforms
-ifeq ($(OS_TARGET), Linux)
+ifeq ($(OS_ARCH), Linux)
JAVA_CLASSES = $(JAVA_HOME)/lib/classes.zip
ifeq ($(JRE_HOME),)
@@ -235,7 +243,11 @@ ifeq ($(OS_TARGET), Linux)
JAVA_CLIBS =
JAVA_LIBS = -L$(JAVA_HOME)/$(JAVA_LIBDIR)/$(JDK_THREADING_MODEL) -lhpi
- JAVA_LIBS += -L$(JAVA_HOME)/$(JAVA_LIBDIR)/classic -ljvm
+ ifeq ($(JDK_VERSION), 1.4)
+ JAVA_LIBS += -L$(JAVA_HOME)/$(JAVA_LIBDIR)/server -ljvm
+ else
+ JAVA_LIBS += -L$(JAVA_HOME)/$(JAVA_LIBDIR)/classic -ljvm
+ endif
JAVA_LIBS += -L$(JAVA_HOME)/$(JAVA_LIBDIR) -ljava
JAVA_LIBS += $(JAVA_CLIBS)
@@ -246,7 +258,7 @@ ifeq ($(OS_TARGET), Linux)
endif
# set [IBM AIX] platforms
-ifeq ($(OS_TARGET), AIX)
+ifeq ($(OS_ARCH), AIX)
JAVA_CLASSES = $(JAVA_HOME)/lib/classes.zip
ifeq ($(JRE_HOME),)
@@ -285,7 +297,7 @@ ifeq ($(OS_TARGET), AIX)
endif
# set [Digital UNIX] platforms
-ifeq ($(OS_TARGET), OSF1)
+ifeq ($(OS_ARCH), OSF1)
JAVA_CLASSES = $(JAVA_HOME)/lib/classes.zip
ifeq ($(JRE_HOME),)
@@ -324,7 +336,7 @@ ifeq ($(OS_TARGET), OSF1)
endif
# set [Silicon Graphics IRIX] platforms
-ifeq ($(OS_TARGET), IRIX)
+ifeq ($(OS_ARCH), IRIX)
JAVA_CLASSES = $(JAVA_HOME)/lib/dev.jar:$(JAVA_HOME)/lib/rt.jar
ifeq ($(JRE_HOME),)
@@ -396,6 +408,9 @@ ifeq ($(JDK_CLASSPATH_OPT),)
JDK_CLASSPATH_OPT = -classpath $(JDK_CLASSPATH)
endif
+ifeq ($(USE_64), 1)
+ JDK_USE_64 = -d64
+endif
endif
@@ -437,6 +452,7 @@ ifeq ($(JAVA),)
JAVA_FLAGS += $(JDK_DEBUG_OPT)
JAVA_FLAGS += $(JDK_CLASSPATH_OPT)
JAVA_FLAGS += $(JDK_JIT_OPT)
+ JAVA_FLAGS += $(JDK_USE_64)
JAVA = $(JAVA_PROG) $(JAVA_FLAGS)
endif
@@ -451,6 +467,7 @@ ifeq ($(JAVAC),)
JAVAC_FLAGS += $(JDK_DEBUG_OPT)
JAVAC_FLAGS += $(JDK_CLASSPATH_OPT)
JAVAC_FLAGS += $(JDK_CLASS_REPOSITORY_OPT)
+ JAVAC_FLAGS += $(JDK_USE_64)
JAVAC = $(JAVAC_PROG) $(JAVAC_FLAGS)
endif
diff --git a/security/nss/cmd/certutil/certutil.c b/security/nss/cmd/certutil/certutil.c
index 772c7d215..adaa87d77 100644
--- a/security/nss/cmd/certutil/certutil.c
+++ b/security/nss/cmd/certutil/certutil.c
@@ -233,13 +233,13 @@ GetCertRequest(PRFileDesc *inFile, PRBool ascii)
data
*/
PORT_Memset(&signedData, 0, sizeof(signedData));
- rv = SEC_ASN1DecodeItem(arena, &signedData, CERT_SignedDataTemplate,
- &reqDER);
+ rv = SEC_ASN1DecodeItem(arena, &signedData,
+ SEC_ASN1_GET(CERT_SignedDataTemplate), &reqDER);
if (rv)
break;
- rv = SEC_ASN1DecodeItem(arena, certReq, CERT_CertificateRequestTemplate,
- &signedData.data);
+ rv = SEC_ASN1DecodeItem(arena, certReq,
+ SEC_ASN1_GET(CERT_CertificateRequestTemplate), &signedData.data);
} while (0);
if (rv) {
@@ -308,42 +308,12 @@ AddCert(PK11SlotInfo *slot, CERTCertDBHandle *handle, char *name, char *trusts,
GEN_BREAK(SECFailure);
}
-#ifdef notdef
- /* CERT_ImportCert only collects certificates and returns the
- * first certficate. It does not insert these certificates into
- * the dbase. For now, just call CERT_NewTempCertificate.
- * This will result in decoding the der twice. This have to
- * be handle properly.
- */
-
- tempCert = CERT_NewTempCertificate(handle, &cert->derCert, NULL,
- PR_FALSE, PR_TRUE);
-
- if (!PK11_IsInternal(slot)) {
- tempCert->trust = trust;
-
- rv = PK11_ImportCertForKeyToSlot(slot, tempCert, name,
- PR_FALSE, NULL);
- }
-
- if (tempCert == NULL) {
- SECU_PrintError(progName,"unable to add cert to the temp database");
- GEN_BREAK(SECFailure);
- }
-
- rv = CERT_AddTempCertToPerm(tempCert, name, trust);
- if (rv) {
- SECU_PrintError(progName, "could not add certificate to database");
- GEN_BREAK(SECFailure);
- }
-
- if ( emailcert )
- CERT_SaveSMimeProfile(tempCert, NULL, NULL);
-#else
- rv = PK11_Authenticate(slot, PR_TRUE, pwdata);
- if (rv != SECSuccess) {
- SECU_PrintError(progName, "could authenticate to token or database");
- GEN_BREAK(SECFailure);
+ if (!PK11_IsFriendly(slot)) {
+ rv = PK11_Authenticate(slot, PR_TRUE, pwdata);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "could not authenticate to token or database");
+ GEN_BREAK(SECFailure);
+ }
}
rv = PK11_ImportCert(slot, cert, CK_INVALID_HANDLE, name, PR_FALSE);
@@ -362,12 +332,8 @@ AddCert(PK11SlotInfo *slot, CERTCertDBHandle *handle, char *name, char *trusts,
CERT_SaveSMimeProfile(cert, NULL, pwdata);
}
-#endif
} while (0);
-#ifdef notdef
- CERT_DestroyCertificate (tempCert);
-#endif
CERT_DestroyCertificate (cert);
PORT_Free(trust);
PORT_Free(certDER.data);
@@ -409,7 +375,7 @@ CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType,
/* Der encode the request */
encoding = SEC_ASN1EncodeItem(arena, NULL, cr,
- CERT_CertificateRequestTemplate);
+ SEC_ASN1_GET(CERT_CertificateRequestTemplate));
if (encoding == NULL) {
SECU_PrintError(progName, "der encoding of request failed");
return SECFailure;
@@ -530,6 +496,7 @@ ChangeTrustAttributes(CERTCertDBHandle *handle, char *name, char *trusts)
SECU_PrintError(progName, "unable to modify trust attributes");
return SECFailure;
}
+ CERT_DestroyCertificate(cert);
return SECSuccess;
}
@@ -577,6 +544,7 @@ dumpChain(CERTCertDBHandle *handle, char *name, PK11SlotInfo *slot,
return SECFailure;
}
chain = CERT_CertChainFromCert(the_cert, 0, PR_TRUE);
+ CERT_DestroyCertificate(the_cert);
if (!chain) {
SECU_PrintError(progName, "Could not obtain chain for: %s\n", name);
return SECFailure;
@@ -586,7 +554,9 @@ dumpChain(CERTCertDBHandle *handle, char *name, PK11SlotInfo *slot,
c = CERT_FindCertByDERCert(handle, &chain->certs[i]);
for (j=i; j<chain->len-1; j++) printf(" ");
printf("\"%s\" [%s]\n\n", c->nickname, c->subjectName);
+ CERT_DestroyCertificate(c);
}
+ CERT_DestroyCertificateList(chain);
return SECSuccess;
}
@@ -597,86 +567,53 @@ listCerts(CERTCertDBHandle *handle, char *name, PK11SlotInfo *slot,
CERTCertificate *cert;
SECItem data;
PRInt32 numBytes;
- SECStatus rv;
+ SECStatus rv = SECFailure;
-#ifdef nodef
- /* For now, split handling of slot to internal vs. other. slot should
- * probably be allowed to be NULL so that all slots can be listed.
- * In that case, need to add a call to PK11_TraverseSlotCerts().
- */
- if (PK11_IsInternal(slot)) {
- if (name == NULL) {
- /* Print all certs in internal slot db. */
- rv = SECU_PrintCertificateNames(handle, PR_STDOUT,
- PR_FALSE, PR_TRUE);
- if (rv) {
- SECU_PrintError(progName,
- "problem printing certificate nicknames");
- return SECFailure;
- }
- } else if (raw || ascii) {
- /* Dump binary or ascii DER for the cert to stdout. */
- cert = CERT_FindCertByNicknameOrEmailAddr(handle, name);
- if (!cert) {
- SECU_PrintError(progName,
- "could not find certificate named \"%s\"", name);
- return SECFailure;
- }
- data.data = cert->derCert.data;
- data.len = cert->derCert.len;
- if (ascii) {
- PR_fprintf(outfile, "%s\n%s\n%s\n", NS_CERT_HEADER,
+ /* List certs on a non-internal slot. */
+ if (!PK11_IsFriendly(slot) && PK11_NeedLogin(slot))
+ PK11_Authenticate(slot, PR_TRUE, pwarg);
+ if (name) {
+ CERTCertificate *the_cert;
+ the_cert = PK11_FindCertFromNickname(name, NULL);
+ if (!the_cert) {
+ SECU_PrintError(progName, "Could not find: %s\n", name);
+ return SECFailure;
+ }
+ data.data = the_cert->derCert.data;
+ data.len = the_cert->derCert.len;
+ if (ascii) {
+ PR_fprintf(outfile, "%s\n%s\n%s\n", NS_CERT_HEADER,
BTOA_DataToAscii(data.data, data.len), NS_CERT_TRAILER);
- } else if (raw) {
- numBytes = PR_Write(outfile, data.data, data.len);
- if (numBytes != data.len) {
- SECU_PrintSystemError(progName, "error writing raw cert");
- return SECFailure;
- }
+ rv = SECSuccess;
+ } else if (raw) {
+ numBytes = PR_Write(outfile, data.data, data.len);
+ if (numBytes != data.len) {
+ SECU_PrintSystemError(progName, "error writing raw cert");
+ rv = SECFailure;
}
+ rv = SECSuccess;
} else {
- /* Pretty-print cert. */
- rv = CERT_TraversePermCertsForNickname(handle, name, printCertCB,
- NULL);
+ rv = printCertCB(the_cert, the_cert->trust);
}
+ CERT_DestroyCertificate(the_cert);
} else {
-#endif
- /* List certs on a non-internal slot. */
- if (!PK11_IsFriendly(slot) && PK11_NeedLogin(slot))
- PK11_Authenticate(slot, PR_TRUE, pwarg);
- if (name) {
- CERTCertificate *the_cert;
- the_cert = PK11_FindCertFromNickname(name, NULL);
- if (!the_cert) {
- SECU_PrintError(progName, "Could not find: %s\n", name);
- return SECFailure;
+ CERTCertList *certs;
+ CERTCertListNode *node;
+
+ certs = PK11_ListCertsInSlot(slot);
+ if (certs) {
+ for (node = CERT_LIST_HEAD(certs); !CERT_LIST_END(node,certs);
+ node = CERT_LIST_NEXT(node)) {
+ SECU_PrintCertNickname(node->cert,stdout);
}
- data.data = the_cert->derCert.data;
- data.len = the_cert->derCert.len;
- if (ascii) {
- PR_fprintf(outfile, "%s\n%s\n%s\n", NS_CERT_HEADER,
- BTOA_DataToAscii(data.data, data.len), NS_CERT_TRAILER);
- rv = SECSuccess;
- } else if (raw) {
- numBytes = PR_Write(outfile, data.data, data.len);
- if (numBytes != data.len) {
- SECU_PrintSystemError(progName, "error writing raw cert");
- rv = SECFailure;
- }
- rv = SECSuccess;
- } else {
- rv = printCertCB(the_cert, the_cert->trust);
- }
- } else {
- rv = PK11_TraverseCertsInSlot(slot, SECU_PrintCertNickname, stdout);
- }
- if (rv) {
- SECU_PrintError(progName, "problem printing certificate nicknames");
- return SECFailure;
+ CERT_DestroyCertList(certs);
+ rv = SECSuccess;
}
-#ifdef notdef
}
-#endif
+ if (rv) {
+ SECU_PrintError(progName, "problem printing certificate nicknames");
+ return SECFailure;
+ }
return SECSuccess; /* not rv ?? */
}
@@ -742,6 +679,7 @@ DeleteCert(CERTCertDBHandle *handle, char *name)
}
rv = SEC_DeletePermCertificate(cert);
+ CERT_DestroyCertificate(cert);
if (rv) {
SECU_PrintError(progName, "unable to delete certificate");
return SECFailure;
@@ -755,7 +693,7 @@ ValidateCert(CERTCertDBHandle *handle, char *name, char *date,
char *certUsage, PRBool checkSig, PRBool logit, secuPWData *pwdata)
{
SECStatus rv;
- CERTCertificate *cert;
+ CERTCertificate *cert = NULL;
int64 timeBoundary;
SECCertUsage usage;
CERTVerifyLog reallog;
@@ -844,84 +782,13 @@ ValidateCert(CERTCertDBHandle *handle, char *name, char *date,
}
} while (0);
- return (rv);
-}
-
-#ifdef notdef
-static SECStatus
-DumpPublicKey(int dbindex, char *nickname, FILE *out)
-{
- SECKEYLowPrivateKey *privKey;
- SECKEYLowPublicKey *publicKey;
-
- if (dbindex) {
- /*privKey = secu_GetPrivKeyFromIndex(dbindex);*/
- } else {
- privKey = GetPrivKeyFromNickname(nickname);
+ if (cert) {
+ CERT_DestroyCertificate(cert);
}
- publicKey = SECKEY_LowConvertToPublicKey(privKey);
- /* Output public key (in the clear) */
- switch(publicKey->keyType) {
- case rsaKey:
- fprintf(out, "RSA Public-Key:\n");
- SECU_PrintInteger(out, &publicKey->u.rsa.modulus, "modulus", 1);
- SECU_PrintInteger(out, &publicKey->u.rsa.publicExponent,
- "publicExponent", 1);
- break;
- case dsaKey:
- fprintf(out, "DSA Public-Key:\n");
- SECU_PrintInteger(out, &publicKey->u.dsa.params.prime, "prime", 1);
- SECU_PrintInteger(out, &publicKey->u.dsa.params.subPrime,
- "subPrime", 1);
- SECU_PrintInteger(out, &publicKey->u.dsa.params.base, "base", 1);
- SECU_PrintInteger(out, &publicKey->u.dsa.publicValue, "publicValue", 1);
- break;
- default:
- fprintf(out, "unknown key type\n");
- break;
- }
- return SECSuccess;
+ return (rv);
}
-static SECStatus
-DumpPrivateKey(int dbindex, char *nickname, FILE *out)
-{
- SECKEYLowPrivateKey *key;
- if (dbindex) {
- /*key = secu_GetPrivKeyFromIndex(dbindex);*/
- } else {
- key = GetPrivKeyFromNickname(nickname);
- }
-
- switch(key->keyType) {
- case rsaKey:
- fprintf(out, "RSA Private-Key:\n");
- SECU_PrintInteger(out, &key->u.rsa.modulus, "modulus", 1);
- SECU_PrintInteger(out, &key->u.rsa.publicExponent, "publicExponent", 1);
- SECU_PrintInteger(out, &key->u.rsa.privateExponent,
- "privateExponent", 1);
- SECU_PrintInteger(out, &key->u.rsa.prime1, "prime1", 1);
- SECU_PrintInteger(out, &key->u.rsa.prime2, "prime2", 1);
- SECU_PrintInteger(out, &key->u.rsa.exponent1, "exponent2", 1);
- SECU_PrintInteger(out, &key->u.rsa.exponent2, "exponent2", 1);
- SECU_PrintInteger(out, &key->u.rsa.coefficient, "coefficient", 1);
- break;
- case dsaKey:
- fprintf(out, "DSA Private-Key:\n");
- SECU_PrintInteger(out, &key->u.dsa.params.prime, "prime", 1);
- SECU_PrintInteger(out, &key->u.dsa.params.subPrime, "subPrime", 1);
- SECU_PrintInteger(out, &key->u.dsa.params.base, "base", 1);
- SECU_PrintInteger(out, &key->u.dsa.publicValue, "publicValue", 1);
- SECU_PrintInteger(out, &key->u.dsa.privateValue, "privateValue", 1);
- break;
- default:
- fprintf(out, "unknown key type\n");
- break;
- }
- return SECSuccess;
-}
-#endif
static SECStatus
printKeyCB(SECKEYPublicKey *key, SECItem *data, void *arg)
@@ -936,31 +803,19 @@ printKeyCB(SECKEYPublicKey *key, SECItem *data, void *arg)
return SECSuccess;
}
-struct secuCBData {
- FILE *file;
- int keycount;
- void *wincx;
-};
-
/* callback for listing certs through pkcs11 */
static SECStatus
-secu_PrintKeyFromCert(CERTCertificate *cert, void *data)
+secu_PrintKey(FILE *out, int count, SECKEYPrivateKey *key)
{
- FILE *out;
- struct secuCBData *cbdata;
- SECKEYPrivateKey *key;
-
- cbdata = (struct secuCBData *)data;
- out = cbdata->file;
- key = PK11_FindPrivateKeyFromCert(cert->slot, cert, cbdata->wincx);
- if (!key) {
- fprintf(out, "XXX could not extract key for %s.\n", cert->nickname);
- return SECFailure;
- }
- /* XXX should have a type field also */
- fprintf(out, "<%d> %s\n", 0, cert->nickname);
+ char *name;
- cbdata->keycount++;
+ name = PK11_GetPrivateKeyNickname(key);
+ if (name == NULL) {
+ /* should look up associated cert */
+ name = PORT_Strdup("< orphaned >");
+ }
+ fprintf(out, "<%d> %s\n", count, name);
+ PORT_Free(name);
return SECSuccess;
}
@@ -968,43 +823,29 @@ secu_PrintKeyFromCert(CERTCertificate *cert, void *data)
static SECStatus
listKeys(PK11SlotInfo *slot, KeyType keyType, void *pwarg)
{
- SECStatus rv = SECSuccess;
- struct secuCBData cbdata;
+ SECKEYPrivateKeyList *list;
+ SECKEYPrivateKeyListNode *node;
+ int count;
- cbdata.keycount = 0;
- cbdata.file = stdout;
- cbdata.wincx = pwarg;
-
-#ifdef notdef
- if (PK11_IsInternal(slot)) {
- /* Print all certs in internal slot db. */
- rv = SECU_PrintKeyNames(SECKEY_GetDefaultKeyDB(), stdout);
- if (rv) {
- SECU_PrintError(progName, "problem listing keys");
- return SECFailure;
- }
- } else {
-#endif
- /* XXX need a function as below */
- /* could iterate over certs on slot and print keys */
- /* this would miss stranded keys */
- /*rv = PK11_TraverseSlotKeys(slotname, keyType, printKeyCB, NULL, NULL);*/
- if (PK11_NeedLogin(slot))
+ if (PK11_NeedLogin(slot))
PK11_Authenticate(slot, PR_TRUE, pwarg);
- rv = PK11_TraverseCertsInSlot(slot, secu_PrintKeyFromCert, &cbdata);
- if (rv) {
- SECU_PrintError(progName, "problem listing keys");
- return SECFailure;
- }
- if (cbdata.keycount == 0) {
- SECU_PrintError(progName, "no keys found");
- return SECFailure;
- }
- return SECSuccess;
-#ifdef notdef
+
+ list = PK11_ListPrivateKeysInSlot(slot);
+ if (list == NULL) {
+ SECU_PrintError(progName, "problem listing keys");
+ return SECFailure;
}
- return rv;
-#endif
+ for (count=0, node=PRIVKEY_LIST_HEAD(list) ; !PRIVKEY_LIST_END(node,list);
+ node= PRIVKEY_LIST_NEXT(node),count++) {
+ secu_PrintKey(stdout, count, node->key);
+ }
+ SECKEY_DestroyPrivateKeyList(list);
+
+ if (count == 0) {
+ SECU_PrintError(progName, "no keys found");
+ return SECFailure;
+ }
+ return SECSuccess;
}
static SECStatus
@@ -1013,19 +854,6 @@ ListKeys(PK11SlotInfo *slot, char *keyname, int index,
{
SECStatus rv = SECSuccess;
-#ifdef notdef
- if (keyname) {
- if (dopriv) {
- return DumpPrivateKey(index, keyname, stdout);
- } else {
- return DumpPublicKey(index, keyname, stdout);
- }
- }
-#endif
- /* For now, split handling of slot to internal vs. other. slot should
- * probably be allowed to be NULL so that all slots can be listed.
- * In that case, need to add a call to PK11_TraverseSlotCerts().
- */
if (slot == NULL) {
PK11SlotList *list;
PK11SlotListElement *le;
@@ -1051,11 +879,16 @@ DeleteKey(char *nickname, secuPWData *pwdata)
if (PK11_NeedLogin(slot))
PK11_Authenticate(slot, PR_TRUE, pwdata);
cert = PK11_FindCertFromNickname(nickname, pwdata);
- if (!cert) return SECFailure;
+ if (!cert) {
+ PK11_FreeSlot(slot);
+ return SECFailure;
+ }
rv = PK11_DeleteTokenCertAndKey(cert, pwdata);
if (rv != SECSuccess) {
SECU_PrintError("problem deleting private key \"%s\"\n", nickname);
}
+ CERT_DestroyCertificate(cert);
+ PK11_FreeSlot(slot);
return rv;
}
@@ -1565,6 +1398,14 @@ CreateOidSequence(void)
return (CERTOidSequence *)NULL;
}
+static void
+DestroyOidSequence(CERTOidSequence *os)
+{
+ if (os->arena) {
+ PORT_FreeArena(os->arena, PR_FALSE);
+ }
+}
+
static SECStatus
AddOidToSequence(CERTOidSequence *os, SECOidTag oidTag)
{
@@ -1604,11 +1445,19 @@ AddOidToSequence(CERTOidSequence *os, SECOidTag oidTag)
return SECSuccess;
}
+SEC_ASN1_MKSUB(SEC_ObjectIDTemplate);
+
+const SEC_ASN1Template CERT_OidSeqTemplate[] = {
+ { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN,
+ offsetof(CERTOidSequence, oids),
+ SEC_ASN1_SUB(SEC_ObjectIDTemplate) }
+};
+
+
static SECItem *
EncodeOidSequence(CERTOidSequence *os)
{
SECItem *rv;
- extern const SEC_ASN1Template CERT_OidSeqTemplate[];
rv = (SECItem *)PORT_ArenaZAlloc(os->arena, sizeof(SECItem));
if( (SECItem *)NULL == rv ) {
@@ -1697,7 +1546,7 @@ AddExtKeyUsage (void *extHandle)
? PR_TRUE : PR_FALSE), PR_TRUE);
/*FALLTHROUGH*/
loser:
- CERT_DestroyOidSequence(os);
+ DestroyOidSequence(os);
return rv;
}
@@ -1809,7 +1658,7 @@ AddBasicConstraint(void *extHandle)
static SECItem *
SignCert(CERTCertDBHandle *handle,
CERTCertificate *cert, PRBool selfsign,
-SECKEYPrivateKey *selfsignprivkey, char *issuerNickName, void *pwarg)
+SECKEYPrivateKey *privKey, char *issuerNickName, void *pwarg)
{
SECItem der;
SECItem *result = NULL;
@@ -1819,10 +1668,7 @@ SECKEYPrivateKey *selfsignprivkey, char *issuerNickName, void *pwarg)
SECOidTag algID;
void *dummy;
- if( selfsign ) {
- caPrivateKey = selfsignprivkey;
- } else {
- /*CERTCertificate *issuer = CERT_FindCertByNickname(handle, issuerNickName);*/
+ if( !selfsign ) {
CERTCertificate *issuer = PK11_FindCertFromNickname(issuerNickName, pwarg);
if( (CERTCertificate *)NULL == issuer ) {
SECU_PrintError(progName, "unable to find issuer with nickname %s",
@@ -1830,7 +1676,8 @@ SECKEYPrivateKey *selfsignprivkey, char *issuerNickName, void *pwarg)
return (SECItem *)NULL;
}
- caPrivateKey = PK11_FindKeyByAnyCert(issuer, pwarg);
+ privKey = caPrivateKey = PK11_FindKeyByAnyCert(issuer, pwarg);
+ CERT_DestroyCertificate(issuer);
if (caPrivateKey == NULL) {
SECU_PrintError(progName, "unable to retrieve key %s", issuerNickName);
return NULL;
@@ -1839,7 +1686,7 @@ SECKEYPrivateKey *selfsignprivkey, char *issuerNickName, void *pwarg)
arena = cert->arena;
- switch(caPrivateKey->keyType) {
+ switch(privKey->keyType) {
case rsaKey:
algID = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION;
break;
@@ -1864,7 +1711,8 @@ SECKEYPrivateKey *selfsignprivkey, char *issuerNickName, void *pwarg)
der.len = 0;
der.data = NULL;
- dummy = SEC_ASN1EncodeItem (arena, &der, cert, CERT_CertificateTemplate);
+ dummy = SEC_ASN1EncodeItem (arena, &der, cert,
+ SEC_ASN1_GET(CERT_CertificateTemplate));
if (!dummy) {
fprintf (stderr, "Could not encode certificate.\n");
goto done;
@@ -1876,7 +1724,7 @@ SECKEYPrivateKey *selfsignprivkey, char *issuerNickName, void *pwarg)
goto done;
}
- rv = SEC_DerSignData (arena, result, der.data, der.len, caPrivateKey,
+ rv = SEC_DerSignData (arena, result, der.data, der.len, privKey,
algID);
if (rv != SECSuccess) {
fprintf (stderr, "Could not sign encoded certificate data.\n");
@@ -1886,7 +1734,9 @@ SECKEYPrivateKey *selfsignprivkey, char *issuerNickName, void *pwarg)
}
cert->derCert = *result;
done:
- SECKEY_DestroyPrivateKey(caPrivateKey);
+ if (caPrivateKey) {
+ SECKEY_DestroyPrivateKey(caPrivateKey);
+ }
return result;
}
@@ -2331,7 +2181,7 @@ main(int argc, char **argv)
secuPWData pwdata = { PW_NONE, 0 };
PRBool readOnly = PR_FALSE;
- SECKEYPrivateKey *privkey;
+ SECKEYPrivateKey *privkey = NULL;
SECKEYPublicKey *pubkey = NULL;
int i;
@@ -2873,15 +2723,16 @@ main(int argc, char **argv)
}
shutdown:
- if (slot)
+ if (slot) {
PK11_FreeSlot(slot);
-#ifdef notdef
- if ( certHandle ) {
- CERT_ClosePermCertDB(certHandle);
}
-#else
+ if (privkey) {
+ SECKEY_DestroyPrivateKey(privkey);
+ }
+ if (pubkey) {
+ SECKEY_DestroyPublicKey(pubkey);
+ }
NSS_Shutdown();
-#endif
if (rv == SECSuccess) {
return 0;
diff --git a/security/nss/cmd/certutil/keystuff.c b/security/nss/cmd/certutil/keystuff.c
index 2926f8f1b..317443a27 100644
--- a/security/nss/cmd/certutil/keystuff.c
+++ b/security/nss/cmd/certutil/keystuff.c
@@ -68,6 +68,14 @@ extern char *sys_errlist[];
#define ERROR_BREAK rv = SECFailure;break;
+const SEC_ASN1Template SECKEY_PQGParamsTemplate[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPQGParams) },
+ { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,prime) },
+ { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,subPrime) },
+ { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,base) },
+ { 0, }
+};
+
/* returns 0 for success, -1 for failure (EOF encountered) */
static int
UpdateRNG(void)
@@ -126,8 +134,7 @@ UpdateRNG(void)
rv = -1;
break;
}
- RNG_GetNoise(&randbuf[1], sizeof(randbuf)-1);
- RNG_RandomUpdate(randbuf, sizeof(randbuf));
+ PK11_RandomUpdate(randbuf, sizeof(randbuf));
if (c != randbuf[0]) {
randbuf[0] = c;
FPS "\r|");
@@ -189,27 +196,27 @@ static unsigned char G[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a,
0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88,
0x02 };
-static PQGParams default_pqg_params = {
+static SECKEYPQGParams default_pqg_params = {
NULL,
{ 0, P, sizeof(P) },
{ 0, Q, sizeof(Q) },
{ 0, G, sizeof(G) }
};
-static PQGParams *
+static SECKEYPQGParams *
decode_pqg_params(char *str)
{
char *buf;
unsigned int len;
PRArenaPool *arena;
- PQGParams *params;
+ SECKEYPQGParams *params;
SECStatus status;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL)
return NULL;
- params = PORT_ArenaZAlloc(arena, sizeof(PQGParams));
+ params = PORT_ArenaZAlloc(arena, sizeof(SECKEYPQGParams));
if (params == NULL)
goto loser;
params->arena = arena;
@@ -229,11 +236,19 @@ loser:
PORT_FreeArena(arena, PR_FALSE);
return NULL;
}
-
+
+void
+CERTUTIL_DestroyParamsPQG(SECKEYPQGParams *params)
+{
+ if (params->arena) {
+ PORT_FreeArena(params->arena, PR_FALSE);
+ }
+}
+
static int
pqg_prime_bits(char *str)
{
- PQGParams *params = NULL;
+ SECKEYPQGParams *params = NULL;
int primeBits = 0, i;
params = decode_pqg_params(str);
@@ -246,7 +261,7 @@ pqg_prime_bits(char *str)
done:
if (params != NULL)
- PQG_DestroyParams(params);
+ CERTUTIL_DestroyParamsPQG(params);
return primeBits;
}
@@ -270,7 +285,7 @@ SECU_GetpqgString(char *filename)
return NULL;
}
-PQGParams*
+SECKEYPQGParams*
getpqgfromfile(int keyBits, char *pqgFile)
{
char *end, *str, *pqgString;
@@ -302,6 +317,26 @@ found_match:
return decode_pqg_params(str);
}
+void CERTUTIL_FileForRNG(char *noise)
+{
+ char buf[2048];
+ PRFileDesc *fd;
+ PRInt32 count;
+
+ fd = PR_OpenFile(noise,PR_RDONLY,0666);
+ if (!fd) return;
+
+ do {
+ count = PR_Read(fd,buf,sizeof(buf));
+ if (count > 0) {
+ PK11_RandomUpdate(buf,count);
+ }
+ } while (count > 0);
+
+ PR_Close(fd);
+
+}
+
SECKEYPrivateKey *
CERTUTIL_GeneratePrivateKey(KeyType keytype, PK11SlotInfo *slot, int size,
int publicExponent, char *noise,
@@ -311,17 +346,16 @@ CERTUTIL_GeneratePrivateKey(KeyType keytype, PK11SlotInfo *slot, int size,
CK_MECHANISM_TYPE mechanism;
SECOidTag algtag;
PK11RSAGenParams rsaparams;
- PQGParams *dsaparams = NULL;
+ SECKEYPQGParams *dsaparams = NULL;
void *params;
PRArenaPool *dsaparena;
/*
* Do some random-number initialization.
*/
- RNG_SystemInfoForRNG();
if (noise) {
- RNG_FileForRNG(noise);
+ CERTUTIL_FileForRNG(noise);
} else {
int rv = UpdateRNG();
if (rv) {
@@ -346,7 +380,7 @@ CERTUTIL_GeneratePrivateKey(KeyType keytype, PK11SlotInfo *slot, int size,
} else {
dsaparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (dsaparena == NULL) return NULL;
- dsaparams = PORT_ArenaZAlloc(dsaparena, sizeof(PQGParams));
+ dsaparams = PORT_ArenaZAlloc(dsaparena, sizeof(SECKEYPQGParams));
if (dsaparams == NULL) return NULL;
dsaparams->arena = dsaparena;
SECITEM_AllocItem(dsaparena, &dsaparams->prime, sizeof P);
diff --git a/security/nss/cmd/certutil/manifest.mn b/security/nss/cmd/certutil/manifest.mn
index d387540b9..8d93b0116 100644
--- a/security/nss/cmd/certutil/manifest.mn
+++ b/security/nss/cmd/certutil/manifest.mn
@@ -49,4 +49,4 @@ REQUIRES = dbm seccmd
PROGRAM = certutil
-USE_STATIC_LIBS = 1
+#USE_STATIC_LIBS = 1
diff --git a/security/nss/cmd/crmf-cgi/crmfcgi.c b/security/nss/cmd/crmf-cgi/crmfcgi.c
index c5fd2d451..72199cfd5 100644
--- a/security/nss/cmd/crmf-cgi/crmfcgi.c
+++ b/security/nss/cmd/crmf-cgi/crmfcgi.c
@@ -286,6 +286,7 @@ initNSS(CGIVarTable *varTable)
PK11_SetPasswordFunc(passwordCallback);
keySlot = PK11_GetInternalKeySlot();
rv = PK11_Authenticate(keySlot, PR_FALSE, varTable);
+ PK11_FreeSlot(keySlot);
if (rv != SECSuccess) {
return AUTH_FAILED;
}
diff --git a/security/nss/cmd/crmftest/testcrmf.c b/security/nss/cmd/crmftest/testcrmf.c
index db9add0bc..42e02a38c 100644
--- a/security/nss/cmd/crmftest/testcrmf.c
+++ b/security/nss/cmd/crmftest/testcrmf.c
@@ -177,23 +177,28 @@ GetSubjectPubKeyInfo(SECKEYPrivateKey **destPrivKey,
SECKEYPrivateKey *privKey = NULL;
SECKEYPublicKey *pubKey = NULL;
PK11SlotInfo *keySlot = NULL;
+ PK11SlotInfo *cryptoSlot = NULL;
PK11RSAGenParams *rsaParams = NULL;
PQGParams *dsaParams = NULL;
keySlot = PK11_GetInternalKeySlot();
PK11_Authenticate(keySlot, PR_FALSE, NULL);
- PK11_Authenticate(PK11_GetInternalSlot(), PR_FALSE, NULL);
+ cryptoSlot = PK11_GetInternalSlot();
+ PK11_Authenticate(cryptoSlot, PR_FALSE, NULL);
+ PK11_FreeSlot(cryptoSlot);
rsaParams = GetRSAParams();
privKey = PK11_GenerateKeyPair(keySlot, CKM_RSA_PKCS_KEY_PAIR_GEN,
(void*)rsaParams, &pubKey, PR_FALSE,
PR_FALSE, NULL);
/* dsaParams = GetDSAParams();
if (dsaParams == NULL) {
+ PK11_FreeSlot(keySlot);
return NULL;
}
privKey = PK11_GenerateKeyPair(keySlot, CKM_DSA_KEY_PAIR_GEN,
(void*)dsaParams, &pubKey, PR_FALSE,
PR_FALSE, NULL);*/
+ PK11_FreeSlot(keySlot);
if (privKey == NULL || pubKey == NULL) {
if (pubKey) {
SECKEY_DestroyPublicKey(pubKey);
diff --git a/security/nss/cmd/lib/seccnames.c b/security/nss/cmd/lib/seccnames.c
index 833361e41..a1857dc0e 100644
--- a/security/nss/cmd/lib/seccnames.c
+++ b/security/nss/cmd/lib/seccnames.c
@@ -45,7 +45,9 @@
#include "secutil.h"
#include "secpkcs7.h"
#include "secrng.h"
+#if !defined(_WIN32_WCE)
#include <sys/stat.h>
+#endif
#include <stdarg.h>
#ifdef XP_UNIX
diff --git a/security/nss/cmd/lib/secpwd.c b/security/nss/cmd/lib/secpwd.c
index 57c4aac5f..8bc4eef14 100644
--- a/security/nss/cmd/lib/secpwd.c
+++ b/security/nss/cmd/lib/secpwd.c
@@ -46,7 +46,7 @@
#include <unistd.h>
#endif
-#ifdef _WINDOWS
+#if defined(_WINDOWS) && !defined(_WIN32_WCE)
#include <conio.h>
#include <io.h>
#define QUIET_FGETS quiet_fgets
@@ -82,13 +82,16 @@ static void echoOn(int fd)
char *SEC_GetPassword(FILE *input, FILE *output, char *prompt,
PRBool (*ok)(char *))
{
- char phrase[200];
- int infd = fileno(input);
#if defined(_WINDOWS) || defined(OS2)
int isTTY = (input == stdin);
+#define echoOn(x)
+#define echoOff(x)
#else
+ int infd = fileno(input);
int isTTY = isatty(infd);
#endif
+ char phrase[200];
+
for (;;) {
/* Prompt for password */
if (isTTY) {
@@ -167,8 +170,11 @@ static char * quiet_fgets (char *buf, int length, FILE *input)
while (1)
{
- c = getch();
-
+#if defined (_WIN32_WCE)
+ c = getchar(); /* gets a character from stdin */
+#else
+ c = getch(); /* getch gets a character from the console */
+#endif
if (c == '\b')
{
if (end > buf)
diff --git a/security/nss/cmd/lib/secutil.c b/security/nss/cmd/lib/secutil.c
index f7cfb8d59..6b9ab8e3c 100644
--- a/security/nss/cmd/lib/secutil.c
+++ b/security/nss/cmd/lib/secutil.c
@@ -41,13 +41,16 @@
#include "prerror.h"
#include "prprf.h"
#include "plgetopt.h"
+#include "prenv.h"
#include "secutil.h"
#include "secpkcs7.h"
#include "secrng.h"
-#include <sys/stat.h>
#include <stdarg.h>
+#if !defined(_WIN32_WCE)
+#include <sys/stat.h>
#include <errno.h>
+#endif
#ifdef XP_UNIX
#include <unistd.h>
@@ -110,7 +113,11 @@ SECU_PrintSystemError(char *progName, char *msg, ...)
va_start(args, msg);
fprintf(stderr, "%s: ", progName);
vfprintf(stderr, msg, args);
+#if defined(_WIN32_WCE)
+ fprintf(stderr, ": %d\n", PR_GetOSError());
+#else
fprintf(stderr, ": %s\n", strerror(errno));
+#endif
va_end(args);
}
@@ -388,7 +395,7 @@ SECU_DefaultSSLDir(void)
char *dir;
static char sslDir[1000];
- dir = getenv("SSL_DIR");
+ dir = PR_GetEnv("SSL_DIR");
if (!dir)
return NULL;
@@ -424,7 +431,7 @@ SECU_ConfigDirectory(const char* base)
if (base == NULL || *base == 0) {
- home = getenv("HOME");
+ home = PR_GetEnv("HOME");
if (!home) home = "";
if (*home && home[strlen(home) - 1] == '/')
@@ -1586,6 +1593,9 @@ SECU_PrintCertNickname(CERTCertificate *cert, void *data)
if ( name == NULL ) {
name = cert->emailAddr;
}
+ if ( name == NULL ) {
+ name = "(NULL)";
+ }
trust = cert->trust;
if (trust) {
diff --git a/security/nss/cmd/modutil/modutil.c b/security/nss/cmd/modutil/modutil.c
index bba34e69e..2f1886b47 100644
--- a/security/nss/cmd/modutil/modutil.c
+++ b/security/nss/cmd/modutil/modutil.c
@@ -912,6 +912,7 @@ main(int argc, char *argv[])
break;
}
+ NSS_Shutdown();
loser:
PR_Cleanup();
return errcode;
diff --git a/security/nss/cmd/pk12util/pk12util.c b/security/nss/cmd/pk12util/pk12util.c
index 6e2ec7d0d..a559c415d 100644
--- a/security/nss/cmd/pk12util/pk12util.c
+++ b/security/nss/cmd/pk12util/pk12util.c
@@ -476,7 +476,7 @@ P12U_ImportPKCS12Object(char *in_file, PK11SlotInfo *slot,
PR_Close(p12cxt->file);
p12cxt->file = NULL;
- PK11_FreeSlot(slot);
+ /* PK11_FreeSlot(slot); */
rv = SECSuccess;
@@ -832,6 +832,7 @@ main(int argc, char **argv)
}
done:
+ if (slot) PK11_FreeSlot(slot);
NSS_Shutdown();
exit(pk12uErrno);
}
diff --git a/security/nss/cmd/platlibs.mk b/security/nss/cmd/platlibs.mk
index a40e0a89f..0a8bfb567 100644
--- a/security/nss/cmd/platlibs.mk
+++ b/security/nss/cmd/platlibs.mk
@@ -75,7 +75,7 @@ EXTRA_LIBS += \
$(NULL)
# $(PROGRAM) has NO explicit dependencies on $(OS_LIBS)
-OS_LIBS += \
+#OS_LIBS += \
wsock32.lib \
winmm.lib \
$(NULL)
@@ -155,7 +155,7 @@ EXTRA_LIBS += \
$(NULL)
# $(PROGRAM) has NO explicit dependencies on $(OS_LIBS)
-OS_LIBS += \
+#OS_LIBS += \
wsock32.lib \
winmm.lib \
$(NULL)
diff --git a/security/nss/cmd/rsaperf/defkey.c b/security/nss/cmd/rsaperf/defkey.c
index fe4870d77..3dd4fe36c 100644
--- a/security/nss/cmd/rsaperf/defkey.c
+++ b/security/nss/cmd/rsaperf/defkey.c
@@ -38,6 +38,7 @@
#include "secoidt.h"
#include "lowkeyti.h"
+#undef CONST
#define CONST
static CONST unsigned char default_n[128] = {
diff --git a/security/nss/cmd/sdrtest/sdrtest.c b/security/nss/cmd/sdrtest/sdrtest.c
index 3124ef6cf..9578b3472 100644
--- a/security/nss/cmd/sdrtest/sdrtest.c
+++ b/security/nss/cmd/sdrtest/sdrtest.c
@@ -233,7 +233,10 @@ file_loser:
PK11_GetSlotName(slot));
return SECFailure;
}
+ }
+ if (slot) {
PK11_FreeSlot(slot);
+ slot == NULL;
}
rv = PK11SDR_Encrypt(&keyid, &data, &result, 0);
diff --git a/security/nss/cmd/signtool/certgen.c b/security/nss/cmd/signtool/certgen.c
index dd7128eaa..00222044d 100644
--- a/security/nss/cmd/signtool/certgen.c
+++ b/security/nss/cmd/signtool/certgen.c
@@ -45,8 +45,8 @@ static SECStatus ChangeTrustAttributes(CERTCertDBHandle *db,
CERTCertificate *cert, char *trusts);
static SECStatus set_cert_type(CERTCertificate *cert, unsigned int type);
static SECItem *sign_cert(CERTCertificate *cert, SECKEYPrivateKey *privk);
-static CERTCertificate* install_cert(CERTCertDBHandle *db, PK11SlotInfo *slot,
- SECItem *derCert, char *nickname);
+static CERTCertificate* install_cert(CERTCertDBHandle *db, SECItem *derCert,
+ char *nickname);
static SECStatus GenerateKeyPair(PK11SlotInfo *slot, SECKEYPublicKey **pubk,
SECKEYPrivateKey **privk, int keysize);
static CERTCertificateRequest* make_cert_request(char *subject,
@@ -333,7 +333,7 @@ GenerateSelfSignedObjectSigningCert(char *nickname, CERTCertDBHandle *db,
}
derCert = sign_cert (temp_cert, privk);
- cert = install_cert(db, slot, derCert, nickname);
+ cert = install_cert(db, derCert, nickname);
if(ChangeTrustAttributes(db, cert, ",,uC") != SECSuccess) {
FatalError("Unable to change trust on generated certificate");
}
@@ -491,11 +491,9 @@ sign_cert(CERTCertificate *cert, SECKEYPrivateKey *privk)
* Installs the cert in the permanent database.
*/
static CERTCertificate*
-install_cert(CERTCertDBHandle *db, PK11SlotInfo *slot, SECItem *derCert,
- char *nickname)
+install_cert(CERTCertDBHandle *db, SECItem *derCert, char *nickname)
{
CERTCertificate *newcert;
- CERTCertTrust trust;
PK11SlotInfo *newSlot;
newcert = CERT_DecodeDERCertificate(derCert, PR_TRUE, NULL);
@@ -507,31 +505,12 @@ install_cert(CERTCertDBHandle *db, PK11SlotInfo *slot, SECItem *derCert,
}
newSlot = PK11_ImportCertForKey(newcert, nickname, NULL /*wincx*/);
- if( slot == NULL ) {
+ if( newSlot == NULL ) {
PR_fprintf(errorFD, "Unable to install certificate\n");
errorCount++;
exit(ERRX);
}
-
- PORT_Memset ((void *) &trust, 0, sizeof(trust));
- trust.objectSigningFlags |= CERTDB_USER;
-
- if( newSlot == PK11_GetInternalKeySlot() ) {
- /* newcert is now a permanent cert */
- if( CERT_ChangeCertTrust(db, newcert, &trust) != SECSuccess) {
- PR_fprintf(errorFD,
- "Failed to change trust of generated certificate\n");
- errorCount++;
- exit(ERRX);
- }
- } else {
- if (CERT_AddTempCertToPerm (newcert, nickname, &trust) != SECSuccess) {
- PR_fprintf(errorFD, "%s: Failure adding \"%s\" certificate to "
- "permanent DB\n", PROGRAM_NAME, nickname);
- errorCount++;
- exit (ERRX);
- }
- }
+ PK11_FreeSlot(newSlot);
if(verbosity >= 0){
PR_fprintf(outputFD, "certificate \"%s\" added to database\n", nickname);
diff --git a/security/nss/cmd/signtool/util.c b/security/nss/cmd/signtool/util.c
index 321fe6859..4b4febe28 100644
--- a/security/nss/cmd/signtool/util.c
+++ b/security/nss/cmd/signtool/util.c
@@ -285,6 +285,11 @@ VerifyCertDir(char *dir, char *keyName)
{
char fn [FNSIZE];
+ /* don't try verifying if we don't have a local directory */
+ if (strncmp(dir,"multiaccess:",sizeof("multiaccess:")-1) == 0) {
+ return;
+ }
+
sprintf (fn, "%s/cert7.db", dir);
if (PR_Access (fn, PR_ACCESS_EXISTS))
@@ -804,8 +809,10 @@ InitCrypto(char *cert_dir, PRBool readOnly)
NULL /*wincx*/) != SECSuccess) {
fprintf(stderr, "%s: Unable to authenticate to %s.\n",
PROGRAM_NAME, PK11_GetSlotName(slotinfo));
+ PK11_FreeSlot(slotinfo);
return -1;
}
+ PK11_FreeSlot(slotinfo);
}
/* Make sure there is a password set on the internal key slot */
@@ -828,9 +835,11 @@ InitCrypto(char *cert_dir, PRBool readOnly)
NULL /*wincx*/) != SECSuccess) {
fprintf(stderr, "%s: Unable to authenticate to %s.\n",
PROGRAM_NAME, PK11_GetSlotName(slotinfo));
+ PK11_FreeSlot(slotinfo);
return -1;
}
}
+ PK11_FreeSlot(slotinfo);
}
return 0;
diff --git a/security/nss/cmd/smimetools/cmsutil.c b/security/nss/cmd/smimetools/cmsutil.c
index 92263f1bb..ec2fe56e8 100644
--- a/security/nss/cmd/smimetools/cmsutil.c
+++ b/security/nss/cmd/smimetools/cmsutil.c
@@ -390,7 +390,7 @@ signed_data(struct signOptionsStr *signOptions)
NSSCMSContentInfo *cinfo;
NSSCMSSignedData *sigd;
NSSCMSSignerInfo *signerinfo;
- CERTCertificate *cert, *ekpcert;
+ CERTCertificate *cert= NULL, *ekpcert = NULL;
if (cms_verbose) {
fprintf(stderr, "Input to signed_data:\n");
@@ -563,8 +563,20 @@ signed_data(struct signOptionsStr *signOptions)
if (cms_verbose) {
fprintf(stderr, "created signed-date message\n");
}
+ if (ekpcert) {
+ CERT_DestroyCertificate(ekpcert);
+ }
+ if (cert) {
+ CERT_DestroyCertificate(cert);
+ }
return cmsg;
loser:
+ if (ekpcert) {
+ CERT_DestroyCertificate(ekpcert);
+ }
+ if (cert) {
+ CERT_DestroyCertificate(cert);
+ }
NSS_CMSMessage_Destroy(cmsg);
return NULL;
}
@@ -576,11 +588,11 @@ enveloped_data(struct envelopeOptionsStr *envelopeOptions)
NSSCMSContentInfo *cinfo;
NSSCMSEnvelopedData *envd;
NSSCMSRecipientInfo *recipientinfo;
- CERTCertificate **recipientcerts;
+ CERTCertificate **recipientcerts = NULL;
CERTCertDBHandle *dbhandle;
PLArenaPool *tmppoolp = NULL;
SECOidTag bulkalgtag;
- int keysize, i;
+ int keysize, i = 0;
int cnt;
dbhandle = envelopeOptions->options->certHandle;
/* count the recipients */
@@ -607,10 +619,12 @@ enveloped_data(struct envelopeOptionsStr *envelopeOptions)
== NULL) {
SECU_PrintError(progName, "cannot find certificate for \"%s\"",
envelopeOptions->recipients[i]);
+ i=0;
goto loser;
}
}
recipientcerts[i] = NULL;
+ i=0;
/* find a nice bulk algorithm */
if (NSS_SMIMEUtil_FindBulkAlgForRecipients(recipientcerts, &bulkalgtag,
&keysize) != SECSuccess) {
@@ -661,11 +675,17 @@ enveloped_data(struct envelopeOptionsStr *envelopeOptions)
fprintf(stderr, "ERROR: cannot add CMS recipientInfo object.\n");
goto loser;
}
+ CERT_DestroyCertificate(recipientcerts[i]);
}
if (tmppoolp)
PORT_FreeArena(tmppoolp, PR_FALSE);
return cmsg;
loser:
+ if (recipientcerts) {
+ for (; recipientcerts[i] != NULL; i++) {
+ CERT_DestroyCertificate(recipientcerts[i]);
+ }
+ }
if (cmsg)
NSS_CMSMessage_Destroy(cmsg);
if (tmppoolp)
@@ -829,10 +849,10 @@ signed_data_certsonly(struct certsonlyOptionsStr *certsonlyOptions)
NSSCMSMessage *cmsg = NULL;
NSSCMSContentInfo *cinfo;
NSSCMSSignedData *sigd;
- CERTCertificate **certs;
+ CERTCertificate **certs = NULL;
CERTCertDBHandle *dbhandle;
PLArenaPool *tmppoolp = NULL;
- int i, cnt;
+ int i = 0, cnt;
dbhandle = certsonlyOptions->options->certHandle;
if ((cnt = nss_CMSArray_Count((void**)certsonlyOptions->recipients)) == 0) {
fprintf(stderr,
@@ -857,10 +877,12 @@ signed_data_certsonly(struct certsonlyOptionsStr *certsonlyOptions)
== NULL) {
SECU_PrintError(progName, "cannot find certificate for \"%s\"",
certsonlyOptions->recipients[i]);
+ i=0;
goto loser;
}
}
certs[i] = NULL;
+ i=0;
/*
* create the message object
*/
@@ -877,12 +899,14 @@ signed_data_certsonly(struct certsonlyOptionsStr *certsonlyOptions)
fprintf(stderr, "ERROR: cannot create CMS signedData object.\n");
goto loser;
}
+ CERT_DestroyCertificate(certs[0]);
for (i=1; i<cnt; i++) {
if (NSS_CMSSignedData_AddCertChain(sigd, certs[i])) {
fprintf(stderr, "ERROR: cannot add cert chain for \"%s\".\n",
certsonlyOptions->recipients[i]);
goto loser;
}
+ CERT_DestroyCertificate(certs[i]);
}
cinfo = NSS_CMSMessage_GetContentInfo(cmsg);
if (NSS_CMSContentInfo_SetContent_SignedData(cmsg, cinfo, sigd)
@@ -900,6 +924,11 @@ signed_data_certsonly(struct certsonlyOptionsStr *certsonlyOptions)
PORT_FreeArena(tmppoolp, PR_FALSE);
return cmsg;
loser:
+ if (certs) {
+ for (; i<cnt; i++) {
+ CERT_DestroyCertificate(certs[i]);
+ }
+ }
if (cmsg)
NSS_CMSMessage_Destroy(cmsg);
if (tmppoolp)
@@ -924,7 +953,7 @@ int
main(int argc, char **argv)
{
FILE *outFile;
- NSSCMSMessage *cmsg;
+ NSSCMSMessage *cmsg = NULL;
PRFileDesc *inFile;
PLOptState *optstate;
PLOptStatus status;
@@ -1299,6 +1328,10 @@ main(int argc, char **argv)
SECU_PrintError(progName, "problem encrypting");
exitstatus = 1;
}
+ if (encryptOptions.bulkkey) {
+ PK11_FreeSymKey(encryptOptions.bulkkey);
+ encryptOptions.bulkkey = NULL;
+ }
break;
case ENVELOPE:
envelopeOptions.options = &options;
@@ -1392,5 +1425,6 @@ main(int argc, char **argv)
if (decodeOptions.contentFile)
PR_Close(decodeOptions.contentFile);
+ NSS_Shutdown();
exit(exitstatus);
}
diff --git a/security/nss/cmd/strsclnt/strsclnt.c b/security/nss/cmd/strsclnt/strsclnt.c
index 29c90274e..461ba0641 100644
--- a/security/nss/cmd/strsclnt/strsclnt.c
+++ b/security/nss/cmd/strsclnt/strsclnt.c
@@ -39,8 +39,10 @@
#include <unistd.h>
#endif
#include <stdlib.h>
+#if !defined(_WIN32_WCE)
#include <errno.h>
#include <fcntl.h>
+#endif
#include <stdarg.h>
#include "plgetopt.h"
@@ -293,6 +295,8 @@ printSecurityInfo(PRFileDesc *fd)
fprintf(stderr, "strsclnt: issuer DN: %s\n", ip);
PR_Free(ip);
}
+ }
+ if (cert) {
CERT_DestroyCertificate(cert);
cert = NULL;
}
diff --git a/security/nss/cmd/tstclnt/tstclnt.c b/security/nss/cmd/tstclnt/tstclnt.c
index f576b6af4..4598fdcc2 100644
--- a/security/nss/cmd/tstclnt/tstclnt.c
+++ b/security/nss/cmd/tstclnt/tstclnt.c
@@ -724,6 +724,7 @@ int main(int argc, char **argv)
done:
PR_Close(s);
+ SSL_ClearSessionCache();
NSS_Shutdown();
PR_Cleanup();
return error;
diff --git a/security/nss/cmd/zlib/zutil.h b/security/nss/cmd/zlib/zutil.h
index 12a59356c..6918260cf 100644
--- a/security/nss/cmd/zlib/zutil.h
+++ b/security/nss/cmd/zlib/zutil.h
@@ -15,7 +15,8 @@
#include "zlib.h"
-#if defined(MSDOS)||defined(VMS)||defined(CRAY)||defined(WIN32)||defined(RISCOS)
+#if defined(_WIN32_WCE)
+#elif defined(MSDOS)||defined(VMS)||defined(CRAY)||defined(WIN32)||defined(RISCOS)
# include <stddef.h>
# include <errno.h>
#else
diff --git a/security/nss/lib/Makefile b/security/nss/lib/Makefile
index 92aa6ff63..d7c687fe8 100644
--- a/security/nss/lib/Makefile
+++ b/security/nss/lib/Makefile
@@ -54,7 +54,9 @@ include $(CORE_DEPTH)/coreconf/config.mk
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
#######################################################################
-
+ifeq ($(OS_TARGET), WINCE)
+DIRS := $(filter-out fortcrypt,$(DIRS))
+endif
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
diff --git a/security/nss/lib/base/arena.c b/security/nss/lib/base/arena.c
index 31bf5f485..648b7e864 100644
--- a/security/nss/lib/base/arena.c
+++ b/security/nss/lib/base/arena.c
@@ -1127,14 +1127,15 @@ nss_ZRealloc
new_h = (struct pointer_header *)p;
new_h->arena = h->arena;
new_h->size = newSize;
- rv = (void *)((char *)h + sizeof(struct pointer_header));
- (void)nsslibc_memcpy(rv, pointer, h->size);
- (void)nsslibc_memset(&((char *)rv)[ h->size ], 0,
- (newSize - h->size));
- (void)nsslibc_memset(pointer, 0, h->size);
+ rv = (void *)((char *)new_h + sizeof(struct pointer_header));
+ if (rv != pointer) {
+ (void)nsslibc_memcpy(rv, pointer, h->size);
+ (void)nsslibc_memset(pointer, 0, h->size);
+ }
+ (void)nsslibc_memset(&((char *)rv)[ h->size ], 0, (newSize - h->size));
h->arena = (NSSArena *)NULL;
h->size = 0;
- PR_Unlock(h->arena->lock);
+ PR_Unlock(new_h->arena->lock);
return rv;
}
/*NOTREACHED*/
diff --git a/security/nss/lib/base/base.h b/security/nss/lib/base/base.h
index 492da7259..9a8d2d294 100644
--- a/security/nss/lib/base/base.h
+++ b/security/nss/lib/base/base.h
@@ -452,6 +452,25 @@ extern const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD;
#define nss_ZNEWARRAY(arenaOpt, type, quantity) ((type *)nss_ZAlloc((arenaOpt), sizeof(type) * (quantity)))
/*
+ * nss_ZREALLOCARRAY
+ *
+ * This preprocessor macro will reallocate memory for an array of
+ * new objects, and will cast the return value appropriately.
+ * This routine may return NULL upon error, in which case it will
+ * have set an error upon the error stack.
+ *
+ * The error may be one of the following values:
+ * NSS_ERROR_INVALID_POINTER
+ * NSS_ERROR_NO_MEMORY
+ * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
+ *
+ * Return value:
+ * NULL upon error
+ * A pointer to the replacement segment of memory
+ */
+#define nss_ZREALLOCARRAY(p, type, quantity) ((type *)nss_ZRealloc((p), sizeof(type) * (quantity)))
+
+/*
* nssArena_verifyPointer
*
* This method is only present in debug builds.
diff --git a/security/nss/lib/base/list.c b/security/nss/lib/base/list.c
index f4ef49b70..ae601d50c 100644
--- a/security/nss/lib/base/list.c
+++ b/security/nss/lib/base/list.c
@@ -313,19 +313,23 @@ nssList_Count(nssList *list)
NSS_IMPLEMENT PRStatus
nssList_GetArray(nssList *list, void **rvArray, PRUint32 maxElements)
{
- nssListIterator *iter;
- void *el;
+ nssListElement *node;
PRUint32 i = 0;
PR_ASSERT(maxElements > 0);
- iter = nssList_CreateIterator(list);
- for (el = nssListIterator_Start(iter); el != NULL;
- el = nssListIterator_Next(iter))
- {
- rvArray[i++] = el;
+ node = list->head;
+ if (!node) {
+ return PR_SUCCESS;
+ }
+ NSSLIST_LOCK_IF(list);
+ while (node) {
+ rvArray[i++] = node->data;
if (i == maxElements) break;
+ node = (nssListElement *)PR_NEXT_LINK(&node->link);
+ if (node == list->head) {
+ break;
+ }
}
- nssListIterator_Finish(iter);
- nssListIterator_Destroy(iter);
+ NSSLIST_UNLOCK_IF(list);
return PR_SUCCESS;
}
diff --git a/security/nss/lib/certdb/certdb.c b/security/nss/lib/certdb/certdb.c
index 983908737..89d351603 100644
--- a/security/nss/lib/certdb/certdb.c
+++ b/security/nss/lib/certdb/certdb.c
@@ -1659,6 +1659,7 @@ CERT_IsCADERCert(SECItem *derCert, unsigned int *type) {
CERTCertificate *cert;
PRBool isCA;
+ /* This is okay -- only looks at extensions */
cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
if (cert == NULL) return PR_FALSE;
@@ -2006,6 +2007,7 @@ CERT_SaveImportedCert(CERTCertificate *cert, SECCertUsage usage,
loser:
rv = SECFailure;
done:
+
return(rv);
}
@@ -2028,29 +2030,47 @@ CERT_ImportCerts(CERTCertDBHandle *certdb, SECCertUsage usage,
/* decode all of the certs into the temporary DB */
for ( i = 0, fcerts= 0; i < ncerts; i++) {
- certs[fcerts] = CERT_DecodeDERCertificate(derCerts[i], PR_FALSE,
- NULL);
+ certs[fcerts] = CERT_NewTempCertificate(certdb,
+ derCerts[i],
+ NULL,
+ PR_FALSE,
+ PR_TRUE);
if (certs[fcerts]) fcerts++;
}
if ( keepCerts ) {
for ( i = 0; i < fcerts; i++ ) {
+ char* canickname = NULL;
+ PRBool freeNickname = PR_FALSE;
+
SECKEY_UpdateCertPQG(certs[i]);
+
+ if ( CERT_IsCACert(certs[i], NULL) ) {
+ canickname = CERT_MakeCANickname(certs[i]);
+ if ( canickname != NULL ) {
+ freeNickname = PR_TRUE;
+ }
+ }
+
if(CERT_IsCACert(certs[i], NULL) && (fcerts > 1)) {
/* if we are importing only a single cert and specifying
* a nickname, we want to use that nickname if it a CA,
* otherwise if there are more than one cert, we don't
- * know which cert it belongs to.
+ * know which cert it belongs to. But we still may try
+ * the individual canickname from the cert itself.
*/
- rv = PK11_ImportCert(PK11_GetInternalKeySlot(),certs[i],
- CK_INVALID_HANDLE,NULL,PR_TRUE);
+ rv = CERT_AddTempCertToPerm(certs[i], canickname, NULL);
} else {
- rv = PK11_ImportCert(PK11_GetInternalKeySlot(),certs[i],
- CK_INVALID_HANDLE,nickname,PR_TRUE);
+ rv = CERT_AddTempCertToPerm(certs[i],
+ nickname?nickname:canickname, NULL);
}
if (rv == SECSuccess) {
CERT_SaveImportedCert(certs[i], usage, caOnly, NULL);
}
+
+ if (PR_TRUE == freeNickname) {
+ PORT_Free(canickname);
+ }
/* don't care if it fails - keep going */
}
}
diff --git a/security/nss/lib/certdb/certt.h b/security/nss/lib/certdb/certt.h
index 1c5298383..3f70dcc84 100644
--- a/security/nss/lib/certdb/certt.h
+++ b/security/nss/lib/certdb/certt.h
@@ -177,7 +177,7 @@ struct CERTCertTrustStr {
/*
* defined the types of trust that exist
*/
-typedef enum {
+typedef enum SECTrustTypeEnum {
trustSSL = 0,
trustEmail = 1,
trustObjectSigning = 2,
@@ -458,7 +458,7 @@ struct CERTDistNamesStr {
NS_CERT_TYPE_EMAIL_CA | \
NS_CERT_TYPE_OBJECT_SIGNING_CA | \
EXT_KEY_USAGE_STATUS_RESPONDER )
-typedef enum {
+typedef enum SECCertUsageEnum {
certUsageSSLClient = 0,
certUsageSSLServer = 1,
certUsageSSLServerWithStepUp = 2,
@@ -476,7 +476,7 @@ typedef enum {
/*
* Does the cert belong to the user, a peer, or a CA.
*/
-typedef enum {
+typedef enum CERTCertOwnerEnum {
certOwnerUser = 0,
certOwnerPeer = 1,
certOwnerCA = 2
@@ -485,7 +485,7 @@ typedef enum {
/*
* This enum represents the state of validity times of a certificate
*/
-typedef enum {
+typedef enum SECCertTimeValidityEnum {
secCertTimeValid = 0,
secCertTimeExpired = 1,
secCertTimeNotValidYet = 2
@@ -576,7 +576,7 @@ struct CERTBasicConstraintsStr {
/* If we needed to extract the general name field, use this */
/* General Name types */
-typedef enum {
+typedef enum CERTGeneralNameTypeEnum {
certOtherName = 1,
certRFC822Name = 2,
certDNSName = 3,
@@ -652,7 +652,7 @@ struct CERTAuthKeyIDStr {
/*
* defined the types of CRL Distribution points
*/
-typedef enum {
+typedef enum DistributionPointTypesEnum {
generalName = 1, /* only support this for now */
relativeDistinguishedName = 2
} DistributionPointTypes;
@@ -734,7 +734,7 @@ typedef char * (*CERTDBNameFunc)(void *arg, int dbVersion);
/*
* types of cert packages that we can decode
*/
-typedef enum {
+typedef enum CERTPackageTypeEnum {
certPackageNone = 0,
certPackageCert = 1,
certPackagePKCS7 = 2,
diff --git a/security/nss/lib/certdb/stanpcertdb.c b/security/nss/lib/certdb/stanpcertdb.c
index 293b33d8a..654da08dd 100644
--- a/security/nss/lib/certdb/stanpcertdb.c
+++ b/security/nss/lib/certdb/stanpcertdb.c
@@ -86,8 +86,10 @@ SECStatus
SEC_DeletePermCertificate(CERTCertificate *cert)
{
PRStatus nssrv;
+ NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
NSSCertificate *c = STAN_GetNSSCertificate(cert);
nssrv = NSSCertificate_DeleteStoredObject(c, NULL);
+ nssTrustDomain_RemoveCertFromCache(td, c);
return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
}
@@ -135,17 +137,17 @@ SECStatus
__CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
CERTCertTrust *trust)
{
- PRStatus nssrv;
NSSUTF8 *stanNick;
PK11SlotInfo *slot;
NSSToken *internal;
NSSCryptoContext *context;
+ nssCryptokiObject *permInstance;
NSSCertificate *c = STAN_GetNSSCertificate(cert);
context = c->object.cryptoContext;
if (!context) {
- return PR_FAILURE; /* wasn't a temp cert */
+ return SECFailure; /* wasn't a temp cert */
}
- stanNick = NSSCertificate_GetNickname(c, NULL);
+ stanNick = nssCertificate_GetNickname(c, NULL);
if (stanNick && nickname && strcmp(nickname, stanNick) != 0) {
/* take the new nickname */
cert->nickname = NULL;
@@ -157,20 +159,36 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
/* Delete the temp instance */
nssCertificateStore_Remove(context->certStore, c);
c->object.cryptoContext = NULL;
- /* the perm instance will assume the reference */
- nssList_Clear(c->object.instanceList, NULL);
/* Import the perm instance onto the internal token */
slot = PK11_GetInternalKeySlot();
internal = PK11Slot_GetNSSToken(slot);
- nssrv = nssToken_ImportCertificate(internal, NULL, c, stanNick, PR_TRUE);
- if (nssrv != PR_SUCCESS) {
+ permInstance = nssToken_ImportCertificate(internal, NULL,
+ NSSCertificateType_PKIX,
+ &c->id,
+ stanNick,
+ &c->encoding,
+ &c->issuer,
+ &c->subject,
+ &c->serial,
+ cert->emailAddr,
+ PR_TRUE);
+ PK11_FreeSlot(slot);
+ if (!permInstance) {
return SECFailure;
}
+ nssPKIObject_AddInstance(&c->object, permInstance);
+ nssTrustDomain_AddCertsToCache(STAN_GetDefaultTrustDomain(), &c, 1);
/* reset the CERTCertificate fields */
cert->nssCertificate = NULL;
cert = STAN_GetCERTCertificate(c); /* will return same pointer */
+ if (!cert) {
+ return SECFailure;
+ }
cert->istemp = PR_FALSE;
cert->isperm = PR_TRUE;
+ if (!trust) {
+ return PR_SUCCESS;
+ }
return (STAN_ChangeCertTrust(cert, trust) == PR_SUCCESS) ?
SECSuccess: SECFailure;
}
@@ -188,11 +206,11 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
{
PRStatus nssrv;
NSSCertificate *c;
- NSSCryptoContext *context;
- NSSArena *arena;
CERTCertificate *cc;
NSSCertificate *tempCert;
+ nssPKIObject *pkio;
NSSCryptoContext *gCC = STAN_GetDefaultCryptoContext();
+ NSSTrustDomain *gTD = STAN_GetDefaultTrustDomain();
if (!isperm) {
NSSDER encoding;
NSSITEM_FROM_SECITEM(&encoding, derCert);
@@ -208,27 +226,32 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
return STAN_GetCERTCertificate(c);
}
}
- arena = NSSArena_Create();
- if (!arena) {
+ pkio = nssPKIObject_Create(NULL, NULL, gTD, gCC);
+ if (!pkio) {
return NULL;
}
- c = nss_ZNEW(arena, NSSCertificate);
+ c = nss_ZNEW(pkio->arena, NSSCertificate);
if (!c) {
- nssArena_Destroy(arena);
+ nssPKIObject_Destroy(pkio);
return NULL;
}
- NSSITEM_FROM_SECITEM(&c->encoding, derCert);
- nssrv = nssPKIObject_Initialize(&c->object, arena, NULL, NULL);
- if (nssrv != PR_SUCCESS) {
- goto loser;
+ c->object = *pkio;
+ if (copyDER) {
+ nssItem_Create(c->object.arena, &c->encoding,
+ derCert->len, derCert->data);
+ } else {
+ NSSITEM_FROM_SECITEM(&c->encoding, derCert);
}
/* Forces a decoding of the cert in order to obtain the parts used
* below
*/
cc = STAN_GetCERTCertificate(c);
- nssItem_Create(arena,
+ if (!cc) {
+ return NULL;
+ }
+ nssItem_Create(c->object.arena,
&c->issuer, cc->derIssuer.len, cc->derIssuer.data);
- nssItem_Create(arena,
+ nssItem_Create(c->object.arena,
&c->subject, cc->derSubject.len, cc->derSubject.data);
if (PR_TRUE) {
/* CERTCertificate stores serial numbers decoded. I need the DER
@@ -237,31 +260,30 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
SECItem derSerial = { 0 };
CERT_SerialNumberFromDERCert(&cc->derCert, &derSerial);
if (!derSerial.data) goto loser;
- nssItem_Create(arena, &c->serial, derSerial.len, derSerial.data);
+ nssItem_Create(c->object.arena, &c->serial, derSerial.len, derSerial.data);
PORT_Free(derSerial.data);
}
if (nickname) {
- c->object.tempName = nssUTF8_Create(arena,
+ c->object.tempName = nssUTF8_Create(c->object.arena,
nssStringType_UTF8String,
(NSSUTF8 *)nickname,
PORT_Strlen(nickname));
}
if (cc->emailAddr) {
- c->email = nssUTF8_Create(arena,
+ c->email = nssUTF8_Create(c->object.arena,
nssStringType_PrintableString,
(NSSUTF8 *)cc->emailAddr,
PORT_Strlen(cc->emailAddr));
}
- context = STAN_GetDefaultCryptoContext();
/* this function cannot detect if the cert exists as a temp cert now, but
* didn't when CERT_NewTemp was first called.
*/
- nssrv = NSSCryptoContext_ImportCertificate(context, c);
+ nssrv = NSSCryptoContext_ImportCertificate(gCC, c);
if (nssrv != PR_SUCCESS) {
goto loser;
}
/* so find the entry in the temp store */
- tempCert = NSSCryptoContext_FindCertificateByIssuerAndSerialNumber(context,
+ tempCert = NSSCryptoContext_FindCertificateByIssuerAndSerialNumber(gCC,
&c->issuer,
&c->serial);
/* destroy the copy */
@@ -270,10 +292,12 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
/* and use the "official" entry */
c = tempCert;
cc = STAN_GetCERTCertificate(c);
+ if (!cc) {
+ return NULL;
+ }
} else {
return NULL;
}
- c->object.trustDomain = STAN_GetDefaultTrustDomain();
cc->istemp = PR_TRUE;
cc->isperm = PR_FALSE;
return cc;
@@ -308,17 +332,18 @@ CERT_FindCertByIssuerAndSN(CERTCertDBHandle *handle, CERTIssuerAndSN *issuerAndS
static NSSCertificate *
get_best_temp_or_perm(NSSCertificate *ct, NSSCertificate *cp)
{
- nssBestCertificateCB best;
NSSUsage usage;
- usage.anyUsage = PR_TRUE;
- nssBestCertificate_SetArgs(&best, NULL, &usage, NULL);
- if (ct) {
- nssBestCertificate_Callback(ct, (void *)&best);
- }
- if (cp) {
- nssBestCertificate_Callback(cp, (void *)&best);
+ NSSCertificate *arr[3];
+ if (!ct) {
+ return nssCertificate_AddRef(cp);
+ } else if (!cp) {
+ return nssCertificate_AddRef(ct);
}
- return best.cert;
+ arr[0] = ct;
+ arr[1] = cp;
+ arr[2] = NULL;
+ usage.anyUsage = PR_TRUE;
+ return nssCertificateArray_FindBestCertificate(arr, NULL, &usage, NULL);
}
CERTCertificate *
@@ -338,10 +363,16 @@ CERT_FindCertByName(CERTCertDBHandle *handle, SECItem *name)
c = get_best_temp_or_perm(ct, cp);
if (ct) {
CERTCertificate *cert = STAN_GetCERTCertificate(ct);
+ if (!cert) {
+ return NULL;
+ }
CERT_DestroyCertificate(cert);
}
if (cp) {
CERTCertificate *cert = STAN_GetCERTCertificate(cp);
+ if (!cert) {
+ return NULL;
+ }
CERT_DestroyCertificate(cert);
}
if (c) {
@@ -388,6 +419,9 @@ CERT_FindCertByNickname(CERTCertDBHandle *handle, char *nickname)
CERT_DestroyCertificate(cert);
if (ct) {
CERTCertificate *cert2 = STAN_GetCERTCertificate(ct);
+ if (!cert2) {
+ return NULL;
+ }
CERT_DestroyCertificate(cert2);
}
} else {
@@ -438,6 +472,9 @@ CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, char *name)
CERT_DestroyCertificate(cert);
if (ct) {
CERTCertificate *cert2 = STAN_GetCERTCertificate(ct);
+ if (!cert2) {
+ return NULL;
+ }
CERT_DestroyCertificate(cert2);
}
} else {
@@ -503,14 +540,18 @@ CERT_CreateSubjectCertList(CERTCertList *certList, CERTCertDBHandle *handle,
ci = tSubjectCerts;
while (ci && *ci) {
cert = STAN_GetCERTCertificate(*ci);
- add_to_subject_list(certList, cert, validOnly, sorttime);
+ if (cert) {
+ add_to_subject_list(certList, cert, validOnly, sorttime);
+ }
ci++;
}
/* Iterate over the matching perm certs. Add them to the list */
ci = pSubjectCerts;
while (ci && *ci) {
cert = STAN_GetCERTCertificate(*ci);
- add_to_subject_list(certList, cert, validOnly, sorttime);
+ if (cert) {
+ add_to_subject_list(certList, cert, validOnly, sorttime);
+ }
ci++;
}
nss_ZFreeIf(tSubjectCerts);
@@ -573,7 +614,9 @@ CERT_DestroyCertificate(CERTCertificate *cert)
}
/* delete the NSSCertificate */
NSSCertificate_Destroy(tmp);
- }
+ } else {
+ PORT_FreeArena(cert->arena, PR_FALSE);
+ }
#endif
}
return;
@@ -825,6 +868,9 @@ loser:
if (stanProfile) {
nssSMIMEProfile_Destroy(stanProfile);
}
+ if (slot) {
+ PK11_FreeSlot(slot);
+ }
return(rv);
}
@@ -835,11 +881,12 @@ CERT_FindSMimeProfile(CERTCertificate *cert)
PK11SlotInfo *slot = NULL;
NSSCertificate *c;
NSSCryptoContext *cc;
+ SECItem *rvItem = NULL;
+
c = STAN_GetNSSCertificate(cert);
if (!c) return NULL;
cc = c->object.cryptoContext;
if (cc != NULL) {
- SECItem *rvItem = NULL;
nssSMIMEProfile *stanProfile;
stanProfile = nssCryptoContext_FindSMIMEProfileForCertificate(cc, c);
if (stanProfile) {
@@ -852,8 +899,12 @@ CERT_FindSMimeProfile(CERTCertificate *cert)
}
return rvItem;
}
- return
+ rvItem =
PK11_FindSMimeProfile(&slot, cert->emailAddr, &cert->derSubject, NULL);
+ if (slot) {
+ PK11_FreeSlot(slot);
+ }
+ return rvItem;
}
/*
diff --git a/security/nss/lib/certhigh/certhigh.c b/security/nss/lib/certhigh/certhigh.c
index 06cccb43b..1cd3916ea 100644
--- a/security/nss/lib/certhigh/certhigh.c
+++ b/security/nss/lib/certhigh/certhigh.c
@@ -91,6 +91,31 @@ CERT_MatchNickname(char *name1, char *name2) {
return PR_TRUE;
}
+static SECStatus
+cert_UserCertsOnly(CERTCertList *certList)
+{
+ CERTCertListNode *node, *freenode;
+ CERTCertificate *cert;
+
+ node = CERT_LIST_HEAD(certList);
+
+ while ( ! CERT_LIST_END(node, certList) ) {
+ cert = node->cert;
+ if ( !( cert->trust->sslFlags & CERTDB_USER ) &&
+ !( cert->trust->emailFlags & CERTDB_USER ) &&
+ !( cert->trust->objectSigningFlags & CERTDB_USER ) ) {
+ /* Not a User Cert, so remove this cert from the list */
+ freenode = node;
+ node = CERT_LIST_NEXT(node);
+ CERT_RemoveCertListNode(freenode);
+ } else {
+ /* Is a User cert, so leave it in the list */
+ node = CERT_LIST_NEXT(node);
+ }
+ }
+
+ return(SECSuccess);
+}
/*
* Find all user certificates that match the given criteria.
@@ -157,6 +182,8 @@ CERT_FindUserCertsByUsage(CERTCertDBHandle *handle,
/* collect certs for this nickname, sorting them into the list */
certList = CERT_CreateSubjectCertList(certList, handle,
&cert->derSubject, time, validOnly);
+
+ cert_UserCertsOnly(certList);
/* drop the extra reference */
CERT_DestroyCertificate(cert);
@@ -287,6 +314,8 @@ CERT_FindUserCertByUsage(CERTCertDBHandle *handle,
certList = CERT_CreateSubjectCertList(certList, handle,
&cert->derSubject, time, validOnly);
+ cert_UserCertsOnly(certList);
+
/* drop the extra reference */
CERT_DestroyCertificate(cert);
cert = NULL;
@@ -825,6 +854,7 @@ cert_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage, PRBool
certs++;
/* decode my certificate */
+ /* This use is ok -- only looks at decoded parts, calls NewTemp later */
newcert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
if ( newcert == NULL ) {
goto loser;
@@ -886,7 +916,8 @@ cert_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage, PRBool
}
}
- cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
+ cert = CERT_NewTempCertificate(handle, derCert, NULL,
+ PR_FALSE, PR_FALSE);
if ( cert == NULL ) {
goto loser;
}
@@ -894,9 +925,7 @@ cert_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage, PRBool
/* get a default nickname for it */
nickname = CERT_MakeCANickname(cert);
- cert->trust = &trust;
- rv = PK11_ImportCert(PK11_GetInternalKeySlot(), cert,
- CK_INVALID_HANDLE, nickname, PR_TRUE);
+ rv = CERT_AddTempCertToPerm(cert, nickname, &trust);
/* free the nickname */
if ( nickname ) {
@@ -1101,6 +1130,9 @@ loser:
while (stanCert) {
SECItem derCert;
CERTCertificate *cCert = STAN_GetCERTCertificate(stanCert);
+ if (!cCert) {
+ goto loser;
+ }
derCert.len = (unsigned int)stanCert->encoding.size;
derCert.data = (unsigned char *)stanCert->encoding.data;
SECITEM_CopyItem(arena, &chain->certs[i], &derCert);
@@ -1121,7 +1153,9 @@ loser:
stanCert = stanChain[i];
while (stanCert) {
CERTCertificate *cCert = STAN_GetCERTCertificate(stanCert);
- CERT_DestroyCertificate(cCert);
+ if (cCert) {
+ CERT_DestroyCertificate(cCert);
+ }
stanCert = stanChain[++i];
}
nss_ZFreeIf(stanChain);
diff --git a/security/nss/lib/certhigh/ocsp.c b/security/nss/lib/certhigh/ocsp.c
index 4d4c549ac..6afa26b59 100644
--- a/security/nss/lib/certhigh/ocsp.c
+++ b/security/nss/lib/certhigh/ocsp.c
@@ -1490,6 +1490,9 @@ ocsp_GetResponseSignature(CERTOCSPResponse *response)
ocspBasicOCSPResponse *basic;
PORT_Assert(response != NULL);
+ if (NULL == response->responseBytes) {
+ return NULL;
+ }
PORT_Assert(response->responseBytes != NULL);
PORT_Assert(response->responseBytes->responseTypeTag
== SEC_OID_PKIX_OCSP_BASIC_RESPONSE);
@@ -1515,7 +1518,7 @@ CERT_DestroyOCSPResponse(CERTOCSPResponse *response)
{
if (response != NULL) {
ocspSignature *signature = ocsp_GetResponseSignature(response);
- if (signature->cert != NULL)
+ if (signature && signature->cert != NULL)
CERT_DestroyCertificate(signature->cert);
/*
@@ -1853,7 +1856,8 @@ ocsp_GetEncodedResponse(PRArenaPool *arena, PRFileDesc *sock)
bufsize = OCSP_BUFSIZE;
- buf = PORT_Alloc(bufsize);
+ buf = PORT_Alloc(bufsize+1);
+ buf[bufsize] = 0; /* NULL termination so string functions are OK */
if (buf == NULL) {
goto loser;
}
@@ -2015,26 +2019,6 @@ ocsp_GetEncodedResponse(PRArenaPool *arena, PRFileDesc *sock)
continue;
}
/*
- * So, we have a good newline pointer (just past a CR, LF or CRLF),
- * but now we want to make sure that what it points to is long
- * enough to be something we are looking for. If it isn't, add
- * more to the buffer after first copying what's left to the
- * beginning.
- */
- if (((char *)bufEnd - newline) < 40) {
- len = (char *)bufEnd - newline;
- PORT_Memmove(buf, newline, len);
- bytesRead = ocsp_MinMaxRead(sock, buf + len, 40 - len,
- bufsize - len);
- if (bytesRead <= 0) {
- if (bytesRead == 0)
- PORT_SetError(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
- goto loser;
- }
- newline = (char *)buf;
- bufEnd = buf + len + bytesRead;
- }
- /*
* Okay, now we know that we are looking at an HTTP header line
* with enough length to be safe for our comparisons. See if it is
* one of the ones we are interested in. (That is, "Content-Length"
diff --git a/security/nss/lib/ckfw/builtins/Makefile b/security/nss/lib/ckfw/builtins/Makefile
index d58e910d9..7c392f2c9 100644
--- a/security/nss/lib/ckfw/builtins/Makefile
+++ b/security/nss/lib/ckfw/builtins/Makefile
@@ -47,8 +47,6 @@ ifeq (,$(filter-out WIN%,$(OS_TARGET)))
EXTRA_LIBS += \
$(DIST)/lib/$(NSPR31_LIB_PREFIX)plc4_s.lib \
$(DIST)/lib/$(NSPR31_LIB_PREFIX)plds4_s.lib \
- wsock32.lib \
- winmm.lib \
$(NULL)
else
diff --git a/security/nss/lib/ckfw/nsprstub.c b/security/nss/lib/ckfw/nsprstub.c
index e4c33cdbd..c9e3964d9 100644
--- a/security/nss/lib/ckfw/nsprstub.c
+++ b/security/nss/lib/ckfw/nsprstub.c
@@ -200,7 +200,7 @@ PORT_ArenaUnmark(PLArenaPool *arena, void *mark)
}
char *
-PORT_ArenaStrdup(PLArenaPool *arena,char *str) {
+PORT_ArenaStrdup(PLArenaPool *arena,const char *str) {
int len = PORT_Strlen(str)+1;
char *newstr;
diff --git a/security/nss/lib/ckfw/sessobj.c b/security/nss/lib/ckfw/sessobj.c
index 11de006ba..66555fe23 100644
--- a/security/nss/lib/ckfw/sessobj.c
+++ b/security/nss/lib/ckfw/sessobj.c
@@ -202,7 +202,7 @@ nss_ckmdSessionObject_GetAttributeSize
CK_RV *pError
);
-static const NSSItem *
+static NSSCKFWItem
nss_ckmdSessionObject_GetAttribute
(
NSSCKMDObject *mdObject,
@@ -582,7 +582,7 @@ nss_ckmdSessionObject_GetAttributeSize
* nss_ckmdSessionObject_GetAttribute
*
*/
-static const NSSItem *
+static NSSCKFWItem
nss_ckmdSessionObject_GetAttribute
(
NSSCKMDObject *mdObject,
@@ -597,17 +597,20 @@ nss_ckmdSessionObject_GetAttribute
CK_RV *pError
)
{
+ NSSCKFWItem item;
nssCKMDSessionObject *obj;
CK_ULONG i;
+ item.needsFreeing = PR_FALSE;
+ item.item = NULL;
#ifdef NSSDEBUG
if( (CK_RV *)NULL == pError ) {
- return 0;
+ return item;
}
*pError = nss_ckmdSessionObject_verifyPointer(mdObject);
if( CKR_OK != *pError ) {
- return 0;
+ return item;
}
/* We could even check all the other arguments, for sanity. */
@@ -617,12 +620,13 @@ nss_ckmdSessionObject_GetAttribute
for( i = 0; i < obj->n; i++ ) {
if( attribute == obj->types[i] ) {
- return &obj->attributes[i];
+ item.item = &obj->attributes[i];
+ return item;
}
}
*pError = CKR_ATTRIBUTE_TYPE_INVALID;
- return 0;
+ return item;
}
/*
diff --git a/security/nss/lib/crmf/asn1cmn.c b/security/nss/lib/crmf/asn1cmn.c
index 59ce5b4a8..3ca062027 100644
--- a/security/nss/lib/crmf/asn1cmn.c
+++ b/security/nss/lib/crmf/asn1cmn.c
@@ -164,10 +164,7 @@ cmmf_DecodeDERCertificate(CERTCertDBHandle *db, SECItem *derCert)
{
CERTCertificate *newCert;
- newCert = CERT_DecodeDERCertificate(derCert, PR_TRUE, NULL);
- if (newCert != NULL && newCert->dbhandle == NULL) {
- newCert->dbhandle = db;
- }
+ newCert = CERT_NewTempCertificate(db, derCert, NULL, PR_FALSE, PR_TRUE);
return newCert;
}
diff --git a/security/nss/lib/crmf/respcmn.c b/security/nss/lib/crmf/respcmn.c
index d7c703ec0..871ece3ec 100644
--- a/security/nss/lib/crmf/respcmn.c
+++ b/security/nss/lib/crmf/respcmn.c
@@ -168,7 +168,8 @@ cmmf_MakeCertList(CERTCertificate **inCerts)
if (derCert->data == NULL) {
derCert = freeCert = cmmf_encode_certificate(inCerts[i]);
}
- currCert=CERT_DecodeDERCertificate(derCert, PR_TRUE, NULL);
+ currCert=CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
+ derCert, NULL, PR_FALSE, PR_TRUE);
if (freeCert != NULL) {
SECITEM_FreeItem(freeCert, PR_TRUE);
freeCert = NULL;
diff --git a/security/nss/lib/dev/Makefile b/security/nss/lib/dev/Makefile
index 4cbbfed70..cd7561ce6 100644
--- a/security/nss/lib/dev/Makefile
+++ b/security/nss/lib/dev/Makefile
@@ -37,4 +37,17 @@ include $(CORE_DEPTH)/coreconf/config.mk
include config.mk
include $(CORE_DEPTH)/coreconf/rules.mk
+# On AIX 4.3, IBM xlC_r compiler (version 3.6.6) cannot compile
+# ckhelper.c in 64-bit mode for unknown reasons. A workaround is
+# to compile it with optimizations turned on. (Bugzilla bug #63815)
+ifeq ($(OS_TARGET)$(OS_RELEASE),AIX4.3)
+ifeq ($(USE_64),1)
+ifndef BUILD_OPT
+$(OBJDIR)/ckhelper.o: ckhelper.c
+ @$(MAKE_OBJDIR)
+ $(CC) -o $@ -c -O2 $(CFLAGS) $<
+endif
+endif
+endif
+
export:: private_export
diff --git a/security/nss/lib/dev/ckhelper.c b/security/nss/lib/dev/ckhelper.c
index 85283ff1f..1f3f1e3bc 100644
--- a/security/nss/lib/dev/ckhelper.c
+++ b/security/nss/lib/dev/ckhelper.c
@@ -35,26 +35,18 @@
static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#endif /* DEBUG */
-#ifndef DEV_H
-#include "dev.h"
-#endif /* DEV_H */
-
-#ifdef NSS_3_4_CODE
-#include "pkcs11.h"
-#else
#ifndef NSSCKEPV_H
#include "nssckepv.h"
#endif /* NSSCKEPV_H */
-#endif /* NSS_3_4_CODE */
+
+#ifndef DEVM_H
+#include "devm.h"
+#endif /* DEVM_H */
#ifndef CKHELPER_H
#include "ckhelper.h"
#endif /* CKHELPER_H */
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-
static const CK_BBOOL s_true = CK_TRUE;
NSS_IMPLEMENT_DATA const NSSItem
g_ck_true = { (CK_VOID_PTR)&s_true, sizeof(s_true) };
@@ -111,6 +103,7 @@ nssCKObject_GetAttributes
CK_RV ckrv;
PRStatus nssrv;
PRBool alloced = PR_FALSE;
+ void *epv = nssSlot_GetCryptokiEPV(slot);
hSession = session->handle;
if (arenaOpt) {
mark = nssArena_Mark(arenaOpt);
@@ -124,8 +117,8 @@ nssCKObject_GetAttributes
*/
if (obj_template[0].ulValueLen == 0) {
/* Get the storage size needed for each attribute */
- ckrv = CKAPI(slot)->C_GetAttributeValue(hSession,
- object, obj_template, count);
+ ckrv = CKAPI(epv)->C_GetAttributeValue(hSession,
+ object, obj_template, count);
if (ckrv != CKR_OK &&
ckrv != CKR_ATTRIBUTE_TYPE_INVALID &&
ckrv != CKR_ATTRIBUTE_SENSITIVE)
@@ -154,8 +147,8 @@ nssCKObject_GetAttributes
alloced = PR_TRUE;
}
/* Obtain the actual attribute values. */
- ckrv = CKAPI(slot)->C_GetAttributeValue(hSession,
- object, obj_template, count);
+ ckrv = CKAPI(epv)->C_GetAttributeValue(hSession,
+ object, obj_template, count);
nssSession_ExitMonitor(session);
if (ckrv != CKR_OK &&
ckrv != CKR_ATTRIBUTE_TYPE_INVALID &&
@@ -177,7 +170,9 @@ nssCKObject_GetAttributes
* of the attributes we passed. For those tokens read them one at
* a time */
for (i=0; i < count; i++) {
- if (obj_template[i].ulValueLen == 0) {
+ if ((obj_template[i].ulValueLen == 0)
+ || (obj_template[i].ulValueLen == -1)) {
+ obj_template[i].ulValueLen=0;
(void) nssCKObject_GetAttributes(object,&obj_template[i], 1,
arenaOpt, session, slot);
}
@@ -238,11 +233,12 @@ nssCKObject_IsAttributeTrue
CK_ATTRIBUTE_PTR attr;
CK_ATTRIBUTE atemplate = { 0, NULL, 0 };
CK_RV ckrv;
+ void *epv = nssSlot_GetCryptokiEPV(slot);
attr = &atemplate;
NSS_CK_SET_ATTRIBUTE_VAR(attr, attribute, bool);
nssSession_EnterMonitor(session);
- ckrv = CKAPI(slot)->C_GetAttributeValue(session->handle, object,
- &atemplate, 1);
+ ckrv = CKAPI(epv)->C_GetAttributeValue(session->handle, object,
+ &atemplate, 1);
nssSession_ExitMonitor(session);
if (ckrv != CKR_OK) {
*rvStatus = PR_FAILURE;
@@ -263,9 +259,10 @@ nssCKObject_SetAttributes
)
{
CK_RV ckrv;
+ void *epv = nssSlot_GetCryptokiEPV(slot);
nssSession_EnterMonitor(session);
- ckrv = CKAPI(slot)->C_SetAttributeValue(session->handle, object,
- obj_template, count);
+ ckrv = CKAPI(epv)->C_SetAttributeValue(session->handle, object,
+ obj_template, count);
nssSession_ExitMonitor(session);
if (ckrv == CKR_OK) {
return PR_SUCCESS;
@@ -290,3 +287,436 @@ nssCKObject_IsTokenObjectTemplate
return PR_FALSE;
}
+static NSSCertificateType
+nss_cert_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib)
+{
+ CK_CERTIFICATE_TYPE ckCertType;
+ if (!attrib->pValue) {
+ /* default to PKIX */
+ return NSSCertificateType_PKIX;
+ }
+ ckCertType = *((CK_ULONG *)attrib->pValue);
+ switch (ckCertType) {
+ case CKC_X_509:
+ return NSSCertificateType_PKIX;
+ default:
+ break;
+ }
+ return NSSCertificateType_Unknown;
+}
+
+/* incoming pointers must be valid */
+NSS_IMPLEMENT PRStatus
+nssCryptokiCertificate_GetAttributes
+(
+ nssCryptokiObject *certObject,
+ nssSession *sessionOpt,
+ NSSArena *arenaOpt,
+ NSSCertificateType *certTypeOpt,
+ NSSItem *idOpt,
+ NSSDER *encodingOpt,
+ NSSDER *issuerOpt,
+ NSSDER *serialOpt,
+ NSSDER *subjectOpt,
+ NSSASCII7 **emailOpt
+)
+{
+ PRStatus status;
+ PRUint32 i;
+ nssSession *session;
+ NSSSlot *slot;
+ CK_ULONG template_size;
+ CK_ATTRIBUTE_PTR attr;
+ CK_ATTRIBUTE cert_template[7];
+ /* Set up a template of all options chosen by caller */
+ NSS_CK_TEMPLATE_START(cert_template, attr, template_size);
+ if (certTypeOpt) {
+ NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_CERTIFICATE_TYPE);
+ }
+ if (idOpt) {
+ NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ID);
+ }
+ if (encodingOpt) {
+ NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE);
+ }
+ if (issuerOpt) {
+ NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ISSUER);
+ }
+ if (serialOpt) {
+ NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SERIAL_NUMBER);
+ }
+ 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 */
+ return PR_SUCCESS;
+ }
+
+ status = nssToken_GetCachedObjectAttributes(certObject->token, arenaOpt,
+ certObject, CKO_CERTIFICATE,
+ cert_template, template_size);
+ if (status != PR_SUCCESS) {
+
+ session = sessionOpt ?
+ sessionOpt :
+ nssToken_GetDefaultSession(certObject->token);
+
+ slot = nssToken_GetSlot(certObject->token);
+ status = nssCKObject_GetAttributes(certObject->handle,
+ cert_template, template_size,
+ arenaOpt, session, slot);
+ nssSlot_Destroy(slot);
+ if (status != PR_SUCCESS) {
+ return status;
+ }
+ }
+
+ i=0;
+ if (certTypeOpt) {
+ *certTypeOpt = nss_cert_type_from_ck_attrib(&cert_template[i]); i++;
+ }
+ if (idOpt) {
+ NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], idOpt); i++;
+ }
+ if (encodingOpt) {
+ NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], encodingOpt); i++;
+ }
+ if (issuerOpt) {
+ NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], issuerOpt); i++;
+ }
+ if (serialOpt) {
+ NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], serialOpt); i++;
+ }
+ 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;
+}
+
+#ifdef PURE_STAN_BUILD
+static NSSKeyPairType
+nss_key_pair_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib)
+{
+ CK_KEY_TYPE ckKeyType;
+ PR_ASSERT(attrib->pValue);
+ ckKeyType = *((CK_ULONG *)attrib->pValue);
+ switch (ckKeyType) {
+ case CKK_RSA: return NSSKeyPairType_RSA;
+ case CKK_DSA: return NSSKeyPairType_DSA;
+ default: break;
+ }
+ return NSSKeyPairType_Unknown;
+}
+
+NSS_IMPLEMENT PRStatus
+nssCryptokiPrivateKey_GetAttributes
+(
+ nssCryptokiObject *keyObject,
+ nssSession *sessionOpt,
+ NSSArena *arenaOpt,
+ NSSKeyPairType *keyTypeOpt,
+ NSSItem *idOpt
+)
+{
+ PRStatus status;
+ PRUint32 i;
+ nssSession *session;
+ NSSSlot *slot;
+ CK_ULONG template_size;
+ CK_ATTRIBUTE_PTR attr;
+ CK_ATTRIBUTE key_template[2];
+ /* Set up a template of all options chosen by caller */
+ NSS_CK_TEMPLATE_START(key_template, attr, template_size);
+ if (keyTypeOpt) {
+ NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_KEY_TYPE);
+ }
+ if (idOpt) {
+ NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ID);
+ }
+ NSS_CK_TEMPLATE_FINISH(key_template, attr, template_size);
+ if (template_size == 0) {
+ /* caller didn't want anything */
+ return PR_SUCCESS;
+ }
+
+ session = sessionOpt ?
+ sessionOpt :
+ nssToken_GetDefaultSession(keyObject->token);
+
+ slot = nssToken_GetSlot(keyObject->token);
+ status = nssCKObject_GetAttributes(keyObject->handle,
+ key_template, template_size,
+ arenaOpt, session, slot);
+ nssSlot_Destroy(slot);
+ if (status != PR_SUCCESS) {
+ return status;
+ }
+
+ i=0;
+ if (keyTypeOpt) {
+ *keyTypeOpt = nss_key_pair_type_from_ck_attrib(&key_template[i]); i++;
+ }
+ if (idOpt) {
+ NSS_CK_ATTRIBUTE_TO_ITEM(&key_template[i], idOpt); i++;
+ }
+ return PR_SUCCESS;
+}
+
+NSS_IMPLEMENT PRStatus
+nssCryptokiPublicKey_GetAttributes
+(
+ nssCryptokiObject *keyObject,
+ nssSession *sessionOpt,
+ NSSArena *arenaOpt,
+ NSSKeyPairType *keyTypeOpt,
+ NSSItem *idOpt
+)
+{
+ PRStatus status;
+ PRUint32 i;
+ nssSession *session;
+ NSSSlot *slot;
+ CK_ULONG template_size;
+ CK_ATTRIBUTE_PTR attr;
+ CK_ATTRIBUTE key_template[2];
+ /* Set up a template of all options chosen by caller */
+ NSS_CK_TEMPLATE_START(key_template, attr, template_size);
+ if (keyTypeOpt) {
+ NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_KEY_TYPE);
+ }
+ if (idOpt) {
+ NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ID);
+ }
+ NSS_CK_TEMPLATE_FINISH(key_template, attr, template_size);
+ if (template_size == 0) {
+ /* caller didn't want anything */
+ return PR_SUCCESS;
+ }
+
+ session = sessionOpt ?
+ sessionOpt :
+ nssToken_GetDefaultSession(keyObject->token);
+
+ slot = nssToken_GetSlot(keyObject->token);
+ status = nssCKObject_GetAttributes(keyObject->handle,
+ key_template, template_size,
+ arenaOpt, session, slot);
+ nssSlot_Destroy(slot);
+ if (status != PR_SUCCESS) {
+ return status;
+ }
+
+ i=0;
+ if (keyTypeOpt) {
+ *keyTypeOpt = nss_key_pair_type_from_ck_attrib(&key_template[i]); i++;
+ }
+ if (idOpt) {
+ NSS_CK_ATTRIBUTE_TO_ITEM(&key_template[i], idOpt); i++;
+ }
+ return PR_SUCCESS;
+}
+#endif /* PURE_STAN_BUILD */
+
+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,
+ nssSession *sessionOpt,
+ nssTrustLevel *serverAuth,
+ nssTrustLevel *clientAuth,
+ nssTrustLevel *codeSigning,
+ nssTrustLevel *emailProtection
+)
+{
+ PRStatus status;
+ NSSSlot *slot;
+ nssSession *session;
+ 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);
+
+ status = nssToken_GetCachedObjectAttributes(trustObject->token, NULL,
+ trustObject,
+ CKO_NETSCAPE_TRUST,
+ trust_template, trust_size);
+ if (status != PR_SUCCESS) {
+ session = sessionOpt ?
+ sessionOpt :
+ nssToken_GetDefaultSession(trustObject->token);
+
+ slot = nssToken_GetSlot(trustObject->token);
+ status = nssCKObject_GetAttributes(trustObject->handle,
+ trust_template, trust_size,
+ NULL, 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,
+ nssSession *sessionOpt,
+ NSSArena *arenaOpt,
+ NSSItem *encodingOpt,
+ NSSUTF8 **urlOpt,
+ PRBool *isKRLOpt
+)
+{
+ PRStatus status;
+ NSSSlot *slot;
+ nssSession *session;
+ CK_BBOOL isToken;
+ CK_ATTRIBUTE_PTR attr;
+ CK_ATTRIBUTE crl_template[5];
+ CK_ULONG crl_size;
+ PRUint32 i;
+
+ NSS_CK_TEMPLATE_START(crl_template, attr, crl_size);
+ /* NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TOKEN, isToken); */
+ if (encodingOpt) {
+ NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE);
+ }
+ if (urlOpt) {
+ NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NETSCAPE_URL);
+ }
+ if (isKRLOpt) {
+ NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NETSCAPE_KRL);
+ }
+ NSS_CK_TEMPLATE_FINISH(crl_template, attr, crl_size);
+
+ status = nssToken_GetCachedObjectAttributes(crlObject->token, NULL,
+ crlObject,
+ CKO_NETSCAPE_CRL,
+ crl_template, crl_size);
+ if (status != PR_SUCCESS) {
+ session = sessionOpt ?
+ sessionOpt :
+ nssToken_GetDefaultSession(crlObject->token);
+
+ slot = nssToken_GetSlot(crlObject->token);
+ status = nssCKObject_GetAttributes(crlObject->handle,
+ crl_template, crl_size,
+ arenaOpt, session, slot);
+ nssSlot_Destroy(slot);
+ if (status != PR_SUCCESS) {
+ return status;
+ }
+ }
+
+ i=0;
+ if (encodingOpt) {
+ NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[i], encodingOpt); i++;
+ }
+ if (urlOpt) {
+ NSS_CK_ATTRIBUTE_TO_UTF8(&crl_template[i], *urlOpt); i++;
+ }
+ if (isKRLOpt) {
+ NSS_CK_ATTRIBUTE_TO_BOOL(&crl_template[i], *isKRLOpt); i++;
+ }
+ return PR_SUCCESS;
+}
+
+NSS_IMPLEMENT PRStatus
+nssCryptokiPrivateKey_SetCertificate
+(
+ nssCryptokiObject *keyObject,
+ nssSession *sessionOpt,
+ NSSUTF8 *nickname,
+ NSSItem *id,
+ NSSDER *subject
+)
+{
+ CK_RV ckrv;
+ CK_ATTRIBUTE_PTR attr;
+ CK_ATTRIBUTE key_template[3];
+ CK_ULONG key_size;
+ void *epv = nssToken_GetCryptokiEPV(keyObject->token);
+ nssSession *session;
+ NSSToken *token = keyObject->token;
+ nssSession *defaultSession = nssToken_GetDefaultSession(token);
+ PRBool createdSession = PR_FALSE;
+
+ NSS_CK_TEMPLATE_START(key_template, attr, key_size);
+ NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname);
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id);
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject);
+ NSS_CK_TEMPLATE_FINISH(key_template, attr, key_size);
+
+ if (sessionOpt) {
+ if (!nssSession_IsReadWrite(sessionOpt)) {
+ return PR_FAILURE;
+ } else {
+ session = sessionOpt;
+ }
+ } else if (nssSession_IsReadWrite(defaultSession)) {
+ session = defaultSession;
+ } else {
+ NSSSlot *slot = nssToken_GetSlot(token);
+ session = nssSlot_CreateSession(token->slot, NULL, PR_TRUE);
+ createdSession = PR_TRUE;
+ nssSlot_Destroy(slot);
+ }
+
+ ckrv = CKAPI(epv)->C_SetAttributeValue(session->handle,
+ keyObject->handle,
+ key_template,
+ key_size);
+
+ if (createdSession) {
+ nssSession_Destroy(session);
+ }
+
+ return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
+}
+
diff --git a/security/nss/lib/dev/ckhelper.h b/security/nss/lib/dev/ckhelper.h
index 1d92eec0e..9beab920d 100644
--- a/security/nss/lib/dev/ckhelper.h
+++ b/security/nss/lib/dev/ckhelper.h
@@ -50,10 +50,6 @@ static const char CKHELPER_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
PR_BEGIN_EXTERN_C
-/* Shortcut to cryptoki API functions. */
-#define CKAPI(x) \
- ((CK_FUNCTION_LIST_PTR)((x)->epv))
-
/* Some globals to keep from constantly redeclaring common cryptoki
* attribute types on the stack.
*/
@@ -90,6 +86,12 @@ NSS_EXTERN_DATA const NSSItem g_ck_class_privkey;
(pattr)->ulValueLen = (CK_ULONG)sizeof(var); \
(pattr)++;
+#define NSS_CK_SET_ATTRIBUTE_NULL(pattr, kind) \
+ (pattr)->type = kind; \
+ (pattr)->pValue = (CK_VOID_PTR)NULL; \
+ (pattr)->ulValueLen = 0; \
+ (pattr)++;
+
#define NSS_CK_TEMPLATE_FINISH(_template, attr, size) \
size = (attr) - (_template); \
PR_ASSERT(size <= sizeof(_template)/sizeof(_template[0]));
@@ -107,6 +109,15 @@ NSS_EXTERN_DATA const NSSItem g_ck_class_privkey;
(item)->size = 0; \
}
+#define NSS_CK_ATTRIBUTE_TO_BOOL(attrib, boolvar) \
+ if ((attrib)->ulValueLen > 0) { \
+ if (*((CK_BBOOL*)(attrib)->pValue) == CK_TRUE) { \
+ boolvar = PR_TRUE; \
+ } else { \
+ boolvar = PR_FALSE; \
+ } \
+ }
+
/* NSS_CK_ATTRIBUTE_TO_UTF8(attrib, str)
*
* Convert a CK_ATTRIBUTE to a string.
@@ -131,7 +142,7 @@ nssCKObject_GetAttributes
CK_ULONG count,
NSSArena *arenaOpt,
nssSession *session,
- NSSSlot *slot
+ NSSSlot *slot
);
/* Get a single attribute as an item. */
diff --git a/security/nss/lib/dev/dev.h b/security/nss/lib/dev/dev.h
index 65dee8d63..e7651aa47 100644
--- a/security/nss/lib/dev/dev.h
+++ b/security/nss/lib/dev/dev.h
@@ -34,53 +34,142 @@
#ifndef DEV_H
#define DEV_H
+/*
+ * dev.h
+ *
+ * Low-level methods for interaction with cryptoki devices
+ */
+
#ifdef DEBUG
static const char DEV_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#endif /* DEBUG */
-#ifndef DEVT_H
-#include "devt.h"
-#endif /* DEVT_H */
-
#ifndef NSSCKT_H
#include "nssckt.h"
#endif /* NSSCKT_H */
-#ifndef NSSPKIT_H
-#include "nsspkit.h"
-#endif /* NSSPKIT_H */
+#ifndef NSSDEV_H
+#include "nssdev.h"
+#endif /* NSSDEV_H */
-#ifndef BASET_H
-#include "baset.h"
-#endif /* BASET_H */
+#ifndef DEVT_H
+#include "devt.h"
+#endif /* DEVT_H */
-/*
- * nssdev.h
+PR_BEGIN_EXTERN_C
+
+/* the global module list
+ *
+ * These functions are for managing the global set of modules. Trust Domains,
+ * etc., will draw from this set. These functions are completely internal
+ * and only invoked when there are changes to the global module state
+ * (load or unload).
*
- * This file prototypes the methods of the low-level cryptoki devices.
+ * nss_InitializeGlobalModuleList
+ * nss_DestroyGlobalModuleList
+ * nss_GetLoadedModules
*
- * |-----------|---> NSSSlot <--> NSSToken
- * | NSSModule |---> NSSSlot <--> NSSToken
- * |-----------|---> NSSSlot <--> NSSToken
+ * nssGlobalModuleList_Add
+ * nssGlobalModuleList_Remove
+ * nssGlobalModuleList_FindModuleByName
+ * nssGlobalModuleList_FindSlotByName
+ * nssGlobalModuleList_FindTokenByName
*/
-PR_BEGIN_EXTERN_C
+NSS_EXTERN PRStatus
+nss_InitializeGlobalModuleList
+(
+ void
+);
+
+NSS_EXTERN PRStatus
+nss_DestroyGlobalModuleList
+(
+ void
+);
+
+NSS_EXTERN NSSModule **
+nss_GetLoadedModules
+(
+ void
+);
+
+NSS_EXTERN PRStatus
+nssGlobalModuleList_Add
+(
+ NSSModule *module
+);
+
+NSS_EXTERN PRStatus
+nssGlobalModuleList_Remove
+(
+ NSSModule *module
+);
+
+NSS_EXTERN NSSModule *
+nssGlobalModuleList_FindModuleByName
+(
+ NSSUTF8 *moduleName
+);
+
+NSS_EXTERN NSSSlot *
+nssGlobalModuleList_FindSlotByName
+(
+ NSSUTF8 *slotName
+);
+
+NSS_EXTERN NSSToken *
+nssGlobalModuleList_FindTokenByName
+(
+ NSSUTF8 *tokenName
+);
+
+NSS_EXTERN NSSToken *
+nss_GetDefaultCryptoToken
+(
+ void
+);
+
+NSS_EXTERN NSSToken *
+nss_GetDefaultDatabaseToken
+(
+ void
+);
+
+/*
+ * |-----------|<---> NSSSlot <--> NSSToken
+ * | NSSModule |<---> NSSSlot <--> NSSToken
+ * |-----------|<---> NSSSlot <--> NSSToken
+ */
+
+/* NSSModule
+ *
+ * nssModule_Create
+ * nssModule_CreateFromSpec
+ * nssModule_AddRef
+ * nssModule_GetName
+ * nssModule_GetSlots
+ * nssModule_FindSlotByName
+ * nssModule_FindTokenByName
+ * nssModule_GetCertOrder
+ */
NSS_EXTERN NSSModule *
nssModule_Create
(
NSSUTF8 *moduleOpt,
NSSUTF8 *uriOpt,
- NSSUTF8 *opaqueOpt, /* XXX is this where the mech flags go??? */
+ NSSUTF8 *opaqueOpt,
void *reserved
- /* XXX more? */
);
/* This is to use the new loading mechanism. */
NSS_EXTERN NSSModule *
nssModule_CreateFromSpec
(
- NSSUTF8 *moduleSpec
+ NSSUTF8 *moduleSpec,
+ NSSModule *parent,
+ PRBool loadSubModules
);
NSS_EXTERN PRStatus
@@ -95,20 +184,8 @@ nssModule_AddRef
NSSModule *mod
);
-NSS_EXTERN PRStatus
-nssModule_Load
-(
- NSSModule *mod
-);
-
-NSS_EXTERN PRStatus
-nssModule_Unload
-(
- NSSModule *mod
-);
-
-NSS_EXTERN PRStatus
-nssModule_LogoutAllSlots
+NSS_EXTERN NSSUTF8 *
+nssModule_GetName
(
NSSModule *mod
);
@@ -133,27 +210,69 @@ nssModule_FindTokenByName
NSSUTF8 *tokenName
);
-/* This descends from NSSTrustDomain_TraverseCertificates, a questionable
- * function. Do we want NSS to have access to this at the module level?
+NSS_EXTERN PRInt32
+nssModule_GetCertOrder
+(
+ NSSModule *module
+);
+
+/* NSSSlot
+ *
+ * nssSlot_Destroy
+ * nssSlot_AddRef
+ * nssSlot_GetName
+ * nssSlot_GetTokenName
+ * nssSlot_IsTokenPresent
+ * nssSlot_IsPermanent
+ * nssSlot_IsFriendly
+ * nssSlot_IsHardware
+ * nssSlot_Refresh
+ * nssSlot_GetModule
+ * nssSlot_GetToken
+ * nssSlot_Login
+ * nssSlot_Logout
+ * nssSlot_SetPassword
+ * nssSlot_CreateSession
*/
-NSS_EXTERN PRStatus *
-nssModule_TraverseCertificates
+
+NSS_EXTERN PRStatus
+nssSlot_Destroy
(
- NSSModule *mod,
- PRStatus (*callback)(NSSCertificate *c, void *arg),
- void *arg
+ NSSSlot *slot
);
NSS_EXTERN NSSSlot *
-nssSlot_Create
+nssSlot_AddRef
(
- NSSArena *arenaOpt,
- CK_SLOT_ID slotId,
- NSSModule *parent
+ NSSSlot *slot
);
-NSS_EXTERN PRStatus
-nssSlot_Destroy
+NSS_EXTERN NSSUTF8 *
+nssSlot_GetName
+(
+ NSSSlot *slot
+);
+
+NSS_EXTERN NSSUTF8 *
+nssSlot_GetTokenName
+(
+ NSSSlot *slot
+);
+
+NSS_EXTERN NSSModule *
+nssSlot_GetModule
+(
+ NSSSlot *slot
+);
+
+NSS_EXTERN NSSToken *
+nssSlot_GetToken
+(
+ NSSSlot *slot
+);
+
+NSS_EXTERN PRBool
+nssSlot_IsTokenPresent
(
NSSSlot *slot
);
@@ -164,30 +283,34 @@ nssSlot_IsPermanent
NSSSlot *slot
);
-NSS_EXTERN PRStatus
-nssSlot_Refresh
+NSS_EXTERN PRBool
+nssSlot_IsFriendly
(
NSSSlot *slot
);
-NSS_EXTERN NSSSlot *
-nssSlot_AddRef
+NSS_EXTERN PRBool
+nssSlot_IsHardware
(
NSSSlot *slot
);
-NSS_EXTERN NSSUTF8 *
-nssSlot_GetName
+NSS_EXTERN PRBool
+nssSlot_IsLoggedIn
(
- NSSSlot *slot,
- NSSArena *arenaOpt
+ NSSSlot *slot
+);
+
+NSS_EXTERN PRStatus
+nssSlot_Refresh
+(
+ NSSSlot *slot
);
NSS_EXTERN PRStatus
nssSlot_Login
(
NSSSlot *slot,
- PRBool asSO,
NSSCallback *pwcb
);
extern const NSSError NSS_ERROR_INVALID_PASSWORD;
@@ -213,7 +336,8 @@ NSS_EXTERN PRStatus
nssSlot_SetPassword
(
NSSSlot *slot,
- NSSCallback *pwcb
+ NSSUTF8 *oldPasswordOpt,
+ NSSUTF8 *newPassword
);
extern const NSSError NSS_ERROR_INVALID_PASSWORD;
extern const NSSError NSS_ERROR_USER_CANCELED;
@@ -230,13 +354,37 @@ nssSlot_CreateSession
PRBool readWrite /* so far, this is the only flag used */
);
-NSS_EXTERN NSSToken *
-nssToken_Create
-(
- NSSArena *arenaOpt,
- CK_SLOT_ID slotID,
- NSSSlot *parent
-);
+/* NSSToken
+ *
+ * nssToken_Destroy
+ * nssToken_AddRef
+ * nssToken_GetName
+ * nssToken_GetModule
+ * nssToken_GetSlot
+ * nssToken_NeedsPINInitialization
+ * nssToken_ImportCertificate
+ * nssToken_ImportTrust
+ * nssToken_ImportCRL
+ * nssToken_GenerateKeyPair
+ * nssToken_GenerateSymmetricKey
+ * nssToken_DeleteStoredObject
+ * nssToken_FindCertificates
+ * nssToken_FindCertificatesBySubject
+ * nssToken_FindCertificatesByNickname
+ * nssToken_FindCertificatesByEmail
+ * nssToken_FindCertificateByIssuerAndSerialNumber
+ * nssToken_FindCertificateByEncodedCertificate
+ * nssToken_FindTrustObjects
+ * nssToken_FindTrustForCertificate
+ * nssToken_FindCRLs
+ * nssToken_FindCRLsBySubject
+ * nssToken_FindPrivateKeys
+ * nssToken_FindPrivateKeyByID
+ * nssToken_Digest
+ * nssToken_BeginDigest
+ * nssToken_ContinueDigest
+ * nssToken_FinishDigest
+ */
NSS_EXTERN PRStatus
nssToken_Destroy
@@ -244,12 +392,6 @@ nssToken_Destroy
NSSToken *tok
);
-NSS_EXTERN PRBool
-nssToken_IsPresent
-(
- NSSToken *token
-);
-
NSS_EXTERN NSSToken *
nssToken_AddRef
(
@@ -262,142 +404,215 @@ nssToken_GetName
NSSToken *tok
);
-NSS_EXTERN PRStatus
+NSS_EXTERN NSSModule *
+nssToken_GetModule
+(
+ NSSToken *token
+);
+
+NSS_EXTERN NSSSlot *
+nssToken_GetSlot
+(
+ NSSToken *tok
+);
+
+NSS_EXTERN PRBool
+nssToken_NeedsPINInitialization
+(
+ NSSToken *token
+);
+
+NSS_EXTERN nssCryptokiObject *
nssToken_ImportCertificate
(
NSSToken *tok,
nssSession *sessionOpt,
- NSSCertificate *cert,
+ NSSCertificateType certType,
+ NSSItem *id,
NSSUTF8 *nickname,
+ NSSDER *encoding,
+ NSSDER *issuer,
+ NSSDER *subject,
+ NSSDER *serial,
+ NSSASCII7 *emailAddr,
PRBool asTokenObject
);
-
-NSS_EXTERN PRStatus
+
+NSS_EXTERN nssCryptokiObject *
nssToken_ImportTrust
(
NSSToken *tok,
nssSession *sessionOpt,
- NSSTrust *trust,
+ NSSDER *certEncoding,
+ NSSDER *certIssuer,
+ NSSDER *certSerial,
+ nssTrustLevel serverAuth,
+ nssTrustLevel clientAuth,
+ nssTrustLevel codeSigning,
+ nssTrustLevel emailProtection,
PRBool asTokenObject
);
-NSS_EXTERN PRStatus
-nssToken_SetTrustCache
+NSS_EXTERN nssCryptokiObject *
+nssToken_ImportCRL
(
- NSSToken *tok
+ NSSToken *token,
+ nssSession *sessionOpt,
+ NSSDER *subject,
+ NSSDER *encoding,
+ PRBool isKRL,
+ NSSUTF8 *url,
+ PRBool asTokenObject
);
+/* Permanently remove an object from the token. */
NSS_EXTERN PRStatus
-nssToken_SetCrlCache
+nssToken_DeleteStoredObject
(
- NSSToken *tok
+ nssCryptokiObject *instance
);
-NSS_EXTERN PRBool
-nssToken_HasCrls
+NSS_EXTERN nssCryptokiObject **
+nssToken_FindCertificates
(
- NSSToken *tok
+ NSSToken *token,
+ nssSession *sessionOpt,
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
);
-NSS_EXTERN PRStatus
-nssToken_SetHasCrls
+NSS_EXTERN nssCryptokiObject **
+nssToken_FindCertificatesBySubject
(
- NSSToken *tok
+ NSSToken *token,
+ nssSession *sessionOpt,
+ NSSDER *subject,
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
);
-NSS_EXTERN NSSPublicKey *
-nssToken_GenerateKeyPair
+NSS_EXTERN nssCryptokiObject **
+nssToken_FindCertificatesByNickname
(
- NSSToken *tok,
- nssSession *sessionOpt
- /* algorithm and parameters */
+ NSSToken *token,
+ nssSession *sessionOpt,
+ NSSUTF8 *name,
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
);
-NSS_EXTERN NSSSymmetricKey *
-nssToken_GenerateSymmetricKey
+NSS_EXTERN nssCryptokiObject **
+nssToken_FindCertificatesByEmail
(
- NSSToken *tok,
- nssSession *sessionOpt
- /* algorithm and parameters */
+ NSSToken *token,
+ nssSession *sessionOpt,
+ NSSASCII7 *email,
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
);
-/* Permanently remove an object from the token. */
-NSS_EXTERN PRStatus
-nssToken_DeleteStoredObject
+NSS_EXTERN nssCryptokiObject **
+nssToken_FindCertificatesByID
(
- nssCryptokiInstance *instance
+ NSSToken *token,
+ nssSession *sessionOpt,
+ NSSItem *id,
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
);
-NSS_EXTERN NSSTrust *
-nssToken_FindTrustForCert
+NSS_EXTERN nssCryptokiObject *
+nssToken_FindCertificateByIssuerAndSerialNumber
(
NSSToken *token,
nssSession *sessionOpt,
- NSSCertificate *c,
- nssTokenSearchType searchType
+ NSSDER *issuer,
+ NSSDER *serial,
+ nssTokenSearchType searchType,
+ PRStatus *statusOpt
);
-NSS_EXTERN PRStatus
-nssToken_TraverseCertificates
+NSS_EXTERN nssCryptokiObject *
+nssToken_FindCertificateByEncodedCertificate
(
- NSSToken *tok,
+ NSSToken *token,
nssSession *sessionOpt,
- nssTokenCertSearch *search
+ NSSBER *encodedCertificate,
+ nssTokenSearchType searchType,
+ PRStatus *statusOpt
);
-NSS_EXTERN PRStatus
-nssToken_TraverseCertificatesBySubject
+NSS_EXTERN nssCryptokiObject **
+nssToken_FindTrustObjects
(
NSSToken *token,
nssSession *sessionOpt,
- NSSDER *subject,
- nssTokenCertSearch *search
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
);
-NSS_EXTERN PRStatus
-nssToken_TraverseCertificatesByNickname
+NSS_EXTERN nssCryptokiObject *
+nssToken_FindTrustForCertificate
(
NSSToken *token,
nssSession *sessionOpt,
- NSSUTF8 *name,
- nssTokenCertSearch *search
+ NSSDER *certEncoding,
+ NSSDER *certIssuer,
+ NSSDER *certSerial,
+ nssTokenSearchType searchType
);
-NSS_EXTERN PRStatus
-nssToken_TraverseCertificatesByEmail
+NSS_EXTERN nssCryptokiObject **
+nssToken_FindCRLs
(
NSSToken *token,
nssSession *sessionOpt,
- NSSASCII7 *email,
- nssTokenCertSearch *search
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
);
-NSS_EXTERN NSSCertificate *
-nssToken_FindCertificateByIssuerAndSerialNumber
+NSS_EXTERN nssCryptokiObject **
+nssToken_FindCRLsBySubject
(
NSSToken *token,
nssSession *sessionOpt,
- NSSDER *issuer,
- NSSDER *serial,
- nssTokenSearchType searchType
+ NSSDER *subject,
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
);
-NSS_EXTERN NSSCertificate *
-nssToken_FindCertificateByEncodedCertificate
+NSS_EXTERN nssCryptokiObject **
+nssToken_FindPrivateKeys
(
NSSToken *token,
nssSession *sessionOpt,
- NSSBER *encodedCertificate,
- nssTokenSearchType searchType
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
);
-NSS_EXTERN NSSTrust *
-nssToken_FindTrustForCert
+NSS_EXTERN nssCryptokiObject *
+nssToken_FindPrivateKeyByID
(
NSSToken *token,
- nssSession *session,
- NSSCertificate *c,
- nssTokenSearchType searchType
+ nssSession *sessionOpt,
+ NSSItem *keyID
+);
+
+NSS_EXTERN nssCryptokiObject *
+nssToken_FindPublicKeyByID
+(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ NSSItem *keyID
);
NSS_EXTERN NSSItem *
@@ -436,6 +651,14 @@ nssToken_FinishDigest
NSSArena *arenaOpt
);
+/* nssSession
+ *
+ * nssSession_Destroy
+ * nssSession_EnterMonitor
+ * nssSession_ExitMonitor
+ * nssSession_IsReadWrite
+ */
+
NSS_EXTERN PRStatus
nssSession_Destroy
(
@@ -463,28 +686,283 @@ nssSession_IsReadWrite
nssSession *s
);
-NSS_EXTERN NSSAlgorithmAndParameters *
-NSSAlgorithmAndParameters_CreateSHA1Digest
+/* nssCryptokiObject
+ *
+ * An object living on a cryptoki token.
+ * Not really proper to mix up the object types just because
+ * nssCryptokiObject itself is generic, but doing so anyway.
+ *
+ * nssCryptokiObject_Destroy
+ * nssCryptokiObject_Equal
+ * nssCryptokiObject_Clone
+ * nssCryptokiCertificate_GetAttributes
+ * nssCryptokiPrivateKey_GetAttributes
+ * nssCryptokiPublicKey_GetAttributes
+ * nssCryptokiTrust_GetAttributes
+ * nssCryptokiCRL_GetAttributes
+ */
+
+NSS_EXTERN void
+nssCryptokiObject_Destroy
(
- NSSArena *arenaOpt
+ nssCryptokiObject *object
);
-NSS_EXTERN NSSAlgorithmAndParameters *
-NSSAlgorithmAndParameters_CreateMD5Digest
+NSS_EXTERN PRBool
+nssCryptokiObject_Equal
+(
+ nssCryptokiObject *object1,
+ nssCryptokiObject *object2
+);
+
+NSS_EXTERN nssCryptokiObject *
+nssCryptokiObject_Clone
+(
+ nssCryptokiObject *object
+);
+
+NSS_EXTERN PRStatus
+nssCryptokiCertificate_GetAttributes
+(
+ nssCryptokiObject *object,
+ nssSession *sessionOpt,
+ NSSArena *arenaOpt,
+ NSSCertificateType *certTypeOpt,
+ NSSItem *idOpt,
+ NSSDER *encodingOpt,
+ NSSDER *issuerOpt,
+ NSSDER *serialOpt,
+ NSSDER *subjectOpt,
+ NSSASCII7 **emailOpt
+);
+
+NSS_EXTERN PRStatus
+nssCryptokiTrust_GetAttributes
+(
+ nssCryptokiObject *trustObject,
+ nssSession *sessionOpt,
+ nssTrustLevel *serverAuth,
+ nssTrustLevel *clientAuth,
+ nssTrustLevel *codeSigning,
+ nssTrustLevel *emailProtection
+);
+
+NSS_EXTERN PRStatus
+nssCryptokiCRL_GetAttributes
+(
+ nssCryptokiObject *crlObject,
+ nssSession *sessionOpt,
+ NSSArena *arenaOpt,
+ NSSItem *encodingOpt,
+ NSSUTF8 **urlOpt,
+ PRBool *isKRLOpt
+);
+
+/* I'm including this to handle import of certificates in NSS 3.5. This
+ * function will set the cert-related attributes of a key, in order to
+ * associate it with a cert. Does it stay like this for 4.0?
+ */
+NSS_EXTERN PRStatus
+nssCryptokiPrivateKey_SetCertificate
+(
+ nssCryptokiObject *keyObject,
+ nssSession *sessionOpt,
+ NSSUTF8 *nickname,
+ NSSItem *id,
+ NSSDER *subject
+);
+
+NSS_EXTERN void
+nssModuleArray_Destroy
+(
+ NSSModule **modules
+);
+
+/* nssSlotArray
+ *
+ * nssSlotArray_Destroy
+ */
+
+NSS_EXTERN void
+nssSlotArray_Destroy
+(
+ NSSSlot **slots
+);
+
+/* nssTokenArray
+ *
+ * nssTokenArray_Destroy
+ */
+
+NSS_EXTERN void
+nssTokenArray_Destroy
+(
+ NSSToken **tokens
+);
+
+/* nssCryptokiObjectArray
+ *
+ * nssCryptokiObjectArray_Destroy
+ */
+NSS_EXTERN void
+nssCryptokiObjectArray_Destroy
+(
+ nssCryptokiObject **object
+);
+
+/* nssSlotList
+*
+ * An ordered list of slots. The order can be anything, it is set in the
+ * Add methods. Perhaps it should be CreateInCertOrder, ...?
+ *
+ * nssSlotList_Create
+ * nssSlotList_Destroy
+ * nssSlotList_Add
+ * nssSlotList_AddModuleSlots
+ * nssSlotList_GetSlots
+ * nssSlotList_FindSlotByName
+ * nssSlotList_FindTokenByName
+ * nssSlotList_GetBestSlot
+ * nssSlotList_GetBestSlotForAlgorithmAndParameters
+ * nssSlotList_GetBestSlotForAlgorithmsAndParameters
+ */
+
+/* nssSlotList_Create
+ */
+NSS_EXTERN nssSlotList *
+nssSlotList_Create
(
NSSArena *arenaOpt
);
+/* nssSlotList_Destroy
+ */
+NSS_EXTERN void
+nssSlotList_Destroy
+(
+ nssSlotList *slotList
+);
+
+/* nssSlotList_Add
+ *
+ * Add the given slot in the given order.
+ */
+NSS_EXTERN PRStatus
+nssSlotList_Add
+(
+ nssSlotList *slotList,
+ NSSSlot *slot,
+ PRUint32 order
+);
+
+/* nssSlotList_AddModuleSlots
+ *
+ * Add all slots in the module, in the given order (the slots will have
+ * equal weight).
+ */
+NSS_EXTERN PRStatus
+nssSlotList_AddModuleSlots
+(
+ nssSlotList *slotList,
+ NSSModule *module,
+ PRUint32 order
+);
+
+/* nssSlotList_GetSlots
+ */
+NSS_EXTERN NSSSlot **
+nssSlotList_GetSlots
+(
+ nssSlotList *slotList
+);
+
+/* nssSlotList_FindSlotByName
+ */
+NSS_EXTERN NSSSlot *
+nssSlotList_FindSlotByName
+(
+ nssSlotList *slotList,
+ NSSUTF8 *slotName
+);
+
+/* nssSlotList_FindTokenByName
+ */
+NSS_EXTERN NSSToken *
+nssSlotList_FindTokenByName
+(
+ nssSlotList *slotList,
+ NSSUTF8 *tokenName
+);
+
+/* nssSlotList_GetBestSlot
+ *
+ * The best slot is the highest ranking in order, i.e., the first in the
+ * list.
+ */
+NSS_EXTERN NSSSlot *
+nssSlotList_GetBestSlot
+(
+ nssSlotList *slotList
+);
+
+/* nssSlotList_GetBestSlotForAlgorithmAndParameters
+ *
+ * Highest-ranking slot than can handle algorithm/parameters.
+ */
+NSS_EXTERN NSSSlot *
+nssSlotList_GetBestSlotForAlgorithmAndParameters
+(
+ nssSlotList *slotList,
+ NSSAlgorithmAndParameters *ap
+);
+
+/* nssSlotList_GetBestSlotForAlgorithmsAndParameters
+ *
+ * Highest-ranking slot than can handle all algorithms/parameters.
+ */
+NSS_EXTERN NSSSlot *
+nssSlotList_GetBestSlotForAlgorithmsAndParameters
+(
+ nssSlotList *slotList,
+ NSSAlgorithmAndParameters **ap
+);
+
#ifdef NSS_3_4_CODE
-/* exposing this for the smart card cache code */
-NSS_EXTERN nssCryptokiInstance *
-nssCryptokiInstance_Create
+
+NSS_EXTERN PRBool
+nssToken_IsPresent
(
- NSSArena *arena,
- NSSToken *t,
- CK_OBJECT_HANDLE h,
- PRBool isTokenObject
+ NSSToken *token
);
+
+NSS_EXTERN nssSession *
+nssToken_GetDefaultSession
+(
+ NSSToken *token
+);
+
+NSS_EXTERN PRStatus
+nssToken_GetTrustOrder
+(
+ NSSToken *tok
+);
+
+NSS_EXTERN PRStatus
+nssToken_NofifyCertsNotVisible
+(
+ NSSToken *tok
+);
+
+NSS_EXTERN PRStatus
+nssToken_TraverseCertificates
+(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ nssTokenSearchType searchType,
+ PRStatus (* callback)(nssCryptokiObject *instance, void *arg),
+ void *arg
+);
+
#endif
PR_END_EXTERN_C
diff --git a/security/nss/lib/dev/devm.h b/security/nss/lib/dev/devm.h
index d226069c9..0dd0d5b36 100644
--- a/security/nss/lib/dev/devm.h
+++ b/security/nss/lib/dev/devm.h
@@ -38,25 +38,201 @@
static const char DEVM_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#endif /* DEBUG */
-#ifndef DEVT_H
-#include "devt.h"
-#endif /* DEVT_H */
+#ifndef BASE_H
+#include "base.h"
+#endif /* BASE_H */
#ifndef NSSCKT_H
#include "nssckt.h"
#endif /* NSSCKT_H */
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
+#ifndef DEV_H
+#include "dev.h"
+#endif /* DEV_H */
+
+#ifndef DEVTM_H
+#include "devtm.h"
+#endif /* DEVTM_H */
PR_BEGIN_EXTERN_C
+/* Shortcut to cryptoki API functions. */
+#define CKAPI(epv) \
+ ((CK_FUNCTION_LIST_PTR)(epv))
+
+NSS_EXTERN void
+nssDevice_AddRef
+(
+ struct nssDeviceBaseStr *device
+);
+
+NSS_EXTERN PRBool
+nssDevice_Destroy
+(
+ struct nssDeviceBaseStr *device
+);
+
+NSS_EXTERN PRBool
+nssModule_IsThreadSafe
+(
+ NSSModule *module
+);
+
+NSS_EXTERN PRBool
+nssModule_IsInternal
+(
+ NSSModule *mod
+);
+
+NSS_EXTERN PRBool
+nssModule_IsModuleDBOnly
+(
+ NSSModule *mod
+);
+
+NSS_EXTERN void *
+nssModule_GetCryptokiEPV
+(
+ NSSModule *mod
+);
+
+NSS_EXTERN NSSSlot *
+nssSlot_Create
+(
+ CK_SLOT_ID slotId,
+ NSSModule *parent
+);
+
+NSS_EXTERN void *
+nssSlot_GetCryptokiEPV
+(
+ NSSSlot *slot
+);
+
+NSS_EXTERN NSSToken *
+nssToken_Create
+(
+ CK_SLOT_ID slotID,
+ NSSSlot *peer
+);
+
+NSS_EXTERN void *
+nssToken_GetCryptokiEPV
+(
+ NSSToken *token
+);
+
+NSS_EXTERN nssSession *
+nssToken_GetDefaultSession
+(
+ NSSToken *token
+);
+
+NSS_EXTERN PRBool
+nssToken_IsLoginRequired
+(
+ NSSToken *token
+);
+
+NSS_EXTERN void
+nssToken_Remove
+(
+ NSSToken *token
+);
+
+NSS_EXTERN nssCryptokiObject *
+nssCryptokiObject_Create
+(
+ NSSToken *t,
+ nssSession *session,
+ CK_OBJECT_HANDLE h
+);
+
+NSS_EXTERN nssTokenObjectCache *
+nssTokenObjectCache_Create
+(
+ NSSToken *token,
+ PRBool cacheCerts,
+ PRBool cacheTrust,
+ PRBool cacheCRLs
+);
+
+NSS_EXTERN void
+nssTokenObjectCache_Destroy
+(
+ nssTokenObjectCache *cache
+);
+
+NSS_EXTERN void
+nssTokenObjectCache_Clear
+(
+ nssTokenObjectCache *cache
+);
+
+NSS_EXTERN PRBool
+nssTokenObjectCache_HaveObjectClass
+(
+ nssTokenObjectCache *cache,
+ CK_OBJECT_CLASS objclass
+);
+
+NSS_EXTERN nssCryptokiObject **
+nssTokenObjectCache_FindObjectsByTemplate
+(
+ nssTokenObjectCache *cache,
+ CK_OBJECT_CLASS objclass,
+ CK_ATTRIBUTE_PTR otemplate,
+ CK_ULONG otlen,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
+);
+
+NSS_EXTERN PRStatus
+nssTokenObjectCache_GetObjectAttributes
+(
+ nssTokenObjectCache *cache,
+ NSSArena *arenaOpt,
+ nssCryptokiObject *object,
+ CK_OBJECT_CLASS objclass,
+ CK_ATTRIBUTE_PTR atemplate,
+ CK_ULONG atlen
+);
+
+NSS_EXTERN PRStatus
+nssTokenObjectCache_ImportObject
+(
+ nssTokenObjectCache *cache,
+ nssCryptokiObject *object,
+ CK_OBJECT_CLASS objclass,
+ CK_ATTRIBUTE_PTR ot,
+ CK_ULONG otlen
+);
+
+NSS_EXTERN void
+nssTokenObjectCache_RemoveObject
+(
+ nssTokenObjectCache *cache,
+ nssCryptokiObject *object
+);
+
+/* XXX allows peek back into token */
+NSS_EXTERN PRStatus
+nssToken_GetCachedObjectAttributes
+(
+ NSSToken *token,
+ NSSArena *arenaOpt,
+ nssCryptokiObject *object,
+ CK_OBJECT_CLASS objclass,
+ CK_ATTRIBUTE_PTR atemplate,
+ CK_ULONG atlen
+);
+
/* PKCS#11 stores strings in a fixed-length buffer padded with spaces. This
* function gets the length of the actual string.
*/
NSS_EXTERN PRUint32
-nssPKCS11StringLength(
+nssPKCS11String_Length
+(
CK_CHAR *pkcs11str,
PRUint32 bufLen
);
diff --git a/security/nss/lib/dev/devmod.c b/security/nss/lib/dev/devmod.c
index 455d063e8..e0006370f 100644
--- a/security/nss/lib/dev/devmod.c
+++ b/security/nss/lib/dev/devmod.c
@@ -35,27 +35,69 @@
static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#endif /* DEBUG */
-#include "nspr.h"
-
-#ifndef DEV_H
-#include "dev.h"
-#endif /* DEV_H */
+#ifndef NSSCKEPV_H
+#include "nssckepv.h"
+#endif /* NSSCKEPV_H */
#ifndef DEVM_H
#include "devm.h"
#endif /* DEVM_H */
-#ifndef NSSCKEPV_H
-#include "nssckepv.h"
-#endif /* NSSCKEPV_H */
-
#ifndef CKHELPER_H
#include "ckhelper.h"
#endif /* CKHELPER_H */
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
+#ifdef PURE_STAN_CODE
+
+extern void FC_GetFunctionList(void);
+extern void NSC_GetFunctionList(void);
+extern void NSC_ModuleDBFunc(void);
+
+/* The list of boolean flags used to describe properties of a
+ * module.
+ */
+#define NSSMODULE_FLAGS_NOT_THREADSAFE 0x0001 /* isThreadSafe */
+#define NSSMODULE_FLAGS_INTERNAL 0x0002 /* isInternal */
+#define NSSMODULE_FLAGS_FIPS 0x0004 /* isFIPS */
+#define NSSMODULE_FLAGS_MODULE_DB 0x0008 /* isModuleDB */
+#define NSSMODULE_FLAGS_MODULE_DB_ONLY 0x0010 /* moduleDBOnly */
+#define NSSMODULE_FLAGS_CRITICAL 0x0020 /* isCritical */
+
+struct NSSModuleStr {
+ struct nssDeviceBaseStr base;
+ NSSUTF8 *libraryName;
+ PRLibrary *library;
+ char *libraryParams;
+ void *moduleDBFunc;
+ void *epv;
+ CK_INFO info;
+ NSSSlot **slots;
+ PRUint32 numSlots;
+ PRBool isLoaded;
+ struct {
+ PRInt32 trust;
+ PRInt32 cipher;
+ PRInt32 certStorage;
+ } order;
+};
+
+#define NSSMODULE_IS_THREADSAFE(module) \
+ (!(module->base.flags & NSSMODULE_FLAGS_NOT_THREADSAFE))
+
+#define NSSMODULE_IS_INTERNAL(module) \
+ (module->base.flags & NSSMODULE_FLAGS_INTERNAL)
+
+#define NSSMODULE_IS_FIPS(module) \
+ (module->base.flags & NSSMODULE_FLAGS_FIPS)
+
+#define NSSMODULE_IS_MODULE_DB(module) \
+ (module->base.flags & NSSMODULE_FLAGS_MODULE_DB)
+
+#define NSSMODULE_IS_MODULE_DB_ONLY(module) \
+ (module->base.flags & NSSMODULE_FLAGS_MODULE_DB_ONLY)
+
+#define NSSMODULE_IS_CRITICAL(module) \
+ (module->base.flags & NSSMODULE_FLAGS_CRITICAL)
/* Threading callbacks for C_Initialize. Use NSPR threads. */
@@ -92,6 +134,9 @@ nss_ck_UnlockMutex(CK_VOID_PTR mutex)
}
/* Default callback args to C_Initialize */
+/* XXX not const because we are modifying the pReserved argument in order
+ * to use the libraryParams extension.
+ */
static CK_C_INITIALIZE_ARGS
s_ck_initialize_args = {
nss_ck_CreateMutex, /* CreateMutex */
@@ -103,55 +148,6 @@ s_ck_initialize_args = {
NULL /* pReserved */
};
-/* Alloc memory for a module. Copy in the module name and library path
- * if provided. XXX use the opaque arg also, right?
- */
-NSS_IMPLEMENT NSSModule *
-nssModule_Create
-(
- NSSUTF8 *moduleOpt,
- NSSUTF8 *uriOpt,
- NSSUTF8 *opaqueOpt,
- void *reserved
-)
-{
- NSSArena *arena;
- NSSModule *rvMod;
- arena = NSSArena_Create();
- if(!arena) {
- return (NSSModule *)NULL;
- }
- rvMod = nss_ZNEW(arena, NSSModule);
- if (!rvMod) {
- goto loser;
- }
- if (moduleOpt) {
- /* XXX making the gross assumption this is just the module name */
- /* if the name is a duplicate, should that be tested here? or
- * wait for Load?
- */
- rvMod->name = nssUTF8_Duplicate(moduleOpt, arena);
- if (!rvMod->name) {
- goto loser;
- }
- }
- if (uriOpt) {
- /* Load the module from a URI. */
- /* XXX at this time - only file URI (even worse, no file:// for now) */
- rvMod->libraryPath = nssUTF8_Duplicate(uriOpt, arena);
- if (!rvMod->libraryPath) {
- goto loser;
- }
- }
- rvMod->arena = arena;
- rvMod->refCount = 1;
- /* everything else is 0/NULL at this point. */
- return rvMod;
-loser:
- nssArena_Destroy(arena);
- return (NSSModule *)NULL;
-}
-
/* load all slots in a module. */
static PRStatus
module_load_slots(NSSModule *mod)
@@ -163,7 +159,7 @@ module_load_slots(NSSModule *mod)
PRStatus nssrv;
CK_RV ckrv;
/* Get the number of slots */
- ckrv = CKAPI(mod)->C_GetSlotList(CK_FALSE, NULL, &ulNumSlots);
+ ckrv = CKAPI(mod->epv)->C_GetSlotList(CK_FALSE, NULL, &ulNumSlots);
if (ckrv != CKR_OK) {
/* what is the error? */
return PR_FAILURE;
@@ -174,26 +170,26 @@ module_load_slots(NSSModule *mod)
goto loser;
}
/* Get the actual slot list */
- ckrv = CKAPI(mod)->C_GetSlotList(CK_FALSE, slotIDs, &ulNumSlots);
+ ckrv = CKAPI(mod->epv)->C_GetSlotList(CK_FALSE, slotIDs, &ulNumSlots);
if (ckrv != CKR_OK) {
/* what is the error? */
goto loser;
}
/* Alloc memory for the array of slots, in the module's arena */
- mark = nssArena_Mark(mod->arena);
+ mark = nssArena_Mark(mod->base.arena); /* why mark? it'll be destroyed */
if (!mark) {
return PR_FAILURE;
}
- slots = nss_ZNEWARRAY(mod->arena, NSSSlot *, ulNumSlots);
+ slots = nss_ZNEWARRAY(mod->base.arena, NSSSlot *, ulNumSlots);
if (!slots) {
goto loser;
}
/* Initialize each slot */
for (i=0; i<ulNumSlots; i++) {
- slots[i] = nssSlot_Create(mod->arena, slotIDs[i], mod);
+ slots[i] = nssSlot_Create(slotIDs[i], mod);
}
nss_ZFreeIf(slotIDs);
- nssrv = nssArena_Unmark(mod->arena, mark);
+ nssrv = nssArena_Unmark(mod->base.arena, mark);
if (nssrv != PR_SUCCESS) {
goto loser;
}
@@ -202,44 +198,12 @@ module_load_slots(NSSModule *mod)
return PR_SUCCESS;
loser:
if (mark) {
- nssArena_Release(mod->arena, mark);
+ nssArena_Release(mod->base.arena, mark);
}
nss_ZFreeIf(slotIDs);
return PR_FAILURE;
}
-/* This is going to take much more thought. The module has a list of slots,
- * each of which points to a token. Presumably, all are ref counted. Some
- * kind of consistency check is needed here, or perhaps at a higher level.
- */
-NSS_IMPLEMENT PRStatus
-nssModule_Destroy
-(
- NSSModule *mod
-)
-{
- PRUint32 i;
- if (--mod->refCount == 0) {
- /* Ignore any failure here. */
- for (i=0; i<mod->numSlots; i++) {
- nssSlot_Destroy(mod->slots[i]);
- }
- (void)nssModule_Unload(mod);
- return NSSArena_Destroy(mod->arena);
- }
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT NSSModule *
-nssModule_AddRef
-(
- NSSModule *mod
-)
-{
- ++mod->refCount;
- return mod;
-}
-
NSS_IMPLEMENT PRStatus
nssModule_Load
(
@@ -247,48 +211,79 @@ nssModule_Load
)
{
PRLibrary *library = NULL;
- CK_C_GetFunctionList ep;
+ CK_C_GetFunctionList epv;
CK_RV ckrv;
- /* Use NSPR to load the library */
- library = PR_LoadLibrary((char *)mod->libraryPath);
- if (!library) {
- /* what's the error to set? */
- return PR_FAILURE;
+ if (NSSMODULE_IS_INTERNAL(mod)) {
+ /* internal, statically get the C_GetFunctionList function */
+ if (NSSMODULE_IS_FIPS(mod)) {
+ epv = (CK_C_GetFunctionList) FC_GetFunctionList;
+ } else {
+ epv = (CK_C_GetFunctionList) NSC_GetFunctionList;
+ }
+ if (NSSMODULE_IS_MODULE_DB(mod)) {
+ mod->moduleDBFunc = (void *) NSC_ModuleDBFunc;
+ }
+ if (NSSMODULE_IS_MODULE_DB_ONLY(mod)) {
+ mod->isLoaded = PR_TRUE; /* XXX needed? */
+ return PR_SUCCESS;
+ }
+ } else {
+ /* Use NSPR to load the library */
+ library = PR_LoadLibrary(mod->libraryName);
+ if (!library) {
+ /* what's the error to set? */
+ return PR_FAILURE;
+ }
+ mod->library = library;
+ /* Skip if only getting the db loader function */
+ if (!NSSMODULE_IS_MODULE_DB_ONLY(mod)) {
+ /* Load the cryptoki entry point function */
+ epv = (CK_C_GetFunctionList)PR_FindSymbol(library,
+ "C_GetFunctionList");
+ }
+ /* Load the module database loader function */
+ if (NSSMODULE_IS_MODULE_DB(mod)) {
+ mod->moduleDBFunc = (void *)PR_FindSymbol(library,
+ "NSS_ReturnModuleSpecData");
+ }
}
- mod->library = library;
- /* TODO: semantics here in SECMOD_LoadModule about module db */
- /* Load the cryptoki entry point function */
- ep = (CK_C_GetFunctionList)PR_FindSymbol(library, "C_GetFunctionList");
- if (ep == NULL) {
+ if (epv == NULL) {
goto loser;
}
/* Load the cryptoki entry point vector (function list) */
- ckrv = (*ep)((CK_FUNCTION_LIST_PTR *)&mod->epv);
+ ckrv = (*epv)((CK_FUNCTION_LIST_PTR *)&mod->epv);
if (ckrv != CKR_OK) {
goto loser;
}
/* Initialize the module */
- /* XXX This is where some additional parameters may need to come in,
- * SECMOD_LoadModule has LibraryParameters
- */
- ckrv = CKAPI(mod)->C_Initialize(&s_ck_initialize_args);
+ if (mod->libraryParams) {
+ s_ck_initialize_args.LibraryParameters = (void *)mod->libraryParams;
+ } else {
+ s_ck_initialize_args.LibraryParameters = NULL;
+ }
+ ckrv = CKAPI(mod->epv)->C_Initialize(&s_ck_initialize_args);
if (ckrv != CKR_OK) {
/* Apparently the token is not thread safe. Retry without
* threading parameters.
*/
- mod->flags |= NSSMODULE_FLAGS_NOT_THREADSAFE;
- ckrv = CKAPI(mod)->C_Initialize((CK_VOID_PTR)NULL);
+ mod->base.flags |= NSSMODULE_FLAGS_NOT_THREADSAFE;
+ ckrv = CKAPI(mod->epv)->C_Initialize((CK_VOID_PTR)NULL);
if (ckrv != CKR_OK) {
goto loser;
}
}
/* TODO: check the version # using C_GetInfo */
+ ckrv = CKAPI(mod->epv)->C_GetInfo(&mod->info);
+ if (ckrv != CKR_OK) {
+ goto loser;
+ }
/* TODO: if the name is not set, get it from info.libraryDescription */
/* Now load the slots */
if (module_load_slots(mod) != PR_SUCCESS) {
goto loser;
}
/* Module has successfully loaded */
+ mod->isLoaded = PR_TRUE;
return PR_SUCCESS;
loser:
if (library) {
@@ -308,15 +303,540 @@ nssModule_Unload
{
PRStatus nssrv = PR_SUCCESS;
if (mod->library) {
- (void)CKAPI(mod)->C_Finalize(NULL);
+ (void)CKAPI(mod->epv)->C_Finalize(NULL);
nssrv = PR_UnloadLibrary(mod->library);
}
/* Free the slots, yes? */
mod->library = NULL;
mod->epv = NULL;
+ mod->isLoaded = PR_FALSE;
+ return nssrv;
+}
+
+/* Alloc memory for a module. Copy in the module name and library path
+ * if provided. XXX use the opaque arg also, right?
+ */
+NSS_IMPLEMENT NSSModule *
+nssModule_Create
+(
+ NSSUTF8 *moduleOpt,
+ NSSUTF8 *uriOpt,
+ NSSUTF8 *opaqueOpt,
+ void *reserved
+)
+{
+ NSSArena *arena;
+ NSSModule *rvMod;
+ arena = NSSArena_Create();
+ if(!arena) {
+ return (NSSModule *)NULL;
+ }
+ rvMod = nss_ZNEW(arena, NSSModule);
+ if (!rvMod) {
+ goto loser;
+ }
+ if (moduleOpt) {
+ /* XXX making the gross assumption this is just the module name */
+ /* if the name is a duplicate, should that be tested here? or
+ * wait for Load?
+ */
+ rvMod->base.name = nssUTF8_Duplicate(moduleOpt, arena);
+ if (!rvMod->base.name) {
+ goto loser;
+ }
+ }
+ if (uriOpt) {
+ /* Load the module from a URI. */
+ /* XXX at this time - only file URI (even worse, no file:// for now) */
+ rvMod->libraryName = nssUTF8_Duplicate(uriOpt, arena);
+ if (!rvMod->libraryName) {
+ goto loser;
+ }
+ }
+ rvMod->base.arena = arena;
+ rvMod->base.refCount = 1;
+ rvMod->base.lock = PZ_NewLock(nssNSSILockOther);
+ if (!rvMod->base.lock) {
+ goto loser;
+ }
+ /* everything else is 0/NULL at this point. */
+ return rvMod;
+loser:
+ nssArena_Destroy(arena);
+ return (NSSModule *)NULL;
+}
+
+NSS_EXTERN PRStatus
+nssCryptokiArgs_ParseNextPair
+(
+ NSSUTF8 *start,
+ NSSUTF8 **attrib,
+ NSSUTF8 **value,
+ NSSUTF8 **remainder,
+ NSSArena *arenaOpt
+);
+
+static PRStatus
+parse_slot_flags
+(
+ NSSSlot *slot,
+ NSSUTF8 *slotFlags
+)
+{
+ PRStatus nssrv = PR_SUCCESS;
+#if 0
+ PRBool done = PR_FALSE;
+ NSSUTF8 *mark, *last;
+ last = mark = slotFlags;
+ while (PR_TRUE) {
+ while (*mark && *mark != ',') ++mark;
+ if (!*mark) done = PR_TRUE;
+ *mark = '\0';
+ if (nssUTF8_Equal(last, "RANDOM", &nssrv)) {
+ slot->base.flags |= NSSSLOT_FLAGS_HAS_RANDOM;
+ } else if (nssUTF8_Equal(last, "RSA", &nssrv)) {
+ slot->base.flags |= NSSSLOT_FLAGS_RSA;
+ } else if (nssUTF8_Equal(last, "DSA", &nssrv)) {
+ slot->base.flags |= NSSSLOT_FLAGS_DSA;
+ } else if (nssUTF8_Equal(last, "DH", &nssrv)) {
+ slot->base.flags |= NSSSLOT_FLAGS_DH;
+ } else if (nssUTF8_Equal(last, "RC2", &nssrv)) {
+ slot->base.flags |= NSSSLOT_FLAGS_RC2;
+ } else if (nssUTF8_Equal(last, "RC4", &nssrv)) {
+ slot->base.flags |= NSSSLOT_FLAGS_RC4;
+ } else if (nssUTF8_Equal(last, "RC5", &nssrv)) {
+ slot->base.flags |= NSSSLOT_FLAGS_RC5;
+ } else if (nssUTF8_Equal(last, "DES", &nssrv)) {
+ slot->base.flags |= NSSSLOT_FLAGS_DES;
+ } else if (nssUTF8_Equal(last, "AES", &nssrv)) {
+ slot->base.flags |= NSSSLOT_FLAGS_AES;
+ } else if (nssUTF8_Equal(last, "SHA1", &nssrv)) {
+ slot->base.flags |= NSSSLOT_FLAGS_SHA1;
+ } else if (nssUTF8_Equal(last, "MD2", &nssrv)) {
+ slot->base.flags |= NSSSLOT_FLAGS_MD2;
+ } else if (nssUTF8_Equal(last, "MD5", &nssrv)) {
+ slot->base.flags |= NSSSLOT_FLAGS_MD5;
+ } else if (nssUTF8_Equal(last, "SSL", &nssrv)) {
+ slot->base.flags |= NSSSLOT_FLAGS_SSL;
+ } else if (nssUTF8_Equal(last, "TLS", &nssrv)) {
+ slot->base.flags |= NSSSLOT_FLAGS_TLS;
+ } else if (nssUTF8_Equal(last, "PublicCerts", &nssrv)) {
+ slot->base.flags |= NSSSLOT_FLAGS_FRIENDLY;
+ } else {
+ return PR_FAILURE;
+ }
+ if (done) break;
+ last = ++mark;
+ }
+#endif
+ return nssrv;
+}
+
+static PRStatus
+parse_slot_parameters
+(
+ NSSSlot *slot,
+ NSSUTF8 *slotParams,
+ NSSArena *tmparena
+)
+{
+ PRStatus nssrv = PR_SUCCESS;
+ NSSUTF8 *current, *remainder;
+ NSSUTF8 *attrib, *value;
+ current = slotParams;
+ while (nssrv == PR_SUCCESS) {
+ nssrv = nssCryptokiArgs_ParseNextPair(current,
+ &attrib, &value,
+ &remainder, tmparena);
+ if (nssrv != PR_SUCCESS) break;
+ if (value) {
+ if (nssUTF8_Equal(attrib, "slotFlags", &nssrv)) {
+ nssrv = parse_slot_flags(slot, value);
+ } else if (nssUTF8_Equal(attrib, "askpw", &nssrv)) {
+ } else if (nssUTF8_Equal(attrib, "timeout", &nssrv)) {
+ }
+ }
+ if (*remainder == '\0') break;
+ current = remainder;
+ }
+ return nssrv;
+}
+
+/* softoken seems to use "0x0000001", but no standard yet... perhaps this
+ * should store the number as an ID, in case the input isn't 1,2,3,...?
+ */
+static PRIntn
+get_slot_number(NSSUTF8* snString)
+{
+ /* XXX super big hack */
+ return atoi(&snString[strlen(snString)-1]);
+}
+
+static PRStatus
+parse_module_slot_parameters
+(
+ NSSModule *mod,
+ NSSUTF8 *slotParams
+)
+{
+ PRStatus nssrv = PR_SUCCESS;
+ NSSUTF8 *current, *remainder;
+ NSSUTF8 *attrib, *value;
+ NSSArena *tmparena;
+ PRIntn slotNum;
+ tmparena = nssArena_Create();
+ if (!tmparena) {
+ return PR_FAILURE;
+ }
+ current = slotParams;
+ while (nssrv == PR_SUCCESS) {
+ nssrv = nssCryptokiArgs_ParseNextPair(current,
+ &attrib, &value,
+ &remainder, tmparena);
+ if (nssrv != PR_SUCCESS) break;
+ if (value) {
+ slotNum = get_slot_number(attrib);
+ if (slotNum < 0 || slotNum > mod->numSlots) {
+ return PR_FAILURE;
+ }
+ nssrv = parse_slot_parameters(mod->slots[slotNum],
+ value, tmparena);
+ if (nssrv != PR_SUCCESS) break;
+ }
+ if (*remainder == '\0') break;
+ current = remainder;
+ }
+ return nssrv;
+}
+
+static PRStatus
+parse_nss_flags
+(
+ NSSModule *mod,
+ NSSUTF8 *nssFlags
+)
+{
+ PRStatus nssrv = PR_SUCCESS;
+ PRBool done = PR_FALSE;
+ NSSUTF8 *mark, *last;
+ last = mark = nssFlags;
+ while (PR_TRUE) {
+ while (*mark && *mark != ',') ++mark;
+ if (!*mark) done = PR_TRUE;
+ *mark = '\0';
+ if (nssUTF8_Equal(last, "internal", &nssrv)) {
+ mod->base.flags |= NSSMODULE_FLAGS_INTERNAL;
+ } else if (nssUTF8_Equal(last, "moduleDB", &nssrv)) {
+ mod->base.flags |= NSSMODULE_FLAGS_MODULE_DB;
+ } else if (nssUTF8_Equal(last, "moduleDBOnly", &nssrv)) {
+ mod->base.flags |= NSSMODULE_FLAGS_MODULE_DB_ONLY;
+ } else if (nssUTF8_Equal(last, "critical", &nssrv)) {
+ mod->base.flags |= NSSMODULE_FLAGS_CRITICAL;
+ } else {
+ return PR_FAILURE;
+ }
+ if (done) break;
+ last = ++mark;
+ }
+ return nssrv;
+}
+
+static PRStatus
+parse_nss_parameters
+(
+ NSSModule *mod,
+ NSSUTF8 *nssParams,
+ NSSArena *tmparena,
+ NSSUTF8 **slotParams
+)
+{
+ PRStatus nssrv = PR_SUCCESS;
+ NSSUTF8 *current, *remainder;
+ NSSUTF8 *attrib, *value;
+ current = nssParams;
+ while (nssrv == PR_SUCCESS) {
+ nssrv = nssCryptokiArgs_ParseNextPair(current,
+ &attrib, &value,
+ &remainder, tmparena);
+ if (nssrv != PR_SUCCESS) break;
+ if (value) {
+ if (nssUTF8_Equal(attrib, "flags", &nssrv) ||
+ nssUTF8_Equal(attrib, "Flags", &nssrv)) {
+ nssrv = parse_nss_flags(mod, value);
+ } else if (nssUTF8_Equal(attrib, "trustOrder", &nssrv)) {
+ mod->order.trust = atoi(value);
+ } else if (nssUTF8_Equal(attrib, "cipherOrder", &nssrv)) {
+ mod->order.cipher = atoi(value);
+ } else if (nssUTF8_Equal(attrib, "ciphers", &nssrv)) {
+ } else if (nssUTF8_Equal(attrib, "slotParams", &nssrv)) {
+ /* slotParams doesn't get an arena, it is handled separately */
+ *slotParams = nssUTF8_Duplicate(value, NULL);
+ }
+ }
+ if (*remainder == '\0') break;
+ current = remainder;
+ }
+ return nssrv;
+}
+
+static PRStatus
+parse_module_parameters
+(
+ NSSModule *mod,
+ NSSUTF8 *moduleParams,
+ NSSUTF8 **slotParams
+)
+{
+ PRStatus nssrv = PR_SUCCESS;
+ NSSUTF8 *current, *remainder;
+ NSSUTF8 *attrib, *value;
+ NSSArena *arena = mod->base.arena;
+ NSSArena *tmparena;
+ current = moduleParams;
+ tmparena = nssArena_Create();
+ if (!tmparena) {
+ return PR_FAILURE;
+ }
+ while (nssrv == PR_SUCCESS) {
+ nssrv = nssCryptokiArgs_ParseNextPair(current,
+ &attrib, &value,
+ &remainder, tmparena);
+ if (nssrv != PR_SUCCESS) break;
+ if (value) {
+ if (nssUTF8_Equal(attrib, "name", &nssrv)) {
+ mod->base.name = nssUTF8_Duplicate(value, arena);
+ } else if (nssUTF8_Equal(attrib, "library", &nssrv)) {
+ mod->libraryName = nssUTF8_Duplicate(value, arena);
+ } else if (nssUTF8_Equal(attrib, "parameters", &nssrv)) {
+ mod->libraryParams = nssUTF8_Duplicate(value, arena);
+ } else if (nssUTF8_Equal(attrib, "NSS", &nssrv)) {
+ parse_nss_parameters(mod, value, tmparena, slotParams);
+ }
+ }
+ if (*remainder == '\0') break;
+ current = remainder;
+ }
+ nssArena_Destroy(tmparena);
return nssrv;
}
+static NSSUTF8 **
+get_module_specs
+(
+ NSSModule *mod
+)
+{
+ SECMODModuleDBFunc func = (SECMODModuleDBFunc)mod->moduleDBFunc;
+ if (func) {
+ return (*func)(SECMOD_MODULE_DB_FUNCTION_FIND,
+ mod->libraryParams,
+ NULL);
+ }
+ return NULL;
+}
+
+/* XXX continue working on */
+NSS_IMPLEMENT NSSModule *
+nssModule_CreateFromSpec
+(
+ NSSUTF8 *moduleSpec,
+ NSSModule *parent,
+ PRBool loadSubModules
+)
+{
+ PRStatus nssrv;
+ NSSModule *thisModule;
+ NSSArena *arena;
+ NSSUTF8 *slotParams = NULL;
+ arena = nssArena_Create();
+ if (!arena) {
+ return NULL;
+ }
+ thisModule = nss_ZNEW(arena, NSSModule);
+ if (!thisModule) {
+ goto loser;
+ }
+ thisModule->base.lock = PZ_NewLock(nssILockOther);
+ if (!thisModule->base.lock) {
+ goto loser;
+ }
+ PR_AtomicIncrement(&thisModule->base.refCount);
+ thisModule->base.arena = arena;
+ thisModule->base.lock = PZ_NewLock(nssNSSILockOther);
+ if (!thisModule->base.lock) {
+ goto loser;
+ }
+ nssrv = parse_module_parameters(thisModule, moduleSpec, &slotParams);
+ if (nssrv != PR_SUCCESS) {
+ goto loser;
+ }
+ nssrv = nssModule_Load(thisModule);
+ if (nssrv != PR_SUCCESS) {
+ goto loser;
+ }
+ if (slotParams) {
+ nssrv = parse_module_slot_parameters(thisModule, slotParams);
+ nss_ZFreeIf(slotParams);
+ if (nssrv != PR_SUCCESS) {
+ goto loser;
+ }
+ }
+ if (loadSubModules && NSSMODULE_IS_MODULE_DB(thisModule)) {
+ NSSUTF8 **moduleSpecs;
+ NSSUTF8 **index;
+ /* get the array of sub modules one level below this module */
+ moduleSpecs = get_module_specs(thisModule);
+ /* iterate over the array */
+ for (index = moduleSpecs; index && *index; index++) {
+ NSSModule *child;
+ /* load the child recursively */
+ child = nssModule_CreateFromSpec(*index, thisModule, PR_TRUE);
+ if (!child) {
+ /* when children fail, does the parent? */
+ nssrv = PR_FAILURE;
+ break;
+ }
+ if (NSSMODULE_IS_CRITICAL(child) && !child->isLoaded) {
+ nssrv = PR_FAILURE;
+ nssModule_Destroy(child);
+ break;
+ }
+ nssModule_Destroy(child);
+ /*nss_ZFreeIf(*index);*/
+ }
+ /*nss_ZFreeIf(moduleSpecs);*/
+ }
+ /* The global list inherits the reference */
+ nssrv = nssGlobalModuleList_Add(thisModule);
+ if (nssrv != PR_SUCCESS) {
+ goto loser;
+ }
+ return thisModule;
+loser:
+ if (thisModule->base.lock) {
+ PZ_DestroyLock(thisModule->base.lock);
+ }
+ nssArena_Destroy(arena);
+ return (NSSModule *)NULL;
+}
+
+NSS_IMPLEMENT PRStatus
+nssModule_Destroy
+(
+ NSSModule *mod
+)
+{
+ PRUint32 i, numSlots;
+ PR_AtomicDecrement(&mod->base.refCount);
+ if (mod->base.refCount == 0) {
+ if (mod->numSlots == 0) {
+ (void)nssModule_Unload(mod);
+ return nssArena_Destroy(mod->base.arena);
+ } else {
+ numSlots = mod->numSlots;
+ for (i=0; i<numSlots; i++) {
+ nssSlot_Destroy(mod->slots[i]);
+ }
+ }
+ }
+ return PR_SUCCESS;
+}
+
+NSS_IMPLEMENT PRStatus
+nssModule_DestroyFromSlot
+(
+ NSSModule *mod,
+ NSSSlot *slot
+)
+{
+ PRUint32 i, numSlots = 0;
+ PR_ASSERT(mod->base.refCount == 0);
+ for (i=0; i<mod->numSlots; i++) {
+ if (mod->slots[i] == slot) {
+ mod->slots[i] = NULL;
+ } else if (mod->slots[i]) {
+ numSlots++;
+ }
+ }
+ if (numSlots == 0) {
+ (void)nssModule_Unload(mod);
+ return nssArena_Destroy(mod->base.arena);
+ }
+ return PR_SUCCESS;
+}
+
+NSS_IMPLEMENT NSSModule *
+nssModule_AddRef
+(
+ NSSModule *mod
+)
+{
+ PR_AtomicIncrement(&mod->base.refCount);
+ return mod;
+}
+
+NSS_IMPLEMENT NSSUTF8 *
+nssModule_GetName
+(
+ NSSModule *mod
+)
+{
+ return mod->base.name;
+}
+
+NSS_IMPLEMENT PRBool
+nssModule_IsThreadSafe
+(
+ NSSModule *module
+)
+{
+ return NSSMODULE_IS_THREADSAFE(module);
+}
+
+NSS_IMPLEMENT PRBool
+nssModule_IsInternal
+(
+ NSSModule *mod
+)
+{
+ return NSSMODULE_IS_INTERNAL(mod);
+}
+
+NSS_IMPLEMENT PRBool
+nssModule_IsModuleDBOnly
+(
+ NSSModule *mod
+)
+{
+ return NSSMODULE_IS_MODULE_DB_ONLY(mod);
+}
+
+NSS_IMPLEMENT void *
+nssModule_GetCryptokiEPV
+(
+ NSSModule *mod
+)
+{
+ return mod->epv;
+}
+
+NSS_IMPLEMENT NSSSlot **
+nssModule_GetSlots
+(
+ NSSModule *mod
+)
+{
+ PRUint32 i;
+ NSSSlot **rvSlots;
+ rvSlots = nss_ZNEWARRAY(NULL, NSSSlot *, mod->numSlots + 1);
+ if (rvSlots) {
+ for (i=0; i<mod->numSlots; i++) {
+ rvSlots[i] = nssSlot_AddRef(mod->slots[i]);
+ }
+ }
+ return rvSlots;
+}
+
NSS_IMPLEMENT NSSSlot *
nssModule_FindSlotByName
(
@@ -326,9 +846,13 @@ nssModule_FindSlotByName
{
PRUint32 i;
PRStatus nssrv;
+ NSSSlot *slot;
+ NSSUTF8 *name;
for (i=0; i<mod->numSlots; i++) {
- if (nssUTF8_Equal(mod->slots[i]->name, slotName, &nssrv)) {
- return nssSlot_AddRef(mod->slots[i]);
+ slot = mod->slots[i];
+ name = nssSlot_GetName(slot);
+ if (nssUTF8_Equal(name, slotName, &nssrv)) {
+ return nssSlot_AddRef(slot);
}
if (nssrv != PR_SUCCESS) {
break;
@@ -337,7 +861,7 @@ nssModule_FindSlotByName
return (NSSSlot *)NULL;
}
-NSS_EXTERN NSSToken *
+NSS_IMPLEMENT NSSToken *
nssModule_FindTokenByName
(
NSSModule *mod,
@@ -347,50 +871,30 @@ nssModule_FindTokenByName
PRUint32 i;
PRStatus nssrv;
NSSToken *tok;
+ NSSUTF8 *name;
for (i=0; i<mod->numSlots; i++) {
- tok = mod->slots[i]->token;
- if (nssUTF8_Equal(tok->name, tokenName, &nssrv)) {
- return nssToken_AddRef(tok);
- }
- if (nssrv != PR_SUCCESS) {
- break;
+ tok = nssSlot_GetToken(mod->slots[i]);
+ if (tok) {
+ name = nssToken_GetName(tok);
+ if (nssUTF8_Equal(name, tokenName, &nssrv)) {
+ return tok;
+ }
+ if (nssrv != PR_SUCCESS) {
+ break;
+ }
}
}
return (NSSToken *)NULL;
}
-NSS_IMPLEMENT PRStatus *
-nssModule_TraverseCertificates
+NSS_IMPLEMENT PRInt32
+nssModule_GetCertOrder
(
- NSSModule *mod,
- PRStatus (*callback)(NSSCertificate *c, void *arg),
- void *arg
+ NSSModule *module
)
{
- return NULL;
+ return 1; /* XXX */
}
-#ifdef DEBUG
-void
-nssModule_Debug(NSSModule *m)
-{
- PRUint32 i;
- printf("\n");
- printf("Module Name: %s\n", m->name);
- printf("Module Path: %s\n", m->libraryPath);
- printf("Number of Slots in Module: %d\n\n", m->numSlots);
- for (i=0; i<m->numSlots; i++) {
- printf("\tSlot #%d\n", i);
- if (m->slots[i]->name) {
- printf("\tSlot Name: %s\n", m->slots[i]->name);
- } else {
- printf("\tSlot Name: <NULL>\n");
- }
- if (m->slots[i]->token) {
- printf("\tToken Name: %s\n", m->slots[i]->token->name);
- } else {
- printf("\tToken: <NULL>\n");
- }
- }
-}
-#endif
+#endif /* PURE_STAN_BUILD */
+
diff --git a/security/nss/lib/dev/devobject.c b/security/nss/lib/dev/devobject.c
deleted file mode 100644
index 06150df50..000000000
--- a/security/nss/lib/dev/devobject.c
+++ /dev/null
@@ -1,1093 +0,0 @@
-/*
- * 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 */
-
-#ifndef DEV_H
-#include "dev.h"
-#endif /* DEV_H */
-
-#ifndef DEVM_H
-#include "devm.h"
-#endif /* DEVM_H */
-
-#ifndef NSSCKEPV_H
-#include "nssckepv.h"
-#endif /* NSSCKEPV_H */
-
-#ifndef CKHELPER_H
-#include "ckhelper.h"
-#endif /* CKHELPER_H */
-
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-
-/* XXX */
-#ifndef PKI_H
-#include "pki.h"
-#endif /* PKI_H */
-
-/* XXX */
-#ifndef NSSPKI_H
-#include "nsspki.h"
-#endif /* NSSPKI_H */
-
-#ifdef NSS_3_4_CODE
-#include "pkim.h" /* for cert decoding */
-#include "pk11func.h" /* for PK11_HasRootCerts */
-#endif
-
-/* The number of object handles to grab during each call to C_FindObjects */
-#define OBJECT_STACK_SIZE 16
-
-NSS_IMPLEMENT PRStatus
-nssToken_DeleteStoredObject
-(
- nssCryptokiInstance *instance
-)
-{
- CK_RV ckrv;
- PRStatus nssrv;
- PRBool createdSession = PR_FALSE;
- NSSToken *token = instance->token;
- nssSession *session = NULL;
- if (nssCKObject_IsAttributeTrue(instance->handle, CKA_TOKEN,
- token->defaultSession,
- token->slot, &nssrv)) {
- if (nssSession_IsReadWrite(token->defaultSession)) {
- session = token->defaultSession;
- } else {
- session = nssSlot_CreateSession(token->slot, NULL, PR_TRUE);
- createdSession = PR_TRUE;
- }
- }
- if (session == NULL) {
- return PR_FAILURE;
- }
- nssSession_EnterMonitor(session);
- ckrv = CKAPI(token)->C_DestroyObject(session->handle, instance->handle);
- nssSession_ExitMonitor(session);
- if (createdSession) {
- nssSession_Destroy(session);
- }
- if (ckrv != CKR_OK) {
- return PR_FAILURE;
- }
- return PR_SUCCESS;
-}
-
-static CK_OBJECT_HANDLE
-import_object
-(
- NSSToken *tok,
- nssSession *sessionOpt,
- CK_ATTRIBUTE_PTR objectTemplate,
- CK_ULONG otsize
-)
-{
- nssSession *session = NULL;
- PRBool createdSession = PR_FALSE;
- CK_OBJECT_HANDLE object;
- CK_RV ckrv;
- if (nssCKObject_IsTokenObjectTemplate(objectTemplate, otsize)) {
- if (sessionOpt) {
- if (!nssSession_IsReadWrite(sessionOpt)) {
- return CK_INVALID_HANDLE;
- } else {
- session = sessionOpt;
- }
- } else if (nssSession_IsReadWrite(tok->defaultSession)) {
- session = tok->defaultSession;
- } else {
- session = nssSlot_CreateSession(tok->slot, NULL, PR_TRUE);
- createdSession = PR_TRUE;
- }
- } else {
- session = (sessionOpt) ? sessionOpt : tok->defaultSession;
- }
- if (session == NULL) {
- return CK_INVALID_HANDLE;
- }
- nssSession_EnterMonitor(session);
- ckrv = CKAPI(tok->slot)->C_CreateObject(session->handle,
- objectTemplate, otsize,
- &object);
- nssSession_ExitMonitor(session);
- if (createdSession) {
- nssSession_Destroy(session);
- }
- if (ckrv != CKR_OK) {
- return CK_INVALID_HANDLE;
- }
- return object;
-}
-
-static CK_OBJECT_HANDLE
-find_object_by_template
-(
- NSSToken *tok,
- nssSession *sessionOpt,
- CK_ATTRIBUTE_PTR cktemplate,
- CK_ULONG ctsize
-)
-{
- CK_SESSION_HANDLE hSession;
- CK_OBJECT_HANDLE rvObject = CK_INVALID_HANDLE;
- CK_ULONG count = 0;
- CK_RV ckrv;
- nssSession *session;
- session = (sessionOpt) ? sessionOpt : tok->defaultSession;
- hSession = session->handle;
- nssSession_EnterMonitor(session);
- ckrv = CKAPI(tok)->C_FindObjectsInit(hSession, cktemplate, ctsize);
- if (ckrv != CKR_OK) {
- nssSession_ExitMonitor(session);
- return CK_INVALID_HANDLE;
- }
- ckrv = CKAPI(tok)->C_FindObjects(hSession, &rvObject, 1, &count);
- if (ckrv != CKR_OK) {
- nssSession_ExitMonitor(session);
- return CK_INVALID_HANDLE;
- }
- ckrv = CKAPI(tok)->C_FindObjectsFinal(hSession);
- nssSession_ExitMonitor(session);
- if (ckrv != CKR_OK) {
- return CK_INVALID_HANDLE;
- }
- return rvObject;
-}
-
-static PRStatus
-traverse_objects_by_template
-(
- NSSToken *tok,
- nssSession *sessionOpt,
- CK_ATTRIBUTE_PTR obj_template,
- CK_ULONG otsize,
- PRStatus (*callback)(NSSToken *t, nssSession *session,
- CK_OBJECT_HANDLE h, void *arg),
- void *arg
-)
-{
- NSSSlot *slot;
- PRStatus cbrv;
- PRUint32 i;
- CK_RV ckrv;
- CK_ULONG count;
- CK_OBJECT_HANDLE *objectStack;
- CK_OBJECT_HANDLE startOS[OBJECT_STACK_SIZE];
- CK_SESSION_HANDLE hSession;
- NSSArena *objectArena = NULL;
- nssSession *session;
- nssList *objectList = NULL;
- int objectStackSize = OBJECT_STACK_SIZE;
- slot = tok->slot;
- objectStack = startOS;
- session = (sessionOpt) ? sessionOpt : tok->defaultSession;
- hSession = session->handle;
- nssSession_EnterMonitor(session);
- ckrv = CKAPI(slot)->C_FindObjectsInit(hSession, obj_template, otsize);
- if (ckrv != CKR_OK) {
- nssSession_ExitMonitor(session);
- goto loser;
- }
- while (PR_TRUE) {
- ckrv = CKAPI(slot)->C_FindObjects(hSession, objectStack,
- objectStackSize, &count);
- if (ckrv != CKR_OK) {
- nssSession_ExitMonitor(session);
- goto loser;
- }
- if (count == objectStackSize) {
- if (!objectList) {
- objectArena = NSSArena_Create();
- objectList = nssList_Create(objectArena, PR_FALSE);
- }
- nssList_Add(objectList, objectStack);
- objectStackSize = objectStackSize * 2;
- objectStack = nss_ZNEWARRAY(objectArena, CK_OBJECT_HANDLE,
- objectStackSize);
- if (objectStack == NULL) {
- count =0;
- break;
- /* return what we can */
- }
- } else {
- break;
- }
- }
- ckrv = CKAPI(slot)->C_FindObjectsFinal(hSession);
- nssSession_ExitMonitor(session);
- if (ckrv != CKR_OK) {
- goto loser;
- }
- if (objectList) {
- nssListIterator *objects;
- CK_OBJECT_HANDLE *localStack;
- objects = nssList_CreateIterator(objectList);
- objectStackSize = OBJECT_STACK_SIZE;
- for (localStack = (CK_OBJECT_HANDLE *)nssListIterator_Start(objects);
- localStack != NULL;
- localStack = (CK_OBJECT_HANDLE *)nssListIterator_Next(objects)) {
- for (i=0; i< objectStackSize; i++) {
- cbrv = (*callback)(tok, session, localStack[i], arg);
- }
- objectStackSize = objectStackSize * 2;
- }
- nssListIterator_Finish(objects);
- nssListIterator_Destroy(objects);
- }
- for (i=0; i<count; i++) {
- cbrv = (*callback)(tok, session, objectStack[i], arg);
- }
- if (objectArena)
- NSSArena_Destroy(objectArena);
- return PR_SUCCESS;
-loser:
- if (objectArena)
- NSSArena_Destroy(objectArena);
- return PR_FAILURE;
-}
-
-static nssCryptokiInstance *
-create_cryptoki_instance
-(
- NSSArena *arena,
- NSSToken *t,
- CK_OBJECT_HANDLE h,
- PRBool isTokenObject
-)
-{
- PRStatus nssrv;
- nssCryptokiInstance *instance;
- CK_ATTRIBUTE cert_template = { CKA_LABEL, NULL, 0 };
- nssrv = nssCKObject_GetAttributes(h, &cert_template, 1,
- arena, t->defaultSession, t->slot);
- if (nssrv != PR_SUCCESS) {
- /* a failure here indicates a device error */
- return NULL;
- }
- instance = nss_ZNEW(arena, nssCryptokiInstance);
- if (!instance) {
- return NULL;
- }
- instance->handle = h;
- instance->token = t;
- instance->isTokenObject = isTokenObject;
- NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template, instance->label);
- return instance;
-}
-
-#ifdef NSS_3_4_CODE
-/* exposing this for the smart card cache code */
-NSS_IMPLEMENT nssCryptokiInstance *
-nssCryptokiInstance_Create
-(
- NSSArena *arena,
- NSSToken *t,
- CK_OBJECT_HANDLE h,
- PRBool isTokenObject
-)
-{
- return create_cryptoki_instance(arena, t, h, isTokenObject);
-}
-#endif
-
-static NSSCertificateType
-nss_cert_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib)
-{
- CK_CERTIFICATE_TYPE ckCertType;
- if (!attrib->pValue) {
- /* default to PKIX */
- return NSSCertificateType_PKIX;
- }
- ckCertType = *((CK_ULONG *)attrib->pValue);
- switch (ckCertType) {
- case CKC_X_509:
- return NSSCertificateType_PKIX;
- default:
- break;
- }
- return NSSCertificateType_Unknown;
-}
-
-/* Create a certificate from an object handle. */
-static NSSCertificate *
-get_token_cert
-(
- NSSToken *token,
- nssSession *sessionOpt,
- CK_OBJECT_HANDLE handle
-)
-{
- NSSCertificate *rvCert;
- NSSArena *arena;
- nssSession *session;
- PRStatus nssrv;
- CK_ULONG template_size;
- CK_ATTRIBUTE cert_template[] = {
- { CKA_CERTIFICATE_TYPE, NULL, 0 },
- { CKA_ID, NULL, 0 },
- { CKA_VALUE, NULL, 0 },
- { CKA_ISSUER, NULL, 0 },
- { CKA_SERIAL_NUMBER, NULL, 0 },
- { CKA_SUBJECT, NULL, 0 },
- { CKA_NETSCAPE_EMAIL, NULL, 0 }
- };
- template_size = sizeof(cert_template) / sizeof(cert_template[0]);
- session = (sessionOpt) ? sessionOpt : token->defaultSession;
- arena = nssArena_Create();
- if (!arena) {
- return NULL;
- }
- rvCert = nss_ZNEW(arena, NSSCertificate);
- if (!rvCert) {
- NSSArena_Destroy(arena);
- return NULL;
- }
- nssrv = nssPKIObject_Initialize(&rvCert->object, arena,
- token->trustDomain, NULL);
- if (nssrv != PR_SUCCESS) {
- goto loser;
- }
- nssrv = nssCKObject_GetAttributes(handle,
- cert_template, template_size,
- arena, session, token->slot);
- if (nssrv != PR_SUCCESS) {
- goto loser;
- }
- rvCert->type = nss_cert_type_from_ck_attrib(&cert_template[0]);
- NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[1], &rvCert->id);
- NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[2], &rvCert->encoding);
- NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[3], &rvCert->issuer);
- NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[4], &rvCert->serial);
- NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[5], &rvCert->subject);
- NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[6], rvCert->email);
- /* XXX this would be better accomplished by dividing attributes to
- * retrieve into "required" and "optional"
- */
- if (rvCert->encoding.size == 0 ||
- rvCert->issuer.size == 0 ||
- rvCert->serial.size == 0 ||
- rvCert->subject.size == 0)
- {
- /* received a bum object from the token */
- goto loser;
- }
-#ifdef NSS_3_4_CODE
- /* nss 3.4 database doesn't associate email address with cert */
- if (!rvCert->email) {
- nssDecodedCert *dc;
- NSSASCII7 *email;
- dc = nssCertificate_GetDecoding(rvCert);
- if (dc) {
- email = dc->getEmailAddress(dc);
- if (email)
- rvCert->email = nssUTF8_Duplicate(email, arena);
- } else {
- goto loser;
- }
- }
- /* nss 3.4 must deal with tokens that do not follow the PKCS#11
- * standard and return decoded serial numbers. The easiest way to
- * work around this is just to grab the serial # from the full encoding
- */
- if (PR_TRUE) {
- nssDecodedCert *dc;
- dc = nssCertificate_GetDecoding(rvCert);
- if (dc) {
- PRStatus sn_stat;
- sn_stat = dc->getDERSerialNumber(dc, &rvCert->serial, arena);
- if (sn_stat != PR_SUCCESS) {
- goto loser;
- }
- } else {
- goto loser;
- }
- }
-#endif
- return rvCert;
-loser:
- nssPKIObject_Destroy(&rvCert->object);
- return (NSSCertificate *)NULL;
-}
-
-NSS_IMPLEMENT PRStatus
-nssToken_ImportCertificate
-(
- NSSToken *tok,
- nssSession *sessionOpt,
- NSSCertificate *cert,
- NSSUTF8 *nickname,
- PRBool asTokenObject
-)
-{
- nssCryptokiInstance *instance;
- CK_CERTIFICATE_TYPE cert_type = CKC_X_509;
- CK_OBJECT_HANDLE handle;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE cert_tmpl[9];
- CK_ULONG ctsize;
- NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize);
- 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_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
- NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CERTIFICATE_TYPE, cert_type);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, &cert->id);
- NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, &cert->encoding);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, &cert->issuer);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, &cert->subject);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, &cert->serial);
- NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize);
- /* Import the certificate onto the token */
- handle = import_object(tok, sessionOpt, cert_tmpl, ctsize);
- if (handle == CK_INVALID_HANDLE) {
- return PR_FAILURE;
- }
- instance = create_cryptoki_instance(cert->object.arena,
- tok, handle, asTokenObject);
- if (!instance) {
- /* XXX destroy object */
- return PR_FAILURE;
- }
- nssList_Add(cert->object.instanceList, instance);
- /* XXX Fix this! */
- nssListIterator_Destroy(cert->object.instances);
- cert->object.instances = nssList_CreateIterator(cert->object.instanceList);
- return PR_SUCCESS;
-}
-
-static PRBool
-compare_cert_by_encoding(void *a, void *b)
-{
- NSSCertificate *c1 = (NSSCertificate *)a;
- NSSCertificate *c2 = (NSSCertificate *)b;
- return (nssItem_Equal(&c1->encoding, &c2->encoding, NULL));
-}
-
-static PRStatus
-retrieve_cert(NSSToken *t, nssSession *session, CK_OBJECT_HANDLE h, void *arg)
-{
- PRStatus nssrv;
- PRBool found, inCache;
- nssTokenCertSearch *search = (nssTokenCertSearch *)arg;
- NSSCertificate *cert = NULL;
- nssListIterator *instances;
- nssCryptokiInstance *ci;
- CK_ATTRIBUTE derValue = { CKA_VALUE, NULL, 0 };
- inCache = PR_FALSE;
- if (search->cached) {
- NSSCertificate csi; /* a fake cert for indexing */
- nssrv = nssCKObject_GetAttributes(h, &derValue, 1,
- NULL, session, t->slot);
- NSS_CK_ATTRIBUTE_TO_ITEM(&derValue, &csi.encoding);
- cert = (NSSCertificate *)nssList_Get(search->cached, &csi);
- nss_ZFreeIf(csi.encoding.data);
- }
- found = PR_FALSE;
- if (cert) {
- inCache = PR_TRUE;
- nssCertificate_AddRef(cert);
- instances = cert->object.instances;
- for (ci = (nssCryptokiInstance *)nssListIterator_Start(instances);
- ci != (nssCryptokiInstance *)NULL;
- ci = (nssCryptokiInstance *)nssListIterator_Next(instances))
- {
- /* The builtins token will not return the same handle for objects
- * during the lifetime of the token. Thus, assuming the found
- * object is the same as the cached object if there is already an
- * instance for the token.
- */
- if (ci->token == t) {
- found = PR_TRUE;
- break;
- }
- }
- nssListIterator_Finish(instances);
- } else {
- cert = get_token_cert(t, session, h);
- if (!cert) return PR_FAILURE;
- }
- if (!found) {
- PRBool isTokenObject;
- /* XXX this is incorrect if the search is over both types */
- isTokenObject = (search->searchType == nssTokenSearchType_TokenOnly) ?
- PR_TRUE : PR_FALSE;
- ci = create_cryptoki_instance(cert->object.arena, t, h, isTokenObject);
- if (!ci) {
- NSSCertificate_Destroy(cert);
- return PR_FAILURE;
- }
- nssList_Add(cert->object.instanceList, ci);
- /* XXX Fix this! */
- nssListIterator_Destroy(cert->object.instances);
- cert->object.instances = nssList_CreateIterator(cert->object.instanceList);
- }
- if (!inCache) {
- nssrv = (*search->callback)(cert, search->cbarg);
- } else {
- nssrv = PR_SUCCESS; /* cached entries already handled */
- }
- NSSCertificate_Destroy(cert);
- return nssrv;
-}
-
-/* traverse all certificates - this should only happen if the token
- * has been marked as "traversable"
- */
-NSS_IMPLEMENT PRStatus
-nssToken_TraverseCertificates
-(
- NSSToken *token,
- nssSession *sessionOpt,
- nssTokenCertSearch *search
-)
-{
- PRStatus nssrv;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE cert_template[2];
- CK_ULONG ctsize;
- NSS_CK_TEMPLATE_START(cert_template, attr, ctsize);
- /* Set the search to token/session only if provided */
- if (search->searchType == nssTokenSearchType_SessionOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
- } else if (search->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_cert);
- NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize);
- if (search->cached) {
- nssList_SetCompareFunction(search->cached, compare_cert_by_encoding);
- }
- nssrv = traverse_objects_by_template(token, sessionOpt,
- cert_template, ctsize,
- retrieve_cert, search);
- return nssrv;
-}
-
-NSS_IMPLEMENT PRStatus
-nssToken_TraverseCertificatesBySubject
-(
- NSSToken *token,
- nssSession *sessionOpt,
- NSSDER *subject,
- nssTokenCertSearch *search
-)
-{
- PRStatus nssrv;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE subj_template[3];
- CK_ULONG stsize;
- NSS_CK_TEMPLATE_START(subj_template, attr, stsize);
- /* Set the search to token/session only if provided */
- if (search->searchType == nssTokenSearchType_SessionOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
- } else if (search->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_cert);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject);
- NSS_CK_TEMPLATE_FINISH(subj_template, attr, stsize);
- if (search->cached) {
- nssList_SetCompareFunction(search->cached, compare_cert_by_encoding);
- }
- /* now traverse the token certs matching this template */
- nssrv = traverse_objects_by_template(token, sessionOpt,
- subj_template, stsize,
- retrieve_cert, search);
- return nssrv;
-}
-
-NSS_IMPLEMENT PRStatus
-nssToken_TraverseCertificatesByNickname
-(
- NSSToken *token,
- nssSession *sessionOpt,
- NSSUTF8 *name,
- nssTokenCertSearch *search
-)
-{
- PRStatus nssrv;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE nick_template[3];
- CK_ULONG ntsize;
- NSS_CK_TEMPLATE_START(nick_template, attr, ntsize);
- NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, name);
- /* Set the search to token/session only if provided */
- if (search->searchType == nssTokenSearchType_SessionOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
- } else if (search->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_cert);
- NSS_CK_TEMPLATE_FINISH(nick_template, attr, ntsize);
- if (search->cached) {
- nssList_SetCompareFunction(search->cached, compare_cert_by_encoding);
- }
- /* now traverse the token certs matching this template */
- nssrv = traverse_objects_by_template(token, sessionOpt,
- nick_template, ntsize,
- retrieve_cert, search);
- if (nssrv != PR_SUCCESS) {
- return nssrv;
- }
- /* This is to workaround the fact that PKCS#11 doesn't specify
- * whether the '\0' should be included. XXX Is that still true?
- * im - this is not needed by the current softoken. However, I'm
- * leaving it in until I have surveyed more tokens to see if it needed.
- * well, its needed by the builtin token...
- */
- nick_template[0].ulValueLen++;
- nssrv = traverse_objects_by_template(token, sessionOpt,
- nick_template, ntsize,
- retrieve_cert, search);
- return nssrv;
-}
-
-NSS_IMPLEMENT PRStatus
-nssToken_TraverseCertificatesByEmail
-(
- NSSToken *token,
- nssSession *sessionOpt,
- NSSASCII7 *email,
- nssTokenCertSearch *search
-)
-{
- PRStatus nssrv;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE email_template[3];
- CK_ULONG etsize;
- NSS_CK_TEMPLATE_START(email_template, attr, etsize);
- NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NETSCAPE_EMAIL, email);
- /* Set the search to token/session only if provided */
- if (search->searchType == nssTokenSearchType_SessionOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
- } else if (search->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_cert);
- NSS_CK_TEMPLATE_FINISH(email_template, attr, etsize);
- if (search->cached) {
- nssList_SetCompareFunction(search->cached, compare_cert_by_encoding);
- }
- /* now traverse the token certs matching this template */
- nssrv = traverse_objects_by_template(token, sessionOpt,
- email_template, etsize,
- retrieve_cert, search);
- if (nssrv != PR_SUCCESS) {
- return nssrv;
- }
-#if 0
- /* This is to workaround the fact that PKCS#11 doesn't specify
- * whether the '\0' should be included. XXX Is that still true?
- */
- email_tmpl[0].ulValueLen--;
- nssrv = traverse_objects_by_template(token, sessionOpt,
- email_tmpl, etsize,
- retrieve_cert, search);
-#endif
- return nssrv;
-}
-
-/* XXX these next two need to create instances as needed */
-
-NSS_IMPLEMENT NSSCertificate *
-nssToken_FindCertificateByIssuerAndSerialNumber
-(
- NSSToken *token,
- nssSession *sessionOpt,
- NSSDER *issuer,
- NSSDER *serial,
- nssTokenSearchType searchType
-)
-{
- NSSCertificate *rvCert = NULL;
- nssSession *session;
- PRStatus nssrv;
- CK_OBJECT_HANDLE object;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE cert_template[4];
- 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);
- }
- /* Set the unique id */
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, issuer);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, serial);
- NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize);
- /* get the object handle */
- object = find_object_by_template(token, sessionOpt, cert_template, ctsize);
- if (object == CK_INVALID_HANDLE) {
- return NULL;
- }
- session = (sessionOpt) ? sessionOpt : token->defaultSession;
- rvCert = get_token_cert(token, sessionOpt, object);
- if (rvCert) {
- PRBool isTokenObject;
- nssCryptokiInstance *instance;
- isTokenObject = nssCKObject_IsAttributeTrue(object, CKA_TOKEN,
- session, token->slot,
- &nssrv);
- instance = create_cryptoki_instance(rvCert->object.arena,
- token, object, isTokenObject);
- if (!instance) {
- NSSCertificate_Destroy(rvCert);
- return NULL;
- }
- nssList_Add(rvCert->object.instanceList, instance);
- /* XXX Fix this! */
- nssListIterator_Destroy(rvCert->object.instances);
- rvCert->object.instances = nssList_CreateIterator(rvCert->object.instanceList);
- }
- return rvCert;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-nssToken_FindCertificateByEncodedCertificate
-(
- NSSToken *token,
- nssSession *sessionOpt,
- NSSBER *encodedCertificate,
- nssTokenSearchType searchType
-)
-{
- NSSCertificate *rvCert = NULL;
- nssSession *session;
- PRStatus nssrv;
- CK_OBJECT_HANDLE object;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE cert_template[3];
- 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_CLASS, &g_ck_class_cert);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encodedCertificate);
- NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize);
- /* get the object handle */
- object = find_object_by_template(token, sessionOpt, cert_template, ctsize);
- if (object == CK_INVALID_HANDLE) {
- return NULL;
- }
- session = (sessionOpt) ? sessionOpt : token->defaultSession;
- rvCert = get_token_cert(token, sessionOpt, object);
- if (rvCert) {
- PRBool isTokenObject;
- nssCryptokiInstance *instance;
- isTokenObject = nssCKObject_IsAttributeTrue(object, CKA_TOKEN,
- session, token->slot,
- &nssrv);
- instance = create_cryptoki_instance(rvCert->object.arena,
- token, object, isTokenObject);
- if (!instance) {
- NSSCertificate_Destroy(rvCert);
- return NULL;
- }
- nssList_Add(rvCert->object.instanceList, instance);
- /* XXX Fix this! */
- nssListIterator_Destroy(rvCert->object.instances);
- rvCert->object.instances = nssList_CreateIterator(rvCert->object.instanceList);
- }
- return rvCert;
-}
-
-static void
-sha1_hash(NSSItem *input, NSSItem *output)
-{
- NSSAlgorithmAndParameters *ap;
- NSSToken *token = STAN_GetDefaultCryptoToken();
- ap = NSSAlgorithmAndParameters_CreateSHA1Digest(NULL);
- (void)nssToken_Digest(token, NULL, ap, input, output, NULL);
-#ifdef NSS_3_4_CODE
- PK11_FreeSlot(token->pk11slot);
-#endif
- nss_ZFreeIf(ap);
-}
-
-static void
-md5_hash(NSSItem *input, NSSItem *output)
-{
- NSSAlgorithmAndParameters *ap;
- NSSToken *token = STAN_GetDefaultCryptoToken();
- ap = NSSAlgorithmAndParameters_CreateMD5Digest(NULL);
- (void)nssToken_Digest(token, NULL, ap, input, output, NULL);
-#ifdef NSS_3_4_CODE
- PK11_FreeSlot(token->pk11slot);
-#endif
- nss_ZFreeIf(ap);
-}
-
-NSS_IMPLEMENT PRStatus
-nssToken_ImportTrust
-(
- NSSToken *tok,
- nssSession *sessionOpt,
- NSSTrust *trust,
- PRBool asTokenObject
-)
-{
- CK_OBJECT_HANDLE handle;
- CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE trust_tmpl[10];
- CK_ULONG tsize;
- PRUint8 sha1[20]; /* this is cheating... */
- PRUint8 md5[16];
- NSSItem sha1_result, md5_result;
- NSSCertificate *c = trust->certificate;
- sha1_result.data = sha1; sha1_result.size = sizeof sha1;
- md5_result.data = md5; md5_result.size = sizeof md5;
- sha1_hash(&c->encoding, &sha1_result);
- md5_hash(&c->encoding, &md5_result);
- 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, &c->issuer);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, &c->serial);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_SHA1_HASH, &sha1_result);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_MD5_HASH, &md5_result);
- /* now set the trust values */
- NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_SERVER_AUTH, trust->serverAuth);
- NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CLIENT_AUTH, trust->clientAuth);
- NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, trust->codeSigning);
- NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_EMAIL_PROTECTION,
- trust->emailProtection);
- NSS_CK_TEMPLATE_FINISH(trust_tmpl, attr, tsize);
- /* import the trust object onto the token */
- handle = import_object(tok, NULL, trust_tmpl, tsize);
- if (handle != CK_INVALID_HANDLE) {
- nssCryptokiInstance *instance;
- instance = create_cryptoki_instance(trust->object.arena,
- tok, handle, asTokenObject);
- if (!instance) {
- return PR_FAILURE;
- }
- nssList_Add(trust->object.instanceList, instance);
- /* XXX Fix this! */
- nssListIterator_Destroy(trust->object.instances);
- trust->object.instances = nssList_CreateIterator(trust->object.instanceList);
- tok->hasNoTrust = PR_FALSE;
- return PR_SUCCESS;
- }
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT PRStatus
-nssToken_SetTrustCache
-(
- NSSToken *token
-)
-{
- CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE tobj_template[2];
- CK_ULONG tobj_size;
- CK_OBJECT_HANDLE obj;
- nssSession *session = token->defaultSession;
-
- NSS_CK_TEMPLATE_START(tobj_template, attr, tobj_size);
- NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, tobjc);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- NSS_CK_TEMPLATE_FINISH(tobj_template, attr, tobj_size);
-
- obj = find_object_by_template(token, session,
- tobj_template, tobj_size);
- token->hasNoTrust = PR_FALSE;
- if (obj == CK_INVALID_HANDLE) {
- token->hasNoTrust = PR_TRUE;
- }
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT PRStatus
-nssToken_SetCrlCache
-(
- NSSToken *token
-)
-{
- CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_CRL;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE tobj_template[2];
- CK_ULONG tobj_size;
- CK_OBJECT_HANDLE obj;
- nssSession *session = token->defaultSession;
-
- NSS_CK_TEMPLATE_START(tobj_template, attr, tobj_size);
- NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, tobjc);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- NSS_CK_TEMPLATE_FINISH(tobj_template, attr, tobj_size);
-
- obj = find_object_by_template(token, session,
- tobj_template, tobj_size);
- token->hasNoCrls = PR_TRUE;
- if (obj == CK_INVALID_HANDLE) {
- token->hasNoCrls = PR_TRUE;
- }
- return PR_SUCCESS;
-}
-
-static CK_OBJECT_HANDLE
-get_cert_trust_handle
-(
- NSSToken *token,
- nssSession *session,
- NSSCertificate *c,
- nssTokenSearchType searchType
-)
-{
- CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE tobj_template[5];
- CK_ULONG tobj_size;
- PRUint8 sha1[20]; /* this is cheating... */
- NSSItem sha1_result;
-
- if (token->hasNoTrust) {
- return CK_INVALID_HANDLE;
- }
- sha1_result.data = sha1; sha1_result.size = sizeof sha1;
- sha1_hash(&c->encoding, &sha1_result);
- 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_CERT_SHA1_HASH, &sha1_result);
-#ifdef NSS_3_4_CODE
- if (!PK11_HasRootCerts(token->pk11slot)) {
-#endif
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, &c->issuer);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER , &c->serial);
-#ifdef NSS_3_4_CODE
- }
- /*
- * we need to arrange for the built-in token to lose the bottom 2
- * attributes so that old built-in tokens will continue to work.
- */
-#endif
- NSS_CK_TEMPLATE_FINISH(tobj_template, attr, tobj_size);
- return find_object_by_template(token, session,
- tobj_template, tobj_size);
-}
-
-NSS_IMPLEMENT NSSTrust *
-nssToken_FindTrustForCert
-(
- NSSToken *token,
- nssSession *sessionOpt,
- NSSCertificate *c,
- nssTokenSearchType searchType
-)
-{
- PRStatus nssrv;
- NSSTrust *rvTrust;
- nssSession *session;
- NSSArena *arena;
- nssCryptokiInstance *instance;
- PRBool isTokenObject;
- CK_BBOOL isToken;
- CK_TRUST saTrust, caTrust, epTrust, csTrust;
- CK_OBJECT_HANDLE tobjID;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE trust_template[5];
- CK_ULONG trust_size;
- session = (sessionOpt) ? sessionOpt : token->defaultSession;
- tobjID = get_cert_trust_handle(token, session, c, searchType);
- if (tobjID == CK_INVALID_HANDLE) {
- return NULL;
- }
- /* Then 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);
- nssrv = nssCKObject_GetAttributes(tobjID,
- trust_template, trust_size,
- NULL, session, token->slot);
- if (nssrv != PR_SUCCESS) {
- return NULL;
- }
- arena = nssArena_Create();
- if (!arena) {
- return NULL;
- }
- rvTrust = nss_ZNEW(arena, NSSTrust);
- if (!rvTrust) {
- nssArena_Destroy(arena);
- return NULL;
- }
- nssrv = nssPKIObject_Initialize(&rvTrust->object, arena,
- token->trustDomain, NULL);
- if (nssrv != PR_SUCCESS) {
- goto loser;
- }
- isTokenObject = (isToken == CK_TRUE) ? PR_TRUE : PR_FALSE;
- instance = create_cryptoki_instance(arena, token, tobjID, isTokenObject);
- if (!instance) {
- goto loser;
- }
- rvTrust->serverAuth = saTrust;
- rvTrust->clientAuth = caTrust;
- rvTrust->emailProtection = epTrust;
- rvTrust->codeSigning = csTrust;
- return rvTrust;
-loser:
- nssPKIObject_Destroy(&rvTrust->object);
- return (NSSTrust *)NULL;
-}
-
diff --git a/security/nss/lib/dev/devslot.c b/security/nss/lib/dev/devslot.c
index a113b46f5..843a5bd4b 100644
--- a/security/nss/lib/dev/devslot.c
+++ b/security/nss/lib/dev/devslot.c
@@ -35,34 +35,62 @@
static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#endif /* DEBUG */
-#ifndef DEV_H
-#include "dev.h"
-#endif /* DEV_H */
+#ifndef NSSCKEPV_H
+#include "nssckepv.h"
+#endif /* NSSCKEPV_H */
#ifndef DEVM_H
#include "devm.h"
#endif /* DEVM_H */
-#ifdef NSS_3_4_CODE
-#include "pkcs11.h"
-#else
-#ifndef NSSCKEPV_H
-#include "nssckepv.h"
-#endif /* NSSCKEPV_H */
-#endif /* NSS_3_4_CODE */
-
#ifndef CKHELPER_H
#include "ckhelper.h"
#endif /* CKHELPER_H */
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
+/* measured in seconds */
+#define NSSSLOT_TOKEN_DELAY_TIME 10
+
+/* this should track global and per-transaction login information */
+
+#ifdef PURE_STAN_CODE
+typedef enum {
+ nssSlotAskPasswordTimes_FirstTime = 0,
+ nssSlotAskPasswordTimes_EveryTime = 1,
+ nssSlotAskPasswordTimes_Timeout = 2
+}
+nssSlotAskPasswordTimes;
+
+struct nssSlotAuthInfoStr
+{
+ PRTime lastLogin;
+ nssSlotAskPasswordTimes askTimes;
+ PRIntervalTime askPasswordTimeout;
+};
+
+struct NSSSlotStr
+{
+ struct nssDeviceBaseStr base;
+ NSSModule *module; /* Parent */
+ NSSToken *token; /* Peer */
+ CK_SLOT_ID slotID;
+ CK_FLAGS ckFlags; /* from CK_SLOT_INFO.flags */
+ struct nssSlotAuthInfoStr authInfo;
+ PRIntervalTime lastTokenPing;
+#ifdef NSS_3_4_CODE
+ PK11SlotInfo *pk11slot;
+#endif
+};
+#endif /* PURE_STAN_CODE */
+
+#define NSSSLOT_IS_FRIENDLY(slot) \
+ (slot->base.flags & NSSSLOT_FLAGS_FRIENDLY)
+
+/* measured as interval */
+static PRIntervalTime s_token_delay_time = 0;
/* The flags needed to open a read-only session. */
static const CK_FLAGS s_ck_readonly_flags = CKF_SERIAL_SESSION;
-#ifdef PURE_STAN
/* In pk11slot.c, this was a no-op. So it is here also. */
static CK_RV PR_CALLBACK
nss_ck_slot_notify
@@ -74,56 +102,41 @@ nss_ck_slot_notify
{
return CKR_OK;
}
-#endif
-/* maybe this should really inherit completely from the module... I dunno,
- * any uses of slots where independence is needed?
- */
+#ifdef PURE_STAN_BUILD
NSS_IMPLEMENT NSSSlot *
nssSlot_Create
(
- NSSArena *arenaOpt,
CK_SLOT_ID slotID,
NSSModule *parent
)
{
NSSArena *arena = NULL;
- nssArenaMark *mark = NULL;
NSSSlot *rvSlot;
NSSToken *token = NULL;
NSSUTF8 *slotName = NULL;
PRUint32 length;
- PRBool newArena;
- PRStatus nssrv;
CK_SLOT_INFO slotInfo;
CK_RV ckrv;
- if (arenaOpt) {
- arena = arenaOpt;
- mark = nssArena_Mark(arena);
- if (!mark) {
- return (NSSSlot *)NULL;
- }
- newArena = PR_FALSE;
- } else {
- arena = NSSArena_Create();
- if(!arena) {
- return (NSSSlot *)NULL;
- }
- newArena = PR_TRUE;
+ void *epv;
+ arena = NSSArena_Create();
+ if(!arena) {
+ return (NSSSlot *)NULL;
}
rvSlot = nss_ZNEW(arena, NSSSlot);
if (!rvSlot) {
goto loser;
}
/* Get slot information */
- ckrv = CKAPI(parent)->C_GetSlotInfo(slotID, &slotInfo);
+ epv = nssModule_GetCryptokiEPV(parent);
+ ckrv = CKAPI(epv)->C_GetSlotInfo(slotID, &slotInfo);
if (ckrv != CKR_OK) {
/* set an error here, eh? */
goto loser;
}
/* Grab the slot description from the PKCS#11 fixed-length buffer */
- length = nssPKCS11StringLength(slotInfo.slotDescription,
- sizeof(slotInfo.slotDescription));
+ length = nssPKCS11String_Length(slotInfo.slotDescription,
+ sizeof(slotInfo.slotDescription));
if (length > 0) {
slotName = nssUTF8_Create(arena, nssStringType_UTF8String,
(void *)slotInfo.slotDescription, length);
@@ -131,45 +144,31 @@ nssSlot_Create
goto loser;
}
}
- if (!arenaOpt) {
- /* Avoid confusion now - only set the slot's arena to a non-NULL value
- * if a new arena is created. Otherwise, depend on the caller (having
- * passed arenaOpt) to free the arena.
- */
- rvSlot->arena = arena;
+ rvSlot->base.arena = arena;
+ rvSlot->base.refCount = 1;
+ rvSlot->base.name = slotName;
+ rvSlot->base.lock = PZ_NewLock(nssNSSILockOther); /* XXX */
+ if (!rvSlot->base.lock) {
+ goto loser;
}
- rvSlot->refCount = 1;
- rvSlot->epv = parent->epv;
- rvSlot->module = parent;
- rvSlot->name = slotName;
+ rvSlot->module = parent; /* refs go from module to slots */
rvSlot->slotID = slotID;
rvSlot->ckFlags = slotInfo.flags;
/* Initialize the token if present. */
if (slotInfo.flags & CKF_TOKEN_PRESENT) {
- token = nssToken_Create(arena, slotID, rvSlot);
+ token = nssToken_Create(slotID, rvSlot);
if (!token) {
goto loser;
}
}
rvSlot->token = token;
- if (mark) {
- nssrv = nssArena_Unmark(arena, mark);
- if (nssrv != PR_SUCCESS) {
- goto loser;
- }
- }
return rvSlot;
loser:
- if (newArena) {
- nssArena_Destroy(arena);
- } else {
- if (mark) {
- nssArena_Release(arena, mark);
- }
- }
+ nssArena_Destroy(arena);
/* everything was created in the arena, nothing to see here, move along */
return (NSSSlot *)NULL;
}
+#endif /* PURE_STAN_BUILD */
NSS_IMPLEMENT PRStatus
nssSlot_Destroy
@@ -177,46 +176,316 @@ nssSlot_Destroy
NSSSlot *slot
)
{
- if (--slot->refCount == 0) {
-#ifndef NSS_3_4_CODE
- /* Not going to do this in 3.4, maybe never */
- nssToken_Destroy(slot->token);
+ if (slot) {
+ PR_AtomicDecrement(&slot->base.refCount);
+ if (slot->base.refCount == 0) {
+ PZ_DestroyLock(slot->base.lock);
+#ifdef PURE_STAN_BUILD
+ nssToken_Destroy(slot->token);
+ nssModule_DestroyFromSlot(slot->module, slot);
#endif
- if (slot->arena) {
- return NSSArena_Destroy(slot->arena);
- } else {
- nss_ZFreeIf(slot);
+ return nssArena_Destroy(slot->base.arena);
}
}
return PR_SUCCESS;
}
+NSS_IMPLEMENT void
+NSSSlot_Destroy
+(
+ NSSSlot *slot
+)
+{
+ (void)nssSlot_Destroy(slot);
+}
+
NSS_IMPLEMENT NSSSlot *
nssSlot_AddRef
(
NSSSlot *slot
)
{
- ++slot->refCount;
+ PR_AtomicIncrement(&slot->base.refCount);
return slot;
}
NSS_IMPLEMENT NSSUTF8 *
nssSlot_GetName
(
+ NSSSlot *slot
+)
+{
+ return slot->base.name;
+}
+
+NSS_IMPLEMENT NSSUTF8 *
+nssSlot_GetTokenName
+(
+ NSSSlot *slot
+)
+{
+ return nssToken_GetName(slot->token);
+}
+
+static PRBool
+within_token_delay_period(NSSSlot *slot)
+{
+ PRIntervalTime time, lastTime;
+ /* Set the delay time for checking the token presence */
+ if (s_token_delay_time == 0) {
+ s_token_delay_time = PR_SecondsToInterval(NSSSLOT_TOKEN_DELAY_TIME);
+ }
+ time = PR_IntervalNow();
+ lastTime = slot->lastTokenPing;
+ if ((time > lastTime) && ((time - lastTime) < s_token_delay_time)) {
+ return PR_TRUE;
+ }
+ slot->lastTokenPing = time;
+ return PR_FALSE;
+}
+
+NSS_IMPLEMENT PRBool
+nssSlot_IsTokenPresent
+(
+ NSSSlot *slot
+)
+{
+ CK_RV ckrv;
+ PRStatus nssrv;
+ /* XXX */
+ nssSession *session;
+ CK_SLOT_INFO slotInfo;
+ void *epv;
+ /* permanent slots are always present */
+ if (nssSlot_IsPermanent(slot)) {
+ return PR_TRUE;
+ }
+ /* avoid repeated calls to check token status within set interval */
+ if (within_token_delay_period(slot)) {
+ return (PRBool)((slot->ckFlags & CKF_TOKEN_PRESENT) != 0);
+ }
+ /* First obtain the slot info */
+#ifdef PURE_STAN_BUILD
+ epv = nssModule_GetCryptokiEPV(slot->module);
+#else
+ epv = slot->epv;
+#endif
+ if (!epv) {
+ return PR_FALSE;
+ }
+ ckrv = CKAPI(epv)->C_GetSlotInfo(slot->slotID, &slotInfo);
+ if (ckrv != CKR_OK) {
+ slot->token->base.name[0] = 0; /* XXX */
+ return PR_FALSE;
+ }
+ slot->ckFlags = slotInfo.flags;
+ /* check for the presence of the token */
+ if ((slot->ckFlags & CKF_TOKEN_PRESENT) == 0) {
+ if (!slot->token) {
+ /* token was ne'er present */
+ return PR_FALSE;
+ }
+ session = nssToken_GetDefaultSession(slot->token);
+ nssSession_EnterMonitor(session);
+ /* token is not present */
+ if (session->handle != CK_INVALID_SESSION) {
+ /* session is valid, close and invalidate it */
+ CKAPI(epv)->C_CloseSession(session->handle);
+ session->handle = CK_INVALID_SESSION;
+ }
+ nssSession_ExitMonitor(session);
+#ifdef NSS_3_4_CODE
+ if (slot->token->base.name[0] != 0) {
+ /* notify the high-level cache that the token is removed */
+ slot->token->base.name[0] = 0; /* XXX */
+ nssToken_NofifyCertsNotVisible(slot->token);
+ }
+#endif
+ slot->token->base.name[0] = 0; /* XXX */
+ /* clear the token cache */
+ nssToken_Remove(slot->token);
+ return PR_FALSE;
+#ifdef PURE_STAN_CODE
+ } else if (!slot->token) {
+ /* token was not present at boot time, is now */
+ slot->token = nssToken_Create(slot->slotID, slot);
+ return (slot->token != NULL);
+#endif
+ }
+ /* token is present, use the session info to determine if the card
+ * has been removed and reinserted.
+ */
+ session = nssToken_GetDefaultSession(slot->token);
+ nssSession_EnterMonitor(session);
+ if (session->handle != CK_INVALID_SESSION) {
+ CK_SESSION_INFO sessionInfo;
+ ckrv = CKAPI(epv)->C_GetSessionInfo(session->handle, &sessionInfo);
+ if (ckrv != CKR_OK) {
+ /* session is screwy, close and invalidate it */
+ CKAPI(epv)->C_CloseSession(session->handle);
+ session->handle = CK_INVALID_SESSION;
+ }
+ }
+ nssSession_ExitMonitor(session);
+ /* token not removed, finished */
+ if (session->handle != CK_INVALID_SESSION) {
+ return PR_TRUE;
+ } else {
+ /* token has been removed, need to refresh with new session */
+ nssrv = nssSlot_Refresh(slot);
+ if (nssrv != PR_SUCCESS) {
+ slot->token->base.name[0] = 0; /* XXX */
+ return PR_FALSE;
+ }
+ return PR_TRUE;
+ }
+}
+
+#ifdef PURE_STAN_BUILD
+NSS_IMPLEMENT NSSModule *
+nssSlot_GetModule
+(
+ NSSSlot *slot
+)
+{
+ return nssModule_AddRef(slot->module);
+}
+#endif /* PURE_STAN_BUILD */
+
+NSS_IMPLEMENT void *
+nssSlot_GetCryptokiEPV
+(
+ NSSSlot *slot
+)
+{
+#ifdef PURE_STAN_BUILD
+ return nssModule_GetCryptokiEPV(slot->module);
+#else
+ return slot->epv;
+#endif
+}
+
+NSS_IMPLEMENT NSSToken *
+nssSlot_GetToken
+(
+ NSSSlot *slot
+)
+{
+ if (nssSlot_IsTokenPresent(slot)) {
+ return nssToken_AddRef(slot->token);
+ }
+ return (NSSToken *)NULL;
+}
+
+#ifdef PURE_STAN_BUILD
+NSS_IMPLEMENT PRBool
+nssSlot_IsPermanent
+(
+ NSSSlot *slot
+)
+{
+ return (!(slot->ckFlags & CKF_REMOVABLE_DEVICE));
+}
+
+NSS_IMPLEMENT PRBool
+nssSlot_IsFriendly
+(
+ NSSSlot *slot
+)
+{
+ return PR_TRUE /* XXX NSSSLOT_IS_FRIENDLY(slot)*/;
+}
+
+NSS_IMPLEMENT PRBool
+nssSlot_IsHardware
+(
+ NSSSlot *slot
+)
+{
+ return (slot->ckFlags & CKF_HW_SLOT);
+}
+
+NSS_IMPLEMENT PRStatus
+nssSlot_Refresh
+(
+ NSSSlot *slot
+)
+{
+ /* XXX */
+#if 0
+ nssToken_Destroy(slot->token);
+ if (slotInfo.flags & CKF_TOKEN_PRESENT) {
+ slot->token = nssToken_Create(NULL, slotID, slot);
+ }
+#endif
+ return PR_SUCCESS;
+}
+
+static PRBool
+slot_needs_login
+(
NSSSlot *slot,
- NSSArena *arenaOpt
+ nssSession *session
)
{
- if (slot->name) {
- return nssUTF8_Duplicate(slot->name, arenaOpt);
+ PRBool needsLogin, logout;
+ struct nssSlotAuthInfoStr *authInfo = &slot->authInfo;
+ void *epv = nssModule_GetCryptokiEPV(slot->module);
+ if (!nssToken_IsLoginRequired(slot->token)) {
+ return PR_FALSE;
+ }
+ if (authInfo->askTimes == nssSlotAskPasswordTimes_EveryTime) {
+ logout = PR_TRUE;
+ } else if (authInfo->askTimes == nssSlotAskPasswordTimes_Timeout) {
+ PRIntervalTime currentTime = PR_IntervalNow();
+ if (authInfo->lastLogin - currentTime < authInfo->askPasswordTimeout) {
+ logout = PR_FALSE;
+ } else {
+ logout = PR_TRUE;
+ }
+ } else { /* nssSlotAskPasswordTimes_FirstTime */
+ logout = PR_FALSE;
+ }
+ if (logout) {
+ /* The login has expired, timeout */
+ nssSession_EnterMonitor(session);
+ CKAPI(epv)->C_Logout(session->handle);
+ nssSession_ExitMonitor(session);
+ needsLogin = PR_TRUE;
+ } else {
+ CK_RV ckrv;
+ CK_SESSION_INFO sessionInfo;
+ nssSession_EnterMonitor(session);
+ ckrv = CKAPI(epv)->C_GetSessionInfo(session->handle, &sessionInfo);
+ nssSession_ExitMonitor(session);
+ if (ckrv != CKR_OK) {
+ /* XXX error -- invalidate session */
+ return PR_FALSE;
+ }
+ switch (sessionInfo.state) {
+ case CKS_RW_PUBLIC_SESSION:
+ case CKS_RO_PUBLIC_SESSION:
+ default:
+ needsLogin = PR_TRUE;
+ break;
+ case CKS_RW_USER_FUNCTIONS:
+ case CKS_RW_SO_FUNCTIONS:
+ case CKS_RO_USER_FUNCTIONS:
+ needsLogin = PR_FALSE;
+ break;
+ }
}
- return (NSSUTF8 *)NULL;
+ return needsLogin;
}
static PRStatus
-nssslot_login(NSSSlot *slot, nssSession *session,
- CK_USER_TYPE userType, NSSCallback *pwcb)
+slot_login
+(
+ NSSSlot *slot,
+ nssSession *session,
+ CK_USER_TYPE userType,
+ NSSCallback *pwcb
+)
{
PRStatus nssrv;
PRUint32 attempts;
@@ -224,15 +493,19 @@ nssslot_login(NSSSlot *slot, nssSession *session,
NSSUTF8 *password = NULL;
CK_ULONG pwLen;
CK_RV ckrv;
+ void *epv;
if (!pwcb->getPW) {
/* set error INVALID_ARG */
return PR_FAILURE;
}
+ epv = nssModule_GetCryptokiEPV(slot->module);
keepTrying = PR_TRUE;
nssrv = PR_FAILURE;
attempts = 0;
while (keepTrying) {
- nssrv = pwcb->getPW(slot->name, &attempts, pwcb->arg, &password);
+ /* use the token name, since it is present */
+ NSSUTF8 *tokenName = nssToken_GetName(slot->token);
+ nssrv = pwcb->getPW(tokenName, attempts, pwcb->arg, &password);
if (nssrv != PR_SUCCESS) {
nss_SetError(NSS_ERROR_USER_CANCELED);
break;
@@ -242,8 +515,8 @@ nssslot_login(NSSSlot *slot, nssSession *session,
break;
}
nssSession_EnterMonitor(session);
- ckrv = CKAPI(slot)->C_Login(session->handle, userType,
- (CK_CHAR_PTR)password, pwLen);
+ ckrv = CKAPI(epv)->C_Login(session->handle, userType,
+ (CK_CHAR_PTR)password, pwLen);
nssSession_ExitMonitor(session);
switch (ckrv) {
case CKR_OK:
@@ -265,129 +538,130 @@ nssslot_login(NSSSlot *slot, nssSession *session,
password = NULL;
++attempts;
}
- nss_ZFreeIf(password);
return nssrv;
}
static PRStatus
-nssslot_init_password(NSSSlot *slot, nssSession *rwSession, NSSCallback *pwcb)
+init_slot_password
+(
+ NSSSlot *slot,
+ nssSession *rwSession,
+ NSSUTF8 *password
+)
{
- NSSUTF8 *userPW = NULL;
- NSSUTF8 *ssoPW = NULL;
- PRStatus nssrv;
+ PRStatus status;
+ NSSUTF8 *ssoPW = "";
CK_ULONG userPWLen, ssoPWLen;
CK_RV ckrv;
- if (!pwcb->getInitPW) {
- /* set error INVALID_ARG */
- return PR_FAILURE;
- }
+ void *epv = nssModule_GetCryptokiEPV(slot->module);
/* Get the SO and user passwords */
- nssrv = pwcb->getInitPW(slot->name, pwcb->arg, &ssoPW, &userPW);
- if (nssrv != PR_SUCCESS) goto loser;
- userPWLen = (CK_ULONG)nssUTF8_Length(userPW, &nssrv);
- if (nssrv != PR_SUCCESS) goto loser;
- ssoPWLen = (CK_ULONG)nssUTF8_Length(ssoPW, &nssrv);
- if (nssrv != PR_SUCCESS) goto loser;
+ userPWLen = (CK_ULONG)nssUTF8_Length(password, &status);
+ if (status != PR_SUCCESS) {
+ goto loser;
+ }
+ ssoPWLen = (CK_ULONG)nssUTF8_Length(ssoPW, &status);
+ if (status != PR_SUCCESS) {
+ goto loser;
+ }
/* First log in as SO */
- ckrv = CKAPI(slot)->C_Login(rwSession->handle, CKU_SO,
- (CK_CHAR_PTR)ssoPW, ssoPWLen);
+ ckrv = CKAPI(epv)->C_Login(rwSession->handle, CKU_SO,
+ (CK_CHAR_PTR)ssoPW, ssoPWLen);
if (ckrv != CKR_OK) {
/* set error ...SO_LOGIN_FAILED */
goto loser;
}
/* Now change the user PIN */
- ckrv = CKAPI(slot)->C_InitPIN(rwSession->handle,
- (CK_CHAR_PTR)userPW, userPWLen);
+ ckrv = CKAPI(epv)->C_InitPIN(rwSession->handle,
+ (CK_CHAR_PTR)password, userPWLen);
if (ckrv != CKR_OK) {
/* set error */
goto loser;
}
- nss_ZFreeIf(ssoPW);
- nss_ZFreeIf(userPW);
return PR_SUCCESS;
loser:
- nss_ZFreeIf(ssoPW);
- nss_ZFreeIf(userPW);
return PR_FAILURE;
}
static PRStatus
-nssslot_change_password(NSSSlot *slot, nssSession *rwSession, NSSCallback *pwcb)
+change_slot_password
+(
+ NSSSlot *slot,
+ nssSession *rwSession,
+ NSSUTF8 *oldPassword,
+ NSSUTF8 *newPassword
+)
{
- NSSUTF8 *userPW = NULL;
- NSSUTF8 *newPW = NULL;
- PRUint32 attempts;
- PRStatus nssrv;
- PRBool keepTrying = PR_TRUE;
+ PRStatus status;
CK_ULONG userPWLen, newPWLen;
CK_RV ckrv;
- if (!pwcb->getNewPW) {
- /* set error INVALID_ARG */
- return PR_FAILURE;
+ void *epv = nssModule_GetCryptokiEPV(slot->module);
+ userPWLen = (CK_ULONG)nssUTF8_Length(oldPassword, &status);
+ if (status != PR_SUCCESS) {
+ return status;
}
- attempts = 0;
- while (keepTrying) {
- nssrv = pwcb->getNewPW(slot->name, &attempts, pwcb->arg,
- &userPW, &newPW);
- if (nssrv != PR_SUCCESS) {
- nss_SetError(NSS_ERROR_USER_CANCELED);
- break;
- }
- userPWLen = (CK_ULONG)nssUTF8_Length(userPW, &nssrv);
- if (nssrv != PR_SUCCESS) return nssrv;
- newPWLen = (CK_ULONG)nssUTF8_Length(newPW, &nssrv);
- if (nssrv != PR_SUCCESS) return nssrv;
- nssSession_EnterMonitor(rwSession);
- ckrv = CKAPI(slot)->C_SetPIN(rwSession->handle,
- (CK_CHAR_PTR)userPW, userPWLen,
- (CK_CHAR_PTR)newPW, newPWLen);
- nssSession_ExitMonitor(rwSession);
- switch (ckrv) {
- case CKR_OK:
- slot->authInfo.lastLogin = PR_Now();
- nssrv = PR_SUCCESS;
- keepTrying = PR_FALSE;
- break;
- case CKR_PIN_INCORRECT:
- nss_SetError(NSS_ERROR_INVALID_PASSWORD);
- keepTrying = PR_TRUE; /* received bad pw, keep going */
- break;
- default:
- nssrv = PR_FAILURE;
- keepTrying = PR_FALSE;
- break;
- }
- nss_ZFreeIf(userPW);
- nss_ZFreeIf(newPW);
- userPW = NULL;
- newPW = NULL;
- ++attempts;
+ newPWLen = (CK_ULONG)nssUTF8_Length(newPassword, &status);
+ if (status != PR_SUCCESS) {
+ return status;
}
- nss_ZFreeIf(userPW);
- nss_ZFreeIf(newPW);
- return nssrv;
+ nssSession_EnterMonitor(rwSession);
+ ckrv = CKAPI(epv)->C_SetPIN(rwSession->handle,
+ (CK_CHAR_PTR)oldPassword, userPWLen,
+ (CK_CHAR_PTR)newPassword, newPWLen);
+ nssSession_ExitMonitor(rwSession);
+ switch (ckrv) {
+ case CKR_OK:
+ slot->authInfo.lastLogin = PR_Now();
+ status = PR_SUCCESS;
+ break;
+ case CKR_PIN_INCORRECT:
+ nss_SetError(NSS_ERROR_INVALID_PASSWORD);
+ status = PR_FAILURE;
+ break;
+ default:
+ status = PR_FAILURE;
+ break;
+ }
+ return status;
}
NSS_IMPLEMENT PRStatus
nssSlot_Login
(
NSSSlot *slot,
- PRBool asSO,
NSSCallback *pwcb
)
{
- PRBool needsLogin, needsInit;
- CK_USER_TYPE userType;
- userType = (asSO) ? CKU_SO : CKU_USER;
- needsInit = PR_FALSE; /* XXX */
- needsLogin = PR_TRUE; /* XXX */
- if (needsInit) {
- return nssSlot_SetPassword(slot, pwcb);
- } else if (needsLogin) {
- return nssslot_login(slot, slot->token->defaultSession,
- userType, pwcb);
- }
- return PR_SUCCESS; /* login not required */
+ PRStatus status;
+ CK_USER_TYPE userType = CKU_USER;
+ NSSToken *token = nssSlot_GetToken(slot);
+ nssSession *session;
+ if (!token) {
+ return PR_FAILURE;
+ }
+ if (!nssToken_IsLoginRequired(token)) {
+ nssToken_Destroy(token);
+ return PR_SUCCESS;
+ }
+ session = nssToken_GetDefaultSession(slot->token);
+ if (nssToken_NeedsPINInitialization(token)) {
+ NSSUTF8 *password = NULL;
+ if (!pwcb->getInitPW) {
+ nssToken_Destroy(token);
+ return PR_FAILURE; /* don't know how to get initial password */
+ }
+ status = (*pwcb->getInitPW)(slot->base.name, pwcb->arg, &password);
+ if (status == PR_SUCCESS) {
+ session = nssSlot_CreateSession(slot, NULL, PR_TRUE);
+ status = init_slot_password(slot, session, password);
+ nssSession_Destroy(session);
+ }
+ } else if (slot_needs_login(slot, session)) {
+ status = slot_login(slot, session, userType, pwcb);
+ } else {
+ status = PR_SUCCESS;
+ }
+ nssToken_Destroy(token);
+ return status;
}
NSS_IMPLEMENT PRStatus
@@ -397,12 +671,15 @@ nssSlot_Logout
nssSession *sessionOpt
)
{
- nssSession *session;
PRStatus nssrv = PR_SUCCESS;
+ nssSession *session;
CK_RV ckrv;
- session = (sessionOpt) ? sessionOpt : slot->token->defaultSession;
+ void *epv = nssModule_GetCryptokiEPV(slot->module);
+ session = sessionOpt ?
+ sessionOpt :
+ nssToken_GetDefaultSession(slot->token);
nssSession_EnterMonitor(session);
- ckrv = CKAPI(slot)->C_Logout(session->handle);
+ ckrv = CKAPI(epv)->C_Logout(session->handle);
nssSession_ExitMonitor(session);
if (ckrv != CKR_OK) {
/* translate the error */
@@ -411,6 +688,16 @@ nssSlot_Logout
return nssrv;
}
+NSS_IMPLEMENT PRBool
+nssSlot_IsLoggedIn
+(
+ NSSSlot *slot
+)
+{
+ nssSession *session = nssToken_GetDefaultSession(slot->token);
+ return !slot_needs_login(slot, session);
+}
+
NSS_IMPLEMENT void
nssSlot_SetPasswordDefaults
(
@@ -421,28 +708,36 @@ nssSlot_SetPasswordDefaults
slot->authInfo.askPasswordTimeout = askPasswordTimeout;
}
+
NSS_IMPLEMENT PRStatus
nssSlot_SetPassword
(
NSSSlot *slot,
- NSSCallback *pwcb
+ NSSUTF8 *oldPasswordOpt,
+ NSSUTF8 *newPassword
)
{
- PRStatus nssrv;
+ PRStatus status;
nssSession *rwSession;
- PRBool needsInit;
- needsInit = PR_FALSE; /* XXX */
+ NSSToken *token = nssSlot_GetToken(slot);
+ if (!token) {
+ return PR_FAILURE;
+ }
rwSession = nssSlot_CreateSession(slot, NULL, PR_TRUE);
- if (needsInit) {
- nssrv = nssslot_init_password(slot, rwSession, pwcb);
+ if (nssToken_NeedsPINInitialization(token)) {
+ status = init_slot_password(slot, rwSession, newPassword);
+ } else if (oldPasswordOpt) {
+ status = change_slot_password(slot, rwSession,
+ oldPasswordOpt, newPassword);
} else {
- nssrv = nssslot_change_password(slot, rwSession, pwcb);
+ /* old password must be given in order to change */
+ status = PR_FAILURE;
}
nssSession_Destroy(rwSession);
- return nssrv;
+ nssToken_Destroy(token);
+ return status;
}
-#ifdef PURE_STAN
NSS_IMPLEMENT nssSession *
nssSlot_CreateSession
(
@@ -453,18 +748,15 @@ nssSlot_CreateSession
{
CK_RV ckrv;
CK_FLAGS ckflags;
- CK_SESSION_HANDLE session;
+ CK_SESSION_HANDLE handle;
+ void *epv = nssModule_GetCryptokiEPV(slot->module);
nssSession *rvSession;
ckflags = s_ck_readonly_flags;
if (readWrite) {
ckflags |= CKF_RW_SESSION;
}
- /* does the opening and closing of sessions need to be done in a
- * threadsafe manner? should there be a "meta-lock" controlling
- * calls like this?
- */
- ckrv = CKAPI(slot)->C_OpenSession(slot->slotID, ckflags,
- slot, nss_ck_slot_notify, &session);
+ ckrv = CKAPI(epv)->C_OpenSession(slot->slotID, ckflags,
+ slot, nss_ck_slot_notify, &handle);
if (ckrv != CKR_OK) {
/* set an error here, eh? */
return (nssSession *)NULL;
@@ -473,7 +765,7 @@ nssSlot_CreateSession
if (!rvSession) {
return (nssSession *)NULL;
}
- if (slot->module->flags & NSSMODULE_FLAGS_NOT_THREADSAFE) {
+ if (!nssModule_IsThreadSafe(slot->module)) {
/* If the parent module is not threadsafe, create lock to manage
* session within threads.
*/
@@ -487,7 +779,7 @@ nssSlot_CreateSession
return (nssSession *)NULL;
}
}
- rvSession->handle = session;
+ rvSession->handle = handle;
rvSession->slot = slot;
rvSession->isRW = readWrite;
return rvSession;
@@ -501,7 +793,8 @@ nssSession_Destroy
{
CK_RV ckrv = CKR_OK;
if (s) {
- ckrv = CKAPI(s->slot)->C_CloseSession(s->handle);
+ void *epv = s->slot->epv;
+ ckrv = CKAPI(epv)->C_CloseSession(s->handle);
if (s->lock) {
PZ_DestroyLock(s->lock);
}
@@ -509,7 +802,7 @@ nssSession_Destroy
}
return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
}
-#endif
+#endif /* PURE_STAN_BUILD */
NSS_IMPLEMENT PRStatus
nssSession_EnterMonitor
diff --git a/security/nss/lib/dev/devt.h b/security/nss/lib/dev/devt.h
index ef031524b..10a7978c3 100644
--- a/security/nss/lib/dev/devt.h
+++ b/security/nss/lib/dev/devt.h
@@ -72,81 +72,70 @@ PR_BEGIN_EXTERN_C
typedef struct nssSessionStr nssSession;
-/* The list of boolean flags used to describe properties of a
- * module.
- */
-#define NSSMODULE_FLAGS_NOT_THREADSAFE 0x0001 /* isThreadSafe */
-
-struct NSSModuleStr {
- NSSArena *arena;
- PRInt32 refCount;
- NSSUTF8 *name;
- NSSUTF8 *libraryPath;
- PRLibrary *library;
- void *epv;
- NSSSlot **slots;
- PRUint32 numSlots;
- PRUint32 flags;
-};
-
-/* The list of boolean flags used to describe properties of a
- * slot.
- */
-#define NSSSLOT_FLAGS_LOGIN_REQUIRED 0x0001 /* needLogin */
-/*#define NSSSLOT_FLAGS_READONLY 0x0002*/ /* readOnly */
-
-/* this should track global and per-transaction login information */
-struct nssSlotAuthInfoStr
+/* XXX until NSSTokenStr is moved */
+struct nssDeviceBaseStr
{
- PRTime lastLogin;
- PRInt32 askPasswordTimeout;
+ NSSArena *arena;
+ PZLock *lock;
+ PRInt32 refCount;
+ NSSUTF8 *name;
+ PRUint32 flags;
};
-struct NSSSlotStr
-{
- NSSArena *arena;
- PRInt32 refCount;
- NSSModule *module; /* Parent */
- NSSToken *token; /* Child (or peer, if you will) */
- NSSUTF8 *name;
- CK_SLOT_ID slotID;
- void *epv;
- CK_FLAGS ckFlags; /* from CK_SLOT_INFO.flags */
- PRUint32 flags;
- struct nssSlotAuthInfoStr authInfo;
- NSSTrustDomain *trustDomain;
-#ifdef NSS_3_4_CODE
- PK11SlotInfo *pk11slot;
-#endif
-};
+typedef struct nssTokenObjectCacheStr nssTokenObjectCache;
+/* XXX until devobject.c goes away */
struct NSSTokenStr
{
- NSSArena *arena;
- PRInt32 refCount;
+ struct nssDeviceBaseStr base;
NSSSlot *slot; /* Parent (or peer, if you will) */
- NSSUTF8 *name;
CK_FLAGS ckFlags; /* from CK_TOKEN_INFO.flags */
PRUint32 flags;
void *epv;
nssSession *defaultSession;
NSSTrustDomain *trustDomain;
PRIntervalTime lastTime;
- PRBool hasNoTrust;
- PRBool hasNoCrls;
+ nssTokenObjectCache *cache;
#ifdef NSS_3_4_CODE
PK11SlotInfo *pk11slot;
- nssList *certList; /* local cache of certs for slow tokens */
- PRBool loggedIn;
+#endif
+};
+
+typedef enum {
+ nssSlotAskPasswordTimes_FirstTime = 0,
+ nssSlotAskPasswordTimes_EveryTime = 1,
+ nssSlotAskPasswordTimes_Timeout = 2
+}
+nssSlotAskPasswordTimes;
+
+struct nssSlotAuthInfoStr
+{
+ PRTime lastLogin;
+ nssSlotAskPasswordTimes askTimes;
+ PRIntervalTime askPasswordTimeout;
+};
+
+struct NSSSlotStr
+{
+ struct nssDeviceBaseStr base;
+ NSSModule *module; /* Parent */
+ NSSToken *token; /* Peer */
+ CK_SLOT_ID slotID;
+ CK_FLAGS ckFlags; /* from CK_SLOT_INFO.flags */
+ struct nssSlotAuthInfoStr authInfo;
+ PRIntervalTime lastTokenPing;
+#ifdef NSS_3_4_CODE
+ void *epv;
+ PK11SlotInfo *pk11slot;
#endif
};
struct nssSessionStr
{
- PZLock *lock;
- CK_SESSION_HANDLE handle;
- NSSSlot *slot;
- PRBool isRW;
+ PZLock *lock;
+ CK_SESSION_HANDLE handle;
+ NSSSlot *slot;
+ PRBool isRW;
};
typedef enum {
@@ -155,15 +144,17 @@ typedef enum {
} NSSCertificateType;
#ifdef nodef
+/* the current definition of NSSTrust depends on this value being CK_ULONG */
+typedef CK_ULONG nssTrustLevel;
+#else
typedef enum {
nssTrustLevel_Unknown = 0,
nssTrustLevel_NotTrusted = 1,
nssTrustLevel_Trusted = 2,
nssTrustLevel_TrustedDelegator = 3,
- nssTrustLevel_Valid = 4
+ nssTrustLevel_Valid = 4,
+ nssTrustLevel_ValidDelegator = 5
} nssTrustLevel;
-#else
-typedef CK_ULONG nssTrustLevel; /* for now */
#endif
typedef struct nssCryptokiInstanceStr nssCryptokiInstance;
@@ -176,12 +167,15 @@ struct nssCryptokiInstanceStr
NSSUTF8 *label;
};
+typedef struct nssCryptokiInstanceStr nssCryptokiObject;
+
typedef struct nssTokenCertSearchStr nssTokenCertSearch;
typedef enum {
nssTokenSearchType_AllObjects = 0,
nssTokenSearchType_SessionOnly = 1,
- nssTokenSearchType_TokenOnly = 2
+ nssTokenSearchType_TokenOnly = 2,
+ nssTokenSearchType_TokenForced = 3
} nssTokenSearchType;
struct nssTokenCertSearchStr
@@ -195,6 +189,9 @@ struct nssTokenCertSearchStr
*/
};
+struct nssSlotListStr;
+typedef struct nssSlotListStr nssSlotList;
+
struct NSSAlgorithmAndParametersStr
{
CK_MECHANISM mechanism;
diff --git a/security/nss/lib/dev/devtoken.c b/security/nss/lib/dev/devtoken.c
index b3b168a5f..a43ed43f4 100644
--- a/security/nss/lib/dev/devtoken.c
+++ b/security/nss/lib/dev/devtoken.c
@@ -35,74 +35,68 @@
static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#endif /* DEBUG */
-#ifndef DEV_H
-#include "dev.h"
-#endif /* DEV_H */
+#ifndef NSSCKEPV_H
+#include "nssckepv.h"
+#endif /* NSSCKEPV_H */
#ifndef DEVM_H
#include "devm.h"
#endif /* DEVM_H */
-#ifndef NSSCKEPV_H
-#include "nssckepv.h"
-#endif /* NSSCKEPV_H */
-
#ifndef CKHELPER_H
#include "ckhelper.h"
#endif /* CKHELPER_H */
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
+#ifdef NSS_3_4_CODE
+#include "pk11func.h"
+#include "dev3hack.h"
+#endif
+
+/* The number of object handles to grab during each call to C_FindObjects */
+#define OBJECT_STACK_SIZE 16
+
+#ifdef PURE_STAN_BUILD
+struct NSSTokenStr
+{
+ struct nssDeviceBaseStr base;
+ NSSSlot *slot; /* Peer */
+ CK_FLAGS ckFlags; /* from CK_TOKEN_INFO.flags */
+ nssSession *defaultSession;
+ nssTokenObjectCache *cache;
+};
-/* maybe this should really inherit completely from the module... I dunno,
- * any uses of slots where independence is needed?
- */
NSS_IMPLEMENT NSSToken *
nssToken_Create
(
- NSSArena *arenaOpt,
CK_SLOT_ID slotID,
- NSSSlot *parent
+ NSSSlot *peer
)
{
NSSArena *arena;
- nssArenaMark *mark = NULL;
NSSToken *rvToken;
nssSession *session = NULL;
NSSUTF8 *tokenName = NULL;
PRUint32 length;
- PRBool newArena;
PRBool readWrite;
- PRStatus nssrv;
CK_TOKEN_INFO tokenInfo;
CK_RV ckrv;
- if (arenaOpt) {
- arena = arenaOpt;
- mark = nssArena_Mark(arena);
- if (!mark) {
- return (NSSToken *)NULL;
- }
- newArena = PR_FALSE;
- } else {
- arena = NSSArena_Create();
- if(!arena) {
- return (NSSToken *)NULL;
- }
- newArena = PR_TRUE;
+ void *epv = nssSlot_GetCryptokiEPV(peer);
+ arena = NSSArena_Create();
+ if(!arena) {
+ return (NSSToken *)NULL;
}
rvToken = nss_ZNEW(arena, NSSToken);
if (!rvToken) {
goto loser;
}
/* Get token information */
- ckrv = CKAPI(parent)->C_GetTokenInfo(slotID, &tokenInfo);
+ ckrv = CKAPI(epv)->C_GetTokenInfo(slotID, &tokenInfo);
if (ckrv != CKR_OK) {
/* set an error here, eh? */
goto loser;
}
/* Grab the slot description from the PKCS#11 fixed-length buffer */
- length = nssPKCS11StringLength(tokenInfo.label, sizeof(tokenInfo.label));
+ length = nssPKCS11String_Length(tokenInfo.label, sizeof(tokenInfo.label));
if (length > 0) {
tokenName = nssUTF8_Create(arena, nssStringType_UTF8String,
(void *)tokenInfo.label, length);
@@ -117,28 +111,26 @@ nssToken_Create
} else {
readWrite = PR_FALSE;
}
- session = nssSlot_CreateSession(parent, arena, readWrite);
+ session = nssSlot_CreateSession(peer, arena, readWrite);
if (session == NULL) {
goto loser;
}
/* TODO: seed the RNG here */
- if (!arenaOpt) {
- /* Avoid confusion now - only set the token's arena to a non-NULL value
- * if a new arena is created. Otherwise, depend on the caller (having
- * passed arenaOpt) to free the arena.
- */
- rvToken->arena = arena;
+ rvToken->base.arena = arena;
+ rvToken->base.refCount = 1;
+ rvToken->base.name = tokenName;
+ rvToken->base.lock = PZ_NewLock(nssNSSILockOther); /* XXX */
+ if (!rvToken->base.lock) {
+ goto loser;
}
- rvToken->refCount = 1;
- rvToken->slot = parent;
- rvToken->name = tokenName;
+ rvToken->slot = peer; /* slot owns ref to token */
rvToken->ckFlags = tokenInfo.flags;
rvToken->defaultSession = session;
- rvToken->hasNoTrust = PR_FALSE;
- rvToken->hasNoCrls = PR_FALSE;
- if (mark) {
- nssrv = nssArena_Unmark(arena, mark);
- if (nssrv != PR_SUCCESS) {
+ if (nssSlot_IsHardware(peer)) {
+ rvToken->cache = nssTokenObjectCache_Create(rvToken,
+ PR_TRUE, PR_TRUE, PR_TRUE);
+ if (!rvToken->cache) {
+ nssSlot_Destroy(peer);
goto loser;
}
}
@@ -147,15 +139,10 @@ loser:
if (session) {
nssSession_Destroy(session);
}
- if (newArena) {
- nssArena_Destroy(arena);
- } else {
- if (mark) {
- nssArena_Release(arena, mark);
- }
- }
+ nssArena_Destroy(arena);
return (NSSToken *)NULL;
}
+#endif /* PURE_STAN_BUILD */
NSS_IMPLEMENT PRStatus
nssToken_Destroy
@@ -163,141 +150,1238 @@ nssToken_Destroy
NSSToken *tok
)
{
- if (--tok->refCount == 0) {
-#ifndef NSS_3_4_CODE
- /* don't do this in 3.4 -- let PK11SlotInfo handle it */
- if (tok->defaultSession) {
- nssSession_Destroy(tok->defaultSession);
- }
- if (tok->arena) {
- return NSSArena_Destroy(tok->arena);
- } else {
- nss_ZFreeIf(tok);
+ if (tok) {
+ PR_AtomicDecrement(&tok->base.refCount);
+ if (tok->base.refCount == 0) {
+ PZ_DestroyLock(tok->base.lock);
+ nssTokenObjectCache_Destroy(tok->cache);
+ return nssArena_Destroy(tok->base.arena);
}
-#else
- nss_ZFreeIf(tok);
-#endif
}
return PR_SUCCESS;
}
+NSS_IMPLEMENT void
+nssToken_Remove
+(
+ NSSToken *tok
+)
+{
+ nssTokenObjectCache_Clear(tok->cache);
+}
+
+NSS_IMPLEMENT void
+NSSToken_Destroy
+(
+ NSSToken *tok
+)
+{
+ (void)nssToken_Destroy(tok);
+}
+
NSS_IMPLEMENT NSSToken *
nssToken_AddRef
(
NSSToken *tok
)
{
- ++tok->refCount;
+ PR_AtomicIncrement(&tok->base.refCount);
return tok;
}
+NSS_IMPLEMENT NSSSlot *
+nssToken_GetSlot
+(
+ NSSToken *tok
+)
+{
+ return nssSlot_AddRef(tok->slot);
+}
+
+#ifdef PURE_STAN_BUILD
+NSS_IMPLEMENT NSSModule *
+nssToken_GetModule
+(
+ NSSToken *token
+)
+{
+ return nssSlot_GetModule(token->slot);
+}
+#endif
+
+NSS_IMPLEMENT void *
+nssToken_GetCryptokiEPV
+(
+ NSSToken *token
+)
+{
+ return nssSlot_GetCryptokiEPV(token->slot);
+}
+
+NSS_IMPLEMENT nssSession *
+nssToken_GetDefaultSession
+(
+ NSSToken *token
+)
+{
+ return token->defaultSession;
+}
+
NSS_IMPLEMENT NSSUTF8 *
nssToken_GetName
(
NSSToken *tok
)
{
- if (tok->name[0] == 0) {
- (void) nssToken_IsPresent(tok);
+ if (tok == NULL) {
+ return "";
+ }
+ if (tok->base.name[0] == 0) {
+ (void) nssSlot_IsTokenPresent(tok->slot);
}
- return tok->name;
+ return tok->base.name;
+}
+
+NSS_IMPLEMENT NSSUTF8 *
+NSSToken_GetName
+(
+ NSSToken *token
+)
+{
+ return nssToken_GetName(token);
}
NSS_IMPLEMENT PRBool
-nssToken_IsPresent
+nssToken_IsLoginRequired
+(
+ NSSToken *token
+)
+{
+ return (token->ckFlags & CKF_LOGIN_REQUIRED);
+}
+
+NSS_IMPLEMENT PRBool
+nssToken_NeedsPINInitialization
(
NSSToken *token
)
{
+ return (!(token->ckFlags & CKF_USER_PIN_INITIALIZED));
+}
+
+NSS_IMPLEMENT PRStatus
+nssToken_DeleteStoredObject
+(
+ nssCryptokiObject *instance
+)
+{
CK_RV ckrv;
- PRStatus nssrv;
- nssSession *session;
- CK_SLOT_INFO slotInfo;
- NSSSlot *slot = token->slot;
- PRIntervalTime time,lastTime;
- static PRIntervalTime delayTime = 0;
-
- session = token->defaultSession;
- /* permanent slots are always present */
- if (nssSlot_IsPermanent(slot) && session != CK_INVALID_SESSION) {
- return PR_TRUE;
- }
-
- if (delayTime == 0) {
- delayTime = PR_SecondsToInterval(10);
- }
-
- time = PR_IntervalNow();
- lastTime = token->lastTime;
- if ((time > lastTime) && ((time - lastTime) < delayTime)) {
- return (PRBool) ((slot->ckFlags & CKF_TOKEN_PRESENT) != 0);
- }
- token->lastTime = time;
+ PRStatus status;
+ PRBool createdSession = PR_FALSE;
+ NSSToken *token = instance->token;
+ nssSession *session = NULL;
+ void *epv = nssToken_GetCryptokiEPV(instance->token);
+ if (token->cache) {
+ nssTokenObjectCache_RemoveObject(token->cache, instance);
+ }
+ if (instance->isTokenObject) {
+ if (nssSession_IsReadWrite(token->defaultSession)) {
+ session = token->defaultSession;
+ } else {
+ session = nssSlot_CreateSession(token->slot, NULL, PR_TRUE);
+ createdSession = PR_TRUE;
+ }
+ }
+ if (session == NULL) {
+ return PR_FAILURE;
+ }
nssSession_EnterMonitor(session);
- /* First obtain the slot info */
- ckrv = CKAPI(slot)->C_GetSlotInfo(slot->slotID, &slotInfo);
- if (ckrv != CKR_OK) {
- nssSession_ExitMonitor(session);
- token->name[0] = 0;
- return PR_FALSE;
- }
- slot->ckFlags = slotInfo.flags;
- /* check for the presence of the token */
- if ((slot->ckFlags & CKF_TOKEN_PRESENT) == 0) {
- /* token is not present */
- if (session->handle != CK_INVALID_SESSION) {
- /* session is valid, close and invalidate it */
- CKAPI(slot)->C_CloseSession(session->handle);
- session->handle = CK_INVALID_SESSION;
+ ckrv = CKAPI(epv)->C_DestroyObject(session->handle, instance->handle);
+ nssSession_ExitMonitor(session);
+ if (createdSession) {
+ nssSession_Destroy(session);
+ }
+ status = (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
+ return status;
+}
+
+static nssCryptokiObject *
+import_object
+(
+ NSSToken *tok,
+ nssSession *sessionOpt,
+ CK_ATTRIBUTE_PTR objectTemplate,
+ CK_ULONG otsize
+)
+{
+ nssSession *session = NULL;
+ PRBool createdSession = PR_FALSE;
+ nssCryptokiObject *object = NULL;
+ CK_OBJECT_HANDLE handle;
+ CK_RV ckrv;
+ void *epv = nssToken_GetCryptokiEPV(tok);
+ if (nssCKObject_IsTokenObjectTemplate(objectTemplate, otsize)) {
+ if (sessionOpt) {
+ if (!nssSession_IsReadWrite(sessionOpt)) {
+ return CK_INVALID_HANDLE;
+ } else {
+ session = sessionOpt;
+ }
+ } else if (nssSession_IsReadWrite(tok->defaultSession)) {
+ session = tok->defaultSession;
+ } else {
+ session = nssSlot_CreateSession(tok->slot, NULL, PR_TRUE);
+ createdSession = PR_TRUE;
+ }
+ } else {
+ session = (sessionOpt) ? sessionOpt : tok->defaultSession;
+ }
+ if (session == NULL) {
+ return CK_INVALID_HANDLE;
+ }
+ nssSession_EnterMonitor(session);
+ ckrv = CKAPI(epv)->C_CreateObject(session->handle,
+ objectTemplate, otsize,
+ &handle);
+ nssSession_ExitMonitor(session);
+ if (ckrv == CKR_OK) {
+ object = nssCryptokiObject_Create(tok, session, handle);
+ }
+ if (createdSession) {
+ nssSession_Destroy(session);
+ }
+ return object;
+}
+
+static nssCryptokiObject **
+create_objects_from_handles
+(
+ NSSToken *tok,
+ nssSession *session,
+ CK_OBJECT_HANDLE *handles,
+ PRUint32 numH
+)
+{
+ nssCryptokiObject **objects;
+ objects = nss_ZNEWARRAY(NULL, nssCryptokiObject *, numH + 1);
+ if (objects) {
+ PRInt32 i;
+ for (i=0; i<(PRInt32)numH; i++) {
+ objects[i] = nssCryptokiObject_Create(tok, session, handles[i]);
+ if (!objects[i]) {
+ for (--i; i>0; --i) {
+ nssCryptokiObject_Destroy(objects[i]);
+ }
+ return (nssCryptokiObject **)NULL;
+ }
}
+ }
+ return objects;
+}
+
+static nssCryptokiObject **
+find_objects
+(
+ NSSToken *tok,
+ nssSession *sessionOpt,
+ CK_ATTRIBUTE_PTR obj_template,
+ CK_ULONG otsize,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
+)
+{
+ CK_RV ckrv;
+ CK_ULONG count;
+ CK_OBJECT_HANDLE *objectHandles;
+ PRUint32 arraySize, numHandles;
+ void *epv = nssToken_GetCryptokiEPV(tok);
+ nssCryptokiObject **objects;
+ NSSArena *arena;
+ nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession;
+ /* the arena is only for the array of object handles */
+ arena = nssArena_Create();
+ if (!arena) {
+ if (statusOpt) *statusOpt = PR_FAILURE;
+ return (nssCryptokiObject **)NULL;
+ }
+ if (maximumOpt > 0) {
+ arraySize = maximumOpt;
+ } else {
+ arraySize = OBJECT_STACK_SIZE;
+ }
+ numHandles = 0;
+ objectHandles = nss_ZNEWARRAY(arena, CK_OBJECT_HANDLE, arraySize);
+ if (!objectHandles) {
+ goto loser;
+ }
+ nssSession_EnterMonitor(session); /* ==== session lock === */
+ /* Initialize the find with the template */
+ ckrv = CKAPI(epv)->C_FindObjectsInit(session->handle,
+ obj_template, otsize);
+ if (ckrv != CKR_OK) {
nssSession_ExitMonitor(session);
- token->name[0] = 0;
- return PR_FALSE;
+ goto loser;
}
- /* token is present, use the session info to determine if the card
- * has been removed and reinserted.
- */
- if (session != CK_INVALID_SESSION) {
- CK_SESSION_INFO sessionInfo;
- ckrv = CKAPI(slot)->C_GetSessionInfo(session->handle, &sessionInfo);
+ while (PR_TRUE) {
+ /* Issue the find for up to arraySize - numHandles objects */
+ ckrv = CKAPI(epv)->C_FindObjects(session->handle,
+ objectHandles + numHandles,
+ arraySize - numHandles,
+ &count);
if (ckrv != CKR_OK) {
- /* session is screwy, close and invalidate it */
- CKAPI(slot)->C_CloseSession(session->handle);
- session->handle = CK_INVALID_SESSION;
+ nssSession_ExitMonitor(session);
+ goto loser;
+ }
+ /* bump the number of found objects */
+ numHandles += count;
+ if (maximumOpt > 0 || numHandles < arraySize) {
+ /* When a maximum is provided, the search is done all at once,
+ * so the search is finished. If the number returned was less
+ * than the number sought, the search is finished.
+ */
+ break;
+ }
+ /* the array is filled, double it and continue */
+ arraySize *= 2;
+ objectHandles = nss_ZREALLOCARRAY(objectHandles,
+ CK_OBJECT_HANDLE,
+ arraySize);
+ if (!objectHandles) {
+ nssSession_ExitMonitor(session);
+ goto loser;
}
}
- nssSession_ExitMonitor(session);
- /* token not removed, finished */
- if (session->handle != CK_INVALID_SESSION) {
- return PR_TRUE;
+ ckrv = CKAPI(epv)->C_FindObjectsFinal(session->handle);
+ nssSession_ExitMonitor(session); /* ==== end session lock === */
+ if (ckrv != CKR_OK) {
+ goto loser;
+ }
+ if (numHandles > 0) {
+ objects = create_objects_from_handles(tok, session,
+ objectHandles, numHandles);
} else {
- /* token has been removed, need to refresh with new session */
- nssrv = nssSlot_Refresh(slot);
- if (nssrv != PR_SUCCESS) {
- token->name[0] = 0;
- return PR_FALSE;
+ objects = NULL;
+ }
+ nssArena_Destroy(arena);
+ if (statusOpt) *statusOpt = PR_SUCCESS;
+ return objects;
+loser:
+ nssArena_Destroy(arena);
+ if (statusOpt) *statusOpt = PR_FAILURE;
+ return (nssCryptokiObject **)NULL;
+}
+
+static nssCryptokiObject **
+find_objects_by_template
+(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ CK_ATTRIBUTE_PTR obj_template,
+ CK_ULONG otsize,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
+)
+{
+ CK_OBJECT_CLASS objclass;
+ nssCryptokiObject **objects = NULL;
+ PRUint32 i;
+ for (i=0; i<otsize; i++) {
+ if (obj_template[i].type == CKA_CLASS) {
+ objclass = *(CK_OBJECT_CLASS *)obj_template[i].pValue;
+ break;
+ }
+ }
+ PR_ASSERT(i < otsize);
+ /* If these objects are being cached, try looking there first */
+ if (token->cache &&
+ nssTokenObjectCache_HaveObjectClass(token->cache, objclass))
+ {
+ PRStatus status;
+ objects = nssTokenObjectCache_FindObjectsByTemplate(token->cache,
+ objclass,
+ obj_template,
+ otsize,
+ maximumOpt,
+ &status);
+ if (status == PR_SUCCESS) {
+ if (statusOpt) *statusOpt = status;
+ return objects;
}
- return PR_TRUE;
}
+ /* Either they are not cached, or cache failed; look on token. */
+ objects = find_objects(token, sessionOpt,
+ obj_template, otsize,
+ maximumOpt, statusOpt);
+ return objects;
}
-NSS_IMPLEMENT PRBool
-nssToken_HasCrls
+NSS_IMPLEMENT nssCryptokiObject *
+nssToken_ImportCertificate
+(
+ NSSToken *tok,
+ nssSession *sessionOpt,
+ NSSCertificateType certType,
+ NSSItem *id,
+ NSSUTF8 *nickname,
+ NSSDER *encoding,
+ NSSDER *issuer,
+ NSSDER *subject,
+ NSSDER *serial,
+ NSSASCII7 *email,
+ PRBool asTokenObject
+)
+{
+ CK_CERTIFICATE_TYPE cert_type;
+ CK_ATTRIBUTE_PTR attr;
+ CK_ATTRIBUTE cert_tmpl[10];
+ CK_ULONG ctsize;
+ nssTokenSearchType searchType;
+ nssCryptokiObject *rvObject = NULL;
+
+ if (certType == NSSCertificateType_PKIX) {
+ cert_type = CKC_X_509;
+ } else {
+ return (nssCryptokiObject *)NULL;
+ }
+ 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;
+ }
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
+ NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CERTIFICATE_TYPE, cert_type);
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id);
+ NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname);
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encoding);
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, issuer);
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject);
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, serial);
+ if (email) {
+ NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NETSCAPE_EMAIL, email);
+ }
+ NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize);
+ /* see if the cert is already there */
+ rvObject = nssToken_FindCertificateByIssuerAndSerialNumber(tok,
+ sessionOpt,
+ issuer,
+ serial,
+ searchType,
+ NULL);
+ if (rvObject) {
+ NSSSlot *slot = nssToken_GetSlot(tok);
+ nssSession *session = nssSlot_CreateSession(slot, NULL, PR_TRUE);
+ if (!session) {
+ nssCryptokiObject_Destroy(rvObject);
+ return (nssCryptokiObject *)NULL;
+ }
+ /* according to PKCS#11, label, ID, issuer, and serial number
+ * may change after the object has been created. For PKIX, the
+ * last two attributes can't change, so for now we'll only worry
+ * about the first two.
+ */
+ NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize);
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id);
+ NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname);
+ NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize);
+ /* reset the mutable attributes on the token */
+ nssCKObject_SetAttributes(rvObject->handle,
+ cert_tmpl, ctsize,
+ session, slot);
+ if (!rvObject->label && nickname) {
+ rvObject->label = nssUTF8_Duplicate(nickname, NULL);
+ }
+ nssSession_Destroy(session);
+ nssSlot_Destroy(slot);
+ } else {
+ /* Import the certificate onto the token */
+ rvObject = import_object(tok, sessionOpt, cert_tmpl, ctsize);
+ }
+ if (rvObject && tok->cache) {
+ /* The cache will overwrite the attributes if the object already
+ * exists.
+ */
+ nssTokenObjectCache_ImportObject(tok->cache, rvObject,
+ CKO_CERTIFICATE,
+ cert_tmpl, ctsize);
+ }
+ return rvObject;
+}
+
+/* traverse all certificates - this should only happen if the token
+ * has been marked as "traversable"
+ */
+NSS_IMPLEMENT nssCryptokiObject **
+nssToken_FindCertificates
(
- NSSToken *tok
+ NSSToken *token,
+ nssSession *sessionOpt,
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
)
{
- return !tok->hasNoCrls;
+ CK_ATTRIBUTE_PTR attr;
+ CK_ATTRIBUTE cert_template[2];
+ CK_ULONG ctsize;
+ nssCryptokiObject **objects;
+ 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 ||
+ searchType == nssTokenSearchType_TokenForced) {
+ 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);
+
+ if (searchType == nssTokenSearchType_TokenForced) {
+ objects = find_objects(token, sessionOpt,
+ cert_template, ctsize,
+ maximumOpt, statusOpt);
+ } else {
+ objects = find_objects_by_template(token, sessionOpt,
+ cert_template, ctsize,
+ maximumOpt, statusOpt);
+ }
+ return objects;
+}
+
+NSS_IMPLEMENT nssCryptokiObject **
+nssToken_FindCertificatesBySubject
+(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ NSSDER *subject,
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
+)
+{
+ CK_ATTRIBUTE_PTR attr;
+ CK_ATTRIBUTE subj_template[3];
+ CK_ULONG stsize;
+ nssCryptokiObject **objects;
+ NSS_CK_TEMPLATE_START(subj_template, attr, stsize);
+ /* 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_CLASS, &g_ck_class_cert);
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject);
+ NSS_CK_TEMPLATE_FINISH(subj_template, attr, stsize);
+ /* now locate the token certs matching this template */
+ objects = find_objects_by_template(token, sessionOpt,
+ subj_template, stsize,
+ maximumOpt, statusOpt);
+ return objects;
+}
+
+NSS_IMPLEMENT nssCryptokiObject **
+nssToken_FindCertificatesByNickname
+(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ NSSUTF8 *name,
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
+)
+{
+ CK_ATTRIBUTE_PTR attr;
+ CK_ATTRIBUTE nick_template[3];
+ CK_ULONG ntsize;
+ nssCryptokiObject **objects;
+ NSS_CK_TEMPLATE_START(nick_template, attr, ntsize);
+ NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, name);
+ /* 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_CLASS, &g_ck_class_cert);
+ NSS_CK_TEMPLATE_FINISH(nick_template, attr, ntsize);
+ /* now locate the token certs matching this template */
+ objects = find_objects_by_template(token, sessionOpt,
+ nick_template, ntsize,
+ maximumOpt, statusOpt);
+ if (!objects) {
+ /* This is to workaround the fact that PKCS#11 doesn't specify
+ * whether the '\0' should be included. XXX Is that still true?
+ * im - this is not needed by the current softoken. However, I'm
+ * leaving it in until I have surveyed more tokens to see if it needed.
+ * well, its needed by the builtin token...
+ */
+ nick_template[0].ulValueLen++;
+ objects = find_objects_by_template(token, sessionOpt,
+ nick_template, ntsize,
+ maximumOpt, statusOpt);
+ }
+ return objects;
+}
+
+/* XXX
+ * This function *does not* use the token object cache, because not even
+ * the softoken will return a value for CKA_NETSCAPE_EMAIL from a call
+ * to GetAttributes. The softoken does allow searches with that attribute,
+ * it just won't return a value for it.
+ */
+NSS_IMPLEMENT nssCryptokiObject **
+nssToken_FindCertificatesByEmail
+(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ NSSASCII7 *email,
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
+)
+{
+ CK_ATTRIBUTE_PTR attr;
+ CK_ATTRIBUTE email_template[3];
+ CK_ULONG etsize;
+ nssCryptokiObject **objects;
+ NSS_CK_TEMPLATE_START(email_template, attr, etsize);
+ NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NETSCAPE_EMAIL, email);
+ /* 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_CLASS, &g_ck_class_cert);
+ NSS_CK_TEMPLATE_FINISH(email_template, attr, etsize);
+ /* now locate the token certs matching this template */
+ objects = find_objects(token, sessionOpt,
+ email_template, etsize,
+ maximumOpt, statusOpt);
+ if (!objects) {
+ /* This is to workaround the fact that PKCS#11 doesn't specify
+ * whether the '\0' should be included. XXX Is that still true?
+ * im - this is not needed by the current softoken. However, I'm
+ * leaving it in until I have surveyed more tokens to see if it needed.
+ * well, its needed by the builtin token...
+ */
+ email_template[0].ulValueLen++;
+ objects = find_objects(token, sessionOpt,
+ email_template, etsize,
+ maximumOpt, statusOpt);
+ }
+ return objects;
+}
+
+NSS_IMPLEMENT nssCryptokiObject **
+nssToken_FindCertificatesByID
+(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ NSSItem *id,
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
+)
+{
+ CK_ATTRIBUTE_PTR attr;
+ CK_ATTRIBUTE id_template[3];
+ CK_ULONG idtsize;
+ nssCryptokiObject **objects;
+ NSS_CK_TEMPLATE_START(id_template, attr, idtsize);
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id);
+ /* 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_CLASS, &g_ck_class_cert);
+ NSS_CK_TEMPLATE_FINISH(id_template, attr, idtsize);
+ /* now locate the token certs matching this template */
+ objects = find_objects_by_template(token, sessionOpt,
+ id_template, idtsize,
+ maximumOpt, statusOpt);
+ return objects;
+}
+
+/*
+ * decode the serial item and return our result.
+ * NOTE serialDecode's data is really stored in serial. Don't free it.
+ */
+static PRStatus
+nssToken_decodeSerialItem(NSSItem *serial, NSSItem *serialDecode)
+{
+ unsigned char *data = (unsigned char *)serial->data;
+ int data_left, data_len, index;
+
+ if ((serial->size >= 3) && (data[0] == 0x2)) {
+ /* remove the der encoding of the serial number before generating the
+ * key.. */
+ data_left = serial->size-2;
+ data_len = data[1];
+ index = 2;
+
+ /* extended length ? (not very likely for a serial number) */
+ if (data_len & 0x80) {
+ int len_count = data_len & 0x7f;
+
+ data_len = 0;
+ data_left -= len_count;
+ if (data_left > 0) {
+ while (len_count --) {
+ data_len = (data_len << 8) | data[index++];
+ }
+ }
+ }
+ /* XXX leaving any leading zeros on the serial number for backwards
+ * compatibility
+ */
+ /* not a valid der, must be just an unlucky serial number value */
+ if (data_len == data_left) {
+ serialDecode->size = data_len;
+ serialDecode->data = &data[index];
+ return PR_SUCCESS;
+ }
+ }
+ return PR_FAILURE;
+}
+
+NSS_IMPLEMENT nssCryptokiObject *
+nssToken_FindCertificateByIssuerAndSerialNumber
+(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ NSSDER *issuer,
+ NSSDER *serial,
+ nssTokenSearchType searchType,
+ PRStatus *statusOpt
+)
+{
+ CK_ATTRIBUTE_PTR attr;
+ CK_ATTRIBUTE_PTR serialAttr;
+ CK_ATTRIBUTE cert_template[4];
+ CK_ULONG ctsize;
+ nssCryptokiObject **objects;
+ nssCryptokiObject *rvObject = NULL;
+ 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);
+ }
+ /* Set the unique id */
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, issuer);
+ serialAttr = attr;
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, serial);
+ NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize);
+ /* get the object handle */
+ objects = find_objects_by_template(token, sessionOpt,
+ cert_template, ctsize,
+ 1, statusOpt);
+ if (objects) {
+ rvObject = objects[0];
+ nss_ZFreeIf(objects);
+ }
+
+ /*
+ * NSS used to incorrectly store serial numbers in their decoded form.
+ * because of this old tokens have decoded serial numbers.
+ */
+ if (!objects) {
+ NSSItem serialDecode;
+ PRStatus status;
+
+ status = nssToken_decodeSerialItem(serial, &serialDecode);
+ if (status != PR_SUCCESS) {
+ return NULL;
+ }
+ NSS_CK_SET_ATTRIBUTE_ITEM(serialAttr,CKA_SERIAL_NUMBER,&serialDecode);
+ objects = find_objects_by_template(token, sessionOpt,
+ cert_template, ctsize,
+ 1, statusOpt);
+ if (objects) {
+ rvObject = objects[0];
+ nss_ZFreeIf(objects);
+ }
+ }
+ return rvObject;
+}
+
+NSS_IMPLEMENT nssCryptokiObject *
+nssToken_FindCertificateByEncodedCertificate
+(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ NSSBER *encodedCertificate,
+ nssTokenSearchType searchType,
+ PRStatus *statusOpt
+)
+{
+ CK_ATTRIBUTE_PTR attr;
+ CK_ATTRIBUTE cert_template[3];
+ CK_ULONG ctsize;
+ nssCryptokiObject **objects;
+ nssCryptokiObject *rvObject = NULL;
+ 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_CLASS, &g_ck_class_cert);
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encodedCertificate);
+ NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize);
+ /* get the object handle */
+ objects = find_objects_by_template(token, sessionOpt,
+ cert_template, ctsize,
+ 1, statusOpt);
+ if (objects) {
+ rvObject = objects[0];
+ nss_ZFreeIf(objects);
+ }
+ return rvObject;
+}
+
+NSS_IMPLEMENT nssCryptokiObject **
+nssToken_FindPrivateKeys
+(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
+)
+{
+ CK_ATTRIBUTE_PTR attr;
+ CK_ATTRIBUTE key_template[2];
+ CK_ULONG ktsize;
+ 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_TEMPLATE_FINISH(key_template, attr, ktsize);
+
+ objects = find_objects_by_template(token, sessionOpt,
+ key_template, ktsize,
+ maximumOpt, statusOpt);
+ return objects;
+}
+
+/* XXX ?there are no session cert objects, so only search token objects */
+NSS_IMPLEMENT nssCryptokiObject *
+nssToken_FindPrivateKeyByID
+(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ 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_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, sessionOpt,
+ 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 *sessionOpt,
+ 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, sessionOpt,
+ key_template, ktsize,
+ 1, NULL);
+ if (objects) {
+ rvKey = objects[0];
+ nss_ZFreeIf(objects);
+ }
+ return rvKey;
+}
+
+static void
+sha1_hash(NSSItem *input, NSSItem *output)
+{
+ NSSAlgorithmAndParameters *ap;
+#ifdef NSS_3_4_CODE
+ PK11SlotInfo *internal = PK11_GetInternalSlot();
+ NSSToken *token = PK11Slot_GetNSSToken(internal);
+#else
+ NSSToken *token = nss_GetDefaultCryptoToken();
+#endif
+ ap = NSSAlgorithmAndParameters_CreateSHA1Digest(NULL);
+ (void)nssToken_Digest(token, NULL, ap, input, output, NULL);
+#ifdef NSS_3_4_CODE
+ PK11_FreeSlot(token->pk11slot);
+#endif
+ nss_ZFreeIf(ap);
+}
+
+static void
+md5_hash(NSSItem *input, NSSItem *output)
+{
+ NSSAlgorithmAndParameters *ap;
+#ifdef NSS_3_4_CODE
+ PK11SlotInfo *internal = PK11_GetInternalSlot();
+ NSSToken *token = PK11Slot_GetNSSToken(internal);
+#else
+ NSSToken *token = nss_GetDefaultCryptoToken();
+#endif
+ ap = NSSAlgorithmAndParameters_CreateMD5Digest(NULL);
+ (void)nssToken_Digest(token, NULL, ap, input, output, NULL);
+#ifdef NSS_3_4_CODE
+ PK11_FreeSlot(token->pk11slot);
+#endif
+ nss_ZFreeIf(ap);
+}
+
+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 *sessionOpt,
+ 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;
+ PRUint8 sha1[20]; /* this is cheating... */
+ PRUint8 md5[16];
+ NSSItem sha1_result, md5_result;
+ sha1_result.data = sha1; sha1_result.size = sizeof sha1;
+ md5_result.data = md5; md5_result.size = sizeof md5;
+ sha1_hash(certEncoding, &sha1_result);
+ md5_hash(certEncoding, &md5_result);
+ 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);
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_SHA1_HASH, &sha1_result);
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_MD5_HASH, &md5_result);
+ /* 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, sessionOpt, trust_tmpl, tsize);
+ if (object && tok->cache) {
+ nssTokenObjectCache_ImportObject(tok->cache, object, tobjc,
+ trust_tmpl, tsize);
+ }
+ return object;
+}
+
+NSS_IMPLEMENT nssCryptokiObject **
+nssToken_FindTrustObjects
+(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ 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;
+ nssSession *session = sessionOpt ? sessionOpt : token->defaultSession;
+
+ 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 ||
+ searchType == nssTokenSearchType_TokenForced) {
+ 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);
+
+ if (searchType == nssTokenSearchType_TokenForced) {
+ objects = find_objects(token, session,
+ tobj_template, tobj_size,
+ maximumOpt, statusOpt);
+ } else {
+ objects = find_objects_by_template(token, session,
+ tobj_template, tobj_size,
+ maximumOpt, statusOpt);
+ }
+ return objects;
+}
+
+NSS_IMPLEMENT nssCryptokiObject *
+nssToken_FindTrustForCertificate
+(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ 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;
+ PRUint8 sha1[20]; /* this is cheating... */
+ NSSItem sha1_result;
+ nssSession *session = sessionOpt ? sessionOpt : token->defaultSession;
+ nssCryptokiObject *object, **objects;
+
+ sha1_result.data = sha1; sha1_result.size = sizeof sha1;
+ sha1_hash(certEncoding, &sha1_result);
+ 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_CERT_SHA1_HASH, &sha1_result);
+#ifdef NSS_3_4_CODE
+ if (!PK11_HasRootCerts(token->pk11slot)) {
+#endif
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, certIssuer);
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER , certSerial);
+#ifdef NSS_3_4_CODE
+ }
+ /*
+ * we need to arrange for the built-in token to lose the bottom 2
+ * attributes so that old built-in tokens will continue to work.
+ */
+#endif
+ 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 nssCryptokiObject *
+nssToken_ImportCRL
+(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ NSSDER *subject,
+ NSSDER *encoding,
+ PRBool isKRL,
+ NSSUTF8 *url,
+ PRBool asTokenObject
+)
+{
+ nssCryptokiObject *object;
+ CK_OBJECT_CLASS crlobjc = CKO_NETSCAPE_CRL;
+ CK_ATTRIBUTE_PTR attr;
+ CK_ATTRIBUTE crl_tmpl[6];
+ CK_ULONG crlsize;
+
+ NSS_CK_TEMPLATE_START(crl_tmpl, attr, crlsize);
+ 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, crlobjc);
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject);
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encoding);
+ NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NETSCAPE_URL, url);
+ if (isKRL) {
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_NETSCAPE_KRL, &g_ck_true);
+ } else {
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_NETSCAPE_KRL, &g_ck_false);
+ }
+ NSS_CK_TEMPLATE_FINISH(crl_tmpl, attr, crlsize);
+
+ /* import the crl object onto the token */
+ object = import_object(token, sessionOpt, crl_tmpl, crlsize);
+ if (object && token->cache) {
+ nssTokenObjectCache_ImportObject(token->cache, object, crlobjc,
+ crl_tmpl, crlsize);
+ }
+ return object;
+}
+
+NSS_IMPLEMENT nssCryptokiObject **
+nssToken_FindCRLs
+(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
+)
+{
+ CK_OBJECT_CLASS crlobjc = CKO_NETSCAPE_CRL;
+ CK_ATTRIBUTE_PTR attr;
+ CK_ATTRIBUTE crlobj_template[2];
+ CK_ULONG crlobj_size;
+ nssCryptokiObject **objects;
+ nssSession *session = sessionOpt ? sessionOpt : token->defaultSession;
+
+ NSS_CK_TEMPLATE_START(crlobj_template, attr, crlobj_size);
+ if (searchType == nssTokenSearchType_SessionOnly) {
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
+ } else if (searchType == nssTokenSearchType_TokenOnly ||
+ searchType == nssTokenSearchType_TokenForced) {
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
+ }
+ NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, crlobjc);
+ NSS_CK_TEMPLATE_FINISH(crlobj_template, attr, crlobj_size);
+
+ if (searchType == nssTokenSearchType_TokenForced) {
+ objects = find_objects(token, session,
+ crlobj_template, crlobj_size,
+ maximumOpt, statusOpt);
+ } else {
+ objects = find_objects_by_template(token, session,
+ crlobj_template, crlobj_size,
+ maximumOpt, statusOpt);
+ }
+ return objects;
+}
+
+NSS_IMPLEMENT nssCryptokiObject **
+nssToken_FindCRLsBySubject
+(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ NSSDER *subject,
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
+)
+{
+ CK_OBJECT_CLASS crlobjc = CKO_NETSCAPE_CRL;
+ CK_ATTRIBUTE_PTR attr;
+ CK_ATTRIBUTE crlobj_template[3];
+ CK_ULONG crlobj_size;
+ nssCryptokiObject **objects;
+ nssSession *session = sessionOpt ? sessionOpt : token->defaultSession;
+
+ NSS_CK_TEMPLATE_START(crlobj_template, attr, crlobj_size);
+ if (searchType == nssTokenSearchType_SessionOnly) {
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
+ } else if (searchType == nssTokenSearchType_TokenOnly ||
+ searchType == nssTokenSearchType_TokenForced) {
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
+ }
+ NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, crlobjc);
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject);
+ NSS_CK_TEMPLATE_FINISH(crlobj_template, attr, crlobj_size);
+
+ objects = find_objects_by_template(token, session,
+ crlobj_template, crlobj_size,
+ maximumOpt, statusOpt);
+ return objects;
}
NSS_IMPLEMENT PRStatus
-nssToken_SetHasCrls
+nssToken_GetCachedObjectAttributes
(
- NSSToken *tok
+ NSSToken *token,
+ NSSArena *arenaOpt,
+ nssCryptokiObject *object,
+ CK_OBJECT_CLASS objclass,
+ CK_ATTRIBUTE_PTR atemplate,
+ CK_ULONG atlen
)
{
- tok->hasNoCrls = PR_FALSE;
- return PR_SUCCESS;
+ if (!token->cache) {
+ return PR_FAILURE;
+ }
+ return nssTokenObjectCache_GetObjectAttributes(token->cache, arenaOpt,
+ object, objclass,
+ atemplate, atlen);
}
NSS_IMPLEMENT NSSItem *
@@ -315,17 +1399,18 @@ nssToken_Digest
CK_ULONG digestLen;
CK_BYTE_PTR digest;
NSSItem *rvItem = NULL;
+ void *epv = nssToken_GetCryptokiEPV(tok);
nssSession *session;
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
nssSession_EnterMonitor(session);
- ckrv = CKAPI(tok)->C_DigestInit(session->handle, &ap->mechanism);
+ ckrv = CKAPI(epv)->C_DigestInit(session->handle, &ap->mechanism);
if (ckrv != CKR_OK) {
nssSession_ExitMonitor(session);
return NULL;
}
#if 0
/* XXX the standard says this should work, but it doesn't */
- ckrv = CKAPI(tok)->C_Digest(session->handle, NULL, 0, NULL, &digestLen);
+ ckrv = CKAPI(epv)->C_Digest(session->handle, NULL, 0, NULL, &digestLen);
if (ckrv != CKR_OK) {
nssSession_ExitMonitor(session);
return NULL;
@@ -351,7 +1436,7 @@ nssToken_Digest
return NULL;
}
}
- ckrv = CKAPI(tok)->C_Digest(session->handle,
+ ckrv = CKAPI(epv)->C_Digest(session->handle,
(CK_BYTE_PTR)data->data,
(CK_ULONG)data->size,
(CK_BYTE_PTR)digest,
@@ -377,9 +1462,10 @@ nssToken_BeginDigest
{
CK_RV ckrv;
nssSession *session;
+ void *epv = nssToken_GetCryptokiEPV(tok);
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
nssSession_EnterMonitor(session);
- ckrv = CKAPI(tok)->C_DigestInit(session->handle, &ap->mechanism);
+ ckrv = CKAPI(epv)->C_DigestInit(session->handle, &ap->mechanism);
nssSession_ExitMonitor(session);
return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
}
@@ -394,9 +1480,10 @@ nssToken_ContinueDigest
{
CK_RV ckrv;
nssSession *session;
+ void *epv = nssToken_GetCryptokiEPV(tok);
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
nssSession_EnterMonitor(session);
- ckrv = CKAPI(tok)->C_DigestUpdate(session->handle,
+ ckrv = CKAPI(epv)->C_DigestUpdate(session->handle,
(CK_BYTE_PTR)item->data,
(CK_ULONG)item->size);
nssSession_ExitMonitor(session);
@@ -416,10 +1503,11 @@ nssToken_FinishDigest
CK_ULONG digestLen;
CK_BYTE_PTR digest;
NSSItem *rvItem = NULL;
+ void *epv = nssToken_GetCryptokiEPV(tok);
nssSession *session;
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
nssSession_EnterMonitor(session);
- ckrv = CKAPI(tok)->C_DigestFinal(session->handle, NULL, &digestLen);
+ ckrv = CKAPI(epv)->C_DigestFinal(session->handle, NULL, &digestLen);
if (ckrv != CKR_OK || digestLen == 0) {
nssSession_ExitMonitor(session);
return NULL;
@@ -443,7 +1531,7 @@ nssToken_FinishDigest
return NULL;
}
}
- ckrv = CKAPI(tok)->C_DigestFinal(session->handle, digest, &digestLen);
+ ckrv = CKAPI(epv)->C_DigestFinal(session->handle, digest, &digestLen);
nssSession_ExitMonitor(session);
if (ckrv != CKR_OK) {
nss_ZFreeIf(digest);
@@ -455,36 +1543,122 @@ nssToken_FinishDigest
return rvItem;
}
-/* XXX of course this doesn't belong here */
-NSS_IMPLEMENT NSSAlgorithmAndParameters *
-NSSAlgorithmAndParameters_CreateSHA1Digest
+NSS_IMPLEMENT PRBool
+nssToken_IsPresent
(
- NSSArena *arenaOpt
+ NSSToken *token
)
{
- NSSAlgorithmAndParameters *rvAP = NULL;
- rvAP = nss_ZNEW(arenaOpt, NSSAlgorithmAndParameters);
- if (rvAP) {
- rvAP->mechanism.mechanism = CKM_SHA_1;
- rvAP->mechanism.pParameter = NULL;
- rvAP->mechanism.ulParameterLen = 0;
- }
- return rvAP;
+ return nssSlot_IsTokenPresent(token->slot);
}
-NSS_IMPLEMENT NSSAlgorithmAndParameters *
-NSSAlgorithmAndParameters_CreateMD5Digest
+/* Sigh. The methods to find objects declared above cause problems with
+ * the low-level object cache in the softoken -- the objects are found in
+ * toto, then one wave of GetAttributes is done, then another. Having a
+ * large number of objects causes the cache to be thrashed, as the objects
+ * are gone before there's any chance to ask for their attributes.
+ * So, for now, bringing back traversal methods for certs. This way all of
+ * the cert's attributes can be grabbed immediately after finding it,
+ * increasing the likelihood that the cache takes care of it.
+ */
+NSS_IMPLEMENT PRStatus
+nssToken_TraverseCertificates
(
- NSSArena *arenaOpt
+ NSSToken *token,
+ nssSession *sessionOpt,
+ nssTokenSearchType searchType,
+ PRStatus (* callback)(nssCryptokiObject *instance, void *arg),
+ void *arg
)
{
- NSSAlgorithmAndParameters *rvAP = NULL;
- rvAP = nss_ZNEW(arenaOpt, NSSAlgorithmAndParameters);
- if (rvAP) {
- rvAP->mechanism.mechanism = CKM_MD5;
- rvAP->mechanism.pParameter = NULL;
- rvAP->mechanism.ulParameterLen = 0;
+ CK_RV ckrv;
+ CK_ULONG count;
+ CK_OBJECT_HANDLE *objectHandles;
+ CK_ATTRIBUTE_PTR attr;
+ CK_ATTRIBUTE cert_template[2];
+ CK_ULONG ctsize;
+ NSSArena *arena;
+ PRStatus status;
+ PRUint32 arraySize, numHandles;
+ nssCryptokiObject **objects;
+ void *epv = nssToken_GetCryptokiEPV(token);
+ nssSession *session = (sessionOpt) ? sessionOpt : token->defaultSession;
+
+ /* template for all certs */
+ NSS_CK_TEMPLATE_START(cert_template, attr, ctsize);
+ if (searchType == nssTokenSearchType_SessionOnly) {
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
+ } else if (searchType == nssTokenSearchType_TokenOnly ||
+ searchType == nssTokenSearchType_TokenForced) {
+ 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);
+
+ /* the arena is only for the array of object handles */
+ arena = nssArena_Create();
+ if (!arena) {
+ return PR_FAILURE;
}
- return rvAP;
+ arraySize = OBJECT_STACK_SIZE;
+ numHandles = 0;
+ objectHandles = nss_ZNEWARRAY(arena, CK_OBJECT_HANDLE, arraySize);
+ if (!objectHandles) {
+ goto loser;
+ }
+ nssSession_EnterMonitor(session); /* ==== session lock === */
+ /* Initialize the find with the template */
+ ckrv = CKAPI(epv)->C_FindObjectsInit(session->handle,
+ cert_template, ctsize);
+ if (ckrv != CKR_OK) {
+ nssSession_ExitMonitor(session);
+ goto loser;
+ }
+ while (PR_TRUE) {
+ /* Issue the find for up to arraySize - numHandles objects */
+ ckrv = CKAPI(epv)->C_FindObjects(session->handle,
+ objectHandles + numHandles,
+ arraySize - numHandles,
+ &count);
+ if (ckrv != CKR_OK) {
+ nssSession_ExitMonitor(session);
+ goto loser;
+ }
+ /* bump the number of found objects */
+ numHandles += count;
+ if (numHandles < arraySize) {
+ break;
+ }
+ /* the array is filled, double it and continue */
+ arraySize *= 2;
+ objectHandles = nss_ZREALLOCARRAY(objectHandles,
+ CK_OBJECT_HANDLE,
+ arraySize);
+ if (!objectHandles) {
+ nssSession_ExitMonitor(session);
+ goto loser;
+ }
+ }
+ ckrv = CKAPI(epv)->C_FindObjectsFinal(session->handle);
+ nssSession_ExitMonitor(session); /* ==== end session lock === */
+ if (ckrv != CKR_OK) {
+ goto loser;
+ }
+ if (numHandles > 0) {
+ objects = create_objects_from_handles(token, session,
+ objectHandles, numHandles);
+ if (objects) {
+ nssCryptokiObject **op;
+ for (op = objects; *op; op++) {
+ status = (*callback)(*op, arg);
+ }
+ nss_ZFreeIf(objects);
+ }
+ }
+ nssArena_Destroy(arena);
+ return PR_SUCCESS;
+loser:
+ nssArena_Destroy(arena);
+ return PR_FAILURE;
}
diff --git a/security/nss/lib/dev/devutil.c b/security/nss/lib/dev/devutil.c
index 02db7831b..99218f83d 100644
--- a/security/nss/lib/dev/devutil.c
+++ b/security/nss/lib/dev/devutil.c
@@ -39,14 +39,1407 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#include "devm.h"
#endif /* DEVM_H */
+#ifndef CKHELPER_H
+#include "ckhelper.h"
+#endif /* CKHELPER_H */
+
+NSS_IMPLEMENT nssCryptokiObject *
+nssCryptokiObject_Create
+(
+ NSSToken *t,
+ nssSession *session,
+ CK_OBJECT_HANDLE h
+)
+{
+ PRStatus status;
+ NSSSlot *slot;
+ nssCryptokiObject *object;
+ CK_BBOOL *isTokenObject;
+ CK_ATTRIBUTE cert_template[] = {
+ { CKA_TOKEN, NULL, 0 },
+ { CKA_LABEL, NULL, 0 }
+ };
+ slot = nssToken_GetSlot(t);
+ status = nssCKObject_GetAttributes(h, cert_template, 2,
+ NULL, session, slot);
+ nssSlot_Destroy(slot);
+ if (status != PR_SUCCESS) {
+ /* a failure here indicates a device error */
+ return (nssCryptokiObject *)NULL;
+ }
+ object = nss_ZNEW(NULL, nssCryptokiObject);
+ if (!object) {
+ return (nssCryptokiObject *)NULL;
+ }
+ object->handle = h;
+ object->token = nssToken_AddRef(t);
+ isTokenObject = (CK_BBOOL *)cert_template[0].pValue;
+ object->isTokenObject = *isTokenObject;
+ nss_ZFreeIf(isTokenObject);
+ NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[1], object->label);
+ return object;
+}
+
+NSS_IMPLEMENT void
+nssCryptokiObject_Destroy
+(
+ nssCryptokiObject *object
+)
+{
+ if (object) {
+ nssToken_Destroy(object->token);
+ nss_ZFreeIf(object->label);
+ nss_ZFreeIf(object);
+ }
+}
+
+NSS_IMPLEMENT nssCryptokiObject *
+nssCryptokiObject_Clone
+(
+ nssCryptokiObject *object
+)
+{
+ nssCryptokiObject *rvObject;
+ rvObject = nss_ZNEW(NULL, nssCryptokiObject);
+ if (rvObject) {
+ rvObject->handle = object->handle;
+ rvObject->token = nssToken_AddRef(object->token);
+ rvObject->isTokenObject = object->isTokenObject;
+ if (object->label) {
+ rvObject->label = nssUTF8_Duplicate(object->label, NULL);
+ }
+ }
+ return rvObject;
+}
+
+NSS_EXTERN PRBool
+nssCryptokiObject_Equal
+(
+ nssCryptokiObject *o1,
+ nssCryptokiObject *o2
+)
+{
+ return (o1->token == o2->token && o1->handle == o2->handle);
+}
+
NSS_IMPLEMENT PRUint32
-nssPKCS11StringLength(CK_CHAR *pkcs11Str, PRUint32 bufLen)
+nssPKCS11String_Length(CK_CHAR *pkcs11Str, PRUint32 bufLen)
{
PRInt32 i;
for (i = bufLen - 1; i>=0; ) {
- if (pkcs11Str[i] != ' ') break;
+ if (pkcs11Str[i] != ' ' && pkcs11Str[i] != '\0') break;
--i;
}
return (PRUint32)(i + 1);
}
+/*
+ * Slot arrays
+ */
+
+NSS_IMPLEMENT NSSSlot **
+nssSlotArray_Clone
+(
+ NSSSlot **slots
+)
+{
+ NSSSlot **rvSlots = NULL;
+ NSSSlot **sp = slots;
+ PRUint32 count = 0;
+ while (sp && *sp) count++;
+ if (count > 0) {
+ rvSlots = nss_ZNEWARRAY(NULL, NSSSlot *, count + 1);
+ if (rvSlots) {
+ sp = slots;
+ count = 0;
+ for (sp = slots; *sp; sp++) {
+ rvSlots[count++] = nssSlot_AddRef(*sp);
+ }
+ }
+ }
+ return rvSlots;
+}
+
+#ifdef PURE_STAN_BUILD
+NSS_IMPLEMENT void
+nssModuleArray_Destroy
+(
+ NSSModule **modules
+)
+{
+ if (modules) {
+ NSSModule **mp;
+ for (mp = modules; *mp; mp++) {
+ nssModule_Destroy(*mp);
+ }
+ nss_ZFreeIf(modules);
+ }
+}
+#endif
+
+NSS_IMPLEMENT void
+nssSlotArray_Destroy
+(
+ NSSSlot **slots
+)
+{
+ if (slots) {
+ NSSSlot **slotp;
+ for (slotp = slots; *slotp; slotp++) {
+ nssSlot_Destroy(*slotp);
+ }
+ nss_ZFreeIf(slots);
+ }
+}
+
+NSS_IMPLEMENT void
+NSSSlotArray_Destroy
+(
+ NSSSlot **slots
+)
+{
+ nssSlotArray_Destroy(slots);
+}
+
+NSS_IMPLEMENT void
+nssTokenArray_Destroy
+(
+ NSSToken **tokens
+)
+{
+ if (tokens) {
+ NSSToken **tokenp;
+ for (tokenp = tokens; *tokenp; tokenp++) {
+ nssToken_Destroy(*tokenp);
+ }
+ nss_ZFreeIf(tokens);
+ }
+}
+
+NSS_IMPLEMENT void
+NSSTokenArray_Destroy
+(
+ NSSToken **tokens
+)
+{
+ nssTokenArray_Destroy(tokens);
+}
+
+NSS_IMPLEMENT void
+nssCryptokiObjectArray_Destroy
+(
+ nssCryptokiObject **objects
+)
+{
+ if (objects) {
+ nssCryptokiObject **op;
+ for (op = objects; *op; op++) {
+ nssCryptokiObject_Destroy(*op);
+ }
+ nss_ZFreeIf(objects);
+ }
+}
+
+#ifdef PURE_STAN_BUILD
+/*
+ * Slot lists
+ */
+
+struct nssSlotListNodeStr
+{
+ PRCList link;
+ NSSSlot *slot;
+ PRUint32 order;
+};
+
+/* XXX separate slots with non-present tokens? */
+struct nssSlotListStr
+{
+ NSSArena *arena;
+ PRBool i_allocated_arena;
+ PZLock *lock;
+ PRCList head;
+ PRUint32 count;
+};
+
+NSS_IMPLEMENT nssSlotList *
+nssSlotList_Create
+(
+ NSSArena *arenaOpt
+)
+{
+ nssSlotList *rvList;
+ NSSArena *arena;
+ nssArenaMark *mark;
+ if (arenaOpt) {
+ arena = arenaOpt;
+ mark = nssArena_Mark(arena);
+ if (!mark) {
+ return (nssSlotList *)NULL;
+ }
+ } else {
+ arena = nssArena_Create();
+ if (!arena) {
+ return (nssSlotList *)NULL;
+ }
+ }
+ rvList = nss_ZNEW(arena, nssSlotList);
+ if (!rvList) {
+ goto loser;
+ }
+ rvList->lock = PZ_NewLock(nssILockOther); /* XXX */
+ if (!rvList->lock) {
+ goto loser;
+ }
+ PR_INIT_CLIST(&rvList->head);
+ rvList->arena = arena;
+ rvList->i_allocated_arena = (arenaOpt == NULL);
+ nssArena_Unmark(arena, mark);
+ return rvList;
+loser:
+ if (arenaOpt) {
+ nssArena_Release(arena, mark);
+ } else {
+ nssArena_Destroy(arena);
+ }
+ return (nssSlotList *)NULL;
+}
+
+NSS_IMPLEMENT void
+nssSlotList_Destroy
+(
+ nssSlotList *slotList
+)
+{
+ PRCList *link;
+ struct nssSlotListNodeStr *node;
+ if (slotList) {
+ link = PR_NEXT_LINK(&slotList->head);
+ while (link != &slotList->head) {
+ node = (struct nssSlotListNodeStr *)link;
+ nssSlot_Destroy(node->slot);
+ link = PR_NEXT_LINK(link);
+ }
+ if (slotList->i_allocated_arena) {
+ nssArena_Destroy(slotList->arena);
+ }
+ }
+}
+
+/* XXX should do allocs outside of lock */
+NSS_IMPLEMENT PRStatus
+nssSlotList_Add
+(
+ nssSlotList *slotList,
+ NSSSlot *slot,
+ PRUint32 order
+)
+{
+ PRCList *link;
+ struct nssSlotListNodeStr *node;
+ PZ_Lock(slotList->lock);
+ link = PR_NEXT_LINK(&slotList->head);
+ while (link != &slotList->head) {
+ node = (struct nssSlotListNodeStr *)link;
+ if (order < node->order) {
+ break;
+ }
+ link = PR_NEXT_LINK(link);
+ }
+ node = nss_ZNEW(slotList->arena, struct nssSlotListNodeStr);
+ if (!node) {
+ return PR_FAILURE;
+ }
+ PR_INIT_CLIST(&node->link);
+ node->slot = nssSlot_AddRef(slot);
+ node->order = order;
+ PR_INSERT_AFTER(&node->link, link);
+ slotList->count++;
+ PZ_Unlock(slotList->lock);
+ return PR_SUCCESS;
+}
+
+NSS_IMPLEMENT PRStatus
+nssSlotList_AddModuleSlots
+(
+ nssSlotList *slotList,
+ NSSModule *module,
+ PRUint32 order
+)
+{
+ nssArenaMark *mark = NULL;
+ NSSSlot **sp, **slots = NULL;
+ PRCList *link;
+ struct nssSlotListNodeStr *node;
+ PZ_Lock(slotList->lock);
+ link = PR_NEXT_LINK(&slotList->head);
+ while (link != &slotList->head) {
+ node = (struct nssSlotListNodeStr *)link;
+ if (order < node->order) {
+ break;
+ }
+ link = PR_NEXT_LINK(link);
+ }
+ slots = nssModule_GetSlots(module);
+ if (!slots) {
+ PZ_Unlock(slotList->lock);
+ return PR_SUCCESS;
+ }
+ mark = nssArena_Mark(slotList->arena);
+ if (!mark) {
+ goto loser;
+ }
+ for (sp = slots; *sp; sp++) {
+ node = nss_ZNEW(slotList->arena, struct nssSlotListNodeStr);
+ if (!node) {
+ goto loser;
+ }
+ PR_INIT_CLIST(&node->link);
+ node->slot = *sp; /* have ref from nssModule_GetSlots */
+ node->order = order;
+ PR_INSERT_AFTER(&node->link, link);
+ slotList->count++;
+ }
+ PZ_Unlock(slotList->lock);
+ nssArena_Unmark(slotList->arena, mark);
+ return PR_SUCCESS;
+loser:
+ PZ_Unlock(slotList->lock);
+ if (mark) {
+ nssArena_Release(slotList->arena, mark);
+ }
+ if (slots) {
+ nssSlotArray_Destroy(slots);
+ }
+ return PR_FAILURE;
+}
+
+NSS_IMPLEMENT NSSSlot **
+nssSlotList_GetSlots
+(
+ nssSlotList *slotList
+)
+{
+ PRUint32 i;
+ PRCList *link;
+ struct nssSlotListNodeStr *node;
+ NSSSlot **rvSlots = NULL;
+ PZ_Lock(slotList->lock);
+ rvSlots = nss_ZNEWARRAY(NULL, NSSSlot *, slotList->count + 1);
+ if (!rvSlots) {
+ PZ_Unlock(slotList->lock);
+ return (NSSSlot **)NULL;
+ }
+ i = 0;
+ link = PR_NEXT_LINK(&slotList->head);
+ while (link != &slotList->head) {
+ node = (struct nssSlotListNodeStr *)link;
+ rvSlots[i] = nssSlot_AddRef(node->slot);
+ link = PR_NEXT_LINK(link);
+ i++;
+ }
+ PZ_Unlock(slotList->lock);
+ return rvSlots;
+}
+
+#if 0
+NSS_IMPLEMENT NSSSlot *
+nssSlotList_GetBestSlotForAlgorithmAndParameters
+(
+ nssSlotList *slotList,
+ NSSAlgorithmAndParameters *ap
+)
+{
+ PRCList *link;
+ struct nssSlotListNodeStr *node;
+ NSSSlot *rvSlot = NULL;
+ PZ_Lock(slotList->lock);
+ link = PR_NEXT_LINK(&slotList->head);
+ while (link != &slotList->head) {
+ node = (struct nssSlotListNodeStr *)link;
+ if (nssSlot_DoesAlgorithmAndParameters(ap)) {
+ rvSlot = nssSlot_AddRef(node->slot); /* XXX check isPresent? */
+ }
+ link = PR_NEXT_LINK(link);
+ }
+ PZ_Unlock(slotList->lock);
+ return rvSlot;
+}
+#endif
+
+NSS_IMPLEMENT NSSSlot *
+nssSlotList_GetBestSlot
+(
+ nssSlotList *slotList
+)
+{
+ PRCList *link;
+ struct nssSlotListNodeStr *node;
+ NSSSlot *rvSlot = NULL;
+ PZ_Lock(slotList->lock);
+ if (PR_CLIST_IS_EMPTY(&slotList->head)) {
+ PZ_Unlock(slotList->lock);
+ return (NSSSlot *)NULL;
+ }
+ link = PR_NEXT_LINK(&slotList->head);
+ node = (struct nssSlotListNodeStr *)link;
+ rvSlot = nssSlot_AddRef(node->slot); /* XXX check isPresent? */
+ PZ_Unlock(slotList->lock);
+ return rvSlot;
+}
+
+NSS_IMPLEMENT NSSSlot *
+nssSlotList_FindSlotByName
+(
+ nssSlotList *slotList,
+ NSSUTF8 *slotName
+)
+{
+ PRCList *link;
+ struct nssSlotListNodeStr *node;
+ NSSSlot *rvSlot = NULL;
+ PZ_Lock(slotList->lock);
+ link = PR_NEXT_LINK(&slotList->head);
+ while (link != &slotList->head) {
+ NSSUTF8 *sName;
+ node = (struct nssSlotListNodeStr *)link;
+ sName = nssSlot_GetName(node->slot);
+ if (nssUTF8_Equal(sName, slotName, NULL)) {
+ rvSlot = nssSlot_AddRef(node->slot);
+ break;
+ }
+ link = PR_NEXT_LINK(link);
+ }
+ PZ_Unlock(slotList->lock);
+ return rvSlot;
+}
+
+NSS_IMPLEMENT NSSToken *
+nssSlotList_FindTokenByName
+(
+ nssSlotList *slotList,
+ NSSUTF8 *tokenName
+)
+{
+ PRCList *link;
+ struct nssSlotListNodeStr *node;
+ NSSToken *rvToken = NULL;
+ PZ_Lock(slotList->lock);
+ link = PR_NEXT_LINK(&slotList->head);
+ while (link != &slotList->head) {
+ NSSUTF8 *tName;
+ node = (struct nssSlotListNodeStr *)link;
+ tName = nssSlot_GetTokenName(node->slot);
+ if (nssUTF8_Equal(tName, tokenName, NULL)) {
+ rvToken = nssSlot_GetToken(node->slot);
+ break;
+ }
+ link = PR_NEXT_LINK(link);
+ }
+ PZ_Unlock(slotList->lock);
+ return rvToken;
+}
+#endif /* PURE_STAN_BUILD */
+
+/* object cache for token */
+
+typedef struct
+{
+ NSSArena *arena;
+ nssCryptokiObject *object;
+ CK_ATTRIBUTE_PTR attributes;
+ CK_ULONG numAttributes;
+}
+nssCryptokiObjectAndAttributes;
+
+enum {
+ cachedCerts = 0,
+ cachedTrust = 1,
+ cachedCRLs = 2
+} cachedObjectType;
+
+struct nssTokenObjectCacheStr
+{
+ NSSToken *token;
+ PZLock *lock;
+ PRBool loggedIn;
+ PRBool doObjectType[3];
+ PRBool searchedObjectType[3];
+ nssCryptokiObjectAndAttributes **objects[3];
+};
+
+NSS_IMPLEMENT nssTokenObjectCache *
+nssTokenObjectCache_Create
+(
+ NSSToken *token,
+ PRBool cacheCerts,
+ PRBool cacheTrust,
+ PRBool cacheCRLs
+)
+{
+ nssTokenObjectCache *rvCache;
+ rvCache = nss_ZNEW(NULL, nssTokenObjectCache);
+ if (!rvCache) {
+ goto loser;
+ }
+ rvCache->lock = PZ_NewLock(nssILockOther); /* XXX */
+ if (!rvCache->lock) {
+ goto loser;
+ }
+ rvCache->doObjectType[cachedCerts] = cacheCerts;
+ rvCache->doObjectType[cachedTrust] = cacheTrust;
+ rvCache->doObjectType[cachedCRLs] = cacheCRLs;
+ rvCache->token = token; /* cache goes away with token */
+ return rvCache;
+loser:
+ return (nssTokenObjectCache *)NULL;
+}
+
+static void
+clear_cache
+(
+ nssTokenObjectCache *cache
+)
+{
+ nssCryptokiObjectAndAttributes **oa;
+ PRUint32 objectType;
+ for (objectType = cachedCerts; objectType <= cachedCRLs; objectType++) {
+ if (!cache->objects[objectType]) {
+ continue;
+ }
+ for (oa = cache->objects[objectType]; *oa; oa++) {
+ /* prevent the token from being destroyed */
+ (*oa)->object->token = NULL;
+ nssCryptokiObject_Destroy((*oa)->object);
+ nssArena_Destroy((*oa)->arena);
+ }
+ nss_ZFreeIf(cache->objects[objectType]);
+ cache->objects[objectType] = NULL;
+ cache->searchedObjectType[objectType] = PR_FALSE;
+ }
+}
+
+NSS_IMPLEMENT void
+nssTokenObjectCache_Clear
+(
+ nssTokenObjectCache *cache
+)
+{
+ if (cache) {
+ clear_cache(cache);
+ }
+}
+
+NSS_IMPLEMENT void
+nssTokenObjectCache_Destroy
+(
+ nssTokenObjectCache *cache
+)
+{
+ if (cache) {
+ clear_cache(cache);
+ PZ_DestroyLock(cache->lock);
+ nss_ZFreeIf(cache);
+ }
+}
+
+NSS_IMPLEMENT PRBool
+nssTokenObjectCache_HaveObjectClass
+(
+ nssTokenObjectCache *cache,
+ CK_OBJECT_CLASS objclass
+)
+{
+ PRBool haveIt;
+ PZ_Lock(cache->lock);
+ switch (objclass) {
+ case CKO_CERTIFICATE: haveIt = cache->doObjectType[cachedCerts]; break;
+ case CKO_NETSCAPE_TRUST: haveIt = cache->doObjectType[cachedTrust]; break;
+ case CKO_NETSCAPE_CRL: haveIt = cache->doObjectType[cachedCRLs]; break;
+ default: haveIt = PR_FALSE;
+ }
+ PZ_Unlock(cache->lock);
+ return haveIt;
+}
+
+static nssCryptokiObjectAndAttributes **
+create_object_array
+(
+ nssCryptokiObject **objects,
+ PRBool *doObjects,
+ PRUint32 *numObjects,
+ PRStatus *status
+)
+{
+ nssCryptokiObject **op = objects;
+ nssCryptokiObjectAndAttributes **rvOandA = NULL;
+ *numObjects = 0;
+ /* There are no objects for this type */
+ if (!objects) {
+ return (nssCryptokiObjectAndAttributes **)NULL;
+ }
+ while (*op++) (*numObjects)++;
+ if (*numObjects == MAX_LOCAL_CACHE_OBJECTS) {
+ /* Hit the maximum allowed, so don't use a cache (there are
+ * too many objects to make caching worthwhile, presumably, if
+ * the token can handle that many objects, it can handle searching.
+ */
+ *doObjects = PR_FALSE;
+ *status = PR_FAILURE;
+ *numObjects = 0;
+ } else if (*numObjects > 0) {
+ rvOandA = nss_ZNEWARRAY(NULL,
+ nssCryptokiObjectAndAttributes *,
+ *numObjects + 1);
+ *status = rvOandA ? PR_SUCCESS : PR_FALSE;
+ }
+ return rvOandA;
+}
+
+static nssCryptokiObjectAndAttributes *
+create_object
+(
+ nssCryptokiObject *object,
+ CK_ATTRIBUTE_TYPE *types,
+ PRUint32 numTypes,
+ PRStatus *status
+)
+{
+ PRUint32 j;
+ NSSArena *arena;
+ NSSSlot *slot = NULL;
+ nssSession *session = NULL;
+ nssCryptokiObjectAndAttributes *rvCachedObject = NULL;
+
+ slot = nssToken_GetSlot(object->token);
+ session = nssToken_GetDefaultSession(object->token);
+
+ arena = nssArena_Create();
+ if (!arena) {
+ nssSlot_Destroy(slot);
+ return (nssCryptokiObjectAndAttributes *)NULL;
+ }
+ rvCachedObject = nss_ZNEW(arena, nssCryptokiObjectAndAttributes);
+ if (!rvCachedObject) {
+ goto loser;
+ }
+ rvCachedObject->arena = arena;
+ /* The cache is tied to the token, and therefore the objects
+ * in it should not hold references to the token.
+ */
+ nssToken_Destroy(object->token);
+ rvCachedObject->object = object;
+ rvCachedObject->attributes = nss_ZNEWARRAY(arena, CK_ATTRIBUTE, numTypes);
+ if (!rvCachedObject->attributes) {
+ goto loser;
+ }
+ for (j=0; j<numTypes; j++) {
+ rvCachedObject->attributes[j].type = types[j];
+ }
+ *status = nssCKObject_GetAttributes(object->handle,
+ rvCachedObject->attributes,
+ numTypes,
+ arena,
+ session,
+ slot);
+ if (*status != PR_SUCCESS) {
+ goto loser;
+ }
+ rvCachedObject->numAttributes = numTypes;
+ *status = PR_SUCCESS;
+ if (slot) {
+ nssSlot_Destroy(slot);
+ }
+ return rvCachedObject;
+loser:
+ *status = PR_FAILURE;
+ if (slot) {
+ nssSlot_Destroy(slot);
+ }
+ nssArena_Destroy(arena);
+ return (nssCryptokiObjectAndAttributes *)NULL;
+}
+
+/*
+ *
+ * State diagram for cache:
+ *
+ * token !present token removed
+ * +-------------------------+<----------------------+
+ * | ^ |
+ * v | |
+ * +----------+ slot friendly | token present +----------+
+ * | cache | -----------------> % ---------------> | cache |
+ * | unloaded | | loaded |
+ * +----------+ +----------+
+ * ^ | ^ |
+ * | | slot !friendly slot logged in | |
+ * | +-----------------------> % ----------------------+ |
+ * | | |
+ * | slot logged out v slot !friendly |
+ * +-----------------------------+<--------------------------+
+ *
+ */
+static PRBool
+search_for_objects
+(
+ nssTokenObjectCache *cache
+)
+{
+ PRBool doSearch = PR_FALSE;
+ NSSSlot *slot = nssToken_GetSlot(cache->token);
+ if (!nssSlot_IsTokenPresent(slot)) {
+ /* The token is no longer present, destroy any cached objects */
+ /* clear_cache(cache); */
+ nssSlot_Destroy(slot);
+ return PR_FALSE;
+ }
+ /* Handle non-friendly slots (slots which require login for objects) */
+ if (!nssSlot_IsFriendly(slot)) {
+ if (nssSlot_IsLoggedIn(slot)) {
+ /* Either no state change, or went from !logged in -> logged in */
+ cache->loggedIn = PR_TRUE;
+ doSearch = PR_TRUE;
+ } else {
+ if (cache->loggedIn) {
+ /* went from logged in -> !logged in, destroy cached objects */
+ clear_cache(cache);
+ cache->loggedIn = PR_FALSE;
+ } /* else no state change, still not logged in, so exit */
+ }
+ } else {
+ /* slot is friendly, thus always available for search */
+ doSearch = PR_TRUE;
+ }
+ nssSlot_Destroy(slot);
+ return doSearch;
+}
+
+static nssCryptokiObjectAndAttributes *
+create_cert
+(
+ nssCryptokiObject *object,
+ PRStatus *status
+)
+{
+ CK_ATTRIBUTE_TYPE certAttr[] = {
+ CKA_CLASS,
+ CKA_TOKEN,
+ CKA_LABEL,
+ CKA_CERTIFICATE_TYPE,
+ CKA_ID,
+ CKA_VALUE,
+ CKA_ISSUER,
+ CKA_SERIAL_NUMBER,
+ CKA_SUBJECT,
+ CKA_NETSCAPE_EMAIL
+ };
+ PRUint32 numCertAttr = sizeof(certAttr) / sizeof(certAttr[0]);
+ return create_object(object, certAttr, numCertAttr, status);
+}
+
+static PRStatus
+get_token_certs_for_cache
+(
+ nssTokenObjectCache *cache
+)
+{
+ PRStatus status;
+ nssCryptokiObject **objects;
+ PRBool *doIt = &cache->doObjectType[cachedCerts];
+ PRUint32 i, numObjects;
+
+ if (!search_for_objects(cache) ||
+ cache->searchedObjectType[cachedCerts] ||
+ !cache->doObjectType[cachedCerts])
+ {
+ /* Either there was a state change that prevents a search
+ * (token removed or logged out), or the search was already done,
+ * or certs are not being cached.
+ */
+ return PR_SUCCESS;
+ }
+ objects = nssToken_FindCertificates(cache->token, NULL,
+ nssTokenSearchType_TokenForced,
+ MAX_LOCAL_CACHE_OBJECTS, &status);
+ if (status != PR_SUCCESS) {
+ return status;
+ }
+ cache->objects[cachedCerts] = create_object_array(objects,
+ doIt,
+ &numObjects,
+ &status);
+ if (status != PR_SUCCESS) {
+ return status;
+ }
+ for (i=0; i<numObjects; i++) {
+ cache->objects[cachedCerts][i] = create_cert(objects[i], &status);
+ if (status != PR_SUCCESS) {
+ break;
+ }
+ }
+ if (status == PR_SUCCESS) {
+ nss_ZFreeIf(objects);
+ } else {
+ PRUint32 j;
+ for (j=0; j<i; j++) {
+ /* sigh */
+ nssToken_AddRef(cache->objects[cachedCerts][i]->object->token);
+ nssArena_Destroy(cache->objects[cachedCerts][i]->arena);
+ }
+ nssCryptokiObjectArray_Destroy(objects);
+ }
+ cache->searchedObjectType[cachedCerts] = PR_TRUE;
+ return status;
+}
+
+static nssCryptokiObjectAndAttributes *
+create_trust
+(
+ nssCryptokiObject *object,
+ PRStatus *status
+)
+{
+ CK_ATTRIBUTE_TYPE trustAttr[] = {
+ CKA_CLASS,
+ CKA_TOKEN,
+ CKA_LABEL,
+ CKA_CERT_SHA1_HASH,
+ CKA_CERT_MD5_HASH,
+ CKA_ISSUER,
+ CKA_SUBJECT,
+ CKA_TRUST_SERVER_AUTH,
+ CKA_TRUST_CLIENT_AUTH,
+ CKA_TRUST_EMAIL_PROTECTION,
+ CKA_TRUST_CODE_SIGNING
+ };
+ PRUint32 numTrustAttr = sizeof(trustAttr) / sizeof(trustAttr[0]);
+ return create_object(object, trustAttr, numTrustAttr, status);
+}
+
+static PRStatus
+get_token_trust_for_cache
+(
+ nssTokenObjectCache *cache
+)
+{
+ PRStatus status;
+ nssCryptokiObject **objects;
+ PRBool *doIt = &cache->doObjectType[cachedTrust];
+ PRUint32 i, numObjects;
+
+ if (!search_for_objects(cache) ||
+ cache->searchedObjectType[cachedTrust] ||
+ !cache->doObjectType[cachedTrust])
+ {
+ /* Either there was a state change that prevents a search
+ * (token removed or logged out), or the search was already done,
+ * or trust is not being cached.
+ */
+ return PR_SUCCESS;
+ }
+ objects = nssToken_FindTrustObjects(cache->token, NULL,
+ nssTokenSearchType_TokenForced,
+ MAX_LOCAL_CACHE_OBJECTS, &status);
+ if (status != PR_SUCCESS) {
+ return status;
+ }
+ cache->objects[cachedTrust] = create_object_array(objects,
+ doIt,
+ &numObjects,
+ &status);
+ if (status != PR_SUCCESS) {
+ return status;
+ }
+ for (i=0; i<numObjects; i++) {
+ cache->objects[cachedTrust][i] = create_trust(objects[i], &status);
+ if (status != PR_SUCCESS) {
+ break;
+ }
+ }
+ if (status == PR_SUCCESS) {
+ nss_ZFreeIf(objects);
+ } else {
+ PRUint32 j;
+ for (j=0; j<i; j++) {
+ /* sigh */
+ nssToken_AddRef(cache->objects[cachedTrust][i]->object->token);
+ nssArena_Destroy(cache->objects[cachedTrust][i]->arena);
+ }
+ nssCryptokiObjectArray_Destroy(objects);
+ }
+ cache->searchedObjectType[cachedTrust] = PR_TRUE;
+ return status;
+}
+
+static nssCryptokiObjectAndAttributes *
+create_crl
+(
+ nssCryptokiObject *object,
+ PRStatus *status
+)
+{
+ CK_ATTRIBUTE_TYPE crlAttr[] = {
+ CKA_CLASS,
+ CKA_TOKEN,
+ CKA_LABEL,
+ CKA_VALUE,
+ CKA_SUBJECT,
+ CKA_NETSCAPE_KRL,
+ CKA_NETSCAPE_URL
+ };
+ PRUint32 numCRLAttr = sizeof(crlAttr) / sizeof(crlAttr[0]);
+ return create_object(object, crlAttr, numCRLAttr, status);
+}
+
+static PRStatus
+get_token_crls_for_cache
+(
+ nssTokenObjectCache *cache
+)
+{
+ PRStatus status;
+ nssCryptokiObject **objects;
+ PRBool *doIt = &cache->doObjectType[cachedCRLs];
+ PRUint32 i, numObjects;
+
+ if (!search_for_objects(cache) ||
+ cache->searchedObjectType[cachedCRLs] ||
+ !cache->doObjectType[cachedCRLs])
+ {
+ /* Either there was a state change that prevents a search
+ * (token removed or logged out), or the search was already done,
+ * or CRLs are not being cached.
+ */
+ return PR_SUCCESS;
+ }
+ objects = nssToken_FindCRLs(cache->token, NULL,
+ nssTokenSearchType_TokenForced,
+ MAX_LOCAL_CACHE_OBJECTS, &status);
+ if (status != PR_SUCCESS) {
+ return status;
+ }
+ cache->objects[cachedCRLs] = create_object_array(objects,
+ doIt,
+ &numObjects,
+ &status);
+ if (status != PR_SUCCESS) {
+ return status;
+ }
+ for (i=0; i<numObjects; i++) {
+ cache->objects[cachedCRLs][i] = create_crl(objects[i], &status);
+ if (status != PR_SUCCESS) {
+ break;
+ }
+ }
+ if (status == PR_SUCCESS) {
+ nss_ZFreeIf(objects);
+ } else {
+ PRUint32 j;
+ for (j=0; j<i; j++) {
+ /* sigh */
+ nssToken_AddRef(cache->objects[cachedCRLs][i]->object->token);
+ nssArena_Destroy(cache->objects[cachedCRLs][i]->arena);
+ }
+ nssCryptokiObjectArray_Destroy(objects);
+ }
+ cache->searchedObjectType[cachedCRLs] = PR_TRUE;
+ return status;
+}
+
+static nssCryptokiObject **
+find_objects_in_array
+(
+ nssCryptokiObjectAndAttributes **objArray,
+ CK_ATTRIBUTE_PTR ot,
+ CK_ULONG otlen,
+ PRUint32 maximumOpt
+)
+{
+ PRIntn oi;
+ PRUint32 i, j;
+ PRBool match;
+ NSSArena *arena;
+ PRUint32 size = 8;
+ PRUint32 numMatches = 0;
+ nssCryptokiObject **objects = NULL;
+ nssCryptokiObjectAndAttributes **matches = NULL;
+ if (!objArray) {
+ return (nssCryptokiObject **)NULL;
+ }
+ arena = nssArena_Create();
+ if (!arena) {
+ return (nssCryptokiObject **)NULL;
+ }
+ matches = nss_ZNEWARRAY(arena, nssCryptokiObjectAndAttributes *, size);
+ if (!matches) {
+ goto loser;
+ }
+ if (maximumOpt == 0) maximumOpt = ~0;
+ for (; *objArray && numMatches < maximumOpt; objArray++) {
+ nssCryptokiObjectAndAttributes *obj = *objArray;
+ for (i=0; i<otlen; i++) {
+ for (j=0; j<obj->numAttributes; j++) {
+ if (ot[i].type == obj->attributes[j].type) {
+ if (ot[i].ulValueLen == obj->attributes[j].ulValueLen &&
+ nsslibc_memequal(ot[i].pValue,
+ obj->attributes[j].pValue,
+ ot[i].ulValueLen, NULL))
+ {
+ match = PR_TRUE;
+ } else {
+ match = PR_FALSE;
+ }
+ break;
+ }
+ }
+ if (j == obj->numAttributes || !match) {
+ break;
+ }
+ }
+ if (match) {
+ matches[numMatches++] = obj;
+ if (numMatches == size) {
+ size *= 2;
+ matches = nss_ZREALLOCARRAY(matches,
+ nssCryptokiObjectAndAttributes *,
+ size);
+ if (!matches) {
+ goto loser;
+ }
+ }
+ }
+ }
+ if (numMatches > 0) {
+ objects = nss_ZNEWARRAY(NULL, nssCryptokiObject *, numMatches + 1);
+ if (!objects) {
+ goto loser;
+ }
+ for (oi=0; oi<(PRIntn)numMatches; oi++) {
+ objects[oi] = nssCryptokiObject_Clone(matches[oi]->object);
+ if (!objects[oi]) {
+ goto loser;
+ }
+ }
+ }
+ nssArena_Destroy(arena);
+ return objects;
+loser:
+ if (objects) {
+ for (--oi; oi>=0; --oi) {
+ nssCryptokiObject_Destroy(objects[oi]);
+ }
+ }
+ nssArena_Destroy(arena);
+ return (nssCryptokiObject **)NULL;
+}
+
+NSS_IMPLEMENT nssCryptokiObject **
+nssTokenObjectCache_FindObjectsByTemplate
+(
+ nssTokenObjectCache *cache,
+ CK_OBJECT_CLASS objclass,
+ CK_ATTRIBUTE_PTR otemplate,
+ CK_ULONG otlen,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
+)
+{
+ PRStatus status = PR_FAILURE;
+ nssCryptokiObject **rvObjects = NULL;
+ PZ_Lock(cache->lock);
+ switch (objclass) {
+ case CKO_CERTIFICATE:
+ if (cache->doObjectType[cachedCerts]) {
+ status = get_token_certs_for_cache(cache);
+ if (status != PR_SUCCESS) {
+ goto finish;
+ }
+ rvObjects = find_objects_in_array(cache->objects[cachedCerts],
+ otemplate, otlen, maximumOpt);
+ }
+ break;
+ case CKO_NETSCAPE_TRUST:
+ if (cache->doObjectType[cachedTrust]) {
+ status = get_token_trust_for_cache(cache);
+ if (status != PR_SUCCESS) {
+ goto finish;
+ }
+ rvObjects = find_objects_in_array(cache->objects[cachedTrust],
+ otemplate, otlen, maximumOpt);
+ }
+ break;
+ case CKO_NETSCAPE_CRL:
+ if (cache->doObjectType[cachedCRLs]) {
+ status = get_token_crls_for_cache(cache);
+ if (status != PR_SUCCESS) {
+ goto finish;
+ }
+ rvObjects = find_objects_in_array(cache->objects[cachedCRLs],
+ otemplate, otlen, maximumOpt);
+ }
+ break;
+ default: break;
+ }
+finish:
+ PZ_Unlock(cache->lock);
+ if (statusOpt) {
+ *statusOpt = status;
+ }
+ return rvObjects;
+}
+
+static PRBool
+cache_available_for_object_type
+(
+ nssTokenObjectCache *cache,
+ PRUint32 objectType
+)
+{
+ if (!cache->doObjectType[objectType]) {
+ /* not caching this object kind */
+ return PR_FALSE;
+ }
+ if (!cache->searchedObjectType[objectType]) {
+ /* objects are not cached yet */
+ return PR_FALSE;
+ }
+ if (!search_for_objects(cache)) {
+ /* not logged in or removed */
+ return PR_FALSE;
+ }
+ return PR_TRUE;
+}
+
+NSS_IMPLEMENT PRStatus
+nssTokenObjectCache_GetObjectAttributes
+(
+ nssTokenObjectCache *cache,
+ NSSArena *arenaOpt,
+ nssCryptokiObject *object,
+ CK_OBJECT_CLASS objclass,
+ CK_ATTRIBUTE_PTR atemplate,
+ CK_ULONG atlen
+)
+{
+ PRUint32 i, j;
+ NSSArena *arena = NULL;
+ nssArenaMark *mark = NULL;
+ nssCryptokiObjectAndAttributes *cachedOA = NULL;
+ nssCryptokiObjectAndAttributes **oa = NULL;
+ PRUint32 objectType;
+ PZ_Lock(cache->lock);
+ switch (objclass) {
+ case CKO_CERTIFICATE: objectType = cachedCerts; break;
+ case CKO_NETSCAPE_TRUST: objectType = cachedTrust; break;
+ case CKO_NETSCAPE_CRL: objectType = cachedCRLs; break;
+ default: goto loser;
+ }
+ if (!cache_available_for_object_type(cache, objectType)) {
+ goto loser;
+ }
+ oa = cache->objects[objectType];
+ if (!oa) {
+ goto loser;
+ }
+ for (; *oa; oa++) {
+ if (nssCryptokiObject_Equal((*oa)->object, object)) {
+ cachedOA = *oa;
+ break;
+ }
+ }
+ if (!cachedOA) {
+ goto loser; /* don't have this object */
+ }
+ if (arenaOpt) {
+ arena = arenaOpt;
+ mark = nssArena_Mark(arena);
+ }
+ for (i=0; i<atlen; i++) {
+ for (j=0; j<cachedOA->numAttributes; j++) {
+ if (atemplate[i].type == cachedOA->attributes[j].type) {
+ CK_ATTRIBUTE_PTR attr = &cachedOA->attributes[j];
+ if (cachedOA->attributes[j].ulValueLen == 0 ||
+ cachedOA->attributes[j].ulValueLen == (CK_ULONG)-1)
+ {
+ break; /* invalid attribute */
+ }
+ if (atemplate[i].ulValueLen > 0) {
+ if (atemplate[i].pValue == NULL ||
+ atemplate[i].ulValueLen < attr->ulValueLen)
+ {
+ goto loser;
+ }
+ } else {
+ atemplate[i].pValue = nss_ZAlloc(arena, attr->ulValueLen);
+ if (!atemplate[i].pValue) {
+ goto loser;
+ }
+ }
+ nsslibc_memcpy(atemplate[i].pValue,
+ attr->pValue, attr->ulValueLen);
+ atemplate[i].ulValueLen = attr->ulValueLen;
+ break;
+ }
+ }
+ if (j == cachedOA->numAttributes) {
+ atemplate[i].ulValueLen = (CK_ULONG)-1;
+ }
+ }
+ PZ_Unlock(cache->lock);
+ if (mark) {
+ nssArena_Unmark(arena, mark);
+ }
+ return PR_SUCCESS;
+loser:
+ PZ_Unlock(cache->lock);
+ if (mark) {
+ nssArena_Release(arena, mark);
+ }
+ return PR_FAILURE;
+}
+
+NSS_IMPLEMENT PRStatus
+nssTokenObjectCache_ImportObject
+(
+ nssTokenObjectCache *cache,
+ nssCryptokiObject *object,
+ CK_OBJECT_CLASS objclass,
+ CK_ATTRIBUTE_PTR ot,
+ CK_ULONG otlen
+)
+{
+ PRStatus status = PR_SUCCESS;
+ PRUint32 count;
+ nssCryptokiObjectAndAttributes **oa, ***otype;
+ PRUint32 objectType;
+ PRBool haveIt = PR_FALSE;
+
+ PZ_Lock(cache->lock);
+ switch (objclass) {
+ case CKO_CERTIFICATE: objectType = cachedCerts; break;
+ case CKO_NETSCAPE_TRUST: objectType = cachedTrust; break;
+ case CKO_NETSCAPE_CRL: objectType = cachedCRLs; break;
+ default:
+ PZ_Unlock(cache->lock);
+ return PR_SUCCESS; /* don't need to import it here */
+ }
+ if (!cache_available_for_object_type(cache, objectType)) {
+ PZ_Unlock(cache->lock);
+ return PR_SUCCESS; /* cache not active, ignored */
+ }
+ count = 0;
+ otype = &cache->objects[objectType]; /* index into array of types */
+ oa = *otype; /* the array of objects for this type */
+ while (oa && *oa) {
+ if (nssCryptokiObject_Equal((*oa)->object, object)) {
+ haveIt = PR_TRUE;
+ break;
+ }
+ count++;
+ oa++;
+ }
+ if (haveIt) {
+ /* Destroy the old entry */
+ (*oa)->object->token = NULL;
+ nssCryptokiObject_Destroy((*oa)->object);
+ nssArena_Destroy((*oa)->arena);
+ } else {
+ /* Create space for a new entry */
+ if (count > 0) {
+ *otype = nss_ZREALLOCARRAY(*otype,
+ nssCryptokiObjectAndAttributes *,
+ count + 2);
+ } else {
+ *otype = nss_ZNEWARRAY(NULL, nssCryptokiObjectAndAttributes *, 2);
+ }
+ }
+ if (*otype) {
+ nssCryptokiObject *copyObject = nssCryptokiObject_Clone(object);
+ if (objectType == cachedCerts) {
+ (*otype)[count] = create_cert(copyObject, &status);
+ } else if (objectType == cachedTrust) {
+ (*otype)[count] = create_trust(copyObject, &status);
+ } else if (objectType == cachedCRLs) {
+ (*otype)[count] = create_crl(copyObject, &status);
+ }
+ } else {
+ status = PR_FAILURE;
+ }
+ PZ_Unlock(cache->lock);
+ return status;
+}
+
+NSS_IMPLEMENT void
+nssTokenObjectCache_RemoveObject
+(
+ nssTokenObjectCache *cache,
+ nssCryptokiObject *object
+)
+{
+ PRUint32 oType;
+ nssCryptokiObjectAndAttributes **oa, **swp = NULL;
+ PZ_Lock(cache->lock);
+ for (oType=0; oType<3; oType++) {
+ if (!cache_available_for_object_type(cache, oType) ||
+ !cache->objects[oType])
+ {
+ continue;
+ }
+ for (oa = cache->objects[oType]; *oa; oa++) {
+ if (nssCryptokiObject_Equal((*oa)->object, object)) {
+ swp = oa; /* the entry to remove */
+ while (oa[1]) oa++; /* go to the tail */
+ (*swp)->object->token = NULL;
+ nssCryptokiObject_Destroy((*swp)->object);
+ nssArena_Destroy((*swp)->arena); /* destroy it */
+ *swp = *oa; /* swap the last with the removed */
+ *oa = NULL; /* null-terminate the array */
+ break;
+ }
+ }
+ if (swp) {
+ break;
+ }
+ }
+ if ((oType <3) &&
+ cache->objects[oType] && cache->objects[oType][0] == NULL) {
+ nss_ZFreeIf(cache->objects[oType]); /* no entries remaining */
+ cache->objects[oType] = NULL;
+ }
+ PZ_Unlock(cache->lock);
+}
+
+/* XXX of course this doesn't belong here */
+NSS_IMPLEMENT NSSAlgorithmAndParameters *
+NSSAlgorithmAndParameters_CreateSHA1Digest
+(
+ NSSArena *arenaOpt
+)
+{
+ NSSAlgorithmAndParameters *rvAP = NULL;
+ rvAP = nss_ZNEW(arenaOpt, NSSAlgorithmAndParameters);
+ if (rvAP) {
+ rvAP->mechanism.mechanism = CKM_SHA_1;
+ rvAP->mechanism.pParameter = NULL;
+ rvAP->mechanism.ulParameterLen = 0;
+ }
+ return rvAP;
+}
+
+NSS_IMPLEMENT NSSAlgorithmAndParameters *
+NSSAlgorithmAndParameters_CreateMD5Digest
+(
+ NSSArena *arenaOpt
+)
+{
+ NSSAlgorithmAndParameters *rvAP = NULL;
+ rvAP = nss_ZNEW(arenaOpt, NSSAlgorithmAndParameters);
+ if (rvAP) {
+ rvAP->mechanism.mechanism = CKM_MD5;
+ rvAP->mechanism.pParameter = NULL;
+ rvAP->mechanism.ulParameterLen = 0;
+ }
+ return rvAP;
+}
+
diff --git a/security/nss/lib/dev/manifest.mn b/security/nss/lib/dev/manifest.mn
index 46013ab5e..effab4805 100644
--- a/security/nss/lib/dev/manifest.mn
+++ b/security/nss/lib/dev/manifest.mn
@@ -39,6 +39,7 @@ PRIVATE_EXPORTS = \
devt.h \
dev.h \
nssdevt.h \
+ nssdev.h \
$(NULL)
EXPORTS = \
@@ -49,7 +50,6 @@ MODULE = security
CSRCS = \
devmod.c \
devslot.c \
- devobject.c \
devtoken.c \
devutil.c \
ckhelper.c \
@@ -58,6 +58,7 @@ CSRCS = \
# here is where the 3.4 glue code is added
ifndef PURE_STAN_BUILD
DEFINES = -DNSS_3_4_CODE
+PRIVATE_EXPORTS += devm.h devtm.h
endif
REQUIRES = security nspr
diff --git a/security/nss/lib/fortcrypt/swfort/pkcs11/stub.c b/security/nss/lib/fortcrypt/swfort/pkcs11/stub.c
index e3b854f3d..0f673e77b 100644
--- a/security/nss/lib/fortcrypt/swfort/pkcs11/stub.c
+++ b/security/nss/lib/fortcrypt/swfort/pkcs11/stub.c
@@ -115,6 +115,19 @@ PORT_ZFree(void *ptr, size_t len)
}
}
+char *
+PORT_Strdup(const char *str)
+{
+ size_t len = PORT_Strlen(str)+1;
+ char *newstr;
+
+ newstr = (char *)PORT_Alloc(len);
+ if (newstr) {
+ PORT_Memcpy(newstr, str, len);
+ }
+ return newstr;
+}
+
void
PORT_SetError(int value)
{
@@ -210,7 +223,7 @@ PORT_ArenaUnmark(PLArenaPool *arena, void *mark)
}
char *
-PORT_ArenaStrdup(PLArenaPool *arena,char *str) {
+PORT_ArenaStrdup(PLArenaPool *arena,const char *str) {
int len = PORT_Strlen(str)+1;
char *newstr;
diff --git a/security/nss/lib/freebl/Makefile b/security/nss/lib/freebl/Makefile
index eaaff9658..05cf9dc17 100644
--- a/security/nss/lib/freebl/Makefile
+++ b/security/nss/lib/freebl/Makefile
@@ -120,6 +120,7 @@ endif
endif
ifeq ($(OS_TARGET), HP-UX)
+ifneq ($(OS_TEST), ia64)
MKSHLIB += +k +vshlibunsats -u FREEBL_GetVector +e FREEBL_GetVector
ifndef FREEBL_EXTENDED_BUILD
ifdef USE_PURE_32
@@ -143,6 +144,7 @@ endif
endif
endif
endif
+endif
# Note: -xarch=v8 or v9 is now done in coreconf
ifeq ($(OS_TARGET),SunOS)
@@ -202,6 +204,7 @@ endif
endif
endif
+$(OBJDIR)/sysrand$(OBJ_SUFFIX): sysrand.c unix_rand.c win_rand.c mac_rand.c os2_rand.c
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
diff --git a/security/nss/lib/freebl/arcfour.c b/security/nss/lib/freebl/arcfour.c
index 71de64b2d..23205ba73 100644
--- a/security/nss/lib/freebl/arcfour.c
+++ b/security/nss/lib/freebl/arcfour.c
@@ -49,6 +49,11 @@
#define USE_LONG
#endif
+#if defined(_WIN32_WCE)
+#undef WORD
+#define WORD ARC4WORD
+#endif
+
#if defined(NSS_USE_HYBRID) && !defined(SOLARIS) && !defined(NSS_USE_64)
typedef unsigned long long WORD;
#else
diff --git a/security/nss/lib/freebl/config.mk b/security/nss/lib/freebl/config.mk
index 476e7743f..6bae7893b 100644
--- a/security/nss/lib/freebl/config.mk
+++ b/security/nss/lib/freebl/config.mk
@@ -37,7 +37,9 @@ ifndef FREEBL_RECURSIVE_BUILD
ifndef USE_64
ifeq ($(OS_TARGET), HP-UX)
- FREEBL_EXTENDED_BUILD = 1
+ ifneq ($(OS_TEST), ia64)
+ FREEBL_EXTENDED_BUILD = 1
+ endif
endif
ifeq ($(OS_TARGET),SunOS)
diff --git a/security/nss/lib/freebl/mpi/mpi.h b/security/nss/lib/freebl/mpi/mpi.h
index c44099bdd..a587c0a76 100644
--- a/security/nss/lib/freebl/mpi/mpi.h
+++ b/security/nss/lib/freebl/mpi/mpi.h
@@ -60,8 +60,10 @@
#undef ULLONG_MAX
#endif
-#ifdef macintosh
+#if defined( macintosh )
#include <Types.h>
+#elif defined( _WIN32_WCE)
+/* #include <sys/types.h> What do we need here ?? */
#else
#include <sys/types.h>
#endif
diff --git a/security/nss/lib/freebl/mpi/mpmontg.c b/security/nss/lib/freebl/mpi/mpmontg.c
index 146c8c625..a4c5022ad 100644
--- a/security/nss/lib/freebl/mpi/mpmontg.c
+++ b/security/nss/lib/freebl/mpi/mpmontg.c
@@ -56,6 +56,12 @@
#define MAX_WINDOW_BITS 6
#define MAX_ODD_INTS 32 /* 2 ** (WINDOW_BITS - 1) */
+#if defined(_WIN32_WCE)
+#define ABORT res = MP_UNDEF; goto CLEANUP
+#else
+#define ABORT abort()
+#endif
+
typedef struct {
mp_int N; /* modulus N */
mp_digit n0prime; /* n0' = - (n0 ** -1) mod MP_RADIX */
@@ -272,7 +278,7 @@ mp_err mp_exptmod_f(const mp_int * montBase,
} else if (smallExp & 8) {
SQR; MUL(smallExp/16); SQR; SQR; SQR;
} else {
- abort();
+ ABORT;
}
} else if (window_bits == 5) {
if (!smallExp) {
@@ -288,7 +294,7 @@ mp_err mp_exptmod_f(const mp_int * montBase,
} else if (smallExp & 0x10) {
SQR; MUL(smallExp/32); SQR; SQR; SQR; SQR;
} else {
- abort();
+ ABORT;
}
} else if (window_bits == 6) {
if (!smallExp) {
@@ -306,10 +312,10 @@ mp_err mp_exptmod_f(const mp_int * montBase,
} else if (smallExp & 0x20) {
SQR; MUL(smallExp/64); SQR; SQR; SQR; SQR; SQR;
} else {
- abort();
+ ABORT;
}
} else {
- abort();
+ ABORT;
}
}
@@ -416,7 +422,7 @@ mp_err mp_exptmod_i(const mp_int * montBase,
SQR(pa1,pa2); MUL(smallExp/16,pa2,pa1); SQR(pa1,pa2);
SQR(pa2,pa1); SQR(pa1,pa2); SWAPPA;
} else {
- abort();
+ ABORT;
}
} else if (window_bits == 5) {
if (!smallExp) {
@@ -438,7 +444,7 @@ mp_err mp_exptmod_i(const mp_int * montBase,
SQR(pa1,pa2); MUL(smallExp/32,pa2,pa1); SQR(pa1,pa2);
SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
} else {
- abort();
+ ABORT;
}
} else if (window_bits == 6) {
if (!smallExp) {
@@ -464,10 +470,10 @@ mp_err mp_exptmod_i(const mp_int * montBase,
SQR(pa1,pa2); MUL(smallExp/64,pa2,pa1); SQR(pa1,pa2);
SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SWAPPA;
} else {
- abort();
+ ABORT;
}
} else {
- abort();
+ ABORT;
}
}
diff --git a/security/nss/lib/freebl/rsa.c b/security/nss/lib/freebl/rsa.c
index 3151ebb87..e1d973fdb 100644
--- a/security/nss/lib/freebl/rsa.c
+++ b/security/nss/lib/freebl/rsa.c
@@ -759,11 +759,13 @@ swap_in_key_value(PRArenaPool *arena, mp_int *mpval, SECItem *buffer)
if ((unsigned int)len <= buffer->len) {
/* The new value is no longer than the old buffer, so use it */
err = mp_to_unsigned_octets(mpval, buffer->data, len);
+ if (err >= 0) err = MP_OKAY;
buffer->len = len;
} else if (arena) {
/* The new value is longer, but working within an arena */
(void)SECITEM_AllocItem(arena, buffer, len);
err = mp_to_unsigned_octets(mpval, buffer->data, len);
+ if (err >= 0) err = MP_OKAY;
} else {
/* The new value is longer, no arena, can't handle this key */
return SECFailure;
@@ -810,6 +812,7 @@ RSA_PrivateKeyCheck(RSAPrivateKey *key)
/* mind the p's and q's (and d_p's and d_q's) */
SECItem tmp;
mp_exch(&p, &q);
+ mp_exch(&d_p,&d_q);
tmp = key->prime1;
key->prime1 = key->prime2;
key->prime2 = tmp;
diff --git a/security/nss/lib/freebl/unix_rand.c b/security/nss/lib/freebl/unix_rand.c
index aa64c8866..4db400655 100644
--- a/security/nss/lib/freebl/unix_rand.c
+++ b/security/nss/lib/freebl/unix_rand.c
@@ -180,6 +180,18 @@ GiveSystemInfo(void)
#define getdtablesize() sysconf(_SC_OPEN_MAX)
+#if defined(__ia64)
+#include <ia64/sys/inline.h>
+
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{
+ PRUint64 t;
+
+ t = _Asm_mov_from_ar(_AREG44);
+ return CopyLowBits(buf, maxbytes, &t, sizeof(t));
+}
+#else
static size_t
GetHighResClock(void *buf, size_t maxbytes)
{
@@ -189,6 +201,7 @@ GetHighResClock(void *buf, size_t maxbytes)
cr16val = ret_cr16();
return CopyLowBits(buf, maxbytes, &cr16val, sizeof(cr16val));
}
+#endif
static void
GiveSystemInfo(void)
diff --git a/security/nss/lib/freebl/win_rand.c b/security/nss/lib/freebl/win_rand.c
index dc16b19b7..bad0365cd 100644
--- a/security/nss/lib/freebl/win_rand.c
+++ b/security/nss/lib/freebl/win_rand.c
@@ -34,10 +34,16 @@
#include "secrng.h"
#ifdef XP_WIN
#include <windows.h>
+
+#if defined(_WIN32_WCE)
+#include <stdlib.h> /* Win CE puts lots of stuff here. */
+#include "prprf.h" /* for PR_snprintf */
+#else
#include <time.h>
#include <io.h>
#include <sys/types.h>
#include <sys/stat.h>
+#endif
#include <stdio.h>
#ifndef _WIN32
@@ -46,6 +52,13 @@
#include <dos.h>
#endif
+#include "prio.h"
+
+static PRInt32 filesToRead;
+static DWORD totalFileBytes;
+static DWORD maxFileBytes = 250000; /* 250 thousand */
+static DWORD dwNumFiles, dwReadEvery;
+
static BOOL
CurrentClockTickTime(LPDWORD lpdwHigh, LPDWORD lpdwLow)
{
@@ -116,7 +129,6 @@ size_t RNG_GetNoise(void *buf, size_t maxbuf)
DWORD dwHigh, dwLow, dwVal;
int n = 0;
int nBytes;
- time_t sTime;
if (maxbuf <= 0)
return 0;
@@ -151,18 +163,81 @@ size_t RNG_GetNoise(void *buf, size_t maxbuf)
if (maxbuf <= 0)
return n;
+#if defined(_WIN32_WCE)
+ {
+ // get the number of milliseconds elapsed since Windows CE was started.
+ DWORD tickCount = GetTickCount();
+ nBytes = (sizeof tickCount) > maxbuf ? maxbuf : (sizeof tickCount);
+ memcpy(((char *)buf) + n, &tickCount, nBytes);
+ n += nBytes;
+ }
+#else
+ {
+ time_t sTime;
// get the time in seconds since midnight Jan 1, 1970
time(&sTime);
nBytes = sizeof(sTime) > maxbuf ? maxbuf : sizeof(sTime);
memcpy(((char *)buf) + n, &sTime, nBytes);
n += nBytes;
+ }
+#endif
return n;
}
+#if defined(_WIN32_WCE)
static BOOL
-EnumSystemFiles(void (*func)(const char *))
+EnumSystemFilesWithNSPR(const char * dirName,
+ BOOL recursive,
+ PRInt32 (*func)(const char *))
{
+ PRDir * pDir;
+ PRDirEntry * pEntry;
+ BOOL rv = FALSE;
+
+ pDir = PR_OpenDir(dirName);
+ if (!pDir)
+ return rv;
+ while ((pEntry = PR_ReadDir(pDir, PR_SKIP_BOTH|PR_SKIP_HIDDEN)) != NULL) {
+ PRStatus status;
+ PRInt32 count;
+ PRInt32 stop;
+ PRFileInfo fileInfo;
+ char szFileName[_MAX_PATH];
+
+ count = (PRInt32)PR_snprintf(szFileName, sizeof szFileName, "%s\\%s",
+ dirName, PR_DirName(pEntry));
+ if (count < 1)
+ continue;
+ status = PR_GetFileInfo(szFileName, &fileInfo);
+ if (status != PR_SUCCESS)
+ continue;
+ if (fileInfo.type == PR_FILE_FILE) {
+ stop = (*func)(szFileName);
+ rv = TRUE;
+ if (stop)
+ break;
+ continue;
+ }
+ if (recursive && fileInfo.type == PR_FILE_DIRECTORY) {
+ rv |= EnumSystemFilesWithNSPR(szFileName, recursive, func);
+ }
+ }
+ PR_CloseDir(pDir);
+ return rv;
+}
+#endif
+
+static BOOL
+EnumSystemFiles(PRInt32 (*func)(const char *))
+{
+#if defined(_WIN32_WCE)
+ BOOL rv = FALSE;
+ rv |= EnumSystemFilesWithNSPR("\\Windows\\Temporary Internet Files", TRUE, func);
+ rv |= EnumSystemFilesWithNSPR("\\Temp", FALSE, func);
+ rv |= EnumSystemFilesWithNSPR("\\Windows", FALSE, func);
+ return rv;
+#else
int iStatus;
char szSysDir[_MAX_PATH];
char szFileName[_MAX_PATH];
@@ -207,23 +282,31 @@ EnumSystemFiles(void (*func)(const char *))
#endif
return TRUE;
+#endif
}
-static DWORD dwNumFiles, dwReadEvery;
-
-static void
+static PRInt32
CountFiles(const char *file)
{
dwNumFiles++;
+ return 0;
}
-static void
+static PRInt32
ReadFiles(const char *file)
{
- if ((dwNumFiles % dwReadEvery) == 0)
+ if ((dwNumFiles % dwReadEvery) == 0) {
+ ++filesToRead;
+ }
+ if (filesToRead) {
+ DWORD prevFileBytes = totalFileBytes;
RNG_FileForRNG(file);
-
+ if (prevFileBytes < totalFileBytes) {
+ --filesToRead;
+ }
+ }
dwNumFiles++;
+ return (totalFileBytes >= maxFileBytes);
}
static void
@@ -237,6 +320,7 @@ ReadSystemFiles()
RNG_RandomUpdate(&dwNumFiles, sizeof(dwNumFiles));
// now read 10 files
+ filesToRead = 10;
if (dwNumFiles == 0)
return;
@@ -255,12 +339,14 @@ void RNG_SystemInfoForRNG(void)
int nBytes;
#ifdef _WIN32
MEMORYSTATUS sMem;
+ HANDLE hVal;
+#if !defined(_WIN32_WCE)
DWORD dwSerialNum;
DWORD dwComponentLen;
DWORD dwSysFlags;
char volName[128];
DWORD dwSectors, dwBytes, dwFreeClusters, dwNumClusters;
- HANDLE hVal;
+#endif
#else
int iVal;
HTASK hTask;
@@ -275,10 +361,10 @@ void RNG_SystemInfoForRNG(void)
sMem.dwLength = sizeof(sMem);
GlobalMemoryStatus(&sMem); // assorted memory stats
RNG_RandomUpdate(&sMem, sizeof(sMem));
-
+#if !defined(_WIN32_WCE)
dwVal = GetLogicalDrives();
RNG_RandomUpdate(&dwVal, sizeof(dwVal)); // bitfields in bits 0-25
-
+#endif
#else
dwVal = GetFreeSpace(0);
RNG_RandomUpdate(&dwVal, sizeof(dwVal));
@@ -290,10 +376,11 @@ void RNG_SystemInfoForRNG(void)
#endif
#ifdef _WIN32
+#if !defined(_WIN32_WCE)
dwVal = sizeof(buffer);
if (GetComputerName(buffer, &dwVal))
RNG_RandomUpdate(buffer, dwVal);
-
+#endif
/* XXX This is code that got yanked because of NSPR20. We should put it
* back someday.
*/
@@ -326,6 +413,7 @@ void RNG_SystemInfoForRNG(void)
dwVal = GetCurrentProcessId(); // process ID (4 bytes)
RNG_RandomUpdate(&dwVal, sizeof(dwVal));
+#if !defined(_WIN32_WCE)
volName[0] = '\0';
buffer[0] = '\0';
GetVolumeInformation(NULL,
@@ -349,7 +437,7 @@ void RNG_SystemInfoForRNG(void)
RNG_RandomUpdate(&dwFreeClusters, sizeof(dwFreeClusters));
RNG_RandomUpdate(&dwNumClusters, sizeof(dwNumClusters));
}
-
+#endif
#else /* is WIN16 */
hTask = GetCurrentTask();
RNG_RandomUpdate((void *)&hTask, sizeof(hTask));
@@ -372,6 +460,47 @@ void RNG_SystemInfoForRNG(void)
RNG_RandomUpdate(buffer, nBytes);
}
+#if defined(_WIN32_WCE)
+void RNG_FileForRNG(const char *filename)
+{
+ PRFileDesc * file;
+ int nBytes;
+ PRFileInfo infoBuf;
+ unsigned char buffer[1024];
+
+ /* windows doesn't initialize all the bytes in the stat buf,
+ * so initialize them all here to avoid UMRs.
+ */
+ memset(&infoBuf, 0, sizeof infoBuf);
+
+ if (PR_GetFileInfo(filename, &infoBuf) < 0)
+ return;
+
+ RNG_RandomUpdate((unsigned char*)&infoBuf, sizeof(infoBuf));
+
+ file = PR_Open(filename, PR_RDONLY, 0);
+ if (file != NULL) {
+ for (;;) {
+ PRInt32 bytes = PR_Read(file, buffer, sizeof buffer);
+
+ if (bytes <= 0)
+ break;
+
+ RNG_RandomUpdate(buffer, bytes);
+ totalFileBytes += bytes;
+ if (totalFileBytes > maxFileBytes)
+ break;
+ }
+
+ PR_Close(file);
+ }
+
+ nBytes = RNG_GetNoise(buffer, 20); // get up to 20 bytes
+ RNG_RandomUpdate(buffer, nBytes);
+}
+
+#else /* not WinCE */
+
void RNG_FileForRNG(const char *filename)
{
FILE* file;
@@ -379,7 +508,7 @@ void RNG_FileForRNG(const char *filename)
struct stat stat_buf;
unsigned char buffer[1024];
- static DWORD totalFileBytes = 0;
+ /* static DWORD totalFileBytes = 0; */
/* windows doesn't initialize all the bytes in the stat buf,
* so initialize them all here to avoid UMRs.
@@ -401,7 +530,7 @@ void RNG_FileForRNG(const char *filename)
RNG_RandomUpdate(buffer, bytes);
totalFileBytes += bytes;
- if (totalFileBytes > 250000)
+ if (totalFileBytes > maxFileBytes)
break;
}
@@ -412,4 +541,5 @@ void RNG_FileForRNG(const char *filename)
RNG_RandomUpdate(buffer, nBytes);
}
+#endif /* not WinCE */
#endif /* is XP_WIN */
diff --git a/security/nss/lib/nss/Makefile b/security/nss/lib/nss/Makefile
index 2eeeaef56..cb58ef545 100644
--- a/security/nss/lib/nss/Makefile
+++ b/security/nss/lib/nss/Makefile
@@ -42,8 +42,6 @@ include manifest.mn
# (2) Include "global" configuration information. (OPTIONAL) #
#######################################################################
-include $(CORE_DEPTH)/coreconf/arch.mk
-
include $(CORE_DEPTH)/coreconf/config.mk
#######################################################################
diff --git a/security/nss/lib/nss/config.mk b/security/nss/lib/nss/config.mk
index c18b1c6ae..693b6d31a 100644
--- a/security/nss/lib/nss/config.mk
+++ b/security/nss/lib/nss/config.mk
@@ -97,3 +97,10 @@ ifeq ($(OS_TARGET),SunOS)
# dependencies (libsoftokn3.so) in the same directory where it resides.
MKSHLIB += -R '$$ORIGIN'
endif
+
+ifeq (,$(filter-out WINNT WIN95,$(OS_TARGET)))
+# Export 'mktemp' to be backward compatible with NSS 3.2.x and 3.3.x
+# but do not put it in the import library. See bug 142575.
+DEFINES += -DWIN32_NSS3_DLL_COMPAT
+DLLFLAGS += -EXPORT:mktemp=nss_mktemp,PRIVATE
+endif
diff --git a/security/nss/lib/nss/nss.def b/security/nss/lib/nss/nss.def
index 97bfae94f..71ec33b37 100644
--- a/security/nss/lib/nss/nss.def
+++ b/security/nss/lib/nss/nss.def
@@ -660,3 +660,23 @@ nss_DumpCertificateCacheInfo;
;+ local:
;+ *;
;+};
+;+NSS_3.5 { # cert creation APIs used by certutil
+;+ global:
+CERT_AddExtension;
+CERT_CopyRDN;
+CERT_CreateCertificate;
+CERT_CreateValidity;
+CERT_DestroyValidity;
+CERT_EncodeAndAddBitStrExtension;
+CERT_EncodeAuthKeyID;
+CERT_EncodeBasicConstraintValue;
+CERT_EncodeCRLDistributionPoints;
+CERT_FinishExtensions;
+CERT_StartCertExtensions;
+DER_AsciiToTime;
+PK11_ImportCert;
+PORT_Strdup;
+SECMOD_CanDeleteInternalModule;
+;+ local:
+;+ *;
+;+};
diff --git a/security/nss/lib/nss/nss.h b/security/nss/lib/nss/nss.h
index 519f26ef8..fa4840e02 100644
--- a/security/nss/lib/nss/nss.h
+++ b/security/nss/lib/nss/nss.h
@@ -49,9 +49,9 @@ SEC_BEGIN_PROTOS
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>] [<Beta>]"
*/
-#define NSS_VERSION "3.4 Beta"
+#define NSS_VERSION "3.5 Beta"
#define NSS_VMAJOR 3
-#define NSS_VMINOR 4
+#define NSS_VMINOR 5
#define NSS_VPATCH 0
#define NSS_BETA PR_TRUE
@@ -132,7 +132,7 @@ SECStatus NSS_NoDB_Init(const char *configdir);
/*
* Close the Cert, Key databases.
*/
-extern void NSS_Shutdown(void);
+extern SECStatus NSS_Shutdown(void);
/*
* set the PKCS #11 strings for the internal token.
diff --git a/security/nss/lib/nss/nssinit.c b/security/nss/lib/nss/nssinit.c
index 1389867fe..91a666f97 100644
--- a/security/nss/lib/nss/nssinit.c
+++ b/security/nss/lib/nss/nssinit.c
@@ -52,6 +52,24 @@
#include "pki3hack.h"
+/*
+ * On Windows nss3.dll needs to export the symbol 'mktemp' to be
+ * fully backward compatible with the nss3.dll in NSS 3.2.x and
+ * 3.3.x. This symbol was unintentionally exported and its
+ * definition (in DBM) was moved from nss3.dll to softokn3.dll
+ * in NSS 3.4. See bug 142575.
+ */
+#ifdef WIN32_NSS3_DLL_COMPAT
+#include <io.h>
+
+/* exported as 'mktemp' */
+char *
+nss_mktemp(char *path)
+{
+ return _mktemp(path);
+}
+#endif
+
#define NSS_MAX_FLAG_SIZE sizeof("readOnly")+sizeof("noCertDB")+ \
sizeof("noModDB")+sizeof("forceOpen")+sizeof("passwordRequired")
#define NSS_DEFAULT_MOD_NAME "NSS Internal Module"
@@ -274,26 +292,76 @@ static const char *dllname =
/* Should we have platform ifdefs here??? */
#define FILE_SEP '/'
+static void nss_FindExternalRootPaths(const char *dbpath, const char* secmodprefix,
+ char** retoldpath, char** retnewpath)
+{
+ char *path, *oldpath = NULL, *lastsep;
+ int len, path_len, secmod_len, dll_len;
+
+ path_len = PORT_Strlen(dbpath);
+ secmod_len = PORT_Strlen(secmodprefix);
+ dll_len = PORT_Strlen(dllname);
+ len = path_len + secmod_len + dll_len + 2; /* FILE_SEP + NULL */
+
+ path = PORT_Alloc(len);
+ if (path == NULL) return;
+
+ /* back up to the top of the directory */
+ PORT_Memcpy(path,dbpath,path_len);
+ if (path[path_len-1] != FILE_SEP) {
+ path[path_len++] = FILE_SEP;
+ }
+ PORT_Strcpy(&path[path_len],dllname);
+ if (secmodprefix) {
+ lastsep = PORT_Strrchr(secmodprefix, FILE_SEP);
+ if (lastsep) {
+ int secmoddir_len = lastsep-secmodprefix+1; /* FILE_SEP */
+ oldpath = PORT_Alloc(len);
+ if (oldpath == NULL) {
+ PORT_Free(path);
+ return;
+ }
+ PORT_Memcpy(oldpath,path,path_len);
+ PORT_Memcpy(&oldpath[path_len],secmodprefix,secmoddir_len);
+ PORT_Strcpy(&oldpath[path_len+secmoddir_len],dllname);
+ }
+ }
+ *retoldpath = oldpath;
+ *retnewpath = path;
+ return;
+}
+
+static void nss_FreeExternalRootPaths(char* oldpath, char* path)
+{
+ if (path) {
+ PORT_Free(path);
+ }
+ if (oldpath) {
+ PORT_Free(oldpath);
+ }
+}
+
static void
-nss_FindExternalRoot(const char *dbpath)
+nss_FindExternalRoot(const char *dbpath, const char* secmodprefix)
{
- char *path;
- int len, path_len;
-
- path_len = PORT_Strlen(dbpath);
- len = path_len + PORT_Strlen(dllname) + 2; /* FILE_SEP + NULL */
-
- path = PORT_Alloc(len);
- if (path == NULL) return;
-
- /* back up to the top of the directory */
- PORT_Memcpy(path,dbpath,path_len);
- if (path[path_len-1] != FILE_SEP) {
- path[path_len++] = FILE_SEP;
- }
- PORT_Strcpy(&path[path_len],dllname);
- (void) SECMOD_AddNewModule("Root Certs",path, 0, 0);
- PORT_Free(path);
+ char *path = NULL;
+ char *oldpath = NULL;
+ PRBool hasrootcerts = PR_FALSE;
+
+ /*
+ * 'oldpath' is the external root path in NSS 3.3.x or older.
+ * For backward compatibility we try to load the root certs
+ * module with the old path first.
+ */
+ nss_FindExternalRootPaths(dbpath, secmodprefix, &oldpath, &path);
+ if (oldpath) {
+ (void) SECMOD_AddNewModule("Root Certs",oldpath, 0, 0);
+ hasrootcerts = SECMOD_HasRootCerts();
+ }
+ if (path && !hasrootcerts) {
+ (void) SECMOD_AddNewModule("Root Certs",path, 0, 0);
+ }
+ nss_FreeExternalRootPaths(oldpath, path);
return;
}
#endif
@@ -390,7 +458,7 @@ loser:
/* only servers need this. We currently do not have a mac server */
if ((!noModDB) && (!noCertDB) && (!noRootInit)) {
if (!SECMOD_HasRootCerts()) {
- nss_FindExternalRoot(configdir);
+ nss_FindExternalRoot(configdir, secmodName);
}
}
#endif
@@ -454,13 +522,16 @@ NSS_NoDB_Init(const char * configdir)
PR_TRUE,PR_TRUE,PR_TRUE,PR_TRUE,PR_TRUE);
}
-void
+SECStatus
NSS_Shutdown(void)
{
+ SECStatus rv;
+
SECOID_Shutdown();
- SECMOD_Shutdown();
STAN_Shutdown();
+ rv = SECMOD_Shutdown();
nss_IsInitted = PR_FALSE;
+ return rv;
}
diff --git a/security/nss/lib/pk11wrap/dev3hack.c b/security/nss/lib/pk11wrap/dev3hack.c
index 43a12628b..9ffd63fc9 100644
--- a/security/nss/lib/pk11wrap/dev3hack.c
+++ b/security/nss/lib/pk11wrap/dev3hack.c
@@ -43,12 +43,13 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#include "pkit.h"
#endif /* PKIT_H */
-#ifndef DEVT_H
-#include "devt.h"
-#endif /* DEVT_H */
+#ifndef DEVM_H
+#include "devm.h"
+#endif /* DEVM_H */
#include "pki3hack.h"
#include "dev3hack.h"
+#include "pkim.h"
#ifndef BASE_H
#include "base.h"
@@ -117,17 +118,24 @@ static NSSSlot *
nssSlot_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
{
NSSSlot *rvSlot;
- rvSlot = nss_ZNEW(td->arena, NSSSlot);
+ NSSArena *arena;
+ arena = nssArena_Create();
+ if (!arena) {
+ return NULL;
+ }
+ rvSlot = nss_ZNEW(arena, NSSSlot);
if (!rvSlot) {
+ nssArena_Destroy(arena);
return NULL;
}
- rvSlot->refCount = 1;
+ rvSlot->base.refCount = 1;
+ rvSlot->base.lock = PZ_NewLock(nssILockOther);
+ rvSlot->base.arena = arena;
rvSlot->pk11slot = nss3slot;
rvSlot->epv = nss3slot->functionList;
rvSlot->slotID = nss3slot->slotID;
- rvSlot->trustDomain = td;
/* Grab the slot name from the PKCS#11 fixed-length buffer */
- rvSlot->name = nssUTF8_Duplicate(nss3slot->slot_name,td->arena);
+ rvSlot->base.name = nssUTF8_Duplicate(nss3slot->slot_name,td->arena);
return rvSlot;
}
@@ -135,24 +143,40 @@ NSS_IMPLEMENT NSSToken *
nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
{
NSSToken *rvToken;
- rvToken = nss_ZNEW(td->arena, NSSToken);
+ NSSArena *arena;
+ arena = nssArena_Create();
+ if (!arena) {
+ return NULL;
+ }
+ rvToken = nss_ZNEW(arena, NSSToken);
if (!rvToken) {
+ nssArena_Destroy(arena);
return NULL;
}
- rvToken->refCount = 1;
+ rvToken->base.refCount = 1;
+ rvToken->base.lock = PZ_NewLock(nssILockOther);
+ rvToken->base.arena = arena;
rvToken->pk11slot = nss3slot;
rvToken->epv = nss3slot->functionList;
rvToken->defaultSession = nssSession_ImportNSS3Session(td->arena,
nss3slot->session,
nss3slot->sessionLock,
nss3slot->defRWSession);
+ /* The above test was used in 3.4, for this cache have it always on */
+ if (!PK11_IsInternal(nss3slot) && PK11_IsHW(nss3slot)) {
+ rvToken->cache = nssTokenObjectCache_Create(rvToken,
+ PR_TRUE, PR_TRUE, PR_TRUE);
+ if (!rvToken->cache) {
+ nssArena_Destroy(arena);
+ return (NSSToken *)NULL;
+ }
+ }
rvToken->trustDomain = td;
/* Grab the token name from the PKCS#11 fixed-length buffer */
- rvToken->name = nssUTF8_Duplicate(nss3slot->token_name,td->arena);
+ rvToken->base.name = nssUTF8_Duplicate(nss3slot->token_name,td->arena);
rvToken->slot = nssSlot_CreateFromPK11SlotInfo(td, nss3slot);
rvToken->slot->token = rvToken;
rvToken->defaultSession->slot = rvToken->slot;
- rvToken->arena = td->arena;
return rvToken;
}
@@ -162,7 +186,7 @@ nssToken_UpdateName(NSSToken *token)
if (!token) {
return;
}
- token->name = nssUTF8_Duplicate(token->pk11slot->token_name,token->arena);
+ token->base.name = nssUTF8_Duplicate(token->pk11slot->token_name,token->base.arena);
}
NSS_IMPLEMENT PRBool
@@ -174,6 +198,15 @@ nssSlot_IsPermanent
return slot->pk11slot->isPerm;
}
+NSS_IMPLEMENT PRBool
+nssSlot_IsFriendly
+(
+ NSSSlot *slot
+)
+{
+ return PK11_IsFriendly(slot->pk11slot);
+}
+
NSS_IMPLEMENT PRStatus
nssToken_Refresh(NSSToken *token)
{
@@ -183,12 +216,11 @@ nssToken_Refresh(NSSToken *token)
return PR_SUCCESS;
}
nss3slot = token->pk11slot;
- token->defaultSession = nssSession_ImportNSS3Session(token->slot->arena,
+ token->defaultSession = nssSession_ImportNSS3Session(token->slot->base.arena,
nss3slot->session,
nss3slot->sessionLock,
nss3slot->defRWSession);
- nssToken_DestroyCertList(token, PR_TRUE);
- return nssToken_LoadCerts(token);
+ return PR_SUCCESS;
}
NSS_IMPLEMENT PRStatus
@@ -198,12 +230,44 @@ nssSlot_Refresh
)
{
PK11SlotInfo *nss3slot = slot->pk11slot;
+ PRBool doit = PR_FALSE;
+ if (slot->token->base.name[0] == 0) {
+ doit = PR_TRUE;
+ }
if (PK11_InitToken(nss3slot, PR_FALSE) != SECSuccess) {
return PR_FAILURE;
}
+ if (doit) {
+ nssTrustDomain_UpdateCachedTokenCerts(slot->token->trustDomain,
+ slot->token);
+ }
return nssToken_Refresh(slot->token);
}
+NSS_IMPLEMENT PRStatus
+nssToken_GetTrustOrder
+(
+ NSSToken *tok
+)
+{
+ PK11SlotInfo *slot;
+ SECMODModule *module;
+ slot = tok->pk11slot;
+ module = PK11_GetModule(slot);
+ return module->trustOrder;
+}
+
+NSS_IMPLEMENT PRBool
+nssSlot_IsLoggedIn
+(
+ NSSSlot *slot
+)
+{
+ if (!slot->pk11slot->needLogin) {
+ return PR_TRUE;
+ }
+ return PK11_IsLoggedIn(slot->pk11slot, NULL);
+}
NSSTrustDomain *
@@ -212,25 +276,19 @@ nssToken_GetTrustDomain(NSSToken *token)
return token->trustDomain;
}
-typedef enum {
- nssPK11Event_DefaultSessionRO = 0,
- nssPK11Event_DefaultSessionRW = 1
-} nssPK11Event;
+NSS_EXTERN PRStatus
+nssTrustDomain_RemoveTokenCertsFromCache
+(
+ NSSTrustDomain *td,
+ NSSToken *token
+);
NSS_IMPLEMENT PRStatus
-nssToken_Nofify
+nssToken_NofifyCertsNotVisible
(
- NSSToken *tok,
- nssPK11Event event
+ NSSToken *tok
)
-
{
-#ifdef notdef
- switch (event) {
- default:
- return PR_FAILURE;
- }
-#endif
- return PR_FAILURE;
+ return nssTrustDomain_RemoveTokenCertsFromCache(tok->trustDomain, tok);
}
diff --git a/security/nss/lib/pk11wrap/dev3hack.h b/security/nss/lib/pk11wrap/dev3hack.h
index 19f9bbb8b..d2e3ab4e1 100644
--- a/security/nss/lib/pk11wrap/dev3hack.h
+++ b/security/nss/lib/pk11wrap/dev3hack.h
@@ -58,12 +58,6 @@ void PK11Slot_SetNSSToken(PK11SlotInfo *sl, NSSToken *nsst);
NSSToken * PK11Slot_GetNSSToken(PK11SlotInfo *sl);
-NSS_EXTERN PRStatus
-nssToken_LoadCerts(NSSToken *token);
-
-NSS_EXTERN void
-nssToken_UpdateTrustForCerts(NSSToken *token);
-
PR_END_EXTERN_C
#endif /* DEVNSS3HACK_H */
diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c
index 9611ff06f..ae0629d49 100644
--- a/security/nss/lib/pk11wrap/pk11cert.c
+++ b/security/nss/lib/pk11wrap/pk11cert.c
@@ -58,11 +58,12 @@
#include "pki3hack.h"
#include "dev3hack.h"
-#include "dev.h"
+#include "devm.h"
#include "nsspki.h"
#include "pki.h"
#include "pkim.h"
#include "pkitm.h"
+#include "pkistore.h" /* to remove temp cert */
#define PK11_SEARCH_CHUNKSIZE 10
@@ -89,50 +90,6 @@ static PRStatus convert_cert(NSSCertificate *c, void *arg)
return (secrv) ? PR_FAILURE : PR_SUCCESS;
}
-static PRStatus convert_and_cache_cert(NSSCertificate *c, void *arg)
-{
- PRStatus nssrv;
- NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
- struct nss3_cert_cbstr *nss3cb = (struct nss3_cert_cbstr *)arg;
- NSSCertificate *cp = nssCertificate_AddRef(c);
- /* The cert coming in has been retrieved from a token. It was not in
- * the cache when the search was begun. But it may be in the cache now,
- * and if it isn't, it will be, because it is going to be cracked into
- * a CERTCertificate and fed into the callback.
- */
- nssrv = nssTrustDomain_AddCertsToCache(td, &c, 1);
- /* This is why the hack of copying the cert was done above. The pointer
- * c passed to this function is provided by retrieve_cert. That function
- * will destroy the pointer once this function returns. Since c is a local
- * copy, there is no way to notify retrieve_cert if it has changed. That
- * would happen if the above call to add it to the cache found the cert
- * already there. In that case, the pointer c passed to the callback
- * below will be the cached cert, and the pointer c that retrieve_cert
- * has will be the same as the copy made above. Thus, retrieve_cert will
- * destroy the reference to the copy, the callback will use the reference
- * to the cached entry, and everyone should be happy.
- */
- nssrv = convert_cert(c, arg);
- /* This function owns a reference to the cert, either from the AddRef
- * or by getting it from the cache.
- */
- CERT_DestroyCertificate(STAN_GetCERTCertificate(c));
- return nssrv;
-}
-
-/* this is redeclared from trustdomain.c, but this code is just 3.4 glue
- * anyway
- */
-static void cert_destructor(void *el)
-{
- NSSCertificate *c = (NSSCertificate *)el;
- CERTCertificate *cert = STAN_GetCERTCertificate(c);
- /* It's already been obtained as a CERTCertificate, so it must
- * be destroyed as one
- */
- CERT_DestroyCertificate(cert);
-}
-
void
PK11Slot_SetNSSToken(PK11SlotInfo *sl, NSSToken *nsst)
{
@@ -435,59 +392,54 @@ pk11_isID0(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID)
return isZero;
}
-
+
+/*
+ * Create an NSSCertificate from a slot/certID pair, return it as a
+ * CERTCertificate.
+ */
CERTCertificate
*pk11_fastCert(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID,
CK_ATTRIBUTE *privateLabel, char **nickptr)
{
- CK_ATTRIBUTE certTemp[] = {
- { CKA_ID, NULL, 0 },
- { CKA_VALUE, NULL, 0 },
- { CKA_LABEL, NULL, 0 }
- };
- CK_ATTRIBUTE *id = &certTemp[0];
- CK_ATTRIBUTE *certDER = &certTemp[1];
- CK_ATTRIBUTE *label = &certTemp[2];
- SECItem derCert;
- int csize = sizeof(certTemp)/sizeof(certTemp[0]);
- PRArenaPool *arena;
- char *nickname;
- CERTCertificate *cert;
- CK_RV crv;
+ NSSCertificate *c;
+ nssCryptokiObject *co;
+ nssPKIObject *pkio;
+ NSSToken *token;
+ NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) return NULL;
- /*
- * grab the der encoding
- */
- crv = PK11_GetAttributes(arena,slot,certID,certTemp,csize);
- if (crv != CKR_OK) {
- PORT_FreeArena(arena,PR_FALSE);
- PORT_SetError( PK11_MapError(crv) );
+ /* Get the cryptoki object from the handle */
+ token = PK11Slot_GetNSSToken(slot);
+ co = nssCryptokiObject_Create(token, token->defaultSession, certID);
+ if (!co) {
return NULL;
}
- /*
- * build a certificate out of it
- */
- derCert.data = (unsigned char*)certDER->pValue;
- derCert.len = certDER->ulValueLen;
+ /* Create a PKI object from the cryptoki instance */
+ pkio = nssPKIObject_Create(NULL, co, td, NULL);
+ if (!pkio) {
+ nssCryptokiObject_Destroy(co);
+ return NULL;
+ }
- /* figure out the nickname.... */
- nickname = pk11_buildNickname(slot,label,privateLabel,id);
- cert = CERT_DecodeDERCertificate(&derCert, PR_TRUE, nickname);
- if (cert) {
- cert->dbhandle = (CERTCertDBHandle *)
- nssToken_GetTrustDomain(slot->nssToken);
+ /* Create a certificate */
+ c = nssCertificate_Create(pkio);
+ if (!c) {
+ nssPKIObject_Destroy(pkio);
+ return NULL;
}
-
+
+ /* Build the old-fashioned nickname */
if (nickptr) {
- *nickptr = nickname;
- } else {
- if (nickname) PORT_Free(nickname);
+ CK_ATTRIBUTE label, id;
+ label.type = CKA_LABEL;
+ label.pValue = co->label;
+ label.ulValueLen = PORT_Strlen(co->label);
+ id.type = CKA_ID;
+ id.pValue = c->id.data;
+ id.ulValueLen = c->id.size;
+ *nickptr = pk11_buildNickname(slot, &label, privateLabel, &id);
}
- PORT_FreeArena(arena,PR_FALSE);
- return cert;
+ return STAN_GetCERTCertificate(c);
}
CK_TRUST
@@ -1015,7 +967,9 @@ pk11_TraverseAllSlots( SECStatus (*callback)(PK11SlotInfo *,void *),
rv = PK11_Authenticate(le->slot, PR_FALSE, wincx);
if (rv != SECSuccess) continue;
}
- (*callback)(le->slot,arg);
+ if (callback) {
+ (*callback)(le->slot,arg);
+ }
}
PK11_FreeSlotList(list);
@@ -1063,6 +1017,10 @@ PK11_TraverseSlotCerts(SECStatus(* callback)(CERTCertificate*,SECItem *,void *),
NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();
struct fake_der_cb_argstr fda;
struct nss3_cert_cbstr pk11cb;
+
+ /* authenticate to the tokens first */
+ (void) pk11_TraverseAllSlots( NULL, NULL, wincx);
+
fda.callback = callback;
fda.arg = arg;
pk11cb.callback = fake_der_cb;
@@ -1215,123 +1173,37 @@ PK11_FindObjectsFromNickname(char *nickname,PK11SlotInfo **slotptr,
return objID;
}
-static PRStatus
-get_newest_cert(NSSCertificate *c, void *arg)
-{
- nssDecodedCert *dc, *founddc;
- NSSCertificate **cfound = (NSSCertificate **)arg;
- if (!*cfound) {
- *cfound = nssCertificate_AddRef(c);
- return PR_SUCCESS;
- }
- dc = nssCertificate_GetDecoding(c);
- founddc = nssCertificate_GetDecoding(*cfound);
- if (!founddc->isNewerThan(founddc, dc)) {
- CERT_DestroyCertificate(STAN_GetCERTCertificate(*cfound));
- *cfound = nssCertificate_AddRef(c);
- }
- return PR_SUCCESS;
-}
-
-struct token_cbstr {
- NSSToken *token;
- PRStatus (* callback)(NSSCertificate *c, void *arg);
- void *cbarg;
-};
-
-/* This callback matches all certs on a given token. It is used to filter
- * cert lists to only those certs on a particular token.
- */
-static PRStatus
-token_callback(NSSCertificate *c, void *arg)
-{
- nssListIterator *instances;
- nssCryptokiInstance *instance;
- PRBool isToken = PR_FALSE;
- struct token_cbstr *token_cb = (struct token_cbstr *)arg;
- instances = c->object.instances;
- for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances);
- instance != (nssCryptokiInstance *)NULL;
- instance = (nssCryptokiInstance *)nssListIterator_Next(instances))
- {
- if (instance->token == token_cb->token) {
- isToken = PR_TRUE;
- break;
- }
- }
- nssListIterator_Finish(instances);
- if (isToken) {
- return (*token_cb->callback)(c, token_cb->cbarg);
- } else {
- return PR_SUCCESS;
- }
-}
-
-/* match all token certs with a nickname */
-static nssList *
-filter_token_certs_nickname(NSSToken *token, NSSUTF8 *nickname)
-{
- nssListIterator *certs;
- NSSCertificate *cert;
- PRStatus nssrv;
- nssList *rvList;
- certs = nssList_CreateIterator(token->certList);
- if (!certs) return NULL;
- rvList = nssList_Create(NULL, PR_FALSE);
- if (!rvList) {
- nssListIterator_Destroy(certs);
- return NULL;
- }
- for (cert = (NSSCertificate *)nssListIterator_Start(certs);
- cert != (NSSCertificate *)NULL;
- cert = (NSSCertificate *)nssListIterator_Next(certs))
- {
- NSSUTF8 *tokenNick = NSSCertificate_GetNickname(cert, token);
- if (!tokenNick) continue;
- if (nssUTF8_Equal(tokenNick, nickname, &nssrv)) {
- nssList_Add(rvList, nssCertificate_AddRef(cert));
- }
- }
- nssListIterator_Finish(certs);
- nssListIterator_Destroy(certs);
- if (nssList_Count(rvList) == 0) {
- nssList_Destroy(rvList);
- rvList = NULL;
- }
- return rvList;
-}
-
-/* match all token certs with an email address */
-static nssList *
-filter_token_certs_email(NSSToken *token, NSSASCII7 *email)
-{
- nssListIterator *certs;
- NSSCertificate *cert;
- PRStatus nssrv;
- nssList *rvList;
- certs = nssList_CreateIterator(token->certList);
- if (!certs) return NULL;
- rvList = nssList_Create(NULL, PR_FALSE);
- if (!rvList) {
- nssListIterator_Destroy(certs);
- return NULL;
- }
- for (cert = (NSSCertificate *)nssListIterator_Start(certs);
- cert != (NSSCertificate *)NULL;
- cert = (NSSCertificate *)nssListIterator_Next(certs))
- {
- if (!cert->email) continue;
- if (nssUTF8_Equal(cert->email, email, &nssrv)) {
- nssList_Add(rvList, nssCertificate_AddRef(cert));
+static void
+transfer_token_certs_to_collection(nssList *certList, NSSToken *token,
+ nssPKIObjectCollection *collection)
+{
+ NSSCertificate **certs;
+ PRUint32 i, count;
+ NSSToken **tokens, **tp;
+ count = nssList_Count(certList);
+ if (count == 0) {
+ return;
+ }
+ certs = nss_ZNEWARRAY(NULL, NSSCertificate *, count);
+ if (!certs) {
+ return;
+ }
+ nssList_GetArray(certList, (void **)certs, count);
+ for (i=0; i<count; i++) {
+ tokens = nssPKIObject_GetTokens(&certs[i]->object, NULL);
+ if (tokens) {
+ for (tp = tokens; *tp; tp++) {
+ if (*tp == token) {
+ nssPKIObjectCollection_AddObject(collection,
+ (nssPKIObject *)certs[i]);
+ }
+ }
+ nssTokenArray_Destroy(tokens);
}
+ /* *must* be a valid CERTCertificate, came from cache */
+ CERT_DestroyCertificate(STAN_GetCERTCertificate(certs[i]));
}
- nssListIterator_Finish(certs);
- nssListIterator_Destroy(certs);
- if (nssList_Count(rvList) == 0) {
- nssList_Destroy(rvList);
- rvList = NULL;
- }
- return rvList;
+ nss_ZFreeIf(certs);
}
CERTCertificate *
@@ -1349,8 +1221,10 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) {
PORT_Free(certID);
return cert;
#else
+ PRStatus status;
CERTCertificate *rvCert = NULL;
NSSCertificate *cert = NULL;
+ NSSCertificate **certs = NULL;
NSSUsage usage;
NSSToken *token;
PK11SlotInfo *slot = NULL;
@@ -1375,111 +1249,79 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) {
token = PK11Slot_GetNSSToken(slot);
}
if (token) {
- nssTokenCertSearch search;
- struct token_cbstr token_cb;
nssList *certList;
-
+ nssCryptokiObject **instances;
+ nssPKIObjectCollection *collection;
+ nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
if (!PK11_IsPresent(slot)) {
- return NULL;
+ goto loser;
}
if (!PK11_IsFriendly(slot)) {
if (PK11_Authenticate(slot, PR_TRUE, wincx) != SECSuccess) {
- PK11_FreeSlot(slot);
- return NULL;
+ goto loser;
}
}
- /* find best cert on token */
- if (!nssToken_SearchCerts(token, NULL)) {
- /* token certs are in cache, filter the list of token certs to
- * match the nickname
- */
- certList = filter_token_certs_nickname(token, nickname);
- if (certList) {
- nssCertificateList_DoCallback(certList,
- get_newest_cert,
- (void *)&cert);
- }
- } else {
- /* find matching certs on the token */
- certList = nssList_Create(NULL, PR_FALSE);
- if (!certList) return NULL;
- /* first, get all matching certs from the cache */
- (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
- nickname,
- certList);
- /* set the search criteria */
- token_cb.callback = get_newest_cert;
- token_cb.cbarg = (void *)&cert;
- token_cb.token = token;
- search.callback = token_callback;
- search.cbarg = &token_cb;
- search.cached = certList;
- search.searchType = nssTokenSearchType_TokenOnly;
- /* now search the token */
- nssToken_TraverseCertificatesByNickname(token, NULL,
- (NSSUTF8 *)nickname,
- &search);
- /* filter the list of cached certs for only those on the token */
- nssCertificateList_DoCallback(certList,
- token_callback,
- &token_cb);
- }
- if (certList) {
- nssList_Clear(certList, cert_destructor);
- nssList_Destroy(certList);
+ collection = nssCertificateCollection_Create(defaultTD, NULL);
+ if (!collection) {
+ goto loser;
}
+ certList = nssList_Create(NULL, PR_FALSE);
+ if (!certList) {
+ nssPKIObjectCollection_Destroy(collection);
+ goto loser;
+ }
+ (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
+ nickname,
+ certList);
+ transfer_token_certs_to_collection(certList, token, collection);
+ instances = nssToken_FindCertificatesByNickname(token,
+ NULL,
+ nickname,
+ tokenOnly,
+ 0,
+ &status);
+ nssPKIObjectCollection_AddInstances(collection, instances, 0);
+ nss_ZFreeIf(instances);
/* if it wasn't found, repeat the process for email address */
- if (!cert) {
- if (!nssToken_SearchCerts(token, NULL)) {
- certList = filter_token_certs_email(token, nickname);
- if (certList) {
- nssCertificateList_DoCallback(certList,
- get_newest_cert,
- (void *)&cert);
- }
- } else {
- certList = nssList_Create(NULL, PR_FALSE);
- if (!certList) return NULL;
- (void)nssTrustDomain_GetCertsForEmailAddressFromCache(
- defaultTD,
+ if (nssPKIObjectCollection_Count(collection) == 0 &&
+ PORT_Strchr(nickname, '@') != NULL)
+ {
+ (void)nssTrustDomain_GetCertsForEmailAddressFromCache(defaultTD,
nickname,
certList);
- search.cached = certList;
- nssToken_TraverseCertificatesByEmail(token, NULL,
- (NSSASCII7 *)nickname,
- &search);
- nssCertificateList_DoCallback(certList,
- token_callback,
- &token_cb);
- }
- if (certList) {
- nssList_Clear(certList, cert_destructor);
- nssList_Destroy(certList);
- }
- }
- if (cert) {
- (void)nssTrustDomain_AddCertsToCache(defaultTD, &cert, 1);
+ transfer_token_certs_to_collection(certList, token, collection);
+ instances = nssToken_FindCertificatesByEmail(token,
+ NULL,
+ nickname,
+ tokenOnly,
+ 0,
+ &status);
+ nssPKIObjectCollection_AddInstances(collection, instances, 0);
+ nss_ZFreeIf(instances);
+ }
+ certs = nssPKIObjectCollection_GetCertificates(collection,
+ NULL, 0, NULL);
+ nssPKIObjectCollection_Destroy(collection);
+ if (certs) {
+ cert = nssCertificateArray_FindBestCertificate(certs, NULL,
+ &usage, NULL);
rvCert = STAN_GetCERTCertificate(cert);
+ nssCertificateArray_Destroy(certs);
}
+ nssList_Destroy(certList);
}
if (slot) {
PK11_FreeSlot(slot);
}
if (nickCopy) PORT_Free(nickCopy);
return rvCert;
-#endif
-}
-
-static PRStatus
-collect_certs(NSSCertificate *c, void *arg)
-{
- nssList *list = (nssList *)arg;
- /* Add the cert to the return list if not present */
- if (!nssList_Get(list, (void *)c)) {
- nssCertificate_AddRef(c);
- nssList_Add(list, (void *)c);
+loser:
+ if (slot) {
+ PK11_FreeSlot(slot);
}
- return PR_SUCCESS;
+ if (nickCopy) PORT_Free(nickCopy);
+ return NULL;
+#endif
}
CERTCertList *
@@ -1509,12 +1351,12 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) {
PORT_Free(certID);
return certList;
#else
- PRStatus nssrv;
char *nickCopy;
char *delimit = NULL;
char *tokenName;
int i;
CERTCertList *certList = NULL;
+ nssPKIObjectCollection *collection = NULL;
NSSCertificate **foundCerts = NULL;
NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();
NSSCertificate *c;
@@ -1538,37 +1380,45 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) {
token = PK11Slot_GetNSSToken(slot);
}
if (token) {
- nssTokenCertSearch search;
- PRUint32 count;
+ PRStatus status;
nssList *nameList;
+ nssCryptokiObject **instances;
+ nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
if (!PK11_IsFriendly(slot)) {
if (PK11_Authenticate(slot, PR_TRUE, wincx) != SECSuccess) {
PK11_FreeSlot(slot);
+ if (nickCopy) PORT_Free(nickCopy);
return NULL;
}
}
- if (!nssToken_SearchCerts(token, NULL)) {
- nameList = filter_token_certs_nickname(token, nickname);
- } else {
- nameList = nssList_Create(NULL, PR_FALSE);
- if (!nameList) return NULL;
- (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
- nickname,
- nameList);
- /* set the search criteria */
- search.callback = collect_certs;
- search.cbarg = nameList;
- search.cached = nameList;
- search.searchType = nssTokenSearchType_TokenOnly;
- nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
- nickname, &search);
- }
- if (nameList) {
- count = nssList_Count(nameList);
- foundCerts = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1);
- nssList_GetArray(nameList, (void **)foundCerts, count);
- nssList_Destroy(nameList);
+ collection = nssCertificateCollection_Create(defaultTD, NULL);
+ if (!collection) {
+ PK11_FreeSlot(slot);
+ if (nickCopy) PORT_Free(nickCopy);
+ return NULL;
+ }
+ nameList = nssList_Create(NULL, PR_FALSE);
+ if (!nameList) {
+ PK11_FreeSlot(slot);
+ if (nickCopy) PORT_Free(nickCopy);
+ return NULL;
}
+ (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
+ nickname,
+ nameList);
+ transfer_token_certs_to_collection(nameList, token, collection);
+ instances = nssToken_FindCertificatesByNickname(token,
+ NULL,
+ nickname,
+ tokenOnly,
+ 0,
+ &status);
+ nssPKIObjectCollection_AddInstances(collection, instances, 0);
+ nss_ZFreeIf(instances);
+ nssList_Destroy(nameList);
+ foundCerts = nssPKIObjectCollection_GetCertificates(collection,
+ NULL, 0, NULL);
+ nssPKIObjectCollection_Destroy(collection);
}
if (slot) {
PK11_FreeSlot(slot);
@@ -1577,7 +1427,10 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) {
if (foundCerts) {
certList = CERT_NewCertList();
for (i=0, c = *foundCerts; c; c = foundCerts[++i]) {
- CERT_AddCertToListTail(certList, STAN_GetCERTCertificate(c));
+ CERTCertificate *certCert = STAN_GetCERTCertificate(c);
+ if (certCert) {
+ CERT_AddCertToListTail(certList, certCert);
+ }
}
if (CERT_LIST_HEAD(certList) == NULL) {
CERT_DestroyCertList(certList);
@@ -1692,6 +1545,7 @@ PK11_MakeIDFromPubKey(SECItem *pubKeyData) {
SECStatus
PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
CK_OBJECT_HANDLE key, char *nickname, PRBool includeTrust) {
+#ifdef NSS_CLASSIC
int len = 0;
SECItem *keyID = pk11_mkcertKeyID(cert);
CK_ATTRIBUTE keyAttrs[] = {
@@ -1715,6 +1569,7 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
{ CKA_SERIAL_NUMBER, NULL, 0},
{ CKA_VALUE, NULL, 0},
{ CKA_NETSCAPE_TRUST, NULL, 0},
+ { CKA_NETSCAPE_EMAIL, NULL, 0},
};
int certCount = sizeof(certAttrs)/sizeof(certAttrs[0]), keyCount = 2;
int realCount = 0;
@@ -1765,6 +1620,11 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
PK11_SETATTRS(attrs,CKA_NETSCAPE_TRUST, certUsage,
sizeof(SECCertUsage));
attrs++;
+ if (cert->emailAddr) {
+ PK11_SETATTRS(attrs,CKA_NETSCAPE_EMAIL, cert->emailAddr,
+ PORT_Strlen(cert->emailAddr);
+ attrs++;
+ }
}
realCount = attrs - certAttrs;
PORT_Assert(realCount <= certCount);
@@ -1815,24 +1675,13 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
instance->token = slot->nssToken;
instance->handle = cert->pkcs11ID;
instance->isTokenObject = PR_TRUE;
- nssList_Add(c->object.instanceList, instance);
- /* XXX Fix this! */
- nssListIterator_Destroy(c->object.instances);
- c->object.instances = nssList_CreateIterator(c->object.instanceList);
+ nssPKIObject_AddInstance(&c->object, instance);
} else {
cert->nssCertificate = STAN_GetNSSCertificate(cert);
}
}
cert->trust = nssTrust_GetCERTCertTrustForCert(cert->nssCertificate, cert);
token = PK11Slot_GetNSSToken(slot);
- if (token->certList) {
- /* create a persistent reference for the token */
- NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
- nssCertificate_AddRef(cert->nssCertificate);
- nssList_Add(token->certList, cert->nssCertificate);
- /* and add the cert to the cache */
- nssTrustDomain_AddCertsToCache(td, &cert->nssCertificate, 1);
- }
done:
if (derSerial.data) PORT_Free(derSerial.data);
@@ -1842,7 +1691,89 @@ done:
PORT_Free(certUsage);
}
return rv;
+#else
+ PRStatus status;
+ NSSCertificate *c;
+ nssCryptokiObject *keyobj, *certobj;
+ NSSToken *token = PK11Slot_GetNSSToken(slot);
+ SECItem *keyID = pk11_mkcertKeyID(cert);
+ char *emailAddr = NULL;
+
+ if (keyID == NULL) {
+ goto loser;
+ }
+
+ if (PK11_IsInternal(slot) && cert->emailAddr) {
+ emailAddr = cert->emailAddr;
+ }
+
+ /* need to get the cert as a stan cert */
+ if (cert->nssCertificate) {
+ c = cert->nssCertificate;
+ } else {
+ c = STAN_GetNSSCertificate(cert);
+ }
+
+ if (c->object.cryptoContext) {
+ /* Delete the temp instance */
+ nssCertificateStore_Remove(c->object.cryptoContext->certStore, c);
+ c->object.cryptoContext = NULL;
+ cert->istemp = PR_FALSE;
+ cert->isperm = PR_TRUE;
+ }
+
+ /* set the id for the cert */
+ nssItem_Create(c->object.arena, &c->id, keyID->len, keyID->data);
+ if (!c->id.data) {
+ goto loser;
+ }
+
+ if (key != CK_INVALID_HANDLE) {
+ /* create an object for the key, ... */
+ keyobj = nss_ZNEW(NULL, nssCryptokiObject);
+ if (!keyobj) {
+ goto loser;
+ }
+ keyobj->token = nssToken_AddRef(token);
+ keyobj->handle = key;
+ keyobj->isTokenObject = PR_TRUE;
+ /* ... in order to set matching attributes for the key */
+ status = nssCryptokiPrivateKey_SetCertificate(keyobj, NULL, nickname,
+ &c->id, &c->subject);
+ nssCryptokiObject_Destroy(keyobj);
+ if (status != PR_SUCCESS) {
+ goto loser;
+ }
+ }
+
+ /* do the token import */
+ certobj = nssToken_ImportCertificate(token, NULL,
+ NSSCertificateType_PKIX,
+ &c->id,
+ nickname,
+ &c->encoding,
+ &c->issuer,
+ &c->subject,
+ &c->serial,
+ emailAddr,
+ PR_TRUE);
+ if (!certobj) {
+ goto loser;
+ }
+ /* add the new instance to the cert, force an update of the
+ * CERTCertificate, and finish
+ */
+ nssPKIObject_AddInstance(&c->object, certobj);
+ nssTrustDomain_AddCertsToCache(STAN_GetDefaultTrustDomain(), &c, 1);
+ (void)STAN_ForceCERTCertificateUpdate(c);
+ SECITEM_FreeItem(keyID,PR_TRUE);
+ return SECSuccess;
+loser:
+ SECITEM_FreeItem(keyID,PR_TRUE);
+ PORT_SetError(SEC_ERROR_ADDING_CERT);
+ return SECFailure;
+#endif
}
/*
@@ -1977,6 +1908,9 @@ PK11_KeyForDERCertExists(SECItem *derCert, CK_OBJECT_HANDLE *keyPtr,
CERTCertificate *cert;
PK11SlotInfo *slot = NULL;
+ /* letting this use go -- the only thing that the cert is used for is
+ * to get the ID attribute.
+ */
cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
if (cert == NULL) return NULL;
@@ -2009,7 +1943,8 @@ PK11_ImportDERCertForKey(SECItem *derCert, char *nickname,void *wincx) {
CERTCertificate *cert;
PK11SlotInfo *slot = NULL;
- cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
+ cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
+ derCert, NULL, PR_FALSE, PR_FALSE);
if (cert == NULL) return NULL;
slot = PK11_ImportCertForKey(cert, nickname, wincx);
@@ -2434,12 +2369,18 @@ PK11_FindCertByIssuerAndSN(PK11SlotInfo **slotPtr, CERTIssuerAndSN *issuerSN,
SECITEM_FreeItem(derSerial, PR_TRUE);
return STAN_GetCERTCertificate(cert);
}
+retry:
cert = NSSTrustDomain_FindCertificateByIssuerAndSerialNumber(
STAN_GetDefaultTrustDomain(),
&issuer,
&serial);
if (cert) {
rvCert = STAN_GetCERTCertificate(cert);
+ /* Check to see if the cert's token is still there */
+ if (!PK11_IsPresent(rvCert->slot)) {
+ CERT_DestroyCertificate(rvCert);
+ goto retry;
+ }
if (slotPtr) *slotPtr = PK11_ReferenceSlot(rvCert->slot);
}
SECITEM_FreeItem(derSerial, PR_TRUE);
@@ -2597,72 +2538,6 @@ PK11_TraverseCertsForSubject(CERTCertificate *cert,
return PK11_TraverseCertsForSubjectInSlot(cert, cert->slot, callback, arg);
}
-/* Find all certs with a given subject in the list of token certs */
-static nssList *
-filter_token_certs_subject(NSSToken *token, NSSDER *subject)
-{
- nssListIterator *certs;
- NSSCertificate *cert;
- PRStatus nssrv;
- nssList *rvList;
- certs = nssList_CreateIterator(token->certList);
- if (!certs) return NULL;
- rvList = nssList_Create(NULL, PR_FALSE);
- if (!rvList) {
- nssListIterator_Destroy(certs);
- return NULL;
- }
- for (cert = (NSSCertificate *)nssListIterator_Start(certs);
- cert != (NSSCertificate *)NULL;
- cert = (NSSCertificate *)nssListIterator_Next(certs))
- {
- if (nssItem_Equal(&cert->subject, subject, &nssrv)) {
- nssList_Add(rvList, nssCertificate_AddRef(cert));
- }
- }
- nssListIterator_Finish(certs);
- nssListIterator_Destroy(certs);
- if (nssList_Count(rvList) == 0) {
- nssList_Destroy(rvList);
- rvList = NULL;
- }
- return rvList;
-}
-
-/* remove all certs in a list that are not on the given token */
-static void
-filter_list_for_token_certs(nssList *certList, NSSToken *token)
-{
- nssListIterator *instances, *certs;
- nssCryptokiInstance *instance;
- NSSCertificate *c;
- PRBool isToken = PR_FALSE;
- certs = nssList_CreateIterator(certList);
- if (!certs) return;
- for (c = (NSSCertificate *)nssListIterator_Start(certs);
- c != (NSSCertificate *)NULL;
- c = (NSSCertificate *)nssListIterator_Next(certs)) {
- instances = c->object.instances;
- for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances);
- instance != (nssCryptokiInstance *)NULL;
- instance = (nssCryptokiInstance *)nssListIterator_Next(instances))
- {
- if (instance->token == token) {
- isToken = PR_TRUE;
- break;
- }
- }
- nssListIterator_Finish(instances);
- if (!isToken) {
- /* safe since iterator is copied */
- nssList_Remove(certList, c);
- CERT_DestroyCertificate(STAN_GetCERTCertificate(c));
- }
- }
- nssListIterator_Finish(certs);
- nssListIterator_Destroy(certs);
-}
-
SECStatus
PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
SECStatus(* callback)(CERTCertificate*, void *), void *arg)
@@ -2695,48 +2570,53 @@ PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
return PK11_TraverseSlot(slot, &callarg);
#else
- struct nss3_cert_cbstr pk11cb;
PRStatus nssrv = PR_SUCCESS;
NSSToken *token;
NSSDER subject;
NSSTrustDomain *td;
nssList *subjectList;
- nssTokenCertSearch search;
- pk11cb.callback = callback;
- pk11cb.arg = arg;
+ nssPKIObjectCollection *collection;
+ nssCryptokiObject **instances;
+ NSSCertificate **certs;
+ nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
td = STAN_GetDefaultTrustDomain();
NSSITEM_FROM_SECITEM(&subject, &cert->derSubject);
token = PK11Slot_GetNSSToken(slot);
- if (!nssToken_SearchCerts(token, NULL)) {
- subjectList = filter_token_certs_subject(token, &subject);
- if (subjectList) {
- nssrv = nssCertificateList_DoCallback(subjectList,
- convert_cert, &pk11cb);
+ if (!nssToken_IsPresent(token)) {
+ return SECSuccess;
+ }
+ collection = nssCertificateCollection_Create(td, NULL);
+ if (!collection) {
+ return SECFailure;
+ }
+ subjectList = nssList_Create(NULL, PR_FALSE);
+ if (!subjectList) {
+ nssPKIObjectCollection_Destroy(collection);
+ return SECFailure;
+ }
+ (void)nssTrustDomain_GetCertsForSubjectFromCache(td, &subject,
+ subjectList);
+ transfer_token_certs_to_collection(subjectList, token, collection);
+ instances = nssToken_FindCertificatesBySubject(token, NULL,
+ &subject,
+ tokenOnly, 0, &nssrv);
+ nssPKIObjectCollection_AddInstances(collection, instances, 0);
+ nss_ZFreeIf(instances);
+ nssList_Destroy(subjectList);
+ certs = nssPKIObjectCollection_GetCertificates(collection,
+ NULL, 0, NULL);
+ nssPKIObjectCollection_Destroy(collection);
+ if (certs) {
+ CERTCertificate *oldie;
+ NSSCertificate **cp;
+ for (cp = certs; *cp; cp++) {
+ oldie = STAN_GetCERTCertificate(*cp);
+ if ((*callback)(oldie, arg) != SECSuccess) {
+ nssrv = PR_FAILURE;
+ break;
+ }
}
- } else {
- subjectList = nssList_Create(NULL, PR_FALSE);
- if (!subjectList) {
- return SECFailure;
- }
- (void)nssTrustDomain_GetCertsForSubjectFromCache(td, &subject,
- subjectList);
- /* set the search criteria */
- search.callback = convert_and_cache_cert;
- search.cbarg = &pk11cb;
- search.cached = subjectList;
- search.searchType = nssTokenSearchType_TokenOnly;
- pk11cb.cached = subjectList;
- nssrv = nssToken_TraverseCertificatesBySubject(token, NULL,
- &subject, &search);
- if (nssrv == PR_SUCCESS) {
- filter_list_for_token_certs(subjectList, token);
- nssrv = nssCertificateList_DoCallback(subjectList,
- convert_cert, &pk11cb);
- }
- }
- if (subjectList) {
- nssList_Clear(subjectList, cert_destructor);
- nssList_Destroy(subjectList);
+ nssCertificateArray_Destroy(certs);
}
return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
#endif
@@ -2785,10 +2665,17 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
NSSTrustDomain *td;
NSSUTF8 *nick;
PRBool created = PR_FALSE;
- nssTokenCertSearch search;
- nssList *nameList;
+ nssCryptokiObject **instances;
+ nssPKIObjectCollection *collection = NULL;
+ NSSCertificate **certs;
+ nssList *nameList = NULL;
+ nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
pk11cb.callback = callback;
pk11cb.arg = arg;
+ token = PK11Slot_GetNSSToken(slot);
+ if (!nssToken_IsPresent(token)) {
+ return SECSuccess;
+ }
if (nickname->data[nickname->len-1] != '\0') {
nick = nssUTF8_Create(NULL, nssStringType_UTF8String,
nickname->data, nickname->len);
@@ -2797,36 +2684,50 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
nick = (NSSUTF8 *)nickname->data;
}
td = STAN_GetDefaultTrustDomain();
- token = PK11Slot_GetNSSToken(slot);
- if (!nssToken_SearchCerts(token, NULL)) {
- nameList = filter_token_certs_nickname(token, nick);
- if (nameList) {
- nssrv = nssCertificateList_DoCallback(nameList,
- convert_cert, &pk11cb);
- }
- } else {
- nameList = nssList_Create(NULL, PR_FALSE);
- (void)nssTrustDomain_GetCertsForNicknameFromCache(td, nick, nameList);
- /* set the search criteria */
- search.callback = convert_and_cache_cert;
- search.cbarg = &pk11cb;
- search.cached = nameList;
- search.searchType = nssTokenSearchType_TokenOnly;
- pk11cb.cached = nameList;
- nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
- nick, &search);
- if (nssrv == PR_SUCCESS) {
- filter_list_for_token_certs(nameList, token);
- nssrv = nssCertificateList_DoCallback(nameList,
- convert_cert, &pk11cb);
+ collection = nssCertificateCollection_Create(td, NULL);
+ if (!collection) {
+ goto loser;
+ }
+ nameList = nssList_Create(NULL, PR_FALSE);
+ if (!nameList) {
+ goto loser;
+ }
+ (void)nssTrustDomain_GetCertsForNicknameFromCache(td, nick, nameList);
+ transfer_token_certs_to_collection(nameList, token, collection);
+ instances = nssToken_FindCertificatesByNickname(token, NULL,
+ nick,
+ tokenOnly, 0, &nssrv);
+ nssPKIObjectCollection_AddInstances(collection, instances, 0);
+ nss_ZFreeIf(instances);
+ nssList_Destroy(nameList);
+ certs = nssPKIObjectCollection_GetCertificates(collection,
+ NULL, 0, NULL);
+ nssPKIObjectCollection_Destroy(collection);
+ if (certs) {
+ CERTCertificate *oldie;
+ NSSCertificate **cp;
+ for (cp = certs; *cp; cp++) {
+ oldie = STAN_GetCERTCertificate(*cp);
+ if ((*callback)(oldie, arg) != SECSuccess) {
+ nssrv = PR_FAILURE;
+ break;
+ }
}
+ nssCertificateArray_Destroy(certs);
+ }
+ if (created) nss_ZFreeIf(nick);
+ return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
+loser:
+ if (created) {
+ nss_ZFreeIf(nick);
+ }
+ if (collection) {
+ nssPKIObjectCollection_Destroy(collection);
}
if (nameList) {
- nssList_Clear(nameList, cert_destructor);
nssList_Destroy(nameList);
}
- if (created) nss_ZFreeIf(nick);
- return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
+ return SECFailure;
#endif
}
@@ -2862,62 +2763,49 @@ PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
#else
PRStatus nssrv;
NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
- struct nss3_cert_cbstr pk11cb;
NSSToken *tok;
nssList *certList = NULL;
- nssTokenCertSearch search;
- pk11cb.callback = callback;
- pk11cb.arg = arg;
+ nssCryptokiObject **instances;
+ nssPKIObjectCollection *collection;
+ NSSCertificate **certs;
+ nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
tok = PK11Slot_GetNSSToken(slot);
- if (!nssToken_SearchCerts(tok, NULL)) {
- certList = tok->certList;
- nssrv = nssCertificateList_DoCallback(certList, convert_cert, &pk11cb);
- } else {
- certList = nssList_Create(NULL, PR_FALSE);
- if (!certList) {
- return SECFailure;
- }
- (void *)nssTrustDomain_GetCertsFromCache(td, certList);
- /* set the search criteria */
- search.callback = convert_and_cache_cert;
- search.cbarg = &pk11cb;
- search.cached = certList;
- search.searchType = nssTokenSearchType_TokenOnly;
- pk11cb.cached = certList;
- nssrv = nssToken_TraverseCertificates(tok, NULL, &search);
- if (nssrv == PR_SUCCESS) {
- filter_list_for_token_certs(certList, tok);
- nssrv = nssCertificateList_DoCallback(certList,
- convert_cert, &pk11cb);
- }
- nssList_Clear(certList, cert_destructor);
- nssList_Destroy(certList);
+ if (!nssToken_IsPresent(tok)) {
+ return SECSuccess;
}
- return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
-#endif
-}
-
-static NSSCertificate *
-filter_token_certs_DER(NSSToken *token, NSSDER *der)
-{
- nssListIterator *certs;
- NSSCertificate *cert, *rvCert;
- PRStatus nssrv;
- certs = nssList_CreateIterator(token->certList);
- if (!certs) return NULL;
- rvCert = NULL;
- for (cert = (NSSCertificate *)nssListIterator_Start(certs);
- cert != (NSSCertificate *)NULL;
- cert = (NSSCertificate *)nssListIterator_Next(certs))
- {
- if (nssItem_Equal(&cert->encoding, der, &nssrv)) {
- rvCert = nssCertificate_AddRef(cert);
- break;
+ collection = nssCertificateCollection_Create(td, NULL);
+ if (!collection) {
+ return SECFailure;
+ }
+ certList = nssList_Create(NULL, PR_FALSE);
+ if (!certList) {
+ nssPKIObjectCollection_Destroy(collection);
+ return SECFailure;
+ }
+ (void *)nssTrustDomain_GetCertsFromCache(td, certList);
+ transfer_token_certs_to_collection(certList, tok, collection);
+ instances = nssToken_FindCertificates(tok, NULL,
+ tokenOnly, 0, &nssrv);
+ nssPKIObjectCollection_AddInstances(collection, instances, 0);
+ nss_ZFreeIf(instances);
+ nssList_Destroy(certList);
+ certs = nssPKIObjectCollection_GetCertificates(collection,
+ NULL, 0, NULL);
+ nssPKIObjectCollection_Destroy(collection);
+ if (certs) {
+ CERTCertificate *oldie;
+ NSSCertificate **cp;
+ for (cp = certs; *cp; cp++) {
+ oldie = STAN_GetCERTCertificate(*cp);
+ if ((*callback)(oldie, arg) != SECSuccess) {
+ nssrv = PR_FAILURE;
+ break;
+ }
}
+ nssCertificateArray_Destroy(certs);
}
- nssListIterator_Finish(certs);
- nssListIterator_Destroy(certs);
- return rvCert;
+ return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
+#endif
}
/*
@@ -2970,14 +2858,23 @@ PK11_FindCertFromDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
return NULL;
}
}
- if (!nssToken_SearchCerts(tok, NULL)) {
- c = filter_token_certs_DER(tok, &derCert);
- } else {
- c = nssTrustDomain_GetCertByDERFromCache(td, &derCert);
- if (!c) {
- c = nssToken_FindCertificateByEncodedCertificate(tok, NULL,
- &derCert,
- nssTokenSearchType_TokenOnly);
+ c = NSSTrustDomain_FindCertificateByEncodedCertificate(td, &derCert);
+ if (c) {
+ PRBool isToken = PR_FALSE;
+ NSSToken **tp;
+ NSSToken **tokens = nssPKIObject_GetTokens(&c->object, NULL);
+ if (tokens) {
+ for (tp = tokens; *tp; tp++) {
+ if (*tp == tok) {
+ isToken = PR_TRUE;
+ break;
+ }
+ }
+ if (!isToken) {
+ NSSCertificate_Destroy(c);
+ c = NULL;
+ }
+ nssTokenArray_Destroy(tokens);
}
}
if (c) {
@@ -3348,12 +3245,16 @@ pk11ListCertCallback(CERTCertificate *cert, void *arg)
CERTCertList *certList = listCertP->certList;
CERTCertTrust *trust;
PRBool isUnique = PR_FALSE;
+ PRBool isCA = PR_FALSE;
char *nickname = NULL;
unsigned int certType;
if ((type == PK11CertListUnique) || (type == PK11CertListRootUnique)) {
isUnique = PR_TRUE;
}
+ if ((type == PK11CertListCA) || (type == PK11CertListRootUnique)) {
+ isCA = PR_TRUE;
+ }
/* at this point the nickname is correct for the cert. save it for later */
if (!isUnique && cert->nickname) {
nickname = PORT_ArenaStrdup(listCertP->certList->arena,cert->nickname);
@@ -3397,7 +3298,7 @@ pk11ListCertCallback(CERTCertificate *cert, void *arg)
}
/* if we want CA certs and it ain't one, skip it */
- if( type == PK11CertListCA && (!CERT_IsCACert(newCert, &certType)) ) {
+ if( isCA && (!CERT_IsCACert(newCert, &certType)) ) {
CERT_DestroyCertificate(newCert);
return SECSuccess;
}
@@ -3440,7 +3341,18 @@ PK11_ListCerts(PK11CertListType type, void *pwarg)
listCerts.certList = certList;
pk11cb.callback = pk11ListCertCallback;
pk11cb.arg = &listCerts;
- NSSTrustDomain_TraverseCertificates(defaultTD, convert_cert, &pk11cb);
+
+ /* authenticate to the slots */
+ (void) pk11_TraverseAllSlots( NULL, NULL, pwarg);
+#ifdef notdef
+ if (type == PK11CertListUser) {
+ NSSTrustDomain_TraverseUserCertificates(defaultTD, convert_cert &pk11cb);
+ } else {
+ NSSTrustDomain_TraverseCertificates(defaultTD, convert_cert, &pk11cb);
+ }
+#else
+ NSSTrustDomain_TraverseCertificates(defaultTD, convert_cert, &pk11cb);
+#endif
return certList;
#endif
}
@@ -3592,7 +3504,6 @@ PK11_ListPublicKeysInSlot(PK11SlotInfo *slot, char *nickname)
int tsize = 0;
int objCount = 0;
CK_OBJECT_HANDLE *key_ids;
- SECStatus status;
SECKEYPublicKeyList *keys;
int i,len;
@@ -3619,7 +3530,9 @@ PK11_ListPublicKeysInSlot(PK11SlotInfo *slot, char *nickname)
for (i=0; i < objCount ; i++) {
SECKEYPublicKey *pubKey =
PK11_ExtractPublicKey(slot,nullKey,key_ids[i]);
- SECKEY_AddPublicKeyToListTail(keys, pubKey);
+ if (pubKey) {
+ SECKEY_AddPublicKeyToListTail(keys, pubKey);
+ }
}
PORT_Free(key_ids);
@@ -3636,7 +3549,6 @@ PK11_ListPrivKeysInSlot(PK11SlotInfo *slot, char *nickname, void *wincx)
int tsize = 0;
int objCount = 0;
CK_OBJECT_HANDLE *key_ids;
- SECStatus status;
SECKEYPrivateKeyList *keys;
int i,len;
@@ -3677,6 +3589,7 @@ SECItem *
PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle,
SECItem *name, int type, char **url)
{
+#ifdef NSS_CLASSIC
CK_OBJECT_CLASS crlClass = CKO_NETSCAPE_CRL;
CK_ATTRIBUTE theTemplate[] = {
{ CKA_SUBJECT, NULL, 0 },
@@ -3710,9 +3623,6 @@ PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle,
/* loop through all the fortezza tokens */
for (le = list->head; le; le = le->next) {
- if (le->slot->nssToken && !nssToken_HasCrls(le->slot->nssToken)) {
- continue;
- }
crlh = pk11_FindObjectByTemplate(le->slot,theTemplate,tsize);
if (crlh != CK_INVALID_HANDLE) {
*slot = PK11_ReferenceSlot(le->slot);
@@ -3759,12 +3669,68 @@ loser:
}
if (crlData[1].pValue) PORT_Free(crlData[1].pValue);
return derCrl;
+#else
+ NSSCRL **crls, **crlp, *crl;
+ NSSDER subject;
+ SECItem *rvItem;
+ NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
+ NSSITEM_FROM_SECITEM(&subject, name);
+ if (*slot) {
+ nssCryptokiObject **instances;
+ nssPKIObjectCollection *collection;
+ nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
+ NSSToken *token = PK11Slot_GetNSSToken(*slot);
+ collection = nssCRLCollection_Create(td, NULL);
+ if (!collection) {
+ return NULL;
+ }
+ instances = nssToken_FindCRLsBySubject(token, NULL, &subject,
+ tokenOnly, 0, NULL);
+ nssPKIObjectCollection_AddInstances(collection, instances, 0);
+ nss_ZFreeIf(instances);
+ crls = nssPKIObjectCollection_GetCRLs(collection, NULL, 0, NULL);
+ nssPKIObjectCollection_Destroy(collection);
+ } else {
+ crls = nssTrustDomain_FindCRLsBySubject(td, &subject);
+ }
+ if (!crls) {
+ return NULL;
+ }
+ crl = NULL;
+ for (crlp = crls; *crlp; crlp++) {
+ if ((!(*crlp)->isKRL && type == SEC_CRL_TYPE) ||
+ ((*crlp)->isKRL && type != SEC_CRL_TYPE))
+ {
+ crl = nssCRL_AddRef(*crlp);
+ break;
+ }
+ }
+ nssCRLArray_Destroy(crls);
+ if (!crl) {
+ return NULL;
+ }
+ *slot = PK11_ReferenceSlot(crl->object.instances[0]->token->pk11slot);
+ *crlHandle = crl->object.instances[0]->handle;
+ if (crl->url) {
+ *url = PORT_Strdup(crl->url);
+ }
+ rvItem = SECITEM_AllocItem(NULL, NULL, crl->encoding.size);
+ if (!rvItem) {
+ PORT_Free(*url);
+ nssCRL_Destroy(crl);
+ return NULL;
+ }
+ memcpy(rvItem->data, crl->encoding.data, crl->encoding.size);
+ nssCRL_Destroy(crl);
+ return rvItem;
+#endif
}
CK_OBJECT_HANDLE
PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, SECItem *name,
char *url, int type)
{
+#ifdef NSS_CLASSIC
CK_OBJECT_CLASS crlClass = CKO_NETSCAPE_CRL;
CK_ATTRIBUTE theTemplate[] = {
{ CKA_SUBJECT, NULL, 0 },
@@ -3810,12 +3776,29 @@ PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, SECItem *name,
PK11_RestoreROSession(slot,rwsession);
- if (slot->nssToken) {
- nssToken_SetHasCrls(slot->nssToken);
- }
return crlh;
-}
+#else
+ NSSItem derCRL, derSubject;
+ NSSToken *token = PK11Slot_GetNSSToken(slot);
+ nssCryptokiObject *object;
+ PRBool isKRL = (type == SEC_CRL_TYPE) ? PR_FALSE : PR_TRUE;
+ CK_OBJECT_HANDLE rvH;
+ NSSITEM_FROM_SECITEM(&derSubject, name);
+ NSSITEM_FROM_SECITEM(&derCRL, crl);
+
+ object = nssToken_ImportCRL(token, NULL,
+ &derSubject, &derCRL, isKRL, url, PR_TRUE);
+
+ if (object) {
+ rvH = object->handle;
+ nssCryptokiObject_Destroy(object);
+ } else {
+ rvH = CK_INVALID_HANDLE;
+ }
+ return rvH;
+#endif
+}
/*
@@ -3824,6 +3807,7 @@ PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, SECItem *name,
SECStatus
SEC_DeletePermCRL(CERTSignedCrl *crl)
{
+#ifdef NSS_CLASSIC
PK11SlotInfo *slot = crl->slot;
CK_RV crv;
@@ -3836,12 +3820,34 @@ SEC_DeletePermCRL(CERTSignedCrl *crl)
crv = PK11_DestroyTokenObject(slot,crl->pkcs11ID);
if (crv != CKR_OK) {
PORT_SetError( PK11_MapError(crv) );
- goto loser;
+ return SECFailure;
}
crl->slot = NULL;
PK11_FreeSlot(slot);
-loser:
return SECSuccess;
+#else
+ PRStatus status;
+ NSSToken *token;
+ nssCryptokiObject *object;
+ PK11SlotInfo *slot = crl->slot;
+
+ if (slot == NULL) {
+ /* shouldn't happen */
+ PORT_SetError( SEC_ERROR_CRL_INVALID);
+ return SECFailure;
+ }
+ token = PK11Slot_GetNSSToken(slot);
+
+ object = nss_ZNEW(NULL, nssCryptokiObject);
+ object->token = nssToken_AddRef(token);
+ object->handle = crl->pkcs11ID;
+ object->isTokenObject = PR_TRUE;
+
+ status = nssToken_DeleteStoredObject(object);
+
+ nssCryptokiObject_Destroy(object);
+ return (status == PR_SUCCESS) ? SECSuccess : SECFailure;
+#endif
}
/*
@@ -3966,6 +3972,7 @@ PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj,
CK_OBJECT_HANDLE smimeh = CK_INVALID_HANDLE;
CK_ATTRIBUTE *attrs = theTemplate;
CK_SESSION_HANDLE rwsession;
+ PK11SlotInfo *free_slot = NULL;
CK_RV crv;
#ifdef DEBUG
int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]);
@@ -3986,13 +3993,16 @@ PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj,
PORT_Assert (realSize <= tsize);
if (slot == NULL) {
- slot = PK11_GetInternalKeySlot();
+ free_slot = slot = PK11_GetInternalKeySlot();
/* we need to free the key slot in the end!!! */
}
rwsession = PK11_GetRWSession(slot);
if (rwsession == CK_INVALID_SESSION) {
PORT_SetError(SEC_ERROR_READ_ONLY);
+ if (free_slot) {
+ PK11_FreeSlot(free_slot);
+ }
return SECFailure;
}
@@ -4003,6 +4013,10 @@ PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj,
}
PK11_RestoreROSession(slot,rwsession);
+
+ if (free_slot) {
+ PK11_FreeSlot(free_slot);
+ }
return SECSuccess;
}
diff --git a/security/nss/lib/pk11wrap/pk11pars.c b/security/nss/lib/pk11wrap/pk11pars.c
index 71ed7b0b7..b1602f1c8 100644
--- a/security/nss/lib/pk11wrap/pk11pars.c
+++ b/security/nss/lib/pk11wrap/pk11pars.c
@@ -40,6 +40,7 @@
#include "seccomon.h"
#include "secmod.h"
#include "secmodi.h"
+#include "pki3hack.h"
#include "pk11pars.h"
@@ -144,6 +145,8 @@ SECMOD_CreateModule(char *library, char *moduleName, char *parameters, char *nss
pk11_argSetNewCipherFlags(&mod->ssl[0],ciphers);
if (ciphers) PORT_Free(ciphers);
+ secmod_PrivateModuleCount++;
+
return mod;
}
@@ -261,15 +264,16 @@ SECMOD_DeletePermDB(SECMODModule *module)
}
SECStatus
-SECMOD_FreeModuleSpecList(SECMODModule *parent, char **moduleSpecList)
+SECMOD_FreeModuleSpecList(SECMODModule *module, char **moduleSpecList)
{
- char ** index;
-
- for(index = moduleSpecList; *index; index++) {
- PORT_Free(*index);
+ SECMODModuleDBFunc func = (SECMODModuleDBFunc) module->moduleDBFunc;
+ char **retString;
+ if (func) {
+ retString = (*func)(SECMOD_MODULE_DB_FUNCTION_RELEASE,
+ module->libraryParams,moduleSpecList);
+ if (retString != NULL) return SECSuccess;
}
- PORT_Free(moduleSpecList);
- return SECSuccess;
+ return SECFailure;
}
/*
diff --git a/security/nss/lib/pk11wrap/pk11pbe.c b/security/nss/lib/pk11wrap/pk11pbe.c
index 71548a07a..5d828dba3 100644
--- a/security/nss/lib/pk11wrap/pk11pbe.c
+++ b/security/nss/lib/pk11wrap/pk11pbe.c
@@ -504,6 +504,7 @@ PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
SECItem mechItem;
CK_PBE_PARAMS pbe_params;
CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM;
+ PK11SlotInfo *slot;
PK11SymKey *symKey = NULL;
unsigned char ivData[8];
@@ -567,8 +568,10 @@ PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
mechItem.len = sizeof(pbe_params);
- symKey = PK11_RawPBEKeyGen(PK11_GetInternalSlot(),mechanism,
+ slot = PK11_GetInternalSlot();
+ symKey = PK11_RawPBEKeyGen(slot,mechanism,
&mechItem, pwitem, PR_FALSE, NULL);
+ PK11_FreeSlot(slot);
if (symKey != NULL) {
if (bitGenPurpose == pbeBitGenCipherIV) {
/* NOTE: this assumes that bitsNeeded is a multiple of 8! */
@@ -615,6 +618,7 @@ SEC_PKCS5GetIV(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES)
SECItem *iv = NULL;
SECStatus rv;
int iv_len;
+ PK11SlotInfo *slot;
PK11SymKey *symKey;
rv = pbe_PK11AlgidToParam(algid,&mechItem);
@@ -626,8 +630,10 @@ SEC_PKCS5GetIV(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES)
iv_len = PK11_GetIVLength(mechanism);
pbe_params = (CK_PBE_PARAMS_PTR)mechItem.data;
- symKey = PK11_RawPBEKeyGen(PK11_GetInternalSlot(),mechanism,
+ slot = PK11_GetInternalSlot();
+ symKey = PK11_RawPBEKeyGen(slot,mechanism,
&mechItem, pwitem, faulty3DES,NULL);
+ PK11_FreeSlot(slot);
if (symKey) {
SECItem tmp;
diff --git a/security/nss/lib/pk11wrap/pk11skey.c b/security/nss/lib/pk11wrap/pk11skey.c
index b77b718fb..7955a203e 100644
--- a/security/nss/lib/pk11wrap/pk11skey.c
+++ b/security/nss/lib/pk11wrap/pk11skey.c
@@ -161,7 +161,6 @@ static PK11SymKey *
pk11_getKeyFromList(PK11SlotInfo *slot) {
PK11SymKey *symKey = NULL;
-
PK11_USE_THREADS(PZ_Lock(slot->freeListLock);)
if (slot->freeSymKeysHead) {
symKey = slot->freeSymKeysHead;
@@ -180,11 +179,6 @@ pk11_getKeyFromList(PK11SlotInfo *slot) {
if (symKey == NULL) {
return NULL;
}
- symKey->refLock = PZ_NewLock(nssILockRefLock);
- if (symKey->refLock == NULL) {
- PORT_Free(symKey);
- return NULL;
- }
symKey->session = pk11_GetNewSession(slot,&symKey->sessionOwner);
symKey->next = NULL;
return symKey;
@@ -199,7 +193,6 @@ PK11_CleanKeyList(PK11SlotInfo *slot)
symKey = slot->freeSymKeysHead;
slot->freeSymKeysHead = symKey->next;
pk11_CloseSession(slot, symKey->session,symKey->sessionOwner);
- PK11_USE_THREADS(PZ_DestroyLock(symKey->refLock);)
PORT_Free(symKey);
};
return;
@@ -243,16 +236,10 @@ PK11_CreateSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, void *wincx)
void
PK11_FreeSymKey(PK11SymKey *symKey)
{
- PRBool destroy = PR_FALSE;
PK11SlotInfo *slot;
PRBool freeit = PR_TRUE;
- PK11_USE_THREADS(PZ_Lock(symKey->refLock);)
- if (symKey->refCount-- == 1) {
- destroy= PR_TRUE;
- }
- PK11_USE_THREADS(PZ_Unlock(symKey->refLock);)
- if (destroy) {
+ if (PR_AtomicDecrement(&symKey->refCount) == 0) {
if ((symKey->owner) && symKey->objectID != CK_INVALID_HANDLE) {
pk11_EnterKeyMonitor(symKey);
(void) PK11_GETTAB(symKey->slot)->
@@ -266,17 +253,16 @@ PK11_FreeSymKey(PK11SymKey *symKey)
slot = symKey->slot;
PK11_USE_THREADS(PZ_Lock(slot->freeListLock);)
if (slot->keyCount < slot->maxKeyCount) {
- symKey->next = slot->freeSymKeysHead;
- slot->freeSymKeysHead = symKey;
- slot->keyCount++;
- symKey->slot = NULL;
- freeit = PR_FALSE;
+ symKey->next = slot->freeSymKeysHead;
+ slot->freeSymKeysHead = symKey;
+ slot->keyCount++;
+ symKey->slot = NULL;
+ freeit = PR_FALSE;
}
PK11_USE_THREADS(PZ_Unlock(slot->freeListLock);)
if (freeit) {
pk11_CloseSession(symKey->slot, symKey->session,
symKey->sessionOwner);
- PK11_USE_THREADS(PZ_DestroyLock(symKey->refLock);)
PORT_Free(symKey);
}
PK11_FreeSlot(slot);
@@ -286,9 +272,7 @@ PK11_FreeSymKey(PK11SymKey *symKey)
PK11SymKey *
PK11_ReferenceSymKey(PK11SymKey *symKey)
{
- PK11_USE_THREADS(PZ_Lock(symKey->refLock);)
- symKey->refCount++;
- PK11_USE_THREADS(PZ_Unlock(symKey->refLock);)
+ PR_AtomicIncrement(&symKey->refCount);
return symKey;
}
@@ -1568,7 +1552,6 @@ pk11_PairwiseConsistencyCheck(SECKEYPublicKey *pubKey,
PK11_ExitSlotMonitor(slot);
PORT_SetError( PK11_MapError(crv) );
PORT_Free( ciphertext );
- PK11_FreeSlot(slot);
return SECFailure;
}
@@ -1591,7 +1574,6 @@ pk11_PairwiseConsistencyCheck(SECKEYPublicKey *pubKey,
if( crv != CKR_OK ) {
PORT_SetError( PK11_MapError(crv) );
- PK11_FreeSlot(slot);
return SECFailure;
}
@@ -1602,7 +1584,6 @@ pk11_PairwiseConsistencyCheck(SECKEYPublicKey *pubKey,
PAIRWISE_MESSAGE_LENGTH ) != 0 ) ) {
/* Set error to Bad PUBLIC Key. */
PORT_SetError( SEC_ERROR_BAD_KEY );
- PK11_FreeSlot(slot);
return SECFailure;
}
}
@@ -3207,12 +3188,14 @@ PK11_PubEncryptRaw(SECKEYPublicKey *key, unsigned char *enc,
if (crv != CKR_OK) {
if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot);
pk11_CloseSession(slot,session,owner);
+ PK11_FreeSlot(slot);
PORT_SetError( PK11_MapError(crv) );
return SECFailure;
}
crv = PK11_GETTAB(slot)->C_Encrypt(session,data,dataLen,enc,&out);
if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot);
pk11_CloseSession(slot,session,owner);
+ PK11_FreeSlot(slot);
if (crv != CKR_OK) {
PORT_SetError( PK11_MapError(crv) );
return SECFailure;
@@ -4463,7 +4446,7 @@ PK11_ExportEncryptedPrivateKeyInfo(PK11SlotInfo *slot, SECOidTag algTag,
SECItem *pwitem, CERTCertificate *cert, int iteration, void *wincx)
{
SECKEYEncryptedPrivateKeyInfo *epki = NULL;
- SECKEYPrivateKey *pk;
+ SECKEYPrivateKey *pk = NULL;
PRArenaPool *arena = NULL;
SECAlgorithmID *algid;
CK_MECHANISM_TYPE mechanism;
@@ -4580,6 +4563,10 @@ loser:
PK11_FreeSymKey(key);
}
+ if (pk != NULL) {
+ SECKEY_DestroyPrivateKey(pk);
+ }
+
if(rv == SECFailure) {
if(arena != NULL) {
PORT_FreeArena(arena, PR_TRUE);
@@ -4771,8 +4758,11 @@ PK11_WrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey,
privSlot = int_slot; /* The private key has a new home */
newPrivKey = pk11_loadPrivKey(privSlot,privKey,NULL,PR_FALSE,PR_FALSE);
+ /* newPrivKey has allocated its own reference to the slot, so it's
+ * safe until we destroy newPrivkey.
+ */
+ PK11_FreeSlot(int_slot);
if (newPrivKey == NULL) {
- PK11_FreeSlot (int_slot);
return SECFailure;
}
privKey = newPrivKey;
diff --git a/security/nss/lib/pk11wrap/pk11slot.c b/security/nss/lib/pk11wrap/pk11slot.c
index cd2d29bd4..6d93bc650 100644
--- a/security/nss/lib/pk11wrap/pk11slot.c
+++ b/security/nss/lib/pk11wrap/pk11slot.c
@@ -54,6 +54,7 @@
#include "dev.h"
#include "dev3hack.h"
#include "pki3hack.h"
+#include "pkim.h"
/*************************************************************
@@ -727,10 +728,6 @@ PK11_Logout(PK11SlotInfo *slot)
PK11_EnterSlotMonitor(slot);
crv = PK11_GETTAB(slot)->C_Logout(slot->session);
PK11_ExitSlotMonitor(slot);
- if (slot->nssToken && !PK11_IsFriendly(slot)) {
- /* If the slot certs are not public readable, destroy them */
- nssToken_DestroyCertList(slot->nssToken, PR_TRUE);
- }
if (crv != CKR_OK) {
PORT_SetError(PK11_MapError(crv));
return SECFailure;
@@ -1146,10 +1143,9 @@ PK11_DoPassword(PK11SlotInfo *slot, PRBool loadCerts, void *wincx)
}
if (rv == SECSuccess) {
rv = pk11_CheckVerifyTest(slot);
- if (rv == SECSuccess && slot->nssToken && !PK11_IsFriendly(slot)) {
- /* notify stan about the login if certs are not public readable */
- nssToken_LoadCerts(slot->nssToken);
- nssToken_UpdateTrustForCerts(slot->nssToken);
+ if (!PK11_IsFriendly(slot)) {
+ nssTrustDomain_UpdateCachedTokenCerts(slot->nssToken->trustDomain,
+ slot->nssToken);
}
} else if (!attempt) PORT_SetError(SEC_ERROR_BAD_PASSWORD);
return rv;
@@ -1571,7 +1567,10 @@ PK11_VerifySlotMechanisms(PK11SlotInfo *slot)
mechList = (CK_MECHANISM_TYPE *)
PORT_Alloc(count *sizeof(CK_MECHANISM_TYPE));
alloced = PR_TRUE;
- if (mechList == NULL) return PR_FALSE;
+ if (mechList == NULL) {
+ PK11_FreeSlot(intern);
+ return PR_FALSE;
+ }
}
/* get the list */
if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
@@ -1718,6 +1717,11 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
slot->protectedAuthPath =
((tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
? PR_TRUE : PR_FALSE);
+ /* on some platforms Active Card incorrectly sets the
+ * CKF_PROTECTED_AUTHENTICATION_PATH bit when it doesn't mean to. */
+ if (slot->isActiveCard) {
+ slot->protectedAuthPath = PR_FALSE;
+ }
tmp = PK11_MakeString(NULL,slot->token_name,
(char *)tokenInfo.label, sizeof(tokenInfo.label));
slot->minPassword = tokenInfo.ulMinPinLen;
@@ -1826,6 +1830,7 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
random_bytes, sizeof(random_bytes));
PK11_ExitSlotMonitor(slot);
}
+ PK11_FreeSlot(int_slot);
}
}
@@ -1891,6 +1896,9 @@ PK11_InitSlot(SECMODModule *mod,CK_SLOT_ID slotID,PK11SlotInfo *slot)
tmp = PK11_MakeString(NULL,slot->slot_name,
(char *)slotInfo.slotDescription, sizeof(slotInfo.slotDescription));
slot->isHW = (PRBool)((slotInfo.flags & CKF_HW_SLOT) == CKF_HW_SLOT);
+#define ACTIVE_CARD "ActivCard SA"
+ slot->isActiveCard = (PRBool)(PORT_Strncmp((char *)slotInfo.manufacturerID,
+ ACTIVE_CARD, sizeof(ACTIVE_CARD)-1) == 0);
if ((slotInfo.flags & CKF_REMOVABLE_DEVICE) == 0) {
slot->isPerm = PR_TRUE;
/* permanment slots must have the token present always */
@@ -4356,12 +4364,18 @@ PK11_MapPBEMechanismToCryptoMechanism(CK_MECHANISM_PTR pPBEMechanism,
if (pk11_isAllZero(pPBEparams->pInitVector,iv_len)) {
SECItem param;
PK11SymKey *symKey;
+ PK11SlotInfo *intSlot = PK11_GetInternalSlot();
+
+ if (intSlot == NULL) {
+ return CKR_DEVICE_ERROR;
+ }
param.data = pPBEMechanism->pParameter;
param.len = pPBEMechanism->ulParameterLen;
- symKey = PK11_RawPBEKeyGen(PK11_GetInternalSlot(),
+ symKey = PK11_RawPBEKeyGen(intSlot,
pPBEMechanism->mechanism, &param, pbe_pwd, faulty3DES, NULL);
+ PK11_FreeSlot(intSlot);
if (symKey== NULL) {
return CKR_DEVICE_ERROR; /* sigh */
}
diff --git a/security/nss/lib/pk11wrap/pk11util.c b/security/nss/lib/pk11wrap/pk11util.c
index 67b439125..11673d9f6 100644
--- a/security/nss/lib/pk11wrap/pk11util.c
+++ b/security/nss/lib/pk11wrap/pk11util.c
@@ -39,6 +39,7 @@
#include "secmodi.h"
#include "pk11func.h"
#include "pki3hack.h"
+#include "secerr.h"
/* these are for displaying error messages */
@@ -47,13 +48,17 @@ static SECMODModuleList *modulesDB = NULL;
static SECMODModuleList *modulesUnload = NULL;
static SECMODModule *internalModule = NULL;
static SECMODModule *defaultDBModule = NULL;
+static SECMODModule *pendingModule = NULL;
static SECMODListLock *moduleLock = NULL;
+int secmod_PrivateModuleCount = 0;
+
extern PK11DefaultArrayEntry PK11_DefaultArray[];
extern int num_pk11_default_mechanisms;
-void SECMOD_Init() {
+void
+SECMOD_Init() {
/* don't initialize twice */
if (moduleLock) return;
@@ -62,7 +67,8 @@ void SECMOD_Init() {
}
-void SECMOD_Shutdown() {
+SECStatus
+SECMOD_Shutdown() {
/* destroy the lock */
if (moduleLock) {
SECMOD_DestroyListLock(moduleLock);
@@ -73,6 +79,13 @@ void SECMOD_Shutdown() {
SECMOD_DestroyModule(internalModule);
internalModule = NULL;
}
+
+ /* free the default database module */
+ if (defaultDBModule) {
+ SECMOD_DestroyModule(defaultDBModule);
+ defaultDBModule = NULL;
+ }
+
/* destroy the list */
if (modules) {
SECMOD_DestroyModuleList(modules);
@@ -91,6 +104,13 @@ void SECMOD_Shutdown() {
/* make all the slots and the lists go away */
PK11_DestroySlotLists();
+
+#ifdef DEBUG
+ if (PR_GetEnv("NSS_STRICT_SHUTDOWN")) {
+ PORT_Assert(secmod_PrivateModuleCount == 0);
+ }
+#endif
+ return (secmod_PrivateModuleCount == 0) ? SECSuccess : SECFailure;
}
@@ -285,6 +305,11 @@ SECMOD_DeleteInternalModule(char *name) {
SECMODModuleList **mlpp;
SECStatus rv = SECFailure;
+ if (pendingModule) {
+ PORT_SetError(SEC_ERROR_MODULE_STUCK);
+ return rv;
+ }
+
SECMOD_GetWriteLock(moduleLock);
for(mlpp = &modules,mlp = modules;
mlp != NULL; mlpp = &mlp->next, mlp = *mlpp) {
@@ -329,12 +354,12 @@ SECMOD_DeleteInternalModule(char *name) {
}
newModule->libraryParams =
PORT_ArenaStrdup(newModule->arena,mlp->module->libraryParams);
- oldModule = internalModule;
+ pendingModule = oldModule = internalModule;
internalModule = NULL;
SECMOD_DestroyModule(oldModule);
SECMOD_DeletePermDB(mlp->module);
SECMOD_DestroyModuleListElement(mlp);
- internalModule = SECMOD_ReferenceModule(newModule);
+ internalModule = newModule; /* adopt the module */
SECMOD_AddModule(internalModule);
}
return rv;
@@ -434,6 +459,10 @@ SECStatus SECMOD_AddNewModuleEx(char* moduleName, char* dllPath,
module = SECMOD_CreateModule(dllPath,moduleName, modparms, nssparms);
+ if (module == NULL) {
+ return result;
+ }
+
if (module->dllName != NULL) {
if (module->dllName[0] != 0) {
result = SECMOD_AddModule(module);
@@ -485,8 +514,8 @@ SECStatus SECMOD_UpdateModule(SECMODModule *module)
result = SECMOD_DeletePermDB(module);
if (result == SECSuccess) {
- }
result = SECMOD_AddPermDB(module);
+ }
return result;
}
@@ -590,6 +619,13 @@ SECMOD_DestroyModule(SECMODModule *module) {
if (!willfree) {
return;
}
+
+ if (module->parent != NULL) {
+ SECMODModule *parent = module->parent;
+ /* paranoia, don't loop forever if the modules are looped */
+ module->parent = NULL;
+ SECMOD_DestroyModule(parent);
+ }
/* slots can't really disappear until our module starts freeing them,
* so this check is safe */
@@ -627,11 +663,17 @@ SECMOD_SlotDestroyModule(SECMODModule *module, PRBool fromSlot) {
PK11_USE_THREADS(PZ_Unlock((PZLock *)module->refLock);)
if (!willfree) return;
}
+
+ if (module == pendingModule) {
+ pendingModule = NULL;
+ }
+
if (module->loaded) {
SECMOD_UnloadModule(module);
}
PK11_USE_THREADS(PZ_DestroyLock((PZLock *)module->refLock);)
PORT_FreeArena(module->arena,PR_FALSE);
+ secmod_PrivateModuleCount--;
}
/* destroy a list element
@@ -661,3 +703,8 @@ SECMOD_DestroyModuleList(SECMODModuleList *list) {
for ( lp = list; lp != NULL; lp = SECMOD_DestroyModuleListElement(lp)) ;
}
+PRBool
+SECMOD_CanDeleteInternalModule(void)
+{
+ return (PRBool) pendingModule == NULL;
+}
diff --git a/security/nss/lib/pk11wrap/secmod.h b/security/nss/lib/pk11wrap/secmod.h
index 303e3fe58..64461a112 100644
--- a/security/nss/lib/pk11wrap/secmod.h
+++ b/security/nss/lib/pk11wrap/secmod.h
@@ -91,7 +91,7 @@ SECStatus SECMOD_UnloadUserModule(SECMODModule *mod);
SECMODModule * SECMOD_CreateModule(char *lib, char *name, char *param,
char *nss);
-extern void SECMOD_Shutdown(void);
+extern SECStatus SECMOD_Shutdown(void);
/* Module Management */
@@ -117,6 +117,7 @@ extern void SECMOD_ReleaseWriteLock(SECMODListLock *);
extern SECMODModule *SECMOD_FindModule(char *name);
extern SECStatus SECMOD_DeleteModule(char *name, int *type);
extern SECStatus SECMOD_DeleteInternalModule(char *name);
+extern PRBool SECMOD_CanDeleteInternalModule(void);
extern SECStatus SECMOD_AddNewModule(char* moduleName, char* dllPath,
unsigned long defaultMechanismFlags,
unsigned long cipherEnableFlags);
diff --git a/security/nss/lib/pk11wrap/secmodi.h b/security/nss/lib/pk11wrap/secmodi.h
index 9e78addb4..050f7de4f 100644
--- a/security/nss/lib/pk11wrap/secmodi.h
+++ b/security/nss/lib/pk11wrap/secmodi.h
@@ -57,6 +57,8 @@ SEC_BEGIN_PROTOS
extern SECStatus SECMOD_DeletePermDB(SECMODModule *module);
extern SECStatus SECMOD_AddPermDB(SECMODModule *module);
+extern int secmod_PrivateModuleCount;
+
extern void SECMOD_Init(void);
/* list managment */
diff --git a/security/nss/lib/pk11wrap/secmodti.h b/security/nss/lib/pk11wrap/secmodti.h
index 9d3919903..232b58c7a 100644
--- a/security/nss/lib/pk11wrap/secmodti.h
+++ b/security/nss/lib/pk11wrap/secmodti.h
@@ -130,6 +130,7 @@ struct PK11SlotInfoStr {
PRBool hasRSAInfo;
CK_FLAGS RSAInfoFlags;
PRBool protectedAuthPath;
+ PRBool isActiveCard;
/* for Stan */
NSSToken *nssToken;
};
@@ -145,8 +146,7 @@ struct PK11SymKeyStr {
SECItem data; /* raw key data if available */
CK_SESSION_HANDLE session;
PRBool sessionOwner;
- int refCount; /* number of references to this key */
- PZLock *refLock;
+ PRInt32 refCount; /* number of references to this key */
int size; /* key size in bytes */
PK11Origin origin; /* where this key came from
(see def in secmodt.h) */
diff --git a/security/nss/lib/pkcs12/p12d.c b/security/nss/lib/pkcs12/p12d.c
index 051428575..ca5017cc5 100644
--- a/security/nss/lib/pkcs12/p12d.c
+++ b/security/nss/lib/pkcs12/p12d.c
@@ -1093,7 +1093,7 @@ p12u_DigestRead(void *arg, unsigned char *buf, unsigned long len)
return -1;
}
- if (!p12cxt->buffer || ((p12cxt->filesize-p12cxt->currentpos)<len) ) {
+ if (!p12cxt->buffer || ((p12cxt->filesize-p12cxt->currentpos)<(long)len) ) {
/* trying to read past the end of the buffer */
toread = p12cxt->filesize-p12cxt->currentpos;
}
@@ -1111,7 +1111,7 @@ p12u_DigestWrite(void *arg, unsigned char *buf, unsigned long len)
return -1;
}
- if (p12cxt->currentpos+len > p12cxt->filesize) {
+ if (p12cxt->currentpos+(long)len > p12cxt->filesize) {
p12cxt->filesize = p12cxt->currentpos + len;
}
else {
@@ -1191,7 +1191,8 @@ SEC_PKCS12DecoderStart(SECItem *pwitem, PK11SlotInfo *slot, void *wincx,
p12dcx->arena = arena;
p12dcx->pwitem = pwitem;
- p12dcx->slot = (slot ? slot : PK11_GetInternalKeySlot());
+ p12dcx->slot = (slot ? PK11_ReferenceSlot(slot)
+ : PK11_GetInternalKeySlot());
p12dcx->wincx = wincx;
#ifdef IS_LITTLE_ENDIAN
p12dcx->swapUnicodeBytes = PR_TRUE;
@@ -1201,12 +1202,6 @@ SEC_PKCS12DecoderStart(SECItem *pwitem, PK11SlotInfo *slot, void *wincx,
p12dcx->errorValue = 0;
p12dcx->error = PR_FALSE;
- /* a slot is *required */
- if(!slot) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
/* start the decoding of the PFX and set the notify proc
* for the PFX item.
*/
@@ -1214,6 +1209,7 @@ SEC_PKCS12DecoderStart(SECItem *pwitem, PK11SlotInfo *slot, void *wincx,
sec_PKCS12PFXItemTemplate);
if(!p12dcx->pfxDcx) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
+ PK11_FreeSlot(p12dcx->slot);
goto loser;
}
@@ -1279,14 +1275,15 @@ static SECStatus
sec_pkcs12_decoder_verify_mac(SEC_PKCS12DecoderContext *p12dcx)
{
SECStatus rv = SECFailure;
+ SECStatus lrv;
SECItem hmacRes;
unsigned char buf[IN_BUF_LEN];
unsigned int bufLen;
int iteration;
PK11Context *pk11cx = NULL;
+ PK11SymKey *symKey = NULL;
+ SECItem *params = NULL;
SECItem ignore = {0};
- PK11SymKey *symKey;
- SECItem *params;
SECOidTag algtag;
CK_MECHANISM_TYPE integrityMech;
@@ -1318,15 +1315,18 @@ sec_pkcs12_decoder_verify_mac(SEC_PKCS12DecoderContext *p12dcx)
symKey = PK11_KeyGen(NULL, integrityMech, params, 20, NULL);
PK11_DestroyPBEParams(params);
+ params = NULL;
if (!symKey) goto loser;
/* init hmac */
pk11cx = PK11_CreateContextBySymKey(sec_pkcs12_algtag_to_mech(algtag),
CKA_SIGN, symKey, &ignore);
if(!pk11cx) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
+ goto loser;
+ }
+ lrv = PK11_DigestBegin(pk11cx);
+ if (lrv == SECFailure ) {
+ goto loser;
}
- rv = PK11_DigestBegin(pk11cx);
/* try to open the data for readback */
if(p12dcx->dOpen && ((*p12dcx->dOpen)(p12dcx->dArg, PR_TRUE)
@@ -1346,14 +1346,20 @@ sec_pkcs12_decoder_verify_mac(SEC_PKCS12DecoderContext *p12dcx)
goto loser;
}
- rv = PK11_DigestOp(pk11cx, buf, bytesRead);
+ lrv = PK11_DigestOp(pk11cx, buf, bytesRead);
+ if (lrv == SECFailure) {
+ goto loser;
+ }
if(bytesRead < IN_BUF_LEN) {
break;
}
}
/* finish the hmac context */
- rv = PK11_DigestFinal(pk11cx, buf, &bufLen, IN_BUF_LEN);
+ lrv = PK11_DigestFinal(pk11cx, buf, &bufLen, IN_BUF_LEN);
+ if (lrv == SECFailure ) {
+ goto loser;
+ }
hmacRes.data = buf;
hmacRes.len = bufLen;
@@ -1375,6 +1381,12 @@ loser:
if(pk11cx) {
PK11_DestroyContext(pk11cx, PR_TRUE);
}
+ if (params) {
+ PK11_DestroyPBEParams(params);
+ }
+ if (symKey) {
+ PK11_FreeSymKey(symKey);
+ }
return rv;
}
@@ -1460,6 +1472,11 @@ SEC_PKCS12DecoderFinish(SEC_PKCS12DecoderContext *p12dcx)
p12dcx->hmacDcx = NULL;
}
+ if(p12dcx->slot) {
+ PK11_FreeSlot(p12dcx->slot);
+ p12dcx->slot = NULL;
+ }
+
if(p12dcx->arena) {
PORT_FreeArena(p12dcx->arena, PR_TRUE);
}
@@ -2223,7 +2240,7 @@ sec_pkcs12_validate_cert(sec_PKCS12SafeBag *cert,
}
cert->noInstall = PR_FALSE;
- cert->removeExisting = PR_FALSE;
+ cert->unused = PR_FALSE;
cert->problem = PR_FALSE;
cert->error = 0;
@@ -2236,26 +2253,7 @@ sec_pkcs12_validate_cert(sec_PKCS12SafeBag *cert,
return;
}
- testCert = PK11_FindCertFromDERCert(cert->slot, leafCert, wincx);
CERT_DestroyCertificate(leafCert);
- /* if we can't find the certificate through the PKCS11 interface,
- * we should check the cert database directly, if we are
- * importing to an internal slot.
- */
- if(!testCert && PK11_IsInternal(cert->slot)) {
- testCert = CERT_FindCertByDERCert(CERT_GetDefaultCertDB(),
- &cert->safeBagContent.certBag->value.x509Cert);
- }
-
- if(testCert) {
- if(!testCert->nickname) {
- cert->removeExisting = PR_TRUE;
- }
- CERT_DestroyCertificate(testCert);
- if(cert->noInstall && !cert->removeExisting) {
- return;
- }
- }
sec_pkcs12_validate_cert_nickname(cert, key, nicknameCb, wincx);
}
@@ -2303,59 +2301,6 @@ sec_pkcs12_validate_key_by_cert(sec_PKCS12SafeBag *cert, sec_PKCS12SafeBag *key,
}
static SECStatus
-sec_pkcs12_remove_existing_cert(sec_PKCS12SafeBag *cert,
- void *wincx)
-{
- SECItem *derCert = NULL;
- CERTCertificate *tempCert = NULL;
- CK_OBJECT_HANDLE certObj;
- PRBool removed = PR_FALSE;
-
- if(!cert) {
- return SECFailure;
- }
-
- PORT_Assert(cert->removeExisting);
-
- cert->removeExisting = PR_FALSE;
- derCert = &cert->safeBagContent.certBag->value.x509Cert;
- tempCert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
- if(!tempCert) {
- return SECFailure;
- }
-
- certObj = PK11_FindCertInSlot(cert->slot, tempCert, wincx);
- CERT_DestroyCertificate(tempCert);
- tempCert = NULL;
-
- if(certObj != CK_INVALID_HANDLE) {
- PK11_DestroyObject(cert->slot, certObj);
- removed = PR_TRUE;
- } else if(PK11_IsInternal(cert->slot)) {
- tempCert = CERT_FindCertByDERCert(CERT_GetDefaultCertDB(), derCert);
- if(tempCert) {
- if(SEC_DeletePermCertificate(tempCert) == SECSuccess) {
- removed = PR_TRUE;
- }
- CERT_DestroyCertificate(tempCert);
- tempCert = NULL;
- }
- }
-
- if(!removed) {
- cert->problem = PR_TRUE;
- cert->error = SEC_ERROR_NO_MEMORY;
- cert->noInstall = PR_TRUE;
- }
-
- if(tempCert) {
- CERT_DestroyCertificate(tempCert);
- }
-
- return ((removed) ? SECSuccess : SECFailure);
-}
-
-static SECStatus
sec_pkcs12_add_cert(sec_PKCS12SafeBag *cert, PRBool keyExists, void *wincx)
{
SECItem *derCert, *nickName;
@@ -2371,15 +2316,8 @@ sec_pkcs12_add_cert(sec_PKCS12SafeBag *cert, PRBool keyExists, void *wincx)
}
derCert = &cert->safeBagContent.certBag->value.x509Cert;
- if(cert->removeExisting) {
- if(sec_pkcs12_remove_existing_cert(cert, wincx)
- != SECSuccess) {
- return SECFailure;
- }
- cert->removeExisting = PR_FALSE;
- }
- PORT_Assert(!cert->problem && !cert->removeExisting && !cert->noInstall);
+ PORT_Assert(!cert->problem && !cert->noInstall);
nickName = sec_pkcs12_get_nickname(cert);
if(nickName) {
@@ -2389,7 +2327,8 @@ sec_pkcs12_add_cert(sec_PKCS12SafeBag *cert, PRBool keyExists, void *wincx)
if(keyExists) {
CERTCertificate *newCert;
- newCert = CERT_DecodeDERCertificate( derCert, PR_FALSE, NULL);
+ newCert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
+ derCert, NULL, PR_FALSE, PR_FALSE);
if(!newCert) {
if(nickName) SECITEM_ZfreeItem(nickName, PR_TRUE);
cert->error = SEC_ERROR_NO_MEMORY;
@@ -2424,12 +2363,6 @@ sec_pkcs12_add_key(sec_PKCS12SafeBag *key, SECItem *publicValue,
return SECFailure;
}
- if(key->removeExisting) {
- key->problem = PR_TRUE;
- key->error = SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY;
- return SECFailure;
- }
-
if(key->problem || key->noInstall) {
return SECSuccess;
}
@@ -2571,7 +2504,9 @@ SEC_PKCS12DecoderGetCerts(SEC_PKCS12DecoderContext *p12dcx)
CERTCertificate *tempCert = NULL;
if (derCert == NULL) continue;
- tempCert=CERT_DecodeDERCertificate(derCert, PR_TRUE, NULL);
+ tempCert=CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
+ derCert, NULL,
+ PR_FALSE, PR_TRUE);
if (tempCert) {
CERT_AddCertToListTail(certList,tempCert);
@@ -3312,7 +3247,7 @@ sec_PKCS12ConvertOldSafeToNew(PRArenaPool *arena, PK11SlotInfo *slot,
}
p12dcx->arena = arena;
- p12dcx->slot = slot;
+ p12dcx->slot = PK11_ReferenceSlot(slot);
p12dcx->wincx = wincx;
p12dcx->error = PR_FALSE;
p12dcx->swapUnicodeBytes = swapUnicode;
diff --git a/security/nss/lib/pkcs12/p12e.c b/security/nss/lib/pkcs12/p12e.c
index 9f9a92cea..1b86a49ac 100644
--- a/security/nss/lib/pkcs12/p12e.c
+++ b/security/nss/lib/pkcs12/p12e.c
@@ -194,7 +194,7 @@ SEC_PKCS12CreateExportContext(SECKEYGetPasswordKey pwfn, void *pwfnarg,
p12ctxt->integrityEnabled = PR_FALSE;
p12ctxt->arena = arena;
p12ctxt->wincx = wincx;
- p12ctxt->slot = (slot) ? slot : PK11_GetInternalSlot();
+ p12ctxt->slot = (slot) ? PK11_ReferenceSlot(slot) : PK11_GetInternalSlot();
return p12ctxt;
@@ -352,7 +352,7 @@ SEC_PKCS12CreatePasswordPrivSafe(SEC_PKCS12ExportContext *p12ctxt,
{
SEC_PKCS12SafeInfo *safeInfo = NULL;
void *mark = NULL;
- PK11SlotInfo *slot;
+ PK11SlotInfo *slot = NULL;
SECAlgorithmID *algId;
SECItem uniPwitem = {siBuffer, NULL, 0};
@@ -393,7 +393,7 @@ SEC_PKCS12CreatePasswordPrivSafe(SEC_PKCS12ExportContext *p12ctxt,
}
/* generate the encryption key */
- slot = p12ctxt->slot;
+ slot = PK11_ReferenceSlot(p12ctxt->slot);
if(!slot) {
slot = PK11_GetInternalKeySlot();
if(!slot) {
@@ -419,9 +419,16 @@ SEC_PKCS12CreatePasswordPrivSafe(SEC_PKCS12ExportContext *p12ctxt,
SECITEM_ZfreeItem(&uniPwitem, PR_FALSE);
}
PORT_ArenaUnmark(p12ctxt->arena, mark);
+
+ if (slot) {
+ PK11_FreeSlot(slot);
+ }
return safeInfo;
loser:
+ if (slot) {
+ PK11_FreeSlot(slot);
+ }
if(safeInfo->cinfo) {
SEC_PKCS7DestroyContentInfo(safeInfo->cinfo);
}
@@ -1285,7 +1292,7 @@ SEC_PKCS12AddKeyForCert(SEC_PKCS12ExportContext *p12ctxt, SEC_PKCS12SafeInfo *sa
/* extract the key encrypted */
SECKEYEncryptedPrivateKeyInfo *epki = NULL;
- PK11SlotInfo *slot = p12ctxt->slot;
+ PK11SlotInfo *slot = NULL;
if(!sec_pkcs12_convert_item_to_unicode(p12ctxt->arena, &uniPwitem,
pwitem, PR_TRUE, PR_TRUE, PR_TRUE)) {
@@ -1296,14 +1303,14 @@ SEC_PKCS12AddKeyForCert(SEC_PKCS12ExportContext *p12ctxt, SEC_PKCS12SafeInfo *sa
/* we want to make sure to take the key out of the key slot */
if(PK11_IsInternal(p12ctxt->slot)) {
slot = PK11_GetInternalKeySlot();
+ } else {
+ slot = PK11_ReferenceSlot(p12ctxt->slot);
}
epki = PK11_ExportEncryptedPrivateKeyInfo(slot, algorithm,
&uniPwitem, cert, 1,
p12ctxt->wincx);
- if(PK11_IsInternal(p12ctxt->slot)) {
- PK11_FreeSlot(slot);
- }
+ PK11_FreeSlot(slot);
keyItem = PORT_ArenaZAlloc(p12ctxt->arena,
sizeof(SECKEYEncryptedPrivateKeyInfo));
@@ -1409,7 +1416,8 @@ SEC_PKCS12AddDERCertAndEncryptedKey(SEC_PKCS12ExportContext *p12ctxt,
mark = PORT_ArenaMark(p12ctxt->arena);
- cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
+ cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
+ derCert, NULL, PR_FALSE, PR_FALSE);
if(!cert) {
PORT_ArenaRelease(p12ctxt->arena, mark);
PORT_SetError(SEC_ERROR_NO_MEMORY);
@@ -1719,6 +1727,8 @@ sec_pkcs12_encoder_start_context(SEC_PKCS12ExportContext *p12exp)
p12enc->hmacCx = PK11_CreateContextBySymKey(
sec_pkcs12_algtag_to_mech(p12exp->integrityInfo.pwdInfo.algorithm),
CKA_SIGN, symKey, &ignore);
+
+ PK11_FreeSymKey(symKey);
if(!p12enc->hmacCx) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
goto loser;
@@ -2137,6 +2147,8 @@ SEC_PKCS12DestroyExportContext(SEC_PKCS12ExportContext *p12ecx)
}
}
+ PK11_FreeSlot(p12ecx->slot);
+
PORT_FreeArena(p12ecx->arena, PR_TRUE);
}
diff --git a/security/nss/lib/pkcs12/p12t.h b/security/nss/lib/pkcs12/p12t.h
index 6b9d3da1b..74e803c60 100644
--- a/security/nss/lib/pkcs12/p12t.h
+++ b/security/nss/lib/pkcs12/p12t.h
@@ -111,7 +111,7 @@ struct sec_PKCS12SafeBagStr {
unsigned int nAttribs;
/* used for validation/importing */
- PRBool problem, noInstall, validated, hasKey, removeExisting, installed;
+ PRBool problem, noInstall, validated, hasKey, unused, installed;
int error;
PRBool swapUnicodeBytes;
diff --git a/security/nss/lib/pkcs7/certread.c b/security/nss/lib/pkcs7/certread.c
index 073a9e545..672e3b132 100644
--- a/security/nss/lib/pkcs7/certread.c
+++ b/security/nss/lib/pkcs7/certread.c
@@ -162,7 +162,8 @@ CERT_ConvertAndDecodeCertificate(char *certstr)
if (rv != SECSuccess)
return NULL;
- cert = CERT_DecodeDERCertificate(&der, PR_TRUE, NULL);
+ cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
+ &der, NULL, PR_FALSE, PR_TRUE);
PORT_Free(der.data);
return cert;
@@ -528,7 +529,9 @@ CERT_DecodeCertFromPackage(char *certbuf, int certlen)
rv = CERT_DecodeCertPackage(certbuf, certlen, collect_certs,
(void *)&collectArgs);
if ( rv == SECSuccess ) {
- cert = CERT_DecodeDERCertificate(&collectArgs.cert, PR_TRUE, NULL);
+ cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
+ &collectArgs.cert, NULL,
+ PR_FALSE, PR_TRUE);
}
PORT_FreeArena(collectArgs.arena, PR_FALSE);
diff --git a/security/nss/lib/pki/Makefile b/security/nss/lib/pki/Makefile
index bfe27629c..4cbbfed70 100644
--- a/security/nss/lib/pki/Makefile
+++ b/security/nss/lib/pki/Makefile
@@ -34,11 +34,7 @@ MAKEFILE_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$ $Name$"
include manifest.mn
include $(CORE_DEPTH)/coreconf/config.mk
-ifdef PURE_STAN_BUILD
include config.mk
-else
-include config34.mk
-endif
include $(CORE_DEPTH)/coreconf/rules.mk
export:: private_export
diff --git a/security/nss/lib/pki/certdecode.c b/security/nss/lib/pki/certdecode.c
index fbf0c1d67..cac766496 100644
--- a/security/nss/lib/pki/certdecode.c
+++ b/security/nss/lib/pki/certdecode.c
@@ -43,78 +43,6 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#include "pkim.h"
#endif /* PKIM_H */
-/* XXX
- * move this to a more appropriate location
- */
-NSS_IMPLEMENT PRStatus
-nssPKIObject_Initialize
-(
- struct nssPKIObjectBaseStr *object,
- NSSArena *arena,
- NSSTrustDomain *td,
- NSSCryptoContext *cc
-)
-{
- object->arena = arena;
- object->trustDomain = td;
- object->cryptoContext = cc;
- object->lock = PZ_NewLock(nssILockOther);
- if (!object->lock) {
- return PR_FAILURE;
- }
- object->instanceList = nssList_Create(arena, PR_TRUE);
- if (!object->instanceList) {
- PZ_DestroyLock(object->lock);
- return PR_FAILURE;
- }
- object->instances = nssList_CreateIterator(object->instanceList);
- if (!object->instances) {
- nssList_Destroy(object->instanceList);
- PZ_DestroyLock(object->lock);
- return PR_FAILURE;
- }
- object->refCount = 1;
- return PR_SUCCESS;
-}
-
-/* XXX
- * move this to a more appropriate location
- */
-NSS_IMPLEMENT void
-nssPKIObject_AddRef
-(
- struct nssPKIObjectBaseStr *object
-)
-{
- PZ_Lock(object->lock);
- object->refCount++;
- PZ_Unlock(object->lock);
-}
-
-/* XXX
- * move this to a more appropriate location
- */
-NSS_IMPLEMENT PRBool
-nssPKIObject_Destroy
-(
- struct nssPKIObjectBaseStr *object
-)
-{
- PRUint32 refCount;
- PZ_Lock(object->lock);
- PORT_Assert(object->refCount > 0);
- refCount = --object->refCount;
- PZ_Unlock(object->lock);
- if (refCount == 0) {
- PZ_DestroyLock(object->lock);
- nssListIterator_Destroy(object->instances);
- nssList_Destroy(object->instanceList);
- nssArena_Destroy(object->arena);
- return PR_TRUE;
- }
- return PR_FALSE;
-}
-
#ifdef NSS_3_4_CODE
/* This is defined in nss3hack.c */
NSS_EXTERN nssDecodedCert *
@@ -194,39 +122,3 @@ nssDecodedCert_Destroy
return PR_FAILURE;
}
-/* Of course none of this belongs here */
-
-/* how bad would it be to have a static now sitting around, updated whenever
- * this was called? would avoid repeated allocs...
- */
-NSS_IMPLEMENT NSSTime *
-NSSTime_Now
-(
- NSSTime *timeOpt
-)
-{
- return NSSTime_SetPRTime(timeOpt, PR_Now());
-}
-
-NSS_IMPLEMENT NSSTime *
-NSSTime_SetPRTime
-(
- NSSTime *timeOpt,
- PRTime prTime
-)
-{
- NSSTime *rvTime;
- rvTime = (timeOpt) ? timeOpt : nss_ZNEW(NULL, NSSTime);
- rvTime->prTime = prTime;
- return rvTime;
-}
-
-NSS_IMPLEMENT PRTime
-NSSTime_GetPRTime
-(
- NSSTime *time
-)
-{
- return time->prTime;
-}
-
diff --git a/security/nss/lib/pki/certificate.c b/security/nss/lib/pki/certificate.c
index f9dc9a7e3..913fe559d 100644
--- a/security/nss/lib/pki/certificate.c
+++ b/security/nss/lib/pki/certificate.c
@@ -61,6 +61,40 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
extern const NSSError NSS_ERROR_NOT_FOUND;
+/* Creates a certificate from a base object */
+NSS_IMPLEMENT NSSCertificate *
+nssCertificate_Create
+(
+ nssPKIObject *object
+)
+{
+ PRStatus status;
+ NSSCertificate *rvCert;
+ /* mark? */
+ NSSArena *arena = object->arena;
+ PR_ASSERT(object->instances != NULL && object->numInstances > 0);
+ rvCert = nss_ZNEW(arena, NSSCertificate);
+ if (!rvCert) {
+ return (NSSCertificate *)NULL;
+ }
+ rvCert->object = *object;
+ /* XXX should choose instance based on some criteria */
+ status = nssCryptokiCertificate_GetAttributes(object->instances[0],
+ NULL, /* XXX sessionOpt */
+ arena,
+ &rvCert->type,
+ &rvCert->id,
+ &rvCert->encoding,
+ &rvCert->issuer,
+ &rvCert->serial,
+ &rvCert->subject,
+ &rvCert->email);
+ if (status != PR_SUCCESS) {
+ return (NSSCertificate *)NULL;
+ }
+ return rvCert;
+}
+
NSS_IMPLEMENT NSSCertificate *
nssCertificate_AddRef
(
@@ -74,7 +108,7 @@ nssCertificate_AddRef
}
NSS_IMPLEMENT PRStatus
-NSSCertificate_Destroy
+nssCertificate_Destroy
(
NSSCertificate *c
)
@@ -92,37 +126,84 @@ NSSCertificate_Destroy
return PR_SUCCESS;
}
+NSS_IMPLEMENT PRStatus
+NSSCertificate_Destroy
+(
+ NSSCertificate *c
+)
+{
+ return nssCertificate_Destroy(c);
+}
+
+NSS_IMPLEMENT NSSDER *
+nssCertificate_GetEncoding
+(
+ NSSCertificate *c
+)
+{
+ if (c->encoding.size > 0 && c->encoding.data) {
+ return &c->encoding;
+ } else {
+ return (NSSDER *)NULL;
+ }
+}
+
+NSS_IMPLEMENT NSSDER *
+nssCertificate_GetIssuer
+(
+ NSSCertificate *c
+)
+{
+ if (c->issuer.size > 0 && c->issuer.data) {
+ return &c->issuer;
+ } else {
+ return (NSSDER *)NULL;
+ }
+}
+
+NSS_IMPLEMENT NSSDER *
+nssCertificate_GetSerialNumber
+(
+ NSSCertificate *c
+)
+{
+ if (c->serial.size > 0 && c->serial.data) {
+ return &c->serial;
+ } else {
+ return (NSSDER *)NULL;
+ }
+}
+
+NSS_IMPLEMENT NSSDER *
+nssCertificate_GetSubject
+(
+ NSSCertificate *c
+)
+{
+ if (c->subject.size > 0 && c->subject.data) {
+ return &c->subject;
+ } else {
+ return (NSSDER *)NULL;
+ }
+}
+
NSS_IMPLEMENT NSSUTF8 *
-NSSCertificate_GetNickname
+nssCertificate_GetNickname
(
NSSCertificate *c,
NSSToken *tokenOpt
)
{
- NSSUTF8 *rvNick = NULL;
- nssCryptokiInstance *instance;
- nssListIterator *instances = c->object.instances;
- if (c->object.cryptoContext) {
- return c->object.tempName;
- }
- for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances);
- instance != (nssCryptokiInstance *)NULL;
- instance = (nssCryptokiInstance *)nssListIterator_Next(instances))
- {
- if (tokenOpt) {
- if (instance->token == tokenOpt) {
- /* take the nickname on the given token */
- rvNick = instance->label;
- break;
- }
- } else {
- /* take the first one */
- rvNick = instance->label;
- break;
- }
- }
- nssListIterator_Finish(instances);
- return rvNick;
+ return nssPKIObject_GetNicknameForToken(&c->object, tokenOpt);
+}
+
+NSS_IMPLEMENT NSSASCII7 *
+nssCertificate_GetEmailAddress
+(
+ NSSCertificate *c
+)
+{
+ return c->email;
}
NSS_IMPLEMENT PRStatus
@@ -132,39 +213,7 @@ NSSCertificate_DeleteStoredObject
NSSCallback *uhh
)
{
- /* this needs more thought on what will happen when there are multiple
- * instances
- */
- /* XXX use callback to log in if neccessary */
- PRStatus nssrv = PR_SUCCESS;
- nssCryptokiInstance *instance;
- nssListIterator *instances = c->object.instances;
- for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances);
- instance != (nssCryptokiInstance *)NULL;
- instance = (nssCryptokiInstance *)nssListIterator_Next(instances))
- {
- /* XXX this should be fixed to understand read-only tokens, for
- * now, to handle the builtins, just make the attempt.
- */
- nssrv = nssToken_DeleteStoredObject(instance);
- if (nssrv == PR_SUCCESS) {
- nssList_Remove(c->object.instanceList, instance);
-#ifdef NSS_3_4_CODE
- if (instance->token->certList) {
- /* If the cert has been cached locally on the token, remove
- * that reference
- */
- nssList_Remove(instance->token->certList, c);
- NSSCertificate_Destroy(c);
- }
-#endif
- }
- }
- nssListIterator_Finish(instances);
- c->object.instances = nssList_CreateIterator(c->object.instanceList);
- nssListIterator_Destroy(instances);
- /* XXX for now, always success */
- return PR_SUCCESS;
+ return nssPKIObject_DeleteStoredObject(&c->object, uhh, PR_TRUE);
}
NSS_IMPLEMENT PRStatus
@@ -238,79 +287,88 @@ nssCertificate_GetDecoding
return c->decoding;
}
-static void
-nssCertificateArray_Destroy
+static NSSCertificate *
+filter_subject_certs_for_id
(
- NSSCertificate **certArray
+ NSSCertificate **subjectCerts,
+ NSSItem *id
)
{
- NSSCertificate **ci;
- ci = certArray;
- while (ci && *ci) {
- NSSCertificate_Destroy(*ci);
- ci++;
- }
- nss_ZFreeIf(certArray);
-}
-
-static NSSCertificate *
-filter_subject_certs_for_id(NSSCertificate **subjectCerts, NSSItem *id)
-{
NSSCertificate **si;
NSSCertificate *rvCert = NULL;
nssDecodedCert *dcp;
/* walk the subject certs */
- si = subjectCerts;
- while (*si) {
+ for (si = subjectCerts; *si; si++) {
dcp = nssCertificate_GetDecoding(*si);
if (dcp->matchIdentifier(dcp, id)) {
/* this cert has the correct identifier */
rvCert = nssCertificate_AddRef(*si);
break;
}
- si++;
}
return rvCert;
}
static NSSCertificate *
-find_issuer_cert_for_identifier(NSSCertificate *c, NSSItem *id)
+find_cert_issuer
+(
+ NSSCertificate *c,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt
+)
{
- NSSCertificate *rvCert = NULL;
- NSSCertificate **subjectCerts = NULL;
+ NSSArena *arena;
+ NSSCertificate **certs = NULL;
+ NSSCertificate **ccIssuers = NULL;
+ NSSCertificate **tdIssuers = NULL;
+ NSSCertificate *issuer = NULL;
NSSTrustDomain *td;
NSSCryptoContext *cc;
- /* Find all certs with this cert's issuer as the subject */
cc = c->object.cryptoContext; /* NSSCertificate_GetCryptoContext(c); */
+ td = NSSCertificate_GetTrustDomain(c);
+#ifdef NSS_3_4_CODE
+ if (!td) {
+ td = STAN_GetDefaultTrustDomain();
+ }
+#endif
+ arena = nssArena_Create();
+ if (!arena) {
+ return (NSSCertificate *)NULL;
+ }
if (cc) {
- subjectCerts = NSSCryptoContext_FindCertificatesBySubject(cc,
- &c->issuer,
- NULL,
- 0,
- NULL);
- if (subjectCerts) {
- rvCert = filter_subject_certs_for_id(subjectCerts, id);
- nssCertificateArray_Destroy(subjectCerts);
- }
+ ccIssuers = nssCryptoContext_FindCertificatesBySubject(cc,
+ &c->issuer,
+ NULL,
+ 0,
+ arena);
}
- if (!rvCert) {
- /* The general behavior of NSS <3.4 seems to be that if the search
- * turns up empty in the temp db, fall back to the perm db,
- * irregardless of whether or not the cert itself is perm or temp.
- * This is replicated here.
- */
- td = NSSCertificate_GetTrustDomain(c);
- subjectCerts = NSSTrustDomain_FindCertificatesBySubject(td,
- &c->issuer,
- NULL,
- 0,
- NULL);
- if (subjectCerts) {
- rvCert = filter_subject_certs_for_id(subjectCerts, id);
- nssCertificateArray_Destroy(subjectCerts);
+ tdIssuers = nssTrustDomain_FindCertificatesBySubject(td,
+ &c->issuer,
+ NULL,
+ 0,
+ arena);
+ certs = nssCertificateArray_Join(ccIssuers, tdIssuers);
+ if (certs) {
+ nssDecodedCert *dc = NULL;
+ NSSItem *issuerID = NULL;
+ dc = nssCertificate_GetDecoding(c);
+ if (dc) {
+ issuerID = dc->getIssuerIdentifier(dc);
}
+ if (issuerID) {
+ issuer = filter_subject_certs_for_id(certs, issuerID);
+ nssItem_Destroy(issuerID);
+ } else {
+ issuer = nssCertificateArray_FindBestCertificate(certs,
+ timeOpt,
+ usage,
+ policiesOpt);
+ }
+ nssCertificateArray_Destroy(certs);
}
- return rvCert;
+ nssArena_Destroy(arena);
+ return issuer;
}
/* XXX review based on CERT_FindCertIssuer
@@ -318,145 +376,110 @@ find_issuer_cert_for_identifier(NSSCertificate *c, NSSItem *id)
* if authority key id does not exist
*/
NSS_IMPLEMENT NSSCertificate **
-NSSCertificate_BuildChain
+nssCertificate_BuildChain
(
NSSCertificate *c,
NSSTime *timeOpt,
NSSUsage *usage,
NSSPolicies *policiesOpt,
NSSCertificate **rvOpt,
- PRUint32 rvLimit, /* zero for no limit */
+ PRUint32 rvLimit,
NSSArena *arenaOpt,
PRStatus *statusOpt
)
{
- PRStatus nssrv;
- nssList *chain;
- NSSItem *issuerID;
+ PRStatus status;
NSSCertificate **rvChain;
+#ifdef NSS_3_4_CODE
+ NSSCertificate *cp;
+#endif
NSSTrustDomain *td;
- NSSCryptoContext *cc;
- nssDecodedCert *dc;
- NSSCertificate *ct, *cp;
- cc = c->object.cryptoContext; /* NSSCertificate_GetCryptoContext(c); */
+ nssPKIObjectCollection *collection;
td = NSSCertificate_GetTrustDomain(c);
#ifdef NSS_3_4_CODE
if (!td) {
td = STAN_GetDefaultTrustDomain();
}
#endif
- chain = nssList_Create(NULL, PR_FALSE);
- nssList_Add(chain, nssCertificate_AddRef(c));
if (statusOpt) *statusOpt = PR_SUCCESS;
- if (rvLimit == 1) goto finish;
- while (!nssItem_Equal(&c->subject, &c->issuer, &nssrv)) {
- dc = nssCertificate_GetDecoding(c);
- issuerID = dc->getIssuerIdentifier(dc);
- if (issuerID) {
- c = find_issuer_cert_for_identifier(c, issuerID);
- nssItem_Destroy(issuerID);
- issuerID = NULL;
- if (!c) {
- nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);
- if (statusOpt) *statusOpt = PR_FAILURE;
- goto finish;
- }
- } else {
- nssBestCertificateCB best;
- NSSDER *issuer = &c->issuer;
+ collection = nssCertificateCollection_Create(td, NULL);
+ if (!collection) {
+ if (statusOpt) *statusOpt = PR_FAILURE;
+ return (NSSCertificate **)NULL;
+ }
+ nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c);
+ if (rvLimit == 1) {
+ goto finish;
+ }
+ while (!nssItem_Equal(&c->subject, &c->issuer, &status)) {
#ifdef NSS_3_4_CODE
+ cp = c;
+#endif
+ c = find_cert_issuer(c, timeOpt, usage, policiesOpt);
+#ifdef NSS_3_4_CODE
+ if (!c) {
PRBool tmpca = usage->nss3lookingForCA;
usage->nss3lookingForCA = PR_TRUE;
-#endif
- c = ct = cp = NULL;
- if (cc) {
- ct = NSSCryptoContext_FindBestCertificateBySubject(cc,
- issuer,
- timeOpt,
- usage,
- policiesOpt);
- /* Mimic functionality from CERT_FindCertIssuer. If a matching
- * cert (based on trust & usage) cannot be found, just take the
- * newest cert with the correct subject.
- */
- if (!ct && !usage->anyUsage) {
- usage->anyUsage = PR_TRUE;
- ct = NSSCryptoContext_FindBestCertificateBySubject(cc,
- issuer,
- timeOpt,
- usage,
- policiesOpt);
- usage->anyUsage = PR_FALSE;
- }
- }
- cp = NSSTrustDomain_FindBestCertificateBySubject(td,
- issuer,
- timeOpt,
- usage,
- policiesOpt);
- /* Mimic functionality from CERT_FindCertIssuer. If a matching
- * cert (based on trust & usage) cannot be found, just take the
- * newest cert with the correct subject.
- */
- if (!cp && !usage->anyUsage) {
+ c = find_cert_issuer(cp, timeOpt, usage, policiesOpt);
+ if (!c && !usage->anyUsage) {
usage->anyUsage = PR_TRUE;
- cp = NSSTrustDomain_FindBestCertificateBySubject(td,
- issuer,
- timeOpt,
- usage,
- policiesOpt);
+ c = find_cert_issuer(cp, timeOpt, usage, policiesOpt);
usage->anyUsage = PR_FALSE;
}
- nssBestCertificate_SetArgs(&best, timeOpt, usage, policiesOpt);
- /* Take the better of the best temp and best perm cert, according
- * to the given usage
- */
- if (ct) {
- nssBestCertificate_Callback(ct, (void *)&best);
- }
- if (cp) {
- nssBestCertificate_Callback(cp, (void *)&best);
- }
- if (!best.cert) {
- best.usage->anyUsage = PR_TRUE;
- /* Take the newest of the best temp and best perm cert */
- if (ct) {
- nssBestCertificate_Callback(ct, (void *)&best);
- }
- if (cp) {
- nssBestCertificate_Callback(cp, (void *)&best);
- }
- }
- if (ct) NSSCertificate_Destroy(ct);
- if (cp) NSSCertificate_Destroy(cp);
- c = best.cert;
-#ifdef NSS_3_4_CODE
usage->nss3lookingForCA = tmpca;
-#endif
- if (!c) {
- nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);
- if (statusOpt) *statusOpt = PR_FAILURE;
- goto finish;
+ }
+#endif /* NSS_3_4_CODE */
+ if (c) {
+ nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c);
+ nssCertificate_Destroy(c); /* collection has it */
+ if (rvLimit > 0 &&
+ nssPKIObjectCollection_Count(collection) == rvLimit)
+ {
+ break;
}
+ } else {
+ nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);
+ if (statusOpt) *statusOpt = PR_FAILURE;
+ break;
}
- nssList_Add(chain, c);
- if (nssList_Count(chain) == rvLimit) goto finish;
}
finish:
- if (rvOpt) {
- rvChain = rvOpt;
- } else {
- rvLimit = nssList_Count(chain);
- rvChain = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, rvLimit + 1);
- }
- nssList_GetArray(chain, (void **)rvChain, rvLimit);
- nssList_Destroy(chain);
- /* XXX now, the question is, cache all certs in the chain? */
+ rvChain = nssPKIObjectCollection_GetCertificates(collection,
+ rvOpt,
+ rvLimit,
+ arenaOpt);
+ nssPKIObjectCollection_Destroy(collection);
return rvChain;
}
+NSS_IMPLEMENT NSSCertificate **
+NSSCertificate_BuildChain
+(
+ NSSCertificate *c,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt,
+ NSSCertificate **rvOpt,
+ PRUint32 rvLimit, /* zero for no limit */
+ NSSArena *arenaOpt,
+ PRStatus *statusOpt
+)
+{
+ return nssCertificate_BuildChain(c, timeOpt, usage, policiesOpt,
+ rvOpt, rvLimit, arenaOpt, statusOpt);
+}
+
+NSS_IMPLEMENT NSSCryptoContext *
+nssCertificate_GetCryptoContext
+(
+ NSSCertificate *c
+)
+{
+ return c->object.cryptoContext;
+}
+
NSS_IMPLEMENT NSSTrustDomain *
-NSSCertificate_GetTrustDomain
+nssCertificate_GetTrustDomain
(
NSSCertificate *c
)
@@ -464,6 +487,15 @@ NSSCertificate_GetTrustDomain
return c->object.trustDomain;
}
+NSS_IMPLEMENT NSSTrustDomain *
+NSSCertificate_GetTrustDomain
+(
+ NSSCertificate *c
+)
+{
+ return nssCertificate_GetTrustDomain(c);
+}
+
NSS_IMPLEMENT NSSToken *
NSSCertificate_GetToken
(
@@ -782,7 +814,9 @@ nssBestCertificate_Callback
* what the trust values are for the cert.
* Ignore the returned pointer, the refcount is in c anyway.
*/
- (void)STAN_GetCERTCertificate(c);
+ if (STAN_GetCERTCertificate(c) == NULL) {
+ return PR_FAILURE;
+ }
#endif
if (dc->matchUsage(dc, best->usage)) {
best->cert = nssCertificate_AddRef(c);
@@ -825,22 +859,24 @@ nssSMIMEProfile_Create
NSSItem *profileData
)
{
- PRStatus nssrv;
NSSArena *arena;
nssSMIMEProfile *rvProfile;
+ nssPKIObject *object;
+ NSSTrustDomain *td = nssCertificate_GetTrustDomain(cert);
+ NSSCryptoContext *cc = nssCertificate_GetCryptoContext(cert);
arena = nssArena_Create();
if (!arena) {
return NULL;
}
+ object = nssPKIObject_Create(arena, NULL, td, cc);
+ if (!object) {
+ goto loser;
+ }
rvProfile = nss_ZNEW(arena, nssSMIMEProfile);
if (!rvProfile) {
- nssArena_Destroy(arena);
- return NULL;
- }
- nssrv = nssPKIObject_Initialize(&rvProfile->object, arena, NULL, NULL);
- if (nssrv != PR_SUCCESS) {
goto loser;
}
+ rvProfile->object = *object;
rvProfile->certificate = cert;
rvProfile->email = nssUTF8_Duplicate(cert->email, arena);
rvProfile->subject = nssItem_Duplicate(&cert->subject, arena, NULL);
@@ -852,8 +888,8 @@ nssSMIMEProfile_Create
}
return rvProfile;
loser:
- nssPKIObject_Destroy(&rvProfile->object);
- return NULL;
+ nssPKIObject_Destroy(object);
+ return (nssSMIMEProfile *)NULL;
}
/* execute a callback function on all members of a cert list */
@@ -896,6 +932,65 @@ nssCertificateList_AddReferences
}
NSS_IMPLEMENT NSSTrust *
+nssTrust_Create
+(
+ nssPKIObject *object
+)
+{
+ PRStatus status;
+ PRUint32 i;
+ PRUint32 lastTrustOrder, myTrustOrder;
+ 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++) {
+ instance = object->instances[i];
+ myTrustOrder = nssToken_GetTrustOrder(instance->token);
+ status = nssCryptokiTrust_GetAttributes(instance, NULL,
+ &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
@@ -943,3 +1038,78 @@ nssSMIMEProfile_Destroy
return PR_SUCCESS;
}
+NSS_IMPLEMENT NSSCRL *
+nssCRL_Create
+(
+ nssPKIObject *object
+)
+{
+ PRStatus status;
+ NSSCRL *rvCRL;
+ NSSArena *arena = object->arena;
+ PR_ASSERT(object->instances != NULL && object->numInstances > 0);
+ rvCRL = nss_ZNEW(arena, NSSCRL);
+ if (!rvCRL) {
+ return (NSSCRL *)NULL;
+ }
+ rvCRL->object = *object;
+ /* XXX should choose instance based on some criteria */
+ status = nssCryptokiCRL_GetAttributes(object->instances[0],
+ NULL, /* XXX sessionOpt */
+ arena,
+ &rvCRL->encoding,
+ &rvCRL->url,
+ &rvCRL->isKRL);
+ if (status != PR_SUCCESS) {
+ return (NSSCRL *)NULL;
+ }
+ return rvCRL;
+}
+
+NSS_IMPLEMENT NSSCRL *
+nssCRL_AddRef
+(
+ NSSCRL *crl
+)
+{
+ if (crl) {
+ nssPKIObject_AddRef(&crl->object);
+ }
+ return crl;
+}
+
+NSS_IMPLEMENT PRStatus
+nssCRL_Destroy
+(
+ NSSCRL *crl
+)
+{
+ if (crl) {
+ (void)nssPKIObject_Destroy(&crl->object);
+ }
+ return PR_SUCCESS;
+}
+
+NSS_IMPLEMENT PRStatus
+nssCRL_DeleteStoredObject
+(
+ NSSCRL *crl,
+ NSSCallback *uhh
+)
+{
+ return nssPKIObject_DeleteStoredObject(&crl->object, uhh, PR_TRUE);
+}
+
+NSS_IMPLEMENT NSSDER *
+nssCRL_GetEncoding
+(
+ NSSCRL *crl
+)
+{
+ if (crl->encoding.data != NULL && crl->encoding.size > 0) {
+ return &crl->encoding;
+ } else {
+ return (NSSDER *)NULL;
+ }
+}
+
diff --git a/security/nss/lib/pki/config.mk b/security/nss/lib/pki/config.mk
index 9614977ee..4a9ed7dda 100644
--- a/security/nss/lib/pki/config.mk
+++ b/security/nss/lib/pki/config.mk
@@ -1,4 +1,4 @@
-#
+#
# 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
@@ -30,115 +30,19 @@
# may use your version of this file under either the MPL or the
# GPL.
#
-
-#CONFIG_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$ $Name$"
+CONFIG_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$ $Name$"
ifdef BUILD_IDG
DEFINES += -DNSSDEBUG
endif
-# can't do this in manifest.mn because OS_TARGET isn't defined there.
-ifeq (,$(filter-out WIN%,$(OS_TARGET)))
-
-# don't want the 32 in the shared library name
-SHARED_LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).dll
-IMPORT_LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).lib
-
-DLLFLAGS += -DEF:nsspki.def
-RES = $(OBJDIR)/nsspki.res
-RESNAME = nsspki.rc
-
-# $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
-
-SHARED_LIBRARY_LIBS = \
- $(DIST)/lib/nssb.lib \
- $(DIST)/lib/nssdev.lib \
- $(DIST)/lib/nsspki.lib \
- $(NULL)
-
-SHARED_LIBRARY_DIRS = \
- ../base \
- ../dev \
- $(NULL)
-
-EXTRA_LIBS += \
- $(NULL)
-
-EXTRA_SHARED_LIBS += \
- $(DIST)/lib/$(NSPR31_LIB_PREFIX)plc4.lib \
- $(DIST)/lib/$(NSPR31_LIB_PREFIX)plds4.lib \
- $(DIST)/lib/$(NSPR31_LIB_PREFIX)nspr4.lib \
- $(NULL)
-
-# $(PROGRAM) has NO explicit dependencies on $(OS_LIBS)
-#OS_LIBS += \
-# wsock32.lib \
-# winmm.lib \
-# $(NULL)
-else
-
-# $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
-SHARED_LIBRARY_LIBS = \
- $(DIST)/lib/libnssb.$(LIB_SUFFIX) \
- $(DIST)/lib/libnssdev.$(LIB_SUFFIX) \
- $(DIST)/lib/libnsspki.$(LIB_SUFFIX) \
- $(NULL)
-
-EXTRA_LIBS += \
- $(NULL)
-
-SHARED_LIBRARY_DIRS = \
- ../base \
- ../dev \
- $(NULL)
-
-# $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS)
-# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
-EXTRA_SHARED_LIBS += \
- -L$(DIST)/lib/ \
- -lplc4 \
- -lplds4 \
- -lnspr4 \
- $(NULL)
-endif
-
-ifeq ($(OS_TARGET),SunOS)
-MAPFILE = $(OBJDIR)/nsspkimap.sun
-ALL_TRASH += $(MAPFILE)
-MKSHLIB += -M $(MAPFILE)
-ifndef USE_64
-ifeq ($(CPU_ARCH),sparc)
-# The -R '$ORIGIN' linker option instructs libnss3.so to search for its
-# dependencies (libfreebl_*.so) in the same directory where it resides.
-MKSHLIB += -R '$$ORIGIN'
-endif
-endif
-endif
-
-ifeq ($(OS_TARGET),AIX)
-MAPFILE = $(OBJDIR)/nsspkimap.aix
-ALL_TRASH += $(MAPFILE)
-EXPORT_RULES = -bexport:$(MAPFILE)
-endif
-
-ifeq ($(OS_TARGET),HP-UX)
-MAPFILE = $(OBJDIR)/nsspkimap.hp
-ALL_TRASH += $(MAPFILE)
-MKSHLIB += -c $(MAPFILE)
-endif
-
-ifeq ($(OS_TARGET), OSF1)
-MAPFILE = $(OBJDIR)/nsspkimap.osf
-ALL_TRASH += $(MAPFILE)
-MKSHLIB += -hidden -input $(MAPFILE)
-endif
-
-ifeq ($(OS_TARGET),Linux)
-MAPFILE = $(OBJDIR)/nsspkimap.linux
-ALL_TRASH += $(MAPFILE)
-MKSHLIB += -Wl,--version-script,$(MAPFILE)
-endif
-
+#
+# Override TARGETS variable so that only static libraries
+# are specifed as dependencies within rules.mk.
+#
-
+TARGETS = $(LIBRARY)
+SHARED_LIBRARY =
+IMPORT_LIBRARY =
+PROGRAM =
diff --git a/security/nss/lib/pki/config34.mk b/security/nss/lib/pki/config34.mk
deleted file mode 100644
index 4a9ed7dda..000000000
--- a/security/nss/lib/pki/config34.mk
+++ /dev/null
@@ -1,48 +0,0 @@
-#
-# 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.
-#
-CONFIG_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$ $Name$"
-
-ifdef BUILD_IDG
-DEFINES += -DNSSDEBUG
-endif
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/pki/cryptocontext.c b/security/nss/lib/pki/cryptocontext.c
index f713bcb10..21d524072 100644
--- a/security/nss/lib/pki/cryptocontext.c
+++ b/security/nss/lib/pki/cryptocontext.c
@@ -35,33 +35,56 @@
static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#endif /* DEBUG */
-#ifndef NSSPKI_H
-#include "nsspki.h"
-#endif /* NSSPKI_H */
+#ifndef DEV_H
+#include "dev.h"
+#endif /* DEV_H */
#ifndef PKIM_H
#include "pkim.h"
#endif /* PKIM_H */
-#ifndef PKIT_H
-#include "pkit.h"
-#endif /* PKIT_H */
-
-#ifndef DEV_H
-#include "dev.h"
-#endif /* DEV_H */
-
#ifndef PKISTORE_H
#include "pkistore.h"
#endif /* PKISTORE_H */
-#ifdef NSS_3_4_CODE
-#include "pk11func.h"
-#include "dev3hack.h"
+#include "pki1t.h"
+
+#ifdef PURE_STAN_BUILD
+struct NSSCryptoContextStr
+{
+ PRInt32 refCount;
+ NSSArena *arena;
+ NSSTrustDomain *td;
+ NSSToken *token;
+ nssSession *session;
+ nssCertificateStore *certStore;
+};
#endif
extern const NSSError NSS_ERROR_NOT_FOUND;
+NSS_IMPLEMENT NSSCryptoContext *
+nssCryptoContext_Create
+(
+ NSSTrustDomain *td,
+ NSSCallback *uhhOpt
+)
+{
+ NSSArena *arena;
+ NSSCryptoContext *rvCC;
+ arena = NSSArena_Create();
+ if (!arena) {
+ return NULL;
+ }
+ rvCC = nss_ZNEW(arena, NSSCryptoContext);
+ if (!rvCC) {
+ return NULL;
+ }
+ rvCC->td = td;
+ rvCC->arena = arena;
+ return rvCC;
+}
+
NSS_IMPLEMENT PRStatus
NSSCryptoContext_Destroy
(
@@ -177,9 +200,11 @@ nssCryptoContext_ImportTrust
}
}
nssrv = nssCertificateStore_AddTrust(cc->certStore, trust);
+#if 0
if (nssrv == PR_SUCCESS) {
trust->object.cryptoContext = cc;
}
+#endif
return nssrv;
}
@@ -198,9 +223,11 @@ nssCryptoContext_ImportSMIMEProfile
}
}
nssrv = nssCertificateStore_AddSMIMEProfile(cc->certStore, profile);
+#if 0
if (nssrv == PR_SUCCESS) {
profile->object.cryptoContext = cc;
}
+#endif
return nssrv;
}
@@ -214,36 +241,22 @@ NSSCryptoContext_FindBestCertificateByNickname
NSSPolicies *policiesOpt /* NULL for none */
)
{
- PRIntn i;
- NSSCertificate *c;
- NSSCertificate **nickCerts;
- nssBestCertificateCB best;
+ NSSCertificate **certs;
+ NSSCertificate *rvCert = NULL;
if (!cc->certStore) {
return NULL;
}
- nssBestCertificate_SetArgs(&best, timeOpt, usage, policiesOpt);
- /* This could be improved by querying the store with a callback */
- nickCerts = nssCertificateStore_FindCertificatesByNickname(cc->certStore,
- name,
- NULL,
- 0,
- NULL);
- if (nickCerts) {
- PRStatus nssrv;
- for (i=0, c = *nickCerts; c != NULL; c = nickCerts[++i]) {
- nssrv = nssBestCertificate_Callback(c, &best);
- NSSCertificate_Destroy(c);
- if (nssrv != PR_SUCCESS) {
- if (best.cert) {
- NSSCertificate_Destroy(best.cert);
- best.cert = NULL;
- }
- break;
- }
- }
- nss_ZFreeIf(nickCerts);
+ certs = nssCertificateStore_FindCertificatesByNickname(cc->certStore,
+ name,
+ NULL, 0, NULL);
+ if (certs) {
+ rvCert = nssCertificateArray_FindBestCertificate(certs,
+ timeOpt,
+ usage,
+ policiesOpt);
+ nssCertificateArray_Destroy(certs);
}
- return best.cert;
+ return rvCert;
}
NSS_IMPLEMENT NSSCertificate **
@@ -295,39 +308,26 @@ NSSCryptoContext_FindBestCertificateBySubject
NSSPolicies *policiesOpt
)
{
- PRIntn i;
- NSSCertificate *c;
- NSSCertificate **subjectCerts;
- nssBestCertificateCB best;
+ NSSCertificate **certs;
+ NSSCertificate *rvCert = NULL;
if (!cc->certStore) {
return NULL;
}
- nssBestCertificate_SetArgs(&best, timeOpt, usage, policiesOpt);
- subjectCerts = nssCertificateStore_FindCertificatesBySubject(cc->certStore,
- subject,
- NULL,
- 0,
- NULL);
- if (subjectCerts) {
- PRStatus nssrv;
- for (i=0, c = *subjectCerts; c != NULL; c = subjectCerts[++i]) {
- nssrv = nssBestCertificate_Callback(c, &best);
- NSSCertificate_Destroy(c);
- if (nssrv != PR_SUCCESS) {
- if (best.cert) {
- NSSCertificate_Destroy(best.cert);
- best.cert = NULL;
- }
- break;
- }
- }
- nss_ZFreeIf(subjectCerts);
+ certs = nssCertificateStore_FindCertificatesBySubject(cc->certStore,
+ subject,
+ NULL, 0, NULL);
+ if (certs) {
+ rvCert = nssCertificateArray_FindBestCertificate(certs,
+ timeOpt,
+ usage,
+ policiesOpt);
+ nssCertificateArray_Destroy(certs);
}
- return best.cert;
+ return rvCert;
}
NSS_IMPLEMENT NSSCertificate **
-NSSCryptoContext_FindCertificatesBySubject
+nssCryptoContext_FindCertificatesBySubject
(
NSSCryptoContext *cc,
NSSDER *subject,
@@ -348,6 +348,21 @@ NSSCryptoContext_FindCertificatesBySubject
return rvCerts;
}
+NSS_IMPLEMENT NSSCertificate **
+NSSCryptoContext_FindCertificatesBySubject
+(
+ NSSCryptoContext *cc,
+ NSSDER *subject,
+ NSSCertificate *rvOpt[],
+ PRUint32 maximumOpt, /* 0 for no max */
+ NSSArena *arenaOpt
+)
+{
+ return nssCryptoContext_FindCertificatesBySubject(cc, subject,
+ rvOpt, maximumOpt,
+ arenaOpt);
+}
+
NSS_IMPLEMENT NSSCertificate *
NSSCryptoContext_FindBestCertificateByNameComponents
(
@@ -401,35 +416,22 @@ NSSCryptoContext_FindBestCertificateByEmail
NSSPolicies *policiesOpt
)
{
- PRIntn i;
- NSSCertificate *c;
- NSSCertificate **emailCerts;
- nssBestCertificateCB best;
+ NSSCertificate **certs;
+ NSSCertificate *rvCert = NULL;
if (!cc->certStore) {
return NULL;
}
- nssBestCertificate_SetArgs(&best, timeOpt, usage, policiesOpt);
- emailCerts = nssCertificateStore_FindCertificatesByEmail(cc->certStore,
- email,
- NULL,
- 0,
- NULL);
- if (emailCerts) {
- PRStatus nssrv;
- for (i=0, c = *emailCerts; c != NULL; c = emailCerts[++i]) {
- nssrv = nssBestCertificate_Callback(c, &best);
- NSSCertificate_Destroy(c);
- if (nssrv != PR_SUCCESS) {
- if (best.cert) {
- NSSCertificate_Destroy(best.cert);
- best.cert = NULL;
- }
- break;
- }
- }
- nss_ZFreeIf(emailCerts);
+ certs = nssCertificateStore_FindCertificatesByEmail(cc->certStore,
+ email,
+ NULL, 0, NULL);
+ if (certs) {
+ rvCert = nssCertificateArray_FindBestCertificate(certs,
+ timeOpt,
+ usage,
+ policiesOpt);
+ nssCertificateArray_Destroy(certs);
}
- return best.cert;
+ return rvCert;
}
NSS_IMPLEMENT NSSCertificate **
@@ -649,31 +651,6 @@ struct token_session_str {
nssSession *session;
};
-#ifdef nodef
-static nssSession *
-get_token_session(NSSCryptoContext *cc, NSSToken *tok)
-{
- struct token_session_str *ts;
- for (ts = (struct token_session_str *)nssListIterator_Start(cc->sessions);
- ts != (struct token_session_str *)NULL;
- ts = (struct token_session_str *)nssListIterator_Next(cc->sessions))
- {
- if (ts->token == tok) { /* will this need to be more general? */
- break;
- }
- }
- nssListIterator_Finish(cc->sessions);
- if (!ts) {
- /* need to create a session for this token. */
- ts = nss_ZNEW(NULL, struct token_session_str);
- ts->token = nssToken_AddRef(tok);
- ts->session = nssSlot_CreateSession(tok->slot, cc->arena, PR_FALSE);
- nssList_AddElement(cc->sessionList, (void *)ts);
- }
- return ts->session;
-}
-#endif
-
NSS_IMPLEMENT NSSItem *
NSSCryptoContext_Decrypt
(
@@ -685,58 +662,7 @@ NSSCryptoContext_Decrypt
NSSArena *arenaOpt
)
{
-#if 0
- NSSToken *tok;
- nssSession *session;
- NSSItem *rvData;
- PRUint32 dataLen;
- NSSAlgorithmAndParameters *ap;
- CK_RV ckrv;
- ap = (apOpt) ? apOpt : cc->defaultAlgorithm;
- /* Get the token for this operation */
- tok = nssTrustDomain_GetCryptoToken(cc->trustDomain, ap);
- if (!tok) {
- return (NSSItem *)NULL;
- }
- /* Get the local session for this token */
- session = get_token_session(cc, tok);
- /* Get the key needed to decrypt */
- keyHandle = get_decrypt_key(cc, ap);
- /* Set up the decrypt operation */
- ckrv = CKAPI(tok)->C_DecryptInit(session->handle,
- &ap->mechanism, keyHandle);
- if (ckrv != CKR_OK) {
- /* handle PKCS#11 error */
- return (NSSItem *)NULL;
- }
- /* Get the length of the output buffer */
- ckrv = CKAPI(tok)->C_Decrypt(session->handle,
- (CK_BYTE_PTR)encryptedData->data,
- (CK_ULONG)encryptedData->size,
- (CK_BYTE_PTR)NULL,
- (CK_ULONG_PTR)&dataLen);
- if (ckrv != CKR_OK) {
- /* handle PKCS#11 error */
- return (NSSItem *)NULL;
- }
- /* Alloc return value memory */
- rvData = nssItem_Create(NULL, NULL, dataLen, NULL);
- if (!rvItem) {
- return (NSSItem *)NULL;
- }
- /* Do the decryption */
- ckrv = CKAPI(tok)->C_Decrypt(cc->session->handle,
- (CK_BYTE_PTR)encryptedData->data,
- (CK_ULONG)encryptedData->size,
- (CK_BYTE_PTR)rvData->data,
- (CK_ULONG_PTR)&dataLen);
- if (ckrv != CKR_OK) {
- /* handle PKCS#11 error */
- nssItem_ZFreeIf(rvData);
- return (NSSItem *)NULL;
- }
- return rvData;
-#endif
+ nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
diff --git a/security/nss/lib/pki/manifest.mn b/security/nss/lib/pki/manifest.mn
index 2367cf8e4..c4bf70b24 100644
--- a/security/nss/lib/pki/manifest.mn
+++ b/security/nss/lib/pki/manifest.mn
@@ -55,6 +55,7 @@ CSRCS = \
tdcache.c \
certdecode.c \
pkistore.c \
+ pkibase.c \
$(NULL)
ifndef PURE_STAN_BUILD
diff --git a/security/nss/lib/pki/nsspki.def b/security/nss/lib/pki/nsspki.def
deleted file mode 100644
index d32a4d1e6..000000000
--- a/security/nss/lib/pki/nsspki.def
+++ /dev/null
@@ -1,249 +0,0 @@
-;+#
-;+# 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) 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.
-;+#
-;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS
-;+# 1. For all unix platforms, the string ";-" means "remove this line"
-;+# 2. For all unix platforms, the string " DATA " will be removed from any
-;+# line on which it occurs.
-;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
-;+# On AIX, lines containing ";+" will be removed.
-;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed.
-;+# 5. For all unix platforms, after the above processing has taken place,
-;+# all characters after the first ";" on the line will be removed.
-;+# And for AIX, the first ";" will also be removed.
-;+# This file is passed directly to windows. Since ';' is a comment, all UNIX
-;+# directives are hidden behind ";", ";+", and ";-"
-;+#
-;+#
-;+# This file contains the complete Stan API to date. Functions that are
-;+# not yet implemented are commented out.
-;+
-;+NSS_3.4 { # NSS 3.4 release
-;+ global:
-LIBRARY nsspki3 ;-
-EXPORTS ;-
-NSSArena_Create
-NSSArena_Destroy
-NSS_GetError
-NSS_GetErrorStack
-;NSSCertificate_Destroy;
-;NSSCertificate_DeleteStoredObject;
-;NSSCertificate_Validate;
-;NSSCertificate_ValidateCompletely;
-;NSSCertificate_ValidateAndDiscoverUsagesAndPolicies;
-;NSSCertificate_Encode;
-;NSSCertificate_BuildChain;
-;NSSCertificate_GetTrustDomain;
-;NSSCertificate_GetToken;
-;NSSCertificate_GetSlot;
-;NSSCertificate_GetModule;
-;NSSCertificate_Encrypt;
-;NSSCertificate_Verify;
-;NSSCertificate_VerifyRecover;
-;NSSCertificate_WrapSymmetricKey;
-;NSSCertificate_CreateCryptoContext;
-;NSSCertificate_GetPublicKey;
-;NSSCertificate_FindPrivateKey;
-;NSSCertificate_IsPrivateKeyAvailable;
-;NSSUserCertificate_IsStillPresent;
-;NSSUserCertificate_Decrypt;
-;NSSUserCertificate_Sign;
-;NSSUserCertificate_SignRecover;
-;NSSUserCertificate_UnwrapSymmetricKey;
-;NSSUserCertificate_DeriveSymmetricKey;
-;NSSPrivateKey_Destroy;
-;NSSPrivateKey_DeleteStoredObject;
-;NSSPrivateKey_GetSignatureLength;
-;NSSPrivateKey_GetPrivateModulusLength;
-;NSSPrivateKey_IsStillPresent;
-;NSSPrivateKey_Encode;
-;NSSPrivateKey_GetTrustDomain;
-;NSSPrivateKey_GetToken;
-;NSSPrivateKey_GetSlot;
-;NSSPrivateKey_GetModule;
-;NSSPrivateKey_Decrypt;
-;NSSPrivateKey_Sign;
-;NSSPrivateKey_SignRecover;
-;NSSPrivateKey_UnwrapSymmetricKey;
-;NSSPrivateKey_DeriveSymmetricKey;
-;NSSPrivateKey_FindPublicKey;
-;NSSPrivateKey_CreateCryptoContext;
-;NSSPrivateKey_FindCertificates;
-;NSSPrivateKey_FindBestCertificate;
-;NSSPublicKey_Destroy;
-;NSSPublicKey_DeleteStoredObject;
-;NSSPublicKey_Encode;
-;NSSPublicKey_GetTrustDomain;
-;NSSPublicKey_GetToken;
-;NSSPublicKey_GetSlot;
-;NSSPublicKey_GetModule;
-;NSSPublicKey_Encrypt;
-;NSSPublicKey_Verify;
-;NSSPublicKey_VerifyRecover;
-;NSSPublicKey_WrapSymmetricKey;
-;NSSPublicKey_CreateCryptoContext;
-;NSSPublicKey_FindCertificates;
-;NSSPublicKey_FindBestCertificate;
-;NSSPublicKey_FindPrivateKey;
-;NSSSymmetricKey_Destroy;
-;NSSSymmetricKey_DeleteStoredObject;
-;NSSSymmetricKey_GetKeyLength;
-;NSSSymmetricKey_GetKeyStrength;
-;NSSSymmetricKey_IsStillPresent;
-;NSSSymmetricKey_GetTrustDomain;
-;NSSSymmetricKey_GetToken;
-;NSSSymmetricKey_GetSlot;
-;NSSSymmetricKey_GetModule;
-;NSSSymmetricKey_Encrypt;
-;NSSSymmetricKey_Decrypt;
-;NSSSymmetricKey_Sign;
-;NSSSymmetricKey_SignRecover;
-;NSSSymmetricKey_Verify;
-;NSSSymmetricKey_VerifyRecover;
-;NSSSymmetricKey_WrapSymmetricKey;
-;NSSSymmetricKey_WrapPrivateKey;
-;NSSSymmetricKey_UnwrapSymmetricKey;
-;NSSSymmetricKey_UnwrapPrivateKey;
-;NSSSymmetricKey_DeriveSymmetricKey;
-;NSSSymmetricKey_CreateCryptoContext;
-NSSTrustDomain_Create;
-;NSSTrustDomain_Destroy;
-;NSSTrustDomain_SetDefaultCallback;
-;NSSTrustDomain_GetDefaultCallback;
-NSSTrustDomain_LoadModule;
-;NSSTrustDomain_DisableToken;
-;NSSTrustDomain_EnableToken;
-;NSSTrustDomain_IsTokenEnabled;
-;NSSTrustDomain_FindSlotByName;
-;NSSTrustDomain_FindTokenByName;
-;NSSTrustDomain_FindTokenBySlotName;
-;NSSTrustDomain_FindTokenForAlgorithm;
-;NSSTrustDomain_FindBestTokenForAlgorithms;
-;NSSTrustDomain_Login;
-;NSSTrustDomain_Logout;
-;NSSTrustDomain_ImportCertificate;
-;NSSTrustDomain_ImportPKIXCertificate;
-;NSSTrustDomain_ImportEncodedCertificate;
-;NSSTrustDomain_ImportEncodedCertificateChain;
-;NSSTrustDomain_ImportEncodedPrivateKey;
-;NSSTrustDomain_ImportEncodedPublicKey;
-;NSSTrustDomain_FindBestCertificateByNickname;
-NSSTrustDomain_FindCertificatesByNickname
-;NSSTrustDomain_FindCertificateByIssuerAndSerialNumber;
-;NSSTrustDomain_FindBestCertificateBySubject;
-;NSSTrustDomain_FindCertificatesBySubject;
-;NSSTrustDomain_FindBestCertificateByNameComponents;
-;NSSTrustDomain_FindCertificatesByNameComponents;
-;NSSTrustDomain_FindCertificateByEncodedCertificate;
-;NSSTrustDomain_FindCertificateByEmail;
-;NSSTrustDomain_FindCertificatesByEmail;
-;NSSTrustDomain_FindCertificateByOCSPHash;
-;NSSTrustDomain_FindBestUserCertificate;
-;NSSTrustDomain_FindUserCertificates;
-;NSSTrustDomain_FindBestUserCertificateForSSLClientAuth;
-;NSSTrustDomain_FindUserCertificatesForSSLClientAuth;
-;NSSTrustDomain_FindBestUserCertificateForEmailSigning;
-;NSSTrustDomain_FindUserCertificatesForEmailSigning;
-;NSSTrustDomain_GenerateKeyPair;
-;NSSTrustDomain_GenerateSymmetricKey;
-;NSSTrustDomain_GenerateSymmetricKeyFromPassword;
-;NSSTrustDomain_FindSymmetricKeyByAlgorithmAndKeyID;
-;NSSTrustDomain_CreateCryptoContext;
-;NSSTrustDomain_CreateCryptoContextForAlgorithm;
-;NSSTrustDomain_CreateCryptoContextForAlgorithmAndParameters;
-;NSSCryptoContext_Destroy;
-;NSSCryptoContext_SetDefaultCallback;
-;NSSCryptoContext_GetDefaultCallback;
-;NSSCryptoContext_GetTrustDomain;
-;NSSCryptoContext_ImportCertificate;
-;NSSCryptoContext_ImportPKIXCertificate;
-;NSSCryptoContext_ImportEncodedCertificate;
-;NSSCryptoContext_ImportEncodedPKIXCertificateChain;
-;NSSCryptoContext_FindBestCertificateByNickname;
-;NSSCryptoContext_FindCertificatesByNickname;
-;NSSCryptoContext_FindCertificateByIssuerAndSerialNumber;
-;NSSCryptoContext_FindBestCertificateBySubject;
-;NSSCryptoContext_FindCertificatesBySubject;
-;NSSCryptoContext_FindBestCertificateByNameComponents;
-;NSSCryptoContext_FindCertificatesByNameComponents;
-;NSSCryptoContext_FindCertificateByEncodedCertificate;
-;NSSCryptoContext_FindBestCertificateByEmail;
-;NSSCryptoContext_FindCertificatesByEmail;
-;NSSCryptoContext_FindCertificateByOCSPHash;
-;NSSCryptoContext_FindBestUserCertificate;
-;NSSCryptoContext_FindUserCertificates;
-;NSSCryptoContext_FindBestUserCertificateForSSLClientAuth;
-;NSSCryptoContext_FindUserCertificatesForSSLClientAuth;
-;NSSCryptoContext_FindBestUserCertificateForEmailSigning;
-;NSSCryptoContext_FindUserCertificatesForEmailSigning;
-;NSSCryptoContext_GenerateKeyPair;
-;NSSCryptoContext_GenerateSymmetricKey;
-;NSSCryptoContext_GenerateSymmetricKeyFromPassword;
-;NSSCryptoContext_FindSymmetricKeyByAlgorithmAndKeyID;
-;NSSCryptoContext_Decrypt;
-;NSSCryptoContext_BeginDecrypt;
-;NSSCryptoContext_ContinueDecrypt;
-;NSSCryptoContext_FinishDecrypt;
-;NSSCryptoContext_Sign;
-;NSSCryptoContext_BeginSign;
-;NSSCryptoContext_ContinueSign;
-;NSSCryptoContext_FinishSign;
-;NSSCryptoContext_SignRecover;
-;NSSCryptoContext_BeginSignRecover;
-;NSSCryptoContext_ContinueSignRecover;
-;NSSCryptoContext_FinishSignRecover;
-;NSSCryptoContext_UnwrapSymmetricKey;
-;NSSCryptoContext_DeriveSymmetricKey;
-;NSSCryptoContext_Encrypt;
-;NSSCryptoContext_BeginEncrypt;
-;NSSCryptoContext_ContinueEncrypt;
-;NSSCryptoContext_FinishEncrypt;
-;NSSCryptoContext_Verify;
-;NSSCryptoContext_BeginVerify;
-;NSSCryptoContext_ContinueVerify;
-;NSSCryptoContext_FinishVerify;
-;NSSCryptoContext_VerifyRecover;
-;NSSCryptoContext_BeginVerifyRecover;
-;NSSCryptoContext_ContinueVerifyRecover;
-;NSSCryptoContext_FinishVerifyRecover;
-;NSSCryptoContext_WrapSymmetricKey;
-;NSSCryptoContext_Digest;
-;NSSCryptoContext_BeginDigest;
-;NSSCryptoContext_ContinueDigest;
-;NSSCryptoContext_FinishDigest;
-;NSSCryptoContext_Clone;
-;+ local:
-NSSTrustDomain_TraverseCertificates;
-NSSCertificate_GetID;
-NSSCertificate_GetLabel;
-;+ *;
-;+};
diff --git a/security/nss/lib/pki/nsspki.rc b/security/nss/lib/pki/nsspki.rc
deleted file mode 100644
index 5228cefb3..000000000
--- a/security/nss/lib/pki/nsspki.rc
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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) 2001 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.
- */
-
-#include "nss.h"
-#include <winver.h>
-
-#define MY_LIBNAME "nsspki"
-#define MY_FILEDESCRIPTION "NSS PKI Base Library"
-
-#define STRINGIZE(x) #x
-#define STRINGIZE2(x) STRINGIZE(x)
-#define NSS_VMAJOR_STR STRINGIZE2(NSS_VMAJOR)
-
-#ifdef _DEBUG
-#define MY_DEBUG_STR " (debug)"
-#define MY_FILEFLAGS_1 VS_FF_DEBUG
-#else
-#define MY_DEBUG_STR ""
-#define MY_FILEFLAGS_1 0x0L
-#endif
-#if NSS_BETA
-#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE
-#else
-#define MY_FILEFLAGS_2 MY_FILEFLAGS_1
-#endif
-
-#ifdef WINNT
-#define MY_FILEOS VOS_NT_WINDOWS32
-#else
-#define MY_FILEOS VOS__WINDOWS32
-#endif
-
-#define MY_INTERNAL_NAME MY_LIBNAME NSS_VMAJOR_STR
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Version-information resource
-//
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,0
- PRODUCTVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,0
- FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
- FILEFLAGS MY_FILEFLAGS_2
- FILEOS MY_FILEOS
- FILETYPE VFT_DLL
- FILESUBTYPE 0x0L // not used
-
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904B0" // Lang=US English, CharSet=Unicode
- BEGIN
- VALUE "CompanyName", "Netscape Communications Corporation\0"
- VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
- VALUE "FileVersion", NSS_VERSION "\0"
- VALUE "InternalName", MY_INTERNAL_NAME "\0"
- VALUE "LegalCopyright", "Copyright \251 1994-2001 Netscape Communications Corporation\0"
- VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
- VALUE "ProductName", "Network Security Services\0"
- VALUE "ProductVersion", NSS_VERSION "\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
-END
diff --git a/security/nss/lib/pki/pki.h b/security/nss/lib/pki/pki.h
index 4460b52be..d9af582b0 100644
--- a/security/nss/lib/pki/pki.h
+++ b/security/nss/lib/pki/pki.h
@@ -38,29 +38,147 @@
static const char PKI_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#endif /* DEBUG */
-#ifndef PKIT_H
-#include "pkit.h"
-#endif /* PKIT_H */
-
#ifndef NSSDEVT_H
#include "nssdevt.h"
#endif /* NSSDEVT_H */
+#ifndef NSSPKI_H
+#include "nsspki.h"
+#endif /* NSSPKI_H */
+
+#ifndef PKIT_H
+#include "pkit.h"
+#endif /* PKIT_H */
+
PR_BEGIN_EXTERN_C
+NSS_EXTERN NSSCallback *
+nssTrustDomain_GetDefaultCallback
+(
+ NSSTrustDomain *td,
+ PRStatus *statusOpt
+);
+
+NSS_EXTERN NSSCertificate **
+nssTrustDomain_FindCertificatesBySubject
+(
+ NSSTrustDomain *td,
+ NSSDER *subject,
+ NSSCertificate *rvOpt[],
+ PRUint32 maximumOpt,
+ NSSArena *arenaOpt
+);
+
+NSS_EXTERN NSSTrust *
+nssTrustDomain_FindTrustForCertificate
+(
+ NSSTrustDomain *td,
+ NSSCertificate *c
+);
+
NSS_EXTERN NSSCertificate *
nssCertificate_AddRef
(
NSSCertificate *c
);
+NSS_EXTERN PRStatus
+nssCertificate_Destroy
+(
+ NSSCertificate *c
+);
+
+NSS_EXTERN NSSDER *
+nssCertificate_GetEncoding
+(
+ NSSCertificate *c
+);
+
+NSS_EXTERN NSSDER *
+nssCertificate_GetIssuer
+(
+ NSSCertificate *c
+);
+
+NSS_EXTERN NSSDER *
+nssCertificate_GetSerialNumber
+(
+ NSSCertificate *c
+);
+
+NSS_EXTERN NSSDER *
+nssCertificate_GetSubject
+(
+ NSSCertificate *c
+);
+
NSS_EXTERN NSSUTF8 *
-NSSCertificate_GetNickname
+nssCertificate_GetNickname
(
NSSCertificate *c,
NSSToken *tokenOpt
);
+NSS_EXTERN NSSASCII7 *
+nssCertificate_GetEmailAddress
+(
+ NSSCertificate *c
+);
+
+NSS_EXTERN PRBool
+nssCertificate_IssuerAndSerialEqual
+(
+ NSSCertificate *c1,
+ NSSCertificate *c2
+);
+
+NSS_EXTERN NSSPrivateKey *
+nssPrivateKey_AddRef
+(
+ NSSPrivateKey *vk
+);
+
+NSS_EXTERN PRStatus
+nssPrivateKey_Destroy
+(
+ NSSPrivateKey *vk
+);
+
+NSS_EXTERN NSSItem *
+nssPrivateKey_GetID
+(
+ NSSPrivateKey *vk
+);
+
+NSS_EXTERN NSSUTF8 *
+nssPrivateKey_GetNickname
+(
+ NSSPrivateKey *vk,
+ NSSToken *tokenOpt
+);
+
+NSS_EXTERN PRStatus
+nssPublicKey_Destroy
+(
+ NSSPublicKey *bk
+);
+
+NSS_EXTERN NSSItem *
+nssPublicKey_GetID
+(
+ NSSPublicKey *vk
+);
+
+NSS_EXTERN NSSCertificate **
+nssCryptoContext_FindCertificatesBySubject
+(
+ NSSCryptoContext *cc,
+ NSSDER *subject,
+ NSSCertificate *rvOpt[],
+ PRUint32 maximumOpt, /* 0 for no max */
+ NSSArena *arenaOpt
+);
+
/* putting here for now, needs more thought */
NSS_EXTERN PRStatus
nssCryptoContext_ImportTrust
diff --git a/security/nss/lib/pki/pki3hack.c b/security/nss/lib/pki/pki3hack.c
index 8a8d3bf63..93d840506 100644
--- a/security/nss/lib/pki/pki3hack.c
+++ b/security/nss/lib/pki/pki3hack.c
@@ -71,9 +71,6 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#include "pkistore.h"
#include "secmod.h"
-/* if it's got more than 10 certs, it better handle traversal well */
-#define NSSTOKEN_MAX_LOCAL_CERTS 10
-
NSSTrustDomain *g_default_trust_domain = NULL;
NSSCryptoContext *g_default_crypto_context = NULL;
@@ -90,246 +87,6 @@ STAN_GetDefaultCryptoContext()
return g_default_crypto_context;
}
-NSS_IMPLEMENT NSSToken *
-STAN_GetDefaultCryptoToken
-(
- void
-)
-{
- PK11SlotInfo *pk11slot = PK11_GetInternalSlot();
- return PK11Slot_GetNSSToken(pk11slot);
-}
-
-static CERTCertificate *
-stan_GetCERTCertificate(NSSCertificate *c, PRBool forceUpdate);
-
-/* stuff the cert in the global trust domain cache, and then add a reference
- * to remain with the token in a list.
- */
-static PRStatus
-cache_token_cert(NSSCertificate *c, void *arg)
-{
- NSSToken *token = (NSSToken *)arg;
- NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
- NSSCertificate *cp = nssCertificate_AddRef(c);
- if (nssList_Count(token->certList) > NSSTOKEN_MAX_LOCAL_CERTS) {
- nssToken_DestroyCertList(token, PR_TRUE);
- /* terminate the traversal */
- return PR_FAILURE;
- }
- nssTrustDomain_AddCertsToCache(td, &c, 1);
- if (cp == c) {
- NSSCertificate_Destroy(cp);
- } else {
- /* The cert was already in the cache, from another token. Add this
- * token's instance to the cert.
- */
- nssCryptokiInstance *tokenInstance, *instance;
- nssList_GetArray(cp->object.instanceList, (void **)&tokenInstance, 1);
- instance = nssCryptokiInstance_Create(c->object.arena, token,
- tokenInstance->handle, PR_TRUE);
- nssList_Add(c->object.instanceList, instance);
- nssListIterator_Destroy(c->object.instances);
- c->object.instances = nssList_CreateIterator(c->object.instanceList);
- }
- /* This list reference persists with the token */
- nssList_Add(token->certList, nssCertificate_AddRef(c));
- /* The cert needs to become external (made into a CERTCertificate)
- * in order for it to be properly released.
- * Force an update of the nickname and slot fields.
- */
- (void)stan_GetCERTCertificate(c, PR_TRUE);
- return PR_SUCCESS;
-}
-
-static void remove_token_instance(NSSCertificate *c, NSSToken *token)
-{
- nssListIterator *instances;
- nssCryptokiInstance *instance, *rmInstance = NULL;
- instances = c->object.instances;
- for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances);
- instance != (nssCryptokiInstance *)NULL;
- instance = (nssCryptokiInstance *)nssListIterator_Next(instances))
- {
- if (instance->token == token) {
- rmInstance = instance;
- break;
- }
- }
- nssListIterator_Finish(instances);
- if (rmInstance) {
- nssList_Remove(c->object.instanceList, rmInstance);
- nssListIterator_Destroy(instances);
- c->object.instances = nssList_CreateIterator(c->object.instanceList);
- }
-}
-
-static PRBool instance_destructor(NSSCertificate *c, NSSToken *token)
-{
- remove_token_instance(c, token);
- if (nssList_Count(c->object.instanceList) == 0) {
- return PR_TRUE;
- }
- return PR_FALSE;
-}
-
-NSS_IMPLEMENT void
-destroy_token_certs(nssList *certList, NSSToken *token, PRBool renewInstances)
-{
- nssListIterator *certs;
- NSSCertificate *cert;
- PRBool removeIt;
- certs = nssList_CreateIterator(certList);
- for (cert = (NSSCertificate *)nssListIterator_Start(certs);
- cert != (NSSCertificate *)NULL;
- cert = (NSSCertificate *)nssListIterator_Next(certs))
- {
- removeIt = instance_destructor(cert, token);
- if (removeIt) {
- nssList_Remove(certList, cert);
- CERT_DestroyCertificate(STAN_GetCERTCertificate(cert));
- } else if (renewInstances) {
- /* force an update of the nickname and slot fields of the cert */
- (void)stan_GetCERTCertificate(cert, PR_TRUE);
- }
- }
- nssListIterator_Finish(certs);
- nssListIterator_Destroy(certs);
-}
-
-NSS_IMPLEMENT void
-nssCertificateList_DestroyTokenCerts(nssList *certList, NSSToken *token)
-{
- destroy_token_certs(certList, token, PR_TRUE);
-}
-
-NSS_IMPLEMENT void
-nssCertificateList_RemoveTokenCerts(nssList *certList, NSSToken *token)
-{
- nssListIterator *certs;
- NSSCertificate *cert;
- PRBool removeIt;
- certs = nssList_CreateIterator(certList);
- for (cert = (NSSCertificate *)nssListIterator_Start(certs);
- cert != (NSSCertificate *)NULL;
- cert = (NSSCertificate *)nssListIterator_Next(certs))
- {
- removeIt = instance_destructor(cert, token);
- if (removeIt) {
- nssList_Remove(certList, cert);
- } else {
- /* force an update of the nickname and slot fields of the cert */
- (void)stan_GetCERTCertificate(cert, PR_TRUE);
- }
- }
- nssListIterator_Finish(certs);
- nssListIterator_Destroy(certs);
-}
-
-/* destroy the list of certs on a token */
-NSS_IMPLEMENT void
-nssToken_DestroyCertList(NSSToken *token, PRBool renewInstances)
-{
- if (!token->certList) {
- return;
- }
- destroy_token_certs(token->certList, token, renewInstances);
- nssList_Clear(token->certList, NULL);
- /* leave the list non-null to prevent it from being searched */
-}
-
-/* create a list of local cert references for certain tokens */
-NSS_IMPLEMENT PRStatus
-nssToken_LoadCerts(NSSToken *token)
-{
- PRStatus nssrv = PR_SUCCESS;
- nssTokenCertSearch search;
- if (!PK11_IsInternal(token->pk11slot) && PK11_IsHW(token->pk11slot)) {
- /* Hardware token certs will be immediately cached, and no searches
- * will be performed on the token (the certs will be discovered by
- * cache lookups)
- */
- search.callback = cache_token_cert;
- search.cbarg = token;
- search.cached = NULL;
- search.searchType = nssTokenSearchType_TokenOnly;
- if (!token->certList) {
- token->certList = nssList_Create(token->arena, PR_FALSE);
- if (!token->certList) {
- return PR_FAILURE;
- }
- } else if (nssList_Count(token->certList) > 0) {
- /* already been done */
- return PR_SUCCESS;
- }
- /* ignore the rv, just work without the list */
- (void)nssToken_TraverseCertificates(token, NULL, &search);
- (void)nssToken_SetTrustCache(token);
- (void)nssToken_SetCrlCache(token);
-
- /* even if there are no certs, leave a valid list pointer should
- * any be imported. Having the pointer will also prevent searches,
- * see below.
- */
- if (nssList_Count(token->certList) == 0 &&
- !PK11_IsLoggedIn(token->pk11slot, NULL)) {
- /* If the token is not logged in, that may be the reason no
- * certs were found.
- */
- token->loggedIn = PR_FALSE;
- }
- }
- return nssrv;
-}
-
-NSS_IMPLEMENT void
-nssToken_UpdateTrustForCerts(NSSToken *token)
-{
- nssListIterator *certs;
- NSSCertificate *cert;
- certs = nssList_CreateIterator(token->certList);
- for (cert = (NSSCertificate *)nssListIterator_Start(certs);
- cert != (NSSCertificate *)NULL;
- cert = (NSSCertificate *)nssListIterator_Next(certs))
- {
- CERTCertificate *cc = STAN_GetCERTCertificate(cert);
- cc->trust = NULL;
- /* force an update of the trust fields of the CERTCertificate */
- (void)stan_GetCERTCertificate(cert, PR_FALSE);
- }
- nssListIterator_Finish(certs);
- nssListIterator_Destroy(certs);
-}
-
-NSS_IMPLEMENT PRBool
-nssToken_SearchCerts
-(
- NSSToken *token,
- PRBool *notPresentOpt
-)
-{
- if (notPresentOpt) {
- *notPresentOpt = PR_FALSE;
- }
- if (!nssToken_IsPresent(token)) {
- nssToken_DestroyCertList(token, PR_TRUE); /* will free cached certs */
- if (notPresentOpt) {
- *notPresentOpt = PR_TRUE;
- }
- } else if (token->certList &&
- nssList_Count(token->certList) == 0 &&
- !token->loggedIn) {
- /* If the token has no cached certs, but wasn't logged in, check
- * to see if it is logged in now and retry
- */
- if (PK11_IsLoggedIn(token->pk11slot, NULL)) {
- token->loggedIn = PR_TRUE;
- nssToken_LoadCerts(token);
- }
- }
- return (PRBool) (token->certList == NULL);
-}
-
NSS_IMPLEMENT PRStatus
STAN_LoadDefaultNSS3TrustDomain
(
@@ -338,8 +95,6 @@ STAN_LoadDefaultNSS3TrustDomain
{
NSSTrustDomain *td;
NSSToken *token;
- PK11SlotList *list;
- PK11SlotListElement *le;
SECMODModuleList *mlp;
SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
int i;
@@ -358,17 +113,9 @@ STAN_LoadDefaultNSS3TrustDomain
}
}
SECMOD_ReleaseReadLock(moduleLock);
+ td->tokens = nssList_CreateIterator(td->tokenList);
g_default_trust_domain = td;
g_default_crypto_context = NSSTrustDomain_CreateCryptoContext(td, NULL);
- /* Cache hardware token certs with the token to make them persistent */
- td->tokens = nssList_CreateIterator(td->tokenList);
- for (token = (NSSToken *)nssListIterator_Start(td->tokens);
- token != (NSSToken *)NULL;
- token = (NSSToken *)nssListIterator_Next(td->tokens))
- {
- nssToken_LoadCerts(token);
- }
- nssListIterator_Finish(td->tokens);
return PR_SUCCESS;
}
@@ -385,7 +132,6 @@ STAN_AddModuleToDefaultTrustDomain
for (i=0; i<module->slotCount; i++) {
token = nssToken_CreateFromPK11SlotInfo(td, module->slots[i]);
PK11Slot_SetNSSToken(module->slots[i], token);
- nssToken_LoadCerts(token);
nssList_Add(td->tokenList, token);
}
nssListIterator_Destroy(td->tokens);
@@ -393,15 +139,6 @@ STAN_AddModuleToDefaultTrustDomain
return SECSuccess;
}
-NSS_IMPLEMENT void
-STAN_DestroyNSSToken(NSSToken *token)
-{
- if (token->certList) {
- nssToken_DestroyCertList(token, PR_FALSE);
- }
- nssToken_Destroy(token);
-}
-
NSS_IMPLEMENT SECStatus
STAN_RemoveModuleFromDefaultTrustDomain
(
@@ -416,7 +153,7 @@ STAN_RemoveModuleFromDefaultTrustDomain
token = PK11Slot_GetNSSToken(module->slots[i]);
if (token) {
nssList_Remove(td->tokenList, token);
- STAN_DestroyNSSToken(token);
+ nssToken_Destroy(token);
}
}
nssListIterator_Destroy(td->tokens);
@@ -461,6 +198,31 @@ STAN_GetCertIdentifierFromDER(NSSArena *arenaOpt, NSSDER *der)
return rvKey;
}
+NSS_IMPLEMENT PRStatus
+nssPKIX509_GetIssuerAndSerialFromDER(NSSDER *der, NSSArena *arena,
+ NSSDER *issuer, NSSDER *serial)
+{
+ SECStatus secrv;
+ SECItem derCert;
+ SECItem derIssuer = { 0 };
+ SECItem derSerial = { 0 };
+ SECITEM_FROM_NSSITEM(&derCert, der);
+ secrv = CERT_SerialNumberFromDERCert(&derCert, &derSerial);
+ if (secrv != SECSuccess) {
+ return PR_FAILURE;
+ }
+ (void)nssItem_Create(arena, serial, derSerial.len, derSerial.data);
+ secrv = CERT_IssuerNameFromDERCert(&derCert, &derIssuer);
+ if (secrv != SECSuccess) {
+ PORT_Free(derSerial.data);
+ return PR_FAILURE;
+ }
+ (void)nssItem_Create(arena, issuer, derIssuer.len, derIssuer.data);
+ PORT_Free(derSerial.data);
+ PORT_Free(derIssuer.data);
+ return PR_SUCCESS;
+}
+
static NSSItem *
nss3certificate_getIdentifier(nssDecodedCert *dc)
{
@@ -476,9 +238,7 @@ nss3certificate_getIssuerIdentifier(nssDecodedCert *dc)
CERTCertificate *c = (CERTCertificate *)dc->data;
CERTAuthKeyID *cAuthKeyID;
PRArenaPool *tmpArena = NULL;
- SECItem issuerCertKey;
NSSItem *rvID = NULL;
- SECStatus secrv;
tmpArena = PORT_NewArena(512);
cAuthKeyID = CERT_FindAuthKeyIDExten(tmpArena, c);
if (cAuthKeyID == NULL) {
@@ -690,22 +450,21 @@ PK11_IsUserCert(PK11SlotInfo *, CERTCertificate *, CK_OBJECT_HANDLE);
/* see pk11cert.c:pk11_HandleTrustObject */
static unsigned int
-get_nss3trust_from_cktrust(CK_TRUST t)
+get_nss3trust_from_nss4trust(CK_TRUST t)
{
unsigned int rt = 0;
- if (t == CKT_NETSCAPE_TRUSTED) {
+ if (t == nssTrustLevel_Trusted) {
rt |= CERTDB_VALID_PEER | CERTDB_TRUSTED;
}
- if (t == CKT_NETSCAPE_TRUSTED_DELEGATOR) {
+ if (t == nssTrustLevel_TrustedDelegator) {
rt |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA /*| CERTDB_NS_TRUSTED_CA*/;
}
- if (t == CKT_NETSCAPE_VALID) {
+ if (t == nssTrustLevel_Valid) {
rt |= CERTDB_VALID_PEER;
}
- if (t == CKT_NETSCAPE_VALID_DELEGATOR) {
+ if (t == nssTrustLevel_ValidDelegator) {
rt |= CERTDB_VALID_CA;
}
- /* user */
return rt;
}
@@ -719,95 +478,61 @@ cert_trust_from_stan_trust(NSSTrust *t, PRArenaPool *arena)
}
rvTrust = PORT_ArenaAlloc(arena, sizeof(CERTCertTrust));
if (!rvTrust) return NULL;
- rvTrust->sslFlags = get_nss3trust_from_cktrust(t->serverAuth);
- client = get_nss3trust_from_cktrust(t->clientAuth);
+ rvTrust->sslFlags = get_nss3trust_from_nss4trust(t->serverAuth);
+ client = get_nss3trust_from_nss4trust(t->clientAuth);
if (client & (CERTDB_TRUSTED_CA|CERTDB_NS_TRUSTED_CA)) {
client &= ~(CERTDB_TRUSTED_CA|CERTDB_NS_TRUSTED_CA);
rvTrust->sslFlags |= CERTDB_TRUSTED_CLIENT_CA;
}
rvTrust->sslFlags |= client;
- rvTrust->emailFlags = get_nss3trust_from_cktrust(t->emailProtection);
- rvTrust->objectSigningFlags = get_nss3trust_from_cktrust(t->codeSigning);
+ rvTrust->emailFlags = get_nss3trust_from_nss4trust(t->emailProtection);
+ rvTrust->objectSigningFlags = get_nss3trust_from_nss4trust(t->codeSigning);
return rvTrust;
}
-static int nsstoken_get_trust_order(NSSToken *token)
-{
- PK11SlotInfo *slot;
- SECMODModule *module;
- slot = token->pk11slot;
- module = PK11_GetModule(slot);
- return module->trustOrder;
-}
-
/* check all cert instances for private key */
static PRBool is_user_cert(NSSCertificate *c, CERTCertificate *cc)
{
PRBool isUser = PR_FALSE;
- nssCryptokiInstance *instance;
- nssListIterator *instances = c->object.instances;
- for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances);
- instance != (nssCryptokiInstance *)NULL;
- instance = (nssCryptokiInstance *)nssListIterator_Next(instances))
- {
+ nssCryptokiObject **ip;
+ nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object);
+ if (!instances) {
+ return PR_FALSE;
+ }
+ for (ip = instances; *ip; ip++) {
+ nssCryptokiObject *instance = *ip;
if (PK11_IsUserCert(instance->token->pk11slot, cc, instance->handle)) {
isUser = PR_TRUE;
}
}
- nssListIterator_Finish(instances);
+ nssCryptokiObjectArray_Destroy(instances);
return isUser;
}
CERTCertTrust *
nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc)
{
- CERTCertTrust *rvTrust;
+ CERTCertTrust *rvTrust = NULL;
NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
- NSSToken *tok;
- NSSTrust *tokenTrust;
- NSSTrust t;
- nssListIterator *tokens;
- int lastTrustOrder, myTrustOrder;
- tokens = nssList_CreateIterator(td->tokenList);
- if (!tokens) return NULL;
- lastTrustOrder = 1<<16; /* just make it big */
- t.serverAuth = CKT_NETSCAPE_TRUST_UNKNOWN;
- t.clientAuth = CKT_NETSCAPE_TRUST_UNKNOWN;
- t.emailProtection = CKT_NETSCAPE_TRUST_UNKNOWN;
- t.codeSigning = CKT_NETSCAPE_TRUST_UNKNOWN;
- for (tok = (NSSToken *)nssListIterator_Start(tokens);
- tok != (NSSToken *)NULL;
- tok = (NSSToken *)nssListIterator_Next(tokens))
- {
- tokenTrust = nssToken_FindTrustForCert(tok, NULL, c,
- nssTokenSearchType_TokenOnly);
- if (tokenTrust) {
- myTrustOrder = nsstoken_get_trust_order(tok);
- if (t.serverAuth == CKT_NETSCAPE_TRUST_UNKNOWN ||
- myTrustOrder < lastTrustOrder) {
- t.serverAuth = tokenTrust->serverAuth;
- }
- if (t.clientAuth == CKT_NETSCAPE_TRUST_UNKNOWN ||
- myTrustOrder < lastTrustOrder) {
- t.clientAuth = tokenTrust->clientAuth;
- }
- if (t.emailProtection == CKT_NETSCAPE_TRUST_UNKNOWN ||
- myTrustOrder < lastTrustOrder) {
- t.emailProtection = tokenTrust->emailProtection;
- }
- if (t.codeSigning == CKT_NETSCAPE_TRUST_UNKNOWN ||
- myTrustOrder < lastTrustOrder) {
- t.codeSigning = tokenTrust->codeSigning;
- }
- (void)nssTrust_Destroy(tokenTrust);
- lastTrustOrder = myTrustOrder;
+ NSSTrust *t;
+ t = nssTrustDomain_FindTrustForCertificate(td, c);
+ if (t) {
+ rvTrust = cert_trust_from_stan_trust(t, cc->arena);
+ if (!rvTrust) {
+ nssTrust_Destroy(t);
+ return NULL;
}
+ nssTrust_Destroy(t);
+ } else {
+ rvTrust = PORT_ArenaAlloc(cc->arena, sizeof(CERTCertTrust));
+ if (!rvTrust) {
+ return NULL;
+ }
+ memset(rvTrust, 0, sizeof(*rvTrust));
}
- nssListIterator_Finish(tokens);
- nssListIterator_Destroy(tokens);
- rvTrust = cert_trust_from_stan_trust(&t, cc->arena);
- if (!rvTrust) return NULL;
if (is_user_cert(c, cc)) {
+ if (!rvTrust) {
+ }
rvTrust->sslFlags |= CERTDB_USER;
rvTrust->emailFlags |= CERTDB_USER;
rvTrust->objectSigningFlags |= CERTDB_USER;
@@ -818,15 +543,15 @@ nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc)
static nssCryptokiInstance *
get_cert_instance(NSSCertificate *c)
{
- nssCryptokiInstance *instance, *ci;
- nssListIterator *instances = c->object.instances;
+ nssCryptokiObject *instance, **ci;
+ nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object);
+ if (!instances) {
+ return NULL;
+ }
instance = NULL;
- for (ci = (nssCryptokiInstance *)nssListIterator_Start(instances);
- ci != (nssCryptokiInstance *)NULL;
- ci = (nssCryptokiInstance *)nssListIterator_Next(instances))
- {
+ for (ci = instances; *ci; ci++) {
if (!instance) {
- instance = ci;
+ instance = nssCryptokiObject_Clone(*ci);
} else {
/* This only really works for two instances... But 3.4 can't
* handle more anyway. The logic is, if there are multiple
@@ -834,11 +559,12 @@ get_cert_instance(NSSCertificate *c)
* a hardware device.
*/
if (PK11_IsInternal(instance->token->pk11slot)) {
- instance = ci;
+ nssCryptokiObject_Destroy(instance);
+ instance = nssCryptokiObject_Clone(*ci);
}
}
}
- nssListIterator_Finish(instances);
+ nssCryptokiObjectArray_Destroy(instances);
return instance;
}
@@ -860,7 +586,6 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced
int nicklen, tokenlen, len;
NSSUTF8 *tokenName = NULL;
char *nick;
- nicklen = nssUTF8_Size(stanNick, &nssrv);
if (instance && !PK11_IsInternal(instance->token->pk11slot)) {
tokenName = nssToken_GetName(instance->token);
tokenlen = nssUTF8_Size(tokenName, &nssrv);
@@ -868,16 +593,21 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced
/* don't use token name for internal slot; 3.3 didn't */
tokenlen = 0;
}
- len = tokenlen + nicklen;
- cc->nickname = PORT_ArenaAlloc(cc->arena, len);
- nick = cc->nickname;
- if (tokenName) {
- memcpy(nick, tokenName, tokenlen-1);
- nick += tokenlen-1;
- *nick++ = ':';
+ if (stanNick) {
+ nicklen = nssUTF8_Size(stanNick, &nssrv);
+ len = tokenlen + nicklen;
+ cc->nickname = PORT_ArenaAlloc(cc->arena, len);
+ nick = cc->nickname;
+ if (tokenName) {
+ memcpy(nick, tokenName, tokenlen-1);
+ nick += tokenlen-1;
+ *nick++ = ':';
+ }
+ memcpy(nick, stanNick, nicklen-1);
+ cc->nickname[len-1] = '\0';
+ } else {
+ cc->nickname = NULL;
}
- memcpy(nick, stanNick, nicklen-1);
- cc->nickname[len-1] = '\0';
}
if (context) {
/* trust */
@@ -888,12 +618,18 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced
}
} else if (instance) {
/* slot */
- cc->slot = PK11_ReferenceSlot(instance->token->pk11slot);
+ if (cc->slot != instance->token->pk11slot) {
+ if (cc->slot) {
+ PK11_FreeSlot(cc->slot);
+ }
+ cc->slot = PK11_ReferenceSlot(instance->token->pk11slot);
+ }
cc->ownSlot = PR_TRUE;
/* pkcs11ID */
cc->pkcs11ID = instance->handle;
/* trust */
cc->trust = nssTrust_GetCERTCertTrustForCert(c, cc);
+ nssCryptokiObject_Destroy(instance);
}
/* database handle is now the trust domain */
cc->dbhandle = c->object.trustDomain;
@@ -933,33 +669,39 @@ stan_GetCERTCertificate(NSSCertificate *c, PRBool forceUpdate)
}
NSS_IMPLEMENT CERTCertificate *
+STAN_ForceCERTCertificateUpdate(NSSCertificate *c)
+{
+ return stan_GetCERTCertificate(c, PR_TRUE);
+}
+
+NSS_IMPLEMENT CERTCertificate *
STAN_GetCERTCertificate(NSSCertificate *c)
{
return stan_GetCERTCertificate(c, PR_FALSE);
}
-static CK_TRUST
+static nssTrustLevel
get_stan_trust(unsigned int t, PRBool isClientAuth)
{
if (isClientAuth) {
if (t & CERTDB_TRUSTED_CLIENT_CA) {
- return CKT_NETSCAPE_TRUSTED_DELEGATOR;
+ return nssTrustLevel_TrustedDelegator;
}
} else {
if (t & CERTDB_TRUSTED_CA || t & CERTDB_NS_TRUSTED_CA) {
- return CKT_NETSCAPE_TRUSTED_DELEGATOR;
+ return nssTrustLevel_TrustedDelegator;
}
}
if (t & CERTDB_TRUSTED) {
- return CKT_NETSCAPE_TRUSTED;
+ return nssTrustLevel_Trusted;
}
if (t & CERTDB_VALID_CA) {
- return CKT_NETSCAPE_VALID_DELEGATOR;
+ return nssTrustLevel_ValidDelegator;
}
if (t & CERTDB_VALID_PEER) {
- return CKT_NETSCAPE_VALID;
+ return nssTrustLevel_Valid;
}
- return CKT_NETSCAPE_UNTRUSTED;
+ return nssTrustLevel_NotTrusted;
}
NSS_EXTERN NSSCertificate *
@@ -967,8 +709,8 @@ STAN_GetNSSCertificate(CERTCertificate *cc)
{
NSSCertificate *c;
nssCryptokiInstance *instance;
+ nssPKIObject *pkiob;
NSSArena *arena;
- PRStatus nssrv;
c = cc->nssCertificate;
if (c) {
return c;
@@ -987,10 +729,12 @@ STAN_GetNSSCertificate(CERTCertificate *cc)
}
NSSITEM_FROM_SECITEM(&c->encoding, &cc->derCert);
c->type = NSSCertificateType_PKIX;
- nssrv = nssPKIObject_Initialize(&c->object, arena, cc->dbhandle, NULL);
- if (nssrv != PR_SUCCESS) {
- nssPKIObject_Destroy(&c->object);
+ pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL);
+ if (!pkiob) {
+ nssArena_Destroy(arena);
+ return NULL;
}
+ c->object = *pkiob;
nssItem_Create(arena,
&c->issuer, cc->derIssuer.len, cc->derIssuer.data);
nssItem_Create(arena,
@@ -1012,7 +756,7 @@ STAN_GetNSSCertificate(CERTCertificate *cc)
}
if (cc->slot) {
instance = nss_ZNEW(arena, nssCryptokiInstance);
- instance->token = PK11Slot_GetNSSToken(cc->slot);
+ instance->token = nssToken_AddRef(PK11Slot_GetNSSToken(cc->slot));
instance->handle = cc->pkcs11ID;
instance->isTokenObject = PR_TRUE;
if (cc->nickname) {
@@ -1021,10 +765,7 @@ STAN_GetNSSCertificate(CERTCertificate *cc)
(NSSUTF8 *)cc->nickname,
PORT_Strlen(cc->nickname));
}
- nssList_Add(c->object.instanceList, instance);
- /* XXX Fix this! */
- nssListIterator_Destroy(c->object.instances);
- c->object.instances = nssList_CreateIterator(c->object.instanceList);
+ nssPKIObject_AddInstance(&c->object, instance);
}
c->decoding = create_decoded_pkix_cert_from_nss3cert(NULL, cc);
cc->nssCertificate = c;
@@ -1043,6 +784,8 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
CERTCertTrust *oldTrust;
nssListIterator *tokens;
PRBool moving_object;
+ nssCryptokiObject *newInstance;
+ nssPKIObject *pkiob;
oldTrust = nssTrust_GetCERTCertTrustForCert(c, cc);
if (oldTrust) {
if (memcmp(oldTrust, trust, sizeof (CERTCertTrust)) == 0) {
@@ -1060,11 +803,12 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
arena = nssArena_Create();
if (!arena) return PR_FAILURE;
nssTrust = nss_ZNEW(arena, NSSTrust);
- nssrv = nssPKIObject_Initialize(&nssTrust->object, arena, NULL, NULL);
- if (nssrv != PR_SUCCESS) {
- nssPKIObject_Destroy(&nssTrust->object);
+ pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL);
+ if (!pkiob) {
+ nssArena_Destroy(arena);
return PR_FAILURE;
}
+ nssTrust->object = *pkiob;
nssTrust->certificate = c;
nssTrust->serverAuth = get_stan_trust(trust->sslFlags, PR_FALSE);
nssTrust->clientAuth = get_stan_trust(trust->sslFlags, PR_TRUE);
@@ -1078,7 +822,7 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
nssTrust_Destroy(nssTrust);
return nssrv;
}
- if (nssList_Count(c->object.instanceList) == 0) {
+ if (c->object.numInstances == 0) {
/* The context is the only instance, finished */
return nssrv;
}
@@ -1106,11 +850,39 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
/* this is kind of hacky. the softoken needs the cert
* object in order to store trust. forcing it to be perm
*/
- NSSUTF8 *nickname = NSSCertificate_GetNickname(c, NULL);
- nssrv = nssToken_ImportCertificate(tok, NULL, c, nickname, PR_TRUE);
- if (nssrv != PR_SUCCESS) return nssrv;
+ NSSUTF8 *nickname = nssCertificate_GetNickname(c, NULL);
+ NSSASCII7 *email = NULL;
+
+ if (PK11_IsInternal(tok->pk11slot)) {
+ email = c->email;
+ }
+ newInstance = nssToken_ImportCertificate(tok, NULL,
+ NSSCertificateType_PKIX,
+ &c->id,
+ nickname,
+ &c->encoding,
+ &c->issuer,
+ &c->subject,
+ &c->serial,
+ email,
+ PR_TRUE);
+ if (!newInstance) {
+ return PR_FAILURE;
+ }
+ nssPKIObject_AddInstance(&c->object, newInstance);
+ }
+ newInstance = nssToken_ImportTrust(tok, NULL, &c->encoding,
+ &c->issuer, &c->serial,
+ nssTrust->serverAuth,
+ nssTrust->clientAuth,
+ nssTrust->codeSigning,
+ nssTrust->emailProtection, PR_TRUE);
+ if (newInstance) {
+ nssCryptokiObject_Destroy(newInstance);
+ nssrv = PR_SUCCESS;
+ } else {
+ nssrv = PR_FAILURE;
}
- nssrv = nssToken_ImportTrust(tok, NULL, nssTrust, PR_TRUE);
} else {
nssrv = PR_FAILURE;
}
@@ -1174,103 +946,6 @@ nssTrustDomain_TraverseCertificatesByNickname
return nssrv;
}
-/* SEC_TraversePermCerts */
-NSS_IMPLEMENT PRStatus
-nssTrustDomain_TraverseCertificates
-(
- NSSTrustDomain *td,
- PRStatus (*callback)(NSSCertificate *c, void *arg),
- void *arg
-)
-{
- PRStatus nssrv = PR_SUCCESS;
- NSSToken *token;
- nssList *certList;
- nssTokenCertSearch search;
- /* grab all cache certs (XXX please only do this here...)
- * the alternative is to provide a callback through search that allows
- * the token to query the cache for the cert during traversal.
- */
- certList = nssList_Create(NULL, PR_FALSE);
- (void)nssTrustDomain_GetCertsFromCache(td, certList);
- /* set the search criteria */
- search.callback = callback;
- search.cbarg = arg;
- search.cached = certList;
- search.searchType = nssTokenSearchType_TokenOnly;
- for (token = (NSSToken *)nssListIterator_Start(td->tokens);
- token != (NSSToken *)NULL;
- token = (NSSToken *)nssListIterator_Next(td->tokens))
- {
- nssrv = nssToken_TraverseCertificates(token, NULL, &search);
- }
- nssListIterator_Finish(td->tokens);
- nssList_Destroy(certList);
- return nssrv;
-}
-
-#if 0
-static CK_CERTIFICATE_TYPE
-get_cert_type(NSSCertificateType nssType)
-{
- switch (nssType) {
- case NSSCertificateType_PKIX:
- return CKC_X_509;
- default:
- return CK_INVALID_HANDLE; /* Not really! CK_INVALID_HANDLE is not a
- * type CK_CERTIFICATE_TYPE */
- }
-}
-#endif
-
-/* CERT_AddTempCertToPerm */
-NSS_EXTERN PRStatus
-nssTrustDomain_AddTempCertToPerm
-(
- NSSCertificate *c
-)
-{
-#if 0
- NSSToken *token;
- CK_CERTIFICATE_TYPE cert_type;
- CK_ATTRIBUTE cert_template[] =
- {
- { CKA_CLASS, NULL, 0 },
- { CKA_CERTIFICATE_TYPE, NULL, 0 },
- { CKA_ID, NULL, 0 },
- { CKA_VALUE, NULL, 0 },
- { CKA_LABEL, NULL, 0 },
- { CKA_ISSUER, NULL, 0 },
- { CKA_SUBJECT, NULL, 0 },
- { CKA_SERIAL_NUMBER, NULL, 0 }
- };
- CK_ULONG ctsize;
- ctsize = (CK_ULONG)(sizeof(cert_template) / sizeof(cert_template[0]));
- /* XXX sanity checking needed */
- cert_type = get_cert_type(c->type);
- /* Set up the certificate object */
- NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert);
- NSS_CK_SET_ATTRIBUTE_VAR( cert_template, 1, cert_type);
- NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 2, &c->id);
- NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 3, &c->encoding);
- NSS_CK_SET_ATTRIBUTE_UTF8(cert_template, 4, c->nickname);
- NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 5, &c->issuer);
- NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 6, &c->subject);
- NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 7, &c->serial);
- /* This is a hack, ignoring the 4.0 token ordering scheme */
- token = STAN_GetInternalToken();
- c->handle = nssToken_ImportObject(token, NULL, cert_template, ctsize);
- if (c->handle == CK_INVALID_HANDLE) {
- return PR_FAILURE;
- }
- c->token = token;
- c->slot = token->slot;
- /* Do the trust object */
- return PR_SUCCESS;
-#endif
- return PR_FAILURE;
-}
-
static void cert_dump_iter(const void *k, void *v, void *a)
{
NSSCertificate *c = (NSSCertificate *)k;
diff --git a/security/nss/lib/pki/pki3hack.h b/security/nss/lib/pki/pki3hack.h
index c79fc747b..529c81e2b 100644
--- a/security/nss/lib/pki/pki3hack.h
+++ b/security/nss/lib/pki/pki3hack.h
@@ -75,29 +75,6 @@ STAN_LoadDefaultNSS3TrustDomain
NSS_EXTERN void
STAN_Shutdown();
-NSS_EXTERN void
-STAN_DestroyNSSToken(NSSToken *token);
-
-NSS_EXTERN PRBool
-nssToken_SearchCerts
-(
- NSSToken *token,
- PRBool *notPresentOpt
-);
-
-/* renewInstances -- if the cached token certs have multiple instances,
- * don't destroy them. If this parameter is false, they will be destroyed
- * anyway (used for clean shutdown).
- */
-NSS_EXTERN void
-nssToken_DestroyCertList(NSSToken *token, PRBool renewInstances);
-
-NSS_EXTERN void
-nssCertificateList_DestroyTokenCerts(nssList *certList, NSSToken *token);
-
-NSS_EXTERN void
-nssCertificateList_RemoveTokenCerts(nssList *certList, NSSToken *token);
-
NSS_EXTERN SECStatus
STAN_AddModuleToDefaultTrustDomain
(
@@ -111,6 +88,9 @@ STAN_RemoveModuleFromDefaultTrustDomain
);
NSS_EXTERN CERTCertificate *
+STAN_ForceCERTCertificateUpdate(NSSCertificate *c);
+
+NSS_EXTERN CERTCertificate *
STAN_GetCERTCertificate(NSSCertificate *c);
NSS_EXTERN NSSCertificate *
@@ -122,6 +102,10 @@ nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc);
NSS_EXTERN PRStatus
STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust);
+NSS_EXTERN PRStatus
+nssPKIX509_GetIssuerAndSerialFromDER(NSSDER *der, NSSArena *arena,
+ NSSDER *issuer, NSSDER *serial);
+
/* exposing this */
NSS_EXTERN NSSCertificate *
NSSCertificate_Create
diff --git a/security/nss/lib/pki/pkim.h b/security/nss/lib/pki/pkim.h
index 566381055..170a4d938 100644
--- a/security/nss/lib/pki/pkim.h
+++ b/security/nss/lib/pki/pkim.h
@@ -42,97 +42,546 @@ static const char PKIM_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#include "base.h"
#endif /* BASE_H */
+#ifndef PKI_H
+#include "pki.h"
+#endif /* PKI_H */
+
#ifndef PKITM_H
#include "pkitm.h"
#endif /* PKITM_H */
PR_BEGIN_EXTERN_C
-NSS_EXTERN NSSToken *
-STAN_GetDefaultCryptoToken
+/* nssPKIObject
+ *
+ * This is the base object class, common to all PKI objects defined in
+ * in this module. Each object can be safely 'casted' to an nssPKIObject,
+ * then passed to these methods.
+ *
+ * nssPKIObject_Create
+ * nssPKIObject_Destroy
+ * nssPKIObject_AddRef
+ * nssPKIObject_AddInstance
+ * nssPKIObject_HasInstance
+ * nssPKIObject_GetTokens
+ * nssPKIObject_GetNicknameForToken
+ * nssPKIObject_RemoveInstanceForToken
+ * nssPKIObject_DeleteStoredObject
+ */
+
+/* nssPKIObject_Create
+ *
+ * A generic PKI object. It must live in a trust domain. It may be
+ * initialized with a token instance, or alternatively in a crypto context.
+ */
+NSS_EXTERN nssPKIObject *
+nssPKIObject_Create
(
- void
+ NSSArena *arenaOpt,
+ nssCryptokiObject *instanceOpt,
+ NSSTrustDomain *td,
+ NSSCryptoContext *ccOpt
);
-NSS_EXTERN nssHash *
-nssHash_CreateCertificate
+/* nssPKIObject_AddRef
+ */
+NSS_EXTERN nssPKIObject *
+nssPKIObject_AddRef
+(
+ nssPKIObject *object
+);
+
+/* nssPKIObject_Destroy
+ *
+ * Returns true if object was destroyed. This notifies the subclass that
+ * all references are gone and it should delete any members it owns.
+ */
+NSS_EXTERN PRBool
+nssPKIObject_Destroy
+(
+ nssPKIObject *object
+);
+
+/* nssPKIObject_AddInstance
+ *
+ * Add a token instance to the object, if it does not have it already.
+ */
+NSS_EXTERN PRStatus
+nssPKIObject_AddInstance
+(
+ nssPKIObject *object,
+ nssCryptokiObject *instance
+);
+
+/* nssPKIObject_HasInstance
+ *
+ * Query the object for a token instance.
+ */
+NSS_EXTERN PRBool
+nssPKIObject_HasInstance
+(
+ nssPKIObject *object,
+ nssCryptokiObject *instance
+);
+
+/* nssPKIObject_GetTokens
+ *
+ * Get all tokens which have an instance of the object.
+ */
+NSS_EXTERN NSSToken **
+nssPKIObject_GetTokens
+(
+ nssPKIObject *object,
+ PRStatus *statusOpt
+);
+
+/* nssPKIObject_GetNicknameForToken
+ *
+ * tokenOpt == NULL means take the first available, otherwise return the
+ * nickname for the specified token.
+ */
+NSS_EXTERN NSSUTF8 *
+nssPKIObject_GetNicknameForToken
+(
+ nssPKIObject *object,
+ NSSToken *tokenOpt
+);
+
+/* nssPKIObject_RemoveInstanceForToken
+ *
+ * Remove the instance of the object on the specified token.
+ */
+NSS_EXTERN PRStatus
+nssPKIObject_RemoveInstanceForToken
+(
+ nssPKIObject *object,
+ NSSToken *token
+);
+
+/* nssPKIObject_DeleteStoredObject
+ *
+ * Delete all token instances of the object, as well as any crypto context
+ * instances (TODO). If any of the instances are read-only, or if the
+ * removal fails, the object will keep those instances. 'isFriendly' refers
+ * to the object -- can this object be removed from a friendly token without
+ * login? For example, certificates are friendly, private keys are not.
+ * Note that if the token is not friendly, authentication will be required
+ * regardless of the value of 'isFriendly'.
+ */
+NSS_EXTERN PRStatus
+nssPKIObject_DeleteStoredObject
+(
+ nssPKIObject *object,
+ NSSCallback *uhh,
+ PRBool isFriendly
+);
+
+#ifdef NSS_3_4_CODE
+NSS_EXTERN nssCryptokiObject **
+nssPKIObject_GetInstances
+(
+ nssPKIObject *object
+);
+#endif
+
+NSS_EXTERN NSSCertificate **
+nssTrustDomain_FindCertificatesByID
+(
+ NSSTrustDomain *td,
+ NSSItem *id,
+ NSSCertificate **rvOpt,
+ PRUint32 maximumOpt,
+ NSSArena *arenaOpt
+);
+
+NSS_EXTERN NSSCRL **
+nssTrustDomain_FindCRLsBySubject
+(
+ NSSTrustDomain *td,
+ NSSDER *subject
+);
+
+/* module-private nsspki methods */
+
+NSS_EXTERN NSSCryptoContext *
+nssCryptoContext_Create
+(
+ NSSTrustDomain *td,
+ NSSCallback *uhhOpt
+);
+
+/* XXX for the collection */
+NSS_EXTERN NSSCertificate *
+nssCertificate_Create
+(
+ nssPKIObject *object
+);
+
+NSS_EXTERN PRStatus
+nssCertificate_SetCertTrust
+(
+ NSSCertificate *c,
+ NSSTrust *trust
+);
+
+NSS_EXTERN nssDecodedCert *
+nssCertificate_GetDecoding
+(
+ NSSCertificate *c
+);
+
+NSS_EXTERN nssDecodedCert *
+nssDecodedCert_Create
(
NSSArena *arenaOpt,
- PRUint32 numBuckets
+ NSSDER *encoding,
+ NSSCertificateType type
+);
+
+NSS_EXTERN PRStatus
+nssDecodedCert_Destroy
+(
+ nssDecodedCert *dc
);
-/* Token ordering routines */
+NSS_EXTERN NSSTrust *
+nssTrust_Create
+(
+ nssPKIObject *object
+);
-/*
- * Given a crypto algorithm, return the preferred token for performing
- * the crypto operation.
+NSS_EXTERN NSSCRL *
+nssCRL_Create
+(
+ nssPKIObject *object
+);
+
+NSS_EXTERN NSSCRL *
+nssCRL_AddRef
+(
+ NSSCRL *crl
+);
+
+NSS_EXTERN PRStatus
+nssCRL_Destroy
+(
+ NSSCRL *crl
+);
+
+NSS_EXTERN PRStatus
+nssCRL_DeleteStoredObject
+(
+ NSSCRL *crl,
+ NSSCallback *uhh
+);
+
+NSS_EXTERN NSSPrivateKey *
+nssPrivateKey_Create
+(
+ nssPKIObject *o
+);
+
+NSS_EXTERN NSSDER *
+nssCRL_GetEncoding
+(
+ NSSCRL *crl
+);
+
+NSS_EXTERN NSSPublicKey *
+nssPublicKey_Create
+(
+ nssPKIObject *object
+);
+
+/* nssCertificateArray
+ *
+ * These are being thrown around a lot, might as well group together some
+ * functionality.
+ *
+ * nssCertificateArray_Destroy
+ * nssCertificateArray_Join
+ * nssCertificateArray_FindBestCertificate
+ * nssCertificateArray_Traverse
+ */
+
+/* nssCertificateArray_Destroy
+ *
+ * Will destroy the array and the certs within it. If the array was created
+ * in an arena, will *not* (of course) destroy the arena. However, is safe
+ * to call this method on an arena-allocated array.
+ */
+NSS_EXTERN void
+nssCertificateArray_Destroy
+(
+ NSSCertificate **certs
+);
+
+/* nssCertificateArray_Join
+ *
+ * Join two arrays into one. The two arrays, certs1 and certs2, should
+ * be considered invalid after a call to this function (they may be destroyed
+ * as part of the join). certs1 and/or certs2 may be NULL. Safe to
+ * call with arrays allocated in an arena, the result will also be in the
+ * arena.
+ */
+NSS_EXTERN NSSCertificate **
+nssCertificateArray_Join
+(
+ NSSCertificate **certs1,
+ NSSCertificate **certs2
+);
+
+/* nssCertificateArray_FindBestCertificate
+ *
+ * Use the usual { time, usage, policies } to find the best cert in the
+ * array.
+ */
+NSS_EXTERN NSSCertificate *
+nssCertificateArray_FindBestCertificate
+(
+ NSSCertificate **certs,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt
+);
+
+/* nssCertificateArray_Traverse
+ *
+ * Do the callback for each cert, terminate the traversal if the callback
+ * fails.
*/
-NSS_EXTERN NSSToken *
-nssTrustDomain_GetCryptoToken
+NSS_EXTERN PRStatus
+nssCertificateArray_Traverse
+(
+ NSSCertificate **certs,
+ PRStatus (* callback)(NSSCertificate *c, void *arg),
+ void *arg
+);
+
+NSS_EXTERN void
+nssCRLArray_Destroy
+(
+ NSSCRL **crls
+);
+
+/* nssPKIObjectCollection
+ *
+ * This is a handy way to group objects together and perform operations
+ * on them. It can also handle "proto-objects"-- references to
+ * objects instances on tokens, where the actual object hasn't
+ * been formed yet.
+ *
+ * nssCertificateCollection_Create
+ * nssPrivateKeyCollection_Create
+ * nssPublicKeyCollection_Create
+ *
+ * If this was a language that provided for inheritance, each type would
+ * inherit all of the following methods. Instead, there is only one
+ * type (nssPKIObjectCollection), shared among all. This may cause
+ * confusion; an alternative would be to define all of the methods
+ * for each subtype (nssCertificateCollection_Destroy, ...), but that doesn't
+ * seem worth the code bloat.. It is left up to the caller to remember
+ * what type of collection he/she is dealing with.
+ *
+ * nssPKIObjectCollection_Destroy
+ * nssPKIObjectCollection_Count
+ * nssPKIObjectCollection_AddObject
+ * nssPKIObjectCollection_AddInstances
+ * nssPKIObjectCollection_Traverse
+ *
+ * Back to type-specific methods.
+ *
+ * nssPKIObjectCollection_GetCertificates
+ * nssPKIObjectCollection_GetCRLs
+ * nssPKIObjectCollection_GetPrivateKeys
+ * nssPKIObjectCollection_GetPublicKeys
+ */
+
+/* nssCertificateCollection_Create
+ *
+ * Create a collection of certificates in the specified trust domain.
+ * Optionally provide a starting set of certs.
+ */
+NSS_EXTERN nssPKIObjectCollection *
+nssCertificateCollection_Create
(
NSSTrustDomain *td,
- NSSAlgorithmAndParameters *ap
+ NSSCertificate **certsOpt
);
-/* The following routines are used to obtain the preferred token on which
- * to store particular objects.
+/* 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
+);
-/*
- * Find the preferred token for storing user certificates.
+/* nssPrivateKeyCollection_Create
+ *
+ * Create a collection of private keys in the specified trust domain.
+ * Optionally provide a starting set of keys.
*/
-NSS_EXTERN NSSToken *
-nssTrustDomain_GetUserCertToken
+NSS_EXTERN nssPKIObjectCollection *
+nssPrivateKeyCollection_Create
(
- NSSTrustDomain *td
+ NSSTrustDomain *td,
+ NSSPrivateKey **pvkOpt
);
-/*
- * Find the preferred token for storing email certificates.
+/* nssPublicKeyCollection_Create
+ *
+ * Create a collection of public keys in the specified trust domain.
+ * Optionally provide a starting set of keys.
*/
-NSS_EXTERN NSSToken *
-nssTrustDomain_GetEmailCertToken
+NSS_EXTERN nssPKIObjectCollection *
+nssPublicKeyCollection_Create
(
- NSSTrustDomain *td
+ NSSTrustDomain *td,
+ NSSPublicKey **pvkOpt
);
-/*
- * Find the preferred token for storing SSL certificates.
+/* nssPKIObjectCollection_Destroy
*/
-NSS_EXTERN NSSToken *
-nssTrustDomain_GetSSLCertToken
+NSS_EXTERN void
+nssPKIObjectCollection_Destroy
(
- NSSTrustDomain *td
+ nssPKIObjectCollection *collection
);
-/*
- * Find the preferred token for storing root certificates.
+/* nssPKIObjectCollection_Count
*/
-NSS_EXTERN NSSToken *
-nssTrustDomain_GetRootCertToken
+NSS_EXTERN PRUint32
+nssPKIObjectCollection_Count
(
- NSSTrustDomain *td
+ nssPKIObjectCollection *collection
);
-/*
- * Find the preferred token for storing private keys.
+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 NSSToken *
-nssTrustDomain_GetPrivateKeyToken
+NSS_EXTERN PRStatus
+nssPKIObjectCollection_AddInstances
(
- NSSTrustDomain *td
+ nssPKIObjectCollection *collection,
+ nssCryptokiObject **instances,
+ PRUint32 numInstances
);
-/*
- * Find the preferred token for storing symmetric keys.
+/* nssPKIObjectCollection_Traverse
*/
-NSS_EXTERN NSSToken *
-nssTrustDomain_GetSymmetricKeyToken
+NSS_EXTERN PRStatus
+nssPKIObjectCollection_Traverse
(
- NSSTrustDomain *td
+ nssPKIObjectCollection *collection,
+ nssPKIObjectCallback *callback
);
-/* Certificate cache routines */
+/* This function is being added for NSS 3.5. It corresponds to the function
+ * nssToken_TraverseCertificates. The idea is to use the collection during
+ * a traversal, creating certs each time a new instance is added for which
+ * a cert does not already exist.
+ */
+NSS_EXTERN PRStatus
+nssPKIObjectCollection_AddInstanceAsObject
+(
+ nssPKIObjectCollection *collection,
+ nssCryptokiObject *instance
+);
+
+/* nssPKIObjectCollection_GetCertificates
+ *
+ * Get all of the certificates in the collection.
+ */
+NSS_EXTERN NSSCertificate **
+nssPKIObjectCollection_GetCertificates
+(
+ nssPKIObjectCollection *collection,
+ NSSCertificate **rvOpt,
+ PRUint32 maximumOpt,
+ NSSArena *arenaOpt
+);
+
+NSS_EXTERN NSSCRL **
+nssPKIObjectCollection_GetCRLs
+(
+ nssPKIObjectCollection *collection,
+ NSSCRL **rvOpt,
+ PRUint32 maximumOpt,
+ NSSArena *arenaOpt
+);
+
+NSS_EXTERN NSSPrivateKey **
+nssPKIObjectCollection_GetPrivateKeys
+(
+ nssPKIObjectCollection *collection,
+ NSSPrivateKey **rvOpt,
+ PRUint32 maximumOpt,
+ NSSArena *arenaOpt
+);
+
+NSS_EXTERN NSSPublicKey **
+nssPKIObjectCollection_GetPublicKeys
+(
+ nssPKIObjectCollection *collection,
+ NSSPublicKey **rvOpt,
+ PRUint32 maximumOpt,
+ NSSArena *arenaOpt
+);
+
+NSS_EXTERN NSSTime *
+NSSTime_Now
+(
+ NSSTime *timeOpt
+);
+
+NSS_EXTERN NSSTime *
+NSSTime_SetPRTime
+(
+ NSSTime *timeOpt,
+ PRTime prTime
+);
+
+NSS_EXTERN PRTime
+NSSTime_GetPRTime
+(
+ NSSTime *time
+);
+
+NSS_EXTERN nssHash *
+nssHash_CreateCertificate
+(
+ NSSArena *arenaOpt,
+ PRUint32 numBuckets
+);
+
+/* 3.4 Certificate cache routines */
+
+NSS_EXTERN PRStatus
+nssTrustDomain_InitializeCache
+(
+ NSSTrustDomain *td,
+ PRUint32 cacheSize
+);
NSS_EXTERN PRStatus
nssTrustDomain_AddCertsToCache
@@ -173,6 +622,13 @@ nssTrustDomain_RemoveTokenCertsFromCache
NSSToken *token
);
+NSS_EXTERN PRStatus
+nssTrustDomain_UpdateCachedTokenCerts
+(
+ NSSTrustDomain *td,
+ NSSToken *token
+);
+
/*
* Find all cached certs with this nickname (label).
*/
@@ -238,54 +694,11 @@ nssTrustDomain_GetCertsFromCache
nssList *certListOpt
);
-NSS_EXTERN PRStatus
-nssCertificate_SetCertTrust
-(
- NSSCertificate *c,
- NSSTrust *trust
-);
-
-NSS_EXTERN nssDecodedCert *
-nssCertificate_GetDecoding
-(
- NSSCertificate *c
-);
-
-NSS_EXTERN nssDecodedCert *
-nssDecodedCert_Create
-(
- NSSArena *arenaOpt,
- NSSDER *encoding,
- NSSCertificateType type
-);
-
-NSS_EXTERN PRStatus
-nssDecodedCert_Destroy
-(
- nssDecodedCert *dc
-);
-
-NSS_EXTERN void
-nssBestCertificate_SetArgs
-(
- nssBestCertificateCB *best,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policies
-);
-
-NSS_EXTERN PRStatus
-nssBestCertificate_Callback
-(
- NSSCertificate *c,
- void *arg
-);
-
-NSS_EXTERN PRStatus
-nssCertificateList_DoCallback
+NSS_EXTERN void
+nssTrustDomain_DumpCacheInfo
(
- nssList *certList,
- PRStatus (* callback)(NSSCertificate *c, void *arg),
+ NSSTrustDomain *td,
+ void (* cert_dump_iter)(const void *, void *, void *),
void *arg
);
@@ -295,54 +708,6 @@ nssCertificateList_AddReferences
nssList *certList
);
-NSS_EXTERN PRStatus
-nssPKIObject_Initialize
-(
- struct nssPKIObjectBaseStr *object,
- NSSArena *arena,
- NSSTrustDomain *td,
- NSSCryptoContext *cc
-);
-
-NSS_EXTERN void
-nssPKIObject_AddRef
-(
- struct nssPKIObjectBaseStr *object
-);
-
-NSS_EXTERN PRBool
-nssPKIObject_Destroy
-(
- struct nssPKIObjectBaseStr *object
-);
-
-NSS_EXTERN NSSTime *
-NSSTime_Now
-(
- NSSTime *timeOpt
-);
-
-NSS_EXTERN NSSTime *
-NSSTime_SetPRTime
-(
- NSSTime *timeOpt,
- PRTime prTime
-);
-
-NSS_EXTERN PRTime
-NSSTime_GetPRTime
-(
- NSSTime *time
-);
-
-NSS_EXTERN void
-nssTrustDomain_DumpCacheInfo
-(
- NSSTrustDomain *td,
- void (* cert_dump_iter)(const void *, void *, void *),
- void *arg
-);
-
PR_END_EXTERN_C
#endif /* PKIM_H */
diff --git a/security/nss/lib/pki/pkistore.c b/security/nss/lib/pki/pkistore.c
index 0b1463fcb..a045b0a68 100644
--- a/security/nss/lib/pki/pkistore.c
+++ b/security/nss/lib/pki/pkistore.c
@@ -435,8 +435,8 @@ static void match_nickname(const void *k, void *v, void *a)
nssList *subjectList = (nssList *)v;
struct nickname_template_str *nt = (struct nickname_template_str *)a;
nssrv = nssList_GetArray(subjectList, (void **)&c, 1);
- nickname = NSSCertificate_GetNickname(c, NULL);
- if (nssrv == PR_SUCCESS &&
+ nickname = nssCertificate_GetNickname(c, NULL);
+ if (nssrv == PR_SUCCESS && nickname &&
nssUTF8_Equal(nickname, nt->nickname, &nssrv))
{
nt->subjectList = subjectList;
diff --git a/security/nss/lib/pki/pkit.h b/security/nss/lib/pki/pkit.h
index 1e0f98a4f..f8bd067b9 100644
--- a/security/nss/lib/pki/pkit.h
+++ b/security/nss/lib/pki/pkit.h
@@ -71,13 +71,6 @@ static const char PKIT_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
PR_BEGIN_EXTERN_C
-typedef struct nssDecodedCertStr nssDecodedCert;
-
-typedef struct nssCertificateStoreStr nssCertificateStore;
-
-/* How wide is the scope of this? */
-typedef struct nssSMIMEProfileStr nssSMIMEProfile;
-
/*
* A note on ephemeral certs
*
@@ -93,17 +86,25 @@ typedef struct nssSMIMEProfileStr nssSMIMEProfile;
* for each object.
*/
-/* The common data from which all objects inherit */
-struct nssPKIObjectBaseStr
+/* nssPKIObject
+ *
+ * This is the base object class, common to all PKI objects defined in
+ * nsspkit.h
+ */
+struct nssPKIObjectStr
{
/* The arena for all object memory */
NSSArena *arena;
- /* Thread-safe reference counting */
- PZLock *lock;
+ /* Atomically incremented/decremented reference counting */
PRInt32 refCount;
- /* List of nssCryptokiInstance's of the object */
- nssList *instanceList;
- nssListIterator *instances;
+ /* 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?
+ */
+ nssCryptokiObject **instances;
+ PRUint32 numInstances;
/* The object must live in a trust domain */
NSSTrustDomain *trustDomain;
/* The object may live in a crypto context */
@@ -112,9 +113,18 @@ struct nssPKIObjectBaseStr
NSSUTF8 *tempName;
};
+typedef struct nssDecodedCertStr nssDecodedCert;
+
+typedef struct nssCertificateStoreStr nssCertificateStore;
+
+/* How wide is the scope of this? */
+typedef struct nssSMIMEProfileStr nssSMIMEProfile;
+
+typedef struct nssPKIObjectStr nssPKIObject;
+
struct NSSTrustStr
{
- struct nssPKIObjectBaseStr object;
+ nssPKIObject object;
NSSCertificate *certificate;
nssTrustLevel serverAuth;
nssTrustLevel clientAuth;
@@ -124,7 +134,7 @@ struct NSSTrustStr
struct nssSMIMEProfileStr
{
- struct nssPKIObjectBaseStr object;
+ nssPKIObject object;
NSSCertificate *certificate;
NSSASCII7 *email;
NSSDER *subject;
@@ -134,7 +144,7 @@ struct nssSMIMEProfileStr
struct NSSCertificateStr
{
- struct nssPKIObjectBaseStr object;
+ nssPKIObject object;
NSSCertificateType type;
NSSItem id;
NSSBER encoding;
@@ -156,7 +166,7 @@ typedef struct nssTDCertificateCacheStr nssTDCertificateCache;
struct NSSTrustDomainStr {
PRInt32 refCount;
NSSArena *arena;
- NSSCallback defaultCallback;
+ NSSCallback *defaultCallback;
nssList *tokenList;
nssListIterator *tokens;
nssTDCertificateCache *cache;
@@ -180,6 +190,15 @@ struct NSSTimeStr {
PRTime prTime;
};
+struct NSSCRLStr {
+ nssPKIObject object;
+ NSSDER encoding;
+ NSSUTF8 *url;
+ PRBool isKRL;
+};
+
+typedef struct NSSCRLStr NSSCRL;
+
struct NSSPoliciesStr;
struct NSSAlgorithmAndParametersStr;
diff --git a/security/nss/lib/pki/pkitm.h b/security/nss/lib/pki/pkitm.h
index a943fd834..d163923e6 100644
--- a/security/nss/lib/pki/pkitm.h
+++ b/security/nss/lib/pki/pkitm.h
@@ -104,6 +104,19 @@ struct nssBestCertificateCBStr {
NSSPolicies *policies;
};
+typedef struct nssPKIObjectCollectionStr nssPKIObjectCollection;
+
+typedef struct
+{
+ union {
+ PRStatus (* cert)(NSSCertificate *c, void *arg);
+ PRStatus (* crl)(NSSCRL *crl, void *arg);
+ PRStatus (* pvkey)(NSSPrivateKey *vk, void *arg);
+ PRStatus (* pbkey)(NSSPublicKey *bk, void *arg);
+ } func;
+ void *arg;
+} nssPKIObjectCallback;
+
PR_END_EXTERN_C
#endif /* PKITM_H */
diff --git a/security/nss/lib/pki/tdcache.c b/security/nss/lib/pki/tdcache.c
index e34c6403a..0adc08e06 100644
--- a/security/nss/lib/pki/tdcache.c
+++ b/security/nss/lib/pki/tdcache.c
@@ -61,6 +61,8 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#ifdef NSS_3_4_CODE
#include "cert.h"
+#include "dev.h"
+#include "pki3hack.h"
#endif
#ifdef DEBUG_CACHE
@@ -124,6 +126,7 @@ struct cache_entry_str
PRUint32 hits;
PRTime lastHit;
NSSArena *arena;
+ NSSUTF8 *nickname;
};
typedef struct cache_entry_str cache_entry;
@@ -139,6 +142,7 @@ new_cache_entry(NSSArena *arena, void *value, PRBool ownArena)
if (ownArena) {
ce->arena = arena;
}
+ ce->nickname = NULL;
}
return ce;
}
@@ -274,6 +278,7 @@ remove_subject_entry
nssTDCertificateCache *cache,
NSSCertificate *cert,
nssList **subjectList,
+ NSSUTF8 **nickname,
NSSArena **arena
)
{
@@ -287,6 +292,7 @@ remove_subject_entry
/* Remove the cert from the subject hash */
nssList_Remove(ce->entry.list, cert);
*subjectList = ce->entry.list;
+ *nickname = ce->nickname;
*arena = ce->arena;
nssrv = PR_SUCCESS;
#ifdef DEBUG_CACHE
@@ -303,12 +309,11 @@ static PRStatus
remove_nickname_entry
(
nssTDCertificateCache *cache,
- NSSCertificate *cert,
+ NSSUTF8 *nickname,
nssList *subjectList
)
{
PRStatus nssrv;
- NSSUTF8 *nickname = NSSCertificate_GetNickname(cert, NULL);
if (nickname) {
nssHash_Remove(cache->nickname, nickname);
nssrv = PR_SUCCESS;
@@ -373,6 +378,8 @@ nssTrustDomain_RemoveCertFromCache
PRStatus nssrv;
cache_entry *ce;
NSSArena *arena;
+ NSSUTF8 *nickname;
+
#ifdef DEBUG_CACHE
log_cert_ref("attempt to remove cert", cert);
#endif
@@ -392,13 +399,14 @@ nssTrustDomain_RemoveCertFromCache
if (nssrv != PR_SUCCESS) {
goto loser;
}
- nssrv = remove_subject_entry(td->cache, cert, &subjectList, &arena);
+ nssrv = remove_subject_entry(td->cache, cert, &subjectList,
+ &nickname, &arena);
if (nssrv != PR_SUCCESS) {
goto loser;
}
if (nssList_Count(subjectList) == 0) {
PRStatus nssrv2;
- nssrv = remove_nickname_entry(td->cache, cert, subjectList);
+ nssrv = remove_nickname_entry(td->cache, nickname, subjectList);
nssrv2 = remove_email_entry(td->cache, cert, subjectList);
#ifndef NSS_3_4_CODE
/* XXX Again, 3.4 allows for certs w/o either nickname or email */
@@ -441,23 +449,39 @@ nssTrustDomain_FlushCache
{
}
-struct token_cert_destructor {
- nssTDCertificateCache *cache;
+struct token_cert_dtor {
NSSToken *token;
+ nssTDCertificateCache *cache;
+ NSSCertificate **certs;
+ PRUint32 numCerts, arrSize;
};
static void
remove_token_certs(const void *k, void *v, void *a)
{
-#if 0
- struct NSSItem *identifier = (struct NSSItem *)k;
- NSSCertificate *c = (NSSCertificate *)v;
- struct token_cert_destructor *tcd = (struct token_cert_destructor *)a;
- if (c->token == tcd->token) {
- nssHash_Remove(tcd->cache->issuerAndSN, identifier);
- /* remove from the other hashes */
+ NSSCertificate *c = (NSSCertificate *)k;
+ nssPKIObject *object = &c->object;
+ struct token_cert_dtor *dtor = a;
+ PRUint32 i;
+ PZ_Lock(object->lock);
+ for (i=0; i<object->numInstances; i++) {
+ if (object->instances[i]->token == dtor->token) {
+ nssCryptokiObject_Destroy(object->instances[i]);
+ object->instances[i] = object->instances[object->numInstances-1];
+ object->instances[object->numInstances-1] = NULL;
+ object->numInstances--;
+ dtor->certs[dtor->numCerts++] = nssCertificate_AddRef(c);
+ if (dtor->numCerts == dtor->arrSize) {
+ dtor->arrSize *= 2;
+ dtor->certs = nss_ZREALLOCARRAY(dtor->certs,
+ NSSCertificate *,
+ dtor->arrSize);
+ }
+ break;
+ }
}
-#endif
+ PZ_Unlock(object->lock);
+ return;
}
/*
@@ -471,12 +495,72 @@ nssTrustDomain_RemoveTokenCertsFromCache
NSSToken *token
)
{
- struct token_cert_destructor tcd;
- tcd.cache = td->cache;
- tcd.token = token;
+ NSSCertificate **certs;
+ PRUint32 i, arrSize = 10;
+ struct token_cert_dtor dtor;
+ certs = nss_ZNEWARRAY(NULL, NSSCertificate *, arrSize);
+ if (!certs) {
+ return PR_FAILURE;
+ }
+ dtor.cache = td->cache;
+ dtor.token = token;
+ dtor.certs = certs;
+ dtor.numCerts = 0;
+ dtor.arrSize = arrSize;
PZ_Lock(td->cache->lock);
- nssHash_Iterate(td->cache->issuerAndSN, remove_token_certs, (void *)&tcd);
+ nssHash_Iterate(td->cache->issuerAndSN, remove_token_certs, (void *)&dtor);
PZ_Unlock(td->cache->lock);
+ for (i=0; i<dtor.numCerts; i++) {
+ if (dtor.certs[i]->object.numInstances == 0) {
+ nssTrustDomain_RemoveCertFromCache(td, dtor.certs[i]);
+ } else {
+ STAN_ForceCERTCertificateUpdate(dtor.certs[i]);
+ }
+ nssCertificate_Destroy(dtor.certs[i]);
+ }
+ nss_ZFreeIf(dtor.certs);
+ return PR_SUCCESS;
+}
+
+NSS_IMPLEMENT PRStatus
+nssTrustDomain_UpdateCachedTokenCerts
+(
+ NSSTrustDomain *td,
+ NSSToken *token
+)
+{
+ NSSCertificate **cp, **cached = NULL;
+ nssList *certList;
+ PRUint32 count;
+ certList = nssList_Create(NULL, PR_FALSE);
+ if (!certList) return PR_FAILURE;
+ (void *)nssTrustDomain_GetCertsFromCache(td, certList);
+ count = nssList_Count(certList);
+ if (count > 0) {
+ cached = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1);
+ if (!cached) {
+ return PR_FAILURE;
+ }
+ nssList_GetArray(certList, (void **)cached, count);
+ nssList_Destroy(certList);
+ for (cp = cached; *cp; cp++) {
+ nssCryptokiObject *instance;
+ NSSCertificate *c = *cp;
+ nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
+ instance = nssToken_FindCertificateByIssuerAndSerialNumber(
+ token,
+ NULL,
+ &c->issuer,
+ &c->serial,
+ tokenOnly,
+ NULL);
+ if (instance) {
+ nssPKIObject_AddInstance(&c->object, instance);
+ STAN_ForceCERTCertificateUpdate(c);
+ }
+ }
+ nssCertificateArray_Destroy(cached);
+ }
return PR_SUCCESS;
}
@@ -502,6 +586,7 @@ add_subject_entry
NSSArena *arena,
nssTDCertificateCache *cache,
NSSCertificate *cert,
+ NSSUTF8 *nickname,
nssList **subjectList
)
{
@@ -529,6 +614,9 @@ add_subject_entry
if (!ce) {
return PR_FAILURE;
}
+ if (nickname) {
+ ce->nickname = nssUTF8_Duplicate(nickname, arena);
+ }
nssList_SetSortFunction(list, subject_list_sort);
/* Add the cert entry to this list of subjects */
nssrv = nssList_AddUnique(list, cert);
@@ -557,12 +645,11 @@ add_nickname_entry
(
NSSArena *arena,
nssTDCertificateCache *cache,
- NSSCertificate *cert,
+ NSSUTF8 *certNickname,
nssList *subjectList
)
{
PRStatus nssrv = PR_SUCCESS;
- NSSUTF8 *certNickname = NSSCertificate_GetNickname(cert, NULL);
cache_entry *ce;
ce = (cache_entry *)nssHash_Lookup(cache->nickname, certNickname);
if (ce) {
@@ -654,7 +741,7 @@ add_email_entry
extern const NSSError NSS_ERROR_CERTIFICATE_IN_CACHE;
-static PRStatus
+static NSSCertificate *
add_cert_to_cache
(
NSSTrustDomain *td,
@@ -662,21 +749,29 @@ add_cert_to_cache
)
{
NSSArena *arena = NULL;
- nssList *subjectList;
+ nssList *subjectList = NULL;
PRStatus nssrv;
PRUint32 added = 0;
+ cache_entry *ce;
+ NSSCertificate *rvCert = NULL;
+ NSSUTF8 *certNickname = nssCertificate_GetNickname(cert, NULL);
+
PZ_Lock(td->cache->lock);
/* If it exists in the issuer/serial hash, it's already in all */
- if (nssHash_Exists(td->cache->issuerAndSN, cert)) {
+ ce = (cache_entry *)nssHash_Lookup(td->cache->issuerAndSN, cert);
+ if (ce) {
+ ce->hits++;
+ ce->lastHit = PR_Now();
+ rvCert = nssCertificate_AddRef(ce->entry.cert);
#ifdef DEBUG_CACHE
log_cert_ref("attempted to add cert already in cache", cert);
#endif
PZ_Unlock(td->cache->lock);
- /* collision - most likely, somebody else already added the cert
+ /* collision - somebody else already added the cert
* to the cache before this thread got around to it.
*/
- nss_SetError(NSS_ERROR_CERTIFICATE_IN_CACHE);
- return PR_FAILURE;
+ nssCertificate_Destroy(cert);
+ return rvCert;
}
/* create a new cache entry for this cert within the cert's arena*/
nssrv = add_issuer_and_serial_entry(cert->object.arena, td->cache, cert);
@@ -690,7 +785,8 @@ add_cert_to_cache
goto loser;
}
/* create a new subject list for this cert, or add to existing */
- nssrv = add_subject_entry(arena, td->cache, cert, &subjectList);
+ nssrv = add_subject_entry(arena, td->cache, cert,
+ certNickname, &subjectList);
if (nssrv != PR_SUCCESS) {
goto loser;
}
@@ -698,9 +794,9 @@ add_cert_to_cache
/* If a new subject entry was created, also need nickname and/or email */
if (subjectList != NULL) {
PRBool handle = PR_FALSE;
- NSSUTF8 *certNickname = NSSCertificate_GetNickname(cert, NULL);
if (certNickname) {
- nssrv = add_nickname_entry(arena, td->cache, cert, subjectList);
+ nssrv = add_nickname_entry(arena, td->cache,
+ certNickname, subjectList);
if (nssrv != PR_SUCCESS) {
goto loser;
}
@@ -727,9 +823,9 @@ add_cert_to_cache
}
#endif
}
- nssCertificate_AddRef(cert);
+ rvCert = nssCertificate_AddRef(cert);
PZ_Unlock(td->cache->lock);
- return nssrv;
+ return rvCert;
loser:
/* Remove any handles that have been created */
subjectList = NULL;
@@ -737,10 +833,11 @@ loser:
(void)remove_issuer_and_serial_entry(td->cache, cert);
}
if (added >= 2) {
- (void)remove_subject_entry(td->cache, cert, &subjectList, &arena);
+ (void)remove_subject_entry(td->cache, cert, &subjectList,
+ &certNickname, &arena);
}
if (added == 3 || added == 5) {
- (void)remove_nickname_entry(td->cache, cert, subjectList);
+ (void)remove_nickname_entry(td->cache, certNickname, subjectList);
}
if (added >= 4) {
(void)remove_email_entry(td->cache, cert, subjectList);
@@ -753,7 +850,7 @@ loser:
nssArena_Destroy(arena);
}
PZ_Unlock(td->cache->lock);
- return PR_FAILURE;
+ return NULL;
}
NSS_IMPLEMENT PRStatus
@@ -765,32 +862,14 @@ nssTrustDomain_AddCertsToCache
)
{
PRUint32 i;
- NSSError e;
+ NSSCertificate *c;
for (i=0; i<numCerts && certs[i]; i++) {
- if (add_cert_to_cache(td, certs[i]) != PR_SUCCESS) {
- if ((e = NSS_GetError()) == NSS_ERROR_CERTIFICATE_IN_CACHE) {
- /* collision - delete and replace the cert here in favor
- * of the already cached entry. This is safe as long as
- * the cert being added here only has a single reference.
- * This should be the case as this function is only called
- * immediately following a traversal and before any certs
- * are returned to the caller.
- */
- NSSCertificate *c;
- c = nssTrustDomain_GetCertForIssuerAndSNFromCache(td,
- &certs[i]->issuer,
- &certs[i]->serial);
- if (c != certs[i]) {
- NSSCertificate_Destroy(certs[i]);
- certs[i] = c;
- } else {
- NSSCertificate_Destroy(c);
- }
- nss_ClearErrorStack();
- continue;
- }
+ c = add_cert_to_cache(td, certs[i]);
+ if (c == NULL) {
return PR_FAILURE;
- }
+ } else {
+ certs[i] = c;
+ }
}
return PR_SUCCESS;
}
diff --git a/security/nss/lib/pki/trustdomain.c b/security/nss/lib/pki/trustdomain.c
index f3ebc5125..c5e3dc337 100644
--- a/security/nss/lib/pki/trustdomain.c
+++ b/security/nss/lib/pki/trustdomain.c
@@ -35,41 +35,42 @@
static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#endif /* DEBUG */
-#ifndef NSSPKI_H
-#include "nsspki.h"
-#endif /* NSSPKI_H */
-
-#ifndef PKI_H
-#include "pki.h"
-#endif /* PKI_H */
+#ifndef DEV_H
+#include "dev.h"
+#endif /* DEV_H */
#ifndef PKIM_H
#include "pkim.h"
#endif /* PKIM_H */
-#ifndef DEV_H
-#include "dev.h"
-#endif /* DEV_H */
-
-#ifndef CKHELPER_H
-#include "ckhelper.h"
-#endif /* CKHELPER_H */
+#ifndef PKI1T_H
+#include "pki1t.h"
+#endif /* PKI1T_H */
#ifdef NSS_3_4_CODE
#include "cert.h"
#include "pki3hack.h"
#endif
-extern const NSSError NSS_ERROR_NOT_FOUND;
-
#define NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE 32
-NSS_EXTERN PRStatus
-nssTrustDomain_InitializeCache
-(
- NSSTrustDomain *td,
- PRUint32 cacheSize
-);
+#ifdef PURE_STAN_BUILD
+struct NSSTrustDomainStr {
+ PRInt32 refCount;
+ NSSArena *arena;
+ NSSCallback *defaultCallback;
+ struct {
+ nssSlotList *forCerts;
+ nssSlotList *forCiphers;
+ nssSlotList *forTrust;
+ } slots;
+ nssCertificateCache *cache;
+};
+#endif
+
+extern const NSSError NSS_ERROR_NOT_FOUND;
+
+typedef PRUint32 nssUpdateLevel;
NSS_IMPLEMENT NSSTrustDomain *
NSSTrustDomain_Create
@@ -90,9 +91,9 @@ NSSTrustDomain_Create
if (!rvTD) {
goto loser;
}
+ nssTrustDomain_InitializeCache(rvTD, NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE);
rvTD->arena = arena;
rvTD->refCount = 1;
- nssTrustDomain_InitializeCache(rvTD, NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE);
#ifdef NSS_3_4_CODE
rvTD->statusConfig = NULL;
#endif
@@ -106,13 +107,9 @@ static void
token_destructor(void *t)
{
NSSToken *tok = (NSSToken *)t;
-#ifdef NSS_3_4_CODE
/* in 3.4, also destroy the slot (managed separately) */
(void)nssSlot_Destroy(tok->slot);
- STAN_DestroyNSSToken(tok);
-#else
- (void)nssToken_Destroy(tok);
-#endif
+ nssToken_Destroy(tok);
}
NSS_IMPLEMENT PRStatus
@@ -135,6 +132,48 @@ NSSTrustDomain_Destroy
return PR_SUCCESS;
}
+/* XXX uses tokens until slot list is in place */
+static NSSSlot **
+nssTrustDomain_GetActiveSlots
+(
+ NSSTrustDomain *td,
+ nssUpdateLevel *updateLevel
+)
+{
+ PRUint32 count;
+ NSSSlot **slots = NULL;
+ NSSToken **tp, **tokens;
+ *updateLevel = 1;
+ count = nssList_Count(td->tokenList);
+ tokens = nss_ZNEWARRAY(NULL, NSSToken *, count + 1);
+ if (!tokens) {
+ return NULL;
+ }
+ slots = nss_ZNEWARRAY(NULL, NSSSlot *, count + 1);
+ if (!slots) {
+ nss_ZFreeIf(tokens);
+ return NULL;
+ }
+ nssList_GetArray(td->tokenList, (void **)tokens, count);
+ count = 0;
+ for (tp = tokens; *tp; tp++) {
+ slots[count++] = nssToken_GetSlot(*tp);
+ }
+ nss_ZFreeIf(tokens);
+ return slots;
+}
+
+/* XXX */
+static nssSession *
+nssTrustDomain_GetSessionForToken
+(
+ NSSTrustDomain *td,
+ NSSToken *token
+)
+{
+ return nssToken_GetDefaultSession(token);
+}
+
NSS_IMPLEMENT PRStatus
NSSTrustDomain_SetDefaultCallback
(
@@ -143,8 +182,24 @@ NSSTrustDomain_SetDefaultCallback
NSSCallback **oldCallbackOpt
)
{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
+ if (oldCallbackOpt) {
+ *oldCallbackOpt = td->defaultCallback;
+ }
+ td->defaultCallback = newCallback;
+ return PR_SUCCESS;
+}
+
+NSS_IMPLEMENT NSSCallback *
+nssTrustDomain_GetDefaultCallback
+(
+ NSSTrustDomain *td,
+ PRStatus *statusOpt
+)
+{
+ if (statusOpt) {
+ *statusOpt = PR_SUCCESS;
+ }
+ return td->defaultCallback;
}
NSS_IMPLEMENT NSSCallback *
@@ -154,8 +209,7 @@ NSSTrustDomain_GetDefaultCallback
PRStatus *statusOpt
)
{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
+ return nssTrustDomain_GetDefaultCallback(td, statusOpt);
}
NSS_IMPLEMENT PRStatus
@@ -231,8 +285,10 @@ NSSTrustDomain_FindTokenByName
tok != (NSSToken *)NULL;
tok = (NSSToken *)nssListIterator_Next(td->tokens))
{
- myName = nssToken_GetName(tok);
- if (nssUTF8_Equal(tokenName, myName, &nssrv)) break;
+ if (nssToken_IsPresent(tok)) {
+ myName = nssToken_GetName(tok);
+ if (nssUTF8_Equal(tokenName, myName, &nssrv)) break;
+ }
}
nssListIterator_Finish(td->tokens);
return tok;
@@ -366,83 +422,115 @@ NSSTrustDomain_ImportEncodedPublicKey
return NULL;
}
-static void cert_destructor(void *el)
+static NSSCertificate **
+get_certs_from_list(nssList *list)
{
- NSSCertificate *c = (NSSCertificate *)el;
- NSSCertificate_Destroy(c);
-}
-
-struct collect_arg_str {
- nssList *list;
- PRUint32 maximum;
-};
-
-extern const NSSError NSS_ERROR_MAXIMUM_FOUND;
-
-static PRStatus
-collect_certs(NSSCertificate *c, void *arg)
-{
- struct collect_arg_str *ca = (struct collect_arg_str *)arg;
- /* Add the cert to the return list if not present */
- if (!nssList_Get(ca->list, (void *)c)) {
- nssCertificate_AddRef(c);
- nssList_Add(ca->list, (void *)c);
- }
- if (ca->maximum > 0 && nssList_Count(ca->list) >= ca->maximum) {
- /* signal the end of collection) */
- nss_SetError(NSS_ERROR_MAXIMUM_FOUND);
- return PR_FAILURE;
+ PRUint32 count = nssList_Count(list);
+ NSSCertificate **certs = NULL;
+ if (count > 0) {
+ certs = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1);
+ if (certs) {
+ nssList_GetArray(list, (void **)certs, count);
+ }
}
- return PR_SUCCESS;
+ return certs;
}
-NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_FindBestCertificateByNickname
+NSS_IMPLEMENT NSSCertificate **
+nssTrustDomain_FindCertificatesByNickname
(
NSSTrustDomain *td,
NSSUTF8 *name,
- NSSTime *timeOpt, /* NULL for "now" */
- NSSUsage *usage,
- NSSPolicies *policiesOpt /* NULL for none */
+ NSSCertificate *rvOpt[],
+ PRUint32 maximumOpt, /* 0 for no max */
+ NSSArena *arenaOpt
)
{
- PRStatus nssrv;
- NSSToken *token;
- nssTokenCertSearch search;
- nssBestCertificateCB best;
+ PRStatus status;
+ PRUint32 numRemaining;
+ NSSToken *token = NULL;
+ NSSSlot **slots = NULL;
+ NSSSlot **slotp;
+ NSSCertificate **rvCerts = NULL;
+ nssPKIObjectCollection *collection = NULL;
+ nssUpdateLevel updateLevel;
nssList *nameList;
- PRBool notPresent;
- /* set the criteria for determining the best cert */
- nssBestCertificate_SetArgs(&best, timeOpt, usage, policiesOpt);
- /* find all matching certs in the cache */
+ /* First, grab from the cache */
nameList = nssList_Create(NULL, PR_FALSE);
+ if (!nameList) {
+ return NULL;
+ }
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nameList);
- /* set the search criteria */
- search.callback = nssBestCertificate_Callback;
- search.cbarg = &best;
- search.cached = nameList;
- search.searchType = nssTokenSearchType_TokenOnly;
- /* traverse the tokens */
- for (token = (NSSToken *)nssListIterator_Start(td->tokens);
- token != (NSSToken *)NULL;
- token = (NSSToken *)nssListIterator_Next(td->tokens))
- {
- if (nssToken_SearchCerts(token, &notPresent)) {
- nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
- name, &search);
- }
- if (notPresent) {
- nssCertificateList_DestroyTokenCerts(nameList, token);
+ rvCerts = get_certs_from_list(nameList);
+ /* initialize the collection of token certificates with the set of
+ * cached certs (if any).
+ */
+ collection = nssCertificateCollection_Create(td, rvCerts);
+ nssCertificateArray_Destroy(rvCerts);
+ nssList_Destroy(nameList);
+ if (!collection) {
+ return (NSSCertificate **)NULL;
+ }
+ /* obtain the current set of active slots in the trust domain */
+ slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
+ if (!slots) {
+ goto loser;
+ }
+ /* iterate over the slots */
+ numRemaining = maximumOpt;
+ for (slotp = slots; *slotp; slotp++) {
+ token = nssSlot_GetToken(*slotp);
+ if (token) {
+ nssSession *session;
+ nssCryptokiObject **instances;
+ nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
+ session = nssTrustDomain_GetSessionForToken(td, token);
+ if (!session) {
+ nssToken_Destroy(token);
+ goto loser;
+ }
+ instances = nssToken_FindCertificatesByNickname(token,
+ session,
+ name,
+ tokenOnly,
+ numRemaining,
+ &status);
+ nssToken_Destroy(token);
+ if (status != PR_SUCCESS) {
+ goto loser;
+ }
+ if (instances) {
+ status = nssPKIObjectCollection_AddInstances(collection,
+ instances, 0);
+ nss_ZFreeIf(instances);
+ if (status != PR_SUCCESS) {
+ goto loser;
+ }
+ if (maximumOpt > 0) {
+ PRUint32 count;
+ count = nssPKIObjectCollection_Count(collection);
+ numRemaining = maximumOpt - count;
+ if (numRemaining == 0) break;
+ }
+ }
}
}
- nssListIterator_Finish(td->tokens);
- nssCertificateList_DoCallback(nameList, nssBestCertificate_Callback, &best);
- nssList_Clear(nameList, cert_destructor);
- nssList_Destroy(nameList);
- if (best.cert) {
- nssTrustDomain_AddCertsToCache(td, &best.cert, 1);
+ /* Grab the certs collected in the search. */
+ rvCerts = nssPKIObjectCollection_GetCertificates(collection,
+ rvOpt, maximumOpt,
+ arenaOpt);
+ /* clean up */
+ nssPKIObjectCollection_Destroy(collection);
+ nssSlotArray_Destroy(slots);
+ return rvCerts;
+loser:
+ if (slots) {
+ nssSlotArray_Destroy(slots);
+ }
+ if (collection) {
+ nssPKIObjectCollection_Destroy(collection);
}
- return best.cert;
+ return (NSSCertificate **)NULL;
}
NSS_IMPLEMENT NSSCertificate **
@@ -455,260 +543,204 @@ NSSTrustDomain_FindCertificatesByNickname
NSSArena *arenaOpt
)
{
- NSSCertificate **rvCerts = NULL;
- NSSToken *token;
- PRUint32 count;
- PRStatus nssrv;
- nssList *nameList;
- nssTokenCertSearch search;
- struct collect_arg_str ca;
- PRBool notPresent;
- /* set up the collection */
- nameList = nssList_Create(NULL, PR_FALSE);
- (void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nameList);
- ca.list = nameList;
- ca.maximum = maximumOpt;
- /* set the search criteria */
- search.callback = collect_certs;
- search.cbarg = &ca;
- search.cached = nameList;
- search.searchType = nssTokenSearchType_TokenOnly;
- /* traverse the tokens */
- for (token = (NSSToken *)nssListIterator_Start(td->tokens);
- token != (NSSToken *)NULL;
- token = (NSSToken *)nssListIterator_Next(td->tokens))
- {
- if (nssToken_SearchCerts(token, &notPresent)) {
- nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
- name, &search);
- }
- if (notPresent) {
- nssCertificateList_DestroyTokenCerts(nameList, token);
- }
- }
- nssListIterator_Finish(td->tokens);
- count = nssList_Count(nameList);
- if (maximumOpt > 0 && count > maximumOpt) count = maximumOpt;
- if (count > 0) {
- if (rvOpt) {
- nssList_GetArray(nameList, (void **)rvOpt, count);
- rvOpt[count] = NULL;
- } else {
- rvCerts = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, count + 1);
- nssList_GetArray(nameList, (void **)rvCerts, count);
- }
- nssTrustDomain_AddCertsToCache(td, rvCerts, count);
- }
- nssList_Destroy(nameList);
- /* The return array assumes the references from the list */
- return rvCerts;
-}
-
-static PRBool cert_token_not_present(NSSCertificate *c)
-{
- nssListIterator *instances;
- nssCryptokiInstance *instance;
- PRBool freeIt = PR_FALSE;
- PRBool notPresent = PR_TRUE;
- instances = nssList_CreateIterator(c->object.instanceList);
- for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances);
- instance != (nssCryptokiInstance *)NULL;
- instance = (nssCryptokiInstance *)nssListIterator_Next(instances))
- {
- if (!nssToken_IsPresent(instance->token)) {
- nssToken_DestroyCertList(instance->token, PR_TRUE);
- nssList_Remove(c->object.instanceList, instance);
- freeIt = PR_TRUE;
- } else {
- notPresent = PR_FALSE;
- }
- }
- nssListIterator_Finish(instances);
- nssListIterator_Destroy(instances);
- if (freeIt) {
- nssListIterator_Destroy(c->object.instances);
- c->object.instances = nssList_CreateIterator(c->object.instanceList);
- }
- return notPresent;
+ return nssTrustDomain_FindCertificatesByNickname(td,
+ name,
+ rvOpt,
+ maximumOpt,
+ arenaOpt);
}
NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_FindCertificateByIssuerAndSerialNumber
+nssTrustDomain_FindBestCertificateByNickname
(
NSSTrustDomain *td,
- NSSDER *issuer,
- NSSDER *serialNumber
+ NSSUTF8 *name,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt
)
{
+ NSSCertificate **nicknameCerts;
NSSCertificate *rvCert = NULL;
- NSSToken *tok;
- /* Try the cache */
- rvCert = nssTrustDomain_GetCertForIssuerAndSNFromCache(td,
- issuer,
- serialNumber);
- if (rvCert) {
- if (cert_token_not_present(rvCert)) {
- CERT_DestroyCertificate(STAN_GetCERTCertificate(rvCert));
- rvCert = NULL;
- }
- return rvCert;
- }
- /* Not cached, look for it on tokens */
- for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
- tok != (NSSToken *)NULL;
- tok = (NSSToken *)nssListIterator_Next(td->tokens))
- {
- if (nssToken_SearchCerts(tok, NULL)) {
- rvCert = nssToken_FindCertificateByIssuerAndSerialNumber(tok,
- NULL,
- issuer,
- serialNumber,
- nssTokenSearchType_TokenOnly);
- }
-#ifdef NSS_3_4_CODE
- if (!rvCert) {
- /* Some tokens expect a decoded serial number. For compatibility,
- * try the search again.
- */
- NSSDER decodedSerial;
- SECItem ds = { 0 };
- SECItem sn;
- SECStatus secrv;
- sn.data = serialNumber->data;
- sn.len = serialNumber->size;
- secrv = SEC_ASN1DecodeItem(NULL, &ds, SEC_IntegerTemplate, &sn);
- if (secrv == SECSuccess) {
- decodedSerial.data = ds.data;
- decodedSerial.size = ds.len;
- if (nssToken_SearchCerts(tok, NULL)) {
- rvCert = nssToken_FindCertificateByIssuerAndSerialNumber(
- tok,
- NULL,
- issuer,
- &decodedSerial,
- nssTokenSearchType_TokenOnly);
- }
- PORT_Free(ds.data);
- }
- }
-#endif
- if (rvCert) {
- /* cache it */
- nssTrustDomain_AddCertsToCache(td, &rvCert, 1);
- break;
- }
+ nicknameCerts = nssTrustDomain_FindCertificatesByNickname(td, name,
+ NULL,
+ 0,
+ NULL);
+ if (nicknameCerts) {
+ rvCert = nssCertificateArray_FindBestCertificate(nicknameCerts,
+ timeOpt,
+ usage,
+ policiesOpt);
+ nssCertificateArray_Destroy(nicknameCerts);
}
- nssListIterator_Finish(td->tokens);
return rvCert;
}
NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_FindBestCertificateBySubject
+NSSTrustDomain_FindBestCertificateByNickname
(
NSSTrustDomain *td,
- NSSDER *subject,
+ NSSUTF8 *name,
NSSTime *timeOpt,
NSSUsage *usage,
NSSPolicies *policiesOpt
)
{
- PRStatus nssrv;
- NSSToken *token;
- nssList *subjectList;
- nssBestCertificateCB best;
- nssTokenCertSearch search;
- PRBool notPresent;
- /* set the criteria for determining the best cert */
- nssBestCertificate_SetArgs(&best, timeOpt, usage, policiesOpt);
- /* find all matching certs in the cache */
- subjectList = nssList_Create(NULL, PR_FALSE);
- (void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList);
- /* set the search criteria */
- search.callback = nssBestCertificate_Callback;
- search.cbarg = &best;
- search.cached = subjectList;
- search.searchType = nssTokenSearchType_TokenOnly;
- /* traverse the tokens */
- for (token = (NSSToken *)nssListIterator_Start(td->tokens);
- token != (NSSToken *)NULL;
- token = (NSSToken *)nssListIterator_Next(td->tokens))
- {
- if (nssToken_SearchCerts(token, &notPresent)) {
- nssrv = nssToken_TraverseCertificatesBySubject(token, NULL,
- subject, &search);
- }
- if (notPresent) {
- nssCertificateList_DestroyTokenCerts(subjectList, token);
- }
- }
- nssListIterator_Finish(td->tokens);
- nssCertificateList_DoCallback(subjectList,
- nssBestCertificate_Callback, &best);
- nssList_Clear(subjectList, cert_destructor);
- nssList_Destroy(subjectList);
- if (best.cert) {
- nssTrustDomain_AddCertsToCache(td, &best.cert, 1);
- }
- return best.cert;
+ return nssTrustDomain_FindBestCertificateByNickname(td,
+ name,
+ timeOpt,
+ usage,
+ policiesOpt);
}
NSS_IMPLEMENT NSSCertificate **
-NSSTrustDomain_FindCertificatesBySubject
+nssTrustDomain_FindCertificatesBySubject
(
NSSTrustDomain *td,
NSSDER *subject,
NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
+ PRUint32 maximumOpt,
NSSArena *arenaOpt
)
{
- PRStatus nssrv;
+ PRStatus status;
+ PRUint32 numRemaining;
+ NSSToken *token = NULL;
+ NSSSlot **slots = NULL;
+ NSSSlot **slotp;
NSSCertificate **rvCerts = NULL;
- NSSToken *token;
- PRUint32 count;
+ nssPKIObjectCollection *collection = NULL;
+ nssUpdateLevel updateLevel;
nssList *subjectList;
- struct collect_arg_str ca;
- nssTokenCertSearch search;
- PRBool notPresent;
- /* set up the collection */
+ /* look in cache */
subjectList = nssList_Create(NULL, PR_FALSE);
+ if (!subjectList) {
+ return NULL;
+ }
(void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList);
- ca.list = subjectList;
- ca.maximum = maximumOpt;
- /* set the search criteria */
- search.callback = collect_certs;
- search.cbarg = &ca;
- search.cached = subjectList;
- search.searchType = nssTokenSearchType_TokenOnly;
- /* traverse the tokens */
- for (token = (NSSToken *)nssListIterator_Start(td->tokens);
- token != (NSSToken *)NULL;
- token = (NSSToken *)nssListIterator_Next(td->tokens))
- {
- if (nssToken_SearchCerts(token, &notPresent)) {
- nssrv = nssToken_TraverseCertificatesBySubject(token, NULL,
- subject, &search);
- }
- if (notPresent) {
- nssCertificateList_DestroyTokenCerts(subjectList, token);
- }
+ rvCerts = get_certs_from_list(subjectList);
+ collection = nssCertificateCollection_Create(td, rvCerts);
+ nssCertificateArray_Destroy(rvCerts);
+ nssList_Destroy(subjectList);
+ if (!collection) {
+ return (NSSCertificate **)NULL;
}
- nssListIterator_Finish(td->tokens);
- count = nssList_Count(subjectList);
- if (maximumOpt > 0 && count > maximumOpt) count = maximumOpt;
- if (count > 0) {
- if (rvOpt) {
- nssList_GetArray(subjectList, (void **)rvOpt, count);
- rvOpt[count] = NULL;
- } else {
- rvCerts = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, count + 1);
- nssList_GetArray(subjectList, (void **)rvCerts, count);
+ slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
+ if (!slots) {
+ goto loser;
+ }
+ numRemaining = maximumOpt;
+ for (slotp = slots; *slotp; slotp++) {
+ token = nssSlot_GetToken(*slotp);
+ if (token) {
+ nssSession *session;
+ nssCryptokiObject **instances;
+ nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
+ session = nssTrustDomain_GetSessionForToken(td, token);
+ if (!session) {
+ nssToken_Destroy(token);
+ goto loser;
+ }
+ instances = nssToken_FindCertificatesBySubject(token,
+ session,
+ subject,
+ tokenOnly,
+ numRemaining,
+ &status);
+ nssToken_Destroy(token);
+ if (status != PR_SUCCESS) {
+ goto loser;
+ }
+ if (instances) {
+ status = nssPKIObjectCollection_AddInstances(collection,
+ instances, 0);
+ nss_ZFreeIf(instances);
+ if (status != PR_SUCCESS) {
+ goto loser;
+ }
+ if (maximumOpt > 0) {
+ PRUint32 count;
+ count = nssPKIObjectCollection_Count(collection);
+ numRemaining = maximumOpt - count;
+ if (numRemaining == 0) break;
+ }
+ }
}
- nssTrustDomain_AddCertsToCache(td, rvCerts, count);
}
- nssList_Destroy(subjectList);
- /* The return array assumes the references from the list */
+ rvCerts = nssPKIObjectCollection_GetCertificates(collection,
+ rvOpt, maximumOpt,
+ arenaOpt);
+ nssPKIObjectCollection_Destroy(collection);
+ nssSlotArray_Destroy(slots);
return rvCerts;
+loser:
+ if (slots) {
+ nssSlotArray_Destroy(slots);
+ }
+ if (collection) {
+ nssPKIObjectCollection_Destroy(collection);
+ }
+ return (NSSCertificate **)NULL;
+}
+
+NSS_IMPLEMENT NSSCertificate **
+NSSTrustDomain_FindCertificatesBySubject
+(
+ NSSTrustDomain *td,
+ NSSDER *subject,
+ NSSCertificate *rvOpt[],
+ PRUint32 maximumOpt,
+ NSSArena *arenaOpt
+)
+{
+ return nssTrustDomain_FindCertificatesBySubject(td,
+ subject,
+ rvOpt,
+ maximumOpt,
+ arenaOpt);
+}
+
+NSS_IMPLEMENT NSSCertificate *
+nssTrustDomain_FindBestCertificateBySubject
+(
+ NSSTrustDomain *td,
+ NSSDER *subject,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt
+)
+{
+ NSSCertificate **subjectCerts;
+ NSSCertificate *rvCert = NULL;
+ subjectCerts = nssTrustDomain_FindCertificatesBySubject(td, subject,
+ NULL,
+ 0,
+ NULL);
+ if (subjectCerts) {
+ rvCert = nssCertificateArray_FindBestCertificate(subjectCerts,
+ timeOpt,
+ usage,
+ policiesOpt);
+ nssCertificateArray_Destroy(subjectCerts);
+ }
+ return rvCert;
+}
+
+NSS_IMPLEMENT NSSCertificate *
+NSSTrustDomain_FindBestCertificateBySubject
+(
+ NSSTrustDomain *td,
+ NSSDER *subject,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt
+)
+{
+ return nssTrustDomain_FindBestCertificateBySubject(td,
+ subject,
+ timeOpt,
+ usage,
+ policiesOpt);
}
NSS_IMPLEMENT NSSCertificate *
@@ -740,45 +772,138 @@ NSSTrustDomain_FindCertificatesByNameComponents
}
NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_FindCertificateByEncodedCertificate
+nssTrustDomain_FindCertificateByIssuerAndSerialNumber
(
NSSTrustDomain *td,
- NSSBER *encodedCertificate
+ NSSDER *issuer,
+ NSSDER *serial
)
{
+ PRStatus status;
+ NSSToken *token = NULL;
+ NSSSlot **slots = NULL;
+ NSSSlot **slotp;
NSSCertificate *rvCert = NULL;
- NSSToken *tok;
- /* Try the cache */
- rvCert = nssTrustDomain_GetCertByDERFromCache(td, encodedCertificate);
+ nssPKIObjectCollection *collection = NULL;
+ nssUpdateLevel updateLevel;
+ /* see if this search is already cached */
+ rvCert = nssTrustDomain_GetCertForIssuerAndSNFromCache(td,
+ issuer,
+ serial);
if (rvCert) {
- if (cert_token_not_present(rvCert)) {
- CERT_DestroyCertificate(STAN_GetCERTCertificate(rvCert));
- rvCert = NULL;
- }
return rvCert;
}
- /* Not cached, look for it on tokens */
- for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
- tok != (NSSToken *)NULL;
- tok = (NSSToken *)nssListIterator_Next(td->tokens))
- {
- if (nssToken_SearchCerts(tok, NULL)) {
- rvCert = nssToken_FindCertificateByEncodedCertificate(tok, NULL,
- encodedCertificate,
- nssTokenSearchType_TokenOnly);
+ slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
+ if (!slots) {
+ goto loser;
+ }
+ for (slotp = slots; *slotp; slotp++) {
+ token = nssSlot_GetToken(*slotp);
+ if (token) {
+ nssSession *session;
+ nssCryptokiObject *instance;
+ nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
+ session = nssTrustDomain_GetSessionForToken(td, token);
+ if (!session) {
+ nssToken_Destroy(token);
+ goto loser;
+ }
+ instance = nssToken_FindCertificateByIssuerAndSerialNumber(
+ token,
+ session,
+ issuer,
+ serial,
+ tokenOnly,
+ &status);
+ nssToken_Destroy(token);
+ if (status != PR_SUCCESS) {
+ goto loser;
+ }
+ if (instance) {
+ if (!collection) {
+ collection = nssCertificateCollection_Create(td, NULL);
+ if (!collection) {
+ goto loser;
+ }
+ }
+ nssPKIObjectCollection_AddInstances(collection,
+ &instance, 1);
+ }
}
- if (rvCert) {
- /* cache it */
- nssTrustDomain_AddCertsToCache(td, &rvCert, 1);
- break;
+ }
+ if (collection) {
+ (void)nssPKIObjectCollection_GetCertificates(collection,
+ &rvCert, 1, NULL);
+ nssPKIObjectCollection_Destroy(collection);
+ if (!rvCert) {
+ goto loser;
}
}
- nssListIterator_Finish(td->tokens);
+ nssSlotArray_Destroy(slots);
+ return rvCert;
+loser:
+ if (collection) {
+ nssPKIObjectCollection_Destroy(collection);
+ }
+ if (slots) {
+ nssSlotArray_Destroy(slots);
+ }
+ return (NSSCertificate *)NULL;
+}
+
+NSS_IMPLEMENT NSSCertificate *
+NSSTrustDomain_FindCertificateByIssuerAndSerialNumber
+(
+ NSSTrustDomain *td,
+ NSSDER *issuer,
+ NSSDER *serial
+)
+{
+ return nssTrustDomain_FindCertificateByIssuerAndSerialNumber(td,
+ issuer,
+ serial);
+}
+
+NSS_IMPLEMENT NSSCertificate *
+nssTrustDomain_FindCertificateByEncodedCertificate
+(
+ NSSTrustDomain *td,
+ NSSBER *ber
+)
+{
+ PRStatus status;
+ NSSCertificate *rvCert = NULL;
+ NSSDER issuer = { 0 };
+ NSSDER serial = { 0 };
+ NSSArena *arena = nssArena_Create();
+ if (!arena) {
+ return (NSSCertificate *)NULL;
+ }
+ /* XXX this is not generic... will any cert crack into issuer/serial? */
+ status = nssPKIX509_GetIssuerAndSerialFromDER(ber, arena, &issuer, &serial);
+ if (status != PR_SUCCESS) {
+ goto finish;
+ }
+ rvCert = nssTrustDomain_FindCertificateByIssuerAndSerialNumber(td,
+ &issuer,
+ &serial);
+finish:
+ nssArena_Destroy(arena);
return rvCert;
}
NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_FindCertificateByEmail
+NSSTrustDomain_FindCertificateByEncodedCertificate
+(
+ NSSTrustDomain *td,
+ NSSBER *ber
+)
+{
+ return nssTrustDomain_FindCertificateByEncodedCertificate(td, ber);
+}
+
+NSS_IMPLEMENT NSSCertificate *
+NSSTrustDomain_FindBestCertificateByEmail
(
NSSTrustDomain *td,
NSSASCII7 *email,
@@ -787,44 +912,7 @@ NSSTrustDomain_FindCertificateByEmail
NSSPolicies *policiesOpt
)
{
- PRStatus nssrv;
- NSSToken *token;
- nssBestCertificateCB best;
- nssTokenCertSearch search;
- nssList *emailList;
- PRBool notPresent;
- /* set the criteria for determining the best cert */
- nssBestCertificate_SetArgs(&best, timeOpt, usage, policiesOpt);
- /* find all matching certs in the cache */
- emailList = nssList_Create(NULL, PR_FALSE);
- (void)nssTrustDomain_GetCertsForEmailAddressFromCache(td, email, emailList);
- /* set the search criteria */
- search.callback = nssBestCertificate_Callback;
- search.cbarg = &best;
- search.cached = emailList;
- search.searchType = nssTokenSearchType_TokenOnly;
- /* traverse the tokens */
- for (token = (NSSToken *)nssListIterator_Start(td->tokens);
- token != (NSSToken *)NULL;
- token = (NSSToken *)nssListIterator_Next(td->tokens))
- {
- if (nssToken_SearchCerts(token, &notPresent)) {
- nssrv = nssToken_TraverseCertificatesByEmail(token, NULL,
- email, &search);
- }
- if (notPresent) {
- nssCertificateList_DestroyTokenCerts(emailList, token);
- }
- }
- nssListIterator_Finish(td->tokens);
- nssCertificateList_DoCallback(emailList,
- nssBestCertificate_Callback, &best);
- nssList_Clear(emailList, cert_destructor);
- nssList_Destroy(emailList);
- if (best.cert) {
- nssTrustDomain_AddCertsToCache(td, &best.cert, 1);
- }
- return best.cert;
+ return 0;
}
NSS_IMPLEMENT NSSCertificate **
@@ -947,127 +1035,309 @@ NSSTrustDomain_FindUserCertificatesForEmailSigning
return NULL;
}
-struct traverse_arg
+static PRStatus
+collector(nssCryptokiObject *instance, void *arg)
{
- PRStatus (*callback)(NSSCertificate *c, void *arg);
- nssList *cached;
- void *arg;
-};
+ nssPKIObjectCollection *collection = (nssPKIObjectCollection *)arg;
+ return nssPKIObjectCollection_AddInstanceAsObject(collection, instance);
+}
-static PRStatus traverse_callback(NSSCertificate *c, void *arg)
+NSS_IMPLEMENT PRStatus *
+NSSTrustDomain_TraverseCertificates
+(
+ NSSTrustDomain *td,
+ PRStatus (*callback)(NSSCertificate *c, void *arg),
+ void *arg
+)
{
- PRStatus nssrv;
- struct traverse_arg *ta = (struct traverse_arg *)arg;
- NSSCertificate *cp = nssCertificate_AddRef(c);
- NSSTrustDomain *td = NSSCertificate_GetTrustDomain(c);
- /* The cert coming in has been retrieved from a token. It was not in
- * the cache when the search was begun. But it may be in the cache now,
- * and if it isn't, it will be, because it is going to be cracked into
- * a CERTCertificate and fed into the callback.
- */
- nssrv = nssTrustDomain_AddCertsToCache(td, &c, 1);
- if (!nssList_Get(ta->cached, c)) {
- /* add it to the cached list for this search */
- nssCertificate_AddRef(c);
- nssList_Add(ta->cached, c);
+ PRStatus status;
+ NSSToken *token = NULL;
+ NSSSlot **slots = NULL;
+ NSSSlot **slotp;
+ nssPKIObjectCollection *collection = NULL;
+ nssPKIObjectCallback pkiCallback;
+ nssUpdateLevel updateLevel;
+ NSSCertificate **cached = NULL;
+ nssList *certList;
+
+ certList = nssList_Create(NULL, PR_FALSE);
+ if (!certList) return NULL;
+ (void *)nssTrustDomain_GetCertsFromCache(td, certList);
+ cached = get_certs_from_list(certList);
+ collection = nssCertificateCollection_Create(td, cached);
+ nssCertificateArray_Destroy(cached);
+ nssList_Destroy(certList);
+ if (!collection) {
+ return (PRStatus *)NULL;
+ }
+ /* obtain the current set of active slots in the trust domain */
+ slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
+ if (!slots) {
+ goto loser;
+ }
+ /* iterate over the slots */
+ for (slotp = slots; *slotp; slotp++) {
+ /* get the token for the slot, if present */
+ token = nssSlot_GetToken(*slotp);
+ if (token) {
+ nssSession *session;
+ nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
+ /* get a session for the token */
+ session = nssTrustDomain_GetSessionForToken(td, token);
+ if (!session) {
+ nssToken_Destroy(token);
+ goto loser;
+ }
+ /* perform the traversal */
+ status = nssToken_TraverseCertificates(token,
+ session,
+ tokenOnly,
+ collector,
+ collection);
+ nssToken_Destroy(token);
+ if (status != PR_SUCCESS) {
+ goto loser;
+ }
+ }
}
- /* This is why the hack of copying the cert was done above. The pointer
- * c passed to this function is provided by retrieve_cert. That function
- * will destroy the pointer once this function returns. Since c is a local
- * copy, there is no way to notify retrieve_cert if it has changed. That
- * would happen if the above call to add it to the cache found the cert
- * already there. In that case, the pointer c passed to the callback
- * below will be the cached cert, and the pointer c that retrieve_cert
- * has will be the same as the copy made above. Thus, retrieve_cert will
- * destroy the reference to the copy, the callback will use the reference
- * to the cached entry, and everyone should be happy.
- */
- nssrv = (*ta->callback)(c, ta->arg);
- /* This function owns a reference to the cert, either from the AddRef
- * or by getting it from the cache.
- */
- CERT_DestroyCertificate(STAN_GetCERTCertificate(c));
- return nssrv;
-}
-#ifdef NSS_3_4_CODE
-static void cert_destructor_with_cache(void *el)
-{
- NSSCertificate *c = (NSSCertificate *)el;
- CERTCertificate *cert = STAN_GetCERTCertificate(c);
- /* It's already been obtained as a CERTCertificate, so it must
- * be destroyed as one
- */
- CERT_DestroyCertificate(cert);
+ /* Traverse the collection */
+ pkiCallback.func.cert = callback;
+ pkiCallback.arg = arg;
+ status = nssPKIObjectCollection_Traverse(collection, &pkiCallback);
+ /* clean up */
+ nssPKIObjectCollection_Destroy(collection);
+ nssSlotArray_Destroy(slots);
+ return NULL;
+loser:
+ if (slots) {
+ nssSlotArray_Destroy(slots);
+ }
+ if (collection) {
+ nssPKIObjectCollection_Destroy(collection);
+ }
+ return NULL;
}
-#endif
+#ifdef notdef
+/*
+ * search for Public and Private keys first
+ */
NSS_IMPLEMENT PRStatus *
-NSSTrustDomain_TraverseCertificates
+NSSTrustDomain_TraverseUserCertificates
(
NSSTrustDomain *td,
PRStatus (*callback)(NSSCertificate *c, void *arg),
void *arg
)
{
- PRStatus nssrv;
- NSSToken *token;
- nssList *certList, *cacheList;
- nssTokenCertSearch search;
- struct traverse_arg ta;
- nssListIterator *tokens;
- PRBool notPresent;
+ PRStatus status;
+ NSSToken *token = NULL;
+ NSSSlot **slots = NULL;
+ NSSSlot **slotp;
+ nssPKIObjectCollection *collection = NULL;
+ nssPKIObjectCallback pkiCallback;
+ nssUpdateLevel updateLevel;
+ NSSCertificate **cached = NULL;
+ nssList *certList;
certList = nssList_Create(NULL, PR_FALSE);
if (!certList) return NULL;
(void *)nssTrustDomain_GetCertsFromCache(td, certList);
- cacheList = nssList_Clone(certList);
- if (!cacheList) {
- goto cleanup;
+ cached = get_certs_from_list(certList);
+ collection = nssCertificateCollection_Create(td, cached);
+ nssCertificateArray_Destroy(cached);
+ nssList_Destroy(certList);
+ if (!collection) {
+ return (PRStatus *)NULL;
}
- /* set traverse args */
- ta.callback = callback;
- ta.cached = certList;
- ta.arg = arg;
- /* set the search criteria */
- search.callback = traverse_callback;
- search.cbarg = &ta;
- search.cached = certList;
- search.searchType = nssTokenSearchType_TokenOnly;
- /* Must create a local copy of the token list, because the callback
- * above may want to traverse the tokens as well.
- */
- tokens = nssList_CreateIterator(td->tokenList);
- if (!tokens) {
- goto cleanup;
+ /* obtain the current set of active slots in the trust domain */
+ slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
+ if (!slots) {
+ goto loser;
}
- /* traverse the tokens */
- for (token = (NSSToken *)nssListIterator_Start(tokens);
- token != (NSSToken *)NULL;
- token = (NSSToken *)nssListIterator_Next(tokens))
- {
- if (nssToken_SearchCerts(token, &notPresent)) {
- nssrv = nssToken_TraverseCertificates(token, NULL, &search);
- }
- if (notPresent) {
- nssCertificateList_RemoveTokenCerts(cacheList, token);
+ /* 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);
+ if (!session) {
+ nssToken_Destroy(token);
+ goto loser;
+ }
+ /* perform the traversal */
+ if (!isLoggedIn(tok)) {
+ instances = nssToken_FindPublicKeys(token,
+ session,
+ tokenOnly,
+ 0, &status);
+ } else {
+ instances = nssToken_FindPrivateKeys(token,
+ session,
+ tokenOnly,
+ 0, &status);
+ }
+ nssToken_Destroy(token);
+ if (status != PR_SUCCESS) {
+ goto loser;
+ }
+ /* add the found certificates to the collection */
+ status = nssPKIObjectCollection_AddInstances(collection,
+ instances, 0);
+ nss_ZFreeIf(instances);
+ if (status != PR_SUCCESS) {
+ goto loser;
+ }
}
}
- nssListIterator_Finish(tokens);
- nssListIterator_Destroy(tokens);
- /* now do the callback on the cached certs,
- * sans certs from removed tokens
- */
- nssCertificateList_DoCallback(cacheList, callback, arg);
- nssList_Destroy(cacheList);
-cleanup:
-#ifdef NSS_3_4_CODE
- nssList_Clear(certList, cert_destructor_with_cache);
-#else
- nssList_Clear(certList, cert_destructor);
-#endif
- nssList_Destroy(certList);
+ status = nssPKIObjectCollection_MatchCerts(collection);
+ if (status != PR_SUCCESS) {
+ goto loser;
+ }
+ /* Traverse the collection */
+ pkiCallback.func.cert = callback;
+ pkiCallback.arg = arg;
+ status = nssPKIObjectCollection_Traverse(collection, &pkiCallback);
+ /* clean up */
+ nssPKIObjectCollection_Destroy(collection);
+ nssSlotArray_Destroy(slots);
+ return NULL;
+loser:
+ if (slots) {
+ nssSlotArray_Destroy(slots);
+ }
+ if (collection) {
+ nssPKIObjectCollection_Destroy(collection);
+ }
return NULL;
}
+#endif
+
+NSS_IMPLEMENT NSSTrust *
+nssTrustDomain_FindTrustForCertificate
+(
+ NSSTrustDomain *td,
+ NSSCertificate *c
+)
+{
+ PRStatus status;
+ NSSSlot **slots;
+ NSSSlot **slotp;
+ NSSToken *token;
+ 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) {
+ to = nssToken_FindTrustForCertificate(token, NULL,
+ &c->encoding,
+ &c->issuer,
+ &c->serial,
+ nssTokenSearchType_TokenOnly);
+ 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,
+ NSSDER *subject
+)
+{
+ PRStatus status;
+ NSSSlot **slots;
+ NSSSlot **slotp;
+ NSSToken *token;
+ nssUpdateLevel updateLevel;
+ nssPKIObjectCollection *collection;
+ NSSCRL **rvCRLs = NULL;
+ collection = nssCRLCollection_Create(td, NULL);
+ if (!collection) {
+ return (NSSCRL **)NULL;
+ }
+ slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
+ if (!slots) {
+ goto loser;
+ }
+ for (slotp = slots; *slotp; slotp++) {
+ token = nssSlot_GetToken(*slotp);
+ if (token) {
+ nssSession *session;
+ nssCryptokiObject **instances;
+ nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
+ /* get a session for the token */
+ session = nssTrustDomain_GetSessionForToken(td, token);
+ if (!session) {
+ nssToken_Destroy(token);
+ goto loser;
+ }
+ /* perform the traversal */
+ instances = nssToken_FindCRLsBySubject(token, session, subject,
+ tokenOnly, 0, &status);
+ nssToken_Destroy(token);
+ if (status != PR_SUCCESS) {
+ goto loser;
+ }
+ /* add the found CRL's to the collection */
+ status = nssPKIObjectCollection_AddInstances(collection,
+ instances, 0);
+ nss_ZFreeIf(instances);
+ if (status != PR_SUCCESS) {
+ goto loser;
+ }
+ }
+ }
+ rvCRLs = nssPKIObjectCollection_GetCRLs(collection, NULL, 0, NULL);
+ nssPKIObjectCollection_Destroy(collection);
+ nssSlotArray_Destroy(slots);
+ return rvCRLs;
+loser:
+ nssPKIObjectCollection_Destroy(collection);
+ nssSlotArray_Destroy(slots);
+ return (NSSCRL **)NULL;
+}
NSS_IMPLEMENT PRStatus
NSSTrustDomain_GenerateKeyPair
@@ -1127,25 +1397,23 @@ NSSTrustDomain_FindSymmetricKeyByAlgorithmAndKeyID
}
NSS_IMPLEMENT NSSCryptoContext *
+nssTrustDomain_CreateCryptoContext
+(
+ NSSTrustDomain *td,
+ NSSCallback *uhhOpt
+)
+{
+ return nssCryptoContext_Create(td, uhhOpt);
+}
+
+NSS_IMPLEMENT NSSCryptoContext *
NSSTrustDomain_CreateCryptoContext
(
NSSTrustDomain *td,
NSSCallback *uhhOpt
)
{
- NSSArena *arena;
- NSSCryptoContext *rvCC;
- arena = NSSArena_Create();
- if (!arena) {
- return NULL;
- }
- rvCC = nss_ZNEW(arena, NSSCryptoContext);
- if (!rvCC) {
- return NULL;
- }
- rvCC->td = td;
- rvCC->arena = arena;
- return rvCC;
+ return nssTrustDomain_CreateCryptoContext(td, uhhOpt);
}
NSS_IMPLEMENT NSSCryptoContext *
diff --git a/security/nss/lib/smime/cmscinfo.c b/security/nss/lib/smime/cmscinfo.c
index 9e4a2dc5e..85756a536 100644
--- a/security/nss/lib/smime/cmscinfo.c
+++ b/security/nss/lib/smime/cmscinfo.c
@@ -78,6 +78,11 @@ NSS_CMSContentInfo_Destroy(NSSCMSContentInfo *cinfo)
}
if (cinfo->bulkkey)
PK11_FreeSymKey(cinfo->bulkkey);
+
+ if (cinfo->ciphcx) {
+ NSS_CMSCipherContext_Destroy(cinfo->ciphcx);
+ cinfo->ciphcx = NULL;
+ }
/* we live in a pool, so no need to worry about storage */
}
diff --git a/security/nss/lib/smime/cmsencdata.c b/security/nss/lib/smime/cmsencdata.c
index 61aae96d8..fdfa0a2b9 100644
--- a/security/nss/lib/smime/cmsencdata.c
+++ b/security/nss/lib/smime/cmsencdata.c
@@ -202,8 +202,10 @@ NSS_CMSEncryptedData_Encode_BeforeData(NSSCMSEncryptedData *encd)
SECStatus
NSS_CMSEncryptedData_Encode_AfterData(NSSCMSEncryptedData *encd)
{
- if (encd->contentInfo.ciphcx)
+ if (encd->contentInfo.ciphcx) {
NSS_CMSCipherContext_Destroy(encd->contentInfo.ciphcx);
+ encd->contentInfo.ciphcx = NULL;
+ }
/* nothing to do after data */
return SECSuccess;
@@ -265,7 +267,10 @@ loser:
SECStatus
NSS_CMSEncryptedData_Decode_AfterData(NSSCMSEncryptedData *encd)
{
- NSS_CMSCipherContext_Destroy(encd->contentInfo.ciphcx);
+ if (encd->contentInfo.ciphcx) {
+ NSS_CMSCipherContext_Destroy(encd->contentInfo.ciphcx);
+ encd->contentInfo.ciphcx = NULL;
+ }
return SECSuccess;
}
diff --git a/security/nss/lib/smime/cmssigdata.c b/security/nss/lib/smime/cmssigdata.c
index fab7189f2..03a37cda1 100644
--- a/security/nss/lib/smime/cmssigdata.c
+++ b/security/nss/lib/smime/cmssigdata.c
@@ -540,7 +540,7 @@ NSS_CMSSignedData_VerifyCertsOnly(NSSCMSSignedData *sigd,
count = NSS_CMSArray_Count((void**)sigd->rawCerts);
for (i=0; i < count; i++) {
if (sigd->certs && sigd->certs[i]) {
- cert = sigd->certs[i];
+ cert = CERT_DupCertificate(sigd->certs[i]);
} else {
cert = CERT_FindCertByDERCert(certdb, sigd->rawCerts[i]);
if (!cert) {
@@ -550,6 +550,7 @@ NSS_CMSSignedData_VerifyCertsOnly(NSSCMSSignedData *sigd,
}
rv |= CERT_VerifyCert(certdb, cert, PR_TRUE, usage, PR_Now(),
NULL, NULL);
+ CERT_DestroyCertificate(cert);
}
return rv;
diff --git a/security/nss/lib/softoken/cdbhdl.h b/security/nss/lib/softoken/cdbhdl.h
index b606e9876..f52712422 100644
--- a/security/nss/lib/softoken/cdbhdl.h
+++ b/security/nss/lib/softoken/cdbhdl.h
@@ -51,4 +51,21 @@ struct NSSLOWCERTCertDBHandleStr {
PZMonitor *dbMon;
};
+#ifdef DBM_USING_NSPR
+#define NO_RDONLY PR_RDONLY
+#define NO_RDWR PR_RDWR
+#define NO_CREATE (PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE)
+#else
+#define NO_RDONLY O_RDONLY
+#define NO_RDWR O_RDWR
+#define NO_CREATE (O_RDWR | O_CREAT | O_TRUNC)
+#endif
+
+typedef DB * (*rdbfunc)(const char *appName, const char *prefix,
+ const char *type, int flags);
+
+DB * rdbopen(const char *appName, const char *prefix,
+ const char *type, int flags);
+
+SECStatus db_Copy(DB *dest,DB *src);
#endif
diff --git a/security/nss/lib/softoken/config.mk b/security/nss/lib/softoken/config.mk
index b59f0cf32..0d72934be 100644
--- a/security/nss/lib/softoken/config.mk
+++ b/security/nss/lib/softoken/config.mk
@@ -95,3 +95,7 @@ MKSHLIB += -R '$$ORIGIN'
endif
endif
endif
+
+ifeq ($(OS_TARGET),WINCE)
+DEFINES += -DDBM_USING_NSPR
+endif
diff --git a/security/nss/lib/softoken/dbinit.c b/security/nss/lib/softoken/dbinit.c
index 8fa73fef2..87098dc0a 100644
--- a/security/nss/lib/softoken/dbinit.c
+++ b/security/nss/lib/softoken/dbinit.c
@@ -102,6 +102,29 @@ pk11_keydb_name_cb(void *arg, int dbVersion)
#define CKR_CERTDB_FAILED CKR_DEVICE_ERROR
#define CKR_KEYDB_FAILED CKR_DEVICE_ERROR
+const char *
+pk11_EvaluateConfigDir(const char *configdir,char **appName)
+{
+ if (PORT_Strncmp(configdir, MULTIACCESS, sizeof(MULTIACCESS)-1) == 0) {
+ char *cdir;
+
+ *appName = PORT_Strdup(configdir+sizeof(MULTIACCESS)-1);
+ if (*appName == NULL) {
+ return configdir;
+ }
+ cdir = *appName;
+ while (*cdir && *cdir != ':') {
+ cdir++;
+ }
+ if (*cdir == ':') {
+ *cdir = 0;
+ cdir++;
+ }
+ configdir = cdir;
+ }
+ return configdir;
+}
+
static CK_RV
pk11_OpenCertDB(const char * configdir, const char *prefix, PRBool readOnly,
NSSLOWCERTCertDBHandle **certdbPtr)
@@ -110,11 +133,14 @@ pk11_OpenCertDB(const char * configdir, const char *prefix, PRBool readOnly,
CK_RV crv = CKR_CERTDB_FAILED;
SECStatus rv;
char * name = NULL;
+ char * appName = NULL;
if (prefix == NULL) {
prefix = "";
}
+ configdir = pk11_EvaluateConfigDir(configdir, &appName);
+
name = PR_smprintf("%s" PATH_SEPARATOR "%s",configdir,prefix);
if (name == NULL) goto loser;
@@ -123,7 +149,7 @@ pk11_OpenCertDB(const char * configdir, const char *prefix, PRBool readOnly,
goto loser;
/* fix when we get the DB in */
- rv = nsslowcert_OpenCertDB(certdb, readOnly,
+ rv = nsslowcert_OpenCertDB(certdb, readOnly, appName, prefix,
pk11_certdb_name_cb, (void *)name, PR_FALSE);
if (rv == SECSuccess) {
crv = CKR_OK;
@@ -133,6 +159,7 @@ pk11_OpenCertDB(const char * configdir, const char *prefix, PRBool readOnly,
loser:
if (certdb) PR_Free(certdb);
if (name) PORT_Free(name);
+ if (appName) PORT_Free(appName);
return crv;
}
@@ -142,15 +169,20 @@ pk11_OpenKeyDB(const char * configdir, const char *prefix, PRBool readOnly,
{
NSSLOWKEYDBHandle *keydb;
char * name = NULL;
+ char * appName = NULL;
if (prefix == NULL) {
prefix = "";
}
+ configdir = pk11_EvaluateConfigDir(configdir, &appName);
+
name = PR_smprintf("%s" PATH_SEPARATOR "%s",configdir,prefix);
if (name == NULL)
return SECFailure;
- keydb = nsslowkey_OpenKeyDB(readOnly, pk11_keydb_name_cb, (void *)name);
+ keydb = nsslowkey_OpenKeyDB(readOnly, appName, prefix,
+ pk11_keydb_name_cb, (void *)name);
PORT_Free(name);
+ if (appName) PORT_Free(appName);
if (keydb == NULL)
return CKR_KEYDB_FAILED;
*keydbPtr = keydb;
@@ -222,3 +254,57 @@ pk11_DBShutdown(NSSLOWCERTCertDBHandle *certHandle,
keyHandle= NULL;
}
}
+
+static rdbfunc pk11_rdbfunc;
+
+/* NOTE: SHLIB_SUFFIX is defined on the command line */
+#define RDBLIB "rdb."SHLIB_SUFFIX
+
+DB * rdbopen(const char *appName, const char *prefix,
+ const char *type, int flags)
+{
+ PRLibrary *lib;
+ DB *db;
+
+ if (pk11_rdbfunc) {
+ db = (*pk11_rdbfunc)(appName,prefix,type,flags);
+ return db;
+ }
+
+ /*
+ * try to open the library.
+ */
+ lib = PR_LoadLibrary(RDBLIB);
+
+ if (!lib) {
+ return NULL;
+ }
+
+ /* get the entry point */
+ pk11_rdbfunc = (rdbfunc) PR_FindSymbol(lib,"rdbopen");
+ if (pk11_rdbfunc) {
+ return (*pk11_rdbfunc)(appName,prefix,type,flags);
+ }
+
+ /* couldn't find the entry point, unload the library and fail */
+ PR_UnloadLibrary(lib);
+ return NULL;
+}
+
+SECStatus
+db_Copy(DB *dest,DB *src)
+{
+ int ret;
+ DBT key,data;
+ ret = (*src->seq)(src, &key, &data, R_FIRST);
+ if (ret) {
+ return SECSuccess;
+ }
+
+ do {
+ (void)(*dest->put)(dest,&key,&data, R_NOOVERWRITE);
+ } while ( (*src->seq)(src, &key, &data, R_NEXT) == 0);
+ (void)(*dest->sync)(dest,0);
+
+ return SECSuccess;
+}
diff --git a/security/nss/lib/softoken/fipstokn.c b/security/nss/lib/softoken/fipstokn.c
index e3abfaf88..c33670451 100644
--- a/security/nss/lib/softoken/fipstokn.c
+++ b/security/nss/lib/softoken/fipstokn.c
@@ -164,11 +164,17 @@ CK_RV FC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList) {
return CKR_OK;
}
+/* sigh global so pkcs11 can read it */
+PRBool nsf_init = PR_FALSE;
/* FC_Initialize initializes the PKCS #11 library. */
CK_RV FC_Initialize(CK_VOID_PTR pReserved) {
CK_RV crv;
+ if (nsf_init) {
+ return CKR_CRYPTOKI_ALREADY_INITIALIZED;
+ }
+
crv = nsc_CommonInitialize(pReserved, PR_TRUE);
/* not an 'else' rv can be set by either PK11_LowInit or PK11_SlotInit*/
@@ -181,17 +187,24 @@ CK_RV FC_Initialize(CK_VOID_PTR pReserved) {
crv = pk11_fipsPowerUpSelfTest();
if (crv != CKR_OK) {
+ nsc_CommonFinalize(NULL, PR_TRUE);
fatalError = PR_TRUE;
return crv;
}
+ nsf_init = PR_TRUE;
return CKR_OK;
}
/*FC_Finalize indicates that an application is done with the PKCS #11 library.*/
CK_RV FC_Finalize (CK_VOID_PTR pReserved) {
- /* this should free up FIPS Slot */
- return NSC_Finalize (pReserved);
+ CK_RV crv;
+ if (!nsf_init) {
+ return CKR_OK;
+ }
+ crv = nsc_CommonFinalize (pReserved, PR_TRUE);
+ nsf_init = (PRBool) !(crv == CKR_OK);
+ return crv;
}
@@ -203,7 +216,8 @@ CK_RV FC_GetInfo(CK_INFO_PTR pInfo) {
/* FC_GetSlotList obtains a list of slots in the system. */
CK_RV FC_GetSlotList(CK_BBOOL tokenPresent,
CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) {
- return NSC_GetSlotList(tokenPresent,pSlotList,pulCount);
+ return nsc_CommonGetSlotList(tokenPresent,pSlotList,pulCount,
+ NSC_FIPS_MODULE);
}
/* FC_GetSlotInfo obtains information about a particular slot in the system. */
diff --git a/security/nss/lib/softoken/keydb.c b/security/nss/lib/softoken/keydb.c
index 818427a08..dc58a402d 100644
--- a/security/nss/lib/softoken/keydb.c
+++ b/security/nss/lib/softoken/keydb.c
@@ -47,6 +47,7 @@
#include "mcom_db.h"
#include "lowpbe.h"
#include "secerr.h"
+#include "cdbhdl.h"
#include "keydbi.h"
@@ -546,13 +547,6 @@ keyDBFilenameCallback(void *arg, int dbVersion)
return(PORT_Strdup((char *)arg));
}
-NSSLOWKEYDBHandle *
-nsslowkey_OpenKeyDBFilename(char *dbname, PRBool readOnly)
-{
- return(nsslowkey_OpenKeyDB(readOnly, keyDBFilenameCallback,
- (void *)dbname));
-}
-
static SECStatus
ChangeKeyDBPasswordAlg(NSSLOWKEYDBHandle *handle,
SECItem *oldpwitem, SECItem *newpwitem,
@@ -592,148 +586,12 @@ nsslowkey_version(DB *db)
return 255;
}
- if ( ret == 1 ) {
+ if ( ret >= 1 ) {
return 0;
}
return *( (unsigned char *)versionData.data);
}
-#ifdef NSS_USE_KEY4_DB
-nsslowkey_UpdateKey3DBPass1(NSSLOWKEYDBHandle *handle)
-{
- SECStatus rv;
- DBT checkKey;
- DBT checkData;
- DBT saltKey;
- DBT saltData;
- DBT key;
- DBT data;
- DBT newKey;
- unsigned char buf[SHA1_LENGTH];
- unsigned char version;
- SECItem *rc4key = NULL;
- NSSLOWKEYDBKey *dbkey = NULL;
- SECItem *oldSalt = NULL;
- int ret;
- SECItem checkitem;
-
- if ( handle->updatedb == NULL ) {
- return(SECSuccess);
- }
-
- /*
- * check the version record
- */
- version = nsslowkey_version(handle->updatedb);
- if (version != 3) {
- goto done;
- }
-
- saltKey.data = SALT_STRING;
- saltKey.size = sizeof(SALT_STRING) - 1;
-
- ret = (* handle->updatedb->get)(handle->updatedb, &saltKey, &saltData, 0);
- if ( ret ) {
- /* no salt in old db, so it is corrupted */
- goto done;
- }
-
- oldSalt = decodeKeyDBGlobalSalt(&saltData);
- if ( oldSalt == NULL ) {
- /* bad salt in old db, so it is corrupted */
- goto done;
- }
-
- /*
- * look for a pw check entry
- */
- checkKey.data = KEYDB_PW_CHECK_STRING;
- checkKey.size = KEYDB_PW_CHECK_LEN;
-
- ret = (* handle->updatedb->get)(handle->updatedb, &checkKey,
- &checkData, 0 );
- if (ret) {
- checkKey.data = KEYDB_FAKE_PW_CHECK_STRING;
- checkKey.size = KEYDB_FAKE_PW_CHECK_LEN;
- ret = (* handle->updatedb->get)(handle->updatedb, &checkKey,
- &checkData, 0 );
- if (ret) {
- goto done;
- }
- }
-
- /* put global salt into the new database now */
- ret = (* handle->db->put)( handle->db, &saltKey, &saltData, 0);
- if ( ret ) {
- goto done;
- }
-
- if (checkKey.size == KEYDB_PW_CHECK_LEN) {
- dbkey = decode_dbkey(&checkData, 3);
- if ( dbkey == NULL ) {
- goto done;
- }
- rv = put_dbkey(handle, &checkKey, dbkey, PR_FALSE);
- ret = (rv != SECSuccess);
- } else {
- ret = (* handle->db->put)(handle->db, &checkKey, &checkData, 0);
- }
- if ( ret ) {
- goto done;
- }
-
- /* now traverse the database */
- ret = (* handle->updatedb->seq)(handle->updatedb, &key, &data, R_FIRST);
- if ( ret ) {
- goto done;
- }
-
- do {
-
- /* skip version record */
- if ( data.size > 1 ) {
- /* skip salt */
- if ( key.size == ( sizeof(SALT_STRING) - 1 ) ) {
- if ( PORT_Memcmp(key.data, SALT_STRING, key.size) == 0 ) {
- continue;
- }
- }
- /* skip pw check entry */
- if ( key.size == checkKey.size ) {
- if ( PORT_Memcmp(key.data, checkKey.data, key.size) == 0 ) {
- continue;
- }
- }
- dbkey = decode_dbkey(&data, 3);
- if ( dbkey == NULL ) {
- continue;
- }
- SHA1_HashBuf(buf,key.data,key.size);
- newKey.data = buf;
- newKey.size = SHA1_LENGTH;
-
- rv = put_dbkey(handle, &newKey, dbkey, PR_FALSE);
-
- sec_destroy_dbkey(dbkey);
-
- }
- } while ( (* handle->updatedb->seq)(handle->updatedb, &key, &data,
- R_NEXT) == 0 );
-
-done:
- /* sync the database */
- ret = (* handle->db->sync)(handle->db, 0);
-
- (* handle->updatedb->close)(handle->updatedb);
- handle->updatedb = NULL;
-
- if ( oldSalt ) {
- SECITEM_FreeItem(oldSalt, PR_TRUE);
- }
- return(SECSuccess);
-}
-#endif
-
static PRBool
seckey_HasAServerKey(DB *db)
{
@@ -973,11 +831,9 @@ done:
return(SECSuccess);
}
-
-
-
NSSLOWKEYDBHandle *
-nsslowkey_OpenKeyDB(PRBool readOnly, NSSLOWKEYDBNameFunc namecb, void *cbarg)
+nsslowkey_OpenKeyDB(PRBool readOnly, const char *appName, const char *prefix,
+ NSSLOWKEYDBNameFunc namecb, void *cbarg)
{
NSSLOWKEYDBHandle *handle;
int ret;
@@ -991,12 +847,8 @@ nsslowkey_OpenKeyDB(PRBool readOnly, NSSLOWKEYDBNameFunc namecb, void *cbarg)
PORT_SetError (SEC_ERROR_NO_MEMORY);
return NULL;
}
-
- if ( readOnly ) {
- openflags = O_RDONLY;
- } else {
- openflags = O_RDWR;
- }
+
+ openflags = readOnly ? NO_RDONLY : NO_RDWR;
dbname = (*namecb)(cbarg, NSSLOWKEY_DB_FILE_VERSION);
if ( dbname == NULL ) {
@@ -1005,8 +857,12 @@ nsslowkey_OpenKeyDB(PRBool readOnly, NSSLOWKEYDBNameFunc namecb, void *cbarg)
handle->dbname = PORT_Strdup(dbname);
handle->readOnly = readOnly;
-
- handle->db = dbopen( dbname, openflags, 0600, DB_HASH, 0 );
+
+ if (appName) {
+ handle->db = rdbopen( appName, prefix, "key", openflags);
+ } else {
+ handle->db = dbopen( dbname, openflags, 0600, DB_HASH, 0 );
+ }
/* check for correct version number */
if (handle->db != NULL) {
@@ -1025,40 +881,31 @@ nsslowkey_OpenKeyDB(PRBool readOnly, NSSLOWKEYDBNameFunc namecb, void *cbarg)
}
newdb:
-
+
/* if first open fails, try to create a new DB */
if ( handle->db == NULL ) {
-#ifdef NSS_USE_KEY4_DB
- char *dbname3 = (*namecb)(cbarg, 3);
-
- if ( readOnly ) {
- if (dbname3 == NULL) {
- goto loser;
- }
- handle->db = dbopen( dbname3, O_RDONLY, 0600, DB_HASH, 0 );
- PORT_Free(handle->dbname);
- handle->dbname = dbname3;
- dbname3 = NULL;
- if (handle->db == NULL) {
- goto loser;
- }
- handle->version = nsslowkey_version(handle->db);
- if (handle->version != 3) {
- /* bogus version number record, reset the database */
- (* handle->db->close)( handle->db );
- handle->db = NULL;
- goto loser;
- }
- goto done;
- }
-#else
if ( readOnly ) {
goto loser;
}
-#endif
-
- handle->db = dbopen( dbname,
- O_RDWR | O_CREAT | O_TRUNC, 0600, DB_HASH, 0 );
+
+ if (appName) {
+ handle->db = rdbopen( appName, prefix, "key", NO_CREATE);
+ handle->updatedb = dbopen( dbname, NO_RDONLY, 0600, DB_HASH, 0 );
+ if (handle->updatedb) {
+ handle->version = nsslowkey_version(handle->updatedb);
+ if (handle->version != NSSLOWKEY_DB_FILE_VERSION) {
+ (*handle->updatedb->close)(handle->updatedb);
+ handle->updatedb = NULL;
+ } else {
+ db_Copy(handle->db, handle->updatedb);
+ (*handle->updatedb->close)(handle->updatedb);
+ handle->updatedb = NULL;
+ goto done;
+ }
+ }
+ } else {
+ handle->db = dbopen( dbname, NO_CREATE, 0600, DB_HASH, 0 );
+ }
PORT_Free( dbname );
dbname = NULL;
@@ -1072,28 +919,12 @@ newdb:
if ( rv != SECSuccess ) {
goto loser;
}
-
-#ifdef NSS_USE_KEY4_DB
- handle->updatedb = dbopen( dbname3, O_RDONLY, 0600, DB_HASH, 0 );
- PORT_Free(dbname3);
- dbname3 = NULL;
- if (handle->updatedb) {
- /*
- * copy the key data, all the real work happens in pass2
- */
- rv = nsslowkey_UpdateKey3DBPass1(handle);
- if ( rv == SECSuccess ) {
- updated = PR_TRUE;
- }
- goto skip_v2_db;
- }
-#endif /* NSS_USE_KEY4_DB */
/*
* try to update from v2 db
*/
dbname = (*namecb)(cbarg, 2);
if ( dbname != NULL ) {
- handle->updatedb = dbopen( dbname, O_RDONLY, 0600, DB_HASH, 0 );
+ handle->updatedb = dbopen( dbname, NO_RDONLY, 0600, DB_HASH, 0 );
PORT_Free( dbname );
dbname = NULL;
@@ -1112,9 +943,6 @@ newdb:
}
-#ifdef NSS_USE_KEY4_DB
-skip_v2_db:
-#endif
/* we are using the old salt if we updated from an old db */
if ( ! updated ) {
rv = makeGlobalSalt(handle);
@@ -1130,9 +958,8 @@ skip_v2_db:
}
}
-#ifdef NSS_USE_KEY4_DB
done:
-#endif
+
handle->global_salt = GetKeyDBGlobalSalt(handle);
if ( dbname )
PORT_Free( dbname );
@@ -2557,8 +2384,7 @@ nsslowkey_ResetKeyDB(NSSLOWKEYDBHandle *handle)
}
(* handle->db->close)(handle->db);
- handle->db = dbopen( handle->dbname,
- O_RDWR | O_CREAT | O_TRUNC, 0600, DB_HASH, 0 );
+ handle->db = dbopen( handle->dbname, NO_CREATE, 0600, DB_HASH, 0 );
if (handle->db == NULL) {
/* set an error code */
return SECFailure;
diff --git a/security/nss/lib/softoken/lowkeyi.h b/security/nss/lib/softoken/lowkeyi.h
index ccece767e..e1af7b0d1 100644
--- a/security/nss/lib/softoken/lowkeyi.h
+++ b/security/nss/lib/softoken/lowkeyi.h
@@ -66,11 +66,11 @@ typedef char * (* NSSLOWKEYDBNameFunc)(void *arg, int dbVersion);
** Open a key database.
*/
extern NSSLOWKEYDBHandle *nsslowkey_OpenKeyDB(PRBool readOnly,
+ const char *domain,
+ const char *prefix,
NSSLOWKEYDBNameFunc namecb,
void *cbarg);
-extern NSSLOWKEYDBHandle *nsslowkey_OpenKeyDBFilename(char *filename,
- PRBool readOnly);
/*
* Clear out all the keys in the existing database
diff --git a/security/nss/lib/softoken/lowpbe.c b/security/nss/lib/softoken/lowpbe.c
index 51831b4db..c858e9719 100644
--- a/security/nss/lib/softoken/lowpbe.c
+++ b/security/nss/lib/softoken/lowpbe.c
@@ -867,7 +867,7 @@ sec_pkcs5_des(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_des,
encrypt);
if(ctxt != NULL) {
- rv = ((encrypt != PR_TRUE) ? DES_Decrypt : DES_Encrypt)(
+ rv = (encrypt ? DES_Encrypt : DES_Decrypt)(
ctxt, dest->data, &dest->len,
dup_src->len + 64, dup_src->data, dup_src->len);
@@ -947,7 +947,7 @@ sec_pkcs5_rc2(SECItem *key, SECItem *iv, SECItem *src, PRBool dummy,
NSS_RC2_CBC, key->len);
if(ctxt != NULL) {
- rv = ((encrypt != PR_TRUE) ? RC2_Decrypt : RC2_Encrypt)(
+ rv = (encrypt ? RC2_Encrypt: RC2_Decrypt)(
ctxt, dest->data, &dest->len,
dup_src->len + 64, dup_src->data, dup_src->len);
@@ -1004,7 +1004,7 @@ sec_pkcs5_rc4(SECItem *key, SECItem *iv, SECItem *src, PRBool dummy_op,
ctxt = RC4_CreateContext(key->data, key->len);
if(ctxt) {
- rv = ((encrypt != PR_FALSE) ? RC4_Decrypt : RC4_Encrypt)(
+ rv = (encrypt ? RC4_Encrypt : RC4_Decrypt)(
ctxt, dest->data, &dest->len,
src->len + 64, src->data, src->len);
RC4_DestroyContext(ctxt, PR_TRUE);
diff --git a/security/nss/lib/softoken/manifest.mn b/security/nss/lib/softoken/manifest.mn
index 59da34782..1649cd0f1 100644
--- a/security/nss/lib/softoken/manifest.mn
+++ b/security/nss/lib/softoken/manifest.mn
@@ -40,15 +40,7 @@ LIBRARY_NAME = softokn
LIBRARY_VERSION = 3
MAPFILE = $(OBJDIR)/softokn.def
-#
-# turn this on to get key4 generation and use.
-#
-# key4.db is properly indexed so we don't have to do db traversals to find keys.
-# turning on key4.db will automatically upgrade to key4 on startup if we open
-# the directory R/W and key4.db doesn't exist. If we open the directory up
-# R/O it opens and used the old key3.db without any update at all.
-#
-#DEFINES += -DNSS_USE_KEY4_DB
+DEFINES += -DSHLIB_SUFFIX=\"${DLL_SUFFIX}\"
EXPORTS = \
diff --git a/security/nss/lib/softoken/pcert.h b/security/nss/lib/softoken/pcert.h
index d7e48004e..c1d9b3128 100644
--- a/security/nss/lib/softoken/pcert.h
+++ b/security/nss/lib/softoken/pcert.h
@@ -139,6 +139,7 @@ nsslowcert_DestroyDBEntry(certDBEntry *entry);
SECStatus
nsslowcert_OpenCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
+ const char *domain, const char *prefix,
NSSLOWCERTDBNameFunc namecb, void *cbarg, PRBool openVolatile);
void
diff --git a/security/nss/lib/softoken/pcertdb.c b/security/nss/lib/softoken/pcertdb.c
index b392d36a3..bd50e00e1 100644
--- a/security/nss/lib/softoken/pcertdb.c
+++ b/security/nss/lib/softoken/pcertdb.c
@@ -541,7 +541,7 @@ static SECStatus
DecodeDBCertEntry(certDBEntryCert *entry, SECItem *dbentry)
{
unsigned int nnlen;
- int headerlen;
+ unsigned int headerlen;
int lenoff;
/* allow updates of old versions of the database */
@@ -2602,6 +2602,7 @@ ReadDBVersionEntry(NSSLOWCERTCertDBHandle *handle)
certDBEntryVersion *entry;
SECItem dbkey;
SECItem dbentry;
+ SECStatus rv;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if ( arena == NULL ) {
@@ -2633,7 +2634,10 @@ ReadDBVersionEntry(NSSLOWCERTCertDBHandle *handle)
PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], SEC_DB_VERSION_KEY,
SEC_DB_VERSION_KEY_LEN);
- ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);
+ rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
PORT_FreeArena(tmparena, PR_FALSE);
return(entry);
@@ -2758,11 +2762,11 @@ AddPermSubjectNode(certDBEntrySubject *entry, NSSLOWCERTCertificate *cert,
char *nickname)
{
SECItem *newCertKeys, *newKeyIDs;
- int i;
+ unsigned int i;
SECStatus rv;
NSSLOWCERTCertificate *cmpcert;
unsigned int nnlen;
- int ncerts;
+ unsigned int ncerts;
PORT_Assert(entry);
@@ -2860,7 +2864,7 @@ nsslowcert_TraversePermCertsForSubject(NSSLOWCERTCertDBHandle *handle,
NSSLOWCERTCertCallback cb, void *cbarg)
{
certDBEntrySubject *entry;
- int i;
+ unsigned int i;
NSSLOWCERTCertificate *cert;
SECStatus rv = SECSuccess;
@@ -3012,6 +3016,8 @@ nsslowcert_AddPermNickname(NSSLOWCERTCertDBHandle *dbhandle,
if (entry == NULL) goto loser;
if ( entry->nickname == NULL ) {
+ certDBEntryNickname *nicknameEntry = NULL;
+
/* no nickname for subject */
rv = AddNicknameToSubject(dbhandle, cert, nickname);
if ( rv != SECSuccess ) {
@@ -3021,6 +3027,15 @@ nsslowcert_AddPermNickname(NSSLOWCERTCertDBHandle *dbhandle,
if ( rv != SECSuccess ) {
goto loser;
}
+ nicknameEntry = NewDBNicknameEntry(nickname, &cert->derSubject, 0);
+ if ( nicknameEntry == NULL ) {
+ goto loser;
+ }
+
+ rv = WriteDBNicknameEntry(dbhandle, nicknameEntry);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
} else {
/* subject already has a nickname */
rv = AddNicknameToPermCert(dbhandle, cert, entry->nickname);
@@ -3535,13 +3550,24 @@ nsslowcert_CertNicknameConflict(char *nickname, SECItem *derSubject,
return(rv);
}
+#ifdef DBM_USING_NSPR
+#define NO_RDONLY PR_RDONLY
+#define NO_RDWR PR_RDWR
+#define NO_CREATE (PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE)
+#else
+#define NO_RDONLY O_RDONLY
+#define NO_RDWR O_RDWR
+#define NO_CREATE (O_RDWR | O_CREAT | O_TRUNC)
+#endif
+
/*
* Open the certificate database and index databases. Create them if
* they are not there or bad.
*/
static SECStatus
nsslowcert_OpenPermCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
- NSSLOWCERTDBNameFunc namecb, void *cbarg)
+ const char *appName, const char *prefix,
+ NSSLOWCERTDBNameFunc namecb, void *cbarg)
{
SECStatus rv;
int openflags;
@@ -3556,17 +3582,17 @@ nsslowcert_OpenPermCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
if ( certdbname == NULL ) {
return(SECFailure);
}
-
- if ( readOnly ) {
- openflags = O_RDONLY;
- } else {
- openflags = O_RDWR;
- }
-
+
+ openflags = readOnly ? NO_RDONLY : NO_RDWR;
+
/*
* first open the permanent file based database.
*/
- handle->permCertDB = dbopen( certdbname, openflags, 0600, DB_HASH, 0 );
+ if (appName) {
+ handle->permCertDB = rdbopen( appName, prefix, "cert", openflags);
+ } else {
+ handle->permCertDB = dbopen( certdbname, openflags, 0600, DB_HASH, 0 );
+ }
/* check for correct version number */
if ( handle->permCertDB ) {
@@ -3587,7 +3613,6 @@ nsslowcert_OpenPermCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
}
}
-
/* if first open fails, try to create a new DB */
if ( handle->permCertDB == NULL ) {
@@ -3596,9 +3621,19 @@ nsslowcert_OpenPermCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
goto loser;
}
- handle->permCertDB = dbopen(certdbname,
- O_RDWR | O_CREAT | O_TRUNC,
- 0600, DB_HASH, 0);
+ if (appName) {
+ handle->permCertDB=rdbopen( appName, prefix, "cert", NO_CREATE);
+
+ updatedb = dbopen(certdbname, NO_RDONLY, 0600, DB_HASH, 0);
+ if (updatedb) {
+ db_Copy(handle->permCertDB,updatedb);
+ (*updatedb->close)(updatedb);
+ PORT_Free(certdbname);
+ return(SECSuccess);
+ }
+ } else {
+ handle->permCertDB=dbopen(certdbname, NO_CREATE, 0600, DB_HASH, 0);
+ }
/* if create fails then we lose */
if ( handle->permCertDB == 0 ) {
@@ -3621,7 +3656,7 @@ nsslowcert_OpenPermCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
/* try to upgrade old db here */
tmpname = (* namecb)(cbarg, 6); /* get v6 db name */
if ( tmpname ) {
- updatedb = dbopen( tmpname, O_RDONLY, 0600, DB_HASH, 0 );
+ updatedb = dbopen( tmpname, NO_RDONLY, 0600, DB_HASH, 0 );
PORT_Free(tmpname);
if ( updatedb ) {
rv = UpdateV6DB(handle, updatedb);
@@ -3632,7 +3667,7 @@ nsslowcert_OpenPermCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
} else { /* no v6 db, so try v5 db */
tmpname = (* namecb)(cbarg, 5); /* get v5 db name */
if ( tmpname ) {
- updatedb = dbopen( tmpname, O_RDONLY, 0600, DB_HASH, 0 );
+ updatedb = dbopen( tmpname, NO_RDONLY, 0600, DB_HASH, 0 );
PORT_Free(tmpname);
if ( updatedb ) {
rv = UpdateV5DB(handle, updatedb);
@@ -3644,8 +3679,8 @@ nsslowcert_OpenPermCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
/* try to upgrade v4 db */
tmpname = (* namecb)(cbarg, 4); /* get v4 db name */
if ( tmpname ) {
- updatedb = dbopen( tmpname, O_RDONLY, 0600,
- DB_HASH, 0 );
+ updatedb = dbopen( tmpname, NO_RDONLY, 0600,
+ DB_HASH, 0 );
PORT_Free(tmpname);
if ( updatedb ) {
/* NES has v5 db's with v4 db names! */
@@ -4045,6 +4080,7 @@ done:
*/
SECStatus
nsslowcert_OpenCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
+ const char *appName, const char *prefix,
NSSLOWCERTDBNameFunc namecb, void *cbarg, PRBool openVolatile)
{
int rv;
@@ -4054,7 +4090,8 @@ nsslowcert_OpenCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
handle->dbMon = PZ_NewMonitor(nssILockCertDB);
PORT_Assert(handle->dbMon != NULL);
- rv = nsslowcert_OpenPermCertDB(handle, readOnly, namecb, cbarg);
+ rv = nsslowcert_OpenPermCertDB(handle, readOnly, appName, prefix,
+ namecb, cbarg);
if ( rv ) {
goto loser;
}
diff --git a/security/nss/lib/softoken/pk11db.c b/security/nss/lib/softoken/pk11db.c
index fcc906d06..69376db1e 100644
--- a/security/nss/lib/softoken/pk11db.c
+++ b/security/nss/lib/softoken/pk11db.c
@@ -39,6 +39,7 @@
#include "pk11pars.h"
#include "pkcs11i.h"
#include "mcom_db.h"
+#include "cdbhdl.h"
#define FREE_CLEAR(p) if (p) { PORT_Free(p); p = NULL; }
@@ -247,13 +248,14 @@ secmod_freeParams(pk11_parameters *params)
char *
-secmod_getSecmodName(char *param, PRBool *rw)
+secmod_getSecmodName(char *param, char **appName, char **filename,PRBool *rw)
{
int next;
char *configdir = NULL;
char *secmodName = NULL;
char *value = NULL;
char *save_params = param;
+ const char *lconfigdir;
param = pk11_argStrip(param);
@@ -268,13 +270,15 @@ secmod_getSecmodName(char *param, PRBool *rw)
pk11_argHasFlag("flags","noModDB",save_params)) *rw = PR_FALSE;
if (!secmodName || *secmodName == '\0') secmodName = PORT_Strdup(SECMOD_DB);
+ *filename = secmodName;
- if (configdir) {
- value = PR_smprintf("%s" PATH_SEPARATOR "%s",configdir,secmodName);
+ lconfigdir = pk11_EvaluateConfigDir(configdir, appName);
+
+ if (lconfigdir) {
+ value = PR_smprintf("%s" PATH_SEPARATOR "%s",lconfigdir,secmodName);
} else {
- value = PORT_Strdup(secmodName);
+ value = PR_smprintf("%s",secmodName);
}
- PORT_Free(secmodName);
if (configdir) PORT_Free(configdir);
return value;
}
@@ -296,7 +300,9 @@ static SECStatus secmod_MakeKey(DBT *key, char * module) {
}
/* free out constructed database key */
-static void secmod_FreeKey(DBT *key) {
+static void
+secmod_FreeKey(DBT *key)
+{
if (key->data) {
PORT_Free(key->data);
}
@@ -359,7 +365,9 @@ struct secmodSlotDataStr {
/*
* build a data base entry from a module
*/
-static SECStatus secmod_EncodeData(DBT *data, char * module) {
+static SECStatus
+secmod_EncodeData(DBT *data, char * module)
+{
secmodData *encoded = NULL;
secmodSlotData *slot;
unsigned char *dataPtr;
@@ -437,7 +445,7 @@ static SECStatus secmod_EncodeData(DBT *data, char * module) {
SECMOD_PUTLONG(encoded->ssl,ssl[0]);
SECMOD_PUTLONG(&encoded->ssl[4],ssl[1]);
- offset = (unsigned long) &(((secmodData *)0)->names[0]);
+ offset = (unsigned short) &(((secmodData *)0)->names[0]);
SECMOD_PUTSHORT(encoded->nameStart,offset);
offset = offset + len + len2 + len3 + 3*sizeof(unsigned short);
SECMOD_PUTSHORT(encoded->slotOffset,offset);
@@ -611,8 +619,10 @@ secmod_DecodeData(char *defParams, DBT *data, PRBool *retInternal)
trustOrder = 100;
}
- slotStrings[i] = pk11_mkSlotString(slotID,defaultFlags,
- timeout,slots[i].askpw,hasRootCerts,hasRootTrust);
+ slotStrings[i] = pk11_mkSlotString(slotID, defaultFlags, timeout,
+ (unsigned char)slots[i].askpw,
+ (unsigned char)hasRootCerts,
+ (unsigned char)hasRootTrust);
}
nss = pk11_mkNSS(slotStrings, slotCount, internal, isFIPS, isModuleDB,
@@ -626,24 +636,61 @@ secmod_DecodeData(char *defParams, DBT *data, PRBool *retInternal)
-static DB *secmod_OpenDB(char *dbName, PRBool readOnly) {
+static DB *
+secmod_OpenDB(const char *appName, const char *filename, const char *dbName,
+ PRBool readOnly, PRBool update)
+{
DB *pkcs11db = NULL;
-
+
+
+ if (appName) {
+ char *secname = PORT_Strdup(filename);
+ int len = strlen(secname);
+
+ if (len >= 3 && PORT_Strcmp(&secname[len-3],".db") == 0) {
+ secname[len-3] = 0;
+ }
+ pkcs11db=rdbopen(appName, "", secname, readOnly ? NO_RDONLY:NO_CREATE);
+ if (update && !pkcs11db) {
+ DB *updatedb;
+
+ pkcs11db = rdbopen(appName, "", secname, NO_CREATE);
+ if (!pkcs11db) {
+ PORT_Free(secname);
+ return NULL;
+ }
+ updatedb = dbopen(dbName, NO_RDONLY, 0600, DB_HASH, 0);
+ if (updatedb) {
+ db_Copy(pkcs11db,updatedb);
+ (*updatedb->close)(updatedb);
+ } else {
+ (*pkcs11db->close)(pkcs11db);
+ PORT_Free(secname);
+ return NULL;
+ }
+ }
+ PORT_Free(secname);
+ return pkcs11db;
+ }
+
/* I'm sure we should do more checks here sometime... */
- pkcs11db = dbopen(dbName, readOnly ? O_RDONLY : O_RDWR, 0600, DB_HASH, 0);
+ pkcs11db = dbopen(dbName, readOnly ? NO_RDONLY : NO_RDWR, 0600, DB_HASH, 0);
/* didn't exist? create it */
if (pkcs11db == NULL) {
- if (readOnly) return NULL;
+ if (readOnly)
+ return NULL;
- pkcs11db = dbopen( dbName,
- O_RDWR | O_CREAT | O_TRUNC, 0600, DB_HASH, 0 );
- if (pkcs11db) (* pkcs11db->sync)(pkcs11db, 0);
+ pkcs11db = dbopen( dbName, NO_CREATE, 0600, DB_HASH, 0 );
+ if (pkcs11db)
+ (* pkcs11db->sync)(pkcs11db, 0);
}
return pkcs11db;
}
-static void secmod_CloseDB(DB *pkcs11db) {
+static void
+secmod_CloseDB(DB *pkcs11db)
+{
(*pkcs11db->close)(pkcs11db);
}
@@ -676,12 +723,14 @@ secmod_addEscape(const char *string, char quote)
}
#define SECMOD_STEP 10
-#define PK11_DEFAULT_INTERNAL_INIT "library= name=\"NSS Internal PKCS #11 Module\" parameters=\"%s\" NSS=\"Flags=internal,critical trustOrder=0 cipherOrder=100 slotParams=(1={%s askpw=any timeout=30})\""
+#define PK11_DEFAULT_INTERNAL_INIT "library= name=\"NSS Internal PKCS #11 Module\" parameters=\"%s\" NSS=\"Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={%s askpw=any timeout=30})\""
/*
* Read all the existing modules in
*/
char **
-secmod_ReadPermDB(char *dbname, char *params, PRBool rw) {
+secmod_ReadPermDB(const char *appName, const char *filename,
+ const char *dbname, char *params, PRBool rw)
+{
DBT key,data;
int ret;
DB *pkcs11db = NULL;
@@ -692,7 +741,7 @@ secmod_ReadPermDB(char *dbname, char *params, PRBool rw) {
moduleList = (char **) PORT_ZAlloc(useCount*sizeof(char **));
if (moduleList == NULL) return NULL;
- pkcs11db = secmod_OpenDB(dbname,PR_TRUE);
+ pkcs11db = secmod_OpenDB(appName,filename,dbname,PR_TRUE,rw);
if (pkcs11db == NULL) goto done;
/* read and parse the file or data base */
@@ -734,16 +783,30 @@ done:
if (pkcs11db) {
secmod_CloseDB(pkcs11db);
} else {
- secmod_AddPermDB(dbname,moduleList[0], rw) ;
+ secmod_AddPermDB(appName,filename,dbname,moduleList[0], rw) ;
}
return moduleList;
}
+SECStatus
+secmod_ReleasePermDBData(const char *appName, const char *filename,
+ const char *dbname, char **moduleSpecList, PRBool rw)
+{
+ char **index;
+ for(index = moduleSpecList; *index; index++) {
+ PR_smprintf_free(*index);
+ }
+ PORT_Free(moduleSpecList);
+ return SECSuccess;
+}
+
/*
* Delete a module from the Data Base
*/
SECStatus
-secmod_DeletePermDB(char *dbname, char *args, PRBool rw) {
+secmod_DeletePermDB(const char *appName, const char *filename,
+ const char *dbname, char *args, PRBool rw)
+{
DBT key;
SECStatus rv = SECFailure;
DB *pkcs11db = NULL;
@@ -752,7 +815,7 @@ secmod_DeletePermDB(char *dbname, char *args, PRBool rw) {
if (!rw) return SECFailure;
/* make sure we have a db handle */
- pkcs11db = secmod_OpenDB(dbname,PR_FALSE);
+ pkcs11db = secmod_OpenDB(appName,filename,dbname,PR_FALSE,PR_FALSE);
if (pkcs11db == NULL) {
return SECFailure;
}
@@ -777,7 +840,9 @@ done:
* Add a module to the Data base
*/
SECStatus
-secmod_AddPermDB(char *dbname, char *module, PRBool rw) {
+secmod_AddPermDB(const char *appName, const char *filename,
+ const char *dbname, char *module, PRBool rw)
+{
DBT key,data;
SECStatus rv = SECFailure;
DB *pkcs11db = NULL;
@@ -787,7 +852,7 @@ secmod_AddPermDB(char *dbname, char *module, PRBool rw) {
if (!rw) return SECFailure;
/* make sure we have a db handle */
- pkcs11db = secmod_OpenDB(dbname,PR_FALSE);
+ pkcs11db = secmod_OpenDB(appName,filename,dbname,PR_FALSE,PR_FALSE);
if (pkcs11db == NULL) {
return SECFailure;
}
diff --git a/security/nss/lib/softoken/pk11pars.h b/security/nss/lib/softoken/pk11pars.h
index 389599a9d..309313f66 100644
--- a/security/nss/lib/softoken/pk11pars.h
+++ b/security/nss/lib/softoken/pk11pars.h
@@ -692,7 +692,7 @@ pk11_mkSlotFlags(unsigned long defaultFlags)
char *string = NULL;
for (j=0; j < pk11_argSlotFlagTableSize; j++) {
- if (pk11_argSlotFlagTable[j].value == (1<<i)) {
+ if (pk11_argSlotFlagTable[j].value == (((unsigned long)1)<<i)) {
string = pk11_argSlotFlagTable[j].name;
break;
}
diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c
index e8beefac9..2a6a43a85 100644
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -605,7 +605,8 @@ pk11_handleCertObject(PK11Session *session,PK11Object *object)
NSSLOWCERTCertTrust defTrust =
{ CERTDB_TRUSTED_UNKNOWN,
CERTDB_TRUSTED_UNKNOWN, CERTDB_TRUSTED_UNKNOWN };
- char *label;
+ char *label = NULL;
+ char *email = NULL;
SECStatus rv;
PRBool inDB = PR_TRUE;
@@ -646,10 +647,28 @@ pk11_handleCertObject(PK11Session *session,PK11Object *object)
if (label) PORT_Free(label);
pk11_FreeAttribute(attribute);
+
if (rv != SECSuccess) {
nsslowcert_DestroyCertificate(cert);
return CKR_DEVICE_ERROR;
}
+
+ /*
+ * Add a NULL S/MIME profile if necessary.
+ */
+ email = pk11_getString(object,CKA_NETSCAPE_EMAIL);
+ if (email) {
+ certDBEntrySMime *entry;
+
+ entry = nsslowcert_ReadDBSMimeEntry(slot->certDB,email);
+ if (!entry) {
+ nsslowcert_SaveSMimeProfile(slot->certDB, email,
+ &cert->derSubject, NULL, NULL);
+ } else {
+ nsslowcert_DestroyDBEntry((certDBEntry *)entry);
+ }
+ PORT_Free(email);
+ }
object->handle=pk11_mkHandle(slot,&cert->certKey,PK11_TOKEN_TYPE_CERT);
nsslowcert_DestroyCertificate(cert);
}
@@ -1705,7 +1724,7 @@ pk11_mkPrivKey(PK11Object *object,CK_KEY_TYPE key_type)
if (arena == NULL) return NULL;
privKey = (NSSLOWKEYPrivateKey *)
- PORT_ArenaAlloc(arena,sizeof(NSSLOWKEYPrivateKey));
+ PORT_ArenaZAlloc(arena,sizeof(NSSLOWKEYPrivateKey));
if (privKey == NULL) {
PORT_FreeArena(arena,PR_FALSE);
return NULL;
@@ -1893,7 +1912,7 @@ pk11_mkSecretKeyRep(PK11Object *object)
if (arena == NULL) { crv = CKR_HOST_MEMORY; goto loser; }
privKey = (NSSLOWKEYPrivateKey *)
- PORT_ArenaAlloc(arena,sizeof(NSSLOWKEYPrivateKey));
+ PORT_ArenaZAlloc(arena,sizeof(NSSLOWKEYPrivateKey));
if (privKey == NULL) { crv = CKR_HOST_MEMORY; goto loser; }
privKey->arena = arena;
@@ -2037,57 +2056,81 @@ pk11_getDefSlotName(CK_SLOT_ID slotID)
return buf;
}
-static CK_ULONG nscSlotCount = 0;
-static CK_SLOT_ID_PTR nscSlotList = NULL;
-static CK_ULONG nscSlotListSize = 0;
-static PLHashTable *nscSlotHashTable = NULL;
+static CK_ULONG nscSlotCount[2] = {0 , 0};
+static CK_SLOT_ID_PTR nscSlotList[2] = {NULL, NULL};
+static CK_ULONG nscSlotListSize[2] = {0, 0};
+static PLHashTable *nscSlotHashTable[2] = {NULL, NULL};
+
+static int
+pk11_GetModuleIndex(CK_SLOT_ID slotID)
+{
+ if ((slotID == FIPS_SLOT_ID) || (slotID > 100)) {
+ return NSC_FIPS_MODULE;
+ }
+ return NSC_NON_FIPS_MODULE;
+}
/* look up a slot structure from the ID (used to be a macro when we only
* had two slots) */
PK11Slot *
pk11_SlotFromID(CK_SLOT_ID slotID)
{
- return (PK11Slot *)PL_HashTableLookupConst(nscSlotHashTable, (void *)slotID);
+ int index = pk11_GetModuleIndex(slotID);
+ return (PK11Slot *)PL_HashTableLookupConst(nscSlotHashTable[index],
+ (void *)slotID);
}
PK11Slot *
pk11_SlotFromSessionHandle(CK_SESSION_HANDLE handle)
{
- int slotIDIndex = (handle >> 24) & 0xff;
+ CK_ULONG slotIDIndex = (handle >> 24) & 0x7f;
+ CK_ULONG moduleIndex = (handle >> 31) & 1;
- if (slotIDIndex >= nscSlotCount) {
+ if (slotIDIndex >= nscSlotCount[moduleIndex]) {
return NULL;
}
- return pk11_SlotFromID(nscSlotList[slotIDIndex]);
+ return pk11_SlotFromID(nscSlotList[moduleIndex][slotIDIndex]);
}
-PK11Slot * pk11_NewSlotFromID(CK_SLOT_ID slotID)
+PK11Slot * pk11_NewSlotFromID(CK_SLOT_ID slotID, int moduleIndex)
{
PK11Slot *slot = NULL;
PLHashEntry *entry;
+ int index;
- if (nscSlotList == NULL) {
- nscSlotListSize = NSC_SLOT_LIST_BLOCK_SIZE;
- nscSlotList = (CK_SLOT_ID *)
- PORT_ZAlloc(nscSlotListSize*sizeof(CK_SLOT_ID));
- if (nscSlotList == NULL) {
+ index = pk11_GetModuleIndex(slotID);
+
+ /* make sure the slotID for this module is valid */
+ if (moduleIndex != index) {
+ return NULL;
+ }
+
+ if (nscSlotList[index] == NULL) {
+ nscSlotListSize[index] = NSC_SLOT_LIST_BLOCK_SIZE;
+ nscSlotList[index] = (CK_SLOT_ID *)
+ PORT_ZAlloc(nscSlotListSize[index]*sizeof(CK_SLOT_ID));
+ if (nscSlotList[index] == NULL) {
return NULL;
}
}
- if (nscSlotCount >= nscSlotListSize) {
- nscSlotListSize += NSC_SLOT_LIST_BLOCK_SIZE;
- nscSlotList = (CK_SLOT_ID *) PORT_Realloc(nscSlotList,
- nscSlotListSize*sizeof(CK_SLOT_ID));
- if (nscSlotList == NULL) {
- return NULL;
+ if (nscSlotCount[index] >= nscSlotListSize[index]) {
+ CK_SLOT_ID* oldNscSlotList = nscSlotList[index];
+ CK_ULONG oldNscSlotListSize = nscSlotListSize[index];
+ nscSlotListSize[index] += NSC_SLOT_LIST_BLOCK_SIZE;
+ nscSlotList[index] = (CK_SLOT_ID *) PORT_Realloc(oldNscSlotList,
+ nscSlotListSize[index]*sizeof(CK_SLOT_ID));
+ if (nscSlotList[index] == NULL) {
+ nscSlotList[index] = oldNscSlotList;
+ nscSlotListSize[index] = oldNscSlotListSize;
+ return NULL;
}
}
- if (nscSlotHashTable == NULL) {
- nscSlotHashTable = PL_NewHashTable(64,pk11_HashNumber,PL_CompareValues,
- PL_CompareValues, NULL, 0);
- if (nscSlotHashTable == NULL) {
+ if (nscSlotHashTable[index] == NULL) {
+ nscSlotHashTable[index] = PL_NewHashTable(64,pk11_HashNumber,
+ PL_CompareValues, PL_CompareValues, NULL, 0);
+ if (nscSlotHashTable[index] == NULL) {
return NULL;
}
}
@@ -2097,13 +2140,13 @@ PK11Slot * pk11_NewSlotFromID(CK_SLOT_ID slotID)
return NULL;
}
- entry = PL_HashTableAdd(nscSlotHashTable,(void *)slotID,slot);
+ entry = PL_HashTableAdd(nscSlotHashTable[index],(void *)slotID,slot);
if (entry == NULL) {
PORT_Free(slot);
return NULL;
}
- slot->index = nscSlotCount;
- nscSlotList[nscSlotCount++] = slotID;
+ slot->index = (nscSlotCount[index] & 0x7f) | ((index << 7) & 0x80);
+ nscSlotList[index][nscSlotCount[index]++] = slotID;
return slot;
}
@@ -2112,11 +2155,11 @@ PK11Slot * pk11_NewSlotFromID(CK_SLOT_ID slotID)
* initialize one of the slot structures. figure out which by the ID
*/
CK_RV
-PK11_SlotInit(char *configdir,pk11_token_parameters *params)
+PK11_SlotInit(char *configdir,pk11_token_parameters *params, int moduleIndex)
{
int i;
CK_SLOT_ID slotID = params->slotID;
- PK11Slot *slot = pk11_NewSlotFromID(slotID);
+ PK11Slot *slot = pk11_NewSlotFromID(slotID, moduleIndex);
PRBool needLogin = !params->noKeyDB;
CK_RV crv;
@@ -2257,34 +2300,92 @@ pk11_DestroySlotData(PK11Slot *slot)
* handle the SECMOD.db
*/
char **
-NSC_ModuleDBFunc(unsigned long function,char *parameters, char *args)
+NSC_ModuleDBFunc(unsigned long function,char *parameters, void *args)
{
- char *secmod;
+ char *secmod = NULL;
+ char *appName = NULL;
+ char *filename = NULL;
PRBool rw;
static char *success="Success";
char **rvstr = NULL;
- secmod = secmod_getSecmodName(parameters,&rw);
+ secmod = secmod_getSecmodName(parameters,&appName,&filename, &rw);
switch (function) {
case SECMOD_MODULE_DB_FUNCTION_FIND:
- rvstr = secmod_ReadPermDB(secmod,parameters,rw);
+ rvstr = secmod_ReadPermDB(appName,filename,secmod,(char *)parameters,rw);
break;
case SECMOD_MODULE_DB_FUNCTION_ADD:
- rvstr = (secmod_AddPermDB(secmod,args,rw) == SECSuccess)
- ? &success: NULL;
+ rvstr = (secmod_AddPermDB(appName,filename,secmod,(char *)args,rw)
+ == SECSuccess) ? &success: NULL;
break;
case SECMOD_MODULE_DB_FUNCTION_DEL:
- rvstr = (secmod_DeletePermDB(secmod,args,rw) == SECSuccess)
- ? &success: NULL;
+ rvstr = (secmod_DeletePermDB(appName,filename,secmod,(char *)args,rw)
+ == SECSuccess) ? &success: NULL;
+ break;
+ case SECMOD_MODULE_DB_FUNCTION_RELEASE:
+ rvstr = (secmod_ReleasePermDBData(appName,filename,secmod,
+ (char **)args,rw) == SECSuccess) ? &success: NULL;
break;
}
if (secmod) PR_smprintf_free(secmod);
+ if (appName) PORT_Free(appName);
+ if (filename) PORT_Free(filename);
return rvstr;
}
+static void nscFreeAllSlots(int moduleIndex)
+{
+ /* free all the slots */
+ PK11Slot *slot = NULL;
+ CK_SLOT_ID slotID;
+ int i;
+
+ if (nscSlotList[moduleIndex]) {
+ CK_ULONG tmpSlotCount = nscSlotCount[moduleIndex];
+ CK_SLOT_ID_PTR tmpSlotList = nscSlotList[moduleIndex];
+ PLHashTable *tmpSlotHashTable = nscSlotHashTable[moduleIndex];
+
+ /* now clear out the statics */
+ nscSlotList[moduleIndex] = NULL;
+ nscSlotCount[moduleIndex] = 0;
+ nscSlotHashTable[moduleIndex] = NULL;
+ nscSlotListSize[moduleIndex] = 0;
+
+ for (i=0; i < (int) tmpSlotCount; i++) {
+ slotID = tmpSlotList[i];
+ slot = (PK11Slot *)
+ PL_HashTableLookup(tmpSlotHashTable, (void *)slotID);
+ PORT_Assert(slot);
+ if (!slot) continue;
+ pk11_DestroySlotData(slot);
+ PL_HashTableRemove(tmpSlotHashTable, (void *)slotID);
+ }
+ PORT_Free(tmpSlotList);
+ PL_HashTableDestroy(tmpSlotHashTable);
+ }
+}
+
+static void
+pk11_closePeer(PRBool isFIPS)
+{
+ CK_SLOT_ID slotID = isFIPS ? PRIVATE_KEY_SLOT_ID: FIPS_SLOT_ID;
+ PK11Slot *slot;
+ int moduleIndex = isFIPS? NSC_NON_FIPS_MODULE : NSC_FIPS_MODULE;
+ PLHashTable *tmpSlotHashTable = nscSlotHashTable[moduleIndex];
+
+ slot = (PK11Slot *) PL_HashTableLookup(tmpSlotHashTable, (void *)slotID);
+ if (slot == NULL) {
+ return;
+ }
+ pk11_DBShutdown(slot->certDB,slot->keyDB);
+ slot->certDB = NULL;
+ slot->keyDB = NULL;
+ return;
+}
static PRBool nsc_init = PR_FALSE;
+
/* NSC_Initialize initializes the Cryptoki library. */
CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)
{
@@ -2292,10 +2393,7 @@ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)
SECStatus rv;
CK_C_INITIALIZE_ARGS *init_args = (CK_C_INITIALIZE_ARGS *) pReserved;
int i;
-
- if (nsc_init) {
- return crv;
- }
+ int moduleIndex = isFIPS? NSC_FIPS_MODULE : NSC_NON_FIPS_MODULE;
rv = RNG_RNGInit(); /* initialize random number generator */
if (rv != SECSuccess) {
@@ -2328,59 +2426,53 @@ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)
goto loser;
}
+ /* if we have a peer already open, have him close his DB's so we
+ * don't clobber each other. */
+ if ((isFIPS && nsc_init) || (!isFIPS && nsf_init)) {
+ pk11_closePeer(isFIPS);
+ }
+
for (i=0; i < paramStrings.token_count; i++) {
crv =
- PK11_SlotInit(paramStrings.configdir, &paramStrings.tokens[i]);
- if (crv != CKR_OK) break;
+ PK11_SlotInit(paramStrings.configdir, &paramStrings.tokens[i],
+ moduleIndex);
+ if (crv != CKR_OK) {
+ nscFreeAllSlots(moduleIndex);
+ break;
+ }
}
loser:
secmod_freeParams(&paramStrings);
}
- nsc_init = (PRBool) (crv == CKR_OK);
return crv;
}
CK_RV NSC_Initialize(CK_VOID_PTR pReserved)
{
- return nsc_CommonInitialize(pReserved,PR_FALSE);
+ CK_RV crv;
+ if (nsc_init) {
+ return CKR_CRYPTOKI_ALREADY_INITIALIZED;
+ }
+ crv = nsc_CommonInitialize(pReserved,PR_FALSE);
+ nsc_init = (PRBool) (crv == CKR_OK);
+ return crv;
}
/* NSC_Finalize indicates that an application is done with the
* Cryptoki library.*/
-CK_RV NSC_Finalize (CK_VOID_PTR pReserved)
+CK_RV nsc_CommonFinalize (CK_VOID_PTR pReserved, PRBool isFIPS)
{
- PK11Slot *slot = NULL;
- CK_SLOT_ID slotID;
- int i;
+
- if (!nsc_init) {
+ nscFreeAllSlots(isFIPS ? NSC_FIPS_MODULE : NSC_NON_FIPS_MODULE);
+
+ /* don't muck with the globals is our peer is still initialized */
+ if (isFIPS && nsc_init) {
return CKR_OK;
}
-
- /* free all the slots */
- if (nscSlotList) {
- CK_ULONG tmpSlotCount = nscSlotCount;
- CK_SLOT_ID_PTR tmpSlotList = nscSlotList;
- PLHashTable *tmpSlotHashTable = nscSlotHashTable;
-
- /* now clear out the statics */
- nscSlotList = NULL;
- nscSlotCount = 0;
- nscSlotHashTable = NULL;
- nscSlotListSize = 0;
-
- for (i=0; i < tmpSlotCount; i++) {
- slotID = tmpSlotList[i];
- slot = (PK11Slot *)
- PL_HashTableLookup(tmpSlotHashTable, (void *)slotID);
- PORT_Assert(slot);
- if (!slot) continue;
- pk11_DestroySlotData(slot);
- PL_HashTableRemove(tmpSlotHashTable, (void *)slotID);
- }
- PORT_Free(tmpSlotList);
- PL_HashTableDestroy(tmpSlotHashTable);
+ if (!isFIPS && nsf_init) {
+ return CKR_OK;
}
nsslowcert_DestroyGlobalLocks();
@@ -2406,6 +2498,23 @@ CK_RV NSC_Finalize (CK_VOID_PTR pReserved)
return CKR_OK;
}
+/* NSC_Finalize indicates that an application is done with the
+ * Cryptoki library.*/
+CK_RV NSC_Finalize (CK_VOID_PTR pReserved)
+{
+ CK_RV crv;
+
+ if (!nsc_init) {
+ return CKR_OK;
+ }
+
+ crv = nsc_CommonFinalize (pReserved, PR_FALSE);
+
+ nsc_init = (PRBool) !(crv == CKR_OK);
+
+ return crv;
+}
+
extern const char __nss_softokn_rcsid[];
extern const char __nss_softokn_sccsid[];
@@ -2425,16 +2534,26 @@ CK_RV NSC_GetInfo(CK_INFO_PTR pInfo)
return CKR_OK;
}
+
/* NSC_GetSlotList obtains a list of slots in the system. */
-CK_RV NSC_GetSlotList(CK_BBOOL tokenPresent,
- CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount)
+CK_RV nsc_CommonGetSlotList(CK_BBOOL tokenPresent,
+ CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount, int moduleIndex)
{
- *pulCount = nscSlotCount;
+ *pulCount = nscSlotCount[moduleIndex];
if (pSlotList != NULL) {
- PORT_Memcpy(pSlotList,nscSlotList,nscSlotCount*sizeof(CK_SLOT_ID));
+ PORT_Memcpy(pSlotList,nscSlotList[moduleIndex],
+ nscSlotCount[moduleIndex]*sizeof(CK_SLOT_ID));
}
return CKR_OK;
}
+
+/* NSC_GetSlotList obtains a list of slots in the system. */
+CK_RV NSC_GetSlotList(CK_BBOOL tokenPresent,
+ CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount)
+{
+ return nsc_CommonGetSlotList(tokenPresent, pSlotList, pulCount,
+ NSC_NON_FIPS_MODULE);
+}
/* NSC_GetSlotInfo obtains information about a particular slot in the system. */
CK_RV NSC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
@@ -2701,7 +2820,7 @@ CK_RV NSC_InitPIN(CK_SESSION_HANDLE hSession,
if (ulPinLen > PK11_MAX_PIN) {
return CKR_PIN_LEN_RANGE;
}
- if (ulPinLen < slot->minimumPinLen) {
+ if (ulPinLen < (CK_ULONG)slot->minimumPinLen) {
return CKR_PIN_LEN_RANGE;
}
@@ -2776,7 +2895,7 @@ CK_RV NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
if ((ulNewLen > PK11_MAX_PIN) || (ulOldLen > PK11_MAX_PIN)) {
return CKR_PIN_LEN_RANGE;
}
- if (ulNewLen < slot->minimumPinLen) {
+ if (ulNewLen < (CK_ULONG)slot->minimumPinLen) {
return CKR_PIN_LEN_RANGE;
}
@@ -3213,7 +3332,6 @@ CK_RV NSC_CopyObject(CK_SESSION_HANDLE hSession,
if (crv != CKR_OK) {
pk11_FreeObject(destObject);
pk11_FreeSession(session);
- return crv;
}
crv = pk11_handleObject(destObject,session);
@@ -3488,6 +3606,16 @@ pk11_key_collect(DBT *key, DBT *data, void *arg)
if (keyData->id->len == 0) {
haveMatch = PR_TRUE; /* taking any key */
+ /* Make sure this isn't a NSC_KEY */
+ privKey = nsslowkey_FindKeyByPublicKey(keyData->slot->keyDB,
+ &tmpDBKey, keyData->slot->password);
+ if (privKey) {
+ haveMatch = isSecretKey(privKey) ?
+ (PRBool)(keyData->classFlags & NSC_KEY) != 0:
+ (PRBool)(keyData->classFlags &
+ (NSC_PRIVATE|NSC_PUBLIC)) != 0;
+ nsslowkey_DestroyPrivateKey(privKey);
+ }
} else {
SHA1_HashBuf( hashKey, key->data, key->size ); /* match id */
haveMatch = SECITEM_ItemsAreEqual(keyData->id,&result);
@@ -3571,15 +3699,15 @@ pk11_searchKeys(PK11Slot *slot, SECItem *key_id, PRBool isLoggedIn,
if (key_id->data) {
privKey = nsslowkey_FindKeyByPublicKey(keyHandle, key_id, slot->password);
if (privKey) {
- if (classFlags & NSC_KEY) {
+ if ((classFlags & NSC_KEY) && isSecretKey(privKey)) {
pk11_addHandle(search,
pk11_mkHandle(slot,key_id,PK11_TOKEN_TYPE_KEY));
}
- if (classFlags & NSC_PRIVATE) {
+ if ((classFlags & NSC_PRIVATE) && !isSecretKey(privKey)) {
pk11_addHandle(search,
pk11_mkHandle(slot,key_id,PK11_TOKEN_TYPE_PRIV));
}
- if (classFlags & NSC_PUBLIC) {
+ if ((classFlags & NSC_PUBLIC) && !isSecretKey(privKey)) {
pk11_addHandle(search,
pk11_mkHandle(slot,key_id,PK11_TOKEN_TYPE_PUB));
}
diff --git a/security/nss/lib/softoken/pkcs11i.h b/security/nss/lib/softoken/pkcs11i.h
index 391f2f152..af3350cd0 100644
--- a/security/nss/lib/softoken/pkcs11i.h
+++ b/security/nss/lib/softoken/pkcs11i.h
@@ -90,6 +90,9 @@
#define NSC_SEARCH_BLOCK_SIZE 5
#define NSC_SLOT_LIST_BLOCK_SIZE 10
+#define NSC_FIPS_MODULE 1
+#define NSC_NON_FIPS_MODULE 0
+
/* these are data base storage hashes, not cryptographic hashes.. The define
* the effective size of the various object hash tables */
#ifdef MOZ_CLIENT
@@ -113,6 +116,8 @@
#endif
#define MAX_KEY_LEN 256
+#define MULTIACCESS "multiaccess:"
+
/*
* LOG2_BUCKETS_PER_SESSION_LOCK must be a prime number.
* With SESSION_HASH_SIZE=1024, LOG2 can be 9, 5, 1, or 0.
@@ -519,9 +524,14 @@ typedef struct pk11_parametersStr {
SEC_BEGIN_PROTOS
+extern int nsf_init;
extern CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS);
+extern CK_RV nsc_CommonFinalize(CK_VOID_PTR pReserved, PRBool isFIPS);
+extern CK_RV nsc_CommonGetSlotList(CK_BBOOL tokPresent,
+ CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount, int moduleIndex);
/* shared functions between PKCS11.c and PK11FIPS.c */
-extern CK_RV PK11_SlotInit(char *configdir,pk11_token_parameters *params);
+extern CK_RV PK11_SlotInit(char *configdir,pk11_token_parameters *params,
+ int moduleIndex);
/* internal utility functions used by pkcs11.c */
extern PK11Attribute *pk11_FindAttribute(PK11Object *object,
@@ -594,10 +604,16 @@ extern PRBool pk11_IsWeakKey(unsigned char *key,CK_KEY_TYPE key_type);
extern CK_RV secmod_parseParameters(char *param, pk11_parameters *parsed,
PRBool isFIPS);
extern void secmod_freeParams(pk11_parameters *params);
-extern char *secmod_getSecmodName(char *params, PRBool *rw);
-extern char ** secmod_ReadPermDB(char *dbname, char *params, PRBool rw);
-extern SECStatus secmod_DeletePermDB(char *dbname,char *args, PRBool rw);
-extern SECStatus secmod_AddPermDB(char *dbname, char *module, PRBool rw);
+extern char *secmod_getSecmodName(char *params, char **domain,
+ char **filename, PRBool *rw);
+extern char ** secmod_ReadPermDB(const char *domain, const char *filename,
+ const char *dbname, char *params, PRBool rw);
+extern SECStatus secmod_DeletePermDB(const char *domain, const char *filename,
+ const char *dbname, char *args, PRBool rw);
+extern SECStatus secmod_AddPermDB(const char *domain, const char *filename,
+ const char *dbname, char *module, PRBool rw);
+extern SECStatus secmod_ReleasePermDBData(const char *domain,
+ const char *filename, const char *dbname, char **specList, PRBool rw);
/*
* OK there are now lots of options here, lets go through them all:
*
@@ -623,6 +639,8 @@ CK_RV pk11_DBInit(const char *configdir, const char *certPrefix,
void pk11_DBShutdown(NSSLOWCERTCertDBHandle *certHandle,
NSSLOWKEYDBHandle *keyHandle);
+const char *pk11_EvaluateConfigDir(const char *configdir, char **domain);
+
/*
* narrow objects
*/
diff --git a/security/nss/lib/softoken/pkcs11n.h b/security/nss/lib/softoken/pkcs11n.h
index 7ee4c6c34..c2b57acab 100644
--- a/security/nss/lib/softoken/pkcs11n.h
+++ b/security/nss/lib/softoken/pkcs11n.h
@@ -213,11 +213,13 @@ typedef CK_ULONG CK_TRUST;
* The function 'ADD' takes a PKCS #11 initialization string and stores it.
* The function 'DEL' takes a 'name= library=' value and deletes the associated
* string.
+ * The function 'RELEASE' frees the array returned by 'FIND'
*/
#define SECMOD_MODULE_DB_FUNCTION_FIND 0
#define SECMOD_MODULE_DB_FUNCTION_ADD 1
#define SECMOD_MODULE_DB_FUNCTION_DEL 2
+#define SECMOD_MODULE_DB_FUNCTION_RELEASE 3
typedef char ** (PR_CALLBACK *SECMODModuleDBFunc)(unsigned long function,
- char *parameters, char *moduleSpec);
+ char *parameters, void *moduleSpec);
#endif /* _PKCS11N_H_ */
diff --git a/security/nss/lib/softoken/pkcs11u.c b/security/nss/lib/softoken/pkcs11u.c
index 2dd69ed39..5e42975e0 100644
--- a/security/nss/lib/softoken/pkcs11u.c
+++ b/security/nss/lib/softoken/pkcs11u.c
@@ -1261,6 +1261,50 @@ pk11_nullAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type)
}
pk11_FreeAttribute(attribute);
}
+
+static CK_RV
+pk11_SetCertAttribute(PK11TokenObject *to, CK_ATTRIBUTE_TYPE type,
+ void *value, unsigned int len)
+{
+ NSSLOWCERTCertificate *cert;
+ char *nickname = NULL;
+ SECStatus rv;
+
+ /* we can't change the ID or the EMAIL values, but let the
+ * upper layers feel better about the fact we tried to set these */
+ if ((type == CKA_ID) || (type == CKA_NETSCAPE_EMAIL)) {
+ return CKR_OK;
+ }
+
+ if (to->obj.slot->certDB == NULL) {
+ return CKR_TOKEN_WRITE_PROTECTED;
+ }
+
+ if (type != CKA_LABEL) {
+ return CKR_ATTRIBUTE_READ_ONLY;
+ }
+
+ cert = pk11_getCert(to);
+ if (cert == NULL) {
+ return CKR_OBJECT_HANDLE_INVALID;
+ }
+
+ if (value != NULL) {
+ nickname = PORT_ZAlloc(len+1);
+ if (nickname == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+ PORT_Memcpy(nickname,value,len);
+ nickname[len] = 0;
+ }
+ rv = nsslowcert_AddPermNickname(to->obj.slot->certDB, cert, nickname);
+ if (nickname) PORT_Free(nickname);
+ if (rv != SECSuccess) {
+ return CKR_DEVICE_ERROR;
+ }
+ return CKR_OK;
+}
+
static CK_RV
pk11_SetPrivateKeyAttribute(PK11TokenObject *to, CK_ATTRIBUTE_TYPE type,
void *value, unsigned int len)
@@ -1381,6 +1425,7 @@ pk11_forceTokenAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type,
switch (object->objclass) {
case CKO_CERTIFICATE:
/* change NICKNAME, EMAIL, */
+ crv = pk11_SetCertAttribute(to,type,value,len);
break;
case CKO_NETSCAPE_CRL:
/* change URL */
diff --git a/security/nss/lib/softoken/softokn.rc b/security/nss/lib/softoken/softokn.rc
index 8c4c6f7c6..a6477ed12 100644
--- a/security/nss/lib/softoken/softokn.rc
+++ b/security/nss/lib/softoken/softokn.rc
@@ -34,13 +34,21 @@
#include "nss.h"
#include <winver.h>
-#define MY_LIBNAME "softokn"
+#define MY_LIBNAME "softoken"
#ifdef MOZ_CLIENT
-#define MY_FILEDESCRIPTION "NSS Builtin Crypto PKCS #11 Library for Clients"
+#define CLIENTS " for Clients"
#else
-#define MY_FILEDESCRIPTION "NSS Builtin Crypto PKCS #11 Library"
+#define CLIENTS ""
#endif
+#ifdef REMOTE_DBM
+#define DBM " with Shared Database"
+#else
+#define DBM ""
+#endif
+
+#define MY_FILEDESCRIPTION "NSS PKCS #11 Library" CLIENTS DBM
+
#define STRINGIZE(x) #x
#define STRINGIZE2(x) STRINGIZE(x)
#define NSS_VMAJOR_STR STRINGIZE2(NSS_VMAJOR)
diff --git a/security/nss/lib/ssl/sslimpl.h b/security/nss/lib/ssl/sslimpl.h
index a1d09e814..e9dfe6f31 100644
--- a/security/nss/lib/ssl/sslimpl.h
+++ b/security/nss/lib/ssl/sslimpl.h
@@ -1289,12 +1289,12 @@ SEC_END_PROTOS
#endif
#if defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)
-#define SSL_GETPID() getpid()
+#define SSL_GETPID getpid
+#elif defined(_WIN32_WCE)
+#define SSL_GETPID GetCurrentProcessId
#elif defined(WIN32)
-
extern int __cdecl _getpid(void);
-/* #define SSL_GETPID() GetCurrentProcessId() */
-#define SSL_GETPID() _getpid()
+#define SSL_GETPID _getpid
#else
#define SSL_GETPID() 0
#endif
diff --git a/security/nss/lib/ssl/sslmutex.c b/security/nss/lib/ssl/sslmutex.c
index 6f88c27d8..85d6e88c2 100644
--- a/security/nss/lib/ssl/sslmutex.c
+++ b/security/nss/lib/ssl/sslmutex.c
@@ -33,6 +33,10 @@
* $Id$
*/
+#include "seccomon.h"
+/* This ifdef should match the one in sslsnce.c */
+#if (defined(XP_UNIX) || defined(XP_WIN32) || defined (XP_OS2) || defined(XP_BEOS)) && !defined(_WIN32_WCE)
+
#include "sslmutex.h"
#include "prerr.h"
@@ -83,7 +87,7 @@ static SECStatus single_process_sslMutex_Lock(sslMutex* pMutex)
return SECSuccess;
}
-#if defined(LINUX) || defined(AIX) || defined(VMS) || defined(BEOS) || defined(BSDI)
+#if defined(LINUX) || defined(AIX) || defined(VMS) || defined(BEOS) || defined(BSDI) || defined(NETBSD) || defined(OPENBSD)
#include <unistd.h>
#include <fcntl.h>
@@ -504,7 +508,9 @@ sslMutex_Lock(sslMutex *pMutex)
break;
case WAIT_TIMEOUT:
+#if defined(WAIT_IO_COMPLETION)
case WAIT_IO_COMPLETION:
+#endif
default: /* should never happen. nothing we can do. */
PR_ASSERT(!("WaitForSingleObject returned invalid value."));
PORT_SetError(PR_UNKNOWN_ERROR);
@@ -652,3 +658,5 @@ sslMutex_Lock(sslMutex *pMutex)
}
#endif
+
+#endif
diff --git a/security/nss/lib/ssl/sslmutex.h b/security/nss/lib/ssl/sslmutex.h
index 4ede0eba3..97115782f 100644
--- a/security/nss/lib/ssl/sslmutex.h
+++ b/security/nss/lib/ssl/sslmutex.h
@@ -77,7 +77,7 @@ typedef struct
typedef int sslPID;
-#elif defined(LINUX) || defined(AIX) || defined(VMS) || defined(BEOS) || defined(BSDI)
+#elif defined(LINUX) || defined(AIX) || defined(VMS) || defined(BEOS) || defined(BSDI) || defined(NETBSD) || defined(OPENBSD)
#include <sys/types.h>
#include "prtypes.h"
diff --git a/security/nss/lib/ssl/sslnonce.c b/security/nss/lib/ssl/sslnonce.c
index 36dd7f073..ac79c6d66 100644
--- a/security/nss/lib/ssl/sslnonce.c
+++ b/security/nss/lib/ssl/sslnonce.c
@@ -44,7 +44,7 @@
#include "sslproto.h"
#include "nssilock.h"
#include "nsslocks.h"
-#if defined(XP_UNIX) || defined(XP_WIN) || defined(_WINDOWS) || defined(XP_BEOS)
+#if (defined(XP_UNIX) || defined(XP_WIN) || defined(_WINDOWS) || defined(XP_BEOS)) && !defined(_WIN32_WCE)
#include <time.h>
#endif
@@ -348,7 +348,7 @@ PRUint32
ssl_Time(void)
{
PRUint32 myTime;
-#if defined(XP_UNIX) || defined(XP_WIN) || defined(_WINDOWS) || defined(XP_BEOS)
+#if (defined(XP_UNIX) || defined(XP_WIN) || defined(_WINDOWS) || defined(XP_BEOS)) && !defined(_WIN32_WCE)
myTime = time(NULL); /* accurate until the year 2038. */
#else
/* portable, but possibly slower */
diff --git a/security/nss/lib/ssl/sslsecur.c b/security/nss/lib/ssl/sslsecur.c
index 85bb024c8..e5c2bc136 100644
--- a/security/nss/lib/ssl/sslsecur.c
+++ b/security/nss/lib/ssl/sslsecur.c
@@ -43,16 +43,6 @@
#include "secoid.h" /* for SECOID_GetALgorithmTag */
#include "pk11func.h" /* for PK11_GenerateRandom */
-#if defined(_WINDOWS)
-#include "winsock.h" /* for MSG_PEEK */
-#elif defined(XP_MAC)
-#include "macsocket.h"
-#elif defined(BEOS)
-#define MSG_PEEK 0x2
-#else
-#include <sys/socket.h> /* for MSG_PEEK */
-#endif
-
#define MAX_BLOCK_CYPHER_SIZE 32
#define TEST_FOR_FAILURE /* reminder */
@@ -549,7 +539,7 @@ DoRecv(sslSocket *ss, unsigned char *out, int len, int flags)
/* Dole out clear data to reader */
amount = PR_MIN(len, available);
PORT_Memcpy(out, ss->gs.buf.buf + ss->gs.readOffset, amount);
- if (!(flags & MSG_PEEK)) {
+ if (!(flags & PR_MSG_PEEK)) {
ss->gs.readOffset += amount;
}
rv = amount;
@@ -952,7 +942,7 @@ ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR);
return PR_FAILURE;
}
- if (flags & ~MSG_PEEK) {
+ if (flags & ~PR_MSG_PEEK) {
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
return PR_FAILURE;
}
diff --git a/security/nss/lib/ssl/sslsnce.c b/security/nss/lib/ssl/sslsnce.c
index f69f3fd42..f4d4d08d3 100644
--- a/security/nss/lib/ssl/sslsnce.c
+++ b/security/nss/lib/ssl/sslsnce.c
@@ -69,7 +69,7 @@
#include "nssrenam.h"
#include "seccomon.h"
-#if defined(XP_UNIX) || defined(XP_WIN32) || defined (XP_OS2) || defined(XP_BEOS)
+#if (defined(XP_UNIX) || defined(XP_WIN32) || defined (XP_OS2) || defined(XP_BEOS)) && !defined(_WIN32_WCE)
#include "cert.h"
#include "ssl.h"
diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c
index 0042924b8..1025cc609 100644
--- a/security/nss/lib/ssl/sslsock.c
+++ b/security/nss/lib/ssl/sslsock.c
@@ -1801,7 +1801,7 @@ ssl_NewSocket(void)
{
sslSocket *ss;
#ifdef DEBUG
-#if defined(XP_UNIX) || defined(XP_WIN32) || defined(XP_BEOS)
+#if (defined(XP_UNIX) || defined(XP_WIN32) || defined(XP_BEOS)) && !defined(_WIN32_WCE)
static int firsttime = 1;
if (firsttime) {
diff --git a/security/nss/lib/ssl/win32err.c b/security/nss/lib/ssl/win32err.c
index acfce2c9d..4f55f280c 100644
--- a/security/nss/lib/ssl/win32err.c
+++ b/security/nss/lib/ssl/win32err.c
@@ -41,6 +41,8 @@
* $Id$
*/
+#if !defined(_WIN32_WCE)
+
#include "prerror.h"
#include "prlog.h"
#include <errno.h>
@@ -371,3 +373,4 @@ void nss_MD_win32_map_default_error(PRInt32 err)
PR_SetError(prError, err);
}
+#endif
diff --git a/security/nss/lib/util/Makefile b/security/nss/lib/util/Makefile
index 26b783874..0236afefa 100644
--- a/security/nss/lib/util/Makefile
+++ b/security/nss/lib/util/Makefile
@@ -47,8 +47,10 @@ include manifest.mn
include $(CORE_DEPTH)/coreconf/config.mk
ifeq ($(OS_TARGET),HP-UX)
+ifneq ($(OS_TEST),ia64)
ASFILES += ret_cr16.s
endif
+endif
#######################################################################
# (3) Include "component" configuration information. (OPTIONAL) #
diff --git a/security/nss/lib/util/dersubr.c b/security/nss/lib/util/dersubr.c
index dc91ffe6f..a61eee760 100644
--- a/security/nss/lib/util/dersubr.c
+++ b/security/nss/lib/util/dersubr.c
@@ -62,10 +62,10 @@ DER_StoreHeader(unsigned char *buf, unsigned int code, uint32 len)
{
unsigned char b[4];
- b[0] = (len >> 24) & 0xff;
- b[1] = (len >> 16) & 0xff;
- b[2] = (len >> 8) & 0xff;
- b[3] = len & 0xff;
+ b[0] = (unsigned char)(len >> 24);
+ b[1] = (unsigned char)(len >> 16);
+ b[2] = (unsigned char)(len >> 8);
+ b[3] = (unsigned char)len;
if ((code & DER_TAGNUM_MASK) == DER_SET
|| (code & DER_TAGNUM_MASK) == DER_SEQUENCE)
code |= DER_CONSTRUCTED;
diff --git a/security/nss/lib/util/manifest.mn b/security/nss/lib/util/manifest.mn
index 60ebb1fae..fc9a38094 100644
--- a/security/nss/lib/util/manifest.mn
+++ b/security/nss/lib/util/manifest.mn
@@ -59,8 +59,6 @@ EXPORTS = \
watcomfx.h \
$(NULL)
-MODULE = security
-
CSRCS = \
secdig.c \
derdec.c \
@@ -86,6 +84,9 @@ CSRCS = \
utf8.c \
$(NULL)
-REQUIRES = security dbm
+MODULE = security
+
+# don't duplicate module name in REQUIRES
+REQUIRES = dbm
LIBRARY_NAME = secutil
diff --git a/security/nss/lib/util/secder.h b/security/nss/lib/util/secder.h
index 3f957ab9c..fdd43b1de 100644
--- a/security/nss/lib/util/secder.h
+++ b/security/nss/lib/util/secder.h
@@ -41,7 +41,11 @@
* $Id$
*/
+#if defined(_WIN32_WCE)
+#else
#include <time.h>
+#endif
+
#include "plarena.h"
#include "prlong.h"
diff --git a/security/nss/lib/util/secerr.h b/security/nss/lib/util/secerr.h
index ff9c784ee..0742d7386 100644
--- a/security/nss/lib/util/secerr.h
+++ b/security/nss/lib/util/secerr.h
@@ -179,7 +179,8 @@ SEC_ERROR_OCSP_FUTURE_RESPONSE = (SEC_ERROR_BASE + 131),
SEC_ERROR_OCSP_OLD_RESPONSE = (SEC_ERROR_BASE + 132),
/* smime stuff */
SEC_ERROR_DIGEST_NOT_FOUND = (SEC_ERROR_BASE + 133),
-SEC_ERROR_UNSUPPORTED_MESSAGE_TYPE = (SEC_ERROR_BASE + 134)
+SEC_ERROR_UNSUPPORTED_MESSAGE_TYPE = (SEC_ERROR_BASE + 134),
+SEC_ERROR_MODULE_STUCK = (SEC_ERROR_BASE + 135)
} SECErrorCodes;
#endif /* NO_SECURITY_ERROR_ENUM */
diff --git a/security/nss/lib/util/secoid.c b/security/nss/lib/util/secoid.c
index d7a74ae7a..1ad0aa197 100644
--- a/security/nss/lib/util/secoid.c
+++ b/security/nss/lib/util/secoid.c
@@ -61,7 +61,7 @@
#define NETSCAPE_OID 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42
#define NETSCAPE_CERT_EXT NETSCAPE_OID, 0x01
#define NETSCAPE_DATA_TYPE NETSCAPE_OID, 0x02
-/* netscape directory oid - owned by Tim Howes(howes@netscape.com) */
+/* netscape directory oid - owned by Mark Smith (mcs@netscape.com) */
#define NETSCAPE_DIRECTORY NETSCAPE_OID, 0x03
#define NETSCAPE_POLICY NETSCAPE_OID, 0x04
#define NETSCAPE_CERT_SERVER NETSCAPE_OID, 0x05
@@ -264,6 +264,9 @@ CONST_OID nsExtCertRenewalTime[] = { NETSCAPE_CERT_EXT, 0x0f };
CONST_OID nsExtAIACertRenewal[] = { NETSCAPE_CERT_EXT_AIA, 0x01 };
CONST_OID nsExtCertScopeOfUse[] = { NETSCAPE_CERT_EXT, 0x11 };
+/* Reserved Netscape (2 16 840 1 113730 1 18) = { NETSCAPE_CERT_EXT, 0x12 }; */
+
+/* Netscape policy values */
CONST_OID nsKeyUsageGovtApproved[] = { NETSCAPE_POLICY, 0x01 };
/* Netscape other name types */
diff --git a/security/nss/lib/util/secport.c b/security/nss/lib/util/secport.c
index bfde55a81..276cf6208 100644
--- a/security/nss/lib/util/secport.c
+++ b/security/nss/lib/util/secport.c
@@ -159,6 +159,19 @@ PORT_ZFree(void *ptr, size_t len)
}
}
+char *
+PORT_Strdup(const char *str)
+{
+ size_t len = PORT_Strlen(str)+1;
+ char *newstr;
+
+ newstr = (char *)PORT_Alloc(len);
+ if (newstr) {
+ PORT_Memcpy(newstr, str, len);
+ }
+ return newstr;
+}
+
void
PORT_SetError(int value)
{
@@ -258,6 +271,12 @@ PORT_FreeArena(PLArenaPool *arena, PRBool zero)
PZ_Lock(lock);
}
if (!pvd) {
+ /* Each of NSPR's DLLs has a function libVersionPoint().
+ ** We could do a lot of extra work to be sure we're calling the
+ ** one in the DLL that holds PR_FreeArenaPool, but instead we
+ ** rely on the fact that ALL NSPR DLLs in the same directory
+ ** must be from the same release, and we call which ever one we get.
+ */
/* no need for thread protection here */
pvd = libVersionPoint();
if ((pvd->vMajor > 4) ||
@@ -440,7 +459,7 @@ PORT_ArenaUnmark(PLArenaPool *arena, void *mark)
}
char *
-PORT_ArenaStrdup(PLArenaPool *arena, char *str) {
+PORT_ArenaStrdup(PLArenaPool *arena, const char *str) {
int len = PORT_Strlen(str)+1;
char *newstr;
@@ -529,7 +548,7 @@ PORT_UCS2_ASCIIConversion(PRBool toUnicode, unsigned char *inBuf,
int
NSS_PutEnv(const char * envVarName, const char * envValue)
{
-#if defined(XP_MAC)
+#if defined(XP_MAC) || defined(_WIN32_WCE)
return SECFailure;
#else
SECStatus result = SECSuccess;
diff --git a/security/nss/lib/util/secport.h b/security/nss/lib/util/secport.h
index c89c7dcd5..b154c0915 100644
--- a/security/nss/lib/util/secport.h
+++ b/security/nss/lib/util/secport.h
@@ -85,7 +85,10 @@
#include "watcomfx.h"
#endif
-#ifdef XP_MAC
+#if defined(_WIN32_WCE)
+#include <windef.h>
+#include <types.h>
+#elif defined( XP_MAC )
#include <types.h>
#include <time.h> /* for time_t below */
#else
@@ -100,7 +103,11 @@
#include <ctype.h>
#include <string.h>
+#if defined(_WIN32_WCE)
+#include <stdlib.h> /* WinCE puts some stddef symbols here. */
+#else
#include <stddef.h>
+#endif
#include <stdlib.h>
#include "prtypes.h"
#include "prlog.h" /* for PR_ASSERT */
@@ -137,7 +144,7 @@ extern void *PORT_ArenaGrow(PLArenaPool *arena, void *ptr,
extern void *PORT_ArenaMark(PLArenaPool *arena);
extern void PORT_ArenaRelease(PLArenaPool *arena, void *mark);
extern void PORT_ArenaUnmark(PLArenaPool *arena, void *mark);
-extern char *PORT_ArenaStrdup(PLArenaPool *arena, char *str);
+extern char *PORT_ArenaStrdup(PLArenaPool *arena, const char *str);
#ifdef __cplusplus
}
@@ -203,10 +210,10 @@ extern char *PORT_ArenaStrdup(PLArenaPool *arena, char *str);
#define PORT_Strcasecmp PL_strcasecmp
#define PORT_Strcat strcat
#define PORT_Strchr strchr
-#define PORT_Strrchr PL_strrchr
+#define PORT_Strrchr strrchr
#define PORT_Strcmp strcmp
#define PORT_Strcpy strcpy
-#define PORT_Strdup PL_strdup
+extern char *PORT_Strdup(const char *s);
#define PORT_Strlen(s) strlen(s)
#define PORT_Strncasecmp PL_strncasecmp
#define PORT_Strncat strncat
diff --git a/security/nss/macbuild/NSS.xml b/security/nss/macbuild/NSS.xml
index ef06cc17c..a9aefb197 100644
--- a/security/nss/macbuild/NSS.xml
+++ b/security/nss/macbuild/NSS.xml
@@ -1137,13 +1137,6 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
- <PATH>devobject.c</PATH>
- <PATHFORMAT>MacOS</PATHFORMAT>
- <FILEKIND>Text</FILEKIND>
- <FILEFLAGS></FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
<PATH>devslot.c</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -1200,6 +1193,13 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>pkibase.c</PATH>
+ <PATHFORMAT>MacOS</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS></FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>pkistore.c</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -1626,11 +1626,6 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
- <PATH>devobject.c</PATH>
- <PATHFORMAT>MacOS</PATHFORMAT>
- </FILEREF>
- <FILEREF>
- <PATHTYPE>Name</PATHTYPE>
<PATH>devslot.c</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
@@ -1671,6 +1666,11 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>pkibase.c</PATH>
+ <PATHFORMAT>MacOS</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>pkistore.c</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
@@ -3155,13 +3155,6 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
- <PATH>devobject.c</PATH>
- <PATHFORMAT>MacOS</PATHFORMAT>
- <FILEKIND>Text</FILEKIND>
- <FILEFLAGS></FILEFLAGS>
- </FILE>
- <FILE>
- <PATHTYPE>Name</PATHTYPE>
<PATH>devslot.c</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -3218,6 +3211,13 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>pkibase.c</PATH>
+ <PATHFORMAT>MacOS</PATHFORMAT>
+ <FILEKIND>Text</FILEKIND>
+ <FILEFLAGS></FILEFLAGS>
+ </FILE>
+ <FILE>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>pkistore.c</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
@@ -3634,11 +3634,6 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
- <PATH>devobject.c</PATH>
- <PATHFORMAT>MacOS</PATHFORMAT>
- </FILEREF>
- <FILEREF>
- <PATHTYPE>Name</PATHTYPE>
<PATH>devslot.c</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
@@ -3679,6 +3674,11 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>pkibase.c</PATH>
+ <PATHFORMAT>MacOS</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>pkistore.c</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
@@ -4219,12 +4219,6 @@
<FILEREF>
<TARGETNAME>NSS3Debug.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
- <PATH>devobject.c</PATH>
- <PATHFORMAT>MacOS</PATHFORMAT>
- </FILEREF>
- <FILEREF>
- <TARGETNAME>NSS3Debug.shlb</TARGETNAME>
- <PATHTYPE>Name</PATHTYPE>
<PATH>devslot.c</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
@@ -4375,6 +4369,12 @@
<FILEREF>
<TARGETNAME>NSS3Debug.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
+ <PATH>pkibase.c</PATH>
+ <PATHFORMAT>MacOS</PATHFORMAT>
+ </FILEREF>
+ <FILEREF>
+ <TARGETNAME>NSS3Debug.shlb</TARGETNAME>
+ <PATHTYPE>Name</PATHTYPE>
<PATH>pkistore.c</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
diff --git a/security/nss/macbuild/NSSCommon.h b/security/nss/macbuild/NSSCommon.h
index 3b3a94c31..83a54d7e3 100755
--- a/security/nss/macbuild/NSSCommon.h
+++ b/security/nss/macbuild/NSSCommon.h
@@ -2,4 +2,5 @@
#define NSPR20 1
#define MP_API_COMPATIBLE 1
-#define NSS_3_4_CODE 1 /* Remove this when we start building NSS 4.0 by default */ \ No newline at end of file
+#define NSS_3_4_CODE 1 /* Remove this when we start building NSS 4.0 by default */
+#define SHLIB_SUFFIX "shlb"
diff --git a/security/nss/manifest.mn b/security/nss/manifest.mn
index a72cac1ea..97533f29e 100644
--- a/security/nss/manifest.mn
+++ b/security/nss/manifest.mn
@@ -33,8 +33,8 @@
CORE_DEPTH = ..
DEPTH = ..
-IMPORTS = nspr20/v4.1.2 \
- dbm/DBM_1_61_RC1 \
+IMPORTS = nspr20/v4.2 \
+ dbm/DBM_1_61_RTM \
$(NULL)
RELEASE = security
diff --git a/security/nss/tests/cert/cert.sh b/security/nss/tests/cert/cert.sh
index cfb3d16df..05e602d38 100755
--- a/security/nss/tests/cert/cert.sh
+++ b/security/nss/tests/cert/cert.sh
@@ -34,7 +34,7 @@
########################################################################
#
-# mozilla/security/nss/tests/cert/cert.sh
+# mozilla/security/nss/tests/cert/rcert.sh
#
# Certificate generating and handeling for NSS QA, can be included
# multiple times from all.sh and the individual scripts
@@ -85,7 +85,7 @@ cert_init()
cert_log() ###################### write the cert_status file
{
- #echo "$SCRIPTNAME $*"
+ echo "$SCRIPTNAME $*"
echo $* >>${CERT_LOG_FILE}
}
@@ -98,7 +98,7 @@ cert_log() ###################### write the cert_status file
#########################################################################
noise()
{
- netstat >> ${NOISE_FILE} 2>&1
+ #netstat >> ${NOISE_FILE} 2>&1
date >> ${NOISE_FILE} 2>&1
}
@@ -129,6 +129,9 @@ certu()
else
html_passed "<TR><TD>${CU_ACTION}"
fi
+
+ # echo "Contine?"
+ # cat > /dev/null
return $RET
}
@@ -140,6 +143,7 @@ cert_init_cert()
CERTDIR="$1"
CERTNAME="$2"
CERTSERIAL="$3"
+ DOMAIN="$4"
if [ ! -d "${CERTDIR}" ]; then
mkdir -p "${CERTDIR}"
@@ -149,6 +153,11 @@ cert_init_cert()
cd "${CERTDIR}"
CERTDIR="."
+ PROFILEDIR=${CERTDIR}
+ if [ -n "${MULTIACCESS_DBM}" ]; then
+ PROFILEDIR="multiaccess:${DOMAIN}"
+ fi
+
noise
}
@@ -166,9 +175,9 @@ hw_acc()
echo "modutil -add rainbow -libfile /usr/lib/libcryptoki22.so "
- echo " -dbdir . 2>&1 "
+ echo " -dbdir ${PROFILEDIR} 2>&1 "
echo | modutil -add rainbow -libfile /usr/lib/libcryptoki22.so \
- -dbdir . 2>&1
+ -dbdir ${PROFILEDIR} 2>&1
if [ "$?" -ne 0 ]; then
echo "modutil -add rainbow failed in `pwd`"
HW_ACC_RET=1
@@ -177,10 +186,10 @@ hw_acc()
echo "modutil -add ncipher "
echo " -libfile /opt/nfast/toolkits/pkcs11/libcknfast.so "
- echo " -dbdir . 2>&1 "
+ echo " -dbdir ${PROFILEDIR} 2>&1 "
echo | modutil -add ncipher \
-libfile /opt/nfast/toolkits/pkcs11/libcknfast.so \
- -dbdir . 2>&1
+ -dbdir ${PROFILEDIR} 2>&1
if [ "$?" -ne 0 ]; then
echo "modutil -add ncipher failed in `pwd`"
HW_ACC_RET=`expr $HW_ACC_RET + 2`
@@ -204,16 +213,16 @@ hw_acc()
########################################################################
cert_create_cert()
{
- cert_init_cert "$1" "$2" "$3"
+ cert_init_cert "$1" "$2" "$3" "$4"
CU_ACTION="Initializing ${CERTNAME}'s Cert DB"
- certu -N -d "${CERTDIR}" -f "${R_PWFILE}" 2>&1
+ certu -N -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1
if [ "$RET" -ne 0 ]; then
return $RET
fi
hw_acc
CU_ACTION="Import Root CA for $CERTNAME"
- certu -A -n "TestCA" -t "TC,TC,TC" -f "${R_PWFILE}" -d "${CERTDIR}" \
+ certu -A -n "TestCA" -t "TC,TC,TC" -f "${R_PWFILE}" -d "${PROFILEDIR}" \
-i "${R_CADIR}/root.cert" 2>&1
if [ "$RET" -ne 0 ]; then
return $RET
@@ -234,20 +243,20 @@ cert_add_cert()
CU_ACTION="Generate Cert Request for $CERTNAME"
CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
- certu -R -d "${CERTDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1
+ certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1
if [ "$RET" -ne 0 ]; then
return $RET
fi
CU_ACTION="Sign ${CERTNAME}'s Request"
- certu -C -c "TestCA" -m "$CERTSERIAL" -v 60 -d "${R_CADIR}" \
+ certu -C -c "TestCA" -m "$CERTSERIAL" -v 60 -d "${P_R_CADIR}" \
-i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" 2>&1
if [ "$RET" -ne 0 ]; then
return $RET
fi
CU_ACTION="Import $CERTNAME's Cert"
- certu -A -n "$CERTNAME" -t "u,u,u" -d "${CERTDIR}" -f "${R_PWFILE}" \
+ certu -A -n "$CERTNAME" -t "u,u,u" -d "${PROFILEDIR}" -f "${R_PWFILE}" \
-i "${CERTNAME}.cert" 2>&1
if [ "$RET" -ne 0 ]; then
return $RET
@@ -267,23 +276,23 @@ cert_all_CA()
echo nss > ${PWFILE}
ALL_CU_SUBJECT="CN=NSS Test CA, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
- cert_CA $CADIR TestCA -x "CTu,CTu,CTu"
+ cert_CA $CADIR TestCA -x "CTu,CTu,CTu" ${D_CA}
ALL_CU_SUBJECT="CN=NSS Server Test CA, O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
- cert_CA $SERVER_CADIR serverCA -x "Cu,Cu,Cu"
+ cert_CA $SERVER_CADIR serverCA -x "Cu,Cu,Cu" ${D_SERVER_CA}
ALL_CU_SUBJECT="CN=NSS Chain1 Server Test CA, O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
- cert_CA $SERVER_CADIR chain-1-serverCA "-c serverCA" "u,u,u"
+ cert_CA $SERVER_CADIR chain-1-serverCA "-c serverCA" "u,u,u" ${D_SERVER_CA}
ALL_CU_SUBJECT="CN=NSS Chain2 Server Test CA, O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
- cert_CA $SERVER_CADIR chain-2-serverCA "-c chain-1-serverCA" "u,u,u"
+ cert_CA $SERVER_CADIR chain-2-serverCA "-c chain-1-serverCA" "u,u,u" ${D_SERVER_CA}
ALL_CU_SUBJECT="CN=NSS Client Test CA, O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
- cert_CA $CLIENT_CADIR clientCA -x "Tu,Cu,Cu"
+ cert_CA $CLIENT_CADIR clientCA -x "Tu,Cu,Cu" ${D_CLIENT_CA}
ALL_CU_SUBJECT="CN=NSS Chain1 Client Test CA, O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
- cert_CA $CLIENT_CADIR chain-1-clientCA "-c clientCA" "u,u,u"
+ cert_CA $CLIENT_CADIR chain-1-clientCA "-c clientCA" "u,u,u" ${D_CLIENT_CA}
ALL_CU_SUBJECT="CN=NSS Chain2 Client Test CA, O=BOGUS NSS, L=Santa Clara, ST=California, C=US"
- cert_CA $CLIENT_CADIR chain-2-clientCA "-c chain-1-clientCA" "u,u,u"
+ cert_CA $CLIENT_CADIR chain-2-clientCA "-c chain-1-clientCA" "u,u,u" ${D_CLIENT_CA}
rm $CLIENT_CADIR/root.cert $SERVER_CADIR/root.cert
# root.cert in $CLIENT_CADIR and in $SERVER_CADIR is the one of the last
@@ -300,6 +309,7 @@ cert_CA()
NICKNAME=$2
SIGNER=$3
TRUSTARG=$4
+ DOMAIN=$5
echo "$SCRIPTNAME: Creating a CA Certificate $NICKNAME =========================="
@@ -309,10 +319,14 @@ cert_CA()
cd ${CUR_CADIR}
pwd
+ LPROFILE=.
+ if [ -n "${MULTIACCESS_DBM}" ]; then
+ LPROFILE="multiaccess:${DOMAIN}"
+ fi
if [ "$SIGNER" = "-x" ] ; then # self signed -> create DB
CU_ACTION="Creating CA Cert DB"
- certu -N -d . -f ${R_PWFILE} 2>&1
+ certu -N -d ${LPROFILE} -f ${R_PWFILE} 2>&1
if [ "$RET" -ne 0 ]; then
Exit 5 "Fatal - failed to create CA $NICKNAME "
fi
@@ -324,7 +338,7 @@ cert_CA()
#
CU_ACTION="Creating CA Cert $NICKNAME "
CU_SUBJECT=$ALL_CU_SUBJECT
- certu -S -n $NICKNAME -t $TRUSTARG -v 60 $SIGNER -d . -1 -2 -5 \
+ certu -S -n $NICKNAME -t $TRUSTARG -v 60 $SIGNER -d ${LPROFILE} -1 -2 -5 \
-f ${R_PWFILE} -z ${R_NOISE_FILE} 2>&1 <<CERTSCRIPT
5
9
@@ -340,13 +354,14 @@ n
CERTSCRIPT
if [ "$RET" -ne 0 ]; then
+ echo "return value is $RET"
Exit 6 "Fatal - failed to create CA cert"
fi
################# Exporting Root Cert ###################################
#
CU_ACTION="Exporting Root Cert"
- certu -L -n $NICKNAME -r -d . -o root.cert
+ certu -L -n $NICKNAME -r -d ${LPROFILE} -o root.cert
if [ "$RET" -ne 0 ]; then
Exit 7 "Fatal - failed to export root cert"
fi
@@ -361,43 +376,44 @@ cert_smime_client()
CERTFAILED=0
echo "$SCRIPTNAME: Creating Client CA Issued Certificates =============="
- cert_create_cert ${ALICEDIR} "Alice" 3
- cert_create_cert ${BOBDIR} "Bob" 4
+ cert_create_cert ${ALICEDIR} "Alice" 3 ${D_ALICE}
+ cert_create_cert ${BOBDIR} "Bob" 4 ${D_BOB}
echo "$SCRIPTNAME: Creating Dave's Certificate -------------------------"
- cert_init_cert "${DAVEDIR}" Dave 5
- cp ${CADIR}/*.db .
- hw_acc
+ cert_create_cert "${DAVEDIR}" Dave 5 ${D_DAVE}
+ #echo "************* Copying CA files to ${SERVERDIR}"
+ #cp ${CADIR}/*.db .
+ #hw_acc
#########################################################################
#
- cd ${CERTDIR}
- CU_ACTION="Creating ${CERTNAME}'s Server Cert"
- CU_SUBJECT="CN=${CERTNAME}, E=${CERTNAME}@bogus.com, O=BOGUS Netscape, L=Mountain View, ST=California, C=US"
- certu -S -n "${CERTNAME}" -c "TestCA" -t "u,u,u" -m "$CERTSERIAL" -d . \
- -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -v 60 2>&1
+ #cd ${CERTDIR}
+ #CU_ACTION="Creating ${CERTNAME}'s Server Cert"
+ #CU_SUBJECT="CN=${CERTNAME}, E=${CERTNAME}@bogus.com, O=BOGUS Netscape, L=Mountain View, ST=California, C=US"
+ #certu -S -n "${CERTNAME}" -c "TestCA" -t "u,u,u" -m "$CERTSERIAL" \
+ # -d ${PROFILEDIR} -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -v 60 2>&1
- CU_ACTION="Export Dave's Cert"
- cd ${DAVEDIR}
- certu -L -n "Dave" -r -d . -o Dave.cert
+ #CU_ACTION="Export Dave's Cert"
+ #cd ${DAVEDIR}
+ #certu -L -n "Dave" -r -d ${P_R_DAVE} -o Dave.cert
################# Importing Certificates for S/MIME tests ###############
#
echo "$SCRIPTNAME: Importing Certificates =============================="
CU_ACTION="Import Alices's cert into Bob's db"
- certu -E -t "p,p,p" -d ${R_BOBDIR} -f ${R_PWFILE} \
+ certu -E -t "p,p,p" -d ${P_R_BOBDIR} -f ${R_PWFILE} \
-i ${R_ALICEDIR}/Alice.cert 2>&1
CU_ACTION="Import Bob's cert into Alice's db"
- certu -E -t "p,p,p" -d ${R_ALICEDIR} -f ${R_PWFILE} \
+ certu -E -t "p,p,p" -d ${P_R_ALICEDIR} -f ${R_PWFILE} \
-i ${R_BOBDIR}/Bob.cert 2>&1
CU_ACTION="Import Dave's cert into Alice's DB"
- certu -E -t "p,p,p" -d ${R_ALICEDIR} -f ${R_PWFILE} \
+ certu -E -t "p,p,p" -d ${P_R_ALICEDIR} -f ${R_PWFILE} \
-i ${R_DAVEDIR}/Dave.cert 2>&1
CU_ACTION="Import Dave's cert into Bob's DB"
- certu -E -t "p,p,p" -d ${R_BOBDIR} -f ${R_PWFILE} \
+ certu -E -t "p,p,p" -d ${P_R_BOBDIR} -f ${R_PWFILE} \
-i ${R_DAVEDIR}/Dave.cert 2>&1
if [ "$CERTFAILED" != 0 ] ; then
@@ -419,26 +435,26 @@ cert_extended_ssl()
echo " of a chain of CA's which are not in the same database============"
echo "Server Cert"
- cert_init_cert ${EXT_SERVERDIR} "${HOSTADDR}" 1
+ cert_init_cert ${EXT_SERVERDIR} "${HOSTADDR}" 1 ${D_EXT_SERVER}
CU_ACTION="Initializing ${CERTNAME}'s Cert DB (ext.)"
- certu -N -d "${CERTDIR}" -f "${R_PWFILE}" 2>&1
+ certu -N -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1
CU_ACTION="Generate Cert Request for $CERTNAME (ext)"
CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
- certu -R -d "${CERTDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1
+ certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1
CU_ACTION="Sign ${CERTNAME}'s Request (ext)"
cp ${CERTDIR}/req ${SERVER_CADIR}
- certu -C -c "chain-2-serverCA" -m "$CERTSERIAL" -v 60 -d "${SERVER_CADIR}" \
+ certu -C -c "chain-2-serverCA" -m "$CERTSERIAL" -v 60 -d "${P_SERVER_CADIR}" \
-i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" 2>&1
CU_ACTION="Import $CERTNAME's Cert -t u,u,u (ext)"
- certu -A -n "$CERTNAME" -t "u,u,u" -d "${CERTDIR}" -f "${R_PWFILE}" \
+ certu -A -n "$CERTNAME" -t "u,u,u" -d "${PROFILEDIR}" -f "${R_PWFILE}" \
-i "${CERTNAME}.cert" 2>&1
CU_ACTION="Import Client Root CA -t T,, for $CERTNAME (ext.)"
- certu -A -n "clientCA" -t "T,," -f "${R_PWFILE}" -d "${CERTDIR}" \
+ certu -A -n "clientCA" -t "T,," -f "${R_PWFILE}" -d "${PROFILEDIR}" \
-i "${CLIENT_CADIR}/clientCA.ca.cert" 2>&1
echo "Importing all the server's own CA chain into the servers DB"
for CA in `find ${SERVER_CADIR} -name "?*.ca.cert"` ;
@@ -450,30 +466,30 @@ cert_extended_ssl()
T="-t u,u,u"
fi
CU_ACTION="Import $N CA $T for $CERTNAME (ext.) "
- certu -A -n $N $T -f "${R_PWFILE}" -d "${CERTDIR}" \
+ certu -A -n $N $T -f "${R_PWFILE}" -d "${PROFILEDIR}" \
-i "${CA}" 2>&1
done
#============
echo "Client Cert"
- cert_init_cert ${EXT_CLIENTDIR} ExtendedSSLUser 1
+ cert_init_cert ${EXT_CLIENTDIR} ExtendedSSLUser 1 ${D_EXT_CLIENT}
CU_ACTION="Initializing ${CERTNAME}'s Cert DB (ext.)"
- certu -N -d "${CERTDIR}" -f "${R_PWFILE}" 2>&1
+ certu -N -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1
CU_ACTION="Generate Cert Request for $CERTNAME (ext)"
CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
- certu -R -d "${CERTDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1
+ certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1
CU_ACTION="Sign ${CERTNAME}'s Request (ext)"
cp ${CERTDIR}/req ${CLIENT_CADIR}
- certu -C -c "chain-2-clientCA" -m "$CERTSERIAL" -v 60 -d "${CLIENT_CADIR}" \
+ certu -C -c "chain-2-clientCA" -m "$CERTSERIAL" -v 60 -d "${P_CLIENT_CADIR}" \
-i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" 2>&1
CU_ACTION="Import $CERTNAME's Cert -t u,u,u (ext)"
- certu -A -n "$CERTNAME" -t "u,u,u" -d "${CERTDIR}" -f "${R_PWFILE}" \
+ certu -A -n "$CERTNAME" -t "u,u,u" -d "${PROFILEDIR}" -f "${R_PWFILE}" \
-i "${CERTNAME}.cert" 2>&1
CU_ACTION="Import Server Root CA -t C,C,C for $CERTNAME (ext.)"
- certu -A -n "serverCA" -t "C,C,C" -f "${R_PWFILE}" -d "${CERTDIR}" \
+ certu -A -n "serverCA" -t "C,C,C" -f "${R_PWFILE}" -d "${PROFILEDIR}" \
-i "${SERVER_CADIR}/serverCA.ca.cert" 2>&1
echo "Importing all the client's own CA chain into the servers DB"
for CA in `find ${CLIENT_CADIR} -name "?*.ca.cert"` ;
@@ -485,7 +501,7 @@ cert_extended_ssl()
T="-t u,u,u"
fi
CU_ACTION="Import $N CA $T for $CERTNAME (ext.)"
- certu -A -n $N $T -f "${R_PWFILE}" -d "${CERTDIR}" \
+ certu -A -n $N $T -f "${R_PWFILE}" -d "${PROFILEDIR}" \
-i "${CA}" 2>&1
done
if [ "$CERTFAILED" != 0 ] ; then
@@ -504,17 +520,20 @@ cert_ssl()
#
CERTFAILED=0
echo "$SCRIPTNAME: Creating Client CA Issued Certificates ==============="
- cert_create_cert ${CLIENTDIR} "TestUser" 6
+ cert_create_cert ${CLIENTDIR} "TestUser" 6 ${D_CLIENT}
echo "$SCRIPTNAME: Creating Server CA Issued Certificate for \\"
echo " ${HOSTADDR} ------------------------------------"
- cert_init_cert ${SERVERDIR} "${HOSTADDR}" 1
- cp ${CADIR}/*.db .
- hw_acc
- CU_ACTION="Creating ${CERTNAME}'s Server Cert"
- CU_SUBJECT="CN=${CERTNAME}, O=BOGUS Netscape, L=Mountain View, ST=California, C=US"
- certu -S -n "${CERTNAME}" -c "TestCA" -t "Pu,Pu,Pu" -d . -f "${R_PWFILE}" \
- -z "${R_NOISE_FILE}" -v 60 2>&1
+ cert_create_cert ${SERVERDIR} "${HOSTADDR}" 1 ${D_SERVER}
+ certu -M -n "TestCA" -t "TC,TC,TC" -d ${PROFILEDIR}
+# cert_init_cert ${SERVERDIR} "${HOSTADDR}" 1 ${D_SERVER}
+# echo "************* Copying CA files to ${SERVERDIR}"
+# cp ${CADIR}/*.db .
+# hw_acc
+# CU_ACTION="Creating ${CERTNAME}'s Server Cert"
+# CU_SUBJECT="CN=${CERTNAME}, O=BOGUS Netscape, L=Mountain View, ST=California, C=US"
+# certu -S -n "${CERTNAME}" -c "TestCA" -t "Pu,Pu,Pu" -d ${PROFILEDIR} \
+# -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -v 60 2>&1
if [ "$CERTFAILED" != 0 ] ; then
cert_log "ERROR: SSL failed $RET"
@@ -533,6 +552,10 @@ cert_stresscerts()
CERTDIR="$CLIENTDIR"
cd "${CERTDIR}"
+ PROFILEDIR=${CERTDIR}
+ if [ -n "${MULTIACCESS_DBM}" ]; then
+ PROFILEDIR="multiaccess:${D_CLIENT}"
+ fi
CERTFAILED=0
echo "$SCRIPTNAME: Creating Client CA Issued Certificates ==============="
@@ -560,13 +583,13 @@ cert_fips()
{
CERTFAILED=0
echo "$SCRIPTNAME: Creating FIPS 140-1 DSA Certificates =============="
- cert_init_cert "${FIPSDIR}" "FIPS PUB 140-1 Test Certificate" 1000
+ cert_init_cert "${FIPSDIR}" "FIPS PUB 140-1 Test Certificate" 1000 "${D_FIPS}"
CU_ACTION="Initializing ${CERTNAME}'s Cert DB"
- certu -N -d "${CERTDIR}" -f "${R_FIPSPWFILE}" 2>&1
+ certu -N -d "${PROFILEDIR}" -f "${R_FIPSPWFILE}" 2>&1
echo "$SCRIPTNAME: Enable FIPS mode on database -----------------------"
- modutil -dbdir ${CERTDIR} -fips true 2>&1 <<MODSCRIPT
+ modutil -dbdir ${PROFILEDIR} -fips true 2>&1 <<MODSCRIPT
y
MODSCRIPT
CU_ACTION="Enable FIPS mode on database for ${CERTNAME}"
@@ -579,7 +602,7 @@ MODSCRIPT
CU_ACTION="Generate Certificate for ${CERTNAME}"
CU_SUBJECT="CN=${CERTNAME}, E=fips@bogus.com, O=BOGUS NSS, OU=FIPS PUB 140-1, L=Mountain View, ST=California, C=US"
- certu -S -n ${FIPSCERTNICK} -x -t "Cu,Cu,Cu" -d "${CERTDIR}" -f "${R_FIPSPWFILE}" -k dsa -m ${CERTSERIAL} -z "${R_NOISE_FILE}" 2>&1
+ certu -S -n ${FIPSCERTNICK} -x -t "Cu,Cu,Cu" -d "${PROFILEDIR}" -f "${R_FIPSPWFILE}" -k dsa -m ${CERTSERIAL} -z "${R_NOISE_FILE}" 2>&1
if [ "$RET" -eq 0 ]; then
cert_log "SUCCESS: FIPS passed"
fi
diff --git a/security/nss/tests/cipher/cipher.sh b/security/nss/tests/cipher/cipher.sh
index 63acc897c..a90a9dbe4 100755
--- a/security/nss/tests/cipher/cipher.sh
+++ b/security/nss/tests/cipher/cipher.sh
@@ -65,12 +65,17 @@ cipher_init()
CIPHERDIR=${HOSTDIR}/cipher
CIPHERTESTDIR=${QADIR}/../cmd/bltest
+ D_CIPHER="Cipher.$version"
CIPHER_TXT=${QADIR}/cipher/cipher.txt
mkdir -p ${CIPHERDIR}
cd ${CIPHERTESTDIR}
+ P_CIPHER=.
+ if [ -n "${MULTIACCESS_DBM}" ]; then
+ P_CIPHER="multiaccess:${D_CIPHER}"
+ fi
}
############################## cipher_main #############################
@@ -84,9 +89,9 @@ cipher_main()
PARAM=`echo $PARAM | sed -e "s/_-/ -/g"`
TESTNAME=`echo $TESTNAME | sed -e "s/_/ /g"`
echo "$SCRIPTNAME: $TESTNAME --------------------------------"
- echo "bltest -T -m $PARAM -d ."
+ echo "bltest -T -m $PARAM -d ${P_CIPHER}"
- bltest -T -m $PARAM -d .
+ bltest -T -m $PARAM -d ${P_CIPHER}
html_msg $? $EXP_RET "$TESTNAME"
fi
done
diff --git a/security/nss/tests/clean_tbx b/security/nss/tests/clean_tbx
index 74d83de4f..4de955576 100755
--- a/security/nss/tests/clean_tbx
+++ b/security/nss/tests/clean_tbx
@@ -22,9 +22,9 @@ $PASSED_TBX_KEEP_HOURS=2;
$IF_TBX_KEEP_HOURS=2;
$PASSED_NEWER_DIRS=2;
$IF_NEWER_DIRS=2;
-$verbose = 0;
+$verbose = 1;
-$TBX_TESTDIR="/share/builds/mccrel/nss/nsstip/tinderbox/tests_results/security";
+$TBX_TESTDIR="/share/builds/mccrel3/nss/nsstip/tinderbox/tests_results/security";
$FTP_STAGE="/u/sonmi/tmp/ftp_stage/tinderbox";
@tbx_dirs = ();
@@ -34,7 +34,7 @@ $ePASSED_TBX_KEEP=$PASSED_TBX_KEEP_HOURS*60*60;
$eIF_TBX_KEEP=$IF_TBX_KEEP_HOURS*60*60;
$eNOT_FAILED_TBX_KEEP=$NOT_FAILED_TBX_KEEP_HOURS*60*60;
-$days, $hours, $minutes, $seconds;
+$year, $month, $days, $hours, $minutes, $seconds;
$efulldate=0;
$fulldate=0;
@@ -56,8 +56,6 @@ debug ("$seconds, $minutes, $hours, $days, $month, $year");
$enow = timelocal(localtime);
-
-
sub debug;
sub warning;
sub error;
@@ -65,7 +63,6 @@ sub msg;
sub init;
sub check_tbx_dirs;
-
sub check_tbx_dirs
{
my $platform_idx=0; # counts directories per platform, newest
@@ -141,6 +138,7 @@ sub rm_tbx()
debug ("DELETING $tbx_dir... (@_[0]) ");
system("rm -rf $TBX_TESTDIR/$tbx_dir");
+#debug ("rm -rf $TBX_TESTDIR/$tbx_dir");
}
diff --git a/security/nss/tests/common/init.sh b/security/nss/tests/common/init.sh
index 343ff134b..529cbef02 100644
--- a/security/nss/tests/common/init.sh
+++ b/security/nss/tests/common/init.sh
@@ -359,6 +359,19 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then
FIPSP12PWFILE=${TMP}/tests.fipsp12pw.$$
FIPSCERTNICK="FIPS_PUB_140-1_Test_Certificate"
+ # domains to handle ipc based access to databases
+ D_CA="TestCA.$version"
+ D_ALICE="Alice.$version"
+ D_BOB="Bob.$version"
+ D_DAVE="Dave.$version"
+ D_SERVER_CA="ServerCA.$version"
+ D_CLIENT_CA="ClientCA.$version"
+ D_SERVER="Server.$version"
+ D_CLIENT="Client.$version"
+ D_FIPS="FIPS.$version"
+ D_EXT_SERVER="ExtendedServer.$version"
+ D_EXT_CLIENT="ExtendedClient.$version"
+
# we need relative pathnames of these files abd directories, since our
# tools can't handle the unix style absolut pathnames on cygnus
@@ -371,6 +384,33 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then
R_EXT_SERVERDIR=../ext_server
R_EXT_CLIENTDIR=../ext_client
+ #
+ # profiles are either paths or domains depending on the setting of
+ # MULTIACCESS_DBM
+ #
+ P_R_CADIR=${R_CADIR}
+ P_R_ALICEDIR=${R_ALICEDIR}
+ P_R_BOBDIR=${R_BOBDIR}
+ P_R_DAVEDIR=${R_DAVEDIR}
+ P_R_SERVERDIR=${R_SERVERDIR}
+ P_R_CLIENTDIR=${R_CLIENTDIR}
+ P_R_EXT_SERVERDIR=${R_EXT_SERVERDIR}
+ P_R_EXT_CLIENTDIR=${R_EXT_CLIENTDIR}
+ P_SERVER_CADIR=${SERVER_CADIR}
+ P_CLIENT_CADIR=${CLIENT_CADIR}
+ if [ -n "${MULTIACCESS_DBM}" ]; then
+ P_R_CADIR="multiaccess:${D_CA}"
+ P_R_ALICEDIR="multiaccess:${D_ALICE}"
+ P_R_BOBDIR="multiaccess:${D_BOB}"
+ P_R_DAVEDIR="multiaccess:${D_DAVE}"
+ P_R_SERVERDIR="multiaccess:${D_SERVER}"
+ P_R_CLIENTDIR="multiaccess:${D_CLIENT}"
+ P_R_EXT_SERVERDIR="multiaccess:${D_EXT_SERVER}"
+ P_R_EXT_CLIENTDIR="multiaccess:${D_EXT_CLIENT}"
+ P_SERVER_CADIR="multiaccess:${D_SERVER_CA}"
+ P_CLIENT_CADIR="multiaccess:${D_CLIENT_CA}"
+ fi
+
R_PWFILE=../tests.pw.$$
R_NOISE_FILE=../tests_noise.$$
diff --git a/security/nss/tests/fips/fips.sh b/security/nss/tests/fips/fips.sh
index 8e4fcb1f0..cf94db945 100755
--- a/security/nss/tests/fips/fips.sh
+++ b/security/nss/tests/fips/fips.sh
@@ -76,8 +76,13 @@ fips_init()
COPYDIR=${FIPSDIR}/copydir
R_FIPSDIR=../fips
+ P_R_FIPSDIR=../fips
R_COPYDIR=../fips/copydir
+ if [ -n "${MULTIACCESS_DBM}" ]; then
+ P_R_FIPSDIR="multiaccess:${D_FIPS}"
+ fi
+
mkdir -p ${FIPSDIR}
mkdir -p ${COPYDIR}
@@ -91,73 +96,73 @@ fips_init()
fips_140_1()
{
echo "$SCRIPTNAME: List the FIPS module certificates -----------------"
- echo "certutil -d ${R_FIPSDIR} -L"
- certutil -d ${R_FIPSDIR} -L 2>&1
+ echo "certutil -d ${P_R_FIPSDIR} -L"
+ certutil -d ${P_R_FIPSDIR} -L 2>&1
html_msg $? 0 "List the FIPS module certificates (certutil -L)"
echo "$SCRIPTNAME: List the FIPS module keys -------------------------"
- echo "certutil -d ${R_FIPSDIR} -K -f ${R_FIPSPWFILE}"
- certutil -d ${R_FIPSDIR} -K -f ${R_FIPSPWFILE} 2>&1
+ echo "certutil -d ${P_R_FIPSDIR} -K -f ${R_FIPSPWFILE}"
+ certutil -d ${P_R_FIPSDIR} -K -f ${R_FIPSPWFILE} 2>&1
html_msg $? 0 "List the FIPS module keys (certutil -K)"
echo "$SCRIPTNAME: Attempt to list FIPS module keys with incorrect password"
- echo "certutil -d ${R_FIPSDIR} -K -f ${FIPSBADPWFILE}"
- certutil -d ${R_FIPSDIR} -K -f ${FIPSBADPWFILE} 2>&1
+ echo "certutil -d ${P_R_FIPSDIR} -K -f ${FIPSBADPWFILE}"
+ certutil -d ${P_R_FIPSDIR} -K -f ${FIPSBADPWFILE} 2>&1
RET=$?
html_msg $RET 255 "Attempt to list FIPS module keys with incorrect password (certutil -K)"
echo "certutil -K returned $RET"
echo "$SCRIPTNAME: Validate the certificate --------------------------"
- echo "certutil -d ${R_FIPSDIR} -V -n ${FIPSCERTNICK} -u SR -e -f ${R_FIPSPWFILE}"
- certutil -d ${R_FIPSDIR} -V -n ${FIPSCERTNICK} -u SR -e -f ${R_FIPSPWFILE}
+ echo "certutil -d ${P_R_FIPSDIR} -V -n ${FIPSCERTNICK} -u SR -e -f ${R_FIPSPWFILE}"
+ certutil -d ${P_R_FIPSDIR} -V -n ${FIPSCERTNICK} -u SR -e -f ${R_FIPSPWFILE}
html_msg $? 0 "Validate the certificate (certutil -V -e)"
echo "$SCRIPTNAME: Export the certificate and key as a PKCS#12 file --"
- echo "pk12util -d ${R_FIPSDIR} -o fips140.p12 -n ${FIPSCERTNICK} -w ${R_FIPSP12PWFILE} -k ${R_FIPSPWFILE}"
- pk12util -d ${R_FIPSDIR} -o fips140.p12 -n ${FIPSCERTNICK} -w ${R_FIPSP12PWFILE} -k ${R_FIPSPWFILE} 2>&1
+ echo "pk12util -d ${P_R_FIPSDIR} -o fips140.p12 -n ${FIPSCERTNICK} -w ${R_FIPSP12PWFILE} -k ${R_FIPSPWFILE}"
+ pk12util -d ${P_R_FIPSDIR} -o fips140.p12 -n ${FIPSCERTNICK} -w ${R_FIPSP12PWFILE} -k ${R_FIPSPWFILE} 2>&1
html_msg $? 0 "Export the certificate and key as a PKCS#12 file (pk12util -o)"
echo "$SCRIPTNAME: Export the certificate as a DER-encoded file ------"
- echo "certutil -d ${R_FIPSDIR} -L -n ${FIPSCERTNICK} -r -o fips140.crt"
- certutil -d ${R_FIPSDIR} -L -n ${FIPSCERTNICK} -r -o fips140.crt 2>&1
+ echo "certutil -d ${P_R_FIPSDIR} -L -n ${FIPSCERTNICK} -r -o fips140.crt"
+ certutil -d ${P_R_FIPSDIR} -L -n ${FIPSCERTNICK} -r -o fips140.crt 2>&1
html_msg $? 0 "Export the certificate as a DER (certutil -L -r)"
echo "$SCRIPTNAME: List the FIPS module certificates -----------------"
- echo "certutil -d ${R_FIPSDIR} -L"
- certutil -d ${R_FIPSDIR} -L 2>&1
+ echo "certutil -d ${P_R_FIPSDIR} -L"
+ certutil -d ${P_R_FIPSDIR} -L 2>&1
html_msg $? 0 "List the FIPS module certificates (certutil -L)"
echo "$SCRIPTNAME: Delete the certificate and key from the FIPS module"
- echo "certutil -d ${R_FIPSDIR} -F -n ${FIPSCERTNICK} -f ${R_FIPSPWFILE}"
- certutil -d ${R_FIPSDIR} -F -n ${FIPSCERTNICK} -f ${R_FIPSPWFILE} 2>&1
+ echo "certutil -d ${P_R_FIPSDIR} -F -n ${FIPSCERTNICK} -f ${R_FIPSPWFILE}"
+ certutil -d ${P_R_FIPSDIR} -F -n ${FIPSCERTNICK} -f ${R_FIPSPWFILE} 2>&1
html_msg $? 0 "Delete the certificate and key from the FIPS module (certutil -D)"
echo "$SCRIPTNAME: List the FIPS module certificates -----------------"
- echo "certutil -d ${R_FIPSDIR} -L"
- certutil -d ${R_FIPSDIR} -L 2>&1
+ echo "certutil -d ${P_R_FIPSDIR} -L"
+ certutil -d ${P_R_FIPSDIR} -L 2>&1
html_msg $? 0 "List the FIPS module certificates (certutil -L)"
echo "$SCRIPTNAME: List the FIPS module keys."
- echo "certutil -d ${R_FIPSDIR} -K -f ${R_FIPSPWFILE}"
- certutil -d ${R_FIPSDIR} -K -f ${R_FIPSPWFILE} 2>&1
+ echo "certutil -d ${P_R_FIPSDIR} -K -f ${R_FIPSPWFILE}"
+ certutil -d ${P_R_FIPSDIR} -K -f ${R_FIPSPWFILE} 2>&1
# certutil -K now returns a failure if no keys are found. This verifies that
# our delete succeded.
html_msg $? 255 "List the FIPS module keys (certutil -K)"
echo "$SCRIPTNAME: Import the certificate and key from the PKCS#12 file"
- echo "pk12util -d ${R_FIPSDIR} -i fips140.p12 -w ${R_FIPSP12PWFILE} -k ${R_FIPSPWFILE}"
- pk12util -d ${R_FIPSDIR} -i fips140.p12 -w ${R_FIPSP12PWFILE} -k ${R_FIPSPWFILE} 2>&1
+ echo "pk12util -d ${P_R_FIPSDIR} -i fips140.p12 -w ${R_FIPSP12PWFILE} -k ${R_FIPSPWFILE}"
+ pk12util -d ${P_R_FIPSDIR} -i fips140.p12 -w ${R_FIPSP12PWFILE} -k ${R_FIPSPWFILE} 2>&1
html_msg $? 0 "Import the certificate and key from the PKCS#12 file (pk12util -i)"
echo "$SCRIPTNAME: List the FIPS module certificates -----------------"
- echo "certutil -d ${R_FIPSDIR} -L"
- certutil -d ${R_FIPSDIR} -L 2>&1
+ echo "certutil -d ${P_R_FIPSDIR} -L"
+ certutil -d ${P_R_FIPSDIR} -L 2>&1
html_msg $? 0 "List the FIPS module certificates (certutil -L)"
echo "$SCRIPTNAME: List the FIPS module keys --------------------------"
- echo "certutil -d ${R_FIPSDIR} -K -f ${R_FIPSPWFILE}"
- certutil -d ${R_FIPSDIR} -K -f ${R_FIPSPWFILE} 2>&1
+ echo "certutil -d ${P_R_FIPSDIR} -K -f ${R_FIPSPWFILE}"
+ certutil -d ${P_R_FIPSDIR} -K -f ${R_FIPSPWFILE} 2>&1
html_msg $? 0 "List the FIPS module keys (certutil -K)"
}
diff --git a/security/nss/tests/header b/security/nss/tests/header
index a0b2cc13f..b5d117b2d 100644
--- a/security/nss/tests/header
+++ b/security/nss/tests/header
@@ -208,7 +208,7 @@ export BC_RELEASE
EARLY_EXIT=TRUE #before the report file has been created, causes Exit to
#create it
-UX_D0=/share/builds/mccrel/nss
+UX_D0=/share/builds/mccrel3/nss
################################### glob_init ##########################
# global shell function, main initialisation function
@@ -568,9 +568,9 @@ init_dirs()
set_daily_build_dirs
if [ -z "${BCDIST}" ] ; then
- #BCDIST=/share/builds/mccrel/nss/${BC_MASTER}/mozilla/dist
+ #BCDIST=/share/builds/mccrel3/nss/${BC_MASTER}/mozilla/dist
BCDIST=${NSS_VER_DIR}/../${BC_MASTER}/mozilla/dist
- if [ ! -d $BCDIST ] ; then
+ if [ ! -d $BCDIST -a `basename $0` != jssqa ] ; then
ask "Backward compatibility directory $BCDIST does not exist, continue" "y" "n" || Exit
fi
fi
@@ -602,7 +602,7 @@ init_dirs()
TESTSCRIPTDIR=${MOZILLA_ROOT}/security/nss/tests
fi
- if [ ! -d $TESTSCRIPTDIR ] ; then
+ if [ ! -d $TESTSCRIPTDIR -a `basename $0` != jssqa ] ; then
if [ "$O_WIN" = "ON" -a "$WIN_WAIT_FOREVER" = "ON" ]
then
WaitForever $TESTSCRIPTDIR/all.sh 1
@@ -871,23 +871,21 @@ eval_opts()
-*)
glob_usage "Error: Can't handle option $1"
;;
- ?*)
+ tip|3.|3..)
NSSVER=$1
- if [ -z "$NSSVER" ]
- then
- NSSVER="tip"
- Debug "NSS Version: Parameters missing - defaulting to tip!"
- else
- BUILDDATE=$2
- if [ -z "$BUILDDATE" ]
- then
- BUILDDATE=`date +%m%d`
- Debug "Builddate: Parameters missing - defaulting to today!"
- else
- shift
- fi
+ if [ -z "$NSSVER" ] ; then
+ glob_usage "Error: illegal parameter"
+ fi
+ ;;
+ [01][0-9][0123][0-9])
+ BUILDDATE=$1
+ if [ -z "$BUILDDATE" ] ; then
+ glob_usage "Error: illegal parameter"
fi
;;
+ ?*)
+ glob_usage "Error: Can't handle parameter $1"
+ ;;
esac
shift
done
@@ -895,17 +893,18 @@ eval_opts()
if [ -z "$PORT" -a "$O_TBX" = "ON" ] ; then
PORT=8444
export PORT
+ if [ -z "$NSSVER" ] ; then
+ NSSVER="tip"
+ Debug "NSS Version: Parameters missing - defaulting to tip!"
+ fi
+ elif [ -z "$NSSVER" ] ; then
+ NSSVER="341"
+ Debug "NSS Version: Parameters missing - defaulting to 341!"
fi
- if [ -z "$BUILDDATE" ]
- then
+ if [ -z "$BUILDDATE" ] ; then
BUILDDATE=`date +%m%d`
Debug "Builddate: Parameters missing - defaulting to today!"
fi
- if [ -z "$NSSVER" ]
- then
- NSSVER="tip"
- Debug "NSS Version: Parameters missing - defaulting to tip!"
- fi
Debug "Builddate $BUILDDATE NssVersion $NSSVER"
export BUILDDATE NSSVER
diff --git a/security/nss/tests/jssdir b/security/nss/tests/jssdir
index 6c9fd355e..1609fbfcf 100755
--- a/security/nss/tests/jssdir
+++ b/security/nss/tests/jssdir
@@ -17,7 +17,7 @@ else if ( "$QAYEAR" == "" ) then
endif
-setenv JSS_VER_DIR /share/builds/mccrel/jss/jss$JSSVER
+setenv JSS_VER_DIR /share/builds/mccrel3/jss/jss$JSSVER
setenv NTDIST ${JSS_VER_DIR}/builds/${QAYEAR}${BUILDDATE}.1/blowfish_NT4.0_Win95/mozilla/dist
setenv UXDIST ${JSS_VER_DIR}/builds/${QAYEAR}${BUILDDATE}.1/booboo_Solaris8/mozilla/dist
setenv TESTSCRIPTDIR ${JSS_VER_DIR}/builds/${QAYEAR}${BUILDDATE}.1/booboo_Solaris8/mozilla/security/jss/tests
diff --git a/security/nss/tests/nssdir b/security/nss/tests/nssdir
index 296872217..884c299f5 100755
--- a/security/nss/tests/nssdir
+++ b/security/nss/tests/nssdir
@@ -17,7 +17,7 @@ else if ( "$QAYEAR" == "" ) then
endif
-setenv NSS_VER_DIR /share/builds/mccrel/nss/nss$NSSVER
+setenv NSS_VER_DIR /share/builds/mccrel3/nss/nss$NSSVER
setenv NTDIST ${NSS_VER_DIR}/builds/${QAYEAR}${BUILDDATE}.1/blowfish_NT4.0_Win95/mozilla/dist
setenv UXDIST ${NSS_VER_DIR}/builds/${QAYEAR}${BUILDDATE}.1/booboo_Solaris8/mozilla/dist
setenv TESTSCRIPTDIR ${NSS_VER_DIR}/builds/${QAYEAR}${BUILDDATE}.1/booboo_Solaris8/mozilla/security/nss/tests
diff --git a/security/nss/tests/qa_stage b/security/nss/tests/qa_stage
index f818c605a..f0960c845 100755
--- a/security/nss/tests/qa_stage
+++ b/security/nss/tests/qa_stage
@@ -46,7 +46,7 @@ qa_stage_init()
Echo "Init..."
DAYBUILD=${QAYEAR}${BUILDDATE}.${BUILDNUMBER}
- NSS_D0=/share/builds/mccrel/nss
+ NSS_D0=/share/builds/mccrel3/nss
NSS_VER_DIR=${NSS_D0}/nss${NSSVER}
NTDIST=${NSS_VER_DIR}/builds/${DAYBUILD}/blowfish_NT4.0_Win95/mozilla/dist
UXDIST=${NSS_VER_DIR}/builds/${DAYBUILD}/booboo_Solaris8/mozilla/dist
@@ -130,7 +130,7 @@ qa_stage_tbx()
Echo "find from $TBX_FIND_FROM"
for w in `find $TBX_FIND_FROM -name "result.html"`
do
- if [ ! -d $TBX_STAGE/`dirname $w` ] ; then
+ if [ ! -d "$TBX_STAGE/`dirname $w`" ] ; then
mkdir -p $TBX_STAGE/`dirname $w`
fi
rm $TBX_STAGE/$w 2>/dev/null
@@ -294,11 +294,15 @@ else
TARPARAM=cvf
fi
-if [ "$DO_DQA" = "ON" && "$DO_TBX" = "ON" ] ; then
+
+if [ "$DO_DQA" = "ON" -a "$DO_TBX" = "ON" ] ; then
+ Echo "tar $TARPARAM all.tar daily_qa tinderbox"
tar $TARPARAM all.tar daily_qa tinderbox
elif [ "$DO_DQA" = "ON" ] ; then
+ Echo "tar $TARPARAM all.tar daily_qa"
tar $TARPARAM all.tar daily_qa
else
+ Echo "tar $TARPARAM all.tar tinderbox"
tar $TARPARAM all.tar tinderbox
fi
gzip all.tar
diff --git a/security/nss/tests/qa_stat b/security/nss/tests/qa_stat
index 231a3b68b..aa3e4bb88 100755
--- a/security/nss/tests/qa_stat
+++ b/security/nss/tests/qa_stat
@@ -239,7 +239,7 @@ etscape]">
<h2>
<a href="http://tinderbox.mozilla.org/showbuilds.cgi?tree=NSS">Tinderbox</a
><br>
-<a href="http://cindercone.red.iplanet.com/share/builds/mccrel/nss/nsstip/tinderbox/tests_results/security/">Tinderbox QA&nbsp;result</a><br>
+<a href="http://cindercone.red.iplanet.com/share/builds/mccrel3/nss/nsstip/tinderbox/tests_results/security/">Tinderbox QA&nbsp;result</a><br>
<a href="ftp://ftp.mozilla.org/pub/security/nss/daily_qa">Mozilla Daily NSS QA&nbsp;result</a></h2>
&nbsp;
diff --git a/security/nss/tests/sdr/sdr.sh b/security/nss/tests/sdr/sdr.sh
index a36066589..36c0f40ae 100755
--- a/security/nss/tests/sdr/sdr.sh
+++ b/security/nss/tests/sdr/sdr.sh
@@ -71,10 +71,16 @@ sdr_init()
T2="The quick brown fox jumped over the lazy dog"
SDRDIR=${HOSTDIR}/SDR
+ D_SDR="SDR.$version"
if [ ! -d ${SDRDIR} ]; then
mkdir -p ${SDRDIR}
fi
+ PROFILE=.
+ if [ -n "${MULTIACCESS_DBM}" ]; then
+ PROFILE="multiaccess:${D_SDR}"
+ fi
+
cd ${SDRDIR}
html_head "SDR Tests"
}
@@ -85,23 +91,23 @@ sdr_init()
sdr_main()
{
echo "$SCRIPTNAME: Creating an SDR key/Encrypt"
- echo "sdrtest -d . -o ${VALUE1} -t Test1"
- sdrtest -d . -o ${VALUE1} -t Test1
+ echo "sdrtest -d ${PROFILE} -o ${VALUE1} -t Test1"
+ sdrtest -d ${PROFILE} -o ${VALUE1} -t Test1
html_msg $? 0 "Creating SDR Key"
echo "$SCRIPTNAME: SDR Encrypt - Second Value"
- echo "sdrtest -d . -o ${VALUE2} -t '${T2}'"
- sdrtest -d . -o ${VALUE2} -t "${T2}"
+ echo "sdrtest -d ${PROFILE} -o ${VALUE2} -t '${T2}'"
+ sdrtest -d ${PROFILE} -o ${VALUE2} -t "${T2}"
html_msg $? 0 "Encrypt - Value 2"
echo "$SCRIPTNAME: Decrypt - Value 1"
- echo "sdrtest -d . -i ${VALUE1} -t Test1"
- sdrtest -d . -i ${VALUE1} -t Test1
+ echo "sdrtest -d ${PROFILE} -i ${VALUE1} -t Test1"
+ sdrtest -d ${PROFILE} -i ${VALUE1} -t Test1
html_msg $? 0 "Decrypt - Value 1"
echo "$SCRIPTNAME: Decrypt - Value 2"
- echo "sdrtest -d . -i ${VALUE2} -t ${T2}"
- sdrtest -d . -i ${VALUE2} -t "${T2}"
+ echo "sdrtest -d ${PROFILE} -i ${VALUE2} -t ${T2}"
+ sdrtest -d ${PROFILE} -i ${VALUE2} -t "${T2}"
html_msg $? 0 "Decrypt - Value 2"
}
diff --git a/security/nss/tests/set_environment b/security/nss/tests/set_environment
index 829d6c6d9..5a3515cca 100644
--- a/security/nss/tests/set_environment
+++ b/security/nss/tests/set_environment
@@ -33,6 +33,7 @@ if [ "$os_name" != "Windows_95" -a \
then
PATH=.:$HOME/bin:/tools/ns/bin:/bin:/usr/bin:/usr/sbin:/usr/ccs/bin:/usr/dist/local/exe:/usr/bin/X11:/usr/audio/bin:/u/sonmi/bin:$PATH
JAVA_HOME="D:/i386/jdk1.2.2"
+ JAVA_HOME14="R:/jdk/1.4.0/WINNT"
fi
CVSROOT=:pserver:svbld@redcvs.red.iplanet.com:/m/src
@@ -60,6 +61,7 @@ if [ "$os_name" = "HP-UX" ]
then
PATH=$PATH:/usr/local/bin:/opt/aCC/bin:/usr/local/bin/audio:/tools/ns/bin:/etc:/usr/contrib/bin:/usr/contrib/bin/X11:/usr/local/hpux/bin:/nfs/iapp1/hphome/bin:/etc:/u/svbld/bin/HP/perl/bin
JAVA_HOME="/share/builds/components/cms_jdk/HP-UX/1.2.2.04"
+ JAVA_HOME14=$JAVA_HOME
# JAVA_HOME="/share/builds/components/cms_jdk/HP-UX/1.3.0.00"
elif [ "$os_name" = "SunOS" ]
then
@@ -71,10 +73,12 @@ then
then
#PATH=/usr/ucb:/opt/usr/local/bin:$PATH
JAVA_HOME="/usr/java1.2"
+ JAVA_HOME14=/share/builds/components/jdk/1.4.0/SunOS_x86
PATH=".:/usr/dist/share/forte_dev_i386,v6.2/SUNWspro/bin:/opt/usr/local/perl5/bin:/opt/SUNWspro/bin:/opt/usr/local/bin:/bin:/usr/bin:/usr/sbin:/usr/ccs/bin:/usr/dist/local/exe:/usr/ccs/bin:/usr/ucb/bin:/usr/ucb:/opt/SUNWwabi/bin:/usr/local/bin:/tools/ns/bin:/etc:/tools/contrib/bin"
else
PATH=/usr/ucb:$PATH
JAVA_HOME="/share/builds/components/jdk/1.2.2/SunOS"
+ JAVA_HOME14=/share/builds/components/jdk/1.4.0/SunOS64
PATH=/tools/ns/bin:$PATH:/opt/SUNWspro/bin:/usr/bin/X11:/usr/openwin/bin:/usr/openwin/demo
if [ "$os_version" = "5.8" -o "$os_version" = "5.7" -o \
@@ -93,11 +97,13 @@ then
PATH=$PATH:/tools/ns/bin:/usr/local/bin:/etc:/usr/bsd
MANPATH=/tools/ns/man:/usr/local/man
JAVA_HOME="/share/builds/components/jdk/1.2.2/IRIX"
+ JAVA_HOME14=$JAVA_HOME
elif [ "$os_name" = "IRIX64" ]
then
PATH=$PATH:/tools/ns/bin:/usr/local/bin:/etc:/usr/bsd
MANPATH=/tools/ns/man:/usr/local/man
JAVA_HOME="/share/builds/components/jdk/1.2.2/IRIX"
+ JAVA_HOME14=$JAVA_HOME
elif [ "$os_name" = "Linux" ]
then
PATH=/lib:/usr/lib:/bin:/sbin:/usr/bin:/usr/sbin:$PATH
@@ -107,16 +113,19 @@ then
BEFORE_CONTEXT_GREP="--before-context=10"
AFTER_CONTEXT_GREP="--after-context=3"
JAVA_HOME="/share/builds/components/jdk/1.2.2/Linux"
+ JAVA_HOME14=/share/builds/components/jdk/1.4.0/Linux
elif [ "$os_name" = "AIX" ]
then
PATH=$PATH:/tools/contrib/bin:/usr/local/bin
TERM=vt100
export TERM
JAVA_HOME="/share/builds/components/cms_jdk/AIX/1.3.0"
+ JAVA_HOME14=$JAVA_HOME
elif [ "$os_name" = "OSF1" ]
then
PATH=$PATH:/usr/local/bin
JAVA_HOME="/share/builds/components/jdk/1.2.2/OSF1"
+ JAVA_HOME14=$JAVA_HOME
fi
if [ "$os_name" = "IRIX" ]
@@ -218,6 +227,8 @@ system=`uname -n` # name of this system.
JAVAC=$JAVA_HOME/bin/javac
JAVA=$JAVA_HOME/bin/java
+JAVAC14=$JAVA_HOME14/bin/javac
+JAVA14=$JAVA_HOME14/bin/java
#JAVA=$JAVA_HOME/jre/bin/java
-export JAVAC JAVA JAVA_HOME
+export JAVAC JAVA JAVA_HOME JAVAC14 JAVA_HOME14 JAVA14
diff --git a/security/nss/tests/smime/smime.sh b/security/nss/tests/smime/smime.sh
index 040ced05c..64726e558 100755
--- a/security/nss/tests/smime/smime.sh
+++ b/security/nss/tests/smime/smime.sh
@@ -89,12 +89,12 @@ smime_main()
{
echo "$SCRIPTNAME: Signing Attached Message ------------------------------"
- echo "cmsutil -S -N Alice -i alice.txt -d ${R_ALICEDIR} -p nss -o alice.sig"
- cmsutil -S -N Alice -i alice.txt -d ${R_ALICEDIR} -p nss -o alice.sig
+ echo "cmsutil -S -N Alice -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig"
+ cmsutil -S -N Alice -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig
html_msg $? 0 "Create Signature Alice" "."
- echo "cmsutil -D -i alice.sig -d ${R_BOBDIR} -o alice.data1"
- cmsutil -D -i alice.sig -d ${R_BOBDIR} -o alice.data1
+ echo "cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1"
+ cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1
html_msg $? 0 "Decode Alice's Signature" "."
echo "diff alice.txt alice.data1"
@@ -102,14 +102,14 @@ smime_main()
html_msg $? 0 "Compare Decoded Signature and Original" "."
echo "$SCRIPTNAME: Enveloped Data Tests ------------------------------"
- echo "cmsutil -E -r bob@bogus.com -i alice.txt -d ${R_ALICEDIR} -p nss \\"
+ echo "cmsutil -E -r bob@bogus.com -i alice.txt -d ${P_R_ALICEDIR} -p nss \\"
echo " -o alice.env"
- cmsutil -E -r bob@bogus.com -i alice.txt -d ${R_ALICEDIR} -p nss -o alice.env
+ cmsutil -E -r bob@bogus.com -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.env
html_msg $? 0 "Create Enveloped Data Alice" "."
- echo "cmsutil -D -i alice.env -d ${R_BOBDIR} -p nss -o alice.data1"
- cmsutil -D -i alice.env -d ${R_BOBDIR} -p nss -o alice.data1
+ echo "cmsutil -D -i alice.env -d ${P_R_BOBDIR} -p nss -o alice.data1"
+ cmsutil -D -i alice.env -d ${P_R_BOBDIR} -p nss -o alice.data1
html_msg $? 0 "Decode Enveloped Data Alice" "."
echo "diff alice.txt alice.data1"
@@ -118,9 +118,9 @@ smime_main()
# multiple recip
echo "$SCRIPTNAME: Testing multiple recipients ------------------------------"
- echo "cmsutil -E -i alicecc.txt -d ${R_ALICEDIR} -o alicecc.env \\"
+ echo "cmsutil -E -i alicecc.txt -d ${P_R_ALICEDIR} -o alicecc.env \\"
echo " -r bob@bogus.com,dave@bogus.com"
- cmsutil -E -i alice.txt -d ${R_ALICEDIR} -o alicecc.env \
+ cmsutil -E -i alice.txt -d ${P_R_ALICEDIR} -o alicecc.env \
-r bob@bogus.com,dave@bogus.com
ret=$?
html_msg $ret 0 "Create Multiple Recipients Enveloped Data Alice" "."
@@ -130,21 +130,21 @@ smime_main()
cp -r ${R_ALICEDIR} ${R_ALICEDIR}.trouble
while [ $i -lt 100 ] ; do
echo "will attempt to list the certs in the db `expr 100 - $i` more times"
- echo "certutil -L -d ${R_ALICEDIR}"
- certutil -L -d ${R_ALICEDIR}
- echo "certutil -L -d ${R_ALICEDIR} -n dave@bogus.com"
- certutil -L -d ${R_ALICEDIR} -n dave@bogus.com
+ echo "certutil -L -d ${P_R_ALICEDIR}"
+ certutil -L -d ${P_R_ALICEDIR}
+ echo "certutil -L -d ${P_R_ALICEDIR} -n dave@bogus.com"
+ certutil -L -d ${P_R_ALICEDIR} -n dave@bogus.com
sleep 30
i=`expr $i + 1`
done
fi
- echo "cmsutil -D -i alicecc.env -d ${R_BOBDIR} -p nss -o alice.data2"
- cmsutil -D -i alicecc.env -d ${R_BOBDIR} -p nss -o alice.data2
+ echo "cmsutil -D -i alicecc.env -d ${P_R_BOBDIR} -p nss -o alice.data2"
+ cmsutil -D -i alicecc.env -d ${P_R_BOBDIR} -p nss -o alice.data2
html_msg $? 0 "Decode Multiple Recipients Enveloped Data Alice by Bob" "."
- echo "cmsutil -D -i alicecc.env -d ${R_DAVEDIR} -p nss -o alice.data2"
- cmsutil -D -i alicecc.env -d ${R_DAVEDIR} -p nss -o alice.data3
+ echo "cmsutil -D -i alicecc.env -d ${P_R_DAVEDIR} -p nss -o alice.data2"
+ cmsutil -D -i alicecc.env -d ${P_R_DAVEDIR} -p nss -o alice.data3
html_msg $? 0 "Decode Multiple Recipients Enveloped Data Alice by Dave" "."
diff alice.txt alice.data2
@@ -155,24 +155,24 @@ smime_main()
echo "$SCRIPTNAME: Sending CERTS-ONLY Message ------------------------------"
echo "cmsutil -O -r \"Alice,bob@bogus.com,dave@bogus.com\" \\"
- echo " -d ${R_ALICEDIR} > co.der"
- cmsutil -O -r "Alice,bob@bogus.com,dave@bogus.com" -d ${R_ALICEDIR} > co.der
+ echo " -d ${P_R_ALICEDIR} > co.der"
+ cmsutil -O -r "Alice,bob@bogus.com,dave@bogus.com" -d ${P_R_ALICEDIR} > co.der
html_msg $? 0 "Create Certs-Only Alice" "."
- echo "cmsutil -D -i co.der -d ${R_BOBDIR}"
- cmsutil -D -i co.der -d ${R_BOBDIR}
+ echo "cmsutil -D -i co.der -d ${P_R_BOBDIR}"
+ cmsutil -D -i co.der -d ${P_R_BOBDIR}
html_msg $? 0 "Verify Certs-Only by CA" "."
echo "$SCRIPTNAME: Encrypted-Data Message ---------------------------------"
- echo "cmsutil -C -i alice.txt -e alicehello.env -d ${R_ALICEDIR} \\"
+ echo "cmsutil -C -i alice.txt -e alicehello.env -d ${P_R_ALICEDIR} \\"
echo " -r \"bob@bogus.com\" > alice.enc"
- cmsutil -C -i alice.txt -e alicehello.env -d ${R_ALICEDIR} \
+ cmsutil -C -i alice.txt -e alicehello.env -d ${P_R_ALICEDIR} \
-r "bob@bogus.com" > alice.enc
html_msg $? 0 "Create Encrypted-Data" "."
- echo "cmsutil -D -i alice.enc -d ${R_BOBDIR} -e alicehello.env -p nss \\"
+ echo "cmsutil -D -i alice.enc -d ${P_R_BOBDIR} -e alicehello.env -p nss \\"
echo " -o alice.data2"
- cmsutil -D -i alice.enc -d ${R_BOBDIR} -e alicehello.env -p nss -o alice.data2
+ cmsutil -D -i alice.enc -d ${P_R_BOBDIR} -e alicehello.env -p nss -o alice.data2
html_msg $? 0 "Decode Encrypted-Data" "."
diff alice.txt alice.data2
diff --git a/security/nss/tests/ssl/ssl.sh b/security/nss/tests/ssl/ssl.sh
index 464319030..2db98b457 100755
--- a/security/nss/tests/ssl/ssl.sh
+++ b/security/nss/tests/ssl/ssl.sh
@@ -127,13 +127,15 @@ is_selfserv_alive()
########################################################################
wait_for_selfserv()
{
- echo "tstclnt -p ${PORT} -h ${HOST} -q -d . < ${REQUEST_FILE} "
+ echo "tstclnt -p ${PORT} -h ${HOST} -q "
+ echo " -d ${P_R_CLIENTDIR} < ${REQUEST_FILE} \\"
#echo "tstclnt -q started at `date`"
- tstclnt -p ${PORT} -h ${HOST} -q -d . < ${REQUEST_FILE}
+ tstclnt -p ${PORT} -h ${HOST} -q -d ${P_R_CLIENTDIR} < ${REQUEST_FILE}
if [ $? -ne 0 ]; then
html_failed "<TR><TD> Wait for Server "
- echo "RETRY: tstclnt -p ${PORT} -h ${HOST} -q -d . < ${REQUEST_FILE}"
- tstclnt -p ${PORT} -h ${HOST} -q -d . < ${REQUEST_FILE}
+ echo "RETRY: tstclnt -p ${PORT} -h ${HOST} -q \\"
+ echo " -d ${P_R_CLIENTDIR} < ${REQUEST_FILE}"
+ tstclnt -p ${PORT} -h ${HOST} -q -d ${P_R_CLIENTDIR} < ${REQUEST_FILE}
elif [ sparam = "-c ABCDEFabcdefghijklmnvy" ] ; then # "$1" = "cov" ] ; then
html_passed "<TR><TD> Wait for Server"
fi
@@ -165,15 +167,15 @@ start_selfserv()
echo "$SCRIPTNAME: $testname ----"
fi
sparam=`echo $sparam | sed -e 's;_; ;g'`
- echo "selfserv -D -p ${PORT} -d ${R_SERVERDIR} -n ${HOSTADDR} \\"
+ echo "selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} -n ${HOSTADDR} \\"
echo " -w nss ${sparam} -i ${R_SERVERPID} $verbose &"
echo "selfserv started at `date`"
if [ ${fileout} -eq 1 ]; then
- selfserv -D -p ${PORT} -d ${R_SERVERDIR} -n ${HOSTADDR} \
+ selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} -n ${HOSTADDR} \
-w nss ${sparam} -i ${R_SERVERPID} $verbose \
> ${SERVEROUTFILE} 2>&1 &
else
- selfserv -D -p ${PORT} -d ${R_SERVERDIR} -n ${HOSTADDR} \
+ selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} -n ${HOSTADDR} \
-w nss ${sparam} -i ${R_SERVERPID} $verbose &
fi
wait_for_selfserv
@@ -211,11 +213,12 @@ ssl_cov()
is_selfserv_alive
echo "tstclnt -p ${PORT} -h ${HOST} -c ${param} ${TLS_FLAG} \\"
- echo " -f -d . < ${REQUEST_FILE}"
+ echo " -f -d ${P_R_CLIENTDIR} < ${REQUEST_FILE}"
rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
tstclnt -p ${PORT} -h ${HOST} -c ${param} ${TLS_FLAG} -f \
- -d . < ${REQUEST_FILE} >${TMP}/$HOST.tmp.$$ 2>&1
+ -d ${P_R_CLIENTDIR} < ${REQUEST_FILE} \
+ >${TMP}/$HOST.tmp.$$ 2>&1
ret=$?
cat ${TMP}/$HOST.tmp.$$
rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
@@ -240,11 +243,12 @@ ssl_auth()
cparam=`echo $cparam | sed -e 's;_; ;g' -e "s/TestUser/$USER_NICKNAME/g" `
start_selfserv
- echo "tstclnt -p ${PORT} -h ${HOST} -f -d . ${cparam} \\"
- echo " < ${REQUEST_FILE}"
+ echo "tstclnt -p ${PORT} -h ${HOST} -f -d ${P_R_CLIENTDIR} \\"
+ echo " ${cparam} < ${REQUEST_FILE}"
rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
tstclnt -p ${PORT} -h ${HOST} -f ${cparam} \
- -d . < ${REQUEST_FILE} >${TMP}/$HOST.tmp.$$ 2>&1
+ -d ${P_R_CLIENTDIR} < ${REQUEST_FILE} \
+ >${TMP}/$HOST.tmp.$$ 2>&1
ret=$?
cat ${TMP}/$HOST.tmp.$$
rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
@@ -279,10 +283,11 @@ ssl_stress()
ps -ef | grep selfserv
fi
- echo "strsclnt -q -p ${PORT} -d . -w nss $cparam $verbose \\"
- echo " ${HOSTADDR}"
+ echo "strsclnt -q -p ${PORT} -d ${P_R_CLIENTDIR} -w nss $cparam \\"
+ echo " $verbose ${HOSTADDR}"
echo "strsclnt started at `date`"
- strsclnt -q -p ${PORT} -d . -w nss $cparam $verbose ${HOSTADDR}
+ strsclnt -q -p ${PORT} -d ${P_R_CLIENTDIR} -w nss $cparam \
+ $verbose ${HOSTADDR}
ret=$?
echo "strsclnt completed at `date`"
html_msg $ret $value "${testname}"
@@ -323,6 +328,8 @@ if [ -z "$DO_REM_ST" -a -z "$DO_DIST_ST" ] ; then
CLIENTDIR=$EXT_CLIENTDIR
R_SERVERDIR=$R_EXT_SERVERDIR
R_CLIENTDIR=$R_EXT_CLIENTDIR
+ P_R_SERVERDIR=$P_R_EXT_SERVERDIR
+ P_R_CLIENTDIR=$P_R_EXT_CLIENTDIR
USER_NICKNAME=ExtendedSSLUser
NORM_EXT="Extended test"
cd ${CLIENTDIR}
diff --git a/security/nss/tests/ssl/ssl_dist_stress.sh b/security/nss/tests/ssl/ssl_dist_stress.sh
index b418f80d7..e9b328e4b 100755
--- a/security/nss/tests/ssl/ssl_dist_stress.sh
+++ b/security/nss/tests/ssl/ssl_dist_stress.sh
@@ -198,7 +198,7 @@ ssl_ds_rem_stress()
CONTINUE=$MAX_CERT
while [ $CONTINUE -ge $MIN_CERT ]
do
- echo "strsclnt -D -p ${PORT} -d . -w nss -c 1 $verbose "
+ echo "strsclnt -D -p ${PORT} -d ${P_R_CLIENTDIR} -w nss -c 1 $verbose "
echo " -n TestUser$CONTINUE ${HOSTADDR} #`uname -n`"
strsclnt -D -p ${PORT} -d . -w nss -c 1 $verbose \
-n "TestUser$CONTINUE" ${HOSTADDR} &
@@ -289,9 +289,9 @@ ssl_ds_dist_stress()
sleep 500 # give the clients time to finish #FIXME ADJUST
echo "GET /stop HTTP/1.0\n\n" > stdin.txt #check to make sure it has /r/n
- echo "tstclnt -h $HOSTADDR -p 8443 -d ${CLIENTDIR} -n TestUser0 "
+ echo "tstclnt -h $HOSTADDR -p 8443 -d ${P_R_CLIENTDIR} -n TestUser0 "
echo " -w nss -f < stdin.txt"
- tstclnt -h $HOSTADDR -p 8443 -d ${CLIENTDIR} -n TestUser0 \
+ tstclnt -h $HOSTADDR -p 8443 -d ${P_R_CLIENTDIR} -n TestUser0 \
-w nss -f < stdin.txt
html_msg 0 0 "${testname}"
diff --git a/security/nss/tests/tools/tools.sh b/security/nss/tests/tools/tools.sh
index bfab403d5..b301fc72b 100644
--- a/security/nss/tests/tools/tools.sh
+++ b/security/nss/tests/tools/tools.sh
@@ -82,6 +82,10 @@ tools_init()
R_TOOLSDIR=../tools
R_COPYDIR=../tools/copydir
+ P_R_COPYDIR=${R_COPYDIR}
+ if [ -n "${MULTIACCESS_DBM}" ]; then
+ P_R_COPYDIR="multiaccess:Tools.$version"
+ fi
mkdir -p ${TOOLSDIR}
mkdir -p ${COPYDIR}
@@ -97,17 +101,17 @@ tools_init()
tools_p12()
{
echo "$SCRIPTNAME: Exporting Alice's email cert & key------------------"
- echo "pk12util -o Alice.p12 -n \"Alice\" -d ${R_ALICEDIR} -k ${R_PWFILE} \\"
+ echo "pk12util -o Alice.p12 -n \"Alice\" -d ${P_R_ALICEDIR} -k ${R_PWFILE} \\"
echo " -w ${R_PWFILE}"
- pk12util -o Alice.p12 -n "Alice" -d ${R_ALICEDIR} -k ${R_PWFILE} \
+ pk12util -o Alice.p12 -n "Alice" -d ${P_R_ALICEDIR} -k ${R_PWFILE} \
-w ${R_PWFILE} 2>&1
ret=$?
html_msg $ret 0 "Exporting Alice's email cert & key (pk12util -o)"
check_tmpfile
echo "$SCRIPTNAME: Importing Alice's email cert & key -----------------"
- echo "pk12util -i Alice.p12 -d ${R_COPYDIR} -k ${R_PWFILE} -w ${R_PWFILE}"
- pk12util -i Alice.p12 -d ${R_COPYDIR} -k ${R_PWFILE} -w ${R_PWFILE} 2>&1
+ echo "pk12util -i Alice.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -w ${R_PWFILE}"
+ pk12util -i Alice.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -w ${R_PWFILE} 2>&1
ret=$?
html_msg $ret 0 "Importing Alice's email cert & key (pk12util -i)"
check_tmpfile
@@ -131,8 +135,8 @@ check_tmpfile()
tools_sign()
{
echo "$SCRIPTNAME: Create objsign cert -------------------------------"
- echo "signtool -G \"objectsigner\" -d ${R_ALICEDIR} -p \"nss\""
- signtool -G "objsigner" -d ${R_ALICEDIR} -p "nss" 2>&1 <<SIGNSCRIPT
+ echo "signtool -G \"objectsigner\" -d ${P_R_ALICEDIR} -p \"nss\""
+ signtool -G "objsigner" -d ${P_R_ALICEDIR} -p "nss" 2>&1 <<SIGNSCRIPT
y
TEST
MOZ
@@ -145,19 +149,20 @@ SIGNSCRIPT
html_msg $? 0 "Create objsign cert (signtool -G)"
echo "$SCRIPTNAME: Signing a set of files ----------------------------"
- echo "signtool -Z nojs.jar -d ${R_ALICEDIR} -p \"nss\" -k objsigner \\"
+ echo "signtool -Z nojs.jar -d ${P_R_ALICEDIR} -p \"nss\" -k objsigner \\"
echo " ${R_TOOLSDIR}/html"
- signtool -Z nojs.jar -d ${R_ALICEDIR} -p "nss" -k objsigner ${R_TOOLSDIR}/html
+ signtool -Z nojs.jar -d ${P_R_ALICEDIR} -p "nss" -k objsigner \
+ ${R_TOOLSDIR}/html
html_msg $? 0 "Signing a set of files (signtool -Z)"
echo "$SCRIPTNAME: Listing signed files in jar ----------------------"
- echo "signtool -v nojs.jar -d ${R_ALICEDIR} -p nss -k objsigner"
- signtool -v nojs.jar -d ${R_ALICEDIR} -p nss -k objsigner
+ echo "signtool -v nojs.jar -d ${P_R_ALICEDIR} -p nss -k objsigner"
+ signtool -v nojs.jar -d ${P_R_ALICEDIR} -p nss -k objsigner
html_msg $? 0 "Listing signed files in jar (signtool -v)"
echo "$SCRIPTNAME: Show who signed jar ------------------------------"
- echo "signtool -w nojs.jar -d ${R_ALICEDIR}"
- signtool -w nojs.jar -d ${R_ALICEDIR}
+ echo "signtool -w nojs.jar -d ${P_R_ALICEDIR}"
+ signtool -w nojs.jar -d ${P_R_ALICEDIR}
html_msg $? 0 "Show who signed jar (signtool -w)"
}