summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--security/nss/cmd/certutil/certutil.c64
-rw-r--r--security/nss/cmd/crlutil/crlutil.c21
-rw-r--r--security/nss/cmd/crlutil/manifest.mn2
-rw-r--r--security/nss/cmd/lib/seccnames.c2
-rw-r--r--security/nss/cmd/lib/secutil.c15
-rw-r--r--security/nss/cmd/modutil/manifest.mn5
-rw-r--r--security/nss/cmd/modutil/modutil.c38
-rw-r--r--security/nss/cmd/modutil/pk11.c25
-rw-r--r--security/nss/cmd/ocspclnt/ocspclnt.c3
-rw-r--r--security/nss/cmd/platlibs.mk4
-rw-r--r--security/nss/cmd/rsaperf/defkey.c18
-rw-r--r--security/nss/cmd/rsaperf/rsaperf.c17
-rw-r--r--security/nss/cmd/signtool/certgen.c3
-rw-r--r--security/nss/cmd/signtool/list.c8
-rw-r--r--security/nss/cmd/swfort/instinit/instinit.c3
-rw-r--r--security/nss/cmd/swfort/newuser/newuser.c5
-rw-r--r--security/nss/lib/asn1/asn1.c17
-rw-r--r--security/nss/lib/base/list.c5
-rw-r--r--security/nss/lib/base/nssbaset.h4
-rw-r--r--security/nss/lib/base/utf8.c4
-rw-r--r--security/nss/lib/certdb/cert.h89
-rw-r--r--security/nss/lib/certdb/certdb.c162
-rw-r--r--security/nss/lib/certdb/certdb.h344
-rw-r--r--security/nss/lib/certdb/certinit.c416
-rw-r--r--security/nss/lib/certdb/certt.h13
-rw-r--r--security/nss/lib/certdb/crl.c218
-rw-r--r--security/nss/lib/certdb/manifest.mn10
-rw-r--r--security/nss/lib/certdb/pcertdb.c7490
-rw-r--r--security/nss/lib/certdb/stanpcertdb.c1036
-rw-r--r--security/nss/lib/certhigh/certhigh.c43
-rw-r--r--security/nss/lib/certhigh/certvfy.c26
-rw-r--r--security/nss/lib/certhigh/ocsp.c296
-rw-r--r--security/nss/lib/certhigh/ocsp.h5
-rw-r--r--security/nss/lib/certhigh/ocspti.h6
-rw-r--r--security/nss/lib/ckfw/ckt.h170
-rw-r--r--security/nss/lib/ckfw/manifest.mn2
-rw-r--r--security/nss/lib/ckfw/nssckepv.h100
-rw-r--r--security/nss/lib/ckfw/nssckft.h459
-rw-r--r--security/nss/lib/ckfw/nssckg.h528
-rw-r--r--security/nss/lib/ckfw/nssckp.h66
-rw-r--r--security/nss/lib/ckfw/nssckt.h1091
-rw-r--r--security/nss/lib/cryptohi/seckey.c8
-rw-r--r--security/nss/lib/dev/ckhelper.h4
-rw-r--r--security/nss/lib/dev/dev.h4
-rw-r--r--security/nss/lib/dev/devm.h4
-rw-r--r--security/nss/lib/dev/devmod.c (renamed from security/nss/lib/dev/module.c)8
-rw-r--r--security/nss/lib/dev/devslot.c (renamed from security/nss/lib/dev/slot.c)0
-rw-r--r--security/nss/lib/dev/devt.h7
-rw-r--r--security/nss/lib/dev/devtoken.c (renamed from security/nss/lib/dev/token.c)49
-rw-r--r--security/nss/lib/dev/devutil.c (renamed from security/nss/lib/dev/util.c)0
-rw-r--r--security/nss/lib/dev/manifest.mn10
-rw-r--r--security/nss/lib/dev/nssdevt.h9
-rw-r--r--security/nss/lib/fortcrypt/swfort/pkcs11/Makefile4
-rw-r--r--security/nss/lib/jar/jarevil.c7
-rw-r--r--security/nss/lib/jar/jarevil.h2
-rw-r--r--security/nss/lib/jar/jarint.h2
-rw-r--r--security/nss/lib/jar/jarver.c46
-rw-r--r--security/nss/lib/manifest.mn40
-rw-r--r--security/nss/lib/nss/config.mk89
-rw-r--r--security/nss/lib/nss/manifest.mn2
-rw-r--r--security/nss/lib/nss/nss.def1
-rw-r--r--security/nss/lib/nss/nssinit.c4
-rw-r--r--security/nss/lib/nss/nsssym.c429
-rw-r--r--security/nss/lib/pk11wrap/dev3hack.c (renamed from security/nss/lib/dev/nss3hack.c)15
-rw-r--r--security/nss/lib/pk11wrap/dev3hack.h (renamed from security/nss/lib/dev/devnss3hack.h)8
-rw-r--r--security/nss/lib/pk11wrap/manifest.mn6
-rw-r--r--security/nss/lib/pk11wrap/pk11cert.c892
-rw-r--r--security/nss/lib/pk11wrap/pk11func.h18
-rw-r--r--security/nss/lib/pk11wrap/pk11init.h (renamed from security/nss/lib/ckfw/nsscku.h)68
-rw-r--r--security/nss/lib/pk11wrap/pk11kea.c10
-rw-r--r--security/nss/lib/pk11wrap/pk11pbe.c689
-rw-r--r--security/nss/lib/pk11wrap/pk11pk12.c53
-rw-r--r--security/nss/lib/pk11wrap/pk11pqg.c12
-rw-r--r--security/nss/lib/pk11wrap/pk11skey.c71
-rw-r--r--security/nss/lib/pk11wrap/pk11slot.c175
-rw-r--r--security/nss/lib/pk11wrap/pk11util.c2
-rw-r--r--security/nss/lib/pk11wrap/secmodt.h9
-rw-r--r--security/nss/lib/pk11wrap/secmodti.h18
-rw-r--r--security/nss/lib/pkcs12/p12d.c44
-rw-r--r--security/nss/lib/pkcs12/p12dec.c4
-rw-r--r--security/nss/lib/pkcs12/p12e.c13
-rw-r--r--security/nss/lib/pkcs12/p12plcy.c2
-rw-r--r--security/nss/lib/pkcs7/p7common.c30
-rw-r--r--security/nss/lib/pkcs7/p7decode.c14
-rw-r--r--security/nss/lib/pkcs7/p7encode.c1
-rw-r--r--security/nss/lib/pkcs7/p7local.c2
-rw-r--r--security/nss/lib/pki/certdecode.c2
-rw-r--r--security/nss/lib/pki/certificate.c29
-rw-r--r--security/nss/lib/pki/manifest.mn4
-rw-r--r--security/nss/lib/pki/pki3hack.c (renamed from security/nss/lib/pki/nss3hack.c)76
-rw-r--r--security/nss/lib/pki/pki3hack.h (renamed from security/nss/lib/pki/pkinss3hack.h)0
-rw-r--r--security/nss/lib/pki/tdcache.c6
-rw-r--r--security/nss/lib/pki/trustdomain.c9
-rw-r--r--security/nss/lib/pki1/Makefile8
-rw-r--r--security/nss/lib/pki1/atav.c13
-rw-r--r--security/nss/lib/pki1/manifest.mn5
-rwxr-xr-xsecurity/nss/lib/pki1/oidgen.perl10
-rw-r--r--security/nss/lib/smime/cmscipher.c2
-rw-r--r--security/nss/lib/smime/cmsenvdata.c2
-rw-r--r--security/nss/lib/smime/cmssigdata.c2
-rw-r--r--security/nss/lib/softoken/alghmac.c22
-rw-r--r--security/nss/lib/softoken/alghmac.h4
-rw-r--r--security/nss/lib/softoken/cdbhdl.h (renamed from security/nss/lib/certdb/cdbhdl.h)7
-rw-r--r--security/nss/lib/softoken/config.mk81
-rw-r--r--security/nss/lib/softoken/dbinit.c141
-rw-r--r--security/nss/lib/softoken/fipstest.c18
-rw-r--r--security/nss/lib/softoken/fipstokn.c75
-rw-r--r--security/nss/lib/softoken/keydb.c1094
-rw-r--r--security/nss/lib/softoken/keydbi.h (renamed from security/nss/lib/softoken/private.h)14
-rw-r--r--security/nss/lib/softoken/keydbt.h88
-rw-r--r--security/nss/lib/softoken/keytboth.h71
-rw-r--r--security/nss/lib/softoken/keytlow.h75
-rw-r--r--security/nss/lib/softoken/lowcert.c525
-rw-r--r--security/nss/lib/softoken/lowkey.c108
-rw-r--r--security/nss/lib/softoken/lowkeyi.h (renamed from security/nss/lib/softoken/keylow.h)98
-rw-r--r--security/nss/lib/softoken/lowkeyti.h138
-rw-r--r--security/nss/lib/softoken/lowpbe.c1184
-rw-r--r--security/nss/lib/softoken/lowpbe.h132
-rw-r--r--security/nss/lib/softoken/mac_rand.c (renamed from security/nss/lib/util/mac_rand.c)0
-rw-r--r--security/nss/lib/softoken/manifest.mn31
-rw-r--r--security/nss/lib/softoken/os2_rand.c (renamed from security/nss/lib/util/os2_rand.c)0
-rw-r--r--security/nss/lib/softoken/pcert.h147
-rw-r--r--security/nss/lib/softoken/pcertdb.c4410
-rw-r--r--security/nss/lib/softoken/pcertt.h433
-rw-r--r--security/nss/lib/softoken/pk11db.c190
-rw-r--r--security/nss/lib/softoken/pk11pars.h4
-rw-r--r--security/nss/lib/softoken/pkcs11.c3194
-rw-r--r--security/nss/lib/softoken/pkcs11.h13
-rw-r--r--security/nss/lib/softoken/pkcs11c.c808
-rw-r--r--security/nss/lib/softoken/pkcs11f.h9
-rw-r--r--security/nss/lib/softoken/pkcs11i.h206
-rw-r--r--security/nss/lib/softoken/pkcs11t.h336
-rw-r--r--security/nss/lib/softoken/pkcs11u.c1697
-rw-r--r--security/nss/lib/softoken/rsawrapr.c288
-rw-r--r--security/nss/lib/softoken/secpkcs5.c1849
-rw-r--r--security/nss/lib/softoken/secpkcs5.h185
-rw-r--r--security/nss/lib/softoken/softoken.h23
-rw-r--r--security/nss/lib/softoken/softokn.def57
-rw-r--r--security/nss/lib/softoken/softokn.rc98
-rw-r--r--security/nss/lib/softoken/sysrand.c (renamed from security/nss/lib/util/sysrand.c)3
-rw-r--r--security/nss/lib/softoken/unix_rand.c (renamed from security/nss/lib/util/unix_rand.c)0
-rw-r--r--security/nss/lib/softoken/win_rand.c (renamed from security/nss/lib/util/win_rand.c)0
-rw-r--r--security/nss/lib/ssl/ssl3con.c4
-rw-r--r--security/nss/lib/util/manifest.mn11
-rw-r--r--security/nss/lib/util/nssilckt.h219
-rw-r--r--security/nss/lib/util/nssilock.h76
-rw-r--r--security/nss/lib/util/secoid.c6
147 files changed, 14569 insertions, 19489 deletions
diff --git a/security/nss/cmd/certutil/certutil.c b/security/nss/cmd/certutil/certutil.c
index b8cb13758..403332bd7 100644
--- a/security/nss/cmd/certutil/certutil.c
+++ b/security/nss/cmd/certutil/certutil.c
@@ -272,7 +272,7 @@ GetYesNo(char *prompt)
static SECStatus
AddCert(PK11SlotInfo *slot, CERTCertDBHandle *handle, char *name, char *trusts,
- PRFileDesc *inFile, PRBool ascii, PRBool emailcert)
+ PRFileDesc *inFile, PRBool ascii, PRBool emailcert, void *pwdata)
{
CERTCertTrust *trust = NULL;
CERTCertificate *cert = NULL, *tempCert = NULL;
@@ -308,6 +308,7 @@ 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.
@@ -320,6 +321,7 @@ AddCert(PK11SlotInfo *slot, CERTCertDBHandle *handle, char *name, char *trusts,
if (!PK11_IsInternal(slot)) {
tempCert->trust = trust;
+
rv = PK11_ImportCertForKeyToSlot(slot, tempCert, name,
PR_FALSE, NULL);
}
@@ -337,9 +339,36 @@ AddCert(PK11SlotInfo *slot, CERTCertDBHandle *handle, char *name, char *trusts,
if ( emailcert )
CERT_SaveSMimeProfile(tempCert, NULL, NULL);
+#else
+ cert->trust = trust;
+ rv = PK11_Authenticate(slot, PR_TRUE, pwdata);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "could authenticate to token or database");
+ GEN_BREAK(SECFailure);
+ }
+
+ rv = PK11_ImportCert(slot, cert, CK_INVALID_HANDLE, name, PR_FALSE);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "could not add certificate to token or database");
+ GEN_BREAK(SECFailure);
+ }
+
+ rv = CERT_ChangeCertTrust(handle, cert, trust);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "could not change trust on certificate");
+ GEN_BREAK(SECFailure);
+ }
+
+ if ( emailcert ) {
+ CERT_SaveSMimeProfile(cert, NULL, pwdata);
+ }
+
+#endif
} while (0);
+#ifdef notdef
CERT_DestroyCertificate (tempCert);
+#endif
CERT_DestroyCertificate (cert);
PORT_Free(trust);
PORT_Free(certDER.data);
@@ -525,8 +554,8 @@ printCertCB(CERTCertificate *cert, void *arg)
if (trust) {
SECU_PrintTrustFlags(stdout, trust,
"Certificate Trust Flags", 1);
- } else {
- SECU_PrintTrustFlags(stdout, &cert->dbEntry->trust,
+ } else if (cert->trust) {
+ SECU_PrintTrustFlags(stdout, cert->trust,
"Certificate Trust Flags", 1);
}
@@ -544,6 +573,7 @@ listCerts(CERTCertDBHandle *handle, char *name, PK11SlotInfo *slot,
PRInt32 numBytes;
SECStatus rv;
+#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().
@@ -584,8 +614,9 @@ listCerts(CERTCertDBHandle *handle, char *name, PK11SlotInfo *slot,
NULL);
}
} else {
+#endif
/* List certs on a non-internal slot. */
- if (PK11_NeedLogin(slot))
+ if ( !PK11_IsFriendly(slot) && PK11_NeedLogin(slot))
PK11_Authenticate(slot, PR_TRUE, pwarg);
if (name) {
CERTCertificate *the_cert;
@@ -594,7 +625,22 @@ listCerts(CERTCertDBHandle *handle, char *name, PK11SlotInfo *slot,
SECU_PrintError(progName, "Could not find: %s\n", name);
return SECFailure;
}
- rv = printCertCB(the_cert, the_cert->trust);
+ 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);
}
@@ -602,7 +648,9 @@ listCerts(CERTCertDBHandle *handle, char *name, PK11SlotInfo *slot,
SECU_PrintError(progName, "problem printing certificate nicknames");
return SECFailure;
}
+#ifdef notdef
}
+#endif
return SECSuccess; /* not rv ?? */
}
@@ -2690,7 +2738,7 @@ main(int argc, char **argv)
certutil.options[opt_Trust].arg,
inFile,
certutil.options[opt_ASCIIForIO].activated,
- certutil.commands[cmd_AddEmailCert].activated);
+ certutil.commands[cmd_AddEmailCert].activated,&pwdata);
if (rv)
return 255;
}
@@ -2701,9 +2749,13 @@ main(int argc, char **argv)
PR_Delete(certreqfile);
}
+#ifdef notdef
if ( certHandle ) {
CERT_ClosePermCertDB(certHandle);
}
+#else
+ NSS_Shutdown();
+#endif
return rv;
}
diff --git a/security/nss/cmd/crlutil/crlutil.c b/security/nss/cmd/crlutil/crlutil.c
index b2633c40d..8d0dadc9d 100644
--- a/security/nss/cmd/crlutil/crlutil.c
+++ b/security/nss/cmd/crlutil/crlutil.c
@@ -64,7 +64,7 @@ static CERTSignedCrl *FindCRL
return ((CERTSignedCrl *)NULL);
}
- crl = SEC_FindCrlByKey(certHandle, &cert->derSubject, type);
+ crl = SEC_FindCrlByName(certHandle, &cert->derSubject, type);
if (crl ==NULL)
SECU_PrintError
(progName, "could not find %s's CRL", name);
@@ -81,7 +81,7 @@ static void DisplayCRL (CERTCertDBHandle *certHandle, char *nickName, int crlTyp
if (crl) {
SECU_PrintCRLInfo (stdout, &crl->crl, "CRL Info:\n", 0);
- CERT_DestroyCrl (crl);
+ SEC_DestroyCrl (crl);
}
}
@@ -124,10 +124,8 @@ static void ListCRLNames (CERTCertDBHandle *certHandle, int crlType)
fprintf (stdout, "\n");
fprintf (stdout, "\n%-40s %-5s\n\n", "CRL names", "CRL Type");
while (crlNode) {
- mark = PORT_ArenaMark (arena);
- rv = SEC_ASN1DecodeItem
- (arena, name, CERT_NameTemplate, &(crlNode->crl->crl.derName));
- if (!name){
+ name = &crlNode->crl->crl.name;
+ if (!name){
fprintf(stderr, "%s: fail to get the CRL issuer name\n", progName,
SECU_Strerror(PORT_GetError()));
break;
@@ -135,7 +133,6 @@ static void ListCRLNames (CERTCertDBHandle *certHandle, int crlType)
fprintf (stdout, "\n%-40s %-5s\n", CERT_NameToAscii(name), "CRL");
crlNode = crlNode->next;
- PORT_ArenaRelease (arena, mark);
}
} while (0);
@@ -172,14 +169,6 @@ static SECStatus DeleteCRL (CERTCertDBHandle *certHandle, char *name, int type)
name, SECU_Strerror(PORT_GetError()));
return SECFailure;
}
-
- rv = SEC_DeleteTempCrl (crl);
- if (rv != SECSuccess) {
- SECU_PrintError
- (progName, "fail to delete the issuer %s's CRL from the temp dbase (reason: %s)",
- name, SECU_Strerror(PORT_GetError()));
- return SECFailure;
- }
return (rv);
}
@@ -214,7 +203,7 @@ SECStatus ImportCRL (CERTCertDBHandle *certHandle, char *url, int type,
(progName, "unable to import CRL");
}
PORT_Free (crlDER.data);
- CERT_DestroyCrl (crl);
+ SEC_DestroyCrl (crl);
return (rv);
}
diff --git a/security/nss/cmd/crlutil/manifest.mn b/security/nss/cmd/crlutil/manifest.mn
index e63d71c05..72fafb24a 100644
--- a/security/nss/cmd/crlutil/manifest.mn
+++ b/security/nss/cmd/crlutil/manifest.mn
@@ -50,4 +50,4 @@ CSRCS = crlutil.c
# PROGRAM = ./$(OBJDIR)/crlutil.exe
PROGRAM = crlutil
-USE_STATIC_LIBS = 1
+#USE_STATIC_LIBS = 1
diff --git a/security/nss/cmd/lib/seccnames.c b/security/nss/cmd/lib/seccnames.c
index b2acdfb37..833361e41 100644
--- a/security/nss/cmd/lib/seccnames.c
+++ b/security/nss/cmd/lib/seccnames.c
@@ -82,7 +82,7 @@ sec_CollectCertNamesAndTrust(CERTCertificate *cert, SECItem *unknown, void *arg)
int i;
i = pCertNames->numCerts;
- name = cert->dbEntry->nickname ? cert->dbEntry->nickname : cert->emailAddr;
+ name = cert->nickname ? cert->nickname : cert->emailAddr;
if (name)
pCertNames->nameAndTrustEntries[i].name = PORT_Strdup(name);
diff --git a/security/nss/cmd/lib/secutil.c b/security/nss/cmd/lib/secutil.c
index f82a0e07a..b706ab7b7 100644
--- a/security/nss/cmd/lib/secutil.c
+++ b/security/nss/cmd/lib/secutil.c
@@ -1518,20 +1518,6 @@ SECU_PrintCertNickname(CERTCertificate *cert, void *data)
PORT_Memset (trusts, 0, sizeof (trusts));
out = (FILE *)data;
- if ( cert->dbEntry ) {
- name = cert->dbEntry->nickname;
- if ( name == NULL ) {
- name = cert->emailAddr;
- }
-
- trust = &cert->dbEntry->trust;
- printflags(trusts, trust->sslFlags);
- PORT_Strcat(trusts, ",");
- printflags(trusts, trust->emailFlags);
- PORT_Strcat(trusts, ",");
- printflags(trusts, trust->objectSigningFlags);
- fprintf(out, "%-60s %-5s\n", name, trusts);
- } else {
name = cert->nickname;
if ( name == NULL ) {
name = cert->emailAddr;
@@ -1548,7 +1534,6 @@ SECU_PrintCertNickname(CERTCertificate *cert, void *data)
PORT_Memcpy(trusts,",,",3);
}
fprintf(out, "%-60s %-5s\n", name, trusts);
- }
return (SECSuccess);
}
diff --git a/security/nss/cmd/modutil/manifest.mn b/security/nss/cmd/modutil/manifest.mn
index fb0ac6ae3..a40aec6db 100644
--- a/security/nss/cmd/modutil/manifest.mn
+++ b/security/nss/cmd/modutil/manifest.mn
@@ -54,6 +54,7 @@ REQUIRES = seccmd security dbm
DEFINES = -DNSPR20
-INCLUDES =
+# sigh
+INCLUDES += -I$(CORE_DEPTH)/nss/lib/pk11wrap
-USE_STATIC_LIBS = 1
+USE_STATIC_LIBS = 1
diff --git a/security/nss/cmd/modutil/modutil.c b/security/nss/cmd/modutil/modutil.c
index 522d070b4..b3505f7fc 100644
--- a/security/nss/cmd/modutil/modutil.c
+++ b/security/nss/cmd/modutil/modutil.c
@@ -57,6 +57,7 @@ typedef enum {
JAR_COMMAND,
LIST_COMMAND,
RAW_LIST_COMMAND,
+ RAW_ADD_COMMAND,
UNDEFAULT_COMMAND
} Command;
@@ -74,6 +75,7 @@ static char *commandNames[] = {
"-jar",
"-list",
"-rawlist",
+ "-rawadd",
"-undefault"
};
@@ -81,6 +83,7 @@ static char *commandNames[] = {
/* this enum must be kept in sync with the optionStrings list */
typedef enum {
ADD_ARG=0,
+ RAW_ADD_ARG,
CHANGEPW_ARG,
CIPHERS_ARG,
CREATE_ARG,
@@ -112,6 +115,7 @@ typedef enum {
/* This list must be kept in sync with the Arg enum */
static char *optionStrings[] = {
"-add",
+ "-rawadd",
"-changepw",
"-ciphers",
"-create",
@@ -150,6 +154,7 @@ static Command command = NO_COMMAND;
static char* pwFile = NULL;
static char* newpwFile = NULL;
static char* moduleName = NULL;
+static char* moduleSpec = NULL;
static char* slotName = NULL;
static char* secmodName = NULL;
static char* tokenName = NULL;
@@ -398,6 +403,18 @@ parse_args(int argc, char *argv[])
moduleName = argv[++i];
}
break;
+ case RAW_ADD_ARG:
+ if(command != NO_COMMAND) {
+ PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
+ return MULTIPLE_COMMAND_ERR;
+ }
+ command = RAW_ADD_COMMAND;
+ if(TRY_INC(i, argc)) {
+ PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
+ return OPTION_NEEDS_ARG_ERR;
+ }
+ moduleSpec = argv[i];
+ break;
case MECHANISMS_ARG:
if(mechanisms != NULL) {
PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg);
@@ -500,6 +517,8 @@ verify_params()
case LIST_COMMAND:
case RAW_LIST_COMMAND:
break;
+ case RAW_ADD_COMMAND:
+ break;
case UNDEFAULT_COMMAND:
case DEFAULT_COMMAND:
if(mechanisms == NULL) {
@@ -777,17 +796,26 @@ main(int argc, char *argv[])
goto loser;
}
- if (command == RAW_LIST_COMMAND) {
+ if ((command == RAW_LIST_COMMAND) || (command == RAW_ADD_COMMAND)) {
if(!moduleName) {
+ char *readOnlyStr, *noCertDBStr, *sep;
if (!secmodName) secmodName="secmod.db";
if (!dbprefix) dbprefix = "";
+ sep = ((command == RAW_LIST_COMMAND) && nocertdb) ? "," : " ";
+ readOnlyStr = (command == RAW_LIST_COMMAND) ? "readOnly" : "" ;
+ noCertDBStr = nocertdb ? "noCertDB" : "";
SECU_ConfigDirectory(dbdir);
- moduleName=PR_smprintf("name=\"NSS default Module DB\" parameters=\"configdir=%s certPrefix=%s keyPrefix=%s secmod=%s flags=readOnly%s\" NSS=\"flags=internal,moduleDB,moduleDBOnly,critical\"",
- SECU_ConfigDirectory(NULL),dbprefix,
- dbprefix,secmodName, nocertdb?",noCertDB":"");
+ moduleName=PR_smprintf("name=\"NSS default Module DB\" parameters=\"configdir=%s certPrefix=%s keyPrefix=%s secmod=%s flags=%s%s%s\" NSS=\"flags=internal,moduleDB,moduleDBOnly,critical\"",
+ SECU_ConfigDirectory(NULL),dbprefix, dbprefix,
+ secmodName, readOnlyStr,sep, noCertDBStr);
+ }
+ if (command == RAW_LIST_COMMAND) {
+ errcode = RawListModule(moduleName);
+ } else {
+ PORT_Assert(moduleSpec);
+ errcode = RawAddModule(moduleName,moduleSpec);
}
- errcode = RawListModule(moduleName);
goto loser;
}
diff --git a/security/nss/cmd/modutil/pk11.c b/security/nss/cmd/modutil/pk11.c
index 7f8433e8b..20838e6a0 100644
--- a/security/nss/cmd/modutil/pk11.c
+++ b/security/nss/cmd/modutil/pk11.c
@@ -303,6 +303,31 @@ RawListModule(char *modulespec)
return SUCCESS;
}
+RawAddModule(char *dbmodulespec, char *modulespec)
+{
+ SECMODModule *module;
+ SECMODModule *dbmodule;
+
+
+ dbmodule = SECMOD_LoadModule(dbmodulespec,NULL,PR_TRUE);
+ if (dbmodule == NULL) {
+ /* handle error */
+ return NO_SUCH_MODULE_ERR;
+ }
+
+ module = SECMOD_LoadModule(modulespec,dbmodule,PR_FALSE);
+ if (module == NULL) {
+ /* handle error */
+ return NO_SUCH_MODULE_ERR;
+ }
+
+ if( SECMOD_UpdateModule(module) != SECSuccess ) {
+ PR_fprintf(PR_STDERR, errStrings[UPDATE_MOD_FAILED_ERR], modulespec);
+ return UPDATE_MOD_FAILED_ERR;
+ }
+ return SUCCESS;
+}
+
/************************************************************************
*
* L i s t M o d u l e s
diff --git a/security/nss/cmd/ocspclnt/ocspclnt.c b/security/nss/cmd/ocspclnt/ocspclnt.c
index c26633fbe..a5a1448c6 100644
--- a/security/nss/cmd/ocspclnt/ocspclnt.c
+++ b/security/nss/cmd/ocspclnt/ocspclnt.c
@@ -859,7 +859,7 @@ print_response (FILE *out_file, SECItem *data, CERTCertDBHandle *handle)
}
sigStatus = CERT_VerifyOCSPResponseSignature (response, handle,
- NULL, &signerCert);
+ NULL, &signerCert, NULL);
SECU_Indent (out_file, level);
fprintf (out_file, "Signature verification ");
if (sigStatus != SECSuccess) {
@@ -1209,7 +1209,6 @@ nssdone:
if (handle != NULL) {
(void) CERT_DisableOCSPChecking (handle);
- CERT_ClosePermCertDB (handle);
}
NSS_Shutdown ();
diff --git a/security/nss/cmd/platlibs.mk b/security/nss/cmd/platlibs.mk
index 8c0220c4e..2b82b4a7f 100644
--- a/security/nss/cmd/platlibs.mk
+++ b/security/nss/cmd/platlibs.mk
@@ -61,7 +61,7 @@ EXTRA_LIBS += \
$(DIST)/lib/cryptohi.lib \
$(DIST)/lib/pk11wrap.lib \
$(DIST)/lib/certdb.lib \
- $(DIST)/lib/softoken.lib \
+ $(DIST)/lib/softokn.lib \
$(CRYPTOLIB) \
$(DIST)/lib/swfci.lib \
$(DIST)/lib/secutil.lib \
@@ -106,7 +106,7 @@ EXTRA_LIBS += \
$(DIST)/lib/libcerthi.$(LIB_SUFFIX) \
$(DIST)/lib/libnsspki.$(LIB_SUFFIX) \
$(DIST)/lib/libpk11wrap.$(LIB_SUFFIX) \
- $(DIST)/lib/libsoftoken.$(LIB_SUFFIX) \
+ $(DIST)/lib/libsoftokn.$(LIB_SUFFIX) \
$(DIST)/lib/libcertdb.$(LIB_SUFFIX) \
$(DIST)/lib/libnsspki.$(LIB_SUFFIX) \
$(DIST)/lib/libnssdev.$(LIB_SUFFIX) \
diff --git a/security/nss/cmd/rsaperf/defkey.c b/security/nss/cmd/rsaperf/defkey.c
index bcab2b683..fe4870d77 100644
--- a/security/nss/cmd/rsaperf/defkey.c
+++ b/security/nss/cmd/rsaperf/defkey.c
@@ -36,7 +36,7 @@
*/
#include "seccomon.h"
#include "secoidt.h"
-#include "keytlow.h"
+#include "lowkeyti.h"
#define CONST
@@ -100,16 +100,16 @@ static CONST unsigned char default_qInvModP[64] = {
};
-static struct SECKEYLowPrivateKeyStr rsaPriv;
+static struct NSSLOWKEYPrivateKeyStr rsaPriv;
-SECKEYLowPrivateKey *
+NSSLOWKEYPrivateKey *
getDefaultRSAPrivateKey(void)
{
- if (rsaPriv.keyType != lowRSAKey) {
+ if (rsaPriv.keyType != NSSLOWKEYRSAKey) {
/* leaving arena uninitialized. It isn't used in this test. */
- rsaPriv.keyType = lowRSAKey;
+ rsaPriv.keyType = NSSLOWKEYRSAKey;
/* leaving arena uninitialized. It isn't used. */
/* leaving version uninitialized. It isn't used. */
@@ -134,14 +134,14 @@ getDefaultRSAPrivateKey(void)
return &rsaPriv;
}
-static struct SECKEYLowPublicKeyStr rsaPub;
+static struct NSSLOWKEYPublicKeyStr rsaPub;
-SECKEYLowPublicKey *
+NSSLOWKEYPublicKey *
getDefaultRSAPublicKey(void)
{
- if (rsaPub.keyType != lowRSAKey) {
+ if (rsaPub.keyType != NSSLOWKEYRSAKey) {
- rsaPub.keyType = lowRSAKey;
+ rsaPub.keyType = NSSLOWKEYRSAKey;
rsaPub.u.rsa.modulus.data = default_n;
rsaPub.u.rsa.modulus.len = sizeof default_n;
diff --git a/security/nss/cmd/rsaperf/rsaperf.c b/security/nss/cmd/rsaperf/rsaperf.c
index dbfc21d01..36a9ea383 100644
--- a/security/nss/cmd/rsaperf/rsaperf.c
+++ b/security/nss/cmd/rsaperf/rsaperf.c
@@ -38,14 +38,14 @@
#include "nss.h"
#include "blapi.h"
#include "plgetopt.h"
-#include "keylow.h"
+#include "lowkeyi.h"
#define MAX_RSA_MODULUS_BYTES (1024/8)
#define DEFAULT_ITERS 10
-extern SECKEYLowPrivateKey * getDefaultRSAPrivateKey(void);
-extern SECKEYLowPublicKey * getDefaultRSAPublicKey(void);
+extern NSSLOWKEYPrivateKey * getDefaultRSAPrivateKey(void);
+extern NSSLOWKEYPublicKey * getDefaultRSAPublicKey(void);
typedef struct TimingContextStr TimingContext;
@@ -196,7 +196,7 @@ dumpItem( SECItem * item, const char * description)
}
void
-printPrivKey(SECKEYLowPrivateKey * privKey)
+printPrivKey(NSSLOWKEYPrivateKey * privKey)
{
RSAPrivateKey *rsa = &privKey->u.rsa;
@@ -226,10 +226,9 @@ int
main(int argc, char **argv)
{
TimingContext * timeCtx;
- SECKEYKeyDBHandle * keydb;
SECKEYPublicKey * pubHighKey;
- SECKEYLowPrivateKey * privKey;
- SECKEYLowPublicKey * pubKey;
+ NSSLOWKEYPrivateKey * privKey;
+ NSSLOWKEYPublicKey * pubKey;
CERTCertificate * cert;
char * progName;
char * secDir = NULL;
@@ -292,7 +291,6 @@ main(int argc, char **argv)
exit(1);
}
certdb = CERT_GetDefaultCertDB();
- keydb = SECKEY_GetDefaultKeyDB();
} else {
rv = NSS_NoDB_Init(secDir);
if (rv != SECSuccess) {
@@ -342,9 +340,6 @@ main(int argc, char **argv)
exit(1);
}
-#if 0
- printPrivKey(privKey);
-#endif
fn = (RSAOp)RSA_PrivateKeyOp;
rsaKey = (void *)(&privKey->u.rsa);
}
diff --git a/security/nss/cmd/signtool/certgen.c b/security/nss/cmd/signtool/certgen.c
index 0709e5b44..dd7128eaa 100644
--- a/security/nss/cmd/signtool/certgen.c
+++ b/security/nss/cmd/signtool/certgen.c
@@ -498,8 +498,7 @@ install_cert(CERTCertDBHandle *db, PK11SlotInfo *slot, SECItem *derCert,
CERTCertTrust trust;
PK11SlotInfo *newSlot;
- newcert = CERT_NewTempCertificate(db, derCert, NULL,
- /*isperm*/ PR_FALSE, /*copyDER*/ PR_TRUE);
+ newcert = CERT_DecodeDERCertificate(derCert, PR_TRUE, NULL);
if (newcert == NULL) {
PR_fprintf(errorFD, "%s: can't create new certificate\n", PROGRAM_NAME);
diff --git a/security/nss/cmd/signtool/list.c b/security/nss/cmd/signtool/list.c
index 83ae4d6a3..2e2d1d1ac 100644
--- a/security/nss/cmd/signtool/list.c
+++ b/security/nss/cmd/signtool/list.c
@@ -91,14 +91,6 @@ ListCerts(char *key, int list_certs)
return -1;
}
- /* Traverse Internal DB */
- rv = SEC_TraversePermCerts(db, cert_trav_callback, (void*)&list_certs);
-
- if (rv) {
- PR_fprintf(outputFD, "**Traverse of internal DB failed**\n");
- return -1;
- }
-
if (num_trav_certs == 0) {
PR_fprintf(outputFD,
"You don't appear to have any object signing certificates.\n");
diff --git a/security/nss/cmd/swfort/instinit/instinit.c b/security/nss/cmd/swfort/instinit/instinit.c
index 5c840bab4..f6e5e5e2f 100644
--- a/security/nss/cmd/swfort/instinit/instinit.c
+++ b/security/nss/cmd/swfort/instinit/instinit.c
@@ -318,7 +318,8 @@ main(int argc, char ** argv)
}
continue;
}
- cert = CERT_NewTempCertificate(certhandle,derCert, NULL,
+ cert = (CERTCertificate *)
+ __CERT_NewTempCertificate(certhandle,derCert, NULL,
PR_FALSE, PR_TRUE);
if (cert == NULL) {
if (verbose) {
diff --git a/security/nss/cmd/swfort/newuser/newuser.c b/security/nss/cmd/swfort/newuser/newuser.c
index f6862af31..94e6c21ab 100644
--- a/security/nss/cmd/swfort/newuser/newuser.c
+++ b/security/nss/cmd/swfort/newuser/newuser.c
@@ -40,7 +40,7 @@
#include "blapi.h" /* program calls low level functions directly!*/
#include "pk11func.h"
#include "secmod.h"
-#include "secmodi.h"
+/*#include "secmodi.h"*/
#include "cert.h"
#include "key.h"
#include "swforti.h"
@@ -791,7 +791,8 @@ main(int argc, char **argv)
}
derCert.data = origCert;
derCert.len = Cert_length(origCert, sizeof(origCert));
- cert = CERT_NewTempCertificate(certhandle,&derCert, NULL,
+ cert =
+ (CERTCertificate *)CERT_NewTempCertificate(certhandle,&derCert, NULL,
PR_FALSE, PR_TRUE);
caCert.valid[i].cert = cert;
if (cert == NULL) continue;
diff --git a/security/nss/lib/asn1/asn1.c b/security/nss/lib/asn1/asn1.c
index 3d5cfc8f7..9c584c770 100644
--- a/security/nss/lib/asn1/asn1.c
+++ b/security/nss/lib/asn1/asn1.c
@@ -316,7 +316,7 @@ nssASN1Decoder_Update
PRUint32 amount
)
{
- PRStatus rv;
+ SECStatus rv;
#ifdef DEBUG
if( PR_SUCCESS != nssASN1Decoder_verify(decoder) ) {
@@ -332,7 +332,7 @@ nssASN1Decoder_Update
rv = SEC_ASN1DecoderUpdate((SEC_ASN1DecoderContext *)decoder,
(const char *)data,
(unsigned long)amount);
- if( PR_SUCCESS != rv ) {
+ if( SECSuccess != rv ) {
nss_SetError(PORT_GetError()); /* ugly */
return PR_FAILURE;
}
@@ -361,7 +361,8 @@ nssASN1Decoder_Finish
nssASN1Decoder *decoder
)
{
- PRStatus rv;
+ PRStatus rv = PR_SUCCESS;
+ SECStatus srv;
#ifdef DEBUG
if( PR_SUCCESS != nssASN1Decoder_verify(decoder) ) {
@@ -369,10 +370,11 @@ nssASN1Decoder_Finish
}
#endif /* DEBUG */
- rv = SEC_ASN1DecoderFinish((SEC_ASN1DecoderContext *)decoder);
+ srv = SEC_ASN1DecoderFinish((SEC_ASN1DecoderContext *)decoder);
- if( PR_SUCCESS != rv ) {
+ if( SECSuccess != srv ) {
nss_SetError(PORT_GetError()); /* ugly */
+ rv = PR_FAILURE;
}
#ifdef DEBUG
@@ -763,7 +765,7 @@ nssASN1Encoder_Update
PRUint32 length
)
{
- PRStatus rv;
+ SECStatus rv;
#ifdef DEBUG
if( PR_SUCCESS != nssASN1Encoder_verify(encoder) ) {
@@ -778,7 +780,7 @@ nssASN1Encoder_Update
rv = SEC_ASN1EncoderUpdate((SEC_ASN1EncoderContext *)encoder,
(const char *)data,
(unsigned long)length);
- if( PR_SUCCESS != rv ) {
+ if( SECSuccess != rv ) {
nss_SetError(PORT_GetError()); /* ugly */
return PR_FAILURE;
}
@@ -1187,7 +1189,6 @@ nssASN1_EncodeItem
NSSASN1EncodingType encoding
)
{
- PLArenaPool *hack = (PLArenaPool *)arenaOpt;
NSSDER *rv;
PRUint32 len = 0;
PRStatus status;
diff --git a/security/nss/lib/base/list.c b/security/nss/lib/base/list.c
index 6bcde183c..7738633d4 100644
--- a/security/nss/lib/base/list.c
+++ b/security/nss/lib/base/list.c
@@ -91,7 +91,10 @@ nsslist_get_matching_element(nssList *list, void *data)
break;
}
link = &node->link;
- if (link == PR_LIST_TAIL(&list->head->link)) break;
+ if (link == PR_LIST_TAIL(&list->head->link)) {
+ node = NULL;
+ break;
+ }
node = (nssListElement *)PR_NEXT_LINK(&node->link);
}
return node;
diff --git a/security/nss/lib/base/nssbaset.h b/security/nss/lib/base/nssbaset.h
index f5cea5fb0..c3e84c46e 100644
--- a/security/nss/lib/base/nssbaset.h
+++ b/security/nss/lib/base/nssbaset.h
@@ -138,7 +138,7 @@ typedef NSSItem NSSBitString;
* Character strings encoded in UTF-8, as defined by RFC 2279.
*/
-typedef PRUint8 NSSUTF8;
+typedef char NSSUTF8;
/*
* NSSASCII7
@@ -146,7 +146,7 @@ typedef PRUint8 NSSUTF8;
* Character strings guaranteed to be 7-bit ASCII.
*/
-typedef PRUint8 NSSASCII7;
+typedef char NSSASCII7;
PR_END_EXTERN_C
diff --git a/security/nss/lib/base/utf8.c b/security/nss/lib/base/utf8.c
index 6be6912d7..3a8641f95 100644
--- a/security/nss/lib/base/utf8.c
+++ b/security/nss/lib/base/utf8.c
@@ -679,7 +679,7 @@ nssUTF8_CopyIntoFixedBuffer
#endif /* NSSDEBUG */
if( (NSSUTF8 *)NULL == string ) {
- string = (unsigned char*) "";
+ string = (NSSUTF8 *) "";
}
stringSize = nssUTF8_Size(string, (PRStatus *)NULL);
@@ -699,7 +699,7 @@ nssUTF8_CopyIntoFixedBuffer
}
/* Too long. We have to trim the last character */
- for( bs; bs != 0; bs-- ) {
+ for( /*bs*/; bs != 0; bs-- ) {
if( (buffer[bs-1] & 0xC0) != 0x80 ) {
buffer[bs-1] = pad;
break;
diff --git a/security/nss/lib/certdb/cert.h b/security/nss/lib/certdb/cert.h
index 5a70d7302..394d518f9 100644
--- a/security/nss/lib/certdb/cert.h
+++ b/security/nss/lib/certdb/cert.h
@@ -276,6 +276,10 @@ extern CERTCertDBHandle *CERT_GetDefaultCertDB(void);
extern CERTCertList *CERT_GetCertChainFromCert(CERTCertificate *cert,
int64 time,
SECCertUsage usage);
+extern CERTCertificate *
+CERT_NewTempCertificate (CERTCertDBHandle *handle, SECItem *derCert,
+ char *nickname, PRBool isperm, PRBool copyDER);
+
/******************************************************************************
*
@@ -397,26 +401,7 @@ extern void CERT_DestroyCrl (CERTSignedCrl *crl);
** Decode a certificate and put it into the temporary certificate database
*/
extern CERTCertificate *
-CERT_NewTempCertificate (CERTCertDBHandle *handle, SECItem *derCert,
- char *nickname, PRBool isperm, PRBool copyDER);
-
-/*
-** Add a certificate to the temporary database.
-** "dbCert" is the certificate from the perm database.
-** "isperm" indicates if the cert is in the permanent database.
-*/
-extern CERTCertificate *
-CERT_AddTempCertificate (CERTCertDBHandle *handle, certDBEntryCert *entry,
- PRBool isperm);
-
-/*
-** Add a temporary certificate to the permanent database.
-** "cert" is the temporary cert
-** "nickname" is the permanent nickname to use
-** "trust" is the certificate trust parameters to assign to the cert
-*/
-extern SECStatus
-CERT_AddTempCertToPerm (CERTCertificate *cert, char *nickname, CERTCertTrust *trust);
+CERT_DecodeCertificate (SECItem *derCert, char *nickname,PRBool copyDER);
/*
** Find a certificate in the database
@@ -425,16 +410,6 @@ CERT_AddTempCertToPerm (CERTCertificate *cert, char *nickname, CERTCertTrust *tr
extern CERTCertificate *CERT_FindCertByKey(CERTCertDBHandle *handle, SECItem *key);
/*
- * Lookup a certificate in the databases without locking
- * "certKey" is the database key to look for
- *
- * XXX - this should be internal, but pkcs 11 needs to call it during a
- * traversal.
- */
-CERTCertificate *
-CERT_FindCertByKeyNoLocking(CERTCertDBHandle *handle, SECItem *certKey);
-
-/*
** Find a certificate in the database by name
** "name" is the distinguished name to look up
*/
@@ -470,6 +445,7 @@ CERT_FindCertByIssuerAndSN (CERTCertDBHandle *handle, CERTIssuerAndSN *issuerAnd
*/
extern CERTCertificate *
CERT_FindCertByNickname (CERTCertDBHandle *handle, char *nickname);
+
/*
** Find a certificate in the database by a DER encoded certificate
** "derCert" is the DER encoded certificate
@@ -505,17 +481,6 @@ CERTCertificate *
CERT_FindCertIssuer(CERTCertificate *cert, int64 validTime, SECCertUsage usage);
/*
-** Delete a certificate from the temporary database
-** "cert" is the certificate to be deleted
-*/
-extern SECStatus CERT_DeleteTempCertificate(CERTCertificate *cert);
-
-/*
-** Flush and close the permanent database.
-*/
-extern void CERT_ClosePermCertDB(CERTCertDBHandle *handle);
-
-/*
** Check the validity times of a certificate vs. time 't', allowing
** some slop for broken clocks and stuff.
** "cert" is the certificate to be checked
@@ -641,6 +606,14 @@ extern char *CERT_HTMLCertInfo(CERTCertificate *cert, PRBool showImages,
*/
extern SECItem *CERT_DecodeAVAValue(SECItem *derAVAValue);
+/*
+ * take a DER certificate and decode it into a certificate structure
+ */
+CERTCertificate *
+CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
+ char *nickname);
+
+
/*
** extract various element strings from a distinguished name.
@@ -926,32 +899,6 @@ extern void CERT_DestroyCertificateList(CERTCertificateList *list);
/* is cert a newer than cert b? */
PRBool CERT_IsNewer(CERTCertificate *certa, CERTCertificate *certb);
-typedef SECStatus (* CERTCertCallback)(CERTCertificate *cert, void *arg);
-
-SECStatus
-CERT_TraversePermCertsForSubject(CERTCertDBHandle *handle, SECItem *derSubject,
- CERTCertCallback cb, void *cbarg);
-int
-CERT_NumPermCertsForSubject(CERTCertDBHandle *handle, SECItem *derSubject);
-
-SECStatus
-CERT_TraversePermCertsForNickname(CERTCertDBHandle *handle, char *nickname,
- CERTCertCallback cb, void *cbarg);
-
-int
-CERT_NumPermCertsForNickname(CERTCertDBHandle *handle, char *nickname);
-
-int
-CERT_NumCertsForCertSubject(CERTCertificate *cert);
-
-int
-CERT_NumPermCertsForCertSubject(CERTCertificate *cert);
-
-SECStatus
-CERT_TraverseCertsForSubject(CERTCertDBHandle *handle,
- CERTSubjectList *subjectList,
- CERTCertCallback cb, void *cbarg);
-
/* currently a stub for address book */
PRBool
CERT_IsCertRevoked(CERTCertificate *cert);
@@ -1009,12 +956,6 @@ CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile,
SECItem *
CERT_FindSMimeProfile(CERTCertificate *cert);
-int
-CERT_GetDBContentVersion(CERTCertDBHandle *handle);
-
-void
-CERT_SetDBContentVersion(int version, CERTCertDBHandle *handle);
-
SECStatus
CERT_AddNewCerts(CERTCertDBHandle *handle);
@@ -1370,6 +1311,8 @@ CERT_GetStatusConfig(CERTCertDBHandle *handle);
void
CERT_SetStatusConfig(CERTCertDBHandle *handle, CERTStatusConfig *config);
+
+
/*
* Acquire the cert reference count lock
* There is currently one global lock for all certs, but I'm putting a cert
diff --git a/security/nss/lib/certdb/certdb.c b/security/nss/lib/certdb/certdb.c
index 75413cc04..592418f5a 100644
--- a/security/nss/lib/certdb/certdb.c
+++ b/security/nss/lib/certdb/certdb.c
@@ -58,7 +58,7 @@
#include "secerr.h"
#include "sslerr.h"
#include "nsslocks.h"
-#include "cdbhdl.h"
+#include "pk11func.h"
#ifndef NSS_3_4_CODE
#define NSS_3_4_CODE
@@ -462,7 +462,7 @@ fortezzaIsCA( CERTCertificate *cert) {
unsigned char *end;
int len;
- rawkey = spki->subjectPublicKey;
+ rawkey = spki->subjectPublicKey;
DER_ConvertBitString(&rawkey);
rawptr = rawkey.data;
end = rawkey.data + rawkey.len;
@@ -489,7 +489,7 @@ fortezzaIsCA( CERTCertificate *cert) {
/* DSSPrivilege (the string up to the first byte with the hi-bit on */
if (*rawptr & 0x30) isCA = PR_TRUE;
-
+
}
return isCA;
}
@@ -627,12 +627,12 @@ CERT_GetCertType(CERTCertificate *cert)
cert->nsCertType = NS_CERT_TYPE_SSL_CLIENT | NS_CERT_TYPE_SSL_SERVER |
NS_CERT_TYPE_EMAIL;
- /* if the basic constraint extension says the cert is a CA, then
+ /* if the basic constraint extension says the cert is a CA, then
allow SSL CA and EMAIL CA and Status Responder */
if ((basicConstraintPresent == PR_TRUE)
&& (basicConstraint.isCA)) {
- cert->nsCertType |= NS_CERT_TYPE_SSL_CA;
- cert->nsCertType |= NS_CERT_TYPE_EMAIL_CA;
+ cert->nsCertType |= NS_CERT_TYPE_SSL_CA;
+ cert->nsCertType |= NS_CERT_TYPE_EMAIL_CA;
cert->nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER;
} else if (CERT_IsCACert(cert, NULL) == PR_TRUE) {
cert->nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER;
@@ -640,8 +640,8 @@ CERT_GetCertType(CERTCertificate *cert)
/* if the cert is a fortezza CA cert, then allow SSL CA and EMAIL CA */
if (fortezzaIsCA(cert)) {
- cert->nsCertType |= NS_CERT_TYPE_SSL_CA;
- cert->nsCertType |= NS_CERT_TYPE_EMAIL_CA;
+ cert->nsCertType |= NS_CERT_TYPE_SSL_CA;
+ cert->nsCertType |= NS_CERT_TYPE_EMAIL_CA;
}
}
@@ -688,9 +688,9 @@ cert_GetKeyID(CERTCertificate *cert)
cert->subjectKeyID.data = (unsigned char *)PORT_ArenaAlloc(cert->arena, 8);
if ( cert->subjectKeyID.data != NULL ) {
- PORT_Memcpy(cert->subjectKeyID.data, key->u.fortezza.KMID, 8);
- cert->subjectKeyID.len = 8;
- cert->keyIDGenerated = PR_FALSE;
+ PORT_Memcpy(cert->subjectKeyID.data, key->u.fortezza.KMID, 8);
+ cert->subjectKeyID.len = 8;
+ cert->keyIDGenerated = PR_FALSE;
}
}
@@ -705,7 +705,7 @@ cert_GetKeyID(CERTCertificate *cert)
*/
cert->subjectKeyID.data = (unsigned char *)PORT_ArenaAlloc(cert->arena, SHA1_LENGTH);
if ( cert->subjectKeyID.data != NULL ) {
- rv = SHA1_HashBuf(cert->subjectKeyID.data,
+ rv = PK11_HashBuf(SEC_OID_SHA1,cert->subjectKeyID.data,
cert->derPublicKey.data,
cert->derPublicKey.len);
if ( rv == SECSuccess ) {
@@ -725,7 +725,7 @@ cert_GetKeyID(CERTCertificate *cert)
* take a DER certificate and decode it into a certificate structure
*/
CERTCertificate *
-__CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
+CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
char *nickname)
{
CERTCertificate *cert;
@@ -833,7 +833,7 @@ __CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
cert->referenceCount = 1;
cert->slot = NULL;
- cert->pkcs11ID = CK_INVALID_KEY;
+ cert->pkcs11ID = CK_INVALID_HANDLE;
cert->dbnickname = NULL;
return(cert);
@@ -848,12 +848,13 @@ loser:
}
CERTCertificate *
-CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
+__CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
char *nickname)
{
- return(__CERT_DecodeDERCertificate(derSignedCert, copyDER, nickname));
+ return CERT_DecodeDERCertificate(derSignedCert, copyDER, nickname);
}
+
/*
** Amount of time that a certifiate is allowed good before it is actually
** good. This is used for pending certificates, ones that are about to be
@@ -909,7 +910,7 @@ CERT_CheckCertValidTimes(CERTCertificate *c, PRTime t, PRBool allowOverride)
/* if cert is already marked OK, then don't bother to check */
if ( allowOverride && c->timeOK ) {
- return(secCertTimeValid);
+ return(secCertTimeValid);
}
rv = CERT_GetCertTimes(c, &notBefore, &notAfter);
@@ -1184,70 +1185,6 @@ CERT_GetDefaultCertDB(void)
return(default_cert_db_handle);
}
-/*
- * Open volatile certificate database and index databases. This is a
- * fallback if the real databases can't be opened or created. It is only
- * resident in memory, so it will not be persistent. We do this so that
- * we don't crash if the databases can't be created.
- */
-SECStatus
-CERT_OpenVolatileCertDB(CERTCertDBHandle *handle)
-{
-#ifndef STAN_CERT_DB
-#define DBM_DEFAULT 0
- static const HASHINFO hashInfo = {
- DBM_DEFAULT, /* bucket size */
- DBM_DEFAULT, /* fill factor */
- DBM_DEFAULT, /* number of elements */
- 256 * 1024, /* bytes to cache */
- DBM_DEFAULT, /* hash function */
- DBM_DEFAULT /* byte order */
- };
- /*
- * Open the memory resident perm cert database.
- */
- handle->permCertDB = dbopen(0, O_RDWR | O_CREAT, 0600, DB_HASH, &hashInfo);
- if ( !handle->permCertDB ) {
- goto loser;
- }
-
- /*
- * Open the memory resident decoded cert database.
- */
- handle->tempCertDB = dbopen(0, O_RDWR | O_CREAT, 0600, DB_HASH, &hashInfo);
- if ( !handle->tempCertDB ) {
- goto loser;
- }
-
- handle->dbMon = PZ_NewMonitor(nssILockCertDB);
- PORT_Assert(handle->dbMon != NULL);
-
- handle->spkDigestInfo = NULL;
- handle->statusConfig = NULL;
-
- /* initialize the cert database */
- (void) CERT_InitCertDB(handle);
-
- return (SECSuccess);
-
-loser:
-
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
-
- if ( handle->permCertDB ) {
- (* handle->permCertDB->close)(handle->permCertDB);
- handle->permCertDB = 0;
- }
-
- if ( handle->tempCertDB ) {
- (* handle->tempCertDB->close)(handle->tempCertDB);
- handle->tempCertDB = 0;
- }
-
-#endif
- return(SECFailure);
-}
-
/* XXX this would probably be okay/better as an xp routine? */
static void
sec_lower_string(char *s)
@@ -1272,14 +1209,14 @@ SECStatus
CERT_AddOKDomainName(CERTCertificate *cert, const char *hn)
{
CERTOKDomainName *domainOK;
- int newNameLen;
+ int newNameLen;
if (!hn || !(newNameLen = strlen(hn))) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
domainOK = (CERTOKDomainName *)PORT_ArenaZAlloc(cert->arena,
- (sizeof *domainOK) + newNameLen);
+ (sizeof *domainOK) + newNameLen);
if (!domainOK)
return SECFailure; /* error code is already set. */
@@ -1705,14 +1642,12 @@ CERT_IsCACert(CERTCertificate *cert, unsigned int *rettype)
return(ret);
}
-
PRBool
CERT_IsCADERCert(SECItem *derCert, unsigned int *type) {
CERTCertificate *cert;
PRBool isCA;
- cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), derCert, NULL,
- PR_FALSE, PR_TRUE);
+ cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
if (cert == NULL) return PR_FALSE;
isCA = CERT_IsCACert(cert,type);
@@ -1961,8 +1896,8 @@ 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_NewTempCertificate(certdb, derCerts[i], NULL,
- PR_FALSE, PR_TRUE);
+ certs[fcerts] = CERT_DecodeDERCertificate(derCerts[i], PR_FALSE,
+ NULL);
if (certs[fcerts]) fcerts++;
}
@@ -1975,10 +1910,11 @@ CERT_ImportCerts(CERTCertDBHandle *certdb, SECCertUsage usage,
* otherwise if there are more than one cert, we don't
* know which cert it belongs to.
*/
- rv = CERT_SaveImportedCert(certs[i], usage, caOnly, NULL);
+ rv = PK11_ImportCert(PK11_GetInternalKeySlot(),certs[i],
+ CK_INVALID_HANDLE,NULL,PR_TRUE);
} else {
- rv = CERT_SaveImportedCert(certs[i], usage, caOnly,
- nickname);
+ rv = PK11_ImportCert(PK11_GetInternalKeySlot(),certs[i],
+ CK_INVALID_HANDLE,nickname,PR_TRUE);
}
/* don't care if it fails - keep going */
}
@@ -2321,40 +2257,6 @@ loser:
return(SECFailure);
}
-/*
- * Acquire the global lock on the cert database.
- * This lock is currently used for the following operations:
- * adding or deleting a cert to either the temp or perm databases
- * converting a temp to perm or perm to temp
- * changing(maybe just adding !?) the trust of a cert
- * chaning the DB status checking Configuration
- */
-void
-CERT_LockDB(CERTCertDBHandle *handle)
-{
-#ifndef STAN_CERT_DB
- PZ_EnterMonitor(handle->dbMon);
- return;
-#endif
-}
-
-/*
- * Free the global cert database lock.
- */
-void
-CERT_UnlockDB(CERTCertDBHandle *handle)
-{
-#ifndef STAN_CERT_DB
- PRStatus prstat;
-
- prstat = PZ_ExitMonitor(handle->dbMon);
-
- PORT_Assert(prstat == PR_SUCCESS);
-
- return;
-#endif
-}
-
static PZLock *certRefCountLock = NULL;
/*
@@ -2436,7 +2338,12 @@ CERT_UnlockCertTrust(CERTCertificate *cert)
CERTStatusConfig *
CERT_GetStatusConfig(CERTCertDBHandle *handle)
{
+#ifdef notdef
return handle->statusConfig;
+#else
+ /*PORT_Assert(0); */
+ return NULL;
+#endif
}
/*
@@ -2446,7 +2353,10 @@ CERT_GetStatusConfig(CERTCertDBHandle *handle)
void
CERT_SetStatusConfig(CERTCertDBHandle *handle, CERTStatusConfig *statusConfig)
{
+#ifdef notdef
PORT_Assert(handle->statusConfig == NULL);
-
handle->statusConfig = statusConfig;
+#else
+ PORT_Assert(0);
+#endif
}
diff --git a/security/nss/lib/certdb/certdb.h b/security/nss/lib/certdb/certdb.h
index 2d75ee8b5..736d5f097 100644
--- a/security/nss/lib/certdb/certdb.h
+++ b/security/nss/lib/certdb/certdb.h
@@ -34,247 +34,6 @@
#ifndef _CERTDB_H_
#define _CERTDB_H_
-#include "plarena.h"
-#include "prlong.h"
-/*
- * Certificate Database related definitions and data structures
- */
-
-/* version number of certificate database */
-#define CERT_DB_FILE_VERSION 7
-#ifdef USE_NS_ROOTS
-#define CERT_DB_CONTENT_VERSION 28
-#else
-#define CERT_DB_CONTENT_VERSION 2
-#endif
-
-#define SEC_DB_ENTRY_HEADER_LEN 3
-#define SEC_DB_KEY_HEADER_LEN 1
-
-/* All database entries have this form:
- *
- * byte offset field
- * ----------- -----
- * 0 version
- * 1 type
- * 2 flags
- */
-
-/* database entry types */
-typedef enum {
- certDBEntryTypeVersion = 0,
- certDBEntryTypeCert = 1,
- certDBEntryTypeNickname = 2,
- certDBEntryTypeSubject = 3,
- certDBEntryTypeRevocation = 4,
- certDBEntryTypeKeyRevocation = 5,
- certDBEntryTypeSMimeProfile = 6,
- certDBEntryTypeContentVersion = 7
-} certDBEntryType;
-
-typedef struct {
- certDBEntryType type;
- unsigned int version;
- unsigned int flags;
- PRArenaPool *arena;
-} certDBEntryCommon;
-
-/*
- * Certificate entry:
- *
- * byte offset field
- * ----------- -----
- * 0 sslFlags-msb
- * 1 sslFlags-lsb
- * 2 emailFlags-msb
- * 3 emailFlags-lsb
- * 4 objectSigningFlags-msb
- * 5 objectSigningFlags-lsb
- * 6 derCert-len-msb
- * 7 derCert-len-lsb
- * 8 nickname-len-msb
- * 9 nickname-len-lsb
- * ... derCert
- * ... nickname
- *
- * NOTE: the nickname string as stored in the database is null terminated,
- * in other words, the last byte of the db entry is always 0
- * if a nickname is present.
- * NOTE: if nickname is not present, then nickname-len-msb and
- * nickname-len-lsb will both be zero.
- */
-struct _certDBEntryCert {
- certDBEntryCommon common;
- CERTCertTrust trust;
- SECItem derCert;
- char *nickname;
-};
-
-/*
- * Certificate Nickname entry:
- *
- * byte offset field
- * ----------- -----
- * 0 subjectname-len-msb
- * 1 subjectname-len-lsb
- * 2... subjectname
- *
- * The database key for this type of entry is a nickname string
- * The "subjectname" value is the DER encoded DN of the identity
- * that matches this nickname.
- */
-typedef struct {
- certDBEntryCommon common;
- char *nickname;
- SECItem subjectName;
-} certDBEntryNickname;
-
-#define DB_NICKNAME_ENTRY_HEADER_LEN 2
-
-/*
- * Certificate Subject entry:
- *
- * byte offset field
- * ----------- -----
- * 0 ncerts-msb
- * 1 ncerts-lsb
- * 2 nickname-msb
- * 3 nickname-lsb
- * 4 emailAddr-msb
- * 5 emailAddr-lsb
- * ... nickname
- * ... emailAddr
- * ...+2*i certkey-len-msb
- * ...+1+2*i certkey-len-lsb
- * ...+2*ncerts+2*i keyid-len-msb
- * ...+1+2*ncerts+2*i keyid-len-lsb
- * ... certkeys
- * ... keyids
- *
- * The database key for this type of entry is the DER encoded subject name
- * The "certkey" value is an array of certificate database lookup keys that
- * points to the database entries for the certificates that matche
- * this subject.
- *
- */
-typedef struct _certDBEntrySubject {
- certDBEntryCommon common;
- SECItem derSubject;
- unsigned int ncerts;
- char *nickname;
- char *emailAddr;
- SECItem *certKeys;
- SECItem *keyIDs;
-} certDBEntrySubject;
-
-#define DB_SUBJECT_ENTRY_HEADER_LEN 6
-
-/*
- * Certificate SMIME profile entry:
- *
- * byte offset field
- * ----------- -----
- * 0 subjectname-len-msb
- * 1 subjectname-len-lsb
- * 2 smimeoptions-len-msb
- * 3 smimeoptions-len-lsb
- * 4 options-date-len-msb
- * 5 options-date-len-lsb
- * 6... subjectname
- * ... smimeoptions
- * ... options-date
- *
- * The database key for this type of entry is the email address string
- * The "subjectname" value is the DER encoded DN of the identity
- * that matches this nickname.
- * The "smimeoptions" value is a string that represents the algorithm
- * capabilities on the remote user.
- * The "options-date" is the date that the smime options value was created.
- * This is generally the signing time of the signed message that contained
- * the options. It is a UTCTime value.
- */
-typedef struct {
- certDBEntryCommon common;
- char *emailAddr;
- SECItem subjectName;
- SECItem smimeOptions;
- SECItem optionsDate;
-} certDBEntrySMime;
-
-#define DB_SMIME_ENTRY_HEADER_LEN 6
-
-/*
- * Crl/krl entry:
- *
- * byte offset field
- * ----------- -----
- * 0 derCert-len-msb
- * 1 derCert-len-lsb
- * 2 url-len-msb
- * 3 url-len-lsb
- * ... derCert
- * ... url
- *
- * NOTE: the url string as stored in the database is null terminated,
- * in other words, the last byte of the db entry is always 0
- * if a nickname is present.
- * NOTE: if url is not present, then url-len-msb and
- * url-len-lsb will both be zero.
- */
-#define DB_CRL_ENTRY_HEADER_LEN 4
-struct _certDBEntryRevocation {
- certDBEntryCommon common;
- SECItem derCrl;
- char *url; /* where to load the crl from */
-};
-
-/*
- * Database Version Entry:
- *
- * byte offset field
- * ----------- -----
- * only the low level header...
- *
- * The database key for this type of entry is the string "Version"
- */
-typedef struct {
- certDBEntryCommon common;
-} certDBEntryVersion;
-
-#define SEC_DB_VERSION_KEY "Version"
-#define SEC_DB_VERSION_KEY_LEN sizeof(SEC_DB_VERSION_KEY)
-
-/*
- * Database Content Version Entry:
- *
- * byte offset field
- * ----------- -----
- * 0 contentVersion
- *
- * The database key for this type of entry is the string "ContentVersion"
- */
-typedef struct {
- certDBEntryCommon common;
- char contentVersion;
-} certDBEntryContentVersion;
-
-#define SEC_DB_CONTENT_VERSION_KEY "ContentVersion"
-#define SEC_DB_CONTENT_VERSION_KEY_LEN sizeof(SEC_DB_CONTENT_VERSION_KEY)
-
-typedef union {
- certDBEntryCommon common;
- certDBEntryVersion version;
- certDBEntryCert cert;
- certDBEntryNickname nickname;
- certDBEntrySubject subject;
- certDBEntryRevocation revocation;
-} certDBEntry;
-
-/* length of the fixed part of a database entry */
-#define DBCERT_V4_HEADER_LEN 7
-#define DB_CERT_V5_ENTRY_HEADER_LEN 7
-#define DB_CERT_V6_ENTRY_HEADER_LEN 7
-#define DB_CERT_ENTRY_HEADER_LEN 10
/* common flags for all types of certificates */
#define CERTDB_VALID_PEER (1<<0)
@@ -288,31 +47,58 @@ typedef union {
#define CERTDB_INVISIBLE_CA (1<<8) /* don't show in UI */
#define CERTDB_GOVT_APPROVED_CA (1<<9) /* can do strong crypto in export ver */
+
SEC_BEGIN_PROTOS
+CERTSignedCrl *
+SEC_FindCrlByKey(CERTCertDBHandle *handle, SECItem *crlKey, int type);
+
+CERTSignedCrl *
+SEC_FindCrlByName(CERTCertDBHandle *handle, SECItem *crlKey, int type);
+
+CERTSignedCrl *
+SEC_FindCrlByDERCert(CERTCertDBHandle *handle, SECItem *derCrl, int type);
+
+PRBool
+SEC_CertNicknameConflict(char *nickname, SECItem *derSubject,
+ CERTCertDBHandle *handle);
+CERTSignedCrl *
+SEC_NewCrl(CERTCertDBHandle *handle, char *url, SECItem *derCrl, int type);
+
+SECStatus
+SEC_DeletePermCRL(CERTSignedCrl *crl);
+
+
+SECStatus
+SEC_LookupCrls(CERTCertDBHandle *handle, CERTCrlHeadNode **nodes, int type);
+
+SECStatus
+SEC_DestroyCrl(CERTSignedCrl *crl);
+
+#ifdef notdef
/*
** Add a DER encoded certificate to the permanent database.
** "derCert" is the DER encoded certificate.
** "nickname" is the nickname to use for the cert
** "trust" is the trust parameters for the cert
*/
-SECStatus SEC_AddPermCertificate(CERTCertDBHandle *handle, SECItem *derCert,
- char *nickname, CERTCertTrust *trust);
+SECStatus SEC_AddPermCertificate(PCERTCertDBHandle *handle, SECItem *derCert,
+ char *nickname, PCERTCertTrust *trust);
certDBEntryCert *
-SEC_FindPermCertByKey(CERTCertDBHandle *handle, SECItem *certKey);
+SEC_FindPermCertByKey(PCERTCertDBHandle *handle, SECItem *certKey);
certDBEntryCert
-*SEC_FindPermCertByName(CERTCertDBHandle *handle, SECItem *name);
+*SEC_FindPermCertByName(PCERTCertDBHandle *handle, SECItem *name);
-SECStatus SEC_OpenPermCertDB(CERTCertDBHandle *handle,
+SECStatus SEC_OpenPermCertDB(PCERTCertDBHandle *handle,
PRBool readOnly,
- CERTDBNameFunc namecb,
+ PCERTDBNameFunc namecb,
void *cbarg);
-SECStatus SEC_DeletePermCertificate(CERTCertificate *cert);
+SECStatus SEC_DeletePermCertificate(PCERTCertificate *cert);
-typedef SECStatus (PR_CALLBACK * PermCertCallback)(CERTCertificate *cert,
+typedef SECStatus (PR_CALLBACK * PermCertCallback)(PCERTCertificate *cert,
SECItem *k, void *pdata);
/*
** Traverse the entire permanent database, and pass the certs off to a
@@ -321,75 +107,47 @@ typedef SECStatus (PR_CALLBACK * PermCertCallback)(CERTCertificate *cert,
** "udata" is the user's data, which is passed through to "certfunc"
*/
SECStatus
-SEC_TraversePermCerts(CERTCertDBHandle *handle,
+PCERT_TraversePermCerts(PCERTCertDBHandle *handle,
PermCertCallback certfunc,
void *udata );
SECStatus
-SEC_AddTempNickname(CERTCertDBHandle *handle, char *nickname, SECItem *certKey);
+SEC_AddTempNickname(PCERTCertDBHandle *handle, char *nickname, SECItem *certKey);
SECStatus
-SEC_DeleteTempNickname(CERTCertDBHandle *handle, char *nickname);
+SEC_DeleteTempNickname(PCERTCertDBHandle *handle, char *nickname);
-PRBool
-SEC_CertNicknameConflict(char *nickname, SECItem *derSubject,
- CERTCertDBHandle *handle);
PRBool
-SEC_CertDBKeyConflict(SECItem *derCert, CERTCertDBHandle *handle);
+SEC_CertDBKeyConflict(SECItem *derCert, PCERTCertDBHandle *handle);
SECStatus
-SEC_GetCrlTimes(CERTCrl *dates, PRTime *notBefore, PRTime *notAfter);
+SEC_GetCrlTimes(PCERTCrl *dates, PRTime *notBefore, PRTime *notAfter);
SECCertTimeValidity
-SEC_CheckCrlTimes(CERTCrl *crl, PRTime t);
+SEC_CheckCrlTimes(PCERTCrl *crl, PRTime t);
PRBool
-SEC_CrlIsNewer(CERTCrl *inNew, CERTCrl *old);
+SEC_CrlIsNewer(PCERTCrl *inNew, PCERTCrl *old);
-CERTSignedCrl *
-SEC_AddPermCrlToTemp(CERTCertDBHandle *handle, certDBEntryRevocation *entry);
+PCERTSignedCrl *
+SEC_AddPermCrlToTemp(PCERTCertDBHandle *handle, certDBEntryRevocation *entry);
SECStatus
-SEC_DeleteTempCrl(CERTSignedCrl *crl);
+SEC_DeleteTempCrl(PCERTSignedCrl *crl);
-CERTSignedCrl *
-SEC_FindCrlByKey(CERTCertDBHandle *handle, SECItem *crlKey, int type);
-
-CERTSignedCrl *
-SEC_FindCrlByName(CERTCertDBHandle *handle, SECItem *crlKey, int type);
-
-CERTSignedCrl *
-SEC_FindCrlByDERCert(CERTCertDBHandle *handle, SECItem *derCrl, int type);
-
-SECStatus
-SEC_DestroyCrl(CERTSignedCrl *crl);
-
-CERTSignedCrl *
-SEC_NewCrl(CERTCertDBHandle *handle, char *url, SECItem *derCrl, int type);
-
-CERTSignedCrl *
-cert_DBInsertCRL
- (CERTCertDBHandle *handle, char *url,
- CERTSignedCrl *newCrl, SECItem *derCrl, int type);
-
-SECStatus
-SEC_CheckKRL(CERTCertDBHandle *handle,SECKEYPublicKey *key,
- CERTCertificate *rootCert, int64 t, void *wincx);
-
-SECStatus
-SEC_CheckCRL(CERTCertDBHandle *handle,CERTCertificate *cert,
- CERTCertificate *caCert, int64 t, void *wincx);
SECStatus
-SEC_DeletePermCRL(CERTSignedCrl *crl);
-
+SEC_CheckKRL(PCERTCertDBHandle *handle,SECKEYLowPublicKey *key,
+ PCERTCertificate *rootCert, int64 t, void *wincx);
SECStatus
-SEC_LookupCrls(CERTCertDBHandle *handle, CERTCrlHeadNode **nodes, int type);
+SEC_CheckCRL(PCERTCertDBHandle *handle,PCERTCertificate *cert,
+ PCERTCertificate *caCert, int64 t, void *wincx);
SECStatus
-SEC_CrlReplaceUrl(CERTSignedCrl *crl,char *url);
+SEC_CrlReplaceUrl(PCERTSignedCrl *crl,char *url);
+#endif
SEC_END_PROTOS
diff --git a/security/nss/lib/certdb/certinit.c b/security/nss/lib/certdb/certinit.c
deleted file mode 100644
index d19b16cbf..000000000
--- a/security/nss/lib/certdb/certinit.c
+++ /dev/null
@@ -1,416 +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.
- */
-
-#include "cert.h"
-#include "base64.h"
-#include "mcom_db.h"
-#include "certdb.h"
-
-#ifdef STATIC_CERT_INIT
-static char example_com_server_ca[] =
-"MIICBTCCAW6gAwIBAgIBATANBgkqhkiG9w0BAQQFADA+MREwDwYICZIm9ZgeZAET"
-"A2NvbTEVMBMGCAmSJvWYHmQBEwdFeGFtcGxlMRIwEAYDVQQDEwlTZXJ2ZXIgQ0Ew"
-"HhcNMDAwMjAzMjIyMDA3WhcNMTAwNTAzMjIyMDA3WjA+MREwDwYICZIm9ZgeZAET"
-"A2NvbTEVMBMGCAmSJvWYHmQBEwdFeGFtcGxlMRIwEAYDVQQDEwlTZXJ2ZXIgQ0Ew"
-"gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALGiKEvTd2k4ZJbdAVWokfFlB6Hz"
-"WJXveXm8+IgmFlgtAnicZI11z5wAutFRvDpun7WmRLgHxvEhU3tLoiACGYdGJXPw"
-"+lI2pzHzFSd63B0qcA/NVAW3EOBJeaEFwy0jkUaCIki8qQV06g8RosNX/zv6a+OF"
-"d5NMpS0fecK4fEvdAgMBAAGjEzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN"
-"AQEEBQADgYEAi5rFiG6afWS1PHigssk2LwAJws5cszPbVIeIMHCBbtu259V7uWts"
-"gNxUPJRjeQBsK0ItAfinC0xxLeuMbRfIdZoRYv/OYDxCwGW7hUcNLi+fHlGnJNXH"
-"TWaCRdOwkljnws4v8ABas2DYA/k7xUFAygkIJd9NtE29ZrdrWpfSavI=";
-
-static char example_com_individual_ca[] =
-"MIICDTCCAXagAwIBAgIBAjANBgkqhkiG9w0BAQQFADBCMREwDwYICZIm9ZgeZAET"
-"A2NvbTEVMBMGCAmSJvWYHmQBEwdFeGFtcGxlMRYwFAYDVQQDEw1JbmRpdmlkdWFs"
-"IENBMB4XDTAwMDIwMzIyMjE1NFoXDTEwMDUwMzIyMjE1NFowQjERMA8GCAmSJvWY"
-"HmQBEwNjb20xFTATBggJkib1mB5kARMHRXhhbXBsZTEWMBQGA1UEAxMNSW5kaXZp"
-"ZHVhbCBDQTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAu5syfboe93MOkGec"
-"dOuJholyX42wcaH/RgnL3C/8NnZp9WWaTaguvn7KrbCj4TAMzu0pabUN8apB3J60"
-"9C/FlixjXF7r73OzbyTCM5ja6/bPfmHMPmDl9l/9tKqhh+loFvRizXDaWSFRViDS"
-"XvKNeQztwwAOpEAqnJwyTkn4FjECAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zAN"
-"BgkqhkiG9w0BAQQFAAOBgQB1XK+5pXdXYq3O3TC/ZY5LWlZ7zuoWUO75OpuMY7XF"
-"iW/jeXbVT5IYZXoRGXJFGGaDmnAuK1/m6FTDhjSTG0XUmd5tg4aFieI+LY4rkYEv"
-"mbJElxKabXl5hVD4mg2bwYlFY7XBmifTa1Ll3HDX3VZM0DC1bm4KCHBnY0qXjSYq"
-"PA==";
-
-static char example_com_objsign_ca[] =
-"MIICETCCAXqgAwIBAgIBAzANBgkqhkiG9w0BAQQFADBEMREwDwYICZIm9ZgeZAET"
-"A2NvbTEVMBMGCAmSJvWYHmQBEwdFeGFtcGxlMRgwFgYDVQQDEw9Db2RlIFNpZ25p"
-"bmcgQ0EwHhcNMDAwMjAzMjIyMzEzWhcNMTAwNTAzMjIyMzEzWjBEMREwDwYICZIm"
-"9ZgeZAETA2NvbTEVMBMGCAmSJvWYHmQBEwdFeGFtcGxlMRgwFgYDVQQDEw9Db2Rl"
-"IFNpZ25pbmcgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALcy76InmpM9"
-"S9K2MlNSjusx6nkYWWbx7eDRTV+xhRPeDxW4t8jtKPqDF5LTusyM9WCI/nneqsIP"
-"7iTSHpxlGx37J1VbqKX5fZsfJ3wKv6ZIylzeRuFY9MFypPA2UmVd1ACDOUB3YDvY"
-"mrCVkOPEhjnZKbq4FfCpf8KNL2A5EBcZAgMBAAGjEzARMA8GA1UdEwEB/wQFMAMB"
-"Af8wDQYJKoZIhvcNAQEEBQADgYEAI0IXzwgBRXvow3JQi8Y4YdG2wZc4BWRGW87x"
-"2zOD7GOA0CWN149vb6rEchECykDsJj9LoBl6o1aRxk9WkIFnXmMOJSuJA+ilCe//"
-"81a5OhKbe0p7ym6rh190BLwh2VePFeyabq6NipfZlN6qgWUzoepf+jVblufW/2EI"
-"fbMSylc=";
-#endif
-
-/* This is the cert->certKey (serial number and issuer name) of
- * the cert that we want to revoke.
- */
-static unsigned char revoked_system_principal_key[] = {
-0x40, 0x18, 0xf2, 0x35, 0x86, 0x06, 0x78, 0xce, 0x87, 0x89,
-0x0c, 0x5d, 0x68, 0x67, 0x33, 0x09, 0x30, 0x81, 0xc1, 0x31,
-0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x16,
-0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54,
-0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f,
-0x72, 0x6b, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04,
-0x0b, 0x13, 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
-0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x3a, 0x30,
-0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x56, 0x65,
-0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x4f, 0x62, 0x6a,
-0x65, 0x63, 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e,
-0x67, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x43, 0x6c, 0x61,
-0x73, 0x73, 0x20, 0x33, 0x20, 0x4f, 0x72, 0x67, 0x61, 0x6e,
-0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x49, 0x30,
-0x47, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x40, 0x77, 0x77,
-0x77, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e,
-0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x20, 0x49,
-0x6e, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x62, 0x79, 0x20, 0x52,
-0x65, 0x66, 0x2e, 0x20, 0x4c, 0x49, 0x41, 0x42, 0x49, 0x4c,
-0x49, 0x54, 0x59, 0x20, 0x4c, 0x54, 0x44, 0x2e, 0x28, 0x63,
-0x29, 0x39, 0x37, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69,
-0x67, 0x6e
-};
-
-SECStatus
-CERT_CheckForEvilCert(CERTCertificate *cert)
-{
- if ( cert->certKey.len == sizeof(revoked_system_principal_key) ) {
- if ( PORT_Memcmp(cert->certKey.data,
- revoked_system_principal_key,
- sizeof(revoked_system_principal_key)) == 0 ) {
- return(SECFailure);
- }
- }
-
- return(SECSuccess);
-}
-
-#ifdef STATIC_CERT_INIT
-
-#define DEFAULT_TRUST_FLAGS (CERTDB_VALID_CA | \
- CERTDB_TRUSTED_CA | \
- CERTDB_NS_TRUSTED_CA)
-
-typedef enum {
- certUpdateNone,
- certUpdateAdd,
- certUpdateDelete,
- certUpdateAddTrust,
- certUpdateRemoveTrust,
- certUpdateSetTrust
-} certUpdateOp;
-
-typedef struct {
- char *cert;
- char *nickname;
- CERTCertTrust trust;
- int updateVersion;
- certUpdateOp op;
- CERTCertTrust trustDelta;
-} certInitEntry;
-
-static certInitEntry initialcerts[] = {
- {
- example_com_server_ca,
- "Example.com Server CA",
- { DEFAULT_TRUST_FLAGS | CERTDB_GOVT_APPROVED_CA, 0, 0 },
- 1,
- certUpdateAdd,
- { 0, 0, 0 }
- },
- {
- example_com_server_ca,
- "Example.com Server CA",
- { DEFAULT_TRUST_FLAGS | CERTDB_GOVT_APPROVED_CA, 0, 0 },
- 2,
- certUpdateAddTrust,
- { CERTDB_GOVT_APPROVED_CA, 0, 0 }
- },
-
- {
- example_com_individual_ca,
- "Example.com Individual CA",
- { 0, DEFAULT_TRUST_FLAGS, 0 },
- 1,
- certUpdateAdd,
- { 0, 0, 0 }
- },
- {
- example_com_individual_ca,
- "Example.com Individual CA",
- { 0, DEFAULT_TRUST_FLAGS, 0 },
- 2,
- certUpdateRemoveTrust,
- { 0, 0, DEFAULT_TRUST_FLAGS }
- },
-
- {
- example_com_objsign_ca,
- "Example.com Code Signing CA",
- { 0, 0, DEFAULT_TRUST_FLAGS },
- 2,
- certUpdateAdd,
- { 0, 0, 0 }
- },
-
- {
- 0, 0
- }
-};
-
-
-static SECStatus
-ConvertAndCheckCertificate(CERTCertDBHandle *handle, char *asciicert,
- char *nickname, CERTCertTrust *trust)
-{
- SECItem sdder;
- SECStatus rv;
- CERTCertificate *cert;
- PRBool conflict;
- SECItem derSubject;
-
- /* First convert ascii to binary */
- rv = ATOB_ConvertAsciiToItem (&sdder, asciicert);
- if (rv != SECSuccess) {
- return(rv);
- }
-
- /*
- ** Inside the ascii is a Signed Certificate.
- */
-
- cert = NULL;
-
- /* make sure that no conflicts exist */
- conflict = SEC_CertDBKeyConflict(&sdder, handle);
- if ( conflict ) {
- goto done;
- }
-
- rv = CERT_NameFromDERCert(&sdder, &derSubject);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- conflict = SEC_CertNicknameConflict(nickname, &derSubject, handle);
- if ( conflict ) {
- goto done;
- }
-
- cert = CERT_NewTempCertificate(handle, &sdder, NULL, PR_FALSE, PR_TRUE);
- if ( cert == NULL ) {
- goto loser;
- }
-
- rv = CERT_AddTempCertToPerm(cert, nickname, trust);
-
- CERT_DestroyCertificate(cert);
-
- if (rv == SECSuccess) {
- /*
- ** XXX should verify signatures too, if we have the certificate for
- ** XXX its issuer...
- */
- }
-
-done:
- PORT_Free(sdder.data);
- return(rv);
-
-loser:
- return(SECFailure);
-}
-
-#endif
-
-extern void certdb_InitDBLock(void);
-
-SECStatus
-CERT_InitCertDB(CERTCertDBHandle *handle)
-{
-#ifdef STATIC_CERT_INIT
- SECStatus rv;
- certInitEntry *entry;
- certdb_InitDBLock();
-
- entry = initialcerts;
-
- while ( entry->cert != NULL) {
- if ( entry->op != certUpdateDelete ) {
- rv = ConvertAndCheckCertificate(handle, entry->cert,
- entry->nickname, &entry->trust);
- /* keep going */
- }
-
- entry++;
- }
-done:
- CERT_SetDBContentVersion(CERT_DB_CONTENT_VERSION, handle);
- return(rv);
-#else
-#ifdef DO_ANYTHING_HERE_FOR_3_4
- certdb_InitDBLock();
- CERT_SetDBContentVersion(0, handle);
-#endif
- return(SECSuccess);
-#endif
-}
-
-#ifdef STATIC_CERT_INIT
-static CERTCertificate *
-CertFromEntry(CERTCertDBHandle *handle, char *asciicert)
-{
- SECItem sdder;
- SECStatus rv;
- CERTCertificate *cert;
-
- /* First convert ascii to binary */
- rv = ATOB_ConvertAsciiToItem (&sdder, asciicert);
- if (rv != SECSuccess) {
- return(NULL);
- }
-
- /*
- ** Inside the ascii is a Signed Certificate.
- */
-
- cert = CERT_NewTempCertificate(handle, &sdder, NULL, PR_FALSE, PR_TRUE);
-
- return(cert);
-}
-#endif
-
-SECStatus
-CERT_AddNewCerts(CERTCertDBHandle *handle)
-{
-#ifdef STATIC_CERT_INIT
- int oldversion;
- int newversion;
- certInitEntry *entry;
- CERTCertTrust tmptrust;
- SECStatus rv;
- CERTCertificate *cert;
-
- newversion = CERT_DB_CONTENT_VERSION;
-
- oldversion = CERT_GetDBContentVersion(handle);
-
- if ( newversion > oldversion ) {
- entry = initialcerts;
-
- while ( entry->cert != NULL ) {
- if ( entry->updateVersion > oldversion ) {
- switch ( entry->op ) {
- default:
- break;
- case certUpdateAdd:
- rv = ConvertAndCheckCertificate(handle, entry->cert,
- entry->nickname,
- &entry->trust);
- break;
- case certUpdateDelete:
- cert = CertFromEntry(handle, entry->cert);
- if ( cert != NULL ) {
- if ( cert->isperm ) {
- rv = SEC_DeletePermCertificate(cert);
- }
- CERT_DestroyCertificate(cert);
- }
- break;
- case certUpdateAddTrust:
- cert = CertFromEntry(handle, entry->cert);
- if ( cert != NULL ) {
- if ( cert->isperm ) {
- tmptrust = *cert->trust;
- tmptrust.sslFlags |= entry->trustDelta.sslFlags;
- tmptrust.emailFlags |=
- entry->trustDelta.emailFlags;
- tmptrust.objectSigningFlags |=
- entry->trustDelta.objectSigningFlags;
- rv = CERT_ChangeCertTrust(handle, cert,
-&tmptrust);
- }
- CERT_DestroyCertificate(cert);
- }
- break;
- case certUpdateRemoveTrust:
- cert = CertFromEntry(handle, entry->cert);
- if ( cert != NULL ) {
- if ( cert->isperm ) {
- tmptrust = *cert->trust;
- tmptrust.sslFlags &=
- (~entry->trustDelta.sslFlags);
- tmptrust.emailFlags &=
- (~entry->trustDelta.emailFlags);
- tmptrust.objectSigningFlags &=
- (~entry->trustDelta.objectSigningFlags);
- rv = CERT_ChangeCertTrust(handle, cert,
-&tmptrust);
- }
- CERT_DestroyCertificate(cert);
- }
- break;
- case certUpdateSetTrust:
- cert = CertFromEntry(handle, entry->cert);
- if ( cert != NULL ) {
- if ( cert->isperm ) {
- tmptrust = *cert->trust;
- tmptrust.sslFlags = entry->trustDelta.sslFlags;
- tmptrust.emailFlags =
- entry->trustDelta.emailFlags;
- tmptrust.objectSigningFlags =
- entry->trustDelta.objectSigningFlags;
- rv = CERT_ChangeCertTrust(handle, cert,
-&tmptrust);
- }
- CERT_DestroyCertificate(cert);
- }
- break;
- }
- }
-
- entry++;
- }
-
- CERT_SetDBContentVersion(newversion, handle);
- }
-
-#endif
- return(SECSuccess);
-}
diff --git a/security/nss/lib/certdb/certt.h b/security/nss/lib/certdb/certt.h
index f186fd21f..5b208acd6 100644
--- a/security/nss/lib/certdb/certt.h
+++ b/security/nss/lib/certdb/certt.h
@@ -169,9 +169,6 @@ struct CERTPublicKeyAndChallengeStr {
SECItem challenge;
};
-typedef struct _certDBEntryCert certDBEntryCert;
-typedef struct _certDBEntryRevocation certDBEntryRevocation;
-
struct CERTCertTrustStr {
unsigned int sslFlags;
unsigned int emailFlags;
@@ -215,7 +212,7 @@ struct CERTSubjectListStr {
char *emailAddr;
CERTSubjectNode *head;
CERTSubjectNode *tail; /* do we need tail? */
- struct _certDBEntrySubject *entry;
+ void *entry;
};
/*
@@ -275,7 +272,7 @@ struct CERTCertificateStr {
PRBool istemp;
char *nickname;
char *dbnickname;
- certDBEntryCert *dbEntry; /* database entry struct */
+ void *dbEntry; /* database entry struct */
CERTCertTrust *trust;
/* the reference count is modified whenever someone looks up, dups
@@ -404,8 +401,10 @@ struct CERTCrlKeyStr {
struct CERTSignedCrlStr {
PRArenaPool *arena;
CERTCrl crl;
- certDBEntryRevocation *dbEntry; /* database entry struct */
- PRBool keep; /* keep this crl in the cache for the session*/
+ /*certDBEntryRevocation *dbEntry; database entry struct */
+ PK11SlotInfo *slot;
+ /* PRBool keep; keep this crl in the cache for the session*/
+ CK_OBJECT_HANDLE pkcs11ID;
PRBool isperm;
PRBool istemp;
int referenceCount;
diff --git a/security/nss/lib/certdb/crl.c b/security/nss/lib/certdb/crl.c
index 30a17a8fb..d6c232ec7 100644
--- a/security/nss/lib/certdb/crl.c
+++ b/security/nss/lib/certdb/crl.c
@@ -45,6 +45,7 @@
#include "certxutl.h"
#include "prtime.h"
#include "secerr.h"
+#include "pk11func.h"
const SEC_ASN1Template SEC_CERTExtensionTemplate[] = {
{ SEC_ASN1_SEQUENCE,
@@ -389,6 +390,223 @@ loser:
return(0);
}
+/*
+ * Lookup a CRL in the databases. We mirror the same fast caching data base
+ * caching stuff used by certificates....?
+ */
+CERTSignedCrl *
+SEC_FindCrlByKeyOnSlot(PK11SlotInfo *slot, SECItem *crlKey, int type)
+{
+ CERTSignedCrl *crl = NULL;
+ SECItem *derCrl;
+ CK_OBJECT_HANDLE crlHandle;
+
+ if (slot) {
+ PK11_ReferenceSlot(slot);
+ }
+
+ derCrl = PK11_FindCrlByName(&slot, &crlHandle, crlKey,type);
+ if (derCrl == NULL) {
+ goto loser;
+ }
+
+ crl = CERT_DecodeDERCrl(NULL, derCrl, type);
+ if (crl) {
+ crl->slot = slot;
+ slot = NULL; /* adopt it */
+ }
+
+loser:
+ if (slot) {
+ PK11_FreeSlot(slot);
+ }
+ return(crl);
+}
+
+SECStatus SEC_DestroyCrl(CERTSignedCrl *crl);
+
+CERTSignedCrl *
+crl_storeCRL (PK11SlotInfo *slot,char *url,
+ CERTSignedCrl *newCrl, SECItem *derCrl, int type)
+{
+ CERTSignedCrl *oldCrl = NULL, *crl = NULL;
+ CK_OBJECT_HANDLE crlHandle;
+
+ oldCrl = SEC_FindCrlByKeyOnSlot(slot, &newCrl->crl.derName, type);
+
+ /* if there is an old crl, make sure the one we are installing
+ * is newer. If not, exit out, otherwise delete the old crl.
+ */
+ if (oldCrl != NULL) {
+ if (!SEC_CrlIsNewer(&newCrl->crl,&oldCrl->crl)) {
+
+ if (type == SEC_CRL_TYPE) {
+ PORT_SetError(SEC_ERROR_OLD_CRL);
+ } else {
+ PORT_SetError(SEC_ERROR_OLD_KRL);
+ }
+
+ goto done;
+ }
+
+ if ((SECITEM_CompareItem(&newCrl->crl.derName,
+ &oldCrl->crl.derName) != SECEqual) &&
+ (type == SEC_KRL_TYPE) ) {
+
+ PORT_SetError(SEC_ERROR_CKL_CONFLICT);
+ goto done;
+ }
+
+ /* if we have a url in the database, use that one */
+ if (oldCrl->url) {
+ url = oldCrl->url;
+ }
+
+
+ /* really destroy this crl */
+ /* first drum it out of the permanment Data base */
+ SEC_DeletePermCRL(oldCrl);
+ }
+
+ /* Write the new entry into the data base */
+ crlHandle = PK11_PutCrl(slot, derCrl, &newCrl->crl.derName, url, type);
+ if (crlHandle != CK_INVALID_HANDLE) {
+ crl = newCrl;
+ crl->slot = PK11_ReferenceSlot(slot);
+ crl->pkcs11ID = crlHandle;
+ }
+
+done:
+ if (oldCrl) SEC_DestroyCrl(oldCrl);
+
+ return crl;
+}
+
+CERTSignedCrl *
+SEC_FindCrlByName(CERTCertDBHandle *handle, SECItem *crlKey, int type)
+{
+ return SEC_FindCrlByKeyOnSlot(NULL,crlKey,type);
+}
+
+/*
+ *
+ * create a new CRL from DER material.
+ *
+ * The signature on this CRL must be checked before you
+ * load it. ???
+ */
+CERTSignedCrl *
+SEC_NewCrl(CERTCertDBHandle *handle, char *url, SECItem *derCrl, int type)
+{
+ CERTSignedCrl *newCrl = NULL, *crl = NULL;
+ PK11SlotInfo *slot;
+
+ /* make this decode dates! */
+ newCrl = CERT_DecodeDERCrl(NULL, derCrl, type);
+ if (newCrl == NULL) {
+ if (type == SEC_CRL_TYPE) {
+ PORT_SetError(SEC_ERROR_CRL_INVALID);
+ } else {
+ PORT_SetError(SEC_ERROR_KRL_INVALID);
+ }
+ goto done;
+ }
+
+ slot = PK11_GetInternalKeySlot();
+ crl = crl_storeCRL(slot, url, newCrl, derCrl, type);
+ PK11_FreeSlot(slot);
+
+
+done:
+ if (crl == NULL) {
+ if (newCrl) {
+ PORT_FreeArena(newCrl->arena, PR_FALSE);
+ }
+ }
+
+ return crl;
+}
+
+
+CERTSignedCrl *
+SEC_FindCrlByDERCert(CERTCertDBHandle *handle, SECItem *derCrl, int type)
+{
+ PRArenaPool *arena;
+ SECItem crlKey;
+ SECStatus rv;
+ CERTSignedCrl *crl = NULL;
+
+ /* create a scratch arena */
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( arena == NULL ) {
+ return(NULL);
+ }
+
+ /* extract the database key from the cert */
+ rv = CERT_KeyFromDERCrl(arena, derCrl, &crlKey);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ /* find the crl */
+ crl = SEC_FindCrlByName(handle, &crlKey, type);
+
+loser:
+ PORT_FreeArena(arena, PR_FALSE);
+ return(crl);
+}
+
+
+SECStatus
+SEC_DestroyCrl(CERTSignedCrl *crl)
+{
+ if (crl) {
+ if (crl->referenceCount-- <= 1) {
+ if (crl->slot) {
+ PK11_FreeSlot(crl->slot);
+ }
+ PORT_FreeArena(crl->arena, PR_FALSE);
+ }
+ }
+ return SECSuccess;
+}
+
+SECStatus
+SEC_LookupCrls(CERTCertDBHandle *handle, CERTCrlHeadNode **nodes, int type)
+{
+ CERTCrlHeadNode *head;
+ PRArenaPool *arena = NULL;
+ SECStatus rv;
+
+ *nodes = NULL;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( arena == NULL ) {
+ return SECFailure;
+ }
+
+ /* build a head structure */
+ head = (CERTCrlHeadNode *)PORT_ArenaAlloc(arena, sizeof(CERTCrlHeadNode));
+ head->arena = arena;
+ head->first = NULL;
+ head->last = NULL;
+ head->dbhandle = handle;
+
+ /* Look up the proper crl types */
+ *nodes = head;
+
+ rv = PK11_LookupCrls(nodes, type, NULL);
+
+ if (rv != SECSuccess) {
+ if ( arena ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ *nodes = NULL;
+ }
+ }
+
+ return rv;
+}
+
/* These functions simply return the address of the above-declared templates.
** This is necessary for Windows DLLs. Sigh.
*/
diff --git a/security/nss/lib/certdb/manifest.mn b/security/nss/lib/certdb/manifest.mn
index 37b08b85a..a9b5f3d8c 100644
--- a/security/nss/lib/certdb/manifest.mn
+++ b/security/nss/lib/certdb/manifest.mn
@@ -42,28 +42,20 @@ PRIVATE_EXPORTS = \
genname.h \
xconst.h \
certxutl.h \
- cdbhdl.h \
$(NULL)
MODULE = security
-CERTINIT=certinit.c
-ifdef NSS_STAN_MODULE
-PCERTDB=stanpcertdb.c
DEFINES=-DSTAN_CERT_DB
-else
-PCERTDB=pcertdb.c
-endif
CSRCS = \
alg1485.c \
certdb.c \
certv3.c \
- $(CERTINIT) \
certxutl.c \
crl.c \
genname.c \
- $(PCERTDB) \
+ stanpcertdb.c \
polcyxtn.c \
secname.c \
xauthkid.c \
diff --git a/security/nss/lib/certdb/pcertdb.c b/security/nss/lib/certdb/pcertdb.c
deleted file mode 100644
index 48ea44c5a..000000000
--- a/security/nss/lib/certdb/pcertdb.c
+++ /dev/null
@@ -1,7490 +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.
- */
-
-/*
- * Permanent Certificate database handling code
- *
- * $Id$
- */
-#include "prtime.h"
-
-#include "cert.h"
-#include "mcom_db.h"
-#include "certdb.h"
-#include "secitem.h"
-#include "secder.h"
-
-/* Call to PK11_FreeSlot below */
-
-#include "secasn1.h"
-#include "secerr.h"
-#include "nssilock.h"
-#include "prmon.h"
-#include "nsslocks.h"
-#include "base64.h"
-#include "sechash.h"
-#include "plhash.h"
-#include "pk11func.h" /* sigh */
-
-#include "cdbhdl.h"
-
-/* forward declaration */
-CERTCertificate *
-CERT_FindCertByDERCertNoLocking(CERTCertDBHandle *handle, SECItem *derCert);
-
-/*
- * the following functions are wrappers for the db library that implement
- * a global lock to make the database thread safe.
- */
-static PZLock *dbLock = NULL;
-
-void
-certdb_InitDBLock(void)
-{
- if (dbLock == NULL) {
- nss_InitLock(&dbLock, nssILockCertDB);
- PORT_Assert(dbLock != NULL);
- }
-
- return;
-}
-
-static int
-certdb_Get(DB *db, DBT *key, DBT *data, unsigned int flags)
-{
- PRStatus prstat;
- int ret;
-
- PORT_Assert(dbLock != NULL);
- PZ_Lock(dbLock);
-
- ret = (* db->get)(db, key, data, flags);
-
- prstat = PZ_Unlock(dbLock);
-
- return(ret);
-}
-
-static int
-certdb_Put(DB *db, DBT *key, DBT *data, unsigned int flags)
-{
- PRStatus prstat;
- int ret;
-
- PORT_Assert(dbLock != NULL);
- PZ_Lock(dbLock);
-
- ret = (* db->put)(db, key, data, flags);
-
- prstat = PZ_Unlock(dbLock);
-
- return(ret);
-}
-
-static int
-certdb_Sync(DB *db, unsigned int flags)
-{
- PRStatus prstat;
- int ret;
-
- PORT_Assert(dbLock != NULL);
- PZ_Lock(dbLock);
-
- ret = (* db->sync)(db, flags);
-
- prstat = PZ_Unlock(dbLock);
-
- return(ret);
-}
-
-static int
-certdb_Del(DB *db, DBT *key, unsigned int flags)
-{
- PRStatus prstat;
- int ret;
-
- PORT_Assert(dbLock != NULL);
- PZ_Lock(dbLock);
-
- ret = (* db->del)(db, key, flags);
-
- prstat = PZ_Unlock(dbLock);
-
- return(ret);
-}
-
-static int
-certdb_Seq(DB *db, DBT *key, DBT *data, unsigned int flags)
-{
- PRStatus prstat;
- int ret;
-
- PORT_Assert(dbLock != NULL);
- PZ_Lock(dbLock);
-
- ret = (* db->seq)(db, key, data, flags);
-
- prstat = PZ_Unlock(dbLock);
-
- return(ret);
-}
-
-static void
-certdb_Close(DB *db)
-{
- PRStatus prstat;
-
- PORT_Assert(dbLock != NULL);
- PZ_Lock(dbLock);
-
- (* db->close)(db);
-
- prstat = PZ_Unlock(dbLock);
-
- return;
-}
-
-/* forward references */
-static void CERT_DestroyCertificateNoLocking(CERTCertificate *cert);
-static SECStatus AddCertToSPKDigestTable(CERTCertDBHandle *handle,
- CERTCertificate *cert);
-static SECStatus RemoveCertFromSPKDigestTable(CERTCertDBHandle *handle,
- CERTCertificate *cert);
-
-static SECStatus
-DeleteDBEntry(CERTCertDBHandle *handle, certDBEntryType type, SECItem *dbkey)
-{
- DBT key;
- int ret;
-
- /* init the database key */
- key.data = dbkey->data;
- key.size = dbkey->len;
-
- dbkey->data[0] = (unsigned char)type;
-
- /* delete entry from database */
- ret = certdb_Del(handle->permCertDB, &key, 0 );
- if ( ret != 0 ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- ret = certdb_Sync(handle->permCertDB, 0);
- if ( ret ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-static SECStatus
-ReadDBEntry(CERTCertDBHandle *handle, certDBEntryCommon *entry,
- SECItem *dbkey, SECItem *dbentry, PRArenaPool *arena)
-{
- DBT data, key;
- int ret;
- unsigned char *buf;
-
- /* init the database key */
- key.data = dbkey->data;
- key.size = dbkey->len;
-
- dbkey->data[0] = (unsigned char)entry->type;
-
- /* read entry from database */
- ret = certdb_Get(handle->permCertDB, &key, &data, 0 );
- if ( ret != 0 ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- /* validate the entry */
- if ( data.size < SEC_DB_ENTRY_HEADER_LEN ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
- buf = (unsigned char *)data.data;
- if ( buf[0] != (unsigned char)CERT_DB_FILE_VERSION ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
- if ( buf[1] != (unsigned char)entry->type ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- /* copy out header information */
- entry->version = (unsigned int)buf[0];
- entry->type = (certDBEntryType)buf[1];
- entry->flags = (unsigned int)buf[2];
-
- /* format body of entry for return to caller */
- dbentry->len = data.size - SEC_DB_ENTRY_HEADER_LEN;
- if ( dbentry->len ) {
- dbentry->data = (unsigned char *)PORT_ArenaAlloc(arena, dbentry->len);
- if ( dbentry->data == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- PORT_Memcpy(dbentry->data, &buf[SEC_DB_ENTRY_HEADER_LEN],
- dbentry->len);
- } else {
- dbentry->data = NULL;
- }
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/**
- ** Implement low level database access
- **/
-static SECStatus
-WriteDBEntry(CERTCertDBHandle *handle, certDBEntryCommon *entry,
- SECItem *dbkey, SECItem *dbentry)
-{
- int ret;
- DBT data, key;
- unsigned char *buf;
-
- data.data = dbentry->data;
- data.size = dbentry->len;
-
- buf = (unsigned char*)data.data;
-
- buf[0] = (unsigned char)entry->version;
- buf[1] = (unsigned char)entry->type;
- buf[2] = (unsigned char)entry->flags;
-
- key.data = dbkey->data;
- key.size = dbkey->len;
-
- dbkey->data[0] = (unsigned char)entry->type;
-
- /* put the record into the database now */
- ret = certdb_Put(handle->permCertDB, &key, &data, 0);
-
- if ( ret != 0 ) {
- goto loser;
- }
-
- ret = certdb_Sync( handle->permCertDB, 0 );
-
- if ( ret ) {
- goto loser;
- }
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/*
- * encode a database cert record
- */
-static SECStatus
-EncodeDBCertEntry(certDBEntryCert *entry, PRArenaPool *arena, SECItem *dbitem)
-{
- unsigned int nnlen;
- unsigned char *buf;
- char *nn;
- char zbuf = 0;
-
- if ( entry->nickname ) {
- nn = entry->nickname;
- } else {
- nn = &zbuf;
- }
- nnlen = PORT_Strlen(nn) + 1;
-
- /* allocate space for encoded database record, including space
- * for low level header
- */
- dbitem->len = entry->derCert.len + nnlen + DB_CERT_ENTRY_HEADER_LEN +
- SEC_DB_ENTRY_HEADER_LEN;
-
- dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len);
- if ( dbitem->data == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* fill in database record */
- buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN];
-
- buf[0] = ( entry->trust.sslFlags >> 8 ) & 0xff;
- buf[1] = entry->trust.sslFlags & 0xff;
- buf[2] = ( entry->trust.emailFlags >> 8 ) & 0xff;
- buf[3] = entry->trust.emailFlags & 0xff;
- buf[4] = ( entry->trust.objectSigningFlags >> 8 ) & 0xff;
- buf[5] = entry->trust.objectSigningFlags & 0xff;
- buf[6] = ( entry->derCert.len >> 8 ) & 0xff;
- buf[7] = entry->derCert.len & 0xff;
- buf[8] = ( nnlen >> 8 ) & 0xff;
- buf[9] = nnlen & 0xff;
-
- PORT_Memcpy(&buf[DB_CERT_ENTRY_HEADER_LEN], entry->derCert.data,
- entry->derCert.len);
-
- PORT_Memcpy(&buf[DB_CERT_ENTRY_HEADER_LEN + entry->derCert.len],
- nn, nnlen);
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/*
- * encode a database key for a cert record
- */
-static SECStatus
-EncodeDBCertKey(SECItem *certKey, PRArenaPool *arena, SECItem *dbkey)
-{
- dbkey->len = certKey->len + SEC_DB_KEY_HEADER_LEN;
- dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
- if ( dbkey->data == NULL ) {
- goto loser;
- }
- PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN],
- certKey->data, certKey->len);
- dbkey->data[0] = certDBEntryTypeCert;
-
- return(SECSuccess);
-loser:
- return(SECFailure);
-}
-
-static SECStatus
-EncodeDBGenericKey(SECItem *certKey, PRArenaPool *arena, SECItem *dbkey,
- certDBEntryType entryType)
-{
- /*
- * we only allow _one_ KRL key!
- */
- if (entryType == certDBEntryTypeKeyRevocation) {
- dbkey->len = SEC_DB_KEY_HEADER_LEN;
- dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
- if ( dbkey->data == NULL ) {
- goto loser;
- }
- dbkey->data[0] = (unsigned char) entryType;
- return(SECSuccess);
- }
-
-
- dbkey->len = certKey->len + SEC_DB_KEY_HEADER_LEN;
- dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
- if ( dbkey->data == NULL ) {
- goto loser;
- }
- PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN],
- certKey->data, certKey->len);
- dbkey->data[0] = (unsigned char) entryType;
-
- return(SECSuccess);
-loser:
- return(SECFailure);
-}
-
-static SECStatus
-DecodeDBCertEntry(certDBEntryCert *entry, SECItem *dbentry)
-{
- unsigned int nnlen;
- int headerlen;
- int lenoff;
-
- /* allow updates of old versions of the database */
- switch ( entry->common.version ) {
- case 5:
- headerlen = DB_CERT_V5_ENTRY_HEADER_LEN;
- lenoff = 3;
- break;
- case 6:
- /* should not get here */
- PORT_Assert(0);
- headerlen = DB_CERT_V6_ENTRY_HEADER_LEN;
- lenoff = 3;
- break;
- case 7:
- headerlen = DB_CERT_ENTRY_HEADER_LEN;
- lenoff = 6;
- break;
- default:
- /* better not get here */
- PORT_Assert(0);
- headerlen = DB_CERT_V5_ENTRY_HEADER_LEN;
- lenoff = 3;
- break;
- }
-
- /* is record long enough for header? */
- if ( dbentry->len < headerlen ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- /* is database entry correct length? */
- entry->derCert.len = ( ( dbentry->data[lenoff] << 8 ) |
- dbentry->data[lenoff+1] );
- nnlen = ( ( dbentry->data[lenoff+2] << 8 ) | dbentry->data[lenoff+3] );
- if ( ( entry->derCert.len + nnlen + headerlen )
- != dbentry->len) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- /* copy the dercert */
- entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(entry->common.arena,
- entry->derCert.len);
- if ( entry->derCert.data == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- PORT_Memcpy(entry->derCert.data, &dbentry->data[headerlen],
- entry->derCert.len);
-
- /* copy the nickname */
- if ( nnlen > 1 ) {
- entry->nickname = (char *)PORT_ArenaAlloc(entry->common.arena, nnlen);
- if ( entry->nickname == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- PORT_Memcpy(entry->nickname,
- &dbentry->data[headerlen +
- entry->derCert.len],
- nnlen);
- } else {
- entry->nickname = NULL;
- }
-
- if ( entry->common.version < 7 ) {
- /* allow updates of v5 db */
- entry->trust.sslFlags = dbentry->data[0];
- entry->trust.emailFlags = dbentry->data[1];
- entry->trust.objectSigningFlags = dbentry->data[2];
- } else {
- entry->trust.sslFlags = ( dbentry->data[0] << 8 ) | dbentry->data[1];
- entry->trust.emailFlags = ( dbentry->data[2] << 8 ) | dbentry->data[3];
- entry->trust.objectSigningFlags =
- ( dbentry->data[4] << 8 ) | dbentry->data[5];
- }
-
- return(SECSuccess);
-loser:
- return(SECFailure);
-}
-
-
-/*
- * Create a new certDBEntryCert from existing data
- */
-static certDBEntryCert *
-NewDBCertEntry(SECItem *derCert, char *nickname,
- CERTCertTrust *trust, int flags)
-{
- certDBEntryCert *entry;
- PRArenaPool *arena = NULL;
- int nnlen;
-
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE );
-
- if ( !arena ) {
- goto loser;
- }
-
- entry = (certDBEntryCert *)PORT_ArenaZAlloc(arena, sizeof(certDBEntryCert));
-
- if ( entry == NULL ) {
- goto loser;
- }
-
- /* fill in the dbCert */
- entry->common.arena = arena;
- entry->common.type = certDBEntryTypeCert;
- entry->common.version = CERT_DB_FILE_VERSION;
- entry->common.flags = flags;
-
- if ( trust ) {
- entry->trust = *trust;
- }
-
- entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(arena, derCert->len);
- if ( !entry->derCert.data ) {
- goto loser;
- }
- entry->derCert.len = derCert->len;
- PORT_Memcpy(entry->derCert.data, derCert->data, derCert->len);
-
- nnlen = ( nickname ? strlen(nickname) + 1 : 0 );
-
- if ( nnlen ) {
- entry->nickname = (char *)PORT_ArenaAlloc(arena, nnlen);
- if ( !entry->nickname ) {
- goto loser;
- }
- PORT_Memcpy(entry->nickname, nickname, nnlen);
-
- } else {
- entry->nickname = 0;
- }
-
- return(entry);
-
-loser:
-
- /* allocation error, free arena and return */
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return(0);
-}
-
-/*
- * Decode a version 4 DBCert from the byte stream database format
- * and construct a current database entry struct
- */
-static certDBEntryCert *
-DecodeV4DBCertEntry(unsigned char *buf, int len)
-{
- certDBEntryCert *entry;
- int certlen;
- int nnlen;
- PRArenaPool *arena;
-
- /* make sure length is at least long enough for the header */
- if ( len < DBCERT_V4_HEADER_LEN ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return(0);
- }
-
- /* get other lengths */
- certlen = buf[3] << 8 | buf[4];
- nnlen = buf[5] << 8 | buf[6];
-
- /* make sure DB entry is the right size */
- if ( ( certlen + nnlen + DBCERT_V4_HEADER_LEN ) != len ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return(0);
- }
-
- /* allocate arena */
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE );
-
- if ( !arena ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return(0);
- }
-
- /* allocate structure and members */
- entry = (certDBEntryCert *) PORT_ArenaAlloc(arena, sizeof(certDBEntryCert));
-
- if ( !entry ) {
- goto loser;
- }
-
- entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(arena, certlen);
- if ( !entry->derCert.data ) {
- goto loser;
- }
- entry->derCert.len = certlen;
-
- if ( nnlen ) {
- entry->nickname = (char *) PORT_ArenaAlloc(arena, nnlen);
- if ( !entry->nickname ) {
- goto loser;
- }
- } else {
- entry->nickname = 0;
- }
-
- entry->common.arena = arena;
- entry->common.version = CERT_DB_FILE_VERSION;
- entry->common.type = certDBEntryTypeCert;
- entry->common.flags = 0;
- entry->trust.sslFlags = buf[0];
- entry->trust.emailFlags = buf[1];
- entry->trust.objectSigningFlags = buf[2];
-
- PORT_Memcpy(entry->derCert.data, &buf[DBCERT_V4_HEADER_LEN], certlen);
- PORT_Memcpy(entry->nickname, &buf[DBCERT_V4_HEADER_LEN + certlen], nnlen);
-
- if (PORT_Strcmp(entry->nickname,"Server-Cert") == 0) {
- entry->trust.sslFlags |= CERTDB_USER;
- }
-
- return(entry);
-
-loser:
- PORT_FreeArena(arena, PR_FALSE);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return(0);
-}
-
-/*
- * Encode a Certificate database entry into byte stream suitable for
- * the database
- */
-static SECStatus
-WriteDBCertEntry(CERTCertDBHandle *handle, certDBEntryCert *entry)
-{
- SECItem dbitem, dbkey;
- PRArenaPool *tmparena = NULL;
- SECItem tmpitem;
- SECStatus rv;
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- goto loser;
- }
-
- rv = EncodeDBCertEntry(entry, tmparena, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* get the database key and format it */
- rv = CERT_KeyFromDERCert(tmparena, &entry->derCert, &tmpitem);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- rv = EncodeDBCertKey(&tmpitem, tmparena, &dbkey);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- /* now write it to the database */
- rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- return(SECFailure);
-}
-
-
-/*
- * delete a certificate entry
- */
-static SECStatus
-DeleteDBCertEntry(CERTCertDBHandle *handle, SECItem *certKey)
-{
- SECItem dbkey;
- PRArenaPool *arena = NULL;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- rv = EncodeDBCertKey(certKey, arena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = DeleteDBEntry(handle, certDBEntryTypeCert, &dbkey);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- PORT_FreeArena(arena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(SECFailure);
-}
-
-/*
- * Read a certificate entry
- */
-static certDBEntryCert *
-ReadDBCertEntry(CERTCertDBHandle *handle, SECItem *certKey)
-{
- PRArenaPool *arena = NULL;
- PRArenaPool *tmparena = NULL;
- certDBEntryCert *entry;
- SECItem dbkey;
- SECItem dbentry;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- entry = (certDBEntryCert *)PORT_ArenaAlloc(arena, sizeof(certDBEntryCert));
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- entry->common.arena = arena;
- entry->common.type = certDBEntryTypeCert;
-
- rv = EncodeDBCertKey(certKey, tmparena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- rv = DecodeDBCertEntry(entry, &dbentry);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(entry);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-/*
- * encode a database cert record
- */
-static SECStatus
-EncodeDBCrlEntry(certDBEntryRevocation *entry, PRArenaPool *arena, SECItem *dbitem)
-{
- unsigned int nnlen = 0;
- unsigned char *buf;
-
- if (entry->url) {
- nnlen = PORT_Strlen(entry->url) + 1;
- }
-
- /* allocate space for encoded database record, including space
- * for low level header
- */
- dbitem->len = entry->derCrl.len + nnlen
- + SEC_DB_ENTRY_HEADER_LEN + DB_CRL_ENTRY_HEADER_LEN;
-
- dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len);
- if ( dbitem->data == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* fill in database record */
- buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN];
-
- buf[0] = ( entry->derCrl.len >> 8 ) & 0xff;
- buf[1] = entry->derCrl.len & 0xff;
- buf[2] = ( nnlen >> 8 ) & 0xff;
- buf[3] = nnlen & 0xff;
-
- PORT_Memcpy(&buf[DB_CRL_ENTRY_HEADER_LEN], entry->derCrl.data,
- entry->derCrl.len);
-
- if (nnlen != 0) {
- PORT_Memcpy(&buf[DB_CRL_ENTRY_HEADER_LEN + entry->derCrl.len],
- entry->url, nnlen);
- }
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-static SECStatus
-DecodeDBCrlEntry(certDBEntryRevocation *entry, SECItem *dbentry)
-{
- unsigned int nnlen;
-
- /* is record long enough for header? */
- if ( dbentry->len < DB_CRL_ENTRY_HEADER_LEN ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- /* is database entry correct length? */
- entry->derCrl.len = ( ( dbentry->data[0] << 8 ) | dbentry->data[1] );
- nnlen = ( ( dbentry->data[2] << 8 ) | dbentry->data[3] );
- if ( ( entry->derCrl.len + nnlen + DB_CRL_ENTRY_HEADER_LEN )
- != dbentry->len) {
- /* CRL entry is greater than 64 K. Hack to make this continue to work */
- if (dbentry->len >= (0xffff - DB_CRL_ENTRY_HEADER_LEN) - nnlen) {
- entry->derCrl.len =
- (dbentry->len - DB_CRL_ENTRY_HEADER_LEN) - nnlen;
- } else {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
- }
-
- /* copy the dercert */
- entry->derCrl.data = (unsigned char *)PORT_ArenaAlloc(entry->common.arena,
- entry->derCrl.len);
- if ( entry->derCrl.data == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- PORT_Memcpy(entry->derCrl.data, &dbentry->data[DB_CRL_ENTRY_HEADER_LEN],
- entry->derCrl.len);
-
- /* copy the url */
- entry->url = NULL;
- if (nnlen != 0) {
- entry->url = (char *)PORT_ArenaAlloc(entry->common.arena, nnlen);
- if ( entry->url == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- PORT_Memcpy(entry->url,
- &dbentry->data[DB_CRL_ENTRY_HEADER_LEN + entry->derCrl.len],
- nnlen);
- }
-
- return(SECSuccess);
-loser:
- return(SECFailure);
-}
-
-/*
- * Create a new certDBEntryRevocation from existing data
- */
-static certDBEntryRevocation *
-NewDBCrlEntry(SECItem *derCrl, char * url, certDBEntryType crlType, int flags)
-{
- certDBEntryRevocation *entry;
- PRArenaPool *arena = NULL;
- int nnlen;
-
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE );
-
- if ( !arena ) {
- goto loser;
- }
-
- entry = (certDBEntryRevocation*)
- PORT_ArenaZAlloc(arena, sizeof(certDBEntryRevocation));
-
- if ( entry == NULL ) {
- goto loser;
- }
-
- /* fill in the dbRevolcation */
- entry->common.arena = arena;
- entry->common.type = crlType;
- entry->common.version = CERT_DB_FILE_VERSION;
- entry->common.flags = flags;
-
-
- entry->derCrl.data = (unsigned char *)PORT_ArenaAlloc(arena, derCrl->len);
- if ( !entry->derCrl.data ) {
- goto loser;
- }
-
- if (url) {
- nnlen = PORT_Strlen(url) + 1;
- entry->url = (char *)PORT_ArenaAlloc(arena, nnlen);
- if ( !entry->url ) {
- goto loser;
- }
- PORT_Memcpy(entry->url, url, nnlen);
- } else {
- entry->url = NULL;
- }
-
-
- entry->derCrl.len = derCrl->len;
- PORT_Memcpy(entry->derCrl.data, derCrl->data, derCrl->len);
-
- return(entry);
-
-loser:
-
- /* allocation error, free arena and return */
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return(0);
-}
-
-
-static SECStatus
-WriteDBCrlEntry(CERTCertDBHandle *handle, certDBEntryRevocation *entry )
-{
- SECItem dbkey;
- PRArenaPool *tmparena = NULL;
- SECItem tmpitem,encodedEntry;
- SECStatus rv;
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- goto loser;
- }
-
- /* get the database key and format it */
- rv = CERT_KeyFromDERCrl(tmparena, &entry->derCrl, &tmpitem);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- rv = EncodeDBCrlEntry(entry, tmparena, &encodedEntry);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- rv = EncodeDBGenericKey(&tmpitem, tmparena, &dbkey, entry->common.type);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- /* now write it to the database */
- rv = WriteDBEntry(handle, &entry->common, &dbkey, &encodedEntry);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- return(SECFailure);
-}
-/*
- * delete a crl entry
- */
-static SECStatus
-DeleteDBCrlEntry(CERTCertDBHandle *handle, SECItem *crlKey,
- certDBEntryType crlType)
-{
- SECItem dbkey;
- PRArenaPool *arena = NULL;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- rv = EncodeDBGenericKey(crlKey, arena, &dbkey, crlType);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = DeleteDBEntry(handle, crlType, &dbkey);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- PORT_FreeArena(arena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(SECFailure);
-}
-
-/*
- * Read a certificate entry
- */
-static certDBEntryRevocation *
-ReadDBCrlEntry(CERTCertDBHandle *handle, SECItem *certKey,
- certDBEntryType crlType)
-{
- PRArenaPool *arena = NULL;
- PRArenaPool *tmparena = NULL;
- certDBEntryRevocation *entry;
- SECItem dbkey;
- SECItem dbentry;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- entry = (certDBEntryRevocation *)
- PORT_ArenaAlloc(arena, sizeof(certDBEntryRevocation));
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- entry->common.arena = arena;
- entry->common.type = crlType;
-
- rv = EncodeDBGenericKey(certKey, tmparena, &dbkey, crlType);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- rv = DecodeDBCrlEntry(entry, &dbentry);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(entry);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-/*
- * destroy a database entry
- */
-static void
-DestroyDBEntry(certDBEntry *entry)
-{
- PRArenaPool *arena = entry->common.arena;
-
- /* Zero out the entry struct, so that any further attempts to use it
- * will cause an exception (e.g. null pointer reference). */
- PORT_Memset(&entry->common, 0, sizeof entry->common);
- PORT_FreeArena(arena, PR_FALSE);
-
- return;
-}
-
-/*
- * Encode a database nickname record
- */
-static SECStatus
-EncodeDBNicknameEntry(certDBEntryNickname *entry, PRArenaPool *arena,
- SECItem *dbitem)
-{
- unsigned char *buf;
-
- /* allocate space for encoded database record, including space
- * for low level header
- */
- dbitem->len = entry->subjectName.len + DB_NICKNAME_ENTRY_HEADER_LEN +
- SEC_DB_ENTRY_HEADER_LEN;
-
- dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len);
- if ( dbitem->data == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* fill in database record */
- buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN];
-
- buf[0] = ( entry->subjectName.len >> 8 ) & 0xff;
- buf[1] = entry->subjectName.len & 0xff;
-
- PORT_Memcpy(&buf[DB_NICKNAME_ENTRY_HEADER_LEN], entry->subjectName.data,
- entry->subjectName.len);
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/*
- * Encode a database key for a nickname record
- */
-static SECStatus
-EncodeDBNicknameKey(char *nickname, PRArenaPool *arena,
- SECItem *dbkey)
-{
- unsigned int nnlen;
-
- nnlen = PORT_Strlen(nickname) + 1; /* includes null */
-
- /* now get the database key and format it */
- dbkey->len = nnlen + SEC_DB_KEY_HEADER_LEN;
- dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
- if ( dbkey->data == NULL ) {
- goto loser;
- }
- PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], nickname, nnlen);
- dbkey->data[0] = certDBEntryTypeNickname;
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-static SECStatus
-DecodeDBNicknameEntry(certDBEntryNickname *entry, SECItem *dbentry,
- char *nickname)
-{
- /* is record long enough for header? */
- if ( dbentry->len < DB_NICKNAME_ENTRY_HEADER_LEN ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- /* is database entry correct length? */
- entry->subjectName.len = ( ( dbentry->data[0] << 8 ) | dbentry->data[1] );
- if (( entry->subjectName.len + DB_NICKNAME_ENTRY_HEADER_LEN ) !=
- dbentry->len ){
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- /* copy the certkey */
- entry->subjectName.data =
- (unsigned char *)PORT_ArenaAlloc(entry->common.arena,
- entry->subjectName.len);
- if ( entry->subjectName.data == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- PORT_Memcpy(entry->subjectName.data,
- &dbentry->data[DB_NICKNAME_ENTRY_HEADER_LEN],
- entry->subjectName.len);
-
- entry->nickname = (char *)PORT_ArenaAlloc(entry->common.arena,
- PORT_Strlen(nickname)+1);
- if ( entry->nickname ) {
- PORT_Strcpy(entry->nickname, nickname);
- }
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/*
- * create a new nickname entry
- */
-static certDBEntryNickname *
-NewDBNicknameEntry(char *nickname, SECItem *subjectName, unsigned int flags)
-{
- PRArenaPool *arena = NULL;
- certDBEntryNickname *entry;
- int nnlen;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- entry = (certDBEntryNickname *)PORT_ArenaAlloc(arena,
- sizeof(certDBEntryNickname));
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* init common fields */
- entry->common.arena = arena;
- entry->common.type = certDBEntryTypeNickname;
- entry->common.version = CERT_DB_FILE_VERSION;
- entry->common.flags = flags;
-
- /* copy the nickname */
- nnlen = PORT_Strlen(nickname) + 1;
-
- entry->nickname = (char*)PORT_ArenaAlloc(arena, nnlen);
- if ( entry->nickname == NULL ) {
- goto loser;
- }
-
- PORT_Memcpy(entry->nickname, nickname, nnlen);
-
- rv = SECITEM_CopyItem(arena, &entry->subjectName, subjectName);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- return(entry);
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-/*
- * delete a nickname entry
- */
-static SECStatus
-DeleteDBNicknameEntry(CERTCertDBHandle *handle, char *nickname)
-{
- PRArenaPool *arena = NULL;
- SECStatus rv;
- SECItem dbkey;
-
- if ( nickname == NULL ) {
- return(SECSuccess);
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- rv = EncodeDBNicknameKey(nickname, arena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = DeleteDBEntry(handle, certDBEntryTypeNickname, &dbkey);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- PORT_FreeArena(arena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(SECFailure);
-}
-
-/*
- * Read a nickname entry
- */
-static certDBEntryNickname *
-ReadDBNicknameEntry(CERTCertDBHandle *handle, char *nickname)
-{
- PRArenaPool *arena = NULL;
- PRArenaPool *tmparena = NULL;
- certDBEntryNickname *entry;
- SECItem dbkey;
- SECItem dbentry;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- entry = (certDBEntryNickname *)PORT_ArenaAlloc(arena,
- sizeof(certDBEntryNickname));
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- entry->common.arena = arena;
- entry->common.type = certDBEntryTypeNickname;
-
- rv = EncodeDBNicknameKey(nickname, tmparena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- /* is record long enough for header? */
- if ( dbentry.len < DB_NICKNAME_ENTRY_HEADER_LEN ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- rv = DecodeDBNicknameEntry(entry, &dbentry, nickname);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(entry);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-/*
- * Encode a nickname entry into byte stream suitable for
- * the database
- */
-static SECStatus
-WriteDBNicknameEntry(CERTCertDBHandle *handle, certDBEntryNickname *entry)
-{
- SECItem dbitem, dbkey;
- PRArenaPool *tmparena = NULL;
- SECStatus rv;
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- goto loser;
- }
-
- rv = EncodeDBNicknameEntry(entry, tmparena, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = EncodeDBNicknameKey(entry->nickname, tmparena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* now write it to the database */
- rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- return(SECFailure);
-
-}
-
-/*
- * Encode a database smime record
- */
-static SECStatus
-EncodeDBSMimeEntry(certDBEntrySMime *entry, PRArenaPool *arena,
- SECItem *dbitem)
-{
- unsigned char *buf;
-
- /* allocate space for encoded database record, including space
- * for low level header
- */
- dbitem->len = entry->subjectName.len + entry->smimeOptions.len +
- entry->optionsDate.len +
- DB_SMIME_ENTRY_HEADER_LEN + SEC_DB_ENTRY_HEADER_LEN;
-
- dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len);
- if ( dbitem->data == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* fill in database record */
- buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN];
-
- buf[0] = ( entry->subjectName.len >> 8 ) & 0xff;
- buf[1] = entry->subjectName.len & 0xff;
- buf[2] = ( entry->smimeOptions.len >> 8 ) & 0xff;
- buf[3] = entry->smimeOptions.len & 0xff;
- buf[4] = ( entry->optionsDate.len >> 8 ) & 0xff;
- buf[5] = entry->optionsDate.len & 0xff;
-
- /* if no smime options, then there should not be an options date either */
- PORT_Assert( ! ( ( entry->smimeOptions.len == 0 ) &&
- ( entry->optionsDate.len != 0 ) ) );
-
- PORT_Memcpy(&buf[DB_SMIME_ENTRY_HEADER_LEN], entry->subjectName.data,
- entry->subjectName.len);
- if ( entry->smimeOptions.len ) {
- PORT_Memcpy(&buf[DB_SMIME_ENTRY_HEADER_LEN+entry->subjectName.len],
- entry->smimeOptions.data,
- entry->smimeOptions.len);
- PORT_Memcpy(&buf[DB_SMIME_ENTRY_HEADER_LEN + entry->subjectName.len +
- entry->smimeOptions.len],
- entry->optionsDate.data,
- entry->optionsDate.len);
- }
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/*
- * Encode a database key for a SMIME record
- */
-static SECStatus
-EncodeDBSMimeKey(char *emailAddr, PRArenaPool *arena,
- SECItem *dbkey)
-{
- unsigned int addrlen;
-
- addrlen = PORT_Strlen(emailAddr) + 1; /* includes null */
-
- /* now get the database key and format it */
- dbkey->len = addrlen + SEC_DB_KEY_HEADER_LEN;
- dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
- if ( dbkey->data == NULL ) {
- goto loser;
- }
- PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], emailAddr, addrlen);
- dbkey->data[0] = certDBEntryTypeSMimeProfile;
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/*
- * Decode a database SMIME record
- */
-static SECStatus
-DecodeDBSMimeEntry(certDBEntrySMime *entry, SECItem *dbentry, char *emailAddr)
-{
- /* is record long enough for header? */
- if ( dbentry->len < DB_SMIME_ENTRY_HEADER_LEN ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- /* is database entry correct length? */
- entry->subjectName.len = ( ( dbentry->data[0] << 8 ) | dbentry->data[1] );
- entry->smimeOptions.len = ( ( dbentry->data[2] << 8 ) | dbentry->data[3] );
- entry->optionsDate.len = ( ( dbentry->data[4] << 8 ) | dbentry->data[5] );
- if (( entry->subjectName.len + entry->smimeOptions.len +
- entry->optionsDate.len + DB_SMIME_ENTRY_HEADER_LEN ) != dbentry->len){
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- /* copy the subject name */
- entry->subjectName.data =
- (unsigned char *)PORT_ArenaAlloc(entry->common.arena,
- entry->subjectName.len);
- if ( entry->subjectName.data == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- PORT_Memcpy(entry->subjectName.data,
- &dbentry->data[DB_SMIME_ENTRY_HEADER_LEN],
- entry->subjectName.len);
-
- /* copy the smime options */
- if ( entry->smimeOptions.len ) {
- entry->smimeOptions.data =
- (unsigned char *)PORT_ArenaAlloc(entry->common.arena,
- entry->smimeOptions.len);
- if ( entry->smimeOptions.data == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- PORT_Memcpy(entry->smimeOptions.data,
- &dbentry->data[DB_SMIME_ENTRY_HEADER_LEN +
- entry->subjectName.len],
- entry->smimeOptions.len);
- }
- if ( entry->optionsDate.len ) {
- entry->optionsDate.data =
- (unsigned char *)PORT_ArenaAlloc(entry->common.arena,
- entry->optionsDate.len);
- if ( entry->optionsDate.data == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- PORT_Memcpy(entry->optionsDate.data,
- &dbentry->data[DB_SMIME_ENTRY_HEADER_LEN +
- entry->subjectName.len +
- entry->smimeOptions.len],
- entry->optionsDate.len);
- }
-
- /* both options and options date must either exist or not exist */
- if ( ( ( entry->optionsDate.len == 0 ) ||
- ( entry->smimeOptions.len == 0 ) ) &&
- entry->smimeOptions.len != entry->optionsDate.len ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- entry->emailAddr = (char *)PORT_Alloc(PORT_Strlen(emailAddr)+1);
- if ( entry->emailAddr ) {
- PORT_Strcpy(entry->emailAddr, emailAddr);
- }
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/*
- * create a new SMIME entry
- */
-static certDBEntrySMime *
-NewDBSMimeEntry(char *emailAddr, SECItem *subjectName, SECItem *smimeOptions,
- SECItem *optionsDate, unsigned int flags)
-{
- PRArenaPool *arena = NULL;
- certDBEntrySMime *entry;
- int addrlen;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- entry = (certDBEntrySMime *)PORT_ArenaAlloc(arena,
- sizeof(certDBEntrySMime));
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* init common fields */
- entry->common.arena = arena;
- entry->common.type = certDBEntryTypeSMimeProfile;
- entry->common.version = CERT_DB_FILE_VERSION;
- entry->common.flags = flags;
-
- /* copy the email addr */
- addrlen = PORT_Strlen(emailAddr) + 1;
-
- entry->emailAddr = (char*)PORT_ArenaAlloc(arena, addrlen);
- if ( entry->emailAddr == NULL ) {
- goto loser;
- }
-
- PORT_Memcpy(entry->emailAddr, emailAddr, addrlen);
-
- /* copy the subject name */
- rv = SECITEM_CopyItem(arena, &entry->subjectName, subjectName);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* copy the smime options */
- if ( smimeOptions ) {
- rv = SECITEM_CopyItem(arena, &entry->smimeOptions, smimeOptions);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- } else {
- PORT_Assert(optionsDate == NULL);
- entry->smimeOptions.data = NULL;
- entry->smimeOptions.len = 0;
- }
-
- /* copy the options date */
- if ( optionsDate ) {
- rv = SECITEM_CopyItem(arena, &entry->optionsDate, optionsDate);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- } else {
- PORT_Assert(smimeOptions == NULL);
- entry->optionsDate.data = NULL;
- entry->optionsDate.len = 0;
- }
-
- return(entry);
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-/*
- * delete a SMIME entry
- */
-static SECStatus
-DeleteDBSMimeEntry(CERTCertDBHandle *handle, char *emailAddr)
-{
- PRArenaPool *arena = NULL;
- SECStatus rv;
- SECItem dbkey;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- rv = EncodeDBSMimeKey(emailAddr, arena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = DeleteDBEntry(handle, certDBEntryTypeSMimeProfile, &dbkey);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- PORT_FreeArena(arena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(SECFailure);
-}
-
-/*
- * Read a SMIME entry
- */
-static certDBEntrySMime *
-ReadDBSMimeEntry(CERTCertDBHandle *handle, char *emailAddr)
-{
- PRArenaPool *arena = NULL;
- PRArenaPool *tmparena = NULL;
- certDBEntrySMime *entry;
- SECItem dbkey;
- SECItem dbentry;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- entry = (certDBEntrySMime *)PORT_ArenaAlloc(arena,
- sizeof(certDBEntrySMime));
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- entry->common.arena = arena;
- entry->common.type = certDBEntryTypeSMimeProfile;
-
- rv = EncodeDBSMimeKey(emailAddr, tmparena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- /* is record long enough for header? */
- if ( dbentry.len < DB_SMIME_ENTRY_HEADER_LEN ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- rv = DecodeDBSMimeEntry(entry, &dbentry, emailAddr);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(entry);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-/*
- * Encode a SMIME entry into byte stream suitable for
- * the database
- */
-static SECStatus
-WriteDBSMimeEntry(CERTCertDBHandle *handle, certDBEntrySMime *entry)
-{
- SECItem dbitem, dbkey;
- PRArenaPool *tmparena = NULL;
- SECStatus rv;
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- goto loser;
- }
-
- rv = EncodeDBSMimeEntry(entry, tmparena, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = EncodeDBSMimeKey(entry->emailAddr, tmparena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* now write it to the database */
- rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- return(SECFailure);
-
-}
-
-/*
- * Encode a database subject record
- */
-static SECStatus
-EncodeDBSubjectEntry(certDBEntrySubject *entry, PRArenaPool *arena,
- SECItem *dbitem)
-{
- unsigned char *buf;
- int len;
- unsigned int ncerts;
- unsigned int i;
- unsigned char *tmpbuf;
- unsigned int nnlen = 0;
- unsigned int eaddrlen = 0;
- int keyidoff;
- SECItem *certKeys;
- SECItem *keyIDs;
-
- if ( entry->nickname ) {
- nnlen = PORT_Strlen(entry->nickname) + 1;
- }
- if ( entry->emailAddr ) {
- eaddrlen = PORT_Strlen(entry->emailAddr) + 1;
- }
-
- ncerts = entry->ncerts;
-
- /* compute the length of the entry */
- keyidoff = DB_SUBJECT_ENTRY_HEADER_LEN + nnlen + eaddrlen;
- len = keyidoff + 4 * ncerts;
- for ( i = 0; i < ncerts; i++ ) {
- len += entry->certKeys[i].len;
- len += entry->keyIDs[i].len;
- }
-
- /* allocate space for encoded database record, including space
- * for low level header
- */
- dbitem->len = len + SEC_DB_ENTRY_HEADER_LEN;
-
- dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len);
- if ( dbitem->data == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* fill in database record */
- buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN];
-
- buf[0] = ( ncerts >> 8 ) & 0xff;
- buf[1] = ncerts & 0xff;
- buf[2] = ( nnlen >> 8 ) & 0xff;
- buf[3] = nnlen & 0xff;
- buf[4] = ( eaddrlen >> 8 ) & 0xff;
- buf[5] = eaddrlen & 0xff;
-
- PORT_Memcpy(&buf[DB_SUBJECT_ENTRY_HEADER_LEN], entry->nickname, nnlen);
- PORT_Memcpy(&buf[DB_SUBJECT_ENTRY_HEADER_LEN+nnlen], entry->emailAddr,
- eaddrlen);
-
- for ( i = 0; i < ncerts; i++ ) {
-
- certKeys = entry->certKeys;
- keyIDs = entry->keyIDs;
-
- buf[keyidoff+i*2] = ( certKeys[i].len >> 8 ) & 0xff;
- buf[keyidoff+1+i*2] = certKeys[i].len & 0xff;
- buf[keyidoff+ncerts*2+i*2] = ( keyIDs[i].len >> 8 ) & 0xff;
- buf[keyidoff+1+ncerts*2+i*2] = keyIDs[i].len & 0xff;
- }
-
- /* temp pointer used to stuff certkeys and keyids into the buffer */
- tmpbuf = &buf[keyidoff+ncerts*4];
-
- for ( i = 0; i < ncerts; i++ ) {
- certKeys = entry->certKeys;
- PORT_Memcpy(tmpbuf, certKeys[i].data, certKeys[i].len);
- tmpbuf = tmpbuf + certKeys[i].len;
- }
-
- for ( i = 0; i < ncerts; i++ ) {
- keyIDs = entry->keyIDs;
- PORT_Memcpy(tmpbuf, keyIDs[i].data, keyIDs[i].len);
- tmpbuf = tmpbuf + keyIDs[i].len;
- }
-
- PORT_Assert(tmpbuf == &buf[len]);
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/*
- * Encode a database key for a subject record
- */
-static SECStatus
-EncodeDBSubjectKey(SECItem *derSubject, PRArenaPool *arena,
- SECItem *dbkey)
-{
- dbkey->len = derSubject->len + SEC_DB_KEY_HEADER_LEN;
- dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
- if ( dbkey->data == NULL ) {
- goto loser;
- }
- PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], derSubject->data,
- derSubject->len);
- dbkey->data[0] = certDBEntryTypeSubject;
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-static SECStatus
-DecodeDBSubjectEntry(certDBEntrySubject *entry, SECItem *dbentry,
- SECItem *derSubject)
-{
- unsigned int ncerts;
- PRArenaPool *arena;
- unsigned int len, itemlen;
- unsigned char *tmpbuf;
- unsigned int i;
- SECStatus rv;
- unsigned int keyidoff;
- unsigned int nnlen, eaddrlen;
-
- arena = entry->common.arena;
-
- rv = SECITEM_CopyItem(arena, &entry->derSubject, derSubject);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* is record long enough for header? */
- if ( dbentry->len < DB_SUBJECT_ENTRY_HEADER_LEN ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- entry->ncerts = ncerts = ( ( dbentry->data[0] << 8 ) | dbentry->data[1] );
- nnlen = ( ( dbentry->data[2] << 8 ) | dbentry->data[3] );
- eaddrlen = ( ( dbentry->data[4] << 8 ) | dbentry->data[5] );
- if ( dbentry->len < ( ncerts * 4 + DB_SUBJECT_ENTRY_HEADER_LEN +
- nnlen + eaddrlen) ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- entry->certKeys = (SECItem *)PORT_ArenaAlloc(arena,
- sizeof(SECItem) * ncerts);
- entry->keyIDs = (SECItem *)PORT_ArenaAlloc(arena,
- sizeof(SECItem) * ncerts);
-
- if ( ( entry->certKeys == NULL ) || ( entry->keyIDs == NULL ) ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- if ( nnlen > 1 ) { /* null terminator is stored */
- entry->nickname = (char *)PORT_ArenaAlloc(arena, nnlen);
- if ( entry->nickname == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- PORT_Memcpy(entry->nickname,
- &dbentry->data[DB_SUBJECT_ENTRY_HEADER_LEN],
- nnlen);
- } else {
- entry->nickname = NULL;
- }
-
- if ( eaddrlen > 1 ) { /* null terminator is stored */
- entry->emailAddr = (char *)PORT_ArenaAlloc(arena, eaddrlen);
- if ( entry->emailAddr == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- PORT_Memcpy(entry->emailAddr,
- &dbentry->data[DB_SUBJECT_ENTRY_HEADER_LEN+nnlen],
- eaddrlen);
- } else {
- entry->emailAddr = NULL;
- }
-
- /* collect the lengths of the certKeys and keyIDs, and total the
- * overall length.
- */
- keyidoff = DB_SUBJECT_ENTRY_HEADER_LEN + nnlen + eaddrlen;
- len = keyidoff + 4 * ncerts;
-
- tmpbuf = &dbentry->data[0];
-
- for ( i = 0; i < ncerts; i++ ) {
-
- itemlen = ( tmpbuf[keyidoff + 2*i] << 8 ) | tmpbuf[keyidoff + 1 + 2*i] ;
- len += itemlen;
- entry->certKeys[i].len = itemlen;
-
- itemlen = ( tmpbuf[keyidoff + 2*ncerts + 2*i] << 8 ) |
- tmpbuf[keyidoff + 1 + 2*ncerts + 2*i] ;
- len += itemlen;
- entry->keyIDs[i].len = itemlen;
- }
-
- /* is database entry correct length? */
- if ( len != dbentry->len ){
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- tmpbuf = &tmpbuf[keyidoff + 4*ncerts];
- for ( i = 0; i < ncerts; i++ ) {
- entry->certKeys[i].data =
- (unsigned char *)PORT_ArenaAlloc(arena, entry->certKeys[i].len);
- if ( entry->certKeys[i].data == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- PORT_Memcpy(entry->certKeys[i].data, tmpbuf, entry->certKeys[i].len);
- tmpbuf = &tmpbuf[entry->certKeys[i].len];
- }
-
- for ( i = 0; i < ncerts; i++ ) {
- entry->keyIDs[i].data =
- (unsigned char *)PORT_ArenaAlloc(arena, entry->keyIDs[i].len);
- if ( entry->keyIDs[i].data == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- PORT_Memcpy(entry->keyIDs[i].data, tmpbuf, entry->keyIDs[i].len);
- tmpbuf = &tmpbuf[entry->keyIDs[i].len];
- }
-
- PORT_Assert(tmpbuf == &dbentry->data[dbentry->len]);
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/*
- * create a new subject entry with a single cert
- */
-static certDBEntrySubject *
-NewDBSubjectEntry(SECItem *derSubject, SECItem *certKey,
- SECItem *keyID, char *nickname, char *emailAddr,
- unsigned int flags)
-{
- PRArenaPool *arena = NULL;
- certDBEntrySubject *entry;
- SECStatus rv;
- unsigned int nnlen;
- unsigned int eaddrlen;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- entry = (certDBEntrySubject *)PORT_ArenaAlloc(arena,
- sizeof(certDBEntrySubject));
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* init common fields */
- entry->common.arena = arena;
- entry->common.type = certDBEntryTypeSubject;
- entry->common.version = CERT_DB_FILE_VERSION;
- entry->common.flags = flags;
-
- /* copy the subject */
- rv = SECITEM_CopyItem(arena, &entry->derSubject, derSubject);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- entry->ncerts = 1;
- /* copy nickname */
- if ( nickname && ( *nickname != '\0' ) ) {
- nnlen = PORT_Strlen(nickname) + 1;
- entry->nickname = (char *)PORT_ArenaAlloc(arena, nnlen);
- if ( entry->nickname == NULL ) {
- goto loser;
- }
-
- PORT_Memcpy(entry->nickname, nickname, nnlen);
- } else {
- entry->nickname = NULL;
- }
-
- /* copy email addr */
- if ( emailAddr && ( *emailAddr != '\0' ) ) {
- emailAddr = CERT_FixupEmailAddr(emailAddr);
- if ( emailAddr == NULL ) {
- entry->emailAddr = NULL;
- goto loser;
- }
-
- eaddrlen = PORT_Strlen(emailAddr) + 1;
- entry->emailAddr = (char *)PORT_ArenaAlloc(arena, eaddrlen);
- if ( entry->emailAddr == NULL ) {
- PORT_Free(emailAddr);
- goto loser;
- }
-
- PORT_Memcpy(entry->emailAddr, emailAddr, eaddrlen);
- PORT_Free(emailAddr);
- } else {
- entry->emailAddr = NULL;
- }
-
- /* allocate space for certKeys and keyIDs */
- entry->certKeys = (SECItem *)PORT_ArenaAlloc(arena, sizeof(SECItem));
- entry->keyIDs = (SECItem *)PORT_ArenaAlloc(arena, sizeof(SECItem));
- if ( ( entry->certKeys == NULL ) || ( entry->keyIDs == NULL ) ) {
- goto loser;
- }
-
- /* copy the certKey and keyID */
- rv = SECITEM_CopyItem(arena, &entry->certKeys[0], certKey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- rv = SECITEM_CopyItem(arena, &entry->keyIDs[0], keyID);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- return(entry);
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-/*
- * delete a subject entry
- */
-static SECStatus
-DeleteDBSubjectEntry(CERTCertDBHandle *handle, SECItem *derSubject)
-{
- SECItem dbkey;
- PRArenaPool *arena = NULL;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- rv = EncodeDBSubjectKey(derSubject, arena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = DeleteDBEntry(handle, certDBEntryTypeSubject, &dbkey);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- PORT_FreeArena(arena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(SECFailure);
-}
-
-/*
- * Read the subject entry
- */
-static certDBEntrySubject *
-ReadDBSubjectEntry(CERTCertDBHandle *handle, SECItem *derSubject)
-{
- PRArenaPool *arena = NULL;
- PRArenaPool *tmparena = NULL;
- certDBEntrySubject *entry;
- SECItem dbkey;
- SECItem dbentry;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- entry = (certDBEntrySubject *)PORT_ArenaAlloc(arena,
- sizeof(certDBEntrySubject));
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- entry->common.arena = arena;
- entry->common.type = certDBEntryTypeSubject;
-
- rv = EncodeDBSubjectKey(derSubject, tmparena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- rv = DecodeDBSubjectEntry(entry, &dbentry, derSubject);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(entry);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-/*
- * Encode a subject name entry into byte stream suitable for
- * the database
- */
-static SECStatus
-WriteDBSubjectEntry(CERTCertDBHandle *handle, certDBEntrySubject *entry)
-{
- SECItem dbitem, dbkey;
- PRArenaPool *tmparena = NULL;
- SECStatus rv;
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- goto loser;
- }
-
- rv = EncodeDBSubjectEntry(entry, tmparena, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = EncodeDBSubjectKey(&entry->derSubject, tmparena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* now write it to the database */
- rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- return(SECFailure);
-
-}
-
-static SECStatus
-UpdateSubjectWithEmailAddr(CERTCertificate *cert, char *emailAddr)
-{
- CERTSubjectList *subjectList;
- PRBool save = PR_FALSE, delold = PR_FALSE;
- certDBEntrySubject *entry;
- SECStatus rv;
-
- emailAddr = CERT_FixupEmailAddr(emailAddr);
- if ( emailAddr == NULL ) {
- return(SECFailure);
- }
-
- subjectList = cert->subjectList;
- PORT_Assert(subjectList != NULL);
-
- if ( subjectList->emailAddr ) {
- if ( PORT_Strcmp(subjectList->emailAddr, emailAddr) != 0 ) {
- save = PR_TRUE;
- delold = PR_TRUE;
- }
- } else {
- save = PR_TRUE;
- }
-
- if ( delold ) {
- /* delete the old smime entry, because this cert now has a new
- * smime entry pointing to it
- */
- PORT_Assert(save);
- PORT_Assert(subjectList->emailAddr != NULL);
- DeleteDBSMimeEntry(cert->dbhandle, subjectList->emailAddr);
- }
-
- if ( save ) {
- unsigned int len;
-
- entry = subjectList->entry;
-
- PORT_Assert(entry != NULL);
- len = PORT_Strlen(emailAddr) + 1;
- entry->emailAddr = (char *)PORT_ArenaAlloc(entry->common.arena, len);
- if ( entry->emailAddr == NULL ) {
- goto loser;
- }
- PORT_Memcpy(entry->emailAddr, emailAddr, len);
-
- /* delete the subject entry */
- DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject);
-
- /* write the new one */
- rv = WriteDBSubjectEntry(cert->dbhandle, entry);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- }
-
- PORT_Free(emailAddr);
- return(SECSuccess);
-
-loser:
- PORT_Free(emailAddr);
- return(SECFailure);
-}
-
-/*
- * writes a nickname to an existing subject entry that does not currently
- * have one
- */
-static SECStatus
-AddNicknameToSubject(CERTCertificate *cert, char *nickname)
-{
- CERTSubjectList *subjectList;
- certDBEntrySubject *entry;
- SECStatus rv;
-
- if ( nickname == NULL ) {
- return(SECFailure);
- }
-
- subjectList = cert->subjectList;
- PORT_Assert(subjectList != NULL);
- if ( subjectList == NULL ) {
- goto loser;
- }
-
- entry = subjectList->entry;
- PORT_Assert(entry != NULL);
- if ( entry == NULL ) {
- goto loser;
- }
-
- PORT_Assert(entry->nickname == NULL);
- if ( entry->nickname != NULL ) {
- goto loser;
- }
-
- entry->nickname = (nickname) ? PORT_ArenaStrdup(entry->common.arena, nickname) : NULL;
-
- if ( entry->nickname == NULL ) {
- goto loser;
- }
-
- /* delete the subject entry */
- DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject);
-
- /* write the new one */
- rv = WriteDBSubjectEntry(cert->dbhandle, entry);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/*
- * create a new version entry
- */
-static certDBEntryVersion *
-NewDBVersionEntry(unsigned int flags)
-{
- PRArenaPool *arena = NULL;
- certDBEntryVersion *entry;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- entry = (certDBEntryVersion *)PORT_ArenaAlloc(arena,
- sizeof(certDBEntryVersion));
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- entry->common.arena = arena;
- entry->common.type = certDBEntryTypeVersion;
- entry->common.version = CERT_DB_FILE_VERSION;
- entry->common.flags = flags;
-
- return(entry);
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-/*
- * Read the version entry
- */
-static certDBEntryVersion *
-ReadDBVersionEntry(CERTCertDBHandle *handle)
-{
- PRArenaPool *arena = NULL;
- PRArenaPool *tmparena = NULL;
- certDBEntryVersion *entry;
- SECItem dbkey;
- SECItem dbentry;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- entry = (certDBEntryVersion *)PORT_ArenaAlloc(arena,
- sizeof(certDBEntryVersion));
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- entry->common.arena = arena;
- entry->common.type = certDBEntryTypeVersion;
-
- /* now get the database key and format it */
- dbkey.len = SEC_DB_VERSION_KEY_LEN + SEC_DB_KEY_HEADER_LEN;
- dbkey.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbkey.len);
- if ( dbkey.data == NULL ) {
- goto loser;
- }
- 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);
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(entry);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-
-/*
- * Encode a version entry into byte stream suitable for
- * the database
- */
-static SECStatus
-WriteDBVersionEntry(CERTCertDBHandle *handle, certDBEntryVersion *entry)
-{
- SECItem dbitem, dbkey;
- PRArenaPool *tmparena = NULL;
- SECStatus rv;
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- goto loser;
- }
-
- /* allocate space for encoded database record, including space
- * for low level header
- */
- dbitem.len = SEC_DB_ENTRY_HEADER_LEN;
-
- dbitem.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbitem.len);
- if ( dbitem.data == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* now get the database key and format it */
- dbkey.len = SEC_DB_VERSION_KEY_LEN + SEC_DB_KEY_HEADER_LEN;
- dbkey.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbkey.len);
- if ( dbkey.data == NULL ) {
- goto loser;
- }
- PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], SEC_DB_VERSION_KEY,
- SEC_DB_VERSION_KEY_LEN);
-
- /* now write it to the database */
- rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- return(SECFailure);
-}
-
-/*
- * create a new version entry
- */
-static certDBEntryContentVersion *
-NewDBContentVersionEntry(unsigned int flags)
-{
- PRArenaPool *arena = NULL;
- certDBEntryContentVersion *entry;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- entry = (certDBEntryContentVersion *)
- PORT_ArenaAlloc(arena, sizeof(certDBEntryContentVersion));
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- entry->common.arena = arena;
- entry->common.type = certDBEntryTypeContentVersion;
- entry->common.version = CERT_DB_FILE_VERSION;
- entry->common.flags = flags;
-
- entry->contentVersion = CERT_DB_CONTENT_VERSION;
-
- return(entry);
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-/*
- * Read the version entry
- */
-static certDBEntryContentVersion *
-ReadDBContentVersionEntry(CERTCertDBHandle *handle)
-{
- PRArenaPool *arena = NULL;
- PRArenaPool *tmparena = NULL;
- certDBEntryContentVersion *entry;
- SECItem dbkey;
- SECItem dbentry;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- entry = (certDBEntryContentVersion *)
- PORT_ArenaAlloc(arena, sizeof(certDBEntryContentVersion));
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- entry->common.arena = arena;
- entry->common.type = certDBEntryTypeContentVersion;
-
- /* now get the database key and format it */
- dbkey.len = SEC_DB_CONTENT_VERSION_KEY_LEN + SEC_DB_KEY_HEADER_LEN;
- dbkey.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbkey.len);
- if ( dbkey.data == NULL ) {
- goto loser;
- }
- PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], SEC_DB_CONTENT_VERSION_KEY,
- SEC_DB_CONTENT_VERSION_KEY_LEN);
-
- dbentry.len = 0;
- dbentry.data = NULL;
-
- ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);
-
- if ( dbentry.len != 1 ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- entry->contentVersion = dbentry.data[0];
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(entry);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-/*
- * Encode a version entry into byte stream suitable for
- * the database
- */
-static SECStatus
-WriteDBContentVersionEntry(CERTCertDBHandle *handle,
- certDBEntryContentVersion *entry)
-{
- SECItem dbitem, dbkey;
- PRArenaPool *tmparena = NULL;
- SECStatus rv;
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- goto loser;
- }
-
- /* allocate space for encoded database record, including space
- * for low level header
- */
- dbitem.len = SEC_DB_ENTRY_HEADER_LEN + 1;
-
- dbitem.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbitem.len);
- if ( dbitem.data == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- dbitem.data[SEC_DB_ENTRY_HEADER_LEN] = entry->contentVersion;
-
- /* now get the database key and format it */
- dbkey.len = SEC_DB_CONTENT_VERSION_KEY_LEN + SEC_DB_KEY_HEADER_LEN;
- dbkey.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbkey.len);
- if ( dbkey.data == NULL ) {
- goto loser;
- }
- PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], SEC_DB_CONTENT_VERSION_KEY,
- SEC_DB_CONTENT_VERSION_KEY_LEN);
-
- /* now write it to the database */
- rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- return(SECFailure);
-}
-
-/*
- * delete a content version entry
- */
-static SECStatus
-DeleteDBContentVersionEntry(CERTCertDBHandle *handle)
-{
- SECItem dbkey;
- PRArenaPool *arena = NULL;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- /* now get the database key and format it */
- dbkey.len = SEC_DB_CONTENT_VERSION_KEY_LEN + SEC_DB_KEY_HEADER_LEN;
- dbkey.data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey.len);
- if ( dbkey.data == NULL ) {
- goto loser;
- }
- PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], SEC_DB_CONTENT_VERSION_KEY,
- SEC_DB_CONTENT_VERSION_KEY_LEN);
-
- rv = DeleteDBEntry(handle, certDBEntryTypeContentVersion, &dbkey);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- PORT_FreeArena(arena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(SECFailure);
-}
-
-/*
- * Routines and datastructures to manage the list of certificates for a
- * particular subject name.
- */
-
-/*
- * Create a new certificate subject list. If entry exists, then populate
- * the list with the entries from the permanent database.
- */
-static CERTSubjectList *
-NewSubjectList(certDBEntrySubject *entry)
-{
- PRArenaPool *permarena;
- unsigned int i;
- CERTSubjectList *subjectList;
- CERTSubjectNode *node;
- SECStatus rv;
-
- permarena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( permarena == NULL ) {
- goto loser;
- }
- subjectList = (CERTSubjectList *)PORT_ArenaAlloc(permarena,
- sizeof(CERTSubjectList));
- if ( subjectList == NULL ) {
- goto loser;
- }
-
- subjectList->arena = permarena;
- subjectList->ncerts = 0;
- subjectList->head = NULL;
- subjectList->tail = NULL;
- subjectList->entry = entry;
- subjectList->emailAddr = NULL;
- if ( entry ) {
-
- /* initialize the list with certs from database entry */
- for ( i = 0; i < entry->ncerts; i++ ) {
- /* Init the node */
- node = (CERTSubjectNode *)PORT_ArenaAlloc(permarena,
- sizeof(CERTSubjectNode));
- if ( node == NULL ) {
- goto loser;
- }
-
- /* copy certKey and keyID to node */
- rv = SECITEM_CopyItem(permarena, &node->certKey,
- &entry->certKeys[i]);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- rv = SECITEM_CopyItem(permarena, &node->keyID,
- &entry->keyIDs[i]);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* the certs are already in order, so just add them
- * to the tail.
- */
- node->next = NULL;
- if ( subjectList->tail == NULL ) {
- /* first in list */
- subjectList->head = node;
- subjectList->tail = node;
- node->prev = NULL;
- } else {
- /* add to end of list */
- node->prev = subjectList->tail;
- subjectList->tail = node;
- node->prev->next = node;
- }
- subjectList->ncerts++;
- }
- }
-
- return(subjectList);
-
-loser:
- PORT_FreeArena(permarena, PR_FALSE);
- return(NULL);
-}
-
-/*
- * Find the Subject entry in the temp database. It it is not in the
- * temp database, then get it from the perm DB. It its not there either,
- * then create a new one.
- */
-static CERTSubjectList *
-FindSubjectList(CERTCertDBHandle *handle, SECItem *subject, PRBool create)
-{
- PRArenaPool *arena = NULL;
- SECItem keyitem;
- SECStatus rv;
- DBT namekey;
- DBT tmpdata;
- int ret;
- CERTSubjectList *subjectList = NULL;
- certDBEntrySubject *entry;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- rv = EncodeDBSubjectKey(subject, arena, &keyitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- namekey.data = keyitem.data;
- namekey.size = keyitem.len;
-
- /* lookup in the temporary database */
- ret = certdb_Get(handle->tempCertDB, &namekey, &tmpdata, 0);
-
- /* error accessing the database */
- if ( ret < 0 ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- if ( ret == 0 ) { /* found in temp database */
- if ( tmpdata.size != sizeof(CERTCertificate *) ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- /* copy pointer out of database */
- PORT_Memcpy(&subjectList, tmpdata.data, tmpdata.size);
- } else { /* not found in temporary database */
- entry = ReadDBSubjectEntry(handle, subject);
- if ( entry || create ) {
- /* decode or create new subject list */
- subjectList = NewSubjectList(entry);
-
- /* put it in the temp database */
- if ( subjectList ) {
- tmpdata.data = (unsigned char *)(&subjectList);
- tmpdata.size = sizeof(subjectList);
- ret = certdb_Put(handle->tempCertDB, &namekey,
- &tmpdata, R_NOOVERWRITE);
- if ( ret ) {
- goto loser;
- }
- }
- } else {
- PORT_SetError(SEC_ERROR_UNKNOWN_CERT);
- goto loser;
- }
- }
-
- goto done;
-
-loser:
- subjectList = NULL;
-
-done:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(subjectList);
-}
-
-/*
- * Add a temp cert to the temp subject list
- */
-static SECStatus
-AddTempCertToSubjectList(CERTCertificate *cert)
-{
- CERTSubjectList *subjectList;
- CERTSubjectNode *node, *newnode;
- CERTCertificate *cmpcert;
- PRBool newer;
- SECStatus rv;
-
- PORT_Assert(cert->isperm == PR_FALSE);
- PORT_Assert(cert->subjectList == NULL);
-
- subjectList = FindSubjectList(cert->dbhandle, &cert->derSubject, PR_TRUE);
-
- if ( subjectList == NULL ) {
- goto loser;
- }
-
- newnode = (CERTSubjectNode*)PORT_ArenaAlloc(subjectList->arena,
- sizeof(CERTSubjectNode));
- /* copy certKey and keyID to node */
- rv = SECITEM_CopyItem(subjectList->arena, &newnode->certKey,
- &cert->certKey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- rv = SECITEM_CopyItem(subjectList->arena, &newnode->keyID,
- &cert->subjectKeyID);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- node = subjectList->head;
-
- if ( node ) {
- /* list is not empty */
- while ( node ) {
- cmpcert = CERT_FindCertByKeyNoLocking(cert->dbhandle,
- &node->certKey);
- if ( cmpcert ) {
-
- newer = CERT_IsNewer(cert, cmpcert);
- CERT_DestroyCertificateNoLocking(cmpcert);
- if ( newer ) {
- /* insert before this cert */
- newnode->next = node;
- newnode->prev = node->prev;
- if ( newnode->prev ) {
- newnode->prev->next = newnode;
- } else {
- /* at the head of the list */
- subjectList->head = newnode;
- }
- node->prev = newnode;
- goto done;
- }
- }
- node = node->next;
- }
- /* if we get here, we add the node to the end of the list */
- newnode->prev = subjectList->tail;
- newnode->next = NULL;
- subjectList->tail->next = newnode;
- subjectList->tail = newnode;
- } else {
- /* this is a new/empty list */
- newnode->next = NULL;
- newnode->prev = NULL;
- subjectList->head = newnode;
- subjectList->tail = newnode;
- }
-
-done:
- subjectList->ncerts++;
- cert->subjectList = subjectList;
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/*
- * Find the node in a subjectList that belongs a cert
- */
-static CERTSubjectNode *
-FindCertSubjectNode(CERTCertificate *cert)
-{
- CERTSubjectList *subjectList;
- CERTSubjectNode *node = NULL;
-
- PORT_Assert(cert->subjectList);
-
- subjectList = cert->subjectList;
-
- if ( subjectList ) {
- node = subjectList->head;
- }
-
- while ( node ) {
- if ( SECITEM_CompareItem(&node->certKey, &cert->certKey) == SECEqual ){
- return(node);
- break;
- }
-
- node = node->next;
- }
-
- return(NULL);
-}
-
-/*
- * Remove a temp cert from the temp subject list
- */
-static SECStatus
-RemoveTempCertFromSubjectList(CERTCertificate *cert)
-{
- CERTSubjectList *subjectList;
- CERTSubjectNode *node;
- SECItem keyitem;
- DBT namekey;
- SECStatus rv;
- int ret;
- CERTCertDBHandle *handle;
-
- PORT_Assert(cert->subjectList);
-
- /* don't remove perm certs */
- if ( cert->isperm ) {
- return(SECSuccess);
- }
-
- subjectList = cert->subjectList;
-
- node = FindCertSubjectNode(cert);
-
- if ( node ) {
- /* found it, unlink it */
- if ( node->next ) {
- node->next->prev = node->prev;
- } else {
- /* removing from tail of list */
- subjectList->tail = node->prev;
- }
- if ( node->prev ) {
- node->prev->next = node->next;
- } else {
- /* removing from head of list */
- subjectList->head = node->next;
- }
-
- subjectList->ncerts--;
-
- /* dont need to free the node, because it is from subjectList
- * arena.
- */
-
- /* remove reference from cert */
- cert->subjectList = NULL;
-
- /* if the list is now empty, remove the list from the db and free it */
- if ( subjectList->head == NULL ) {
- PORT_Assert(subjectList->ncerts == 0);
- rv = EncodeDBSubjectKey(&cert->derSubject, subjectList->arena,
- &keyitem);
- if ( rv == SECSuccess ) {
- namekey.data = keyitem.data;
- namekey.size = keyitem.len;
-
- handle = cert->dbhandle;
-
- ret = certdb_Del(handle->tempCertDB, &namekey, 0);
- /* keep going if it fails */
-
- if ( cert->dbnickname ) {
- rv = SEC_DeleteTempNickname(handle, cert->dbnickname);
- } else if ( cert->nickname ) {
- rv = SEC_DeleteTempNickname(handle, cert->nickname);
- }
-
- /* keep going if it fails */
- }
-
- PORT_FreeArena(subjectList->arena, PR_FALSE);
- }
- }
-
- PORT_Assert(cert->subjectList == NULL);
-
- if ( cert->subjectList != NULL ) {
- return(SECFailure);
- }
-
- return(SECSuccess);
-}
-
-/*
- * cert is no longer a perm cert, but will remain a temp cert
- */
-static SECStatus
-RemovePermSubjectNode(CERTCertificate *cert)
-{
- CERTSubjectList *subjectList;
- certDBEntrySubject *entry;
- unsigned int i;
- SECStatus rv;
-
- PORT_Assert(cert->isperm);
- if ( !cert->isperm ) {
- return(SECFailure);
- }
-
- subjectList = cert->subjectList;
- PORT_Assert(subjectList);
- if ( subjectList == NULL ) {
- return(SECFailure);
- }
- entry = subjectList->entry;
- PORT_Assert(entry);
- if ( entry == NULL ) {
- return(SECFailure);
- }
-
- PORT_Assert(entry->ncerts);
- rv = SECFailure;
-
- if ( entry->ncerts > 1 ) {
- for ( i = 0; i < entry->ncerts; i++ ) {
- if ( SECITEM_CompareItem(&entry->certKeys[i], &cert->certKey) ==
- SECEqual ) {
- /* copy rest of list forward one entry */
- for ( i = i + 1; i < entry->ncerts; i++ ) {
- entry->certKeys[i-1] = entry->certKeys[i];
- entry->keyIDs[i-1] = entry->keyIDs[i];
- }
- entry->ncerts--;
- DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject);
- rv = WriteDBSubjectEntry(cert->dbhandle, entry);
- break;
- }
- }
- } else {
- /* no entries left, delete the perm entry in the DB */
- if ( subjectList->entry->emailAddr ) {
- /* if the subject had an email record, then delete it too */
- DeleteDBSMimeEntry(cert->dbhandle, subjectList->entry->emailAddr);
- }
-
- DestroyDBEntry((certDBEntry *)subjectList->entry);
- subjectList->entry = NULL;
- DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject);
- }
-
- return(rv);
-}
-
-/*
- * add a cert to the perm subject list
- */
-static SECStatus
-AddPermSubjectNode(CERTCertificate *cert, char *nickname)
-{
- CERTSubjectList *subjectList;
- certDBEntrySubject *entry;
- SECItem *newCertKeys, *newKeyIDs;
- int i;
- SECStatus rv;
- CERTCertificate *cmpcert;
- unsigned int nnlen;
- int ncerts;
-
- subjectList = cert->subjectList;
-
- PORT_Assert(subjectList);
- if ( subjectList == NULL ) {
- return(SECFailure);
- }
-
- entry = subjectList->entry;
-
- if ( entry ) {
- ncerts = entry->ncerts;
-
- if ( nickname && entry->nickname ) {
- /* nicknames must be the same */
- PORT_Assert(PORT_Strcmp(nickname, entry->nickname) == 0);
- }
-
- if ( ( entry->nickname == NULL ) && ( nickname != NULL ) ) {
- /* copy nickname into the entry */
- nnlen = PORT_Strlen(nickname) + 1;
- entry->nickname = (char *)PORT_ArenaAlloc(entry->common.arena,
- nnlen);
- if ( entry->nickname == NULL ) {
- return(SECFailure);
- }
- PORT_Memcpy(entry->nickname, nickname, nnlen);
- }
-
- /* a DB entry already exists, so add this cert */
- newCertKeys = (SECItem *)PORT_ArenaAlloc(entry->common.arena,
- sizeof(SECItem) *
- ( ncerts + 1 ) );
- newKeyIDs = (SECItem *)PORT_ArenaAlloc(entry->common.arena,
- sizeof(SECItem) *
- ( ncerts + 1 ) );
-
- if ( ( newCertKeys == NULL ) || ( newKeyIDs == NULL ) ) {
- return(SECFailure);
- }
-
- for ( i = 0; i < ncerts; i++ ) {
- cmpcert = CERT_FindCertByKeyNoLocking(cert->dbhandle,
- &entry->certKeys[i]);
- PORT_Assert(cmpcert);
-
- if ( CERT_IsNewer(cert, cmpcert) ) {
- /* insert before cmpcert */
- rv = SECITEM_CopyItem(entry->common.arena, &newCertKeys[i],
- &cert->certKey);
- if ( rv != SECSuccess ) {
- return(SECFailure);
- }
- rv = SECITEM_CopyItem(entry->common.arena, &newKeyIDs[i],
- &cert->subjectKeyID);
- if ( rv != SECSuccess ) {
- return(SECFailure);
- }
- /* copy the rest of the entry */
- for ( ; i < ncerts; i++ ) {
- newCertKeys[i+1] = entry->certKeys[i];
- newKeyIDs[i+1] = entry->keyIDs[i];
- }
-
- /* update certKeys and keyIDs */
- entry->certKeys = newCertKeys;
- entry->keyIDs = newKeyIDs;
-
- /* increment count */
- entry->ncerts++;
- break;
- }
- /* copy this cert entry */
- newCertKeys[i] = entry->certKeys[i];
- newKeyIDs[i] = entry->keyIDs[i];
- }
-
- if ( entry->ncerts == ncerts ) {
- /* insert new one at end */
- rv = SECITEM_CopyItem(entry->common.arena, &newCertKeys[ncerts],
- &cert->certKey);
- if ( rv != SECSuccess ) {
- return(SECFailure);
- }
- rv = SECITEM_CopyItem(entry->common.arena, &newKeyIDs[ncerts],
- &cert->subjectKeyID);
- if ( rv != SECSuccess ) {
- return(SECFailure);
- }
-
- /* update certKeys and keyIDs */
- entry->certKeys = newCertKeys;
- entry->keyIDs = newKeyIDs;
-
- /* increment count */
- entry->ncerts++;
- }
- } else {
- /* need to make a new DB entry */
- entry = NewDBSubjectEntry(&cert->derSubject, &cert->certKey,
- &cert->subjectKeyID, nickname,
- NULL, 0);
- cert->subjectList->entry = entry;
- }
- if ( entry ) {
- DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject);
- rv = WriteDBSubjectEntry(cert->dbhandle, entry);
- } else {
- rv = SECFailure;
- }
-
- return(rv);
-}
-
-
-
-SECStatus
-__CERT_TraversePermCertsForSubject(CERTCertDBHandle *handle,
- SECItem *derSubject,
- CERTCertCallback cb, void *cbarg)
-{
- certDBEntrySubject *entry;
- int i;
- CERTCertificate *cert;
- SECStatus rv = SECSuccess;
-
- entry = ReadDBSubjectEntry(handle, derSubject);
-
- if ( entry == NULL ) {
- return(SECFailure);
- }
-
- for( i = 0; i < entry->ncerts; i++ ) {
- cert = CERT_FindCertByKey(handle, &entry->certKeys[i]);
- rv = (* cb)(cert, cbarg);
- CERT_DestroyCertificate(cert);
- if ( rv == SECFailure ) {
- break;
- }
- }
-
- DestroyDBEntry((certDBEntry *)entry);
-
- return(rv);
-}
-
-SECStatus
-CERT_TraversePermCertsForSubject(CERTCertDBHandle *handle, SECItem *derSubject,
- CERTCertCallback cb, void *cbarg)
-{
- return(__CERT_TraversePermCertsForSubject(handle, derSubject, cb, cbarg));
-}
-
-int
-CERT_NumPermCertsForSubject(CERTCertDBHandle *handle, SECItem *derSubject)
-{
- certDBEntrySubject *entry;
- int ret;
-
- entry = ReadDBSubjectEntry(handle, derSubject);
-
- if ( entry == NULL ) {
- return(SECFailure);
- }
-
- ret = entry->ncerts;
-
- DestroyDBEntry((certDBEntry *)entry);
-
- return(ret);
-}
-
-SECStatus
-__CERT_TraversePermCertsForNickname(CERTCertDBHandle *handle, char *nickname,
- CERTCertCallback cb, void *cbarg)
-{
- certDBEntryNickname *nnentry = NULL;
- certDBEntrySMime *smentry = NULL;
- SECStatus rv;
- SECItem *derSubject = NULL;
-
- nnentry = ReadDBNicknameEntry(handle, nickname);
- if ( nnentry ) {
- derSubject = &nnentry->subjectName;
- } else {
- smentry = ReadDBSMimeEntry(handle, nickname);
- if ( smentry ) {
- derSubject = &smentry->subjectName;
- }
- }
-
- if ( derSubject ) {
- rv = CERT_TraversePermCertsForSubject(handle, derSubject,
- cb, cbarg);
- } else {
- rv = SECFailure;
- }
-
- if ( nnentry ) {
- DestroyDBEntry((certDBEntry *)nnentry);
- }
- if ( smentry ) {
- DestroyDBEntry((certDBEntry *)smentry);
- }
-
- return(rv);
-}
-
-SECStatus
-CERT_TraversePermCertsForNickname(CERTCertDBHandle *handle, char *nickname,
- CERTCertCallback cb, void *cbarg)
-{
- return(__CERT_TraversePermCertsForNickname(handle, nickname, cb, cbarg));
-}
-
-int
-CERT_NumPermCertsForNickname(CERTCertDBHandle *handle, char *nickname)
-{
- certDBEntryNickname *entry;
- int ret;
-
- entry = ReadDBNicknameEntry(handle, nickname);
-
- if ( entry ) {
- ret = CERT_NumPermCertsForSubject(handle, &entry->subjectName);
- DestroyDBEntry((certDBEntry *)entry);
- } else {
- ret = 0;
- }
- return(ret);
-}
-
-int
-CERT_NumCertsForCertSubject(CERTCertificate *cert)
-{
- int ret = 0;
-
- if ( cert->subjectList ) {
- ret = cert->subjectList->ncerts;
- }
- return(ret);
-}
-
-int
-CERT_NumPermCertsForCertSubject(CERTCertificate *cert)
-{
- int ret = 0;
-
- if ( cert->subjectList ) {
- if ( cert->subjectList->entry ) {
- ret = cert->subjectList->entry->ncerts;
- }
- }
- return(ret);
-}
-
-SECStatus
-CERT_TraverseCertsForSubject(CERTCertDBHandle *handle,
- CERTSubjectList *subjectList,
- CERTCertCallback cb, void *cbarg)
-{
- CERTSubjectNode *node;
- CERTCertificate *cert;
- SECStatus rv = SECSuccess;
-
- CERT_LockDB(handle);
-
- node = subjectList->head;
- while ( node ) {
-
- cert = CERT_FindCertByKeyNoLocking(handle, &node->certKey);
-
- PORT_Assert(cert != NULL);
-
- if ( cert != NULL ) {
- rv = (* cb)(cert, cbarg);
- CERT_DestroyCertificateNoLocking(cert);
- if ( rv == SECFailure ) {
- break;
- }
- }
-
- node = node->next;
- }
-
- CERT_UnlockDB(handle);
-
- return(rv);
-}
-
-
-/*
- * Given a cert, find the cert with the same subject name that
- * has the given key usage. If the given cert has the correct keyUsage, then
- * return it, otherwise search the list in order.
- */
-CERTCertificate *
-CERT_FindCertByUsage(CERTCertificate *basecert, unsigned int requiredKeyUsage)
-{
- CERTSubjectNode *node;
- CERTCertificate *cert;
- CERTSubjectList *subjectList;
-
- if ( ( basecert->keyUsage & requiredKeyUsage ) == requiredKeyUsage ) {
- return(CERT_DupCertificate(basecert));
- }
-
- CERT_LockDB(basecert->dbhandle);
-
- subjectList = basecert->subjectList;
-
- node = subjectList->head;
- while ( node ) {
-
- cert = CERT_FindCertByKeyNoLocking(basecert->dbhandle, &node->certKey);
-
- PORT_Assert(cert != NULL);
-
- if ( cert != NULL ) {
- if ( ( cert->keyUsage & requiredKeyUsage ) ==
- requiredKeyUsage ) {
- CERT_UnlockDB(basecert->dbhandle);
- return(cert);
- }
-
- CERT_DestroyCertificateNoLocking(cert);
- }
-
- node = node->next;
- }
-
- CERT_UnlockDB(basecert->dbhandle);
-
- return(NULL);
-}
-
-
-/*
- * add a nickname to a cert that doesn't have one
- */
-static SECStatus
-AddNicknameToPermCert(CERTCertificate *cert, char *nickname)
-{
- certDBEntryCert *entry;
- int rv;
-
- PORT_Assert(cert->isperm);
- if ( !cert->isperm ) {
- goto loser;
- }
-
- entry = cert->dbEntry;
- PORT_Assert(entry != NULL);
- if ( entry == NULL ) {
- goto loser;
- }
-
- entry->nickname = PORT_ArenaStrdup(entry->common.arena, nickname);
-
- rv = WriteDBCertEntry(cert->dbhandle, entry);
- if ( rv ) {
- goto loser;
- }
-
- cert->nickname = PORT_ArenaStrdup(cert->arena, nickname);
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/*
- * add a nickname to a cert that is already in the perm database, but doesn't
- * have one yet (it is probably an e-mail cert).
- */
-SECStatus
-CERT_AddPermNickname(CERTCertificate *cert, char *nickname)
-{
- SECStatus rv;
-
- CERT_LockDB(cert->dbhandle);
-
- PORT_Assert(cert->nickname == NULL);
- PORT_Assert(cert->isperm);
- PORT_Assert(cert->subjectList != NULL);
- PORT_Assert(cert->subjectList->entry != NULL);
-
- if ( cert->nickname != NULL ) {
- goto done;
- }
-
- if ( cert->subjectList == NULL ) {
- goto loser;
- }
-
- if ( cert->subjectList->entry == NULL ) {
- goto loser;
- }
-
- if ( cert->subjectList->entry->nickname == NULL ) {
- /* no nickname for subject */
- rv = AddNicknameToSubject(cert, nickname);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- rv = AddNicknameToPermCert(cert, nickname);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- rv = SEC_AddTempNickname(cert->dbhandle, nickname,
- &cert->derSubject);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- } else {
- /* subject already has a nickname */
- rv = AddNicknameToPermCert(cert, cert->subjectList->entry->nickname);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- }
-
-done:
- CERT_UnlockDB(cert->dbhandle);
- return(SECSuccess);
-loser:
- CERT_UnlockDB(cert->dbhandle);
- return(SECFailure);
-}
-
-static certDBEntryCert *
-AddCertToPermDB(CERTCertDBHandle *handle, CERTCertificate *cert,
- char *nickname, CERTCertTrust *trust)
-{
- certDBEntryCert *certEntry = NULL;
- certDBEntryNickname *nicknameEntry = NULL;
- certDBEntrySubject *subjectEntry = NULL;
- int state = 0;
- SECStatus rv;
- PRBool donnentry = PR_FALSE;
-
- if ( nickname ) {
- donnentry = PR_TRUE;
- }
-
- if ( cert->subjectList != NULL ) {
- if ( cert->subjectList->entry != NULL ) {
- if ( cert->subjectList->entry->ncerts > 0 ) {
- /* of other certs with same subject exist, then they already
- * have a nickname, so don't add a new one.
- */
- donnentry = PR_FALSE;
- nickname = cert->subjectList->entry->nickname;
- }
- }
- }
-
- certEntry = NewDBCertEntry(&cert->derCert, nickname, trust, 0);
- if ( certEntry == NULL ) {
- goto loser;
- }
-
- if ( donnentry ) {
- nicknameEntry = NewDBNicknameEntry(nickname, &cert->derSubject, 0);
- if ( nicknameEntry == NULL ) {
- goto loser;
- }
- }
-
- rv = WriteDBCertEntry(handle, certEntry);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- state = 1;
-
- if ( nicknameEntry ) {
- rv = WriteDBNicknameEntry(handle, nicknameEntry);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- }
-
- state = 2;
-
- /* add to or create new subject entry */
- if ( cert->subjectList ) {
- rv = AddPermSubjectNode(cert, nickname);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- } else {
- /* make a new subject entry - this case is only used when updating
- * an old version of the database. This is OK because the oldnickname
- * db format didn't allow multiple certs with the same subject.
- */
- subjectEntry = NewDBSubjectEntry(&cert->derSubject, &cert->certKey,
- &cert->subjectKeyID, nickname,
- NULL, 0);
- if ( subjectEntry == NULL ) {
- goto loser;
- }
- rv = WriteDBSubjectEntry(handle, subjectEntry);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- }
-
- state = 3;
-
- if ( nicknameEntry ) {
- DestroyDBEntry((certDBEntry *)nicknameEntry);
- }
-
- if ( subjectEntry ) {
- DestroyDBEntry((certDBEntry *)subjectEntry);
- }
-
- return(certEntry);
-
-loser:
- /* don't leave partial entry in the database */
- if ( state > 0 ) {
- rv = DeleteDBCertEntry(handle, &cert->certKey);
- }
- if ( ( state > 1 ) && donnentry ) {
- rv = DeleteDBNicknameEntry(handle, nickname);
- }
- if ( state > 2 ) {
- rv = DeleteDBSubjectEntry(handle, &cert->derSubject);
- }
- if ( certEntry ) {
- DestroyDBEntry((certDBEntry *)certEntry);
- }
- if ( nicknameEntry ) {
- DestroyDBEntry((certDBEntry *)nicknameEntry);
- }
- if ( subjectEntry ) {
- DestroyDBEntry((certDBEntry *)subjectEntry);
- }
-
- return(NULL);
-}
-
-/*
- * NOTE - Version 6 DB did not go out to the real world in a release,
- * so we can remove this function in a later release.
- */
-static SECStatus
-UpdateV6DB(CERTCertDBHandle *handle, DB *updatedb)
-{
- int ret;
- DBT key, data;
- unsigned char *buf, *tmpbuf = NULL;
- certDBEntryType type;
- certDBEntryNickname *nnEntry = NULL;
- certDBEntrySubject *subjectEntry = NULL;
- certDBEntrySMime *emailEntry = NULL;
- char *nickname;
- char *emailAddr;
- SECStatus rv;
-
- /*
- * Sequence through the old database and copy all of the entries
- * to the new database. Subject name entries will have the new
- * fields inserted into them (with zero length).
- */
- ret = (* updatedb->seq)(updatedb, &key, &data, R_FIRST);
- if ( ret ) {
- return(SECFailure);
- }
-
- do {
- buf = (unsigned char *)data.data;
-
- if ( data.size >= 3 ) {
- if ( buf[0] == 6 ) { /* version number */
- type = (certDBEntryType)buf[1];
- if ( type == certDBEntryTypeSubject ) {
- /* expando subjecto entrieo */
- tmpbuf = (unsigned char *)PORT_Alloc(data.size + 4);
- if ( tmpbuf ) {
- /* copy header stuff */
- PORT_Memcpy(tmpbuf, buf, SEC_DB_ENTRY_HEADER_LEN + 2);
- /* insert 4 more bytes of zero'd header */
- PORT_Memset(&tmpbuf[SEC_DB_ENTRY_HEADER_LEN + 2],
- 0, 4);
- /* copy rest of the data */
- PORT_Memcpy(&tmpbuf[SEC_DB_ENTRY_HEADER_LEN + 6],
- &buf[SEC_DB_ENTRY_HEADER_LEN + 2],
- data.size - (SEC_DB_ENTRY_HEADER_LEN + 2));
-
- data.data = (void *)tmpbuf;
- data.size += 4;
- buf = tmpbuf;
- }
- } else if ( type == certDBEntryTypeCert ) {
- /* expando certo entrieo */
- tmpbuf = (unsigned char *)PORT_Alloc(data.size + 3);
- if ( tmpbuf ) {
- /* copy header stuff */
- PORT_Memcpy(tmpbuf, buf, SEC_DB_ENTRY_HEADER_LEN);
-
- /* copy trust flage, setting msb's to 0 */
- tmpbuf[SEC_DB_ENTRY_HEADER_LEN] = 0;
- tmpbuf[SEC_DB_ENTRY_HEADER_LEN+1] =
- buf[SEC_DB_ENTRY_HEADER_LEN];
- tmpbuf[SEC_DB_ENTRY_HEADER_LEN+2] = 0;
- tmpbuf[SEC_DB_ENTRY_HEADER_LEN+3] =
- buf[SEC_DB_ENTRY_HEADER_LEN+1];
- tmpbuf[SEC_DB_ENTRY_HEADER_LEN+4] = 0;
- tmpbuf[SEC_DB_ENTRY_HEADER_LEN+5] =
- buf[SEC_DB_ENTRY_HEADER_LEN+2];
-
- /* copy rest of the data */
- PORT_Memcpy(&tmpbuf[SEC_DB_ENTRY_HEADER_LEN + 6],
- &buf[SEC_DB_ENTRY_HEADER_LEN + 3],
- data.size - (SEC_DB_ENTRY_HEADER_LEN + 3));
-
- data.data = (void *)tmpbuf;
- data.size += 3;
- buf = tmpbuf;
- }
-
- }
-
- /* update the record version number */
- buf[0] = CERT_DB_FILE_VERSION;
-
- /* copy to the new database */
- ret = certdb_Put(handle->permCertDB, &key, &data, 0);
- if ( tmpbuf ) {
- PORT_Free(tmpbuf);
- tmpbuf = NULL;
- }
- }
- }
- } while ( (* updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0 );
-
- ret = certdb_Sync(handle->permCertDB, 0);
-
- ret = (* updatedb->seq)(updatedb, &key, &data, R_FIRST);
- if ( ret ) {
- return(SECFailure);
- }
-
- do {
- buf = (unsigned char *)data.data;
-
- if ( data.size >= 3 ) {
- if ( buf[0] == CERT_DB_FILE_VERSION ) { /* version number */
- type = (certDBEntryType)buf[1];
- if ( type == certDBEntryTypeNickname ) {
- nickname = &((char *)key.data)[1];
-
- /* get the matching nickname entry in the new DB */
- nnEntry = ReadDBNicknameEntry(handle, nickname);
- if ( nnEntry == NULL ) {
- goto endloop;
- }
-
- /* find the subject entry pointed to by nickname */
- subjectEntry = ReadDBSubjectEntry(handle,
- &nnEntry->subjectName);
- if ( subjectEntry == NULL ) {
- goto endloop;
- }
-
- subjectEntry->nickname =
- (char *)PORT_ArenaAlloc(subjectEntry->common.arena,
- key.size - 1);
- if ( subjectEntry->nickname ) {
- PORT_Memcpy(subjectEntry->nickname, nickname,
- key.size - 1);
- rv = WriteDBSubjectEntry(handle, subjectEntry);
- }
- } else if ( type == certDBEntryTypeSMimeProfile ) {
- emailAddr = &((char *)key.data)[1];
-
- /* get the matching smime entry in the new DB */
- emailEntry = ReadDBSMimeEntry(handle, emailAddr);
- if ( emailEntry == NULL ) {
- goto endloop;
- }
-
- /* find the subject entry pointed to by nickname */
- subjectEntry = ReadDBSubjectEntry(handle,
- &emailEntry->subjectName);
- if ( subjectEntry == NULL ) {
- goto endloop;
- }
-
- subjectEntry->nickname =
- (char *)PORT_ArenaAlloc(subjectEntry->common.arena,
- key.size - 1);
- if ( subjectEntry->emailAddr ) {
- PORT_Memcpy(subjectEntry->emailAddr, emailAddr,
- key.size - 1);
- rv = WriteDBSubjectEntry(handle, subjectEntry);
- }
- }
-
-endloop:
- if ( subjectEntry ) {
- DestroyDBEntry((certDBEntry *)subjectEntry);
- subjectEntry = NULL;
- }
- if ( nnEntry ) {
- DestroyDBEntry((certDBEntry *)nnEntry);
- nnEntry = NULL;
- }
- if ( emailEntry ) {
- DestroyDBEntry((certDBEntry *)emailEntry);
- emailEntry = NULL;
- }
- }
- }
- } while ( (* updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0 );
-
- ret = certdb_Sync(handle->permCertDB, 0);
-
- (* updatedb->close)(updatedb);
- return(SECSuccess);
-}
-
-
-static SECStatus
-updateV5Callback(CERTCertificate *cert, SECItem *k, void *pdata)
-{
- CERTCertDBHandle *handle;
- certDBEntryCert *entry;
- CERTCertTrust *trust;
-
- handle = (CERTCertDBHandle *)pdata;
- trust = &cert->dbEntry->trust;
-
- /* SSL user certs can be used for email if they have an email addr */
- if ( cert->emailAddr && ( trust->sslFlags & CERTDB_USER ) &&
- ( trust->emailFlags == 0 ) ) {
- trust->emailFlags = CERTDB_USER;
- }
- /* servers didn't set the user flags on the server cert.. */
- if (PORT_Strcmp(cert->dbEntry->nickname,"Server-Cert") == 0) {
- trust->sslFlags |= CERTDB_USER;
- }
-
- entry = AddCertToPermDB(handle, cert, cert->dbEntry->nickname,
- &cert->dbEntry->trust);
- if ( entry ) {
- DestroyDBEntry((certDBEntry *)entry);
- }
-
- return(SECSuccess);
-}
-
-static SECStatus
-UpdateV5DB(CERTCertDBHandle *handle, DB *updatedb)
-{
- CERTCertDBHandle updatehandle;
- SECStatus rv;
-
- updatehandle.permCertDB = updatedb;
- updatehandle.dbMon = PZ_NewMonitor(nssILockCertDB);
-
- rv = SEC_TraversePermCerts(&updatehandle, updateV5Callback,
- (void *)handle);
-
- PZ_DestroyMonitor(updatehandle.dbMon);
-
- (* updatedb->close)(updatedb);
- return(SECSuccess);
-}
-
-static PRBool
-isV4DB(DB *db) {
- DBT key,data;
- int ret;
-
- key.data = "Version";
- key.size = 7;
-
- ret = (*db->get)(db, &key, &data, 0);
- if (ret) {
- return PR_FALSE;
- }
-
- if ((data.size == 1) && (*(unsigned char *)data.data <= 4)) {
- return PR_TRUE;
- }
-
- return PR_FALSE;
-}
-
-static SECStatus
-UpdateV4DB(CERTCertDBHandle *handle, DB *updatedb)
-{
- DBT key, data;
- certDBEntryCert *entry, *entry2;
- SECItem derSubject;
- int ret;
- PRArenaPool *arena = NULL;
- CERTCertificate *cert;
-
- ret = (* updatedb->seq)(updatedb, &key, &data, R_FIRST);
-
- if ( ret ) {
- return(SECFailure);
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- return(SECFailure);
- }
-
- do {
- if ( data.size != 1 ) { /* skip version number */
-
- /* decode the old DB entry */
- entry = (certDBEntryCert *)DecodeV4DBCertEntry((unsigned char*)data.data, data.size);
- derSubject.data = NULL;
-
- if ( entry ) {
- cert = CERT_DecodeDERCertificate(&entry->derCert, PR_TRUE,
- entry->nickname);
-
- if ( cert != NULL ) {
- /* add to new database */
- entry2 = AddCertToPermDB(handle, cert, entry->nickname,
- &entry->trust);
-
- CERT_DestroyCertificate(cert);
- if ( entry2 ) {
- DestroyDBEntry((certDBEntry *)entry2);
- }
- }
- DestroyDBEntry((certDBEntry *)entry);
- }
- }
- } while ( (* updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0 );
-
- PORT_FreeArena(arena, PR_FALSE);
- (* updatedb->close)(updatedb);
- return(SECSuccess);
-}
-
-/*
- * return true if a database key conflict exists
- */
-PRBool
-SEC_CertDBKeyConflict(SECItem *derCert, CERTCertDBHandle *handle)
-{
- SECStatus rv;
- DBT tmpdata;
- DBT namekey;
- int ret;
- SECItem keyitem;
- PRArenaPool *arena = NULL;
- SECItem derKey;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- /* get the db key of the cert */
- rv = CERT_KeyFromDERCert(arena, derCert, &derKey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = EncodeDBCertKey(&derKey, arena, &keyitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- namekey.data = keyitem.data;
- namekey.size = keyitem.len;
-
- /* lookup in the temporary database */
- ret = certdb_Get(handle->tempCertDB, &namekey, &tmpdata, 0);
-
- if ( ret == 0 ) { /* found in temp database */
- goto loser;
- } else { /* not found in temporary database */
- ret = certdb_Get(handle->permCertDB, &namekey, &tmpdata, 0);
- if ( ret == 0 ) {
- goto loser;
- }
- }
-
- PORT_FreeArena(arena, PR_FALSE);
-
- return(PR_FALSE);
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(PR_TRUE);
-}
-
-#ifdef NOTDEF
-/*
- * return true if a subject name conflict exists
- * NOTE: caller must have already made sure that this exact cert
- * doesn't exist in the DB
- */
-PRBool
-SEC_CertSubjectConflict(SECItem *derCert, CERTCertDBHandle *handle)
-{
- SECStatus rv;
- DBT tmpdata;
- DBT namekey;
- int ret;
- SECItem keyitem;
- PRArenaPool *arena = NULL;
- SECItem derName;
-
- derName.data = NULL;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- /* get the subject name of the cert */
- rv = CERT_NameFromDERCert(derCert, &derName);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = EncodeDBSubjectKey(&derName, arena, &keyitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- namekey.data = keyitem.data;
- namekey.size = keyitem.len;
-
- /* lookup in the temporary database */
- ret = certdb_Get(handle->tempCertDB, &namekey, &tmpdata, 0);
-
- if ( ret == 0 ) { /* found in temp database */
- return(PR_TRUE);
- } else { /* not found in temporary database */
- ret = certdb_Get(handle->permCertDB, &namekey, &tmpdata, 0);
- if ( ret == 0 ) {
- return(PR_TRUE);
- }
- }
-
- PORT_FreeArena(arena, PR_FALSE);
- PORT_Free(derName.data);
-
- return(PR_FALSE);
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- if ( derName.data ) {
- PORT_Free(derName.data);
- }
-
- return(PR_TRUE);
-}
-#endif
-
-/*
- * return true if a nickname conflict exists
- * NOTE: caller must have already made sure that this exact cert
- * doesn't exist in the DB
- */
-PRBool
-SEC_CertNicknameConflict(char *nickname, SECItem *derSubject,
- CERTCertDBHandle *handle)
-{
- PRBool rv;
- certDBEntryNickname *entry;
-
- if ( nickname == NULL ) {
- return(PR_FALSE);
- }
-
- entry = ReadDBNicknameEntry(handle, nickname);
-
- if ( entry == NULL ) {
- /* no entry for this nickname, so no conflict */
- return(PR_FALSE);
- }
-
- rv = PR_TRUE;
- if ( SECITEM_CompareItem(derSubject, &entry->subjectName) == SECEqual ) {
- /* if subject names are the same, then no conflict */
- rv = PR_FALSE;
- }
-
- DestroyDBEntry((certDBEntry *)entry);
- return(rv);
-}
-
-/*
- * Open the certificate database and index databases. Create them if
- * they are not there or bad.
- */
-SECStatus
-SEC_OpenPermCertDB(CERTCertDBHandle *handle, PRBool readOnly,
- CERTDBNameFunc namecb, void *cbarg)
-{
- SECStatus rv;
- int openflags;
- certDBEntryVersion *versionEntry = NULL;
- DB *updatedb = NULL;
- char *tmpname;
- char *certdbname;
- PRBool updated = PR_FALSE;
- PRBool forceUpdate = PR_FALSE;
-
- certdbname = (* namecb)(cbarg, CERT_DB_FILE_VERSION);
- if ( certdbname == NULL ) {
- return(SECFailure);
- }
-
- if ( readOnly ) {
- openflags = O_RDONLY;
- } else {
- openflags = O_RDWR;
- }
-
- /*
- * first open the permanent file based database.
- */
- handle->permCertDB = dbopen( certdbname, openflags, 0600, DB_HASH, 0 );
-
- /* check for correct version number */
- if ( handle->permCertDB ) {
- versionEntry = ReadDBVersionEntry(handle);
-
- if ( versionEntry == NULL ) {
- /* no version number */
- certdb_Close(handle->permCertDB);
- handle->permCertDB = 0;
- } else if ( versionEntry->common.version != CERT_DB_FILE_VERSION ) {
- /* wrong version number, can't update in place */
- DestroyDBEntry((certDBEntry *)versionEntry);
- PORT_Free(certdbname);
- return(SECFailure);
- } else {
- DestroyDBEntry((certDBEntry *)versionEntry);
- versionEntry = NULL;
- }
- }
-
-
- /* if first open fails, try to create a new DB */
- if ( handle->permCertDB == NULL ) {
-
- /* don't create if readonly */
- if ( readOnly ) {
- goto loser;
- }
-
- handle->permCertDB = dbopen(certdbname,
- O_RDWR | O_CREAT | O_TRUNC,
- 0600, DB_HASH, 0);
-
- /* if create fails then we lose */
- if ( handle->permCertDB == 0 ) {
- goto loser;
- }
-
- versionEntry = NewDBVersionEntry(0);
- if ( versionEntry == NULL ) {
- goto loser;
- }
-
- rv = WriteDBVersionEntry(handle, versionEntry);
-
- DestroyDBEntry((certDBEntry *)versionEntry);
-
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* 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 );
- PORT_Free(tmpname);
- if ( updatedb ) {
- rv = UpdateV6DB(handle, updatedb);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- updated = PR_TRUE;
- } 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 );
- PORT_Free(tmpname);
- if ( updatedb ) {
- rv = UpdateV5DB(handle, updatedb);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- updated = PR_TRUE;
- } else { /* no v5 db, so try v4 db */
- /* try to upgrade v4 db */
- tmpname = (* namecb)(cbarg, 4); /* get v4 db name */
- if ( tmpname ) {
- updatedb = dbopen( tmpname, O_RDONLY, 0600,
- DB_HASH, 0 );
- PORT_Free(tmpname);
- if ( updatedb ) {
- /* NES has v5 db's with v4 db names! */
- if (isV4DB(updatedb)) {
- rv = UpdateV4DB(handle, updatedb);
- } else {
- rv = UpdateV5DB(handle, updatedb);
- }
- if ( rv != SECSuccess ) {
- goto loser;
- }
- forceUpdate = PR_TRUE;
- updated = PR_TRUE;
- }
- }
- }
- }
- }
- }
-
- /* initialize the database with our well known certificates
- * or in the case of update, just fall down to CERT_AddNewCerts()
- * below.
- * Note - if we are updating a really old database, then we try
- * to push all of the certs into it.
- */
- if ( ( !updated ) || forceUpdate ) {
- rv = CERT_InitCertDB(handle);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- }
- }
-
- rv = CERT_AddNewCerts(handle);
-
- PORT_Free(certdbname);
-
- return (SECSuccess);
-
-loser:
-
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
-
- if ( handle->permCertDB ) {
- certdb_Close(handle->permCertDB);
- handle->permCertDB = 0;
- }
-
- PORT_Free(certdbname);
-
- return(SECFailure);
-}
-
-/*
- * delete all DB records associated with a particular certificate
- */
-static SECStatus
-DeletePermCert(CERTCertificate *cert)
-{
- SECStatus rv;
- SECStatus ret;
-
- ret = SECSuccess;
-
- rv = DeleteDBCertEntry(cert->dbhandle, &cert->certKey);
- if ( rv != SECSuccess ) {
- ret = SECFailure;
- }
-
- if ( cert->nickname ) {
- rv = DeleteDBNicknameEntry(cert->dbhandle, cert->nickname);
- if ( rv != SECSuccess ) {
- ret = SECFailure;
- }
- }
-
- rv = RemovePermSubjectNode(cert);
-
- return(ret);
-}
-
-/*
- * Delete a certificate from the permanent database.
- */
-SECStatus
-SEC_DeletePermCertificate(CERTCertificate *cert)
-{
- SECStatus rv;
-
- if ( !cert->isperm ) {
- return(SECSuccess);
- }
- CERT_LockDB(cert->dbhandle);
- /* delete the records from the permanent database */
- rv = DeletePermCert(cert);
-
- /* no longer permanent */
- cert->isperm = PR_FALSE;
-
- /* get rid of dbcert and stuff pointing to it */
- DestroyDBEntry((certDBEntry *)cert->dbEntry);
- cert->dbEntry = NULL;
- cert->trust = NULL;
-
- /* delete it from the temporary database too. It will remain in
- * memory until all references go away.
- */
- if (cert->slot) {
- /* If it's owned by a PKCS #11 slot, don't deleted if from the temp DB just
- * yet... rv inherited from DeletePermCert (as if anyone checks the return
- * code from this function anyway. */
- CERT_DestroyCertificateNoLocking(cert);
- rv = SECSuccess;
- } else {
- rv = CERT_DeleteTempCertificate(cert);
- }
-
- CERT_UnlockDB(cert->dbhandle);
- return(rv);
-}
-
-/*
- * Lookup a certificate in the databases.
- */
-certDBEntryCert *
-SEC_FindPermCertByKey(CERTCertDBHandle *handle, SECItem *key)
-{
- return(ReadDBCertEntry(handle, key));
-}
-
-/*
- * Lookup a certificate in the database by name
- */
-certDBEntryCert *
-SEC_FindPermCertByName(CERTCertDBHandle *handle, SECItem *derSubject)
-{
- certDBEntrySubject *subjectEntry;
- certDBEntryCert *certEntry;
-
- subjectEntry = ReadDBSubjectEntry(handle, derSubject);
-
- if ( subjectEntry == NULL ) {
- goto loser;
- }
-
- certEntry = ReadDBCertEntry(handle, &subjectEntry->certKeys[0]);
- DestroyDBEntry((certDBEntry *)subjectEntry);
-
- return(certEntry);
-
-loser:
- return(NULL);
-}
-
-/*
- * Lookup a certificate in the database by nickname
- */
-certDBEntryCert *
-SEC_FindPermCertByNickname(CERTCertDBHandle *handle, char *nickname)
-{
- certDBEntryNickname *nicknameEntry;
- certDBEntryCert *certEntry;
-
- nicknameEntry = ReadDBNicknameEntry(handle, nickname);
-
- if ( nicknameEntry == NULL ) {
- goto loser;
- }
-
- certEntry = SEC_FindPermCertByName(handle, &nicknameEntry->subjectName);
- DestroyDBEntry((certDBEntry *)nicknameEntry);
-
- return(certEntry);
-
-loser:
- return(NULL);
-}
-
-/*
- * Traverse all of the entries in the database of a particular type
- * call the given function for each one.
- */
-SECStatus
-SEC_TraverseDBEntries(CERTCertDBHandle *handle,
- certDBEntryType type,
- SECStatus (* callback)(SECItem *data, SECItem *key,
- certDBEntryType type, void *pdata),
- void *udata )
-{
- DBT data;
- DBT key;
- SECStatus rv;
- int ret;
- SECItem dataitem;
- SECItem keyitem;
- unsigned char *buf;
- unsigned char *keybuf;
-
- ret = certdb_Seq(handle->permCertDB, &key, &data, R_FIRST);
-
- if ( ret ) {
- return(SECFailure);
- }
-
- do {
- buf = (unsigned char *)data.data;
-
- if ( buf[1] == (unsigned char)type ) {
- dataitem.len = data.size;
- dataitem.data = buf;
- dataitem.type = siBuffer;
- keyitem.len = key.size - SEC_DB_KEY_HEADER_LEN;
- keybuf = (unsigned char *)key.data;
- keyitem.data = &keybuf[SEC_DB_KEY_HEADER_LEN];
- keyitem.type = siBuffer;
-
- rv = (* callback)(&dataitem, &keyitem, type, udata);
- if ( rv != SECSuccess ) {
- return(rv);
- }
- }
- } while ( certdb_Seq(handle->permCertDB, &key, &data, R_NEXT) == 0 );
-
- return(SECSuccess);
-}
-
-typedef struct {
- PermCertCallback certfunc;
- CERTCertDBHandle *handle;
- void *data;
-} PermCertCallbackState;
-
-/*
- * traversal callback to decode certs and call callers callback
- */
-static SECStatus
-certcallback(SECItem *dbdata, SECItem *dbkey, certDBEntryType type, void *data)
-{
- PermCertCallbackState *mystate;
- SECStatus rv;
- certDBEntryCert entry;
- SECItem entryitem;
- CERTCertificate *cert;
- PRArenaPool *arena = NULL;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- mystate = (PermCertCallbackState *)data;
- entry.common.version = (unsigned int)dbdata->data[0];
- entry.common.type = (certDBEntryType)dbdata->data[1];
- entry.common.flags = (unsigned int)dbdata->data[2];
- entry.common.arena = arena;
-
- entryitem.len = dbdata->len - SEC_DB_ENTRY_HEADER_LEN;
- entryitem.data = &dbdata->data[SEC_DB_ENTRY_HEADER_LEN];
-
- rv = DecodeDBCertEntry(&entry, &entryitem);
- if (rv != SECSuccess ) {
- goto loser;
- }
- entry.derCert.type = siBuffer;
-
- cert = CERT_DecodeDERCertificate(&entry.derCert, PR_FALSE,
- entry.nickname);
- cert->dbEntry = &entry;
- cert->trust = &entry.trust;
- cert->dbhandle = mystate->handle;
-
- if ( CERT_IsCACert(cert, NULL) ||
- (( cert->trust->sslFlags & CERTDB_VALID_CA ) ||
- ( cert->trust->emailFlags & CERTDB_VALID_CA ) ||
- ( cert->trust->objectSigningFlags & CERTDB_VALID_CA)) ) {
- cert->nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER;
- }
-
- rv = (* mystate->certfunc)(cert, dbkey, mystate->data);
-
- /* arena destroyed by SEC_DestroyCert */
- CERT_DestroyCertificateNoLocking(cert);
-
- return(rv);
-
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- return(SECFailure);
-}
-
-/*
- * Traverse all of the certificates in the permanent database and
- * call the given function for each one; expect the caller to have lock.
- */
-static SECStatus
-TraversePermCertsNoLocking(CERTCertDBHandle *handle,
- SECStatus (* certfunc)(CERTCertificate *cert,
- SECItem *k,
- void *pdata),
- void *udata )
-{
- SECStatus rv;
- PermCertCallbackState mystate;
-
- mystate.certfunc = certfunc;
- mystate.handle = handle;
- mystate.data = udata;
- rv = SEC_TraverseDBEntries(handle, certDBEntryTypeCert, certcallback,
- (void *)&mystate);
-
- return(rv);
-}
-
-/*
- * Traverse all of the certificates in the permanent database and
- * call the given function for each one.
- */
-SECStatus
-SEC_TraversePermCerts(CERTCertDBHandle *handle,
- SECStatus (* certfunc)(CERTCertificate *cert, SECItem *k,
- void *pdata),
- void *udata )
-{
- SECStatus rv;
-
- CERT_LockDB(handle);
- rv = TraversePermCertsNoLocking(handle, certfunc, udata);
- CERT_UnlockDB(handle);
-
- return(rv);
-}
-
-
-
-/*
- * Close the database
- */
-void
-__CERT_ClosePermCertDB(CERTCertDBHandle *handle)
-{
- if ( handle ) {
- if ( handle->permCertDB ) {
- if ( handle->statusConfig ) {
- PORT_Assert(handle->statusConfig->statusDestroy != NULL);
- (void) (* handle->statusConfig->statusDestroy)(handle->statusConfig);
- handle->statusConfig = NULL; /* Destroy frees the structure */
- PORT_Assert(handle->statusConfig == NULL);
- }
- certdb_Close( handle->permCertDB );
- handle->permCertDB = 0;
- }
- }
- return;
-}
-
-void
-CERT_ClosePermCertDB(CERTCertDBHandle *handle)
-{
- __CERT_ClosePermCertDB(handle);
-}
-
-/*
- * Get the trust attributes from a certificate
- */
-SECStatus
-CERT_GetCertTrust(CERTCertificate *cert, CERTCertTrust *trust)
-{
- SECStatus rv;
-
- CERT_LockCertTrust(cert);
-
- if ( cert->trust == NULL ) {
- rv = SECFailure;
- } else {
- *trust = *cert->trust;
- rv = SECSuccess;
- }
-
- CERT_UnlockCertTrust(cert);
- return(rv);
-}
-
-static char *
-cert_parseNickname(char *nickname)
-{
- char *cp;
-
- for (cp=nickname; *cp && *cp != ':'; cp++);
-
- if (*cp == ':') return cp+1;
- return nickname;
-}
-
-/*
- * Change the trust attributes of a certificate and make them permanent
- * in the database.
- */
-SECStatus
-CERT_ChangeCertTrust(CERTCertDBHandle *handle, CERTCertificate *cert,
- CERTCertTrust *trust)
-{
- certDBEntryCert *entry;
- int rv;
- SECStatus ret;
-
- CERT_LockDB(handle);
- CERT_LockCertTrust(cert);
- /* only set the trust on permanent certs */
- if ( cert->trust == NULL ) {
- ret = SECFailure;
- goto done;
- }
-
- *cert->trust = *trust;
- if ( cert->dbEntry == NULL ) {
- ret = SECSuccess; /* not in permanent database */
- if ((cert->slot) && PK11_IsReadOnly(cert->slot)) {
- char *nickname = cert_parseNickname(cert->nickname);
- ret = CERT_AddTempCertToPerm(cert, nickname, trust);
- }
- goto done;
- }
-
- entry = cert->dbEntry;
- entry->trust = *trust;
-
- rv = WriteDBCertEntry(handle, entry);
- if ( rv ) {
- ret = SECFailure;
- goto done;
- }
-
- ret = SECSuccess;
-
-done:
- CERT_UnlockCertTrust(cert);
- CERT_UnlockDB(handle);
- return(ret);
-}
-
-
-SECStatus
-CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
- CERTCertTrust *trust)
-{
- char *oldnn;
- certDBEntryCert *entry;
- SECStatus rv;
- PRBool conflict;
- SECStatus ret;
-
- PORT_Assert(cert->dbhandle);
-
- CERT_LockDB(cert->dbhandle);
-
- PORT_Assert(cert->istemp);
- PORT_Assert(!cert->isperm);
- PORT_Assert(!cert->dbEntry);
-
- /* don't add a conflicting nickname */
- conflict = SEC_CertNicknameConflict(nickname, &cert->derSubject,
- cert->dbhandle);
- if ( conflict ) {
- ret = SECFailure;
- goto done;
- }
-
- /* save old nickname so that we can delete it */
- oldnn = cert->nickname;
-
- entry = AddCertToPermDB(cert->dbhandle, cert, nickname, trust);
-
- if ( entry == NULL ) {
- ret = SECFailure;
- goto done;
- }
-
- cert->nickname = (entry->nickname) ? PORT_ArenaStrdup(cert->arena,entry->nickname) : NULL;
- cert->trust = &entry->trust;
- cert->isperm = PR_TRUE;
- cert->dbEntry = entry;
-
- if ( nickname && oldnn && ( PORT_Strcmp(nickname, oldnn) != 0 ) ) {
- /* only delete the old one if they are not the same */
- /* delete old nickname from temp database */
- rv = SEC_DeleteTempNickname(cert->dbhandle, oldnn);
- if ( rv != SECSuccess ) {
- /* do we care?? */
- }
- }
- /* add new nickname to temp database */
- if ( cert->nickname ) {
- rv = SEC_AddTempNickname(cert->dbhandle, cert->nickname,
- &cert->derSubject);
- if ( rv != SECSuccess ) {
- ret = SECFailure;
- goto done;
- }
- }
-
- ret = SECSuccess;
-done:
- CERT_UnlockDB(cert->dbhandle);
- return(ret);
-}
-
-/*
- * Open the certificate database and index databases. Create them if
- * they are not there or bad.
- */
-SECStatus
-CERT_OpenCertDB(CERTCertDBHandle *handle, PRBool readOnly,
- CERTDBNameFunc namecb, void *cbarg)
-{
- int rv;
-#define DBM_DEFAULT 0
- static const HASHINFO hashInfo = {
- DBM_DEFAULT, /* bucket size */
- DBM_DEFAULT, /* fill factor */
- DBM_DEFAULT, /* number of elements */
- 256 * 1024, /* bytes to cache */
- DBM_DEFAULT, /* hash function */
- DBM_DEFAULT /* byte order */
- };
-
- certdb_InitDBLock();
-
- handle->dbMon = PZ_NewMonitor(nssILockCertDB);
- PORT_Assert(handle->dbMon != NULL);
-
- handle->spkDigestInfo = NULL;
- handle->statusConfig = NULL;
-
- /*
- * Open the memory resident decoded cert database.
- */
- handle->tempCertDB = dbopen(0, O_RDWR | O_CREAT, 0600, DB_HASH, &hashInfo);
- if ( !handle->tempCertDB ) {
- goto loser;
- }
-
- rv = SEC_OpenPermCertDB(handle, readOnly, namecb, cbarg);
- if ( rv ) {
- goto loser;
- }
-
- return (SECSuccess);
-
-loser:
-
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
-
- if ( handle->tempCertDB ) {
- certdb_Close(handle->tempCertDB);
- handle->tempCertDB = 0;
- }
-
- return(SECFailure);
-}
-
-static char *
-certDBFilenameCallback(void *arg, int dbVersion)
-{
- return(PORT_Strdup((char *)arg));
-}
-
-SECStatus
-CERT_OpenCertDBFilename(CERTCertDBHandle *handle, char *certdbname,
- PRBool readOnly)
-{
- return(CERT_OpenCertDB(handle, readOnly, certDBFilenameCallback,
- (void *)certdbname));
-}
-
-/*
- * Add a nickname to the temp database
- */
-SECStatus
-SEC_AddTempNickname(CERTCertDBHandle *handle, char *nickname,
- SECItem *subjectName)
-{
- DBT namekey;
- int ret;
- SECItem nameitem;
- SECStatus rv;
- DBT keydata;
- PRArenaPool *arena = NULL;
- SECItem tmpitem;
-
- PORT_Assert(nickname != NULL);
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- rv = EncodeDBNicknameKey(nickname, arena, &nameitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- namekey.data = nameitem.data;
- namekey.size = nameitem.len;
-
- /* see if an entry already exists */
- ret = certdb_Get(handle->tempCertDB, &namekey, &keydata, 0);
-
- if ( ret == 0 ) {
- /* found in temp database */
- tmpitem.data = (unsigned char*)keydata.data;
- tmpitem.len = keydata.size;
-
- if ( SECITEM_CompareItem(subjectName, &tmpitem) == SECEqual ) {
- /* same subject name */
- goto done;
- } else {
- /* different subject name is an error */
- goto loser;
- }
- }
-
- keydata.data = subjectName->data;
- keydata.size = subjectName->len;
-
- /* put into temp byname index */
- ret = certdb_Put(handle->tempCertDB, &namekey, &keydata, R_NOOVERWRITE);
-
- if ( ret ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
-done:
- PORT_FreeArena(arena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- return(SECFailure);
-}
-
-SECStatus
-SEC_DeleteTempNickname(CERTCertDBHandle *handle, char *nickname)
-{
- DBT namekey;
- SECStatus rv;
- PRArenaPool *arena = NULL;
- SECItem nameitem;
- int ret;
-
- PORT_Assert(nickname != NULL);
- if ( nickname == NULL ) {
- return(SECSuccess);
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* format a database key based on the nickname */
- if ( nickname ) {
- rv = EncodeDBNicknameKey(nickname, arena, &nameitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- namekey.data = nameitem.data;
- namekey.size = nameitem.len;
-
- ret = certdb_Del(handle->tempCertDB, &namekey, 0);
- if ( ret ) {
- goto loser;
- }
- }
-
- PORT_FreeArena(arena, PR_FALSE);
-
- return(SECSuccess);
-
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- return(SECFailure);
-}
-
-/*
- * Decode a certificate and enter it into the temporary certificate database.
- * Deal with nicknames correctly
- *
- * nickname is only used if isperm == PR_TRUE
- *
- * This is the private entry point, and locking is optional
- */
-static CERTCertificate *
-NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, char *nickname,
- PRBool isperm, PRBool copyDER, PRBool lockdb)
-
-{
- DBT key;
- DBT data;
- int status;
- CERTCertificate *cert = NULL;
- PRBool promoteError = PR_TRUE;
- PRArenaPool *arena = NULL;
- SECItem keyitem;
- SECStatus rv;
-
- if ( lockdb ) {
- CERT_LockDB(handle);
- }
-
- if ( isperm == PR_FALSE ) {
- cert = CERT_FindCertByDERCertNoLocking(handle, derCert);
- if ( cert ) {
- goto winner;
- }
-
- nickname = NULL;
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- cert = CERT_DecodeDERCertificate(derCert, copyDER, nickname );
-
- if ( cert == NULL ) {
- /* We want to save the decoding error here */
- promoteError = PR_FALSE;
- goto loser;
- }
-
- cert->dbhandle = handle;
-
- /* only save pointer to cert in database */
- data.data = &cert;
- data.size = sizeof(cert);
-
- /* if this is a perm cert, then it is already in the subject db */
- if ( isperm == PR_FALSE ) {
- /* enter into the subject index */
- rv = AddTempCertToSubjectList(cert);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- /*
- * Since it's not a perm cert, add it to the key hash lookup; if it
- * is permanent it will either already be there or will get put there
- * later along with the rest of the perm certs. A failure of the
- * addition does not seem to warrant failing this whole function,
- * so we intentionally ignore the returned status.
- */
- (void) AddCertToSPKDigestTable(handle, cert);
- } else {
- cert->subjectList = FindSubjectList(cert->dbhandle, &cert->derSubject,
- PR_FALSE);
- }
-
- rv = EncodeDBCertKey(&cert->certKey, arena, &keyitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- key.data = keyitem.data;
- key.size = keyitem.len;
-
- /* enter into main db */
- status = certdb_Put(handle->tempCertDB, &key, &data, R_NOOVERWRITE);
- if ( status ) {
- goto loser;
- }
-
- if ( cert->nickname ) {
- status = SEC_AddTempNickname(handle, cert->nickname,
- &cert->derSubject);
- if ( status ) {
- promoteError = PR_FALSE;
- goto loser;
- }
- }
-
- cert->isperm = isperm;
- cert->istemp = PR_TRUE;
-
- PORT_FreeArena(arena, PR_FALSE);
-
-winner:
-
- if ( lockdb ) {
- CERT_UnlockDB(handle);
- }
-
- return(cert);
-
-loser:
- if ( cert ) {
- CERT_DestroyCertificateNoLocking(cert);
- }
-
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- if ( promoteError ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- }
-
- if ( lockdb ) {
- CERT_UnlockDB(handle);
- }
-
- return(0);
-}
-
-/*
- * Decode a certificate and enter it into the temporary certificate database.
- * Deal with nicknames correctly
- *
- * nickname is only used if isperm == PR_TRUE
- *
- * This is the public entry point and does locking.
- */
-CERTCertificate *
-__CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
- char *nickname, PRBool isperm, PRBool copyDER)
-{
- return( NewTempCertificate(handle, derCert, nickname, isperm, copyDER,
- PR_TRUE) );
-}
-
-CERTCertificate *
-CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
- char *nickname, PRBool isperm, PRBool copyDER)
-{
- return( __CERT_NewTempCertificate(handle, derCert, nickname,
- isperm, copyDER) );
-}
-
-/*
- * Decode a permanent certificate and enter it into the temporary certificate
- * database.
- */
-static CERTCertificate *
-SEC_AddPermCertToTemp(CERTCertDBHandle *handle, certDBEntryCert *entry)
-{
- CERTCertificate *cert;
-
- /* we already hold the lock */
- cert = NewTempCertificate(handle, &entry->derCert, entry->nickname,
- PR_TRUE, PR_TRUE, PR_FALSE);
- if ( !cert ) {
- return(0);
- }
-
- cert->dbEntry = entry;
-
- cert->trust = &entry->trust;
-
- return(cert);
-}
-
-SECStatus
-CERT_DeleteTempCertificate(CERTCertificate *cert)
-{
- SECStatus rv;
- DBT nameKey;
- CERTCertDBHandle *handle;
- SECItem keyitem;
- PRArenaPool *arena;
- int ret;
-
- handle = cert->dbhandle;
-
- if ( !cert->istemp ) {
- return(SECSuccess);
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- if (cert->slot) {
- PK11_FreeSlot(cert->slot);
- cert->slot = NULL;
- cert->pkcs11ID = CK_INVALID_KEY;
- }
-
- /* delete from subject list (also takes care of nickname) */
- rv = RemoveTempCertFromSubjectList(cert);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- if ( !cert->isperm ) {
- /*
- * Remove the cert from the subject public key digest table,
- * though we do not care if the removal fails (perhaps meaning
- * the cert wasn't even there).
- */
- (void) RemoveCertFromSPKDigestTable(handle, cert);
- }
-
- rv = EncodeDBCertKey(&cert->certKey, arena, &keyitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- nameKey.data = keyitem.data;
- nameKey.size = keyitem.len;
- /* delete the cert */
- ret = certdb_Del(handle->tempCertDB, &nameKey, 0);
- if ( ret ) {
- goto loser;
- }
-
- cert->istemp = PR_FALSE;
-
- PORT_FreeArena(arena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(SECFailure);
-}
-
-/*
- * Lookup a certificate in the databases.
- */
-static CERTCertificate *
-FindCertByKey(CERTCertDBHandle *handle, SECItem *certKey, PRBool lockdb)
-{
- DBT tmpdata;
- int ret;
- SECItem keyitem;
- DBT key;
- SECStatus rv;
- CERTCertificate *cert = NULL;
- PRArenaPool *arena = NULL;
- certDBEntryCert *entry;
- PRBool locked = PR_FALSE;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- rv = EncodeDBCertKey(certKey, arena, &keyitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- key.data = keyitem.data;
- key.size = keyitem.len;
-
- if ( lockdb ) {
- locked = PR_TRUE;
- CERT_LockDB(handle);
- }
-
- /* lookup in the temporary database */
- ret = certdb_Get( handle->tempCertDB, &key, &tmpdata, 0 );
-
- /* error accessing the database */
- if ( ret < 0 ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- if ( ret == 0 ) { /* found in temp database */
- if ( tmpdata.size != sizeof(CERTCertificate *) ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- PORT_Memcpy(&cert, tmpdata.data, tmpdata.size);
- CERT_LockCertRefCount(cert);
- cert->referenceCount++;
- CERT_UnlockCertRefCount(cert);
- }
- if ( ret != 0 ) {
- /* not found in temporary database */
-
- /* find in perm database */
- entry = SEC_FindPermCertByKey(handle, certKey);
-
- if ( entry == NULL ) {
- goto loser;
- }
-
- cert = SEC_AddPermCertToTemp(handle, entry);
- }
-
-loser:
- if ( locked ) {
- CERT_UnlockDB(handle);
- }
-
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(cert);
-}
-
-/*
- * Lookup a certificate in the databases, with locking
- */
-CERTCertificate *
-CERT_FindCertByKey(CERTCertDBHandle *handle, SECItem *certKey)
-{
- return(FindCertByKey(handle, certKey, PR_TRUE));
-}
-
-/*
- * Lookup a certificate in the databases without locking
- */
-CERTCertificate *
-CERT_FindCertByKeyNoLocking(CERTCertDBHandle *handle, SECItem *certKey)
-{
- return(FindCertByKey(handle, certKey, PR_FALSE));
-}
-
-/*
- * Generate a key from an issuerAndSerialNumber, and find the
- * associated cert in the database.
- */
-CERTCertificate *
-CERT_FindCertByIssuerAndSN(CERTCertDBHandle *handle, CERTIssuerAndSN *issuerAndSN)
-{
- SECItem certKey;
- CERTCertificate *cert;
-
- certKey.len = issuerAndSN->serialNumber.len + issuerAndSN->derIssuer.len;
- certKey.data = (unsigned char*)PORT_Alloc(certKey.len);
-
- if ( certKey.data == NULL ) {
- return(0);
- }
-
- /* copy the serialNumber */
- PORT_Memcpy(certKey.data, issuerAndSN->serialNumber.data,
- issuerAndSN->serialNumber.len);
-
- /* copy the issuer */
- PORT_Memcpy( &certKey.data[issuerAndSN->serialNumber.len],
- issuerAndSN->derIssuer.data, issuerAndSN->derIssuer.len);
-
- cert = CERT_FindCertByKey(handle, &certKey);
-
- PORT_Free(certKey.data);
-
- return(cert);
-}
-
-/*
- * Lookup a certificate in the database by name
- */
-CERTCertificate *
-CERT_FindCertByName(CERTCertDBHandle *handle, SECItem *name)
-{
- CERTCertificate *cert = NULL;
- CERTSubjectList *subjectList;
-
- CERT_LockDB(handle);
-
- subjectList = FindSubjectList(handle, name, PR_FALSE);
-
- if ( subjectList ) {
- PORT_Assert(subjectList->head);
- cert = CERT_FindCertByKeyNoLocking(handle,
- &subjectList->head->certKey);
- }
-
- CERT_UnlockDB(handle);
-
- return(cert);
-}
-
-/*
- * Lookup a certificate in the database by name and key ID
- */
-CERTCertificate *
-CERT_FindCertByKeyID(CERTCertDBHandle *handle, SECItem *name, SECItem *keyID)
-{
- CERTCertificate *cert = NULL;
- CERTSubjectList *subjectList;
- CERTSubjectNode *node;
-
- CERT_LockDB(handle);
-
- /* find the list of certs for the given subject */
- subjectList = FindSubjectList(handle, name, PR_FALSE);
-
- if ( subjectList ) {
- PORT_Assert(subjectList->head);
- node = subjectList->head;
-
- /* walk through the certs until we find one with a matching key ID */
- while ( node ) {
- if ( SECITEM_CompareItem(keyID, &node->keyID) == SECEqual ) {
- cert = CERT_FindCertByKeyNoLocking(handle, &node->certKey);
- break;
- }
- node = node->next;
- }
- }
-
- CERT_UnlockDB(handle);
-
- return(cert);
-}
-
-/*
- * look up a cert by its nickname string
- */
-CERTCertificate *
-CERT_FindCertByNickname(CERTCertDBHandle *handle, char *nickname)
-{
- DBT tmpdata;
- DBT namekey;
- CERTCertificate *cert;
- SECStatus rv;
- int ret;
- SECItem keyitem;
- PRArenaPool *arena = NULL;
- certDBEntryCert *entry;
-
- PORT_Assert(nickname != NULL);
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- rv = EncodeDBNicknameKey(nickname, arena, &keyitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- namekey.data = keyitem.data;
- namekey.size = keyitem.len;
-
- /* lookup in the temporary database */
- ret = certdb_Get(handle->tempCertDB, &namekey, &tmpdata, 0);
-
- /* error accessing the database */
- if ( ret < 0 ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- if ( ret == 0 ) { /* found in temp database */
- SECItem nameitem;
-
- nameitem.len = tmpdata.size;
- nameitem.data = (unsigned char *)PORT_Alloc(tmpdata.size);
- if ( nameitem.data == NULL ) {
- goto loser;
- }
- PORT_Memcpy(nameitem.data, tmpdata.data, nameitem.len);
- cert = CERT_FindCertByName(handle, &nameitem);
- PORT_Free(nameitem.data);
- } else { /* not found in temporary database */
-
- CERT_LockDB(handle);
-
- entry = SEC_FindPermCertByNickname(handle, nickname);
-
- if ( entry == NULL ) {
- CERT_UnlockDB(handle);
- goto loser;
- }
-
- cert = SEC_AddPermCertToTemp(handle, entry);
- CERT_UnlockDB(handle);
- }
-
- PORT_FreeArena(arena, PR_FALSE);
-
- return(cert);
-
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(0);
-}
-
-/*
- * look for the given DER certificate in the database
- */
-CERTCertificate *
-CERT_FindCertByDERCert(CERTCertDBHandle *handle, SECItem *derCert)
-{
- PRArenaPool *arena;
- SECItem certKey;
- SECStatus rv;
- CERTCertificate *cert = NULL;
-
- /* create a scratch arena */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- return(NULL);
- }
-
- /* extract the database key from the cert */
- rv = CERT_KeyFromDERCert(arena, derCert, &certKey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* find the certificate */
- cert = CERT_FindCertByKey(handle, &certKey);
-
-loser:
- PORT_FreeArena(arena, PR_FALSE);
- return(cert);
-}
-
-/*
- * look for the given DER certificate in the database
- */
-CERTCertificate *
-CERT_FindCertByDERCertNoLocking(CERTCertDBHandle *handle, SECItem *derCert)
-{
- PRArenaPool *arena;
- SECItem certKey;
- SECStatus rv;
- CERTCertificate *cert = NULL;
-
- /* create a scratch arena */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- return(NULL);
- }
-
- /* extract the database key from the cert */
- rv = CERT_KeyFromDERCert(arena, derCert, &certKey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* find the certificate */
- cert = CERT_FindCertByKeyNoLocking(handle, &certKey);
-
-loser:
- PORT_FreeArena(arena, PR_FALSE);
- return(cert);
-}
-
-/*
- * The following is bunch of types and code to allow looking up a certificate
- * by a hash of its subject public key. Because the words "hash" and "key"
- * are overloaded and thus terribly confusing, I tried to disambiguate things.
- * - Where I could, I used "digest" instead of "hash" when referring to
- * hashing of the subject public key. The PLHashTable interfaces and
- * our own HASH_Foo interfaces had to be left as is, obviously. The latter
- * should be thought of as "digest" in this case.
- * - There are three keys in use here -- the subject public key, the key
- * used to do a lookup in the PLHashTable, and the key used to do a lookup
- * in the cert database. As the latter is a fairly pervasive interface,
- * I left it alone. The other two uses I changed to "spk" or "SPK" when
- * referring to the subject public key, and "index" when referring to the
- * key into the PLHashTable.
- */
-
-typedef struct SPKDigestInfoStr {
- PLHashTable *table;
- PRBool permPopulated;
-} SPKDigestInfo;
-
-/*
- * Since the key hash information is "hidden" (in a void pointer in the handle)
- * these macros with the appropriate casts make it easy to get at the parts.
- */
-#define SPK_DIGEST_TABLE(handle) \
- (((SPKDigestInfo *)(handle->spkDigestInfo))->table)
-
-/*
-** Hash allocator ops for the SPKDigest hash table. The rules are:
-** + The index and value fields are "owned" by the hash table, and are
-** freed when the table entry is deleted.
-** + Replacing a value in the table is not allowed, since the caller can't
-** tell whether the index field was used or not, resulting in a memory
-** leak. (This is a bug in the PL_Hash routines.
-*/
-static void * PR_CALLBACK
-spkAllocTable(void *pool, PRSize size)
-{
-#if defined(XP_MAC)
-#pragma unused (pool)
-#endif
-
- return PR_MALLOC(size);
-}
-
-static void PR_CALLBACK
-spkFreeTable(void *pool, void *item)
-{
-#if defined(XP_MAC)
-#pragma unused (pool)
-#endif
-
- PR_Free(item);
-}
-
-/* NOTE: the key argument here appears to be useless, since the RawAdd
- * routine in PL_Hash just uses the original anyway.
- */
-static PLHashEntry * PR_CALLBACK
-spkAllocEntry(void *pool, const void *key)
-{
-#if defined(XP_MAC)
-#pragma unused (pool,key)
-#endif
-
- return PR_NEW(PLHashEntry);
-}
-
-static void PR_CALLBACK
-spkFreeEntry(void *pool, PLHashEntry *he, PRUintn flag)
-{
-#if defined(XP_MAC)
-#pragma unused (pool)
-#endif
-
- SECItem *value = (SECItem *)he->value;
-
- /* The flag should always be to free the whole entry. Otherwise the
- * index field gets leaked because the caller can't tell whether
- * the "new" value (which is the same as the old) was used or not.
- */
- PORT_Assert(flag == HT_FREE_ENTRY);
-
- /* We always free the value */
- SECITEM_FreeItem(value, PR_TRUE);
-
- if (flag == HT_FREE_ENTRY)
- {
- /* Comes from BTOA, is this the right free call? */
- PORT_Free((char *)he->key);
- PR_Free(he);
- }
-}
-
-static PLHashAllocOps spkHashAllocOps = {
- spkAllocTable, spkFreeTable,
- spkAllocEntry, spkFreeEntry
-};
-
-
-/*
- * Create the key hash lookup table. Note that the table, and the
- * structure which holds it and a little more information, is never freed.
- * This is because the temporary database is never actually closed out,
- * so there is no safe/obvious place to free the whole thing.
- *
- * The database must be locked already.
- */
-static SECStatus
-InitDBspkDigestInfo(CERTCertDBHandle *handle)
-{
- SPKDigestInfo *spkDigestInfo;
- PLHashTable *table;
-
- PORT_Assert(handle != NULL);
- PORT_Assert(handle->spkDigestInfo == NULL);
-
- spkDigestInfo = PORT_ZAlloc(sizeof(SPKDigestInfo));
- if ( spkDigestInfo == NULL ) {
- return(SECFailure);
- }
-
- table = PL_NewHashTable(128, PL_HashString, PL_CompareStrings,
- (PLHashComparator) SECITEM_ItemsAreEqual,
- &spkHashAllocOps, NULL);
- if ( table == NULL ) {
- PORT_Free(spkDigestInfo);
- return(SECFailure);
- }
-
- spkDigestInfo->table = table;
- handle->spkDigestInfo = spkDigestInfo;
- return(SECSuccess);
-}
-
-static const SECHashObject *
-OidTagToRawDigestObject(SECOidTag digestAlg)
-{
- const SECHashObject *rawDigestObject;
-
- switch (digestAlg) {
- case SEC_OID_MD2:
- rawDigestObject = &SECRawHashObjects[HASH_AlgMD2];
- break;
- case SEC_OID_MD5:
- rawDigestObject = &SECRawHashObjects[HASH_AlgMD5];
- break;
- case SEC_OID_SHA1:
- rawDigestObject = &SECRawHashObjects[HASH_AlgSHA1];
- break;
- default:
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- rawDigestObject = NULL;
- break;
- }
- return(rawDigestObject);
-}
-
-/*
- * Digest the cert's subject public key using the specified algorithm.
- * The necessary storage for the digest data is allocated. If "fill" is
- * non-null, the data is put there, otherwise a SECItem is allocated.
- * Allocation from "arena" if it is non-null, heap otherwise. Any problem
- * results in a NULL being returned (and an appropriate error set).
- */
-SECItem *
-CERT_SPKDigestValueForCert(PRArenaPool *arena, CERTCertificate *cert,
- SECOidTag digestAlg, SECItem *fill)
-{
- const SECHashObject *digestObject;
- void *digestContext;
- SECItem *result = NULL;
- void *mark = NULL;
- SECItem spk;
-
- if ( arena != NULL ) {
- mark = PORT_ArenaMark(arena);
- }
-
- /*
- * This can end up being called before PKCS #11 is initialized,
- * so we have to use the raw digest functions.
- */
- digestObject = OidTagToRawDigestObject(digestAlg);
- if ( digestObject == NULL ) {
- goto loser;
- }
-
- result = SECITEM_AllocItem(arena, fill, digestObject->length);
- if ( result == NULL ) {
- goto loser;
- }
-
- /*
- * Copy just the length and data pointer (nothing needs to be freed)
- * of the subject public key so we can convert the length from bits
- * to bytes, which is what the digest function expects.
- */
- spk = cert->subjectPublicKeyInfo.subjectPublicKey;
- DER_ConvertBitString(&spk);
-
- /*
- * Now digest the value, using the specified algorithm.
- */
- digestContext = digestObject->create();
- if ( digestContext == NULL ) {
- goto loser;
- }
- digestObject->begin(digestContext);
- digestObject->update(digestContext, spk.data, spk.len);
- digestObject->end(digestContext, result->data, &(result->len), result->len);
- digestObject->destroy(digestContext, PR_TRUE);
-
- if ( arena != NULL ) {
- PORT_ArenaUnmark(arena, mark);
- }
- return(result);
-
-loser:
- if ( arena != NULL ) {
- PORT_ArenaRelease(arena, mark);
- } else {
- if ( result != NULL ) {
- SECITEM_FreeItem(result, (fill == NULL) ? PR_TRUE : PR_FALSE);
- }
- }
- return(NULL);
-}
-
-/*
- * Return the index for the spk digest lookup table for "spkDigest".
- *
- * Caller is responsible for freeing the returned string.
- */
-static char *
-spkDigestIndexFromDigest(SECItem *spkDigest)
-{
- return BTOA_ConvertItemToAscii(spkDigest);
-}
-
-/*
- * Return the index for the spk digest lookup table for this certificate,
- * based on the specified digest algorithm.
- *
- * Caller is responsible for freeing the returned string.
- */
-static char *
-spkDigestIndexFromCert(CERTCertificate *cert, SECOidTag digestAlg)
-{
- SECItem *spkDigest;
- char *index;
-
- spkDigest = CERT_SPKDigestValueForCert(NULL, cert, digestAlg, NULL);
- if ( spkDigest == NULL )
- return(NULL);
-
- index = spkDigestIndexFromDigest(spkDigest);
-
- SECITEM_FreeItem(spkDigest, PR_TRUE);
-
- return(index);
-}
-
-/*
- * Remove the spk digest for the given cert from the spk digest table,
- * based on the given digest algorithm.
- *
- * The database must be locked already.
- */
-static SECStatus
-RemoveCertFromSPKDigestTableForAlg(CERTCertDBHandle *handle,
- CERTCertificate *cert, SECOidTag digestAlg)
-{
- SECStatus rv = SECSuccess;
- char *index = NULL;
- PLHashTable *table;
-
- /* Expect to only be called if there is a table to work with. */
- PORT_Assert(handle->spkDigestInfo != NULL);
-
- table = SPK_DIGEST_TABLE(handle);
- PORT_Assert(table != NULL);
-
- index = spkDigestIndexFromCert(cert, digestAlg);
- if ( index == NULL ) {
- rv = SECFailure;
- goto done;
- }
-
- if ( PL_HashTableRemove(table, index) != PR_TRUE ) {
- /* not found means nothing to remove, which is fine */
- }
-
-done:
- if ( index != NULL ) {
- PORT_Free(index);
- }
- return(rv);
-}
-
-/*
- * Remove the spk digests for the given cert from the spk digest table,
- * for all known digest algorithms.
- *
- * The database must be locked already.
- */
-static SECStatus
-RemoveCertFromSPKDigestTable(CERTCertDBHandle *handle, CERTCertificate *cert)
-{
- /*
- * If no certs have been added yet, then nothing to do.
- */
- if ( handle->spkDigestInfo == NULL ) {
- return(SECSuccess);
- }
-
- (void) RemoveCertFromSPKDigestTableForAlg(handle, cert, SEC_OID_MD2);
- (void) RemoveCertFromSPKDigestTableForAlg(handle, cert, SEC_OID_MD5);
- return RemoveCertFromSPKDigestTableForAlg(handle, cert, SEC_OID_SHA1);
-}
-
-/*
- * Add the spk digest for the given cert to the spk digest table,
- * based on the given digest algorithm.
- *
- * If a cert for the same spk digest is already in the table, choose whichever
- * cert is "newer". (The other cert cannot be found via spk digest.)
- *
- * The database must be locked already.
- *
- * XXX Note that this implementation results in leaking the index value.
- * Fixing that did not seem worth the trouble, given we will only leak
- * once per cert. This whole thing should be done differently in the
- * new rewrite (Stan), and then the problem will go away.
- */
-static SECStatus
-AddCertToSPKDigestTableForAlg(CERTCertDBHandle *handle, CERTCertificate *cert,
- SECItem *certDBKey, SECOidTag digestAlg)
-{
- SECStatus rv = SECFailure;
- SECItem *oldCertDBKey;
- PRBool addit = PR_TRUE;
- CERTCertificate *oldCert = NULL;
- char *index = NULL;
- PLHashTable *table;
-
- /*
- * After running some testing doing key hash lookups (like using OCSP),
- * if these are never hit, they can probably be removed.
- */
- PORT_Assert(handle != NULL);
- PORT_Assert(handle == cert->dbhandle);
- PORT_Assert(handle->spkDigestInfo != NULL);
- PORT_Assert((certDBKey == &cert->certKey)
- || (SECITEM_CompareItem(certDBKey,
- &cert->certKey) == SECEqual));
-
- table = SPK_DIGEST_TABLE(handle);
- PORT_Assert(table != NULL);
-
- index = spkDigestIndexFromCert(cert, digestAlg);
- if ( index == NULL ) {
- goto loser;
- }
-
- /*
- * See if this cert's spk digest is already in the table.
- */
- oldCertDBKey = PL_HashTableLookup(table, index);
- if ( oldCertDBKey != NULL ) {
- /*
- * The spk digest *is* already in the table. We need to find that
- * cert and see -- if it is the same, then we can just leave as is.
- * Otherwise we have to choose which cert we want represented;
- * in that case the best plan I can think of is to hang onto the
- * most recent one.
- */
- oldCert = CERT_FindCertByKey(handle, oldCertDBKey);
- if ( oldCert != NULL ) {
- if ( cert == oldCert ) {
- /* They are the same cert, so we are done. */
- addit = PR_FALSE;
- } else if ( CERT_IsNewer(cert, oldCert) ) {
- if ( PL_HashTableRemove(table, index) != PR_TRUE ) {
- goto loser;
- }
- } else {
- /* oldCert is "newer", so we are done. */
- addit = PR_FALSE;
- }
- }
- }
-
- if ( addit ) {
- certDBKey = SECITEM_DupItem(certDBKey);
- if ( certDBKey == NULL ) {
- goto loser;
- }
- if ( PL_HashTableAdd(table, index, certDBKey) == NULL ) {
- SECITEM_FreeItem(certDBKey, PR_TRUE);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- index = NULL; /* don't want to free it */
- }
-
- rv = SECSuccess;
-
-loser:
- if ( index != NULL ) {
- PORT_Free(index);
- }
- if ( oldCert != NULL ) {
- CERT_DestroyCertificate(oldCert);
- }
- return(rv);
-}
-
-/*
- * Add the spk digest for the given cert to the spk digest table,
- * for all known digest algorithms.
- *
- * The database must be locked already, and the digest table already created.
- */
-static SECStatus
-AddCertToSPKDigestTableForAllAlgs(CERTCertDBHandle *handle,
- CERTCertificate *cert, SECItem *certDBKey)
-{
- (void) AddCertToSPKDigestTableForAlg(handle, cert, certDBKey, SEC_OID_MD2);
- (void) AddCertToSPKDigestTableForAlg(handle, cert, certDBKey, SEC_OID_MD5);
- return AddCertToSPKDigestTableForAlg(handle, cert, certDBKey, SEC_OID_SHA1);
-}
-
-/*
- * Add the spk digests for the given cert to the spk digest table,
- * for all known digest algorithms. (This function is called when a
- * new cert is added to the temporary database.)
- *
- * If the spk digest table does not yet exist, create it.
- *
- * In an ideal world, we would not hardwire the digest algorithms.
- * But it is the case that we do not currently support any digest
- * algorithms outside of these three. In the newer, cleaned-up world,
- * this may be done differently.
- *
- * The database must be locked already.
- */
-static SECStatus
-AddCertToSPKDigestTable(CERTCertDBHandle *handle, CERTCertificate *cert)
-{
- SECStatus rv;
-
- if ( handle->spkDigestInfo == NULL ) {
- rv = InitDBspkDigestInfo(handle);
- if ( rv != SECSuccess ) {
- return(rv);
- }
- }
-
- return AddCertToSPKDigestTableForAllAlgs(handle, cert, &cert->certKey);
-}
-
-/*
- * Add the spk digest for the given cert to the spk digest table,
- * for all known digest algorithms. This function is called while
- * traversing all of the certs in the permanent database -- since
- * that imposes some constraints on its arguments this routine is a
- * simple cover for the "real" interface.
- *
- * The database must be locked already, and the digest table already created.
- */
-static SECStatus
-AddCertToSPKDigestTableInTraversal(CERTCertificate *cert, SECItem *certDBKey,
- void *data)
-{
- CERTCertDBHandle *handle = data;
-
- return AddCertToSPKDigestTableForAllAlgs(handle, cert, certDBKey);
-}
-
-/*
- * Add the spk digests for the all permanent certs to the spk digest table,
- * for all known digest algorithms.
- *
- * This locks the database, and then checks to make sure that the work
- * actually needs to get done.
- *
- * If the spk digest table does not yet exist, it is created.
- */
-static SECStatus
-PopulateSPKDigestTable(CERTCertDBHandle *handle)
-{
- SPKDigestInfo *spkDigestInfo;
- SECStatus rv = SECSuccess;
-
- CERT_LockDB(handle);
-
- spkDigestInfo = handle->spkDigestInfo;
- if ( spkDigestInfo == NULL ) {
- rv = InitDBspkDigestInfo(handle);
- if ( rv != SECSuccess ) {
- return(rv);
- }
- spkDigestInfo = handle->spkDigestInfo;
- PORT_Assert(spkDigestInfo != NULL);
- } else {
- /*
- * Check to see if someone already did it; it is important to do
- * this after getting the lock.
- */
- if ( spkDigestInfo->permPopulated == PR_TRUE ) {
- goto done;
- }
- }
-
- rv = TraversePermCertsNoLocking(handle, AddCertToSPKDigestTableInTraversal,
- handle);
-
- if ( rv != SECSuccess ) {
- goto done;
- }
-
- spkDigestInfo->permPopulated = PR_TRUE;
-
-done:
- CERT_UnlockDB(handle);
-
- return(rv);
-}
-
-/*
- * Lookup a certificate by a digest of a subject public key. If it is
- * found, it is returned (and must then be destroyed by the caller).
- * NULL is returned otherwise -- if there was a problem performing the
- * lookup, an appropriate error is set (e.g. SEC_ERROR_NO_MEMORY);
- * if the cert simply was not found, the error is SEC_ERROR_UNKNOWN_CERT.
- *
- * If the lookup table has not yet been created or populated, do that first.
- */
-CERTCertificate *
-CERT_FindCertBySPKDigest(CERTCertDBHandle *handle, SECItem *spkDigest)
-{
- SPKDigestInfo *spkDigestInfo;
- char *index = NULL;
- SECItem *certDBKey;
- CERTCertificate *cert = NULL;
-
- PORT_Assert(handle != NULL);
- spkDigestInfo = handle->spkDigestInfo;
-
- if ( spkDigestInfo == NULL || spkDigestInfo->permPopulated != PR_TRUE ) {
- if ( PopulateSPKDigestTable(handle) != SECSuccess ) {
- goto loser;
- }
- }
-
- index = spkDigestIndexFromDigest(spkDigest);
- if ( index == NULL ) {
- goto loser;
- }
-
- certDBKey = PL_HashTableLookup(SPK_DIGEST_TABLE(handle), index);
- if ( certDBKey != NULL ) {
- cert = CERT_FindCertByKey(handle, certDBKey);
- }
-
- if ( cert == NULL ) {
- PORT_SetError(SEC_ERROR_UNKNOWN_CERT);
- }
-
-loser:
- if ( index != NULL ) {
- PORT_Free(index);
- }
- return(cert);
-}
-
-static void
-DestroyCertificate(CERTCertificate *cert, PRBool lockdb)
-{
- int refCount;
- CERTCertDBHandle *handle;
-
- if ( cert ) {
-
- handle = cert->dbhandle;
-
- /*
- * handle may be NULL, for example if the cert was created with
- * CERT_DecodeDERCertificate.
- */
- if ( lockdb && handle ) {
- CERT_LockDB(handle);
- }
-
- CERT_LockCertRefCount(cert);
- PORT_Assert(cert->referenceCount > 0);
- refCount = --cert->referenceCount;
- CERT_UnlockCertRefCount(cert);
-
- if ( ( refCount == 0 ) && !cert->keepSession ) {
- certDBEntryCert *entry = cert->dbEntry;
- PRArenaPool * arena = cert->arena;
-
- if ( cert->istemp ) {
- CERT_DeleteTempCertificate(cert);
- }
-
- if ( entry ) {
- DestroyDBEntry((certDBEntry *)entry);
- }
-
- /* zero cert before freeing. Any stale references to this cert
- * after this point will probably cause an exception. */
- PORT_Memset(cert, 0, sizeof *cert);
-
- cert = NULL;
-
- /* free the arena that contains the cert. */
- PORT_FreeArena(arena, PR_FALSE);
- }
- if ( lockdb && handle ) {
- CERT_UnlockDB(handle);
- }
- }
-
- return;
-}
-
-void
-CERT_DestroyCertificate(CERTCertificate *cert)
-{
- DestroyCertificate(cert, PR_TRUE);
- return;
-}
-
-void
-CERT_DestroyCertificateNoLocking(CERTCertificate *cert)
-{
- DestroyCertificate(cert, PR_FALSE);
- return;
-}
-
-/*
- * cache a CRL from the permanent database into the temporary database
- */
-CERTSignedCrl *
-SEC_AddPermCrlToTemp(CERTCertDBHandle *handle, certDBEntryRevocation *entry)
-{
- CERTSignedCrl *crl = NULL;
- DBT key;
- DBT data;
- int status;
- PRArenaPool *arena = NULL;
- SECItem keyitem;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- crl = CERT_DecodeDERCrl(NULL, &entry->derCrl,
- entry->common.type == certDBEntryTypeRevocation ?
- SEC_CRL_TYPE : SEC_KRL_TYPE);
-
- if ( crl == NULL ) {
- goto loser;
- }
-
- /* only save pointer to cert in database */
- data.data = &crl;
- data.size = sizeof(crl);
-
-
- rv = EncodeDBGenericKey(&(crl->crl.derName), arena,
- &keyitem, entry->common.type);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- if (entry->url) {
- int nnlen = PORT_Strlen(entry->url) + 1;
- crl->url = (char *)PORT_ArenaAlloc(crl->arena, nnlen);
- if ( !crl->url ) {
- goto loser;
- }
- PORT_Memcpy(crl->url, entry->url, nnlen);
- } else {
- crl->url = NULL;
- }
-
- key.data = keyitem.data;
- key.size = keyitem.len;
-
- /* enter into main db */
- status = certdb_Put(handle->tempCertDB, &key, &data, R_NOOVERWRITE);
- if ( status ) {
- goto loser;
- }
-
- crl->istemp = PR_TRUE;
- crl->isperm = PR_TRUE;
- crl->dbhandle = handle;
- crl->dbEntry = entry;
-
-
- PORT_FreeArena(arena, PR_FALSE);
-
- crl->keep = PR_TRUE;
- return(crl);
-
-loser:
- if ( crl ) {
- SEC_DestroyCrl(crl);
- }
-
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return(0);
-}
-
-SECStatus
-SEC_DeleteTempCrl(CERTSignedCrl *crl)
-{
- SECStatus rv;
- DBT nameKey;
- CERTCertDBHandle *handle;
- SECItem keyitem;
- PRArenaPool *arena;
- int ret;
-
- handle = crl->dbhandle;
-
- if ( !crl->istemp ) {
- return(SECSuccess);
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- rv = EncodeDBGenericKey
- (&crl->crl.derName, arena, &keyitem, crl->dbEntry->common.type);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- nameKey.data = keyitem.data;
- nameKey.size = keyitem.len;
-
- /* delete the cert */
- ret = certdb_Del(handle->tempCertDB, &nameKey, 0);
- if ( ret ) {
- goto loser;
- }
-
- crl->istemp = PR_FALSE;
-
- PORT_FreeArena(arena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(SECFailure);
-}
-
-/*
- * Lookup a CRL in the databases. We mirror the same fast caching data base
- * caching stuff used by certificates....?
- */
-CERTSignedCrl *
-SEC_FindCrlByKey(CERTCertDBHandle *handle, SECItem *crlKey, int type)
-{
- DBT tmpdata;
- int ret;
- SECItem keyitem;
- DBT key;
- SECStatus rv;
- CERTSignedCrl *crl = NULL;
- PRArenaPool *arena = NULL;
- certDBEntryRevocation *entry;
- certDBEntryType crlType = (type == SEC_CRL_TYPE) ?
- certDBEntryTypeRevocation : certDBEntryTypeKeyRevocation;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- rv = EncodeDBGenericKey(crlKey, arena, &keyitem, crlType);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- key.data = keyitem.data;
- key.size = keyitem.len;
-
- /* lookup in the temporary database */
- ret = certdb_Get( handle->tempCertDB, &key, &tmpdata, 0 );
-
- /* error accessing the database */
- if ( ret < 0 ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- if ( ret == 0 ) { /* found in temp database */
- if ( tmpdata.size != sizeof(CERTSignedCrl *) ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- PORT_Memcpy(&crl, tmpdata.data, tmpdata.size);
- crl->referenceCount++;
- } else { /* not found in temporary database */
-
- /* find in perm database */
- entry = ReadDBCrlEntry(handle, crlKey, crlType);
-
- if ( entry == NULL ) {
- goto loser;
- }
-
- crl = SEC_AddPermCrlToTemp(handle, entry);
- }
-
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(crl);
-}
-
-
-CERTSignedCrl *
-SEC_FindCrlByName(CERTCertDBHandle *handle, SECItem *crlKey, int type)
-{
- return SEC_FindCrlByKey(handle,crlKey,type);
-}
-
-CERTSignedCrl *
-SEC_FindCrlByDERCert(CERTCertDBHandle *handle, SECItem *derCrl, int type)
-{
- PRArenaPool *arena;
- SECItem crlKey;
- SECStatus rv;
- CERTSignedCrl *crl = NULL;
-
- /* create a scratch arena */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- return(NULL);
- }
-
- /* extract the database key from the cert */
- rv = CERT_KeyFromDERCrl(arena, derCrl, &crlKey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* find the crl */
- crl = SEC_FindCrlByKey(handle, &crlKey, type);
-
-loser:
- PORT_FreeArena(arena, PR_FALSE);
- return(crl);
-}
-
-
-SECStatus
-SEC_DestroyCrl(CERTSignedCrl *crl)
-{
- if (crl) {
- if (crl->referenceCount-- <= 1) {
- if (!crl->keep) {
- SEC_DeleteTempCrl(crl);
- if (crl->dbEntry) {
- DestroyDBEntry((certDBEntry *)crl->dbEntry);
- }
- PORT_FreeArena(crl->arena, PR_FALSE);
- }
- }
- }
- return SECSuccess;
-}
-
-CERTSignedCrl *
-cert_DBInsertCRL (CERTCertDBHandle *handle, char *url,
- CERTSignedCrl *newCrl, SECItem *derCrl, int type)
-{
- CERTSignedCrl *oldCrl = NULL, *crl = NULL;
- certDBEntryRevocation *entry = NULL;
- PRArenaPool *arena = NULL;
- SECCertTimeValidity validity;
- certDBEntryType crlType = (type == SEC_CRL_TYPE) ?
- certDBEntryTypeRevocation : certDBEntryTypeKeyRevocation;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) goto done;
-
- validity = SEC_CheckCrlTimes(&newCrl->crl,PR_Now());
- if ( validity == secCertTimeExpired) {
- if (type == SEC_CRL_TYPE) {
- PORT_SetError(SEC_ERROR_CRL_EXPIRED);
- } else {
- PORT_SetError(SEC_ERROR_KRL_EXPIRED);
- }
- goto done;
- } else if (validity == secCertTimeNotValidYet) {
- if (type == SEC_CRL_TYPE) {
- PORT_SetError(SEC_ERROR_CRL_NOT_YET_VALID);
- } else {
- PORT_SetError(SEC_ERROR_KRL_NOT_YET_VALID);
- }
- goto done;
- }
-
- oldCrl = SEC_FindCrlByKey(handle, &newCrl->crl.derName, type);
-
- /* if there is an old crl, make sure the one we are installing
- * is newer. If not, exit out, otherwise delete the old crl.
- */
- if (oldCrl != NULL) {
- if (!SEC_CrlIsNewer(&newCrl->crl,&oldCrl->crl)) {
-
- if (type == SEC_CRL_TYPE) {
- PORT_SetError(SEC_ERROR_OLD_CRL);
- } else {
- PORT_SetError(SEC_ERROR_OLD_KRL);
- }
-
- goto done;
- }
-
- if ((SECITEM_CompareItem(&newCrl->crl.derName,
- &oldCrl->crl.derName) != SECEqual) &&
- (type == SEC_KRL_TYPE) ) {
-
- PORT_SetError(SEC_ERROR_CKL_CONFLICT);
- goto done;
- }
-
- /* if we have a url in the database, use that one */
- if (oldCrl->url) {
- int nnlen = PORT_Strlen(oldCrl->url) + 1;
- url = (char *)PORT_ArenaAlloc(arena, nnlen);
- if ( url != NULL ) {
- PORT_Memcpy(url, oldCrl->url, nnlen);
- }
- }
-
-
- /* really destroy this crl */
- /* first drum it out of the permanment Data base */
- SEC_DeletePermCRL(oldCrl);
- /* then get rid of our reference to it... */
- SEC_DestroyCrl(oldCrl);
- oldCrl = NULL;
-
- }
-
- /* Write the new entry into the data base */
- entry = NewDBCrlEntry(derCrl, url, crlType, 0);
- if (entry == NULL) goto done;
-
- rv = WriteDBCrlEntry(handle, entry);
- if (rv != SECSuccess) goto done;
-
- crl = SEC_AddPermCrlToTemp(handle, entry);
- if (crl) entry = NULL; /*crl->dbEntry now points to entry data */
- crl->isperm = PR_TRUE;
-
-done:
- if (entry) DestroyDBEntry((certDBEntry *)entry);
- if (arena) PORT_FreeArena(arena, PR_FALSE);
- if (oldCrl) SEC_DestroyCrl(oldCrl);
-
- return crl;
-}
-
-
-/*
- * create a new CRL from DER material.
- *
- * The signature on this CRL must be checked before you
- * load it. ???
- */
-CERTSignedCrl *
-SEC_NewCrl(CERTCertDBHandle *handle, char *url, SECItem *derCrl, int type)
-{
- CERTSignedCrl *newCrl = NULL, *crl = NULL;
-
- /* make this decode dates! */
- newCrl = CERT_DecodeDERCrl(NULL, derCrl, type);
- if (newCrl == NULL) {
- if (type == SEC_CRL_TYPE) {
- PORT_SetError(SEC_ERROR_CRL_INVALID);
- } else {
- PORT_SetError(SEC_ERROR_KRL_INVALID);
- }
- goto done;
- }
-
- crl = cert_DBInsertCRL (handle, url, newCrl, derCrl, type);
-
-
-done:
- if (newCrl) PORT_FreeArena(newCrl->arena, PR_FALSE);
-
- return crl;
-}
-
-
-/*
- * replace the existing URL in the data base with a new one
- */
-SECStatus
-SEC_CrlReplaceUrl(CERTSignedCrl *crl,char *url) {
- SECStatus rv = SECFailure;
- certDBEntryRevocation *entry = NULL;
- int nnlen=0;
-
- SEC_DeletePermCRL(crl);
-
- /* Write the new entry into the data base */
- entry = NewDBCrlEntry(&crl->dbEntry->derCrl, url, crl->dbEntry->common.type, 0);
- if (entry == NULL) goto done;
-
- rv = WriteDBCrlEntry(crl->dbhandle, entry);
- if (rv != SECSuccess) goto done;
-
- if (url) {
- nnlen = PORT_Strlen(url) + 1;
- crl->url = (char *)PORT_ArenaAlloc(crl->arena, nnlen);
- if ( !crl->url ) {
- goto done;
- }
- PORT_Memcpy(crl->url, url, nnlen);
- } else {
- crl->url = NULL;
- }
-done:
- return rv;
-}
-
-
-/*
- * collect a linked list of CRL's
- */
-static SECStatus CollectCrls(SECItem *dbdata, SECItem *dbkey,
- certDBEntryType type, void *data) {
- SECStatus rv;
- certDBEntryRevocation entry;
- SECItem entryitem;
- PRArenaPool *arena = NULL;
- CERTCrlHeadNode *head;
- CERTCrlNode *new_node;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- head = (CERTCrlHeadNode *)data;
- entry.common.version = (unsigned int)dbdata->data[0];
- entry.common.type = (certDBEntryType)dbdata->data[1];
- entry.common.flags = (unsigned int)dbdata->data[2];
- entry.common.arena = arena;
-
- entryitem.len = dbdata->len - SEC_DB_ENTRY_HEADER_LEN;
- entryitem.data = &dbdata->data[SEC_DB_ENTRY_HEADER_LEN];
-
- rv = DecodeDBCrlEntry(&entry, &entryitem);
- if (rv != SECSuccess ) {
- goto loser;
- }
-
- new_node = (CERTCrlNode *)PORT_ArenaAlloc(head->arena, sizeof(CERTCrlNode));
- if (new_node == NULL) {
- goto loser;
- }
-
- new_node->type = (entry.common.type == certDBEntryTypeRevocation) ?
- SEC_CRL_TYPE : SEC_KRL_TYPE;
- new_node->crl=CERT_DecodeDERCrl(head->arena,&entry.derCrl,new_node->type);
-
- if (entry.url) {
- int nnlen = PORT_Strlen(entry.url) + 1;
- new_node->crl->url = (char *)PORT_ArenaAlloc(head->arena, nnlen);
- if ( !new_node->crl->url ) {
- goto loser;
- }
- PORT_Memcpy(new_node->crl->url, entry.url, nnlen);
- } else {
- new_node->crl->url = NULL;
- }
-
-
- new_node->next = NULL;
- if (head->last) {
- head->last->next = new_node;
- head->last = new_node;
- } else {
- head->first = head->last = new_node;
- }
- return (SECSuccess);
-
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- return(SECFailure);
-}
-
-
-SECStatus
-SEC_LookupCrls(CERTCertDBHandle *handle, CERTCrlHeadNode **nodes, int type)
-{
- CERTCrlHeadNode *head;
- PRArenaPool *arena = NULL;
- SECStatus rv;
-
- *nodes = NULL;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- return SECFailure;
- }
-
- /* build a head structure */
- head = (CERTCrlHeadNode *)PORT_ArenaAlloc(arena, sizeof(CERTCrlHeadNode));
- head->arena = arena;
- head->first = NULL;
- head->last = NULL;
- head->dbhandle = handle;
-
- /* Look up the proper crl types */
- *nodes = head;
-
- CERT_LockDB(handle);
-
- switch (type) {
- case SEC_CRL_TYPE:
- rv = SEC_TraverseDBEntries(handle, certDBEntryTypeRevocation,
- CollectCrls, (void *)head);
- break;
- case SEC_KRL_TYPE:
- rv = SEC_TraverseDBEntries(handle, certDBEntryTypeKeyRevocation,
- CollectCrls, (void *)head);
- break;
- case -1:
- rv = SEC_TraverseDBEntries(handle, certDBEntryTypeKeyRevocation,
- CollectCrls, (void *)head);
- if (rv != SECSuccess) break;
- rv = SEC_TraverseDBEntries(handle, certDBEntryTypeRevocation,
- CollectCrls, (void *)head);
- break;
- default:
- rv = SECFailure;
- break;
- }
-
- CERT_UnlockDB(handle);
-
- if (rv != SECSuccess) {
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- *nodes = NULL;
- }
- }
-
- return rv;
-}
-
-
-SECStatus
-SEC_DeletePermCRL(CERTSignedCrl *crl) {
- SECStatus rv;
-
- if (crl == NULL) {
- return SECFailure;
- }
-
- rv = DeleteDBCrlEntry(crl->dbhandle, &crl->crl.derName,
- crl->dbEntry->common.type);
- if (rv != SECSuccess) goto done;
-
- /* now force it to be freed when all the reference counts go */
- crl->keep = PR_FALSE;
- /* force it out of the temporary data base */
- SEC_DeleteTempCrl(crl);
-
-done:
- return rv;
-}
-
-/*
- * find a cert by email address
- *
- * pick one that is a valid recipient, meaning that it is an encryption
- * cert.
- *
- */
-static CERTCertificate*
-find_smime_recipient_cert(CERTCertDBHandle* handle, const char* email_addr)
-{
- CERTCertificate* cert = NULL;
- CERTCertList* certList = NULL;
- SECStatus rv;
-
- certList = CERT_CreateEmailAddrCertList(NULL, handle, (char*)email_addr,
- PR_Now(), PR_TRUE);
- if (certList == NULL) {
- return NULL;
- }
-
- rv = CERT_FilterCertListByUsage(certList, certUsageEmailRecipient,
- PR_FALSE);
-
- if (!CERT_LIST_END(CERT_LIST_HEAD(certList), certList)) {
- cert = CERT_DupCertificate(CERT_LIST_HEAD(certList)->cert);
- }
-
- CERT_DestroyCertList(certList);
-
- return cert; /* cert may point to a cert or may be NULL */
-}
-
-/*
- * This function has the logic that decides if another person's cert and
- * email profile from an S/MIME message should be saved. It can deal with
- * the case when there is no profile.
- */
-SECStatus
-CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile,
- SECItem *profileTime)
-{
- certDBEntrySMime *entry = NULL, *oldentry = NULL;
- int64 oldtime;
- int64 newtime;
- SECStatus rv;
- CERTCertificate *oldcert = NULL;
- PRBool saveit;
- CERTCertTrust trust;
- CERTCertTrust tmptrust;
- char *emailAddr;
-
- emailAddr = cert->emailAddr;
-
- PORT_Assert(emailAddr);
- if ( emailAddr == NULL ) {
- goto loser;
- }
-
- saveit = PR_FALSE;
-
- oldcert = find_smime_recipient_cert(cert->dbhandle, emailAddr);
- if (oldcert) {
- /* see if there is an entry already */
- oldentry = ReadDBSMimeEntry(cert->dbhandle, emailAddr);
- }
-
- /* both profileTime and emailProfile have to exist or not exist */
- if ( emailProfile == NULL ) {
- profileTime = NULL;
- } else if ( profileTime == NULL ) {
- emailProfile = NULL;
- }
-
- if ( oldentry == NULL ) {
- /* no old entry for this address */
- PORT_Assert(oldcert == NULL);
- saveit = PR_TRUE;
- } else {
- /* there was already a profile for this email addr */
- if ( profileTime ) {
- /* we have an old and new profile - save whichever is more recent*/
- if ( oldentry->optionsDate.len == 0 ) {
- /* always replace if old entry doesn't have a time */
- oldtime = LL_MININT;
- } else {
- rv = DER_UTCTimeToTime(&oldtime, &oldentry->optionsDate);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- }
-
- rv = DER_UTCTimeToTime(&newtime, profileTime);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- if ( LL_CMP(newtime, >, oldtime ) ) {
- /* this is a newer profile, save it and cert */
- saveit = PR_TRUE;
- }
- } else {
- /* we don't have a new profile or time */
- if ( oldentry->optionsDate.len == 0 ) {
- /* the old entry doesn't have a time either, so compare certs*/
- if ( CERT_IsNewer(cert, oldcert) ) {
- /* new cert is newer, use it instead */
- saveit = PR_TRUE;
- }
- } else {
- if (oldcert) {
- if (CERT_IsNewer(cert, oldcert)) {
- saveit = PR_TRUE;
- }
- } else {
- saveit = PR_TRUE;
- }
- }
- }
- }
-
- if ( saveit ) {
- if ( oldcert && ( oldcert != cert ) ) {
- /* old cert is different from new cert */
- if ( PORT_Memcmp(oldcert->trust, &trust, sizeof(trust)) == 0 ) {
- /* old cert is only for e-mail, so delete it */
- SEC_DeletePermCertificate(oldcert);
- } else {
- /* old cert is for other things too, so just change trust */
- tmptrust = *oldcert->trust;
- tmptrust.emailFlags &= ( ~CERTDB_VALID_PEER );
- rv = CERT_ChangeCertTrust(oldcert->dbhandle, oldcert,
- &tmptrust);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- }
- }
-
-/* Subroutine */
- /* now save the entry */
- entry = NewDBSMimeEntry(emailAddr, &cert->derSubject, emailProfile,
- profileTime, 0);
- if ( entry == NULL ) {
- goto loser;
- }
-
- CERT_LockDB(cert->dbhandle);
-
- rv = DeleteDBSMimeEntry(cert->dbhandle, emailAddr);
- /* if delete fails, try to write new entry anyway... */
-
- rv = WriteDBSMimeEntry(cert->dbhandle, entry);
- if ( rv != SECSuccess ) {
- CERT_UnlockDB(cert->dbhandle);
- goto loser;
- }
-
- /* link subject entry back here */
- rv = UpdateSubjectWithEmailAddr(cert, emailAddr);
- if ( rv != SECSuccess ) {
- CERT_UnlockDB(cert->dbhandle);
- goto loser;
- }
-
- CERT_UnlockDB(cert->dbhandle);
-/* End Subroutine */
- }
-
- rv = SECSuccess;
- goto done;
-
-loser:
- rv = SECFailure;
-
-done:
- if ( oldcert ) {
- CERT_DestroyCertificate(oldcert);
- }
-
- if ( entry ) {
- DestroyDBEntry((certDBEntry *)entry);
- }
- if ( oldentry ) {
- DestroyDBEntry((certDBEntry *)oldentry);
- }
-
- return(rv);
-}
-
-CERTCertificate *
-CERT_FindCertByEmailAddr(CERTCertDBHandle *handle, char *emailAddr)
-{
- certDBEntrySMime *entry;
- CERTCertificate *cert = NULL;
-
- emailAddr = CERT_FixupEmailAddr(emailAddr);
- if ( emailAddr == NULL ) {
- return(NULL);
- }
-
- entry = ReadDBSMimeEntry(handle, emailAddr);
-
- /* XXX - this will have to change when multiple certs per subject
- * are allowed
- */
- if ( entry != NULL ) {
- cert = CERT_FindCertByName(handle, &entry->subjectName);
- }
-
- if ( entry ) {
- DestroyDBEntry((certDBEntry *)entry);
- }
-
- PORT_Free(emailAddr);
-
- return(cert);
-}
-
-/*
- * find the smime symmetric capabilities profile for a given cert
- */
-SECItem *
-CERT_FindSMimeProfile(CERTCertificate *cert)
-{
- certDBEntrySMime *entry;
- SECItem *retitem = NULL;
-
- PORT_Assert(cert->emailAddr != NULL);
-
- if ( cert->emailAddr == NULL ) {
- return(NULL);
- }
-
- entry = ReadDBSMimeEntry(cert->dbhandle, cert->emailAddr);
-
- if ( entry ) {
- /* May not be for this cert... */
- if (SECITEM_ItemsAreEqual(&cert->derSubject, &entry->subjectName))
- retitem = SECITEM_DupItem(&entry->smimeOptions);
- DestroyDBEntry((certDBEntry *)entry);
- }
-
- return(retitem);
-}
-
-CERTCertificate *
-CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, char *name)
-{
- CERTCertificate *cert;
- cert = CERT_FindCertByNickname(handle, name);
- if ( cert == NULL ) {
- cert = CERT_FindCertByEmailAddr(handle, name);
- }
-
- return(cert);
-}
-
-PRBool
-CERT_IsCertRevoked(CERTCertificate *cert)
-{
- return(PR_FALSE);
-}
-
-CERTCertificate *
-CERT_NextSubjectCert(CERTCertificate *cert)
-{
- CERTSubjectNode *node;
- CERTCertificate *retcert = NULL;
-
- CERT_LockDB(cert->dbhandle);
-
- node = FindCertSubjectNode(cert);
- PORT_Assert(node != NULL);
-
- if ( node->next != NULL ) {
- retcert = CERT_FindCertByKeyNoLocking(cert->dbhandle,
- &node->next->certKey);
- }
-
- CERT_UnlockDB(cert->dbhandle);
-
- return(retcert);
-}
-
-CERTCertificate *
-CERT_PrevSubjectCert(CERTCertificate *cert)
-{
- CERTSubjectNode *node;
- CERTCertificate *retcert = NULL;
-
- CERT_LockDB(cert->dbhandle);
- node = FindCertSubjectNode(cert);
- PORT_Assert(node != NULL);
-
- if ( node->prev != NULL ) {
- retcert = CERT_FindCertByKeyNoLocking(cert->dbhandle,
- &node->prev->certKey);
- }
- CERT_UnlockDB(cert->dbhandle);
-
- return(retcert);
-}
-
-SECStatus
-CERT_SaveImportedCert(CERTCertificate *cert, SECCertUsage usage,
- PRBool caOnly, char *nickname)
-{
- SECStatus rv;
- PRBool saveit;
- CERTCertTrust trust;
- CERTCertTrust tmptrust;
- PRBool isCA;
- unsigned int certtype;
- PRBool freeNickname = PR_FALSE;
-
- isCA = CERT_IsCACert(cert, NULL);
- if ( caOnly && ( !isCA ) ) {
- return(SECSuccess);
- }
-
- saveit = PR_TRUE;
-
- PORT_Memset((void *)&trust, 0, sizeof(trust));
-
- certtype = cert->nsCertType;
-
- /* if no CA bits in cert type, then set all CA bits */
- if ( isCA && ( ! ( certtype & NS_CERT_TYPE_CA ) ) ) {
- certtype |= NS_CERT_TYPE_CA;
- }
-
- /* if no app bits in cert type, then set all app bits */
- if ( ( !isCA ) && ( ! ( certtype & NS_CERT_TYPE_APP ) ) ) {
- certtype |= NS_CERT_TYPE_APP;
- }
-
- if ( isCA && !nickname ) {
- nickname = CERT_MakeCANickname(cert);
- if ( nickname != NULL ) {
- freeNickname = PR_TRUE;
- }
- }
-
- switch ( usage ) {
- case certUsageEmailSigner:
- case certUsageEmailRecipient:
- if ( isCA ) {
- if ( certtype & NS_CERT_TYPE_EMAIL_CA ) {
- trust.emailFlags = CERTDB_VALID_CA;
- }
- } else {
- PORT_Assert(nickname == NULL);
-
- if ( cert->emailAddr == NULL ) {
- saveit = PR_FALSE;
- }
-
- if ( certtype & NS_CERT_TYPE_EMAIL ) {
- trust.emailFlags = CERTDB_VALID_PEER;
- if ( ! ( cert->rawKeyUsage & KU_KEY_ENCIPHERMENT ) ) {
- /* don't save it if KeyEncipherment is not allowed */
- saveit = PR_FALSE;
- }
- }
- }
- break;
- case certUsageUserCertImport:
- if ( isCA ) {
- if ( certtype & NS_CERT_TYPE_SSL_CA ) {
- trust.sslFlags = CERTDB_VALID_CA;
- }
-
- if ( certtype & NS_CERT_TYPE_EMAIL_CA ) {
- trust.emailFlags = CERTDB_VALID_CA;
- }
-
- if ( certtype & NS_CERT_TYPE_OBJECT_SIGNING_CA ) {
- trust.objectSigningFlags = CERTDB_VALID_CA;
- }
-
- } else {
- if ( certtype & NS_CERT_TYPE_SSL_CLIENT ) {
- trust.sslFlags = CERTDB_VALID_PEER;
- }
-
- if ( certtype & NS_CERT_TYPE_EMAIL ) {
- trust.emailFlags = CERTDB_VALID_PEER;
- }
-
- if ( certtype & NS_CERT_TYPE_OBJECT_SIGNING ) {
- trust.objectSigningFlags = CERTDB_VALID_PEER;
- }
- }
- break;
- case certUsageAnyCA:
- trust.sslFlags = CERTDB_VALID_CA;
- break;
- case certUsageSSLCA:
- trust.sslFlags = CERTDB_VALID_CA |
- CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA;
- break;
- default: /* XXX added to quiet warnings; no other cases needed? */
- break;
- }
-
- if ( saveit ) {
- if ( cert->isperm ) {
- /* Cert already in the DB. Just adjust flags */
- tmptrust = *cert->trust;
- tmptrust.sslFlags |= trust.sslFlags;
- tmptrust.emailFlags |= trust.emailFlags;
- tmptrust.objectSigningFlags |= trust.objectSigningFlags;
-
- rv = CERT_ChangeCertTrust(cert->dbhandle, cert,
- &tmptrust);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- } else {
- /* Cert not already in the DB. Add it */
- rv = CERT_AddTempCertToPerm(cert, nickname, &trust);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- }
- }
-
- rv = SECSuccess;
- goto done;
-
-loser:
- rv = SECFailure;
-done:
-
- if ( freeNickname ) {
- PORT_Free(nickname);
- }
-
- return(rv);
-}
-
-SECStatus
-CERT_ChangeCertTrustByUsage(CERTCertDBHandle *certdb,
- CERTCertificate *cert, SECCertUsage usage)
-{
- SECStatus rv;
- CERTCertTrust trust;
- CERTCertTrust tmptrust;
- unsigned int certtype;
- PRBool saveit;
-
- saveit = PR_TRUE;
-
- PORT_Memset((void *)&trust, 0, sizeof(trust));
-
- certtype = cert->nsCertType;
-
- /* if no app bits in cert type, then set all app bits */
- if ( ! ( certtype & NS_CERT_TYPE_APP ) ) {
- certtype |= NS_CERT_TYPE_APP;
- }
-
- switch ( usage ) {
- case certUsageEmailSigner:
- case certUsageEmailRecipient:
- if ( certtype & NS_CERT_TYPE_EMAIL ) {
- trust.emailFlags = CERTDB_VALID_PEER;
- if ( ! ( cert->rawKeyUsage & KU_KEY_ENCIPHERMENT ) ) {
- /* don't save it if KeyEncipherment is not allowed */
- saveit = PR_FALSE;
- }
- }
- break;
- case certUsageUserCertImport:
- if ( certtype & NS_CERT_TYPE_EMAIL ) {
- trust.emailFlags = CERTDB_VALID_PEER;
- }
- /* VALID_USER is already set if the cert was imported,
- * in the case that the cert was already in the database
- * through SMIME or other means, we should set the USER
- * flags, if they are not already set.
- */
- if( cert->isperm ) {
- if ( certtype & NS_CERT_TYPE_SSL_CLIENT ) {
- if( !(cert->trust->sslFlags & CERTDB_USER) ) {
- trust.sslFlags |= CERTDB_USER;
- }
- }
-
- if ( certtype & NS_CERT_TYPE_EMAIL ) {
- if( !(cert->trust->emailFlags & CERTDB_USER) ) {
- trust.emailFlags |= CERTDB_USER;
- }
- }
-
- if ( certtype & NS_CERT_TYPE_OBJECT_SIGNING ) {
- if( !(cert->trust->objectSigningFlags & CERTDB_USER) ) {
- trust.objectSigningFlags |= CERTDB_USER;
- }
- }
- }
- break;
- default: /* XXX added to quiet warnings; no other cases needed? */
- break;
- }
-
- if ( (trust.sslFlags | trust.emailFlags | trust.objectSigningFlags) == 0 ){
- saveit = PR_FALSE;
- }
-
- if ( saveit && cert->isperm ) {
- /* Cert already in the DB. Just adjust flags */
- tmptrust = *cert->trust;
- tmptrust.sslFlags |= trust.sslFlags;
- tmptrust.emailFlags |= trust.emailFlags;
- tmptrust.objectSigningFlags |= trust.objectSigningFlags;
-
- rv = CERT_ChangeCertTrust(cert->dbhandle, cert,
- &tmptrust);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- }
-
- rv = SECSuccess;
- goto done;
-
-loser:
- rv = SECFailure;
-done:
-
- return(rv);
-}
-
-int
-CERT_GetDBContentVersion(CERTCertDBHandle *handle)
-{
- certDBEntryContentVersion *entry;
- int ret;
-
- entry = ReadDBContentVersionEntry(handle);
-
- if ( entry == NULL ) {
- return(0);
- }
-
- ret = entry->contentVersion;
-
- DestroyDBEntry((certDBEntry *)entry);
-
- return(ret);
-}
-
-void
-CERT_SetDBContentVersion(int version, CERTCertDBHandle *handle)
-{
- SECStatus rv;
- certDBEntryContentVersion *entry;
-
- entry = NewDBContentVersionEntry(0);
-
- if ( entry == NULL ) {
- return;
- }
-
- rv = DeleteDBContentVersionEntry(handle);
- rv = WriteDBContentVersionEntry(handle, entry);
-
- DestroyDBEntry((certDBEntry *)entry);
-
- return;
-}
-
-/*
- * Creates or adds to a list of all certs with a give subject name, sorted by
- * validity time, newest first. Invalid certs are considered older than
- * valid certs. If validOnly is set, do not include invalid certs on list.
- */
-CERTCertList *
-CERT_CreateSubjectCertList(CERTCertList *certList, CERTCertDBHandle *handle,
- SECItem *name, int64 sorttime, PRBool validOnly)
-{
- CERTCertificate *cert = NULL;
- CERTSubjectList *subjectList = NULL;
- CERTSubjectNode *node;
- SECStatus rv;
-
- if ( certList == NULL ) {
- certList = CERT_NewCertList();
- }
-
- if ( certList == NULL ) {
- goto loser;
- }
-
- subjectList = FindSubjectList(handle, name, PR_FALSE);
-
- if ( subjectList != NULL ) {
- node = subjectList->head;
- PORT_Assert(node);
- while (node) {
- cert = CERT_FindCertByKey(handle, &node->certKey);
-
- /* if validOnly, then check validity period before adding to list*/
- if ( ( !validOnly ) ||
- ( CERT_CheckCertValidTimes(cert, sorttime, PR_FALSE)
- == secCertTimeValid ) ) {
- rv = CERT_AddCertToListSorted(certList, cert,
- CERT_SortCBValidity,
- (void *)&sorttime);
- if ( rv != SECSuccess ) {
- CERT_DestroyCertificate(cert);
- goto loser;
- }
- } else {
- CERT_DestroyCertificate(cert);
- }
-
- node = node->next;
- }
- }
-
- return(certList);
-
-loser:
- if ( certList != NULL ) {
- CERT_DestroyCertList(certList);
- }
-
- return(NULL);
-}
-
-/*
- * Creates or adds to a list of all certs with a give nickname, sorted by
- * validity time, newest first. Invalid certs are considered older than valid
- * certs. If validOnly is set, do not include invalid certs on list.
- */
-CERTCertList *
-CERT_CreateNicknameCertList(CERTCertList *certList, CERTCertDBHandle *handle,
- char *nickname, int64 sorttime, PRBool validOnly)
-{
- CERTCertificate *cert;
- CERTCertList *ret;
-
- cert = CERT_FindCertByNickname(handle, nickname);
- if ( cert == NULL ) {
- return(NULL);
- }
-
- ret = CERT_CreateSubjectCertList(certList, handle, &cert->derSubject,
- sorttime, validOnly);
-
- CERT_DestroyCertificate(cert);
-
- return(ret);
-}
-
-/*
- * Creates or adds to a list of all certs with a give email addr, sorted by
- * validity time, newest first. Invalid certs are considered older than valid
- * certs. If validOnly is set, do not include invalid certs on list.
- */
-CERTCertList *
-CERT_CreateEmailAddrCertList(CERTCertList *certList, CERTCertDBHandle *handle,
- char *emailAddr, int64 sorttime, PRBool validOnly)
-{
- CERTCertificate *cert;
- CERTCertList *ret;
-
- cert = CERT_FindCertByEmailAddr(handle, emailAddr);
- if ( cert == NULL ) {
- return(NULL);
- }
-
- ret = CERT_CreateSubjectCertList(certList, handle, &cert->derSubject,
- sorttime, validOnly);
-
- CERT_DestroyCertificate(cert);
-
- return(ret);
-}
diff --git a/security/nss/lib/certdb/stanpcertdb.c b/security/nss/lib/certdb/stanpcertdb.c
index 115442853..fca67551f 100644
--- a/security/nss/lib/certdb/stanpcertdb.c
+++ b/security/nss/lib/certdb/stanpcertdb.c
@@ -51,109 +51,16 @@
#include "plhash.h"
#include "pk11func.h" /* sigh */
-#include "cdbhdl.h"
-
#ifndef NSS_3_4_CODE
#define NSS_3_4_CODE
#endif /* NSS_3_4_CODE */
#include "nsspki.h"
#include "pkit.h"
#include "pkim.h"
-#include "pkinss3hack.h"
+#include "pki3hack.h"
#include "ckhelper.h"
#include "base.h"
-struct stan_cert_callback_str {
- CERTCertCallback callback;
- void *arg;
-};
-
-/* Translate from NSSCertificate to CERTCertificate, then pass the latter
- * to a callback.
- */
-static PRStatus convert_cert(NSSCertificate *c, void *arg)
-{
- CERTCertificate *nss3cert;
- SECStatus secrv;
- struct stan_cert_callback_str *scba = (struct stan_cert_callback_str *)arg;
- nss3cert = STAN_GetCERTCertificate(c);
- if (!nss3cert) return PR_FAILURE;
- secrv = (*scba->callback)(nss3cert, scba->arg);
- CERT_DestroyCertificate(nss3cert);
- return (secrv) ? PR_FAILURE : PR_SUCCESS;
-}
-
-struct stan_cert_der_callback_str {
- SECStatus (* callback)(CERTCertificate *cert, SECItem *k, void *pdata);
- void *arg;
-};
-
-/* Translate from NSSCertificate to CERTCertificate, then pass the latter
- * to a callback.
- */
-static PRStatus convert_cert_der(NSSCertificate *c, void *arg)
-{
- CERTCertificate *nss3cert;
- SECStatus secrv;
- SECItem certKey;
- struct stan_cert_der_callback_str *scdba =
- (struct stan_cert_der_callback_str *)arg;
- nss3cert = STAN_GetCERTCertificate(c);
- if (!nss3cert) return PR_FAILURE;
- SECITEM_FROM_NSSITEM(&certKey, &c->encoding);
- secrv = (*scdba->callback)(nss3cert, &certKey, scdba->arg);
- CERT_DestroyCertificate(nss3cert);
- return (secrv) ? PR_FAILURE : PR_SUCCESS;
-}
-
-
-SECStatus
-__CERT_TraversePermCertsForSubject(CERTCertDBHandle *handle,
- SECItem *derSubject,
- CERTCertCallback cb, void *cbarg)
-{
- struct stan_cert_callback_str scba;
- PRStatus nssrv;
- NSSDER subject;
- scba.callback = cb;
- scba.arg = cbarg;
- NSSITEM_FROM_SECITEM(&subject, derSubject);
- nssrv = nssTrustDomain_TraverseCertificatesBySubject(handle,
- &subject,
- convert_cert,
- &scba);
- return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
-}
-
-SECStatus
-CERT_TraversePermCertsForSubject(CERTCertDBHandle *handle, SECItem *derSubject,
- CERTCertCallback cb, void *cbarg)
-{
- return(__CERT_TraversePermCertsForSubject(handle, derSubject, cb, cbarg));
-}
-
-SECStatus
-__CERT_TraversePermCertsForNickname(CERTCertDBHandle *handle, char *nickname,
- CERTCertCallback cb, void *cbarg)
-{
- struct stan_cert_callback_str scba;
- PRStatus nssrv;
- scba.callback = cb;
- scba.arg = cbarg;
- nssrv = nssTrustDomain_TraverseCertificatesByNickname(handle,
- (NSSUTF8 *)nickname,
- convert_cert,
- &scba);
- return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
-}
-
-SECStatus
-CERT_TraversePermCertsForNickname(CERTCertDBHandle *handle, char *nickname,
- CERTCertCallback cb, void *cbarg)
-{
- return(__CERT_TraversePermCertsForNickname(handle, nickname, cb, cbarg));
-}
-
PRBool
SEC_CertNicknameConflict(char *nickname, SECItem *derSubject,
CERTCertDBHandle *handle)
@@ -172,33 +79,6 @@ SEC_DeletePermCertificate(CERTCertificate *cert)
}
SECStatus
-SEC_TraversePermCerts(CERTCertDBHandle *handle,
- SECStatus (* certfunc)(CERTCertificate *cert, SECItem *k,
- void *pdata),
- void *udata )
-{
- struct stan_cert_der_callback_str scdba;
- PRStatus nssrv;
- scdba.callback = certfunc;
- scdba.arg = udata;
- nssrv = nssTrustDomain_TraverseCertificates(handle,
- convert_cert_der, &scdba);
- return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
-}
-
-void
-__CERT_ClosePermCertDB(CERTCertDBHandle *handle)
-{
- /* XXX do anything? */
-}
-
-void
-CERT_ClosePermCertDB(CERTCertDBHandle *handle)
-{
- __CERT_ClosePermCertDB(handle);
-}
-
-SECStatus
CERT_GetCertTrust(CERTCertificate *cert, CERTCertTrust *trust)
{
SECStatus rv;
@@ -227,12 +107,12 @@ SECStatus
CERT_ChangeCertTrust(CERTCertDBHandle *handle, CERTCertificate *cert,
CERTCertTrust *trust)
{
- SECStatus ret;
- CERT_LockDB(handle);
+ SECStatus rv = SECFailure;
+ PRStatus ret;
+
CERT_LockCertTrust(cert);
/* only set the trust on permanent certs */
if ( cert->trust == NULL ) {
- ret = SECFailure;
goto done;
}
if (PK11_IsReadOnly(cert->slot)) {
@@ -240,13 +120,13 @@ CERT_ChangeCertTrust(CERTCertDBHandle *handle, CERTCertificate *cert,
/* XXX store it on a writeable token */
goto done;
} else {
- STAN_ChangeCertTrust(cert->nssCertificate, trust);
+ NSSCertificate *c = STAN_GetNSSCertificate(cert);
+ ret = STAN_ChangeCertTrust(c, trust);
+ rv = (ret == PR_SUCCESS) ? SECSuccess : SECFailure;
}
- ret = SECSuccess;
done:
CERT_UnlockCertTrust(cert);
- CERT_UnlockDB(handle);
- return(ret);
+ return rv;
}
SECStatus
@@ -254,9 +134,12 @@ CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
CERTCertTrust *trust)
{
NSSCertificate *c = STAN_GetNSSCertificate(cert);
+#ifdef notdef
/* might as well keep these */
+ /* actually we shouldn't keep these! rjr */
PORT_Assert(cert->istemp);
PORT_Assert(!cert->isperm);
+#endif
if (SEC_CertNicknameConflict(nickname, &cert->derSubject, cert->dbhandle)){
return SECFailure;
}
@@ -277,20 +160,6 @@ CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
return SECFailure;
}
-SECStatus
-CERT_OpenCertDBFilename(CERTCertDBHandle *handle, char *certdbname,
- PRBool readOnly)
-{
- /* XXX what to do here? */
-}
-
-/* only for jarver.c */
-SECStatus
-SEC_AddTempNickname(CERTCertDBHandle *handle, char *nickname,
- SECItem *subjectName)
-{
-}
-
CERTCertificate *
__CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
char *nickname, PRBool isperm, PRBool copyDER)
@@ -329,10 +198,11 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
PORT_Strlen(cc->emailAddr));
}
c->trustDomain = handle;
+ cc->dbhandle = handle;
nssTrustDomain_AddCertsToCache(handle, &c, 1);
cc->istemp = 1;
cc->isperm = 0;
- /* XXX if !copyDER destroy it? */
+
return cc;
loser:
nssArena_Destroy(arena);
@@ -348,26 +218,18 @@ CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
}
/* maybe all the wincx's should be some const for internal token login? */
-
-CERTCertificate *
-CERT_FindCertByKey(CERTCertDBHandle *handle, SECItem *certKey)
-{
-}
-
-/*
- * Lookup a certificate in the databases without locking
- */
-CERTCertificate *
-CERT_FindCertByKeyNoLocking(CERTCertDBHandle *handle, SECItem *certKey)
-{
- return(CERT_FindCertByKey(handle, certKey));
-}
-
CERTCertificate *
CERT_FindCertByIssuerAndSN(CERTCertDBHandle *handle, CERTIssuerAndSN *issuerAndSN)
{
PK11SlotInfo *slot;
- return PK11_FindCertByIssuerAndSN(&slot, issuerAndSN, NULL);
+ CERTCertificate *cert;
+
+ cert = PK11_FindCertByIssuerAndSN(&slot,issuerAndSN,NULL);
+ if (slot) {
+ PK11_FreeSlot(slot);
+ }
+
+ return cert;
}
CERTCertificate *
@@ -383,10 +245,23 @@ CERT_FindCertByName(CERTCertDBHandle *handle, SECItem *name)
return STAN_GetCERTCertificate(c);
}
-/* this one is gonna be tough ... looks like traversal */
CERTCertificate *
CERT_FindCertByKeyID(CERTCertDBHandle *handle, SECItem *name, SECItem *keyID)
{
+ CERTCertList *list =
+ CERT_CreateSubjectCertList(NULL,handle,name,0,PR_FALSE);
+ CERTCertificate *cert = NULL;
+ CERTCertListNode *node = CERT_LIST_HEAD(list);
+
+ if (list == NULL) return NULL;
+
+ for (node = CERT_LIST_HEAD(list); node ; node = CERT_LIST_NEXT(node)) {
+ if (SECITEM_ItemsAreEqual(&cert->subjectKeyID, keyID) ) {
+ cert = CERT_DupCertificate(node->cert);
+ break;
+ }
+ }
+ return cert;
}
CERTCertificate *
@@ -468,12 +343,6 @@ loser:
return NULL;
}
-SECStatus
-CERT_DeleteTempCertificate(CERTCertificate *cert)
-{
- /* remove from cache */
-}
-
void
CERT_DestroyCertificate(CERTCertificate *cert)
{
@@ -488,7 +357,7 @@ CERT_DestroyCertificate(CERTCertificate *cert)
if ( ( refCount == 0 ) && !cert->keepSession ) {
PRArenaPool *arena = cert->arena;
if ( cert->istemp ) {
- CERT_DeleteTempCertificate(cert);
+ /* uncache the cert ? */
}
/* delete the NSSCertificate */
/* zero cert before freeing. Any stale references to this cert
@@ -502,144 +371,7 @@ CERT_DestroyCertificate(CERTCertificate *cert)
return;
}
-SECStatus
-CERT_SaveImportedCert(CERTCertificate *cert, SECCertUsage usage,
- PRBool caOnly, char *nickname)
-{
- SECStatus rv;
- PRBool saveit;
- CERTCertTrust trust;
- CERTCertTrust tmptrust;
- PRBool isCA;
- unsigned int certtype;
- PRBool freeNickname = PR_FALSE;
-
- isCA = CERT_IsCACert(cert, NULL);
- if ( caOnly && ( !isCA ) ) {
- return(SECSuccess);
- }
-
- saveit = PR_TRUE;
-
- PORT_Memset((void *)&trust, 0, sizeof(trust));
-
- certtype = cert->nsCertType;
-
- /* if no CA bits in cert type, then set all CA bits */
- if ( isCA && ( ! ( certtype & NS_CERT_TYPE_CA ) ) ) {
- certtype |= NS_CERT_TYPE_CA;
- }
-
- /* if no app bits in cert type, then set all app bits */
- if ( ( !isCA ) && ( ! ( certtype & NS_CERT_TYPE_APP ) ) ) {
- certtype |= NS_CERT_TYPE_APP;
- }
-
- if ( isCA && !nickname ) {
- nickname = CERT_MakeCANickname(cert);
- if ( nickname != NULL ) {
- freeNickname = PR_TRUE;
- }
- }
-
- switch ( usage ) {
- case certUsageEmailSigner:
- case certUsageEmailRecipient:
- if ( isCA ) {
- if ( certtype & NS_CERT_TYPE_EMAIL_CA ) {
- trust.emailFlags = CERTDB_VALID_CA;
- }
- } else {
- PORT_Assert(nickname == NULL);
-
- if ( cert->emailAddr == NULL ) {
- saveit = PR_FALSE;
- }
-
- if ( certtype & NS_CERT_TYPE_EMAIL ) {
- trust.emailFlags = CERTDB_VALID_PEER;
- if ( ! ( cert->rawKeyUsage & KU_KEY_ENCIPHERMENT ) ) {
- /* don't save it if KeyEncipherment is not allowed */
- saveit = PR_FALSE;
- }
- }
- }
- break;
- case certUsageUserCertImport:
- if ( isCA ) {
- if ( certtype & NS_CERT_TYPE_SSL_CA ) {
- trust.sslFlags = CERTDB_VALID_CA;
- }
-
- if ( certtype & NS_CERT_TYPE_EMAIL_CA ) {
- trust.emailFlags = CERTDB_VALID_CA;
- }
-
- if ( certtype & NS_CERT_TYPE_OBJECT_SIGNING_CA ) {
- trust.objectSigningFlags = CERTDB_VALID_CA;
- }
-
- } else {
- if ( certtype & NS_CERT_TYPE_SSL_CLIENT ) {
- trust.sslFlags = CERTDB_VALID_PEER;
- }
-
- if ( certtype & NS_CERT_TYPE_EMAIL ) {
- trust.emailFlags = CERTDB_VALID_PEER;
- }
-
- if ( certtype & NS_CERT_TYPE_OBJECT_SIGNING ) {
- trust.objectSigningFlags = CERTDB_VALID_PEER;
- }
- }
- break;
- case certUsageAnyCA:
- trust.sslFlags = CERTDB_VALID_CA;
- break;
- case certUsageSSLCA:
- trust.sslFlags = CERTDB_VALID_CA |
- CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA;
- break;
- default: /* XXX added to quiet warnings; no other cases needed? */
- break;
- }
-
- if ( saveit ) {
- if ( cert->isperm ) {
- /* Cert already in the DB. Just adjust flags */
- tmptrust = *cert->trust;
- tmptrust.sslFlags |= trust.sslFlags;
- tmptrust.emailFlags |= trust.emailFlags;
- tmptrust.objectSigningFlags |= trust.objectSigningFlags;
-
- rv = CERT_ChangeCertTrust(cert->dbhandle, cert,
- &tmptrust);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- } else {
- /* Cert not already in the DB. Add it */
- rv = CERT_AddTempCertToPerm(cert, nickname, &trust);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- }
- }
-
- rv = SECSuccess;
- goto done;
-
-loser:
- rv = SECFailure;
-done:
-
- if ( freeNickname ) {
- PORT_Free(nickname);
- }
-
- return(rv);
-}
-
+#ifdef notdef
SECStatus
CERT_ChangeCertTrustByUsage(CERTCertDBHandle *certdb,
CERTCertificate *cert, SECCertUsage usage)
@@ -732,11 +464,13 @@ done:
return(rv);
}
+#endif
int
CERT_GetDBContentVersion(CERTCertDBHandle *handle)
{
- /* do anything? */
+ /* should read the DB content version from the pkcs #11 device */
+ return 0;
}
/*
@@ -749,649 +483,135 @@ SECStatus
CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile,
SECItem *profileTime)
{
-}
-
-SECItem *
-CERT_FindSMimeProfile(CERTCertificate *cert)
-{
-}
-
-/*
- *
- * Manage CRL's
- *
- */
-
-/* only for crlutil.c */
-CERTSignedCrl *
-SEC_FindCrlByKey(CERTCertDBHandle *handle, SECItem *crlKey, int type)
-{
-}
-
-CERTSignedCrl *
-SEC_FindCrlByName(CERTCertDBHandle *handle, SECItem *crlKey, int type)
-{
-}
-
-SECStatus
-SEC_DestroyCrl(CERTSignedCrl *crl)
-{
-}
-
-CERTSignedCrl *
-cert_DBInsertCRL (CERTCertDBHandle *handle, char *url,
- CERTSignedCrl *newCrl, SECItem *derCrl, int type)
-{
- CERTSignedCrl *oldCrl = NULL, *crl = NULL;
- PRArenaPool *arena = NULL;
- SECCertTimeValidity validity;
- /*
- certDBEntryType crlType = (type == SEC_CRL_TYPE) ?
- certDBEntryTypeRevocation : certDBEntryTypeKeyRevocation;
- */
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) goto done;
-
- validity = SEC_CheckCrlTimes(&newCrl->crl,PR_Now());
- if ( validity == secCertTimeExpired) {
- if (type == SEC_CRL_TYPE) {
- PORT_SetError(SEC_ERROR_CRL_EXPIRED);
- } else {
- PORT_SetError(SEC_ERROR_KRL_EXPIRED);
- }
- goto done;
- } else if (validity == secCertTimeNotValidYet) {
- if (type == SEC_CRL_TYPE) {
- PORT_SetError(SEC_ERROR_CRL_NOT_YET_VALID);
- } else {
- PORT_SetError(SEC_ERROR_KRL_NOT_YET_VALID);
- }
- goto done;
+ int64 oldtime;
+ int64 newtime;
+ SECStatus rv = SECFailure;
+ PRBool saveit;
+ char *emailAddr;
+ SECItem *oldProfile = NULL;
+ SECItem *oldProfileTime = NULL;
+ PK11SlotInfo *slot = NULL;
+
+ emailAddr = cert->emailAddr;
+
+ PORT_Assert(emailAddr);
+ if ( emailAddr == NULL ) {
+ goto loser;
}
- oldCrl = SEC_FindCrlByKey(handle, &newCrl->crl.derName, type);
-
- /* if there is an old crl, make sure the one we are installing
- * is newer. If not, exit out, otherwise delete the old crl.
- */
- if (oldCrl != NULL) {
- if (!SEC_CrlIsNewer(&newCrl->crl,&oldCrl->crl)) {
-
- if (type == SEC_CRL_TYPE) {
- PORT_SetError(SEC_ERROR_OLD_CRL);
+ saveit = PR_FALSE;
+
+ oldProfile = PK11_FindSMimeProfile(&slot, emailAddr, &cert->derSubject,
+ &oldProfileTime);
+
+ /* both profileTime and emailProfile have to exist or not exist */
+ if ( emailProfile == NULL ) {
+ profileTime = NULL;
+ } else if ( profileTime == NULL ) {
+ emailProfile = NULL;
+ }
+
+ if ( oldProfileTime == NULL ) {
+ saveit = PR_TRUE;
+ } else {
+ /* there was already a profile for this email addr */
+ if ( profileTime ) {
+ /* we have an old and new profile - save whichever is more recent*/
+ if ( oldProfileTime->len == 0 ) {
+ /* always replace if old entry doesn't have a time */
+ oldtime = LL_MININT;
} else {
- PORT_SetError(SEC_ERROR_OLD_KRL);
+ rv = DER_UTCTimeToTime(&oldtime, oldProfileTime);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
}
-
- goto done;
- }
-
- if ((SECITEM_CompareItem(&newCrl->crl.derName,
- &oldCrl->crl.derName) != SECEqual) &&
- (type == SEC_KRL_TYPE) ) {
- PORT_SetError(SEC_ERROR_CKL_CONFLICT);
- goto done;
- }
-
- /* if we have a url in the database, use that one */
- if (oldCrl->url) {
- int nnlen = PORT_Strlen(oldCrl->url) + 1;
- url = (char *)PORT_ArenaAlloc(arena, nnlen);
- if ( url != NULL ) {
- PORT_Memcpy(url, oldCrl->url, nnlen);
+ rv = DER_UTCTimeToTime(&newtime, profileTime);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ if ( LL_CMP(newtime, >, oldtime ) ) {
+ /* this is a newer profile, save it and cert */
+ saveit = PR_TRUE;
}
- }
-
-
- /* really destroy this crl */
- /* first drum it out of the permanment Data base */
- SEC_DeletePermCRL(oldCrl);
- /* then get rid of our reference to it... */
- SEC_DestroyCrl(oldCrl);
- oldCrl = NULL;
-
- }
-
- /* Write the new entry into the data base */
-#ifdef KNOW_HOW_TO_WRITE_CRL_TO_TOKEN
- entry = NewDBCrlEntry(derCrl, url, crlType, 0);
- if (entry == NULL) goto done;
-
- rv = WriteDBCrlEntry(handle, entry);
- if (rv != SECSuccess) goto done;
-
- crl = SEC_AddPermCrlToTemp(handle, entry);
- if (crl) entry = NULL; /*crl->dbEntry now points to entry data */
- crl->isperm = PR_TRUE;
-#endif /* KNOW_HOW_TO_WRITE_CRL_TO_TOKEN */
-
-done:
- if (arena) PORT_FreeArena(arena, PR_FALSE);
- if (oldCrl) SEC_DestroyCrl(oldCrl);
-
- return crl;
-}
-
-
-/*
- * create a new CRL from DER material.
- *
- * The signature on this CRL must be checked before you
- * load it. ???
- */
-CERTSignedCrl *
-SEC_NewCrl(CERTCertDBHandle *handle, char *url, SECItem *derCrl, int type)
-{
- CERTSignedCrl *newCrl = NULL, *crl = NULL;
-
- /* make this decode dates! */
- newCrl = CERT_DecodeDERCrl(NULL, derCrl, type);
- if (newCrl == NULL) {
- if (type == SEC_CRL_TYPE) {
- PORT_SetError(SEC_ERROR_CRL_INVALID);
} else {
- PORT_SetError(SEC_ERROR_KRL_INVALID);
+ saveit = PR_TRUE;
}
- goto done;
}
- crl = cert_DBInsertCRL (handle, url, newCrl, derCrl, type);
-
-
-done:
- if (newCrl) PORT_FreeArena(newCrl->arena, PR_FALSE);
-
- return crl;
-}
-
-SECStatus
-SEC_LookupCrls(CERTCertDBHandle *handle, CERTCrlHeadNode **nodes, int type)
-{
-}
-
-SECStatus
-SEC_DeletePermCRL(CERTSignedCrl *crl)
-{
-}
-/*
- *
- * SPK Digest code, unmodified from pcertdb.c
- *
- */
-
-/*
- * The following is bunch of types and code to allow looking up a certificate
- * by a hash of its subject public key. Because the words "hash" and "key"
- * are overloaded and thus terribly confusing, I tried to disambiguate things.
- * - Where I could, I used "digest" instead of "hash" when referring to
- * hashing of the subject public key. The PLHashTable interfaces and
- * our own HASH_Foo interfaces had to be left as is, obviously. The latter
- * should be thought of as "digest" in this case.
- * - There are three keys in use here -- the subject public key, the key
- * used to do a lookup in the PLHashTable, and the key used to do a lookup
- * in the cert database. As the latter is a fairly pervasive interface,
- * I left it alone. The other two uses I changed to "spk" or "SPK" when
- * referring to the subject public key, and "index" when referring to the
- * key into the PLHashTable.
- */
-
-typedef struct SPKDigestInfoStr {
- PLHashTable *table;
- PRBool permPopulated;
-} SPKDigestInfo;
-
-/*
- * Since the key hash information is "hidden" (in a void pointer in the handle)
- * these macros with the appropriate casts make it easy to get at the parts.
- */
-#define SPK_DIGEST_TABLE(handle) \
- (((SPKDigestInfo *)(handle->spkDigestInfo))->table)
-
-/*
-** Hash allocator ops for the SPKDigest hash table. The rules are:
-** + The index and value fields are "owned" by the hash table, and are
-** freed when the table entry is deleted.
-** + Replacing a value in the table is not allowed, since the caller can't
-** tell whether the index field was used or not, resulting in a memory
-** leak. (This is a bug in the PL_Hash routines.
-*/
-static void * PR_CALLBACK
-spkAllocTable(void *pool, PRSize size)
-{
-#if defined(XP_MAC)
-#pragma unused (pool)
-#endif
- return PR_MALLOC(size);
-}
-
-static void PR_CALLBACK
-spkFreeTable(void *pool, void *item)
-{
-#if defined(XP_MAC)
-#pragma unused (pool)
-#endif
- PR_Free(item);
-}
-
-/* NOTE: the key argument here appears to be useless, since the RawAdd
- * routine in PL_Hash just uses the original anyway.
- */
-static PLHashEntry * PR_CALLBACK
-spkAllocEntry(void *pool, const void *key)
-{
-#if defined(XP_MAC)
-#pragma unused (pool,key)
-#endif
- return PR_NEW(PLHashEntry);
-}
-
-static void PR_CALLBACK
-spkFreeEntry(void *pool, PLHashEntry *he, PRUintn flag)
-{
-#if defined(XP_MAC)
-#pragma unused (pool)
-#endif
- SECItem *value = (SECItem *)he->value;
- /* The flag should always be to free the whole entry. Otherwise the
- * index field gets leaked because the caller can't tell whether
- * the "new" value (which is the same as the old) was used or not.
- */
- PORT_Assert(flag == HT_FREE_ENTRY);
- /* We always free the value */
- SECITEM_FreeItem(value, PR_TRUE);
- if (flag == HT_FREE_ENTRY)
- {
- /* Comes from BTOA, is this the right free call? */
- PORT_Free((char *)he->key);
- PR_Free(he);
+ if (saveit) {
+ rv = PK11_SaveSMimeProfile(slot, emailAddr, &cert->derSubject,
+ emailProfile, profileTime);
+ } else {
+ rv = SECSuccess;
}
-}
-
-static PLHashAllocOps spkHashAllocOps = {
- spkAllocTable, spkFreeTable,
- spkAllocEntry, spkFreeEntry
-};
-/*
- * Create the key hash lookup table. Note that the table, and the
- * structure which holds it and a little more information, is never freed.
- * This is because the temporary database is never actually closed out,
- * so there is no safe/obvious place to free the whole thing.
- *
- * The database must be locked already.
- */
-static SECStatus
-InitDBspkDigestInfo(CERTCertDBHandle *handle)
-{
- SPKDigestInfo *spkDigestInfo;
- PLHashTable *table;
- PORT_Assert(handle != NULL);
- PORT_Assert(handle->spkDigestInfo == NULL);
- spkDigestInfo = PORT_ZAlloc(sizeof(SPKDigestInfo));
- if ( spkDigestInfo == NULL ) {
- return(SECFailure);
- }
- table = PL_NewHashTable(128, PL_HashString, PL_CompareStrings,
- (PLHashComparator) SECITEM_ItemsAreEqual,
- &spkHashAllocOps, NULL);
- if ( table == NULL ) {
- PORT_Free(spkDigestInfo);
- return(SECFailure);
+loser:
+ if (oldProfile) {
+ SECITEM_FreeItem(oldProfile,PR_TRUE);
}
- spkDigestInfo->table = table;
- handle->spkDigestInfo = spkDigestInfo;
- return(SECSuccess);
-}
-
-static const SECHashObject *
-OidTagToRawDigestObject(SECOidTag digestAlg)
-{
- const SECHashObject *rawDigestObject;
- switch (digestAlg) {
- case SEC_OID_MD2:
- rawDigestObject = &SECRawHashObjects[HASH_AlgMD2];
- break;
- case SEC_OID_MD5:
- rawDigestObject = &SECRawHashObjects[HASH_AlgMD5];
- break;
- case SEC_OID_SHA1:
- rawDigestObject = &SECRawHashObjects[HASH_AlgSHA1];
- break;
- default:
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- rawDigestObject = NULL;
- break;
+ if (oldProfileTime) {
+ SECITEM_FreeItem(oldProfileTime,PR_TRUE);
}
- return(rawDigestObject);
+
+ return(rv);
}
-/*
- * Digest the cert's subject public key using the specified algorithm.
- * The necessary storage for the digest data is allocated. If "fill" is
- * non-null, the data is put there, otherwise a SECItem is allocated.
- * Allocation from "arena" if it is non-null, heap otherwise. Any problem
- * results in a NULL being returned (and an appropriate error set).
- */
SECItem *
-CERT_SPKDigestValueForCert(PRArenaPool *arena, CERTCertificate *cert,
- SECOidTag digestAlg, SECItem *fill)
-{
- const SECHashObject *digestObject;
- void *digestContext;
- SECItem *result = NULL;
- void *mark = NULL;
- SECItem spk;
- if ( arena != NULL ) {
- mark = PORT_ArenaMark(arena);
- }
- /*
- * This can end up being called before PKCS #11 is initialized,
- * so we have to use the raw digest functions.
- */
- digestObject = OidTagToRawDigestObject(digestAlg);
- if ( digestObject == NULL ) {
- goto loser;
- }
- result = SECITEM_AllocItem(arena, fill, digestObject->length);
- if ( result == NULL ) {
- goto loser;
- }
- /*
- * Copy just the length and data pointer (nothing needs to be freed)
- * of the subject public key so we can convert the length from bits
- * to bytes, which is what the digest function expects.
- */
- spk = cert->subjectPublicKeyInfo.subjectPublicKey;
- DER_ConvertBitString(&spk);
- /*
- * Now digest the value, using the specified algorithm.
- */
- digestContext = digestObject->create();
- if ( digestContext == NULL ) {
- goto loser;
- }
- digestObject->begin(digestContext);
- digestObject->update(digestContext, spk.data, spk.len);
- digestObject->end(digestContext, result->data, &(result->len), result->len);
- digestObject->destroy(digestContext, PR_TRUE);
- if ( arena != NULL ) {
- PORT_ArenaUnmark(arena, mark);
- }
- return(result);
-loser:
- if ( arena != NULL ) {
- PORT_ArenaRelease(arena, mark);
- } else {
- if ( result != NULL ) {
- SECITEM_FreeItem(result, (fill == NULL) ? PR_TRUE : PR_FALSE);
- }
- }
- return(NULL);
-}
-
-/*
- * Return the index for the spk digest lookup table for "spkDigest".
- *
- * Caller is responsible for freeing the returned string.
- */
-static char *
-spkDigestIndexFromDigest(SECItem *spkDigest)
+CERT_FindSMimeProfile(CERTCertificate *cert)
{
- return BTOA_ConvertItemToAscii(spkDigest);
+ return
+ PK11_FindSMimeProfile(NULL, cert->emailAddr, &cert->derSubject, NULL);
}
/*
- * Return the index for the spk digest lookup table for this certificate,
- * based on the specified digest algorithm.
- *
- * Caller is responsible for freeing the returned string.
+ * depricated functions that are now just stubs.
*/
-static char *
-spkDigestIndexFromCert(CERTCertificate *cert, SECOidTag digestAlg)
-{
- SECItem *spkDigest;
- char *index;
- spkDigest = CERT_SPKDigestValueForCert(NULL, cert, digestAlg, NULL);
- if ( spkDigest == NULL )
- return(NULL);
- index = spkDigestIndexFromDigest(spkDigest);
- SECITEM_FreeItem(spkDigest, PR_TRUE);
- return(index);
-}
-
/*
- * Add the spk digest for the given cert to the spk digest table,
- * based on the given digest algorithm.
- *
- * If a cert for the same spk digest is already in the table, choose whichever
- * cert is "newer". (The other cert cannot be found via spk digest.)
- *
- * The database must be locked already.
- *
- * XXX Note that this implementation results in leaking the index value.
- * Fixing that did not seem worth the trouble, given we will only leak
- * once per cert. This whole thing should be done differently in the
- * new rewrite (Stan), and then the problem will go away.
+ * Close the database
*/
-static SECStatus
-AddCertToSPKDigestTableForAlg(CERTCertDBHandle *handle, CERTCertificate *cert,
- SECItem *certDBKey, SECOidTag digestAlg)
+void
+__CERT_ClosePermCertDB(CERTCertDBHandle *handle)
{
- SECStatus rv = SECFailure;
- SECItem *oldCertDBKey;
- PRBool addit = PR_TRUE;
- CERTCertificate *oldCert = NULL;
- char *index = NULL;
- PLHashTable *table;
- /*
- * After running some testing doing key hash lookups (like using OCSP),
- * if these are never hit, they can probably be removed.
- */
- PORT_Assert(handle != NULL);
- PORT_Assert(handle == cert->dbhandle);
- PORT_Assert(handle->spkDigestInfo != NULL);
- PORT_Assert((certDBKey == &cert->certKey)
- || (SECITEM_CompareItem(certDBKey,
- &cert->certKey) == SECEqual));
- table = SPK_DIGEST_TABLE(handle);
- PORT_Assert(table != NULL);
- index = spkDigestIndexFromCert(cert, digestAlg);
- if ( index == NULL ) {
- goto loser;
- }
- /*
- * See if this cert's spk digest is already in the table.
- */
- oldCertDBKey = PL_HashTableLookup(table, index);
- if ( oldCertDBKey != NULL ) {
- /*
- * The spk digest *is* already in the table. We need to find that
- * cert and see -- if it is the same, then we can just leave as is.
- * Otherwise we have to choose which cert we want represented;
- * in that case the best plan I can think of is to hang onto the
- * most recent one.
- */
- oldCert = CERT_FindCertByKey(handle, oldCertDBKey);
- if ( oldCert != NULL ) {
- if ( cert == oldCert ) {
- /* They are the same cert, so we are done. */
- addit = PR_FALSE;
- } else if ( CERT_IsNewer(cert, oldCert) ) {
- if ( PL_HashTableRemove(table, index) != PR_TRUE ) {
- goto loser;
- }
- } else {
- /* oldCert is "newer", so we are done. */
- addit = PR_FALSE;
- }
- }
- }
- if ( addit ) {
- certDBKey = SECITEM_DupItem(certDBKey);
- if ( certDBKey == NULL ) {
- goto loser;
- }
- if ( PL_HashTableAdd(table, index, certDBKey) == NULL ) {
- SECITEM_FreeItem(certDBKey, PR_TRUE);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- index = NULL; /* don't want to free it */
- }
- rv = SECSuccess;
-loser:
- if ( index != NULL ) {
- PORT_Free(index);
- }
- if ( oldCert != NULL ) {
- CERT_DestroyCertificate(oldCert);
- }
- return(rv);
+ PORT_Assert("CERT_ClosePermCertDB is Depricated" == NULL);
+ return;
}
-/*
- * Add the spk digest for the given cert to the spk digest table,
- * for all known digest algorithms.
- *
- * The database must be locked already, and the digest table already created.
- */
-static SECStatus
-AddCertToSPKDigestTableForAllAlgs(CERTCertDBHandle *handle,
- CERTCertificate *cert, SECItem *certDBKey)
+SECStatus
+CERT_OpenCertDBFilename(CERTCertDBHandle *handle, char *certdbname,
+ PRBool readOnly)
{
- (void) AddCertToSPKDigestTableForAlg(handle, cert, certDBKey, SEC_OID_MD2);
- (void) AddCertToSPKDigestTableForAlg(handle, cert, certDBKey, SEC_OID_MD5);
- return AddCertToSPKDigestTableForAlg(handle, cert, certDBKey, SEC_OID_SHA1);
+ PORT_Assert("CERT_OpenCertDBFilename is Depricated" == NULL);
+ return SECFailure;
}
-/*
- * Add the spk digest for the given cert to the spk digest table,
- * for all known digest algorithms. This function is called while
- * traversing all of the certs in the permanent database -- since
- * that imposes some constraints on its arguments this routine is a
- * simple cover for the "real" interface.
- *
- * The database must be locked already, and the digest table already created.
- */
-static SECStatus
-AddCertToSPKDigestTableInTraversal(CERTCertificate *cert, SECItem *certDBKey,
- void *data)
+SECItem *
+SECKEY_HashPassword(char *pw, SECItem *salt)
{
- CERTCertDBHandle *handle = data;
- return AddCertToSPKDigestTableForAllAlgs(handle, cert, certDBKey);
+ PORT_Assert("SECKEY_HashPassword is Depricated" == NULL);
+ return NULL;
}
-/*
- * Add the spk digests for the all permanent certs to the spk digest table,
- * for all known digest algorithms.
- *
- * This locks the database, and then checks to make sure that the work
- * actually needs to get done.
- *
- * If the spk digest table does not yet exist, it is created.
- */
-static SECStatus
-PopulateSPKDigestTable(CERTCertDBHandle *handle)
+SECStatus
+__CERT_TraversePermCertsForSubject(CERTCertDBHandle *handle,
+ SECItem *derSubject,
+ void *cb, void *cbarg)
{
- SPKDigestInfo *spkDigestInfo;
- SECStatus rv = SECSuccess;
- CERT_LockDB(handle);
- spkDigestInfo = handle->spkDigestInfo;
- if ( spkDigestInfo == NULL ) {
- rv = InitDBspkDigestInfo(handle);
- if ( rv != SECSuccess ) {
- return(rv);
- }
- spkDigestInfo = handle->spkDigestInfo;
- PORT_Assert(spkDigestInfo != NULL);
- } else {
- /*
- * Check to see if someone already did it; it is important to do
- * this after getting the lock.
- */
- if ( spkDigestInfo->permPopulated == PR_TRUE ) {
- goto done;
- }
- }
- rv = SEC_TraversePermCerts(handle, AddCertToSPKDigestTableInTraversal,
- handle);
- if ( rv != SECSuccess ) {
- goto done;
- }
- spkDigestInfo->permPopulated = PR_TRUE;
-done:
- CERT_UnlockDB(handle);
- return(rv);
+ PORT_Assert("CERT_TraversePermCertsForSubject is Depricated" == NULL);
+ return SECFailure;
}
-/*
- * Lookup a certificate by a digest of a subject public key. If it is
- * found, it is returned (and must then be destroyed by the caller).
- * NULL is returned otherwise -- if there was a problem performing the
- * lookup, an appropriate error is set (e.g. SEC_ERROR_NO_MEMORY);
- * if the cert simply was not found, the error is SEC_ERROR_UNKNOWN_CERT.
- *
- * If the lookup table has not yet been created or populated, do that first.
- */
-CERTCertificate *
-CERT_FindCertBySPKDigest(CERTCertDBHandle *handle, SECItem *spkDigest)
-{
- SPKDigestInfo *spkDigestInfo;
- char *index = NULL;
- SECItem *certDBKey;
- CERTCertificate *cert = NULL;
- PORT_Assert(handle != NULL);
- spkDigestInfo = handle->spkDigestInfo;
- if ( spkDigestInfo == NULL || spkDigestInfo->permPopulated != PR_TRUE ) {
- if ( PopulateSPKDigestTable(handle) != SECSuccess ) {
- goto loser;
- }
- }
- index = spkDigestIndexFromDigest(spkDigest);
- if ( index == NULL ) {
- goto loser;
- }
- certDBKey = PL_HashTableLookup(SPK_DIGEST_TABLE(handle), index);
- if ( certDBKey != NULL ) {
- cert = CERT_FindCertByKey(handle, certDBKey);
- }
- if ( cert == NULL ) {
- PORT_SetError(SEC_ERROR_UNKNOWN_CERT);
- }
-loser:
- if ( index != NULL ) {
- PORT_Free(index);
- }
- return(cert);
-}
-/* XXX
- * XXX
- *
- * These are included for now to allow this to build, but will not be needed
- * once the softoken is below PKCS#11.
- */
SECStatus
-CERT_AddPermNickname(CERTCertificate *cert, char *nickname)
+__CERT_TraversePermCertsForNickname(CERTCertDBHandle *handle, char *nickname,
+ void *cb, void *cbarg)
{
+ PORT_Assert("CERT_TraversePermCertsForNickname is Depricated" == NULL);
+ return SECFailure;
}
-int
-CERT_NumPermCertsForSubject(CERTCertDBHandle *handle, SECItem *derSubject)
-{
-}
-int
-CERT_NumPermCertsForNickname(CERTCertDBHandle *handle, char *nickname)
-{
-}
-SECStatus
-CERT_OpenCertDB(CERTCertDBHandle *handle, PRBool readOnly,
- CERTDBNameFunc namecb, void *cbarg)
-{
- return SECSuccess;
-}
diff --git a/security/nss/lib/certhigh/certhigh.c b/security/nss/lib/certhigh/certhigh.c
index 8a715fafb..62f2b1d88 100644
--- a/security/nss/lib/certhigh/certhigh.c
+++ b/security/nss/lib/certhigh/certhigh.c
@@ -44,7 +44,7 @@
#include "nsspki.h"
#include "pkit.h"
#include "pkitm.h"
-#include "pkinss3hack.h"
+#include "pki3hack.h"
/*
* Find all user certificates that match the given criteria.
@@ -424,18 +424,11 @@ CERT_GetCertNicknames(CERTCertDBHandle *handle, int what, void *wincx)
names->what = what;
names->totallen = 0;
- rv = SEC_TraversePermCerts(handle, CollectNicknames, (void *)names);
+ rv = PK11_TraverseSlotCerts(CollectNicknames, (void *)names, wincx);
if ( rv ) {
goto loser;
}
- if ( wincx != NULL ) {
- rv = PK11_TraverseSlotCerts(CollectNicknames, (void *)names, wincx);
- if ( rv ) {
- goto loser;
- }
- }
-
if ( names->numnicknames ) {
names->nicknames = (char**)PORT_ArenaAlloc(arena,
names->numnicknames * sizeof(char *));
@@ -502,9 +495,7 @@ CollectDistNames( CERTCertificate *cert, SECItem *k, void *data)
trust = cert->trust;
/* only collect names of CAs trusted for issuing SSL clients */
- if ( ( trust->sslFlags &
- ( CERTDB_VALID_CA | CERTDB_TRUSTED_CLIENT_CA ) ) ==
- ( CERTDB_VALID_CA | CERTDB_TRUSTED_CLIENT_CA ) ) {
+ if ( trust->sslFlags & CERTDB_TRUSTED_CLIENT_CA ) {
saveit = PR_TRUE;
}
}
@@ -568,7 +559,7 @@ CERT_GetSSLCACerts(CERTCertDBHandle *handle)
names->names = NULL;
/* collect the names from the database */
- rv = SEC_TraversePermCerts(handle, CollectDistNames, (void *)names);
+ rv = PK11_TraverseSlotCerts(CollectDistNames, (void *)names, NULL);
if ( rv ) {
goto loser;
}
@@ -746,10 +737,12 @@ CERTSignedCrl * CERT_ImportCRL
break;
}
+#ifdef FIXME
/* Do CRL validation and add to the dbase if this crl is more present then the one
in the dbase, if one exists.
*/
crl = cert_DBInsertCRL (handle, url, newCrl, derCRL, type);
+#endif
} while (0);
@@ -763,7 +756,6 @@ cert_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage, PRBool
{
SECStatus rv;
SECItem *derCert;
- SECItem certKey;
PRArenaPool *arena;
CERTCertificate *cert = NULL;
CERTCertificate *newcert = NULL;
@@ -785,22 +777,6 @@ cert_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage, PRBool
while (numcerts--) {
derCert = certs;
certs++;
-
- /* get the key (issuer+cn) from the cert */
- rv = CERT_KeyFromDERCert(arena, derCert, &certKey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* same cert already exists in the database, don't need to do
- * anything more with it
- */
- cert = CERT_FindCertByKey(handle, &certKey);
- if ( cert ) {
- CERT_DestroyCertificate(cert);
- cert = NULL;
- continue;
- }
/* decode my certificate */
newcert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
@@ -864,7 +840,7 @@ cert_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage, PRBool
}
}
- cert = CERT_NewTempCertificate(handle, derCert, NULL, PR_FALSE, PR_TRUE);
+ cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
if ( cert == NULL ) {
goto loser;
}
@@ -872,7 +848,10 @@ cert_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage, PRBool
/* get a default nickname for it */
nickname = CERT_MakeCANickname(cert);
- rv = CERT_AddTempCertToPerm(cert, nickname, &trust);
+ cert->trust = &trust;
+ rv = PK11_ImportCert(PK11_GetInternalKeySlot(), cert,
+ CK_INVALID_HANDLE, nickname, PR_TRUE);
+
/* free the nickname */
if ( nickname ) {
PORT_Free(nickname);
diff --git a/security/nss/lib/certhigh/certvfy.c b/security/nss/lib/certhigh/certvfy.c
index 580aac49f..c23adced7 100644
--- a/security/nss/lib/certhigh/certvfy.c
+++ b/security/nss/lib/certhigh/certvfy.c
@@ -48,7 +48,7 @@
#include "nsspki.h"
#include "pkitm.h"
#include "pkim.h"
-#include "pkinss3hack.h"
+#include "pki3hack.h"
#include "base.h"
#define PENDING_SLOP (24L*60L*60L)
@@ -322,8 +322,6 @@ CERT_FindCertIssuer(CERTCertificate *cert, int64 validTime, SECCertUsage usage)
CERTCertificate * issuerCert = NULL;
SECItem * caName;
PRArenaPool *tmpArena = NULL;
- SECItem issuerCertKey;
- SECStatus rv;
tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
@@ -361,14 +359,16 @@ CERT_FindCertIssuer(CERTCertificate *cert, int64 validTime, SECCertUsage usage)
*/
if (caName != NULL) {
- rv = CERT_KeyFromIssuerAndSN(tmpArena, caName,
- &authorityKeyID->authCertSerialNumber,
- &issuerCertKey);
- if ( rv == SECSuccess ) {
- issuerCert = CERT_FindCertByKey(cert->dbhandle,
- &issuerCertKey);
- }
-
+ CERTIssuerAndSN issuerSN;
+
+ issuerSN.derIssuer.data = caName->data;
+ issuerSN.derIssuer.len = caName->len;
+ issuerSN.serialNumber.data =
+ authorityKeyID->authCertSerialNumber.data;
+ issuerSN.serialNumber.len =
+ authorityKeyID->authCertSerialNumber.len;
+ issuerCert = CERT_FindCertByIssuerAndSN(cert->dbhandle,
+ &issuerSN);
if ( issuerCert == NULL ) {
PORT_SetError (SEC_ERROR_UNKNOWN_ISSUER);
goto loser;
@@ -994,13 +994,15 @@ CERT_VerifyCert(CERTCertDBHandle *handle, CERTCertificate *cert,
PRBool allowOverride;
SECCertTimeValidity validity;
CERTStatusConfig *statusConfig;
-
+
+#ifdef notdef
/* check if this cert is in the Evil list */
rv = CERT_CheckForEvilCert(cert);
if ( rv != SECSuccess ) {
PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE);
LOG_ERROR_OR_EXIT(log,cert,0,0);
}
+#endif
/* make sure that the cert is valid at time t */
allowOverride = (PRBool)((certUsage == certUsageSSLServer) ||
diff --git a/security/nss/lib/certhigh/ocsp.c b/security/nss/lib/certhigh/ocsp.c
index 150977149..2dc75e474 100644
--- a/security/nss/lib/certhigh/ocsp.c
+++ b/security/nss/lib/certhigh/ocsp.c
@@ -653,6 +653,28 @@ ocsp_CreateCertID(PRArenaPool *arena, CERTCertificate *cert, int64 time)
if (rv != SECSuccess) {
goto loser;
}
+ certID->issuerSHA1NameHash.data = certID->issuerNameHash.data;
+ certID->issuerSHA1NameHash.len = certID->issuerNameHash.len;
+ /* cache the other two hash algorithms as well */
+ if (SECITEM_AllocItem(arena, &(certID->issuerMD5NameHash),
+ MD5_LENGTH) == NULL) {
+ goto loser;
+ }
+ rv = PK11_HashBuf(SEC_OID_MD5, certID->issuerMD5NameHash.data,
+ tempItem->data, tempItem->len);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (SECITEM_AllocItem(arena, &(certID->issuerMD2NameHash),
+ MD2_LENGTH) == NULL) {
+ goto loser;
+ }
+ rv = PK11_HashBuf(SEC_OID_MD2, certID->issuerMD2NameHash.data,
+ tempItem->data, tempItem->len);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
SECITEM_FreeItem(tempItem, PR_TRUE);
tempItem = NULL;
@@ -660,6 +682,18 @@ ocsp_CreateCertID(PRArenaPool *arena, CERTCertificate *cert, int64 time)
&(certID->issuerKeyHash)) == NULL) {
goto loser;
}
+ certID->issuerSHA1KeyHash.data = certID->issuerKeyHash.data;
+ certID->issuerSHA1KeyHash.len = certID->issuerKeyHash.len;
+ /* cache the other two hash algorithms as well */
+ if (CERT_SPKDigestValueForCert(arena, issuerCert, SEC_OID_MD5,
+ &(certID->issuerMD5KeyHash)) == NULL) {
+ goto loser;
+ }
+ if (CERT_SPKDigestValueForCert(arena, issuerCert, SEC_OID_MD2,
+ &(certID->issuerMD2KeyHash)) == NULL) {
+ goto loser;
+ }
+
/* now we are done with issuerCert */
CERT_DestroyCertificate(issuerCert);
@@ -2368,6 +2402,40 @@ ocsp_CertHasNoCheckExtension(CERTCertificate *cert)
}
#endif /* LATER */
+static PRBool
+ocsp_matchcert(SECItem *certIndex,CERTCertificate *testCert)
+{
+ SECItem item;
+ unsigned char buf[SHA1_LENGTH]; /* MAX Hash Len */
+
+ item.data = buf;
+ item.len = SHA1_LENGTH;
+
+ if (CERT_SPKDigestValueForCert(NULL,testCert,SEC_OID_SHA1, &item) == NULL) {
+ return PR_FALSE;
+ }
+ if (SECITEM_ItemsAreEqual(certIndex,&item)) {
+ return PR_TRUE;
+ }
+ if (CERT_SPKDigestValueForCert(NULL,testCert,SEC_OID_MD5, &item) == NULL) {
+ return PR_FALSE;
+ }
+ if (SECITEM_ItemsAreEqual(certIndex,&item)) {
+ return PR_TRUE;
+ }
+ if (CERT_SPKDigestValueForCert(NULL,testCert,SEC_OID_MD2, &item) == NULL) {
+ return PR_FALSE;
+ }
+ if (SECITEM_ItemsAreEqual(certIndex,&item)) {
+ return PR_TRUE;
+ }
+
+ return PR_FALSE;
+}
+
+static CERTCertificate *
+ocsp_CertGetDefaultResponder(CERTCertDBHandle *handle,CERTOCSPCertID *certID);
+
/*
* Check the signature on some OCSP data. This is a helper function that
* can be used to check either a request or a response. The result is
@@ -2397,15 +2465,18 @@ ocsp_CheckSignature(ocspSignature *signature, void *tbs,
const SEC_ASN1Template *encodeTemplate,
CERTCertDBHandle *handle, SECCertUsage certUsage,
int64 checkTime, PRBool lookupByName, void *certIndex,
- void *pwArg, CERTCertificate **pSignerCert)
+ void *pwArg, CERTCertificate **pSignerCert,
+ CERTCertificate *issuer)
{
SECItem rawSignature;
SECItem *encodedTBS = NULL;
+ CERTCertificate *responder = NULL;
CERTCertificate *signerCert = NULL;
SECKEYPublicKey *signerKey = NULL;
CERTCertificate **certs = NULL;
SECStatus rv = SECFailure;
int certCount;
+ int i;
/*
* If this signature has already gone through verification, just
@@ -2432,6 +2503,7 @@ ocsp_CheckSignature(ocspSignature *signature, void *tbs,
if (signature->derCerts != NULL) {
for (; signature->derCerts[certCount] != NULL; certCount++) {
/* just counting */
+ /*IMPORT CERT TO SPKI TABLE */
}
}
rv = CERT_ImportCerts(handle, certUsage, certCount,
@@ -2455,7 +2527,22 @@ ocsp_CheckSignature(ocspSignature *signature, void *tbs,
signerCert = CERT_FindCertByName(handle, encodedName);
SECITEM_FreeItem(encodedName, PR_TRUE);
} else {
- signerCert = CERT_FindCertBySPKDigest(handle, certIndex);
+ /*
+ * The signer is either 1) a known issuer CA we passed in,
+ * 2) the default OCSP responder, or 3) and intermediate CA
+ * passed in the cert list to use. Figure out which it is.
+ */
+ responder = ocsp_CertGetDefaultResponder(handle,NULL);
+ if (responder && ocsp_matchcert(certIndex,responder)) {
+ signerCert = CERT_DupCertificate(responder);
+ } else if (issuer && ocsp_matchcert(certIndex,issuer)) {
+ signerCert = CERT_DupCertificate(issuer);
+ }
+ for (i=0; (signerCert == NULL) && (i < certCount); i++) {
+ if (ocsp_matchcert(certIndex,certs[i])) {
+ signerCert = CERT_DupCertificate(certs[i]);
+ }
+ }
}
if (signerCert == NULL) {
@@ -2546,6 +2633,7 @@ finish:
if (certs != NULL)
CERT_DestroyCertArray(certs, certCount);
+ /* Free CERTS from SPKDigest Table */
return rv;
}
@@ -2583,7 +2671,8 @@ finish:
SECStatus
CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
CERTCertDBHandle *handle, void *pwArg,
- CERTCertificate **pSignerCert)
+ CERTCertificate **pSignerCert,
+ CERTCertificate *issuer)
{
ocspResponseData *tbsData; /* this is what is signed */
PRBool byName;
@@ -2623,7 +2712,7 @@ CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
return ocsp_CheckSignature(ocsp_GetResponseSignature(response),
tbsData, ocsp_ResponseDataTemplate,
handle, certUsageStatusResponder, producedAt,
- byName, certIndex, pwArg, pSignerCert);
+ byName, certIndex, pwArg, pSignerCert, issuer);
}
/*
@@ -2635,12 +2724,10 @@ ocsp_CertIDsMatch(CERTCertDBHandle *handle,
CERTOCSPCertID *certID1, CERTOCSPCertID *certID2)
{
PRBool match = PR_FALSE;
- CERTCertificate *issuer1 = NULL;
- CERTCertificate *issuer2 = NULL;
SECItem *foundHash = NULL;
- CERTCertificate *found;
SECOidTag hashAlg;
- SECItem *givenHash;
+ SECItem *keyHash;
+ SECItem *nameHash;
/*
* In order to match, they must have the same issuer and the same
@@ -2668,63 +2755,34 @@ ocsp_CertIDsMatch(CERTCertDBHandle *handle,
goto done;
}
- /*
- * The hash algorithms are different; this is harder. We have
- * to do a lookup of each one and compare them.
- */
- issuer1 = CERT_FindCertBySPKDigest(handle, &certID1->issuerKeyHash);
- issuer2 = CERT_FindCertBySPKDigest(handle, &certID2->issuerKeyHash);
-
- if (issuer1 == NULL && issuer2 == NULL) {
- /* If we cannot find an issuer cert, we have no way to compare. */
- goto done;
- }
-
- if (issuer1 != NULL && issuer2 != NULL) {
- /* If we found a cert for each hash, we can just compare them. */
- if (issuer1 == issuer2)
- match = PR_TRUE;
- goto done;
- }
-
- /*
- * We found one issuer, but not both. So we have to use the other certID
- * hash algorithm on the key in the found issuer cert to see if they match.
- */
-
- if (issuer1 != NULL) {
- found = issuer1;
- hashAlg = SECOID_FindOIDTag(&certID2->hashAlgorithm.algorithm);
- givenHash = &certID2->issuerKeyHash;
- } else {
- found = issuer2;
- hashAlg = SECOID_FindOIDTag(&certID1->hashAlgorithm.algorithm);
- givenHash = &certID1->issuerKeyHash;
+ hashAlg = SECOID_FindOIDTag(&certID2->hashAlgorithm.algorithm);
+ switch (hashAlg) {
+ case SEC_OID_SHA1:
+ keyHash = &certID1->issuerSHA1KeyHash;
+ nameHash = &certID1->issuerSHA1NameHash;
+ break;
+ case SEC_OID_MD5:
+ keyHash = &certID1->issuerMD5KeyHash;
+ nameHash = &certID1->issuerMD5NameHash;
+ break;
+ case SEC_OID_MD2:
+ keyHash = &certID1->issuerMD2KeyHash;
+ nameHash = &certID1->issuerMD2NameHash;
+ break;
+ default:
+ foundHash == NULL;
}
- foundHash = CERT_SPKDigestValueForCert(NULL, found, hashAlg, NULL);
if (foundHash == NULL) {
goto done;
}
- if (SECITEM_CompareItem(foundHash, givenHash) == SECEqual) {
- /*
- * Strictly speaking, we should compare the issuerNameHash, too,
- * but I think the added complexity doesn't actually buy anything.
- */
+ if ((SECITEM_CompareItem(nameHash, &certID2->issuerNameHash) == SECEqual)
+ && (SECITEM_CompareItem(keyHash, &certID2->issuerKeyHash) == SECEqual)) {
match = PR_TRUE;
}
done:
- if (issuer1 != NULL) {
- CERT_DestroyCertificate(issuer1);
- }
- if (issuer2 != NULL) {
- CERT_DestroyCertificate(issuer2);
- }
- if (foundHash != NULL) {
- SECITEM_FreeItem(foundHash, PR_TRUE);
- }
return match;
}
@@ -2788,15 +2846,12 @@ ocsp_GetCheckingContext(CERTCertDBHandle *handle)
return ocspcx;
}
-
/*
* Return true if the given signerCert is the default responder for
* the given certID. If not, or if any error, return false.
*/
-static PRBool
-ocsp_CertIsDefaultResponderForCertID(CERTCertDBHandle *handle,
- CERTCertificate *signerCert,
- CERTOCSPCertID *certID)
+static CERTCertificate *
+ocsp_CertGetDefaultResponder(CERTCertDBHandle *handle,CERTOCSPCertID *certID)
{
ocspCheckingContext *ocspcx;
@@ -2814,12 +2869,26 @@ ocsp_CertIsDefaultResponderForCertID(CERTCertDBHandle *handle,
*/
if (ocspcx->useDefaultResponder) {
PORT_Assert(ocspcx->defaultResponderCert != NULL);
- if (ocspcx->defaultResponderCert == signerCert)
- return PR_TRUE;
+ return ocspcx->defaultResponderCert;
}
loser:
- return PR_FALSE;
+ return NULL;
+}
+
+/*
+ * Return true if the given signerCert is the default responder for
+ * the given certID. If not, or if any error, return false.
+ */
+static PRBool
+ocsp_CertIsDefaultResponderForCertID(CERTCertDBHandle *handle,
+ CERTCertificate *signerCert,
+ CERTOCSPCertID *certID)
+{
+ CERTCertificate *defaultResponderCert;
+
+ defaultResponderCert = ocsp_CertGetDefaultResponder(handle, certID);
+ return (PRBool) (defaultResponderCert == signerCert);
}
/*
@@ -3300,6 +3369,7 @@ CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
CERTOCSPRequest *request = NULL;
CERTOCSPResponse *response = NULL;
CERTCertificate *signerCert = NULL;
+ CERTCertificate *issuerCert = NULL;
ocspResponseData *responseData;
int64 producedAt;
CERTOCSPCertID *certID;
@@ -3413,7 +3483,9 @@ CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
* If we've made it this far, we expect a response with a good signature.
* So, check for that.
*/
- rv = CERT_VerifyOCSPResponseSignature(response, handle, pwArg, &signerCert);
+ issuerCert = CERT_FindCertIssuer(cert, time, certUsageAnyCA);
+ rv = CERT_VerifyOCSPResponseSignature(response, handle, pwArg, &signerCert,
+ issuerCert);
if (rv != SECSuccess)
goto loser;
@@ -3471,6 +3543,8 @@ CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
rv = ocsp_CertHasGoodStatus(single, time);
loser:
+ if (issuerCert != NULL)
+ CERT_DestroyCertificate(issuerCert);
if (signerCert != NULL)
CERT_DestroyCertificate(signerCert);
if (response != NULL)
@@ -3905,3 +3979,97 @@ CERT_DisableOCSPDefaultResponder(CERTCertDBHandle *handle)
statusContext->useDefaultResponder = PR_FALSE;
return SECSuccess;
}
+static const SECHashObject *
+OidTagToDigestObject(SECOidTag digestAlg)
+{
+ const SECHashObject *rawDigestObject;
+
+ switch (digestAlg) {
+ case SEC_OID_MD2:
+ rawDigestObject = &SECHashObjects[HASH_AlgMD2];
+ break;
+ case SEC_OID_MD5:
+ rawDigestObject = &SECHashObjects[HASH_AlgMD5];
+ break;
+ case SEC_OID_SHA1:
+ rawDigestObject = &SECHashObjects[HASH_AlgSHA1];
+ break;
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+ rawDigestObject = NULL;
+ break;
+ }
+ return(rawDigestObject);
+}
+
+/*
+ * Digest the cert's subject public key using the specified algorithm.
+ * The necessary storage for the digest data is allocated. If "fill" is
+ * non-null, the data is put there, otherwise a SECItem is allocated.
+ * Allocation from "arena" if it is non-null, heap otherwise. Any problem
+ * results in a NULL being returned (and an appropriate error set).
+ */
+SECItem *
+CERT_SPKDigestValueForCert(PRArenaPool *arena, CERTCertificate *cert,
+ SECOidTag digestAlg, SECItem *fill)
+{
+ const SECHashObject *digestObject;
+ void *digestContext;
+ SECItem *result = NULL;
+ void *mark = NULL;
+ SECItem spk;
+
+ if ( arena != NULL ) {
+ mark = PORT_ArenaMark(arena);
+ }
+
+ digestObject = OidTagToDigestObject(digestAlg);
+ if ( digestObject == NULL ) {
+ goto loser;
+ }
+
+ if ((fill == NULL) || (fill->data == NULL)) {
+ result = SECITEM_AllocItem(arena, fill, digestObject->length);
+ if ( result == NULL ) {
+ goto loser;
+ }
+ fill = result;
+ }
+
+ /*
+ * Copy just the length and data pointer (nothing needs to be freed)
+ * of the subject public key so we can convert the length from bits
+ * to bytes, which is what the digest function expects.
+ */
+ spk = cert->subjectPublicKeyInfo.subjectPublicKey;
+ DER_ConvertBitString(&spk);
+
+ /*
+ * Now digest the value, using the specified algorithm.
+ */
+ digestContext = digestObject->create();
+ if ( digestContext == NULL ) {
+ goto loser;
+ }
+ digestObject->begin(digestContext);
+ digestObject->update(digestContext, spk.data, spk.len);
+ digestObject->end(digestContext, fill->data, &(fill->len), fill->len);
+ digestObject->destroy(digestContext, PR_TRUE);
+
+ if ( arena != NULL ) {
+ PORT_ArenaUnmark(arena, mark);
+ }
+ return(fill);
+
+loser:
+ if ( arena != NULL ) {
+ PORT_ArenaRelease(arena, mark);
+ } else {
+ if ( result != NULL ) {
+ SECITEM_FreeItem(result, (fill == NULL) ? PR_TRUE : PR_FALSE);
+ }
+ }
+ return(NULL);
+}
+
+
diff --git a/security/nss/lib/certhigh/ocsp.h b/security/nss/lib/certhigh/ocsp.h
index 51f81e867..e4bd7dbdd 100644
--- a/security/nss/lib/certhigh/ocsp.h
+++ b/security/nss/lib/certhigh/ocsp.h
@@ -353,6 +353,8 @@ CERT_GetEncodedOCSPResponse(PRArenaPool *arena, CERTCertList *certList,
* Pointer to CERTCertDBHandle for certificate DB to use for verification.
* void *pwArg
* Pointer to argument for password prompting, if needed.
+ * CERTCertificate *issuerCert
+ * Issuer of the certificate that generated the OCSP request.
* OUTPUTS:
* CERTCertificate **pSignerCert
* Pointer in which to store signer's certificate; only filled-in if
@@ -371,7 +373,8 @@ CERT_GetEncodedOCSPResponse(PRArenaPool *arena, CERTCertList *certList,
extern SECStatus
CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
CERTCertDBHandle *handle, void *pwArg,
- CERTCertificate **pSignerCert);
+ CERTCertificate **pSignerCert,
+ CERTCertificate *issuerCert);
/*
* FUNCTION: CERT_GetOCSPAuthorityInfoAccessLocation
diff --git a/security/nss/lib/certhigh/ocspti.h b/security/nss/lib/certhigh/ocspti.h
index 5f530c4bf..9c739bef4 100644
--- a/security/nss/lib/certhigh/ocspti.h
+++ b/security/nss/lib/certhigh/ocspti.h
@@ -194,6 +194,12 @@ struct CERTOCSPCertIDStr {
SECItem issuerNameHash; /* an OCTET STRING */
SECItem issuerKeyHash; /* an OCTET STRING */
SECItem serialNumber; /* an INTEGER */
+ SECItem issuerSHA1NameHash; /* keep other hashes around when */
+ SECItem issuerMD5NameHash; /* we have them */
+ SECItem issuerMD2NameHash;
+ SECItem issuerSHA1KeyHash; /* keep other hashes around when */
+ SECItem issuerMD5KeyHash; /* we have them */
+ SECItem issuerMD2KeyHash;
};
/*
diff --git a/security/nss/lib/ckfw/ckt.h b/security/nss/lib/ckfw/ckt.h
index 762a70a0b..bf114dbc0 100644
--- a/security/nss/lib/ckfw/ckt.h
+++ b/security/nss/lib/ckfw/ckt.h
@@ -31,169 +31,7 @@
* GPL.
*/
-#ifndef CKT_H
-#define CKT_H
-
-#ifdef DEBUG
-static const char CKT_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
-#endif /* DEBUG */
-
-/*
- * ckt.h
- *
- * This file contains the NSS-specific type definitions for Cryptoki
- * (PKCS#11).
- */
-
-#ifndef NSSCKT_H
-#include "nssckt.h"
-#endif /* NSSCKT_H */
-
-/*
- * NSSCK_VENDOR_NETSCAPE
- *
- * Cryptoki reserves the high half of all the number spaces for
- * vendor-defined use. I'd like to keep all of our Netscape-
- * specific values together, but not in the oh-so-obvious
- * 0x80000001, 0x80000002, etc. area. So I've picked an offset,
- * and constructed values for the beginnings of our spaces.
- *
- * Note that some "historical" Netscape values don't fall within
- * this range.
- */
-#define NSSCK_VENDOR_NETSCAPE 0x4E534350 /* NSCP */
-
-/*
- * Netscape-defined object classes
- *
- */
-#define CKO_NETSCAPE (CKO_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE)
-
-#define CKO_NETSCAPE_CRL (CKO_NETSCAPE + 1)
-#define CKO_NETSCAPE_SMIME (CKO_NETSCAPE + 2)
-#define CKO_NETSCAPE_TRUST (CKO_NETSCAPE + 3)
-#define CKO_NETSCAPE_BUILTIN_ROOT_LIST (CKO_NETSCAPE + 4)
-
-/*
- * Netscape-defined key types
- *
- */
-#define CKK_NETSCAPE (CKK_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE)
-
-#define CKK_NETSCAPE_PKCS8 (CKK_NETSCAPE + 1)
-/*
- * Netscape-defined certificate types
- *
- */
-#define CKC_NETSCAPE (CKC_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE)
-
-/*
- * Netscape-defined object attributes
- *
- */
-#define CKA_NETSCAPE (CKA_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE)
-
-#define CKA_NETSCAPE_URL (CKA_NETSCAPE + 1)
-#define CKA_NETSCAPE_EMAIL (CKA_NETSCAPE + 2)
-#define CKA_NETSCAPE_SMIME_INFO (CKA_NETSCAPE + 3)
-#define CKA_NETSCAPE_SMIME_TIMESTAMP (CKA_NETSCAPE + 4)
-#define CKA_NETSCAPE_PKCS8_SALT (CKA_NETSCAPE + 5)
-#define CKA_NETSCAPE_PASSWORD_CHECK (CKA_NETSCAPE + 6)
-#define CKA_NETSCAPE_EXPIRES (CKA_NETSCAPE + 7)
-
-/*
- * Trust attributes:
- *
- * If trust goes standard, these probably will too. So I'll
- * put them all in one place.
- */
-
-#define CKA_TRUST (CKA_NETSCAPE + 0x2000)
-
-/* "Usage" key information */
-#define CKA_TRUST_DIGITAL_SIGNATURE (CKA_TRUST + 1)
-#define CKA_TRUST_NON_REPUDIATION (CKA_TRUST + 2)
-#define CKA_TRUST_KEY_ENCIPHERMENT (CKA_TRUST + 3)
-#define CKA_TRUST_DATA_ENCIPHERMENT (CKA_TRUST + 4)
-#define CKA_TRUST_KEY_AGREEMENT (CKA_TRUST + 5)
-#define CKA_TRUST_KEY_CERT_SIGN (CKA_TRUST + 6)
-#define CKA_TRUST_CRL_SIGN (CKA_TRUST + 7)
-
-/* "Purpose" trust information */
-#define CKA_TRUST_SERVER_AUTH (CKA_TRUST + 8)
-#define CKA_TRUST_CLIENT_AUTH (CKA_TRUST + 9)
-#define CKA_TRUST_CODE_SIGNING (CKA_TRUST + 10)
-#define CKA_TRUST_EMAIL_PROTECTION (CKA_TRUST + 11)
-#define CKA_TRUST_IPSEC_END_SYSTEM (CKA_TRUST + 12)
-#define CKA_TRUST_IPSEC_TUNNEL (CKA_TRUST + 13)
-#define CKA_TRUST_IPSEC_USER (CKA_TRUST + 14)
-#define CKA_TRUST_TIME_STAMPING (CKA_TRUST + 15)
-#define CKA_CERT_SHA1_HASH (CKA_TRUST + 100)
-#define CKA_CERT_MD5_HASH (CKA_TRUST + 101)
-
-/* Netscape trust stuff */
-/* XXX fgmr new ones here-- step-up, etc. */
-
-/* HISTORICAL: define used to pass in the database key for DSA private keys */
-#define CKA_NETSCAPE_DB 0xD5A0DB00L
-#define CKA_NETSCAPE_TRUST 0x80000001L
-
-/*
- * Netscape-defined crypto mechanisms
- *
- */
-#define CKM_NETSCAPE (CKM_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE)
-/*
- * HISTORICAL:
- * Do not attempt to use these. They are only used by NETSCAPE's internal
- * PKCS #11 interface. Most of these are place holders for other mechanism
- * and will change in the future.
- */
-#define CKM_NETSCAPE_PBE_KEY_GEN 0x80000001L
-#define CKM_NETSCAPE_PBE_SHA1_DES_CBC 0x80000002L
-#define CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC 0x80000003L
-#define CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC 0x80000004L
-#define CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC 0x80000005L
-#define CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4 0x80000006L
-#define CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4 0x80000007L
-#define CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC 0x80000008L
-#define CKM_TLS_MASTER_KEY_DERIVE 0x80000371L
-#define CKM_TLS_KEY_AND_MAC_DERIVE 0x80000372L
-
-/*
- * Netscape-defined return values
- *
- */
-#define CKR_NETSCAPE (CKM_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE)
-
-/*
- * Trust info
- *
- * This isn't part of the Cryptoki standard (yet), so I'm putting
- * all the definitions here. Some of this would move to nssckt.h
- * if trust info were made part of the standard. In view of this
- * possibility, I'm putting my (Netscape) values in the netscape
- * vendor space, like everything else.
- */
-
-typedef CK_ULONG CK_TRUST;
-
-/* The following trust types are defined: */
-#define CKT_VENDOR_DEFINED 0x80000000
-
-#define CKT_NETSCAPE (CKT_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE)
-
-/* If trust goes standard, these'll probably drop out of vendor space. */
-#define CKT_NETSCAPE_TRUSTED (CKT_NETSCAPE + 1)
-#define CKT_NETSCAPE_TRUSTED_DELEGATOR (CKT_NETSCAPE + 2)
-#define CKT_NETSCAPE_UNTRUSTED (CKT_NETSCAPE + 3)
-
-/*
- * These may well remain Netscape-specific; I'm only using them
- * to cache resolution data.
- */
-#define CKT_NETSCAPE_VALID (CKT_NETSCAPE + 4)
-#define CKT_NETSCAPE_VALID_DELEGATOR (CKT_NETSCAPE + 5)
-
-
-#endif /* CKT_H */
+/* get back to just one set of PKCS #11 headers. Use the onese that
+ * are easiest to maintain from the RSA website */
+/* this one is the one that defines NSS specific data */
+#include "pkcs11n.h"
diff --git a/security/nss/lib/ckfw/manifest.mn b/security/nss/lib/ckfw/manifest.mn
index d228e12ab..8a4f15086 100644
--- a/security/nss/lib/ckfw/manifest.mn
+++ b/security/nss/lib/ckfw/manifest.mn
@@ -54,9 +54,7 @@ EXPORTS = \
nssckfwt.h \
nssckg.h \
nssckmdt.h \
- nssckp.h \
nssckt.h \
- nsscku.h \
$(NULL)
MODULE = security
diff --git a/security/nss/lib/ckfw/nssckepv.h b/security/nss/lib/ckfw/nssckepv.h
index 88ff9d773..bfa79ac78 100644
--- a/security/nss/lib/ckfw/nssckepv.h
+++ b/security/nss/lib/ckfw/nssckepv.h
@@ -31,102 +31,4 @@
* may use your version of this file under either the MPL or the
* GPL.
*/
-#ifndef NSSCKEPV_H
-#define NSSCKEPV_H
-
-#ifdef DEBUG
-static const char NSSCKEPV_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$ ; @(#) $RCSfile$ $Revision$ $Date$ $Name$";
-#endif /* DEBUG */
-
-/*
- * nssckepv.h
- *
- * This automatically-generated header file defines the type
- * CK_FUNCTION_LIST specified by PKCS#11.
- */
-
-#ifndef NSSCKT_H
-#include "nssckt.h"
-#endif /* NSSCKT_H */
-
-#ifndef NSSCKFT_H
-#include "nssckft.h"
-#endif /* NSSCKFT_H */
-
-#include "nssckp.h"
-
-struct CK_FUNCTION_LIST {
- CK_VERSION version;
- CK_C_Initialize C_Initialize;
- CK_C_Finalize C_Finalize;
- CK_C_GetInfo C_GetInfo;
- CK_C_GetFunctionList C_GetFunctionList;
- CK_C_GetSlotList C_GetSlotList;
- CK_C_GetSlotInfo C_GetSlotInfo;
- CK_C_GetTokenInfo C_GetTokenInfo;
- CK_C_GetMechanismList C_GetMechanismList;
- CK_C_GetMechanismInfo C_GetMechanismInfo;
- CK_C_InitToken C_InitToken;
- CK_C_InitPIN C_InitPIN;
- CK_C_SetPIN C_SetPIN;
- CK_C_OpenSession C_OpenSession;
- CK_C_CloseSession C_CloseSession;
- CK_C_CloseAllSessions C_CloseAllSessions;
- CK_C_GetSessionInfo C_GetSessionInfo;
- CK_C_GetOperationState C_GetOperationState;
- CK_C_SetOperationState C_SetOperationState;
- CK_C_Login C_Login;
- CK_C_Logout C_Logout;
- CK_C_CreateObject C_CreateObject;
- CK_C_CopyObject C_CopyObject;
- CK_C_DestroyObject C_DestroyObject;
- CK_C_GetObjectSize C_GetObjectSize;
- CK_C_GetAttributeValue C_GetAttributeValue;
- CK_C_SetAttributeValue C_SetAttributeValue;
- CK_C_FindObjectsInit C_FindObjectsInit;
- CK_C_FindObjects C_FindObjects;
- CK_C_FindObjectsFinal C_FindObjectsFinal;
- CK_C_EncryptInit C_EncryptInit;
- CK_C_Encrypt C_Encrypt;
- CK_C_EncryptUpdate C_EncryptUpdate;
- CK_C_EncryptFinal C_EncryptFinal;
- CK_C_DecryptInit C_DecryptInit;
- CK_C_Decrypt C_Decrypt;
- CK_C_DecryptUpdate C_DecryptUpdate;
- CK_C_DecryptFinal C_DecryptFinal;
- CK_C_DigestInit C_DigestInit;
- CK_C_Digest C_Digest;
- CK_C_DigestUpdate C_DigestUpdate;
- CK_C_DigestKey C_DigestKey;
- CK_C_DigestFinal C_DigestFinal;
- CK_C_SignInit C_SignInit;
- CK_C_Sign C_Sign;
- CK_C_SignUpdate C_SignUpdate;
- CK_C_SignFinal C_SignFinal;
- CK_C_SignRecoverInit C_SignRecoverInit;
- CK_C_SignRecover C_SignRecover;
- CK_C_VerifyInit C_VerifyInit;
- CK_C_Verify C_Verify;
- CK_C_VerifyUpdate C_VerifyUpdate;
- CK_C_VerifyFinal C_VerifyFinal;
- CK_C_VerifyRecoverInit C_VerifyRecoverInit;
- CK_C_VerifyRecover C_VerifyRecover;
- CK_C_DigestEncryptUpdate C_DigestEncryptUpdate;
- CK_C_DecryptDigestUpdate C_DecryptDigestUpdate;
- CK_C_SignEncryptUpdate C_SignEncryptUpdate;
- CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate;
- CK_C_GenerateKey C_GenerateKey;
- CK_C_GenerateKeyPair C_GenerateKeyPair;
- CK_C_WrapKey C_WrapKey;
- CK_C_UnwrapKey C_UnwrapKey;
- CK_C_DeriveKey C_DeriveKey;
- CK_C_SeedRandom C_SeedRandom;
- CK_C_GenerateRandom C_GenerateRandom;
- CK_C_GetFunctionStatus C_GetFunctionStatus;
- CK_C_CancelFunction C_CancelFunction;
- CK_C_WaitForSlotEvent C_WaitForSlotEvent;
-};
-
-#include "nsscku.h"
-
-#endif /* NSSCKEPV_H */
+#include "pkcs11.h"
diff --git a/security/nss/lib/ckfw/nssckft.h b/security/nss/lib/ckfw/nssckft.h
index 287f91956..ef3e897ce 100644
--- a/security/nss/lib/ckfw/nssckft.h
+++ b/security/nss/lib/ckfw/nssckft.h
@@ -31,462 +31,5 @@
* may use your version of this file under either the MPL or the
* GPL.
*/
-#ifndef NSSCKFT_H
-#define NSSCKFT_H
-#ifdef DEBUG
-static const char NSSCKFT_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$ ; @(#) $RCSfile$ $Revision$ $Date$ $Name$";
-#endif /* DEBUG */
-
-/*
- * nssckft.h
- *
- * The automatically-generated header file declares a typedef
- * each of the Cryptoki functions specified by PKCS#11.
- */
-
-#ifndef NSSCKT_H
-#include "nssckt.h"
-#endif /* NSSCKT_H */
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_Initialize)(
- CK_VOID_PTR pInitArgs
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_Finalize)(
- CK_VOID_PTR pReserved
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_GetInfo)(
- CK_INFO_PTR pInfo
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_GetFunctionList)(
- CK_FUNCTION_LIST_PTR_PTR ppFunctionList
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_GetSlotList)(
- CK_BBOOL tokenPresent,
- CK_SLOT_ID_PTR pSlotList,
- CK_ULONG_PTR pulCount
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_GetSlotInfo)(
- CK_SLOT_ID slotID,
- CK_SLOT_INFO_PTR pInfo
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_GetTokenInfo)(
- CK_SLOT_ID slotID,
- CK_TOKEN_INFO_PTR pInfo
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_GetMechanismList)(
- CK_SLOT_ID slotID,
- CK_MECHANISM_TYPE_PTR pMechanismList,
- CK_ULONG_PTR pulCount
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_GetMechanismInfo)(
- CK_SLOT_ID slotID,
- CK_MECHANISM_TYPE type,
- CK_MECHANISM_INFO_PTR pInfo
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_InitToken)(
- CK_SLOT_ID slotID,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen,
- CK_CHAR_PTR pLabel
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_InitPIN)(
- CK_SESSION_HANDLE hSession,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_SetPIN)(
- CK_SESSION_HANDLE hSession,
- CK_CHAR_PTR pOldPin,
- CK_ULONG ulOldLen,
- CK_CHAR_PTR pNewPin,
- CK_ULONG ulNewLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_OpenSession)(
- CK_SLOT_ID slotID,
- CK_FLAGS flags,
- CK_VOID_PTR pApplication,
- CK_NOTIFY Notify,
- CK_SESSION_HANDLE_PTR phSession
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_CloseSession)(
- CK_SESSION_HANDLE hSession
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_CloseAllSessions)(
- CK_SLOT_ID slotID
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_GetSessionInfo)(
- CK_SESSION_HANDLE hSession,
- CK_SESSION_INFO_PTR pInfo
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_GetOperationState)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState,
- CK_ULONG_PTR pulOperationStateLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_SetOperationState)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState,
- CK_ULONG ulOperationStateLen,
- CK_OBJECT_HANDLE hEncryptionKey,
- CK_OBJECT_HANDLE hAuthenticationKey
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_Login)(
- CK_SESSION_HANDLE hSession,
- CK_USER_TYPE userType,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_Logout)(
- CK_SESSION_HANDLE hSession
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_CreateObject)(
- CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phObject
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_CopyObject)(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phNewObject
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_DestroyObject)(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_GetObjectSize)(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ULONG_PTR pulSize
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_GetAttributeValue)(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_SetAttributeValue)(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_FindObjectsInit)(
- CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_FindObjects)(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE_PTR phObject,
- CK_ULONG ulMaxObjectCount,
- CK_ULONG_PTR pulObjectCount
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_FindObjectsFinal)(
- CK_SESSION_HANDLE hSession
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_EncryptInit)(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_Encrypt)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pEncryptedData,
- CK_ULONG_PTR pulEncryptedDataLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_EncryptUpdate)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_EncryptFinal)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastEncryptedPart,
- CK_ULONG_PTR pulLastEncryptedPartLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_DecryptInit)(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_Decrypt)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedData,
- CK_ULONG ulEncryptedDataLen,
- CK_BYTE_PTR pData,
- CK_ULONG_PTR pulDataLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_DecryptUpdate)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart,
- CK_ULONG_PTR pulPartLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_DecryptFinal)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastPart,
- CK_ULONG_PTR pulLastPartLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_DigestInit)(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_Digest)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pulDigestLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_DigestUpdate)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_DigestKey)(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hKey
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_DigestFinal)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pulDigestLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_SignInit)(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_Sign)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_SignUpdate)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_SignFinal)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_SignRecoverInit)(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_SignRecover)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_VerifyInit)(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_Verify)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_VerifyUpdate)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_VerifyFinal)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_VerifyRecoverInit)(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_VerifyRecover)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen,
- CK_BYTE_PTR pData,
- CK_ULONG_PTR pulDataLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_DigestEncryptUpdate)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_DecryptDigestUpdate)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart,
- CK_ULONG_PTR pulPartLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_SignEncryptUpdate)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_DecryptVerifyUpdate)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart,
- CK_ULONG_PTR pulPartLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_GenerateKey)(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phKey
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_GenerateKeyPair)(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_ATTRIBUTE_PTR pPublicKeyTemplate,
- CK_ULONG ulPublicKeyAttributeCount,
- CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
- CK_ULONG ulPrivateKeyAttributeCount,
- CK_OBJECT_HANDLE_PTR phPublicKey,
- CK_OBJECT_HANDLE_PTR phPrivateKey
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_WrapKey)(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hWrappingKey,
- CK_OBJECT_HANDLE hKey,
- CK_BYTE_PTR pWrappedKey,
- CK_ULONG_PTR pulWrappedKeyLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_UnwrapKey)(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hUnwrappingKey,
- CK_BYTE_PTR pWrappedKey,
- CK_ULONG ulWrappedKeyLen,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_DeriveKey)(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hBaseKey,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_SeedRandom)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSeed,
- CK_ULONG ulSeedLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_GenerateRandom)(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR RandomData,
- CK_ULONG ulRandomLen
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_GetFunctionStatus)(
- CK_SESSION_HANDLE hSession
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_CancelFunction)(
- CK_SESSION_HANDLE hSession
-);
-
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_C_WaitForSlotEvent)(
- CK_FLAGS flags,
- CK_SLOT_ID_PTR pSlot,
- CK_VOID_PTR pRserved
-);
-
-#endif /* NSSCKFT_H */
+#include "pkcs11t.h"
diff --git a/security/nss/lib/ckfw/nssckg.h b/security/nss/lib/ckfw/nssckg.h
index 3dc76622a..bfa79ac78 100644
--- a/security/nss/lib/ckfw/nssckg.h
+++ b/security/nss/lib/ckfw/nssckg.h
@@ -31,530 +31,4 @@
* may use your version of this file under either the MPL or the
* GPL.
*/
-#ifndef NSSCKG_H
-#define NSSCKG_H
-
-#ifdef DEBUG
-static const char NSSCKG_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$ ; @(#) $RCSfile$ $Revision$ $Date$ $Name$";
-#endif /* DEBUG */
-
-/*
- * nssckg.h
- *
- * This automatically-generated header file prototypes the Cryptoki
- * functions specified by PKCS#11.
- */
-
-#ifndef NSSCKT_H
-#include "nssckt.h"
-#endif /* NSSCKT_H */
-
-CK_RV CK_ENTRY C_Initialize
-(
- CK_VOID_PTR pInitArgs
-);
-
-CK_RV CK_ENTRY C_Finalize
-(
- CK_VOID_PTR pReserved
-);
-
-CK_RV CK_ENTRY C_GetInfo
-(
- CK_INFO_PTR pInfo
-);
-
-CK_RV CK_ENTRY C_GetFunctionList
-(
- CK_FUNCTION_LIST_PTR_PTR ppFunctionList
-);
-
-CK_RV CK_ENTRY C_GetSlotList
-(
- CK_BBOOL tokenPresent,
- CK_SLOT_ID_PTR pSlotList,
- CK_ULONG_PTR pulCount
-);
-
-CK_RV CK_ENTRY C_GetSlotInfo
-(
- CK_SLOT_ID slotID,
- CK_SLOT_INFO_PTR pInfo
-);
-
-CK_RV CK_ENTRY C_GetTokenInfo
-(
- CK_SLOT_ID slotID,
- CK_TOKEN_INFO_PTR pInfo
-);
-
-CK_RV CK_ENTRY C_GetMechanismList
-(
- CK_SLOT_ID slotID,
- CK_MECHANISM_TYPE_PTR pMechanismList,
- CK_ULONG_PTR pulCount
-);
-
-CK_RV CK_ENTRY C_GetMechanismInfo
-(
- CK_SLOT_ID slotID,
- CK_MECHANISM_TYPE type,
- CK_MECHANISM_INFO_PTR pInfo
-);
-
-CK_RV CK_ENTRY C_InitToken
-(
- CK_SLOT_ID slotID,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen,
- CK_CHAR_PTR pLabel
-);
-
-CK_RV CK_ENTRY C_InitPIN
-(
- CK_SESSION_HANDLE hSession,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen
-);
-
-CK_RV CK_ENTRY C_SetPIN
-(
- CK_SESSION_HANDLE hSession,
- CK_CHAR_PTR pOldPin,
- CK_ULONG ulOldLen,
- CK_CHAR_PTR pNewPin,
- CK_ULONG ulNewLen
-);
-
-CK_RV CK_ENTRY C_OpenSession
-(
- CK_SLOT_ID slotID,
- CK_FLAGS flags,
- CK_VOID_PTR pApplication,
- CK_NOTIFY Notify,
- CK_SESSION_HANDLE_PTR phSession
-);
-
-CK_RV CK_ENTRY C_CloseSession
-(
- CK_SESSION_HANDLE hSession
-);
-
-CK_RV CK_ENTRY C_CloseAllSessions
-(
- CK_SLOT_ID slotID
-);
-
-CK_RV CK_ENTRY C_GetSessionInfo
-(
- CK_SESSION_HANDLE hSession,
- CK_SESSION_INFO_PTR pInfo
-);
-
-CK_RV CK_ENTRY C_GetOperationState
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState,
- CK_ULONG_PTR pulOperationStateLen
-);
-
-CK_RV CK_ENTRY C_SetOperationState
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState,
- CK_ULONG ulOperationStateLen,
- CK_OBJECT_HANDLE hEncryptionKey,
- CK_OBJECT_HANDLE hAuthenticationKey
-);
-
-CK_RV CK_ENTRY C_Login
-(
- CK_SESSION_HANDLE hSession,
- CK_USER_TYPE userType,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen
-);
-
-CK_RV CK_ENTRY C_Logout
-(
- CK_SESSION_HANDLE hSession
-);
-
-CK_RV CK_ENTRY C_CreateObject
-(
- CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phObject
-);
-
-CK_RV CK_ENTRY C_CopyObject
-(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phNewObject
-);
-
-CK_RV CK_ENTRY C_DestroyObject
-(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject
-);
-
-CK_RV CK_ENTRY C_GetObjectSize
-(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ULONG_PTR pulSize
-);
-
-CK_RV CK_ENTRY C_GetAttributeValue
-(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount
-);
-
-CK_RV CK_ENTRY C_SetAttributeValue
-(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount
-);
-
-CK_RV CK_ENTRY C_FindObjectsInit
-(
- CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount
-);
-
-CK_RV CK_ENTRY C_FindObjects
-(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE_PTR phObject,
- CK_ULONG ulMaxObjectCount,
- CK_ULONG_PTR pulObjectCount
-);
-
-CK_RV CK_ENTRY C_FindObjectsFinal
-(
- CK_SESSION_HANDLE hSession
-);
-
-CK_RV CK_ENTRY C_EncryptInit
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-);
-
-CK_RV CK_ENTRY C_Encrypt
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pEncryptedData,
- CK_ULONG_PTR pulEncryptedDataLen
-);
-
-CK_RV CK_ENTRY C_EncryptUpdate
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen
-);
-
-CK_RV CK_ENTRY C_EncryptFinal
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastEncryptedPart,
- CK_ULONG_PTR pulLastEncryptedPartLen
-);
-
-CK_RV CK_ENTRY C_DecryptInit
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-);
-
-CK_RV CK_ENTRY C_Decrypt
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedData,
- CK_ULONG ulEncryptedDataLen,
- CK_BYTE_PTR pData,
- CK_ULONG_PTR pulDataLen
-);
-
-CK_RV CK_ENTRY C_DecryptUpdate
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart,
- CK_ULONG_PTR pulPartLen
-);
-
-CK_RV CK_ENTRY C_DecryptFinal
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastPart,
- CK_ULONG_PTR pulLastPartLen
-);
-
-CK_RV CK_ENTRY C_DigestInit
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism
-);
-
-CK_RV CK_ENTRY C_Digest
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pulDigestLen
-);
-
-CK_RV CK_ENTRY C_DigestUpdate
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen
-);
-
-CK_RV CK_ENTRY C_DigestKey
-(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hKey
-);
-
-CK_RV CK_ENTRY C_DigestFinal
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pulDigestLen
-);
-
-CK_RV CK_ENTRY C_SignInit
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-);
-
-CK_RV CK_ENTRY C_Sign
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen
-);
-
-CK_RV CK_ENTRY C_SignUpdate
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen
-);
-
-CK_RV CK_ENTRY C_SignFinal
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen
-);
-
-CK_RV CK_ENTRY C_SignRecoverInit
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-);
-
-CK_RV CK_ENTRY C_SignRecover
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen
-);
-
-CK_RV CK_ENTRY C_VerifyInit
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-);
-
-CK_RV CK_ENTRY C_Verify
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen
-);
-
-CK_RV CK_ENTRY C_VerifyUpdate
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen
-);
-
-CK_RV CK_ENTRY C_VerifyFinal
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen
-);
-
-CK_RV CK_ENTRY C_VerifyRecoverInit
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-);
-
-CK_RV CK_ENTRY C_VerifyRecover
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen,
- CK_BYTE_PTR pData,
- CK_ULONG_PTR pulDataLen
-);
-
-CK_RV CK_ENTRY C_DigestEncryptUpdate
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen
-);
-
-CK_RV CK_ENTRY C_DecryptDigestUpdate
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart,
- CK_ULONG_PTR pulPartLen
-);
-
-CK_RV CK_ENTRY C_SignEncryptUpdate
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen
-);
-
-CK_RV CK_ENTRY C_DecryptVerifyUpdate
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart,
- CK_ULONG_PTR pulPartLen
-);
-
-CK_RV CK_ENTRY C_GenerateKey
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phKey
-);
-
-CK_RV CK_ENTRY C_GenerateKeyPair
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_ATTRIBUTE_PTR pPublicKeyTemplate,
- CK_ULONG ulPublicKeyAttributeCount,
- CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
- CK_ULONG ulPrivateKeyAttributeCount,
- CK_OBJECT_HANDLE_PTR phPublicKey,
- CK_OBJECT_HANDLE_PTR phPrivateKey
-);
-
-CK_RV CK_ENTRY C_WrapKey
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hWrappingKey,
- CK_OBJECT_HANDLE hKey,
- CK_BYTE_PTR pWrappedKey,
- CK_ULONG_PTR pulWrappedKeyLen
-);
-
-CK_RV CK_ENTRY C_UnwrapKey
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hUnwrappingKey,
- CK_BYTE_PTR pWrappedKey,
- CK_ULONG ulWrappedKeyLen,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey
-);
-
-CK_RV CK_ENTRY C_DeriveKey
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hBaseKey,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey
-);
-
-CK_RV CK_ENTRY C_SeedRandom
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSeed,
- CK_ULONG ulSeedLen
-);
-
-CK_RV CK_ENTRY C_GenerateRandom
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR RandomData,
- CK_ULONG ulRandomLen
-);
-
-CK_RV CK_ENTRY C_GetFunctionStatus
-(
- CK_SESSION_HANDLE hSession
-);
-
-CK_RV CK_ENTRY C_CancelFunction
-(
- CK_SESSION_HANDLE hSession
-);
-
-CK_RV CK_ENTRY C_WaitForSlotEvent
-(
- CK_FLAGS flags,
- CK_SLOT_ID_PTR pSlot,
- CK_VOID_PTR pRserved
-);
-
-#endif /* NSSCKG_H */
+#include "pkcs11.h"
diff --git a/security/nss/lib/ckfw/nssckp.h b/security/nss/lib/ckfw/nssckp.h
deleted file mode 100644
index 502e18408..000000000
--- a/security/nss/lib/ckfw/nssckp.h
+++ /dev/null
@@ -1,66 +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.
- */
-
-/*
- * This file is in part derived from a file "pkcs11t.h" made available
- * by RSA Security at ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-11/pkcs11t.h
- */
-
-#ifndef NSSCKP_H
-#define NSSCKP_H
-
-#ifdef DEBUG
-static const char NSSCKP_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
-#endif /* DEBUG */
-
-#endif /* NSSCKP_H */
-
-/*
- * These platform-dependent packing rules are required by all PKCS#11
- * modules, to be binary compatible. These rules have been placed in
- * separate header files (nssckp.h to enable the packing, nsscku.h to
- * disable) for consistancy. These files can be included many times,
- * so the bodies should *NOT* be in the multiple-inclusion-preventing
- * #ifndef/#endif area above.
- */
-
-/*
- * WIN32 is defined (when appropriate) in NSPR's prcpucfg.h.
- */
-
-#ifdef WIN32
-#pragma warning(disable:4103)
-#pragma pack(push, cryptoki, 1)
-#endif /* WIN32 */
-
-/* End of nssckp.h */
diff --git a/security/nss/lib/ckfw/nssckt.h b/security/nss/lib/ckfw/nssckt.h
index f2bf36f1d..f1b2ef1b5 100644
--- a/security/nss/lib/ckfw/nssckt.h
+++ b/security/nss/lib/ckfw/nssckt.h
@@ -30,1094 +30,13 @@
* may use your version of this file under either the MPL or the
* GPL.
*/
+#ifndef _NSSCKT_H_
+#define _NSSCKT_H_ 1
-/*
- * This file is in part derived from a file "pkcs11t.h" made available
- * by RSA Security at ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-11/pkcs11t.h
- *
- * Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document
- * is granted provided that it is identified as "RSA Security Inc Public-Key
- * Cryptography Standards (PKCS)" in all material mentioning or referencing
- * this document.
- *
- */
-
-#ifndef NSSCKT_H
-#define NSSCKT_H
-
-#ifdef DEBUG
-static const char NSSCKT_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
-#endif /* DEBUG */
-
-#include "nspr.h"
-
-/*
- * nssckt.h
- *
- * This file contains the type definitions for Cryptoki (PKCS#11).
- * These definitions are taken from the RSA Standard.
- *
- * NOTE: Unlike most things in NSS, there are public types and
- * preprocessor definitions which do *NOT* begin with NSS-- rather,
- * they begin with CK, as per the standard.
- */
-
-#ifndef CK_FALSE
-#define CK_FALSE 0
-#endif
-
-#ifndef CK_TRUE
-#define CK_TRUE (!CK_FALSE)
-#endif
-
-#define CK_PTR *
-#define CK_NULL_PTR 0
-#define CK_CALLBACK_FUNCTION(rv,func) rv (PR_CALLBACK * func)
-#define CK_DECLARE_FUNCTION(rv,func) NSS_EXTERN rv func
-#define CK_DECLARE_FUNCTION_POINTER(rv,func) rv (PR_CALLBACK * func)
-
-/* an unsigned 8-bit value */
-typedef unsigned char CK_BYTE;
-
-/* an unsigned 8-bit character */
-typedef CK_BYTE CK_CHAR;
-
-/* a BYTE-sized Boolean flag */
-typedef CK_BYTE CK_BBOOL;
-
-/* an unsigned value, at least 16 bits long */
-typedef unsigned short int CK_USHORT;
-
-/* a signed value, the same size as a CK_USHORT */
-typedef short int CK_SHORT;
-
-/* an unsigned value, at least 32 bits long */
-typedef unsigned long int CK_ULONG;
-
-/* a signed value, the same size as a CK_ULONG */
-/* CK_LONG is new for v2.0 */
-typedef long int CK_LONG;
-
-/* at least 32 bits; each bit is a Boolean flag */
-typedef CK_ULONG CK_FLAGS;
-
-
-/* some special values for certain CK_ULONG variables */
-#define CK_UNAVAILABLE_INFORMATION (~0UL)
-#define CK_EFFECTIVELY_INFINITE 0
-
-
-typedef CK_BYTE CK_PTR CK_BYTE_PTR;
-typedef CK_CHAR CK_PTR CK_CHAR_PTR;
-typedef CK_ULONG CK_PTR CK_ULONG_PTR;
-typedef void CK_PTR CK_VOID_PTR;
-
-/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
-typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
-
-
-/* The following value is always invalid if used as a session */
-/* handle or object handle */
-#define CK_INVALID_HANDLE 0
-
-#define CK_ENTRY
-
-/* pack */
-#include "nssckp.h"
-
-typedef struct CK_VERSION {
- CK_BYTE major; /* integer portion of version number */
- CK_BYTE minor; /* 1/100ths portion of version number */
-} CK_VERSION;
-
-typedef CK_VERSION CK_PTR CK_VERSION_PTR;
-
-
-typedef struct CK_INFO {
- CK_VERSION cryptokiVersion; /* Cryptoki interface ver */
- CK_CHAR manufacturerID[32]; /* blank padded */
- CK_FLAGS flags; /* must be zero */
-
- /* libraryDescription and libraryVersion are new for v2.0 */
- CK_CHAR libraryDescription[32]; /* blank padded */
- CK_VERSION libraryVersion; /* version of library */
-} CK_INFO;
-
-typedef CK_INFO CK_PTR CK_INFO_PTR;
-
-
-/* CK_NOTIFICATION enumerates the types of notifications that
- * Cryptoki provides to an application */
-/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
- * for v2.0 */
-typedef CK_ULONG CK_NOTIFICATION;
-#define CKN_SURRENDER 0
-
-
-typedef CK_ULONG CK_SLOT_ID;
-
-typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
-
-
-/* CK_SLOT_INFO provides information about a slot */
-typedef struct CK_SLOT_INFO {
- CK_CHAR slotDescription[64]; /* blank padded */
- CK_CHAR manufacturerID[32]; /* blank padded */
- CK_FLAGS flags;
-
- /* hardwareVersion and firmwareVersion are new for v2.0 */
- CK_VERSION hardwareVersion; /* version of hardware */
- CK_VERSION firmwareVersion; /* version of firmware */
-} CK_SLOT_INFO;
-
-/* flags: bit flags that provide capabilities of the slot
- * Bit Flag Mask Meaning
- */
-#define CKF_TOKEN_PRESENT 0x00000001 /* a token is there */
-#define CKF_REMOVABLE_DEVICE 0x00000002 /* removable devices*/
-#define CKF_HW_SLOT 0x00000004 /* hardware slot */
-
-typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
-
-
-/* CK_TOKEN_INFO provides information about a token */
-typedef struct CK_TOKEN_INFO {
- CK_CHAR label[32]; /* blank padded */
- CK_CHAR manufacturerID[32]; /* blank padded */
- CK_CHAR model[16]; /* blank padded */
- CK_CHAR serialNumber[16]; /* blank padded */
- CK_FLAGS flags; /* see below */
-
- /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
- * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
- * changed from CK_USHORT to CK_ULONG for v2.0 */
- CK_ULONG ulMaxSessionCount; /* max open sessions */
- CK_ULONG ulSessionCount; /* sess. now open */
- CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */
- CK_ULONG ulRwSessionCount; /* R/W sess. now open */
- CK_ULONG ulMaxPinLen; /* in bytes */
- CK_ULONG ulMinPinLen; /* in bytes */
- CK_ULONG ulTotalPublicMemory; /* in bytes */
- CK_ULONG ulFreePublicMemory; /* in bytes */
- CK_ULONG ulTotalPrivateMemory; /* in bytes */
- CK_ULONG ulFreePrivateMemory; /* in bytes */
-
- /* hardwareVersion, firmwareVersion, and time are new for
- * v2.0 */
- CK_VERSION hardwareVersion; /* version of hardware */
- CK_VERSION firmwareVersion; /* version of firmware */
- CK_CHAR utcTime[16]; /* time */
-} CK_TOKEN_INFO;
-
-/* The flags parameter is defined as follows:
- * Bit Flag Mask Meaning
- */
-#define CKF_RNG 0x00000001 /* has random #
- * generator */
-#define CKF_WRITE_PROTECTED 0x00000002 /* token is
- * write-
- * protected */
-#define CKF_LOGIN_REQUIRED 0x00000004 /* user must
- * login */
-#define CKF_USER_PIN_INITIALIZED 0x00000008 /* normal user's
- * PIN is set */
-
-/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0. If it is set,
- * that means that *every* time the state of cryptographic
- * operations of a session is successfully saved, all keys
- * needed to continue those operations are stored in the state */
-#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020
-
-/* CKF_CLOCK_ON_TOKEN is new for v2.0. If it is set, that means
- * that the token has some sort of clock. The time on that
- * clock is returned in the token info structure */
-#define CKF_CLOCK_ON_TOKEN 0x00000040
-
-/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0. If it is
- * set, that means that there is some way for the user to login
- * without sending a PIN through the Cryptoki library itself */
-#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
-
-/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0. If it is true,
- * that means that a single session with the token can perform
- * dual simultaneous cryptographic operations (digest and
- * encrypt; decrypt and digest; sign and encrypt; and decrypt
- * and sign) */
-#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200
-
-typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
-
-
-/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
- * identifies a session */
-typedef CK_ULONG CK_SESSION_HANDLE;
-
-typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
-
-
-/* CK_USER_TYPE enumerates the types of Cryptoki users */
-/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
- * v2.0 */
-typedef CK_ULONG CK_USER_TYPE;
-/* Security Officer */
-#define CKU_SO 0
-/* Normal user */
-#define CKU_USER 1
-
-
-/* CK_STATE enumerates the session states */
-/* CK_STATE has been changed from an enum to a CK_ULONG for
- * v2.0 */
-typedef CK_ULONG CK_STATE;
-#define CKS_RO_PUBLIC_SESSION 0
-#define CKS_RO_USER_FUNCTIONS 1
-#define CKS_RW_PUBLIC_SESSION 2
-#define CKS_RW_USER_FUNCTIONS 3
-#define CKS_RW_SO_FUNCTIONS 4
-
-
-/* CK_SESSION_INFO provides information about a session */
-typedef struct CK_SESSION_INFO {
- CK_SLOT_ID slotID;
- CK_STATE state;
- CK_FLAGS flags; /* see below */
-
- /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
- CK_ULONG ulDeviceError; /* device-dependent error code */
-} CK_SESSION_INFO;
-
-/* The flags are defined in the following table:
- * Bit Flag Mask Meaning
- */
-#define CKF_RW_SESSION 0x00000002 /* session is r/w */
-#define CKF_SERIAL_SESSION 0x00000004 /* no parallel */
-
-typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
-
-
-/* CK_OBJECT_HANDLE is a token-specific identifier for an
- * object */
-typedef CK_ULONG CK_OBJECT_HANDLE;
-
-typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
-
-
-/* CK_OBJECT_CLASS is a value that identifies the classes (or
- * types) of objects that Cryptoki recognizes. It is defined
- * as follows: */
-/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
-typedef CK_ULONG CK_OBJECT_CLASS;
-
-/* The following classes of objects are defined: */
-#define CKO_DATA 0x00000000
-#define CKO_CERTIFICATE 0x00000001
-#define CKO_PUBLIC_KEY 0x00000002
-#define CKO_PRIVATE_KEY 0x00000003
-#define CKO_SECRET_KEY 0x00000004
-#define CKO_VENDOR_DEFINED 0x80000000
-
-typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
-
-
-/* CK_KEY_TYPE is a value that identifies a key type */
-/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
-typedef CK_ULONG CK_KEY_TYPE;
-
-/* the following key types are defined: */
-#define CKK_RSA 0x00000000
-#define CKK_DSA 0x00000001
-#define CKK_DH 0x00000002
-
-/* CKK_ECDSA and CKK_KEA are new for v2.0 */
-
-/* Cryptoki V2.01 probably won't actually have ECDSA in it */
-#define CKK_ECDSA 0x00000003
-
-#define CKK_KEA 0x00000005
-
-#define CKK_GENERIC_SECRET 0x00000010
-#define CKK_RC2 0x00000011
-#define CKK_RC4 0x00000012
-#define CKK_DES 0x00000013
-#define CKK_DES2 0x00000014
-#define CKK_DES3 0x00000015
-
-/* all these key types are new for v2.0 */
-#define CKK_CAST 0x00000016
-#define CKK_CAST3 0x00000017
-#define CKK_CAST5 0x00000018
-#define CKK_CAST128 0x00000018 /* CAST128=CAST5 */
-#define CKK_RC5 0x00000019
-#define CKK_IDEA 0x0000001A
-#define CKK_SKIPJACK 0x0000001B
-#define CKK_BATON 0x0000001C
-#define CKK_JUNIPER 0x0000001D
-#define CKK_CDMF 0x0000001E
-
-#define CKK_VENDOR_DEFINED 0x80000000
-
-
-/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
- * type */
-/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
- * for v2.0 */
-typedef CK_ULONG CK_CERTIFICATE_TYPE;
-
-/* The following certificate types are defined: */
-#define CKC_X_509 0x00000000
-#define CKC_VENDOR_DEFINED 0x80000000
-
-/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
- * type */
-/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
-typedef CK_ULONG CK_ATTRIBUTE_TYPE;
+#include "pkcs11t.h"
typedef CK_ATTRIBUTE_TYPE CK_PTR CK_ATTRIBUTE_TYPE_PTR;
+#define CK_ENTRY
-/* The following attribute types are defined: */
-#define CKA_CLASS 0x00000000
-#define CKA_TOKEN 0x00000001
-#define CKA_PRIVATE 0x00000002
-#define CKA_LABEL 0x00000003
-#define CKA_APPLICATION 0x00000010
-#define CKA_VALUE 0x00000011
-#define CKA_CERTIFICATE_TYPE 0x00000080
-#define CKA_ISSUER 0x00000081
-#define CKA_SERIAL_NUMBER 0x00000082
-#define CKA_KEY_TYPE 0x00000100
-#define CKA_SUBJECT 0x00000101
-#define CKA_ID 0x00000102
-#define CKA_SENSITIVE 0x00000103
-#define CKA_ENCRYPT 0x00000104
-#define CKA_DECRYPT 0x00000105
-#define CKA_WRAP 0x00000106
-#define CKA_UNWRAP 0x00000107
-#define CKA_SIGN 0x00000108
-#define CKA_SIGN_RECOVER 0x00000109
-#define CKA_VERIFY 0x0000010A
-#define CKA_VERIFY_RECOVER 0x0000010B
-#define CKA_DERIVE 0x0000010C
-#define CKA_START_DATE 0x00000110
-#define CKA_END_DATE 0x00000111
-#define CKA_MODULUS 0x00000120
-#define CKA_MODULUS_BITS 0x00000121
-#define CKA_PUBLIC_EXPONENT 0x00000122
-#define CKA_PRIVATE_EXPONENT 0x00000123
-#define CKA_PRIME_1 0x00000124
-#define CKA_PRIME_2 0x00000125
-#define CKA_EXPONENT_1 0x00000126
-#define CKA_EXPONENT_2 0x00000127
-#define CKA_COEFFICIENT 0x00000128
-#define CKA_PRIME 0x00000130
-#define CKA_SUBPRIME 0x00000131
-#define CKA_BASE 0x00000132
-#define CKA_VALUE_BITS 0x00000160
-#define CKA_VALUE_LEN 0x00000161
-
-/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
- * CKA_ALWAYS_SENSITIVE, and CKA_MODIFIABLE are new for v2.0 */
-#define CKA_EXTRACTABLE 0x00000162
-#define CKA_LOCAL 0x00000163
-#define CKA_NEVER_EXTRACTABLE 0x00000164
-#define CKA_ALWAYS_SENSITIVE 0x00000165
-#define CKA_MODIFIABLE 0x00000170
-
-#define CKA_VENDOR_DEFINED 0x80000000
-
-
-/* CK_ATTRIBUTE is a structure that includes the type, length
- * and value of an attribute */
-typedef struct CK_ATTRIBUTE {
- CK_ATTRIBUTE_TYPE type;
- CK_VOID_PTR pValue;
-
- /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
- CK_ULONG ulValueLen; /* in bytes */
-} CK_ATTRIBUTE;
-
-typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
-
-
-/* CK_DATE is a structure that defines a date */
-typedef struct CK_DATE{
- CK_CHAR year[4]; /* the year ("1900" - "9999") */
- CK_CHAR month[2]; /* the month ("01" - "12") */
- CK_CHAR day[2]; /* the day ("01" - "31") */
-} CK_DATE;
-
-
-/* CK_MECHANISM_TYPE is a value that identifies a mechanism
- * type */
-/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
-typedef CK_ULONG CK_MECHANISM_TYPE;
-
-/* the following mechanism types are defined: */
-#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000
-#define CKM_RSA_PKCS 0x00000001
-#define CKM_RSA_9796 0x00000002
-#define CKM_RSA_X_509 0x00000003
-
-/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
- * are new for v2.0. They are mechanisms which hash and sign */
-#define CKM_MD2_RSA_PKCS 0x00000004
-#define CKM_MD5_RSA_PKCS 0x00000005
-#define CKM_SHA1_RSA_PKCS 0x00000006
-
-#define CKM_DSA_KEY_PAIR_GEN 0x00000010
-#define CKM_DSA 0x00000011
-#define CKM_DSA_SHA1 0x00000012
-#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020
-#define CKM_DH_PKCS_DERIVE 0x00000021
-#define CKM_RC2_KEY_GEN 0x00000100
-#define CKM_RC2_ECB 0x00000101
-#define CKM_RC2_CBC 0x00000102
-#define CKM_RC2_MAC 0x00000103
-
-/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
-#define CKM_RC2_MAC_GENERAL 0x00000104
-#define CKM_RC2_CBC_PAD 0x00000105
-
-#define CKM_RC4_KEY_GEN 0x00000110
-#define CKM_RC4 0x00000111
-#define CKM_DES_KEY_GEN 0x00000120
-#define CKM_DES_ECB 0x00000121
-#define CKM_DES_CBC 0x00000122
-#define CKM_DES_MAC 0x00000123
-
-/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
-#define CKM_DES_MAC_GENERAL 0x00000124
-#define CKM_DES_CBC_PAD 0x00000125
-
-#define CKM_DES2_KEY_GEN 0x00000130
-#define CKM_DES3_KEY_GEN 0x00000131
-#define CKM_DES3_ECB 0x00000132
-#define CKM_DES3_CBC 0x00000133
-#define CKM_DES3_MAC 0x00000134
-
-/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
- * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
- * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
-#define CKM_DES3_MAC_GENERAL 0x00000135
-#define CKM_DES3_CBC_PAD 0x00000136
-#define CKM_CDMF_KEY_GEN 0x00000140
-#define CKM_CDMF_ECB 0x00000141
-#define CKM_CDMF_CBC 0x00000142
-#define CKM_CDMF_MAC 0x00000143
-#define CKM_CDMF_MAC_GENERAL 0x00000144
-#define CKM_CDMF_CBC_PAD 0x00000145
-
-#define CKM_MD2 0x00000200
-
-/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
-#define CKM_MD2_HMAC 0x00000201
-#define CKM_MD2_HMAC_GENERAL 0x00000202
-
-#define CKM_MD5 0x00000210
-
-/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
-#define CKM_MD5_HMAC 0x00000211
-#define CKM_MD5_HMAC_GENERAL 0x00000212
-
-#define CKM_SHA_1 0x00000220
-
-/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
-#define CKM_SHA_1_HMAC 0x00000221
-#define CKM_SHA_1_HMAC_GENERAL 0x00000222
-
-/* All of the following mechanisms are new for v2.0 */
-/* Note that CAST128 and CAST5 are the same algorithm */
-#define CKM_CAST_KEY_GEN 0x00000300
-#define CKM_CAST_ECB 0x00000301
-#define CKM_CAST_CBC 0x00000302
-#define CKM_CAST_MAC 0x00000303
-#define CKM_CAST_MAC_GENERAL 0x00000304
-#define CKM_CAST_CBC_PAD 0x00000305
-#define CKM_CAST3_KEY_GEN 0x00000310
-#define CKM_CAST3_ECB 0x00000311
-#define CKM_CAST3_CBC 0x00000312
-#define CKM_CAST3_MAC 0x00000313
-#define CKM_CAST3_MAC_GENERAL 0x00000314
-#define CKM_CAST3_CBC_PAD 0x00000315
-#define CKM_CAST5_KEY_GEN 0x00000320
-#define CKM_CAST128_KEY_GEN 0x00000320
-#define CKM_CAST5_ECB 0x00000321
-#define CKM_CAST128_ECB 0x00000321
-#define CKM_CAST5_CBC 0x00000322
-#define CKM_CAST128_CBC 0x00000322
-#define CKM_CAST5_MAC 0x00000323
-#define CKM_CAST128_MAC 0x00000323
-#define CKM_CAST5_MAC_GENERAL 0x00000324
-#define CKM_CAST128_MAC_GENERAL 0x00000324
-#define CKM_CAST5_CBC_PAD 0x00000325
-#define CKM_CAST128_CBC_PAD 0x00000325
-#define CKM_RC5_KEY_GEN 0x00000330
-#define CKM_RC5_ECB 0x00000331
-#define CKM_RC5_CBC 0x00000332
-#define CKM_RC5_MAC 0x00000333
-#define CKM_RC5_MAC_GENERAL 0x00000334
-#define CKM_RC5_CBC_PAD 0x00000335
-#define CKM_IDEA_KEY_GEN 0x00000340
-#define CKM_IDEA_ECB 0x00000341
-#define CKM_IDEA_CBC 0x00000342
-#define CKM_IDEA_MAC 0x00000343
-#define CKM_IDEA_MAC_GENERAL 0x00000344
-#define CKM_IDEA_CBC_PAD 0x00000345
-#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350
-#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360
-#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362
-#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363
-#define CKM_XOR_BASE_AND_DATA 0x00000364
-#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365
-#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370
-#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371
-#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372
-#define CKM_SSL3_MD5_MAC 0x00000380
-#define CKM_SSL3_SHA1_MAC 0x00000381
-#define CKM_MD5_KEY_DERIVATION 0x00000390
-#define CKM_MD2_KEY_DERIVATION 0x00000391
-#define CKM_SHA1_KEY_DERIVATION 0x00000392
-#define CKM_PBE_MD2_DES_CBC 0x000003A0
-#define CKM_PBE_MD5_DES_CBC 0x000003A1
-#define CKM_PBE_MD5_CAST_CBC 0x000003A2
-#define CKM_PBE_MD5_CAST3_CBC 0x000003A3
-#define CKM_PBE_MD5_CAST5_CBC 0x000003A4
-#define CKM_PBE_MD5_CAST128_CBC 0x000003A4
-#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5
-#define CKM_PBE_SHA1_CAST128_CBC 0x000003A5
-#define CKM_PBE_SHA1_RC4_128 0x000003A6
-#define CKM_PBE_SHA1_RC4_40 0x000003A7
-#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8
-#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9
-#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AA
-#define CKM_PBE_SHA1_RC2_40_CBC 0x000003AB
-#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0
-#define CKM_KEY_WRAP_LYNKS 0x00000400
-#define CKM_KEY_WRAP_SET_OAEP 0x00000401
-
-/* Fortezza mechanisms */
-#define CKM_SKIPJACK_KEY_GEN 0x00001000
-#define CKM_SKIPJACK_ECB64 0x00001001
-#define CKM_SKIPJACK_CBC64 0x00001002
-#define CKM_SKIPJACK_OFB64 0x00001003
-#define CKM_SKIPJACK_CFB64 0x00001004
-#define CKM_SKIPJACK_CFB32 0x00001005
-#define CKM_SKIPJACK_CFB16 0x00001006
-#define CKM_SKIPJACK_CFB8 0x00001007
-#define CKM_SKIPJACK_WRAP 0x00001008
-#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009
-#define CKM_SKIPJACK_RELAYX 0x0000100a
-#define CKM_KEA_KEY_PAIR_GEN 0x00001010
-#define CKM_KEA_KEY_DERIVE 0x00001011
-#define CKM_FORTEZZA_TIMESTAMP 0x00001020
-#define CKM_BATON_KEY_GEN 0x00001030
-#define CKM_BATON_ECB128 0x00001031
-#define CKM_BATON_ECB96 0x00001032
-#define CKM_BATON_CBC128 0x00001033
-#define CKM_BATON_COUNTER 0x00001034
-#define CKM_BATON_SHUFFLE 0x00001035
-#define CKM_BATON_WRAP 0x00001036
-
-/* Cryptoki V2.01 probably won't actually have ECDSA in it */
-#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040
-#define CKM_ECDSA 0x00001041
-#define CKM_ECDSA_SHA1 0x00001042
-
-#define CKM_JUNIPER_KEY_GEN 0x00001060
-#define CKM_JUNIPER_ECB128 0x00001061
-#define CKM_JUNIPER_CBC128 0x00001062
-#define CKM_JUNIPER_COUNTER 0x00001063
-#define CKM_JUNIPER_SHUFFLE 0x00001064
-#define CKM_JUNIPER_WRAP 0x00001065
-#define CKM_FASTHASH 0x00001070
-
-#define CKM_VENDOR_DEFINED 0x80000000
-
-typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
-
-
-/* CK_MECHANISM is a structure that specifies a particular
- * mechanism */
-typedef struct CK_MECHANISM {
- CK_MECHANISM_TYPE mechanism;
- CK_VOID_PTR pParameter;
-
- /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
- CK_ULONG ulParameterLen; /* in bytes */
-} CK_MECHANISM;
-
-typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
-
-
-/* CK_MECHANISM_INFO provides information about a particular
- * mechanism */
-typedef struct CK_MECHANISM_INFO {
- CK_ULONG ulMinKeySize;
- CK_ULONG ulMaxKeySize;
- CK_FLAGS flags;
-} CK_MECHANISM_INFO;
-
-/* The flags are defined as follows:
- * Bit Flag Mask Meaning */
-#define CKF_HW 0x00000001 /* performed by HW */
-
-/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
- * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
- * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
- * and CKF_DERIVE are new for v2.0. They specify whether or not
- * a mechanism can be used for a particular task */
-#define CKF_ENCRYPT 0x00000100
-#define CKF_DECRYPT 0x00000200
-#define CKF_DIGEST 0x00000400
-#define CKF_SIGN 0x00000800
-#define CKF_SIGN_RECOVER 0x00001000
-#define CKF_VERIFY 0x00002000
-#define CKF_VERIFY_RECOVER 0x00004000
-#define CKF_GENERATE 0x00008000
-#define CKF_GENERATE_KEY_PAIR 0x00010000
-#define CKF_WRAP 0x00020000
-#define CKF_UNWRAP 0x00040000
-#define CKF_DERIVE 0x00080000
-
-#define CKF_EXTENSION 0x80000000 /* FALSE for 2.01 */
-
-typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
-
-
-/* CK_RV is a value that identifies the return value of a
- * Cryptoki function */
-/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
-typedef CK_ULONG CK_RV;
-
-#define CKR_OK 0x00000000
-#define CKR_CANCEL 0x00000001
-#define CKR_HOST_MEMORY 0x00000002
-#define CKR_SLOT_ID_INVALID 0x00000003
-
-/* CKR_FLAGS_INVALID was removed for v2.0 */
-
-/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
-#define CKR_GENERAL_ERROR 0x00000005
-#define CKR_FUNCTION_FAILED 0x00000006
-
-/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
- * and CKR_CANT_LOCK are new for v2.01 */
-#define CKR_ARGUMENTS_BAD 0x00000007
-#define CKR_NO_EVENT 0x00000008
-#define CKR_NEED_TO_CREATE_THREADS 0x00000009
-#define CKR_CANT_LOCK 0x0000000A
-
-#define CKR_ATTRIBUTE_READ_ONLY 0x00000010
-#define CKR_ATTRIBUTE_SENSITIVE 0x00000011
-#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012
-#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013
-#define CKR_DATA_INVALID 0x00000020
-#define CKR_DATA_LEN_RANGE 0x00000021
-#define CKR_DEVICE_ERROR 0x00000030
-#define CKR_DEVICE_MEMORY 0x00000031
-#define CKR_DEVICE_REMOVED 0x00000032
-#define CKR_ENCRYPTED_DATA_INVALID 0x00000040
-#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041
-#define CKR_FUNCTION_CANCELED 0x00000050
-#define CKR_FUNCTION_NOT_PARALLEL 0x00000051
-
-/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
-#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054
-
-#define CKR_KEY_HANDLE_INVALID 0x00000060
-
-/* CKR_KEY_SENSITIVE was removed for v2.0 */
-
-#define CKR_KEY_SIZE_RANGE 0x00000062
-#define CKR_KEY_TYPE_INCONSISTENT 0x00000063
-
-/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
- * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
- * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
- * v2.0 */
-#define CKR_KEY_NOT_NEEDED 0x00000064
-#define CKR_KEY_CHANGED 0x00000065
-#define CKR_KEY_NEEDED 0x00000066
-#define CKR_KEY_INDIGESTIBLE 0x00000067
-#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068
-#define CKR_KEY_NOT_WRAPPABLE 0x00000069
-#define CKR_KEY_UNEXTRACTABLE 0x0000006A
-
-#define CKR_MECHANISM_INVALID 0x00000070
-#define CKR_MECHANISM_PARAM_INVALID 0x00000071
-
-/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
- * were removed for v2.0 */
-#define CKR_OBJECT_HANDLE_INVALID 0x00000082
-#define CKR_OPERATION_ACTIVE 0x00000090
-#define CKR_OPERATION_NOT_INITIALIZED 0x00000091
-#define CKR_PIN_INCORRECT 0x000000A0
-#define CKR_PIN_INVALID 0x000000A1
-#define CKR_PIN_LEN_RANGE 0x000000A2
-
-/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
-#define CKR_PIN_EXPIRED 0x000000A3
-#define CKR_PIN_LOCKED 0x000000A4
-
-#define CKR_SESSION_CLOSED 0x000000B0
-#define CKR_SESSION_COUNT 0x000000B1
-#define CKR_SESSION_HANDLE_INVALID 0x000000B3
-#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4
-#define CKR_SESSION_READ_ONLY 0x000000B5
-#define CKR_SESSION_EXISTS 0x000000B6
-
-/* CKR_SESSION_READ_ONLY_EXISTS and
- * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
-#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7
-#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8
-
-#define CKR_SIGNATURE_INVALID 0x000000C0
-#define CKR_SIGNATURE_LEN_RANGE 0x000000C1
-#define CKR_TEMPLATE_INCOMPLETE 0x000000D0
-#define CKR_TEMPLATE_INCONSISTENT 0x000000D1
-#define CKR_TOKEN_NOT_PRESENT 0x000000E0
-#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1
-#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2
-#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0
-#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1
-#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2
-#define CKR_USER_ALREADY_LOGGED_IN 0x00000100
-#define CKR_USER_NOT_LOGGED_IN 0x00000101
-#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102
-#define CKR_USER_TYPE_INVALID 0x00000103
-
-/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
- * are new to v2.01 */
-#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104
-#define CKR_USER_TOO_MANY_TYPES 0x00000105
-
-#define CKR_WRAPPED_KEY_INVALID 0x00000110
-#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112
-#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113
-#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114
-#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115
-#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120
-
-/* These are new to v2.0 */
-#define CKR_RANDOM_NO_RNG 0x00000121
-#define CKR_BUFFER_TOO_SMALL 0x00000150
-#define CKR_SAVED_STATE_INVALID 0x00000160
-#define CKR_INFORMATION_SENSITIVE 0x00000170
-#define CKR_STATE_UNSAVEABLE 0x00000180
-
-/* These are new to v2.01 */
-#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190
-#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191
-#define CKR_MUTEX_BAD 0x000001A0
-#define CKR_MUTEX_NOT_LOCKED 0x000001A1
-
-#define CKR_VENDOR_DEFINED 0x80000000
-
-
-/* CK_NOTIFY is an application callback that processes events */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_NOTIFICATION event,
- CK_VOID_PTR pApplication /* passed to C_OpenSession */
-);
-
-
-/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
- * version and pointers of appropriate types to all the
- * Cryptoki functions */
-/* CK_FUNCTION_LIST is new for v2.0 */
-typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
-
-typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
-
-typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
-
-
-/* CK_CREATEMUTEX is an application callback for creating a
- * mutex object */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
- CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */
-);
-
-
-/* CK_DESTROYMUTEX is an application callback for destroying a
- * mutex object */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
- CK_VOID_PTR pMutex /* pointer to mutex */
-);
-
-
-/* CK_LOCKMUTEX is an application callback for locking a mutex */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
- CK_VOID_PTR pMutex /* pointer to mutex */
-);
-
-
-/* CK_UNLOCKMUTEX is an application callback for unlocking a
- * mutex */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
- CK_VOID_PTR pMutex /* pointer to mutex */
-);
-
-
-/* CK_C_INITIALIZE_ARGS provides the optional arguments to
- * C_Initialize */
-typedef struct CK_C_INITIALIZE_ARGS {
- CK_CREATEMUTEX CreateMutex;
- CK_DESTROYMUTEX DestroyMutex;
- CK_LOCKMUTEX LockMutex;
- CK_UNLOCKMUTEX UnlockMutex;
- CK_FLAGS flags;
-#ifdef FGMR
- CK_BYTE_PTR pConfig;
- CK_ULONG ulConfigLen;
-#endif /* FGMR */
- CK_VOID_PTR pReserved;
-} CK_C_INITIALIZE_ARGS;
-
-/* flags: bit flags that provide capabilities of the slot
- * Bit Flag Mask Meaning
- */
-#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
-#define CKF_OS_LOCKING_OK 0x00000002
-
-typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
-
-
-/* additional flags for parameters to functions */
-
-/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
-#define CKF_DONT_BLOCK 1
-
-
-/* CK_KEA_DERIVE_PARAMS provides the parameters to the
- * CKM_KEA_DERIVE mechanism */
-/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
-typedef struct CK_KEA_DERIVE_PARAMS {
- CK_BBOOL isSender;
- CK_ULONG ulRandomLen;
- CK_BYTE_PTR pRandomA;
- CK_BYTE_PTR pRandomB;
- CK_ULONG ulPublicDataLen;
- CK_BYTE_PTR pPublicData;
-} CK_KEA_DERIVE_PARAMS;
-
-typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
-
-
-/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
- * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just
- * holds the effective keysize */
-typedef CK_ULONG CK_RC2_PARAMS;
-
-typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
-
-
-/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
- * mechanism */
-typedef struct CK_RC2_CBC_PARAMS {
- /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
- CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
-
- CK_BYTE iv[8]; /* IV for CBC mode */
-} CK_RC2_CBC_PARAMS;
-
-typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
-
-
-/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
- * CKM_RC2_MAC_GENERAL mechanism */
-/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
-typedef struct CK_RC2_MAC_GENERAL_PARAMS {
- CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
- CK_ULONG ulMacLength; /* Length of MAC in bytes */
-} CK_RC2_MAC_GENERAL_PARAMS;
-
-typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
- CK_RC2_MAC_GENERAL_PARAMS_PTR;
-
-
-/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
- * CKM_RC5_MAC mechanisms */
-/* CK_RC5_PARAMS is new for v2.0 */
-typedef struct CK_RC5_PARAMS {
- CK_ULONG ulWordsize; /* wordsize in bits */
- CK_ULONG ulRounds; /* number of rounds */
-} CK_RC5_PARAMS;
-
-typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
-
-
-/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
- * mechanism */
-/* CK_RC5_CBC_PARAMS is new for v2.0 */
-typedef struct CK_RC5_CBC_PARAMS {
- CK_ULONG ulWordsize; /* wordsize in bits */
- CK_ULONG ulRounds; /* number of rounds */
- CK_BYTE_PTR pIv; /* pointer to IV */
- CK_ULONG ulIvLen; /* length of IV in bytes */
-} CK_RC5_CBC_PARAMS;
-
-typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
-
-
-/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
- * CKM_RC5_MAC_GENERAL mechanism */
-/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
-typedef struct CK_RC5_MAC_GENERAL_PARAMS {
- CK_ULONG ulWordsize; /* wordsize in bits */
- CK_ULONG ulRounds; /* number of rounds */
- CK_ULONG ulMacLength; /* Length of MAC in bytes */
-} CK_RC5_MAC_GENERAL_PARAMS;
-
-typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
- CK_RC5_MAC_GENERAL_PARAMS_PTR;
-
-
-/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
- * ciphers' MAC_GENERAL mechanisms. Its value is the length of
- * the MAC */
-/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
-typedef CK_ULONG CK_MAC_GENERAL_PARAMS;
-
-typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
-
-
-/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
- * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
-/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
-typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
- CK_ULONG ulPasswordLen;
- CK_BYTE_PTR pPassword;
- CK_ULONG ulPublicDataLen;
- CK_BYTE_PTR pPublicData;
- CK_ULONG ulPAndGLen;
- CK_ULONG ulQLen;
- CK_ULONG ulRandomLen;
- CK_BYTE_PTR pRandomA;
- CK_BYTE_PTR pPrimeP;
- CK_BYTE_PTR pBaseG;
- CK_BYTE_PTR pSubprimeQ;
-} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
-
-typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
- CK_SKIPJACK_PRIVATE_WRAP_PTR;
-
-
-/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
- * CKM_SKIPJACK_RELAYX mechanism */
-/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
-typedef struct CK_SKIPJACK_RELAYX_PARAMS {
- CK_ULONG ulOldWrappedXLen;
- CK_BYTE_PTR pOldWrappedX;
- CK_ULONG ulOldPasswordLen;
- CK_BYTE_PTR pOldPassword;
- CK_ULONG ulOldPublicDataLen;
- CK_BYTE_PTR pOldPublicData;
- CK_ULONG ulOldRandomLen;
- CK_BYTE_PTR pOldRandomA;
- CK_ULONG ulNewPasswordLen;
- CK_BYTE_PTR pNewPassword;
- CK_ULONG ulNewPublicDataLen;
- CK_BYTE_PTR pNewPublicData;
- CK_ULONG ulNewRandomLen;
- CK_BYTE_PTR pNewRandomA;
-} CK_SKIPJACK_RELAYX_PARAMS;
-
-typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
- CK_SKIPJACK_RELAYX_PARAMS_PTR;
-
-
-typedef struct CK_PBE_PARAMS {
- CK_CHAR_PTR pInitVector;
- CK_CHAR_PTR pPassword;
- CK_ULONG ulPasswordLen;
- CK_CHAR_PTR pSalt;
- CK_ULONG ulSaltLen;
- CK_ULONG ulIteration;
-} CK_PBE_PARAMS;
-
-typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
-
-
-/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
- * CKM_KEY_WRAP_SET_OAEP mechanism */
-/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
-typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
- CK_BYTE bBC; /* block contents byte */
- CK_BYTE_PTR pX; /* extra data */
- CK_ULONG ulXLen; /* length of extra data in bytes */
-} CK_KEY_WRAP_SET_OAEP_PARAMS;
-
-typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
- CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
-
-
-typedef struct CK_SSL3_RANDOM_DATA {
- CK_BYTE_PTR pClientRandom;
- CK_ULONG ulClientRandomLen;
- CK_BYTE_PTR pServerRandom;
- CK_ULONG ulServerRandomLen;
-} CK_SSL3_RANDOM_DATA;
-
-
-typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
- CK_SSL3_RANDOM_DATA RandomInfo;
- CK_VERSION_PTR pVersion;
-} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
-
-typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
- CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
-
-
-typedef struct CK_SSL3_KEY_MAT_OUT {
- CK_OBJECT_HANDLE hClientMacSecret;
- CK_OBJECT_HANDLE hServerMacSecret;
- CK_OBJECT_HANDLE hClientKey;
- CK_OBJECT_HANDLE hServerKey;
- CK_BYTE_PTR pIVClient;
- CK_BYTE_PTR pIVServer;
-} CK_SSL3_KEY_MAT_OUT;
-
-typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
-
-
-typedef struct CK_SSL3_KEY_MAT_PARAMS {
- CK_ULONG ulMacSizeInBits;
- CK_ULONG ulKeySizeInBits;
- CK_ULONG ulIVSizeInBits;
- CK_BBOOL bIsExport;
- CK_SSL3_RANDOM_DATA RandomInfo;
- CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
-} CK_SSL3_KEY_MAT_PARAMS;
-
-typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
-
-
-typedef struct CK_KEY_DERIVATION_STRING_DATA {
- CK_BYTE_PTR pData;
- CK_ULONG ulLen;
-} CK_KEY_DERIVATION_STRING_DATA;
-
-typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
- CK_KEY_DERIVATION_STRING_DATA_PTR;
-
-
-/* The CK_EXTRACT_PARAMS is used for the
- * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit
- * of the base key should be used as the first bit of the
- * derived key */
-/* CK_EXTRACT_PARAMS is new for v2.0 */
-typedef CK_ULONG CK_EXTRACT_PARAMS;
-
-typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
-
-/* undo packing */
-#include "nsscku.h"
+#endif /* _NSSCKT_H_ */
-#endif /* NSSCKT_H */
diff --git a/security/nss/lib/cryptohi/seckey.c b/security/nss/lib/cryptohi/seckey.c
index 78ad26115..076dbc6a6 100644
--- a/security/nss/lib/cryptohi/seckey.c
+++ b/security/nss/lib/cryptohi/seckey.c
@@ -860,7 +860,7 @@ seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki)
pubk->arena = arena;
pubk->pkcs11Slot = 0;
- pubk->pkcs11ID = CK_INVALID_KEY;
+ pubk->pkcs11ID = CK_INVALID_HANDLE;
/* Convert bit string length from bits to bytes */
@@ -1037,7 +1037,7 @@ SECKEY_CopyPrivateKey(SECKEYPrivateKey *privk)
if (privk->pkcs11IsTemp) {
copyk->pkcs11ID =
PK11_CopyKey(privk->pkcs11Slot,privk->pkcs11ID);
- if (copyk->pkcs11ID == CK_INVALID_KEY) goto fail;
+ if (copyk->pkcs11ID == CK_INVALID_HANDLE) goto fail;
} else {
copyk->pkcs11ID = privk->pkcs11ID;
}
@@ -1072,7 +1072,7 @@ SECKEY_CopyPublicKey(SECKEYPublicKey *pubk)
copyk->arena = arena;
copyk->keyType = pubk->keyType;
copyk->pkcs11Slot = NULL; /* go get own reference */
- copyk->pkcs11ID = CK_INVALID_KEY;
+ copyk->pkcs11ID = CK_INVALID_HANDLE;
switch (pubk->keyType) {
case rsaKey:
rv = SECITEM_CopyItem(arena, &copyk->u.rsa.modulus,
@@ -1201,7 +1201,7 @@ SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk)
}
pubk->keyType = privk->keyType;
pubk->pkcs11Slot = NULL;
- pubk->pkcs11ID = CK_INVALID_KEY;
+ pubk->pkcs11ID = CK_INVALID_HANDLE;
pubk->arena = arena;
/*
diff --git a/security/nss/lib/dev/ckhelper.h b/security/nss/lib/dev/ckhelper.h
index 5088a3b7f..d1da20500 100644
--- a/security/nss/lib/dev/ckhelper.h
+++ b/security/nss/lib/dev/ckhelper.h
@@ -44,13 +44,9 @@
static const char CKHELPER_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#endif /* DEBUG */
-#ifdef NSS_3_4_CODE
-#include "pkcs11t.h"
-#else
#ifndef NSSCKT_H
#include "nssckt.h"
#endif /* NSSCKT_H */
-#endif /* NSS_3_4_CODE */
PR_BEGIN_EXTERN_C
diff --git a/security/nss/lib/dev/dev.h b/security/nss/lib/dev/dev.h
index 7333cb69a..0bca3fc46 100644
--- a/security/nss/lib/dev/dev.h
+++ b/security/nss/lib/dev/dev.h
@@ -42,13 +42,9 @@ static const char DEV_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#include "devt.h"
#endif /* DEVT_H */
-#ifdef NSS_3_4_CODE
-#include "pkcs11t.h"
-#else
#ifndef NSSCKT_H
#include "nssckt.h"
#endif /* NSSCKT_H */
-#endif /* NSS_3_4_CODE */
#ifndef NSSPKIT_H
#include "nsspkit.h"
diff --git a/security/nss/lib/dev/devm.h b/security/nss/lib/dev/devm.h
index 989198600..d226069c9 100644
--- a/security/nss/lib/dev/devm.h
+++ b/security/nss/lib/dev/devm.h
@@ -42,13 +42,9 @@ static const char DEVM_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#include "devt.h"
#endif /* DEVT_H */
-#ifdef NSS_3_4_CODE
-#include "pkcs11t.h"
-#else
#ifndef NSSCKT_H
#include "nssckt.h"
#endif /* NSSCKT_H */
-#endif /* NSS_3_4_CODE */
#ifndef BASE_H
#include "base.h"
diff --git a/security/nss/lib/dev/module.c b/security/nss/lib/dev/devmod.c
index a3cb0b164..301799b77 100644
--- a/security/nss/lib/dev/module.c
+++ b/security/nss/lib/dev/devmod.c
@@ -35,6 +35,8 @@
static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#endif /* DEBUG */
+#include "nspr.h"
+
#ifndef DEV_H
#include "dev.h"
#endif /* DEV_H */
@@ -43,13 +45,9 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#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"
@@ -252,7 +250,7 @@ nssModule_Load
CK_C_GetFunctionList ep;
CK_RV ckrv;
/* Use NSPR to load the library */
- library = PR_LoadLibrary(mod->libraryPath);
+ library = PR_LoadLibrary((char *)mod->libraryPath);
if (!library) {
/* what's the error to set? */
return PR_FAILURE;
diff --git a/security/nss/lib/dev/slot.c b/security/nss/lib/dev/devslot.c
index 25e16d2c4..25e16d2c4 100644
--- a/security/nss/lib/dev/slot.c
+++ b/security/nss/lib/dev/devslot.c
diff --git a/security/nss/lib/dev/devt.h b/security/nss/lib/dev/devt.h
index f2deaa130..cf8a6309a 100644
--- a/security/nss/lib/dev/devt.h
+++ b/security/nss/lib/dev/devt.h
@@ -56,13 +56,12 @@ static const char DEVT_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#include "nssdevt.h"
#endif /* NSSDEVT_H */
-#ifdef NSS_3_4_CODE
-#include "pkcs11t.h"
-#include "secmodt.h"
-#else
#ifndef NSSCKT_H
#include "nssckt.h"
#endif /* NSSCKT_H */
+
+#ifdef NSS_3_4_CODE
+#include "secmodt.h"
#endif /* NSS_3_4_CODE */
PR_BEGIN_EXTERN_C
diff --git a/security/nss/lib/dev/token.c b/security/nss/lib/dev/devtoken.c
index 341583b8c..ceb7b2441 100644
--- a/security/nss/lib/dev/token.c
+++ b/security/nss/lib/dev/devtoken.c
@@ -48,13 +48,9 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#include "pki.h"
#endif /* PKI_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 NSSPKI_H
#include "nsspki.h"
@@ -219,25 +215,30 @@ nssToken_DeleteStoredObject
CK_OBJECT_HANDLE object
)
{
- nssSession *session;
+ nssSession *session = NULL;
CK_RV ckrv;
PRStatus nssrv;
PRBool createdSession;
if (nssCKObject_IsAttributeTrue(object, CKA_TOKEN, tok->defaultSession,
- tok->slot, &nssrv)) {
- if (sessionOpt) {
- if (!nssSession_IsReadWrite(sessionOpt)) {
- return PR_FAILURE;;
- } else {
- session = sessionOpt;
- }
- } else if (nssSession_IsReadWrite(tok->defaultSession)) {
- session = tok->defaultSession;
- } else {
- session = nssSlot_CreateSession(tok->slot, NULL, PR_TRUE);
- createdSession = PR_TRUE;
- }
+ tok->slot, &nssrv)) {
+ if (sessionOpt) {
+ if (!nssSession_IsReadWrite(sessionOpt)) {
+ return PR_FAILURE;;
+ } else {
+ session = sessionOpt;
+ }
+ } else if (nssSession_IsReadWrite(tok->defaultSession)) {
+ session = tok->defaultSession;
+ } else {
+ session = nssSlot_CreateSession(tok->slot, NULL, PR_TRUE);
+ createdSession = PR_TRUE;
+ }
}
+
+ if (session == NULL) {
+ return PR_FAILURE;
+ }
+
nssSession_EnterMonitor(session);
ckrv = CKAPI(tok->slot)->C_DestroyObject(session->handle, object);
nssSession_ExitMonitor(session);
@@ -259,10 +260,11 @@ nssToken_ImportObject
CK_ULONG otsize
)
{
- nssSession *session;
+ 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)) {
@@ -277,6 +279,9 @@ nssToken_ImportObject
createdSession = PR_TRUE;
}
}
+ if (session == NULL) {
+ return PR_FAILURE;
+ }
nssSession_EnterMonitor(session);
ckrv = CKAPI(tok->slot)->C_CreateObject(session->handle,
objectTemplate, otsize,
@@ -311,17 +316,17 @@ nssToken_FindObjectByTemplate
ckrv = CKAPI(tok)->C_FindObjectsInit(hSession, cktemplate, ctsize);
if (ckrv != CKR_OK) {
nssSession_ExitMonitor(session);
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
ckrv = CKAPI(tok)->C_FindObjects(hSession, &rvObject, 1, &count);
if (ckrv != CKR_OK) {
nssSession_ExitMonitor(session);
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
ckrv = CKAPI(tok)->C_FindObjectsFinal(hSession);
nssSession_ExitMonitor(session);
if (ckrv != CKR_OK) {
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
return rvObject;
}
diff --git a/security/nss/lib/dev/util.c b/security/nss/lib/dev/devutil.c
index 02db7831b..02db7831b 100644
--- a/security/nss/lib/dev/util.c
+++ b/security/nss/lib/dev/devutil.c
diff --git a/security/nss/lib/dev/manifest.mn b/security/nss/lib/dev/manifest.mn
index 570eeae73..279bfe0b2 100644
--- a/security/nss/lib/dev/manifest.mn
+++ b/security/nss/lib/dev/manifest.mn
@@ -47,17 +47,15 @@ EXPORTS = \
MODULE = security
CSRCS = \
- module.c \
- slot.c \
- token.c \
- util.c \
+ devmod.c \
+ devslot.c \
+ devtoken.c \
+ devutil.c \
ckhelper.c \
$(NULL)
# here is where the 3.4 glue code is added
ifndef PURE_STAN_BUILD
-CSRCS += nss3hack.c
-PRIVATE_EXPORTS += devnss3hack.h
DEFINES = -DNSS_3_4_CODE
endif
diff --git a/security/nss/lib/dev/nssdevt.h b/security/nss/lib/dev/nssdevt.h
index 61f9d1a50..a402ddddd 100644
--- a/security/nss/lib/dev/nssdevt.h
+++ b/security/nss/lib/dev/nssdevt.h
@@ -52,15 +52,6 @@ static const char NSSDEVT_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#include "nsspkit.h"
#endif /* NSSPKIT_H */
-#ifdef NSS_3_4_CODE
-#include "pkcs11t.h"
-#include "secmodt.h"
-#else
-#ifndef NSSCKT_H
-#include "nssckt.h"
-#endif /* NSSCKT_H */
-#endif /* NSS_3_4_CODE */
-
PR_BEGIN_EXTERN_C
/*
diff --git a/security/nss/lib/fortcrypt/swfort/pkcs11/Makefile b/security/nss/lib/fortcrypt/swfort/pkcs11/Makefile
index 00c911bc6..495e70ae3 100644
--- a/security/nss/lib/fortcrypt/swfort/pkcs11/Makefile
+++ b/security/nss/lib/fortcrypt/swfort/pkcs11/Makefile
@@ -55,7 +55,7 @@ endif
# $(DIST)/lib/$(NSPR31_LIB_PREFIX)nspr4.lib
EXTRA_LIBS = \
$(DIST)/lib/swfci.lib \
- $(DIST)/lib/softoken.lib \
+ $(DIST)/lib/softokn.lib \
$(CRYPTO_LIB) \
$(DIST)/lib/secutil.lib \
$(DIST)/lib/$(NSPR31_LIB_PREFIX)plc4_s.lib \
@@ -89,7 +89,7 @@ endif
EXTRA_LIBS += \
$(DIST)/lib/libswfci.$(LIB_SUFFIX) \
- $(DIST)/lib/libsoftoken.$(LIB_SUFFIX) \
+ $(DIST)/lib/libsoftokn.$(LIB_SUFFIX) \
$(CRYPTO_LIB) \
$(DIST)/lib/libsecutil.$(LIB_SUFFIX) \
$(PLC_STATIC_LIB) \
diff --git a/security/nss/lib/jar/jarevil.c b/security/nss/lib/jar/jarevil.c
index 8ceba9d3c..56dc5dbc3 100644
--- a/security/nss/lib/jar/jarevil.c
+++ b/security/nss/lib/jar/jarevil.c
@@ -394,7 +394,7 @@ struct EVIL_certkey
int error;
CERTCertificate *cert;
CERTCertDBHandle *certdb;
- SECItem *seckey;
+ CERTIssuerAndSN *seckey;
};
@@ -407,7 +407,7 @@ PR_STATIC_CALLBACK(void) jar_moz_certkey_fn (void *data)
PORT_SetError (certkey_data->error);
- cert = CERT_FindCertByKey (certkey_data->certdb, certkey_data->seckey);
+ cert=CERT_FindCertByIssuerAndSN(certkey_data->certdb, certkey_data->seckey);
certkey_data->cert = cert;
certkey_data->error = PORT_GetError();
@@ -416,7 +416,8 @@ PR_STATIC_CALLBACK(void) jar_moz_certkey_fn (void *data)
/* Wrapper for the ET_MOZ call */
-CERTCertificate *jar_moz_certkey (CERTCertDBHandle *certdb, SECItem *seckey)
+CERTCertificate *jar_moz_certkey (CERTCertDBHandle *certdb,
+ CERTIssuerAndSN *seckey)
{
CERTCertificate *cert;
ALLOC_OR_DEFINE(struct EVIL_certkey, certkey_data, NULL);
diff --git a/security/nss/lib/jar/jarevil.h b/security/nss/lib/jar/jarevil.h
index a7c835e6c..95b4f6883 100644
--- a/security/nss/lib/jar/jarevil.h
+++ b/security/nss/lib/jar/jarevil.h
@@ -68,7 +68,7 @@ extern SECStatus jar_moz_perm
(CERTCertificate *cert, char *nickname, CERTCertTrust *trust);
extern CERTCertificate *jar_moz_certkey
- (CERTCertDBHandle *certdb, SECItem *seckey);
+ (CERTCertDBHandle *certdb, CERTIssuerAndSN *seckey);
extern CERTCertificate *jar_moz_issuer (CERTCertificate *cert);
diff --git a/security/nss/lib/jar/jarint.h b/security/nss/lib/jar/jarint.h
index a107f8c2b..7baa4f3f1 100644
--- a/security/nss/lib/jar/jarint.h
+++ b/security/nss/lib/jar/jarint.h
@@ -36,7 +36,7 @@
#include "nspr.h"
/* definitely required */
-#include "certdb.h"
+/*#include "certdb.h" */
#include "key.h"
#include "base64.h"
diff --git a/security/nss/lib/jar/jarver.c b/security/nss/lib/jar/jarver.c
index a7f5bdb77..af1a28328 100644
--- a/security/nss/lib/jar/jarver.c
+++ b/security/nss/lib/jar/jarver.c
@@ -45,7 +45,7 @@
#ifdef USE_MOZ_THREAD
#include "jarevil.h"
#endif
-#include "cdbhdl.h"
+/*#include "cdbhdl.h" */
#include "secder.h"
/* to use huge pointers in win16 */
@@ -74,11 +74,12 @@ extern SECStatus SEC_AddTempNickname
(CERTCertDBHandle *handle, char *nickname, SECItem *certKey);
/* from certdb.h */
typedef SECStatus (* PermCertCallback)(CERTCertificate *cert, SECItem *k, void *pdata);
-#endif
/* from certdb.h */
SECStatus SEC_TraversePermCerts
(CERTCertDBHandle *handle, PermCertCallback certfunc, void *udata);
+#endif
+
#define SZ 512
@@ -856,6 +857,7 @@ static int jar_add_cert
(JAR *jar, JAR_Signer *signer, int type, CERTCertificate *cert)
{
JAR_Cert *fing;
+ unsigned char *keyData;
if (cert == NULL)
return JAR_ERR_ORDER;
@@ -873,14 +875,18 @@ static int jar_add_cert
/* get the certkey */
- fing->length = cert->certKey.len;
+ fing->length = cert->derIssuer.len + 2 + cert->serialNumber.len;
- fing->key = (char *) PORT_ZAlloc (fing->length);
+ keyData = (unsigned char *) PORT_ZAlloc (fing->length);
+ fing->key = keyData;
if (fing->key == NULL)
goto loser;
-
- PORT_Memcpy (fing->key, cert->certKey.data, fing->length);
+ keyData[0] = ((cert->derIssuer.len) >> 8) & 0xff;
+ keyData[1] = ((cert->derIssuer.len) & 0xff);
+ PORT_Memcpy (&keyData[2], cert->derIssuer.data, cert->derIssuer.len);
+ PORT_Memcpy (&keyData[2+cert->derIssuer.len], cert->serialNumber.data,
+ cert->serialNumber.len);
ADDITEM (signer->certs, type,
/* pathname */ NULL, fing, sizeof (JAR_Cert));
@@ -1518,7 +1524,7 @@ extern int PR_CALLBACK JAR_stash_cert
void *JAR_fetch_cert (long length, void *key)
{
- SECItem seckey;
+ CERTIssuerAndSN issuerSN;
CERTCertificate *cert = NULL;
CERTCertDBHandle *certdb;
@@ -1527,13 +1533,16 @@ void *JAR_fetch_cert (long length, void *key)
if (certdb)
{
- seckey.len = length;
- seckey.data = (unsigned char*)key;
+ unsigned char *keyData = (unsigned char *)key;
+ issuerSN.derIssuer.len = (keyData[0] << 8) + keyData[0];
+ issuerSN.derIssuer.data = &keyData[2];
+ issuerSN.serialNumber.len = length - (2 + issuerSN.derIssuer.len);
+ issuerSN.serialNumber.data = &keyData[2+issuerSN.derIssuer.len];
#ifdef USE_MOZ_THREAD
- cert = jar_moz_certkey (certdb, &seckey);
+ cert = jar_moz_certkey (certdb, &issuerSN);
#else
- cert = CERT_FindCertByKey (certdb, &seckey);
+ cert = CERT_FindCertByIssuerAndSN (certdb, &issuerSN);
#endif
JAR_close_database (certdb);
@@ -1816,21 +1825,8 @@ CERTCertDBHandle *JAR_open_database (void)
int keepcerts = 0;
CERTCertDBHandle *certdb;
- /* local_certdb will only be used if calling from a command line tool */
- static CERTCertDBHandle local_certdb;
-
certdb = CERT_GetDefaultCertDB();
- if (certdb == NULL)
- {
- if (CERT_OpenCertDBFilename (&local_certdb, NULL, (PRBool)!keepcerts) !=
- SECSuccess)
- {
- return NULL;
- }
- certdb = &local_certdb;
- }
-
return certdb;
}
@@ -1844,6 +1840,7 @@ CERTCertDBHandle *JAR_open_database (void)
int JAR_close_database (CERTCertDBHandle *certdb)
{
+#ifdef notdef
CERTCertDBHandle *defaultdb;
/* This really just retrieves the handle, nothing more */
@@ -1854,6 +1851,7 @@ int JAR_close_database (CERTCertDBHandle *certdb)
if (defaultdb == NULL && certdb != NULL)
CERT_ClosePermCertDB (certdb);
+#endif
return 0;
}
diff --git a/security/nss/lib/manifest.mn b/security/nss/lib/manifest.mn
index 1e3274293..2738cf722 100644
--- a/security/nss/lib/manifest.mn
+++ b/security/nss/lib/manifest.mn
@@ -33,29 +33,25 @@
CORE_DEPTH = ../..
DEPTH = ../..
-DIRS = \
- base \
- asn1 \
- dev \
- pki \
- pki1 \
- crmf \
- jar \
- certhigh \
- pk11wrap \
- cryptohi \
- softoken \
- certdb \
- crypto \
- util \
- freebl \
- nss \
- pkcs12 \
- fortcrypt \
- pkcs7 \
- smime \
- ssl \
+#
+# organized by DLL
+#
+# softoken and prereqs.
+# stan (not a separate dll yet)
+# nss base (traditional)
+# ssl
+# smime
+# ckfw (builtins module)
+# crmf jar (not dll's)
+# fortcrypt
+DIRS = util freebl softoken \
+ base asn1 dev pki pki1 \
+ certdb certhigh pk11wrap cryptohi crypto nss \
+ ssl \
+ pkcs12 pkcs7 smime \
+ crmf jar \
ckfw \
+ fortcrypt \
$(NULL)
# NSS 4.0 build - pure stan libraries
diff --git a/security/nss/lib/nss/config.mk b/security/nss/lib/nss/config.mk
index c33cdd3ab..dec348831 100644
--- a/security/nss/lib/nss/config.mk
+++ b/security/nss/lib/nss/config.mk
@@ -48,25 +48,15 @@ ifeq ($(OS_ARCH), WINNT)
SHARED_LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).dll
IMPORT_LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).lib
-DLLFLAGS += -DEF:nss.def
-RES = $(OBJDIR)/nss.res
-RESNAME = nss.rc
+RES = $(OBJDIR)/$(LIBRARY_NAME).res
+RESNAME = $(LIBRARY_NAME).rc
# $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
-CRYPTOLIB=$(DIST)/lib/freebl.lib
-CRYPTODIR=../freebl
-ifdef MOZILLA_SECURITY_BUILD
- CRYPTOLIB=$(DIST)/lib/crypto.lib
- CRYPTODIR=../crypto
-endif
-
SHARED_LIBRARY_LIBS = \
$(DIST)/lib/certhi.lib \
$(DIST)/lib/cryptohi.lib \
$(DIST)/lib/pk11wrap.lib \
$(DIST)/lib/certdb.lib \
- $(DIST)/lib/softoken.lib \
- $(CRYPTOLIB) \
$(DIST)/lib/secutil.lib \
$(DIST)/lib/nsspki.lib \
$(DIST)/lib/nssdev.lib \
@@ -78,67 +68,37 @@ SHARED_LIBRARY_DIRS = \
../cryptohi \
../pk11wrap \
../certdb \
- ../softoken \
- $(CRYPTODIR) \
../util \
../pki \
../dev \
../base \
$(NULL)
-EXTRA_LIBS += \
- $(DIST)/lib/dbm.lib \
- $(NULL)
-
-ifdef MOZILLA_BSAFE_BUILD
- EXTRA_LIBS+=$(DIST)/lib/bsafe$(BSAFEVER).lib
-endif
-
EXTRA_SHARED_LIBS += \
+ $(DIST)/lib/softokn3.lib \
$(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)
-CRYPTOLIB=$(DIST)/lib/libfreebl.$(LIB_SUFFIX)
-CRYPTODIR=../freebl
-ifdef MOZILLA_SECURITY_BUILD
- CRYPTOLIB=$(DIST)/lib/libcrypto.$(LIB_SUFFIX)
- CRYPTODIR=../crypto
-endif
SHARED_LIBRARY_LIBS = \
$(DIST)/lib/libcerthi.$(LIB_SUFFIX) \
$(DIST)/lib/libpk11wrap.$(LIB_SUFFIX) \
$(DIST)/lib/libcryptohi.$(LIB_SUFFIX) \
- $(DIST)/lib/libsoftoken.$(LIB_SUFFIX) \
$(DIST)/lib/libcertdb.$(LIB_SUFFIX) \
- $(CRYPTOLIB) \
$(DIST)/lib/libsecutil.$(LIB_SUFFIX) \
$(DIST)/lib/libnsspki.$(LIB_SUFFIX) \
$(DIST)/lib/libnssdev.$(LIB_SUFFIX) \
$(DIST)/lib/libnssb.$(LIB_SUFFIX) \
$(NULL)
-EXTRA_LIBS += \
- $(DIST)/lib/libdbm.$(LIB_SUFFIX) \
- $(NULL)
-ifdef MOZILLA_BSAFE_BUILD
- EXTRA_LIBS+=$(DIST)/lib/libbsafe.$(LIB_SUFFIX)
-endif
+
SHARED_LIBRARY_DIRS = \
../certhigh \
../pk11wrap \
../cryptohi \
- ../softoken \
../certdb \
- $(CRYPTODIR) \
../util \
../pki \
../dev \
@@ -149,49 +109,10 @@ SHARED_LIBRARY_DIRS = \
# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
EXTRA_SHARED_LIBS += \
-L$(DIST)/lib/ \
+ -lsoftokn3 \
-lplc4 \
-lplds4 \
-lnspr4 \
$(NULL)
endif
-ifeq ($(OS_ARCH),SunOS)
-MAPFILE = $(OBJDIR)/nssmap.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_ARCH),AIX)
-MAPFILE = $(OBJDIR)/nssmap.aix
-ALL_TRASH += $(MAPFILE)
-EXPORT_RULES = -bexport:$(MAPFILE)
-endif
-
-ifeq ($(OS_ARCH),HP-UX)
-MAPFILE = $(OBJDIR)/nssmap.hp
-ALL_TRASH += $(MAPFILE)
-MKSHLIB += -c $(MAPFILE)
-endif
-
-ifeq ($(OS_ARCH), OSF1)
-MAPFILE = $(OBJDIR)/nssmap.osf
-ALL_TRASH += $(MAPFILE)
-MKSHLIB += -hidden -input $(MAPFILE)
-endif
-
-ifeq ($(OS_ARCH),Linux)
-MAPFILE = $(OBJDIR)/nssmap.linux
-ALL_TRASH += $(MAPFILE)
-MKSHLIB += -Wl,--version-script,$(MAPFILE)
-endif
-
-
-
-
diff --git a/security/nss/lib/nss/manifest.mn b/security/nss/lib/nss/manifest.mn
index 5d822c170..1fbdc045d 100644
--- a/security/nss/lib/nss/manifest.mn
+++ b/security/nss/lib/nss/manifest.mn
@@ -49,5 +49,7 @@ CSRCS = \
REQUIRES = security dbm
+MAPFILE = $(OBJDIR)/nss.def
+
LIBRARY_NAME = nss
LIBRARY_VERSION = 3
diff --git a/security/nss/lib/nss/nss.def b/security/nss/lib/nss/nss.def
index fc1424372..75650ff24 100644
--- a/security/nss/lib/nss/nss.def
+++ b/security/nss/lib/nss/nss.def
@@ -564,6 +564,7 @@ SECMOD_LoadModule;
SECMOD_GetModuleSpecList;
SECMOD_FreeModuleSpecList;
SECMOD_UpdateModule;
+PK11_RawPBEKeyGen;
;+ local:
;+ *;
;+};
diff --git a/security/nss/lib/nss/nssinit.c b/security/nss/lib/nss/nssinit.c
index e63c569f4..fac40d786 100644
--- a/security/nss/lib/nss/nssinit.c
+++ b/security/nss/lib/nss/nssinit.c
@@ -50,7 +50,7 @@
#include "secrng.h"
#include "pk11func.h"
-#include "pkinss3hack.h"
+#include "pki3hack.h"
#define NSS_MAX_FLAG_SIZE sizeof("readOnly")+sizeof("noCertDB")+ \
sizeof("noModDB")+sizeof("forceOpen")+sizeof("passwordRequired")
@@ -241,6 +241,8 @@ nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix,
}
STAN_LoadDefaultNSS3TrustDomain();
+ CERT_SetDefaultCertDB((CERTCertDBHandle *)
+ STAN_GetDefaultTrustDomain());
return rv;
}
diff --git a/security/nss/lib/nss/nsssym.c b/security/nss/lib/nss/nsssym.c
deleted file mode 100644
index e0c53c993..000000000
--- a/security/nss/lib/nss/nsssym.c
+++ /dev/null
@@ -1,429 +0,0 @@
-
-#define INC_SSL 1
-#define INC_SMIME 1
-
-
-#ifdef INC_SSL
-extern int nss_InitLock;
-
-extern void ATOB_AsciiToData();
-extern void BTOA_DataToAscii();
-extern void CERT_CertChainFromCert();
-extern void CERT_CheckCertValidTimes();
-extern void CERT_DestroyCertificate();
-extern void CERT_DestroyCertificateList();
-extern void CERT_DupCertList();
-extern void CERT_DupCertificate();
-extern void CERT_ExtractPublicKey();
-extern void CERT_FindCertByName();
-extern void CERT_FreeNicknames();
-extern void CERT_GetCertNicknames();
-extern void CERT_GetDefaultCertDB();
-extern void CERT_GetSSLCACerts();
-extern void CERT_NameToAscii();
-extern void CERT_NewTempCertificate();
-extern void CERT_VerifyCertName();
-extern void CERT_VerifyCertNow();
-extern void DER_Lengths();
-extern void DSAU_DecodeDerSig();
-extern void DSAU_EncodeDerSig();
-extern void NSSRWLock_Destroy();
-extern void NSSRWLock_HaveWriteLock();
-extern void NSSRWLock_LockRead();
-extern void NSSRWLock_LockWrite();
-extern void NSSRWLock_New();
-extern void NSSRWLock_UnlockRead();
-extern void NSSRWLock_UnlockWrite();
-extern void NSS_PutEnv();
-extern void PK11_CipherOp();
-extern void PK11_CloneContext();
-extern void PK11_CreateContextByRawKey();
-extern void PK11_CreateContextBySymKey();
-extern void PK11_CreateDigestContext();
-extern void PK11_Derive();
-extern void PK11_DeriveWithFlags();
-extern void PK11_DestroyContext();
-extern void PK11_DigestBegin();
-extern void PK11_DigestFinal();
-extern void PK11_DigestKey();
-extern void PK11_DigestOp();
-extern void PK11_FindBestKEAMatch();
-extern void PK11_FindCertFromNickname();
-extern void PK11_FindFixedKey();
-extern void PK11_FindKeyByAnyCert();
-extern void PK11_FreeSlot();
-extern void PK11_FreeSymKey();
-extern void PK11_GenerateFortezzaIV();
-extern void PK11_GenerateRandom();
-extern void PK11_GetBestKeyLength();
-extern void PK11_GetBestSlot();
-extern void PK11_GetBestSlotMultiple();
-extern void PK11_GetBestWrapMechanism();
-extern void PK11_GetCurrentWrapIndex();
-extern void PK11_GetInternalSlot();
-extern void PK11_GetKeyData();
-extern void PK11_GetMechanism();
-extern void PK11_GetModuleID();
-extern void PK11_GetPrivateModulusLen();
-extern void PK11_GetSlotFromKey();
-extern void PK11_GetSlotFromPrivateKey();
-extern void PK11_GetSlotID();
-extern void PK11_GetSlotSeries();
-extern void PK11_GetTokenInfo();
-extern void PK11_GetWindow();
-extern void PK11_GetWrapKey();
-extern void PK11_IVFromParam();
-extern void PK11_IsPresent();
-extern void PK11_KeyGen();
-extern void PK11_MakeKEAPubKey();
-extern void PK11_ParamFromIV();
-extern void PK11_PubDecryptRaw();
-extern void PK11_PubDerive();
-extern void PK11_PubEncryptRaw();
-extern void PK11_PubUnwrapSymKey();
-extern void PK11_PubWrapSymKey();
-extern void PK11_ReferenceSymKey();
-extern void PK11_RestoreContext();
-extern void PK11_SaveContext();
-extern void PK11_SetFortezzaHack();
-extern void PK11_SetWrapKey();
-extern void PK11_Sign();
-extern void PK11_SignatureLen();
-extern void PK11_SymKeyFromHandle();
-extern void PK11_TokenExists();
-extern void PK11_UnwrapSymKey();
-extern void PK11_UnwrapSymKeyWithFlags();
-extern void PK11_Verify();
-extern void PK11_VerifyKeyOK();
-extern void PK11_WrapSymKey();
-extern void PORT_Alloc();
-extern void PORT_ArenaAlloc();
-extern void PORT_ArenaZAlloc();
-extern void PORT_Free();
-extern void PORT_FreeArena();
-extern void PORT_GetError();
-extern void PORT_NewArena();
-extern void PORT_Realloc();
-extern void PORT_SetError();
-extern void PORT_ZAlloc();
-extern void PORT_ZFree();
-extern void RSA_FormatBlock();
-extern void SECITEM_CompareItem();
-extern void SECITEM_CopyItem();
-extern void SECITEM_FreeItem();
-extern void SECITEM_ZfreeItem();
-extern void SECKEY_CopyPrivateKey();
-extern void SECKEY_CreateRSAPrivateKey();
-extern void SECKEY_DestroyPrivateKey();
-extern void SECKEY_DestroyPublicKey();
-extern void SECKEY_PublicKeyStrength();
-extern void SECKEY_UpdateCertPQG();
-extern void SECMOD_LookupSlot();
-extern void SECOID_GetAlgorithmTag();
-extern void SGN_Begin();
-extern void SGN_DestroyContext();
-extern void SGN_End();
-extern void SGN_NewContext();
-extern void SGN_Update();
-extern void VFY_Begin();
-extern void VFY_CreateContext();
-extern void VFY_DestroyContext();
-extern void VFY_End();
-extern void VFY_Update();
-
-void
-nss_referenceNSSFunctionsForSSL() {
- int tmp2 = nss_InitLock;
-
- ATOB_AsciiToData();
- BTOA_DataToAscii();
- CERT_CertChainFromCert();
- CERT_CheckCertValidTimes();
- CERT_DestroyCertificate();
- CERT_DestroyCertificateList();
- CERT_DupCertList();
- CERT_DupCertificate();
- CERT_ExtractPublicKey();
- CERT_FindCertByName();
- CERT_FreeNicknames();
- CERT_GetCertNicknames();
- CERT_GetDefaultCertDB();
- CERT_GetSSLCACerts();
- CERT_NameToAscii();
- CERT_NewTempCertificate();
- CERT_VerifyCertName();
- CERT_VerifyCertNow();
- DER_Lengths();
- DSAU_DecodeDerSig();
- DSAU_EncodeDerSig();
- NSSRWLock_Destroy();
- NSSRWLock_HaveWriteLock();
- NSSRWLock_LockRead();
- NSSRWLock_LockWrite();
- NSSRWLock_New();
- NSSRWLock_UnlockRead();
- NSSRWLock_UnlockWrite();
- NSS_PutEnv();
- PK11_CipherOp();
- PK11_CloneContext();
- PK11_CreateContextByRawKey();
- PK11_CreateContextBySymKey();
- PK11_CreateDigestContext();
- PK11_Derive();
- PK11_DeriveWithFlags();
- PK11_DestroyContext();
- PK11_DigestBegin();
- PK11_DigestFinal();
- PK11_DigestKey();
- PK11_DigestOp();
- PK11_FindBestKEAMatch();
- PK11_FindCertFromNickname();
- PK11_FindFixedKey();
- PK11_FindKeyByAnyCert();
- PK11_FreeSlot();
- PK11_FreeSymKey();
- PK11_GenerateFortezzaIV();
- PK11_GenerateRandom();
- PK11_GetBestKeyLength();
- PK11_GetBestSlot();
- PK11_GetBestSlotMultiple();
- PK11_GetBestWrapMechanism();
- PK11_GetCurrentWrapIndex();
- PK11_GetInternalSlot();
- PK11_GetKeyData();
- PK11_GetMechanism();
- PK11_GetModuleID();
- PK11_GetPrivateModulusLen();
- PK11_GetSlotFromKey();
- PK11_GetSlotFromPrivateKey();
- PK11_GetSlotID();
- PK11_GetSlotSeries();
- PK11_GetTokenInfo();
- PK11_GetWindow();
- PK11_GetWrapKey();
- PK11_IVFromParam();
- PK11_IsPresent();
- PK11_KeyGen();
- PK11_MakeKEAPubKey();
- PK11_ParamFromIV();
- PK11_PubDecryptRaw();
- PK11_PubDerive();
- PK11_PubEncryptRaw();
- PK11_PubUnwrapSymKey();
- PK11_PubWrapSymKey();
- PK11_ReferenceSymKey();
- PK11_RestoreContext();
- PK11_SaveContext();
- PK11_SetFortezzaHack();
- PK11_SetWrapKey();
- PK11_Sign();
- PK11_SignatureLen();
- PK11_SymKeyFromHandle();
- PK11_TokenExists();
- PK11_UnwrapSymKey();
- PK11_UnwrapSymKeyWithFlags();
- PK11_Verify();
- PK11_VerifyKeyOK();
- PK11_WrapSymKey();
- PORT_Alloc();
- PORT_ArenaAlloc();
- PORT_ArenaZAlloc();
- PORT_Free();
- PORT_FreeArena();
- PORT_GetError();
- PORT_NewArena();
- PORT_Realloc();
- PORT_SetError();
- PORT_ZAlloc();
- PORT_ZFree();
- RSA_FormatBlock();
- SECITEM_CompareItem();
- SECITEM_CopyItem();
- SECITEM_FreeItem();
- SECITEM_ZfreeItem();
- SECKEY_CopyPrivateKey();
- SECKEY_CreateRSAPrivateKey();
- SECKEY_DestroyPrivateKey();
- SECKEY_DestroyPublicKey();
- SECKEY_PublicKeyStrength();
- SECKEY_UpdateCertPQG();
- SECMOD_LookupSlot();
- SECOID_GetAlgorithmTag();
- SGN_Begin();
- SGN_DestroyContext();
- SGN_End();
- SGN_NewContext();
- SGN_Update();
- VFY_Begin();
- VFY_CreateContext();
- VFY_DestroyContext();
- VFY_End();
- VFY_Update();
-}
-
-#endif
-
-#ifdef INC_SMIME
-extern int CERT_IssuerAndSNTemplate;
-extern int CERT_SetOfSignedCrlTemplate;
-extern int SEC_PointerToAnyTemplate;
-extern int SEC_PointerToOctetStringTemplate;
-extern int SEC_SetOfAnyTemplate;
-
-extern void CERT_CertListFromCert();
-extern void CERT_DestroyCertArray();
-extern void CERT_FindSMimeProfile();
-extern void CERT_GetCertIssuerAndSN();
-extern void CERT_ImportCerts();
-extern void CERT_OpenCertDBFilename();
-extern void CERT_SaveSMimeProfile();
-extern void CERT_VerifyCert();
-extern void DER_TimeToUTCTime();
-extern void PK11_CreatePBEAlgorithmID();
-extern void PK11_FindCertAndKeyByRecipientList();
-extern void PK11_FindCertAndKeyByRecipientListNew();
-extern void PK11_FortezzaHasKEA();
-extern void PK11_FortezzaMapSig();
-extern void PK11_GenerateNewParam();
-extern void PK11_GetKeyStrength();
-extern void PK11_IsHW();
-extern void PK11_PBEKeyGen();
-extern void PK11_ParamToAlgid();
-extern void PK11_SetPasswordFunc();
-extern void SEC_ASN1DecodeInteger();
-extern void SEC_ASN1DecoderClearFilterProc();
-extern void SEC_ASN1DecoderClearNotifyProc();
-extern void SEC_ASN1DecoderFinish();
-extern void SEC_ASN1DecoderSetFilterProc();
-extern void SEC_ASN1DecoderSetNotifyProc();
-extern void SEC_ASN1DecoderStart();
-extern void SEC_ASN1DecoderUpdate();
-extern void SEC_ASN1EncoderClearNotifyProc();
-extern void SEC_ASN1EncoderClearStreaming();
-extern void SEC_ASN1EncoderClearTakeFromBuf();
-extern void SEC_ASN1EncoderFinish();
-extern void SEC_ASN1EncoderSetNotifyProc();
-extern void SEC_ASN1EncoderSetStreaming();
-extern void SEC_ASN1EncoderSetTakeFromBuf();
-extern void SEC_ASN1EncoderStart();
-extern void SEC_ASN1EncoderUpdate();
-extern void SEC_PKCS5IsAlgorithmPBEAlg();
-extern void SEC_SignData();
-extern void SGN_Digest();
-extern void VFY_VerifyDigest();
-
-nss_referenceNSSFunctionsForSMIME() {
- int tmp1=CERT_IssuerAndSNTemplate;
- int tmp2=CERT_SetOfSignedCrlTemplate;
- int tmp3=SEC_PointerToAnyTemplate;
- int tmp4=SEC_PointerToOctetStringTemplate;
- int tmp5=SEC_SetOfAnyTemplate;
-
- CERT_CertListFromCert();
- CERT_FindSMimeProfile();
- CERT_GetCertIssuerAndSN();
- CERT_ImportCerts();
- CERT_SaveSMimeProfile();
- CERT_VerifyCert();
- DER_TimeToUTCTime();
- PK11_CreatePBEAlgorithmID();
- PK11_FindCertAndKeyByRecipientListNew();
- PK11_FortezzaHasKEA();
- PK11_FortezzaMapSig();
- PK11_GenerateNewParam();
- PK11_GetKeyStrength();
- PK11_IsHW();
- PK11_ParamToAlgid();
- PK11_SetPasswordFunc();
- SEC_ASN1DecodeInteger();
- SEC_ASN1DecoderClearFilterProc();
- SEC_ASN1DecoderFinish();
- SEC_ASN1DecoderSetFilterProc();
- SEC_ASN1DecoderSetNotifyProc();
- SEC_ASN1DecoderStart();
- SEC_ASN1DecoderUpdate();
- SEC_ASN1EncoderClearNotifyProc();
- SEC_ASN1EncoderClearStreaming();
- SEC_ASN1EncoderClearTakeFromBuf();
- SEC_ASN1EncoderFinish();
- SEC_ASN1EncoderSetNotifyProc();
- SEC_ASN1EncoderSetStreaming();
- SEC_ASN1EncoderSetTakeFromBuf();
- SEC_ASN1EncoderStart();
- SEC_ASN1EncoderUpdate();
- SEC_PKCS5IsAlgorithmPBEAlg();
- SEC_SignData();
- SGN_Digest();
- VFY_VerifyDigest();
- CERT_OpenCertDBFilename();
- CERT_DestroyCertArray();
- PK11_PBEKeyGen();
- PK11_FindCertAndKeyByRecipientList();
- SEC_ASN1DecoderClearNotifyProc();
-}
-#endif
-
-extern int CERT_CertificateRequestTemplate;
-
-extern void CERT_DecodeCertificatePoliciesExtension();
-extern void CERT_DecodeUserNotice();
-extern void CERT_DestroyCertificatePoliciesExtension();
-extern void CERT_GenTime2FormattedAscii();
-extern void CERT_Hexify();
-extern void DER_GeneralizedTimeToTime();
-extern void HASH_GetHashObject();
-extern void MD2_Flatten();
-extern void MD2_Resurrect();
-extern void MD5_Flatten();
-extern void MD5_Resurrect();
-extern void NSSBase64Decoder_Create();
-extern void NSSBase64Decoder_Destroy();
-extern void NSSBase64Decoder_Update();
-extern void NSSBase64Encoder_Create();
-extern void NSSBase64Encoder_Destroy();
-extern void NSSBase64Encoder_Update();
-extern void PK11_ChangePW();
-extern void PK11_CheckUserPassword();
-extern void PK11_DoPassword();
-extern void PK11_FindKeyByKeyID();
-extern void PK11_InitPin();
-extern void PK11_NeedUserInit();
-extern void PQG_ParamGen();
-extern void PQG_VerifyParams();
-extern void SECITEM_ReallocItem();
-extern void SECKEY_DeriveKeyDBPassword();
-extern void SECKEY_GetKeyDBVersion();
-
-nss_CMDExports() {
- int tmp1 = CERT_CertificateRequestTemplate;
-
- CERT_DecodeCertificatePoliciesExtension();
- CERT_DecodeUserNotice();
- CERT_DestroyCertificatePoliciesExtension();
- CERT_GenTime2FormattedAscii();
- CERT_Hexify();
- DER_GeneralizedTimeToTime();
- HASH_GetHashObject();
- MD2_Flatten();
- MD2_Resurrect();
- MD5_Flatten();
- MD5_Resurrect();
- NSSBase64Decoder_Create();
- NSSBase64Decoder_Destroy();
- NSSBase64Decoder_Update();
- NSSBase64Encoder_Create();
- NSSBase64Encoder_Destroy();
- NSSBase64Encoder_Update();
- PK11_ChangePW();
- PK11_CheckUserPassword();
- PK11_DoPassword();
- PK11_FindKeyByKeyID();
- PK11_InitPin();
- PK11_NeedUserInit();
- PQG_ParamGen();
- PQG_VerifyParams();
- SECITEM_ReallocItem();
- SECKEY_DeriveKeyDBPassword();
- SECKEY_GetKeyDBVersion();
-}
-
diff --git a/security/nss/lib/dev/nss3hack.c b/security/nss/lib/pk11wrap/dev3hack.c
index f77085028..5c40608f3 100644
--- a/security/nss/lib/dev/nss3hack.c
+++ b/security/nss/lib/pk11wrap/dev3hack.c
@@ -35,6 +35,10 @@
static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#endif /* DEBUG */
+#ifndef NSS_3_4_CODE
+#define NSS_3_4_CODE
+#endif /* NSS_3_4_CODE */
+
#ifndef PKIT_H
#include "pkit.h"
#endif /* PKIT_H */
@@ -43,9 +47,7 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#include "devt.h"
#endif /* DEVT_H */
-#ifndef DEVM_H
-#include "devm.h"
-#endif /* DEVM_H */
+#include "dev3hack.h"
#ifndef BASE_H
#include "base.h"
@@ -160,6 +162,13 @@ nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
return rvToken;
}
+
+NSSTrustDomain *
+nssToken_GetTrustDomain(NSSToken *token)
+{
+ return token->trustDomain;
+}
+
typedef enum {
nssPK11Event_DefaultSessionRO = 0,
nssPK11Event_DefaultSessionRW = 1
diff --git a/security/nss/lib/dev/devnss3hack.h b/security/nss/lib/pk11wrap/dev3hack.h
index a9d28e2e2..2ae362a15 100644
--- a/security/nss/lib/dev/devnss3hack.h
+++ b/security/nss/lib/pk11wrap/dev3hack.h
@@ -45,6 +45,14 @@ PR_BEGIN_EXTERN_C
NSS_EXTERN NSSToken *
nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot);
+NSSTrustDomain *
+nssToken_GetTrustDomain(NSSToken *token);
+
+void PK11Slot_SetNSSToken(PK11SlotInfo *sl, NSSToken *nsst);
+
+NSSToken * PK11Slot_GetNSSToken(PK11SlotInfo *sl);
+
+
PR_END_EXTERN_C
#endif /* DEVNSS3HACK_H */
diff --git a/security/nss/lib/pk11wrap/manifest.mn b/security/nss/lib/pk11wrap/manifest.mn
index c043af789..1c525506d 100644
--- a/security/nss/lib/pk11wrap/manifest.mn
+++ b/security/nss/lib/pk11wrap/manifest.mn
@@ -41,13 +41,14 @@ EXPORTS = \
$(NULL)
PRIVATE_EXPORTS = \
- secmodi.h \
- secmodti.h \
+ pk11init.h \
+ dev3hack.h \
$(NULL)
MODULE = security
CSRCS = \
+ dev3hack.c \
pk11cert.c \
pk11err.c \
pk11load.c \
@@ -60,6 +61,7 @@ CSRCS = \
pk11sdr.c \
pk11pqg.c \
pk11pk12.c \
+ pk11pbe.c \
$(NULL)
REQUIRES = security dbm
diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c
index ab4289bdb..47bf56b12 100644
--- a/security/nss/lib/pk11wrap/pk11cert.c
+++ b/security/nss/lib/pk11wrap/pk11cert.c
@@ -52,14 +52,13 @@
#include "secerr.h"
#include "sslerr.h"
-#define NSSCKT_H /* we included pkcs11t.h, so block ckt.h from including nssckt.h */
-#include "ckt.h"
-
#ifndef NSS_3_4_CODE
#define NSS_3_4_CODE
#endif /* NSS_3_4_CODE */
-#include "pkinss3hack.h"
-#include "dev.h"
+#include "pki3hack.h"
+#include "dev3hack.h"
+
+/*#include "dev.h" */
#include "nsspki.h"
#include "pkitm.h"
@@ -120,10 +119,6 @@ pk11_buildNickname(PK11SlotInfo *slot,CK_ATTRIBUTE *cert_label,
char buildNew[sizeof(DEFAULT_STRING)+MAX_CERT_ID*2];
char *next,*nickname;
- if (slot->isInternal) {
- return NULL;
- }
-
if ((cert_label) && (cert_label->pValue)) {
suffixLen = cert_label->ulValueLen;
suffix = (char*)cert_label->pValue;
@@ -150,6 +145,7 @@ pk11_buildNickname(PK11SlotInfo *slot,CK_ATTRIBUTE *cert_label,
return NULL;
}
+ /* if is internal key slot, add code to skip the prefix!! */
next = nickname = (char *)PORT_Alloc(prefixLen+1+suffixLen+1);
if (nickname == NULL) return NULL;
@@ -180,7 +176,7 @@ pk11_FindObjectByTemplate(PK11SlotInfo *slot,CK_ATTRIBUTE *theTemplate,int tsize
if (crv != CKR_OK) {
PK11_ExitSlotMonitor(slot);
PORT_SetError( PK11_MapError(crv) );
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
crv=PK11_GETTAB(slot)->C_FindObjects(slot->session,&object,1,&objectCount);
@@ -190,11 +186,11 @@ pk11_FindObjectByTemplate(PK11SlotInfo *slot,CK_ATTRIBUTE *theTemplate,int tsize
/* shouldn't use SSL_ERROR... here */
PORT_SetError( crv != CKR_OK ? PK11_MapError(crv) :
SSL_ERROR_NO_CERTIFICATE);
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
/* blow up if the PKCS #11 module returns us and invalid object handle */
- PORT_Assert(object != CK_INVALID_KEY);
+ PORT_Assert(object != CK_INVALID_HANDLE);
return object;
}
@@ -282,13 +278,13 @@ PK11_MatchItem(PK11SlotInfo *slot, CK_OBJECT_HANDLE searchID,
/* now we need to create space for the public key */
arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) return CK_INVALID_KEY;
+ if (arena == NULL) return CK_INVALID_HANDLE;
crv = PK11_GetAttributes(arena,slot,searchID,theTemplate,tsize);
if (crv != CKR_OK) {
PORT_FreeArena(arena,PR_FALSE);
PORT_SetError( PK11_MapError(crv) );
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
/*
@@ -316,7 +312,7 @@ PK11_IsUserCert(PK11SlotInfo *slot, CERTCertificate *cert,
if (!PK11_IsLoggedIn(slot,NULL) && PK11_NeedLogin(slot)) {
theClass = CKO_PUBLIC_KEY;
}
- if (PK11_MatchItem(slot, certID , theClass) != CK_INVALID_KEY) {
+ if (PK11_MatchItem(slot, certID , theClass) != CK_INVALID_HANDLE) {
return PR_TRUE;
}
@@ -353,7 +349,7 @@ PK11_IsUserCert(PK11SlotInfo *slot, CERTCertificate *cert,
return PR_FALSE;
}
pk11_SignedToUnsigned(&theTemplate);
- if (pk11_FindObjectByTemplate(slot,&theTemplate,1) != CK_INVALID_KEY) {
+ if (pk11_FindObjectByTemplate(slot,&theTemplate,1) != CK_INVALID_HANDLE) {
SECKEY_DestroyPublicKey(pubKey);
return PR_TRUE;
}
@@ -436,8 +432,12 @@ CERTCertificate
/* figure out the nickname.... */
nickname = pk11_buildNickname(slot,label,privateLabel,id);
- cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &derCert, nickname,
- PR_FALSE, PR_TRUE);
+ cert = CERT_DecodeDERCertificate(&derCert, PR_TRUE, nickname);
+ if (cert) {
+ cert->dbhandle = (CERTCertDBHandle *)
+ nssToken_GetTrustDomain(slot->nssToken);
+ }
+
if (nickptr) {
*nickptr = nickname;
} else {
@@ -481,11 +481,7 @@ pk11_HandleTrustObject(PK11SlotInfo *slot, CERTCertificate *cert, CERTCertTrust
CK_OBJECT_HANDLE tobjID;
unsigned char sha1_hash[SHA1_LENGTH];
- CK_TRUST serverAuth, codeSigning, emailProtection;
-/*
- CK_TRUST digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment,
- keyAgreement, keyCertSign, crlSign, serverAuth, clientAuth, codeSigning,
- emailProtection, ipsecEndSystem, ipsecTunnel, ipsecUser, timeStamping; */
+ CK_TRUST serverAuth, codeSigning, emailProtection, clientAuth;
PK11_HashBuf(SEC_OID_SHA1, sha1_hash, cert->derCert.data, cert->derCert.len);
@@ -495,7 +491,7 @@ pk11_HandleTrustObject(PK11SlotInfo *slot, CERTCertificate *cert, CERTCertTrust
tobjID = pk11_FindObjectByTemplate(slot, tobjTemplate,
sizeof(tobjTemplate)/sizeof(tobjTemplate[0]));
- if( CK_INVALID_KEY == tobjID ) {
+ if( CK_INVALID_HANDLE == tobjID ) {
return PR_FALSE;
}
@@ -511,46 +507,37 @@ pk11_HandleTrustObject(PK11SlotInfo *slot, CERTCertificate *cert, CERTCertTrust
/* We could verify CKA_EXPIRES here */
- /* "Usage" trust information */
- /* digitalSignature = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_DIGITAL_SIGNATURE); */
- /* nonRepudiation = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_NON_REPUDIATION); */
- /* keyEncipherment = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_KEY_ENCIPHERMENT); */
- /* dataEncipherment = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_DATA_ENCIPHERMENT); */
- /* keyAgreement = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_KEY_AGREEMENT); */
- /* keyCertSign = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_KEY_CERT_SIGN); */
- /* crlSign = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_CRL_SIGN); */
/* "Purpose" trust information */
- serverAuth = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_SERVER_AUTH);
- /* clientAuth = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_CLIENT_AUTH); */
- codeSigning = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_CODE_SIGNING);
- emailProtection = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_EMAIL_PROTECTION);
- /* ipsecEndSystem = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_IPSEC_END_SYSTEM); */
- /* ipsecTunnel = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_IPSEC_TUNNEL); */
- /* ipsecUser = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_IPSEC_USER); */
- /* timeStamping = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_TIME_STAMPING); */
-
- /* Here's where the fun logic happens. We have to map back from the key usage,
- * extended key usage, purpose, and possibly other trust values into the old
- * trust-flags bits.
- */
+ serverAuth = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_SERVER_AUTH);
+ clientAuth = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_CLIENT_AUTH);
+ codeSigning = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_CODE_SIGNING);
+ emailProtection = pk11_GetTrustField(slot, arena, tobjID,
+ CKA_TRUST_EMAIL_PROTECTION);
+ /* Here's where the fun logic happens. We have to map back from the
+ * key usage, extended key usage, purpose, and possibly other trust values
+ * into the old trust-flags bits. */
/* First implementation: keep it simple for testing. We can study what other
* mappings would be appropriate and add them later.. fgmr 20000724 */
- if( serverAuth == CKT_NETSCAPE_TRUSTED ) {
+ if ( serverAuth == CKT_NETSCAPE_TRUSTED ) {
trust->sslFlags |= CERTDB_VALID_PEER | CERTDB_TRUSTED;
}
- if( serverAuth == CKT_NETSCAPE_TRUSTED_DELEGATOR ) {
- trust->sslFlags |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA | CERTDB_NS_TRUSTED_CA;
+ if ( serverAuth == CKT_NETSCAPE_TRUSTED_DELEGATOR ) {
+ trust->sslFlags |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA |
+ CERTDB_NS_TRUSTED_CA;
+ }
+ if ( clientAuth == CKT_NETSCAPE_TRUSTED_DELEGATOR ) {
+ trust->sslFlags |= CERTDB_TRUSTED_CLIENT_CA ;
}
- if( emailProtection == CKT_NETSCAPE_TRUSTED ) {
+ if ( emailProtection == CKT_NETSCAPE_TRUSTED ) {
trust->emailFlags |= CERTDB_VALID_PEER | CERTDB_TRUSTED;
}
- if( emailProtection == CKT_NETSCAPE_TRUSTED_DELEGATOR ) {
+ if ( emailProtection == CKT_NETSCAPE_TRUSTED_DELEGATOR ) {
trust->emailFlags |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA | CERTDB_NS_TRUSTED_CA;
}
@@ -605,24 +592,17 @@ PK11_MakeCertFromHandle(PK11SlotInfo *slot,CK_OBJECT_HANDLE certID,
cert->ownSlot = PR_TRUE;
}
- if (cert->trust == NULL) {
- unsigned int type;
-
- trust =
- (CERTCertTrust*)PORT_ArenaAlloc(cert->arena, sizeof(CERTCertTrust));
- if (trust == NULL) goto loser;
+ trust = (CERTCertTrust*)PORT_ArenaAlloc(cert->arena, sizeof(CERTCertTrust));
+ if (trust == NULL) goto loser;
+ PORT_Memset(trust,0, sizeof(CERTCertTrust));
+ cert->trust = trust;
- PORT_Memset(trust,0, sizeof(CERTCertTrust));
- cert->trust = trust;
- /* build some cert trust flags */
+
- /* First, see if there's a trust object for this cert. */
- /* For the first implementation, we'll just check this slot
- * and worry about overriding trust info later. */
- if( pk11_HandleTrustObject(slot, cert, trust) ) {
- ;
- } else
+ if(! pk11_HandleTrustObject(slot, cert, trust) ) {
+ unsigned int type;
+ /* build some cert trust flags */
if (CERT_IsCACert(cert, &type)) {
unsigned int trustflags = CERTDB_VALID_CA;
@@ -652,8 +632,6 @@ PK11_MakeCertFromHandle(PK11SlotInfo *slot,CK_OBJECT_HANDLE certID,
trust->objectSigningFlags |= trustflags;
}
}
- } else {
- trust = cert->trust;
}
if (PK11_IsUserCert(slot,cert,certID)) {
@@ -662,29 +640,6 @@ PK11_MakeCertFromHandle(PK11SlotInfo *slot,CK_OBJECT_HANDLE certID,
/* trust->objectSigningFlags |= CERTDB_USER; */
}
-
- /* if fortezza, write the root cert to the DB */
- if ((isFortezzaRootCA) && (!cert->isperm)) {
- char *name = NULL;
- if (swapNickname) {
- nickname = cert->nickname;
- cert->nickname = cert->dbnickname;
- }
- if (cert->nickname) {
- name = PORT_Strdup(cert->nickname);
- }
- if (name == NULL) name = CERT_MakeCANickname(cert);
- CERT_AddTempCertToPerm(cert,name,cert->trust);
- if (name) PORT_Free(name);
- if (swapNickname) {
- if (cert->nickname != NULL) {
- cert->dbnickname = cert->nickname;
- }
- cert->nickname = PORT_ArenaStrdup(cert->arena,nickname);
- }
-
- }
-
return cert;
loser:
@@ -706,7 +661,7 @@ PK11_GetCertFromPrivateKey(SECKEYPrivateKey *privKey)
SECStatus rv;
CERTCertificate *cert;
- if (certID == CK_INVALID_KEY) {
+ if (certID == CK_INVALID_HANDLE) {
/* couldn't find it on the card, look in our data base */
SECItem derSubject;
@@ -765,7 +720,7 @@ PK11_DeleteTokenCertAndKey(CERTCertificate *cert,void *wincx)
PK11_DestroyTokenObject(cert->slot,cert->pkcs11ID);
PK11_DeleteTokenPrivateKey(privKey);
}
- if ((pubKey != CK_INVALID_KEY) && (slot != NULL)) {
+ if ((pubKey != CK_INVALID_HANDLE) && (slot != NULL)) {
PK11_DestroyTokenObject(slot,pubKey);
PK11_FreeSlot(slot);
}
@@ -817,13 +772,14 @@ PK11_NumberObjectsFor(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate,
typedef struct pk11DoCertCallbackStr {
SECStatus(* callback)(PK11SlotInfo *slot, CERTCertificate*, void *);
SECStatus(* noslotcallback)(CERTCertificate*, void *);
+ SECStatus(* itemcallback)(CERTCertificate*, SECItem *, void *);
void *callbackArg;
} pk11DoCertCallback;
/*
* callback to map object handles to certificate structures.
*/
-SECStatus
+static SECStatus
pk11_DoCerts(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID, void *arg)
{
CERTCertificate *cert;
@@ -842,6 +798,9 @@ pk11_DoCerts(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID, void *arg)
if (certcb->noslotcallback) {
(*certcb->noslotcallback)(cert, certcb->callbackArg);
}
+ if (certcb->itemcallback) {
+ (*certcb->itemcallback)(cert, NULL, certcb->callbackArg);
+ }
}
CERT_DestroyCertificate(cert);
@@ -849,6 +808,63 @@ pk11_DoCerts(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID, void *arg)
return SECSuccess;
}
+static SECStatus
+pk11_CollectCrls(PK11SlotInfo *slot, CK_OBJECT_HANDLE crlID, void *arg)
+{
+ SECItem derCrl;
+ CERTCrlHeadNode *head = (CERTCrlHeadNode *) arg;
+ CERTCrlNode *new_node = NULL;
+ CK_ATTRIBUTE fetchCrl[3] = {
+ { CKA_VALUE, NULL, 0},
+ { CKA_NETSCAPE_KRL, NULL, 0},
+ { CKA_NETSCAPE_URL, NULL, 0},
+ };
+ const int fetchCrlSize = sizeof(fetchCrl)/sizeof(fetchCrl[2]);
+ SECStatus rv;
+
+ rv = PK11_GetAttributes(head->arena,slot,crlID,fetchCrl,fetchCrlSize);
+ if (rv == SECFailure) {
+ goto loser;
+ }
+ rv = SECFailure;
+
+ new_node = (CERTCrlNode *)PORT_ArenaAlloc(head->arena, sizeof(CERTCrlNode));
+ if (new_node == NULL) {
+ goto loser;
+ }
+
+ new_node->type = *((CK_BBOOL *)fetchCrl[1].pValue) ?
+ SEC_KRL_TYPE : SEC_CRL_TYPE;
+ derCrl.data = (unsigned char *)fetchCrl[0].pValue;
+ derCrl.len = fetchCrl[0].ulValueLen;
+ new_node->crl=CERT_DecodeDERCrl(head->arena,&derCrl,new_node->type);
+
+ if (fetchCrl[2].pValue) {
+ int nnlen = fetchCrl[2].ulValueLen;
+ new_node->crl->url = (char *)PORT_ArenaAlloc(head->arena, nnlen+1);
+ if ( !new_node->crl->url ) {
+ goto loser;
+ }
+ PORT_Memcpy(new_node->crl->url, fetchCrl[2].pValue, nnlen);
+ new_node->crl->url[nnlen] = 0;
+ } else {
+ new_node->crl->url = NULL;
+ }
+
+
+ new_node->next = NULL;
+ if (head->last) {
+ head->last->next = new_node;
+ head->last = new_node;
+ } else {
+ head->first = head->last = new_node;
+ }
+ rv = SECSuccess;
+
+loser:
+ return(rv);
+}
+
/*
* key call back structure.
@@ -927,191 +943,24 @@ typedef struct pk11CertCallbackStr {
void *callbackArg;
} pk11CertCallback;
-static SECStatus
-pk11_SaveCert(PK11SlotInfo *slot, CERTCertificate *cert, void *arg)
-{
- pk11CertCallback *certcb = (pk11CertCallback *)arg;
- SECStatus rv = SECSuccess;
-
- if (slot->cert_count == slot->array_size) return CKR_OK;
-
- slot->cert_array[slot->cert_count] = CERT_DupCertificate(cert);
- if (slot->cert_array[slot->cert_count] == NULL) {
- return SECFailure;
- }
- /* now the slot has a hold of the cert, free the slot's element in the
- * cert.. */
- if (cert->ownSlot && (slot == cert->slot)) {
- PK11_FreeSlot(cert->slot);
- cert->ownSlot = PR_FALSE;
- }
- slot->cert_count++;
-
- if (certcb->callback) {
- rv = (*certcb->callback)(cert, NULL, certcb->callbackArg);
- }
- return rv;
-}
-
-
-/* free the slots */
-void
-PK11_FreeSlotCerts(PK11SlotInfo *slot)
-{
- int i;
-
- if (slot->cert_array) {
- for (i=0; i < slot->cert_count; i++) {
- /* if we point the cert on our array, the cert doesn't have a
- * reference to use (otherwise you would never be able to free
- * a slot :) */
- if ((slot->cert_array[i]->slot == slot) &&
- (!slot->cert_array[i]->ownSlot)) {
- slot->cert_array[i]->slot = NULL;
- }
- CERT_DestroyCertificate(slot->cert_array[i]);
- }
- PORT_Free(slot->cert_array);
- slot->cert_array = NULL;
- slot->cert_count = 0;
- }
- return;
-}
-
-/*
- * Update PQG parameters for all the certs on a slot.
- */
-static SECStatus
-pk11_UpdateSlotPQG(PK11SlotInfo *slot)
-{
- int i, tag;
- CERTCertificate * cert;
- SECOidData *oid;
- SECStatus rv1 = SECSuccess;
- SECStatus rv2 = SECSuccess;
-
- if (slot->cert_array) {
- for (i=0; i < slot->cert_count; i++) {
-
- cert = slot->cert_array[i];
-
- oid = SECOID_FindOID(&cert->subjectPublicKeyInfo.algorithm.algorithm);
-
- if (oid != NULL) {
- tag = oid->offset;
-
- /* Check if cert has a DSA or Fortezza public key */
- if ( (tag == SEC_OID_MISSI_KEA_DSS_OLD) ||
- (tag == SEC_OID_MISSI_DSS_OLD) ||
- (tag == SEC_OID_MISSI_KEA_DSS) ||
- (tag == SEC_OID_MISSI_DSS) ||
- (tag == SEC_OID_ANSIX9_DSA_SIGNATURE) ||
- (tag == SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) ||
- (tag == SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST) ) {
-
- /* update PQG parameters */
-
- rv1 = SECKEY_UpdateCertPQG(cert);
- if (rv1 == SECFailure) {
- rv2 = rv1;
- }
- }
- } /* end of if oid != NULL */
- } /* end of for loop */
- }
- return rv2;
-}
-
-
/*
* Extract all the certs on a card from a slot.
*/
static SECStatus
-pk11_ExtractCertsFromSlot(PK11SlotInfo *slot, void *arg)
-{
- pk11TraverseSlot *slotcb = (pk11TraverseSlot*) arg;
- int object_count;
- SECStatus rv;
-
- rv = SECSuccess;
-
- PK11_FreeSlotCerts(slot);
-
- object_count = PK11_NumberObjectsFor(slot,slotcb->findTemplate,
- slotcb->templateCount);
-
- /*Actually this isn't a failure... there just were no certs to be found*/
- if (object_count == 0) {
- return SECSuccess;
- }
-
- slot->cert_array = (CERTCertificate **)
- PORT_Alloc(sizeof(CERTCertificate *)*object_count);
- if (slot->cert_array == NULL) {
- return SECFailure;
- }
- slot->cert_count = 0;
- slot->array_size = object_count;
- PK11_TraverseSlot(slot,arg);
-
- /* Update the PQG parameters for the extracted certs. */
- rv = pk11_UpdateSlotPQG(slot);
-
- return rv;
-}
-
-/*
- * read all the certs from a slot
- */
-SECStatus
-PK11_ReadSlotCerts(PK11SlotInfo *slot)
-{
-
- /* build slot list */
- pk11CertCallback caller;
- pk11DoCertCallback saver;
- pk11TraverseSlot creater;
- CK_ATTRIBUTE theTemplate;
- CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
-
- PK11_SETATTRS(&theTemplate, CKA_CLASS, &certClass, sizeof(certClass));
-
- caller.callback = NULL;
- caller.callbackArg = NULL;
- saver.callback = pk11_SaveCert;
- saver.noslotcallback = NULL;
- saver.callbackArg = (void *) & caller;
- creater.callback = pk11_DoCerts;
- creater.callbackArg = (void *) & saver;
- creater.findTemplate = &theTemplate;
- creater.templateCount = 1;
-
- return pk11_ExtractCertsFromSlot(slot, &creater);
-}
-
-/*
- * Extract all the certs on a card from a slot.
- */
-static SECStatus
-pk11_TraverseAllSlots(PRBool loadCerts,
- SECStatus (*callback)(PK11SlotInfo *,void *),void *arg,void *wincx) {
-
+pk11_TraverseAllSlots( SECStatus (*callback)(PK11SlotInfo *,void *),
+ void *arg,void *wincx) {
PK11SlotList *list;
PK11SlotListElement *le;
SECStatus rv;
/* get them all! */
- list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,loadCerts,wincx);
+ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_FALSE,wincx);
if (list == NULL) return SECFailure;
/* look at each slot and authenticate as necessary */
for (le = list->head ; le; le = le->next) {
- /* don't nab internal slots */
- if ((!loadCerts) && le->slot->isInternal == PR_TRUE) {
- continue;
- }
- if (loadCerts || !PK11_IsFriendly(le->slot)) {
- rv = PK11_Authenticate(le->slot, loadCerts, wincx);
+ if (!PK11_IsFriendly(le->slot)) {
+ rv = PK11_Authenticate(le->slot, PR_FALSE, wincx);
if (rv != SECSuccess) continue;
}
(*callback)(le->slot,arg);
@@ -1128,26 +977,48 @@ pk11_TraverseAllSlots(PRBool loadCerts,
SECStatus
PK11_TraverseSlotCerts(SECStatus(* callback)(CERTCertificate*,SECItem *,void *),
void *arg, void *wincx) {
- pk11CertCallback caller;
- pk11DoCertCallback saver;
+ pk11DoCertCallback caller;
pk11TraverseSlot creater;
CK_ATTRIBUTE theTemplate;
CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
PK11_SETATTRS(&theTemplate, CKA_CLASS, &certClass, sizeof(certClass));
- caller.callback = callback;
+ caller.callback = NULL;
+ caller.noslotcallback = NULL;
+ caller.itemcallback = callback;
caller.callbackArg = arg;
- saver.callback = pk11_SaveCert;
- saver.noslotcallback = NULL;
- saver.callbackArg = (void *) & caller;
creater.callback = pk11_DoCerts;
- creater.callbackArg = (void *) & saver;
+ creater.callbackArg = (void *) & caller;
creater.findTemplate = &theTemplate;
creater.templateCount = 1;
- return pk11_TraverseAllSlots(PR_FALSE, pk11_ExtractCertsFromSlot,
- &creater, wincx);
+ return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, wincx);
+}
+
+/*
+ * Extract all the certs on a card from a slot.
+ */
+SECStatus
+PK11_LookupCrls(CERTCrlHeadNode *nodes, int type, void *wincx) {
+ pk11TraverseSlot creater;
+ CK_ATTRIBUTE theTemplate[2];
+ CK_ATTRIBUTE *attrs;
+ CK_OBJECT_CLASS certClass = CKO_NETSCAPE_CRL;
+
+ attrs = theTemplate;
+ PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass)); attrs++;
+ if (type != -1) {
+ CK_BBOOL isKrl = (CK_BBOOL) (type == SEC_KRL_TYPE);
+ PK11_SETATTRS(attrs, CKA_NETSCAPE_KRL, &isKrl, sizeof(isKrl)); attrs++;
+ }
+
+ creater.callback = pk11_CollectCrls;
+ creater.callbackArg = (void *) nodes;
+ creater.findTemplate = theTemplate;
+ creater.templateCount = (attrs - theTemplate);
+
+ return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, wincx);
}
/***********************************************************************
@@ -1194,7 +1065,8 @@ PK11_TraversePrivateKeysInSlot( PK11SlotInfo *slot,
CK_OBJECT_HANDLE *
PK11_FindObjectsFromNickname(char *nickname,PK11SlotInfo **slotptr,
- CK_OBJECT_CLASS objclass, int *returnCount, void *wincx) {
+ CK_OBJECT_CLASS objclass, int *returnCount, void *wincx)
+{
char *tokenName;
char *delimit;
PK11SlotInfo *slot;
@@ -1229,7 +1101,7 @@ PK11_FindObjectsFromNickname(char *nickname,PK11SlotInfo **slotptr,
*slotptr = slot = PK11_GetInternalKeySlot();
}
if (slot == NULL) {
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
if (!PK11_IsFriendly(slot)) {
@@ -1237,7 +1109,7 @@ PK11_FindObjectsFromNickname(char *nickname,PK11SlotInfo **slotptr,
if (rv != SECSuccess) {
PK11_FreeSlot(slot);
*slotptr = NULL;
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
}
@@ -1273,7 +1145,7 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) {
CKO_CERTIFICATE, &count, wincx);
CERTCertificate *cert;
- if (certID == CK_INVALID_KEY) return NULL;
+ if (certID == CK_INVALID_HANDLE) return NULL;
cert = PK11_MakeCertFromHandle(slot,certID[0],NULL);
PK11_FreeSlot(slot);
PORT_Free(certID);
@@ -1579,11 +1451,13 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
}
rwsession = PK11_GetRWSession(slot);
- crv = PK11_GETTAB(slot)->C_SetAttributeValue(rwsession,key,keyAttrs,
+ if (key != CK_INVALID_HANDLE) {
+ crv = PK11_GETTAB(slot)->C_SetAttributeValue(rwsession,key,keyAttrs,
keyCount);
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- goto done;
+ if (crv != CKR_OK) {
+ PORT_SetError( PK11_MapError(crv) );
+ goto done;
+ }
}
crv = PK11_GETTAB(slot)->
@@ -1594,8 +1468,11 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
PORT_SetError( PK11_MapError(crv) );
}
- if (cert->nssCertificate) {
- cert->nssCertificate->token = slot->nssToken;
+ if (cert->slot == NULL) {
+ cert->slot = PK11_ReferenceSlot(slot);
+ if (cert->nssCertificate) {
+ cert->nssCertificate->token = slot->nssToken;
+ }
}
done:
@@ -1619,7 +1496,7 @@ pk11_getcerthandle(PK11SlotInfo *slot, CERTCertificate *cert,
if (cert->slot == slot) {
certh = cert->pkcs11ID;
- if (certh == CK_INVALID_KEY) {
+ if (certh == CK_INVALID_HANDLE) {
certh = pk11_FindObjectByTemplate(slot,theTemplate,tsize);
cert->pkcs11ID = certh;
}
@@ -1660,11 +1537,11 @@ PK11_FindPrivateKeyFromCert(PK11SlotInfo *slot, CERTCertificate *cert,
}
certh = pk11_getcerthandle(slot,cert,theTemplate,tsize);
- if (certh == CK_INVALID_KEY) {
+ if (certh == CK_INVALID_HANDLE) {
return NULL;
}
keyh = PK11_MatchItem(slot,certh,CKO_PRIVATE_KEY);
- if (keyh == CK_INVALID_KEY) { return NULL; }
+ if (keyh == CK_INVALID_HANDLE) { return NULL; }
return PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyh, wincx);
}
@@ -1718,7 +1595,7 @@ PK11_KeyForCertExists(CERTCertificate *cert, CK_OBJECT_HANDLE *keyPtr,
if (rv != SECSuccess) continue;
key = pk11_FindPrivateKeyFromCertID(le->slot,keyID);
- if (key != CK_INVALID_KEY) {
+ if (key != CK_INVALID_HANDLE) {
slot = PK11_ReferenceSlot(le->slot);
if (keyPtr) *keyPtr = key;
break;
@@ -1740,8 +1617,7 @@ PK11_KeyForDERCertExists(SECItem *derCert, CK_OBJECT_HANDLE *keyPtr,
CERTCertificate *cert;
PK11SlotInfo *slot = NULL;
- cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), derCert, NULL,
- PR_FALSE, PR_TRUE);
+ cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
if (cert == NULL) return NULL;
slot = PK11_KeyForCertExists(cert, keyPtr, wincx);
@@ -1773,8 +1649,7 @@ PK11_ImportDERCertForKey(SECItem *derCert, char *nickname,void *wincx) {
CERTCertificate *cert;
PK11SlotInfo *slot = NULL;
- cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), derCert, NULL,
- PR_FALSE, PR_TRUE);
+ cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
if (cert == NULL) return NULL;
slot = PK11_ImportCertForKey(cert, nickname, wincx);
@@ -1787,7 +1662,7 @@ pk11_FindCertObjectByTemplate(PK11SlotInfo **slotPtr,
CK_ATTRIBUTE *searchTemplate, int count, void *wincx) {
PK11SlotList *list;
PK11SlotListElement *le;
- CK_OBJECT_HANDLE certHandle = CK_INVALID_KEY;
+ CK_OBJECT_HANDLE certHandle = CK_INVALID_HANDLE;
PK11SlotInfo *slot = NULL;
SECStatus rv;
@@ -1797,7 +1672,7 @@ pk11_FindCertObjectByTemplate(PK11SlotInfo **slotPtr,
list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx);
if (list == NULL) {
if (list) PK11_FreeSlotList(list);
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
@@ -1809,7 +1684,7 @@ pk11_FindCertObjectByTemplate(PK11SlotInfo **slotPtr,
}
certHandle = pk11_FindObjectByTemplate(le->slot,searchTemplate,count);
- if (certHandle != CK_INVALID_KEY) {
+ if (certHandle != CK_INVALID_HANDLE) {
slot = PK11_ReferenceSlot(le->slot);
break;
}
@@ -1818,7 +1693,7 @@ pk11_FindCertObjectByTemplate(PK11SlotInfo **slotPtr,
PK11_FreeSlotList(list);
if (slot == NULL) {
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
*slotPtr = slot;
return certHandle;
@@ -1867,7 +1742,7 @@ pk11_FindCertObjectByRecipientNew(PK11SlotInfo *slot, NSSCMSRecipient **recipien
ri->id.issuerAndSN->serialNumber.data,ri->id.issuerAndSN->serialNumber.len);
certHandle = pk11_FindObjectByTemplate(slot,searchTemplate,count);
- if (certHandle != CK_INVALID_KEY) {
+ if (certHandle != CK_INVALID_HANDLE) {
CERTCertificate *cert = pk11_fastCert(slot,certHandle,NULL,NULL);
if (PK11_IsUserCert(slot,cert,certHandle)) {
/* we've found a cert handle, now let's see if there is a key
@@ -1882,7 +1757,7 @@ pk11_FindCertObjectByRecipientNew(PK11SlotInfo *slot, NSSCMSRecipient **recipien
}
}
*rlIndex = -1;
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
/*
@@ -1896,14 +1771,14 @@ pk11_AllFindCertObjectByRecipientNew(NSSCMSRecipient **recipientlist, void *winc
{
PK11SlotList *list;
PK11SlotListElement *le;
- CK_OBJECT_HANDLE certHandle = CK_INVALID_KEY;
+ CK_OBJECT_HANDLE certHandle = CK_INVALID_HANDLE;
SECStatus rv;
/* get them all! */
list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx);
if (list == NULL) {
if (list) PK11_FreeSlotList(list);
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
/* Look for the slot that holds the Key */
@@ -1914,13 +1789,13 @@ pk11_AllFindCertObjectByRecipientNew(NSSCMSRecipient **recipientlist, void *winc
}
certHandle = pk11_FindCertObjectByRecipientNew(le->slot, recipientlist, rlIndex);
- if (certHandle != CK_INVALID_KEY)
+ if (certHandle != CK_INVALID_HANDLE)
break;
}
PK11_FreeSlotList(list);
- return (le == NULL) ? CK_INVALID_KEY : certHandle;
+ return (le == NULL) ? CK_INVALID_HANDLE : certHandle;
}
/*
@@ -1960,7 +1835,7 @@ pk11_FindCertObjectByRecipient(PK11SlotInfo *slot,
ri->issuerAndSN->serialNumber.data,ri->issuerAndSN->serialNumber.len);
certHandle = pk11_FindObjectByTemplate(slot,searchTemplate,count);
- if (certHandle != CK_INVALID_KEY) {
+ if (certHandle != CK_INVALID_HANDLE) {
CERTCertificate *cert = pk11_fastCert(slot,certHandle,NULL,NULL);
if (PK11_IsUserCert(slot,cert,certHandle)) {
/* we've found a cert handle, now let's see if there is a key
@@ -1974,7 +1849,7 @@ pk11_FindCertObjectByRecipient(PK11SlotInfo *slot,
}
}
*rip = NULL;
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
/*
@@ -1986,7 +1861,7 @@ pk11_AllFindCertObjectByRecipient(PK11SlotInfo **slotPtr,
void *wincx) {
PK11SlotList *list;
PK11SlotListElement *le;
- CK_OBJECT_HANDLE certHandle = CK_INVALID_KEY;
+ CK_OBJECT_HANDLE certHandle = CK_INVALID_HANDLE;
PK11SlotInfo *slot = NULL;
SECStatus rv;
@@ -1996,7 +1871,7 @@ pk11_AllFindCertObjectByRecipient(PK11SlotInfo **slotPtr,
list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx);
if (list == NULL) {
if (list) PK11_FreeSlotList(list);
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
*rip = NULL;
@@ -2010,7 +1885,7 @@ pk11_AllFindCertObjectByRecipient(PK11SlotInfo **slotPtr,
certHandle = pk11_FindCertObjectByRecipient(le->slot,
recipientArray,rip);
- if (certHandle != CK_INVALID_KEY) {
+ if (certHandle != CK_INVALID_HANDLE) {
slot = PK11_ReferenceSlot(le->slot);
break;
}
@@ -2019,7 +1894,7 @@ pk11_AllFindCertObjectByRecipient(PK11SlotInfo **slotPtr,
PK11_FreeSlotList(list);
if (slot == NULL) {
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
*slotPtr = slot;
return certHandle;
@@ -2037,14 +1912,14 @@ PK11_FindCertAndKeyByRecipientList(PK11SlotInfo **slotPtr,
SEC_PKCS7RecipientInfo **array, SEC_PKCS7RecipientInfo **rip,
SECKEYPrivateKey**privKey, void *wincx)
{
- CK_OBJECT_HANDLE certHandle = CK_INVALID_KEY;
- CK_OBJECT_HANDLE keyHandle = CK_INVALID_KEY;
+ CK_OBJECT_HANDLE certHandle = CK_INVALID_HANDLE;
+ CK_OBJECT_HANDLE keyHandle = CK_INVALID_HANDLE;
CERTCertificate *cert = NULL;
SECStatus rv;
*privKey = NULL;
certHandle = pk11_AllFindCertObjectByRecipient(slotPtr,array,rip,wincx);
- if (certHandle == CK_INVALID_KEY) {
+ if (certHandle == CK_INVALID_HANDLE) {
return NULL;
}
@@ -2056,7 +1931,7 @@ PK11_FindCertAndKeyByRecipientList(PK11SlotInfo **slotPtr,
}
keyHandle = PK11_MatchItem(*slotPtr,certHandle,CKO_PRIVATE_KEY);
- if (keyHandle == CK_INVALID_KEY) {
+ if (keyHandle == CK_INVALID_HANDLE) {
PK11_FreeSlot(*slotPtr);
*slotPtr = NULL;
return NULL;
@@ -2087,13 +1962,13 @@ PK11_FindCertAndKeyByRecipientList(PK11SlotInfo **slotPtr,
int
PK11_FindCertAndKeyByRecipientListNew(NSSCMSRecipient **recipientlist, void *wincx)
{
- CK_OBJECT_HANDLE certHandle = CK_INVALID_KEY;
- CK_OBJECT_HANDLE keyHandle = CK_INVALID_KEY;
+ CK_OBJECT_HANDLE certHandle = CK_INVALID_HANDLE;
+ CK_OBJECT_HANDLE keyHandle = CK_INVALID_HANDLE;
NSSCMSRecipient *rl;
int rlIndex;
certHandle = pk11_AllFindCertObjectByRecipientNew(recipientlist, wincx, &rlIndex);
- if (certHandle == CK_INVALID_KEY) {
+ if (certHandle == CK_INVALID_HANDLE) {
return -1;
}
@@ -2110,7 +1985,7 @@ PK11_FindCertAndKeyByRecipientListNew(NSSCMSRecipient **recipientlist, void *win
/* try to get a private key handle for the cert we found */
keyHandle = PK11_MatchItem(rl->slot, certHandle, CKO_PRIVATE_KEY);
- if (keyHandle == CK_INVALID_KEY) {
+ if (keyHandle == CK_INVALID_HANDLE) {
PK11_FreeSlot(rl->slot);
rl->slot = NULL;
return -1;
@@ -2142,13 +2017,16 @@ PK11_FindCertByIssuerAndSN(PK11SlotInfo **slotPtr, CERTIssuerAndSN *issuerSN,
#ifndef NSS_SOFTOKEN_MODULE
CK_OBJECT_HANDLE certHandle;
CERTCertificate *cert = NULL;
+ CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
CK_ATTRIBUTE searchTemplate[] = {
+ { CKA_CLASS, NULL, 0 },
{ CKA_ISSUER, NULL, 0 },
{ CKA_SERIAL_NUMBER, NULL, 0}
};
int count = sizeof(searchTemplate)/sizeof(CK_ATTRIBUTE);
CK_ATTRIBUTE *attrs = searchTemplate;
+ PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass)); attrs++;
PK11_SETATTRS(attrs, CKA_ISSUER, issuerSN->derIssuer.data,
issuerSN->derIssuer.len); attrs++;
PK11_SETATTRS(attrs, CKA_SERIAL_NUMBER, issuerSN->serialNumber.data,
@@ -2156,7 +2034,7 @@ PK11_FindCertByIssuerAndSN(PK11SlotInfo **slotPtr, CERTIssuerAndSN *issuerSN,
certHandle = pk11_FindCertObjectByTemplate
(slotPtr,searchTemplate,count,wincx);
- if (certHandle == CK_INVALID_KEY) {
+ if (certHandle == CK_INVALID_HANDLE) {
return NULL;
}
cert = PK11_MakeCertFromHandle(*slotPtr,certHandle,NULL);
@@ -2197,14 +2075,14 @@ PK11_FindObjectForCert(CERTCertificate *cert, void *wincx, PK11SlotInfo **pSlot)
if (cert->slot) {
certHandle = pk11_getcerthandle(cert->slot,cert,&searchTemplate,1);
- if (certHandle != CK_INVALID_KEY) {
+ if (certHandle != CK_INVALID_HANDLE) {
*pSlot = PK11_ReferenceSlot(cert->slot);
return certHandle;
}
}
certHandle = pk11_FindCertObjectByTemplate(pSlot,&searchTemplate,1,wincx);
- if (certHandle != CK_INVALID_KEY) {
+ if (certHandle != CK_INVALID_HANDLE) {
if (cert->slot == NULL) {
cert->slot = PK11_ReferenceSlot(*pSlot);
cert->pkcs11ID = certHandle;
@@ -2225,7 +2103,7 @@ PK11_FindKeyByAnyCert(CERTCertificate *cert, void *wincx)
SECStatus rv;
certHandle = PK11_FindObjectForCert(cert, wincx, &slot);
- if (certHandle == CK_INVALID_KEY) {
+ if (certHandle == CK_INVALID_HANDLE) {
return NULL;
}
rv = PK11_Authenticate(slot, PR_TRUE, wincx);
@@ -2234,7 +2112,7 @@ PK11_FindKeyByAnyCert(CERTCertificate *cert, void *wincx)
return NULL;
}
keyHandle = PK11_MatchItem(slot,certHandle,CKO_PRIVATE_KEY);
- if (keyHandle == CK_INVALID_KEY) {
+ if (keyHandle == CK_INVALID_HANDLE) {
PK11_FreeSlot(slot);
return NULL;
}
@@ -2250,13 +2128,13 @@ pk11_FindPubKeyByAnyCert(CERTCertificate *cert, PK11SlotInfo **slot, void *wincx
CK_OBJECT_HANDLE keyHandle;
certHandle = PK11_FindObjectForCert(cert, wincx, slot);
- if (certHandle == CK_INVALID_KEY) {
- return CK_INVALID_KEY;
+ if (certHandle == CK_INVALID_HANDLE) {
+ return CK_INVALID_HANDLE;
}
keyHandle = PK11_MatchItem(*slot,certHandle,CKO_PUBLIC_KEY);
- if (keyHandle == CK_INVALID_KEY) {
+ if (keyHandle == CK_INVALID_HANDLE) {
PK11_FreeSlot(*slot);
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
return keyHandle;
}
@@ -2268,7 +2146,7 @@ PK11_FindKeyByKeyID(PK11SlotInfo *slot, SECItem *keyID, void *wincx)
SECKEYPrivateKey *privKey;
keyHandle = pk11_FindPrivateKeyFromCertID(slot, keyID);
- if (keyHandle == CK_INVALID_KEY) {
+ if (keyHandle == CK_INVALID_HANDLE) {
return NULL;
}
privKey = PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyHandle, wincx);
@@ -2292,8 +2170,18 @@ PK11_NumberCertsForCertSubject(CERTCertificate *cert)
PK11_SETATTRS(attr,CKA_CLASS, &certClass, sizeof(certClass)); attr++;
PK11_SETATTRS(attr,CKA_SUBJECT,cert->derSubject.data,cert->derSubject.len);
- if ((cert->slot == NULL) || (cert->slot->isInternal)) {
- return 0;
+ if (cert->slot == NULL) {
+ PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
+ PR_FALSE,PR_TRUE,NULL);
+ PK11SlotListElement *le;
+ int count = 0;
+
+ /* loop through all the fortezza tokens */
+ for (le = list->head; le; le = le->next) {
+ count += PK11_NumberObjectsFor(le->slot,theTemplate,templateSize);
+ }
+ PK11_FreeSlotList(list);
+ return count;
}
return PK11_NumberObjectsFor(cert->slot,theTemplate,templateSize);
@@ -2309,6 +2197,19 @@ PK11_TraverseCertsForSubject(CERTCertificate *cert,
if(!cert) {
return SECFailure;
}
+ if (cert->slot == NULL) {
+ PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
+ PR_FALSE,PR_TRUE,NULL);
+ PK11SlotListElement *le;
+
+ /* loop through all the fortezza tokens */
+ for (le = list->head; le; le = le->next) {
+ PK11_TraverseCertsForSubjectInSlot(cert,le->slot,callback,arg);
+ }
+ PK11_FreeSlotList(list);
+ return SECSuccess;
+
+ }
return PK11_TraverseCertsForSubjectInSlot(cert, cert->slot, callback, arg);
}
@@ -2331,11 +2232,12 @@ PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
PK11_SETATTRS(attr,CKA_CLASS, &certClass, sizeof(certClass)); attr++;
PK11_SETATTRS(attr,CKA_SUBJECT,cert->derSubject.data,cert->derSubject.len);
- if ((slot == NULL) || (slot->isInternal)) {
+ if (slot == NULL) {
return SECSuccess;
}
caller.noslotcallback = callback;
caller.callback = NULL;
+ caller.itemcallback = NULL;
caller.callbackArg = arg;
callarg.callback = pk11_DoCerts;
callarg.callbackArg = (void *) & caller;
@@ -2395,12 +2297,13 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
PK11_SETATTRS(attr,CKA_CLASS, &certClass, sizeof(certClass)); attr++;
PK11_SETATTRS(attr,CKA_LABEL,nickname->data,nickname->len);
- if ((slot == NULL) || (slot->isInternal)) {
+ if (slot == NULL) {
return SECSuccess;
}
caller.noslotcallback = callback;
caller.callback = NULL;
+ caller.itemcallback = NULL;
caller.callbackArg = arg;
callarg.callback = pk11_DoCerts;
callarg.callbackArg = (void *) & caller;
@@ -2460,6 +2363,7 @@ PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
caller.noslotcallback = callback;
caller.callback = NULL;
+ caller.itemcallback = NULL;
caller.callbackArg = arg;
callarg.callback = pk11_DoCerts;
callarg.callbackArg = (void *) & caller;
@@ -2513,7 +2417,7 @@ PK11_FindCertFromDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
}
certh = pk11_getcerthandle(slot,cert,theTemplate,tsize);
- if (certh == CK_INVALID_KEY) {
+ if (certh == CK_INVALID_HANDLE) {
return NULL;
}
return PK11_MakeCertFromHandle(slot, certh, NULL);
@@ -2569,7 +2473,7 @@ PK11_FindCertFromDERSubjectAndNickname(PK11SlotInfo *slot,
}
certh = pk11_getcerthandle(slot,cert,theTemplate,tsize);
- if (certh == CK_INVALID_KEY) {
+ if (certh == CK_INVALID_HANDLE) {
return NULL;
}
@@ -2589,15 +2493,15 @@ pk11_findKeyObjectByDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
SECStatus rv;
if((slot == NULL) || (cert == NULL)) {
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
keyID = pk11_mkcertKeyID(cert);
if(keyID == NULL) {
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
- key = CK_INVALID_KEY;
+ key = CK_INVALID_HANDLE;
rv = PK11_Authenticate(slot, PR_TRUE, wincx);
if (rv != SECSuccess) goto loser;
@@ -2620,7 +2524,7 @@ PK11_FindKeyByDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
}
keyHandle = pk11_findKeyObjectByDERCert(slot, cert, wincx);
- if (keyHandle == CK_INVALID_KEY) {
+ if (keyHandle == CK_INVALID_HANDLE) {
return NULL;
}
@@ -2639,7 +2543,7 @@ PK11_ImportCertForKeyToSlot(PK11SlotInfo *slot, CERTCertificate *cert,
}
keyHandle = pk11_findKeyObjectByDERCert(slot, cert, wincx);
- if (keyHandle == CK_INVALID_KEY) {
+ if (keyHandle == CK_INVALID_HANDLE) {
return SECFailure;
}
@@ -2794,7 +2698,7 @@ PK11_FindCertInSlot(PK11SlotInfo *slot, CERTCertificate *cert, void *wincx)
*/
rv = PK11_Authenticate(slot, PR_TRUE, wincx);
if (rv != SECSuccess) {
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
return pk11_getcerthandle(slot,cert,theTemplate,tsize);
@@ -2813,7 +2717,7 @@ PK11_GetKeyIDFromCert(CERTCertificate *cert, void *wincx)
CK_RV crv;
handle = PK11_FindObjectForCert(cert,wincx,&slot);
- if (handle == CK_INVALID_KEY) {
+ if (handle == CK_INVALID_HANDLE) {
goto loser;
}
@@ -2963,9 +2867,6 @@ PK11_ListCerts(PK11CertListType type, void *pwarg)
listCerts.type = type;
listCerts.certList = certList;
- SEC_TraversePermCerts(CERT_GetDefaultCertDB(),pk11ListCertCallback,
- &listCerts);
-
PK11_TraverseSlotCerts(pk11ListCertCallback,&listCerts,pwarg);
if (CERT_LIST_HEAD(certList) == NULL) {
@@ -3044,13 +2945,13 @@ PK11_GetLowLevelKeyIDForCert(PK11SlotInfo *slot,
certHandle = pk11_getcerthandle(slot,cert,theTemplate,tsize);
} else {
certHandle = PK11_FindObjectForCert(cert, wincx, &slotRef);
- if (certHandle == CK_INVALID_KEY) {
+ if (certHandle == CK_INVALID_HANDLE) {
return pk11_mkcertKeyID(cert);
}
slot = slotRef;
}
- if (certHandle == CK_INVALID_KEY) {
+ if (certHandle == CK_INVALID_HANDLE) {
return NULL;
}
@@ -3121,3 +3022,306 @@ PK11_ListPrivateKeysInSlot(PK11SlotInfo *slot)
return keys;
}
+/*
+ * return the certificate associated with a derCert
+ */
+SECItem *
+PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle,
+ SECItem *name, int type)
+{
+ CK_OBJECT_CLASS crlClass = CKO_NETSCAPE_CRL;
+ CK_ATTRIBUTE theTemplate[] = {
+ { CKA_SUBJECT, NULL, 0 },
+ { CKA_CLASS, NULL, 0 },
+ { CKA_NETSCAPE_KRL, NULL, 0 },
+ };
+ CK_ATTRIBUTE crlData = { CKA_VALUE, NULL, 0 };
+ /* if you change the array, change the variable below as well */
+ int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]);
+ CK_BBOOL ck_true = CK_TRUE;
+ CK_BBOOL ck_false = CK_FALSE;
+ CK_OBJECT_HANDLE crlh = CK_INVALID_HANDLE;
+ CK_ATTRIBUTE *attrs = theTemplate;
+ CK_RV crv;
+ SECStatus rv;
+ SECItem *derCrl = NULL;
+
+ PK11_SETATTRS(attrs, CKA_SUBJECT, name->data, name->len); attrs++;
+ PK11_SETATTRS(attrs, CKA_CLASS, &crlClass, sizeof(crlClass)); attrs++;
+ PK11_SETATTRS(attrs, CKA_NETSCAPE_KRL, (type == SEC_CRL_TYPE) ?
+ &ck_false : &ck_true, sizeof (CK_BBOOL)); attrs++;
+
+ if (*slot) {
+ crlh = pk11_FindObjectByTemplate(*slot,theTemplate,tsize);
+ } else {
+ PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
+ PR_FALSE,PR_TRUE,NULL);
+ PK11SlotListElement *le;
+
+ /* loop through all the fortezza tokens */
+ for (le = list->head; le; le = le->next) {
+ crlh = pk11_FindObjectByTemplate(le->slot,theTemplate,tsize);
+ if (crlh != CK_INVALID_HANDLE) {
+ *slot = PK11_ReferenceSlot(le->slot);
+ break;
+ }
+ }
+ PK11_FreeSlotList(list);
+ }
+
+ if (crlh == CK_INVALID_HANDLE) {
+ PORT_SetError(SEC_ERROR_NO_KRL);
+ return NULL;
+ }
+ crv = PK11_GetAttributes(NULL,*slot,crlh,&crlData,1);
+ if (crv != CKR_OK) {
+ PORT_SetError(PK11_MapError (crv));
+ goto loser;
+ }
+
+ derCrl = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
+ if (derCrl == NULL) {
+ goto loser;
+ }
+
+ derCrl->data = crlData.pValue;
+ derCrl->len = crlData.ulValueLen;
+
+ if (crlHandle) {
+ *crlHandle = crlh;
+ }
+
+loser:
+ if (!derCrl) {
+ if (crlData.pValue) PORT_Free(crlData.pValue);
+ }
+ return derCrl;
+}
+
+CK_OBJECT_HANDLE
+PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, SECItem *name,
+ char *url, int type)
+{
+ CK_OBJECT_CLASS crlClass = CKO_NETSCAPE_CRL;
+ CK_ATTRIBUTE theTemplate[] = {
+ { CKA_SUBJECT, NULL, 0 },
+ { CKA_CLASS, NULL, 0 },
+ { CKA_NETSCAPE_KRL, NULL, 0 },
+ { CKA_NETSCAPE_URL, NULL, 0 },
+ { CKA_VALUE, NULL, 0 }
+ };
+ /* if you change the array, change the variable below as well */
+ int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]);
+ CK_BBOOL ck_true = CK_TRUE;
+ CK_BBOOL ck_false = CK_FALSE;
+ CK_OBJECT_HANDLE crlh = CK_INVALID_HANDLE;
+ CK_ATTRIBUTE *attrs = theTemplate;
+ CK_SESSION_HANDLE rwsession;
+ CK_RV crv;
+
+ PK11_SETATTRS(attrs, CKA_SUBJECT, name->data, name->len); attrs++;
+ PK11_SETATTRS(attrs, CKA_CLASS, &crlClass, sizeof(crlClass)); attrs++;
+ PK11_SETATTRS(attrs, CKA_NETSCAPE_KRL, (type == SEC_CRL_TYPE) ?
+ &ck_false : &ck_true, sizeof (CK_BBOOL)); attrs++;
+ PK11_SETATTRS(attrs, CKA_NETSCAPE_URL, url, PORT_Strlen(url)+1); attrs++;
+ PK11_SETATTRS(attrs, CKA_VALUE,crl->data,crl->len); attrs++;
+
+ rwsession = PK11_GetRWSession(slot);
+ if (rwsession == CK_INVALID_SESSION) {
+ PORT_SetError(SEC_ERROR_READ_ONLY);
+ return crlh;
+ }
+
+ crv = PK11_GETTAB(slot)->
+ C_CreateObject(rwsession,attrs,tsize,&crlh);
+ if (crv != CKR_OK) {
+ PORT_SetError( PK11_MapError(crv) );
+ }
+
+ PK11_RestoreROSession(slot,rwsession);
+ return crlh;
+}
+
+
+
+/*
+ * delete a crl.
+ */
+SECStatus
+SEC_DeletePermCRL(CERTSignedCrl *crl)
+{
+ PK11SlotInfo *slot = crl->slot;
+ CK_RV crv;
+
+ if (slot == NULL) {
+ /* shouldn't happen */
+ PORT_SetError( SEC_ERROR_CRL_INVALID);
+ return SECFailure;
+ }
+
+ crv = PK11_DestroyTokenObject(slot,crl->pkcs11ID);
+ if (crv != CKR_OK) {
+ PORT_SetError( PK11_MapError(crv) );
+ goto loser;
+ }
+ crl->slot = NULL;
+ PK11_FreeSlot(slot);
+loser:
+ return SECSuccess;
+}
+
+/*
+ * return the certificate associated with a derCert
+ */
+SECItem *
+PK11_FindSMimeProfile(PK11SlotInfo **slot, char *emailAddr,
+ SECItem *name, SECItem **profileTime)
+{
+ CK_OBJECT_CLASS smimeClass = CKO_NETSCAPE_SMIME;
+ CK_ATTRIBUTE theTemplate[] = {
+ { CKA_SUBJECT, NULL, 0 },
+ { CKA_CLASS, NULL, 0 },
+ { CKA_NETSCAPE_EMAIL, NULL, 0 },
+ };
+ CK_ATTRIBUTE smimeData[] = {
+ { CKA_SUBJECT, NULL, 0 },
+ { CKA_VALUE, NULL, 0 },
+ };
+ /* if you change the array, change the variable below as well */
+ int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]);
+ CK_BBOOL ck_true = CK_TRUE;
+ CK_BBOOL ck_false = CK_FALSE;
+ CK_OBJECT_HANDLE smimeh = CK_INVALID_HANDLE;
+ CK_ATTRIBUTE *attrs = theTemplate;
+ CK_RV crv;
+ SECStatus rv;
+ SECItem *emailProfile = NULL;
+
+ PK11_SETATTRS(attrs, CKA_SUBJECT, name->data, name->len); attrs++;
+ PK11_SETATTRS(attrs, CKA_CLASS, &smimeClass, sizeof(smimeClass)); attrs++;
+ PK11_SETATTRS(attrs, CKA_NETSCAPE_EMAIL, emailAddr, strlen(emailAddr));
+ attrs++;
+
+ if (*slot) {
+ smimeh = pk11_FindObjectByTemplate(*slot,theTemplate,tsize);
+ } else {
+ PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
+ PR_FALSE,PR_TRUE,NULL);
+ PK11SlotListElement *le;
+
+ /* loop through all the fortezza tokens */
+ for (le = list->head; le; le = le->next) {
+ smimeh = pk11_FindObjectByTemplate(le->slot,theTemplate,tsize);
+ if (smimeh != CK_INVALID_HANDLE) {
+ *slot = PK11_ReferenceSlot(le->slot);
+ break;
+ }
+ }
+ PK11_FreeSlotList(list);
+ }
+
+ if (smimeh == CK_INVALID_HANDLE) {
+ PORT_SetError(SEC_ERROR_NO_KRL);
+ return NULL;
+ }
+
+ if (profileTime) {
+ PK11_SETATTRS(smimeData, CKA_NETSCAPE_SMIME_TIMESTAMP, NULL, 0);
+ }
+
+ crv = PK11_GetAttributes(NULL,*slot,smimeh,smimeData,2);
+ if (crv != CKR_OK) {
+ PORT_SetError(PK11_MapError (crv));
+ goto loser;
+ }
+
+ if (!profileTime) {
+ SECItem profileSubject;
+
+ profileSubject.data = smimeData[0].pValue;
+ profileSubject.len = smimeData[0].ulValueLen;
+ if (!SECITEM_ItemsAreEqual(&profileSubject,name)) {
+ goto loser;
+ }
+ }
+
+ emailProfile = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
+ if (emailProfile == NULL) {
+ goto loser;
+ }
+
+ emailProfile->data = smimeData[1].pValue;
+ emailProfile->len = smimeData[1].ulValueLen;
+
+ if (profileTime) {
+ *profileTime = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
+ if (*profileTime) {
+ (*profileTime)->data = smimeData[0].pValue;
+ (*profileTime)->len = smimeData[0].ulValueLen;
+ }
+ }
+
+loser:
+ if (emailProfile == NULL) {
+ if (smimeData[1].pValue) {
+ PORT_Free(smimeData[1].pValue);
+ }
+ }
+ if (profileTime == NULL || *profileTime == NULL) {
+ if (smimeData[0].pValue) {
+ PORT_Free(smimeData[0].pValue);
+ }
+ }
+ return emailProfile;
+}
+
+
+SECStatus
+PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj,
+ SECItem *emailProfile, SECItem *profileTime)
+{
+ CK_OBJECT_CLASS smimeClass = CKO_NETSCAPE_CRL;
+ CK_ATTRIBUTE theTemplate[] = {
+ { CKA_SUBJECT, NULL, 0 },
+ { CKA_CLASS, NULL, 0 },
+ { CKA_NETSCAPE_EMAIL, NULL, 0 },
+ { CKA_NETSCAPE_SMIME_TIMESTAMP, NULL, 0 },
+ { CKA_VALUE, NULL, 0 }
+ };
+ /* if you change the array, change the variable below as well */
+ int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]);
+ CK_OBJECT_HANDLE smimeh = CK_INVALID_HANDLE;
+ CK_ATTRIBUTE *attrs = theTemplate;
+ CK_SESSION_HANDLE rwsession;
+ CK_RV crv;
+
+ PK11_SETATTRS(attrs, CKA_SUBJECT, derSubj->data, derSubj->len); attrs++;
+ PK11_SETATTRS(attrs, CKA_CLASS, &smimeClass, sizeof(smimeClass)); attrs++;
+ PK11_SETATTRS(attrs, CKA_NETSCAPE_SMIME_TIMESTAMP, profileTime->data,
+ profileTime->len); attrs++;
+ PK11_SETATTRS(attrs, CKA_NETSCAPE_EMAIL,
+ emailAddr, PORT_Strlen(emailAddr)+1); attrs++;
+ PK11_SETATTRS(attrs, CKA_VALUE,emailProfile->data,emailProfile->len); attrs++;
+
+ if (slot == NULL) {
+ 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);
+ return SECFailure;
+ }
+
+ crv = PK11_GETTAB(slot)->
+ C_CreateObject(rwsession,attrs,tsize,&smimeh);
+ if (crv != CKR_OK) {
+ PORT_SetError( PK11_MapError(crv) );
+ }
+
+ PK11_RestoreROSession(slot,rwsession);
+ return SECSuccess;
+}
+
+
diff --git a/security/nss/lib/pk11wrap/pk11func.h b/security/nss/lib/pk11wrap/pk11func.h
index 3679a0add..51252f0fc 100644
--- a/security/nss/lib/pk11wrap/pk11func.h
+++ b/security/nss/lib/pk11wrap/pk11func.h
@@ -477,6 +477,9 @@ PK11_CreatePBEAlgorithmID(SECOidTag algorithm, int iteration, SECItem *salt);
PK11SymKey *
PK11_PBEKeyGen(PK11SlotInfo *slot, SECAlgorithmID *algid, SECItem *pwitem,
PRBool faulty3DES, void *wincx);
+PK11SymKey *
+PK11_RawPBEKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *params,
+ SECItem *pwitem, PRBool faulty3DES, void *wincx);
SECItem *
PK11_GetPBEIV(SECAlgorithmID *algid, SECItem *pwitem);
@@ -489,6 +492,21 @@ PK11_GetLowLevelKeyIDForCert(PK11SlotInfo *slot,
SECItem *
PK11_GetLowLevelKeyIDForPrivateKey(SECKEYPrivateKey *key);
+SECItem *
+PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *handle,
+ SECItem *derName, int type);
+
+CK_OBJECT_HANDLE
+PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl,
+ SECItem *name, char *url, int type);
+
+SECItem *
+PK11_FindSMimeProfile(PK11SlotInfo **slotp, char *emailAddr, SECItem *derSubj,
+ SECItem **profileTime);
+SECStatus
+PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj,
+ SECItem *emailProfile, SECItem *profileTime);
+
SEC_END_PROTOS
#endif
diff --git a/security/nss/lib/ckfw/nsscku.h b/security/nss/lib/pk11wrap/pk11init.h
index 46f4d1f59..b5fa0b4ec 100644
--- a/security/nss/lib/ckfw/nsscku.h
+++ b/security/nss/lib/pk11wrap/pk11init.h
@@ -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,42 +30,34 @@
* may use your version of this file under either the MPL or the
* GPL.
*/
-
/*
- * This file is in part derived from a file "pkcs11t.h" made available
- * by RSA Security at ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-11/pkcs11t.h
- *
- * Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document
- * is granted provided that it is identified as "RSA Security Inc. Public-Key
- * Cryptography Standards (PKCS)" in all material mentioning or referencing
- * this document.
+ * Internal header file included in pk11wrap dir, or in softoken
*/
-
-#ifndef NSSCKU_H
-#define NSSCKU_H
-
-#ifdef DEBUG
-static const char NSSCKU_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
-#endif /* DEBUG */
-
-#endif /* NSSCKU_H */
-
-/*
- * These platform-dependent packing rules are required by all PKCS#11
- * modules, to be binary compatible. These rules have been placed in
- * separate header files (nssckp.h to enable the packing, nsscku.h to
- * disable) for consistancy. These files can be included many times,
- * so the bodies should *NOT* be in the multiple-inclusion-preventing
- * #ifndef/#endif area above.
- */
-
-/*
- * WIN32 is defined (when appropriate) in NSPR's prcpucfg.h.
- */
-
-#ifdef WIN32
-#pragma warning(disable:4103)
-#pragma pack(pop, cryptoki)
-#endif /* WIN32 */
-
-/* End of nsscku.h */
+#ifndef _PK11_INIT_H_
+#define _PK11_INIT_H_ 1
+
+/* hold slot default flags until we initialize a slot. This structure is only
+ * useful between the time we define a module (either by hand or from the
+ * database) and the time the module is loaded. Not reference counted */
+struct PK11PreSlotInfoStr {
+ CK_SLOT_ID slotID; /* slot these flags are for */
+ unsigned long defaultFlags; /* bit mask of default implementation this slot
+ * provides */
+ int askpw; /* slot specific password bits */
+ long timeout; /* slot specific timeout value */
+ char hasRootCerts; /* is this the root cert PKCS #11 module? */
+ char hasRootTrust; /* is this the root cert PKCS #11 module? */
+};
+
+#define SECMOD_SLOT_FLAGS "slotFlags=[RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES]"
+
+#define SECMOD_MAKE_NSS_FLAGS(fips,slot) \
+"Flags=internal,critical"fips" slotparams=("#slot"={"SECMOD_SLOT_FLAGS"})"
+
+#define SECMOD_INT_NAME "NSS Internal PKCS #11 Module"
+#define SECMOD_INT_FLAGS SECMOD_MAKE_NSS_FLAGS("",1)
+#define SECMOD_FIPS_NAME "NSS Internal FIPS PKCS #11 Module"
+#define SECMOD_FIPS_FLAGS SECMOD_MAKE_NSS_FLAGS(",fips",3)
+
+
+#endif /* _PK11_INIT_H_ 1 */
diff --git a/security/nss/lib/pk11wrap/pk11kea.c b/security/nss/lib/pk11wrap/pk11kea.c
index c50b9d8b6..b5b810d0b 100644
--- a/security/nss/lib/pk11wrap/pk11kea.c
+++ b/security/nss/lib/pk11wrap/pk11kea.c
@@ -85,8 +85,8 @@ pk11_KeyExchange(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
/* RSA */
if (PK11_DoesMechanism(symKey->slot, CKM_RSA_PKCS) &&
PK11_DoesMechanism(slot,CKM_RSA_PKCS)) {
- CK_OBJECT_HANDLE pubKeyHandle = CK_INVALID_KEY;
- CK_OBJECT_HANDLE privKeyHandle = CK_INVALID_KEY;
+ CK_OBJECT_HANDLE pubKeyHandle = CK_INVALID_HANDLE;
+ CK_OBJECT_HANDLE privKeyHandle = CK_INVALID_HANDLE;
SECKEYPublicKey *pubKey = NULL;
SECKEYPrivateKey *privKey = NULL;
SECItem wrapData;
@@ -95,12 +95,12 @@ pk11_KeyExchange(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
/* find RSA Public Key on target */
pubKeyHandle = pk11_FindRSAPubKey(slot);
- if (pubKeyHandle != CK_INVALID_KEY) {
+ if (pubKeyHandle != CK_INVALID_HANDLE) {
privKeyHandle = PK11_MatchItem(slot,pubKeyHandle,CKO_PRIVATE_KEY);
}
/* if no key exists, generate a key pair */
- if (privKeyHandle == CK_INVALID_KEY) {
+ if (privKeyHandle == CK_INVALID_HANDLE) {
unsigned int symKeyLength = PK11_GetKeyLength(symKey);
PK11RSAGenParams rsaParams;
@@ -125,7 +125,7 @@ pk11_KeyExchange(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
if (pubKey && pubKey->pkcs11Slot) {
PK11_FreeSlot(pubKey->pkcs11Slot);
pubKey->pkcs11Slot = NULL;
- pubKey->pkcs11ID = CK_INVALID_KEY;
+ pubKey->pkcs11ID = CK_INVALID_HANDLE;
}
}
}
diff --git a/security/nss/lib/pk11wrap/pk11pbe.c b/security/nss/lib/pk11wrap/pk11pbe.c
new file mode 100644
index 000000000..45ee01a84
--- /dev/null
+++ b/security/nss/lib/pk11wrap/pk11pbe.c
@@ -0,0 +1,689 @@
+/*
+ * 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.
+ */
+
+#include "plarena.h"
+
+#include "seccomon.h"
+#include "secitem.h"
+#include "secport.h"
+#include "hasht.h"
+#include "pkcs11t.h"
+/*#include "blapi.h" */
+#include "sechash.h"
+#include "secasn1.h"
+#include "secder.h"
+#include "secoid.h"
+#include "alghmac.h"
+#include "secerr.h"
+#include "secmod.h"
+#include "pk11func.h"
+
+/* stuff for the new secpkcs5.h */
+/* used for V2 PKCS 12 Draft Spec */
+typedef enum {
+ pbeBitGenIDNull = 0,
+ pbeBitGenCipherKey = 0x01,
+ pbeBitGenCipherIV = 0x02,
+ pbeBitGenIntegrityKey = 0x03
+} PBEBitGenID;
+
+typedef struct PBEBitGenContextStr PBEBitGenContext;
+
+/* end new secpkcs5.h */
+
+typedef struct SEC_PKCS5PBEParameterStr SEC_PKCS5PBEParameter;
+struct SEC_PKCS5PBEParameterStr {
+ PRArenaPool *poolp;
+ SECItem salt; /* octet string */
+ SECItem iteration; /* integer */
+};
+
+
+/* template for PKCS 5 PBE Parameter. This template has been expanded
+ * based upon the additions in PKCS 12. This should eventually be moved
+ * if RSA updates PKCS 5.
+ */
+const SEC_ASN1Template SEC_PKCS5PBEParameterTemplate[] =
+{
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(SEC_PKCS5PBEParameter) },
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(SEC_PKCS5PBEParameter, salt) },
+ { SEC_ASN1_INTEGER,
+ offsetof(SEC_PKCS5PBEParameter, iteration) },
+ { 0 }
+};
+
+const SEC_ASN1Template SEC_V2PKCS12PBEParameterTemplate[] =
+{
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter) },
+ { SEC_ASN1_OCTET_STRING, offsetof(SEC_PKCS5PBEParameter, salt) },
+ { SEC_ASN1_INTEGER, offsetof(SEC_PKCS5PBEParameter, iteration) },
+ { 0 }
+};
+
+/* maps crypto algorithm from PBE algorithm.
+ */
+SECOidTag
+SEC_PKCS5GetCryptoAlgorithm(SECAlgorithmID *algid)
+{
+
+ SECOidTag algorithm;
+
+ if(algid == NULL)
+ return SEC_OID_UNKNOWN;
+
+ algorithm = SECOID_GetAlgorithmTag(algid);
+ switch(algorithm)
+ {
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
+ case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
+ return SEC_OID_DES_EDE3_CBC;
+ case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
+ case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
+ case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
+ return SEC_OID_DES_CBC;
+ case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
+ case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
+ return SEC_OID_RC2_CBC;
+ case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
+ case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
+ return SEC_OID_RC4;
+ default:
+ break;
+ }
+
+ return SEC_OID_UNKNOWN;
+}
+
+/* check to see if an oid is a pbe algorithm
+ */
+PRBool
+SEC_PKCS5IsAlgorithmPBEAlg(SECAlgorithmID *algid)
+{
+ return (PRBool)(SEC_PKCS5GetCryptoAlgorithm(algid) != SEC_OID_UNKNOWN);
+}
+
+/* maps PBE algorithm from crypto algorithm, assumes SHA1 hashing.
+ */
+SECOidTag
+SEC_PKCS5GetPBEAlgorithm(SECOidTag algTag, int keyLen)
+{
+ switch(algTag)
+ {
+ case SEC_OID_DES_EDE3_CBC:
+ switch(keyLen) {
+ case 168:
+ case 192:
+ return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC;
+ case 128:
+ case 92:
+ return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC;
+ default:
+ break;
+ }
+ break;
+ case SEC_OID_DES_CBC:
+ return SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC;
+ case SEC_OID_RC2_CBC:
+ switch(keyLen) {
+ case 40:
+ return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC;
+ case 128:
+ return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC;
+ default:
+ break;
+ }
+ break;
+ case SEC_OID_RC4:
+ switch(keyLen) {
+ case 40:
+ return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4;
+ case 128:
+ return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return SEC_OID_UNKNOWN;
+}
+
+
+/* get the key length needed for the PBE algorithm
+ */
+
+int
+SEC_PKCS5GetKeyLength(SECAlgorithmID *algid)
+{
+
+ SECOidTag algorithm;
+
+ if(algid == NULL)
+ return SEC_OID_UNKNOWN;
+
+ algorithm = SECOID_GetAlgorithmTag(algid);
+
+ switch(algorithm)
+ {
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
+ case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
+ return 24;
+ case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
+ case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
+ case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
+ return 8;
+ case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
+ case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
+ return 5;
+ case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
+ case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
+ return 16;
+ default:
+ break;
+ }
+ return -1;
+}
+
+
+/* the V2 algorithms only encode the salt, there is no iteration
+ * count so we need a check for V2 algorithm parameters.
+ */
+static PRBool
+sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(SECOidTag algorithm)
+{
+ switch(algorithm)
+ {
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
+ return PR_TRUE;
+ default:
+ break;
+ }
+
+ return PR_FALSE;
+}
+/* destroy a pbe parameter. it assumes that the parameter was
+ * generated using the appropriate create function and therefor
+ * contains an arena pool.
+ */
+static void
+sec_pkcs5_destroy_pbe_param(SEC_PKCS5PBEParameter *pbe_param)
+{
+ if(pbe_param != NULL)
+ PORT_FreeArena(pbe_param->poolp, PR_TRUE);
+}
+
+/* creates a PBE parameter based on the PBE algorithm. the only required
+ * parameters are algorithm and interation. the return is a PBE parameter
+ * which conforms to PKCS 5 parameter unless an extended parameter is needed.
+ * this is primarily if keyLen and a variable key length algorithm are
+ * specified.
+ * salt - if null, a salt will be generated from random bytes.
+ * iteration - number of iterations to perform hashing.
+ * keyLen - only used in variable key length algorithms
+ * iv - if null, the IV will be generated based on PKCS 5 when needed.
+ * params - optional, currently unsupported additional parameters.
+ * once a parameter is allocated, it should be destroyed calling
+ * sec_pkcs5_destroy_pbe_parameter or SEC_PKCS5DestroyPBEParameter.
+ */
+static SEC_PKCS5PBEParameter *
+sec_pkcs5_create_pbe_parameter(SECOidTag algorithm,
+ SECItem *salt,
+ int iteration)
+{
+ PRArenaPool *poolp = NULL;
+ SEC_PKCS5PBEParameter *pbe_param = NULL;
+ SECStatus rv;
+ void *dummy = NULL;
+
+ if(iteration < 0) {
+ return NULL;
+ }
+ if(!salt || !salt->data) {
+ return NULL;
+ }
+
+ poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
+ if(poolp == NULL)
+ return NULL;
+
+ pbe_param = (SEC_PKCS5PBEParameter *)PORT_ArenaZAlloc(poolp,
+ sizeof(SEC_PKCS5PBEParameter));
+ if(!pbe_param) {
+ PORT_FreeArena(poolp, PR_TRUE);
+ return NULL;
+ }
+
+ pbe_param->poolp = poolp;
+
+ rv = SECITEM_CopyItem(poolp, &pbe_param->salt, salt);
+
+ if(rv != SECSuccess) {
+ PORT_FreeArena(poolp, PR_TRUE);
+ return NULL;
+ }
+
+ /* encode the integer */
+ dummy = SEC_ASN1EncodeInteger(poolp, &pbe_param->iteration,
+ iteration);
+ rv = (dummy) ? SECSuccess : SECFailure;
+
+ if(rv != SECSuccess) {
+ PORT_FreeArena(poolp, PR_FALSE);
+ return NULL;
+ }
+
+ return pbe_param;
+}
+
+/* creates a algorithm ID containing the PBE algorithm and appropriate
+ * parameters. the required parameter is the algorithm. if salt is
+ * not specified, it is generated randomly. if IV is specified, it overrides
+ * the PKCS 5 generation of the IV.
+ *
+ * the returned SECAlgorithmID should be destroyed using
+ * SECOID_DestroyAlgorithmID
+ */
+SECAlgorithmID *
+SEC_PKCS5CreateAlgorithmID(SECOidTag algorithm,
+ SECItem *salt,
+ int iteration)
+{
+ PRArenaPool *poolp = NULL;
+ SECAlgorithmID *algid, *ret_algid;
+ SECItem der_param;
+ SECStatus rv = SECFailure;
+ SEC_PKCS5PBEParameter *pbe_param;
+
+#ifdef nodef
+ if(sec_pkcs5_hash_algorithm(algorithm) == SEC_OID_UNKNOWN)
+ return NULL;
+#endif
+
+ if(iteration <= 0) {
+ return NULL;
+ }
+
+ der_param.data = NULL;
+ der_param.len = 0;
+
+ /* generate the parameter */
+ pbe_param = sec_pkcs5_create_pbe_parameter(algorithm, salt, iteration);
+ if(!pbe_param) {
+ return NULL;
+ }
+
+ poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
+ if(!poolp) {
+ sec_pkcs5_destroy_pbe_param(pbe_param);
+ return NULL;
+ }
+
+ /* generate the algorithm id */
+ algid = (SECAlgorithmID *)PORT_ArenaZAlloc(poolp, sizeof(SECAlgorithmID));
+ if(algid != NULL) {
+ void *dummy;
+ if(!sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) {
+ dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param,
+ SEC_PKCS5PBEParameterTemplate);
+ } else {
+ dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param,
+ SEC_V2PKCS12PBEParameterTemplate);
+ }
+
+ if(dummy) {
+ rv = SECOID_SetAlgorithmID(poolp, algid, algorithm, &der_param);
+ }
+ }
+
+ ret_algid = NULL;
+ if(algid != NULL) {
+ ret_algid = (SECAlgorithmID *)PORT_ZAlloc(sizeof(SECAlgorithmID));
+ if(ret_algid != NULL) {
+ rv = SECOID_CopyAlgorithmID(NULL, ret_algid, algid);
+ if(rv != SECSuccess) {
+ SECOID_DestroyAlgorithmID(ret_algid, PR_TRUE);
+ ret_algid = NULL;
+ }
+ }
+ }
+
+ if(poolp != NULL) {
+ PORT_FreeArena(poolp, PR_TRUE);
+ algid = NULL;
+ }
+
+ sec_pkcs5_destroy_pbe_param(pbe_param);
+
+ return ret_algid;
+}
+
+SECStatus
+pbe_PK11AlgidToParam(SECAlgorithmID *algid,SECItem *mech)
+{
+ CK_PBE_PARAMS *pbe_params = NULL;
+ SEC_PKCS5PBEParameter p5_param;
+ SECItem *salt = NULL;
+ SECOidTag algorithm = SECOID_GetAlgorithmTag(algid);
+ PRArenaPool *arena = NULL;
+ SECStatus rv = SECFailure;
+ int iv_len;
+
+
+ arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
+ if (arena == NULL) {
+ goto loser;
+ }
+ iv_len = PK11_GetIVLength(PK11_AlgtagToMechanism(algorithm));
+ if (iv_len < 0) {
+ goto loser;
+ }
+
+ if (sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) {
+ rv = SEC_ASN1DecodeItem(arena, &p5_param,
+ SEC_V2PKCS12PBEParameterTemplate, &algid->parameters);
+ } else {
+ rv = SEC_ASN1DecodeItem(arena,&p5_param,SEC_PKCS5PBEParameterTemplate,
+ &algid->parameters);
+ }
+
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ salt = &p5_param.salt;
+
+ pbe_params = (CK_PBE_PARAMS *)PORT_ZAlloc(sizeof(CK_PBE_PARAMS)+
+ salt->len+iv_len);
+ if (pbe_params == NULL) {
+ goto loser;
+ }
+
+ /* get salt */
+ pbe_params->pSalt = ((CK_CHAR_PTR) pbe_params)+sizeof(CK_PBE_PARAMS);
+ if (iv_len) {
+ pbe_params->pInitVector = ((CK_CHAR_PTR) pbe_params)+
+ sizeof(CK_PBE_PARAMS)+salt->len;
+ }
+ PORT_Memcpy(pbe_params->pSalt, salt->data, salt->len);
+ pbe_params->ulSaltLen = (CK_ULONG) salt->len;
+
+ /* get iteration count */
+ pbe_params->ulIteration = (CK_ULONG) DER_GetInteger(&p5_param.iteration);
+
+ /* copy into the mechanism sec item */
+ mech->data = (unsigned char *)pbe_params;
+ mech->len = sizeof(*pbe_params);
+ if (arena) {
+ PORT_FreeArena(arena,PR_TRUE);
+ }
+ return SECSuccess;
+
+loser:
+ if (pbe_params) {
+ PORT_Free(pbe_params);
+ }
+ if (arena) {
+ PORT_FreeArena(arena,PR_TRUE);
+ }
+ return SECFailure;
+}
+
+SECStatus
+PBE_PK11ParamToAlgid(SECOidTag algTag, SECItem *param, PRArenaPool *arena,
+ SECAlgorithmID *algId)
+{
+ CK_PBE_PARAMS *pbe_param;
+ SECItem pbeSalt;
+ SECAlgorithmID *pbeAlgID = NULL;
+ SECStatus rv;
+
+ if(!param || !algId) {
+ return SECFailure;
+ }
+
+ pbe_param = (CK_PBE_PARAMS *)param->data;
+ pbeSalt.data = (unsigned char *)pbe_param->pSalt;
+ pbeSalt.len = pbe_param->ulSaltLen;
+ pbeAlgID = SEC_PKCS5CreateAlgorithmID(algTag, &pbeSalt,
+ (int)pbe_param->ulIteration);
+ if(!pbeAlgID) {
+ return SECFailure;
+ }
+
+ rv = SECOID_CopyAlgorithmID(arena, algId, pbeAlgID);
+ SECOID_DestroyAlgorithmID(pbeAlgID, PR_TRUE);
+ return rv;
+}
+
+PBEBitGenContext *
+PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
+ SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded,
+ unsigned int iterations)
+{
+ SECItem *context = NULL;
+ SECItem mechItem;
+ CK_PBE_PARAMS pbe_params;
+ CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM;
+ PK11SymKey *symKey = NULL;
+ unsigned char ivData[8];
+
+
+ /* use the purpose to select the low level keygen algorithm */
+ switch (bitGenPurpose) {
+ case pbeBitGenIntegrityKey:
+ switch (hashAlgorithm) {
+ case SEC_OID_SHA1:
+ mechanism = CKM_PBA_SHA1_WITH_SHA1_HMAC;
+ break;
+ case SEC_OID_MD2:
+ mechanism = CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN;
+ break;
+ case SEC_OID_MD5:
+ mechanism = CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN;
+ break;
+ default:
+ break;
+ }
+ break;
+ case pbeBitGenCipherIV:
+ if (bitsNeeded > 64) {
+ break;
+ }
+ if (hashAlgorithm != SEC_OID_SHA1) {
+ break;
+ }
+ mechanism = CKM_PBE_SHA1_DES3_EDE_CBC;
+ case pbeBitGenCipherKey:
+ if (hashAlgorithm != SEC_OID_SHA1) {
+ break;
+ }
+ switch (bitsNeeded) {
+ case 40:
+ mechanism = CKM_PBE_SHA1_RC4_40;
+ break;
+ case 128:
+ mechanism = CKM_PBE_SHA1_RC4_128;
+ break;
+ default:
+ break;
+ }
+ case pbeBitGenIDNull:
+ break;
+ }
+
+ if (mechanism == CKM_INVALID_MECHANISM) {
+ /* we should set an error, but this is a depricated function, and
+ * we are keeping bug for bug compatibility;)... */
+ return NULL;
+ }
+
+ pbe_params.pInitVector = ivData;
+ pbe_params.pPassword = pwitem->data;
+ pbe_params.ulPasswordLen = pwitem->len;
+ pbe_params.pSalt = salt->data;
+ pbe_params.ulSaltLen = salt->len;
+ pbe_params.ulIteration = iterations;
+ mechItem.data = (unsigned char *) &pbe_params;
+ mechItem.len = sizeof(pbe_params);
+
+
+ symKey = PK11_RawPBEKeyGen(PK11_GetInternalSlot(),mechanism,
+ &mechItem, pwitem, PR_FALSE, NULL);
+ if (symKey == NULL) {
+ if (bitGenPurpose == pbeBitGenCipherIV) {
+ /* NOTE: this assumes that bitsNeeded is a multiple of 8! */
+ SECItem ivItem;
+
+ ivItem.data = ivData;
+ ivItem.len = bitsNeeded/8;
+ context = SECITEM_DupItem(&ivItem);
+ } else {
+ SECItem *keyData;
+ PK11_ExtractKeyValue(symKey);
+ keyData = PK11_GetKeyData(symKey);
+
+ /* assert bitsNeeded with length? */
+ if (keyData) {
+ context = SECITEM_DupItem(keyData);
+ }
+ }
+ PK11_FreeSymKey(symKey);
+ }
+
+ return (PBEBitGenContext *)context;
+}
+
+SECItem *
+PBE_GenerateBits(PBEBitGenContext *context)
+{
+ return (SECItem *)context;
+}
+
+void
+PBE_DestroyContext(PBEBitGenContext *context)
+{
+ SECITEM_FreeItem((SECItem *)context,PR_TRUE);
+}
+
+SECItem *
+SEC_PKCS5GetIV(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES)
+{
+ SECItem mechItem;
+ SECOidTag algorithm = SECOID_GetAlgorithmTag(algid);
+ CK_PBE_PARAMS *pbe_params;
+ CK_MECHANISM_TYPE mechanism;
+ SECItem *iv = NULL;
+ SECStatus rv;
+ int iv_len;
+ PK11SymKey *symKey;
+
+ rv = pbe_PK11AlgidToParam(algid,&mechItem);
+ if (rv != SECSuccess) {
+ return NULL;
+ }
+
+ mechanism = PK11_AlgtagToMechanism(algorithm);
+ iv_len = PK11_GetIVLength(mechanism);
+ pbe_params = (CK_PBE_PARAMS_PTR)mechItem.data;
+
+ symKey = PK11_RawPBEKeyGen(PK11_GetInternalSlot(),mechanism,
+ &mechItem, pwitem, faulty3DES,NULL);
+
+ if (symKey) {
+ SECItem tmp;
+
+ tmp.data = pbe_params->pInitVector;
+ tmp.len = iv_len;
+ iv = SECITEM_DupItem(&tmp);
+ PK11_FreeSymKey(symKey);
+ }
+
+ if (mechItem.data) {
+ PORT_ZFree(mechItem.data,mechItem.len);
+ }
+
+ return iv;
+}
+
+/*
+ * Subs from nss 3.x that are depricated
+ */
+PBEBitGenContext *
+__PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
+ SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded,
+ unsigned int iterations)
+{
+ PORT_Assert("__PBE_CreateContext is Depricated" == NULL);
+ return NULL;
+}
+
+SECItem *
+__PBE_GenerateBits(PBEBitGenContext *context)
+{
+ PORT_Assert("__PBE_GenerateBits is Depricated" == NULL);
+ return NULL;
+}
+
+void
+__PBE_DestroyContext(PBEBitGenContext *context)
+{
+ PORT_Assert("__PBE_DestroyContext is Depricated" == NULL);
+}
+
+SECStatus
+RSA_FormatBlock(SECItem *result, unsigned modulusLen,
+ int blockType, SECItem *data)
+{
+ PORT_Assert("RSA_FormatBlock is Depricated" == NULL);
+ return SECFailure;
+}
+
diff --git a/security/nss/lib/pk11wrap/pk11pk12.c b/security/nss/lib/pk11wrap/pk11pk12.c
index df6646e04..aea0ea8df 100644
--- a/security/nss/lib/pk11wrap/pk11pk12.c
+++ b/security/nss/lib/pk11wrap/pk11pk12.c
@@ -106,9 +106,41 @@ struct SECKEYRawPrivateKeyStr {
} u;
};
typedef struct SECKEYRawPrivateKeyStr SECKEYRawPrivateKey;
-/*const SEC_ASN1Template SECKEY_PrivateKeyInfoTemplate[];*/
+/* ASN1 Templates for new decoder/encoder */
+/*
+ * Attribute value for PKCS8 entries (static?)
+ */
+const SEC_ASN1Template SECKEY_AttributeTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(SECKEYAttribute) },
+ { SEC_ASN1_OBJECT_ID, offsetof(SECKEYAttribute, attrType) },
+ { SEC_ASN1_SET_OF, offsetof(SECKEYAttribute, attrValue),
+ SEC_AnyTemplate },
+ { 0 }
+};
+
+const SEC_ASN1Template SECKEY_SetOfAttributeTemplate[] = {
+ { SEC_ASN1_SET_OF, 0, SECKEY_AttributeTemplate },
+};
+
+const SEC_ASN1Template SECKEY_PrivateKeyInfoTemplate[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPrivateKeyInfo) },
+ { SEC_ASN1_INTEGER, offsetof(SECKEYPrivateKeyInfo,version) },
+ { SEC_ASN1_INLINE, offsetof(SECKEYPrivateKeyInfo,algorithm),
+ SECOID_AlgorithmIDTemplate },
+ { SEC_ASN1_OCTET_STRING, offsetof(SECKEYPrivateKeyInfo,privateKey) },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
+ offsetof(SECKEYPrivateKeyInfo,attributes),
+ SECKEY_SetOfAttributeTemplate },
+ { 0 }
+};
+
+const SEC_ASN1Template SECKEY_PointerToPrivateKeyInfoTemplate[] = {
+ { SEC_ASN1_POINTER, 0, SECKEY_PrivateKeyInfoTemplate }
+};
+
const SEC_ASN1Template SECKEY_RSAPrivateKeyExportTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYRawPrivateKey) },
{ SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.version) },
@@ -133,6 +165,25 @@ const SEC_ASN1Template SECKEY_DHPrivateKeyExportTemplate[] = {
{ SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dh.prime) },
};
+const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(SECKEYEncryptedPrivateKeyInfo) },
+ { SEC_ASN1_INLINE,
+ offsetof(SECKEYEncryptedPrivateKeyInfo,algorithm),
+ SECOID_AlgorithmIDTemplate },
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(SECKEYEncryptedPrivateKeyInfo,encryptedData) },
+ { 0 }
+};
+
+const SEC_ASN1Template SECKEY_PointerToEncryptedPrivateKeyInfoTemplate[] = {
+ { SEC_ASN1_POINTER, 0, SECKEY_EncryptedPrivateKeyInfoTemplate }
+};
+
+SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_EncryptedPrivateKeyInfoTemplate)
+SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToEncryptedPrivateKeyInfoTemplate)
+SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PrivateKeyInfoTemplate)
+SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToPrivateKeyInfoTemplate)
SECStatus
diff --git a/security/nss/lib/pk11wrap/pk11pqg.c b/security/nss/lib/pk11wrap/pk11pqg.c
index ef741198b..530548c36 100644
--- a/security/nss/lib/pk11wrap/pk11pqg.c
+++ b/security/nss/lib/pk11wrap/pk11pqg.c
@@ -42,7 +42,11 @@
*/
extern SECStatus
PK11_PQG_ParamGen(unsigned int j, PQGParams **pParams, PQGVerify **pVfy) {
+#ifdef notdef
return PQG_ParamGen(j, pParams, pVfy);
+#else
+ return SECFailure;
+#endif
}
/* Generate PQGParams and PQGVerify structs.
@@ -53,7 +57,11 @@ PK11_PQG_ParamGen(unsigned int j, PQGParams **pParams, PQGVerify **pVfy) {
extern SECStatus
PK11_PQG_ParamGenSeedLen( unsigned int j, unsigned int seedBytes,
PQGParams **pParams, PQGVerify **pVfy) {
+#ifdef notdef
return PQG_ParamGenSeedLen(j, seedBytes, pParams, pVfy);
+#else
+ return SECFailure;
+#endif
}
/* Test PQGParams for validity as DSS PQG values.
@@ -85,7 +93,11 @@ PK11_PQG_ParamGenSeedLen( unsigned int j, unsigned int seedBytes,
extern SECStatus
PK11_PQG_VerifyParams(const PQGParams *params,
const PQGVerify *vfy, SECStatus *result) {
+#ifdef notdef
return PQG_VerifyParams(params, vfy, result);
+#else
+ return SECFailure;
+#endif
}
diff --git a/security/nss/lib/pk11wrap/pk11skey.c b/security/nss/lib/pk11wrap/pk11skey.c
index c036e46a0..430bd2cf7 100644
--- a/security/nss/lib/pk11wrap/pk11skey.c
+++ b/security/nss/lib/pk11wrap/pk11skey.c
@@ -49,7 +49,7 @@
#include "sechash.h"
#include "cert.h"
#include "secerr.h"
-#include "secpkcs5.h"
+/*#include "secpkcs5.h" */
#define PAIRWISE_SECITEM_TYPE siBuffer
#define PAIRWISE_DIGEST_LENGTH SHA1_LENGTH /* 160-bits */
@@ -225,7 +225,7 @@ PK11_CreateSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, void *wincx)
symKey->data.data = NULL;
symKey->data.len = 0;
symKey->owner = PR_TRUE;
- symKey->objectID = CK_INVALID_KEY;
+ symKey->objectID = CK_INVALID_HANDLE;
symKey->slot = slot;
symKey->series = slot->series;
symKey->cx = wincx;
@@ -253,7 +253,7 @@ PK11_FreeSymKey(PK11SymKey *symKey)
}
PK11_USE_THREADS(PZ_Unlock(symKey->refLock);)
if (destroy) {
- if ((symKey->owner) && symKey->objectID != CK_INVALID_KEY) {
+ if ((symKey->owner) && symKey->objectID != CK_INVALID_HANDLE) {
pk11_EnterKeyMonitor(symKey);
(void) PK11_GETTAB(symKey->slot)->
C_DestroyObject(symKey->session, symKey->objectID);
@@ -301,7 +301,7 @@ PK11_SymKeyFromHandle(PK11SlotInfo *slot, PK11SymKey *parent, PK11Origin origin,
{
PK11SymKey *symKey;
- if (keyID == CK_INVALID_KEY) {
+ if (keyID == CK_INVALID_HANDLE) {
return NULL;
}
@@ -338,7 +338,7 @@ PK11_GetWrapKey(PK11SlotInfo *slot, int wrap, CK_MECHANISM_TYPE type,
PK11SymKey *symKey = NULL;
if (slot->series != series) return NULL;
- if (slot->refKeys[wrap] == CK_INVALID_KEY) return NULL;
+ if (slot->refKeys[wrap] == CK_INVALID_HANDLE) return NULL;
if (type == CKM_INVALID_MECHANISM) type = slot->wrapMechanism;
symKey = PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive,
@@ -535,7 +535,7 @@ PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey,
/* what about fortezza??? */
default:
PORT_SetError( SEC_ERROR_BAD_KEY );
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
templateCount = attrs - theTemplate;
@@ -547,7 +547,7 @@ PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey,
rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION, theTemplate,
templateCount, isToken, &objectID);
if ( rv != SECSuccess) {
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
}
@@ -588,7 +588,7 @@ PK11_FindFixedKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *keyID,
PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE));
key_id = pk11_FindObjectByTemplate(slot,findTemp,tsize);
- if (key_id == CK_INVALID_KEY) {
+ if (key_id == CK_INVALID_HANDLE) {
return NULL;
}
return PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive, type, key_id,
@@ -1140,7 +1140,7 @@ PK11_CopyKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE srcObject)
PK11_ExitSlotMonitor(slot);
if (crv == CKR_OK) return destObject;
PORT_SetError( PK11_MapError(crv) );
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
@@ -1374,7 +1374,7 @@ pk11_PairwiseConsistencyCheck(SECKEYPublicKey *pubKey,
}
id = PK11_ImportPublicKey(slot,pubKey,PR_FALSE);
- if (id == CK_INVALID_KEY) {
+ if (id == CK_INVALID_HANDLE) {
PK11_FreeSlot(slot);
return SECFailure;
}
@@ -1702,7 +1702,7 @@ pk11_loadPrivKey(PK11SlotInfo *slot,SECKEYPrivateKey *privKey,
if (pubKey->pkcs11Slot) {
PK11_FreeSlot(pubKey->pkcs11Slot);
pubKey->pkcs11Slot = NULL;
- pubKey->pkcs11ID = CK_INVALID_KEY;
+ pubKey->pkcs11ID = CK_INVALID_HANDLE;
}
}
@@ -2491,7 +2491,7 @@ PK11_MakeKEAPubKey(unsigned char *keyData,int length)
pubk->arena = arena;
pubk->pkcs11Slot = 0;
- pubk->pkcs11ID = CK_INVALID_KEY;
+ pubk->pkcs11ID = CK_INVALID_HANDLE;
pubk->keyType = fortezzaKey;
rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.KEAKey, &pkData);
if (rv != SECSuccess) {
@@ -3226,7 +3226,7 @@ pk11_restoreContext(PK11Context *context,void *space, unsigned long savedLength)
{
CK_RV crv;
CK_OBJECT_HANDLE objectID = (context->key) ? context->key->objectID:
- CK_INVALID_KEY;
+ CK_INVALID_HANDLE;
PORT_Assert(space != NULL);
if (space == NULL) {
@@ -4096,24 +4096,21 @@ PK11_DestroyPBEParams(SECItem *params)
SECAlgorithmID *
PK11_CreatePBEAlgorithmID(SECOidTag algorithm, int iteration, SECItem *salt)
{
- SECAlgorithmID *algid;
-
+ SECAlgorithmID *algid = NULL;
+#ifdef notdef
algid = SEC_PKCS5CreateAlgorithmID(algorithm, salt, iteration);
+#endif
return algid;
}
PK11SymKey *
-PK11_PBEKeyGen(PK11SlotInfo *slot, SECAlgorithmID *algid, SECItem *pwitem,
- PRBool faulty3DES, void *wincx)
+PK11_RawPBEKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *mech,
+ SECItem *pwitem, PRBool faulty3DES, void *wincx)
{
/* pbe stuff */
CK_PBE_PARAMS *pbe_params;
- CK_MECHANISM_TYPE type;
- SECItem *mech;
PK11SymKey *symKey;
- mech = PK11_ParamFromAlgid(algid);
- type = PK11_AlgtagToMechanism(SECOID_FindOIDTag(&algid->algorithm));
if(faulty3DES && (type == CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC)) {
type = CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC;
}
@@ -4134,6 +4131,30 @@ PK11_PBEKeyGen(PK11SlotInfo *slot, SECAlgorithmID *algid, SECItem *pwitem,
symKey = PK11_KeyGen(slot, type, mech, 0, wincx);
PORT_ZFree(pbe_params->pPassword, pwitem->len);
+ pbe_params->pPassword = NULL;
+ pbe_params->ulPasswordLen = 0;
+ return symKey;
+}
+
+PK11SymKey *
+PK11_PBEKeyGen(PK11SlotInfo *slot, SECAlgorithmID *algid, SECItem *pwitem,
+ PRBool faulty3DES, void *wincx)
+{
+ /* pbe stuff */
+ CK_MECHANISM_TYPE type;
+ SECItem *mech;
+ PK11SymKey *symKey;
+
+ mech = PK11_ParamFromAlgid(algid);
+ type = PK11_AlgtagToMechanism(SECOID_FindOIDTag(&algid->algorithm));
+ if(faulty3DES && (type == CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC)) {
+ type = CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC;
+ }
+ if(mech == NULL) {
+ return NULL;
+ }
+ symKey = PK11_RawPBEKeyGen(slot, type, mech, pwitem, faulty3DES, wincx);
+
SECITEM_ZfreeItem(mech, PR_TRUE);
return symKey;
}
@@ -4205,7 +4226,8 @@ PK11_ImportEncryptedPrivateKeyInfo(PK11SlotInfo *slot,
try_faulty_3des:
pbe_param = PK11_ParamFromAlgid(&epki->algorithm);
- key = PK11_PBEKeyGen(slot, &epki->algorithm, pwitem, faulty3DES, wincx);
+ key = PK11_RawPBEKeyGen(slot, mechanism, pbe_param, pwitem,
+ faulty3DES, wincx);
if((key == NULL) || (pbe_param == NULL)) {
rv = SECFailure;
goto done;
@@ -4372,7 +4394,9 @@ PK11_ExportEncryptedPrivateKeyInfo(PK11SlotInfo *slot, SECOidTag algTag,
goto loser;
}
epki->arena = arena;
+#ifdef notdef
algid = SEC_PKCS5CreateAlgorithmID(algTag, NULL, iteration);
+#endif
if(algid == NULL) {
rv = SECFailure;
goto loser;
@@ -4383,7 +4407,8 @@ PK11_ExportEncryptedPrivateKeyInfo(PK11SlotInfo *slot, SECOidTag algTag,
pbeMech.mechanism = mechanism;
pbeMech.pParameter = pbe_param->data;
pbeMech.ulParameterLen = pbe_param->len;
- key = PK11_PBEKeyGen(slot, algid, pwitem, PR_FALSE, wincx);
+ key = PK11_RawPBEKeyGen(slot, mechanism, pbe_param, pwitem,
+ PR_FALSE, wincx);
if((key == NULL) || (pbe_param == NULL)) {
rv = SECFailure;
diff --git a/security/nss/lib/pk11wrap/pk11slot.c b/security/nss/lib/pk11wrap/pk11slot.c
index f468c217b..b42607f57 100644
--- a/security/nss/lib/pk11wrap/pk11slot.c
+++ b/security/nss/lib/pk11wrap/pk11slot.c
@@ -49,9 +49,7 @@
#include "prtime.h"
#include "prlong.h"
#include "secerr.h"
-#include "secpkcs5.h"
-#define NSSCKT_H /* we included pkcs11t.h, so block ckt.h from including nssckt.h */
-#include "ckt.h"
+/*#include "secpkcs5.h" */
/*************************************************************
@@ -419,7 +417,7 @@ PK11_NewSlotInfo(void)
slot->series = 0;
slot->wrapKey = 0;
slot->wrapMechanism = CKM_INVALID_MECHANISM;
- slot->refKeys[0] = CK_INVALID_KEY;
+ slot->refKeys[0] = CK_INVALID_HANDLE;
slot->reason = PK11_DIS_NONE;
slot->readOnly = PR_TRUE;
slot->needLogin = PR_FALSE;
@@ -467,9 +465,6 @@ PK11_DestroySlot(PK11SlotInfo *slot)
PK11_GETTAB(slot)->C_CloseAllSessions(slot->slotID);
}
- /* now free up all the certificates we grabbed on this slot */
- PK11_FreeSlotCerts(slot);
-
/* free up the cached keys and sessions */
PK11_CleanKeyList(slot);
@@ -1082,9 +1077,6 @@ PK11_DoPassword(PK11SlotInfo *slot, PRBool loadCerts, void *wincx)
if (rv != SECWouldBlock) break;
}
if (rv == SECSuccess) {
- if ((loadCerts) && (!slot->isInternal) && (slot->cert_count == 0)) {
- PK11_ReadSlotCerts(slot);
- }
rv = pk11_CheckVerifyTest(slot);
} else if (!attempt) PORT_SetError(SEC_ERROR_BAD_PASSWORD);
return rv;
@@ -1715,14 +1707,6 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
}
- /*if we have cached slotcerts, free them they are almost certainly stale*/
- PK11_FreeSlotCerts(slot);
-
- if (loadCerts && (!slot->isInternal) &&
- ((!slot->needLogin) || (slot->defaultFlags & SECMOD_FRIENDLY_FLAG))) {
- PK11_ReadSlotCerts(slot);
- }
-
if (!(slot->needLogin)) {
return pk11_CheckVerifyTest(slot);
}
@@ -1783,7 +1767,7 @@ pk11_isRootSlot(PK11SlotInfo *slot)
PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE));
handle = pk11_FindObjectByTemplate(slot,findTemp,tsize);
- if (handle == CK_INVALID_KEY) {
+ if (handle == CK_INVALID_HANDLE) {
return PR_FALSE;
}
return PR_TRUE;
@@ -1891,7 +1875,6 @@ pk11_IsPresentCertLoad(PK11SlotInfo *slot, PRBool loadCerts)
PK11_GETTAB(slot)->C_CloseSession(slot->session);
slot->session = CK_INVALID_SESSION;
/* force certs to be freed */
- PK11_FreeSlotCerts(slot);
}
if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
return PR_FALSE;
@@ -1904,7 +1887,6 @@ pk11_IsPresentCertLoad(PK11SlotInfo *slot, PRBool loadCerts)
if (crv != CKR_OK) {
PK11_GETTAB(slot)->C_CloseSession(slot->session);
slot->session = CK_INVALID_SESSION;
- PK11_FreeSlotCerts(slot);
}
}
if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
@@ -3334,59 +3316,6 @@ static unsigned long rc2_unmap(unsigned long x)
}
-/*
- * Helper function to decode a PKCS5 DER encode paramter block into a PKCS #11
- * PBE_Parameter structure.
- */
-SECStatus
-pk11_pbe_decode(SECAlgorithmID *algid, SECItem *mech)
-{
- CK_PBE_PARAMS *pbe_params = NULL;
- SEC_PKCS5PBEParameter *p5_param;
- SECItem *p5_misc = NULL;
- int paramSize = 0;
-
- p5_param = SEC_PKCS5GetPBEParameter(algid);
- if(p5_param == NULL) {
- return SECFailure;
- }
-
-
- p5_misc = &p5_param->salt;
- paramSize = sizeof(CK_PBE_PARAMS);
-
- pbe_params = (CK_PBE_PARAMS *)PORT_ZAlloc(paramSize);
- if (pbe_params == NULL) {
- SEC_PKCS5DestroyPBEParameter(p5_param);
- return SECFailure;
- }
-
- /* get salt */
- pbe_params->pSalt = (CK_CHAR_PTR)PORT_ZAlloc(p5_misc->len);
- if (pbe_params->pSalt == CK_NULL_PTR) {
- goto loser;
- }
- PORT_Memcpy(pbe_params->pSalt, p5_misc->data, p5_misc->len);
- pbe_params->ulSaltLen = (CK_ULONG) p5_misc->len;
-
- /* get iteration count */
- p5_misc = &p5_param->iteration;
- pbe_params->ulIteration = (CK_ULONG) DER_GetInteger(p5_misc);
-
- /* copy into the mechanism sec item */
- mech->data = (unsigned char *)pbe_params;
- mech->len = paramSize;
- SEC_PKCS5DestroyPBEParameter(p5_param);
- return SECSuccess;
-
-loser:
- if (pbe_params->pSalt != CK_NULL_PTR) {
- PORT_Free(pbe_params->pSalt);
- }
- PORT_Free(pbe_params);
- SEC_PKCS5DestroyPBEParameter(p5_param);
- return SECFailure;
-}
/* Generate a mechaism param from a type, and iv. */
SECItem *
@@ -3520,7 +3449,7 @@ PK11_ParamFromAlgid(SECAlgorithmID *algid)
case CKM_PBE_SHA1_RC2_128_CBC:
case CKM_PBE_SHA1_RC4_40:
case CKM_PBE_SHA1_RC4_128:
- rv = pk11_pbe_decode(algid,mech);
+ rv = pbe_PK11AlgidToParam(algid,mech);
if (rv != SECSuccess) {
PORT_Free(mech);
return NULL;
@@ -4285,7 +4214,6 @@ PK11_ResetToken(PK11SlotInfo *slot, char *sso_pwd)
/* first shutdown the token. Existing sessions will get closed here */
PK11_GETTAB(slot)->C_CloseAllSessions(slot->slotID);
slot->session = CK_INVALID_SESSION;
- PK11_FreeSlotCerts(slot);
/* now re-init the token */
crv = PK11_GETTAB(slot)->C_InitToken(slot->slotID,
@@ -4301,47 +4229,14 @@ PK11_ResetToken(PK11SlotInfo *slot, char *sso_pwd)
return SECSuccess;
}
-
-
-
-static SECOidTag
-pk11_MapPBEMechanismTypeToAlgtag(CK_MECHANISM_TYPE mech)
-{
- switch(mech) {
- case CKM_PBE_MD2_DES_CBC:
- return SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC;
- case CKM_PBE_MD5_DES_CBC:
- return SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC;
- case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
- return SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC;
- case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
- return SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC;
- case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
- return SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC;
- case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
- return SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4;
- case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
- return SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4;
- case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
- return SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC;
- case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
- return SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC;
- case CKM_PBE_SHA1_RC2_128_CBC:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC;
- case CKM_PBE_SHA1_RC2_40_CBC:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC;
- case CKM_PBE_SHA1_RC4_40:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4;
- case CKM_PBE_SHA1_RC4_128:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4;
- case CKM_PBE_SHA1_DES3_EDE_CBC:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC;
- case CKM_PBE_SHA1_DES2_EDE_CBC:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC;
- default:
- break;
+static PRBool
+pk11_isAllZero(unsigned char *data,int len) {
+ while (len--) {
+ if (*data++) {
+ return PR_FALSE;
+ }
}
- return SEC_OID_UNKNOWN;
+ return PR_TRUE;
}
CK_RV
@@ -4353,9 +4248,6 @@ PK11_MapPBEMechanismToCryptoMechanism(CK_MECHANISM_PTR pPBEMechanism,
CK_PBE_PARAMS_PTR pPBEparams;
CK_RC2_CBC_PARAMS_PTR rc2_params;
CK_ULONG rc2_key_len;
- SECStatus rv = SECFailure;
- SECAlgorithmID temp_algid;
- SECItem param, *iv;
if((pPBEMechanism == CK_NULL_PTR) || (pCryptoMechanism == CK_NULL_PTR)) {
return CKR_HOST_MEMORY;
@@ -4364,32 +4256,20 @@ PK11_MapPBEMechanismToCryptoMechanism(CK_MECHANISM_PTR pPBEMechanism,
pPBEparams = (CK_PBE_PARAMS_PTR)pPBEMechanism->pParameter;
iv_len = PK11_GetIVLength(pPBEMechanism->mechanism);
- if(pPBEparams->pInitVector == CK_NULL_PTR) {
- pPBEparams->pInitVector = (CK_CHAR_PTR)PORT_ZAlloc(iv_len);
- if(pPBEparams->pInitVector == NULL) {
- return CKR_HOST_MEMORY;
- }
- param.data = (unsigned char*)pPBEMechanism->pParameter;
- param.len = pPBEMechanism->ulParameterLen;
- rv = PK11_ParamToAlgid(pk11_MapPBEMechanismTypeToAlgtag(
- pPBEMechanism->mechanism),
- &param, NULL, &temp_algid);
- if(rv != SECSuccess) {
- SECOID_DestroyAlgorithmID(&temp_algid, PR_FALSE);
- return CKR_HOST_MEMORY;
- } else {
- iv = SEC_PKCS5GetIV(&temp_algid, pbe_pwd, faulty3DES);
- if((iv == NULL) && (iv_len != 0)) {
- SECOID_DestroyAlgorithmID(&temp_algid, PR_FALSE);
- return CKR_HOST_MEMORY;
- }
- SECOID_DestroyAlgorithmID(&temp_algid, PR_FALSE);
- if(iv != NULL) {
- PORT_Memcpy((char *)pPBEparams->pInitVector,
- (char *)iv->data,
- iv->len);
- SECITEM_ZfreeItem(iv, PR_TRUE);
+ if (iv_len) {
+ if (pk11_isAllZero(pPBEparams->pInitVector,iv_len)) {
+ SECItem param;
+ PK11SymKey *symKey;
+
+ param.data = pPBEMechanism->pParameter;
+ param.len = pPBEMechanism->ulParameterLen;
+
+ symKey = PK11_RawPBEKeyGen(PK11_GetInternalSlot(),
+ pPBEMechanism->mechanism, &param, pbe_pwd, faulty3DES, NULL);
+ if (symKey== NULL) {
+ return CKR_DEVICE_ERROR; /* sigh */
}
+ PK11_FreeSymKey(symKey);
}
}
@@ -4430,9 +4310,10 @@ have_crypto_mechanism:
rc2_key_len = 128;
have_key_len:
pCryptoMechanism->mechanism = CKM_RC2_CBC;
- pCryptoMechanism->ulParameterLen = (CK_ULONG)sizeof(CK_RC2_CBC_PARAMS);
- pCryptoMechanism->pParameter =
- (CK_RC2_CBC_PARAMS_PTR)PORT_ZAlloc(sizeof(CK_RC2_CBC_PARAMS));
+ pCryptoMechanism->ulParameterLen = (CK_ULONG)
+ sizeof(CK_RC2_CBC_PARAMS);
+ pCryptoMechanism->pParameter = (CK_RC2_CBC_PARAMS_PTR)
+ PORT_ZAlloc(sizeof(CK_RC2_CBC_PARAMS));
if(pCryptoMechanism->pParameter == NULL) {
return CKR_HOST_MEMORY;
}
diff --git a/security/nss/lib/pk11wrap/pk11util.c b/security/nss/lib/pk11wrap/pk11util.c
index adf16cb43..a8326a404 100644
--- a/security/nss/lib/pk11wrap/pk11util.c
+++ b/security/nss/lib/pk11wrap/pk11util.c
@@ -460,8 +460,8 @@ SECStatus SECMOD_UpdateModule(SECMODModule *module)
result = SECMOD_DeletePermDB(module);
if (result == SECSuccess) {
- result = SECMOD_AddPermDB(module);
}
+ result = SECMOD_AddPermDB(module);
return result;
}
diff --git a/security/nss/lib/pk11wrap/secmodt.h b/security/nss/lib/pk11wrap/secmodt.h
index b36350ae6..de2ae10f3 100644
--- a/security/nss/lib/pk11wrap/secmodt.h
+++ b/security/nss/lib/pk11wrap/secmodt.h
@@ -162,8 +162,6 @@ struct PK11DefaultArrayEntryStr {
#define CKM_FAKE_RANDOM 0x80000efeL
#define CKM_INVALID_MECHANISM 0xffffffffL
#define CKA_DIGEST 0x81000000L
-#define CK_INVALID_KEY 0
-#define CK_INVALID_SESSION 0
/* Cryptographic module types */
#define SECMOD_EXTERNAL 0 /* external module */
@@ -206,11 +204,11 @@ typedef PRBool (*PK11IsLoggedInFunc)(PK11SlotInfo *slot, void *arg);
/*
** Attributes
*/
-struct SECKEYPrivAttributeStr {
+struct SECKEYAttributeStr {
SECItem attrType;
SECItem **attrValue;
};
-typedef struct SECKEYPrivAttributeStr SECKEYPrivAttribute;
+typedef struct SECKEYAttributeStr SECKEYAttribute;
/*
** A PKCS#8 private key info object
@@ -220,10 +218,9 @@ struct SECKEYPrivateKeyInfoStr {
SECItem version;
SECAlgorithmID algorithm;
SECItem privateKey;
- SECKEYPrivAttribute **attributes;
+ SECKEYAttribute **attributes;
};
typedef struct SECKEYPrivateKeyInfoStr SECKEYPrivateKeyInfo;
-#define SEC_PRIVATE_KEY_INFO_VERSION 0 /* what we *create* */
/*
** A PKCS#8 private key info object
diff --git a/security/nss/lib/pk11wrap/secmodti.h b/security/nss/lib/pk11wrap/secmodti.h
index b25c257c5..30f431f90 100644
--- a/security/nss/lib/pk11wrap/secmodti.h
+++ b/security/nss/lib/pk11wrap/secmodti.h
@@ -35,8 +35,12 @@
* pkcs11 specific client and server files.
*/
+#ifndef _SECMODTI_H_
+#define _SECMODTI_H_ 1
#include "prmon.h"
#include "prtypes.h"
+#include "nssilckt.h"
+#include "pk11init.h"
#ifndef NSS_3_4_CODE
#define NSS_3_4_CODE
@@ -129,19 +133,6 @@ struct PK11SlotInfoStr {
NSSToken *nssToken;
};
-/* hold slot default flags until we initialize a slot. This structure is only
- * useful between the time we define a module (either by hand or from the
- * database) and the time the module is loaded. Not reference counted */
-struct PK11PreSlotInfoStr {
- CK_SLOT_ID slotID; /* slot these flags are for */
- unsigned long defaultFlags; /* bit mask of default implementation this slot
- * provides */
- int askpw; /* slot specific password bits */
- long timeout; /* slot specific timeout value */
- char hasRootCerts; /* is this the root cert PKCS #11 module? */
- char hasRootTrust; /* is this the root cert PKCS #11 module? */
-};
-
#define SECMOD_SLOT_FLAGS "slotFlags=[RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES]"
#define SECMOD_MAKE_NSS_FLAGS(fips,slot) \
@@ -203,3 +194,4 @@ struct PK11ContextStr {
* non-standard semantics*/
};
+#endif /* _SECMODTI_H_ */
diff --git a/security/nss/lib/pkcs12/p12d.c b/security/nss/lib/pkcs12/p12d.c
index 60edeae0d..051428575 100644
--- a/security/nss/lib/pkcs12/p12d.c
+++ b/security/nss/lib/pkcs12/p12d.c
@@ -1976,8 +1976,7 @@ sec_pkcs12_get_existing_nick_for_dn(sec_PKCS12SafeBag *cert, void *wincx)
return NULL;
}
- tempCert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), derCert, NULL,
- PR_FALSE, PR_TRUE);
+ tempCert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
if(!tempCert) {
returnDn = NULL;
goto loser;
@@ -2002,15 +2001,6 @@ sec_pkcs12_get_existing_nick_for_dn(sec_PKCS12SafeBag *cert, void *wincx)
/* if the token is local, first traverse the cert database
* then traverse the token.
*/
- if(PK11_IsInternal(cert->slot)) {
- if(CERT_TraversePermCertsForSubject(CERT_GetDefaultCertDB(),
- &tempCert->derSubject, gatherNicknames,
- nickArg) != SECSuccess) {
- returnDn = NULL;
- goto loser;
- }
- }
-
if(PK11_TraverseCertsForSubjectInSlot(tempCert, cert->slot, gatherNicknames,
(void *)nickArg) != SECSuccess) {
returnDn = NULL;
@@ -2071,12 +2061,6 @@ sec_pkcs12_certs_for_nickname_exist(SECItem *nickname, PK11SlotInfo *slot)
}
/* we want to check the local database first if we are importing to it */
- if(PK11_IsInternal(slot)) {
- CERT_TraversePermCertsForNickname(CERT_GetDefaultCertDB(),
- (char *)nickname->data,
- countCertificate, (void *)&nCerts);
- }
-
PK11_TraverseCertsForNicknameInSlot(nickname, slot, countCertificate,
(void *)&nCerts);
if(nCerts) return PR_TRUE;
@@ -2243,9 +2227,8 @@ sec_pkcs12_validate_cert(sec_PKCS12SafeBag *cert,
cert->problem = PR_FALSE;
cert->error = 0;
- leafCert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
- &cert->safeBagContent.certBag->value.x509Cert,
- NULL, PR_FALSE, PR_TRUE);
+ leafCert = CERT_DecodeDERCertificate(
+ &cert->safeBagContent.certBag->value.x509Cert, PR_FALSE, NULL);
if(!leafCert) {
cert->noInstall = PR_TRUE;
cert->problem = PR_TRUE;
@@ -2297,9 +2280,8 @@ sec_pkcs12_validate_key_by_cert(sec_PKCS12SafeBag *cert, sec_PKCS12SafeBag *key,
return;
}
- leafCert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
- &(cert->safeBagContent.certBag->value.x509Cert),
- NULL, PR_FALSE, PR_TRUE);
+ leafCert = CERT_DecodeDERCertificate(
+ &(cert->safeBagContent.certBag->value.x509Cert), PR_FALSE, NULL);
if(!leafCert) {
key->problem = PR_TRUE;
key->noInstall = PR_TRUE;
@@ -2337,8 +2319,7 @@ sec_pkcs12_remove_existing_cert(sec_PKCS12SafeBag *cert,
cert->removeExisting = PR_FALSE;
derCert = &cert->safeBagContent.certBag->value.x509Cert;
- tempCert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), derCert,
- NULL, PR_FALSE, PR_TRUE);
+ tempCert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
if(!tempCert) {
return SECFailure;
}
@@ -2347,7 +2328,7 @@ sec_pkcs12_remove_existing_cert(sec_PKCS12SafeBag *cert,
CERT_DestroyCertificate(tempCert);
tempCert = NULL;
- if(certObj != CK_INVALID_KEY) {
+ if(certObj != CK_INVALID_HANDLE) {
PK11_DestroyObject(cert->slot, certObj);
removed = PR_TRUE;
} else if(PK11_IsInternal(cert->slot)) {
@@ -2408,8 +2389,7 @@ sec_pkcs12_add_cert(sec_PKCS12SafeBag *cert, PRBool keyExists, void *wincx)
if(keyExists) {
CERTCertificate *newCert;
- newCert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
- derCert, NULL, PR_FALSE, PR_TRUE);
+ newCert = CERT_DecodeDERCertificate( derCert, PR_FALSE, NULL);
if(!newCert) {
if(nickName) SECITEM_ZfreeItem(nickName, PR_TRUE);
cert->error = SEC_ERROR_NO_MEMORY;
@@ -2591,8 +2571,7 @@ SEC_PKCS12DecoderGetCerts(SEC_PKCS12DecoderContext *p12dcx)
CERTCertificate *tempCert = NULL;
if (derCert == NULL) continue;
- tempCert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
- derCert, NULL, PR_FALSE, PR_TRUE);
+ tempCert=CERT_DecodeDERCertificate(derCert, PR_TRUE, NULL);
if (tempCert) {
CERT_AddCertToListTail(certList,tempCert);
@@ -2777,9 +2756,8 @@ sec_pkcs12_get_public_value_and_type(sec_PKCS12SafeBag *certBag,
return NULL;
}
- cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
- &certBag->safeBagContent.certBag->value.x509Cert,
- NULL, PR_FALSE, PR_FALSE);
+ cert = CERT_DecodeDERCertificate(
+ &certBag->safeBagContent.certBag->value.x509Cert, PR_FALSE, NULL);
if(!cert) {
return NULL;
}
diff --git a/security/nss/lib/pkcs12/p12dec.c b/security/nss/lib/pkcs12/p12dec.c
index bae2bd736..f1f9fe464 100644
--- a/security/nss/lib/pkcs12/p12dec.c
+++ b/security/nss/lib/pkcs12/p12dec.c
@@ -44,8 +44,8 @@
#include "cert.h"
#include "certdb.h"
#include "p12plcy.h"
-#include "p12.h"
-#include "secpkcs5.h"
+#include "p12.h"
+/*#include "secpkcs5.h" */
/* PFX extraction and validation routines */
diff --git a/security/nss/lib/pkcs12/p12e.c b/security/nss/lib/pkcs12/p12e.c
index 22ff31104..1a7248e70 100644
--- a/security/nss/lib/pkcs12/p12e.c
+++ b/security/nss/lib/pkcs12/p12e.c
@@ -1029,17 +1029,17 @@ SEC_PKCS12AddCert(SEC_PKCS12ExportContext *p12ctxt, SEC_PKCS12SafeInfo *safe,
CERTCertificate *tempCert;
/* decode the certificate */
- tempCert = CERT_NewTempCertificate(certDb,
- &certList->certs[count], NULL,
- PR_FALSE, PR_TRUE);
+ tempCert =
+ CERT_DecodeDERCertificate( &certList->certs[count],
+ PR_FALSE, NULL);
if(!tempCert) {
CERT_DestroyCertificateList(certList);
goto loser;
}
/* add the certificate */
- if(SEC_PKCS12AddCert(p12ctxt, safe, nestedDest, tempCert, certDb,
- NULL, PR_FALSE) != SECSuccess) {
+ if(SEC_PKCS12AddCert(p12ctxt, safe, nestedDest, tempCert,
+ certDb, NULL, PR_FALSE) != SECSuccess) {
CERT_DestroyCertificate(tempCert);
CERT_DestroyCertificateList(certList);
goto loser;
@@ -1400,8 +1400,7 @@ SEC_PKCS12AddDERCertAndEncryptedKey(SEC_PKCS12ExportContext *p12ctxt,
mark = PORT_ArenaMark(p12ctxt->arena);
- cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), derCert,
- NULL, PR_FALSE, PR_TRUE);
+ cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
if(!cert) {
PORT_ArenaRelease(p12ctxt->arena, mark);
PORT_SetError(SEC_ERROR_NO_MEMORY);
diff --git a/security/nss/lib/pkcs12/p12plcy.c b/security/nss/lib/pkcs12/p12plcy.c
index e9616ade0..26edd16ba 100644
--- a/security/nss/lib/pkcs12/p12plcy.c
+++ b/security/nss/lib/pkcs12/p12plcy.c
@@ -35,7 +35,7 @@
#include "p12plcy.h"
#include "secoid.h"
#include "secport.h"
-#include "secpkcs5.h" /* LOTS of PKCS5 calls below. XXX EVIL. */
+/*#include "secpkcs5.h" LOTS of PKCS5 calls below. XXX EVIL. */
#define PKCS12_NULL 0x0000
diff --git a/security/nss/lib/pkcs7/p7common.c b/security/nss/lib/pkcs7/p7common.c
index 8bab3685f..329b078ed 100644
--- a/security/nss/lib/pkcs7/p7common.c
+++ b/security/nss/lib/pkcs7/p7common.c
@@ -485,16 +485,22 @@ SEC_PKCS7EncryptContents(PRArenaPool *poolp,
rv = SECFailure;
goto loser;
}
- eKey = PK11_PBEKeyGen(slot, algid, key, PR_FALSE, wincx);
- if(eKey == NULL) {
+ pbeMech.mechanism = PK11_AlgtagToMechanism(algtag);
+ result = PK11_ParamFromAlgid(algid);
+ if (result == NULL) {
rv = SECFailure;
goto loser;
}
-
- pbeMech.mechanism = PK11_AlgtagToMechanism(algtag);
- result = PK11_ParamFromAlgid(algid);
pbeMech.pParameter = result->data;
pbeMech.ulParameterLen = result->len;
+
+ eKey = PK11_RawPBEKeyGen(slot, pbeMech.mechanism, result, key, PR_FALSE,
+ wincx);
+ if(eKey == NULL) {
+ rv = SECFailure;
+ goto loser;
+ }
+
if(PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, key,
PR_FALSE) != CKR_OK) {
rv = SECFailure;
@@ -646,16 +652,20 @@ SEC_PKCS7DecryptContents(PRArenaPool *poolp,
rv = SECFailure;
goto loser;
}
- eKey = PK11_PBEKeyGen(slot, algid, key, PR_FALSE, wincx);
- if(eKey == NULL) {
+ pbeMech.mechanism = PK11_AlgtagToMechanism(algtag);
+ result = PK11_ParamFromAlgid(algid);
+ if (result == NULL) {
rv = SECFailure;
goto loser;
}
-
- pbeMech.mechanism = PK11_AlgtagToMechanism(algtag);
- result = PK11_ParamFromAlgid(algid);
pbeMech.pParameter = result->data;
pbeMech.ulParameterLen = result->len;
+ eKey = PK11_RawPBEKeyGen(slot,pbeMech.mechanism,result,key,PR_FALSE,wincx);
+ if(eKey == NULL) {
+ rv = SECFailure;
+ goto loser;
+ }
+
if(PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, key,
PR_FALSE) != CKR_OK) {
rv = SECFailure;
diff --git a/security/nss/lib/pkcs7/p7decode.c b/security/nss/lib/pkcs7/p7decode.c
index a6c47bbc1..0df147a3f 100644
--- a/security/nss/lib/pkcs7/p7decode.c
+++ b/security/nss/lib/pkcs7/p7decode.c
@@ -47,7 +47,7 @@
/* the add certificate code needs to get */
/* rewritten/abstracted and then this */
/* include should be removed! */
-#include "cdbhdl.h"
+/*#include "cdbhdl.h" */
#include "cryptohi.h"
#include "key.h"
#include "secasn1.h"
@@ -58,7 +58,7 @@
#include "secerr.h"
#include "sechash.h" /* for HASH_GetHashObject() */
#include "secder.h"
-#include "secpkcs5.h"
+/*#include "secpkcs5.h" */
struct sec_pkcs7_decoder_worker {
int depth;
@@ -1449,7 +1449,7 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
SEC_PKCS7SignerInfo **signerinfos, *signerinfo;
CERTCertificate *cert, **certs;
PRBool goodsig;
- CERTCertDBHandle local_certdb, *certdb, *defaultdb;
+ CERTCertDBHandle *certdb, *defaultdb;
SECOidData *algiddata;
int i, certcount;
SECKEYPublicKey *publickey;
@@ -1541,10 +1541,7 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
*/
certdb = defaultdb;
if (certdb == NULL) {
- if (CERT_OpenCertDBFilename (&local_certdb, NULL,
- (PRBool)!keepcerts) != SECSuccess)
- goto done;
- certdb = &local_certdb;
+ goto done;
}
certcount = 0;
@@ -1915,9 +1912,6 @@ done:
if (certs != NULL)
CERT_DestroyCertArray (certs, certcount);
- if (defaultdb == NULL && certdb != NULL)
- CERT_ClosePermCertDB (certdb);
-
if (publickey != NULL)
SECKEY_DestroyPublicKey (publickey);
diff --git a/security/nss/lib/pkcs7/p7encode.c b/security/nss/lib/pkcs7/p7encode.c
index c38026a56..879a1b286 100644
--- a/security/nss/lib/pkcs7/p7encode.c
+++ b/security/nss/lib/pkcs7/p7encode.c
@@ -96,7 +96,6 @@ sec_pkcs7_encoder_start_encrypt (SEC_PKCS7ContentInfo *cinfo,
void *mark, *wincx;
int i;
PRArenaPool *arena = NULL;
- unsigned char zero = 0;
/* Get the context in case we need it below. */
wincx = cinfo->pwfn_arg;
diff --git a/security/nss/lib/pkcs7/p7local.c b/security/nss/lib/pkcs7/p7local.c
index 68376cec0..114bf73eb 100644
--- a/security/nss/lib/pkcs7/p7local.c
+++ b/security/nss/lib/pkcs7/p7local.c
@@ -47,7 +47,7 @@
#include "secoid.h"
#include "secitem.h"
#include "pk11func.h"
-#include "secpkcs5.h"
+/*#include "secpkcs5.h" */
#include "secerr.h"
/*
diff --git a/security/nss/lib/pki/certdecode.c b/security/nss/lib/pki/certdecode.c
index d815275e4..deccb57ce 100644
--- a/security/nss/lib/pki/certdecode.c
+++ b/security/nss/lib/pki/certdecode.c
@@ -114,7 +114,7 @@ nssDecodedCert_Destroy
#if 0
nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
#endif
- return PR_FAILURE;
+ break;
}
return PR_FAILURE;
}
diff --git a/security/nss/lib/pki/certificate.c b/security/nss/lib/pki/certificate.c
index ff41de22d..16f9291e3 100644
--- a/security/nss/lib/pki/certificate.c
+++ b/security/nss/lib/pki/certificate.c
@@ -135,7 +135,7 @@ NSSCertificate_Create
if (!arenaOpt) {
rvCert->arena = arena;
}
- rvCert->handle = CK_INVALID_KEY;
+ rvCert->handle = CK_INVALID_HANDLE;
return rvCert;
loser:
if (!arenaOpt && arena) {
@@ -191,27 +191,30 @@ nssCertificate_GetCertTrust
)
{
PRStatus nssrv;
- CK_TRUST saTrust, epTrust, csTrust;
+ CK_TRUST saTrust, caTrust, epTrust, csTrust;
CK_OBJECT_HANDLE tobjID;
CK_ULONG trust_size;
CK_ATTRIBUTE trust_template[] = {
{ CKA_TRUST_SERVER_AUTH, NULL, 0 },
+ { CKA_TRUST_CLIENT_AUTH, NULL, 0 },
{ CKA_TRUST_EMAIL_PROTECTION, NULL, 0 },
{ CKA_TRUST_CODE_SIGNING, NULL, 0 }
};
trust_size = sizeof(trust_template) / sizeof(trust_template[0]);
tobjID = get_cert_trust_handle(c, session);
- if (tobjID == CK_INVALID_KEY) {
+ if (tobjID == CK_INVALID_HANDLE) {
return PR_FAILURE;
}
/* Then use the trust object to find the trust settings */
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 0, saTrust);
- NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 1, epTrust);
- NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 2, csTrust);
+ NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 1, caTrust);
+ NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 2, epTrust);
+ NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 3, csTrust);
nssrv = nssCKObject_GetAttributes(tobjID,
trust_template, trust_size,
NULL, session, c->slot);
c->trust.serverAuth = saTrust;
+ c->trust.clientAuth = caTrust;
c->trust.emailProtection = epTrust;
c->trust.codeSigning = csTrust;
return PR_SUCCESS;
@@ -371,9 +374,17 @@ nssCertificate_SetCertTrust
}
session = c->token->defaultSession;
tobjID = get_cert_trust_handle(c, session);
- if (tobjID == CK_INVALID_KEY) {
+ if (tobjID == CK_INVALID_HANDLE) {
/* trust object doesn't exist yet, create one */
- return create_cert_trust_object(c, trust);
+ tobjID = create_cert_trust_object(c, trust);
+ if (tobjID == CK_INVALID_HANDLE) {
+ return PR_FAILURE;
+ }
+ c->trust.serverAuth = trust->serverAuth;
+ c->trust.clientAuth = trust->clientAuth;
+ c->trust.emailProtection = trust->emailProtection;
+ c->trust.codeSigning = trust->codeSigning;
+ return PR_SUCCESS;
}
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 0, trust->serverAuth);
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 1, trust->clientAuth);
@@ -754,13 +765,15 @@ NSSCertificate_GetPublicKey
NSSCertificate *c
)
{
- PRStatus nssrv;
CK_ATTRIBUTE pubktemplate[] = {
{ CKA_CLASS, NULL, 0 },
{ CKA_ID, NULL, 0 },
{ CKA_SUBJECT, NULL, 0 }
};
+#if 0
+ PRStatus nssrv;
CK_ULONG count = sizeof(pubktemplate) / sizeof(pubktemplate[0]);
+#endif
NSS_CK_SET_ATTRIBUTE_ITEM(pubktemplate, 0, &g_ck_class_pubkey);
if (c->id.size > 0) {
/* CKA_ID */
diff --git a/security/nss/lib/pki/manifest.mn b/security/nss/lib/pki/manifest.mn
index 80713dba5..e52c8d146 100644
--- a/security/nss/lib/pki/manifest.mn
+++ b/security/nss/lib/pki/manifest.mn
@@ -57,8 +57,8 @@ CSRCS = \
$(NULL)
ifndef PURE_STAN_BUILD
-CSRCS += nss3hack.c
-PRIVATE_EXPORTS += pkinss3hack.h pkitm.h pkim.h
+CSRCS += pki3hack.c
+PRIVATE_EXPORTS += pki3hack.h pkitm.h pkim.h
DEFINES = -DNSS_3_4_CODE
endif
diff --git a/security/nss/lib/pki/nss3hack.c b/security/nss/lib/pki/pki3hack.c
index 5968ac571..db6a4e2b0 100644
--- a/security/nss/lib/pki/nss3hack.c
+++ b/security/nss/lib/pki/pki3hack.c
@@ -56,11 +56,11 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#endif /* CKHELPER_H */
#ifndef DEVNSS3HACK_H
-#include "devnss3hack.h"
+#include "dev3hack.h"
#endif /* DEVNSS3HACK_H */
#ifndef PKINSS3HACK_H
-#include "pkinss3hack.h"
+#include "pki3hack.h"
#endif /* PKINSS3HACK_H */
#include "secitem.h"
@@ -95,13 +95,10 @@ STAN_LoadDefaultNSS3TrustDomain
td->tokenList = nssList_Create(td->arena, PR_TRUE);
list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, NULL);
if (list) {
- /* XXX this doesn't work until softoken is a true PKCS#11 mod */
for (le = list->head; le; le = le->next) {
- if (!PK11_IsInternal(le->slot)) {
- token = nssToken_CreateFromPK11SlotInfo(td, le->slot);
- PK11Slot_SetNSSToken(le->slot, token);
- nssList_Add(td->tokenList, token);
- }
+ token = nssToken_CreateFromPK11SlotInfo(td, le->slot);
+ PK11Slot_SetNSSToken(le->slot, token);
+ nssList_Add(td->tokenList, token);
}
}
td->tokens = nssList_CreateIterator(td->tokenList);
@@ -322,7 +319,14 @@ static CERTCertTrust *
nssTrust_GetCERTCertTrust(NSSTrust *t, CERTCertificate *cc)
{
CERTCertTrust *rvTrust = PORT_ArenaAlloc(cc->arena, sizeof(CERTCertTrust));
+ unsigned int client;
rvTrust->sslFlags = get_nss3trust_from_cktrust(t->serverAuth);
+ client = get_nss3trust_from_cktrust(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);
if (PK11_IsUserCert(cc->slot, cc, cc->pkcs11ID)) {
@@ -347,7 +351,7 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc)
}
/* trust */
cc->trust = nssTrust_GetCERTCertTrust(&c->trust, cc);
- /* referenceCount addref? */
+ cc->referenceCount++;
/* subjectList ? */
/* pkcs11ID */
cc->pkcs11ID = c->handle;
@@ -378,14 +382,55 @@ NSS_EXTERN NSSCertificate *
STAN_GetNSSCertificate(CERTCertificate *cc)
{
NSSCertificate *c;
+ NSSArena *arena;
+
c = cc->nssCertificate;
- if (!c) {
- /* i don't think this should happen. but if it can, need to create
- * NSSCertificate from CERTCertificate values here.
- */
+ if (c) {
+ return c;
+ }
+
+ /* i don't think this should happen. but if it can, need to create
+ * NSSCertificate from CERTCertificate values here. */
+ /* Yup, it can happen. */
+ arena = NSSArena_Create();
+ if (!arena) {
return NULL;
}
+ c = NSSCertificate_Create(arena);
+ if (!c) {
+ goto loser;
+ }
+ NSSITEM_FROM_SECITEM(&c->encoding, &cc->derCert);
+ c->type = NSSCertificateType_PKIX;
+ c->arena = arena;
+ nssItem_Create(arena,
+ &c->issuer, cc->derIssuer.len, cc->derIssuer.data);
+ nssItem_Create(arena,
+ &c->subject, cc->derSubject.len, cc->derSubject.data);
+ nssItem_Create(arena,
+ &c->serial, cc->serialNumber.len, cc->serialNumber.data);
+ if (cc->nickname) {
+ c->nickname = nssUTF8_Create(arena,
+ nssStringType_UTF8String,
+ (NSSUTF8 *)cc->nickname,
+ PORT_Strlen(cc->nickname));
+ }
+ if (cc->emailAddr) {
+ c->email = nssUTF8_Create(arena,
+ nssStringType_PrintableString,
+ (NSSUTF8 *)cc->emailAddr,
+ PORT_Strlen(cc->emailAddr));
+ }
+ c->trustDomain = (NSSTrustDomain *)cc->dbhandle;
+ if (cc->slot) {
+ c->token = PK11Slot_GetNSSToken(cc->slot);
+ c->slot = c->token->slot;
+ }
+ cc->nssCertificate = c;
return c;
+loser:
+ nssArena_Destroy(arena);
+ return NULL;
}
static CK_TRUST
@@ -545,7 +590,8 @@ get_cert_type(NSSCertificateType nssType)
case NSSCertificateType_PKIX:
return CKC_X_509;
default:
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE; /* Not really! CK_INVALID_HANDLE is not a
+ * type CK_CERTIFICATE_TYPE */
}
}
@@ -591,7 +637,7 @@ nssTrustDomain_AddTempCertToPerm
/* 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_KEY) {
+ if (c->handle == CK_INVALID_HANDLE) {
return PR_FAILURE;
}
c->token = token;
diff --git a/security/nss/lib/pki/pkinss3hack.h b/security/nss/lib/pki/pki3hack.h
index c9c58e283..c9c58e283 100644
--- a/security/nss/lib/pki/pkinss3hack.h
+++ b/security/nss/lib/pki/pki3hack.h
diff --git a/security/nss/lib/pki/tdcache.c b/security/nss/lib/pki/tdcache.c
index f164bd609..6c01694dc 100644
--- a/security/nss/lib/pki/tdcache.c
+++ b/security/nss/lib/pki/tdcache.c
@@ -398,7 +398,7 @@ collect_subject_certs
)
{
NSSCertificate *c;
- NSSCertificate **rvArray;
+ NSSCertificate **rvArray = NULL;
PRUint32 count;
if (rvCertListOpt) {
nssListIterator *iter = nssList_CreateIterator(subjectList);
@@ -409,15 +409,13 @@ collect_subject_certs
}
nssListIterator_Finish(iter);
nssListIterator_Destroy(iter);
- return (NSSCertificate **)NULL;
} else {
count = nssList_Count(subjectList);
rvArray = nss_ZNEWARRAY(NULL, NSSCertificate *, count);
if (!rvArray) return (NSSCertificate **)NULL;
nssList_GetArray(subjectList, (void **)rvArray, count);
- return rvArray;
}
- return (NSSCertificate **)NULL;
+ return rvArray;
}
/*
diff --git a/security/nss/lib/pki/trustdomain.c b/security/nss/lib/pki/trustdomain.c
index 6f3a23dd9..91eeb24de 100644
--- a/security/nss/lib/pki/trustdomain.c
+++ b/security/nss/lib/pki/trustdomain.c
@@ -393,11 +393,8 @@ get_best_cert(NSSCertificate *c, void *arg)
}
/* either they are both valid at time, or neither valid; take the newer */
/* XXX later -- defer to policies */
- if (bestdc->isNewerThan(bestdc, dc)) {
- return PR_SUCCESS;
- } else {
+ if (!bestdc->isNewerThan(bestdc, dc)) {
best->cert = c;
- return PR_SUCCESS;
}
/* policies */
return PR_SUCCESS;
@@ -721,7 +718,7 @@ NSSTrustDomain_FindCertificateByIssuerAndSerialNumber
{
object = nssToken_FindObjectByTemplate(tok, NULL,
cert_template, ctsize);
- if (object != CK_INVALID_KEY) {
+ if (object != CK_INVALID_HANDLE) {
/* Could not find cert, so create it */
rvCert = nssCertificate_CreateFromHandle(NULL, object,
NULL, tok->slot);
@@ -864,7 +861,7 @@ NSSTrustDomain_FindCertificateByEncodedCertificate
{
object = nssToken_FindObjectByTemplate(tok, NULL,
cert_template, ctsize);
- if (object != CK_INVALID_KEY) {
+ if (object != CK_INVALID_HANDLE) {
/* Could not find cert, so create it */
rvCert = nssCertificate_CreateFromHandle(NULL, object,
NULL, tok->slot);
diff --git a/security/nss/lib/pki1/Makefile b/security/nss/lib/pki1/Makefile
index 72e97c17c..3207c6bbf 100644
--- a/security/nss/lib/pki1/Makefile
+++ b/security/nss/lib/pki1/Makefile
@@ -38,8 +38,10 @@ include config.mk
include $(CORE_DEPTH)/coreconf/rules.mk
# Generate oiddata.h and oiddata.c.
-generate:
- perl oidgen.perl < oids.txt
+$(OBJDIR)/oiddata.c $(OBJDIR)/oiddata.h: oidgen.perl oids.txt
+ @$(MAKE_OBJDIR)
+ rm -f $(OBJDIR)/oiddata.c $(OBJDIR)/oiddata.h
+ perl oidgen.perl $(OBJDIR)/oiddata.c $(OBJDIR)/oiddata.h oids.txt
-export:: generate private_export
+export:: private_export
diff --git a/security/nss/lib/pki1/atav.c b/security/nss/lib/pki1/atav.c
index 1f8d056a3..5d87efaf6 100644
--- a/security/nss/lib/pki1/atav.c
+++ b/security/nss/lib/pki1/atav.c
@@ -961,13 +961,13 @@ nss_atav_utf8_string_is_hex
return PR_TRUE;
}
-static PRUint8
+static NSSUTF8
nss_atav_fromhex
(
- PRUint8 *d
+ NSSUTF8 *d
)
{
- PRUint8 rv;
+ NSSUTF8 rv;
if( d[0] <= '9' ) {
rv = (d[0] - '0') * 16;
@@ -1105,8 +1105,8 @@ nssATAV_CreateFromUTF8
if( '#' == *value ) { /* XXX fgmr.. was it '#'? or backslash? */
PRUint32 size;
PRUint32 len;
- PRUint8 *c;
- PRUint8 *d;
+ NSSUTF8 *c;
+ NSSUTF8 *d;
PRStatus status;
/* It's in hex */
@@ -1717,6 +1717,9 @@ nssATAV_Compare
break;
case nssStringType_BMPString:
break;
+ case nssStringType_GeneralString:
+ /* what to do here? */
+ break;
case nssStringType_UTF8String:
break;
case nssStringType_PHGString:
diff --git a/security/nss/lib/pki1/manifest.mn b/security/nss/lib/pki1/manifest.mn
index e99df9a11..a5b4ef80f 100644
--- a/security/nss/lib/pki1/manifest.mn
+++ b/security/nss/lib/pki1/manifest.mn
@@ -35,7 +35,7 @@ MANIFEST_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$ $Name$"
CORE_DEPTH = ../../..
PRIVATE_EXPORTS = \
- oiddata.h \
+ $(OBJDIR)/oiddata.h \
pki1.h \
pki1t.h \
$(NULL)
@@ -47,6 +47,9 @@ EXPORTS = \
MODULE = security
+BUILT_CSRCS = oiddata.c \
+ $(NULL)
+
CSRCS = \
atav.c \
genname.c \
diff --git a/security/nss/lib/pki1/oidgen.perl b/security/nss/lib/pki1/oidgen.perl
index 959e3cbaf..2d644481e 100755
--- a/security/nss/lib/pki1/oidgen.perl
+++ b/security/nss/lib/pki1/oidgen.perl
@@ -32,7 +32,8 @@
# GPL.
#
$cvs_id = '@(#) $RCSfile$ $Revision$ $Date$ $Name$';
-
+$cfile = shift;
+$hfile = shift;
$count = -1;
while(<>) {
s/^((?:[^"#]+|"[^"]*")*)(\s*#.*$)/$1/;
@@ -60,7 +61,8 @@ while(<>) {
}
# dodump();
-doprint();
+
+doprint($cfile,$hfile);
sub dodump {
for( $i = 0; $i <= $count; $i++ ) {
@@ -73,8 +75,8 @@ for( $i = 0; $i <= $count; $i++ ) {
}
sub doprint {
-open(CFILE, ">oiddata.c") || die "Can't open oiddata.c: $!";
-open(HFILE, ">oiddata.h") || die "Can't open oiddata.h: $!";
+open(CFILE, "> $cfile") || die "Can't open $cfile: $!";
+open(HFILE, "> $hfile") || die "Can't open $hfile: $!";
print CFILE <<EOD
/* THIS IS A GENERATED FILE */
diff --git a/security/nss/lib/smime/cmscipher.c b/security/nss/lib/smime/cmscipher.c
index 27e5668aa..8ad4efcc5 100644
--- a/security/nss/lib/smime/cmscipher.c
+++ b/security/nss/lib/smime/cmscipher.c
@@ -43,7 +43,7 @@
#include "secitem.h"
#include "pk11func.h"
#include "secerr.h"
-#include "secpkcs5.h"
+/*#include "secpkcs5.h" */
/*
* -------------------------------------------------------------------
diff --git a/security/nss/lib/smime/cmsenvdata.c b/security/nss/lib/smime/cmsenvdata.c
index e64c829a6..fdd3d821a 100644
--- a/security/nss/lib/smime/cmsenvdata.c
+++ b/security/nss/lib/smime/cmsenvdata.c
@@ -46,7 +46,7 @@
#include "secoid.h"
#include "pk11func.h"
#include "secerr.h"
-#include "secpkcs5.h"
+/*#include "secpkcs5.h" */
/*
* NSS_CMSEnvelopedData_Create - create an enveloped data message
diff --git a/security/nss/lib/smime/cmssigdata.c b/security/nss/lib/smime/cmssigdata.c
index 34c36284f..1af54fc9b 100644
--- a/security/nss/lib/smime/cmssigdata.c
+++ b/security/nss/lib/smime/cmssigdata.c
@@ -40,7 +40,7 @@
#include "cmslocal.h"
#include "cert.h"
-#include "cdbhdl.h"
+/*#include "cdbhdl.h"*/
#include "secasn1.h"
#include "secitem.h"
#include "secoid.h"
diff --git a/security/nss/lib/softoken/alghmac.c b/security/nss/lib/softoken/alghmac.c
index aef81a76b..60abd73d0 100644
--- a/security/nss/lib/softoken/alghmac.c
+++ b/security/nss/lib/softoken/alghmac.c
@@ -31,10 +31,10 @@
* GPL.
*/
-#include "alghmac.h"
#include "sechash.h"
-#include "secoid.h"
#include "secport.h"
+#include "alghmac.h"
+/*#include "secoid.h"*/
#define HMAC_PAD_SIZE 64
@@ -57,8 +57,7 @@ HMAC_Destroy(HMACContext *cx)
}
HMACContext *
-HMAC_Create(SECOidTag hash_alg,
- const unsigned char *secret,
+HMAC_Create(const SECHashObject *hash_obj, const unsigned char *secret,
unsigned int secret_len)
{
HMACContext *cx;
@@ -68,20 +67,7 @@ HMAC_Create(SECOidTag hash_alg,
cx = (HMACContext*)PORT_ZAlloc(sizeof(HMACContext));
if (cx == NULL)
return NULL;
-
- switch (hash_alg) {
- case SEC_OID_MD5:
- cx->hashobj = &SECRawHashObjects[HASH_AlgMD5];
- break;
- case SEC_OID_MD2:
- cx->hashobj = &SECRawHashObjects[HASH_AlgMD2];
- break;
- case SEC_OID_SHA1:
- cx->hashobj = &SECRawHashObjects[HASH_AlgSHA1];
- break;
- default:
- goto loser;
- }
+ cx->hashobj = hash_obj;
cx->hash = cx->hashobj->create();
if (cx->hash == NULL)
diff --git a/security/nss/lib/softoken/alghmac.h b/security/nss/lib/softoken/alghmac.h
index 10d598267..3cb1a74dc 100644
--- a/security/nss/lib/softoken/alghmac.h
+++ b/security/nss/lib/softoken/alghmac.h
@@ -34,8 +34,6 @@
#ifndef _ALGHMAC_H_
#define _ALGHMAC_H_
-#include "secoid.h"
-
typedef struct HMACContextStr HMACContext;
SEC_BEGIN_PROTOS
@@ -53,7 +51,7 @@ HMAC_Destroy(HMACContext *cx);
* NULL is returned if an error occurs or the secret is > 64 bytes.
*/
extern HMACContext *
-HMAC_Create(SECOidTag hash_alg, const unsigned char *secret,
+HMAC_Create(const SECHashObject *hashObj, const unsigned char *secret,
unsigned int secret_len);
/* reset HMAC for a fresh round */
diff --git a/security/nss/lib/certdb/cdbhdl.h b/security/nss/lib/softoken/cdbhdl.h
index c195eb308..b606e9876 100644
--- a/security/nss/lib/certdb/cdbhdl.h
+++ b/security/nss/lib/softoken/cdbhdl.h
@@ -41,16 +41,13 @@
#include "nspr.h"
#include "mcom_db.h"
-#include "certt.h"
+#include "pcertt.h"
/*
* Handle structure for open certificate databases
*/
-struct CERTCertDBHandleStr {
+struct NSSLOWCERTCertDBHandleStr {
DB *permCertDB;
- DB *tempCertDB;
- void *spkDigestInfo;
- CERTStatusConfig *statusConfig;
PZMonitor *dbMon;
};
diff --git a/security/nss/lib/softoken/config.mk b/security/nss/lib/softoken/config.mk
index 0a00dc61e..702802b8c 100644
--- a/security/nss/lib/softoken/config.mk
+++ b/security/nss/lib/softoken/config.mk
@@ -36,8 +36,81 @@
# are specifed as dependencies within rules.mk.
#
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
+#TARGETS = $(LIBRARY)
+#SHARED_LIBRARY =
+#IMPORT_LIBRARY =
+#PROGRAM =
+# can't do this in manifest.mn because OS_ARCH isn't defined there.
+ifeq ($(OS_ARCH), WINNT)
+
+# 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
+
+RES = $(OBJDIR)/$(LIBRARY_NAME).res
+RESNAME = $(LIBRARY_NAME).rc
+
+# $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
+CRYPTOLIB=$(DIST)/lib/freebl.lib
+CRYPTODIR=../freebl
+ifdef MOZILLA_SECURITY_BUILD
+ CRYPTOLIB=$(DIST)/lib/crypto.lib
+ CRYPTODIR=../crypto
+endif
+
+EXTRA_SHARED_LIBRARY_LIBS += \
+ $(CRYPTOLIB) \
+ $(DIST)/lib/secutil.lib \
+ $(NULL)
+
+EXTRA_LIBS += \
+ $(DIST)/lib/dbm.lib \
+ $(NULL)
+
+ifdef MOZILLA_BSAFE_BUILD
+ EXTRA_LIBS+=$(DIST)/lib/bsafe$(BSAFEVER).lib
+endif
+
+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)
+else
+
+# $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
+CRYPTOLIB=$(DIST)/lib/libfreebl.$(LIB_SUFFIX)
+CRYPTODIR=../freebl
+ifdef MOZILLA_SECURITY_BUILD
+ CRYPTOLIB=$(DIST)/lib/libcrypto.$(LIB_SUFFIX)
+ CRYPTODIR=../crypto
+endif
+EXTRA_LIBS += \
+ $(CRYPTOLIB) \
+ $(DIST)/lib/libsecutil.$(LIB_SUFFIX) \
+ $(DIST)/lib/libdbm.$(LIB_SUFFIX) \
+ $(NULL)
+ifdef MOZILLA_BSAFE_BUILD
+ EXTRA_LIBS+=$(DIST)/lib/libbsafe.$(LIB_SUFFIX)
+endif
+
+# $(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_ARCH),SunOS)
+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
diff --git a/security/nss/lib/softoken/dbinit.c b/security/nss/lib/softoken/dbinit.c
index f31eb514b..bae037a4a 100644
--- a/security/nss/lib/softoken/dbinit.c
+++ b/security/nss/lib/softoken/dbinit.c
@@ -40,22 +40,15 @@
#include "prinit.h"
#include "prprf.h"
#include "prmem.h"
-#include "cert.h"
-#include "keylow.h"
-#include "keydbt.h"
-#include "ssl.h"
-#include "sslproto.h"
-#include "secmod.h"
-#include "secmodi.h"
-#include "secoid.h"
-#include "nss.h"
+#include "pcertt.h"
+#include "lowkeyi.h"
+#include "pcert.h"
+/*#include "secmodi.h" */
#include "secrng.h"
#include "cdbhdl.h"
-#include "pk11func.h"
+/*#include "pk11func.h" */
#include "pkcs11i.h"
-static char *secmodname = NULL;
-
static char *
pk11_certdb_name_cb(void *arg, int dbVersion)
{
@@ -109,77 +102,61 @@ pk11_keydb_name_cb(void *arg, int dbVersion)
#define CKR_KEYDB_FAILED CKR_DEVICE_ERROR
static CK_RV
-pk11_OpenCertDB(const char * configdir, const char *prefix, PRBool readOnly)
+pk11_OpenCertDB(const char * configdir, const char *prefix, PRBool readOnly,
+ NSSLOWCERTCertDBHandle **certdbPtr)
{
- CERTCertDBHandle *certdb;
- CK_RV crv = CKR_OK;
+ NSSLOWCERTCertDBHandle *certdb;
+ CK_RV crv = CKR_CERTDB_FAILED;
SECStatus rv;
char * name = NULL;
- certdb = CERT_GetDefaultCertDB();
- if (certdb)
- return CKR_OK; /* idempotency */
+ if (prefix == NULL) {
+ prefix = "";
+ }
name = PR_smprintf("%s" PATH_SEPARATOR "%s",configdir,prefix);
if (name == NULL) goto loser;
- certdb = (CERTCertDBHandle*)PORT_ZAlloc(sizeof(CERTCertDBHandle));
+ certdb = (NSSLOWCERTCertDBHandle*)PORT_ZAlloc(sizeof(NSSLOWCERTCertDBHandle));
if (certdb == NULL)
goto loser;
/* fix when we get the DB in */
- rv = CERT_OpenCertDB(certdb, readOnly, pk11_certdb_name_cb, (void *)name);
- if (rv == SECSuccess)
- CERT_SetDefaultCertDB(certdb);
- else {
- PR_Free(certdb);
-loser:
- crv = CKR_CERTDB_FAILED;
+ rv = nsslowcert_OpenCertDB(certdb, readOnly,
+ pk11_certdb_name_cb, (void *)name, PR_FALSE);
+ if (rv == SECSuccess) {
+ crv = CKR_OK;
+ *certdbPtr = certdb;
+ certdb = NULL;
}
+loser:
+ if (certdb) PR_Free(certdb);
if (name) PORT_Free(name);
return crv;
}
static CK_RV
-pk11_OpenKeyDB(const char * configdir, const char *prefix, PRBool readOnly)
+pk11_OpenKeyDB(const char * configdir, const char *prefix, PRBool readOnly,
+ NSSLOWKEYDBHandle **keydbPtr)
{
- SECKEYKeyDBHandle *keydb;
+ NSSLOWKEYDBHandle *keydb;
char * name = NULL;
- keydb = SECKEY_GetDefaultKeyDB();
- if (keydb)
- return SECSuccess;
+ if (prefix == NULL) {
+ prefix = "";
+ }
name = PR_smprintf("%s" PATH_SEPARATOR "%s",configdir,prefix);
if (name == NULL)
return SECFailure;
- keydb = SECKEY_OpenKeyDB(readOnly, pk11_keydb_name_cb, (void *)name);
+ keydb = nsslowkey_OpenKeyDB(readOnly, pk11_keydb_name_cb, (void *)name);
+ PORT_Free(name);
if (keydb == NULL)
return CKR_KEYDB_FAILED;
- SECKEY_SetDefaultKeyDB(keydb);
- PORT_Free(name);
+ *keydbPtr = keydb;
return CKR_OK;
}
-static CERTCertDBHandle certhandle = { 0 };
-
-static PRBool isInitialized = PR_FALSE;
-
-static CK_RV
-pk11_OpenVolatileCertDB() {
- SECStatus rv = SECSuccess;
- /* now we want to verify the signature */
- /* Initialize the cert code */
- rv = CERT_OpenVolatileCertDB(&certhandle);
- if (rv != SECSuccess) {
- return CKR_DEVICE_ERROR;
- }
- CERT_SetDefaultCertDB(&certhandle);
- return CKR_OK;
-}
-
-/* forward declare so that a failure in the init case can shutdown */
-void pk11_Shutdown(void);
/*
* OK there are now lots of options here, lets go through them all:
@@ -200,71 +177,53 @@ void pk11_Shutdown(void);
*/
CK_RV
pk11_DBInit(const char *configdir, const char *certPrefix,
- const char *keyPrefix,
- const char *secmodName, PRBool readOnly, PRBool noCertDB,
- PRBool noModDB, PRBool forceOpen)
+ const char *keyPrefix, PRBool readOnly,
+ PRBool noCertDB, PRBool noKeyDB, PRBool forceOpen,
+ NSSLOWCERTCertDBHandle **certdbPtr, NSSLOWKEYDBHandle **keydbPtr)
{
- SECStatus rv = SECFailure;
CK_RV crv = CKR_OK;
- if( isInitialized ) {
- return CKR_OK;
- }
-
- rv = RNG_RNGInit(); /* initialize random number generator */
- if (rv != SECSuccess) {
- crv = CKR_DEVICE_ERROR;
- goto loser;
- }
- RNG_SystemInfoForRNG();
- if (noCertDB) {
- crv = pk11_OpenVolatileCertDB();
- if (crv != CKR_OK) {
- goto loser;
- }
- } else {
- crv = pk11_OpenCertDB(configdir, certPrefix, readOnly);
+ if (!noCertDB) {
+ crv = pk11_OpenCertDB(configdir, certPrefix, readOnly, certdbPtr);
if (crv != CKR_OK) {
if (!forceOpen) goto loser;
- crv = pk11_OpenVolatileCertDB();
- if (crv != CKR_OK) {
- goto loser;
- }
+ crv = CKR_OK;
}
+ }
+ if (!noKeyDB) {
- crv = pk11_OpenKeyDB(configdir, keyPrefix, readOnly);
+ crv = pk11_OpenKeyDB(configdir, keyPrefix, readOnly, keydbPtr);
if (crv != CKR_OK) {
if (!forceOpen) goto loser;
+ crv = CKR_OK;
}
}
- isInitialized = PR_TRUE;
loser:
- if (crv != CKR_OK) {
- pk11_Shutdown();
- }
return crv;
}
+#ifdef notdef
void
pk11_Shutdown(void)
{
- CERTCertDBHandle *certHandle;
- SECKEYKeyDBHandle *keyHandle;
+ NSSLOWCERTCertDBHandle *certHandle;
+ NSSLOWKEYDBHandle *keyHandle;
PR_FREEIF(secmodname);
- certHandle = CERT_GetDefaultCertDB();
+ certHandle = nsslowcert_GetDefaultCertDB();
if (certHandle)
- CERT_ClosePermCertDB(certHandle);
- CERT_SetDefaultCertDB(NULL);
+ nsslowcert_ClosePermCertDB(certHandle);
+ nsslowcert_SetDefaultCertDB(NULL);
- keyHandle = SECKEY_GetDefaultKeyDB();
+ keyHandle = nsslowkey_GetDefaultKeyDB();
if (keyHandle)
- SECKEY_CloseKeyDB(keyHandle);
- SECKEY_SetDefaultKeyDB(NULL);
+ nsslowkey_CloseKeyDB(keyHandle);
+ nsslowkey_SetDefaultKeyDB(NULL);
isInitialized = PR_FALSE;
}
+#endif
diff --git a/security/nss/lib/softoken/fipstest.c b/security/nss/lib/softoken/fipstest.c
index f11448356..15e490090 100644
--- a/security/nss/lib/softoken/fipstest.c
+++ b/security/nss/lib/softoken/fipstest.c
@@ -39,7 +39,7 @@
/* DES-CBC, DES3-ECB, DES3-CBC, RSA */
/* and DSA. */
#include "seccomon.h" /* Required for RSA and DSA. */
-#include "keylow.h" /* Required for RSA and DSA. */
+#include "lowkeyi.h" /* Required for RSA and DSA. */
#include "pkcs11.h" /* Required for PKCS #11. */
#include "secerr.h"
@@ -792,13 +792,13 @@ pk11_fips_RSA_PowerUpSelfTest( void )
PLArenaPool * rsa_public_arena;
PLArenaPool * rsa_private_arena;
#endif
- SECKEYLowPublicKey * rsa_public_key;
- SECKEYLowPrivateKey * rsa_private_key;
+ NSSLOWKEYPublicKey * rsa_public_key;
+ NSSLOWKEYPrivateKey * rsa_private_key;
unsigned int rsa_bytes_signed;
SECStatus rsa_status;
- SECKEYLowPublicKey low_public_key = { NULL, lowRSAKey, };
- SECKEYLowPrivateKey low_private_key = { NULL, lowRSAKey, };
+ NSSLOWKEYPublicKey low_public_key = { NULL, NSSLOWKEYRSAKey, };
+ NSSLOWKEYPrivateKey low_private_key = { NULL, NSSLOWKEYRSAKey, };
PRUint8 rsa_computed_ciphertext[FIPS_RSA_ENCRYPT_LENGTH];
PRUint8 rsa_computed_plaintext[FIPS_RSA_DECRYPT_LENGTH];
PRUint8 rsa_computed_signature[FIPS_RSA_SIGNATURE_LENGTH];
@@ -894,16 +894,16 @@ pk11_fips_RSA_PowerUpSelfTest( void )
goto rsa_loser;
/* Dispose of all RSA key material. */
- SECKEY_LowDestroyPublicKey( rsa_public_key );
- SECKEY_LowDestroyPrivateKey( rsa_private_key );
+ nsslowkey_DestroyPublicKey( rsa_public_key );
+ nsslowkey_DestroyPrivateKey( rsa_private_key );
return( CKR_OK );
rsa_loser:
- SECKEY_LowDestroyPublicKey( rsa_public_key );
- SECKEY_LowDestroyPrivateKey( rsa_private_key );
+ nsslowkey_DestroyPublicKey( rsa_public_key );
+ nsslowkey_DestroyPrivateKey( rsa_private_key );
return( CKR_DEVICE_ERROR );
}
diff --git a/security/nss/lib/softoken/fipstokn.c b/security/nss/lib/softoken/fipstokn.c
index e72a9965a..b547a93e4 100644
--- a/security/nss/lib/softoken/fipstokn.c
+++ b/security/nss/lib/softoken/fipstokn.c
@@ -48,32 +48,11 @@
*/
#include "seccomon.h"
#include "softoken.h"
-#include "key.h"
+#include "lowkeyi.h"
+#include "pcert.h"
#include "pkcs11.h"
#include "pkcs11i.h"
-/* The next two strings must be exactly 64 characters long, with the
- first 32 characters meaningful */
-static char *slotDescription =
- "Netscape Internal FIPS-140-1 Cryptographic Services ";
-static char *privSlotDescription =
- "Netscape FIPS-140-1 User Private Key Services ";
-
-
-/*
- * Configuration utils
- */
-void
-PK11_ConfigureFIPS(char *slotdes, char *pslotdes)
-{
- if (slotdes && (PORT_Strlen(slotdes) == 65)) {
- slotDescription = slotdes;
- }
- if (pslotdes && (PORT_Strlen(pslotdes) == 65)) {
- privSlotDescription = pslotdes;
- }
- return;
-}
/*
* ******************** Password Utilities *******************************
@@ -170,30 +149,22 @@ CK_RV FC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList) {
/* FC_Initialize initializes the PKCS #11 library. */
CK_RV FC_Initialize(CK_VOID_PTR pReserved) {
- CK_RV rv;
- static PRBool init= PR_FALSE;
-
-
- rv = PK11_LowInitialize(pReserved);
+ CK_RV crv;
- if (rv == CKR_OK && !init) {
- init = PR_TRUE;
- rv = PK11_SlotInit(FIPS_SLOT_ID,PR_TRUE);
- /* fall through to check below */
- }
+ crv = nsc_CommonInitialize(pReserved, PR_TRUE);
/* not an 'else' rv can be set by either PK11_LowInit or PK11_SlotInit*/
- if (rv != CKR_OK) {
+ if (crv != CKR_OK) {
fatalError = PR_TRUE;
- return rv;
+ return crv;
}
fatalError = PR_FALSE; /* any error has been reset */
- rv = pk11_fipsPowerUpSelfTest();
- if (rv != CKR_OK) {
+ crv = pk11_fipsPowerUpSelfTest();
+ if (crv != CKR_OK) {
fatalError = PR_TRUE;
- return rv;
+ return crv;
}
return CKR_OK;
@@ -214,11 +185,7 @@ 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) {
- *pulCount = 1;
- if (pSlotList != NULL) {
- pSlotList[0] = FIPS_SLOT_ID;
- }
- return CKR_OK;
+ return NSC_GetSlotList(tokenPresent,pSlotList,pulCount);
}
/* FC_GetSlotInfo obtains information about a particular slot in the system. */
@@ -226,16 +193,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_RV crv;
- if (slotID != FIPS_SLOT_ID) return CKR_SLOT_ID_INVALID;
-
- /* Use NETSCAPE_SLOT_ID as a basis so that we get Library version number,
- * not key_DB version number */
- crv = NSC_GetSlotInfo(NETSCAPE_SLOT_ID,pInfo);
+ crv = NSC_GetSlotInfo(slotID,pInfo);
if (crv != CKR_OK) {
return crv;
}
- PORT_Memcpy(pInfo->slotDescription,slotDescription,64);
return CKR_OK;
}
@@ -244,13 +206,8 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_RV FC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo) {
CK_RV crv;
- if (slotID != FIPS_SLOT_ID) return CKR_SLOT_ID_INVALID;
-
- /* use PRIVATE_KEY_SLOT_ID so we get the correct
- Authentication information */
- crv = NSC_GetTokenInfo(PRIVATE_KEY_SLOT_ID,pInfo);
+ crv = NSC_GetTokenInfo(slotID,pInfo);
pInfo->flags |= CKF_RNG | CKF_LOGIN_REQUIRED;
- /* yes virginia, FIPS can do random number generation:) */
return crv;
}
@@ -261,9 +218,9 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_RV FC_GetMechanismList(CK_SLOT_ID slotID,
CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pusCount) {
PK11_FIPSFATALCHECK();
- if (slotID != FIPS_SLOT_ID) return CKR_SLOT_ID_INVALID;
+ if (slotID == FIPS_SLOT_ID) slotID = NETSCAPE_SLOT_ID;
/* FIPS Slot supports all functions */
- return NSC_GetMechanismList(NETSCAPE_SLOT_ID,pMechanismList,pusCount);
+ return NSC_GetMechanismList(slotID,pMechanismList,pusCount);
}
@@ -272,9 +229,9 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_RV FC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
CK_MECHANISM_INFO_PTR pInfo) {
PK11_FIPSFATALCHECK();
- if (slotID != FIPS_SLOT_ID) return CKR_SLOT_ID_INVALID;
+ if (slotID == FIPS_SLOT_ID) slotID = NETSCAPE_SLOT_ID;
/* FIPS Slot supports all functions */
- return NSC_GetMechanismInfo(NETSCAPE_SLOT_ID,type,pInfo);
+ return NSC_GetMechanismInfo(slotID,type,pInfo);
}
diff --git a/security/nss/lib/softoken/keydb.c b/security/nss/lib/softoken/keydb.c
index f13ca5374..cc00014f7 100644
--- a/security/nss/lib/softoken/keydb.c
+++ b/security/nss/lib/softoken/keydb.c
@@ -35,9 +35,7 @@
* $Id$
*/
-#include "keylow.h"
-#include "keydbt.h"
-#include "keytboth.h"
+#include "lowkeyi.h"
#include "seccomon.h"
#include "sechash.h"
#include "secder.h"
@@ -45,12 +43,12 @@
#include "secoid.h"
#include "blapi.h"
#include "secitem.h"
-#include "cert.h"
+#include "pcert.h"
#include "mcom_db.h"
-#include "secpkcs5.h"
+#include "lowpbe.h"
#include "secerr.h"
-#include "private.h"
+#include "keydbi.h"
/*
* Record keys for keydb
@@ -66,55 +64,36 @@
#define SALT_LENGTH 16
/* ASN1 Templates for new decoder/encoder */
-/*
- * Attribute value for PKCS8 entries (static?)
- */
-const SEC_ASN1Template SECKEY_AttributeTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SECKEYAttribute) },
- { SEC_ASN1_OBJECT_ID, offsetof(SECKEYAttribute, attrType) },
- { SEC_ASN1_SET_OF, offsetof(SECKEYAttribute, attrValue),
- SEC_AnyTemplate },
- { 0 }
-};
-
-const SEC_ASN1Template SECKEY_SetOfAttributeTemplate[] = {
- { SEC_ASN1_SET_OF, 0, SECKEY_AttributeTemplate },
-};
-
-const SEC_ASN1Template SECKEY_PrivateKeyInfoTemplate[] = {
+const SEC_ASN1Template nsslowkey_PrivateKeyInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(PrivateKeyInfo) },
+ 0, NULL, sizeof(NSSLOWKEYPrivateKeyInfo) },
{ SEC_ASN1_INTEGER,
- offsetof(PrivateKeyInfo,version) },
+ offsetof(NSSLOWKEYPrivateKeyInfo,version) },
{ SEC_ASN1_INLINE,
- offsetof(PrivateKeyInfo,algorithm),
+ offsetof(NSSLOWKEYPrivateKeyInfo,algorithm),
SECOID_AlgorithmIDTemplate },
{ SEC_ASN1_OCTET_STRING,
- offsetof(PrivateKeyInfo,privateKey) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(PrivateKeyInfo,attributes),
- SECKEY_SetOfAttributeTemplate },
+ offsetof(NSSLOWKEYPrivateKeyInfo,privateKey) },
{ 0 }
};
-const SEC_ASN1Template SECKEY_PointerToPrivateKeyInfoTemplate[] = {
- { SEC_ASN1_POINTER, 0, SECKEY_PrivateKeyInfoTemplate }
+const SEC_ASN1Template nsslowkey_PointerToPrivateKeyInfoTemplate[] = {
+ { SEC_ASN1_POINTER, 0, nsslowkey_PrivateKeyInfoTemplate }
};
-const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[] = {
+const SEC_ASN1Template nsslowkey_EncryptedPrivateKeyInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(EncryptedPrivateKeyInfo) },
+ 0, NULL, sizeof(NSSLOWKEYEncryptedPrivateKeyInfo) },
{ SEC_ASN1_INLINE,
- offsetof(EncryptedPrivateKeyInfo,algorithm),
+ offsetof(NSSLOWKEYEncryptedPrivateKeyInfo,algorithm),
SECOID_AlgorithmIDTemplate },
{ SEC_ASN1_OCTET_STRING,
- offsetof(EncryptedPrivateKeyInfo,encryptedData) },
+ offsetof(NSSLOWKEYEncryptedPrivateKeyInfo,encryptedData) },
{ 0 }
};
-const SEC_ASN1Template SECKEY_PointerToEncryptedPrivateKeyInfoTemplate[] = {
- { SEC_ASN1_POINTER, 0, SECKEY_EncryptedPrivateKeyInfoTemplate }
+const SEC_ASN1Template nsslowkey_PointerToEncryptedPrivateKeyInfoTemplate[] = {
+ { SEC_ASN1_POINTER, 0, nsslowkey_EncryptedPrivateKeyInfoTemplate }
};
@@ -126,13 +105,13 @@ static SECOidTag defaultKeyDBAlg = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_C
* Default algorithm for encrypting data in the key database
*/
SECOidTag
-SECKEY_GetDefaultKeyDBAlg(void)
+nsslowkey_GetDefaultKeyDBAlg(void)
{
return(defaultKeyDBAlg);
}
void
-SECKEY_SetDefaultKeyDBAlg(SECOidTag alg)
+nsslowkey_SetDefaultKeyDBAlg(SECOidTag alg)
{
defaultKeyDBAlg = alg;
@@ -140,7 +119,7 @@ SECKEY_SetDefaultKeyDBAlg(SECOidTag alg)
}
static void
-sec_destroy_dbkey(SECKEYDBKey *dbkey)
+sec_destroy_dbkey(NSSLOWKEYDBKey *dbkey)
{
if ( dbkey && dbkey->arena ) {
PORT_FreeArena(dbkey->arena, PR_FALSE);
@@ -170,7 +149,7 @@ free_dbt(DBT *dbt)
* ... encrypted-key-data
*/
static DBT *
-encode_dbkey(SECKEYDBKey *dbkey)
+encode_dbkey(NSSLOWKEYDBKey *dbkey)
{
DBT *bufitem = NULL;
unsigned char *buf;
@@ -202,7 +181,7 @@ encode_dbkey(SECKEYDBKey *dbkey)
buf = (unsigned char *)bufitem->data;
/* set version number */
- buf[0] = PRIVATE_KEY_DB_FILE_VERSION;
+ buf[0] = NSSLOWKEY_DB_FILE_VERSION;
/* set length of salt */
PORT_Assert(dbkey->salt.len < 256);
@@ -232,10 +211,10 @@ loser:
return(NULL);
}
-static SECKEYDBKey *
+static NSSLOWKEYDBKey *
decode_dbkey(DBT *bufitem, int expectedVersion)
{
- SECKEYDBKey *dbkey;
+ NSSLOWKEYDBKey *dbkey;
PLArenaPool *arena = NULL;
unsigned char *buf;
int version;
@@ -256,7 +235,7 @@ decode_dbkey(DBT *bufitem, int expectedVersion)
goto loser;
}
- dbkey = (SECKEYDBKey *)PORT_ArenaZAlloc(arena, sizeof(SECKEYDBKey));
+ dbkey = (NSSLOWKEYDBKey *)PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYDBKey));
if ( dbkey == NULL ) {
goto loser;
}
@@ -274,7 +253,7 @@ decode_dbkey(DBT *bufitem, int expectedVersion)
saltoff = 2;
keyoff = 2 + dbkey->salt.len;
- if ( expectedVersion == PRIVATE_KEY_DB_FILE_VERSION ) {
+ if ( expectedVersion == NSSLOWKEY_DB_FILE_VERSION ) {
nnlen = buf[2];
if ( nnlen ) {
dbkey->nickname = (char *)PORT_ArenaZAlloc(arena, nnlen + 1);
@@ -307,10 +286,10 @@ loser:
return(NULL);
}
-static SECKEYDBKey *
-get_dbkey(SECKEYKeyDBHandle *handle, DBT *index)
+static NSSLOWKEYDBKey *
+get_dbkey(NSSLOWKEYDBHandle *handle, DBT *index)
{
- SECKEYDBKey *dbkey;
+ NSSLOWKEYDBKey *dbkey;
DBT entry;
int ret;
@@ -323,13 +302,13 @@ get_dbkey(SECKEYKeyDBHandle *handle, DBT *index)
/* set up dbkey struct */
- dbkey = decode_dbkey(&entry, PRIVATE_KEY_DB_FILE_VERSION);
+ dbkey = decode_dbkey(&entry, NSSLOWKEY_DB_FILE_VERSION);
return(dbkey);
}
static SECStatus
-put_dbkey(SECKEYKeyDBHandle *handle, DBT *index, SECKEYDBKey *dbkey, PRBool update)
+put_dbkey(NSSLOWKEYDBHandle *handle, DBT *index, NSSLOWKEYDBKey *dbkey, PRBool update)
{
DBT *keydata = NULL;
int status;
@@ -369,7 +348,7 @@ loser:
}
SECStatus
-SECKEY_TraverseKeys(SECKEYKeyDBHandle *handle,
+nsslowkey_TraverseKeys(NSSLOWKEYDBHandle *handle,
SECStatus (* keyfunc)(DBT *k, DBT *d, void *pdata),
void *udata )
{
@@ -480,7 +459,7 @@ decodeKeyDBGlobalSalt(DBT *saltData)
}
static SECItem *
-GetKeyDBGlobalSalt(SECKEYKeyDBHandle *handle)
+GetKeyDBGlobalSalt(NSSLOWKEYDBHandle *handle)
{
DBT saltKey;
DBT saltData;
@@ -498,14 +477,14 @@ GetKeyDBGlobalSalt(SECKEYKeyDBHandle *handle)
}
static SECStatus
-makeGlobalVersion(SECKEYKeyDBHandle *handle)
+makeGlobalVersion(NSSLOWKEYDBHandle *handle)
{
unsigned char version;
DBT versionData;
DBT versionKey;
int status;
- version = PRIVATE_KEY_DB_FILE_VERSION;
+ version = NSSLOWKEY_DB_FILE_VERSION;
versionData.data = &version;
versionData.size = 1;
versionKey.data = VERSION_STRING;
@@ -522,7 +501,7 @@ makeGlobalVersion(SECKEYKeyDBHandle *handle)
static SECStatus
-makeGlobalSalt(SECKEYKeyDBHandle *handle)
+makeGlobalSalt(NSSLOWKEYDBHandle *handle)
{
DBT saltKey;
DBT saltData;
@@ -551,17 +530,241 @@ keyDBFilenameCallback(void *arg, int dbVersion)
return(PORT_Strdup((char *)arg));
}
-SECKEYKeyDBHandle *
-SECKEY_OpenKeyDBFilename(char *dbname, PRBool readOnly)
+NSSLOWKEYDBHandle *
+nsslowkey_OpenKeyDBFilename(char *dbname, PRBool readOnly)
{
- return(SECKEY_OpenKeyDB(readOnly, keyDBFilenameCallback,
+ return(nsslowkey_OpenKeyDB(readOnly, keyDBFilenameCallback,
(void *)dbname));
}
-SECKEYKeyDBHandle *
-SECKEY_OpenKeyDB(PRBool readOnly, SECKEYDBNameFunc namecb, void *cbarg)
+static SECStatus
+ChangeKeyDBPasswordAlg(NSSLOWKEYDBHandle *handle,
+ SECItem *oldpwitem, SECItem *newpwitem,
+ SECOidTag new_algorithm);
+/*
+ * Second pass of updating the key db. This time we have a password.
+ */
+static SECStatus
+nsslowkey_UpdateKeyDBPass2(NSSLOWKEYDBHandle *handle, SECItem *pwitem)
+{
+ SECStatus rv;
+
+ rv = ChangeKeyDBPasswordAlg(handle, pwitem, pwitem,
+ nsslowkey_GetDefaultKeyDBAlg());
+
+ return(rv);
+}
+
+static SECStatus
+encodePWCheckEntry(PLArenaPool *arena, SECItem *entry, SECOidTag alg,
+ SECItem *encCheck);
+/*
+ * currently updates key database from v2 to v3
+ */
+static SECStatus
+nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle)
+{
+ SECStatus rv;
+ DBT versionKey;
+ DBT versionData;
+ DBT checkKey;
+ DBT checkData;
+ DBT saltKey;
+ DBT saltData;
+ DBT key;
+ DBT data;
+ SECItem *rc4key = NULL;
+ NSSLOWKEYDBKey *dbkey = NULL;
+ SECItem *oldSalt = NULL;
+ int ret;
+ SECItem checkitem;
+
+ if ( handle->updatedb == NULL ) {
+ return(SECSuccess);
+ }
+
+ /*
+ * check the version record
+ */
+ versionKey.data = VERSION_STRING;
+ versionKey.size = sizeof(VERSION_STRING)-1;
+
+ ret = (* handle->updatedb->get)(handle->updatedb, &versionKey,
+ &versionData, 0 );
+
+ if (ret) {
+ /* no version record, so old db never used */
+ goto done;
+ }
+
+ if ( ( versionData.size != 1 ) ||
+ ( *((unsigned char *)versionData.data) != 2 ) ) {
+ /* corrupt or wrong version number so don't update */
+ 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) {
+ /*
+ * if we have a key, but no KEYDB_PW_CHECK_STRING, then this must
+ * be an old server database, and it does have a password associated
+ * with it. Put a fake entry in so we can identify this db when we do
+ * get the password for it.
+ */
+ if (seckey_HasAServerKey(handle->updatedb)) {
+ DBT fcheckKey;
+ DBT fcheckData;
+
+ /*
+ * include a fake string
+ */
+ fcheckKey.data = KEYDB_FAKE_PW_CHECK_STRING;
+ fcheckKey.size = KEYDB_FAKE_PW_CHECK_LEN;
+ fcheckData.data = "1";
+ fcheckData.size = 1;
+ /* put global salt into the new database now */
+ ret = (* handle->db->put)( handle->db, &saltKey, &saltData, 0);
+ if ( ret ) {
+ goto done;
+ }
+ ret = (* handle->db->put)( handle->db, &fcheckKey, &fcheckData, 0);
+ if ( ret ) {
+ goto done;
+ }
+ } else {
+ goto done;
+ }
+ } else {
+ /* put global salt into the new database now */
+ ret = (* handle->db->put)( handle->db, &saltKey, &saltData, 0);
+ if ( ret ) {
+ goto done;
+ }
+
+ dbkey = decode_dbkey(&checkData, 2);
+ if ( dbkey == NULL ) {
+ goto done;
+ }
+ checkitem = dbkey->derPK;
+ dbkey->derPK.data = NULL;
+
+ /* format the new pw check entry */
+ rv = encodePWCheckEntry(NULL, &dbkey->derPK, SEC_OID_RC4, &checkitem);
+ if ( rv != SECSuccess ) {
+ goto done;
+ }
+
+ rv = put_dbkey(handle, &checkKey, dbkey, PR_TRUE);
+ if ( rv != SECSuccess ) {
+ goto done;
+ }
+
+ /* free the dbkey */
+ sec_destroy_dbkey(dbkey);
+ dbkey = NULL;
+ }
+
+
+ /* 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;
+ }
+ }
+
+ /* keys stored by nickname will have 0 as the last byte of the
+ * db key. Other keys must be stored by modulus. We will not
+ * update those because they are left over from a keygen that
+ * never resulted in a cert.
+ */
+ if ( ((unsigned char *)key.data)[key.size-1] != 0 ) {
+ continue;
+ }
+
+ dbkey = decode_dbkey(&data, 2);
+ if ( dbkey == NULL ) {
+ continue;
+ }
+
+ /* This puts the key into the new database with the same
+ * index (nickname) that it had before. The second pass
+ * of the update will have the password. It will decrypt
+ * and re-encrypt the entries using a new algorithm.
+ */
+ dbkey->nickname = (char *)key.data;
+ rv = put_dbkey(handle, &key, dbkey, PR_FALSE);
+ dbkey->nickname = NULL;
+
+ sec_destroy_dbkey(dbkey);
+ }
+ } while ( (* handle->updatedb->seq)(handle->updatedb, &key, &data,
+ R_NEXT) == 0 );
+
+ dbkey = NULL;
+
+done:
+ /* sync the database */
+ ret = (* handle->db->sync)(handle->db, 0);
+
+ (* handle->updatedb->close)(handle->updatedb);
+ handle->updatedb = NULL;
+
+ if ( rc4key ) {
+ SECITEM_FreeItem(rc4key, PR_TRUE);
+ }
+
+ if ( oldSalt ) {
+ SECITEM_FreeItem(oldSalt, PR_TRUE);
+ }
+
+ if ( dbkey ) {
+ sec_destroy_dbkey(dbkey);
+ }
+
+ return(SECSuccess);
+}
+
+NSSLOWKEYDBHandle *
+nsslowkey_OpenKeyDB(PRBool readOnly, NSSLOWKEYDBNameFunc namecb, void *cbarg)
{
- SECKEYKeyDBHandle *handle;
+ NSSLOWKEYDBHandle *handle;
DBT versionKey;
DBT versionData;
int ret;
@@ -570,7 +773,7 @@ SECKEY_OpenKeyDB(PRBool readOnly, SECKEYDBNameFunc namecb, void *cbarg)
char *dbname = NULL;
PRBool updated = PR_FALSE;
- handle = (SECKEYKeyDBHandle *)PORT_ZAlloc (sizeof(SECKEYKeyDBHandle));
+ handle = (NSSLOWKEYDBHandle *)PORT_ZAlloc (sizeof(NSSLOWKEYDBHandle));
if (handle == NULL) {
PORT_SetError (SEC_ERROR_NO_MEMORY);
return NULL;
@@ -585,7 +788,7 @@ SECKEY_OpenKeyDB(PRBool readOnly, SECKEYDBNameFunc namecb, void *cbarg)
openflags = O_RDWR;
}
- dbname = (*namecb)(cbarg, PRIVATE_KEY_DB_FILE_VERSION);
+ dbname = (*namecb)(cbarg, NSSLOWKEY_DB_FILE_VERSION);
if ( dbname == NULL ) {
goto loser;
}
@@ -616,7 +819,7 @@ SECKEY_OpenKeyDB(PRBool readOnly, SECKEYDBNameFunc namecb, void *cbarg)
handle->version = *( (unsigned char *)versionData.data);
- if (handle->version != PRIVATE_KEY_DB_FILE_VERSION ) {
+ if (handle->version != NSSLOWKEY_DB_FILE_VERSION ) {
/* bogus version number record, reset the database */
(* handle->db->close)( handle->db );
handle->db = NULL;
@@ -666,7 +869,7 @@ newdb:
* have a password, then this will fail and we will do the
* update later
*/
- rv = SECKEY_UpdateKeyDBPass1(handle);
+ rv = nsslowkey_UpdateKeyDBPass1(handle);
if ( rv == SECSuccess ) {
updated = PR_TRUE;
}
@@ -716,11 +919,11 @@ loser:
* Close the database
*/
void
-SECKEY_CloseKeyDB(SECKEYKeyDBHandle *handle)
+nsslowkey_CloseKeyDB(NSSLOWKEYDBHandle *handle)
{
if (handle != NULL) {
- if (handle == SECKEY_GetDefaultKeyDB()) {
- SECKEY_SetDefaultKeyDB(NULL);
+ if (handle == nsslowkey_GetDefaultKeyDB()) {
+ nsslowkey_SetDefaultKeyDB(NULL);
}
if (handle->db != NULL) {
(* handle->db->close)(handle->db);
@@ -732,7 +935,7 @@ SECKEY_CloseKeyDB(SECKEYKeyDBHandle *handle)
/* Get the key database version */
int
-SECKEY_GetKeyDBVersion(SECKEYKeyDBHandle *handle)
+nsslowkey_GetKeyDBVersion(NSSLOWKEYDBHandle *handle)
{
PORT_Assert(handle != NULL);
@@ -744,16 +947,16 @@ SECKEY_GetKeyDBVersion(SECKEYKeyDBHandle *handle)
* not have to pass the handle all over the place.
*/
-static SECKEYKeyDBHandle *sec_default_key_db = NULL;
+static NSSLOWKEYDBHandle *sec_default_key_db = NULL;
void
-SECKEY_SetDefaultKeyDB(SECKEYKeyDBHandle *handle)
+nsslowkey_SetDefaultKeyDB(NSSLOWKEYDBHandle *handle)
{
sec_default_key_db = handle;
}
-SECKEYKeyDBHandle *
-SECKEY_GetDefaultKeyDB(void)
+NSSLOWKEYDBHandle *
+nsslowkey_GetDefaultKeyDB(void)
{
return sec_default_key_db;
}
@@ -762,7 +965,7 @@ SECKEY_GetDefaultKeyDB(void)
* Delete a private key that was stored in the database
*/
SECStatus
-SECKEY_DeleteKey(SECKEYKeyDBHandle *handle, SECItem *pubkey)
+nsslowkey_DeleteKey(NSSLOWKEYDBHandle *handle, SECItem *pubkey)
{
DBT namekey;
int ret;
@@ -797,112 +1000,66 @@ SECKEY_DeleteKey(SECKEYKeyDBHandle *handle, SECItem *pubkey)
* Store a key in the database, indexed by its public key modulus.(value!)
*/
SECStatus
-SECKEY_StoreKeyByPublicKey(SECKEYKeyDBHandle *handle,
- SECKEYLowPrivateKey *privkey,
+nsslowkey_StoreKeyByPublicKey(NSSLOWKEYDBHandle *handle,
+ NSSLOWKEYPrivateKey *privkey,
SECItem *pubKeyData,
char *nickname,
- SECKEYLowGetPasswordKey f, void *arg)
+ SECItem *arg)
{
- return SECKEY_StoreKeyByPublicKeyAlg(handle, privkey, pubKeyData, nickname,
- f, arg, SECKEY_GetDefaultKeyDBAlg());
+ return nsslowkey_StoreKeyByPublicKeyAlg(handle, privkey, pubKeyData,
+ nickname, arg, nsslowkey_GetDefaultKeyDBAlg());
}
/* see if the public key for this cert is in the database filed
* by modulus
*/
-SECStatus
-SECKEY_KeyForCertExists(SECKEYKeyDBHandle *handle, CERTCertificate *cert)
+PRBool
+nsslowkey_KeyForCertExists(NSSLOWKEYDBHandle *handle, NSSLOWCERTCertificate *cert)
{
- SECKEYPublicKey *pubkey = NULL;
+ NSSLOWKEYPublicKey *pubkey = NULL;
DBT namekey;
DBT dummy;
int status;
/* get cert's public key */
- pubkey = CERT_ExtractPublicKey(cert);
+ pubkey = nsslowcert_ExtractPublicKey(cert);
if ( pubkey == NULL ) {
- return SECFailure;
+ return PR_FALSE;
}
- /* TNH - make key from SECKEYPublicKey */
+ /* TNH - make key from NSSLOWKEYPublicKey */
switch (pubkey->keyType) {
- case rsaKey:
+ case NSSLOWKEYRSAKey:
namekey.data = pubkey->u.rsa.modulus.data;
namekey.size = pubkey->u.rsa.modulus.len;
break;
- case dsaKey:
+ case NSSLOWKEYDSAKey:
namekey.data = pubkey->u.dsa.publicValue.data;
namekey.size = pubkey->u.dsa.publicValue.len;
break;
- case dhKey:
+ case NSSLOWKEYDHKey:
namekey.data = pubkey->u.dh.publicValue.data;
namekey.size = pubkey->u.dh.publicValue.len;
break;
default:
/* XXX We don't do Fortezza or DH yet. */
- return SECFailure;
+ return PR_FALSE;
}
status = (* handle->db->get)(handle->db, &namekey, &dummy, 0);
- SECKEY_DestroyPublicKey(pubkey);
+ nsslowkey_DestroyPublicKey(pubkey);
if ( status ) {
- /* TNH - should this really set an error? */
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return SECFailure;
+ return PR_FALSE;
}
- return SECSuccess;
-}
-
-/*
- * find the private key for a cert
- */
-SECKEYLowPrivateKey *
-SECKEY_FindKeyByCert(SECKEYKeyDBHandle *handle, CERTCertificate *cert,
- SECKEYLowGetPasswordKey f, void *arg)
-{
- SECKEYPublicKey *pubkey = NULL;
- SECItem *keyItem = NULL;
- SECKEYLowPrivateKey *privKey = NULL;
-
- /* get cert's public key */
- pubkey = CERT_ExtractPublicKey(cert);
- if ( !pubkey ) {
- goto loser;
- }
-
- /* TNH - make record key from SECKEYPublicKey (again) */
- switch (pubkey->keyType) {
- case rsaKey:
- keyItem = &pubkey->u.rsa.modulus;
- break;
- case dsaKey:
- keyItem = &pubkey->u.dsa.publicValue;
- break;
- case dhKey:
- keyItem = &pubkey->u.dh.publicValue;
- break;
- /* fortezza an NULL keys are not stored in the data base */
- case keaKey:
- case fortezzaKey:
- case nullKey:
- goto loser;
- }
- PORT_Assert( keyItem != NULL );
-
- privKey = SECKEY_FindKeyByPublicKey(handle, keyItem, f, arg);
-
- /* success falls through */
-loser:
- SECKEY_DestroyPublicKey(pubkey);
- return(privKey);
+ return PR_TRUE;
}
/*
* check to see if the user has a password
*/
SECStatus
-SECKEY_HasKeyDBPassword(SECKEYKeyDBHandle *handle)
+nsslowkey_HasKeyDBPassword(NSSLOWKEYDBHandle *handle)
{
DBT checkkey, checkdata;
int ret;
@@ -933,23 +1090,10 @@ SECKEY_HasKeyDBPassword(SECKEYKeyDBHandle *handle)
* This is done by encrypting a known plaintext with the user's key.
*/
SECStatus
-SECKEY_SetKeyDBPassword(SECKEYKeyDBHandle *handle, SECItem *pwitem)
-{
- return SECKEY_SetKeyDBPasswordAlg(handle, pwitem,
- SECKEY_GetDefaultKeyDBAlg());
-}
-
-/*
- * Re-encrypt the entire key database with a new password.
- * NOTE: This really should create a new database rather than doing it
- * in place in the original
- */
-SECStatus
-SECKEY_ChangeKeyDBPassword(SECKEYKeyDBHandle *handle,
- SECItem *oldpwitem, SECItem *newpwitem)
+nsslowkey_SetKeyDBPassword(NSSLOWKEYDBHandle *handle, SECItem *pwitem)
{
- return SECKEY_ChangeKeyDBPasswordAlg(handle, oldpwitem, newpwitem,
- SECKEY_GetDefaultKeyDBAlg());
+ return nsslowkey_SetKeyDBPasswordAlg(handle, pwitem,
+ nsslowkey_GetDefaultKeyDBAlg());
}
static SECStatus
@@ -976,7 +1120,7 @@ HashPassword(unsigned char *hashresult, char *pw, SECItem *salt)
}
SECItem *
-SECKEY_HashPassword(char *pw, SECItem *salt)
+nsslowkey_HashPassword(char *pw, SECItem *salt)
{
SECItem *pwitem;
SECStatus rv;
@@ -1004,13 +1148,13 @@ SECKEY_HashPassword(char *pw, SECItem *salt)
/* Derive the actual password value for the database from a pw string */
SECItem *
-SECKEY_DeriveKeyDBPassword(SECKEYKeyDBHandle *keydb, char *pw)
+nsslowkey_DeriveKeyDBPassword(NSSLOWKEYDBHandle *keydb, char *pw)
{
PORT_Assert(keydb != NULL);
PORT_Assert(pw != NULL);
if (keydb == NULL || pw == NULL) return(NULL);
- return SECKEY_HashPassword(pw, keydb->global_salt);
+ return nsslowkey_HashPassword(pw, keydb->global_salt);
}
#if 0
@@ -1019,11 +1163,11 @@ SECKEY_DeriveKeyDBPassword(SECKEYKeyDBHandle *keydb, char *pw)
* is encrypted.
*/
SECOidTag
-seckey_get_private_key_algorithm(SECKEYKeyDBHandle *keydb, DBT *index)
+seckey_get_private_key_algorithm(NSSLOWKEYDBHandle *keydb, DBT *index)
{
- SECKEYDBKey *dbkey = NULL;
+ NSSLOWKEYDBKey *dbkey = NULL;
SECOidTag algorithm = SEC_OID_UNKNOWN;
- EncryptedPrivateKeyInfo *epki = NULL;
+ NSSLOWKEYEncryptedPrivateKeyInfo *epki = NULL;
PLArenaPool *poolp = NULL;
SECStatus rv;
@@ -1035,12 +1179,12 @@ seckey_get_private_key_algorithm(SECKEYKeyDBHandle *keydb, DBT *index)
if(dbkey == NULL)
return (SECOidTag)SECFailure;
- epki = (EncryptedPrivateKeyInfo *)PORT_ArenaZAlloc(poolp,
- sizeof(EncryptedPrivateKeyInfo));
+ epki = (NSSLOWKEYEncryptedPrivateKeyInfo *)PORT_ArenaZAlloc(poolp,
+ sizeof(NSSLOWKEYEncryptedPrivateKeyInfo));
if(epki == NULL)
goto loser;
rv = SEC_ASN1DecodeItem(poolp, epki,
- SECKEY_EncryptedPrivateKeyInfoTemplate, &dbkey->derPK);
+ nsslowkey_EncryptedPrivateKeyInfoTemplate, &dbkey->derPK);
if(rv == SECFailure)
goto loser;
@@ -1129,7 +1273,7 @@ seckey_create_rc4_salt(void)
}
SECItem *
-seckey_rc4_cipher(SECItem *key, SECItem *src, PRBool encrypt)
+seckey_rc4_decode(SECItem *key, SECItem *src)
{
SECItem *dest = NULL;
RC4Context *ctxt = NULL;
@@ -1149,11 +1293,7 @@ seckey_rc4_cipher(SECItem *key, SECItem *src, PRBool encrypt)
ctxt = RC4_CreateContext(key->data, key->len);
if(ctxt != NULL)
{
- if(encrypt == PR_TRUE)
- rv = RC4_Encrypt(ctxt, dest->data, &dest->len,
- src->len + 64, src->data, src->len);
- else
- rv = RC4_Decrypt(ctxt, dest->data, &dest->len,
+ rv = RC4_Decrypt(ctxt, dest->data, &dest->len,
src->len + 64, src->data, src->len);
RC4_DestroyContext(ctxt, PR_TRUE);
}
@@ -1171,19 +1311,21 @@ seckey_rc4_cipher(SECItem *key, SECItem *src, PRBool encrypt)
/* TNH - keydb is unused */
/* TNH - the pwitem should be the derived key for RC4 */
-EncryptedPrivateKeyInfo *
+NSSLOWKEYEncryptedPrivateKeyInfo *
seckey_encrypt_private_key(
- SECKEYLowPrivateKey *pk, SECItem *pwitem, SECKEYKeyDBHandle *keydb,
- SECOidTag algorithm)
+ NSSLOWKEYPrivateKey *pk, SECItem *pwitem, NSSLOWKEYDBHandle *keydb,
+ SECOidTag algorithm, SECItem **salt)
{
- EncryptedPrivateKeyInfo *epki = NULL;
- PrivateKeyInfo *pki = NULL;
+ NSSLOWKEYEncryptedPrivateKeyInfo *epki = NULL;
+ NSSLOWKEYPrivateKeyInfo *pki = NULL;
SECStatus rv = SECFailure;
- SECAlgorithmID *algid = NULL;
PLArenaPool *temparena = NULL, *permarena = NULL;
- SECItem *key = NULL, *salt = NULL, *der_item = NULL;
+ SECItem *der_item = NULL;
+ NSSPKCS5PBEParameter *param;
SECItem *dummy = NULL, *dest = NULL;
+ SECAlgorithmID *algid;
+ *salt = NULL;
permarena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
if(permarena == NULL)
return NULL;
@@ -1193,10 +1335,10 @@ seckey_encrypt_private_key(
goto loser;
/* allocate structures */
- epki = (EncryptedPrivateKeyInfo *)PORT_ArenaZAlloc(permarena,
- sizeof(EncryptedPrivateKeyInfo));
- pki = (PrivateKeyInfo *)PORT_ArenaZAlloc(temparena,
- sizeof(PrivateKeyInfo));
+ epki = (NSSLOWKEYEncryptedPrivateKeyInfo *)PORT_ArenaZAlloc(permarena,
+ sizeof(NSSLOWKEYEncryptedPrivateKeyInfo));
+ pki = (NSSLOWKEYPrivateKeyInfo *)PORT_ArenaZAlloc(temparena,
+ sizeof(NSSLOWKEYPrivateKeyInfo));
der_item = (SECItem *)PORT_ArenaZAlloc(temparena, sizeof(SECItem));
if((epki == NULL) || (pki == NULL) || (der_item == NULL))
goto loser;
@@ -1205,15 +1347,15 @@ seckey_encrypt_private_key(
/* setup private key info */
dummy = SEC_ASN1EncodeInteger(temparena, &(pki->version),
- SEC_PRIVATE_KEY_INFO_VERSION);
+ NSSLOWKEY_PRIVATE_KEY_INFO_VERSION);
if(dummy == NULL)
goto loser;
/* Encode the key, and set the algorithm (with params) */
switch (pk->keyType) {
- case lowRSAKey:
+ case NSSLOWKEYRSAKey:
dummy = SEC_ASN1EncodeItem(temparena, &(pki->privateKey), pk,
- SECKEY_LowRSAPrivateKeyTemplate);
+ nsslowkey_RSAPrivateKeyTemplate);
if (dummy == NULL) {
rv = SECFailure;
goto loser;
@@ -1226,16 +1368,16 @@ seckey_encrypt_private_key(
}
break;
- case lowDSAKey:
+ case NSSLOWKEYDSAKey:
dummy = SEC_ASN1EncodeItem(temparena, &(pki->privateKey), pk,
- SECKEY_LowDSAPrivateKeyTemplate);
+ nsslowkey_DSAPrivateKeyTemplate);
if (dummy == NULL) {
rv = SECFailure;
goto loser;
}
dummy = SEC_ASN1EncodeItem(temparena, NULL, &pk->u.dsa.params,
- SECKEY_LowPQGParamsTemplate);
+ nsslowkey_PQGParamsTemplate);
if (dummy == NULL) {
rv = SECFailure;
goto loser;
@@ -1248,9 +1390,9 @@ seckey_encrypt_private_key(
}
break;
- case lowDHKey:
+ case NSSLOWKEYDHKey:
dummy = SEC_ASN1EncodeItem(temparena, &(pki->privateKey), pk,
- SECKEY_LowDHPrivateKeyTemplate);
+ nsslowkey_DHPrivateKeyTemplate);
if (dummy == NULL) {
rv = SECFailure;
goto loser;
@@ -1270,85 +1412,72 @@ seckey_encrypt_private_key(
/* setup encrypted private key info */
dummy = SEC_ASN1EncodeItem(temparena, der_item, pki,
- SECKEY_PrivateKeyInfoTemplate);
+ nsslowkey_PrivateKeyInfoTemplate);
if(dummy == NULL) {
rv = SECFailure;
goto loser;
}
rv = SECFailure; /* assume failure */
- switch(algorithm)
- {
- case SEC_OID_RC4:
- salt = seckey_create_rc4_salt();
- if(salt != NULL)
- {
- key = seckey_create_rc4_key(pwitem, salt);
- if(key != NULL)
- {
- dest = seckey_rc4_cipher(key, der_item, PR_TRUE);
- if(dest != NULL)
- {
- rv = SECITEM_CopyItem(permarena, &epki->encryptedData,
- dest);
- if(rv == SECSuccess)
- rv = SECOID_SetAlgorithmID(permarena,
- &epki->algorithm, SEC_OID_RC4, salt);
- }
- }
- }
- if(dest != NULL)
- SECITEM_FreeItem(dest, PR_TRUE);
- if(key != NULL)
- SECITEM_ZfreeItem(key, PR_TRUE);
- break;
- default:
- algid = SEC_PKCS5CreateAlgorithmID(algorithm, NULL, 1);
- if(algid != NULL)
- {
- dest = SEC_PKCS5CipherData(algid, pwitem,
- der_item, PR_TRUE, NULL);
- if(dest != NULL)
- {
- rv = SECITEM_CopyItem(permarena, &epki->encryptedData,
- dest);
- if(rv == SECSuccess)
- rv = SECOID_CopyAlgorithmID(permarena,
- &epki->algorithm, algid);
- }
- }
- if(dest != NULL)
- SECITEM_FreeItem(dest, PR_TRUE);
- if(algid != NULL)
- SECOID_DestroyAlgorithmID(algid, PR_TRUE);
- break;
+ *salt = seckey_create_rc4_salt();
+ if (*salt == NULL) {
+ goto loser;
}
- /* let success fall through */
+ param = nsspkcs5_NewParam(algorithm,*salt,1);
+ if (param == NULL) {
+ goto loser;
+ }
+
+ dest = nsspkcs5_CipherData(param, pwitem, der_item, PR_TRUE, NULL);
+ if (dest == NULL) {
+ goto loser;
+ }
+
+ rv = SECITEM_CopyItem(permarena, &epki->encryptedData, dest);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ algid = nsspkcs5_CreateAlgorithmID(permarena, algorithm, param);
+ if (algid == NULL) {
+ rv = SECFailure;
+ goto loser;
+ }
+
+ rv = SECOID_CopyAlgorithmID(permarena, &epki->algorithm, algid);
+ SECOID_DestroyAlgorithmID(algid, PR_TRUE);
+
loser:
+ if(dest != NULL)
+ SECITEM_FreeItem(dest, PR_TRUE);
+
+ if(param != NULL)
+ nsspkcs5_DestroyPBEParameter(param);
+
+ /* let success fall through */
if(rv == SECFailure)
{
PORT_FreeArena(permarena, PR_TRUE);
- epki = NULL;
+ epki = NULL;
+ if(*salt != NULL)
+ SECITEM_FreeItem(*salt, PR_TRUE);
}
if(temparena != NULL)
PORT_FreeArena(temparena, PR_TRUE);
-
- if(salt != NULL)
- SECITEM_FreeItem(salt, PR_TRUE);
return epki;
}
-SECStatus
-seckey_put_private_key(SECKEYKeyDBHandle *keydb, DBT *index, SECItem *pwitem,
- SECKEYLowPrivateKey *pk, char *nickname, PRBool update,
+static SECStatus
+seckey_put_private_key(NSSLOWKEYDBHandle *keydb, DBT *index, SECItem *pwitem,
+ NSSLOWKEYPrivateKey *pk, char *nickname, PRBool update,
SECOidTag algorithm)
{
- SECKEYDBKey *dbkey = NULL;
- EncryptedPrivateKeyInfo *epki = NULL;
+ NSSLOWKEYDBKey *dbkey = NULL;
+ NSSLOWKEYEncryptedPrivateKeyInfo *epki = NULL;
PLArenaPool *temparena = NULL, *permarena = NULL;
SECItem *dummy = NULL;
SECItem *salt = NULL;
@@ -1362,7 +1491,7 @@ seckey_put_private_key(SECKEYKeyDBHandle *keydb, DBT *index, SECItem *pwitem,
if(permarena == NULL)
return SECFailure;
- dbkey = (SECKEYDBKey *)PORT_ArenaZAlloc(permarena, sizeof(SECKEYDBKey));
+ dbkey = (NSSLOWKEYDBKey *)PORT_ArenaZAlloc(permarena, sizeof(NSSLOWKEYDBKey));
if(dbkey == NULL)
goto loser;
dbkey->arena = permarena;
@@ -1370,33 +1499,19 @@ seckey_put_private_key(SECKEYKeyDBHandle *keydb, DBT *index, SECItem *pwitem,
/* TNH - for RC4, the salt should be created here */
- epki = seckey_encrypt_private_key(pk, pwitem, keydb, algorithm);
+ epki = seckey_encrypt_private_key(pk, pwitem, keydb, algorithm, &salt);
if(epki == NULL)
goto loser;
temparena = epki->arena;
- /* extract salt for db key */
- switch(algorithm)
+ if(salt != NULL)
{
- case SEC_OID_RC4:
- rv = SECITEM_CopyItem(permarena, &(dbkey->salt),
- &(epki->algorithm.parameters));
- epki->algorithm.parameters.len = 0;
- epki->algorithm.parameters.data = NULL;
- break;
- default:
- /* TNH - this should not be necessary */
- salt = SEC_PKCS5GetSalt(&epki->algorithm);
- if(salt != NULL)
- {
- rv = SECITEM_CopyItem(permarena, &(dbkey->salt), salt);
- SECITEM_ZfreeItem(salt, PR_TRUE);
- }
- break;
+ rv = SECITEM_CopyItem(permarena, &(dbkey->salt), salt);
+ SECITEM_ZfreeItem(salt, PR_TRUE);
}
dummy = SEC_ASN1EncodeItem(permarena, &(dbkey->derPK), epki,
- SECKEY_EncryptedPrivateKeyInfoTemplate);
+ nsslowkey_EncryptedPrivateKeyInfoTemplate);
if(dummy == NULL)
rv = SECFailure;
else
@@ -1418,15 +1533,14 @@ loser:
* Note that the nickname is optional. It was only used by keyutil.
*/
SECStatus
-SECKEY_StoreKeyByPublicKeyAlg(SECKEYKeyDBHandle *handle,
- SECKEYLowPrivateKey *privkey,
+nsslowkey_StoreKeyByPublicKeyAlg(NSSLOWKEYDBHandle *handle,
+ NSSLOWKEYPrivateKey *privkey,
SECItem *pubKeyData,
char *nickname,
- SECKEYLowGetPasswordKey f, void *arg,
+ SECItem *pwitem,
SECOidTag algorithm)
{
DBT namekey;
- SECItem *pwitem = NULL;
SECStatus rv;
if (handle == NULL) {
@@ -1438,29 +1552,24 @@ SECKEY_StoreKeyByPublicKeyAlg(SECKEYKeyDBHandle *handle,
namekey.data = pubKeyData->data;
namekey.size = pubKeyData->len;
- pwitem = (*f )(arg, handle);
- if ( pwitem == NULL ) {
- return(SECFailure);
- }
-
/* encrypt the private key */
rv = seckey_put_private_key(handle, &namekey, pwitem, privkey, nickname,
PR_FALSE, algorithm);
- SECITEM_ZfreeItem(pwitem, PR_TRUE);
return(rv);
}
-SECKEYLowPrivateKey *
-seckey_decrypt_private_key(EncryptedPrivateKeyInfo *epki,
+NSSLOWKEYPrivateKey *
+seckey_decrypt_private_key(NSSLOWKEYEncryptedPrivateKeyInfo *epki,
SECItem *pwitem)
{
- SECKEYLowPrivateKey *pk = NULL;
- PrivateKeyInfo *pki = NULL;
+ NSSLOWKEYPrivateKey *pk = NULL;
+ NSSLOWKEYPrivateKeyInfo *pki = NULL;
SECStatus rv = SECFailure;
SECOidTag algorithm;
PLArenaPool *temparena = NULL, *permarena = NULL;
SECItem *salt = NULL, *dest = NULL, *key = NULL;
+ NSSPKCS5PBEParameter *param;
if((epki == NULL) || (pwitem == NULL))
goto loser;
@@ -1471,12 +1580,12 @@ seckey_decrypt_private_key(EncryptedPrivateKeyInfo *epki,
goto loser;
/* allocate temporary items */
- pki = (PrivateKeyInfo *)PORT_ArenaZAlloc(temparena,
- sizeof(PrivateKeyInfo));
+ pki = (NSSLOWKEYPrivateKeyInfo *)PORT_ArenaZAlloc(temparena,
+ sizeof(NSSLOWKEYPrivateKeyInfo));
/* allocate permanent arena items */
- pk = (SECKEYLowPrivateKey *)PORT_ArenaZAlloc(permarena,
- sizeof(SECKEYLowPrivateKey));
+ pk = (NSSLOWKEYPrivateKey *)PORT_ArenaZAlloc(permarena,
+ sizeof(NSSLOWKEYPrivateKey));
if((pk == NULL) || (pki == NULL))
goto loser;
@@ -1493,8 +1602,7 @@ seckey_decrypt_private_key(EncryptedPrivateKeyInfo *epki,
key = seckey_create_rc4_key(pwitem, salt);
if(key != NULL)
{
- dest = seckey_rc4_cipher(key, &epki->encryptedData,
- PR_FALSE);
+ dest = seckey_rc4_decode(key, &epki->encryptedData);
}
}
if(salt != NULL)
@@ -1506,40 +1614,45 @@ seckey_decrypt_private_key(EncryptedPrivateKeyInfo *epki,
/* we depend on the fact that if this key was encoded with
* DES, that the pw was also encoded with DES, so we don't have
* to do the update here, the password code will handle it. */
- dest = SEC_PKCS5CipherData(&epki->algorithm, pwitem,
- &epki->encryptedData, PR_FALSE, NULL);
+ param = nsspkcs5_AlgidToParam(&epki->algorithm);
+ if (param == NULL) {
+ break;
+ }
+ dest = nsspkcs5_CipherData(param, pwitem, &epki->encryptedData,
+ PR_FALSE, NULL);
+ nsspkcs5_DestroyPBEParameter(param);
break;
}
if(dest != NULL)
{
rv = SEC_ASN1DecodeItem(temparena, pki,
- SECKEY_PrivateKeyInfoTemplate, dest);
+ nsslowkey_PrivateKeyInfoTemplate, dest);
if(rv == SECSuccess)
{
switch(SECOID_GetAlgorithmTag(&pki->algorithm)) {
case SEC_OID_X500_RSA_ENCRYPTION:
case SEC_OID_PKCS1_RSA_ENCRYPTION:
- pk->keyType = lowRSAKey;
+ pk->keyType = NSSLOWKEYRSAKey;
rv = SEC_ASN1DecodeItem(permarena, pk,
- SECKEY_LowRSAPrivateKeyTemplate,
+ nsslowkey_RSAPrivateKeyTemplate,
&pki->privateKey);
break;
case SEC_OID_ANSIX9_DSA_SIGNATURE:
- pk->keyType = lowDSAKey;
+ pk->keyType = NSSLOWKEYDSAKey;
rv = SEC_ASN1DecodeItem(permarena, pk,
- SECKEY_LowDSAPrivateKeyTemplate,
+ nsslowkey_DSAPrivateKeyTemplate,
&pki->privateKey);
if (rv != SECSuccess)
goto loser;
rv = SEC_ASN1DecodeItem(permarena, &pk->u.dsa.params,
- SECKEY_LowPQGParamsTemplate,
+ nsslowkey_PQGParamsTemplate,
&pki->algorithm.parameters);
break;
case SEC_OID_X942_DIFFIE_HELMAN_KEY:
- pk->keyType = lowDHKey;
+ pk->keyType = NSSLOWKEYDHKey;
rv = SEC_ASN1DecodeItem(permarena, pk,
- SECKEY_LowDHPrivateKeyTemplate,
+ nsslowkey_DHPrivateKeyTemplate,
&pki->privateKey);
break;
default:
@@ -1571,11 +1684,11 @@ loser:
return pk;
}
-static SECKEYLowPrivateKey *
-seckey_decode_encrypted_private_key(SECKEYDBKey *dbkey, SECItem *pwitem)
+static NSSLOWKEYPrivateKey *
+seckey_decode_encrypted_private_key(NSSLOWKEYDBKey *dbkey, SECItem *pwitem)
{
- SECKEYLowPrivateKey *pk = NULL;
- EncryptedPrivateKeyInfo *epki;
+ NSSLOWKEYPrivateKey *pk = NULL;
+ NSSLOWKEYEncryptedPrivateKeyInfo *epki;
PLArenaPool *temparena = NULL;
SECStatus rv;
SECOidTag algorithm;
@@ -1589,15 +1702,15 @@ seckey_decode_encrypted_private_key(SECKEYDBKey *dbkey, SECItem *pwitem)
return NULL;
}
- epki = (EncryptedPrivateKeyInfo *)
- PORT_ArenaZAlloc(temparena, sizeof(EncryptedPrivateKeyInfo));
+ epki = (NSSLOWKEYEncryptedPrivateKeyInfo *)
+ PORT_ArenaZAlloc(temparena, sizeof(NSSLOWKEYEncryptedPrivateKeyInfo));
if(epki == NULL) {
goto loser;
}
rv = SEC_ASN1DecodeItem(temparena, epki,
- SECKEY_EncryptedPrivateKeyInfoTemplate,
+ nsslowkey_EncryptedPrivateKeyInfoTemplate,
&(dbkey->derPK));
if(rv != SECSuccess) {
goto loser;
@@ -1625,12 +1738,12 @@ loser:
return pk;
}
-SECKEYLowPrivateKey *
-seckey_get_private_key(SECKEYKeyDBHandle *keydb, DBT *index, char **nickname,
+NSSLOWKEYPrivateKey *
+seckey_get_private_key(NSSLOWKEYDBHandle *keydb, DBT *index, char **nickname,
SECItem *pwitem)
{
- SECKEYDBKey *dbkey = NULL;
- SECKEYLowPrivateKey *pk = NULL;
+ NSSLOWKEYDBKey *dbkey = NULL;
+ NSSLOWKEYPrivateKey *pk = NULL;
if( ( keydb == NULL ) || ( index == NULL ) || ( pwitem == NULL ) ) {
return NULL;
@@ -1665,9 +1778,9 @@ loser:
* used by pkcs11 to import keys into it's object format... In the future
* we really need a better way to tie in...
*/
-SECKEYLowPrivateKey *
-SECKEY_DecryptKey(DBT *key, SECItem *pwitem,
- SECKEYKeyDBHandle *handle) {
+NSSLOWKEYPrivateKey *
+nsslowkey_DecryptKey(DBT *key, SECItem *pwitem,
+ NSSLOWKEYDBHandle *handle) {
return seckey_get_private_key(handle,key,NULL,pwitem);
}
@@ -1678,13 +1791,12 @@ SECKEY_DecryptKey(DBT *key, SECItem *pwitem,
* is looked up by the public modulus in the certificate, and the
* re-stored by its nickname.
*/
-SECKEYLowPrivateKey *
-SECKEY_FindKeyByPublicKey(SECKEYKeyDBHandle *handle, SECItem *modulus,
- SECKEYLowGetPasswordKey f, void *arg)
+NSSLOWKEYPrivateKey *
+nsslowkey_FindKeyByPublicKey(NSSLOWKEYDBHandle *handle, SECItem *modulus,
+ SECItem *pwitem)
{
DBT namekey;
- SECKEYLowPrivateKey *pk = NULL;
- SECItem *pwitem = NULL;
+ NSSLOWKEYPrivateKey *pk = NULL;
if (handle == NULL) {
PORT_SetError(SEC_ERROR_BAD_DATABASE);
@@ -1695,13 +1807,7 @@ SECKEY_FindKeyByPublicKey(SECKEYKeyDBHandle *handle, SECItem *modulus,
namekey.data = modulus->data;
namekey.size = modulus->len;
- pwitem = (*f )(arg, handle);
- if ( pwitem == NULL ) {
- return(NULL);
- }
-
pk = seckey_get_private_key(handle, &namekey, NULL, pwitem);
- SECITEM_ZfreeItem(pwitem, PR_TRUE);
/* no need to free dbkey, since its on the stack, and the data it
* points to is owned by the database
@@ -1754,15 +1860,15 @@ loser:
* This is done by encrypting a known plaintext with the user's key.
*/
SECStatus
-SECKEY_SetKeyDBPasswordAlg(SECKEYKeyDBHandle *handle,
+nsslowkey_SetKeyDBPasswordAlg(NSSLOWKEYDBHandle *handle,
SECItem *pwitem, SECOidTag algorithm)
{
DBT checkkey;
- SECAlgorithmID *algid = NULL;
+ NSSPKCS5PBEParameter *param = NULL;
SECStatus rv = SECFailure;
- SECKEYDBKey *dbkey = NULL;
+ NSSLOWKEYDBKey *dbkey = NULL;
PLArenaPool *arena;
- SECItem *key = NULL, *salt = NULL;
+ SECItem *salt = NULL;
SECItem *dest = NULL, test_key;
if (handle == NULL) {
@@ -1775,7 +1881,7 @@ SECKEY_SetKeyDBPasswordAlg(SECKEYKeyDBHandle *handle,
goto loser;
}
- dbkey = (SECKEYDBKey *)PORT_ArenaZAlloc(arena, sizeof(SECKEYDBKey));
+ dbkey = (NSSLOWKEYDBKey *)PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYDBKey));
if ( dbkey == NULL ) {
rv = SECFailure;
goto loser;
@@ -1793,40 +1899,31 @@ SECKEY_SetKeyDBPasswordAlg(SECKEYKeyDBHandle *handle,
goto loser;
}
- switch(algorithm)
- {
- case SEC_OID_RC4:
- key = seckey_create_rc4_key(pwitem, salt);
- if(key != NULL)
- {
- dest = seckey_rc4_cipher(key, &test_key, PR_TRUE);
- SECITEM_FreeItem(key, PR_TRUE);
- }
- break;
- default:
- algid = SEC_PKCS5CreateAlgorithmID(algorithm, salt, 1);
- if(algid != NULL)
- dest = SEC_PKCS5CipherData(algid, pwitem, &test_key,
- PR_TRUE, NULL);
- break;
+ param = nsspkcs5_NewParam(algorithm, salt, 1);
+ if (param == NULL) {
+ rv = SECFailure;
+ goto loser;
}
- if(dest != NULL)
+ dest = nsspkcs5_CipherData(param, pwitem, &test_key, PR_TRUE, NULL);
+ if (dest == NULL)
{
- rv = SECITEM_CopyItem(arena, &dbkey->salt, salt);
- if(rv == SECFailure)
- goto loser;
+ rv = SECFailure;
+ goto loser;
+ }
+
+ rv = SECITEM_CopyItem(arena, &dbkey->salt, salt);
+ if (rv == SECFailure) {
+ goto loser;
+ }
- rv = encodePWCheckEntry(arena, &dbkey->derPK, algorithm, dest);
-
- if ( rv != SECSuccess ) {
- goto loser;
- }
+ rv = encodePWCheckEntry(arena, &dbkey->derPK, algorithm, dest);
- rv = put_dbkey(handle, &checkkey, dbkey, PR_TRUE);
- } else {
- rv = SECFailure;
+ if ( rv != SECSuccess ) {
+ goto loser;
}
+
+ rv = put_dbkey(handle, &checkkey, dbkey, PR_TRUE);
/* let success fall through */
loser:
@@ -1841,6 +1938,10 @@ loser:
if ( salt != NULL ) {
SECITEM_ZfreeItem(salt, PR_TRUE);
}
+
+ if (param != NULL) {
+ nsspkcs5_DestroyPBEParameter(param);
+ }
return(rv);
}
@@ -1896,12 +1997,12 @@ seckey_HasAServerKey(DB *db)
}
static SECStatus
-seckey_CheckKeyDB1Password(SECKEYKeyDBHandle *handle, SECItem *pwitem)
+seckey_CheckKeyDB1Password(NSSLOWKEYDBHandle *handle, SECItem *pwitem)
{
SECStatus rv = SECFailure;
keyList keylist;
keyNode *node = NULL;
- SECKEYLowPrivateKey *privkey = NULL;
+ NSSLOWKEYPrivateKey *privkey = NULL;
/*
@@ -1919,7 +2020,7 @@ seckey_CheckKeyDB1Password(SECKEYKeyDBHandle *handle, SECItem *pwitem)
/* TNH - TraverseKeys should not be public, since it exposes
the underlying DBT data type. */
- rv = SECKEY_TraverseKeys(handle, sec_add_key_to_list, (void *)&keylist);
+ rv = nsslowkey_TraverseKeys(handle, sec_add_key_to_list, (void *)&keylist);
if ( rv != SECSuccess )
goto done;
@@ -1939,7 +2040,7 @@ seckey_CheckKeyDB1Password(SECKEYKeyDBHandle *handle, SECItem *pwitem)
/* if we can decrypt the private key, then we had the correct password */
rv = SECSuccess;
- SECKEY_LowDestroyPrivateKey(privkey);
+ nsslowkey_DestroyPrivateKey(privkey);
done:
@@ -1955,13 +2056,13 @@ done:
* check to see if the user has typed the right password
*/
SECStatus
-SECKEY_CheckKeyDBPassword(SECKEYKeyDBHandle *handle, SECItem *pwitem)
+nsslowkey_CheckKeyDBPassword(NSSLOWKEYDBHandle *handle, SECItem *pwitem)
{
DBT checkkey;
DBT checkdata;
- SECAlgorithmID *algid = NULL;
+ NSSPKCS5PBEParameter *param = NULL;
SECStatus rv = SECFailure;
- SECKEYDBKey *dbkey = NULL;
+ NSSLOWKEYDBKey *dbkey = NULL;
SECItem *key = NULL;
SECItem *dest = NULL;
SECOidTag algorithm;
@@ -1993,7 +2094,7 @@ SECKEY_CheckKeyDBPassword(SECKEYKeyDBHandle *handle, SECItem *pwitem)
rv = seckey_CheckKeyDB1Password(handle,pwitem);
if (rv == SECSuccess) {
/* OK we have enough to complete our conversion */
- SECKEY_UpdateKeyDBPass2(handle,pwitem);
+ nsslowkey_UpdateKeyDBPass2(handle,pwitem);
}
return rv;
}
@@ -2022,14 +2123,13 @@ SECKEY_CheckKeyDBPassword(SECKEYKeyDBHandle *handle, SECItem *pwitem)
case SEC_OID_RC4:
key = seckey_create_rc4_key(pwitem, &dbkey->salt);
if(key != NULL) {
- dest = seckey_rc4_cipher(key, &encstring, PR_FALSE);
+ dest = seckey_rc4_decode(key, &encstring);
SECITEM_FreeItem(key, PR_TRUE);
}
break;
default:
- algid = SEC_PKCS5CreateAlgorithmID(algorithm,
- &dbkey->salt, 1);
- if(algid != NULL) {
+ param = nsspkcs5_NewParam(algorithm, &dbkey->salt, 1);
+ if (param != NULL) {
/* Decrypt - this function implements a workaround for
* a previous coding error. It will decrypt values using
* DES rather than 3DES, if the initial try at 3DES
@@ -2037,9 +2137,9 @@ SECKEY_CheckKeyDBPassword(SECKEYKeyDBHandle *handle, SECItem *pwitem)
* set to TRUE. This indication is used later to force
* an update of the database to "real" 3DES encryption.
*/
- dest = SEC_PKCS5CipherData(algid, pwitem,
+ dest = nsspkcs5_CipherData(param, pwitem,
&encstring, PR_FALSE, &update);
- SECOID_DestroyAlgorithmID(algid, PR_TRUE);
+ nsspkcs5_DestroyPBEParameter(param);
}
break;
}
@@ -2055,7 +2155,7 @@ SECKEY_CheckKeyDBPassword(SECKEYKeyDBHandle *handle, SECItem *pwitem)
/* we succeeded */
if ( algorithm == SEC_OID_RC4 ) {
/* partially updated database */
- SECKEY_UpdateKeyDBPass2(handle, pwitem);
+ nsslowkey_UpdateKeyDBPass2(handle, pwitem);
}
/* Force an update of the password to remove the incorrect DES
* encryption (see the note above)
@@ -2063,7 +2163,7 @@ SECKEY_CheckKeyDBPassword(SECKEYKeyDBHandle *handle, SECItem *pwitem)
if (update &&
(algorithm == SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC)) {
/* data base was encoded with DES not triple des, fix it */
- SECKEY_UpdateKeyDBPass2(handle,pwitem);
+ nsslowkey_UpdateKeyDBPass2(handle,pwitem);
}
}
@@ -2082,14 +2182,14 @@ loser:
* the caller.
*/
static SECStatus
-ChangeKeyDBPasswordAlg(SECKEYKeyDBHandle *handle,
+ChangeKeyDBPasswordAlg(NSSLOWKEYDBHandle *handle,
SECItem *oldpwitem, SECItem *newpwitem,
SECOidTag new_algorithm)
{
SECStatus rv;
keyList keylist;
keyNode *node = NULL;
- SECKEYLowPrivateKey *privkey = NULL;
+ NSSLOWKEYPrivateKey *privkey = NULL;
char *nickname;
DBT newkey;
int ret;
@@ -2105,7 +2205,7 @@ ChangeKeyDBPasswordAlg(SECKEYKeyDBHandle *handle,
/* TNH - TraverseKeys should not be public, since it exposes
the underlying DBT data type. */
- rv = SECKEY_TraverseKeys(handle, sec_add_key_to_list, (void *)&keylist);
+ rv = nsslowkey_TraverseKeys(handle, sec_add_key_to_list, (void *)&keylist);
if ( rv != SECSuccess )
goto loser;
@@ -2133,20 +2233,19 @@ ChangeKeyDBPasswordAlg(SECKEYKeyDBHandle *handle,
/* get the public key, which we use as the database index */
switch (privkey->keyType) {
- case lowRSAKey:
+ case NSSLOWKEYRSAKey:
newkey.data = privkey->u.rsa.modulus.data;
newkey.size = privkey->u.rsa.modulus.len;
break;
- case lowDSAKey:
+ case NSSLOWKEYDSAKey:
newkey.data = privkey->u.dsa.publicValue.data;
newkey.size = privkey->u.dsa.publicValue.len;
break;
- case lowDHKey:
+ case NSSLOWKEYDHKey:
newkey.data = privkey->u.dh.publicValue.data;
newkey.size = privkey->u.dh.publicValue.len;
break;
default:
- /* XXX We don't do Fortezza. */
return SECFailure;
}
@@ -2164,7 +2263,7 @@ ChangeKeyDBPasswordAlg(SECKEYKeyDBHandle *handle,
node = node->next;
}
- rv = SECKEY_SetKeyDBPasswordAlg(handle, newpwitem, new_algorithm);
+ rv = nsslowkey_SetKeyDBPasswordAlg(handle, newpwitem, new_algorithm);
loser:
@@ -2182,9 +2281,8 @@ loser:
* in place in the original
*/
SECStatus
-SECKEY_ChangeKeyDBPasswordAlg(SECKEYKeyDBHandle *handle,
- SECItem *oldpwitem, SECItem *newpwitem,
- SECOidTag new_algorithm)
+nsslowkey_ChangeKeyDBPassword(NSSLOWKEYDBHandle *handle,
+ SECItem *oldpwitem, SECItem *newpwitem)
{
SECStatus rv;
@@ -2194,240 +2292,25 @@ SECKEY_ChangeKeyDBPasswordAlg(SECKEYKeyDBHandle *handle,
goto loser;
}
- rv = SECKEY_CheckKeyDBPassword(handle, oldpwitem);
+ rv = nsslowkey_CheckKeyDBPassword(handle, oldpwitem);
if ( rv != SECSuccess ) {
return(SECFailure); /* return rv? */
}
- rv = ChangeKeyDBPasswordAlg(handle, oldpwitem, newpwitem, new_algorithm);
+ rv = ChangeKeyDBPasswordAlg(handle, oldpwitem, newpwitem,
+ nsslowkey_GetDefaultKeyDBAlg());
loser:
return(rv);
}
-/*
- * Second pass of updating the key db. This time we have a password.
- */
-SECStatus
-SECKEY_UpdateKeyDBPass2(SECKEYKeyDBHandle *handle, SECItem *pwitem)
-{
- SECStatus rv;
-
- rv = ChangeKeyDBPasswordAlg(handle, pwitem, pwitem,
- SECKEY_GetDefaultKeyDBAlg());
-
- return(rv);
-}
-
-/*
- * currently updates key database from v2 to v3
- */
-SECStatus
-SECKEY_UpdateKeyDBPass1(SECKEYKeyDBHandle *handle)
-{
- SECStatus rv;
- DBT versionKey;
- DBT versionData;
- DBT checkKey;
- DBT checkData;
- DBT saltKey;
- DBT saltData;
- DBT key;
- DBT data;
- SECItem *rc4key = NULL;
- SECKEYDBKey *dbkey = NULL;
- SECItem *oldSalt = NULL;
- int ret;
- SECItem checkitem;
-
- if ( handle->updatedb == NULL ) {
- return(SECSuccess);
- }
-
- /*
- * check the version record
- */
- versionKey.data = VERSION_STRING;
- versionKey.size = sizeof(VERSION_STRING)-1;
-
- ret = (* handle->updatedb->get)(handle->updatedb, &versionKey,
- &versionData, 0 );
-
- if (ret) {
- /* no version record, so old db never used */
- goto done;
- }
-
- if ( ( versionData.size != 1 ) ||
- ( *((unsigned char *)versionData.data) != 2 ) ) {
- /* corrupt or wrong version number so don't update */
- 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) {
- /*
- * if we have a key, but no KEYDB_PW_CHECK_STRING, then this must
- * be an old server database, and it does have a password associated
- * with it. Put a fake entry in so we can identify this db when we do
- * get the password for it.
- */
- if (seckey_HasAServerKey(handle->updatedb)) {
- DBT fcheckKey;
- DBT fcheckData;
-
- /*
- * include a fake string
- */
- fcheckKey.data = KEYDB_FAKE_PW_CHECK_STRING;
- fcheckKey.size = KEYDB_FAKE_PW_CHECK_LEN;
- fcheckData.data = "1";
- fcheckData.size = 1;
- /* put global salt into the new database now */
- ret = (* handle->db->put)( handle->db, &saltKey, &saltData, 0);
- if ( ret ) {
- goto done;
- }
- ret = (* handle->db->put)( handle->db, &fcheckKey, &fcheckData, 0);
- if ( ret ) {
- goto done;
- }
- } else {
- goto done;
- }
- } else {
- /* put global salt into the new database now */
- ret = (* handle->db->put)( handle->db, &saltKey, &saltData, 0);
- if ( ret ) {
- goto done;
- }
-
- dbkey = decode_dbkey(&checkData, 2);
- if ( dbkey == NULL ) {
- goto done;
- }
- checkitem = dbkey->derPK;
- dbkey->derPK.data = NULL;
-
- /* format the new pw check entry */
- rv = encodePWCheckEntry(NULL, &dbkey->derPK, SEC_OID_RC4, &checkitem);
- if ( rv != SECSuccess ) {
- goto done;
- }
-
- rv = put_dbkey(handle, &checkKey, dbkey, PR_TRUE);
- if ( rv != SECSuccess ) {
- goto done;
- }
-
- /* free the dbkey */
- sec_destroy_dbkey(dbkey);
- dbkey = NULL;
- }
-
-
- /* 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;
- }
- }
-
- /* keys stored by nickname will have 0 as the last byte of the
- * db key. Other keys must be stored by modulus. We will not
- * update those because they are left over from a keygen that
- * never resulted in a cert.
- */
- if ( ((unsigned char *)key.data)[key.size-1] != 0 ) {
- continue;
- }
-
- dbkey = decode_dbkey(&data, 2);
- if ( dbkey == NULL ) {
- continue;
- }
-
- /* This puts the key into the new database with the same
- * index (nickname) that it had before. The second pass
- * of the update will have the password. It will decrypt
- * and re-encrypt the entries using a new algorithm.
- */
- dbkey->nickname = (char *)key.data;
- rv = put_dbkey(handle, &key, dbkey, PR_FALSE);
- dbkey->nickname = NULL;
-
- sec_destroy_dbkey(dbkey);
- }
- } while ( (* handle->updatedb->seq)(handle->updatedb, &key, &data,
- R_NEXT) == 0 );
-
- dbkey = NULL;
-
-done:
- /* sync the database */
- ret = (* handle->db->sync)(handle->db, 0);
-
- (* handle->updatedb->close)(handle->updatedb);
- handle->updatedb = NULL;
-
- if ( rc4key ) {
- SECITEM_FreeItem(rc4key, PR_TRUE);
- }
-
- if ( oldSalt ) {
- SECITEM_FreeItem(oldSalt, PR_TRUE);
- }
-
- if ( dbkey ) {
- sec_destroy_dbkey(dbkey);
- }
-
- return(SECSuccess);
-}
#define MAX_DB_SIZE 0xffff
/*
* Clear out all the keys in the existing database
*/
SECStatus
-SECKEY_ResetKeyDB(SECKEYKeyDBHandle *handle)
+nsslowkey_ResetKeyDB(NSSLOWKEYDBHandle *handle)
{
SECStatus rv;
int ret;
@@ -2478,12 +2361,3 @@ done:
return (errors == 0 ? SECSuccess : SECFailure);
}
-
-/* These functions simply return the address of the above-declared templates.
-** This is necessary for Windows DLLs. Sigh.
-*/
-SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PrivateKeyInfoTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToPrivateKeyInfoTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_EncryptedPrivateKeyInfoTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToEncryptedPrivateKeyInfoTemplate)
-
diff --git a/security/nss/lib/softoken/private.h b/security/nss/lib/softoken/keydbi.h
index 0125c7e7b..28eb962ad 100644
--- a/security/nss/lib/softoken/private.h
+++ b/security/nss/lib/softoken/keydbi.h
@@ -35,8 +35,8 @@
* $Id$
*/
-#ifndef _PRIVATE_H_
-#define _PRIVATE_H_
+#ifndef _KEYDBI_H_
+#define _KEYDBI_H_
#include "nspr.h"
#include "seccomon.h"
@@ -45,7 +45,7 @@
/*
* Handle structure for open key databases
*/
-struct SECKEYKeyDBHandleStr {
+struct NSSLOWKEYDBHandleStr {
DB *db;
DB *updatedb; /* used when updating an old version */
SECItem *global_salt; /* password hashing salt for this db */
@@ -60,7 +60,7 @@ struct SECKEYKeyDBHandleStr {
** "data" is the key data
** "pdata" is the user's data
*/
-typedef SECStatus (* SECKEYTraverseKeysFunc)(DBT *key, DBT *data, void *pdata);
+typedef SECStatus (* NSSLOWKEYTraverseKeysFunc)(DBT *key, DBT *data, void *pdata);
SEC_BEGIN_PROTOS
@@ -71,10 +71,10 @@ SEC_BEGIN_PROTOS
** "f" is the user function to call for each key
** "udata" is the user's data, which is passed through to "f"
*/
-extern SECStatus SECKEY_TraverseKeys(SECKEYKeyDBHandle *handle,
- SECKEYTraverseKeysFunc f,
+extern SECStatus NSSLOWKEY_TraverseKeys(NSSLOWKEYDBHandle *handle,
+ NSSLOWKEYTraverseKeysFunc f,
void *udata);
SEC_END_PROTOS
-#endif /* _PRIVATE_H_ */
+#endif /* _KEYDBI_H_ */
diff --git a/security/nss/lib/softoken/keydbt.h b/security/nss/lib/softoken/keydbt.h
deleted file mode 100644
index 5cb574b47..000000000
--- a/security/nss/lib/softoken/keydbt.h
+++ /dev/null
@@ -1,88 +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.
- *
- * keydbt.h - private data structures for the private key library
- *
- * $Id$
- */
-
-#ifndef _KEYDBT_H_
-#define _KEYDBT_H_
-
-#include "prtypes.h"
-#include "plarena.h"
-#include "secitem.h"
-#include "secasn1t.h"
-#include "secmodt.h"
-#include "pkcs11t.h"
-
-
-/*
- * a key in/for the data base
- */
-struct SECKEYDBKeyStr {
- PLArenaPool *arena;
- int version;
- char *nickname;
- SECItem salt;
- SECItem derPK;
-};
-typedef struct SECKEYDBKeyStr SECKEYDBKey;
-
-typedef struct SECKEYKeyDBHandleStr SECKEYKeyDBHandle;
-
-#define PRIVATE_KEY_DB_FILE_VERSION 3
-
-#define SEC_PRIVATE_KEY_VERSION 0 /* what we *create* */
-
-/*
-** Typedef for callback to get a password "key".
-*/
-typedef SECItem * (* SECKEYLowGetPasswordKey)(void *arg,
- SECKEYKeyDBHandle *handle);
-
-extern const SEC_ASN1Template SECKEY_LowPQGParamsTemplate[];
-extern const SEC_ASN1Template SECKEY_LowRSAPrivateKeyTemplate[];
-extern const SEC_ASN1Template SECKEY_LowDSAPrivateKeyTemplate[];
-extern const SEC_ASN1Template SECKEY_LowDSAPrivateKeyExportTemplate[];
-extern const SEC_ASN1Template SECKEY_LowDHPrivateKeyTemplate[];
-extern const SEC_ASN1Template SECKEY_LowDHPrivateKeyExportTemplate[];
-
-extern const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[];
-extern const SEC_ASN1Template SECKEY_AttributeTemplate[];
-
-/* These functions simply return the address of the above-declared templates.
-** This is necessary for Windows DLLs. Sigh.
-*/
-extern SEC_ASN1TemplateChooser NSS_Get_SECKEY_EncryptedPrivateKeyInfoTemplate;
-
-#endif /* _KEYDBT_H_ */
diff --git a/security/nss/lib/softoken/keytboth.h b/security/nss/lib/softoken/keytboth.h
deleted file mode 100644
index 0e4816cb6..000000000
--- a/security/nss/lib/softoken/keytboth.h
+++ /dev/null
@@ -1,71 +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.
- */
-#ifndef _KEYTBOTH_H_
-#define _KEYTBOTH_H_ 1
-
-#include "blapit.h"
-#include "secoidt.h"
-
-/*
-** Attributes
-*/
-struct SECKEYAttributeStr {
- SECItem attrType;
- SECItem **attrValue;
-};
-typedef struct SECKEYAttributeStr SECKEYAttribute;
-
-/*
-** A PKCS#8 private key info object
-*/
-struct PrivateKeyInfoStr {
- PLArenaPool *arena;
- SECItem version;
- SECAlgorithmID algorithm;
- SECItem privateKey;
- SECKEYAttribute **attributes;
-};
-typedef struct PrivateKeyInfoStr PrivateKeyInfo;
-#define SEC_PRIVATE_KEY_INFO_VERSION 0 /* what we *create* */
-
-/*
-** A PKCS#8 private key info object
-*/
-struct EncryptedPrivateKeyInfoStr {
- PLArenaPool *arena;
- SECAlgorithmID algorithm;
- SECItem encryptedData;
-};
-typedef struct EncryptedPrivateKeyInfoStr EncryptedPrivateKeyInfo;
-
-#endif /* _KEYT_H_ */
diff --git a/security/nss/lib/softoken/keytlow.h b/security/nss/lib/softoken/keytlow.h
deleted file mode 100644
index 3c0c55ab0..000000000
--- a/security/nss/lib/softoken/keytlow.h
+++ /dev/null
@@ -1,75 +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.
- */
-#ifndef _KEYTLOW_H_
-#define _KEYTLOW_H_ 1
-
-#include "blapit.h"
-
-typedef enum {
- lowNullKey = 0,
- lowRSAKey = 1,
- lowDSAKey = 2,
- lowDHKey = 4
-} LowKeyType;
-
-/*
-** An RSA public key object.
-*/
-struct SECKEYLowPublicKeyStr {
- PLArenaPool *arena;
- LowKeyType keyType ;
- union {
- RSAPublicKey rsa;
- DSAPublicKey dsa;
- DHPublicKey dh;
- } u;
-};
-typedef struct SECKEYLowPublicKeyStr SECKEYLowPublicKey;
-
-/*
-** Low Level private key object
-** This is only used by the raw Crypto engines (crypto), keydb (keydb),
-** and PKCS #11. Everyone else uses the high level key structure.
-*/
-struct SECKEYLowPrivateKeyStr {
- PLArenaPool *arena;
- LowKeyType keyType;
- union {
- RSAPrivateKey rsa;
- DSAPrivateKey dsa;
- DHPrivateKey dh;
- } u;
-};
-typedef struct SECKEYLowPrivateKeyStr SECKEYLowPrivateKey;
-
-#endif /* _KEYTLOW_H_ */
diff --git a/security/nss/lib/softoken/lowcert.c b/security/nss/lib/softoken/lowcert.c
new file mode 100644
index 000000000..0cea4e396
--- /dev/null
+++ b/security/nss/lib/softoken/lowcert.c
@@ -0,0 +1,525 @@
+/*
+ * 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.
+ */
+
+/*
+ * Certificate handling code
+ *
+ * $Id$
+ */
+
+#include "seccomon.h"
+#include "secder.h"
+#include "nssilock.h"
+#include "prmon.h"
+#include "prtime.h"
+#include "lowkeyi.h"
+#include "pcert.h"
+#include "secasn1.h"
+#include "secoid.h"
+
+/* should have been in a 'util' header */
+extern const SEC_ASN1Template CERT_ValidityTemplate[];
+
+static const SEC_ASN1Template nsslowcert_CertKeyTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(NSSLOWCERTCertKey) },
+ { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
+ SEC_ASN1_CONTEXT_SPECIFIC | 0, 0, SEC_SkipTemplate }, /* version */
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWCERTCertKey,serialNumber) },
+ { SEC_ASN1_SKIP }, /* signature algorithm */
+ { SEC_ASN1_ANY, offsetof(NSSLOWCERTCertKey,derIssuer) },
+ { SEC_ASN1_SKIP_REST },
+ { 0 }
+};
+
+const SEC_ASN1Template nsslowcert_SubjectPublicKeyInfoTemplate[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWCERTSubjectPublicKeyInfo) },
+ { SEC_ASN1_INLINE, offsetof(NSSLOWCERTSubjectPublicKeyInfo,algorithm),
+ SECOID_AlgorithmIDTemplate },
+ { SEC_ASN1_BIT_STRING,
+ offsetof(NSSLOWCERTSubjectPublicKeyInfo,subjectPublicKey), },
+ { 0, }
+};
+
+const SEC_ASN1Template nsslowcert_CertificateTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(NSSLOWCERTCertificate) },
+ { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
+ SEC_ASN1_CONTEXT_SPECIFIC | 0, 0, SEC_SkipTemplate }, /* version */
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWCERTCertificate,serialNumber) },
+ { SEC_ASN1_SKIP }, /* Signature algorithm */
+ { SEC_ASN1_ANY, offsetof(NSSLOWCERTCertificate,derIssuer) },
+ { SEC_ASN1_INLINE,
+ offsetof(NSSLOWCERTCertificate,validity),
+ CERT_ValidityTemplate },
+ { SEC_ASN1_ANY, offsetof(NSSLOWCERTCertificate,derSubject) },
+ { SEC_ASN1_INLINE,
+ offsetof(NSSLOWCERTCertificate,subjectPublicKeyInfo),
+ nsslowcert_SubjectPublicKeyInfoTemplate },
+ { SEC_ASN1_SKIP_REST },
+ { 0 }
+};
+const SEC_ASN1Template nsslowcert_SignedCertificateTemplate[] =
+{
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWCERTCertificate) },
+ { SEC_ASN1_INLINE, 0, nsslowcert_CertificateTemplate },
+ { SEC_ASN1_SKIP_REST },
+ { 0 }
+};
+const SEC_ASN1Template nsslowcert_SignedDataTemplate[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWCERTSignedData) },
+ { SEC_ASN1_ANY, offsetof(NSSLOWCERTSignedData,data), },
+ { SEC_ASN1_SKIP_REST },
+ { 0, }
+};
+const SEC_ASN1Template nsslowcert_RSAPublicKeyTemplate[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPublicKey) },
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey,u.rsa.modulus), },
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey,u.rsa.publicExponent), },
+ { 0, }
+};
+const SEC_ASN1Template nsslowcert_DSAPublicKeyTemplate[] = {
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey,u.dsa.publicValue), },
+ { 0, }
+};
+const SEC_ASN1Template nsslowcert_DHPublicKeyTemplate[] = {
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey,u.dh.publicValue), },
+ { 0, }
+};
+
+
+static PZLock *pcertRefCountLock = NULL;
+
+/*
+ * Acquire the cert reference count lock
+ * There is currently one global lock for all certs, but I'm putting a cert
+ * arg here so that it will be easy to make it per-cert in the future if
+ * that turns out to be necessary.
+ */
+void
+nsslowcert_LockCertRefCount(NSSLOWCERTCertificate *cert)
+{
+ if ( pcertRefCountLock == NULL ) {
+ nss_InitLock(&pcertRefCountLock, nssILockRefLock);
+ PORT_Assert(pcertRefCountLock != NULL);
+ }
+
+ PZ_Lock(pcertRefCountLock);
+ return;
+}
+
+/*
+ * Free the cert reference count lock
+ */
+void
+nsslowcert_UnlockCertRefCount(NSSLOWCERTCertificate *cert)
+{
+ PRStatus prstat;
+
+ PORT_Assert(pcertRefCountLock != NULL);
+
+ prstat = PZ_Unlock(pcertRefCountLock);
+
+ PORT_Assert(prstat == PR_SUCCESS);
+
+ return;
+}
+
+
+NSSLOWCERTCertificate *
+nsslowcert_DupCertificate(NSSLOWCERTCertificate *c)
+{
+ if (c) {
+ nsslowcert_LockCertRefCount(c);
+ ++c->referenceCount;
+ nsslowcert_UnlockCertRefCount(c);
+ }
+ return c;
+}
+
+/*
+ * Allow use of default cert database, so that apps(such as mozilla) don't
+ * have to pass the handle all over the place.
+ */
+static NSSLOWCERTCertDBHandle *default_pcert_db_handle = 0;
+
+void
+nsslowcert_SetDefaultCertDB(NSSLOWCERTCertDBHandle *handle)
+{
+ default_pcert_db_handle = handle;
+
+ return;
+}
+
+NSSLOWCERTCertDBHandle *
+nsslowcert_GetDefaultCertDB(void)
+{
+ return(default_pcert_db_handle);
+}
+
+
+SECStatus
+nsslowcert_GetCertTimes(NSSLOWCERTCertificate *c, PRTime *notBefore, PRTime *notAfter)
+{
+ int rv;
+
+ /* convert DER not-before time */
+ rv = DER_UTCTimeToTime(notBefore, &c->validity.notBefore);
+ if (rv) {
+ return(SECFailure);
+ }
+
+ /* convert DER not-after time */
+ rv = DER_UTCTimeToTime(notAfter, &c->validity.notAfter);
+ if (rv) {
+ return(SECFailure);
+ }
+
+ return(SECSuccess);
+}
+
+/*
+ * is certa newer than certb? If one is expired, pick the other one.
+ */
+PRBool
+nsslowcert_IsNewer(NSSLOWCERTCertificate *certa, NSSLOWCERTCertificate *certb)
+{
+ PRTime notBeforeA, notAfterA, notBeforeB, notAfterB, now;
+ SECStatus rv;
+ PRBool newerbefore, newerafter;
+
+ rv = nsslowcert_GetCertTimes(certa, &notBeforeA, &notAfterA);
+ if ( rv != SECSuccess ) {
+ return(PR_FALSE);
+ }
+
+ rv = nsslowcert_GetCertTimes(certb, &notBeforeB, &notAfterB);
+ if ( rv != SECSuccess ) {
+ return(PR_TRUE);
+ }
+
+ newerbefore = PR_FALSE;
+ if ( LL_CMP(notBeforeA, >, notBeforeB) ) {
+ newerbefore = PR_TRUE;
+ }
+
+ newerafter = PR_FALSE;
+ if ( LL_CMP(notAfterA, >, notAfterB) ) {
+ newerafter = PR_TRUE;
+ }
+
+ if ( newerbefore && newerafter ) {
+ return(PR_TRUE);
+ }
+
+ if ( ( !newerbefore ) && ( !newerafter ) ) {
+ return(PR_FALSE);
+ }
+
+ /* get current UTC time */
+ now = PR_Now();
+
+ if ( newerbefore ) {
+ /* cert A was issued after cert B, but expires sooner */
+ /* if A is expired, then pick B */
+ if ( LL_CMP(notAfterA, <, now ) ) {
+ return(PR_FALSE);
+ }
+ return(PR_TRUE);
+ } else {
+ /* cert B was issued after cert A, but expires sooner */
+ /* if B is expired, then pick A */
+ if ( LL_CMP(notAfterB, <, now ) ) {
+ return(PR_TRUE);
+ }
+ return(PR_FALSE);
+ }
+}
+
+#define SOFT_DEFAULT_CHUNKSIZE 2048
+
+/*
+ * take a DER certificate and decode it into a certificate structure
+ */
+NSSLOWCERTCertificate *
+nsslowcert_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
+ char *nickname)
+{
+ NSSLOWCERTCertificate *cert;
+ PRArenaPool *arena;
+ void *data;
+ int rv;
+ int len;
+
+ /* make a new arena */
+ arena = PORT_NewArena(SOFT_DEFAULT_CHUNKSIZE);
+
+ if ( !arena ) {
+ return 0;
+ }
+
+ /* allocate the certificate structure */
+ cert = (NSSLOWCERTCertificate *)PORT_ArenaZAlloc(arena, sizeof(NSSLOWCERTCertificate));
+
+ if ( !cert ) {
+ goto loser;
+ }
+
+ cert->arena = arena;
+
+ if ( copyDER ) {
+ /* copy the DER data for the cert into this arena */
+ data = (void *)PORT_ArenaAlloc(arena, derSignedCert->len);
+ if ( !data ) {
+ goto loser;
+ }
+ cert->derCert.data = (unsigned char *)data;
+ cert->derCert.len = derSignedCert->len;
+ PORT_Memcpy(data, derSignedCert->data, derSignedCert->len);
+ } else {
+ /* point to passed in DER data */
+ cert->derCert = *derSignedCert;
+ }
+
+ /* decode the certificate info */
+ rv = SEC_ASN1DecodeItem(arena, cert, nsslowcert_SignedCertificateTemplate,
+ &cert->derCert);
+
+ /* cert->subjectKeyID; x509v3 subject key identifier */
+ cert->dbEntry = NULL;
+ cert ->trust = NULL;
+
+#ifdef notdef
+ /* these fields are used by client GUI code to keep track of ssl sockets
+ * that are blocked waiting on GUI feedback related to this cert.
+ * XXX - these should be moved into some sort of application specific
+ * data structure. They are only used by the browser right now.
+ */
+ struct SECSocketNode *socketlist;
+ int socketcount;
+ struct SECSocketNode *authsocketlist;
+ int authsocketcount;
+
+ /* This is PKCS #11 stuff. */
+ PK11SlotInfo *slot; /*if this cert came of a token, which is it*/
+ CK_OBJECT_HANDLE pkcs11ID; /*and which object on that token is it */
+ PRBool ownSlot; /*true if the cert owns the slot reference */
+#endif
+
+ /* generate and save the database key for the cert */
+ rv = nsslowcert_KeyFromDERCert(arena, &cert->derCert, &cert->certKey);
+ if ( rv ) {
+ goto loser;
+ }
+
+ /* set the nickname */
+ if ( nickname == NULL ) {
+ cert->nickname = NULL;
+ } else {
+ /* copy and install the nickname */
+ len = PORT_Strlen(nickname) + 1;
+ cert->nickname = (char*)PORT_ArenaAlloc(arena, len);
+ if ( cert->nickname == NULL ) {
+ goto loser;
+ }
+
+ PORT_Memcpy(cert->nickname, nickname, len);
+ }
+
+#ifdef FIXME
+ /* initialize the subjectKeyID */
+ rv = cert_GetKeyID(cert);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ /* set the email address */
+ cert->emailAddr = CERT_GetCertificateEmailAddress(cert);
+
+#endif
+
+ cert->referenceCount = 1;
+
+ return(cert);
+
+loser:
+
+ if ( arena ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ return(0);
+}
+
+char *
+nsslowcert_FixupEmailAddr(char *emailAddr)
+{
+ char *retaddr;
+ char *str;
+
+ if ( emailAddr == NULL ) {
+ return(NULL);
+ }
+
+ /* copy the string */
+ str = retaddr = PORT_Strdup(emailAddr);
+ if ( str == NULL ) {
+ return(NULL);
+ }
+
+ /* make it lower case */
+ while ( *str ) {
+ *str = tolower( *str );
+ str++;
+ }
+
+ return(retaddr);
+}
+
+static SECStatus
+nsslowcert_KeyFromIssuerAndSN(PRArenaPool *arena, SECItem *issuer, SECItem *sn,
+ SECItem *key)
+{
+ key->len = sn->len + issuer->len;
+
+ key->data = (unsigned char*)PORT_ArenaAlloc(arena, key->len);
+ if ( !key->data ) {
+ goto loser;
+ }
+
+ /* copy the serialNumber */
+ PORT_Memcpy(key->data, sn->data, sn->len);
+
+ /* copy the issuer */
+ PORT_Memcpy(&key->data[sn->len], issuer->data, issuer->len);
+
+ return(SECSuccess);
+
+loser:
+ return(SECFailure);
+}
+
+
+
+/*
+ * Generate a database key, based on serial number and issuer, from a
+ * DER certificate.
+ */
+SECStatus
+nsslowcert_KeyFromDERCert(PRArenaPool *arena, SECItem *derCert, SECItem *key)
+{
+ int rv;
+ NSSLOWCERTSignedData sd;
+ NSSLOWCERTCertKey certkey;
+
+ PORT_Memset(&sd, 0, sizeof(NSSLOWCERTSignedData));
+ PORT_Memset(&certkey, 0, sizeof(NSSLOWCERTCertKey));
+
+ rv = SEC_ASN1DecodeItem(arena, &sd, nsslowcert_SignedDataTemplate, derCert);
+
+ if ( rv ) {
+ goto loser;
+ }
+
+ PORT_Memset(&certkey, 0, sizeof(NSSLOWCERTCertKey));
+ rv = SEC_ASN1DecodeItem(arena, &certkey,
+ nsslowcert_CertKeyTemplate, &sd.data);
+
+ if ( rv ) {
+ goto loser;
+ }
+
+ return(nsslowcert_KeyFromIssuerAndSN(arena, &certkey.derIssuer,
+ &certkey.serialNumber, key));
+loser:
+ return(SECFailure);
+}
+
+NSSLOWKEYPublicKey *
+nsslowcert_ExtractPublicKey(NSSLOWCERTCertificate *cert)
+{
+ NSSLOWCERTSubjectPublicKeyInfo *spki = &cert->subjectPublicKeyInfo;
+ NSSLOWKEYPublicKey *pubk;
+ SECItem os;
+ SECStatus rv;
+ PRArenaPool *arena;
+ SECOidTag tag;
+
+ arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);
+ if (arena == NULL)
+ return NULL;
+
+ pubk = (NSSLOWKEYPublicKey *)
+ PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYPublicKey));
+ if (pubk == NULL) {
+ PORT_FreeArena (arena, PR_FALSE);
+ return NULL;
+ }
+
+ pubk->arena = arena;
+
+ /* Convert bit string length from bits to bytes */
+ os = spki->subjectPublicKey;
+ DER_ConvertBitString (&os);
+
+ tag = SECOID_GetAlgorithmTag(&spki->algorithm);
+ switch ( tag ) {
+ case SEC_OID_X500_RSA_ENCRYPTION:
+ case SEC_OID_PKCS1_RSA_ENCRYPTION:
+ pubk->keyType = NSSLOWKEYRSAKey;
+ rv = SEC_ASN1DecodeItem(arena, pubk,
+ nsslowcert_RSAPublicKeyTemplate, &os);
+ if (rv == SECSuccess)
+ return pubk;
+ break;
+ case SEC_OID_ANSIX9_DSA_SIGNATURE:
+ pubk->keyType = NSSLOWKEYDSAKey;
+ rv = SEC_ASN1DecodeItem(arena, pubk,
+ nsslowcert_DSAPublicKeyTemplate, &os);
+ if (rv == SECSuccess) return pubk;
+ break;
+ case SEC_OID_X942_DIFFIE_HELMAN_KEY:
+ pubk->keyType = NSSLOWKEYDHKey;
+ rv = SEC_ASN1DecodeItem(arena, pubk,
+ nsslowcert_DHPublicKeyTemplate, &os);
+ if (rv == SECSuccess) return pubk;
+ break;
+ default:
+ rv = SECFailure;
+ break;
+ }
+
+ nsslowkey_DestroyPublicKey (pubk);
+ return NULL;
+}
+
diff --git a/security/nss/lib/softoken/lowkey.c b/security/nss/lib/softoken/lowkey.c
index fafbf361e..3d7cfa94a 100644
--- a/security/nss/lib/softoken/lowkey.c
+++ b/security/nss/lib/softoken/lowkey.c
@@ -30,17 +30,17 @@
* may use your version of this file under either the MPL or the
* GPL.
*/
-#include "keylow.h"
+#include "lowkeyi.h"
#include "secoid.h"
#include "secitem.h"
#include "secder.h"
#include "base64.h"
#include "secasn1.h"
-#include "cert.h"
+#include "pcert.h"
#include "secerr.h"
-const SEC_ASN1Template SECKEY_LowPQGParamsTemplate[] = {
+const SEC_ASN1Template nsslowkey_PQGParamsTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(PQGParams) },
{ SEC_ASN1_INTEGER, offsetof(PQGParams,prime) },
{ SEC_ASN1_INTEGER, offsetof(PQGParams,subPrime) },
@@ -48,43 +48,43 @@ const SEC_ASN1Template SECKEY_LowPQGParamsTemplate[] = {
{ 0, }
};
-const SEC_ASN1Template SECKEY_LowRSAPrivateKeyTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPrivateKey) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.rsa.version) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.rsa.modulus) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.rsa.publicExponent) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.rsa.privateExponent) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.rsa.prime1) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.rsa.prime2) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.rsa.exponent1) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.rsa.exponent2) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.rsa.coefficient) },
+const SEC_ASN1Template nsslowkey_RSAPrivateKeyTemplate[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.version) },
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.modulus) },
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.publicExponent) },
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.privateExponent) },
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.prime1) },
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.prime2) },
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.exponent1) },
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.exponent2) },
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.coefficient) },
{ 0 }
};
-const SEC_ASN1Template SECKEY_LowDSAPrivateKeyTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYLowPrivateKey) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.dsa.publicValue) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.dsa.privateValue) },
+const SEC_ASN1Template nsslowkey_DSAPrivateKeyTemplate[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.publicValue) },
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.privateValue) },
{ 0, }
};
-const SEC_ASN1Template SECKEY_LowDSAPrivateKeyExportTemplate[] = {
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.dsa.privateValue) },
+const SEC_ASN1Template nsslowkey_DSAPrivateKeyExportTemplate[] = {
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.privateValue) },
};
-const SEC_ASN1Template SECKEY_LowDHPrivateKeyTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYLowPrivateKey) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.dh.publicValue) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.dh.privateValue) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.dh.base) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYLowPrivateKey,u.dh.prime) },
+const SEC_ASN1Template nsslowkey_DHPrivateKeyTemplate[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.publicValue) },
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.privateValue) },
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.base) },
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.prime) },
{ 0, }
};
void
-SECKEY_LowDestroyPrivateKey(SECKEYLowPrivateKey *privk)
+nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *privk)
{
if (privk && privk->arena) {
PORT_FreeArena(privk->arena, PR_TRUE);
@@ -92,14 +92,14 @@ SECKEY_LowDestroyPrivateKey(SECKEYLowPrivateKey *privk)
}
void
-SECKEY_LowDestroyPublicKey(SECKEYLowPublicKey *pubk)
+nsslowkey_DestroyPublicKey(NSSLOWKEYPublicKey *pubk)
{
if (pubk && pubk->arena) {
PORT_FreeArena(pubk->arena, PR_FALSE);
}
}
unsigned
-SECKEY_LowPublicModulusLen(SECKEYLowPublicKey *pubk)
+nsslowkey_PublicModulusLen(NSSLOWKEYPublicKey *pubk)
{
unsigned char b0;
@@ -107,7 +107,7 @@ SECKEY_LowPublicModulusLen(SECKEYLowPublicKey *pubk)
* fortezza that's the public key length */
switch (pubk->keyType) {
- case lowRSAKey:
+ case NSSLOWKEYRSAKey:
b0 = pubk->u.rsa.modulus.data[0];
return b0 ? pubk->u.rsa.modulus.len : pubk->u.rsa.modulus.len - 1;
default:
@@ -117,13 +117,13 @@ SECKEY_LowPublicModulusLen(SECKEYLowPublicKey *pubk)
}
unsigned
-SECKEY_LowPrivateModulusLen(SECKEYLowPrivateKey *privk)
+nsslowkey_PrivateModulusLen(NSSLOWKEYPrivateKey *privk)
{
unsigned char b0;
switch (privk->keyType) {
- case lowRSAKey:
+ case NSSLOWKEYRSAKey:
b0 = privk->u.rsa.modulus.data[0];
return b0 ? privk->u.rsa.modulus.len : privk->u.rsa.modulus.len - 1;
default:
@@ -132,10 +132,10 @@ SECKEY_LowPrivateModulusLen(SECKEYLowPrivateKey *privk)
return 0;
}
-SECKEYLowPublicKey *
-SECKEY_LowConvertToPublicKey(SECKEYLowPrivateKey *privk)
+NSSLOWKEYPublicKey *
+nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk)
{
- SECKEYLowPublicKey *pubk;
+ NSSLOWKEYPublicKey *pubk;
PLArenaPool *arena;
@@ -146,16 +146,16 @@ SECKEY_LowConvertToPublicKey(SECKEYLowPrivateKey *privk)
}
switch(privk->keyType) {
- case lowRSAKey:
- case nullKey:
- pubk = (SECKEYLowPublicKey *)PORT_ArenaZAlloc(arena,
- sizeof (SECKEYLowPublicKey));
+ case NSSLOWKEYRSAKey:
+ case NSSLOWKEYNullKey:
+ pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
+ sizeof (NSSLOWKEYPublicKey));
if (pubk != NULL) {
SECStatus rv;
pubk->arena = arena;
pubk->keyType = privk->keyType;
- if (privk->keyType == nullKey) return pubk;
+ if (privk->keyType == NSSLOWKEYNullKey) return pubk;
rv = SECITEM_CopyItem(arena, &pubk->u.rsa.modulus,
&privk->u.rsa.modulus);
if (rv == SECSuccess) {
@@ -164,14 +164,14 @@ SECKEY_LowConvertToPublicKey(SECKEYLowPrivateKey *privk)
if (rv == SECSuccess)
return pubk;
}
- SECKEY_LowDestroyPublicKey (pubk);
+ nsslowkey_DestroyPublicKey (pubk);
} else {
PORT_SetError (SEC_ERROR_NO_MEMORY);
}
break;
- case lowDSAKey:
- pubk = (SECKEYLowPublicKey *)PORT_ArenaZAlloc(arena,
- sizeof(SECKEYLowPublicKey));
+ case NSSLOWKEYDSAKey:
+ pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
+ sizeof(NSSLOWKEYPublicKey));
if (pubk != NULL) {
SECStatus rv;
@@ -191,9 +191,9 @@ SECKEY_LowConvertToPublicKey(SECKEYLowPrivateKey *privk)
if (rv == SECSuccess) return pubk;
}
break;
- case lowDHKey:
- pubk = (SECKEYLowPublicKey *)PORT_ArenaZAlloc(arena,
- sizeof(SECKEYLowPublicKey));
+ case NSSLOWKEYDHKey:
+ pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
+ sizeof(NSSLOWKEYPublicKey));
if (pubk != NULL) {
SECStatus rv;
@@ -220,10 +220,10 @@ SECKEY_LowConvertToPublicKey(SECKEYLowPrivateKey *privk)
return NULL;
}
-SECKEYLowPrivateKey *
-SECKEY_CopyLowPrivateKey(SECKEYLowPrivateKey *privKey)
+NSSLOWKEYPrivateKey *
+nsslowkey_CopyPrivateKey(NSSLOWKEYPrivateKey *privKey)
{
- SECKEYLowPrivateKey *returnKey = NULL;
+ NSSLOWKEYPrivateKey *returnKey = NULL;
SECStatus rv = SECFailure;
PLArenaPool *poolp;
@@ -236,7 +236,7 @@ SECKEY_CopyLowPrivateKey(SECKEYLowPrivateKey *privKey)
return NULL;
}
- returnKey = (SECKEYLowPrivateKey*)PORT_ArenaZAlloc(poolp, sizeof(SECKEYLowPrivateKey));
+ returnKey = (NSSLOWKEYPrivateKey*)PORT_ArenaZAlloc(poolp, sizeof(NSSLOWKEYPrivateKey));
if(!returnKey) {
rv = SECFailure;
goto loser;
@@ -246,7 +246,7 @@ SECKEY_CopyLowPrivateKey(SECKEYLowPrivateKey *privKey)
returnKey->arena = poolp;
switch(privKey->keyType) {
- case lowRSAKey:
+ case NSSLOWKEYRSAKey:
rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.modulus),
&(privKey->u.rsa.modulus));
if(rv != SECSuccess) break;
@@ -275,7 +275,7 @@ SECKEY_CopyLowPrivateKey(SECKEYLowPrivateKey *privKey)
&(privKey->u.rsa.coefficient));
if(rv != SECSuccess) break;
break;
- case lowDSAKey:
+ case NSSLOWKEYDSAKey:
rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.publicValue),
&(privKey->u.dsa.publicValue));
if(rv != SECSuccess) break;
@@ -293,7 +293,7 @@ SECKEY_CopyLowPrivateKey(SECKEYLowPrivateKey *privKey)
&(privKey->u.dsa.params.base));
if(rv != SECSuccess) break;
break;
- case lowDHKey:
+ case NSSLOWKEYDHKey:
rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.publicValue),
&(privKey->u.dh.publicValue));
if(rv != SECSuccess) break;
diff --git a/security/nss/lib/softoken/keylow.h b/security/nss/lib/softoken/lowkeyi.h
index 3c7679b3a..0a58b1fa3 100644
--- a/security/nss/lib/softoken/keylow.h
+++ b/security/nss/lib/softoken/lowkeyi.h
@@ -35,65 +35,64 @@
* $Id$
*/
-#ifndef _KEYLOW_H_
-#define _KEYLOW_H_
+#ifndef _LOWKEYI_H_
+#define _LOWKEYI_H_
#include "prtypes.h"
#include "seccomon.h"
-#include "keydbt.h"
#include "secoidt.h"
-#include "certt.h"
-#include "keytlow.h"
+#include "pcertt.h"
+#include "lowkeyti.h"
SEC_BEGIN_PROTOS
-typedef char * (* SECKEYDBNameFunc)(void *arg, int dbVersion);
+typedef char * (* NSSLOWKEYDBNameFunc)(void *arg, int dbVersion);
/*
** Open a key database.
*/
-extern SECKEYKeyDBHandle *SECKEY_OpenKeyDB(PRBool readOnly,
- SECKEYDBNameFunc namecb,
+extern NSSLOWKEYDBHandle *nsslowkey_OpenKeyDB(PRBool readOnly,
+ NSSLOWKEYDBNameFunc namecb,
void *cbarg);
-extern SECKEYKeyDBHandle *SECKEY_OpenKeyDBFilename(char *filename,
+extern NSSLOWKEYDBHandle *nsslowkey_OpenKeyDBFilename(char *filename,
PRBool readOnly);
/*
** Update the database
*/
-extern SECStatus SECKEY_UpdateKeyDBPass1(SECKEYKeyDBHandle *handle);
-extern SECStatus SECKEY_UpdateKeyDBPass2(SECKEYKeyDBHandle *handle,
+extern SECStatus nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle);
+extern SECStatus nsslowkey_UpdateKeyDBPass2(NSSLOWKEYDBHandle *handle,
SECItem *pwitem);
/*
* Clear out all the keys in the existing database
*/
-extern SECStatus SECKEY_ResetKeyDB(SECKEYKeyDBHandle *handle);
+extern SECStatus nsslowkey_ResetKeyDB(NSSLOWKEYDBHandle *handle);
/*
** Close the specified key database.
*/
-extern void SECKEY_CloseKeyDB(SECKEYKeyDBHandle *handle);
+extern void nsslowkey_CloseKeyDB(NSSLOWKEYDBHandle *handle);
/*
* Get the version number of the database
*/
-extern int SECKEY_GetKeyDBVersion(SECKEYKeyDBHandle *handle);
+extern int nsslowkey_GetKeyDBVersion(NSSLOWKEYDBHandle *handle);
/*
** Support a default key database.
*/
-extern void SECKEY_SetDefaultKeyDB(SECKEYKeyDBHandle *handle);
-extern SECKEYKeyDBHandle *SECKEY_GetDefaultKeyDB(void);
+extern void nsslowkey_SetDefaultKeyDB(NSSLOWKEYDBHandle *handle);
+extern NSSLOWKEYDBHandle *nsslowkey_GetDefaultKeyDB(void);
/* set the alg id of the key encryption algorithm */
-extern void SECKEY_SetDefaultKeyDBAlg(SECOidTag alg);
+extern void nsslowkey_SetDefaultKeyDBAlg(SECOidTag alg);
/*
* given a password and salt, produce a hash of the password
*/
-extern SECItem *SECKEY_HashPassword(char *pw, SECItem *salt);
+extern SECItem *nsslowkey_HashPassword(char *pw, SECItem *salt);
/*
* Derive the actual password value for a key database from the
@@ -101,12 +100,12 @@ extern SECItem *SECKEY_HashPassword(char *pw, SECItem *salt);
* stored in the key database.
*/
extern SECItem *
-SECKEY_DeriveKeyDBPassword(SECKEYKeyDBHandle *handle, char *pw);
+nsslowkey_DeriveKeyDBPassword(NSSLOWKEYDBHandle *handle, char *pw);
/*
** Delete a key from the database
*/
-extern SECStatus SECKEY_DeleteKey(SECKEYKeyDBHandle *handle,
+extern SECStatus nsslowkey_DeleteKey(NSSLOWKEYDBHandle *handle,
SECItem *pubkey);
/*
@@ -115,27 +114,22 @@ extern SECStatus SECKEY_DeleteKey(SECKEYKeyDBHandle *handle,
** "f" is a the callback function for getting the password
** "arg" is the argument for the callback
*/
-extern SECStatus SECKEY_StoreKeyByPublicKey(SECKEYKeyDBHandle *handle,
- SECKEYLowPrivateKey *pk,
+extern SECStatus nsslowkey_StoreKeyByPublicKey(NSSLOWKEYDBHandle *handle,
+ NSSLOWKEYPrivateKey *pk,
SECItem *pubKeyData,
char *nickname,
- SECKEYLowGetPasswordKey f,
- void *arg);
+ SECItem *arg);
/* does the key for this cert exist in the database filed by modulus */
-extern SECStatus SECKEY_KeyForCertExists(SECKEYKeyDBHandle *handle,
- CERTCertificate *cert);
+extern PRBool nsslowkey_KeyForCertExists(NSSLOWKEYDBHandle *handle,
+ NSSLOWCERTCertificate *cert);
-SECKEYLowPrivateKey *
-SECKEY_FindKeyByCert(SECKEYKeyDBHandle *handle, CERTCertificate *cert,
- SECKEYLowGetPasswordKey f, void *arg);
-
-extern SECStatus SECKEY_HasKeyDBPassword(SECKEYKeyDBHandle *handle);
-extern SECStatus SECKEY_SetKeyDBPassword(SECKEYKeyDBHandle *handle,
+extern SECStatus nsslowkey_HasKeyDBPassword(NSSLOWKEYDBHandle *handle);
+extern SECStatus nsslowkey_SetKeyDBPassword(NSSLOWKEYDBHandle *handle,
SECItem *pwitem);
-extern SECStatus SECKEY_CheckKeyDBPassword(SECKEYKeyDBHandle *handle,
+extern SECStatus nsslowkey_CheckKeyDBPassword(NSSLOWKEYDBHandle *handle,
SECItem *pwitem);
-extern SECStatus SECKEY_ChangeKeyDBPassword(SECKEYKeyDBHandle *handle,
+extern SECStatus nsslowkey_ChangeKeyDBPassword(NSSLOWKEYDBHandle *handle,
SECItem *oldpwitem,
SECItem *newpwitem);
@@ -144,32 +138,32 @@ extern SECStatus SECKEY_ChangeKeyDBPassword(SECKEYKeyDBHandle *handle,
** "key" the object
** "freeit" if PR_TRUE then free the object as well as its sub-objects
*/
-extern void SECKEY_LowDestroyPrivateKey(SECKEYLowPrivateKey *key);
+extern void nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *key);
/*
** Destroy a public key object.
** "key" the object
** "freeit" if PR_TRUE then free the object as well as its sub-objects
*/
-extern void SECKEY_LowDestroyPublicKey(SECKEYLowPublicKey *key);
+extern void nsslowkey_DestroyPublicKey(NSSLOWKEYPublicKey *key);
/*
** Return the modulus length of "pubKey".
*/
-extern unsigned int SECKEY_LowPublicModulusLen(SECKEYLowPublicKey *pubKey);
+extern unsigned int nsslowkey_PublicModulusLen(NSSLOWKEYPublicKey *pubKey);
/*
** Return the modulus length of "privKey".
*/
-extern unsigned int SECKEY_LowPrivateModulusLen(SECKEYLowPrivateKey *privKey);
+extern unsigned int nsslowkey_PrivateModulusLen(NSSLOWKEYPrivateKey *privKey);
/*
** Convert a low private key "privateKey" into a public low key
*/
-extern SECKEYLowPublicKey
- *SECKEY_LowConvertToPublicKey(SECKEYLowPrivateKey *privateKey);
+extern NSSLOWKEYPublicKey
+ *nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privateKey);
/*
* Set the Key Database password.
@@ -181,7 +175,7 @@ extern SECKEYLowPublicKey
* returned.
*/
extern SECStatus
-SECKEY_SetKeyDBPasswordAlg(SECKEYKeyDBHandle *handle,
+nsslowkey_SetKeyDBPasswordAlg(NSSLOWKEYDBHandle *handle,
SECItem *pwitem,
SECOidTag algorithm);
@@ -194,7 +188,7 @@ SECKEY_SetKeyDBPasswordAlg(SECKEYKeyDBHandle *handle,
* actual password. If it is not, SECFailure is returned.
*/
extern SECStatus
-SECKEY_CheckKeyDBPasswordAlg(SECKEYKeyDBHandle *handle,
+nsslowkey_CheckKeyDBPasswordAlg(NSSLOWKEYDBHandle *handle,
SECItem *pwitem,
SECOidTag algorithm);
@@ -210,7 +204,7 @@ SECKEY_CheckKeyDBPasswordAlg(SECKEYKeyDBHandle *handle,
* A return of anything but SECSuccess indicates failure.
*/
extern SECStatus
-SECKEY_ChangeKeyDBPasswordAlg(SECKEYKeyDBHandle *handle,
+nsslowkey_ChangeKeyDBPasswordAlg(NSSLOWKEYDBHandle *handle,
SECItem *oldpwitem, SECItem *newpwitem,
SECOidTag old_algorithm);
@@ -223,11 +217,11 @@ SECKEY_ChangeKeyDBPasswordAlg(SECKEYKeyDBHandle *handle,
* A return of anything but SECSuccess indicates failure.
*/
extern SECStatus
-SECKEY_StoreKeyByPublicKeyAlg(SECKEYKeyDBHandle *handle,
- SECKEYLowPrivateKey *privkey,
+nsslowkey_StoreKeyByPublicKeyAlg(NSSLOWKEYDBHandle *handle,
+ NSSLOWKEYPrivateKey *privkey,
SECItem *pubKeyData,
char *nickname,
- SECKEYLowGetPasswordKey f, void *arg,
+ SECItem *arg,
SECOidTag algorithm);
/* Find key by modulus. This function is the inverse of store key
@@ -236,17 +230,17 @@ SECKEY_StoreKeyByPublicKeyAlg(SECKEYKeyDBHandle *handle,
* else NULL is returned.
* modulus is the modulus to locate
*/
-extern SECKEYLowPrivateKey *
-SECKEY_FindKeyByPublicKey(SECKEYKeyDBHandle *handle, SECItem *modulus,
- SECKEYLowGetPasswordKey f, void *arg);
+extern NSSLOWKEYPrivateKey *
+nsslowkey_FindKeyByPublicKey(NSSLOWKEYDBHandle *handle, SECItem *modulus,
+ SECItem *arg);
/* Make a copy of a low private key in it's own arena.
* a return of NULL indicates an error.
*/
-extern SECKEYLowPrivateKey *
-SECKEY_CopyLowPrivateKey(SECKEYLowPrivateKey *privKey);
+extern NSSLOWKEYPrivateKey *
+nsslowkey_CopyPrivateKey(NSSLOWKEYPrivateKey *privKey);
SEC_END_PROTOS
-#endif /* _KEYLOW_H_ */
+#endif /* _LOWKEYI_H_ */
diff --git a/security/nss/lib/softoken/lowkeyti.h b/security/nss/lib/softoken/lowkeyti.h
new file mode 100644
index 000000000..b8941bb0d
--- /dev/null
+++ b/security/nss/lib/softoken/lowkeyti.h
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ */
+#ifndef _LOWKEYTI_H_
+#define _LOWKEYTI_H_ 1
+
+#include "blapit.h"
+#include "prtypes.h"
+#include "plarena.h"
+#include "secitem.h"
+#include "secasn1t.h"
+#include "secoidt.h"
+/*#include "secmodt.h"
+#include "pkcs11t.h" */
+
+
+/*
+ * a key in/for the data base
+ */
+struct NSSLOWKEYDBKeyStr {
+ PLArenaPool *arena;
+ int version;
+ char *nickname;
+ SECItem salt;
+ SECItem derPK;
+};
+typedef struct NSSLOWKEYDBKeyStr NSSLOWKEYDBKey;
+
+typedef struct NSSLOWKEYDBHandleStr NSSLOWKEYDBHandle;
+
+#define NSSLOWKEY_DB_FILE_VERSION 3
+
+#define NSSLOWKEY_VERSION 0 /* what we *create* */
+
+/*
+** Typedef for callback to get a password "key".
+*/
+extern const SEC_ASN1Template nsslowkey_PQGParamsTemplate[];
+extern const SEC_ASN1Template nsslowkey_RSAPrivateKeyTemplate[];
+extern const SEC_ASN1Template nsslowkey_DSAPrivateKeyTemplate[];
+extern const SEC_ASN1Template nsslowkey_DSAPrivateKeyExportTemplate[];
+extern const SEC_ASN1Template nsslowkey_DHPrivateKeyTemplate[];
+extern const SEC_ASN1Template nsslowkey_DHPrivateKeyExportTemplate[];
+
+extern const SEC_ASN1Template nsslowkey_PrivateKeyInfoTemplate[];
+extern const SEC_ASN1Template nsslowkey_EncryptedPrivateKeyInfoTemplate[];
+
+
+/*
+** A PKCS#8 private key info object
+*/
+struct NSSLOWKEYPrivateKeyInfoStr {
+ PLArenaPool *arena;
+ SECItem version;
+ SECAlgorithmID algorithm;
+ SECItem privateKey;
+};
+typedef struct NSSLOWKEYPrivateKeyInfoStr NSSLOWKEYPrivateKeyInfo;
+#define NSSLOWKEY_PRIVATE_KEY_INFO_VERSION 0 /* what we *create* */
+
+/*
+** A PKCS#8 private key info object
+*/
+struct NSSLOWKEYEncryptedPrivateKeyInfoStr {
+ PLArenaPool *arena;
+ SECAlgorithmID algorithm;
+ SECItem encryptedData;
+};
+typedef struct NSSLOWKEYEncryptedPrivateKeyInfoStr NSSLOWKEYEncryptedPrivateKeyInfo;
+
+
+typedef enum {
+ NSSLOWKEYNullKey = 0,
+ NSSLOWKEYRSAKey = 1,
+ NSSLOWKEYDSAKey = 2,
+ NSSLOWKEYDHKey = 4
+} NSSLOWKEYType;
+
+/*
+** An RSA public key object.
+*/
+struct NSSLOWKEYPublicKeyStr {
+ PLArenaPool *arena;
+ NSSLOWKEYType keyType ;
+ union {
+ RSAPublicKey rsa;
+ DSAPublicKey dsa;
+ DHPublicKey dh;
+ } u;
+};
+typedef struct NSSLOWKEYPublicKeyStr NSSLOWKEYPublicKey;
+
+/*
+** Low Level private key object
+** This is only used by the raw Crypto engines (crypto), keydb (keydb),
+** and PKCS #11. Everyone else uses the high level key structure.
+*/
+struct NSSLOWKEYPrivateKeyStr {
+ PLArenaPool *arena;
+ NSSLOWKEYType keyType;
+ union {
+ RSAPrivateKey rsa;
+ DSAPrivateKey dsa;
+ DHPrivateKey dh;
+ } u;
+};
+typedef struct NSSLOWKEYPrivateKeyStr NSSLOWKEYPrivateKey;
+
+#endif /* _LOWKEYTI_H_ */
diff --git a/security/nss/lib/softoken/lowpbe.c b/security/nss/lib/softoken/lowpbe.c
new file mode 100644
index 000000000..cac83b90c
--- /dev/null
+++ b/security/nss/lib/softoken/lowpbe.c
@@ -0,0 +1,1184 @@
+/*
+ * 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.
+ */
+
+#include "plarena.h"
+
+#include "seccomon.h"
+#include "secitem.h"
+#include "secport.h"
+#include "hasht.h"
+#include "pkcs11t.h"
+#include "blapi.h"
+#include "hasht.h"
+#include "secasn1.h"
+#include "secder.h"
+#include "lowpbe.h"
+#include "secoid.h"
+#include "alghmac.h"
+#include "softoken.h"
+#include "secerr.h"
+
+/* template for PKCS 5 PBE Parameter. This template has been expanded
+ * based upon the additions in PKCS 12. This should eventually be moved
+ * if RSA updates PKCS 5.
+ */
+static const SEC_ASN1Template NSSPKCS5PBEParameterTemplate[] =
+{
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(NSSPKCS5PBEParameter) },
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(NSSPKCS5PBEParameter, salt) },
+ { SEC_ASN1_INTEGER,
+ offsetof(NSSPKCS5PBEParameter, iteration) },
+ { 0 }
+};
+
+static const SEC_ASN1Template NSSPKCS5PKCS12V2PBEParameterTemplate[] =
+{
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSPKCS5PBEParameter) },
+ { SEC_ASN1_OCTET_STRING, offsetof(NSSPKCS5PBEParameter, salt) },
+ { SEC_ASN1_INTEGER, offsetof(NSSPKCS5PBEParameter, iteration) },
+ { 0 }
+};
+
+SECStatus
+nsspkcs5_HashBuf(const SECHashObject *hashObj, unsigned char *dest,
+ unsigned char *src, int len)
+{
+ void *ctx;
+ unsigned int retLen;
+
+ ctx = hashObj->create();
+ if(ctx == NULL) {
+ return SECFailure;
+ }
+ hashObj->begin(ctx);
+ hashObj->update(ctx, src, len);
+ hashObj->end(ctx, dest, &retLen, hashObj->length);
+ hashObj->destroy(ctx, PR_TRUE);
+ return SECSuccess;
+}
+
+/* generate bits using any hash
+ */
+static SECItem *
+nsspkcs5_PBKDF1(const SECHashObject *hashObj, SECItem *salt, SECItem *pwd,
+ int iter, PRBool faulty3DES)
+{
+ SECItem *hash = NULL, *pre_hash = NULL;
+ SECStatus rv = SECFailure;
+
+ if((salt == NULL) || (pwd == NULL) || (iter < 0)) {
+ return NULL;
+ }
+
+ hash = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
+ pre_hash = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
+
+ if((hash != NULL) && (pre_hash != NULL)) {
+ int i, ph_len;
+
+ ph_len = hashObj->length;
+ if((salt->len + pwd->len) > hashObj->length) {
+ ph_len = salt->len + pwd->len;
+ }
+
+ rv = SECFailure;
+
+ /* allocate buffers */
+ hash->data = (unsigned char *)PORT_ZAlloc(SHA1_LENGTH);
+ hash->len = hashObj->length;
+ pre_hash->data = (unsigned char *)PORT_ZAlloc(ph_len);
+
+ /* in pbeSHA1TripleDESCBC there was an allocation error that made
+ * it into the caller. We do not want to propagate those errors
+ * further, so we are doing it correctly, but reading the old method.
+ */
+ if (faulty3DES) {
+ pre_hash->len = ph_len;
+ } else {
+ pre_hash->len = salt->len + pwd->len;
+ }
+
+ /* preform hash */
+ if ((hash->data != NULL) && (pre_hash->data != NULL)) {
+ rv = SECSuccess;
+ /* check for 0 length password */
+ if(pwd->len > 0) {
+ PORT_Memcpy(pre_hash->data, pwd->data, pwd->len);
+ }
+ if(salt->len > 0) {
+ PORT_Memcpy((pre_hash->data+pwd->len), salt->data, salt->len);
+ }
+ for(i = 0; ((i < iter) && (rv == SECSuccess)); i++) {
+ rv = nsspkcs5_HashBuf(hashObj, hash->data,
+ pre_hash->data, pre_hash->len);
+ if(rv != SECFailure) {
+ pre_hash->len = hashObj->length;
+ PORT_Memcpy(pre_hash->data, hash->data, hashObj->length);
+ }
+ }
+ }
+ }
+
+ if(pre_hash != NULL) {
+ SECITEM_FreeItem(pre_hash, PR_TRUE);
+ }
+
+ if((rv != SECSuccess) && (hash != NULL)) {
+ SECITEM_FreeItem(hash, PR_TRUE);
+ hash = NULL;
+ }
+
+ return hash;
+}
+
+/* this bit generation routine is described in PKCS 12 and the proposed
+ * extensions to PKCS 5. an initial hash is generated following the
+ * instructions laid out in PKCS 5. If the number of bits generated is
+ * insufficient, then the method discussed in the proposed extensions to
+ * PKCS 5 in PKCS 12 are used. This extension makes use of the HMAC
+ * function. And the P_Hash function from the TLS standard.
+ */
+static SECItem *
+nsspkcs5_PFXPBE(const SECHashObject *hashObj, NSSPKCS5PBEParameter *pbe_param,
+ SECItem *init_hash, unsigned int bytes_needed)
+{
+ SECItem *ret_bits = NULL;
+ int hash_size = 0;
+ unsigned int i;
+ unsigned int hash_iter;
+ unsigned int dig_len;
+ SECStatus rv = SECFailure;
+ unsigned char *state = NULL;
+ unsigned int state_len;
+ HMACContext *cx = NULL;
+
+ hash_size = hashObj->length;
+ hash_iter = (bytes_needed + (unsigned int)hash_size - 1) / hash_size;
+
+ /* allocate return buffer */
+ ret_bits = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
+ if(ret_bits == NULL)
+ return NULL;
+ ret_bits->data = (unsigned char *)PORT_ZAlloc((hash_iter * hash_size) + 1);
+ ret_bits->len = (hash_iter * hash_size);
+ if(ret_bits->data == NULL) {
+ PORT_Free(ret_bits);
+ return NULL;
+ }
+
+ /* allocate intermediate hash buffer. 8 is for the 8 bytes of
+ * data which are added based on iteration number
+ */
+
+ if ((unsigned int)hash_size > pbe_param->salt.len) {
+ state_len = hash_size;
+ } else {
+ state_len = pbe_param->salt.len;
+ }
+ state = (unsigned char *)PORT_ZAlloc(state_len);
+ if(state == NULL) {
+ rv = SECFailure;
+ goto loser;
+ }
+ if(pbe_param->salt.len > 0) {
+ PORT_Memcpy(state, pbe_param->salt.data, pbe_param->salt.len);
+ }
+
+ cx = HMAC_Create(hashObj, init_hash->data, init_hash->len);
+ if (cx == NULL) {
+ rv = SECFailure;
+ goto loser;
+ }
+
+ for(i = 0; i < hash_iter; i++) {
+
+ /* generate output bits */
+ HMAC_Begin(cx);
+ HMAC_Update(cx, state, state_len);
+ HMAC_Update(cx, pbe_param->salt.data, pbe_param->salt.len);
+ rv = HMAC_Finish(cx, ret_bits->data + (i * hash_size),
+ &dig_len, hash_size);
+ if (rv != SECSuccess)
+ goto loser;
+ PORT_Assert((unsigned int)hash_size == dig_len);
+
+ /* generate new state */
+ HMAC_Begin(cx);
+ HMAC_Update(cx, state, state_len);
+ rv = HMAC_Finish(cx, state, &state_len, state_len);
+ if (rv != SECSuccess)
+ goto loser;
+ PORT_Assert(state_len == dig_len);
+ }
+
+loser:
+ if (state != NULL)
+ PORT_ZFree(state, state_len);
+ HMAC_Destroy(cx);
+
+ if(rv != SECSuccess) {
+ SECITEM_ZfreeItem(ret_bits, PR_TRUE);
+ ret_bits = NULL;
+ }
+
+ return ret_bits;
+}
+
+/* generate bits for the key and iv determination. if enough bits
+ * are not generated using PKCS 5, then we need to generate more bits
+ * based on the extension proposed in PKCS 12
+ */
+static SECItem *
+nsspkcs5_PBKDF1Extended(const SECHashObject *hashObj,
+ NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem, PRBool faulty3DES)
+{
+ SECItem * hash = NULL;
+ SECItem * newHash = NULL;
+ int bytes_needed;
+ int bytes_available;
+
+ bytes_needed = pbe_param->ivLen + pbe_param->keyLen;
+ bytes_available = hashObj->length;
+
+ hash = nsspkcs5_PBKDF1(hashObj, &pbe_param->salt, pwitem,
+ pbe_param->iter, faulty3DES);
+
+ if(hash == NULL) {
+ return NULL;
+ }
+
+ if(bytes_needed <= bytes_available) {
+ return hash;
+ }
+
+ newHash = nsspkcs5_PFXPBE(hashObj, pbe_param, hash, bytes_needed);
+ if (hash != newHash)
+ SECITEM_FreeItem(hash, PR_TRUE);
+ return newHash;
+}
+
+#ifdef PBKDF2
+
+/*
+ * PBDKDF2 is PKCS #5 v2.0 it's currently not used by NSS
+ */
+/*
+ * We This is safe because hLen for all our
+ * HMAC algorithms are multiples of 4.
+ */
+static void
+xorbytes(unsigned char *dest, unsigned char *src, int len)
+{
+#ifdef PARANOIA
+ while (len--) {
+ *dest = *dest ^ *src;
+ dest++;
+ src++;
+ }
+#else
+ PRUInt32 dest32 = (PRUInt32 *)dest;
+ PRUInt32 src32 = (PRUInt32 *)dest;
+ while (len -= sizeof(PRUInt32)) {
+ *dest32 = *dest32 ^ *src32;
+ dest++;
+ src++;
+ }
+#endif
+}
+
+static SECStatus
+nsspkcs5_PBKFD2_F(const SECHashObject *hashobj, SECItem *pwitem, SECItem *salt,
+ int iterations, unsigned int i, unsigned char *T)
+{
+ int j;
+ HMACContext *cx = NULL;
+ unsigned int hLen = hashObject->length
+ SECStatus rv = SECFailure;
+ unsigned char *last = NULL;
+ int lastLength = salt->len + 4;
+
+ cx=HMAC_Create(hashobj,pwitem->data,pwitem->len);
+ if (cx == NULL) {
+ goto loser;
+ }
+ PORT_Memset(T,0,hLen);
+ realLastLength= MAX(lastLength,hLen);
+ last = PORT_Alloc(realLastLength);
+ if (last == NULL) {
+ goto loser;
+ }
+ PORT_Memcpy(last,salt.data,salt.len);
+ last[salt->len ] = (i >> 24) & 0xff;
+ last[salt->len+1] = (i >> 16) & 0xff;
+ last[salt->len+2] = (i >> 8) & 0xff;
+ last[salt->len+3] = i & 0xff;
+
+ /* NOTE: we need at least one iteration to return success! */
+ for (j=0; j < interations; j++) {
+ rv =HMAC_Begin(cx);
+ if (rv !=SECSuccess) {
+ break;
+ }
+ HMAC_Update(cx,last,lastLength);
+ rv =HMAC_Finish(cx,last,&lastLength,hLen);
+ if (rv !=SECSuccess) {
+ break;
+ }
+ do_xor(T,last,hLen);
+ }
+loser:
+ if (cx) {
+ HMAC_DestroyContext(cx);
+ }
+ if (last) {
+ PORT_ZFree(last,reaLastLength);
+ }
+ return rv;
+}
+
+static SECItem *
+nsspkcs5_PBKFD2(const SECHashObject *hashObj, NSSPKCS5PBEParameter *pbe_param,
+ SECItem *pwitem)
+{
+ unsigned int dkLen = bytesNeeded;
+ unsigned int hLen = hashObject->length
+ unsigned int l = (dkLen+hLen-1) / hLen;
+ unsigned char *rp;
+ SECItem *result;
+ SECItem *salt = pbe_param->salt;
+ int interations = pbe_param->iter;
+ int bytesNeeded = pbe_param->keyLen;
+
+ result = SECITEM_AllocItem(NULL,NULL,l*hLen);
+ if (result == NULL) {
+ return NULL;
+ }
+
+ T = PORT_Alloc(hLen);
+ if (T == NULL) {
+ goto loser;
+ }
+
+ for (i=0,rp=results->data; i < l ; i++, rp +=hLen) {
+ rv = nsspkcs5_PBKFD2_F(hashobj,pwitem,salt,iterations,i,T);
+ if (rv != SECSuccess) {
+ break;
+ }
+ PORT_Memcpy(rp,T,hLen);
+ }
+
+loser:
+ if (T) {
+ PORT_ZFree(T);
+ }
+ if (rv != SECSuccess) {
+ SECITEM_FreeITEM(result,PR_TRUE);
+ result = NULL;
+ } else {
+ result->len = dkLen;
+ }
+
+ return result;
+}
+#endif
+
+#define HMAC_BUFFER 64
+#define ROUNDUP(x,y) ((((x)+((y)-1))/(y))*(y))
+/*
+ * This is the extended PBE function defined by the final PKCS #12 spec.
+ */
+static SECItem *
+nsspkcs5_PKCS12PBE(const SECHashObject *hashObject,
+ NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem,
+ PBEBitGenID bitGenPurpose, unsigned int bytesNeeded)
+{
+ PRArenaPool *arena = NULL;
+ unsigned int SLen,PLen;
+ unsigned int hashLength = hashObject->length;
+ unsigned char *S, *P;
+ SECItem *A = NULL, B, D, I;
+ SECItem *salt = &pbe_param->salt;
+ unsigned int c,i = 0;
+ unsigned int hashLen, iter;
+ unsigned char *iterBuf;
+ void *hash = NULL;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if(!arena) {
+ return NULL;
+ }
+
+ /* how many hash object lengths are needed */
+ c = (bytesNeeded + (hashLength-1))/hashLength;
+
+ /* initialize our buffers */
+ D.len = HMAC_BUFFER;
+ /* B and D are the same length, use one alloc go get both */
+ D.data = (unsigned char*)PORT_ArenaZAlloc(arena, D.len*2);
+ B.len = D.len;
+ B.data = D.data + D.len;
+
+ /* if all goes well, A will be returned, so don't use our temp arena */
+ A = SECITEM_AllocItem(NULL,NULL,c*hashLength);
+ if (A == NULL) {
+ goto loser;
+ }
+
+ SLen = ROUNDUP(salt->len,HMAC_BUFFER);
+ PLen = ROUNDUP(pwitem->len,HMAC_BUFFER);
+ I.len = SLen+PLen;
+ I.data = (unsigned char*)PORT_ArenaZAlloc(arena, I.len);
+ if (I.data == NULL) {
+ goto loser;
+ }
+
+ /* S & P are only used to initialize I */
+ S = I.data;
+ P = S + SLen;
+
+ PORT_Memset(D.data, (char)bitGenPurpose, D.len);
+ if (SLen) {
+ PORT_Memcpy(S, salt->data, salt->len);
+ if (salt->len != SLen) {
+ PORT_Memcpy(S+salt->len, salt->data, SLen-(salt->len));
+ }
+ }
+ if (PLen) {
+ PORT_Memcpy(P, salt->data, salt->len);
+ if (salt->len != PLen) {
+ PORT_Memcpy(P+salt->len, salt->data, PLen-salt->len);
+ }
+ }
+
+ iterBuf = (unsigned char*)PORT_ArenaZAlloc(arena,hashLength);
+ if (iterBuf == NULL) {
+ goto loser;
+ }
+
+ hash = hashObject->create();
+ if(!hash) {
+ goto loser;
+ }
+ /* calculate the PBE now */
+ for(i = 0; i < c; i++) {
+ int Bidx; /* must be signed or the for loop won't terminate */
+ unsigned int k, j;
+ unsigned char *Ai = A->data+i*hashLength;
+
+
+ for(iter = 0; iter < pbe_param->iter; iter++) {
+ hashObject->begin(hash);
+
+ if (iter) {
+ hashObject->update(hash, iterBuf, hashLen);
+ } else {
+ hashObject->update(hash, D.data, D.len);
+ hashObject->update(hash, I.data, I.len);
+ }
+
+ hashObject->end(hash, iterBuf, &hashLen, hashObject->length);
+ if(hashLen != hashObject->length) {
+ break;
+ }
+ }
+
+ PORT_Memcpy(Ai, iterBuf, hashLength);
+ for (Bidx = 0; Bidx < B.len; B.len += hashLength) {
+ PORT_Memcpy(B.data +Bidx, iterBuf,
+ (((Bidx + hashLength) > B.len) ? (B.len - Bidx) :
+ hashLength));
+ }
+
+ k = I.len/B.len;
+ for(j = 0; j < k; j++) {
+ unsigned int q, carryBit;
+ unsigned char *Ij = I.data + j*B.len;
+
+ /* (Ij = Ij+B+1) */
+ for (Bidx = (B.len-1), q=1, carryBit=0; Bidx >= 0; Bidx--,q=0) {
+ q += (unsigned int)Ij[Bidx];
+ q += (unsigned int)B.data[Bidx];
+ q += carryBit;
+
+ carryBit = (q > 0xff);
+ Ij[Bidx] = (unsigned char)(q & 0xff);
+ }
+ }
+ }
+loser:
+ if (hash) {
+ hashObject->destroy(hash, PR_TRUE);
+ }
+ if(arena) {
+ PORT_FreeArena(arena, PR_TRUE);
+ }
+
+ /* if i != c, then we didn't complete the loop above and must of failed
+ * somwhere along the way */
+ if (i != c) {
+ SECITEM_ZfreeItem(A,PR_TRUE);
+ A = NULL;
+ } else {
+ A->len = bytesNeeded;
+ }
+
+ return A;
+}
+
+/*
+ * generate key as per PKCS 5
+ */
+SECItem *
+nsspkcs5_ComputeKeyAndIV(NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem,
+ SECItem *iv, PRBool faulty3DES)
+{
+ SECItem *hash = NULL, *key = NULL;
+ const SECHashObject *hashObj;
+ PRBool getIV = PR_FALSE;
+
+ if((pbe_param == NULL) || (pwitem == NULL)) {
+ return NULL;
+ }
+
+ key = SECITEM_AllocItem(NULL,NULL,pbe_param->keyLen);
+ if (key == NULL) {
+ return NULL;
+ }
+
+ if ((pbe_param->ivLen) && (iv->data == NULL)) {
+ getIV = PR_TRUE;
+ iv->data = (unsigned char *)PORT_Alloc(pbe_param->ivLen);
+ if (iv->data == NULL) {
+ goto loser;
+ }
+ iv->len = pbe_param->ivLen;
+ }
+
+ hashObj = &SECRawHashObjects[pbe_param->hashType];
+ switch (pbe_param->pbeType) {
+ case NSSPKCS5_PBKDF1:
+ hash = nsspkcs5_PBKDF1Extended(hashObj,pbe_param,pwitem,faulty3DES);
+ if (hash == NULL) {
+ goto loser;
+ }
+ PORT_Assert(hash->len >= key->len+iv->len);
+ if (getIV) {
+ PORT_Memcpy(iv->data, hash->data+(hash->len - iv->len),iv->len);
+ }
+ break;
+#ifdef PBKDF2
+ case NSSPKCS5_PBKDF2:
+ hash = nsspkcs5_PBKDF2(hashObj,pbe_param,pwitem);
+ PORT_Assert(!getIV);
+ break;
+#endif
+ case NSSPKCS5_PKCS12_V2:
+ if (getIV) {
+ hash = nsspkcs5_PKCS12PBE(hashObj,pbe_param,pwitem,
+ pbeBitGenCipherIV,iv->len);
+ if (hash == NULL) {
+ goto loser;
+ }
+ PORT_Memcpy(iv->data,hash->data,iv->len);
+ SECITEM_ZfreeItem(hash,PR_TRUE);
+ hash = NULL;
+ }
+ hash = nsspkcs5_PKCS12PBE(hashObj,pbe_param,pwitem,
+ pbe_param->keyID,key->len);
+ default:
+ break;
+ }
+
+ if (hash == NULL) {
+ goto loser;
+ }
+
+ if (pbe_param->is2KeyDES) {
+ PORT_Memcpy(key->data, hash->data, (key->len * 2) / 3);
+ PORT_Memcpy(&(key->data[(key->len * 2) / 3]), key->data,
+ key->len / 3);
+ } else {
+ PORT_Memcpy(key->data, hash->data, key->len);
+ }
+
+ SECITEM_FreeItem(hash, PR_TRUE);
+ return key;
+
+loser:
+ if (getIV && iv->data) {
+ PORT_ZFree(iv->data,iv->len);
+ iv->data = NULL;
+ }
+
+ SECITEM_ZfreeItem(key, PR_TRUE);
+ return NULL;
+}
+
+static SECStatus
+nsspkcs5_FillInParam(SECOidTag algorithm, NSSPKCS5PBEParameter *pbe_param)
+{
+ PRBool skipType = PR_FALSE;
+
+ pbe_param->keyLen = 5;
+ pbe_param->ivLen = 8;
+ pbe_param->hashType = HASH_AlgSHA1;
+ pbe_param->pbeType = NSSPKCS5_PBKDF1;
+ pbe_param->encAlg = SEC_OID_RC2_CBC;
+ pbe_param->is2KeyDES = PR_FALSE;
+ switch(algorithm) {
+ /* DES3 Algorithms */
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
+ pbe_param->is2KeyDES = PR_TRUE;
+ /* fall through */
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
+ pbe_param->pbeType = NSSPKCS5_PKCS12_V2;
+ /* fall through */
+ case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
+ pbe_param->keyLen = 24;
+ pbe_param->encAlg = SEC_OID_DES_EDE3_CBC;
+ break;
+
+ /* DES Algorithms */
+ case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
+ pbe_param->hashType = HASH_AlgMD2;
+ goto finish_des;
+ case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
+ pbe_param->hashType = HASH_AlgMD5;
+ /* fall through */
+ case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
+finish_des:
+ pbe_param->keyLen = 8;
+ pbe_param->encAlg = SEC_OID_DES_CBC;
+ break;
+
+ /* RC2 Algorithms */
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
+ pbe_param->keyLen = 16;
+ /* fall through */
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
+ pbe_param->pbeType = NSSPKCS5_PKCS12_V2;
+ break;
+ case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
+ pbe_param->keyLen = 16;
+ /* fall through */
+ case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
+ break;
+
+ /* RC4 algorithms */
+ case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
+ skipType = PR_TRUE;
+ /* fall through */
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
+ pbe_param->keyLen = 16;
+ /* fall through */
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
+ if (!skipType) {
+ pbe_param->pbeType = NSSPKCS5_PKCS12_V2;
+ }
+ /* fall through */
+ case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
+ pbe_param->ivLen = 0;
+ pbe_param->encAlg = SEC_OID_RC4;
+ break;
+ default:
+ return SECFailure;
+ }
+
+ return SECSuccess;
+}
+
+/* decode the algid and generate a PKCS 5 parameter from it
+ */
+NSSPKCS5PBEParameter *
+nsspkcs5_NewParam(SECOidTag alg, SECItem *salt, int iterator)
+{
+ PRArenaPool *arena = NULL;
+ NSSPKCS5PBEParameter *pbe_param = NULL;
+ SECStatus rv = SECFailure;
+
+ arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
+ if (arena == NULL)
+ return NULL;
+
+ /* allocate memory for the parameter */
+ pbe_param = (NSSPKCS5PBEParameter *)PORT_ArenaZAlloc(arena,
+ sizeof(NSSPKCS5PBEParameter));
+
+ if (pbe_param == NULL) {
+ goto loser;
+ }
+
+ pbe_param->poolp = arena;
+
+ rv = nsspkcs5_FillInParam(alg, pbe_param);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ pbe_param->iter = iterator;
+ if (salt) {
+ rv = SECITEM_CopyItem(arena,&pbe_param->salt,salt);
+ }
+
+ /* default key gen */
+ pbe_param->keyID = pbeBitGenCipherKey;
+
+loser:
+ if (rv != SECSuccess) {
+ PORT_FreeArena(arena, PR_TRUE);
+ pbe_param = NULL;
+ }
+
+ return pbe_param;
+}
+
+/* decode the algid and generate a PKCS 5 parameter from it
+ */
+NSSPKCS5PBEParameter *
+nsspkcs5_AlgidToParam(SECAlgorithmID *algid)
+{
+ NSSPKCS5PBEParameter *pbe_param = NULL;
+ SECOidTag algorithm;
+ SECStatus rv = SECFailure;
+
+ if (algid == NULL) {
+ return NULL;
+ }
+
+ algorithm = SECOID_GetAlgorithmTag(algid);
+ if (algorithm == SEC_OID_UNKNOWN) {
+ goto loser;
+ }
+
+ pbe_param = nsspkcs5_NewParam(algorithm, NULL, 1);
+ if (pbe_param == NULL) {
+ goto loser;
+ }
+
+ /* decode parameter */
+ rv = SECFailure;
+ switch (pbe_param->pbeType) {
+ case NSSPKCS5_PBKDF1:
+ rv = SEC_ASN1DecodeItem(pbe_param->poolp, pbe_param,
+ NSSPKCS5PBEParameterTemplate, &algid->parameters);
+ break;
+ case NSSPKCS5_PKCS12_V2:
+ rv = SEC_ASN1DecodeItem(pbe_param->poolp, pbe_param,
+ NSSPKCS5PKCS12V2PBEParameterTemplate, &algid->parameters);
+ break;
+ case NSSPKCS5_PBKDF2:
+ break;
+ }
+
+loser:
+ if (rv == SECSuccess) {
+ pbe_param->iter = DER_GetInteger(&pbe_param->iteration);
+ } else {
+ nsspkcs5_DestroyPBEParameter(pbe_param);
+ pbe_param = NULL;
+ }
+
+ return pbe_param;
+}
+
+/* destroy a pbe parameter. it assumes that the parameter was
+ * generated using the appropriate create function and therefor
+ * contains an arena pool.
+ */
+void
+nsspkcs5_DestroyPBEParameter(NSSPKCS5PBEParameter *pbe_param)
+{
+ if (pbe_param != NULL) {
+ PORT_FreeArena(pbe_param->poolp, PR_TRUE);
+ }
+}
+
+
+/* crypto routines */
+/* perform DES encryption and decryption. these routines are called
+ * by nsspkcs5_CipherData. In the case of an error, NULL is returned.
+ */
+static SECItem *
+sec_pkcs5_des(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_des,
+ PRBool encrypt)
+{
+ SECItem *dest;
+ SECItem *dup_src;
+ SECStatus rv = SECFailure;
+ int pad;
+
+ if((src == NULL) || (key == NULL) || (iv == NULL))
+ return NULL;
+
+ dup_src = SECITEM_DupItem(src);
+ if(dup_src == NULL) {
+ return NULL;
+ }
+
+ if(encrypt != PR_FALSE) {
+ void *dummy;
+
+ dummy = DES_PadBuffer(NULL, dup_src->data,
+ dup_src->len, &dup_src->len);
+ if(dummy == NULL) {
+ SECITEM_FreeItem(dup_src, PR_TRUE);
+ return NULL;
+ }
+ dup_src->data = (unsigned char*)dummy;
+ }
+
+ dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
+ if(dest != NULL) {
+ /* allocate with over flow */
+ dest->data = (unsigned char *)PORT_ZAlloc(dup_src->len + 64);
+ if(dest->data != NULL) {
+ DESContext *ctxt;
+ ctxt = DES_CreateContext(key->data, iv->data,
+ (triple_des ? NSS_DES_EDE3_CBC : NSS_DES_CBC),
+ encrypt);
+
+ if(ctxt != NULL) {
+ rv = ((encrypt != PR_TRUE) ? DES_Decrypt : DES_Encrypt)(
+ ctxt, dest->data, &dest->len,
+ dup_src->len + 64, dup_src->data, dup_src->len);
+
+ /* remove padding -- assumes 64 bit blocks */
+ if((encrypt == PR_FALSE) && (rv == SECSuccess)) {
+ pad = dest->data[dest->len-1];
+ if((pad > 0) && (pad <= 8)) {
+ if(dest->data[dest->len-pad] != pad) {
+ rv = SECFailure;
+ PORT_SetError(SEC_ERROR_BAD_PASSWORD);
+ } else {
+ dest->len -= pad;
+ }
+ } else {
+ rv = SECFailure;
+ PORT_SetError(SEC_ERROR_BAD_PASSWORD);
+ }
+ }
+ DES_DestroyContext(ctxt, PR_TRUE);
+ }
+ }
+ }
+
+ if(rv == SECFailure) {
+ if(dest != NULL) {
+ SECITEM_FreeItem(dest, PR_TRUE);
+ }
+ dest = NULL;
+ }
+
+ if(dup_src != NULL) {
+ SECITEM_FreeItem(dup_src, PR_TRUE);
+ }
+
+ return dest;
+}
+
+/* perform rc2 encryption/decryption if an error occurs, NULL is returned
+ */
+static SECItem *
+sec_pkcs5_rc2(SECItem *key, SECItem *iv, SECItem *src, PRBool dummy,
+ PRBool encrypt)
+{
+ SECItem *dest;
+ SECItem *dup_src;
+ SECStatus rv = SECFailure;
+ int pad;
+
+ if((src == NULL) || (key == NULL) || (iv == NULL)) {
+ return NULL;
+ }
+
+ dup_src = SECITEM_DupItem(src);
+ if(dup_src == NULL) {
+ return NULL;
+ }
+
+ if(encrypt != PR_FALSE) {
+ void *dummy;
+
+ dummy = DES_PadBuffer(NULL, dup_src->data,
+ dup_src->len, &dup_src->len);
+ if(dummy == NULL) {
+ SECITEM_FreeItem(dup_src, PR_TRUE);
+ return NULL;
+ }
+ dup_src->data = (unsigned char*)dummy;
+ }
+
+ dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
+ if(dest != NULL) {
+ dest->data = (unsigned char *)PORT_ZAlloc(dup_src->len + 64);
+ if(dest->data != NULL) {
+ RC2Context *ctxt;
+
+ ctxt = RC2_CreateContext(key->data, key->len, iv->data,
+ NSS_RC2_CBC, key->len);
+
+ if(ctxt != NULL) {
+ rv = ((encrypt != PR_TRUE) ? RC2_Decrypt : RC2_Encrypt)(
+ ctxt, dest->data, &dest->len,
+ dup_src->len + 64, dup_src->data, dup_src->len);
+
+ /* assumes 8 byte blocks -- remove padding */
+ if((rv == SECSuccess) && (encrypt != PR_TRUE)) {
+ pad = dest->data[dest->len-1];
+ if((pad > 0) && (pad <= 8)) {
+ if(dest->data[dest->len-pad] != pad) {
+ PORT_SetError(SEC_ERROR_BAD_PASSWORD);
+ rv = SECFailure;
+ } else {
+ dest->len -= pad;
+ }
+ } else {
+ PORT_SetError(SEC_ERROR_BAD_PASSWORD);
+ rv = SECFailure;
+ }
+ }
+
+ }
+ }
+ }
+
+ if((rv != SECSuccess) && (dest != NULL)) {
+ SECITEM_FreeItem(dest, PR_TRUE);
+ dest = NULL;
+ }
+
+ if(dup_src != NULL) {
+ SECITEM_FreeItem(dup_src, PR_TRUE);
+ }
+
+ return dest;
+}
+
+/* perform rc4 encryption and decryption */
+static SECItem *
+sec_pkcs5_rc4(SECItem *key, SECItem *iv, SECItem *src, PRBool dummy_op,
+ PRBool encrypt)
+{
+ SECItem *dest;
+ SECStatus rv = SECFailure;
+
+ if((src == NULL) || (key == NULL) || (iv == NULL)) {
+ return NULL;
+ }
+
+ dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
+ if(dest != NULL) {
+ dest->data = (unsigned char *)PORT_ZAlloc(sizeof(unsigned char) *
+ (src->len + 64));
+ if(dest->data != NULL) {
+ RC4Context *ctxt;
+
+ ctxt = RC4_CreateContext(key->data, key->len);
+ if(ctxt) {
+ rv = ((encrypt != PR_FALSE) ? RC4_Decrypt : RC4_Encrypt)(
+ ctxt, dest->data, &dest->len,
+ src->len + 64, src->data, src->len);
+ RC4_DestroyContext(ctxt, PR_TRUE);
+ }
+ }
+ }
+
+ if((rv != SECSuccess) && (dest)) {
+ SECITEM_FreeItem(dest, PR_TRUE);
+ dest = NULL;
+ }
+
+ return dest;
+}
+/* function pointer template for crypto functions */
+typedef SECItem *(* pkcs5_crypto_func)(SECItem *key, SECItem *iv,
+ SECItem *src, PRBool op1, PRBool op2);
+
+/* performs the cipher operation on the src and returns the result.
+ * if an error occurs, NULL is returned.
+ *
+ * a null length password is allowed. this corresponds to encrypting
+ * the data with ust the salt.
+ */
+/* change this to use PKCS 11? */
+SECItem *
+nsspkcs5_CipherData(NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem,
+ SECItem *src, PRBool encrypt, PRBool *update)
+{
+ SECItem *key = NULL, iv;
+ SECItem *dest = NULL;
+ PRBool tripleDES = PR_TRUE;
+ pkcs5_crypto_func cryptof;
+
+ iv.data = NULL;
+
+ if (update) {
+ *update = PR_FALSE;
+ }
+
+ if ((pwitem == NULL) || (src == NULL)) {
+ return NULL;
+ }
+
+ /* get key, and iv */
+ key = nsspkcs5_ComputeKeyAndIV(pbe_param, pwitem, &iv, PR_FALSE);
+ if(key == NULL) {
+ return NULL;
+ }
+
+ switch(pbe_param->encAlg) {
+ case SEC_OID_DES_EDE3_CBC:
+ cryptof = sec_pkcs5_des;
+ tripleDES = PR_TRUE;
+ break;
+ case SEC_OID_DES_CBC:
+ cryptof = sec_pkcs5_des;
+ tripleDES = PR_FALSE;
+ break;
+ case SEC_OID_RC2_CBC:
+ cryptof = sec_pkcs5_rc2;
+ break;
+ case SEC_OID_RC4:
+ cryptof = sec_pkcs5_rc4;
+ break;
+ default:
+ cryptof = NULL;
+ break;
+ }
+
+ if (cryptof == NULL) {
+ goto loser;
+ }
+
+ dest = (*cryptof)(key, &iv, src, tripleDES, encrypt);
+ /*
+ * it's possible for some keys and keydb's to claim to
+ * be triple des when they're really des. In this case
+ * we simply try des. If des works we set the update flag
+ * so the key db knows it needs to update all it's entries.
+ * The case can only happen on decrypted of a
+ * SEC_OID_DES_EDE3_CBD.
+ */
+ if ((dest == NULL) && (encrypt == PR_FALSE) &&
+ (pbe_param->encAlg == SEC_OID_DES_EDE3_CBC)) {
+ dest = (*cryptof)(key, &iv, src, PR_FALSE, encrypt);
+ if (update && (dest != NULL)) *update = PR_TRUE;
+ }
+
+loser:
+ if (key != NULL) {
+ SECITEM_ZfreeItem(key, PR_TRUE);
+ }
+ if (iv.data != NULL) {
+ SECITEM_ZfreeItem(&iv, PR_FALSE);
+ }
+
+ return dest;
+}
+
+/* creates a algorithm ID containing the PBE algorithm and appropriate
+ * parameters. the required parameter is the algorithm. if salt is
+ * not specified, it is generated randomly. if IV is specified, it overrides
+ * the PKCS 5 generation of the IV.
+ *
+ * the returned SECAlgorithmID should be destroyed using
+ * SECOID_DestroyAlgorithmID
+ */
+SECAlgorithmID *
+nsspkcs5_CreateAlgorithmID(PRArenaPool *arena, SECOidTag algorithm,
+ NSSPKCS5PBEParameter *pbe_param)
+{
+ SECAlgorithmID *algid, *ret_algid;
+ SECItem der_param;
+ SECStatus rv = SECFailure;
+ void *dummy = NULL;
+
+ if (arena == NULL) {
+ return NULL;
+ }
+
+ der_param.data = NULL;
+ der_param.len = 0;
+
+ /* generate the algorithm id */
+ algid = (SECAlgorithmID *)PORT_ArenaZAlloc(arena, sizeof(SECAlgorithmID));
+ if (algid == NULL) {
+ goto loser;
+ }
+
+ if (pbe_param->iteration.data == NULL) {
+ dummy = SEC_ASN1EncodeInteger(pbe_param->poolp,&pbe_param->iteration,
+ pbe_param->iter);
+ if (dummy == NULL) {
+ goto loser;
+ }
+ }
+ switch (pbe_param->pbeType) {
+ case NSSPKCS5_PBKDF1:
+ dummy = SEC_ASN1EncodeItem(arena, &der_param, pbe_param,
+ NSSPKCS5PBEParameterTemplate);
+ break;
+ case NSSPKCS5_PKCS12_V2:
+ dummy = SEC_ASN1EncodeItem(arena, &der_param, pbe_param,
+ NSSPKCS5PKCS12V2PBEParameterTemplate);
+ break;
+ default:
+ break;
+ }
+
+ if (dummy == NULL) {
+ goto loser;
+ }
+
+ rv = SECOID_SetAlgorithmID(arena, algid, algorithm, &der_param);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ ret_algid = (SECAlgorithmID *)PORT_ZAlloc(sizeof(SECAlgorithmID));
+ if (ret_algid == NULL) {
+ goto loser;
+ }
+
+ rv = SECOID_CopyAlgorithmID(NULL, ret_algid, algid);
+ if (rv != SECSuccess) {
+ SECOID_DestroyAlgorithmID(ret_algid, PR_TRUE);
+ ret_algid = NULL;
+ }
+
+loser:
+
+ return ret_algid;
+}
diff --git a/security/nss/lib/softoken/lowpbe.h b/security/nss/lib/softoken/lowpbe.h
new file mode 100644
index 000000000..8ddee11a6
--- /dev/null
+++ b/security/nss/lib/softoken/lowpbe.h
@@ -0,0 +1,132 @@
+/*
+ * 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.
+ */
+
+#ifndef _SECPKCS5_H_
+#define _SECPKCS5_H_
+
+#include "plarena.h"
+#include "secitem.h"
+#include "seccomon.h"
+#include "secoidt.h"
+#include "hasht.h"
+
+typedef SECItem * (* SEC_PKCS5GetPBEPassword)(void *arg);
+
+/* used for V2 PKCS 12 Draft Spec */
+typedef enum {
+ pbeBitGenIDNull = 0,
+ pbeBitGenCipherKey = 0x01,
+ pbeBitGenCipherIV = 0x02,
+ pbeBitGenIntegrityKey = 0x03
+} PBEBitGenID;
+
+typedef enum {
+ NSSPKCS5_PBKDF1 = 0,
+ NSSPKCS5_PBKDF2 = 1,
+ NSSPKCS5_PKCS12_V2 = 2
+} NSSPKCS5PBEType;
+
+typedef struct NSSPKCS5PBEParameterStr NSSPKCS5PBEParameter;
+
+struct NSSPKCS5PBEParameterStr {
+ PRArenaPool *poolp;
+ SECItem salt; /* octet string */
+ SECItem iteration; /* integer */
+
+ /* used locally */
+ int iter;
+ int keyLen;
+ int ivLen;
+ HASH_HashType hashType;
+ NSSPKCS5PBEType pbeType;
+ PBEBitGenID keyID;
+ SECOidTag encAlg;
+ PRBool is2KeyDES;
+};
+
+
+SEC_BEGIN_PROTOS
+/* Create a PKCS5 Algorithm ID
+ * The algorithm ID is set up using the PKCS #5 parameter structure
+ * algorithm is the PBE algorithm ID for the desired algorithm
+ * pbe is a pbe param block with all the info needed to create the
+ * algorithm id.
+ * If an error occurs or the algorithm specified is not supported
+ * or is not a password based encryption algorithm, NULL is returned.
+ * Otherwise, a pointer to the algorithm id is returned.
+ */
+extern SECAlgorithmID *
+nsspkcs5_CreateAlgorithmID(PRArenaPool *arena, SECOidTag algorithm,
+ NSSPKCS5PBEParameter *pbe);
+
+/*
+ * Convert an Algorithm ID to a PBE Param.
+ * NOTE: this does not suppport PKCS 5 v2 because it's only used for the
+ * keyDB which only support PKCS 5 v1, PFX, and PKCS 12.
+ */
+NSSPKCS5PBEParameter *
+nsspkcs5_AlgidToParam(SECAlgorithmID *algid);
+
+/*
+ * Convert an Algorithm ID to a PBE Param.
+ * NOTE: this does not suppport PKCS 5 v2 because it's only used for the
+ * keyDB which only support PKCS 5 v1, PFX, and PKCS 12.
+ */
+NSSPKCS5PBEParameter *
+nsspkcs5_NewParam(SECOidTag alg, SECItem *salt, int iterator);
+
+
+/* Encrypt/Decrypt data using password based encryption.
+ * algid is the PBE algorithm identifier,
+ * pwitem is the password,
+ * src is the source for encryption/decryption,
+ * encrypt is PR_TRUE for encryption, PR_FALSE for decryption.
+ * The key and iv are generated based upon PKCS #5 then the src
+ * is either encrypted or decrypted. If an error occurs, NULL
+ * is returned, otherwise the ciphered contents is returned.
+ */
+extern SECItem *
+nsspkcs5_CipherData(NSSPKCS5PBEParameter *, SECItem *pwitem,
+ SECItem *src, PRBool encrypt, PRBool *update);
+
+extern SECItem *
+nsspkcs5_ComputeKeyAndIV(NSSPKCS5PBEParameter *, SECItem *pwitem,
+ SECItem *iv, PRBool faulty3DES);
+
+/* Destroys PBE parameter */
+extern void
+nsspkcs5_DestroyPBEParameter(NSSPKCS5PBEParameter *param);
+
+SEC_END_PROTOS
+
+#endif
diff --git a/security/nss/lib/util/mac_rand.c b/security/nss/lib/softoken/mac_rand.c
index 6198f3407..6198f3407 100644
--- a/security/nss/lib/util/mac_rand.c
+++ b/security/nss/lib/softoken/mac_rand.c
diff --git a/security/nss/lib/softoken/manifest.mn b/security/nss/lib/softoken/manifest.mn
index c889a90c4..9d06365bb 100644
--- a/security/nss/lib/softoken/manifest.mn
+++ b/security/nss/lib/softoken/manifest.mn
@@ -36,39 +36,42 @@ MODULE = security
REQUIRES = dbm
-LIBRARY_NAME = softoken
+LIBRARY_NAME = softokn
+LIBRARY_VERSION = 3
+MAPFILE = $(OBJDIR)/softokn.def
EXPORTS = \
- secpkcs5.h \
pkcs11.h \
pkcs11f.h \
pkcs11p.h \
pkcs11t.h \
+ pkcs11n.h \
pkcs11u.h \
$(NULL)
PRIVATE_EXPORTS = \
alghmac.h \
- pkcs11i.h \
pk11pars.h \
+ pkcs11i.h \
$(NULL)
CSRCS = \
alghmac.c \
- rsawrapr.c \
- pkcs11.c \
- pkcs11c.c \
- pkcs11u.c \
- secpkcs5.c \
+ dbinit.c \
+ fipstest.c \
+ fipstokn.c \
keydb.c \
+ lowcert.c \
lowkey.c \
+ lowpbe.c \
padbuf.c \
- fipstest.c \
- fipstokn.c \
- rawhash.c \
- dbinit.c \
+ pcertdb.c \
pk11db.c \
+ pkcs11.c \
+ pkcs11c.c \
+ pkcs11u.c \
+ rawhash.c \
+ rsawrapr.c \
+ sysrand.c \
$(NULL)
-
-
diff --git a/security/nss/lib/util/os2_rand.c b/security/nss/lib/softoken/os2_rand.c
index b1dbba805..b1dbba805 100644
--- a/security/nss/lib/util/os2_rand.c
+++ b/security/nss/lib/softoken/os2_rand.c
diff --git a/security/nss/lib/softoken/pcert.h b/security/nss/lib/softoken/pcert.h
new file mode 100644
index 000000000..51a969f1a
--- /dev/null
+++ b/security/nss/lib/softoken/pcert.h
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ */
+
+#ifndef _PCERTDB_H_
+#define _PCERTDB_H_
+
+#include "plarena.h"
+#include "prlong.h"
+#include "pcertt.h"
+
+SEC_BEGIN_PROTOS
+
+/*
+** Add a DER encoded certificate to the permanent database.
+** "derCert" is the DER encoded certificate.
+** "nickname" is the nickname to use for the cert
+** "trust" is the trust parameters for the cert
+*/
+SECStatus nsslowcert_AddPermCert(NSSLOWCERTCertDBHandle *handle,
+ NSSLOWCERTCertificate *cert,
+ char *nickname, NSSLOWCERTCertTrust *trust);
+
+SECStatus nsslowcert_DeletePermCertificate(NSSLOWCERTCertificate *cert);
+
+typedef SECStatus (PR_CALLBACK * PermCertCallback)(NSSLOWCERTCertificate *cert,
+ SECItem *k, void *pdata);
+/*
+** Traverse the entire permanent database, and pass the certs off to a
+** user supplied function.
+** "certfunc" is the user function to call for each certificate
+** "udata" is the user's data, which is passed through to "certfunc"
+*/
+SECStatus
+nsslowcert_TraversePermCerts(NSSLOWCERTCertDBHandle *handle,
+ PermCertCallback certfunc,
+ void *udata );
+
+PRBool
+nsslowcert_CertDBKeyConflict(SECItem *derCert, NSSLOWCERTCertDBHandle *handle);
+
+SECItem *
+nsslowcert_FindCrlByKey(NSSLOWCERTCertDBHandle *handle, SECItem *crlKey,
+ char **urlp, PRBool isKRL);
+
+SECStatus
+nsslowcert_DeletePermCRL(NSSLOWCERTCertDBHandle *handle,SECItem *derName,
+ PRBool isKRL);
+SECStatus
+nsslowcert_AddCrl(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl ,
+ SECItem *derKey, char *url, PRBool isKRL);
+
+NSSLOWCERTCertDBHandle *nsslowcert_GetDefaultCertDB();
+NSSLOWKEYPublicKey *nsslowcert_ExtractPublicKey(NSSLOWCERTCertificate *);
+
+NSSLOWCERTCertificate *
+nsslowcert_NewTempCertificate(NSSLOWCERTCertDBHandle *handle, SECItem *derCert,
+ char *nickname, PRBool isperm, PRBool copyDER);
+NSSLOWCERTCertificate *
+nsslowcert_DupCertificate(NSSLOWCERTCertificate *cert);
+void nsslowcert_DestroyCertificate(NSSLOWCERTCertificate *cert);
+
+/*
+ * Lookup a certificate in the databases without locking
+ * "certKey" is the database key to look for
+ *
+ * XXX - this should be internal, but pkcs 11 needs to call it during a
+ * traversal.
+ */
+NSSLOWCERTCertificate *
+nsslowcert_FindCertByKey(NSSLOWCERTCertDBHandle *handle, SECItem *certKey);
+
+/*
+** Generate a certificate key from the issuer and serialnumber, then look it
+** up in the database. Return the cert if found.
+** "issuerAndSN" is the issuer and serial number to look for
+*/
+extern NSSLOWCERTCertificate *
+nsslowcert_FindCertByIssuerAndSN (NSSLOWCERTCertDBHandle *handle, NSSLOWCERTIssuerAndSN *issuerAndSN);
+
+/*
+** Find a certificate in the database by a DER encoded certificate
+** "derCert" is the DER encoded certificate
+*/
+extern NSSLOWCERTCertificate *
+nsslowcert_FindCertByDERCert(NSSLOWCERTCertDBHandle *handle, SECItem *derCert);
+
+/* convert an email address to lower case */
+char *nsslowcert_FixupEmailAddr(char *emailAddr);
+
+/*
+** Decode a DER encoded certificate into an NSSLOWCERTCertificate structure
+** "derSignedCert" is the DER encoded signed certificate
+** "copyDER" is true if the DER should be copied, false if the
+** existing copy should be referenced
+** "nickname" is the nickname to use in the database. If it is NULL
+** then a temporary nickname is generated.
+*/
+extern NSSLOWCERTCertificate *
+nsslowcert_DecodeDERCertificate (SECItem *derSignedCert, PRBool copyDER, char *nickname);
+
+SECStatus
+nsslowcert_KeyFromDERCert(PRArenaPool *arena, SECItem *derCert, SECItem *key);
+
+certDBEntrySMime *
+nsslowcert_ReadDBSMimeEntry(NSSLOWCERTCertDBHandle *certHandle,
+ char *emailAddr);
+void
+nsslowcert_DestroyDBEntry(certDBEntry *entry);
+
+SECStatus
+nsslowcert_OpenCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
+ NSSLOWCERTDBNameFunc namecb, void *cbarg, PRBool openVolatile);
+
+
+SEC_END_PROTOS
+
+ #endif /* _PCERTDB_H_ */
diff --git a/security/nss/lib/softoken/pcertdb.c b/security/nss/lib/softoken/pcertdb.c
new file mode 100644
index 000000000..e23752990
--- /dev/null
+++ b/security/nss/lib/softoken/pcertdb.c
@@ -0,0 +1,4410 @@
+/*
+ * 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.
+ */
+
+/*
+ * Permanent Certificate database handling code
+ *
+ * $Id$
+ */
+#include "prtime.h"
+
+#include "lowkeyti.h"
+#include "pcert.h"
+#include "mcom_db.h"
+#include "pcert.h"
+#include "secitem.h"
+#include "secder.h"
+
+/* Call to PK11_FreeSlot below */
+
+#include "secasn1.h"
+#include "secerr.h"
+#include "nssilock.h"
+#include "prmon.h"
+#include "nsslocks.h"
+#include "base64.h"
+#include "sechash.h"
+#include "plhash.h"
+
+#include "cdbhdl.h"
+
+/* forward declaration */
+NSSLOWCERTCertificate *
+nsslowcert_FindCertByDERCertNoLocking(NSSLOWCERTCertDBHandle *handle, SECItem *derCert);
+
+/*
+ * the following functions are wrappers for the db library that implement
+ * a global lock to make the database thread safe.
+ */
+static PZLock *dbLock = NULL;
+
+void
+certdb_InitDBLock(NSSLOWCERTCertDBHandle *handle)
+{
+ if (dbLock == NULL) {
+ nss_InitLock(&dbLock, nssILockCertDB);
+ PORT_Assert(dbLock != NULL);
+ }
+
+ return;
+}
+
+/*
+ * Acquire the global lock on the cert database.
+ * This lock is currently used for the following operations:
+ * adding or deleting a cert to either the temp or perm databases
+ * converting a temp to perm or perm to temp
+ * changing(maybe just adding????) the trust of a cert
+ * chaning the DB status checking Configuration
+ */
+static void
+nsslowcert_LockDB(NSSLOWCERTCertDBHandle *handle)
+{
+ PZ_EnterMonitor(handle->dbMon);
+ return;
+}
+
+/*
+ * Free the global cert database lock.
+ */
+static void
+nsslowcert_UnlockDB(NSSLOWCERTCertDBHandle *handle)
+{
+ PRStatus prstat;
+
+ prstat = PZ_ExitMonitor(handle->dbMon);
+
+ PORT_Assert(prstat == PR_SUCCESS);
+
+ return;
+}
+
+static PZLock *certRefCountLock = NULL;
+
+/*
+ * Acquire the cert reference count lock
+ * There is currently one global lock for all certs, but I'm putting a cert
+ * arg here so that it will be easy to make it per-cert in the future if
+ * that turns out to be necessary.
+ */
+static void
+nsslowcert_LockCertRefCount(NSSLOWCERTCertificate *cert)
+{
+ if ( certRefCountLock == NULL ) {
+ nss_InitLock(&certRefCountLock, nssILockRefLock);
+ PORT_Assert(certRefCountLock != NULL);
+ }
+
+ PZ_Lock(certRefCountLock);
+ return;
+}
+
+/*
+ * Free the cert reference count lock
+ */
+static void
+nsslowcert_UnlockCertRefCount(NSSLOWCERTCertificate *cert)
+{
+ PRStatus prstat;
+
+ PORT_Assert(certRefCountLock != NULL);
+
+ prstat = PZ_Unlock(certRefCountLock);
+
+ PORT_Assert(prstat == PR_SUCCESS);
+
+ return;
+}
+
+static PZLock *certTrustLock = NULL;
+
+/*
+ * Acquire the cert trust lock
+ * There is currently one global lock for all certs, but I'm putting a cert
+ * arg here so that it will be easy to make it per-cert in the future if
+ * that turns out to be necessary.
+ */
+void
+nsslowcert_LockCertTrust(NSSLOWCERTCertificate *cert)
+{
+ if ( certTrustLock == NULL ) {
+ nss_InitLock(&certTrustLock, nssILockCertDB);
+ PORT_Assert(certTrustLock != NULL);
+ }
+
+ PZ_Lock(certTrustLock);
+ return;
+}
+
+/*
+ * Free the cert trust lock
+ */
+void
+nsslowcert_UnlockCertTrust(NSSLOWCERTCertificate *cert)
+{
+ PRStatus prstat;
+
+ PORT_Assert(certTrustLock != NULL);
+
+ prstat = PZ_Unlock(certTrustLock);
+
+ PORT_Assert(prstat == PR_SUCCESS);
+
+ return;
+}
+
+
+static int
+certdb_Get(DB *db, DBT *key, DBT *data, unsigned int flags)
+{
+ PRStatus prstat;
+ int ret;
+
+ PORT_Assert(dbLock != NULL);
+ PZ_Lock(dbLock);
+
+ ret = (* db->get)(db, key, data, flags);
+
+ prstat = PZ_Unlock(dbLock);
+
+ return(ret);
+}
+
+static int
+certdb_Put(DB *db, DBT *key, DBT *data, unsigned int flags)
+{
+ PRStatus prstat;
+ int ret;
+
+ PORT_Assert(dbLock != NULL);
+ PZ_Lock(dbLock);
+
+ ret = (* db->put)(db, key, data, flags);
+
+ prstat = PZ_Unlock(dbLock);
+
+ return(ret);
+}
+
+static int
+certdb_Sync(DB *db, unsigned int flags)
+{
+ PRStatus prstat;
+ int ret;
+
+ PORT_Assert(dbLock != NULL);
+ PZ_Lock(dbLock);
+
+ ret = (* db->sync)(db, flags);
+
+ prstat = PZ_Unlock(dbLock);
+
+ return(ret);
+}
+
+static int
+certdb_Del(DB *db, DBT *key, unsigned int flags)
+{
+ PRStatus prstat;
+ int ret;
+
+ PORT_Assert(dbLock != NULL);
+ PZ_Lock(dbLock);
+
+ ret = (* db->del)(db, key, flags);
+
+ prstat = PZ_Unlock(dbLock);
+
+ return(ret);
+}
+
+static int
+certdb_Seq(DB *db, DBT *key, DBT *data, unsigned int flags)
+{
+ PRStatus prstat;
+ int ret;
+
+ PORT_Assert(dbLock != NULL);
+ PZ_Lock(dbLock);
+
+ ret = (* db->seq)(db, key, data, flags);
+
+ prstat = PZ_Unlock(dbLock);
+
+ return(ret);
+}
+
+static void
+certdb_Close(DB *db)
+{
+ PRStatus prstat;
+
+ PORT_Assert(dbLock != NULL);
+ PZ_Lock(dbLock);
+
+ (* db->close)(db);
+
+ prstat = PZ_Unlock(dbLock);
+
+ return;
+}
+
+/* forward references */
+static void nsslowcert_DestroyCertificateNoLocking(NSSLOWCERTCertificate *cert);
+
+static SECStatus
+DeleteDBEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryType type, SECItem *dbkey)
+{
+ DBT key;
+ int ret;
+
+ /* init the database key */
+ key.data = dbkey->data;
+ key.size = dbkey->len;
+
+ dbkey->data[0] = (unsigned char)type;
+
+ /* delete entry from database */
+ ret = certdb_Del(handle->permCertDB, &key, 0 );
+ if ( ret != 0 ) {
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ goto loser;
+ }
+
+ ret = certdb_Sync(handle->permCertDB, 0);
+ if ( ret ) {
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ goto loser;
+ }
+
+ return(SECSuccess);
+
+loser:
+ return(SECFailure);
+}
+
+static SECStatus
+ReadDBEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCommon *entry,
+ SECItem *dbkey, SECItem *dbentry, PRArenaPool *arena)
+{
+ DBT data, key;
+ int ret;
+ unsigned char *buf;
+
+ /* init the database key */
+ key.data = dbkey->data;
+ key.size = dbkey->len;
+
+ dbkey->data[0] = (unsigned char)entry->type;
+
+ /* read entry from database */
+ ret = certdb_Get(handle->permCertDB, &key, &data, 0 );
+ if ( ret != 0 ) {
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ goto loser;
+ }
+
+ /* validate the entry */
+ if ( data.size < SEC_DB_ENTRY_HEADER_LEN ) {
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ goto loser;
+ }
+ buf = (unsigned char *)data.data;
+ if ( buf[0] != (unsigned char)CERT_DB_FILE_VERSION ) {
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ goto loser;
+ }
+ if ( buf[1] != (unsigned char)entry->type ) {
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ goto loser;
+ }
+
+ /* copy out header information */
+ entry->version = (unsigned int)buf[0];
+ entry->type = (certDBEntryType)buf[1];
+ entry->flags = (unsigned int)buf[2];
+
+ /* format body of entry for return to caller */
+ dbentry->len = data.size - SEC_DB_ENTRY_HEADER_LEN;
+ if ( dbentry->len ) {
+ dbentry->data = (unsigned char *)PORT_ArenaAlloc(arena, dbentry->len);
+ if ( dbentry->data == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ PORT_Memcpy(dbentry->data, &buf[SEC_DB_ENTRY_HEADER_LEN],
+ dbentry->len);
+ } else {
+ dbentry->data = NULL;
+ }
+
+ return(SECSuccess);
+
+loser:
+ return(SECFailure);
+}
+
+/**
+ ** Implement low level database access
+ **/
+static SECStatus
+WriteDBEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCommon *entry,
+ SECItem *dbkey, SECItem *dbentry)
+{
+ int ret;
+ DBT data, key;
+ unsigned char *buf;
+
+ data.data = dbentry->data;
+ data.size = dbentry->len;
+
+ buf = (unsigned char*)data.data;
+
+ buf[0] = (unsigned char)entry->version;
+ buf[1] = (unsigned char)entry->type;
+ buf[2] = (unsigned char)entry->flags;
+
+ key.data = dbkey->data;
+ key.size = dbkey->len;
+
+ dbkey->data[0] = (unsigned char)entry->type;
+
+ /* put the record into the database now */
+ ret = certdb_Put(handle->permCertDB, &key, &data, 0);
+
+ if ( ret != 0 ) {
+ goto loser;
+ }
+
+ ret = certdb_Sync( handle->permCertDB, 0 );
+
+ if ( ret ) {
+ goto loser;
+ }
+
+ return(SECSuccess);
+
+loser:
+ return(SECFailure);
+}
+
+/*
+ * encode a database cert record
+ */
+static SECStatus
+EncodeDBCertEntry(certDBEntryCert *entry, PRArenaPool *arena, SECItem *dbitem)
+{
+ unsigned int nnlen;
+ unsigned char *buf;
+ char *nn;
+ char zbuf = 0;
+
+ if ( entry->nickname ) {
+ nn = entry->nickname;
+ } else {
+ nn = &zbuf;
+ }
+ nnlen = PORT_Strlen(nn) + 1;
+
+ /* allocate space for encoded database record, including space
+ * for low level header
+ */
+ dbitem->len = entry->derCert.len + nnlen + DB_CERT_ENTRY_HEADER_LEN +
+ SEC_DB_ENTRY_HEADER_LEN;
+
+ dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len);
+ if ( dbitem->data == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ /* fill in database record */
+ buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN];
+
+ buf[0] = ( entry->trust.sslFlags >> 8 ) & 0xff;
+ buf[1] = entry->trust.sslFlags & 0xff;
+ buf[2] = ( entry->trust.emailFlags >> 8 ) & 0xff;
+ buf[3] = entry->trust.emailFlags & 0xff;
+ buf[4] = ( entry->trust.objectSigningFlags >> 8 ) & 0xff;
+ buf[5] = entry->trust.objectSigningFlags & 0xff;
+ buf[6] = ( entry->derCert.len >> 8 ) & 0xff;
+ buf[7] = entry->derCert.len & 0xff;
+ buf[8] = ( nnlen >> 8 ) & 0xff;
+ buf[9] = nnlen & 0xff;
+
+ PORT_Memcpy(&buf[DB_CERT_ENTRY_HEADER_LEN], entry->derCert.data,
+ entry->derCert.len);
+
+ PORT_Memcpy(&buf[DB_CERT_ENTRY_HEADER_LEN + entry->derCert.len],
+ nn, nnlen);
+
+ return(SECSuccess);
+
+loser:
+ return(SECFailure);
+}
+
+/*
+ * encode a database key for a cert record
+ */
+static SECStatus
+EncodeDBCertKey(SECItem *certKey, PRArenaPool *arena, SECItem *dbkey)
+{
+ dbkey->len = certKey->len + SEC_DB_KEY_HEADER_LEN;
+ dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
+ if ( dbkey->data == NULL ) {
+ goto loser;
+ }
+ PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN],
+ certKey->data, certKey->len);
+ dbkey->data[0] = certDBEntryTypeCert;
+
+ return(SECSuccess);
+loser:
+ return(SECFailure);
+}
+
+static SECStatus
+EncodeDBGenericKey(SECItem *certKey, PRArenaPool *arena, SECItem *dbkey,
+ certDBEntryType entryType)
+{
+ /*
+ * we only allow _one_ KRL key!
+ */
+ if (entryType == certDBEntryTypeKeyRevocation) {
+ dbkey->len = SEC_DB_KEY_HEADER_LEN;
+ dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
+ if ( dbkey->data == NULL ) {
+ goto loser;
+ }
+ dbkey->data[0] = (unsigned char) entryType;
+ return(SECSuccess);
+ }
+
+
+ dbkey->len = certKey->len + SEC_DB_KEY_HEADER_LEN;
+ dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
+ if ( dbkey->data == NULL ) {
+ goto loser;
+ }
+ PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN],
+ certKey->data, certKey->len);
+ dbkey->data[0] = (unsigned char) entryType;
+
+ return(SECSuccess);
+loser:
+ return(SECFailure);
+}
+
+static SECStatus
+DecodeDBCertEntry(certDBEntryCert *entry, SECItem *dbentry)
+{
+ unsigned int nnlen;
+ int headerlen;
+ int lenoff;
+
+ /* allow updates of old versions of the database */
+ switch ( entry->common.version ) {
+ case 5:
+ headerlen = DB_CERT_V5_ENTRY_HEADER_LEN;
+ lenoff = 3;
+ break;
+ case 6:
+ /* should not get here */
+ PORT_Assert(0);
+ headerlen = DB_CERT_V6_ENTRY_HEADER_LEN;
+ lenoff = 3;
+ break;
+ case 7:
+ headerlen = DB_CERT_ENTRY_HEADER_LEN;
+ lenoff = 6;
+ break;
+ default:
+ /* better not get here */
+ PORT_Assert(0);
+ headerlen = DB_CERT_V5_ENTRY_HEADER_LEN;
+ lenoff = 3;
+ break;
+ }
+
+ /* is record long enough for header? */
+ if ( dbentry->len < headerlen ) {
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ goto loser;
+ }
+
+ /* is database entry correct length? */
+ entry->derCert.len = ( ( dbentry->data[lenoff] << 8 ) |
+ dbentry->data[lenoff+1] );
+ nnlen = ( ( dbentry->data[lenoff+2] << 8 ) | dbentry->data[lenoff+3] );
+ if ( ( entry->derCert.len + nnlen + headerlen )
+ != dbentry->len) {
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ goto loser;
+ }
+
+ /* copy the dercert */
+ entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(entry->common.arena,
+ entry->derCert.len);
+ if ( entry->derCert.data == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+ PORT_Memcpy(entry->derCert.data, &dbentry->data[headerlen],
+ entry->derCert.len);
+
+ /* copy the nickname */
+ if ( nnlen > 1 ) {
+ entry->nickname = (char *)PORT_ArenaAlloc(entry->common.arena, nnlen);
+ if ( entry->nickname == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+ PORT_Memcpy(entry->nickname,
+ &dbentry->data[headerlen +
+ entry->derCert.len],
+ nnlen);
+ } else {
+ entry->nickname = NULL;
+ }
+
+ if ( entry->common.version < 7 ) {
+ /* allow updates of v5 db */
+ entry->trust.sslFlags = dbentry->data[0];
+ entry->trust.emailFlags = dbentry->data[1];
+ entry->trust.objectSigningFlags = dbentry->data[2];
+ } else {
+ entry->trust.sslFlags = ( dbentry->data[0] << 8 ) | dbentry->data[1];
+ entry->trust.emailFlags = ( dbentry->data[2] << 8 ) | dbentry->data[3];
+ entry->trust.objectSigningFlags =
+ ( dbentry->data[4] << 8 ) | dbentry->data[5];
+ }
+
+ return(SECSuccess);
+loser:
+ return(SECFailure);
+}
+
+
+/*
+ * Create a new certDBEntryCert from existing data
+ */
+static certDBEntryCert *
+NewDBCertEntry(SECItem *derCert, char *nickname,
+ NSSLOWCERTCertTrust *trust, int flags)
+{
+ certDBEntryCert *entry;
+ PRArenaPool *arena = NULL;
+ int nnlen;
+
+ arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE );
+
+ if ( !arena ) {
+ goto loser;
+ }
+
+ entry = (certDBEntryCert *)PORT_ArenaZAlloc(arena, sizeof(certDBEntryCert));
+
+ if ( entry == NULL ) {
+ goto loser;
+ }
+
+ /* fill in the dbCert */
+ entry->common.arena = arena;
+ entry->common.type = certDBEntryTypeCert;
+ entry->common.version = CERT_DB_FILE_VERSION;
+ entry->common.flags = flags;
+
+ if ( trust ) {
+ entry->trust = *trust;
+ }
+
+ entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(arena, derCert->len);
+ if ( !entry->derCert.data ) {
+ goto loser;
+ }
+ entry->derCert.len = derCert->len;
+ PORT_Memcpy(entry->derCert.data, derCert->data, derCert->len);
+
+ nnlen = ( nickname ? strlen(nickname) + 1 : 0 );
+
+ if ( nnlen ) {
+ entry->nickname = (char *)PORT_ArenaAlloc(arena, nnlen);
+ if ( !entry->nickname ) {
+ goto loser;
+ }
+ PORT_Memcpy(entry->nickname, nickname, nnlen);
+
+ } else {
+ entry->nickname = 0;
+ }
+
+ return(entry);
+
+loser:
+
+ /* allocation error, free arena and return */
+ if ( arena ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return(0);
+}
+
+/*
+ * Decode a version 4 DBCert from the byte stream database format
+ * and construct a current database entry struct
+ */
+static certDBEntryCert *
+DecodeV4DBCertEntry(unsigned char *buf, int len)
+{
+ certDBEntryCert *entry;
+ int certlen;
+ int nnlen;
+ PRArenaPool *arena;
+
+ /* make sure length is at least long enough for the header */
+ if ( len < DBCERT_V4_HEADER_LEN ) {
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ return(0);
+ }
+
+ /* get other lengths */
+ certlen = buf[3] << 8 | buf[4];
+ nnlen = buf[5] << 8 | buf[6];
+
+ /* make sure DB entry is the right size */
+ if ( ( certlen + nnlen + DBCERT_V4_HEADER_LEN ) != len ) {
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ return(0);
+ }
+
+ /* allocate arena */
+ arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE );
+
+ if ( !arena ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return(0);
+ }
+
+ /* allocate structure and members */
+ entry = (certDBEntryCert *) PORT_ArenaAlloc(arena, sizeof(certDBEntryCert));
+
+ if ( !entry ) {
+ goto loser;
+ }
+
+ entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(arena, certlen);
+ if ( !entry->derCert.data ) {
+ goto loser;
+ }
+ entry->derCert.len = certlen;
+
+ if ( nnlen ) {
+ entry->nickname = (char *) PORT_ArenaAlloc(arena, nnlen);
+ if ( !entry->nickname ) {
+ goto loser;
+ }
+ } else {
+ entry->nickname = 0;
+ }
+
+ entry->common.arena = arena;
+ entry->common.version = CERT_DB_FILE_VERSION;
+ entry->common.type = certDBEntryTypeCert;
+ entry->common.flags = 0;
+ entry->trust.sslFlags = buf[0];
+ entry->trust.emailFlags = buf[1];
+ entry->trust.objectSigningFlags = buf[2];
+
+ PORT_Memcpy(entry->derCert.data, &buf[DBCERT_V4_HEADER_LEN], certlen);
+ PORT_Memcpy(entry->nickname, &buf[DBCERT_V4_HEADER_LEN + certlen], nnlen);
+
+ if (PORT_Strcmp(entry->nickname,"Server-Cert") == 0) {
+ entry->trust.sslFlags |= CERTDB_USER;
+ }
+
+ return(entry);
+
+loser:
+ PORT_FreeArena(arena, PR_FALSE);
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return(0);
+}
+
+/*
+ * Encode a Certificate database entry into byte stream suitable for
+ * the database
+ */
+static SECStatus
+WriteDBCertEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCert *entry)
+{
+ SECItem dbitem, dbkey;
+ PRArenaPool *tmparena = NULL;
+ SECItem tmpitem;
+ SECStatus rv;
+
+ tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( tmparena == NULL ) {
+ goto loser;
+ }
+
+ rv = EncodeDBCertEntry(entry, tmparena, &dbitem);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ /* get the database key and format it */
+ rv = nsslowcert_KeyFromDERCert(tmparena, &entry->derCert, &tmpitem);
+ if ( rv == SECFailure ) {
+ goto loser;
+ }
+
+ rv = EncodeDBCertKey(&tmpitem, tmparena, &dbkey);
+ if ( rv == SECFailure ) {
+ goto loser;
+ }
+
+ /* now write it to the database */
+ rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ PORT_FreeArena(tmparena, PR_FALSE);
+ return(SECSuccess);
+
+loser:
+ if ( tmparena ) {
+ PORT_FreeArena(tmparena, PR_FALSE);
+ }
+ return(SECFailure);
+}
+
+
+/*
+ * delete a certificate entry
+ */
+static SECStatus
+DeleteDBCertEntry(NSSLOWCERTCertDBHandle *handle, SECItem *certKey)
+{
+ SECItem dbkey;
+ PRArenaPool *arena = NULL;
+ SECStatus rv;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( arena == NULL ) {
+ goto loser;
+ }
+
+ rv = EncodeDBCertKey(certKey, arena, &dbkey);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ rv = DeleteDBEntry(handle, certDBEntryTypeCert, &dbkey);
+ if ( rv == SECFailure ) {
+ goto loser;
+ }
+
+ PORT_FreeArena(arena, PR_FALSE);
+ return(SECSuccess);
+
+loser:
+ if ( arena ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ return(SECFailure);
+}
+
+/*
+ * Read a certificate entry
+ */
+static certDBEntryCert *
+ReadDBCertEntry(NSSLOWCERTCertDBHandle *handle, SECItem *certKey)
+{
+ PRArenaPool *arena = NULL;
+ PRArenaPool *tmparena = NULL;
+ certDBEntryCert *entry;
+ SECItem dbkey;
+ SECItem dbentry;
+ SECStatus rv;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( arena == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( tmparena == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ entry = (certDBEntryCert *)PORT_ArenaAlloc(arena, sizeof(certDBEntryCert));
+ if ( entry == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+ entry->common.arena = arena;
+ entry->common.type = certDBEntryTypeCert;
+
+ rv = EncodeDBCertKey(certKey, tmparena, &dbkey);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);
+ if ( rv == SECFailure ) {
+ goto loser;
+ }
+
+ rv = DecodeDBCertEntry(entry, &dbentry);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ PORT_FreeArena(tmparena, PR_FALSE);
+ return(entry);
+
+loser:
+ if ( tmparena ) {
+ PORT_FreeArena(tmparena, PR_FALSE);
+ }
+ if ( arena ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ return(NULL);
+}
+
+/*
+ * encode a database cert record
+ */
+static SECStatus
+EncodeDBCrlEntry(certDBEntryRevocation *entry, PRArenaPool *arena, SECItem *dbitem)
+{
+ unsigned int nnlen = 0;
+ unsigned char *buf;
+
+ if (entry->url) {
+ nnlen = PORT_Strlen(entry->url) + 1;
+ }
+
+ /* allocate space for encoded database record, including space
+ * for low level header
+ */
+ dbitem->len = entry->derCrl.len + nnlen
+ + SEC_DB_ENTRY_HEADER_LEN + DB_CRL_ENTRY_HEADER_LEN;
+
+ dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len);
+ if ( dbitem->data == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ /* fill in database record */
+ buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN];
+
+ buf[0] = ( entry->derCrl.len >> 8 ) & 0xff;
+ buf[1] = entry->derCrl.len & 0xff;
+ buf[2] = ( nnlen >> 8 ) & 0xff;
+ buf[3] = nnlen & 0xff;
+
+ PORT_Memcpy(&buf[DB_CRL_ENTRY_HEADER_LEN], entry->derCrl.data,
+ entry->derCrl.len);
+
+ if (nnlen != 0) {
+ PORT_Memcpy(&buf[DB_CRL_ENTRY_HEADER_LEN + entry->derCrl.len],
+ entry->url, nnlen);
+ }
+
+ return(SECSuccess);
+
+loser:
+ return(SECFailure);
+}
+
+static SECStatus
+DecodeDBCrlEntry(certDBEntryRevocation *entry, SECItem *dbentry)
+{
+ unsigned int nnlen;
+
+ /* is record long enough for header? */
+ if ( dbentry->len < DB_CRL_ENTRY_HEADER_LEN ) {
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ goto loser;
+ }
+
+ /* is database entry correct length? */
+ entry->derCrl.len = ( ( dbentry->data[0] << 8 ) | dbentry->data[1] );
+ nnlen = ( ( dbentry->data[2] << 8 ) | dbentry->data[3] );
+ if ( ( entry->derCrl.len + nnlen + DB_CRL_ENTRY_HEADER_LEN )
+ != dbentry->len) {
+ /* CRL entry is greater than 64 K. Hack to make this continue to work */
+ if (dbentry->len >= (0xffff - DB_CRL_ENTRY_HEADER_LEN) - nnlen) {
+ entry->derCrl.len =
+ (dbentry->len - DB_CRL_ENTRY_HEADER_LEN) - nnlen;
+ } else {
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ goto loser;
+ }
+ }
+
+ /* copy the dercert */
+ entry->derCrl.data = (unsigned char *)PORT_ArenaAlloc(entry->common.arena,
+ entry->derCrl.len);
+ if ( entry->derCrl.data == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+ PORT_Memcpy(entry->derCrl.data, &dbentry->data[DB_CRL_ENTRY_HEADER_LEN],
+ entry->derCrl.len);
+
+ /* copy the url */
+ entry->url = NULL;
+ if (nnlen != 0) {
+ entry->url = (char *)PORT_ArenaAlloc(entry->common.arena, nnlen);
+ if ( entry->url == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+ PORT_Memcpy(entry->url,
+ &dbentry->data[DB_CRL_ENTRY_HEADER_LEN + entry->derCrl.len],
+ nnlen);
+ }
+
+ return(SECSuccess);
+loser:
+ return(SECFailure);
+}
+
+/*
+ * Create a new certDBEntryRevocation from existing data
+ */
+static certDBEntryRevocation *
+NewDBCrlEntry(SECItem *derCrl, char * url, certDBEntryType crlType, int flags)
+{
+ certDBEntryRevocation *entry;
+ PRArenaPool *arena = NULL;
+ int nnlen;
+
+ arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE );
+
+ if ( !arena ) {
+ goto loser;
+ }
+
+ entry = (certDBEntryRevocation*)
+ PORT_ArenaZAlloc(arena, sizeof(certDBEntryRevocation));
+
+ if ( entry == NULL ) {
+ goto loser;
+ }
+
+ /* fill in the dbRevolcation */
+ entry->common.arena = arena;
+ entry->common.type = crlType;
+ entry->common.version = CERT_DB_FILE_VERSION;
+ entry->common.flags = flags;
+
+
+ entry->derCrl.data = (unsigned char *)PORT_ArenaAlloc(arena, derCrl->len);
+ if ( !entry->derCrl.data ) {
+ goto loser;
+ }
+
+ if (url) {
+ nnlen = PORT_Strlen(url) + 1;
+ entry->url = (char *)PORT_ArenaAlloc(arena, nnlen);
+ if ( !entry->url ) {
+ goto loser;
+ }
+ PORT_Memcpy(entry->url, url, nnlen);
+ } else {
+ entry->url = NULL;
+ }
+
+
+ entry->derCrl.len = derCrl->len;
+ PORT_Memcpy(entry->derCrl.data, derCrl->data, derCrl->len);
+
+ return(entry);
+
+loser:
+
+ /* allocation error, free arena and return */
+ if ( arena ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return(0);
+}
+
+
+static SECStatus
+WriteDBCrlEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryRevocation *entry,
+ SECItem *crlKey )
+{
+ SECItem dbkey;
+ PRArenaPool *tmparena = NULL;
+ SECItem encodedEntry;
+ SECStatus rv;
+
+ tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( tmparena == NULL ) {
+ goto loser;
+ }
+
+ rv = EncodeDBCrlEntry(entry, tmparena, &encodedEntry);
+ if ( rv == SECFailure ) {
+ goto loser;
+ }
+
+ rv = EncodeDBGenericKey(crlKey, tmparena, &dbkey, entry->common.type);
+ if ( rv == SECFailure ) {
+ goto loser;
+ }
+
+ /* now write it to the database */
+ rv = WriteDBEntry(handle, &entry->common, &dbkey, &encodedEntry);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ PORT_FreeArena(tmparena, PR_FALSE);
+ return(SECSuccess);
+
+loser:
+ if ( tmparena ) {
+ PORT_FreeArena(tmparena, PR_FALSE);
+ }
+ return(SECFailure);
+}
+/*
+ * delete a crl entry
+ */
+static SECStatus
+DeleteDBCrlEntry(NSSLOWCERTCertDBHandle *handle, SECItem *crlKey,
+ certDBEntryType crlType)
+{
+ SECItem dbkey;
+ PRArenaPool *arena = NULL;
+ SECStatus rv;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( arena == NULL ) {
+ goto loser;
+ }
+
+ rv = EncodeDBGenericKey(crlKey, arena, &dbkey, crlType);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ rv = DeleteDBEntry(handle, crlType, &dbkey);
+ if ( rv == SECFailure ) {
+ goto loser;
+ }
+
+ PORT_FreeArena(arena, PR_FALSE);
+ return(SECSuccess);
+
+loser:
+ if ( arena ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ return(SECFailure);
+}
+
+/*
+ * Read a certificate entry
+ */
+static certDBEntryRevocation *
+ReadDBCrlEntry(NSSLOWCERTCertDBHandle *handle, SECItem *certKey,
+ certDBEntryType crlType)
+{
+ PRArenaPool *arena = NULL;
+ PRArenaPool *tmparena = NULL;
+ certDBEntryRevocation *entry;
+ SECItem dbkey;
+ SECItem dbentry;
+ SECStatus rv;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( arena == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( tmparena == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ entry = (certDBEntryRevocation *)
+ PORT_ArenaAlloc(arena, sizeof(certDBEntryRevocation));
+ if ( entry == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+ entry->common.arena = arena;
+ entry->common.type = crlType;
+
+ rv = EncodeDBGenericKey(certKey, tmparena, &dbkey, crlType);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);
+ if ( rv == SECFailure ) {
+ goto loser;
+ }
+
+ rv = DecodeDBCrlEntry(entry, &dbentry);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ PORT_FreeArena(tmparena, PR_FALSE);
+ return(entry);
+
+loser:
+ if ( tmparena ) {
+ PORT_FreeArena(tmparena, PR_FALSE);
+ }
+ if ( arena ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ return(NULL);
+}
+
+/*
+ * destroy a database entry
+ */
+static void
+DestroyDBEntry(certDBEntry *entry)
+{
+ PRArenaPool *arena = entry->common.arena;
+
+ /* Zero out the entry struct, so that any further attempts to use it
+ * will cause an exception (e.g. null pointer reference). */
+ PORT_Memset(&entry->common, 0, sizeof entry->common);
+ PORT_FreeArena(arena, PR_FALSE);
+
+ return;
+}
+
+void
+nsslowcert_DestroyDBEntry(certDBEntry *entry)
+{
+ DestroyDBEntry(entry);
+ return;
+}
+
+/*
+ * Encode a database nickname record
+ */
+static SECStatus
+EncodeDBNicknameEntry(certDBEntryNickname *entry, PRArenaPool *arena,
+ SECItem *dbitem)
+{
+ unsigned char *buf;
+
+ /* allocate space for encoded database record, including space
+ * for low level header
+ */
+ dbitem->len = entry->subjectName.len + DB_NICKNAME_ENTRY_HEADER_LEN +
+ SEC_DB_ENTRY_HEADER_LEN;
+
+ dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len);
+ if ( dbitem->data == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ /* fill in database record */
+ buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN];
+
+ buf[0] = ( entry->subjectName.len >> 8 ) & 0xff;
+ buf[1] = entry->subjectName.len & 0xff;
+
+ PORT_Memcpy(&buf[DB_NICKNAME_ENTRY_HEADER_LEN], entry->subjectName.data,
+ entry->subjectName.len);
+
+ return(SECSuccess);
+
+loser:
+ return(SECFailure);
+}
+
+/*
+ * Encode a database key for a nickname record
+ */
+static SECStatus
+EncodeDBNicknameKey(char *nickname, PRArenaPool *arena,
+ SECItem *dbkey)
+{
+ unsigned int nnlen;
+
+ nnlen = PORT_Strlen(nickname) + 1; /* includes null */
+
+ /* now get the database key and format it */
+ dbkey->len = nnlen + SEC_DB_KEY_HEADER_LEN;
+ dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
+ if ( dbkey->data == NULL ) {
+ goto loser;
+ }
+ PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], nickname, nnlen);
+ dbkey->data[0] = certDBEntryTypeNickname;
+
+ return(SECSuccess);
+
+loser:
+ return(SECFailure);
+}
+
+static SECStatus
+DecodeDBNicknameEntry(certDBEntryNickname *entry, SECItem *dbentry,
+ char *nickname)
+{
+ /* is record long enough for header? */
+ if ( dbentry->len < DB_NICKNAME_ENTRY_HEADER_LEN ) {
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ goto loser;
+ }
+
+ /* is database entry correct length? */
+ entry->subjectName.len = ( ( dbentry->data[0] << 8 ) | dbentry->data[1] );
+ if (( entry->subjectName.len + DB_NICKNAME_ENTRY_HEADER_LEN ) !=
+ dbentry->len ){
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ goto loser;
+ }
+
+ /* copy the certkey */
+ entry->subjectName.data =
+ (unsigned char *)PORT_ArenaAlloc(entry->common.arena,
+ entry->subjectName.len);
+ if ( entry->subjectName.data == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+ PORT_Memcpy(entry->subjectName.data,
+ &dbentry->data[DB_NICKNAME_ENTRY_HEADER_LEN],
+ entry->subjectName.len);
+
+ entry->nickname = (char *)PORT_ArenaAlloc(entry->common.arena,
+ PORT_Strlen(nickname)+1);
+ if ( entry->nickname ) {
+ PORT_Strcpy(entry->nickname, nickname);
+ }
+
+ return(SECSuccess);
+
+loser:
+ return(SECFailure);
+}
+
+/*
+ * create a new nickname entry
+ */
+static certDBEntryNickname *
+NewDBNicknameEntry(char *nickname, SECItem *subjectName, unsigned int flags)
+{
+ PRArenaPool *arena = NULL;
+ certDBEntryNickname *entry;
+ int nnlen;
+ SECStatus rv;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( arena == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ entry = (certDBEntryNickname *)PORT_ArenaAlloc(arena,
+ sizeof(certDBEntryNickname));
+ if ( entry == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ /* init common fields */
+ entry->common.arena = arena;
+ entry->common.type = certDBEntryTypeNickname;
+ entry->common.version = CERT_DB_FILE_VERSION;
+ entry->common.flags = flags;
+
+ /* copy the nickname */
+ nnlen = PORT_Strlen(nickname) + 1;
+
+ entry->nickname = (char*)PORT_ArenaAlloc(arena, nnlen);
+ if ( entry->nickname == NULL ) {
+ goto loser;
+ }
+
+ PORT_Memcpy(entry->nickname, nickname, nnlen);
+
+ rv = SECITEM_CopyItem(arena, &entry->subjectName, subjectName);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ return(entry);
+loser:
+ if ( arena ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ return(NULL);
+}
+
+/*
+ * delete a nickname entry
+ */
+static SECStatus
+DeleteDBNicknameEntry(NSSLOWCERTCertDBHandle *handle, char *nickname)
+{
+ PRArenaPool *arena = NULL;
+ SECStatus rv;
+ SECItem dbkey;
+
+ if ( nickname == NULL ) {
+ return(SECSuccess);
+ }
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( arena == NULL ) {
+ goto loser;
+ }
+
+ rv = EncodeDBNicknameKey(nickname, arena, &dbkey);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ rv = DeleteDBEntry(handle, certDBEntryTypeNickname, &dbkey);
+ if ( rv == SECFailure ) {
+ goto loser;
+ }
+
+ PORT_FreeArena(arena, PR_FALSE);
+ return(SECSuccess);
+
+loser:
+ if ( arena ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ return(SECFailure);
+}
+
+/*
+ * Read a nickname entry
+ */
+static certDBEntryNickname *
+ReadDBNicknameEntry(NSSLOWCERTCertDBHandle *handle, char *nickname)
+{
+ PRArenaPool *arena = NULL;
+ PRArenaPool *tmparena = NULL;
+ certDBEntryNickname *entry;
+ SECItem dbkey;
+ SECItem dbentry;
+ SECStatus rv;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( arena == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( tmparena == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ entry = (certDBEntryNickname *)PORT_ArenaAlloc(arena,
+ sizeof(certDBEntryNickname));
+ if ( entry == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+ entry->common.arena = arena;
+ entry->common.type = certDBEntryTypeNickname;
+
+ rv = EncodeDBNicknameKey(nickname, tmparena, &dbkey);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);
+ if ( rv == SECFailure ) {
+ goto loser;
+ }
+
+ /* is record long enough for header? */
+ if ( dbentry.len < DB_NICKNAME_ENTRY_HEADER_LEN ) {
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ goto loser;
+ }
+
+ rv = DecodeDBNicknameEntry(entry, &dbentry, nickname);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ PORT_FreeArena(tmparena, PR_FALSE);
+ return(entry);
+
+loser:
+ if ( tmparena ) {
+ PORT_FreeArena(tmparena, PR_FALSE);
+ }
+ if ( arena ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ return(NULL);
+}
+
+/*
+ * Encode a nickname entry into byte stream suitable for
+ * the database
+ */
+static SECStatus
+WriteDBNicknameEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryNickname *entry)
+{
+ SECItem dbitem, dbkey;
+ PRArenaPool *tmparena = NULL;
+ SECStatus rv;
+
+ tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( tmparena == NULL ) {
+ goto loser;
+ }
+
+ rv = EncodeDBNicknameEntry(entry, tmparena, &dbitem);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ rv = EncodeDBNicknameKey(entry->nickname, tmparena, &dbkey);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ /* now write it to the database */
+ rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ PORT_FreeArena(tmparena, PR_FALSE);
+ return(SECSuccess);
+
+loser:
+ if ( tmparena ) {
+ PORT_FreeArena(tmparena, PR_FALSE);
+ }
+ return(SECFailure);
+
+}
+
+SECStatus
+EncodeDBSMimeEntry(certDBEntrySMime *entry, PRArenaPool *arena,
+ SECItem *dbitem)
+{
+ unsigned char *buf;
+
+ /* allocate space for encoded database record, including space
+ * for low level header
+ */
+ dbitem->len = entry->subjectName.len + entry->smimeOptions.len +
+ entry->optionsDate.len +
+ DB_SMIME_ENTRY_HEADER_LEN + SEC_DB_ENTRY_HEADER_LEN;
+
+ dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len);
+ if ( dbitem->data == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ /* fill in database record */
+ buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN];
+
+ buf[0] = ( entry->subjectName.len >> 8 ) & 0xff;
+ buf[1] = entry->subjectName.len & 0xff;
+ buf[2] = ( entry->smimeOptions.len >> 8 ) & 0xff;
+ buf[3] = entry->smimeOptions.len & 0xff;
+ buf[4] = ( entry->optionsDate.len >> 8 ) & 0xff;
+ buf[5] = entry->optionsDate.len & 0xff;
+
+ /* if no smime options, then there should not be an options date either */
+ PORT_Assert( ! ( ( entry->smimeOptions.len == 0 ) &&
+ ( entry->optionsDate.len != 0 ) ) );
+
+ PORT_Memcpy(&buf[DB_SMIME_ENTRY_HEADER_LEN], entry->subjectName.data,
+ entry->subjectName.len);
+ if ( entry->smimeOptions.len ) {
+ PORT_Memcpy(&buf[DB_SMIME_ENTRY_HEADER_LEN+entry->subjectName.len],
+ entry->smimeOptions.data,
+ entry->smimeOptions.len);
+ PORT_Memcpy(&buf[DB_SMIME_ENTRY_HEADER_LEN + entry->subjectName.len +
+ entry->smimeOptions.len],
+ entry->optionsDate.data,
+ entry->optionsDate.len);
+ }
+
+ return(SECSuccess);
+
+loser:
+ return(SECFailure);
+}
+
+/*
+ * Encode a database key for a SMIME record
+ */
+static SECStatus
+EncodeDBSMimeKey(char *emailAddr, PRArenaPool *arena,
+ SECItem *dbkey)
+{
+ unsigned int addrlen;
+
+ addrlen = PORT_Strlen(emailAddr) + 1; /* includes null */
+
+ /* now get the database key and format it */
+ dbkey->len = addrlen + SEC_DB_KEY_HEADER_LEN;
+ dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
+ if ( dbkey->data == NULL ) {
+ goto loser;
+ }
+ PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], emailAddr, addrlen);
+ dbkey->data[0] = certDBEntryTypeSMimeProfile;
+
+ return(SECSuccess);
+
+loser:
+ return(SECFailure);
+}
+
+/*
+ * Decode a database SMIME record
+ */
+static SECStatus
+DecodeDBSMimeEntry(certDBEntrySMime *entry, SECItem *dbentry, char *emailAddr)
+{
+ /* is record long enough for header? */
+ if ( dbentry->len < DB_SMIME_ENTRY_HEADER_LEN ) {
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ goto loser;
+ }
+
+ /* is database entry correct length? */
+ entry->subjectName.len = ( ( dbentry->data[0] << 8 ) | dbentry->data[1] );
+ entry->smimeOptions.len = ( ( dbentry->data[2] << 8 ) | dbentry->data[3] );
+ entry->optionsDate.len = ( ( dbentry->data[4] << 8 ) | dbentry->data[5] );
+ if (( entry->subjectName.len + entry->smimeOptions.len +
+ entry->optionsDate.len + DB_SMIME_ENTRY_HEADER_LEN ) != dbentry->len){
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ goto loser;
+ }
+
+ /* copy the subject name */
+ entry->subjectName.data =
+ (unsigned char *)PORT_ArenaAlloc(entry->common.arena,
+ entry->subjectName.len);
+ if ( entry->subjectName.data == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+ PORT_Memcpy(entry->subjectName.data,
+ &dbentry->data[DB_SMIME_ENTRY_HEADER_LEN],
+ entry->subjectName.len);
+
+ /* copy the smime options */
+ if ( entry->smimeOptions.len ) {
+ entry->smimeOptions.data =
+ (unsigned char *)PORT_ArenaAlloc(entry->common.arena,
+ entry->smimeOptions.len);
+ if ( entry->smimeOptions.data == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+ PORT_Memcpy(entry->smimeOptions.data,
+ &dbentry->data[DB_SMIME_ENTRY_HEADER_LEN +
+ entry->subjectName.len],
+ entry->smimeOptions.len);
+ }
+ if ( entry->optionsDate.len ) {
+ entry->optionsDate.data =
+ (unsigned char *)PORT_ArenaAlloc(entry->common.arena,
+ entry->optionsDate.len);
+ if ( entry->optionsDate.data == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+ PORT_Memcpy(entry->optionsDate.data,
+ &dbentry->data[DB_SMIME_ENTRY_HEADER_LEN +
+ entry->subjectName.len +
+ entry->smimeOptions.len],
+ entry->optionsDate.len);
+ }
+
+ /* both options and options date must either exist or not exist */
+ if ( ( ( entry->optionsDate.len == 0 ) ||
+ ( entry->smimeOptions.len == 0 ) ) &&
+ entry->smimeOptions.len != entry->optionsDate.len ) {
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ goto loser;
+ }
+
+ entry->emailAddr = (char *)PORT_Alloc(PORT_Strlen(emailAddr)+1);
+ if ( entry->emailAddr ) {
+ PORT_Strcpy(entry->emailAddr, emailAddr);
+ }
+
+ return(SECSuccess);
+
+loser:
+ return(SECFailure);
+}
+
+/*
+ * create a new SMIME entry
+ */
+static certDBEntrySMime *
+NewDBSMimeEntry(char *emailAddr, SECItem *subjectName, SECItem *smimeOptions,
+ SECItem *optionsDate, unsigned int flags)
+{
+ PRArenaPool *arena = NULL;
+ certDBEntrySMime *entry;
+ int addrlen;
+ SECStatus rv;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( arena == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ entry = (certDBEntrySMime *)PORT_ArenaAlloc(arena,
+ sizeof(certDBEntrySMime));
+ if ( entry == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ /* init common fields */
+ entry->common.arena = arena;
+ entry->common.type = certDBEntryTypeSMimeProfile;
+ entry->common.version = CERT_DB_FILE_VERSION;
+ entry->common.flags = flags;
+
+ /* copy the email addr */
+ addrlen = PORT_Strlen(emailAddr) + 1;
+
+ entry->emailAddr = (char*)PORT_ArenaAlloc(arena, addrlen);
+ if ( entry->emailAddr == NULL ) {
+ goto loser;
+ }
+
+ PORT_Memcpy(entry->emailAddr, emailAddr, addrlen);
+
+ /* copy the subject name */
+ rv = SECITEM_CopyItem(arena, &entry->subjectName, subjectName);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ /* copy the smime options */
+ if ( smimeOptions ) {
+ rv = SECITEM_CopyItem(arena, &entry->smimeOptions, smimeOptions);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+ } else {
+ PORT_Assert(optionsDate == NULL);
+ entry->smimeOptions.data = NULL;
+ entry->smimeOptions.len = 0;
+ }
+
+ /* copy the options date */
+ if ( optionsDate ) {
+ rv = SECITEM_CopyItem(arena, &entry->optionsDate, optionsDate);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+ } else {
+ PORT_Assert(smimeOptions == NULL);
+ entry->optionsDate.data = NULL;
+ entry->optionsDate.len = 0;
+ }
+
+ return(entry);
+loser:
+ if ( arena ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ return(NULL);
+}
+
+/*
+ * delete a SMIME entry
+ */
+static SECStatus
+DeleteDBSMimeEntry(NSSLOWCERTCertDBHandle *handle, char *emailAddr)
+{
+ PRArenaPool *arena = NULL;
+ SECStatus rv;
+ SECItem dbkey;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( arena == NULL ) {
+ goto loser;
+ }
+
+ rv = EncodeDBSMimeKey(emailAddr, arena, &dbkey);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ rv = DeleteDBEntry(handle, certDBEntryTypeSMimeProfile, &dbkey);
+ if ( rv == SECFailure ) {
+ goto loser;
+ }
+
+ PORT_FreeArena(arena, PR_FALSE);
+ return(SECSuccess);
+
+loser:
+ if ( arena ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ return(SECFailure);
+}
+
+/*
+ * Read a SMIME entry
+ */
+certDBEntrySMime *
+nsslowcert_ReadDBSMimeEntry(NSSLOWCERTCertDBHandle *handle, char *emailAddr)
+{
+ PRArenaPool *arena = NULL;
+ PRArenaPool *tmparena = NULL;
+ certDBEntrySMime *entry;
+ SECItem dbkey;
+ SECItem dbentry;
+ SECStatus rv;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( arena == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( tmparena == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ entry = (certDBEntrySMime *)PORT_ArenaAlloc(arena,
+ sizeof(certDBEntrySMime));
+ if ( entry == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+ entry->common.arena = arena;
+ entry->common.type = certDBEntryTypeSMimeProfile;
+
+ rv = EncodeDBSMimeKey(emailAddr, tmparena, &dbkey);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);
+ if ( rv == SECFailure ) {
+ goto loser;
+ }
+
+ /* is record long enough for header? */
+ if ( dbentry.len < DB_SMIME_ENTRY_HEADER_LEN ) {
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ goto loser;
+ }
+
+ rv = DecodeDBSMimeEntry(entry, &dbentry, emailAddr);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ PORT_FreeArena(tmparena, PR_FALSE);
+ return(entry);
+
+loser:
+ if ( tmparena ) {
+ PORT_FreeArena(tmparena, PR_FALSE);
+ }
+ if ( arena ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ return(NULL);
+}
+
+/*
+ * Encode a SMIME entry into byte stream suitable for
+ * the database
+ */
+static SECStatus
+WriteDBSMimeEntry(NSSLOWCERTCertDBHandle *handle, certDBEntrySMime *entry)
+{
+ SECItem dbitem, dbkey;
+ PRArenaPool *tmparena = NULL;
+ SECStatus rv;
+
+ tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( tmparena == NULL ) {
+ goto loser;
+ }
+
+ rv = EncodeDBSMimeEntry(entry, tmparena, &dbitem);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ rv = EncodeDBSMimeKey(entry->emailAddr, tmparena, &dbkey);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ /* now write it to the database */
+ rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ PORT_FreeArena(tmparena, PR_FALSE);
+ return(SECSuccess);
+
+loser:
+ if ( tmparena ) {
+ PORT_FreeArena(tmparena, PR_FALSE);
+ }
+ return(SECFailure);
+
+}
+
+/*
+ * Encode a database subject record
+ */
+static SECStatus
+EncodeDBSubjectEntry(certDBEntrySubject *entry, PRArenaPool *arena,
+ SECItem *dbitem)
+{
+ unsigned char *buf;
+ int len;
+ unsigned int ncerts;
+ unsigned int i;
+ unsigned char *tmpbuf;
+ unsigned int nnlen = 0;
+ unsigned int eaddrlen = 0;
+ int keyidoff;
+ SECItem *certKeys;
+ SECItem *keyIDs;
+
+ if ( entry->nickname ) {
+ nnlen = PORT_Strlen(entry->nickname) + 1;
+ }
+ if ( entry->emailAddr ) {
+ eaddrlen = PORT_Strlen(entry->emailAddr) + 1;
+ }
+
+ ncerts = entry->ncerts;
+
+ /* compute the length of the entry */
+ keyidoff = DB_SUBJECT_ENTRY_HEADER_LEN + nnlen + eaddrlen;
+ len = keyidoff + 4 * ncerts;
+ for ( i = 0; i < ncerts; i++ ) {
+ len += entry->certKeys[i].len;
+ len += entry->keyIDs[i].len;
+ }
+
+ /* allocate space for encoded database record, including space
+ * for low level header
+ */
+ dbitem->len = len + SEC_DB_ENTRY_HEADER_LEN;
+
+ dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len);
+ if ( dbitem->data == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ /* fill in database record */
+ buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN];
+
+ buf[0] = ( ncerts >> 8 ) & 0xff;
+ buf[1] = ncerts & 0xff;
+ buf[2] = ( nnlen >> 8 ) & 0xff;
+ buf[3] = nnlen & 0xff;
+ buf[4] = ( eaddrlen >> 8 ) & 0xff;
+ buf[5] = eaddrlen & 0xff;
+
+ PORT_Memcpy(&buf[DB_SUBJECT_ENTRY_HEADER_LEN], entry->nickname, nnlen);
+ PORT_Memcpy(&buf[DB_SUBJECT_ENTRY_HEADER_LEN+nnlen], entry->emailAddr,
+ eaddrlen);
+
+ for ( i = 0; i < ncerts; i++ ) {
+
+ certKeys = entry->certKeys;
+ keyIDs = entry->keyIDs;
+
+ buf[keyidoff+i*2] = ( certKeys[i].len >> 8 ) & 0xff;
+ buf[keyidoff+1+i*2] = certKeys[i].len & 0xff;
+ buf[keyidoff+ncerts*2+i*2] = ( keyIDs[i].len >> 8 ) & 0xff;
+ buf[keyidoff+1+ncerts*2+i*2] = keyIDs[i].len & 0xff;
+ }
+
+ /* temp pointer used to stuff certkeys and keyids into the buffer */
+ tmpbuf = &buf[keyidoff+ncerts*4];
+
+ for ( i = 0; i < ncerts; i++ ) {
+ certKeys = entry->certKeys;
+ PORT_Memcpy(tmpbuf, certKeys[i].data, certKeys[i].len);
+ tmpbuf = tmpbuf + certKeys[i].len;
+ }
+
+ for ( i = 0; i < ncerts; i++ ) {
+ keyIDs = entry->keyIDs;
+ PORT_Memcpy(tmpbuf, keyIDs[i].data, keyIDs[i].len);
+ tmpbuf = tmpbuf + keyIDs[i].len;
+ }
+
+ PORT_Assert(tmpbuf == &buf[len]);
+
+ return(SECSuccess);
+
+loser:
+ return(SECFailure);
+}
+
+/*
+ * Encode a database key for a subject record
+ */
+static SECStatus
+EncodeDBSubjectKey(SECItem *derSubject, PRArenaPool *arena,
+ SECItem *dbkey)
+{
+ dbkey->len = derSubject->len + SEC_DB_KEY_HEADER_LEN;
+ dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
+ if ( dbkey->data == NULL ) {
+ goto loser;
+ }
+ PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], derSubject->data,
+ derSubject->len);
+ dbkey->data[0] = certDBEntryTypeSubject;
+
+ return(SECSuccess);
+
+loser:
+ return(SECFailure);
+}
+
+static SECStatus
+DecodeDBSubjectEntry(certDBEntrySubject *entry, SECItem *dbentry,
+ SECItem *derSubject)
+{
+ unsigned int ncerts;
+ PRArenaPool *arena;
+ unsigned int len, itemlen;
+ unsigned char *tmpbuf;
+ unsigned int i;
+ SECStatus rv;
+ unsigned int keyidoff;
+ unsigned int nnlen, eaddrlen;
+
+ arena = entry->common.arena;
+
+ rv = SECITEM_CopyItem(arena, &entry->derSubject, derSubject);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ /* is record long enough for header? */
+ if ( dbentry->len < DB_SUBJECT_ENTRY_HEADER_LEN ) {
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ goto loser;
+ }
+
+ entry->ncerts = ncerts = ( ( dbentry->data[0] << 8 ) | dbentry->data[1] );
+ nnlen = ( ( dbentry->data[2] << 8 ) | dbentry->data[3] );
+ eaddrlen = ( ( dbentry->data[4] << 8 ) | dbentry->data[5] );
+ if ( dbentry->len < ( ncerts * 4 + DB_SUBJECT_ENTRY_HEADER_LEN +
+ nnlen + eaddrlen) ) {
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ goto loser;
+ }
+
+ entry->certKeys = (SECItem *)PORT_ArenaAlloc(arena,
+ sizeof(SECItem) * ncerts);
+ entry->keyIDs = (SECItem *)PORT_ArenaAlloc(arena,
+ sizeof(SECItem) * ncerts);
+
+ if ( ( entry->certKeys == NULL ) || ( entry->keyIDs == NULL ) ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ if ( nnlen > 1 ) { /* null terminator is stored */
+ entry->nickname = (char *)PORT_ArenaAlloc(arena, nnlen);
+ if ( entry->nickname == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+ PORT_Memcpy(entry->nickname,
+ &dbentry->data[DB_SUBJECT_ENTRY_HEADER_LEN],
+ nnlen);
+ } else {
+ entry->nickname = NULL;
+ }
+
+ if ( eaddrlen > 1 ) { /* null terminator is stored */
+ entry->emailAddr = (char *)PORT_ArenaAlloc(arena, eaddrlen);
+ if ( entry->emailAddr == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+ PORT_Memcpy(entry->emailAddr,
+ &dbentry->data[DB_SUBJECT_ENTRY_HEADER_LEN+nnlen],
+ eaddrlen);
+ } else {
+ entry->emailAddr = NULL;
+ }
+
+ /* collect the lengths of the certKeys and keyIDs, and total the
+ * overall length.
+ */
+ keyidoff = DB_SUBJECT_ENTRY_HEADER_LEN + nnlen + eaddrlen;
+ len = keyidoff + 4 * ncerts;
+
+ tmpbuf = &dbentry->data[0];
+
+ for ( i = 0; i < ncerts; i++ ) {
+
+ itemlen = ( tmpbuf[keyidoff + 2*i] << 8 ) | tmpbuf[keyidoff + 1 + 2*i] ;
+ len += itemlen;
+ entry->certKeys[i].len = itemlen;
+
+ itemlen = ( tmpbuf[keyidoff + 2*ncerts + 2*i] << 8 ) |
+ tmpbuf[keyidoff + 1 + 2*ncerts + 2*i] ;
+ len += itemlen;
+ entry->keyIDs[i].len = itemlen;
+ }
+
+ /* is database entry correct length? */
+ if ( len != dbentry->len ){
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ goto loser;
+ }
+
+ tmpbuf = &tmpbuf[keyidoff + 4*ncerts];
+ for ( i = 0; i < ncerts; i++ ) {
+ entry->certKeys[i].data =
+ (unsigned char *)PORT_ArenaAlloc(arena, entry->certKeys[i].len);
+ if ( entry->certKeys[i].data == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+ PORT_Memcpy(entry->certKeys[i].data, tmpbuf, entry->certKeys[i].len);
+ tmpbuf = &tmpbuf[entry->certKeys[i].len];
+ }
+
+ for ( i = 0; i < ncerts; i++ ) {
+ entry->keyIDs[i].data =
+ (unsigned char *)PORT_ArenaAlloc(arena, entry->keyIDs[i].len);
+ if ( entry->keyIDs[i].data == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+ PORT_Memcpy(entry->keyIDs[i].data, tmpbuf, entry->keyIDs[i].len);
+ tmpbuf = &tmpbuf[entry->keyIDs[i].len];
+ }
+
+ PORT_Assert(tmpbuf == &dbentry->data[dbentry->len]);
+
+ return(SECSuccess);
+
+loser:
+ return(SECFailure);
+}
+
+/*
+ * create a new subject entry with a single cert
+ */
+static certDBEntrySubject *
+NewDBSubjectEntry(SECItem *derSubject, SECItem *certKey,
+ SECItem *keyID, char *nickname, char *emailAddr,
+ unsigned int flags)
+{
+ PRArenaPool *arena = NULL;
+ certDBEntrySubject *entry;
+ SECStatus rv;
+ unsigned int nnlen;
+ unsigned int eaddrlen;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( arena == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ entry = (certDBEntrySubject *)PORT_ArenaAlloc(arena,
+ sizeof(certDBEntrySubject));
+ if ( entry == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ /* init common fields */
+ entry->common.arena = arena;
+ entry->common.type = certDBEntryTypeSubject;
+ entry->common.version = CERT_DB_FILE_VERSION;
+ entry->common.flags = flags;
+
+ /* copy the subject */
+ rv = SECITEM_CopyItem(arena, &entry->derSubject, derSubject);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ entry->ncerts = 1;
+ /* copy nickname */
+ if ( nickname && ( *nickname != '\0' ) ) {
+ nnlen = PORT_Strlen(nickname) + 1;
+ entry->nickname = (char *)PORT_ArenaAlloc(arena, nnlen);
+ if ( entry->nickname == NULL ) {
+ goto loser;
+ }
+
+ PORT_Memcpy(entry->nickname, nickname, nnlen);
+ } else {
+ entry->nickname = NULL;
+ }
+
+ /* copy email addr */
+ if ( emailAddr && ( *emailAddr != '\0' ) ) {
+ emailAddr = nsslowcert_FixupEmailAddr(emailAddr);
+ if ( emailAddr == NULL ) {
+ entry->emailAddr = NULL;
+ goto loser;
+ }
+
+ eaddrlen = PORT_Strlen(emailAddr) + 1;
+ entry->emailAddr = (char *)PORT_ArenaAlloc(arena, eaddrlen);
+ if ( entry->emailAddr == NULL ) {
+ PORT_Free(emailAddr);
+ goto loser;
+ }
+
+ PORT_Memcpy(entry->emailAddr, emailAddr, eaddrlen);
+ PORT_Free(emailAddr);
+ } else {
+ entry->emailAddr = NULL;
+ }
+
+ /* allocate space for certKeys and keyIDs */
+ entry->certKeys = (SECItem *)PORT_ArenaAlloc(arena, sizeof(SECItem));
+ entry->keyIDs = (SECItem *)PORT_ArenaAlloc(arena, sizeof(SECItem));
+ if ( ( entry->certKeys == NULL ) || ( entry->keyIDs == NULL ) ) {
+ goto loser;
+ }
+
+ /* copy the certKey and keyID */
+ rv = SECITEM_CopyItem(arena, &entry->certKeys[0], certKey);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+ rv = SECITEM_CopyItem(arena, &entry->keyIDs[0], keyID);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ return(entry);
+loser:
+ if ( arena ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ return(NULL);
+}
+
+/*
+ * delete a subject entry
+ */
+static SECStatus
+DeleteDBSubjectEntry(NSSLOWCERTCertDBHandle *handle, SECItem *derSubject)
+{
+ SECItem dbkey;
+ PRArenaPool *arena = NULL;
+ SECStatus rv;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( arena == NULL ) {
+ goto loser;
+ }
+
+ rv = EncodeDBSubjectKey(derSubject, arena, &dbkey);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ rv = DeleteDBEntry(handle, certDBEntryTypeSubject, &dbkey);
+ if ( rv == SECFailure ) {
+ goto loser;
+ }
+
+ PORT_FreeArena(arena, PR_FALSE);
+ return(SECSuccess);
+
+loser:
+ if ( arena ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ return(SECFailure);
+}
+
+/*
+ * Read the subject entry
+ */
+static certDBEntrySubject *
+ReadDBSubjectEntry(NSSLOWCERTCertDBHandle *handle, SECItem *derSubject)
+{
+ PRArenaPool *arena = NULL;
+ PRArenaPool *tmparena = NULL;
+ certDBEntrySubject *entry;
+ SECItem dbkey;
+ SECItem dbentry;
+ SECStatus rv;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( arena == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( tmparena == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ entry = (certDBEntrySubject *)PORT_ArenaAlloc(arena,
+ sizeof(certDBEntrySubject));
+ if ( entry == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+ entry->common.arena = arena;
+ entry->common.type = certDBEntryTypeSubject;
+
+ rv = EncodeDBSubjectKey(derSubject, tmparena, &dbkey);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);
+ if ( rv == SECFailure ) {
+ goto loser;
+ }
+
+ rv = DecodeDBSubjectEntry(entry, &dbentry, derSubject);
+ if ( rv == SECFailure ) {
+ goto loser;
+ }
+
+ PORT_FreeArena(tmparena, PR_FALSE);
+ return(entry);
+
+loser:
+ if ( tmparena ) {
+ PORT_FreeArena(tmparena, PR_FALSE);
+ }
+ if ( arena ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ return(NULL);
+}
+
+/*
+ * Encode a subject name entry into byte stream suitable for
+ * the database
+ */
+static SECStatus
+WriteDBSubjectEntry(NSSLOWCERTCertDBHandle *handle, certDBEntrySubject *entry)
+{
+ SECItem dbitem, dbkey;
+ PRArenaPool *tmparena = NULL;
+ SECStatus rv;
+
+ tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( tmparena == NULL ) {
+ goto loser;
+ }
+
+ rv = EncodeDBSubjectEntry(entry, tmparena, &dbitem);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ rv = EncodeDBSubjectKey(&entry->derSubject, tmparena, &dbkey);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ /* now write it to the database */
+ rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ PORT_FreeArena(tmparena, PR_FALSE);
+ return(SECSuccess);
+
+loser:
+ if ( tmparena ) {
+ PORT_FreeArena(tmparena, PR_FALSE);
+ }
+ return(SECFailure);
+
+}
+
+static SECStatus
+UpdateSubjectWithEmailAddr(NSSLOWCERTCertDBHandle *dbhandle,
+ SECItem *derSubject, char *emailAddr)
+{
+ PRBool save = PR_FALSE, delold = PR_FALSE;
+ certDBEntrySubject *entry;
+ SECStatus rv;
+
+ if (emailAddr) {
+ emailAddr = nsslowcert_FixupEmailAddr(emailAddr);
+ if (emailAddr == NULL) {
+ return SECFailure;
+ }
+ }
+
+ entry = ReadDBSubjectEntry(dbhandle,derSubject);
+
+ if ( entry->emailAddr ) {
+ if ( (emailAddr == NULL) ||
+ (PORT_Strcmp(entry->emailAddr, emailAddr) != 0) ) {
+ save = PR_TRUE;
+ delold = PR_TRUE;
+ }
+ } else if (emailAddr) {
+ save = PR_TRUE;
+ }
+
+ if ( delold ) {
+ /* delete the old smime entry, because this cert now has a new
+ * smime entry pointing to it
+ */
+ PORT_Assert(save);
+ PORT_Assert(entry->emailAddr != NULL);
+ DeleteDBSMimeEntry(dbhandle, entry->emailAddr);
+ }
+
+ if ( save ) {
+ unsigned int len;
+
+ PORT_Assert(entry != NULL);
+ if (emailAddr) {
+ len = PORT_Strlen(emailAddr) + 1;
+ entry->emailAddr = (char *)PORT_ArenaAlloc(entry->common.arena, len);
+ if ( entry->emailAddr == NULL ) {
+ goto loser;
+ }
+ PORT_Memcpy(entry->emailAddr, emailAddr, len);
+ } else {
+ entry->emailAddr = NULL;
+ }
+
+ /* delete the subject entry */
+ DeleteDBSubjectEntry(dbhandle, derSubject);
+
+ /* write the new one */
+ rv = WriteDBSubjectEntry(dbhandle, entry);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+ }
+
+ if (emailAddr) PORT_Free(emailAddr);
+ return(SECSuccess);
+
+loser:
+ if (emailAddr) PORT_Free(emailAddr);
+ return(SECFailure);
+}
+
+/*
+ * writes a nickname to an existing subject entry that does not currently
+ * have one
+ */
+static SECStatus
+AddNicknameToSubject(NSSLOWCERTCertDBHandle *dbhandle,
+ NSSLOWCERTCertificate *cert, char *nickname)
+{
+ certDBEntrySubject *entry;
+ SECStatus rv;
+
+ if ( nickname == NULL ) {
+ return(SECFailure);
+ }
+
+ entry = ReadDBSubjectEntry(dbhandle,&cert->derSubject);
+ PORT_Assert(entry != NULL);
+ if ( entry == NULL ) {
+ goto loser;
+ }
+
+ PORT_Assert(entry->nickname == NULL);
+ if ( entry->nickname != NULL ) {
+ goto loser;
+ }
+
+ entry->nickname = (nickname) ?
+ PORT_ArenaStrdup(entry->common.arena, nickname) : NULL;
+
+ if ( entry->nickname == NULL ) {
+ goto loser;
+ }
+
+ /* delete the subject entry */
+ DeleteDBSubjectEntry(dbhandle, &cert->derSubject);
+
+ /* write the new one */
+ rv = WriteDBSubjectEntry(dbhandle, entry);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ return(SECSuccess);
+
+loser:
+ return(SECFailure);
+}
+
+/*
+ * create a new version entry
+ */
+static certDBEntryVersion *
+NewDBVersionEntry(unsigned int flags)
+{
+ PRArenaPool *arena = NULL;
+ certDBEntryVersion *entry;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( arena == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ entry = (certDBEntryVersion *)PORT_ArenaAlloc(arena,
+ sizeof(certDBEntryVersion));
+ if ( entry == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+ entry->common.arena = arena;
+ entry->common.type = certDBEntryTypeVersion;
+ entry->common.version = CERT_DB_FILE_VERSION;
+ entry->common.flags = flags;
+
+ return(entry);
+loser:
+ if ( arena ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ return(NULL);
+}
+
+/*
+ * Read the version entry
+ */
+static certDBEntryVersion *
+ReadDBVersionEntry(NSSLOWCERTCertDBHandle *handle)
+{
+ PRArenaPool *arena = NULL;
+ PRArenaPool *tmparena = NULL;
+ certDBEntryVersion *entry;
+ SECItem dbkey;
+ SECItem dbentry;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( arena == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( tmparena == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ entry = (certDBEntryVersion *)PORT_ArenaAlloc(arena,
+ sizeof(certDBEntryVersion));
+ if ( entry == NULL ) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+ entry->common.arena = arena;
+ entry->common.type = certDBEntryTypeVersion;
+
+ /* now get the database key and format it */
+ dbkey.len = SEC_DB_VERSION_KEY_LEN + SEC_DB_KEY_HEADER_LEN;
+ dbkey.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbkey.len);
+ if ( dbkey.data == NULL ) {
+ goto loser;
+ }
+ 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);
+
+ PORT_FreeArena(tmparena, PR_FALSE);
+ return(entry);
+
+loser:
+ if ( tmparena ) {
+ PORT_FreeArena(tmparena, PR_FALSE);
+ }
+ if ( arena ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ return(NULL);
+}
+
+
+/*
+ * Encode a version entry into byte stream suitable for
+ * the database
+ */
+static SECStatus
+WriteDBVersionEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryVersion *entry)
+{
+ SECItem dbitem, dbkey;
+ PRArenaPool *tmparena = NULL;
+ SECStatus rv;
+
+ tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( tmparena == NULL ) {
+ goto loser;
+ }
+
+ /* allocate space for encoded database record, including space
+ * for low level header
+ */
+ dbitem.len = SEC_DB_ENTRY_HEADER_LEN;
+
+ dbitem.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbitem.len);
+ if ( dbitem.data == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ /* now get the database key and format it */
+ dbkey.len = SEC_DB_VERSION_KEY_LEN + SEC_DB_KEY_HEADER_LEN;
+ dbkey.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbkey.len);
+ if ( dbkey.data == NULL ) {
+ goto loser;
+ }
+ PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], SEC_DB_VERSION_KEY,
+ SEC_DB_VERSION_KEY_LEN);
+
+ /* now write it to the database */
+ rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ PORT_FreeArena(tmparena, PR_FALSE);
+ return(SECSuccess);
+
+loser:
+ if ( tmparena ) {
+ PORT_FreeArena(tmparena, PR_FALSE);
+ }
+ return(SECFailure);
+}
+
+/*
+ * cert is no longer a perm cert, but will remain a temp cert
+ */
+static SECStatus
+RemovePermSubjectNode(NSSLOWCERTCertificate *cert)
+{
+ certDBEntrySubject *entry;
+ unsigned int i;
+ SECStatus rv;
+
+ entry = ReadDBSubjectEntry(cert->dbhandle,&cert->derSubject);
+ PORT_Assert(entry);
+ if ( entry == NULL ) {
+ return(SECFailure);
+ }
+
+ PORT_Assert(entry->ncerts);
+ rv = SECFailure;
+
+ if ( entry->ncerts > 1 ) {
+ for ( i = 0; i < entry->ncerts; i++ ) {
+ if ( SECITEM_CompareItem(&entry->certKeys[i], &cert->certKey) ==
+ SECEqual ) {
+ /* copy rest of list forward one entry */
+ for ( i = i + 1; i < entry->ncerts; i++ ) {
+ entry->certKeys[i-1] = entry->certKeys[i];
+ entry->keyIDs[i-1] = entry->keyIDs[i];
+ }
+ entry->ncerts--;
+ DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject);
+ rv = WriteDBSubjectEntry(cert->dbhandle, entry);
+ break;
+ }
+ }
+ } else {
+ /* no entries left, delete the perm entry in the DB */
+ if ( entry->emailAddr ) {
+ /* if the subject had an email record, then delete it too */
+ DeleteDBSMimeEntry(cert->dbhandle, entry->emailAddr);
+ }
+
+ DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject);
+ }
+ DestroyDBEntry((certDBEntry *)entry);
+
+ return(rv);
+}
+
+/*
+ * add a cert to the perm subject list
+ */
+static SECStatus
+AddPermSubjectNode(certDBEntrySubject *entry, NSSLOWCERTCertificate *cert,
+ char *nickname)
+{
+ SECItem *newCertKeys, *newKeyIDs;
+ int i;
+ SECStatus rv;
+ NSSLOWCERTCertificate *cmpcert;
+ unsigned int nnlen;
+ int ncerts;
+
+
+ PORT_Assert(entry);
+ ncerts = entry->ncerts;
+
+ if ( nickname && entry->nickname ) {
+ /* nicknames must be the same */
+ PORT_Assert(PORT_Strcmp(nickname, entry->nickname) == 0);
+ }
+
+ if ( ( entry->nickname == NULL ) && ( nickname != NULL ) ) {
+ /* copy nickname into the entry */
+ nnlen = PORT_Strlen(nickname) + 1;
+ entry->nickname = (char *)PORT_ArenaAlloc(entry->common.arena,nnlen);
+ if ( entry->nickname == NULL ) {
+ return(SECFailure);
+ }
+ PORT_Memcpy(entry->nickname, nickname, nnlen);
+ }
+
+ /* a DB entry already exists, so add this cert */
+ newCertKeys = (SECItem *)PORT_ArenaAlloc(entry->common.arena,
+ sizeof(SECItem) * ( ncerts + 1 ) );
+ newKeyIDs = (SECItem *)PORT_ArenaAlloc(entry->common.arena,
+ sizeof(SECItem) * ( ncerts + 1 ) );
+
+ if ( ( newCertKeys == NULL ) || ( newKeyIDs == NULL ) ) {
+ return(SECFailure);
+ }
+
+ for ( i = 0; i < ncerts; i++ ) {
+ cmpcert = nsslowcert_FindCertByKey(cert->dbhandle,
+ &entry->certKeys[i]);
+ PORT_Assert(cmpcert);
+ if ( nsslowcert_IsNewer(cert, cmpcert) ) {
+ /* insert before cmpcert */
+ rv = SECITEM_CopyItem(entry->common.arena, &newCertKeys[i],
+ &cert->certKey);
+ if ( rv != SECSuccess ) {
+ return(SECFailure);
+ }
+ rv = SECITEM_CopyItem(entry->common.arena, &newKeyIDs[i],
+ &cert->subjectKeyID);
+ if ( rv != SECSuccess ) {
+ return(SECFailure);
+ }
+ /* copy the rest of the entry */
+ for ( ; i < ncerts; i++ ) {
+ newCertKeys[i+1] = entry->certKeys[i];
+ newKeyIDs[i+1] = entry->keyIDs[i];
+ }
+
+ /* update certKeys and keyIDs */
+ entry->certKeys = newCertKeys;
+ entry->keyIDs = newKeyIDs;
+
+ /* increment count */
+ entry->ncerts++;
+ break;
+ }
+ /* copy this cert entry */
+ newCertKeys[i] = entry->certKeys[i];
+ newKeyIDs[i] = entry->keyIDs[i];
+ }
+
+ if ( entry->ncerts == ncerts ) {
+ /* insert new one at end */
+ rv = SECITEM_CopyItem(entry->common.arena, &newCertKeys[ncerts],
+ &cert->certKey);
+ if ( rv != SECSuccess ) {
+ return(SECFailure);
+ }
+ rv = SECITEM_CopyItem(entry->common.arena, &newKeyIDs[ncerts],
+ &cert->subjectKeyID);
+ if ( rv != SECSuccess ) {
+ return(SECFailure);
+ }
+
+ /* update certKeys and keyIDs */
+ entry->certKeys = newCertKeys;
+ entry->keyIDs = newKeyIDs;
+
+ /* increment count */
+ entry->ncerts++;
+ }
+ DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject);
+ rv = WriteDBSubjectEntry(cert->dbhandle, entry);
+ return(rv);
+}
+
+
+SECStatus
+nsslowcert_TraversePermCertsForSubject(NSSLOWCERTCertDBHandle *handle,
+ SECItem *derSubject,
+ NSSLOWCERTCertCallback cb, void *cbarg)
+{
+ certDBEntrySubject *entry;
+ int i;
+ NSSLOWCERTCertificate *cert;
+ SECStatus rv = SECSuccess;
+
+ entry = ReadDBSubjectEntry(handle, derSubject);
+
+ if ( entry == NULL ) {
+ return(SECFailure);
+ }
+
+ for( i = 0; i < entry->ncerts; i++ ) {
+ cert = nsslowcert_FindCertByKey(handle, &entry->certKeys[i]);
+ rv = (* cb)(cert, cbarg);
+ nsslowcert_DestroyCertificate(cert);
+ if ( rv == SECFailure ) {
+ break;
+ }
+ }
+
+ DestroyDBEntry((certDBEntry *)entry);
+
+ return(rv);
+}
+
+int
+nsslowcert_NumPermCertsForSubject(NSSLOWCERTCertDBHandle *handle, SECItem *derSubject)
+{
+ certDBEntrySubject *entry;
+ int ret;
+
+ entry = ReadDBSubjectEntry(handle, derSubject);
+
+ if ( entry == NULL ) {
+ return(SECFailure);
+ }
+
+ ret = entry->ncerts;
+
+ DestroyDBEntry((certDBEntry *)entry);
+
+ return(ret);
+}
+
+SECStatus
+nsslowcert_TraversePermCertsForNickname(NSSLOWCERTCertDBHandle *handle, char *nickname,
+ NSSLOWCERTCertCallback cb, void *cbarg)
+{
+ certDBEntryNickname *nnentry = NULL;
+ certDBEntrySMime *smentry = NULL;
+ SECStatus rv;
+ SECItem *derSubject = NULL;
+
+ nnentry = ReadDBNicknameEntry(handle, nickname);
+ if ( nnentry ) {
+ derSubject = &nnentry->subjectName;
+ } else {
+ smentry = nsslowcert_ReadDBSMimeEntry(handle, nickname);
+ if ( smentry ) {
+ derSubject = &smentry->subjectName;
+ }
+ }
+
+ if ( derSubject ) {
+ rv = nsslowcert_TraversePermCertsForSubject(handle, derSubject,
+ cb, cbarg);
+ } else {
+ rv = SECFailure;
+ }
+
+ if ( nnentry ) {
+ DestroyDBEntry((certDBEntry *)nnentry);
+ }
+ if ( smentry ) {
+ DestroyDBEntry((certDBEntry *)smentry);
+ }
+
+ return(rv);
+}
+
+
+int
+nsslowcert_NumPermCertsForNickname(NSSLOWCERTCertDBHandle *handle, char *nickname)
+{
+ certDBEntryNickname *entry;
+ int ret;
+
+ entry = ReadDBNicknameEntry(handle, nickname);
+
+ if ( entry ) {
+ ret = nsslowcert_NumPermCertsForSubject(handle, &entry->subjectName);
+ DestroyDBEntry((certDBEntry *)entry);
+ } else {
+ ret = 0;
+ }
+ return(ret);
+}
+
+/*
+ * add a nickname to a cert that doesn't have one
+ */
+static SECStatus
+AddNicknameToPermCert(NSSLOWCERTCertDBHandle *dbhandle,
+ NSSLOWCERTCertificate *cert, char *nickname)
+{
+ certDBEntryCert *entry;
+ int rv;
+
+ entry = cert->dbEntry;
+ PORT_Assert(entry != NULL);
+ if ( entry == NULL ) {
+ goto loser;
+ }
+
+ entry->nickname = PORT_ArenaStrdup(entry->common.arena, nickname);
+
+ rv = WriteDBCertEntry(dbhandle, entry);
+ if ( rv ) {
+ goto loser;
+ }
+
+ cert->nickname = PORT_ArenaStrdup(cert->arena, nickname);
+ return(SECSuccess);
+
+loser:
+ return(SECFailure);
+}
+
+/*
+ * add a nickname to a cert that is already in the perm database, but doesn't
+ * have one yet (it is probably an e-mail cert).
+ */
+SECStatus
+nsslowcert_AddPermNickname(NSSLOWCERTCertDBHandle *dbhandle,
+ NSSLOWCERTCertificate *cert, char *nickname)
+{
+ SECStatus rv = SECFailure;
+ certDBEntrySubject *entry = NULL;
+
+ nsslowcert_LockDB(dbhandle);
+
+ PORT_Assert(cert->nickname == NULL);
+
+ if ( cert->nickname != NULL ) {
+ rv = SECSuccess;
+ goto loser;
+ }
+
+ entry = ReadDBSubjectEntry(dbhandle, &cert->derSubject);
+ if (entry == NULL) goto loser;
+
+ if ( entry->nickname == NULL ) {
+ /* no nickname for subject */
+ rv = AddNicknameToSubject(dbhandle, cert, nickname);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+ rv = AddNicknameToPermCert(dbhandle, cert, nickname);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+ } else {
+ /* subject already has a nickname */
+ rv = AddNicknameToPermCert(dbhandle, cert, entry->nickname);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+ }
+ rv = SECSuccess;
+
+loser:
+ if (entry) {
+ DestroyDBEntry((certDBEntry *)entry);
+ }
+ nsslowcert_UnlockDB(dbhandle);
+ return(rv);
+}
+
+static certDBEntryCert *
+AddCertToPermDB(NSSLOWCERTCertDBHandle *handle, NSSLOWCERTCertificate *cert,
+ char *nickname, NSSLOWCERTCertTrust *trust)
+{
+ certDBEntryCert *certEntry = NULL;
+ certDBEntryNickname *nicknameEntry = NULL;
+ certDBEntrySubject *subjectEntry = NULL;
+ int state = 0;
+ SECStatus rv;
+ PRBool donnentry = PR_FALSE;
+
+ if ( nickname ) {
+ donnentry = PR_TRUE;
+ }
+
+ subjectEntry = ReadDBSubjectEntry(handle, &cert->derSubject);
+
+ if ( subjectEntry ) {
+ donnentry = PR_FALSE;
+ nickname = subjectEntry->nickname;
+ }
+
+ certEntry = NewDBCertEntry(&cert->derCert, nickname, trust, 0);
+ if ( certEntry == NULL ) {
+ goto loser;
+ }
+
+ if ( donnentry ) {
+ nicknameEntry = NewDBNicknameEntry(nickname, &cert->derSubject, 0);
+ if ( nicknameEntry == NULL ) {
+ goto loser;
+ }
+ }
+
+ rv = WriteDBCertEntry(handle, certEntry);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+ state = 1;
+
+ if ( nicknameEntry ) {
+ rv = WriteDBNicknameEntry(handle, nicknameEntry);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+ }
+
+ state = 2;
+
+ /* add to or create new subject entry */
+ if ( subjectEntry ) {
+ /* REWRITE BASED ON SUBJECT ENTRY */
+ rv = AddPermSubjectNode(subjectEntry, cert, nickname);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+ } else {
+ /* make a new subject entry - this case is only used when updating
+ * an old version of the database. This is OK because the oldnickname
+ * db format didn't allow multiple certs with the same subject.
+ */
+ /* where does subjectKeyID and certKey come from? */
+ subjectEntry = NewDBSubjectEntry(&cert->derSubject, &cert->certKey,
+ &cert->subjectKeyID, nickname,
+ NULL, 0);
+ if ( subjectEntry == NULL ) {
+ goto loser;
+ }
+ rv = WriteDBSubjectEntry(handle, subjectEntry);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+ }
+
+ state = 3;
+
+ if ( nicknameEntry ) {
+ DestroyDBEntry((certDBEntry *)nicknameEntry);
+ }
+
+ if ( subjectEntry ) {
+ DestroyDBEntry((certDBEntry *)subjectEntry);
+ }
+
+ return(certEntry);
+
+loser:
+ /* don't leave partial entry in the database */
+ if ( state > 0 ) {
+ rv = DeleteDBCertEntry(handle, &cert->certKey);
+ }
+ if ( ( state > 1 ) && donnentry ) {
+ rv = DeleteDBNicknameEntry(handle, nickname);
+ }
+ if ( state > 2 ) {
+ rv = DeleteDBSubjectEntry(handle, &cert->derSubject);
+ }
+ if ( certEntry ) {
+ DestroyDBEntry((certDBEntry *)certEntry);
+ }
+ if ( nicknameEntry ) {
+ DestroyDBEntry((certDBEntry *)nicknameEntry);
+ }
+ if ( subjectEntry ) {
+ DestroyDBEntry((certDBEntry *)subjectEntry);
+ }
+
+ return(NULL);
+}
+
+/*
+ * NOTE - Version 6 DB did not go out to the real world in a release,
+ * so we can remove this function in a later release.
+ */
+static SECStatus
+UpdateV6DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb)
+{
+ int ret;
+ DBT key, data;
+ unsigned char *buf, *tmpbuf = NULL;
+ certDBEntryType type;
+ certDBEntryNickname *nnEntry = NULL;
+ certDBEntrySubject *subjectEntry = NULL;
+ certDBEntrySMime *emailEntry = NULL;
+ char *nickname;
+ char *emailAddr;
+ SECStatus rv;
+
+ /*
+ * Sequence through the old database and copy all of the entries
+ * to the new database. Subject name entries will have the new
+ * fields inserted into them (with zero length).
+ */
+ ret = (* updatedb->seq)(updatedb, &key, &data, R_FIRST);
+ if ( ret ) {
+ return(SECFailure);
+ }
+
+ do {
+ buf = (unsigned char *)data.data;
+
+ if ( data.size >= 3 ) {
+ if ( buf[0] == 6 ) { /* version number */
+ type = (certDBEntryType)buf[1];
+ if ( type == certDBEntryTypeSubject ) {
+ /* expando subjecto entrieo */
+ tmpbuf = (unsigned char *)PORT_Alloc(data.size + 4);
+ if ( tmpbuf ) {
+ /* copy header stuff */
+ PORT_Memcpy(tmpbuf, buf, SEC_DB_ENTRY_HEADER_LEN + 2);
+ /* insert 4 more bytes of zero'd header */
+ PORT_Memset(&tmpbuf[SEC_DB_ENTRY_HEADER_LEN + 2],
+ 0, 4);
+ /* copy rest of the data */
+ PORT_Memcpy(&tmpbuf[SEC_DB_ENTRY_HEADER_LEN + 6],
+ &buf[SEC_DB_ENTRY_HEADER_LEN + 2],
+ data.size - (SEC_DB_ENTRY_HEADER_LEN + 2));
+
+ data.data = (void *)tmpbuf;
+ data.size += 4;
+ buf = tmpbuf;
+ }
+ } else if ( type == certDBEntryTypeCert ) {
+ /* expando certo entrieo */
+ tmpbuf = (unsigned char *)PORT_Alloc(data.size + 3);
+ if ( tmpbuf ) {
+ /* copy header stuff */
+ PORT_Memcpy(tmpbuf, buf, SEC_DB_ENTRY_HEADER_LEN);
+
+ /* copy trust flage, setting msb's to 0 */
+ tmpbuf[SEC_DB_ENTRY_HEADER_LEN] = 0;
+ tmpbuf[SEC_DB_ENTRY_HEADER_LEN+1] =
+ buf[SEC_DB_ENTRY_HEADER_LEN];
+ tmpbuf[SEC_DB_ENTRY_HEADER_LEN+2] = 0;
+ tmpbuf[SEC_DB_ENTRY_HEADER_LEN+3] =
+ buf[SEC_DB_ENTRY_HEADER_LEN+1];
+ tmpbuf[SEC_DB_ENTRY_HEADER_LEN+4] = 0;
+ tmpbuf[SEC_DB_ENTRY_HEADER_LEN+5] =
+ buf[SEC_DB_ENTRY_HEADER_LEN+2];
+
+ /* copy rest of the data */
+ PORT_Memcpy(&tmpbuf[SEC_DB_ENTRY_HEADER_LEN + 6],
+ &buf[SEC_DB_ENTRY_HEADER_LEN + 3],
+ data.size - (SEC_DB_ENTRY_HEADER_LEN + 3));
+
+ data.data = (void *)tmpbuf;
+ data.size += 3;
+ buf = tmpbuf;
+ }
+
+ }
+
+ /* update the record version number */
+ buf[0] = CERT_DB_FILE_VERSION;
+
+ /* copy to the new database */
+ ret = certdb_Put(handle->permCertDB, &key, &data, 0);
+ if ( tmpbuf ) {
+ PORT_Free(tmpbuf);
+ tmpbuf = NULL;
+ }
+ }
+ }
+ } while ( (* updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0 );
+
+ ret = certdb_Sync(handle->permCertDB, 0);
+
+ ret = (* updatedb->seq)(updatedb, &key, &data, R_FIRST);
+ if ( ret ) {
+ return(SECFailure);
+ }
+
+ do {
+ buf = (unsigned char *)data.data;
+
+ if ( data.size >= 3 ) {
+ if ( buf[0] == CERT_DB_FILE_VERSION ) { /* version number */
+ type = (certDBEntryType)buf[1];
+ if ( type == certDBEntryTypeNickname ) {
+ nickname = &((char *)key.data)[1];
+
+ /* get the matching nickname entry in the new DB */
+ nnEntry = ReadDBNicknameEntry(handle, nickname);
+ if ( nnEntry == NULL ) {
+ goto endloop;
+ }
+
+ /* find the subject entry pointed to by nickname */
+ subjectEntry = ReadDBSubjectEntry(handle,
+ &nnEntry->subjectName);
+ if ( subjectEntry == NULL ) {
+ goto endloop;
+ }
+
+ subjectEntry->nickname =
+ (char *)PORT_ArenaAlloc(subjectEntry->common.arena,
+ key.size - 1);
+ if ( subjectEntry->nickname ) {
+ PORT_Memcpy(subjectEntry->nickname, nickname,
+ key.size - 1);
+ rv = WriteDBSubjectEntry(handle, subjectEntry);
+ }
+ } else if ( type == certDBEntryTypeSMimeProfile ) {
+ emailAddr = &((char *)key.data)[1];
+
+ /* get the matching smime entry in the new DB */
+ emailEntry = nsslowcert_ReadDBSMimeEntry(handle, emailAddr);
+ if ( emailEntry == NULL ) {
+ goto endloop;
+ }
+
+ /* find the subject entry pointed to by nickname */
+ subjectEntry = ReadDBSubjectEntry(handle,
+ &emailEntry->subjectName);
+ if ( subjectEntry == NULL ) {
+ goto endloop;
+ }
+
+ subjectEntry->nickname =
+ (char *)PORT_ArenaAlloc(subjectEntry->common.arena,
+ key.size - 1);
+ if ( subjectEntry->emailAddr ) {
+ PORT_Memcpy(subjectEntry->emailAddr, emailAddr,
+ key.size - 1);
+ rv = WriteDBSubjectEntry(handle, subjectEntry);
+ }
+ }
+
+endloop:
+ if ( subjectEntry ) {
+ DestroyDBEntry((certDBEntry *)subjectEntry);
+ subjectEntry = NULL;
+ }
+ if ( nnEntry ) {
+ DestroyDBEntry((certDBEntry *)nnEntry);
+ nnEntry = NULL;
+ }
+ if ( emailEntry ) {
+ DestroyDBEntry((certDBEntry *)emailEntry);
+ emailEntry = NULL;
+ }
+ }
+ }
+ } while ( (* updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0 );
+
+ ret = certdb_Sync(handle->permCertDB, 0);
+
+ (* updatedb->close)(updatedb);
+ return(SECSuccess);
+}
+
+
+static SECStatus
+updateV5Callback(NSSLOWCERTCertificate *cert, SECItem *k, void *pdata)
+{
+ NSSLOWCERTCertDBHandle *handle;
+ certDBEntryCert *entry;
+ NSSLOWCERTCertTrust *trust;
+
+ handle = (NSSLOWCERTCertDBHandle *)pdata;
+ trust = &cert->dbEntry->trust;
+
+ /* SSL user certs can be used for email if they have an email addr */
+ if ( cert->emailAddr && ( trust->sslFlags & CERTDB_USER ) &&
+ ( trust->emailFlags == 0 ) ) {
+ trust->emailFlags = CERTDB_USER;
+ }
+ /* servers didn't set the user flags on the server cert.. */
+ if (PORT_Strcmp(cert->dbEntry->nickname,"Server-Cert") == 0) {
+ trust->sslFlags |= CERTDB_USER;
+ }
+
+ entry = AddCertToPermDB(handle, cert, cert->dbEntry->nickname,
+ &cert->dbEntry->trust);
+ if ( entry ) {
+ DestroyDBEntry((certDBEntry *)entry);
+ }
+
+ return(SECSuccess);
+}
+
+static SECStatus
+UpdateV5DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb)
+{
+ NSSLOWCERTCertDBHandle updatehandle;
+ SECStatus rv;
+
+ updatehandle.permCertDB = updatedb;
+ updatehandle.dbMon = PZ_NewMonitor(nssILockCertDB);
+
+ rv = nsslowcert_TraversePermCerts(&updatehandle, updateV5Callback,
+ (void *)handle);
+
+ PZ_DestroyMonitor(updatehandle.dbMon);
+
+ (* updatedb->close)(updatedb);
+ return(SECSuccess);
+}
+
+static PRBool
+isV4DB(DB *db) {
+ DBT key,data;
+ int ret;
+
+ key.data = "Version";
+ key.size = 7;
+
+ ret = (*db->get)(db, &key, &data, 0);
+ if (ret) {
+ return PR_FALSE;
+ }
+
+ if ((data.size == 1) && (*(unsigned char *)data.data <= 4)) {
+ return PR_TRUE;
+ }
+
+ return PR_FALSE;
+}
+
+static SECStatus
+UpdateV4DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb)
+{
+ DBT key, data;
+ certDBEntryCert *entry, *entry2;
+ SECItem derSubject;
+ int ret;
+ PRArenaPool *arena = NULL;
+ NSSLOWCERTCertificate *cert;
+
+ ret = (* updatedb->seq)(updatedb, &key, &data, R_FIRST);
+
+ if ( ret ) {
+ return(SECFailure);
+ }
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (arena == NULL) {
+ return(SECFailure);
+ }
+
+ do {
+ if ( data.size != 1 ) { /* skip version number */
+
+ /* decode the old DB entry */
+ entry = (certDBEntryCert *)DecodeV4DBCertEntry((unsigned char*)data.data, data.size);
+ derSubject.data = NULL;
+
+ if ( entry ) {
+ cert = nsslowcert_DecodeDERCertificate(&entry->derCert, PR_TRUE,
+ entry->nickname);
+
+ if ( cert != NULL ) {
+ /* add to new database */
+ entry2 = AddCertToPermDB(handle, cert, entry->nickname,
+ &entry->trust);
+
+ nsslowcert_DestroyCertificate(cert);
+ if ( entry2 ) {
+ DestroyDBEntry((certDBEntry *)entry2);
+ }
+ }
+ DestroyDBEntry((certDBEntry *)entry);
+ }
+ }
+ } while ( (* updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0 );
+
+ PORT_FreeArena(arena, PR_FALSE);
+ (* updatedb->close)(updatedb);
+ return(SECSuccess);
+}
+
+
+/*
+ * return true if a database key conflict exists
+ */
+PRBool
+nsslowcert_CertDBKeyConflict(SECItem *derCert, NSSLOWCERTCertDBHandle *handle)
+{
+ SECStatus rv;
+ DBT tmpdata;
+ DBT namekey;
+ int ret;
+ SECItem keyitem;
+ PRArenaPool *arena = NULL;
+ SECItem derKey;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( arena == NULL ) {
+ goto loser;
+ }
+
+ /* get the db key of the cert */
+ rv = nsslowcert_KeyFromDERCert(arena, derCert, &derKey);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ rv = EncodeDBCertKey(&derKey, arena, &keyitem);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ namekey.data = keyitem.data;
+ namekey.size = keyitem.len;
+
+ ret = certdb_Get(handle->permCertDB, &namekey, &tmpdata, 0);
+ if ( ret == 0 ) {
+ goto loser;
+ }
+
+ PORT_FreeArena(arena, PR_FALSE);
+
+ return(PR_FALSE);
+loser:
+ if ( arena ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ return(PR_TRUE);
+}
+
+/*
+ * return true if a nickname conflict exists
+ * NOTE: caller must have already made sure that this exact cert
+ * doesn't exist in the DB
+ */
+static PRBool
+nsslowcert_CertNicknameConflict(char *nickname, SECItem *derSubject,
+ NSSLOWCERTCertDBHandle *handle)
+{
+ PRBool rv;
+ certDBEntryNickname *entry;
+
+ if ( nickname == NULL ) {
+ return(PR_FALSE);
+ }
+
+ entry = ReadDBNicknameEntry(handle, nickname);
+
+ if ( entry == NULL ) {
+ /* no entry for this nickname, so no conflict */
+ return(PR_FALSE);
+ }
+
+ rv = PR_TRUE;
+ if ( SECITEM_CompareItem(derSubject, &entry->subjectName) == SECEqual ) {
+ /* if subject names are the same, then no conflict */
+ rv = PR_FALSE;
+ }
+
+ DestroyDBEntry((certDBEntry *)entry);
+ return(rv);
+}
+
+/*
+ * 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)
+{
+ SECStatus rv;
+ int openflags;
+ certDBEntryVersion *versionEntry = NULL;
+ DB *updatedb = NULL;
+ char *tmpname;
+ char *certdbname;
+ PRBool updated = PR_FALSE;
+ PRBool forceUpdate = PR_FALSE;
+
+ certdbname = (* namecb)(cbarg, CERT_DB_FILE_VERSION);
+ if ( certdbname == NULL ) {
+ return(SECFailure);
+ }
+
+ if ( readOnly ) {
+ openflags = O_RDONLY;
+ } else {
+ openflags = O_RDWR;
+ }
+
+ /*
+ * first open the permanent file based database.
+ */
+ handle->permCertDB = dbopen( certdbname, openflags, 0600, DB_HASH, 0 );
+
+ /* check for correct version number */
+ if ( handle->permCertDB ) {
+ versionEntry = ReadDBVersionEntry(handle);
+
+ if ( versionEntry == NULL ) {
+ /* no version number */
+ certdb_Close(handle->permCertDB);
+ handle->permCertDB = 0;
+ } else if ( versionEntry->common.version != CERT_DB_FILE_VERSION ) {
+ /* wrong version number, can't update in place */
+ DestroyDBEntry((certDBEntry *)versionEntry);
+ PORT_Free(certdbname);
+ return(SECFailure);
+ } else {
+ DestroyDBEntry((certDBEntry *)versionEntry);
+ versionEntry = NULL;
+ }
+ }
+
+
+ /* if first open fails, try to create a new DB */
+ if ( handle->permCertDB == NULL ) {
+
+ /* don't create if readonly */
+ if ( readOnly ) {
+ goto loser;
+ }
+
+ handle->permCertDB = dbopen(certdbname,
+ O_RDWR | O_CREAT | O_TRUNC,
+ 0600, DB_HASH, 0);
+
+ /* if create fails then we lose */
+ if ( handle->permCertDB == 0 ) {
+ goto loser;
+ }
+
+ versionEntry = NewDBVersionEntry(0);
+ if ( versionEntry == NULL ) {
+ goto loser;
+ }
+
+ rv = WriteDBVersionEntry(handle, versionEntry);
+
+ DestroyDBEntry((certDBEntry *)versionEntry);
+
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ /* 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 );
+ PORT_Free(tmpname);
+ if ( updatedb ) {
+ rv = UpdateV6DB(handle, updatedb);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+ updated = PR_TRUE;
+ } 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 );
+ PORT_Free(tmpname);
+ if ( updatedb ) {
+ rv = UpdateV5DB(handle, updatedb);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+ updated = PR_TRUE;
+ } else { /* no v5 db, so try v4 db */
+ /* try to upgrade v4 db */
+ tmpname = (* namecb)(cbarg, 4); /* get v4 db name */
+ if ( tmpname ) {
+ updatedb = dbopen( tmpname, O_RDONLY, 0600,
+ DB_HASH, 0 );
+ PORT_Free(tmpname);
+ if ( updatedb ) {
+ /* NES has v5 db's with v4 db names! */
+ if (isV4DB(updatedb)) {
+ rv = UpdateV4DB(handle, updatedb);
+ } else {
+ rv = UpdateV5DB(handle, updatedb);
+ }
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+ forceUpdate = PR_TRUE;
+ updated = PR_TRUE;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Root certs are no longer automatically added to the DB. They
+ * come from and external PKCS #11 file.
+ */
+ }
+
+ PORT_Free(certdbname);
+
+ return (SECSuccess);
+
+loser:
+
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+
+ if ( handle->permCertDB ) {
+ certdb_Close(handle->permCertDB);
+ handle->permCertDB = 0;
+ }
+
+ PORT_Free(certdbname);
+
+ return(SECFailure);
+}
+
+/*
+ * delete all DB records associated with a particular certificate
+ */
+static SECStatus
+DeletePermCert(NSSLOWCERTCertificate *cert)
+{
+ SECStatus rv;
+ SECStatus ret;
+
+ ret = SECSuccess;
+
+ rv = DeleteDBCertEntry(cert->dbhandle, &cert->certKey);
+ if ( rv != SECSuccess ) {
+ ret = SECFailure;
+ }
+
+ if ( cert->nickname ) {
+ rv = DeleteDBNicknameEntry(cert->dbhandle, cert->nickname);
+ if ( rv != SECSuccess ) {
+ ret = SECFailure;
+ }
+ }
+
+ rv = RemovePermSubjectNode(cert);
+
+ return(ret);
+}
+
+/*
+ * Delete a certificate from the permanent database.
+ */
+SECStatus
+nsslowcert_DeletePermCertificate(NSSLOWCERTCertificate *cert)
+{
+ SECStatus rv;
+
+ nsslowcert_LockDB(cert->dbhandle);
+ /* delete the records from the permanent database */
+ rv = DeletePermCert(cert);
+
+ /* get rid of dbcert and stuff pointing to it */
+ DestroyDBEntry((certDBEntry *)cert->dbEntry);
+ cert->dbEntry = NULL;
+ cert->trust = NULL;
+
+ nsslowcert_UnlockDB(cert->dbhandle);
+ return(rv);
+}
+
+/*
+ * Traverse all of the entries in the database of a particular type
+ * call the given function for each one.
+ */
+SECStatus
+nsslowcert_TraverseDBEntries(NSSLOWCERTCertDBHandle *handle,
+ certDBEntryType type,
+ SECStatus (* callback)(SECItem *data, SECItem *key,
+ certDBEntryType type, void *pdata),
+ void *udata )
+{
+ DBT data;
+ DBT key;
+ SECStatus rv;
+ int ret;
+ SECItem dataitem;
+ SECItem keyitem;
+ unsigned char *buf;
+ unsigned char *keybuf;
+
+ ret = certdb_Seq(handle->permCertDB, &key, &data, R_FIRST);
+
+ if ( ret ) {
+ return(SECFailure);
+ }
+
+ do {
+ buf = (unsigned char *)data.data;
+
+ if ( buf[1] == (unsigned char)type ) {
+ dataitem.len = data.size;
+ dataitem.data = buf;
+ dataitem.type = siBuffer;
+ keyitem.len = key.size - SEC_DB_KEY_HEADER_LEN;
+ keybuf = (unsigned char *)key.data;
+ keyitem.data = &keybuf[SEC_DB_KEY_HEADER_LEN];
+ keyitem.type = siBuffer;
+
+ rv = (* callback)(&dataitem, &keyitem, type, udata);
+ if ( rv != SECSuccess ) {
+ return(rv);
+ }
+ }
+ } while ( certdb_Seq(handle->permCertDB, &key, &data, R_NEXT) == 0 );
+
+ return(SECSuccess);
+}
+/*
+ * Decode a certificate and enter it into the temporary certificate database.
+ * Deal with nicknames correctly
+ *
+ * This is the private entry point.
+ */
+static NSSLOWCERTCertificate *
+DecodeACert(NSSLOWCERTCertDBHandle *handle, certDBEntryCert *entry)
+{
+ NSSLOWCERTCertificate *cert = NULL;
+
+ cert = nsslowcert_DecodeDERCertificate(&entry->derCert, PR_TRUE,
+ entry->nickname );
+
+ if ( cert == NULL ) {
+ goto loser;
+ }
+
+ cert->dbhandle = handle;
+ cert->dbEntry = entry;
+ cert->trust = &entry->trust;
+
+ return(cert);
+
+loser:
+ return(0);
+}
+
+typedef struct {
+ PermCertCallback certfunc;
+ NSSLOWCERTCertDBHandle *handle;
+ void *data;
+} PermCertCallbackState;
+
+/*
+ * traversal callback to decode certs and call callers callback
+ */
+static SECStatus
+certcallback(SECItem *dbdata, SECItem *dbkey, certDBEntryType type, void *data)
+{
+ PermCertCallbackState *mystate;
+ SECStatus rv;
+ certDBEntryCert *entry;
+ SECItem entryitem;
+ NSSLOWCERTCertificate *cert;
+ PRArenaPool *arena = NULL;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( arena == NULL ) {
+ goto loser;
+ }
+
+ entry = (certDBEntryCert *)PORT_ArenaAlloc(arena, sizeof(certDBEntryCert));
+ mystate = (PermCertCallbackState *)data;
+ entry->common.version = (unsigned int)dbdata->data[0];
+ entry->common.type = (certDBEntryType)dbdata->data[1];
+ entry->common.flags = (unsigned int)dbdata->data[2];
+ entry->common.arena = arena;
+
+ entryitem.len = dbdata->len - SEC_DB_ENTRY_HEADER_LEN;
+ entryitem.data = &dbdata->data[SEC_DB_ENTRY_HEADER_LEN];
+
+ rv = DecodeDBCertEntry(entry, &entryitem);
+ if (rv != SECSuccess ) {
+ goto loser;
+ }
+ entry->derCert.type = siBuffer;
+
+ /* note: Entry is 'inheritted'. */
+ cert = DecodeACert(mystate->handle, entry);
+
+ rv = (* mystate->certfunc)(cert, dbkey, mystate->data);
+
+ /* arena stored in entry destroyed by nsslowcert_DestroyCertificate */
+ nsslowcert_DestroyCertificateNoLocking(cert);
+
+ return(rv);
+
+loser:
+ if ( arena ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+ return(SECFailure);
+}
+
+/*
+ * Traverse all of the certificates in the permanent database and
+ * call the given function for each one; expect the caller to have lock.
+ */
+static SECStatus
+TraversePermCertsNoLocking(NSSLOWCERTCertDBHandle *handle,
+ SECStatus (* certfunc)(NSSLOWCERTCertificate *cert,
+ SECItem *k,
+ void *pdata),
+ void *udata )
+{
+ SECStatus rv;
+ PermCertCallbackState mystate;
+
+ mystate.certfunc = certfunc;
+ mystate.handle = handle;
+ mystate.data = udata;
+ rv = nsslowcert_TraverseDBEntries(handle, certDBEntryTypeCert, certcallback,
+ (void *)&mystate);
+
+ return(rv);
+}
+
+/*
+ * Traverse all of the certificates in the permanent database and
+ * call the given function for each one.
+ */
+SECStatus
+nsslowcert_TraversePermCerts(NSSLOWCERTCertDBHandle *handle,
+ SECStatus (* certfunc)(NSSLOWCERTCertificate *cert, SECItem *k,
+ void *pdata),
+ void *udata )
+{
+ SECStatus rv;
+
+ nsslowcert_LockDB(handle);
+ rv = TraversePermCertsNoLocking(handle, certfunc, udata);
+ nsslowcert_UnlockDB(handle);
+
+ return(rv);
+}
+
+
+
+/*
+ * Close the database
+ */
+void
+__nsslowcert_ClosePermCertDB(NSSLOWCERTCertDBHandle *handle)
+{
+ if ( handle ) {
+ if ( handle->permCertDB ) {
+ certdb_Close( handle->permCertDB );
+ handle->permCertDB = 0;
+ }
+ }
+ return;
+}
+
+void
+nsslowcert_ClosePermCertDB(NSSLOWCERTCertDBHandle *handle)
+{
+ __nsslowcert_ClosePermCertDB(handle);
+}
+
+/*
+ * Get the trust attributes from a certificate
+ */
+SECStatus
+nsslowcert_GetCertTrust(NSSLOWCERTCertificate *cert, NSSLOWCERTCertTrust *trust)
+{
+ SECStatus rv;
+
+ nsslowcert_LockCertTrust(cert);
+
+ if ( cert->trust == NULL ) {
+ rv = SECFailure;
+ } else {
+ *trust = *cert->trust;
+ rv = SECSuccess;
+ }
+
+ nsslowcert_UnlockCertTrust(cert);
+ return(rv);
+}
+
+/*
+ * Change the trust attributes of a certificate and make them permanent
+ * in the database.
+ */
+SECStatus
+nsslowcert_ChangeCertTrust(NSSLOWCERTCertDBHandle *handle, NSSLOWCERTCertificate *cert,
+ NSSLOWCERTCertTrust *trust)
+{
+ certDBEntryCert *entry;
+ int rv;
+ SECStatus ret;
+
+ nsslowcert_LockDB(handle);
+ nsslowcert_LockCertTrust(cert);
+ /* only set the trust on permanent certs */
+ if ( cert->trust == NULL ) {
+ ret = SECFailure;
+ goto done;
+ }
+
+ *cert->trust = *trust;
+ if ( cert->dbEntry == NULL ) {
+ ret = SECSuccess; /* not in permanent database */
+ goto done;
+ }
+
+ entry = cert->dbEntry;
+ entry->trust = *trust;
+
+ rv = WriteDBCertEntry(handle, entry);
+ if ( rv ) {
+ ret = SECFailure;
+ goto done;
+ }
+
+ ret = SECSuccess;
+
+done:
+ nsslowcert_UnlockCertTrust(cert);
+ nsslowcert_UnlockDB(handle);
+ return(ret);
+}
+
+
+SECStatus
+nsslowcert_AddPermCert(NSSLOWCERTCertDBHandle *dbhandle,
+ NSSLOWCERTCertificate *cert, char *nickname, NSSLOWCERTCertTrust *trust)
+{
+ char *oldnn;
+ certDBEntryCert *entry;
+ PRBool conflict;
+ SECStatus ret;
+
+ nsslowcert_LockDB(dbhandle);
+
+ PORT_Assert(!cert->dbEntry);
+
+ /* don't add a conflicting nickname */
+ conflict = nsslowcert_CertNicknameConflict(nickname, &cert->derSubject,
+ dbhandle);
+ if ( conflict ) {
+ ret = SECFailure;
+ goto done;
+ }
+
+ /* save old nickname so that we can delete it */
+ oldnn = cert->nickname;
+
+ entry = AddCertToPermDB(dbhandle, cert, nickname, trust);
+
+ if ( entry == NULL ) {
+ ret = SECFailure;
+ goto done;
+ }
+
+ cert->nickname = (entry->nickname) ? PORT_ArenaStrdup(cert->arena,entry->nickname) : NULL;
+ cert->trust = &entry->trust;
+ cert->dbEntry = entry;
+
+ ret = SECSuccess;
+done:
+ nsslowcert_UnlockDB(dbhandle);
+ return(ret);
+}
+
+/*
+ * Open the certificate database and index databases. Create them if
+ * they are not there or bad.
+ */
+SECStatus
+nsslowcert_OpenCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
+ NSSLOWCERTDBNameFunc namecb, void *cbarg, PRBool openVolatile)
+{
+ int rv;
+
+ certdb_InitDBLock(handle);
+
+ handle->dbMon = PZ_NewMonitor(nssILockCertDB);
+ PORT_Assert(handle->dbMon != NULL);
+
+ rv = nsslowcert_OpenPermCertDB(handle, readOnly, namecb, cbarg);
+ if ( rv ) {
+ goto loser;
+ }
+
+ return (SECSuccess);
+
+loser:
+
+ PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ return(SECFailure);
+}
+
+
+/*
+ * Lookup a certificate in the databases.
+ */
+static NSSLOWCERTCertificate *
+FindCertByKey(NSSLOWCERTCertDBHandle *handle, SECItem *certKey, PRBool lockdb)
+{
+ SECItem keyitem;
+ DBT key;
+ SECStatus rv;
+ NSSLOWCERTCertificate *cert = NULL;
+ PRArenaPool *arena = NULL;
+ certDBEntryCert *entry;
+ PRBool locked = PR_FALSE;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( arena == NULL ) {
+ goto loser;
+ }
+
+ rv = EncodeDBCertKey(certKey, arena, &keyitem);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ key.data = keyitem.data;
+ key.size = keyitem.len;
+
+ if ( lockdb ) {
+ locked = PR_TRUE;
+ nsslowcert_LockDB(handle);
+ }
+
+ /* find in perm database */
+ entry = ReadDBCertEntry(handle, certKey);
+
+ if ( entry == NULL ) {
+ goto loser;
+ }
+
+ /* inherit entry */
+ cert = DecodeACert(handle, entry);
+
+loser:
+ if ( locked ) {
+ nsslowcert_UnlockDB(handle);
+ }
+
+ if ( arena ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ return(cert);
+}
+
+/*
+ * Lookup a certificate in the databases without locking
+ */
+NSSLOWCERTCertificate *
+nsslowcert_FindCertByKey(NSSLOWCERTCertDBHandle *handle, SECItem *certKey)
+{
+ return(FindCertByKey(handle, certKey, PR_FALSE));
+}
+
+/*
+ * Generate a key from an issuerAndSerialNumber, and find the
+ * associated cert in the database.
+ */
+NSSLOWCERTCertificate *
+nsslowcert_FindCertByIssuerAndSN(NSSLOWCERTCertDBHandle *handle, NSSLOWCERTIssuerAndSN *issuerAndSN)
+{
+ SECItem certKey;
+ NSSLOWCERTCertificate *cert;
+
+ certKey.len = issuerAndSN->serialNumber.len + issuerAndSN->derIssuer.len;
+ certKey.data = (unsigned char*)PORT_Alloc(certKey.len);
+
+ if ( certKey.data == NULL ) {
+ return(0);
+ }
+
+ /* copy the serialNumber */
+ PORT_Memcpy(certKey.data, issuerAndSN->serialNumber.data,
+ issuerAndSN->serialNumber.len);
+
+ /* copy the issuer */
+ PORT_Memcpy( &certKey.data[issuerAndSN->serialNumber.len],
+ issuerAndSN->derIssuer.data, issuerAndSN->derIssuer.len);
+
+ cert = nsslowcert_FindCertByKey(handle, &certKey);
+
+ PORT_Free(certKey.data);
+
+ return(cert);
+}
+
+/*
+ * look for the given DER certificate in the database
+ */
+NSSLOWCERTCertificate *
+nsslowcert_FindCertByDERCert(NSSLOWCERTCertDBHandle *handle, SECItem *derCert)
+{
+ PRArenaPool *arena;
+ SECItem certKey;
+ SECStatus rv;
+ NSSLOWCERTCertificate *cert = NULL;
+
+ /* create a scratch arena */
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( arena == NULL ) {
+ return(NULL);
+ }
+
+ /* extract the database key from the cert */
+ rv = nsslowcert_KeyFromDERCert(arena, derCert, &certKey);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ /* find the certificate */
+ cert = nsslowcert_FindCertByKey(handle, &certKey);
+
+loser:
+ PORT_FreeArena(arena, PR_FALSE);
+ return(cert);
+}
+
+static void
+DestroyCertificate(NSSLOWCERTCertificate *cert, PRBool lockdb)
+{
+ int refCount;
+ NSSLOWCERTCertDBHandle *handle;
+
+ if ( cert ) {
+
+ handle = cert->dbhandle;
+
+ /*
+ * handle may be NULL, for example if the cert was created with
+ * nsslowcert_DecodeDERCertificate.
+ */
+ if ( lockdb && handle ) {
+ nsslowcert_LockDB(handle);
+ }
+
+ nsslowcert_LockCertRefCount(cert);
+ PORT_Assert(cert->referenceCount > 0);
+ refCount = --cert->referenceCount;
+ nsslowcert_UnlockCertRefCount(cert);
+
+ if ( ( refCount == 0 ) ) {
+ certDBEntryCert *entry = cert->dbEntry;
+ PRArenaPool * arena = cert->arena;
+
+ if ( entry ) {
+ DestroyDBEntry((certDBEntry *)entry);
+ }
+
+ /* zero cert before freeing. Any stale references to this cert
+ * after this point will probably cause an exception. */
+ PORT_Memset(cert, 0, sizeof *cert);
+
+ cert = NULL;
+
+ /* free the arena that contains the cert. */
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+ if ( lockdb && handle ) {
+ nsslowcert_UnlockDB(handle);
+ }
+ }
+
+ return;
+}
+
+void
+nsslowcert_DestroyCertificate(NSSLOWCERTCertificate *cert)
+{
+ DestroyCertificate(cert, PR_TRUE);
+ return;
+}
+
+static void
+nsslowcert_DestroyCertificateNoLocking(NSSLOWCERTCertificate *cert)
+{
+ DestroyCertificate(cert, PR_FALSE);
+ return;
+}
+
+/*
+ * Lookup a CRL in the databases. We mirror the same fast caching data base
+ * caching stuff used by certificates....?
+ */
+SECItem *
+nsslowcert_FindCrlByKey(NSSLOWCERTCertDBHandle *handle, SECItem *crlKey,
+ char **url, PRBool isKRL)
+{
+ SECItem keyitem;
+ DBT key;
+ SECStatus rv;
+ SECItem *crl = NULL;
+ PRArenaPool *arena = NULL;
+ certDBEntryRevocation *entry;
+ certDBEntryType crlType = isKRL ? certDBEntryTypeKeyRevocation
+ : certDBEntryTypeRevocation;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( arena == NULL ) {
+ goto loser;
+ }
+
+ rv = EncodeDBGenericKey(crlKey, arena, &keyitem, crlType);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ key.data = keyitem.data;
+ key.size = keyitem.len;
+
+ /* find in perm database */
+ entry = ReadDBCrlEntry(handle, crlKey, crlType);
+
+ if ( entry == NULL ) {
+ goto loser;
+ }
+
+ if (entry->url) {
+ *url = PORT_Strdup(entry->url);
+ }
+ crl = SECITEM_DupItem(&entry->derCrl);
+
+loser:
+ if ( arena ) {
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+ if (entry) {
+ DestroyDBEntry((certDBEntry *)entry);
+ }
+
+ return(crl);
+}
+
+/*
+ * replace the existing URL in the data base with a new one
+ */
+SECStatus
+nsslowcert_AddCrl(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl,
+ SECItem *crlKey, char *url, PRBool isKRL)
+{
+ SECStatus rv = SECFailure;
+ certDBEntryRevocation *entry = NULL;
+ certDBEntryType crlType = isKRL ? certDBEntryTypeKeyRevocation
+ : certDBEntryTypeRevocation;
+ DeleteDBCrlEntry(handle, crlKey, crlType);
+
+ /* Write the new entry into the data base */
+ entry = NewDBCrlEntry(derCrl, url, crlType, 0);
+ if (entry == NULL) goto done;
+
+ rv = WriteDBCrlEntry(handle, entry, crlKey);
+ if (rv != SECSuccess) goto done;
+
+done:
+ if (entry) {
+ DestroyDBEntry((certDBEntry *)entry);
+ }
+ return rv;
+}
+
+SECStatus
+nsslowcert_DeletePermCRL(NSSLOWCERTCertDBHandle *handle, SECItem *derName,
+ PRBool isKRL)
+{
+ SECStatus rv;
+ certDBEntryType crlType = isKRL ? certDBEntryTypeKeyRevocation
+ : certDBEntryTypeRevocation;
+
+ rv = DeleteDBCrlEntry(handle, derName, crlType);
+ if (rv != SECSuccess) goto done;
+
+done:
+ return rv;
+}
+
+
+PRBool
+nsslowcert_hasTrust(NSSLOWCERTCertificate *cert)
+{
+ NSSLOWCERTCertTrust *trust;
+
+ if (cert->trust == NULL) {
+ return PR_FALSE;
+ }
+ trust = cert->trust;
+ return !((trust->sslFlags & CERTDB_TRUSTED_UNKNOWN) &&
+ (trust->emailFlags & CERTDB_TRUSTED_UNKNOWN) &&
+ (trust->objectSigningFlags & CERTDB_TRUSTED_UNKNOWN));
+}
+
+/*
+ * This function has the logic that decides if another person's cert and
+ * email profile from an S/MIME message should be saved. It can deal with
+ * the case when there is no profile.
+ */
+SECStatus
+nsslowcert_SaveSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle, char *emailAddr,
+ SECItem *derSubject, SECItem *emailProfile, SECItem *profileTime)
+{
+ certDBEntrySMime *entry = NULL;
+ SECStatus rv = SECFailure;;
+
+ /* find our existing entry */
+ entry = nsslowcert_ReadDBSMimeEntry(dbhandle, emailAddr);
+
+ if ( entry ) {
+ /* keep our old db entry consistant for old applications. */
+ if (!SECITEM_ItemsAreEqual(derSubject, &entry->subjectName)) {
+ UpdateSubjectWithEmailAddr(dbhandle, &entry->subjectName, NULL);
+ }
+ DestroyDBEntry((certDBEntry *)entry);
+ entry = NULL;
+ }
+
+ /* now save the entry */
+ entry = NewDBSMimeEntry(emailAddr, derSubject, emailProfile,
+ profileTime, 0);
+ if ( entry == NULL ) {
+ rv = SECFailure;
+ goto loser;
+ }
+
+ nsslowcert_LockDB(dbhandle);
+
+ rv = DeleteDBSMimeEntry(dbhandle, emailAddr);
+ /* if delete fails, try to write new entry anyway... */
+
+ /* link subject entry back here */
+ rv = UpdateSubjectWithEmailAddr(dbhandle, derSubject, emailAddr);
+ if ( rv != SECSuccess ) {
+ nsslowcert_UnlockDB(dbhandle);
+ goto loser;
+ }
+
+ rv = WriteDBSMimeEntry(dbhandle, entry);
+ if ( rv != SECSuccess ) {
+ nsslowcert_UnlockDB(dbhandle);
+ goto loser;
+ }
+
+ nsslowcert_UnlockDB(dbhandle);
+
+ rv = SECSuccess;
+
+loser:
+ if ( entry ) {
+ DestroyDBEntry((certDBEntry *)entry);
+ }
+ return(rv);
+}
diff --git a/security/nss/lib/softoken/pcertt.h b/security/nss/lib/softoken/pcertt.h
new file mode 100644
index 000000000..808f95fe1
--- /dev/null
+++ b/security/nss/lib/softoken/pcertt.h
@@ -0,0 +1,433 @@
+/*
+ * 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.
+ */
+/*
+ * certt.h - public data structures for the certificate library
+ *
+ * $Id$
+ */
+#ifndef _PCERTT_H_
+#define _PCERTT_H_
+
+#include "prclist.h"
+#include "pkcs11t.h"
+#include "seccomon.h"
+#include "secoidt.h"
+#include "plarena.h"
+#include "prcvar.h"
+#include "nssilock.h"
+#include "prio.h"
+#include "prmon.h"
+
+
+/* Non-opaque objects */
+typedef struct NSSLOWCERTCertDBHandleStr NSSLOWCERTCertDBHandle;
+typedef struct NSSLOWCERTCertKeyStr NSSLOWCERTCertKey;
+
+typedef struct NSSLOWCERTCertTrustStr NSSLOWCERTCertTrust;
+typedef struct NSSLOWCERTCertificateStr NSSLOWCERTCertificate;
+typedef struct NSSLOWCERTCertificateListStr NSSLOWCERTCertificateList;
+typedef struct NSSLOWCERTIssuerAndSNStr NSSLOWCERTIssuerAndSN;
+typedef struct NSSLOWCERTSignedDataStr NSSLOWCERTSignedData;
+typedef struct NSSLOWCERTSubjectPublicKeyInfoStr NSSLOWCERTSubjectPublicKeyInfo;
+typedef struct NSSLOWCERTValidityStr NSSLOWCERTValidity;
+
+/*
+** An X.509 validity object
+*/
+struct NSSLOWCERTValidityStr {
+ PRArenaPool *arena;
+ SECItem notBefore;
+ SECItem notAfter;
+};
+
+/*
+ * A serial number and issuer name, which is used as a database key
+ */
+struct NSSLOWCERTCertKeyStr {
+ SECItem serialNumber;
+ SECItem derIssuer;
+};
+
+/*
+** A signed data object. Used to implement the "signed" macro used
+** in the X.500 specs.
+*/
+struct NSSLOWCERTSignedDataStr {
+ SECItem data;
+ SECAlgorithmID signatureAlgorithm;
+ SECItem signature;
+};
+
+/*
+** An X.509 subject-public-key-info object
+*/
+struct NSSLOWCERTSubjectPublicKeyInfoStr {
+ PRArenaPool *arena;
+ SECAlgorithmID algorithm;
+ SECItem subjectPublicKey;
+};
+
+typedef struct _certDBEntryCert certDBEntryCert;
+typedef struct _certDBEntryRevocation certDBEntryRevocation;
+
+struct NSSLOWCERTCertTrustStr {
+ unsigned int sslFlags;
+ unsigned int emailFlags;
+ unsigned int objectSigningFlags;
+};
+
+/*
+** An X.509 certificate object (the unsigned form)
+*/
+struct NSSLOWCERTCertificateStr {
+ /* the arena is used to allocate any data structures that have the same
+ * lifetime as the cert. This is all stuff that hangs off of the cert
+ * structure, and is all freed at the same time. I is used when the
+ * cert is decoded, destroyed, and at some times when it changes
+ * state
+ */
+ PRArenaPool *arena;
+ NSSLOWCERTCertDBHandle *dbhandle;
+
+ SECItem derCert; /* original DER for the cert */
+ SECItem derIssuer; /* DER for issuer name */
+ SECItem serialNumber;
+ SECItem derSubject; /* DER for subject name */
+ NSSLOWCERTSubjectPublicKeyInfo subjectPublicKeyInfo;
+ SECItem certKey; /* database key for this cert */
+ NSSLOWCERTValidity validity;
+ certDBEntryCert *dbEntry; /* database entry struct */
+ SECItem subjectKeyID; /* x509v3 subject key identifier */
+ char *nickname;
+ char *emailAddr;
+ NSSLOWCERTCertTrust *trust;
+
+ /* the reference count is modified whenever someone looks up, dups
+ * or destroys a certificate
+ */
+ int referenceCount;
+};
+#define SEC_CERTIFICATE_VERSION_1 0 /* default created */
+#define SEC_CERTIFICATE_VERSION_2 1 /* v2 */
+#define SEC_CERTIFICATE_VERSION_3 2 /* v3 extensions */
+
+#define SEC_CRL_VERSION_1 0 /* default */
+#define SEC_CRL_VERSION_2 1 /* v2 extensions */
+
+struct NSSLOWCERTIssuerAndSNStr {
+ SECItem derIssuer;
+ SECItem serialNumber;
+};
+
+typedef SECStatus (* NSSLOWCERTCertCallback)(NSSLOWCERTCertificate *cert, void *arg);
+
+/* This is the typedef for the callback passed to nsslowcert_OpenCertDB() */
+/* callback to return database name based on version number */
+typedef char * (*NSSLOWCERTDBNameFunc)(void *arg, int dbVersion);
+
+/* XXX Lisa thinks the template declarations belong in cert.h, not here? */
+
+#include "secasn1t.h" /* way down here because I expect template stuff to
+ * move out of here anyway */
+
+SEC_BEGIN_PROTOS
+
+extern const SEC_ASN1Template nsslowcert_CertificateTemplate[];
+extern const SEC_ASN1Template SEC_SignedCertificateTemplate[];
+extern const SEC_ASN1Template nsslowcert_SignedDataTemplate[];
+extern const SEC_ASN1Template NSSLOWKEY_PublicKeyTemplate[];
+extern const SEC_ASN1Template nsslowcert_SubjectPublicKeyInfoTemplate[];
+extern const SEC_ASN1Template nsslowcert_ValidityTemplate[];
+
+SEC_END_PROTOS
+
+/*
+ * Certificate Database related definitions and data structures
+ */
+
+/* version number of certificate database */
+#define CERT_DB_FILE_VERSION 7
+#ifdef USE_NS_ROOTS
+#define CERT_DB_CONTENT_VERSION 28
+#else
+#define CERT_DB_CONTENT_VERSION 2
+#endif
+
+#define SEC_DB_ENTRY_HEADER_LEN 3
+#define SEC_DB_KEY_HEADER_LEN 1
+
+/* All database entries have this form:
+ *
+ * byte offset field
+ * ----------- -----
+ * 0 version
+ * 1 type
+ * 2 flags
+ */
+
+/* database entry types */
+typedef enum {
+ certDBEntryTypeVersion = 0,
+ certDBEntryTypeCert = 1,
+ certDBEntryTypeNickname = 2,
+ certDBEntryTypeSubject = 3,
+ certDBEntryTypeRevocation = 4,
+ certDBEntryTypeKeyRevocation = 5,
+ certDBEntryTypeSMimeProfile = 6,
+ certDBEntryTypeContentVersion = 7
+} certDBEntryType;
+
+typedef struct {
+ certDBEntryType type;
+ unsigned int version;
+ unsigned int flags;
+ PRArenaPool *arena;
+} certDBEntryCommon;
+
+/*
+ * Certificate entry:
+ *
+ * byte offset field
+ * ----------- -----
+ * 0 sslFlags-msb
+ * 1 sslFlags-lsb
+ * 2 emailFlags-msb
+ * 3 emailFlags-lsb
+ * 4 objectSigningFlags-msb
+ * 5 objectSigningFlags-lsb
+ * 6 derCert-len-msb
+ * 7 derCert-len-lsb
+ * 8 nickname-len-msb
+ * 9 nickname-len-lsb
+ * ... derCert
+ * ... nickname
+ *
+ * NOTE: the nickname string as stored in the database is null terminated,
+ * in other words, the last byte of the db entry is always 0
+ * if a nickname is present.
+ * NOTE: if nickname is not present, then nickname-len-msb and
+ * nickname-len-lsb will both be zero.
+ */
+struct _certDBEntryCert {
+ certDBEntryCommon common;
+ NSSLOWCERTCertTrust trust;
+ SECItem derCert;
+ char *nickname;
+};
+
+/*
+ * Certificate Nickname entry:
+ *
+ * byte offset field
+ * ----------- -----
+ * 0 subjectname-len-msb
+ * 1 subjectname-len-lsb
+ * 2... subjectname
+ *
+ * The database key for this type of entry is a nickname string
+ * The "subjectname" value is the DER encoded DN of the identity
+ * that matches this nickname.
+ */
+typedef struct {
+ certDBEntryCommon common;
+ char *nickname;
+ SECItem subjectName;
+} certDBEntryNickname;
+
+#define DB_NICKNAME_ENTRY_HEADER_LEN 2
+
+/*
+ * Certificate Subject entry:
+ *
+ * byte offset field
+ * ----------- -----
+ * 0 ncerts-msb
+ * 1 ncerts-lsb
+ * 2 nickname-msb
+ * 3 nickname-lsb
+ * 4 emailAddr-msb
+ * 5 emailAddr-lsb
+ * ... nickname
+ * ... emailAddr
+ * ...+2*i certkey-len-msb
+ * ...+1+2*i certkey-len-lsb
+ * ...+2*ncerts+2*i keyid-len-msb
+ * ...+1+2*ncerts+2*i keyid-len-lsb
+ * ... certkeys
+ * ... keyids
+ *
+ * The database key for this type of entry is the DER encoded subject name
+ * The "certkey" value is an array of certificate database lookup keys that
+ * points to the database entries for the certificates that matche
+ * this subject.
+ *
+ */
+typedef struct _certDBEntrySubject {
+ certDBEntryCommon common;
+ SECItem derSubject;
+ unsigned int ncerts;
+ char *nickname;
+ char *emailAddr;
+ SECItem *certKeys;
+ SECItem *keyIDs;
+} certDBEntrySubject;
+
+#define DB_SUBJECT_ENTRY_HEADER_LEN 6
+
+/*
+ * Certificate SMIME profile entry:
+ *
+ * byte offset field
+ * ----------- -----
+ * 0 subjectname-len-msb
+ * 1 subjectname-len-lsb
+ * 2 smimeoptions-len-msb
+ * 3 smimeoptions-len-lsb
+ * 4 options-date-len-msb
+ * 5 options-date-len-lsb
+ * 6... subjectname
+ * ... smimeoptions
+ * ... options-date
+ *
+ * The database key for this type of entry is the email address string
+ * The "subjectname" value is the DER encoded DN of the identity
+ * that matches this nickname.
+ * The "smimeoptions" value is a string that represents the algorithm
+ * capabilities on the remote user.
+ * The "options-date" is the date that the smime options value was created.
+ * This is generally the signing time of the signed message that contained
+ * the options. It is a UTCTime value.
+ */
+typedef struct {
+ certDBEntryCommon common;
+ char *emailAddr;
+ SECItem subjectName;
+ SECItem smimeOptions;
+ SECItem optionsDate;
+} certDBEntrySMime;
+
+#define DB_SMIME_ENTRY_HEADER_LEN 6
+
+/*
+ * Crl/krl entry:
+ *
+ * byte offset field
+ * ----------- -----
+ * 0 derCert-len-msb
+ * 1 derCert-len-lsb
+ * 2 url-len-msb
+ * 3 url-len-lsb
+ * ... derCert
+ * ... url
+ *
+ * NOTE: the url string as stored in the database is null terminated,
+ * in other words, the last byte of the db entry is always 0
+ * if a nickname is present.
+ * NOTE: if url is not present, then url-len-msb and
+ * url-len-lsb will both be zero.
+ */
+#define DB_CRL_ENTRY_HEADER_LEN 4
+struct _certDBEntryRevocation {
+ certDBEntryCommon common;
+ SECItem derCrl;
+ char *url; /* where to load the crl from */
+};
+
+/*
+ * Database Version Entry:
+ *
+ * byte offset field
+ * ----------- -----
+ * only the low level header...
+ *
+ * The database key for this type of entry is the string "Version"
+ */
+typedef struct {
+ certDBEntryCommon common;
+} certDBEntryVersion;
+
+#define SEC_DB_VERSION_KEY "Version"
+#define SEC_DB_VERSION_KEY_LEN sizeof(SEC_DB_VERSION_KEY)
+
+/*
+ * Database Content Version Entry:
+ *
+ * byte offset field
+ * ----------- -----
+ * 0 contentVersion
+ *
+ * The database key for this type of entry is the string "ContentVersion"
+ */
+typedef struct {
+ certDBEntryCommon common;
+ char contentVersion;
+} certDBEntryContentVersion;
+
+#define SEC_DB_CONTENT_VERSION_KEY "ContentVersion"
+#define SEC_DB_CONTENT_VERSION_KEY_LEN sizeof(SEC_DB_CONTENT_VERSION_KEY)
+
+typedef union {
+ certDBEntryCommon common;
+ certDBEntryVersion version;
+ certDBEntryCert cert;
+ certDBEntryNickname nickname;
+ certDBEntrySubject subject;
+ certDBEntryRevocation revocation;
+} certDBEntry;
+
+/* length of the fixed part of a database entry */
+#define DBCERT_V4_HEADER_LEN 7
+#define DB_CERT_V5_ENTRY_HEADER_LEN 7
+#define DB_CERT_V6_ENTRY_HEADER_LEN 7
+#define DB_CERT_ENTRY_HEADER_LEN 10
+
+/* common flags for all types of certificates */
+#define CERTDB_VALID_PEER (1<<0)
+#define CERTDB_TRUSTED (1<<1)
+#define CERTDB_SEND_WARN (1<<2)
+#define CERTDB_VALID_CA (1<<3)
+#define CERTDB_TRUSTED_CA (1<<4) /* trusted for issuing server certs */
+#define CERTDB_NS_TRUSTED_CA (1<<5)
+#define CERTDB_USER (1<<6)
+#define CERTDB_TRUSTED_CLIENT_CA (1<<7) /* trusted for issuing client certs */
+#define CERTDB_INVISIBLE_CA (1<<8) /* don't show in UI */
+#define CERTDB_GOVT_APPROVED_CA (1<<9) /* can do strong crypto in export ver */
+#define CERTDB_NOT_TRUSTED (1<<10) /* explicitly don't trust this cert */
+#define CERTDB_TRUSTED_UNKNOWN (1<<11) /* accept trust from another source */
+
+/* bits not affected by the CKO_NETSCAPE_TRUST object */
+#define CERTDB_PRESERVE_TRUST_BITS (CERTDB_USER | CERTDB_VALID_PEER | \
+ CERTDB_NS_TRUSTED_CA | CERTDB_VALID_CA | CERTDB_INVISIBLE_CA | \
+ CERTDB_GOVT_APPROVED_CA)
+
+#endif /* _PCERTT_H_ */
diff --git a/security/nss/lib/softoken/pk11db.c b/security/nss/lib/softoken/pk11db.c
index ee0e94d0e..162d53714 100644
--- a/security/nss/lib/softoken/pk11db.c
+++ b/security/nss/lib/softoken/pk11db.c
@@ -38,68 +38,210 @@
#include "pk11pars.h"
#include "pkcs11i.h"
+#include "mcom_db.h"
#define FREE_CLEAR(p) if (p) { PORT_Free(p); p = NULL; }
static void
-secmod_parseFlags(char *tmp, pk11_parameters *parsed) {
+secmod_parseTokenFlags(char *tmp, pk11_token_parameters *parsed) {
parsed->readOnly = pk11_argHasFlag("flags","readOnly",tmp);
parsed->noCertDB = pk11_argHasFlag("flags","noCertDB",tmp);
+ parsed->noKeyDB = pk11_argHasFlag("flags","noKeyDB",tmp);
+ parsed->forceOpen = pk11_argHasFlag("flags","forceOpen",tmp);
+ parsed->pwRequired = pk11_argHasFlag("flags","passwordRequired",tmp);
+ return;
+}
+
+static void
+secmod_parseFlags(char *tmp, pk11_parameters *parsed) {
parsed->noModDB = pk11_argHasFlag("flags","noModDB",tmp);
+ parsed->readOnly = pk11_argHasFlag("flags","readOnly",tmp);
+ /* keep legacy interface working */
+ parsed->noCertDB = pk11_argHasFlag("flags","noCertDB",tmp);
parsed->forceOpen = pk11_argHasFlag("flags","forceOpen",tmp);
parsed->pwRequired = pk11_argHasFlag("flags","passwordRequired",tmp);
return;
}
+CK_RV
+secmod_parseTokenParameters(char *param, pk11_token_parameters *parsed)
+{
+ int next;
+ char *tmp;
+ char *index;
+ index = pk11_argStrip(param);
+
+ while (*index) {
+ PK11_HANDLE_STRING_ARG(index,parsed->configdir,"configdir=",;)
+ PK11_HANDLE_STRING_ARG(index,parsed->certPrefix,"certprefix=",;)
+ PK11_HANDLE_STRING_ARG(index,parsed->keyPrefix,"keyprefix=",;)
+ PK11_HANDLE_STRING_ARG(index,parsed->tokdes,"tokenDescription=",;)
+ PK11_HANDLE_STRING_ARG(index,parsed->slotdes,"slotDescription=",;)
+ PK11_HANDLE_STRING_ARG(index,tmp,"minPWLen=",
+ if(tmp) { parsed->minPW=atoi(tmp); PORT_Free(tmp); })
+ PK11_HANDLE_STRING_ARG(index,tmp,"flags=",
+ if(tmp) { secmod_parseTokenFlags(param,parsed); PORT_Free(tmp); })
+ PK11_HANDLE_FINAL_ARG(index)
+ }
+ return CKR_OK;
+}
+
+static void
+secmod_parseTokens(char *tokenParams, pk11_parameters *parsed)
+{
+ char *tokenIndex;
+ pk11_token_parameters *tokens = NULL;
+ int i=0,count = 0,next;
+
+ if ((tokenParams == NULL) || (*tokenParams == 0)) return;
+ /* first count the number of slots */
+ for (tokenIndex = pk11_argStrip(tokenParams); *tokenIndex;
+ tokenIndex = pk11_argStrip(pk11_argSkipParameter(tokenIndex))) {
+ count++;
+ }
+
+ /* get the data structures */
+ tokens = (pk11_token_parameters *)
+ PORT_ZAlloc(count*sizeof(pk11_token_parameters));
+ if (tokens == NULL) return;
+
+ for (tokenIndex = pk11_argStrip(tokenParams), i = 0;
+ *tokenIndex && i < count ; i++ ) {
+ char *name;
+ name = pk11_argGetName(tokenIndex,&next);
+ tokenIndex += next;
+
+ tokens[i].slotID = pk11_argDecodeNumber(name);
+ tokens[i].readOnly = PR_TRUE;
+ tokens[i].noCertDB = PR_TRUE;
+ tokens[i].noKeyDB = PR_TRUE;
+ if (!pk11_argIsBlank(*tokenIndex)) {
+ char *args = pk11_argFetchValue(tokenIndex,&next);
+ tokenIndex += next;
+ if (args) {
+ secmod_parseTokenParameters(args,&tokens[i]);
+ PORT_Free(args);
+ }
+ }
+ if (name) PORT_Free(name);
+ tokenIndex = pk11_argStrip(tokenIndex);
+ }
+ parsed->token_count = i;
+ parsed->tokens = tokens;
+ return;
+}
CK_RV
-secmod_parseParameters(char *param, pk11_parameters *parsed)
+secmod_parseParameters(char *param, pk11_parameters *parsed, PRBool isFIPS)
{
int next;
char *tmp;
char *index;
+ char *certPrefix = NULL, *keyPrefix = NULL;
+ char *tokdes = NULL, *ptokdes = NULL;
+ char *slotdes = NULL, *pslotdes = NULL;
+ char *fslotdes = NULL, *fpslotdes = NULL;
+ char *minPW = NULL;
index = pk11_argStrip(param);
PORT_Memset(parsed, 0, sizeof(pk11_parameters));
while (*index) {
PK11_HANDLE_STRING_ARG(index,parsed->configdir,"configdir=",;)
- PK11_HANDLE_STRING_ARG(index,parsed->certPrefix,"certprefix=",;)
- PK11_HANDLE_STRING_ARG(index,parsed->keyPrefix,"keyprefix=",;)
PK11_HANDLE_STRING_ARG(index,parsed->secmodName,"secmod=",;)
PK11_HANDLE_STRING_ARG(index,parsed->man,"manufactureID=",;)
PK11_HANDLE_STRING_ARG(index,parsed->libdes,"libraryDescription=",;)
- PK11_HANDLE_STRING_ARG(index,parsed->tokdes,"cryptoTokenDescription=",;)
- PK11_HANDLE_STRING_ARG(index,parsed->ptokdes,"dbTokenDescription=",;)
- PK11_HANDLE_STRING_ARG(index,parsed->slotdes,"cryptoSlotDescription=",;)
- PK11_HANDLE_STRING_ARG(index,parsed->pslotdes,"dbSlotDescription=",;)
- PK11_HANDLE_STRING_ARG(index,parsed->fslotdes,"FIPSSlotDescription=",;)
- PK11_HANDLE_STRING_ARG(index,parsed->fpslotdes,"FIPSTokenDescription=",;)
- PK11_HANDLE_STRING_ARG(index,tmp,"minPWLen=",
- if(tmp) { parsed->minPW=atoi(tmp); PORT_Free(tmp); })
+ /* constructed values, used so legacy interfaces still work */
+ PK11_HANDLE_STRING_ARG(index,certPrefix,"certprefix=",;)
+ PK11_HANDLE_STRING_ARG(index,keyPrefix,"keyprefix=",;)
+ PK11_HANDLE_STRING_ARG(index,tokdes,"cryptoTokenDescription=",;)
+ PK11_HANDLE_STRING_ARG(index,ptokdes,"dbTokenDescription=",;)
+ PK11_HANDLE_STRING_ARG(index,slotdes,"cryptoSlotDescription=",;)
+ PK11_HANDLE_STRING_ARG(index,pslotdes,"dbSlotDescription=",;)
+ PK11_HANDLE_STRING_ARG(index,fslotdes,"FIPSSlotDescription=",;)
+ PK11_HANDLE_STRING_ARG(index,minPW,"FIPSTokenDescription=",;)
+ PK11_HANDLE_STRING_ARG(index,tmp,"minPWLen=",;)
+
PK11_HANDLE_STRING_ARG(index,tmp,"flags=",
if(tmp) { secmod_parseFlags(param,parsed); PORT_Free(tmp); })
+ PK11_HANDLE_STRING_ARG(index,tmp,"tokens=",
+ if(tmp) { secmod_parseTokens(tmp,parsed); PORT_Free(tmp); })
PK11_HANDLE_FINAL_ARG(index)
- }
- return CKR_OK;
+ }
+ if (parsed->tokens == NULL) {
+ int count = isFIPS ? 1 : 2;
+ int index = count-1;
+ pk11_token_parameters *tokens = NULL;
+
+ tokens = (pk11_token_parameters *)
+ PORT_ZAlloc(count*sizeof(pk11_token_parameters));
+ if (tokens == NULL) {
+ goto loser;
+ }
+ parsed->tokens = tokens;
+ parsed->token_count = count;
+ tokens[index].slotID = isFIPS ? FIPS_SLOT_ID : PRIVATE_KEY_SLOT_ID;
+ tokens[index].certPrefix = certPrefix;
+ tokens[index].keyPrefix = keyPrefix;
+ tokens[index].minPW = minPW ? atoi(minPW) : 0;
+ tokens[index].readOnly = parsed->readOnly;
+ tokens[index].noCertDB = parsed->noCertDB;
+ tokens[index].forceOpen = parsed->forceOpen;
+ tokens[index].pwRequired = parsed->pwRequired;
+ certPrefix = NULL;
+ keyPrefix = NULL;
+ if (isFIPS) {
+ tokens[index].tokdes = fslotdes;
+ tokens[index].slotdes = fpslotdes;
+ fslotdes = NULL;
+ fpslotdes = NULL;
+ } else {
+ tokens[index].tokdes = ptokdes;
+ tokens[index].slotdes = pslotdes;
+ tokens[0].slotID = NETSCAPE_SLOT_ID;
+ tokens[0].tokdes = tokdes;
+ tokens[0].slotdes = slotdes;
+ tokens[0].noCertDB = PR_TRUE;
+ tokens[0].noKeyDB = PR_TRUE;
+ ptokdes = NULL;
+ pslotdes = NULL;
+ tokdes = NULL;
+ slotdes = NULL;
+ }
+ }
+
+loser:
+ FREE_CLEAR(certPrefix);
+ FREE_CLEAR(keyPrefix);
+ FREE_CLEAR(tokdes);
+ FREE_CLEAR(ptokdes);
+ FREE_CLEAR(slotdes);
+ FREE_CLEAR(pslotdes);
+ FREE_CLEAR(fslotdes);
+ FREE_CLEAR(fpslotdes);
+ FREE_CLEAR(minPW);
+ return CKR_OK;
}
void
secmod_freeParams(pk11_parameters *params)
{
+ int i;
+
+ for (i=0; i < params->token_count; i++) {
+ FREE_CLEAR(params->tokens[i].configdir);
+ FREE_CLEAR(params->tokens[i].certPrefix);
+ FREE_CLEAR(params->tokens[i].keyPrefix);
+ FREE_CLEAR(params->tokens[i].tokdes);
+ FREE_CLEAR(params->tokens[i].slotdes);
+ }
+
FREE_CLEAR(params->configdir);
- FREE_CLEAR(params->certPrefix);
- FREE_CLEAR(params->keyPrefix);
FREE_CLEAR(params->secmodName);
FREE_CLEAR(params->man);
FREE_CLEAR(params->libdes);
- FREE_CLEAR(params->tokdes);
- FREE_CLEAR(params->ptokdes);
- FREE_CLEAR(params->slotdes);
- FREE_CLEAR(params->pslotdes);
- FREE_CLEAR(params->fslotdes);
- FREE_CLEAR(params->fpslotdes);
+ FREE_CLEAR(params->tokens);
}
@@ -462,7 +604,7 @@ secmod_DecodeData(char *defParams, DBT *data, PRBool *retInternal)
trustOrder = 20;
}
- slotStrings[i] = pk11_mkSlotString(slotID,defaultFlags,
+ slotStrings[i] = pk11_mkSlotString(slotID,defaultFlags,
timeout,slots[i].askpw,hasRootCerts,hasRootTrust);
}
@@ -488,7 +630,7 @@ static DB *secmod_OpenDB(char *dbName, PRBool readOnly) {
if (readOnly) return NULL;
pkcs11db = dbopen( dbName,
- O_RDWR | O_CREAT | O_TRUNC, 0600, DB_HASH, 0 );
+ O_RDWR | O_CREAT | O_TRUNC, 0600, DB_HASH, 0 );
if (pkcs11db) (* pkcs11db->sync)(pkcs11db, 0);
}
return pkcs11db;
diff --git a/security/nss/lib/softoken/pk11pars.h b/security/nss/lib/softoken/pk11pars.h
index 7710820ab..9e273f104 100644
--- a/security/nss/lib/softoken/pk11pars.h
+++ b/security/nss/lib/softoken/pk11pars.h
@@ -45,8 +45,8 @@
#include "pkcs11.h"
#include "seccomon.h"
#include "prprf.h"
-#include "secmod.h"
-#include "secmodi.h"
+#include "secmodt.h"
+#include "pk11init.h"
#define PK11_ARG_LIBRARY_PARAMETER "library="
#define PK11_ARG_NAME_PARAMETER "name="
diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c
index 78a26cebf..e6eaf1f1e 100644
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -52,14 +52,13 @@
#include "pkcs11.h"
#include "pkcs11i.h"
#include "softoken.h"
-#include "cert.h"
-#include "keylow.h"
+#include "lowkeyi.h"
#include "blapi.h"
#include "secder.h"
#include "secport.h"
-#include "certdb.h"
+#include "pcert.h"
-#include "private.h"
+#include "keydbi.h"
/*
@@ -71,6 +70,7 @@ static char *manufacturerID = "mozilla.org ";
static char manufacturerID_space[33];
static char *libraryDescription = "NSS Internal Crypto Services ";
static char libraryDescription_space[33];
+#ifdef notdef
static char *tokDescription = "NSS Generic Crypto Services ";
static char tokDescription_space[33];
static char *privTokDescription = "NSS Certificate DB ";
@@ -83,7 +83,13 @@ static char slotDescription_space[65];
static char *privSlotDescription =
"NSS User Private Key and Certificate Services ";
static char privSlotDescription_space[65];
-static int minimumPinLen = 0;
+/* The next two strings must be exactly 64 characters long, with the
+ first 32 characters meaningful */
+static char *slotDescription =
+ "Netscape Internal FIPS-140-1 Cryptographic Services ";
+static char *privSlotDescription =
+ "Netscape FIPS-140-1 User Private Key Services ";
+#endif
#define __PASTE(x,y) x##y
@@ -104,7 +110,7 @@ static int minimumPinLen = 0;
/* build the crypto module table */
-static CK_FUNCTION_LIST pk11_funcList = {
+static const CK_FUNCTION_LIST pk11_funcList = {
{ 1, 10 },
#undef CK_PKCS11_FUNCTION_INFO
@@ -124,7 +130,7 @@ static CK_FUNCTION_LIST pk11_funcList = {
/* List of DES Weak Keys */
typedef unsigned char desKey[8];
-static desKey pk11_desWeakTable[] = {
+static const desKey pk11_desWeakTable[] = {
#ifdef noParity
/* weak */
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
@@ -178,12 +184,12 @@ static desKey pk11_desWeakTable[] = {
};
-static int pk11_desWeakTableSize = sizeof(pk11_desWeakTable)/
+static const int pk11_desWeakTableSize = sizeof(pk11_desWeakTable)/
sizeof(pk11_desWeakTable[0]);
/* DES KEY Parity conversion table. Takes each byte/2 as an index, returns
* that byte with the proper parity bit set */
-static unsigned char parityTable[256] = {
+static const unsigned char parityTable[256] = {
/* Even...0x00,0x02,0x04,0x06,0x08,0x0a,0x0c,0x0e */
/* E */ 0x01,0x02,0x04,0x07,0x08,0x0b,0x0d,0x0e,
/* Odd....0x10,0x12,0x14,0x16,0x18,0x1a,0x1c,0x1e */
@@ -239,7 +245,9 @@ struct mechanismList {
#define CKF_SN_VR_RE CKF_SN_VR | CKF_SN_RE
#define CKF_DUZ_IT_ALL CKF_EN_DE_WR_UN | CKF_SN_VR_RE
-static struct mechanismList mechanisms[] = {
+#define CK_MAX 0xffffffff
+
+static const struct mechanismList mechanisms[] = {
/*
* PKCS #11 Mechanism List.
@@ -262,16 +270,16 @@ static struct mechanismList mechanisms[] = {
*/
/* ------------------------- RSA Operations ---------------------------*/
- {CKM_RSA_PKCS_KEY_PAIR_GEN,{128,0xffffffff,CKF_GENERATE_KEY_PAIR},PR_TRUE},
- {CKM_RSA_PKCS, {128,0xffffffff, CKF_DUZ_IT_ALL},PR_TRUE},
+ {CKM_RSA_PKCS_KEY_PAIR_GEN,{128,CK_MAX,CKF_GENERATE_KEY_PAIR},PR_TRUE},
+ {CKM_RSA_PKCS, {128,CK_MAX,CKF_DUZ_IT_ALL}, PR_TRUE},
#ifdef PK11_RSA9796_SUPPORTED
- {CKM_RSA_9796, {128,0xffffffff, CKF_DUZ_IT_ALL},PR_TRUE},
+ {CKM_RSA_9796, {128,CK_MAX,CKF_DUZ_IT_ALL}, PR_TRUE},
#endif
- {CKM_RSA_X_509, {128,0xffffffff, CKF_DUZ_IT_ALL},PR_TRUE},
+ {CKM_RSA_X_509, {128,CK_MAX,CKF_DUZ_IT_ALL}, PR_TRUE},
/* -------------- RSA Multipart Signing Operations -------------------- */
- {CKM_MD2_RSA_PKCS, {128,0xffffffff, CKF_SN_VR}, PR_TRUE},
- {CKM_MD5_RSA_PKCS, {128,0xffffffff, CKF_SN_VR}, PR_TRUE},
- {CKM_SHA1_RSA_PKCS, {128,0xffffffff, CKF_SN_VR}, PR_TRUE},
+ {CKM_MD2_RSA_PKCS, {128,CK_MAX,CKF_SN_VR}, PR_TRUE},
+ {CKM_MD5_RSA_PKCS, {128,CK_MAX,CKF_SN_VR}, PR_TRUE},
+ {CKM_SHA1_RSA_PKCS, {128,CK_MAX,CKF_SN_VR}, PR_TRUE},
/* ------------------------- DSA Operations --------------------------- */
{CKM_DSA_KEY_PAIR_GEN, {512, 1024, CKF_GENERATE_KEY_PAIR}, PR_TRUE},
{CKM_DSA, {512, 1024, CKF_SN_VR}, PR_TRUE},
@@ -330,7 +338,7 @@ static struct mechanismList mechanisms[] = {
{CKM_SHA_1_HMAC_GENERAL, {1, 128, CKF_SN_VR}, PR_FALSE},
{CKM_TLS_PRF_GENERAL, {0, 512, CKF_SN_VR}, PR_FALSE},
/* ------------------------- CAST Operations --------------------------- */
-#ifdef PK11_CAST_SUPPORTED
+#ifdef NSS_SOFTOKEN_DOES_CAST
/* Cast operations are not supported ( yet? ) */
{CKM_CAST_KEY_GEN, {1, 8, CKF_GENERATE}, PR_FALSE},
{CKM_CAST_ECB, {1, 8, CKF_EN_DE_WR_UN}, PR_FALSE},
@@ -354,13 +362,13 @@ static struct mechanismList mechanisms[] = {
#if NSS_SOFTOKEN_DOES_RC5
/* ------------------------- RC5 Operations --------------------------- */
{CKM_RC5_KEY_GEN, {1, 32, CKF_GENERATE}, PR_FALSE},
- {CKM_RC5_ECB, {1, 32, CKF_EN_DE_WR_UN}, PR_FALSE},
+ {CKM_RC5_ECB, {1, 32, CKF_EN_DE_WR_UN}, PR_FALSE},
{CKM_RC5_CBC, {1, 32, CKF_EN_DE_WR_UN}, PR_FALSE},
{CKM_RC5_MAC, {1, 32, CKF_SN_VR}, PR_FALSE},
{CKM_RC5_MAC_GENERAL, {1, 32, CKF_SN_VR}, PR_FALSE},
{CKM_RC5_CBC_PAD, {1, 32, CKF_EN_DE_WR_UN}, PR_FALSE},
#endif
-#ifdef PK11_IDEA_SUPPORTED
+#ifdef NSS_SOFTOKEN_DOES_IDEA
/* ------------------------- IDEA Operations -------------------------- */
{CKM_IDEA_KEY_GEN, {16, 16, CKF_GENERATE}, PR_FALSE},
{CKM_IDEA_ECB, {16, 16, CKF_EN_DE_WR_UN}, PR_FALSE},
@@ -394,26 +402,19 @@ static struct mechanismList mechanisms[] = {
{CKM_PBE_MD5_DES_CBC, {8, 8, CKF_DERIVE}, PR_TRUE},
/* ------------------ NETSCAPE PBE Key Derivations ------------------- */
{CKM_NETSCAPE_PBE_SHA1_DES_CBC, { 8, 8, CKF_GENERATE}, PR_TRUE},
- {CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC, {24,24, CKF_GENERATE}, PR_TRUE},
{CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC, {24,24, CKF_GENERATE}, PR_TRUE},
- {CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC, {40,40, CKF_GENERATE}, PR_TRUE},
- {CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC, {40,40, CKF_GENERATE}, PR_TRUE},
- {CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4, {40,40, CKF_GENERATE}, PR_TRUE},
- {CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4, {128,128, CKF_GENERATE}, PR_TRUE},
{CKM_PBE_SHA1_DES3_EDE_CBC, {24,24, CKF_GENERATE}, PR_TRUE},
{CKM_PBE_SHA1_DES2_EDE_CBC, {24,24, CKF_GENERATE}, PR_TRUE},
{CKM_PBE_SHA1_RC2_40_CBC, {40,40, CKF_GENERATE}, PR_TRUE},
{CKM_PBE_SHA1_RC2_128_CBC, {128,128, CKF_GENERATE}, PR_TRUE},
{CKM_PBE_SHA1_RC4_40, {40,40, CKF_GENERATE}, PR_TRUE},
{CKM_PBE_SHA1_RC4_128, {128,128, CKF_GENERATE}, PR_TRUE},
- {CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN, {1,32, CKF_GENERATE}, PR_TRUE},
- {CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN, {1,32, CKF_GENERATE}, PR_TRUE},
- {CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN, {1,32, CKF_GENERATE}, PR_TRUE},
+ {CKM_PBA_SHA1_WITH_SHA1_HMAC, {20,20, CKF_GENERATE}, PR_TRUE},
+ {CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN, {20,20, CKF_GENERATE}, PR_TRUE},
+ {CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN, {16,16, CKF_GENERATE}, PR_TRUE},
+ {CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN, {16,16, CKF_GENERATE}, PR_TRUE},
};
static CK_ULONG mechanismCount = sizeof(mechanisms)/sizeof(mechanisms[0]);
-/* load up our token database */
-static CK_RV pk11_importKeyDB(PK11Slot *slot);
-
static char *
pk11_setStringName(char *inString, char *buffer, int buffer_length) {
@@ -431,9 +432,7 @@ pk11_setStringName(char *inString, char *buffer, int buffer_length) {
* Configuration utils
*/
static CK_RV
-pk11_configure(char *man, char *libdes, char *tokdes, char *ptokdes,
- char *slotdes, char *pslotdes, char *fslotdes, char *fpslotdes,
- int minPwd, int pwRequired)
+pk11_configure(char *man, char *libdes)
{
/* make sure the internationalization was done correctly... */
@@ -445,32 +444,6 @@ pk11_configure(char *man, char *libdes, char *tokdes, char *ptokdes,
libraryDescription = pk11_setStringName(libdes,
libraryDescription_space, sizeof(libraryDescription_space));
}
- if (tokdes) {
- tokDescription = pk11_setStringName(tokdes,tokDescription_space,
- sizeof(tokDescription_space));
- }
- if (ptokdes) {
- privTokDescription = pk11_setStringName(ptokdes,
- privTokDescription_space, sizeof(privTokDescription_space));
- }
- if (slotdes) {
- slotDescription = pk11_setStringName(slotdes,slotDescription_space,
- sizeof(slotDescription_space));
- }
- if (pslotdes) {
- privSlotDescription = pk11_setStringName(pslotdes,
- privSlotDescription_space, sizeof(privSlotDescription_space));
- }
-
- if (minimumPinLen <= PK11_MAX_PIN) {
- minimumPinLen = minPwd;
- }
- if ((minimumPinLen == 0) && (pwRequired) &&
- (minimumPinLen <= PK11_MAX_PIN)) {
- minimumPinLen = 1;
- }
-
- PK11_ConfigureFIPS(fslotdes,fpslotdes);
return CKR_OK;
}
@@ -479,33 +452,20 @@ pk11_configure(char *man, char *libdes, char *tokdes, char *ptokdes,
* ******************** Password Utilities *******************************
*/
-/* Handle to give the password to the database. user arg should be a pointer
- * to the slot. */
-static SECItem *pk11_givePass(void *sp,SECKEYKeyDBHandle *handle)
-{
- PK11Slot *slot = (PK11Slot *)sp;
-
- if (slot->password == NULL) return NULL;
-
- return SECITEM_DupItem(slot->password);
-}
-
/*
* see if the key DB password is enabled
*/
PRBool
-pk11_hasNullPassword(SECItem **pwitem)
+pk11_hasNullPassword(NSSLOWKEYDBHandle *keydb,SECItem **pwitem)
{
PRBool pwenabled;
- SECKEYKeyDBHandle *keydb;
- keydb = SECKEY_GetDefaultKeyDB();
pwenabled = PR_FALSE;
*pwitem = NULL;
- if (SECKEY_HasKeyDBPassword (keydb) == SECSuccess) {
- *pwitem = SECKEY_HashPassword("", keydb->global_salt);
+ if (nsslowkey_HasKeyDBPassword (keydb) == SECSuccess) {
+ *pwitem = nsslowkey_HashPassword("", keydb->global_salt);
if ( *pwitem ) {
- if (SECKEY_CheckKeyDBPassword (keydb, *pwitem) == SECSuccess) {
+ if (nsslowkey_CheckKeyDBPassword (keydb, *pwitem) == SECSuccess) {
pwenabled = PR_TRUE;
} else {
SECITEM_ZfreeItem(*pwitem, PR_TRUE);
@@ -563,13 +523,12 @@ pk11_handleDataObject(PK11Session *session,PK11Object *object)
static CK_RV
pk11_handleCertObject(PK11Session *session,PK11Object *object)
{
- PK11Attribute *attribute;
CK_CERTIFICATE_TYPE type;
- SECItem derCert;
- char *label;
- CERTCertDBHandle *handle;
- CERTCertificate *cert;
+ PK11Attribute *attribute;
CK_RV crv;
+ PK11SessionObject *sessObject = pk11_narrowToSessionObject(object);
+
+ PORT_Assert(sessObject);
/* certificates must have a type */
if ( !pk11_hasAttribute(object,CKA_CERTIFICATE_TYPE) ) {
@@ -603,99 +562,393 @@ pk11_handleCertObject(PK11Session *session,PK11Object *object)
return CKR_TEMPLATE_INCOMPLETE;
}
- /*
- * now parse the certificate
- */
- handle = CERT_GetDefaultCertDB();
-
- /* get the nickname */
- label = pk11_getString(object,CKA_LABEL);
- object->label = label;
- if (label == NULL) {
- return CKR_HOST_MEMORY;
+ /* in PKCS #11, Issuer is a required field */
+ if ( !pk11_hasAttribute(object,CKA_ISSUER) ) {
+ return CKR_TEMPLATE_INCOMPLETE;
}
-
- /* get the der cert */
- attribute = pk11_FindAttribute(object,CKA_VALUE);
- derCert.data = (unsigned char *)attribute->attrib.pValue;
- derCert.len = attribute->attrib.ulValueLen ;
-
- cert = CERT_NewTempCertificate(handle, &derCert, label, PR_FALSE, PR_TRUE);
- pk11_FreeAttribute(attribute);
- if (cert == NULL) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ /* in PKCS #11, Serial is a required field */
+ if ( !pk11_hasAttribute(object,CKA_SERIAL_NUMBER) ) {
+ return CKR_TEMPLATE_INCOMPLETE;
}
/* add it to the object */
- object->objectInfo = cert;
- object->infoFree = (PK11Free) CERT_DestroyCertificate;
+ object->objectInfo = NULL;
+ object->infoFree = (PK11Free) NULL;
/* now just verify the required date fields */
crv = pk11_defaultAttribute(object, CKA_ID, NULL, 0);
if (crv != CKR_OK) { return crv; }
- crv = pk11_defaultAttribute(object,CKA_ISSUER,
- pk11_item_expand(&cert->derIssuer));
- if (crv != CKR_OK) { return crv; }
- crv = pk11_defaultAttribute(object,CKA_SERIAL_NUMBER,
- pk11_item_expand(&cert->serialNumber));
- if (crv != CKR_OK) { return crv; }
-
if (pk11_isTrue(object,CKA_TOKEN)) {
- SECCertUsage *certUsage = NULL;
- CERTCertTrust trust = { CERTDB_USER, CERTDB_USER, CERTDB_USER };
+ PK11Slot *slot = session->slot;
+ SECItem derCert;
+ NSSLOWCERTCertificate *cert;
+ NSSLOWCERTCertTrust *trust = NULL;
+ NSSLOWCERTCertTrust userTrust =
+ { CERTDB_USER, CERTDB_USER, CERTDB_USER };
+ NSSLOWCERTCertTrust defTrust =
+ { CERTDB_TRUSTED_UNKNOWN,
+ CERTDB_TRUSTED_UNKNOWN, CERTDB_TRUSTED_UNKNOWN };
+ char *label;
+ SECStatus rv;
+ PRBool inDB = PR_TRUE;
+
+ if (slot->certDB == NULL) {
+ return CKR_TOKEN_WRITE_PROTECTED;
+ }
+
+ /* get the der cert */
+ attribute = pk11_FindAttribute(object,CKA_VALUE);
+ PORT_Assert(attribute);
- attribute = pk11_FindAttribute(object,CKA_NETSCAPE_TRUST);
- if(attribute) {
- certUsage = (SECCertUsage*)attribute->attrib.pValue;
- pk11_FreeAttribute(attribute);
+ derCert.data = (unsigned char *)attribute->attrib.pValue;
+ derCert.len = attribute->attrib.ulValueLen ;
+
+ label = pk11_getString(object,CKA_LABEL);
+
+ cert = nsslowcert_FindCertByDERCert(slot->certDB, &derCert);
+ if (cert == NULL) {
+ cert = nsslowcert_DecodeDERCertificate(&derCert,PR_FALSE,label);
+ inDB = PR_FALSE;
+ }
+ if (cert == NULL) {
+ if (label) PORT_Free(label);
+ pk11_FreeAttribute(attribute);
+ return CKR_ATTRIBUTE_VALUE_INVALID;
}
- /* Temporary for PKCS 12 */
- if(cert->nickname == NULL) {
- /* use the arena so we at least don't leak memory */
- cert->nickname = PORT_ArenaStrdup(cert->arena, label);
+ if (slot->keyDB && nsslowkey_KeyForCertExists(slot->keyDB,cert)) {
+ trust = &userTrust;
+ }
+ if (!inDB) {
+ if (!trust) trust = &defTrust;
+ rv = nsslowcert_AddPermCert(slot->certDB, cert, label, trust);
+ } else {
+ rv = trust ? nsslowcert_ChangeCertTrust(slot->certDB,cert,trust) :
+ SECSuccess;
}
- /* only add certs that have a private key */
- if (SECKEY_KeyForCertExists(SECKEY_GetDefaultKeyDB(),cert)
- != SECSuccess) {
+ if (label) PORT_Free(label);
+ pk11_FreeAttribute(attribute);
+ if (rv != SECSuccess) {
+ nsslowcert_DestroyCertificate(cert);
+ return CKR_DEVICE_ERROR;
+ }
+ object->handle=pk11_mkHandle(slot,&cert->certKey,PK11_TOKEN_TYPE_CERT);
+ nsslowcert_DestroyCertificate(cert);
+ }
+
+ return CKR_OK;
+}
+unsigned int
+pk11_MapTrust(CK_TRUST trust, PRBool clientAuth)
+{
+ unsigned int trustCA = clientAuth ? CERTDB_TRUSTED_CLIENT_CA :
+ CERTDB_TRUSTED_CA;
+ switch (trust) {
+ case CKT_NETSCAPE_TRUSTED:
+ return CERTDB_VALID_PEER|CERTDB_TRUSTED;
+ case CKT_NETSCAPE_TRUSTED_DELEGATOR:
+ return CERTDB_VALID_CA|trustCA;
+ case CKT_NETSCAPE_UNTRUSTED:
+ return CERTDB_NOT_TRUSTED;
+ case CKT_NETSCAPE_MUST_VERIFY:
+ return 0;
+ case CKT_NETSCAPE_VALID: /* implies must verify */
+ return CERTDB_VALID_PEER;
+ case CKT_NETSCAPE_VALID_DELEGATOR: /* implies must verify */
+ return CERTDB_VALID_CA;
+ default:
+ break;
+ }
+ return CERTDB_TRUSTED_UNKNOWN;
+}
+
+
+/*
+ * check the consistancy and initialize a Trust Object
+ */
+static CK_RV
+pk11_handleTrustObject(PK11Session *session,PK11Object *object)
+{
+ NSSLOWCERTIssuerAndSN issuerSN;
+
+ /* we can't store any certs private */
+ if (pk11_isTrue(object,CKA_PRIVATE)) {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ /* certificates must have a type */
+ if ( !pk11_hasAttribute(object,CKA_ISSUER) ) {
+ return CKR_TEMPLATE_INCOMPLETE;
+ }
+ if ( !pk11_hasAttribute(object,CKA_SERIAL_NUMBER) ) {
+ return CKR_TEMPLATE_INCOMPLETE;
+ }
+ if ( !pk11_hasAttribute(object,CKA_CERT_SHA1_HASH) ) {
+ return CKR_TEMPLATE_INCOMPLETE;
+ }
+ if ( !pk11_hasAttribute(object,CKA_CERT_MD5_HASH) ) {
+ return CKR_TEMPLATE_INCOMPLETE;
+ }
+
+ if (pk11_isTrue(object,CKA_TOKEN)) {
+ PK11Slot *slot = session->slot;
+ PK11Attribute *issuer = NULL;
+ PK11Attribute *serial = NULL;
+ NSSLOWCERTCertificate *cert = NULL;
+ PK11Attribute *trust;
+ CK_TRUST sslTrust = CKT_NETSCAPE_TRUST_UNKNOWN;
+ CK_TRUST clientTrust = CKT_NETSCAPE_TRUST_UNKNOWN;
+ CK_TRUST emailTrust = CKT_NETSCAPE_TRUST_UNKNOWN;
+ CK_TRUST signTrust = CKT_NETSCAPE_TRUST_UNKNOWN;
+ NSSLOWCERTCertTrust dbTrust;
+ SECStatus rv;
+
+
+ if (slot->certDB == NULL) {
+ return CKR_TOKEN_WRITE_PROTECTED;
+ }
+ issuer = pk11_FindAttribute(object,CKA_ISSUER);
+ PORT_Assert(issuer);
+ issuerSN.derIssuer.data = (unsigned char *)issuer->attrib.pValue;
+ issuerSN.derIssuer.len = issuer->attrib.ulValueLen ;
+
+ serial = pk11_FindAttribute(object,CKA_SERIAL_NUMBER);
+ PORT_Assert(serial);
+ issuerSN.serialNumber.data = (unsigned char *)serial->attrib.pValue;
+ issuerSN.serialNumber.len = serial->attrib.ulValueLen ;
+
+ cert = nsslowcert_FindCertByIssuerAndSN(slot->certDB,&issuerSN);
+ pk11_FreeAttribute(serial);
+ pk11_FreeAttribute(issuer);
+
+ if (cert == NULL) {
return CKR_ATTRIBUTE_VALUE_INVALID;
}
- if (!cert->isperm) {
- if (CERT_AddTempCertToPerm(cert, label, &trust) != SECSuccess) {
- return CKR_HOST_MEMORY;
+
+ trust = pk11_FindAttribute(object,CKA_TRUST_SERVER_AUTH);
+ if (trust) {
+ if (trust->attrib.ulValueLen == sizeof(CK_TRUST)) {
+ PORT_Memcpy(&sslTrust,trust->attrib.pValue, sizeof(sslTrust));
+ }
+ pk11_FreeAttribute(trust);
+ }
+ trust = pk11_FindAttribute(object,CKA_TRUST_CLIENT_AUTH);
+ if (trust) {
+ if (trust->attrib.ulValueLen == sizeof(CK_TRUST)) {
+ PORT_Memcpy(&clientTrust,trust->attrib.pValue,
+ sizeof(clientTrust));
+ }
+ pk11_FreeAttribute(trust);
+ }
+ trust = pk11_FindAttribute(object,CKA_TRUST_EMAIL_PROTECTION);
+ if (trust) {
+ if (trust->attrib.ulValueLen == sizeof(CK_TRUST)) {
+ PORT_Memcpy(&emailTrust,trust->attrib.pValue,
+ sizeof(emailTrust));
}
- } else {
- CERT_ChangeCertTrust(cert->dbhandle,cert,&trust);
+ pk11_FreeAttribute(trust);
}
- if(certUsage) {
- if(CERT_ChangeCertTrustByUsage(CERT_GetDefaultCertDB(),
- cert, *certUsage) != SECSuccess) {
- return CKR_HOST_MEMORY;
+ trust = pk11_FindAttribute(object,CKA_TRUST_CODE_SIGNING);
+ if (trust) {
+ if (trust->attrib.ulValueLen == sizeof(CK_TRUST)) {
+ PORT_Memcpy(&signTrust,trust->attrib.pValue,
+ sizeof(signTrust));
}
+ pk11_FreeAttribute(trust);
+ }
+
+ /* preserve certain old fields */
+ if (cert->trust) {
+ dbTrust.sslFlags =
+ cert->trust->sslFlags & CERTDB_PRESERVE_TRUST_BITS;
+ dbTrust.emailFlags=
+ cert->trust->emailFlags & CERTDB_PRESERVE_TRUST_BITS;
+ dbTrust.objectSigningFlags =
+ cert->trust->objectSigningFlags & CERTDB_PRESERVE_TRUST_BITS;
+ }
+
+ dbTrust.sslFlags = pk11_MapTrust(sslTrust,PR_FALSE);
+ dbTrust.sslFlags |= pk11_MapTrust(clientTrust,PR_TRUE);
+ dbTrust.emailFlags = pk11_MapTrust(emailTrust,PR_FALSE);
+ dbTrust.objectSigningFlags = pk11_MapTrust(signTrust,PR_FALSE);
+
+ rv = nsslowcert_ChangeCertTrust(slot->certDB,cert,&dbTrust);
+ object->handle=pk11_mkHandle(slot,&cert->certKey,PK11_TOKEN_TYPE_TRUST);
+ nsslowcert_DestroyCertificate(cert);
+ if (rv != SECSuccess) {
+ return CKR_DEVICE_ERROR;
+ }
+ }
+
+ return CKR_OK;
+}
+
+/*
+ * check the consistancy and initialize a Trust Object
+ */
+static CK_RV
+pk11_handleSMimeObject(PK11Session *session,PK11Object *object)
+{
+
+ /* we can't store any certs private */
+ if (pk11_isTrue(object,CKA_PRIVATE)) {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ /* certificates must have a type */
+ if ( !pk11_hasAttribute(object,CKA_SUBJECT) ) {
+ return CKR_TEMPLATE_INCOMPLETE;
+ }
+ if ( !pk11_hasAttribute(object,CKA_NETSCAPE_SMIME_TIMESTAMP) ) {
+ return CKR_TEMPLATE_INCOMPLETE;
+ }
+ if ( !pk11_hasAttribute(object,CKA_NETSCAPE_EMAIL) ) {
+ return CKR_TEMPLATE_INCOMPLETE;
+ }
+ if ( !pk11_hasAttribute(object,CKA_VALUE) ) {
+ return CKR_TEMPLATE_INCOMPLETE;
+ }
+
+ if (pk11_isTrue(object,CKA_TOKEN)) {
+ PK11Slot *slot = session->slot;
+ SECItem derSubj,rawProfile,rawTime,emailKey;
+ char *email = NULL;
+ PK11Attribute *subject,*profile,*time;
+ SECStatus rv;
+
+ PORT_Assert(slot);
+ if (slot->certDB == NULL) {
+ return CKR_TOKEN_WRITE_PROTECTED;
+ }
+
+ /* lookup SUBJECT */
+ subject = pk11_FindAttribute(object,CKA_SUBJECT);
+ PORT_Assert(subject);
+ derSubj.data = (unsigned char *)subject->attrib.pValue;
+ derSubj.len = subject->attrib.ulValueLen ;
+
+ /* lookup VALUE */
+ profile = pk11_FindAttribute(object,CKA_VALUE);
+ PORT_Assert(profile);
+ rawProfile.data = (unsigned char *)profile->attrib.pValue;
+ rawProfile.len = profile->attrib.ulValueLen ;
+
+ /* lookup Time */
+ time = pk11_FindAttribute(object,CKA_NETSCAPE_SMIME_TIMESTAMP);
+ PORT_Assert(time);
+ rawTime.data = (unsigned char *)time->attrib.pValue;
+ rawTime.len = time->attrib.ulValueLen ;
+
+
+ email = pk11_getString(object,CKA_NETSCAPE_EMAIL);
+
+ /* Store CRL by SUBJECT */
+ rv = nsslowcert_SaveSMimeProfile(slot->certDB, email, &derSubj,
+ &rawProfile,&rawTime);
+
+ pk11_FreeAttribute(profile);
+ pk11_FreeAttribute(subject);
+ pk11_FreeAttribute(time);
+ if (rv != SECSuccess) {
+ PORT_Free(email);
+ return CKR_DEVICE_ERROR;
}
- object->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_CERT);
- object->inDB = PR_TRUE;
+ emailKey.data = (unsigned char *)email;
+ emailKey.len = PORT_Strlen(email)+1;
+
+ object->handle = pk11_mkHandle(slot, &emailKey, PK11_TOKEN_TYPE_SMIME);
+ PORT_Free(email);
+ }
+
+ return CKR_OK;
+}
+
+/*
+ * check the consistancy and initialize a Trust Object
+ */
+static CK_RV
+pk11_handleCrlObject(PK11Session *session,PK11Object *object)
+{
+
+ /* we can't store any certs private */
+ if (pk11_isTrue(object,CKA_PRIVATE)) {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ /* certificates must have a type */
+ if ( !pk11_hasAttribute(object,CKA_SUBJECT) ) {
+ return CKR_TEMPLATE_INCOMPLETE;
+ }
+ if ( !pk11_hasAttribute(object,CKA_VALUE) ) {
+ return CKR_TEMPLATE_INCOMPLETE;
}
- /* label has been adopted by object->label */
- /*PORT_Free(label); */
+ if (pk11_isTrue(object,CKA_TOKEN)) {
+ PK11Slot *slot = session->slot;
+ PRBool isKRL = PR_FALSE;
+ SECItem derSubj,derCrl;
+ char *url = NULL;
+ PK11Attribute *subject,*crl;
+ SECStatus rv;
+
+ PORT_Assert(slot);
+ if (slot->certDB == NULL) {
+ return CKR_TOKEN_WRITE_PROTECTED;
+ }
+
+ /* lookup SUBJECT */
+ subject = pk11_FindAttribute(object,CKA_SUBJECT);
+ PORT_Assert(subject);
+ derSubj.data = (unsigned char *)subject->attrib.pValue;
+ derSubj.len = subject->attrib.ulValueLen ;
+
+ /* lookup VALUE */
+ crl = pk11_FindAttribute(object,CKA_VALUE);
+ PORT_Assert(crl);
+ derCrl.data = (unsigned char *)crl->attrib.pValue;
+ derCrl.len = crl->attrib.ulValueLen ;
+
+
+ url = pk11_getString(object,CKA_NETSCAPE_URL);
+ isKRL = pk11_isTrue(object,CKA_NETSCAPE_KRL);
+
+ /* Store CRL by SUBJECT */
+ rv = nsslowcert_AddCrl(slot->certDB, &derCrl, &derSubj, url, isKRL);
+
+ if (url) {
+ PORT_Free(url);
+ }
+ pk11_FreeAttribute(crl);
+ if (rv != SECSuccess) {
+ pk11_FreeAttribute(subject);
+ return CKR_DEVICE_ERROR;
+ }
+
+ object->handle = pk11_mkHandle(slot,&derSubj,
+ isKRL ? PK11_TOKEN_KRL_HANDLE : PK11_TOKEN_TYPE_CRL);
+ pk11_FreeAttribute(subject);
+ }
return CKR_OK;
}
-SECKEYLowPublicKey * pk11_GetPubKey(PK11Object *object,CK_KEY_TYPE key);
+NSSLOWKEYPublicKey * pk11_GetPubKey(PK11Object *object,CK_KEY_TYPE key);
/*
* check the consistancy and initialize a Public Key Object
*/
static CK_RV
-pk11_handlePublicKeyObject(PK11Object *object,CK_KEY_TYPE key_type)
+pk11_handlePublicKeyObject(PK11Session *session, PK11Object *object,
+ CK_KEY_TYPE key_type)
{
- CK_BBOOL cktrue = CK_TRUE;
CK_BBOOL encrypt = CK_TRUE;
CK_BBOOL recover = CK_TRUE;
CK_BBOOL wrap = CK_TRUE;
+ CK_BBOOL derive = CK_FALSE;
+ CK_BBOOL verify = CK_TRUE;
+ CK_ATTRIBUTE_TYPE pubKeyAttr = CKA_VALUE;
CK_RV crv;
switch (key_type) {
@@ -706,6 +959,7 @@ pk11_handlePublicKeyObject(PK11Object *object,CK_KEY_TYPE key_type)
if ( !pk11_hasAttribute(object, CKA_PUBLIC_EXPONENT)) {
return CKR_TEMPLATE_INCOMPLETE;
}
+ pubKeyAttr = CKA_MODULUS;
break;
case CKK_DSA:
if ( !pk11_hasAttribute(object, CKA_SUBPRIME)) {
@@ -721,6 +975,10 @@ pk11_handlePublicKeyObject(PK11Object *object,CK_KEY_TYPE key_type)
if ( !pk11_hasAttribute(object, CKA_VALUE)) {
return CKR_TEMPLATE_INCOMPLETE;
}
+ if (key_type == CKK_DH) {
+ verify = CK_FALSE;
+ derive = CK_TRUE;
+ }
encrypt = CK_FALSE;
recover = CK_FALSE;
wrap = CK_FALSE;
@@ -734,176 +992,55 @@ pk11_handlePublicKeyObject(PK11Object *object,CK_KEY_TYPE key_type)
if (crv != CKR_OK) return crv;
crv = pk11_defaultAttribute(object,CKA_ENCRYPT,&encrypt,sizeof(CK_BBOOL));
if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_VERIFY,&cktrue,sizeof(CK_BBOOL));
+ crv = pk11_defaultAttribute(object,CKA_VERIFY,&verify,sizeof(CK_BBOOL));
if (crv != CKR_OK) return crv;
crv = pk11_defaultAttribute(object,CKA_VERIFY_RECOVER,
&recover,sizeof(CK_BBOOL));
if (crv != CKR_OK) return crv;
crv = pk11_defaultAttribute(object,CKA_WRAP,&wrap,sizeof(CK_BBOOL));
if (crv != CKR_OK) return crv;
+ crv = pk11_defaultAttribute(object,CKA_DERIVE,&derive,sizeof(CK_BBOOL));
+ if (crv != CKR_OK) return crv;
object->objectInfo = pk11_GetPubKey(object,key_type);
- object->infoFree = (PK11Free) SECKEY_LowDestroyPublicKey;
+ object->infoFree = (PK11Free) nsslowkey_DestroyPublicKey;
if (pk11_isTrue(object,CKA_TOKEN)) {
- object->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PUB);
- }
-
- return CKR_OK;
-}
-/* pk11_GetPubItem returns data associated with the public key.
- * one only needs to free the public key. This comment is here
- * because this sematic would be non-obvious otherwise. All callers
- * should include this comment.
- */
-static SECItem *
-pk11_GetPubItem(SECKEYPublicKey *pubKey) {
- SECItem *pubItem = NULL;
- /* get value to compare from the cert's public key */
- switch ( pubKey->keyType ) {
- case rsaKey:
- pubItem = &pubKey->u.rsa.modulus;
- break;
- case dsaKey:
- pubItem = &pubKey->u.dsa.publicValue;
- break;
- default:
- break;
- }
- return pubItem;
-}
-
-/* convert a high key type to a low key type. This will go away when
- * the last SECKEYPublicKey structs go away.
- */
-LowKeyType
-seckeyLow_KeyType(KeyType keyType)
-{
- switch (keyType) {
- case rsaKey:
- return lowRSAKey;
- case dsaKey:
- return lowDSAKey;
- case dhKey:
- return lowDHKey;
- default:
- break;
- }
- return lowNullKey;
-}
-
-typedef struct {
- CERTCertificate *cert;
- SECItem *pubKey;
-} find_cert_callback_arg;
-
-static SECStatus
-find_cert_by_pub_key(CERTCertificate *cert, SECItem *k, void *arg)
-{
- find_cert_callback_arg *cbarg;
- SECKEYPublicKey *pubKey = NULL;
- SECItem *pubItem;
-
- if((cert == NULL) || (arg == NULL)) {
- return SECFailure;
- }
-
- /* if this cert doesn't look like a user cert, we aren't interested */
- if (!((cert->isperm) && (cert->trust) &&
- (( cert->trust->sslFlags & CERTDB_USER ) ||
- ( cert->trust->emailFlags & CERTDB_USER ) ||
- ( cert->trust->objectSigningFlags & CERTDB_USER )) &&
- ( cert->nickname != NULL ) ) ) {
- goto done;
- }
-
- /* get cert's public key */
- pubKey = CERT_ExtractPublicKey(cert);
- if ( pubKey == NULL ) {
- goto done;
- }
- /* pk11_GetPubItem returns data associated with the public key.
- * one only needs to free the public key. This comment is here
- * because this sematic would be non-obvious otherwise. All callers
- * should include this comment.
- */
- pubItem = pk11_GetPubItem(pubKey);
- if (pubItem == NULL) goto done;
-
- cbarg = (find_cert_callback_arg *)arg;
-
- if(SECITEM_CompareItem(pubItem, cbarg->pubKey) == SECEqual) {
- cbarg->cert = CERT_DupCertificate(cert);
- return SECFailure;
- }
-
-done:
- if ( pubKey ) {
- SECKEY_DestroyPublicKey(pubKey);
- }
+ PK11Slot *slot = session->slot;
+ NSSLOWKEYPrivateKey *priv;
+ SECItem pubKey;
- return (SECSuccess);
-}
+ crv = pk11_Attribute2SSecItem(NULL,&pubKey,object,pubKeyAttr);
+ if (crv != CKR_OK) return crv;
-static PK11Object *pk11_importCertificate(PK11Slot *slot,CERTCertificate *cert,
- unsigned char *data, unsigned int size, PRBool needCert);
-/*
- * find a cert associated with the key and load it.
- */
-static SECStatus
-reload_existing_certificate(PK11Object *privKeyObject,SECItem *pubKey)
-{
- find_cert_callback_arg cbarg;
- SECItem nickName;
- CERTCertificate *cert = NULL;
- CK_RV crv;
- SECStatus rv;
-
- cbarg.pubKey = pubKey;
- cbarg.cert = NULL;
- SEC_TraversePermCerts(CERT_GetDefaultCertDB(),
- find_cert_by_pub_key, (void *)&cbarg);
- if (cbarg.cert != NULL) {
- CERTCertificate *cert = NULL;
- /* can anyone tell me why this is call is necessary? rjr */
- cert = CERT_FindCertByDERCert(CERT_GetDefaultCertDB(),
- &cbarg.cert->derCert);
-
- /* does the certificate in the database have a
- * nickname? if not, it probably was inserted
- * through SMIME and a nickname needs to be
- * set.
- */
- if (cert && !cert->nickname) {
- crv=pk11_Attribute2SecItem(NULL,&nickName,privKeyObject,CKA_LABEL);
- if (crv != CKR_OK) {
- goto loser;
- }
- rv = CERT_AddPermNickname(cert, (char *)nickName.data);
- SECITEM_ZfreeItem(&nickName, PR_FALSE);
- if (rv != SECSuccess) {
- goto loser;
- }
+ PORT_Assert(pubKey.data);
+ if (slot->keyDB == NULL) {
+ PORT_Free(pubKey.data);
+ return CKR_TOKEN_WRITE_PROTECTED;
+ }
+ /* make sure the associated private key already exists */
+ /* only works if we are logged in */
+ priv = nsslowkey_FindKeyByPublicKey(slot->keyDB, &pubKey,
+ slot->password);
+ if (priv == NULL) {
+ PORT_Free(pubKey.data);
+ return CKR_ATTRIBUTE_VALUE_INVALID;
}
+ nsslowkey_DestroyPrivateKey(priv);
- /* associate the certificate with the key */
- pk11_importCertificate(privKeyObject->slot, cert, pubKey->data,
- pubKey->len, PR_FALSE);
+ object->handle = pk11_mkHandle(slot, &pubKey, PK11_TOKEN_TYPE_PUB);
+ PORT_Free(pubKey.data);
}
- return SECSuccess;
-loser:
- if (cert) CERT_DestroyCertificate(cert);
- if (cbarg.cert) CERT_DestroyCertificate(cbarg.cert);
- return SECFailure;
+ return CKR_OK;
}
-static SECKEYLowPrivateKey * pk11_mkPrivKey(PK11Object *object,CK_KEY_TYPE key);
+static NSSLOWKEYPrivateKey * pk11_mkPrivKey(PK11Object *object,CK_KEY_TYPE key);
/*
* check the consistancy and initialize a Private Key Object
*/
static CK_RV
-pk11_handlePrivateKeyObject(PK11Object *object,CK_KEY_TYPE key_type)
+pk11_handlePrivateKeyObject(PK11Session *session,PK11Object *object,CK_KEY_TYPE key_type)
{
CK_BBOOL cktrue = CK_TRUE;
CK_BBOOL encrypt = CK_TRUE;
@@ -996,60 +1133,59 @@ pk11_handlePrivateKeyObject(PK11Object *object,CK_KEY_TYPE key_type)
if (crv != CKR_OK) return crv;
if (pk11_isTrue(object,CKA_TOKEN)) {
- SECKEYLowPrivateKey *privKey;
+ PK11Slot *slot = session->slot;
+ NSSLOWKEYPrivateKey *privKey;
char *label;
SECStatus rv = SECSuccess;
SECItem pubKey;
+ if (slot->keyDB == NULL) {
+ return CKR_TOKEN_WRITE_PROTECTED;
+ }
+
privKey=pk11_mkPrivKey(object,key_type);
if (privKey == NULL) return CKR_HOST_MEMORY;
- label = object->label = pk11_getString(object,CKA_LABEL);
+ label = pk11_getString(object,CKA_LABEL);
crv = pk11_Attribute2SecItem(NULL,&pubKey,object,CKA_NETSCAPE_DB);
- if (crv == CKR_OK) {
- rv = SECKEY_StoreKeyByPublicKey(SECKEY_GetDefaultKeyDB(),
- privKey, &pubKey, label,
- (SECKEYLowGetPasswordKey) pk11_givePass, object->slot);
-
- /* check for the existance of an existing certificate and activate
- * it if necessary */
- if (rv == SECSuccess) {
- reload_existing_certificate(object,&pubKey);
- }
-
- if (pubKey.data) PORT_Free(pubKey.data);
- } else {
- rv = SECFailure;
+ if (crv != CKR_OK) {
+ if (label) PORT_Free(label);
+ nsslowkey_DestroyPrivateKey(privKey);
+ return CKR_TEMPLATE_INCOMPLETE;
}
+ rv = nsslowkey_StoreKeyByPublicKey(object->slot->keyDB,
+ privKey, &pubKey, label, object->slot->password);
- SECKEY_LowDestroyPrivateKey(privKey);
+ if (label) PORT_Free(label);
+ object->handle = pk11_mkHandle(slot,&pubKey,PK11_TOKEN_TYPE_PRIV);
+ if (pubKey.data) PORT_Free(pubKey.data);
+ nsslowkey_DestroyPrivateKey(privKey);
if (rv != SECSuccess) return CKR_DEVICE_ERROR;
- object->inDB = PR_TRUE;
- object->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
} else {
object->objectInfo = pk11_mkPrivKey(object,key_type);
if (object->objectInfo == NULL) return CKR_HOST_MEMORY;
- object->infoFree = (PK11Free) SECKEY_LowDestroyPrivateKey;
- }
- /* now NULL out the sensitive attributes */
- if (pk11_isTrue(object,CKA_SENSITIVE)) {
- pk11_nullAttribute(object,CKA_PRIVATE_EXPONENT);
- pk11_nullAttribute(object,CKA_PRIME_1);
- pk11_nullAttribute(object,CKA_PRIME_2);
- pk11_nullAttribute(object,CKA_EXPONENT_1);
- pk11_nullAttribute(object,CKA_EXPONENT_2);
- pk11_nullAttribute(object,CKA_COEFFICIENT);
+ object->infoFree = (PK11Free) nsslowkey_DestroyPrivateKey;
+ /* now NULL out the sensitive attributes */
+ if (pk11_isTrue(object,CKA_SENSITIVE)) {
+ pk11_nullAttribute(object,CKA_PRIVATE_EXPONENT);
+ pk11_nullAttribute(object,CKA_PRIME_1);
+ pk11_nullAttribute(object,CKA_PRIME_2);
+ pk11_nullAttribute(object,CKA_EXPONENT_1);
+ pk11_nullAttribute(object,CKA_EXPONENT_2);
+ pk11_nullAttribute(object,CKA_COEFFICIENT);
+ }
}
return CKR_OK;
}
/* forward delcare the DES formating function for handleSecretKey */
void pk11_FormatDESKey(unsigned char *key, int length);
-static SECKEYLowPrivateKey *pk11_mkSecretKeyRep(PK11Object *object);
+static NSSLOWKEYPrivateKey *pk11_mkSecretKeyRep(PK11Object *object);
/* Validate secret key data, and set defaults */
static CK_RV
-validateSecretKey(PK11Object *object, CK_KEY_TYPE key_type, PRBool isFIPS)
+validateSecretKey(PK11Session *session, PK11Object *object,
+ CK_KEY_TYPE key_type, PRBool isFIPS)
{
CK_RV crv;
CK_BBOOL cktrue = CK_TRUE;
@@ -1095,9 +1231,14 @@ validateSecretKey(PK11Object *object, CK_KEY_TYPE key_type, PRBool isFIPS)
#if NSS_SOFTOKEN_DOES_RC5
case CKK_RC5:
#endif
+#ifdef NSS_SOFTOKEN_DOES_CAST
case CKK_CAST:
case CKK_CAST3:
case CKK_CAST5:
+#endif
+#if NSS_SOFTOKEN_DOES_IDEA
+ case CKK_IDEA:
+#endif
attribute = pk11_FindAttribute(object,CKA_VALUE);
/* shouldn't happen */
if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
@@ -1127,45 +1268,51 @@ validateSecretKey(PK11Object *object, CK_KEY_TYPE key_type, PRBool isFIPS)
* check the consistancy and initialize a Secret Key Object
*/
static CK_RV
-pk11_handleSecretKeyObject(PK11Object *object,CK_KEY_TYPE key_type,
- PRBool isFIPS)
+pk11_handleSecretKeyObject(PK11Session *session,PK11Object *object,
+ CK_KEY_TYPE key_type, PRBool isFIPS)
{
CK_RV crv;
- SECKEYLowPrivateKey *privKey = NULL;
+ NSSLOWKEYPrivateKey *privKey = NULL;
SECItem pubKey;
+ char *label = NULL;
pubKey.data = 0;
/* First validate and set defaults */
- crv = validateSecretKey(object, key_type, isFIPS);
+ crv = validateSecretKey(session, object, key_type, isFIPS);
if (crv != CKR_OK) goto loser;
/* If the object is a TOKEN object, store in the database */
if (pk11_isTrue(object,CKA_TOKEN)) {
- char *label;
+ PK11Slot *slot = session->slot;
SECStatus rv = SECSuccess;
+ if (slot->keyDB == NULL) {
+ return CKR_TOKEN_WRITE_PROTECTED;
+ }
privKey=pk11_mkSecretKeyRep(object);
if (privKey == NULL) return CKR_HOST_MEMORY;
- label = object->label = pk11_getString(object,CKA_LABEL);
+ label = pk11_getString(object,CKA_LABEL);
- crv = pk11_Attribute2SecItem(NULL,&pubKey,object,CKA_ID); /* Should this be ID? */
+ crv = pk11_Attribute2SecItem(NULL, &pubKey, object, CKA_ID);
+ /* Should this be ID? */
if (crv != CKR_OK) goto loser;
- rv = SECKEY_StoreKeyByPublicKey(SECKEY_GetDefaultKeyDB(),
- privKey, &pubKey, label,
- (SECKEYLowGetPasswordKey) pk11_givePass, object->slot);
+ PORT_Assert(slot->keyDB);
+ rv = nsslowkey_StoreKeyByPublicKey(slot->keyDB,
+ privKey, &pubKey, label, slot->password);
if (rv != SECSuccess) {
crv = CKR_DEVICE_ERROR;
+ goto loser;
}
- object->inDB = PR_TRUE;
- object->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
+ object->handle = pk11_mkHandle(slot,&pubKey,PK11_TOKEN_TYPE_KEY);
}
loser:
- if (privKey) SECKEY_LowDestroyPrivateKey(privKey);
+ if (label) PORT_Free(label);
+ if (privKey) nsslowkey_DestroyPrivateKey(privKey);
if (pubKey.data) PORT_Free(pubKey.data);
return crv;
@@ -1207,12 +1354,12 @@ pk11_handleKeyObject(PK11Session *session, PK11Object *object)
switch (object->objclass) {
case CKO_PUBLIC_KEY:
- return pk11_handlePublicKeyObject(object,key_type);
+ return pk11_handlePublicKeyObject(session,object,key_type);
case CKO_PRIVATE_KEY:
- return pk11_handlePrivateKeyObject(object,key_type);
+ return pk11_handlePrivateKeyObject(session,object,key_type);
case CKO_SECRET_KEY:
/* make sure the required fields exist */
- return pk11_handleSecretKeyObject(object,key_type,
+ return pk11_handleSecretKeyObject(session,object,key_type,
(PRBool)(session->slot->slotID == FIPS_SLOT_ID));
default:
break;
@@ -1223,8 +1370,8 @@ pk11_handleKeyObject(PK11Session *session, PK11Object *object)
/*
* Handle Object does all the object consistancy checks, automatic attribute
* generation, attribute defaulting, etc. If handleObject succeeds, the object
- * will be assigned an object handle, and the object pointer will be adopted
- * by the session. (that is don't free object).
+ * will be assigned an object handle, and the object installed in the session
+ * or stored in the DB.
*/
CK_RV
pk11_handleObject(PK11Object *object, PK11Session *session)
@@ -1257,17 +1404,6 @@ pk11_handleObject(PK11Object *object, PK11Session *session)
(pk11_isTrue(object,CKA_TOKEN))) {
return CKR_SESSION_READ_ONLY;
}
-
- if (pk11_isTrue(object, CKA_TOKEN)) {
- if (slot->DB_loaded == PR_FALSE) {
- /* we are creating a token object, make sure we load the database
- * first so we don't get duplicates....
- * ... NOTE: This assumes we are logged in as well!
- */
- pk11_importKeyDB(slot);
- slot->DB_loaded = PR_TRUE;
- }
- }
/* PKCS #11 object ID's are unique for all objects on a
* token */
@@ -1288,9 +1424,19 @@ pk11_handleObject(PK11Object *object, PK11Session *session)
switch (object->objclass) {
case CKO_DATA:
crv = pk11_handleDataObject(session,object);
+ break;
case CKO_CERTIFICATE:
crv = pk11_handleCertObject(session,object);
break;
+ case CKO_NETSCAPE_TRUST:
+ crv = pk11_handleTrustObject(session,object);
+ break;
+ case CKO_NETSCAPE_CRL:
+ crv = pk11_handleCrlObject(session,object);
+ break;
+ case CKO_NETSCAPE_SMIME:
+ crv = pk11_handleSMimeObject(session,object);
+ break;
case CKO_PRIVATE_KEY:
case CKO_PUBLIC_KEY:
case CKO_SECRET_KEY:
@@ -1308,632 +1454,23 @@ pk11_handleObject(PK11Object *object, PK11Session *session)
}
/* now link the object into the slot and session structures */
- object->slot = slot;
- pk11_AddObject(session,object);
-
- return CKR_OK;
-}
-
-/* import a private key as an object. We don't call handle object.
- * because we the private key came from the key DB and we don't want to
- * write back out again */
-static PK11Object *
-pk11_importPrivateKey(PK11Slot *slot,SECKEYLowPrivateKey *lowPriv,
- SECItem *dbKey)
-{
- PK11Object *privateKey;
- CK_KEY_TYPE key_type;
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_BBOOL sign = CK_TRUE;
- CK_BBOOL recover = CK_TRUE;
- CK_BBOOL decrypt = CK_TRUE;
- CK_BBOOL derive = CK_FALSE;
- CK_RV crv = CKR_OK;
- CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY;
- unsigned char cka_id[SHA1_LENGTH];
-
- /*
- * now lets create an object to hang the attributes off of
- */
- privateKey = pk11_NewObject(slot); /* fill in the handle later */
- if (privateKey == NULL) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
-
- /* Netscape Private Attribute for dealing with database storeage */
- if (pk11_AddAttributeType(privateKey, CKA_NETSCAPE_DB,
- pk11_item_expand(dbKey)) ) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
-
- /* now force the CKA_ID */
- SHA1_HashBuf(cka_id, (unsigned char *)dbKey->data, (uint32)dbKey->len);
- if (pk11_AddAttributeType(privateKey, CKA_ID, cka_id, sizeof(cka_id))) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
-
-
- /* Fill in the common Default values */
- if (pk11_AddAttributeType(privateKey,CKA_CLASS, &privClass,
- sizeof(CK_OBJECT_CLASS)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_TOKEN, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_PRIVATE, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_MODIFIABLE, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_LABEL, NULL, 0) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_START_DATE, NULL, 0) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_END_DATE, NULL, 0) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_DERIVE, &ckfalse,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- /* local: well we really don't know for sure... it could have been an
- * imported key, but it's not a useful attribute anyway. */
- if (pk11_AddAttributeType(privateKey,CKA_LOCAL, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_SUBJECT, NULL, 0) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_SENSITIVE, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_EXTRACTABLE, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- /* is this really true? Maybe we should just say false here? */
- if (pk11_AddAttributeType(privateKey,CKA_ALWAYS_SENSITIVE, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_NEVER_EXTRACTABLE, &ckfalse,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
-
- /* Now Set up the parameters to generate the key (based on mechanism) */
- /* NOTE: for safety sake we *DO NOT* remember critical attributes. PKCS #11
- * will look them up again from the database when it needs them.
- */
- switch (lowPriv->keyType) {
- case lowRSAKey:
- /* format the keys */
- key_type = CKK_RSA;
- sign = CK_TRUE;
- recover = CK_TRUE;
- decrypt = CK_TRUE;
- derive = CK_FALSE;
- /* now fill in the RSA dependent parameters in the public key */
- crv = pk11_AddAttributeType(privateKey,CKA_MODULUS,
- pk11_item_expand(&lowPriv->u.rsa.modulus));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_PRIVATE_EXPONENT,NULL,0);
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_PUBLIC_EXPONENT,
- pk11_item_expand(&lowPriv->u.rsa.publicExponent));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_PRIME_1,NULL,0);
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_PRIME_2,NULL,0);
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_EXPONENT_1,NULL,0);
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_EXPONENT_2,NULL,0);
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_COEFFICIENT,NULL,0);
- break;
- case lowDSAKey:
- key_type = CKK_DSA;
- sign = CK_TRUE;
- recover = CK_FALSE;
- decrypt = CK_FALSE;
- derive = CK_FALSE;
- crv = pk11_AddAttributeType(privateKey,CKA_PRIME,
- pk11_item_expand(&lowPriv->u.dsa.params.prime));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_SUBPRIME,
- pk11_item_expand(&lowPriv->u.dsa.params.subPrime));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_BASE,
- pk11_item_expand(&lowPriv->u.dsa.params.base));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_VALUE,NULL,0);
- if (crv != CKR_OK) break;
- break;
- case lowDHKey:
- key_type = CKK_DH;
- sign = CK_FALSE;
- decrypt = CK_FALSE;
- recover = CK_FALSE;
- derive = CK_TRUE;
- crv = CKR_MECHANISM_INVALID;
- break;
- default:
- crv = CKR_MECHANISM_INVALID;
- }
-
- if (crv != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
-
-
- if (pk11_AddAttributeType(privateKey,CKA_SIGN, &sign,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_SIGN_RECOVER, &recover,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_DECRYPT, &decrypt,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_UNWRAP, &decrypt,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_DERIVE, &derive,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_KEY_TYPE,&key_type,
- sizeof(CK_KEY_TYPE)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- PK11_USE_THREADS(PZ_Lock(slot->objectLock);)
- privateKey->handle = slot->tokenIDCount++;
- privateKey->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
- PK11_USE_THREADS(PZ_Unlock(slot->objectLock);)
- privateKey->objclass = privClass;
- privateKey->slot = slot;
- privateKey->inDB = PR_TRUE;
-
- return privateKey;
-}
-
-/* import a private key or cert as a public key object.*/
-static PK11Object *
-pk11_importPublicKey(PK11Slot *slot,
- SECKEYLowPrivateKey *lowPriv, CERTCertificate *cert, SECItem *dbKey)
-{
- PK11Object *publicKey = NULL;
- CK_KEY_TYPE key_type;
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_BBOOL verify = CK_TRUE;
- CK_BBOOL recover = CK_TRUE;
- CK_BBOOL encrypt = CK_TRUE;
- CK_BBOOL derive = CK_FALSE;
- CK_RV crv = CKR_OK;
- CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
- unsigned char cka_id[SHA1_LENGTH];
- LowKeyType keyType = nullKey;
- SECKEYPublicKey *pubKey = NULL;
- CK_ATTRIBUTE theTemplate[2];
- PK11ObjectListElement *objectList = NULL;
-
- if (lowPriv == NULL) {
- pubKey = CERT_ExtractPublicKey(cert);
- if (pubKey == NULL) {
- goto failed;
- }
- /* pk11_GetPubItem returns data associated with the public key.
- * one only needs to free the public key. This comment is here
- * because this sematic would be non-obvious otherwise. All callers
- * should include this comment.
- */
- dbKey = pk11_GetPubItem(pubKey);
- if (dbKey == NULL) {
- goto failed;
- }
- }
- SHA1_HashBuf(cka_id, (unsigned char *)dbKey->data, (uint32)dbKey->len);
- theTemplate[0].type = CKA_ID;
- theTemplate[0].pValue = cka_id;
- theTemplate[0].ulValueLen = sizeof(cka_id);
- theTemplate[1].type = CKA_CLASS;
- theTemplate[1].pValue = &pubClass;
- theTemplate[1].ulValueLen = sizeof(CK_OBJECT_CLASS);
- crv = pk11_searchObjectList(&objectList,slot->tokObjects,
- slot->objectLock, theTemplate, 2, slot->isLoggedIn);
- if ((crv == CKR_OK) && (objectList != NULL)) {
- goto failed;
- }
- /*
- * now lets create an object to hang the attributes off of
- */
- publicKey = pk11_NewObject(slot); /* fill in the handle later */
- if (publicKey == NULL) {
- goto failed;
- }
-
- /* now force the CKA_ID */
- if (pk11_AddAttributeType(publicKey, CKA_ID, cka_id, sizeof(cka_id))) {
- goto failed;
- }
-
- /* Fill in the common Default values */
- if (pk11_AddAttributeType(publicKey,CKA_CLASS,&pubClass,
- sizeof(CK_OBJECT_CLASS)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_TOKEN, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_PRIVATE, &ckfalse,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_MODIFIABLE, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_LABEL, NULL, 0) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_START_DATE, NULL, 0) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_END_DATE, NULL, 0) != CKR_OK) {
- goto failed;
- }
- /* local: well we really don't know for sure... it could have been an
- * imported key, but it's not a useful attribute anyway. */
- if (pk11_AddAttributeType(publicKey,CKA_LOCAL, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_SUBJECT, NULL, 0) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_SENSITIVE, &ckfalse,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_EXTRACTABLE, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_ALWAYS_SENSITIVE, &ckfalse,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_NEVER_EXTRACTABLE, &ckfalse,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
-
- /* Now Set up the parameters to generate the key (based on mechanism) */
- if (lowPriv == NULL) {
-
- keyType = seckeyLow_KeyType(pubKey->keyType);
- } else {
- keyType = lowPriv->keyType;
- }
-
-
- switch (keyType) {
- case lowRSAKey:
- /* format the keys */
- key_type = CKK_RSA;
- verify = CK_TRUE;
- recover = CK_TRUE;
- encrypt = CK_TRUE;
- derive = CK_FALSE;
- /* now fill in the RSA dependent parameters in the public key */
- if (lowPriv) {
- crv = pk11_AddAttributeType(publicKey,CKA_MODULUS,
- pk11_item_expand(&lowPriv->u.rsa.modulus));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_PUBLIC_EXPONENT,
- pk11_item_expand(&lowPriv->u.rsa.publicExponent));
- if (crv != CKR_OK) break;
- } else {
- crv = pk11_AddAttributeType(publicKey,CKA_MODULUS,
- pk11_item_expand(&pubKey->u.rsa.modulus));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_PUBLIC_EXPONENT,
- pk11_item_expand(&pubKey->u.rsa.publicExponent));
- if (crv != CKR_OK) break;
- }
- break;
- case lowDSAKey:
- key_type = CKK_DSA;
- verify = CK_TRUE;
- recover = CK_FALSE;
- encrypt = CK_FALSE;
- derive = CK_FALSE;
- if (lowPriv) {
- crv = pk11_AddAttributeType(publicKey,CKA_PRIME,
- pk11_item_expand(&lowPriv->u.dsa.params.prime));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_SUBPRIME,
- pk11_item_expand(&lowPriv->u.dsa.params.subPrime));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_BASE,
- pk11_item_expand(&lowPriv->u.dsa.params.base));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_VALUE,
- pk11_item_expand(&lowPriv->u.dsa.publicValue));
- if (crv != CKR_OK) break;
- } else {
- crv = pk11_AddAttributeType(publicKey,CKA_PRIME,
- pk11_item_expand(&pubKey->u.dsa.params.prime));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_SUBPRIME,
- pk11_item_expand(&pubKey->u.dsa.params.subPrime));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_BASE,
- pk11_item_expand(&pubKey->u.dsa.params.base));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_VALUE,
- pk11_item_expand(&pubKey->u.dsa.publicValue));
- if (crv != CKR_OK) break;
- }
- break;
- case lowDHKey:
- key_type = CKK_DH;
- verify = CK_FALSE;
- encrypt = CK_FALSE;
- recover = CK_FALSE;
- derive = CK_TRUE;
- crv = CKR_MECHANISM_INVALID;
- break;
- default:
- crv = CKR_MECHANISM_INVALID;
- }
-
- if (pubKey) {
- SECKEY_DestroyPublicKey(pubKey);
- pubKey = NULL;
- }
-
- if (crv != CKR_OK) {
- goto failed;
- }
-
- if (pk11_AddAttributeType(publicKey,CKA_VERIFY, &verify,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_VERIFY_RECOVER, &recover,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_ENCRYPT, &encrypt,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_WRAP, &encrypt,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_DERIVE, &derive,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_KEY_TYPE,&key_type,
- sizeof(CK_KEY_TYPE)) != CKR_OK) {
- goto failed;
- }
- PK11_USE_THREADS(PZ_Lock(slot->objectLock);)
- publicKey->handle = slot->tokenIDCount++;
- publicKey->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PUB);
- PK11_USE_THREADS(PZ_Unlock(slot->objectLock);)
- publicKey->objclass = pubClass;
- publicKey->slot = slot;
- publicKey->inDB = PR_FALSE; /* not really in the Database */
-
- return publicKey;
-failed:
- if (pubKey) SECKEY_DestroyPublicKey(pubKey);
- if (publicKey) pk11_FreeObject(publicKey);
- return NULL;
-}
-
-/*
- * Question.. Why doesn't import Cert call pk11_handleObject, or
- * pk11 handleCertObject? Answer: because they will try to write
- * this cert back out to the Database, even though it is already in
- * the database.
- */
-static PK11Object *
-pk11_importCertificate(PK11Slot *slot, CERTCertificate *cert,
- unsigned char *data, unsigned int size, PRBool needObject)
-{
- PK11Object *certObject = NULL;
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_CERTIFICATE_TYPE certType = CKC_X_509;
- CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
- unsigned char cka_id[SHA1_LENGTH];
- CK_ATTRIBUTE theTemplate;
- PK11ObjectListElement *objectList = NULL;
- CK_RV crv;
-
-
- /*
- * first make sure that no object for this cert already exists.
- */
- theTemplate.type = CKA_VALUE;
- theTemplate.pValue = cert->derCert.data;
- theTemplate.ulValueLen = cert->derCert.len;
- crv = pk11_searchObjectList(&objectList,slot->tokObjects,
- slot->objectLock, &theTemplate, 1, slot->isLoggedIn);
- if ((crv == CKR_OK) && (objectList != NULL)) {
- if (needObject) {
- pk11_ReferenceObject(objectList->object);
- certObject = objectList->object;
- }
- pk11_FreeObjectList(objectList);
- return certObject;
- }
-
- /*
- * now lets create an object to hang the attributes off of
- */
- certObject = pk11_NewObject(slot); /* fill in the handle later */
- if (certObject == NULL) {
- return NULL;
- }
-
- /* First set the CKA_ID */
- if (data == NULL) {
- SECKEYPublicKey *pubKey = CERT_ExtractPublicKey(cert);
- SECItem *pubItem;
- if (pubKey == NULL) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- /* pk11_GetPubItem returns data associated with the public key.
- * one only needs to free the public key. This comment is here
- * because this sematic would be non-obvious otherwise.
- */
- pubItem =pk11_GetPubItem(pubKey);
- if (pubItem == NULL) {
- SECKEY_DestroyPublicKey(pubKey);
- pk11_FreeObject(certObject);
- return NULL;
- }
- SHA1_HashBuf(cka_id, (unsigned char *)pubItem->data,
- (uint32)pubItem->len);
- SECKEY_DestroyPublicKey(pubKey);
- } else {
- SHA1_HashBuf(cka_id, (unsigned char *)data, (uint32)size);
- }
- if (pk11_AddAttributeType(certObject, CKA_ID, cka_id, sizeof(cka_id))) {
- pk11_FreeObject(certObject);
- return NULL;
- }
-
- /* initalize the certificate attributes */
- if (pk11_AddAttributeType(certObject, CKA_CLASS, &certClass,
- sizeof(CK_OBJECT_CLASS)) != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_TOKEN, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_PRIVATE, &ckfalse,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_LABEL, cert->nickname,
- PORT_Strlen(cert->nickname))
- != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_MODIFIABLE, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_CERTIFICATE_TYPE, &certType,
- sizeof(CK_CERTIFICATE_TYPE))!=CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_VALUE,
- pk11_item_expand(&cert->derCert)) != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_ISSUER,
- pk11_item_expand(&cert->derIssuer)) != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_SUBJECT,
- pk11_item_expand(&cert->derSubject)) != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_SERIAL_NUMBER,
- pk11_item_expand(&cert->serialNumber)) != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
-
-
- certObject->objectInfo = CERT_DupCertificate(cert);
- certObject->infoFree = (PK11Free) CERT_DestroyCertificate;
-
- /* now just verify the required date fields */
- PK11_USE_THREADS(PZ_Lock(slot->objectLock);)
- certObject->handle = slot->tokenIDCount++;
- certObject->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_CERT);
- PK11_USE_THREADS(PZ_Unlock(slot->objectLock);)
- certObject->objclass = certClass;
- certObject->slot = slot;
- certObject->inDB = PR_TRUE;
- pk11_AddSlotObject(slot, certObject);
- if (needObject) {
- pk11_ReferenceObject(certObject);
+ if (pk11_isToken(object->handle)) {
+ pk11_convertSessionToToken(object);
} else {
- certObject = NULL;
+ object->slot = slot;
+ pk11_AddObject(session,object);
}
- return certObject;
+ return CKR_OK;
}
/*
* ******************** Public Key Utilities ***************************
*/
/* Generate a low public key structure from an object */
-SECKEYLowPublicKey *pk11_GetPubKey(PK11Object *object,CK_KEY_TYPE key_type)
+NSSLOWKEYPublicKey *pk11_GetPubKey(PK11Object *object,CK_KEY_TYPE key_type)
{
- SECKEYLowPublicKey *pubKey;
+ NSSLOWKEYPublicKey *pubKey;
PLArenaPool *arena;
CK_RV crv;
@@ -1941,17 +1478,21 @@ SECKEYLowPublicKey *pk11_GetPubKey(PK11Object *object,CK_KEY_TYPE key_type)
return NULL;
}
+ if (pk11_isToken(object->handle)) {
+/* ferret out the token object handle */
+ }
+
/* If we already have a key, use it */
if (object->objectInfo) {
- return (SECKEYLowPublicKey *)object->objectInfo;
+ return (NSSLOWKEYPublicKey *)object->objectInfo;
}
/* allocate the structure */
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) return NULL;
- pubKey = (SECKEYLowPublicKey *)
- PORT_ArenaAlloc(arena,sizeof(SECKEYLowPublicKey));
+ pubKey = (NSSLOWKEYPublicKey *)
+ PORT_ArenaAlloc(arena,sizeof(NSSLOWKEYPublicKey));
if (pubKey == NULL) {
PORT_FreeArena(arena,PR_FALSE);
return NULL;
@@ -1961,7 +1502,7 @@ SECKEYLowPublicKey *pk11_GetPubKey(PK11Object *object,CK_KEY_TYPE key_type)
pubKey->arena = arena;
switch (key_type) {
case CKK_RSA:
- pubKey->keyType = lowRSAKey;
+ pubKey->keyType = NSSLOWKEYRSAKey;
crv = pk11_Attribute2SSecItem(arena,&pubKey->u.rsa.modulus,
object,CKA_MODULUS);
if (crv != CKR_OK) break;
@@ -1969,7 +1510,7 @@ SECKEYLowPublicKey *pk11_GetPubKey(PK11Object *object,CK_KEY_TYPE key_type)
object,CKA_PUBLIC_EXPONENT);
break;
case CKK_DSA:
- pubKey->keyType = lowDSAKey;
+ pubKey->keyType = NSSLOWKEYDSAKey;
crv = pk11_Attribute2SSecItem(arena,&pubKey->u.dsa.params.prime,
object,CKA_PRIME);
if (crv != CKR_OK) break;
@@ -1983,7 +1524,7 @@ SECKEYLowPublicKey *pk11_GetPubKey(PK11Object *object,CK_KEY_TYPE key_type)
object,CKA_VALUE);
break;
case CKK_DH:
- pubKey->keyType = lowDHKey;
+ pubKey->keyType = NSSLOWKEYDHKey;
crv = pk11_Attribute2SSecItem(arena,&pubKey->u.dh.prime,
object,CKA_PRIME);
if (crv != CKR_OK) break;
@@ -2003,24 +1544,25 @@ SECKEYLowPublicKey *pk11_GetPubKey(PK11Object *object,CK_KEY_TYPE key_type)
}
object->objectInfo = pubKey;
- object->infoFree = (PK11Free) SECKEY_LowDestroyPublicKey;
+ object->infoFree = (PK11Free) nsslowkey_DestroyPublicKey;
return pubKey;
}
/* make a private key from a verified object */
-static SECKEYLowPrivateKey *
+static NSSLOWKEYPrivateKey *
pk11_mkPrivKey(PK11Object *object,CK_KEY_TYPE key_type)
{
- SECKEYLowPrivateKey *privKey;
+ NSSLOWKEYPrivateKey *privKey;
PLArenaPool *arena;
CK_RV crv = CKR_OK;
SECStatus rv;
+ PORT_Assert(!pk11_isToken(object->handle));
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) return NULL;
- privKey = (SECKEYLowPrivateKey *)
- PORT_ArenaAlloc(arena,sizeof(SECKEYLowPrivateKey));
+ privKey = (NSSLOWKEYPrivateKey *)
+ PORT_ArenaAlloc(arena,sizeof(NSSLOWKEYPrivateKey));
if (privKey == NULL) {
PORT_FreeArena(arena,PR_FALSE);
return NULL;
@@ -2030,7 +1572,7 @@ pk11_mkPrivKey(PK11Object *object,CK_KEY_TYPE key_type)
privKey->arena = arena;
switch (key_type) {
case CKK_RSA:
- privKey->keyType = lowRSAKey;
+ privKey->keyType = NSSLOWKEYRSAKey;
crv=pk11_Attribute2SSecItem(arena,&privKey->u.rsa.modulus,
object,CKA_MODULUS);
if (crv != CKR_OK) break;
@@ -2056,12 +1598,12 @@ pk11_mkPrivKey(PK11Object *object,CK_KEY_TYPE key_type)
CKA_COEFFICIENT);
if (crv != CKR_OK) break;
rv = DER_SetUInteger(privKey->arena, &privKey->u.rsa.version,
- SEC_PRIVATE_KEY_VERSION);
+ NSSLOWKEY_VERSION);
if (rv != SECSuccess) crv = CKR_HOST_MEMORY;
break;
case CKK_DSA:
- privKey->keyType = lowDSAKey;
+ privKey->keyType = NSSLOWKEYDSAKey;
crv = pk11_Attribute2SSecItem(arena,&privKey->u.dsa.params.prime,
object,CKA_PRIME);
if (crv != CKR_OK) break;
@@ -2080,7 +1622,7 @@ pk11_mkPrivKey(PK11Object *object,CK_KEY_TYPE key_type)
break;
case CKK_DH:
- privKey->keyType = lowDHKey;
+ privKey->keyType = NSSLOWKEYDHKey;
crv = pk11_Attribute2SSecItem(arena,&privKey->u.dh.prime,
object,CKA_PRIME);
if (crv != CKR_OK) break;
@@ -2089,6 +1631,9 @@ pk11_mkPrivKey(PK11Object *object,CK_KEY_TYPE key_type)
if (crv != CKR_OK) break;
crv = pk11_Attribute2SSecItem(arena,&privKey->u.dh.privateValue,
object,CKA_VALUE);
+ if (crv != CKR_OK) break;
+ crv = pk11_Attribute2SSecItem(arena,&privKey->u.dh.publicValue,
+ object,CKA_NETSCAPE_DB);
break;
default:
crv = CKR_KEY_TYPE_INCONSISTENT;
@@ -2103,52 +1648,31 @@ pk11_mkPrivKey(PK11Object *object,CK_KEY_TYPE key_type)
/* Generate a low private key structure from an object */
-SECKEYLowPrivateKey *
+NSSLOWKEYPrivateKey *
pk11_GetPrivKey(PK11Object *object,CK_KEY_TYPE key_type)
{
- SECKEYLowPrivateKey *priv = NULL;
+ NSSLOWKEYPrivateKey *priv = NULL;
if (object->objclass != CKO_PRIVATE_KEY) {
return NULL;
}
if (object->objectInfo) {
- return (SECKEYLowPrivateKey *)object->objectInfo;
+ return (NSSLOWKEYPrivateKey *)object->objectInfo;
}
- if (pk11_isTrue(object,CKA_TOKEN)) {
+ if (pk11_isToken(object->handle)) {
/* grab it from the data base */
- SECItem pubKey;
- CK_RV crv;
+ PK11TokenObject *to = pk11_narrowToTokenObject(object);
- /* KEYID is the public KEY for DSA and DH, and the MODULUS for
- * RSA */
- crv=pk11_Attribute2SecItem(NULL,&pubKey,object,CKA_NETSCAPE_DB);
- if (crv != CKR_OK) return NULL;
-
- priv=SECKEY_FindKeyByPublicKey(SECKEY_GetDefaultKeyDB(),&pubKey,
- (SECKEYLowGetPasswordKey) pk11_givePass,
- object->slot);
- if (!priv && pubKey.data[0] == 0) {
- /* Because of legacy code issues, sometimes the public key has
- * a '0' prepended to it, forcing it to be unsigned. The database
- * may not store that '0', so remove it and try again.
- */
- SECItem tmpPubKey;
- tmpPubKey.data = pubKey.data + 1;
- tmpPubKey.len = pubKey.len - 1;
- priv=SECKEY_FindKeyByPublicKey(SECKEY_GetDefaultKeyDB(),&tmpPubKey,
- (SECKEYLowGetPasswordKey) pk11_givePass,
- object->slot);
- }
- if (pubKey.data) PORT_Free(pubKey.data);
-
- /* don't 'cache' DB private keys */
- return priv;
- }
-
- priv = pk11_mkPrivKey(object, key_type);
+ PORT_Assert(to);
+ PORT_Assert(object->slot->keyDB);
+ priv = nsslowkey_FindKeyByPublicKey(object->slot->keyDB, &to->dbKey,
+ object->slot->password);
+ } else {
+ priv = pk11_mkPrivKey(object, key_type);
+ }
object->objectInfo = priv;
- object->infoFree = (PK11Free) SECKEY_LowDestroyPrivateKey;
+ object->infoFree = (PK11Free) nsslowkey_DestroyPrivateKey;
return priv;
}
@@ -2213,10 +1737,10 @@ pk11_IsWeakKey(unsigned char *key,CK_KEY_TYPE key_type)
/* make a fake private key representing a symmetric key */
-static SECKEYLowPrivateKey *
+static NSSLOWKEYPrivateKey *
pk11_mkSecretKeyRep(PK11Object *object)
{
- SECKEYLowPrivateKey *privKey;
+ NSSLOWKEYPrivateKey *privKey;
PLArenaPool *arena = 0;
CK_RV crv;
SECStatus rv;
@@ -2225,8 +1749,8 @@ pk11_mkSecretKeyRep(PK11Object *object)
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) { crv = CKR_HOST_MEMORY; goto loser; }
- privKey = (SECKEYLowPrivateKey *)
- PORT_ArenaAlloc(arena,sizeof(SECKEYLowPrivateKey));
+ privKey = (NSSLOWKEYPrivateKey *)
+ PORT_ArenaAlloc(arena,sizeof(NSSLOWKEYPrivateKey));
if (privKey == NULL) { crv = CKR_HOST_MEMORY; goto loser; }
privKey->arena = arena;
@@ -2240,7 +1764,7 @@ pk11_mkSecretKeyRep(PK11Object *object)
* is used for the key.
* all others - set to integer 0
*/
- privKey->keyType = lowRSAKey;
+ privKey->keyType = NSSLOWKEYRSAKey;
/* The modulus is set to the key id of the symmetric key */
crv=pk11_Attribute2SecItem(arena,&privKey->u.rsa.modulus,object,CKA_ID);
@@ -2272,7 +1796,8 @@ pk11_mkSecretKeyRep(PK11Object *object)
if (crv != CKR_OK) goto loser;
/* Private key version field set normally for compatibility */
- rv = DER_SetUInteger(privKey->arena, &privKey->u.rsa.version,SEC_PRIVATE_KEY_VERSION);
+ rv = DER_SetUInteger(privKey->arena,
+ &privKey->u.rsa.version, NSSLOWKEY_VERSION);
if (rv != SECSuccess) { crv = CKR_HOST_MEMORY; goto loser; }
loser:
@@ -2285,117 +1810,178 @@ loser:
}
static PRBool
-isSecretKey(SECKEYLowPrivateKey *privKey)
+isSecretKey(NSSLOWKEYPrivateKey *privKey)
{
- if (privKey->keyType == lowRSAKey && privKey->u.rsa.publicExponent.len == 1 &&
- privKey->u.rsa.publicExponent.data[0] == 0)
+ if (privKey->keyType == NSSLOWKEYRSAKey &&
+ privKey->u.rsa.publicExponent.len == 1 &&
+ privKey->u.rsa.publicExponent.data[0] == 0)
return PR_TRUE;
return PR_FALSE;
}
-/* Import a Secret Key */
-static PRBool
-importSecretKey(PK11Slot *slot, SECKEYLowPrivateKey *priv)
-{
- PK11Object *object;
- CK_OBJECT_CLASS secretClass = CKO_SECRET_KEY;
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_KEY_TYPE key_type;
+/**********************************************************************
+ *
+ * Start of PKCS 11 functions
+ *
+ **********************************************************************/
- /* Check for secret key representation, return if it isn't one */
- if (!isSecretKey(priv))
- return PR_FALSE;
- /*
- * now lets create an object to hang the attributes off of
- */
- object = pk11_NewObject(slot); /* fill in the handle later */
- if (object == NULL) {
- goto loser;
- }
+/* return the function list */
+CK_RV NSC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList)
+{
+ *pFunctionList = (CK_FUNCTION_LIST_PTR) &pk11_funcList;
+ return CKR_OK;
+}
- /* Set the ID value */
- if (pk11_AddAttributeType(object, CKA_ID,
- priv->u.rsa.modulus.data, priv->u.rsa.modulus.len)) {
- pk11_FreeObject(object);
- goto loser;
- }
+/* return the function list */
+CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList)
+{
+ return NSC_GetFunctionList(pFunctionList);
+}
- /* initalize the object attributes */
- if (pk11_AddAttributeType(object, CKA_CLASS, &secretClass,
- sizeof(secretClass)) != CKR_OK) {
- pk11_FreeObject(object);
- goto loser;
- }
+static PLHashNumber
+pk11_HashNumber(const void *key)
+{
+ return (PLHashNumber) key;
+}
- if (pk11_AddAttributeType(object, CKA_TOKEN, &cktrue,
- sizeof(cktrue)) != CKR_OK) {
- pk11_FreeObject(object);
- goto loser;
- }
+/*
+ * eventually I'd like to expunge all occurances of XXX_SLOT_ID and
+ * just go with the info in the slot. This is one place, however,
+ * where it might be a little difficult.
+ */
+char *
+pk11_getDefTokName(CK_SLOT_ID slotID)
+{
+ static char buf[33];
- if (pk11_AddAttributeType(object, CKA_PRIVATE, &ckfalse,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(object);
- goto loser;
+ switch (slotID) {
+ case NETSCAPE_SLOT_ID:
+ return "NSS Generic Crypto Services ";
+ case PRIVATE_KEY_SLOT_ID:
+ return "NSS Certificate DB ";
+ case FIPS_SLOT_ID:
+ return "NSS FIPS-140-1 Cerificate DB ";
+ default:
+ break;
}
+ sprintf(buf,"NSS Application Token %08x ",(unsigned int) slotID);
+ return buf;
+}
- if (pk11_AddAttributeType(object, CKA_VALUE,
- pk11_item_expand(&priv->u.rsa.privateExponent)) != CKR_OK) {
- pk11_FreeObject(object);
- goto loser;
- }
+char *
+pk11_getDefSlotName(CK_SLOT_ID slotID)
+{
+ static char buf[65];
- if (pk11_AddAttributeType(object, CKA_KEY_TYPE,
- pk11_item_expand(&priv->u.rsa.coefficient)) != CKR_OK) {
- pk11_FreeObject(object);
- goto loser;
+ switch (slotID) {
+ case NETSCAPE_SLOT_ID:
+ return
+ "NSS Internal Cryptographic Services Version 3.4 ";
+ case PRIVATE_KEY_SLOT_ID:
+ return
+ "NSS User Private Key and Certificate Services ";
+ case FIPS_SLOT_ID:
+ return
+ "Netscape FIPS-140-1 User Private Key Services ";
+ default:
+ break;
}
- key_type = *(CK_KEY_TYPE*)priv->u.rsa.coefficient.data;
+ sprintf(buf,
+ "NSS Application Slot %08x ",
+ (unsigned int) slotID);
+ return buf;
+}
- /* Validate and add default attributes */
- validateSecretKey(object, key_type, (PRBool)(slot->slotID == FIPS_SLOT_ID));
+static CK_ULONG nscSlotCount = 0;
+static CK_SLOT_ID_PTR nscSlotList = NULL;
+static CK_ULONG nscSlotListSize = 0;
+static PLHashTable *nscSlotHashTable = NULL;
- /* now just verify the required date fields */
- PK11_USE_THREADS(PZ_Lock(slot->objectLock);)
- object->handle = slot->tokenIDCount++;
- object->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
- PK11_USE_THREADS(PZ_Unlock(slot->objectLock);)
+/* 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);
+}
+
+PK11Slot *
+pk11_SlotFromSessionHandle(CK_SESSION_HANDLE handle)
+{
+ int slotIDIndex = (handle >> 24) & 0xff;
- object->objclass = secretClass;
- object->slot = slot;
- object->inDB = PR_TRUE;
- pk11_AddSlotObject(slot, object);
+ if (slotIDIndex >= nscSlotCount) {
+ return NULL;
+ }
-loser:
- return PR_TRUE;
+ return pk11_SlotFromID(nscSlotList[slotIDIndex]);
}
+
+PK11Slot * pk11_NewSlotFromID(CK_SLOT_ID slotID)
+{
+ PK11Slot *slot = NULL;
+ PLHashEntry *entry;
+
+ if (nscSlotList == NULL) {
+ nscSlotListSize = NSC_SLOT_LIST_BLOCK_SIZE;
+ nscSlotList = (CK_SLOT_ID *)
+ PORT_ZAlloc(nscSlotListSize*sizeof(CK_SLOT_ID));
+ if (nscSlotList == 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 (nscSlotHashTable == NULL) {
+ nscSlotHashTable = PL_NewHashTable(64,pk11_HashNumber,PL_CompareValues,
+ PL_CompareValues, NULL, 0);
+ if (nscSlotHashTable == NULL) {
+ return NULL;
+ }
+ }
-/**********************************************************************
- *
- * Start of PKCS 11 functions
- *
- **********************************************************************/
+ slot = (PK11Slot *) PORT_ZAlloc(sizeof(PK11Slot));
+ if (slot == NULL) {
+ return NULL;
+ }
+ entry = PL_HashTableAdd(nscSlotHashTable,(void *)slotID,slot);
+ if (entry == NULL) {
+ PORT_Free(slot);
+ return NULL;
+ }
+ slot->index = nscSlotCount;
+ nscSlotList[nscSlotCount++] = slotID;
-/* return the function list */
-CK_RV NSC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList)
-{
- *pFunctionList = &pk11_funcList;
- return CKR_OK;
+ return slot;
}
/*
* initialize one of the slot structures. figure out which by the ID
*/
CK_RV
-PK11_SlotInit(CK_SLOT_ID slotID, PRBool needLogin)
+PK11_SlotInit(char *configdir,pk11_token_parameters *params)
{
int i;
- PK11Slot *slot = pk11_SlotFromID(slotID);
+ CK_SLOT_ID slotID = params->slotID;
+ PK11Slot *slot = pk11_NewSlotFromID(slotID);
+ PRBool needLogin = !params->noKeyDB;
+ CK_RV crv;
+
+ if (slot == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+
#ifdef PKCS11_USE_THREADS
slot->sessionLock = PZ_NewLock(nssILockSession);
if (slot->sessionLock == NULL) return CKR_HOST_MEMORY;
@@ -2411,6 +1997,11 @@ PK11_SlotInit(CK_SLOT_ID slotID, PRBool needLogin)
for(i=0; i < TOKEN_OBJECT_HASH_SIZE; i++) {
slot->tokObjects[i] = NULL;
}
+ slot->tokenHashTable = PL_NewHashTable(64,pk11_HashNumber,PL_CompareValues,
+ SECITEM_HashCompare, NULL, 0);
+ if (slot->tokenHashTable == NULL) {
+ return CKR_HOST_MEMORY;
+ }
slot->password = NULL;
slot->hasTokens = PR_FALSE;
slot->sessionIDCount = 1;
@@ -2422,61 +2013,39 @@ PK11_SlotInit(CK_SLOT_ID slotID, PRBool needLogin)
slot->ssoLoggedIn = PR_FALSE;
slot->DB_loaded = PR_FALSE;
slot->slotID = slotID;
- if (needLogin) {
- /* if the data base is initialized with a null password,remember that */
- slot->needLogin = (PRBool)!pk11_hasNullPassword(&slot->password);
- }
- return CKR_OK;
-}
-
-
-/*
- * common initialization routines between PKCS #11 and FIPS
- */
-CK_RV PK11_LowInitialize(CK_VOID_PTR pReserved)
-{
- CK_RV crv = CKR_OK;
- CK_C_INITIALIZE_ARGS *init_args = (CK_C_INITIALIZE_ARGS *) pReserved;
-
- /* NOTE:
- * we should be getting out mutexes from this list, not statically binding
- * them from NSPR. This should happen before we allow the internal to split
- * off from the rest on NSS.
- */
-
- /* initialize the key and cert db's */
- SECKEY_SetDefaultKeyDBAlg(SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC);
-
- if ((init_args && init_args->LibraryParameters)) {
- pk11_parameters paramStrings;
-
- crv = secmod_parseParameters
- ((char *)init_args->LibraryParameters,&paramStrings);
+ slot->certDB = NULL;
+ slot->keyDB = NULL;
+ slot->minimumPinLen = 0;
+ slot->readOnly = params->readOnly;
+ pk11_setStringName(params->tokdes ? params->tokdes :
+ pk11_getDefTokName(slotID), slot->tokDescription,
+ sizeof(slot->tokDescription));
+ pk11_setStringName(params->slotdes ? params->slotdes :
+ pk11_getDefSlotName(slotID), slot->slotDescription,
+ sizeof(slot->slotDescription));
+
+ if ((!params->noCertDB) || (!params->noKeyDB)) {
+ crv = pk11_DBInit(params->configdir ? params->configdir : configdir,
+ params->certPrefix, params->keyPrefix, params->readOnly,
+ params->noCertDB, params->noKeyDB, params->forceOpen,
+ &slot->certDB, &slot->keyDB);
if (crv != CKR_OK) {
+ /* shoutdown slot? */
return crv;
}
-
- crv = pk11_DBInit(paramStrings.configdir,paramStrings.certPrefix,
- paramStrings.keyPrefix,paramStrings.secmodName, paramStrings.readOnly,paramStrings.noCertDB,
- paramStrings.noModDB, paramStrings.forceOpen);
- if (crv != CKR_OK) {
- secmod_freeParams(&paramStrings);
- return crv;
+ }
+ if (needLogin) {
+ /* if the data base is initialized with a null password,remember that */
+ slot->needLogin =
+ (PRBool)!pk11_hasNullPassword(slot->keyDB,&slot->password);
+ if (params->minPW <= PK11_MAX_PIN) {
+ slot->minimumPinLen = params->minPW;
}
- crv = pk11_configure(paramStrings.man, paramStrings.libdes,
- paramStrings.tokdes,paramStrings.ptokdes,paramStrings.slotdes,
- paramStrings.pslotdes,paramStrings.fslotdes,
- paramStrings.fpslotdes, paramStrings.minPW,
- paramStrings.pwRequired);
- secmod_freeParams(&paramStrings);
- if (crv != CKR_OK) {
- return crv;
+ if ((slot->minimumPinLen == 0) && (params->pwRequired) &&
+ (slot->minimumPinLen <= PK11_MAX_PIN)) {
+ slot->minimumPinLen = 1;
}
- } else {
- return CKR_ARGUMENTS_BAD;
}
-
-
return CKR_OK;
}
@@ -2507,25 +2076,67 @@ NSC_ModuleDBFunc(unsigned long function,char *parameters, char *args)
/* NSC_Initialize initializes the Cryptoki library. */
-CK_RV NSC_Initialize(CK_VOID_PTR pReserved)
+CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)
{
static PRBool init = PR_FALSE;
CK_RV crv = CKR_OK;
+ SECStatus rv;
+ CK_C_INITIALIZE_ARGS *init_args = (CK_C_INITIALIZE_ARGS *) pReserved;
+ int i;
- crv = PK11_LowInitialize(pReserved);
- if (crv != CKR_OK) return crv;
+ if (init) {
+ return crv;
+ }
- /* intialize all the slots */
- if (!init) {
- crv = PK11_SlotInit(NETSCAPE_SLOT_ID,PR_FALSE);
- if (crv != CKR_OK) return crv;
- crv = PK11_SlotInit(PRIVATE_KEY_SLOT_ID,PR_TRUE);
- init = PR_TRUE;
+ rv = RNG_RNGInit(); /* initialize random number generator */
+ if (rv != SECSuccess) {
+ crv = CKR_DEVICE_ERROR;
+ goto loser;
}
+ RNG_SystemInfoForRNG();
+
+
+ /* NOTE:
+ * we should be getting out mutexes from this list, not statically binding
+ * them from NSPR. This should happen before we allow the internal to split
+ * off from the rest on NSS.
+ */
+
+ /* initialize the key and cert db's */
+ nsslowkey_SetDefaultKeyDBAlg
+ (SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC);
+ crv = CKR_ARGUMENTS_BAD;
+ if ((init_args && init_args->LibraryParameters)) {
+ pk11_parameters paramStrings;
+
+ crv = secmod_parseParameters
+ ((char *)init_args->LibraryParameters,&paramStrings, isFIPS);
+ if (crv != CKR_OK) {
+ return crv;
+ }
+ crv = pk11_configure(paramStrings.man, paramStrings.libdes);
+ if (crv != CKR_OK) {
+ goto loser;
+ }
+
+ for (i=0; i < paramStrings.token_count; i++) {
+ crv =
+ PK11_SlotInit(paramStrings.configdir,&paramStrings.tokens[i]);
+ if (crv != CKR_OK) break;
+ }
+loser:
+ secmod_freeParams(&paramStrings);
+ }
+ init = (PRBool) (crv == CKR_OK);
return crv;
}
+CK_RV NSC_Initialize(CK_VOID_PTR pReserved)
+{
+ return nsc_CommonInitialize(pReserved,PR_FALSE);
+}
+
/* NSC_Finalize indicates that an application is done with the
* Cryptoki library.*/
CK_RV NSC_Finalize (CK_VOID_PTR pReserved)
@@ -2538,7 +2149,7 @@ CK_RV NSC_Finalize (CK_VOID_PTR pReserved)
CK_RV NSC_GetInfo(CK_INFO_PTR pInfo)
{
pInfo->cryptokiVersion.major = 2;
- pInfo->cryptokiVersion.minor = 1;
+ pInfo->cryptokiVersion.minor = 11;
PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
pInfo->libraryVersion.major = 3;
pInfo->libraryVersion.minor = 2;
@@ -2551,10 +2162,9 @@ CK_RV NSC_GetInfo(CK_INFO_PTR pInfo)
CK_RV NSC_GetSlotList(CK_BBOOL tokenPresent,
CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount)
{
- *pulCount = 2;
+ *pulCount = nscSlotCount;
if (pSlotList != NULL) {
- pSlotList[0] = NETSCAPE_SLOT_ID;
- pSlotList[1] = PRIVATE_KEY_SLOT_ID;
+ PORT_Memcpy(pSlotList,nscSlotList,nscSlotCount*sizeof(CK_SLOT_ID));
}
return CKR_OK;
}
@@ -2562,28 +2172,19 @@ CK_RV NSC_GetSlotList(CK_BBOOL tokenPresent,
/* NSC_GetSlotInfo obtains information about a particular slot in the system. */
CK_RV NSC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
{
+ PK11Slot *slot = pk11_SlotFromID(slotID);
+ if (slot == NULL) return CKR_SLOT_ID_INVALID;
+
pInfo->firmwareVersion.major = 0;
pInfo->firmwareVersion.minor = 0;
- switch (slotID) {
- case NETSCAPE_SLOT_ID:
- PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
- PORT_Memcpy(pInfo->slotDescription,slotDescription,64);
- pInfo->flags = CKF_TOKEN_PRESENT;
- pInfo->hardwareVersion.major = 3;
- pInfo->hardwareVersion.minor = 2;
- return CKR_OK;
- case PRIVATE_KEY_SLOT_ID:
- PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
- PORT_Memcpy(pInfo->slotDescription,privSlotDescription,64);
- pInfo->flags = CKF_TOKEN_PRESENT;
- /* ok we really should read it out of the keydb file. */
- pInfo->hardwareVersion.major = PRIVATE_KEY_DB_FILE_VERSION;
- pInfo->hardwareVersion.minor = 0;
- return CKR_OK;
- default:
- break;
- }
- return CKR_SLOT_ID_INVALID;
+ PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
+ PORT_Memcpy(pInfo->slotDescription,slot->slotDescription,64);
+ pInfo->flags = CKF_TOKEN_PRESENT;
+ /* ok we really should read it out of the keydb file. */
+ /* pInfo->hardwareVersion.major = NSSLOWKEY_DB_FILE_VERSION; */
+ pInfo->hardwareVersion.major = 3;
+ pInfo->hardwareVersion.minor = 2;
+ return CKR_OK;
}
#define CKF_THREAD_SAFE 0x8000 /* for now */
@@ -2593,12 +2194,12 @@ CK_RV NSC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
{
PK11Slot *slot = pk11_SlotFromID(slotID);
- SECKEYKeyDBHandle *handle;
+ NSSLOWKEYDBHandle *handle;
if (slot == NULL) return CKR_SLOT_ID_INVALID;
PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
- PORT_Memcpy(pInfo->model,"Libsec 4.0 ",16);
+ PORT_Memcpy(pInfo->model,"NSS 3 ",16);
PORT_Memcpy(pInfo->serialNumber,"0000000000000000",16);
pInfo->ulMaxSessionCount = 0; /* arbitrarily large */
pInfo->ulSessionCount = slot->sessionCount;
@@ -2606,9 +2207,9 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
pInfo->ulRwSessionCount = slot->rwSessionCount;
pInfo->firmwareVersion.major = 0;
pInfo->firmwareVersion.minor = 0;
- switch (slotID) {
- case NETSCAPE_SLOT_ID:
- PORT_Memcpy(pInfo->label,tokDescription,32);
+ PORT_Memcpy(pInfo->label,slot->tokDescription,32);
+ handle = slot->keyDB;
+ if (handle == NULL) {
pInfo->flags= CKF_RNG | CKF_WRITE_PROTECTED | CKF_THREAD_SAFE;
pInfo->ulMaxPinLen = 0;
pInfo->ulMinPinLen = 0;
@@ -2618,10 +2219,7 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
pInfo->ulFreePrivateMemory = 0;
pInfo->hardwareVersion.major = 4;
pInfo->hardwareVersion.minor = 0;
- return CKR_OK;
- case PRIVATE_KEY_SLOT_ID:
- PORT_Memcpy(pInfo->label,privTokDescription,32);
- handle = SECKEY_GetDefaultKeyDB();
+ } else {
/*
* we have three possible states which we may be in:
* (1) No DB password has been initialized. This also means we
@@ -2631,7 +2229,7 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
* (3) Finally we have an initialized password whicn is not NULL, and
* we will need to prompt for it.
*/
- if (SECKEY_HasKeyDBPassword(handle) == SECFailure) {
+ if (nsslowkey_HasKeyDBPassword(handle) == SECFailure) {
pInfo->flags = CKF_THREAD_SAFE | CKF_LOGIN_REQUIRED;
} else if (!slot->needLogin) {
pInfo->flags = CKF_THREAD_SAFE | CKF_USER_PIN_INITIALIZED;
@@ -2641,8 +2239,8 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
}
pInfo->ulMaxPinLen = PK11_MAX_PIN;
pInfo->ulMinPinLen = 0;
- if (minimumPinLen > 0) {
- pInfo->ulMinPinLen = (CK_ULONG)minimumPinLen;
+ if (slot->minimumPinLen > 0) {
+ pInfo->ulMinPinLen = (CK_ULONG)slot->minimumPinLen;
}
pInfo->ulTotalPublicMemory = 1;
pInfo->ulFreePublicMemory = 1;
@@ -2650,11 +2248,8 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
pInfo->ulFreePrivateMemory = 1;
pInfo->hardwareVersion.major = CERT_DB_FILE_VERSION;
pInfo->hardwareVersion.minor = 0;
- return CKR_OK;
- default:
- break;
}
- return CKR_SLOT_ID_INVALID;
+ return CKR_OK;
}
@@ -2674,8 +2269,8 @@ CK_RV NSC_GetMechanismList(CK_SLOT_ID slotID,
pMechanismList[i] = mechanisms[i].type;
}
}
- return CKR_OK;
- case PRIVATE_KEY_SLOT_ID:
+ break;
+ default:
*pulCount = 0;
for (i=0; i < (int) mechanismCount; i++) {
if (mechanisms[i].privkey) {
@@ -2685,11 +2280,9 @@ CK_RV NSC_GetMechanismList(CK_SLOT_ID slotID,
}
}
}
- return CKR_OK;
- default:
break;
}
- return CKR_SLOT_ID_INVALID;
+ return CKR_OK;
}
@@ -2705,11 +2298,9 @@ CK_RV NSC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
case NETSCAPE_SLOT_ID:
isPrivateKey = PR_FALSE;
break;
- case PRIVATE_KEY_SLOT_ID:
+ default:
isPrivateKey = PR_TRUE;
break;
- default:
- return CKR_SLOT_ID_INVALID;
}
for (i=0; i < (int) mechanismCount; i++) {
if (type == mechanisms[i].type) {
@@ -2725,19 +2316,19 @@ CK_RV NSC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
}
static SECStatus
-pk11_TurnOffUser(CERTCertificate *cert, SECItem *k, void *arg)
+pk11_TurnOffUser(NSSLOWCERTCertificate *cert, SECItem *k, void *arg)
{
- CERTCertTrust trust;
+ NSSLOWCERTCertTrust trust;
SECStatus rv;
- rv = CERT_GetCertTrust(cert,&trust);
+ rv = nsslowcert_GetCertTrust(cert,&trust);
if (rv == SECSuccess && ((trust.emailFlags & CERTDB_USER) ||
(trust.sslFlags & CERTDB_USER) ||
(trust.objectSigningFlags & CERTDB_USER))) {
trust.emailFlags &= ~CERTDB_USER;
trust.sslFlags &= ~CERTDB_USER;
trust.objectSigningFlags &= ~CERTDB_USER;
- CERT_ChangeCertTrust(cert->dbhandle,cert,&trust);
+ nsslowcert_ChangeCertTrust(cert->dbhandle,cert,&trust);
}
return SECSuccess;
}
@@ -2746,8 +2337,8 @@ pk11_TurnOffUser(CERTCertificate *cert, SECItem *k, void *arg)
CK_RV NSC_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin,
CK_ULONG ulPinLen,CK_CHAR_PTR pLabel) {
PK11Slot *slot = pk11_SlotFromID(slotID);
- SECKEYKeyDBHandle *handle;
- CERTCertDBHandle *certHandle;
+ NSSLOWKEYDBHandle *handle;
+ NSSLOWCERTCertDBHandle *certHandle;
SECStatus rv;
int i;
PK11Object *object;
@@ -2784,19 +2375,19 @@ CK_RV NSC_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin,
PK11_USE_THREADS(PZ_Unlock(slot->objectLock);)
/* then clear out the key database */
- handle = SECKEY_GetDefaultKeyDB();
+ handle = slot->keyDB;
if (handle == NULL) {
return CKR_TOKEN_WRITE_PROTECTED;
}
/* what to do on an error here? */
- rv = SECKEY_ResetKeyDB(handle);
+ rv = nsslowkey_ResetKeyDB(handle);
/* finally mark all the user certs as non-user certs */
- certHandle = CERT_GetDefaultCertDB();
+ certHandle = slot->certDB;
if (certHandle == NULL) return CKR_OK;
- SEC_TraversePermCerts(certHandle,pk11_TurnOffUser, NULL);
+ nsslowcert_TraversePermCerts(certHandle,pk11_TurnOffUser, NULL);
return CKR_OK; /*is this the right function for not implemented*/
}
@@ -2808,9 +2399,9 @@ CK_RV NSC_InitPIN(CK_SESSION_HANDLE hSession,
{
PK11Session *sp;
PK11Slot *slot;
- SECKEYKeyDBHandle *handle;
+ NSSLOWKEYDBHandle *handle;
SECItem *newPin;
- char newPinStr[256];
+ char newPinStr[PK11_MAX_PIN+1];
SECStatus rv;
@@ -2819,36 +2410,35 @@ CK_RV NSC_InitPIN(CK_SESSION_HANDLE hSession,
return CKR_SESSION_HANDLE_INVALID;
}
- if (sp->info.slotID == NETSCAPE_SLOT_ID) {
+ slot = pk11_SlotFromSession(sp);
+ if (slot == NULL) {
pk11_FreeSession(sp);
- return CKR_PIN_LEN_RANGE;
+ return CKR_SESSION_HANDLE_INVALID;;
}
- /* should be an assert */
- if (!((sp->info.slotID == PRIVATE_KEY_SLOT_ID) ||
- (sp->info.slotID == FIPS_SLOT_ID)) ) {
+ handle = slot->keyDB;
+ if (handle == NULL) {
pk11_FreeSession(sp);
- return CKR_SESSION_HANDLE_INVALID;;
+ return CKR_PIN_LEN_RANGE;
}
+
if (sp->info.state != CKS_RW_SO_FUNCTIONS) {
pk11_FreeSession(sp);
return CKR_USER_NOT_LOGGED_IN;
}
- slot = pk11_SlotFromSession(sp);
pk11_FreeSession(sp);
/* make sure the pins aren't too long */
- if (ulPinLen > 255) {
+ if (ulPinLen > PK11_MAX_PIN) {
return CKR_PIN_LEN_RANGE;
}
-
- handle = SECKEY_GetDefaultKeyDB();
- if (handle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
+ if (ulPinLen < slot->minimumPinLen) {
+ return CKR_PIN_LEN_RANGE;
}
- if (SECKEY_HasKeyDBPassword(handle) != SECFailure) {
+
+ if (nsslowkey_HasKeyDBPassword(handle) != SECFailure) {
return CKR_DEVICE_ERROR;
}
@@ -2857,11 +2447,11 @@ CK_RV NSC_InitPIN(CK_SESSION_HANDLE hSession,
newPinStr[ulPinLen] = 0;
/* build the hashed pins which we pass around */
- newPin = SECKEY_HashPassword(newPinStr,handle->global_salt);
+ newPin = nsslowkey_HashPassword(newPinStr,handle->global_salt);
PORT_Memset(newPinStr,0,sizeof(newPinStr));
/* change the data base */
- rv = SECKEY_SetKeyDBPassword(handle,newPin);
+ rv = nsslowkey_SetKeyDBPassword(handle,newPin);
/* Now update our local copy of the pin */
if (rv == SECSuccess) {
@@ -2884,10 +2474,10 @@ CK_RV NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
{
PK11Session *sp;
PK11Slot *slot;
- SECKEYKeyDBHandle *handle;
+ NSSLOWKEYDBHandle *handle;
SECItem *newPin;
SECItem *oldPin;
- char newPinStr[256],oldPinStr[256];
+ char newPinStr[PK11_MAX_PIN+1],oldPinStr[PK11_MAX_PIN+1];
SECStatus rv;
@@ -2896,20 +2486,18 @@ CK_RV NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
return CKR_SESSION_HANDLE_INVALID;
}
- if (sp->info.slotID == NETSCAPE_SLOT_ID) {
+ slot = pk11_SlotFromSession(sp);
+ if (!slot) {
pk11_FreeSession(sp);
- return CKR_PIN_LEN_RANGE;
+ return CKR_SESSION_HANDLE_INVALID;;
}
- /* should be an assert */
- /* should be an assert */
- if (!((sp->info.slotID == PRIVATE_KEY_SLOT_ID) ||
- (sp->info.slotID == FIPS_SLOT_ID)) ) {
+ handle = slot->keyDB;
+ if (handle == NULL) {
pk11_FreeSession(sp);
- return CKR_SESSION_HANDLE_INVALID;;
+ return CKR_PIN_LEN_RANGE;
}
- slot = pk11_SlotFromSession(sp);
if (slot->needLogin && sp->info.state != CKS_RW_USER_FUNCTIONS) {
pk11_FreeSession(sp);
return CKR_USER_NOT_LOGGED_IN;
@@ -2918,16 +2506,14 @@ CK_RV NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
pk11_FreeSession(sp);
/* make sure the pins aren't too long */
- if ((ulNewLen > 255) || (ulOldLen > 255)) {
+ if ((ulNewLen > PK11_MAX_PIN) || (ulOldLen > PK11_MAX_PIN)) {
return CKR_PIN_LEN_RANGE;
}
-
-
- handle = SECKEY_GetDefaultKeyDB();
- if (handle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
+ if (ulNewLen < slot->minimumPinLen) {
+ return CKR_PIN_LEN_RANGE;
}
+
/* convert to null terminated string */
PORT_Memcpy(newPinStr,pNewPin,ulNewLen);
newPinStr[ulNewLen] = 0;
@@ -2935,13 +2521,13 @@ CK_RV NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
oldPinStr[ulOldLen] = 0;
/* build the hashed pins which we pass around */
- newPin = SECKEY_HashPassword(newPinStr,handle->global_salt);
- oldPin = SECKEY_HashPassword(oldPinStr,handle->global_salt);
+ newPin = nsslowkey_HashPassword(newPinStr,handle->global_salt);
+ oldPin = nsslowkey_HashPassword(oldPinStr,handle->global_salt);
PORT_Memset(newPinStr,0,sizeof(newPinStr));
PORT_Memset(oldPinStr,0,sizeof(oldPinStr));
/* change the data base */
- rv = SECKEY_ChangeKeyDBPassword(handle,oldPin,newPin);
+ rv = nsslowkey_ChangeKeyDBPassword(handle,oldPin,newPin);
/* Now update our local copy of the pin */
SECITEM_ZfreeItem(oldPin, PR_TRUE);
@@ -2974,12 +2560,8 @@ CK_RV NSC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags,
if (session == NULL) return CKR_HOST_MEMORY;
PK11_USE_THREADS(PZ_Lock(slot->sessionLock);)
- sessionID = slot->sessionIDCount++;
- if (slotID == PRIVATE_KEY_SLOT_ID) {
- sessionID |= PK11_PRIVATE_KEY_FLAG;
- } else if (slotID == FIPS_SLOT_ID) {
- sessionID |= PK11_FIPS_FLAG;
- } else if (flags & CKF_RW_SESSION) {
+ sessionID = slot->sessionIDCount++ | (slot->index << 24);
+ if (slot->readOnly && (flags & CKF_RW_SESSION)) {
/* NETSCAPE_SLOT_ID is Read ONLY */
session->info.flags &= ~CKF_RW_SESSION;
}
@@ -3101,9 +2683,9 @@ CK_RV NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
{
PK11Slot *slot;
PK11Session *session;
- SECKEYKeyDBHandle *handle;
+ NSSLOWKEYDBHandle *handle;
SECItem *pin;
- char pinStr[256];
+ char pinStr[PK11_MAX_PIN+1];
/* get the slot */
@@ -3123,20 +2705,23 @@ CK_RV NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
if (slot->isLoggedIn) return CKR_USER_ALREADY_LOGGED_IN;
slot->ssoLoggedIn = PR_FALSE;
- if (ulPinLen > 255) return CKR_PIN_LEN_RANGE;
+ if (ulPinLen > PK11_MAX_PIN) return CKR_PIN_LEN_RANGE;
/* convert to null terminated string */
PORT_Memcpy(pinStr,pPin,ulPinLen);
pinStr[ulPinLen] = 0;
- handle = SECKEY_GetDefaultKeyDB();
+ handle = slot->keyDB;
+ if (handle == NULL) {
+ return CKR_USER_TYPE_INVALID;
+ }
/*
* Deal with bootstrap. We allow the SSO to login in with a NULL
* password if and only if we haven't initialized the KEY DB yet.
* We only allow this on a RW session.
*/
- if (SECKEY_HasKeyDBPassword(handle) == SECFailure) {
+ if (nsslowkey_HasKeyDBPassword(handle) == SECFailure) {
/* allow SSO's to log in only if there is not password on the
* key database */
if (((userType == CKU_SO) && (session->info.flags & CKF_RW_SESSION))
@@ -3165,10 +2750,10 @@ CK_RV NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
/* build the hashed pins which we pass around */
- pin = SECKEY_HashPassword(pinStr,handle->global_salt);
+ pin = nsslowkey_HashPassword(pinStr,handle->global_salt);
if (pin == NULL) return CKR_HOST_MEMORY;
- if (SECKEY_CheckKeyDBPassword(handle,pin) == SECSuccess) {
+ if (nsslowkey_CheckKeyDBPassword(handle,pin) == SECSuccess) {
SECItem *tmp;
PK11_USE_THREADS(PZ_Lock(slot->sessionLock);)
tmp = slot->password;
@@ -3255,14 +2840,11 @@ CK_RV NSC_CreateObject(CK_SESSION_HANDLE hSession,
* handle the base object stuff
*/
crv = pk11_handleObject(object,session);
+ *phObject = object->handle;
pk11_FreeSession(session);
- if (crv != CKR_OK) {
- pk11_FreeObject(object);
- return crv;
- }
+ pk11_FreeObject(object);
- *phObject = object->handle;
- return CKR_OK;
+ return crv;
}
@@ -3343,12 +2925,9 @@ CK_RV NSC_CopyObject(CK_SESSION_HANDLE hSession,
crv = pk11_handleObject(destObject,session);
*phNewObject = destObject->handle;
pk11_FreeSession(session);
- if (crv != CKR_OK) {
- pk11_FreeObject(destObject);
- return crv;
- }
+ pk11_FreeObject(destObject);
- return CKR_OK;
+ return crv;
}
@@ -3497,568 +3076,641 @@ CK_RV NSC_SetAttributeValue (CK_SESSION_HANDLE hSession,
}
pk11_FreeObject(object);
- return CKR_OK;
+ return crv;
}
-/* stolen from keydb.c */
-#define KEYDB_PW_CHECK_STRING "password-check"
-#define KEYDB_PW_CHECK_LEN 14
-
-SECKEYLowPrivateKey * SECKEY_DecryptKey(DBT *key, SECItem *pwitem,
- SECKEYKeyDBHandle *handle);
-typedef struct pk11keyNodeStr {
- struct pk11keyNodeStr *next;
- SECKEYLowPrivateKey *privKey;
- CERTCertificate *cert;
- SECItem *pubItem;
-} pk11keyNode;
+/*
+ * find any certs that may match the template and load them.
+ */
+#define NSC_CERT 0x00000001
+#define NSC_TRUST 0x00000002
+#define NSC_CRL 0x00000004
+#define NSC_SMIME 0x00000008
+#define NSC_PRIVATE 0x00000010
+#define NSC_PUBLIC 0x00000020
+#define NSC_KEY 0x00000040
-typedef struct {
- PLArenaPool *arena;
- pk11keyNode *head;
+/*
+ * structure to collect key handles.
+ */
+typedef struct pk11CrlDataStr {
PK11Slot *slot;
-} keyList;
+ PK11SearchResults *searchHandles;
+ CK_ATTRIBUTE *template;
+ CK_ULONG templ_count;
+} pk11CrlData;
+
static SECStatus
-add_key_to_list(DBT *key, DBT *data, void *arg)
+pk11_crl_collect(SECItem *data, SECItem *key, certDBEntryType type, void *arg)
{
- keyList *keylist;
- pk11keyNode *node;
- void *keydata;
- SECKEYLowPrivateKey *privKey = NULL;
+ pk11CrlData *crlData;
+ CK_OBJECT_HANDLE class_handle;
+ PK11Slot *slot;
- keylist = (keyList *)arg;
+ crlData = (pk11CrlData *)arg;
+ slot = crlData->slot;
- privKey = SECKEY_DecryptKey(key, keylist->slot->password,
- SECKEY_GetDefaultKeyDB());
- if ( privKey == NULL ) {
- goto loser;
+ class_handle = (type == certDBEntryTypeRevocation) ? PK11_TOKEN_TYPE_CRL :
+ PK11_TOKEN_KRL_HANDLE;
+ if (pk11_tokenMatch(slot, key, class_handle,
+ crlData->template, crlData->templ_count)) {
+ pk11_addHandle(crlData->searchHandles,
+ pk11_mkHandle(slot,key,class_handle));
}
+ return(SECSuccess);
+}
- /* allocate the node struct */
- node = (pk11keyNode*)PORT_ArenaZAlloc(keylist->arena, sizeof(pk11keyNode));
- if ( node == NULL ) {
- goto loser;
- }
-
- /* allocate room for key data */
- keydata = PORT_ArenaZAlloc(keylist->arena, key->size);
- if ( keydata == NULL ) {
- goto loser;
- }
+static void
+pk11_searchCrls(PK11Slot *slot, SECItem *derSubject, PRBool isKrl,
+ unsigned long classFlags, PK11SearchResults *search,
+ CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount)
+{
+ NSSLOWCERTCertDBHandle *certHandle = NULL;
- /* link node into list */
- node->next = keylist->head;
- keylist->head = node;
-
- node->privKey = privKey;
- switch (privKey->keyType) {
- case lowRSAKey:
- node->pubItem = &privKey->u.rsa.modulus;
- break;
- case lowDSAKey:
- node->pubItem = &privKey->u.dsa.publicValue;
- break;
- default:
- break;
- }
-
- return(SECSuccess);
-loser:
- if ( privKey ) {
- SECKEY_LowDestroyPrivateKey(privKey);
+ certHandle = slot->certDB;
+ if (certHandle == NULL) {
+ return;
}
- return(SECSuccess);
+ if (derSubject->data != NULL) {
+ SECItem *crl =
+ nsslowcert_FindCrlByKey(certHandle,derSubject,NULL,isKrl);
+
+ if (crl != NULL) {
+ pk11_addHandle(search, pk11_mkHandle(slot,derSubject,
+ isKrl ? PK11_TOKEN_KRL_HANDLE : PK11_TOKEN_TYPE_CRL));
+ }
+ } else {
+ pk11CrlData crlData;
+
+ /* traverse */
+ crlData.slot = slot;
+ crlData.searchHandles = search;
+ crlData.template = pTemplate;
+ crlData.templ_count = ulCount;
+ nsslowcert_TraverseDBEntries(certHandle, certDBEntryTypeRevocation,
+ pk11_crl_collect, (void *)&crlData);
+ nsslowcert_TraverseDBEntries(certHandle, certDBEntryTypeKeyRevocation,
+ pk11_crl_collect, (void *)&crlData);
+ }
}
/*
- * If the cert is a user cert, then try to match it to a key on the
- * linked list of private keys built earlier.
- * If the cert matches one on the list, then save it.
+ * structure to collect key handles.
*/
+typedef struct pk11KeyDataStr {
+ PK11Slot *slot;
+ PK11SearchResults *searchHandles;
+ SECItem *id;
+ CK_ATTRIBUTE *template;
+ CK_ULONG templ_count;
+ unsigned long classFlags;
+ PRBool isLoggedIn;
+ PRBool strict;
+} pk11KeyData;
+
+
static SECStatus
-add_cert_to_list(CERTCertificate *cert, SECItem *k, void *pdata)
+pk11_key_collect(DBT *key, DBT *data, void *arg)
{
- keyList *keylist;
- pk11keyNode *node;
- SECKEYPublicKey *pubKey = NULL;
- SECItem *pubItem;
- CERTCertificate *oldcert;
-
- keylist = (keyList *)pdata;
+ pk11KeyData *keyData;
+ NSSLOWKEYPrivateKey *privKey = NULL;
+ SECItem tmpDBKey;
+ PK11Slot *slot;
- /* only if it is a user cert and has a nickname!! */
- if ( ( ( cert->trust->sslFlags & CERTDB_USER ) ||
- ( cert->trust->emailFlags & CERTDB_USER ) ||
- ( cert->trust->objectSigningFlags & CERTDB_USER ) ) &&
- ( cert->nickname != NULL ) ) {
-
- /* get cert's public key */
- pubKey = CERT_ExtractPublicKey(cert);
- if ( pubKey == NULL ) {
- goto done;
- }
-
- /* pk11_GetPubItem returns data associated with the public key.
- * one only needs to free the public key. This comment is here
- * because this sematic would be non-obvious otherwise.
- */
- pubItem = pk11_GetPubItem(pubKey);
- if (pubItem == NULL) goto done;
-
- node = keylist->head;
- while ( node ) {
- /* if key type is different, then there is no match */
- if (node->privKey->keyType == seckeyLow_KeyType(pubKey->keyType)) {
-
- /* compare public value from cert with public value from
- * the key
- */
- if ( SECITEM_CompareItem(pubItem, node->pubItem) == SECEqual ){
- /* this is a match */
-
- /* if no cert has yet been found for this key, or this
- * cert is newer, then save this cert
- */
- if ( ( node->cert == NULL ) ||
- CERT_IsNewer(cert, node->cert ) ) {
-
- oldcert = node->cert;
-
- /* get a real DB copy of the cert, since the one
- * passed in here is not properly recorded in the
- * temp database
- */
-
- /* We need a better way to deal with this */
- node->cert =
- CERT_FindCertByKeyNoLocking(CERT_GetDefaultCertDB(),
- &cert->certKey);
-
- /* free the old cert if there was one */
- if ( oldcert ) {
- CERT_DestroyCertificate(oldcert);
- }
- }
- }
+ keyData = (pk11KeyData *)arg;
+ slot = keyData->slot;
+
+ tmpDBKey.data = key->data;
+ tmpDBKey.len = key->size;
+
+ PORT_Assert(slot->keyDB);
+ if (!keyData->strict && keyData->id) {
+ SECItem result;
+ unsigned char hashKey[SHA1_LENGTH];
+ result.data = hashKey;
+ result.len = sizeof(hashKey);
+
+ SHA1_HashBuf( hashKey, key->data, key->size );
+ if (SECITEM_ItemsAreEqual(keyData->id,&result)) {
+ if (keyData->classFlags & NSC_PRIVATE) {
+ pk11_addHandle(keyData->searchHandles,
+ pk11_mkHandle(slot,&tmpDBKey,PK11_TOKEN_TYPE_PRIV));
}
-
- node = node->next;
+ if (keyData->classFlags & NSC_PUBLIC) {
+ pk11_addHandle(keyData->searchHandles,
+ pk11_mkHandle(slot,&tmpDBKey,PK11_TOKEN_TYPE_PUB));
+ }
+ /* NSC_KEY Already handled */
}
+ return SECSuccess;
}
-done:
- if ( pubKey ) {
- SECKEY_DestroyPublicKey(pubKey);
+
+ privKey = nsslowkey_FindKeyByPublicKey(keyData->slot->keyDB, &tmpDBKey,
+ keyData->slot->password);
+ if ( privKey == NULL ) {
+ goto loser;
+ }
+
+ if (isSecretKey(privKey)) {
+ if ((keyData->classFlags & NSC_KEY) &&
+ pk11_tokenMatch(keyData->slot, &tmpDBKey, PK11_TOKEN_TYPE_KEY,
+ keyData->template, keyData->templ_count)) {
+ pk11_addHandle(keyData->searchHandles,
+ pk11_mkHandle(keyData->slot, &tmpDBKey, PK11_TOKEN_TYPE_KEY));
+ }
+ } else {
+ if ((keyData->classFlags & NSC_PRIVATE) &&
+ pk11_tokenMatch(keyData->slot, &tmpDBKey, PK11_TOKEN_TYPE_PRIV,
+ keyData->template, keyData->templ_count)) {
+ pk11_addHandle(keyData->searchHandles,
+ pk11_mkHandle(keyData->slot,&tmpDBKey,PK11_TOKEN_TYPE_PRIV));
+ }
+ if ((keyData->classFlags & NSC_PUBLIC) &&
+ pk11_tokenMatch(keyData->slot, &tmpDBKey, PK11_TOKEN_TYPE_PUB,
+ keyData->template, keyData->templ_count)) {
+ pk11_addHandle(keyData->searchHandles,
+ pk11_mkHandle(keyData->slot, &tmpDBKey,PK11_TOKEN_TYPE_PUB));
+ }
}
+loser:
+ if ( privKey ) {
+ nsslowkey_DestroyPrivateKey(privKey);
+ }
return(SECSuccess);
}
-#if 0
-/* This appears to be obsolete - TNH */
-static SECItem *
-decodeKeyDBGlobalSalt(DBT *saltData)
+static void
+pk11_searchKeys(PK11Slot *slot, SECItem *key_id, PRBool isLoggedIn,
+ unsigned long classFlags, PK11SearchResults *search,
+ CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount)
{
- SECItem *saltitem;
-
- saltitem = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if ( saltitem == NULL ) {
- return(NULL);
+ NSSLOWKEYDBHandle *keyHandle = NULL;
+ NSSLOWKEYPrivateKey *privKey;
+ pk11KeyData keyData;
+
+ keyHandle = slot->keyDB;
+ if (keyHandle == NULL) {
+ return;
}
-
- saltitem->data = (unsigned char *)PORT_ZAlloc(saltData->size);
- if ( saltitem->data == NULL ) {
- PORT_Free(saltitem);
- return(NULL);
+
+ if (key_id->data && (classFlags & NSC_KEY)) {
+ privKey = nsslowkey_FindKeyByPublicKey(keyHandle,key_id, slot->password);
+ if (privKey) {
+ pk11_addHandle(search,pk11_mkHandle(slot,key_id,PK11_TOKEN_TYPE_KEY));
+ nsslowkey_DestroyPrivateKey(privKey);
+ }
+ if ( !(classFlags & (NSC_PRIVATE|NSC_PUBLIC)) ) {
+ /* skip the traverse, nothing new to find */
+ return;
+ }
}
-
- saltitem->len = saltData->size;
- PORT_Memcpy(saltitem->data, saltData->data, saltitem->len);
-
- return(saltitem);
+ keyData.slot = slot;
+ keyData.searchHandles = search;
+ keyData.id = key_id;
+ keyData.template = pTemplate;
+ keyData.templ_count = ulCount;
+ keyData.isLoggedIn = isLoggedIn;
+ keyData.classFlags = classFlags;
+ keyData.strict = NSC_STRICT;
+
+ nsslowkey_TraverseKeys(keyHandle, pk11_key_collect, &keyData);
}
-#endif
-#if 0
/*
- * Create a (fixed) DES3 key [ testing ]
+ * structure to collect certs into
*/
-static unsigned char keyValue[] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17
-};
-
-static SECItem keyItem = {
- 0,
- keyValue,
- sizeof keyValue
-};
-
-static unsigned char keyID[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
+typedef struct pk11CertDataStr {
+ PK11Slot *slot;
+ int cert_count;
+ int max_cert_count;
+ NSSLOWCERTCertificate **certs;
+ CK_ATTRIBUTE *template;
+ CK_ULONG templ_count;
+ unsigned long classFlags;
+ PRBool strict;
+} pk11CertData;
-static SECItem keyIDItem = {
- 0,
- keyID,
- sizeof keyID
-};
-/* +AAA */
-static CK_RV
-pk11_createFixedDES3Key(PK11Slot *slot)
+/*
+ * collect all the certs from the traverse call.
+ */
+static SECStatus
+pk11_cert_collect(NSSLOWCERTCertificate *cert,void *arg)
{
- CK_RV rv = CKR_OK;
- PK11Object *keyObject;
- CK_BBOOL true = CK_TRUE;
- CK_OBJECT_CLASS class = CKO_SECRET_KEY;
- CK_KEY_TYPE keyType = CKK_DES3;
+ pk11CertData *cd = (pk11CertData *)arg;
- /*
- * Create the object
- */
- keyObject = pk11_NewObject(slot); /* fill in the handle later */
- if (keyObject == NULL) {
- return CKR_HOST_MEMORY;
+ if (cd->certs == NULL) {
+ return SECFailure;
}
- /* Add attributes to the object */
- rv = pk11_AddAttributeType(keyObject, CKA_ID, keyID, sizeof keyID);
- if (rv != CKR_OK) {
- pk11_FreeObject(keyObject);
- return rv;
+ if (cd->strict) {
+ if ((cd->classFlags & NSC_CERT) && !pk11_tokenMatch(cd->slot,
+ &cert->certKey, PK11_TOKEN_TYPE_CERT, cd->template,cd->templ_count)) {
+ return SECSuccess;
+ }
+ if ((cd->classFlags & NSC_TRUST) && !pk11_tokenMatch(cd->slot,
+ &cert->certKey, PK11_TOKEN_TYPE_TRUST,
+ cd->template, cd->templ_count)) {
+ return SECSuccess;
+ }
}
- rv = pk11_AddAttributeType(keyObject, CKA_VALUE, keyValue, sizeof keyValue);
- if (rv != CKR_OK) {
- pk11_FreeObject(keyObject);
- return rv;
+ /* allocate more space if we need it. This should only happen in
+ * the general traversal case */
+ if (cd->cert_count >= cd->max_cert_count) {
+ int size;
+ cd->max_cert_count += NSC_CERT_BLOCK_SIZE;
+ size = cd->max_cert_count * sizeof (NSSLOWCERTCertificate *);
+ cd->certs = (NSSLOWCERTCertificate **)PORT_Realloc(cd->certs,size);
+ if (cd->certs == NULL) {
+ return SECFailure;
+ }
}
- rv = pk11_AddAttributeType(keyObject, CKA_TOKEN, &true, sizeof true);
- if (rv != CKR_OK) {
- pk11_FreeObject(keyObject);
- return rv;
- }
+ cd->certs[cd->cert_count++] = nsslowcert_DupCertificate(cert);
+ return SECSuccess;
+}
- rv = pk11_AddAttributeType(keyObject, CKA_CLASS, &class, sizeof class);
- if (rv != CKR_OK) {
- pk11_FreeObject(keyObject);
- return rv;
- }
+/* provide impedence matching ... */
+static SECStatus
+pk11_cert_collect2(NSSLOWCERTCertificate *cert, SECItem *dymmy, void *arg)
+{
+ return pk11_cert_collect(cert, arg);
+}
- rv = pk11_AddAttributeType(keyObject, CKA_KEY_TYPE, &keyType, sizeof keyType);
- if (rv != CKR_OK) {
- pk11_FreeObject(keyObject);
- return rv;
+static void
+pk11_searchSingleCert(pk11CertData *certData,NSSLOWCERTCertificate *cert)
+{
+ if (cert == NULL) {
+ return;
}
+ if (certData->strict &&
+ !pk11_tokenMatch(certData->slot, &cert->certKey, PK11_TOKEN_TYPE_CERT,
+ certData->template,certData->templ_count)) {
+ nsslowcert_DestroyCertificate(cert);
+ return;
+ }
+ certData->certs = (NSSLOWCERTCertificate **)
+ PORT_Alloc(sizeof (NSSLOWCERTCertificate *));
+ if (certData->certs == NULL) {
+ nsslowcert_DestroyCertificate(cert);
+ return;
+ }
+ certData->certs[0] = cert;
+ certData->cert_count = 1;
+}
- pk11_handleSecretKeyObject(keyObject, keyType, PR_TRUE);
-
- PK11_USE_THREADS(PZ_Lock(slot->objectLock);)
- keyObject->handle = slot->tokenIDCount++;
- PK11_USE_THREADS(PZ_Unlock(slot->objectLock);)
- keyObject->slot = slot;
- keyObject->objclass = CKO_SECRET_KEY;
- pk11_AddSlotObject(slot, keyObject);
+static void
+pk11_CertSetupData(pk11CertData *certData,int count)
+{
+ certData->max_cert_count = count;
- return rv;
+ if (certData->max_cert_count <= 0) {
+ return;
+ }
+ certData->certs = (NSSLOWCERTCertificate **)
+ PORT_Alloc( count * sizeof(NSSLOWCERTCertificate *));
+ return;
}
-#endif /* Fixed DES key */
-/*
- * load up our token database
- */
-static CK_RV
-pk11_importKeyDB(PK11Slot *slot)
+static void
+pk11_searchCertsAndTrust(PK11Slot *slot, SECItem *derCert, SECItem *name,
+ SECItem *derSubject, NSSLOWCERTIssuerAndSN *issuerSN,
+ unsigned long classFlags, PK11SearchResults *handles,
+ CK_ATTRIBUTE *pTemplate, CK_LONG ulCount)
{
- keyList keylist;
- pk11keyNode *node;
- CK_RV crv;
- SECStatus rv;
- PK11Object *privateKeyObject;
- PK11Object *publicKeyObject;
- PK11Object *certObject;
+ NSSLOWCERTCertDBHandle *certHandle = NULL;
+ pk11CertData certData;
+ int i;
- /* traverse the database, collecting the index keys of all
- * records into a linked list
- */
- keylist.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( keylist.arena == NULL ) {
- return CKR_HOST_MEMORY;
- }
- keylist.head = NULL;
- keylist.slot = slot;
-
- /* collect all of the keys */
- rv = SECKEY_TraverseKeys(SECKEY_GetDefaultKeyDB(),
- add_key_to_list, (void *)&keylist);
- if (rv != SECSuccess) {
- PORT_FreeArena(keylist.arena, PR_FALSE);
- return CKR_HOST_MEMORY;
- }
+ certHandle = slot->certDB;
+ if (certHandle == NULL) return;
- /* find certs that match any of the keys */
- crv = SEC_TraversePermCerts(CERT_GetDefaultCertDB(),
- add_cert_to_list, (void *)&keylist);
- if ( crv != SECSuccess ) {
- PORT_FreeArena(keylist.arena, PR_FALSE);
- return CKR_HOST_MEMORY;
- }
+ certData.slot = slot;
+ certData.max_cert_count = 0;
+ certData.certs = NULL;
+ certData.cert_count = 0;
+ certData.template = pTemplate;
+ certData.templ_count = ulCount;
+ certData.classFlags = classFlags;
+ certData.strict = NSC_STRICT;
- /* now traverse the list and entry certs/keys into the
- * pkcs11 world
+
+ /*
+ * Find the Cert.
*/
- for (node = keylist.head; node != NULL; node=node->next ) {
- /* Check for "special" private key that wraps a symmetric key */
- if (isSecretKey(node->privKey)) {
- importSecretKey(slot, node->privKey);
- goto end_loop;
- }
-
- /* create the private key object */
- privateKeyObject = pk11_importPrivateKey(slot, node->privKey,
- node->pubItem);
- if ( privateKeyObject == NULL ) {
- goto end_loop;
- }
+ if (derCert->data != NULL) {
+ NSSLOWCERTCertificate *cert =
+ nsslowcert_FindCertByDERCert(certHandle,derCert);
+ pk11_searchSingleCert(&certData,cert);
+ } else if (name->data != NULL) {
+ char *tmp_name = (char*)PORT_Alloc(name->len+1);
+ int count;
- publicKeyObject = pk11_importPublicKey(slot, node->privKey, NULL,
- node->pubItem);
- if ( node->cert ) {
- /* Now import the Cert */
- certObject = pk11_importCertificate(slot, node->cert,
- node->pubItem->data,
- node->pubItem->len, PR_TRUE);
-
- /* Copy the subject */
- if ( certObject ) {
- /* NOTE: cert has been adopted */
- PK11Attribute *attribute;
-
- /* Copy the Subject */
- attribute = pk11_FindAttribute(certObject,CKA_SUBJECT);
- if (attribute) {
- pk11_forceAttribute(privateKeyObject,
- pk11_attr_expand(&attribute->attrib));
- if (publicKeyObject) {
- pk11_forceAttribute(publicKeyObject,
- pk11_attr_expand(&attribute->attrib));
- }
- pk11_FreeAttribute(attribute);
- }
- pk11_FreeObject(certObject);
- }
+ if (tmp_name == NULL) {
+ return;
}
+ PORT_Memcpy(tmp_name,name->data,name->len);
+ tmp_name[name->len] = 0;
- if ( publicKeyObject != NULL ) {
- pk11_AddSlotObject(slot, publicKeyObject);
- }
+ count= nsslowcert_NumPermCertsForNickname(certHandle,tmp_name);
+ pk11_CertSetupData(&certData,count);
+ nsslowcert_TraversePermCertsForNickname(certHandle,tmp_name,
+ pk11_cert_collect, &certData);
+ PORT_Free(tmp_name);
+ } else if (derSubject->data != NULL) {
+ int count;
+
+ count = nsslowcert_NumPermCertsForSubject(certHandle,derSubject);
+ pk11_CertSetupData(&certData,count);
+ nsslowcert_TraversePermCertsForSubject(certHandle,derSubject,
+ pk11_cert_collect, &certData);
+ } else if ((issuerSN->derIssuer.data != NULL) &&
+ (issuerSN->serialNumber.data != NULL)) {
+ NSSLOWCERTCertificate *cert =
+ nsslowcert_FindCertByIssuerAndSN(certHandle,issuerSN);
+
+ pk11_searchSingleCert(&certData,cert);
+ } else {
+ /* we aren't filtering the certs, we are working on all, so turn
+ * on the strict filters. */
+ certData.strict = PR_TRUE;
+ pk11_CertSetupData(&certData,NSC_CERT_BLOCK_SIZE);
+ nsslowcert_TraversePermCerts(certHandle, pk11_cert_collect2, &certData);
+ }
- pk11_AddSlotObject(slot, privateKeyObject);
+ /*
+ * build the handles
+ */
+ for (i=0 ; i < certData.cert_count ; i++) {
+ NSSLOWCERTCertificate *cert = certData.certs[i];
-end_loop:
- SECKEY_LowDestroyPrivateKey(node->privKey);
- if ( node->cert ) {
- CERT_DestroyCertificate(node->cert);
+ /* if we filtered it would have been on the stuff above */
+ if (classFlags & NSC_CERT) {
+ pk11_addHandle(handles,
+ pk11_mkHandle(slot,&cert->certKey,PK11_TOKEN_TYPE_CERT));
}
-
+ if ((classFlags & NSC_TRUST) && nsslowcert_hasTrust(cert)) {
+ pk11_addHandle(handles,
+ pk11_mkHandle(slot,&cert->certKey,PK11_TOKEN_TYPE_TRUST));
+ }
+ nsslowcert_DestroyCertificate(cert);
}
- PORT_FreeArena(keylist.arena, PR_FALSE);
- return CKR_OK;
+ if (certData.certs) PORT_Free(certData.certs);
+ return;
}
-/*
- * structure to collect certs into
- */
-typedef struct pk11CertDataStr {
- int cert_count;
- int max_cert_count;
- CERTCertificate **certs;
-} pk11CertData;
+static void
+pk11_searchSMime(PK11Slot *slot, SECItem *email, PK11SearchResults *handles,
+ CK_ATTRIBUTE *pTemplate, CK_LONG ulCount)
+{
+ NSSLOWCERTCertDBHandle *certHandle = NULL;
+ certDBEntrySMime *entry;
-/*
- * collect all the certs from the traverse call.
- */
-static SECStatus
-pk11_cert_collect(CERTCertificate *cert,void *arg) {
- pk11CertData *cd = (pk11CertData *)arg;
+ certHandle = slot->certDB;
+ if (certHandle == NULL) return;
- /* shouldn't happen, but don't crash if it does */
- if (cd->cert_count >= cd->max_cert_count) {
- PORT_Assert(0);
- return SECFailure;
- }
+ if (email->data != NULL) {
+ char *tmp_name = (char*)PORT_Alloc(email->len+1);
- cd->certs[cd->cert_count++] = CERT_DupCertificate(cert);
- return SECSuccess;
+ if (tmp_name == NULL) {
+ return;
+ }
+ PORT_Memcpy(tmp_name,email->data,email->len);
+ tmp_name[email->len] = 0;
+
+ entry = nsslowcert_ReadDBSMimeEntry(certHandle,tmp_name);
+ if (entry) {
+ SECItem emailKey;
+
+ emailKey.data = (unsigned char *)tmp_name;
+ emailKey.len = PORT_Strlen(tmp_name)+1;
+ pk11_addHandle(handles,
+ pk11_mkHandle(slot,&emailKey,PK11_TOKEN_TYPE_SMIME));
+ nsslowcert_DestroyDBEntry((certDBEntry *)entry);
+ }
+ PORT_Free(tmp_name);
+ }
+ return;
}
-/*
- * find any certs that may match the template and load them.
- */
-static void
-pk11_searchCerts(PK11Slot *slot, CK_ATTRIBUTE *pTemplate, CK_LONG ulCount) {
+
+static CK_RV
+pk11_searchTokenList(PK11Slot *slot, PK11SearchResults *search,
+ CK_ATTRIBUTE *pTemplate, CK_LONG ulCount,
+ PRBool *tokenOnly, PRBool isLoggedIn)
+{
int i;
+ PRBool isKrl = PR_FALSE;
SECItem derCert = { siBuffer, NULL, 0 };
SECItem derSubject = { siBuffer, NULL, 0 };
SECItem name = { siBuffer, NULL, 0 };
- CERTIssuerAndSN issuerSN = {
+ SECItem email = { siBuffer, NULL, 0 };
+ SECItem key_id = { siBuffer, NULL, 0 };
+ SECItem cert_sha1_hash = { siBuffer, NULL, 0 };
+ SECItem cert_md5_hash = { siBuffer, NULL, 0 };
+ NSSLOWCERTIssuerAndSN issuerSN = {
{ siBuffer, NULL, 0 },
- { NULL, NULL },
{ siBuffer, NULL, 0 }
};
SECItem *copy = NULL;
- CERTCertDBHandle *handle = NULL;
- SECKEYKeyDBHandle *keyHandle = NULL;
- pk11CertData certData;
+ unsigned long classFlags =
+ NSC_CERT|NSC_TRUST|NSC_PRIVATE|NSC_PUBLIC|NSC_KEY|NSC_SMIME ;
+ /* if we aren't logged in, don't look for private or secret keys */
+ if (!isLoggedIn) {
+ classFlags &= ~(NSC_PRIVATE|NSC_KEY);
+ }
/*
- * These should be stored in the slot some day in the future
- */
- handle = CERT_GetDefaultCertDB();
- if (handle == NULL) return;
- keyHandle = SECKEY_GetDefaultKeyDB();
- if (keyHandle == NULL) return;
-
- /*
- * look for things to search on certs for. We only need one of these
- * items. If we find all the certs that match that item, import them
- * (as long as they are user certs). We'll let find objects filter out
- * the ones that don't apply.
+ * look for things to search on token objects for. If the right options
+ * are specified, we can use them as direct indeces into the database
+ * (rather than using linear searches. We can also use the attributes to
+ * limit the kinds of objects we are searching for. Later we can use this
+ * array to filter the remaining objects more finely.
*/
- for (i=0 ;i < (int)ulCount; i++) {
+ for (i=0 ;classFlags && i < (int)ulCount; i++) {
switch (pTemplate[i].type) {
- case CKA_SUBJECT: copy = &derSubject; break;
- case CKA_ISSUER: copy = &issuerSN.derIssuer; break;
- case CKA_SERIAL_NUMBER: copy = &issuerSN.serialNumber; break;
- case CKA_VALUE: copy = &derCert; break;
- case CKA_LABEL: copy = &name; break;
+ case CKA_SUBJECT:
+ copy = &derSubject;
+ classFlags &= (NSC_CERT|NSC_PRIVATE|NSC_PUBLIC|NSC_SMIME);
+ break;
+ case CKA_ISSUER:
+ copy = &issuerSN.derIssuer;
+ classFlags &= (NSC_CERT|NSC_CRL|NSC_TRUST);
+ break;
+ case CKA_SERIAL_NUMBER:
+ copy = &issuerSN.serialNumber;
+ classFlags &= (NSC_CERT|NSC_TRUST);
+ break;
+ case CKA_VALUE:
+ copy = &derCert;
+ classFlags &= (NSC_CERT|NSC_CRL|NSC_SMIME);
+ break;
+ case CKA_LABEL:
+ copy = &name;
+ break;
+ case CKA_NETSCAPE_EMAIL:
+ copy = &email;
+ classFlags &= NSC_SMIME;
+ break;
+ case CKA_NETSCAPE_SMIME_TIMESTAMP:
+ classFlags &= NSC_SMIME;
+ break;
case CKA_CLASS:
if (pTemplate[i].ulValueLen != sizeof(CK_OBJECT_CLASS)) {
- return;
+ classFlags = 0;
+ break;;
}
- if (*((CK_OBJECT_CLASS *)pTemplate[i].pValue) != CKO_CERTIFICATE) {
- return;
+ switch (*((CK_OBJECT_CLASS *)pTemplate[i].pValue)) {
+ case CKO_CERTIFICATE:
+ classFlags &= NSC_CERT;
+ break;
+ case CKO_NETSCAPE_TRUST:
+ classFlags &= NSC_TRUST;
+ break;
+ case CKO_NETSCAPE_CRL:
+ classFlags &= NSC_CRL;
+ break;
+ case CKO_NETSCAPE_SMIME:
+ classFlags &= NSC_SMIME;
+ break;
+ case CKO_PRIVATE_KEY:
+ classFlags &= NSC_PRIVATE;
+ break;
+ case CKO_PUBLIC_KEY:
+ classFlags &= NSC_PUBLIC;
+ break;
+ case CKO_SECRET_KEY:
+ classFlags &= NSC_KEY;
+ break;
+ default:
+ classFlags = 0;
+ break;
}
- copy = NULL; break;
+ break;
case CKA_PRIVATE:
if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) {
- return;
+ classFlags = 0;
+ }
+ if (*((CK_BBOOL *)pTemplate[i].pValue) == CK_TRUE) {
+ classFlags &= (NSC_PRIVATE|NSC_KEY);
+ } else {
+ classFlags &= ~(NSC_PRIVATE|NSC_KEY);
+ }
+ break;
+ case CKA_SENSITIVE:
+ if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) {
+ classFlags = 0;
}
- if (*((CK_BBOOL *)pTemplate[i].pValue) != CK_FALSE) {
- return;
+ if (*((CK_BBOOL *)pTemplate[i].pValue) == CK_TRUE) {
+ classFlags &= (NSC_PRIVATE|NSC_KEY);
+ } else {
+ classFlags = 0;
}
- copy = NULL; break;
+ break;
case CKA_TOKEN:
if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) {
- return;
+ classFlags = 0;
}
- if (*((CK_BBOOL *)pTemplate[i].pValue) != CK_TRUE) {
- return;
+ if (*((CK_BBOOL *)pTemplate[i].pValue) == CK_TRUE) {
+ *tokenOnly = PR_TRUE;
+ } else {
+ classFlags = 0;
}
- copy = NULL; break;
+ break;
+ case CKA_CERT_SHA1_HASH:
+ classFlags &= NSC_TRUST;
+ copy = &cert_sha1_hash; break;
+ case CKA_CERT_MD5_HASH:
+ classFlags &= NSC_TRUST;
+ copy = &cert_md5_hash; break;
case CKA_CERTIFICATE_TYPE:
+ if (pTemplate[i].ulValueLen != sizeof(CK_CERTIFICATE_TYPE)) {
+ classFlags = 0;
+ }
+ classFlags &= NSC_CERT;
+ if (*((CK_CERTIFICATE_TYPE *)pTemplate[i].pValue) != CKC_X_509) {
+ classFlags = 0;
+ }
+ break;
case CKA_ID:
+ copy = &key_id;
+ classFlags &= (NSC_CERT|NSC_PRIVATE|NSC_KEY|NSC_PUBLIC);
+ break;
+ case CKA_NETSCAPE_KRL:
+ if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) {
+ classFlags = 0;
+ }
+ classFlags &= NSC_CRL;
+ isKrl = (PRBool)(*((CK_BBOOL *)pTemplate[i].pValue) == CK_TRUE);
+ break;
case CKA_MODIFIABLE:
- copy = NULL; break;
+ break;
+ case CKA_KEY_TYPE:
+ case CKA_DERIVE:
+ classFlags &= NSC_PUBLIC|NSC_PRIVATE|NSC_KEY;
+ break;
+ case CKA_VERIFY_RECOVER:
+ classFlags &= NSC_PUBLIC;
+ break;
+ case CKA_SIGN_RECOVER:
+ classFlags &= NSC_PRIVATE;
+ break;
+ case CKA_ENCRYPT:
+ case CKA_VERIFY:
+ case CKA_WRAP:
+ classFlags &= NSC_PUBLIC|NSC_KEY;
+ break;
+ case CKA_DECRYPT:
+ case CKA_SIGN:
+ case CKA_UNWRAP:
+ case CKA_ALWAYS_SENSITIVE:
+ case CKA_EXTRACTABLE:
+ case CKA_NEVER_EXTRACTABLE:
+ classFlags &= NSC_PRIVATE|NSC_KEY;
+ break;
/* can't be a certificate if it doesn't match one of the above
* attributes */
- default: return;
+ default:
+ classFlags = 0;
+ break;
}
if (copy) {
copy->data = (unsigned char*)pTemplate[i].pValue;
copy->len = pTemplate[i].ulValueLen;
}
+ copy = NULL;
}
- certData.max_cert_count = 0;
- certData.certs = NULL;
- certData.cert_count = 0;
-
- if (derCert.data != NULL) {
- CERTCertificate *cert = CERT_FindCertByDERCert(handle,&derCert);
- if (cert != NULL) {
- certData.certs =
- (CERTCertificate **) PORT_Alloc(sizeof (CERTCertificate *));
- if (certData.certs) {
- certData.certs[0] = cert;
- certData.cert_count = 1;
- } else CERT_DestroyCertificate(cert);
- }
- } else if (name.data != NULL) {
- char *tmp_name = (char*)PORT_Alloc(name.len+1);
-
- if (tmp_name == NULL) {
- return;
- }
- PORT_Memcpy(tmp_name,name.data,name.len);
- tmp_name[name.len] = 0;
-
- certData.max_cert_count=CERT_NumPermCertsForNickname(handle,tmp_name);
- if (certData.max_cert_count > 0) {
- certData.certs = (CERTCertificate **)
- PORT_Alloc(certData.max_cert_count *sizeof(CERTCertificate *));
- if (certData.certs) {
- CERT_TraversePermCertsForNickname(handle,tmp_name,
- pk11_cert_collect, &certData);
- }
-
- }
- PORT_Free(tmp_name);
- } else if (derSubject.data != NULL) {
- certData.max_cert_count=CERT_NumPermCertsForSubject(handle,&derSubject);
- if (certData.max_cert_count > 0) {
- certData.certs = (CERTCertificate **)
- PORT_Alloc(certData.max_cert_count *sizeof(CERTCertificate *));
- if (certData.certs) {
- CERT_TraversePermCertsForSubject(handle,&derSubject,
- pk11_cert_collect, &certData);
- }
- }
- } else if ((issuerSN.derIssuer.data != NULL) &&
- (issuerSN.serialNumber.data != NULL)) {
- CERTCertificate *cert = CERT_FindCertByIssuerAndSN(handle,&issuerSN);
-
- if (cert != NULL) {
- certData.certs =
- (CERTCertificate **) PORT_Alloc(sizeof (CERTCertificate *));
- if (certData.certs) {
- certData.certs[0] = cert;
- certData.cert_count = 1;
- } else CERT_DestroyCertificate(cert);
- }
- } else {
- /* PORT_Assert(0); may get called when not looking for certs */
- /* look up all the certs sometime, and get rid of the assert */;
+ /* certs */
+ if (classFlags & (NSC_CERT|NSC_TRUST)) {
+ pk11_searchCertsAndTrust(slot,&derCert,&name,&derSubject,
+ &issuerSN,classFlags,search,
+ pTemplate, ulCount);
}
+ /* keys */
+ if (classFlags & (NSC_PRIVATE|NSC_PUBLIC|NSC_KEY)) {
+ pk11_searchKeys(slot, &key_id, isLoggedIn, classFlags, search,
+ pTemplate, ulCount);
+ }
- for (i=0 ; i < certData.cert_count ; i++) {
- CERTCertificate *cert = certData.certs[i];
-
- /* we are only interested in permanment user certs here */
- if ((cert->isperm) && (cert->trust) &&
- (( cert->trust->sslFlags & CERTDB_USER ) ||
- ( cert->trust->emailFlags & CERTDB_USER ) ||
- ( cert->trust->objectSigningFlags & CERTDB_USER )) &&
- ( cert->nickname != NULL ) &&
- (SECKEY_KeyForCertExists(keyHandle, cert) == SECSuccess)) {
- PK11Object *obj;
- pk11_importCertificate(slot, cert, NULL, 0, PR_FALSE);
- obj = pk11_importPublicKey(slot, NULL, cert, NULL);
- if (obj) pk11_AddSlotObject(slot, obj);
- }
- CERT_DestroyCertificate(cert);
+ /* crl's */
+ if (classFlags & NSC_CRL) {
+ pk11_searchCrls(slot, &derSubject, isKrl, classFlags, search,
+ pTemplate, ulCount);
+ }
+ /* Add S/MIME entry stuff */
+ if (classFlags & NSC_SMIME) {
+ pk11_searchSMime(slot, &email, search, pTemplate, ulCount);
}
- if (certData.certs) PORT_Free(certData.certs);
- return;
+ return CKR_OK;
}
@@ -4067,74 +3719,50 @@ pk11_searchCerts(PK11Slot *slot, CK_ATTRIBUTE *pTemplate, CK_LONG ulCount) {
CK_RV NSC_FindObjectsInit(CK_SESSION_HANDLE hSession,
CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)
{
- PK11ObjectListElement *objectList = NULL;
- PK11ObjectListElement *olp;
PK11SearchResults *search,*freeSearch;
- PK11Session *session;
+ PK11Session *session = NULL;
PK11Slot *slot = pk11_SlotFromSessionHandle(hSession);
- int count, i;
- CK_RV crv;
+ PRBool tokenOnly = PR_FALSE;
+ CK_RV crv = CKR_OK;
+ PRBool isLoggedIn;
session = pk11_SessionFromHandle(hSession);
if (session == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
-
- /* resync token objects with the data base */
- if ((session->info.slotID == PRIVATE_KEY_SLOT_ID) ||
- (session->info.slotID == FIPS_SLOT_ID)) {
- if (slot->DB_loaded == PR_FALSE) {
- /* if we aren't logged in, we can't unload all key keys
- * and certs. Just unload those certs we need for this search
- */
- if ((!slot->isLoggedIn) && (slot->needLogin)) {
- pk11_searchCerts(slot,pTemplate,ulCount);
- } else {
- pk11_importKeyDB(slot);
- slot->DB_loaded = PR_TRUE;
- }
- }
- }
-
-
- /* build list of found objects in the session */
- crv = pk11_searchObjectList(&objectList,slot->tokObjects,
- slot->objectLock, pTemplate, ulCount, (PRBool)((!slot->needLogin) ||
- slot->isLoggedIn));
- if (crv != CKR_OK) {
- pk11_FreeObjectList(objectList);
- pk11_FreeSession(session);
- return crv;
- }
-
-
- /* copy list to session */
- count = 0;
- for (olp = objectList; olp != NULL; olp = olp->next) {
- count++;
+ crv = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
}
+
search = (PK11SearchResults *)PORT_Alloc(sizeof(PK11SearchResults));
if (search == NULL) {
- pk11_FreeObjectList(objectList);
- pk11_FreeSession(session);
- return CKR_HOST_MEMORY;
+ crv = CKR_HOST_MEMORY;
+ goto loser;
}
search->handles = (CK_OBJECT_HANDLE *)
- PORT_Alloc(sizeof(CK_OBJECT_HANDLE) * count);
+ PORT_Alloc(sizeof(CK_OBJECT_HANDLE) * NSC_SEARCH_BLOCK_SIZE);
if (search->handles == NULL) {
- PORT_Free(search);
- pk11_FreeObjectList(objectList);
- pk11_FreeSession(session);
- return CKR_HOST_MEMORY;
+ crv = CKR_HOST_MEMORY;
+ goto loser;
}
- for (i=0; i < count; i++) {
- search->handles[i] = objectList->object->handle;
- objectList = pk11_FreeObjectListElement(objectList);
+ search->index = 0;
+ search->size = 0;
+ search->array_size = NSC_SEARCH_BLOCK_SIZE;
+ isLoggedIn = (PRBool)((!slot->needLogin) || slot->isLoggedIn);
+
+ crv = pk11_searchTokenList(slot, search, pTemplate, ulCount, &tokenOnly,
+ isLoggedIn);
+ if (crv != CKR_OK) {
+ goto loser;
+ }
+
+ /* build list of found objects in the session */
+ if (!tokenOnly) {
+ crv = pk11_searchObjectList(search, slot->tokObjects,
+ slot->objectLock, pTemplate, ulCount, isLoggedIn);
+ }
+ if (crv != CKR_OK) {
+ goto loser;
}
- /* store the search info */
- search->index = 0;
- search->size = count;
if ((freeSearch = session->search) != NULL) {
session->search = NULL;
pk11_FreeSearch(freeSearch);
@@ -4142,6 +3770,15 @@ CK_RV NSC_FindObjectsInit(CK_SESSION_HANDLE hSession,
session->search = search;
pk11_FreeSession(session);
return CKR_OK;
+
+loser:
+ if (freeSearch) {
+ pk11_FreeSearch(freeSearch);
+ }
+ if (session) {
+ pk11_FreeSession(session);
+ }
+ return crv;
}
@@ -4166,8 +3803,13 @@ CK_RV NSC_FindObjects(CK_SESSION_HANDLE hSession,
search = session->search;
left = session->search->size - session->search->index;
transfer = ((int)ulMaxObjectCount > left) ? left : ulMaxObjectCount;
- PORT_Memcpy(phObject,&search->handles[search->index],
- transfer*sizeof(CK_OBJECT_HANDLE_PTR));
+ if (transfer > 0) {
+ PORT_Memcpy(phObject,&search->handles[search->index],
+ transfer*sizeof(CK_OBJECT_HANDLE_PTR));
+ } else {
+ *phObject = CK_INVALID_HANDLE;
+ }
+
search->index += transfer;
if (search->index == search->size) {
session->search = NULL;
diff --git a/security/nss/lib/softoken/pkcs11.h b/security/nss/lib/softoken/pkcs11.h
index 9ada2625e..9b54421e7 100644
--- a/security/nss/lib/softoken/pkcs11.h
+++ b/security/nss/lib/softoken/pkcs11.h
@@ -16,7 +16,7 @@
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
- * Contributor(s):
+ * Contributor(s): RSA Labs
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@@ -35,6 +35,9 @@
* is granted provided that it is identified as "RSA Security In.c Public-Key
* Cryptography Standards (PKCS)" in all material mentioning or referencing
* this document.
+ *
+ * The latest version of this header can be found at:
+ * http://www.rsalabs.com/pkcs/pkcs-11/index.html
*/
#ifndef _PKCS11_H_
#define _PKCS11_H_ 1
@@ -313,12 +316,4 @@ struct CK_FUNCTION_LIST {
}
#endif
-/*
-** Functions called directly by applications to configure the FIPS token.
-*/
-extern void PK11_ConfigurePKCS11(char *man, char *libdes, char *tokdes,
- char *ptokdes, char *slotdes, char *pslotdes, char *fslotdes,
- char *fpslotdes, int minPwd, int pwdRequired);
-extern void PK11_ConfigureFIPS(char *slotdes, char *pslotdes);
-
#endif
diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c
index 32eef81ca..cde08a599 100644
--- a/security/nss/lib/softoken/pkcs11c.c
+++ b/security/nss/lib/softoken/pkcs11c.c
@@ -53,20 +53,20 @@
#include "blapi.h"
#include "pkcs11.h"
#include "pkcs11i.h"
-#include "keylow.h"
-#include "cert.h"
+#include "lowkeyi.h"
+#include "pcert.h"
#include "sechash.h"
#include "secder.h"
#include "secdig.h"
-#include "secpkcs5.h" /* We do PBE below */
+#include "lowpbe.h" /* We do PBE below */
#include "pkcs11t.h"
#include "secoid.h"
#include "alghmac.h"
#include "softoken.h"
#include "secasn1.h"
-#include "secmodi.h"
+/*#include "secmodi.h" */
-#include "certdb.h"
+#include "pcert.h"
#include "ssl3prot.h" /* for SSL3_RANDOM_LENGTH */
#define __PASTE(x,y) x##y
@@ -102,9 +102,9 @@ static void pk11_Null(void *data, PRBool freeit)
* other free routines to the destroy signature.
*/
static void
-pk11_FreePrivKey(SECKEYLowPrivateKey *key, PRBool freeit)
+pk11_FreePrivKey(NSSLOWKEYPrivateKey *key, PRBool freeit)
{
- SECKEY_LowDestroyPrivateKey(key);
+ nsslowkey_DestroyPrivateKey(key);
}
static void
@@ -119,11 +119,6 @@ pk11_Space(void *data, PRBool freeit)
PORT_Free(data);
}
-static void pk11_FreeSignInfo(PK11HashSignInfo *data, PRBool freeit)
-{
- SECKEY_LowDestroyPrivateKey(data->key);
- PORT_Free(data);
-}
/*
* turn a CDMF key into a des key. CDMF is an old IBM scheme to export DES by
@@ -176,9 +171,9 @@ pk11_cdmf2des(unsigned char *cdmfkey, unsigned char *deskey)
static CK_RV
-pk11_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+pk11_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_TYPE etype,
- PK11ContextType contextType);
+ PK11ContextType contextType, PRBool isEncrypt);
/*
* Calculate a Lynx checksum for CKM_LYNX_WRAP mechanism.
*/
@@ -206,7 +201,8 @@ pk11_calcLynxChecksum(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hWrapKey,
/* encrypt with key 1 */
- crv = pk11_EncryptInit(hSession,&mech,hWrapKey,CKA_WRAP, PK11_ENCRYPT);
+ crv = pk11_CryptInit(hSession,&mech,hWrapKey,CKA_WRAP, PK11_ENCRYPT,
+ PR_TRUE);
if (crv != CKR_OK) return crv;
crv = NSC_Encrypt(hSession,key,len,E,&Elen);
@@ -215,7 +211,8 @@ pk11_calcLynxChecksum(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hWrapKey,
E[8] = (sum2 >> 8) & 0xff;
E[9] = sum2 & 0xff;
- crv = pk11_EncryptInit(hSession,&mech,hWrapKey,CKA_WRAP, PK11_ENCRYPT);
+ crv = pk11_CryptInit(hSession,&mech,hWrapKey,CKA_WRAP, PK11_ENCRYPT,
+ PR_TRUE);
if (crv != CKR_OK) return crv;
crv = NSC_Encrypt(hSession,&E[2],len,C,&Clen);
@@ -422,18 +419,19 @@ pk11_InitGeneric(PK11Session *session,PK11SessionContext **contextPtr,
context->hashInfo = NULL;
context->doPad = PR_FALSE;
context->padDataLength = 0;
+ context->key = key;
*contextPtr = context;
return CKR_OK;
}
-/* NSC_EncryptInit initializes an encryption operation. */
+/* NSC_CryptInit initializes an encryption/Decryption operation. */
/* This function is used by NSC_EncryptInit and NSC_WrapKey. The only difference
* in their uses if whether or not etype is CKA_ENCRYPT or CKA_WRAP */
static CK_RV
-pk11_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+pk11_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_TYPE etype,
- PK11ContextType contextType)
+ PK11ContextType contextType, PRBool isEncrypt)
{
PK11Session *session;
PK11Object *key;
@@ -446,7 +444,6 @@ pk11_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
#endif
CK_KEY_TYPE key_type;
CK_RV crv = CKR_OK;
- SECKEYLowPublicKey *pubKey;
unsigned effectiveKeyLength;
unsigned char newdeskey[8];
PRBool useNewKey=PR_FALSE;
@@ -456,7 +453,7 @@ pk11_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
crv = pk11_InitGeneric(session,&context,contextType,&key,hKey,&key_type,
- CKO_PUBLIC_KEY, etype);
+ isEncrypt ?CKO_PUBLIC_KEY:CKO_PRIVATE_KEY, etype);
if (crv != CKR_OK) {
pk11_FreeSession(session);
@@ -472,14 +469,22 @@ pk11_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
break;
}
context->multi = PR_FALSE;
- pubKey = pk11_GetPubKey(key,CKK_RSA);
- if (pubKey == NULL) {
+ context->cipherInfo = isEncrypt ?
+ (void *)pk11_GetPubKey(key,CKK_RSA) :
+ (void *)pk11_GetPrivKey(key,CKK_RSA);
+ if (context->cipherInfo == NULL) {
crv = CKR_HOST_MEMORY;
break;
}
- context->cipherInfo = pubKey;
- context->update = (PK11Cipher) (pMechanism->mechanism == CKM_RSA_X_509
- ? RSA_EncryptRaw : RSA_EncryptBlock);
+ if (isEncrypt) {
+ context->update = (PK11Cipher)
+ (pMechanism->mechanism == CKM_RSA_X_509
+ ? RSA_EncryptRaw : RSA_EncryptBlock);
+ } else {
+ context->update = (PK11Cipher)
+ (pMechanism->mechanism == CKM_RSA_X_509
+ ? RSA_DecryptRaw : RSA_DecryptBlock);
+ }
context->destroy = pk11_Null;
break;
case CKM_RC2_CBC_PAD:
@@ -509,7 +514,7 @@ pk11_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
crv = CKR_HOST_MEMORY;
break;
}
- context->update = (PK11Cipher) RC2_Encrypt;
+ context->update = (PK11Cipher) (isEncrypt ? RC2_Encrypt : RC2_Decrypt);
context->destroy = (PK11Destroy) RC2_DestroyContext;
break;
#if NSS_SOFTOKEN_DOES_RC5
@@ -541,7 +546,7 @@ pk11_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
crv = CKR_HOST_MEMORY;
break;
}
- context->update = (PK11Cipher) RC5_Encrypt;
+ context->update = (PK11Cipher) (isEncrypt ? RC5_Encrypt : RC5_Decrypt);
context->destroy = (PK11Destroy) RC5_DestroyContext;
break;
#endif
@@ -563,7 +568,7 @@ pk11_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
crv = CKR_HOST_MEMORY; /* WRONG !!! */
break;
}
- context->update = (PK11Cipher) RC4_Encrypt;
+ context->update = (PK11Cipher) (isEncrypt ? RC4_Encrypt : RC4_Decrypt);
context->destroy = (PK11Destroy) RC4_DestroyContext;
break;
case CKM_CDMF_CBC_PAD:
@@ -630,13 +635,13 @@ finish_des:
}
context->cipherInfo = DES_CreateContext(
useNewKey ? newdeskey : (unsigned char*)att->attrib.pValue,
- (unsigned char*)pMechanism->pParameter,t, PR_TRUE);
+ (unsigned char*)pMechanism->pParameter,t, isEncrypt);
pk11_FreeAttribute(att);
if (context->cipherInfo == NULL) {
crv = CKR_HOST_MEMORY;
break;
}
- context->update = (PK11Cipher) DES_Encrypt;
+ context->update = (PK11Cipher) (isEncrypt ? DES_Encrypt : DES_Decrypt);
context->destroy = (PK11Destroy) DES_DestroyContext;
break;
@@ -659,13 +664,13 @@ finish_des:
(unsigned char*)att->attrib.pValue,
(unsigned char*)pMechanism->pParameter,
pMechanism->mechanism == CKM_AES_ECB ? NSS_AES : NSS_AES_CBC,
- PR_TRUE, att->attrib.ulValueLen, 16);
+ isEncrypt, att->attrib.ulValueLen, 16);
pk11_FreeAttribute(att);
if (context->cipherInfo == NULL) {
crv = CKR_HOST_MEMORY;
break;
}
- context->update = (PK11Cipher) AES_Encrypt;
+ context->update = (PK11Cipher) (isEncrypt ? AES_Encrypt : AES_Decrypt);
context->destroy = (PK11Destroy) AES_DestroyContext;
break;
@@ -674,7 +679,6 @@ finish_des:
break;
}
- pk11_FreeObject(key);
if (crv != CKR_OK) {
pk11_FreeContext(context);
pk11_FreeSession(session);
@@ -689,8 +693,8 @@ finish_des:
CK_RV NSC_EncryptInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
{
- return pk11_EncryptInit(hSession, pMechanism, hKey, CKA_ENCRYPT,
- PK11_ENCRYPT);
+ return pk11_CryptInit(hSession, pMechanism, hKey, CKA_ENCRYPT,
+ PK11_ENCRYPT, PR_TRUE);
}
/* NSC_EncryptUpdate continues a multiple-part encryption operation. */
@@ -846,258 +850,11 @@ CK_RV NSC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
*/
/* NSC_DecryptInit initializes a decryption operation. */
-static CK_RV pk11_DecryptInit( CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_TYPE dtype,
- PK11ContextType contextType)
-{
- PK11Session *session;
- PK11Object *key;
- PK11Attribute *att;
- PK11SessionContext *context;
- CK_RC2_CBC_PARAMS *rc2_param;
-#if NSS_SOFTOKEN_DOES_RC5
- CK_RC5_CBC_PARAMS *rc5_param;
- SECItem rc5Key;
-#endif
- CK_KEY_TYPE key_type;
- CK_RV crv = CKR_OK;
- unsigned effectiveKeyLength;
- SECKEYLowPrivateKey *privKey;
- unsigned char newdeskey[8];
- PRBool useNewKey=PR_FALSE;
- int t;
-
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
-
- crv = pk11_InitGeneric(session,&context,contextType,&key,hKey,&key_type,
- CKO_PRIVATE_KEY,dtype);
- if (crv != CKR_OK) {
- pk11_FreeSession(session);
- return crv;
- }
-
- /*
- * now handle each mechanism
- */
- switch(pMechanism->mechanism) {
- case CKM_RSA_PKCS:
- case CKM_RSA_X_509:
- if (key_type != CKK_RSA) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- context->multi = PR_FALSE;
- privKey = pk11_GetPrivKey(key,CKK_RSA);
- if (privKey == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->cipherInfo = privKey;
- context->update = (PK11Cipher) (pMechanism->mechanism == CKM_RSA_X_509
- ? RSA_DecryptRaw : RSA_DecryptBlock);
- context->destroy = (context->cipherInfo == key->objectInfo) ?
- (PK11Destroy) pk11_Null : (PK11Destroy) pk11_FreePrivKey;
- break;
- case CKM_RC2_CBC_PAD:
- context->doPad = PR_TRUE;
- context->blockSize = 8;
- /* fall thru */
- case CKM_RC2_ECB:
- case CKM_RC2_CBC:
- if (key_type != CKK_RC2) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- att = pk11_FindAttribute(key,CKA_VALUE);
- rc2_param = (CK_RC2_CBC_PARAMS *)pMechanism->pParameter;
- effectiveKeyLength = (rc2_param->ulEffectiveBits+7)/8;
- context->cipherInfo = RC2_CreateContext((unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen, rc2_param->iv,
- pMechanism->mechanism == CKM_RC2_ECB ? NSS_RC2 :
- NSS_RC2_CBC, effectiveKeyLength);
- pk11_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->update = (PK11Cipher) RC2_Decrypt;
- context->destroy = (PK11Destroy) RC2_DestroyContext;
- break;
-#if NSS_SOFTOKEN_DOES_RC5
- case CKM_RC5_CBC_PAD:
- context->doPad = PR_TRUE;
- /* fall thru */
- case CKM_RC5_ECB:
- case CKM_RC5_CBC:
- if (key_type != CKK_RC5) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- att = pk11_FindAttribute(key,CKA_VALUE);
- if (att == NULL) {
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- rc5_param = (CK_RC5_CBC_PARAMS *)pMechanism->pParameter;
- if (context->doPad) {
- context->blockSize = rc5_param->ulWordsize*2;
- }
- rc5Key.data = (unsigned char*)att->attrib.pValue;
- rc5Key.len = att->attrib.ulValueLen;
- context->cipherInfo = RC5_CreateContext(&rc5Key,rc5_param->ulRounds,
- rc5_param->ulWordsize,rc5_param->pIv,
- pMechanism->mechanism == CKM_RC5_ECB ? NSS_RC5 : NSS_RC5_CBC);
- pk11_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->update = (PK11Cipher) RC5_Decrypt;
- context->destroy = (PK11Destroy) RC5_DestroyContext;
- break;
-#endif
- case CKM_RC4:
- if (key_type != CKK_RC4) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- att = pk11_FindAttribute(key,CKA_VALUE);
- context->cipherInfo =
- RC4_CreateContext((unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen);
- pk11_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->update = (PK11Cipher) RC4_Decrypt;
- context->destroy = (PK11Destroy) RC4_DestroyContext;
- break;
- case CKM_CDMF_CBC_PAD:
- context->doPad = PR_TRUE;
- context->blockSize = 8;
- /* fall thru */
- case CKM_CDMF_ECB:
- case CKM_CDMF_CBC:
- if (key_type != CKK_CDMF) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = (pMechanism->mechanism == CKM_CDMF_ECB) ? NSS_DES : NSS_DES_CBC;
- useNewKey = PR_TRUE;
- if (crv != CKR_OK) break;
- goto finish_des;
- case CKM_DES_ECB:
- if (key_type != CKK_DES) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = NSS_DES;
- goto finish_des;
- case CKM_DES_CBC_PAD:
- context->doPad = PR_TRUE;
- context->blockSize = 8;
- /* fall thru */
- case CKM_DES_CBC:
- if (key_type != CKK_DES) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = NSS_DES_CBC;
- goto finish_des;
- case CKM_DES3_ECB:
- if ((key_type != CKK_DES2) && (key_type != CKK_DES3)) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = NSS_DES_EDE3;
- goto finish_des;
- case CKM_DES3_CBC_PAD:
- context->doPad = PR_TRUE;
- context->blockSize = 8;
- /* fall thru */
- case CKM_DES3_CBC:
- if ((key_type != CKK_DES2) && (key_type != CKK_DES3)) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = NSS_DES_EDE3_CBC;
-finish_des:
- att = pk11_FindAttribute(key,CKA_VALUE);
- if (att == NULL) {
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- if (useNewKey) {
- crv = pk11_cdmf2des((unsigned char*)att->attrib.pValue,newdeskey);
- if (crv != CKR_OK) {
- pk11_FreeAttribute(att);
- break;
- }
- }
- context->cipherInfo = DES_CreateContext(
- useNewKey ? newdeskey : (unsigned char*)att->attrib.pValue,
- (unsigned char*)pMechanism->pParameter,t, PR_FALSE);
- pk11_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->update = (PK11Cipher) DES_Decrypt;
- context->destroy = (PK11Destroy) DES_DestroyContext;
-
- break;
- case CKM_AES_CBC_PAD:
- context->doPad = PR_TRUE;
- context->blockSize = 16;
- /* fall thru */
- case CKM_AES_ECB:
- case CKM_AES_CBC:
- if (key_type != CKK_AES) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- att = pk11_FindAttribute(key,CKA_VALUE);
- if (att == NULL) {
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- context->cipherInfo = AES_CreateContext(
- (unsigned char*)att->attrib.pValue,
- (unsigned char*)pMechanism->pParameter,
- pMechanism->mechanism == CKM_AES_ECB ? NSS_AES : NSS_AES_CBC,
- PR_FALSE, att->attrib.ulValueLen,16);
- pk11_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->update = (PK11Cipher) AES_Decrypt;
- context->destroy = (PK11Destroy) AES_DestroyContext;
-
- break;
- default:
- crv = CKR_MECHANISM_INVALID;
- break;
- }
-
- pk11_FreeObject(key);
- if (crv != CKR_OK) {
- pk11_FreeContext(context);
- pk11_FreeSession(session);
- return crv;
- }
- pk11_SetContextByType(session, contextType, context);
- pk11_FreeSession(session);
- return CKR_OK;
-}
-
-/* NSC_DecryptInit initializes a decryption operation. */
CK_RV NSC_DecryptInit( CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
{
- return pk11_DecryptInit(hSession,pMechanism,hKey,CKA_DECRYPT,PK11_DECRYPT);
+ return pk11_CryptInit(hSession, pMechanism, hKey, CKA_DECRYPT,
+ PK11_DECRYPT, PR_FALSE);
}
/* NSC_DecryptUpdate continues a multiple-part decryption operation. */
@@ -1448,17 +1205,19 @@ pk11_HMACCmp(CK_ULONG *copyLen,unsigned char *sig,unsigned int sigLen,
* common HMAC initalization routine
*/
static CK_RV
-pk11_doHMACInit(PK11SessionContext *context,SECOidTag oid,
+pk11_doHMACInit(PK11SessionContext *context,HASH_HashType hash,
PK11Object *key, CK_ULONG mac_size)
{
PK11Attribute *keyval;
HMACContext *HMACcontext;
CK_ULONG *intpointer;
+ const SECHashObject *hashObj = &SECRawHashObjects[hash];
keyval = pk11_FindAttribute(key,CKA_VALUE);
if (keyval == NULL) return CKR_KEY_SIZE_RANGE;
- HMACcontext = HMAC_Create(oid, (const unsigned char*)keyval->attrib.pValue,
+ HMACcontext = HMAC_Create(hashObj,
+ (const unsigned char*)keyval->attrib.pValue,
keyval->attrib.ulValueLen);
context->hashInfo = HMACcontext;
context->multi = PR_TRUE;
@@ -1865,8 +1624,8 @@ pk11_InitCBCMac(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
return CKR_FUNCTION_NOT_SUPPORTED;
}
- crv = pk11_EncryptInit(hSession, &cbc_mechanism, hKey, keyUsage,
- contextType);
+ crv = pk11_CryptInit(hSession, &cbc_mechanism, hKey, keyUsage,
+ contextType, PR_TRUE);
if (crv != CKR_OK) return crv;
crv = pk11_GetContext(hSession,&context,contextType,PR_TRUE,NULL);
@@ -1926,7 +1685,7 @@ nsc_DSA_Verify_Stub(void *ctx, void *sigBuf, unsigned int sigLen,
void *dataBuf, unsigned int dataLen)
{
SECItem signature, digest;
- SECKEYLowPublicKey *key = (SECKEYLowPublicKey *)ctx;
+ NSSLOWKEYPublicKey *key = (NSSLOWKEYPublicKey *)ctx;
signature.data = (unsigned char *)sigBuf;
signature.len = sigLen;
@@ -1942,7 +1701,7 @@ nsc_DSA_Sign_Stub(void *ctx, void *sigBuf,
{
SECItem signature = { 0 }, digest;
SECStatus rv;
- SECKEYLowPrivateKey *key = (SECKEYLowPrivateKey *)ctx;
+ NSSLOWKEYPrivateKey *key = (NSSLOWKEYPrivateKey *)ctx;
(void)SECITEM_AllocItem(NULL, &signature, maxSigLen);
digest.data = (unsigned char *)dataBuf;
@@ -1984,7 +1743,7 @@ CK_RV NSC_SignInit(CK_SESSION_HANDLE hSession,
PK11SessionContext *context;
CK_KEY_TYPE key_type;
CK_RV crv = CKR_OK;
- SECKEYLowPrivateKey *privKey;
+ NSSLOWKEYPrivateKey *privKey;
PK11HashSignInfo *info = NULL;
/* Block Cipher MACing Algorithms use a different Context init method..*/
@@ -2061,23 +1820,14 @@ finish_rsa:
/* OK, info is allocated only if we're doing hash and sign mechanism.
* It's necessary to be able to set the correct OID in the final
* signature.
- * Second, what's special about privKey == key->objectInfo?
- * Well we don't 'cache' token versions
- * of private keys because (1) it's sensitive data, and (2) it never
- * gets destroyed. Instead we grab the key out of the database as
- * necessary, but now the key is our context, and we need to free
- * it when we are done. Non-token private keys will get freed when
- * the user destroys the session object (or the session the session
- * object lives in) */
+ */
if (info) {
info->key = privKey;
context->cipherInfo = info;
- context->destroy = (privKey == key->objectInfo) ?
- (PK11Destroy)pk11_Space:(PK11Destroy)pk11_FreeSignInfo;
+ context->destroy = (PK11Destroy)pk11_Space;
} else {
context->cipherInfo = privKey;
- context->destroy = (privKey == key->objectInfo) ?
- (PK11Destroy)pk11_Null:(PK11Destroy)pk11_FreePrivKey;
+ context->destroy = (PK11Destroy)pk11_Null;
}
break;
@@ -2103,25 +1853,25 @@ finish_rsa:
break;
case CKM_MD2_HMAC_GENERAL:
- crv = pk11_doHMACInit(context,SEC_OID_MD2,key,
+ crv = pk11_doHMACInit(context,HASH_AlgMD2,key,
*(CK_ULONG *)pMechanism->pParameter);
break;
case CKM_MD2_HMAC:
- crv = pk11_doHMACInit(context,SEC_OID_MD2,key,MD2_LENGTH);
+ crv = pk11_doHMACInit(context,HASH_AlgMD2,key,MD2_LENGTH);
break;
case CKM_MD5_HMAC_GENERAL:
- crv = pk11_doHMACInit(context,SEC_OID_MD5,key,
+ crv = pk11_doHMACInit(context,HASH_AlgMD5,key,
*(CK_ULONG *)pMechanism->pParameter);
break;
case CKM_MD5_HMAC:
- crv = pk11_doHMACInit(context,SEC_OID_MD5,key,MD5_LENGTH);
+ crv = pk11_doHMACInit(context,HASH_AlgMD5,key,MD5_LENGTH);
break;
case CKM_SHA_1_HMAC_GENERAL:
- crv = pk11_doHMACInit(context,SEC_OID_SHA1,key,
+ crv = pk11_doHMACInit(context,HASH_AlgSHA1,key,
*(CK_ULONG *)pMechanism->pParameter);
break;
case CKM_SHA_1_HMAC:
- crv = pk11_doHMACInit(context,SEC_OID_SHA1,key,SHA1_LENGTH);
+ crv = pk11_doHMACInit(context,HASH_AlgSHA1,key,SHA1_LENGTH);
break;
case CKM_SSL3_MD5_MAC:
crv = pk11_doSSLMACInit(context,SEC_OID_MD5,key,
@@ -2139,9 +1889,8 @@ finish_rsa:
break;
}
- pk11_FreeObject(key);
if (crv != CKR_OK) {
- PORT_Free(context);
+ pk11_FreeContext(context);
pk11_FreeSession(session);
return crv;
}
@@ -2363,7 +2112,7 @@ pk11_hashCheckSign(PK11HashVerifyInfo *info, unsigned char *sig,
if (info->key == NULL) goto loser;
- it.len = SECKEY_LowPublicModulusLen(info->key);
+ it.len = nsslowkey_PublicModulusLen(info->key);
if (!it.len) goto loser;
it.data = (unsigned char *) PORT_Alloc(it.len);
@@ -2407,7 +2156,7 @@ CK_RV NSC_VerifyInit(CK_SESSION_HANDLE hSession,
PK11SessionContext *context;
CK_KEY_TYPE key_type;
CK_RV crv = CKR_OK;
- SECKEYLowPublicKey *pubKey;
+ NSSLOWKEYPublicKey *pubKey;
PK11HashVerifyInfo *info = NULL;
/* Block Cipher MACing Algorithms use a different Context init method..*/
@@ -2508,25 +2257,25 @@ finish_rsa:
break;
case CKM_MD2_HMAC_GENERAL:
- crv = pk11_doHMACInit(context,SEC_OID_MD2,key,
+ crv = pk11_doHMACInit(context,HASH_AlgMD2,key,
*(CK_ULONG *)pMechanism->pParameter);
break;
case CKM_MD2_HMAC:
- crv = pk11_doHMACInit(context,SEC_OID_MD2,key,MD2_LENGTH);
+ crv = pk11_doHMACInit(context,HASH_AlgMD2,key,MD2_LENGTH);
break;
case CKM_MD5_HMAC_GENERAL:
- crv = pk11_doHMACInit(context,SEC_OID_MD5,key,
+ crv = pk11_doHMACInit(context,HASH_AlgMD5,key,
*(CK_ULONG *)pMechanism->pParameter);
break;
case CKM_MD5_HMAC:
- crv = pk11_doHMACInit(context,SEC_OID_MD5,key,MD5_LENGTH);
+ crv = pk11_doHMACInit(context,HASH_AlgMD5,key,MD5_LENGTH);
break;
case CKM_SHA_1_HMAC_GENERAL:
- crv = pk11_doHMACInit(context,SEC_OID_SHA1,key,
+ crv = pk11_doHMACInit(context,HASH_AlgSHA1,key,
*(CK_ULONG *)pMechanism->pParameter);
break;
case CKM_SHA_1_HMAC:
- crv = pk11_doHMACInit(context,SEC_OID_SHA1,key,SHA1_LENGTH);
+ crv = pk11_doHMACInit(context,HASH_AlgSHA1,key,SHA1_LENGTH);
break;
case CKM_SSL3_MD5_MAC:
crv = pk11_doSSLMACInit(context,SEC_OID_MD5,key,
@@ -2544,7 +2293,6 @@ finish_rsa:
break;
}
- pk11_FreeObject(key);
if (crv != CKR_OK) {
PORT_Free(context);
pk11_FreeSession(session);
@@ -2650,7 +2398,7 @@ CK_RV NSC_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
PK11SessionContext *context;
CK_KEY_TYPE key_type;
CK_RV crv = CKR_OK;
- SECKEYLowPublicKey *pubKey;
+ NSSLOWKEYPublicKey *pubKey;
session = pk11_SessionFromHandle(hSession);
if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
@@ -2686,7 +2434,6 @@ CK_RV NSC_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
break;
}
- pk11_FreeObject(key);
if (crv != CKR_OK) {
PORT_Free(context);
pk11_FreeSession(session);
@@ -2755,105 +2502,50 @@ CK_RV NSC_GenerateRandom(CK_SESSION_HANDLE hSession,
**************************** Key Functions: ************************
*/
-CK_RV
-pk11_pbe_hmac_key_gen(CK_MECHANISM_PTR pMechanism, char *buf,
- unsigned long *len, PRBool faultyPBE3DES)
-{
- PBEBitGenContext *pbeCx;
- SECItem pwd, salt, *key;
- SECOidTag hashAlg;
- unsigned long keylenbits;
- CK_PBE_PARAMS *pbe_params = NULL;
- pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
- pwd.data = (unsigned char *)pbe_params->pPassword;
- pwd.len = (unsigned int)pbe_params->ulPasswordLen;
- salt.data = (unsigned char *)pbe_params->pSalt;
- salt.len = (unsigned int)pbe_params->ulSaltLen;
- switch (pMechanism->mechanism) {
- case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
- hashAlg = SEC_OID_SHA1; keylenbits = 160; break;
- case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
- hashAlg = SEC_OID_MD5; keylenbits = 128; break;
- case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
- hashAlg = SEC_OID_MD2; keylenbits = 128; break;
- default:
- return CKR_MECHANISM_INVALID;
- }
- pbeCx = PBE_CreateContext(hashAlg, pbeBitGenIntegrityKey, &pwd,
- &salt, keylenbits, pbe_params->ulIteration);
- key = PBE_GenerateBits(pbeCx);
- PORT_Memcpy(buf, key->data, key->len);
- *len = key->len;
- PBE_DestroyContext(pbeCx);
- SECITEM_ZfreeItem(key, PR_TRUE);
- return CKR_OK;
-}
/*
* generate a password based encryption key. This code uses
- * PKCS5 to do the work. Note that it calls PBE_PK11ParamToAlgid, which is
- * a utility function in secpkcs5.c. This function is used in here
- * and in PK11_ParamToAlgid.
+ * PKCS5 to do the work.
*/
-CK_RV
-pk11_pbe_key_gen(SECOidTag algtag,CK_MECHANISM_PTR pMechanism,
- char *buf,CK_ULONG *key_length, PRBool faulty3DES)
+static CK_RV
+nsc_pbe_key_gen(NSSPKCS5PBEParameter *pkcs5_pbe, CK_MECHANISM_PTR pMechanism,
+ char *buf, CK_ULONG *key_length, PRBool faulty3DES)
{
- SECAlgorithmID algid;
- SECItem *pbe_key = NULL, mech;
+ SECItem *pbe_key = NULL, iv, pwitem;
CK_PBE_PARAMS *pbe_params = NULL;
- SECStatus pbe_rv;
*key_length = 0;
+ iv.data = NULL; iv.len = 0;
- mech.data = (unsigned char *)pMechanism->pParameter;
- mech.len = (unsigned int)pMechanism->ulParameterLen;
-
- /* A common routine to map from Params to AlgIDs for PBE
- * algorithms was created in secpkcs5.c. This function is
- * called both by PK11_ParamToAlgid and this function.
- */
- pbe_rv = PBE_PK11ParamToAlgid(algtag, &mech, NULL, &algid);
- if (pbe_rv != SECSuccess) {
- return CKR_DATA_INVALID;
- }
pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
- mech.data = (unsigned char *)pbe_params->pPassword;
- mech.len = (unsigned int)pbe_params->ulPasswordLen;
- pbe_key = SEC_PKCS5GetKey(&algid, &mech, faulty3DES);
+
+ pwitem.data = (unsigned char *)pbe_params->pPassword;
+ pwitem.len = (unsigned int)pbe_params->ulPasswordLen;
+ pbe_key = nsspkcs5_ComputeKeyAndIV(pkcs5_pbe, &pwitem, &iv, faulty3DES);
if (pbe_key == NULL) {
- SECOID_DestroyAlgorithmID(&algid, PR_FALSE);
return CKR_HOST_MEMORY;
}
+
PORT_Memcpy(buf, pbe_key->data, pbe_key->len);
*key_length = pbe_key->len;
SECITEM_ZfreeItem(pbe_key, PR_TRUE);
pbe_key = NULL;
- if (pbe_params->pInitVector == NULL) {
- pbe_key = SEC_PKCS5GetIV(&algid, &mech, faulty3DES);
- if (pbe_key == NULL) {
- SECOID_DestroyAlgorithmID(&algid, PR_FALSE);
- SECITEM_ZfreeItem(pbe_key, PR_TRUE);
- return CKR_HOST_MEMORY;
- }
+ if (iv.data && pbe_params->pInitVector == NULL) {
pbe_params->pInitVector = (CK_CHAR_PTR)PORT_ZAlloc(pbe_key->len);
if (pbe_params->pInitVector == NULL) {
- SECOID_DestroyAlgorithmID(&algid, PR_FALSE);
- SECITEM_ZfreeItem(pbe_key, PR_TRUE);
return CKR_HOST_MEMORY;
}
- PORT_Memcpy(pbe_params->pInitVector, pbe_key->data, pbe_key->len);
+ PORT_Memcpy(pbe_params->pInitVector, iv.data, iv.len);
}
- SECITEM_ZfreeItem(pbe_key, PR_TRUE);
- SECOID_DestroyAlgorithmID(&algid, PR_FALSE);
return CKR_OK;
}
static CK_RV
-nsc_SetupBulkKeyGen(CK_MECHANISM_TYPE mechanism,
- CK_KEY_TYPE *key_type,CK_ULONG *key_length) {
+nsc_SetupBulkKeyGen(CK_MECHANISM_TYPE mechanism, CK_KEY_TYPE *key_type,
+ CK_ULONG *key_length)
+{
CK_RV crv = CKR_OK;
switch (mechanism) {
@@ -2904,81 +2596,111 @@ nsc_SetupBulkKeyGen(CK_MECHANISM_TYPE mechanism,
return crv;
}
+CK_RV
+nsc_SetupHMACKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe)
+{
+ SECItem salt;
+ CK_PBE_PARAMS *pbe_params = NULL;
+ NSSPKCS5PBEParameter *params;
+ PRArenaPool *arena = NULL;
+ SECStatus rv;
+
+ *pbe = NULL;
+
+ arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
+ if (arena == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+
+ params = (NSSPKCS5PBEParameter *) PORT_ArenaZAlloc(arena,
+ sizeof(NSSPKCS5PBEParameter));
+ if (params == NULL) {
+ PORT_FreeArena(arena,PR_TRUE);
+ return CKR_HOST_MEMORY;
+ }
+
+ params->ivLen = 0;
+ params->pbeType = NSSPKCS5_PKCS12_V2;
+ params->hashType = HASH_AlgSHA1;
+ params->encAlg = SEC_OID_SHA1; /* any invalid value */
+ params->is2KeyDES = PR_FALSE;
+ params->keyID = pbeBitGenIntegrityKey;
+ params->iter = pbe_params->ulIteration;
+
+ pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
+ salt.data = (unsigned char *)pbe_params->pSalt;
+ salt.len = (unsigned int)pbe_params->ulSaltLen;
+ rv = SECITEM_CopyItem(arena,&params->salt,&salt);
+ if (rv != SECSuccess) {
+ PORT_FreeArena(arena,PR_TRUE);
+ return CKR_HOST_MEMORY;
+ }
+ switch (pMechanism->mechanism) {
+ case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
+ case CKM_PBA_SHA1_WITH_SHA1_HMAC:
+ params->hashType = HASH_AlgSHA1;
+ params->keyLen = 20;
+ break;
+ case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
+ params->hashType = HASH_AlgMD5;
+ params->keyLen = 16;
+ break;
+ case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
+ params->hashType = HASH_AlgMD2;
+ params->keyLen = 16;
+ break;
+ default:
+ PORT_FreeArena(arena,PR_TRUE);
+ return CKR_MECHANISM_INVALID;
+ }
+ *pbe = params;
+ return CKR_OK;
+}
+/* maybe this should be table driven? */
static CK_RV
-nsc_SetupPBEKeyGen(CK_MECHANISM_TYPE mechanism,SECOidTag *algtag,
- CK_KEY_TYPE *key_type,CK_ULONG *key_length) {
+nsc_SetupPBEKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe,
+ CK_KEY_TYPE *key_type)
+{
CK_RV crv = CKR_OK;
+ SECOidData *oid;
+ CK_PBE_PARAMS *pbe_params;
+ NSSPKCS5PBEParameter *params;
+ SECItem salt;
- switch (mechanism) {
- case CKM_PBE_MD2_DES_CBC:
- *algtag = SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC;
+ oid = SECOID_FindOIDByMechanism(pMechanism->mechanism);
+ if (oid == NULL) {
+ return CKR_MECHANISM_INVALID;
+ }
+
+ pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
+ salt.data = (unsigned char *)pbe_params->pSalt;
+ salt.len = (unsigned int)pbe_params->ulSaltLen;
+
+ params=nsspkcs5_NewParam(oid->offset, &salt, pbe_params->ulIteration);
+ if (params == NULL) {
+ return CKR_MECHANISM_INVALID;
+ }
+
+
+ switch (params->encAlg) {
+ case SEC_OID_DES_CBC:
*key_type = CKK_DES;
break;
+ case SEC_OID_DES_EDE3_CBC:
+ *key_type = params->is2KeyDES ? CKK_DES2 : CKK_DES3;
case CKM_PBE_MD5_DES_CBC:
- *algtag = SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC;
- *key_type = CKK_DES;
- break;
- case CKM_PBE_SHA1_RC4_40:
- *algtag = SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4;
- *key_length = 5;
- *key_type = CKK_RC4;
- break;
- case CKM_PBE_SHA1_RC4_128:
- *algtag = SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4;
- *key_length = 16;
- *key_type = CKK_RC4;
- break;
- case CKM_PBE_SHA1_RC2_40_CBC:
- *algtag = SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC;
- *key_length = 5;
- *key_type = CKK_RC2;
- break;
- case CKM_PBE_SHA1_RC2_128_CBC:
- *algtag = SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC;
- *key_length = 16;
- *key_type = CKK_RC2;
- break;
- case CKM_PBE_SHA1_DES3_EDE_CBC:
- *algtag = SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC;
- *key_length = 24;
- *key_type = CKK_DES3;
- break;
- case CKM_PBE_SHA1_DES2_EDE_CBC:
- *algtag = SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC;
- *key_length = 16;
- *key_type = CKK_DES2;
- break;
- case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
- *algtag = SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC;
*key_type = CKK_DES;
break;
- case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
- case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
- *algtag = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC;
- *key_type = CKK_DES3;
- break;
- case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
- *algtag = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC;
- *key_type = CKK_RC2;
- break;
- case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
- *algtag = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC;
- *key_type = CKK_RC2;
- break;
- case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
- *algtag = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4;
+ case SEC_OID_RC2_CBC:
*key_type = CKK_RC4;
break;
- case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
- *algtag = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4;
+ case SEC_OID_RC4:
*key_type = CKK_RC4;
break;
default:
- PORT_Assert(0);
crv = CKR_MECHANISM_INVALID;
break;
}
-
return crv;
}
@@ -2998,8 +2720,8 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
int i;
PK11Slot *slot = pk11_SlotFromSessionHandle(hSession);
char buf[MAX_KEY_LEN];
- enum {pk11_pbe, pk11_pbe_hmac, pk11_ssl, pk11_bulk} key_gen_type;
- SECOidTag algtag = SEC_OID_UNKNOWN;
+ enum {nsc_pbe, nsc_ssl, nsc_bulk} key_gen_type;
+ NSSPKCS5PBEParameter *pbe_param;
SSL3RSAPreMasterSecret *rsa_pms;
CK_VERSION *version;
/* in very old versions of NSS, there were implementation errors with key
@@ -3040,7 +2762,7 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
pk11_DeleteAttributeType(key,CKA_VALUE);
/* Now Set up the parameters to generate the key (based on mechanism) */
- key_gen_type = pk11_bulk; /* bulk key by default */
+ key_gen_type = nsc_bulk; /* bulk key by default */
switch (pMechanism->mechanism) {
case CKM_CDMF_KEY_GEN:
case CKM_DES_KEY_GEN:
@@ -3059,16 +2781,18 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
case CKM_SSL3_PRE_MASTER_KEY_GEN:
key_type = CKK_GENERIC_SECRET;
key_length = 48;
- key_gen_type = pk11_ssl;
+ key_gen_type = nsc_ssl;
break;
- case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
- faultyPBE3DES = PR_TRUE;
+ case CKM_PBA_SHA1_WITH_SHA1_HMAC:
case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
- key_gen_type = pk11_pbe_hmac;
+ key_gen_type = nsc_pbe;
key_type = CKK_GENERIC_SECRET;
+ crv = nsc_SetupHMACKeyGen(pMechanism, &pbe_param);
break;
+ case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
+ faultyPBE3DES = PR_TRUE;
case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
@@ -3083,9 +2807,8 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
case CKM_PBE_SHA1_RC4_40:
case CKM_PBE_MD5_DES_CBC:
case CKM_PBE_MD2_DES_CBC:
- key_gen_type = pk11_pbe;
- crv = nsc_SetupPBEKeyGen(pMechanism->mechanism,&algtag,
- &key_type,&key_length);
+ key_gen_type = nsc_pbe;
+ crv = nsc_SetupPBEKeyGen(pMechanism,&pbe_param, &key_type);
break;
default:
crv = CKR_MECHANISM_INVALID;
@@ -3109,15 +2832,11 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
* now to the actual key gen.
*/
switch (key_gen_type) {
- case pk11_pbe_hmac:
- crv = pk11_pbe_hmac_key_gen(pMechanism, buf, &key_length,
- faultyPBE3DES);
- break;
- case pk11_pbe:
- crv = pk11_pbe_key_gen(algtag, pMechanism, buf, &key_length,
+ case nsc_pbe:
+ crv = nsc_pbe_key_gen(pbe_param, pMechanism, buf, &key_length,
faultyPBE3DES);
break;
- case pk11_ssl:
+ case nsc_ssl:
rsa_pms = (SSL3RSAPreMasterSecret *)buf;
version = (CK_VERSION *)pMechanism->pParameter;
rsa_pms->client_version[0] = version->major;
@@ -3125,7 +2844,7 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
crv =
NSC_GenerateRandom(0,&rsa_pms->random[0], sizeof(rsa_pms->random));
break;
- case pk11_bulk:
+ case nsc_bulk:
/* get the key, check for weak keys and repeat if found */
do {
crv = NSC_GenerateRandom(0, (unsigned char *)buf, key_length);
@@ -3158,10 +2877,6 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
*/
crv = pk11_handleObject(key,session);
pk11_FreeSession(session);
- if (crv != CKR_OK) {
- pk11_FreeObject(key);
- return crv;
- }
if (pk11_isTrue(key,CKA_SENSITIVE)) {
pk11_forceAttribute(key,CKA_ALWAYS_SENSITIVE,&cktrue,sizeof(CK_BBOOL));
}
@@ -3170,7 +2885,8 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
}
*phKey = key->handle;
- return CKR_OK;
+ pk11_FreeObject(key);
+ return crv;
}
@@ -3495,7 +3211,7 @@ dhgn_done:
/*
* handle the base object cleanup for the public Key
*/
- crv = pk11_handleObject(publicKey,session);
+ crv = pk11_handleObject(privateKey,session);
if (crv != CKR_OK) {
pk11_FreeSession(session);
pk11_FreeObject(privateKey);
@@ -3508,11 +3224,12 @@ dhgn_done:
* If we have any problems, we destroy the public Key we've
* created and linked.
*/
- crv = pk11_handleObject(privateKey,session);
+ crv = pk11_handleObject(publicKey,session);
pk11_FreeSession(session);
if (crv != CKR_OK) {
+ pk11_FreeObject(publicKey);
+ NSC_DestroyObject(hSession,privateKey->handle);
pk11_FreeObject(privateKey);
- NSC_DestroyObject(hSession,publicKey->handle);
return crv;
}
if (pk11_isTrue(privateKey,CKA_SENSITIVE)) {
@@ -3533,14 +3250,16 @@ dhgn_done:
}
*phPrivateKey = privateKey->handle;
*phPublicKey = publicKey->handle;
+ pk11_FreeObject(publicKey);
+ pk11_FreeObject(privateKey);
return CKR_OK;
}
static SECItem *pk11_PackagePrivateKey(PK11Object *key)
{
- SECKEYLowPrivateKey *lk = NULL;
- PrivateKeyInfo *pki = NULL;
+ NSSLOWKEYPrivateKey *lk = NULL;
+ NSSLOWKEYPrivateKeyInfo *pki = NULL;
PK11Attribute *attribute = NULL;
PLArenaPool *arena = NULL;
SECOidTag algorithm = SEC_OID_UNKNOWN;
@@ -3569,8 +3288,8 @@ static SECItem *pk11_PackagePrivateKey(PK11Object *key)
goto loser;
}
- pki = (PrivateKeyInfo*)PORT_ArenaZAlloc(arena,
- sizeof(PrivateKeyInfo));
+ pki = (NSSLOWKEYPrivateKeyInfo*)PORT_ArenaZAlloc(arena,
+ sizeof(NSSLOWKEYPrivateKeyInfo));
if(!pki) {
rv = SECFailure;
goto loser;
@@ -3579,25 +3298,25 @@ static SECItem *pk11_PackagePrivateKey(PK11Object *key)
param = NULL;
switch(lk->keyType) {
- case lowRSAKey:
+ case NSSLOWKEYRSAKey:
dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,
- SECKEY_LowRSAPrivateKeyTemplate);
+ nsslowkey_RSAPrivateKeyTemplate);
algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION;
break;
- case lowDSAKey:
+ case NSSLOWKEYDSAKey:
dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,
- SECKEY_LowDSAPrivateKeyExportTemplate);
+ nsslowkey_DSAPrivateKeyExportTemplate);
param = SEC_ASN1EncodeItem(NULL, NULL, &(lk->u.dsa.params),
- SECKEY_LowPQGParamsTemplate);
+ nsslowkey_PQGParamsTemplate);
algorithm = SEC_OID_ANSIX9_DSA_SIGNATURE;
break;
- case lowDHKey:
+ case NSSLOWKEYDHKey:
default:
dummy = NULL;
break;
}
- if(!dummy || ((lk->keyType == lowDSAKey) && !param)) {
+ if(!dummy || ((lk->keyType == NSSLOWKEYDSAKey) && !param)) {
goto loser;
}
@@ -3609,14 +3328,14 @@ static SECItem *pk11_PackagePrivateKey(PK11Object *key)
}
dummy = SEC_ASN1EncodeInteger(arena, &pki->version,
- SEC_PRIVATE_KEY_INFO_VERSION);
+ NSSLOWKEY_PRIVATE_KEY_INFO_VERSION);
if(!dummy) {
rv = SECFailure;
goto loser;
}
encodedKey = SEC_ASN1EncodeItem(NULL, NULL, pki,
- SECKEY_PrivateKeyInfoTemplate);
+ nsslowkey_PrivateKeyInfoTemplate);
loser:
if(arena) {
@@ -3624,7 +3343,7 @@ loser:
}
if(lk && (lk != key->objectInfo)) {
- SECKEY_LowDestroyPrivateKey(lk);
+ nsslowkey_DestroyPrivateKey(lk);
}
if(param) {
@@ -3680,8 +3399,8 @@ CK_RV NSC_WrapKey(CK_SESSION_HANDLE hSession,
len = *pulWrappedKeyLen;
}
- crv = pk11_EncryptInit(hSession, pMechanism, hWrappingKey,
- CKA_WRAP, PK11_ENCRYPT);
+ crv = pk11_CryptInit(hSession, pMechanism, hWrappingKey,
+ CKA_WRAP, PK11_ENCRYPT, PR_TRUE);
if (crv != CKR_OK) {
pk11_FreeAttribute(attribute);
break;
@@ -3712,8 +3431,8 @@ CK_RV NSC_WrapKey(CK_SESSION_HANDLE hSession,
break;
}
- crv = pk11_EncryptInit(hSession, pMechanism, hWrappingKey,
- CKA_WRAP, PK11_ENCRYPT);
+ crv = pk11_CryptInit(hSession, pMechanism, hWrappingKey,
+ CKA_WRAP, PK11_ENCRYPT, PR_TRUE);
if(crv != CKR_OK) {
SECITEM_ZfreeItem(bpki, PR_TRUE);
crv = CKR_KEY_TYPE_INCONSISTENT;
@@ -3747,8 +3466,8 @@ pk11_unwrapPrivateKey(PK11Object *key, SECItem *bpki)
const SEC_ASN1Template *keyTemplate, *paramTemplate;
void *paramDest = NULL;
PLArenaPool *arena;
- SECKEYLowPrivateKey *lpk = NULL;
- PrivateKeyInfo *pki = NULL;
+ NSSLOWKEYPrivateKey *lpk = NULL;
+ NSSLOWKEYPrivateKeyInfo *pki = NULL;
SECItem *ck_id = NULL;
CK_RV crv = CKR_KEY_TYPE_INCONSISTENT;
@@ -3757,21 +3476,21 @@ pk11_unwrapPrivateKey(PK11Object *key, SECItem *bpki)
return SECFailure;
}
- pki = (PrivateKeyInfo*)PORT_ArenaZAlloc(arena,
- sizeof(PrivateKeyInfo));
+ pki = (NSSLOWKEYPrivateKeyInfo*)PORT_ArenaZAlloc(arena,
+ sizeof(NSSLOWKEYPrivateKeyInfo));
if(!pki) {
PORT_FreeArena(arena, PR_TRUE);
return SECFailure;
}
- if(SEC_ASN1DecodeItem(arena, pki, SECKEY_PrivateKeyInfoTemplate, bpki)
+ if(SEC_ASN1DecodeItem(arena, pki, nsslowkey_PrivateKeyInfoTemplate, bpki)
!= SECSuccess) {
PORT_FreeArena(arena, PR_FALSE);
return SECFailure;
}
- lpk = (SECKEYLowPrivateKey *)PORT_ArenaZAlloc(arena,
- sizeof(SECKEYLowPrivateKey));
+ lpk = (NSSLOWKEYPrivateKey *)PORT_ArenaZAlloc(arena,
+ sizeof(NSSLOWKEYPrivateKey));
if(lpk == NULL) {
goto loser;
}
@@ -3779,18 +3498,18 @@ pk11_unwrapPrivateKey(PK11Object *key, SECItem *bpki)
switch(SECOID_GetAlgorithmTag(&pki->algorithm)) {
case SEC_OID_PKCS1_RSA_ENCRYPTION:
- keyTemplate = SECKEY_LowRSAPrivateKeyTemplate;
+ keyTemplate = nsslowkey_RSAPrivateKeyTemplate;
paramTemplate = NULL;
paramDest = NULL;
- lpk->keyType = lowRSAKey;
+ lpk->keyType = NSSLOWKEYRSAKey;
break;
case SEC_OID_ANSIX9_DSA_SIGNATURE:
- keyTemplate = SECKEY_LowDSAPrivateKeyExportTemplate;
- paramTemplate = SECKEY_LowPQGParamsTemplate;
+ keyTemplate = nsslowkey_DSAPrivateKeyExportTemplate;
+ paramTemplate = nsslowkey_PQGParamsTemplate;
paramDest = &(lpk->u.dsa.params);
- lpk->keyType = lowDSAKey;
+ lpk->keyType = NSSLOWKEYDSAKey;
break;
- /* case lowDHKey: */
+ /* case NSSLOWKEYDHKey: */
default:
keyTemplate = NULL;
paramTemplate = NULL;
@@ -3818,7 +3537,7 @@ pk11_unwrapPrivateKey(PK11Object *key, SECItem *bpki)
rv = SECFailure;
switch (lpk->keyType) {
- case lowRSAKey:
+ case NSSLOWKEYRSAKey:
keyType = CKK_RSA;
if(pk11_hasAttribute(key, CKA_NETSCAPE_DB)) {
pk11_DeleteAttributeType(key, CKA_NETSCAPE_DB);
@@ -3862,7 +3581,7 @@ pk11_unwrapPrivateKey(PK11Object *key, SECItem *bpki)
crv = pk11_AddAttributeType(key, CKA_COEFFICIENT,
pk11_item_expand(&lpk->u.rsa.coefficient));
break;
- case lowDSAKey:
+ case NSSLOWKEYDSAKey:
keyType = CKK_DSA;
crv = (pk11_hasAttribute(key, CKA_NETSCAPE_DB)) ? CKR_OK :
CKR_KEY_TYPE_INCONSISTENT;
@@ -3890,7 +3609,7 @@ pk11_unwrapPrivateKey(PK11Object *key, SECItem *bpki)
if(crv != CKR_OK) break;
break;
#ifdef notdef
- case lowDHKey:
+ case NSSLOWKEYDHKey:
template = dhTemplate;
templateCount = sizeof(dhTemplate)/sizeof(CK_ATTRIBUTE);
keyType = CKK_DH;
@@ -3908,7 +3627,7 @@ loser:
}
if(lpk) {
- SECKEY_LowDestroyPrivateKey(lpk);
+ nsslowkey_DestroyPrivateKey(lpk);
}
if(crv != CKR_OK) {
@@ -3972,8 +3691,8 @@ CK_RV NSC_UnwrapKey(CK_SESSION_HANDLE hSession,
ulWrappedKeyLen -= 2; /* don't decrypt the checksum */
}
- crv = pk11_DecryptInit(hSession,pMechanism,hUnwrappingKey,CKA_UNWRAP,
- PK11_DECRYPT);
+ crv = pk11_CryptInit(hSession,pMechanism,hUnwrappingKey,CKA_UNWRAP,
+ PK11_DECRYPT, PR_FALSE);
if (crv != CKR_OK) {
pk11_FreeObject(key);
return pk11_mapWrap(crv);
@@ -4050,14 +3769,11 @@ CK_RV NSC_UnwrapKey(CK_SESSION_HANDLE hSession,
* handle the base object stuff
*/
crv = pk11_handleObject(key,session);
+ *phKey = key->handle;
pk11_FreeSession(session);
- if (crv != CKR_OK) {
- pk11_FreeObject(key);
- return crv;
- }
+ pk11_FreeObject(key);
- *phKey = key->handle;
- return CKR_OK;
+ return crv;
}
@@ -4080,10 +3796,10 @@ pk11_buildSSLKey(CK_SESSION_HANDLE hSession, PK11Object *baseKey,
/*
* now lets create an object to hang the attributes off of
*/
- *keyHandle = CK_INVALID_KEY;
+ *keyHandle = CK_INVALID_HANDLE;
key = pk11_NewObject(baseKey->slot);
if (key == NULL) return CKR_HOST_MEMORY;
- key->wasDerived = PR_TRUE;
+ pk11_narrowToSessionObject(key)->wasDerived = PR_TRUE;
crv = pk11_CopyObject(key,baseKey);
if (crv != CKR_OK) goto loser;
@@ -4115,10 +3831,7 @@ pk11_buildSSLKey(CK_SESSION_HANDLE hSession, PK11Object *baseKey,
crv = pk11_handleObject(key,session);
pk11_FreeSession(session);
- if (crv == CKR_OK) {
- *keyHandle = key->handle;
- return crv;
- }
+ *keyHandle = key->handle;
loser:
if (key) pk11_FreeObject(key);
return crv;
@@ -4131,16 +3844,16 @@ loser:
static void
pk11_freeSSLKeys(CK_SESSION_HANDLE session,
CK_SSL3_KEY_MAT_OUT *returnedMaterial ) {
- if (returnedMaterial->hClientMacSecret != CK_INVALID_KEY) {
+ if (returnedMaterial->hClientMacSecret != CK_INVALID_HANDLE) {
NSC_DestroyObject(session,returnedMaterial->hClientMacSecret);
}
- if (returnedMaterial->hServerMacSecret != CK_INVALID_KEY) {
+ if (returnedMaterial->hServerMacSecret != CK_INVALID_HANDLE) {
NSC_DestroyObject(session, returnedMaterial->hServerMacSecret);
}
- if (returnedMaterial->hClientKey != CK_INVALID_KEY) {
+ if (returnedMaterial->hClientKey != CK_INVALID_HANDLE) {
NSC_DestroyObject(session, returnedMaterial->hClientKey);
}
- if (returnedMaterial->hServerKey != CK_INVALID_KEY) {
+ if (returnedMaterial->hServerKey != CK_INVALID_HANDLE) {
NSC_DestroyObject(session, returnedMaterial->hServerKey);
}
}
@@ -4233,7 +3946,7 @@ pk11_MapKeySize(CK_KEY_TYPE keyType) {
/* TLS P_hash function */
static SECStatus
-pk11_P_hash(SECOidTag alg, const SECItem *secret, const char *label,
+pk11_P_hash(HASH_HashType hashType, const SECItem *secret, const char *label,
SECItem *seed, SECItem *result)
{
unsigned char state[PHASH_STATE_MAX_LEN];
@@ -4244,6 +3957,7 @@ pk11_P_hash(SECOidTag alg, const SECItem *secret, const char *label,
SECStatus status;
HMACContext *cx;
SECStatus rv = SECFailure;
+ const SECHashObject *hashObj = &SECRawHashObjects[hashType];
PORT_Assert((secret != NULL) && (secret->data != NULL || !secret->len));
PORT_Assert((seed != NULL) && (seed->data != NULL));
@@ -4255,7 +3969,7 @@ pk11_P_hash(SECOidTag alg, const SECItem *secret, const char *label,
if (label != NULL)
label_len = PORT_Strlen(label);
- cx = HMAC_Create(alg, secret->data, secret->len);
+ cx = HMAC_Create(hashObj, secret->data, secret->len);
if (cx == NULL)
goto loser;
@@ -4330,11 +4044,11 @@ pk11_PRF(const SECItem *secret, const char *label, SECItem *seed,
goto loser;
tmp.len = result->len;
- status = pk11_P_hash(SEC_OID_MD5, &S1, label, seed, result);
+ status = pk11_P_hash(HASH_AlgMD5, &S1, label, seed, result);
if (status != SECSuccess)
goto loser;
- status = pk11_P_hash(SEC_OID_SHA1, &S2, label, seed, &tmp);
+ status = pk11_P_hash(HASH_AlgSHA1, &S2, label, seed, &tmp);
if (status != SECSuccess)
goto loser;
@@ -4404,7 +4118,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
/*
* now lets create an object to hang the attributes off of
*/
- if (phKey) *phKey = CK_INVALID_KEY;
+ if (phKey) *phKey = CK_INVALID_HANDLE;
key = pk11_NewObject(slot); /* fill in the handle later */
if (key == NULL) {
@@ -4513,9 +4227,10 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
ssl3_master = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *)
pMechanism->pParameter;
if (ssl3_master->pVersion) {
+ PK11SessionObject *sessKey = pk11_narrowToSessionObject(key);
rsa_pms = (SSL3RSAPreMasterSecret *) att->attrib.pValue;
/* don't leak more key material then necessary for SSL to work */
- if (key->wasDerived) {
+ if ((sessKey == NULL) || sessKey->wasDerived) {
ssl3_master->pVersion->major = 0xff;
ssl3_master->pVersion->minor = 0xff;
} else {
@@ -4652,10 +4367,10 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
* clear out our returned keys so we can recover on failure
*/
ssl3_keys_out = ssl3_keys->pReturnedKeyMaterial;
- ssl3_keys_out->hClientMacSecret = CK_INVALID_KEY;
- ssl3_keys_out->hServerMacSecret = CK_INVALID_KEY;
- ssl3_keys_out->hClientKey = CK_INVALID_KEY;
- ssl3_keys_out->hServerKey = CK_INVALID_KEY;
+ ssl3_keys_out->hClientMacSecret = CK_INVALID_HANDLE;
+ ssl3_keys_out->hServerMacSecret = CK_INVALID_HANDLE;
+ ssl3_keys_out->hClientKey = CK_INVALID_HANDLE;
+ ssl3_keys_out->hServerKey = CK_INVALID_HANDLE;
/*
* generate the key material: This looks amazingly similar to the
@@ -5222,8 +4937,10 @@ key_and_mac_derive_fail:
/* link the key object into the list */
if (key) {
+ PK11SessionObject *sessKey = pk11_narrowToSessionObject(key);
+ PORT_Assert(sessKey);
/* get the session */
- key->wasDerived = PR_TRUE;
+ sessKey->wasDerived = PR_TRUE;
session = pk11_SessionFromHandle(hSession);
if (session == NULL) {
pk11_FreeObject(key);
@@ -5232,10 +4949,7 @@ key_and_mac_derive_fail:
crv = pk11_handleObject(key,session);
pk11_FreeSession(session);
- if (crv == CKR_OK) {
- *phKey = key->handle;
- return crv;
- }
+ *phKey = key->handle;
pk11_FreeObject(key);
}
return crv;
diff --git a/security/nss/lib/softoken/pkcs11f.h b/security/nss/lib/softoken/pkcs11f.h
index 71ee2676a..70d34da5e 100644
--- a/security/nss/lib/softoken/pkcs11f.h
+++ b/security/nss/lib/softoken/pkcs11f.h
@@ -150,10 +150,11 @@ CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
CK_PKCS11_FUNCTION_INFO(C_InitToken)
#ifdef CK_NEED_ARG_LIST
(
- CK_SLOT_ID slotID, /* ID of the token's slot */
- CK_CHAR_PTR pPin, /* the SO's initial PIN */
- CK_ULONG ulPinLen, /* length in bytes of the PIN */
- CK_CHAR_PTR pLabel /* 32-byte token label (blank padded) */
+/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
+ CK_SLOT_ID slotID, /* ID of the token's slot */
+ CK_CHAR_PTR pPin, /* the SO's initial PIN */
+ CK_ULONG ulPinLen, /* length in bytes of the PIN */
+ CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */
);
#endif
diff --git a/security/nss/lib/softoken/pkcs11i.h b/security/nss/lib/softoken/pkcs11i.h
index 2e924a4ef..c09b2635e 100644
--- a/security/nss/lib/softoken/pkcs11i.h
+++ b/security/nss/lib/softoken/pkcs11i.h
@@ -39,14 +39,67 @@
#include "nssilock.h"
#include "seccomon.h"
#include "secoidt.h"
-#include "keytlow.h"
+#include "lowkeyti.h"
#include "pkcs11t.h"
+#include "pcertt.h"
-#define PKCS11_USE_THREADS
-#define NO_ARENA
-#define MAX_OBJS_ATTRS 45
-#define ATTR_SPACE 50 /* hold up to a SSL premaster secret */
+/*
+ * Configuration Defines
+ *
+ * The following defines affect the space verse speed trade offs of
+ * the PKCS #11 module. For the most part the current settings are optimized
+ * for web servers, where we want faster speed and lower lock contention at
+ * the expense of space.
+ */
+
+#define PKCS11_USE_THREADS /* set to true of you are need threads */
+/*
+ * Attribute Allocation strategy:
+ *
+ * 1) static allocation (PKCS11_STATIC_ATTRIBUTES set
+ * PKCS11_REF_COUNT_ATTRIBUTES not set)
+ * Attributes are pre-allocated as part of the session object and used from
+ * the object array.
+ *
+ * 2) heap allocation with ref counting (PKCS11_STATIC_ATTRIBUTES not set
+ * PKCS11_REF_COUNT_ATTRIBUTES set)
+ * Attributes are allocated from the heap when needed and freed when their
+ * reference count goes to zero.
+ *
+ * 3) arena allocation (PKCS11_STATIC_ATTRIBUTES not set
+ * PKCS11_REF_COUNT_ATTRIBUTE not set)
+ * Attributes are allocated from the arena when needed and freed only when
+ * the object goes away.
+ */
+#define PKCS11_STATIC_ATTRIBUTES
+/*#define PKCS11_REF_COUNT_ATTRIBUTES */
+/* the next two are only active if PKCS11_STATIC_ATTRIBUTES is set */
+#define MAX_OBJS_ATTRS 45 /* number of attributes to preallocate in
+ * the object (must me the absolute max) */
+#define ATTR_SPACE 50 /* Maximum size of attribute data before extra
+ * data needs to be allocated. This is set to
+ * enough space to hold an SSL MASTER secret */
+
+#define NSC_STRICT PR_FALSE /* forces the code to do strict template
+ * matching when doing C_FindObject on token
+ * objects. This will slow down search in
+ * NSS. */
+/* default search block allocations and increments */
+#define NSC_CERT_BLOCK_SIZE 50
+#define NSC_SEARCH_BLOCK_SIZE 5
+#define NSC_SLOT_LIST_BLOCK_SIZE 10
+
+/* these are data base storage hashes, not cryptographic hashes.. The define
+ * the effective size of the various object hash tables */
+#define ATTRIBUTE_HASH_SIZE 32
+#define SESSION_OBJECT_HASH_SIZE 32
+#define TOKEN_OBJECT_HASH_SIZE 1024
+#define SESSION_HASH_SIZE 512
+#define MAX_OBJECT_LIST_SIZE 800 /* how many objects to keep on the free list
+ * before we start freeing them */
+#define MAX_KEY_LEN 256
+
#ifdef PKCS11_USE_THREADS
@@ -60,6 +113,8 @@ typedef struct PK11AttributeStr PK11Attribute;
typedef struct PK11ObjectListStr PK11ObjectList;
typedef struct PK11ObjectListElementStr PK11ObjectListElement;
typedef struct PK11ObjectStr PK11Object;
+typedef struct PK11SessionObjectStr PK11SessionObject;
+typedef struct PK11TokenObjectStr PK11TokenObject;
typedef struct PK11SessionStr PK11Session;
typedef struct PK11SlotStr PK11Slot;
typedef struct PK11SessionContextStr PK11SessionContext;
@@ -78,17 +133,6 @@ typedef void (*PK11Hash)(void *,void *,unsigned int);
typedef void (*PK11End)(void *,void *,unsigned int *,unsigned int);
typedef void (*PK11Free)(void *);
-/*
- * these are data base storage hashes, not cryptographic hashes.. The define
- * the effective size of the various object hash tables
- */
-#define ATTRIBUTE_HASH_SIZE 32
-#define SESSION_OBJECT_HASH_SIZE 32
-#define TOKEN_OBJECT_HASH_SIZE 1024
-#define SESSION_HASH_SIZE 512
-#define MAX_KEY_LEN 256
-#define MAX_OBJECT_LIST_SIZE 800
-
/* Value to tell if an attribute is modifiable or not.
* NEVER: attribute is only set on creation.
* ONCOPY: attribute is set on creation and can only be changed on copy.
@@ -118,14 +162,16 @@ typedef enum {
struct PK11AttributeStr {
PK11Attribute *next;
PK11Attribute *prev;
-#ifdef REF_COUNT_ATTRIBUTE
+ PRBool freeAttr;
+ PRBool freeData;
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
int refCount;
PZLock *refLock;
#endif
/*must be called handle to make pk11queue_find work */
CK_ATTRIBUTE_TYPE handle;
CK_ATTRIBUTE attrib;
-#ifdef NO_ARENA
+#ifdef PKCS11_STATIC_ATTRIBUTES
unsigned char space[ATTR_SPACE];
#endif
};
@@ -145,27 +191,33 @@ struct PK11ObjectListStr {
*/
struct PK11ObjectStr {
PK11Object *next;
- PK11Object *prev;
- PK11ObjectList sessionList;
- CK_OBJECT_HANDLE handle;
-#ifdef NO_ARENA
- int nextAttr;
-#else
- PLArenaPool *arena;
-#endif
- int refCount;
+ PK11Object *prev;
+ CK_OBJECT_CLASS objclass;
+ CK_OBJECT_HANDLE handle;
+ int refCount;
PZLock *refLock;
- PZLock *attributeLock;
- PK11Session *session;
PK11Slot *slot;
- CK_OBJECT_CLASS objclass;
void *objectInfo;
PK11Free infoFree;
- char *label;
- PRBool inDB;
+#ifndef PKCS11_STATIC_ATTRIBUTES
+ PLArenaPool *arena;
+#endif
+};
+
+struct PK11TokenObjectStr {
+ PK11Object obj;
+ SECItem dbKey;
+};
+
+struct PK11SessionObjectStr {
+ PK11Object obj;
+ PK11ObjectList sessionList;
+ PZLock *attributeLock;
+ PK11Session *session;
PRBool wasDerived;
PK11Attribute *head[ATTRIBUTE_HASH_SIZE];
-#ifdef NO_ARENA
+#ifdef PKCS11_STATIC_ATTRIBUTES
+ int nextAttr;
PK11Attribute attrList[MAX_OBJS_ATTRS];
#endif
};
@@ -185,6 +237,7 @@ struct PK11SearchResultsStr {
CK_OBJECT_HANDLE *handles;
int size;
int index;
+ int array_size;
};
@@ -227,6 +280,7 @@ struct PK11SessionContextStr {
PK11Destroy hashdestroy;
PK11Verify verify;
unsigned int maxLen;
+ PK11Object *key;
};
/*
@@ -264,12 +318,20 @@ struct PK11SlotStr {
PRBool ssoLoggedIn;
PRBool needLogin;
PRBool DB_loaded;
+ PRBool readOnly;
+ NSSLOWCERTCertDBHandle *certDB;
+ NSSLOWKEYDBHandle *keyDB;
+ int minimumPinLen;
int sessionIDCount;
int sessionCount;
int rwSessionCount;
int tokenIDCount;
+ int index;
+ PLHashTable *tokenHashTable;
PK11Object *tokObjects[TOKEN_OBJECT_HASH_SIZE];
PK11Session *head[SESSION_HASH_SIZE];
+ char tokDescription[33];
+ char slotDescription[64];
};
/*
@@ -277,12 +339,12 @@ struct PK11SlotStr {
*/
struct PK11HashVerifyInfoStr {
SECOidTag hashOid;
- SECKEYLowPublicKey *key;
+ NSSLOWKEYPublicKey *key;
};
struct PK11HashSignInfoStr {
SECOidTag hashOid;
- SECKEYLowPrivateKey *key;
+ NSSLOWKEYPrivateKey *key;
};
/* context for the Final SSLMAC message */
@@ -300,8 +362,7 @@ struct PK11SSLMACInfoStr {
/*
* session handle modifiers
*/
-#define PK11_PRIVATE_KEY_FLAG 0x80000000L
-#define PK11_FIPS_FLAG 0x40000000L
+#define PK11_SESSION_SLOT_MASK 0xff000000L
/*
* object handle modifiers
@@ -309,10 +370,17 @@ struct PK11SSLMACInfoStr {
#define PK11_TOKEN_MASK 0x80000000L
#define PK11_TOKEN_MAGIC 0x80000000L
#define PK11_TOKEN_TYPE_MASK 0x70000000L
-#define PK11_TOKEN_TYPE_CERT 0x00000000L
+/* keydb (high bit == 0) */
#define PK11_TOKEN_TYPE_PRIV 0x10000000L
#define PK11_TOKEN_TYPE_PUB 0x20000000L
-
+#define PK11_TOKEN_TYPE_KEY 0x30000000L
+/* certdb (high bit == 1) */
+#define PK11_TOKEN_TYPE_TRUST 0x40000000L
+#define PK11_TOKEN_TYPE_CRL 0x50000000L
+#define PK11_TOKEN_TYPE_SMIME 0x60000000L
+#define PK11_TOKEN_TYPE_CERT 0x70000000L
+
+#define PK11_TOKEN_KRL_HANDLE (PK11_TOKEN_MAGIC|PK11_TOKEN_TYPE_CRL|0)
/* how big a password/pin we can deal with */
#define PK11_MAX_PIN 255
@@ -351,27 +419,36 @@ struct PK11SSLMACInfoStr {
#define pk11_attr_expand(ap) (ap)->type,(ap)->pValue,(ap)->ulValueLen
#define pk11_item_expand(ip) (ip)->data,(ip)->len
-typedef struct pk11_parametersStr {
+typedef struct pk11_token_parametersStr {
+ CK_SLOT_ID slotID;
char *configdir;
char *certPrefix;
char *keyPrefix;
- char *secmodName;
- char *man;
- char *libdes;
char *tokdes;
- char *ptokdes;
char *slotdes;
- char *pslotdes;
- char *fslotdes;
- char *fpslotdes;
int minPW;
PRBool readOnly;
PRBool noCertDB;
+ PRBool noKeyDB;
+ PRBool forceOpen;
+ PRBool pwRequired;
+} pk11_token_parameters;
+
+typedef struct pk11_parametersStr {
+ char *configdir;
+ char *secmodName;
+ char *man;
+ char *libdes;
+ PRBool readOnly;
PRBool noModDB;
+ PRBool noCertDB;
PRBool forceOpen;
PRBool pwRequired;
+ pk11_token_parameters *tokens;
+ int token_count;
} pk11_parameters;
+
/* machine dependent path stuff used by dbinit.c and pk11db.c */
#ifdef macintosh
#define PATH_SEPARATOR ":"
@@ -387,9 +464,9 @@ typedef struct pk11_parametersStr {
SEC_BEGIN_PROTOS
+extern CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS);
/* shared functions between PKCS11.c and PK11FIPS.c */
-extern CK_RV PK11_LowInitialize(CK_VOID_PTR pReserved);
-extern CK_RV PK11_SlotInit(CK_SLOT_ID slotID, PRBool needLogin);
+extern CK_RV PK11_SlotInit(char *configdir,pk11_token_parameters *params);
/* internal utility functions used by pkcs11.c */
extern PK11Attribute *pk11_FindAttribute(PK11Object *object,
@@ -422,14 +499,14 @@ extern CK_RV pk11_defaultAttribute(PK11Object *object, CK_ATTRIBUTE_TYPE type,
extern PK11Object *pk11_NewObject(PK11Slot *slot);
extern CK_RV pk11_CopyObject(PK11Object *destObject, PK11Object *srcObject);
extern PK11FreeStatus pk11_FreeObject(PK11Object *object);
-extern void pk11_DeleteObject(PK11Session *session, PK11Object *object);
+extern CK_RV pk11_DeleteObject(PK11Session *session, PK11Object *object);
extern void pk11_ReferenceObject(PK11Object *object);
extern PK11Object *pk11_ObjectFromHandle(CK_OBJECT_HANDLE handle,
PK11Session *session);
extern void pk11_AddSlotObject(PK11Slot *slot, PK11Object *object);
extern void pk11_AddObject(PK11Session *session, PK11Object *object);
-extern CK_RV pk11_searchObjectList(PK11ObjectListElement **objectList,
+extern CK_RV pk11_searchObjectList(PK11SearchResults *search,
PK11Object **head, PZLock *lock,
CK_ATTRIBUTE_PTR inTemplate, int count,
PRBool isLoggedIn);
@@ -449,15 +526,16 @@ extern void pk11_update_state(PK11Slot *slot,PK11Session *session);
extern void pk11_update_all_states(PK11Slot *slot);
extern void pk11_FreeContext(PK11SessionContext *context);
-extern SECKEYLowPublicKey *pk11_GetPubKey(PK11Object *object,
+extern NSSLOWKEYPublicKey *pk11_GetPubKey(PK11Object *object,
CK_KEY_TYPE key_type);
-extern SECKEYLowPrivateKey *pk11_GetPrivKey(PK11Object *object,
+extern NSSLOWKEYPrivateKey *pk11_GetPrivKey(PK11Object *object,
CK_KEY_TYPE key_type);
extern void pk11_FormatDESKey(unsigned char *key, int length);
extern PRBool pk11_CheckDESKey(unsigned char *key);
extern PRBool pk11_IsWeakKey(unsigned char *key,CK_KEY_TYPE key_type);
-extern CK_RV secmod_parseParameters(char *param, pk11_parameters *parsed);
+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);
@@ -481,10 +559,26 @@ extern SECStatus secmod_AddPermDB(char *dbname, char *module, PRBool rw);
* be opened.
*/
CK_RV pk11_DBInit(const char *configdir, const char *certPrefix,
- const char *keyPrefix, const char *secmodName, PRBool readOnly,
- PRBool noCertDB, PRBool noModDB, PRBool forceOpen);
+ const char *keyPrefix, PRBool readOnly, PRBool noCertDB,
+ PRBool noKeyDB, PRBool forceOpen,
+ NSSLOWCERTCertDBHandle **certDB, NSSLOWKEYDBHandle **keyDB);
+/*
+ * narrow objects
+ */
+PK11SessionObject * pk11_narrowToSessionObject(PK11Object *);
+PK11TokenObject * pk11_narrowToTokenObject(PK11Object *);
+/*
+ * token object utilities
+ */
+void pk11_addHandle(PK11SearchResults *search, CK_OBJECT_HANDLE handle);
+PRBool pk11_tokenMatch(PK11Slot *slot, SECItem *dbKey, CK_OBJECT_HANDLE class,
+ CK_ATTRIBUTE_PTR theTemplate,int count);
+CK_OBJECT_HANDLE pk11_mkHandle(PK11Slot *slot,
+ SECItem *dbKey, CK_OBJECT_HANDLE class);
+PK11Object * pk11_NewTokenObject(PK11Slot *slot, SECItem *dbKey,
+ CK_OBJECT_HANDLE handle);
SEC_END_PROTOS
#endif /* _PKCS11I_H_ */
diff --git a/security/nss/lib/softoken/pkcs11t.h b/security/nss/lib/softoken/pkcs11t.h
index aa3d70496..124a1bb27 100644
--- a/security/nss/lib/softoken/pkcs11t.h
+++ b/security/nss/lib/softoken/pkcs11t.h
@@ -17,7 +17,6 @@
* Rights Reserved.
*
* Contributor(s):
- * Dr Stephen Henson <stephen.henson@gemplus.com>
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@@ -61,12 +60,17 @@
#define CK_DECLARE_FUNCTION(rv,func) PR_EXTERN(rv) func
#define CK_DECLARE_FUNCTION_POINTER(rv,func) rv (PR_CALLBACK * func)
+#define CK_INVALID_SESSION 0
+
/* an unsigned 8-bit value */
typedef unsigned char CK_BYTE;
/* an unsigned 8-bit character */
typedef CK_BYTE CK_CHAR;
+/* an unsigned 8-bit character */
+typedef CK_BYTE CK_UTF8CHAR;
+
/* a BYTE-sized Boolean flag */
typedef CK_BYTE CK_BBOOL;
@@ -88,6 +92,7 @@ typedef CK_ULONG CK_FLAGS;
typedef CK_BYTE CK_PTR CK_BYTE_PTR;
typedef CK_CHAR CK_PTR CK_CHAR_PTR;
+typedef CK_UTF8CHAR CK_PTR CK_UTF8CHAR_PTR;
typedef CK_ULONG CK_PTR CK_ULONG_PTR;
typedef void CK_PTR CK_VOID_PTR;
@@ -112,12 +117,14 @@ typedef CK_VERSION CK_PTR CK_VERSION_PTR;
typedef struct CK_INFO {
+ /* manufacturerID and libraryDecription have been changed from
+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
CK_VERSION cryptokiVersion; /* PKCS #11 interface ver */
- CK_CHAR manufacturerID[32]; /* blank padded */
+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
CK_FLAGS flags; /* must be zero */
/* libraryDescription and libraryVersion are new for v2.0 */
- CK_CHAR libraryDescription[32]; /* blank padded */
+ CK_UTF8CHAR libraryDescription[32]; /* blank padded */
CK_VERSION libraryVersion; /* version of library */
} CK_INFO;
@@ -139,8 +146,10 @@ typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
/* CK_SLOT_INFO provides information about a slot */
typedef struct CK_SLOT_INFO {
- CK_CHAR slotDescription[64]; /* blank padded */
- CK_CHAR manufacturerID[32]; /* blank padded */
+ /* slotDescription and manufacturerID have been changed from
+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
+ CK_UTF8CHAR slotDescription[64]; /* blank padded */
+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
CK_FLAGS flags;
/* hardwareVersion and firmwareVersion are new for v2.0 */
@@ -160,9 +169,11 @@ typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
/* CK_TOKEN_INFO provides information about a token */
typedef struct CK_TOKEN_INFO {
- CK_CHAR label[32]; /* blank padded */
- CK_CHAR manufacturerID[32]; /* blank padded */
- CK_CHAR model[16]; /* blank padded */
+ /* label, manufacturerID, and model have been changed from
+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
+ CK_UTF8CHAR label[32]; /* blank padded */
+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
+ CK_UTF8CHAR model[16]; /* blank padded */
CK_CHAR serialNumber[16]; /* blank padded */
CK_FLAGS flags; /* see below */
@@ -223,6 +234,57 @@ typedef struct CK_TOKEN_INFO {
* and sign) */
#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200
+/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
+ * token has been initialized using C_InitializeToken or an
+ * equivalent mechanism outside the scope of PKCS #11.
+ * Calling C_InitializeToken when this flag is set will cause
+ * the token to be reinitialized. */
+#define CKF_TOKEN_INITIALIZED 0x00000400
+
+/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
+ * true, the token supports secondary authentication for
+ * private key objects. */
+/* DEPRICATED in v2.11 */
+#define CKF_SECONDARY_AUTHENTICATION 0x00000800
+
+/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
+ * incorrect user login PIN has been entered at least once
+ * since the last successful authentication. */
+#define CKF_USER_PIN_COUNT_LOW 0x00010000
+
+/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
+ * supplying an incorrect user PIN will it to become locked. */
+#define CKF_USER_PIN_FINAL_TRY 0x00020000
+
+/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
+ * user PIN has been locked. User login to the token is not
+ * possible. */
+#define CKF_USER_PIN_LOCKED 0x00040000
+
+/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
+ * the user PIN value is the default value set by token
+ * initialization or manufacturing. */
+#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000
+
+/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
+ * incorrect SO login PIN has been entered at least once since
+ * the last successful authentication. */
+#define CKF_SO_PIN_COUNT_LOW 0x00100000
+
+/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
+ * supplying an incorrect SO PIN will it to become locked. */
+#define CKF_SO_PIN_FINAL_TRY 0x00200000
+
+/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
+ * PIN has been locked. SO login to the token is not possible.
+ */
+#define CKF_SO_PIN_LOCKED 0x00400000
+
+/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
+ * the SO PIN value is the default value set by token
+ * initialization or manufacturing. */
+#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000
+
typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
@@ -289,15 +351,28 @@ typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
typedef CK_ULONG CK_OBJECT_CLASS;
/* The following classes of objects are defined: */
-#define CKO_DATA 0x00000000
-#define CKO_CERTIFICATE 0x00000001
-#define CKO_PUBLIC_KEY 0x00000002
-#define CKO_PRIVATE_KEY 0x00000003
-#define CKO_SECRET_KEY 0x00000004
-#define CKO_VENDOR_DEFINED 0x80000000
+/* CKO_HW_FEATURE is new for v2.10 */
+/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
+#define CKO_DATA 0x00000000
+#define CKO_CERTIFICATE 0x00000001
+#define CKO_PUBLIC_KEY 0x00000002
+#define CKO_PRIVATE_KEY 0x00000003
+#define CKO_SECRET_KEY 0x00000004
+#define CKO_HW_FEATURE 0x00000005
+#define CKO_DOMAIN_PARAMETERS 0x00000006
+#define CKO_VENDOR_DEFINED 0x80000000
typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
+/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a
+ * value that identifies the hardware feature type of an object
+ * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
+typedef CK_ULONG CK_HW_FEATURE_TYPE;
+
+/* The following hardware feature types are defined */
+#define CKH_MONOTONIC_COUNTER 0x00000001
+#define CKH_CLOCK 0x00000002
+#define CKH_VENDOR_DEFINED 0x80000000
/* CK_KEY_TYPE is a value that identifies a key type */
/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
@@ -309,10 +384,10 @@ typedef CK_ULONG CK_KEY_TYPE;
#define CKK_DH 0x00000002
/* CKK_ECDSA and CKK_KEA are new for v2.0 */
-
-/* PKCS #11 V2.01 probably won't actually have ECDSA in it */
-#define CKK_ECDSA 0x00000003
-
+/* CKK_X9_42_DH is new for v2.11 */
+#define CKK_ECDSA 0x00000003 /* deprecated in v2.11 */
+#define CKK_EC 0x00000003
+#define CKK_X9_42_DH 0x00000004
#define CKK_KEA 0x00000005
#define CKK_GENERIC_SECRET 0x00000010
@@ -325,8 +400,8 @@ typedef CK_ULONG CK_KEY_TYPE;
/* all these key types are new for v2.0 */
#define CKK_CAST 0x00000016
#define CKK_CAST3 0x00000017
-#define CKK_CAST5 0x00000018
-#define CKK_CAST128 0x00000018 /* CAST128=CAST5 */
+#define CKK_CAST5 0x00000018 /* deprecated in v2.11 */
+#define CKK_CAST128 0x00000018
#define CKK_RC5 0x00000019
#define CKK_IDEA 0x0000001A
#define CKK_SKIPJACK 0x0000001B
@@ -348,7 +423,9 @@ typedef CK_ULONG CK_KEY_TYPE;
typedef CK_ULONG CK_CERTIFICATE_TYPE;
/* The following certificate types are defined: */
+/* CKC_X_509_ATTR_CERT is new for v2.10 */
#define CKC_X_509 0x00000000
+#define CKC_X_509_ATTR_CERT 0x00000001
#define CKC_VENDOR_DEFINED 0x80000000
@@ -365,9 +442,22 @@ typedef CK_ULONG CK_ATTRIBUTE_TYPE;
#define CKA_LABEL 0x00000003
#define CKA_APPLICATION 0x00000010
#define CKA_VALUE 0x00000011
+
+/* CKA_OBJECT_ID is new for v2.10 */
+#define CKA_OBJECT_ID 0x00000012
+
#define CKA_CERTIFICATE_TYPE 0x00000080
#define CKA_ISSUER 0x00000081
#define CKA_SERIAL_NUMBER 0x00000082
+
+/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
+ * for v2.10 */
+#define CKA_AC_ISSUER 0x00000083
+#define CKA_OWNER 0x00000084
+#define CKA_ATTR_TYPES 0x00000085
+/* CKA_TRUSTED is new for v2.11 */
+#define CKA_TRUSTED 0x00000086
+
#define CKA_KEY_TYPE 0x00000100
#define CKA_SUBJECT 0x00000101
#define CKA_ID 0x00000102
@@ -395,16 +485,34 @@ typedef CK_ULONG CK_ATTRIBUTE_TYPE;
#define CKA_PRIME 0x00000130
#define CKA_SUBPRIME 0x00000131
#define CKA_BASE 0x00000132
+/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
+#define CKA_PRIME_BITS 0x00000133
+#define CKA_SUB_PRIME_BITS 0x00000134
#define CKA_VALUE_BITS 0x00000160
#define CKA_VALUE_LEN 0x00000161
/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
- * CKA_ALWAYS_SENSITIVE, and CKA_MODIFIABLE are new for v2.0 */
+ * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
+ * and CKA_EC_POINT are new for v2.0 */
#define CKA_EXTRACTABLE 0x00000162
#define CKA_LOCAL 0x00000163
#define CKA_NEVER_EXTRACTABLE 0x00000164
#define CKA_ALWAYS_SENSITIVE 0x00000165
+/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
+#define CKA_KEY_GEN_MECHANISM 0x00000166
#define CKA_MODIFIABLE 0x00000170
+#define CKA_ECDSA_PARAMS 0x00000180 /* depricated v2.11 */
+#define CKA_EC_PARAMS 0x00000180
+#define CKA_EC_POINT 0x00000181
+
+/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
+ * CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
+ * are new for v2.10 */
+#define CKA_SECONDARY_AUTH 0x00000200 /* depricated v2.11 */
+#define CKA_AUTH_PIN_FLAGS 0x00000201 /* depricated v2.11 */
+#define CKA_HW_FEATURE_TYPE 0x00000300
+#define CKA_RESET_ON_INIT 0x00000301
+#define CKA_HAS_RESET 0x00000302
#define CKA_VENDOR_DEFINED 0x80000000
@@ -448,11 +556,32 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_MD5_RSA_PKCS 0x00000005
#define CKM_SHA1_RSA_PKCS 0x00000006
+/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS & CKM_RSA_OAEP
+ * are new for 2.10 */
+#define CKM_RIPEMD128_RSA_PKCS 0x00000007
+#define CKM_RIPEMD160_RSA_PKCS 0x00000008
+#define CKM_RSA_PKCS_OAEP 0x00000009
+
+/* CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31 & CKM_RSA_X9_31_KEY_PAIR_GEN
+ * are new for 2.11 */
+#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000A
+#define CKM_RSA_X9_31 0x0000000B
+#define CKM_SHA1_RSA_X9_31 0x0000000C
+
#define CKM_DSA_KEY_PAIR_GEN 0x00000010
#define CKM_DSA 0x00000011
#define CKM_DSA_SHA1 0x00000012
#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020
#define CKM_DH_PKCS_DERIVE 0x00000021
+
+/* CKM_X9_42_DH_PKCS_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
+ * CKM_X9_42_DH_HYBRID_DERIVE, & CKM_X9_42_MQV_DERIVE
+ * are new for v2.11 */
+#define CKM_X9_42_DH_PKCS_KEY_PAIR_GEN 0x00000030
+#define CKM_X9_42_DH_DERIVE 0x00000031
+#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032
+#define CKM_X9_42_MQV_DERIVE 0x00000033
+
#define CKM_RC2_KEY_GEN 0x00000100
#define CKM_RC2_ECB 0x00000101
#define CKM_RC2_CBC 0x00000102
@@ -509,6 +638,16 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_SHA_1_HMAC 0x00000221
#define CKM_SHA_1_HMAC_GENERAL 0x00000222
+/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
+ * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
+ * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
+#define CKM_RIPEMD128 0x00000230
+#define CKM_RIPEMD128_HMAC 0x00000231
+#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232
+#define CKM_RIPEMD160 0x00000240
+#define CKM_RIPEMD160_HMAC 0x00000241
+#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242
+
/* All of the following mechanisms are new for v2.0 */
/* Note that CAST128 and CAST5 are the same algorithm */
#define CKM_CAST_KEY_GEN 0x00000300
@@ -556,6 +695,17 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370
#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371
#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372
+
+/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
+ * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE,
+ * CKM_TLS_MASTER_KEY_DERIVE_DH, & CKM_SSL3_MASTER_KEY_DERIVE_DH
+ * are new for v2.11. */
+#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373
+#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374
+#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375
+#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376
+#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377
+
#define CKM_SSL3_MD5_MAC 0x00000380
#define CKM_SSL3_SHA1_MAC 0x00000381
#define CKM_MD5_KEY_DERIVATION 0x00000390
@@ -575,6 +725,10 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9
#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AA
#define CKM_PBE_SHA1_RC2_40_CBC 0x000003AB
+
+/* CKM_PKCS5_PBKD2 is new for v2.10 */
+#define CKM_PKCS5_PBKD2 0x000003B0
+
#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0
#define CKM_KEY_WRAP_LYNKS 0x00000400
#define CKM_KEY_WRAP_SET_OAEP 0x00000401
@@ -601,12 +755,16 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_BATON_COUNTER 0x00001034
#define CKM_BATON_SHUFFLE 0x00001035
#define CKM_BATON_WRAP 0x00001036
-
-/* PKCS #11 V2.01 probably won't actually have ECDSA in it */
-#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040
+#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040 /* depricated in v2.11 */
+#define CKM_EC_KEY_PAIR_GEN 0x00001040
#define CKM_ECDSA 0x00001041
#define CKM_ECDSA_SHA1 0x00001042
+/* ECDH1 is new for 2.11 */
+#define CKM_ECDH1_DERIVE 0x00001043
+#define CKM_ECDH1_COFACTOR_DERIVE 0x00001044
+#define CKM_ECMQV_DERIVE 0x00001045
+
#define CKM_JUNIPER_KEY_GEN 0x00001060
#define CKM_JUNIPER_ECB128 0x00001061
#define CKM_JUNIPER_CBC128 0x00001062
@@ -615,6 +773,7 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_JUNIPER_WRAP 0x00001065
#define CKM_FASTHASH 0x00001070
+/* AES is new for 2.11 */
#define CKM_AES_KEY_GEN 0x00001080
#define CKM_AES_ECB 0x00001081
#define CKM_AES_CBC 0x00001082
@@ -622,6 +781,12 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_AES_MAC_GENERAL 0x00001084
#define CKM_AES_CBC_PAD 0x00001085
+/* CKM_DSA_PARAMETER_GEN, CKM_DH_PKCS_PARAMETER_GEN,
+ * and CKM_DH_X9_42_PARAMETER_GEN are new for 2.11 */
+#define CKM_DSA_PARAMETER_GEN 0x00002000
+#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001
+#define CKM_DH_X9_42_PARAMETER_GEN 0x00002002
+
#define CKM_VENDOR_DEFINED 0x80000000
typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
@@ -658,6 +823,8 @@ typedef struct CK_MECHANISM_INFO {
* CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
* and CKF_DERIVE are new for v2.0. They specify whether or not
* a mechanism can be used for a particular task */
+/* The flags CKF_EC_FP, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
+ * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11 */
#define CKF_ENCRYPT 0x00000100
#define CKF_DECRYPT 0x00000200
#define CKF_DIGEST 0x00000400
@@ -670,6 +837,12 @@ typedef struct CK_MECHANISM_INFO {
#define CKF_WRAP 0x00020000
#define CKF_UNWRAP 0x00040000
#define CKF_DERIVE 0x00080000
+#define CKF_EC_FP 0x00100000
+#define CKF_EC_F_2M 0x00200000
+#define CKF_EC_ECPARAMETERS 0x00400000
+#define CKF_EC_NAMEDCURVE 0x00800000
+#define CKF_EC_UNCOMPRESS 0x01000000
+#define CKF_EC_COMPRESS 0x02000000
#define CKF_EXTENSION 0x80000000 /* FALSE for 2.01 */
@@ -735,6 +908,9 @@ typedef CK_ULONG CK_RV;
#define CKR_KEY_NOT_WRAPPABLE 0x00000069
#define CKR_KEY_UNEXTRACTABLE 0x0000006A
+/* CKR_KEY_PARAMS_INVALID is new for v2.11 */
+#define CKR_KEY_PARAMS_INVALID 0x0000006B
+
#define CKR_MECHANISM_INVALID 0x00000070
#define CKR_MECHANISM_PARAM_INVALID 0x00000071
@@ -790,8 +966,13 @@ typedef CK_ULONG CK_RV;
#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115
#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120
-/* These are new to v2.0 */
+/* New for v2.0 */
#define CKR_RANDOM_NO_RNG 0x00000121
+
+/* New for v2.11 */
+#define CKR_DOMAIN_PARAMS_INVALID 0x00000130
+
+/* These are new to v2.0 */
#define CKR_BUFFER_TOO_SMALL 0x00000150
#define CKR_SAVED_STATE_INVALID 0x00000160
#define CKR_INFORMATION_SENSITIVE 0x00000170
@@ -878,6 +1059,41 @@ typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
#define CKF_DONT_BLOCK 1
+/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
+ * CK_RSA_PKCS_OAEP_MGF_TYPE is used to indicate the Message
+ * Generation Function (MGF) applied to a message block when
+ * formatting a message block for the PKCS #1 OAEP encryption
+ * scheme. */
+typedef CK_ULONG CK_RSA_PKCS_OAEP_MGF_TYPE;
+
+typedef CK_RSA_PKCS_OAEP_MGF_TYPE CK_PTR CK_RSA_PKCS_OAEP_MGF_TYPE_PTR;
+
+/* The following MGFs are defined */
+#define CKG_MGF1_SHA1 0x00000001
+
+/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
+ * CK_RSA_PKCS_OAEP_SOURCE_TYPE is used to indicate the source
+ * of the encoding parameter when formatting a message block
+ * for the PKCS #1 OAEP encryption scheme. */
+typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
+
+typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
+
+/* The following encoding parameter sources are defined */
+#define CKZ_DATA_SPECIFIED 0x00000001
+
+/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
+ * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
+ * CKM_RSA_PKCS_OAEP mechanism. */
+typedef struct CK_RSA_PKCS_OAEP_PARAMS {
+ CK_MECHANISM_TYPE hashAlg;
+ CK_RSA_PKCS_OAEP_MGF_TYPE mgf;
+ CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
+ CK_VOID_PTR pSourceData;
+ CK_ULONG ulSourceDataLen;
+} CK_RSA_PKCS_OAEP_PARAMS;
+
+typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
/* CK_KEA_DERIVE_PARAMS provides the parameters to the
* CKM_KEA_DERIVE mechanism */
@@ -1102,36 +1318,46 @@ typedef CK_ULONG CK_EXTRACT_PARAMS;
typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
-/* Do not attempt to use these. They are only used by NETSCAPE's internal
- * PKCS #11 interface. Most of these are place holders for other mechanism
- * and will change in the future.
- */
-#define CKM_NETSCAPE_PBE_KEY_GEN 0x80000001L
-#define CKM_NETSCAPE_PBE_SHA1_DES_CBC 0x80000002L
-#define CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC 0x80000003L
-#define CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC 0x80000004L
-#define CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC 0x80000005L
-#define CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4 0x80000006L
-#define CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4 0x80000007L
-#define CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC 0x80000008L
-#define CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN 0x80000009L
-#define CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN 0x8000000aL
-#define CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN 0x8000000bL
-#define CKM_TLS_MASTER_KEY_DERIVE 0x80000371L
-#define CKM_TLS_KEY_AND_MAC_DERIVE 0x80000372L
-#define CKM_TLS_PRF_GENERAL 0x80000373L
-#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x80000374L
-#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x80000375L
-
-/* define used to pass in the database key for DSA private keys */
-#define CKA_NETSCAPE_DB 0xD5A0DB00L
-#define CKA_NETSCAPE_TRUST 0x80000001L
-
-#define SECMOD_MODULE_DB_FUNCTION_FIND 0
-#define SECMOD_MODULE_DB_FUNCTION_ADD 1
-#define SECMOD_MODULE_DB_FUNCTION_DEL 2
-typedef char ** (PR_CALLBACK *SECMODModuleDBFunc)(unsigned long function,
- char *parameters, char *moduleSpec);
+/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
+ * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
+ * indicate the Pseudo-Random Function (PRF) used to generate
+ * key bits using PKCS #5 PBKDF2. */
+typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
+
+typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
+
+/* The following PRFs are defined in PKCS #5 v2.0. */
+#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
+
+
+/* CK_PKCS5_PBKD2_SALT_SOURCE_TYPE is new for v2.10.
+ * CK_PKCS5_PBKD2_SALT_SOURCE_TYPE is used to indicate the
+ * source of the salt value when deriving a key using PKCS #5
+ * PBKDF2. */
+typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
+
+typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
+
+/* The following salt value sources are defined in PKCS #5 v2.0. */
+#define CKZ_SALT_SPECIFIED 0x00000001
+
+/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
+ * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
+ * parameters to the CKM_PKCS5_PBKD2 mechanism. */
+typedef struct CK_PKCS5_PBKD2_PARAMS {
+ CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
+ CK_VOID_PTR pSaltSourceData;
+ CK_ULONG ulSaltSourceDataLen;
+ CK_ULONG iterations;
+ CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
+ CK_VOID_PTR pPrfData;
+ CK_ULONG ulPrfDataLen;
+} CK_PKCS5_PBKD2_PARAMS;
+
+typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
+
+/* Netscape Specific defines */
+#include "pkcs11n.h"
/* undo packing */
#include "pkcs11u.h"
diff --git a/security/nss/lib/softoken/pkcs11u.c b/security/nss/lib/softoken/pkcs11u.c
index 0aa42823a..1c8cd821a 100644
--- a/security/nss/lib/softoken/pkcs11u.c
+++ b/security/nss/lib/softoken/pkcs11u.c
@@ -35,18 +35,10 @@
*/
#include "pkcs11.h"
#include "pkcs11i.h"
-#include "key.h"
-#include "keylow.h"
-#include "certdb.h"
-
-
-/* declare the internal pkcs11 slot structures:
- * There are threee:
- * slot 0 is the generic crypto service token.
- * slot 1 is the Database service token.
- * slot 2 is the FIPS token (both generic and database).
- */
-static PK11Slot pk11_slot[3];
+#include "pcertt.h"
+#include "lowkeyi.h"
+#include "pcert.h"
+#include "secasn1.h"
/*
* ******************** Attribute Utilities *******************************
@@ -62,27 +54,36 @@ pk11_NewAttribute(PK11Object *object,
{
PK11Attribute *attribute;
-#ifdef NO_ARENA
+#ifdef PKCS11_STATIC_ATTRIBUTES
+ PK11SessionObject *so = pk11_narrowToSessionObject(object);
int index;
+
+ if (so == NULL) {
+ /* allocate new attribute in a buffer */
+ PORT_Assert(0);
+ }
/*
- * NO_ARENA attempts to keep down contention on Malloc and Arena locks
+ * PKCS11_STATIC_ATTRIBUTES attempts to keep down contention on Malloc and Arena locks
* by limiting the number of these calls on high traversed paths. this
* is done for attributes by 'allocating' them from a pool already allocated
* by the parent object.
*/
- PK11_USE_THREADS(PZ_Lock(object->attributeLock);)
- index = object->nextAttr++;
- PK11_USE_THREADS(PZ_Unlock(object->attributeLock);)
+ PK11_USE_THREADS(PZ_Lock(so->attributeLock);)
+ index = so->nextAttr++;
+ PK11_USE_THREADS(PZ_Unlock(so->attributeLock);)
PORT_Assert(index < MAX_OBJS_ATTRS);
if (index >= MAX_OBJS_ATTRS) return NULL;
- attribute = &object->attrList[index];
+ attribute = &so->attrList[index];
attribute->attrib.type = type;
+ attribute->freeAttr = PR_FALSE;
+ attribute->freeData = PR_FALSE;
if (value) {
if (len <= ATTR_SPACE) {
attribute->attrib.pValue = attribute->space;
} else {
attribute->attrib.pValue = PORT_Alloc(len);
+ attribute->freeData = PR_TRUE;
}
if (attribute->attrib.pValue == NULL) {
return NULL;
@@ -94,23 +95,27 @@ pk11_NewAttribute(PK11Object *object,
attribute->attrib.ulValueLen = 0;
}
#else
-#ifdef REF_COUNT_ATTRIBUTE
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
attribute = (PK11Attribute*)PORT_Alloc(sizeof(PK11Attribute));
+ attribute->freeAttr = PR_TRUE;
#else
attribute = (PK11Attribute*)PORT_ArenaAlloc(object->arena,sizeof(PK11Attribute));
-#endif /* REF_COUNT_ATTRIBUTE */
+ attribute->freeAttr = PR_FALSE;
+#endif /* PKCS11_REF_COUNT_ATTRIBUTES */
if (attribute == NULL) return NULL;
+ attribute->freeData = PR_FALSE;
if (value) {
-#ifdef REF_COUNT_ATTRIBUTE
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
attribute->attrib.pValue = PORT_Alloc(len);
+ attribute->freeData = PR_TRUE;
#else
attribute->attrib.pValue = PORT_ArenaAlloc(object->arena,len);
-#endif /* REF_COUNT_ATTRIBUTE */
+#endif /* PKCS11_REF_COUNT_ATTRIBUTES */
if (attribute->attrib.pValue == NULL) {
-#ifdef REF_COUNT_ATTRIBUTE
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
PORT_Free(attribute);
-#endif /* REF_COUNT_ATTRIBUTE */
+#endif /* PKCS11_REF_COUNT_ATTRIBUTES */
return NULL;
}
PORT_Memcpy(attribute->attrib.pValue,value,len);
@@ -119,11 +124,11 @@ pk11_NewAttribute(PK11Object *object,
attribute->attrib.pValue = NULL;
attribute->attrib.ulValueLen = 0;
}
-#endif /* NO_ARENA */
+#endif /* PKCS11_STATIC_ATTRIBUTES */
attribute->attrib.type = type;
attribute->handle = type;
attribute->next = attribute->prev = NULL;
-#ifdef REF_COUNT_ATTRIBUTE
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
attribute->refCount = 1;
#ifdef PKCS11_USE_THREADS
attribute->refLock = PZ_NewLock(nssILockRefLock);
@@ -135,31 +140,893 @@ pk11_NewAttribute(PK11Object *object,
#else
attribute->refLock = NULL;
#endif
-#endif /* REF_COUNT_ATTRIBUTE */
+#endif /* PKCS11_REF_COUNT_ATTRIBUTES */
+ return attribute;
+}
+
+static PK11Attribute *
+pk11_NewTokenAttribute(CK_ATTRIBUTE_TYPE type, CK_VOID_PTR value,
+ CK_ULONG len, PRBool copy)
+{
+ PK11Attribute *attribute;
+
+ attribute = (PK11Attribute*)PORT_Alloc(sizeof(PK11Attribute));
+
+ if (attribute == NULL) return NULL;
+ attribute->attrib.type = type;
+ attribute->handle = type;
+ attribute->next = attribute->prev = NULL;
+ attribute->freeAttr = PR_TRUE;
+ attribute->freeData = PR_FALSE;
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
+ attribute->refCount = 1;
+#ifdef PKCS11_USE_THREADS
+ attribute->refLock = PZ_NewLock(nssILockRefLock);
+ if (attribute->refLock == NULL) {
+ PORT_Free(attribute);
+ return NULL;
+ }
+#else
+ attribute->refLock = NULL;
+#endif
+#endif /* PKCS11_REF_COUNT_ATTRIBUTES */
+ attribute->attrib.type = type;
+ if (!copy) {
+ attribute->attrib.pValue = value;
+ attribute->attrib.ulValueLen = len;
+ return attribute;
+ }
+
+ if (value) {
+#ifdef PKCS11_STATIC_ATTRIBUTES
+ if (len <= ATTR_SPACE) {
+ attribute->attrib.pValue = attribute->space;
+ } else {
+ attribute->attrib.pValue = PORT_Alloc(len);
+ attribute->freeData = PR_TRUE;
+ }
+#else
+ attribute->attrib.pValue = PORT_Alloc(len);
+ attribute->freeData = PR_TRUE;
+#endif
+ if (attribute->attrib.pValue == NULL) {
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
+ if (attribute->refLock) {
+ PK11_USE_THREADS(PZ_DestroyLock(attribute->refLock);)
+ }
+#endif
+ PORT_Free(attribute);
+ return NULL;
+ }
+ PORT_Memcpy(attribute->attrib.pValue,value,len);
+ attribute->attrib.ulValueLen = len;
+ } else {
+ attribute->attrib.pValue = NULL;
+ attribute->attrib.ulValueLen = 0;
+ }
return attribute;
}
+static PK11Attribute *
+pk11_NewTokenAttributeSigned(CK_ATTRIBUTE_TYPE type, CK_VOID_PTR value,
+ CK_ULONG len, PRBool copy)
+{
+ unsigned char * dval = (unsigned char *)value;
+ if (*dval == 0) {
+ dval++;
+ len--;
+ }
+ return pk11_NewTokenAttribute(type,dval,len,copy);
+}
+
/*
* Free up all the memory associated with an attribute. Reference count
* must be zero to call this.
*/
-#ifdef REF_COUNT_ATTRIBUTE
static void
pk11_DestroyAttribute(PK11Attribute *attribute)
{
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
PORT_Assert(attribute->refCount == 0);
PK11_USE_THREADS(PZ_DestroyLock(attribute->refLock);)
- if (attribute->attrib.pValue) {
- /* clear out the data in the attribute value... it may have been
- * sensitive data */
- PORT_Memset(attribute->attrib.pValue,0,attribute->attrib.ulValueLen);
- PORT_Free(attribute->attrib.pValue);
+#endif
+ if (attribute->freeData) {
+ if (attribute->attrib.pValue) {
+ /* clear out the data in the attribute value... it may have been
+ * sensitive data */
+ PORT_Memset(attribute->attrib.pValue, 0,
+ attribute->attrib.ulValueLen);
+ }
+ PORT_Free(attribute->attrib.pValue);
}
PORT_Free(attribute);
}
+
+/*
+ * release a reference to an attribute structure
+ */
+void
+pk11_FreeAttribute(PK11Attribute *attribute)
+{
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
+ PRBool destroy = PR_FALSE;
#endif
+
+ if (attribute->freeAttr) {
+ pk11_DestroyAttribute(attribute);
+ return;
+ }
+
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
+ PK11_USE_THREADS(PZ_Lock(attribute->refLock);)
+ if (attribute->refCount == 1) destroy = PR_TRUE;
+ attribute->refCount--;
+ PK11_USE_THREADS(PZ_Unlock(attribute->refLock);)
+
+ if (destroy) pk11_DestroyAttribute(attribute);
+#endif
+}
+
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
+#define PK11_DEF_ATTRIBUTE(value,len) \
+ { NULL, NULL, PR_FALSE, PR_FALSE, 1, NULL, 0, { 0, value, len } }
+
+#else
+#define PK11_DEF_ATTRIBUTE(value,len) \
+ { NULL, NULL, PR_FALSE, PR_FALSE, 0, { 0, value, len } }
+#endif
+
+CK_BBOOL pk11_staticTrueValue = CK_TRUE;
+CK_BBOOL pk11_staticFalseValue = CK_FALSE;
+static const PK11Attribute pk11_StaticTrueAttr =
+ PK11_DEF_ATTRIBUTE(&pk11_staticTrueValue,sizeof(pk11_staticTrueValue));
+static const PK11Attribute pk11_StaticFalseAttr =
+ PK11_DEF_ATTRIBUTE(&pk11_staticFalseValue,sizeof(pk11_staticFalseValue));
+static const PK11Attribute pk11_StaticNullAttr = PK11_DEF_ATTRIBUTE(NULL,0);
+
+CK_CERTIFICATE_TYPE pk11_staticX509Value = CKC_X_509;
+static const PK11Attribute pk11_StaticX509Attr =
+ PK11_DEF_ATTRIBUTE(&pk11_staticX509Value, sizeof(pk11_staticX509Value));
+CK_TRUST pk11_staticTrustedValue = CKT_NETSCAPE_TRUSTED;
+CK_TRUST pk11_staticTrustedDelegatorValue = CKT_NETSCAPE_TRUSTED_DELEGATOR;
+CK_TRUST pk11_staticUnTrustedValue = CKT_NETSCAPE_UNTRUSTED;
+CK_TRUST pk11_staticTrustUnknownValue = CKT_NETSCAPE_TRUST_UNKNOWN;
+CK_TRUST pk11_staticMustVerifyValue = CKT_NETSCAPE_MUST_VERIFY;
+static const PK11Attribute pk11_StaticTrustedAttr =
+ PK11_DEF_ATTRIBUTE(&pk11_staticTrustedValue,
+ sizeof(pk11_staticTrustedValue));
+static const PK11Attribute pk11_StaticTrustedDelegatorAttr =
+ PK11_DEF_ATTRIBUTE(&pk11_staticTrustedDelegatorValue,
+ sizeof(pk11_staticTrustedDelegatorValue));
+static const PK11Attribute pk11_StaticUnTrustedAttr =
+ PK11_DEF_ATTRIBUTE(&pk11_staticUnTrustedValue,
+ sizeof(pk11_staticUnTrustedValue));
+static const PK11Attribute pk11_StaticTrustUnknownAttr =
+ PK11_DEF_ATTRIBUTE(&pk11_staticTrustUnknownValue,
+ sizeof(pk11_staticTrustUnknownValue));
+static const PK11Attribute pk11_StaticMustVerifyAttr =
+ PK11_DEF_ATTRIBUTE(&pk11_staticMustVerifyValue,
+ sizeof(pk11_staticMustVerifyValue));
+
+static void pk11_FreeItem(SECItem *item)
+{
+ SECITEM_FreeItem(item, PR_TRUE);
+}
+
+static certDBEntrySMime *
+pk11_getSMime(PK11TokenObject *object)
+{
+ certDBEntrySMime *entry;
+
+ if (object->obj.objclass != CKO_NETSCAPE_SMIME) {
+ return NULL;
+ }
+ if (object->obj.objectInfo) {
+ return (certDBEntrySMime *)object->obj.objectInfo;
+ }
+
+ entry = nsslowcert_ReadDBSMimeEntry(object->obj.slot->certDB,
+ (char *)object->dbKey.data);
+ object->obj.objectInfo = (void *)entry;
+ object->obj.infoFree = (PK11Free) nsslowcert_DestroyDBEntry;
+ return entry;
+}
+
+static SECItem *
+pk11_getCrl(PK11TokenObject *object)
+{
+ SECItem *crl;
+ PRBool isKrl;
+
+ if (object->obj.objclass != CKO_NETSCAPE_CRL) {
+ return NULL;
+ }
+ if (object->obj.objectInfo) {
+ return (SECItem *)object->obj.objectInfo;
+ }
+
+ isKrl = (PRBool) object->obj.handle == PK11_TOKEN_KRL_HANDLE;
+ crl = nsslowcert_FindCrlByKey(object->obj.slot->certDB,&object->dbKey,
+ NULL,isKrl);
+ object->obj.objectInfo = (void *)crl;
+ object->obj.infoFree = (PK11Free) pk11_FreeItem;
+ return crl;
+}
+
+static char *
+pk11_getUrl(PK11TokenObject *object)
+{
+ SECItem *crl;
+ PRBool isKrl;
+ char *url = NULL;
+
+ if (object->obj.objclass != CKO_NETSCAPE_CRL) {
+ return NULL;
+ }
+
+ isKrl = (PRBool) object->obj.handle == PK11_TOKEN_KRL_HANDLE;
+ crl = nsslowcert_FindCrlByKey(object->obj.slot->certDB,&object->dbKey,
+ &url,isKrl);
+ if (object->obj.objectInfo == NULL) {
+ object->obj.objectInfo = (void *)crl;
+ object->obj.infoFree = (PK11Free) pk11_FreeItem;
+ } else {
+ if (crl) SECITEM_FreeItem(crl,PR_TRUE);
+ }
+ return url;
+}
+
+static NSSLOWCERTCertificate *
+pk11_getCert(PK11TokenObject *object)
+{
+ NSSLOWCERTCertificate *cert;
+
+ if ((object->obj.objclass != CKO_CERTIFICATE) &&
+ (object->obj.objclass != CKO_NETSCAPE_TRUST)) {
+ return NULL;
+ }
+ if (object->obj.objectInfo) {
+ return (NSSLOWCERTCertificate *)object->obj.objectInfo;
+ }
+ cert = nsslowcert_FindCertByKey(object->obj.slot->certDB,&object->dbKey);
+ object->obj.objectInfo = (void *)cert;
+ object->obj.infoFree = (PK11Free) nsslowcert_DestroyCertificate ;
+ return cert;
+}
+
+static NSSLOWKEYPublicKey *
+pk11_GetPublicKey(PK11TokenObject *object)
+{
+ NSSLOWKEYPublicKey *pubKey;
+ NSSLOWKEYPrivateKey *privKey;
+
+ if (object->obj.objclass != CKO_PUBLIC_KEY) {
+ return NULL;
+ }
+ if (object->obj.objectInfo) {
+ return (NSSLOWKEYPublicKey *)object->obj.objectInfo;
+ }
+ privKey = nsslowkey_FindKeyByPublicKey(object->obj.slot->keyDB,
+ &object->dbKey, object->obj.slot->password);
+ pubKey = nsslowkey_ConvertToPublicKey(privKey);
+ nsslowkey_DestroyPrivateKey(privKey);
+ object->obj.objectInfo = (void *) pubKey;
+ object->obj.infoFree = (PK11Free) nsslowkey_DestroyPublicKey ;
+ return pubKey;
+}
+
+static NSSLOWKEYPrivateKey *
+pk11_GetPrivateKey(PK11TokenObject *object)
+{
+ NSSLOWKEYPrivateKey *privKey;
+
+ if ((object->obj.objclass != CKO_PRIVATE_KEY) &&
+ (object->obj.objclass != CKO_SECRET_KEY)) {
+ return NULL;
+ }
+ if (object->obj.objectInfo) {
+ return (NSSLOWKEYPrivateKey *)object->obj.objectInfo;
+ }
+ privKey = nsslowkey_FindKeyByPublicKey(object->obj.slot->keyDB,
+ &object->dbKey, object->obj.slot->password);
+ object->obj.objectInfo = (void *) privKey;
+ object->obj.infoFree = (PK11Free) nsslowkey_DestroyPrivateKey ;
+ return privKey;
+}
+
+/* pk11_GetPubItem returns data associated with the public key.
+ * one only needs to free the public key. This comment is here
+ * because this sematic would be non-obvious otherwise. All callers
+ * should include this comment.
+ */
+static SECItem *
+pk11_GetPubItem(NSSLOWKEYPublicKey *pubKey) {
+ SECItem *pubItem = NULL;
+ /* get value to compare from the cert's public key */
+ switch ( pubKey->keyType ) {
+ case NSSLOWKEYRSAKey:
+ pubItem = &pubKey->u.rsa.modulus;
+ break;
+ case NSSLOWKEYDSAKey:
+ pubItem = &pubKey->u.dsa.publicValue;
+ break;
+ case NSSLOWKEYDHKey:
+ pubItem = &pubKey->u.dh.publicValue;
+ break;
+ default:
+ break;
+ }
+ return pubItem;
+}
+
+static const SEC_ASN1Template pk11_SerialTemplate[] = {
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWCERTCertificate,serialNumber) },
+ { 0 }
+};
+
+static PK11Attribute *
+pk11_FindRSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type)
+{
+ unsigned char hash[SHA1_LENGTH];
+ CK_KEY_TYPE keyType = CKK_RSA;
+
+ switch (type) {
+ case CKA_KEY_TYPE:
+ return pk11_NewTokenAttribute(type,&keyType,sizeof(keyType), PR_TRUE);
+ case CKA_ID:
+ SHA1_HashBuf(hash,key->u.rsa.modulus.data,key->u.rsa.modulus.len);
+ return pk11_NewTokenAttribute(type,hash,SHA1_LENGTH, PR_TRUE);
+ case CKA_DERIVE:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_ENCRYPT:
+ case CKA_VERIFY:
+ case CKA_VERIFY_RECOVER:
+ case CKA_WRAP:
+ return (PK11Attribute *) &pk11_StaticTrueAttr;
+ default:
+ case CKA_MODULUS:
+ return pk11_NewTokenAttributeSigned(type,key->u.rsa.modulus.data,
+ key->u.rsa.modulus.len, PR_FALSE);
+ case CKA_PUBLIC_EXPONENT:
+ return pk11_NewTokenAttributeSigned(type,key->u.rsa.publicExponent.data,
+ key->u.rsa.publicExponent.len, PR_FALSE);
+ break;
+ }
+ return NULL;
+}
+
+static PK11Attribute *
+pk11_FindDSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type)
+{
+ unsigned char hash[SHA1_LENGTH];
+ CK_KEY_TYPE keyType = CKK_DSA;
+
+ switch (type) {
+ case CKA_KEY_TYPE:
+ return pk11_NewTokenAttribute(type,&keyType,sizeof(keyType), PR_TRUE);
+ case CKA_ID:
+ SHA1_HashBuf(hash,key->u.dsa.publicValue.data,
+ key->u.dsa.publicValue.len);
+ return pk11_NewTokenAttribute(type,hash,SHA1_LENGTH, PR_TRUE);
+ case CKA_DERIVE:
+ case CKA_ENCRYPT:
+ case CKA_VERIFY_RECOVER:
+ case CKA_WRAP:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_VERIFY:
+ return (PK11Attribute *) &pk11_StaticTrueAttr;
+ case CKA_VALUE:
+ return pk11_NewTokenAttributeSigned(type,key->u.dsa.publicValue.data,
+ key->u.dsa.publicValue.len, PR_FALSE);
+ case CKA_PRIME:
+ return pk11_NewTokenAttributeSigned(type,key->u.dsa.params.prime.data,
+ key->u.dsa.params.prime.len, PR_FALSE);
+ case CKA_SUBPRIME:
+ return pk11_NewTokenAttributeSigned(type,
+ key->u.dsa.params.subPrime.data,
+ key->u.dsa.params.subPrime.len, PR_FALSE);
+ case CKA_BASE:
+ return pk11_NewTokenAttributeSigned(type,key->u.dsa.params.base.data,
+ key->u.dsa.params.base.len, PR_FALSE);
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static PK11Attribute *
+pk11_FindDHPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type)
+{
+ unsigned char hash[SHA1_LENGTH];
+ CK_KEY_TYPE keyType = CKK_DH;
+
+ switch (type) {
+ case CKA_KEY_TYPE:
+ return pk11_NewTokenAttribute(type,&keyType,sizeof(keyType), PR_TRUE);
+ case CKA_ID:
+ SHA1_HashBuf(hash,key->u.dh.publicValue.data,key->u.dh.publicValue.len);
+ return pk11_NewTokenAttribute(type,hash,SHA1_LENGTH, PR_TRUE);
+ case CKA_DERIVE:
+ return (PK11Attribute *) &pk11_StaticTrueAttr;
+ case CKA_ENCRYPT:
+ case CKA_VERIFY:
+ case CKA_VERIFY_RECOVER:
+ case CKA_WRAP:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_VALUE:
+ return pk11_NewTokenAttributeSigned(type,key->u.dh.publicValue.data,
+ key->u.dh.publicValue.len, PR_FALSE);
+ case CKA_PRIME:
+ return pk11_NewTokenAttributeSigned(type,key->u.dh.prime.data,
+ key->u.dh.prime.len, PR_FALSE);
+ case CKA_BASE:
+ return pk11_NewTokenAttributeSigned(type,key->u.dh.base.data,
+ key->u.dh.base.len, PR_FALSE);
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static PK11Attribute *
+pk11_FindPublicKeyAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
+{
+ NSSLOWKEYPublicKey *key;
+
+ switch (type) {
+ case CKA_PRIVATE:
+ case CKA_SENSITIVE:
+ case CKA_ALWAYS_SENSITIVE:
+ case CKA_NEVER_EXTRACTABLE:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_MODIFIABLE:
+ case CKA_EXTRACTABLE:
+ return (PK11Attribute *) &pk11_StaticTrueAttr;
+ default:
+ break;
+ }
+
+ key = pk11_GetPublicKey(object);
+ if (key == NULL) {
+ return NULL;
+ }
+ switch (key->keyType) {
+ case NSSLOWKEYRSAKey:
+ return pk11_FindRSAPublicKeyAttribute(key,type);
+ case NSSLOWKEYDSAKey:
+ return pk11_FindDSAPublicKeyAttribute(key,type);
+ case NSSLOWKEYDHKey:
+ return pk11_FindDHPublicKeyAttribute(key,type);
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
+static PK11Attribute *
+pk11_FindSecretKeyAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
+{
+ NSSLOWKEYPrivateKey *key;
+ switch (type) {
+ case CKA_PRIVATE:
+ case CKA_SENSITIVE:
+ case CKA_ALWAYS_SENSITIVE:
+ case CKA_EXTRACTABLE:
+ case CKA_DERIVE:
+ case CKA_ENCRYPT:
+ case CKA_DECRYPT:
+ case CKA_SIGN:
+ case CKA_VERIFY:
+ case CKA_WRAP:
+ case CKA_UNWRAP:
+ return (PK11Attribute *) &pk11_StaticTrueAttr;
+ case CKA_NEVER_EXTRACTABLE:
+ case CKA_MODIFIABLE:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_VALUE:
+ return (PK11Attribute *) &pk11_StaticNullAttr;
+ default:
+ break;
+ }
+
+ key = pk11_GetPrivateKey(object);
+ if (key == NULL) {
+ return NULL;
+ }
+ switch (type) {
+ case CKA_KEY_TYPE:
+ return pk11_NewTokenAttribute(type,key->u.rsa.coefficient.data,
+ key->u.rsa.coefficient.len, PR_FALSE);
+ case CKA_VALUE:
+ return pk11_NewTokenAttribute(type,key->u.rsa.privateExponent.data,
+ key->u.rsa.privateExponent.len, PR_FALSE);
+ }
+
+ return NULL;
+}
+
+static PK11Attribute *
+pk11_FindRSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key,
+ CK_ATTRIBUTE_TYPE type)
+{
+ unsigned char hash[SHA1_LENGTH];
+ CK_KEY_TYPE keyType = CKK_RSA;
+
+ switch (type) {
+ case CKA_KEY_TYPE:
+ return pk11_NewTokenAttribute(type,&keyType,sizeof(keyType), PR_TRUE);
+ case CKA_ID:
+ SHA1_HashBuf(hash,key->u.rsa.modulus.data,key->u.rsa.modulus.len);
+ return pk11_NewTokenAttribute(type,hash,SHA1_LENGTH, PR_TRUE);
+ case CKA_DERIVE:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_DECRYPT:
+ case CKA_SIGN:
+ case CKA_SIGN_RECOVER:
+ case CKA_UNWRAP:
+ return (PK11Attribute *) &pk11_StaticTrueAttr;
+ case CKA_MODULUS:
+ return pk11_NewTokenAttributeSigned(type,key->u.rsa.modulus.data,
+ key->u.rsa.modulus.len, PR_FALSE);
+ case CKA_PUBLIC_EXPONENT:
+ return pk11_NewTokenAttributeSigned(type,key->u.rsa.publicExponent.data,
+ key->u.rsa.publicExponent.len, PR_FALSE);
+ case CKA_PRIVATE_EXPONENT:
+ case CKA_PRIME_1:
+ case CKA_PRIME_2:
+ case CKA_EXPONENT_1:
+ case CKA_EXPONENT_2:
+ case CKA_COEFFICIENT:
+ return (PK11Attribute *) &pk11_StaticNullAttr;
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static PK11Attribute *
+pk11_FindDSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key,
+ CK_ATTRIBUTE_TYPE type)
+{
+ unsigned char hash[SHA1_LENGTH];
+ CK_KEY_TYPE keyType = CKK_DSA;
+
+ switch (type) {
+ case CKA_KEY_TYPE:
+ return pk11_NewTokenAttribute(type,&keyType,sizeof(keyType), PR_TRUE);
+ case CKA_ID:
+ SHA1_HashBuf(hash,key->u.dsa.publicValue.data,
+ key->u.dsa.publicValue.len);
+ return pk11_NewTokenAttribute(type,hash,SHA1_LENGTH, PR_TRUE);
+ case CKA_DERIVE:
+ case CKA_DECRYPT:
+ case CKA_SIGN_RECOVER:
+ case CKA_UNWRAP:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_SIGN:
+ return (PK11Attribute *) &pk11_StaticTrueAttr;
+ case CKA_VALUE:
+ return (PK11Attribute *) &pk11_StaticNullAttr;
+ case CKA_PRIME:
+ return pk11_NewTokenAttributeSigned(type,key->u.dsa.params.prime.data,
+ key->u.dsa.params.prime.len, PR_FALSE);
+ case CKA_SUBPRIME:
+ return pk11_NewTokenAttributeSigned(type,
+ key->u.dsa.params.subPrime.data,
+ key->u.dsa.params.subPrime.len, PR_FALSE);
+ case CKA_BASE:
+ return pk11_NewTokenAttributeSigned(type,key->u.dsa.params.base.data,
+ key->u.dsa.params.base.len, PR_FALSE);
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static PK11Attribute *
+pk11_FindDHPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type)
+{
+ unsigned char hash[SHA1_LENGTH];
+ CK_KEY_TYPE keyType = CKK_DH;
+
+ switch (type) {
+ case CKA_KEY_TYPE:
+ return pk11_NewTokenAttribute(type,&keyType,sizeof(keyType), PR_TRUE);
+ case CKA_ID:
+ SHA1_HashBuf(hash,key->u.dh.publicValue.data,key->u.dh.publicValue.len);
+ return pk11_NewTokenAttribute(type,hash,SHA1_LENGTH, PR_TRUE);
+ case CKA_DERIVE:
+ return (PK11Attribute *) &pk11_StaticTrueAttr;
+ case CKA_DECRYPT:
+ case CKA_SIGN:
+ case CKA_SIGN_RECOVER:
+ case CKA_UNWRAP:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_VALUE:
+ return (PK11Attribute *) &pk11_StaticNullAttr;
+ case CKA_PRIME:
+ return pk11_NewTokenAttributeSigned(type,key->u.dh.prime.data,
+ key->u.dh.prime.len, PR_FALSE);
+ case CKA_BASE:
+ return pk11_NewTokenAttributeSigned(type,key->u.dh.base.data,
+ key->u.dh.base.len, PR_FALSE);
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static PK11Attribute *
+pk11_FindPrivateKeyAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
+{
+ NSSLOWKEYPrivateKey *key;
+ switch (type) {
+ case CKA_PRIVATE:
+ case CKA_SENSITIVE:
+ case CKA_ALWAYS_SENSITIVE:
+ case CKA_EXTRACTABLE:
+ case CKA_MODIFIABLE:
+ return (PK11Attribute *) &pk11_StaticTrueAttr;
+ case CKA_NEVER_EXTRACTABLE:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ default:
+ break;
+ }
+ key = pk11_GetPrivateKey(object);
+ if (key == NULL) {
+ return NULL;
+ }
+ switch (key->keyType) {
+ case NSSLOWKEYRSAKey:
+ return pk11_FindRSAPrivateKeyAttribute(key,type);
+ case NSSLOWKEYDSAKey:
+ return pk11_FindDSAPrivateKeyAttribute(key,type);
+ case NSSLOWKEYDHKey:
+ return pk11_FindDHPrivateKeyAttribute(key,type);
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
+static PK11Attribute *
+pk11_FindSMIMEAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
+{
+ certDBEntrySMime *entry;
+ switch (type) {
+ case CKA_PRIVATE:
+ case CKA_MODIFIABLE:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_NETSCAPE_EMAIL:
+ return pk11_NewTokenAttribute(type,object->dbKey.data,
+ object->dbKey.len, PR_FALSE);
+ default:
+ break;
+ }
+ entry = pk11_getSMime(object);
+ if (entry == NULL) {
+ return NULL;
+ }
+ switch (type) {
+ case CKA_NETSCAPE_SMIME_TIMESTAMP:
+ return pk11_NewTokenAttribute(type,entry->optionsDate.data,
+ entry->optionsDate.len, PR_FALSE);
+ case CKA_SUBJECT:
+ return pk11_NewTokenAttribute(type,entry->subjectName.data,
+ entry->subjectName.len, PR_FALSE);
+ case CKA_VALUE:
+ return pk11_NewTokenAttribute(type,entry->smimeOptions.data,
+ entry->smimeOptions.len, PR_FALSE);
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static PK11Attribute *
+pk11_FindTrustAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
+{
+ NSSLOWCERTCertificate *cert;
+ unsigned char hash[SHA1_LENGTH];
+ SECItem *item;
+ PK11Attribute *attr;
+ unsigned int trustFlags;
+
+ switch (type) {
+ case CKA_PRIVATE:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_MODIFIABLE:
+ return (PK11Attribute *) &pk11_StaticTrueAttr;
+ default:
+ break;
+ }
+ cert = pk11_getCert(object);
+ if (cert == NULL) {
+ return NULL;
+ }
+ switch (type) {
+ case CKA_CERT_SHA1_HASH:
+ SHA1_HashBuf(hash,cert->derCert.data,cert->derCert.len);
+ return pk11_NewTokenAttribute(type,hash,SHA1_LENGTH, PR_TRUE);
+ case CKA_CERT_MD5_HASH:
+ MD5_HashBuf(hash,cert->derCert.data,cert->derCert.len);
+ return pk11_NewTokenAttribute(type,hash,MD5_LENGTH, PR_TRUE);
+ case CKA_ISSUER:
+ return pk11_NewTokenAttribute(type,cert->derIssuer.data,
+ cert->derIssuer.len, PR_FALSE);
+ case CKA_SERIAL_NUMBER:
+ item = SEC_ASN1EncodeItem(NULL,NULL,cert,pk11_SerialTemplate);
+ if (item == NULL) break;
+ attr = pk11_NewTokenAttribute(type, item->data, item->len, PR_TRUE);
+ SECITEM_FreeItem(item,PR_TRUE);
+ return attr;
+ case CKA_TRUST_CLIENT_AUTH:
+ trustFlags = cert->trust->sslFlags & CERTDB_TRUSTED_CLIENT_CA ?
+ cert->trust->sslFlags | CERTDB_TRUSTED_CA : 0 ;
+ goto trust;
+ case CKA_TRUST_SERVER_AUTH:
+ trustFlags = cert->trust->sslFlags;
+ goto trust;
+ case CKA_TRUST_EMAIL_PROTECTION:
+ trustFlags = cert->trust->emailFlags;
+ goto trust;
+ case CKA_TRUST_CODE_SIGNING:
+ trustFlags = cert->trust->objectSigningFlags;
+trust:
+ if (trustFlags & CERTDB_TRUSTED_CA ) {
+ return (PK11Attribute *)&pk11_StaticTrustedDelegatorAttr;
+ }
+ if (trustFlags & CERTDB_TRUSTED) {
+ return (PK11Attribute *)&pk11_StaticTrustedAttr;
+ }
+ if (trustFlags & CERTDB_NOT_TRUSTED) {
+ return (PK11Attribute *)&pk11_StaticUnTrustedAttr;
+ }
+ if (trustFlags & CERTDB_TRUSTED_UNKNOWN) {
+ return (PK11Attribute *)&pk11_StaticTrustUnknownAttr;
+ }
+ return (PK11Attribute *)&pk11_StaticMustVerifyAttr;
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static PK11Attribute *
+pk11_FindCrlAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
+{
+ SECItem *crl;
+ char *url;
+
+ switch (type) {
+ case CKA_PRIVATE:
+ case CKA_MODIFIABLE:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_NETSCAPE_KRL:
+ return (PK11Attribute *) ((object->obj.handle == PK11_TOKEN_KRL_HANDLE)
+ ? &pk11_StaticTrueAttr : &pk11_StaticFalseAttr);
+ case CKA_NETSCAPE_URL:
+ url = pk11_getUrl(object);
+ if (url == NULL) {
+ return (PK11Attribute *) &pk11_StaticNullAttr;
+ }
+ return pk11_NewTokenAttribute(type, url, PORT_Strlen(url)+1, PR_TRUE);
+ case CKA_VALUE:
+ crl = pk11_getCrl(object);
+ if (crl == NULL) break;
+ return pk11_NewTokenAttribute(type, crl->data, crl->len, PR_FALSE);
+ case CKA_SUBJECT:
+ return pk11_NewTokenAttribute(type,object->dbKey.data,
+ object->dbKey.len, PR_FALSE);
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static PK11Attribute *
+pk11_FindCertAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
+{
+ NSSLOWCERTCertificate *cert;
+ NSSLOWKEYPublicKey *pubKey;
+ unsigned char hash[SHA1_LENGTH];
+ SECItem *item;
+ PK11Attribute *attr;
+
+ switch (type) {
+ case CKA_PRIVATE:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_MODIFIABLE:
+ return (PK11Attribute *) &pk11_StaticTrueAttr;
+ case CKA_CERTIFICATE_TYPE:
+ /* hardcoding X.509 into here */
+ return (PK11Attribute *)&pk11_StaticX509Attr;
+ default:
+ break;
+ }
+ cert = pk11_getCert(object);
+ if (cert == NULL) {
+ return NULL;
+ }
+ switch (type) {
+ case CKA_VALUE:
+ return pk11_NewTokenAttribute(type,cert->derCert.data,
+ cert->derCert.len,PR_FALSE);
+ case CKA_ID:
+ pubKey = nsslowcert_ExtractPublicKey(cert);
+ if (pubKey == NULL) break;
+ item = pk11_GetPubItem(pubKey);
+ if (item == NULL) {
+ nsslowkey_DestroyPublicKey(pubKey);
+ break;
+ }
+ SHA1_HashBuf(hash,item->data,item->len);
+ /* item is imbedded in pubKey, just free the key */
+ nsslowkey_DestroyPublicKey(pubKey);
+ return pk11_NewTokenAttribute(type, hash, SHA1_LENGTH, PR_TRUE);
+ case CKA_LABEL:
+ return cert->nickname ? pk11_NewTokenAttribute(type, cert->nickname,
+ PORT_Strlen(cert->nickname)+1, PR_FALSE) :
+ (PK11Attribute *) &pk11_StaticNullAttr;
+ case CKA_SUBJECT:
+ return pk11_NewTokenAttribute(type,cert->derSubject.data,
+ cert->derSubject.len, PR_FALSE);
+ case CKA_ISSUER:
+ return pk11_NewTokenAttribute(type,cert->derIssuer.data,
+ cert->derIssuer.len, PR_FALSE);
+ case CKA_SERIAL_NUMBER:
+ item = SEC_ASN1EncodeItem(NULL,NULL,cert,pk11_SerialTemplate);
+ if (item == NULL) break;
+ attr = pk11_NewTokenAttribute(type, item->data, item->len, PR_TRUE);
+ SECITEM_FreeItem(item,PR_TRUE);
+ return attr;
+ default:
+ break;
+ }
+ return NULL;
+}
-
+static PK11Attribute *
+pk11_FindTokenAttribute(PK11TokenObject *object,CK_ATTRIBUTE_TYPE type)
+{
+ /* handle the common ones */
+ switch (type) {
+ case CKA_CLASS:
+ return pk11_NewTokenAttribute(type,&object->obj.objclass,
+ sizeof(object->obj.objclass),PR_FALSE);
+ case CKA_TOKEN:
+ return (PK11Attribute *) &pk11_StaticTrueAttr;
+ case CKA_LABEL:
+ return (object->obj.objclass != CKO_CERTIFICATE) ?
+ (PK11Attribute *) &pk11_StaticNullAttr :
+ pk11_FindCertAttribute(object,type);
+ default:
+ break;
+ }
+ switch (object->obj.objclass) {
+ case CKO_CERTIFICATE:
+ return pk11_FindCertAttribute(object,type);
+ case CKO_NETSCAPE_CRL:
+ return pk11_FindCrlAttribute(object,type);
+ case CKO_NETSCAPE_TRUST:
+ return pk11_FindTrustAttribute(object,type);
+ case CKO_NETSCAPE_SMIME:
+ return pk11_FindSMIMEAttribute(object,type);
+ case CKO_PUBLIC_KEY:
+ return pk11_FindPublicKeyAttribute(object,type);
+ case CKO_PRIVATE_KEY:
+ return pk11_FindPrivateKeyAttribute(object,type);
+ case CKO_SECRET_KEY:
+ return pk11_FindSecretKeyAttribute(object,type);
+ default:
+ break;
+ }
+ PORT_Assert(0);
+ return NULL;
+}
+
/*
* look up and attribute structure from a type and Object structure.
* The returned attribute is referenced and needs to be freed when
@@ -169,10 +1036,15 @@ PK11Attribute *
pk11_FindAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type)
{
PK11Attribute *attribute;
+ PK11SessionObject *sessObject = pk11_narrowToSessionObject(object);
+
+ if (sessObject == NULL) {
+ return pk11_FindTokenAttribute(pk11_narrowToTokenObject(object),type);
+ }
- PK11_USE_THREADS(PZ_Lock(object->attributeLock);)
- pk11queue_find(attribute,type,object->head,ATTRIBUTE_HASH_SIZE);
-#ifdef REF_COUNT_ATTRIBUTE
+ PK11_USE_THREADS(PZ_Lock(sessObject->attributeLock);)
+ pk11queue_find(attribute,type,sessObject->head,ATTRIBUTE_HASH_SIZE);
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
if (attribute) {
/* atomic increment would be nice here */
PK11_USE_THREADS(PZ_Lock(attribute->refLock);)
@@ -180,31 +1052,19 @@ pk11_FindAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type)
PK11_USE_THREADS(PZ_Unlock(attribute->refLock);)
}
#endif
- PK11_USE_THREADS(PZ_Unlock(object->attributeLock);)
+ PK11_USE_THREADS(PZ_Unlock(sessObject->attributeLock);)
return(attribute);
}
-/*
- * release a reference to an attribute structure
- */
-void
-pk11_FreeAttribute(PK11Attribute *attribute)
-{
-#ifdef REF_COUNT_ATTRIBUTE
- PRBool destroy = PR_FALSE;
-
- PK11_USE_THREADS(PZ_Lock(attribute->refLock);)
- if (attribute->refCount == 1) destroy = PR_TRUE;
- attribute->refCount--;
- PK11_USE_THREADS(PZ_Unlock(attribute->refLock);)
- if (destroy) pk11_DestroyAttribute(attribute);
-#endif
+PRBool
+pk11_hasAttributeToken(PK11TokenObject *object)
+{
+ return PR_FALSE;
}
-
/*
* return true if object has attribute
*/
@@ -212,10 +1072,15 @@ PRBool
pk11_hasAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type)
{
PK11Attribute *attribute;
+ PK11SessionObject *sessObject = pk11_narrowToSessionObject(object);
- PK11_USE_THREADS(PZ_Lock(object->attributeLock);)
- pk11queue_find(attribute,type,object->head,ATTRIBUTE_HASH_SIZE);
- PK11_USE_THREADS(PZ_Unlock(object->attributeLock);)
+ if (sessObject == NULL) {
+ return pk11_hasAttributeToken(pk11_narrowToTokenObject(object));
+ }
+
+ PK11_USE_THREADS(PZ_Lock(sessObject->attributeLock);)
+ pk11queue_find(attribute,type,sessObject->head,ATTRIBUTE_HASH_SIZE);
+ PK11_USE_THREADS(PZ_Unlock(sessObject->attributeLock);)
return (PRBool)(attribute != NULL);
}
@@ -223,12 +1088,16 @@ pk11_hasAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type)
/*
* add an attribute to an object
*/
-static
-void pk11_AddAttribute(PK11Object *object,PK11Attribute *attribute)
+static void
+pk11_AddAttribute(PK11Object *object,PK11Attribute *attribute)
{
- PK11_USE_THREADS(PZ_Lock(object->attributeLock);)
- pk11queue_add(attribute,attribute->handle,object->head,ATTRIBUTE_HASH_SIZE);
- PK11_USE_THREADS(PZ_Unlock(object->attributeLock);)
+ PK11SessionObject *sessObject = pk11_narrowToSessionObject(object);
+
+ if (sessObject == NULL) return;
+ PK11_USE_THREADS(PZ_Lock(sessObject->attributeLock);)
+ pk11queue_add(attribute,attribute->handle,
+ sessObject->head,ATTRIBUTE_HASH_SIZE);
+ PK11_USE_THREADS(PZ_Unlock(sessObject->attributeLock);)
}
/*
@@ -277,13 +1146,18 @@ pk11_Attribute2SSecItem(PLArenaPool *arena,SECItem *item,PK11Object *object,
static void
pk11_DeleteAttribute(PK11Object *object, PK11Attribute *attribute)
{
- PK11_USE_THREADS(PZ_Lock(object->attributeLock);)
+ PK11SessionObject *sessObject = pk11_narrowToSessionObject(object);
+
+ if (sessObject == NULL) {
+ return ;
+ }
+ PK11_USE_THREADS(PZ_Lock(sessObject->attributeLock);)
if (pk11queue_is_queued(attribute,attribute->handle,
- object->head,ATTRIBUTE_HASH_SIZE)) {
+ sessObject->head,ATTRIBUTE_HASH_SIZE)) {
pk11queue_delete(attribute,attribute->handle,
- object->head,ATTRIBUTE_HASH_SIZE);
+ sessObject->head,ATTRIBUTE_HASH_SIZE);
}
- PK11_USE_THREADS(PZ_Unlock(object->attributeLock);)
+ PK11_USE_THREADS(PZ_Unlock(sessObject->attributeLock);)
pk11_FreeAttribute(attribute);
}
@@ -320,20 +1194,106 @@ pk11_nullAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type)
if (attribute->attrib.pValue != NULL) {
PORT_Memset(attribute->attrib.pValue,0,attribute->attrib.ulValueLen);
-#ifdef REF_COUNT_ATTRIBUTE
- PORT_Free(attribute->attrib.pValue);
-#endif /* REF_COUNT_ATTRIBUTE */
-#ifdef NO_ARENA
- if (attribute->attrib.pValue != attribute->space) {
+ if (attribute->freeData) {
PORT_Free(attribute->attrib.pValue);
}
-#endif /* NO_ARENA */
+ attribute->freeData = PR_FALSE;
attribute->attrib.pValue = NULL;
attribute->attrib.ulValueLen = 0;
}
pk11_FreeAttribute(attribute);
}
+static CK_RV
+pk11_SetTrustAttribute(PK11TokenObject *to, CK_ATTRIBUTE_TYPE type,
+ void *value, unsigned int len)
+{
+ unsigned int flags;
+ CK_TRUST trust;
+ NSSLOWCERTCertificate *cert;
+ NSSLOWCERTCertTrust dbTrust;
+ SECStatus rv;
+
+ if (to->obj.slot->certDB == NULL) {
+ return CKR_TOKEN_WRITE_PROTECTED;
+ }
+ if (len != sizeof (CK_TRUST)) {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+ trust = *(CK_TRUST *)value;
+ flags = pk11_MapTrust(trust, (PRBool) (type == CKA_TRUST_SERVER_AUTH));
+
+ cert = pk11_getCert(to);
+ if (cert == NULL) {
+ return CKR_OBJECT_HANDLE_INVALID;
+ }
+ dbTrust = *cert->trust;
+
+ switch (type) {
+ case CKA_TRUST_EMAIL_PROTECTION:
+ dbTrust.emailFlags = flags |
+ (cert->trust->emailFlags & CERTDB_PRESERVE_TRUST_BITS);
+ break;
+ case CKA_TRUST_CODE_SIGNING:
+ dbTrust.objectSigningFlags = flags |
+ (cert->trust->objectSigningFlags & CERTDB_PRESERVE_TRUST_BITS);
+ break;
+ case CKA_TRUST_CLIENT_AUTH:
+ dbTrust.sslFlags = flags | (cert->trust->sslFlags &
+ CERTDB_PRESERVE_TRUST_BITS|CERTDB_TRUSTED_CA);
+ break;
+ case CKA_TRUST_SERVER_AUTH:
+ dbTrust.sslFlags = flags | (cert->trust->sslFlags &
+ CERTDB_PRESERVE_TRUST_BITS|CERTDB_TRUSTED_CLIENT_CA);
+ break;
+ default:
+ return CKR_ATTRIBUTE_READ_ONLY;
+ }
+
+ rv = nsslowcert_ChangeCertTrust(to->obj.slot->certDB,cert,&dbTrust);
+ if (rv != SECSuccess) {
+ return CKR_DEVICE_ERROR;
+ }
+ return CKR_OK;
+}
+
+static CK_RV
+pk11_forceTokenAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type,
+ void *value, unsigned int len)
+{
+ PK11Attribute *attribute;
+ PK11TokenObject *to = pk11_narrowToTokenObject(object);
+ CK_RV crv = CKR_ATTRIBUTE_READ_ONLY;
+
+ PORT_Assert(to);
+ if (to == NULL) {
+ return CKR_DEVICE_ERROR;
+ }
+
+ /* if we are just setting it to the value we already have,
+ * allow it to happen. */
+ attribute=pk11_FindAttribute(object,type);
+ if ((attribute->attrib.ulValueLen == len) &&
+ PORT_Memcmp(attribute->attrib.pValue,value,len) == 0) {
+ pk11_FreeAttribute(attribute);
+ return CKR_OK;
+ }
+
+ switch (object->objclass) {
+ case CKO_CERTIFICATE:
+ /* change NICKNAME, EMAIL, */
+ break;
+ case CKO_NETSCAPE_CRL:
+ /* change URL */
+ break;
+ case CKO_NETSCAPE_TRUST:
+ crv = pk11_SetTrustAttribute(to,type,value,len);
+ break;
+ }
+ pk11_FreeAttribute(attribute);
+ return crv;
+}
+
/*
* force an attribute to a spaecif value.
*/
@@ -343,25 +1303,31 @@ pk11_forceAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type, void *value,
{
PK11Attribute *attribute;
void *att_val = NULL;
+ PRBool freeData = PR_FALSE;
+ if (pk11_isToken(object->handle)) {
+ return pk11_forceTokenAttribute(object,type,value,len);
+ }
attribute=pk11_FindAttribute(object,type);
if (attribute == NULL) return pk11_AddAttributeType(object,type,value,len);
if (value) {
-#ifdef NO_ARENA
+#ifdef PKCS11_STATIC_ATTRIBUTES
if (len <= ATTR_SPACE) {
att_val = attribute->space;
} else {
att_val = PORT_Alloc(len);
+ freeData = PR_TRUE;
}
#else
-#ifdef REF_COUNT_ATTRIBUTE
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
att_val = PORT_Alloc(len);
+ freeData = PR_TRUE;
#else
att_val = PORT_ArenaAlloc(object->arena,len);
-#endif /* REF_COUNT_ATTRIBUTE */
-#endif /* NO_ARENA */
+#endif /* PKCS11_REF_COUNT_ATTRIBUTES */
+#endif /* PKCS11_STATIC_ATTRIBUTES */
if (att_val == NULL) {
return CKR_HOST_MEMORY;
}
@@ -376,21 +1342,19 @@ pk11_forceAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type, void *value,
PORT_Memset(attribute->attrib.pValue,0,
attribute->attrib.ulValueLen);
}
-#ifdef REF_COUNT_ATTRIBUTE
- PORT_Free(attribute->attrib.pValue);
-#endif /* REF_COUNT_ATTRIBUTE */
-#ifdef NO_ARENA
- if (attribute->attrib.pValue != attribute->space) {
+ if (attribute->freeData) {
PORT_Free(attribute->attrib.pValue);
}
-#endif /* NO_ARENA */
+ attribute->freeData = PR_FALSE;
attribute->attrib.pValue = NULL;
attribute->attrib.ulValueLen = 0;
}
if (att_val) {
attribute->attrib.pValue = att_val;
attribute->attrib.ulValueLen = len;
+ attribute->freeData = freeData;
}
+ pk11_FreeAttribute(attribute);
return CKR_OK;
}
@@ -591,6 +1555,62 @@ pk11_AddAttributeType(PK11Object *object,CK_ATTRIBUTE_TYPE type,void *valPtr,
* ******************** Object Utilities *******************************
*/
+static SECStatus
+pk11_deleteTokenKeyByHandle(PK11Slot *slot, CK_OBJECT_HANDLE handle)
+{
+ SECItem *item;
+ PRBool rem;
+
+ item = (SECItem *)PL_HashTableLookupConst(slot->tokenHashTable,
+ (void *)handle);
+ if (item) {
+ SECITEM_FreeItem(item,PR_TRUE);
+ }
+ rem = PL_HashTableRemove(slot->tokenHashTable,(void *)handle) ;
+ return rem ? SECSuccess : SECFailure;
+}
+
+static SECStatus
+pk11_addTokenKeyByHandle(PK11Slot *slot, CK_OBJECT_HANDLE handle, SECItem *key)
+{
+ PLHashEntry *entry;
+ SECItem *item;
+
+ item = SECITEM_DupItem(key);
+ if (item == NULL) {
+ return SECFailure;
+ }
+ entry = PL_HashTableAdd(slot->tokenHashTable,(void *)handle,item);
+ if (entry == NULL) {
+ SECITEM_FreeItem(item,PR_TRUE);
+ return SECFailure;
+ }
+ return SECSuccess;
+}
+
+static SECItem *
+pk11_lookupTokenKeyByHandle(PK11Slot *slot, CK_OBJECT_HANDLE handle)
+{
+ return (SECItem *)PL_HashTableLookupConst(slot->tokenHashTable,
+ (void *)handle);
+}
+
+/*
+ * use the refLock. This operations should be very rare, so the added
+ * contention on the ref lock should be lower than the overhead of adding
+ * a new lock. We use separate functions for this just in case I'm wrong.
+ */
+static void
+pk11_tokenKeyLock(PK11Slot *slot) {
+ PK11_USE_THREADS(PZ_Lock(slot->objectLock);)
+}
+
+static void
+pk11_tokenKeyUnlock(PK11Slot *slot) {
+ PK11_USE_THREADS(PZ_Unlock(slot->objectLock);)
+}
+
+
/* allocation hooks that allow us to recycle old object structures */
#ifdef MAX_OBJECT_LIST_SIZE
static PK11Object * objectFreeList = NULL;
@@ -620,26 +1640,26 @@ pk11_GetObjectFromList(PRBool *hasLocks) {
}
#endif
- object = (PK11Object*)PORT_ZAlloc(sizeof(PK11Object));
+ object = (PK11Object*)PORT_ZAlloc(sizeof(PK11SessionObject));
*hasLocks = PR_FALSE;
return object;
}
static void
-pk11_PutObjectToList(PK11Object *object) {
+pk11_PutObjectToList(PK11SessionObject *object) {
#ifdef MAX_OBJECT_LIST_SIZE
if (object_count < MAX_OBJECT_LIST_SIZE) {
PK11_USE_THREADS(PZ_Lock(objectLock));
- object->next = objectFreeList;
- objectFreeList = object;
+ object->obj.next = objectFreeList;
+ objectFreeList = &object->obj;
object_count++;
PK11_USE_THREADS(PZ_Unlock(objectLock));
return;
}
#endif
PK11_USE_THREADS(PZ_DestroyLock(object->attributeLock);)
- PK11_USE_THREADS(PZ_DestroyLock(object->refLock);)
- object->attributeLock = object->refLock = NULL;
+ PK11_USE_THREADS(PZ_DestroyLock(object->obj.refLock);)
+ object->attributeLock = object->obj.refLock = NULL;
PORT_Free(object);
}
@@ -651,58 +1671,63 @@ PK11Object *
pk11_NewObject(PK11Slot *slot)
{
PK11Object *object;
+ PK11SessionObject *sessObject;
PRBool hasLocks = PR_FALSE;
int i;
-#ifdef NO_ARENA
+#ifdef PKCS11_STATIC_ATTRIBUTES
object = pk11_GetObjectFromList(&hasLocks);
if (object == NULL) {
return NULL;
}
- object->nextAttr = 0;
+ sessObject = (PK11SessionObject *)object;
+ sessObject->nextAttr = 0;
+
+ for (i=0; i < MAX_OBJS_ATTRS; i++) {
+ sessObject->attrList[i].attrib.pValue = NULL;
+ sessObject->attrList[i].freeData = PR_FALSE;
+ }
#else
+ PRArenaPool *arena;
+
arena = PORT_NewArena(2048);
if (arena == NULL) return NULL;
- object = (PK11Object*)PORT_ArenaAlloc(arena,sizeof(PK11Object));
+ object = (PK11Object*)PORT_ArenaAlloc(arena,sizeof(PK11SessionObject));
if (object == NULL) {
PORT_FreeArena(arena,PR_FALSE);
return NULL;
}
object->arena = arena;
- for (i=0; i < MAX_OBJS_ATTRS; i++) {
- object->attrList[i].attrib.pValue = NULL;
- }
+ sessObject = (PK11SessionObject *)object;
#endif
object->handle = 0;
object->next = object->prev = NULL;
- object->sessionList.next = NULL;
- object->sessionList.prev = NULL;
- object->sessionList.parent = object;
- object->inDB = PR_FALSE;
- object->label = NULL;
- object->refCount = 1;
- object->session = NULL;
object->slot = slot;
object->objclass = 0xffff;
- object->wasDerived = PR_FALSE;
+ object->refCount = 1;
+ sessObject->sessionList.next = NULL;
+ sessObject->sessionList.prev = NULL;
+ sessObject->sessionList.parent = object;
+ sessObject->session = NULL;
+ sessObject->wasDerived = PR_FALSE;
#ifdef PKCS11_USE_THREADS
if (!hasLocks) object->refLock = PZ_NewLock(nssILockRefLock);
if (object->refLock == NULL) {
-#ifdef NO_ARENA
+#ifdef PKCS11_STATIC_ATTRIBUTES
PORT_Free(object);
#else
PORT_FreeArena(arena,PR_FALSE);
#endif
return NULL;
}
- if (!hasLocks) object->attributeLock = PZ_NewLock(nssILockAttribute);
- if (object->attributeLock == NULL) {
+ if (!hasLocks) sessObject->attributeLock = PZ_NewLock(nssILockAttribute);
+ if (sessObject->attributeLock == NULL) {
PK11_USE_THREADS(PZ_DestroyLock(object->refLock);)
-#ifdef NO_ARENA
+#ifdef PKCS11_STATIC_ATTRIBUTES
PORT_Free(object);
#else
PORT_FreeArena(arena,PR_FALSE);
@@ -710,17 +1735,55 @@ pk11_NewObject(PK11Slot *slot)
return NULL;
}
#else
- object->attributeLock = NULL;
+ sessObject->attributeLock = NULL;
object->refLock = NULL;
#endif
for (i=0; i < ATTRIBUTE_HASH_SIZE; i++) {
- object->head[i] = NULL;
+ sessObject->head[i] = NULL;
}
object->objectInfo = NULL;
object->infoFree = NULL;
return object;
}
+static CK_RV
+pk11_DestroySessionObjectData(PK11SessionObject *so)
+{
+ int i;
+
+#ifdef PKCS11_STATIC_ATTRIBUTES
+ for (i=0; i < MAX_OBJS_ATTRS; i++) {
+ unsigned char *value = so->attrList[i].attrib.pValue;
+ if (value) {
+ PORT_Memset(value,0,so->attrList[i].attrib.ulValueLen);
+ if (so->attrList[i].freeData) {
+ PORT_Free(value);
+ }
+ so->attrList[i].attrib.pValue = NULL;
+ so->attrList[i].freeData = PR_FALSE;
+ }
+ }
+#endif
+
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
+ /* clean out the attributes */
+ /* since no one is referencing us, it's safe to walk the chain
+ * without a lock */
+ for (i=0; i < ATTRIBUTE_HASH_SIZE; i++) {
+ PK11Attribute *ap,*next;
+ for (ap = so->head[i]; ap != NULL; ap = next) {
+ next = ap->next;
+ /* paranoia */
+ ap->next = ap->prev = NULL;
+ pk11_FreeAttribute(ap);
+ }
+ so->head[i] = NULL;
+ }
+#endif
+/* PK11_USE_THREADS(PZ_DestroyLock(so->attributeLock));*/
+ return CKR_OK;
+}
+
/*
* free all the data associated with an object. Object reference count must
* be 'zero'.
@@ -728,86 +1791,33 @@ pk11_NewObject(PK11Slot *slot)
static CK_RV
pk11_DestroyObject(PK11Object *object)
{
-#if defined(REF_COUNT_ATTRIBUTE) || defined(NO_ARENA)
- int i;
-#endif
- SECItem pubKey;
CK_RV crv = CKR_OK;
- SECStatus rv;
+ PK11SessionObject *so = pk11_narrowToSessionObject(object);
+ PK11TokenObject *to = pk11_narrowToTokenObject(object);
PORT_Assert(object->refCount == 0);
/* delete the database value */
- if (object->inDB) {
- if (pk11_isToken(object->handle)) {
- /* remove the objects from the real data base */
- switch (object->handle & PK11_TOKEN_TYPE_MASK) {
- case PK11_TOKEN_TYPE_PRIV:
- /* KEYID is the public KEY for DSA and DH, and the MODULUS for
- * RSA */
- crv=pk11_Attribute2SecItem(NULL,&pubKey,object,CKA_NETSCAPE_DB);
- if (crv != CKR_OK) break;
- rv = SECKEY_DeleteKey(SECKEY_GetDefaultKeyDB(), &pubKey);
- if (rv != SECSuccess && pubKey.data[0] == 0) {
- /* Because of legacy code issues, sometimes the public key
- * has a '0' prepended to it, forcing it to be unsigned.
- * The database may not store that '0', so remove it and
- * try again.
- */
- SECItem tmpPubKey;
- tmpPubKey.data = pubKey.data + 1;
- tmpPubKey.len = pubKey.len - 1;
- rv = SECKEY_DeleteKey(SECKEY_GetDefaultKeyDB(), &tmpPubKey);
- }
- if (rv != SECSuccess) crv= CKR_DEVICE_ERROR;
- break;
- case PK11_TOKEN_TYPE_CERT:
- rv = SEC_DeletePermCertificate((CERTCertificate *)object->objectInfo);
- if (rv != SECSuccess) crv = CKR_DEVICE_ERROR;
- break;
- }
+ if (to) {
+ if (to->dbKey.data) {
+ PORT_Free(to->dbKey.data);
+ to->dbKey.data = NULL;
}
}
- if (object->label) PORT_Free(object->label);
-
- object->inDB = PR_FALSE;
- object->label = NULL;
-
-#ifdef NO_ARENA
- for (i=0; i < MAX_OBJS_ATTRS; i++) {
- unsigned char *value = object->attrList[i].attrib.pValue;
- if (value) {
- PORT_Memset(value,0,object->attrList[i].attrib.ulValueLen);
- if (value != object->attrList[i].space) {
- PORT_Free(value);
- }
- object->attrList[i].attrib.pValue = NULL;
- }
+ if (so) {
+ pk11_DestroySessionObjectData(so);
}
-#endif
-
-#ifdef REF_COUNT_ATTRIBUTE
- /* clean out the attributes */
- /* since no one is referencing us, it's safe to walk the chain
- * without a lock */
- for (i=0; i < ATTRIBUTE_HASH_SIZE; i++) {
- PK11Attribute *ap,*next;
- for (ap = object->head[i]; ap != NULL; ap = next) {
- next = ap->next;
- /* paranoia */
- ap->next = ap->prev = NULL;
- pk11_FreeAttribute(ap);
- }
- object->head[i] = NULL;
- }
-#endif
if (object->objectInfo) {
(*object->infoFree)(object->objectInfo);
}
-#ifdef NO_ARENA
- pk11_PutObjectToList(object);
+#ifdef PKCS11_STATIC_ATTRIBUTES
+ if (so) {
+ pk11_PutObjectToList(so);
+ } else {
+ PK11_USE_THREADS(PZ_DestroyLock(object->refLock);)
+ PORT_Free(to);;
+ }
#else
- PK11_USE_THREADS(PZ_DestroyLock(object->attributeLock);)
PK11_USE_THREADS(PZ_DestroyLock(object->refLock);)
arena = object->arena;
PORT_FreeArena(arena,PR_FALSE);
@@ -830,6 +1840,10 @@ pk11_ObjectFromHandleOnSlot(CK_OBJECT_HANDLE handle, PK11Slot *slot)
PZLock *lock;
PK11Object *object;
+ if (pk11_isToken(handle)) {
+ return pk11_NewTokenObject(slot, NULL, handle);
+ }
+
head = slot->tokObjects;
lock = slot->objectLock;
@@ -888,7 +1902,8 @@ void
pk11_AddSlotObject(PK11Slot *slot, PK11Object *object)
{
PK11_USE_THREADS(PZ_Lock(slot->objectLock);)
- pk11queue_add(object,object->handle,slot->tokObjects,TOKEN_OBJECT_HASH_SIZE);
+ pk11queue_add(object,object->handle,slot->tokObjects,
+ TOKEN_OBJECT_HASH_SIZE);
PK11_USE_THREADS(PZ_Unlock(slot->objectLock);)
}
@@ -896,35 +1911,98 @@ void
pk11_AddObject(PK11Session *session, PK11Object *object)
{
PK11Slot *slot = pk11_SlotFromSession(session);
+ PK11SessionObject *so = pk11_narrowToSessionObject(object);
- if (!pk11_isToken(object->handle)) {
+ if (so) {
PK11_USE_THREADS(PZ_Lock(session->objectLock);)
- pk11queue_add(&object->sessionList,0,session->objects,0);
- object->session = session;
+ pk11queue_add(&so->sessionList,0,session->objects,0);
+ so->session = session;
PK11_USE_THREADS(PZ_Unlock(session->objectLock);)
}
pk11_AddSlotObject(slot,object);
+ pk11_ReferenceObject(object);
}
/*
* add an object to a slot andsession queue
*/
-void
+CK_RV
pk11_DeleteObject(PK11Session *session, PK11Object *object)
{
PK11Slot *slot = pk11_SlotFromSession(session);
+ PK11SessionObject *so = pk11_narrowToSessionObject(object);
+ PK11TokenObject *to = pk11_narrowToTokenObject(object);
+ CK_RV crv = CKR_OK;
+ SECStatus rv;
+ NSSLOWCERTCertificate *cert;
+ NSSLOWCERTCertTrust tmptrust;
+ PRBool isKrl;
- if (object->session) {
- PK11Session *session = object->session;
+ /* Handle Token case */
+ if (so && so->session) {
+ PK11Session *session = so->session;
PK11_USE_THREADS(PZ_Lock(session->objectLock);)
- pk11queue_delete(&object->sessionList,0,session->objects,0);
+ pk11queue_delete(&so->sessionList,0,session->objects,0);
PK11_USE_THREADS(PZ_Unlock(session->objectLock);)
- }
- PK11_USE_THREADS(PZ_Lock(slot->objectLock);)
- pk11queue_delete(object,object->handle,slot->tokObjects,
+ PK11_USE_THREADS(PZ_Lock(slot->objectLock);)
+ pk11queue_delete(object,object->handle,slot->tokObjects,
TOKEN_OBJECT_HASH_SIZE);
- PK11_USE_THREADS(PZ_Unlock(slot->objectLock);)
- pk11_FreeObject(object);
+ PK11_USE_THREADS(PZ_Unlock(slot->objectLock);)
+ pk11_FreeObject(object); /* reduce it's reference count */
+ } else {
+ PORT_Assert(to);
+ /* remove the objects from the real data base */
+ switch (object->handle & PK11_TOKEN_TYPE_MASK) {
+ case PK11_TOKEN_TYPE_PRIV:
+ case PK11_TOKEN_TYPE_KEY:
+ /* KEYID is the public KEY for DSA and DH, and the MODULUS for
+ * RSA */
+ PORT_Assert(slot->keyDB);
+ rv = nsslowkey_DeleteKey(slot->keyDB, &to->dbKey);
+ if (rv != SECSuccess) crv= CKR_DEVICE_ERROR;
+ break;
+ case PK11_TOKEN_TYPE_PUB:
+ break; /* public keys only exist at the behest of the priv key */
+ case PK11_TOKEN_TYPE_CERT:
+ cert = nsslowcert_FindCertByKey(slot->certDB,&to->dbKey);
+ if (cert == NULL) {
+ crv = CKR_DEVICE_ERROR;
+ break;
+ }
+ rv = nsslowcert_DeletePermCertificate(cert);
+ if (rv != SECSuccess) crv = CKR_DEVICE_ERROR;
+ nsslowcert_DestroyCertificate(cert);
+ break;
+ case PK11_TOKEN_TYPE_CRL:
+ isKrl = (PRBool) (object->handle == PK11_TOKEN_KRL_HANDLE);
+ rv = nsslowcert_DeletePermCRL(slot->certDB,&to->dbKey,isKrl);
+ if (rv == SECFailure) crv = CKR_DEVICE_ERROR;
+ break;
+ case PK11_TOKEN_TYPE_TRUST:
+ cert = nsslowcert_FindCertByKey(slot->certDB,&to->dbKey);
+ if (cert == NULL) {
+ crv = CKR_DEVICE_ERROR;
+ break;
+ }
+ tmptrust = *cert->trust;
+ tmptrust.sslFlags &= CERTDB_PRESERVE_TRUST_BITS;
+ tmptrust.emailFlags &= CERTDB_PRESERVE_TRUST_BITS;
+ tmptrust.objectSigningFlags &= CERTDB_PRESERVE_TRUST_BITS;
+ tmptrust.sslFlags |= CERTDB_TRUSTED_UNKNOWN;
+ tmptrust.emailFlags |= CERTDB_TRUSTED_UNKNOWN;
+ tmptrust.objectSigningFlags |= CERTDB_TRUSTED_UNKNOWN;
+ rv = nsslowcert_ChangeCertTrust(slot->certDB,cert,&tmptrust);
+ if (rv != SECSuccess) crv = CKR_DEVICE_ERROR;
+ nsslowcert_DestroyCertificate(cert);
+ break;
+ default:
+ break;
+ }
+ pk11_tokenKeyLock(object->slot);
+ pk11_deleteTokenKeyByHandle(object->slot,object->handle);
+ pk11_tokenKeyUnlock(object->slot);
+ }
+ return crv;
}
/*
@@ -936,11 +2014,16 @@ CK_RV
pk11_CopyObject(PK11Object *destObject,PK11Object *srcObject)
{
PK11Attribute *attribute;
+ PK11SessionObject *src_so = pk11_narrowToSessionObject(srcObject);
int i;
- PK11_USE_THREADS(PZ_Lock(srcObject->attributeLock);)
+ if (src_so == NULL) {
+ return CKR_DEVICE_ERROR; /* can't copy token objects yet */
+ }
+
+ PK11_USE_THREADS(PZ_Lock(src_so->attributeLock);)
for(i=0; i < ATTRIBUTE_HASH_SIZE; i++) {
- attribute = srcObject->head[i];
+ attribute = src_so->head[i];
do {
if (attribute) {
if (!pk11_hasAttribute(destObject,attribute->handle)) {
@@ -949,7 +2032,7 @@ pk11_CopyObject(PK11Object *destObject,PK11Object *srcObject)
PK11Attribute *newAttribute = pk11_NewAttribute(
destObject,pk11_attr_expand(&attribute->attrib));
if (newAttribute == NULL) {
- PK11_USE_THREADS(PZ_Unlock(srcObject->attributeLock);)
+ PK11_USE_THREADS(PZ_Unlock(src_so->attributeLock);)
return CKR_HOST_MEMORY;
}
pk11_AddAttribute(destObject,newAttribute);
@@ -958,7 +2041,7 @@ pk11_CopyObject(PK11Object *destObject,PK11Object *srcObject)
}
} while (attribute != NULL);
}
- PK11_USE_THREADS(PZ_Unlock(srcObject->attributeLock);)
+ PK11_USE_THREADS(PZ_Unlock(src_so->attributeLock);)
return CKR_OK;
}
@@ -1012,7 +2095,7 @@ pk11_objectMatch(PK11Object *object,CK_ATTRIBUTE_PTR theTemplate,int count)
* in the object list.
*/
CK_RV
-pk11_searchObjectList(PK11ObjectListElement **objectList,PK11Object **head,
+pk11_searchObjectList(PK11SearchResults *search,PK11Object **head,
PZLock *lock, CK_ATTRIBUTE_PTR theTemplate, int count, PRBool isLoggedIn)
{
int i;
@@ -1027,10 +2110,7 @@ pk11_searchObjectList(PK11ObjectListElement **objectList,PK11Object **head,
if (pk11_objectMatch(object,theTemplate,count)) {
/* don't return objects that aren't yet visible */
if ((!isLoggedIn) && pk11_isTrue(object,CKA_PRIVATE)) continue;
- crv = AddToList(objectList,object);
- if (crv != CKR_OK) {
- break;
- }
+ pk11_addHandle(search,object->handle);
}
}
PK11_USE_THREADS(PZ_Unlock(lock);)
@@ -1126,37 +2206,11 @@ pk11_FreeContext(PK11SessionContext *context)
if (context->hashInfo) {
(*context->hashdestroy)(context->hashInfo,PR_TRUE);
}
- PORT_Free(context);
-}
-
-/* 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)
-{
- switch (slotID) {
- case NETSCAPE_SLOT_ID:
- return &pk11_slot[0];
- case PRIVATE_KEY_SLOT_ID:
- return &pk11_slot[1];
- case FIPS_SLOT_ID:
- return &pk11_slot[2];
- default:
- break; /* fall through to NULL */
+ if (context->key) {
+ pk11_FreeObject(context->key);
+ context->key = NULL;
}
- return NULL;
-}
-
-PK11Slot *
-pk11_SlotFromSessionHandle(CK_SESSION_HANDLE handle)
-{
- if (handle & PK11_PRIVATE_KEY_FLAG) {
- return &pk11_slot[1];
- }
- if (handle & PK11_FIPS_FLAG) {
- return &pk11_slot[2];
- }
- return &pk11_slot[0];
+ PORT_Free(context);
}
/*
@@ -1278,3 +2332,190 @@ pk11_FreeSession(PK11Session *session)
if (destroy) pk11_DestroySession(session);
}
+/*
+ * handle Token Object stuff
+ */
+
+/* Make a token handle for an object and record it so we can find it again */
+CK_OBJECT_HANDLE
+pk11_mkHandle(PK11Slot *slot, SECItem *dbKey, CK_OBJECT_HANDLE class)
+{
+ unsigned char hashBuf[SHA1_LENGTH];
+ CK_OBJECT_HANDLE handle;
+ SECItem *key;
+
+ handle = class;
+ /* there is only one KRL, use a fixed handle for it */
+ if (handle != PK11_TOKEN_KRL_HANDLE) {
+ SHA1_HashBuf(hashBuf,dbKey->data,dbKey->len);
+ handle = (hashBuf[0] << 24) | (hashBuf[1] << 16) |
+ (hashBuf[2] << 8) | hashBuf[3];
+ handle = PK11_TOKEN_MAGIC | class |
+ (handle & ~(PK11_TOKEN_TYPE_MASK|PK11_TOKEN_MASK));
+ /* we have a CRL who's handle has randomly matched the reserved KRL
+ * handle, increment it */
+ if (handle == PK11_TOKEN_KRL_HANDLE) {
+ handle++;
+ }
+ }
+
+ pk11_tokenKeyLock(slot);
+ while ((key = pk11_lookupTokenKeyByHandle(slot,handle)) != NULL) {
+ if (SECITEM_ItemsAreEqual(key,dbKey)) {
+ pk11_tokenKeyUnlock(slot);
+ return handle;
+ }
+ handle++;
+ }
+ pk11_addTokenKeyByHandle(slot,handle,dbKey);
+ pk11_tokenKeyUnlock(slot);
+ return handle;
+}
+
+void
+pk11_addHandle(PK11SearchResults *search, CK_OBJECT_HANDLE handle)
+{
+ if (search->handles == NULL) {
+ return;
+ }
+ if (search->size >= search->array_size) {
+ search->array_size += NSC_SEARCH_BLOCK_SIZE;
+ search->handles = (CK_OBJECT_HANDLE *) PORT_Realloc(search->handles,
+ sizeof(CK_OBJECT_HANDLE)* search->array_size);
+ if (search->handles == NULL) {
+ return;
+ }
+ }
+ search->handles[search->size] = handle;
+ search->size++;
+}
+
+static const CK_OBJECT_HANDLE pk11_classArray[] = {
+ 0, CKO_PRIVATE_KEY, CKO_PUBLIC_KEY, CKO_SECRET_KEY,
+ CKO_NETSCAPE_TRUST, CKO_NETSCAPE_CRL, CKO_NETSCAPE_SMIME,
+ CKO_CERTIFICATE };
+
+#define handleToClass(handle) \
+ pk11_classArray[((handle & PK11_TOKEN_TYPE_MASK))>>28]
+
+PK11Object *
+pk11_NewTokenObject(PK11Slot *slot, SECItem *dbKey, CK_OBJECT_HANDLE handle)
+{
+ PK11Object *object = NULL;
+ PK11TokenObject *tokObject = NULL;
+ SECStatus rv;
+
+#ifdef PKCS11_STATIC_ATTRIBUTES
+ object = (PK11Object *) PORT_ZAlloc(sizeof(PK11TokenObject));
+ if (object == NULL) {
+ return NULL;
+ }
+#else
+ PRArenaPool *arena;
+
+ arena = PORT_NewArena(2048);
+ if (arena == NULL) return NULL;
+
+ object = (PK11Object*)PORT_ArenaAlloc(arena,sizeof(PK11TokenObject));
+ if (object == NULL) {
+ PORT_FreeArena(arena,PR_FALSE);
+ return NULL;
+ }
+ object->arena = arena;
+#endif
+ tokObject = (PK11TokenObject *) object;
+
+ object->objclass = handleToClass(handle);
+ object->handle = handle;
+ object->refCount = 1;
+ object->slot = slot;
+ object->objectInfo = NULL;
+ object->infoFree = NULL;
+ if (dbKey == NULL) {
+ pk11_tokenKeyLock(slot);
+ dbKey = pk11_lookupTokenKeyByHandle(slot,handle);
+ if (dbKey == NULL) {
+ pk11_tokenKeyUnlock(slot);
+ goto loser;
+ }
+ rv = SECITEM_CopyItem(NULL,&tokObject->dbKey,dbKey);
+ pk11_tokenKeyUnlock(slot);
+ } else {
+ rv = SECITEM_CopyItem(NULL,&tokObject->dbKey,dbKey);
+ }
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+#ifdef PKCS11_USE_THREADS
+ object->refLock = PZ_NewLock(nssILockRefLock);
+ if (object->refLock == NULL) {
+ goto loser;
+ }
+#endif
+
+ return object;
+loser:
+ if (object) {
+ pk11_FreeObject(object);
+ }
+ return NULL;
+
+}
+
+PRBool
+pk11_tokenMatch(PK11Slot *slot, SECItem *dbKey, CK_OBJECT_HANDLE class,
+ CK_ATTRIBUTE_PTR theTemplate,int count)
+{
+ PK11Object *object;
+ PRBool ret;
+
+ object = pk11_NewTokenObject(slot,dbKey,PK11_TOKEN_MASK|class);
+ if (object == NULL) {
+ return PR_FALSE;
+ }
+
+ ret = pk11_objectMatch(object,theTemplate,count);
+ pk11_FreeObject(object);
+ return ret;
+}
+
+PK11TokenObject *
+pk11_convertSessionToToken(PK11SessionObject *so)
+{
+ SECItem *key;
+ PK11TokenObject *to = pk11_narrowToTokenObject(&so->obj);
+ SECStatus rv;
+
+ pk11_DestroySessionObjectData(so);
+ PK11_USE_THREADS(PZ_DestroyLock(so->attributeLock));
+ if (to == NULL) {
+ return NULL;
+ }
+ pk11_tokenKeyLock(so->obj.slot);
+ key = pk11_lookupTokenKeyByHandle(so->obj.slot,so->obj.handle);
+ if (key == NULL) {
+ pk11_tokenKeyUnlock(so->obj.slot);
+ return NULL;
+ }
+ rv = SECITEM_CopyItem(NULL,&to->dbKey,key);
+ pk11_tokenKeyUnlock(so->obj.slot);
+ if (rv == SECFailure) {
+ return NULL;
+ }
+
+ return to;
+
+}
+
+PK11SessionObject *
+pk11_narrowToSessionObject(PK11Object *obj)
+{
+ return !pk11_isToken(obj->handle) ? (PK11SessionObject *)obj : NULL;
+}
+
+PK11TokenObject *
+pk11_narrowToTokenObject(PK11Object *obj)
+{
+ return pk11_isToken(obj->handle) ? (PK11TokenObject *)obj : NULL;
+}
+
diff --git a/security/nss/lib/softoken/rsawrapr.c b/security/nss/lib/softoken/rsawrapr.c
index 7ada1e28c..b1e499016 100644
--- a/security/nss/lib/softoken/rsawrapr.c
+++ b/security/nss/lib/softoken/rsawrapr.c
@@ -40,7 +40,7 @@
#include "softoken.h"
#include "sechash.h"
-#include "keylow.h"
+#include "lowkeyi.h"
#include "secerr.h"
#define RSA_BLOCK_MIN_PAD_LEN 8
@@ -182,8 +182,8 @@ oaep_xor_with_h2(unsigned char *salt, unsigned int saltlen,
* Format one block of data for public/private key encryption using
* the rules defined in PKCS #1.
*/
-unsigned char *
-RSA_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType,
+static unsigned char *
+rsa_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType,
SECItem *data)
{
unsigned char *block;
@@ -341,8 +341,8 @@ RSA_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType,
return block;
}
-SECStatus
-RSA_FormatBlock(SECItem *result, unsigned modulusLen,
+static SECStatus
+rsa_FormatBlock(SECItem *result, unsigned modulusLen,
RSA_BlockType blockType, SECItem *data)
{
/*
@@ -370,7 +370,7 @@ RSA_FormatBlock(SECItem *result, unsigned modulusLen,
*/
PORT_Assert (data->len <= (modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN)));
- result->data = RSA_FormatOneBlock(modulusLen, blockType, data);
+ result->data = rsa_FormatOneBlock(modulusLen, blockType, data);
if (result->data == NULL) {
result->len = 0;
return SECFailure;
@@ -390,7 +390,7 @@ RSA_FormatBlock(SECItem *result, unsigned modulusLen,
PORT_Assert (data->len <= (modulusLen - (2 + OAEP_SALT_LEN
+ OAEP_PAD_LEN)));
- result->data = RSA_FormatOneBlock(modulusLen, blockType, data);
+ result->data = rsa_FormatOneBlock(modulusLen, blockType, data);
if (result->data == NULL) {
result->len = 0;
return SECFailure;
@@ -420,193 +420,9 @@ RSA_FormatBlock(SECItem *result, unsigned modulusLen,
return SECSuccess;
}
-/*
- * Takes a formatted block and returns the data part.
- * (This is the inverse of RSA_FormatOneBlock().)
- * In some formats the start of the data is ambiguous;
- * if it is non-zero, expectedLen will disambiguate.
- *
- * NOTE: this routine is not yet used/tested! (XXX please
- * remove this comment once that is no longer the case ;-)
- */
-unsigned char *
-RSA_DecodeOneBlock(unsigned char *data,
- unsigned int modulusLen,
- unsigned int expectedLen,
- RSA_BlockType *pResultType,
- unsigned int *pResultLen)
-{
- RSA_BlockType blockType;
- unsigned char *dp, *res;
- unsigned int i, len, padLen;
-
- dp = data;
- if (*dp++ != RSA_BLOCK_FIRST_OCTET) {
- PORT_SetError (SEC_ERROR_BAD_DATA);
- return NULL;
- }
-
- blockType = (RSA_BlockType)*dp++;
- switch (blockType) {
- case RSA_BlockPrivate0:
- if (expectedLen) {
- padLen = modulusLen - expectedLen - 3;
- PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN);
- for (i = 0; i < padLen; i++) {
- if (*dp++ != RSA_BLOCK_PRIVATE0_PAD_OCTET)
- break;
- }
- if ((i != padLen) || (*dp != RSA_BLOCK_AFTER_PAD_OCTET)) {
- PORT_SetError (SEC_ERROR_BAD_DATA);
- return NULL;
- }
- dp++;
- len = expectedLen;
- } else {
- for (i = 0; i < modulusLen; i++) {
- if (*dp++ != RSA_BLOCK_PRIVATE0_PAD_OCTET)
- break;
- }
- if (i == modulusLen) {
- PORT_SetError (SEC_ERROR_BAD_DATA);
- return NULL;
- }
- if (RSA_BLOCK_PRIVATE0_PAD_OCTET == RSA_BLOCK_AFTER_PAD_OCTET)
- dp--;
- padLen = dp - data - 2;
- if ((padLen < RSA_BLOCK_MIN_PAD_LEN)
- || (*dp != RSA_BLOCK_AFTER_PAD_OCTET)) {
- PORT_SetError (SEC_ERROR_BAD_DATA);
- return NULL;
- }
- dp++;
- len = modulusLen - (dp - data);
- }
- res = (unsigned char *) PORT_Alloc(len);
- if (res == NULL) {
- return NULL;
- }
- PORT_Memcpy (res, dp, len);
- break;
-
- case RSA_BlockPrivate:
- for (i = 0; i < modulusLen; i++) {
- if (*dp++ != RSA_BLOCK_PRIVATE_PAD_OCTET)
- break;
- }
- if ((i == modulusLen) || (*dp != RSA_BLOCK_AFTER_PAD_OCTET)) {
- PORT_SetError (SEC_ERROR_BAD_DATA);
- return NULL;
- }
- padLen = dp - data - 2;
- dp++;
- len = modulusLen - (dp - data);
- if ((padLen < RSA_BLOCK_MIN_PAD_LEN) || (expectedLen
- && (expectedLen != len))) {
- PORT_SetError (SEC_ERROR_BAD_DATA);
- return NULL;
- }
- res = (unsigned char *) PORT_Alloc(len);
- if (res == NULL) {
- return NULL;
- }
- PORT_Memcpy (res, dp, len);
- break;
-
- case RSA_BlockPublic:
- for (i = 0; i < modulusLen; i++) {
- if (*dp++ == RSA_BLOCK_AFTER_PAD_OCTET)
- break;
- }
- if (i == modulusLen) {
- PORT_SetError (SEC_ERROR_BAD_DATA);
- return NULL;
- }
- padLen = dp - data - 2;
- dp++;
- len = modulusLen - (dp - data);
- if ((padLen < RSA_BLOCK_MIN_PAD_LEN) || (expectedLen
- && (expectedLen != len))) {
- PORT_SetError (SEC_ERROR_BAD_DATA);
- return NULL;
- }
- res = (unsigned char *) PORT_Alloc(len);
- if (res == NULL) {
- return NULL;
- }
- PORT_Memcpy (res, dp, len);
- break;
-
- case RSA_BlockOAEP:
- {
- unsigned char *salt, *tmp_res;
- SECStatus rv;
-
- len = modulusLen - 2 - OAEP_SALT_LEN;
- /*
- * dp points to:
- * Modified2(Salt) || Modified1(PaddedData)
- * To recover Salt we need to XOR it with the low-order hash
- * of Modified1.
- */
- salt = (unsigned char *) PORT_Alloc(OAEP_SALT_LEN);
- if (salt == NULL) {
- return NULL;
- }
- PORT_Memcpy (salt, dp, OAEP_SALT_LEN);
- dp += OAEP_SALT_LEN;
- rv = oaep_xor_with_h2 (salt, OAEP_SALT_LEN, dp, len);
- if (rv != SECSuccess) {
- PORT_Free (salt);
- return NULL;
- }
- if (expectedLen) {
- PORT_Assert (expectedLen <= len);
- len = expectedLen;
- }
- tmp_res = (unsigned char *) PORT_Alloc(len);
- if (tmp_res == NULL) {
- PORT_Free (salt);
- return NULL;
- }
- PORT_Memcpy (tmp_res, dp, len);
- rv = oaep_xor_with_h1 (tmp_res, len, salt, OAEP_SALT_LEN);
- PORT_Free (salt);
- if (rv != SECSuccess) {
- return NULL;
- }
- for (i = 0; i < OAEP_PAD_LEN; i++) {
- if (tmp_res[i] != OAEP_PAD_OCTET) {
- PORT_SetError (SEC_ERROR_BAD_DATA);
- PORT_Free (tmp_res);
- return NULL;
- }
- }
- len -= OAEP_PAD_LEN;
- res = (unsigned char *) PORT_Alloc(len);
- if (res == NULL) {
- PORT_Free (tmp_res);
- return NULL;
- }
- PORT_Memcpy (res, tmp_res + OAEP_PAD_LEN, len);
- PORT_Free (tmp_res);
- }
- break;
-
- default:
- PORT_SetError (SEC_ERROR_BAD_DATA);
- return NULL;
- }
-
- PORT_Assert (res != NULL);
- *pResultLen = len;
- *pResultType = blockType;
- return res;
-}
-
/* XXX Doesn't set error code */
SECStatus
-RSA_Sign(SECKEYLowPrivateKey *key,
+RSA_Sign(NSSLOWKEYPrivateKey *key,
unsigned char * output,
unsigned int * output_len,
unsigned int maxOutputLen,
@@ -614,20 +430,20 @@ RSA_Sign(SECKEYLowPrivateKey *key,
unsigned int input_len)
{
SECStatus rv = SECSuccess;
- unsigned int modulus_len = SECKEY_LowPrivateModulusLen(key);
+ unsigned int modulus_len = nsslowkey_PrivateModulusLen(key);
SECItem formatted;
SECItem unformatted;
if (maxOutputLen < modulus_len)
return SECFailure;
- PORT_Assert(key->keyType == lowRSAKey);
- if (key->keyType != lowRSAKey)
+ PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
+ if (key->keyType != NSSLOWKEYRSAKey)
return SECFailure;
unformatted.len = input_len;
unformatted.data = input;
formatted.data = NULL;
- rv = RSA_FormatBlock(&formatted, modulus_len, RSA_BlockPrivate,
+ rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockPrivate,
&unformatted);
if (rv != SECSuccess)
goto done;
@@ -645,24 +461,24 @@ done:
/* XXX Doesn't set error code */
SECStatus
-RSA_CheckSign(SECKEYLowPublicKey *key,
+RSA_CheckSign(NSSLOWKEYPublicKey *key,
unsigned char * sign,
unsigned int sign_len,
unsigned char * hash,
unsigned int hash_len)
{
SECStatus rv;
- unsigned int modulus_len = SECKEY_LowPublicModulusLen(key);
+ unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
unsigned int i;
unsigned char * buffer;
- modulus_len = SECKEY_LowPublicModulusLen(key);
+ modulus_len = nsslowkey_PublicModulusLen(key);
if (sign_len != modulus_len)
goto failure;
if (hash_len > modulus_len - 8)
goto failure;
- PORT_Assert(key->keyType == lowRSAKey);
- if (key->keyType != lowRSAKey)
+ PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
+ if (key->keyType != NSSLOWKEYRSAKey)
goto failure;
buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
@@ -702,7 +518,7 @@ failure:
/* XXX Doesn't set error code */
SECStatus
-RSA_CheckSignRecover(SECKEYLowPublicKey *key,
+RSA_CheckSignRecover(NSSLOWKEYPublicKey *key,
unsigned char * data,
unsigned int * data_len,
unsigned int max_output_len,
@@ -710,14 +526,14 @@ RSA_CheckSignRecover(SECKEYLowPublicKey *key,
unsigned int sign_len)
{
SECStatus rv;
- unsigned int modulus_len = SECKEY_LowPublicModulusLen(key);
+ unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
unsigned int i;
unsigned char * buffer;
if (sign_len != modulus_len)
goto failure;
- PORT_Assert(key->keyType == lowRSAKey);
- if (key->keyType != lowRSAKey)
+ PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
+ if (key->keyType != NSSLOWKEYRSAKey)
goto failure;
buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
@@ -763,7 +579,7 @@ failure:
/* XXX Doesn't set error code */
SECStatus
-RSA_EncryptBlock(SECKEYLowPublicKey *key,
+RSA_EncryptBlock(NSSLOWKEYPublicKey *key,
unsigned char * output,
unsigned int * output_len,
unsigned int max_output_len,
@@ -771,21 +587,21 @@ RSA_EncryptBlock(SECKEYLowPublicKey *key,
unsigned int input_len)
{
SECStatus rv;
- unsigned int modulus_len = SECKEY_LowPublicModulusLen(key);
+ unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
SECItem formatted;
SECItem unformatted;
formatted.data = NULL;
if (max_output_len < modulus_len)
goto failure;
- PORT_Assert(key->keyType == lowRSAKey);
- if (key->keyType != lowRSAKey)
+ PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
+ if (key->keyType != NSSLOWKEYRSAKey)
goto failure;
unformatted.len = input_len;
unformatted.data = input;
formatted.data = NULL;
- rv = RSA_FormatBlock(&formatted, modulus_len, RSA_BlockPublic,
+ rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockPublic,
&unformatted);
if (rv != SECSuccess)
goto failure;
@@ -806,7 +622,7 @@ failure:
/* XXX Doesn't set error code */
SECStatus
-RSA_DecryptBlock(SECKEYLowPrivateKey *key,
+RSA_DecryptBlock(NSSLOWKEYPrivateKey *key,
unsigned char * output,
unsigned int * output_len,
unsigned int max_output_len,
@@ -814,12 +630,12 @@ RSA_DecryptBlock(SECKEYLowPrivateKey *key,
unsigned int input_len)
{
SECStatus rv;
- unsigned int modulus_len = SECKEY_LowPrivateModulusLen(key);
+ unsigned int modulus_len = nsslowkey_PrivateModulusLen(key);
unsigned int i;
unsigned char * buffer;
- PORT_Assert(key->keyType == lowRSAKey);
- if (key->keyType != lowRSAKey)
+ PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
+ if (key->keyType != NSSLOWKEYRSAKey)
goto failure;
if (input_len != modulus_len)
goto failure;
@@ -863,7 +679,7 @@ failure:
* RAW is RSA_X_509
*/
SECStatus
-RSA_SignRaw(SECKEYLowPrivateKey *key,
+RSA_SignRaw(NSSLOWKEYPrivateKey *key,
unsigned char * output,
unsigned int * output_len,
unsigned int maxOutputLen,
@@ -871,20 +687,20 @@ RSA_SignRaw(SECKEYLowPrivateKey *key,
unsigned int input_len)
{
SECStatus rv = SECSuccess;
- unsigned int modulus_len = SECKEY_LowPrivateModulusLen(key);
+ unsigned int modulus_len = nsslowkey_PrivateModulusLen(key);
SECItem formatted;
SECItem unformatted;
if (maxOutputLen < modulus_len)
return SECFailure;
- PORT_Assert(key->keyType == lowRSAKey);
- if (key->keyType != lowRSAKey)
+ PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
+ if (key->keyType != NSSLOWKEYRSAKey)
return SECFailure;
unformatted.len = input_len;
unformatted.data = input;
formatted.data = NULL;
- rv = RSA_FormatBlock(&formatted, modulus_len, RSA_BlockRaw, &unformatted);
+ rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockRaw, &unformatted);
if (rv != SECSuccess)
goto done;
@@ -899,22 +715,22 @@ done:
/* XXX Doesn't set error code */
SECStatus
-RSA_CheckSignRaw(SECKEYLowPublicKey *key,
+RSA_CheckSignRaw(NSSLOWKEYPublicKey *key,
unsigned char * sign,
unsigned int sign_len,
unsigned char * hash,
unsigned int hash_len)
{
SECStatus rv;
- unsigned int modulus_len = SECKEY_LowPublicModulusLen(key);
+ unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
unsigned char * buffer;
if (sign_len != modulus_len)
goto failure;
if (hash_len > modulus_len)
goto failure;
- PORT_Assert(key->keyType == lowRSAKey);
- if (key->keyType != lowRSAKey)
+ PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
+ if (key->keyType != NSSLOWKEYRSAKey)
goto failure;
buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
@@ -943,7 +759,7 @@ failure:
/* XXX Doesn't set error code */
SECStatus
-RSA_CheckSignRecoverRaw(SECKEYLowPublicKey *key,
+RSA_CheckSignRecoverRaw(NSSLOWKEYPublicKey *key,
unsigned char * data,
unsigned int * data_len,
unsigned int max_output_len,
@@ -951,14 +767,14 @@ RSA_CheckSignRecoverRaw(SECKEYLowPublicKey *key,
unsigned int sign_len)
{
SECStatus rv;
- unsigned int modulus_len = SECKEY_LowPublicModulusLen(key);
+ unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
if (sign_len != modulus_len)
goto failure;
if (max_output_len < modulus_len)
goto failure;
- PORT_Assert(key->keyType == lowRSAKey);
- if (key->keyType != lowRSAKey)
+ PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
+ if (key->keyType != NSSLOWKEYRSAKey)
goto failure;
rv = RSA_PublicKeyOp(&key->u.rsa, data, sign);
@@ -975,7 +791,7 @@ failure:
/* XXX Doesn't set error code */
SECStatus
-RSA_EncryptRaw(SECKEYLowPublicKey *key,
+RSA_EncryptRaw(NSSLOWKEYPublicKey *key,
unsigned char * output,
unsigned int * output_len,
unsigned int max_output_len,
@@ -983,21 +799,21 @@ RSA_EncryptRaw(SECKEYLowPublicKey *key,
unsigned int input_len)
{
SECStatus rv;
- unsigned int modulus_len = SECKEY_LowPublicModulusLen(key);
+ unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
SECItem formatted;
SECItem unformatted;
formatted.data = NULL;
if (max_output_len < modulus_len)
goto failure;
- PORT_Assert(key->keyType == lowRSAKey);
- if (key->keyType != lowRSAKey)
+ PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
+ if (key->keyType != NSSLOWKEYRSAKey)
goto failure;
unformatted.len = input_len;
unformatted.data = input;
formatted.data = NULL;
- rv = RSA_FormatBlock(&formatted, modulus_len, RSA_BlockRaw, &unformatted);
+ rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockRaw, &unformatted);
if (rv != SECSuccess)
goto failure;
@@ -1017,7 +833,7 @@ failure:
/* XXX Doesn't set error code */
SECStatus
-RSA_DecryptRaw(SECKEYLowPrivateKey *key,
+RSA_DecryptRaw(NSSLOWKEYPrivateKey *key,
unsigned char * output,
unsigned int * output_len,
unsigned int max_output_len,
@@ -1025,14 +841,14 @@ RSA_DecryptRaw(SECKEYLowPrivateKey *key,
unsigned int input_len)
{
SECStatus rv;
- unsigned int modulus_len = SECKEY_LowPrivateModulusLen(key);
+ unsigned int modulus_len = nsslowkey_PrivateModulusLen(key);
if (modulus_len <= 0)
goto failure;
if (modulus_len > max_output_len)
goto failure;
- PORT_Assert(key->keyType == lowRSAKey);
- if (key->keyType != lowRSAKey)
+ PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
+ if (key->keyType != NSSLOWKEYRSAKey)
goto failure;
if (input_len != modulus_len)
goto failure;
diff --git a/security/nss/lib/softoken/secpkcs5.c b/security/nss/lib/softoken/secpkcs5.c
deleted file mode 100644
index 1cfa37206..000000000
--- a/security/nss/lib/softoken/secpkcs5.c
+++ /dev/null
@@ -1,1849 +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.
- */
-
-#include "plarena.h"
-
-#include "seccomon.h"
-#include "secitem.h"
-#include "secport.h"
-#include "hasht.h"
-#include "pkcs11t.h"
-#include "blapi.h"
-#include "sechash.h"
-#include "secasn1.h"
-#include "secder.h"
-#include "secpkcs5.h"
-#include "secoid.h"
-#include "alghmac.h"
-#include "softoken.h"
-#include "secerr.h"
-
-#define DES_IV_LENGTH 8
-#define RC2_IV_LENGTH 8
-#define MD2_LENGTH 16
-#define MD5_LENGTH 16
-#define SHA1_LENGTH 20
-#define SEED_LENGTH 16
-#define SALT_LENGTH 8
-#define PBE_SALT_LENGTH 16
-
-/* template for PKCS 5 PBE Parameter. This template has been expanded
- * based upon the additions in PKCS 12. This should eventually be moved
- * if RSA updates PKCS 5.
- */
-const SEC_ASN1Template SEC_PKCS5PBEParameterTemplate[] =
-{
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SEC_PKCS5PBEParameter) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(SEC_PKCS5PBEParameter, salt) },
- { SEC_ASN1_INTEGER,
- offsetof(SEC_PKCS5PBEParameter, iteration) },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_V2PKCS12PBEParameterTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter) },
- { SEC_ASN1_OCTET_STRING, offsetof(SEC_PKCS5PBEParameter, salt) },
- { SEC_ASN1_INTEGER, offsetof(SEC_PKCS5PBEParameter, iteration) },
- { 0 }
-};
-
-pbeBitGenParameters pbeHashAlgorithmParams[] = {
- { 0, 0, SEC_OID_UNKNOWN },
- { 128, 512, SEC_OID_MD2 },
- { 128, 512, SEC_OID_MD5 },
- { 160, 512, SEC_OID_SHA1 },
-};
-
-/* generate some random bytes. this is used to generate the
- * salt if it is not specified.
- */
-static SECStatus
-sec_pkcs5_generate_random_bytes(PRArenaPool *poolp,
- SECItem *dest, int len)
-{
- SECStatus rv = SECFailure;
-
- if(dest != NULL)
- {
- void *mark = PORT_ArenaMark(poolp);
- dest->data = (unsigned char *)PORT_ArenaZAlloc(poolp, len);
- if(dest->data != NULL)
- {
- dest->len = len;
- RNG_GenerateGlobalRandomBytes(dest->data, dest->len);
- PORT_ArenaUnmark(poolp, mark);
- rv = SECSuccess;
- } else
- PORT_ArenaRelease(poolp, mark);
- }
-
- return rv;
-}
-
-/* maps hash algorithm from PBE algorithm.
- */
-static SECOidTag
-sec_pkcs5_hash_algorithm(SECOidTag algorithm)
-{
- switch(algorithm)
- {
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- return SEC_OID_SHA1;
- case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
- return SEC_OID_MD5;
- case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
- return SEC_OID_MD2;
- default:
- break;
- }
- return SEC_OID_UNKNOWN;
-}
-
-/* get the iv length needed for the PBE algorithm
- */
-static int
-sec_pkcs5_iv_length(SECOidTag algorithm)
-{
- switch(algorithm)
- {
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
- return DES_IV_LENGTH;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- return RC2_IV_LENGTH;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
- return 0;
- default:
- break;
- }
- return -1;
-}
-
-/* get the key length needed for the PBE algorithm
- */
-static int
-sec_pkcs5_key_length(SECOidTag algorithm)
-{
- switch(algorithm)
- {
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
- return 24;
- case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
- return 8;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- return 5;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
- return 16;
- default:
- break;
- }
- return -1;
-}
-
-/* the V2 algorithms only encode the salt, there is no iteration
- * count so we need a check for V2 algorithm parameters.
- */
-static PRBool
-sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(SECOidTag algorithm)
-{
- switch(algorithm)
- {
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- return PR_TRUE;
- default:
- break;
- }
-
- return PR_FALSE;
-}
-
-/* creates a PBE parameter based on the PBE algorithm. the only required
- * parameters are algorithm and interation. the return is a PBE parameter
- * which conforms to PKCS 5 parameter unless an extended parameter is needed.
- * this is primarily if keyLen and a variable key length algorithm are
- * specified.
- * salt - if null, a salt will be generated from random bytes.
- * iteration - number of iterations to perform hashing.
- * keyLen - only used in variable key length algorithms
- * iv - if null, the IV will be generated based on PKCS 5 when needed.
- * params - optional, currently unsupported additional parameters.
- * once a parameter is allocated, it should be destroyed calling
- * sec_pkcs5_destroy_pbe_parameter or SEC_PKCS5DestroyPBEParameter.
- */
-static SEC_PKCS5PBEParameter *
-sec_pkcs5_create_pbe_parameter(SECOidTag algorithm,
- SECItem *salt,
- int iteration)
-{
- PRArenaPool *poolp = NULL;
- SEC_PKCS5PBEParameter *pbe_param = NULL;
- SECStatus rv;
- void *dummy = NULL;
-
- if(iteration < 0) {
- return NULL;
- }
-
- poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(poolp == NULL)
- return NULL;
-
- pbe_param = (SEC_PKCS5PBEParameter *)PORT_ArenaZAlloc(poolp,
- sizeof(SEC_PKCS5PBEParameter));
- if(!pbe_param) {
- PORT_FreeArena(poolp, PR_TRUE);
- return NULL;
- }
-
- pbe_param->poolp = poolp;
- pbe_param->algorithm = algorithm;
-
- /* should we generate the salt? */
- if(!salt || !salt->data) {
- rv = sec_pkcs5_generate_random_bytes(poolp, &pbe_param->salt,
- SALT_LENGTH);
- } else {
- rv = SECITEM_CopyItem(poolp, &pbe_param->salt, salt);
- }
-
- if(rv != SECSuccess) {
- PORT_FreeArena(poolp, PR_TRUE);
- return NULL;
- }
-
- /* encode the integer */
- dummy = SEC_ASN1EncodeInteger(poolp, &pbe_param->iteration,
- iteration);
- rv = (dummy) ? SECSuccess : SECFailure;
-
- if(rv != SECSuccess) {
- PORT_FreeArena(poolp, PR_FALSE);
- return NULL;
- }
-
- return pbe_param;
-}
-
-/* generate bits for key and iv using MD5 hashing
- */
-static SECItem *
-sec_pkcs5_compute_md5_hash(SECItem *salt, SECItem *pwd, int iter,
- PRBool dummy)
-{
- SECItem *hash = NULL, *pre_hash = NULL;
- SECStatus rv = SECFailure;
-
- if((salt == NULL) || (pwd == NULL) || (iter < 0)) {
- return NULL;
- }
-
- hash = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- pre_hash = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if((hash != NULL) && (pre_hash != NULL)) {
- unsigned int i, ph_len;
-
- ph_len = MD5_LENGTH;
- if(ph_len < (salt->len + pwd->len)) {
- ph_len = salt->len + pwd->len;
- }
-
- rv = SECFailure;
- hash->data = (unsigned char *)PORT_ZAlloc(MD5_LENGTH);
- hash->len = MD5_LENGTH;
- pre_hash->data = (unsigned char *)PORT_ZAlloc(ph_len);
- pre_hash->len = salt->len + pwd->len;
-
- if((hash->data != NULL) && (pre_hash->data != NULL)) {
- rv = SECSuccess;
- /* handle 0 length password */
- if(pwd->len > 0) {
- PORT_Memcpy(pre_hash->data, pwd->data, pwd->len);
- }
- if(salt->len > 0) {
- PORT_Memcpy((pre_hash->data+pwd->len), salt->data, salt->len);
- }
- for(i = 0; ((i < (unsigned int)iter) && (rv == SECSuccess)); i++) {
- rv = MD5_HashBuf(hash->data, pre_hash->data, pre_hash->len);
- if(rv != SECFailure) {
- PORT_Memcpy(pre_hash->data, hash->data, MD5_LENGTH);
- pre_hash->len = MD5_LENGTH;
- }
- }
- }
- }
-
- if(pre_hash != NULL)
- SECITEM_FreeItem(pre_hash, PR_TRUE);
-
- if((rv == SECFailure) && (hash)) {
- SECITEM_FreeItem(hash, PR_TRUE);
- hash = NULL;
- }
-
- return hash;
-}
-
-/* generate bits for key and iv using MD2 hashing
- */
-static SECItem *
-sec_pkcs5_compute_md2_hash(SECItem *salt, SECItem *pwd, int iter,
- PRBool dummy)
-{
- SECItem *hash = NULL, *pre_hash = NULL;
- SECStatus rv = SECFailure;
-
- if((salt == NULL) || (pwd == NULL) || (iter < 0))
- return NULL;
-
- hash = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- pre_hash = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if((hash != NULL) && (pre_hash != NULL))
- {
- int i, ph_len;
-
- ph_len = MD2_LENGTH;
- if((salt->len + pwd->len) > MD2_LENGTH)
- ph_len = salt->len+pwd->len;
-
- rv = SECFailure;
- hash->data = (unsigned char *)PORT_ZAlloc(MD2_LENGTH);
- hash->len = MD2_LENGTH;
- pre_hash->data = (unsigned char *)PORT_ZAlloc(ph_len);
- pre_hash->len = salt->len + pwd->len;
-
- if((hash->data != NULL) && (pre_hash->data != NULL))
- {
- MD2Context *ctxt;
-
- rv = SECSuccess;
- if(pwd->len > 0) {
- PORT_Memcpy(pre_hash->data, pwd->data, pwd->len);
- }
- if(salt->len > 0) {
- PORT_Memcpy((pre_hash->data+pwd->len), salt->data, salt->len);
- }
-
- for(i = 0; ((i < iter) && (rv == SECSuccess)); i++)
- {
- ctxt = MD2_NewContext();
- if(ctxt == NULL)
- rv = SECFailure;
- else
- {
- MD2_Update(ctxt, pre_hash->data, pre_hash->len);
- MD2_End(ctxt, hash->data, &hash->len, hash->len);
- PORT_Memcpy(pre_hash->data, hash->data, MD2_LENGTH);
- pre_hash->len = MD2_LENGTH;
- MD2_DestroyContext(ctxt, PR_TRUE);
- }
- }
- }
- }
-
- if(pre_hash != NULL)
- SECITEM_FreeItem(pre_hash, PR_TRUE);
-
- if(rv != SECSuccess)
- if(hash != NULL)
- {
- SECITEM_FreeItem(hash, PR_TRUE);
- hash = NULL;
- }
-
- return hash;
-}
-
-/* generate bits using SHA1 hash
- */
-static SECItem *
-sec_pkcs5_compute_sha1_hash(SECItem *salt, SECItem *pwd, int iter,
- PRBool faulty3DES)
-{
- SECItem *hash = NULL, *pre_hash = NULL;
- SECStatus rv = SECFailure;
-
- if((salt == NULL) || (pwd == NULL) || (iter < 0)) {
- return NULL;
- }
-
- hash = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- pre_hash = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
-
- if((hash != NULL) && (pre_hash != NULL)) {
- int i, ph_len;
-
- ph_len = SHA1_LENGTH;
- if((salt->len + pwd->len) > SHA1_LENGTH) {
- ph_len = salt->len + pwd->len;
- }
-
- rv = SECFailure;
-
- /* allocate buffers */
- hash->data = (unsigned char *)PORT_ZAlloc(SHA1_LENGTH);
- hash->len = SHA1_LENGTH;
- pre_hash->data = (unsigned char *)PORT_ZAlloc(ph_len);
-
- /* in pbeSHA1TripleDESCBC there was an allocation error that made
- * it into the caller. We do not want to propagate those errors
- * further, so we are doing it correctly, but reading the old method.
- */
- if(faulty3DES) {
- pre_hash->len = ph_len;
- } else {
- pre_hash->len = salt->len + pwd->len;
- }
-
- /* preform hash */
- if((hash->data != NULL) && (pre_hash->data != NULL)) {
- rv = SECSuccess;
- /* check for 0 length password */
- if(pwd->len > 0) {
- PORT_Memcpy(pre_hash->data, pwd->data, pwd->len);
- }
- if(salt->len > 0) {
- PORT_Memcpy((pre_hash->data+pwd->len), salt->data, salt->len);
- }
- for(i = 0; ((i < iter) && (rv == SECSuccess)); i++) {
- rv = SHA1_HashBuf(hash->data, pre_hash->data, pre_hash->len);
- if(rv != SECFailure) {
- pre_hash->len = SHA1_LENGTH;
- PORT_Memcpy(pre_hash->data, hash->data, SHA1_LENGTH);
- }
- }
- }
- }
-
- if(pre_hash != NULL) {
- SECITEM_FreeItem(pre_hash, PR_TRUE);
- }
-
- if((rv != SECSuccess) && (hash != NULL)) {
- SECITEM_FreeItem(hash, PR_TRUE);
- hash = NULL;
- }
-
- return hash;
-}
-
-/* bit generation/key and iv generation routines. */
-typedef SECItem *(* sec_pkcs5_hash_func)(SECItem *s, SECItem *p,
- int iter, PRBool faulty3DES);
-
-/* generates bits needed for the key and iv based on PKCS 5,
- * be concatenating the password and salt and using the appropriate
- * hash algorithm. This function serves as a front end to the
- * specific hash functions above. a return of NULL indicates an
- * error.
- */
-static SECItem *
-sec_pkcs5_compute_hash(SEC_PKCS5PBEParameter *pbe_param, SECItem *pwitem,
- PRBool faulty3DES)
-{
- sec_pkcs5_hash_func hash_func;
- SECOidTag hash_alg;
- SECItem *hash = NULL;
- SECItem *salt = NULL;
-
- hash_alg = sec_pkcs5_hash_algorithm(pbe_param->algorithm);
- salt = &(pbe_param->salt);
- switch(hash_alg)
- {
- case SEC_OID_SHA1:
- hash_func = sec_pkcs5_compute_sha1_hash;
- break;
- case SEC_OID_MD2:
- hash_func = sec_pkcs5_compute_md2_hash;
- break;
- case SEC_OID_MD5:
- hash_func = sec_pkcs5_compute_md5_hash;
- break;
- default:
- hash_func = NULL;
- }
-
- if(hash_func) {
- hash = (* hash_func)(salt, pwitem, pbe_param->iter, faulty3DES);
- }
-
- return hash;
-}
-
-/* determines the number of bits needed for key and iv generation
- * based upon the algorithm identifier. if a number of
- * bits greater than the hash algorithm can produce are needed,
- * the bits will be generated based upon the extended PKCS 5
- * described in PKCS 12.
- *
- * a return of -1 indicates an error.
- */
-static int
-sec_pkcs5_bits_needed(SEC_PKCS5PBEParameter *pbe_param)
-{
- int iv_bits;
- int key_bits;
-
- if(pbe_param == NULL) {
- return -1;
- }
-
- iv_bits = sec_pkcs5_iv_length(pbe_param->algorithm) * 8;
- key_bits = sec_pkcs5_key_length(pbe_param->algorithm) * 8;
-
- if(key_bits != 0) {
- return iv_bits + key_bits;
- }
-
- return -1;
-}
-
-/* determines the number of bits generated by each hash algorithm.
- * in case of an error, -1 is returned.
- */
-static int
-sec_pkcs5_hash_bits_generated(SEC_PKCS5PBEParameter *pbe_param)
-{
- if(pbe_param == NULL) {
- return -1;
- }
-
- switch(sec_pkcs5_hash_algorithm(pbe_param->algorithm)) {
- case SEC_OID_SHA1:
- return SHA1_LENGTH * 8;
- case SEC_OID_MD2:
- return MD2_LENGTH * 8;
- case SEC_OID_MD5:
- return MD5_LENGTH * 8;
- default:
- break;
- }
-
- return -1;
-}
-
-/* this bit generation routine is described in PKCS 12 and the proposed
- * extensions to PKCS 5. an initial hash is generated following the
- * instructions laid out in PKCS 5. If the number of bits generated is
- * insufficient, then the method discussed in the proposed extensions to
- * PKCS 5 in PKCS 12 are used. This extension makes use of the HMAC
- * function. And the P_Hash function from the TLS standard.
- */
-static SECItem *
-sec_pkcs5_bit_generator(SEC_PKCS5PBEParameter *pbe_param,
- SECItem *init_hash,
- unsigned int bits_needed)
-{
- SECItem *ret_bits = NULL;
- int hash_size = 0;
- unsigned int i;
- unsigned int hash_iter;
- unsigned int dig_len;
- SECStatus rv = SECFailure;
- unsigned char *state = NULL;
- unsigned int state_len;
- HMACContext *cx = NULL;
-
- hash_size = sec_pkcs5_hash_bits_generated(pbe_param);
- if(hash_size == -1)
- return NULL;
-
- hash_iter = (bits_needed + (unsigned int)hash_size - 1) / hash_size;
- hash_size /= 8;
-
- /* allocate return buffer */
- ret_bits = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(ret_bits == NULL)
- return NULL;
- ret_bits->data = (unsigned char *)PORT_ZAlloc((hash_iter * hash_size) + 1);
- ret_bits->len = (hash_iter * hash_size);
- if(ret_bits->data == NULL) {
- PORT_Free(ret_bits);
- return NULL;
- }
-
- /* allocate intermediate hash buffer. 8 is for the 8 bytes of
- * data which are added based on iteration number
- */
-
- if ((unsigned int)hash_size > pbe_param->salt.len) {
- state_len = hash_size;
- } else {
- state_len = pbe_param->salt.len;
- }
- state = (unsigned char *)PORT_ZAlloc(state_len);
- if(state == NULL) {
- rv = SECFailure;
- goto loser;
- }
- if(pbe_param->salt.len > 0) {
- PORT_Memcpy(state, pbe_param->salt.data, pbe_param->salt.len);
- }
-
- cx = HMAC_Create(sec_pkcs5_hash_algorithm(pbe_param->algorithm),
- init_hash->data, init_hash->len);
- if (cx == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- for(i = 0; i < hash_iter; i++) {
-
- /* generate output bits */
- HMAC_Begin(cx);
- HMAC_Update(cx, state, state_len);
- HMAC_Update(cx, pbe_param->salt.data, pbe_param->salt.len);
- rv = HMAC_Finish(cx, ret_bits->data + (i * hash_size),
- &dig_len, hash_size);
- if (rv != SECSuccess)
- goto loser;
- PORT_Assert((unsigned int)hash_size == dig_len);
-
- /* generate new state */
- HMAC_Begin(cx);
- HMAC_Update(cx, state, state_len);
- rv = HMAC_Finish(cx, state, &state_len, state_len);
- if (rv != SECSuccess)
- goto loser;
- PORT_Assert(state_len == dig_len);
- }
-
-loser:
- if (state != NULL)
- PORT_ZFree(state, state_len);
- HMAC_Destroy(cx);
-
- if(rv != SECSuccess) {
- SECITEM_ZfreeItem(ret_bits, PR_TRUE);
- ret_bits = NULL;
- }
-
- return ret_bits;
-}
-
-/* generate bits for the key and iv determination. if enough bits
- * are not generated using PKCS 5, then we need to generate more bits
- * based on the extension proposed in PKCS 12
- */
-static SECItem *
-sec_pkcs5_generate_bits(SEC_PKCS5PBEParameter *pbe_param, SECItem *pwitem,
- PRBool faulty3DES)
-{
- SECItem * hash = NULL;
- SECItem * newHash = NULL;
- int bits_needed;
- int bits_available;
-
- bits_needed = sec_pkcs5_bits_needed(pbe_param);
- bits_available = sec_pkcs5_hash_bits_generated(pbe_param);
-
- if((bits_needed == -1) || (bits_available == -1)) {
- return NULL;
- }
-
- hash = sec_pkcs5_compute_hash(pbe_param, pwitem, faulty3DES);
- if(hash == NULL) {
- return NULL;
- }
-
- if(bits_needed <= bits_available) {
- return hash;
- }
-
- newHash = sec_pkcs5_bit_generator(pbe_param, hash, bits_needed);
- if (hash != newHash)
- SECITEM_FreeItem(hash, PR_TRUE);
- return newHash;
-}
-
-/* compute the IV as per PKCS 5
- */
-static SECItem *
-sec_pkcs5_compute_iv(SEC_PKCS5PBEParameter *pbe_param, SECItem *pwitem,
- PRBool faulty3DES)
-{
- SECItem *hash = NULL, *iv = NULL;
-
- if((pbe_param == NULL) || (pwitem == NULL)) {
- return NULL;
- }
-
- /* generate iv */
- iv = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(!iv) {
- return NULL;
- }
-
- iv->len = sec_pkcs5_iv_length(pbe_param->algorithm);
- if(iv->len == -1) {
- PORT_Free(iv);
- return NULL;
- }
-
- iv->data = (unsigned char *)PORT_ZAlloc(iv->len);
- if(iv->data == NULL) {
- PORT_Free(iv);
- return NULL;
- }
-
- if(sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(pbe_param->algorithm)) {
- SECOidTag hashAlg;
- PBEBitGenContext *ctxt;
- hashAlg = sec_pkcs5_hash_algorithm(pbe_param->algorithm);
- ctxt = PBE_CreateContext(hashAlg, pbeBitGenCipherIV,
- pwitem, &pbe_param->salt,
- iv->len * 8, pbe_param->iter);
- if(!ctxt) {
- SECITEM_FreeItem(iv, PR_TRUE);
- return NULL;
- }
-
- hash = PBE_GenerateBits(ctxt);
- PBE_DestroyContext(ctxt);
- } else {
- hash = sec_pkcs5_generate_bits(pbe_param, pwitem, faulty3DES);
- }
-
- if(!hash) {
- SECITEM_FreeItem(iv, PR_TRUE);
- return NULL;
- }
-
- PORT_Memcpy(iv->data, (hash->data+(hash->len - iv->len)), iv->len);
- SECITEM_FreeItem(hash, PR_TRUE);
-
- return iv;
-}
-
-/* generate key as per PKCS 5
- */
-static SECItem *
-sec_pkcs5_compute_key(SEC_PKCS5PBEParameter *pbe_param, SECItem *pwitem,
- PRBool faulty3DES)
-{
- SECItem *hash = NULL, *key = NULL;
-
- if((pbe_param == NULL) || (pwitem == NULL)) {
- return NULL;
- }
-
- key = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(!key) {
- return NULL;
- }
-
- key->len = sec_pkcs5_key_length(pbe_param->algorithm);
- if(key->len == -1) {
- PORT_Free(key);
- return NULL;
- }
-
- key->data = (unsigned char *)PORT_ZAlloc(sizeof(unsigned char) *
- key->len);
- if(!key->data) {
- PORT_Free(key);
- return NULL;
- }
-
-
- if(sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(pbe_param->algorithm)) {
- SECOidTag hashAlg;
- PBEBitGenContext *ctxt;
- hashAlg = sec_pkcs5_hash_algorithm(pbe_param->algorithm);
- ctxt = PBE_CreateContext(hashAlg, pbeBitGenCipherKey,
- pwitem, &pbe_param->salt,
- key->len * 8, pbe_param->iter);
- if(!ctxt) {
- SECITEM_FreeItem(key, PR_TRUE);
- return NULL;
- }
-
- hash = PBE_GenerateBits(ctxt);
- PBE_DestroyContext(ctxt);
- } else {
- hash = sec_pkcs5_generate_bits(pbe_param, pwitem, faulty3DES);
- }
-
- if(!hash) {
- SECITEM_FreeItem(key, PR_TRUE);
- return NULL;
- }
-
- if(pbe_param->algorithm ==
- SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC) {
- PORT_Memcpy(key->data, hash->data, (key->len * 2) / 3);
- PORT_Memcpy(&(key->data[(key->len * 2) / 3]), key->data,
- key->len / 3);
- } else {
- PORT_Memcpy(key->data, hash->data, key->len);
- }
-
- SECITEM_FreeItem(hash, PR_TRUE);
- return key;
-}
-
-/* decode the algid and generate a PKCS 5 parameter from it
- */
-static SEC_PKCS5PBEParameter *
-sec_pkcs5_convert_algid(SECAlgorithmID *algid)
-{
- PRArenaPool *poolp;
- SEC_PKCS5PBEParameter *pbe_param = NULL;
- SECOidTag algorithm;
- SECStatus rv = SECFailure;
-
- if(algid == NULL)
- return NULL;
-
- algorithm = SECOID_GetAlgorithmTag(algid);
-
- if(sec_pkcs5_hash_algorithm(algorithm) == SEC_OID_UNKNOWN)
- return NULL;
-
- poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(poolp == NULL)
- return NULL;
-
- /* allocate memory for the parameter */
- pbe_param = (SEC_PKCS5PBEParameter *)PORT_ArenaZAlloc(poolp,
- sizeof(SEC_PKCS5PBEParameter));
-
- /* decode parameter */
- if(pbe_param && !sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) {
- pbe_param->poolp = poolp;
- rv = SEC_ASN1DecodeItem(poolp, pbe_param,
- SEC_PKCS5PBEParameterTemplate, &algid->parameters);
- if(rv != SECSuccess) {
- goto loser;
- }
- pbe_param->algorithm = algorithm;
- pbe_param->iter = DER_GetInteger(&pbe_param->iteration);
- } else if(sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) {
- pbe_param->algorithm = algorithm;
- pbe_param->poolp = poolp;
- rv = SEC_ASN1DecodeItem(poolp, pbe_param, SEC_V2PKCS12PBEParameterTemplate,
- &algid->parameters);
- if(rv != SECSuccess) {
- goto loser;
- }
- pbe_param->iter = DER_GetInteger(&pbe_param->iteration);
- }
-
-loser:
- if((pbe_param == NULL) || (rv != SECSuccess)) {
- PORT_FreeArena(poolp, PR_TRUE);
- pbe_param = NULL;
- }
-
- return pbe_param;
-}
-
-/* destroy a pbe parameter. it assumes that the parameter was
- * generated using the appropriate create function and therefor
- * contains an arena pool.
- */
-static void
-sec_pkcs5_destroy_pbe_param(SEC_PKCS5PBEParameter *pbe_param)
-{
- if(pbe_param != NULL)
- PORT_FreeArena(pbe_param->poolp, PR_TRUE);
-}
-
-
-/* crypto routines */
-
-/* function pointer template for crypto functions */
-typedef SECItem *(* pkcs5_crypto_func)(SECItem *key, SECItem *iv,
- SECItem *src, PRBool op1, PRBool op2);
-
-/* map PBE algorithm to crypto algorithm */
-static SECOidTag
-sec_pkcs5_encryption_algorithm(SECOidTag algorithm)
-{
- switch(algorithm)
- {
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
- return SEC_OID_DES_EDE3_CBC;
- case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
- return SEC_OID_DES_CBC;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- return SEC_OID_RC2_CBC;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
- return SEC_OID_RC4;
- default:
- break;
- }
- return SEC_OID_UNKNOWN;
-}
-
-/* perform DES encryption and decryption. these routines are called
- * by SEC_PKCS5CipherData. In the case of an error, NULL is returned.
- */
-static SECItem *
-sec_pkcs5_des(SECItem *key,
- SECItem *iv,
- SECItem *src,
- PRBool triple_des,
- PRBool encrypt)
-{
- SECItem *dest;
- SECItem *dup_src;
- SECStatus rv = SECFailure;
- int pad;
-
- if((src == NULL) || (key == NULL) || (iv == NULL))
- return NULL;
-
- dup_src = SECITEM_DupItem(src);
- if(dup_src == NULL) {
- return NULL;
- }
-
- if(encrypt != PR_FALSE) {
- void *dummy;
-
- dummy = DES_PadBuffer(NULL, dup_src->data,
- dup_src->len, &dup_src->len);
- if(dummy == NULL) {
- SECITEM_FreeItem(dup_src, PR_TRUE);
- return NULL;
- }
- dup_src->data = (unsigned char*)dummy;
- }
-
- dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(dest != NULL) {
- /* allocate with over flow */
- dest->data = (unsigned char *)PORT_ZAlloc(dup_src->len + 64);
- if(dest->data != NULL) {
- DESContext *ctxt;
- ctxt = DES_CreateContext(key->data, iv->data,
- (triple_des ? NSS_DES_EDE3_CBC : NSS_DES_CBC),
- encrypt);
-
- if(ctxt != NULL) {
- rv = ((encrypt != PR_TRUE) ? DES_Decrypt : DES_Encrypt)(
- ctxt, dest->data, &dest->len,
- dup_src->len + 64, dup_src->data, dup_src->len);
-
- /* remove padding -- assumes 64 bit blocks */
- if((encrypt == PR_FALSE) && (rv == SECSuccess)) {
- pad = dest->data[dest->len-1];
- if((pad > 0) && (pad <= 8)) {
- if(dest->data[dest->len-pad] != pad) {
- rv = SECFailure;
- PORT_SetError(SEC_ERROR_BAD_PASSWORD);
- } else {
- dest->len -= pad;
- }
- } else {
- rv = SECFailure;
- PORT_SetError(SEC_ERROR_BAD_PASSWORD);
- }
- }
- DES_DestroyContext(ctxt, PR_TRUE);
- }
- }
- }
-
- if(rv == SECFailure) {
- if(dest != NULL) {
- SECITEM_FreeItem(dest, PR_TRUE);
- }
- dest = NULL;
- }
-
- if(dup_src != NULL) {
- SECITEM_FreeItem(dup_src, PR_TRUE);
- }
-
- return dest;
-}
-
-/* perform rc2 encryption/decryption if an error occurs, NULL is returned
- */
-static SECItem *
-sec_pkcs5_rc2(SECItem *key,
- SECItem *iv,
- SECItem *src,
- PRBool cbc_mode,
- PRBool encrypt)
-{
- SECItem *dest;
- SECItem *dup_src;
- SECStatus rv = SECFailure;
- int pad;
-
- if((src == NULL) || (key == NULL) || (iv == NULL)) {
- return NULL;
- }
-
- dup_src = SECITEM_DupItem(src);
- if(dup_src == NULL) {
- return NULL;
- }
-
- if(encrypt != PR_FALSE) {
- void *dummy;
-
- dummy = DES_PadBuffer(NULL, dup_src->data,
- dup_src->len, &dup_src->len);
- if(dummy == NULL) {
- SECITEM_FreeItem(dup_src, PR_TRUE);
- return NULL;
- }
- dup_src->data = (unsigned char*)dummy;
- }
-
- dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(dest != NULL) {
- dest->data = (unsigned char *)PORT_ZAlloc(dup_src->len + 64);
- if(dest->data != NULL) {
- RC2Context *ctxt;
-
- ctxt = RC2_CreateContext(key->data, key->len, iv->data,
- ((cbc_mode != PR_TRUE) ? NSS_RC2 : NSS_RC2_CBC),
- key->len);
-
- if(ctxt != NULL) {
- rv = ((encrypt != PR_TRUE) ? RC2_Decrypt : RC2_Encrypt)(
- ctxt, dest->data, &dest->len,
- dup_src->len + 64, dup_src->data, dup_src->len);
-
- /* assumes 8 byte blocks -- remove padding */
- if((rv == SECSuccess) && (encrypt != PR_TRUE) &&
- (cbc_mode == PR_TRUE)) {
- pad = dest->data[dest->len-1];
- if((pad > 0) && (pad <= 8)) {
- if(dest->data[dest->len-pad] != pad) {
- PORT_SetError(SEC_ERROR_BAD_PASSWORD);
- rv = SECFailure;
- } else {
- dest->len -= pad;
- }
- } else {
- PORT_SetError(SEC_ERROR_BAD_PASSWORD);
- rv = SECFailure;
- }
- }
-
- }
- }
- }
-
- if((rv != SECSuccess) && (dest != NULL)) {
- SECITEM_FreeItem(dest, PR_TRUE);
- dest = NULL;
- }
-
- if(dup_src != NULL) {
- SECITEM_FreeItem(dup_src, PR_TRUE);
- }
-
- return dest;
-}
-
-/* perform rc4 encryption and decryption */
-static SECItem *
-sec_pkcs5_rc4(SECItem *key,
- SECItem *iv,
- SECItem *src,
- PRBool dummy_op,
- PRBool encrypt)
-{
- SECItem *dest;
- SECStatus rv = SECFailure;
-
- if((src == NULL) || (key == NULL) || (iv == NULL)) {
- return NULL;
- }
-
- dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(dest != NULL) {
- dest->data = (unsigned char *)PORT_ZAlloc(sizeof(unsigned char) *
- (src->len + 64));
- if(dest->data != NULL) {
- RC4Context *ctxt;
-
- ctxt = RC4_CreateContext(key->data, key->len);
- if(ctxt) {
- rv = ((encrypt != PR_FALSE) ? RC4_Decrypt : RC4_Encrypt)(
- ctxt, dest->data, &dest->len,
- src->len + 64, src->data, src->len);
- RC4_DestroyContext(ctxt, PR_TRUE);
- }
- }
- }
-
- if((rv != SECSuccess) && (dest)) {
- SECITEM_FreeItem(dest, PR_TRUE);
- dest = NULL;
- }
-
- return dest;
-}
-
-/* performs the cipher operation on the src and returns the result.
- * if an error occurs, NULL is returned.
- *
- * a null length password is allowed. this corresponds to encrypting
- * the data with ust the salt.
- */
-/* change this to use PKCS 11? */
-SECItem *
-SEC_PKCS5CipherData(SECAlgorithmID *algid,
- SECItem *pwitem,
- SECItem *src,
- PRBool encrypt, PRBool *update)
-{
- SEC_PKCS5PBEParameter *pbe_param;
- SECOidTag enc_alg;
- SECItem *key = NULL, *iv = NULL;
- SECItem *dest = NULL;
- int iv_len;
-
- if (update) {
- *update = PR_FALSE;
- }
-
- if((algid == NULL) || (pwitem == NULL) || (src == NULL)) {
- return NULL;
- }
-
- /* convert algid to pbe parameter */
- pbe_param = sec_pkcs5_convert_algid(algid);
- if(pbe_param == NULL) {
- return NULL;
- }
-
- /* get algorithm, key, and iv */
- enc_alg = sec_pkcs5_encryption_algorithm(pbe_param->algorithm);
- key = sec_pkcs5_compute_key(pbe_param, pwitem, PR_FALSE);
- if(key != NULL) {
- iv_len = sec_pkcs5_iv_length(pbe_param->algorithm);
- iv = sec_pkcs5_compute_iv(pbe_param, pwitem, PR_FALSE);
-
- if((iv != NULL) || (iv_len == 0)) {
- /*perform encryption / decryption */
- PRBool op1 = PR_TRUE;
- pkcs5_crypto_func cryptof;
-
- switch(enc_alg) {
- case SEC_OID_DES_EDE3_CBC:
- cryptof = sec_pkcs5_des;
- break;
- case SEC_OID_DES_CBC:
- cryptof = sec_pkcs5_des;
- op1 = PR_FALSE;
- break;
- case SEC_OID_RC2_CBC:
- cryptof = sec_pkcs5_rc2;
- break;
- case SEC_OID_RC4:
- cryptof = sec_pkcs5_rc4;
- break;
- default:
- cryptof = NULL;
- break;
- }
-
- if(cryptof) {
- dest = (*cryptof)(key, iv, src, op1, encrypt);
- /*
- * it's possible for some keys and keydb's to claim to
- * be triple des when they're really des. In this case
- * we simply try des. If des works we set the update flag
- * so the key db knows it needs to update all it's entries.
- * The case can only happen on decrypted of a
- * SEC_OID_DES_EDE3_CBD.
- */
- if ((dest == NULL) && (encrypt == PR_FALSE) &&
- (enc_alg == SEC_OID_DES_EDE3_CBC)) {
- dest = (*cryptof)(key, iv, src, PR_FALSE, encrypt);
- if (update && (dest != NULL)) *update = PR_TRUE;
- }
- }
- }
- }
-
- sec_pkcs5_destroy_pbe_param(pbe_param);
-
- if(key != NULL) {
- SECITEM_ZfreeItem(key, PR_TRUE);
- }
- if(iv != NULL) {
- SECITEM_ZfreeItem(iv, PR_TRUE);
- }
-
- return dest;
-}
-
-/* creates a algorithm ID containing the PBE algorithm and appropriate
- * parameters. the required parameter is the algorithm. if salt is
- * not specified, it is generated randomly. if IV is specified, it overrides
- * the PKCS 5 generation of the IV.
- *
- * the returned SECAlgorithmID should be destroyed using
- * SECOID_DestroyAlgorithmID
- */
-SECAlgorithmID *
-SEC_PKCS5CreateAlgorithmID(SECOidTag algorithm,
- SECItem *salt,
- int iteration)
-{
- PRArenaPool *poolp = NULL;
- SECAlgorithmID *algid, *ret_algid;
- SECItem der_param;
- SECStatus rv = SECFailure;
- SEC_PKCS5PBEParameter *pbe_param;
-
- if(sec_pkcs5_hash_algorithm(algorithm) == SEC_OID_UNKNOWN)
- return NULL;
-
- if(iteration <= 0) {
- return NULL;
- }
-
- der_param.data = NULL;
- der_param.len = 0;
-
- /* generate the parameter */
- pbe_param = sec_pkcs5_create_pbe_parameter(algorithm, salt, iteration);
- if(!pbe_param) {
- return NULL;
- }
-
- poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(!poolp) {
- sec_pkcs5_destroy_pbe_param(pbe_param);
- return NULL;
- }
-
- /* generate the algorithm id */
- algid = (SECAlgorithmID *)PORT_ArenaZAlloc(poolp, sizeof(SECAlgorithmID));
- if(algid != NULL) {
- void *dummy;
- if(!sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) {
- dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param,
- SEC_PKCS5PBEParameterTemplate);
- } else {
- dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param,
- SEC_V2PKCS12PBEParameterTemplate);
- }
-
- if(dummy) {
- rv = SECOID_SetAlgorithmID(poolp, algid, algorithm, &der_param);
- }
- }
-
- ret_algid = NULL;
- if(algid != NULL) {
- ret_algid = (SECAlgorithmID *)PORT_ZAlloc(sizeof(SECAlgorithmID));
- if(ret_algid != NULL) {
- rv = SECOID_CopyAlgorithmID(NULL, ret_algid, algid);
- if(rv != SECSuccess) {
- SECOID_DestroyAlgorithmID(ret_algid, PR_TRUE);
- ret_algid = NULL;
- }
- }
- }
-
- if(poolp != NULL) {
- PORT_FreeArena(poolp, PR_TRUE);
- algid = NULL;
- }
-
- sec_pkcs5_destroy_pbe_param(pbe_param);
-
- return ret_algid;
-}
-
-/* wrapper for converting the algid to a pbe parameter.
- */
-SEC_PKCS5PBEParameter *
-SEC_PKCS5GetPBEParameter(SECAlgorithmID *algid)
-{
- if(algid) {
- return sec_pkcs5_convert_algid(algid);
- }
-
- return NULL;
-}
-
-/* destroy a pbe parameter */
-void
-SEC_PKCS5DestroyPBEParameter(SEC_PKCS5PBEParameter *pbe_param)
-{
- sec_pkcs5_destroy_pbe_param(pbe_param);
-}
-
-/* return the initialization vector either the preset one if it
- * exists or generated based on pkcs 5.
- *
- * a null length password is allowed...but not a null password
- * secitem.
- */
-SECItem *
-SEC_PKCS5GetIV(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES)
-{
- SECItem *iv;
- SEC_PKCS5PBEParameter *pbe_param;
-
- if((algid == NULL) || (pwitem == NULL)) {
- return NULL;
- }
-
- pbe_param = sec_pkcs5_convert_algid(algid);
- if(!pbe_param) {
- return NULL;
- }
-
- iv = sec_pkcs5_compute_iv(pbe_param, pwitem, faulty3DES);
-
- sec_pkcs5_destroy_pbe_param(pbe_param);
-
- return iv;
-}
-
-/* generate the key
- * a 0 length password is allowed. corresponds to a key generated
- * from just the salt.
- */
-SECItem *
-SEC_PKCS5GetKey(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES)
-{
- SECItem *key;
- SEC_PKCS5PBEParameter *pbe_param;
-
- if((algid == NULL) || (pwitem == NULL)) {
- return NULL;
- }
-
- pbe_param = sec_pkcs5_convert_algid(algid);
- if(pbe_param == NULL) {
- return NULL;
- }
-
- key = sec_pkcs5_compute_key(pbe_param, pwitem, faulty3DES);
-
- sec_pkcs5_destroy_pbe_param(pbe_param);
-
- return key;
-}
-
-/* retrieve the salt */
-SECItem *
-SEC_PKCS5GetSalt(SECAlgorithmID *algid)
-{
- SECItem *salt;
- SEC_PKCS5PBEParameter *pbe_param;
-
- if(algid == NULL)
- return NULL;
-
- pbe_param = sec_pkcs5_convert_algid(algid);
- if(pbe_param == NULL)
- return NULL;
-
- if(pbe_param->salt.data) {
- salt = SECITEM_DupItem(&pbe_param->salt);
- } else {
- salt = NULL;
- }
-
- sec_pkcs5_destroy_pbe_param(pbe_param);
-
- return salt;
-}
-
-/* check to see if an oid is a pbe algorithm
- */
-PRBool
-SEC_PKCS5IsAlgorithmPBEAlg(SECAlgorithmID *algid)
-{
- SECOidTag algorithm;
-
- algorithm = SECOID_GetAlgorithmTag(algid);
- if(sec_pkcs5_hash_algorithm(algorithm) == SEC_OID_UNKNOWN) {
- return PR_FALSE;
- }
-
- return PR_TRUE;
-}
-
-int
-SEC_PKCS5GetKeyLength(SECAlgorithmID *algid)
-{
- SEC_PKCS5PBEParameter *pbe_param;
- int keyLen = -1;
-
- if(algid == NULL)
- return -1;
-
- pbe_param = sec_pkcs5_convert_algid(algid);
- if(pbe_param == NULL)
- return -1;
-
- keyLen = sec_pkcs5_key_length(pbe_param->algorithm);
-
- sec_pkcs5_destroy_pbe_param(pbe_param);
-
- return keyLen;
-}
-
-/* maps crypto algorithm from PBE algorithm.
- */
-SECOidTag
-SEC_PKCS5GetCryptoAlgorithm(SECAlgorithmID *algid)
-{
- SEC_PKCS5PBEParameter *pbe_param;
-
- if(algid == NULL)
- return SEC_OID_UNKNOWN;
-
- pbe_param = sec_pkcs5_convert_algid(algid);
- if(pbe_param == NULL)
- return SEC_OID_UNKNOWN;
-
- switch(pbe_param->algorithm)
- {
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
- return SEC_OID_DES_EDE3_CBC;
- case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
- return SEC_OID_DES_CBC;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- return SEC_OID_RC2_CBC;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
- return SEC_OID_RC4;
- default:
- break;
- }
-
- sec_pkcs5_destroy_pbe_param(pbe_param);
-
- return SEC_OID_UNKNOWN;
-}
-
-/* maps PBE algorithm from crypto algorithm, assumes SHA1 hashing.
- */
-SECOidTag
-SEC_PKCS5GetPBEAlgorithm(SECOidTag algTag, int keyLen)
-{
- switch(algTag)
- {
- case SEC_OID_DES_EDE3_CBC:
- switch(keyLen) {
- case 168:
- case 192:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC;
- case 128:
- case 92:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC;
- default:
- break;
- }
- break;
- case SEC_OID_DES_CBC:
- return SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC;
- case SEC_OID_RC2_CBC:
- switch(keyLen) {
- case 40:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC;
- case 128:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC;
- default:
- break;
- }
- break;
- case SEC_OID_RC4:
- switch(keyLen) {
- case 40:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4;
- case 128:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4;
- default:
- break;
- }
- break;
- default:
- break;
- }
-
- return SEC_OID_UNKNOWN;
-}
-
-/* zero length password and salts are allowed. however, the items
- * containing the salt and password must be non-null.
- */
-PBEBitGenContext *
-__PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
- SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded,
- unsigned int iterations)
-{
- PRArenaPool *arena = NULL;
- PBEBitGenContext *pbeCtxt = NULL;
- HASH_HashType pbeHash;
- int vbytes, ubytes;
-
- unsigned int c;
-
- if(!pwitem || !salt) {
- return NULL;
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if(!arena) {
- return NULL;
- }
-
- pbeCtxt = (PBEBitGenContext*)PORT_ArenaZAlloc(arena, sizeof(PBEBitGenContext));
- if(!pbeCtxt) {
- goto loser;
- }
-
- switch(hashAlgorithm) {
- case SEC_OID_MD2:
- pbeHash = HASH_AlgMD2;
- break;
- case SEC_OID_MD5:
- pbeHash = HASH_AlgMD5;
- break;
- case SEC_OID_SHA1:
- pbeHash = HASH_AlgSHA1;
- break;
- default:
- goto loser;
- }
-
- pbeCtxt->hashObject = &SECRawHashObjects[pbeHash];
- PORT_Memcpy(&pbeCtxt->pbeParams, &pbeHashAlgorithmParams[pbeHash],
- sizeof(pbeBitGenParameters));
- PORT_Assert(pbeCtxt->pbeParams.hashAlgorithm == hashAlgorithm);
-
- vbytes = pbeCtxt->pbeParams.v / 8;
- ubytes = pbeCtxt->pbeParams.u / 8;
-
- c = (bitsNeeded / pbeCtxt->pbeParams.u);
- c += ((bitsNeeded - (pbeCtxt->pbeParams.u * c)) > 0) ? 1 : 0;
- pbeCtxt->c = c;
- pbeCtxt->n = bitsNeeded;
- pbeCtxt->iterations = iterations;
-
- /* allocate buffers */
- pbeCtxt->D.len = vbytes;
- pbeCtxt->S.len = (((salt->len * 8) / pbeCtxt->pbeParams.v) +
- ((((salt->len * 8) % pbeCtxt->pbeParams.v) > 0) ? 1 : 0)) *
- vbytes;
- pbeCtxt->P.len = (((pwitem->len * 8) / pbeCtxt->pbeParams.v) +
- ((((pwitem->len * 8) % pbeCtxt->pbeParams.v) > 0) ? 1 : 0)) *
- vbytes;
- pbeCtxt->I.len = pbeCtxt->S.len + pbeCtxt->P.len;
- pbeCtxt->A.len = c * ubytes;
- pbeCtxt->B.len = pbeCtxt->D.len;
-
- pbeCtxt->D.data = (unsigned char*)PORT_ArenaZAlloc(arena, pbeCtxt->D.len);
- if(pbeCtxt->S.len) {
- pbeCtxt->S.data = (unsigned char*)PORT_ArenaZAlloc(arena, pbeCtxt->S.len);
- }
- if(pbeCtxt->P.len) {
- pbeCtxt->P.data = (unsigned char*)PORT_ArenaZAlloc(arena, pbeCtxt->P.len);
- }
- if(pbeCtxt->I.len) {
- pbeCtxt->I.data = (unsigned char*)PORT_ArenaZAlloc(arena, pbeCtxt->I.len);
- }
- pbeCtxt->A.data = (unsigned char*)PORT_ArenaZAlloc(arena, pbeCtxt->A.len);
- pbeCtxt->B.data = (unsigned char*)PORT_ArenaZAlloc(arena, pbeCtxt->B.len);
-
- if(!pbeCtxt->D.data || !pbeCtxt->A.data || !pbeCtxt->B.data ||
- (!pbeCtxt->S.data && pbeCtxt->S.len) ||
- (!pbeCtxt->P.data && pbeCtxt->P.len) ||
- (!pbeCtxt->I.data && pbeCtxt->I.len)) {
- goto loser;
- }
-
- PORT_Memset(pbeCtxt->D.data, (char)bitGenPurpose, pbeCtxt->D.len);
- if(pbeCtxt->P.len) {
- unsigned int z = 0;
- while(z < pbeCtxt->P.len) {
- PORT_Memcpy(&(pbeCtxt->P.data[z]), pwitem->data,
- ((z + pwitem->len > pbeCtxt->P.len) ? (pbeCtxt->P.len - z) :
- (pwitem->len)));
- z += pwitem->len;
- }
- }
- if(pbeCtxt->S.len) {
- unsigned int z = 0;
- while(z < pbeCtxt->S.len) {
- PORT_Memcpy(&(pbeCtxt->S.data[z]), salt->data,
- ((z + salt->len > pbeCtxt->S.len) ? (pbeCtxt->S.len - z) :
- (salt->len)));
- z += salt->len;
- }
- }
- if(pbeCtxt->I.len) {
- if(pbeCtxt->S.len) {
- PORT_Memcpy(pbeCtxt->I.data, pbeCtxt->S.data, pbeCtxt->S.len);
- }
- if(pbeCtxt->P.len) {
- PORT_Memcpy(&(pbeCtxt->I.data[pbeCtxt->S.len]), pbeCtxt->P.data,
- pbeCtxt->P.len);
- }
- }
-
- pbeCtxt->arena = arena;
-
- return pbeCtxt;
-
-loser:
- if(arena) {
- PORT_FreeArena(arena, PR_TRUE);
- }
-
- return NULL;
-}
-
-PBEBitGenContext *
-PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
- SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded,
- unsigned int iterations)
-{
- return __PBE_CreateContext(hashAlgorithm, bitGenPurpose, pwitem,
- salt, bitsNeeded, iterations);
-}
-
-SECItem *
-__PBE_GenerateBits(PBEBitGenContext *pbeCtxt)
-{
- unsigned int i;
- SECItem *A, *D, *I, *B, *S, *P;
- unsigned int u, v, c, z, hashLen, n, iter;
- unsigned int vbyte, ubyte;
- unsigned char *iterBuf;
- void *hash = NULL;
-
- if(!pbeCtxt) {
- return NULL;
- }
-
- A = &pbeCtxt->A;
- B = &pbeCtxt->B;
- I = &pbeCtxt->I;
- D = &pbeCtxt->D;
- S = &pbeCtxt->S;
- P = &pbeCtxt->P;
- u = pbeCtxt->pbeParams.u;
- v = pbeCtxt->pbeParams.v;
- vbyte = v / 8;
- ubyte = u / 8;
- c = pbeCtxt->c;
- n = pbeCtxt->n;
- z = 0;
-
- iterBuf = (unsigned char*)PORT_Alloc(ubyte);
- if(!iterBuf) {
- goto loser;
- }
-
- for(i = 1; i <= c; i++) {
- unsigned int Bidx;
- unsigned int k, j;
-
-
- for(iter = 1; iter <= pbeCtxt->iterations; iter++) {
- hash = pbeCtxt->hashObject->create();
- if(!hash) {
- goto loser;
- }
-
- pbeCtxt->hashObject->begin(hash);
-
- if(iter == 1) {
- pbeCtxt->hashObject->update(hash, D->data, D->len);
- pbeCtxt->hashObject->update(hash, I->data, I->len);
- } else {
- pbeCtxt->hashObject->update(hash, iterBuf, hashLen);
- }
-
- pbeCtxt->hashObject->end(hash, iterBuf, &hashLen, (ubyte));
- pbeCtxt->hashObject->destroy(hash, PR_TRUE);
- if(hashLen != (ubyte)) {
- goto loser;
- }
- }
-
- PORT_Memcpy(&(A->data[z]), iterBuf, (ubyte));
-
- Bidx = 0;
- while(Bidx < B->len) {
- PORT_Memcpy(&(B->data[Bidx]), &(A->data[z]),
- (((Bidx + (ubyte)) > B->len) ? (B->len - Bidx) :
- (ubyte)));
- Bidx += (ubyte);
- }
-
- k = (S->len / (vbyte)) + (P->len / (vbyte));
- for(j = 0; j < k; j++) {
- unsigned int byteIdx = (vbyte);
- unsigned int q, carryBit = 0;
-
- while(byteIdx > 0) {
- q = (unsigned int)I->data[(j * (vbyte)) + byteIdx - 1];
- q += (unsigned int)B->data[byteIdx - 1];
- q += carryBit;
- if(byteIdx == (vbyte)) {
- q += 1;
- }
-
- carryBit = ((q > 255) ? 1 : 0);
-
- I->data[(j * (vbyte)) + byteIdx - 1] = (unsigned char)(q & 255);
-
- byteIdx--;
- }
- }
-
- z += (ubyte);
- }
-
- A->len = (n / 8);
-
- return SECITEM_DupItem(A);
-
-loser:
- return NULL;
-}
-
-SECItem *
-PBE_GenerateBits(PBEBitGenContext *pbeCtxt)
-{
- return __PBE_GenerateBits(pbeCtxt);
-}
-
-void
-__PBE_DestroyContext(PBEBitGenContext *pbeCtxt)
-{
- if(pbeCtxt) {
- PORT_FreeArena(pbeCtxt->arena, PR_TRUE);
- }
-}
-
-void
-PBE_DestroyContext(PBEBitGenContext *pbeCtxt)
-{
- __PBE_DestroyContext(pbeCtxt);
-}
-
-SECStatus
-PBE_PK11ParamToAlgid(SECOidTag algTag, SECItem *param, PRArenaPool *arena,
- SECAlgorithmID *algId)
-{
- CK_PBE_PARAMS *pbe_param;
- SECItem pbeSalt;
- SECAlgorithmID *pbeAlgID = NULL;
- SECStatus rv;
-
- if(!param || !algId) {
- return SECFailure;
- }
-
- pbe_param = (CK_PBE_PARAMS *)param->data;
- pbeSalt.data = (unsigned char *)pbe_param->pSalt;
- pbeSalt.len = pbe_param->ulSaltLen;
- pbeAlgID = SEC_PKCS5CreateAlgorithmID(algTag, &pbeSalt,
- (int)pbe_param->ulIteration);
- if(!pbeAlgID) {
- return SECFailure;
- }
-
- rv = SECOID_CopyAlgorithmID(arena, algId, pbeAlgID);
- SECOID_DestroyAlgorithmID(pbeAlgID, PR_TRUE);
- return rv;
-}
diff --git a/security/nss/lib/softoken/secpkcs5.h b/security/nss/lib/softoken/secpkcs5.h
deleted file mode 100644
index d538450dd..000000000
--- a/security/nss/lib/softoken/secpkcs5.h
+++ /dev/null
@@ -1,185 +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.
- */
-
-#ifndef _SECPKCS5_H_
-#define _SECPKCS5_H_
-
-#include "plarena.h"
-#include "secitem.h"
-#include "seccomon.h"
-#include "secoidt.h"
-#include "hasht.h"
-
-typedef SECItem * (* SEC_PKCS5GetPBEPassword)(void *arg);
-
-/* used for V2 PKCS 12 Draft Spec */
-typedef enum {
- pbeBitGenIDNull = 0,
- pbeBitGenCipherKey = 0x01,
- pbeBitGenCipherIV = 0x02,
- pbeBitGenIntegrityKey = 0x03
-} PBEBitGenID;
-
-typedef struct _pbeBitGenParameters {
- unsigned int u, v;
- SECOidTag hashAlgorithm;
-} pbeBitGenParameters;
-
-typedef struct _PBEBitGenContext {
- PRArenaPool *arena;
-
- /* hash algorithm information */
- pbeBitGenParameters pbeParams;
- const SECHashObject *hashObject;
- void *hash;
-
- /* buffers used in generation of bits */
- SECItem D, S, P, I, A, B;
- unsigned int c, n;
- unsigned int iterations;
-} PBEBitGenContext;
-
-extern const SEC_ASN1Template SEC_PKCS5PBEParameterTemplate[];
-typedef struct SEC_PKCS5PBEParameterStr SEC_PKCS5PBEParameter;
-
-struct SEC_PKCS5PBEParameterStr {
- PRArenaPool *poolp;
- SECItem salt; /* octet string */
- SECItem iteration; /* integer */
-
- /* used locally */
- SECOidTag algorithm;
- int iter;
-};
-
-
-SEC_BEGIN_PROTOS
-/* Create a PKCS5 Algorithm ID
- * The algorithm ID is set up using the PKCS #5 parameter structure
- * algorithm is the PBE algorithm ID for the desired algorithm
- * salt can be specified or can be NULL, if salt is NULL then the
- * salt is generated from random bytes
- * iteration is the number of iterations for which to perform the
- * hash prior to key and iv generation.
- * If an error occurs or the algorithm specified is not supported
- * or is not a password based encryption algorithm, NULL is returned.
- * Otherwise, a pointer to the algorithm id is returned.
- */
-extern SECAlgorithmID *
-SEC_PKCS5CreateAlgorithmID(SECOidTag algorithm,
- SECItem *salt,
- int iteration);
-
-/* Get the initialization vector. The password is passed in, hashing
- * is performed, and the initialization vector is returned.
- * algid is a pointer to a PBE algorithm ID
- * pwitem is the password
- * If an error occurs or the algorithm id is not a PBE algrithm,
- * NULL is returned. Otherwise, the iv is returned in a secitem.
- */
-extern SECItem *
-SEC_PKCS5GetIV(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES);
-
-/* Get the key. The password is passed in, hashing is performed,
- * and the key is returned.
- * algid is a pointer to a PBE algorithm ID
- * pwitem is the password
- * If an error occurs or the algorithm id is not a PBE algrithm,
- * NULL is returned. Otherwise, the key is returned in a secitem.
- */
-extern SECItem *
-SEC_PKCS5GetKey(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES);
-
-/* Get PBE salt. The salt for the password based algorithm is returned.
- * algid is the PBE algorithm identifier
- * If an error occurs NULL is returned, otherwise the salt is returned
- * in a SECItem.
- */
-extern SECItem *
-SEC_PKCS5GetSalt(SECAlgorithmID *algid);
-
-/* Encrypt/Decrypt data using password based encryption.
- * algid is the PBE algorithm identifier,
- * pwitem is the password,
- * src is the source for encryption/decryption,
- * encrypt is PR_TRUE for encryption, PR_FALSE for decryption.
- * The key and iv are generated based upon PKCS #5 then the src
- * is either encrypted or decrypted. If an error occurs, NULL
- * is returned, otherwise the ciphered contents is returned.
- */
-extern SECItem *
-SEC_PKCS5CipherData(SECAlgorithmID *algid, SECItem *pwitem,
- SECItem *src, PRBool encrypt, PRBool *update);
-
-/* Checks to see if algid algorithm is a PBE algorithm. If
- * so, PR_TRUE is returned, otherwise PR_FALSE is returned.
- */
-extern PRBool
-SEC_PKCS5IsAlgorithmPBEAlg(SECAlgorithmID *algid);
-
-/* Destroys PBE parameter */
-extern void
-SEC_PKCS5DestroyPBEParameter(SEC_PKCS5PBEParameter *param);
-
-/* Convert Algorithm ID to PBE parameter */
-extern SEC_PKCS5PBEParameter *
-SEC_PKCS5GetPBEParameter(SECAlgorithmID *algid);
-
-/* Determine how large the key generated is */
-extern int
-SEC_PKCS5GetKeyLength(SECAlgorithmID *algid);
-
-/* map crypto algorithm to pbe algorithm, assume sha 1 hashing for DES
- */
-extern SECOidTag
-SEC_PKCS5GetPBEAlgorithm(SECOidTag algTag, int keyLen);
-
-/* return the underlying crypto algorithm */
-extern SECOidTag
-SEC_PKCS5GetCryptoAlgorithm(SECAlgorithmID *algid);
-
-extern PBEBitGenContext *
-PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
- SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded,
- unsigned int interations);
-
-extern SECItem *
-PBE_GenerateBits(PBEBitGenContext *pbeCtxt);
-
-extern void PBE_DestroyContext(PBEBitGenContext *pbeCtxt);
-
-extern SECStatus PBE_PK11ParamToAlgid(SECOidTag algTag, SECItem *param,
- PRArenaPool *arena, SECAlgorithmID *algId);
-SEC_END_PROTOS
-
-#endif
diff --git a/security/nss/lib/softoken/softoken.h b/security/nss/lib/softoken/softoken.h
index b13a93461..f9fb06222 100644
--- a/security/nss/lib/softoken/softoken.h
+++ b/security/nss/lib/softoken/softoken.h
@@ -39,8 +39,7 @@
#define _SOFTOKEN_H_
#include "blapi.h"
-#include "keytlow.h"
-#include "keytboth.h"
+#include "lowkeyti.h"
#include "softoknt.h"
#include "secoidt.h"
@@ -83,23 +82,23 @@ extern unsigned char *RSA_FormatOneBlock(unsigned int modulusLen,
* RSA_DecryptBlock.
*/
extern
-SECStatus RSA_Sign(SECKEYLowPrivateKey *key, unsigned char *output,
+SECStatus RSA_Sign(NSSLOWKEYPrivateKey *key, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
unsigned char *input, unsigned int inputLen);
extern
-SECStatus RSA_CheckSign(SECKEYLowPublicKey *key, unsigned char *sign,
+SECStatus RSA_CheckSign(NSSLOWKEYPublicKey *key, unsigned char *sign,
unsigned int signLength, unsigned char *hash,
unsigned int hashLength);
extern
-SECStatus RSA_CheckSignRecover(SECKEYLowPublicKey *key, unsigned char *data,
+SECStatus RSA_CheckSignRecover(NSSLOWKEYPublicKey *key, unsigned char *data,
unsigned int *data_len,unsigned int max_output_len,
unsigned char *sign, unsigned int sign_len);
extern
-SECStatus RSA_EncryptBlock(SECKEYLowPublicKey *key, unsigned char *output,
+SECStatus RSA_EncryptBlock(NSSLOWKEYPublicKey *key, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
unsigned char *input, unsigned int inputLen);
extern
-SECStatus RSA_DecryptBlock(SECKEYLowPrivateKey *key, unsigned char *output,
+SECStatus RSA_DecryptBlock(NSSLOWKEYPrivateKey *key, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
unsigned char *input, unsigned int inputLen);
@@ -108,24 +107,24 @@ SECStatus RSA_DecryptBlock(SECKEYLowPrivateKey *key, unsigned char *output,
* RAW is RSA_X_509
*/
extern
-SECStatus RSA_SignRaw( SECKEYLowPrivateKey *key, unsigned char *output,
+SECStatus RSA_SignRaw( NSSLOWKEYPrivateKey *key, unsigned char *output,
unsigned int *output_len, unsigned int maxOutputLen,
unsigned char *input, unsigned int input_len);
extern
-SECStatus RSA_CheckSignRaw( SECKEYLowPublicKey *key, unsigned char *sign,
+SECStatus RSA_CheckSignRaw( NSSLOWKEYPublicKey *key, unsigned char *sign,
unsigned int sign_len, unsigned char *hash,
unsigned int hash_len);
extern
-SECStatus RSA_CheckSignRecoverRaw( SECKEYLowPublicKey *key, unsigned char *data,
+SECStatus RSA_CheckSignRecoverRaw( NSSLOWKEYPublicKey *key, unsigned char *data,
unsigned int *data_len, unsigned int max_output_len,
unsigned char *sign, unsigned int sign_len);
extern
-SECStatus RSA_EncryptRaw( SECKEYLowPublicKey *key, unsigned char *output,
+SECStatus RSA_EncryptRaw( NSSLOWKEYPublicKey *key, unsigned char *output,
unsigned int *output_len,
unsigned int max_output_len,
unsigned char *input, unsigned int input_len);
extern
-SECStatus RSA_DecryptRaw(SECKEYLowPrivateKey *key, unsigned char *output,
+SECStatus RSA_DecryptRaw(NSSLOWKEYPrivateKey *key, unsigned char *output,
unsigned int *output_len,
unsigned int max_output_len,
unsigned char *input, unsigned int input_len);
diff --git a/security/nss/lib/softoken/softokn.def b/security/nss/lib/softoken/softokn.def
new file mode 100644
index 000000000..443583334
--- /dev/null
+++ b/security/nss/lib/softoken/softokn.def
@@ -0,0 +1,57 @@
+;+#
+;+# 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):
+;+# Dr Stephen Henson <stephen.henson@gemplus.com>
+;+#
+;+# 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 ";-"
+;+SOFTOKEN_3.4 { # Softoken 3.4 release
+;+ global:
+LIBRARY softoken ;-
+EXPORTS ;-
+NSC_GetFunctionList ;
+NSC_ModuleDBFunc ;
+FC_GetFunctionList ;
+C_GetFunctionList ; Make this function like a real PKCS #11 module as well
+;+ local:
+;+ *;
+;+};
diff --git a/security/nss/lib/softoken/softokn.rc b/security/nss/lib/softoken/softokn.rc
new file mode 100644
index 000000000..31bdb2272
--- /dev/null
+++ b/security/nss/lib/softoken/softokn.rc
@@ -0,0 +1,98 @@
+/*
+ * 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 "softoken"
+#define MY_FILEDESCRIPTION "NSS Builtin Crypto PKCS #11 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/util/sysrand.c b/security/nss/lib/softoken/sysrand.c
index f79cb9d53..2f647041a 100644
--- a/security/nss/lib/util/sysrand.c
+++ b/security/nss/lib/softoken/sysrand.c
@@ -41,3 +41,6 @@
#ifdef XP_MAC
#include "mac_rand.c"
#endif
+#ifdef XP_OS2
+#include "os2_rand.c"
+#endif
diff --git a/security/nss/lib/util/unix_rand.c b/security/nss/lib/softoken/unix_rand.c
index 12b08aea3..12b08aea3 100644
--- a/security/nss/lib/util/unix_rand.c
+++ b/security/nss/lib/softoken/unix_rand.c
diff --git a/security/nss/lib/util/win_rand.c b/security/nss/lib/softoken/win_rand.c
index de2e06ea7..de2e06ea7 100644
--- a/security/nss/lib/util/win_rand.c
+++ b/security/nss/lib/softoken/win_rand.c
diff --git a/security/nss/lib/ssl/ssl3con.c b/security/nss/lib/ssl/ssl3con.c
index ccff7fb81..6889e5afa 100644
--- a/security/nss/lib/ssl/ssl3con.c
+++ b/security/nss/lib/ssl/ssl3con.c
@@ -4272,7 +4272,7 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
peerKey->arena = arena;
peerKey->keyType = rsaKey;
peerKey->pkcs11Slot = NULL;
- peerKey->pkcs11ID = CK_INVALID_KEY;
+ peerKey->pkcs11ID = CK_INVALID_HANDLE;
if (SECITEM_CopyItem(arena, &peerKey->u.rsa.modulus, &modulus) ||
SECITEM_CopyItem(arena, &peerKey->u.rsa.publicExponent, &exponent))
{
@@ -4354,7 +4354,7 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
peerKey->arena = arena;
peerKey->keyType = dhKey;
peerKey->pkcs11Slot = NULL;
- peerKey->pkcs11ID = CK_INVALID_KEY;
+ peerKey->pkcs11ID = CK_INVALID_HANDLE;
if (SECITEM_CopyItem(arena, &peerKey->u.dh.prime, &dh_p) ||
SECITEM_CopyItem(arena, &peerKey->u.dh.base, &dh_g) ||
diff --git a/security/nss/lib/util/manifest.mn b/security/nss/lib/util/manifest.mn
index 3e89b483e..d0a9c3755 100644
--- a/security/nss/lib/util/manifest.mn
+++ b/security/nss/lib/util/manifest.mn
@@ -39,6 +39,7 @@ EXPORTS = \
nssb64t.h \
nsslocks.h \
nssilock.h \
+ nssilckt.h \
nssrwlk.h \
nssrwlkt.h \
portreg.h \
@@ -84,19 +85,9 @@ CSRCS = \
sectime.c \
secport.c \
secinit.c \
- sysrand.c \
utf8.c \
$(NULL)
-ifeq ($(subst /,,$(shell uname -s)),OS2)
- CSRCS += os2_rand.c
-endif
-
-# mac_rand.c
-# unix_rand.c
-# win_rand.c
-# prelib.c
-
REQUIRES = security dbm
LIBRARY_NAME = secutil
diff --git a/security/nss/lib/util/nssilckt.h b/security/nss/lib/util/nssilckt.h
new file mode 100644
index 000000000..34fa60234
--- /dev/null
+++ b/security/nss/lib/util/nssilckt.h
@@ -0,0 +1,219 @@
+/*
+ * 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.
+ */
+
+/*
+** nssilock.h - Instrumented locking functions for NSS
+**
+** Description:
+** nssilock provides instrumentation for locks and monitors in
+** the NSS libraries. The instrumentation, when enabled, causes
+** each call to the instrumented function to record data about
+** the call to an external file. The external file
+** subsequently used to extract performance data and other
+** statistical information about the operation of locks used in
+** the nss library.
+**
+** To enable compilation with instrumentation, build NSS with
+** the compile time switch NEED_NSS_ILOCK defined.
+**
+** say: "gmake OS_CFLAGS+=-DNEED_NSS_ILOCK" at make time.
+**
+** At runtime, to enable recording from nssilock, one or more
+** environment variables must be set. For each nssILockType to
+** be recorded, an environment variable of the form NSS_ILOCK_x
+** must be set to 1. For example:
+**
+** set NSS_ILOCK_Cert=1
+**
+** nssilock uses PRLOG is used to record to trace data. The
+** PRLogModule name associated with nssilock data is: "nssilock".
+** To enable recording of nssilock data you will need to set the
+** environment variable NSPR_LOG_MODULES to enable
+** recording for the nssilock log module. Similarly, you will
+** need to set the environment variable NSPR_LOG_FILE to specify
+** the filename to receive the recorded data. See prlog.h for usage.
+** Example:
+**
+** export NSPR_LOG_MODULES=nssilock:6
+** export NSPR_LOG_FILE=xxxLogfile
+**
+** Operation:
+** nssilock wraps calls to NSPR's PZLock and PZMonitor functions
+** with similarly named functions: PZ_NewLock(), etc. When NSS is
+** built with lock instrumentation enabled, the PZ* functions are
+** compiled into NSS; when lock instrumentation is disabled,
+** calls to PZ* functions are directly mapped to PR* functions
+** and the instrumentation arguments to the PZ* functions are
+** compiled away.
+**
+**
+** File Format:
+** The format of the external file is implementation
+** dependent. Where NSPR's PR_LOG() function is used, the file
+** contains data defined for PR_LOG() plus the data written by
+** the wrapped function. On some platforms and under some
+** circumstances, platform dependent logging or
+** instrumentation probes may be used. In any case, the
+** relevant data provided by the lock instrumentation is:
+**
+** lockType, func, address, duration, line, file [heldTime]
+**
+** where:
+**
+** lockType: a character representation of nssILockType for the
+** call. e.g. ... "cert"
+**
+** func: the function doing the tracing. e.g. "NewLock"
+**
+** address: address of the instrumented lock or monitor
+**
+** duration: is how long was spent in the instrumented function,
+** in PRIntervalTime "ticks".
+**
+** line: the line number within the calling function
+**
+** file: the file from which the call was made
+**
+** heldTime: how long the lock/monitor was held. field
+** present only for PZ_Unlock() and PZ_ExitMonitor().
+**
+** Design Notes:
+** The design for lock instrumentation was influenced by the
+** need to gather performance data on NSS 3.x. It is intended
+** that the effort to modify NSS to use lock instrumentation
+** be minimized. Existing calls to locking functions need only
+** have their names changed to the instrumentation function
+** names.
+**
+** Private NSS Interface:
+** nssilock.h defines a private interface for use by NSS.
+** nssilock.h is experimental in nature and is subject to
+** change or revocation without notice. ... Don't mess with
+** it.
+**
+*/
+
+/*
+ * $Id:
+ */
+
+#ifndef _NSSILCKT_H_
+#define _NSSILCKT_H_
+
+#include "prtypes.h"
+#include "prmon.h"
+#include "prlock.h"
+#include "prcvar.h"
+
+typedef enum {
+ nssILockArena = 0,
+ nssILockSession = 1,
+ nssILockObject = 2,
+ nssILockRefLock = 3,
+ nssILockCert = 4,
+ nssILockCertDB = 5,
+ nssILockDBM = 6,
+ nssILockCache = 7,
+ nssILockSSL = 8,
+ nssILockList = 9,
+ nssILockSlot = 10,
+ nssILockFreelist = 11,
+ nssILockOID = 12,
+ nssILockAttribute = 13,
+ nssILockPK11cxt = 14, /* pk11context */
+ nssILockRWLock = 15,
+ nssILockOther = 16,
+ nssILockSelfServ = 17,
+ nssILockLast /* don't use this one! */
+} nssILockType;
+
+/*
+** Declare operation type enumerator
+** enumerations identify the function being performed
+*/
+typedef enum {
+ FlushTT = 0,
+ NewLock = 1,
+ Lock = 2,
+ Unlock = 3,
+ DestroyLock = 4,
+ NewCondVar = 5,
+ WaitCondVar = 6,
+ NotifyCondVar = 7,
+ NotifyAllCondVar = 8,
+ DestroyCondVar = 9,
+ NewMonitor = 10,
+ EnterMonitor = 11,
+ ExitMonitor = 12,
+ Notify = 13,
+ NotifyAll = 14,
+ Wait = 15,
+ DestroyMonitor = 16
+} nssILockOp;
+
+/*
+** Declare the trace record
+*/
+struct pzTrace_s {
+ PRUint32 threadID; /* PR_GetThreadID() */
+ nssILockOp op; /* operation being performed */
+ nssILockType ltype; /* lock type identifier */
+ PRIntervalTime callTime; /* time spent in function */
+ PRIntervalTime heldTime; /* lock held time, or -1 */
+ void *lock; /* address of lock structure */
+ PRIntn line; /* line number */
+ char file[24]; /* filename */
+};
+
+/*
+** conditionally compile in nssilock features
+*/
+#if defined(NEED_NSS_ILOCK)
+
+/*
+** declare opaque types. See: nssilock.c
+*/
+typedef struct pzlock_s PZLock;
+typedef struct pzcondvar_s PZCondVar;
+typedef struct pzmonitor_s PZMonitor;
+
+#else /* NEED_NSS_ILOCK */
+
+#define PZLock PRLock
+#define PZCondVar PRCondVar
+#define PZMonitor PRMonitor
+
+#endif /* NEED_NSS_ILOCK */
+
+PR_END_EXTERN_C
+#endif /* _NSSILCKT_H_ */
diff --git a/security/nss/lib/util/nssilock.h b/security/nss/lib/util/nssilock.h
index 0ba90193a..38b457387 100644
--- a/security/nss/lib/util/nssilock.h
+++ b/security/nss/lib/util/nssilock.h
@@ -135,80 +135,12 @@
#include "prlock.h"
#include "prcvar.h"
-PR_BEGIN_EXTERN_C
-
-typedef enum {
- nssILockArena = 0,
- nssILockSession = 1,
- nssILockObject = 2,
- nssILockRefLock = 3,
- nssILockCert = 4,
- nssILockCertDB = 5,
- nssILockDBM = 6,
- nssILockCache = 7,
- nssILockSSL = 8,
- nssILockList = 9,
- nssILockSlot = 10,
- nssILockFreelist = 11,
- nssILockOID = 12,
- nssILockAttribute = 13,
- nssILockPK11cxt = 14, /* pk11context */
- nssILockRWLock = 15,
- nssILockOther = 16,
- nssILockSelfServ = 17,
- nssILockLast /* don't use this one! */
-} nssILockType;
+#include "nssilckt.h"
-/*
-** Declare operation type enumerator
-** enumerations identify the function being performed
-*/
-typedef enum {
- FlushTT = 0,
- NewLock = 1,
- Lock = 2,
- Unlock = 3,
- DestroyLock = 4,
- NewCondVar = 5,
- WaitCondVar = 6,
- NotifyCondVar = 7,
- NotifyAllCondVar = 8,
- DestroyCondVar = 9,
- NewMonitor = 10,
- EnterMonitor = 11,
- ExitMonitor = 12,
- Notify = 13,
- NotifyAll = 14,
- Wait = 15,
- DestroyMonitor = 16
-} nssILockOp;
-
-/*
-** Declare the trace record
-*/
-struct pzTrace_s {
- PRUint32 threadID; /* PR_GetThreadID() */
- nssILockOp op; /* operation being performed */
- nssILockType ltype; /* lock type identifier */
- PRIntervalTime callTime; /* time spent in function */
- PRIntervalTime heldTime; /* lock held time, or -1 */
- void *lock; /* address of lock structure */
- PRIntn line; /* line number */
- char file[24]; /* filename */
-};
+PR_BEGIN_EXTERN_C
-/*
-** conditionally compile in nssilock features
-*/
#if defined(NEED_NSS_ILOCK)
-/*
-** declare opaque types. See: nssilock.c
-*/
-typedef struct pzlock_s PZLock;
-typedef struct pzcondvar_s PZCondVar;
-typedef struct pzmonitor_s PZMonitor;
-
#define PZ_NewLock(t) pz_NewLock((t),__FILE__,__LINE__)
extern PZLock *
pz_NewLock(
@@ -356,21 +288,17 @@ extern void pz_TraceFlush( void );
#else /* NEED_NSS_ILOCK */
-#define PZLock PRLock
-
#define PZ_NewLock(t) PR_NewLock()
#define PZ_DestroyLock(k) PR_DestroyLock((k))
#define PZ_Lock(k) PR_Lock((k))
#define PZ_Unlock(k) PR_Unlock((k))
-#define PZCondVar PRCondVar
#define PZ_NewCondVar(l) PR_NewCondVar((l))
#define PZ_DestroyCondVar(v) PR_DestroyCondVar((v))
#define PZ_WaitCondVar(v,t) PR_WaitCondVar((v),(t))
#define PZ_NotifyCondVar(v) PR_NotifyCondVar((v))
#define PZ_NotifyAllCondVar(v) PR_NotifyAllCondVar((v))
-#define PZMonitor PRMonitor
#define PZ_NewMonitor(t) PR_NewMonitor()
#define PZ_DestroyMonitor(m) PR_DestroyMonitor((m))
#define PZ_EnterMonitor(m) PR_EnterMonitor((m))
diff --git a/security/nss/lib/util/secoid.c b/security/nss/lib/util/secoid.c
index fbe35bae9..c38564861 100644
--- a/security/nss/lib/util/secoid.c
+++ b/security/nss/lib/util/secoid.c
@@ -385,18 +385,24 @@ CONST_OID dhPublicKey[] = { ANSI_X942_ALGORITHM, 0x1 };
CONST_OID aes128_ECB[] = { AES, 1 };
CONST_OID aes128_CBC[] = { AES, 2 };
+#ifdef DEFINE_ALL_AES_CIPHERS
CONST_OID aes128_OFB[] = { AES, 3 };
CONST_OID aes128_CFB[] = { AES, 4 };
+#endif
CONST_OID aes192_ECB[] = { AES, 21 };
CONST_OID aes192_CBC[] = { AES, 22 };
+#ifdef DEFINE_ALL_AES_CIPHERS
CONST_OID aes192_OFB[] = { AES, 23 };
CONST_OID aes192_CFB[] = { AES, 24 };
+#endif
CONST_OID aes256_ECB[] = { AES, 41 };
CONST_OID aes256_CBC[] = { AES, 42 };
+#ifdef DEFINE_ALL_AES_CIPHERS
CONST_OID aes256_OFB[] = { AES, 43 };
CONST_OID aes256_CFB[] = { AES, 44 };
+#endif
#define OI(x) { siDEROID, (unsigned char *)x, sizeof x }
#ifndef SECOID_NO_STRINGS