summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormkaply%us.ibm.com <devnull@localhost>2004-02-10 20:19:15 +0000
committermkaply%us.ibm.com <devnull@localhost>2004-02-10 20:19:15 +0000
commitded9650079adb3f060e6af226caec428e840b070 (patch)
tree4d1d60c60437c6c60ae7a867b05d392e009ec7df
parentc3c3fe2a2fe2c6f5688d26a59b23543484a638e7 (diff)
downloadnss-hg-ded9650079adb3f060e6af226caec428e840b070.tar.gz
a=mkaply - NSS 3.9 on the 1.6 branch
-rw-r--r--security/coreconf/WIN32.mk3
-rw-r--r--security/nss/cmd/dbck/dbck.c4
-rw-r--r--security/nss/cmd/lib/secutil.c2
-rw-r--r--security/nss/cmd/signver/pk7print.c2
-rw-r--r--security/nss/cmd/smimetools/cmsutil.c290
-rw-r--r--security/nss/cmd/symkeyutil/symkeyutil.c2
-rw-r--r--security/nss/lib/base/error.c59
-rw-r--r--security/nss/lib/certdb/alg1485.c1
-rw-r--r--security/nss/lib/certdb/cert.h1
-rw-r--r--security/nss/lib/certdb/certdb.c25
-rw-r--r--security/nss/lib/certdb/certv3.c27
-rw-r--r--security/nss/lib/certdb/crl.c2
-rw-r--r--security/nss/lib/certdb/genname.c6
-rw-r--r--security/nss/lib/certdb/secname.c20
-rw-r--r--security/nss/lib/certdb/stanpcertdb.c1
-rw-r--r--security/nss/lib/cryptohi/dsautil.c9
-rw-r--r--security/nss/lib/cryptohi/seckey.c6
-rw-r--r--security/nss/lib/cryptohi/secvfy.c1
-rw-r--r--security/nss/lib/fortcrypt/swfort/swfutl.c2
-rw-r--r--security/nss/lib/freebl/ecl/README2
-rw-r--r--security/nss/lib/freebl/manifest.mn2
-rw-r--r--security/nss/lib/freebl/rsa.c18
-rw-r--r--security/nss/lib/jar/jarver.c2
-rw-r--r--security/nss/lib/nss/nss.def12
-rw-r--r--security/nss/lib/nss/nss.h4
-rw-r--r--security/nss/lib/pk11wrap/pk11cert.c36
-rw-r--r--security/nss/lib/pk11wrap/pk11func.h12
-rw-r--r--security/nss/lib/pk11wrap/pk11skey.c12
-rw-r--r--security/nss/lib/pk11wrap/pk11slot.c204
-rw-r--r--security/nss/lib/pkcs12/p12d.c12
-rw-r--r--security/nss/lib/pkcs7/p7create.c2
-rw-r--r--security/nss/lib/pkcs7/p7decode.c2
-rw-r--r--security/nss/lib/pki/pkibase.c9
-rw-r--r--security/nss/lib/pki/tdcache.c51
-rw-r--r--security/nss/lib/smime/cms.h5
-rw-r--r--security/nss/lib/smime/cmsarray.c4
-rw-r--r--security/nss/lib/smime/cmsattr.c27
-rw-r--r--security/nss/lib/smime/cmscinfo.c28
-rw-r--r--security/nss/lib/smime/cmscipher.c1
-rw-r--r--security/nss/lib/smime/cmsdecode.c157
-rw-r--r--security/nss/lib/smime/cmsdigdata.c20
-rw-r--r--security/nss/lib/smime/cmsdigest.c202
-rw-r--r--security/nss/lib/smime/cmsenvdata.c8
-rw-r--r--security/nss/lib/smime/cmsmessage.c4
-rw-r--r--security/nss/lib/smime/cmspubkey.c9
-rw-r--r--security/nss/lib/smime/cmssigdata.c192
-rw-r--r--security/nss/lib/smime/cmssiginfo.c70
-rw-r--r--security/nss/lib/softoken/keydb.c213
-rw-r--r--security/nss/lib/softoken/lowcert.c4
-rw-r--r--security/nss/lib/softoken/pcert.h3
-rw-r--r--security/nss/lib/softoken/pcertdb.c75
-rw-r--r--security/nss/lib/softoken/pkcs11.c4
-rw-r--r--security/nss/lib/softoken/pkcs11u.c3
-rw-r--r--security/nss/lib/ssl/ssl3con.c12
-rw-r--r--security/nss/lib/ssl/sslgathr.c4
-rw-r--r--security/nss/lib/util/dertime.c54
-rw-r--r--security/nss/lib/util/nssilckt.h1
-rw-r--r--security/nss/lib/util/secasn1d.c2
-rw-r--r--security/nss/lib/util/secder.h10
-rw-r--r--security/nss/lib/util/secitem.c22
-rw-r--r--security/nss/lib/util/secitem.h7
-rw-r--r--security/nss/lib/util/secoid.c2
-rw-r--r--security/nss/lib/util/secport.c5
-rw-r--r--security/nss/lib/util/sectime.c10
-rw-r--r--security/nss/lib/util/utf8.c10
-rw-r--r--security/nss/manifest.mn2
66 files changed, 1372 insertions, 641 deletions
diff --git a/security/coreconf/WIN32.mk b/security/coreconf/WIN32.mk
index 42347d850..d275300b2 100644
--- a/security/coreconf/WIN32.mk
+++ b/security/coreconf/WIN32.mk
@@ -136,7 +136,8 @@ else # !NS_USE_GCC
USERNAME := $(subst -,_,$(USERNAME))
DEFINES += -DDEBUG -D_DEBUG -UNDEBUG -DDEBUG_$(USERNAME)
DLLFLAGS += -DEBUG -DEBUGTYPE:CV -OUT:"$@"
- LDFLAGS += -DEBUG -DEBUGTYPE:CV -PDB:NONE
+ # Purify requires /FIXED:NO when linking EXEs.
+ LDFLAGS += -DEBUG -DEBUGTYPE:CV -PDB:NONE /FIXED:NO
endif
endif # NS_USE_GCC
diff --git a/security/nss/cmd/dbck/dbck.c b/security/nss/cmd/dbck/dbck.c
index a5fa1e6fd..cba8e0287 100644
--- a/security/nss/cmd/dbck/dbck.c
+++ b/security/nss/cmd/dbck/dbck.c
@@ -265,8 +265,8 @@ dumpCertificate(CERTCertificate *cert, int num, PRFileDesc *outfile)
int64 timeBefore, timeAfter;
PRExplodedTime beforePrintable, afterPrintable;
char *beforestr, *afterstr;
- CERT_DecodeTimeChoice(&timeBefore, &cert->validity.notBefore);
- CERT_DecodeTimeChoice(&timeAfter, &cert->validity.notAfter);
+ DER_DecodeTimeChoice(&timeBefore, &cert->validity.notBefore);
+ DER_DecodeTimeChoice(&timeAfter, &cert->validity.notAfter);
PR_ExplodeTime(timeBefore, PR_GMTParameters, &beforePrintable);
PR_ExplodeTime(timeAfter, PR_GMTParameters, &afterPrintable);
beforestr = PORT_Alloc(100);
diff --git a/security/nss/cmd/lib/secutil.c b/security/nss/cmd/lib/secutil.c
index b01b6dada..f27c1d067 100644
--- a/security/nss/cmd/lib/secutil.c
+++ b/security/nss/cmd/lib/secutil.c
@@ -712,8 +712,6 @@ SECU_PrintAsHex(FILE *out, SECItem *data, const char *m, int level)
if (!isString)
for (i = 0; i < data->len; i++) {
- unsigned char val = data->data[i];
-
if (i != data->len - 1) {
fprintf(out, "%02x:", data->data[i]);
column += 3;
diff --git a/security/nss/cmd/signver/pk7print.c b/security/nss/cmd/signver/pk7print.c
index 2b19df1d1..71851fb17 100644
--- a/security/nss/cmd/signver/pk7print.c
+++ b/security/nss/cmd/signver/pk7print.c
@@ -110,7 +110,7 @@ sv_PrintTime(FILE *out, SECItem *t, char *m)
char *timeString;
int rv;
- rv = CERT_DecodeTimeChoice(&time, t);
+ rv = DER_DecodeTimeChoice(&time, t);
if (rv) return rv;
/* Convert to local time */
diff --git a/security/nss/cmd/smimetools/cmsutil.c b/security/nss/cmd/smimetools/cmsutil.c
index 6b7a06b21..ddaef6c83 100644
--- a/security/nss/cmd/smimetools/cmsutil.c
+++ b/security/nss/cmd/smimetools/cmsutil.c
@@ -87,6 +87,7 @@ DigestFile(PLArenaPool *poolp, SECItem ***digests, SECItem *input,
SECAlgorithmID **algids)
{
NSSCMSDigestContext *digcx;
+ SECStatus rv;
digcx = NSS_CMSDigestContext_StartMultiple(algids);
if (digcx == NULL)
@@ -94,7 +95,8 @@ DigestFile(PLArenaPool *poolp, SECItem ***digests, SECItem *input,
NSS_CMSDigestContext_Update(digcx, input->data, input->len);
- return NSS_CMSDigestContext_FinishMultiple(digcx, poolp, digests);
+ rv = NSS_CMSDigestContext_FinishMultiple(digcx, poolp, digests);
+ return rv;
}
@@ -105,9 +107,11 @@ Usage(char *progName)
"Usage: %s [-C|-D|-E|-O|-S] [<options>] [-d dbdir] [-u certusage]\n"
" -C create a CMS encrypted data message\n"
" -D decode a CMS message\n"
+" -b decode a batch of files named in infile\n"
" -c content use this detached content\n"
" -n suppress output of content\n"
" -h num display num levels of CMS message info as email headers\n"
+" -k keep decoded encryption certs in perm cert db\n"
" -E create a CMS enveloped data message\n"
" -r id,... create envelope for these recipients,\n"
" where id can be a certificate nickname or email address\n"
@@ -155,11 +159,12 @@ struct optionsStr {
struct decodeOptionsStr {
struct optionsStr *options;
- PRFileDesc *contentFile;
+ SECItem content;
int headerLevel;
PRBool suppressContent;
NSSCMSGetDecryptKeyCallback dkcb;
PK11SymKey *bulkkey;
+ PRBool keepCerts;
};
struct signOptionsStr {
@@ -195,22 +200,14 @@ struct encryptOptionsStr {
};
static NSSCMSMessage *
-decode(FILE *out, SECItem *output, SECItem *input,
- const struct decodeOptionsStr *decodeOptions)
+decode(FILE *out, SECItem *input, const struct decodeOptionsStr *decodeOptions)
{
NSSCMSDecoderContext *dcx;
NSSCMSMessage *cmsg;
- NSSCMSContentInfo *cinfo;
- NSSCMSSignedData *sigd = NULL;
- NSSCMSEnvelopedData *envd;
- NSSCMSEncryptedData *encd;
- int nlevels, i, nsigners, j;
- char *signercn;
- NSSCMSSignerInfo *si;
- SECOidTag typetag;
- SECItem **digests;
+ int nlevels, i;
SECItem sitem = { 0, 0, 0 };
+ PORT_SetError(0);
dcx = NSS_CMSDecoder_Start(NULL,
NULL, NULL, /* content callback */
pwcb, pwcb_arg, /* password callback */
@@ -230,6 +227,9 @@ decode(FILE *out, SECItem *output, SECItem *input,
nlevels = NSS_CMSMessage_ContentLevelCount(cmsg);
for (i = 0; i < nlevels; i++) {
+ NSSCMSContentInfo *cinfo;
+ SECOidTag typetag;
+
cinfo = NSS_CMSMessage_ContentLevel(cmsg, i);
typetag = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
@@ -238,25 +238,28 @@ decode(FILE *out, SECItem *output, SECItem *input,
switch (typetag) {
case SEC_OID_PKCS7_SIGNED_DATA:
+ {
+ NSSCMSSignedData *sigd = NULL;
+ SECItem **digests;
+ int nsigners;
+ int j;
+
if (decodeOptions->headerLevel >= 0)
fprintf(out, "type=signedData; ");
sigd = (NSSCMSSignedData *)NSS_CMSContentInfo_GetContent(cinfo);
if (sigd == NULL) {
- SECU_PrintError(progName,
- "problem finding signedData component");
+ SECU_PrintError(progName, "signedData component missing");
goto loser;
}
/* if we have a content file, but no digests for this signedData */
- if (decodeOptions->contentFile != NULL &&
+ if (decodeOptions->content.data != NULL &&
!NSS_CMSSignedData_HasDigests(sigd)) {
PLArenaPool *poolp;
SECAlgorithmID **digestalgs;
/* detached content: grab content file */
- if (!sitem.data) {
- SECU_FileToItem(&sitem, decodeOptions->contentFile);
- }
+ sitem = decodeOptions->content;
if ((poolp = PORT_NewArena(1024)) == NULL) {
fprintf(stderr, "cmsutil: Out of memory.\n");
@@ -267,13 +270,14 @@ decode(FILE *out, SECItem *output, SECItem *input,
!= SECSuccess) {
SECU_PrintError(progName,
"problem computing message digest");
+ PORT_FreeArena(poolp, PR_FALSE);
goto loser;
}
if (NSS_CMSSignedData_SetDigests(sigd, digestalgs, digests)
!= SECSuccess) {
-
SECU_PrintError(progName,
"problem setting message digests");
+ PORT_FreeArena(poolp, PR_FALSE);
goto loser;
}
PORT_FreeArena(poolp, PR_FALSE);
@@ -283,7 +287,7 @@ decode(FILE *out, SECItem *output, SECItem *input,
if (NSS_CMSSignedData_ImportCerts(sigd,
decodeOptions->options->certHandle,
decodeOptions->options->certUsage,
- PR_FALSE)
+ decodeOptions->keepCerts)
!= SECSuccess) {
SECU_PrintError(progName, "cert import failed");
goto loser;
@@ -294,13 +298,11 @@ decode(FILE *out, SECItem *output, SECItem *input,
if (decodeOptions->headerLevel >= 0)
fprintf(out, "nsigners=%d; ", nsigners);
if (nsigners == 0) {
- /* must be a cert transport message */
+ /* Might be a cert transport message
+ ** or might be an invalid message, such as a QA test message
+ ** or a message from an attacker.
+ */
SECStatus rv;
- /* XXX workaround for bug #54014 */
- NSS_CMSSignedData_ImportCerts(sigd,
- decodeOptions->options->certHandle,
- decodeOptions->options->certUsage,
- PR_TRUE);
rv = NSS_CMSSignedData_VerifyCertsOnly(sigd,
decodeOptions->options->certHandle,
decodeOptions->options->certUsage);
@@ -318,16 +320,23 @@ decode(FILE *out, SECItem *output, SECItem *input,
}
for (j = 0; j < nsigners; j++) {
- SECStatus bad;
- NSSCMSVerificationStatus vs;
const char * svs;
+ NSSCMSSignerInfo *si;
+ NSSCMSVerificationStatus vs;
+ SECStatus bad;
si = NSS_CMSSignedData_GetSignerInfo(sigd, j);
- signercn = NSS_CMSSignerInfo_GetSignerCommonName(si);
- if (signercn == NULL)
- signercn = "";
- if (decodeOptions->headerLevel >= 0)
+ if (decodeOptions->headerLevel >= 0) {
+ char *signercn;
+ static char empty[] = { "" };
+
+ signercn = NSS_CMSSignerInfo_GetSignerCommonName(si);
+ if (signercn == NULL)
+ signercn = empty;
fprintf(out, "\n\t\tsigner%d.id=\"%s\"; ", j, signercn);
+ if (signercn != empty)
+ PORT_Free(signercn);
+ }
bad = NSS_CMSSignedData_VerifySignerInfo(sigd, j,
decodeOptions->options->certHandle,
decodeOptions->options->certUsage);
@@ -341,17 +350,32 @@ decode(FILE *out, SECItem *output, SECItem *input,
goto loser;
}
}
- break;
+ }
+ break;
case SEC_OID_PKCS7_ENVELOPED_DATA:
+ {
+ NSSCMSEnvelopedData *envd;
if (decodeOptions->headerLevel >= 0)
fprintf(out, "type=envelopedData; ");
envd = (NSSCMSEnvelopedData *)NSS_CMSContentInfo_GetContent(cinfo);
- break;
+ if (envd == NULL) {
+ SECU_PrintError(progName, "envelopedData component missing");
+ goto loser;
+ }
+ }
+ break;
case SEC_OID_PKCS7_ENCRYPTED_DATA:
+ {
+ NSSCMSEncryptedData *encd;
if (decodeOptions->headerLevel >= 0)
fprintf(out, "type=encryptedData; ");
encd = (NSSCMSEncryptedData *)NSS_CMSContentInfo_GetContent(cinfo);
- break;
+ if (encd == NULL) {
+ SECU_PrintError(progName, "encryptedData component missing");
+ goto loser;
+ }
+ }
+ break;
case SEC_OID_PKCS7_DATA:
if (decodeOptions->headerLevel >= 0)
fprintf(out, "type=data; ");
@@ -363,11 +387,12 @@ decode(FILE *out, SECItem *output, SECItem *input,
fprintf(out, "\n");
}
- if (!decodeOptions->suppressContent) {
- SECItem *item = (sitem.data)
- ? &sitem
- : NSS_CMSMessage_GetContent(cmsg);
- SECITEM_CopyItem(NULL, output, item);
+ if (!decodeOptions->suppressContent && out) {
+ SECItem *item = (sitem.data ? &sitem
+ : NSS_CMSMessage_GetContent(cmsg));
+ if (item && item->data && item->len) {
+ fwrite(item->data, item->len, 1, out);
+ }
}
return cmsg;
@@ -953,8 +978,87 @@ loser:
return NULL;
}
+static char *
+pl_fgets(char * buf, int size, PRFileDesc * fd)
+{
+ char * bp = buf;
+ int nb = 0;;
+
+ while (size > 1) {
+ nb = PR_Read(fd, bp, 1);
+ if (nb < 0) {
+ /* deal with error */
+ return NULL;
+ } else if (nb == 0) {
+ /* deal with EOF */
+ return NULL;
+ } else if (*bp == '\n') {
+ /* deal with EOL */
+ ++bp; /* keep EOL character */
+ break;
+ } else {
+ /* ordinary character */
+ ++bp;
+ --size;
+ }
+ }
+ *bp = '\0';
+ return buf;
+}
+
typedef enum { UNKNOWN, DECODE, SIGN, ENCRYPT, ENVELOPE, CERTSONLY } Mode;
+static int
+doBatchDecode(FILE *outFile, PRFileDesc *batchFile,
+ const struct decodeOptionsStr *decodeOptions)
+{
+ char * str;
+ int exitStatus = 0;
+ char batchLine[512];
+
+ while (NULL != (str = pl_fgets(batchLine, sizeof batchLine, batchFile))) {
+ NSSCMSMessage *cmsg = NULL;
+ PRFileDesc * inFile;
+ int len = strlen(str);
+ SECStatus rv;
+ SECItem input = {0, 0, 0};
+ char cc;
+
+ while (len > 0 &&
+ ((cc = str[len - 1]) == '\n' || cc == '\r')) {
+ str[--len] = '\0';
+ }
+ if (!len) /* skip empty line */
+ continue;
+ if (str[0] == '#')
+ continue; /* skip comment line */
+ fprintf(outFile, "========== %s ==========\n", str);
+ inFile = PR_Open(str, PR_RDONLY, 00660);
+ if (inFile == NULL) {
+ fprintf(outFile, "%s: unable to open \"%s\" for reading\n",
+ progName, str);
+ exitStatus = 1;
+ continue;
+ }
+ rv = SECU_FileToItem(&input, inFile);
+ PR_Close(inFile);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "unable to read infile");
+ exitStatus = 1;
+ continue;
+ }
+ cmsg = decode(outFile, &input, decodeOptions);
+ SECITEM_FreeItem(&input, PR_FALSE);
+ if (cmsg)
+ NSS_CMSMessage_Destroy(cmsg);
+ else {
+ SECU_PrintError(progName, "problem decoding");
+ exitStatus = 1;
+ }
+ }
+ return exitStatus;
+}
+
int
main(int argc, char **argv)
{
@@ -976,10 +1080,17 @@ main(int argc, char **argv)
char *str, *tok;
char *envFileName;
SECItem input = { 0, 0, 0};
- SECItem output = { 0, 0, 0};
- SECItem dummy = { 0, 0, 0 };
SECItem envmsg = { 0, 0, 0 };
SECStatus rv;
+ PRFileDesc *contentFile = NULL;
+ PRBool batch = PR_FALSE;
+
+#ifdef NISCC_TESTING
+ const char *ev = PR_GetEnv("NSS_DISABLE_ARENA_FREE_LIST");
+ PORT_Assert(ev);
+ ev = PR_GetEnv("NSS_STRICT_SHUTDOWN");
+ PORT_Assert(ev);
+#endif
progName = strrchr(argv[0], '/');
if (!progName)
@@ -990,9 +1101,11 @@ main(int argc, char **argv)
outFile = stdout;
envFileName = NULL;
mode = UNKNOWN;
- decodeOptions.contentFile = NULL;
+ decodeOptions.content.data = NULL;
+ decodeOptions.content.len = 0;
decodeOptions.suppressContent = PR_FALSE;
decodeOptions.headerLevel = -1;
+ decodeOptions.keepCerts = PR_FALSE;
options.certUsage = certUsageEmailSigner;
options.password = NULL;
signOptions.nickname = NULL;
@@ -1013,7 +1126,7 @@ main(int argc, char **argv)
* Parse command line arguments
*/
optstate = PL_CreateOptState(argc, argv,
- "CDEGH:N:OPSTY:c:d:e:h:i:no:p:r:s:u:v");
+ "CDEGH:N:OPSTY:bc:d:e:h:i:kno:p:r:s:u:v");
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
switch (optstate->option) {
case 'C':
@@ -1112,6 +1225,17 @@ main(int argc, char **argv)
signOptions.encryptionKeyPreferenceNick = strdup(optstate->value);
break;
+ case 'b':
+ if (mode != DECODE) {
+ fprintf(stderr,
+ "%s: option -b only supported with option -D.\n",
+ progName);
+ Usage(progName);
+ exit(1);
+ }
+ batch = PR_TRUE;
+ break;
+
case 'c':
if (mode != DECODE) {
fprintf(stderr,
@@ -1120,12 +1244,25 @@ main(int argc, char **argv)
Usage(progName);
exit(1);
}
- if ((decodeOptions.contentFile =
- PR_Open(optstate->value, PR_RDONLY, 006600)) == NULL) {
+ contentFile = PR_Open(optstate->value, PR_RDONLY, 006600);
+ if (contentFile == NULL) {
fprintf(stderr, "%s: unable to open \"%s\" for reading.\n",
progName, optstate->value);
exit(1);
}
+
+ rv = SECU_FileToItem(&decodeOptions.content, contentFile);
+ PR_Close(contentFile);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "problem reading content file");
+ exit(1);
+ }
+ if (!decodeOptions.content.data) {
+ /* file was zero length */
+ decodeOptions.content.data = (unsigned char *)PORT_Strdup("");
+ decodeOptions.content.len = 0;
+ }
+
break;
case 'd':
SECU_ConfigDirectory(optstate->value);
@@ -1158,6 +1295,17 @@ main(int argc, char **argv)
}
break;
+ case 'k':
+ if (mode != DECODE) {
+ fprintf(stderr,
+ "%s: option -k only supported with option -D.\n",
+ progName);
+ Usage(progName);
+ exit(1);
+ }
+ decodeOptions.keepCerts = PR_TRUE;
+ break;
+
case 'n':
if (mode != DECODE) {
fprintf(stderr,
@@ -1227,10 +1375,16 @@ main(int argc, char **argv)
if (mode == UNKNOWN)
Usage(progName);
- if (mode != CERTSONLY)
- SECU_FileToItem(&input, inFile);
- if (inFile != PR_STDIN)
- PR_Close(inFile);
+ if (mode != CERTSONLY && !batch) {
+ rv = SECU_FileToItem(&input, inFile);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "unable to read infile");
+ exit(1);
+ }
+ if (inFile != PR_STDIN) {
+ PR_Close(inFile);
+ }
+ }
if (cms_verbose) {
fprintf(stderr, "received commands\n");
}
@@ -1289,8 +1443,7 @@ main(int argc, char **argv)
*/
SECU_FileToItem(&envmsg, encryptOptions.envFile);
decodeOptions.options = &options;
- encryptOptions.envmsg = decode(NULL, &dummy, &envmsg,
- &decodeOptions);
+ encryptOptions.envmsg = decode(NULL, &envmsg, &decodeOptions);
if (!encryptOptions.envmsg) {
SECU_PrintError(progName, "problem decoding env msg");
exitstatus = 1;
@@ -1300,12 +1453,18 @@ main(int argc, char **argv)
decodeOptions.dkcb = dkcb;
decodeOptions.bulkkey = encryptOptions.bulkkey;
}
- cmsg = decode(outFile, &output, &input, &decodeOptions);
- if (!cmsg) {
- SECU_PrintError(progName, "problem decoding");
- exitstatus = 1;
+ if (!batch) {
+ cmsg = decode(outFile, &input, &decodeOptions);
+ if (!cmsg) {
+ SECU_PrintError(progName, "problem decoding");
+ exitstatus = 1;
+ }
+ } else {
+ exitstatus = doBatchDecode(outFile, inFile, &decodeOptions);
+ if (inFile != PR_STDIN) {
+ PR_Close(inFile);
+ }
}
- fwrite(output.data, output.len, 1, outFile);
break;
case SIGN: /* -S */
signOptions.options = &options;
@@ -1338,8 +1497,7 @@ main(int argc, char **argv)
} else {
SECU_FileToItem(&envmsg, encryptOptions.envFile);
decodeOptions.options = &options;
- encryptOptions.envmsg = decode(NULL, &dummy, &envmsg,
- &decodeOptions);
+ encryptOptions.envmsg = decode(NULL, &envmsg, &decodeOptions);
if (encryptOptions.envmsg == NULL) {
SECU_PrintError(progName, "problem decrypting env msg");
exitstatus = 1;
@@ -1433,7 +1591,6 @@ main(int argc, char **argv)
if (cms_verbose) {
fprintf(stderr, "encoding passed\n");
}
- /*PR_Write(output.data, output.len);*/
fwrite(output.data, output.len, 1, outFile);
if (cms_verbose) {
fprintf(stderr, "wrote to file\n");
@@ -1445,10 +1602,13 @@ main(int argc, char **argv)
if (outFile != stdout)
fclose(outFile);
- if (decodeOptions.contentFile)
- PR_Close(decodeOptions.contentFile);
+ SECITEM_FreeItem(&decodeOptions.content, PR_FALSE);
+ SECITEM_FreeItem(&envmsg, PR_FALSE);
+ SECITEM_FreeItem(&input, PR_FALSE);
if (NSS_Shutdown() != SECSuccess) {
- exit(1);
+ SECU_PrintError(progName, "NSS_Shutdown failed");
+ exitstatus = 1;
}
- exit(exitstatus);
+ PR_Cleanup();
+ return exitstatus;
}
diff --git a/security/nss/cmd/symkeyutil/symkeyutil.c b/security/nss/cmd/symkeyutil/symkeyutil.c
index 5c355e33b..f1f3d1c41 100644
--- a/security/nss/cmd/symkeyutil/symkeyutil.c
+++ b/security/nss/cmd/symkeyutil/symkeyutil.c
@@ -1093,7 +1093,7 @@ main(int argc, char **argv)
goto shutdown;
}
rv = SECFailure;
- newKey = PK11_MoveKey(target, CKA_ENCRYPT, 0, PR_TRUE, symKey);
+ newKey = PK11_MoveSymKey(target, CKA_ENCRYPT, 0, PR_TRUE, symKey);
if (!newKey) {
PR_fprintf(PR_STDERR, "%s: Couldn't move the key \n",progName);
goto shutdown;
diff --git a/security/nss/lib/base/error.c b/security/nss/lib/base/error.c
index 3e736b2b0..ce5825159 100644
--- a/security/nss/lib/base/error.c
+++ b/security/nss/lib/base/error.c
@@ -45,6 +45,9 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#ifndef BASE_H
#include "base.h"
#endif /* BASE_H */
+#include <string.h> /* for memmove */
+
+#define NSS_MAX_ERROR_STACK_COUNT 16 /* error codes */
/*
* The stack itself has a header, and a sequence of integers.
@@ -87,12 +90,8 @@ static PRCallOnceType error_call_once;
*
* This is the once-called callback.
*/
-
static PRStatus
-error_once_function
-(
- void
-)
+error_once_function ( void)
{
return nss_NewThreadPrivateIndex(&error_stack_index,PR_Free);
/* return PR_NewThreadPrivateIndex(&error_stack_index, PR_Free); */
@@ -107,10 +106,7 @@ error_once_function
*/
static error_stack *
-error_get_my_stack
-(
- void
-)
+error_get_my_stack ( void)
{
PRStatus st;
error_stack *rv;
@@ -129,18 +125,16 @@ error_get_my_stack
if( (error_stack *)NULL == rv ) {
/* Doesn't exist; create one */
new_size = 16;
+ } else if( rv->header.count == rv->header.space &&
+ rv->header.count < NSS_MAX_ERROR_STACK_COUNT ) {
+ /* Too small, expand it */
+ new_size = PR_MIN( rv->header.space * 2, NSS_MAX_ERROR_STACK_COUNT);
} else {
- if( rv->header.count == rv->header.space ) {
- /* Too small, expand it */
- new_size = rv->header.space + 16;
- } else {
- /* Okay, return it */
- return rv;
- }
+ /* Okay, return it */
+ return rv;
}
- new_bytes = (new_size * sizeof(PRInt32)) +
- sizeof(struct stack_header_str);
+ new_bytes = (new_size * sizeof(PRInt32)) + sizeof(error_stack);
/* Use NSPR's calloc/realloc, not NSS's, to avoid loops! */
new_stack = PR_Calloc(1, new_bytes);
@@ -187,10 +181,7 @@ error_get_my_stack
*/
NSS_IMPLEMENT PRInt32
-NSS_GetError
-(
- void
-)
+NSS_GetError ( void)
{
error_stack *es = error_get_my_stack();
@@ -224,10 +215,7 @@ NSS_GetError
*/
NSS_IMPLEMENT PRInt32 *
-NSS_GetErrorStack
-(
- void
-)
+NSS_GetErrorStack ( void)
{
error_stack *es = error_get_my_stack();
@@ -250,10 +238,7 @@ NSS_GetErrorStack
*/
NSS_IMPLEMENT void
-nss_SetError
-(
- PRUint32 error
-)
+nss_SetError ( PRUint32 error)
{
error_stack *es;
@@ -268,8 +253,13 @@ nss_SetError
return;
}
- es->stack[ es->header.count ] = error;
- es->header.count++;
+ if (es->header.count < es->header.space) {
+ es->stack[ es->header.count++ ] = error;
+ } else {
+ memmove(es->stack, es->stack + 1,
+ (es->header.space - 1) * (sizeof es->stack[0]));
+ es->stack[ es->header.space - 1 ] = error;
+ }
return;
}
@@ -280,10 +270,7 @@ nss_SetError
*/
NSS_IMPLEMENT void
-nss_ClearErrorStack
-(
- void
-)
+nss_ClearErrorStack ( void)
{
error_stack *es = error_get_my_stack();
if( (error_stack *)NULL == es ) {
diff --git a/security/nss/lib/certdb/alg1485.c b/security/nss/lib/certdb/alg1485.c
index f1a450f47..916f09cbe 100644
--- a/security/nss/lib/certdb/alg1485.c
+++ b/security/nss/lib/certdb/alg1485.c
@@ -1102,6 +1102,7 @@ CERT_GetCertEmailAddress(CERTName *name)
return(emailAddr);
}
+/* The return value must be freed with PORT_Free. */
char *
CERT_GetCommonName(CERTName *name)
{
diff --git a/security/nss/lib/certdb/cert.h b/security/nss/lib/certdb/cert.h
index 34f0339cb..a154cba78 100644
--- a/security/nss/lib/certdb/cert.h
+++ b/security/nss/lib/certdb/cert.h
@@ -733,6 +733,7 @@ extern const char * CERT_GetFirstEmailAddress(CERTCertificate * cert);
extern const char * CERT_GetNextEmailAddress(CERTCertificate * cert,
const char * prev);
+/* The return value must be freed with PORT_Free. */
extern char *CERT_GetCommonName(CERTName *name);
extern char *CERT_GetCountryName(CERTName *name);
diff --git a/security/nss/lib/certdb/certdb.c b/security/nss/lib/certdb/certdb.c
index 5c1adc99d..5cd21baab 100644
--- a/security/nss/lib/certdb/certdb.c
+++ b/security/nss/lib/certdb/certdb.c
@@ -963,13 +963,13 @@ CERT_GetCertTimes(CERTCertificate *c, PRTime *notBefore, PRTime *notAfter)
}
/* convert DER not-before time */
- rv = CERT_DecodeTimeChoice(notBefore, &c->validity.notBefore);
+ rv = DER_DecodeTimeChoice(notBefore, &c->validity.notBefore);
if (rv) {
return(SECFailure);
}
/* convert DER not-after time */
- rv = CERT_DecodeTimeChoice(notAfter, &c->validity.notAfter);
+ rv = DER_DecodeTimeChoice(notAfter, &c->validity.notAfter);
if (rv) {
return(SECFailure);
}
@@ -1020,14 +1020,14 @@ SEC_GetCrlTimes(CERTCrl *date, PRTime *notBefore, PRTime *notAfter)
int rv;
/* convert DER not-before time */
- rv = CERT_DecodeTimeChoice(notBefore, &date->lastUpdate);
+ rv = DER_DecodeTimeChoice(notBefore, &date->lastUpdate);
if (rv) {
return(SECFailure);
}
/* convert DER not-after time */
if (date->nextUpdate.data) {
- rv = CERT_DecodeTimeChoice(notAfter, &date->nextUpdate);
+ rv = DER_DecodeTimeChoice(notAfter, &date->nextUpdate);
if (rv) {
return(SECFailure);
}
@@ -2245,7 +2245,7 @@ CERT_ImportCerts(CERTCertDBHandle *certdb, SECCertUsage usage,
unsigned int fcerts = 0;
if ( ncerts ) {
- certs = (CERTCertificate**)PORT_ZAlloc(sizeof(CERTCertificate *) * ncerts );
+ certs = PORT_ZNewArray(CERTCertificate*, ncerts);
if ( certs == NULL ) {
return(SECFailure);
}
@@ -2306,18 +2306,7 @@ CERT_ImportCerts(CERTCertDBHandle *certdb, SECCertUsage usage,
}
}
- return(SECSuccess);
-
-#if 0 /* dead code here - why ?? XXX */
-loser:
- if ( retCerts ) {
- *retCerts = NULL;
- }
- if ( certs ) {
- CERT_DestroyCertArray(certs, ncerts);
- }
- return(SECFailure);
-#endif
+ return (fcerts ? SECSuccess : SECFailure);
}
/*
@@ -2609,7 +2598,7 @@ CERT_FilterCertListByUsage(CERTCertList *certList, SECCertUsage usage,
* takes trust flags into consideration. Should probably
* fix the cert decoding code to do this.
*/
- PRBool dummyret = CERT_IsCACert(node->cert, &certType);
+ (void)CERT_IsCACert(node->cert, &certType);
} else {
certType = node->cert->nsCertType;
}
diff --git a/security/nss/lib/certdb/certv3.c b/security/nss/lib/certdb/certv3.c
index e50c66279..f4e11b3ae 100644
--- a/security/nss/lib/certdb/certv3.c
+++ b/security/nss/lib/certdb/certv3.c
@@ -294,19 +294,28 @@ SECStatus
CERT_FindSubjectKeyIDExtension(CERTCertificate *cert, SECItem *retItem)
{
- SECItem encodedValue;
SECStatus rv;
+ SECItem encodedValue = {siBuffer, NULL, 0 };
+ SECItem decodedValue = {siBuffer, NULL, 0 };
- encodedValue.data = NULL;
rv = cert_FindExtension
(cert->extensions, SEC_OID_X509_SUBJECT_KEY_ID, &encodedValue);
- if (rv != SECSuccess)
- return (rv);
- rv = SEC_ASN1DecodeItem (NULL, retItem, SEC_OctetStringTemplate,
- &encodedValue);
- PORT_Free (encodedValue.data);
-
- return (rv);
+ if (rv == SECSuccess) {
+ PLArenaPool * tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (tmpArena) {
+ rv = SEC_QuickDERDecodeItem(tmpArena, &decodedValue,
+ SEC_OctetStringTemplate,
+ &encodedValue);
+ if (rv == SECSuccess) {
+ rv = SECITEM_CopyItem(NULL, retItem, &decodedValue);
+ }
+ PORT_FreeArena(tmpArena, PR_FALSE);
+ } else {
+ rv = SECFailure;
+ }
+ }
+ SECITEM_FreeItem(&encodedValue, PR_FALSE);
+ return rv;
}
SECStatus
diff --git a/security/nss/lib/certdb/crl.c b/security/nss/lib/certdb/crl.c
index d3d07db92..9957e1dd2 100644
--- a/security/nss/lib/certdb/crl.c
+++ b/security/nss/lib/certdb/crl.c
@@ -1875,7 +1875,7 @@ CERT_CheckCRL(CERTCertificate* cert, CERTCertificate* issuer, SECItem* dp,
/* check the time if we have one */
if (entry->revocationDate.data && entry->revocationDate.len) {
int64 revocationDate = 0;
- if (SECSuccess == CERT_DecodeTimeChoice(&revocationDate,
+ if (SECSuccess == DER_DecodeTimeChoice(&revocationDate,
&entry->revocationDate)) {
/* we got a good revocation date, only consider the
certificate revoked if the time we are inquiring about
diff --git a/security/nss/lib/certdb/genname.c b/security/nss/lib/certdb/genname.c
index 05feaaaa9..93c437778 100644
--- a/security/nss/lib/certdb/genname.c
+++ b/security/nss/lib/certdb/genname.c
@@ -120,7 +120,7 @@ static const SEC_ASN1Template CERT_DNSNameTemplate[] = {
};
static const SEC_ASN1Template CERT_X400AddressTemplate[] = {
- { SEC_ASN1_ANY | SEC_ASN1_CONTEXT_SPECIFIC | 3,
+ { SEC_ASN1_CONTEXT_SPECIFIC | 3,
offsetof(CERTGeneralName, name.other), SEC_AnyTemplate,
sizeof (CERTGeneralName)}
};
@@ -133,7 +133,7 @@ static const SEC_ASN1Template CERT_DirectoryNameTemplate[] = {
static const SEC_ASN1Template CERT_EDIPartyNameTemplate[] = {
- { SEC_ASN1_ANY | SEC_ASN1_CONTEXT_SPECIFIC | 5,
+ { SEC_ASN1_CONTEXT_SPECIFIC | 5,
offsetof(CERTGeneralName, name.other), SEC_AnyTemplate,
sizeof (CERTGeneralName)}
};
@@ -438,7 +438,7 @@ CERT_DecodeGeneralName(PRArenaPool *arena,
case certX400Address: template = CERT_X400AddressTemplate; break;
case certDirectoryName: template = CERT_DirectoryNameTemplate; break;
default:
- PORT_Assert(0); goto loser;
+ goto loser;
}
rv = SEC_ASN1DecodeItem(arena, genName, template, encodedName);
if (rv != SECSuccess)
diff --git a/security/nss/lib/certdb/secname.c b/security/nss/lib/certdb/secname.c
index 6ddadc355..5a40249da 100644
--- a/security/nss/lib/certdb/secname.c
+++ b/security/nss/lib/certdb/secname.c
@@ -161,24 +161,24 @@ SetupAVAValue(PRArenaPool *arena, int valueType, char *value, SECItem *it,
break;
case SEC_ASN1_UNIVERSAL_STRING:
valueLen = PORT_Strlen(value);
- ucs4Val = (unsigned char *)PORT_ArenaZAlloc(arena,
- PORT_Strlen(value) * 6);
- ucs4MaxLen = PORT_Strlen(value) * 6;
- if(!ucs4Val || !PORT_UCS4_UTF8Conversion(PR_TRUE, (unsigned char *)value, valueLen,
+ ucs4MaxLen = valueLen * 6;
+ ucs4Val = (unsigned char *)PORT_ArenaZAlloc(arena, ucs4MaxLen);
+ if(!ucs4Val || !PORT_UCS4_UTF8Conversion(PR_TRUE,
+ (unsigned char *)value, valueLen,
ucs4Val, ucs4MaxLen, &ucs4Len)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
value = (char *)ucs4Val;
valueLen = ucs4Len;
+ maxLen *= 4;
break;
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
- if (((valueType != SEC_ASN1_UNIVERSAL_STRING) && (valueLen > maxLen)) ||
- ((valueType == SEC_ASN1_UNIVERSAL_STRING) && (valueLen > (maxLen * 4)))) {
+ if (valueLen > maxLen) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
@@ -654,9 +654,11 @@ CERT_DecodeAVAValue(const SECItem *derAVAValue)
unsigned char *utf8Val = (unsigned char*)
PORT_ArenaZAlloc(newarena, utf8ValLen);
- if(!PORT_UCS4_UTF8Conversion(PR_FALSE, avaValue.data, avaValue.len,
+ if(avaValue.len % 4 != 0 ||
+ !PORT_UCS4_UTF8Conversion(PR_FALSE, avaValue.data, avaValue.len,
utf8Val, utf8ValLen, &utf8ValLen)) {
PORT_FreeArena(newarena, PR_FALSE);
+ PORT_SetError(SEC_ERROR_INVALID_AVA);
return NULL;
}
@@ -669,9 +671,11 @@ CERT_DecodeAVAValue(const SECItem *derAVAValue)
unsigned char *utf8Val = (unsigned char*)
PORT_ArenaZAlloc(newarena, utf8ValLen);
- if(!PORT_UCS2_UTF8Conversion(PR_FALSE, avaValue.data, avaValue.len,
+ if(avaValue.len % 2 != 0 ||
+ !PORT_UCS2_UTF8Conversion(PR_FALSE, avaValue.data, avaValue.len,
utf8Val, utf8ValLen, &utf8ValLen)) {
PORT_FreeArena(newarena, PR_FALSE);
+ PORT_SetError(SEC_ERROR_INVALID_AVA);
return NULL;
}
diff --git a/security/nss/lib/certdb/stanpcertdb.c b/security/nss/lib/certdb/stanpcertdb.c
index 61e9508bc..7d607e255 100644
--- a/security/nss/lib/certdb/stanpcertdb.c
+++ b/security/nss/lib/certdb/stanpcertdb.c
@@ -154,6 +154,7 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
NSSCertificate *c = STAN_GetNSSCertificate(cert);
context = c->object.cryptoContext;
if (!context) {
+ PORT_SetError(SEC_ERROR_ADDING_CERT);
return SECFailure; /* wasn't a temp cert */
}
stanNick = nssCertificate_GetNickname(c, NULL);
diff --git a/security/nss/lib/cryptohi/dsautil.c b/security/nss/lib/cryptohi/dsautil.c
index 39eb3191b..9cd0b820e 100644
--- a/security/nss/lib/cryptohi/dsautil.c
+++ b/security/nss/lib/cryptohi/dsautil.c
@@ -34,6 +34,7 @@
* may use your version of this file under either the MPL or the
* GPL.
*/
+#include "cryptohi.h"
#include "secasn1.h"
#include "secitem.h"
#include "prerr.h"
@@ -138,7 +139,7 @@ common_EncodeDerSig(SECItem *dest, SECItem *src)
DSA_ASN1Signature sig;
unsigned char *signedR;
unsigned char *signedS;
- int len;
+ unsigned int len;
/* Allocate memory with room for an extra byte that
* may be required if the top bit in the first byte
@@ -191,7 +192,7 @@ common_EncodeDerSig(SECItem *dest, SECItem *src)
** For ECDSA, len depends on the key size used to create the signature.
*/
static SECItem *
-common_DecodeDerSig(SECItem *item, int len)
+common_DecodeDerSig(SECItem *item, unsigned int len)
{
SECItem * result = NULL;
SECStatus status;
@@ -264,7 +265,7 @@ DSAU_EncodeDerSig(SECItem *dest, SECItem *src)
** by len/2 bytes of s). dest is the signature DER encoded.
*/
SECStatus
-DSAU_EncodeDerSigWithLen(SECItem *dest, SECItem *src, int len)
+DSAU_EncodeDerSigWithLen(SECItem *dest, SECItem *src, unsigned int len)
{
PORT_Assert((src->len == len) && (len % 2 == 0));
@@ -293,7 +294,7 @@ DSAU_DecodeDerSig(SECItem *item)
** r followed by s (both padded to take up exactly len/2 bytes).
*/
SECItem *
-DSAU_DecodeDerSigToLen(SECItem *item, int len)
+DSAU_DecodeDerSigToLen(SECItem *item, unsigned int len)
{
return common_DecodeDerSig(item, len/2);
}
diff --git a/security/nss/lib/cryptohi/seckey.c b/security/nss/lib/cryptohi/seckey.c
index 11f625164..d1b3f6a05 100644
--- a/security/nss/lib/cryptohi/seckey.c
+++ b/security/nss/lib/cryptohi/seckey.c
@@ -1113,7 +1113,7 @@ CERT_KMIDPublicKey(CERTCertificate *cert)
}
int
-SECKEY_ECParams2KeySize(SECItem *encodedParams)
+SECKEY_ECParamsToKeySize(const SECItem *encodedParams)
{
SECOidTag tag;
SECItem oid = { siBuffer, NULL, 0};
@@ -1268,7 +1268,7 @@ SECKEY_PublicKeyStrength(SECKEYPublicKey *pubk)
/* Get the key size in bits and adjust */
if (pubk->u.ec.size == 0) {
pubk->u.ec.size =
- SECKEY_ECParams2KeySize(&pubk->u.ec.DEREncodedParams);
+ SECKEY_ECParamsToKeySize(&pubk->u.ec.DEREncodedParams);
}
return (pubk->u.ec.size + 7)/8;
#endif /* NSS_ENABLE_ECC */
@@ -1292,7 +1292,7 @@ SECKEY_PublicKeyStrengthInBits(SECKEYPublicKey *pubk)
case ecKey:
if (pubk->u.ec.size == 0) {
pubk->u.ec.size =
- SECKEY_ECParams2KeySize(&pubk->u.ec.DEREncodedParams);
+ SECKEY_ECParamsToKeySize(&pubk->u.ec.DEREncodedParams);
}
return pubk->u.ec.size;
#endif /* NSS_ENABLE_ECC */
diff --git a/security/nss/lib/cryptohi/secvfy.c b/security/nss/lib/cryptohi/secvfy.c
index f7e9f1114..efc65b8ec 100644
--- a/security/nss/lib/cryptohi/secvfy.c
+++ b/security/nss/lib/cryptohi/secvfy.c
@@ -360,7 +360,6 @@ VFY_EndWithSignature(VFYContext *cx, SECItem *sig)
unsigned part;
SECItem hash,dsasig; /* dsasig is also used for ECDSA */
SECStatus rv;
- int rawSigLen;
if ((cx->hasSignature == PR_FALSE) && (sig == NULL)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
diff --git a/security/nss/lib/fortcrypt/swfort/swfutl.c b/security/nss/lib/fortcrypt/swfort/swfutl.c
index eee677f65..c725bbad1 100644
--- a/security/nss/lib/fortcrypt/swfort/swfutl.c
+++ b/security/nss/lib/fortcrypt/swfort/swfutl.c
@@ -703,7 +703,9 @@ static int path_table_size = sizeof(path_table)/sizeof(path_table[0]);
char *fort_LookupFORTEZZAInitFile(void)
{
char *fname = NULL;
+#if defined(XP_UNIX) || defined(XP_WIN)
char *home = NULL;
+#endif
#ifdef XP_UNIX
char unix_home[512];
#endif
diff --git a/security/nss/lib/freebl/ecl/README b/security/nss/lib/freebl/ecl/README
index 0265675c3..d12eb3610 100644
--- a/security/nss/lib/freebl/ecl/README
+++ b/security/nss/lib/freebl/ecl/README
@@ -46,7 +46,7 @@ that does not have access to mp_ints.
ecl-curve.h - Provides hex encodings (in the form of ECCurveParams
structs) of standardizes elliptic curve domain parameters and mappings
-from ECCurveName to ECCurveParams. For use be code that does not have
+from ECCurveName to ECCurveParams. For use by code that does not have
access to mp_ints.
ecl.h - Interface to constructors for curve parameters and group object,
diff --git a/security/nss/lib/freebl/manifest.mn b/security/nss/lib/freebl/manifest.mn
index 00715a2ee..12f067249 100644
--- a/security/nss/lib/freebl/manifest.mn
+++ b/security/nss/lib/freebl/manifest.mn
@@ -62,7 +62,6 @@ EXPORTS = \
blapit.h \
shsign.h \
ecl-exp.h \
- ecl-curve.h \
$(NULL)
PRIVATE_EXPORTS = \
@@ -71,6 +70,7 @@ PRIVATE_EXPORTS = \
secrng.h \
ec.h \
ecl.h \
+ ecl-curve.h \
$(NULL)
MPI_HDRS = mpi-config.h mpi.h mpi-priv.h mplogic.h mpprime.h logtab.h mp_gf2m.h
diff --git a/security/nss/lib/freebl/rsa.c b/security/nss/lib/freebl/rsa.c
index e1d973fdb..5bbf31f20 100644
--- a/security/nss/lib/freebl/rsa.c
+++ b/security/nss/lib/freebl/rsa.c
@@ -61,6 +61,9 @@
*/
#define MAX_KEY_GEN_ATTEMPTS 10
+#define MAX_RSA_MODULUS 1024 /* bytes, 8k bits */
+#define MAX_RSA_EXPONENT 8 /* bytes, 64 bits */
+
/*
** RSABlindingParamsStr
**
@@ -310,7 +313,7 @@ RSA_PublicKeyOp(RSAPublicKey *key,
unsigned char *output,
const unsigned char *input)
{
- unsigned int modLen;
+ unsigned int modLen, expLen;
mp_int n, e, m, c;
mp_err err = MP_OKAY;
SECStatus rv = SECSuccess;
@@ -327,9 +330,22 @@ RSA_PublicKeyOp(RSAPublicKey *key,
CHECK_MPI_OK( mp_init(&m) );
CHECK_MPI_OK( mp_init(&c) );
modLen = rsa_modulusLen(&key->modulus);
+ expLen = rsa_modulusLen(&key->publicExponent);
/* 1. Obtain public key (n, e) */
+ if (expLen > modLen || modLen > MAX_RSA_MODULUS || expLen > MAX_RSA_EXPONENT) {
+ /* exponent should not be greater than modulus */
+ PORT_SetError(SEC_ERROR_INVALID_KEY);
+ rv = SECFailure;
+ goto cleanup;
+ }
SECITEM_TO_MPINT(key->modulus, &n);
SECITEM_TO_MPINT(key->publicExponent, &e);
+ if (e.used > n.used) {
+ /* exponent should not be greater than modulus */
+ PORT_SetError(SEC_ERROR_INVALID_KEY);
+ rv = SECFailure;
+ goto cleanup;
+ }
/* 2. Represent message as integer in range [0..n-1] */
CHECK_MPI_OK( mp_read_unsigned_octets(&m, input, modLen) );
/* 3. Compute c = m**e mod n */
diff --git a/security/nss/lib/jar/jarver.c b/security/nss/lib/jar/jarver.c
index a6e13d9f5..4252a8d5f 100644
--- a/security/nss/lib/jar/jarver.c
+++ b/security/nss/lib/jar/jarver.c
@@ -1377,7 +1377,9 @@ static char *jar_choose_nickname (CERTCertificate *cert)
char *JAR_cert_html
(JAR *jar, int style, long keylen, void *key, int *result)
{
+#ifdef notdef
char *html;
+#endif
CERTCertificate *cert;
*result = -1;
diff --git a/security/nss/lib/nss/nss.def b/security/nss/lib/nss/nss.def
index 9b002400c..40e959697 100644
--- a/security/nss/lib/nss/nss.def
+++ b/security/nss/lib/nss/nss.def
@@ -758,23 +758,23 @@ SECKEY_PublicKeyStrengthInBits;
;+};
;+NSS_3.9 { # NSS 3.9 release
;+ global:
-CERT_DecodeTimeChoice;
CERT_DestroyOidSequence;
-CERT_EncodeTimeChoice;
CERT_GetOidString;
;;CERT_TimeChoiceTemplate DATA ;
+DER_DecodeTimeChoice;
+DER_EncodeTimeChoice;
DSAU_DecodeDerSigToLen;
DSAU_EncodeDerSigWithLen;
NSS_Get_CERT_TimeChoiceTemplate;
PK11_DeriveWithFlagsPerm;
PK11_ExportEncryptedPrivKeyInfo;
-PK11_FindSlotsByAliases;
+PK11_FindSlotsByNames;
PK11_GetSymKeyType;
-PK11_MoveKey;
-PK11_PubDeriveExtended;
+PK11_MoveSymKey;
+PK11_PubDeriveWithKDF;
PK11_PubUnwrapSymKeyWithFlagsPerm;
PK11_UnwrapSymKeyWithFlagsPerm;
-SECKEY_ECParams2KeySize;
+SECITEM_ArenaDupItem;
SECMOD_GetDBModuleList;
SECMOD_GetDeadModuleList;
SEC_ASN1DecoderAbort;
diff --git a/security/nss/lib/nss/nss.h b/security/nss/lib/nss/nss.h
index 43106c15a..6f6b578eb 100644
--- a/security/nss/lib/nss/nss.h
+++ b/security/nss/lib/nss/nss.h
@@ -49,11 +49,11 @@ SEC_BEGIN_PROTOS
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>] [<Beta>]"
*/
-#define NSS_VERSION "3.9 Beta 3"
+#define NSS_VERSION "3.9"
#define NSS_VMAJOR 3
#define NSS_VMINOR 9
#define NSS_VPATCH 0
-#define NSS_BETA PR_TRUE
+#define NSS_BETA PR_FALSE
/*
diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c
index d2b2cd578..a100caca3 100644
--- a/security/nss/lib/pk11wrap/pk11cert.c
+++ b/security/nss/lib/pk11wrap/pk11cert.c
@@ -3525,17 +3525,40 @@ PK11_GetLowLevelKeyIDForPrivateKey(SECKEYPrivateKey *privKey)
return pk11_GetLowLevelKeyFromHandle(privKey->pkcs11Slot,privKey->pkcs11ID);
}
+/* argument type for listCertsCallback */
+typedef struct {
+ CERTCertList *list;
+ PK11SlotInfo *slot;
+} ListCertsArg;
+
static SECStatus
listCertsCallback(CERTCertificate* cert, void*arg)
{
- CERTCertList *list = (CERTCertList*)arg;
+ ListCertsArg *cdata = (ListCertsArg*)arg;
char *nickname = NULL;
+ nssCryptokiObject *instance, **ci;
+ nssCryptokiObject **instances;
+ NSSCertificate *c = STAN_GetNSSCertificate(cert);
- if (cert->nickname) {
- nickname = PORT_ArenaStrdup(list->arena,cert->nickname);
+ instances = nssPKIObject_GetInstances(&c->object);
+ instance = NULL;
+ for (ci = instances; *ci; ci++) {
+ if ((*ci)->token->pk11slot == cdata->slot) {
+ instance = *ci;
+ break;
+ }
+ }
+ PORT_Assert(instance != NULL);
+ if (!instance) {
+ nssCryptokiObjectArray_Destroy(instances);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
}
+ nickname = STAN_GetCERTCertificateNameForInstance(cdata->list->arena,
+ c, instance);
+ nssCryptokiObjectArray_Destroy(instances);
- return CERT_AddCertToListTailWithData(list,
+ return CERT_AddCertToListTailWithData(cdata->list,
CERT_DupCertificate(cert),nickname);
}
@@ -3544,12 +3567,15 @@ PK11_ListCertsInSlot(PK11SlotInfo *slot)
{
SECStatus status;
CERTCertList *certs;
+ ListCertsArg cdata;
certs = CERT_NewCertList();
if(certs == NULL) return NULL;
+ cdata.list = certs;
+ cdata.slot = slot;
status = PK11_TraverseCertsInSlot(slot, listCertsCallback,
- (void*)certs);
+ &cdata);
if( status != SECSuccess ) {
CERT_DestroyCertList(certs);
diff --git a/security/nss/lib/pk11wrap/pk11func.h b/security/nss/lib/pk11wrap/pk11func.h
index 179f11960..ddd968d22 100644
--- a/security/nss/lib/pk11wrap/pk11func.h
+++ b/security/nss/lib/pk11wrap/pk11func.h
@@ -140,12 +140,12 @@ SECStatus PK11_TokenRefresh(PK11SlotInfo *slot);
PK11SlotInfo *PK11_FindSlotByName(char *name);
PK11SlotInfo *PK11_FindSlotBySerial(char *serial);
/******************************************************************
- * PK11_FindSlotsByAliases searches for a PK11SlotInfo using one or
+ * PK11_FindSlotsByNames searches for a PK11SlotInfo using one or
* more criteria : dllName, slotName and tokenName . In addition, if
* presentOnly is set , only slots with a token inserted will be
* returned.
******************************************************************/
-PK11SlotList *PK11_FindSlotsByAliases(const char *dllName,
+PK11SlotList *PK11_FindSlotsByNames(const char *dllName,
const char* slotName, const char* tokenName, PRBool presentOnly);
PRBool PK11_IsReadOnly(PK11SlotInfo *slot);
PRBool PK11_IsInternal(PK11SlotInfo *slot);
@@ -304,7 +304,7 @@ SECStatus PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *params,
* operation or the flags and making the key permanent at the same time.
* If the key is moved to the same slot, operation and flags values are
* currently ignored */
-PK11SymKey *PK11_MoveKey(PK11SlotInfo *slot, CK_ATTRIBUTE_TYPE operation,
+PK11SymKey *PK11_MoveSymKey(PK11SlotInfo *slot, CK_ATTRIBUTE_TYPE operation,
CK_FLAGS flags, PRBool perm, PK11SymKey *symKey);
/*
* derive a new key from the base key.
@@ -330,11 +330,11 @@ PK11SymKey *PK11_PubDerive( SECKEYPrivateKey *privKey,
SECKEYPublicKey *pubKey, PRBool isSender, SECItem *randomA, SECItem *randomB,
CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target,
CK_ATTRIBUTE_TYPE operation, int keySize,void *wincx) ;
-PK11SymKey *PK11_PubDeriveExtended( SECKEYPrivateKey *privKey,
+PK11SymKey *PK11_PubDeriveWithKDF( SECKEYPrivateKey *privKey,
SECKEYPublicKey *pubKey, PRBool isSender, SECItem *randomA, SECItem *randomB,
CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target,
- CK_ATTRIBUTE_TYPE operation, int keySize,void *wincx,
- CK_ULONG kdf, SECItem *sharedData);
+ CK_ATTRIBUTE_TYPE operation, int keySize,
+ CK_ULONG kdf, SECItem *sharedData, void *wincx);
/*
* unwrap a new key with a symetric key.
diff --git a/security/nss/lib/pk11wrap/pk11skey.c b/security/nss/lib/pk11wrap/pk11skey.c
index 062a22f4a..35c553507 100644
--- a/security/nss/lib/pk11wrap/pk11skey.c
+++ b/security/nss/lib/pk11wrap/pk11skey.c
@@ -73,7 +73,7 @@ static PRBool pk11_FindAttrInTemplate(CK_ATTRIBUTE *attr,
unsigned int numAttrs, CK_ATTRIBUTE_TYPE target);
#ifdef NSS_ENABLE_ECC
-extern int SECKEY_ECParams2KeySize(SECItem *params);
+extern int SECKEY_ECParamsToKeySize(const SECItem *params);
#endif /* NSS_ENABLE_ECC */
/*
@@ -1281,7 +1281,7 @@ PK11_SignatureLen(SECKEYPrivateKey *key)
if (theTemplate.pValue != NULL) {
params.len = theTemplate.ulValueLen;
params.data = (unsigned char *) theTemplate.pValue;
- length = SECKEY_ECParams2KeySize(&params);
+ length = SECKEY_ECParamsToKeySize(&params);
PORT_Free(theTemplate.pValue);
}
length = ((length + 7)/8) * 2;
@@ -1428,7 +1428,7 @@ pk11_ForceSlot(PK11SymKey *symKey,CK_MECHANISM_TYPE type,
}
PK11SymKey *
-PK11_MoveKey(PK11SlotInfo *slot, CK_ATTRIBUTE_TYPE operation,
+PK11_MoveSymKey(PK11SlotInfo *slot, CK_ATTRIBUTE_TYPE operation,
CK_FLAGS flags, PRBool perm, PK11SymKey *symKey)
{
if (symKey->slot == slot) {
@@ -3000,11 +3000,11 @@ PK11_PubDerive(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
}
PK11SymKey *
-PK11_PubDeriveExtended(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
+PK11_PubDeriveWithKDF(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
PRBool isSender, SECItem *randomA, SECItem *randomB,
CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target,
- CK_ATTRIBUTE_TYPE operation, int keySize,void *wincx,
- CK_ULONG kdf, SECItem *sharedData)
+ CK_ATTRIBUTE_TYPE operation, int keySize,
+ CK_ULONG kdf, SECItem *sharedData, void *wincx)
{
PK11SlotInfo *slot = privKey->pkcs11Slot;
PK11SymKey *symKey;
diff --git a/security/nss/lib/pk11wrap/pk11slot.c b/security/nss/lib/pk11wrap/pk11slot.c
index 7533f61c6..875495940 100644
--- a/security/nss/lib/pk11wrap/pk11slot.c
+++ b/security/nss/lib/pk11wrap/pk11slot.c
@@ -566,7 +566,7 @@ SECMOD_HasRootCerts(void)
* Functions to find specific slots.
***********************************************************/
PK11SlotList *
-PK11_FindSlotsByAliases(const char *dllName, const char* slotName,
+PK11_FindSlotsByNames(const char *dllName, const char* slotName,
const char* tokenName, PRBool presentOnly)
{
SECMODModuleList *mlp;
@@ -2852,11 +2852,10 @@ PK11_AddMechanismEntry(CK_MECHANISM_TYPE type, CK_KEY_TYPE key,
if (size > tableSize) {
int oldTableSize = tableSize;
tableSize += 10;
- newt = (pk11MechanismData *)
- PORT_Alloc(tableSize*sizeof(pk11MechanismData));
+ newt = PORT_NewArray(pk11MechanismData, tableSize);
if (newt == NULL) return;
- if (old) PORT_Memcpy(newt,old,oldTableSize*sizeof(pk11MechanismData));
+ if (old) PORT_Memcpy(newt, old, oldTableSize*sizeof(*newt));
} else old = NULL;
newt[entry].type = type;
@@ -2936,6 +2935,8 @@ PK11_GetKeyType(CK_MECHANISM_TYPE type,unsigned long len)
case CKM_AES_MAC_GENERAL:
case CKM_AES_CBC_PAD:
case CKM_AES_KEY_GEN:
+ case CKM_NETSCAPE_AES_KEY_WRAP:
+ case CKM_NETSCAPE_AES_KEY_WRAP_PAD:
return CKK_AES;
case CKM_DES_ECB:
case CKM_DES_CBC:
@@ -3768,120 +3769,109 @@ static unsigned long rc2_unmap(unsigned long x)
SECItem *
PK11_ParamFromAlgid(SECAlgorithmID *algid)
{
- CK_RC2_CBC_PARAMS *rc2_params = NULL;
- CK_RC2_PARAMS *rc2_ecb_params = NULL;
- CK_RC5_CBC_PARAMS *rc5_params_cbc;
- CK_RC5_PARAMS *rc5_params_ecb;
- SECItem iv;
- sec_rc2cbcParameter rc2;
- sec_rc5cbcParameter rc5;
- SECItem *mech;
- CK_MECHANISM_TYPE type;
- SECOidTag algtag;
- SECStatus rv;
+ CK_RC2_CBC_PARAMS * rc2_cbc_params = NULL;
+ CK_RC2_PARAMS * rc2_ecb_params = NULL;
+ CK_RC5_CBC_PARAMS * rc5_cbc_params = NULL;
+ CK_RC5_PARAMS * rc5_ecb_params = NULL;
+ PRArenaPool * arena = NULL;
+ SECItem * mech = NULL;
+ SECOidTag algtag;
+ SECStatus rv;
+ CK_MECHANISM_TYPE type;
+ /* initialize these to prevent UMRs in the ASN1 decoder. */
+ SECItem iv = {siBuffer, NULL, 0};
+ sec_rc2cbcParameter rc2 = { {siBuffer, NULL, 0}, {siBuffer, NULL, 0} };
+ sec_rc5cbcParameter rc5 = { {siBuffer, NULL, 0}, {siBuffer, NULL, 0},
+ {siBuffer, NULL, 0}, {siBuffer, NULL, 0} };
algtag = SECOID_GetAlgorithmTag(algid);
type = PK11_AlgtagToMechanism(algtag);
- mech = (SECItem *) PORT_Alloc(sizeof(SECItem));
- if (mech == NULL) return NULL;
+ mech = PORT_New(SECItem);
+ if (mech == NULL) {
+ return NULL;
+ }
mech->type = siBuffer;
+ mech->data = NULL;
+ mech->len = 0;
+ arena = PORT_NewArena(1024);
+ if (!arena) {
+ goto loser;
+ }
/* handle the complicated cases */
switch (type) {
case CKM_RC2_ECB:
- rv = SEC_ASN1DecodeItem(NULL, &rc2 ,sec_rc2ecb_parameter_template,
+ rv = SEC_ASN1DecodeItem(arena, &rc2 ,sec_rc2ecb_parameter_template,
&(algid->parameters));
if (rv != SECSuccess) {
- PORT_Free(mech);
- return NULL;
+ goto loser;
}
- rc2_ecb_params = (CK_RC2_PARAMS *)PORT_Alloc(sizeof(CK_RC2_PARAMS));
+ rc2_ecb_params = PORT_New(CK_RC2_PARAMS);
if (rc2_ecb_params == NULL) {
- PORT_Free(rc2.rc2ParameterVersion.data);
- PORT_Free(mech);
- return NULL;
+ goto loser;
}
*rc2_ecb_params = rc2_map(&rc2.rc2ParameterVersion);
- PORT_Free(rc2.rc2ParameterVersion.data);
mech->data = (unsigned char *) rc2_ecb_params;
- mech->len = sizeof(CK_RC2_PARAMS);
- return mech;
+ mech->len = sizeof *rc2_ecb_params;
+ break;
case CKM_RC2_CBC:
case CKM_RC2_CBC_PAD:
- rv = SEC_ASN1DecodeItem(NULL, &rc2 ,sec_rc2cbc_parameter_template,
+ rv = SEC_ASN1DecodeItem(arena, &rc2 ,sec_rc2cbc_parameter_template,
&(algid->parameters));
if (rv != SECSuccess) {
- PORT_Free(mech);
- return NULL;
+ goto loser;
}
- rc2_params = (CK_RC2_CBC_PARAMS *)PORT_Alloc(sizeof(CK_RC2_CBC_PARAMS));
- if (rc2_params == NULL) {
- PORT_Free(rc2.iv.data);
- PORT_Free(rc2.rc2ParameterVersion.data);
- PORT_Free(mech);
- return NULL;
+ rc2_cbc_params = PORT_New(CK_RC2_CBC_PARAMS);
+ if (rc2_cbc_params == NULL) {
+ goto loser;
}
- rc2_params->ulEffectiveBits = rc2_map(&rc2.rc2ParameterVersion);
- PORT_Free(rc2.rc2ParameterVersion.data);
- PORT_Memcpy(rc2_params->iv,rc2.iv.data,sizeof(rc2_params->iv));
- PORT_Free(rc2.iv.data);
- mech->data = (unsigned char *) rc2_params;
- mech->len = sizeof(CK_RC2_CBC_PARAMS);
- return mech;
+ mech->data = (unsigned char *) rc2_cbc_params;
+ mech->len = sizeof *rc2_cbc_params;
+ rc2_cbc_params->ulEffectiveBits = rc2_map(&rc2.rc2ParameterVersion);
+ if (rc2.iv.len != sizeof rc2_cbc_params->iv) {
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ goto loser;
+ }
+ PORT_Memcpy(rc2_cbc_params->iv, rc2.iv.data, rc2.iv.len);
+ break;
case CKM_RC5_ECB:
- rv = SEC_ASN1DecodeItem(NULL, &rc5 ,sec_rc5ecb_parameter_template,
+ rv = SEC_ASN1DecodeItem(arena, &rc5 ,sec_rc5ecb_parameter_template,
&(algid->parameters));
if (rv != SECSuccess) {
- PORT_Free(mech);
- return NULL;
+ goto loser;
}
- rc5_params_ecb=(CK_RC5_PARAMS *)PORT_Alloc(sizeof(CK_RC5_PARAMS));
- PORT_Free(rc5.version.data);
- if (rc5_params_ecb == NULL) {
- PORT_Free(rc5.rounds.data);
- PORT_Free(rc5.blockSizeInBits.data);
- PORT_Free(mech);
- return NULL;
+ rc5_ecb_params = PORT_New(CK_RC5_PARAMS);
+ if (rc5_ecb_params == NULL) {
+ goto loser;
}
- rc5_params_ecb->ulRounds = DER_GetInteger(&rc5.rounds);
- rc5_params_ecb->ulWordsize = DER_GetInteger(&rc5.blockSizeInBits)/8;
- PORT_Free(rc5.rounds.data);
- PORT_Free(rc5.blockSizeInBits.data);
- mech->data = (unsigned char *) rc5_params_ecb;
- mech->len = sizeof(CK_RC5_PARAMS);
- return mech;
+ rc5_ecb_params->ulRounds = DER_GetInteger(&rc5.rounds);
+ rc5_ecb_params->ulWordsize = DER_GetInteger(&rc5.blockSizeInBits)/8;
+ mech->data = (unsigned char *) rc5_ecb_params;
+ mech->len = sizeof *rc5_ecb_params;
+ break;
case CKM_RC5_CBC:
case CKM_RC5_CBC_PAD:
- rv = SEC_ASN1DecodeItem(NULL, &rc5 ,sec_rc5cbc_parameter_template,
+ rv = SEC_ASN1DecodeItem(arena, &rc5 ,sec_rc5cbc_parameter_template,
&(algid->parameters));
if (rv != SECSuccess) {
- PORT_Free(mech);
- return NULL;
+ goto loser;
}
- rc5_params_cbc = (CK_RC5_CBC_PARAMS *)
+ rc5_cbc_params = (CK_RC5_CBC_PARAMS *)
PORT_Alloc(sizeof(CK_RC5_CBC_PARAMS) + rc5.iv.len);
- PORT_Free(rc5.version.data);
- if (rc2_params == NULL) {
- PORT_Free(rc5.iv.data);
- PORT_Free(rc5.rounds.data);
- PORT_Free(rc5.blockSizeInBits.data);
- PORT_Free(mech);
- return NULL;
+ if (rc5_cbc_params == NULL) {
+ goto loser;
}
- rc5_params_cbc->ulRounds = DER_GetInteger(&rc5.rounds);
- rc5_params_cbc->ulWordsize = DER_GetInteger(&rc5.blockSizeInBits)/8;
- PORT_Free(rc5.rounds.data);
- PORT_Free(rc5.blockSizeInBits.data);
- rc5_params_cbc->pIv = ((CK_BYTE_PTR)rc5_params_cbc)
+ mech->data = (unsigned char *) rc5_cbc_params;
+ mech->len = sizeof *rc5_cbc_params;
+ rc5_cbc_params->ulRounds = DER_GetInteger(&rc5.rounds);
+ rc5_cbc_params->ulWordsize = DER_GetInteger(&rc5.blockSizeInBits)/8;
+ rc5_cbc_params->pIv = ((CK_BYTE_PTR)rc5_cbc_params)
+ sizeof(CK_RC5_CBC_PARAMS);
- PORT_Memcpy(rc5_params_cbc->pIv,rc5.iv.data,rc5.iv.len);
- rc5_params_cbc->ulIvLen = rc5.iv.len;
- PORT_Free(rc5.iv.data);
- mech->data = (unsigned char *) rc5_params_cbc;
- mech->len = sizeof(CK_RC5_CBC_PARAMS);
- return mech;
+ rc5_cbc_params->ulIvLen = rc5.iv.len;
+ PORT_Memcpy(rc5_cbc_params->pIv, rc5.iv.data, rc5.iv.len);
+ break;
case CKM_PBE_MD2_DES_CBC:
case CKM_PBE_MD5_DES_CBC:
case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
@@ -3899,25 +3889,9 @@ PK11_ParamFromAlgid(SECAlgorithmID *algid)
case CKM_PBE_SHA1_RC4_128:
rv = pbe_PK11AlgidToParam(algid,mech);
if (rv != SECSuccess) {
- PORT_Free(mech);
- return NULL;
+ goto loser;
}
- return mech;
- default:
- /* must be a simple case */
break;
- }
-
- /* simple cases are simpley Octect encoded IV's */
- rv = SEC_ASN1DecodeItem(NULL, &iv, SEC_OctetStringTemplate,
- &(algid->parameters));
- if (rv != SECSuccess) {
- iv.data = NULL;
- iv.len = 0;
- }
-
- rv = SECSuccess;
- switch (type) {
case CKM_RC4:
case CKM_AES_ECB:
case CKM_DES_ECB:
@@ -3927,15 +3901,13 @@ PK11_ParamFromAlgid(SECAlgorithmID *algid)
case CKM_CAST_ECB:
case CKM_CAST3_ECB:
case CKM_CAST5_ECB:
- mech->data = NULL;
- mech->len = 0;
break;
+
default:
if (pk11_lookup(type)->iv == 0) {
- mech->data = NULL;
- mech->len = 0;
break;
}
+ /* FALL THROUGH */
case CKM_AES_CBC:
case CKM_DES_CBC:
case CKM_DES3_CBC:
@@ -3968,25 +3940,29 @@ PK11_ParamFromAlgid(SECAlgorithmID *algid)
case CKM_JUNIPER_CBC128:
case CKM_JUNIPER_COUNTER:
case CKM_JUNIPER_SHUFFLE:
- if (iv.data == NULL) {
- rv = SECFailure;
- break;
+ /* simple cases are simply octet string encoded IVs */
+ rv = SEC_ASN1DecodeItem(arena, &iv, SEC_OctetStringTemplate,
+ &(algid->parameters));
+ if (rv != SECSuccess || iv.data == NULL) {
+ goto loser;
}
+ /* XXX Should be some IV length sanity check here. */
mech->data = (unsigned char*)PORT_Alloc(iv.len);
if (mech->data == NULL) {
- rv = SECFailure;
- break;
+ goto loser;
}
- PORT_Memcpy(mech->data,iv.data,iv.len);
+ PORT_Memcpy(mech->data, iv.data, iv.len);
mech->len = iv.len;
break;
}
- if (iv.data) PORT_Free(iv.data);
- if (rv != SECSuccess) {
- SECITEM_FreeItem(mech,PR_TRUE);
- return NULL;
- }
+ PORT_FreeArena(arena, PR_FALSE);
return mech;
+
+loser:
+ if (arena)
+ PORT_FreeArena(arena, PR_FALSE);
+ SECITEM_FreeItem(mech,PR_TRUE);
+ return NULL;
}
SECStatus
diff --git a/security/nss/lib/pkcs12/p12d.c b/security/nss/lib/pkcs12/p12d.c
index cbdc352f7..624592117 100644
--- a/security/nss/lib/pkcs12/p12d.c
+++ b/security/nss/lib/pkcs12/p12d.c
@@ -1098,6 +1098,7 @@ p12u_DigestRead(void *arg, unsigned char *buf, unsigned long len)
SEC_PKCS12DecoderContext* p12cxt = arg;
if(!buf || len == 0 || !p12cxt->buffer) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
return -1;
}
@@ -1105,7 +1106,7 @@ p12u_DigestRead(void *arg, unsigned char *buf, unsigned long len)
/* trying to read past the end of the buffer */
toread = p12cxt->filesize - p12cxt->currentpos;
}
- memcpy(buf, (void*)((char*)p12cxt->buffer + p12cxt->currentpos), toread);
+ memcpy(buf, (char*)p12cxt->buffer + p12cxt->currentpos, toread);
p12cxt->currentpos += toread;
return toread;
}
@@ -1136,7 +1137,7 @@ p12u_DigestWrite(void *arg, unsigned char *buf, unsigned long len)
p12cxt->allocated = newsize;
}
PR_ASSERT(p12cxt->buffer);
- memcpy((void*)((char*)p12cxt->buffer + p12cxt->currentpos), buf, len);
+ memcpy((char*)p12cxt->buffer + p12cxt->currentpos, buf, len);
p12cxt->currentpos += len;
return len;
}
@@ -1291,10 +1292,8 @@ loser:
#define IN_BUF_LEN 1024
#ifdef DEBUG
static const char bufferEnd[] = { "BufferEnd" } ;
-#define FUDGE sizeof bufferEnd
-#else
-#define FUDGE 128 /* extra protection when assertions disabled. */
#endif
+#define FUDGE 128 /* must be as large as bufferEnd or more. */
/* verify the hmac by reading the data from the temporary file
* using the routines specified when the decodingContext was
@@ -1318,6 +1317,7 @@ sec_pkcs12_decoder_verify_mac(SEC_PKCS12DecoderContext *p12dcx)
CK_MECHANISM_TYPE integrityMech;
if(!p12dcx || p12dcx->error) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
buf = (unsigned char *)PORT_Alloc(IN_BUF_LEN + FUDGE);
@@ -1388,7 +1388,7 @@ sec_pkcs12_decoder_verify_mac(SEC_PKCS12DecoderContext *p12dcx)
if (bytesRead > IN_BUF_LEN) {
/* dRead callback overflowed buffer. */
- PORT_SetError(SEC_ERROR_PKCS12_UNABLE_TO_READ);
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
goto loser;
}
diff --git a/security/nss/lib/pkcs7/p7create.c b/security/nss/lib/pkcs7/p7create.c
index 6454db74c..62573cb46 100644
--- a/security/nss/lib/pkcs7/p7create.c
+++ b/security/nss/lib/pkcs7/p7create.c
@@ -617,7 +617,7 @@ SEC_PKCS7AddSigningTime (SEC_PKCS7ContentInfo *cinfo)
if (signerinfos == NULL || signerinfos[0] == NULL)
return SECFailure;
- rv = CERT_EncodeTimeChoice(NULL, &stime, PR_Now());
+ rv = DER_EncodeTimeChoice(NULL, &stime, PR_Now());
if (rv != SECSuccess)
return rv;
diff --git a/security/nss/lib/pkcs7/p7decode.c b/security/nss/lib/pkcs7/p7decode.c
index cba3ac9ef..e4d565fb5 100644
--- a/security/nss/lib/pkcs7/p7decode.c
+++ b/security/nss/lib/pkcs7/p7decode.c
@@ -1573,7 +1573,7 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
*/
encoded_stime = SEC_PKCS7GetSigningTime (cinfo);
if (encoded_stime != NULL) {
- if (CERT_DecodeTimeChoice (&stime, encoded_stime) != SECSuccess)
+ if (DER_DecodeTimeChoice (&stime, encoded_stime) != SECSuccess)
encoded_stime = NULL; /* conversion failed, so pretend none */
}
diff --git a/security/nss/lib/pki/pkibase.c b/security/nss/lib/pki/pkibase.c
index 5ee2a4ee9..ecbb6872b 100644
--- a/security/nss/lib/pki/pkibase.c
+++ b/security/nss/lib/pki/pkibase.c
@@ -217,12 +217,11 @@ nssPKIObject_RemoveInstanceForToken (
}
}
if (--object->numInstances > 0) {
- object->instances = nss_ZREALLOCARRAY(object->instances,
+ nssCryptokiObject **instances = nss_ZREALLOCARRAY(object->instances,
nssCryptokiObject *,
object->numInstances);
- if (!object->instances) {
- PZ_Unlock(object->lock);
- return PR_FAILURE;
+ if (instances) {
+ object->instances = instances;
}
} else {
nss_ZFreeIf(object->instances);
@@ -244,10 +243,12 @@ nssPKIObject_DeleteStoredObject (
{
PRUint32 i, numNotDestroyed;
PRStatus status = PR_SUCCESS;
+#ifndef NSS_3_4_CODE
NSSTrustDomain *td = object->trustDomain;
NSSCallback *pwcb = uhh ? /* is this optional? */
uhh :
nssTrustDomain_GetDefaultCallback(td, NULL);
+#endif
numNotDestroyed = 0;
PZ_Lock(object->lock);
for (i=0; i<object->numInstances; i++) {
diff --git a/security/nss/lib/pki/tdcache.c b/security/nss/lib/pki/tdcache.c
index c9fd8012f..77e71a08a 100644
--- a/security/nss/lib/pki/tdcache.c
+++ b/security/nss/lib/pki/tdcache.c
@@ -715,6 +715,50 @@ add_email_entry (
extern const NSSError NSS_ERROR_CERTIFICATE_IN_CACHE;
+static void
+remove_object_instances (
+ nssPKIObject *object,
+ nssCryptokiObject **instances,
+ int numInstances
+)
+{
+ int i;
+
+ for (i = 0; i < numInstances; i++) {
+ nssPKIObject_RemoveInstanceForToken(object, instances[i]->token);
+ }
+}
+
+static SECStatus
+merge_object_instances (
+ nssPKIObject *to,
+ nssPKIObject *from
+)
+{
+ nssCryptokiObject **instances, **ci;
+ int i;
+ SECStatus rv = SECSuccess;
+
+ instances = nssPKIObject_GetInstances(from);
+ if (instances == NULL) {
+ return SECFailure;
+ }
+ for (ci = instances, i = 0; *ci; ci++, i++) {
+ nssCryptokiObject *instance = nssCryptokiObject_Clone(*ci);
+ if (instance) {
+ if (nssPKIObject_AddInstance(to, instance) == SECSuccess) {
+ continue;
+ }
+ nssCryptokiObject_Destroy(instance);
+ }
+ remove_object_instances(to, instances, i);
+ rv = SECFailure;
+ break;
+ }
+ nssCryptokiObjectArray_Destroy(instances);
+ return rv;
+}
+
static NSSCertificate *
add_cert_to_cache (
NSSTrustDomain *td,
@@ -743,6 +787,13 @@ add_cert_to_cache (
/* collision - somebody else already added the cert
* to the cache before this thread got around to it.
*/
+ /* merge the instances of the cert */
+ if (merge_object_instances(&rvCert->object, &cert->object)
+ != SECSuccess) {
+ nssCertificate_Destroy(rvCert);
+ return NULL;
+ }
+ STAN_ForceCERTCertificateUpdate(rvCert);
nssCertificate_Destroy(cert);
return rvCert;
}
diff --git a/security/nss/lib/smime/cms.h b/security/nss/lib/smime/cms.h
index 0538f1a37..7003a6e27 100644
--- a/security/nss/lib/smime/cms.h
+++ b/security/nss/lib/smime/cms.h
@@ -563,9 +563,6 @@ extern SECStatus
NSS_CMSSignedData_AddSignerInfo(NSSCMSSignedData *sigd,
NSSCMSSignerInfo *signerinfo);
-extern SECItem *
-NSS_CMSSignedData_GetDigestByAlgTag(NSSCMSSignedData *sigd, SECOidTag algtag);
-
extern SECStatus
NSS_CMSSignedData_SetDigests(NSSCMSSignedData *sigd,
SECAlgorithmID **digestalgs,
@@ -673,7 +670,7 @@ NSS_CMSSignerInfo_GetSigningCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDB
*
* sinfo - signerInfo data for this signer
*
- * Returns a pointer to allocated memory, which must be freed.
+ * Returns a pointer to allocated memory, which must be freed with PORT_Free.
* A return value of NULL is an error.
*/
extern char *
diff --git a/security/nss/lib/smime/cmsarray.c b/security/nss/lib/smime/cmsarray.c
index 68d7e1963..2673770d9 100644
--- a/security/nss/lib/smime/cmsarray.c
+++ b/security/nss/lib/smime/cmsarray.c
@@ -91,6 +91,10 @@ NSS_CMSArray_Add(PRArenaPool *poolp, void ***array, void *obj)
(n + 1) * sizeof(void *),
(n + 2) * sizeof(void *));
}
+
+ if (dest == NULL)
+ return SECFailure;
+
dest[n] = obj;
dest[n+1] = NULL;
*array = dest;
diff --git a/security/nss/lib/smime/cmsattr.c b/security/nss/lib/smime/cmsattr.c
index 03b516f9e..250670745 100644
--- a/security/nss/lib/smime/cmsattr.c
+++ b/security/nss/lib/smime/cmsattr.c
@@ -86,13 +86,11 @@ NSS_CMSAttribute_Create(PRArenaPool *poolp, SECOidTag oidtag, SECItem *value, PR
goto loser;
if (value != NULL) {
- if ((copiedvalue = SECITEM_AllocItem(poolp, NULL, value->len)) == NULL)
+ if ((copiedvalue = SECITEM_ArenaDupItem(poolp, value)) == NULL)
goto loser;
- if (SECITEM_CopyItem(poolp, copiedvalue, value) != SECSuccess)
+ if (NSS_CMSArray_Add(poolp, (void ***)&(attr->values), (void *)copiedvalue) != SECSuccess)
goto loser;
-
- NSS_CMSArray_Add(poolp, (void ***)&(attr->values), (void *)copiedvalue);
}
attr->encoded = encoded;
@@ -113,18 +111,22 @@ loser:
SECStatus
NSS_CMSAttribute_AddValue(PLArenaPool *poolp, NSSCMSAttribute *attr, SECItem *value)
{
- SECItem copiedvalue;
+ SECItem *copiedvalue;
void *mark;
PORT_Assert (poolp != NULL);
mark = PORT_ArenaMark(poolp);
- /* XXX we need an object memory model #$%#$%! */
- if (SECITEM_CopyItem(poolp, &copiedvalue, value) != SECSuccess)
+ if (value == NULL) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ goto loser;
+ }
+
+ if ((copiedvalue = SECITEM_ArenaDupItem(poolp, value)) == NULL)
goto loser;
- if (NSS_CMSArray_Add(poolp, (void ***)&(attr->values), (void *)&copiedvalue) != SECSuccess)
+ if (NSS_CMSArray_Add(poolp, (void ***)&(attr->values), (void *)copiedvalue) != SECSuccess)
goto loser;
PORT_ArenaUnmark(poolp, mark);
@@ -217,9 +219,12 @@ cms_attr_choose_attr_value_template(void *src_or_dest, PRBool encoding)
attribute = (NSSCMSAttribute *)src_or_dest;
- if (encoding && attribute->encoded)
- /* we're encoding, and the attribute value is already encoded. */
- return SEC_ASN1_GET(SEC_AnyTemplate);
+ if (encoding && (!attribute->values || !attribute->values[0] ||
+ attribute->encoded)) {
+ /* we're encoding, and the attribute has no value or the attribute
+ * value is already encoded. */
+ return SEC_ASN1_GET(SEC_AnyTemplate);
+ }
/* get attribute's typeTag */
oiddata = attribute->typeTag;
diff --git a/security/nss/lib/smime/cmscinfo.c b/security/nss/lib/smime/cmscinfo.c
index d01c5962b..ceb99c605 100644
--- a/security/nss/lib/smime/cmscinfo.c
+++ b/security/nss/lib/smime/cmscinfo.c
@@ -76,6 +76,11 @@ NSS_CMSContentInfo_Destroy(NSSCMSContentInfo *cinfo)
/* XXX Anything else that needs to be "manually" freed/destroyed? */
break;
}
+ if (cinfo->digcx) {
+ /* must destroy digest objects */
+ NSS_CMSDigestContext_Cancel(cinfo->digcx);
+ cinfo->digcx = NULL;
+ }
if (cinfo->bulkkey)
PK11_FreeSymKey(cinfo->bulkkey);
@@ -204,7 +209,10 @@ NSS_CMSContentInfo_SetContent_EncryptedData(NSSCMSMessage *cmsg, NSSCMSContentIn
void *
NSS_CMSContentInfo_GetContent(NSSCMSContentInfo *cinfo)
{
- switch (cinfo->contentTypeTag->offset) {
+ SECOidTag tag = (cinfo && cinfo->contentTypeTag)
+ ? cinfo->contentTypeTag->offset
+ : SEC_OID_UNKNOWN;
+ switch (tag) {
case SEC_OID_PKCS7_DATA:
case SEC_OID_PKCS7_SIGNED_DATA:
case SEC_OID_PKCS7_ENVELOPED_DATA:
@@ -225,22 +233,28 @@ SECItem *
NSS_CMSContentInfo_GetInnerContent(NSSCMSContentInfo *cinfo)
{
NSSCMSContentInfo *ccinfo;
+ SECOidTag tag;
+ SECItem *pItem = NULL;
- switch (NSS_CMSContentInfo_GetContentTypeTag(cinfo)) {
+ tag = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
+ switch (tag) {
case SEC_OID_PKCS7_DATA:
- return cinfo->content.data; /* end of recursion - every message has to have a data cinfo */
+ /* end of recursion - every message has to have a data cinfo */
+ pItem = cinfo->content.data;
+ break;
case SEC_OID_PKCS7_DIGESTED_DATA:
case SEC_OID_PKCS7_ENCRYPTED_DATA:
case SEC_OID_PKCS7_ENVELOPED_DATA:
case SEC_OID_PKCS7_SIGNED_DATA:
- if ((ccinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo)) == NULL)
- break;
- return NSS_CMSContentInfo_GetContent(ccinfo);
+ ccinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo);
+ if (ccinfo != NULL)
+ pItem = NSS_CMSContentInfo_GetContent(ccinfo);
+ break;
default:
PORT_Assert(0);
break;
}
- return NULL;
+ return pItem;
}
/*
diff --git a/security/nss/lib/smime/cmscipher.c b/security/nss/lib/smime/cmscipher.c
index 6d73beaff..71cd9682a 100644
--- a/security/nss/lib/smime/cmscipher.c
+++ b/security/nss/lib/smime/cmscipher.c
@@ -507,7 +507,6 @@ NSS_CMSCipherContext_Decrypt(NSSCMSCipherContext *cc, unsigned char *output,
* If we do not, there is something wrong, either with our own
* logic or with (length of) the data given to us.
*/
- PORT_Assert ((padsize == 0) || (pcount % padsize) == 0);
if ((padsize != 0) && (pcount % padsize) != 0) {
PORT_Assert (final);
PORT_SetError (SEC_ERROR_BAD_DATA);
diff --git a/security/nss/lib/smime/cmsdecode.c b/security/nss/lib/smime/cmsdecode.c
index 8ba2b33dd..1abc1772c 100644
--- a/security/nss/lib/smime/cmsdecode.c
+++ b/security/nss/lib/smime/cmsdecode.c
@@ -48,15 +48,15 @@
#include "secerr.h"
struct NSSCMSDecoderContextStr {
- SEC_ASN1DecoderContext * dcx; /* ASN.1 decoder context */
- NSSCMSMessage * cmsg; /* backpointer to the root message */
- SECOidTag type; /* type of message */
- NSSCMSContent content; /* pointer to message */
- NSSCMSDecoderContext * childp7dcx; /* inner CMS decoder context */
- PRBool saw_contents;
- int error;
- NSSCMSContentCallback cb;
- void * cb_arg;
+ SEC_ASN1DecoderContext * dcx; /* ASN.1 decoder context */
+ NSSCMSMessage * cmsg; /* backpointer to the root message */
+ SECOidTag type; /* type of message */
+ NSSCMSContent content; /* pointer to message */
+ NSSCMSDecoderContext * childp7dcx; /* inner CMS decoder context */
+ PRBool saw_contents;
+ int error;
+ NSSCMSContentCallback cb;
+ void * cb_arg;
};
struct NSSCMSDecoderDataStr {
@@ -66,13 +66,13 @@ struct NSSCMSDecoderDataStr {
typedef struct NSSCMSDecoderDataStr NSSCMSDecoderData;
-static void nss_cms_decoder_update_filter (void *arg, const char *data, unsigned long len,
- int depth, SEC_ASN1EncodingPart data_kind);
+static void nss_cms_decoder_update_filter (void *arg, const char *data,
+ unsigned long len, int depth, SEC_ASN1EncodingPart data_kind);
static SECStatus nss_cms_before_data(NSSCMSDecoderContext *p7dcx);
static SECStatus nss_cms_after_data(NSSCMSDecoderContext *p7dcx);
static SECStatus nss_cms_after_end(NSSCMSDecoderContext *p7dcx);
-static void nss_cms_decoder_work_data(NSSCMSDecoderContext *p7dcx,
- const unsigned char *data, unsigned long len, PRBool final);
+static void nss_cms_decoder_work_data(NSSCMSDecoderContext *p7dcx,
+ const unsigned char *data, unsigned long len, PRBool final);
static NSSCMSDecoderData *nss_cms_create_decoder_data(PRArenaPool *poolp);
extern const SEC_ASN1Template NSSCMSMessageTemplate[];
@@ -129,7 +129,8 @@ nss_cms_decoder_notify(void *arg, PRBool before, void *dest, int depth)
*/
if (after && dest == &(rootcinfo->contentType)) {
p7dcx->type = NSS_CMSContentInfo_GetContentTypeTag(rootcinfo);
- p7dcx->content = rootcinfo->content; /* is this ready already ? need to alloc? */
+ p7dcx->content = rootcinfo->content;
+ /* is this ready already ? need to alloc? */
/* XXX yes we need to alloc -- continue here */
}
break;
@@ -138,8 +139,10 @@ nss_cms_decoder_notify(void *arg, PRBool before, void *dest, int depth)
/* otherwise, we handle this type implicitely in the inner decoders */
if (before && dest == &(rootcinfo->content)) {
- /* fake it to cause the filter to put the data in the right place... */
- /* we want the ASN.1 decoder to deliver the decoded bytes to us from now on */
+ /* cause the filter to put the data in the right place...
+ ** We want the ASN.1 decoder to deliver the decoded bytes to us
+ ** from now on
+ */
SEC_ASN1DecoderSetFilterProc(p7dcx->dcx,
nss_cms_decoder_update_filter,
p7dcx,
@@ -159,13 +162,14 @@ nss_cms_decoder_notify(void *arg, PRBool before, void *dest, int depth)
case SEC_OID_PKCS7_ENCRYPTED_DATA:
if (before && dest == &(rootcinfo->content))
- break; /* we're not there yet */
+ break; /* we're not there yet */
if (p7dcx->content.pointer == NULL)
p7dcx->content = rootcinfo->content;
/* get this data type's inner contentInfo */
- cinfo = NSS_CMSContent_GetContentInfo(p7dcx->content.pointer, p7dcx->type);
+ cinfo = NSS_CMSContent_GetContentInfo(p7dcx->content.pointer,
+ p7dcx->type);
if (before && dest == &(cinfo->contentType)) {
/* at this point, set up the &%$&$ back pointer */
@@ -191,14 +195,18 @@ nss_cms_decoder_notify(void *arg, PRBool before, void *dest, int depth)
}
if (before && dest == &(cinfo->rawContent)) {
- /* we want the ASN.1 decoder to deliver the decoded bytes to us from now on */
- SEC_ASN1DecoderSetFilterProc(p7dcx->dcx, nss_cms_decoder_update_filter,
- p7dcx, (PRBool)(p7dcx->cb != NULL));
+ /* we want the ASN.1 decoder to deliver the decoded bytes to us
+ ** from now on
+ */
+ SEC_ASN1DecoderSetFilterProc(p7dcx->dcx,
+ nss_cms_decoder_update_filter,
+ p7dcx, (PRBool)(p7dcx->cb != NULL));
/* we're right in front of the data */
if (nss_cms_before_data(p7dcx) != SECSuccess) {
- SEC_ASN1DecoderClearFilterProc(p7dcx->dcx); /* stop all processing */
+ SEC_ASN1DecoderClearFilterProc(p7dcx->dcx);
+ /* stop all processing */
p7dcx->error = PORT_GetError();
}
}
@@ -216,7 +224,7 @@ nss_cms_decoder_notify(void *arg, PRBool before, void *dest, int depth)
case SEC_OID_PKCS7_AUTHENTICATED_DATA:
#endif
default:
- /* unsupported or unknown message type - fail (more or less) gracefully */
+ /* unsupported or unknown message type - fail gracefully */
p7dcx->error = SEC_ERROR_UNSUPPORTED_MESSAGE_TYPE;
break;
}
@@ -244,28 +252,24 @@ nss_cms_before_data(NSSCMSDecoderContext *p7dcx)
case SEC_OID_PKCS7_SIGNED_DATA:
/* we're decoding a signedData, so set up the digests */
rv = NSS_CMSSignedData_Decode_BeforeData(p7dcx->content.signedData);
- if (rv != SECSuccess)
- return SECFailure;
break;
case SEC_OID_PKCS7_DIGESTED_DATA:
/* we're encoding a digestedData, so set up the digest */
rv = NSS_CMSDigestedData_Decode_BeforeData(p7dcx->content.digestedData);
- if (rv != SECSuccess)
- return SECFailure;
break;
case SEC_OID_PKCS7_ENVELOPED_DATA:
- rv = NSS_CMSEnvelopedData_Decode_BeforeData(p7dcx->content.envelopedData);
- if (rv != SECSuccess)
- return SECFailure;
+ rv = NSS_CMSEnvelopedData_Decode_BeforeData(
+ p7dcx->content.envelopedData);
break;
case SEC_OID_PKCS7_ENCRYPTED_DATA:
- rv = NSS_CMSEncryptedData_Decode_BeforeData(p7dcx->content.encryptedData);
- if (rv != SECSuccess)
- return SECFailure;
+ rv = NSS_CMSEncryptedData_Decode_BeforeData(
+ p7dcx->content.encryptedData);
break;
default:
return SECFailure;
}
+ if (rv != SECSuccess)
+ return SECFailure;
/* ok, now we have a pointer to cinfo */
/* find out what kind of data is encapsulated */
@@ -288,7 +292,7 @@ nss_cms_before_data(NSSCMSDecoderContext *p7dcx)
if ((template = NSS_CMSUtil_GetTemplateByTypeTag(childtype)) == NULL)
return SECFailure;
- childp7dcx = (NSSCMSDecoderContext *)PORT_ZAlloc(sizeof(NSSCMSDecoderContext));
+ childp7dcx = PORT_ZNew(NSSCMSDecoderContext);
if (childp7dcx == NULL)
return SECFailure;
@@ -301,12 +305,14 @@ nss_cms_before_data(NSSCMSDecoderContext *p7dcx)
goto loser;
/* start the child decoder */
- childp7dcx->dcx = SEC_ASN1DecoderStart(poolp, childp7dcx->content.pointer, template);
+ childp7dcx->dcx = SEC_ASN1DecoderStart(poolp, childp7dcx->content.pointer,
+ template);
if (childp7dcx->dcx == NULL)
goto loser;
/* the new decoder needs to notify, too */
- SEC_ASN1DecoderSetNotifyProc(childp7dcx->dcx, nss_cms_decoder_notify, childp7dcx);
+ SEC_ASN1DecoderSetNotifyProc(childp7dcx->dcx, nss_cms_decoder_notify,
+ childp7dcx);
/* tell the parent decoder that it needs to feed us the content data */
p7dcx->childp7dcx = childp7dcx;
@@ -315,7 +321,9 @@ nss_cms_before_data(NSSCMSDecoderContext *p7dcx)
childp7dcx->cmsg = p7dcx->cmsg; /* backpointer to root message */
- /* should the child decoder encounter real data, it needs to give it to the caller */
+ /* should the child decoder encounter real data,
+ ** it must give it to the caller
+ */
childp7dcx->cb = p7dcx->cb;
childp7dcx->cb_arg = p7dcx->cb_arg;
@@ -339,12 +347,9 @@ loser:
static SECStatus
nss_cms_after_data(NSSCMSDecoderContext *p7dcx)
{
- PLArenaPool *poolp;
NSSCMSDecoderContext *childp7dcx;
SECStatus rv = SECFailure;
- poolp = p7dcx->cmsg->poolp;
-
/* Handle last block. This is necessary to flush out the last bytes
* of a possibly incomplete block */
nss_cms_decoder_work_data(p7dcx, NULL, 0, PR_TRUE);
@@ -372,13 +377,16 @@ nss_cms_after_data(NSSCMSDecoderContext *p7dcx)
rv = NSS_CMSSignedData_Decode_AfterData(p7dcx->content.signedData);
break;
case SEC_OID_PKCS7_ENVELOPED_DATA:
- rv = NSS_CMSEnvelopedData_Decode_AfterData(p7dcx->content.envelopedData);
+ rv = NSS_CMSEnvelopedData_Decode_AfterData(
+ p7dcx->content.envelopedData);
break;
case SEC_OID_PKCS7_DIGESTED_DATA:
- rv = NSS_CMSDigestedData_Decode_AfterData(p7dcx->content.digestedData);
+ rv = NSS_CMSDigestedData_Decode_AfterData(
+ p7dcx->content.digestedData);
break;
case SEC_OID_PKCS7_ENCRYPTED_DATA:
- rv = NSS_CMSEncryptedData_Decode_AfterData(p7dcx->content.encryptedData);
+ rv = NSS_CMSEncryptedData_Decode_AfterData(
+ p7dcx->content.encryptedData);
break;
case SEC_OID_PKCS7_DATA:
/* do nothing */
@@ -394,26 +402,29 @@ done:
static SECStatus
nss_cms_after_end(NSSCMSDecoderContext *p7dcx)
{
- SECStatus rv;
- PLArenaPool *poolp;
-
- poolp = p7dcx->cmsg->poolp;
+ SECStatus rv = SECSuccess;
switch (p7dcx->type) {
case SEC_OID_PKCS7_SIGNED_DATA:
- rv = NSS_CMSSignedData_Decode_AfterEnd(p7dcx->content.signedData);
+ if (p7dcx->content.signedData)
+ rv = NSS_CMSSignedData_Decode_AfterEnd(p7dcx->content.signedData);
break;
case SEC_OID_PKCS7_ENVELOPED_DATA:
- rv = NSS_CMSEnvelopedData_Decode_AfterEnd(p7dcx->content.envelopedData);
+ if (p7dcx->content.envelopedData)
+ rv = NSS_CMSEnvelopedData_Decode_AfterEnd(
+ p7dcx->content.envelopedData);
break;
case SEC_OID_PKCS7_DIGESTED_DATA:
- rv = NSS_CMSDigestedData_Decode_AfterEnd(p7dcx->content.digestedData);
+ if (p7dcx->content.digestedData)
+ rv = NSS_CMSDigestedData_Decode_AfterEnd(
+ p7dcx->content.digestedData);
break;
case SEC_OID_PKCS7_ENCRYPTED_DATA:
- rv = NSS_CMSEncryptedData_Decode_AfterEnd(p7dcx->content.encryptedData);
+ if (p7dcx->content.encryptedData)
+ rv = NSS_CMSEncryptedData_Decode_AfterEnd(
+ p7dcx->content.encryptedData);
break;
case SEC_OID_PKCS7_DATA:
- rv = SECSuccess;
break;
default:
rv = SECFailure; /* we should not have got that far... */
@@ -518,9 +529,10 @@ nss_cms_decoder_work_data(NSSCMSDecoderContext *p7dcx,
if (cinfo->digcx)
NSS_CMSDigestContext_Update(cinfo->digcx, data, len);
- /* at this point, we have the plain decoded & decrypted data */
- /* which is either more encoded DER which we need to hand to the child decoder */
- /* or data we need to hand back to our caller */
+ /* at this point, we have the plain decoded & decrypted data
+ ** which is either more encoded DER (which we need to hand to the child
+ ** decoder) or data we need to hand back to our caller
+ */
/* pass the content back to our caller or */
/* feed our freshly decrypted and decoded data into child decoder */
@@ -589,7 +601,8 @@ nss_cms_decoder_update_filter (void *arg, const char *data, unsigned long len,
/* pass on the content bytes only */
if (data_kind == SEC_ASN1_Contents)
- nss_cms_decoder_work_data(p7dcx, (const unsigned char *) data, len, PR_FALSE);
+ nss_cms_decoder_work_data(p7dcx, (const unsigned char *) data, len,
+ PR_FALSE);
}
/*
@@ -604,7 +617,8 @@ NSSCMSDecoderContext *
NSS_CMSDecoder_Start(PRArenaPool *poolp,
NSSCMSContentCallback cb, void *cb_arg,
PK11PasswordFunc pwfn, void *pwfn_arg,
- NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg)
+ NSSCMSGetDecryptKeyCallback decrypt_key_cb,
+ void *decrypt_key_cb_arg)
{
NSSCMSDecoderContext *p7dcx;
NSSCMSMessage *cmsg;
@@ -613,10 +627,10 @@ NSS_CMSDecoder_Start(PRArenaPool *poolp,
if (cmsg == NULL)
return NULL;
- NSS_CMSMessage_SetEncodingParams(cmsg, pwfn, pwfn_arg, decrypt_key_cb, decrypt_key_cb_arg,
- NULL, NULL);
+ NSS_CMSMessage_SetEncodingParams(cmsg, pwfn, pwfn_arg, decrypt_key_cb,
+ decrypt_key_cb_arg, NULL, NULL);
- p7dcx = (NSSCMSDecoderContext*)PORT_ZAlloc(sizeof(NSSCMSDecoderContext));
+ p7dcx = PORT_ZNew(NSSCMSDecoderContext);
if (p7dcx == NULL) {
NSS_CMSMessage_Destroy(cmsg);
return NULL;
@@ -644,10 +658,14 @@ NSS_CMSDecoder_Start(PRArenaPool *poolp,
* NSS_CMSDecoder_Update - feed DER-encoded data to decoder
*/
SECStatus
-NSS_CMSDecoder_Update(NSSCMSDecoderContext *p7dcx, const char *buf, unsigned long len)
+NSS_CMSDecoder_Update(NSSCMSDecoderContext *p7dcx, const char *buf,
+ unsigned long len)
{
- if (p7dcx->dcx != NULL && p7dcx->error == 0) { /* if error is set already, don't bother */
- if (SEC_ASN1DecoderUpdate (p7dcx->dcx, buf, len) != SECSuccess) {
+ SECStatus rv;
+ if (p7dcx->dcx != NULL && p7dcx->error == 0) {
+ /* if error is set already, don't bother */
+ rv = SEC_ASN1DecoderUpdate(p7dcx->dcx, buf, len);
+ if (rv != SECSuccess) {
p7dcx->error = PORT_GetError();
PORT_Assert (p7dcx->error);
if (p7dcx->error == 0)
@@ -691,10 +709,11 @@ NSS_CMSDecoder_Finish(NSSCMSDecoderContext *p7dcx)
cmsg = p7dcx->cmsg;
- if (p7dcx->dcx == NULL || SEC_ASN1DecoderFinish(p7dcx->dcx) != SECSuccess ||
+ if (p7dcx->dcx == NULL ||
+ SEC_ASN1DecoderFinish(p7dcx->dcx) != SECSuccess ||
nss_cms_after_end(p7dcx) != SECSuccess)
{
- NSS_CMSMessage_Destroy(cmsg); /* needs to get rid of pool if it's ours */
+ NSS_CMSMessage_Destroy(cmsg); /* get rid of pool if it's ours */
cmsg = NULL;
}
@@ -706,13 +725,15 @@ NSSCMSMessage *
NSS_CMSMessage_CreateFromDER(SECItem *DERmessage,
NSSCMSContentCallback cb, void *cb_arg,
PK11PasswordFunc pwfn, void *pwfn_arg,
- NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg)
+ NSSCMSGetDecryptKeyCallback decrypt_key_cb,
+ void *decrypt_key_cb_arg)
{
NSSCMSDecoderContext *p7dcx;
/* first arg(poolp) == NULL => create our own pool */
- p7dcx = NSS_CMSDecoder_Start(NULL, cb, cb_arg, pwfn, pwfn_arg, decrypt_key_cb, decrypt_key_cb_arg);
- (void) NSS_CMSDecoder_Update(p7dcx, (char *)DERmessage->data, DERmessage->len);
+ p7dcx = NSS_CMSDecoder_Start(NULL, cb, cb_arg, pwfn, pwfn_arg,
+ decrypt_key_cb, decrypt_key_cb_arg);
+ NSS_CMSDecoder_Update(p7dcx, (char *)DERmessage->data, DERmessage->len);
return NSS_CMSDecoder_Finish(p7dcx);
}
diff --git a/security/nss/lib/smime/cmsdigdata.c b/security/nss/lib/smime/cmsdigdata.c
index 9d57a5266..23337446f 100644
--- a/security/nss/lib/smime/cmsdigdata.c
+++ b/security/nss/lib/smime/cmsdigdata.c
@@ -151,15 +151,17 @@ NSS_CMSDigestedData_Encode_BeforeData(NSSCMSDigestedData *digd)
SECStatus
NSS_CMSDigestedData_Encode_AfterData(NSSCMSDigestedData *digd)
{
+ SECStatus rv = SECSuccess;
/* did we have digest calculation going on? */
if (digd->contentInfo.digcx) {
- if (NSS_CMSDigestContext_FinishSingle(digd->contentInfo.digcx,
- digd->cmsg->poolp, &(digd->digest)) != SECSuccess)
- return SECFailure; /* error has been set by NSS_CMSDigestContext_FinishSingle */
+ rv = NSS_CMSDigestContext_FinishSingle(digd->contentInfo.digcx,
+ digd->cmsg->poolp,
+ &(digd->digest));
+ /* error has been set by NSS_CMSDigestContext_FinishSingle */
digd->contentInfo.digcx = NULL;
}
- return SECSuccess;
+ return rv;
}
/*
@@ -193,15 +195,17 @@ NSS_CMSDigestedData_Decode_BeforeData(NSSCMSDigestedData *digd)
SECStatus
NSS_CMSDigestedData_Decode_AfterData(NSSCMSDigestedData *digd)
{
+ SECStatus rv = SECSuccess;
/* did we have digest calculation going on? */
if (digd->contentInfo.digcx) {
- if (NSS_CMSDigestContext_FinishSingle(digd->contentInfo.digcx,
- digd->cmsg->poolp, &(digd->cdigest)) != SECSuccess)
- return SECFailure; /* error has been set by NSS_CMSDigestContext_FinishSingle */
+ rv = NSS_CMSDigestContext_FinishSingle(digd->contentInfo.digcx,
+ digd->cmsg->poolp,
+ &(digd->cdigest));
+ /* error has been set by NSS_CMSDigestContext_FinishSingle */
digd->contentInfo.digcx = NULL;
}
- return SECSuccess;
+ return rv;
}
/*
diff --git a/security/nss/lib/smime/cmsdigest.c b/security/nss/lib/smime/cmsdigest.c
index 6c7bd918b..6acc5127e 100644
--- a/security/nss/lib/smime/cmsdigest.c
+++ b/security/nss/lib/smime/cmsdigest.c
@@ -47,14 +47,26 @@
#include "prtime.h"
#include "secerr.h"
+/* #define CMS_FIND_LEAK_MULTIPLE 1 */
+#ifdef CMS_FIND_LEAK_MULTIPLE
+static int stop_on_err = 1;
+static int global_num_digests = 0;
+#endif
+
+struct digestPairStr {
+ const SECHashObject * digobj;
+ void * digcx;
+};
+typedef struct digestPairStr digestPair;
struct NSSCMSDigestContextStr {
PRBool saw_contents;
+ PLArenaPool * pool;
int digcnt;
- void ** digcxs;
-const SECHashObject ** digobjs;
+ digestPair * digPairs;
};
+
/*
* NSS_CMSDigestContext_StartMultiple - start digest calculation using all the
* digest algorithms in "digestalgs" in parallel.
@@ -62,31 +74,43 @@ const SECHashObject ** digobjs;
NSSCMSDigestContext *
NSS_CMSDigestContext_StartMultiple(SECAlgorithmID **digestalgs)
{
+ PLArenaPool * pool;
NSSCMSDigestContext *cmsdigcx;
- const SECHashObject *digobj;
- void *digcx;
int digcnt;
int i;
- digcnt = (digestalgs == NULL) ? 0 : NSS_CMSArray_Count((void **)digestalgs);
+#ifdef CMS_FIND_LEAK_MULTIPLE
+ PORT_Assert(global_num_digests == 0 || !stop_on_err);
+#endif
- cmsdigcx = (NSSCMSDigestContext *)PORT_Alloc(sizeof(NSSCMSDigestContext));
+ digcnt = (digestalgs == NULL) ? 0 : NSS_CMSArray_Count((void **)digestalgs);
+ /* It's OK if digcnt is zero. We have to allow this for "certs only"
+ ** messages.
+ */
+ pool = PORT_NewArena(2048);
+ if (!pool)
+ return NULL;
+
+ cmsdigcx = PORT_ArenaNew(pool, NSSCMSDigestContext);
if (cmsdigcx == NULL)
- return NULL;
+ goto loser;
- if (digcnt > 0) {
- cmsdigcx->digcxs = (void **)PORT_Alloc(digcnt * sizeof (void *));
- cmsdigcx->digobjs = (const SECHashObject **)PORT_Alloc(digcnt * sizeof(SECHashObject *));
- if (cmsdigcx->digcxs == NULL || cmsdigcx->digobjs == NULL)
- goto loser;
- }
+ cmsdigcx->saw_contents = PR_FALSE;
+ cmsdigcx->pool = pool;
+ cmsdigcx->digcnt = digcnt;
- cmsdigcx->digcnt = 0;
+ cmsdigcx->digPairs = PORT_ArenaZNewArray(pool, digestPair, digcnt);
+ if (cmsdigcx->digPairs == NULL) {
+ goto loser;
+ }
/*
* Create a digest object context for each algorithm.
*/
for (i = 0; i < digcnt; i++) {
+ const SECHashObject *digobj;
+ void *digcx;
+
digobj = NSS_CMSUtil_GetHashObjByAlgID(digestalgs[i]);
/*
* Skip any algorithm we do not even recognize; obviously,
@@ -102,29 +126,26 @@ NSS_CMSDigestContext_StartMultiple(SECAlgorithmID **digestalgs)
digcx = (*digobj->create)();
if (digcx != NULL) {
(*digobj->begin) (digcx);
- cmsdigcx->digobjs[cmsdigcx->digcnt] = digobj;
- cmsdigcx->digcxs[cmsdigcx->digcnt] = digcx;
- cmsdigcx->digcnt++;
+ cmsdigcx->digPairs[i].digobj = digobj;
+ cmsdigcx->digPairs[i].digcx = digcx;
+#ifdef CMS_FIND_LEAK_MULTIPLE
+ global_num_digests++;
+#endif
}
}
-
- cmsdigcx->saw_contents = PR_FALSE;
-
return cmsdigcx;
loser:
- if (cmsdigcx) {
- if (cmsdigcx->digobjs)
- PORT_Free(cmsdigcx->digobjs);
- if (cmsdigcx->digcxs)
- PORT_Free(cmsdigcx->digcxs);
+ /* no digest objects have been created, or need to be destroyed. */
+ if (pool) {
+ PORT_FreeArena(pool, PR_FALSE);
}
return NULL;
}
/*
- * NSS_CMSDigestContext_StartSingle - same as NSS_CMSDigestContext_StartMultiple, but
- * only one algorithm.
+ * NSS_CMSDigestContext_StartSingle - same as
+ * NSS_CMSDigestContext_StartMultiple, but only one algorithm.
*/
NSSCMSDigestContext *
NSS_CMSDigestContext_StartSingle(SECAlgorithmID *digestalg)
@@ -139,14 +160,19 @@ NSS_CMSDigestContext_StartSingle(SECAlgorithmID *digestalg)
* NSS_CMSDigestContext_Update - feed more data into the digest machine
*/
void
-NSS_CMSDigestContext_Update(NSSCMSDigestContext *cmsdigcx, const unsigned char *data, int len)
+NSS_CMSDigestContext_Update(NSSCMSDigestContext *cmsdigcx,
+ const unsigned char *data, int len)
{
int i;
+ digestPair *pair = cmsdigcx->digPairs;
cmsdigcx->saw_contents = PR_TRUE;
- for (i = 0; i < cmsdigcx->digcnt; i++)
- (*cmsdigcx->digobjs[i]->update)(cmsdigcx->digcxs[i], data, len);
+ for (i = 0; i < cmsdigcx->digcnt; i++, pair++) {
+ if (pair->digcx) {
+ (*pair->digobj->update)(pair->digcx, data, len);
+ }
+ }
}
/*
@@ -156,9 +182,20 @@ void
NSS_CMSDigestContext_Cancel(NSSCMSDigestContext *cmsdigcx)
{
int i;
-
- for (i = 0; i < cmsdigcx->digcnt; i++)
- (*cmsdigcx->digobjs[i]->destroy)(cmsdigcx->digcxs[i], PR_TRUE);
+ digestPair *pair = cmsdigcx->digPairs;
+
+ for (i = 0; i < cmsdigcx->digcnt; i++, pair++) {
+ if (pair->digcx) {
+ (*pair->digobj->destroy)(pair->digcx, PR_TRUE);
+#ifdef CMS_FIND_LEAK_MULTIPLE
+ --global_num_digests;
+#endif
+ }
+ }
+#ifdef CMS_FIND_LEAK_MULTIPLE
+ PORT_Assert(global_num_digests == 0 || !stop_on_err);
+#endif
+ PORT_FreeArena(cmsdigcx->pool, PR_FALSE);
}
/*
@@ -166,20 +203,18 @@ NSS_CMSDigestContext_Cancel(NSSCMSDigestContext *cmsdigcx)
* into an array of SECItems (allocated on poolp)
*/
SECStatus
-NSS_CMSDigestContext_FinishMultiple(NSSCMSDigestContext *cmsdigcx, PLArenaPool *poolp,
- SECItem ***digestsp)
+NSS_CMSDigestContext_FinishMultiple(NSSCMSDigestContext *cmsdigcx,
+ PLArenaPool *poolp,
+ SECItem ***digestsp)
{
- const SECHashObject *digobj;
- void *digcx;
- SECItem **digests, *digest;
- int i;
- void *mark;
- SECStatus rv = SECFailure;
+ SECItem ** digests = NULL;
+ digestPair *pair;
+ void * mark;
+ int i;
+ SECStatus rv;
- /* no contents? do not update digests */
+ /* no contents? do not finish digests */
if (digestsp == NULL || !cmsdigcx->saw_contents) {
- for (i = 0; i < cmsdigcx->digcnt; i++)
- (*cmsdigcx->digobjs[i]->destroy)(cmsdigcx->digcxs[i], PR_TRUE);
rv = SECSuccess;
goto cleanup;
}
@@ -187,52 +222,53 @@ NSS_CMSDigestContext_FinishMultiple(NSSCMSDigestContext *cmsdigcx, PLArenaPool *
mark = PORT_ArenaMark (poolp);
/* allocate digest array & SECItems on arena */
- digests = (SECItem **)PORT_ArenaAlloc(poolp, (cmsdigcx->digcnt+1) * sizeof(SECItem *));
- digest = (SECItem *)PORT_ArenaZAlloc(poolp, cmsdigcx->digcnt * sizeof(SECItem));
- if (digests == NULL || digest == NULL) {
- goto loser;
- }
+ digests = PORT_ArenaNewArray( poolp, SECItem *, cmsdigcx->digcnt + 1);
- for (i = 0; i < cmsdigcx->digcnt; i++, digest++) {
- digcx = cmsdigcx->digcxs[i];
- digobj = cmsdigcx->digobjs[i];
-
- digest->data = (unsigned char*)PORT_ArenaAlloc(poolp, digobj->length);
- if (digest->data == NULL)
- goto loser;
- digest->len = digobj->length;
- (* digobj->end)(digcx, digest->data, &(digest->len), digest->len);
- digests[i] = digest;
- (* digobj->destroy)(digcx, PR_TRUE);
- }
- digests[i] = NULL;
- *digestsp = digests;
+ rv = ((digests == NULL) ? SECFailure : SECSuccess);
+ pair = cmsdigcx->digPairs;
+ for (i = 0; rv == SECSuccess && i < cmsdigcx->digcnt; i++, pair++) {
+ SECItem digest;
+ unsigned char hash[HASH_LENGTH_MAX];
- rv = SECSuccess;
+ if (!pair->digcx) {
+ digests[i] = NULL;
+ continue;
+ }
-loser:
- if (rv == SECSuccess)
+ digest.type = siBuffer;
+ digest.data = hash;
+ digest.len = pair->digobj->length;
+ (* pair->digobj->end)(pair->digcx, hash, &digest.len, digest.len);
+ digests[i] = SECITEM_ArenaDupItem(poolp, &digest);
+ if (!digests[i]) {
+ rv = SECFailure;
+ }
+ }
+ digests[i] = NULL;
+ if (rv == SECSuccess) {
PORT_ArenaUnmark(poolp, mark);
- else
+ } else
PORT_ArenaRelease(poolp, mark);
cleanup:
- if (cmsdigcx->digcnt > 0) {
- PORT_Free(cmsdigcx->digcxs);
- PORT_Free(cmsdigcx->digobjs);
+ NSS_CMSDigestContext_Cancel(cmsdigcx);
+ /* Don't change the caller's digests pointer if we have no digests.
+ ** NSS_CMSSignedData_Encode_AfterData depends on this behavior.
+ */
+ if (rv == SECSuccess && digestsp && digests) {
+ *digestsp = digests;
}
- PORT_Free(cmsdigcx);
-
return rv;
}
/*
- * NSS_CMSDigestContext_FinishSingle - same as NSS_CMSDigestContext_FinishMultiple,
- * but for one digest.
+ * NSS_CMSDigestContext_FinishSingle - same as
+ * NSS_CMSDigestContext_FinishMultiple, but for one digest.
*/
SECStatus
-NSS_CMSDigestContext_FinishSingle(NSSCMSDigestContext *cmsdigcx, PLArenaPool *poolp,
- SECItem *digest)
+NSS_CMSDigestContext_FinishSingle(NSSCMSDigestContext *cmsdigcx,
+ PLArenaPool *poolp,
+ SECItem *digest)
{
SECStatus rv = SECFailure;
SECItem **dp;
@@ -242,15 +278,11 @@ NSS_CMSDigestContext_FinishSingle(NSSCMSDigestContext *cmsdigcx, PLArenaPool *po
goto loser;
/* get the digests into arena, then copy the first digest into poolp */
- if (NSS_CMSDigestContext_FinishMultiple(cmsdigcx, arena, &dp) != SECSuccess)
- goto loser;
-
- /* now copy it into poolp */
- if (SECITEM_CopyItem(poolp, digest, dp[0]) != SECSuccess)
- goto loser;
-
- rv = SECSuccess;
-
+ rv = NSS_CMSDigestContext_FinishMultiple(cmsdigcx, arena, &dp);
+ if (rv == SECSuccess) {
+ /* now copy it into poolp */
+ rv = SECITEM_CopyItem(poolp, digest, dp[0]);
+ }
loser:
if (arena)
PORT_FreeArena(arena, PR_FALSE);
diff --git a/security/nss/lib/smime/cmsenvdata.c b/security/nss/lib/smime/cmsenvdata.c
index 111ada533..de1420fbf 100644
--- a/security/nss/lib/smime/cmsenvdata.c
+++ b/security/nss/lib/smime/cmsenvdata.c
@@ -360,7 +360,11 @@ NSS_CMSEnvelopedData_Decode_BeforeData(NSSCMSEnvelopedData *envd)
cinfo = &(envd->contentInfo);
bulkalgtag = NSS_CMSContentInfo_GetContentEncAlgTag(cinfo);
- bulkkey = NSS_CMSRecipientInfo_UnwrapBulkKey(ri,recipient->subIndex,
+ if (bulkalgtag == SEC_OID_UNKNOWN) {
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+ } else
+ bulkkey =
+ NSS_CMSRecipientInfo_UnwrapBulkKey(ri,recipient->subIndex,
recipient->cert,
recipient->privkey,
bulkalgtag);
@@ -404,7 +408,7 @@ loser:
SECStatus
NSS_CMSEnvelopedData_Decode_AfterData(NSSCMSEnvelopedData *envd)
{
- if (envd->contentInfo.ciphcx) {
+ if (envd && envd->contentInfo.ciphcx) {
NSS_CMSCipherContext_Destroy(envd->contentInfo.ciphcx);
envd->contentInfo.ciphcx = NULL;
}
diff --git a/security/nss/lib/smime/cmsmessage.c b/security/nss/lib/smime/cmsmessage.c
index 7e785cc1f..c9b076af2 100644
--- a/security/nss/lib/smime/cmsmessage.c
+++ b/security/nss/lib/smime/cmsmessage.c
@@ -178,7 +178,9 @@ SECItem *
NSS_CMSMessage_GetContent(NSSCMSMessage *cmsg)
{
/* this is a shortcut */
- return NSS_CMSContentInfo_GetInnerContent(NSS_CMSMessage_GetContentInfo(cmsg));
+ NSSCMSContentInfo * cinfo = NSS_CMSMessage_GetContentInfo(cmsg);
+ SECItem * pItem = NSS_CMSContentInfo_GetInnerContent(cinfo);
+ return pItem;
}
/*
diff --git a/security/nss/lib/smime/cmspubkey.c b/security/nss/lib/smime/cmspubkey.c
index 1cf0336e4..10eee8155 100644
--- a/security/nss/lib/smime/cmspubkey.c
+++ b/security/nss/lib/smime/cmspubkey.c
@@ -128,7 +128,14 @@ PK11SymKey *
NSS_CMSUtil_DecryptSymKey_RSA(SECKEYPrivateKey *privkey, SECItem *encKey, SECOidTag bulkalgtag)
{
/* that's easy */
- return PK11_PubUnwrapSymKey(privkey, encKey, PK11_AlgtagToMechanism(bulkalgtag), CKA_DECRYPT, 0);
+ CK_MECHANISM_TYPE target;
+ PORT_Assert(bulkalgtag != SEC_OID_UNKNOWN);
+ target = PK11_AlgtagToMechanism(bulkalgtag);
+ if (bulkalgtag == SEC_OID_UNKNOWN || target == CKM_INVALID_MECHANISM) {
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+ return NULL;
+ }
+ return PK11_PubUnwrapSymKey(privkey, encKey, target, CKA_DECRYPT, 0);
}
/* ====== MISSI (Fortezza) ========================================================== */
diff --git a/security/nss/lib/smime/cmssigdata.c b/security/nss/lib/smime/cmssigdata.c
index 98a8fcbc5..573663b9c 100644
--- a/security/nss/lib/smime/cmssigdata.c
+++ b/security/nss/lib/smime/cmssigdata.c
@@ -54,6 +54,11 @@ NSS_CMSSignedData_Create(NSSCMSMessage *cmsg)
NSSCMSSignedData *sigd;
PLArenaPool *poolp;
+ if (!cmsg) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
+ }
+
poolp = cmsg->poolp;
mark = PORT_ArenaMark(poolp);
@@ -132,6 +137,11 @@ NSS_CMSSignedData_Encode_BeforeStart(NSSCMSSignedData *sigd)
int n, i;
PLArenaPool *poolp;
+ if (!sigd) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
poolp = sigd->cmsg->poolp;
/* we assume that we have precomputed digests if there is a list of algorithms, and */
@@ -198,9 +208,16 @@ loser:
SECStatus
NSS_CMSSignedData_Encode_BeforeData(NSSCMSSignedData *sigd)
{
+ if (!sigd) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
/* set up the digests */
- if (sigd->digestAlgorithms != NULL) {
- sigd->contentInfo.digcx = NSS_CMSDigestContext_StartMultiple(sigd->digestAlgorithms);
+ if (sigd->digests && sigd->digests[0]) {
+ sigd->contentInfo.digcx = NULL; /* don't attempt to make new ones. */
+ } else if (sigd->digestAlgorithms != NULL) {
+ sigd->contentInfo.digcx =
+ NSS_CMSDigestContext_StartMultiple(sigd->digestAlgorithms);
if (sigd->contentInfo.digcx == NULL)
return SECFailure;
}
@@ -232,15 +249,22 @@ NSS_CMSSignedData_Encode_AfterData(NSSCMSSignedData *sigd)
CERTCertificateList *certlist;
extern const SEC_ASN1Template NSSCMSSignerInfoTemplate[];
+ if (!sigd) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
poolp = sigd->cmsg->poolp;
cinfo = &(sigd->contentInfo);
/* did we have digest calculation going on? */
if (cinfo->digcx) {
- rv = NSS_CMSDigestContext_FinishMultiple(cinfo->digcx, poolp, &(sigd->digests));
- if (rv != SECSuccess)
- goto loser; /* error has been set by NSS_CMSDigestContext_FinishMultiple */
+ rv = NSS_CMSDigestContext_FinishMultiple(cinfo->digcx, poolp,
+ &(sigd->digests));
+ /* error has been set by NSS_CMSDigestContext_FinishMultiple */
cinfo->digcx = NULL;
+ if (rv != SECSuccess)
+ goto loser;
}
signerinfos = sigd->signerInfos;
@@ -359,6 +383,10 @@ loser:
SECStatus
NSS_CMSSignedData_Decode_BeforeData(NSSCMSSignedData *sigd)
{
+ if (!sigd) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
/* set up the digests */
if (sigd->digestAlgorithms != NULL && sigd->digests == NULL) {
/* if digests are already there, do nothing */
@@ -370,19 +398,27 @@ NSS_CMSSignedData_Decode_BeforeData(NSSCMSSignedData *sigd)
}
/*
- * NSS_CMSSignedData_Decode_AfterData - do all the necessary things to a SignedData
- * after all the encapsulated data was passed through the decoder.
+ * NSS_CMSSignedData_Decode_AfterData - do all the necessary things to a
+ * SignedData after all the encapsulated data was passed through the decoder.
*/
SECStatus
NSS_CMSSignedData_Decode_AfterData(NSSCMSSignedData *sigd)
{
+ SECStatus rv = SECSuccess;
+
+ if (!sigd) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
/* did we have digest calculation going on? */
if (sigd->contentInfo.digcx) {
- if (NSS_CMSDigestContext_FinishMultiple(sigd->contentInfo.digcx, sigd->cmsg->poolp, &(sigd->digests)) != SECSuccess)
- return SECFailure; /* error has been set by NSS_CMSDigestContext_FinishMultiple */
+ rv = NSS_CMSDigestContext_FinishMultiple(sigd->contentInfo.digcx,
+ sigd->cmsg->poolp, &(sigd->digests));
+ /* error set by NSS_CMSDigestContext_FinishMultiple */
sigd->contentInfo.digcx = NULL;
}
- return SECSuccess;
+ return rv;
}
/*
@@ -392,9 +428,14 @@ NSS_CMSSignedData_Decode_AfterData(NSSCMSSignedData *sigd)
SECStatus
NSS_CMSSignedData_Decode_AfterEnd(NSSCMSSignedData *sigd)
{
- NSSCMSSignerInfo **signerinfos;
+ NSSCMSSignerInfo **signerinfos = NULL;
int i;
+ if (!sigd) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
/* set cmsg for all the signerinfos */
signerinfos = sigd->signerInfos;
@@ -413,18 +454,30 @@ NSS_CMSSignedData_Decode_AfterEnd(NSSCMSSignedData *sigd)
NSSCMSSignerInfo **
NSS_CMSSignedData_GetSignerInfos(NSSCMSSignedData *sigd)
{
+ if (!sigd) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
+ }
return sigd->signerInfos;
}
int
NSS_CMSSignedData_SignerInfoCount(NSSCMSSignedData *sigd)
{
+ if (!sigd) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return 0;
+ }
return NSS_CMSArray_Count((void **)sigd->signerInfos);
}
NSSCMSSignerInfo *
NSS_CMSSignedData_GetSignerInfo(NSSCMSSignedData *sigd, int i)
{
+ if (!sigd) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
+ }
return sigd->signerInfos[i];
}
@@ -434,6 +487,10 @@ NSS_CMSSignedData_GetSignerInfo(NSSCMSSignedData *sigd, int i)
SECAlgorithmID **
NSS_CMSSignedData_GetDigestAlgs(NSSCMSSignedData *sigd)
{
+ if (!sigd) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
+ }
return sigd->digestAlgorithms;
}
@@ -443,6 +500,10 @@ NSS_CMSSignedData_GetDigestAlgs(NSSCMSSignedData *sigd)
NSSCMSContentInfo *
NSS_CMSSignedData_GetContentInfo(NSSCMSSignedData *sigd)
{
+ if (!sigd) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
+ }
return &(sigd->contentInfo);
}
@@ -452,6 +513,10 @@ NSS_CMSSignedData_GetContentInfo(NSSCMSSignedData *sigd)
SECItem **
NSS_CMSSignedData_GetCertificateList(NSSCMSSignedData *sigd)
{
+ if (!sigd) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
+ }
return sigd->rawCerts;
}
@@ -468,6 +533,11 @@ NSS_CMSSignedData_ImportCerts(NSSCMSSignedData *sigd, CERTCertDBHandle *certdb,
int i;
PRTime now;
+ if (!sigd) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
certcount = NSS_CMSArray_Count((void **)sigd->rawCerts);
/* get the certs in the temp DB */
@@ -584,22 +654,34 @@ NSS_CMSSignedData_VerifySignerInfo(NSSCMSSignedData *sigd, int i,
NSSCMSContentInfo *cinfo;
SECOidData *algiddata;
SECItem *contentType, *digest;
+ SECOidTag oidTag;
+ SECStatus rv;
+
+ if (!sigd) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
cinfo = &(sigd->contentInfo);
signerinfo = sigd->signerInfos[i];
/* verify certificate */
- if (NSS_CMSSignerInfo_VerifyCertificate(signerinfo, certdb, certusage) != SECSuccess)
- return SECFailure; /* error is set by NSS_CMSSignerInfo_VerifyCertificate */
+ rv = NSS_CMSSignerInfo_VerifyCertificate(signerinfo, certdb, certusage);
+ if (rv != SECSuccess)
+ return rv; /* error is set */
/* find digest and contentType for signerinfo */
algiddata = NSS_CMSSignerInfo_GetDigestAlg(signerinfo);
- digest = NSS_CMSSignedData_GetDigestByAlgTag(sigd, algiddata->offset);
+ oidTag = algiddata ? algiddata->offset : SEC_OID_UNKNOWN;
+ digest = NSS_CMSSignedData_GetDigestValue(sigd, oidTag);
+ /* NULL digest is acceptable. */
contentType = NSS_CMSContentInfo_GetContentTypeOID(cinfo);
+ /* NULL contentType is acceptable. */
/* now verify signature */
- return NSS_CMSSignerInfo_Verify(signerinfo, digest, contentType);
+ rv = NSS_CMSSignerInfo_Verify(signerinfo, digest, contentType);
+ return rv;
}
/*
@@ -647,6 +729,10 @@ NSS_CMSSignedData_VerifyCertsOnly(NSSCMSSignedData *sigd,
PRBool
NSS_CMSSignedData_HasDigests(NSSCMSSignedData *sigd)
{
+ if (!sigd) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return PR_FALSE;
+ }
return (sigd->digests != NULL);
}
@@ -655,10 +741,10 @@ NSS_CMSSignedData_AddCertList(NSSCMSSignedData *sigd, CERTCertificateList *certl
{
SECStatus rv;
- PORT_Assert(certlist != NULL);
-
- if (certlist == NULL)
- return SECFailure;
+ if (!sigd || !certlist) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
/* XXX memory?? a certlist has an arena of its own and is not refcounted!?!? */
rv = NSS_CMSArray_Add(sigd->cmsg->poolp, (void ***)&(sigd->certLists), (void *)certlist);
@@ -678,6 +764,11 @@ NSS_CMSSignedData_AddCertChain(NSSCMSSignedData *sigd, CERTCertificate *cert)
usage = certUsageEmailSigner;
+ if (!sigd || !cert) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
/* do not include root */
certlist = CERT_CertChainFromCert(cert, usage, PR_FALSE);
if (certlist == NULL)
@@ -694,10 +785,10 @@ NSS_CMSSignedData_AddCertificate(NSSCMSSignedData *sigd, CERTCertificate *cert)
CERTCertificate *c;
SECStatus rv;
- PORT_Assert(cert != NULL);
-
- if (cert == NULL)
- return SECFailure;
+ if (!sigd || !cert) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
c = CERT_DupCertificate(cert);
rv = NSS_CMSArray_Add(sigd->cmsg->poolp, (void ***)&(sigd->certs), (void *)c);
@@ -707,6 +798,10 @@ NSS_CMSSignedData_AddCertificate(NSSCMSSignedData *sigd, CERTCertificate *cert)
PRBool
NSS_CMSSignedData_ContainsCertsOrCrls(NSSCMSSignedData *sigd)
{
+ if (!sigd) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return PR_FALSE;
+ }
if (sigd->rawCerts != NULL && sigd->rawCerts[0] != NULL)
return PR_TRUE;
else if (sigd->crls != NULL && sigd->crls[0] != NULL)
@@ -724,6 +819,11 @@ NSS_CMSSignedData_AddSignerInfo(NSSCMSSignedData *sigd,
SECOidTag digestalgtag;
PLArenaPool *poolp;
+ if (!sigd || !signerinfo) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
poolp = sigd->cmsg->poolp;
mark = PORT_ArenaMark(poolp);
@@ -756,15 +856,6 @@ loser:
return SECFailure;
}
-SECItem *
-NSS_CMSSignedData_GetDigestByAlgTag(NSSCMSSignedData *sigd, SECOidTag algtag)
-{
- int idx;
-
- idx = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, algtag);
- return sigd->digests[idx];
-}
-
/*
* NSS_CMSSignedData_SetDigests - set a signedData's digests member
*
@@ -778,6 +869,11 @@ NSS_CMSSignedData_SetDigests(NSSCMSSignedData *sigd,
{
int cnt, i, idx;
+ if (!sigd || !digestalgs || !digests) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
if (sigd->digestAlgorithms == NULL) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
@@ -805,6 +901,13 @@ NSS_CMSSignedData_SetDigests(NSSCMSSignedData *sigd,
PORT_SetError(SEC_ERROR_DIGEST_NOT_FOUND);
return SECFailure;
}
+ if (!digests[idx]) {
+ /* We have no digest for this algorithm, probably because it is
+ ** unrecognized or unsupported. We'll ignore this here. If this
+ ** digest is needed later, an error will be be generated then.
+ */
+ continue;
+ }
/* found it - now set it */
if ((sigd->digests[i] = SECITEM_AllocItem(sigd->cmsg->poolp, NULL, 0)) == NULL ||
@@ -827,6 +930,11 @@ NSS_CMSSignedData_SetDigestValue(NSSCMSSignedData *sigd,
void *mark;
int n, cnt;
+ if (!sigd) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
poolp = sigd->cmsg->poolp;
mark = PORT_ArenaMark(poolp);
@@ -880,6 +988,11 @@ NSS_CMSSignedData_AddDigest(PRArenaPool *poolp,
SECAlgorithmID *digestalg;
void *mark;
+ if (!sigd || !poolp) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
mark = PORT_ArenaMark(poolp);
digestalg = PORT_ArenaZAlloc(poolp, sizeof(SECAlgorithmID));
@@ -904,13 +1017,21 @@ loser:
return SECFailure;
}
+/* XXX This function doesn't set the error code on failure. */
SECItem *
NSS_CMSSignedData_GetDigestValue(NSSCMSSignedData *sigd, SECOidTag digestalgtag)
{
int n;
- if (sigd->digestAlgorithms == NULL)
+ if (!sigd) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
+ }
+
+ if (sigd->digestAlgorithms == NULL || sigd->digests == NULL) {
+ PORT_SetError(SEC_ERROR_DIGEST_NOT_FOUND);
return NULL;
+ }
n = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag);
@@ -941,6 +1062,11 @@ NSS_CMSSignedData_CreateCertsOnly(NSSCMSMessage *cmsg, CERTCertificate *cert, PR
PLArenaPool *poolp;
SECStatus rv;
+ if (!cmsg || !cert) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
+ }
+
poolp = cmsg->poolp;
mark = PORT_ArenaMark(poolp);
diff --git a/security/nss/lib/smime/cmssiginfo.c b/security/nss/lib/smime/cmssiginfo.c
index 89b942222..bcd6839d7 100644
--- a/security/nss/lib/smime/cmssiginfo.c
+++ b/security/nss/lib/smime/cmssiginfo.c
@@ -309,7 +309,7 @@ NSS_CMSSignerInfo_VerifyCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDBHand
* email profile.
*/
if (NSS_CMSSignerInfo_GetSigningTime (signerinfo, &stime) != SECSuccess)
- stime = PR_Now(); /* not found or conversion failed, so check against now */
+ stime = PR_Now(); /* not found or conversion failed, so check against now */
/*
* XXX This uses the signing time, if available. Additionally, we
@@ -319,7 +319,8 @@ NSS_CMSSignerInfo_VerifyCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDBHand
* in a time (and for non-S/MIME callers to pass in nothing, or
* maybe make them pass in the current time, always?).
*/
- if (CERT_VerifyCert(certdb, cert, PR_TRUE, certusage, stime, signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {
+ if (CERT_VerifyCert(certdb, cert, PR_TRUE, certusage, stime,
+ signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {
signerinfo->verificationStatus = NSSCMSVS_SigningCertNotTrusted;
return SECFailure;
}
@@ -329,11 +330,13 @@ NSS_CMSSignerInfo_VerifyCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDBHand
/*
* NSS_CMSSignerInfo_Verify - verify the signature of a single SignerInfo
*
- * Just verifies the signature. The assumption is that verification of the certificate
- * is done already.
+ * Just verifies the signature. The assumption is that verification of
+ * the certificate is done already.
*/
SECStatus
-NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo, SECItem *digest, SECItem *contentType)
+NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo,
+ SECItem *digest, /* may be NULL */
+ SECItem *contentType) /* may be NULL */
{
SECKEYPublicKey *publickey = NULL;
NSSCMSAttribute *attr;
@@ -345,9 +348,11 @@ NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo, SECItem *digest, SECItem
if (signerinfo == NULL)
return SECFailure;
- /* NSS_CMSSignerInfo_GetSigningCertificate will fail if 2nd parm is NULL and */
- /* cert has not been verified */
- if ((cert = NSS_CMSSignerInfo_GetSigningCertificate(signerinfo, NULL)) == NULL) {
+ /* NSS_CMSSignerInfo_GetSigningCertificate will fail if 2nd parm is NULL
+ ** and cert has not been verified
+ */
+ cert = NSS_CMSSignerInfo_GetSigningCertificate(signerinfo, NULL);
+ if (cert == NULL) {
vs = NSSCMSVS_SigningCertNotFound;
goto loser;
}
@@ -390,9 +395,9 @@ NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo, SECItem *digest, SECItem
* be one for message digest which matches our message digest.
* So check these things first.
*/
- if ((attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,
- SEC_OID_PKCS9_CONTENT_TYPE, PR_TRUE)) == NULL)
- {
+ attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,
+ SEC_OID_PKCS9_CONTENT_TYPE, PR_TRUE);
+ if (attr == NULL) {
vs = NSSCMSVS_MalformedSignature;
goto loser;
}
@@ -406,12 +411,14 @@ NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo, SECItem *digest, SECItem
/*
* Check digest
*/
- if ((attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr, SEC_OID_PKCS9_MESSAGE_DIGEST, PR_TRUE)) == NULL)
- {
+ attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,
+ SEC_OID_PKCS9_MESSAGE_DIGEST, PR_TRUE);
+ if (attr == NULL) {
vs = NSSCMSVS_MalformedSignature;
goto loser;
}
- if (NSS_CMSAttribute_CompareValue(attr, digest) == PR_FALSE) {
+ if (!digest ||
+ NSS_CMSAttribute_CompareValue(attr, digest) == PR_FALSE) {
vs = NSSCMSVS_DigestMismatch;
goto loser;
}
@@ -426,14 +433,15 @@ NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo, SECItem *digest, SECItem
*
* The signature is based on a digest of the DER-encoded authenticated
* attributes. So, first we encode and then we digest/verify.
- * we trust the decoder to have the attributes in the right (sorted) order
+ * we trust the decoder to have the attributes in the right (sorted)
+ * order
*/
encoded_attrs.data = NULL;
encoded_attrs.len = 0;
- if (NSS_CMSAttributeArray_Encode(poolp, &(signerinfo->authAttr), &encoded_attrs) == NULL ||
- encoded_attrs.data == NULL || encoded_attrs.len == 0)
- {
+ if (NSS_CMSAttributeArray_Encode(poolp, &(signerinfo->authAttr),
+ &encoded_attrs) == NULL ||
+ encoded_attrs.data == NULL || encoded_attrs.len == 0) {
vs = NSSCMSVS_ProcessingError;
goto loser;
}
@@ -441,21 +449,26 @@ NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo, SECItem *digest, SECItem
vs = (VFY_VerifyData (encoded_attrs.data, encoded_attrs.len,
publickey, &(signerinfo->encDigest),
SECOID_GetAlgorithmTag(&(signerinfo->digestEncAlg)),
- signerinfo->cmsg->pwfn_arg) != SECSuccess) ? NSSCMSVS_BadSignature : NSSCMSVS_GoodSignature;
+ signerinfo->cmsg->pwfn_arg) != SECSuccess)
+ ? NSSCMSVS_BadSignature : NSSCMSVS_GoodSignature;
- PORT_FreeArena(poolp, PR_FALSE); /* awkward memory management :-( */
+ PORT_FreeArena(poolp, PR_FALSE); /* awkward memory management :-( */
} else {
SECItem *sig;
- /* No authenticated attributes. The signature is based on the plain message digest. */
+ /* No authenticated attributes.
+ ** The signature is based on the plain message digest.
+ */
sig = &(signerinfo->encDigest);
if (sig->len == 0)
goto loser;
- vs = (VFY_VerifyDigest(digest, publickey, sig,
+ vs = (!digest ||
+ VFY_VerifyDigest(digest, publickey, sig,
SECOID_GetAlgorithmTag(&(signerinfo->digestEncAlg)),
- signerinfo->cmsg->pwfn_arg) != SECSuccess) ? NSSCMSVS_BadSignature : NSSCMSVS_GoodSignature;
+ signerinfo->cmsg->pwfn_arg) != SECSuccess)
+ ? NSSCMSVS_BadSignature : NSSCMSVS_GoodSignature;
}
if (vs == NSSCMSVS_BadSignature) {
@@ -513,6 +526,11 @@ NSS_CMSSignerInfo_GetDigestAlgTag(NSSCMSSignerInfo *signerinfo)
{
SECOidData *algdata;
+ if (!signerinfo) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SEC_OID_UNKNOWN;
+ }
+
algdata = SECOID_FindOID (&(signerinfo->digestAlg.algorithm));
if (algdata != NULL)
return algdata->offset;
@@ -566,7 +584,7 @@ NSS_CMSSignerInfo_GetSigningTime(NSSCMSSignerInfo *sinfo, PRTime *stime)
/* XXXX multi-valued attributes NIH */
if (attr == NULL || (value = NSS_CMSAttribute_GetValue(attr)) == NULL)
return SECFailure;
- if (CERT_DecodeTimeChoice(stime, value) != SECSuccess)
+ if (DER_DecodeTimeChoice(stime, value) != SECSuccess)
return SECFailure;
sinfo->signingTime = *stime; /* make cached copy */
return SECSuccess;
@@ -620,7 +638,7 @@ NSS_CMSSignerInfo_GetSigningCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDB
*
* sinfo - signerInfo data for this signer
*
- * Returns a pointer to allocated memory, which must be freed.
+ * Returns a pointer to allocated memory, which must be freed with PORT_Free.
* A return value of NULL is an error.
*/
char *
@@ -703,7 +721,7 @@ NSS_CMSSignerInfo_AddSigningTime(NSSCMSSignerInfo *signerinfo, PRTime t)
mark = PORT_ArenaMark(poolp);
/* create new signing time attribute */
- if (CERT_EncodeTimeChoice(NULL, &stime, t) != SECSuccess)
+ if (DER_EncodeTimeChoice(NULL, &stime, t) != SECSuccess)
goto loser;
if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_PKCS9_SIGNING_TIME, &stime, PR_FALSE)) == NULL) {
diff --git a/security/nss/lib/softoken/keydb.c b/security/nss/lib/softoken/keydb.c
index 92ea37d25..f02c3de80 100644
--- a/security/nss/lib/softoken/keydb.c
+++ b/security/nss/lib/softoken/keydb.c
@@ -52,6 +52,7 @@
#include "lowpbe.h"
#include "secerr.h"
#include "cdbhdl.h"
+#include "nsslocks.h"
#include "keydbi.h"
@@ -163,6 +164,36 @@ free_dbt(DBT *dbt)
return;
}
+static int keydb_Get(DB *db, DBT *key, DBT *data, unsigned int flags);
+static int keydb_Put(DB *db, DBT *key, DBT *data, unsigned int flags);
+static int keydb_Sync(DB *db, unsigned int flags);
+static int keydb_Del(DB *db, DBT *key, unsigned int flags);
+static int keydb_Seq(DB *db, DBT *key, DBT *data, unsigned int flags);
+static void keydb_Close(DB *db);
+
+static PZLock *kdbLock = NULL;
+
+static void
+keydb_InitLocks(NSSLOWKEYDBHandle *handle)
+{
+ if (kdbLock == NULL) {
+ nss_InitLock(&kdbLock, nssILockKeyDB);
+ }
+
+ return;
+}
+
+static void
+keydb_DestroyLocks(NSSLOWKEYDBHandle *handle)
+{
+ if (kdbLock != NULL) {
+ PZ_DestroyLock(kdbLock);
+ kdbLock = NULL;
+ }
+
+ return;
+}
+
/*
* format of key database entries for version 3 of database:
* byte offset field
@@ -320,7 +351,7 @@ get_dbkey(NSSLOWKEYDBHandle *handle, DBT *index)
int ret;
/* get it from the database */
- ret = (* handle->db->get)(handle->db, index, &entry, 0);
+ ret = keydb_Get(handle->db, index, &entry, 0);
if ( ret ) {
PORT_SetError(SEC_ERROR_BAD_DATABASE);
return NULL;
@@ -346,10 +377,9 @@ put_dbkey(NSSLOWKEYDBHandle *handle, DBT *index, NSSLOWKEYDBKey *dbkey, PRBool u
/* put it in the database */
if ( update ) {
- status = (* handle->db->put)(handle->db, index, keydata, 0);
+ status = keydb_Put(handle->db, index, keydata, 0);
} else {
- status = (* handle->db->put)(handle->db, index, keydata,
- R_NOOVERWRITE);
+ status = keydb_Put(handle->db, index, keydata, R_NOOVERWRITE);
}
if ( status ) {
@@ -357,7 +387,7 @@ put_dbkey(NSSLOWKEYDBHandle *handle, DBT *index, NSSLOWKEYDBKey *dbkey, PRBool u
}
/* sync the database */
- status = (* handle->db->sync)(handle->db, 0);
+ status = keydb_Sync(handle->db, 0);
if ( status ) {
goto loser;
}
@@ -387,7 +417,7 @@ nsslowkey_TraverseKeys(NSSLOWKEYDBHandle *handle,
return(SECFailure);
}
- ret = (* handle->db->seq)(handle->db, &key, &data, R_FIRST);
+ ret = keydb_Seq(handle->db, &key, &data, R_FIRST);
if ( ret ) {
return(SECFailure);
}
@@ -414,7 +444,7 @@ nsslowkey_TraverseKeys(NSSLOWKEYDBHandle *handle,
return(status);
}
}
- } while ( (* handle->db->seq)(handle->db, &key, &data, R_NEXT) == 0 );
+ } while ( keydb_Seq(handle->db, &key, &data, R_NEXT) == 0 );
return(SECSuccess);
}
@@ -494,7 +524,7 @@ GetKeyDBGlobalSalt(NSSLOWKEYDBHandle *handle)
saltKey.data = SALT_STRING;
saltKey.size = sizeof(SALT_STRING) - 1;
- ret = (* handle->db->get)(handle->db, &saltKey, &saltData, 0);
+ ret = keydb_Get(handle->db, &saltKey, &saltData, 0);
if ( ret ) {
return(NULL);
}
@@ -516,7 +546,7 @@ StoreKeyDBGlobalSalt(NSSLOWKEYDBHandle *handle)
saltData.size = handle->global_salt->len;
/* put global salt into the database now */
- status = (* handle->db->put)( handle->db, &saltKey, &saltData, 0);
+ status = keydb_Put(handle->db, &saltKey, &saltData, 0);
if ( status ) {
return(SECFailure);
}
@@ -539,7 +569,7 @@ makeGlobalVersion(NSSLOWKEYDBHandle *handle)
versionKey.size = sizeof(VERSION_STRING)-1;
/* put version string into the database now */
- status = (* handle->db->put)(handle->db, &versionKey, &versionData, 0);
+ status = keydb_Put(handle->db, &versionKey, &versionData, 0);
if ( status ) {
return(SECFailure);
}
@@ -565,7 +595,7 @@ makeGlobalSalt(NSSLOWKEYDBHandle *handle)
RNG_GenerateGlobalRandomBytes(saltbuf, sizeof(saltbuf));
/* put global salt into the database now */
- status = (* handle->db->put)( handle->db, &saltKey, &saltData, 0);
+ status = keydb_Put(handle->db, &saltKey, &saltData, 0);
if ( status ) {
return(SECFailure);
}
@@ -605,7 +635,7 @@ nsslowkey_version(DB *db)
versionKey.size = sizeof(VERSION_STRING)-1;
/* lookup version string in database */
- ret = (* db->get)( db, &versionKey, &versionData, 0 );
+ ret = keydb_Get( db, &versionKey, &versionData, 0 );
/* error accessing the database */
if ( ret < 0 ) {
@@ -626,7 +656,7 @@ seckey_HasAServerKey(DB *db)
int ret;
PRBool found = PR_FALSE;
- ret = (* db->seq)(db, &key, &data, R_FIRST);
+ ret = keydb_Seq(db, &key, &data, R_FIRST);
if ( ret ) {
return PR_FALSE;
}
@@ -663,7 +693,7 @@ seckey_HasAServerKey(DB *db)
}
}
- } while ( (* db->seq)(db, &key, &data, R_NEXT) == 0 );
+ } while ( keydb_Seq(db, &key, &data, R_NEXT) == 0 );
return found;
}
@@ -702,7 +732,7 @@ nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle)
saltKey.data = SALT_STRING;
saltKey.size = sizeof(SALT_STRING) - 1;
- ret = (* handle->updatedb->get)(handle->updatedb, &saltKey, &saltData, 0);
+ ret = keydb_Get(handle->updatedb, &saltKey, &saltData, 0);
if ( ret ) {
/* no salt in old db, so it is corrupted */
goto done;
@@ -720,7 +750,7 @@ nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle)
checkKey.data = KEYDB_PW_CHECK_STRING;
checkKey.size = KEYDB_PW_CHECK_LEN;
- ret = (* handle->updatedb->get)(handle->updatedb, &checkKey,
+ ret = keydb_Get(handle->updatedb, &checkKey,
&checkData, 0 );
if (ret) {
/*
@@ -741,11 +771,11 @@ nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle)
fcheckData.data = "1";
fcheckData.size = 1;
/* put global salt into the new database now */
- ret = (* handle->db->put)( handle->db, &saltKey, &saltData, 0);
+ ret = keydb_Put( handle->db, &saltKey, &saltData, 0);
if ( ret ) {
goto done;
}
- ret = (* handle->db->put)( handle->db, &fcheckKey, &fcheckData, 0);
+ ret = keydb_Put( handle->db, &fcheckKey, &fcheckData, 0);
if ( ret ) {
goto done;
}
@@ -754,7 +784,7 @@ nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle)
}
} else {
/* put global salt into the new database now */
- ret = (* handle->db->put)( handle->db, &saltKey, &saltData, 0);
+ ret = keydb_Put( handle->db, &saltKey, &saltData, 0);
if ( ret ) {
goto done;
}
@@ -784,7 +814,7 @@ nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle)
/* now traverse the database */
- ret = (* handle->updatedb->seq)(handle->updatedb, &key, &data, R_FIRST);
+ ret = keydb_Seq(handle->updatedb, &key, &data, R_FIRST);
if ( ret ) {
goto done;
}
@@ -830,16 +860,16 @@ nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle)
sec_destroy_dbkey(dbkey);
}
- } while ( (* handle->updatedb->seq)(handle->updatedb, &key, &data,
+ } while ( keydb_Seq(handle->updatedb, &key, &data,
R_NEXT) == 0 );
dbkey = NULL;
done:
/* sync the database */
- ret = (* handle->db->sync)(handle->db, 0);
+ ret = keydb_Sync(handle->db, 0);
- (* handle->updatedb->close)(handle->updatedb);
+ keydb_Close(handle->updatedb);
handle->updatedb = NULL;
if ( rc4key ) {
@@ -902,10 +932,10 @@ openNewDB(const char *appName, const char *prefix, const char *dbname,
if (updatedb) {
handle->version = nsslowkey_version(updatedb);
if (handle->version != NSSLOWKEY_DB_FILE_VERSION) {
- (updatedb->close)(updatedb);
+ keydb_Close(updatedb);
} else {
db_Copy(handle->db, updatedb);
- (updatedb->close)(updatedb);
+ keydb_Close(updatedb);
db_FinishTransaction(handle->db,PR_FALSE);
db_InitComplete(handle->db);
return SECSuccess;
@@ -951,7 +981,7 @@ openNewDB(const char *appName, const char *prefix, const char *dbname,
}
/* sync the database */
- ret = (* handle->db->sync)(handle->db, 0);
+ ret = keydb_Sync(handle->db, 0);
if ( ret ) {
rv = SECFailure;
goto loser;
@@ -981,7 +1011,7 @@ openOldDB(const char *appName, const char *prefix, const char *dbname,
*version = nsslowkey_version(db);
if (*version != NSSLOWKEY_DB_FILE_VERSION ) {
/* bogus version number record, reset the database */
- (* db->close)( db );
+ keydb_Close( db );
db = NULL;
}
}
@@ -1015,6 +1045,8 @@ nsslowkey_OpenKeyDB(PRBool readOnly, const char *appName, const char *prefix,
(prefix ? PORT_Strdup(prefix) : NULL);
handle->readOnly = readOnly;
+ keydb_InitLocks(handle);
+
handle->db = openOldDB(appName, prefix, dbname, openflags,
&handle->version);
@@ -1042,7 +1074,6 @@ nsslowkey_OpenKeyDB(PRBool readOnly, const char *appName, const char *prefix,
} else if (rv != SECSuccess) {
goto loser;
}
-
}
handle->global_salt = GetKeyDBGlobalSalt(handle);
@@ -1057,10 +1088,10 @@ loser:
PORT_SetError(SEC_ERROR_BAD_DATABASE);
if ( handle->db ) {
- (* handle->db->close)(handle->db);
+ keydb_Close(handle->db);
}
if ( handle->updatedb ) {
- (* handle->updatedb->close)(handle->updatedb);
+ keydb_Close(handle->updatedb);
}
PORT_Free(handle);
return NULL;
@@ -1074,13 +1105,14 @@ nsslowkey_CloseKeyDB(NSSLOWKEYDBHandle *handle)
{
if (handle != NULL) {
if (handle->db != NULL) {
- (* handle->db->close)(handle->db);
+ keydb_Close(handle->db);
}
if (handle->dbname) PORT_Free(handle->dbname);
if (handle->appname) PORT_Free(handle->appname);
if (handle->global_salt) {
SECITEM_FreeItem(handle->global_salt,PR_TRUE);
}
+ keydb_DestroyLocks(handle);
PORT_Free(handle);
}
@@ -1114,14 +1146,14 @@ nsslowkey_DeleteKey(NSSLOWKEYDBHandle *handle, SECItem *pubkey)
namekey.size = pubkey->len;
/* delete it from the database */
- ret = (* handle->db->del)(handle->db, &namekey, 0);
+ ret = keydb_Del(handle->db, &namekey, 0);
if ( ret ) {
PORT_SetError(SEC_ERROR_BAD_DATABASE);
return(SECFailure);
}
/* sync the database */
- ret = (* handle->db->sync)(handle->db, 0);
+ ret = keydb_Sync(handle->db, 0);
if ( ret ) {
PORT_SetError(SEC_ERROR_BAD_DATABASE);
return(SECFailure);
@@ -1166,7 +1198,7 @@ nsslowkey_KeyForIDExists(NSSLOWKEYDBHandle *handle, SECItem *id)
namekey.data = (char *)id->data;
namekey.size = id->len;
- status = (* handle->db->get)(handle->db, &namekey, &dummy, 0);
+ status = keydb_Get(handle->db, &namekey, &dummy, 0);
if ( status ) {
return PR_FALSE;
}
@@ -1224,7 +1256,7 @@ nsslowkey_KeyForCertExists(NSSLOWKEYDBHandle *handle, NSSLOWCERTCertificate *cer
namekey.size = sizeof(buf);
}
- status = (* handle->db->get)(handle->db, &namekey, &dummy, 0);
+ status = keydb_Get(handle->db, &namekey, &dummy, 0);
/* some databases have the key stored as a signed value */
if (status) {
unsigned char *buf = (unsigned char *)PORT_Alloc(namekey.size+1);
@@ -1233,7 +1265,7 @@ nsslowkey_KeyForCertExists(NSSLOWKEYDBHandle *handle, NSSLOWCERTCertificate *cer
buf[0] = 0;
namekey.data = buf;
namekey.size ++;
- status = (* handle->db->get)(handle->db, &namekey, &dummy, 0);
+ status = keydb_Get(handle->db, &namekey, &dummy, 0);
PORT_Free(buf);
}
}
@@ -1261,12 +1293,12 @@ nsslowkey_HasKeyDBPassword(NSSLOWKEYDBHandle *handle)
checkkey.data = KEYDB_PW_CHECK_STRING;
checkkey.size = KEYDB_PW_CHECK_LEN;
- ret = (* handle->db->get)(handle->db, &checkkey, &checkdata, 0 );
+ ret = keydb_Get(handle->db, &checkkey, &checkdata, 0 );
if ( ret ) {
/* see if this was an updated DB first */
checkkey.data = KEYDB_FAKE_PW_CHECK_STRING;
checkkey.size = KEYDB_FAKE_PW_CHECK_LEN;
- ret = (* handle->db->get)(handle->db, &checkkey, &checkdata, 0 );
+ ret = keydb_Get(handle->db, &checkkey, &checkdata, 0 );
if ( ret ) {
return(SECFailure);
}
@@ -2381,8 +2413,7 @@ nsslowkey_CheckKeyDBPassword(NSSLOWKEYDBHandle *handle, SECItem *pwitem)
if ( dbkey == NULL ) {
checkkey.data = KEYDB_FAKE_PW_CHECK_STRING;
checkkey.size = KEYDB_FAKE_PW_CHECK_LEN;
- ret = (* handle->db->get)(handle->db, &checkkey,
- &checkdata, 0 );
+ ret = keydb_Get(handle->db, &checkkey, &checkdata, 0 );
if (ret) {
goto loser;
}
@@ -2527,7 +2558,7 @@ ChangeKeyDBPasswordAlg(NSSLOWKEYDBHandle *handle,
}
/* delete the old record */
- ret = (* handle->db->del)(handle->db, &node->key, 0);
+ ret = keydb_Del(handle->db, &node->key, 0);
if ( ret ) {
PORT_SetError(SEC_ERROR_BAD_DATABASE);
rv = SECFailure;
@@ -2644,7 +2675,7 @@ nsslowkey_ResetKeyDB(NSSLOWKEYDBHandle *handle)
return SECFailure;
}
- (* handle->db->close)(handle->db);
+ keydb_Close(handle->db);
if (handle->appname) {
handle->db=
rdbopen(handle->appname, handle->dbname, "key", NO_CREATE, NULL);
@@ -2676,8 +2707,104 @@ nsslowkey_ResetKeyDB(NSSLOWKEYDBHandle *handle)
done:
/* sync the database */
- ret = (* handle->db->sync)(handle->db, 0);
+ ret = keydb_Sync(handle->db, 0);
db_InitComplete(handle->db);
return (errors == 0 ? SECSuccess : SECFailure);
}
+
+static int
+keydb_Get(DB *db, DBT *key, DBT *data, unsigned int flags)
+{
+ PRStatus prstat;
+ int ret;
+
+ PORT_Assert(kdbLock != NULL);
+ PZ_Lock(kdbLock);
+
+ ret = (* db->get)(db, key, data, flags);
+
+ prstat = PZ_Unlock(kdbLock);
+
+ return(ret);
+}
+
+static int
+keydb_Put(DB *db, DBT *key, DBT *data, unsigned int flags)
+{
+ PRStatus prstat;
+ int ret = 0;
+
+ PORT_Assert(kdbLock != NULL);
+ PZ_Lock(kdbLock);
+
+ ret = (* db->put)(db, key, data, flags);
+
+ prstat = PZ_Unlock(kdbLock);
+
+ return(ret);
+}
+
+static int
+keydb_Sync(DB *db, unsigned int flags)
+{
+ PRStatus prstat;
+ int ret;
+
+ PORT_Assert(kdbLock != NULL);
+ PZ_Lock(kdbLock);
+
+ ret = (* db->sync)(db, flags);
+
+ prstat = PZ_Unlock(kdbLock);
+
+ return(ret);
+}
+
+static int
+keydb_Del(DB *db, DBT *key, unsigned int flags)
+{
+ PRStatus prstat;
+ int ret;
+
+ PORT_Assert(kdbLock != NULL);
+ PZ_Lock(kdbLock);
+
+ ret = (* db->del)(db, key, flags);
+
+ prstat = PZ_Unlock(kdbLock);
+
+ return(ret);
+}
+
+static int
+keydb_Seq(DB *db, DBT *key, DBT *data, unsigned int flags)
+{
+ PRStatus prstat;
+ int ret;
+
+ PORT_Assert(kdbLock != NULL);
+ PZ_Lock(kdbLock);
+
+ ret = (* db->seq)(db, key, data, flags);
+
+ prstat = PZ_Unlock(kdbLock);
+
+ return(ret);
+}
+
+static void
+keydb_Close(DB *db)
+{
+ PRStatus prstat;
+
+ PORT_Assert(kdbLock != NULL);
+ PZ_Lock(kdbLock);
+
+ (* db->close)(db);
+
+ prstat = PZ_Unlock(kdbLock);
+
+ return;
+}
+
diff --git a/security/nss/lib/softoken/lowcert.c b/security/nss/lib/softoken/lowcert.c
index 1ef4021fb..652c444c6 100644
--- a/security/nss/lib/softoken/lowcert.c
+++ b/security/nss/lib/softoken/lowcert.c
@@ -288,13 +288,13 @@ nsslowcert_GetCertTimes(NSSLOWCERTCertificate *c, PRTime *notBefore, PRTime *not
}
/* convert DER not-before time */
- rv = CERT_DecodeTimeChoice(notBefore, &validity.notBefore);
+ rv = DER_DecodeTimeChoice(notBefore, &validity.notBefore);
if (rv) {
return(SECFailure);
}
/* convert DER not-after time */
- rv = CERT_DecodeTimeChoice(notAfter, &validity.notAfter);
+ rv = DER_DecodeTimeChoice(notAfter, &validity.notAfter);
if (rv) {
return(SECFailure);
}
diff --git a/security/nss/lib/softoken/pcert.h b/security/nss/lib/softoken/pcert.h
index 9743a8619..e2b5b8c6c 100644
--- a/security/nss/lib/softoken/pcert.h
+++ b/security/nss/lib/softoken/pcert.h
@@ -219,6 +219,9 @@ PRBool
nsslowcert_hasTrust(NSSLOWCERTCertTrust *trust);
void
+nsslowcert_DestroyFreeLists(void);
+
+void
nsslowcert_DestroyGlobalLocks(void);
void
diff --git a/security/nss/lib/softoken/pcertdb.c b/security/nss/lib/softoken/pcertdb.c
index fb7ff6b87..2a3aaa7c2 100644
--- a/security/nss/lib/softoken/pcertdb.c
+++ b/security/nss/lib/softoken/pcertdb.c
@@ -1038,6 +1038,7 @@ CreateCertEntry(void)
entryListCount--;
entryListHead = entry->next;
}
+ PORT_Assert(entryListCount >= 0);
nsslowcert_UnlockFreeList();
if (entry) {
return entry;
@@ -1046,6 +1047,22 @@ CreateCertEntry(void)
return PORT_ZAlloc(sizeof(certDBEntryCert));
}
+static void
+DestroyCertEntryFreeList(void)
+{
+ certDBEntryCert *entry;
+
+ nsslowcert_LockFreeList();
+ while (NULL != (entry = entryListHead)) {
+ entryListCount--;
+ entryListHead = entry->next;
+ PORT_Free(entry);
+ }
+ PORT_Assert(!entryListCount);
+ entryListCount = 0;
+ nsslowcert_UnlockFreeList();
+}
+
/*
* Read a certificate entry
*/
@@ -2681,7 +2698,7 @@ nsslowcert_UpdateSubjectEmailAddr(NSSLOWCERTCertDBHandle *dbhandle,
}
if ( entry->emailAddrs ) {
- for (i=0; i < entry->nemailAddrs; i++) {
+ for (i=0; i < (int)(entry->nemailAddrs); i++) {
if (PORT_Strcmp(entry->emailAddrs[i],emailAddr) == 0) {
index = i;
}
@@ -2695,7 +2712,7 @@ nsslowcert_UpdateSubjectEmailAddr(NSSLOWCERTCertDBHandle *dbhandle,
}
entry->nemailAddrs--;
- for (i=index; i < entry->nemailAddrs; i++) {
+ for (i=index; i < (int)(entry->nemailAddrs); i++) {
entry->emailAddrs[i] = entry->emailAddrs[i+1];
}
} else {
@@ -2708,7 +2725,7 @@ nsslowcert_UpdateSubjectEmailAddr(NSSLOWCERTCertDBHandle *dbhandle,
if (!newAddrs) {
goto loser;
}
- for (i=0; i < entry->nemailAddrs; i++) {
+ for (i=0; i < (int)(entry->nemailAddrs); i++) {
newAddrs[i] = entry->emailAddrs[i];
}
newAddrs[entry->nemailAddrs] =
@@ -4296,6 +4313,7 @@ CreateTrust(void)
trustListCount--;
trustListHead = trust->next;
}
+ PORT_Assert(trustListCount >= 0);
nsslowcert_UnlockFreeList();
if (trust) {
return trust;
@@ -4304,9 +4322,25 @@ CreateTrust(void)
return PORT_ZAlloc(sizeof(NSSLOWCERTTrust));
}
+static void
+DestroyTrustFreeList(void)
+{
+ NSSLOWCERTTrust *trust;
+
+ nsslowcert_LockFreeList();
+ while (NULL != (trust = trustListHead)) {
+ trustListCount--;
+ trustListHead = trust->next;
+ PORT_Free(trust);
+ }
+ PORT_Assert(!trustListCount);
+ trustListCount = 0;
+ nsslowcert_UnlockFreeList();
+}
static NSSLOWCERTTrust *
-DecodeTrustEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCert *entry, SECItem *dbKey)
+DecodeTrustEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCert *entry,
+ SECItem *dbKey)
{
NSSLOWCERTTrust *trust = CreateTrust();
if (trust == NULL) {
@@ -5000,14 +5034,30 @@ nsslowcert_CreateCert(void)
certListHead = cert->next;
certListCount--;
}
+ PORT_Assert(certListCount >= 0);
nsslowcert_UnlockFreeList();
-
if (cert) {
return cert;
}
return (NSSLOWCERTCertificate *) PORT_ZAlloc(sizeof(NSSLOWCERTCertificate));
}
+static void
+DestroyCertFreeList(void)
+{
+ NSSLOWCERTCertificate *cert;
+
+ nsslowcert_LockFreeList();
+ while (NULL != (cert = certListHead)) {
+ certListCount--;
+ certListHead = cert->next;
+ PORT_Free(cert);
+ }
+ PORT_Assert(!certListCount);
+ certListCount = 0;
+ nsslowcert_UnlockFreeList();
+}
+
void
nsslowcert_DestroyTrust(NSSLOWCERTTrust *trust)
{
@@ -5248,8 +5298,21 @@ nsslowcert_SaveSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle, char *emailAddr,
return(rv);
}
+/* If the freeListLock doesn't exist when this function is called,
+** this function will create it, use it 3 times, and delete it.
+*/
+void
+nsslowcert_DestroyFreeLists(void)
+{
+ DestroyCertEntryFreeList();
+ DestroyTrustFreeList();
+ DestroyCertFreeList();
+ PZ_DestroyLock(freeListLock);
+ freeListLock = NULL;
+}
+
void
-nsslowcert_DestroyGlobalLocks()
+nsslowcert_DestroyGlobalLocks(void)
{
if (dbLock) {
PZ_DestroyLock(dbLock);
diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c
index d0fe96637..0d77670f2 100644
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -1040,7 +1040,6 @@ pk11_handlePublicKeyObject(PK11Session *session, PK11Object *object,
CK_BBOOL derive = CK_FALSE;
CK_BBOOL verify = CK_TRUE;
CK_ATTRIBUTE_TYPE pubKeyAttr = CKA_VALUE;
- PK11Attribute *attribute;
CK_RV crv;
switch (key_type) {
@@ -2852,6 +2851,8 @@ CK_RV nsc_CommonFinalize (CK_VOID_PTR pReserved, PRBool isFIPS)
return CKR_OK;
}
+ pk11_CleanupFreeLists();
+ nsslowcert_DestroyFreeLists();
nsslowcert_DestroyGlobalLocks();
#ifdef LEAK_TEST
@@ -2867,7 +2868,6 @@ CK_RV nsc_CommonFinalize (CK_VOID_PTR pReserved, PRBool isFIPS)
RNG_RNGShutdown();
#endif
- pk11_CleanupFreeLists();
/* tell freeBL to clean up after itself */
BL_Cleanup();
/* clean up the default OID table */
diff --git a/security/nss/lib/softoken/pkcs11u.c b/security/nss/lib/softoken/pkcs11u.c
index 046dcdde6..7b1fddf38 100644
--- a/security/nss/lib/softoken/pkcs11u.c
+++ b/security/nss/lib/softoken/pkcs11u.c
@@ -45,6 +45,7 @@
#include "secasn1.h"
#include "blapi.h"
#include "secerr.h"
+#include "prnetdb.h" /* for PR_ntohl */
/*
* ******************** Attribute Utilities *******************************
@@ -1323,7 +1324,6 @@ pk11_ConstrainAttribute(PK11Object *object, CK_ATTRIBUTE_TYPE type,
PK11Attribute *attribute;
unsigned int size;
unsigned char *ptr;
- int i,j;
attribute = pk11_FindAttribute(object, type);
if (!attribute) {
@@ -1922,7 +1922,6 @@ CK_RV
pk11_GetULongAttribute(PK11Object *object, CK_ATTRIBUTE_TYPE type,
CK_ULONG *longData)
{
- int len;
PK11Attribute *attribute;
attribute = pk11_FindAttribute(object, type);
diff --git a/security/nss/lib/ssl/ssl3con.c b/security/nss/lib/ssl/ssl3con.c
index 603e3ab88..1b2cd4fc1 100644
--- a/security/nss/lib/ssl/ssl3con.c
+++ b/security/nss/lib/ssl/ssl3con.c
@@ -3759,9 +3759,9 @@ sendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
}
/* Determine the PMS */
- pms = PK11_PubDeriveExtended(privKey, svrPubKey, PR_FALSE, NULL, NULL,
- CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0, NULL,
- kdf, NULL);
+ pms = PK11_PubDeriveWithKDF(privKey, svrPubKey, PR_FALSE, NULL, NULL,
+ CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0,
+ kdf, NULL, NULL);
if (pms == NULL) {
ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
@@ -6983,9 +6983,9 @@ ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b,
}
/* Determine the PMS */
- pms = PK11_PubDeriveExtended(srvrPrivKey, &clntPubKey, PR_FALSE, NULL, NULL,
- CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0, NULL,
- kdf, NULL);
+ pms = PK11_PubDeriveWithKDF(srvrPrivKey, &clntPubKey, PR_FALSE, NULL, NULL,
+ CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0,
+ kdf, NULL, NULL);
PORT_Free(clntPubKey.u.ec.publicValue.data);
diff --git a/security/nss/lib/ssl/sslgathr.c b/security/nss/lib/ssl/sslgathr.c
index 9f06a25e3..1e0253c8b 100644
--- a/security/nss/lib/ssl/sslgathr.c
+++ b/security/nss/lib/ssl/sslgathr.c
@@ -195,6 +195,10 @@ ssl2_GatherData(sslSocket *ss, sslGather *gs, int flags)
/* is_escape = (gs->hdr[0] & 0x40) != 0; */
gs->recordPadding = gs->hdr[2];
}
+ if (!gs->count) {
+ PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
+ goto cleanup;
+ }
if (gs->count > gs->buf.space) {
err = sslBuffer_Grow(&gs->buf, gs->count);
diff --git a/security/nss/lib/util/dertime.c b/security/nss/lib/util/dertime.c
index 50036f258..a4d065229 100644
--- a/security/nss/lib/util/dertime.c
+++ b/security/nss/lib/util/dertime.c
@@ -125,9 +125,15 @@ DER_TimeToUTCTime(SECItem *dst, int64 gmttime)
return DER_TimeToUTCTimeArena(NULL, dst, gmttime);
}
-
+/* The caller of DER_AsciiToItem MUST ENSURE that either
+** a) "string" points to a null-terminated ASCII string, or
+** b) "string" points to a buffer containing a valid UTCTime,
+** whether null terminated or not.
+** otherwise, this function may UMR and/or crash.
+** It suffices to ensure that the input "string" is at least 17 bytes long.
+*/
SECStatus
-DER_AsciiToTime(int64 *dst, char *string)
+DER_AsciiToTime(int64 *dst, const char *string)
{
long year, month, mday, hour, minute, second, hourOff, minOff, days;
int64 result, tmp1, tmp2;
@@ -223,9 +229,27 @@ DER_AsciiToTime(int64 *dst, char *string)
}
SECStatus
-DER_UTCTimeToTime(int64 *dst, SECItem *time)
+DER_UTCTimeToTime(int64 *dst, const SECItem *time)
{
- return DER_AsciiToTime(dst, (char*) time->data);
+ const char * string;
+ char localBuf[20];
+
+ /* Minimum valid UTCTime is yymmddhhmmZ which is 11 bytes.
+ ** Maximum valid UTCTime is yymmddhhmmss+0000 which is 17 bytes.
+ ** 20 should be large enough for all valid encoded times.
+ */
+ if (!time || !time->data || time->len < 11) {
+ PORT_SetError(SEC_ERROR_INVALID_TIME);
+ return SECFailure;
+ }
+ if (time->len >= sizeof localBuf) {
+ string = (const char *)time->data;
+ } else {
+ memset(localBuf, 0, sizeof localBuf);
+ memcpy(localBuf, time->data, time->len);
+ string = (const char *)localBuf;
+ }
+ return DER_AsciiToTime(dst, string);
}
/*
@@ -292,15 +316,29 @@ DER_TimeToGeneralizedTime(SECItem *dst, int64 gmttime)
the certificate should be consider invalid!?
*/
SECStatus
-DER_GeneralizedTimeToTime(int64 *dst, SECItem *time)
+DER_GeneralizedTimeToTime(int64 *dst, const SECItem *time)
{
PRExplodedTime genTime;
- char *string;
+ const char *string;
long hourOff, minOff;
uint16 century;
+ char localBuf[20];
+
+ /* Minimum valid GeneralizedTime is ccyymmddhhmmZ which is 13 bytes.
+ ** Maximum valid GeneralizedTime is ccyymmddhhmmss+0000 which is 19 bytes.
+ ** 20 should be large enough for all valid encoded times.
+ */
+ if (!time || !time->data || time->len < 13)
+ goto loser;
+ if (time->len >= sizeof localBuf) {
+ string = (const char *)time->data;
+ } else {
+ memset(localBuf, 0, sizeof localBuf);
+ memcpy(localBuf, time->data, time->len);
+ string = (const char *)localBuf;
+ }
- string = (char *)time->data;
- PORT_Memset (&genTime, 0, sizeof (genTime));
+ memset(&genTime, 0, sizeof genTime);
/* Verify time is formatted properly and capture information */
hourOff = 0;
diff --git a/security/nss/lib/util/nssilckt.h b/security/nss/lib/util/nssilckt.h
index e0b49902f..b516df9d6 100644
--- a/security/nss/lib/util/nssilckt.h
+++ b/security/nss/lib/util/nssilckt.h
@@ -154,6 +154,7 @@ typedef enum {
nssILockRWLock = 15,
nssILockOther = 16,
nssILockSelfServ = 17,
+ nssILockKeyDB = 18,
nssILockLast /* don't use this one! */
} nssILockType;
diff --git a/security/nss/lib/util/secasn1d.c b/security/nss/lib/util/secasn1d.c
index 965fa702d..2663abd3b 100644
--- a/security/nss/lib/util/secasn1d.c
+++ b/security/nss/lib/util/secasn1d.c
@@ -959,7 +959,7 @@ sec_asn1d_parse_more_length (sec_asn1d_state *state,
count = 0;
while (len && state->pending) {
- if (HIGH_BITS (state->contents_length, 8) != 0) {
+ if (HIGH_BITS (state->contents_length, 9) != 0) {
/*
* The given full content length overflows our container;
* just give up.
diff --git a/security/nss/lib/util/secder.h b/security/nss/lib/util/secder.h
index a54967f61..dcb43abd7 100644
--- a/security/nss/lib/util/secder.h
+++ b/security/nss/lib/util/secder.h
@@ -148,12 +148,12 @@ extern SECStatus DER_TimeToUTCTimeArena(PRArenaPool* arenaOpt,
** "result" the resulting "UNIX" time
** "string" the der notation ascii value to decode
*/
-extern SECStatus DER_AsciiToTime(int64 *result, char *string);
+extern SECStatus DER_AsciiToTime(int64 *result, const char *string);
/*
** Same as DER_AsciiToTime except takes an SECItem instead of a string
*/
-extern SECStatus DER_UTCTimeToTime(int64 *result, SECItem *time);
+extern SECStatus DER_UTCTimeToTime(int64 *result, const SECItem *time);
/*
** Convert a DER encoded UTC time to an ascii time representation
@@ -186,7 +186,7 @@ extern SECStatus DER_TimeToGeneralizedTimeArena(PRArenaPool* arenaOpt,
** "dst" the resulting "UNIX" time
** "string" the der notation ascii value to decode
*/
-extern SECStatus DER_GeneralizedTimeToTime(int64 *dst, SECItem *time);
+extern SECStatus DER_GeneralizedTimeToTime(int64 *dst, const SECItem *time);
/*
** Convert from a int64 UTC time value to a formatted ascii value. The
@@ -206,12 +206,12 @@ extern char *CERT_GenTime2FormattedAscii (int64 genTime, char *format);
** or a SEC_ASN1_UTC_TIME
*/
-extern SECStatus CERT_DecodeTimeChoice(PRTime* output, SECItem* input);
+extern SECStatus DER_DecodeTimeChoice(PRTime* output, const SECItem* input);
/* encode a PRTime to an ASN.1 DER SECItem containing either a
SEC_ASN1_GENERALIZED_TIME or a SEC_ASN1_UTC_TIME */
-extern SECStatus CERT_EncodeTimeChoice(PRArenaPool* arena, SECItem* output,
+extern SECStatus DER_EncodeTimeChoice(PRArenaPool* arena, SECItem* output,
PRTime input);
SEC_END_PROTOS
diff --git a/security/nss/lib/util/secitem.c b/security/nss/lib/util/secitem.c
index eb4683ca4..daf550d62 100644
--- a/security/nss/lib/util/secitem.c
+++ b/security/nss/lib/util/secitem.c
@@ -180,18 +180,32 @@ SECITEM_ItemsAreEqual(const SECItem *a, const SECItem *b)
SECItem *
SECITEM_DupItem(const SECItem *from)
{
+ return SECITEM_ArenaDupItem(NULL, from);
+}
+
+SECItem *
+SECITEM_ArenaDupItem(PRArenaPool *arena, const SECItem *from)
+{
SECItem *to;
if ( from == NULL ) {
return(NULL);
}
- to = (SECItem *)PORT_Alloc(sizeof(SECItem));
+ if ( arena != NULL ) {
+ to = (SECItem *)PORT_ArenaAlloc(arena, sizeof(SECItem));
+ } else {
+ to = (SECItem *)PORT_Alloc(sizeof(SECItem));
+ }
if ( to == NULL ) {
return(NULL);
}
- to->data = (unsigned char *)PORT_Alloc(from->len);
+ if ( arena != NULL ) {
+ to->data = (unsigned char *)PORT_ArenaAlloc(arena, from->len);
+ } else {
+ to->data = (unsigned char *)PORT_Alloc(from->len);
+ }
if ( to->data == NULL ) {
PORT_Free(to);
return(NULL);
@@ -199,7 +213,9 @@ SECITEM_DupItem(const SECItem *from)
to->len = from->len;
to->type = from->type;
- PORT_Memcpy(to->data, from->data, to->len);
+ if ( to->len ) {
+ PORT_Memcpy(to->data, from->data, to->len);
+ }
return(to);
}
diff --git a/security/nss/lib/util/secitem.h b/security/nss/lib/util/secitem.h
index 76a5d16fb..d957ba0eb 100644
--- a/security/nss/lib/util/secitem.h
+++ b/security/nss/lib/util/secitem.h
@@ -93,6 +93,13 @@ extern SECStatus SECITEM_CopyItem(PRArenaPool *arena, SECItem *to,
extern SECItem *SECITEM_DupItem(const SECItem *from);
/*
+** Allocate an item and copy "from" into it. The item itself and the
+** data it points to are both allocated from the arena. If arena is
+** NULL, this function is equivalent to SECITEM_DupItem.
+*/
+extern SECItem *SECITEM_ArenaDupItem(PRArenaPool *arena, const SECItem *from);
+
+/*
** Free "zap". If freeit is PR_TRUE then "zap" itself is freed.
*/
extern void SECITEM_FreeItem(SECItem *zap, PRBool freeit);
diff --git a/security/nss/lib/util/secoid.c b/security/nss/lib/util/secoid.c
index f9bb70b07..61c6d9aa0 100644
--- a/security/nss/lib/util/secoid.c
+++ b/security/nss/lib/util/secoid.c
@@ -1584,7 +1584,7 @@ secoid_Init(void)
int i;
if (oidhash) {
- return PR_SUCCESS;
+ return SECSuccess;
}
oidhash = PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare,
diff --git a/security/nss/lib/util/secport.c b/security/nss/lib/util/secport.c
index fb0892101..7d276f9b7 100644
--- a/security/nss/lib/util/secport.c
+++ b/security/nss/lib/util/secport.c
@@ -207,6 +207,8 @@ PORT_NewArena(unsigned long chunksize)
return(&pool->arena);
}
+#define MAX_SIZE 0x7fffffffUL
+
void *
PORT_ArenaAlloc(PLArenaPool *arena, size_t size)
{
@@ -218,6 +220,9 @@ PORT_ArenaAlloc(PLArenaPool *arena, size_t size)
size = 1;
}
+ if (size > MAX_SIZE) {
+ /* you lose. */
+ } else
/* Is it one of ours? Assume so and check the magic */
if (ARENAPOOL_MAGIC == pool->magic ) {
PZ_Lock(pool->lock);
diff --git a/security/nss/lib/util/sectime.c b/security/nss/lib/util/sectime.c
index 678021853..475a8c18f 100644
--- a/security/nss/lib/util/sectime.c
+++ b/security/nss/lib/util/sectime.c
@@ -45,7 +45,7 @@ const SEC_ASN1Template CERT_TimeChoiceTemplate[] = {
{ 0 }
};
-SEC_ASN1_CHOOSER_IMPLEMENT(CERT_TimeChoiceTemplate);
+SEC_ASN1_CHOOSER_IMPLEMENT(CERT_TimeChoiceTemplate)
const SEC_ASN1Template CERT_ValidityTemplate[] = {
{ SEC_ASN1_SEQUENCE,
@@ -122,9 +122,9 @@ CERT_CreateValidity(int64 notBefore, int64 notAfter)
v = (CERTValidity*) PORT_ArenaZAlloc(arena, sizeof(CERTValidity));
if (v) {
v->arena = arena;
- rv = CERT_EncodeTimeChoice(arena, &v->notBefore, notBefore);
+ rv = DER_EncodeTimeChoice(arena, &v->notBefore, notBefore);
if (rv) goto loser;
- rv = CERT_EncodeTimeChoice(arena, &v->notAfter, notAfter);
+ rv = DER_EncodeTimeChoice(arena, &v->notAfter, notAfter);
if (rv) goto loser;
}
return v;
@@ -228,7 +228,7 @@ DecodeGeneralizedTime2FormattedAscii (SECItem *generalizedTimeDER, char *format
/* decode a SECItem containing either a SEC_ASN1_GENERALIZED_TIME
or a SEC_ASN1_UTC_TIME */
-SECStatus CERT_DecodeTimeChoice(PRTime* output, SECItem* input)
+SECStatus DER_DecodeTimeChoice(PRTime* output, const SECItem* input)
{
switch (input->type) {
case siGeneralizedTime:
@@ -247,7 +247,7 @@ SECStatus CERT_DecodeTimeChoice(PRTime* output, SECItem* input)
/* encode a PRTime to an ASN.1 DER SECItem containing either a
SEC_ASN1_GENERALIZED_TIME or a SEC_ASN1_UTC_TIME */
-SECStatus CERT_EncodeTimeChoice(PRArenaPool* arena, SECItem* output, PRTime input)
+SECStatus DER_EncodeTimeChoice(PRArenaPool* arena, SECItem* output, PRTime input)
{
if (LL_CMP(input, >, January1st2050)) {
return DER_TimeToGeneralizedTimeArena(arena, output, input);
diff --git a/security/nss/lib/util/utf8.c b/security/nss/lib/util/utf8.c
index 7a3c3954d..013f202a9 100644
--- a/security/nss/lib/util/utf8.c
+++ b/security/nss/lib/util/utf8.c
@@ -236,6 +236,11 @@ sec_port_ucs4_utf8_conversion_function
return PR_TRUE;
} else {
unsigned int i, len = 0;
+ PORT_Assert((inBufLen % 4) == 0);
+ if ((inBufLen % 4) != 0) {
+ *outBufLen = 0;
+ return PR_FALSE;
+ }
for( i = 0; i < inBufLen; i += 4 ) {
if( inBuf[i+L_0] >= 0x04 ) len += 6;
@@ -457,6 +462,11 @@ sec_port_ucs2_utf8_conversion_function
return PR_TRUE;
} else {
unsigned int i, len = 0;
+ PORT_Assert((inBufLen % 2) == 0);
+ if ((inBufLen % 2) != 0) {
+ *outBufLen = 0;
+ return PR_FALSE;
+ }
for( i = 0; i < inBufLen; i += 2 ) {
if( (inBuf[i+H_0] == 0x00) && ((inBuf[i+H_0] & 0x80) == 0x00) ) len += 1;
diff --git a/security/nss/manifest.mn b/security/nss/manifest.mn
index 286954d04..98dc19a6a 100644
--- a/security/nss/manifest.mn
+++ b/security/nss/manifest.mn
@@ -33,7 +33,7 @@
CORE_DEPTH = ..
DEPTH = ..
-IMPORTS = nspr20/v4.3 \
+IMPORTS = nspr20/v4.4.1 \
dbm/DBM_1_61_RTM \
$(NULL)