Bug 669061: Upgrade to NSS 3.13 RC0, r=wtc
authorBrian Smith <bsmith@mozilla.com>
Fri, 07 Oct 2011 13:37:26 -0700
changeset 78386 8f011395145eae05bdb84218266bfc22cc3a07b0
parent 78385 35954e6f3167b3bc823126e3ec340b5a26e93274
child 78387 194720ba054f9ef2a3125fb5586aa985bfd9fe40
push id2517
push usermak77@bonardo.net
push dateSat, 08 Oct 2011 07:42:23 +0000
treeherdermozilla-inbound@fd0f0a12be74 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswtc
bugs669061
milestone10.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 669061: Upgrade to NSS 3.13 RC0, r=wtc
security/coreconf/Darwin.mk
security/coreconf/WIN32.mk
security/coreconf/coreconf.dep
security/nss/TAG-INFO
security/nss/cmd/bltest/blapitest.c
security/nss/cmd/certutil/certutil.c
security/nss/cmd/crlutil/crlutil.c
security/nss/cmd/fipstest/fipstest.c
security/nss/cmd/lib/manifest.mn
security/nss/cmd/lib/secerror.c
security/nss/cmd/lib/secutil.c
security/nss/cmd/lib/secutil.h
security/nss/cmd/strsclnt/strsclnt.c
security/nss/cmd/tstclnt/tstclnt.c
security/nss/lib/certdb/certi.h
security/nss/lib/certhigh/certvfy.c
security/nss/lib/ckfw/builtins/certdata.c
security/nss/lib/ckfw/builtins/certdata.txt
security/nss/lib/dev/ckhelper.c
security/nss/lib/freebl/blapi.h
security/nss/lib/freebl/ec.c
security/nss/lib/freebl/ecl/ecp_mont.c
security/nss/lib/freebl/ldvector.c
security/nss/lib/freebl/loader.c
security/nss/lib/freebl/loader.h
security/nss/lib/freebl/manifest.mn
security/nss/lib/freebl/mgf1.c
security/nss/lib/freebl/mpi/mpcpucache.c
security/nss/lib/freebl/rsa.c
security/nss/lib/freebl/sha512.c
security/nss/lib/freebl/unix_rand.c
security/nss/lib/libpkix/include/pkix_pl_pki.h
security/nss/lib/libpkix/pkix/top/pkix_build.c
security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c
security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.c
security/nss/lib/nss/nss.h
security/nss/lib/nss/nssinit.c
security/nss/lib/pk11wrap/pk11obj.c
security/nss/lib/pkcs7/p7decode.c
security/nss/lib/pkcs7/p7encode.c
security/nss/lib/pkcs7/p7local.c
security/nss/lib/pkcs7/p7local.h
security/nss/lib/pkcs7/pkcs7t.h
security/nss/lib/pkcs7/secmime.c
security/nss/lib/smime/cmsasn1.c
security/nss/lib/smime/cmsdecode.c
security/nss/lib/smime/cmsencode.c
security/nss/lib/smime/cmslocal.h
security/nss/lib/smime/cmspubkey.c
security/nss/lib/smime/cmsrecinfo.c
security/nss/lib/smime/cmssigdata.c
security/nss/lib/smime/cmssiginfo.c
security/nss/lib/smime/cmst.h
security/nss/lib/smime/cmsutil.c
security/nss/lib/smime/smime.h
security/nss/lib/smime/smimeutil.c
security/nss/lib/softoken/pkcs11c.c
security/nss/lib/softoken/rsawrapr.c
security/nss/lib/softoken/sftkdb.c
security/nss/lib/softoken/sftkmod.c
security/nss/lib/softoken/sftkpars.c
security/nss/lib/softoken/softkver.h
security/nss/lib/ssl/SSLerrs.h
security/nss/lib/ssl/manifest.mn
security/nss/lib/ssl/ssl.h
security/nss/lib/ssl/ssl3con.c
security/nss/lib/ssl/sslerr.h
security/nss/lib/ssl/sslimpl.h
security/nss/lib/ssl/sslmutex.c
security/nss/lib/ssl/sslmutex.h
security/nss/lib/ssl/sslsnce.c
security/nss/lib/ssl/sslsock.c
security/nss/lib/util/errstrs.c
security/nss/lib/util/errstrs.h
security/nss/lib/util/manifest.mn
security/nss/lib/util/nssutil.def
security/nss/lib/util/nssutil.h
security/nss/lib/util/pkcs11n.h
security/nss/lib/util/secasn1u.c
security/nss/lib/util/secport.h
security/nss/tests/cert/cert.sh
security/nss/tests/common/init.sh
security/nss/tests/memleak/ignored
security/nss/tests/ssl/sslcov.txt
--- a/security/coreconf/Darwin.mk
+++ b/security/coreconf/Darwin.mk
@@ -54,19 +54,23 @@ ifdef USE_64
 CC              += -arch x86_64
 override CPU_ARCH	= x86_64
 else
 OS_REL_CFLAGS	= -Di386
 CC              += -arch i386
 override CPU_ARCH	= x86
 endif
 else
+ifeq (arm,$(CPU_ARCH))
+# Nothing set for arm currently.
+else
 OS_REL_CFLAGS	= -Dppc
 CC              += -arch ppc
 endif
+endif
 
 ifneq (,$(MACOS_SDK_DIR))
     GCC_VERSION_FULL := $(shell $(CC) -dumpversion)
     GCC_VERSION_MAJOR := $(shell echo $(GCC_VERSION_FULL) | awk -F. '{ print $$1 }')
     GCC_VERSION_MINOR := $(shell echo $(GCC_VERSION_FULL) | awk -F. '{ print $$2 }')
     GCC_VERSION = $(GCC_VERSION_MAJOR).$(GCC_VERSION_MINOR)
 
     ifeq (,$(filter-out 2 3,$(GCC_VERSION_MAJOR)))
--- a/security/coreconf/WIN32.mk
+++ b/security/coreconf/WIN32.mk
@@ -119,19 +119,19 @@ else
 LIB_SUFFIX   = lib
 endif
 DLL_SUFFIX   = dll
 
 ifdef NS_USE_GCC
     # The -mnop-fun-dllimport flag allows us to avoid a drawback of
     # the dllimport attribute that a pointer to a function marked as
     # dllimport cannot be used as as a constant address.
-    OS_CFLAGS += -mno-cygwin -mms-bitfields -mnop-fun-dllimport
+    OS_CFLAGS += -mwindows -mms-bitfields -mnop-fun-dllimport
     _GEN_IMPORT_LIB=-Wl,--out-implib,$(IMPORT_LIBRARY)
-    DLLFLAGS  += -mno-cygwin -o $@ -shared -Wl,--export-all-symbols $(if $(IMPORT_LIBRARY),$(_GEN_IMPORT_LIB))
+    DLLFLAGS  += -mwindows -o $@ -shared -Wl,--export-all-symbols $(if $(IMPORT_LIBRARY),$(_GEN_IMPORT_LIB))
     ifdef BUILD_OPT
 	ifeq (11,$(ALLOW_OPT_CODE_SIZE)$(OPT_CODE_SIZE))
 		OPTIMIZER += -Os
 	else
 		OPTIMIZER += -O2
 	endif
 	DEFINES    += -UDEBUG -U_DEBUG -DNDEBUG
     else
--- a/security/coreconf/coreconf.dep
+++ b/security/coreconf/coreconf.dep
@@ -38,9 +38,8 @@
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSS in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
 
-
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-NSS_3_13_BETA1
+NSS_3_13_RC0
--- a/security/nss/cmd/bltest/blapitest.c
+++ b/security/nss/cmd/bltest/blapitest.c
@@ -45,17 +45,17 @@
 #include "prtime.h"
 #include "prsystem.h"
 #include "plstr.h"
 #include "nssb64.h"
 #include "secutil.h"
 #include "plgetopt.h"
 #include "softoken.h"
 #include "nspr.h"
-#include "nssutil.h"
+#include "secport.h"
 #include "secoid.h"
 
 #ifdef NSS_ENABLE_ECC
 #include "ecl-curve.h"
 SECStatus EC_DecodeParams(const SECItem *encodedParams, 
 	ECParams **ecparams);
 SECStatus EC_CopyParams(PRArenaPool *arena, ECParams *dstParams,
 	      const ECParams *srcParams);
@@ -73,17 +73,17 @@ char *testdir = NULL;
 #define BLTEST_DEFAULT_CHUNKSIZE 4096
 
 #define WORDSIZE sizeof(unsigned long)
 
 #define CHECKERROR(rv, ln) \
     if (rv) { \
 	PRErrorCode prerror = PR_GetError(); \
 	PR_fprintf(PR_STDERR, "%s: ERR %d (%s) at line %d.\n", progName, \
-	prerror, NSS_Strerror(prerror,formatSimple), ln); \
+	prerror, PORT_ErrorToString(prerror), ln); \
 	exit(-1); \
     }
 
 /* Macros for performance timing. */
 #define TIMESTART() \
     time1 = PR_IntervalNow();
 
 #define TIMEFINISH(time, reps) \
@@ -266,17 +266,17 @@ atob(SECItem *ascii, SECItem *binary, PR
     SECStatus status;
     NSSBase64Decoder *cx;
     struct item_with_arena it;
     int len;
     binary->data = NULL;
     binary->len = 0;
     it.item = binary;
     it.arena = arena;
-    len = (strncmp(&ascii->data[ascii->len-2],"\r\n",2)) ? 
+    len = (strncmp((const char *)&ascii->data[ascii->len-2],"\r\n",2)) ?
            ascii->len : ascii->len-2;
     cx = NSSBase64Decoder_Create(get_binary, &it);
     status = NSSBase64Decoder_Update(cx, (const char *)ascii->data, len);
     status = NSSBase64Decoder_Destroy(cx, PR_FALSE);
     return status;
 }
 
 static PRInt32
@@ -291,19 +291,16 @@ output_ascii(void *arg, const char *obuf
     return nb;
 }
 
 static SECStatus
 btoa_file(SECItem *binary, PRFileDesc *outfile)
 {
     SECStatus status;
     NSSBase64Encoder *cx;
-    SECItem ascii;
-    ascii.data = NULL;
-    ascii.len = 0;
     if (binary->len == 0)
 	return SECSuccess;
     cx = NSSBase64Encoder_Create(output_ascii, outfile);
     status = NSSBase64Encoder_Update(cx, binary->data, binary->len);
     status = NSSBase64Encoder_Destroy(cx, PR_FALSE);
     status = PR_Write(outfile, "\r\n", 2);
     return status;
 }
@@ -349,19 +346,16 @@ char2_from_hex(unsigned char byteval, un
 
 void
 serialize_key(SECItem *it, int ni, PRFileDesc *file)
 {
     unsigned char len[4];
     int i;
     SECStatus status;
     NSSBase64Encoder *cx;
-    SECItem ascii;
-    ascii.data = NULL;
-    ascii.len = 0;
     cx = NSSBase64Encoder_Create(output_ascii, file);
     for (i=0; i<ni; i++, it++) {
 	len[0] = (it->len >> 24) & 0xff;
 	len[1] = (it->len >> 16) & 0xff;
 	len[2] = (it->len >>  8) & 0xff;
 	len[3] = (it->len	 & 0xff);
 	status = NSSBase64Encoder_Update(cx, len, 4);
 	status = NSSBase64Encoder_Update(cx, it->data, it->len);
--- a/security/nss/cmd/certutil/certutil.c
+++ b/security/nss/cmd/certutil/certutil.c
@@ -1101,17 +1101,17 @@ static void luE(enum usage_level ul, con
 static void luCommonDetailsAE()
 {
     FPS "%-20s Specify the nickname of the certificate to add\n",
         "   -n cert-name");
     FPS "%-20s Set the certificate trust attributes:\n",
         "   -t trustargs");
     FPS "%-25s trustargs is of the form x,y,z where x is for SSL, y is for S/MIME,\n", "");
     FPS "%-25s and z is for code signing. Use ,, for no explicit trust.\n", "");
-    FPS "%-25s p \t prohibited\n", "");
+    FPS "%-25s p \t prohibited (explicitly distrusted)\n", "");
     FPS "%-25s P \t trusted peer\n", "");
     FPS "%-25s c \t valid CA\n", "");
     FPS "%-25s T \t trusted CA to issue client certs (implies c)\n", "");
     FPS "%-25s C \t trusted CA to issue server certs (implies c)\n", "");
     FPS "%-25s u \t user cert\n", "");
     FPS "%-25s w \t send warning\n", "");
     FPS "%-25s g \t make step-up cert\n", "");
     FPS "%-20s Specify the password file\n",
--- a/security/nss/cmd/crlutil/crlutil.c
+++ b/security/nss/cmd/crlutil/crlutil.c
@@ -243,17 +243,18 @@ static SECStatus DeleteCRL (CERTCertDBHa
 	                "from the perm database (reason: %s)",
 	                name, SECU_Strerror(PORT_GetError()));
 	return SECFailure;
     }
     return (rv);
 }
 
 SECStatus ImportCRL (CERTCertDBHandle *certHandle, char *url, int type, 
-                     PRFileDesc *inFile, PRInt32 importOptions, PRInt32 decodeOptions)
+                     PRFileDesc *inFile, PRInt32 importOptions, PRInt32 decodeOptions,
+                     secuPWData *pwdata)
 {
     CERTSignedCrl *crl = NULL;
     SECItem crlDER;
     PK11SlotInfo* slot = NULL;
     int rv;
 #if defined(DEBUG_jp96085)
     PRIntervalTime starttime, endtime, elapsed;
     PRUint32 mins, secs, msecs;
@@ -267,16 +268,22 @@ SECStatus ImportCRL (CERTCertDBHandle *c
     if (rv != SECSuccess) {
 	SECU_PrintError(progName, "unable to read input file");
 	return (SECFailure);
     }
 
     decodeOptions |= CRL_DECODE_DONT_COPY_DER;
 
     slot = PK11_GetInternalKeySlot();
+
+    if (PK11_NeedLogin(slot)) {
+	rv = PK11_Authenticate(slot, PR_TRUE, pwdata);
+    if (rv != SECSuccess)
+	goto loser;
+    }
  
 #if defined(DEBUG_jp96085)
     starttime = PR_IntervalNow();
 #endif
     crl = PK11_ImportCRL(slot, &crlDER, url, type,
           NULL, importOptions, NULL, decodeOptions);
 #if defined(DEBUG_jp96085)
     endtime = PR_IntervalNow();
@@ -294,16 +301,17 @@ SECStatus ImportCRL (CERTCertDBHandle *c
 	if ( errString && PORT_Strlen (errString) == 0)
 	    SECU_PrintError (progName, 
 	        "CRL is not imported (error: input CRL is not up to date.)");
 	else    
 	    SECU_PrintError (progName, "unable to import CRL");
     } else {
 	SEC_DestroyCrl (crl);
     }
+  loser:
     if (slot) {
         PK11_FreeSlot(slot);
     }
     return (rv);
 }
 
 
 static CERTCertificate*
@@ -1045,17 +1053,17 @@ int main(int argc, char **argv)
 	/* Read in the private key info */
 	if (deleteCRL) 
 	    DeleteCRL (certHandle, nickName, crlType);
 	else if (listCRL) {
 	    rv = ListCRL (certHandle, nickName, crlType);
 	}
 	else if (importCRL) {
 	    rv = ImportCRL (certHandle, url, crlType, inFile, importOptions,
-			    decodeOptions);
+			    decodeOptions, &pwdata);
 	} else if (generateCRL || modifyCRL) {
 	    if (!inCrlInitFile)
 		inCrlInitFile = PR_STDIN;
 	    rv = GenerateCRL (certHandle, nickName, inCrlInitFile,
 			      inFile, outFile, ascii,  slotName,
 			      importOptions, alg, quiet,
 			      decodeOptions, url, &pwdata,
 			      modifyCRL);
@@ -1067,17 +1075,17 @@ int main(int argc, char **argv)
 #ifdef DEBUG
 	else if (test) {
 	    /* list and delete all CRLs */
 	    ListCRLNames (certHandle, crlType, PR_TRUE);
 	    /* list CRLs */
 	    ListCRLNames (certHandle, crlType, PR_FALSE);
 	    /* import CRL as a blob */
 	    rv = ImportCRL (certHandle, url, crlType, inFile, importOptions,
-			    decodeOptions);
+			    decodeOptions, &pwdata);
 	    /* list CRLs */
 	    ListCRLNames (certHandle, crlType, PR_FALSE);
 	}
 #endif    
     }
 
     CRLGEN_DestroyCrlGenParserLock();
 
--- a/security/nss/cmd/fipstest/fipstest.c
+++ b/security/nss/cmd/fipstest/fipstest.c
@@ -35,21 +35,21 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
 
 #include "secitem.h"
 #include "blapi.h"
-#include "nss.h"
+#include "nssutil.h"
 #include "secerr.h"
 #include "secder.h"
 #include "secdig.h"
-#include "keythi.h"
+#include "secoid.h"
 #include "ec.h"
 #include "hasht.h"
 #include "lowkeyi.h"
 #include "softoken.h"
 
 #if 0
 #include "../../lib/freebl/mpi/mpi.h"
 #endif
@@ -1967,20 +1967,20 @@ static CurveNameTagPair nameTagPair[] =
   { "secp128r2", SEC_OID_SECG_EC_SECP128R2},
 
   { "sect113r1", SEC_OID_SECG_EC_SECT113R1},
   { "sect113r2", SEC_OID_SECG_EC_SECT113R2},
   { "sect131r1", SEC_OID_SECG_EC_SECT131R1},
   { "sect131r2", SEC_OID_SECG_EC_SECT131R2},
 };
 
-static SECKEYECParams * 
+static SECItem * 
 getECParams(const char *curve)
 {
-    SECKEYECParams *ecparams;
+    SECItem *ecparams;
     SECOidData *oidData = NULL;
     SECOidTag curveOidTag = SEC_OID_UNKNOWN; /* default */
     int i, numCurves;
 
     if (curve != NULL) {
         numCurves = sizeof(nameTagPair)/sizeof(CurveNameTagPair);
 	for (i = 0; ((i < numCurves) && (curveOidTag == SEC_OID_UNKNOWN)); 
 	     i++) {
@@ -2041,17 +2041,17 @@ ecdsa_keypair_test(char *reqfn)
 	if (buf[0] == '#' || buf[0] == '\n') {
 	    fputs(buf, ecdsaresp);
 	    continue;
 	}
 	/* [X-ddd] */
 	if (buf[0] == '[') {
 	    const char *src;
 	    char *dst;
-	    SECKEYECParams *encodedparams;
+	    SECItem *encodedparams;
 
 	    src = &buf[1];
 	    dst = &curve[4];
 	    *dst++ = tolower(*src);
 	    src += 2;  /* skip the hyphen */
 	    *dst++ = *src++;
 	    *dst++ = *src++;
 	    *dst++ = *src++;
@@ -2147,17 +2147,17 @@ ecdsa_pkv_test(char *reqfn)
 	if (buf[0] == '#' || buf[0] == '\n') {
 	    fputs(buf, ecdsaresp);
 	    continue;
 	}
 	/* [X-ddd] */
 	if (buf[0] == '[') {
 	    const char *src;
 	    char *dst;
-	    SECKEYECParams *encodedparams;
+	    SECItem *encodedparams;
 
 	    src = &buf[1];
 	    dst = &curve[4];
 	    *dst++ = tolower(*src);
 	    src += 2;  /* skip the hyphen */
 	    *dst++ = *src++;
 	    *dst++ = *src++;
 	    *dst++ = *src++;
@@ -2268,17 +2268,17 @@ ecdsa_siggen_test(char *reqfn)
 	if (buf[0] == '#' || buf[0] == '\n') {
 	    fputs(buf, ecdsaresp);
 	    continue;
 	}
 	/* [X-ddd] */
 	if (buf[0] == '[') {
 	    const char *src;
 	    char *dst;
-	    SECKEYECParams *encodedparams;
+	    SECItem *encodedparams;
 
 	    src = &buf[1];
 	    dst = &curve[4];
 	    *dst++ = tolower(*src);
 	    src += 2;  /* skip the hyphen */
 	    *dst++ = *src++;
 	    *dst++ = *src++;
 	    *dst++ = *src++;
@@ -2411,17 +2411,17 @@ ecdsa_sigver_test(char *reqfn)
 	if (buf[0] == '#' || buf[0] == '\n') {
 	    fputs(buf, ecdsaresp);
 	    continue;
 	}
 	/* [X-ddd] */
 	if (buf[0] == '[') {
 	    const char *src;
 	    char *dst;
-	    SECKEYECParams *encodedparams;
+	    SECItem *encodedparams;
 	    ECParams *ecparams;
 
 	    src = &buf[1];
 	    dst = &curve[4];
 	    *dst++ = tolower(*src);
 	    src += 2;  /* skip the hyphen */
 	    *dst++ = *src++;
 	    *dst++ = *src++;
@@ -4230,17 +4230,17 @@ loser:
     if(pqg != NULL) {
         PQG_DestroyParams(pqg);
         pqg = NULL;
     }
     if(vfy != NULL) {
         PQG_DestroyVerify(vfy);
         vfy = NULL;
     }
-    if (dsaKey) {
+    if (dsakey) {
         PORT_FreeArena(dsakey->params.arena, PR_TRUE);
         dsakey = NULL;
     }
 }
 
  /*
  * Perform the DSA Signature Verification Test.
  *
@@ -4935,17 +4935,17 @@ loser:
     if (rsaBlapiPublicKey.publicExponent.data) { /* e */
         SECITEM_ZfreeItem(&rsaBlapiPublicKey.publicExponent, PR_FALSE);
     }
 }
 
 int main(int argc, char **argv)
 {
     if (argc < 2) exit (-1);
-    NSS_NoDB_Init(NULL);
+
     /*************/
     /*   TDEA    */
     /*************/
     if (strcmp(argv[1], "tdea") == 0) {
         /* argv[2]=kat|mmt|mct argv[3]=ecb|cbc argv[4]=<test name>.req */
         if (strcmp(argv[2], "kat") == 0) {
             /* Known Answer Test (KAT) */
             tdea_kat_mmt(argv[4]);     
--- a/security/nss/cmd/lib/manifest.mn
+++ b/security/nss/cmd/lib/manifest.mn
@@ -47,14 +47,13 @@ PRIVATE_EXPORTS	= secutil.h \
 		  pk11table.h \
 		  $(NULL)
 
 CSRCS		= secutil.c \
 		secpwd.c    \
 		derprint.c \
 		moreoids.c \
 		pppolicy.c \
-		secerror.c \
 		ffs.c \
 		pk11table.c \
 		$(NULL)
 
 NO_MD_RELEASE	= 1
deleted file mode 100644
--- a/security/nss/cmd/lib/secerror.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1994-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-#include "prtypes.h"
-#include "nssutil.h"
-
-/* Returns a UTF-8 encoded constant error string for "errNum".
- * Returns NULL if errNum is unknown.
- */
-const char *
-SECU_Strerror(PRErrorCode errNum) {
-    return NSS_Strerror(errNum, formatSimple);
-}
--- a/security/nss/cmd/lib/secutil.c
+++ b/security/nss/cmd/lib/secutil.c
@@ -3674,18 +3674,18 @@ SECU_displayVerifyLog(FILE *outfile, CER
 			do {
 			    fprintf(outfile, "%s\n", emailAddr);
 			    emailAddr = CERT_GetNextEmailAddress(node->cert,
 			                                         emailAddr);
 			} while (emailAddr);
 		    }
 		}
 	    }
-	    fprintf(outfile,"  ERROR %ld: %s\n", node->error,
-						SECU_Strerror(node->error));
+	    fprintf(outfile, "  ERROR %ld: %s\n", node->error,
+			    SECU_Strerror(node->error));
 	    errstr = NULL;
 	    switch (node->error) {
 	    case SEC_ERROR_INADEQUATE_KEY_USAGE:
 		flags = (unsigned int)node->arg;
 		switch (flags) {
 		case KU_DIGITAL_SIGNATURE:
 		    errstr = "Cert cannot sign.";
 		    break;
--- a/security/nss/cmd/lib/secutil.h
+++ b/security/nss/cmd/lib/secutil.h
@@ -33,16 +33,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 #ifndef _SEC_UTIL_H_
 #define _SEC_UTIL_H_
 
 #include "seccomon.h"
 #include "secitem.h"
+#include "secport.h"
 #include "prerror.h"
 #include "base64.h"
 #include "key.h"
 #include "secpkcs7.h"
 #include "secasn1.h"
 #include "secder.h"
 #include <stdio.h>
 
@@ -58,16 +59,18 @@
 #define NS_CERTREQ_TRAILER "-----END NEW CERTIFICATE REQUEST-----"
 
 #define NS_CERT_HEADER "-----BEGIN CERTIFICATE-----"
 #define NS_CERT_TRAILER "-----END CERTIFICATE-----"
 
 #define NS_CRL_HEADER  "-----BEGIN CRL-----"
 #define NS_CRL_TRAILER "-----END CRL-----"
 
+#define SECU_Strerror PORT_ErrorToString
+
 #ifdef SECUTIL_NEW
 typedef int (*SECU_PPFunc)(PRFileDesc *out, SECItem *item, 
                            char *msg, int level);
 #else
 typedef int (*SECU_PPFunc)(FILE *out, SECItem *item, char *msg, int level);
 #endif
 
 typedef struct {
@@ -166,19 +169,16 @@ SECU_GetClientAuthData(void *arg, PRFile
 		       struct SECKEYPrivateKeyStr **pRetKey);
 
 /* print out an error message */
 extern void SECU_PrintError(char *progName, char *msg, ...);
 
 /* print out a system error message */
 extern void SECU_PrintSystemError(char *progName, char *msg, ...);
 
-/* Return informative error string */
-extern const char * SECU_Strerror(PRErrorCode errNum);
-
 /* revalidate the cert and print information about cert verification
  * failure at time == now */
 extern void
 SECU_printCertProblems(FILE *outfile, CERTCertDBHandle *handle, 
 	CERTCertificate *cert, PRBool checksig, 
 	SECCertificateUsage certUsage, void *pinArg, PRBool verbose);
 
 /* revalidate the cert and print information about cert verification
--- a/security/nss/cmd/strsclnt/strsclnt.c
+++ b/security/nss/cmd/strsclnt/strsclnt.c
@@ -1185,17 +1185,21 @@ client_main(
     /* do SSL configuration. */
 
     rv = SSL_OptionSet(model_sock, SSL_SECURITY,
         !(disableSSL2 && disableSSL3 && disableTLS));
     if (rv < 0) {
 	errExit("SSL_OptionSet SSL_SECURITY");
     }
 
-    /* disabling SSL2 compatible hellos also disables SSL2 */
+    rv = SSL_OptionSet(model_sock, SSL_ENABLE_SSL2, !disableSSL2);
+    if (rv != SECSuccess) {
+	errExit("error enabling SSLv2 ");
+    }
+
     rv = SSL_OptionSet(model_sock, SSL_V2_COMPATIBLE_HELLO, !disableSSL2);
     if (rv != SECSuccess) {
 	errExit("error enabling SSLv2 compatible hellos ");
     }
 
     rv = SSL_OptionSet(model_sock, SSL_ENABLE_SSL3, !disableSSL3);
     if (rv != SECSuccess) {
 	errExit("error enabling SSLv3 ");
--- a/security/nss/cmd/tstclnt/tstclnt.c
+++ b/security/nss/cmd/tstclnt/tstclnt.c
@@ -828,20 +828,19 @@ int main(int argc, char **argv)
     }
 
     rv = SSL_OptionSet(s, SSL_ENABLE_TLS, !disableTLS);
     if (rv != SECSuccess) {
 	SECU_PrintError(progName, "error enabling TLS ");
 	return 1;
     }
 
-    /* disable ssl2 and ssl2-compatible client hellos. */
     rv = SSL_OptionSet(s, SSL_V2_COMPATIBLE_HELLO, !disableSSL2);
     if (rv != SECSuccess) {
-	SECU_PrintError(progName, "error disabling v2 compatibility");
+	SECU_PrintError(progName, "error enabling SSLv2 compatible hellos ");
 	return 1;
     }
 
     /* enable PKCS11 bypass */
     rv = SSL_OptionSet(s, SSL_BYPASS_PKCS11, bypassPKCS11);
     if (rv != SECSuccess) {
 	SECU_PrintError(progName, "error enabling PKCS11 bypass");
 	return 1;
--- a/security/nss/lib/certdb/certi.h
+++ b/security/nss/lib/certdb/certi.h
@@ -31,17 +31,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 /*
  * certi.h - private data structures for the certificate library
  *
- * $Id: certi.h,v 1.35 2011/01/29 22:17:20 nelson%bolyard.com Exp $
+ * $Id: certi.h,v 1.36 2011/09/14 23:16:14 wtc%google.com Exp $
  */
 #ifndef _CERTI_H_
 #define _CERTI_H_
 
 #include "certt.h"
 #include "nssrwlkt.h"
 
 /*
@@ -392,10 +392,24 @@ SECStatus cert_ReleaseNamedCRLCache(Name
 /* This is private for now.  Maybe shoule be public. */
 CERTGeneralName *
 cert_GetSubjectAltNameList(CERTCertificate *cert, PRArenaPool *arena);
 
 /* Count DNS names and IP addresses in a list of GeneralNames */
 PRUint32
 cert_CountDNSPatterns(CERTGeneralName *firstName);
 
+/*
+ * returns the trust status of the leaf certificate based on usage.
+ * If the leaf is explicitly untrusted, this function will fail and 
+ * failedFlags will be set to the trust bit value that lead to the failure.
+ * If the leaf is trusted, isTrusted is set to true and the function returns 
+ * SECSuccess. This function does not check if the cert is fit for a 
+ * particular usage.
+ */
+SECStatus
+cert_CheckLeafTrust(CERTCertificate *cert,
+                    SECCertUsage usage, 
+                    unsigned int *failedFlags,
+                    PRBool *isTrusted);
+
 #endif /* _CERTI_H_ */
 
--- a/security/nss/lib/certhigh/certvfy.c
+++ b/security/nss/lib/certhigh/certvfy.c
@@ -383,16 +383,25 @@ cert_VerifyCertChainOld(CERTCertDBHandle
       case certUsageObjectSigner:
       case certUsageVerifyCA:
       case certUsageAnyCA:
       case certUsageStatusResponder:
 	if ( CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags,
 					   &trustType) != SECSuccess ) {
 	    PORT_Assert(0);
 	    EXIT_IF_NOT_LOGGING(log);
+	    /* XXX continuing with requiredFlags = 0 seems wrong.  It'll
+	     * cause the following test to be true incorrectly:
+	     *   flags = SEC_GET_TRUST_FLAGS(issuerCert->trust, trustType);
+	     *   if (( flags & requiredFlags ) == requiredFlags) {
+	     *       rv = rvFinal;
+	     *       goto done;
+	     *   }
+	     * There are three other instances of this problem.
+	     */
 	    requiredFlags = 0;
 	    trustType = trustSSL;
 	}
 	break;
       default:
 	PORT_Assert(0);
 	EXIT_IF_NOT_LOGGING(log);
 	requiredFlags = 0;
@@ -576,20 +585,20 @@ cert_VerifyCertChainOld(CERTCertDBHandle
 	            rv = rvFinal; 
 	            goto done;
 	        }
 	        if (flags & CERTDB_VALID_CA) {
 	            validCAOverride = PR_TRUE;
 	        }
 		/* is it explicitly distrusted? */
 		if ((flags & CERTDB_TERMINAL_RECORD) && 
-			((flags & (CERTDB_VALID_CA|CERTDB_TRUSTED)) == 0)) {
+			((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0)) {
 		    /* untrusted -- the cert is explicitly untrusted, not
 		     * just that it doesn't chain to a trusted cert */
-		    PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
+		    PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER);
 		    LOG_ERROR_OR_EXIT(log,issuerCert,count+1,flags);
 		}
 	    } else {
                 /* Check if we have any valid trust when cheching for
                  * certUsageAnyCA or certUsageStatusResponder. */
                 for (trustType = trustSSL; trustType < trustTypeNone;
                      trustType++) {
                     flags = SEC_GET_TRUST_FLAGS(issuerCert->trust, trustType);
@@ -604,20 +613,20 @@ cert_VerifyCertChainOld(CERTCertDBHandle
 		 * bit to allow this usage to return trusted. Only if none of
 		 * the trust bits are on do we check to see if the cert is 
 		 * untrusted */
                 for (trustType = trustSSL; trustType < trustTypeNone;
                      trustType++) {
                     flags = SEC_GET_TRUST_FLAGS(issuerCert->trust, trustType);
 		    /* is it explicitly distrusted? */
 		    if ((flags & CERTDB_TERMINAL_RECORD) && 
-			((flags & (CERTDB_VALID_CA|CERTDB_TRUSTED)) == 0)) {
+			((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0)) {
 			/* untrusted -- the cert is explicitly untrusted, not
 			 * just that it doesn't chain to a trusted cert */
-			PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
+			PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER);
 			LOG_ERROR_OR_EXIT(log,issuerCert,count+1,flags);
 		    }
                 }
             }
         }
 
 	if (!validCAOverride) {
 	    /*
@@ -737,17 +746,17 @@ CERT_VerifyCACertForUsage(CERTCertDBHand
 		void *wincx, CERTVerifyLog *log)
 {
     SECTrustType trustType;
     CERTBasicConstraints basicConstraint;
     PRBool isca;
     PRBool validCAOverride = PR_FALSE;
     SECStatus rv;
     SECStatus rvFinal = SECSuccess;
-    int flags;
+    unsigned int flags;
     unsigned int caCertType;
     unsigned int requiredCAKeyUsage;
     unsigned int requiredFlags;
     CERTCertificate *issuerCert;
 
 
     if (CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_TRUE,
 					 &requiredCAKeyUsage,
@@ -834,30 +843,30 @@ CERT_VerifyCACertForUsage(CERTCertDBHand
 	     * For years, NSS has treated this as trusted, 
 	     * but it seems incorrect.
 	     */
 	    rv = rvFinal; 
 	    goto done;
         }
 
 	/*
-	 * check the trust parms of the issuer
+	 * check the trust params of the issuer
 	 */
 	flags = SEC_GET_TRUST_FLAGS(cert->trust, trustType);
 	if ( ( flags & requiredFlags ) == requiredFlags) {
 	    /* we found a trusted one, so return */
 	    rv = rvFinal; 
 	    goto done;
 	}
 	if (flags & CERTDB_VALID_CA) {
 	    validCAOverride = PR_TRUE;
 	}
 	/* is it explicitly distrusted? */
 	if ((flags & CERTDB_TERMINAL_RECORD) && 
-		((flags & (CERTDB_VALID_CA|CERTDB_TRUSTED)) == 0)) {
+		((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0)) {
 	    /* untrusted -- the cert is explicitly untrusted, not
 	     * just that it doesn't chain to a trusted cert */
 	    PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
 	    LOG_ERROR_OR_EXIT(log,cert,0,flags);
 	}
     }
     if (!validCAOverride) {
 	/*
@@ -965,21 +974,19 @@ cert_CheckLeafTrust(CERTCertificate *cer
 		    /* don't trust this cert */
 		    *failedFlags = flags;
 		    return SECFailure;
 		}
 	    }
 	    break;
 	  case certUsageSSLCA:
 	    flags = cert->trust->sslFlags;
-	    /* we probably should also not explicitly fail the cert 
-	     * if only the trusted DELEGATOR flag is set */
 	    if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is 
 						    * authoritative */
-		if (( flags & CERTDB_TRUSTED_CA ) == 0) {	
+		if (( flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA) ) == 0) {	
 		    /* don't trust this cert */
 		    *failedFlags = flags;
 		    return SECFailure;
 		}
 	    }
 	    break;
 	  case certUsageEmailSigner:
 	  case certUsageEmailRecipient:
@@ -1036,34 +1043,35 @@ cert_CheckLeafTrust(CERTCertificate *cer
 	    }
 	    /* fall through to test distrust */
 	  case certUsageAnyCA:
 	  case certUsageUserCertImport:
 	    /* do we distrust these certs explicitly */
 	    flags = cert->trust->sslFlags;
 	    if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is 
 						    * authoritative */
-		if ((flags & CERTDB_TRUSTED_CA) == 0) {
+		if ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0) {
 		    *failedFlags = flags;
 		    return SECFailure;
 		}
 	    }
 	    flags = cert->trust->emailFlags;
 	    if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is 
 						    * authoritative */
-		if ((flags & CERTDB_TRUSTED_CA) == 0) {
+		if ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0) {
 		    *failedFlags = flags;
 		    return SECFailure;
 		}
 	    }
+	    /* fall through */
 	  case certUsageProtectedObjectSigner:
 	    flags = cert->trust->objectSigningFlags;
 	    if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is 
 						    * authoritative */
-		if ((flags & CERTDB_TRUSTED_CA) == 0) {
+		if ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0) {
 		    *failedFlags = flags;
 		    return SECFailure;
 		}
 	    }
 	    break;
 	}
     }
     return SECSuccess;
@@ -1191,18 +1199,17 @@ CERT_VerifyCertificate(CERTCertDBHandle 
 
 	rv = cert_CheckLeafTrust(cert, certUsage, &flags, &trusted);
 	if (rv == SECFailure) {
 	    if (PR_TRUE == requiredUsage) {
 		PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
 	    }
 	    LOG_ERROR(log, cert, 0, flags);
 	    INVALID_USAGE();
-	}
-	if (trusted) {
+	} else if (trusted) {
 	    VALID_USAGE();
 	}
 
 	if (PR_TRUE == revoked || PR_TRUE == sigerror) {
 	    INVALID_USAGE();
 	}
 
         rv = cert_VerifyCertChain(handle, cert,
@@ -1323,18 +1330,17 @@ CERT_VerifyCert(CERTCertDBHandle *handle
 	PORT_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE);
 	LOG_ERROR_OR_EXIT(log,cert,0,requiredCertType);
     }
 
     rv = cert_CheckLeafTrust(cert,certUsage, &flags, &trusted);
     if (rv  == SECFailure) {
 	PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
 	LOG_ERROR_OR_EXIT(log,cert,0,flags);
-    }
-    if (trusted) {
+    } else if (trusted) {
 	goto winner;
     }
 
 
     rv = CERT_VerifyCertChain(handle, cert, checkSig, certUsage,
 			      t, wincx, log);
     if (rv != SECSuccess) {
 	EXIT_IF_NOT_LOGGING(log);
--- a/security/nss/lib/ckfw/builtins/certdata.c
+++ b/security/nss/lib/ckfw/builtins/certdata.c
@@ -30,17 +30,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 #ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile: certdata.txt,v $ $Revision: 1.75 $ $Date: 2011/08/01 06:33:47 $""; @(#) $RCSfile: certdata.perl,v $ $Revision: 1.13 $ $Date: 2010/03/26 22:06:47 $";
+static const char CVS_ID[] = "@(#) $RCSfile: certdata.c,v $ $Revision: 1.82 $ $Date: 2011/09/02 19:40:56 $""; @(#) $RCSfile: certdata.c,v $ $Revision: 1.82 $ $Date: 2011/09/02 19:40:56 $";
 #endif /* DEBUG */
 
 #ifndef BUILTINS_H
 #include "builtins.h"
 #endif /* BUILTINS_H */
 
 static const CK_BBOOL ck_false = CK_FALSE;
 static const CK_BBOOL ck_true = CK_TRUE;
@@ -1078,17 +1078,17 @@ static const CK_ATTRIBUTE_TYPE nss_built
 #ifdef DEBUG
 static const NSSItem nss_builtins_items_0 [] = {
   { (void *)&cko_data, (PRUint32)sizeof(CK_OBJECT_CLASS) },
   { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) },
   { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) },
   { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) },
   { (void *)"CVS ID", (PRUint32)7 },
   { (void *)"NSS", (PRUint32)4 },
-  { (void *)"@(#) $RCSfile: certdata.txt,v $ $Revision: 1.75 $ $Date: 2011/08/01 06:33:47 $""; @(#) $RCSfile: certdata.perl,v $ $Revision: 1.13 $ $Date: 2010/03/26 22:06:47 $", (PRUint32)160 }
+  { (void *)"@(#) $RCSfile: certdata.c,v $ $Revision: 1.82 $ $Date: 2011/09/02 19:40:56 $""; @(#) $RCSfile: certdata.c,v $ $Revision: 1.82 $ $Date: 2011/09/02 19:40:56 $", (PRUint32)160 }
 };
 #endif /* DEBUG */
 static const NSSItem nss_builtins_items_1 [] = {
   { (void *)&cko_nss_builtin_root_list, (PRUint32)sizeof(CK_OBJECT_CLASS) },
   { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) },
   { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) },
   { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) },
   { (void *)"Mozilla Builtin Roots", (PRUint32)22 }
--- a/security/nss/lib/ckfw/builtins/certdata.txt
+++ b/security/nss/lib/ckfw/builtins/certdata.txt
@@ -29,17 +29,17 @@
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
-CVS_ID "@(#) $RCSfile: certdata.txt,v $ $Revision: 1.75 $ $Date: 2011/08/01 06:33:47 $"
+CVS_ID "@(#) $RCSfile: certdata.txt,v $ $Revision: 1.79 $ $Date: 2011/09/02 19:40:56 $"
 
 #
 # certdata.txt
 #
 # This file contains the object definitions for the certs and other
 # information "built into" NSS.
 #
 # Object definitions:
--- a/security/nss/lib/dev/ckhelper.c
+++ b/security/nss/lib/dev/ckhelper.c
@@ -30,17 +30,17 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.41 $ $Date: 2011/04/13 00:10:25 $";
+static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.42 $ $Date: 2011/09/14 00:28:48 $";
 #endif /* DEBUG */
 
 #include "pkcs11.h"
 
 #ifndef DEVM_H
 #include "devm.h"
 #endif /* DEVM_H */
 
@@ -432,26 +432,28 @@ nssCryptokiTrust_GetAttributes (
     CK_BBOOL isToken = PR_FALSE;
     CK_BBOOL stepUp = PR_FALSE;
     CK_TRUST saTrust = CKT_NSS_TRUST_UNKNOWN;
     CK_TRUST caTrust = CKT_NSS_TRUST_UNKNOWN;
     CK_TRUST epTrust = CKT_NSS_TRUST_UNKNOWN;
     CK_TRUST csTrust = CKT_NSS_TRUST_UNKNOWN;
     CK_ATTRIBUTE_PTR attr;
     CK_ATTRIBUTE trust_template[7];
+    CK_ATTRIBUTE_PTR sha1_hash_attr;
     CK_ULONG trust_size;
 
     /* Use the trust object to find the trust settings */
     NSS_CK_TEMPLATE_START(trust_template, attr, trust_size);
     NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TOKEN,                  isToken);
     NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_SERVER_AUTH,      saTrust);
     NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CLIENT_AUTH,      caTrust);
     NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_EMAIL_PROTECTION, epTrust);
     NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING,     csTrust);
     NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_STEP_UP_APPROVED, stepUp);
+    sha1_hash_attr = attr;
     NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_SHA1_HASH,     sha1_hash);
     NSS_CK_TEMPLATE_FINISH(trust_template, attr, trust_size);
 
     status = nssToken_GetCachedObjectAttributes(trustObject->token, NULL,
                                                 trustObject, 
                                                 CKO_NSS_TRUST,
                                                 trust_template, trust_size);
     if (status != PR_SUCCESS) {
@@ -468,16 +470,21 @@ nssCryptokiTrust_GetAttributes (
 	                                   trust_template, trust_size,
 	                                   NULL, session, slot);
 	nssSlot_Destroy(slot);
 	if (status != PR_SUCCESS) {
 	    return status;
 	}
     }
 
+    if (sha1_hash_attr->ulValueLen == -1) {
+	/* The trust object does not have the CKA_CERT_SHA1_HASH attribute. */
+	sha1_hash_attr->ulValueLen = 0;
+    }
+    sha1_hash->size = sha1_hash_attr->ulValueLen;
     *serverAuth = get_nss_trust(saTrust);
     *clientAuth = get_nss_trust(caTrust);
     *emailProtection = get_nss_trust(epTrust);
     *codeSigning = get_nss_trust(csTrust);
     *stepUpApproved = stepUp;
     return PR_SUCCESS;
 }
 
--- a/security/nss/lib/freebl/blapi.h
+++ b/security/nss/lib/freebl/blapi.h
@@ -32,17 +32,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: blapi.h,v 1.41 2010/12/06 17:22:49 kaie%kuix.de Exp $ */
+/* $Id: blapi.h,v 1.42 2011/10/04 22:05:53 wtc%google.com Exp $ */
 
 #ifndef _BLAPI_H_
 #define _BLAPI_H_
 
 #include "blapit.h"
 #include "hasht.h"
 #include "alghmac.h"
 
@@ -1252,23 +1252,16 @@ PRNGTEST_Reseed(const PRUint8 *entropy, 
 
 extern SECStatus
 PRNGTEST_Generate(PRUint8 *bytes, unsigned int bytes_len, 
 		  const PRUint8 *additional, unsigned int additional_len);
 
 extern SECStatus
 PRNGTEST_Uninstantiate(void);
 
-/*
- * Mask generation function MGF1
- */
-extern SECStatus
-MGF1(HASH_HashType hashAlg, unsigned char *mask, unsigned int maskLen,
-     const unsigned char *mgfSeed, unsigned int mgfSeedLen);
-
 /* Generate PQGParams and PQGVerify structs.
  * Length of seed and length of h both equal length of P. 
  * All lengths are specified by "j", according to the table above.
  */
 extern SECStatus
 PQG_ParamGen(unsigned int j, 	   /* input : determines length of P. */
              PQGParams **pParams,  /* output: P Q and G returned here */
 	     PQGVerify **pVfy);    /* output: counter and seed. */
--- a/security/nss/lib/freebl/ec.c
+++ b/security/nss/lib/freebl/ec.c
@@ -708,16 +708,37 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *k
 	printf("k : %s \n", mpstr);
         mp_tohex(&n, mpstr);
 	printf("n : %s \n", mpstr);
 #endif
 	PORT_SetError(SEC_ERROR_NEED_RANDOM);
 	goto cleanup;
     }
 
+    /*
+    ** We do not want timing information to leak the length of k,
+    ** so we compute k*G using an equivalent scalar of fixed
+    ** bit-length.
+    ** Fix based on patch for ECDSA timing attack in the paper
+    ** by Billy Bob Brumley and Nicola Tuveri at
+    **   http://eprint.iacr.org/2011/232
+    **
+    ** How do we convert k to a value of a fixed bit-length?
+    ** k starts off as an integer satisfying 0 <= k < n.  Hence,
+    ** n <= k+n < 2n, which means k+n has either the same number
+    ** of bits as n or one more bit than n.  If k+n has the same
+    ** number of bits as n, the second addition ensures that the
+    ** final value has exactly one more bit than n.  Thus, we
+    ** always end up with a value that exactly one more bit than n.
+    */
+    CHECK_MPI_OK( mp_add(&k, &n, &k) );
+    if (mpl_significant_bits(&k) <= mpl_significant_bits(&n)) {
+	CHECK_MPI_OK( mp_add(&k, &n, &k) );
+    }
+
     /* 
     ** ANSI X9.62, Section 5.3.2, Step 2
     **
     ** Compute kG
     */
     kGpoint.len = 2*flen + 1;
     kGpoint.data = PORT_Alloc(2*flen + 1);
     if ((kGpoint.data == NULL) ||
--- a/security/nss/lib/freebl/ecl/ecp_mont.c
+++ b/security/nss/lib/freebl/ecl/ecp_mont.c
@@ -48,17 +48,16 @@
 #include <stdio.h>
 
 /* Construct a generic GFMethod for arithmetic over prime fields with
  * irreducible irr. */
 GFMethod *
 GFMethod_consGFp_mont(const mp_int *irr)
 {
 	mp_err res = MP_OKAY;
-	int i;
 	GFMethod *meth = NULL;
 	mp_mont_modulus *mmm;
 
 	meth = GFMethod_consGFp(irr);
 	if (meth == NULL)
 		return NULL;
 
 	mmm = (mp_mont_modulus *) malloc(sizeof(mp_mont_modulus));
--- a/security/nss/lib/freebl/ldvector.c
+++ b/security/nss/lib/freebl/ldvector.c
@@ -32,17 +32,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: ldvector.c,v 1.28 2010/12/06 17:22:49 kaie%kuix.de Exp $ */
+/* $Id: ldvector.c,v 1.29 2011/10/04 22:05:53 wtc%google.com Exp $ */
 
 #ifdef FREEBL_NO_DEPEND
 extern int FREEBL_InitStubs(void);
 #endif
 
 #include "loader.h"
 #include "alghmac.h"
 
@@ -268,17 +268,16 @@ static const struct FREEBLVectorStr vect
 
     JPAKE_Sign,
     JPAKE_Verify,
     JPAKE_Round2,
     JPAKE_Final,
 
     /* End of Version 3.012 */
 
-    MGF1,
     TLS_P_hash,
     SHA224_NewContext,
     SHA224_DestroyContext,
     SHA224_Begin,
     SHA224_Update,
     SHA224_End,
     SHA224_HashBuf,
     SHA224_Hash,
--- a/security/nss/lib/freebl/loader.c
+++ b/security/nss/lib/freebl/loader.c
@@ -32,17 +32,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: loader.c,v 1.53 2011/01/15 19:54:49 nelson%bolyard.com Exp $ */
+/* $Id: loader.c,v 1.54 2011/10/04 22:05:53 wtc%google.com Exp $ */
 
 #include "loader.h"
 #include "prmem.h"
 #include "prerror.h"
 #include "prinit.h"
 #include "prenv.h"
 
 static const char* default_name =
@@ -1753,25 +1753,16 @@ JPAKE_Final(PLArenaPool * arena, const S
             const SECItem * x2, const SECItem * gx4, const SECItem * x2s,
             const SECItem * B, SECItem * K)
 {
     if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
         return SECFailure;
     return (vector->p_JPAKE_Final)(arena, p, q, x2, gx4, x2s, B, K);
 }
 
-SECStatus
-MGF1(HASH_HashType hashAlg, unsigned char *mask, unsigned int maskLen,
-     const unsigned char *mgfSeed, unsigned int mgfSeedLen)
-{
-    if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
-	return SECFailure;
-    return (vector->p_MGF1)(hashAlg, mask, maskLen, mgfSeed, mgfSeedLen);
-}
-
 SECStatus 
 TLS_P_hash(HASH_HashType hashAlg, const SECItem *secret, const char *label,
            SECItem *seed, SECItem *result, PRBool isFIPS)
 {
   if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
       return SECFailure;
   return (vector->p_TLS_P_hash)(hashAlg, secret, label, seed, result, isFIPS);
 }
--- a/security/nss/lib/freebl/loader.h
+++ b/security/nss/lib/freebl/loader.h
@@ -32,17 +32,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: loader.h,v 1.34 2011/03/29 15:12:44 wtc%google.com Exp $ */
+/* $Id: loader.h,v 1.35 2011/10/04 22:05:53 wtc%google.com Exp $ */
 
 #ifndef _LOADER_H_
 #define _LOADER_H_ 1
 
 #include "blapi.h"
 
 #define FREEBL_VERSION 0x030D
 
@@ -565,20 +565,16 @@ struct FREEBLVectorStr {
 
  SECStatus (*p_JPAKE_Final)(PLArenaPool * arena, const SECItem * p,
                             const SECItem  *q, const SECItem * x2,
                             const SECItem * gx4, const SECItem * x2s,
                             const SECItem * B, SECItem * K);
 
   /* Version 3.012 came to here */
 
- SECStatus (* p_MGF1)(HASH_HashType hashAlg,
-                      unsigned char *mask, unsigned int maskLen,
-                      const unsigned char *mgfSeed, unsigned int mgfSeedLen);
-
  SECStatus (* p_TLS_P_hash)(HASH_HashType hashAlg,
                             const SECItem *secret,
                             const char *label,
                             SECItem *seed,
                             SECItem *result,
                             PRBool isFIPS);
 
  SHA224Context *(*p_SHA224_NewContext)(void);
--- a/security/nss/lib/freebl/manifest.mn
+++ b/security/nss/lib/freebl/manifest.mn
@@ -123,17 +123,16 @@ CSRCS = \
 	freeblver.c \
 	ldvector.c \
 	sysrand.c \
 	$(SHA_SRCS) \
 	md2.c \
 	md5.c \
 	sha512.c \
 	alghmac.c \
-	mgf1.c \
 	rawhash.c \
 	alg2268.c \
 	arcfour.c \
 	arcfive.c \
 	desblapi.c \
 	des.c \
 	drbg.c \
 	rijndael.c \
deleted file mode 100644
--- a/security/nss/lib/freebl/mgf1.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * mgf1.c - implementation of MGF1 as defined in PKCS #1 v2.1 / RFC 3447
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1994-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Hanno Boeck <hanno@hboeck.de>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-/* $Id: mgf1.c,v 1.2 2010/07/22 23:09:46 wtc%google.com Exp $ */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include "blapi.h"
-#include "hasht.h"
-
-SECStatus
-MGF1(HASH_HashType hashAlg, unsigned char *mask, unsigned int maskLen,
-     const unsigned char *mgfSeed, unsigned int mgfSeedLen)
-{
-    unsigned int digestLen;
-    PRUint32 counter, rounds;
-    unsigned char *tempHash, *temp;
-    const SECHashObject *hash;
-    void *hashContext;
-    unsigned char C[4];
-
-    hash = HASH_GetRawHashObject(hashAlg);
-    if (hash == NULL)
-        return SECFailure;
-
-    hashContext = (*hash->create)();
-    rounds = (maskLen + hash->length - 1) / hash->length;
-    for (counter = 0; counter < rounds; counter++) {
-        C[0] = (unsigned char)((counter >> 24) & 0xff);
-        C[1] = (unsigned char)((counter >> 16) & 0xff);
-        C[2] = (unsigned char)((counter >> 8) & 0xff);
-        C[3] = (unsigned char)(counter & 0xff);
-
-        /* This could be optimized when the clone functions in
-         * rawhash.c are implemented. */
-        (*hash->begin)(hashContext);
-        (*hash->update)(hashContext, mgfSeed, mgfSeedLen); 
-        (*hash->update)(hashContext, C, sizeof C);
-
-        tempHash = mask + counter * hash->length;
-        if (counter != (rounds-1)) {
-            (*hash->end)(hashContext, tempHash, &digestLen, hash->length);
-        } else { /* we're in the last round and need to cut the hash */
-            temp = PORT_Alloc(hash->length);
-            (*hash->end)(hashContext, temp, &digestLen, hash->length);
-            PORT_Memcpy(tempHash, temp, maskLen - counter * hash->length);
-            PORT_Free(temp);
-        }
-    }
-    (*hash->destroy)(hashContext, PR_TRUE);
-
-    return SECSuccess;
-}
--- a/security/nss/lib/freebl/mpi/mpcpucache.c
+++ b/security/nss/lib/freebl/mpi/mpcpucache.c
@@ -655,19 +655,23 @@ s_mpi_is_sse2()
     int manufacturer = MAN_UNKNOWN;
     int i;
     char string[13];
 
     if (is386() || is486()) {
 	return 0;
     }
     freebl_cpuid(0, &eax, &ebx, &ecx, &edx);
+    /* string holds the CPU's manufacturer ID string - a twelve
+     * character ASCII string stored in ebx, edx, ecx, and
+     * the 32-bit extended feature flags are in edx, ecx.
+     */
     *(int *)string = ebx;
-    *(int *)&string[4] = edx;
-    *(int *)&string[8] = ecx;
+    *(int *)&string[4] = (int)edx;
+    *(int *)&string[8] = (int)ecx;
     string[12] = 0;
 
     /* has no SSE2 extensions */
     if (eax == 0) {
 	return 0;
     }
 
     for (i=0; i < n_manufacturers; i++) {
@@ -698,19 +702,23 @@ s_mpi_getProcessorLineSize()
     } if (is486()) {
 	return 32; /* really? need more info */
     }
 #endif
 
     /* Pentium, cpuid command is available */
     freebl_cpuid(0, &eax, &ebx, &ecx, &edx);
     cpuidLevel = eax;
+    /* string holds the CPU's manufacturer ID string - a twelve
+     * character ASCII string stored in ebx, edx, ecx, and
+     * the 32-bit extended feature flags are in edx, ecx.
+     */
     *(int *)string = ebx;
-    *(int *)&string[4] = edx;
-    *(int *)&string[8] = ecx;
+    *(int *)&string[4] = (int)edx;
+    *(int *)&string[8] = (int)ecx;
     string[12] = 0;
 
     manufacturer = MAN_UNKNOWN;
     for (i=0; i < n_manufacturers; i++) {
 	if ( strcmp(manMap[i],string) == 0) {
 	    manufacturer = i;
 	}
     }
--- a/security/nss/lib/freebl/rsa.c
+++ b/security/nss/lib/freebl/rsa.c
@@ -32,17 +32,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * RSA key generation, public key op, private key op.
  *
- * $Id: rsa.c,v 1.42 2011/03/30 01:20:12 rrelyea%redhat.com Exp $
+ * $Id: rsa.c,v 1.43 2011/09/21 01:09:48 wtc%google.com Exp $
  */
 #ifdef FREEBL_NO_DEPEND
 #include "stubs.h"
 #endif
 
 #include "secerr.h"
 
 #include "prclist.h"
@@ -1091,18 +1091,16 @@ cleanup:
     return rv;
 }
 
 static SECStatus
 init_blinding_params(RSABlindingParams *rsabp, RSAPrivateKey *key,
                      mp_int *n, unsigned int modLen)
 {
     blindingParams * bp = rsabp->array;
-    SECStatus rv = SECSuccess;
-    mp_err err = MP_OKAY;
     int i = 0;
 
     /* Initialize the list pointer for the element */
     PR_INIT_CLIST(&rsabp->link);
     for (i = 0; i < RSA_BLINDING_PARAMS_MAX_CACHE_SIZE; ++i, ++bp) {
     	bp->next = bp + 1;
 	MP_DIGITS(&bp->f) = 0;
 	MP_DIGITS(&bp->g) = 0;
@@ -1212,17 +1210,17 @@ get_blinding_params(RSAPrivateKey *key, 
 	     */
 	    if (blindingParamsList.waitCount > 0) {
 		PR_NotifyCondVar( blindingParamsList.cVar );
 		blindingParamsList.waitCount--;
 	    }
 	    PZ_Unlock(blindingParamsList.lock); 
 	    return SECSuccess;
 	}
-	/* We did not find a usable set of blinding params.  Can we make one?
+	/* We did not find a usable set of blinding params.  Can we make one? */
 	/* Find a free bp struct. */
 	prevbp = NULL;
 	if ((bp = rsabp->free) != NULL) {
 	    /* unlink this bp */
 	    rsabp->free  = bp->next;
 	    bp->next     = NULL;
 	    bpUnlinked   = bp;  /* In case we fail */
 
--- a/security/nss/lib/freebl/sha512.c
+++ b/security/nss/lib/freebl/sha512.c
@@ -31,17 +31,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: sha512.c,v 1.18 2011/03/30 22:35:43 wtc%google.com Exp $ */
+/* $Id: sha512.c,v 1.19 2011/09/14 17:48:03 wtc%google.com Exp $ */
 
 #ifdef FREEBL_NO_DEPEND
 #include "stubs.h"
 #endif
 
 #include "prcpucfg.h"
 #if defined(NSS_X86) || defined(SHA_NO_LONG_LONG)
 #define NOUNROLL512 1
@@ -566,22 +566,16 @@ SHA224_DestroyContext(SHA224Context *ctx
 
 void
 SHA224_Begin(SHA224Context *ctx)
 {
     memset(ctx, 0, sizeof *ctx);
     memcpy(H, H224, sizeof H224);
 }
 
-static void
-SHA224_Compress(SHA224Context *ctx)
-{
-    SHA256_Compress(ctx);
-}
-
 void
 SHA224_Update(SHA224Context *ctx, const unsigned char *input,
 		    unsigned int inputLen)
 {
     SHA256_Update(ctx, input, inputLen);
 }
 
 void
--- a/security/nss/lib/freebl/unix_rand.c
+++ b/security/nss/lib/freebl/unix_rand.c
@@ -838,33 +838,41 @@ safe_pclose(FILE *fp)
 
     /* Reset SIGCHLD signal hander before returning */
     sigaction(SIGCHLD, &oldact, NULL);
 
     return status;
 }
 
 #ifdef DARWIN
+#include <TargetConditionals.h>
+#if !TARGET_OS_IPHONE
 #include <crt_externs.h>
 #endif
+#endif
 
 /* Fork netstat to collect its output by default. Do not unset this unless
  * another source of entropy is available
  */
 #define DO_NETSTAT 1
 
 void RNG_SystemInfoForRNG(void)
 {
     FILE *fp;
     char buf[BUFSIZ];
     size_t bytes;
     const char * const *cp;
     char *randfile;
 #ifdef DARWIN
+#if TARGET_OS_IPHONE
+    /* iOS does not expose a way to access environ. */
+    char **environ = NULL;
+#else
     char **environ = *_NSGetEnviron();
+#endif
 #else
     extern char **environ;
 #endif
 #ifdef BEOS
     static const char * const files[] = {
 	"/boot/var/swap",
 	"/boot/var/log/syslog",
 	"/boot/var/tmp",
--- a/security/nss/lib/libpkix/include/pkix_pl_pki.h
+++ b/security/nss/lib/libpkix/include/pkix_pl_pki.h
@@ -1530,16 +1530,19 @@ PKIX_PL_Cert_VerifySignature(
  *  "pTrusted". If a certificate is trusted it means that a chain built to that
  *  certificate, and satisfying all the usage, policy, validity, and other
  *  tests, is a valid chain and the End Entity certificate from which it was
  *  built can be trusted.
  *
  *  If the Certificate is not intrinsically trustworthy, it still might end up a
  *  component in a successful chain.
  *
+ *  If the Certificate is intrinsically untrustworthy, this function will return
+ *  an error. 
+ *
  * PARAMETERS
  *  "cert"
  *      Address of Cert whose trustworthiness is to be determined. Must be
  *      non-NULL.
  *  "trustOnlyUserAnchors"
  *      States that we can only trust explicitly defined user trust anchors.
  *  "pTrusted"
  *      Address where the Boolean value will be stored. Must be non-NULL.
@@ -1554,16 +1557,53 @@ PKIX_PL_Cert_VerifySignature(
  */
 PKIX_Error *
 PKIX_PL_Cert_IsCertTrusted(
         PKIX_PL_Cert *cert,
         PKIX_Boolean trustOnlyUserAnchors,
         PKIX_Boolean *pTrusted,
         void *plContext);
 
+/*
+ * FUNCTION: PKIX_PL_Cert_IsLeafCertTrusted
+ * DESCRIPTION:
+ *
+ *  Checks the Leaf Cert specified by "cert" to determine, in a manner that 
+ *  depends on the underlying platform, whether it is trusted, and stores the 
+ *  result in "pTrusted". If a certificate is trusted it means that this
+ *  End Entify certificate has been marked as trusted for the requested usage,
+ *  policy, validity, and other tests.
+ *
+ *  If the Certificate is not intrinsically trustworthy, we can still try to 
+ *  build a successful chain.
+ *
+ *  If the Certificate is intrinsically untrustworthy, this function will return
+ *  an error. 
+ *
+ * PARAMETERS
+ *  "cert"
+ *      Address of Cert whose trustworthiness is to be determined. Must be
+ *      non-NULL.
+ *  "pTrusted"
+ *      Address where the Boolean value will be stored. Must be non-NULL.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a CERT Error if the function fails in a non-fatal way.
+ *  Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+PKIX_Error *
+PKIX_PL_Cert_IsLeafCertTrusted(
+        PKIX_PL_Cert *cert,
+        PKIX_Boolean *pTrusted,
+        void *plContext);
+
 /* FUNCTION: PKIX_PL_Cert_SetAsTrustAnchor */
 PKIX_Error*
 PKIX_PL_Cert_SetAsTrustAnchor(PKIX_PL_Cert *cert, 
                               void *plContext);
 
 /*
  * FUNCTION: PKIX_PL_Cert_GetCacheFlag
  * DESCRIPTION:
--- a/security/nss/lib/libpkix/pkix/top/pkix_build.c
+++ b/security/nss/lib/libpkix/pkix/top/pkix_build.c
@@ -3230,16 +3230,17 @@ pkix_Build_InitiateBuildChain(
         PKIX_List *tentativeChain = NULL;
         PKIX_ValidateResult *valResult = NULL;
         PKIX_BuildResult *buildResult = NULL;
         PKIX_List *certList = NULL;
         PKIX_TrustAnchor *matchingAnchor = NULL;
         PKIX_ForwardBuilderState *state = NULL;
         PKIX_CertStore_CheckTrustCallback trustCallback = NULL;
         PKIX_CertSelector_MatchCallback selectorCallback = NULL;
+        PKIX_Boolean trusted = PKIX_FALSE;
         PKIX_PL_AIAMgr *aiaMgr = NULL;
 
         PKIX_ENTER(BUILD, "pkix_Build_InitiateBuildChain");
         PKIX_NULLCHECK_FOUR(procParams, pNBIOContext, pState, pBuildResult);
 
         nbioContext = *pNBIOContext;
         *pNBIOContext = NULL;
 
@@ -3335,16 +3336,25 @@ pkix_Build_InitiateBuildChain(
                     }
 
             }
 
             if (targetCert == NULL) {
                 PKIX_ERROR(PKIX_NOTARGETCERTSUPPLIED);
             }
 
+            PKIX_CHECK(PKIX_PL_Cert_IsLeafCertTrusted
+                    (targetCert,
+                    &trusted, 
+                    plContext),
+                    PKIX_CERTISCERTTRUSTEDFAILED);
+            /* future: look at the |trusted| flag and force success. We only
+             * want to do this if we aren't validating against a policy (like
+             * EV). */
+
             PKIX_CHECK(PKIX_PL_Cert_GetAllSubjectNames
                     (targetCert,
                     &targetSubjNames,
                     plContext),
                     PKIX_CERTGETALLSUBJECTNAMESFAILED);
     
             PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey
                     (targetCert, &targetPubKey, plContext),
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c
+++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c
@@ -3237,94 +3237,177 @@ PKIX_PL_Cert_MergeNameConstraints(
 
         *pResultNC = mergedNC;
 
 cleanup:
         PKIX_RETURN(CERT);
 }
 
 /*
+ * Find out the state of the NSS trust bits for the requested usage.
+ * Returns SECFailure if the cert is explicitly distrusted.
+ * Returns SECSuccess if the cert can be used to form a chain (normal case),
+ *   or it is explicitly trusted. The trusted bool is set to true if it is
+ *   explicitly trusted.
+ */
+static SECStatus
+pkix_pl_Cert_GetTrusted(void *plContext,
+                        PKIX_PL_Cert *cert,
+                        PKIX_Boolean *trusted,
+                        PKIX_Boolean isCA)
+{
+        SECStatus rv;
+        CERTCertificate *nssCert = NULL;
+        SECCertUsage certUsage = 0;
+        SECCertificateUsage certificateUsage;
+        SECTrustType trustType;
+        unsigned int trustFlags;
+        unsigned int requiredFlags;
+        CERTCertTrust trust;
+
+        *trusted = PKIX_FALSE;
+
+        /* no key usage information  */
+        if (plContext == NULL) {
+                return SECSuccess;
+        }
+
+        certificateUsage = ((PKIX_PL_NssContext*)plContext)->certificateUsage;
+
+        /* ensure we obtained a single usage bit only */
+        PORT_Assert(!(certificateUsage & (certificateUsage - 1)));
+
+        /* convert SECertificateUsage (bit mask) to SECCertUsage (enum) */
+        while (0 != (certificateUsage = certificateUsage >> 1)) { certUsage++; }
+
+        nssCert = cert->nssCert;
+
+        if (!isCA) {
+                PRBool prTrusted;
+                unsigned int failedFlags;
+                rv = cert_CheckLeafTrust(nssCert, certUsage,
+                                         &failedFlags, &prTrusted);
+                *trusted = (PKIX_Boolean) prTrusted;
+                return rv;
+        }
+        rv = CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags,
+                                           &trustType);
+        if (rv != SECSuccess) {
+                return SECSuccess;
+        }
+
+        rv = CERT_GetCertTrust(nssCert, &trust);
+        if (rv != SECSuccess) {
+                return SECSuccess;
+        }
+        trustFlags = SEC_GET_TRUST_FLAGS(&trust, trustType);
+        /* normally trustTypeNone usages accept any of the given trust bits
+         * being on as acceptable. If any are distrusted (and none are trusted),
+         * then we will also distrust the cert */
+        if ((trustFlags == 0) && (trustType == trustTypeNone)) {
+                trustFlags = trust.sslFlags | trust.emailFlags |
+                             trust.objectSigningFlags;
+        }
+        if ((trustFlags & requiredFlags) == requiredFlags) {
+                *trusted = PKIX_TRUE;
+                return SECSuccess;
+        }
+        if ((trustFlags & CERTDB_TERMINAL_RECORD) &&
+            ((trustFlags & (CERTDB_VALID_CA|CERTDB_TRUSTED)) == 0)) {
+                return SECFailure;
+        }
+        return SECSuccess;
+}
+
+/*
  * FUNCTION: PKIX_PL_Cert_IsCertTrusted
  * (see comments in pkix_pl_pki.h)
  */
 PKIX_Error *
 PKIX_PL_Cert_IsCertTrusted(
         PKIX_PL_Cert *cert,
         PKIX_Boolean trustOnlyUserAnchors,
         PKIX_Boolean *pTrusted,
         void *plContext)
 {
         PKIX_CertStore_CheckTrustCallback trustCallback = NULL;
-        SECCertUsage certUsage = 0;
         PKIX_Boolean trusted = PKIX_FALSE;
         SECStatus rv = SECFailure;
-        unsigned int requiredFlags;
-        SECTrustType trustType;
-        CERTCertTrust trust;
-        CERTCertificate *nssCert = NULL;
-        SECCertificateUsage certificateUsage;
-
-        PKIX_ENTER(CERT, "pkix_pl_Cert_IsCertTrusted");
+
+        PKIX_ENTER(CERT, "PKIX_PL_Cert_IsCertTrusted");
         PKIX_NULLCHECK_TWO(cert, pTrusted);
 
+        /* Call GetTrusted first to see if we are going to distrust the
+         * certificate */
+        rv = pkix_pl_Cert_GetTrusted(plContext, cert, &trusted, PKIX_TRUE);
+        if (rv != SECSuccess) {
+                /* Failure means the cert is explicitly distrusted,
+                 * let the next level know not to use it. */
+                *pTrusted = PKIX_FALSE;
+                PKIX_ERROR(PKIX_CERTISCERTTRUSTEDFAILED);
+        }
+
         if (trustOnlyUserAnchors) {
+            /* discard our |trusted| value since we are using the anchors */
             *pTrusted = cert->isUserTrustAnchor;
             goto cleanup;
         }
 
-        /* no key usage information and store is not trusted */
+        /* no key usage information or store is not trusted */
         if (plContext == NULL || cert->store == NULL) {
                 *pTrusted = PKIX_FALSE;
                 goto cleanup;
         }
 
-        if (cert->store) {
-                PKIX_CHECK(PKIX_CertStore_GetTrustCallback
-                        (cert->store, &trustCallback, plContext),
-                        PKIX_CERTSTOREGETTRUSTCALLBACKFAILED);
-
-                PKIX_CHECK_ONLY_FATAL(trustCallback
-                        (cert->store, cert, &trusted, plContext),
-                        PKIX_CHECKTRUSTCALLBACKFAILED);
-
-                if (PKIX_ERROR_RECEIVED || (trusted == PKIX_FALSE)) {
-
-                        *pTrusted = PKIX_FALSE;
-                        goto cleanup;
-                }
-
-        }
-
-        certificateUsage = ((PKIX_PL_NssContext*)plContext)->certificateUsage;
-
-        /* ensure we obtained a single usage bit only */
-        PORT_Assert(!(certificateUsage & (certificateUsage - 1)));
-
-        /* convert SECertificateUsage (bit mask) to SECCertUsage (enum) */
-        while (0 != (certificateUsage = certificateUsage >> 1)) { certUsage++; }
-
-        rv = CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags, &trustType);
-        if (rv != SECSuccess) {
+        PKIX_CHECK(PKIX_CertStore_GetTrustCallback
+                (cert->store, &trustCallback, plContext),
+                PKIX_CERTSTOREGETTRUSTCALLBACKFAILED);
+
+        PKIX_CHECK_ONLY_FATAL(trustCallback
+                (cert->store, cert, &trusted, plContext),
+                PKIX_CHECKTRUSTCALLBACKFAILED);
+
+        /* allow trust store to override if we can trust the trust
+         * bits */
+        if (PKIX_ERROR_RECEIVED || (trusted == PKIX_FALSE)) {
                 *pTrusted = PKIX_FALSE;
                 goto cleanup;
         }
 
-        nssCert = cert->nssCert;
-
-        rv = CERT_GetCertTrust(nssCert, &trust);
-        if (rv == SECSuccess) {
-                unsigned int certFlags;
-                certFlags = SEC_GET_TRUST_FLAGS((&trust), trustType);
-                if ((certFlags & requiredFlags) == requiredFlags) {
-                        trusted = PKIX_TRUE;
-                }
+        *pTrusted = trusted;
+
+cleanup:
+        PKIX_RETURN(CERT);
+}
+
+/*
+ * FUNCTION: PKIX_PL_Cert_IsLeafCertTrusted
+ * (see comments in pkix_pl_pki.h)
+ */
+PKIX_Error *
+PKIX_PL_Cert_IsLeafCertTrusted(
+        PKIX_PL_Cert *cert,
+        PKIX_Boolean *pTrusted,
+        void *plContext)
+{
+        SECStatus rv;
+
+        PKIX_ENTER(CERT, "PKIX_PL_Cert_IsLeafCertTrusted");
+        PKIX_NULLCHECK_TWO(cert, pTrusted);
+
+        *pTrusted = PKIX_FALSE;
+
+        rv = pkix_pl_Cert_GetTrusted(plContext, cert, pTrusted, PKIX_FALSE);
+        if (rv != SECSuccess) {
+                /* Failure means the cert is explicitly distrusted,
+                 * let the next level know not to use it. */
+                *pTrusted = PKIX_FALSE;
+                PKIX_ERROR(PKIX_CERTISCERTTRUSTEDFAILED);
         }
 
-        *pTrusted = trusted;
-
 cleanup:
         PKIX_RETURN(CERT);
 }
 
 /* FUNCTION: PKIX_PL_Cert_SetAsTrustAnchor */
 PKIX_Error*
 PKIX_PL_Cert_SetAsTrustAnchor(PKIX_PL_Cert *cert, 
                               void *plContext)
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.c
+++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.c
@@ -627,17 +627,17 @@ pkix_pl_InfoAccess_ParseTokens(
                     p[len] = '\0';
 
                     *filterP = p;
                     filterP++;
                     numFilters--;
 
                     separator = terminator;
 
-                    if (endPos == '\0') {
+                    if (*endPos == '\0') {
                         *startPos = endPos;
                         break;
                     } else {
                         endPos++;
                         *startPos = endPos;
                         continue;
                     }
             }
--- a/security/nss/lib/nss/nss.h
+++ b/security/nss/lib/nss/nss.h
@@ -31,17 +31,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: nss.h,v 1.83 2011/08/01 07:08:08 kaie%kuix.de Exp $ */
+/* $Id: nss.h,v 1.84 2011/10/04 22:56:31 wtc%google.com Exp $ */
 
 #ifndef __nss_h_
 #define __nss_h_
 
 /* The private macro _NSS_ECC_STRING is for NSS internal use only. */
 #ifdef NSS_ENABLE_ECC
 #ifdef NSS_ECC_MORE_THAN_SUITE_B
 #define _NSS_ECC_STRING " Extended ECC"
@@ -61,22 +61,22 @@
 
 /*
  * NSS's major version, minor version, patch level, build number, and whether
  * this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
  */
-#define NSS_VERSION  "3.13.0.0" _NSS_ECC_STRING _NSS_CUSTOMIZED " Beta"
+#define NSS_VERSION  "3.13.0.0" _NSS_ECC_STRING _NSS_CUSTOMIZED
 #define NSS_VMAJOR   3
 #define NSS_VMINOR   13
 #define NSS_VPATCH   0
 #define NSS_VBUILD   0
-#define NSS_BETA     PR_TRUE
+#define NSS_BETA     PR_FALSE
 
 #ifndef RC_INVOKED
 
 #include "seccomon.h"
 
 typedef struct NSSInitParametersStr NSSInitParameters;
 
 /*
--- a/security/nss/lib/nss/nssinit.c
+++ b/security/nss/lib/nss/nssinit.c
@@ -31,34 +31,33 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: nssinit.c,v 1.108 2011/08/17 14:40:49 emaldona%redhat.com Exp $ */
+/* $Id: nssinit.c,v 1.112 2011/10/04 02:35:58 emaldona%redhat.com Exp $ */
 
 #include <ctype.h>
 #include <string.h>
 #include "seccomon.h"
 #include "prerror.h"
 #include "prinit.h"
 #include "prprf.h"
 #include "prmem.h"
 #include "prtypes.h"
 #include "cert.h"
 #include "key.h"
 #include "secmod.h"
 #include "secoid.h"
 #include "nss.h"
 #include "pk11func.h"
 #include "secerr.h"
-#include "errstrs.h"
 #include "nssbase.h"
 #include "nssutil.h"
 #include "pkixt.h"
 #include "pkix.h"
 #include "pkix_tools.h"
 
 #include "pki3hack.h"
 #include "certi.h"
@@ -376,33 +375,31 @@ nss_InitModules(const char *configdir, c
 		const char *updateDir, const char *updCertPrefix, 
 		const char *updKeyPrefix, const char *updateID, 
 		const char *updateName, char *configName, char *configStrings,
 		PRBool pwRequired, PRBool readOnly, PRBool noCertDB,
 		PRBool noModDB, PRBool forceOpen, PRBool optimizeSpace,
 		PRBool isContextInit)
 {
     SECStatus rv = SECFailure;
-    PRStatus status = PR_SUCCESS;
     char *moduleSpec = NULL;
     char *flags = NULL;
     char *lconfigdir = NULL;
     char *lcertPrefix = NULL;
     char *lkeyPrefix = NULL;
     char *lsecmodName = NULL;
     char *lupdateDir = NULL;
     char *lupdCertPrefix = NULL;
     char *lupdKeyPrefix = NULL;
     char *lupdateID = NULL;
     char *lupdateName = NULL;
 
-    status = NSS_InitializePRErrorTable();
-    if (status != PR_SUCCESS) {
-	PORT_SetError(status);
-	return SECFailure;
+    if (NSS_InitializePRErrorTable() != SECSuccess) {
+	PORT_SetError(SEC_ERROR_NO_MEMORY);
+	return rv;
     }
 
     flags = nss_makeFlags(readOnly,noCertDB,noModDB,forceOpen,
 					pwRequired, optimizeSpace);
     if (flags == NULL) return rv;
 
     /*
      * configdir is double nested, and Windows uses the same character
@@ -527,16 +524,37 @@ struct NSSInitContextStr {
 
 #define NSS_INIT_MAGIC 0x1413A91C
 static SECStatus nss_InitShutdownList(void);
 
 #ifdef DEBUG
 static CERTCertificate dummyCert;
 #endif
 
+/* All initialized to zero in BSS */
+static PRCallOnceType nssInitOnce;
+static PZLock *nssInitLock;
+static PZCondVar *nssInitCondition;
+static int nssIsInInit;
+
+static PRStatus
+nss_doLockInit(void)
+{
+    nssInitLock = PZ_NewLock(nssILockOther);
+    if (nssInitLock == NULL) {
+	return (PRStatus) SECFailure;
+    }
+    nssInitCondition = PZ_NewCondVar(nssInitLock);
+    if (nssInitCondition == NULL) {
+	return (PRStatus) SECFailure;
+    }
+    return (PRStatus) SECSuccess;
+}
+
+
 static SECStatus
 nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix,
 		 const char *secmodName, const char *updateDir, 
 		 const char *updCertPrefix, const char *updKeyPrefix,
 		 const char *updateID, const char *updateName,
 		 NSSInitContext ** initContextPtr,
 		 NSSInitParameters *initParams,
 		 PRBool readOnly, PRBool noCertDB, 
@@ -553,36 +571,59 @@ nss_Init(const char *configdir, const ch
     char *configName = NULL;
     PRBool passwordRequired = PR_FALSE;
 
     /* if we are trying to init with a traditional NSS_Init call, maintain
      * the traditional idempotent behavior. */
     if (!initContextPtr && nssIsInitted) {
 	return SECSuccess;
     }
+  
+    /* make sure our locks are initialized one and only one time */ 
+    rv = PR_CallOnce(&nssInitOnce, nss_doLockInit);
+    if (rv != SECSuccess) {
+	return rv;
+    }
+
+    /*
+     * if we haven't done basic initialization, single thread the 
+     * initializations.
+     */
+    PZ_Lock(nssInitLock);
+    isReallyInitted = NSS_IsInitialized();
+    if (!isReallyInitted) {
+	while (!isReallyInitted && nssIsInInit) {
+	    PZ_WaitCondVar(nssInitCondition,PR_INTERVAL_NO_TIMEOUT);
+	    isReallyInitted = NSS_IsInitialized();
+ 	}
+	/* once we've completed basic initialization, we can allow more than 
+	 * one process initialize NSS at a time. */
+    }
+    /* get the current value */
+    nssIsInInit++;
+    PZ_Unlock(nssInitLock);
 
     /* this tells us whether or not some library has already initialized us.
      * if so, we don't want to double call some of the basic initialization
      * functions */
-    isReallyInitted = NSS_IsInitialized();
 
     if (!isReallyInitted) {
 	/* New option bits must not change the size of CERTCertificate. */
 	PORT_Assert(sizeof(dummyCert.options) == sizeof(void *));
 
 	if (SECSuccess != cert_InitLocks()) {
-            return SECFailure;
+	    goto loser;
 	}
 
 	if (SECSuccess != InitCRLCache()) {
-            return SECFailure;
+	    goto loser;
 	}
     
 	if (SECSuccess != OCSP_InitGlobal()) {
-            return SECFailure;
+	    goto loser;
 	}
     }
 
     if (noSingleThreadedModules || allowAlreadyInitializedModules ||
         dontFinalizeModules) {
         pk11_setGlobalOptions(noSingleThreadedModules,
                               allowAlreadyInitializedModules,
                               dontFinalizeModules);
@@ -692,23 +733,28 @@ nss_Init(const char *configdir, const ch
 
     }
 
     /*
      * Now mark the appropriate init state. If initContextPtr was passed
      * in, then return the new context pointer and add it to the
      * nssInitContextList. Otherwise set the global nss_isInitted flag
      */
+    PZ_Lock(nssInitLock);
     if (!initContextPtr) {
 	nssIsInitted = PR_TRUE;
     } else {
 	(*initContextPtr)->magic = NSS_INIT_MAGIC;
 	(*initContextPtr)->next = nssInitContextList;
 	nssInitContextList = (*initContextPtr);
     }
+    nssIsInInit--;
+    /* now that we are inited, all waiters can move forward */
+    PZ_NotifyAllCondVar(nssInitCondition);
+    PZ_Unlock(nssInitLock);
 
     return SECSuccess;
 
 loser:
     if (initContextPtr && *initContextPtr) {
 	PORT_Free(*initContextPtr);
 	*initContextPtr = NULL;
 	if (configStrings) {
@@ -889,20 +935,23 @@ nss_GetShutdownEntry(NSS_ShutdownFunc sF
 /*
  * register a callback to be called when NSS shuts down
  */
 SECStatus
 NSS_RegisterShutdown(NSS_ShutdownFunc sFunc, void *appData)
 {
     int i;
 
+    PZ_Lock(nssInitLock);
     if (!NSS_IsInitialized()) {
+	PZ_Unlock(nssInitLock);
 	PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
 	return SECFailure;
     }
+    PZ_Unlock(nssInitLock);
     if (sFunc == NULL) {
 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
 	return SECFailure;
     }
 
     PORT_Assert(nssShutdownList.lock);
     PZ_Lock(nssShutdownList.lock);
 
@@ -943,20 +992,24 @@ NSS_RegisterShutdown(NSS_ShutdownFunc sF
 
 /*
  * unregister a callback so it won't get called on shutdown.
  */
 SECStatus
 NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData)
 {
     int i;
+
+    PZ_Lock(nssInitLock);
     if (!NSS_IsInitialized()) {
+	PZ_Unlock(nssInitLock);
 	PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
 	return SECFailure;
     }
+    PZ_Unlock(nssInitLock);
 
     PORT_Assert(nssShutdownList.lock);
     PZ_Lock(nssShutdownList.lock);
     i = nss_GetShutdownEntry(sFunc, appData);
     if (i >= 0) {
 	nssShutdownList.funcs[i].func = NULL;
 	nssShutdownList.funcs[i].appData = NULL;
     }
@@ -1077,22 +1130,33 @@ nss_Shutdown(void)
 	temp = next;
     }
     return shutdownRV;
 }
 
 SECStatus
 NSS_Shutdown(void)
 {
+    SECStatus rv;
+    PZ_Lock(nssInitLock);
+
     if (!nssIsInitted) {
+	PZ_Unlock(nssInitLock);
 	PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
 	return SECFailure;
     }
 
-    return nss_Shutdown();
+    /* If one or more threads are in the middle of init, wait for them
+     * to complete */
+    while (nssIsInInit) {
+	PZ_WaitCondVar(nssInitCondition,PR_INTERVAL_NO_TIMEOUT);
+    }
+    rv = nss_Shutdown();
+    PZ_Unlock(nssInitLock);
+    return rv;
 }
 
 /*
  * remove the context from a list. return true if found, false if not
  */
 PRBool
 nss_RemoveList(NSSInitContext *context) {
     NSSInitContext *this = nssInitContextList;
@@ -1117,42 +1181,59 @@ nss_RemoveList(NSSInitContext *context) 
  * it's own context. The application (which doesn't get a context), calls
  * shutdown with NULL. Once all users have 'checked in' NSS will shutdown.
  * This is different than NSS_Shutdown, where calling it will shutdown NSS
  * irreguardless of who else may have NSS open.
  */
 SECStatus
 NSS_ShutdownContext(NSSInitContext *context)
 {
-   if (!context) {
+    SECStatus rv = SECSuccess;
+
+    PZ_Lock(nssInitLock);
+    /* If one or more threads are in the middle of init, wait for them
+     * to complete */
+    while (nssIsInInit) {
+	PZ_WaitCondVar(nssInitCondition,PR_INTERVAL_NO_TIMEOUT);
+    }
+
+    /* OK, we are the only thread now either initializing or shutting down */
+    
+    if (!context) {
 	if (!nssIsInitted) {
+	    PZ_Unlock(nssInitLock);
 	    PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
 	    return SECFailure;
 	}
 	nssIsInitted = 0;
     } else if (! nss_RemoveList(context)) {
+	PZ_Unlock(nssInitLock);
 	/* context was already freed or wasn't valid */
 	PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
 	return SECFailure;
     }
     if ((nssIsInitted == 0) && (nssInitContextList == NULL)) {
-	return nss_Shutdown();
+	rv = nss_Shutdown();
     }
-    return SECSuccess;
+
+    /* NOTE: we don't try to free the nssInitLocks to prevent races against
+     * the locks. There may be a thread, right now, waiting in NSS_Init for us
+     * to free the lock below. If we delete the locks, bad things would happen
+     * to that thread */
+    PZ_Unlock(nssInitLock);
+
+    return rv;
 }
-	
-	
-
 
 PRBool
 NSS_IsInitialized(void)
 {
     return (nssIsInitted) || (nssInitContextList != NULL);
 }
-
+	
 
 extern const char __nss_base_rcsid[];
 extern const char __nss_base_sccsid[];
 
 PRBool
 NSS_VersionCheck(const char *importedVersion)
 {
     /*
--- a/security/nss/lib/pk11wrap/pk11obj.c
+++ b/security/nss/lib/pk11wrap/pk11obj.c
@@ -345,17 +345,17 @@ PK11_SetObjectNickname(PK11SlotInfo *slo
 /*
  * strip leading zero's from key material
  */
 void
 pk11_SignedToUnsigned(CK_ATTRIBUTE *attrib) {
     char *ptr = (char *)attrib->pValue;
     unsigned long len = attrib->ulValueLen;
 
-    while (len && (*ptr == 0)) {
+    while ((len > 1) && (*ptr == 0)) {
 	len--;
 	ptr++;
     }
     attrib->pValue = ptr;
     attrib->ulValueLen = len;
 }
 
 /*
--- a/security/nss/lib/pkcs7/p7decode.c
+++ b/security/nss/lib/pkcs7/p7decode.c
@@ -33,17 +33,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * PKCS7 decoding, verification.
  *
- * $Id: p7decode.c,v 1.25 2008/03/10 00:01:26 wtc%google.com Exp $
+ * $Id: p7decode.c,v 1.26 2011/08/21 01:14:17 wtc%google.com Exp $
  */
 
 #include "p7local.h"
 
 #include "cert.h"
 				/* XXX do not want to have to include */
 #include "certdb.h"		/* certdb.h -- the trust stuff needed by */
      				/* the add certificate code needs to get */
@@ -423,17 +423,16 @@ sec_pkcs7_decoder_finish_digests (SEC_PK
     PORT_ArenaUnmark (poolp, mark);
     return SECSuccess;
 }
 
 /*
  * XXX Need comment explaining following helper function (which is used
  * by sec_pkcs7_decoder_start_decrypt).
  */
-extern const SEC_ASN1Template SEC_SMIMEKEAParamTemplateAllParams[];
 
 static PK11SymKey *
 sec_pkcs7_decoder_get_recipient_key (SEC_PKCS7DecoderContext *p7dcx,
 				     SEC_PKCS7RecipientInfo **recipientinfos,
 				     SEC_PKCS7EncryptedContentInfo *enccinfo)
 {
     SEC_PKCS7RecipientInfo *ri;
     CERTCertificate *cert = NULL;
@@ -455,144 +454,33 @@ sec_pkcs7_decoder_get_recipient_key (SEC
 	goto no_key_found;
     }
 
     ri->cert = cert;		/* so we can find it later */
     PORT_Assert(privkey != NULL);
 
     keyalgtag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm));
     encalgtag = SECOID_GetAlgorithmTag (&(ri->keyEncAlg));
-    if ((encalgtag != SEC_OID_NETSCAPE_SMIME_KEA) && (keyalgtag != encalgtag)) {
+    if (keyalgtag != encalgtag) {
 	p7dcx->error = SEC_ERROR_PKCS7_KEYALG_MISMATCH;
 	goto no_key_found;
     }
     bulkalgtag = SECOID_GetAlgorithmTag (&(enccinfo->contentEncAlg));
 
     switch (encalgtag) {
       case SEC_OID_PKCS1_RSA_ENCRYPTION:
 	bulkkey = PK11_PubUnwrapSymKey (privkey, &ri->encKey,
 					PK11_AlgtagToMechanism (bulkalgtag),
 					CKA_DECRYPT, 0);
 	if (bulkkey == NULL) {
 	    p7dcx->error = PORT_GetError();
 	    PORT_SetError(0);
 	    goto no_key_found;
 	}
 	break;
-	/* ### mwelch -- KEA */ 
-        case SEC_OID_NETSCAPE_SMIME_KEA:
-	  {
-	      SECStatus err;
-	      CK_MECHANISM_TYPE bulkType;
-	      PK11SymKey *tek;
-	      SECKEYPublicKey *senderPubKey;
-	      SEC_PKCS7SMIMEKEAParameters   keaParams;
-
-	      (void) memset(&keaParams, 0, sizeof(keaParams));
-
-	      /* Decode the KEA algorithm parameters. */
-	      err = SEC_ASN1DecodeItem(NULL,
-				       &keaParams,
-				       SEC_SMIMEKEAParamTemplateAllParams,
-				       &(ri->keyEncAlg.parameters));
-	      if (err != SECSuccess)
-	      {
-		  p7dcx->error = err;
-		  PORT_SetError(0);
-		  goto no_key_found;
-	      }
-	  
-
-	      /* We just got key data, no key structure. So, we
-		 create one. */
-	     senderPubKey = 
-		  PK11_MakeKEAPubKey(keaParams.originatorKEAKey.data,
-				     keaParams.originatorKEAKey.len);
-	     if (senderPubKey == NULL)
-	     {
-		    p7dcx->error = PORT_GetError();
-		    PORT_SetError(0);
-		    goto no_key_found;
-	     }
-	      
-	     /* Generate the TEK (token exchange key) which we use
-	         to unwrap the bulk encryption key. */
-	     tek = PK11_PubDerive(privkey, senderPubKey, 
-				   PR_FALSE,
-				   &keaParams.originatorRA,
-				   NULL,
-				   CKM_KEA_KEY_DERIVE, CKM_SKIPJACK_WRAP,
-				   CKA_WRAP, 0, p7dcx->pwfn_arg);
-	     SECKEY_DestroyPublicKey(senderPubKey);
-	      
-	     if (tek == NULL)
-	     {
-		  p7dcx->error = PORT_GetError();
-		  PORT_SetError(0);
-		  goto no_key_found;
-	     }
-	      
-	      /* Now that we have the TEK, unwrap the bulk key
-	         with which to decrypt the message. We have to
-		 do one of two different things depending on 
-		 whether Skipjack was used for bulk encryption 
-		 of the message. */
-	      bulkType = PK11_AlgtagToMechanism (bulkalgtag);
-	      switch(bulkType)
-	      {
-	      case CKM_SKIPJACK_CBC64:
-	      case CKM_SKIPJACK_ECB64:
-	      case CKM_SKIPJACK_OFB64:
-	      case CKM_SKIPJACK_CFB64:
-	      case CKM_SKIPJACK_CFB32:
-	      case CKM_SKIPJACK_CFB16:
-	      case CKM_SKIPJACK_CFB8:
-		  /* Skipjack is being used as the bulk encryption algorithm.*/
-		  /* Unwrap the bulk key. */
-		  bulkkey = PK11_UnwrapSymKey(tek, CKM_SKIPJACK_WRAP,
-					      NULL, &ri->encKey, 
-					      CKM_SKIPJACK_CBC64, 
-					      CKA_DECRYPT, 0);
-		  break;
-	      default:
-		  /* Skipjack was not used for bulk encryption of this
-		     message. Use Skipjack CBC64, with the nonSkipjackIV
-		     part of the KEA key parameters, to decrypt 
-		     the bulk key. If we got a parameter indicating that the
-		     bulk key size is different than the encrypted key size,
-		     pass in the real key size. */
-		  
-		  /* Check for specified bulk key length (unspecified implies
-		     that the bulk key length is the same as encrypted length) */
-		  if (keaParams.bulkKeySize.len > 0)
-		  {
-		      p7dcx->error = SEC_ASN1DecodeItem(NULL, &bulkLength,
-					SEC_ASN1_GET(SEC_IntegerTemplate),
-					&keaParams.bulkKeySize);
-		  }
-		  
-		  if (p7dcx->error != SECSuccess)
-		      goto no_key_found;
-		  
-		  bulkkey = PK11_UnwrapSymKey(tek, CKM_SKIPJACK_CBC64,
-					      &keaParams.nonSkipjackIV, 
-					      &ri->encKey,
-					      bulkType,
-					      CKA_DECRYPT, bulkLength);
-	      }
-	      
-	      
-	      if (bulkkey == NULL)
-	      {
-		  p7dcx->error = PORT_GetError();
-		  PORT_SetError(0);
-		  goto no_key_found;
-	      }
-	      break;
-	  }
       default:
 	p7dcx->error = SEC_ERROR_UNSUPPORTED_KEYALG;
 	break;
     }
 
 no_key_found:
     if (privkey != NULL)
 	SECKEY_DestroyPrivateKey (privkey);
--- a/security/nss/lib/pkcs7/p7encode.c
+++ b/security/nss/lib/pkcs7/p7encode.c
@@ -33,17 +33,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * PKCS7 encoding.
  *
- * $Id: p7encode.c,v 1.13 2008/03/10 00:01:26 wtc%google.com Exp $
+ * $Id: p7encode.c,v 1.14 2011/08/21 01:14:17 wtc%google.com Exp $
  */
 
 #include "p7local.h"
 
 #include "cert.h"
 #include "cryptohi.h"
 #include "keyhi.h"
 #include "secasn1.h"
@@ -86,30 +86,26 @@ sec_pkcs7_encoder_out(void *arg, const c
 static sec_PKCS7CipherObject *
 sec_pkcs7_encoder_start_encrypt (SEC_PKCS7ContentInfo *cinfo,
 						 PK11SymKey *orig_bulkkey)
 {
     SECOidTag kind;
     sec_PKCS7CipherObject *encryptobj;
     SEC_PKCS7RecipientInfo **recipientinfos, *ri;
     SEC_PKCS7EncryptedContentInfo *enccinfo;
-    SEC_PKCS7SMIMEKEAParameters   keaParams;
     SECKEYPublicKey *publickey = NULL;
     SECKEYPrivateKey *ourPrivKey = NULL;
     PK11SymKey  *bulkkey;
     void *mark, *wincx;
     int i;
     PRArenaPool *arena = NULL;
 
     /* Get the context in case we need it below. */
     wincx = cinfo->pwfn_arg;
 
-    /* Clear keaParams, since cleanup code checks the lengths */
-    (void) memset(&keaParams, 0, sizeof(keaParams));
-
     kind = SEC_PKCS7ContentType (cinfo);
     switch (kind) {
       default:
       case SEC_OID_PKCS7_DATA:
       case SEC_OID_PKCS7_DIGESTED_DATA:
       case SEC_OID_PKCS7_SIGNED_DATA:
 	recipientinfos = NULL;
 	enccinfo = NULL;
@@ -192,18 +188,17 @@ sec_pkcs7_encoder_start_encrypt (SEC_PKC
 	/*
 	 * XXX Want an interface that takes a cert and some data and
 	 * fills in an algorithmID and encrypts the data with the public
 	 * key from the cert.  Or, give me two interfaces -- one which
 	 * gets the algorithm tag from a cert (I should not have to go
 	 * down into the subjectPublicKeyInfo myself) and another which
 	 * takes a public key and algorithm tag and data and encrypts
 	 * the data.  Or something like that.  The point is that all
-	 * of the following hardwired RSA and KEA stuff should be done
-	 * elsewhere.
+	 * of the following hardwired RSA stuff should be done elsewhere.
 	 */
 
 	certalgtag=SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm));
 
 	switch (certalgtag) {
 	case SEC_OID_PKCS1_RSA_ENCRYPTION:
 	    encalgtag = certalgtag;
 	    publickey = CERT_ExtractPublicKey (cert);
@@ -218,159 +213,16 @@ sec_pkcs7_encoder_start_encrypt (SEC_PKC
 	    rv = PK11_PubWrapSymKey(PK11_AlgtagToMechanism(certalgtag),publickey,
 				bulkkey,&ri->encKey);
 
 	    SECKEY_DestroyPublicKey(publickey);
 	    publickey = NULL;
 	    if (rv != SECSuccess) goto loser;
 	    params = NULL; /* paranoia */
 	    break;
-	/* ### mwelch -- KEA */ 
-      case SEC_OID_MISSI_KEA_DSS_OLD:
-      case SEC_OID_MISSI_KEA_DSS:
-      case SEC_OID_MISSI_KEA:
-	    {
-#define SMIME_FORTEZZA_RA_LENGTH 128
-#define SMIME_FORTEZZA_IV_LENGTH 24
-#define SMIME_FORTEZZA_MAX_KEY_SIZE 256
-		SECStatus err;
-		PK11SymKey *tek;
-		CERTCertificate *ourCert;
-		SECKEYPublicKey *ourPubKey;
-		SECKEATemplateSelector whichKEA = SECKEAInvalid;
-
-		/* We really want to show our KEA tag as the
-		   key exchange algorithm tag. */
-		encalgtag = SEC_OID_NETSCAPE_SMIME_KEA;
-
-		/* Get the public key of the recipient. */
-		publickey = CERT_ExtractPublicKey(cert);
-		if (publickey == NULL) goto loser;
-
-		/* Find our own cert, and extract its keys. */
-		ourCert = PK11_FindBestKEAMatch(cert,wincx);
-		if (ourCert == NULL) goto loser;
-
-		arena = PORT_NewArena(1024);
-		if (arena == NULL) goto loser;
-
-		ourPubKey = CERT_ExtractPublicKey(ourCert);
-		if (ourPubKey == NULL)
-		{
-		    CERT_DestroyCertificate(ourCert);
-		    goto loser;
-		}
-
-		/* While we're here, copy the public key into the outgoing
-		 * KEA parameters. */
-		SECITEM_CopyItem(arena, &(keaParams.originatorKEAKey),
-				 &(ourPubKey->u.fortezza.KEAKey));
-		SECKEY_DestroyPublicKey(ourPubKey);
-		ourPubKey = NULL;
-
-		/* Extract our private key in order to derive the 
-		 * KEA key. */
-		ourPrivKey = PK11_FindKeyByAnyCert(ourCert,wincx);
-		CERT_DestroyCertificate(ourCert); /* we're done with this */
-		if (!ourPrivKey) goto loser;
-
-		/* Prepare raItem with 128 bytes (filled with zeros). */
-		keaParams.originatorRA.data = 
-		  (unsigned char*)PORT_ArenaAlloc(arena,SMIME_FORTEZZA_RA_LENGTH);
-		keaParams.originatorRA.len = SMIME_FORTEZZA_RA_LENGTH;
-
-
-		/* Generate the TEK (token exchange key) which we use
-		 * to wrap the bulk encryption key. (raItem) will be
-		 * filled with a random seed which we need to send to
-		 * the recipient. */
-		tek = PK11_PubDerive(ourPrivKey, publickey, PR_TRUE,
-				     &keaParams.originatorRA, NULL,
-				     CKM_KEA_KEY_DERIVE, CKM_SKIPJACK_WRAP,
-				     CKA_WRAP, 0, wincx);
-
-		    SECKEY_DestroyPublicKey(publickey);
-		    SECKEY_DestroyPrivateKey(ourPrivKey);
-		    publickey = NULL;
-		    ourPrivKey = NULL;
-		
-		if (!tek)
-		    goto loser;
-
-		ri->encKey.data = (unsigned char*)PORT_ArenaAlloc(cinfo->poolp,
-						  SMIME_FORTEZZA_MAX_KEY_SIZE);
-		ri->encKey.len = SMIME_FORTEZZA_MAX_KEY_SIZE;
-
-		if (ri->encKey.data == NULL)
-		{
-		    PK11_FreeSymKey(tek);
-		    goto loser;
-		}
-
-		/* Wrap the bulk key. What we do with the resulting data
-		   depends on whether we're using Skipjack to wrap the key. */
-		switch(PK11_AlgtagToMechanism(enccinfo->encalg))
-		{
-		case CKM_SKIPJACK_CBC64:
-		case CKM_SKIPJACK_ECB64:
-		case CKM_SKIPJACK_OFB64:
-		case CKM_SKIPJACK_CFB64:
-		case CKM_SKIPJACK_CFB32:
-		case CKM_SKIPJACK_CFB16:
-		case CKM_SKIPJACK_CFB8:
-		    /* do SKIPJACK, we use the wrap mechanism */
-		    err = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, 
-				      tek, bulkkey, &ri->encKey);
-		    whichKEA = SECKEAUsesSkipjack;
-		    break;
-		default:
-		    /* Not SKIPJACK, we encrypt the raw key data */
-		    keaParams.nonSkipjackIV .data = 
-		      (unsigned char*)PORT_ArenaAlloc(arena,
-						     SMIME_FORTEZZA_IV_LENGTH);
-		    keaParams.nonSkipjackIV.len = SMIME_FORTEZZA_IV_LENGTH;
-		    err = PK11_WrapSymKey(CKM_SKIPJACK_CBC64,
-					  &keaParams.nonSkipjackIV, 
-				          tek, bulkkey, &ri->encKey);
-		    if (err != SECSuccess)
-			goto loser;
-
-		    if (ri->encKey.len != PK11_GetKeyLength(bulkkey))
-		    {
-			/* The size of the encrypted key is not the same as
-			   that of the original bulk key, presumably due to
-			   padding. Encode and store the real size of the
-			   bulk key. */
-			if (SEC_ASN1EncodeInteger(arena, 
-						  &keaParams.bulkKeySize,
-						  PK11_GetKeyLength(bulkkey))
-			    == NULL)
-			    err = (SECStatus)PORT_GetError();
-			else
-			    /* use full template for encoding */
-			    whichKEA = SECKEAUsesNonSkipjackWithPaddedEncKey;
-		    }
-		    else
-			/* enc key length == bulk key length */
-			whichKEA = SECKEAUsesNonSkipjack; 
-		    break;
-		}
-
-		PK11_FreeSymKey(tek);
-		if (err != SECSuccess)
-		    goto loser;
-
-		PORT_Assert( whichKEA != SECKEAInvalid);
-
-		/* Encode the KEA parameters into the recipient info. */
-		params = SEC_ASN1EncodeItem(arena,NULL, &keaParams, 
-				      sec_pkcs7_get_kea_template(whichKEA));
-		if (params == NULL) goto loser;
-		break;
-	    }
 	default:
 	    PORT_SetError (SEC_ERROR_INVALID_ALGORITHM);
 	    goto loser;
 	}
 
 	rv = SECOID_SetAlgorithmID(cinfo->poolp, &ri->keyEncAlg, encalgtag, 
 			params);
 	if (rv != SECSuccess)
@@ -935,20 +787,16 @@ sec_pkcs7_encoder_sig_and_certs (SEC_PKC
 		return SECFailure;
 
 	    /*
 	     * XXX I think there should be a cert-level interface for this,
 	     * so that I do not have to know about subjectPublicKeyInfo...
 	     */
 	    signalgtag = SECOID_GetAlgorithmTag (&(cert->subjectPublicKeyInfo.algorithm));
 
-	    /* Fortezza MISSI have weird signature formats.  Map them
-	     * to standard DSA formats */
-	    signalgtag = PK11_FortezzaMapSig(signalgtag);
-
 	    if (signerinfo->authAttr != NULL) {
 		SEC_PKCS7Attribute *attr;
 		SECItem encoded_attrs;
 		SECItem *dummy;
 		SECOidTag algid;
 
 		/*
 		 * First, find and fill in the message digest attribute.
--- a/security/nss/lib/pkcs7/p7local.c
+++ b/security/nss/lib/pkcs7/p7local.c
@@ -35,17 +35,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * Support routines for PKCS7 implementation, none of which are exported.
  * This file should only contain things that are needed by both the
  * encoding/creation side *and* the decoding/decryption side.  Anything
  * else should be static routines in the appropriate file.
  *
- * $Id: p7local.c,v 1.14 2010/03/15 07:25:14 nelson%bolyard.com Exp $
+ * $Id: p7local.c,v 1.15 2011/08/21 01:14:17 wtc%google.com Exp $
  */
 
 #include "p7local.h"
 
 #include "cryptohi.h" 
 #include "secasn1.h"
 #include "secoid.h"
 #include "secitem.h"
@@ -1303,73 +1303,16 @@ static const SEC_ASN1Template SEC_PKCS7E
 	  SEC_PKCS7EncryptedContentInfoTemplate },
     { 0 }
 };
 
 static const SEC_ASN1Template SEC_PointerToPKCS7EncryptedDataTemplate[] = {
     { SEC_ASN1_POINTER, 0, SEC_PKCS7EncryptedDataTemplate }
 };
 
-const SEC_ASN1Template SEC_SMIMEKEAParamTemplateSkipjack[] = {
-	{ SEC_ASN1_SEQUENCE,
-	  0, NULL, sizeof(SEC_PKCS7SMIMEKEAParameters) },
-	{ SEC_ASN1_OCTET_STRING /* | SEC_ASN1_OPTIONAL */,
-	  offsetof(SEC_PKCS7SMIMEKEAParameters,originatorKEAKey) },
-	{ SEC_ASN1_OCTET_STRING,
-	  offsetof(SEC_PKCS7SMIMEKEAParameters,originatorRA) },
-	{ 0 }
-};
-
-const SEC_ASN1Template SEC_SMIMEKEAParamTemplateNoSkipjack[] = {
-	{ SEC_ASN1_SEQUENCE,
-	  0, NULL, sizeof(SEC_PKCS7SMIMEKEAParameters) },
-	{ SEC_ASN1_OCTET_STRING /* | SEC_ASN1_OPTIONAL */,
-	  offsetof(SEC_PKCS7SMIMEKEAParameters,originatorKEAKey) },
-	{ SEC_ASN1_OCTET_STRING,
-	  offsetof(SEC_PKCS7SMIMEKEAParameters,originatorRA) },
-	{ SEC_ASN1_OCTET_STRING  | SEC_ASN1_OPTIONAL ,
-	  offsetof(SEC_PKCS7SMIMEKEAParameters,nonSkipjackIV) },
-	{ 0 }
-};
-
-const SEC_ASN1Template SEC_SMIMEKEAParamTemplateAllParams[] = {
-	{ SEC_ASN1_SEQUENCE,
-	  0, NULL, sizeof(SEC_PKCS7SMIMEKEAParameters) },
-	{ SEC_ASN1_OCTET_STRING /* | SEC_ASN1_OPTIONAL */,
-	  offsetof(SEC_PKCS7SMIMEKEAParameters,originatorKEAKey) },
-	{ SEC_ASN1_OCTET_STRING,
-	  offsetof(SEC_PKCS7SMIMEKEAParameters,originatorRA) },
-	{ SEC_ASN1_OCTET_STRING  | SEC_ASN1_OPTIONAL ,
-	  offsetof(SEC_PKCS7SMIMEKEAParameters,nonSkipjackIV) },
-	{ SEC_ASN1_OCTET_STRING  | SEC_ASN1_OPTIONAL ,
-	  offsetof(SEC_PKCS7SMIMEKEAParameters,bulkKeySize) },
-	{ 0 }
-};
-
-const SEC_ASN1Template*
-sec_pkcs7_get_kea_template(SECKEATemplateSelector whichTemplate)
-{
-	const SEC_ASN1Template *returnVal = NULL;
-
-	switch(whichTemplate)
-	{
-	case SECKEAUsesNonSkipjack:
-		returnVal = SEC_SMIMEKEAParamTemplateNoSkipjack;
-		break;
-	case SECKEAUsesSkipjack:
-		returnVal = SEC_SMIMEKEAParamTemplateSkipjack;
-		break;
-	case SECKEAUsesNonSkipjackWithPaddedEncKey:
-	default:
-		returnVal = SEC_SMIMEKEAParamTemplateAllParams;
-		break;
-	}
-	return returnVal;
-}
-	
 static const SEC_ASN1Template *
 sec_pkcs7_choose_content_template(void *src_or_dest, PRBool encoding)
 {
     const SEC_ASN1Template *theTemplate;
     SEC_PKCS7ContentInfo *cinfo;
     SECOidTag kind;
 
     PORT_Assert (src_or_dest != NULL);
--- a/security/nss/lib/pkcs7/p7local.h
+++ b/security/nss/lib/pkcs7/p7local.h
@@ -40,17 +40,17 @@
  * encoding/creation side *and* the decoding/decryption side.  Anything
  * else should just be static routines in the appropriate file.
  *
  * Do not export this file!  If something in here is really needed outside
  * of pkcs7 code, first try to add a PKCS7 interface which will do it for
  * you.  If that has a problem, then just move out what you need, changing
  * its name as appropriate!
  *
- * $Id: p7local.h,v 1.2 2004/04/25 15:03:13 gerv%gerv.net Exp $
+ * $Id: p7local.h,v 1.3 2011/08/21 01:14:17 wtc%google.com Exp $
  */
 
 #ifndef _P7LOCAL_H_
 #define _P7LOCAL_H_
 
 #include "secpkcs7.h"
 #include "secasn1t.h"
 
@@ -162,18 +162,12 @@ extern SECStatus sec_PKCS7Decrypt (sec_P
 extern SECStatus sec_PKCS7Encrypt (sec_PKCS7CipherObject *obj,
 				   unsigned char *output,
 				   unsigned int *output_len_p,
 				   unsigned int max_output_len,
 				   const unsigned char *input,
 				   unsigned int input_len,
 				   PRBool final);
 
-/* return the correct kea template based on the template selector. skipjack
- * does not have the extra IV.
- */
-const SEC_ASN1Template * 
-sec_pkcs7_get_kea_template(SECKEATemplateSelector whichTemplate);
-
 /************************************************************************/
 SEC_END_PROTOS
 
 #endif /* _P7LOCAL_H_ */
--- a/security/nss/lib/pkcs7/pkcs7t.h
+++ b/security/nss/lib/pkcs7/pkcs7t.h
@@ -32,17 +32,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * Header for pkcs7 types.
  *
- * $Id: pkcs7t.h,v 1.6 2008/06/14 14:20:24 wtc%google.com Exp $
+ * $Id: pkcs7t.h,v 1.7 2011/08/21 01:14:17 wtc%google.com Exp $
  */
 
 #ifndef _PKCS7T_H_
 #define _PKCS7T_H_
 
 #include "plarena.h"
 
 #include "seccomon.h"
@@ -93,17 +93,16 @@ typedef struct SEC_PKCS7SignedDataStr SE
 typedef struct SEC_PKCS7EncryptedContentInfoStr SEC_PKCS7EncryptedContentInfo;
 typedef struct SEC_PKCS7EnvelopedDataStr SEC_PKCS7EnvelopedData;
 typedef struct SEC_PKCS7SignedAndEnvelopedDataStr
 		SEC_PKCS7SignedAndEnvelopedData;
 typedef struct SEC_PKCS7SignerInfoStr SEC_PKCS7SignerInfo;
 typedef struct SEC_PKCS7RecipientInfoStr SEC_PKCS7RecipientInfo;
 typedef struct SEC_PKCS7DigestedDataStr SEC_PKCS7DigestedData;
 typedef struct SEC_PKCS7EncryptedDataStr SEC_PKCS7EncryptedData;
-typedef struct SEC_PKCS7SMIMEKEAParametersStr SEC_PKCS7SMIMEKEAParameters;
 /*
  * The following is not actually a PKCS7 type, but for now it is only
  * used by PKCS7, so we have adopted it.  If someone else *ever* needs
  * it, its name should be changed and it should be moved out of here.
  * Do not dare to use it without doing so!
  */
 typedef struct SEC_PKCS7AttributeStr SEC_PKCS7Attribute;
 
@@ -218,45 +217,16 @@ struct SEC_PKCS7AttributeStr {
     /* The following fields make up an encoded Attribute: */
     SECItem type;
     SECItem **values;	/* data may or may not be encoded */
     /* The following fields are not part of an encoded Attribute: */
     SECOidData *typeTag;
     PRBool encoded;	/* when true, values are encoded */
 };
 
-/* An enumerated type used to select templates based on the encryption
-   scenario and data specifics. */
-typedef enum
-{
-	SECKEAInvalid = -1,
-	SECKEAUsesSkipjack = 0,
-	SECKEAUsesNonSkipjack = 1,
-	SECKEAUsesNonSkipjackWithPaddedEncKey = 2
-} SECKEATemplateSelector;
-
-/* ### mwelch - S/MIME KEA parameters. These don't really fit here,
-                but I cannot think of a more appropriate place at this time. */
-struct SEC_PKCS7SMIMEKEAParametersStr {
-	SECItem originatorKEAKey;	/* sender KEA key (encrypted?) */
-	SECItem originatorRA;		/* random number generated by sender */
-	SECItem nonSkipjackIV;		/* init'n vector for SkipjackCBC64
-					   decryption of KEA key if Skipjack
-					   is not the bulk algorithm used on
-					   the message */
-	SECItem bulkKeySize;		/* if Skipjack is not the bulk
-					   algorithm used on the message,
-					   and the size of the bulk encryption
-					   key is not the same as that of
-					   originatorKEAKey (due to padding
-					   perhaps), this field will contain
-					   the real size of the bulk encryption
-					   key. */
-};
-
 /*
  * Type of function passed to SEC_PKCS7Decode or SEC_PKCS7DecoderStart.
  * If specified, this is where the content bytes (only) will be "sent"
  * as they are recovered during the decoding.
  *
  * XXX Should just combine this with SEC_PKCS7EncoderContentCallback type
  * and use a simpler, common name.
  */
--- a/security/nss/lib/pkcs7/secmime.c
+++ b/security/nss/lib/pkcs7/secmime.c
@@ -33,17 +33,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * Stuff specific to S/MIME policy and interoperability.
  * Depends on PKCS7, but there should be no dependency the other way around.
  *
- * $Id: secmime.c,v 1.4 2004/06/18 00:38:45 jpierre%netscape.com Exp $
+ * $Id: secmime.c,v 1.5 2011/08/21 01:14:17 wtc%google.com Exp $
  */
 
 #include "secmime.h"
 #include "secoid.h"
 #include "pk11func.h"
 #include "ciferfam.h"	/* for CIPHER_FAMILY symbols */
 #include "secasn1.h"
 #include "secitem.h"
@@ -82,18 +82,17 @@ static smime_cipher_map smime_cipher_map
     { SMIME_RC2_CBC_64,		SEC_OID_RC2_CBC,	&smime_rc2p64 },
     { SMIME_RC2_CBC_128,	SEC_OID_RC2_CBC,	&smime_rc2p128 },
 #ifdef SMIME_DOES_RC5
     { SMIME_RC5PAD_64_16_40,	SEC_OID_RC5_CBC_PAD,	&smime_rc5p40 },
     { SMIME_RC5PAD_64_16_64,	SEC_OID_RC5_CBC_PAD,	&smime_rc5p64 },
     { SMIME_RC5PAD_64_16_128,	SEC_OID_RC5_CBC_PAD,	&smime_rc5p128 },
 #endif
     { SMIME_DES_CBC_56,		SEC_OID_DES_CBC,	NULL },
-    { SMIME_DES_EDE3_168,	SEC_OID_DES_EDE3_CBC,	NULL },
-    { SMIME_FORTEZZA,		SEC_OID_FORTEZZA_SKIPJACK, NULL}
+    { SMIME_DES_EDE3_168,	SEC_OID_DES_EDE3_CBC,	NULL }
 };
 
 /*
  * Note, the following value really just needs to be an upper bound
  * on the ciphers.
  */
 static const int smime_symmetric_count = sizeof(smime_cipher_maps)
 					 / sizeof(smime_cipher_map);
@@ -247,18 +246,16 @@ smime_policy_algorithm (SECAlgorithmID *
 		break;
 	    }
 	}
 	break;
       case SEC_OID_DES_CBC:
 	return SMIME_DES_CBC_56;
       case SEC_OID_DES_EDE3_CBC:
 	return SMIME_DES_EDE3_168;
-      case SEC_OID_FORTEZZA_SKIPJACK:
-	return SMIME_FORTEZZA;
 #ifdef SMIME_DOES_RC5
       case SEC_OID_RC5_CBC_PAD:
 	PORT_Assert (0);	/* XXX need to pull out parameters and match */
 	break;
 #endif
       default:
 	break;
     }
@@ -398,18 +395,17 @@ smime_fill_capability (smime_capability 
 static long
 smime_choose_cipher (CERTCertificate *scert, CERTCertificate **rcerts)
 {
     PRArenaPool *poolp;
     long chosen_cipher;
     int *cipher_abilities;
     int *cipher_votes;
     int strong_mapi;
-    int rcount, mapi, max, i;
-	PRBool isFortezza = PK11_FortezzaHasKEA(scert);
+    int rcount, mapi, max;
 
     if (smime_policy_bits == 0) {
 	PORT_SetError (SEC_ERROR_BAD_EXPORT_ALGORITHM);
 	return -1;
     }
 
     chosen_cipher = SMIME_RC2_CBC_40;		/* the default, LCD */
 
@@ -424,33 +420,21 @@ smime_choose_cipher (CERTCertificate *sc
 
     cipher_votes = (int*)PORT_ArenaZAlloc (poolp,
 				     smime_symmetric_count * sizeof(int));
     if (cipher_votes == NULL)
 	goto done;
 
     /*
      * XXX Should have a #define somewhere which specifies default
-     * strong cipher.  (Or better, a way to configure, which would
-     * take Fortezza into account as well.)
+     * strong cipher.  (Or better, a way to configure.)
      */
 
-    /* If the user has the Fortezza preference turned on, make
-     *  that the strong cipher. Otherwise, use triple-DES. */
-    strong_mapi = -1;
-    if (isFortezza) {
-	for(i=0;i < smime_current_pref_index && strong_mapi < 0;i++)
-	{
-	    if (smime_prefs[i] == SMIME_FORTEZZA)
-		strong_mapi = smime_mapi_by_cipher(SMIME_FORTEZZA);
-	}
-    }
-
-    if (strong_mapi == -1)
-	strong_mapi = smime_mapi_by_cipher (SMIME_DES_EDE3_168);
+    /* Make triple-DES the strong cipher. */
+    strong_mapi = smime_mapi_by_cipher (SMIME_DES_EDE3_168);
 
     PORT_Assert (strong_mapi >= 0);
 
     for (rcount = 0; rcerts[rcount] != NULL; rcount++) {
 	SECItem *profile;
 	smime_capability **caps;
 	int capi, pref;
 	SECStatus dstat;
@@ -500,18 +484,16 @@ smime_choose_cipher (CERTCertificate *sc
     }
 
     max = 0;
     for (mapi = 0; mapi < smime_symmetric_count; mapi++) {
 	if (cipher_abilities[mapi] != rcount)
 	    continue;
 	if (! smime_cipher_allowed (smime_cipher_maps[mapi].cipher))
 	    continue;
-	if (!isFortezza  && (smime_cipher_maps[mapi].cipher == SMIME_FORTEZZA))
-		continue;
 	if (cipher_votes[mapi] > max) {
 	    chosen_cipher = smime_cipher_maps[mapi].cipher;
 	    max = cipher_votes[mapi];
 	} /* XXX else if a tie, let scert break it? */
     }
 
 done:
     if (poolp != NULL)
@@ -548,17 +530,16 @@ smime_keysize_by_cipher (unsigned long w
 	/* XXX See comment above; keysize is not enough... */
 	PORT_Assert (0);
 	PORT_SetError (SEC_ERROR_INVALID_ALGORITHM);
 	keysize = -1;
 	break;
 #endif
       case SMIME_DES_CBC_56:
       case SMIME_DES_EDE3_168:
-      case SMIME_FORTEZZA:
 	/*
 	 * These are special; since the key size is fixed, we actually
 	 * want to *avoid* specifying a key size.
 	 */
 	keysize = 0;
 	break;
       default:
 	keysize = -1;
@@ -637,31 +618,28 @@ SECMIME_CreateEncrypted(CERTCertificate 
     }
 
     return cinfo;
 }
 
 
 static smime_capability **smime_capabilities;
 static SECItem *smime_encoded_caps;
-static PRBool lastUsedFortezza;
 
 
 static SECStatus
-smime_init_caps (PRBool isFortezza)
+smime_init_caps (void)
 {
     smime_capability *cap;
     smime_cipher_map *map;
     SECOidData *oiddata;
     SECStatus rv;
-    int i, capIndex;
+    int i;
 
-    if (smime_encoded_caps != NULL 
-	&& (! smime_prefs_changed) 
-	&& lastUsedFortezza == isFortezza)
+    if (smime_encoded_caps != NULL && (! smime_prefs_changed))
 	return SECSuccess;
 
     if (smime_encoded_caps != NULL) {
 	SECITEM_FreeItem (smime_encoded_caps, PR_TRUE);
 	smime_encoded_caps = NULL;
     }
 
     if (smime_capabilities == NULL) {
@@ -685,58 +663,40 @@ smime_init_caps (PRBool isFortezza)
 
        (b) Encode, using ASN.1, the cipher information in 
            smime_capabilities, leaving the encoded result in 
 	   smime_encoded_caps.
 
        (In the process of performing (a), Lisa put in some optimizations
        which allow us to avoid needlessly re-populating elements in 
        smime_capabilities as we walk through smime_prefs.)
-
-       We want to use separate loop variables for smime_prefs and
-       smime_capabilities because in the case where the Skipjack cipher 
-       is turned on in the prefs, but where we don't want to include 
-       Skipjack in the encoded capabilities (presumably due to using a 
-       non-fortezza cert when sending a message), we want to avoid creating
-       an empty element in smime_capabilities. This would otherwise cause 
-       the encoding step to produce an empty set, since Skipjack happens 
-       to be the first cipher in smime_prefs, if it is turned on.
     */
-    for (i = 0, capIndex = 0; i < smime_current_pref_index; i++, capIndex++) {
+    for (i = 0; i < smime_current_pref_index; i++) {
 	int mapi;
 
 	/* Get the next cipher preference in smime_prefs. */
 	mapi = smime_mapi_by_cipher (smime_prefs[i]);
 	if (mapi < 0)
 	    break;
 
 	/* Find the corresponding entry in the cipher map. */
 	PORT_Assert (mapi < smime_symmetric_count);
 	map = &(smime_cipher_maps[mapi]);
 
-	/* If we're using a non-Fortezza cert, only advertise non-Fortezza
-	   capabilities. (We advertise all capabilities if we have a 
-	   Fortezza cert.) */
-	if ((!isFortezza) && (map->cipher == SMIME_FORTEZZA))
-	{
-	    capIndex--; /* we want to visit the same caps index entry next time */
-	    continue;
-	}
-
 	/*
 	 * Convert the next preference found in smime_prefs into an
 	 * smime_capability.
 	 */
 
-	cap = smime_capabilities[capIndex];
+	cap = smime_capabilities[i];
 	if (cap == NULL) {
 	    cap = (smime_capability*)PORT_ZAlloc (sizeof(smime_capability));
 	    if (cap == NULL)
 		break;
-	    smime_capabilities[capIndex] = cap;
+	    smime_capabilities[i] = cap;
 	} else if (cap->cipher == smime_prefs[i]) {
 	    continue;		/* no change to this one */
 	}
 
 	cap->capIDTag = map->algtag;
 	oiddata = SECOID_FindOIDByTag (map->algtag);
 	if (oiddata == NULL)
 	    break;
@@ -760,57 +720,49 @@ smime_init_caps (PRBool isFortezza)
 	}
 
 	cap->cipher = smime_prefs[i];
     }
 
     if (i != smime_current_pref_index)
 	return rv;
 
-    while (capIndex < smime_symmetric_count) {
-	cap = smime_capabilities[capIndex];
+    while (i < smime_symmetric_count) {
+	cap = smime_capabilities[i];
 	if (cap != NULL) {
 	    SECITEM_FreeItem (&(cap->capabilityID), PR_FALSE);
 	    PORT_Free (cap);
 	}
-	smime_capabilities[capIndex] = NULL;
-	capIndex++;
+	smime_capabilities[i] = NULL;
+	i++;
     }
-    smime_capabilities[capIndex] = NULL;
+    smime_capabilities[i] = NULL;
 
     smime_encoded_caps = SEC_ASN1EncodeItem (NULL, NULL, &smime_capabilities,
 					     smime_capabilities_template);
     if (smime_encoded_caps == NULL)
 	return SECFailure;
 
-    lastUsedFortezza = isFortezza;
-
     return SECSuccess;
 }
 
 
 static SECStatus
 smime_add_profile (CERTCertificate *cert, SEC_PKCS7ContentInfo *cinfo)
 {
-    PRBool isFortezza = PR_FALSE;
-
     PORT_Assert (smime_prefs_complete);
     if (! smime_prefs_complete)
 	return SECFailure;
 
-    /* See if the sender's cert specifies Fortezza key exchange. */
-    if (cert != NULL)
-	isFortezza = PK11_FortezzaHasKEA(cert);
-
     /* For that matter, if capabilities haven't been initialized yet,
        do so now. */
-    if (isFortezza != lastUsedFortezza || smime_encoded_caps == NULL || smime_prefs_changed) {
+    if (smime_encoded_caps == NULL || smime_prefs_changed) {
 	SECStatus rv;
 
-	rv = smime_init_caps(isFortezza);
+	rv = smime_init_caps();
 	if (rv != SECSuccess)
 	    return rv;
 
 	PORT_Assert (smime_encoded_caps != NULL);
     }
 
     return SEC_PKCS7AddSignedAttribute (cinfo, SEC_OID_PKCS9_SMIME_CAPABILITIES,
 					smime_encoded_caps);
--- a/security/nss/lib/smime/cmsasn1.c
+++ b/security/nss/lib/smime/cmsasn1.c
@@ -32,17 +32,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * CMS ASN.1 templates
  *
- * $Id: cmsasn1.c,v 1.9 2011/01/31 23:56:30 rrelyea%redhat.com Exp $
+ * $Id: cmsasn1.c,v 1.10 2011/08/21 01:14:18 wtc%google.com Exp $
  */
 
 #include "cmslocal.h"
 
 #include "cert.h"
 #include "key.h"
 #include "secasn1.h"
 #include "secitem.h"
@@ -489,76 +489,16 @@ SEC_ASN1_CHOOSER_IMPLEMENT(NSSCMSGeneric
 
 const SEC_ASN1Template NSS_PointerToCMSGenericWrapperDataTemplate[] = {
     { SEC_ASN1_POINTER, 0, NSSCMSGenericWrapperDataTemplate }
 };
 
 SEC_ASN1_CHOOSER_IMPLEMENT(NSS_PointerToCMSGenericWrapperDataTemplate);
 
 /* -----------------------------------------------------------------------------
- * FORTEZZA KEA
- */
-const SEC_ASN1Template NSS_SMIMEKEAParamTemplateSkipjack[] = {
-	{ SEC_ASN1_SEQUENCE,
-	  0, NULL, sizeof(NSSCMSSMIMEKEAParameters) },
-	{ SEC_ASN1_OCTET_STRING /* | SEC_ASN1_OPTIONAL */,
-	  offsetof(NSSCMSSMIMEKEAParameters,originatorKEAKey) },
-	{ SEC_ASN1_OCTET_STRING,
-	  offsetof(NSSCMSSMIMEKEAParameters,originatorRA) },
-	{ 0 }
-};
-
-const SEC_ASN1Template NSS_SMIMEKEAParamTemplateNoSkipjack[] = {
-	{ SEC_ASN1_SEQUENCE,
-	  0, NULL, sizeof(NSSCMSSMIMEKEAParameters) },
-	{ SEC_ASN1_OCTET_STRING /* | SEC_ASN1_OPTIONAL */,
-	  offsetof(NSSCMSSMIMEKEAParameters,originatorKEAKey) },
-	{ SEC_ASN1_OCTET_STRING,
-	  offsetof(NSSCMSSMIMEKEAParameters,originatorRA) },
-	{ SEC_ASN1_OCTET_STRING  | SEC_ASN1_OPTIONAL ,
-	  offsetof(NSSCMSSMIMEKEAParameters,nonSkipjackIV) },
-	{ 0 }
-};
-
-const SEC_ASN1Template NSS_SMIMEKEAParamTemplateAllParams[] = {
-	{ SEC_ASN1_SEQUENCE,
-	  0, NULL, sizeof(NSSCMSSMIMEKEAParameters) },
-	{ SEC_ASN1_OCTET_STRING /* | SEC_ASN1_OPTIONAL */,
-	  offsetof(NSSCMSSMIMEKEAParameters,originatorKEAKey) },
-	{ SEC_ASN1_OCTET_STRING,
-	  offsetof(NSSCMSSMIMEKEAParameters,originatorRA) },
-	{ SEC_ASN1_OCTET_STRING  | SEC_ASN1_OPTIONAL ,
-	  offsetof(NSSCMSSMIMEKEAParameters,nonSkipjackIV) },
-	{ SEC_ASN1_OCTET_STRING  | SEC_ASN1_OPTIONAL ,
-	  offsetof(NSSCMSSMIMEKEAParameters,bulkKeySize) },
-	{ 0 }
-};
-
-const SEC_ASN1Template *
-nss_cms_get_kea_template(NSSCMSKEATemplateSelector whichTemplate)
-{
-	const SEC_ASN1Template *returnVal = NULL;
-
-	switch(whichTemplate)
-	{
-	case NSSCMSKEAUsesNonSkipjack:
-		returnVal = NSS_SMIMEKEAParamTemplateNoSkipjack;
-		break;
-	case NSSCMSKEAUsesSkipjack:
-		returnVal = NSS_SMIMEKEAParamTemplateSkipjack;
-		break;
-	case NSSCMSKEAUsesNonSkipjackWithPaddedEncKey:
-	default:
-		returnVal = NSS_SMIMEKEAParamTemplateAllParams;
-		break;
-	}
-	return returnVal;
-}
-
-/* -----------------------------------------------------------------------------
  *
  */
 static const SEC_ASN1Template *
 nss_cms_choose_content_template(void *src_or_dest, PRBool encoding)
 {
     const SEC_ASN1Template *theTemplate;
     NSSCMSContentInfo *cinfo;
     SECOidTag type;
--- a/security/nss/lib/smime/cmsdecode.c
+++ b/security/nss/lib/smime/cmsdecode.c
@@ -32,17 +32,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * CMS decoding.
  *
- * $Id: cmsdecode.c,v 1.13 2011/03/15 17:45:21 emaldona%redhat.com Exp $
+ * $Id: cmsdecode.c,v 1.14 2011/09/30 22:10:13 rrelyea%redhat.com Exp $
  */
 
 #include "cmslocal.h"
 
 #include "cert.h"
 #include "key.h"
 #include "secasn1.h"
 #include "secitem.h"
@@ -55,16 +55,18 @@ struct NSSCMSDecoderContextStr {
     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;
+    PRBool			first_decoded;
+    PRBool			need_indefinite_finish;
 };
 
 struct NSSCMSDecoderDataStr {
     SECItem data; 	/* must be first */
     unsigned int totalBufferSize;
 };
 
 typedef struct NSSCMSDecoderDataStr NSSCMSDecoderData;
@@ -311,16 +313,21 @@ nss_cms_before_data(NSSCMSDecoderContext
 
     childp7dcx->cmsg = p7dcx->cmsg;	/* backpointer to root message */
 
     /* should the child decoder encounter real data, 
     ** it must give it to the caller 
     */
     childp7dcx->cb = p7dcx->cb;
     childp7dcx->cb_arg = p7dcx->cb_arg;
+    childp7dcx->first_decoded = PR_FALSE;
+    childp7dcx->need_indefinite_finish = PR_FALSE;
+    if (childtype == SEC_OID_PKCS7_SIGNED_DATA) {
+	childp7dcx->first_decoded = PR_TRUE;
+    }
 
     /* now set up the parent to hand decoded data to the next level decoder */
     p7dcx->cb = (NSSCMSContentCallback)NSS_CMSDecoder_Update;
     p7dcx->cb_arg = childp7dcx;
 
     PORT_ArenaUnmark(poolp, mark);
 
     return SECSuccess;
@@ -343,16 +350,23 @@ nss_cms_after_data(NSSCMSDecoderContext 
     /* 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);
 
     /* finish any "inner" decoders - there's no more data coming... */
     if (p7dcx->childp7dcx != NULL) {
 	childp7dcx = p7dcx->childp7dcx;
 	if (childp7dcx->dcx != NULL) {
+	    /* we started and indefinite sequence somewhere, not complete it */
+	    if (childp7dcx->need_indefinite_finish) {
+		static const char lbuf[2] = { 0, 0 };
+		NSS_CMSDecoder_Update(childp7dcx, lbuf, sizeof(lbuf));
+		childp7dcx->need_indefinite_finish = PR_FALSE;
+	    }
+
 	    if (SEC_ASN1DecoderFinish(childp7dcx->dcx) != SECSuccess) {
 		/* do what? free content? */
 		rv = SECFailure;
 	    } else {
 		rv = nss_cms_after_end(childp7dcx);
 	    }
 	    if (rv != SECSuccess)
 		goto done;
@@ -642,37 +656,59 @@ NSS_CMSDecoder_Start(PRArenaPool *poolp,
 
     SEC_ASN1DecoderSetNotifyProc (p7dcx->dcx, nss_cms_decoder_notify, p7dcx);
 
     p7dcx->cmsg = cmsg;
     p7dcx->type = SEC_OID_UNKNOWN;
 
     p7dcx->cb = cb;
     p7dcx->cb_arg = cb_arg;
-
+    p7dcx->first_decoded = PR_FALSE;
+    p7dcx->need_indefinite_finish = PR_FALSE;
     return p7dcx;
 }
 
 /*
  * NSS_CMSDecoder_Update - feed DER-encoded data to decoder
  */
 SECStatus
 NSS_CMSDecoder_Update(NSSCMSDecoderContext *p7dcx, const char *buf, 
                       unsigned long len)
 {
-    SECStatus rv;
+    SECStatus rv = SECSuccess;
     if (p7dcx->dcx != NULL && p7dcx->error == 0) {	
     	/* if error is set already, don't bother */
+	if ((p7dcx->type == SEC_OID_PKCS7_SIGNED_DATA) 
+		&& (p7dcx->first_decoded==PR_TRUE)
+		&& (buf[0] == SEC_ASN1_INTEGER)) {
+	    /* Microsoft Windows 2008 left out the Sequence wrapping in some
+	     * of their kerberos replies. If we are here, we most likely are
+	     * dealing with one of those replies. Supply the Sequence wrap
+	     * as indefinite encoding (since we don't know the total length
+	     * yet) */
+	     static const char lbuf[2] = 
+		{ SEC_ASN1_SEQUENCE|SEC_ASN1_CONSTRUCTED, 0x80 };
+	     rv = SEC_ASN1DecoderUpdate(p7dcx->dcx, lbuf, sizeof(lbuf));
+	     if (rv != SECSuccess) {
+		goto loser;
+	    }
+	    /* ok, we're going to need the indefinite finish when we are done */
+	    p7dcx->need_indefinite_finish = PR_TRUE;
+	}
+	
 	rv = SEC_ASN1DecoderUpdate(p7dcx->dcx, buf, len);
-	if (rv != SECSuccess) {
-	    p7dcx->error = PORT_GetError();
-	    PORT_Assert (p7dcx->error);
-	    if (p7dcx->error == 0)
-		p7dcx->error = -1;
-	}
+    }
+
+loser:
+    p7dcx->first_decoded = PR_FALSE;
+    if (rv != SECSuccess) {
+	p7dcx->error = PORT_GetError();
+	PORT_Assert (p7dcx->error);
+	if (p7dcx->error == 0)
+	    p7dcx->error = -1;
     }
 
     if (p7dcx->error == 0)
 	return SECSuccess;
 
     /* there has been a problem, let's finish the decoder */
     if (p7dcx->dcx != NULL) {
 	(void) SEC_ASN1DecoderFinish (p7dcx->dcx);
--- a/security/nss/lib/smime/cmsencode.c
+++ b/security/nss/lib/smime/cmsencode.c
@@ -32,17 +32,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * CMS encoding.
  *
- * $Id: cmsencode.c,v 1.11 2011/02/11 01:53:17 emaldona%redhat.com Exp $
+ * $Id: cmsencode.c,v 1.12 2011/08/21 01:14:18 wtc%google.com Exp $
  */
 
 #include "cmslocal.h"
 
 #include "cert.h"
 #include "key.h"
 #include "secasn1.h"
 #include "secoid.h"
@@ -721,17 +721,16 @@ loser:
  *
  * we need to walk down the chain of encoders and the finish them from the innermost out
  */
 SECStatus
 NSS_CMSEncoder_Finish(NSSCMSEncoderContext *p7ecx)
 {
     SECStatus rv = SECFailure;
     NSSCMSContentInfo *cinfo;
-    SECOidTag childtype;
 
     /*
      * Finish any inner decoders before us so that all the encoded data is flushed
      * This basically finishes all the decoders from the innermost to the outermost.
      * Finishing an inner decoder may result in data being updated to the outer decoder
      * while we are already in NSS_CMSEncoder_Finish, but that's allright.
      */
     if (p7ecx->childp7ecx) {
--- a/security/nss/lib/smime/cmslocal.h
+++ b/security/nss/lib/smime/cmslocal.h
@@ -37,17 +37,17 @@
 /*
  * Support routines for CMS implementation, none of which are exported.
  *
  * Do not export this file!  If something in here is really needed outside
  * of smime code, first try to add a CMS interface which will do it for
  * you.  If that has a problem, then just move out what you need, changing
  * its name as appropriate!
  *
- * $Id: cmslocal.h,v 1.6 2011/01/28 23:03:59 rrelyea%redhat.com Exp $
+ * $Id: cmslocal.h,v 1.8 2011/09/30 19:42:09 rrelyea%redhat.com Exp $
  */
 
 #ifndef _CMSLOCAL_H_
 #define _CMSLOCAL_H_
 
 #include "cms.h"
 #include "cmsreclist.h"
 #include "secasn1t.h"
@@ -195,24 +195,16 @@ NSS_CMSUtil_EncryptSymKey_RSAPubKey(PLAr
  * this function takes an RSA-wrapped symmetric key and unwraps it, returning a symmetric
  * key handle. Please note that the actual unwrapped key data may not be allowed to leave
  * a hardware token...
  */
 extern PK11SymKey *
 NSS_CMSUtil_DecryptSymKey_RSA(SECKEYPrivateKey *privkey, SECItem *encKey, SECOidTag bulkalgtag);
 
 extern SECStatus
-NSS_CMSUtil_EncryptSymKey_MISSI(PLArenaPool *poolp, CERTCertificate *cert, PK11SymKey *key,
-			SECOidTag symalgtag, SECItem *encKey, SECItem **pparams, void *pwfn_arg);
-
-extern PK11SymKey *
-NSS_CMSUtil_DecryptSymKey_MISSI(SECKEYPrivateKey *privkey, SECItem *encKey,
-			SECAlgorithmID *keyEncAlg, SECOidTag bulkalgtag, void *pwfn_arg);
-
-extern SECStatus
 NSS_CMSUtil_EncryptSymKey_ESDH(PLArenaPool *poolp, CERTCertificate *cert, PK11SymKey *key,
 			SECItem *encKey, SECItem **ukm, SECAlgorithmID *keyEncAlg,
 			SECItem *originatorPubKey);
 
 extern PK11SymKey *
 NSS_CMSUtil_DecryptSymKey_ESDH(SECKEYPrivateKey *privkey, SECItem *encKey,
 			SECAlgorithmID *keyEncAlg, SECOidTag bulkalgtag, void *pwfn_arg);
 
@@ -351,16 +343,22 @@ NSS_CMSAttributeArray_SetAttr(PLArenaPoo
 
 /*
  * NSS_CMSSignedData_AddTempCertificate - add temporary certificate references.
  * They may be needed for signature verification on the data, for example.
  */
 extern SECStatus
 NSS_CMSSignedData_AddTempCertificate(NSSCMSSignedData *sigd, CERTCertificate *cert);
 
+/*
+ * local function to handle compatibility issues
+ * by mapping a signature algorithm back to a digest.
+ */
+SECOidTag NSS_CMSUtil_MapSignAlgs(SECOidTag signAlg);
+
 
 /************************************************************************/
 
 /*
  * local functions to handle user defined S/MIME content types
  */
 
 
--- a/security/nss/lib/smime/cmspubkey.c
+++ b/security/nss/lib/smime/cmspubkey.c
@@ -32,17 +32,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * CMS public key crypto
  *
- * $Id: cmspubkey.c,v 1.7 2004/04/25 15:03:16 gerv%gerv.net Exp $
+ * $Id: cmspubkey.c,v 1.8 2011/08/21 01:14:18 wtc%google.com Exp $
  */
 
 #include "cmslocal.h"
 
 #include "cert.h"
 #include "key.h"
 #include "secasn1.h"
 #include "secitem.h"
@@ -136,262 +136,16 @@ NSS_CMSUtil_DecryptSymKey_RSA(SECKEYPriv
     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) ========================================================== */
-
-extern const SEC_ASN1Template NSS_SMIMEKEAParamTemplateAllParams[];
-
-SECStatus
-NSS_CMSUtil_EncryptSymKey_MISSI(PLArenaPool *poolp, CERTCertificate *cert, PK11SymKey *bulkkey,
-			SECOidTag symalgtag, SECItem *encKey, SECItem **pparams, void *pwfn_arg)
-{
-    SECOidTag certalgtag;	/* the certificate's encryption algorithm */
-    SECOidTag encalgtag;	/* the algorithm used for key exchange/agreement */
-    SECStatus rv = SECFailure;
-    SECItem *params = NULL;
-    SECStatus err;
-    PK11SymKey *tek;
-    CERTCertificate *ourCert;
-    SECKEYPublicKey *ourPubKey, *publickey = NULL;
-    SECKEYPrivateKey *ourPrivKey = NULL;
-    NSSCMSKEATemplateSelector whichKEA = NSSCMSKEAInvalid;
-    NSSCMSSMIMEKEAParameters keaParams;
-    PLArenaPool *arena = NULL;
-    extern const SEC_ASN1Template *nss_cms_get_kea_template(NSSCMSKEATemplateSelector whichTemplate);
-
-    /* Clear keaParams, since cleanup code checks the lengths */
-    (void) memset(&keaParams, 0, sizeof(keaParams));
-
-    certalgtag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm));
-    PORT_Assert(certalgtag == SEC_OID_MISSI_KEA_DSS_OLD ||
-		certalgtag == SEC_OID_MISSI_KEA_DSS ||
-		certalgtag == SEC_OID_MISSI_KEA);
-
-#define SMIME_FORTEZZA_RA_LENGTH 128
-#define SMIME_FORTEZZA_IV_LENGTH 24
-#define SMIME_FORTEZZA_MAX_KEY_SIZE 256
-
-    /* We really want to show our KEA tag as the key exchange algorithm tag. */
-    encalgtag = SEC_OID_NETSCAPE_SMIME_KEA;
-
-    /* Get the public key of the recipient. */
-    publickey = CERT_ExtractPublicKey(cert);
-    if (publickey == NULL) goto loser;
-
-    /* Find our own cert, and extract its keys. */
-    ourCert = PK11_FindBestKEAMatch(cert, pwfn_arg);
-    if (ourCert == NULL) goto loser;
-
-    arena = PORT_NewArena(1024);
-    if (arena == NULL)
-	goto loser;
-
-    ourPubKey = CERT_ExtractPublicKey(ourCert);
-    if (ourPubKey == NULL) {
-	CERT_DestroyCertificate(ourCert);
-	goto loser;
-    }
-
-    /* While we're here, copy the public key into the outgoing
-     * KEA parameters. */
-    SECITEM_CopyItem(arena, &(keaParams.originatorKEAKey), &(ourPubKey->u.fortezza.KEAKey));
-    SECKEY_DestroyPublicKey(ourPubKey);
-    ourPubKey = NULL;
-
-    /* Extract our private key in order to derive the KEA key. */
-    ourPrivKey = PK11_FindKeyByAnyCert(ourCert, pwfn_arg);
-    CERT_DestroyCertificate(ourCert); /* we're done with this */
-    if (!ourPrivKey)
-	goto loser;
-
-    /* Prepare raItem with 128 bytes (filled with zeros). */
-    keaParams.originatorRA.data = (unsigned char *)PORT_ArenaAlloc(arena,SMIME_FORTEZZA_RA_LENGTH);
-    keaParams.originatorRA.len = SMIME_FORTEZZA_RA_LENGTH;
-
-    /* Generate the TEK (token exchange key) which we use
-     * to wrap the bulk encryption key. (keaparams.originatorRA) will be
-     * filled with a random seed which we need to send to
-     * the recipient. (user keying material in RFC2630/DSA speak) */
-    tek = PK11_PubDerive(ourPrivKey, publickey, PR_TRUE,
-			 &keaParams.originatorRA, NULL,
-			 CKM_KEA_KEY_DERIVE, CKM_SKIPJACK_WRAP,
-			 CKA_WRAP, 0,  pwfn_arg);
-
-    SECKEY_DestroyPublicKey(publickey);
-    SECKEY_DestroyPrivateKey(ourPrivKey);
-    publickey = NULL;
-    ourPrivKey = NULL;
-    
-    if (!tek)
-	goto loser;
-
-    /* allocate space for the wrapped key data */
-    encKey->data = (unsigned char *)PORT_ArenaAlloc(poolp, SMIME_FORTEZZA_MAX_KEY_SIZE);
-    encKey->len = SMIME_FORTEZZA_MAX_KEY_SIZE;
-
-    if (encKey->data == NULL) {
-	PK11_FreeSymKey(tek);
-	goto loser;
-    }
-
-    /* Wrap the bulk key. What we do with the resulting data
-       depends on whether we're using Skipjack to wrap the key. */
-    switch (PK11_AlgtagToMechanism(symalgtag)) {
-    case CKM_SKIPJACK_CBC64:
-    case CKM_SKIPJACK_ECB64:
-    case CKM_SKIPJACK_OFB64:
-    case CKM_SKIPJACK_CFB64:
-    case CKM_SKIPJACK_CFB32:
-    case CKM_SKIPJACK_CFB16:
-    case CKM_SKIPJACK_CFB8:
-	/* SKIPJACK, we use the wrap mechanism because we can do it on the hardware */
-	err = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, tek, bulkkey, encKey);
-	whichKEA = NSSCMSKEAUsesSkipjack;
-	break;
-    default:
-	/* Not SKIPJACK, we encrypt the raw key data */
-	keaParams.nonSkipjackIV.data = 
-	  (unsigned char *)PORT_ArenaAlloc(arena, SMIME_FORTEZZA_IV_LENGTH);
-	keaParams.nonSkipjackIV.len = SMIME_FORTEZZA_IV_LENGTH;
-	err = PK11_WrapSymKey(CKM_SKIPJACK_CBC64, &keaParams.nonSkipjackIV, tek, bulkkey, encKey);
-	if (err != SECSuccess)
-	    goto loser;
-
-	if (encKey->len != PK11_GetKeyLength(bulkkey)) {
-	    /* The size of the encrypted key is not the same as
-	       that of the original bulk key, presumably due to
-	       padding. Encode and store the real size of the
-	       bulk key. */
-	    if (SEC_ASN1EncodeInteger(arena, &keaParams.bulkKeySize, PK11_GetKeyLength(bulkkey)) == NULL)
-		err = (SECStatus)PORT_GetError();
-	    else
-		/* use full template for encoding */
-		whichKEA = NSSCMSKEAUsesNonSkipjackWithPaddedEncKey;
-	}
-	else
-	    /* enc key length == bulk key length */
-	    whichKEA = NSSCMSKEAUsesNonSkipjack; 
-	break;
-    }
-
-    PK11_FreeSymKey(tek);
-
-    if (err != SECSuccess)
-	goto loser;
-
-    PORT_Assert(whichKEA != NSSCMSKEAInvalid);
-
-    /* Encode the KEA parameters into the recipient info. */
-    params = SEC_ASN1EncodeItem(poolp, NULL, &keaParams, nss_cms_get_kea_template(whichKEA));
-    if (params == NULL)
-	goto loser;
-
-    /* pass back the algorithm params */
-    *pparams = params;
-
-    rv = SECSuccess;
-
-loser:
-    if (arena)
-	PORT_FreeArena(arena, PR_FALSE);
-    if (publickey)
-        SECKEY_DestroyPublicKey(publickey);
-    if (ourPrivKey)
-        SECKEY_DestroyPrivateKey(ourPrivKey);
-    return rv;
-}
-
-PK11SymKey *
-NSS_CMSUtil_DecryptSymKey_MISSI(SECKEYPrivateKey *privkey, SECItem *encKey, SECAlgorithmID *keyEncAlg, SECOidTag bulkalgtag, void *pwfn_arg)
-{
-    /* fortezza: do a key exchange */
-    SECStatus err;
-    CK_MECHANISM_TYPE bulkType;
-    PK11SymKey *tek;
-    SECKEYPublicKey *originatorPubKey;
-    NSSCMSSMIMEKEAParameters keaParams;
-    PK11SymKey *bulkkey;
-    int bulkLength;
-
-    (void) memset(&keaParams, 0, sizeof(keaParams));
-
-    /* NOTE: this uses the SMIME v2 recipientinfo for compatibility.
-       All additional KEA parameters are DER-encoded in the encryption algorithm parameters */
-
-    /* Decode the KEA algorithm parameters. */
-    err = SEC_ASN1DecodeItem(NULL, &keaParams, NSS_SMIMEKEAParamTemplateAllParams,
-			     &(keyEncAlg->parameters));
-    if (err != SECSuccess)
-	goto loser;
-
-    /* get originator's public key */
-   originatorPubKey = PK11_MakeKEAPubKey(keaParams.originatorKEAKey.data,
-			   keaParams.originatorKEAKey.len);
-   if (originatorPubKey == NULL)
-	  goto loser;
-    
-   /* Generate the TEK (token exchange key) which we use to unwrap the bulk encryption key.
-      The Derive function generates a shared secret and combines it with the originatorRA
-      data to come up with an unique session key */
-   tek = PK11_PubDerive(privkey, originatorPubKey, PR_FALSE,
-			 &keaParams.originatorRA, NULL,
-			 CKM_KEA_KEY_DERIVE, CKM_SKIPJACK_WRAP,
-			 CKA_WRAP, 0, pwfn_arg);
-   SECKEY_DestroyPublicKey(originatorPubKey);	/* not needed anymore */
-   if (tek == NULL)
-	goto loser;
-    
-    /* Now that we have the TEK, unwrap the bulk key
-       with which to decrypt the message. We have to
-       do one of two different things depending on 
-       whether Skipjack was used for *bulk* encryption 
-       of the message. */
-    bulkType = PK11_AlgtagToMechanism(bulkalgtag);
-    switch (bulkType) {
-    case CKM_SKIPJACK_CBC64:
-    case CKM_SKIPJACK_ECB64:
-    case CKM_SKIPJACK_OFB64:
-    case CKM_SKIPJACK_CFB64:
-    case CKM_SKIPJACK_CFB32:
-    case CKM_SKIPJACK_CFB16:
-    case CKM_SKIPJACK_CFB8:
-	/* Skipjack is being used as the bulk encryption algorithm.*/
-	/* Unwrap the bulk key. */
-	bulkkey = PK11_UnwrapSymKey(tek, CKM_SKIPJACK_WRAP, NULL,
-				    encKey, CKM_SKIPJACK_CBC64, CKA_DECRYPT, 0);
-	break;
-    default:
-	/* Skipjack was not used for bulk encryption of this
-	   message. Use Skipjack CBC64, with the nonSkipjackIV
-	   part of the KEA key parameters, to decrypt 
-	   the bulk key. If the optional parameter bulkKeySize is present,
-	   bulk key size is different than the encrypted key size */
-	if (keaParams.bulkKeySize.len > 0) {
-	    err = SEC_ASN1DecodeItem(NULL, &bulkLength,
-				     SEC_ASN1_GET(SEC_IntegerTemplate),
-				     &keaParams.bulkKeySize);
-	    if (err != SECSuccess)
-		goto loser;
-	}
-	
-	bulkkey = PK11_UnwrapSymKey(tek, CKM_SKIPJACK_CBC64, &keaParams.nonSkipjackIV, 
-				    encKey, bulkType, CKA_DECRYPT, bulkLength);
-	break;
-    }
-    return bulkkey;
-loser:
-    return NULL;
-}
-
 /* ====== ESDH (Ephemeral-Static Diffie-Hellman) ==================================== */
 
 SECStatus
 NSS_CMSUtil_EncryptSymKey_ESDH(PLArenaPool *poolp, CERTCertificate *cert, PK11SymKey *key,
 			SECItem *encKey, SECItem **ukm, SECAlgorithmID *keyEncAlg,
 			SECItem *pubKey)
 {
 #if 0 /* not yet done */
--- a/security/nss/lib/smime/cmsrecinfo.c
+++ b/security/nss/lib/smime/cmsrecinfo.c
@@ -32,17 +32,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * CMS recipientInfo methods.
  *
- * $Id: cmsrecinfo.c,v 1.20 2008/06/06 01:16:18 wtc%google.com Exp $
+ * $Id: cmsrecinfo.c,v 1.21 2011/08/21 01:14:18 wtc%google.com Exp $
  */
 
 #include "cmslocal.h"
 
 #include "cert.h"
 #include "key.h"
 #include "secasn1.h"
 #include "secitem.h"
@@ -574,21 +574,16 @@ NSS_CMSRecipientInfo_UnwrapBulkKey(NSSCM
 	encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.keyTransRecipientInfo.keyEncAlg));
 	enckey = &(ri->ri.keyTransRecipientInfo.encKey); /* ignore subIndex */
 	switch (encalgtag) {
 	case SEC_OID_PKCS1_RSA_ENCRYPTION:
 	    /* RSA encryption algorithm: */
 	    /* get the symmetric (bulk) key by unwrapping it using our private key */
 	    bulkkey = NSS_CMSUtil_DecryptSymKey_RSA(privkey, enckey, bulkalgtag);
 	    break;
-	case SEC_OID_NETSCAPE_SMIME_KEA:
-	    /* FORTEZZA key exchange algorithm */
-	    /* the supplemental data is in the parameters of encalg */
-	    bulkkey = NSS_CMSUtil_DecryptSymKey_MISSI(privkey, enckey, encalg, bulkalgtag, ri->cmsg->pwfn_arg);
-	    break;
 	default:
 	    error = SEC_ERROR_UNSUPPORTED_KEYALG;
 	    goto loser;
 	}
 	break;
     case NSSCMSRecipientInfoID_KeyAgree:
 	encalg = &(ri->ri.keyAgreeRecipientInfo.keyEncAlg);
 	encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.keyAgreeRecipientInfo.keyEncAlg));
@@ -599,16 +594,17 @@ NSS_CMSRecipientInfo_UnwrapBulkKey(NSSCM
 	    /* XXX not yet implemented */
 	    /* XXX problem: SEC_OID_X942_DIFFIE_HELMAN_KEY points to a PKCS3 mechanism! */
 	    /* we support ephemeral-static DH only, so if the recipientinfo */
 	    /* has originator stuff in it, we punt (or do we? shouldn't be that hard...) */
 	    /* first, we derive the KEK (a symkey!) using a Derive operation, then we get the */
 	    /* content encryption key using a Unwrap op */
 	    /* the derive operation has to generate the key using the algorithm in RFC2631 */
 	    error = SEC_ERROR_UNSUPPORTED_KEYALG;
+	    goto loser;
 	    break;
 	default:
 	    error = SEC_ERROR_UNSUPPORTED_KEYALG;
 	    goto loser;
 	}
 	break;
     case NSSCMSRecipientInfoID_KEK:
 	encalg = &(ri->ri.kekRecipientInfo.keyEncAlg);
@@ -618,16 +614,17 @@ NSS_CMSRecipientInfo_UnwrapBulkKey(NSSCM
 	error = SEC_ERROR_UNSUPPORTED_KEYALG;
 	goto loser;
 	break;
     }
     /* XXXX continue here */
     return bulkkey;
 
 loser:
+    PORT_SetError(error);
     return NULL;
 }
 
 SECStatus NSS_CMSRecipientInfo_GetCertAndKey(NSSCMSRecipientInfo *ri,
                                              CERTCertificate** retcert,
                                              SECKEYPrivateKey** retkey)
 {
     CERTCertificate* cert = NULL;
--- a/security/nss/lib/smime/cmssigdata.c
+++ b/security/nss/lib/smime/cmssigdata.c
@@ -32,17 +32,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * CMS signedData methods.
  *
- * $Id: cmssigdata.c,v 1.31 2011/02/11 01:53:17 emaldona%redhat.com Exp $
+ * $Id: cmssigdata.c,v 1.32 2011/09/30 19:42:09 rrelyea%redhat.com Exp $
  */
 
 #include "cmslocal.h"
 
 #include "cert.h"
 /*#include "cdbhdl.h"*/
 #include "secasn1.h"
 #include "secitem.h"
@@ -401,16 +401,35 @@ NSS_CMSSignedData_Decode_BeforeData(NSSC
     if (!sigd) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
     }
     rv = NSS_CMSContentInfo_Private_Init(&sigd->contentInfo);
     if (rv != SECSuccess) {
 	return SECFailure;
     }
+    /* handle issue with Windows 2003 servers and kerberos */
+    if (sigd->digestAlgorithms != NULL) {
+	int i;
+	for (i=0; sigd->digestAlgorithms[i] != NULL; i++) {
+	    SECAlgorithmID *algid = sigd->digestAlgorithms[i];
+	    SECOidTag senttag= SECOID_FindOIDTag(&algid->algorithm);
+	    SECOidTag maptag = NSS_CMSUtil_MapSignAlgs(senttag);
+
+	    if (maptag != senttag) {
+		SECOidData *hashoid = SECOID_FindOIDByTag(maptag);
+		rv = SECITEM_CopyItem(sigd->cmsg->poolp, &algid->algorithm 
+							,&hashoid->oid);
+		if (rv != SECSuccess) {
+		    return rv;
+		}
+	    }
+	}
+    }
+
     /* set up the digests */
     if (sigd->digestAlgorithms != NULL && sigd->digests == NULL) {
 	/* if digests are already there, do nothing */
 	sigd->contentInfo.privateInfo->digcx = NSS_CMSDigestContext_StartMultiple(sigd->digestAlgorithms);
 	if (sigd->contentInfo.privateInfo->digcx == NULL)
 	    return SECFailure;
     }
     return SECSuccess;
--- a/security/nss/lib/smime/cmssiginfo.c
+++ b/security/nss/lib/smime/cmssiginfo.c
@@ -33,17 +33,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * CMS signerInfo methods.
  *
- * $Id: cmssiginfo.c,v 1.34 2011/02/07 18:32:19 nelson%bolyard.com Exp $
+ * $Id: cmssiginfo.c,v 1.36 2011/09/30 19:42:09 rrelyea%redhat.com Exp $
  */
 
 #include "cmslocal.h"
 
 #include "cert.h"
 #include "key.h"
 #include "secasn1.h"
 #include "secitem.h"
@@ -210,21 +210,16 @@ NSS_CMSSignerInfo_Sign(NSSCMSSignerInfo 
      * XXX I think there should be a cert-level interface for this,
      * so that I do not have to know about subjectPublicKeyInfo...
      */
     pubkAlgTag = SECOID_GetAlgorithmTag(algID);
     if (signerinfo->signerIdentifier.identifierType == NSSCMSSignerID_SubjectKeyID) {
       SECOID_DestroyAlgorithmID(&freeAlgID, PR_FALSE);
     }
 
-    /* Fortezza MISSI have weird signature formats.  
-     * Map them to standard DSA formats 
-     */
-    pubkAlgTag = PK11_FortezzaMapSig(pubkAlgTag);
-
     if (signerinfo->authAttr != NULL) {
 	SECOidTag signAlgTag;
 	SECItem encoded_attrs;
 
 	/* find and fill in the message digest attribute. */
 	rv = NSS_CMSAttributeArray_SetAttr(poolp, &(signerinfo->authAttr), 
 	                       SEC_OID_PKCS9_MESSAGE_DIGEST, digest, PR_FALSE);
 	if (rv != SECSuccess)
@@ -530,30 +525,51 @@ NSSCMSVerificationStatus
 NSS_CMSSignerInfo_GetVerificationStatus(NSSCMSSignerInfo *signerinfo)
 {
     return signerinfo->verificationStatus;
 }
 
 SECOidData *
 NSS_CMSSignerInfo_GetDigestAlg(NSSCMSSignerInfo *signerinfo)
 {
-    return SECOID_FindOID (&(signerinfo->digestAlg.algorithm));
+    SECOidData *algdata;
+    SECOidTag   algtag;
+
+    algdata = SECOID_FindOID (&(signerinfo->digestAlg.algorithm));
+    if (algdata == NULL) {
+	return algdata;
+    }
+    /* Windows may have given us a signer algorithm oid instead of a digest 
+     * algorithm oid. This call will map to a signer oid to a digest one, 
+     * otherwise it leaves the oid alone and let the chips fall as they may
+     * if it's not a digest oid.
+     */
+    algtag = NSS_CMSUtil_MapSignAlgs(algdata->offset);
+    if (algtag != algdata->offset) {
+	/* if the tags don't match, then we must have received a signer 
+	 * algorithID. Now we need to get the oid data for the digest
+	 * oid, which the rest of the code is expecting */
+	algdata = SECOID_FindOIDByTag(algtag);
+    }
+
+    return algdata;
+
 }
 
 SECOidTag
 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));
+    algdata = NSS_CMSSignerInfo_GetDigestAlg(signerinfo);
     if (algdata != NULL)
 	return algdata->offset;
     else
 	return SEC_OID_UNKNOWN;
 }
 
 CERTCertificateList *
 NSS_CMSSignerInfo_GetCertList(NSSCMSSignerInfo *signerinfo)
@@ -779,18 +795,17 @@ NSS_CMSSignerInfo_AddSMIMECaps(NSSCMSSig
 
     mark = PORT_ArenaMark(poolp);
 
     smimecaps = SECITEM_AllocItem(poolp, NULL, 0);
     if (smimecaps == NULL)
 	goto loser;
 
     /* create new signing time attribute */
-    if (NSS_SMIMEUtil_CreateSMIMECapabilities(poolp, smimecaps,
-			    PK11_FortezzaHasKEA(signerinfo->cert)) != SECSuccess)
+    if (NSS_SMIMEUtil_CreateSMIMECapabilities(poolp, smimecaps) != SECSuccess)
 	goto loser;
 
     if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_PKCS9_SMIME_CAPABILITIES, smimecaps, PR_TRUE)) == NULL)
 	goto loser;
 
     if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
 	goto loser;
 
--- a/security/nss/lib/smime/cmst.h
+++ b/security/nss/lib/smime/cmst.h
@@ -32,17 +32,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * Header for CMS types.
  *
- * $Id: cmst.h,v 1.13 2011/02/11 01:53:17 emaldona%redhat.com Exp $
+ * $Id: cmst.h,v 1.14 2011/08/21 01:14:18 wtc%google.com Exp $
  */
 
 #ifndef _CMST_H_
 #define _CMST_H_
 
 #include "seccomon.h"
 #include "secoidt.h"
 #include "certt.h"
@@ -95,18 +95,16 @@ typedef struct NSSCMSEnvelopedDataStr NS
 typedef struct NSSCMSOriginatorInfoStr NSSCMSOriginatorInfo;
 typedef struct NSSCMSRecipientInfoStr NSSCMSRecipientInfo;
 
 typedef struct NSSCMSDigestedDataStr NSSCMSDigestedData;
 typedef struct NSSCMSEncryptedDataStr NSSCMSEncryptedData;
 
 typedef struct NSSCMSGenericWrapperDataStr NSSCMSGenericWrapperData;
 
-typedef struct NSSCMSSMIMEKEAParametersStr NSSCMSSMIMEKEAParameters;
-
 typedef struct NSSCMSAttributeStr NSSCMSAttribute;
 
 typedef struct NSSCMSDecoderContextStr NSSCMSDecoderContext;
 typedef struct NSSCMSEncoderContextStr NSSCMSEncoderContext;
 
 typedef struct NSSCMSCipherContextStr NSSCMSCipherContext;
 typedef struct NSSCMSDigestContextStr NSSCMSDigestContext;
 
@@ -506,48 +504,16 @@ struct NSSCMSEncryptedDataStr {
     NSSCMSContentInfo		contentInfo;
     NSSCMSAttribute **		unprotectedAttr;	/* optional */
     /* --------- local; not part of encoding --------- */
     NSSCMSMessage *		cmsg;		/* back pointer */
 };
 #define NSS_CMS_ENCRYPTED_DATA_VERSION		0	/* what we *create* */
 #define NSS_CMS_ENCRYPTED_DATA_VERSION_UPATTR	2	/* what we *create* */
 
-/* =============================================================================
- * FORTEZZA KEA
- */
-
-/* An enumerated type used to select templates based on the encryption
-   scenario and data specifics. */
-typedef enum {
-    NSSCMSKEAInvalid = -1,
-    NSSCMSKEAUsesSkipjack = 0,
-    NSSCMSKEAUsesNonSkipjack = 1,
-    NSSCMSKEAUsesNonSkipjackWithPaddedEncKey = 2
-} NSSCMSKEATemplateSelector;
-
-/* ### mwelch - S/MIME KEA parameters. These don't really fit here,
-                but I cannot think of a more appropriate place at this time. */
-struct NSSCMSSMIMEKEAParametersStr {
-    SECItem originatorKEAKey;	/* sender KEA key (encrypted?) */
-    SECItem originatorRA;	/* random number generated by sender */
-    SECItem nonSkipjackIV;	/* init'n vector for SkipjackCBC64
-			           decryption of KEA key if Skipjack
-				   is not the bulk algorithm used on
-				   the message */
-    SECItem bulkKeySize;	/* if Skipjack is not the bulk
-			           algorithm used on the message,
-				   and the size of the bulk encryption
-				   key is not the same as that of
-				   originatorKEAKey (due to padding
-				   perhaps), this field will contain
-				   the real size of the bulk encryption
-				   key. */
-};
-
 /*
  * *****************************************************************************
  * *****************************************************************************
  * *****************************************************************************
  */
 
 /*
  * See comment above about this type not really belonging to CMS.
--- a/security/nss/lib/smime/cmsutil.c
+++ b/security/nss/lib/smime/cmsutil.c
@@ -33,17 +33,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * CMS miscellaneous utility functions.
  *
- * $Id: cmsutil.c,v 1.16 2011/01/28 23:03:59 rrelyea%redhat.com Exp $
+ * $Id: cmsutil.c,v 1.17 2011/09/30 19:42:09 rrelyea%redhat.com Exp $
  */
 
 #include "cmslocal.h"
 
 #include "cert.h"
 #include "key.h"
 #include "secasn1.h"
 #include "secitem.h"
@@ -206,16 +206,55 @@ NSS_CMSAlgArray_GetIndexByAlgTag(SECAlgo
 #endif
 
     if (algorithmArray[i] == NULL)
 	return -1;	/* not found */
 
     return i;
 }
 
+/*
+ * Map a sign algorithm to a digest algorithm.
+ * This is used to handle incorrectly formatted packages sent to us
+ * from Windows 2003.
+ */
+SECOidTag
+NSS_CMSUtil_MapSignAlgs(SECOidTag signAlg)
+{
+    switch (signAlg) {
+    case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
+	return SEC_OID_MD2;
+	break;
+    case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
+	return SEC_OID_MD5;
+	break;
+    case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
+    case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
+    case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
+	return SEC_OID_SHA1;
+	break;
+    case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
+    case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
+	return SEC_OID_SHA256;
+	break;
+    case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
+    case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
+	return SEC_OID_SHA384;
+	break;
+    case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
+    case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
+	return SEC_OID_SHA512;
+	break;
+    default:
+	break;
+    }
+    /* not one of the algtags incorrectly sent to us*/
+    return signAlg;
+}
+
 const SECHashObject *
 NSS_CMSUtil_GetHashObjByAlgID(SECAlgorithmID *algid)
 {
     SECOidTag oidTag = SECOID_FindOIDTag(&(algid->algorithm));
     const SECHashObject *digobj = HASH_GetHashObjectByOidTag(oidTag);
 
     return digobj;
 }
@@ -345,8 +384,9 @@ NSS_CMSDEREncode(NSSCMSMessage *cmsg, SE
 	}
     }
     rv |= NSS_CMSEncoder_Finish(ecx);
     if (rv) {
 	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
     }
     return rv;
 }
+
--- a/security/nss/lib/smime/smime.h
+++ b/security/nss/lib/smime/smime.h
@@ -33,17 +33,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * Header file for routines specific to S/MIME.  Keep things that are pure
  * pkcs7 out of here; this is for S/MIME policy, S/MIME interoperability, etc.
  *
- * $Id: smime.h,v 1.10 2011/08/01 07:08:09 kaie%kuix.de Exp $
+ * $Id: smime.h,v 1.11 2011/08/21 01:14:18 wtc%google.com Exp $
  */
 
 #ifndef _SECMIME_H_
 #define _SECMIME_H_ 1
 
 #include "cms.h"
 
 
@@ -121,17 +121,17 @@ extern PRBool NSS_SMIMEUtil_DecryptionAl
 extern PRBool NSS_SMIMEUtil_EncryptionPossible(void);
 
 /*
  * NSS_SMIMEUtil_CreateSMIMECapabilities - get S/MIME capabilities attr value
  *
  * scans the list of allowed and enabled ciphers and construct a PKCS9-compliant
  * S/MIME capabilities attribute value.
  */
-extern SECStatus NSS_SMIMEUtil_CreateSMIMECapabilities(PLArenaPool *poolp, SECItem *dest, PRBool includeFortezzaCiphers);
+extern SECStatus NSS_SMIMEUtil_CreateSMIMECapabilities(PLArenaPool *poolp, SECItem *dest);
 
 /*
  * NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs - create S/MIME encryption key preferences attr value
  */
 extern SECStatus NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs(PLArenaPool *poolp, SECItem *dest, CERTCertificate *cert);
 
 /*
  * NSS_SMIMEUtil_CreateMSSMIMEEncKeyPrefs - create S/MIME encryption key preferences attr value using MS oid
--- a/security/nss/lib/smime/smimeutil.c
+++ b/security/nss/lib/smime/smimeutil.c
@@ -32,17 +32,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * Stuff specific to S/MIME policy and interoperability.
  *
- * $Id: smimeutil.c,v 1.21 2011/08/01 07:08:09 kaie%kuix.de Exp $
+ * $Id: smimeutil.c,v 1.22 2011/08/21 01:14:18 wtc%google.com Exp $
  */
 
 #include "secmime.h"
 #include "secoid.h"
 #include "pk11func.h"
 #include "ciferfam.h"	/* for CIPHER_FAMILY symbols */
 #include "secasn1.h"
 #include "secitem.h"
@@ -147,18 +147,17 @@ typedef struct {
 static smime_cipher_map_entry smime_cipher_map[] = {
 /*    cipher			algtag			parms		enabled  allowed */
 /*    ---------------------------------------------------------------------------------- */
     { SMIME_RC2_CBC_40,		SEC_OID_RC2_CBC,	&param_int40,	PR_TRUE, PR_TRUE },
     { SMIME_DES_CBC_56,		SEC_OID_DES_CBC,	NULL,		PR_TRUE, PR_TRUE },
     { SMIME_RC2_CBC_64,		SEC_OID_RC2_CBC,	&param_int64,	PR_TRUE, PR_TRUE },
     { SMIME_RC2_CBC_128,	SEC_OID_RC2_CBC,	&param_int128,	PR_TRUE, PR_TRUE },
     { SMIME_DES_EDE3_168,	SEC_OID_DES_EDE3_CBC,	NULL,		PR_TRUE, PR_TRUE },
-    { SMIME_AES_CBC_128,	SEC_OID_AES_128_CBC,	NULL,		PR_TRUE, PR_TRUE },
-    { SMIME_FORTEZZA,		SEC_OID_FORTEZZA_SKIPJACK, NULL,	PR_TRUE, PR_TRUE }
+    { SMIME_AES_CBC_128,	SEC_OID_AES_128_CBC,	NULL,		PR_TRUE, PR_TRUE }
 };
 static const int smime_cipher_map_count = sizeof(smime_cipher_map) / sizeof(smime_cipher_map_entry);
 
 /*
  * smime_mapi_by_cipher - find index into smime_cipher_map by cipher
  */
 static int
 smime_mapi_by_cipher(unsigned long cipher)
@@ -268,20 +267,18 @@ nss_smime_get_cipher_for_alg_and_key(SEC
 	c = SMIME_DES_CBC_56;
 	break;
     case SEC_OID_DES_EDE3_CBC:
 	c = SMIME_DES_EDE3_168;
 	break;
     case SEC_OID_AES_128_CBC:
 	c = SMIME_AES_CBC_128;
 	break;
-    case SEC_OID_FORTEZZA_SKIPJACK:
-	c = SMIME_FORTEZZA;
-	break;
     default:
+	PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
 	return SECFailure;
     }
     *cipher = c;
     return SECSuccess;
 }
 
 static PRBool
 nss_smime_cipher_allowed(unsigned long which)
@@ -388,38 +385,31 @@ smime_choose_cipher(CERTCertificate *sce
     PRArenaPool *poolp;
     long cipher;
     long chosen_cipher;
     int *cipher_abilities;
     int *cipher_votes;
     int weak_mapi;
     int strong_mapi;
     int rcount, mapi, max, i;
-    PRBool scert_is_fortezza = (scert == NULL) ? PR_FALSE : PK11_FortezzaHasKEA(scert);
 
     chosen_cipher = SMIME_RC2_CBC_40;		/* the default, LCD */
     weak_mapi = smime_mapi_by_cipher(chosen_cipher);
 
     poolp = PORT_NewArena (1024);		/* XXX what is right value? */
     if (poolp == NULL)
 	goto done;
 
     cipher_abilities = (int *)PORT_ArenaZAlloc(poolp, smime_cipher_map_count * sizeof(int));
     cipher_votes     = (int *)PORT_ArenaZAlloc(poolp, smime_cipher_map_count * sizeof(int));
     if (cipher_votes == NULL || cipher_abilities == NULL)
 	goto done;
 
-    /* If the user has the Fortezza preference turned on, make
-     *  that the strong cipher. Otherwise, use triple-DES. */
+    /* Make triple-DES the strong cipher. */
     strong_mapi = smime_mapi_by_cipher (SMIME_DES_EDE3_168);
-    if (scert_is_fortezza) {
-	mapi = smime_mapi_by_cipher(SMIME_FORTEZZA);
-	if (mapi >= 0 && smime_cipher_map[mapi].enabled)
-	    strong_mapi = mapi;
-    }
 
     /* walk all the recipient's certs */
     for (rcount = 0; rcerts[rcount] != NULL; rcount++) {
 	SECItem *profile;
 	NSSSMIMECapability **caps;
 	int pref;
 
 	/* the first cipher that matches in the user's SMIME profile gets
@@ -493,19 +483,16 @@ smime_choose_cipher(CERTCertificate *sce
     max = 0;
     for (mapi = 0; mapi < smime_cipher_map_count; mapi++) {
 	/* if not all of the recipients can do this, forget it */
 	if (cipher_abilities[mapi] != rcount)
 	    continue;
 	/* if cipher is not enabled or not allowed by policy, forget it */
 	if (!smime_cipher_map[mapi].enabled || !smime_cipher_map[mapi].allowed)
 	    continue;
-	/* if we're not doing fortezza, but the cipher is fortezza, forget it */
-	if (!scert_is_fortezza  && (smime_cipher_map[mapi].cipher == SMIME_FORTEZZA))
-	    continue;
 	/* now see if this one has more votes than the last best one */
 	if (cipher_votes[mapi] >= max) {
 	    /* if equal number of votes, prefer the ones further down in the list */
 	    /* with the expectation that these are higher rated ciphers */
 	    chosen_cipher = smime_cipher_map[mapi].cipher;
 	    max = cipher_votes[mapi];
 	}
     }
@@ -536,17 +523,16 @@ smime_keysize_by_cipher (unsigned long w
 	keysize = 64;
 	break;
       case SMIME_RC2_CBC_128:
       case SMIME_AES_CBC_128:
 	keysize = 128;
 	break;
       case SMIME_DES_CBC_56:
       case SMIME_DES_EDE3_168:
-      case SMIME_FORTEZZA:
 	/*
 	 * These are special; since the key size is fixed, we actually
 	 * want to *avoid* specifying a key size.
 	 */
 	keysize = 0;
 	break;
       default:
 	keysize = -1;
@@ -583,20 +569,19 @@ NSS_SMIMEUtil_FindBulkAlgForRecipients(C
  * scans the list of allowed and enabled ciphers and construct a PKCS9-compliant
  * S/MIME capabilities attribute value.
  *
  * XXX Please note that, in contradiction to RFC2633 2.5.2, the capabilities only include
  * symmetric ciphers, NO signature algorithms or key encipherment algorithms.
  *
  * "poolp" - arena pool to create the S/MIME capabilities data on
  * "dest" - SECItem to put the data in
- * "includeFortezzaCiphers" - PR_TRUE if fortezza ciphers should be included
  */
 SECStatus
-NSS_SMIMEUtil_CreateSMIMECapabilities(PLArenaPool *poolp, SECItem *dest, PRBool includeFortezzaCiphers)
+NSS_SMIMEUtil_CreateSMIMECapabilities(PLArenaPool *poolp, SECItem *dest)
 {
     NSSSMIMECapability *cap;
     NSSSMIMECapability **smime_capabilities;
     smime_cipher_map_entry *map;
     SECOidData *oiddata;
     SECItem *dummy;
     int i, capIndex;
 
@@ -614,22 +599,16 @@ NSS_SMIMEUtil_CreateSMIMECapabilities(PL
      * we prefer the stronger cipher over a weaker one, and we have to list the
      * preferred algorithm first */
     for (i = smime_cipher_map_count - 1; i >= 0; i--) {
 	/* Find the corresponding entry in the cipher map. */
 	map = &(smime_cipher_map[i]);
 	if (!map->enabled)
 	    continue;
 
-	/* If we're using a non-Fortezza cert, only advertise non-Fortezza
-	   capabilities. (We advertise all capabilities if we have a 
-	   Fortezza cert.) */
-	if ((!includeFortezzaCiphers) && (map->cipher == SMIME_FORTEZZA))
-	    continue;
-
 	/* get next SMIME capability */
 	cap = (NSSSMIMECapability *)PORT_ZAlloc(sizeof(NSSSMIMECapability));
 	if (cap == NULL)
 	    break;
 	smime_capabilities[capIndex++] = cap;
 
 	oiddata = SECOID_FindOIDByTag(map->algtag);
 	if (oiddata == NULL)
--- a/security/nss/lib/softoken/pkcs11c.c
+++ b/security/nss/lib/softoken/pkcs11c.c
@@ -2315,17 +2315,16 @@ CK_RV NSC_SignFinal(CK_SESSION_HANDLE hS
         if( !pSignature  ||  maxoutlen < outlen ) {
             if( pSignature ) crv = CKR_BUFFER_TOO_SMALL;
             goto finish;
         }
         if( CKR_OK == (crv = sftk_MACFinal( context )) )
 	    PORT_Memcpy(pSignature, context->macBuf, outlen );
     }
 
-terminate:
     sftk_TerminateOp( session, SFTK_SIGN, context );
 finish:
     *pulSignatureLen = outlen;
     sftk_FreeSession(session);
     return crv;
 }
 
 /* NSC_Sign signs (encrypts with private key) data in a single part,
@@ -2746,17 +2745,16 @@ CK_RV NSC_VerifyFinal(CK_SESSION_HANDLE 
     } else if (ulSignatureLen != context->macSize) {
 	/* must be block cipher MACing */
 	crv = CKR_SIGNATURE_LEN_RANGE;
     } else if (CKR_OK == (crv = sftk_MACFinal(context))) {
 	if (PORT_Memcmp(pSignature, context->macBuf, ulSignatureLen))
 	    crv = CKR_SIGNATURE_INVALID;
     }
 
-terminate:
     sftk_TerminateOp( session, SFTK_VERIFY, context );
     sftk_FreeSession(session);
     return crv;
 
 }
 
 /*
  ************** Crypto Functions:     Verify  Recover ************************
--- a/security/nss/lib/softoken/rsawrapr.c
+++ b/security/nss/lib/softoken/rsawrapr.c
@@ -18,31 +18,32 @@
  * The Original Code is the Netscape security libraries.
  *
  * The Initial Developer of the Original Code is
  * Netscape Communications Corporation.
  * Portions created by the Initial Developer are Copyright (C) 1994-2000
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
+ *   Hanno Boeck <hanno@hboeck.de>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: rsawrapr.c,v 1.17 2010/08/07 18:10:35 wtc%google.com Exp $ */
+/* $Id: rsawrapr.c,v 1.18 2011/10/04 22:05:53 wtc%google.com Exp $ */
 
 #include "blapi.h"
 #include "softoken.h"
 #include "sechash.h"
 
 #include "lowkeyi.h"
 #include "secerr.h"
 
@@ -940,16 +941,63 @@ RSA_DecryptRaw(NSSLOWKEYPrivateKey *key,
     *output_len = modulus_len;
     return SECSuccess;
 
 failure:
     return SECFailure;
 }
 
 /*
+ * Mask generation function MGF1 as defined in PKCS #1 v2.1 / RFC 3447.
+ */
+static SECStatus
+MGF1(HASH_HashType hashAlg, unsigned char *mask, unsigned int maskLen,
+     const unsigned char *mgfSeed, unsigned int mgfSeedLen)
+{
+    unsigned int digestLen;
+    PRUint32 counter, rounds;
+    unsigned char *tempHash, *temp;
+    const SECHashObject *hash;
+    void *hashContext;
+    unsigned char C[4];
+
+    hash = HASH_GetRawHashObject(hashAlg);
+    if (hash == NULL)
+        return SECFailure;
+
+    hashContext = (*hash->create)();
+    rounds = (maskLen + hash->length - 1) / hash->length;
+    for (counter = 0; counter < rounds; counter++) {
+        C[0] = (unsigned char)((counter >> 24) & 0xff);
+        C[1] = (unsigned char)((counter >> 16) & 0xff);
+        C[2] = (unsigned char)((counter >> 8) & 0xff);
+        C[3] = (unsigned char)(counter & 0xff);
+
+        /* This could be optimized when the clone functions in
+         * rawhash.c are implemented. */
+        (*hash->begin)(hashContext);
+        (*hash->update)(hashContext, mgfSeed, mgfSeedLen); 
+        (*hash->update)(hashContext, C, sizeof C);
+
+        tempHash = mask + counter * hash->length;
+        if (counter != (rounds-1)) {
+            (*hash->end)(hashContext, tempHash, &digestLen, hash->length);
+        } else { /* we're in the last round and need to cut the hash */
+            temp = PORT_Alloc(hash->length);
+            (*hash->end)(hashContext, temp, &digestLen, hash->length);
+            PORT_Memcpy(tempHash, temp, maskLen - counter * hash->length);
+            PORT_Free(temp);
+        }
+    }
+    (*hash->destroy)(hashContext, PR_TRUE);
+
+    return SECSuccess;
+}
+
+/*
  * Encode a RSA-PSS signature.
  * Described in RFC 3447, section 9.1.1.
  * We use mHash instead of M as input.
  * emBits from the RFC is just modBits - 1, see section 8.1.1.
  * We only support MGF1 as the MGF.
  *
  * NOTE: this code assumes modBits is a multiple of 8.
  */
--- a/security/nss/lib/softoken/sftkdb.c
+++ b/security/nss/lib/softoken/sftkdb.c
@@ -1490,16 +1490,19 @@ sftkdb_CloseDB(SFTKDBHandle *handle)
 	(*handle->update->sdb_Close)(handle->update);
     }
     if (handle->db) {
         if (handle->db->sdb_SetForkState) {
             (*handle->db->sdb_SetForkState)(parentForkedAfterC_Initialize);
         }
 	(*handle->db->sdb_Close)(handle->db);
     }
+    if (handle->passwordKey.data) {
+	PORT_ZFree(handle->passwordKey.data, handle->passwordKey.len);
+    }
     if (handle->passwordLock) {
 	SKIP_AFTER_FORK(PZ_DestroyLock(handle->passwordLock));
     }
     if (handle->updatePasswordKey) {
 	SECITEM_FreeItem(handle->updatePasswordKey, PR_TRUE);
     }
     if (handle->updateID) {
 	PORT_Free(handle->updateID);
--- a/security/nss/lib/softoken/sftkmod.c
+++ b/security/nss/lib/softoken/sftkmod.c
@@ -174,25 +174,28 @@ sftkdb_growList(char ***pModuleList, int
 static 
 char *sftk_getOldSecmodName(const char *dbname,const char *filename)
 {
     char *file = NULL;
     char *dirPath = PORT_Strdup(dbname);
     char *sep;
 
     sep = PORT_Strrchr(dirPath,*PATH_SEPARATOR);
-#ifdef WINDOWS
+#ifdef _WIN32
     if (!sep) {
-	sep = PORT_Strrchr(dirPath,'/');
+	/* pkcs11i.h defines PATH_SEPARATOR as "/" for all platforms. */
+	sep = PORT_Strrchr(dirPath,'\\');
     }
 #endif
     if (sep) {
-	*(sep)=0;
+	*sep = 0;
+	file = PR_smprintf("%s"PATH_SEPARATOR"%s", dirPath, filename);
+    } else {
+	file = PR_smprintf("%s", filename);
     }
-    file= PR_smprintf("%s"PATH_SEPARATOR"%s", dirPath, filename);
     PORT_Free(dirPath);
     return file;
 }
 
 #ifdef XP_UNIX
 #include <unistd.h>
 #endif
 #include <fcntl.h>
@@ -237,23 +240,28 @@ sftkdb_ReadSecmodDB(SDBType dbType, cons
     int useCount = SECMOD_STEP;
     char line[MAX_LINE_LENGTH];
     PRBool internal = PR_FALSE;
     PRBool skipParams = PR_FALSE;
     char *moduleString = NULL;
     char *paramsValue=NULL;
     PRBool failed = PR_TRUE;
 
-    if ((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS)) {
+    if ((dbname != NULL) &&
+		((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS))) {
 	return sftkdbCall_ReadSecmodDB(appName, filename, dbname, params, rw);
     }
 
     moduleList = (char **) PORT_ZAlloc(useCount*sizeof(char **));
     if (moduleList == NULL) return NULL;
 
+    if (dbname == NULL) {
+	goto return_default;
+    }
+
     /* do we really want to use streams here */
     fd = fopen(dbname, "r");
     if (fd == NULL) goto done;
 
     /*
      * the following loop takes line separated config lines and collapses
      * the lines to a single string, escaping and quoting as necessary.
      */
@@ -400,17 +408,21 @@ sftkdb_ReadSecmodDB(SDBType dbType, cons
 	skipParams = PR_FALSE;
     } 
 
     if (moduleString) {
 	PORT_Free(moduleString);
 	moduleString = NULL;
     }
 done:
-    /* if we couldn't open a pkcs11 database, look for the old one */
+    /* If we couldn't open a pkcs11 database, look for the old one.
+     * This is necessary to maintain the semantics of the transition from
+     * old to new DB's. If there is an old DB and not new DB, we will
+     * automatically use the old DB. If the DB was opened read/write, we
+     * create a new db and upgrade it from the old one. */
     if (fd == NULL) {
 	char *olddbname = sftk_getOldSecmodName(dbname,filename);
 	PRStatus status;
 	char **oldModuleList;
 	int i;
 
 	/* couldn't get the old name */
 	if (!olddbname) {
@@ -457,16 +469,18 @@ done:
 	/* done with the old module list */
 	sftkdbCall_ReleaseSecmodDBData(appName, filename, olddbname, 
 				  oldModuleList, rw);
 bail:
 	if (olddbname) {
 	    PR_smprintf_free(olddbname);
 	}
     }
+
+return_default:
 	
     if (!moduleList[0]) {
 	char * newParams;
 	moduleString = PORT_Strdup(SFTK_DEFAULT_INTERNAL_INIT1);
 	newParams = sftkdb_quote(params,'"');
 	if (newParams == NULL) goto loser;
 	moduleString = sftkdb_DupCat(moduleString, newParams);
 	PORT_Free(newParams);
@@ -510,17 +524,18 @@ loser:
     return moduleList;
 }
 
 SECStatus
 sftkdb_ReleaseSecmodDBData(SDBType dbType, const char *appName, 
 			const char *filename, const char *dbname, 
 			char **moduleSpecList, PRBool rw)
 {
-    if ((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS)) {
+    if ((dbname != NULL) &&
+		((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS))) {
 	return sftkdbCall_ReleaseSecmodDBData(appName, filename, dbname, 
 					  moduleSpecList, rw);
     }
     if (moduleSpecList) {
 	sftkdb_releaseSpecList(moduleSpecList);
     }
     return SECSuccess;
 }
@@ -541,16 +556,20 @@ sftkdb_DeleteSecmodDB(SDBType dbType, co
     char *dbname2 = NULL;
     char *block = NULL;
     char *name = NULL;
     char *lib = NULL;
     int name_len, lib_len;
     PRBool skip = PR_FALSE;
     PRBool found = PR_FALSE;
 
+    if (dbname == NULL) {
+	return SECFailure;
+    }
+
     if ((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS)) {
 	return sftkdbCall_DeleteSecmodDB(appName, filename, dbname, args, rw);
     }
 
     if (!rw) {
 	return SECFailure;
     }
 
@@ -664,16 +683,20 @@ SECStatus
 sftkdb_AddSecmodDB(SDBType dbType, const char *appName, 
 		   const char *filename, const char *dbname, 
 		   char *module, PRBool rw)
 {
     FILE *fd = NULL;
     char *block = NULL;
     PRBool libFound = PR_FALSE;
 
+    if (dbname == NULL) {
+	return SECFailure;
+    }
+
     if ((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS)) {
 	return sftkdbCall_AddSecmodDB(appName, filename, dbname, module, rw);
     }
 
     /* can't write to a read only module */
     if (!rw) {
 	return SECFailure;
     }
--- a/security/nss/lib/softoken/sftkpars.c
+++ b/security/nss/lib/softoken/sftkpars.c
@@ -602,16 +602,17 @@ sftk_getSecmodName(char *param, SDBType 
 		   char **filename, PRBool *rw)
 {
     int next;
     char *configdir = NULL;
     char *secmodName = NULL;
     char *value = NULL;
     char *save_params = param;
     const char *lconfigdir;
+    PRBool noModDB = PR_FALSE;
     param = sftk_argStrip(param);
 	
 
     while (*param) {
 	SFTK_HANDLE_STRING_ARG(param,configdir,"configDir=",;)
 	SFTK_HANDLE_STRING_ARG(param,secmodName,"secmod=",;)
 	SFTK_HANDLE_FINAL_ARG(param)
    }
@@ -626,25 +627,30 @@ sftk_getSecmodName(char *param, SDBType 
 	secmodName = PORT_Strdup(SECMOD_DB);
    }
 
    *filename = secmodName;
    lconfigdir = sftk_EvaluateConfigDir(configdir, dbType, appName);
 
    if (sftk_argHasFlag("flags","noModDB",save_params)) {
 	/* there isn't a module db, don't load the legacy support */
+	noModDB = PR_TRUE;
 	*dbType = SDB_SQL;
+	PORT_Free(*filename);
+	*filename = NULL;
         *rw = PR_FALSE;
    }
 
    /* only use the renamed secmod for legacy databases */
    if ((*dbType != SDB_LEGACY) && (*dbType != SDB_MULTIACCESS)) {
 	secmodName="pkcs11.txt";
    }
 
-   if (lconfigdir) {
+   if (noModDB) {
+	value = NULL;
+   } else if (lconfigdir && lconfigdir[0] != '\0') {
 	value = PR_smprintf("%s" PATH_SEPARATOR "%s",lconfigdir,secmodName);
    } else {
 	value = PR_smprintf("%s",secmodName);
    }
    if (configdir) PORT_Free(configdir);
    return value;
 }
--- a/security/nss/lib/softoken/softkver.h
+++ b/security/nss/lib/softoken/softkver.h
@@ -52,16 +52,16 @@
 
 /*
  * Softoken's major version, minor version, patch level, build number,
  * and whether this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
  */
-#define SOFTOKEN_VERSION  "3.13.0.0" SOFTOKEN_ECC_STRING " Beta"
+#define SOFTOKEN_VERSION  "3.13.0.0" SOFTOKEN_ECC_STRING
 #define SOFTOKEN_VMAJOR   3
 #define SOFTOKEN_VMINOR   13
 #define SOFTOKEN_VPATCH   0
 #define SOFTOKEN_VBUILD   0
-#define SOFTOKEN_BETA     PR_TRUE
+#define SOFTOKEN_BETA     PR_FALSE
 
 #endif /* _SOFTKVER_H_ */
--- a/security/nss/lib/ssl/SSLerrs.h
+++ b/security/nss/lib/ssl/SSLerrs.h
@@ -47,41 +47,42 @@ ER3(SSL_ERROR_NO_CYPHER_OVERLAP,			SSL_E
 "Cannot communicate securely with peer: no common encryption algorithm(s).")
 
 ER3(SSL_ERROR_NO_CERTIFICATE,				SSL_ERROR_BASE + 3,
 "Unable to find the certificate or key necessary for authentication.")
 
 ER3(SSL_ERROR_BAD_CERTIFICATE,				SSL_ERROR_BASE + 4,
 "Unable to communicate securely with peer: peers's certificate was rejected.")
 
-/* unused						(SSL_ERROR_BASE + 5),*/
+ER3(SSL_ERROR_UNUSED_5,					SSL_ERROR_BASE + 5,
+"Unrecognized SSL error code.")
 
 ER3(SSL_ERROR_BAD_CLIENT,				SSL_ERROR_BASE + 6,
 "The server has encountered bad data from the client.")
 
 ER3(SSL_ERROR_BAD_SERVER,				SSL_ERROR_BASE + 7,
 "The client has encountered bad data from the server.")
 
 ER3(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE,		SSL_ERROR_BASE + 8,
 "Unsupported certificate type.")
 
 ER3(SSL_ERROR_UNSUPPORTED_VERSION,			SSL_ERROR_BASE + 9,
 "Peer using unsupported version of security protocol.")
 
-/* unused						(SSL_ERROR_BASE + 10),*/
+ER3(SSL_ERROR_UNUSED_10,				SSL_ERROR_BASE + 10,
+"Unrecognized SSL error code.")
 
 ER3(SSL_ERROR_WRONG_CERTIFICATE,			SSL_ERROR_BASE + 11,
 "Client authentication failed: private key in key database does not match public key in certificate database.")
 
 ER3(SSL_ERROR_BAD_CERT_DOMAIN,				SSL_ERROR_BASE + 12,
 "Unable to communicate securely with peer: requested domain name does not match the server's certificate.")
 
-/* SSL_ERROR_POST_WARNING				(SSL_ERROR_BASE + 13),
-   defined in sslerr.h
-*/
+ER3(SSL_ERROR_POST_WARNING,				SSL_ERROR_BASE + 13,
+"Unrecognized SSL error code.")
 
 ER3(SSL_ERROR_SSL2_DISABLED,				(SSL_ERROR_BASE + 14),
 "Peer only supports SSL version 2, which is locally disabled.")
 
 
 ER3(SSL_ERROR_BAD_MAC_READ,				(SSL_ERROR_BASE + 15),
 "SSL received a record with an incorrect Message Authentication Code.")
 
@@ -98,17 +99,16 @@ ER3(SSL_ERROR_EXPIRED_CERT_ALERT,			(SSL
 "SSL peer rejected your certificate as expired.")
 
 ER3(SSL_ERROR_SSL_DISABLED,				(SSL_ERROR_BASE + 20),
 "Cannot connect: SSL is disabled.")
 
 ER3(SSL_ERROR_FORTEZZA_PQG,				(SSL_ERROR_BASE + 21),
 "Cannot connect: SSL peer is in another FORTEZZA domain.")
 
-
 ER3(SSL_ERROR_UNKNOWN_CIPHER_SUITE          , (SSL_ERROR_BASE + 22),
 "An unknown SSL cipher suite has been requested.")
 
 ER3(SSL_ERROR_NO_CIPHERS_SUPPORTED          , (SSL_ERROR_BASE + 23),
 "No cipher suites are present and enabled in this program.")
 
 ER3(SSL_ERROR_BAD_BLOCK_PADDING             , (SSL_ERROR_BASE + 24),
 "SSL received a record with bad block padding.")
--- a/security/nss/lib/ssl/manifest.mn
+++ b/security/nss/lib/ssl/manifest.mn
@@ -41,21 +41,16 @@ CORE_DEPTH = ../../..
 EXPORTS = \
 	ssl.h \
 	sslt.h \
 	sslerr.h \
 	sslproto.h \
 	preenc.h \
 	$(NULL)
 
-PRIVATE_EXPORTS = \
-	sslerrstrs.h \
-	SSLerrs.h \
- 	$(NULL)
-
 MODULE = nss
 MAPFILE = $(OBJDIR)/ssl.def
 
 CSRCS = \
 	derive.c \
 	prelib.c \
 	ssl3con.c \
 	ssl3gthr.c \
--- a/security/nss/lib/ssl/ssl.h
+++ b/security/nss/lib/ssl/ssl.h
@@ -31,17 +31,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: ssl.h,v 1.42 2011/08/01 07:08:09 kaie%kuix.de Exp $ */
+/* $Id: ssl.h,v 1.44 2011/10/06 22:42:33 wtc%google.com Exp $ */
 
 #ifndef __ssl_h_
 #define __ssl_h_
 
 #include "prtypes.h"
 #include "prerror.h"
 #include "prio.h"
 #include "seccomon.h"
@@ -95,26 +95,26 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFi
 /* options */
 #define SSL_SECURITY			1 /* (on by default) */
 #define SSL_SOCKS			2 /* (off by default) */
 #define SSL_REQUEST_CERTIFICATE		3 /* (off by default) */
 #define SSL_HANDSHAKE_AS_CLIENT		5 /* force accept to hs as client */
                                		  /* (off by default) */
 #define SSL_HANDSHAKE_AS_SERVER		6 /* force connect to hs as server */
                                		  /* (off by default) */
-#define SSL_ENABLE_SSL2			7 /* enable ssl v2 (on by default) */
+#define SSL_ENABLE_SSL2			7 /* enable ssl v2 (off by default) */
 #define SSL_ENABLE_SSL3		        8 /* enable ssl v3 (on by default) */
 #define SSL_NO_CACHE		        9 /* don't use the session cache */
                     		          /* (off by default) */
 #define SSL_REQUIRE_CERTIFICATE        10 /* (SSL_REQUIRE_FIRST_HANDSHAKE */
                                           /* by default) */
 #define SSL_ENABLE_FDX                 11 /* permit simultaneous read/write */
                                           /* (off by default) */
 #define SSL_V2_COMPATIBLE_HELLO        12 /* send v3 client hello in v2 fmt */
-                                          /* (on by default) */
+                                          /* (off by default) */
 #define SSL_ENABLE_TLS		       13 /* enable TLS (on by default) */
 #define SSL_ROLLBACK_DETECTION         14 /* for compatibility, default: on */
 #define SSL_NO_STEP_DOWN               15 /* Disable export cipher suites   */
                                           /* if step-down keys are needed.  */
 					  /* default: off, generate         */
 					  /* step-down keys if needed.      */
 #define SSL_BYPASS_PKCS11              16 /* use PKCS#11 for pub key only   */
 #define SSL_NO_LOCKS                   17 /* Don't use locks for protection */
@@ -135,16 +135,44 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFi
 /* verifying the server's Finished message. This means that we could end up */
 /* sending data to an imposter. However, the data will be encrypted and     */
 /* only the true server can derive the session key. Thus, so long as the    */
 /* cipher isn't broken this is safe. Because of this, False Start will only */
 /* occur on RSA or DH ciphersuites where the cipher's key length is >= 80   */
 /* bits. The advantage of False Start is that it saves a round trip for     */
 /* client-speaks-first protocols when performing a full handshake.          */
 
+/* For SSL 3.0 and TLS 1.0, by default we prevent chosen plaintext attacks
+ * on SSL CBC mode cipher suites (see RFC 4346 Section F.3) by splitting
+ * non-empty application_data records into two records; the first record has
+ * only the first byte of plaintext, and the second has the rest.
+ *
+ * This only prevents the attack in the sending direction; the connection may
+ * still be vulnerable to such attacks if the peer does not implement a similar
+ * countermeasure.
+ *
+ * This protection mechanism is on by default; the default can be overridden by
+ * setting NSS_SSL_CBC_RANDOM_IV=0 in the environment prior to execution,
+ * and/or by the application setting the option SSL_CBC_RANDOM_IV to PR_FALSE.
+ *
+ * The per-record IV in TLS 1.1 and later adds one block of overhead per
+ * record, whereas this hack will add at least two blocks of overhead per
+ * record, so TLS 1.1+ will always be more efficient.
+ *
+ * Other implementations (e.g. some versions of OpenSSL, in some
+ * configurations) prevent the same attack by prepending an empty
+ * application_data record to every application_data record they send; we do
+ * not do that because some implementations cannot handle empty
+ * application_data records. Also, we only split application_data records and
+ * not other types of records, because some implementations will not accept
+ * fragmented records of some other types (e.g. some versions of NSS do not
+ * accept fragmented alerts).
+ */
+#define SSL_CBC_RANDOM_IV 23
+
 #ifdef SSL_DEPRECATED_FUNCTION 
 /* Old deprecated function names */
 SSL_IMPORT SECStatus SSL_Enable(PRFileDesc *fd, int option, PRBool on);
 SSL_IMPORT SECStatus SSL_EnableDefault(int option, PRBool on);
 #endif
 
 /* New function names */
 SSL_IMPORT SECStatus SSL_OptionSet(PRFileDesc *fd, PRInt32 option, PRBool on);
--- a/security/nss/lib/ssl/ssl3con.c
+++ b/security/nss/lib/ssl/ssl3con.c
@@ -34,17 +34,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: ssl3con.c,v 1.151 2011/07/26 02:13:37 wtc%google.com Exp $ */
+/* $Id: ssl3con.c,v 1.152 2011/10/01 03:59:54 bsmith%mozilla.com Exp $ */
 
 #include "cert.h"
 #include "ssl.h"
 #include "cryptohi.h"	/* for DSAU_ stuff */
 #include "keyhi.h"
 #include "secder.h"
 #include "secitem.h"
 
@@ -2032,56 +2032,54 @@ ssl3_ClientAuthTokenPresent(sslSessionID
 	isPresent = PR_FALSE;
     } 
     if (slot) {
 	PK11_FreeSlot(slot);
     }
     return isPresent;
 }
 
+/* Caller must hold the spec read lock. */
 static SECStatus
-ssl3_CompressMACEncryptRecord(sslSocket *        ss,
+ssl3_CompressMACEncryptRecord(ssl3CipherSpec *   cwSpec,
+		              PRBool             isServer,
                               SSL3ContentType    type,
 		              const SSL3Opaque * pIn,
-		              PRUint32           contentLen)
-{
-    ssl3CipherSpec *          cwSpec;
+		              PRUint32           contentLen,
+		              sslBuffer *        wrBuf)
+{
     const ssl3BulkCipherDef * cipher_def;
-    sslBuffer      *          wrBuf 	  = &ss->sec.writeBuf;
     SECStatus                 rv;
     PRUint32                  macLen      = 0;
     PRUint32                  fragLen;
     PRUint32  p1Len, p2Len, oddLen = 0;
     PRInt32   cipherBytes =  0;
 
-    ssl_GetSpecReadLock(ss);	/********************************/
-
-    cwSpec = ss->ssl3.cwSpec;
     cipher_def = cwSpec->cipher_def;
 
     if (cwSpec->compressor) {
 	int outlen;
 	rv = cwSpec->compressor(
 	    cwSpec->compressContext, wrBuf->buf + SSL3_RECORD_HEADER_LENGTH,
 	    &outlen, wrBuf->space - SSL3_RECORD_HEADER_LENGTH, pIn, contentLen);
 	if (rv != SECSuccess)
 	    return rv;
 	pIn = wrBuf->buf + SSL3_RECORD_HEADER_LENGTH;
 	contentLen = outlen;
     }
 
     /*
      * Add the MAC
      */
-    rv = ssl3_ComputeRecordMAC( cwSpec, (PRBool)(ss->sec.isServer),
+    rv = ssl3_ComputeRecordMAC( cwSpec, isServer,
 	type, cwSpec->version, cwSpec->write_seq_num, pIn, contentLen,
 	wrBuf->buf + contentLen + SSL3_RECORD_HEADER_LENGTH, &macLen);
     if (rv != SECSuccess) {
 	ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
-	goto spec_locked_loser;
+	return SECFailure;
     }
     p1Len   = contentLen;
     p2Len   = macLen;
     fragLen = contentLen + macLen;	/* needs to be encrypted */
     PORT_Assert(fragLen <= MAX_FRAGMENT_LENGTH + 1024);
 
     /*
      * Pad the text (if we're doing a block cipher)
@@ -2124,52 +2122,46 @@ ssl3_CompressMACEncryptRecord(sslSocket 
 	rv = cwSpec->encode( cwSpec->encodeContext, 
 	    wrBuf->buf + SSL3_RECORD_HEADER_LENGTH, /* output */
 	    &cipherBytes,                           /* actual outlen */
 	    p1Len,                                  /* max outlen */
 	    pIn, p1Len);                      /* input, and inputlen */
 	PORT_Assert(rv == SECSuccess && cipherBytes == p1Len);
 	if (rv != SECSuccess || cipherBytes != p1Len) {
 	    PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
-	    goto spec_locked_loser;
+	    return SECFailure;
 	}
     }
     if (p2Len > 0) {
 	PRInt32 cipherBytesPart2 = -1;
 	rv = cwSpec->encode( cwSpec->encodeContext, 
 	    wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + p1Len,
 	    &cipherBytesPart2,          /* output and actual outLen */
 	    p2Len,                             /* max outlen */
 	    wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + p1Len,
 	    p2Len);                            /* input and inputLen*/
 	PORT_Assert(rv == SECSuccess && cipherBytesPart2 == p2Len);
 	if (rv != SECSuccess || cipherBytesPart2 != p2Len) {
 	    PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
-	    goto spec_locked_loser;
+	    return SECFailure;
 	}
 	cipherBytes += cipherBytesPart2;
     }	
     PORT_Assert(cipherBytes <= MAX_FRAGMENT_LENGTH + 1024);
 
     ssl3_BumpSequenceNumber(&cwSpec->write_seq_num);
 
     wrBuf->len    = cipherBytes + SSL3_RECORD_HEADER_LENGTH;
     wrBuf->buf[0] = type;
     wrBuf->buf[1] = MSB(cwSpec->version);
     wrBuf->buf[2] = LSB(cwSpec->version);
     wrBuf->buf[3] = MSB(cipherBytes);
     wrBuf->buf[4] = LSB(cipherBytes);
 
-    ssl_ReleaseSpecReadLock(ss); /************************************/
-
     return SECSuccess;
-
-spec_locked_loser:
-    ssl_ReleaseSpecReadLock(ss);
-    return SECFailure;
 }
 
 /* Process the plain text before sending it.
  * Returns the number of bytes of plaintext that were successfully sent
  * 	plus the number of bytes of plaintext that were copied into the
  *	output (write) buffer.
  * Returns SECFailure on a hard IO error, memory error, or crypto error.
  * Does NOT return SECWouldBlock.
@@ -2220,39 +2212,87 @@ ssl3_SendRecord(   sslSocket *        ss
     /* check for Token Presence */
     if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) {
 	PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
 	return SECFailure;
     }
 
     while (nIn > 0) {
 	PRUint32  contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH);
-
-	if (wrBuf->space < contentLen + SSL3_BUFFER_FUDGE) {
-	    PRInt32 newSpace = PR_MAX(wrBuf->space * 2, contentLen);
-	    newSpace = PR_MIN(newSpace, MAX_FRAGMENT_LENGTH);
-	    newSpace += SSL3_BUFFER_FUDGE;
-	    rv = sslBuffer_Grow(wrBuf, newSpace);
+	unsigned int spaceNeeded;
+	unsigned int numRecords;
+
+	ssl_GetSpecReadLock(ss);    /********************************/
+
+	if (nIn > 1 && ss->opt.cbcRandomIV &&
+	    ss->ssl3.cwSpec->version <= SSL_LIBRARY_VERSION_3_1_TLS &&
+	    type == content_application_data &&
+	    ss->ssl3.cwSpec->cipher_def->type == type_block /* CBC mode */) {
+	    /* We will split the first byte of the record into its own record,
+	     * as explained in the documentation for SSL_CBC_RANDOM_IV in ssl.h
+	     */
+	    numRecords = 2;
+	} else {
+	    numRecords = 1;
+	}
+
+	spaceNeeded = contentLen + (numRecords * SSL3_BUFFER_FUDGE);
+	if (spaceNeeded > wrBuf->space) {
+	    rv = sslBuffer_Grow(wrBuf, spaceNeeded);
 	    if (rv != SECSuccess) {
 		SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes",
-			 SSL_GETPID(), ss->fd, newSpace));
-		return SECFailure; /* sslBuffer_Grow set a memory error code. */
+			 SSL_GETPID(), ss->fd, spaceNeeded));
+		goto spec_locked_loser; /* sslBuffer_Grow set error code. */
 	    }
 	}
 
-	rv = ssl3_CompressMACEncryptRecord( ss, type, pIn, contentLen);
+	if (numRecords == 2) {
+	    sslBuffer secondRecord;
+
+	    rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
+	                                       ss->sec.isServer, type, pIn, 1,
+	                                       wrBuf);
+	    if (rv != SECSuccess)
+	        goto spec_locked_loser;
+
+	    PRINT_BUF(50, (ss, "send (encrypted) record data [1/2]:",
+	                   wrBuf->buf, wrBuf->len));
+
+	    secondRecord.buf = wrBuf->buf + wrBuf->len;
+	    secondRecord.len = 0;
+	    secondRecord.space = wrBuf->space - wrBuf->len;
+
+	    rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
+	                                       ss->sec.isServer, type, pIn + 1,
+	                                       contentLen - 1, &secondRecord);
+	    if (rv == SECSuccess) {
+	        PRINT_BUF(50, (ss, "send (encrypted) record data [2/2]:",
+	                       secondRecord.buf, secondRecord.len));
+	        wrBuf->len += secondRecord.len;
+	    }
+	} else {
+	    rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
+	                                       ss->sec.isServer, type, pIn,
+	                                       contentLen, wrBuf);
+	    if (rv == SECSuccess) {
+	        PRINT_BUF(50, (ss, "send (encrypted) record data:",
+	                       wrBuf->buf, wrBuf->len));
+	    }
+	}
+
+spec_locked_loser:
+	ssl_ReleaseSpecReadLock(ss); /************************************/
+
 	if (rv != SECSuccess)
 	    return SECFailure;
 
 	pIn += contentLen;
 	nIn -= contentLen;
 	PORT_Assert( nIn >= 0 );
 
-	PRINT_BUF(50, (ss, "send (encrypted) record data:", wrBuf->buf, wrBuf->len));
-
 	/* If there's still some previously saved ciphertext,
 	 * or the caller doesn't want us to send the data yet,
 	 * then add all our new ciphertext to the amount previously saved.
 	 */
 	if ((ss->pendingBuf.len > 0) ||
 	    (flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) {
 
 	    rv = ssl_SaveWriteData(ss, wrBuf->buf, wrBuf->len);
--- a/security/nss/lib/ssl/sslerr.h
+++ b/security/nss/lib/ssl/sslerr.h
@@ -31,17 +31,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: sslerr.h,v 1.13 2010/09/01 19:43:48 wtc%google.com Exp $ */
+/* $Id: sslerr.h,v 1.14 2011/10/05 18:07:18 emaldona%redhat.com Exp $ */
 #ifndef __SSL_ERR_H_
 #define __SSL_ERR_H_
 
 
 #define SSL_ERROR_BASE				(-0x3000)
 #define SSL_ERROR_LIMIT				(SSL_ERROR_BASE + 1000)
 
 #define IS_SSL_ERROR(code) \
@@ -52,21 +52,23 @@ typedef enum {
 SSL_ERROR_EXPORT_ONLY_SERVER 		= (SSL_ERROR_BASE +  0),
 SSL_ERROR_US_ONLY_SERVER 		= (SSL_ERROR_BASE +  1),
 SSL_ERROR_NO_CYPHER_OVERLAP 		= (SSL_ERROR_BASE +  2),
 /* 
  * Received an alert reporting what we did wrong.  (more alerts below)
  */
 SSL_ERROR_NO_CERTIFICATE /*_ALERT */	= (SSL_ERROR_BASE +  3),
 SSL_ERROR_BAD_CERTIFICATE            	= (SSL_ERROR_BASE +  4),
+SSL_ERROR_UNUSED_5			= (SSL_ERROR_BASE +  5),
 					/* error 5 is obsolete */
 SSL_ERROR_BAD_CLIENT 			= (SSL_ERROR_BASE +  6),
 SSL_ERROR_BAD_SERVER 			= (SSL_ERROR_BASE +  7),
 SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE	= (SSL_ERROR_BASE +  8),
 SSL_ERROR_UNSUPPORTED_VERSION 		= (SSL_ERROR_BASE +  9),
+SSL_ERROR_UNUSED_10			= (SSL_ERROR_BASE + 10),
 					/* error 10 is obsolete */
 SSL_ERROR_WRONG_CERTIFICATE		= (SSL_ERROR_BASE + 11),
 SSL_ERROR_BAD_CERT_DOMAIN 		= (SSL_ERROR_BASE + 12),
 SSL_ERROR_POST_WARNING 			= (SSL_ERROR_BASE + 13),
 SSL_ERROR_SSL2_DISABLED 		= (SSL_ERROR_BASE + 14),
 SSL_ERROR_BAD_MAC_READ 			= (SSL_ERROR_BASE + 15),
 /* 
  * Received an alert reporting what we did wrong.
--- a/security/nss/lib/ssl/sslimpl.h
+++ b/security/nss/lib/ssl/sslimpl.h
@@ -34,17 +34,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: sslimpl.h,v 1.82 2011/03/10 04:29:04 alexei.volkov.bugs%sun.com Exp $ */
+/* $Id: sslimpl.h,v 1.83 2011/10/01 03:59:54 bsmith%mozilla.com Exp $ */
 
 #ifndef __sslimpl_h_
 #define __sslimpl_h_
 
 #ifdef DEBUG
 #undef NDEBUG
 #else
 #undef NDEBUG
@@ -329,16 +329,17 @@ typedef struct sslOptionsStr {
     unsigned int noStepDown             : 1;  /* 15 */
     unsigned int bypassPKCS11           : 1;  /* 16 */
     unsigned int noLocks                : 1;  /* 17 */
     unsigned int enableSessionTickets   : 1;  /* 18 */
     unsigned int enableDeflate          : 1;  /* 19 */
     unsigned int enableRenegotiation    : 2;  /* 20-21 */
     unsigned int requireSafeNegotiation : 1;  /* 22 */
     unsigned int enableFalseStart       : 1;  /* 23 */
+    unsigned int cbcRandomIV            : 1;  /* 24 */
 } sslOptions;
 
 typedef enum { sslHandshakingUndetermined = 0,
 	       sslHandshakingAsClient,
 	       sslHandshakingAsServer 
 } sslHandshakingType;
 
 typedef struct sslServerCertsStr {
--- a/security/nss/lib/ssl/sslmutex.c
+++ b/security/nss/lib/ssl/sslmutex.c
@@ -28,17 +28,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: sslmutex.c,v 1.25 2010/04/03 18:27:33 nelson%bolyard.com Exp $ */
+/* $Id: sslmutex.c,v 1.27 2011/10/01 00:11:02 wtc%google.com Exp $ */
 
 #include "seccomon.h"
 /* This ifdef should match the one in sslsnce.c */
 #if defined(XP_UNIX) || defined(XP_WIN32) || defined (XP_OS2) || defined(XP_BEOS)
 
 #include "sslmutex.h"
 #include "prerr.h"
 
@@ -163,28 +163,32 @@ sslMutex_Init(sslMutex *pMutex, int shar
 loser:
     nss_MD_unix_map_default_error(errno);
     close(pMutex->u.pipeStr.mPipes[0]);
     close(pMutex->u.pipeStr.mPipes[1]);
     return SECFailure;
 }
 
 SECStatus
-sslMutex_Destroy(sslMutex *pMutex)
+sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
 {
     if (PR_FALSE == pMutex->isMultiProcess) {
         return single_process_sslMutex_Destroy(pMutex);
     }
     if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) {
 	PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
 	return SECFailure;
     }
     close(pMutex->u.pipeStr.mPipes[0]);
     close(pMutex->u.pipeStr.mPipes[1]);
 
+    if (processLocal) {
+	return SECSuccess;
+    }
+
     pMutex->u.pipeStr.mPipes[0] = -1;
     pMutex->u.pipeStr.mPipes[1] = -1;
     pMutex->u.pipeStr.mPipes[2] = -1;
     pMutex->u.pipeStr.nWaiters  =  0;
 
     return SECSuccess;
 }
 
@@ -404,17 +408,17 @@ sslMutex_Init(sslMutex *pMutex, int shar
         nss_MD_win32_map_default_error(GetLastError());
         return SECFailure;
     }
     pMutex->u.sslMutx = hMutex;
     return SECSuccess;
 }
 
 SECStatus
-sslMutex_Destroy(sslMutex *pMutex)
+sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
 {
     HANDLE hMutex;
     int    rv;
     int retvalue = SECSuccess;
 
     PR_ASSERT(pMutex != 0);
     if (PR_FALSE == pMutex->isMultiProcess) {
         return single_process_sslMutex_Destroy(pMutex);
@@ -430,19 +434,20 @@ sslMutex_Destroy(sslMutex *pMutex)
                pMutex->u.sslMutx != INVALID_HANDLE_VALUE);
     if (!pMutex || (hMutex = pMutex->u.sslMutx) == 0 
         || hMutex == INVALID_HANDLE_VALUE) {
         PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
         return SECFailure;
     }
     
     rv = CloseHandle(hMutex); /* ignore error */
-    if (rv) {
+    if (!processLocal && rv) {
         pMutex->u.sslMutx = hMutex = INVALID_HANDLE_VALUE;
-    } else {
+    }
+    if (!rv) {
         nss_MD_win32_map_default_error(GetLastError());
         retvalue = SECFailure;
     }
     return retvalue;
 }
 
 int 
 sslMutex_Unlock(sslMutex *pMutex)
@@ -552,22 +557,27 @@ sslMutex_Init(sslMutex *pMutex, int shar
     if (rv < 0) {
         nss_MD_unix_map_default_error(errno);
         return SECFailure;
     }
     return SECSuccess;
 }
 
 SECStatus 
-sslMutex_Destroy(sslMutex *pMutex)
+sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
 {
     int rv;
     if (PR_FALSE == pMutex->isMultiProcess) {
         return single_process_sslMutex_Destroy(pMutex);
     }
+
+    /* semaphores are global resources. See SEM_DESTROY(3) man page */
+    if (processLocal) {
+	return SECSuccess;
+    }
     do {
 	rv = sem_destroy(&pMutex->u.sem);
     } while (rv < 0 && errno == EINTR);
     if (rv < 0) {
 	nss_MD_unix_map_default_error(errno);
 	return SECFailure;
     }
     return SECSuccess;
@@ -618,17 +628,17 @@ sslMutex_Init(sslMutex *pMutex, int shar
         return single_process_sslMutex_Init(pMutex);
     }
     PORT_Assert(!("sslMutex_Init not implemented for multi-process applications !"));
     PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
     return SECFailure;
 }
 
 SECStatus 
-sslMutex_Destroy(sslMutex *pMutex)
+sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
 {
     PR_ASSERT(pMutex);
     if (PR_FALSE == pMutex->isMultiProcess) {
         return single_process_sslMutex_Destroy(pMutex);
     }
     PORT_Assert(!("sslMutex_Destroy not implemented for multi-process applications !"));
     PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
     return SECFailure;
--- a/security/nss/lib/ssl/sslmutex.h
+++ b/security/nss/lib/ssl/sslmutex.h
@@ -28,17 +28,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: sslmutex.h,v 1.12 2009/06/05 02:34:15 nelson%bolyard.com Exp $ */
+/* $Id: sslmutex.h,v 1.13 2011/09/30 23:27:08 rrelyea%redhat.com Exp $ */
 #ifndef __SSLMUTEX_H_
 #define __SSLMUTEX_H_ 1
 
 /* What SSL really wants is portable process-shared unnamed mutexes in 
  * shared memory, that have the property that if the process that holds
  * them dies, they are released automatically, and that (unlike fcntl 
  * record locking) lock to the thread, not to the process.  
  * NSPR doesn't provide that.  
@@ -133,17 +133,20 @@ typedef int sslPID;
 #endif
 
 #include "seccomon.h"
 
 SEC_BEGIN_PROTOS
 
 extern SECStatus sslMutex_Init(sslMutex *sem, int shared);
 
-extern SECStatus sslMutex_Destroy(sslMutex *sem);
+/* If processLocal is set to true, then just free resources which are *only* associated
+ * with the current process. Leave any shared resources (including the state of 
+ * shared memory) intact. */
+extern SECStatus sslMutex_Destroy(sslMutex *sem, PRBool processLocal);
 
 extern SECStatus sslMutex_Unlock(sslMutex *sem);
 
 extern SECStatus sslMutex_Lock(sslMutex *sem);
 
 #ifdef WINNT
 
 extern SECStatus sslMutex_2LevelInit(sslMutex *sem);
--- a/security/nss/lib/ssl/sslsnce.c
+++ b/security/nss/lib/ssl/sslsnce.c
@@ -31,17 +31,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: sslsnce.c,v 1.56 2011/08/17 14:41:10 emaldona%redhat.com Exp $ */
+/* $Id: sslsnce.c,v 1.58 2011/10/01 00:11:02 wtc%google.com Exp $ */
 
 /* Note: ssl_FreeSID() in sslnonce.c gets used for both client and server 
  * cache sids!
  *
  * About record locking among different server processes:
  *
  * All processes that are part of the same conceptual server (serving on 
  * the same address and port) MUST share a common SSL session cache. 
@@ -1022,25 +1022,26 @@ long gettid(void)
 #endif
 
 static void
 CloseCache(cacheDesc *cache)
 {
     int locks_initialized = cache->numSIDCacheLocksInitialized;
 
     if (cache->cacheMem) {
-	/* If everInherited is true, this shared cache was (and may still
-	** be) in use by multiple processes.  We do not wish to destroy
-	** the mutexes while they are still in use.  
-	*/
-	if (cache->sharedCache &&
-            PR_FALSE == cache->sharedCache->everInherited) {
+	if (cache->sharedCache) {
 	    sidCacheLock *pLock = cache->sidCacheLocks;
 	    for (; locks_initialized > 0; --locks_initialized, ++pLock ) {
-		sslMutex_Destroy(&pLock->mutex);
+		/* If everInherited is true, this shared cache was (and may
+		** still be) in use by multiple processes.  We do not wish to
+		** destroy the mutexes while they are still in use, but we do
+		** want to free mutex resources associated with this process.
+		*/
+		sslMutex_Destroy(&pLock->mutex,
+				 cache->sharedCache->everInherited);
 	    }
 	}
 	if (cache->shared) {
 	    PR_MemUnmap(cache->cacheMem, cache->cacheMemSize);
 	} else {
 	    PORT_Free(cache->cacheMem);
 	}
 	cache->cacheMem = NULL;
--- a/security/nss/lib/ssl/sslsock.c
+++ b/security/nss/lib/ssl/sslsock.c
@@ -35,17 +35,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: sslsock.c,v 1.72 2011/08/17 14:41:16 emaldona%redhat.com Exp $ */
+/* $Id: sslsock.c,v 1.74 2011/10/06 22:42:34 wtc%google.com Exp $ */
 #include "seccomon.h"
 #include "cert.h"
 #include "keyhi.h"
 #include "ssl.h"
 #include "sslimpl.h"
 #include "sslproto.h"
 #include "sslutil.h"
 #include "nspr.h"
@@ -165,31 +165,32 @@ static const sslSocketOps ssl_secure_ops
 */
 static sslOptions ssl_defaults = {
     PR_TRUE, 	/* useSecurity        */
     PR_FALSE,	/* useSocks           */
     PR_FALSE,	/* requestCertificate */
     2,	        /* requireCertificate */
     PR_FALSE,	/* handshakeAsClient  */
     PR_FALSE,	/* handshakeAsServer  */
-    PR_TRUE,	/* enableSSL2         */
+    PR_FALSE,	/* enableSSL2         */ /* now defaults to off in NSS 3.13 */
     PR_TRUE,	/* enableSSL3         */
     PR_TRUE, 	/* enableTLS          */ /* now defaults to on in NSS 3.0 */
     PR_FALSE,	/* noCache            */
     PR_FALSE,	/* fdx                */
-    PR_TRUE,	/* v2CompatibleHello  */
+    PR_FALSE,	/* v2CompatibleHello  */ /* now defaults to off in NSS 3.13 */
     PR_TRUE,	/* detectRollBack     */
     PR_FALSE,   /* noStepDown         */
     PR_FALSE,   /* bypassPKCS11       */
     PR_FALSE,   /* noLocks            */
     PR_FALSE,   /* enableSessionTickets */
     PR_FALSE,   /* enableDeflate      */
     2,          /* enableRenegotiation (default: requires extension) */
     PR_FALSE,   /* requireSafeNegotiation */
     PR_FALSE,   /* enableFalseStart   */
+    PR_TRUE     /* cbcRandomIV        */
 };
 
 sslSessionIDLookupFunc  ssl_sid_lookup;
 sslSessionIDCacheFunc   ssl_sid_cache;
 sslSessionIDUncacheFunc ssl_sid_uncache;
 
 static PRBool ssl_inited = PR_FALSE;
 static PRDescIdentity ssl_layer_id;
@@ -730,16 +731,20 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 wh
       case SSL_REQUIRE_SAFE_NEGOTIATION:
 	ss->opt.requireSafeNegotiation = on;
 	break;
 
       case SSL_ENABLE_FALSE_START:
 	ss->opt.enableFalseStart = on;
 	break;
 
+      case SSL_CBC_RANDOM_IV:
+	ss->opt.cbcRandomIV = on;
+	break;
+
       default:
 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
 	rv = SECFailure;
     }
 
     /* We can't use the macros for releasing the locks here,
      * because ss->opt.noLocks might have changed just above.
      * We must release these locks (monitors) here, if we aquired them above,
@@ -794,16 +799,17 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 wh
 	on = ss->opt.enableSessionTickets;
 	break;
     case SSL_ENABLE_DEFLATE:      on = ss->opt.enableDeflate;      break;
     case SSL_ENABLE_RENEGOTIATION:     
                                   on = ss->opt.enableRenegotiation; break;
     case SSL_REQUIRE_SAFE_NEGOTIATION: 
                                   on = ss->opt.requireSafeNegotiation; break;
     case SSL_ENABLE_FALSE_START:  on = ss->opt.enableFalseStart;   break;
+    case SSL_CBC_RANDOM_IV:       on = ss->opt.cbcRandomIV;        break;
 
     default:
 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
 	rv = SECFailure;
     }
 
     ssl_ReleaseSSL3HandshakeLock(ss);
     ssl_Release1stHandshakeLock(ss);
@@ -847,16 +853,17 @@ SSL_OptionGetDefault(PRInt32 which, PRBo
 	break;
     case SSL_ENABLE_DEFLATE:      on = ssl_defaults.enableDeflate;      break;
     case SSL_ENABLE_RENEGOTIATION:     
                                   on = ssl_defaults.enableRenegotiation; break;
     case SSL_REQUIRE_SAFE_NEGOTIATION: 
                                   on = ssl_defaults.requireSafeNegotiation; 
 				  break;
     case SSL_ENABLE_FALSE_START:  on = ssl_defaults.enableFalseStart;   break;
+    case SSL_CBC_RANDOM_IV:       on = ssl_defaults.cbcRandomIV;        break;
 
     default:
 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
 	rv = SECFailure;
     }
 
     *pOn = on;
     return rv;
@@ -1002,16 +1009,20 @@ SSL_OptionSetDefault(PRInt32 which, PRBo
       case SSL_REQUIRE_SAFE_NEGOTIATION:
 	ssl_defaults.requireSafeNegotiation = on;
 	break;
 
       case SSL_ENABLE_FALSE_START:
 	ssl_defaults.enableFalseStart = on;
 	break;
 
+      case SSL_CBC_RANDOM_IV:
+	ssl_defaults.cbcRandomIV = on;
+	break;
+
       default:
 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
 	return SECFailure;
     }
     return SECSuccess;
 }
 
 /* function tells us if the cipher suite is one that we no longer support. */
@@ -2343,16 +2354,21 @@ ssl_SetDefaultsFromEnvironment(void)
 	               ssl_defaults.enableRenegotiation));
 	}
 	ev = getenv("NSS_SSL_REQUIRE_SAFE_NEGOTIATION");
 	if (ev && ev[0] == '1') {
 	    ssl_defaults.requireSafeNegotiation = PR_TRUE;
 	    SSL_TRACE(("SSL: requireSafeNegotiation set to %d", 
 	                PR_TRUE));
 	}
+	ev = getenv("NSS_SSL_CBC_RANDOM_IV");
+	if (ev && ev[0] == '0') {
+	    ssl_defaults.cbcRandomIV = PR_FALSE;
+	    SSL_TRACE(("SSL: cbcRandomIV set to 0"));
+	}
     }
 #endif /* NSS_HAVE_GETENV */
 }
 
 /*
 ** Create a newsocket structure for a file descriptor.
 */
 static sslSocket *
--- a/security/nss/lib/util/errstrs.c
+++ b/security/nss/lib/util/errstrs.c
@@ -58,126 +58,15 @@ static const struct PRErrorTable sec_et 
 
 static PRStatus 
 nss_InitializePRErrorTableOnce(void) {
     return PR_ErrorInstallTable(&sec_et);
 }
 
 static PRCallOnceType once;
 
-PRStatus
+SECStatus
 NSS_InitializePRErrorTable(void)
 {
-    return PR_CallOnce(&once, nss_InitializePRErrorTableOnce);
-}
-
-/* Returns a UTF-8 encoded constant error string for "errNum".
- * Returns NULL if either initialization of the error tables
- * or formatting fails due to insufficient memory. 
- *
- * This is the simpler common function that the others call.
- * It is thread safe and does not preappend anything to the
- * mapped error string.
- */
-static char *
-nss_Strerror(PRErrorCode errNum)
-{
-    static int initDone;
-
-    if (!initDone) {
-    /* nspr_InitializePRErrorTable(); done by PR_Init */
-    PRStatus rv = NSS_InitializePRErrorTable();
-    /* If this calls fails for insufficient memory, just return NULL */
-    if (rv != PR_SUCCESS) return NULL;
-	initDone = 1;
-    }
-
-    return (char *) PR_ErrorToString(errNum, PR_LANGUAGE_I_DEFAULT);
+    return (PR_SUCCESS == PR_CallOnce(&once, nss_InitializePRErrorTableOnce))
+		? SECSuccess : SECFailure;
 }
 
-/* Hope this size is sufficient even with localization */
-#define EBUFF_SIZE 512
-static char ebuf[EBUFF_SIZE];
-
-/* Returns a UTF-8 encoded constant error string for "errNum".
- * Returns NULL if either initialization of the error tables
- * or formatting fails due to insufficient memory.
- *
- * The format argument indicates whether extra error information
- * is desired. This is useful when localizations are not yet
- * available and the mapping would return nothing for a locale. 
- *
- * Specify formatSimple to get just the error string as mapped.
- * Specify formatIncludeErrorCode to format the error code 
- * numeric value plus a bracketed stringized error name
- * preappended to the mapped error string. 
- * 
- * Additional formatting options may be added in teh future
- *
- * This string must not be modified by the application, but may be modified by
- * a subsequent call to NSS_Perror() or NSS_Strerror().
- */
-char *
-NSS_Strerror(PRErrorCode errNum, ReportFormatType format)
-{
-    PRUint32 count;
-    char *errname = (char *) PR_ErrorToName(errNum);
-    char *errstr = nss_Strerror(errNum);
-
-    if (!errstr) return NULL;
-
-    if (format == formatSimple) return errstr;
-
-    count = PR_snprintf(ebuf, EBUFF_SIZE, "[%d %s] %s",
-	errNum, errname, errstr);
-
-    PR_ASSERT(count != -1);
-
-    return ebuf;
-}
-
-/* NSS_StrerrorTS is a thread safe version of NSS_Strerror.
- * It formats output into a buffer allocated at run time.
- * The buffer is allocated with PR_smprintf thus the string
- * returned should be freed with PR_smprintf_free.
- */
-char *
-NSS_StrerrorTS(PRErrorCode errNum, ReportFormatType format)
-{
-    char *errstr = NSS_Strerror(errNum, format);
-
-    return PR_smprintf("[%d %s] %s",
-	errNum, PR_ErrorToName(errNum), errstr ? errstr : "");
-}
-
-/* Prints an error message on the standard error output, describing the last
- * error encountered during a call to an NSS library function.
- *
- * A language-dependent error message is written and formatted to
- * the standard error stream as follows:
- *
- *  If s is not a NULL or empty, prints the string pointed to by s followed
- *  by a colon and a space and then the error message string followed by a
- *  newline.
- *
- * NSS_Perror is partially modeled after the posix function perror.
- */
-void
-NSS_Perror(const char *s, ReportFormatType format)
-{
-    PRErrorCode err;
-    char *errString;
-
-    if (!s || PORT_Strlen(s) == 0) {
-	return;
-    }
-
-    err = PORT_GetError();
-    errString = NSS_Strerror(err, format);
-
-    fprintf(stderr, "%s: ", s);
-
-    if (errString != NULL && PORT_Strlen(errString) > 0) {
-	fprintf(stderr, "%s\n", errString);
-    } else {
-	fprintf(stderr, "Unknown error: %d\n", (int)err);
-    }
-}
deleted file mode 100644
--- a/security/nss/lib/util/errstrs.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * NSS utility functions
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Network Security Services.
- *
- * The Initial Developer of the Original Code is
- * Red Hat Inc.
- * Portions created by the Initial Developer are Copyright (C) 2009
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef __errstrs_h_
-#define __errstrs_h_
-
-#include "prerror.h"
-
-#ifndef RC_INVOKED
-#include "seccomon.h"
-#endif
-
-SEC_BEGIN_PROTOS
-
-extern PRStatus
-nss_InitializePRErrorTable(void);
-
-SEC_END_PROTOS
-
-#endif /* __errstrs_h_ */
--- a/security/nss/lib/util/manifest.mn
+++ b/security/nss/lib/util/manifest.mn
@@ -65,17 +65,16 @@ EXPORTS = \
 	secoid.h \
 	secoidt.h \
 	secport.h \
 	secerr.h \
 	utilrename.h \
 	$(NULL)
 
 PRIVATE_EXPORTS = \
-	errstrs.h \
 	templates.c \
 	$(NULL)
 
 CSRCS = \
 	quickder.c \
 	secdig.c \
 	derdec.c \
 	derenc.c \
--- a/security/nss/lib/util/nssutil.def
+++ b/security/nss/lib/util/nssutil.def
@@ -249,18 +249,15 @@ PORT_LoadLibraryFromOrigin;
 ;+       *;
 ;+};
 ;+NSSUTIL_3.12.7 {       # NSS Utilities 3.12.7 release
 ;+    global:
 PORT_RegExpSearch;
 ;+    local:
 ;+       *;
 ;+};
-;+NSS_3.13 {    # NSS 3.13 release
+;+NSSUTIL_3.13 {         # NSS Utilities 3.13 release
 ;+    global:
 NSSUTIL_GetVersion;
 NSS_InitializePRErrorTable;
-NSS_Strerror;
-NSS_StrerrorTS;
-NSS_Perror;
 ;+    local:
 ;+       *;
 ;+};
--- a/security/nss/lib/util/nssutil.h
+++ b/security/nss/lib/util/nssutil.h
@@ -36,87 +36,38 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef __nssutil_h_
 #define __nssutil_h_
 
 #ifndef RC_INVOKED
-#include "prerror.h"
 #include "seccomon.h"
 #endif
 
 /*
  * NSS utilities's major version, minor version, patch level, build number,
  * and whether this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
  */
-#define NSSUTIL_VERSION  "3.13.0.0 Beta"
+#define NSSUTIL_VERSION  "3.13.0.0"
 #define NSSUTIL_VMAJOR   3
 #define NSSUTIL_VMINOR   13
 #define NSSUTIL_VPATCH   0
 #define NSSUTIL_VBUILD   0
-#define NSSUTIL_BETA     PR_TRUE
-
-typedef enum {
-    formatSimple = 0,
-    formatIncludeErrorCode
-} ReportFormatType;
-    
+#define NSSUTIL_BETA     PR_FALSE
 
 SEC_BEGIN_PROTOS
 
 /*
  * Returns a const string of the UTIL library version.
  */
 extern const char *NSSUTIL_GetVersion(void);
 
-extern PRStatus
+extern SECStatus
 NSS_InitializePRErrorTable(void);
 
-/* Returns a UTF-8 encoded constant error string for "errNum".
- * Returns NULL if either initialization of the error tables
- * or formatting fails due to insufficient memory.
- *
- * The format argument indicates whether extra error information
- * is desired. This is useful when localizations are not yet
- * available and the mapping would return nothing for a locale. 
- *
- * Specify formatSimple to get just the error string as mapped.
- * Specify formatIncludeErrorCode to format the error code 
- * numeric value plus a bracketed stringized error name
- * preappended to the mapped error string. 
- * 
- * Additional formatting options may be added in teh future
- *
- * This string must not be modified by the application, but may be modified by
- * a subsequent call to NSS_Perror() or NSS_Strerror().
- */
-extern char *
-NSS_Strerror(PRErrorCode errNum, ReportFormatType format);
-
-/* NSS_StrerrorTS is a thread safe version of NSS_Strerror.
- * It formats output into a buffer allocated at run time.
- * The buffer is allocated with PR_smprintf thus the string
- * returned should be freed with PR_smprintf_free.
- */
-extern char *
-NSS_StrerrorTS(PRErrorCode errNum, ReportFormatType format);
-
-/* Prints an error message on the standard error output, describing the last
- * error encountered during a call to an NSS library function.
- *
- * A language-dependent error message is written and formatted to the standard
- * error stream as follows:
- *
- *  If s is not a null pointer or empty, it prints the string pointed to
- *  by s followed by a colon and a space and then the error message string
- *  followed by a newline.
- */
-extern void
-NSS_Perror(const char *s, ReportFormatType format);
-
 SEC_END_PROTOS
 
 #endif /* __nssutil_h_ */
--- a/security/nss/lib/util/pkcs11n.h
+++ b/security/nss/lib/util/pkcs11n.h
@@ -34,17 +34,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _PKCS11N_H_
 #define _PKCS11N_H_
 
 #ifdef DEBUG
-static const char CKT_CVS_ID[] = "@(#) $RCSfile: pkcs11n.h,v $ $Revision: 1.22 $ $Date: 2011/04/13 00:10:27 $";
+static const char CKT_CVS_ID[] = "@(#) $RCSfile: pkcs11n.h,v $ $Revision: 1.23 $ $Date: 2011/09/14 01:21:10 $";
 #endif /* DEBUG */
 
 /*
  * pkcs11n.h
  *
  * This file contains the NSS-specific type definitions for Cryptoki
  * (PKCS#11).
  */
@@ -338,17 +338,17 @@ typedef CK_ULONG          CK_TRUST;
  * These may well remain NSS-specific; I'm only using them
  * to cache resolution data.
  */
 #define CKT_NSS_VALID_DELEGATOR    (CKT_NSS + 11)
 
 
 /*
  * old definitions. They still exist, but the plain meaning of the
- * labels have never been accurate to was was really implemented.
+ * labels have never been accurate to what was really implemented.
  * The new labels correctly reflect what the values effectively mean.
  */
 #if __GNUC__ > 3
 /* make GCC warn when we use these #defines */
 /*
  *  This is really painful because GCC doesn't allow us to mark random
  *  #defines as deprecated. We can only mark the following:
  *      functions, variables, and types.
--- a/security/nss/lib/util/secasn1u.c
+++ b/security/nss/lib/util/secasn1u.c
@@ -32,17 +32,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * Utility routines to complement the ASN.1 encoding and decoding functions.
  *
- * $Id: secasn1u.c,v 1.4 2005/04/09 05:06:34 julien.pierre.bugs%sun.com Exp $
+ * $Id: secasn1u.c,v 1.5 2011/10/01 00:39:15 wtc%google.com Exp $
  */
 
 #include "secasn1.h"
 
 
 /*
  * We have a length that needs to be encoded; how many bytes will the
  * encoding take?
@@ -113,17 +113,17 @@ PRBool SEC_ASN1IsTemplateSimple(const SE
     if (!theTemplate) {
 	return PR_TRUE; /* it doesn't get any simpler than NULL */
     }
     /* only templates made of one primitive type or a choice of primitive
        types are considered simple */
     if (! (theTemplate->kind & (~SEC_ASN1_TAGNUM_MASK))) {
 	return PR_TRUE; /* primitive type */
     }
-    if (!theTemplate->kind & SEC_ASN1_CHOICE) {
+    if (!(theTemplate->kind & SEC_ASN1_CHOICE)) {
 	return PR_FALSE; /* no choice means not simple */
     }
     while (++theTemplate && theTemplate->kind) {
 	if (theTemplate->kind & (~SEC_ASN1_TAGNUM_MASK)) {
 	    return PR_FALSE; /* complex type */
 	}
     }
     return PR_TRUE; /* choice of primitive types */
--- a/security/nss/lib/util/secport.h
+++ b/security/nss/lib/util/secport.h
@@ -32,17 +32,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * secport.h - portability interfaces for security libraries
  *
- * $Id: secport.h,v 1.23 2009/10/30 09:44:47 nelson%bolyard.com Exp $
+ * $Id: secport.h,v 1.27 2011/10/04 18:46:04 emaldona%redhat.com Exp $
  */
 
 #ifndef _SECPORT_H_
 #define _SECPORT_H_
 
 #include "utilrename.h"
 #include "prlink.h"
 
@@ -144,16 +144,26 @@ SEC_END_PROTOS
 		(type*) PORT_ArenaAlloc (poolp, sizeof(type)*(num))
 #define PORT_ArenaZNewArray(poolp, type, num)	\
 		(type*) PORT_ArenaZAlloc (poolp, sizeof(type)*(num))
 
 /* Please, keep these defines sorted alphabetically.  Thanks! */
 
 #define PORT_Atoi(buff)	(int)strtol(buff, NULL, 10)
 
+/* Returns a UTF-8 encoded constant error string for err.
+ * Returns NULL if initialization of the error tables fails
+ * due to insufficient memory.
+ *
+ * This string must not be modified by the application.
+ */
+#define PORT_ErrorToString(err) PR_ErrorToString((err), PR_LANGUAGE_I_DEFAULT)
+
+#define PORT_ErrorToName PR_ErrorToName
+
 #define PORT_Memcmp 	memcmp
 #define PORT_Memcpy 	memcpy
 #ifndef SUNOS4
 #define PORT_Memmove 	memmove
 #else /*SUNOS4*/
 #define PORT_Memmove(s,ct,n)    bcopy ((ct), (s), (n))
 #endif/*SUNOS4*/
 #define PORT_Memset 	memset
--- a/security/nss/tests/cert/cert.sh
+++ b/security/nss/tests/cert/cert.sh
@@ -110,32 +110,33 @@ cert_log() ######################    wri
 
 ################################ certu #################################
 # local shell function to call certutil, also: writes action and options to
 # stdout, sets variable RET and writes results to the html file results
 ########################################################################
 certu()
 {
     echo "$SCRIPTNAME: ${CU_ACTION} --------------------------"
+    EXPECTED=${RETEXPECTED-0}
 
     if [ -n "${CU_SUBJECT}" ]; then
         #the subject of the cert contains blanks, and the shell 
         #will strip the quotes off the string, if called otherwise...
         echo "certutil -s \"${CU_SUBJECT}\" $*"
         ${PROFTOOL} ${BINDIR}/certutil -s "${CU_SUBJECT}" $*
         RET=$?
         CU_SUBJECT=""
     else
         echo "certutil $*"
         ${PROFTOOL} ${BINDIR}/certutil $*
         RET=$?
     fi
-    if [ "$RET" -ne 0 ]; then
+    if [ "$RET" -ne "$EXPECTED" ]; then
         CERTFAILED=$RET
-        html_failed "${CU_ACTION} ($RET) " 
+        html_failed "${CU_ACTION} ($RET=$EXPECTED) " 
         cert_log "ERROR: ${CU_ACTION} failed $RET"
     else
         html_passed "${CU_ACTION}"
     fi
 
     return $RET
 }
 
@@ -275,25 +276,25 @@ cert_create_cert()
     if [ "$RET" -ne 0 ]; then
         return $RET
     fi
 
     hw_acc
 
     CU_ACTION="Import Root CA for $CERTNAME"
     certu -A -n "TestCA" -t "TC,TC,TC" -f "${R_PWFILE}" -d "${PROFILEDIR}" \
-          -i "${R_CADIR}/root.cert" 2>&1
+          -i "${R_CADIR}/TestCA.ca.cert" 2>&1
     if [ "$RET" -ne 0 ]; then
         return $RET
     fi
 
     if [ -n "$NSS_ENABLE_ECC" ] ; then
 	CU_ACTION="Import EC Root CA for $CERTNAME"
 	certu -A -n "TestCA-ec" -t "TC,TC,TC" -f "${R_PWFILE}" \
-	    -d "${PROFILEDIR}" -i "${R_CADIR}/ecroot.cert" 2>&1
+	    -d "${PROFILEDIR}" -i "${R_CADIR}/TestCA-ec.ca.cert" 2>&1
 	if [ "$RET" -ne 0 ]; then
             return $RET
 	fi
     fi
 
     cert_add_cert "$5"
     return $?
 }
@@ -1024,17 +1025,17 @@ cert_eccurves()
     CU_ACTION="Initializing EC Curve's Cert DB"
     certu -N -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1
 
     CU_ACTION="Loading root cert module to EC Curve's Cert DB"
     modu -add "RootCerts" -libfile "${ROOTCERTSFILE}" -dbdir "${PROFILEDIR}" 2>&1
 
     CU_ACTION="Import EC Root CA for $CERTNAME"
     certu -A -n "TestCA-ec" -t "TC,TC,TC" -f "${R_PWFILE}" \
-        -d "${PROFILEDIR}" -i "${R_CADIR}/ecroot.cert" 2>&1
+        -d "${PROFILEDIR}" -i "${R_CADIR}/TestCA-ec.ca.cert" 2>&1
 
     if [ -n "${NSS_ECC_MORE_THAN_SUITE_B}" ] ; then
       CURVE_LIST="c2pnb163v1 c2pnb163v2 c2pnb163v3 c2pnb176v1 \
 	c2pnb208w1 c2pnb272w1 c2pnb304w1 c2pnb368w1 \
 	c2tnb191v1 c2tnb191v2 c2tnb191v3 c2tnb239v1 \
 	c2tnb239v2 c2tnb239v3 c2tnb359v1 c2tnb431r1 \
 	nistb163 nistb233 nistb283 nistb409 nistb571 \
 	nistk163 nistk233 nistk283 nistk409 nistk571 \
@@ -1391,16 +1392,88 @@ cert_test_password()
   certu -S -n PasswordCert -c PasswordCA -t "u,u,u" -d "${PROFILEDIR}" -f "${R_FIPSPWFILE}" -z "${R_NOISE_FILE}" 2>&1
   if [ "$RET" -eq 0 ]; then
     cert_log "SUCCESS: PASSWORD passed"
   fi
   CU_ACTION="Verify Certificate for ${CERTNAME} with new password"
   certu -V -n PasswordCert -u S -d "${PROFILEDIR}" -f "${R_FIPSPWFILE}" 2>&1
 }
 
+###############################
+# test if we can distrust a certificate.
+#
+# we create 3 new certs:
+#   1 leaf signed by the trusted root.
+#   1 intermediate signed by the trusted root.
+#   1 leaf signed by the intermediate.
+#
+#  we mark the first leaf and the intermediate as explicitly untrusted.
+#  we then try to verify the two leaf certs for our possible usages.
+#  All verification should fail.
+# 
+cert_test_distrust()
+{
+  echo "$SCRIPTNAME: Creating Distrusted Certificate"
+  cert_create_cert ${DISTRUSTDIR} "Distrusted" 2000 ${D_DISTRUST}
+  CU_ACTION="Mark CERT as unstrusted"
+  certu -M -n "Distrusted" -t p,p,p -d ${PROFILEDIR} -f "${R_PWFILE}" 2>&1
+  echo "$SCRIPTNAME: Creating Distrusted Intermediate"
+  CERTNAME="DistrustedCA"
+  ALL_CU_SUBJECT="CN=${CERTNAME}, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
+  cert_CA ${CADIR} "${CERTNAME}" "-c TestCA" ",," ${D_CA} 2010 2>&1
+  CU_ACTION="Import Distrusted Intermediate"
+  certu -A -n "${CERTNAME}" -t "p,p,p" -f "${R_PWFILE}" -d "${PROFILEDIR}" \
+          -i "${R_CADIR}/DistrustedCA.ca.cert" 2>&1
+
+  # now create the last leaf signed by our distrusted CA
+  # since it's not signed by TestCA it requires more steps.
+  CU_ACTION="Generate Cert Request for Leaf Chained to Distrusted CA"
+  CERTNAME="LeafChainedToDistrustedCA"
+  CU_SUBJECT="CN=${CERTNAME}, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US"
+  certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1
+
+  CU_ACTION="Sign ${CERTNAME}'s Request"
+  cp ${CERTDIR}/req ${CADIR}
+  certu -C -c "DistrustedCA" -m 100 -v 60 -d "${P_R_CADIR}" \
+        -i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" 2>&1
+
+  CU_ACTION="Import $CERTNAME's Cert  -t u,u,u"
+  certu -A -n "$CERTNAME" -t "u,u,u" -d "${PROFILEDIR}" -f "${R_PWFILE}" \
+        -i "${CERTNAME}.cert" 2>&1
+
+  RETEXPECTED=255
+  CU_ACTION="Verify ${CERTNAME} Cert for SSL Server"
+  certu -V -n ${CERTNAME} -u V -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1
+  CU_ACTION="Verify ${CERTNAME} Cert for SSL Client"
+  certu -V -n ${CERTNAME} -u C -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1
+  CU_ACTION="Verify ${CERTNAME} Cert for Email signer"
+  certu -V -n ${CERTNAME} -u S -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1
+  CU_ACTION="Verify ${CERTNAME} Cert for Email recipient"
+  certu -V -n ${CERTNAME} -u R -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1
+  CU_ACTION="Verify ${CERTNAME} Cert for OCSP responder"
+  certu -V -n ${CERTNAME} -u O -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1
+  CU_ACTION="Verify ${CERTNAME} Cert for Object Signer"
+  certu -V -n ${CERTNAME} -u J -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1
+
+  CERTNAME="Distrusted"
+  CU_ACTION="Verify ${CERTNAME} Cert for SSL Server"
+  certu -V -n ${CERTNAME} -u V -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1
+  CU_ACTION="Verify ${CERTNAME} Cert for SSL Client"
+  certu -V -n ${CERTNAME} -u C -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1
+  CU_ACTION="Verify ${CERTNAME} Cert for Email signer"
+  certu -V -n ${CERTNAME} -u S -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1
+  CU_ACTION="Verify ${CERTNAME} Cert for Email recipient"
+  certu -V -n ${CERTNAME} -u R -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1
+  CU_ACTION="Verify ${CERTNAME} Cert for OCSP responder"
+  certu -V -n ${CERTNAME} -u O -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1
+  CU_ACTION="Verify ${CERTNAME} Cert for Object Signer"
+  certu -V -n ${CERTNAME} -u J -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1
+  RETEXPECTED=0
+}
+
 ############################## cert_cleanup ############################
 # local shell function to finish this script (no exit since it might be
 # sourced)
 ########################################################################
 cert_cleanup()
 {
   cert_log "$SCRIPTNAME: finished $SCRIPTNAME"
   html "</TABLE><BR>" 
@@ -1414,16 +1487,17 @@ cert_init
 cert_all_CA
 cert_extended_ssl 
 cert_ssl 
 cert_smime_client        
 cert_fips
 cert_eccurves
 cert_extensions
 cert_test_password
+cert_test_distrust
 
 if [ -z "$NSS_TEST_DISABLE_CRL" ] ; then
     cert_crl_ssl
 else
     echo "$SCRIPTNAME: Skipping CRL Tests"
 fi
 
 if [ -n "$DO_DIST_ST" -a "$DO_DIST_ST" = "TRUE" ] ; then
--- a/security/nss/tests/common/init.sh
+++ b/security/nss/tests/common/init.sh
@@ -90,16 +90,17 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOU
         CLIENTDIR=${HOSTDIR}/client
         ALICEDIR=${HOSTDIR}/alicedir
         BOBDIR=${HOSTDIR}/bobdir
         DAVEDIR=${HOSTDIR}/dave
         EVEDIR=${HOSTDIR}/eve
         FIPSDIR=${HOSTDIR}/fips
         DBPASSDIR=${HOSTDIR}/dbpass
         ECCURVES_DIR=${HOSTDIR}/eccurves
+        DISTRUSTDIR=${HOSTDIR}/distrust
 
         SERVER_CADIR=${HOSTDIR}/serverCA
         CLIENT_CADIR=${HOSTDIR}/clientCA
         EXT_SERVERDIR=${HOSTDIR}/ext_server
         EXT_CLIENTDIR=${HOSTDIR}/ext_client
 
         IOPR_CADIR=${HOSTDIR}/CA_iopr
         IOPR_SSL_SERVERDIR=${HOSTDIR}/server_ssl_iopr
@@ -521,16 +522,17 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOU
     D_SERVER="Server.$version"
     D_CLIENT="Client.$version"
     D_FIPS="FIPS.$version"
     D_DBPASS="DBPASS.$version"
     D_ECCURVES="ECCURVES.$version"
     D_EXT_SERVER="ExtendedServer.$version"
     D_EXT_CLIENT="ExtendedClient.$version"
     D_CERT_EXTENSTIONS="CertExtensions.$version"
+    D_DISTRUST="Distrust.$version"
 
     # we need relative pathnames of these files abd directories, since our 
     # tools can't handle the unix style absolut pathnames on cygnus
 
     R_CADIR=../CA
     R_SERVERDIR=../server
     R_CLIENTDIR=../client
     R_IOPR_CADIR=../CA_iopr
--- a/security/nss/tests/memleak/ignored
+++ b/security/nss/tests/memleak/ignored
@@ -80,8 +80,11 @@
 vfychain/main/PL_CreateOptState/**
 
 #486298
 selfserv/main/PORT_Strdup_Util**
 
 #497251
 **/FREEBL_InitStubs/dlopen@@GLIBC_2.1/**
 
+#679524
+**/nss_Init/PR_CallOnce/nss_doLockInit/**
+
--- a/security/nss/tests/ssl/sslcov.txt
+++ b/security/nss/tests/ssl/sslcov.txt
@@ -43,24 +43,21 @@
 #
   noECC  noTLS   A    SSL2_RC4_128_WITH_MD5
   noECC   TLS    B    SSL2_RC4_128_EXPORT40_WITH_MD5
   noECC   TLS    C    SSL2_RC2_128_CBC_WITH_MD5
   noECC  noTLS   D    SSL2_RC2_128_CBC_EXPORT40_WITH_MD5
   noECC   TLS    E    SSL2_DES_64_CBC_WITH_MD5
   noECC  noTLS   F    SSL2_DES_192_EDE3_CBC_WITH_MD5
 #
-# noECC  noTLS   a    SSL3_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA
-# noECC  noTLS   b    SSL3_FORTEZZA_DMS_WITH_RC4_128_SHA
   noECC  noTLS   c    SSL3_RSA_WITH_RC4_128_MD5
   noECC  noTLS   d    SSL3_RSA_WITH_3DES_EDE_CBC_SHA
   noECC  noTLS   e    SSL3_RSA_WITH_DES_CBC_SHA
   noECC  noTLS   f    SSL3_RSA_EXPORT_WITH_RC4_40_MD5
   noECC  noTLS   g    SSL3_RSA_EXPORT_WITH_RC2_CBC_40_MD5
-# noECC  noTLS   h    SSL3_FORTEZZA_DMS_WITH_NULL_SHA
   noECC  noTLS   i    SSL3_RSA_WITH_NULL_MD5
   noECC  noTLS   j    SSL3_RSA_FIPS_WITH_3DES_EDE_CBC_SHA
   noECC  noTLS   k    SSL3_RSA_FIPS_WITH_DES_CBC_SHA
   noECC  noTLS   l    SSL3_RSA_EXPORT_WITH_DES_CBC_SHA   (new)
   noECC  noTLS   m    SSL3_RSA_EXPORT_WITH_RC4_56_SHA    (new)
   noECC  noTLS   n    SSL3_RSA_WITH_RC4_128_SHA
   noECC  noTLS   v    SSL3_RSA_WITH_AES_128_CBC_SHA
   noECC  noTLS   y    SSL3_RSA_WITH_AES_256_CBC_SHA