Bug 504080: Update NSS to the NSS_3_12_4_RTM CVS tag. r=kaie.
authorWan-Teh Chang <wtc@google.com>
Wed, 19 Aug 2009 06:59:06 -0700
changeset 31666 5d447d9abfdf7bc323e65a707a8c16d9594a04cb
parent 31665 d57c7bf46486af94e130a333a0ad2e818e218da4
child 31667 e202b5021327c9e0ce6141c9fd4afbb2205b9425
push idunknown
push userunknown
push dateunknown
reviewerskaie
bugs504080
milestone1.9.3a1pre
Bug 504080: Update NSS to the NSS_3_12_4_RTM CVS tag. r=kaie.
security/coreconf/Darwin.mk
security/coreconf/HP-UX.mk
security/coreconf/Linux.mk
security/coreconf/Linux2.4.mk
security/coreconf/RISCOS.mk
security/coreconf/WIN32.mk
security/coreconf/config.mk
security/coreconf/coreconf.dep
security/coreconf/rules.mk
security/nss/cmd/lib/pk11table.h
security/nss/cmd/pk11mode/pk11mode.c
security/nss/cmd/pwdecrypt/pwdecrypt.c
security/nss/cmd/shlibsign/Makefile
security/nss/lib/certdb/alg1485.c
security/nss/lib/certdb/certi.h
security/nss/lib/certdb/crl.c
security/nss/lib/ckfw/builtins/certdata.c
security/nss/lib/ckfw/builtins/certdata.txt
security/nss/lib/ckfw/capi/Makefile
security/nss/lib/ckfw/capi/cobject.c
security/nss/lib/libpkix/include/pkixt.h
security/nss/lib/libpkix/pkix/checker/pkix_ocspchecker.c
security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.c
security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.h
security/nss/lib/nss/nss.def
security/nss/lib/nss/nss.h
security/nss/lib/nss/nssinit.c
security/nss/lib/pk11wrap/pk11auth.c
security/nss/lib/pk11wrap/pk11pub.h
security/nss/lib/pk11wrap/pk11slot.c
security/nss/lib/pk11wrap/pk11util.c
security/nss/lib/pki/pki3hack.c
security/nss/lib/softoken/softkver.h
security/nss/lib/softoken/softoknt.h
security/nss/lib/util/nssutil.h
security/nss/lib/util/portreg.c
security/nss/lib/util/portreg.h
security/nss/lib/util/secport.c
security/nss/tests/chains/chains.sh
security/nss/tests/chains/scenarios/crldp.cfg
security/nss/tests/chains/scenarios/ocsp.cfg
--- a/security/coreconf/Darwin.mk
+++ b/security/coreconf/Darwin.mk
@@ -108,16 +108,19 @@ endif
 OS_CFLAGS	= $(DSO_CFLAGS) $(OS_REL_CFLAGS) -Wmost -fpascal-strings -fno-common -pipe -DDARWIN -DHAVE_STRERROR -DHAVE_BSD_FLOCK $(DARWIN_SDK_CFLAGS)
 
 ifdef BUILD_OPT
 ifeq (11,$(ALLOW_OPT_CODE_SIZE)$(OPT_CODE_SIZE))
 	OPTIMIZER       = -Oz
 else
 	OPTIMIZER	= -O2
 endif
+ifdef MOZ_DEBUG_SYMBOLS
+	OPTIMIZER  += -gdwarf-2 -gfull
+endif
 endif
 
 ARCH		= darwin
 
 DSO_CFLAGS	= -fPIC
 # 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
 
--- a/security/coreconf/HP-UX.mk
+++ b/security/coreconf/HP-UX.mk
@@ -79,15 +79,19 @@ LDFLAGS			= -z -Wl,+s
 MKSHLIB			= $(LD) $(DSO_LDOPTS) $(RPATH)
 ifdef MAPFILE
 MKSHLIB += -c $(MAPFILE)
 endif
 PROCESS_MAP_FILE = grep -v ';+' $< | grep -v ';-' | \
          sed -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,,' -e 's,^,+e ,' > $@
 
 DSO_LDOPTS		= -b +h $(notdir $@)
-ifeq ($(USE_64), 1)
-RPATH   = +b '$$ORIGIN'
+RPATH			= +b '$$ORIGIN'
+ifneq ($(OS_TEST),ia64)
+# pa-risc
+ifndef USE_64
+RPATH   =
+endif
 endif
 DSO_LDFLAGS		=
 
 # +Z generates position independent code for use in shared libraries.
 DSO_CFLAGS = +Z
--- a/security/coreconf/Linux.mk
+++ b/security/coreconf/Linux.mk
@@ -119,33 +119,42 @@ ifeq ($(OS_RELEASE),2.0)
 endif
 
 ifdef BUILD_OPT
 ifeq (11,$(ALLOW_OPT_CODE_SIZE)$(OPT_CODE_SIZE))
 	OPTIMIZER = -Os
 else
 	OPTIMIZER = -O2
 endif
+ifdef MOZ_DEBUG_SYMBOLS
+	OPTIMIZER  += -gstabs+
 endif
+endif
+
 
 ifeq ($(USE_PTHREADS),1)
 OS_PTHREAD = -lpthread 
 endif
 
 OS_CFLAGS		= $(DSO_CFLAGS) $(OS_REL_CFLAGS) $(ARCHFLAG) -ansi -Wall -Werror-implicit-function-declaration -Wno-switch -pipe -DLINUX -Dlinux -D_POSIX_SOURCE -D_BSD_SOURCE -DHAVE_STRERROR
 OS_LIBS			= $(OS_PTHREAD) -ldl -lc
 
 ifdef USE_PTHREADS
 	DEFINES		+= -D_REENTRANT
 endif
 
 ARCH			= linux
 
 DSO_CFLAGS		= -fPIC
-DSO_LDOPTS		= -shared $(ARCHFLAG) -Wl,-z,defs
+DSO_LDOPTS		= -shared $(ARCHFLAG)
+# The linker on Red Hat Linux 7.2 and RHEL 2.1 (GNU ld version 2.11.90.0.8)
+# incorrectly reports undefined references in the libraries we link with, so
+# we don't use -z defs there.
+ZDEFS_FLAG		= -Wl,-z,defs
+DSO_LDOPTS		+= $(if $(findstring 2.11.90.0.8,$(shell ld -v)),,$(ZDEFS_FLAG))
 DSO_LDFLAGS		=
 LDFLAGS			+= $(ARCHFLAG)
 
 # INCLUDES += -I/usr/include -Y/usr/include/linux
 G++INCLUDES		= -I/usr/include/g++
 
 #
 # Always set CPU_TAG on Linux, WINCE.
--- a/security/coreconf/Linux2.4.mk
+++ b/security/coreconf/Linux2.4.mk
@@ -40,9 +40,11 @@ include $(CORE_DEPTH)/coreconf/Linux.mk
 OS_REL_CFLAGS   += -DLINUX2_1
 MKSHLIB         = $(CC) $(DSO_LDOPTS) -Wl,-soname -Wl,$(@:$(OBJDIR)/%.so=%.so) $(RPATH)
 
 ifdef MAPFILE
 	MKSHLIB += -Wl,--version-script,$(MAPFILE)
 endif
 PROCESS_MAP_FILE = grep -v ';-' $< | \
         sed -e 's,;+,,' -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,;,' > $@
+        
+NSS_NO_FORK_CHECK=1
 
--- a/security/coreconf/RISCOS.mk
+++ b/security/coreconf/RISCOS.mk
@@ -15,16 +15,17 @@
 # The Original Code is the Netscape security libraries.
 #
 # The Initial Developer of the Original Code is
 # Netscape Communications Corporation.
 # Portions created by the Initial Developer are Copyright (C) 1994-2000
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
+#   Peter Naulls
 #
 # Alternatively, the contents of this file may be used under the terms of
 # either the GNU General Public License Version 2 or later (the "GPL"), or
 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 # in which case the provisions of the GPL or the LGPL are applicable instead
 # of those above. If you wish to allow use of your version of this file only
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
@@ -32,17 +33,24 @@
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 include $(CORE_DEPTH)/coreconf/UNIX.mk
 
-DLL_SUFFIX  = a
-MKSHLIB     = $(GCCSDK_INSTALL_CROSSBIN)/arm-unknown-riscos-ar cr
+LIB_SUFFIX  = a
+DLL_SUFFIX  = so
+AR          = ar cr $@ 
+LDOPTS     += -L$(SOURCE_LIB_DIR)
+MKSHLIB     = $(CC) $(DSO_LDOPTS) -Wl,-soname -Wl,$(@:$(OBJDIR)/%.so=%.so)
 
 OS_RELEASE =
 OS_TARGET  = RISCOS
 
+DSO_CFLAGS              = -fPIC
+DSO_LDOPTS              = -shared
+DSO_LDFLAGS             =
+
 ifdef BUILD_OPT
-	OPTIMIZER = -O2 -mpoke-function-name
+	OPTIMIZER = -O3
 endif
--- a/security/coreconf/WIN32.mk
+++ b/security/coreconf/WIN32.mk
@@ -58,17 +58,17 @@ else
 	LINK         = link
 	AR           = lib
 	AR          += -NOLOGO -OUT:"$@"
 	RANLIB       = echo
 	BSDECHO      = echo
 	RC           = rc.exe
 	MT           = mt.exe
 	# Determine compiler version
-	_MSC_VER_6   = 1200	# MSVC 6
+	_MSC_VER_6   = 1200
 	_MSC_VER    := $(shell $(CC) 2>&1 | sed -ne \
                        's/.*[^0-9.]\([0-9]\{1,\}\)\.\([0-9]\{1,\}\).*/\1\2/p' )
 endif
 
 ifdef BUILD_TREE
 NSINSTALL_DIR  = $(BUILD_TREE)/nss
 else
 NSINSTALL_DIR  = $(CORE_DEPTH)/coreconf/nsinstall
--- a/security/coreconf/config.mk
+++ b/security/coreconf/config.mk
@@ -189,16 +189,21 @@ endif
 ifdef BUILD_LIBPKIX_TESTS
 DEFINES += -DBUILD_LIBPKIX_TESTS
 endif
 
 ifdef NSS_DISABLE_DBM
 DEFINES += -DNSS_DISABLE_DBM
 endif
 
+ifdef NSS_NO_FORK_CHECK
+DEFINES += -DNO_FORK_CHECK
+DEFINES += -DNO_CHECK_FORK
+endif
+
 # Avoid building object leak test code for optimized library
 ifndef BUILD_OPT
 ifdef PKIX_OBJECT_LEAK_TEST
 DEFINES += -DPKIX_OBJECT_LEAK_TEST
 endif
 endif
 
 # This allows all library and tools code to use the util function
--- a/security/coreconf/coreconf.dep
+++ b/security/coreconf/coreconf.dep
@@ -38,10 +38,8 @@
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSS in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
 
-/* NSS 3.12.4 Beta */
-
--- a/security/coreconf/rules.mk
+++ b/security/coreconf/rules.mk
@@ -333,21 +333,17 @@ else
 ifdef MT
 	if test -f $@.manifest; then \
 		$(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;2; \
 		rm -f $@.manifest; \
 	fi
 endif	# MSVC with manifest tool
 endif
 else
-ifeq ($(OS_TARGET),RISCOS)
-	$(MKSHLIB) $@ $(OBJS) $(SUB_SHLOBJS)
-else
 	$(MKSHLIB) -o $@ $(OBJS) $(SUB_SHLOBJS) $(LD_LIBS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS)
-endif
 	chmod +x $@
 ifeq ($(OS_TARGET),Darwin)
 ifdef MAPFILE
 	nmedit -s $(MAPFILE) $@
 endif
 endif
 endif
 endif
--- a/security/nss/cmd/lib/pk11table.h
+++ b/security/nss/cmd/lib/pk11table.h
@@ -69,17 +69,17 @@ typedef enum {
     F_Load,
     F_Unload,
     F_System,
     F_Loop,
     F_Time,
     F_Help,
     F_Quit,
     F_QuitIf,
-    F_QuitIfString,
+    F_QuitIfString
 } FunctionType;
 
 /*
  * Supported Argument Types
  */
 typedef enum {
     ArgNone,
     ArgVar,
@@ -98,17 +98,17 @@ typedef enum {
 /* Modifier Flags */
     ArgMask = 0xff,
     ArgOut = 0x100,
     ArgArray = 0x200,
     ArgNew = 0x400,
     ArgFile = 0x800,
     ArgStatic = 0x1000,
     ArgOpt = 0x2000,
-    ArgFull = 0x4000,
+    ArgFull = 0x4000
 } ArgType;
 
 typedef enum _constType
 {
     ConstNone,
     ConstBool,
     ConstInfoFlags,
     ConstSlotFlags,
--- a/security/nss/cmd/pk11mode/pk11mode.c
+++ b/security/nss/cmd/pk11mode/pk11mode.c
@@ -5270,23 +5270,24 @@ void PKM_CheckPath(char *string)
 }
 
 CK_RV PKM_ForkCheck(int expected, CK_FUNCTION_LIST_PTR fList,
 		    PRBool forkAssert, CK_C_INITIALIZE_ARGS_NSS *initArgs)
 {
     CK_RV crv = CKR_OK;
 #ifndef NO_FORK_CHECK
     int rc = -1;
+    pid_t child, ret;
     NUMTESTS++; /* increment NUMTESTS */
     if (forkAssert) {
 	putenv("NSS_STRICT_NOFORK=1");
     } else {
 	putenv("NSS_STRICT_NOFORK=0");
     }
-    pid_t child = fork();
+    child = fork();
     switch (child) {
     case -1:
         PKM_Error("Fork failed.\n");
         crv = CKR_DEVICE_ERROR;
         break;
     case 0:
         if (fList) {
             if (!initArgs) {
@@ -5311,17 +5312,17 @@ CK_RV PKM_ForkCheck(int expected, CK_FUN
                     child_crv = fList->C_Finalize(NULL);
                 }
                 exit(child_crv & 255);
             }
         }
         exit(expected & 255);
     default:
         PKM_LogIt("Fork succeeded.\n");
-        pid_t ret = wait(&rc);
+        ret = wait(&rc);
         if (ret != child || (!WIFEXITED(rc)) ||
             ( (expected & 255) != (WEXITSTATUS(rc) & 255)) ) {
             int retStatus = -1;
             if (WIFEXITED(rc)) {
                 retStatus = WEXITSTATUS(rc);
             }
             PKM_Error("Child misbehaved.\n");
             printf("Child return status : %d.\n", retStatus & 255);
--- a/security/nss/cmd/pwdecrypt/pwdecrypt.c
+++ b/security/nss/cmd/pwdecrypt/pwdecrypt.c
@@ -32,17 +32,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * Test program for SDR (Secret Decoder Ring) functions.
  *
- * $Id: pwdecrypt.c,v 1.5 2008/08/08 23:47:58 julien.pierre.boogz%sun.com Exp $
+ * $Id: pwdecrypt.c,v 1.7 2009/08/03 07:07:13 nelson%bolyard.com Exp $
  */
 
 #include "nspr.h"
 #include "string.h"
 #include "nss.h"
 #include "secutil.h"
 #include "cert.h"
 #include "pk11func.h"
@@ -111,115 +111,141 @@ long_usage (char *program_name)
 		"  %-13s Password file\n",
 		"-f pwfile");
 }
 
 /*
  * base64 table only used to identify the end of a base64 string 
  */
 static unsigned char b64[256] = {
-/*   0: */        0,      0,      0,      0,      0,      0,      0,      0,
-/*   8: */        0,      0,      0,      0,      0,      0,      0,      0,
-/*  16: */        0,      0,      0,      0,      0,      0,      0,      0,
-/*  24: */        0,      0,      0,      0,      0,      0,      0,      0,
-/*  32: */        0,      0,      0,      0,      0,      0,      0,      0,
-/*  40: */        0,      0,      0,      1,      0,      0,      0,      1,
-/*  48: */        1,      1,      1,      1,      1,      1,      1,      1,
-/*  56: */        1,      1,      0,      0,      0,      0,      0,      0,
-/*  64: */        0,      1,      1,      1,      1,      1,      1,      1,
-/*  72: */        1,      1,      1,      1,      1,      1,      1,      1,
-/*  80: */        1,      1,      1,      1,      1,      1,      1,      1,
-/*  88: */        1,      1,      1,      0,      0,      0,      0,      0,
-/*  96: */        0,      1,      1,      1,      1,      1,      1,      1,
-/* 104: */        1,      1,      1,      1,      1,      1,      1,      1,
-/* 112: */        1,      1,      1,      1,      1,      1,      1,      1,
-/* 120: */        1,      1,      1,      0,      0,      0,      0,      0,
-/* 128: */        0,      0,      0,      0,      0,      0,      0,      0
+/*  00: */	0,	0,	0,	0,	0,	0,	0,	0,
+/*  08: */	0,	0,	0,	0,	0,	0,	0,	0,
+/*  10: */	0,	0,	0,	0,	0,	0,	0,	0,
+/*  18: */	0,	0,	0,	0,	0,	0,	0,	0,
+/*  20: */	0,	0,	0,	0,	0,	0,	0,	0,
+/*  28: */	0,	0,	0,	1,	0,	0,	0,	1,
+/*  30: */	1,	1,	1,	1,	1,	1,	1,	1,
+/*  38: */	1,	1,	0,	0,	0,	0,	0,	0,
+/*  40: */	0,	1,	1,	1,	1,	1,	1,	1,
+/*  48: */	1,	1,	1,	1,	1,	1,	1,	1,
+/*  50: */	1,	1,	1,	1,	1,	1,	1,	1,
+/*  58: */	1,	1,	1,	0,	0,	0,	0,	0,
+/*  60: */	0,	1,	1,	1,	1,	1,	1,	1,
+/*  68: */	1,	1,	1,	1,	1,	1,	1,	1,
+/*  70: */	1,	1,	1,	1,	1,	1,	1,	1,
+/*  78: */	1,	1,	1,	0,	0,	0,	0,	0,
 };
 
 enum {
    false = 0,
    true = 1
 } bool;
 
-int
-isatobchar(int c) { return b64[c] != 0; }
+#define isatobchar(c) (b64[c])
 
+#define MAX_STRING 8192
 
-#define MAX_STRING 256
 int
-getData(FILE *inFile,char **inString) {
-    int len = 0;
-    int space = MAX_STRING;
-    int oneequal = false;
-    int c;
-    char *string = (char *) malloc(space);
-
-    string[len++]='M';
-
-    while ((c = getc(inFile)) != EOF) {
-	if (len >= space) {
-	    char *newString;
+isBase64(char *inString) 
+{
+    unsigned int i;
+    unsigned char c;
 
-	    space *= 2;
-	    newString = (char *)realloc(string,space);
-	    if (newString == NULL) {
-		ungetc(c,inFile);
-		break;
-	    }
-	    string = newString;
-	}
-	string[len++] = c;
-	if (!isatobchar(c)) {
-	   if (c == '=') {
-		if (oneequal) {
-		    break;
-		}
-		oneequal = true;
-		continue;
-	   } else {
-	       ungetc(c,inFile);
-	       len--;
-	       break;
-	   }
-	}
-	if (oneequal) {
-	   ungetc(c,inFile);
-	   len--;
-	   break;
-	}
+    for (i = 0; (c = inString[i]) != 0 && isatobchar(c); ++i) 
+	;
+    if (c == '=') {
+	while ((c = inString[++i]) == '=')
+	    ; /* skip trailing '=' characters */
     }
-    if (len >= space) {
-	space += 2;
-	string = (char *)realloc(string,space);
-    }
-    string[len++] = 0;
-    *inString = string;
+    if (c && c != '\n' && c != '\r')
+	return false;
+    if (i == 0 || i % 4)
+    	return false;
     return true;
 }
 
+void
+doDecrypt(char * dataString, FILE *outFile, FILE *logFile, secuPWData *pwdata)
+{
+    int        strLen = strlen(dataString);
+    SECItem   *decoded = NSSBase64_DecodeBuffer(NULL, NULL, dataString, strLen);
+    SECStatus  rv;
+    int        err;
+    unsigned int i;
+    SECItem    result = { siBuffer, NULL, 0 };
+
+    if ((decoded == NULL) || (decoded->len == 0)) {
+	if (logFile) {
+	    err = PORT_GetError();
+	    fprintf(logFile,"Base 64 decode failed on <%s>\n", dataString);
+	    fprintf(logFile," Error %d: %s\n", err, SECU_Strerror(err));
+	}
+	fputs(dataString, outFile);
+	if (decoded)
+	    SECITEM_FreeItem(decoded, PR_TRUE);
+	return;
+    }
+
+    rv = PK11SDR_Decrypt(decoded, &result, pwdata);
+    SECITEM_ZfreeItem(decoded, PR_TRUE);
+    if (rv == SECSuccess) {
+	/* result buffer has no extra space for a NULL */
+	fprintf(outFile, "Decrypted: \"%.*s\"\n", result.len, result.data);
+	SECITEM_ZfreeItem(&result, PR_FALSE);
+	return;
+    }
+    /* Encryption failed. output raw input. */
+    if (logFile) {
+	err = PORT_GetError();
+	fprintf(logFile,"SDR decrypt failed on <%s>\n", dataString);
+	fprintf(logFile," Error %d: %s\n", err, SECU_Strerror(err));
+    }
+    fputs(dataString,outFile);
+}
+
+void
+doDecode(char * dataString, FILE *outFile, FILE *logFile)
+{
+    int        strLen = strlen(dataString + 1);
+    SECItem   *decoded;
+
+    decoded = NSSBase64_DecodeBuffer(NULL, NULL, dataString + 1, strLen);
+    if ((decoded == NULL) || (decoded->len == 0)) {
+	if (logFile) {
+	    int err = PORT_GetError();
+	    fprintf(logFile,"Base 64 decode failed on <%s>\n", dataString + 1);
+	    fprintf(logFile," Error %d: %s\n", err, SECU_Strerror(err));
+	}
+	fputs(dataString, outFile);
+	if (decoded)
+	    SECITEM_FreeItem(decoded, PR_TRUE);
+	return;
+    }
+    fprintf(outFile, "Decoded: \"%.*s\"\n", decoded->len, decoded->data);
+    SECITEM_ZfreeItem(decoded, PR_TRUE);
+}
+
+char dataString[MAX_STRING + 1];
+
 int
 main (int argc, char **argv)
 {
     int		 retval = 0;  /* 0 - test succeeded.  -1 - test failed */
     SECStatus	 rv;
     PLOptState	*optstate;
     char	*program_name;
     char  *input_file = NULL; 	/* read encrypted data from here (or create) */
     char  *output_file = NULL;	/* write new encrypted data here */
     char  *log_file = NULL;	/* write new encrypted data here */
     FILE	*inFile = stdin;
     FILE	*outFile = stdout;
     FILE	*logFile = NULL;
     PLOptStatus optstatus;
-    SECItem	result;
-    int		c;
     secuPWData  pwdata = { PW_NONE, NULL };
 
-    result.data = 0;
 
     program_name = PL_strrchr(argv[0], '/');
     program_name = program_name ? (program_name + 1) : argv[0];
 
     optstate = PL_CreateOptState (argc, argv, "Hd:f:i:o:l:p:?");
     if (optstate == NULL) {
 	SECU_PrintError (program_name, "PL_CreateOptState failed");
 	return 1;
@@ -265,110 +291,78 @@ main (int argc, char **argv)
     }
     PL_DestroyOptState(optstate);
     if (optstatus == PL_OPT_BAD) {
 	short_usage (program_name);
 	return 1;
     }
 
     if (input_file) {
-      inFile = fopen(input_file,"r");
-      if (inFile == NULL) {
-	perror(input_file);
-	return 1;
-      }
-      PR_Free(input_file);
+        inFile = fopen(input_file,"r");
+        if (inFile == NULL) {
+	    perror(input_file);
+	    return 1;
+        }
+        PR_Free(input_file);
     }
     if (output_file) {
-      outFile = fopen(output_file,"w+");
-      if (outFile == NULL) {
-	perror(output_file);
-	return 1;
-      }
-      PR_Free(output_file);
+        outFile = fopen(output_file,"w+");
+        if (outFile == NULL) {
+	    perror(output_file);
+	    return 1;
+        }
+        PR_Free(output_file);
     }
     if (log_file) {
-      logFile = fopen(log_file,"w+");
-      if (logFile == NULL) {
-	perror(log_file);
-	return 1;
-      }
-      PR_Free(log_file);
+	if (log_file[0] == '-')
+	    logFile = stderr;
+	else
+	    logFile = fopen(log_file,"w+");
+	if (logFile == NULL) {
+	    perror(log_file);
+	    return 1;
+	}
+        PR_Free(log_file);
     }
 
     /*
      * Initialize the Security libraries.
      */
     PK11_SetPasswordFunc(SECU_GetModulePassword);
     rv = NSS_Init(SECU_ConfigDirectory(NULL));
     if (rv != SECSuccess) {
 	SECU_PrintError (program_name, "NSS_Init failed");
 	retval = 1;
 	goto prdone;
     }
 
     /* Get the encrypted result, either from the input file
      * or from encrypting the plaintext value
      */
-
-    while ((c = getc(inFile)) != EOF) {
-	if (c == 'M') {
-	   char *dataString = NULL;
-	   SECItem *inText;
+    while (fgets(dataString, sizeof dataString, inFile)) {
+	unsigned char c = dataString[0];
 
-	   rv = getData(inFile, &dataString);
-	   if (!rv) {
-		fputs(dataString,outFile);
-		free(dataString);
-		continue;
-	   }
-	   inText = NSSBase64_DecodeBuffer(NULL, NULL, dataString,
-							strlen(dataString));
-	   if ((inText == NULL) || (inText->len == 0)) {
-		if (logFile) {
-		    fprintf(logFile,"Base 64 decode failed on <%s>\n",
-								dataString);
-		    fprintf(logFile," Error %x: %s\n",PORT_GetError(),
-			SECU_Strerror(PORT_GetError()));
-		}
-		fputs(dataString,outFile);
-		free(dataString);
-		continue;
-	   }
-	   result.data = NULL;
-	   result.len  = 0;
-	   rv = PK11SDR_Decrypt(inText, &result, &pwdata);
-	   SECITEM_FreeItem(inText, PR_TRUE);
-	   if (rv != SECSuccess) {
-		if (logFile) {
-		    fprintf(logFile,"SDR decrypt failed on <%s>\n",
-								dataString);
-		    fprintf(logFile," Error %x: %s\n",PORT_GetError(),
-			SECU_Strerror(PORT_GetError()));
-		}
-		fputs(dataString,outFile);
-		free(dataString);
-		SECITEM_ZfreeItem(&result, PR_FALSE);
-		continue;
-	   }
-	   /* result buffer has no extra space for a NULL */
-	   fprintf(outFile, "%.*s", result.len, result.data);
-	   SECITEM_ZfreeItem(&result, PR_FALSE);
-         } else {
-	   putc(c,outFile);
-         }
+	if (c == 'M' && isBase64(dataString)) {
+	    doDecrypt(dataString, outFile, logFile, &pwdata);
+        } else if (c == '~' && isBase64(dataString + 1)) {
+	    doDecode(dataString, outFile, logFile);
+	} else {
+	    fputs(dataString, outFile);
+	}
     }
+    if (pwdata.data)
+    	PR_Free(pwdata.data);
 
     fclose(outFile);
     fclose(inFile);
-    if (logFile) {
+    if (logFile && logFile != stderr) {
 	fclose(logFile);
     }
 
     if (NSS_Shutdown() != SECSuccess) {
 	SECU_PrintError (program_name, "NSS_Shutdown failed");
-       exit(1);
+        exit(1);
     }
 
 prdone:
     PR_Cleanup ();
     return retval;
 }
--- a/security/nss/cmd/shlibsign/Makefile
+++ b/security/nss/cmd/shlibsign/Makefile
@@ -75,17 +75,19 @@ EXTRA_SHARED_LIBS += \
 
 endif
 
 
 # sign any and all shared libraries that contain the word freebl
 
 CHECKLIBS = $(DIST)/lib/$(DLL_PREFIX)softokn3.$(DLL_SUFFIX)
 CHECKLIBS += $(wildcard $(DIST)/lib/$(DLL_PREFIX)freebl*3.$(DLL_SUFFIX))
+ifndef NSS_DISABLE_DBM
 CHECKLIBS += $(DIST)/lib/$(DLL_PREFIX)nssdbm3.$(DLL_SUFFIX)
+endif
 CHECKLOC = $(CHECKLIBS:.$(DLL_SUFFIX)=.chk)
 
 MD_LIB_RELEASE_FILES = $(CHECKLOC)
 ALL_TRASH += $(CHECKLOC)
 
 
 #######################################################################
 # (5) Execute "global" rules. (OPTIONAL)                              #
--- a/security/nss/lib/certdb/alg1485.c
+++ b/security/nss/lib/certdb/alg1485.c
@@ -1353,28 +1353,45 @@ appendStringToBuf(char *dest, char *src,
 	    dest[i] = tolower(src[i]);
 	dest[len] = 0;
 	dest        += len + 1;
 	*pRemaining -= len + 1;
     }
     return dest;
 }
 
+#undef NEEDS_HEX_ESCAPE
+#define NEEDS_HEX_ESCAPE(c) (c < 0x20)
+
 static char *
 appendItemToBuf(char *dest, SECItem *src, PRUint32 *pRemaining)
 {
-    if (dest && src && src->data && src->len && src->data[0] && 
-        *pRemaining > src->len + 1 ) {
+    if (dest && src && src->data && src->len && src->data[0]) {
 	PRUint32 len = src->len;
 	PRUint32 i;
-	for (i = 0; i < len && src->data[i] ; ++i)
-	    dest[i] = tolower(src->data[i]);
-	dest[len] = 0;
-	dest        += len + 1;
-	*pRemaining -= len + 1;
+	PRUint32 reqLen = len + 1;
+	/* are there any embedded control characters ? */
+	for (i = 0; i < len; i++) {
+	    if (NEEDS_HEX_ESCAPE(src->data[i]))
+	    	reqLen += 2;   
+	}
+	if (*pRemaining > reqLen) {
+	    for (i = 0; i < len; ++i) {
+		PRUint8 c = src->data[i];
+		if (NEEDS_HEX_ESCAPE(c)) {
+		    *dest++ = C_BACKSLASH;
+		    *dest++ = hexChars[ (c >> 4) & 0x0f ];
+		    *dest++ = hexChars[  c       & 0x0f ];
+		} else {
+		    *dest++ = tolower(c);
+	    	}
+	    }
+	    *dest++ = '\0';
+	    *pRemaining -= reqLen;
+	}
     }
     return dest;
 }
 
 /* Returns a pointer to an environment-like string, a series of 
 ** null-terminated strings, terminated by a zero-length string.
 ** This function is intended to be internal to NSS.
 */
--- a/security/nss/lib/certdb/certi.h
+++ b/security/nss/lib/certdb/certi.h
@@ -31,17 +31,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 /*
  * certi.h - private data structures for the certificate library
  *
- * $Id: certi.h,v 1.30 2009/04/18 05:15:45 alexei.volkov.bugs%sun.com Exp $
+ * $Id: certi.h,v 1.31 2009/07/31 18:35:30 christophe.ravel.bugs%sun.com Exp $
  */
 #ifndef _CERTI_H_
 #define _CERTI_H_
 
 #include "certt.h"
 #include "nssrwlkt.h"
 
 /*
@@ -363,17 +363,17 @@ struct NamedCRLCacheEntryStr {
     PRBool badDER;      /* ASN.1 error */
     PRBool dupe;        /* matching DER CRL already in CRL cache */
     PRBool unsupported; /* IDP, delta, any other reason */
 };
 
 typedef enum {
     certRevocationStatusRevoked = 0,
     certRevocationStatusValid = 1,
-    certRevocationStatusUnknown = 2,
+    certRevocationStatusUnknown = 2
 } CERTRevocationStatus;
 
 /* Returns detailed status of the cert(revStatus variable). Tells if
  * issuer cache has OriginFetchedWithTimeout crl in it. */
 SECStatus
 cert_CheckCertRevocationStatus(CERTCertificate* cert, CERTCertificate* issuer,
                                const SECItem* dp, PRTime t, void *wincx,
                                CERTRevocationStatus *revStatus,
--- a/security/nss/lib/certdb/crl.c
+++ b/security/nss/lib/certdb/crl.c
@@ -32,17 +32,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * Moved from secpkcs7.c
  *
- * $Id: crl.c,v 1.67 2009/05/13 22:47:28 julien.pierre.boogz%sun.com Exp $
+ * $Id: crl.c,v 1.68 2009/08/10 22:25:44 julien.pierre.boogz%sun.com Exp $
  */
  
 #include "cert.h"
 #include "certi.h"
 #include "secder.h"
 #include "secasn1.h"
 #include "secoid.h"
 #include "certdb.h"
@@ -1042,58 +1042,48 @@ void PreAllocator_Destroy(PreAllocator* 
     if (!PreAllocator)
     {
         return;
     }
     if (PreAllocator->arena)
     {
         PORT_FreeArena(PreAllocator->arena, PR_TRUE);
     }
-    if (PreAllocator->data)
-    {
-        PORT_Free(PreAllocator->data);
-    }
-    PORT_Free(PreAllocator);
 }
 
 /* constructor for PreAllocator object */
 PreAllocator* PreAllocator_Create(PRSize size)
 {
-    PreAllocator prebuffer;
-    PreAllocator* prepointer = NULL;
-    memset(&prebuffer, 0, sizeof(PreAllocator));
-    prebuffer.len = size;
-    prebuffer.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-    PORT_Assert(prebuffer.arena);
-    if (!prebuffer.arena)
+    PRArenaPool* arena = NULL;
+    PreAllocator* prebuffer = NULL;
+    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+    if (!arena)
     {
-        PreAllocator_Destroy(&prebuffer);
         return NULL;
     }
-    if (prebuffer.len)
+    prebuffer = (PreAllocator*)PORT_ArenaZAlloc(arena,
+                                                sizeof(PreAllocator));
+    if (!prebuffer)
     {
-        prebuffer.data = PORT_Alloc(prebuffer.len);
-        if (!prebuffer.data)
+        PORT_FreeArena(arena, PR_TRUE);
+        return NULL;
+    }
+    prebuffer->arena = arena;
+
+    if (size)
+    {
+        prebuffer->len = size;
+        prebuffer->data = PORT_ArenaAlloc(arena, size);
+        if (!prebuffer->data)
         {
-            PreAllocator_Destroy(&prebuffer);
+            PORT_FreeArena(arena, PR_TRUE);
             return NULL;
         }
     }
-    else
-    {
-        prebuffer.data = NULL;
-    }
-    prepointer = (PreAllocator*)PORT_Alloc(sizeof(PreAllocator));
-    if (!prepointer)
-    {
-        PreAllocator_Destroy(&prebuffer);
-        return NULL;
-    }
-    *prepointer = prebuffer;
-    return prepointer;
+    return prebuffer;
 }
 
 /* global Named CRL cache object */
 static NamedCRLCache namedCRLCache = { NULL, NULL };
 
 /* global CRL cache object */
 static CRLCache crlcache = { NULL, NULL };
 
--- a/security/nss/lib/ckfw/builtins/certdata.c
+++ b/security/nss/lib/ckfw/builtins/certdata.c
@@ -30,17 +30,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 #ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile: certdata.c,v $ $Revision: 1.54 $ $Date: 2009/05/21 19:50:27 $""; @(#) $RCSfile: certdata.c,v $ $Revision: 1.54 $ $Date: 2009/05/21 19:50:27 $";
+static const char CVS_ID[] = "@(#) $RCSfile: certdata.c,v $ $Revision: 1.55 $ $Date: 2009/08/13 23:40:29 $""; @(#) $RCSfile: certdata.c,v $ $Revision: 1.55 $ $Date: 2009/08/13 23:40:29 $";
 #endif /* DEBUG */
 
 #ifndef BUILTINS_H
 #include "builtins.h"
 #endif /* BUILTINS_H */
 
 static const CK_BBOOL ck_false = CK_FALSE;
 static const CK_BBOOL ck_true = CK_TRUE;
@@ -903,17 +903,17 @@ static const CK_ATTRIBUTE_TYPE nss_built
 #ifdef DEBUG
 static const NSSItem nss_builtins_items_0 [] = {
   { (void *)&cko_data, (PRUint32)sizeof(CK_OBJECT_CLASS) },
   { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) },
   { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) },
   { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) },
   { (void *)"CVS ID", (PRUint32)7 },
   { (void *)"NSS", (PRUint32)4 },
-  { (void *)"@(#) $RCSfile: certdata.c,v $ $Revision: 1.54 $ $Date: 2009/05/21 19:50:27 $""; @(#) $RCSfile: certdata.c,v $ $Revision: 1.54 $ $Date: 2009/05/21 19:50:27 $", (PRUint32)160 }
+  { (void *)"@(#) $RCSfile: certdata.c,v $ $Revision: 1.55 $ $Date: 2009/08/13 23:40:29 $""; @(#) $RCSfile: certdata.c,v $ $Revision: 1.55 $ $Date: 2009/08/13 23:40:29 $", (PRUint32)160 }
 };
 #endif /* DEBUG */
 static const NSSItem nss_builtins_items_1 [] = {
   { (void *)&cko_netscape_builtin_root_list, (PRUint32)sizeof(CK_OBJECT_CLASS) },
   { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) },
   { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) },
   { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) },
   { (void *)"Mozilla Builtin Roots", (PRUint32)22 }
@@ -17976,17 +17976,17 @@ static const NSSItem nss_builtins_items_
   { (void *)&ckt_netscape_trust_unknown, (PRUint32)sizeof(CK_TRUST) },
   { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }
 };
 static const NSSItem nss_builtins_items_266 [] = {
   { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) },
   { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) },
   { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) },
   { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) },
-  { (void *)"AC Ra+íz Certic+Ýmara S.A.", (PRUint32)27 },
+  { (void *)"AC Ra\xC3\xADz Certic\xC3\xA1mara S.A.", (PRUint32)39 },
   { (void *)&ckc_x_509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE) },
   { (void *)"\060\173\061\013\060\011\006\003\125\004\006\023\002\103\117\061"
 "\107\060\105\006\003\125\004\012\014\076\123\157\143\151\145\144"
 "\141\144\040\103\141\155\145\162\141\154\040\144\145\040\103\145"
 "\162\164\151\146\151\143\141\143\151\303\263\156\040\104\151\147"
 "\151\164\141\154\040\055\040\103\145\162\164\151\143\303\241\155"
 "\141\162\141\040\123\056\101\056\061\043\060\041\006\003\125\004"
 "\003\014\032\101\103\040\122\141\303\255\172\040\103\145\162\164"
@@ -18110,17 +18110,17 @@ static const NSSItem nss_builtins_items_
 "\005\211\374\170\326\134\054\046\103\251"
 , (PRUint32)1642 }
 };
 static const NSSItem nss_builtins_items_267 [] = {
   { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) },
   { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) },
   { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) },
   { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) },
-  { (void *)"AC Ra+íz Certic+Ýmara S.A.", (PRUint32)27 },
+  { (void *)"AC Ra\xC3\xADz Certic\xC3\xA1mara S.A.", (PRUint32)39 },
   { (void *)"\313\241\305\370\260\343\136\270\271\105\022\323\371\064\242\351"
 "\006\020\323\066"
 , (PRUint32)20 },
   { (void *)"\223\052\076\366\375\043\151\015\161\040\324\053\107\231\053\246"
 , (PRUint32)16 },
   { (void *)"\060\173\061\013\060\011\006\003\125\004\006\023\002\103\117\061"
 "\107\060\105\006\003\125\004\012\014\076\123\157\143\151\145\144"
 "\141\144\040\103\141\155\145\162\141\154\040\144\145\040\103\145"
--- a/security/nss/lib/ckfw/builtins/certdata.txt
+++ b/security/nss/lib/ckfw/builtins/certdata.txt
@@ -29,17 +29,17 @@
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
-CVS_ID "@(#) $RCSfile: certdata.txt,v $ $Revision: 1.53 $ $Date: 2009/05/21 19:50:28 $"
+CVS_ID "@(#) $RCSfile: certdata.txt,v $ $Revision: 1.54 $ $Date: 2009/08/13 23:40:29 $"
 
 #
 # certdata.txt
 #
 # This file contains the object definitions for the certs and other
 # information "built into" NSS.
 #
 # Object definitions:
@@ -18476,23 +18476,23 @@ CKA_SERIAL_NUMBER MULTILINE_OCTAL
 \002\011\000\376\334\343\001\017\311\110\377
 END
 CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR
 CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR
 CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_TRUST_UNKNOWN
 CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
 
 #
-# Certificate "AC Ra+íz Certic+Ýmara S.A."
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "AC Ra+íz Certic+Ýmara S.A."
+# Certificate "AC Ra\xC3\xADz Certic\xC3\xA1mara S.A."
+#
+CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
+CKA_TOKEN CK_BBOOL CK_TRUE
+CKA_PRIVATE CK_BBOOL CK_FALSE
+CKA_MODIFIABLE CK_BBOOL CK_FALSE
+CKA_LABEL UTF8 "AC Ra\xC3\xADz Certic\xC3\xA1mara S.A."
 CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
 CKA_SUBJECT MULTILINE_OCTAL
 \060\173\061\013\060\011\006\003\125\004\006\023\002\103\117\061
 \107\060\105\006\003\125\004\012\014\076\123\157\143\151\145\144
 \141\144\040\103\141\155\145\162\141\154\040\144\145\040\103\145
 \162\164\151\146\151\143\141\143\151\303\263\156\040\104\151\147
 \151\164\141\154\040\055\040\103\145\162\164\151\143\303\241\155
 \141\162\141\040\123\056\101\056\061\043\060\041\006\003\125\004
@@ -18615,22 +18615,22 @@ CKA_VALUE MULTILINE_OCTAL
 \147\100\136\154\010\121\137\064\132\214\226\150\315\327\367\211
 \302\034\323\062\000\257\122\313\323\140\133\052\072\107\176\153
 \060\063\241\142\051\177\112\271\341\055\347\024\043\016\016\030
 \107\341\171\374\025\125\320\261\374\045\161\143\165\063\034\043
 \053\257\134\331\355\107\167\140\016\073\017\036\322\300\334\144
 \005\211\374\170\326\134\054\046\103\251
 END
 
-# Trust for Certificate "AC Ra+íz Certic+Ýmara S.A."
-CKA_CLASS CK_OBJECT_CLASS CKO_NETSCAPE_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "AC Ra+íz Certic+Ýmara S.A."
+# Trust for Certificate "AC Ra\xC3\xADz Certic\xC3\xA1mara S.A."
+CKA_CLASS CK_OBJECT_CLASS CKO_NETSCAPE_TRUST
+CKA_TOKEN CK_BBOOL CK_TRUE
+CKA_PRIVATE CK_BBOOL CK_FALSE
+CKA_MODIFIABLE CK_BBOOL CK_FALSE
+CKA_LABEL UTF8 "AC Ra\xC3\xADz Certic\xC3\xA1mara S.A."
 CKA_CERT_SHA1_HASH MULTILINE_OCTAL
 \313\241\305\370\260\343\136\270\271\105\022\323\371\064\242\351
 \006\020\323\066
 END
 CKA_CERT_MD5_HASH MULTILINE_OCTAL
 \223\052\076\366\375\043\151\015\161\040\324\053\107\231\053\246
 END
 CKA_ISSUER MULTILINE_OCTAL
--- a/security/nss/lib/ckfw/capi/Makefile
+++ b/security/nss/lib/ckfw/capi/Makefile
@@ -29,17 +29,17 @@
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
-MAKEFILE_CVS_ID = "@(#) $RCSfile: Makefile,v $ $Revision: 1.5 $ $Date: 2007/05/09 00:09:37 $"
+MAKEFILE_CVS_ID = "@(#) $RCSfile: Makefile,v $ $Revision: 1.6 $ $Date: 2009/07/29 20:15:19 $"
 
 include manifest.mn
 include $(CORE_DEPTH)/coreconf/config.mk
 include config.mk
 
 EXTRA_LIBS = \
 	$(DIST)/lib/$(LIB_PREFIX)nssckfw.$(LIB_SUFFIX) \
 	$(DIST)/lib/$(LIB_PREFIX)nssb.$(LIB_SUFFIX) \
@@ -49,16 +49,19 @@ EXTRA_LIBS = \
 ifeq (,$(filter-out WIN%,$(OS_TARGET)))
 
 ifdef NS_USE_GCC
 EXTRA_LIBS += \
 	-L$(NSPR_LIB_DIR) \
 	-lplc4 \
 	-lplds4 \
 	-lnspr4 \
+	-lcrypt32 \
+	-ladvapi32 \
+	-lrpcrt4 \
 	$(NULL)
 else 
 EXTRA_SHARED_LIBS += \
         $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \
         $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \
         $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \
         crypt32.lib \
 	advapi32.lib \
--- a/security/nss/lib/ckfw/capi/cobject.c
+++ b/security/nss/lib/ckfw/capi/cobject.c
@@ -31,17 +31,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 #ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile: cobject.c,v $ $Revision: 1.5 $ $Date: 2009/02/25 18:37:49 $";
+static const char CVS_ID[] = "@(#) $RCSfile: cobject.c,v $ $Revision: 1.6 $ $Date: 2009/07/29 20:15:19 $";
 #endif /* DEBUG */
 
 #include "ckcapi.h"
 #include "nssbase.h"
 
 /*
  * ckcapi/cobject.c
  *
@@ -167,17 +167,17 @@ nss_ckcapi_DERUnwrap
 
     if (count+2 > size) {
       return start;
     }
     while (count-- > 0) {
       len = (len << 8) | (unsigned) *src++;
     }
   }
-  if (len + (src-start) > (unsigned int)size) {
+  if (len + ((unsigned char *)src-start) > (unsigned int)size) {
     return start;
   }
   if (next) {
     *next = src+len;
   }
   *outSize = len;
 
   return src;
--- a/security/nss/lib/libpkix/include/pkixt.h
+++ b/security/nss/lib/libpkix/include/pkixt.h
@@ -495,24 +495,24 @@ PKIX_Error* PKIX_ALLOC_ERROR(void);
 #define PKIX_KEY_USAGE_TIME_STAMP_OID          SEC_OID_EXT_KEY_USAGE_TIME_STAMP
 #define PKIX_KEY_USAGE_OCSP_RESPONDER_OID      SEC_OID_OCSP_RESPONDER
 
 
 /* Available revocation method types. */
 typedef enum PKIX_RevocationMethodTypeEnum {
     PKIX_RevocationMethod_CRL = 0,
     PKIX_RevocationMethod_OCSP,
-    PKIX_RevocationMethod_MAX,
+    PKIX_RevocationMethod_MAX
 } PKIX_RevocationMethodType;
 
 /* A set of statuses revocation checker operates on */
 typedef enum PKIX_RevocationStatusEnum {
     PKIX_RevStatus_NoInfo = 0,
     PKIX_RevStatus_Revoked,
-    PKIX_RevStatus_Success,
+    PKIX_RevStatus_Success
 } PKIX_RevocationStatus;
 
 
 #ifdef __cplusplus
 }
 #endif
 
 #endif /* _PKIXT_H */
--- a/security/nss/lib/libpkix/pkix/checker/pkix_ocspchecker.c
+++ b/security/nss/lib/libpkix/pkix/checker/pkix_ocspchecker.c
@@ -182,17 +182,17 @@ pkix_OcspChecker_CheckLocal(
             PKIX_PL_OcspCertID_Create(cert, NULL, &cid,
                                       plContext),
             PKIX_OCSPCERTIDCREATEFAILED);
         if (!cid) {
             goto cleanup;
         }
 
         PKIX_CHECK(
-            PKIX_PL_OcspCertID_GetFreshCacheStatus(cid, NULL,
+            PKIX_PL_OcspCertID_GetFreshCacheStatus(cid, date,
                                                    &hasFreshStatus,
                                                    &statusIsGood,
                                                    &resultCode,
                                                    plContext),
             PKIX_OCSPCERTIDGETFRESHCACHESTATUSFAILED);
         if (hasFreshStatus) {
             if (statusIsGood) {
                 revStatus = PKIX_RevStatus_Success;
@@ -316,17 +316,17 @@ pkix_OcspChecker_CheckExternal(
                	*pNBIOContext = nbioContext;
                 goto cleanup;
         }
         if (passed == PKIX_FALSE) {
                 goto cleanup;
         }
 
         PKIX_CHECK(
-            pkix_pl_OcspResponse_GetStatusForCert(cid, response,
+            pkix_pl_OcspResponse_GetStatusForCert(cid, response, date,
                                                   &passed, &resultCode,
                                                   plContext),
             PKIX_OCSPRESPONSEGETSTATUSFORCERTFAILED);
         if (passed == PKIX_FALSE) {
             revStatus = PKIX_RevStatus_Revoked;
         } else {
             revStatus = PKIX_RevStatus_Success;
         }
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.c
+++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.c
@@ -965,40 +965,50 @@ cleanup:
  *  Returns NULL if the function succeeds.
  *  Returns an OcspResponse Error if the function fails in a non-fatal way.
  *  Returns a Fatal Error if the function fails in an unrecoverable way.
  */
 PKIX_Error *
 pkix_pl_OcspResponse_GetStatusForCert(
         PKIX_PL_OcspCertID *cid,
         PKIX_PL_OcspResponse *response,
+        PKIX_PL_Date *validity,
         PKIX_Boolean *pPassed,
         SECErrorCodes *pReturnCode,
         void *plContext)
 {
+        PRTime time = 0;
         SECStatus rv = SECFailure;
         SECStatus rvCache;
         PRBool certIDWasConsumed = PR_FALSE;
 
         PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_GetStatusForCert");
         PKIX_NULLCHECK_THREE(response, pPassed, pReturnCode);
 
         /*
          * It is an error to call this function except following a successful
          * return from pkix_pl_OcspResponse_VerifySignature, which would have
          * set response->signerCert.
          */
         PKIX_NULLCHECK_TWO(response->signerCert, response->request);
         PKIX_NULLCHECK_TWO(cid, cid->certID);
 
+        if (validity != NULL) {
+            PKIX_Error *er = pkix_pl_Date_GetPRTime(validity, &time, plContext);
+            PKIX_DECREF(er);
+        }
+        if (!time) {
+            time = PR_Now();
+        }
+
         rv = cert_ProcessOCSPResponse(response->handle,
                                       response->nssOCSPResponse,
                                       cid->certID,
                                       response->signerCert,
-                                      PR_Now(),
+                                      time,
                                       &certIDWasConsumed,
                                       &rvCache);
         if (certIDWasConsumed) {
                 cid->certID = NULL;
         }
 
 	if (rv == SECSuccess) {
                 *pPassed = PKIX_TRUE;
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.h
+++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.h
@@ -108,16 +108,17 @@ pkix_pl_OcspResponse_VerifySignature(
         PKIX_Boolean *pPassed,
         void **pNBIOContext,
         void *plContext);
 
 PKIX_Error *
 pkix_pl_OcspResponse_GetStatusForCert(
         PKIX_PL_OcspCertID *cid,
         PKIX_PL_OcspResponse *response,
+        PKIX_PL_Date *validity,
         PKIX_Boolean *pPassed,
         SECErrorCodes *pReturnCode,
         void *plContext);
 
 PKIX_Error *
 PKIX_PL_OcspResponse_UseBuildChain(
         PKIX_PL_Cert *signerCert,
 	PKIX_PL_Date *producedAt,
--- a/security/nss/lib/nss/nss.def
+++ b/security/nss/lib/nss/nss.def
@@ -967,8 +967,15 @@ PK11_FindCertFromDERCertItem;
 ;+NSS_3.12.3 { 	# NSS 3.12.3 release
 ;+    global:
 CERT_CompareCerts;
 CERT_RegisterAlternateOCSPAIAInfoCallBack;
 PK11_GetSymKeyHandle;
 ;+    local:
 ;+       *;
 ;+};
+;+NSS_3.12.4 { 	# NSS 3.12.4 release
+;+    global:
+PK11_IsInternalKeySlot;
+SECMOD_OpenNewSlot;
+;+    local:
+;+       *;
+;+};
--- a/security/nss/lib/nss/nss.h
+++ b/security/nss/lib/nss/nss.h
@@ -31,17 +31,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: nss.h,v 1.67 2009/07/20 20:06:57 nelson%bolyard.com Exp $ */
+/* $Id: nss.h,v 1.69 2009/08/13 18:11:22 christophe.ravel.bugs%sun.com Exp $ */
 
 #ifndef __nss_h_
 #define __nss_h_
 
 /* The private macro _NSS_ECC_STRING is for NSS internal use only. */
 #ifdef NSS_ENABLE_ECC
 #ifdef NSS_ECC_MORE_THAN_SUITE_B
 #define _NSS_ECC_STRING " Extended ECC"
@@ -61,21 +61,21 @@
 
 /*
  * 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>][ <ECC>][ <Beta>]"
  */
-#define NSS_VERSION  "3.12.4.4" _NSS_ECC_STRING _NSS_CUSTOMIZED " Beta"
+#define NSS_VERSION  "3.12.4.5" _NSS_ECC_STRING _NSS_CUSTOMIZED
 #define NSS_VMAJOR   3
 #define NSS_VMINOR   12
 #define NSS_VPATCH   4
-#define NSS_BETA     PR_TRUE
+#define NSS_BETA     PR_FALSE
 
 #ifndef RC_INVOKED
 
 #include "seccomon.h"
 
 SEC_BEGIN_PROTOS
 
 /*
--- a/security/nss/lib/nss/nssinit.c
+++ b/security/nss/lib/nss/nssinit.c
@@ -31,17 +31,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: nssinit.c,v 1.98 2009/05/29 19:23:30 wtc%google.com Exp $ */
+/* $Id: nssinit.c,v 1.99 2009/07/23 01:56:40 nelson%bolyard.com Exp $ */
 
 #include <ctype.h>
 #include <string.h>
 #include "seccomon.h"
 #include "prinit.h"
 #include "prprf.h"
 #include "prmem.h"
 #include "cert.h"
@@ -769,16 +769,17 @@ NSS_RegisterShutdown(NSS_ShutdownFunc sF
     }
     if (nssShutdownList.allocatedFuncs == nssShutdownList.peakFuncs) {
 	struct NSSShutdownFuncPair *funcs = 
 		(struct NSSShutdownFuncPair *)PORT_Realloc
 		(nssShutdownList.funcs, 
 		(nssShutdownList.allocatedFuncs + NSS_SHUTDOWN_STEP) 
 		*sizeof(struct NSSShutdownFuncPair));
 	if (!funcs) {
+	    PZ_Unlock(nssShutdownList.lock);
 	    return SECFailure;
 	}
 	nssShutdownList.funcs = funcs;
 	nssShutdownList.allocatedFuncs += NSS_SHUTDOWN_STEP;
     }
     nssShutdownList.funcs[nssShutdownList.peakFuncs].func = sFunc;
     nssShutdownList.funcs[nssShutdownList.peakFuncs].appData = appData;
     nssShutdownList.peakFuncs++;
--- a/security/nss/lib/pk11wrap/pk11auth.c
+++ b/security/nss/lib/pk11wrap/pk11auth.c
@@ -478,20 +478,27 @@ SECStatus
 PK11_ChangePW(PK11SlotInfo *slot, const char *oldpw, const char *newpw)
 {
     CK_RV crv;
     SECStatus rv = SECFailure;
     int newLen;
     int oldLen;
     CK_SESSION_HANDLE rwsession;
 
-    if (newpw == NULL) newpw = "";
-    if (oldpw == NULL) oldpw = "";
-    newLen = PORT_Strlen(newpw);
-    oldLen = PORT_Strlen(oldpw);
+    /* use NULL values to trigger the protected authentication path */
+    if (slot->protectedAuthPath) {
+	if (newpw == NULL) newLen = 0;
+	if (oldpw == NULL) oldLen = 0;
+    } else {
+	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;
     }
 
--- a/security/nss/lib/pk11wrap/pk11pub.h
+++ b/security/nss/lib/pk11wrap/pk11pub.h
@@ -104,16 +104,17 @@ PK11SlotInfo *PK11_FindSlotByName(const 
  * more criteria : dllName, slotName and tokenName . In addition, if
  * presentOnly is set , only slots with a token inserted will be
  * returned.
  ******************************************************************/
 PK11SlotList *PK11_FindSlotsByNames(const char *dllName,
         const char* slotName, const char* tokenName, PRBool presentOnly);
 PRBool PK11_IsReadOnly(PK11SlotInfo *slot);
 PRBool PK11_IsInternal(PK11SlotInfo *slot);
+PRBool PK11_IsInternalKeySlot(PK11SlotInfo *slot);
 char * PK11_GetTokenName(PK11SlotInfo *slot);
 char * PK11_GetSlotName(PK11SlotInfo *slot);
 PRBool PK11_NeedLogin(PK11SlotInfo *slot);
 PRBool PK11_IsFriendly(PK11SlotInfo *slot);
 PRBool PK11_IsHW(PK11SlotInfo *slot);
 PRBool PK11_IsRemovable(PK11SlotInfo *slot);
 PRBool PK11_NeedUserInit(PK11SlotInfo *slot);
 PRBool PK11_ProtectedAuthenticationPath(PK11SlotInfo *slot);
@@ -233,16 +234,25 @@ int PK11_GetBestKeyLength(PK11SlotInfo *
  *              optimizeSpace - allocate smaller hash tables and lock tables.
  *                When this flag is not specified, Softoken will allocate
  *                large tables to prevent lock contention.
  */
 PK11SlotInfo *SECMOD_OpenUserDB(const char *moduleSpec);
 SECStatus SECMOD_CloseUserDB(PK11SlotInfo *slot);
 
 /*
+ * This is exactly the same as OpenUserDB except it can be called on any
+ * module that understands softoken style new slot entries. The resulting
+ * slot can be closed using SECMOD_CloseUserDB above. Value of moduleSpec
+ * is token specific.
+ */
+PK11SlotInfo *SECMOD_OpenNewSlot(SECMODModule *mod, const char *moduleSpec);
+
+
+/*
  * merge the permanent objects from on token to another 
  */
 SECStatus PK11_MergeTokens(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
                 PK11MergeLog *log, void *targetPwArg, void *sourcePwArg);
 
 /*
  * create and destroy merge logs needed by PK11_MergeTokens
  */
--- a/security/nss/lib/pk11wrap/pk11slot.c
+++ b/security/nss/lib/pk11wrap/pk11slot.c
@@ -1534,16 +1534,32 @@ PK11_IsRemovable(PK11SlotInfo *slot)
 
 PRBool
 PK11_IsInternal(PK11SlotInfo *slot)
 {
     return slot->isInternal;
 }
 
 PRBool
+PK11_IsInternalKeySlot(PK11SlotInfo *slot)
+{
+    PK11SlotInfo *int_slot;
+    PRBool result;
+
+    if (!slot->isInternal) {
+	return PR_FALSE;
+    }
+
+    int_slot = PK11_GetInternalKeySlot();
+    result = (int_slot == slot) ? PR_TRUE : PR_FALSE;
+    PK11_FreeSlot(int_slot);
+    return result;
+}
+
+PRBool
 PK11_NeedLogin(PK11SlotInfo *slot)
 {
     return slot->needLogin;
 }
 
 PRBool
 PK11_IsFriendly(PK11SlotInfo *slot)
 {
--- a/security/nss/lib/pk11wrap/pk11util.c
+++ b/security/nss/lib/pk11wrap/pk11util.c
@@ -1243,45 +1243,41 @@ SECMOD_HasRemovableSlots(SECMODModule *m
     SECMOD_ReleaseReadLock(moduleLock);
     return ret;
 }
 
 /*
  * helper function to actually create and destroy user defined slots
  */
 static SECStatus
-secmod_UserDBOp(CK_OBJECT_CLASS objClass, const char *sendSpec)
+secmod_UserDBOp(PK11SlotInfo *slot, CK_OBJECT_CLASS objClass, 
+		const char *sendSpec)
 {
-    PK11SlotInfo *slot = PK11_GetInternalSlot();
     CK_OBJECT_HANDLE dummy;
     CK_ATTRIBUTE template[2] ;
     CK_ATTRIBUTE *attrs = template;
-    SECStatus rv;
     CK_RV crv;
 
     PK11_SETATTRS(attrs, CKA_CLASS, &objClass, sizeof(objClass)); attrs++;
     PK11_SETATTRS(attrs, CKA_NETSCAPE_MODULE_SPEC , (unsigned char *)sendSpec,
 					 strlen(sendSpec)+1); attrs++;
 
     PORT_Assert(attrs-template <= 2);
 
 
     PK11_EnterSlotMonitor(slot);
     crv = PK11_CreateNewObject(slot, slot->session,
 	template, attrs-template, PR_FALSE, &dummy);
     PK11_ExitSlotMonitor(slot);
 
     if (crv != CKR_OK) {
-	PK11_FreeSlot(slot);
 	PORT_SetError(PK11_MapError(crv));
 	return SECFailure;
     }
-    rv = SECMOD_UpdateSlotList(slot->module);
-    PK11_FreeSlot(slot);
-    return rv;
+    return SECMOD_UpdateSlotList(slot->module);
 }
 
 /*
  * add escapes to protect quote characters...
  */
 static char *
 nss_addEscape(const char *string, char quote)
 {
@@ -1327,16 +1323,122 @@ nss_doubleEscape(const char *string)
 done:
     if (retValue == NULL) {
         retValue = PORT_Strdup("");
     }
     return retValue;
 }
 
 /*
+ * return true if the selected slot ID is not present or doesn't exist
+ */
+static PRBool
+secmod_SlotIsEmpty(SECMODModule *mod,  CK_SLOT_ID slotID)
+{
+    PK11SlotInfo *slot = SECMOD_LookupSlot(mod->moduleID, slotID);
+    if (slot) {
+	PRBool present = PK11_IsPresent(slot);
+	PK11_FreeSlot(slot);
+	if (present) {
+	    return PR_FALSE;
+	}
+    }
+    /* it doesn't exist or isn't present, it's available */
+    return PR_TRUE;
+}
+
+/*
+ * Find an unused slot id in module.
+ */
+static CK_SLOT_ID
+secmod_FindFreeSlot(SECMODModule *mod)
+{
+    CK_SLOT_ID i, minSlotID, maxSlotID;
+
+    /* look for a free slot id on the internal module */
+    if (mod->internal && mod->isFIPS) {
+	minSlotID = SFTK_MIN_FIPS_USER_SLOT_ID;
+	maxSlotID = SFTK_MAX_FIPS_USER_SLOT_ID;
+    } else {
+	minSlotID = SFTK_MIN_USER_SLOT_ID;
+	maxSlotID = SFTK_MAX_USER_SLOT_ID;
+    }
+    for (i=minSlotID; i < maxSlotID; i++) {
+	if (secmod_SlotIsEmpty(mod,i)) {
+	    return i;
+	}
+    }
+    PORT_SetError(SEC_ERROR_NO_SLOT_SELECTED);
+    return (CK_SLOT_ID) -1;
+}
+
+/*
+ * Attempt to open a new slot.
+ *
+ * This works the same os OpenUserDB except it can be called against
+ * any module that understands the softoken protocol for opening new
+ * slots, not just the softoken itself. If the selected module does not
+ * understand the protocol, C_CreateObject will fail with 
+ * CKR_INVALID_ATTRIBUTE, and SECMOD_OpenNewSlot will return NULL and set
+ * SEC_ERROR_BAD_DATA.
+ * 
+ * NewSlots can be closed with SECMOD_CloseUserDB();
+ *
+ * Modulespec is module dependent.
+ */
+PK11SlotInfo *
+SECMOD_OpenNewSlot(SECMODModule *mod, const char *moduleSpec)
+{
+    CK_SLOT_ID slotID = 0;
+    PK11SlotInfo *slot;
+    char *escSpec;
+    char *sendSpec;
+    SECStatus rv;
+
+    slotID = secmod_FindFreeSlot(mod);
+    if (slotID == (CK_SLOT_ID) -1) {
+	return NULL;
+    }
+
+    if (mod->slotCount == 0) {
+	return NULL;
+    }
+
+    /* just grab the first slot in the module, any present slot should work */
+    slot = PK11_ReferenceSlot(mod->slots[0]);
+    if (slot == NULL) {
+	return NULL;
+    }
+
+    /* we've found the slot, now build the moduleSpec */
+    escSpec = nss_doubleEscape(moduleSpec);
+    if (escSpec == NULL) {
+	PK11_FreeSlot(slot);
+	return NULL;
+    }
+    sendSpec = PR_smprintf("tokens=[0x%x=<%s>]", slotID, escSpec);
+    PORT_Free(escSpec);
+
+    if (sendSpec == NULL) {
+	/* PR_smprintf does not set SEC_ERROR_NO_MEMORY on failure. */
+	PK11_FreeSlot(slot);
+	PORT_SetError(SEC_ERROR_NO_MEMORY);
+	return NULL;
+    }
+    rv = secmod_UserDBOp(slot, CKO_NETSCAPE_NEWSLOT, sendSpec);
+    PR_smprintf_free(sendSpec);
+    PK11_FreeSlot(slot);
+    if (rv != SECSuccess) {
+	return NULL;
+    }
+
+    return SECMOD_FindSlotByID(mod, slotID);
+}
+
+/*
  * Open a new database using the softoken. The caller is responsible for making
  * sure the module spec is correct and usable. The caller should ask for one
  * new database per call if the caller wants to get meaningful information 
  * about the new database.
  *
  * moduleSpec is the same data that you would pass to softoken at 
  * initialization time under the 'tokens' options. For example, if you were
  * to specify tokens=<0x4=[configdir='./mybackup' tokenDescription='Backup']>
@@ -1378,109 +1480,48 @@ done:
  *                (valid only if there is a keyDB).
  *              optimizeSpace - allocate smaller hash tables and lock tables.
  *                When this flag is not specified, Softoken will allocate 
  *                large tables to prevent lock contention. 
  */
 PK11SlotInfo *
 SECMOD_OpenUserDB(const char *moduleSpec)
 {
-    CK_SLOT_ID slotID = 0;
-    char *escSpec;
-    char *sendSpec;
-    SECStatus rv;
     SECMODModule *mod;
-    CK_SLOT_ID i, minSlotID, maxSlotID;
-    PRBool found = PR_FALSE;
 
     if (moduleSpec == NULL) {
 	return NULL;
     }
 
     /* NOTE: unlike most PK11 function, this does not return a reference
      * to the module */
     mod = SECMOD_GetInternalModule();
     if (!mod) {
 	/* shouldn't happen */
 	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
 	return NULL;
     }
-
-    /* look for a free slot id on the internal module */
-    if (mod->isFIPS) {
-	minSlotID = SFTK_MIN_FIPS_USER_SLOT_ID;
-	maxSlotID = SFTK_MAX_FIPS_USER_SLOT_ID;
-    } else {
-	minSlotID = SFTK_MIN_USER_SLOT_ID;
-	maxSlotID = SFTK_MAX_USER_SLOT_ID;
-    }
-    for (i=minSlotID; i < maxSlotID; i++) {
-	PK11SlotInfo *slot = SECMOD_LookupSlot(mod->moduleID, i);
-	if (slot) {
-	    PRBool present = PK11_IsPresent(slot);
-	    PK11_FreeSlot(slot);
-	    if (present) {
-		continue;
-	    }
-	    /* not present means it's available */
-	}
-	/* it doesn't exist or isn't present, it's available */
-	slotID = i;
-	found = PR_TRUE;
-	break;
-    }
+    return SECMOD_OpenNewSlot(mod, moduleSpec);
+}
 
-    if (!found) {
-	/* this could happen if we try to open too many slots */
-	PORT_SetError(SEC_ERROR_NO_SLOT_SELECTED);
-	return NULL;
-    }
-
-    /* we've found the slot, now build the moduleSpec */
-
-    escSpec = nss_doubleEscape(moduleSpec);
-    if (escSpec == NULL) {
-	return NULL;
-    }
-    sendSpec = PR_smprintf("tokens=[0x%x=<%s>]", slotID, escSpec);
-    PORT_Free(escSpec);
-
-    if (sendSpec == NULL) {
-	/* PR_smprintf does not set no memory error */
-	PORT_SetError(SEC_ERROR_NO_MEMORY);
-	return NULL;
-    }
-    rv = secmod_UserDBOp(CKO_NETSCAPE_NEWSLOT, sendSpec);
-    PR_smprintf_free(sendSpec);
-    if (rv != SECSuccess) {
-	return NULL;
-    }
-
-    return SECMOD_FindSlotByID(mod, slotID);
-}
 
 /*
  * close an already opened user database. NOTE: the database must be
  * in the internal token, and must be one created with SECMOD_OpenUserDB().
  * Once the database is closed, the slot will remain as an empty slot
- * until it's used again with SECMOD_OpenUserDB().
+ * until it's used again with SECMOD_OpenUserDB() or SECMOD_OpenNewSlot().
  */
 SECStatus
 SECMOD_CloseUserDB(PK11SlotInfo *slot)
 {
     SECStatus rv;
     char *sendSpec;
-
-    if (!slot->isInternal) {
-	PORT_SetError(SEC_ERROR_INVALID_ARGS);
-	return SECFailure;
-    }
     
     sendSpec = PR_smprintf("tokens=[0x%x=<>]", slot->slotID);
     if (sendSpec == NULL) {
 	/* PR_smprintf does not set no memory error */
 	PORT_SetError(SEC_ERROR_NO_MEMORY);
 	return SECFailure;
     }
-    rv = secmod_UserDBOp(CKO_NETSCAPE_DELSLOT, sendSpec);
+    rv = secmod_UserDBOp(slot, CKO_NETSCAPE_DELSLOT, sendSpec);
     PR_smprintf_free(sendSpec);
     return rv;
 }
--- a/security/nss/lib/pki/pki3hack.c
+++ b/security/nss/lib/pki/pki3hack.c
@@ -30,17 +30,17 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.96 $ $Date: 2008/08/09 01:26:05 $";
+static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.97 $ $Date: 2009/07/30 22:43:32 $";
 #endif /* DEBUG */
 
 /*
  * Hacks to integrate NSS 3.4 and NSS 4.0 certificates.
  */
 
 #ifndef NSSPKI_H
 #include "nsspki.h"
@@ -663,17 +663,17 @@ STAN_GetCERTCertificateNameForInstance (
 
     if (instance) {
 	stanNick = instance->label;
     } else if (context) {
 	stanNick = c->object.tempName;
     }
     if (stanNick) {
 	/* fill other fields needed by NSS3 functions using CERTCertificate */
-	if (instance && (!PK11_IsInternal(instance->token->pk11slot) || 
+	if (instance && (!PK11_IsInternalKeySlot(instance->token->pk11slot) || 
 	                 PORT_Strchr(stanNick, ':') != NULL) ) {
 	    tokenName = nssToken_GetName(instance->token);
 	    tokenlen = nssUTF8_Size(tokenName, &nssrv);
 	} else {
 	/* don't use token name for internal slot; 3.3 didn't */
 	    tokenlen = 0;
 	}
 	nicklen = nssUTF8_Size(stanNick, &nssrv);
@@ -729,17 +729,17 @@ fill_CERTCertificateFields(NSSCertificat
     }
     /* fill other fields needed by NSS3 functions using CERTCertificate */
     if ((!cc->nickname && stanNick) || forced) {
 	PRStatus nssrv;
 	int nicklen, tokenlen, len;
 	NSSUTF8 *tokenName = NULL;
 	char *nick;
 	if (instance && 
-	     (!PK11_IsInternal(instance->token->pk11slot) || 
+	     (!PK11_IsInternalKeySlot(instance->token->pk11slot) || 
 	      (stanNick && PORT_Strchr(stanNick, ':') != NULL))) {
 	    tokenName = nssToken_GetName(instance->token);
 	    tokenlen = nssUTF8_Size(tokenName, &nssrv);
 	} else {
 	    /* don't use token name for internal slot; 3.3 didn't */
 	    tokenlen = 0;
 	}
 	if (stanNick) {
@@ -1156,17 +1156,17 @@ STAN_ChangeCertTrust(CERTCertificate *cc
 	                                   &c->issuer, &c->serial,
 	                                   nssTrust->serverAuth,
 	                                   nssTrust->clientAuth,
 	                                   nssTrust->codeSigning,
 	                                   nssTrust->emailProtection,
 	                                   nssTrust->stepUpApproved, PR_TRUE);
 	/* If the selected token can't handle trust, dump the trust on 
 	 * the internal token */
-	if (!newInstance && !PK11_IsInternal(tok->pk11slot)) {
+	if (!newInstance && !PK11_IsInternalKeySlot(tok->pk11slot)) {
 	    PK11SlotInfo *slot = PK11_GetInternalKeySlot();
 	    NSSUTF8 *nickname = nssCertificate_GetNickname(c, NULL);
 	    NSSASCII7 *email = c->email;
 	    tok = PK11Slot_GetNSSToken(slot);
 	    PK11_FreeSlot(slot);
 	
 	    newInstance = nssToken_ImportCertificate(tok, NULL,
 	                                             NSSCertificateType_PKIX,
--- a/security/nss/lib/softoken/softkver.h
+++ b/security/nss/lib/softoken/softkver.h
@@ -52,15 +52,15 @@
 
 /*
  * Softoken'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>][ <ECC>][ <Beta>]"
  */
-#define SOFTOKEN_VERSION  "3.12.4.4" SOFTOKEN_ECC_STRING
+#define SOFTOKEN_VERSION  "3.12.4.5" SOFTOKEN_ECC_STRING
 #define SOFTOKEN_VMAJOR   3
 #define SOFTOKEN_VMINOR   12
 #define SOFTOKEN_VPATCH   4
 #define SOFTOKEN_BETA     PR_FALSE
 
 #endif /* _SOFTKVER_H_ */
--- a/security/nss/lib/softoken/softoknt.h
+++ b/security/nss/lib/softoken/softoknt.h
@@ -31,17 +31,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: softoknt.h,v 1.5 2009/01/27 23:13:21 rrelyea%redhat.com Exp $ */
+/* $Id: softoknt.h,v 1.6 2009/08/03 16:58:28 christophe.ravel.bugs%sun.com Exp $ */
 
 #ifndef _SOFTOKNT_H_
 #define _SOFTOKNT_H_
 
 /*
  * RSA block types
  *
  * The actual values are important -- they are fixed, *not* arbitrary.
@@ -83,12 +83,12 @@ typedef enum {
     NSS_AUDIT_INIT_PIN,
     NSS_AUDIT_INIT_TOKEN,
     NSS_AUDIT_LOAD_KEY,
     NSS_AUDIT_LOGIN,
     NSS_AUDIT_LOGOUT,
     NSS_AUDIT_SELF_TEST,
     NSS_AUDIT_SET_PIN,
     NSS_AUDIT_UNWRAP_KEY,
-    NSS_AUDIT_WRAP_KEY,
+    NSS_AUDIT_WRAP_KEY
 } NSSAuditType;
 
 #endif /* _SOFTOKNT_H_ */
--- a/security/nss/lib/util/nssutil.h
+++ b/security/nss/lib/util/nssutil.h
@@ -46,15 +46,15 @@
 
 /*
  * NSS utilities'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 NSSUTIL_VERSION  "3.12.4.4 Beta"
+#define NSSUTIL_VERSION  "3.12.4.5"
 #define NSSUTIL_VMAJOR   3
 #define NSSUTIL_VMINOR   12
 #define NSSUTIL_VPATCH   4
-#define NSSUTIL_BETA     PR_TRUE
+#define NSSUTIL_BETA     PR_FALSE
 
 #endif /* __nssutil_h_ */
--- a/security/nss/lib/util/portreg.c
+++ b/security/nss/lib/util/portreg.c
@@ -14,17 +14,19 @@
  * The Original Code is the Netscape security libraries.
  *
  * The Initial Developer of the Original Code is
  * Netscape Communications Corporation.
  * Portions created by the Initial Developer are Copyright (C) 1994-2000
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
+ *      Rob McCool  (original author)
  * 	Ken Key <key+mozilla@ksquared.net>
+ *      Nelson Bolyard <nelson@bolyard.me>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -33,264 +35,353 @@
  * 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 ***** */
 
 /* 
  * shexp.c: shell-like wildcard match routines
  *
- *
  * See shexp.h for public documentation.
- *
  */
 
 #include "seccomon.h"
 #include "portreg.h"
 
 /* ----------------------------- shexp_valid ------------------------------ */
 
 
 static int 
-_valid_subexp(const char *exp, char stop) 
+_valid_subexp(const char *exp, char stop1, char stop2) 
 {
-    register int x,y,t;
-    int nsc,np,tld;
-
-    x=0;nsc=0;tld=0;
+    register int x;
+    int nsc = 0;     /* Number of special characters */
+    int np;          /* Number of pipe characters in union */
+    int tld = 0;     /* Number of tilde characters */
 
-    while(exp[x] && (exp[x] != stop)) {
+    for (x = 0; exp[x] && (exp[x] != stop1) && (exp[x] != stop2); ++x) {
         switch(exp[x]) {
-          case '~':
-            if(tld) return INVALID_SXP;
-            else ++tld;
-          case '*':
-          case '?':
-          case '^':
-          case '$':
+	case '~':
+            if(tld)                 /* at most one exclusion */
+                return INVALID_SXP;
+            if (stop1)              /* no exclusions within unions */
+                return INVALID_SXP;
+            if (!exp[x+1])          /* exclusion cannot be last character */
+                return INVALID_SXP;
+            if (!x)                 /* exclusion cannot be first character */
+                return INVALID_SXP;
+            ++tld;
+	    /* fall through */
+	case '*':
+	case '?':
+	case '$':
             ++nsc;
             break;
-          case '[':
+	case '[':
             ++nsc;
             if((!exp[++x]) || (exp[x] == ']'))
                 return INVALID_SXP;
-            for(++x;exp[x] && (exp[x] != ']');++x)
-                if(exp[x] == '\\')
-                    if(!exp[++x])
-                        return INVALID_SXP;
+            for(; exp[x] && (exp[x] != ']'); ++x) {
+                if(exp[x] == '\\' && !exp[++x])
+                    return INVALID_SXP;
+            }
             if(!exp[x])
                 return INVALID_SXP;
             break;
-          case '(':
-            ++nsc;np = 0;
-            while(1) {
-                if(exp[++x] == ')')
-                    return INVALID_SXP;
-                for(y=x;(exp[y]) && (exp[y] != '|') && (exp[y] != ')');++y)
-                    if(exp[y] == '\\')
-                        if(!exp[++y])
-                            return INVALID_SXP;
-                if(!exp[y])
-                    return INVALID_SXP;
-                if(exp[y] == '|')
-                    ++np;
-                t = _valid_subexp(&exp[x],exp[y]);
-                if(t == INVALID_SXP)
+	case '(':
+            ++nsc;
+	    if (stop1)			/* no nested unions */
+		return INVALID_SXP;
+            np = -1;
+            do {
+                int t = _valid_subexp(&exp[++x], ')', '|');
+                if(t == 0 || t == INVALID_SXP)
                     return INVALID_SXP;
                 x+=t;
-                if(exp[x] == ')') {
-                    if(!np)
-                        return INVALID_SXP;
-                    break;
-                }
-            }
+		if(!exp[x])
+		    return INVALID_SXP;
+		++np;
+            } while (exp[x] == '|' );
+	    if(np < 1)  /* must be at least one pipe */
+		return INVALID_SXP;
             break;
-          case ')':
-          case ']':
+	case ')':
+	case '|':
+	case ']':
             return INVALID_SXP;
-          case '\\':
+	case '\\':
+	    ++nsc;
             if(!exp[++x])
                 return INVALID_SXP;
-          default:
+            break;
+	default:
             break;
         }
-        ++x;
     }
-    if((!stop) && (!nsc))
+    if((!stop1) && (!nsc)) /* must be at least one special character */
         return NON_SXP;
-    return ((exp[x] == stop) ? x : INVALID_SXP);
+    return ((exp[x] == stop1 || exp[x] == stop2) ? x : INVALID_SXP);
 }
 
 int 
 PORT_RegExpValid(const char *exp) 
 {
     int x;
 
-    x = _valid_subexp(exp, '\0');
+    x = _valid_subexp(exp, '\0', '\0');
     return (x < 0 ? x : VALID_SXP);
 }
 
 
 /* ----------------------------- shexp_match ----------------------------- */
 
 
 #define MATCH 0
 #define NOMATCH 1
 #define ABORTED -1
 
-static int _shexp_match(const char *str, const char *exp, PRBool case_insensitive);
-
 static int 
-_handle_union(const char *str, const char *exp, PRBool case_insensitive) 
+_shexp_match(const char *str, const char *exp, PRBool case_insensitive,
+             unsigned int level);
+
+/* Count characters until we reach a NUL character or either of the 
+ * two delimiter characters, stop1 or stop2.  If we encounter a bracketed 
+ * expression, look only for NUL or ']' inside it.  Do not look for stop1 
+ * or stop2 inside it. Return ABORTED if bracketed expression is unterminated.
+ * Handle all escaping.
+ * Return index in input string of first stop found, or ABORTED if not found.
+ * If "dest" is non-NULL, copy counted characters to it and NUL terminate.
+ */
+static int 
+_scan_and_copy(const char *exp, char stop1, char stop2, char *dest)
 {
-    char *e2 = (char *) PORT_Alloc(sizeof(char)*strlen(exp));
-    register int t,p2,p1 = 1;
-    int cp;
+    register int sx;     /* source index */
+    register char cc;
 
-    while(1) {
-        for(cp=1;exp[cp] != ')';cp++)
-            if(exp[cp] == '\\')
-                ++cp;
-        for(p2 = 0;(exp[p1] != '|') && (p1 != cp);p1++,p2++) {
-            if(exp[p1] == '\\')
-                e2[p2++] = exp[p1++];
-            e2[p2] = exp[p1];
-        }
-        for (t=cp+1; ((e2[p2] = exp[t]) != 0); ++t,++p2) {}
-        if(_shexp_match(str,e2, case_insensitive) == MATCH) {
-            PORT_Free(e2);
-            return MATCH;
-        }
-        if(p1 == cp) {
-            PORT_Free(e2);
-            return NOMATCH;
-        }
-        else ++p1;
+    for (sx = 0; (cc = exp[sx]) && cc != stop1 && cc != stop2; sx++) {
+	if (cc == '\\') {
+	    if (!exp[++sx])
+		return ABORTED; /* should be impossible */
+	} else if (cc == '[') {
+	    while ((cc = exp[++sx]) && cc != ']') {
+		if(cc == '\\' && !exp[++sx])
+		    return ABORTED;
+	    }
+	    if (!cc) 
+		return ABORTED; /* should be impossible */
+	}
     }
+    if (dest && sx) {
+	/* Copy all but the closing delimiter. */
+	memcpy(dest, exp, sx);
+	dest[sx] = 0;
+    }
+    return cc ? sx : ABORTED; /* index of closing delimiter */
 }
 
-
+/* On input, exp[0] is the opening parenthesis of a union.
+ * See if any of the alternatives in the union matches as a pattern.
+ * The strategy is to take each of the alternatives, in turn, and append
+ * the rest of the expression (after the closing ')' that marks the end of 
+ * this union) to that alternative, and then see if the resultant expression
+ * matches the input string.  Repeat this until some alternative matches, 
+ * or we have an abort. 
+ */
 static int 
-_shexp_match(const char *str, const char *exp, PRBool case_insensitive) 
+_handle_union(const char *str, const char *exp, PRBool case_insensitive,
+              unsigned int level) 
 {
-    register int x,y;
-    int ret,neg;
+    register int sx;     /* source index */
+    int cp;              /* source index of closing parenthesis */
+    int count;
+    int ret   = NOMATCH;
+    char *e2;
 
-    ret = 0;
-    for(x=0,y=0;exp[y];++y,++x) {
-        if((!str[x]) && (exp[y] != '(') && (exp[y] != '$') && (exp[y] != '*'))
-            ret = ABORTED;
-        else {
-            switch(exp[y]) {
-              case '$':
-                if( (str[x]) )
-                    ret = NOMATCH;
-                else
-                    --x;             /* we don't want loop to increment x */
-                break;
-              case '*':
-                while(exp[++y] == '*'){}
-                if(!exp[y])
-                    return MATCH;
-                while(str[x]) {
-                    switch(_shexp_match(&str[x++],&exp[y], case_insensitive)) {
-                    case NOMATCH:
-                        continue;
-                    case ABORTED:
-                        ret = ABORTED;
-                        break;
-                    default:
-                        return MATCH;
-                    }
-                    break;
-                }
-                if((exp[y] == '$') && (exp[y+1] == '\0') && (!str[x]))
-                    return MATCH;
-                else
-                    ret = ABORTED;
-                break;
-              case '[':
-              	neg = ((exp[++y] == '^') && (exp[y+1] != ']'));
-                if (neg)
-                    ++y;
-                
-                if ((isalnum(exp[y])) && (exp[y+1] == '-') && 
-                   (isalnum(exp[y+2])) && (exp[y+3] == ']'))
-                    {
-                        int start = exp[y], end = exp[y+2];
-                        
-                        /* no safeguards here */
-                        if(neg ^ ((str[x] < start) || (str[x] > end))) {
-                            ret = NOMATCH;
-                            break;
-                        }
-                        y+=3;
-                    }
-                else {
-                    int matched;
-                    
-                    for (matched=0;exp[y] != ']';y++)
-                        matched |= (str[x] == exp[y]);
-                    if (neg ^ (!matched))
-                        ret = NOMATCH;
-                }
-                break;
-              case '(':
-                return _handle_union(&str[x],&exp[y], case_insensitive);
-                break;
-              case '?':
-                break;
-              case '\\':
-                ++y;
-              default:
-		if(case_insensitive)
-		  {
-                    if(toupper(str[x]) != toupper(exp[y]))
-                        ret = NOMATCH;
-		  }
-		else
-		  {
-                    if(str[x] != exp[y])
-                        ret = NOMATCH;
-		  }
-                break;
-            }
-        }
-        if(ret)
+    /* Find the closing parenthesis that ends this union in the expression */
+    cp = _scan_and_copy(exp, ')', '\0', NULL);
+    if (cp == ABORTED || cp < 4) /* must be at least "(a|b" before ')' */
+    	return ABORTED;
+    ++cp;                /* now index of char after closing parenthesis */
+    e2 = (char *) PORT_Alloc(1 + strlen(exp));
+    if (!e2)
+    	return ABORTED;
+    for (sx = 1; ; ++sx) {
+	/* Here, exp[sx] is one character past the preceeding '(' or '|'. */
+	/* Copy everything up to the next delimiter to e2 */
+	count = _scan_and_copy(exp + sx, ')', '|', e2);
+	if (count == ABORTED || !count) {
+	    ret = ABORTED;
+	    break;
+	}
+	sx += count;
+	/* Append everything after closing parenthesis to e2. This is safe. */
+	strcpy(e2+count, exp+cp);
+        ret = _shexp_match(str, e2, case_insensitive, level + 1);
+	if (ret != NOMATCH || !exp[sx] || exp[sx] == ')')
             break;
     }
-    return (ret ? ret : (str[x] ? NOMATCH : MATCH));
+    PORT_Free(e2);
+    if (sx < 2)
+    	ret = ABORTED;
+    return ret;
+}
+
+/* returns 1 if val is in range from start..end, case insensitive. */
+static int
+_is_char_in_range(int start, int end, int val)
+{
+    char map[256];
+    memset(map, 0, sizeof map);
+    while (start <= end)
+	map[tolower(start++)] = 1;
+    return map[tolower(val)];
 }
 
 static int 
-port_RegExpMatch(const char *str, const char *xp, PRBool case_insensitive) {
-    register int x;
+_shexp_match(const char *str, const char *exp, PRBool case_insensitive, 
+             unsigned int level) 
+{
+    register int x;   /* input string index */
+    register int y;   /* expression index */
+    int ret,neg;
+
+    if (level > 20)      /* Don't let the stack get too deep. */
+    	return ABORTED;
+    for(x = 0, y = 0; exp[y]; ++y, ++x) {
+        if((!str[x]) && (exp[y] != '$') && (exp[y] != '*')) {
+            return NOMATCH;
+	}
+	switch(exp[y]) {
+	case '$':
+	    if(str[x])
+		return NOMATCH;
+	    --x;                 /* we don't want loop to increment x */
+	    break;
+	case '*':
+	    while(exp[++y] == '*'){}
+	    if(!exp[y])
+		return MATCH;
+	    while(str[x]) {
+	        ret = _shexp_match(&str[x++], &exp[y], case_insensitive, 
+				   level + 1);
+		switch(ret) {
+		case NOMATCH:
+		    continue;
+		case ABORTED:
+		    return ABORTED;
+		default:
+		    return MATCH;
+		}
+	    }
+	    if((exp[y] == '$') && (exp[y+1] == '\0') && (!str[x]))
+		return MATCH;
+	    else
+		return NOMATCH;
+	case '[': {
+	    int start, end = 0, i;
+	    neg = ((exp[++y] == '^') && (exp[y+1] != ']'));
+	    if (neg)
+		++y;
+	    i = y;
+	    start = (unsigned char)(exp[i++]);
+	    if (start == '\\')
+	    	start = (unsigned char)(exp[i++]);
+	    if (isalnum(start) && exp[i++] == '-') {
+		end = (unsigned char)(exp[i++]); 
+		if (end == '\\')
+		    end = (unsigned char)(exp[i++]);
+	    }
+	    if (isalnum(end) && exp[i] == ']') {
+		/* This is a range form: a-b */
+		int val   = (unsigned char)(str[x]);
+		if (end < start) { /* swap them */
+		    start ^= end;
+		    end ^= start;
+		    start ^= end;
+		}
+		if (case_insensitive && isalpha(val)) {
+		    val = _is_char_in_range(start, end, val);
+		    if (neg == val)
+			return NOMATCH;
+		} else if (neg != ((val < start) || (val > end))) {
+		    return NOMATCH;
+		}
+		y = i;
+	    } else {
+		/* Not range form */
+		int matched = 0;
+		for (; exp[y] != ']'; y++) {
+		    if (exp[y] == '\\')
+			++y;
+		    if(case_insensitive) {
+			matched |= (toupper(str[x]) == toupper(exp[y]));
+		    } else {
+			matched |= (str[x] == exp[y]);
+		    }
+		}
+		if (neg == matched)
+		    return NOMATCH;
+	    }
+	}
+	break;
+	case '(':
+	    if (!exp[y+1])
+	    	return ABORTED;
+	    return _handle_union(&str[x], &exp[y], case_insensitive, level);
+	case '?':
+	    break;
+	case '|':
+	case ']':
+	case ')':
+	    return ABORTED;
+	case '\\':
+	    ++y;
+	    /* fall through */
+	default:
+	    if(case_insensitive) {
+		if(toupper(str[x]) != toupper(exp[y]))
+		    return NOMATCH;
+	    } else {
+		if(str[x] != exp[y])
+		    return NOMATCH;
+	    }
+	    break;
+	}
+    }
+    return (str[x] ? NOMATCH : MATCH);
+}
+
+static int 
+port_RegExpMatch(const char *str, const char *xp, PRBool case_insensitive) 
+{
     char *exp = 0;
+    int x, ret = MATCH;
+
+    if (!strchr(xp, '~'))
+    	return _shexp_match(str, xp, case_insensitive, 0);
 
     exp = PORT_Strdup(xp);
-
     if(!exp)
-	return 1;
+	return NOMATCH;
 
-    for(x=strlen(exp)-1;x;--x) {
-        if((exp[x] == '~') && (exp[x-1] != '\\')) {
-            exp[x] = '\0';
-            if(_shexp_match(str,&exp[++x], case_insensitive) == MATCH)
-                goto punt;
-            break;
+    x = _scan_and_copy(exp, '~', '\0', NULL);
+    if (x != ABORTED && exp[x] == '~') {
+	exp[x++] = '\0';
+	ret = _shexp_match(str, &exp[x], case_insensitive, 0);
+	switch (ret) {
+	case NOMATCH: ret = MATCH;   break;
+	case MATCH:   ret = NOMATCH; break;
+	default:                     break;
         }
     }
-    if(_shexp_match(str,exp, case_insensitive) == MATCH) {
-        PORT_Free(exp);
-        return 0;
-    }
+    if (ret == MATCH)
+	ret = _shexp_match(str, exp, case_insensitive, 0);
 
-  punt:
     PORT_Free(exp);
-    return 1;
+    return ret;
 }
 
 
 /* ------------------------------ shexp_cmp ------------------------------- */
 
 int 
 PORT_RegExpSearch(const char *str, const char *exp)
 {
--- a/security/nss/lib/util/portreg.h
+++ b/security/nss/lib/util/portreg.h
@@ -14,16 +14,18 @@
  * The Original Code is the Netscape security libraries.
  *
  * The Initial Developer of the Original Code is
  * Netscape Communications Corporation.
  * Portions created by the Initial Developer are Copyright (C) 1994-2000
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
+ *      Rob McCool  (original author)
+ *      Nelson Bolyard <nelson@bolyard.me>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -32,33 +34,51 @@
  * 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 ***** */
 
 /*
  * shexp.h: Defines and prototypes for shell exp. match routines
  * 
- *
  * This routine will match a string with a shell expression. The expressions
  * accepted are based loosely on the expressions accepted by zsh.
  * 
  * o * matches anything
  * o ? matches one character
  * o \ will escape a special character
  * o $ matches the end of the string
- * o [abc] matches one occurence of a, b, or c. The only character that needs
- *         to be escaped in this is ], all others are not special.
- * o [a-z] matches any character between a and z
- * o [^az] matches any character except a or z
- * o ~ followed by another shell expression will remove any pattern
- *     matching the shell expression from the match list
- * o (foo|bar) will match either the substring foo, or the substring bar.
- *             These can be shell expressions as well.
- * 
+ * Bracketed expressions:
+ * o [abc] matches one occurence of a, b, or c.  
+ * o [^abc] matches any character except a, b, or c.
+ *     To be matched between [ and ], these characters must be escaped: \ ]
+ *     No other characters need be escaped between brackets. 
+ *     Unnecessary escaping is permitted.
+ * o [a-z] matches any character between a and z, inclusive.
+ *     The two range-definition characters must be alphanumeric ASCII.
+ *     If one is upper case and the other is lower case, then the ASCII
+ *     non-alphanumeric characters between Z and a will also be in range.
+ * o [^a-z] matches any character except those between a and z, inclusive.
+ *     These forms cannot be combined, e.g [a-gp-z] does not work.
+ * o Exclusions:
+ *   As a top level, outter-most expression only, the expression
+ *   foo~bar will match the expression foo, provided it does not also 
+ *     match the expression bar.  Either expression or both may be a union.
+ *     Except between brackets, any unescaped ~ is an exclusion. 
+ *     At most one exclusion is permitted.
+ *     Exclusions cannot be nested (contain other exclusions).
+ *     example: *~abc will match any string except abc
+ * o Unions:
+ *   (foo|bar) will match either the expression foo, or the expression bar.
+ *     At least one '|' separator is required.  More are permitted.
+ *     Expressions inside unions may not include unions or exclusions.
+ *     Inside a union, to be matched and not treated as a special character,
+ *     these characters must be escaped: \ ( | ) [ ~ except when they occur
+ *     inside a bracketed expression, where only \ and ] require escaping.
+ *
  * The public interface to these routines is documented below.
  * 
  */
  
 #ifndef SHEXP_H
 #define SHEXP_H
 
 #include "utilrename.h"
--- a/security/nss/lib/util/secport.c
+++ b/security/nss/lib/util/secport.c
@@ -36,17 +36,17 @@
 
 /*
  * secport.c - portability interfaces for security libraries
  *
  * This file abstracts out libc functionality that libsec depends on
  * 
  * NOTE - These are not public interfaces
  *
- * $Id: secport.c,v 1.23 2008/08/22 01:33:05 wtc%google.com Exp $
+ * $Id: secport.c,v 1.24 2009/07/30 23:28:21 nelson%bolyard.com Exp $
  */
 
 #include "seccomon.h"
 #include "prmem.h"
 #include "prerror.h"
 #include "plarena.h"
 #include "secerr.h"
 #include "prmon.h"
@@ -282,16 +282,18 @@ PORT_FreeArena(PLArenaPool *arena, PRBoo
 {
     PORTArenaPool *pool = (PORTArenaPool *)arena;
     PRLock *       lock = (PRLock *)0;
     size_t         len  = sizeof *arena;
     extern const PRVersionDescription * libVersionPoint(void);
     static const PRVersionDescription * pvd;
     static PRBool  doFreeArenaPool = PR_FALSE;
 
+    if (!pool)
+    	return;
     if (ARENAPOOL_MAGIC == pool->magic ) {
 	len  = sizeof *pool;
 	lock = pool->lock;
 	PZ_Lock(lock);
     }
     if (!pvd) {
 	/* Each of NSPR's DLLs has a function libVersionPoint().
 	** We could do a lot of extra work to be sure we're calling the
--- a/security/nss/tests/chains/chains.sh
+++ b/security/nss/tests/chains/chains.sh
@@ -69,17 +69,18 @@ chains_init()
     mkdir -p ${CHAINS_DIR}
     cd ${CHAINS_DIR}
 
     CHAINS_SCENARIOS="${QADIR}/chains/scenarios/scenarios"
 
     CERT_SN_CNT=$(date '+%m%d%H%M%S' | sed "s/^0*//")
     CERT_SN_FIX=$(expr ${CERT_SN_CNT} - 1000)
 
-    PK7_NONCE=$CERT_SN_CNT;
+    PK7_NONCE=$CERT_SN_CNT
+    SCEN_CNT=0
 
     AIA_FILES="${HOSTDIR}/aiafiles"
 
     CU_DATA=${HOSTDIR}/cu_data
     CRL_DATA=${HOSTDIR}/crl_data
 
     html_head "Certificate Chains Tests"
 }
@@ -410,26 +411,26 @@ process_crldp()
 {
     if [ -n "${CRLDP}" ]; then
         OPTIONS="${OPTIONS} -4"
 
         EXT_DATA="${EXT_DATA}1
 "
 
         for ITEM in ${CRLDP}; do
-            CRL_PUBLIC="${HOST}-$$-${ITEM}.crl"
+            CRL_PUBLIC="${HOST}-$$-${ITEM}-${SCEN_CNT}.crl"
 
             EXT_DATA="${EXT_DATA}7
 ${NSS_AIA_HTTP}/${CRL_PUBLIC}
 "
         done
 
-        EXT_DATA="${EXT_DATA}0
-0
-0
+        EXT_DATA="${EXT_DATA}-1
+-1
+-1
 n
 n
 "
     fi
 }
 
 process_ku_ns_eku()
 {
@@ -454,17 +455,17 @@ n
 copy_crl()
 
 {
     if [ -z "${NSS_AIA_PATH}" ]; then
         return;
     fi
 
     CRL_LOCAL="${COPYCRL}.crl"
-    CRL_PUBLIC="${HOST}-$$-${COPYCRL}.crl"
+    CRL_PUBLIC="${HOST}-$$-${COPYCRL}-${SCEN_CNT}.crl"
 
     cp ${CRL_LOCAL} ${NSS_AIA_PATH}/${CRL_PUBLIC} 2> /dev/null
     chmod a+r ${NSS_AIA_PATH}/${CRL_PUBLIC}
     echo ${NSS_AIA_PATH}/${CRL_PUBLIC} >> ${AIA_FILES}
 }
 
 ########################## process_extension ###########################
 # local shell function to process entity extension parameters and 
@@ -852,16 +853,17 @@ parse_config()
             AIA=
             CRLDP=
             OCSP=
             DB=
             EMAILS=
             EXT_KU=
             EXT_NS=
             EXT_EKU=
+            SERIAL=
             ;;
         "type")
             TYPE="${VALUE}"
             ;;
         "issuer")
             if [ -n "${ISSUER}" ]; then
                 if [ -z "${DB}" ]; then
                     create_entity "${ENTITY}" "${TYPE}"
@@ -973,16 +975,18 @@ parse_config()
             CHAINS_DIR="${HOSTDIR}/chains/${VALUE}"
             mkdir -p ${CHAINS_DIR}
             cd ${CHAINS_DIR}
 
             if [ -n "${MEMLEAK_DBG}" ]; then
                 LOGNAME="libpkix-${VALUE}"
                 LOGFILE="${LOGDIR}/${LOGNAME}"
             fi
+
+            SCEN_CNT=$(expr ${SCEN_CNT} + 1)
             ;;
         "sleep")
             sleep ${VALUE}
             ;;
         "break")
             break
             ;;
         "check_ocsp")
new file mode 100644
--- /dev/null
+++ b/security/nss/tests/chains/scenarios/crldp.cfg
@@ -0,0 +1,97 @@
+scenario CRLDP
+
+entity Root
+  type Root
+
+entity CA0
+  type Intermediate
+  issuer Root
+
+entity CA1
+  type Intermediate
+  crldp CA0
+  issuer CA0
+  serial 10
+    aia CA0:Root
+
+entity EE11
+  type EE
+  crldp CA0
+  issuer CA1
+
+entity CA2
+  type Intermediate
+  crldp CA0
+  issuer CA0
+  serial 20
+    aia CA0:Root
+
+entity EE21
+  type EE
+  issuer CA2
+
+entity EE1
+  type EE
+  crldp CA0
+  issuer CA0
+  serial 30
+    aia CA0:Root
+
+entity EE2
+  type EE
+  crldp CA0
+  issuer CA0
+  serial 40
+    aia CA0:Root
+
+crl Root
+crl CA0
+crl CA1
+crl CA2
+
+revoke CA0
+  serial 20
+
+revoke CA0
+  serial 40
+
+copycrl CA0
+
+db All
+
+import Root::CTu,CTu,CTu
+
+# intermediate CA - OK, EE - OK
+verify EE11:CA1
+  cert CA1:CA0
+  trust Root:
+  fetch
+  rev_type chain
+  rev_mtype crl
+  result pass
+
+# intermediate CA - revoked, EE - OK
+verify EE21:CA2
+  cert CA2:CA0
+  trust Root:
+  fetch
+  rev_type chain
+  rev_mtype crl
+  result fail
+
+# direct EE - OK 
+verify EE1:CA0
+  trust Root:
+  fetch
+  rev_type leaf
+  rev_mtype crl
+  result pass
+
+# direct EE - revoked
+verify EE2:CA0
+  trust Root:
+  fetch
+  rev_type leaf
+  rev_mtype crl
+  result fail
+
--- a/security/nss/tests/chains/scenarios/ocsp.cfg
+++ b/security/nss/tests/chains/scenarios/ocsp.cfg
@@ -18,24 +18,26 @@ revoke OCSPCA1
 
 testdb OCSPRoot
 
 #EE - OK, CA - OK
 verify OCSPEE11:x
   cert OCSPCA1:x
   trust OCSPRoot
   rev_type leaf
+  rev_flags requireFreshInfo
   rev_mtype ocsp
   result pass
 
 #EE - revoked, CA - OK
 verify OCSPEE12:x
   cert OCSPCA1:x
   trust OCSPRoot
   rev_type leaf
+  rev_flags requireFreshInfo
   rev_mtype ocsp
   result fail
 
 #EE - unknown 
 verify OCSPEE15:x
   cert OCSPCA1:x
   trust OCSPRoot
   rev_type leaf
@@ -46,25 +48,34 @@ verify OCSPEE15:x
 verify OCSPEE15:x
   cert OCSPCA1:x
   trust OCSPRoot
   rev_type leaf
   rev_flags requireFreshInfo
   rev_mtype ocsp
   result fail
 
-#EE - OK, CA - revoked, leaf
+#EE - OK, CA - revoked, leaf, no fresh info
 verify OCSPEE21:x
   cert OCSPCA2:x
   trust OCSPRoot
   rev_type leaf
   rev_mtype ocsp
   result pass
 
-#EE - OK, CA - revoked, chain
+#EE - OK, CA - revoked, leaf, requireFreshInfo
+verify OCSPEE21:x
+  cert OCSPCA2:x
+  trust OCSPRoot
+  rev_type leaf
+  rev_flags requireFreshInfo
+  rev_mtype ocsp
+  result fail
+
+#EE - OK, CA - revoked, chain, requireFreshInfo
 verify OCSPEE21:x
   cert OCSPCA2:x
   trust OCSPRoot
   rev_type chain
   rev_flags requireFreshInfo
   rev_mtype ocsp
   result fail
 
@@ -107,16 +118,25 @@ verify OCSPEE12:x
 verify OCSPEE15:x
   cert OCSPCA1:x
   trust OCSPRoot
   rev_type leaf
   rev_mtype ocsp
   rev_mflags failIfNoInfo
   result fail
 
+#EE - OK, CA - revoked, leaf, failIfNoInfo
+verify OCSPEE21:x
+  cert OCSPCA2:x
+  trust OCSPRoot
+  rev_type leaf
+  rev_mtype ocsp
+  rev_mflags failIfNoInfo
+  result fail
+
 testdb OCSPCA1
 
 #EE - OK on OCSP, revoked locally - should fail ??
 # two things about this test: crl is not imported into the db and
 # cert 13 is not revoked by crl.
 verify OCSPEE13:x
   cert OCSPCA1:x
   trust OCSPCA1