fixup commit for branch 'CAMINO_1_0_BRANCH' CAMINO_1_0_BRANCH FIREFOX_1_5_0_1_RELEASE FIREFOX_1_5_0_1rc1_RELEASE MOZILLA_1_8_0_1_RELEASE MOZILLA_1_8_0_1rc1_RELEASE SEAMONKEY_1_0_RELEASE XULRUNNER_1_8_0_1_RELEASE
authorcvs2hg
Thu, 05 Jan 2006 15:40:19 +0000
branchCAMINO_1_0_BRANCH
changeset 6440 8e23ef81677b8168c4f1117fe6bc2820cf70d1e3
parent 5634 7c3cc2b95cd4bb5530b6744c36917af1c226dec0
child 6538 45a1e786f75256a793c5860ee1e22fbbd3261c38
push idunknown
push userunknown
push dateunknown
fixup commit for branch 'CAMINO_1_0_BRANCH'
security/coreconf/Darwin.mk
security/coreconf/OS2.mk
security/coreconf/arch.mk
security/dbm/Makefile
security/dbm/config/config.mk
security/dbm/include/Makefile
security/dbm/include/manifest.mn
security/dbm/manifest.mn
security/dbm/src/Makefile
security/dbm/src/config.mk
security/dbm/src/dirent.c
security/dbm/src/dirent.h
security/dbm/src/manifest.mn
security/dbm/tests/Makefile
security/nss/cmd/bltest/blapitest.c
security/nss/cmd/certutil/certutil.c
security/nss/cmd/crlutil/crlgen.c
security/nss/cmd/rsaperf/rsaperf.c
security/nss/cmd/strsclnt/strsclnt.c
security/nss/cmd/zlib/README
security/nss/cmd/zlib/adler32.c
security/nss/cmd/zlib/compress.c
security/nss/cmd/zlib/crc32.c
security/nss/cmd/zlib/deflate.c
security/nss/cmd/zlib/deflate.h
security/nss/cmd/zlib/example.c
security/nss/cmd/zlib/gzio.c
security/nss/cmd/zlib/infback.c
security/nss/cmd/zlib/inffast.c
security/nss/cmd/zlib/inflate.c
security/nss/cmd/zlib/inflate.h
security/nss/cmd/zlib/inftrees.c
security/nss/cmd/zlib/inftrees.h
security/nss/cmd/zlib/minigzip.c
security/nss/cmd/zlib/trees.c
security/nss/cmd/zlib/zconf.h
security/nss/cmd/zlib/zlib.h
security/nss/cmd/zlib/zutil.c
security/nss/cmd/zlib/zutil.h
security/nss/lib/certhigh/certvfy.c
security/nss/lib/cryptohi/secsign.c
security/nss/lib/cryptohi/secvfy.c
security/nss/lib/dev/devslot.c
security/nss/lib/freebl/dsa.c
security/nss/lib/freebl/loader.c
security/nss/lib/freebl/rsa.c
security/nss/lib/freebl/unix_rand.c
security/nss/lib/nss/nss.def
security/nss/lib/nss/nss.h
security/nss/lib/pk11wrap/pk11akey.c
security/nss/lib/pk11wrap/pk11auth.c
security/nss/lib/pk11wrap/pk11load.c
security/nss/lib/pk11wrap/pk11nobj.c
security/nss/lib/pk11wrap/pk11obj.c
security/nss/lib/pk11wrap/pk11pub.h
security/nss/lib/pk11wrap/pk11skey.c
security/nss/lib/pk11wrap/pk11util.c
security/nss/lib/pk11wrap/secmodi.h
security/nss/lib/pk11wrap/secmodt.h
security/nss/lib/pki/pkistore.c
security/nss/lib/pki/tdcache.c
security/nss/lib/smime/cmslocal.h
security/nss/lib/smime/cmssigdata.c
security/nss/lib/smime/cmst.h
security/nss/lib/softoken/pkcs11.c
security/nss/lib/util/secasn1e.c
security/nss/lib/util/secport.h
security/nss/tests/cipher/cipher.sh
security/nss/tests/cipher/performance.sh
security/nss/tests/common/cleanup.sh
--- a/security/coreconf/Darwin.mk
+++ b/security/coreconf/Darwin.mk
@@ -46,35 +46,71 @@ RANLIB		= ranlib
 ifeq (86,$(findstring 86,$(OS_TEST)))
 OS_REL_CFLAGS	= -Di386
 CPU_ARCH	= i386
 else
 OS_REL_CFLAGS	= -Dppc
 CPU_ARCH	= ppc
 endif
 
+ifneq (,$(MACOS_SDK_DIR))
+    GCC_VERSION_FULL := $(shell $(CC) -v 2>&1 | grep "gcc version" | sed -e "s/^.*gcc version[  ]*//" | awk '{ print $$1 }')
+    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)))
+        # GCC <= 3
+	DARWIN_SDK_FRAMEWORKS = -F$(MACOS_SDK_DIR)/System/Library/Frameworks
+        ifneq (,$(shell find $(MACOS_SDK_DIR)/Library/Frameworks -maxdepth 0))
+            DARWIN_SDK_FRAMEWORKS += -F$(MACOS_SDK_DIR)/Library/Frameworks
+        endif
+        DARWIN_SDK_CFLAGS = -nostdinc -isystem $(MACOS_SDK_DIR)/usr/include/gcc/darwin/$(GCC_VERSION) -isystem $(MACOS_SDK_DIR)/usr/include $(DARWIN_SDK_FRAMEWORKS)
+        DARWIN_SDK_LDFLAGS = -L$(MACOS_SDK_DIR)/usr/lib/gcc/darwin -L$(MACOS_SDK_DIR)/usr/lib/gcc/darwin/$(GCC_VERSION_FULL) -L$(MACOS_SDK_DIR)/usr/lib
+        DARWIN_SDK_DSOFLAGS = $(DARWIN_SDK_LDFLAGS) $(DARWIN_SDK_FRAMEWORKS)
+        NEXT_ROOT = $(MACOS_SDK_DIR)
+        export NEXT_ROOT
+    else
+        # GCC >= 4
+        DARWIN_SDK_CFLAGS = -isysroot $(MACOS_SDK_DIR)
+        ifneq (4.0.0,$(GCC_VERSION_FULL))
+            # gcc > 4.0.0 passes -syslibroot to ld based on -isysroot.
+            # Don't add -isysroot to DARWIN_SDK_LDFLAGS, because the programs
+            # that are linked with those flags also get DARWIN_SDK_CFLAGS.
+            DARWIN_SDK_DSOFLAGS = -isysroot $(MACOS_SDK_DIR)
+        else
+            # gcc 4.0.0 doesn't pass -syslibroot to ld, it needs to be
+            # explicit.
+            DARWIN_SDK_LDFLAGS = -Wl,-syslibroot,$(MACOS_SDK_DIR)
+            DARWIN_SDK_DSOFLAGS = $(DARWIN_SDK_LDFLAGS)
+        endif
+    endif
+
+    LDFLAGS += $(DARWIN_SDK_LDFLAGS)
+endif
+
 # "Commons" are tentative definitions in a global scope, like this:
 #     int x;
 # The meaning of a common is ambiguous.  It may be a true definition:
 #     int x = 0;
 # or it may be a declaration of a symbol defined in another file:
 #     extern int x;
 # Use the -fno-common option to force all commons to become true
 # definitions so that the linker can catch multiply-defined symbols.
 # Also, common symbols are not allowed with Darwin dynamic libraries.
 
-OS_CFLAGS	= $(DSO_CFLAGS) $(OS_REL_CFLAGS) -Wmost -fpascal-strings -no-cpp-precomp -fno-common -pipe -DDARWIN -DHAVE_STRERROR -DHAVE_BSD_FLOCK
+OS_CFLAGS	= $(DSO_CFLAGS) $(OS_REL_CFLAGS) -Wmost -fpascal-strings -no-cpp-precomp -fno-common -pipe -DDARWIN -DHAVE_STRERROR -DHAVE_BSD_FLOCK $(DARWIN_SDK_CFLAGS)
 
 ifdef BUILD_OPT
 OPTIMIZER	= -O2
 endif
 
 ARCH		= darwin
 
 # May override this with -bundle to create a loadable module.
-DSO_LDOPTS	= -dynamiclib -compatibility_version 1 -current_version 1 -install_name @executable_path/$(notdir $@) -headerpad_max_install_names
+DSO_LDOPTS	= -dynamiclib -compatibility_version 1 -current_version 1 -install_name @executable_path/$(notdir $@) -headerpad_max_install_names $(DARWIN_SDK_DSOFLAGS)
 
 MKSHLIB		= $(CC) -arch $(CPU_ARCH) $(DSO_LDOPTS)
 DLL_SUFFIX	= dylib
 PROCESS_MAP_FILE = grep -v ';+' $(LIBRARY_NAME).def | grep -v ';-' | \
                 sed -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,,' -e 's,^,_,' > $@
 
 G++INCLUDES	= -I/usr/include/g++
--- a/security/coreconf/OS2.mk
+++ b/security/coreconf/OS2.mk
@@ -84,17 +84,17 @@ ifndef NO_SHARED_LIB
 WRAP_MALLOC_LIB         = 
 WRAP_MALLOC_CFLAGS      = 
 DSO_CFLAGS              = 
 DSO_PIC_CFLAGS          = 
 MKSHLIB                 = $(CXX) $(CXXFLAGS) $(DSO_LDOPTS) -o $@
 MKCSHLIB                = $(CC) $(CFLAGS) $(DSO_LDOPTS) -o $@
 MKSHLIB_FORCE_ALL       = 
 MKSHLIB_UNFORCE_ALL     = 
-DSO_LDOPTS              = -Zomf -Zdll
+DSO_LDOPTS              = -Zomf -Zdll -Zmap
 SHLIB_LDSTARTFILE	= 
 SHLIB_LDENDFILE		= 
 ifdef MAPFILE
 MKSHLIB += $(MAPFILE)
 endif
 PROCESS_MAP_FILE = \
 	echo LIBRARY $(LIBRARY_NAME)$(LIBRARY_VERSION) INITINSTANCE TERMINSTANCE > $@; \
 	echo PROTMODE >> $@; \
--- a/security/coreconf/arch.mk
+++ b/security/coreconf/arch.mk
@@ -205,16 +205,20 @@ endif
 ifeq ($(OS_ARCH),CYGWIN_95-4.0)
 	OS_ARCH   = CYGWIN_NT-4.0
 	OS_TARGET = WIN95
 endif
 ifeq ($(OS_ARCH),CYGWIN_98-4.10)
 	OS_ARCH   = CYGWIN_NT-4.0
 	OS_TARGET = WIN95
 endif
+ifeq ($(OS_ARCH),CYGWIN_ME-4.90)
+	OS_ARCH   = CYGWIN_NT-4.0
+	OS_TARGET = WIN95
+endif
 
 #
 # On WIN32, we also define the variable CPU_ARCH, if it isn't already.
 #
 ifndef CPU_ARCH
     ifeq ($(OS_ARCH), WINNT)
 	CPU_ARCH := $(shell uname -p)
 	ifeq ($(CPU_ARCH),I386)
deleted file mode 100644
--- a/security/dbm/Makefile
+++ /dev/null
@@ -1,80 +0,0 @@
-#! gmake
-#
-# The contents of this file are subject to the Mozilla Public
-# License Version 1.1 (the "License"); you may not use this file
-# except in compliance with the License. You may obtain a copy of
-# the License at http://www.mozilla.org/MPL/
-# 
-# Software distributed under the License is distributed on an "AS
-# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# rights and limitations under the License.
-# 
-# The Original Code is the Netscape security libraries.
-# 
-# The Initial Developer of the Original Code is Netscape
-# Communications Corporation.  Portions created by Netscape are 
-# Copyright (C) 1994-2000 Netscape Communications Corporation.  All
-# Rights Reserved.
-# 
-# Contributor(s):
-# 
-# Alternatively, the contents of this file may be used under the
-# terms of the GNU General Public License Version 2 or later (the
-# "GPL"), in which case the provisions of the GPL are applicable 
-# instead of those above.  If you wish to allow use of your 
-# version of this file only under the terms of the GPL and not to
-# allow others to use your version of this file under the MPL,
-# indicate your decision by deleting the provisions above and
-# replace them with the notice and other provisions required by
-# the GPL.  If you do not delete the provisions above, a recipient
-# may use your version of this file under either the MPL or the
-# GPL.
-#
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY).   #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL)          #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL)       #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL).      #
-#######################################################################
-
-
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL)                              #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL)                           #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL).                              #
-#######################################################################
-
-coreconf_hack:
-	cd ../coreconf; gmake
-	gmake import
-
-RelEng_bld: coreconf_hack
-	gmake
deleted file mode 100644
--- a/security/dbm/config/config.mk
+++ /dev/null
@@ -1,67 +0,0 @@
-#! gmake
-#
-# The contents of this file are subject to the Mozilla Public
-# License Version 1.1 (the "License"); you may not use this file
-# except in compliance with the License. You may obtain a copy of
-# the License at http://www.mozilla.org/MPL/
-# 
-# Software distributed under the License is distributed on an "AS
-# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# rights and limitations under the License.
-# 
-# The Original Code is the Netscape security libraries.
-# 
-# The Initial Developer of the Original Code is Netscape
-# Communications Corporation.  Portions created by Netscape are 
-# Copyright (C) 1994-2000 Netscape Communications Corporation.  All
-# Rights Reserved.
-# 
-# Contributor(s):
-# 
-# Alternatively, the contents of this file may be used under the
-# terms of the GNU General Public License Version 2 or later (the
-# "GPL"), in which case the provisions of the GPL are applicable 
-# instead of those above.  If you wish to allow use of your 
-# version of this file only under the terms of the GPL and not to
-# allow others to use your version of this file under the MPL,
-# indicate your decision by deleting the provisions above and
-# replace them with the notice and other provisions required by
-# the GPL.  If you do not delete the provisions above, a recipient
-# may use your version of this file under either the MPL or the
-# GPL.
-#
-
-#
-# These macros are defined by mozilla's configure script.
-# We define them manually here.
-#
-
-DEFINES += -DSTDC_HEADERS -DHAVE_STRERROR
-
-#
-# Most platforms have snprintf, so it's simpler to list the exceptions.
-#
-HAVE_SNPRINTF = 1
-#
-# OSF1 V4.0D doesn't have snprintf but V5.0A does.
-#
-ifeq ($(OS_TARGET)$(OS_RELEASE),OSF1V4.0D)
-HAVE_SNPRINTF =
-endif
-ifdef HAVE_SNPRINTF
-DEFINES += -DHAVE_SNPRINTF
-endif
-
-ifeq (,$(filter-out IRIX Linux,$(OS_TARGET)))
-DEFINES += -DHAVE_SYS_CDEFS_H
-endif
-
-ifeq (,$(filter-out DGUX NCR ReliantUNIX SCO_SV SCOOS UNIXWARE,$(OS_TARGET)))
-DEFINES += -DHAVE_SYS_BYTEORDER_H
-endif
-
-#
-# None of the platforms that we are interested in need to
-# define HAVE_MEMORY_H.
-#
deleted file mode 100644
--- a/security/dbm/include/Makefile
+++ /dev/null
@@ -1,76 +0,0 @@
-#! gmake
-#
-# The contents of this file are subject to the Mozilla Public
-# License Version 1.1 (the "License"); you may not use this file
-# except in compliance with the License. You may obtain a copy of
-# the License at http://www.mozilla.org/MPL/
-# 
-# Software distributed under the License is distributed on an "AS
-# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# rights and limitations under the License.
-# 
-# The Original Code is the Netscape security libraries.
-# 
-# The Initial Developer of the Original Code is Netscape
-# Communications Corporation.  Portions created by Netscape are 
-# Copyright (C) 1994-2000 Netscape Communications Corporation.  All
-# Rights Reserved.
-# 
-# Contributor(s):
-# 
-# Alternatively, the contents of this file may be used under the
-# terms of the GNU General Public License Version 2 or later (the
-# "GPL"), in which case the provisions of the GPL are applicable 
-# instead of those above.  If you wish to allow use of your 
-# version of this file only under the terms of the GPL and not to
-# allow others to use your version of this file under the MPL,
-# indicate your decision by deleting the provisions above and
-# replace them with the notice and other provisions required by
-# the GPL.  If you do not delete the provisions above, a recipient
-# may use your version of this file under either the MPL or the
-# GPL.
-#
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY).   #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL)          #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL)       #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL).      #
-#######################################################################
-
-
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL)                              #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL)                           #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL).                              #
-#######################################################################
-
-
-
deleted file mode 100644
--- a/security/dbm/include/manifest.mn
+++ /dev/null
@@ -1,57 +0,0 @@
-#! gmake
-#
-# The contents of this file are subject to the Mozilla Public
-# License Version 1.1 (the "License"); you may not use this file
-# except in compliance with the License. You may obtain a copy of
-# the License at http://www.mozilla.org/MPL/
-# 
-# Software distributed under the License is distributed on an "AS
-# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# rights and limitations under the License.
-# 
-# The Original Code is the Netscape security libraries.
-# 
-# The Initial Developer of the Original Code is Netscape
-# Communications Corporation.  Portions created by Netscape are 
-# Copyright (C) 1994-2000 Netscape Communications Corporation.  All
-# Rights Reserved.
-# 
-# Contributor(s):
-# 
-# Alternatively, the contents of this file may be used under the
-# terms of the GNU General Public License Version 2 or later (the
-# "GPL"), in which case the provisions of the GPL are applicable 
-# instead of those above.  If you wish to allow use of your 
-# version of this file only under the terms of the GPL and not to
-# allow others to use your version of this file under the MPL,
-# indicate your decision by deleting the provisions above and
-# replace them with the notice and other provisions required by
-# the GPL.  If you do not delete the provisions above, a recipient
-# may use your version of this file under either the MPL or the
-# GPL.
-#
-
-CORE_DEPTH = ../..
-
-VPATH  = $(CORE_DEPTH)/../dbm/include
-
-MODULE = dbm
-
-EXPORTS =	nsres.h   \
-		cdefs.h   \
-		mcom_db.h \
-		ncompat.h \
-		winfile.h \
-		$(NULL)
-
-PRIVATE_EXPORTS =	hsearch.h \
-			page.h    \
-			extern.h  \
-			ndbm.h    \
-			queue.h   \
-			hash.h    \
-			mpool.h   \
-			search.h  \
-			$(NULL)
-
deleted file mode 100644
--- a/security/dbm/manifest.mn
+++ /dev/null
@@ -1,45 +0,0 @@
-#! gmake
-#
-# The contents of this file are subject to the Mozilla Public
-# License Version 1.1 (the "License"); you may not use this file
-# except in compliance with the License. You may obtain a copy of
-# the License at http://www.mozilla.org/MPL/
-# 
-# Software distributed under the License is distributed on an "AS
-# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# rights and limitations under the License.
-# 
-# The Original Code is the Netscape security libraries.
-# 
-# The Initial Developer of the Original Code is Netscape
-# Communications Corporation.  Portions created by Netscape are 
-# Copyright (C) 1994-2000 Netscape Communications Corporation.  All
-# Rights Reserved.
-# 
-# Contributor(s):
-# 
-# Alternatively, the contents of this file may be used under the
-# terms of the GNU General Public License Version 2 or later (the
-# "GPL"), in which case the provisions of the GPL are applicable 
-# instead of those above.  If you wish to allow use of your 
-# version of this file only under the terms of the GPL and not to
-# allow others to use your version of this file under the MPL,
-# indicate your decision by deleting the provisions above and
-# replace them with the notice and other provisions required by
-# the GPL.  If you do not delete the provisions above, a recipient
-# may use your version of this file under either the MPL or the
-# GPL.
-#
-
-CORE_DEPTH = ..
-
-MODULE = dbm
-
-IMPORTS = nspr20/v4.4.1
-
-RELEASE = dbm
-
-DIRS =  include \
-        src     \
-	$(NULL)
deleted file mode 100644
--- a/security/dbm/src/Makefile
+++ /dev/null
@@ -1,76 +0,0 @@
-#! gmake
-#
-# The contents of this file are subject to the Mozilla Public
-# License Version 1.1 (the "License"); you may not use this file
-# except in compliance with the License. You may obtain a copy of
-# the License at http://www.mozilla.org/MPL/
-# 
-# Software distributed under the License is distributed on an "AS
-# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# rights and limitations under the License.
-# 
-# The Original Code is the Netscape security libraries.
-# 
-# The Initial Developer of the Original Code is Netscape
-# Communications Corporation.  Portions created by Netscape are 
-# Copyright (C) 1994-2000 Netscape Communications Corporation.  All
-# Rights Reserved.
-# 
-# Contributor(s):
-# 
-# Alternatively, the contents of this file may be used under the
-# terms of the GNU General Public License Version 2 or later (the
-# "GPL"), in which case the provisions of the GPL are applicable 
-# instead of those above.  If you wish to allow use of your 
-# version of this file only under the terms of the GPL and not to
-# allow others to use your version of this file under the MPL,
-# indicate your decision by deleting the provisions above and
-# replace them with the notice and other provisions required by
-# the GPL.  If you do not delete the provisions above, a recipient
-# may use your version of this file under either the MPL or the
-# GPL.
-#
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY).   #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL)          #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL)       #
-#######################################################################
-
-include $(CORE_DEPTH)/dbm/config/config.mk
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL).      #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL)                              #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL)                           #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL).                              #
-#######################################################################
-
-
-
deleted file mode 100644
--- a/security/dbm/src/config.mk
+++ /dev/null
@@ -1,63 +0,0 @@
-#! gmake
-#
-# The contents of this file are subject to the Mozilla Public
-# License Version 1.1 (the "License"); you may not use this file
-# except in compliance with the License. You may obtain a copy of
-# the License at http://www.mozilla.org/MPL/
-# 
-# Software distributed under the License is distributed on an "AS
-# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# rights and limitations under the License.
-# 
-# The Original Code is the Netscape security libraries.
-# 
-# The Initial Developer of the Original Code is Netscape
-# Communications Corporation.  Portions created by Netscape are 
-# Copyright (C) 1994-2000 Netscape Communications Corporation.  All
-# Rights Reserved.
-# 
-# Contributor(s):
-# 
-# Alternatively, the contents of this file may be used under the
-# terms of the GNU General Public License Version 2 or later (the
-# "GPL"), in which case the provisions of the GPL are applicable 
-# instead of those above.  If you wish to allow use of your 
-# version of this file only under the terms of the GPL and not to
-# allow others to use your version of this file under the MPL,
-# indicate your decision by deleting the provisions above and
-# replace them with the notice and other provisions required by
-# the GPL.  If you do not delete the provisions above, a recipient
-# may use your version of this file under either the MPL or the
-# GPL.
-#
-
-DEFINES += -DMEMMOVE -D__DBINTERFACE_PRIVATE $(SECURITY_FLAG)
-
-INCLUDES += -I$(CORE_DEPTH)/../dbm/include
-
-#
-#  Currently, override TARGETS variable so that only static libraries
-#  are specifed as dependencies within rules.mk.
-#
-
-TARGETS        = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PURE_LIBRARY   =
-PROGRAM        =
-
-ifdef SHARED_LIBRARY
-	ifeq (,$(filter-out WINNT WIN95 WINCE,$(OS_TARGET))) # list omits WIN16
-		DLLBASE=/BASE:0x30000000
-		RES=$(OBJDIR)/dbm.res
-		RESNAME=../include/dbm.rc
-	endif
-	ifeq ($(DLL_SUFFIX),dll)
-		DEFINES += -D_DLL
-	endif
-endif
-
-ifeq ($(OS_TARGET),AIX)
-	OS_LIBS += -lc_r
-endif
deleted file mode 100644
--- a/security/dbm/src/dirent.c
+++ /dev/null
@@ -1,348 +0,0 @@
-#ifdef OS2
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#include <dirent.h>
-#include <errno.h>
-
-/*#ifndef __EMX__ 
-#include <libx.h>
-#endif */
-
-#define INCL_DOSFILEMGR
-#define INCL_DOSERRORS
-#include <os2.h>
-
-#if OS2 >= 2
-# define FFBUF	FILEFINDBUF3
-# define Word	ULONG
-  /*
-   * LS20 recommends a request count of 100, but according to the
-   * APAR text it does not lead to missing files, just to funny
-   * numbers of returned entries.
-   *
-   * LS30 HPFS386 requires a count greater than 2, or some files
-   * are missing (those starting with a character less that '.').
-   *
-   * Novell looses entries which overflow the buffer. In previous
-   * versions of dirent2, this could have lead to missing files
-   * when the average length of 100 directory entries was 40 bytes
-   * or more (quite unlikely for files on a Novell server).
-   *
-   * Conclusion: Make sure that the entries all fit into the buffer
-   * and that the buffer is large enough for more than 2 entries
-   * (each entry is at most 300 bytes long). And ignore the LS20
-   * effect.
-   */
-# define Count	25
-# define BufSz	(25 * (sizeof(FILEFINDBUF3)+1))
-#else
-# define FFBUF	FILEFINDBUF
-# define Word	USHORT
-# define BufSz	1024
-# define Count	3
-#endif
-
-#if defined(__IBMC__) || defined(__IBMCPP__)
-  #define error(rc) _doserrno = rc, errno = EOS2ERR
-#elif defined(MICROSOFT)
-  #define error(rc) _doserrno = rc, errno = 255
-#else
-  #define error(rc) errno = 255
-#endif
-
-struct _dirdescr {
-	HDIR		handle;		/* DosFindFirst handle */
-	char		fstype;		/* filesystem type */
-	Word		count;		/* valid entries in <ffbuf> */
-	long		number;		/* absolute number of next entry */
-	int		index;		/* relative number of next entry */
-	FFBUF *		next;		/* pointer to next entry */
-	char		name[MAXPATHLEN+3]; /* directory name */
-	unsigned	attrmask;	/* attribute mask for seekdir */
-	struct dirent	entry;		/* buffer for directory entry */
-	BYTE		ffbuf[BufSz];
-};
-
-/*
- * Return first char of filesystem type, or 0 if unknown.
- */
-static char
-getFSType(const char *path)
-{
-	static char cache[1+26];
-	char drive[3], info[512];
-	Word unit, infolen;
-	char r;
-
-	if (isalpha(path[0]) && path[1] == ':') {
-		unit = toupper(path[0]) - '@';
-		path += 2;
-	} else {
-		ULONG driveMap;
-#if OS2 >= 2
-		if (DosQueryCurrentDisk(&unit, &driveMap))
-#else
-		if (DosQCurDisk(&unit, &driveMap))
-#endif
-			return 0;
-	}
-
-	if ((path[0] == '\\' || path[0] == '/')
-	 && (path[1] == '\\' || path[1] == '/'))
-		return 0;
-
-	if (cache [unit])
-		return cache [unit];
-
-	drive[0] = '@' + unit;
-	drive[1] = ':';
-	drive[2] = '\0';
-	infolen = sizeof info;
-#if OS2 >= 2
-	if (DosQueryFSAttach(drive, 0, FSAIL_QUERYNAME, (PVOID)info, &infolen))
-		return 0;
-	if (infolen >= sizeof(FSQBUFFER2)) {
-		FSQBUFFER2 *p = (FSQBUFFER2 *)info;
-		r = p->szFSDName[p->cbName];
-	} else
-#else
-	if (DosQFSAttach((PSZ)drive, 0, FSAIL_QUERYNAME, (PVOID)info, &infolen, 0))
-		return 0;
-	if (infolen >= 9) {
-		char *p = info + sizeof(USHORT);
-		p += sizeof(USHORT) + *(USHORT *)p + 1 + sizeof(USHORT);
-		r = *p;
-	} else
-#endif
-		r = 0;
-	return cache [unit] = r;
-}
-
-char *
-abs_path(const char *name, char *buffer, int len)
-{
-	char buf[4];
-	if (isalpha(name[0]) && name[1] == ':' && name[2] == '\0') {
-		buf[0] = name[0];
-		buf[1] = name[1];
-		buf[2] = '.';
-		buf[3] = '\0';
-		name = buf;
-	}
-#if OS2 >= 2
-	if (DosQueryPathInfo((PSZ)name, FIL_QUERYFULLNAME, buffer, len))
-#else
-	if (DosQPathInfo((PSZ)name, FIL_QUERYFULLNAME, (PBYTE)buffer, len, 0L))
-#endif
-		return NULL;
-	return buffer;
-}
-
-DIR *
-openxdir(const char *path, unsigned att_mask)
-{
-	DIR *dir;
-	char name[MAXPATHLEN+3];
-	Word rc;
-
-	dir = malloc(sizeof(DIR));
-	if (dir == NULL) {
-		errno = ENOMEM;
-		return NULL;
-	}
-
-	strncpy(name, path, MAXPATHLEN);
-	name[MAXPATHLEN] = '\0';
-	switch (name[strlen(name)-1]) {
-	default:
-		strcat(name, "\\");
-	case '\\':
-	case '/':
-	case ':':
-		;
-	}
-	strcat(name, ".");
-	if (!abs_path(name, dir->name, MAXPATHLEN+1))
-		strcpy(dir->name, name);
-	if (dir->name[strlen(dir->name)-1] == '\\')
-		strcat(dir->name, "*");
-	else
-		strcat(dir->name, "\\*");
-
-	dir->fstype = getFSType(dir->name);
-	dir->attrmask = att_mask | A_DIR;
-
-	dir->handle = HDIR_CREATE;
-	dir->count = 100;
-#if OS2 >= 2
-	rc = DosFindFirst(dir->name, &dir->handle, dir->attrmask,
-		dir->ffbuf, sizeof dir->ffbuf, &dir->count, FIL_STANDARD);
-#else
-	rc = DosFindFirst((PSZ)dir->name, &dir->handle, dir->attrmask,
-		(PFILEFINDBUF)dir->ffbuf, sizeof dir->ffbuf, &dir->count, 0);
-#endif
-	switch (rc) {
-	default:
-		free(dir);
-		error(rc);
-		return NULL;
-	case NO_ERROR:
-	case ERROR_NO_MORE_FILES:
-		;
-	}
-
-	dir->number = 0;
-	dir->index = 0;
-	dir->next = (FFBUF *)dir->ffbuf;
-
-	return (DIR *)dir;
-}
-
-DIR *
-opendir(const char *pathname)
-{
-	return openxdir(pathname, 0);
-}
-
-struct dirent *
-readdir(DIR *dir)
-{
-	static int dummy_ino = 2;
-
-	if (dir->index == dir->count) {
-		Word rc;
-		dir->count = 100;
-#if OS2 >= 2
-		rc = DosFindNext(dir->handle, dir->ffbuf,
-			sizeof dir->ffbuf, &dir->count);
-#else
-		rc = DosFindNext(dir->handle, (PFILEFINDBUF)dir->ffbuf,
-			sizeof dir->ffbuf, &dir->count);
-#endif
-		if (rc) {
-			error(rc);
-			return NULL;
-		}
-
-		dir->index = 0;
-		dir->next = (FFBUF *)dir->ffbuf;
-	}
-
-	if (dir->index == dir->count)
-		return NULL;
-
-	memcpy(dir->entry.d_name, dir->next->achName, dir->next->cchName);
-	dir->entry.d_name[dir->next->cchName] = '\0';
-	dir->entry.d_ino = dummy_ino++;
-	dir->entry.d_reclen = dir->next->cchName;
-	dir->entry.d_namlen = dir->next->cchName;
-	dir->entry.d_size = dir->next->cbFile;
-	dir->entry.d_attribute = dir->next->attrFile;
-	dir->entry.d_time = *(USHORT *)&dir->next->ftimeLastWrite;
-	dir->entry.d_date = *(USHORT *)&dir->next->fdateLastWrite;
-
-	switch (dir->fstype) {
-	case 'F': /* FAT */
-	case 'C': /* CDFS */
-		if (dir->next->attrFile & FILE_DIRECTORY)
-			strupr(dir->entry.d_name);
-		else
-			strlwr(dir->entry.d_name);
-	}
-
-#if OS2 >= 2
-	dir->next = (FFBUF *)((BYTE *)dir->next + dir->next->oNextEntryOffset);
-#else
-	dir->next = (FFBUF *)((BYTE *)dir->next->achName + dir->next->cchName + 1);
-#endif
-	++dir->number;
-	++dir->index;
-
-	return &dir->entry;
-}
-
-long
-telldir(DIR *dir)
-{
-	return dir->number;
-}
-
-void
-seekdir(DIR *dir, long off)
-{
-	if (dir->number > off) {
-		char name[MAXPATHLEN+2];
-		Word rc;
-
-		DosFindClose(dir->handle);
-
-		strcpy(name, dir->name);
-		strcat(name, "*");
-
-		dir->handle = HDIR_CREATE;
-		dir->count = 32767;
-#if OS2 >= 2
-		rc = DosFindFirst(name, &dir->handle, dir->attrmask,
-			dir->ffbuf, sizeof dir->ffbuf, &dir->count, FIL_STANDARD);
-#else
-		rc = DosFindFirst((PSZ)name, &dir->handle, dir->attrmask,
-			(PFILEFINDBUF)dir->ffbuf, sizeof dir->ffbuf, &dir->count, 0);
-#endif
-		switch (rc) {
-		default:
-			error(rc);
-			return;
-		case NO_ERROR:
-		case ERROR_NO_MORE_FILES:
-			;
-		}
-
-		dir->number = 0;
-		dir->index = 0;
-		dir->next = (FFBUF *)dir->ffbuf;
-	}
-
-	while (dir->number < off && readdir(dir))
-		;
-}
-
-void
-closedir(DIR *dir)
-{
-	DosFindClose(dir->handle);
-	free(dir);
-}
-
-/*****************************************************************************/
-
-#ifdef TEST
-
-main(int argc, char **argv)
-{
-	int i;
-	DIR *dir;
-	struct dirent *ep;
-
-	for (i = 1; i < argc; ++i) {
-		dir = opendir(argv[i]);
-		if (!dir)
-			continue;
-		while (ep = readdir(dir))
-			if (strchr("\\/:", argv[i] [strlen(argv[i]) - 1]))
-				printf("%s%s\n", argv[i], ep->d_name);
-			else
-				printf("%s/%s\n", argv[i], ep->d_name);
-		closedir(dir);
-	}
-
-	return 0;
-}
-
-#endif
-
-#endif /* OS2 */
-
deleted file mode 100644
--- a/security/dbm/src/dirent.h
+++ /dev/null
@@ -1,97 +0,0 @@
-#ifndef __DIRENT_H__
-#define __DIRENT_H__
-/*
- * @(#)msd_dir.h 1.4 87/11/06   Public Domain.
- *
- *  A public domain implementation of BSD directory routines for
- *  MS-DOS.  Written by Michael Rendell ({uunet,utai}michael@garfield),
- *  August 1897
- *
- *  Extended by Peter Lim (lim@mullian.oz) to overcome some MS DOS quirks
- *  and returns 2 more pieces of information - file size & attribute.
- *  Plus a little reshuffling of some #define's positions    December 1987
- *
- *  Some modifications by Martin Junius                      02-14-89
- *
- *	AK900712
- *	AK910410	abs_path - make absolute path
- *
- */
-
-#ifdef __EMX__
-#include <sys/param.h>
-#else
-#if defined(__IBMC__) || defined(__IBMCPP__) || defined(XP_W32_MSVC)
-#include <stdio.h>
-#ifdef MAXPATHLEN
-	#undef MAXPATHLEN
-#endif
-#define MAXPATHLEN (FILENAME_MAX*4)
-#define MAXNAMLEN FILENAME_MAX
-
-#else
-#include <param.h>
-#endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* attribute stuff */
-#ifndef A_RONLY
-# define A_RONLY   0x01
-# define A_HIDDEN  0x02
-# define A_SYSTEM  0x04
-# define A_LABEL   0x08
-# define A_DIR     0x10
-# define A_ARCHIVE 0x20
-#endif
-
-struct dirent {
-#if defined(OS2) || defined(WIN32)        /* use the layout of EMX to avoid trouble */
-    int            d_ino;                 /* Dummy */
-    int            d_reclen;		  /* Dummy, same as d_namlen */
-    int            d_namlen;              /* length of name */
-    char           d_name[MAXNAMLEN + 1];
-    unsigned long  d_size;
-    unsigned short d_attribute;           /* attributes (see above) */
-    unsigned short d_time;                /* modification time */
-    unsigned short d_date;                /* modification date */
-#else
-    char	   d_name[MAXNAMLEN + 1]; /* garentee null termination */
-    char	   d_attribute;		  /* .. extension .. */
-    unsigned long  d_size;		  /* .. extension .. */
-#endif
-};
-
-typedef struct _dirdescr DIR;
-/* the structs do not have to be defined here */
-
-extern DIR		*opendir(const char *);
-extern DIR		*openxdir(const char *, unsigned);
-extern struct dirent	*readdir(DIR *);
-extern void		seekdir(DIR *, long);
-extern long		telldir(DIR *);
-extern void 		closedir(DIR *);
-#define			rewinddir(dirp) seekdir(dirp, 0L)
-
-extern char *		abs_path(const char *name, char *buffer, int len);
-
-#ifndef S_IFMT
-#define S_IFMT ( S_IFDIR | S_IFREG )
-#endif
-
-#ifndef S_ISDIR
-#define S_ISDIR( m )                    (((m) & S_IFMT) == S_IFDIR)
-#endif
-
-#ifndef S_ISREG
-#define S_ISREG( m )                    (((m) & S_IFMT) == S_IFREG)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
deleted file mode 100644
--- a/security/dbm/src/manifest.mn
+++ /dev/null
@@ -1,61 +0,0 @@
-#! gmake
-#
-# The contents of this file are subject to the Mozilla Public
-# License Version 1.1 (the "License"); you may not use this file
-# except in compliance with the License. You may obtain a copy of
-# the License at http://www.mozilla.org/MPL/
-# 
-# Software distributed under the License is distributed on an "AS
-# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# rights and limitations under the License.
-# 
-# The Original Code is the Netscape security libraries.
-# 
-# The Initial Developer of the Original Code is Netscape
-# Communications Corporation.  Portions created by Netscape are 
-# Copyright (C) 1994-2000 Netscape Communications Corporation.  All
-# Rights Reserved.
-# 
-# Contributor(s):
-# 
-# Alternatively, the contents of this file may be used under the
-# terms of the GNU General Public License Version 2 or later (the
-# "GPL"), in which case the provisions of the GPL are applicable 
-# instead of those above.  If you wish to allow use of your 
-# version of this file only under the terms of the GPL and not to
-# allow others to use your version of this file under the MPL,
-# indicate your decision by deleting the provisions above and
-# replace them with the notice and other provisions required by
-# the GPL.  If you do not delete the provisions above, a recipient
-# may use your version of this file under either the MPL or the
-# GPL.
-#
-
-CORE_DEPTH = ../..
-
-VPATH  = $(CORE_DEPTH)/../dbm/src
-
-MODULE = dbm
-
-#
-# memmove.c, snprintf.c, and strerror.c are not in CSRCS because
-# the Standard C Library has memmove and strerror and DBM is not
-# using snprintf.
-#
-
-CSRCS = db.c	   \
-	h_bigkey.c \
-	h_func.c   \
-	h_log2.c   \
-	h_page.c   \
-	hash.c	   \
-	hash_buf.c \
-	hsearch.c  \
-	mktemp.c   \
-	ndbm.c	   \
-	nsres.c	   \
-	dirent.c	   \
-	$(NULL)
-
-LIBRARY_NAME = dbm
deleted file mode 100644
--- a/security/dbm/tests/Makefile
+++ /dev/null
@@ -1,69 +0,0 @@
-#! gmake
-#
-# The contents of this file are subject to the Mozilla Public
-# License Version 1.1 (the "License"); you may not use this file
-# except in compliance with the License. You may obtain a copy of
-# the License at http://www.mozilla.org/MPL/
-# 
-# Software distributed under the License is distributed on an "AS
-# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# rights and limitations under the License.
-# 
-# The Original Code is the Netscape security libraries.
-# 
-# The Initial Developer of the Original Code is Netscape
-# Communications Corporation.  Portions created by Netscape are 
-# Copyright (C) 1994-2000 Netscape Communications Corporation.  All
-# Rights Reserved.
-# 
-# Contributor(s):
-# 
-# Alternatively, the contents of this file may be used under the
-# terms of the GNU General Public License Version 2 or later (the
-# "GPL"), in which case the provisions of the GPL are applicable 
-# instead of those above.  If you wish to allow use of your 
-# version of this file only under the terms of the GPL and not to
-# allow others to use your version of this file under the MPL,
-# indicate your decision by deleting the provisions above and
-# replace them with the notice and other provisions required by
-# the GPL.  If you do not delete the provisions above, a recipient
-# may use your version of this file under either the MPL or the
-# GPL.
-#
-DEPTH		= ../..
-CORE_DEPTH	= ../..
-
-VPATH		= $(CORE_DEPTH)/../dbm/tests
-
-MODULE		= dbm
-
-CSRCS		= lots.c
-
-PROGRAM		= lots
-
-include $(DEPTH)/coreconf/config.mk
-
-include $(DEPTH)/dbm/config/config.mk
-
-ifeq (,$(filter-out WIN%,$(OS_TARGET))) 
-LIBDBM		= ../src/$(PLATFORM)/dbm$(STATIC_LIB_SUFFIX)
-else
-LIBDBM		= ../src/$(PLATFORM)/libdbm$(STATIC_LIB_SUFFIX)
-endif
-
-INCLUDES	+= -I$(CORE_DEPTH)/../dbm/include
-
-LDFLAGS		= $(LDOPTS) $(LIBDBM)
-
-include $(DEPTH)/coreconf/rules.mk
-
-lots.pure: lots
-	purify $(CC) -o lots.pure $(CFLAGS) $(OBJS) $(MYLIBS)
-
-crash: crash.o $(MYLIBS)
-	$(CC) -o crash $(CFLAGS) $^
-
-crash.pure: crash.o $(MYLIBS)
-	purify $(CC) -o crash.pure $(CFLAGS) $^
-
--- a/security/nss/cmd/bltest/blapitest.c
+++ b/security/nss/cmd/bltest/blapitest.c
@@ -44,16 +44,17 @@
 #include "prprf.h"
 #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 "nss.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);
@@ -85,66 +86,98 @@ char *testdir = NULL;
 #define TIMESTART() \
     time1 = PR_IntervalNow();
 
 #define TIMEFINISH(time, reps) \
     time2 = (PRIntervalTime)(PR_IntervalNow() - time1); \
     time1 = PR_IntervalToMilliseconds(time2); \
     time = ((double)(time1))/reps;
 
+#define TIMEMARK(seconds) \
+    time1 = PR_SecondsToInterval(seconds); \
+    { \
+        PRInt64 tmp, L100; \
+        LL_I2L(L100, 100); \
+        if (time2 == 0) { \
+            time2 = 1; \
+        } \
+        LL_DIV(tmp, time1, time2); \
+        if (tmp < 10) { \
+            if (tmp == 0) { \
+                opsBetweenChecks = 1; \
+            } else { \
+                LL_L2I(opsBetweenChecks, tmp); \
+            } \
+        } else { \
+            opsBetweenChecks = 10; \
+        } \
+    } \
+    time2 = time1; \
+    time1 = PR_IntervalNow();
+
+#define TIMETOFINISH() \
+    PR_IntervalNow() - time1 >= time2
+
 static void Usage()
 {
 #define PRINTUSAGE(subject, option, predicate) \
     fprintf(stderr, "%10s %s\t%s\n", subject, option, predicate);
     fprintf(stderr, "\n");
     PRINTUSAGE(progName, "[-DEHSV]", "List available cipher modes"); /* XXX */
     fprintf(stderr, "\n");
     PRINTUSAGE(progName, "-E -m mode ", "Encrypt a buffer");
     PRINTUSAGE("",	"", "[-i plaintext] [-o ciphertext] [-k key] [-v iv]");
     PRINTUSAGE("",	"", "[-b bufsize] [-g keysize] [-e exp] [-r rounds]");
-    PRINTUSAGE("",	"", "[-w wordsize] [-p repetitions]");
+    PRINTUSAGE("",	"", "[-w wordsize] [-p repetitions | -5 time_interval]");
+    PRINTUSAGE("",	"", "[-4 th_num]");
     PRINTUSAGE("",	"-m", "cipher mode to use");
     PRINTUSAGE("",	"-i", "file which contains input buffer");
     PRINTUSAGE("",	"-o", "file for output buffer");
     PRINTUSAGE("",	"-k", "file which contains key");
     PRINTUSAGE("",	"-v", "file which contains initialization vector");
     PRINTUSAGE("",	"-b", "size of input buffer");
     PRINTUSAGE("",	"-g", "key size (in bytes)");
     PRINTUSAGE("",	"-p", "do performance test");
+    PRINTUSAGE("",	"-4", "run test in multithread mode. th_num number of parallel threads");
+    PRINTUSAGE("",	"-5", "run test for specified time interval(in seconds)");
     PRINTUSAGE("(rsa)", "-e", "rsa public exponent");
     PRINTUSAGE("(rc5)", "-r", "number of rounds");
     PRINTUSAGE("(rc5)", "-w", "wordsize (32 or 64)");
     fprintf(stderr, "\n");
     PRINTUSAGE(progName, "-D -m mode", "Decrypt a buffer");
     PRINTUSAGE("",	"", "[-i plaintext] [-o ciphertext] [-k key] [-v iv]");
-    PRINTUSAGE("",	"", "[-p repetitions]");
+    PRINTUSAGE("",	"", "[-p repetitions | -5 time_interval] [-4 th_num]");
     PRINTUSAGE("",	"-m", "cipher mode to use");
     PRINTUSAGE("",	"-i", "file which contains input buffer");
     PRINTUSAGE("",	"-o", "file for output buffer");
     PRINTUSAGE("",	"-k", "file which contains key");
     PRINTUSAGE("",	"-v", "file which contains initialization vector");
     PRINTUSAGE("",	"-p", "do performance test");
+    PRINTUSAGE("",	"-4", "run test in multithread mode. th_num number of parallel threads");
+    PRINTUSAGE("",	"-5", "run test for specified time interval(in seconds)");
     fprintf(stderr, "\n");
     PRINTUSAGE(progName, "-H -m mode", "Hash a buffer");
     PRINTUSAGE("",	"", "[-i plaintext] [-o hash]");
     PRINTUSAGE("",	"", "[-b bufsize]");
-    PRINTUSAGE("",	"", "[-p repetitions]");
+    PRINTUSAGE("",	"", "[-p repetitions | -5 time_interval] [-4 th_num]");
     PRINTUSAGE("",	"-m", "cipher mode to use");
     PRINTUSAGE("",	"-i", "file which contains input buffer");
     PRINTUSAGE("",	"-o", "file for hash");
     PRINTUSAGE("",	"-b", "size of input buffer");
     PRINTUSAGE("",	"-p", "do performance test");
+    PRINTUSAGE("",	"-4", "run test in multithread mode. th_num number of parallel threads");
+    PRINTUSAGE("",	"-5", "run test for specified time interval(in seconds)");
     fprintf(stderr, "\n");
     PRINTUSAGE(progName, "-S -m mode", "Sign a buffer");
     PRINTUSAGE("",	"", "[-i plaintext] [-o signature] [-k key]");
     PRINTUSAGE("",	"", "[-b bufsize]");
 #ifdef NSS_ENABLE_ECC
     PRINTUSAGE("",	"", "[-n curvename]");
 #endif
-    PRINTUSAGE("",	"", "[-p repetitions]");
+    PRINTUSAGE("",	"", "[-p repetitions | -5 time_interval] [-4 th_num]");
     PRINTUSAGE("",	"-m", "cipher mode to use");
     PRINTUSAGE("",	"-i", "file which contains input buffer");
     PRINTUSAGE("",	"-o", "file for signature");
     PRINTUSAGE("",	"-k", "file which contains key");
 #ifdef NSS_ENABLE_ECC
     PRINTUSAGE("",	"-n", "name of curve for EC key generation; one of:");
     PRINTUSAGE("",  "",   "  sect163k1, nistk163, sect163r1, sect163r2,");
     PRINTUSAGE("",  "",   "  nistb163, sect193r1, sect193r2, sect233k1, nistk233,");
@@ -160,25 +193,29 @@ static void Usage()
     PRINTUSAGE("",  "",   "  c2tnb191v2, c2tnb191v3, c2onb191v4, c2onb191v5,");
     PRINTUSAGE("",  "",   "  c2pnb208w1, c2tnb239v1, c2tnb239v2, c2tnb239v3,");
     PRINTUSAGE("",  "",   "  c2onb239v4, c2onb239v5, c2pnb272w1, c2pnb304w1,");
     PRINTUSAGE("",  "",   "  c2tnb359w1, c2pnb368w1, c2tnb431r1, secp112r1,");
     PRINTUSAGE("",  "",   "  secp112r2, secp128r1, secp128r2, sect113r1, sect113r2,");
     PRINTUSAGE("",  "",   "  sect131r1, sect131r2");
 #endif
     PRINTUSAGE("",	"-p", "do performance test");
+    PRINTUSAGE("",	"-4", "run test in multithread mode. th_num number of parallel threads");
+    PRINTUSAGE("",	"-5", "run test for specified time interval(in seconds)");
     fprintf(stderr, "\n");
     PRINTUSAGE(progName, "-V -m mode", "Verify a signed buffer");
     PRINTUSAGE("",	"", "[-i plaintext] [-s signature] [-k key]");
-    PRINTUSAGE("",	"", "[-p repetitions]");
+    PRINTUSAGE("",	"", "[-p repetitions | -5 time_interval] [-4 th_num]");
     PRINTUSAGE("",	"-m", "cipher mode to use");
     PRINTUSAGE("",	"-i", "file which contains input buffer");
     PRINTUSAGE("",	"-s", "file which contains signature of input buffer");
     PRINTUSAGE("",	"-k", "file which contains key");
     PRINTUSAGE("",	"-p", "do performance test");
+    PRINTUSAGE("",	"-4", "run test in multithread mode. th_num number of parallel threads");
+    PRINTUSAGE("",	"-5", "run test for specified time interval(in seconds)");
     fprintf(stderr, "\n");
     PRINTUSAGE(progName, "-N -m mode -b bufsize", 
                                             "Create a nonce plaintext and key");
     PRINTUSAGE("",      "", "[-g keysize] [-u cxreps]");
     PRINTUSAGE("",	"-g", "key size (in bytes)");
     PRINTUSAGE("",      "-u", "number of repetitions of context creation");
     fprintf(stderr, "\n");
     PRINTUSAGE(progName, "-F", "Run the FIPS self-test");
@@ -733,40 +770,49 @@ typedef union
     bltestRSAParams	rsa;
     bltestDSAParams	dsa;
 #ifdef NSS_ENABLE_ECC
     bltestECDSAParams	ecdsa;
 #endif
     bltestHashParams	hash;
 } bltestParams;
 
-typedef struct
-{
+typedef struct bltestCipherInfoStr bltestCipherInfo;
+
+struct  bltestCipherInfoStr {
     PRArenaPool *arena;
+    /* link to next in multithreaded test */
+    bltestCipherInfo *next;
+    PRThread         *cipherThread;
+
+    /* MonteCarlo test flag*/
+    PRBool mCarlo;
     /* cipher context */
     void *cx;
     /* I/O streams */
     bltestIO input;
     bltestIO output;
     /* Cipher-specific parameters */
     bltestParams params;
     /* Cipher mode */
     bltestCipherMode  mode;
     /* Cipher function (encrypt/decrypt/sign/verify/hash) */
     union {
 	bltestSymmCipherFn   symmkeyCipher;
 	bltestPubKeyCipherFn pubkeyCipher;
 	bltestHashCipherFn   hashCipher;
     } cipher;
     /* performance testing */
+    int   repetitionsToPerfom;
+    int   seconds;
     int	  repetitions;
     int   cxreps;
     double cxtime;
     double optime;
-} bltestCipherInfo;
+};
 
 PRBool
 is_symmkeyCipher(bltestCipherMode mode)
 {
     /* change as needed! */
     if (mode >= bltestDES_ECB && mode <= bltestAES_CBC)
 	return PR_TRUE;
     return PR_FALSE;
@@ -1891,115 +1937,240 @@ dsaOp(bltestCipherInfo *cipherInfo)
     PRIntervalTime time1, time2;
     SECStatus rv = SECSuccess;
     int i;
     int maxLen = cipherInfo->output.pBuf.len;
     SECItem dummyOut = { 0, 0, 0 };
     SECITEM_AllocItem(NULL, &dummyOut, maxLen);
     if (cipherInfo->cipher.pubkeyCipher == dsa_signDigest) {
 	if (cipherInfo->params.dsa.sigseed.buf.len > 0) {
-	    rv = DSA_SignDigestWithSeed((DSAPrivateKey *)cipherInfo->cx,
-				       &cipherInfo->output.pBuf,
-				       &cipherInfo->input.pBuf,
-				       cipherInfo->params.dsa.sigseed.buf.data);
-	    CHECKERROR(rv, __LINE__);
-	    TIMESTART();
-	    for (i=0; i<cipherInfo->repetitions; i++) {
-		rv |= DSA_SignDigestWithSeed((DSAPrivateKey *)cipherInfo->cx,
-				       &dummyOut,
-				       &cipherInfo->input.pBuf,
-				       cipherInfo->params.dsa.sigseed.buf.data);
-	    }
-	    TIMEFINISH(cipherInfo->optime, 1.0);
-	    CHECKERROR(rv, __LINE__);
-	} else {
-	    rv = DSA_SignDigest((DSAPrivateKey *)cipherInfo->cx,
-				&cipherInfo->output.pBuf,
-				&cipherInfo->input.pBuf);
-	    CHECKERROR(rv, __LINE__);
-	    TIMESTART();
-	    for (i=0; i<cipherInfo->repetitions; i++) {
-		DSA_SignDigest((DSAPrivateKey *)cipherInfo->cx, &dummyOut,
-			       &cipherInfo->input.pBuf);
-	    }
-	    TIMEFINISH(cipherInfo->optime, 1.0);
-	}
-	bltestCopyIO(cipherInfo->arena, &cipherInfo->params.dsa.sig, 
-	             &cipherInfo->output);
+            bltestDSAParams *dsa = &cipherInfo->params.dsa;
+            DSAPrivateKey *key = (DSAPrivateKey *)cipherInfo->cx;
+
+            TIMESTART();
+            rv = DSA_SignDigestWithSeed(key,
+                                        &cipherInfo->output.pBuf,
+                                        &cipherInfo->input.pBuf,
+                                        dsa->sigseed.buf.data);
+            TIMEFINISH(cipherInfo->optime, 1.0);
+            CHECKERROR(rv, __LINE__);
+            cipherInfo->repetitions = 0;
+            if (cipherInfo->repetitionsToPerfom != 0) {
+                TIMESTART();
+                for (i=0; i<cipherInfo->repetitionsToPerfom;
+                     i++, cipherInfo->repetitions++) {
+                    rv = DSA_SignDigestWithSeed(key, &dummyOut,
+                                                &cipherInfo->input.pBuf,
+                                                dsa->sigseed.buf.data);
+                    CHECKERROR(rv, __LINE__);
+                }
+            } else {
+                int opsBetweenChecks = 0;
+                TIMEMARK(cipherInfo->seconds);
+                while (! (TIMETOFINISH())) {
+                    int j = 0;
+                    for (;j < opsBetweenChecks;j++) {
+                        rv = DSA_SignDigestWithSeed(key, &dummyOut,
+                                                    &cipherInfo->input.pBuf,
+                                                    dsa->sigseed.buf.data);
+                        CHECKERROR(rv, __LINE__);
+                    }
+                    cipherInfo->repetitions += j;
+                }
+            }
+            TIMEFINISH(cipherInfo->optime, 1.0);
+        } else {
+            TIMESTART();
+            rv = DSA_SignDigest((DSAPrivateKey *)cipherInfo->cx,
+                                &cipherInfo->output.pBuf,
+                                &cipherInfo->input.pBuf);
+            TIMEFINISH(cipherInfo->optime, 1.0);
+            CHECKERROR(rv, __LINE__);
+            cipherInfo->repetitions = 0;
+            if (cipherInfo->repetitionsToPerfom != 0) {
+                TIMESTART();
+                for (i=0; i<cipherInfo->repetitionsToPerfom;
+                     i++, cipherInfo->repetitions++) {
+                    rv = DSA_SignDigest((DSAPrivateKey *)cipherInfo->cx,
+                                        &dummyOut,
+                                        &cipherInfo->input.pBuf);
+                    CHECKERROR(rv, __LINE__);
+                }
+            } else {
+                int opsBetweenChecks = 0;
+                TIMEMARK(cipherInfo->seconds);
+                while (! (TIMETOFINISH())) {
+                    int j = 0;
+                    for (;j < opsBetweenChecks;j++) {
+                        rv = DSA_SignDigest((DSAPrivateKey *)cipherInfo->cx,
+                                            &dummyOut,
+                                            &cipherInfo->input.pBuf);
+                        CHECKERROR(rv, __LINE__);
+                    }
+                    cipherInfo->repetitions += j;
+                }
+            }
+            TIMEFINISH(cipherInfo->optime, 1.0);
+        }
+        bltestCopyIO(cipherInfo->arena, &cipherInfo->params.dsa.sig, 
+                     &cipherInfo->output);
     } else {
-	rv = DSA_VerifyDigest((DSAPublicKey *)cipherInfo->cx,
-			      &cipherInfo->params.dsa.sig.buf,
-			      &cipherInfo->input.pBuf);
-	CHECKERROR(rv, __LINE__);
-	TIMESTART();
-	for (i=0; i<cipherInfo->repetitions; i++) {
-	    DSA_VerifyDigest((DSAPublicKey *)cipherInfo->cx,
-			     &cipherInfo->params.dsa.sig.buf,
-			     &cipherInfo->input.pBuf);
-	}
-	TIMEFINISH(cipherInfo->optime, 1.0);
+        TIMESTART();
+        rv = DSA_VerifyDigest((DSAPublicKey *)cipherInfo->cx,
+                              &cipherInfo->params.dsa.sig.buf,
+                              &cipherInfo->input.pBuf);
+        TIMEFINISH(cipherInfo->optime, 1.0);
+        CHECKERROR(rv, __LINE__);
+        cipherInfo->repetitions = 0;
+        if (cipherInfo->repetitionsToPerfom != 0) {
+            TIMESTART();
+            for (i=0; i<cipherInfo->repetitionsToPerfom;
+                 i++, cipherInfo->repetitions++) {
+                rv = DSA_VerifyDigest((DSAPublicKey *)cipherInfo->cx,
+                                      &cipherInfo->params.dsa.sig.buf,
+                                      &cipherInfo->input.pBuf);
+                CHECKERROR(rv, __LINE__);
+            }
+        } else {
+            int opsBetweenChecks = 0;
+            TIMEMARK(cipherInfo->seconds);
+            while (! (TIMETOFINISH())) {
+                int j = 0;
+                for (;j < opsBetweenChecks;j++) {
+                    rv = DSA_VerifyDigest((DSAPublicKey *)cipherInfo->cx,
+                                          &cipherInfo->params.dsa.sig.buf,
+                                          &cipherInfo->input.pBuf);
+                    CHECKERROR(rv, __LINE__);
+                }
+                cipherInfo->repetitions += j;
+            }
+        }
+        TIMEFINISH(cipherInfo->optime, 1.0);
     }
     SECITEM_FreeItem(&dummyOut, PR_FALSE);
     return rv;
 }
 
 #ifdef NSS_ENABLE_ECC
 SECStatus
 ecdsaOp(bltestCipherInfo *cipherInfo)
 {
     PRIntervalTime time1, time2;
     SECStatus rv = SECSuccess;
     int i;
     int maxLen = cipherInfo->output.pBuf.len;
     SECItem dummyOut = { 0, 0, 0 };
     SECITEM_AllocItem(NULL, &dummyOut, maxLen);
     if (cipherInfo->cipher.pubkeyCipher == ecdsa_signDigest) {
-	if (cipherInfo->params.ecdsa.sigseed.buf.len > 0) {
-	    rv = ECDSA_SignDigestWithSeed((ECPrivateKey *)cipherInfo->cx,
-				       &cipherInfo->output.pBuf,
-				       &cipherInfo->input.pBuf,
-				       cipherInfo->params.ecdsa.sigseed.buf.data,
-				       cipherInfo->params.ecdsa.sigseed.buf.len);
-	    CHECKERROR(rv, __LINE__);
-	    TIMESTART();
-	    for (i=0; i<cipherInfo->repetitions; i++) {
-		rv |= ECDSA_SignDigestWithSeed((ECPrivateKey *)cipherInfo->cx,
-				       &dummyOut,
-				       &cipherInfo->input.pBuf,
-				       cipherInfo->params.ecdsa.sigseed.buf.data,
-				       cipherInfo->params.ecdsa.sigseed.buf.len);
-	    }
-	    TIMEFINISH(cipherInfo->optime, 1.0);
-	    CHECKERROR(rv, __LINE__);
-	} else {
-	    rv = ECDSA_SignDigest((ECPrivateKey *)cipherInfo->cx,
-				&cipherInfo->output.pBuf,
-				&cipherInfo->input.pBuf);
-	    CHECKERROR(rv, __LINE__);
-	    TIMESTART();
-	    for (i=0; i<cipherInfo->repetitions; i++) {
-		ECDSA_SignDigest((ECPrivateKey *)cipherInfo->cx, &dummyOut,
-			       &cipherInfo->input.pBuf);
-	    }
-	    TIMEFINISH(cipherInfo->optime, 1.0);
-	}
-	bltestCopyIO(cipherInfo->arena, &cipherInfo->params.ecdsa.sig, 
-	             &cipherInfo->output);
+        if (cipherInfo->params.ecdsa.sigseed.buf.len > 0) {
+            ECPrivateKey *key = (ECPrivateKey *)cipherInfo->cx;
+            bltestECDSAParams *ecdsa = &cipherInfo->params.ecdsa;
+
+            TIMESTART();
+            rv = ECDSA_SignDigestWithSeed(key,
+                                          &cipherInfo->output.pBuf,
+                                          &cipherInfo->input.pBuf,
+                                          ecdsa->sigseed.buf.data,
+                                          ecdsa->sigseed.buf.len);
+            TIMEFINISH(cipherInfo->optime, 1.0);
+            CHECKERROR(rv, __LINE__);
+            cipherInfo->repetitions = 0;
+            if (cipherInfo->repetitionsToPerfom != 0) {
+                TIMESTART();
+                for (i=0; i<cipherInfo->repetitionsToPerfom;
+                     i++, cipherInfo->repetitions++) {
+                    rv = ECDSA_SignDigestWithSeed(key, &dummyOut,
+                                                  &cipherInfo->input.pBuf,
+                                                  ecdsa->sigseed.buf.data,
+                                                  ecdsa->sigseed.buf.len);
+                    CHECKERROR(rv, __LINE__);
+                }
+            } else {
+                int opsBetweenChecks = 0;
+                TIMEMARK(cipherInfo->seconds);
+                while (! (TIMETOFINISH())) {
+                    int j = 0;
+                    for (;j < opsBetweenChecks;j++) {
+                        rv = ECDSA_SignDigestWithSeed(key, &dummyOut,
+                                                      &cipherInfo->input.pBuf,
+                                                      ecdsa->sigseed.buf.data,
+                                                      ecdsa->sigseed.buf.len);
+                        CHECKERROR(rv, __LINE__);
+                    }
+                    cipherInfo->repetitions += j;
+                }
+            }
+            TIMEFINISH(cipherInfo->optime, 1.0);
+        } else {
+            TIMESTART();
+            rv = ECDSA_SignDigest((ECPrivateKey *)cipherInfo->cx,
+                                  &cipherInfo->output.pBuf,
+                                  &cipherInfo->input.pBuf);
+            TIMEFINISH(cipherInfo->optime, 1.0);
+            CHECKERROR(rv, __LINE__);
+            cipherInfo->repetitions = 0;
+            if (cipherInfo->repetitionsToPerfom != 0) {
+                TIMESTART();
+                for (i=0; i<cipherInfo->repetitionsToPerfom;
+                     i++, cipherInfo->repetitions++) {
+                    rv = ECDSA_SignDigest((ECPrivateKey *)cipherInfo->cx,
+                                          &dummyOut,
+                                          &cipherInfo->input.pBuf);
+                    CHECKERROR(rv, __LINE__);
+                }
+            } else {
+                int opsBetweenChecks = 0;
+                TIMEMARK(cipherInfo->seconds);
+                while (! (TIMETOFINISH())) {
+                    int j = 0;
+                    for (;j < opsBetweenChecks;j++) {
+                        rv = ECDSA_SignDigest((ECPrivateKey *)cipherInfo->cx,
+                                              &dummyOut,
+                                              &cipherInfo->input.pBuf);
+                        CHECKERROR(rv, __LINE__);
+                    }
+                    cipherInfo->repetitions += j;
+                }
+            }
+            TIMEFINISH(cipherInfo->optime, 1.0);
+        }
+        bltestCopyIO(cipherInfo->arena, &cipherInfo->params.ecdsa.sig, 
+                     &cipherInfo->output);
     } else {
-	rv = ECDSA_VerifyDigest((ECPublicKey *)cipherInfo->cx,
-			      &cipherInfo->params.ecdsa.sig.buf,
-			      &cipherInfo->input.pBuf);
-	CHECKERROR(rv, __LINE__);
-	TIMESTART();
-	for (i=0; i<cipherInfo->repetitions; i++) {
-	    ECDSA_VerifyDigest((ECPublicKey *)cipherInfo->cx,
-			     &cipherInfo->params.ecdsa.sig.buf,
-			     &cipherInfo->input.pBuf);
-	}
-	TIMEFINISH(cipherInfo->optime, 1.0);
+        TIMESTART();
+        rv = ECDSA_VerifyDigest((ECPublicKey *)cipherInfo->cx,
+                                &cipherInfo->params.ecdsa.sig.buf,
+                                &cipherInfo->input.pBuf);
+        TIMEFINISH(cipherInfo->optime, 1.0);
+        CHECKERROR(rv, __LINE__);
+        cipherInfo->repetitions = 0;
+        if (cipherInfo->repetitionsToPerfom != 0) {
+            TIMESTART();
+            for (i=0; i<cipherInfo->repetitionsToPerfom;
+                 i++, cipherInfo->repetitions++) {
+                rv = ECDSA_VerifyDigest((ECPublicKey *)cipherInfo->cx,
+                                        &cipherInfo->params.ecdsa.sig.buf,
+                                        &cipherInfo->input.pBuf);
+                CHECKERROR(rv, __LINE__);
+            }
+        } else {
+            int opsBetweenChecks = 0;
+            TIMEMARK(cipherInfo->seconds);
+            while (! (TIMETOFINISH())) {
+                int j = 0;
+                for (;j < opsBetweenChecks;j++) {
+                    rv = ECDSA_VerifyDigest((ECPublicKey *)cipherInfo->cx,
+                                            &cipherInfo->params.ecdsa.sig.buf,
+                                            &cipherInfo->input.pBuf);
+                    CHECKERROR(rv, __LINE__);
+                }
+                cipherInfo->repetitions += j;
+            }
+        }
+        TIMEFINISH(cipherInfo->optime, 1.0);
     }
     SECITEM_FreeItem(&dummyOut, PR_FALSE);
     return rv;
 }
 #endif
 
 SECStatus
 cipherDoOp(bltestCipherInfo *cipherInfo)
@@ -2012,54 +2183,122 @@ cipherDoOp(bltestCipherInfo *cipherInfo)
     if (cipherInfo->mode == bltestDSA)
 	return dsaOp(cipherInfo);
 #ifdef NSS_ENABLE_ECC
     else if (cipherInfo->mode == bltestECDSA)
 	return ecdsaOp(cipherInfo);
 #endif
     dummyOut = PORT_Alloc(maxLen);
     if (is_symmkeyCipher(cipherInfo->mode)) {
-	rv = (*cipherInfo->cipher.symmkeyCipher)(cipherInfo->cx,
-						 cipherInfo->output.pBuf.data,
-						 &len, maxLen,
-						 cipherInfo->input.pBuf.data,
-						 cipherInfo->input.pBuf.len);
-	TIMESTART();
-	for (i=0; i<cipherInfo->repetitions; i++) {
-	    (*cipherInfo->cipher.symmkeyCipher)(cipherInfo->cx, dummyOut,
-						&len, maxLen,
-						cipherInfo->input.pBuf.data,
-						cipherInfo->input.pBuf.len);
-
-	}
-	TIMEFINISH(cipherInfo->optime, 1.0);
+        TIMESTART();
+        rv = (*cipherInfo->cipher.symmkeyCipher)(cipherInfo->cx,
+                                                 cipherInfo->output.pBuf.data,
+                                                 &len, maxLen,
+                                                 cipherInfo->input.pBuf.data,
+                                                 cipherInfo->input.pBuf.len);
+        TIMEFINISH(cipherInfo->optime, 1.0);
+        CHECKERROR(rv, __LINE__);
+        cipherInfo->repetitions = 0;
+        if (cipherInfo->repetitionsToPerfom != 0) {
+            TIMESTART();
+            for (i=0; i<cipherInfo->repetitionsToPerfom; i++,
+                     cipherInfo->repetitions++) {
+                (*cipherInfo->cipher.symmkeyCipher)(cipherInfo->cx, dummyOut,
+                                                    &len, maxLen,
+                                                    cipherInfo->input.pBuf.data,
+                                                    cipherInfo->input.pBuf.len);
+                
+                CHECKERROR(rv, __LINE__);
+            }
+        } else {
+            int opsBetweenChecks = 0;
+            bltestIO *input = &cipherInfo->input;
+            TIMEMARK(cipherInfo->seconds);
+            while (! (TIMETOFINISH())) {
+                int j = 0;
+                for (;j < opsBetweenChecks;j++) {
+                    (*cipherInfo->cipher.symmkeyCipher)(cipherInfo->cx,
+                                                        dummyOut,
+                                                        &len, maxLen,
+                                                        input->pBuf.data,
+                                                        input->pBuf.len);
+                }
+                cipherInfo->repetitions += j;
+            }
+        }
+        TIMEFINISH(cipherInfo->optime, 1.0);
     } else if (is_pubkeyCipher(cipherInfo->mode)) {
-	rv = (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx,
-						&cipherInfo->output.pBuf,
-						&cipherInfo->input.pBuf);
-	TIMESTART();
-	for (i=0; i<cipherInfo->repetitions; i++) {
-	    SECItem dummy;
-	    dummy.data = dummyOut;
-	    dummy.len = maxLen;
-	    (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx, &dummy,
-					       &cipherInfo->input.pBuf);
-	}
-	TIMEFINISH(cipherInfo->optime, 1.0);
+        TIMESTART();
+        rv = (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx,
+                                                &cipherInfo->output.pBuf,
+                                                &cipherInfo->input.pBuf);
+        TIMEFINISH(cipherInfo->optime, 1.0);
+        CHECKERROR(rv, __LINE__);
+        cipherInfo->repetitions = 0;
+        if (cipherInfo->repetitionsToPerfom != 0) {
+            TIMESTART();
+            for (i=0; i<cipherInfo->repetitionsToPerfom;
+                 i++, cipherInfo->repetitions++) {
+                SECItem dummy;
+                dummy.data = dummyOut;
+                dummy.len = maxLen;
+                (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx, &dummy, 
+                                                   &cipherInfo->input.pBuf);
+                CHECKERROR(rv, __LINE__);
+            }
+        } else {
+            int opsBetweenChecks = 0;
+            TIMEMARK(cipherInfo->seconds);
+            while (! (TIMETOFINISH())) {
+                int j = 0;
+                for (;j < opsBetweenChecks;j++) {
+                    SECItem dummy;
+                    dummy.data = dummyOut;
+                    dummy.len = maxLen;
+                    (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx, &dummy,
+                                                       &cipherInfo->input.pBuf);
+                    CHECKERROR(rv, __LINE__);
+                }
+                cipherInfo->repetitions += j;
+            }
+        }
+        TIMEFINISH(cipherInfo->optime, 1.0);
     } else if (is_hashCipher(cipherInfo->mode)) {
-	rv = (*cipherInfo->cipher.hashCipher)(cipherInfo->output.pBuf.data,
-					      cipherInfo->input.pBuf.data,
-					      cipherInfo->input.pBuf.len);
-	TIMESTART();
-	for (i=0; i<cipherInfo->repetitions; i++) {
-	    (*cipherInfo->cipher.hashCipher)(dummyOut,
-					     cipherInfo->input.pBuf.data,
-					     cipherInfo->input.pBuf.len);
-	}
-	TIMEFINISH(cipherInfo->optime, 1.0);
+        TIMESTART();
+        rv = (*cipherInfo->cipher.hashCipher)(cipherInfo->output.pBuf.data,
+                                              cipherInfo->input.pBuf.data,
+                                              cipherInfo->input.pBuf.len);
+        TIMEFINISH(cipherInfo->optime, 1.0);
+        CHECKERROR(rv, __LINE__);
+        cipherInfo->repetitions = 0;
+        if (cipherInfo->repetitionsToPerfom != 0) {
+            TIMESTART();
+            for (i=0; i<cipherInfo->repetitionsToPerfom;
+                 i++, cipherInfo->repetitions++) {
+                (*cipherInfo->cipher.hashCipher)(dummyOut,
+                                                 cipherInfo->input.pBuf.data,
+                                                 cipherInfo->input.pBuf.len);
+                CHECKERROR(rv, __LINE__);
+            }
+        } else {
+            int opsBetweenChecks = 0;
+            TIMEMARK(cipherInfo->seconds);
+            while (! (TIMETOFINISH())) {
+                int j = 0;
+                for (;j < opsBetweenChecks;j++) {
+                    bltestIO *input = &cipherInfo->input;
+                    (*cipherInfo->cipher.hashCipher)(dummyOut,
+                                                     input->pBuf.data,
+                                                     input->pBuf.len);
+                    CHECKERROR(rv, __LINE__);
+                }
+                cipherInfo->repetitions += j;
+            }
+        }
+        TIMEFINISH(cipherInfo->optime, 1.0);
     }
     PORT_Free(dummyOut);
     return rv;
 }
 
 SECStatus
 cipherFinish(bltestCipherInfo *cipherInfo)
 {
@@ -2115,99 +2354,201 @@ print_exponent(SECItem *exp)
 	for (i=exp->len; i >=0; --i) e |= exp->data[exp->len-i] << 8*(i-1);
 	fprintf(stdout, "%12d", e);
     } else {
 	e = 8*exp->len;
 	fprintf(stdout, "~2**%-8d", e);
     }
 }
 
+static void
+splitToReportUnit(PRInt64 res, int *resArr, int *del, int size)
+{
+    PRInt64 remaining = res, tmp = 0;
+    PRInt64 Ldel;
+    int i = -1;
+
+    while (remaining > 0 && ++i < size) {
+        LL_I2L(Ldel, del[i]);
+        LL_MOD(tmp, remaining, Ldel);
+        LL_L2I(resArr[i], tmp);
+        LL_DIV(remaining, remaining, Ldel);
+    }
+}
+
+static char*
+getHighUnitBytes(PRInt64 res)
+{
+    int spl[] = {0, 0, 0, 0};
+    int del[] = {1024, 1024, 1024, 1024};
+    char *marks[] = {"b", "Kb", "Mb", "Gb"};
+    int i = 3;
+
+    splitToReportUnit(res, spl, del, 4);
+
+    for (;i>0;i--) {
+        if (spl[i] != 0) {
+            break;
+        }
+    }
+
+    return PR_smprintf("%d%s", spl[i], marks[i]);
+}
+
+
+static void
+printPR_smpString(const char *sformat, char *reportStr,
+                  const char *nformat, PRInt64 rNum)
+{
+    if (reportStr) {
+        fprintf(stdout, sformat, reportStr);
+        PR_smprintf_free(reportStr);
+    } else {
+        int prnRes;
+        LL_L2I(prnRes, rNum);
+        fprintf(stdout, nformat, rNum);
+    }
+}
+
+static char*
+getHighUnitOps(PRInt64 res)
+{
+    int spl[] = {0, 0, 0, 0};
+    int del[] = {1000, 1000, 1000, 1000};
+    char *marks[] = {"", "T", "M", "B"};
+    int i = 3;
+
+    splitToReportUnit(res, spl, del, 4);
+
+    for (;i>0;i--) {
+        if (spl[i] != 0) {
+            break;
+        }
+    }
+
+    return PR_smprintf("%d%s", spl[i], marks[i]);
+}
+
 void
-dump_performance_info(bltestCipherInfo *info, PRBool encrypt, PRBool cxonly)
+dump_performance_info(bltestCipherInfo *infoList, double totalTimeInt,
+                      PRBool encrypt, PRBool cxonly)
 {
+    bltestCipherInfo *info = infoList;
+    
+    PRInt64 totalIn = 0;
     PRBool td = PR_TRUE;
+
+    int   repetitions = 0;
+    int   cxreps = 0;
+    double cxtime = 0;
+    double optime = 0;
+    while (info != NULL) {
+        repetitions += info->repetitions;
+        cxreps += info->cxreps;
+        cxtime += info->cxtime;
+        optime += info->optime;
+        totalIn += info->input.buf.len * info->repetitions;
+        
+        info = info->next;
+    }
+    info = infoList;
+
     fprintf(stdout, "#%9s", "mode");
     fprintf(stdout, "%12s", "in");
 print_td:
     switch (info->mode) {
-    case bltestDES_ECB:
-    case bltestDES_CBC:
-    case bltestDES_EDE_ECB:
-    case bltestDES_EDE_CBC:
-    case bltestAES_ECB:
-    case bltestAES_CBC:
-    case bltestRC2_ECB:
-    case bltestRC2_CBC:
-    case bltestRC4:
-	if (td)
-	    fprintf(stdout, "%8s", "symmkey");
-	else
-	    fprintf(stdout, "%8d", 8*info->params.sk.key.buf.len);
-	break;
+      case bltestDES_ECB:
+      case bltestDES_CBC:
+      case bltestDES_EDE_ECB:
+      case bltestDES_EDE_CBC:
+      case bltestAES_ECB:
+      case bltestAES_CBC:
+      case bltestRC2_ECB:
+      case bltestRC2_CBC:
+      case bltestRC4:
+          if (td)
+              fprintf(stdout, "%8s", "symmkey");
+          else
+              fprintf(stdout, "%8d", 8*info->params.sk.key.buf.len);
+          break;
 #if NSS_SOFTOKEN_DOES_RC5
-    case bltestRC5_ECB:
-    case bltestRC5_CBC:
-	if (info->params.sk.key.buf.len > 0)
-	    printf("symmetric key(bytes)=%d,", info->params.sk.key.buf.len);
-	if (info->rounds > 0)
-	    printf("rounds=%d,", info->params.rc5.rounds);
-	if (info->wordsize > 0)
-	    printf("wordsize(bytes)=%d,", info->params.rc5.wordsize);
-	break;
+      case bltestRC5_ECB:
+      case bltestRC5_CBC:
+          if (info->params.sk.key.buf.len > 0)
+              printf("symmetric key(bytes)=%d,", info->params.sk.key.buf.len);
+          if (info->rounds > 0)
+              printf("rounds=%d,", info->params.rc5.rounds);
+          if (info->wordsize > 0)
+              printf("wordsize(bytes)=%d,", info->params.rc5.wordsize);
+          break;
 #endif
-    case bltestRSA:
-	if (td) {
-	    fprintf(stdout, "%8s", "rsa_mod");
-	    fprintf(stdout, "%12s", "rsa_pe");
-	} else {
-	    fprintf(stdout, "%8d", info->params.rsa.keysizeInBits);
-	    print_exponent(&info->params.rsa.rsakey->publicExponent);
-	}
-	break;
-    case bltestDSA:
-	if (td)
-	    fprintf(stdout, "%8s", "pqg_mod");
-	else
-	    fprintf(stdout, "%8d", PQG_INDEX_TO_PBITS(info->params.dsa.j));
-	break;
+      case bltestRSA:
+          if (td) {
+              fprintf(stdout, "%8s", "rsa_mod");
+              fprintf(stdout, "%12s", "rsa_pe");
+          } else {
+              fprintf(stdout, "%8d", info->params.rsa.keysizeInBits);
+              print_exponent(&info->params.rsa.rsakey->publicExponent);
+          }
+          break;
+      case bltestDSA:
+          if (td)
+              fprintf(stdout, "%8s", "pqg_mod");
+          else
+              fprintf(stdout, "%8d", PQG_INDEX_TO_PBITS(info->params.dsa.j));
+          break;
 #ifdef NSS_ENABLE_ECC
-    case bltestECDSA:
-	if (td)
-	    fprintf(stdout, "%12s", "ec_curve");
-	else
-	    fprintf(stdout, "%12s", ecCurve_map[info->params.ecdsa.eckey->ecParams.name]->text);
-	break;
+      case bltestECDSA:
+          if (td)
+              fprintf(stdout, "%12s", "ec_curve");
+          else
+              fprintf(stdout, "%12s",
+                      ecCurve_map[info->params.ecdsa.eckey->ecParams.name]->text);
+          break;
 #endif
-    case bltestMD2:
-    case bltestMD5:
-    case bltestSHA1:
-    case bltestSHA256:
-    case bltestSHA384:
-    case bltestSHA512:
-    default:
-	break;
+      case bltestMD2:
+      case bltestMD5:
+      case bltestSHA1:
+      case bltestSHA256:
+      case bltestSHA384:
+      case bltestSHA512:
+      default:
+          break;
     }
     if (!td) {
-	fprintf(stdout, "%8d", info->repetitions);
-	fprintf(stdout, "%8d", info->cxreps);
-	fprintf(stdout, "%12.3f", info->cxtime);
-	fprintf(stdout, "%12.3f", info->optime);
-	fprintf(stdout, "\n");
-	return;
+        PRInt64 totalThroughPut;
+
+        printPR_smpString("%8s", getHighUnitOps(repetitions),
+                          "%8d", repetitions);
+
+        printPR_smpString("%8s", getHighUnitOps(cxreps), "%8d", cxreps);
+
+        fprintf(stdout, "%12.3f", cxtime);
+        fprintf(stdout, "%12.3f", optime);
+        fprintf(stdout, "%12.03f", totalTimeInt / 1000);
+
+        totalThroughPut = (PRInt64)(totalIn / totalTimeInt * 1000);
+        printPR_smpString("%12s", getHighUnitBytes(totalThroughPut),
+                          "%12d", totalThroughPut);
+
+        fprintf(stdout, "\n");
+        return;
     }
-
+    
     fprintf(stdout, "%8s", "opreps");
     fprintf(stdout, "%8s", "cxreps");
     fprintf(stdout, "%12s", "context");
     fprintf(stdout, "%12s", "op");
+    fprintf(stdout, "%12s", "time(sec)");
+    fprintf(stdout, "%12s", "thrgput");
     fprintf(stdout, "\n");
     fprintf(stdout, "%8s", mode_strings[info->mode]);
     fprintf(stdout, "_%c", (cxonly) ? 'c' : (encrypt) ? 'e' : 'd');
-    fprintf(stdout, "%12d", info->input.buf.len * info->repetitions);
-
+    printPR_smpString("%12s", getHighUnitBytes(totalIn), "%12d", totalIn);
+    
     td = !td;
     goto print_td;
 }
 
 void
 printmodes()
 {
     bltestCipherMode mode;
@@ -2603,16 +2944,34 @@ dump_file(bltestCipherMode mode, char *f
 	key = eckey_from_filedata(&keydata.buf);
 	dump_eckey(key);
 #endif
     }
     PORT_FreeArena(arena, PR_FALSE);
     return SECFailure;
 }
 
+void ThreadExecTest(void *data)
+{
+    bltestCipherInfo *cipherInfo = (bltestCipherInfo*)data;
+
+    if (cipherInfo->mCarlo == PR_TRUE) {
+        int mciter;
+        for (mciter=0; mciter<10000; mciter++) {
+            cipherDoOp(cipherInfo);
+            memcpy(cipherInfo->input.buf.data,
+                   cipherInfo->output.buf.data,
+                   cipherInfo->input.buf.len);
+        }
+    } else {
+        cipherDoOp(cipherInfo);
+    }
+    cipherFinish(cipherInfo);
+}
+
 /* bltest commands */
 enum {
     cmd_Decrypt = 0,
     cmd_Encrypt,
     cmd_FIPS,
     cmd_Hash,
     cmd_Nonce,
     cmd_Dump,
@@ -2649,16 +3008,18 @@ enum {
     opt_IV,
     opt_WordSize,
     opt_UseSeed,
     opt_UseSigSeed,
     opt_SeedFile,
     opt_InputOffset,
     opt_OutputOffset,
     opt_MonteCarlo,
+    opt_ThreadNum,
+    opt_SecondsToRun,
     opt_CmdLine
 };
 
 static secuCommandFlag bltest_commands[] =
 {
     { /* cmd_Decrypt	*/ 'D', PR_FALSE, 0, PR_FALSE },
     { /* cmd_Encrypt	*/ 'E', PR_FALSE, 0, PR_FALSE },
     { /* cmd_FIPS	*/ 'F', PR_FALSE, 0, PR_FALSE },
@@ -2698,36 +3059,38 @@ static secuCommandFlag bltest_options[] 
     { /* opt_IV		  */ 'v', PR_TRUE,  0, PR_FALSE },
     { /* opt_WordSize	  */ 'w', PR_TRUE,  0, PR_FALSE },
     { /* opt_UseSeed	  */ 'x', PR_FALSE, 0, PR_FALSE },
     { /* opt_UseSigSeed	  */ 'y', PR_FALSE, 0, PR_FALSE },
     { /* opt_SeedFile	  */ 'z', PR_FALSE, 0, PR_FALSE },
     { /* opt_InputOffset  */ '1', PR_TRUE,  0, PR_FALSE },
     { /* opt_OutputOffset */ '2', PR_TRUE,  0, PR_FALSE },
     { /* opt_MonteCarlo   */ '3', PR_FALSE, 0, PR_FALSE },
+    { /* opt_ThreadNum    */ '4', PR_TRUE,  0, PR_FALSE },
+    { /* opt_SecondsToRun */ '5', PR_TRUE,  0, PR_FALSE },
     { /* opt_CmdLine	  */ '-', PR_FALSE, 0, PR_FALSE }
 };
 
 int main(int argc, char **argv)
 {
     char *infileName, *outfileName, *keyfileName, *ivfileName;
-    SECStatus rv;
+    SECStatus rv = SECFailure;
 
-    bltestCipherInfo	 cipherInfo;
-    bltestParams	*params;
-    PRFileDesc		*file, *infile, *outfile;
-    char		*instr = NULL;
-    PRArenaPool		*arena;
-    bltestIOMode	 ioMode;
-    int			 keysize, bufsize, exponent;
+    double              totalTime;
+    PRIntervalTime      time1, time2;
+    PRFileDesc          *outfile;           
+    bltestCipherInfo    *cipherInfoListHead, *cipherInfo;
+    bltestIOMode        ioMode;
+    int                 bufsize, exponent, curThrdNum;
 #ifdef NSS_ENABLE_ECC
     char		*curveName = NULL;
 #endif
     int			 i, commandsEntered;
     int			 inoff, outoff;
+    int                  threads = 1;
 
     secuCommand bltest;
     bltest.numCommands = sizeof(bltest_commands) / sizeof(secuCommandFlag);
     bltest.numOptions = sizeof(bltest_options) / sizeof(secuCommandFlag);
     bltest.commands = bltest_commands;
     bltest.options = bltest_options;
 
     progName = strrchr(argv[0], '/');
@@ -2738,38 +3101,42 @@ int main(int argc, char **argv)
     rv = RNG_RNGInit();
     if (rv != SECSuccess) {
     	SECU_PrintPRandOSError(progName);
 	return -1;
     }
     RNG_SystemInfoForRNG();
 
     rv = SECU_ParseCommandLine(argc, argv, progName, &bltest);
+    if (rv == SECFailure) {
+        fprintf(stderr, "%s: command line parsing error!\n", progName);
+        goto print_usage;
+    }
+    rv = SECFailure;
 
-    PORT_Memset(&cipherInfo, 0, sizeof(cipherInfo));
-    arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
-    cipherInfo.arena = arena;
-    params = &cipherInfo.params;
+    cipherInfo = PORT_ZNew(bltestCipherInfo);
+    cipherInfoListHead = cipherInfo;
     /* set some defaults */
     infileName = outfileName = keyfileName = ivfileName = NULL;
 
     /* Check the number of commands entered on the command line. */
     commandsEntered = 0;
     for (i=0; i<bltest.numCommands; i++)
 	if (bltest.commands[i].activated)
 	    commandsEntered++;
 
     if (commandsEntered > 1 &&
 	!(commandsEntered == 2 && bltest.commands[cmd_SelfTest].activated)) {
 	fprintf(stderr, "%s: one command at a time!\n", progName);
-	Usage();
+        goto print_usage;
     }
+
     if (commandsEntered == 0) {
 	fprintf(stderr, "%s: you must enter a command!\n", progName);
-	Usage();
+        goto print_usage;
     }
 
     if (bltest.commands[cmd_Sign].activated)
 	bltest.commands[cmd_Encrypt].activated = PR_TRUE;
     if (bltest.commands[cmd_Verify].activated)
 	bltest.commands[cmd_Decrypt].activated = PR_TRUE;
     if (bltest.commands[cmd_Hash].activated)
 	bltest.commands[cmd_Encrypt].activated = PR_TRUE;
@@ -2807,270 +3174,394 @@ int main(int argc, char **argv)
 	    }
 	}
 	if (bltest.commands[cmd_Decrypt].activated &&
 	    !bltest.commands[cmd_Encrypt].activated)
 	    encrypt = PR_FALSE;
 	if (bltest.commands[cmd_Encrypt].activated &&
 	    !bltest.commands[cmd_Decrypt].activated)
 	    decrypt = PR_FALSE;
-	return blapi_selftest(modesToTest, numModesToTest, inoff, outoff,
-	                      encrypt, decrypt);
+	rv = blapi_selftest(modesToTest, numModesToTest, inoff, outoff,
+                            encrypt, decrypt);
+        PORT_Free(cipherInfo);
+        return rv;
     }
 
     /* Do FIPS self-test */
     if (bltest.commands[cmd_FIPS].activated) {
 	CK_RV ckrv = sftk_fipsPowerUpSelfTest();
 	fprintf(stdout, "CK_RV: %ld.\n", ckrv);
-	return 0;
+        PORT_Free(cipherInfo);
+        if (ckrv == CKR_OK)
+            return SECSuccess;
+        return SECFailure;
     }
 
     /*
      * Check command line arguments for Encrypt/Decrypt/Hash/Sign/Verify
      */
 
     if ((bltest.commands[cmd_Decrypt].activated ||
 	 bltest.commands[cmd_Verify].activated) &&
 	bltest.options[opt_BufSize].activated) {
-	fprintf(stderr, "%s: cannot use a nonce as input to decrypt/verify.\n",
+	fprintf(stderr, "%s: Cannot use a nonce as input to decrypt/verify.\n",
 			 progName);
-	Usage();
+        goto print_usage;
     }
 
     if (bltest.options[opt_Mode].activated) {
-	cipherInfo.mode = get_mode(bltest.options[opt_Mode].arg);
-	if (cipherInfo.mode == bltestINVALID) {
-	    fprintf(stderr, "%s: Invalid mode \"%s\"\n", progName,
-			     bltest.options[opt_Mode].arg);
-	    Usage();
+	cipherInfo->mode = get_mode(bltest.options[opt_Mode].arg);
+	if (cipherInfo->mode == bltestINVALID) {
+            goto print_usage;
 	}
     } else {
 	fprintf(stderr, "%s: You must specify a cipher mode with -m.\n",
 			 progName);
-	Usage();
+        goto print_usage;
+    }
+
+    
+    if (bltest.options[opt_Repetitions].activated &&
+        bltest.options[opt_SecondsToRun].activated) {
+        fprintf(stderr, "%s: Operation time should be defined in either "
+                "repetitions(-p) or seconds(-5) not both",
+                progName);
+        goto print_usage;
     }
 
     if (bltest.options[opt_Repetitions].activated) {
-	cipherInfo.repetitions = PORT_Atoi(bltest.options[opt_Repetitions].arg);
+        cipherInfo->repetitionsToPerfom =
+            PORT_Atoi(bltest.options[opt_Repetitions].arg);
     } else {
-	cipherInfo.repetitions = 0;
+        cipherInfo->repetitionsToPerfom = 0;
+    }
+
+    if (bltest.options[opt_SecondsToRun].activated) {
+        cipherInfo->seconds = PORT_Atoi(bltest.options[opt_SecondsToRun].arg);
+    } else {
+        cipherInfo->seconds = 0;
     }
 
 
     if (bltest.options[opt_CXReps].activated) {
-	cipherInfo.cxreps = PORT_Atoi(bltest.options[opt_CXReps].arg);
+        cipherInfo->cxreps = PORT_Atoi(bltest.options[opt_CXReps].arg);
     } else {
-	cipherInfo.cxreps = 0;
+        cipherInfo->cxreps = 0;
+    }
+
+    if (bltest.options[opt_ThreadNum].activated) {
+        threads = PORT_Atoi(bltest.options[opt_ThreadNum].arg);
+        if (threads <= 0) {
+            threads = 1;
+        }
     }
 
     /* Dump a file (rsakey, dsakey, etc.) */
     if (bltest.commands[cmd_Dump].activated) {
-	return dump_file(cipherInfo.mode, bltest.options[opt_Input].arg);
+        rv = dump_file(cipherInfo->mode, bltest.options[opt_Input].arg);
+        PORT_Free(cipherInfo);
+        return rv;
     }
 
     /* default input mode is binary */
     ioMode = (bltest.options[opt_B64].activated)     ? bltestBase64Encoded :
 	     (bltest.options[opt_Hex].activated)     ? bltestHexStream :
 	     (bltest.options[opt_HexWSpc].activated) ? bltestHexSpaceDelim :
 						       bltestBinary;
 
-    if (bltest.options[opt_KeySize].activated)
-	keysize = PORT_Atoi(bltest.options[opt_KeySize].arg);
-    else
-	keysize = 0;
-
     if (bltest.options[opt_Exponent].activated)
 	exponent = PORT_Atoi(bltest.options[opt_Exponent].arg);
     else
 	exponent = 65537;
 
 #ifdef NSS_ENABLE_ECC
     if (bltest.options[opt_CurveName].activated)
 	curveName = PORT_Strdup(bltest.options[opt_CurveName].arg);
     else
 	curveName = NULL;
 #endif
 
-    /* Set up an encryption key. */
-    keysize = 0;
-    file = NULL;
-    if (is_symmkeyCipher(cipherInfo.mode)) {
-	char *keystr = NULL;  /* if key is on command line */
-	if (bltest.options[opt_Key].activated) {
-	    if (bltest.options[opt_CmdLine].activated) {
-		keystr = bltest.options[opt_Key].arg;
-	    } else {
-		file = PR_Open(bltest.options[opt_Key].arg, PR_RDONLY, 00660);
-	    }
-	} else {
-	    if (bltest.options[opt_KeySize].activated)
-		keysize = PORT_Atoi(bltest.options[opt_KeySize].arg);
-	    else
-		keysize = 8; /* use 64-bit default (DES) */
-	    /* save the random key for reference */
-	    file = PR_Open("tmp.key", PR_WRONLY|PR_CREATE_FILE, 00660);
-	}
-	params->key.mode = ioMode;
-	setupIO(cipherInfo.arena, &params->key, file, keystr, keysize);
-	if (file)
-	    PR_Close(file);
-    } else if (is_pubkeyCipher(cipherInfo.mode)) {
-	if (bltest.options[opt_Key].activated) {
-	    file = PR_Open(bltest.options[opt_Key].arg, PR_RDONLY, 00660);
-	} else {
-	    if (bltest.options[opt_KeySize].activated)
-		keysize = PORT_Atoi(bltest.options[opt_KeySize].arg);
-	    else
-		keysize = 64; /* use 512-bit default */
-	    file = PR_Open("tmp.key", PR_WRONLY|PR_CREATE_FILE, 00660);
-	}
-	params->key.mode = bltestBase64Encoded;
-#ifdef NSS_ENABLE_ECC
-	pubkeyInitKey(&cipherInfo, file, keysize, exponent, curveName);
-#else
-	pubkeyInitKey(&cipherInfo, file, keysize, exponent);
-#endif
-	PR_Close(file);
+    if (bltest.commands[cmd_Verify].activated &&
+        !bltest.options[opt_SigFile].activated) {
+        fprintf(stderr, "%s: You must specify a signature file with -f.\n",
+                progName);
+
+      print_usage:
+        PORT_Free(cipherInfo);
+        Usage();
     }
 
-    /* set up an initialization vector. */
-    if (cipher_requires_IV(cipherInfo.mode)) {
-	char *ivstr = NULL;
-	bltestSymmKeyParams *skp;
-	file = NULL;
-	if (cipherInfo.mode == bltestRC5_CBC)
-	    skp = (bltestSymmKeyParams *)&params->rc5;
-	else
-	    skp = &params->sk;
-	if (bltest.options[opt_IV].activated) {
-	    if (bltest.options[opt_CmdLine].activated) {
-		ivstr = bltest.options[opt_IV].arg;
-	    } else {
-		file = PR_Open(bltest.options[opt_IV].arg, PR_RDONLY, 00660);
-	    }
-	} else {
-	    /* save the random iv for reference */
-	    file = PR_Open("tmp.iv", PR_WRONLY|PR_CREATE_FILE, 00660);
-	}
-	memset(&skp->iv, 0, sizeof skp->iv);
-	skp->iv.mode = ioMode;
-	setupIO(cipherInfo.arena, &skp->iv, file, ivstr, keysize);
-	if (file)
-	    PR_Close(file);
-    }
-
-    if (bltest.commands[cmd_Verify].activated) {
-	if (!bltest.options[opt_SigFile].activated) {
-	    fprintf(stderr, "%s: You must specify a signature file with -f.\n",
-	            progName);
-	    exit(-1);
-	}
-	file = PR_Open(bltest.options[opt_SigFile].arg, PR_RDONLY, 00660);
-	if (cipherInfo.mode == bltestDSA) {
-	    memset(&cipherInfo.params.dsa.sig, 0, sizeof(bltestIO));
-	    cipherInfo.params.dsa.sig.mode = ioMode;
-	    setupIO(cipherInfo.arena, &cipherInfo.params.dsa.sig, file, NULL, 0);
-#ifdef NSS_ENABLE_ECC
-	} else if (cipherInfo.mode == bltestECDSA) {
-	    memset(&cipherInfo.params.ecdsa.sig, 0, sizeof(bltestIO));
-	    cipherInfo.params.ecdsa.sig.mode = ioMode;
-	    setupIO(cipherInfo.arena, &cipherInfo.params.ecdsa.sig, file, NULL, 0);
-#endif
-	}
+    if (bltest.options[opt_MonteCarlo].activated) {
+        cipherInfo->mCarlo = PR_TRUE;
+    } else {
+        cipherInfo->mCarlo = PR_FALSE;
     }
 
-    if (bltest.options[opt_PQGFile].activated) {
-	file = PR_Open(bltest.options[opt_PQGFile].arg, PR_RDONLY, 00660);
-	params->dsa.pqgdata.mode = bltestBase64Encoded;
-	setupIO(cipherInfo.arena, &params->dsa.pqgdata, file, NULL, 0);
+    for (curThrdNum = 0;curThrdNum < threads;curThrdNum++) {
+        int            keysize = 0;
+        PRFileDesc     *file = NULL, *infile;
+        bltestParams   *params;
+        char           *instr = NULL;
+        PRArenaPool    *arena;
+
+        if (curThrdNum > 0) {
+            bltestCipherInfo *newCInfo = PORT_ZNew(bltestCipherInfo);
+            if (!newCInfo) {
+                fprintf(stderr, "%s: Can not allocate  memory.\n", progName);
+                goto exit_point;
+            }
+            newCInfo->mode = cipherInfo->mode;
+            newCInfo->mCarlo = cipherInfo->mCarlo;
+            newCInfo->repetitionsToPerfom =
+                cipherInfo->repetitionsToPerfom;
+            newCInfo->seconds = cipherInfo->seconds;
+            newCInfo->cxreps = cipherInfo->cxreps;
+            cipherInfo->next = newCInfo;
+            cipherInfo = newCInfo;
+        }
+        arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
+        if (!arena) {
+            fprintf(stderr, "%s: Can not allocate memory.\n", progName);
+            goto exit_point;
+        }
+        cipherInfo->arena = arena;
+        params = &cipherInfo->params;
+        
+        /* Set up an encryption key. */
+        keysize = 0;
+        file = NULL;
+        if (is_symmkeyCipher(cipherInfo->mode)) {
+            char *keystr = NULL;  /* if key is on command line */
+            if (bltest.options[opt_Key].activated) {
+                if (bltest.options[opt_CmdLine].activated) {
+                    keystr = bltest.options[opt_Key].arg;
+                } else {
+                    file = PR_Open(bltest.options[opt_Key].arg,
+                                   PR_RDONLY, 00660);
+                }
+            } else {
+                if (bltest.options[opt_KeySize].activated)
+                    keysize = PORT_Atoi(bltest.options[opt_KeySize].arg);
+                else
+                    keysize = 8; /* use 64-bit default (DES) */
+                /* save the random key for reference */
+                file = PR_Open("tmp.key", PR_WRONLY|PR_CREATE_FILE, 00660);
+            }
+            params->key.mode = ioMode;
+            setupIO(cipherInfo->arena, &params->key, file, keystr, keysize);
+            if (file)
+                PR_Close(file);
+        } else if (is_pubkeyCipher(cipherInfo->mode)) {
+            if (bltest.options[opt_Key].activated) {
+                file = PR_Open(bltest.options[opt_Key].arg, PR_RDONLY, 00660);
+            } else {
+                if (bltest.options[opt_KeySize].activated)
+                    keysize = PORT_Atoi(bltest.options[opt_KeySize].arg);
+                else
+                    keysize = 64; /* use 512-bit default */
+                file = PR_Open("tmp.key", PR_WRONLY|PR_CREATE_FILE, 00660);
+            }
+            params->key.mode = bltestBase64Encoded;
+#ifdef NSS_ENABLE_ECC
+            pubkeyInitKey(cipherInfo, file, keysize, exponent, curveName);
+#else
+            pubkeyInitKey(cipherInfo, file, keysize, exponent);
+#endif
+            PR_Close(file);
+        }
+
+        /* set up an initialization vector. */
+        if (cipher_requires_IV(cipherInfo->mode)) {
+            char *ivstr = NULL;
+            bltestSymmKeyParams *skp;
+            file = NULL;
+            if (cipherInfo->mode == bltestRC5_CBC)
+                skp = (bltestSymmKeyParams *)&params->rc5;
+            else
+                skp = &params->sk;
+            if (bltest.options[opt_IV].activated) {
+                if (bltest.options[opt_CmdLine].activated) {
+                    ivstr = bltest.options[opt_IV].arg;
+                } else {
+                    file = PR_Open(bltest.options[opt_IV].arg,
+                                   PR_RDONLY, 00660);
+                }
+            } else {
+                /* save the random iv for reference */
+                file = PR_Open("tmp.iv", PR_WRONLY|PR_CREATE_FILE, 00660);
+            }
+            memset(&skp->iv, 0, sizeof skp->iv);
+            skp->iv.mode = ioMode;
+            setupIO(cipherInfo->arena, &skp->iv, file, ivstr, keysize);
+            if (file) {
+                PR_Close(file);
+            }
+        }
+        
+        if (bltest.commands[cmd_Verify].activated) {
+            file = PR_Open(bltest.options[opt_SigFile].arg, PR_RDONLY, 00660);
+            if (cipherInfo->mode == bltestDSA) {
+                memset(&cipherInfo->params.dsa.sig, 0, sizeof(bltestIO));
+                cipherInfo->params.dsa.sig.mode = ioMode;
+                setupIO(cipherInfo->arena, &cipherInfo->params.dsa.sig,
+                        file, NULL, 0);
+#ifdef NSS_ENABLE_ECC
+            } else if (cipherInfo->mode == bltestECDSA) {
+                memset(&cipherInfo->params.ecdsa.sig, 0, sizeof(bltestIO));
+                cipherInfo->params.ecdsa.sig.mode = ioMode;
+                setupIO(cipherInfo->arena, &cipherInfo->params.ecdsa.sig,
+                        file, NULL, 0);
+#endif
+            }
+            if (file) {
+                PR_Close(file);
+            }
+        }
+        
+        if (bltest.options[opt_PQGFile].activated) {
+            file = PR_Open(bltest.options[opt_PQGFile].arg, PR_RDONLY, 00660);
+            params->dsa.pqgdata.mode = bltestBase64Encoded;
+            setupIO(cipherInfo->arena, &params->dsa.pqgdata, file, NULL, 0);
+            if (file) {
+                PR_Close(file);
+            }
+        }
+
+        /* Set up the input buffer */
+        if (bltest.options[opt_Input].activated) {
+            if (bltest.options[opt_CmdLine].activated) {
+                instr = bltest.options[opt_Input].arg;
+                infile = NULL;
+            } else {
+                /* form file name from testdir and input arg. */
+                char * filename = bltest.options[opt_Input].arg;
+                if (bltest.options[opt_SelfTestDir].activated && 
+                    testdir && filename && filename[0] != '/') {
+                    filename = PR_smprintf("%s/tests/%s/%s", testdir, 
+                                           mode_strings[cipherInfo->mode],
+                                           filename);
+                    if (!filename) {
+                        fprintf(stderr, "%s: Can not allocate memory.\n",
+                                progName);
+                        goto exit_point;
+                    }
+                    infile = PR_Open(filename, PR_RDONLY, 00660);
+                    PR_smprintf_free(filename);
+                } else {
+                    infile = PR_Open(filename, PR_RDONLY, 00660);
+                }
+            }
+        } else if (bltest.options[opt_BufSize].activated) {
+            /* save the random plaintext for reference */
+            char *tmpFName = PR_smprintf("tmp.in.%d", curThrdNum);
+            if (!tmpFName) {
+                fprintf(stderr, "%s: Can not allocate memory.\n", progName);
+                goto exit_point;
+            }
+            infile = PR_Open(tmpFName, PR_WRONLY|PR_CREATE_FILE, 00660);
+            PR_smprintf_free(tmpFName);
+        } else {
+            infile = PR_STDIN;
+        }
+        if (!infile) {
+            fprintf(stderr, "%s: Failed to open input file.\n", progName);
+            goto exit_point;
+        }
+        cipherInfo->input.mode = ioMode;
+
+        /* Set up the output stream */
+        if (bltest.options[opt_Output].activated) {
+            /* form file name from testdir and input arg. */
+            char * filename = bltest.options[opt_Output].arg;
+            if (bltest.options[opt_SelfTestDir].activated && 
+                testdir && filename && filename[0] != '/') {
+                filename = PR_smprintf("%s/tests/%s/%s", testdir, 
+                                       mode_strings[cipherInfo->mode],
+                                       filename);
+                if (!filename) {
+                    fprintf(stderr, "%s: Can not allocate memory.\n", progName);
+                    goto exit_point;
+                }
+                outfile = PR_Open(filename, PR_WRONLY|PR_CREATE_FILE, 00660);
+                PR_smprintf_free(filename);
+            } else {
+                outfile = PR_Open(filename, PR_WRONLY|PR_CREATE_FILE, 00660);
+            }
+        } else {
+            outfile = PR_STDOUT;
+        }
+        if (!outfile) {
+            fprintf(stderr, "%s: Failed to open output file.\n", progName);
+            rv = SECFailure;
+            goto exit_point;
+        }
+        cipherInfo->output.mode = ioMode;
+        if (bltest.options[opt_SelfTestDir].activated && ioMode == bltestBinary)
+            cipherInfo->output.mode = bltestBase64Encoded;
+
+        if (is_hashCipher(cipherInfo->mode))
+            cipherInfo->params.hash.restart =
+                bltest.options[opt_Restart].activated;
+
+        bufsize = 0;
+        if (bltest.options[opt_BufSize].activated)
+            bufsize = PORT_Atoi(bltest.options[opt_BufSize].arg);
+
+        /*infile = NULL;*/
+        setupIO(cipherInfo->arena, &cipherInfo->input, infile, instr, bufsize);
+        if (infile && infile != PR_STDIN)
+            PR_Close(infile);
+        misalignBuffer(cipherInfo->arena, &cipherInfo->input, inoff);
+
+        cipherInit(cipherInfo, bltest.commands[cmd_Encrypt].activated);
+        misalignBuffer(cipherInfo->arena, &cipherInfo->output, outoff);
     }
 
-    /* Set up the input buffer */
-    if (bltest.options[opt_Input].activated) {
-	if (bltest.options[opt_CmdLine].activated) {
-	    instr = bltest.options[opt_Input].arg;
-	    infile = NULL;
-	} else {
-	    /* form file name from testdir and input arg. */
-	    char * filename = bltest.options[opt_Input].arg;
-	    if (bltest.options[opt_SelfTestDir].activated && 
-		testdir && filename && filename[0] != '/') 
-		filename = PR_smprintf("%s/tests/%s/%s", testdir, 
-		               mode_strings[cipherInfo.mode], filename);
-	    infile = PR_Open(filename, PR_RDONLY, 00660);
-	}
-    } else if (bltest.options[opt_BufSize].activated) {
-	/* save the random plaintext for reference */
-	infile = PR_Open("tmp.in", PR_WRONLY|PR_CREATE_FILE, 00660);
-    } else {
-	infile = PR_STDIN;
-    }
-    if (!infile) {
-        fprintf(stderr, "%s: Failed to open input file.\n", progName);
-	    exit(-1);
-    }
-    cipherInfo.input.mode = ioMode;
+    if (!bltest.commands[cmd_Nonce].activated) {
+        TIMESTART();
+        cipherInfo = cipherInfoListHead;
+        while (cipherInfo != NULL) {
+            cipherInfo->cipherThread = 
+                PR_CreateThread(PR_USER_THREAD,
+                                    ThreadExecTest,
+                                    cipherInfo,
+                                    PR_PRIORITY_NORMAL,
+                                    PR_GLOBAL_THREAD,
+                                    PR_JOINABLE_THREAD,
+                                    0);
+            cipherInfo = cipherInfo->next;
+        } 
 
-    /* Set up the output stream */
-    if (bltest.options[opt_Output].activated) {
-        /* form file name from testdir and input arg. */
-	char * filename = bltest.options[opt_Output].arg;
-	if (bltest.options[opt_SelfTestDir].activated && 
-	    testdir && filename && filename[0] != '/') 
-	    filename = PR_smprintf("%s/tests/%s/%s", testdir, 
-	               mode_strings[cipherInfo.mode], filename);
-	outfile = PR_Open(filename, PR_WRONLY|PR_CREATE_FILE, 00660);
-    } else {
-	outfile = PR_STDOUT;
-    }
-    if (!outfile) {
-        fprintf(stderr, "%s: Failed to open output file.\n", progName);
-	    exit(-1);
+        cipherInfo = cipherInfoListHead;
+        while (cipherInfo != NULL) {
+            PR_JoinThread(cipherInfo->cipherThread);
+            finishIO(&cipherInfo->output, outfile);
+            cipherInfo = cipherInfo->next;
+        }
+        TIMEFINISH(totalTime, 1);
     }
-    cipherInfo.output.mode = ioMode;
-    if (bltest.options[opt_SelfTestDir].activated && ioMode == bltestBinary)
-	cipherInfo.output.mode = bltestBase64Encoded;
-
-    if (is_hashCipher(cipherInfo.mode))
-	cipherInfo.params.hash.restart = bltest.options[opt_Restart].activated;
-
-    bufsize = 0;
-    if (bltest.options[opt_BufSize].activated)
-	bufsize = PORT_Atoi(bltest.options[opt_BufSize].arg);
-
-    /*infile = NULL;*/
-    setupIO(cipherInfo.arena, &cipherInfo.input, infile, instr, bufsize);
-    misalignBuffer(cipherInfo.arena, &cipherInfo.input, inoff);
-
-    cipherInit(&cipherInfo, bltest.commands[cmd_Encrypt].activated);
-    misalignBuffer(cipherInfo.arena, &cipherInfo.output, outoff);
+    
+    cipherInfo = cipherInfoListHead;
+    if (cipherInfo->repetitions > 0 || cipherInfo->cxreps > 0 ||
+        threads > 1)
+        dump_performance_info(cipherInfoListHead, totalTime,
+                              bltest.commands[cmd_Encrypt].activated,
+	                      (cipherInfo->repetitions == 0));
+    
+    rv = SECSuccess;
 
-    if (!bltest.commands[cmd_Nonce].activated) {
-	if (bltest.options[opt_MonteCarlo].activated) {
-	    int mciter;
-	    for (mciter=0; mciter<10000; mciter++) {
-		cipherDoOp(&cipherInfo);
-		memcpy(cipherInfo.input.buf.data,
-		       cipherInfo.output.buf.data,
-		       cipherInfo.input.buf.len);
-	    }
-	} else {
-	    cipherDoOp(&cipherInfo);
-	}
-	cipherFinish(&cipherInfo);
-	finishIO(&cipherInfo.output, outfile);
-    }
-
-    if (cipherInfo.repetitions > 0 || cipherInfo.cxreps > 0)
-	dump_performance_info(&cipherInfo, 
-	                      bltest.commands[cmd_Encrypt].activated,
-	                      (cipherInfo.repetitions == 0));
-
-    if (infile && infile != PR_STDIN)
-	PR_Close(infile);
+  exit_point:
     if (outfile && outfile != PR_STDOUT)
 	PR_Close(outfile);
-    PORT_FreeArena(cipherInfo.arena, PR_TRUE);
+    cipherInfo = cipherInfoListHead;
+    while (cipherInfo != NULL) {
+        bltestCipherInfo *tmpInfo = cipherInfo;
+
+        if (cipherInfo->arena)
+            PORT_FreeArena(cipherInfo->arena, PR_TRUE);
+        cipherInfo = cipherInfo->next;
+        PORT_Free(tmpInfo);
+    }
 
     /*NSS_Shutdown();*/
 
     return SECSuccess;
 }
--- a/security/nss/cmd/certutil/certutil.c
+++ b/security/nss/cmd/certutil/certutil.c
@@ -2477,18 +2477,23 @@ secuCommandFlag certutil_options[] =
 	    PR_fprintf(PR_STDERR, "%s -m:  %s is not a valid serial number.\n",
 	               progName, certutil.options[opt_SerialNumber].arg);
 	    return 255;
 	}
 	serialNumber = sn;
     }
 
     /*  -P certdb name prefix */
-    if (certutil.options[opt_DBPrefix].activated)
-	certPrefix = strdup(certutil.options[opt_DBPrefix].arg);
+    if (certutil.options[opt_DBPrefix].activated) {
+        if (certutil.options[opt_DBPrefix].arg) {
+            certPrefix = strdup(certutil.options[opt_DBPrefix].arg);
+        } else {
+            Usage(progName);
+        }
+    }
 
     /*  -q PQG file or curve name */
     if (certutil.options[opt_PQGFile].activated) {
 #ifdef NSS_ENABLE_ECC
 	if ((keytype != dsaKey) && (keytype != ecKey)) {
 	    PR_fprintf(PR_STDERR, "%s -q: specifies a PQG file for DSA keys" \
 		       " (-k dsa) or a named curve for EC keys (-k ec)\n)",
 	               progName);
--- a/security/nss/cmd/crlutil/crlgen.c
+++ b/security/nss/cmd/crlutil/crlgen.c
@@ -1357,22 +1357,22 @@ crlgen_setNextDataFn_extension(CRLGENGen
 
     PORT_Assert(crlGenData);
     if (!crlGenData) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
     }
 
     if (extStr->extData == NULL) {
-        extStr->extData = PORT_ZAlloc(MAX_EXT_DATA_LENGTH);
+        extStr->extData = PORT_ZNewArray(char *, MAX_EXT_DATA_LENGTH);
         if (!extStr->extData) {
             return SECFailure;
         }
     }
-    if (extStr->nextUpdatedData > MAX_EXT_DATA_LENGTH) {
+    if (extStr->nextUpdatedData >= MAX_EXT_DATA_LENGTH) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         crlgen_PrintError(crlGenData->parsedLineNum, 
                           "number of fields in extension "
                           "exceeded maximum allowed data length: %d.\n",
                           MAX_EXT_DATA_LENGTH);
         return SECFailure;
     }
     extStr->extData[extStr->nextUpdatedData] = PORT_Strdup(data);
@@ -1410,17 +1410,17 @@ crlgen_destroyTempData(CRLGENGeneratorDa
           case CRLGEN_RM_CERT_CONTEXT:
               if (crlGenData->certEntry->certId)
                   PORT_Free(crlGenData->certEntry->certId);
               if (crlGenData->certEntry->revocationTime)
                   PORT_Free(crlGenData->certEntry->revocationTime);
               PORT_Free(crlGenData->certEntry);
               break;
           case CRLGEN_ADD_EXTENSION_CONTEXT:
-              if (crlGenData->extensionEntry->nextUpdatedData) {
+              if (crlGenData->extensionEntry->extData) {
                   int i = 0;
                   for (;i < crlGenData->extensionEntry->nextUpdatedData;i++)
                       PORT_Free(*(crlGenData->extensionEntry->extData + i));
                   PORT_Free(crlGenData->extensionEntry->extData);
               }
               PORT_Free(crlGenData->extensionEntry);
               break;
         }
--- a/security/nss/cmd/rsaperf/rsaperf.c
+++ b/security/nss/cmd/rsaperf/rsaperf.c
@@ -44,17 +44,17 @@
 #include "lowkeyi.h"
 #include "pk11pub.h"
 
 
 #define DEFAULT_ITERS           10
 #define DEFAULT_DURATION        10
 #define DEFAULT_KEY_BITS        1024
 #define MIN_KEY_BITS            512
-#define MAX_KEY_BITS            8192
+#define MAX_KEY_BITS            65536
 #define BUFFER_BYTES            MAX_KEY_BITS / 8
 #define DEFAULT_THREADS         1
 #define DEFAULT_EXPONENT        0x10001
 
 extern NSSLOWKEYPrivateKey * getDefaultRSAPrivateKey(void);
 extern NSSLOWKEYPublicKey  * getDefaultRSAPublicKey(void);
 
 secuPWData pwData = { PW_NONE, NULL };
@@ -537,17 +537,17 @@ main(int argc, char **argv)
         fprintf(stderr,"\nGenerating RSA key. This may take a few moments.\n");
 
         privHighKey = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN,
                                            params, &pubHighKey, PR_FALSE,
                                            PR_FALSE, (void*)&pwData);
         if (!privHighKey) {
             fprintf(stderr,
                     "Key generation failed in token \"%s\"\n",
-                    PK11_GetTokenName(privHighKey->pkcs11Slot));
+                    PK11_GetTokenName(slot));
             exit(1);
         }
 
         SECKEY_CacheStaticFlags(privHighKey);
         
         fprintf(stderr,"Keygen completed.\n");
 
         if (doPub) {
--- a/security/nss/cmd/strsclnt/strsclnt.c
+++ b/security/nss/cmd/strsclnt/strsclnt.c
@@ -179,17 +179,19 @@ SECItem	bigBuf;
 static void
 Usage(const char *progName)
 {
     fprintf(stderr, 
     	"Usage: %s [-n nickname] [-p port] [-d dbdir] [-c connections]\n"
 	"          [-3DNTovq] [-2 filename]\n"
 	"          [-w dbpasswd] [-C cipher(s)] [-t threads] hostname\n"
 	" where -v means verbose\n"
-	"       -o means override server certificate validation\n"
+        "       -o flag is interpreted as follows:\n"
+        "          1 -o   means override the result of server certificate validation.\n"
+        "          2 -o's mean skip server certificate validation altogether.\n"
 	"       -D means no TCP delays\n"
 	"       -q means quit when server gone (timeout rather than retry forever)\n"
 	"       -N means no session reuse\n",
 	progName);
     exit(1);
 }
 
 
@@ -248,16 +250,19 @@ myGoodSSLAuthCertificate(void *arg, PRFi
 */
 static SECStatus
 mySSLAuthCertificate(void *arg, PRFileDesc *fd, PRBool checkSig,
 		     PRBool isServer)
 {
     SECStatus rv;
     CERTCertificate *    peerCert;
 
+    if (MakeCertOK>=2) {
+        return SECSuccess;
+    }
     peerCert = SSL_PeerCertificate(fd);
 
     PRINTF("strsclnt: Subject: %s\nstrsclnt: Issuer : %s\n", 
            peerCert->subjectName, peerCert->issuerName); 
     /* invoke the "default" AuthCert handler. */
     rv = SSL_AuthCertificate(arg, fd, checkSig, isServer);
 
     ++certsTested;
@@ -1226,17 +1231,17 @@ main(int argc, char **argv)
 	case 'T': disableTLS = PR_TRUE; break;
 
 	case 'c': connections = PORT_Atoi(optstate->value); break;
 
 	case 'd': dir = optstate->value; break;
 
         case 'n': nickName = PL_strdup(optstate->value); break;
 
-	case 'o': MakeCertOK = 1; break;
+	case 'o': MakeCertOK++; break;
 
 	case 'p': port = PORT_Atoi(optstate->value); break;
 
 	case 'q': QuitOnTimeout = PR_TRUE; break;
 
 	case 't':
 	    tmpInt = PORT_Atoi(optstate->value);
 	    if (tmpInt > 0 && tmpInt < MAX_THREADS) 
--- a/security/nss/cmd/zlib/README
+++ b/security/nss/cmd/zlib/README
@@ -1,45 +1,44 @@
 ZLIB DATA COMPRESSION LIBRARY
 
-zlib 1.2.2 is a general purpose data compression library.  All the code is
+zlib 1.2.3 is a general purpose data compression library.  All the code is
 thread safe.  The data format used by the zlib library is described by RFCs
 (Request for Comments) 1950 to 1952 in the files
 http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
 and rfc1952.txt (gzip format). These documents are also available in other
 formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
 
 All functions of the compression library are documented in the file zlib.h
 (volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
 of the library is given in the file example.c which also tests that the library
 is working correctly. Another example is given in the file minigzip.c. The
 compression library itself is composed of all source files except example.c and
 minigzip.c.
 
 To compile all files and run the test program, follow the instructions given at
 the top of Makefile. In short "make test; make install" should work for most
-machines. For Unix: "./configure; make test; make install" For MSDOS, use one
-of the special makefiles such as Makefile.msc. For VMS, use Make_vms.com or
-descrip.mms.
+machines. For Unix: "./configure; make test; make install". For MSDOS, use one
+of the special makefiles such as Makefile.msc. For VMS, use make_vms.com.
 
 Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
 <info@winimage.com> for the Windows DLL version. The zlib home page is
 http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem,
 please check this site to verify that you have the latest version of zlib;
 otherwise get the latest version and check whether the problem still exists or
 not.
 
 PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking
 for help.
 
 Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
 issue of  Dr. Dobb's Journal; a copy of the article is available in
 http://dogma.net/markn/articles/zlibtool/zlibtool.htm
 
-The changes made in version 1.2.2 are documented in the file ChangeLog.
+The changes made in version 1.2.3 are documented in the file ChangeLog.
 
 Unsupported third party contributions are provided in directory "contrib".
 
 A Java implementation of zlib is available in the Java Development Kit
 http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html
 See the zlib home page http://www.zlib.org for details.
 
 A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is in the
--- a/security/nss/cmd/zlib/adler32.c
+++ b/security/nss/cmd/zlib/adler32.c
@@ -1,28 +1,29 @@
 /* adler32.c -- compute the Adler-32 checksum of a data stream
- * Copyright (C) 1995-2003 Mark Adler
+ * Copyright (C) 1995-2004 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* @(#) $Id$ */
 
 #define ZLIB_INTERNAL
 #include "zlib.h"
 
 #define BASE 65521UL    /* largest prime smaller than 65536 */
 #define NMAX 5552
 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
 
-#define DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
+#define DO1(buf,i)  {adler += (buf)[i]; sum2 += adler;}
 #define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
 #define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
 #define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
 #define DO16(buf)   DO8(buf,0); DO8(buf,8);
 
+/* use NO_DIVIDE if your processor does not do division in hardware */
 #ifdef NO_DIVIDE
 #  define MOD(a) \
     do { \
         if (a >= (BASE << 16)) a -= (BASE << 16); \
         if (a >= (BASE << 15)) a -= (BASE << 15); \
         if (a >= (BASE << 14)) a -= (BASE << 14); \
         if (a >= (BASE << 13)) a -= (BASE << 13); \
         if (a >= (BASE << 12)) a -= (BASE << 12); \
@@ -34,41 +35,115 @@
         if (a >= (BASE << 6)) a -= (BASE << 6); \
         if (a >= (BASE << 5)) a -= (BASE << 5); \
         if (a >= (BASE << 4)) a -= (BASE << 4); \
         if (a >= (BASE << 3)) a -= (BASE << 3); \
         if (a >= (BASE << 2)) a -= (BASE << 2); \
         if (a >= (BASE << 1)) a -= (BASE << 1); \
         if (a >= BASE) a -= BASE; \
     } while (0)
+#  define MOD4(a) \
+    do { \
+        if (a >= (BASE << 4)) a -= (BASE << 4); \
+        if (a >= (BASE << 3)) a -= (BASE << 3); \
+        if (a >= (BASE << 2)) a -= (BASE << 2); \
+        if (a >= (BASE << 1)) a -= (BASE << 1); \
+        if (a >= BASE) a -= BASE; \
+    } while (0)
 #else
 #  define MOD(a) a %= BASE
+#  define MOD4(a) a %= BASE
 #endif
 
 /* ========================================================================= */
 uLong ZEXPORT adler32(adler, buf, len)
     uLong adler;
     const Bytef *buf;
     uInt len;
 {
-    unsigned long s1 = adler & 0xffff;
-    unsigned long s2 = (adler >> 16) & 0xffff;
-    int k;
+    unsigned long sum2;
+    unsigned n;
+
+    /* split Adler-32 into component sums */
+    sum2 = (adler >> 16) & 0xffff;
+    adler &= 0xffff;
+
+    /* in case user likes doing a byte at a time, keep it fast */
+    if (len == 1) {
+        adler += buf[0];
+        if (adler >= BASE)
+            adler -= BASE;
+        sum2 += adler;
+        if (sum2 >= BASE)
+            sum2 -= BASE;
+        return adler | (sum2 << 16);
+    }
+
+    /* initial Adler-32 value (deferred check for len == 1 speed) */
+    if (buf == Z_NULL)
+        return 1L;
 
-    if (buf == Z_NULL) return 1L;
+    /* in case short lengths are provided, keep it somewhat fast */
+    if (len < 16) {
+        while (len--) {
+            adler += *buf++;
+            sum2 += adler;
+        }
+        if (adler >= BASE)
+            adler -= BASE;
+        MOD4(sum2);             /* only added so many BASE's */
+        return adler | (sum2 << 16);
+    }
 
-    while (len > 0) {
-        k = len < NMAX ? (int)len : NMAX;
-        len -= k;
-        while (k >= 16) {
+    /* do length NMAX blocks -- requires just one modulo operation */
+    while (len >= NMAX) {
+        len -= NMAX;
+        n = NMAX / 16;          /* NMAX is divisible by 16 */
+        do {
+            DO16(buf);          /* 16 sums unrolled */
+            buf += 16;
+        } while (--n);
+        MOD(adler);
+        MOD(sum2);
+    }
+
+    /* do remaining bytes (less than NMAX, still just one modulo) */
+    if (len) {                  /* avoid modulos if none remaining */
+        while (len >= 16) {
+            len -= 16;
             DO16(buf);
             buf += 16;
-            k -= 16;
+        }
+        while (len--) {
+            adler += *buf++;
+            sum2 += adler;
         }
-        if (k != 0) do {
-            s1 += *buf++;
-            s2 += s1;
-        } while (--k);
-        MOD(s1);
-        MOD(s2);
+        MOD(adler);
+        MOD(sum2);
     }
-    return (s2 << 16) | s1;
+
+    /* return recombined sums */
+    return adler | (sum2 << 16);
 }
+
+/* ========================================================================= */
+uLong ZEXPORT adler32_combine(adler1, adler2, len2)
+    uLong adler1;
+    uLong adler2;
+    z_off_t len2;
+{
+    unsigned long sum1;
+    unsigned long sum2;
+    unsigned rem;
+
+    /* the derivation of this formula is left as an exercise for the reader */
+    rem = (unsigned)(len2 % BASE);
+    sum1 = adler1 & 0xffff;
+    sum2 = rem * sum1;
+    MOD(sum2);
+    sum1 += (adler2 & 0xffff) + BASE - 1;
+    sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
+    if (sum1 > BASE) sum1 -= BASE;
+    if (sum1 > BASE) sum1 -= BASE;
+    if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
+    if (sum2 > BASE) sum2 -= BASE;
+    return sum1 | (sum2 << 16);
+}
--- a/security/nss/cmd/zlib/compress.c
+++ b/security/nss/cmd/zlib/compress.c
@@ -1,10 +1,10 @@
 /* compress.c -- compress a memory buffer
- * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* @(#) $Id$ */
 
 #define ZLIB_INTERNAL
 #include "zlib.h"
 
--- a/security/nss/cmd/zlib/crc32.c
+++ b/security/nss/cmd/zlib/crc32.c
@@ -1,17 +1,17 @@
 /* crc32.c -- compute the CRC-32 of a data stream
- * Copyright (C) 1995-2003 Mark Adler
+ * Copyright (C) 1995-2005 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  *
  * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
  * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
  * tables for updating the shift register in one step with three exclusive-ors
- * instead of four steps with four exclusive-ors.  This results about a factor
- * of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
+ * instead of four steps with four exclusive-ors.  This results in about a
+ * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
  */
 
 /* @(#) $Id$ */
 
 /*
   Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
   protection on the static variables used to control the first-use generation
   of the crc tables.  Therefore, if you #define DYNAMIC_CRC_TABLE, you should
@@ -59,25 +59,29 @@
                         const unsigned char FAR *, unsigned));
    local unsigned long crc32_big OF((unsigned long,
                         const unsigned char FAR *, unsigned));
 #  define TBLS 8
 #else
 #  define TBLS 1
 #endif /* BYFOUR */
 
+/* Local functions for crc concatenation */
+local unsigned long gf2_matrix_times OF((unsigned long *mat,
+                                         unsigned long vec));
+local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
+
 #ifdef DYNAMIC_CRC_TABLE
 
 local volatile int crc_table_empty = 1;
 local unsigned long FAR crc_table[TBLS][256];
 local void make_crc_table OF((void));
 #ifdef MAKECRCH
    local void write_table OF((FILE *, const unsigned long FAR *));
 #endif /* MAKECRCH */
-
 /*
   Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
   x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
 
   Polynomials over GF(2) are represented in binary, one bit per coefficient,
   with the lowest powers in the most significant bit.  Then adding polynomials
   is just exclusive-or, and multiplying a polynomial by x is a right shift by
   one.  If we call the above polynomial p, and represent a byte as the
@@ -265,17 +269,17 @@ local unsigned long crc32_little(crc, bu
 
     c = (u4)crc;
     c = ~c;
     while (len && ((ptrdiff_t)buf & 3)) {
         c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
         len--;
     }
 
-    buf4 = (const u4 FAR *)buf;
+    buf4 = (const u4 FAR *)(const void FAR *)buf;
     while (len >= 32) {
         DOLIT32;
         len -= 32;
     }
     while (len >= 4) {
         DOLIT4;
         len -= 4;
     }
@@ -305,17 +309,17 @@ local unsigned long crc32_big(crc, buf, 
 
     c = REV((u4)crc);
     c = ~c;
     while (len && ((ptrdiff_t)buf & 3)) {
         c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
         len--;
     }
 
-    buf4 = (const u4 FAR *)buf;
+    buf4 = (const u4 FAR *)(const void FAR *)buf;
     buf4--;
     while (len >= 32) {
         DOBIG32;
         len -= 32;
     }
     while (len >= 4) {
         DOBIG4;
         len -= 4;
@@ -326,8 +330,94 @@ local unsigned long crc32_big(crc, buf, 
     if (len) do {
         c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
     } while (--len);
     c = ~c;
     return (unsigned long)(REV(c));
 }
 
 #endif /* BYFOUR */
+
+#define GF2_DIM 32      /* dimension of GF(2) vectors (length of CRC) */
+
+/* ========================================================================= */
+local unsigned long gf2_matrix_times(mat, vec)
+    unsigned long *mat;
+    unsigned long vec;
+{
+    unsigned long sum;
+
+    sum = 0;
+    while (vec) {
+        if (vec & 1)
+            sum ^= *mat;
+        vec >>= 1;
+        mat++;
+    }
+    return sum;
+}
+
+/* ========================================================================= */
+local void gf2_matrix_square(square, mat)
+    unsigned long *square;
+    unsigned long *mat;
+{
+    int n;
+
+    for (n = 0; n < GF2_DIM; n++)
+        square[n] = gf2_matrix_times(mat, mat[n]);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine(crc1, crc2, len2)
+    uLong crc1;
+    uLong crc2;
+    z_off_t len2;
+{
+    int n;
+    unsigned long row;
+    unsigned long even[GF2_DIM];    /* even-power-of-two zeros operator */
+    unsigned long odd[GF2_DIM];     /* odd-power-of-two zeros operator */
+
+    /* degenerate case */
+    if (len2 == 0)
+        return crc1;
+
+    /* put operator for one zero bit in odd */
+    odd[0] = 0xedb88320L;           /* CRC-32 polynomial */
+    row = 1;
+    for (n = 1; n < GF2_DIM; n++) {
+        odd[n] = row;
+        row <<= 1;
+    }
+
+    /* put operator for two zero bits in even */
+    gf2_matrix_square(even, odd);
+
+    /* put operator for four zero bits in odd */
+    gf2_matrix_square(odd, even);
+
+    /* apply len2 zeros to crc1 (first square will put the operator for one
+       zero byte, eight zero bits, in even) */
+    do {
+        /* apply zeros operator for this bit of len2 */
+        gf2_matrix_square(even, odd);
+        if (len2 & 1)
+            crc1 = gf2_matrix_times(even, crc1);
+        len2 >>= 1;
+
+        /* if no more bits set, then done */
+        if (len2 == 0)
+            break;
+
+        /* another iteration of the loop with odd and even swapped */
+        gf2_matrix_square(odd, even);
+        if (len2 & 1)
+            crc1 = gf2_matrix_times(odd, crc1);
+        len2 >>= 1;
+
+        /* if no more bits set, then done */
+    } while (len2 != 0);
+
+    /* return combined crc */
+    crc1 ^= crc2;
+    return crc1;
+}
--- a/security/nss/cmd/zlib/deflate.c
+++ b/security/nss/cmd/zlib/deflate.c
@@ -1,10 +1,10 @@
 /* deflate.c -- compress data using the deflation algorithm
- * Copyright (C) 1995-2004 Jean-loup Gailly.
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /*
  *  ALGORITHM
  *
  *      The "deflation" process depends on being able to identify portions
  *      of the input text which are identical to earlier input (within a
@@ -47,17 +47,17 @@
  *
  */
 
 /* @(#) $Id$ */
 
 #include "deflate.h"
 
 const char deflate_copyright[] =
-   " deflate 1.2.2 Copyright 1995-2004 Jean-loup Gailly ";
+   " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly ";
 /*
   If you use the zlib library in a product, an acknowledgment is welcome
   in the documentation of your product. If for some reason you cannot
   include such an acknowledgment, I would appreciate that you keep this
   copyright string in the executable of your product.
  */
 
 /* ===========================================================================
@@ -259,26 +259,27 @@ int ZEXPORT deflateInit2_(strm, level, m
 #ifdef GZIP
     else if (windowBits > 15) {
         wrap = 2;       /* write gzip wrapper instead */
         windowBits -= 16;
     }
 #endif
     if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
         windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
-        strategy < 0 || strategy > Z_RLE) {
+        strategy < 0 || strategy > Z_FIXED) {
         return Z_STREAM_ERROR;
     }
     if (windowBits == 8) windowBits = 9;  /* until 256-byte window bug fixed */
     s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
     if (s == Z_NULL) return Z_MEM_ERROR;
     strm->state = (struct internal_state FAR *)s;
     s->strm = strm;
 
     s->wrap = wrap;
+    s->gzhead = Z_NULL;
     s->w_bits = windowBits;
     s->w_size = 1 << s->w_bits;
     s->w_mask = s->w_size - 1;
 
     s->hash_bits = memLevel + 7;
     s->hash_size = 1 << s->hash_bits;
     s->hash_mask = s->hash_size - 1;
     s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
@@ -328,19 +329,17 @@ int ZEXPORT deflateSetDictionary (strm, 
 
     s = strm->state;
     if (s->wrap)
         strm->adler = adler32(strm->adler, dictionary, dictLength);
 
     if (length < MIN_MATCH) return Z_OK;
     if (length > MAX_DIST(s)) {
         length = MAX_DIST(s);
-#ifndef USE_DICT_HEAD
         dictionary += dictLength - length; /* use the tail of the dictionary */
-#endif
     }
     zmemcpy(s->window, dictionary, length);
     s->strstart = length;
     s->block_start = (long)length;
 
     /* Insert all strings in the hash table (except for the last two bytes).
      * s->lookahead stays null, so s->ins_h will be recomputed at the next
      * call of fill_window.
@@ -386,16 +385,27 @@ int ZEXPORT deflateReset (strm)
 
     _tr_init(s);
     lm_init(s);
 
     return Z_OK;
 }
 
 /* ========================================================================= */
+int ZEXPORT deflateSetHeader (strm, head)
+    z_streamp strm;
+    gz_headerp head;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    if (strm->state->wrap != 2) return Z_STREAM_ERROR;
+    strm->state->gzhead = head;
+    return Z_OK;
+}
+
+/* ========================================================================= */
 int ZEXPORT deflatePrime (strm, bits, value)
     z_streamp strm;
     int bits;
     int value;
 {
     if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
     strm->state->bi_valid = bits;
     strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
@@ -415,17 +425,17 @@ int ZEXPORT deflateParams(strm, level, s
     if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
     s = strm->state;
 
 #ifdef FASTEST
     if (level != 0) level = 1;
 #else
     if (level == Z_DEFAULT_COMPRESSION) level = 6;
 #endif
-    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_RLE) {
+    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
         return Z_STREAM_ERROR;
     }
     func = configuration_table[s->level].func;
 
     if (func != configuration_table[level].func && strm->total_in != 0) {
         /* Flush the last buffer: */
         err = deflate(strm, Z_PARTIAL_FLUSH);
     }
@@ -435,16 +445,35 @@ int ZEXPORT deflateParams(strm, level, s
         s->good_match       = configuration_table[level].good_length;
         s->nice_match       = configuration_table[level].nice_length;
         s->max_chain_length = configuration_table[level].max_chain;
     }
     s->strategy = strategy;
     return err;
 }
 
+/* ========================================================================= */
+int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
+    z_streamp strm;
+    int good_length;
+    int max_lazy;
+    int nice_length;
+    int max_chain;
+{
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = strm->state;
+    s->good_match = good_length;
+    s->max_lazy_match = max_lazy;
+    s->nice_match = nice_length;
+    s->max_chain_length = max_chain;
+    return Z_OK;
+}
+
 /* =========================================================================
  * For the default windowBits of 15 and memLevel of 8, this function returns
  * a close to exact, as well as small, upper bound on the compressed size.
  * They are coded as constants here for a reason--if the #define's are
  * changed, then this function needs to be changed as well.  The return
  * value for 15 and 8 only works for those exact settings.
  *
  * For any setting other than those defaults for windowBits and memLevel,
@@ -543,30 +572,57 @@ int ZEXPORT deflate (strm, flush)
     s->strm = strm; /* just in case */
     old_flush = s->last_flush;
     s->last_flush = flush;
 
     /* Write the header */
     if (s->status == INIT_STATE) {
 #ifdef GZIP
         if (s->wrap == 2) {
+            strm->adler = crc32(0L, Z_NULL, 0);
             put_byte(s, 31);
             put_byte(s, 139);
             put_byte(s, 8);
-            put_byte(s, 0);
-            put_byte(s, 0);
-            put_byte(s, 0);
-            put_byte(s, 0);
-            put_byte(s, 0);
-            put_byte(s, s->level == 9 ? 2 :
-                        (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
-                         4 : 0));
-            put_byte(s, 255);
-            s->status = BUSY_STATE;
-            strm->adler = crc32(0L, Z_NULL, 0);
+            if (s->gzhead == NULL) {
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, s->level == 9 ? 2 :
+                            (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+                             4 : 0));
+                put_byte(s, OS_CODE);
+                s->status = BUSY_STATE;
+            }
+            else {
+                put_byte(s, (s->gzhead->text ? 1 : 0) +
+                            (s->gzhead->hcrc ? 2 : 0) +
+                            (s->gzhead->extra == Z_NULL ? 0 : 4) +
+                            (s->gzhead->name == Z_NULL ? 0 : 8) +
+                            (s->gzhead->comment == Z_NULL ? 0 : 16)
+                        );
+                put_byte(s, (Byte)(s->gzhead->time & 0xff));
+                put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
+                put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
+                put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
+                put_byte(s, s->level == 9 ? 2 :
+                            (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+                             4 : 0));
+                put_byte(s, s->gzhead->os & 0xff);
+                if (s->gzhead->extra != NULL) {
+                    put_byte(s, s->gzhead->extra_len & 0xff);
+                    put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
+                }
+                if (s->gzhead->hcrc)
+                    strm->adler = crc32(strm->adler, s->pending_buf,
+                                        s->pending);
+                s->gzindex = 0;
+                s->status = EXTRA_STATE;
+            }
         }
         else
 #endif
         {
             uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
             uInt level_flags;
 
             if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
@@ -587,16 +643,120 @@ int ZEXPORT deflate (strm, flush)
             /* Save the adler32 of the preset dictionary: */
             if (s->strstart != 0) {
                 putShortMSB(s, (uInt)(strm->adler >> 16));
                 putShortMSB(s, (uInt)(strm->adler & 0xffff));
             }
             strm->adler = adler32(0L, Z_NULL, 0);
         }
     }
+#ifdef GZIP
+    if (s->status == EXTRA_STATE) {
+        if (s->gzhead->extra != NULL) {
+            uInt beg = s->pending;  /* start of bytes to update crc */
+
+            while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
+                if (s->pending == s->pending_buf_size) {
+                    if (s->gzhead->hcrc && s->pending > beg)
+                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                            s->pending - beg);
+                    flush_pending(strm);
+                    beg = s->pending;
+                    if (s->pending == s->pending_buf_size)
+                        break;
+                }
+                put_byte(s, s->gzhead->extra[s->gzindex]);
+                s->gzindex++;
+            }
+            if (s->gzhead->hcrc && s->pending > beg)
+                strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                    s->pending - beg);
+            if (s->gzindex == s->gzhead->extra_len) {
+                s->gzindex = 0;
+                s->status = NAME_STATE;
+            }
+        }
+        else
+            s->status = NAME_STATE;
+    }
+    if (s->status == NAME_STATE) {
+        if (s->gzhead->name != NULL) {
+            uInt beg = s->pending;  /* start of bytes to update crc */
+            int val;
+
+            do {
+                if (s->pending == s->pending_buf_size) {
+                    if (s->gzhead->hcrc && s->pending > beg)
+                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                            s->pending - beg);
+                    flush_pending(strm);
+                    beg = s->pending;
+                    if (s->pending == s->pending_buf_size) {
+                        val = 1;
+                        break;
+                    }
+                }
+                val = s->gzhead->name[s->gzindex++];
+                put_byte(s, val);
+            } while (val != 0);
+            if (s->gzhead->hcrc && s->pending > beg)
+                strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                    s->pending - beg);
+            if (val == 0) {
+                s->gzindex = 0;
+                s->status = COMMENT_STATE;
+            }
+        }
+        else
+            s->status = COMMENT_STATE;
+    }
+    if (s->status == COMMENT_STATE) {
+        if (s->gzhead->comment != NULL) {
+            uInt beg = s->pending;  /* start of bytes to update crc */
+            int val;
+
+            do {
+                if (s->pending == s->pending_buf_size) {
+                    if (s->gzhead->hcrc && s->pending > beg)
+                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                            s->pending - beg);
+                    flush_pending(strm);
+                    beg = s->pending;
+                    if (s->pending == s->pending_buf_size) {
+                        val = 1;
+                        break;
+                    }
+                }
+                val = s->gzhead->comment[s->gzindex++];
+                put_byte(s, val);
+            } while (val != 0);
+            if (s->gzhead->hcrc && s->pending > beg)
+                strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                    s->pending - beg);
+            if (val == 0)
+                s->status = HCRC_STATE;
+        }
+        else
+            s->status = HCRC_STATE;
+    }
+    if (s->status == HCRC_STATE) {
+        if (s->gzhead->hcrc) {
+            if (s->pending + 2 > s->pending_buf_size)
+                flush_pending(strm);
+            if (s->pending + 2 <= s->pending_buf_size) {
+                put_byte(s, (Byte)(strm->adler & 0xff));
+                put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+                strm->adler = crc32(0L, Z_NULL, 0);
+                s->status = BUSY_STATE;
+            }
+        }
+        else
+            s->status = BUSY_STATE;
+    }
+#endif
 
     /* Flush as much pending output as possible */
     if (s->pending != 0) {
         flush_pending(strm);
         if (strm->avail_out == 0) {
             /* Since avail_out is 0, deflate will be called again with
              * more output space, but possibly with both pending and
              * avail_in equal to zero. There won't be anything to do,
@@ -699,17 +859,22 @@ int ZEXPORT deflate (strm, flush)
 int ZEXPORT deflateEnd (strm)
     z_streamp strm;
 {
     int status;
 
     if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
 
     status = strm->state->status;
-    if (status != INIT_STATE && status != BUSY_STATE &&
+    if (status != INIT_STATE &&
+        status != EXTRA_STATE &&
+        status != NAME_STATE &&
+        status != COMMENT_STATE &&
+        status != HCRC_STATE &&
+        status != BUSY_STATE &&
         status != FINISH_STATE) {
       return Z_STREAM_ERROR;
     }
 
     /* Deallocate in reverse order of allocations: */
     TRY_FREE(strm, strm->state->pending_buf);
     TRY_FREE(strm, strm->state->head);
     TRY_FREE(strm, strm->state->prev);
@@ -739,22 +904,22 @@ int ZEXPORT deflateCopy (dest, source)
 
 
     if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
         return Z_STREAM_ERROR;
     }
 
     ss = source->state;
 
-    *dest = *source;
+    zmemcpy(dest, source, sizeof(z_stream));
 
     ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
     if (ds == Z_NULL) return Z_MEM_ERROR;
     dest->state = (struct internal_state FAR *) ds;
-    *ds = *ss;
+    zmemcpy(ds, ss, sizeof(deflate_state));
     ds->strm = dest;
 
     ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
     ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
     ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
     overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
     ds->pending_buf = (uchf *) overlay;
 
@@ -833,19 +998,21 @@ local void lm_init (s)
     s->max_chain_length = configuration_table[s->level].max_chain;
 
     s->strstart = 0;
     s->block_start = 0L;
     s->lookahead = 0;
     s->match_length = s->prev_length = MIN_MATCH-1;
     s->match_available = 0;
     s->ins_h = 0;
+#ifndef FASTEST
 #ifdef ASMV
     match_init(); /* initialize the asm code */
 #endif
+#endif
 }
 
 #ifndef FASTEST
 /* ===========================================================================
  * Set match_start to the longest match starting at the given string and
  * return its length. Matches shorter or equal to prev_length are discarded,
  * in which case the result is equal to prev_length and match_start is
  * garbage.
@@ -904,17 +1071,22 @@ local uInt longest_match(s, cur_match)
 
     Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
 
     do {
         Assert(cur_match < s->strstart, "no future");
         match = s->window + cur_match;
 
         /* Skip to next match if the match length cannot increase
-         * or if the match length is less than 2:
+         * or if the match length is less than 2.  Note that the checks below
+         * for insufficient lookahead only occur occasionally for performance
+         * reasons.  Therefore uninitialized memory will be accessed, and
+         * conditional jumps will be made that depend on those values.
+         * However the length of the match is limited to the lookahead, so
+         * the output of deflate is not affected by the uninitialized values.
          */
 #if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
         /* This code assumes sizeof(unsigned short) == 2. Do not use
          * UNALIGNED_OK if your compiler uses a different size.
          */
         if (*(ushf*)(match+best_len-1) != scan_end ||
             *(ushf*)match != scan_start) continue;
 
@@ -1126,16 +1298,17 @@ local void fill_window(s)
             s->block_start -= (long) wsize;
 
             /* Slide the hash table (could be avoided with 32 bit values
                at the expense of memory usage). We slide even when level == 0
                to keep the hash table consistent if we switch back to level > 0
                later. (Using level 0 permanently is not an optimal usage of
                zlib, so we don't care about this pathological case.)
              */
+            /* %%% avoid this when Z_RLE */
             n = s->hash_size;
             p = &s->head[n];
             do {
                 m = *--p;
                 *p = (Pos)(m >= wsize ? m-wsize : NIL);
             } while (--n);
 
             n = wsize;
@@ -1304,22 +1477,22 @@ local block_state deflate_fast(s, flush)
          * At this point we have always match_length < MIN_MATCH
          */
         if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
             /* To simplify the code, we prevent matches with the string
              * of window index 0 (in particular we have to avoid a match
              * of the string with itself at the start of the input file).
              */
 #ifdef FASTEST
-            if ((s->strategy < Z_HUFFMAN_ONLY) ||
+            if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) ||
                 (s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
                 s->match_length = longest_match_fast (s, hash_head);
             }
 #else
-            if (s->strategy < Z_HUFFMAN_ONLY) {
+            if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
                 s->match_length = longest_match (s, hash_head);
             } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
                 s->match_length = longest_match_fast (s, hash_head);
             }
 #endif
             /* longest_match() or longest_match_fast() sets match_start */
         }
         if (s->match_length >= MIN_MATCH) {
@@ -1413,17 +1586,17 @@ local block_state deflate_slow(s, flush)
         s->match_length = MIN_MATCH-1;
 
         if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
             s->strstart - hash_head <= MAX_DIST(s)) {
             /* To simplify the code, we prevent matches with the string
              * of window index 0 (in particular we have to avoid a match
              * of the string with itself at the start of the input file).
              */
-            if (s->strategy < Z_HUFFMAN_ONLY) {
+            if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
                 s->match_length = longest_match (s, hash_head);
             } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
                 s->match_length = longest_match_fast (s, hash_head);
             }
             /* longest_match() or longest_match_fast() sets match_start */
 
             if (s->match_length <= 5 && (s->strategy == Z_FILTERED
 #if TOO_FAR <= 32767
@@ -1495,8 +1668,69 @@ local block_state deflate_slow(s, flush)
         Tracevv((stderr,"%c", s->window[s->strstart-1]));
         _tr_tally_lit(s, s->window[s->strstart-1], bflush);
         s->match_available = 0;
     }
     FLUSH_BLOCK(s, flush == Z_FINISH);
     return flush == Z_FINISH ? finish_done : block_done;
 }
 #endif /* FASTEST */
+
+#if 0
+/* ===========================================================================
+ * For Z_RLE, simply look for runs of bytes, generate matches only of distance
+ * one.  Do not maintain a hash table.  (It will be regenerated if this run of
+ * deflate switches away from Z_RLE.)
+ */
+local block_state deflate_rle(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    int bflush;         /* set if current block must be flushed */
+    uInt run;           /* length of run */
+    uInt max;           /* maximum length of run */
+    uInt prev;          /* byte at distance one to match */
+    Bytef *scan;        /* scan for end of run */
+
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the longest encodable run.
+         */
+        if (s->lookahead < MAX_MATCH) {
+            fill_window(s);
+            if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
+                return need_more;
+            }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* See how many times the previous byte repeats */
+        run = 0;
+        if (s->strstart > 0) {      /* if there is a previous byte, that is */
+            max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH;
+            scan = s->window + s->strstart - 1;
+            prev = *scan++;
+            do {
+                if (*scan++ != prev)
+                    break;
+            } while (++run < max);
+        }
+
+        /* Emit match if have run of MIN_MATCH or longer, else emit literal */
+        if (run >= MIN_MATCH) {
+            check_match(s, s->strstart, s->strstart - 1, run);
+            _tr_tally_dist(s, 1, run - MIN_MATCH, bflush);
+            s->lookahead -= run;
+            s->strstart += run;
+        } else {
+            /* No match, output a literal byte */
+            Tracevv((stderr,"%c", s->window[s->strstart]));
+            _tr_tally_lit (s, s->window[s->strstart], bflush);
+            s->lookahead--;
+            s->strstart++;
+        }
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+#endif
--- a/security/nss/cmd/zlib/deflate.h
+++ b/security/nss/cmd/zlib/deflate.h
@@ -1,10 +1,10 @@
 /* deflate.h -- internal compression state
- * Copyright (C) 1995-2002 Jean-loup Gailly
+ * Copyright (C) 1995-2004 Jean-loup Gailly
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* WARNING: this file should *not* be used by applications. It is
    part of the implementation of the compression library and is
    subject to change. Applications should only use zlib.h.
  */
 
@@ -44,16 +44,20 @@
 
 #define HEAP_SIZE (2*L_CODES+1)
 /* maximum heap size */
 
 #define MAX_BITS 15
 /* All codes must not exceed MAX_BITS bits */
 
 #define INIT_STATE    42
+#define EXTRA_STATE   69
+#define NAME_STATE    73
+#define COMMENT_STATE 91
+#define HCRC_STATE   103
 #define BUSY_STATE   113
 #define FINISH_STATE 666
 /* Stream status */
 
 
 /* Data structure describing a single value and its code string. */
 typedef struct ct_data_s {
     union {
@@ -88,18 +92,20 @@ typedef unsigned IPos;
  */
 
 typedef struct internal_state {
     z_streamp strm;      /* pointer back to this zlib stream */
     int   status;        /* as the name implies */
     Bytef *pending_buf;  /* output still pending */
     ulg   pending_buf_size; /* size of pending_buf */
     Bytef *pending_out;  /* next pending byte to output to the stream */
-    int   pending;       /* nb of bytes in the pending buffer */
+    uInt   pending;      /* nb of bytes in the pending buffer */
     int   wrap;          /* bit 0 true for zlib, bit 1 true for gzip */
+    gz_headerp  gzhead;  /* gzip header information to write */
+    uInt   gzindex;      /* where in extra, name, or comment */
     Byte  method;        /* STORED (for zip only) or DEFLATED */
     int   last_flush;    /* value of flush param for previous deflate call */
 
                 /* used by deflate.c: */
 
     uInt  w_size;        /* LZ77 window size (32K by default) */
     uInt  w_bits;        /* log2(w_size)  (8..16) */
     uInt  w_mask;        /* w_size - 1 */
--- a/security/nss/cmd/zlib/example.c
+++ b/security/nss/cmd/zlib/example.c
@@ -1,23 +1,21 @@
 /* example.c -- usage example of the zlib compression library
- * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * Copyright (C) 1995-2004 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* @(#) $Id$ */
 
 #include <stdio.h>
 #include "zlib.h"
 
 #ifdef STDC
 #  include <string.h>
 #  include <stdlib.h>
-#else
-   extern void exit  OF((int));
 #endif
 
 #if defined(VMS) || defined(RISCOS)
 #  define TESTFILE "foo-gz"
 #else
 #  define TESTFILE "foo.gz"
 #endif
 
--- a/security/nss/cmd/zlib/gzio.c
+++ b/security/nss/cmd/zlib/gzio.c
@@ -1,22 +1,22 @@
 /* gzio.c -- IO on .gz files
- * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h
  *
  * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
  */
 
 /* @(#) $Id$ */
 
 #include <stdio.h>
 
 #include "zutil.h"
 
-#ifdef NO_DEFLATE       /* for compatiblity with old definition */
+#ifdef NO_DEFLATE       /* for compatibility with old definition */
 #  define NO_GZCOMPRESS
 #endif
 
 #ifndef NO_DUMMY_DECL
 struct internal_state {int dummy;}; /* for buggy compilers */
 #endif
 
 #ifndef Z_BUFSIZE
@@ -215,17 +215,17 @@ gzFile ZEXPORT gzopen (path, mode)
 /* ===========================================================================
      Associate a gzFile with the file descriptor fd. fd is not dup'ed here
    to mimic the behavio(u)r of fdopen.
 */
 gzFile ZEXPORT gzdopen (fd, mode)
     int fd;
     const char *mode;
 {
-    char name[20];
+    char name[46];      /* allow for up to 128-bit integers */
 
     if (fd < 0) return (gzFile)Z_NULL;
     sprintf(name, "<fd:%d>", fd); /* for debugging */
 
     return gz_open (name, mode, fd);
 }
 
 /* ===========================================================================
@@ -259,17 +259,17 @@ int ZEXPORT gzsetparams (file, level, st
    IN assertion: the stream s has been sucessfully opened for reading.
 */
 local int get_byte(s)
     gz_stream *s;
 {
     if (s->z_eof) return EOF;
     if (s->stream.avail_in == 0) {
         errno = 0;
-        s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+        s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
         if (s->stream.avail_in == 0) {
             s->z_eof = 1;
             if (ferror(s->file)) s->z_err = Z_ERRNO;
             return EOF;
         }
         s->stream.next_in = s->inbuf;
     }
     s->stream.avail_in--;
@@ -295,17 +295,17 @@ local void check_header(s)
 
     /* Assure two bytes in the buffer so we can peek ahead -- handle case
        where first byte of header is at the end of the buffer after the last
        gzip segment */
     len = s->stream.avail_in;
     if (len < 2) {
         if (len) s->inbuf[0] = s->stream.next_in[0];
         errno = 0;
-        len = fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
+        len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
         if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
         s->stream.avail_in += len;
         s->stream.next_in = s->inbuf;
         if (s->stream.avail_in < 2) {
             s->transparent = s->stream.avail_in;
             return;
         }
     }
@@ -410,16 +410,17 @@ int ZEXPORT gzread (file, buf, len)
     s->stream.avail_out = len;
 
     if (s->stream.avail_out && s->back != EOF) {
         *next_out++ = s->back;
         s->stream.next_out++;
         s->stream.avail_out--;
         s->back = EOF;
         s->out++;
+        start++;
         if (s->last) {
             s->z_err = Z_STREAM_END;
             return 1;
         }
     }
 
     while (s->stream.avail_out != 0) {
 
@@ -431,39 +432,35 @@ int ZEXPORT gzread (file, buf, len)
                 zmemcpy(s->stream.next_out, s->stream.next_in, n);
                 next_out += n;
                 s->stream.next_out = next_out;
                 s->stream.next_in   += n;
                 s->stream.avail_out -= n;
                 s->stream.avail_in  -= n;
             }
             if (s->stream.avail_out > 0) {
-                s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out,
-                                             s->file);
+                s->stream.avail_out -=
+                    (uInt)fread(next_out, 1, s->stream.avail_out, s->file);
             }
             len -= s->stream.avail_out;
             s->in  += len;
             s->out += len;
             if (len == 0) s->z_eof = 1;
             return (int)len;
         }
         if (s->stream.avail_in == 0 && !s->z_eof) {
 
             errno = 0;
-            s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+            s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
             if (s->stream.avail_in == 0) {
                 s->z_eof = 1;
                 if (ferror(s->file)) {
                     s->z_err = Z_ERRNO;
                     break;
                 }
-                if (feof(s->file)) {        /* avoid error for empty file */
-                    s->z_err = Z_STREAM_END;
-                    break;
-                }
             }
             s->stream.next_in = s->inbuf;
         }
         s->in += s->stream.avail_in;
         s->out += s->stream.avail_out;
         s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
         s->in -= s->stream.avail_in;
         s->out -= s->stream.avail_out;
@@ -487,16 +484,19 @@ int ZEXPORT gzread (file, buf, len)
                     s->crc = crc32(0L, Z_NULL, 0);
                 }
             }
         }
         if (s->z_err != Z_OK || s->z_eof) break;
     }
     s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
 
+    if (len == s->stream.avail_out &&
+        (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO))
+        return -1;
     return (int)(len - s->stream.avail_out);
 }
 
 
 /* ===========================================================================
       Reads one byte from the compressed file. gzgetc returns this byte
    or -1 in case of end of file or error.
 */
@@ -898,16 +898,28 @@ int ZEXPORT gzeof (file)
      * on a gz_stream. Handle end-of-stream error explicitly here.
      */
     if (s == NULL || s->mode != 'r') return 0;
     if (s->z_eof) return 1;
     return s->z_err == Z_STREAM_END;
 }
 
 /* ===========================================================================
+     Returns 1 if reading and doing so transparently, otherwise zero.
+*/
+int ZEXPORT gzdirect (file)
+    gzFile file;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || s->mode != 'r') return 0;
+    return s->transparent;
+}
+
+/* ===========================================================================
    Outputs a long in LSB order to the given file
 */
 local void putLong (file, x)
     FILE *file;
     uLong x;
 {
     int n;
     for (n = 0; n < 4; n++) {
@@ -936,39 +948,44 @@ local uLong getLong (s)
 
 /* ===========================================================================
      Flushes all pending output if necessary, closes the compressed file
    and deallocates all the (de)compression state.
 */
 int ZEXPORT gzclose (file)
     gzFile file;
 {
-    int err;
     gz_stream *s = (gz_stream*)file;
 
     if (s == NULL) return Z_STREAM_ERROR;
 
     if (s->mode == 'w') {
 #ifdef NO_GZCOMPRESS
         return Z_STREAM_ERROR;
 #else
-        err = do_flush (file, Z_FINISH);
-        if (err != Z_OK) return destroy((gz_stream*)file);
+        if (do_flush (file, Z_FINISH) != Z_OK)
+            return destroy((gz_stream*)file);
 
         putLong (s->file, s->crc);
         putLong (s->file, (uLong)(s->in & 0xffffffff));
 #endif
     }
     return destroy((gz_stream*)file);
 }
 
+#ifdef STDC
+#  define zstrerror(errnum) strerror(errnum)
+#else
+#  define zstrerror(errnum) ""
+#endif
+
 /* ===========================================================================
-     Returns the error message for the last error which occured on the
+     Returns the error message for the last error which occurred on the
    given compressed file. errnum is set to zlib error number. If an
-   error occured in the file system and not in the compression library,
+   error occurred in the file system and not in the compression library,
    errnum is set to Z_ERRNO and the application may consult errno
    to get the exact error code.
 */
 const char * ZEXPORT gzerror (file, errnum)
     gzFile file;
     int *errnum;
 {
     char *m;
--- a/security/nss/cmd/zlib/infback.c
+++ b/security/nss/cmd/zlib/infback.c
@@ -1,10 +1,10 @@
 /* infback.c -- inflate using a call-back interface
- * Copyright (C) 1995-2003 Mark Adler
+ * Copyright (C) 1995-2005 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /*
    This code is largely copied from inflate.c.  Normally either infback.o or
    inflate.o would be linked into an application--not both.  The interface
    with inffast.c is retained so that optimized assembler-coded versions of
    inflate_fast() can be used with either inflate.c or infback.c.
@@ -21,17 +21,17 @@ local void fixedtables OF((struct inflat
 /*
    strm provides memory allocation functions in zalloc and zfree, or
    Z_NULL to use the library memory allocation functions.
 
    windowBits is in the range 8..15, and window is a user-supplied
    window and output buffer that is 2**windowBits bytes.
  */
 int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
-z_stream FAR *strm;
+z_streamp strm;
 int windowBits;
 unsigned char FAR *window;
 const char *version;
 int stream_size;
 {
     struct inflate_state FAR *state;
 
     if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
@@ -45,17 +45,18 @@ int stream_size;
         strm->zalloc = zcalloc;
         strm->opaque = (voidpf)0;
     }
     if (strm->zfree == (free_func)0) strm->zfree = zcfree;
     state = (struct inflate_state FAR *)ZALLOC(strm, 1,
                                                sizeof(struct inflate_state));
     if (state == Z_NULL) return Z_MEM_ERROR;
     Tracev((stderr, "inflate: allocated\n"));
-    strm->state = (voidpf)state;
+    strm->state = (struct internal_state FAR *)state;
+    state->dmax = 32768U;
     state->wbits = windowBits;
     state->wsize = 1U << windowBits;
     state->window = window;
     state->write = 0;
     state->whave = 0;
     return Z_OK;
 }
 
@@ -233,17 +234,17 @@ struct inflate_state FAR *state;
    Z_BUF_ERROR.  strm->next_in can be checked for Z_NULL to see whether it
    was in() or out() that caused in the error.  Otherwise,  inflateBack()
    returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
    error, or Z_MEM_ERROR if it could not allocate memory for the state.
    inflateBack() can also return Z_STREAM_ERROR if the input parameters
    are not correct, i.e. strm is Z_NULL or the state was not initialized.
  */
 int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
-z_stream FAR *strm;
+z_streamp strm;
 in_func in;
 void FAR *in_desc;
 out_func out;
 void FAR *out_desc;
 {
     struct inflate_state FAR *state;
     unsigned char FAR *next;    /* next input */
     unsigned char FAR *put;     /* next output */
@@ -606,17 +607,17 @@ void FAR *out_desc;
     /* Return unused input */
   inf_leave:
     strm->next_in = next;
     strm->avail_in = have;
     return ret;
 }
 
 int ZEXPORT inflateBackEnd(strm)
-z_stream FAR *strm;
+z_streamp strm;
 {
     if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
         return Z_STREAM_ERROR;
     ZFREE(strm, strm->state);
     strm->state = Z_NULL;
     Tracev((stderr, "inflate: end\n"));
     return Z_OK;
 }
--- a/security/nss/cmd/zlib/inffast.c
+++ b/security/nss/cmd/zlib/inffast.c
@@ -69,16 +69,19 @@ z_streamp strm;
 unsigned start;         /* inflate()'s starting value for strm->avail_out */
 {
     struct inflate_state FAR *state;
     unsigned char FAR *in;      /* local strm->next_in */
     unsigned char FAR *last;    /* while in < last, enough input available */
     unsigned char FAR *out;     /* local strm->next_out */
     unsigned char FAR *beg;     /* inflate()'s initial strm->next_out */
     unsigned char FAR *end;     /* while out < end, enough space available */
+#ifdef INFLATE_STRICT
+    unsigned dmax;              /* maximum distance from zlib header */
+#endif
     unsigned wsize;             /* window size or zero if not using window */
     unsigned whave;             /* valid bytes in the window */
     unsigned write;             /* window write index */
     unsigned char FAR *window;  /* allocated sliding window, if wsize != 0 */
     unsigned long hold;         /* local strm->hold */
     unsigned bits;              /* local strm->bits */
     code const FAR *lcode;      /* local strm->lencode */
     code const FAR *dcode;      /* local strm->distcode */
@@ -93,16 +96,19 @@ unsigned start;         /* inflate()'s s
 
     /* copy state to local variables */
     state = (struct inflate_state FAR *)strm->state;
     in = strm->next_in - OFF;
     last = in + (strm->avail_in - 5);
     out = strm->next_out - OFF;
     beg = out - (start - strm->avail_out);
     end = out + (strm->avail_out - 257);
+#ifdef INFLATE_STRICT
+    dmax = state->dmax;
+#endif
     wsize = state->wsize;
     whave = state->whave;
     write = state->write;
     window = state->window;
     hold = state->hold;
     bits = state->bits;
     lcode = state->lencode;
     dcode = state->distcode;
@@ -162,16 +168,23 @@ unsigned start;         /* inflate()'s s
                     hold += (unsigned long)(PUP(in)) << bits;
                     bits += 8;
                     if (bits < op) {
                         hold += (unsigned long)(PUP(in)) << bits;
                         bits += 8;
                     }
                 }
                 dist += (unsigned)hold & ((1U << op) - 1);
+#ifdef INFLATE_STRICT
+                if (dist > dmax) {
+                    strm->msg = (char *)"invalid distance too far back";
+                    state->mode = BAD;
+                    break;
+                }
+#endif
                 hold >>= op;
                 bits -= op;
                 Tracevv((stderr, "inflate:         distance %u\n", dist));
                 op = (unsigned)(out - beg);     /* max distance in output */
                 if (dist > op) {                /* see if copy from window */
                     op = dist - op;             /* distance back in window */
                     if (op > whave) {
                         strm->msg = (char *)"invalid distance too far back";
--- a/security/nss/cmd/zlib/inflate.c
+++ b/security/nss/cmd/zlib/inflate.c
@@ -1,10 +1,10 @@
 /* inflate.c -- zlib decompression
- * Copyright (C) 1995-2003 Mark Adler
+ * Copyright (C) 1995-2005 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /*
  * Change history:
  *
  * 1.2.beta0    24 Nov 2002
  * - First version -- complete rewrite of inflate to simplify code, avoid
@@ -108,25 +108,44 @@ z_streamp strm;
     if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
     state = (struct inflate_state FAR *)strm->state;
     strm->total_in = strm->total_out = state->total = 0;
     strm->msg = Z_NULL;
     strm->adler = 1;        /* to support ill-conceived Java test suite */
     state->mode = HEAD;
     state->last = 0;
     state->havedict = 0;
+    state->dmax = 32768U;
+    state->head = Z_NULL;
     state->wsize = 0;
     state->whave = 0;
+    state->write = 0;
     state->hold = 0;
     state->bits = 0;
     state->lencode = state->distcode = state->next = state->codes;
     Tracev((stderr, "inflate: reset\n"));
     return Z_OK;
 }
 
+int ZEXPORT inflatePrime(strm, bits, value)
+z_streamp strm;
+int bits;
+int value;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
+    value &= (1L << bits) - 1;
+    state->hold += value << state->bits;
+    state->bits += bits;
+    return Z_OK;
+}
+
 int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
 z_streamp strm;
 int windowBits;
 const char *version;
 int stream_size;
 {
     struct inflate_state FAR *state;
 
@@ -139,17 +158,17 @@ int stream_size;
         strm->zalloc = zcalloc;
         strm->opaque = (voidpf)0;
     }
     if (strm->zfree == (free_func)0) strm->zfree = zcfree;
     state = (struct inflate_state FAR *)
             ZALLOC(strm, 1, sizeof(struct inflate_state));
     if (state == Z_NULL) return Z_MEM_ERROR;
     Tracev((stderr, "inflate: allocated\n"));
-    strm->state = (voidpf)state;
+    strm->state = (struct internal_state FAR *)state;
     if (windowBits < 0) {
         state->wrap = 0;
         windowBits = -windowBits;
     }
     else {
         state->wrap = (windowBits >> 4) + 1;
 #ifdef GUNZIP
         if (windowBits < 48) windowBits &= 15;
@@ -577,36 +596,40 @@ int flush;
             if ((state->wrap & 2) && hold == 0x8b1f) {  /* gzip header */
                 state->check = crc32(0L, Z_NULL, 0);
                 CRC2(state->check, hold);
                 INITBITS();
                 state->mode = FLAGS;
                 break;
             }
             state->flags = 0;           /* expect zlib header */
+            if (state->head != Z_NULL)
+                state->head->done = -1;
             if (!(state->wrap & 1) ||   /* check if zlib header allowed */
 #else
             if (
 #endif
                 ((BITS(8) << 8) + (hold >> 8)) % 31) {
                 strm->msg = (char *)"incorrect header check";
                 state->mode = BAD;
                 break;
             }
             if (BITS(4) != Z_DEFLATED) {
                 strm->msg = (char *)"unknown compression method";
                 state->mode = BAD;
                 break;
             }
             DROPBITS(4);
-            if (BITS(4) + 8 > state->wbits) {
+            len = BITS(4) + 8;
+            if (len > state->wbits) {
                 strm->msg = (char *)"invalid window size";
                 state->mode = BAD;
                 break;
             }
+            state->dmax = 1U << len;
             Tracev((stderr, "inflate:   zlib header ok\n"));
             strm->adler = state->check = adler32(0L, Z_NULL, 0);
             state->mode = hold & 0x200 ? DICTID : TYPE;
             INITBITS();
             break;
 #ifdef GUNZIP
         case FLAGS:
             NEEDBITS(16);
@@ -616,89 +639,126 @@ int flush;
                 state->mode = BAD;
                 break;
             }
             if (state->flags & 0xe000) {
                 strm->msg = (char *)"unknown header flags set";
                 state->mode = BAD;
                 break;
             }
+            if (state->head != Z_NULL)
+                state->head->text = (int)((hold >> 8) & 1);
             if (state->flags & 0x0200) CRC2(state->check, hold);
             INITBITS();
             state->mode = TIME;
         case TIME:
             NEEDBITS(32);
+            if (state->head != Z_NULL)
+                state->head->time = hold;
             if (state->flags & 0x0200) CRC4(state->check, hold);
             INITBITS();
             state->mode = OS;
         case OS:
             NEEDBITS(16);
+            if (state->head != Z_NULL) {
+                state->head->xflags = (int)(hold & 0xff);
+                state->head->os = (int)(hold >> 8);
+            }
             if (state->flags & 0x0200) CRC2(state->check, hold);
             INITBITS();
             state->mode = EXLEN;
         case EXLEN:
             if (state->flags & 0x0400) {
                 NEEDBITS(16);
                 state->length = (unsigned)(hold);
+                if (state->head != Z_NULL)
+                    state->head->extra_len = (unsigned)hold;
                 if (state->flags & 0x0200) CRC2(state->check, hold);
                 INITBITS();
             }
+            else if (state->head != Z_NULL)
+                state->head->extra = Z_NULL;
             state->mode = EXTRA;
         case EXTRA:
             if (state->flags & 0x0400) {
                 copy = state->length;
                 if (copy > have) copy = have;
                 if (copy) {
+                    if (state->head != Z_NULL &&
+                        state->head->extra != Z_NULL) {
+                        len = state->head->extra_len - state->length;
+                        zmemcpy(state->head->extra + len, next,
+                                len + copy > state->head->extra_max ?
+                                state->head->extra_max - len : copy);
+                    }
                     if (state->flags & 0x0200)
                         state->check = crc32(state->check, next, copy);
                     have -= copy;
                     next += copy;
                     state->length -= copy;
                 }
                 if (state->length) goto inf_leave;
             }
+            state->length = 0;
             state->mode = NAME;
         case NAME:
             if (state->flags & 0x0800) {
                 if (have == 0) goto inf_leave;
                 copy = 0;
                 do {
                     len = (unsigned)(next[copy++]);
+                    if (state->head != Z_NULL &&
+                            state->head->name != Z_NULL &&
+                            state->length < state->head->name_max)
+                        state->head->name[state->length++] = len;
                 } while (len && copy < have);
-                if (state->flags & 0x02000)
+                if (state->flags & 0x0200)
                     state->check = crc32(state->check, next, copy);
                 have -= copy;
                 next += copy;
                 if (len) goto inf_leave;
             }
+            else if (state->head != Z_NULL)
+                state->head->name = Z_NULL;
+            state->length = 0;
             state->mode = COMMENT;
         case COMMENT:
             if (state->flags & 0x1000) {
                 if (have == 0) goto inf_leave;
                 copy = 0;
                 do {
                     len = (unsigned)(next[copy++]);
+                    if (state->head != Z_NULL &&
+                            state->head->comment != Z_NULL &&
+                            state->length < state->head->comm_max)
+                        state->head->comment[state->length++] = len;
                 } while (len && copy < have);
-                if (state->flags & 0x02000)
+                if (state->flags & 0x0200)
                     state->check = crc32(state->check, next, copy);
                 have -= copy;
                 next += copy;
                 if (len) goto inf_leave;
             }
+            else if (state->head != Z_NULL)
+                state->head->comment = Z_NULL;
             state->mode = HCRC;
         case HCRC:
             if (state->flags & 0x0200) {
                 NEEDBITS(16);
                 if (hold != (state->check & 0xffff)) {
                     strm->msg = (char *)"header crc mismatch";
                     state->mode = BAD;
                     break;
                 }
                 INITBITS();
             }
+            if (state->head != Z_NULL) {
+                state->head->hcrc = (int)((state->flags >> 9) & 1);
+                state->head->done = 1;
+            }
             strm->adler = state->check = crc32(0L, Z_NULL, 0);
             state->mode = TYPE;
             break;
 #endif
         case DICTID:
             NEEDBITS(32);
             strm->adler = state->check = REVERSE(hold);
             INITBITS();
@@ -964,16 +1024,23 @@ int flush;
             state->extra = (unsigned)(this.op) & 15;
             state->mode = DISTEXT;
         case DISTEXT:
             if (state->extra) {
                 NEEDBITS(state->extra);
                 state->offset += BITS(state->extra);
                 DROPBITS(state->extra);
             }
+#ifdef INFLATE_STRICT
+            if (state->offset > state->dmax) {
+                strm->msg = (char *)"invalid distance too far back";
+                state->mode = BAD;
+                break;
+            }
+#endif
             if (state->offset > state->whave + out - left) {
                 strm->msg = (char *)"invalid distance too far back";
                 state->mode = BAD;
                 break;
             }
             Tracevv((stderr, "inflate:         distance %u\n", state->offset));
             state->mode = MATCH;
         case MATCH:
@@ -1105,22 +1172,26 @@ const Bytef *dictionary;
 uInt dictLength;
 {
     struct inflate_state FAR *state;
     unsigned long id;
 
     /* check state */
     if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
     state = (struct inflate_state FAR *)strm->state;
-    if (state->mode != DICT) return Z_STREAM_ERROR;
+    if (state->wrap != 0 && state->mode != DICT)
+        return Z_STREAM_ERROR;
 
     /* check for correct dictionary id */
-    id = adler32(0L, Z_NULL, 0);
-    id = adler32(id, dictionary, dictLength);
-    if (id != state->check) return Z_DATA_ERROR;
+    if (state->mode == DICT) {
+        id = adler32(0L, Z_NULL, 0);
+        id = adler32(id, dictionary, dictLength);
+        if (id != state->check)
+            return Z_DATA_ERROR;
+    }
 
     /* copy dictionary to window */
     if (updatewindow(strm, strm->avail_out)) {
         state->mode = MEM;
         return Z_MEM_ERROR;
     }
     if (dictLength > state->wsize) {
         zmemcpy(state->window, dictionary + dictLength - state->wsize,
@@ -1132,16 +1203,33 @@ uInt dictLength;
                 dictLength);
         state->whave = dictLength;
     }
     state->havedict = 1;
     Tracev((stderr, "inflate:   dictionary set\n"));
     return Z_OK;
 }
 
+int ZEXPORT inflateGetHeader(strm, head)
+z_streamp strm;
+gz_headerp head;
+{
+    struct inflate_state FAR *state;
+
+    /* check state */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
+
+    /* save header structure */
+    state->head = head;
+    head->done = 0;
+    return Z_OK;
+}
+
 /*
    Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff.  Return when found
    or when out of input.  When called, *have is the number of pattern bytes
    found in order so far, in 0..3.  On return *have is updated to the new
    state.  If on return *have equals four, then the pattern was found and the
    return value is how many bytes were read including the last byte of the
    pattern.  If *have is less than four, then the pattern has not been found
    yet and the return value is len.  In the latter case, syncsearch() can be
@@ -1234,16 +1322,17 @@ z_streamp strm;
 
 int ZEXPORT inflateCopy(dest, source)
 z_streamp dest;
 z_streamp source;
 {
     struct inflate_state FAR *state;
     struct inflate_state FAR *copy;
     unsigned char FAR *window;
+    unsigned wsize;
 
     /* check input */
     if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
         source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
         return Z_STREAM_ERROR;
     state = (struct inflate_state FAR *)source->state;
 
     /* allocate space */
@@ -1256,19 +1345,24 @@ z_streamp source;
                  ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
         if (window == Z_NULL) {
             ZFREE(source, copy);
             return Z_MEM_ERROR;
         }
     }
 
     /* copy state */
-    *dest = *source;
-    *copy = *state;
-    copy->lencode = copy->codes + (state->lencode - state->codes);
-    copy->distcode = copy->codes + (state->distcode - state->codes);
+    zmemcpy(dest, source, sizeof(z_stream));
+    zmemcpy(copy, state, sizeof(struct inflate_state));
+    if (state->lencode >= state->codes &&
+        state->lencode <= state->codes + ENOUGH - 1) {
+        copy->lencode = copy->codes + (state->lencode - state->codes);
+        copy->distcode = copy->codes + (state->distcode - state->codes);
+    }
     copy->next = copy->codes + (state->next - state->codes);
-    if (window != Z_NULL)
-        zmemcpy(window, state->window, 1U << state->wbits);
+    if (window != Z_NULL) {
+        wsize = 1U << state->wbits;
+        zmemcpy(window, state->window, wsize);
+    }
     copy->window = window;
-    dest->state = (voidpf)copy;
+    dest->state = (struct internal_state FAR *)copy;
     return Z_OK;
 }
--- a/security/nss/cmd/zlib/inflate.h
+++ b/security/nss/cmd/zlib/inflate.h
@@ -1,10 +1,10 @@
 /* inflate.h -- internal inflate state definition
- * Copyright (C) 1995-2003 Mark Adler
+ * Copyright (C) 1995-2004 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* WARNING: this file should *not* be used by applications. It is
    part of the implementation of the compression library and is
    subject to change. Applications should only use zlib.h.
  */
 
@@ -14,45 +14,41 @@
    should be left enabled. */
 #ifndef NO_GZIP
 #  define GUNZIP
 #endif
 
 /* Possible inflate modes between inflate() calls */
 typedef enum {
     HEAD,       /* i: waiting for magic header */
-#ifdef GUNZIP
     FLAGS,      /* i: waiting for method and flags (gzip) */
     TIME,       /* i: waiting for modification time (gzip) */
     OS,         /* i: waiting for extra flags and operating system (gzip) */
     EXLEN,      /* i: waiting for extra length (gzip) */
     EXTRA,      /* i: waiting for extra bytes (gzip) */
     NAME,       /* i: waiting for end of file name (gzip) */
     COMMENT,    /* i: waiting for end of comment (gzip) */
     HCRC,       /* i: waiting for header crc (gzip) */
-#endif
     DICTID,     /* i: waiting for dictionary check value */
     DICT,       /* waiting for inflateSetDictionary() call */
         TYPE,       /* i: waiting for type bits, including last-flag bit */
         TYPEDO,     /* i: same, but skip check to exit inflate on new block */
         STORED,     /* i: waiting for stored size (length and complement) */
         COPY,       /* i/o: waiting for input or output to copy stored block */
         TABLE,      /* i: waiting for dynamic block table lengths */
         LENLENS,    /* i: waiting for code length code lengths */
         CODELENS,   /* i: waiting for length/lit and distance code lengths */
             LEN,        /* i: waiting for length/lit code */
             LENEXT,     /* i: waiting for length extra bits */
             DIST,       /* i: waiting for distance code */
             DISTEXT,    /* i: waiting for distance extra bits */
             MATCH,      /* o: waiting for output space to copy string */
             LIT,        /* o: waiting for output space to write literal */
     CHECK,      /* i: waiting for 32-bit check value */
-#ifdef GUNZIP
     LENGTH,     /* i: waiting for 32-bit length (gzip) */
-#endif
     DONE,       /* finished check, done -- remain here until reset */
     BAD,        /* got a data error -- remain here until reset */
     MEM,        /* got an inflate() memory error -- remain here until reset */
     SYNC        /* looking for synchronization bytes to restart inflate() */
 } inflate_mode;
 
 /*
     State transitions between above modes -
@@ -79,18 +75,20 @@ typedef enum {
 
 /* state maintained between inflate() calls.  Approximately 7K bytes. */
 struct inflate_state {
     inflate_mode mode;          /* current inflate mode */
     int last;                   /* true if processing last block */
     int wrap;                   /* bit 0 true for zlib, bit 1 true for gzip */
     int havedict;               /* true if dictionary provided */
     int flags;                  /* gzip header method and flags (0 if zlib) */
+    unsigned dmax;              /* zlib header max distance (INFLATE_STRICT) */
     unsigned long check;        /* protected copy of check value */
     unsigned long total;        /* protected copy of output count */
+    gz_headerp head;            /* where to save gzip header information */
         /* sliding window */
     unsigned wbits;             /* log base 2 of requested window size */
     unsigned wsize;             /* window size or zero if not using window */
     unsigned whave;             /* valid bytes in the window */
     unsigned write;             /* window write index */
     unsigned char FAR *window;  /* allocated sliding window, if needed */
         /* bit accumulator */
     unsigned long hold;         /* input bit accumulator */
--- a/security/nss/cmd/zlib/inftrees.c
+++ b/security/nss/cmd/zlib/inftrees.c
@@ -1,20 +1,20 @@
 /* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-2004 Mark Adler
+ * Copyright (C) 1995-2005 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 #include "zutil.h"
 #include "inftrees.h"
 
 #define MAXBITS 15
 
 const char inflate_copyright[] =
-   " inflate 1.2.2 Copyright 1995-2004 Mark Adler ";
+   " inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
 /*
   If you use the zlib library in a product, an acknowledgment is welcome
   in the documentation of your product. If for some reason you cannot
   include such an acknowledgment, I would appreciate that you keep this
   copyright string in the executable of your product.
  */
 
 /*
@@ -57,17 +57,17 @@ unsigned short FAR *work;
     int end;                    /* use base and extra for symbol > end */
     unsigned short count[MAXBITS+1];    /* number of codes of each length */
     unsigned short offs[MAXBITS+1];     /* offsets in table for each length */
     static const unsigned short lbase[31] = { /* Length codes 257..285 base */
         3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
         35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
     static const unsigned short lext[31] = { /* Length codes 257..285 extra */
         16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
-        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 199, 198};
+        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
     static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
         1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
         257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
         8193, 12289, 16385, 24577, 0, 0};
     static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
         16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
         23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
         28, 28, 29, 29, 64, 64};
@@ -129,17 +129,17 @@ unsigned short FAR *work;
 
     /* check for an over-subscribed or incomplete set of lengths */
     left = 1;
     for (len = 1; len <= MAXBITS; len++) {
         left <<= 1;
         left -= count[len];
         if (left < 0) return -1;        /* over-subscribed */
     }
-    if (left > 0 && (type == CODES || (codes - count[0] != 1)))
+    if (left > 0 && (type == CODES || max != 1))
         return -1;                      /* incomplete set */
 
     /* generate offsets into symbol table for each length for sorting */
     offs[1] = 0;
     for (len = 1; len < MAXBITS; len++)
         offs[len + 1] = offs[len] + count[len];
 
     /* sort symbols by length, by symbol order within each length */
@@ -227,16 +227,17 @@ unsigned short FAR *work;
         else {
             this.op = (unsigned char)(32 + 64);         /* end of block */
             this.val = 0;
         }
 
         /* replicate for those indices with low len bits equal to huff */
         incr = 1U << (len - drop);
         fill = 1U << curr;
+        min = fill;                 /* save offset to next table */
         do {
             fill -= incr;
             next[(huff >> drop) + fill] = this;
         } while (fill != 0);
 
         /* backwards increment the len-bit code huff */
         incr = 1U << (len - 1);
         while (huff & incr)
@@ -257,17 +258,17 @@ unsigned short FAR *work;
 
         /* create new sub-table if needed */
         if (len > root && (huff & mask) != low) {
             /* if first time, transition to sub-tables */
             if (drop == 0)
                 drop = root;
 
             /* increment past last table */
-            next += 1U << curr;
+            next += min;            /* here min is 1 << curr */
 
             /* determine length of next table */
             curr = len - drop;
             left = (int)(1 << curr);
             while (curr + drop < max) {
                 left -= count[curr + drop];
                 if (left <= 0) break;
                 curr++;
--- a/security/nss/cmd/zlib/inftrees.h
+++ b/security/nss/cmd/zlib/inftrees.h
@@ -1,10 +1,10 @@
 /* inftrees.h -- header to use inftrees.c
- * Copyright (C) 1995-2003 Mark Adler
+ * Copyright (C) 1995-2005 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* WARNING: this file should *not* be used by applications. It is
    part of the implementation of the compression library and is
    subject to change. Applications should only use zlib.h.
  */
 
@@ -31,22 +31,22 @@ typedef struct {
     00000000 - literal
     0000tttt - table link, tttt != 0 is the number of table index bits
     0001eeee - length or distance, eeee is the number of extra bits
     01100000 - end of block
     01000000 - invalid code
  */
 
 /* Maximum size of dynamic tree.  The maximum found in a long but non-
-   exhaustive search was 1004 code structures (850 for length/literals
-   and 154 for distances, the latter actually the result of an
+   exhaustive search was 1444 code structures (852 for length/literals
+   and 592 for distances, the latter actually the result of an
    exhaustive search).  The true maximum is not known, but the value
    below is more than safe. */
-#define ENOUGH 1440
-#define MAXD 154
+#define ENOUGH 2048
+#define MAXD 592
 
 /* Type of code to build for inftable() */
 typedef enum {
     CODES,
     LENS,
     DISTS
 } codetype;
 
--- a/security/nss/cmd/zlib/minigzip.c
+++ b/security/nss/cmd/zlib/minigzip.c
@@ -1,10 +1,10 @@
 /* minigzip.c -- simulate gzip using the zlib compression library
- * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /*
  * minigzip is a minimal implementation of the gzip utility. This is
  * only an example of using zlib and isn't meant to replace the
  * full-featured gzip. No attempt is made to deal with file systems
  * limiting names to 14 or 8+3 characters, etc... Error checking is
@@ -16,18 +16,16 @@
 /* @(#) $Id$ */
 
 #include <stdio.h>
 #include "zlib.h"
 
 #ifdef STDC
 #  include <string.h>
 #  include <stdlib.h>
-#else
-   extern void exit  OF((int));
 #endif
 
 #ifdef USE_MMAP
 #  include <sys/types.h>
 #  include <sys/mman.h>
 #  include <sys/stat.h>
 #endif
 
@@ -292,16 +290,18 @@ int main(argc, argv)
         outmode[3] = 'R';
       else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
                (*argv)[2] == 0)
         outmode[2] = (*argv)[1];
       else
         break;
       argc--, argv++;
     }
+    if (outmode[3] == ' ')
+        outmode[3] = 0;
     if (argc == 0) {
         SET_BINARY_MODE(stdin);
         SET_BINARY_MODE(stdout);
         if (uncompr) {
             file = gzdopen(fileno(stdin), "rb");
             if (file == NULL) error("can't gzdopen stdin");
             gz_uncompress(file, stdout);
         } else {
--- a/security/nss/cmd/zlib/trees.c
+++ b/security/nss/cmd/zlib/trees.c
@@ -1,10 +1,10 @@
 /* trees.c -- output deflated data using Huffman coding
- * Copyright (C) 1995-2003 Jean-loup Gailly
+ * Copyright (C) 1995-2005 Jean-loup Gailly
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /*
  *  ALGORITHM
  *
  *      The "deflation" process uses several Huffman trees. The more
  *      common source values are represented by shorter bit sequences.
@@ -550,17 +550,17 @@ local void gen_bitlen(s, desc)
      * lengths instead of fixing only the wrong ones. This idea is taken
      * from 'ar' written by Haruhiko Okumura.)
      */
     for (bits = max_length; bits != 0; bits--) {
         n = s->bl_count[bits];
         while (n != 0) {
             m = s->heap[--h];
             if (m > max_code) continue;
-            if (tree[m].Len != (unsigned) bits) {
+            if ((unsigned) tree[m].Len != (unsigned) bits) {
                 Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
                 s->opt_len += ((long)bits - (long)tree[m].Len)
                               *(long)tree[m].Freq;
                 tree[m].Len = (ush)bits;
             }
             n--;
         }
     }
@@ -925,18 +925,19 @@ void _tr_flush_block(s, buf, stored_len,
     int eof;          /* true if this is the last block for a file */
 {
     ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
     int max_blindex = 0;  /* index of last bit length code of non zero freq */
 
     /* Build the Huffman trees unless a stored block is forced */
     if (s->level > 0) {
 
-         /* Check if the file is ascii or binary */
-        if (s->strm->data_type == Z_UNKNOWN) set_data_type(s);
+        /* Check if the file is binary or text */
+        if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN)
+            set_data_type(s);
 
         /* Construct the literal and distance trees */
         build_tree(s, (tree_desc *)(&(s->l_desc)));
         Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
                 s->static_len));
 
         build_tree(s, (tree_desc *)(&(s->d_desc)));
         Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
@@ -977,17 +978,17 @@ void _tr_flush_block(s, buf, stored_len,
          * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
          * transform a block into a stored block.
          */
         _tr_stored_block(s, buf, stored_len, eof);
 
 #ifdef FORCE_STATIC
     } else if (static_lenb >= 0) { /* force static trees */
 #else
-    } else if (static_lenb == opt_lenb) {
+    } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
 #endif
         send_bits(s, (STATIC_TREES<<1)+eof, 3);
         compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
 #ifdef DEBUG
         s->compressed_len += 3 + s->static_len;
 #endif
     } else {
         send_bits(s, (DYN_TREES<<1)+eof, 3);
@@ -1112,31 +1113,34 @@ local void compress_block(s, ltree, dtre
 
     } while (lx < s->last_lit);
 
     send_code(s, END_BLOCK, ltree);
     s->last_eob_len = ltree[END_BLOCK].Len;
 }
 
 /* ===========================================================================
- * Set the data type to ASCII or BINARY, using a crude approximation:
- * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
- * IN assertion: the fields freq of dyn_ltree are set and the total of all
- * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
+ * Set the data type to BINARY or TEXT, using a crude approximation:
+ * set it to Z_TEXT if all symbols are either printable characters (33 to 255)
+ * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise.
+ * IN assertion: the fields Freq of dyn_ltree are set.
  */
 local void set_data_type(s)
     deflate_state *s;
 {
-    int n = 0;
-    unsigned ascii_freq = 0;
-    unsigned bin_freq = 0;
-    while (n < 7)        bin_freq += s->dyn_ltree[n++].Freq;
-    while (n < 128)    ascii_freq += s->dyn_ltree[n++].Freq;
-    while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
-    s->strm->data_type = bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII;
+    int n;
+
+    for (n = 0; n < 9; n++)
+        if (s->dyn_ltree[n].Freq != 0)
+            break;
+    if (n == 9)
+        for (n = 14; n < 32; n++)
+            if (s->dyn_ltree[n].Freq != 0)
+                break;
+    s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY;
 }
 
 /* ===========================================================================
  * Reverse the first len bits of a code, using straightforward code (a faster
  * method would use a table)
  * IN assertion: 1 <= len <= 15
  */
 local unsigned bi_reverse(code, len)
--- a/security/nss/cmd/zlib/zconf.h
+++ b/security/nss/cmd/zlib/zconf.h
@@ -1,10 +1,10 @@
 /* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2004 Jean-loup Gailly.
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* @(#) $Id$ */
 
 #ifndef ZCONF_H
 #define ZCONF_H
 
@@ -38,16 +38,20 @@
 #  define compress2             z_compress2
 #  define compressBound         z_compressBound
 #  define uncompress            z_uncompress
 #  define adler32               z_adler32
 #  define crc32                 z_crc32
 #  define get_crc_table         z_get_crc_table
 #  define zError                z_zError
 
+#  define alloc_func            z_alloc_func
+#  define free_func             z_free_func
+#  define in_func               z_in_func
+#  define out_func              z_out_func
 #  define Byte                  z_Byte
 #  define uInt                  z_uInt
 #  define uLong                 z_uLong
 #  define Bytef                 z_Bytef
 #  define charf                 z_charf
 #  define intf                  z_intf
 #  define uIntf                 z_uIntf
 #  define uLongf                z_uLongf
@@ -59,18 +63,20 @@
 #  define MSDOS
 #endif
 #if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
 #  define OS2
 #endif
 #if defined(_WINDOWS) && !defined(WINDOWS)
 #  define WINDOWS
 #endif
-#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
-#  define WIN32
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+#  ifndef WIN32
+#    define WIN32
+#  endif
 #endif
 #if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
 #  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
 #    ifndef SYS16BIT
 #      define SYS16BIT
 #    endif
 #  endif
 #endif
--- a/security/nss/cmd/zlib/zlib.h
+++ b/security/nss/cmd/zlib/zlib.h
@@ -1,12 +1,12 @@
 /* zlib.h -- interface of the 'zlib' general purpose compression library
-  version 1.2.2, October 3rd, 2004
+  version 1.2.3, July 18th, 2005
 
-  Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler
+  Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
   arising from the use of this software.
 
   Permission is granted to anyone to use this software for any purpose,
   including commercial applications, and to alter it and redistribute it
   freely, subject to the following restrictions:
@@ -32,18 +32,18 @@
 #define ZLIB_H
 
 #include "zconf.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#define ZLIB_VERSION "1.2.2"
-#define ZLIB_VERNUM 0x1220
+#define ZLIB_VERSION "1.2.3"
+#define ZLIB_VERNUM 0x1230
 
 /*
      The 'zlib' compression library provides in-memory compression and
   decompression functions, including integrity checks of the uncompressed
   data.  This version of the library supports only one compression method
   (deflation) but other algorithms will be added later and will have the same
   stream interface.
 
@@ -90,24 +90,47 @@ typedef struct z_stream_s {
 
     char     *msg;      /* last error message, NULL if no error */
     struct internal_state FAR *state; /* not visible by applications */
 
     alloc_func zalloc;  /* used to allocate the internal state */
     free_func  zfree;   /* used to free the internal state */
     voidpf     opaque;  /* private data object passed to zalloc and zfree */
 
-    int     data_type;  /* best guess about the data type: ascii or binary */
+    int     data_type;  /* best guess about the data type: binary or text */
     uLong   adler;      /* adler32 value of the uncompressed data */
     uLong   reserved;   /* reserved for future use */
 } z_stream;
 
 typedef z_stream FAR *z_streamp;
 
 /*
+     gzip header information passed to and from zlib routines.  See RFC 1952
+  for more details on the meanings of these fields.
+*/
+typedef struct gz_header_s {
+    int     text;       /* true if compressed data believed to be text */
+    uLong   time;       /* modification time */
+    int     xflags;     /* extra flags (not used when writing a gzip file) */
+    int     os;         /* operating system */
+    Bytef   *extra;     /* pointer to extra field or Z_NULL if none */
+    uInt    extra_len;  /* extra field length (valid if extra != Z_NULL) */
+    uInt    extra_max;  /* space at extra (only when reading header) */
+    Bytef   *name;      /* pointer to zero-terminated file name or Z_NULL */
+    uInt    name_max;   /* space at name (only when reading header) */
+    Bytef   *comment;   /* pointer to zero-terminated comment or Z_NULL */
+    uInt    comm_max;   /* space at comment (only when reading header) */
+    int     hcrc;       /* true if there was or will be a header crc */
+    int     done;       /* true when done reading gzip header (not used
+                           when writing a gzip file) */
+} gz_header;
+
+typedef gz_header FAR *gz_headerp;
+
+/*
    The application must update next_in and avail_in when avail_in has
    dropped to zero. It must update next_out and avail_out when avail_out
    has dropped to zero. The application must initialize zalloc, zfree and
    opaque before calling the init function. All other fields are set by the
    compression library and must not be updated by the application.
 
    The opaque value provided by the application will be passed as the first
    parameter for calls of zalloc and zfree. This can be useful for custom
@@ -161,21 +184,23 @@ typedef z_stream FAR *z_streamp;
 #define Z_BEST_SPEED             1
 #define Z_BEST_COMPRESSION       9
 #define Z_DEFAULT_COMPRESSION  (-1)
 /* compression levels */
 
 #define Z_FILTERED            1
 #define Z_HUFFMAN_ONLY        2
 #define Z_RLE                 3
+#define Z_FIXED               4
 #define Z_DEFAULT_STRATEGY    0
 /* compression strategy; see deflateInit2() below for details */
 
 #define Z_BINARY   0
-#define Z_ASCII    1
+#define Z_TEXT     1
+#define Z_ASCII    Z_TEXT   /* for compatibility with 1.2.2 and earlier */
 #define Z_UNKNOWN  2
 /* Possible values of the data_type field (though see inflate()) */
 
 #define Z_DEFLATED   8
 /* The deflate compression method (the only one supported in this version) */
 
 #define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
 
@@ -239,28 +264,32 @@ ZEXTERN int ZEXPORT deflate OF((z_stream
   one of the actions is possible, by providing more input and/or consuming
   more output, and updating avail_in or avail_out accordingly; avail_out
   should never be zero before the call. The application can consume the
   compressed output when it wants, for example when the output buffer is full
   (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
   and with zero avail_out, it must be called again after making room in the
   output buffer because there might be more output pending.
 
+    Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
+  decide how much data to accumualte before producing output, in order to
+  maximize compression.
+
     If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
   flushed to the output buffer and the output is aligned on a byte boundary, so
   that the decompressor can get all input data available so far. (In particular
   avail_in is zero after the call if enough output space has been provided
   before the call.)  Flushing may degrade compression for some compression
   algorithms and so it should be used only when necessary.
 
     If flush is set to Z_FULL_FLUSH, all output is flushed as with
   Z_SYNC_FLUSH, and the compression state is reset so that decompression can
   restart from this point if previous compressed data has been damaged or if
   random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
-  the compression.
+  compression.
 
     If deflate returns with avail_out == 0, this function must be called again
   with the same value of the flush parameter and more output space (updated
   avail_out), until the flush is complete (deflate returns with non-zero
   avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
   avail_out is greater than six to avoid repeated flush markers due to
   avail_out == 0 on return.
 
@@ -275,18 +304,18 @@ ZEXTERN int ZEXPORT deflate OF((z_stream
     Z_FINISH can be used immediately after deflateInit if all the compression
   is to be done in a single step. In this case, avail_out must be at least
   the value returned by deflateBound (see below). If deflate does not return
   Z_STREAM_END, then it must be called again as described above.
 
     deflate() sets strm->adler to the adler32 checksum of all input read
   so far (that is, total_in bytes).
 
-    deflate() may update data_type if it can make a good guess about
-  the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
+    deflate() may update strm->data_type if it can make a good guess about
+  the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
   binary. This field is only for information purposes and does not affect
   the compression algorithm in any manner.
 
     deflate() returns Z_OK if some progress has been made (more input
   processed or more output produced), Z_STREAM_END if all input has been
   consumed and all output has been produced (only when flush is set to
   Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
   if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
@@ -358,21 +387,21 @@ ZEXTERN int ZEXPORT inflate OF((z_stream
   example when the output buffer is full (avail_out == 0), or after each
   call of inflate(). If inflate returns Z_OK and with zero avail_out, it
   must be called again after making room in the output buffer because there
   might be more output pending.
 
     The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
   Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
   output as possible to the output buffer. Z_BLOCK requests that inflate() stop
-  if and when it get to the next deflate block boundary. When decoding the zlib
-  or gzip format, this will cause inflate() to return immediately after the
-  header and before the first block. When doing a raw inflate, inflate() will
-  go ahead and process the first block, and will return when it gets to the end
-  of that block, or when it runs out of data.
+  if and when it gets to the next deflate block boundary. When decoding the
+  zlib or gzip format, this will cause inflate() to return immediately after
+  the header and before the first block. When doing a raw inflate, inflate()
+  will go ahead and process the first block, and will return when it gets to
+  the end of that block, or when it runs out of data.
 
     The Z_BLOCK option assists in appending to or combining deflate streams.
   Also to assist in this, on return inflate() will set strm->data_type to the
   number of unused bits in the last byte taken from strm->next_in, plus 64
   if inflate() is currently decoding the last block in the deflate stream,
   plus 128 if inflate() returned immediately after decoding an end-of-block
   code or decoding the complete header up to just before the first byte of the
   deflate stream. The end-of-block will not be indicated until all of the
@@ -491,17 +520,19 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_s
    string match), or Z_RLE to limit match distances to one (run-length
    encoding). Filtered data consists mostly of small values with a somewhat
    random distribution. In this case, the compression algorithm is tuned to
    compress them better. The effect of Z_FILTERED is to force more Huffman
    coding and less string matching; it is somewhat intermediate between
    Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
    Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
    parameter only affects the compression ratio but not the correctness of the
-   compressed output even if it is not set appropriately.
+   compressed output even if it is not set appropriately.  Z_FIXED prevents the
+   use of dynamic Huffman codes, allowing for a simpler decoder for special
+   applications.
 
       deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
    memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
    method). msg is set to null if there is no error message.  deflateInit2 does
    not perform any compression: this will be done by deflate().
 */
 
 ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
@@ -520,17 +551,19 @@ ZEXTERN int ZEXPORT deflateSetDictionary
    dictionary is most useful when the data to be compressed is short and can be
    predicted with good accuracy; the data can then be compressed better than
    with the default empty dictionary.
 
      Depending on the size of the compression data structures selected by
    deflateInit or deflateInit2, a part of the dictionary may in effect be
    discarded, for example if the dictionary is larger than the window size in
    deflate or deflate2. Thus the strings most likely to be useful should be
-   put at the end of the dictionary, not at the front.
+   put at the end of the dictionary, not at the front. In addition, the
+   current implementation of deflate will use at most the window size minus
+   262 bytes of the provided dictionary.
 
      Upon return of this function, strm->adler is set to the adler32 value
    of the dictionary; the decompressor may later use this value to determine
    which dictionary has been used by the compressor. (The adler32 value
    applies to the whole dictionary even if only a subset of the dictionary is
    actually used by the compressor.) If a raw deflate was requested, then the
    adler32 value is not computed and strm->adler is not set.
 
@@ -586,16 +619,33 @@ ZEXTERN int ZEXPORT deflateParams OF((z_
    a call of deflate(), since the currently available input may have to
    be compressed and flushed. In particular, strm->avail_out must be non-zero.
 
      deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
    stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
    if strm->avail_out was zero.
 */
 
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+                                    int good_length,
+                                    int max_lazy,
+                                    int nice_length,
+                                    int max_chain));
+/*
+     Fine tune deflate's internal compression parameters.  This should only be
+   used by someone who understands the algorithm used by zlib's deflate for
+   searching for the best matching string, and even then only by the most
+   fanatic optimizer trying to squeeze out the last compressed bit for their
+   specific input data.  Read the deflate.c source code for the meaning of the
+   max_lazy, good_length, nice_length, and max_chain parameters.
+
+     deflateTune() can be called after deflateInit() or deflateInit2(), and
+   returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
 ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
                                        uLong sourceLen));
 /*
      deflateBound() returns an upper bound on the compressed size after
    deflation of sourceLen bytes.  It must be called after deflateInit()
    or deflateInit2().  This would be used to allocate an output buffer
    for deflation in a single pass, and so would be called before deflate().
 */
@@ -611,16 +661,40 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_s
   first deflate() call after a deflateInit2() or deflateReset().  bits must be
   less than or equal to 16, and that many of the least significant bits of
   value will be inserted in the output.
 
       deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
    stream state was inconsistent.
 */
 
+ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
+                                         gz_headerp head));
+/*
+      deflateSetHeader() provides gzip header information for when a gzip
+   stream is requested by deflateInit2().  deflateSetHeader() may be called
+   after deflateInit2() or deflateReset() and before the first call of
+   deflate().  The text, time, os, extra field, name, and comment information
+   in the provided gz_header structure are written to the gzip header (xflag is
+   ignored -- the extra flags are set according to the compression level).  The
+   caller must assure that, if not Z_NULL, name and comment are terminated with
+   a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
+   available there.  If hcrc is true, a gzip header crc is included.  Note that
+   the current versions of the command-line version of gzip (up through version
+   1.3.x) do not support header crc's, and will report that it is a "multi-part
+   gzip file" and give up.
+
+      If deflateSetHeader is not used, the default gzip header has text false,
+   the time set to zero, and os set to 255, with no extra, name, or comment
+   fields.  The gzip header is returned to the default state by deflateReset().
+
+      deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
 /*
 ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
                                      int  windowBits));
 
      This is another version of inflateInit with an extra parameter. The
    fields next_in, avail_in, zalloc, zfree and opaque must be initialized
    before by the caller.
 
@@ -643,37 +717,40 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_s
    recommended that a check value such as an adler32 or a crc32 be applied to
    the uncompressed data as is done in the zlib, gzip, and zip formats.  For
    most applications, the zlib format should be used as is. Note that comments
    above on the use in deflateInit2() applies to the magnitude of windowBits.
 
      windowBits can also be greater than 15 for optional gzip decoding. Add
    32 to windowBits to enable zlib and gzip decoding with automatic header
    detection, or add 16 to decode only the gzip format (the zlib format will
-   return a Z_DATA_ERROR.  If a gzip stream is being decoded, strm->adler is
+   return a Z_DATA_ERROR).  If a gzip stream is being decoded, strm->adler is
    a crc32 instead of an adler32.
 
      inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
-   memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
-   memLevel). msg is set to null if there is no error message.  inflateInit2
-   does not perform any decompression apart from reading the zlib header if
-   present: this will be done by inflate(). (So next_in and avail_in may be
-   modified, but next_out and avail_out are unchanged.)
+   memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
+   is set to null if there is no error message.  inflateInit2 does not perform
+   any decompression apart from reading the zlib header if present: this will
+   be done by inflate(). (So next_in and avail_in may be modified, but next_out
+   and avail_out are unchanged.)
 */
 
 ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
                                              const Bytef *dictionary,
                                              uInt  dictLength));
 /*
      Initializes the decompression dictionary from the given uncompressed byte
-   sequence. This function must be called immediately after a call of inflate
-   if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
-   can be determined from the adler32 value returned by this call of
-   inflate. The compressor and decompressor must use exactly the same
-   dictionary (see deflateSetDictionary).
+   sequence. This function must be called immediately after a call of inflate,
+   if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
+   can be determined from the adler32 value returned by that call of inflate.
+   The compressor and decompressor must use exactly the same dictionary (see
+   deflateSetDictionary).  For raw inflate, this function can be called
+   immediately after inflateInit2() or inflateReset() and before any call of
+   inflate() to set the dictionary.  The application must insure that the
+   dictionary that was used for compression is provided.
 
      inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
    parameter is invalid (such as NULL dictionary) or the stream state is
    inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
    expected one (incorrect adler32 value). inflateSetDictionary does not
    perform any decompression: this will be done by subsequent calls of
    inflate().
 */
@@ -714,18 +791,74 @@ ZEXTERN int ZEXPORT inflateReset OF((z_s
      This function is equivalent to inflateEnd followed by inflateInit,
    but does not free and reallocate all the internal decompression state.
    The stream will keep attributes that may have been set by inflateInit2.
 
       inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
    stream state was inconsistent (such as zalloc or state being NULL).
 */
 
+ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+                                     int bits,
+                                     int value));
 /*
-ZEXTERN int ZEXPORT inflateBackInit OF((z_stream FAR *strm, int windowBits,
+     This function inserts bits in the inflate input stream.  The intent is
+  that this function is used to start inflating at a bit position in the
+  middle of a byte.  The provided bits will be used before any bytes are used
+  from next_in.  This function should only be used with raw inflate, and
+  should be used before the first inflate() call after inflateInit2() or
+  inflateReset().  bits must be less than or equal to 16, and that many of the
+  least significant bits of value will be inserted in the input.
+
+      inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+                                         gz_headerp head));
+/*
+      inflateGetHeader() requests that gzip header information be stored in the
+   provided gz_header structure.  inflateGetHeader() may be called after
+   inflateInit2() or inflateReset(), and before the first call of inflate().
+   As inflate() processes the gzip stream, head->done is zero until the header
+   is completed, at which time head->done is set to one.  If a zlib stream is
+   being decoded, then head->done is set to -1 to indicate that there will be
+   no gzip header information forthcoming.  Note that Z_BLOCK can be used to
+   force inflate() to return immediately after header processing is complete
+   and before any actual data is decompressed.
+
+      The text, time, xflags, and os fields are filled in with the gzip header
+   contents.  hcrc is set to true if there is a header CRC.  (The header CRC
+   was valid if done is set to one.)  If extra is not Z_NULL, then extra_max
+   contains the maximum number of bytes to write to extra.  Once done is true,
+   extra_len contains the actual extra field length, and extra contains the
+   extra field, or that field truncated if extra_max is less than extra_len.
+   If name is not Z_NULL, then up to name_max characters are written there,
+   terminated with a zero unless the length is greater than name_max.  If
+   comment is not Z_NULL, then up to comm_max characters are written there,
+   terminated with a zero unless the length is greater than comm_max.  When
+   any of extra, name, or comment are not Z_NULL and the respective field is
+   not present in the header, then that field is set to Z_NULL to signal its
+   absence.  This allows the use of deflateSetHeader() with the returned
+   structure to duplicate the header.  However if those fields are set to
+   allocated memory, then the application will need to save those pointers
+   elsewhere so that they can be eventually freed.
+
+      If inflateGetHeader is not used, then the header information is simply
+   discarded.  The header is always checked for validity, including the header
+   CRC if present.  inflateReset() will reset the process to discard the header
+   information.  The application would need to call inflateGetHeader() again to
+   retrieve the header from the next gzip stream.
+
+      inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
                                         unsigned char FAR *window));
 
      Initialize the internal stream state for decompression using inflateBack()
    calls.  The fields zalloc, zfree and opaque in strm must be initialized
    before the call.  If zalloc and zfree are Z_NULL, then the default library-
    derived memory allocation routines are used.  windowBits is the base two
    logarithm of the window size, in the range 8..15.  window is a caller
    supplied buffer of that size.  Except for special applications where it is
@@ -739,17 +872,17 @@ ZEXTERN int ZEXPORT inflateBackInit OF((
    the paramaters are invalid, Z_MEM_ERROR if the internal state could not
    be allocated, or Z_VERSION_ERROR if the version of the library does not
    match the version of the header file.
 */
 
 typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
 typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
 
-ZEXTERN int ZEXPORT inflateBack OF((z_stream FAR *strm,
+ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
                                     in_func in, void FAR *in_desc,
                                     out_func out, void FAR *out_desc));
 /*
      inflateBack() does a raw inflate with a single call using a call-back
    interface for input and output.  This is more efficient than inflate() for
    file i/o applications in that it avoids copying between the output and the
    sliding window by simply making the window itself the output buffer.  This
    function trusts the application to not change the output buffer passed by
@@ -808,17 +941,17 @@ ZEXTERN int ZEXPORT inflateBack OF((z_st
    initialized.  In the case of Z_BUF_ERROR, an input or output error can be
    distinguished using strm->next_in which will be Z_NULL only if in() returned
    an error.  If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
    out() returning non-zero.  (in() will always be called before out(), so
    strm->next_in is assured to be defined if out() returns non-zero.)  Note
    that inflateBack() cannot return Z_OK.
 */
 
-ZEXTERN int ZEXPORT inflateBackEnd OF((z_stream FAR *strm));
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
 /*
      All memory allocated by inflateBackInit() is freed.
 
      inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
    state was inconsistent.
 */
 
 ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
@@ -1082,16 +1215,22 @@ ZEXTERN z_off_t ZEXPORT    gztell OF((gz
 */
 
 ZEXTERN int ZEXPORT gzeof OF((gzFile file));
 /*
      Returns 1 when EOF has previously been detected reading the given
    input stream, otherwise zero.
 */
 
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+     Returns 1 if file is being read directly without decompression, otherwise
+   zero.
+*/
+
 ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
 /*
      Flushes all pending output if necessary, closes the compressed file
    and deallocates all the (de)compression state. The return value is the zlib
    error number (see function gzerror below).
 */
 
 ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
@@ -1114,65 +1253,83 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFi
 
 /*
      These functions are not related to compression but are exported
    anyway because they might be useful in applications using the
    compression library.
 */
 
 ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
-
 /*
      Update a running Adler-32 checksum with the bytes buf[0..len-1] and
    return the updated checksum. If buf is NULL, this function returns
    the required initial value for the checksum.
    An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
    much faster. Usage example:
 
      uLong adler = adler32(0L, Z_NULL, 0);
 
      while (read_buffer(buffer, length) != EOF) {
        adler = adler32(adler, buffer, length);
      }
      if (adler != original_adler) error();
 */
 
+ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
+                                          z_off_t len2));
+/*
+     Combine two Adler-32 checksums into one.  For two sequences of bytes, seq1
+   and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+   each, adler1 and adler2.  adler32_combine() returns the Adler-32 checksum of
+   seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
+*/
+
 ZEXTERN uLong ZEXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));
 /*
-     Update a running crc with the bytes buf[0..len-1] and return the updated
-   crc. If buf is NULL, this function returns the required initial value
-   for the crc. Pre- and post-conditioning (one's complement) is performed
-   within this function so it shouldn't be done by the application.
+     Update a running CRC-32 with the bytes buf[0..len-1] and return the
+   updated CRC-32. If buf is NULL, this function returns the required initial
+   value for the for the crc. Pre- and post-conditioning (one's complement) is
+   performed within this function so it shouldn't be done by the application.
    Usage example:
 
      uLong crc = crc32(0L, Z_NULL, 0);
 
      while (read_buffer(buffer, length) != EOF) {
        crc = crc32(crc, buffer, length);
      }
      if (crc != original_crc) error();
 */
 
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
+/*
+     Combine two CRC-32 check values into one.  For two sequences of bytes,
+   seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+   calculated for each, crc1 and crc2.  crc32_combine() returns the CRC-32
+   check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+   len2.
+*/
+
 
                         /* various hacks, don't look :) */
 
 /* deflateInit and inflateInit are macros to allow checking the zlib version
  * and the compiler's view of z_stream:
  */
 ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
                                      const char *version, int stream_size));
 ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
                                      const char *version, int stream_size));
 ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,
                                       int windowBits, int memLevel,
                                       int strategy, const char *version,
                                       int stream_size));
 ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
                                       const char *version, int stream_size));
-ZEXTERN int ZEXPORT inflateBackInit_ OF((z_stream FAR *strm, int windowBits,
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
                                          unsigned char FAR *window,
                                          const char *version,
                                          int stream_size));
 #define deflateInit(strm, level) \
         deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream))
 #define inflateInit(strm) \
         inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream))
 #define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
--- a/security/nss/cmd/zlib/zutil.c
+++ b/security/nss/cmd/zlib/zutil.c
@@ -1,25 +1,21 @@
 /* zutil.c -- target dependent utility functions for the compression library
- * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* @(#) $Id$ */
 
 #include "zutil.h"
 
 #ifndef NO_DUMMY_DECL
 struct internal_state      {int dummy;}; /* for buggy compilers */
 #endif
 
-#ifndef STDC
-extern void exit OF((int));
-#endif
-
 const char * const z_errmsg[10] = {
 "need dictionary",     /* Z_NEED_DICT       2  */
 "stream end",          /* Z_STREAM_END      1  */
 "",                    /* Z_OK              0  */
 "file error",          /* Z_ERRNO         (-1) */
 "stream error",        /* Z_STREAM_ERROR  (-2) */
 "data error",          /* Z_DATA_ERROR    (-3) */
 "insufficient memory", /* Z_MEM_ERROR     (-4) */
@@ -73,48 +69,48 @@ uLong ZEXPORT zlibCompileFlags()
 #endif
 #ifdef BUILDFIXED
     flags += 1 << 12;
 #endif
 #ifdef DYNAMIC_CRC_TABLE
     flags += 1 << 13;
 #endif
 #ifdef NO_GZCOMPRESS
-    flags += 1 << 16;
+    flags += 1L << 16;
 #endif
 #ifdef NO_GZIP
-    flags += 1 << 17;
+    flags += 1L << 17;
 #endif
 #ifdef PKZIP_BUG_WORKAROUND
-    flags += 1 << 20;
+    flags += 1L << 20;
 #endif
 #ifdef FASTEST
-    flags += 1 << 21;
+    flags += 1L << 21;
 #endif
 #ifdef STDC
 #  ifdef NO_vsnprintf
-        flags += 1 << 25;
+        flags += 1L << 25;
 #    ifdef HAS_vsprintf_void
-        flags += 1 << 26;
+        flags += 1L << 26;
 #    endif
 #  else
 #    ifdef HAS_vsnprintf_void
-        flags += 1 << 26;
+        flags += 1L << 26;
 #    endif
 #  endif
 #else
-        flags += 1 << 24;
+        flags += 1L << 24;
 #  ifdef NO_snprintf
-        flags += 1 << 25;
+        flags += 1L << 25;
 #    ifdef HAS_sprintf_void
-        flags += 1 << 26;
+        flags += 1L << 26;
 #    endif
 #  else
 #    ifdef HAS_snprintf_void
-        flags += 1 << 26;
+        flags += 1L << 26;
 #    endif
 #  endif
 #endif
     return flags;
 }
 
 #ifdef DEBUG
 
@@ -135,16 +131,24 @@ void z_error (m)
  * uncompress()
  */
 const char * ZEXPORT zError(err)
     int err;
 {
     return ERR_MSG(err);
 }
 
+#if defined(_WIN32_WCE)
+    /* The Microsoft C Run-Time Library for Windows CE doesn't have
+     * errno.  We define it as a global variable to simplify porting.
+     * Its value is always 0 and should not be used.
+     */
+    int errno = 0;
+#endif
+
 #ifndef HAVE_MEMCPY
 
 void zmemcpy(dest, source, len)
     Bytef* dest;
     const Bytef* source;
     uInt  len;
 {
     if (len == 0) return;
--- a/security/nss/cmd/zlib/zutil.h
+++ b/security/nss/cmd/zlib/zutil.h
@@ -1,10 +1,10 @@
 /* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* WARNING: this file should *not* be used by applications. It is
    part of the implementation of the compression library and is
    subject to change. Applications should only use zlib.h.
  */
 
@@ -12,26 +12,36 @@
 
 #ifndef ZUTIL_H
 #define ZUTIL_H
 
 #define ZLIB_INTERNAL
 #include "zlib.h"
 
 #ifdef STDC
-#  include <stddef.h>
+#  ifndef _WIN32_WCE
+#    include <stddef.h>
+#  endif
 #  include <string.h>
 #  include <stdlib.h>
 #endif
-#ifdef _WIN32_WCE
-/* In our WINCE port, errno is emulated as a thread private data. */
-#elif defined(NO_ERRNO_H)
+#ifdef NO_ERRNO_H
+#   ifdef _WIN32_WCE
+      /* The Microsoft C Run-Time Library for Windows CE doesn't have
+       * errno.  We define it as a global variable to simplify porting.
+       * Its value is always 0 and should not be used.  We rename it to
+       * avoid conflict with other libraries that use the same workaround.
+       */
+#     define errno z_errno
+#   endif
     extern int errno;
 #else
-#   include <errno.h>
+#  ifndef _WIN32_WCE
+#    include <errno.h>
+#  endif
 #endif
 
 #ifndef local
 #  define local static
 #endif
 /* compile with -Dlocal if your debugger can't find static symbols */
 
 typedef unsigned char  uch;
@@ -102,16 +112,19 @@ extern const char * const z_errmsg[10]; 
 #endif
 
 #if defined(ATARI) || defined(atarist)
 #  define OS_CODE  0x05
 #endif
 
 #ifdef OS2
 #  define OS_CODE  0x06
+#  ifdef M_I86
+     #include <malloc.h>
+#  endif
 #endif
 
 #if defined(MACOS) || defined(TARGET_OS_MAC)
 #  define OS_CODE  0x07
 #  if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
 #    include <unix.h> /* for fdopen */
 #  else
 #    ifndef fdopen
@@ -190,25 +203,16 @@ extern const char * const z_errmsg[10]; 
 #  ifdef __SASC
 #    define NO_vsnprintf
 #  endif
 #endif
 #ifdef VMS
 #  define NO_vsnprintf
 #endif
 
-#ifdef HAVE_STRERROR
-#  ifndef VMS
-     extern char *strerror OF((int));
-#  endif
-#  define zstrerror(errnum) strerror(errnum)
-#else
-#  define zstrerror(errnum) ""
-#endif
-
 #if defined(pyr)
 #  define NO_MEMCPY
 #endif
 #if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
  /* Use our own functions for small and medium model with MSC <= 5.0.
   * You may have to use the same strategy for Borland C (untested).
   * The __SC__ check is for Symantec.
   */
--- a/security/nss/lib/certhigh/certvfy.c
+++ b/security/nss/lib/certhigh/certvfy.c
@@ -1134,34 +1134,34 @@ CERT_VerifyCACertForUsage(CERTCertDBHand
     return CERT_VerifyCertChain(handle, cert, checkSig, certUsage, t, 
 		     					wincx, log);
 loser:
     rv = SECFailure;
 done:
     return rv;
 }
 
-#define NEXT_ITERATION() { \
+#define NEXT_USAGE() { \
     i*=2; \
     certUsage++; \
     continue; \
 }
 
 #define VALID_USAGE() { \
-    NEXT_ITERATION(); \
+    NEXT_USAGE(); \
 }
 
 #define INVALID_USAGE() { \
     if (returnedUsages) { \
         *returnedUsages &= (~i); \
     } \
     if (PR_TRUE == requiredUsage) { \
         valid = SECFailure; \
     } \
-    NEXT_ITERATION(); \
+    NEXT_USAGE(); \
 }
 
 /*
  * verify a certificate by checking if it's valid and that we
  * trust the issuer.
  *
  * certificateUsage contains a bitfield of all cert usages that are
  * required for verification to succeed
@@ -1228,17 +1228,17 @@ CERT_VerifyCertificate(CERTCertDBHandle 
 
     /* check key usage and netscape cert type */
     cert_GetCertType(cert);
     certType = cert->nsCertType;
 
     for (i=1;i<=certificateUsageHighest && !(SECFailure == valid && !returnedUsages) ;) {
         PRBool requiredUsage = (i & requiredUsages) ? PR_TRUE : PR_FALSE;
         if (PR_FALSE == requiredUsage && PR_FALSE == checkAllUsages) {
-            NEXT_ITERATION();
+            NEXT_USAGE();
         }
         if (returnedUsages) {
             *returnedUsages |= i; /* start off assuming this usage is valid */
         }
         switch ( certUsage ) {
           case certUsageSSLClient:
           case certUsageSSLServer:
           case certUsageSSLServerWithStepUp:
@@ -1259,17 +1259,17 @@ CERT_VerifyCertificate(CERTCertDBHandle 
             }
             break;
 
           case certUsageAnyCA:
           case certUsageProtectedObjectSigner:
           case certUsageUserCertImport:
           case certUsageVerifyCA:
               /* these usages cannot be verified */
-              NEXT_ITERATION();
+              NEXT_USAGE();
 
           default:
             PORT_Assert(0);
             requiredKeyUsage = 0;
             requiredCertType = 0;
             INVALID_USAGE();
         }
         if ( CERT_CheckKeyUsage(cert, requiredKeyUsage) != SECSuccess ) {
@@ -1403,17 +1403,17 @@ CERT_VerifyCertificate(CERTCertDBHandle 
                         LOG_ERROR(log,cert,0,0);
                         revoked = PR_TRUE;
                         INVALID_USAGE();
                     }
                 }
             }
         }
 
-        NEXT_ITERATION();
+        NEXT_USAGE();
     }
     
     return(valid);
 }
 			
 /* obsolete, do not use for new code */
 SECStatus
 CERT_VerifyCert(CERTCertDBHandle *handle, CERTCertificate *cert,
--- a/security/nss/lib/cryptohi/secsign.c
+++ b/security/nss/lib/cryptohi/secsign.c
@@ -196,17 +196,17 @@ SGN_Update(SGNContext *cx, unsigned char
     }
     (*cx->hashobj->update)(cx->hashcx, input, inputLen);
     return SECSuccess;
 }
 
 SECStatus
 SGN_End(SGNContext *cx, SECItem *result)
 {
-    unsigned char digest[32];
+    unsigned char digest[HASH_LENGTH_MAX];
     unsigned part1, signatureLen;
     SECStatus rv;
     SECItem digder, sigitem;
     PRArenaPool *arena = 0;
     SECKEYPrivateKey *privKey = cx->key;
     SGNDigestInfo *di = 0;
 
     result->data = 0;
--- a/security/nss/lib/cryptohi/secvfy.c
+++ b/security/nss/lib/cryptohi/secvfy.c
@@ -78,17 +78,17 @@ DecryptSigBlock(SECOidTag *tagp, unsigne
     if (di == NULL) goto sigloser;
 
     /*
     ** Finally we have the digest info; now we can extract the algorithm
     ** ID and the signature block
     */
     tag = SECOID_GetAlgorithmTag(&di->digestAlgorithm);
     /* XXX Check that tag is an appropriate algorithm? */
-    if (di->digest.len > 32) {
+    if (di->digest.len > HASH_LENGTH_MAX) {
 	PORT_SetError(SEC_ERROR_OUTPUT_LEN);
 	goto loser;
     }
     PORT_Memcpy(digest, di->digest.data, di->digest.len);
     *tagp = tag;
     goto done;
 
   sigloser:
@@ -105,18 +105,21 @@ DecryptSigBlock(SECOidTag *tagp, unsigne
 }
 
 typedef enum { VFY_RSA, VFY_DSA, VFY_ECDSA } VerifyType;
 
 struct VFYContextStr {
     SECOidTag alg;
     VerifyType type;
     SECKEYPublicKey *key;
-    /* digest holds the full dsa signature... 40 bytes */
-    unsigned char digest[DSA_SIGNATURE_LEN];
+    /*
+     * digest holds either the hash (<= HASH_LENGTH_MAX=64 bytes)
+     * in the RSA signature, or the full DSA signature (40 bytes).
+     */
+    unsigned char digest[HASH_LENGTH_MAX];
     void * wincx;
     void *hashcx;
     const SECHashObject *hashobj;
     SECOidTag sigAlg;
     PRBool hasSignature;
     unsigned char ecdsadigest[2 * MAX_ECKEY_LEN];
 };
 
@@ -345,17 +348,17 @@ VFY_Update(VFYContext *cx, unsigned char
     }
     (*cx->hashobj->update)(cx->hashcx, input, inputLen);
     return SECSuccess;
 }
 
 SECStatus
 VFY_EndWithSignature(VFYContext *cx, SECItem *sig)
 {
-    unsigned char final[32];
+    unsigned char final[HASH_LENGTH_MAX];
     unsigned part;
     SECItem hash,dsasig; /* dsasig is also used for ECDSA */
     SECStatus rv;
 
     if ((cx->hasSignature == PR_FALSE) && (sig == NULL)) {
 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
 	return SECFailure;
     }
--- a/security/nss/lib/dev/devslot.c
+++ b/security/nss/lib/dev/devslot.c
@@ -351,26 +351,29 @@ nssSlot_IsTokenPresent (
 	    session->handle = CK_INVALID_SESSION;
 	}
     }
     nssSession_ExitMonitor(session);
     /* token not removed, finished */
     if (session->handle != CK_INVALID_SESSION) {
 	return PR_TRUE;
     } else {
-	/* the token has been removed, and reinserted, invalidate all the old
-	 * information we had on this token */
+	/* the token has been removed, and reinserted, or the slot contains
+	 * a token it doesn't recognize. invalidate all the old
+	 * information we had on this token, if we can't refresh, clear
+	 * the present flag */
 #ifdef NSS_3_4_CODE
 	nssToken_NotifyCertsNotVisible(slot->token);
 #endif /* NSS_3_4_CODE */
 	nssToken_Remove(slot->token);
 	/* token has been removed, need to refresh with new session */
 	nssrv = nssSlot_Refresh(slot);
 	if (nssrv != PR_SUCCESS) {
 	    slot->token->base.name[0] = 0; /* XXX */
+	    slot->ckFlags &= ~CKF_TOKEN_PRESENT;
 	    return PR_FALSE;
 	}
 	return PR_TRUE;
     }
 }
 
 #ifdef PURE_STAN_BUILD
 NSS_IMPLEMENT NSSModule *
--- a/security/nss/lib/freebl/dsa.c
+++ b/security/nss/lib/freebl/dsa.c
@@ -183,21 +183,22 @@ dsa_SignDigest(DSAPrivateKey *key, SECIt
     mp_int x, k;     /* private key & pseudo-random integer */
     mp_int r, s;     /* tuple (r, s) is signature) */
     mp_err err   = MP_OKAY;
     SECStatus rv = SECSuccess;
 
     /* FIPS-compliance dictates that digest is a SHA1 hash. */
     /* Check args. */
     if (!key || !signature || !digest ||
-        (signature->len != DSA_SIGNATURE_LEN) ||
+        (signature->len < DSA_SIGNATURE_LEN) ||
 	(digest->len != SHA1_LENGTH)) {
 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
 	return SECFailure;
     }
+
     /* Initialize MPI integers. */
     MP_DIGITS(&p) = 0;
     MP_DIGITS(&q) = 0;
     MP_DIGITS(&g) = 0;
     MP_DIGITS(&x) = 0;
     MP_DIGITS(&k) = 0;
     MP_DIGITS(&r) = 0;
     MP_DIGITS(&s) = 0;
@@ -248,16 +249,17 @@ dsa_SignDigest(DSAPrivateKey *key, SECIt
     ** Signature is tuple (r, s)
     */
     err = mp_to_fixlen_octets(&r, signature->data, DSA_SUBPRIME_LEN);
     if (err < 0) goto cleanup; 
     err = mp_to_fixlen_octets(&s, signature->data + DSA_SUBPRIME_LEN, 
                                   DSA_SUBPRIME_LEN);
     if (err < 0) goto cleanup; 
     err = MP_OKAY;
+    signature->len = DSA_SIGNATURE_LEN;
 cleanup:
     mp_clear(&p);
     mp_clear(&q);
     mp_clear(&g);
     mp_clear(&x);
     mp_clear(&k);
     mp_clear(&r);
     mp_clear(&s);
--- a/security/nss/lib/freebl/loader.c
+++ b/security/nss/lib/freebl/loader.c
@@ -118,22 +118,48 @@ typedef struct {
     void *dlh;
 } BLLibrary;
 
 static BLLibrary *
 bl_LoadLibrary(const char *name)
 {
     BLLibrary *lib;
     const char *error;
+    Dl_info dli;
 
     lib = PR_NEWZAP(BLLibrary);
     if (NULL == lib) {
         PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
         return NULL;
     }
+
+    /*
+     * In setuid applications, Solaris is unwilling to load freebl unless
+     * we specify an absolute path.  We construct one from the path of the
+     * library that contains this function.
+     */
+    if (dladdr((void *)bl_LoadLibrary, &dli) != 0) {
+        const char *slash = strrchr(dli.dli_fname, '/');
+        if (slash) {
+            size_t dirsize = slash - dli.dli_fname + 1;
+            char *pathname = PR_Malloc(dirsize + strlen(name) + 1);
+            if (NULL == pathname) {
+                PR_Free(lib);
+                PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+                return NULL;
+            }
+            memcpy(pathname, dli.dli_fname, dirsize);
+            strcpy(pathname + dirsize, name);
+            lib->dlh = dlopen(pathname, RTLD_NOW | RTLD_LOCAL);
+            PR_Free(pathname);
+            if (NULL != lib->dlh)
+                return lib;
+        }
+    }
+
     lib->dlh = dlopen(name, RTLD_NOW | RTLD_LOCAL);
     if (NULL == lib->dlh) {
         PR_SetError(PR_LOAD_LIBRARY_ERROR, 0);
         error = dlerror();
         if (NULL != error)
             PR_SetErrorText(strlen(error), error);
         PR_Free(lib);
         return NULL;
--- a/security/nss/lib/freebl/rsa.c
+++ b/security/nss/lib/freebl/rsa.c
@@ -61,16 +61,21 @@
 ** Number of times to attempt to generate a key.  The primes p and q change
 ** for each attempt.
 */
 #define MAX_KEY_GEN_ATTEMPTS 10
 
 #define MAX_RSA_MODULUS  1024 /* bytes, 8k bits */
 #define MAX_RSA_EXPONENT    8 /* bytes, 64 bits */
 
+/* exponent should not be greater than modulus */
+#define BAD_RSA_KEY_SIZE(modLen, expLen) \
+    ((expLen) > (modLen) || (modLen) > MAX_RSA_MODULUS || \
+    (expLen) > MAX_RSA_EXPONENT)
+
 /*
 ** RSABlindingParamsStr
 **
 ** For discussion of Paul Kocher's timing attack against an RSA private key
 ** operation, see http://www.cryptography.com/timingattack/paper.html.  The 
 ** countermeasure to this attack, known as blinding, is also discussed in 
 ** the Handbook of Applied Cryptography, 11.118-11.119.
 */
@@ -226,17 +231,18 @@ RSA_NewKey(int keySizeInBits, SECItem *p
     mp_int p, q, e;
     int kiter;
     mp_err   err = MP_OKAY;
     SECStatus rv = SECSuccess;
     int prerr = 0;
     RSAPrivateKey *key = NULL;
     PRArenaPool *arena = NULL;
     /* Require key size to be a multiple of 16 bits. */
-    if (!publicExponent || keySizeInBits % 16 != 0) {
+    if (!publicExponent || keySizeInBits % 16 != 0 ||
+	    BAD_RSA_KEY_SIZE(keySizeInBits/8, publicExponent->len)) {
 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
 	return NULL;
     }
     /* 1. Allocate arena & key */
     arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE);
     if (!arena) {
 	PORT_SetError(SEC_ERROR_NO_MEMORY);
 	return NULL;
@@ -329,18 +335,17 @@ RSA_PublicKeyOp(RSAPublicKey  *key,
     MP_DIGITS(&c) = 0;
     CHECK_MPI_OK( mp_init(&n) );
     CHECK_MPI_OK( mp_init(&e) );
     CHECK_MPI_OK( mp_init(&m) );
     CHECK_MPI_OK( mp_init(&c) );
     modLen = rsa_modulusLen(&key->modulus);
     expLen = rsa_modulusLen(&key->publicExponent);
     /* 1.  Obtain public key (n, e) */
-    if (expLen > modLen || modLen > MAX_RSA_MODULUS || expLen > MAX_RSA_EXPONENT) {
-	/* exponent should not be greater than modulus */
+    if (BAD_RSA_KEY_SIZE(modLen, expLen)) {
     	PORT_SetError(SEC_ERROR_INVALID_KEY);
 	rv = SECFailure;
 	goto cleanup;
     }
     SECITEM_TO_MPINT(key->modulus, &n);
     SECITEM_TO_MPINT(key->publicExponent, &e);
     if (e.used > n.used) {
 	/* exponent should not be greater than modulus */
--- a/security/nss/lib/freebl/unix_rand.c
+++ b/security/nss/lib/freebl/unix_rand.c
@@ -828,17 +828,17 @@ for the small amount of entropy it provi
 
     /*
      * Pass the C environment and the addresses of the pointers to the
      * hash function. This makes the random number function depend on the
      * execution environment of the user and on the platform the program
      * is running on.
      */
     if (environ != NULL) {
-        cp = environ;
+        cp = (const char * const *) environ;
         while (*cp) {
 	    RNG_RandomUpdate(*cp, strlen(*cp));
 	    cp++;
         }
         RNG_RandomUpdate(environ, (char*)cp - (char*)environ);
     }
 
     /* Give in system information */
--- a/security/nss/lib/nss/nss.def
+++ b/security/nss/lib/nss/nss.def
@@ -845,8 +845,15 @@ SECOID_AddEntry;
 ;+# Don't export these DATA symbols on Windows because they don't work right.
 ;;CERT_SequenceOfCertExtensionTemplate DATA ;
 ;;CERT_SignedCrlTemplate DATA ;
 NSS_Get_CERT_SequenceOfCertExtensionTemplate;
 NSS_Get_CERT_SignedCrlTemplate;
 ;+    local:
 ;+       *;
 ;+};
+;+NSS_3.10.2 { 	# NSS 3.10.2 release
+;+    global:
+PK11_TokenKeyGenWithFlags;
+PK11_GenerateKeyPairWithFlags;
+;+    local:
+;+       *;
+;+};
--- a/security/nss/lib/nss/nss.h
+++ b/security/nss/lib/nss/nss.h
@@ -47,21 +47,21 @@ SEC_BEGIN_PROTOS
 
 /*
  * NSS's major version, minor version, patch level, and whether
  * this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>] [<Beta>]"
  */
-#define NSS_VERSION  "3.10.1 Beta"
+#define NSS_VERSION  "3.10.2"
 #define NSS_VMAJOR   3
 #define NSS_VMINOR   10
-#define NSS_VPATCH   1
-#define NSS_BETA     PR_TRUE
+#define NSS_VPATCH   2
+#define NSS_BETA     PR_FALSE
 
 
 /*
  * Return a boolean that indicates whether the underlying library
  * will perform as the caller expects.
  *
  * The only argument is a string, which should be the verson
  * identifier of the NSS library. That string will be compared
--- a/security/nss/lib/pk11wrap/pk11akey.c
+++ b/security/nss/lib/pk11wrap/pk11akey.c
@@ -762,16 +762,158 @@ failure:
 
 
 /*
  * take a private key in one pkcs11 module and load it into another:
  *  NOTE: the source private key is a rare animal... it can't be sensitive.
  *  This is used to do a key gen using one pkcs11 module and storing the
  *  result into another.
  */
+static SECKEYPrivateKey *
+pk11_loadPrivKeyWithFlags(PK11SlotInfo *slot,SECKEYPrivateKey *privKey, 
+		SECKEYPublicKey *pubKey, PK11AttrFlags attrFlags) 
+{
+    CK_ATTRIBUTE privTemplate[] = {
+        /* class must be first */
+	{ CKA_CLASS, NULL, 0 },
+	{ CKA_KEY_TYPE, NULL, 0 },
+	{ CKA_ID, NULL, 0 },
+#ifdef notdef
+	{ CKA_LABEL, NULL, 0 },
+	{ CKA_SUBJECT, NULL, 0 },
+#endif
+	/* RSA */
+	{ CKA_MODULUS, NULL, 0 },
+	{ CKA_PRIVATE_EXPONENT, NULL, 0 },
+	{ CKA_PUBLIC_EXPONENT, NULL, 0 },
+	{ CKA_PRIME_1, NULL, 0 },
+	{ CKA_PRIME_2, NULL, 0 },
+	{ CKA_EXPONENT_1, NULL, 0 },
+	{ CKA_EXPONENT_2, NULL, 0 },
+	{ CKA_COEFFICIENT, NULL, 0 },
+	/* reserve space for the attributes that may be
+	 * specified in attrFlags */
+	{ CKA_TOKEN, NULL, 0 },
+	{ CKA_PRIVATE, NULL, 0 },
+	{ CKA_MODIFIABLE, NULL, 0 },
+	{ CKA_SENSITIVE, NULL, 0 },
+	{ CKA_EXTRACTABLE, NULL, 0 },
+#define NUM_RESERVED_ATTRS 5    /* number of reserved attributes above */
+    };
+    CK_BBOOL cktrue = CK_TRUE;
+    CK_BBOOL ckfalse = CK_FALSE;
+    CK_ATTRIBUTE *attrs = NULL, *ap;
+    const int templateSize = sizeof(privTemplate)/sizeof(privTemplate[0]);
+    PRArenaPool *arena;
+    CK_OBJECT_HANDLE objectID;
+    int i, count = 0;
+    int extra_count = 0;
+    CK_RV crv;
+    SECStatus rv;
+    PRBool token = ((attrFlags & PK11_ATTR_TOKEN) != 0);
+
+    if (pk11_BadAttrFlags(attrFlags)) {
+	PORT_SetError(SEC_ERROR_INVALID_ARGS);
+	return NULL;
+    }
+
+    for (i=0; i < templateSize; i++) {
+	if (privTemplate[i].type == CKA_MODULUS) {
+	    attrs= &privTemplate[i];
+	    count = i;
+	    break;
+	}
+    }
+    PORT_Assert(attrs != NULL);
+    if (attrs == NULL) {
+	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+	return NULL;
+    }
+
+    ap = attrs;
+
+    switch (privKey->keyType) {
+    case rsaKey:
+	count = templateSize - NUM_RESERVED_ATTRS;
+	extra_count = count - (attrs - privTemplate);
+	break;
+    case dsaKey:
+	ap->type = CKA_PRIME; ap++; count++; extra_count++;
+	ap->type = CKA_SUBPRIME; ap++; count++; extra_count++;
+	ap->type = CKA_BASE; ap++; count++; extra_count++;
+	ap->type = CKA_VALUE; ap++; count++; extra_count++;
+	break;
+    case dhKey:
+	ap->type = CKA_PRIME; ap++; count++; extra_count++;
+	ap->type = CKA_BASE; ap++; count++; extra_count++;
+	ap->type = CKA_VALUE; ap++; count++; extra_count++;
+	break;
+#ifdef NSS_ENABLE_ECC
+    case ecKey:
+	ap->type = CKA_EC_PARAMS; ap++; count++; extra_count++;
+	ap->type = CKA_VALUE; ap++; count++; extra_count++;
+	break;
+#endif /* NSS_ENABLE_ECC */       
+     default:
+	count = 0;
+	extra_count = 0;
+	break;
+     }
+
+     if (count == 0) {
+	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+	return NULL;
+     }
+
+     arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
+     if (arena == NULL) return NULL;
+     /*
+      * read out the old attributes.
+      */
+     crv = PK11_GetAttributes(arena, privKey->pkcs11Slot, privKey->pkcs11ID,
+		privTemplate,count);
+     if (crv != CKR_OK) {
+	PORT_SetError( PK11_MapError(crv) );
+	PORT_FreeArena(arena, PR_TRUE);
+	return NULL;
+     }
+
+     /* Set token, private, modifiable, sensitive, and extractable */
+     count += pk11_AttrFlagsToAttributes(attrFlags, &privTemplate[count],
+					&cktrue, &ckfalse);
+
+     /* Not everyone can handle zero padded key values, give
+      * them the raw data as unsigned */
+     for (ap=attrs; extra_count; ap++, extra_count--) {
+	pk11_SignedToUnsigned(ap);
+     }
+
+     /* now Store the puppies */
+     rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION, privTemplate, 
+						count, token, &objectID);
+     PORT_FreeArena(arena, PR_TRUE);
+     if (rv != SECSuccess) {
+	return NULL;
+     }
+
+     /* try loading the public key */
+     if (pubKey) {
+	PK11_ImportPublicKey(slot, pubKey, token);
+	if (pubKey->pkcs11Slot) {
+	    PK11_FreeSlot(pubKey->pkcs11Slot);
+	    pubKey->pkcs11Slot = NULL;
+	    pubKey->pkcs11ID = CK_INVALID_HANDLE;
+	}
+     }
+
+     /* build new key structure */
+     return PK11_MakePrivKey(slot, privKey->keyType, !token, 
+						objectID, privKey->wincx);
+}
+
 SECKEYPrivateKey *
 pk11_loadPrivKey(PK11SlotInfo *slot,SECKEYPrivateKey *privKey, 
 		SECKEYPublicKey *pubKey, PRBool token, PRBool sensitive) 
 {
     CK_ATTRIBUTE privTemplate[] = {
         /* class must be first */
 	{ CKA_CLASS, NULL, 0 },
 	{ CKA_KEY_TYPE, NULL, 0 },
@@ -905,19 +1047,437 @@ SECKEYPrivateKey *
 PK11_LoadPrivKey(PK11SlotInfo *slot,SECKEYPrivateKey *privKey, 
 		SECKEYPublicKey *pubKey, PRBool token, PRBool sensitive) 
 {
     return pk11_loadPrivKey(slot,privKey,pubKey,token,sensitive);
 }
 
 
 /*
- * Use the token to Generate a key. keySize must be 'zero' for fixed key
- * length algorithms. NOTE: this means we can never generate a DES2 key
- * from this interface!
+ * Use the token to generate a key pair.
+ */
+SECKEYPrivateKey *
+PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type, 
+   void *param, SECKEYPublicKey **pubKey, PK11AttrFlags attrFlags, void *wincx)
+{
+    /* we have to use these native types because when we call PKCS 11 modules
+     * we have to make sure that we are using the correct sizes for all the
+     * parameters. */
+    CK_BBOOL ckfalse = CK_FALSE;
+    CK_BBOOL cktrue = CK_TRUE;
+    CK_ULONG modulusBits;
+    CK_BYTE publicExponent[4];
+    CK_ATTRIBUTE privTemplate[] = {
+	{ CKA_SENSITIVE, NULL, 0},
+	{ CKA_TOKEN,  NULL, 0},
+	{ CKA_PRIVATE,  NULL, 0},
+	{ CKA_DERIVE,  NULL, 0},
+	{ CKA_UNWRAP,  NULL, 0},
+	{ CKA_SIGN,  NULL, 0},
+	{ CKA_DECRYPT,  NULL, 0},
+	{ CKA_EXTRACTABLE, NULL, 0},
+	{ CKA_MODIFIABLE,  NULL, 0},
+    };
+    CK_ATTRIBUTE rsaPubTemplate[] = {
+	{ CKA_MODULUS_BITS, NULL, 0},
+	{ CKA_PUBLIC_EXPONENT, NULL, 0},
+	{ CKA_TOKEN,  NULL, 0},
+	{ CKA_DERIVE,  NULL, 0},
+	{ CKA_WRAP,  NULL, 0},
+	{ CKA_VERIFY,  NULL, 0},
+	{ CKA_VERIFY_RECOVER,  NULL, 0},
+	{ CKA_ENCRYPT,  NULL, 0},
+	{ CKA_MODIFIABLE,  NULL, 0},
+    };
+    CK_ATTRIBUTE dsaPubTemplate[] = {
+	{ CKA_PRIME, NULL, 0 },
+	{ CKA_SUBPRIME, NULL, 0 },
+	{ CKA_BASE, NULL, 0 },
+	{ CKA_TOKEN,  NULL, 0},
+	{ CKA_DERIVE,  NULL, 0},
+	{ CKA_WRAP,  NULL, 0},
+	{ CKA_VERIFY,  NULL, 0},
+	{ CKA_VERIFY_RECOVER,  NULL, 0},
+	{ CKA_ENCRYPT,  NULL, 0},
+	{ CKA_MODIFIABLE,  NULL, 0},
+    };
+    CK_ATTRIBUTE dhPubTemplate[] = {
+      { CKA_PRIME, NULL, 0 }, 
+      { CKA_BASE, NULL, 0 }, 
+      { CKA_TOKEN,  NULL, 0},
+      { CKA_DERIVE,  NULL, 0},
+      { CKA_WRAP,  NULL, 0},
+      { CKA_VERIFY,  NULL, 0},
+      { CKA_VERIFY_RECOVER,  NULL, 0},
+      { CKA_ENCRYPT,  NULL, 0},
+      { CKA_MODIFIABLE,  NULL, 0},
+    };
+#ifdef NSS_ENABLE_ECC
+    CK_ATTRIBUTE ecPubTemplate[] = {
+      { CKA_EC_PARAMS, NULL, 0 }, 
+      { CKA_TOKEN,  NULL, 0},
+      { CKA_DERIVE,  NULL, 0},
+      { CKA_WRAP,  NULL, 0},
+      { CKA_VERIFY,  NULL, 0},
+      { CKA_VERIFY_RECOVER,  NULL, 0},
+      { CKA_ENCRYPT,  NULL, 0},
+      { CKA_MODIFIABLE,  NULL, 0},
+    };
+    SECKEYECParams * ecParams;
+#endif /* NSS_ENABLE_ECC */
+
+    /*CK_ULONG key_size = 0;*/
+    CK_ATTRIBUTE *pubTemplate;
+    int privCount = 0;
+    int pubCount = 0;
+    PK11RSAGenParams *rsaParams;
+    SECKEYPQGParams *dsaParams;
+    SECKEYDHParams * dhParams;
+    CK_MECHANISM mechanism;
+    CK_MECHANISM test_mech;
+    CK_SESSION_HANDLE session_handle;
+    CK_RV crv;
+    CK_OBJECT_HANDLE privID,pubID;
+    SECKEYPrivateKey *privKey;
+    KeyType keyType;
+    PRBool restore;
+    int peCount,i;
+    CK_ATTRIBUTE *attrs;
+    CK_ATTRIBUTE *privattrs;
+    SECItem *pubKeyIndex;
+    CK_ATTRIBUTE setTemplate;
+    SECStatus rv;
+    CK_MECHANISM_INFO mechanism_info;
+    CK_OBJECT_CLASS keyClass;
+    SECItem *cka_id;
+    PRBool haslock = PR_FALSE;
+    PRBool pubIsToken = PR_FALSE;
+    PRBool token = ((attrFlags & PK11_ATTR_TOKEN) != 0);
+    /* subset of attrFlags applicable to the public key */
+    PK11AttrFlags pubKeyAttrFlags = attrFlags &
+	(PK11_ATTR_TOKEN | PK11_ATTR_SESSION
+	| PK11_ATTR_MODIFIABLE | PK11_ATTR_UNMODIFIABLE);
+
+    if (pk11_BadAttrFlags(attrFlags)) {
+	PORT_SetError( SEC_ERROR_INVALID_ARGS );
+	return NULL;
+    }
+
+    PORT_Assert(slot != NULL);
+    if (slot == NULL) {
+	PORT_SetError( SEC_ERROR_NO_MODULE);
+	return NULL;
+    }
+
+    /* if our slot really doesn't do this mechanism, Generate the key
+     * in our internal token and write it out */
+    if (!PK11_DoesMechanism(slot,type)) {
+	PK11SlotInfo *int_slot = PK11_GetInternalSlot();
+
+	/* don't loop forever looking for a slot */
+	if (slot == int_slot) {
+	    PK11_FreeSlot(int_slot);
+	    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+	    return NULL;
+	}
+
+	/* if there isn't a suitable slot, then we can't do the keygen */
+	if (int_slot == NULL) {
+	    PORT_SetError( SEC_ERROR_NO_MODULE );
+	    return NULL;
+	}
+
+	/* generate the temporary key to load */
+	privKey = PK11_GenerateKeyPair(int_slot,type, param, pubKey, PR_FALSE, 
+							PR_FALSE, wincx);
+	PK11_FreeSlot(int_slot);
+
+	/* if successful, load the temp key into the new token */
+	if (privKey != NULL) {
+	    SECKEYPrivateKey *newPrivKey = pk11_loadPrivKeyWithFlags(slot,
+						privKey,*pubKey,attrFlags);
+	    SECKEY_DestroyPrivateKey(privKey);
+	    if (newPrivKey == NULL) {
+		SECKEY_DestroyPublicKey(*pubKey);
+		*pubKey = NULL;
+	    }
+	    return newPrivKey;
+	}
+	return NULL;
+   }
+
+
+    mechanism.mechanism = type;
+    mechanism.pParameter = NULL;
+    mechanism.ulParameterLen = 0;
+    test_mech.pParameter = NULL;
+    test_mech.ulParameterLen = 0;
+
+    /* set up the private key template */
+    privattrs = privTemplate;
+    privattrs += pk11_AttrFlagsToAttributes(attrFlags, privattrs,
+						&cktrue, &ckfalse);
+
+    /* set up the mechanism specific info */
+    switch (type) {
+    case CKM_RSA_PKCS_KEY_PAIR_GEN:
+	rsaParams = (PK11RSAGenParams *)param;
+	modulusBits = rsaParams->keySizeInBits;
+	peCount = 0;
+
+	/* convert pe to a PKCS #11 string */
+	for (i=0; i < 4; i++) {
+	    if (peCount || (rsaParams->pe & 
+				((unsigned long)0xff000000L >> (i*8)))) {
+		publicExponent[peCount] = 
+				(CK_BYTE)((rsaParams->pe >> (3-i)*8) & 0xff);
+		peCount++;
+	    }
+	}
+	PORT_Assert(peCount != 0);
+	attrs = rsaPubTemplate;
+	PK11_SETATTRS(attrs, CKA_MODULUS_BITS, 
+				&modulusBits, sizeof(modulusBits)); attrs++;
+	PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT, 
+				publicExponent, peCount);attrs++;
+	pubTemplate = rsaPubTemplate;
+	keyType = rsaKey;
+	test_mech.mechanism = CKM_RSA_PKCS;
+	break;
+    case CKM_DSA_KEY_PAIR_GEN:
+	dsaParams = (SECKEYPQGParams *)param;
+	attrs = dsaPubTemplate;
+	PK11_SETATTRS(attrs, CKA_PRIME, dsaParams->prime.data,
+				dsaParams->prime.len); attrs++;
+	PK11_SETATTRS(attrs, CKA_SUBPRIME, dsaParams->subPrime.data,
+					dsaParams->subPrime.len); attrs++;
+	PK11_SETATTRS(attrs, CKA_BASE, dsaParams->base.data,
+						dsaParams->base.len); attrs++;
+	pubTemplate = dsaPubTemplate;
+	keyType = dsaKey;
+	test_mech.mechanism = CKM_DSA;
+	break;
+    case CKM_DH_PKCS_KEY_PAIR_GEN:
+        dhParams = (SECKEYDHParams *)param;
+        attrs = dhPubTemplate;
+        PK11_SETATTRS(attrs, CKA_PRIME, dhParams->prime.data,
+                      dhParams->prime.len);   attrs++;
+        PK11_SETATTRS(attrs, CKA_BASE, dhParams->base.data,
+                      dhParams->base.len);    attrs++;
+        pubTemplate = dhPubTemplate;
+        keyType = dhKey;
+        test_mech.mechanism = CKM_DH_PKCS_DERIVE;
+	break;
+#ifdef NSS_ENABLE_ECC
+    case CKM_EC_KEY_PAIR_GEN:
+        ecParams = (SECKEYECParams *)param;
+        attrs = ecPubTemplate;
+        PK11_SETATTRS(attrs, CKA_EC_PARAMS, ecParams->data, 
+	              ecParams->len);   attrs++;
+        pubTemplate = ecPubTemplate;
+        keyType = ecKey;
+	/* XXX An EC key can be used for other mechanisms too such
+	 * as CKM_ECDSA and CKM_ECDSA_SHA1. How can we reflect
+	 * that in test_mech.mechanism so the CKA_SIGN, CKA_VERIFY
+	 * attributes are set correctly? 
+	 */
+        test_mech.mechanism = CKM_ECDH1_DERIVE;
+        break;
+#endif /* NSS_ENABLE_ECC */
+    default:
+	PORT_SetError( SEC_ERROR_BAD_KEY );
+	return NULL;
+    }
+
+    /* now query the slot to find out how "good" a key we can generate */
+    if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
+    crv = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID,
+				test_mech.mechanism,&mechanism_info);
+    if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
+    if ((crv != CKR_OK) || (mechanism_info.flags == 0)) {
+	/* must be old module... guess what it should be... */
+	switch (test_mech.mechanism) {
+	case CKM_RSA_PKCS:
+		mechanism_info.flags = (CKF_SIGN | CKF_DECRYPT | 
+			CKF_WRAP | CKF_VERIFY_RECOVER | CKF_ENCRYPT | CKF_WRAP);;
+		break;
+	case CKM_DSA:
+		mechanism_info.flags = CKF_SIGN | CKF_VERIFY;
+		break;
+	case CKM_DH_PKCS_DERIVE:
+		mechanism_info.flags = CKF_DERIVE;
+		break;
+#ifdef NSS_ENABLE_ECC
+	case CKM_ECDH1_DERIVE:
+		mechanism_info.flags = CKF_DERIVE;
+		break;
+	case CKM_ECDSA:
+	case CKM_ECDSA_SHA1:
+		mechanism_info.flags = CKF_SIGN | CKF_VERIFY;
+		break;
+#endif /* NSS_ENABLE_ECC */
+	default:
+	       break;
+	}
+    }
+    /* set the public key attributes */
+    attrs += pk11_AttrFlagsToAttributes(pubKeyAttrFlags, attrs,
+						&cktrue, &ckfalse);
+    PK11_SETATTRS(attrs, CKA_DERIVE, 
+		mechanism_info.flags & CKF_DERIVE ? &cktrue : &ckfalse,
+					 sizeof(CK_BBOOL)); attrs++;
+    PK11_SETATTRS(attrs, CKA_WRAP, 
+		mechanism_info.flags & CKF_WRAP ? &cktrue : &ckfalse,
+					 sizeof(CK_BBOOL)); attrs++;
+    PK11_SETATTRS(attrs, CKA_VERIFY, 
+		mechanism_info.flags & CKF_VERIFY ? &cktrue : &ckfalse,
+					 sizeof(CK_BBOOL)); attrs++;
+    PK11_SETATTRS(attrs, CKA_VERIFY_RECOVER, 
+		mechanism_info.flags & CKF_VERIFY_RECOVER ? &cktrue : &ckfalse,
+					 sizeof(CK_BBOOL)); attrs++;
+    PK11_SETATTRS(attrs, CKA_ENCRYPT, 
+		mechanism_info.flags & CKF_ENCRYPT? &cktrue : &ckfalse,
+					 sizeof(CK_BBOOL)); attrs++;
+    /* set the private key attributes */
+    PK11_SETATTRS(privattrs, CKA_DERIVE, 
+		mechanism_info.flags & CKF_DERIVE ? &cktrue : &ckfalse,
+					 sizeof(CK_BBOOL)); privattrs++;
+    PK11_SETATTRS(privattrs, CKA_UNWRAP, 
+		mechanism_info.flags & CKF_UNWRAP ? &cktrue : &ckfalse,
+					 sizeof(CK_BBOOL)); privattrs++;
+    PK11_SETATTRS(privattrs, CKA_SIGN, 
+		mechanism_info.flags & CKF_SIGN ? &cktrue : &ckfalse,
+					 sizeof(CK_BBOOL)); privattrs++;
+    PK11_SETATTRS(privattrs, CKA_DECRYPT, 
+		mechanism_info.flags & CKF_DECRYPT ? &cktrue : &ckfalse,
+					 sizeof(CK_BBOOL)); privattrs++;
+
+    if (token) {
+	session_handle = PK11_GetRWSession(slot);
+	haslock = PK11_RWSessionHasLock(slot,session_handle);
+	restore = PR_TRUE;
+    } else {
+        PK11_EnterSlotMonitor(slot); /* gross!! */
+	session_handle = slot->session;
+	restore = PR_FALSE;
+	haslock = PR_TRUE;
+    }
+
+    privCount = privattrs - privTemplate;
+    pubCount = attrs - pubTemplate;
+    crv = PK11_GETTAB(slot)->C_GenerateKeyPair(session_handle, &mechanism,
+	pubTemplate,pubCount,privTemplate,privCount,&pubID,&privID);
+
+    if (crv != CKR_OK) {
+	if (restore)  {
+	    PK11_RestoreROSession(slot,session_handle);
+	} else PK11_ExitSlotMonitor(slot);
+	PORT_SetError( PK11_MapError(crv) );
+	return NULL;
+    }
+    /* This locking code is dangerous and needs to be more thought
+     * out... the real problem is that we're holding the mutex open this long
+     */
+    if (haslock) { PK11_ExitSlotMonitor(slot); }
+
+    /* swap around the ID's for older PKCS #11 modules */
+    keyClass = PK11_ReadULongAttribute(slot,pubID,CKA_CLASS);
+    if (keyClass != CKO_PUBLIC_KEY) {
+	CK_OBJECT_HANDLE tmp = pubID;
+	pubID = privID;
+	privID = tmp;
+    }
+
+    *pubKey = PK11_ExtractPublicKey(slot, keyType, pubID);
+    if (*pubKey == NULL) {
+	if (restore)  {
+	    /* we may have to restore the mutex so it get's exited properly
+	     * in RestoreROSession */
+            if (haslock)  PK11_EnterSlotMonitor(slot); 
+	    PK11_RestoreROSession(slot,session_handle);
+	} 
+	PK11_DestroyObject(slot,pubID);
+	PK11_DestroyObject(slot,privID);
+	return NULL;
+    }
+
+    /* set the ID to the public key so we can find it again */
+    pubKeyIndex =  NULL;
+    switch (type) {
+    case CKM_RSA_PKCS_KEY_PAIR_GEN:
+      pubKeyIndex = &(*pubKey)->u.rsa.modulus;
+      break;
+    case CKM_DSA_KEY_PAIR_GEN:
+      pubKeyIndex = &(*pubKey)->u.dsa.publicValue;
+      break;
+    case CKM_DH_PKCS_KEY_PAIR_GEN:
+      pubKeyIndex = &(*pubKey)->u.dh.publicValue;
+      break;      
+#ifdef NSS_ENABLE_ECC
+    case CKM_EC_KEY_PAIR_GEN:
+      pubKeyIndex = &(*pubKey)->u.ec.publicValue;
+      break;      
+#endif /* NSS_ENABLE_ECC */
+    }
+    PORT_Assert(pubKeyIndex != NULL);
+
+    cka_id = PK11_MakeIDFromPubKey(pubKeyIndex);
+    pubIsToken = (PRBool)PK11_HasAttributeSet(slot,pubID, CKA_TOKEN);
+
+    PK11_SETATTRS(&setTemplate, CKA_ID, cka_id->data, cka_id->len);
+
+    if (haslock) { PK11_EnterSlotMonitor(slot); }
+    crv = PK11_GETTAB(slot)->C_SetAttributeValue(session_handle, privID,
+		&setTemplate, 1);
+   
+    if (crv == CKR_OK && pubIsToken) {
+    	crv = PK11_GETTAB(slot)->C_SetAttributeValue(session_handle, pubID,
+		&setTemplate, 1);
+    }
+
+
+    if (restore) {
+	PK11_RestoreROSession(slot,session_handle);
+    } else {
+	PK11_ExitSlotMonitor(slot);
+    }
+    SECITEM_FreeItem(cka_id,PR_TRUE);
+
+
+    if (crv != CKR_OK) {
+	PK11_DestroyObject(slot,pubID);
+	PK11_DestroyObject(slot,privID);
+	PORT_SetError( PK11_MapError(crv) );
+	*pubKey = NULL;
+	return NULL;
+    }
+
+    privKey = PK11_MakePrivKey(slot,keyType,!token,privID,wincx);
+    if (privKey == NULL) {
+	SECKEY_DestroyPublicKey(*pubKey);
+	PK11_DestroyObject(slot,privID);
+	*pubKey = NULL;
+	return NULL;
+    }
+
+    /* Perform PKCS #11 pairwise consistency check. */
+    rv = pk11_PairwiseConsistencyCheck( *pubKey, privKey, &test_mech, wincx );
+    if( rv != SECSuccess ) {
+	SECKEY_DestroyPublicKey( *pubKey );
+	SECKEY_DestroyPrivateKey( privKey );
+	*pubKey = NULL;
+	privKey = NULL;
+	return NULL;  /* due to pairwise consistency check */
+    }
+
+    return privKey;
+}
+
+/*
+ * Use the token to generate a key pair.
  */
 SECKEYPrivateKey *
 PK11_GenerateKeyPair(PK11SlotInfo *slot,CK_MECHANISM_TYPE type, 
    void *param, SECKEYPublicKey **pubKey, PRBool token, 
 					PRBool sensitive, void *wincx)
 {
     /* we have to use these native types because when we call PKCS 11 modules
      * we have to make sure that we are using the correct sizes for all the
--- a/security/nss/lib/pk11wrap/pk11auth.c
+++ b/security/nss/lib/pk11wrap/pk11auth.c
@@ -75,24 +75,29 @@ static struct PK11GlobalStruct {
  ***********************************************************/
 /*
  * Check the user's password. Log into the card if it's correct.
  * succeed if the user is already logged in.
  */
 SECStatus
 pk11_CheckPassword(PK11SlotInfo *slot,char *pw)
 {
-    int len = PORT_Strlen(pw);
+    int len = 0;
     CK_RV crv;
     SECStatus rv;
     int64 currtime = PR_Now();
 
     if (slot->protectedAuthPath) {
 	len = 0;
 	pw = NULL;
+    } else if (pw == NULL) {
+	PORT_SetError(SEC_ERROR_INVALID_ARGS);
+	return SECFailure;
+    } else {
+	len = PORT_Strlen(pw);
     }
 
     PK11_EnterSlotMonitor(slot);
     crv = PK11_GETTAB(slot)->C_Login(slot->session,CKU_USER,
 						(unsigned char *)pw,len);
     slot->lastLoginCheck = 0;
     PK11_ExitSlotMonitor(slot);
     switch (crv) {
@@ -116,24 +121,29 @@ pk11_CheckPassword(PK11SlotInfo *slot,ch
 
 /*
  * Check the user's password. Logout before hand to make sure that
  * we are really checking the password.
  */
 SECStatus
 PK11_CheckUserPassword(PK11SlotInfo *slot,char *pw)
 {
-    int len = PORT_Strlen(pw);
+    int len = 0;
     CK_RV crv;
     SECStatus rv;
     int64 currtime = PR_Now();
 
     if (slot->protectedAuthPath) {
 	len = 0;
 	pw = NULL;
+    } else if (pw == NULL) {
+	PORT_SetError(SEC_ERROR_INVALID_ARGS);
+	return SECFailure;
+    } else {
+	len = PORT_Strlen(pw);
     }
 
     /* force a logout */
     PK11_EnterSlotMonitor(slot);
     PK11_GETTAB(slot)->C_Logout(slot->session);
 
     crv = PK11_GETTAB(slot)->C_Login(slot->session,CKU_USER,
 					(unsigned char *)pw,len);
@@ -307,25 +317,33 @@ pk11_AuthenticateUnfriendly(PK11SlotInfo
  * NOTE: this assumes that we are logged out of the card before hand
  */
 SECStatus
 PK11_CheckSSOPassword(PK11SlotInfo *slot, char *ssopw)
 {
     CK_SESSION_HANDLE rwsession;
     CK_RV crv;
     SECStatus rv = SECFailure;
-    int len = PORT_Strlen(ssopw);
+    int len = 0;
 
     /* get a rwsession */
     rwsession = PK11_GetRWSession(slot);
-    if (rwsession == CK_INVALID_SESSION) return rv;
+    if (rwsession == CK_INVALID_SESSION) {
+    	PORT_SetError(SEC_ERROR_BAD_DATA);
+    	return rv;
+    }
 
     if (slot->protectedAuthPath) {
 	len = 0;
 	ssopw = NULL;
+    } else if (ssopw == NULL) {
+	PORT_SetError(SEC_ERROR_INVALID_ARGS);
+	return SECFailure;
+    } else {
+	len = PORT_Strlen(ssopw);
     }
 
     /* check the password */
     crv = PK11_GETTAB(slot)->C_Login(rwsession,CKU_SO,
 						(unsigned char *)ssopw,len);
     slot->lastLoginCheck = 0;
     switch (crv) {
     /* if we're already logged in, we're good to go */
@@ -378,17 +396,21 @@ PK11_InitPin(PK11SlotInfo *slot,char *ss
     if (userpw == NULL) userpw = "";
     if (ssopw == NULL) ssopw = "";
 
     len = PORT_Strlen(userpw);
     ssolen = PORT_Strlen(ssopw);
 
     /* get a rwsession */
     rwsession = PK11_GetRWSession(slot);
-    if (rwsession == CK_INVALID_SESSION) goto done;
+    if (rwsession == CK_INVALID_SESSION) {
+    	PORT_SetError(SEC_ERROR_BAD_DATA);
+	slot->lastLoginCheck = 0;
+    	return rv;
+    }
 
     if (slot->protectedAuthPath) {
 	len = 0;
 	ssolen = 0;
 	ssopw = NULL;
 	userpw = NULL;
     }
 
@@ -438,16 +460,20 @@ PK11_ChangePW(PK11SlotInfo *slot,char *o
 
     if (newpw == NULL) newpw = "";
     if (oldpw == NULL) oldpw = "";
     newLen = PORT_Strlen(newpw);
     oldLen = PORT_Strlen(oldpw);
 
     /* get a rwsession */
     rwsession = PK11_GetRWSession(slot);
+    if (rwsession == CK_INVALID_SESSION) {
+    	PORT_SetError(SEC_ERROR_BAD_DATA);
+    	return rv;
+    }
 
     crv = PK11_GETTAB(slot)->C_SetPIN(rwsession,
 		(unsigned char *)oldpw,oldLen,(unsigned char *)newpw,newLen);
     if (crv == CKR_OK) {
 	rv = SECSuccess;
     } else {
 	PORT_SetError(PK11_MapError(crv));
     }
@@ -529,17 +555,44 @@ PK11_DoPassword(PK11SlotInfo *slot, PRBo
      * 	(1) the user refused to enter a password. 
      *			(return error to caller)
      *	(2) the token user password is disabled [usually due to
      *	   too many failed authentication attempts].
      *			(return error to caller)
      *	(3) the password was successful.
      */
     while ((password = pk11_GetPassword(slot, attempt, wincx)) != NULL) {
+	/* if the token has a protectedAuthPath, the application may have
+         * already issued the C_Login as part of it's pk11_GetPassword call.
+         * In this case the application will tell us what the results were in 
+         * the password value (retry or the authentication was successful) so
+	 * we can skip our own C_Login call (which would force the token to
+	 * try to login again).
+	 * 
+	 * Applications that don't know about protectedAuthPath will return a 
+	 * password, which we will ignore and trigger the token to 
+	 * 'authenticate' itself anyway. Hopefully the blinking display on 
+	 * the reader, or the flashing light under the thumbprint reader will 
+	 * attract the user's attention */
 	attempt = PR_TRUE;
+	if (slot->protectedAuthPath) {
+	    /* application tried to authenticate and failed. it wants to try
+	     * again, continue looping */
+	    if (strcmp(password, PK11_PW_RETRY) == 0) {
+		rv = SECWouldBlock;
+		PORT_Free(password);
+		continue;
+	    }
+	    /* applicaton tried to authenticate and succeeded we're done */
+	    if (strcmp(password, PK11_PW_AUTHENTICATED) == 0) {
+		rv = SECSuccess;
+		PORT_Free(password);
+		break;
+	    }
+	}
 	rv = pk11_CheckPassword(slot,password);
 	PORT_Memset(password, 0, PORT_Strlen(password));
 	PORT_Free(password);
 	if (rv != SECWouldBlock) break;
     }
     if (rv == SECSuccess) {
 	rv = pk11_CheckVerifyTest(slot);
 	if (!PK11_IsFriendly(slot)) {
--- a/security/nss/lib/pk11wrap/pk11load.c
+++ b/security/nss/lib/pk11wrap/pk11load.c
@@ -272,16 +272,18 @@ SECMOD_LoadPKCS11Module(SECMODModule *mo
     }
 
     /* check the version number */
     if (PK11_GETTAB(mod)->C_GetInfo(&info) != CKR_OK) goto fail2;
     if (info.cryptokiVersion.major != 2) goto fail2;
     /* all 2.0 are a priori *not* thread safe */
     if (info.cryptokiVersion.minor < 1) mod->isThreadSafe = PR_FALSE;
 
+    mod->cryptokiVersion = info.cryptokiVersion;
+
 
     /* If we don't have a common name, get it from the PKCS 11 module */
     if ((mod->commonName == NULL) || (mod->commonName[0] == 0)) {
 	mod->commonName = PK11_MakeString(mod->arena,NULL,
 	   (char *)info.libraryDescription, sizeof(info.libraryDescription));
 	if (mod->commonName == NULL) goto fail2;
     }
     
--- a/security/nss/lib/pk11wrap/pk11nobj.c
+++ b/security/nss/lib/pk11wrap/pk11nobj.c
@@ -251,21 +251,22 @@ loser:
  * CRLs are allocated in the list's arena.
  */
 SECStatus
 PK11_LookupCrls(CERTCrlHeadNode *nodes, int type, void *wincx) {
     pk11TraverseSlot creater;
     CK_ATTRIBUTE theTemplate[2];
     CK_ATTRIBUTE *attrs;
     CK_OBJECT_CLASS certClass = CKO_NETSCAPE_CRL;
+    CK_BBOOL isKrl = CK_FALSE;
 
     attrs = theTemplate;
     PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass)); attrs++;
     if (type != -1) {
-	CK_BBOOL isKrl = (CK_BBOOL) (type == SEC_KRL_TYPE);
+	isKrl = (CK_BBOOL) (type == SEC_KRL_TYPE);
         PK11_SETATTRS(attrs, CKA_NETSCAPE_KRL, &isKrl, sizeof(isKrl)); attrs++;
     }
 
     creater.callback = pk11_CollectCrls;
     creater.callbackArg = (void *) nodes;
     creater.findTemplate = theTemplate;
     creater.templateCount = (attrs - theTemplate);
 
--- a/security/nss/lib/pk11wrap/pk11obj.c
+++ b/security/nss/lib/pk11wrap/pk11obj.c
@@ -403,17 +403,17 @@ PK11_CreateNewObject(PK11SlotInfo *slot,
 	    PK11_ExitSlotMonitor(slot);
         }
 
 	return rv;
 }
 
 
 unsigned int
-pk11_FlagsToAttributes(CK_FLAGS flags, CK_ATTRIBUTE *attrs, CK_BBOOL *ckTrue)
+pk11_OpFlagsToAttributes(CK_FLAGS flags, CK_ATTRIBUTE *attrs, CK_BBOOL *ckTrue)
 {
 
     const static CK_ATTRIBUTE_TYPE attrTypes[12] = {
 	CKA_ENCRYPT,      CKA_DECRYPT, 0 /* DIGEST */,     CKA_SIGN,
 	CKA_SIGN_RECOVER, CKA_VERIFY,  CKA_VERIFY_RECOVER, 0 /* GEN */,
 	0 /* GEN PAIR */, CKA_WRAP,    CKA_UNWRAP,         CKA_DERIVE 
     };
 
@@ -431,16 +431,62 @@ pk11_FlagsToAttributes(CK_FLAGS flags, C
 	    PK11_SETATTRS(attr, *pType, ckTrue, sizeof *ckTrue); 
 	    ++attr;
 	}
     }
     return (attr - attrs);
 }
 
 /*
+ * Check for conflicting flags, for example, if both PK11_ATTR_PRIVATE
+ * and PK11_ATTR_PUBLIC are set.
+ */
+PRBool
+pk11_BadAttrFlags(PK11AttrFlags attrFlags)
+{
+    PK11AttrFlags trueFlags = attrFlags & 0x55555555;
+    PK11AttrFlags falseFlags = (attrFlags >> 1) & 0x55555555;
+    return ((trueFlags & falseFlags) != 0);
+}
+
+/*
+ * This function may add a maximum of 5 attributes.
+ * The caller must make sure the attribute flags don't have conflicts.
+ */
+unsigned int
+pk11_AttrFlagsToAttributes(PK11AttrFlags attrFlags, CK_ATTRIBUTE *attrs,
+				CK_BBOOL *ckTrue, CK_BBOOL *ckFalse)
+{
+    const static CK_ATTRIBUTE_TYPE attrTypes[5] = {
+	CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_SENSITIVE,
+	CKA_EXTRACTABLE
+    };
+
+    const CK_ATTRIBUTE_TYPE *pType	= attrTypes;
+          CK_ATTRIBUTE      *attr	= attrs;
+          PK11AttrFlags      test	= PK11_ATTR_TOKEN;
+
+    PR_ASSERT(!pk11_BadAttrFlags(attrFlags));
+
+    /* we test two related bitflags in each iteration */
+    for (; attrFlags && test <= PK11_ATTR_EXTRACTABLE; test <<= 2, ++pType) {
+    	if (test & attrFlags) {
+	    attrFlags ^= test;
+	    PK11_SETATTRS(attr, *pType, ckTrue, sizeof *ckTrue); 
+	    ++attr;
+	} else if ((test << 1) & attrFlags) {
+	    attrFlags ^= (test << 1);
+	    PK11_SETATTRS(attr, *pType, ckFalse, sizeof *ckFalse); 
+	    ++attr;
+	}
+    }
+    return (attr - attrs);
+}
+
+/*
  * Some non-compliant PKCS #11 vendors do not give us the modulus, so actually
  * set up a signature to get the signaure length.
  */
 static int
 pk11_backupGetSignLength(SECKEYPrivateKey *key)
 {
     PK11SlotInfo *slot = key->pkcs11Slot;
     CK_MECHANISM mech = {0, NULL, 0 };
--- a/security/nss/lib/pk11wrap/pk11pub.h
+++ b/security/nss/lib/pk11wrap/pk11pub.h
@@ -231,16 +231,20 @@ void PK11_SetWrapKey(PK11SlotInfo *slot,
 CK_MECHANISM_TYPE PK11_GetMechanism(PK11SymKey *symKey);
 CK_OBJECT_HANDLE PK11_ImportPublicKey(PK11SlotInfo *slot, 
 				SECKEYPublicKey *pubKey, PRBool isToken);
 PK11SymKey *PK11_KeyGen(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
 				SECItem *param,	int keySize,void *wincx);
 PK11SymKey *PK11_TokenKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
 				SECItem *param, int keySize, SECItem *keyid,
 				PRBool isToken, void *wincx);
+PK11SymKey *PK11_TokenKeyGenWithFlags(PK11SlotInfo *slot,
+				CK_MECHANISM_TYPE type, SECItem *param,
+				int keySize, SECItem *keyid, CK_FLAGS opFlags,
+				PK11AttrFlags attrFlags, void *wincx);
 PK11SymKey * PK11_ListFixedKeysInSlot(PK11SlotInfo *slot, char *nickname,
 								void *wincx);
 PK11SymKey *PK11_GetNextSymKey(PK11SymKey *symKey);
 CK_KEY_TYPE PK11_GetSymKeyType(PK11SymKey *key);
 
 SECStatus PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey,
 				PK11SymKey *symKey, SECItem *wrappedKey);
 SECStatus PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *params,
@@ -340,16 +344,25 @@ unsigned int PK11_GetKeyLength(PK11SymKe
 /* size of actual secret parts of key in bits */
 /* algid is because RC4 strength is determined by the effective bits as well
  * as the key bits */
 unsigned int PK11_GetKeyStrength(PK11SymKey *key,SECAlgorithmID *algid);
 SECStatus PK11_ExtractKeyValue(PK11SymKey *symKey);
 SECItem * PK11_GetKeyData(PK11SymKey *symKey);
 PK11SlotInfo * PK11_GetSlotFromKey(PK11SymKey *symKey);
 void *PK11_GetWindow(PK11SymKey *symKey);
+/*
+ * The attrFlags is the logical OR of the PK11_ATTR_XXX bitflags.
+ * These flags apply to the private key.  The PK11_ATTR_TOKEN,
+ * PK11_ATTR_SESSION, PK11_ATTR_MODIFIABLE, and PK11_ATTR_UNMODIFIABLE
+ * flags also apply to the public key.
+ */
+SECKEYPrivateKey *PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot,
+   CK_MECHANISM_TYPE type, void *param, SECKEYPublicKey **pubk,
+		 	    PK11AttrFlags attrFlags, void *wincx);
 SECKEYPrivateKey *PK11_GenerateKeyPair(PK11SlotInfo *slot,
    CK_MECHANISM_TYPE type, void *param, SECKEYPublicKey **pubk,
 		 	    PRBool isPerm, PRBool isSensitive, void *wincx);
 SECKEYPrivateKey * PK11_FindPrivateKeyFromCert(PK11SlotInfo *slot,
 				 	CERTCertificate *cert, void *wincx);
 SECKEYPrivateKey * PK11_FindKeyByAnyCert(CERTCertificate *cert, void *wincx);
 SECKEYPrivateKey * PK11_FindKeyByKeyID(PK11SlotInfo *slot, SECItem *keyID,
 				       void *wincx);
--- a/security/nss/lib/pk11wrap/pk11skey.c
+++ b/security/nss/lib/pk11wrap/pk11skey.c
@@ -404,17 +404,17 @@ PK11_ImportSymKeyWithFlags(PK11SlotInfo 
     PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass) ); attrs++;
     PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType) ); attrs++;
     if (isPerm) {
 	PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(cktrue) ); attrs++;
 	/* sigh some tokens think CKA_PRIVATE = false is a reasonable 
 	 * default for secret keys */
 	PK11_SETATTRS(attrs, CKA_PRIVATE, &cktrue, sizeof(cktrue) ); attrs++;
     }
-    attrs += pk11_FlagsToAttributes(flags, attrs, &cktrue);
+    attrs += pk11_OpFlagsToAttributes(flags, attrs, &cktrue);
     if ((operation != CKA_FLAGS_ONLY) &&
     	 !pk11_FindAttrInTemplate(keyTemplate, attrs-keyTemplate, operation)) {
         PK11_SETATTRS(attrs, operation, &cktrue, sizeof(cktrue)); attrs++;
     }
     templateCount = attrs - keyTemplate;
     PR_ASSERT(templateCount+1 <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE));
 
     keyType = PK11_GetKeyType(type,key->len);
@@ -761,19 +761,141 @@ PK11_MoveSymKey(PK11SlotInfo *slot, CK_A
     }
     
     return pk11_CopyToSlotPerm(slot, symKey->type, 
 					operation, flags, perm, symKey);
 }
 
 
 /*
- * Use the token to Generate a key. keySize must be 'zero' for fixed key
- * length algorithms. NOTE: this means we can never generate a DES2 key
- * from this interface!
+ * Use the token to generate a key. keySize must be 'zero' for fixed key
+ * length algorithms. A nonzero keySize causes the CKA_VALUE_LEN attribute
+ * to be added to the template for the key. PKCS #11 modules fail if you
+ * specify the CKA_VALUE_LEN attribute for keys with fixed length.
+ * NOTE: this means to generate a DES2 key from this interface you must
+ * specify CKM_DES2_KEY_GEN as the mechanism directly; specifying
+ * CKM_DES3_CBC as the mechanism and 16 as keySize currently doesn't work.
+ *
+ * CK_FLAGS flags: key operation flags
+ * PK11AttrFlags attrFlags: PK11_ATTR_XXX key attribute flags
+ */
+PK11SymKey *
+PK11_TokenKeyGenWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
+    SECItem *param, int keySize, SECItem *keyid, CK_FLAGS opFlags,
+    PK11AttrFlags attrFlags, void *wincx)
+{
+    PK11SymKey *symKey;
+    CK_ATTRIBUTE genTemplate[MAX_TEMPL_ATTRS];
+    CK_ATTRIBUTE *attrs = genTemplate;
+    int count = sizeof(genTemplate)/sizeof(genTemplate[0]);
+    CK_SESSION_HANDLE session;
+    CK_MECHANISM mechanism;
+    CK_RV crv;
+    CK_BBOOL cktrue = CK_TRUE;
+    CK_BBOOL ckfalse = CK_FALSE;
+    CK_ULONG ck_key_size;       /* only used for variable-length keys */
+    PRBool isToken = ((attrFlags & PK11_ATTR_TOKEN) != 0);
+
+    if (pk11_BadAttrFlags(attrFlags)) {
+	PORT_SetError( SEC_ERROR_INVALID_ARGS );
+	return NULL;
+    }
+
+    if (keySize != 0) {
+        ck_key_size = keySize; /* Convert to PK11 type */
+
+        PK11_SETATTRS(attrs, CKA_VALUE_LEN, &ck_key_size, sizeof(ck_key_size)); 
+							attrs++;
+    }
+
+    /* Include key id value if provided */
+    if (keyid) {
+        PK11_SETATTRS(attrs, CKA_ID, keyid->data, keyid->len); attrs++;
+    }
+
+    attrs += pk11_AttrFlagsToAttributes(attrFlags, attrs, &cktrue, &ckfalse);
+    attrs += pk11_OpFlagsToAttributes(opFlags, attrs, &cktrue);
+
+    count = attrs - genTemplate;
+    PR_ASSERT(count <= sizeof(genTemplate)/sizeof(CK_ATTRIBUTE));
+
+    /* find a slot to generate the key into */
+    /* Only do slot management if this is not a token key */
+    if (!isToken && (slot == NULL || !PK11_DoesMechanism(slot,type))) {
+        PK11SlotInfo *bestSlot;
+
+        bestSlot = PK11_GetBestSlot(type,wincx);
+        if (bestSlot == NULL) {
+	    PORT_SetError( SEC_ERROR_NO_MODULE );
+	    return NULL;
+	}
+
+        symKey = pk11_CreateSymKey(bestSlot, type, !isToken, wincx);
+
+        PK11_FreeSlot(bestSlot);
+    } else {
+	symKey = pk11_CreateSymKey(slot, type, !isToken, wincx);
+    }
+    if (symKey == NULL) return NULL;
+
+    symKey->size = keySize;
+    symKey->origin = PK11_OriginGenerated;
+
+    /* Initialize the Key Gen Mechanism */
+    mechanism.mechanism = PK11_GetKeyGenWithSize(type, keySize);
+    if (mechanism.mechanism == CKM_FAKE_RANDOM) {
+	PORT_SetError( SEC_ERROR_NO_MODULE );
+	return NULL;
+    }
+
+    /* Set the parameters for the key gen if provided */
+    mechanism.pParameter = NULL;
+    mechanism.ulParameterLen = 0;
+    if (param) {
+	mechanism.pParameter = param->data;
+	mechanism.ulParameterLen = param->len;
+    }
+
+    /* Get session and perform locking */
+    if (isToken) {
+	PK11_Authenticate(symKey->slot,PR_TRUE,wincx);
+        session = PK11_GetRWSession(symKey->slot);  /* Should always be original slot */
+	symKey->owner = PR_FALSE;
+    } else {
+        session = symKey->session;
+        pk11_EnterKeyMonitor(symKey);
+    }
+
+    crv = PK11_GETTAB(symKey->slot)->C_GenerateKey(session,
+			 &mechanism, genTemplate, count, &symKey->objectID);
+
+    /* Release lock and session */
+    if (isToken) {
+        PK11_RestoreROSession(symKey->slot, session);
+    } else {
+        pk11_ExitKeyMonitor(symKey);
+    }
+
+    if (crv != CKR_OK) {
+	PK11_FreeSymKey(symKey);
+	PORT_SetError( PK11_MapError(crv) );
+	return NULL;
+    }
+
+    return symKey;
+}
+
+/*
+ * Use the token to generate a key. keySize must be 'zero' for fixed key
+ * length algorithms. A nonzero keySize causes the CKA_VALUE_LEN attribute
+ * to be added to the template for the key. PKCS #11 modules fail if you
+ * specify the CKA_VALUE_LEN attribute for keys with fixed length.
+ * NOTE: this means to generate a DES2 key from this interface you must
+ * specify CKM_DES2_KEY_GEN as the mechanism directly; specifying
+ * CKM_DES3_CBC as the mechanism and 16 as keySize currently doesn't work.
  */
 PK11SymKey *
 PK11_TokenKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param,
     int keySize, SECItem *keyid, PRBool isToken, void *wincx)
 {
     PK11SymKey *symKey;
     CK_ATTRIBUTE genTemplate[6];
     CK_ATTRIBUTE *attrs = genTemplate;
@@ -816,17 +938,17 @@ PK11_TokenKeyGen(PK11SlotInfo *slot, CK_
     count = attrs - genTemplate;
     PR_ASSERT(count <= sizeof(genTemplate)/sizeof(CK_ATTRIBUTE));
 
     /* find a slot to generate the key into */
     /* Only do slot management if this is not a token key */
     if (!isToken && (slot == NULL || !PK11_DoesMechanism(slot,type))) {
         PK11SlotInfo *bestSlot;
 
-        bestSlot = PK11_GetBestSlot(type,wincx); /* TNH: references the slot? */
+        bestSlot = PK11_GetBestSlot(type,wincx);
         if (bestSlot == NULL) {
 	    PORT_SetError( SEC_ERROR_NO_MODULE );
 	    return NULL;
 	}
 
         symKey = pk11_CreateSymKey(bestSlot, type, !isToken, wincx);
 
         PK11_FreeSlot(bestSlot);
@@ -1159,17 +1281,17 @@ PK11SymKey *
 PK11_DeriveWithFlags( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive, 
 	SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, 
 	int keySize, CK_FLAGS flags)
 {
     CK_BBOOL        ckTrue	= CK_TRUE; 
     CK_ATTRIBUTE    keyTemplate[MAX_TEMPL_ATTRS];
     unsigned int    templateCount;
 
-    templateCount = pk11_FlagsToAttributes(flags, keyTemplate, &ckTrue);
+    templateCount = pk11_OpFlagsToAttributes(flags, keyTemplate, &ckTrue);
     return pk11_DeriveWithTemplate(baseKey, derive, param, target, operation, 
 		  keySize, keyTemplate, templateCount, PR_FALSE);
 }
 
 PK11SymKey *
 PK11_DeriveWithFlagsPerm( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive, 
 	SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, 
 	int keySize, CK_FLAGS flags, PRBool isPerm)
@@ -1179,17 +1301,17 @@ PK11_DeriveWithFlagsPerm( PK11SymKey *ba
     CK_ATTRIBUTE    *attrs;
     unsigned int    templateCount = 0;
 
     attrs = keyTemplate;
     if (isPerm) {
         PK11_SETATTRS(attrs, CKA_TOKEN,  &cktrue, sizeof(CK_BBOOL)); attrs++;
     }
     templateCount = attrs - keyTemplate;
-    templateCount += pk11_FlagsToAttributes(flags, attrs, &cktrue);
+    templateCount += pk11_OpFlagsToAttributes(flags, attrs, &cktrue);
     return pk11_DeriveWithTemplate(baseKey, derive, param, target, operation, 
 				   keySize, keyTemplate, templateCount, isPerm);
 }
 
 static PK11SymKey *
 pk11_DeriveWithTemplate( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive, 
 	SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, 
 	int keySize, CK_ATTRIBUTE *userAttr, unsigned int numAttrs,
@@ -1842,17 +1964,17 @@ PK11_UnwrapSymKeyWithFlags(PK11SymKey *w
                    SECItem *param, SECItem *wrappedKey, 
 		   CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, 
 		   int keySize, CK_FLAGS flags)
 {
     CK_BBOOL        ckTrue	= CK_TRUE; 
     CK_ATTRIBUTE    keyTemplate[MAX_TEMPL_ATTRS];
     unsigned int    templateCount;
 
-    templateCount = pk11_FlagsToAttributes(flags, keyTemplate, &ckTrue);
+    templateCount = pk11_OpFlagsToAttributes(flags, keyTemplate, &ckTrue);
     return pk11_AnyUnwrapKey(wrappingKey->slot, wrappingKey->objectID,
 		    wrapType, param, wrappedKey, target, operation, keySize, 
 		    wrappingKey->cx, keyTemplate, templateCount, PR_FALSE);
 }
 
 PK11SymKey *
 PK11_UnwrapSymKeyWithFlagsPerm(PK11SymKey *wrappingKey, 
 		   CK_MECHANISM_TYPE wrapType,
@@ -1865,17 +1987,17 @@ PK11_UnwrapSymKeyWithFlagsPerm(PK11SymKe
     CK_ATTRIBUTE    *attrs;
     unsigned int    templateCount;
 
     attrs = keyTemplate;
     if (isPerm) {
         PK11_SETATTRS(attrs, CKA_TOKEN,  &cktrue, sizeof(CK_BBOOL)); attrs++;
     }
     templateCount = attrs-keyTemplate;
-    templateCount += pk11_FlagsToAttributes(flags, attrs, &cktrue);
+    templateCount += pk11_OpFlagsToAttributes(flags, attrs, &cktrue);
 
     return pk11_AnyUnwrapKey(wrappingKey->slot, wrappingKey->objectID,
 		    wrapType, param, wrappedKey, target, operation, keySize, 
 		    wrappingKey->cx, keyTemplate, templateCount, isPerm);
 }
 
 
 /* unwrap a symetric key with a private key. */
@@ -1902,17 +2024,17 @@ PK11_PubUnwrapSymKeyWithFlags(SECKEYPriv
 	  CK_ATTRIBUTE_TYPE operation, int keySize, CK_FLAGS flags)
 {
     CK_MECHANISM_TYPE wrapType = pk11_mapWrapKeyType(wrappingKey->keyType);
     CK_BBOOL        ckTrue	= CK_TRUE; 
     CK_ATTRIBUTE    keyTemplate[MAX_TEMPL_ATTRS];
     unsigned int    templateCount;
     PK11SlotInfo    *slot = wrappingKey->pkcs11Slot;
 
-    templateCount = pk11_FlagsToAttributes(flags, keyTemplate, &ckTrue);
+    templateCount = pk11_OpFlagsToAttributes(flags, keyTemplate, &ckTrue);
 
     if (SECKEY_HAS_ATTRIBUTE_SET(wrappingKey,CKA_PRIVATE)) {
 	PK11_HandlePasswordCheck(slot,wrappingKey->wincx);
     }
     
     return pk11_AnyUnwrapKey(slot, wrappingKey->pkcs11ID,
 	wrapType, NULL, wrappedKey, target, operation, keySize, 
 	wrappingKey->wincx, keyTemplate, templateCount, PR_FALSE);
@@ -1932,17 +2054,17 @@ PK11_PubUnwrapSymKeyWithFlagsPerm(SECKEY
     PK11SlotInfo    *slot = wrappingKey->pkcs11Slot;
 
     attrs = keyTemplate;
     if (isPerm) {
         PK11_SETATTRS(attrs, CKA_TOKEN,  &cktrue, sizeof(CK_BBOOL)); attrs++;
     }
     templateCount = attrs-keyTemplate;
 
-    templateCount += pk11_FlagsToAttributes(flags, attrs, &cktrue);
+    templateCount += pk11_OpFlagsToAttributes(flags, attrs, &cktrue);
 
     if (SECKEY_HAS_ATTRIBUTE_SET(wrappingKey,CKA_PRIVATE)) {
 	PK11_HandlePasswordCheck(slot,wrappingKey->wincx);
     }
     
     return pk11_AnyUnwrapKey(slot, wrappingKey->pkcs11ID,
 	wrapType, NULL, wrappedKey, target, operation, keySize, 
 	wrappingKey->wincx, keyTemplate, templateCount, isPerm);
--- a/security/nss/lib/pk11wrap/pk11util.c
+++ b/security/nss/lib/pk11wrap/pk11util.c
@@ -1055,16 +1055,23 @@ secmod_HandleWaitForSlotEvent(SECMODModu
 PK11SlotInfo *
 SECMOD_WaitForAnyTokenEvent(SECMODModule *mod, unsigned long flags,
 						 PRIntervalTime latency)
 {
     CK_SLOT_ID id;
     CK_RV crv;
     PK11SlotInfo *slot;
 
+    if ((mod->cryptokiVersion.major == 2) &&
+        (mod->cryptokiVersion.minor < 1)) {
+	/* if the module is version 2.0,
+         * C_WaitForSlotEvent() doesn't exist */
+	return secmod_HandleWaitForSlotEvent(mod, flags, latency);
+    }
+
     /* first the the PKCS #11 call */
     PZ_Lock(mod->refLock);
     if (mod->evControlMask & SECMOD_END_WAIT) {
 	goto end_wait;
     }
     mod->evControlMask |= SECMOD_WAIT_PKCS11_EVENT;
     PZ_Unlock(mod->refLock);
     crv = PK11_GETTAB(mod)->C_WaitForSlotEvent(flags, &id, NULL);
--- a/security/nss/lib/pk11wrap/secmodi.h
+++ b/security/nss/lib/pk11wrap/secmodi.h
@@ -119,18 +119,24 @@ extern void pk11sdr_Shutdown(void);
  * Private to pk11wrap.
  */
 
 PRBool pk11_LoginStillRequired(PK11SlotInfo *slot, void *wincx);
 CK_SESSION_HANDLE pk11_GetNewSession(PK11SlotInfo *slot, PRBool *owner);
 void pk11_CloseSession(PK11SlotInfo *slot, CK_SESSION_HANDLE sess, PRBool own);
 PK11SymKey *pk11_ForceSlot(PK11SymKey *symKey, CK_MECHANISM_TYPE type,
 						CK_ATTRIBUTE_TYPE operation);
-unsigned int pk11_FlagsToAttributes(CK_FLAGS flags, 
+/* Convert key operation flags to PKCS #11 attributes. */
+unsigned int pk11_OpFlagsToAttributes(CK_FLAGS flags, 
 				CK_ATTRIBUTE *attrs, CK_BBOOL *ckTrue);
+/* Check for bad (conflicting) attribute flags */
+PRBool pk11_BadAttrFlags(PK11AttrFlags attrFlags);
+/* Convert key attribute flags to PKCS #11 attributes. */
+unsigned int pk11_AttrFlagsToAttributes(PK11AttrFlags attrFlags,
+		CK_ATTRIBUTE *attrs, CK_BBOOL *ckTrue, CK_BBOOL *ckFalse);
 PRBool pk11_FindAttrInTemplate(CK_ATTRIBUTE *attr, unsigned int numAttrs,
 					CK_ATTRIBUTE_TYPE target);
 
 CK_MECHANISM_TYPE pk11_mapSignKeyType(KeyType keyType);
 CK_MECHANISM_TYPE pk11_mapWrapKeyType(KeyType keyType);
 PK11SymKey *pk11_KeyExchange(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
 		CK_ATTRIBUTE_TYPE operation, CK_FLAGS flags, PRBool isPerm,
 						PK11SymKey *symKey);
--- a/security/nss/lib/pk11wrap/secmodt.h
+++ b/security/nss/lib/pk11wrap/secmodt.h
@@ -35,16 +35,17 @@
  * ***** END LICENSE BLOCK ***** */
 #ifndef _SECMODT_H_
 #define _SECMODT_H_ 1
 
 #include "nssrwlkt.h"
 #include "nssilckt.h"
 #include "secoid.h"
 #include "secasn1.h"
+#include "pkcs11t.h"
 
 /* find a better home for these... */
 extern const SEC_ASN1Template SECKEY_PointerToEncryptedPrivateKeyInfoTemplate[];
 extern SEC_ASN1TemplateChooser NSS_Get_SECKEY_PointerToEncryptedPrivateKeyInfoTemplate;
 extern const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[];
 extern SEC_ASN1TemplateChooser NSS_Get_SECKEY_EncryptedPrivateKeyInfoTemplate;
 extern const SEC_ASN1Template SECKEY_PrivateKeyInfoTemplate[];
 extern SEC_ASN1TemplateChooser NSS_Get_SECKEY_PrivateKeyInfoTemplate;
@@ -92,16 +93,17 @@ struct SECMODModuleStr {
     SECMODModule *parent;	/* module that loaded us */
     PRBool	isCritical;	/* This module must load successfully */
     PRBool	isModuleDB;	/* this module has lists of PKCS #11 modules */
     PRBool	moduleDBOnly;	/* this module only has lists of PKCS #11 modules */
     int		trustOrder;	/* order for this module's certificate trust rollup */
     int		cipherOrder;	/* order for cipher operations */
     unsigned long evControlMask; /* control the running and shutdown of slot
 				  * events (SECMOD_WaitForAnyTokenEvent) */
+    CK_VERSION  cryptokiVersion; /* version of this library */
 };
 
 /* evControlMask flags */
 /*
  * These bits tell the current state of a SECMOD_WaitForAnyTokenEvent.
  *
  * SECMOD_WAIT_PKCS11_EVENT - we're waiting in the PKCS #11 module in
  *  C_WaitForSlotEvent().
@@ -189,16 +191,151 @@ struct PK11DefaultArrayEntryStr {
 #define PK11_DISABLE_FLAG    0x40000000L
 
 /* FAKE PKCS #11 defines */
 #define CKM_FAKE_RANDOM       0x80000efeL
 #define CKM_INVALID_MECHANISM 0xffffffffL
 #define CKA_DIGEST            0x81000000L
 #define CKA_FLAGS_ONLY        0 /* CKA_CLASS */
 
+/*
+ * PK11AttrFlags
+ *
+ * A 32-bit bitmask of PK11_ATTR_XXX flags
+ */
+typedef PRUint32 PK11AttrFlags;
+
+/*
+ * PK11_ATTR_XXX
+ *
+ * The following PK11_ATTR_XXX bitflags are used to specify
+ * PKCS #11 object attributes that have Boolean values.  Some NSS
+ * functions have a "PK11AttrFlags attrFlags" parameter whose value
+ * is the logical OR of these bitflags.  NSS use these bitflags on
+ * private keys or secret keys.  Some of these bitflags also apply
+ * to the public keys associated with the private keys.
+ *
+ * For each PKCS #11 object attribute, we need two bitflags to
+ * specify not only "true" and "false" but also "default".  For
+ * example, PK11_ATTR_PRIVATE and PK11_ATTR_PUBLIC control the
+ * CKA_PRIVATE attribute.  If PK11_ATTR_PRIVATE is set, we add
+ *     { CKA_PRIVATE, &cktrue, sizeof(CK_BBOOL) }
+ * to the template.  If PK11_ATTR_PUBLIC is set, we add
+ *     { CKA_PRIVATE, &ckfalse, sizeof(CK_BBOOL) }
+ * to the template.  If neither flag is set, we don't add any
+ * CKA_PRIVATE entry to the template.
+ */
+
+/*
+ * Attributes for PKCS #11 storage objects, which include not only
+ * keys but also certificates and domain parameters.
+ */
+
+/*
+ * PK11_ATTR_TOKEN
+ * PK11_ATTR_SESSION
+ *
+ * These two flags determine whether the object is a token or
+ * session object.
+ *
+ * These two flags are related and cannot both be set.
+ * If the PK11_ATTR_TOKEN flag is set, the object is a token
+ * object.  If the PK11_ATTR_SESSION flag is set, the object is
+ * a session object.  If neither flag is set, the object is *by
+ * default* a session object.
+ *
+ * These two flags specify the value of the PKCS #11 CKA_TOKEN
+ * attribute.
+ */
+#define PK11_ATTR_TOKEN         0x00000001L
+#define PK11_ATTR_SESSION       0x00000002L
+
+/*
+ * PK11_ATTR_PRIVATE
+ * PK11_ATTR_PUBLIC
+ *
+ * These two flags determine whether the object is a private or
+ * public object.  A user may not access a private object until the
+ * user has authenticated to the token.
+ *
+ * These two flags are related and cannot both be set.
+ * If the PK11_ATTR_PRIVATE flag is set, the object is a private
+ * object.  If the PK11_ATTR_PUBLIC flag is set, the object is a
+ * public object.  If neither flag is set, it is token-specific
+ * whether the object is private or public.
+ *
+ * These two flags specify the value of the PKCS #11 CKA_PRIVATE
+ * attribute.  NSS only uses this attribute on private and secret
+ * keys, so public keys created by NSS get the token-specific
+ * default value of the CKA_PRIVATE attribute.
+ */
+#define PK11_ATTR_PRIVATE       0x00000004L
+#define PK11_ATTR_PUBLIC        0x00000008L
+
+/*
+ * PK11_ATTR_MODIFIABLE
+ * PK11_ATTR_UNMODIFIABLE
+ *
+ * These two flags determine whether the object is modifiable or
+ * read-only.
+ *
+ * These two flags are related and cannot both be set.
+ * If the PK11_ATTR_MODIFIABLE flag is set, the object can be
+ * modified.  If the PK11_ATTR_UNMODIFIABLE flag is set, the object
+ * is read-only.  If neither flag is set, the object is *by default*
+ * modifiable.
+ *
+ * These two flags specify the value of the PKCS #11 CKA_MODIFIABLE
+ * attribute.
+ */
+#define PK11_ATTR_MODIFIABLE    0x00000010L
+#define PK11_ATTR_UNMODIFIABLE  0x00000020L
+
+/* Attributes for PKCS #11 key objects. */
+
+/*
+ * PK11_ATTR_SENSITIVE
+ * PK11_ATTR_INSENSITIVE
+ *
+ * These two flags are related and cannot both be set.
+ * If the PK11_ATTR_SENSITIVE flag is set, the key is sensitive.
+ * If the PK11_ATTR_INSENSITIVE flag is set, the key is not
+ * sensitive.  If neither flag is set, it is token-specific whether
+ * the key is sensitive or not.
+ *
+ * If a key is sensitive, certain attributes of the key cannot be
+ * revealed in plaintext outside the token.
+ *
+ * This flag specifies the value of the PKCS #11 CKA_SENSITIVE
+ * attribute.  Although the default value of the CKA_SENSITIVE
+ * attribute for secret keys is CK_FALSE per PKCS #11, some FIPS
+ * tokens set the default value to CK_TRUE because only CK_TRUE
+ * is allowed.  So in practice the default value of this attribute
+ * is token-specific, hence the need for two bitflags.
+ */
+#define PK11_ATTR_SENSITIVE     0x00000040L
+#define PK11_ATTR_INSENSITIVE   0x00000080L
+
+/*
+ * PK11_ATTR_EXTRACTABLE
+ * PK11_ATTR_UNEXTRACTABLE
+ *
+ * These two flags are related and cannot both be set.
+ * If the PK11_ATTR_EXTRACTABLE flag is set, the key is extractable
+ * and can be wrapped.  If the PK11_ATTR_UNEXTRACTABLE flag is set,
+ * the key is not extractable, and certain attributes of the key
+ * cannot be revealed in plaintext outside the token (just like a
+ * sensitive key).  If neither flag is set, it is token-specific
+ * whether the key is extractable or not.
+ *
+ * These two flags specify the value of the PKCS #11 CKA_EXTRACTABLE
+ * attribute.
+ */
+#define PK11_ATTR_EXTRACTABLE   0x00000100L
+#define PK11_ATTR_UNEXTRACTABLE 0x00000200L
 
 /* Cryptographic module types */
 #define SECMOD_EXTERNAL	0	/* external module */
 #define SECMOD_INTERNAL 1	/* internal default module */
 #define SECMOD_FIPS	2	/* internal fips module */
 
 /* default module configuration strings */
 #define SECMOD_SLOT_FLAGS "slotFlags=[RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,SHA256,SHA512]"
@@ -247,16 +384,33 @@ typedef enum {
 /* function pointer type for password callback function.
  * This type is passed in to PK11_SetPasswordFunc() 
  */
 typedef char *(PR_CALLBACK *PK11PasswordFunc)(PK11SlotInfo *slot, PRBool retry, void *arg);
 typedef PRBool (PR_CALLBACK *PK11VerifyPasswordFunc)(PK11SlotInfo *slot, void *arg);
 typedef PRBool (PR_CALLBACK *PK11IsLoggedInFunc)(PK11SlotInfo *slot, void *arg);
 
 /*
+ * Special strings the password callback function can return only if
+ * the slot is an protected auth path slot.
+ */ 
+#define PK11_PW_RETRY		"RETRY"	/* an failed attempt to authenticate
+					 * has already been made, just retry
+					 * the operation */
+#define PK11_PW_AUTHENTICATED	"AUTH"  /* a successful attempt to authenticate
+					 * has completed. Continue without
+					 * another call to C_Login */
+/* All other non-null values mean that that NSS could call C_Login to force
+ * the authentication. The following define is to aid applications in 
+ * documenting that is what it's trying to do */
+#define PK11_PW_TRY		"TRY"   /* Default: a prompt has been presented
+					 * to the user, initiate a C_Login
+					 * to authenticate the token */
+
+/*
  * PKCS #11 key structures
  */
 
 /*
 ** Attributes
 */
 struct SECKEYAttributeStr {
     SECItem attrType;
--- a/security/nss/lib/pki/pkistore.c
+++ b/security/nss/lib/pki/pkistore.c
@@ -94,20 +94,22 @@ struct certificate_hash_entry_str
  */
 /* sort the subject list from newest to oldest */
 static PRIntn subject_list_sort(void *v1, void *v2)
 {
     NSSCertificate *c1 = (NSSCertificate *)v1;
     NSSCertificate *c2 = (NSSCertificate *)v2;
     nssDecodedCert *dc1 = nssCertificate_GetDecoding(c1);
     nssDecodedCert *dc2 = nssCertificate_GetDecoding(c2);
-    if (dc1->isNewerThan(dc1, dc2)) {
+    if (!dc1) {
+	return dc2 ? 1 : 0;
+    } else if (!dc2) {
 	return -1;
     } else {
-	return 1;
+	return dc1->isNewerThan(dc1, dc2) ? -1 : 1;
     }
 }
 
 NSS_IMPLEMENT nssCertificateStore *
 nssCertificateStore_Create (
   NSSArena *arenaOpt
 )
 {
--- a/security/nss/lib/pki/tdcache.c
+++ b/security/nss/lib/pki/tdcache.c
@@ -152,20 +152,22 @@ new_cache_entry(NSSArena *arena, void *v
 
 /* sort the subject list from newest to oldest */
 static PRIntn subject_list_sort(void *v1, void *v2)
 {
     NSSCertificate *c1 = (NSSCertificate *)v1;
     NSSCertificate *c2 = (NSSCertificate *)v2;
     nssDecodedCert *dc1 = nssCertificate_GetDecoding(c1);
     nssDecodedCert *dc2 = nssCertificate_GetDecoding(c2);
-    if (dc1->isNewerThan(dc1, dc2)) {
+    if (!dc1) {
+	return dc2 ? 1 : 0;
+    } else if (!dc2) {
 	return -1;
-    } else {
-	return 1;
+    } else { 
+	return dc1->isNewerThan(dc1, dc2) ? -1 : 1;
     }
 }
 
 /* this should not be exposed in a header, but is here to keep the above
  * types/functions static
  */
 NSS_IMPLEMENT PRStatus
 nssTrustDomain_InitializeCache (
--- a/security/nss/lib/smime/cmslocal.h
+++ b/security/nss/lib/smime/cmslocal.h
@@ -328,12 +328,19 @@ extern SECStatus
 NSS_CMSAttributeArray_AddAttr(PLArenaPool *poolp, NSSCMSAttribute ***attrs, NSSCMSAttribute *attr);
 
 /*
  * NSS_CMSAttributeArray_SetAttr - set an attribute's value in a set of attributes
  */
 extern SECStatus
 NSS_CMSAttributeArray_SetAttr(PLArenaPool *poolp, NSSCMSAttribute ***attrs, SECOidTag type, SECItem *value, PRBool encoded);
 
+/*
+ * 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);
+
 /************************************************************************/
 SEC_END_PROTOS
 
 #endif /* _CMSLOCAL_H_ */
--- a/security/nss/lib/smime/cmssigdata.c
+++ b/security/nss/lib/smime/cmssigdata.c
@@ -81,32 +81,38 @@ NSS_CMSSignedData_Create(NSSCMSMessage *
 loser:
     PORT_ArenaRelease(poolp, mark);
     return NULL;
 }
 
 void
 NSS_CMSSignedData_Destroy(NSSCMSSignedData *sigd)
 {
-    CERTCertificate **certs, *cert;
+    CERTCertificate **certs, **tempCerts, *cert;
     CERTCertificateList **certlists, *certlist;
     NSSCMSSignerInfo **signerinfos, *si;
 
     if (sigd == NULL)
 	return;
 
     certs = sigd->certs;
+    tempCerts = sigd->tempCerts;
     certlists = sigd->certLists;
     signerinfos = sigd->signerInfos;
 
     if (certs != NULL) {
 	while ((cert = *certs++) != NULL)
 	    CERT_DestroyCertificate (cert);
     }
 
+    if (tempCerts != NULL) {
+	while ((cert = *tempCerts++) != NULL)
+	    CERT_DestroyCertificate (cert);
+    }
+
     if (certlists != NULL) {
 	while ((certlist = *certlists++) != NULL)
 	    CERT_DestroyCertificateList (certlist);
     }
 
     if (signerinfos != NULL) {
 	while ((si = *signerinfos++) != NULL)
 	    NSS_CMSSignerInfo_Destroy(si);
@@ -545,16 +551,23 @@ NSS_CMSSignedData_ImportCerts(NSSCMSSign
 
     /* get the certs in the temp DB */
     rv = CERT_ImportCerts(certdb, certusage, certcount, sigd->rawCerts, 
 			 &certArray, PR_FALSE, PR_FALSE, NULL);
     if (rv != SECSuccess) {
 	goto loser;
     }
 
+    /* save the certs so they don't get destroyed */
+    for (i=0; i < certcount; i++) {
+	CERTCertificate *cert = certArray[i];
+	if (cert)
+            NSS_CMSSignedData_AddTempCertificate(sigd, cert);
+    }
+
     if (!keepcerts) {
 	goto done;
     }
 
     /* build a CertList for filtering */
     certList = CERT_NewCertList();
     if (certList == NULL) {
 	rv = SECFailure;
@@ -777,16 +790,32 @@ NSS_CMSSignedData_AddCertChain(NSSCMSSig
     if (certlist == NULL)
 	return SECFailure;
 
     rv = NSS_CMSSignedData_AddCertList(sigd, certlist);
 
     return rv;
 }
 
+extern SECStatus
+NSS_CMSSignedData_AddTempCertificate(NSSCMSSignedData *sigd, CERTCertificate *cert)
+{
+    CERTCertificate *c;
+    SECStatus rv;
+
+    if (!sigd || !cert) {
+        PORT_SetError(SEC_ERROR_INVALID_ARGS);
+        return SECFailure;
+    }
+
+    c = CERT_DupCertificate(cert);
+    rv = NSS_CMSArray_Add(sigd->cmsg->poolp, (void ***)&(sigd->tempCerts), (void *)c);
+    return rv;
+}
+
 SECStatus
 NSS_CMSSignedData_AddCertificate(NSSCMSSignedData *sigd, CERTCertificate *cert)
 {
     CERTCertificate *c;
     SECStatus rv;
 
     if (!sigd || !cert) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
--- a/security/nss/lib/smime/cmst.h
+++ b/security/nss/lib/smime/cmst.h
@@ -197,16 +197,19 @@ struct NSSCMSSignedDataStr {
     SECItem **			rawCerts;
     CERTSignedCrl **		crls;
     NSSCMSSignerInfo **		signerInfos;
     /* --------- local; not part of encoding --------- */
     NSSCMSMessage *		cmsg;			/* back pointer to message */
     SECItem **			digests;
     CERTCertificate **		certs;
     CERTCertificateList **	certLists;
+    CERTCertificate **          tempCerts;              /* temporary certs, needed
+                                                         * for example for signature
+                                                         * verification */
 };
 #define NSS_CMS_SIGNED_DATA_VERSION_BASIC	1	/* what we *create* */
 #define NSS_CMS_SIGNED_DATA_VERSION_EXT		3	/* what we *create* */
 
 typedef enum {
     NSSCMSVS_Unverified = 0,
     NSSCMSVS_GoodSignature = 1,
     NSSCMSVS_BadSignature = 2,
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -57,16 +57,17 @@
 #include "pkcs11i.h"
 #include "softoken.h"
 #include "lowkeyi.h"
 #include "blapi.h"
 #include "secder.h"
 #include "secport.h"
 #include "pcert.h"
 #include "secrng.h"
+#include "nss.h"
 
 #include "keydbi.h" 
 
 #ifdef NSS_ENABLE_ECC
 extern SECStatus EC_FillParams(PRArenaPool *arena, 
     const SECItem *encodedParams, ECParams *params);
 #endif
 
@@ -2906,18 +2907,18 @@ extern const char __nss_softokn_sccsid[]
 CK_RV  NSC_GetInfo(CK_INFO_PTR pInfo)
 {
     volatile char c; /* force a reference that won't get optimized away */
 
     c = __nss_softokn_rcsid[0] + __nss_softokn_sccsid[0]; 
     pInfo->cryptokiVersion.major = 2;
     pInfo->cryptokiVersion.minor = 11;
     PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
-    pInfo->libraryVersion.major = 3;
-    pInfo->libraryVersion.minor = 8;
+    pInfo->libraryVersion.major = NSS_VMAJOR;
+    pInfo->libraryVersion.minor = NSS_VMINOR;
     PORT_Memcpy(pInfo->libraryDescription,libraryDescription,32);
     pInfo->flags = 0;
     return CKR_OK;
 }
 
 
 /* NSC_GetSlotList obtains a list of slots in the system. */
 CK_RV nsc_CommonGetSlotList(CK_BBOOL tokenPresent, 
@@ -2948,18 +2949,18 @@ CK_RV NSC_GetSlotInfo(CK_SLOT_ID slotID,
     pInfo->firmwareVersion.major = 0;
     pInfo->firmwareVersion.minor = 0;
 
     PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
     PORT_Memcpy(pInfo->slotDescription,slot->slotDescription,64);
     pInfo->flags = CKF_TOKEN_PRESENT;
     /* ok we really should read it out of the keydb file. */
     /* pInfo->hardwareVersion.major = NSSLOWKEY_DB_FILE_VERSION; */
-    pInfo->hardwareVersion.major = 3;
-    pInfo->hardwareVersion.minor = 8;
+    pInfo->hardwareVersion.major = NSS_VMAJOR;
+    pInfo->hardwareVersion.minor = NSS_VMINOR;
     return CKR_OK;
 }
 
 #define CKF_THREAD_SAFE 0x8000 /* for now */
 /*
  * check the current state of the 'needLogin' flag in case the database has
  * been changed underneath us.
  */
--- a/security/nss/lib/util/secasn1e.c
+++ b/security/nss/lib/util/secasn1e.c
@@ -58,16 +58,24 @@ typedef enum {
 
 typedef enum {
     allDone,
     encodeError,
     keepGoing,
     needBytes
 } sec_asn1e_parse_status;
 
+typedef enum {
+    hdr_normal      = 0,  /* encode header normally */
+    hdr_any         = 1,  /* header already encoded in content */
+    hdr_decoder     = 2,  /* template only used by decoder. skip it. */
+    hdr_optional    = 3,  /* optional component, to be omitted */
+    hdr_placeholder = 4   /* place holder for from_buf content */
+} sec_asn1e_hdr_encoding;
+
 typedef struct sec_asn1e_state_struct {
     SEC_ASN1EncoderContext *top;
     const SEC_ASN1Template *theTemplate;
     void *src;
 
     struct sec_asn1e_state_struct *parent;	/* aka prev */
     struct sec_asn1e_state_struct *child;	/* aka next */
 
@@ -303,17 +311,17 @@ sec_asn1e_init_state_based_on_template (
 	 * This is an implicit, non-universal (meaning, application-private
 	 * or context-specific) field.  This results in a "magic" tag but
 	 * encoding based on the underlying type.  We pushed a new state
 	 * that is based on the subtemplate (the underlying type), but
 	 * now we will sort of alias it to give it some of our properties
 	 * (tag, optional status, etc.).
 	 *
 	 * NB: ALL the following flags in the subtemplate are disallowed
-	 *     and/or ignored: ECPLICIT, OPTIONAL, INNER< INLINE< POINTER.
+	 *     and/or ignored: EXPLICIT, OPTIONAL, INNER, INLINE, POINTER.
 	 */
 
 	under_kind = state->theTemplate->kind;
 	if ((under_kind & SEC_ASN1_MAY_STREAM) && !disallowStreaming) {
 	    may_stream = PR_TRUE;
 	}
 	under_kind &= ~(SEC_ASN1_MAY_STREAM | SEC_ASN1_DYNAMIC);
     } else {
@@ -496,17 +504,18 @@ sec_asn1e_which_choice
     }
   }
 
   return 0;
 }
 
 static unsigned long
 sec_asn1e_contents_length (const SEC_ASN1Template *theTemplate, void *src,
-			   PRBool disallowStreaming, PRBool *noheaderp)
+			   PRBool disallowStreaming, PRBool insideIndefinite,
+			   sec_asn1e_hdr_encoding *pHdrException)
 {
     unsigned long encode_kind, underlying_kind;
     PRBool isExplicit, optional, universal, may_stream;
     unsigned long len;
 
     /*
      * This function currently calculates the length in all cases
      * except the following: when writing out the contents of a 
@@ -535,116 +544,124 @@ sec_asn1e_contents_length (const SEC_ASN
 
     PORT_Assert (!(isExplicit && universal));	/* bad templates */
 
     may_stream = (encode_kind & SEC_ASN1_MAY_STREAM) ? PR_TRUE : PR_FALSE;
     encode_kind &= ~SEC_ASN1_MAY_STREAM;
 
     /* Just clear this to get it out of the way; we do not need it here */
     encode_kind &= ~SEC_ASN1_DYNAMIC;
+
+    if (encode_kind & SEC_ASN1_NO_STREAM) {
+	disallowStreaming = PR_TRUE;
+    }
     encode_kind &= ~SEC_ASN1_NO_STREAM;
 
-    if( encode_kind & SEC_ASN1_CHOICE ) {
-      void *src2;
-      int indx = sec_asn1e_which_choice(src, theTemplate);
-      if( 0 == indx ) {
-        /* XXX set an error? "choice not found" */
-        /* state->top->status = encodeError; */
-        return 0;
-      }
+    if (encode_kind & SEC_ASN1_CHOICE) {
+	void *src2;
+	int indx = sec_asn1e_which_choice(src, theTemplate);
+	if (0 == indx) {
+	    /* XXX set an error? "choice not found" */
+	    /* state->top->status = encodeError; */
+	    return 0;
+	}
 
-      src2 = (void *)((char *)src - theTemplate->offset + theTemplate[indx].offset);
+        src2 = (void *)
+	        ((char *)src - theTemplate->offset + theTemplate[indx].offset);
 
-      return sec_asn1e_contents_length(&theTemplate[indx], src2, 
-                                       PR_FALSE, noheaderp);
+        return sec_asn1e_contents_length(&theTemplate[indx], src2, 
+					 disallowStreaming, insideIndefinite,
+					 pHdrException);
     }
 
     if ((encode_kind & (SEC_ASN1_POINTER | SEC_ASN1_INLINE)) || !universal) {
 	/* XXX any bits we want to disallow (PORT_Assert against) here? */
 	theTemplate = SEC_ASN1GetSubtemplate (theTemplate, src, PR_TRUE);
 	if (encode_kind & SEC_ASN1_POINTER) {
 	    src = *(void **)src;
 	    if (src == NULL) {
-		if (optional)
-		    *noheaderp = PR_TRUE;
-		else 
-		    *noheaderp = PR_FALSE;
+		*pHdrException = optional ? hdr_optional : hdr_normal;
 		return 0;
 	    }
 	} else if (encode_kind & SEC_ASN1_INLINE) {
 	    /* check that there are no extraneous bits */
 	    if (optional) {
 		if (PR_FALSE != SEC_ASN1IsTemplateSimple(theTemplate)) {
 		    /* we now know that the target is a SECItem*, so we can check
 		       if the source contains one */
 		    SECItem* target = (SECItem*)src;
 		    if (!target || !target->data || !target->len) {
 			/* no valid data to encode subtemplate */
-			*noheaderp = PR_TRUE;
+			*pHdrException = hdr_optional;
 			return 0;
 		    }
 		} else {
 		    PORT_Assert(0); /* complex templates not handled as inline
                                        optional */
 		}
 	    }
 	}
 
 	src = (char *)src + theTemplate->offset;
 
 	/* recurse to find the length of the subtemplate */
-	len = sec_asn1e_contents_length (theTemplate, src, PR_FALSE, noheaderp);
+	len = sec_asn1e_contents_length (theTemplate, src, disallowStreaming, 
+	                                 insideIndefinite, pHdrException);
 	if (len == 0 && optional) {
-	    *noheaderp = PR_TRUE;
+	    *pHdrException = hdr_optional;
 	} else if (isExplicit) {
-	    if (*noheaderp) {
-		/* Okay, *we* do not want to add in a header, but our caller still does. */
-		*noheaderp = PR_FALSE;
-	    } else {
+	    if (*pHdrException == hdr_any) {
+		/* *we* do not want to add in a header, 
+		** but our caller still does. 
+		*/
+		*pHdrException = hdr_normal;
+	    } else if (*pHdrException == hdr_normal) {
 		/* if the inner content exists, our length is
 		 * len(identifier) + len(length) + len(innercontent)
 		 * XXX we currently assume len(identifier) == 1;
 		 * to support a high-tag-number this would need to be smarter.
 		 */
 		len += 1 + SEC_ASN1LengthLength (len);
 	    }
 	}
 	return len;
     }
     underlying_kind = encode_kind;
 
     /* This is only used in decoding; it plays no part in encoding.  */
     if (underlying_kind & SEC_ASN1_SAVE) {
 	/* check that there are no extraneous bits */
 	PORT_Assert (underlying_kind == SEC_ASN1_SAVE);
-	*noheaderp = PR_TRUE;
+	*pHdrException = hdr_decoder;
 	return 0;
     }
 
 #define UNEXPECTED_FLAGS \
  (SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_INLINE | SEC_ASN1_POINTER |\
   SEC_ASN1_DYNAMIC | SEC_ASN1_MAY_STREAM | SEC_ASN1_SAVE | SEC_ASN1_SKIP)
 
     /* Having any of these bits is not expected here...  */
     PORT_Assert ((underlying_kind & UNEXPECTED_FLAGS) == 0);
     underlying_kind &= ~UNEXPECTED_FLAGS;
 #undef UNEXPECTED_FLAGS
 
-    if( underlying_kind & SEC_ASN1_CHOICE ) {
-      void *src2;
-      int indx = sec_asn1e_which_choice(src, theTemplate);
-      if( 0 == indx ) {
-        /* XXX set an error? "choice not found" */
-        /* state->top->status = encodeError; */
-        return 0;
-      }
+    if (underlying_kind & SEC_ASN1_CHOICE) {
+	void *src2;
+	int indx = sec_asn1e_which_choice(src, theTemplate);
+	if (0 == indx) {
+	    /* XXX set an error? "choice not found" */
+	    /* state->top->status = encodeError; */
+	    return 0;
+	}
 
-      src2 = (void *)((char *)src - theTemplate->offset + theTemplate[indx].offset);
-      len = sec_asn1e_contents_length(&theTemplate[indx], src2, PR_FALSE,
-                                      noheaderp);
+        src2 = (void *)
+		((char *)src - theTemplate->offset + theTemplate[indx].offset);
+        len = sec_asn1e_contents_length(&theTemplate[indx], src2, 
+	                                disallowStreaming, insideIndefinite, 
+					pHdrException);
     } else {
       switch (underlying_kind) {
       case SEC_ASN1_SEQUENCE_OF:
       case SEC_ASN1_SET_OF:
 	{
 	    const SEC_ASN1Template *tmpt;
 	    void *sub_src;
 	    unsigned long sub_len;
@@ -655,47 +672,51 @@ sec_asn1e_contents_length (const SEC_ASN
 	    group = *(void ***)src;
 	    if (group == NULL)
 		break;
 
 	    tmpt = SEC_ASN1GetSubtemplate (theTemplate, src, PR_TRUE);
 
 	    for (; *group != NULL; group++) {
 		sub_src = (char *)(*group) + tmpt->offset;
-		sub_len = sec_asn1e_contents_length (tmpt, sub_src, PR_FALSE,
-                                                     noheaderp);
+		sub_len = sec_asn1e_contents_length (tmpt, sub_src, 
+		                                     disallowStreaming,
+						     insideIndefinite,
+                                                     pHdrException);
 		len += sub_len;
 		/*
 		 * XXX The 1 below is the presumed length of the identifier;
 		 * to support a high-tag-number this would need to be smarter.
 		 */
-		if (!*noheaderp)
+		if (*pHdrException == hdr_normal)
 		    len += 1 + SEC_ASN1LengthLength (sub_len);
 	    }
 	}
 	break;
 
       case SEC_ASN1_SEQUENCE:
       case SEC_ASN1_SET:
 	{
 	    const SEC_ASN1Template *tmpt;
 	    void *sub_src;
 	    unsigned long sub_len;
 
 	    len = 0;
 	    for (tmpt = theTemplate + 1; tmpt->kind; tmpt++) {
 		sub_src = (char *)src + tmpt->offset;
-		sub_len = sec_asn1e_contents_length (tmpt, sub_src, PR_FALSE,
-                                                     noheaderp);
+		sub_len = sec_asn1e_contents_length (tmpt, sub_src, 
+		                                     disallowStreaming,
+						     insideIndefinite,
+                                                     pHdrException);
 		len += sub_len;
 		/*
 		 * XXX The 1 below is the presumed length of the identifier;
 		 * to support a high-tag-number this would need to be smarter.
 		 */
-		if (!*noheaderp)
+		if (*pHdrException == hdr_normal)
 		    len += 1 + SEC_ASN1LengthLength (sub_len);
 	    }
 	}
 	break;
 
       case SEC_ASN1_BIT_STRING:
 	/* convert bit length to byte */
 	len = (((SECItem *)src)->len + 7) >> 3;
@@ -730,108 +751,129 @@ sec_asn1e_contents_length (const SEC_ASN
 		buf++;
 		len--;
 	    }
 	}
 	break;
 
       default:
 	len = ((SECItem *)src)->len;
-	if (may_stream && len == 0 && !disallowStreaming)
-	    len = 1;	/* if we're streaming, we may have a secitem w/len 0 as placeholder */
 	break;
+      }  /* end switch */
+
+#ifndef WHAT_PROBLEM_DOES_THIS_SOLVE
+      /* if we're streaming, we may have a secitem w/len 0 as placeholder */
+      if (!len && insideIndefinite && may_stream && !disallowStreaming) {
+	  len = 1;
       }
-    }
+#endif
+    }    /* end else */
 
-    if ((len == 0 && optional) || underlying_kind == SEC_ASN1_ANY)
-	*noheaderp = PR_TRUE;
+    if (len == 0 && optional)
+	*pHdrException = hdr_optional;
+    else if (underlying_kind == SEC_ASN1_ANY)
+	*pHdrException = hdr_any;
     else 
-	*noheaderp = PR_FALSE;
+	*pHdrException = hdr_normal;
 
     return len;
 }
 
 
 static void
 sec_asn1e_write_header (sec_asn1e_state *state)
 {
     unsigned long contents_length;
     unsigned char tag_number, tag_modifiers;
-    PRBool noheader;
+    sec_asn1e_hdr_encoding hdrException = hdr_normal;
+    PRBool indefinite = PR_FALSE;
 
     PORT_Assert (state->place == beforeHeader);
 
     tag_number = state->tag_number;
     tag_modifiers = state->tag_modifiers;
 
     if (state->underlying_kind == SEC_ASN1_ANY) {
 	state->place = duringContents;
 	return;
     }
 
-    if( state->underlying_kind & SEC_ASN1_CHOICE ) {
-      int indx = sec_asn1e_which_choice(state->src, state->theTemplate);
-      if( 0 == indx ) {
-        /* XXX set an error? "choice not found" */
-        state->top->status = encodeError;
-        return;
-      }
-
-      state->place = afterChoice;
-      state = sec_asn1e_push_state(state->top, &state->theTemplate[indx],
-                                   (char *)state->src - state->theTemplate->offset, 
-				   PR_TRUE);
-
-      if( (sec_asn1e_state *)NULL != state ) {
-        /*
-         * Do the "before" field notification.
-         */
-        sec_asn1e_notify_before (state->top, state->src, state->depth);
-        state = sec_asn1e_init_state_based_on_template (state);
-      }
-      
-      return;
+    if (state->underlying_kind & SEC_ASN1_CHOICE) {
+	int indx = sec_asn1e_which_choice(state->src, state->theTemplate);
+	if( 0 == indx ) {
+	    /* XXX set an error? "choice not found" */
+	    state->top->status = encodeError;
+	    return;
+	}
+	state->place = afterChoice;
+	state = sec_asn1e_push_state(state->top, &state->theTemplate[indx],
+			       (char *)state->src - state->theTemplate->offset, 
+			       PR_TRUE);
+	if (state) {
+	    /*
+	     * Do the "before" field notification.
+	     */
+	    sec_asn1e_notify_before (state->top, state->src, state->depth);
+	    state = sec_asn1e_init_state_based_on_template (state);
+	}
+	return;
     }
 
+    /* The !isString test below is apparently intended to ensure that all 
+    ** constructed types receive indefinite length encoding.
+    */
+   indefinite = (PRBool) 
+	(state->top->streaming && state->may_stream && 
+	 (state->top->from_buf || !state->is_string));
+
     /*
-     * We are doing a definite-length encoding.  First we have to
+     * If we are doing a definite-length encoding, first we have to
      * walk the data structure to calculate the entire contents length.
+     * If we are doing an indefinite-length encoding, we still need to 
+     * know if the contents is:
+     *    optional and to be omitted, or 
+     *    an ANY (header is pre-encoded), or 
+     *    a SAVE or some other kind of template used only by the decoder.
+     * So, we call this function either way.
      */
     contents_length = sec_asn1e_contents_length (state->theTemplate,
 						 state->src, 
                                                  state->disallowStreaming,
-                                                 &noheader);
+						 indefinite,
+                                                 &hdrException);
     /*
      * We might be told explicitly not to put out a header.
      * But it can also be the case, via a pushed subtemplate, that
      * sec_asn1e_contents_length could not know that this field is
      * really optional.  So check for that explicitly, too.
      */
-    if (noheader || (contents_length == 0 && state->optional)) {
+    if (hdrException != hdr_normal || 
+	(contents_length == 0 && state->optional)) {
 	state->place = afterContents;
-	if (state->top->streaming && state->may_stream && state->top->from_buf)
-	    /* we did not find an optional indefinite string, so we don't encode it.
-	     * However, if TakeFromBuf is on, we stop here anyway to give our caller
-	     * a chance to intercept at the same point where we would stop if the
-	     * field were present. */
+	if (state->top->streaming && 
+	    state->may_stream && 
+	    state->top->from_buf) {
+	    /* we did not find an optional indefinite string, so we 
+	     * don't encode it.  However, if TakeFromBuf is on, we stop 
+	     * here anyway to give our caller a chance to intercept at the 
+	     * same point where we would stop if the field were present. 
+	     */
 	    state->top->status = needBytes;
+	}
 	return;
     }
 
-    if (state->top->streaming && state->may_stream
-			      && (state->top->from_buf || !state->is_string)) {
+    if (indefinite) {
 	/*
 	 * We need to put out an indefinite-length encoding.
-	 */
-	state->indefinite = PR_TRUE;
-	/*
 	 * The only universal types that can be constructed are SETs,
 	 * SEQUENCEs, and strings; so check that it is one of those,
 	 * or that it is not universal (e.g. context-specific).
 	 */
+	state->indefinite = PR_TRUE;
 	PORT_Assert ((tag_number == SEC_ASN1_SET)
 		     || (tag_number == SEC_ASN1_SEQUENCE)
 		     || ((tag_modifiers & SEC_ASN1_CLASS_MASK) != 0)
 		     || state->is_string);
 	tag_modifiers |= SEC_ASN1_CONSTRUCTED;
 	contents_length = 0;
     }
 
--- a/security/nss/lib/util/secport.h
+++ b/security/nss/lib/util/secport.h
@@ -32,20 +32,16 @@
  * 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
  *
- * This file abstracts out libc functionality that libsec depends on
- * 
- * NOTE - These are not public interfaces
- *
  * $Id$
  */
 
 #ifndef _SECPORT_H_
 #define _SECPORT_H_
 
 /*
  * define XP_MAC, XP_WIN, XP_BEOS, or XP_UNIX, in case they are not defined
@@ -93,22 +89,16 @@
 #include <types.h>
 #elif defined( XP_MAC ) 
 #include <types.h>
 #include <time.h> /* for time_t below */
 #else
 #include <sys/types.h>
 #endif
 
-#ifdef notdef
-#ifdef XP_MAC
-#include "NSString.h"
-#endif
-#endif
-
 #include <ctype.h>
 #include <string.h>
 #if defined(_WIN32_WCE)
 #include <stdlib.h>	/* WinCE puts some stddef symbols here. */
 #else
 #include <stddef.h>
 #endif
 #include <stdlib.h>
--- a/security/nss/tests/cipher/cipher.sh
+++ b/security/nss/tests/cipher/cipher.sh
@@ -82,28 +82,28 @@ cipher_init()
   fi
 }
 
 ############################## cipher_main #############################
 # local shell function to test NSS ciphers
 ########################################################################
 cipher_main()
 {
-  cat ${CIPHER_TXT} | while read EXP_RET PARAM TESTNAME
+  while read EXP_RET PARAM TESTNAME
   do
       if [ -n "$EXP_RET" -a "$EXP_RET" != "#" ] ; then
           PARAM=`echo $PARAM | sed -e "s/_-/ -/g"`
           TESTNAME=`echo $TESTNAME | sed -e "s/_/ /g"`
           echo "$SCRIPTNAME: $TESTNAME --------------------------------"
           echo "bltest -T -m $PARAM -d ${P_CIPHER}"
 
           bltest -T -m $PARAM -d ${P_CIPHER} 
           html_msg $? $EXP_RET "$TESTNAME"
       fi
-  done
+  done < ${CIPHER_TXT}
 }
 
 ############################## cipher_cleanup ############################
 # local shell function to finish this script (no exit since it might be
 # sourced)
 ########################################################################
 cipher_cleanup()
 {
--- a/security/nss/tests/cipher/performance.sh
+++ b/security/nss/tests/cipher/performance.sh
@@ -27,118 +27,122 @@ if [ -z $1 ]; then
 else
     TESTSET=$1
 fi
 
 if [ $TESTSET = "all" -o $TESTSET = "symmkey" ]; then
 echo "<TABLE BORDER=1><TR><TH COLSPAN=6>Symmetric Key Cipher Performance</TH></TR>" >> ${PERFRESULTS}
 echo "<TR bgcolor=lightGreen><TH>MODE</TH><TH>INPUT SIZE (bytes)</TH><TH>SYMMETRIC KEY SIZE (bits)</TH><TH>REPETITIONS (cx/op)</TH><TH>CONTEXT CREATION TIME (ms)</TH><TH>OPERATION TIME (ms)</TH></TR>" >> ${PERFRESULTS}
 
-cat ${SKTESTS} | while read mode keysize bufsize reps cxreps
+while read mode keysize bufsize reps cxreps
 do
     if [ $mode != "#" ]; then
 	echo "bltest -N -m $mode -b $bufsize -g $keysize -u $cxreps"
 	bltest -N -m $mode -b $bufsize -g $keysize -u $cxreps >> ${SKPERFOUT}
 	mv "tmp.in" "$mode.in"
 	mv tmp.key $mode.key
 	if [ -f tmp.iv ]; then
 	    mv tmp.iv $mode.iv
 	fi
 	echo "bltest -E -m $mode -i ${CIPHERDIR}/$mode.in -k ${CIPHERDIR}/$mode.key -v ${CIPHERDIR}/$mode.iv -p $reps -o ${CIPHERDIR}/$mode.out"
 	bltest -E -m $mode -i ${CIPHERDIR}/$mode.in -k ${CIPHERDIR}/$mode.key -v ${CIPHERDIR}/$mode.iv -p $reps -o ${CIPHERDIR}/$mode.out >> ${SKPERFOUT}
 	echo "bltest -D -m $mode -i ${CIPHERDIR}/$mode.out -k ${CIPHERDIR}/$mode.key -v ${CIPHERDIR}/$mode.iv -p $reps -o ${CIPHERDIR}/$mode.inv"
 	bltest -D -m $mode -i ${CIPHERDIR}/$mode.out -k ${CIPHERDIR}/$mode.key -v ${CIPHERDIR}/$mode.iv -p $reps -o ${CIPHERDIR}/$mode.inv >> ${SKPERFOUT}
     fi
-done
+done < ${SKTESTS} 
 
-cat ${SKPERFOUT} | while read md buf sk rps cxrps cx op
+while read md buf sk rps cxrps cx op
 do
     if [ $md != "#" ]; then
 	echo "<TR><TH>$md</TH><TD align=right>$buf</TD><TD align=right>$sk</TD><TD align=right>$cxrps/$rps</TD><TD align=right>$cx</TD><TD align=right>$op</TD></TR>" >> ${PERFRESULTS}
     fi
-done
+done < ${SKPERFOUT} 
 
 echo "</TABLE><BR>" >> ${PERFRESULTS}
 
 fi
 
 if [ $TESTSET = "all" -o $TESTSET = "rsa" ]; then
-cat ${RSATESTS} | while read mode keysize bufsize exp reps cxreps
+while read mode keysize bufsize exp reps cxreps
 do
     if [ $mode != "#" ]; then
 	echo "bltest -N -m $mode -b $bufsize -e $exp -g $keysize -u $cxreps"
 	bltest -N -m $mode -b $bufsize -e $exp -g $keysize -u $cxreps >> ${RSAPERFOUT}
 	mv "tmp.in" "$mode.in"
 	mv tmp.key $mode.key
 	echo "bltest -E -m $mode -i ${CIPHERDIR}/$mode.in -k ${CIPHERDIR}/$mode.key -p $reps -o ${CIPHERDIR}/$mode.out"
 	bltest -E -m $mode -i ${CIPHERDIR}/$mode.in -k ${CIPHERDIR}/$mode.key -p $reps -o ${CIPHERDIR}/$mode.out >> ${RSAPERFOUT}
 	echo "bltest -D -m $mode -i ${CIPHERDIR}/$mode.out -k ${CIPHERDIR}/$mode.key -p $reps -o ${CIPHERDIR}/$mode.inv"
 	bltest -D -m $mode -i ${CIPHERDIR}/$mode.out -k ${CIPHERDIR}/$mode.key -p $reps -o ${CIPHERDIR}/$mode.inv >> ${RSAPERFOUT}
     fi
-done
+done < ${RSATESTS} 
 
 echo "<TABLE BORDER=1><TR><TH COLSPAN=7>RSA Cipher Performance</TH></TR>" >> ${PERFRESULTS}
 echo "<TR bgcolor=lightGreen><TH>MODE</TH><TH>INPUT SIZE (bytes)</TH><TH>KEY SIZE (bits)</TH><TH>PUBLIC EXPONENT</TH><TH>REPETITIONS (cx/op)</TH><TH>CONTEXT CREATION TIME (ms)</TH><TH>OPERATION TIME (ms)</TH></TR>" >> ${PERFRESULTS}
-cat ${RSAPERFOUT} | while read md buf mod pe rps cxrps cx op
+
+while read md buf mod pe rps cxrps cx op
 do
     if [ $md != "#" ]; then
 	echo "<TR><TH>$md</TH><TD align=right>$buf</TD><TD align=right>$mod</TD><TD align=right>$pe</TD><TD align=right>$cxrps/$rps</TD><TD align=right>$cx</TD><TD align=right>$op</TD></TR>" >> ${PERFRESULTS}
     fi
-done
+done < ${RSAPERFOUT} 
 
 echo "</TABLE><BR>" >> ${PERFRESULTS}
 fi
 
 if [ $TESTSET = "all" -o $TESTSET = "dsa" ]; then
-cat ${DSATESTS} | while read mode keysize bufsize reps cxreps
+
+while read mode keysize bufsize reps cxreps
 do
     if [ $mode != "#" ]; then
 	echo "bltest -N -m $mode -b $bufsize -g $keysize -u $cxreps"
 	bltest -N -m $mode -b $bufsize -g $keysize -u $cxreps >> ${DSAPERFOUT}
 	mv "tmp.in" "$mode.in"
 	mv tmp.key $mode.key
 	echo "bltest -S -m $mode -i ${CIPHERDIR}/$mode.in -k ${CIPHERDIR}/$mode.key -p $reps -o ${CIPHERDIR}/$mode.out"
 	bltest -S -m $mode -i ${CIPHERDIR}/$mode.in -k ${CIPHERDIR}/$mode.key -p $reps -o ${CIPHERDIR}/$mode.out >> ${DSAPERFOUT}
 	echo "bltest -V -m $mode -f ${CIPHERDIR}/$mode.out -k ${CIPHERDIR}/$mode.key -p $reps -i ${CIPHERDIR}/$mode.in -o ${CIPHERDIR}/$mode.out"
 	bltest -V -m $mode -f ${CIPHERDIR}/$mode.out -k ${CIPHERDIR}/$mode.key -p $reps -i ${CIPHERDIR}/$mode.in -o ${CIPHERDIR}/$mode.out >> ${DSAPERFOUT}
     fi
-done
+done < ${DSATESTS} 
 
 echo "<TABLE BORDER=1><TR><TH COLSPAN=6>DSA Cipher Performance</TH></TR>" >> ${PERFRESULTS}
 echo "<TR bgcolor=lightGreen><TH>MODE</TH><TH>INPUT SIZE (bytes)</TH><TH>KEY SIZE (bits)</TH><TH>REPETITIONS (cx/op)</TH><TH>CONTEXT CREATION TIME (ms)</TH><TH>OPERATION TIME (ms)</TH></TR>" >> ${PERFRESULTS}
-cat ${DSAPERFOUT} | while read md buf mod rps cxrps cx op
+
+while read md buf mod rps cxrps cx op
 do
     if [ $md != "#" ]; then
 	echo "<TR><TH>$md</TH><TD align=right>$buf</TD><TD align=right>$mod</TD><TD align=right>$cxrps/$rps</TD><TD align=right>$cx</TD><TD align=right>$op</TD></TR>" >> ${PERFRESULTS}
     fi
-done
+done < ${DSAPERFOUT} 
 
 echo "</TABLE><BR>" >> ${PERFRESULTS}
 fi
 
 if [ $TESTSET = "all" -o $TESTSET = "hash" ]; then
-cat ${HASHTESTS} | while read mode bufsize reps
+while read mode bufsize reps
 do
     if [ $mode != "#" ]; then
 	echo "bltest -N -m $mode -b $bufsize"
 	bltest -N -m $mode -b $bufsize
 	mv "tmp.in" "$mode.in"
 	echo "bltest -H -m $mode -i ${CIPHERDIR}/$mode.in -p $reps -o ${CIPHERDIR}/$mode.out"
 	bltest -H -m $mode -i ${CIPHERDIR}/$mode.in -p $reps -o ${CIPHERDIR}/$mode.out >> ${HASHPERFOUT}
     fi
-done
+done < ${HASHTESTS} 
 
 echo "<TABLE BORDER=1><TR><TH COLSPAN=6>Hash Cipher Performance</TH></TR>" >> ${PERFRESULTS}
 echo "<TR bgcolor=lightGreen><TH>MODE</TH><TH>INPUT SIZE (bytes)</TH><TH>REPETITIONS</TH><TH>OPERATION TIME (ms)</TH></TR>" >> ${PERFRESULTS}
-cat ${HASHPERFOUT} | while read md buf rps cxrps cx op
+
+while read md buf rps cxrps cx op
 do
     if [ $md != "#" ]; then
 	echo "<TR><TH>$md</TH><TD align=right>$buf</TD><TD align=right>$rps</TD><TD align=right>$op</TD></TR>" >> ${PERFRESULTS}
     fi
-done
+done < ${HASHPERFOUT} 
 
 echo "</TABLE><BR>" >> ${PERFRESULTS}
 fi
 
 #rm -f ${TEMPFILES}
 cd ${CURDIR}
 
 echo "</BODY></HTML>" >> ${PERFRESULTS}
--- a/security/nss/tests/common/cleanup.sh
+++ b/security/nss/tests/common/cleanup.sh
@@ -33,11 +33,12 @@
 # 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 *****
 
 
 if [ -z "${CLEANUP}" -o "${CLEANUP}" = "${SCRIPTNAME}" ]; then
+    html "END_OF_TEST<BR>"
     html "</BODY></HTML>" 
     rm -f ${TEMPFILES} 2>/dev/null
 fi