Bug 898431: Update to NSS 3.15.4 beta 3 (NSS_3_15_4_BETA3), r=me
authorBrian Smith <brian@briansmith.org>
Sun, 17 Nov 2013 14:12:45 -0800
changeset 167463 7c8ba61dabfe4736d950eef6fa5de91aa7148fd4
parent 167462 615f1fcd0c01e8c833aeec350a258a5538b7de9f
child 167464 bf6158f1ffc81ff0b2f806c570121e39095ddb31
push id428
push userbbajaj@mozilla.com
push dateTue, 28 Jan 2014 00:16:25 +0000
treeherdermozilla-release@cd72a7ff3a75 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersme
bugs898431
milestone27.0a2
Bug 898431: Update to NSS 3.15.4 beta 3 (NSS_3_15_4_BETA3), r=me
configure.in
security/nss/TAG-INFO
security/nss/cmd/bltest/blapitest.c
security/nss/cmd/certutil/certutil.c
security/nss/cmd/fipstest/fipstest.c
security/nss/cmd/httpserv/httpserv.c
security/nss/cmd/lib/secutil.c
security/nss/cmd/modutil/install-ds.c
security/nss/cmd/pp/pp.c
security/nss/cmd/tstclnt/tstclnt.c
security/nss/coreconf/coreconf.dep
security/nss/coreconf/nsinstall/pathsub.c
security/nss/doc/certutil.xml
security/nss/doc/html/certutil.html
security/nss/doc/html/modutil.html
security/nss/doc/html/pk12util.html
security/nss/doc/html/pp.html
security/nss/doc/html/signtool.html
security/nss/doc/html/signver.html
security/nss/doc/html/ssltap.html
security/nss/doc/html/vfychain.html
security/nss/doc/html/vfyserv.html
security/nss/doc/nroff/certutil.1
security/nss/doc/nroff/pk12util.1
security/nss/doc/nroff/pp.1
security/nss/doc/nroff/signtool.1
security/nss/doc/nroff/signver.1
security/nss/doc/nroff/ssltap.1
security/nss/doc/nroff/vfychain.1
security/nss/doc/nroff/vfyserv.1
security/nss/lib/certdb/cert.h
security/nss/lib/certdb/certt.h
security/nss/lib/certdb/polcyxtn.c
security/nss/lib/certhigh/ocsp.c
security/nss/lib/certhigh/ocsp.h
security/nss/lib/certhigh/ocspi.h
security/nss/lib/ckfw/builtins/certdata.txt
security/nss/lib/ckfw/builtins/nssckbi.h
security/nss/lib/freebl/unix_rand.c
security/nss/lib/libpkix/include/pkix_errorstrings.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/pk11wrap/pk11pub.h
security/nss/lib/pk11wrap/secmodi.h
security/nss/lib/softoken/pkcs11c.c
security/nss/lib/softoken/softkver.h
security/nss/lib/ssl/ssl.def
security/nss/lib/ssl/ssl.h
security/nss/lib/ssl/ssl3con.c
security/nss/lib/ssl/ssl3gthr.c
security/nss/lib/ssl/sslauth.c
security/nss/lib/ssl/sslenum.c
security/nss/lib/ssl/sslimpl.h
security/nss/lib/ssl/sslinfo.c
security/nss/lib/ssl/sslinit.c
security/nss/lib/ssl/sslsecur.c
security/nss/lib/ssl/sslsock.c
security/nss/lib/util/nssutil.h
security/nss/tests/chains/chains.sh
security/nss/tests/chains/ocspd-config/readme
security/nss/tests/chains/scenarios/ocsp.cfg
security/nss/tests/chains/scenarios/ocspd.cfg
security/nss/tests/chains/scenarios/scenarios
security/nss/tests/ocsp/ocsp.sh
--- a/configure.in
+++ b/configure.in
@@ -3670,17 +3670,17 @@ dnl = If NSS was not detected in the sys
 dnl = use the one in the source tree (mozilla/security/nss)
 dnl ========================================================
 
 MOZ_ARG_WITH_BOOL(system-nss,
 [  --with-system-nss       Use system installed NSS],
     _USE_SYSTEM_NSS=1 )
 
 if test -n "$_USE_SYSTEM_NSS"; then
-    AM_PATH_NSS(3.15, [MOZ_NATIVE_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])])
+    AM_PATH_NSS(3.15.4, [MOZ_NATIVE_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])])
 fi
 
 if test -n "$MOZ_NATIVE_NSS"; then
    NSS_LIBS="$NSS_LIBS -lcrmf"
 else
    NSS_CFLAGS='-I$(LIBXUL_DIST)/include/nss'
 
    if test -z "$GNU_CC" -a "$OS_ARCH" = "WINNT" -o "$OS_ARCH" = "OS2"; then
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-NSS_3_15_3_RTM
+NSS_3_15_4_BETA3
--- a/security/nss/cmd/bltest/blapitest.c
+++ b/security/nss/cmd/bltest/blapitest.c
@@ -894,20 +894,18 @@ setupIO(PLArenaPool *arena, bltestIO *in
     SECItem fileData;
     SECItem *in;
     unsigned char *tok;
     unsigned int i, j;
 
     if (file && (numBytes == 0 || file == PR_STDIN)) {
 	/* grabbing data from a file */
 	rv = SECU_FileToItem(&fileData, file);
-	if (rv != SECSuccess) {
-	    PR_Close(file);
+	if (rv != SECSuccess)
 	    return SECFailure;
-	}
 	in = &fileData;
     } else if (str) {
 	/* grabbing data from command line */
 	fileData.data = (unsigned char *)str;
 	fileData.len = PL_strlen(str);
 	in = &fileData;
     } else if (file) {
 	/* create nonce */
@@ -2871,18 +2869,20 @@ load_file_data(PLArenaPool *arena, bltes
 	       char *fn, bltestIOMode ioMode)
 {
     PRFileDesc *file;
     data->mode = ioMode;
     data->file = NULL; /* don't use -- not saving anything */
     data->pBuf.data = NULL;
     data->pBuf.len = 0;
     file = PR_Open(fn, PR_RDONLY, 00660);
-    if (file)
+    if (file) {
 	setupIO(arena, data, file, NULL, 0);
+	PR_Close(file);
+    }
 }
 
 void
 get_params(PLArenaPool *arena, bltestParams *params,
 	   bltestCipherMode mode, int j)
 {
     char filename[256];
     char *modestr = mode_strings[mode];
--- a/security/nss/cmd/certutil/certutil.c
+++ b/security/nss/cmd/certutil/certutil.c
@@ -940,17 +940,17 @@ ListModules(void)
     return SECSuccess;
 }
 
 static void 
 PrintSyntax(char *progName)
 {
 #define FPS fprintf(stderr, 
     FPS "Type %s -H for more detailed descriptions\n", progName);
-    FPS "Usage:  %s -N [-d certdir] [-P dbprefix] [-f pwfile]\n", progName);
+    FPS "Usage:  %s -N [-d certdir] [-P dbprefix] [-f pwfile] [--empty-password]\n", progName);
     FPS "Usage:  %s -T [-d certdir] [-P dbprefix] [-h token-name]\n"
 	"\t\t [-f pwfile] [-0 SSO-password]\n", progName);
     FPS "\t%s -A -n cert-name -t trustargs [-d certdir] [-P dbprefix] [-a] [-i input]\n", 
     	progName);
     FPS "\t%s -B -i batch-file\n", progName);
     FPS "\t%s -C [-c issuer-name | -x] -i cert-request-file -o cert-file\n"
 	"\t\t [-m serial-number] [-w warp-months] [-v months-valid]\n"
         "\t\t [-f pwfile] [-d certdir] [-P dbprefix]\n"
@@ -1356,16 +1356,18 @@ static void luN(enum usage_level ul, con
     FPS "%-15s Create a new certificate database\n",
         "-N");
     if (ul == usage_selected && !is_my_command)
         return;
     FPS "%-20s Cert database directory (default is ~/.netscape)\n",
         "   -d certdir");
     FPS "%-20s Cert & Key database prefix\n",
         "   -P dbprefix");
+    FPS "%-20s use empty password when creating a new database\n",
+        "   --empty-password");
     FPS "\n");
 }
 
 static void luT(enum usage_level ul, const char *command)
 {
     int is_my_command = (command && 0 == strcmp(command, "T"));
     if (ul == usage_all || !command || is_my_command)
     FPS "%-15s Reset the Key database or token\n",
@@ -2186,16 +2188,17 @@ enum certutilOpts {
     opt_AddCmdExtKeyUsageExt,
     opt_SourceDir,
     opt_SourcePrefix,
     opt_UpgradeID,
     opt_UpgradeTokenName,
     opt_KeyOpFlagsOn,
     opt_KeyOpFlagsOff,
     opt_KeyAttrFlags,
+    opt_EmptyPassword,
     opt_Help
 };
 
 static const
 secuCommandFlag commands_init[] =
 {
 	{ /* cmd_AddCert             */  'A', PR_FALSE, 0, PR_FALSE },
 	{ /* cmd_CreateNewCert       */  'C', PR_FALSE, 0, PR_FALSE },
@@ -2293,16 +2296,18 @@ secuCommandFlag options_init[] =
 	{ /* opt_UpgradeTokenName    */  0,   PR_TRUE,  0, PR_FALSE, 
                                                    "upgrade-token-name"},
 	{ /* opt_KeyOpFlagsOn        */  0,   PR_TRUE, 0, PR_FALSE, 
                                                    "keyOpFlagsOn"},
 	{ /* opt_KeyOpFlagsOff       */  0,   PR_TRUE, 0, PR_FALSE, 
                                                    "keyOpFlagsOff"},
 	{ /* opt_KeyAttrFlags        */  0,   PR_TRUE, 0, PR_FALSE, 
                                                    "keyAttrFlags"},
+	{ /* opt_EmptyPassword       */  0,   PR_FALSE, 0, PR_FALSE, 
+                                                   "empty-password"},
 };
 #define NUM_OPTIONS ((sizeof options_init)  / (sizeof options_init[0]))
 
 static secuCommandFlag certutil_commands[NUM_COMMANDS];
 static secuCommandFlag certutil_options [NUM_OPTIONS ];
 
 static const secuCommand certutil = {
     NUM_COMMANDS, 
@@ -2804,17 +2809,20 @@ certutil_main(int argc, char **argv, PRB
       
          SECU_PrintError(progName, "could not find the slot %s",slotname);
          rv = SECFailure;
          goto shutdown;
     }
 
     /*  If creating new database, initialize the password.  */
     if (certutil.commands[cmd_NewDBs].activated) {
-	SECU_ChangePW2(slot, 0, 0, certutil.options[opt_PasswordFile].arg,
+	if(certutil.options[opt_EmptyPassword].activated && (PK11_NeedUserInit(slot)))
+	    PK11_InitPin(slot, (char*)NULL, "");
+	else
+	    SECU_ChangePW2(slot, 0, 0, certutil.options[opt_PasswordFile].arg,
 				certutil.options[opt_NewPasswordFile].arg);
     }
 
     /* walk through the upgrade merge if necessary.
      * This option is more to test what some applications will want to do
      * to do an automatic upgrade. The --merge command is more useful for
      * the general case where 2 database need to be merged together.
      */
--- a/security/nss/cmd/fipstest/fipstest.c
+++ b/security/nss/cmd/fipstest/fipstest.c
@@ -3611,17 +3611,16 @@ void hmac_test(char *reqfn)
     FILE *req = NULL;  /* input stream from the REQUEST file */
     FILE *resp;        /* output stream to the RESPONSE file */
 
     buf = PORT_ZAlloc(bufSize);
     if (buf == NULL) {
         goto loser;
     }      
     msg = PORT_ZAlloc(msgLen);
-    memset(msg, 0, msgLen);
     if (msg == NULL) {
         goto loser;
     } 
 
     req = fopen(reqfn, "r");
     resp = stdout;
     while (fgets(buf, bufSize, req) != NULL) {
         if (strncmp(buf, "Mac", 3) == 0) {
@@ -3672,17 +3671,17 @@ void hmac_test(char *reqfn)
         /* Count = test iteration number*/
         if (strncmp(buf, "Count ", 5) == 0) {    
             /* count can just be put into resp file */
             fputs(buf, resp);
             /* zeroize the variables for the test with this data set */
             keyLen = 0; 
             TLen = 0;
             memset(key, 0, sizeof key);     
-            memset(msg, 0, sizeof msg);  
+            memset(msg, 0, msgLen);
             memset(HMAC, 0, sizeof HMAC);
             continue;
         }
         /* KLen = Length of the Input Secret Key ... */
         if (strncmp(buf, "Klen", 4) == 0) {
             i = 4;
             while (isspace(buf[i]) || buf[i] == '=') {
                 i++;
--- a/security/nss/cmd/httpserv/httpserv.c
+++ b/security/nss/cmd/httpserv/httpserv.c
@@ -22,37 +22,41 @@
 #include <stdarg.h>
 
 #include "nspr.h"
 #include "prio.h"
 #include "prerror.h"
 #include "prnetdb.h"
 #include "prclist.h"
 #include "plgetopt.h"
+#include "pk11func.h"
+#include "nss.h"
+#include "nssb64.h"
+#include "sechash.h"
+#include "cert.h"
+#include "certt.h"
+#include "ocsp.h"
+#include "ocspt.h"
+#include "ocspti.h"
+#include "ocspi.h"
 
 #ifndef PORT_Sprintf
 #define PORT_Sprintf sprintf
 #endif
 
 #ifndef PORT_Strstr
 #define PORT_Strstr strstr
 #endif
 
 #ifndef PORT_Malloc
 #define PORT_Malloc PR_Malloc
 #endif
 
 static int handle_connection( PRFileDesc *, PRFileDesc *, int );
 
-static const char inheritableSockName[] = { "SELFSERV_LISTEN_SOCKET" };
-
-#define DEFAULT_BULK_TEST 16384
-#define MAX_BULK_TEST     1048576 /* 1 MB */
-static PRBool testBulk;
-
 /* data and structures for shutdown */
 static int	stopping;
 
 static PRBool  noDelay;
 static int	verbose;
 
 static PRThread * acceptorThread;
 
@@ -65,43 +69,54 @@ static PRLogModuleInfo *lm;
 
 static void
 Usage(const char *progName)
 {
     fprintf(stderr, 
 
 "Usage: %s -p port [-Dbv]\n"
 "         [-t threads] [-i pid_file]\n"
+"         [-A nickname -C crl-filename]... [-O method]\n"
+"         [-d dbdir] [-f password_file] [-w password] [-P dbprefix]\n"
 "-D means disable Nagle delays in TCP\n"
 "-b means try binding to the port and exit\n"
 "-v means verbose output\n"
 "-t threads -- specify the number of threads to use for connections.\n"
-"-i pid_file file to write the process id of selfserve\n"
+"-i pid_file file to write the process id of httpserv\n"
+"Parameters -A, -C and -O are used to provide an OCSP server at /ocsp?\n"
+"-A a nickname of a CA certificate\n"
+"-C a CRL filename corresponding to the preceding CA nickname\n"
+"-O allowed HTTP methods for OCSP requests: get, post, all, random, get-unknown\n"
+"   random means: randomly fail if request method is GET, POST always works\n"
+"   get-unknown means: status unknown for GET, correct status for POST\n"
+"Multiple pairs of parameters -A and -C are allowed.\n"
+"If status for a cert from an unknown CA is requested, the cert from the\n"
+"first -A parameter will be used to sign the unknown status response.\n"
+"NSS database parameters are used only if OCSP parameters are used.\n"
 	,progName);
 }
 
 static const char *
 errWarn(char * funcString)
 {
     PRErrorCode  perr      = PR_GetError();
     const char * errString = SECU_Strerror(perr);
 
-    fprintf(stderr, "selfserv: %s returned error %d:\n%s\n",
+    fprintf(stderr, "httpserv: %s returned error %d:\n%s\n",
             funcString, perr, errString);
     return errString;
 }
 
 static void
 errExit(char * funcString)
 {
     errWarn(funcString);
     exit(3);
 }
 
-
 #define MAX_VIRT_SERVER_NAME_ARRAY_INDEX  10
 
 /**************************************************************************
 ** Begin thread management routines and data.
 **************************************************************************/
 #define MIN_THREADS 3
 #define DEFAULT_THREADS 8
 #define MAX_THREADS 4096
@@ -250,17 +265,17 @@ launch_threads(
 	slot->b = b;
 	slot->c = c;
 	slot->startFunc = startFunc;
 	slot->prThread = PR_CreateThread(PR_USER_THREAD, 
 			thread_wrapper, slot, PR_PRIORITY_NORMAL, 
                         (PR_TRUE==local)?PR_LOCAL_THREAD:PR_GLOBAL_THREAD,
                         PR_UNJOINABLE_THREAD, 0);
 	if (slot->prThread == NULL) {
-	    printf("selfserv: Failed to launch thread!\n");
+	    printf("httpserv: Failed to launch thread!\n");
 	    slot->state = rs_idle;
 	    rv = SECFailure;
 	    break;
 	} 
 
 	++threadCount;
     }
     PZ_Unlock(qLock); 
@@ -272,17 +287,17 @@ launch_threads(
         PZ_DestroyCondVar(name); name = NULL; }
 #define DESTROY_LOCK(name) if (name) { \
         PZ_DestroyLock(name); name = NULL; }
 	
 
 void
 terminateWorkerThreads(void)
 {
-    VLOG(("selfserv: server_thead: waiting on stopping"));
+    VLOG(("httpserv: server_thead: waiting on stopping"));
     PZ_Lock(qLock);
     PZ_NotifyAllCondVar(jobQNotEmptyCv);
     while (threadCount > 0) {
 	PZ_WaitCondVar(threadCountChangeCv, PR_INTERVAL_NO_TIMEOUT);
     }
     /* The worker threads empty the jobQ before they terminate. */
     PORT_Assert(PR_CLIST_IS_EMPTY(&jobQ));
     PZ_Unlock(qLock); 
@@ -298,90 +313,170 @@ terminateWorkerThreads(void)
 }
 
 /**************************************************************************
 ** End   thread management routines.
 **************************************************************************/
 
 PRBool NoReuse         = PR_FALSE;
 PRBool disableLocking  = PR_FALSE;
-PRBool failedToNegotiateName  = PR_FALSE;
+static secuPWData  pwdata = { PW_NONE, 0 };
 
+struct caRevoInfoStr
+{
+    PRCList link;
+    char *nickname;
+    char *crlFilename;
+    CERTCertificate *cert;
+    CERTOCSPCertID *id;
+    CERTSignedCrl *crl;
+};
+typedef struct caRevoInfoStr caRevoInfo;
+/* Created during app init. No locks necessary, 
+ * because later on, only read access will occur. */
+static caRevoInfo *caRevoInfos = NULL;
+
+static enum { 
+  ocspGetOnly, ocspPostOnly, ocspGetAndPost, ocspRandomGetFailure, ocspGetUnknown
+} ocspMethodsAllowed = ocspGetAndPost;
 
 static const char stopCmd[] = { "GET /stop " };
 static const char getCmd[]  = { "GET " };
 static const char EOFmsg[]  = { "EOF\r\n\r\n\r\n" };
 static const char outHeader[] = {
     "HTTP/1.0 200 OK\r\n"
     "Server: Generic Web Server\r\n"
     "Date: Tue, 26 Aug 1997 22:10:05 GMT\r\n"
     "Content-type: text/plain\r\n"
     "\r\n"
 };
+static const char outOcspHeader[] = {
+    "HTTP/1.0 200 OK\r\n"
+    "Server: Generic OCSP Server\r\n"
+    "Content-type: application/ocsp-response\r\n"
+    "\r\n"
+};
+static const char outBadRequestHeader[] = {
+    "HTTP/1.0 400 Bad Request\r\n"
+    "Server: Generic OCSP Server\r\n"
+    "\r\n"
+};
 
 void stop_server()
 {
     stopping = 1;
     PR_Interrupt(acceptorThread);
     PZ_TraceFlush();
 }
 
+/* Will only work if the original input to url encoding was
+ * a base64 encoded buffer. Will only decode the sequences used
+ * for encoding the special base64 characters, and fail if any
+ * other encoded chars are found.
+ * Will return SECSuccess if input could be processed.
+ * Coversion is done in place.
+ */
+static SECStatus
+urldecode_base64chars_inplace(char *buf)
+{
+    char *walk;
+    size_t remaining_bytes;
+    
+    if (!buf || !*buf)
+	return SECFailure;
+    
+    walk = buf;
+    remaining_bytes = strlen(buf) + 1; /* include terminator */
+    
+    while (*walk) {
+	if (*walk == '%') {
+	    if (!PL_strncasecmp(walk, "%2B", 3)) {
+		*walk = '+';
+	    } else if (!PL_strncasecmp(walk, "%2F", 3)) {
+		*walk = '/';
+	    } else if (!PL_strncasecmp(walk, "%3D", 3)) {
+		*walk = '=';
+	    } else {
+		return SECFailure;
+	    }
+	    remaining_bytes -= 3;
+	    ++walk;
+	    memmove(walk, walk+2, remaining_bytes);
+	} else {
+	    ++walk;
+	    --remaining_bytes;
+	}
+    }
+    return SECSuccess;
+}
+
 int
 handle_connection( 
     PRFileDesc *tcp_sock,
     PRFileDesc *model_sock,
     int         requestCert
     )
 {
     PRFileDesc *       ssl_sock = NULL;
     PRFileDesc *       local_file_fd = NULL;
-    char  *            post;
     char  *            pBuf;			/* unused space at end of buf */
     const char *       errString;
     PRStatus           status;
     int                bufRem;			/* unused bytes at end of buf */
     int                bufDat;			/* characters received in buf */
     int                newln    = 0;		/* # of consecutive newlns */
     int                firstTime = 1;
     int                reqLen;
     int                rv;
     int                numIOVs;
     PRSocketOptionData opt;
     PRIOVec            iovs[16];
     char               msgBuf[160];
     char               buf[10240];
     char               fileName[513];
+    char *getData = NULL; /* inplace conversion */
+    SECItem postData;
+    PRBool isOcspRequest = PR_FALSE;
+    PRBool isPost;
+
+    postData.data = NULL;
+    postData.len = 0;
 
     pBuf   = buf;
     bufRem = sizeof buf;
 
-    VLOG(("selfserv: handle_connection: starting"));
+    VLOG(("httpserv: handle_connection: starting"));
     opt.option             = PR_SockOpt_Nonblocking;
     opt.value.non_blocking = PR_FALSE;
     PR_SetSocketOption(tcp_sock, &opt);
 
-    VLOG(("selfserv: handle_connection: starting\n"));
+    VLOG(("httpserv: handle_connection: starting\n"));
 	ssl_sock = tcp_sock;
 
     if (noDelay) {
 	opt.option         = PR_SockOpt_NoDelay;
 	opt.value.no_delay = PR_TRUE;
 	status = PR_SetSocketOption(ssl_sock, &opt);
 	if (status != PR_SUCCESS) {
 	    errWarn("PR_SetSocketOption(PR_SockOpt_NoDelay, PR_TRUE)");
             if (ssl_sock) {
 	        PR_Close(ssl_sock);
             }
 	    return SECFailure;
 	}
     }
 
     while (1) {
+	const char *post;
+	const char *foundStr = NULL;
+	const char *tmp = NULL;
+
 	newln = 0;
-	reqLen     = 0;
+	reqLen = 0;
+
 	rv = PR_Read(ssl_sock, pBuf, bufRem - 1);
 	if (rv == 0 || 
 	    (rv < 0 && PR_END_OF_FILE_ERROR == PR_GetError())) {
 	    if (verbose)
 		errWarn("HDX PR_Read hit EOF");
 	    break;
 	}
 	if (rv < 0) {
@@ -421,76 +516,266 @@ handle_connection(
 	 * If the request is a POST, then there will be one more
 	 * line of data.
 	 * This parsing is a hack, but ok for SSL test purposes.
 	 */
 	post = PORT_Strstr(buf, "POST ");
 	if (!post || *post != 'P') 
 	    break;
 
-	/* It's a post, so look for the next and final CR/LF. */
-	/* We should parse content length here, but ... */
-	while (reqLen < bufDat && newln < 3) {
-	    int octet = buf[reqLen++];
-	    if (octet == '\n') {
-		newln++;
+	postData.data = (void*)(buf + reqLen);
+	
+	tmp = "content-length: ";
+	foundStr = PL_strcasestr(buf, tmp);
+	if (foundStr) {
+	    int expectedPostLen;
+	    int havePostLen;
+	    
+	    expectedPostLen = atoi(foundStr+strlen(tmp));
+	    havePostLen = bufDat - reqLen;
+	    if (havePostLen >= expectedPostLen) {
+		postData.len = expectedPostLen;
+		break;
 	    }
+	} else {
+	    /* use legacy hack */
+	    /* It's a post, so look for the next and final CR/LF. */
+	    while (reqLen < bufDat && newln < 3) {
+		int octet = buf[reqLen++];
+		if (octet == '\n') {
+		    newln++;
+		}
+	    }
+	    if (newln == 3)
+		break;
 	}
-	if (newln == 3)
-	    break;
     } /* read loop */
 
     bufDat = pBuf - buf;
     if (bufDat) do {	/* just close if no data */
 	/* Have either (a) a complete get, (b) a complete post, (c) EOF */
-	if (reqLen > 0 && !strncmp(buf, getCmd, sizeof getCmd - 1)) {
-	    char *      fnBegin = buf + 4;
-	    char *      fnEnd;
-	    PRFileInfo  info;
-	    /* try to open the file named.  
-	     * If successful, then write it to the client.
-	     */
-	    fnEnd = strpbrk(fnBegin, " \r\n");
-	    if (fnEnd) {
-		int fnLen = fnEnd - fnBegin;
-		if (fnLen < sizeof fileName) {
-                    char *fnstart;
-                    strncpy(fileName, fnBegin, fnLen);
-                    fileName[fnLen] = 0;	/* null terminate */
-                    fnstart = fileName;
-                    /* strip initial / because our root is the current directory*/
-                    while (*fnstart && *fnstart=='/')
-                        ++fnstart;
-		    status = PR_GetFileInfo(fnstart, &info);
-		    if (status == PR_SUCCESS &&
-			info.type == PR_FILE_FILE &&
-			info.size >= 0 ) {
-			local_file_fd = PR_Open(fnstart, PR_RDONLY, 0);
+	if (reqLen > 0) {
+	    PRBool isGetOrPost = PR_FALSE;
+	    unsigned skipChars = 0;
+	    isPost = PR_FALSE;
+	    
+	    if (!strncmp(buf, getCmd, sizeof getCmd - 1)) {
+		isGetOrPost = PR_TRUE;
+		skipChars = 4;
+	    }
+	    else if (!strncmp(buf, "POST ", 5)) {
+		isGetOrPost = PR_TRUE;
+		isPost = PR_TRUE;
+		skipChars = 5;
+	    }
+	    
+	    if (isGetOrPost) {
+		char *      fnBegin = buf;
+		char *      fnEnd;
+		char *      fnstart = NULL;
+		PRFileInfo  info;
+		
+		fnBegin += skipChars;
+		
+		fnEnd = strpbrk(fnBegin, " \r\n");
+		if (fnEnd) {
+		    int fnLen = fnEnd - fnBegin;
+		    if (fnLen < sizeof fileName) {
+			strncpy(fileName, fnBegin, fnLen);
+			fileName[fnLen] = 0;	/* null terminate */
+			fnstart = fileName;
+			/* strip initial / because our root is the current directory*/
+			while (*fnstart && *fnstart=='/')
+			    ++fnstart;
+		    }
+		}
+		if (fnstart) {
+		    if (!strncmp(fnstart, "ocsp", 4)) {
+			if (isPost) {
+			    if (postData.data) {
+				isOcspRequest = PR_TRUE;
+			    }
+			} else {
+			    if (!strncmp(fnstart, "ocsp/", 5)) {
+				isOcspRequest = PR_TRUE;
+				getData = fnstart + 5;
+			    }
+			}
+		    } else {
+			/* try to open the file named.  
+			* If successful, then write it to the client.
+			*/
+			status = PR_GetFileInfo(fnstart, &info);
+			if (status == PR_SUCCESS &&
+			    info.type == PR_FILE_FILE &&
+			    info.size >= 0 ) {
+			    local_file_fd = PR_Open(fnstart, PR_RDONLY, 0);
+			}
 		    }
 		}
 	    }
 	}
 
 	numIOVs = 0;
-
+	
 	iovs[numIOVs].iov_base = (char *)outHeader;
 	iovs[numIOVs].iov_len  = (sizeof(outHeader)) - 1;
 	numIOVs++;
+	
+	if (isOcspRequest && caRevoInfos) {
+	    CERTOCSPRequest *request = NULL;
+	    PRBool failThisRequest = PR_FALSE;
+	    
+	    if (ocspMethodsAllowed == ocspGetOnly && postData.len) {
+		failThisRequest = PR_TRUE;
+	    } else if (ocspMethodsAllowed == ocspPostOnly && getData) {
+		failThisRequest = PR_TRUE;
+	    } else if (ocspMethodsAllowed == ocspRandomGetFailure && getData) {
+		if (!(rand() % 2)) {
+		    failThisRequest = PR_TRUE;
+		}
+	    }
+	    
+	    if (failThisRequest) {
+		PR_Write(ssl_sock, outBadRequestHeader, strlen(outBadRequestHeader));
+		break;
+	    }
+	    /* get is base64, post is binary.
+	     * If we have base64, convert into the (empty) postData array.
+	     */
+	    if (getData) {
+		if (urldecode_base64chars_inplace(getData) == SECSuccess) {
+		    NSSBase64_DecodeBuffer(NULL, &postData, getData, strlen(getData));
+		}
+	    }
+	    if (postData.len) {
+		request = CERT_DecodeOCSPRequest(&postData);
+	    }
+	    if (!request || !request->tbsRequest || 
+	        !request->tbsRequest->requestList ||
+	        !request->tbsRequest->requestList[0]) {
+		PORT_Sprintf(msgBuf, "Cannot decode OCSP request.\r\n");
 
-	if (local_file_fd) {
+		iovs[numIOVs].iov_base = msgBuf;
+		iovs[numIOVs].iov_len  = PORT_Strlen(msgBuf);
+		numIOVs++;
+	    } else {
+	      /* TODO: support more than one request entry */
+	      CERTOCSPCertID *reqid = request->tbsRequest->requestList[0]->reqCert;
+	      const caRevoInfo *revoInfo = NULL;
+	      PRBool unknown = PR_FALSE;
+	      PRBool revoked = PR_FALSE;
+	      PRTime nextUpdate = 0;
+	      PRTime revoDate = 0;
+	      PRCList *caRevoIter;
+
+	      caRevoIter = &caRevoInfos->link;
+	      do {
+		  CERTOCSPCertID *caid;
+
+		  revoInfo = (caRevoInfo*)caRevoIter;
+		  caid = revoInfo->id;
+		  
+		  if (SECOID_CompareAlgorithmID(&reqid->hashAlgorithm, 
+		                                &caid->hashAlgorithm) == SECEqual
+		      &&
+		      SECITEM_CompareItem(&reqid->issuerNameHash,
+					  &caid->issuerNameHash) == SECEqual
+		      &&
+		      SECITEM_CompareItem(&reqid->issuerKeyHash,
+					  &caid->issuerKeyHash) == SECEqual) {
+		      break;
+		  }
+		  revoInfo = NULL;
+		  caRevoIter = PR_NEXT_LINK(caRevoIter);
+	      } while (caRevoIter != &caRevoInfos->link);
+	      
+	      if (!revoInfo) {
+		  unknown = PR_TRUE;
+		  revoInfo = caRevoInfos;
+	      } else {
+		  CERTCrl *crl = &revoInfo->crl->crl;
+		  CERTCrlEntry *entry = NULL;
+		  DER_DecodeTimeChoice(&nextUpdate, &crl->nextUpdate);
+		  if (crl->entries) {
+		      int iv = 0;
+		      /* assign, not compare */
+		      while ((entry = crl->entries[iv++])) {
+			  if (SECITEM_CompareItem(&reqid->serialNumber,
+						  &entry->serialNumber) == SECEqual) {
+			      break;
+			  }
+		      }
+		  }
+		  if (entry) {
+		      /* revoked status response */
+		      revoked = PR_TRUE;
+		      DER_DecodeTimeChoice(&revoDate, &entry->revocationDate);
+		  } else {
+		      /* else good status response */
+		      if (!isPost && ocspMethodsAllowed == ocspGetUnknown) {
+			  unknown = PR_TRUE;
+			  nextUpdate = PR_Now() + 60*60*24 * PR_USEC_PER_SEC; /*tomorrow*/
+			  revoDate = PR_Now() - 60*60*24 * PR_USEC_PER_SEC; /*yesterday*/
+		      }
+		  }
+	      }
+
+	      {
+		  PRTime now = PR_Now();
+		  PLArenaPool *arena = NULL;
+		  CERTOCSPSingleResponse *sr;
+		  CERTOCSPSingleResponse **singleResponses;
+		  SECItem *ocspResponse;
+		  
+		  arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+		  
+		  if (unknown) {
+		      sr = CERT_CreateOCSPSingleResponseUnknown(arena, reqid, now,
+								&nextUpdate);
+		  } else if (revoked) {
+		      sr = CERT_CreateOCSPSingleResponseRevoked(arena, reqid, now,
+			  &nextUpdate, revoDate, NULL);
+		  } else {
+		      sr = CERT_CreateOCSPSingleResponseGood(arena, reqid, now,
+							    &nextUpdate);
+		  }
+		  
+		  /* meaning of value 2: one entry + one end marker */
+		  singleResponses = PORT_ArenaNewArray(arena, CERTOCSPSingleResponse*, 2);
+		  singleResponses[0] = sr;
+		  singleResponses[1] = NULL;
+		  ocspResponse = CERT_CreateEncodedOCSPSuccessResponse(arena, 
+				      revoInfo->cert, ocspResponderID_byName, now,
+				      singleResponses, &pwdata);
+		  
+		  if (!ocspResponse) {
+		      PORT_Sprintf(msgBuf, "Failed to encode response\r\n");
+		      iovs[numIOVs].iov_base = msgBuf;
+		      iovs[numIOVs].iov_len  = PORT_Strlen(msgBuf);
+		      numIOVs++;
+		  } else {
+		      PR_Write(ssl_sock, outOcspHeader, strlen(outOcspHeader));
+		      PR_Write(ssl_sock, ocspResponse->data, ocspResponse->len);
+		      PORT_FreeArena(arena, PR_FALSE);
+		  }
+	      }
+	      break;
+	    }
+	} else if (local_file_fd) {
 	    PRInt32     bytes;
 	    int         errLen;
             bytes = PR_TransmitFile(ssl_sock, local_file_fd, outHeader,
                                     sizeof outHeader - 1,
                                     PR_TRANSMITFILE_KEEP_OPEN,
                                     PR_INTERVAL_NO_TIMEOUT);
             if (bytes >= 0) {
                 bytes -= sizeof outHeader - 1;
                 FPRINTF(stderr, 
-                        "selfserv: PR_TransmitFile wrote %d bytes from %s\n",
+                        "httpserv: PR_TransmitFile wrote %d bytes from %s\n",
                         bytes, fileName);
                 break;
             }
             errString = errWarn("PR_TransmitFile");
             errLen = PORT_Strlen(errString);
             errLen = PR_MIN(errLen, sizeof msgBuf - 1);
             PORT_Memcpy(msgBuf, errString, errLen);
             msgBuf[errLen] = 0;
@@ -518,55 +803,48 @@ handle_connection(
 	    if (verbose > 1) 
 	    	fwrite(buf, 1, reqLen, stdout);	/* display it */
 
 	    iovs[numIOVs].iov_base = buf;
 	    iovs[numIOVs].iov_len  = reqLen;
 	    numIOVs++;
 	}
 
-        /* Don't add the EOF if we want to test bulk encryption */
-        if (!testBulk) {
-            iovs[numIOVs].iov_base = (char *)EOFmsg;
-            iovs[numIOVs].iov_len  = sizeof EOFmsg - 1;
-            numIOVs++;
-        }
-
 	rv = PR_Writev(ssl_sock, iovs, numIOVs, PR_INTERVAL_NO_TIMEOUT);
 	if (rv < 0) {
 	    errWarn("PR_Writev");
 	    break;
 	}
 
     } while (0);
 
 cleanup:
     if (ssl_sock) {
         PR_Close(ssl_sock);
     } else if (tcp_sock) {
         PR_Close(tcp_sock);
     }
     if (local_file_fd)
 	PR_Close(local_file_fd);
-    VLOG(("selfserv: handle_connection: exiting\n"));
+    VLOG(("httpserv: handle_connection: exiting\n"));
 
     /* do a nice shutdown if asked. */
     if (!strncmp(buf, stopCmd, sizeof stopCmd - 1)) {
-        VLOG(("selfserv: handle_connection: stop command"));
+        VLOG(("httpserv: handle_connection: stop command"));
         stop_server();
     }
-    VLOG(("selfserv: handle_connection: exiting"));
+    VLOG(("httpserv: handle_connection: exiting"));
     return SECSuccess;	/* success */
 }
 
 #ifdef XP_UNIX
 
 void sigusr1_handler(int sig)
 {
-    VLOG(("selfserv: sigusr1_handler: stop server"));
+    VLOG(("httpserv: sigusr1_handler: stop server"));
     stop_server();
 }
 
 #endif
 
 SECStatus
 do_accepts(
     PRFileDesc *listen_sock,
@@ -575,17 +853,17 @@ do_accepts(
     )
 {
     PRNetAddr   addr;
     PRErrorCode  perr;
 #ifdef XP_UNIX
     struct sigaction act;
 #endif
 
-    VLOG(("selfserv: do_accepts: starting"));
+    VLOG(("httpserv: do_accepts: starting"));
     PR_SetThreadPriority( PR_GetCurrentThread(), PR_PRIORITY_HIGH);
 
     acceptorThread = PR_GetCurrentThread();
 #ifdef XP_UNIX
     /* set up the signal handler */
     act.sa_handler = sigusr1_handler;
     sigemptyset(&act.sa_mask);
     act.sa_flags = 0;
@@ -593,34 +871,34 @@ do_accepts(
         fprintf(stderr, "Error installing signal handler.\n");
         exit(1);
     }
 #endif
     while (!stopping) {
 	PRFileDesc *tcp_sock;
 	PRCList    *myLink;
 
-	FPRINTF(stderr, "\n\n\nselfserv: About to call accept.\n");
+	FPRINTF(stderr, "\n\n\nhttpserv: About to call accept.\n");
 	tcp_sock = PR_Accept(listen_sock, &addr, PR_INTERVAL_NO_TIMEOUT);
 	if (tcp_sock == NULL) {
     	    perr      = PR_GetError();
 	    if ((perr != PR_CONNECT_RESET_ERROR &&
 	         perr != PR_PENDING_INTERRUPT_ERROR) || verbose) {
 		errWarn("PR_Accept");
 	    } 
 	    if (perr == PR_CONNECT_RESET_ERROR) {
 		FPRINTF(stderr, 
 		        "Ignoring PR_CONNECT_RESET_ERROR error - continue\n");
 		continue;
 	    }
 	    stopping = 1;
 	    break;
 	}
 
-        VLOG(("selfserv: do_accept: Got connection\n"));
+        VLOG(("httpserv: do_accept: Got connection\n"));
 
 	PZ_Lock(qLock);
 	while (PR_CLIST_IS_EMPTY(&freeJobs) && !stopping) {
             PZ_WaitCondVar(freeListNotEmptyCv, PR_INTERVAL_NO_TIMEOUT);
 	}
 	if (stopping) {
 	    PZ_Unlock(qLock);
             if (tcp_sock) {
@@ -640,18 +918,18 @@ do_accepts(
 	    myJob->requestCert = requestCert;
 	}
 
 	PR_APPEND_LINK(myLink, &jobQ);
 	PZ_NotifyCondVar(jobQNotEmptyCv);
 	PZ_Unlock(qLock);
     }
 
-    FPRINTF(stderr, "selfserv: Closing listen socket.\n");
-    VLOG(("selfserv: do_accepts: exiting"));
+    FPRINTF(stderr, "httpserv: Closing listen socket.\n");
+    VLOG(("httpserv: do_accepts: exiting"));
     if (listen_sock) {
         PR_Close(listen_sock);
     }
     return SECSuccess;
 }
 
 PRFileDesc *
 getBoundListenSocket(unsigned short port)
@@ -750,65 +1028,205 @@ haveAChild(int argc, char **argv, PRProc
     if (!newProcess) {
 	errWarn("Can't create new process.");
     } else {
 	child[numChildren++] = newProcess;
     }
     return newProcess;
 }
 
+/* slightly adjusted version of ocsp_CreateCertID (not using issuer) */
+static CERTOCSPCertID *
+ocsp_CreateSelfCAID(PLArenaPool *arena, CERTCertificate *cert, PRTime time)
+{
+    CERTOCSPCertID *certID;
+    void *mark = PORT_ArenaMark(arena);
+    SECStatus rv;
+
+    PORT_Assert(arena != NULL);
+
+    certID = PORT_ArenaZNew(arena, CERTOCSPCertID);
+    if (certID == NULL) {
+	goto loser;
+    }
+
+    rv = SECOID_SetAlgorithmID(arena, &certID->hashAlgorithm, SEC_OID_SHA1,
+			       NULL);
+    if (rv != SECSuccess) {
+	goto loser; 
+    }
+
+    if (CERT_GetSubjectNameDigest(arena, cert, SEC_OID_SHA1,
+                                  &(certID->issuerNameHash)) == NULL) {
+        goto loser;
+    }
+    certID->issuerSHA1NameHash.data = certID->issuerNameHash.data;
+    certID->issuerSHA1NameHash.len = certID->issuerNameHash.len;
+
+    if (CERT_GetSubjectNameDigest(arena, cert, SEC_OID_MD5,
+                                  &(certID->issuerMD5NameHash)) == NULL) {
+        goto loser;
+    }
+
+    if (CERT_GetSubjectNameDigest(arena, cert, SEC_OID_MD2,
+                                  &(certID->issuerMD2NameHash)) == NULL) {
+        goto loser;
+    }
+
+    if (CERT_GetSPKIDigest(arena, cert, SEC_OID_SHA1,
+				   &(certID->issuerKeyHash)) == NULL) {
+	goto loser;
+    }
+    certID->issuerSHA1KeyHash.data = certID->issuerKeyHash.data;
+    certID->issuerSHA1KeyHash.len = certID->issuerKeyHash.len;
+    /* cache the other two hash algorithms as well */
+    if (CERT_GetSPKIDigest(arena, cert, SEC_OID_MD5,
+				   &(certID->issuerMD5KeyHash)) == NULL) {
+	goto loser;
+    }
+    if (CERT_GetSPKIDigest(arena, cert, SEC_OID_MD2,
+				   &(certID->issuerMD2KeyHash)) == NULL) {
+	goto loser;
+    }
+
+    PORT_ArenaUnmark(arena, mark);
+    return certID;
+
+loser:
+    PORT_ArenaRelease(arena, mark);
+    return NULL;
+}
+
+/* slightly adjusted version of CERT_CreateOCSPCertID */
+CERTOCSPCertID*
+cert_CreateSelfCAID(CERTCertificate *cert, PRTime time)
+{
+    PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+    CERTOCSPCertID *certID;
+    PORT_Assert(arena != NULL);
+    if (!arena)
+	return NULL;
+    
+    certID = ocsp_CreateSelfCAID(arena, cert, time);
+    if (!certID) {
+	PORT_FreeArena(arena, PR_FALSE);
+	return NULL;
+    }
+    certID->poolp = arena;
+    return certID;
+}
+
 int
 main(int argc, char **argv)
 {
     char *               progName    = NULL;
+    const char *         dir         = ".";
+    char *               passwd      = NULL;
+    char *               pwfile      = NULL;
     const char *         pidFile     = NULL;
     char *               tmp;
     PRFileDesc *         listen_sock;
     int                  optionsFound = 0;
     unsigned short       port        = 0;
     SECStatus            rv;
     PRStatus             prStatus;
     PRBool               bindOnly = PR_FALSE;
     PRBool               useLocalThreads = PR_FALSE;
     PLOptState		*optstate;
     PLOptStatus          status;
+    char                 emptyString[] = { "" };
+    char*                certPrefix = emptyString;
+    caRevoInfo		*revoInfo = NULL;
+    PRCList             *caRevoIter = NULL;
+    PRBool               provideOcsp = PR_FALSE;
 
     tmp = strrchr(argv[0], '/');
     tmp = tmp ? tmp + 1 : argv[0];
     progName = strrchr(tmp, '\\');
     progName = progName ? progName + 1 : tmp;
 
     PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
 
     /* please keep this list of options in ASCII collating sequence.
     ** numbers, then capital letters, then lower case, alphabetical. 
     */
     optstate = PL_CreateOptState(argc, argv, 
-        "Dbhi:p:t:v");
+        "A:C:DO:P:bd:f:hi:p:t:vw:");
     while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
 	++optionsFound;
 	switch(optstate->option) {
+	/* A first, must be followed by C. Any other order is an error.
+	 * A creates the object. C completes and moves into list.
+	 */
+	case 'A':
+	  provideOcsp = PR_TRUE;
+	  if (revoInfo) { Usage(progName); exit(0); }
+	  revoInfo = PORT_New(caRevoInfo);
+	  revoInfo->nickname = PORT_Strdup(optstate->value);
+	  break;
+	case 'C':
+	  if (!revoInfo) { Usage(progName); exit(0); }
+	  revoInfo->crlFilename = PORT_Strdup(optstate->value);
+	  if (!caRevoInfos) {
+	      PR_INIT_CLIST(&revoInfo->link);
+	      caRevoInfos = revoInfo;
+	  } else {
+	      PR_APPEND_LINK(&revoInfo->link, &caRevoInfos->link);
+	  }
+	  revoInfo = NULL;
+	  break;
+	  
+	case 'O':
+	  if (!PL_strcasecmp(optstate->value, "all")) {
+	      ocspMethodsAllowed = ocspGetAndPost;
+	  } else if (!PL_strcasecmp(optstate->value, "get")) {
+	      ocspMethodsAllowed = ocspGetOnly;
+	  } else if (!PL_strcasecmp(optstate->value, "post")) {
+	      ocspMethodsAllowed = ocspPostOnly;
+	  } else if (!PL_strcasecmp(optstate->value, "random")) {
+	      ocspMethodsAllowed = ocspRandomGetFailure;
+	  } else if (!PL_strcasecmp(optstate->value, "get-unknown")) {
+	      ocspMethodsAllowed = ocspGetUnknown;
+	  } else {
+	      Usage(progName); exit(0);
+	  }
+	  break;
+
 	case 'D': noDelay = PR_TRUE; break;
 
+	case 'P': certPrefix = PORT_Strdup(optstate->value); break;
+
         case 'b': bindOnly = PR_TRUE; break;
 
+	case 'd': dir = optstate->value; break;
+
+	case 'f':
+            pwdata.source = PW_FROMFILE;
+            pwdata.data = pwfile = PORT_Strdup(optstate->value);
+            break;
+
         case 'h': Usage(progName); exit(0); break;
 
 	case 'i': pidFile = optstate->value; break;
 
 	case 'p': port = PORT_Atoi(optstate->value); break;
 
 	case 't':
 	    maxThreads = PORT_Atoi(optstate->value);
 	    if ( maxThreads > MAX_THREADS ) maxThreads = MAX_THREADS;
 	    if ( maxThreads < MIN_THREADS ) maxThreads = MIN_THREADS;
 	    break;
 
 	case 'v': verbose++; break;
 
+	case 'w':
+            pwdata.source = PW_PLAINTEXT;
+            pwdata.data = passwd = PORT_Strdup(optstate->value);
+            break;
+
 	default:
 	case '?':
 	    fprintf(stderr, "Unrecognized or bad option specified.\n");
 	    fprintf(stderr, "Run '%s -h' for usage information.\n", progName);
 	    exit(4);
 	    break;
 	}
     }
@@ -819,17 +1237,17 @@ main(int argc, char **argv)
 	exit(5);
     }
     if (!optionsFound) {
 	Usage(progName);
 	exit(51);
     } 
 
     /* The -b (bindOnly) option is only used by the ssl.sh test
-     * script on Linux to determine whether a previous selfserv
+     * script on Linux to determine whether a previous httpserv
      * process has fully died and freed the port.  (Bug 129701)
      */
     if (bindOnly) {
         listen_sock = getBoundListenSocket(port);
         if (!listen_sock) {
             exit(1);
         }
         if (listen_sock) {
@@ -860,28 +1278,116 @@ main(int argc, char **argv)
     /* we're an ordinary single process server. */
     listen_sock = getBoundListenSocket(port);
     prStatus = PR_SetFDInheritable(listen_sock, PR_FALSE);
     if (prStatus != PR_SUCCESS)
         errExit("PR_SetFDInheritable");
 
     lm = PR_NewLogModule("TestCase");
 
+    /* set our password function */
+    PK11_SetPasswordFunc(SECU_GetModulePassword);
+
+    if (provideOcsp) {
+	/* Call the NSS initialization routines */
+	rv = NSS_Initialize(dir, certPrefix, certPrefix, SECMOD_DB, NSS_INIT_READONLY);
+	if (rv != SECSuccess) {
+	    fputs("NSS_Init failed.\n", stderr);
+		    exit(8);
+	}
+	
+	if (caRevoInfos) {
+	  caRevoIter = &caRevoInfos->link;
+	  do {
+	      PRFileDesc *inFile;
+	      int rv = SECFailure;
+	      SECItem crlDER;
+	      crlDER.data = NULL;
+
+	      revoInfo = (caRevoInfo*)caRevoIter;
+	      revoInfo->cert = CERT_FindCertByNickname(
+		  CERT_GetDefaultCertDB(), revoInfo->nickname);
+	      if (!revoInfo->cert) {
+		  fprintf(stderr, "cannot find cert with nickname %s\n",
+			  revoInfo->nickname);
+		  exit(1);
+	      }
+	      inFile = PR_Open(revoInfo->crlFilename, PR_RDONLY, 0);
+	      if (inFile) {
+		rv = SECU_ReadDERFromFile(&crlDER, inFile, PR_FALSE, PR_FALSE);
+	      }
+	      if (!inFile || rv != SECSuccess) {
+		  fprintf(stderr, "unable to read crl file %s\n",
+			  revoInfo->crlFilename);
+		  exit(1);
+	      }
+	      revoInfo->crl = 
+		  CERT_DecodeDERCrlWithFlags(NULL, &crlDER, SEC_CRL_TYPE,
+					     CRL_DECODE_DEFAULT_OPTIONS);
+	      if (!revoInfo->crl) {
+		  fprintf(stderr, "unable to decode crl file %s\n",
+			  revoInfo->crlFilename);
+		  exit(1);
+	      }
+	      if (CERT_CompareName(&revoInfo->crl->crl.name,
+				   &revoInfo->cert->subject) != SECEqual) {
+		  fprintf(stderr, "CRL %s doesn't match cert identified by preceding nickname %s\n",
+			  revoInfo->crlFilename, revoInfo->nickname);
+		  exit(1);
+	      }
+	      revoInfo->id = cert_CreateSelfCAID(revoInfo->cert, PR_Now());
+	      caRevoIter = PR_NEXT_LINK(caRevoIter);
+	  } while (caRevoIter != &caRevoInfos->link);
+	}
+    }
+
 /* allocate the array of thread slots, and launch the worker threads. */
     rv = launch_threads(&jobLoop, 0, 0, 0, useLocalThreads);
 
     if (rv == SECSuccess) {
 	server_main(listen_sock, 0, 0, 0,
                     0);
     }
 
-    VLOG(("selfserv: server_thread: exiting"));
+    VLOG(("httpserv: server_thread: exiting"));
+
+    if (provideOcsp) {
+	if (caRevoInfos) {
+	    PRCList *caRevoIter;
 
-    if (failedToNegotiateName) {
-        fprintf(stderr, "selfserv: Failed properly negotiate server name\n");
-        exit(1);
+	    caRevoIter = &caRevoInfos->link;
+	    do {
+		caRevoInfo *revoInfo = (caRevoInfo*)caRevoIter;
+		if (revoInfo->nickname)
+		    PORT_Free(revoInfo->nickname);
+		if (revoInfo->crlFilename)
+		    PORT_Free(revoInfo->crlFilename);
+		if (revoInfo->cert)
+		    CERT_DestroyCertificate(revoInfo->cert);
+		if (revoInfo->id)
+		    CERT_DestroyOCSPCertID(revoInfo->id);
+		if (revoInfo->crl)
+		    CERT_DestroyCrl(revoInfo->crl);
+		
+		caRevoIter = PR_NEXT_LINK(caRevoIter);
+	    } while (caRevoIter != &caRevoInfos->link);
+      
+	}
+	if (NSS_Shutdown() != SECSuccess) {
+	    SECU_PrintError(progName, "NSS_Shutdown");
+	    PR_Cleanup();
+	    exit(1);
+	}
     }
-
+    if (passwd) {
+        PORT_Free(passwd);
+    }
+    if (pwfile) {
+        PORT_Free(pwfile);
+    }
+    if (certPrefix && certPrefix != emptyString) {
+        PORT_Free(certPrefix);
+    }
     PR_Cleanup();
-    printf("selfserv: normal termination\n");
+    printf("httpserv: normal termination\n");
     return 0;
 }
 
--- a/security/nss/cmd/lib/secutil.c
+++ b/security/nss/cmd/lib/secutil.c
@@ -1448,16 +1448,28 @@ secu_PrintSubjectPublicKeyInfo(FILE *out
 	SECU_PrintErrMsg(out, level, "Error", "Parsing public key");
 loser:
 	if (i->subjectPublicKey.data) {
 	    SECU_PrintAny(out, &i->subjectPublicKey, "Raw", level);
 	}
     }
 }
 
+static void
+printStringWithoutCRLF(FILE *out, const char *str)
+{
+    const char *c = str;
+    while (*c) {
+	if (*c != '\r' && *c != '\n') {
+	    fputc(*c, out);
+	}
+	++c;
+    }
+}
+
 int
 SECU_PrintDumpDerIssuerAndSerial(FILE *out, SECItem *der, char *m,
                                  int level)
 {
     PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
     CERTCertificate *c;
     int rv = SEC_ERROR_NO_MEMORY;
     char *derIssuerB64;
@@ -1474,25 +1486,42 @@ SECU_PrintDumpDerIssuerAndSerial(FILE *o
     rv = SEC_ASN1DecodeItem(arena, c, 
                             SEC_ASN1_GET(CERT_CertificateTemplate), der);
     if (rv) {
         SECU_PrintErrMsg(out, 0, "Error", "Parsing extension");
         goto loser;
     }
 
     SECU_PrintName(out, &c->subject, "Subject", 0);
-    fprintf(out, "\n");
+    if (!SECU_GetWrapEnabled()) /*SECU_PrintName didn't add newline*/
+	SECU_Newline(out);
     SECU_PrintName(out, &c->issuer, "Issuer", 0);
-    fprintf(out, "\n");
+    if (!SECU_GetWrapEnabled()) /*SECU_PrintName didn't add newline*/
+	SECU_Newline(out);
     SECU_PrintInteger(out, &c->serialNumber, "Serial Number", 0);
     
     derIssuerB64 = BTOA_ConvertItemToAscii(&c->derIssuer);
     derSerialB64 = BTOA_ConvertItemToAscii(&c->serialNumber);
-    fprintf(out, "Issuer DER Base64:\n%s\n", derIssuerB64);
-    fprintf(out, "Serial DER Base64:\n%s\n", derSerialB64);
+
+    fprintf(out, "Issuer DER Base64:\n");
+    if (SECU_GetWrapEnabled()) {
+	fprintf(out, "%s\n", derIssuerB64);
+    } else {
+	printStringWithoutCRLF(out, derIssuerB64);
+	fputs("\n", out);
+    }
+
+    fprintf(out, "Serial DER Base64:\n");
+    if (SECU_GetWrapEnabled()) {
+	fprintf(out, "%s\n", derSerialB64);
+    } else {
+	printStringWithoutCRLF(out, derSerialB64);
+	fputs("\n", out);
+    }
+
     PORT_Free(derIssuerB64);
     PORT_Free(derSerialB64);
     
     fprintf(out, "Serial DER as C source: \n{ %d, \"", c->serialNumber.len);
 
     {
       int i;
       for (i=0; i < c->serialNumber.len; ++i) {
@@ -2288,16 +2317,18 @@ SECU_PrintCertificateRequest(FILE *out, 
                            SEC_ASN1_GET(CERT_CertificateRequestTemplate), der);
     if (rv) 
 	goto loser;
 
     /* Pretty print it out */
     SECU_Indent(out, level); fprintf(out, "%s:\n", m);
     SECU_PrintInteger(out, &cr->version, "Version", level+1);
     SECU_PrintName(out, &cr->subject, "Subject", level+1);
+    if (!SECU_GetWrapEnabled()) /*SECU_PrintName didn't add newline*/
+	SECU_Newline(out);
     secu_PrintSubjectPublicKeyInfo(out, arena, &cr->subjectPublicKeyInfo,
 			      "Subject Public Key Info", level+1);
     if (cr->attributes)
 	SECU_PrintCertAttributes(out, cr->attributes, "Attributes", level+1);
     rv = 0;
 loser:
     PORT_FreeArena(arena, PR_FALSE);
     return rv;
@@ -2330,18 +2361,22 @@ SECU_PrintCertificate(FILE *out, const S
     /* Pretty print it out */
     SECU_Indent(out, level); fprintf(out, "%s:\n", m);
     iv = c->version.len ? DER_GetInteger(&c->version) : 0;  /* version is optional */
     SECU_Indent(out, level+1); fprintf(out, "%s: %d (0x%x)\n", "Version", iv + 1, iv);
 
     SECU_PrintInteger(out, &c->serialNumber, "Serial Number", level+1);
     SECU_PrintAlgorithmID(out, &c->signature, "Signature Algorithm", level+1);
     SECU_PrintName(out, &c->issuer, "Issuer", level+1);
+    if (!SECU_GetWrapEnabled()) /*SECU_PrintName didn't add newline*/
+	SECU_Newline(out);
     secu_PrintValidity(out, &c->validity, "Validity", level+1);
     SECU_PrintName(out, &c->subject, "Subject", level+1);
+    if (!SECU_GetWrapEnabled()) /*SECU_PrintName didn't add newline*/
+	SECU_Newline(out);
     secu_PrintSubjectPublicKeyInfo(out, arena, &c->subjectPublicKeyInfo,
 			      "Subject Public Key Info", level+1);
     if (c->issuerID.data) 
 	secu_PrintDecodedBitString(out, &c->issuerID, "Issuer Unique ID", level+1);
     if (c->subjectID.data) 
 	secu_PrintDecodedBitString(out, &c->subjectID, "Subject Unique ID", level+1);
     SECU_PrintExtensions(out, c->extensions, "Signed Extensions", level+1);
 loser:
@@ -3005,16 +3040,18 @@ int SECU_PrintDERName(FILE *out, SECItem
     if (!name)
 	goto loser;
 
     rv = SEC_ASN1DecodeItem(arena, name, SEC_ASN1_GET(CERT_NameTemplate), der);
     if (rv)
 	goto loser;
 
     SECU_PrintName(out, name, m, level);
+    if (!SECU_GetWrapEnabled()) /*SECU_PrintName didn't add newline*/
+	SECU_Newline(out);
 loser:
     PORT_FreeArena(arena, PR_FALSE);
     return rv;
 }
 
 typedef enum  {
     noSignature = 0,
     withSignature = 1
--- a/security/nss/cmd/modutil/install-ds.c
+++ b/security/nss/cmd/modutil/install-ds.c
@@ -209,23 +209,24 @@ Pk11Install_File_Generate(Pk11Install_Fi
 				Pk11Install_ListIter_delete(subiter);
 				subiter = NULL;
 
 			/* file permissions */
 			} else if( !PORT_Strcasecmp(subpair->key,
                                      FILE_PERMISSIONS_STRING)) {
 				subiter = Pk11Install_ListIter_new(subpair->list);
 				subval = subiter->current;
-				if(!subval || (subval->type != STRING_VALUE)){
+				if(!subval || (subval->type != STRING_VALUE) ||
+				   !subval->string || !subval->string[0]){
 					errStr = PR_smprintf(errString[BOGUS_FILE_PERMISSIONS],
                                     _this->jarPath);
 					goto loser;
 				}
 				_this->permissions = (int) strtol(subval->string, &endp, 8);
-				if(*endp != '\0' || subval->string == "\0") {
+				if(*endp != '\0') {
 					errStr = PR_smprintf(errString[BOGUS_FILE_PERMISSIONS],
                                     _this->jarPath);
 					goto loser;
 				}
 				gotPerms = PR_TRUE;
 				Pk11Install_ListIter_delete(subiter);
 				subiter = NULL;
 			}
--- a/security/nss/cmd/pp/pp.c
+++ b/security/nss/cmd/pp/pp.c
@@ -17,51 +17,54 @@ extern int fprintf(FILE *, char *, ...);
 
 #include "pk11func.h"
 #include "nspr.h"
 #include "nss.h"
 
 static void Usage(char *progName)
 {
     fprintf(stderr,
-	    "Usage:  %s -t type [-a] [-i input] [-o output]\n",
+	    "Usage:  %s -t type [-a] [-i input] [-o output] [-w]\n",
 	    progName);
     fprintf(stderr, "%-20s Specify the input type (must be one of %s,\n",
 	    "-t type", SEC_CT_PRIVATE_KEY);
     fprintf(stderr, "%-20s %s, %s, %s,\n", "", SEC_CT_PUBLIC_KEY,
 	    SEC_CT_CERTIFICATE, SEC_CT_CERTIFICATE_REQUEST);
     fprintf(stderr, "%-20s %s, %s, %s or %s)\n", "", SEC_CT_CERTIFICATE_ID,
             SEC_CT_PKCS7, SEC_CT_CRL, SEC_CT_NAME);
     fprintf(stderr, "%-20s Input is in ascii encoded form (RFC1113)\n",
 	    "-a");
     fprintf(stderr, "%-20s Define an input file to use (default is stdin)\n",
 	    "-i input");
     fprintf(stderr, "%-20s Define an output file to use (default is stdout)\n",
 	    "-o output");
+    fprintf(stderr, "%-20s Don't wrap long output lines\n",
+	    "-w");
     exit(-1);
 }
 
 int main(int argc, char **argv)
 {
     int rv, ascii;
     char *progName;
     FILE *outFile;
     PRFileDesc *inFile;
     SECItem der, data;
     char *typeTag;
     PLOptState *optstate;
+    PRBool wrap = PR_TRUE;
 
     progName = strrchr(argv[0], '/');
     progName = progName ? progName+1 : argv[0];
 
     ascii = 0;
     inFile = 0;
     outFile = 0;
     typeTag = 0;
-    optstate = PL_CreateOptState(argc, argv, "at:i:o:");
+    optstate = PL_CreateOptState(argc, argv, "at:i:o:w");
     while ( PL_GetNextOpt(optstate) == PL_OPT_OK ) {
 	switch (optstate->option) {
 	  case '?':
 	    Usage(progName);
 	    break;
 
 	  case 'a':
 	    ascii = 1;
@@ -83,16 +86,20 @@ int main(int argc, char **argv)
 			progName, optstate->value);
 		return -1;
 	    }
 	    break;
 
 	  case 't':
 	    typeTag = strdup(optstate->value);
 	    break;
+
+	  case 'w':
+	    wrap = PR_FALSE;
+	    break;
 	}
     }
     PL_DestroyOptState(optstate);
     if (!typeTag) Usage(progName);
 
     if (!inFile) inFile = PR_STDIN;
     if (!outFile) outFile = stdout;
 
@@ -110,26 +117,25 @@ int main(int argc, char **argv)
 	fprintf(stderr, "%s: SECU_ReadDERFromFile failed\n", progName);
 	exit(1);
     }
 
     /* Data is untyped, using the specified type */
     data.data = der.data;
     data.len = der.len;
 
+    SECU_EnableWrap(wrap);
+
     /* Pretty print it */
     if (PORT_Strcmp(typeTag, SEC_CT_CERTIFICATE) == 0) {
 	rv = SECU_PrintSignedData(outFile, &data, "Certificate", 0,
 			     SECU_PrintCertificate);
     } else if (PORT_Strcmp(typeTag, SEC_CT_CERTIFICATE_ID) == 0) {
-        PRBool saveWrapeState = SECU_GetWrapEnabled();
-        SECU_EnableWrap(PR_FALSE);
         rv = SECU_PrintSignedContent(outFile, &data, 0, 0,
                                      SECU_PrintDumpDerIssuerAndSerial);
-        SECU_EnableWrap(saveWrapeState);
     } else if (PORT_Strcmp(typeTag, SEC_CT_CERTIFICATE_REQUEST) == 0) {
 	rv = SECU_PrintSignedData(outFile, &data, "Certificate Request", 0,
 			     SECU_PrintCertificateRequest);
     } else if (PORT_Strcmp (typeTag, SEC_CT_CRL) == 0) {
 	rv = SECU_PrintSignedData (outFile, &data, "CRL", 0, SECU_PrintCrl);
 #ifdef HAVE_EPV_TEMPLATE
     } else if (PORT_Strcmp(typeTag, SEC_CT_PRIVATE_KEY) == 0) {
 	rv = SECU_PrintPrivateKey(outFile, &data, "Private Key", 0);
--- a/security/nss/cmd/tstclnt/tstclnt.c
+++ b/security/nss/cmd/tstclnt/tstclnt.c
@@ -523,22 +523,23 @@ ownAuthCertificate(void *arg, PRFileDesc
         cert = SSL_RevealCert(fd);
         if (!cert) {
             exit(254);
         }
 
         csa = SSL_PeerStapledOCSPResponses(fd);
         if (csa) {
             for (i = 0; i < csa->len; ++i) {
-                CERT_CacheOCSPResponseFromSideChannel(
-                    serverCertAuth->dbHandle,
-                    cert,
-                    PR_Now(),
-                    &csa->items[i],
-                    arg);
+		PORT_SetError(0);
+		if (CERT_CacheOCSPResponseFromSideChannel(
+			serverCertAuth->dbHandle, cert, PR_Now(),
+			&csa->items[i], arg) != SECSuccess) {
+		    PRErrorCode error = PR_GetError();
+		    PORT_Assert(error != 0);
+		}
             }
         }
     
         verifyFromSideChannel(cert, serverCertAuth);
         CERT_DestroyCertificate(cert);
         /* return success to ensure our caller will continue and we will 
          * reach the code that handles 
          * serverCertAuth->sideChannelRevocationTestResultCode
@@ -746,41 +747,41 @@ separateReqHeader(const PRFileDesc* outF
     }
 
 static SECStatus
 restartHandshakeAfterServerCertIfNeeded(PRFileDesc * fd,
                                         ServerCertAuth * serverCertAuth,
                                         PRBool override)
 {
     SECStatus rv;
-    PRErrorCode status;
+    PRErrorCode error;
     
     if (!serverCertAuth->isPaused)
 	return SECSuccess;
     
     FPRINTF(stderr, "%s: handshake was paused by auth certificate hook\n",
             progName);
 
     serverCertAuth->isPaused = PR_FALSE;
     rv = SSL_AuthCertificate(serverCertAuth->dbHandle, fd, PR_TRUE, PR_FALSE);
     if (rv != SECSuccess) {
-        status = PR_GetError();
-        if (status == 0) {
+        error = PR_GetError();
+        if (error == 0) {
             PR_NOT_REACHED("SSL_AuthCertificate return SECFailure without "
                            "setting error code.");
-            status = PR_INVALID_STATE_ERROR;
+            error = PR_INVALID_STATE_ERROR;
         } else if (override) {
             rv = ownBadCertHandler(NULL, fd);
         }
     }
     if (rv == SECSuccess) {
-        status = 0;
+        error = 0;
     }
 
-    if (SSL_AuthCertificateComplete(fd, status) != SECSuccess) {
+    if (SSL_AuthCertificateComplete(fd, error) != SECSuccess) {
         rv = SECFailure;
     }
 
     return rv;
 }
     
 int main(int argc, char **argv)
 {
--- a/security/nss/coreconf/coreconf.dep
+++ b/security/nss/coreconf/coreconf.dep
@@ -5,9 +5,8 @@
 
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSS in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
-
--- a/security/nss/coreconf/nsinstall/pathsub.c
+++ b/security/nss/coreconf/nsinstall/pathsub.c
@@ -235,17 +235,17 @@ diagnosePath(const char * path)
     myPath = strdup(path);
     if (!myPath)
 	fail("strdup() failed!");
     do {
     	rv = lstat(myPath, &sb);
 	if (rv < 0) {
 	    perror(myPath);
 	} else if (S_ISLNK(sb.st_mode)) {
-	    rv = readlink(myPath, buf, sizeof buf);
+	    rv = readlink(myPath, buf, sizeof(buf) - 1);
 	    if (rv < 0) {
 	    	perror("readlink");
 		buf[0] = 0;
 	    } else {
 	    	buf[rv] = 0;
 	    }
 	    fprintf(stderr, "%s is a link to %s\n", myPath, buf);
 	} else if (S_ISDIR(sb.st_mode)) {
--- a/security/nss/doc/certutil.xml
+++ b/security/nss/doc/certutil.xml
@@ -204,16 +204,21 @@ If this option is not used, the validity
       </varlistentry>
 
       <varlistentry>
         <term>-e </term>
         <listitem><para>Check a certificate's signature during the process of validating a certificate.</para></listitem>
       </varlistentry>
 
       <varlistentry>
+        <term>--email email-address</term>
+        <listitem><para>Specify the email address of a certificate to list. Used with the -L command option.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term>-f password-file</term>
         <listitem><para>Specify a file that will automatically supply the password to include in a certificate 
  or to access a certificate database. This is a plain-text file containing one password. Be sure to prevent 
  unauthorized access to this file.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         <term>-g keysize</term>
@@ -639,24 +644,29 @@ of the attribute codes:
       </varlistentry>
 
       <varlistentry>
         <term>--extNC</term>
         <listitem><para>Add a Name Constraint extension to the certificate. X.509 certificate extensions are described in RFC 5280.</para></listitem>
       </varlistentry>
 
       <varlistentry>
+        <term>--empty-password</term>
+        <listitem><para>Use empty password when creating new certificate database with -N.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term>--keyAttrFlags attrflags</term>
         <listitem><para>
 PKCS #11 key Attributes. Comma separated list of key attribute flags, selected from the following list of choices: {token | session} {public | private} {sensitive | insensitive} {modifiable | unmodifiable} {extractable | unextractable}</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term>--keyFlagsOn opflags</term>
-        <term>--keyFlagsOff opflags</term>
+        <term>--keyOpFlagsOn opflags</term>
+        <term>--keyOpFlagsOff opflags</term>
         <listitem><para>
 PKCS #11 key Operation Flags.
 Comma separated list of one or more of the following:
 {token | session} {public | private} {sensitive | insensitive} {modifiable | unmodifiable} {extractable | unextractable}
           </para></listitem>
       </varlistentry>
 
       <varlistentry>
--- a/security/nss/doc/html/certutil.html
+++ b/security/nss/doc/html/certutil.html
@@ -1,21 +1,21 @@
-<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>CERTUTIL</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="CERTUTIL"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">CERTUTIL</th></tr></table><hr></div><div class="refentry"><a name="certutil"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>certutil — Manage keys and certificate in both NSS databases and other NSS tokens</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">certutil</code>  [<em class="replaceable"><code>options</code></em>] [[<em class="replaceable"><code>arguments</code></em>]]</p></div></div><div class="refsection"><a name="idm207694846832"></a><h2>STATUS</h2><p>This documentation is still work in progress. Please contribute to the initial review in <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836477" target="_top">Mozilla NSS bug 836477</a>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>CERTUTIL</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="CERTUTIL"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">CERTUTIL</th></tr></table><hr></div><div class="refentry"><a name="certutil"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>certutil — Manage keys and certificate in both NSS databases and other NSS tokens</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">certutil</code>  [<em class="replaceable"><code>options</code></em>] [[<em class="replaceable"><code>arguments</code></em>]]</p></div></div><div class="refsection"><a name="idm224672048528"></a><h2>STATUS</h2><p>This documentation is still work in progress. Please contribute to the initial review in <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836477" target="_top">Mozilla NSS bug 836477</a>
     </p></div><div class="refsection"><a name="description"></a><h2>Description</h2><p>The Certificate Database Tool, <span class="command"><strong>certutil</strong></span>, is a command-line utility that can create and modify certificate and key databases. It can specifically list, generate, modify, or delete certificates, create or change the password, generate new public and private key pairs, display the contents of the key database, or delete key pairs within the key database.</p><p>Certificate issuance, part of the key and certificate management process, requires that keys and certificates be created in the key database. This document discusses certificate and key database management. For information on the security module database management, see the <span class="command"><strong>modutil</strong></span> manpage.</p></div><div class="refsection"><a name="options"></a><h2>Command Options and Arguments</h2><p>Running <span class="command"><strong>certutil</strong></span> always requires one and only one command option to specify the type of certificate operation. Each command option may take zero or more arguments. The command option <code class="option">-H</code> will list all the command options and their relevant arguments.</p><p><span class="command"><strong>Command Options</strong></span></p><div class="variablelist"><dl class="variablelist"><dt><span class="term">-A </span></dt><dd><p>Add an existing certificate to a certificate database. The certificate database should already exist; if one is not present, this command option will initialize one by default.</p></dd><dt><span class="term">-B</span></dt><dd><p>Run a series of commands from the specified batch file. This requires the <code class="option">-i</code> argument.</p></dd><dt><span class="term">-C </span></dt><dd><p>Create a new binary certificate file from a binary certificate request file. Use the <code class="option">-i</code> argument to specify the certificate request file. If this argument is not used, <span class="command"><strong>certutil</strong></span> prompts for a filename. </p></dd><dt><span class="term">-D </span></dt><dd><p>Delete a certificate from the certificate database.</p></dd><dt><span class="term">-E </span></dt><dd><p>Add an email certificate to the certificate database.</p></dd><dt><span class="term">-F</span></dt><dd><p>Delete a private key from a key database. Specify the key to delete with the -n argument. Specify the database from which to delete the key with the 
 <code class="option">-d</code> argument. Use the <code class="option">-k</code> argument to specify explicitly whether to delete a DSA, RSA, or ECC key. If you don't use the <code class="option">-k</code> argument, the option looks for an RSA key matching the specified nickname. 
 </p><p>
 When you delete keys, be sure to also remove any certificates associated with those keys from the certificate database, by using -D. Some smart cards do not let you remove a public key you have generated. In such a case, only the private key is deleted from the key pair. You can display the public key with the command certutil -K -h tokenname. </p></dd><dt><span class="term">-G </span></dt><dd><p>Generate a new public and private key pair within a key database. The key database should already exist; if one is not present, this command option will initialize one by default. Some smart cards can store only one key pair. If you create a new key pair for such a card, the previous pair is overwritten.</p></dd><dt><span class="term">-H </span></dt><dd><p>Display a list of the command options and arguments.</p></dd><dt><span class="term">-K </span></dt><dd><p>List the key ID of keys in the key database. A key ID is the modulus of the RSA key or the publicValue of the DSA key. IDs are displayed in hexadecimal ("0x" is not shown).</p></dd><dt><span class="term">-L </span></dt><dd><p>List all the certificates, or display information about a named certificate, in a certificate database.
 Use the -h tokenname argument to specify the certificate database on a particular hardware or software token.</p></dd><dt><span class="term">-M </span></dt><dd><p>Modify a certificate's trust attributes using the values of the -t argument.</p></dd><dt><span class="term">-N</span></dt><dd><p>Create new certificate and key databases.</p></dd><dt><span class="term">-O </span></dt><dd><p>Print the certificate chain.</p></dd><dt><span class="term">-R</span></dt><dd><p>Create a certificate request file that can be submitted to a Certificate Authority (CA) for processing into a finished certificate. Output defaults to standard out unless you use -o output-file argument.
 
 Use the -a argument to specify ASCII output.</p></dd><dt><span class="term">-S </span></dt><dd><p>Create an individual certificate and add it to a certificate database.</p></dd><dt><span class="term">-T </span></dt><dd><p>Reset the key database or token.</p></dd><dt><span class="term">-U </span></dt><dd><p>List all available modules or print a single named module.</p></dd><dt><span class="term">-V </span></dt><dd><p>Check the validity of a certificate and its attributes.</p></dd><dt><span class="term">-W </span></dt><dd><p>Change the password to a key database.</p></dd><dt><span class="term">--merge</span></dt><dd><p>Merge two databases into one.</p></dd><dt><span class="term">--upgrade-merge</span></dt><dd><p>Upgrade an old database and merge it into a new database. This is used to migrate legacy NSS databases (<code class="filename">cert8.db</code> and <code class="filename">key3.db</code>) into the newer SQLite databases (<code class="filename">cert9.db</code> and <code class="filename">key4.db</code>).</p></dd></dl></div><p><span class="command"><strong>Arguments</strong></span></p><p>Arguments modify a command option and are usually lower case, numbers, or symbols.</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">-a</span></dt><dd><p>Use ASCII format or allow the use of ASCII format for input or output. This formatting follows RFC 1113. 
 For certificate requests, ASCII output defaults to standard output unless redirected.</p></dd><dt><span class="term">-b validity-time</span></dt><dd><p>Specify a time at which a certificate is required to be valid. Use when checking certificate validity with the <code class="option">-V</code> option. The format of the <span class="emphasis"><em>validity-time</em></span> argument is <span class="emphasis"><em>YYMMDDHHMMSS[+HHMM|-HHMM|Z]</em></span>, which allows offsets to be set relative to the validity end time. Specifying seconds (<span class="emphasis"><em>SS</em></span>) is optional. When specifying an explicit time, use a Z at the end of the term, <span class="emphasis"><em>YYMMDDHHMMSSZ</em></span>, to close it. When specifying an offset time, use <span class="emphasis"><em>YYMMDDHHMMSS+HHMM</em></span> or <span class="emphasis"><em>YYMMDDHHMMSS-HHMM</em></span> for adding or subtracting time, respectively.
 </p><p>
 If this option is not used, the validity check defaults to the current system time.</p></dd><dt><span class="term">-c issuer</span></dt><dd><p>Identify the certificate of the CA from which a new certificate will derive its authenticity. 
  Use the exact nickname or alias of the CA certificate, or use the CA's email address. Bracket the issuer string 
- with quotation marks if it contains spaces. </p></dd><dt><span class="term">-d [prefix]directory</span></dt><dd><p>Specify the database directory containing the certificate and key database files.</p><p><span class="command"><strong>certutil</strong></span> supports two types of databases: the legacy security databases (<code class="filename">cert8.db</code>, <code class="filename">key3.db</code>, and <code class="filename">secmod.db</code>) and new SQLite databases (<code class="filename">cert9.db</code>, <code class="filename">key4.db</code>, and <code class="filename">pkcs11.txt</code>). </p><p>NSS recognizes the following prefixes:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><span class="command"><strong>sql: requests the newer database</strong></span></p></li><li class="listitem"><p><span class="command"><strong>dbm: requests the legacy database</strong></span></p></li></ul></div><p>If no prefix is specified the default type is retrieved from NSS_DEFAULT_DB_TYPE. If NSS_DEFAULT_DB_TYPE is not set then dbm: is the default.</p></dd><dt><span class="term">-e </span></dt><dd><p>Check a certificate's signature during the process of validating a certificate.</p></dd><dt><span class="term">-f password-file</span></dt><dd><p>Specify a file that will automatically supply the password to include in a certificate 
+ with quotation marks if it contains spaces. </p></dd><dt><span class="term">-d [prefix]directory</span></dt><dd><p>Specify the database directory containing the certificate and key database files.</p><p><span class="command"><strong>certutil</strong></span> supports two types of databases: the legacy security databases (<code class="filename">cert8.db</code>, <code class="filename">key3.db</code>, and <code class="filename">secmod.db</code>) and new SQLite databases (<code class="filename">cert9.db</code>, <code class="filename">key4.db</code>, and <code class="filename">pkcs11.txt</code>). </p><p>NSS recognizes the following prefixes:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><span class="command"><strong>sql: requests the newer database</strong></span></p></li><li class="listitem"><p><span class="command"><strong>dbm: requests the legacy database</strong></span></p></li></ul></div><p>If no prefix is specified the default type is retrieved from NSS_DEFAULT_DB_TYPE. If NSS_DEFAULT_DB_TYPE is not set then dbm: is the default.</p></dd><dt><span class="term">-e </span></dt><dd><p>Check a certificate's signature during the process of validating a certificate.</p></dd><dt><span class="term">--email email-address</span></dt><dd><p>Specify the email address of a certificate to list. Used with the -L command option.</p></dd><dt><span class="term">-f password-file</span></dt><dd><p>Specify a file that will automatically supply the password to include in a certificate 
  or to access a certificate database. This is a plain-text file containing one password. Be sure to prevent 
  unauthorized access to this file.</p></dd><dt><span class="term">-g keysize</span></dt><dd><p>Set a key size to use when generating new public and private key pairs. The minimum is 512 bits and the maximum is 8192 bits. The default is 1024 bits. Any size between the minimum and maximum is allowed.</p></dd><dt><span class="term">-h tokenname</span></dt><dd><p>Specify the name of a token to use or act on. If not specified the default token is the internal database slot.</p></dd><dt><span class="term">-i input_file</span></dt><dd><p>Pass an input file to the command. Depending on the command option, an input file can be a specific certificate, a certificate request file, or a batch file of commands.</p></dd><dt><span class="term">-k key-type-or-id</span></dt><dd><p>Specify the type or specific ID of a key.</p><p>
            The valid key type options are rsa, dsa, ec, or all. The default 
            value is rsa. Specifying the type of key can avoid mistakes caused by
            duplicate nicknames. Giving a key type generates a new key pair; 
            giving the ID of an existing key reuses that key pair (which is 
            required to renew certificates).
           </p></dd><dt><span class="term">-l </span></dt><dd><p>Display detailed information when validating a certificate with the -V option.</p></dd><dt><span class="term">-m serial-number</span></dt><dd><p>Assign a unique serial number to a certificate being created. This operation should be performed by a CA. If no serial number is provided a default serial number is made from the current time. Serial numbers are limited to integers </p></dd><dt><span class="term">-n nickname</span></dt><dd><p>Specify the nickname of a certificate or key to list, create, add to a database, modify, or validate. Bracket the nickname string with quotation marks if it contains spaces.</p></dd><dt><span class="term">-o output-file</span></dt><dd><p>Specify the output file name for new certificates or binary certificate requests. Bracket the output-file string with quotation marks if it contains spaces. If this argument is not used the output destination defaults to standard output.</p></dd><dt><span class="term">-P dbPrefix</span></dt><dd><p>Specify the prefix used on the certificate and key database file. This argument is provided to support legacy servers. Most applications do not use a database prefix.</p></dd><dt><span class="term">-p phone</span></dt><dd><p>Specify a contact telephone number to include in new certificates or certificate requests. Bracket this string with quotation marks if it contains spaces.</p></dd><dt><span class="term">-q pqgfile or curve-name</span></dt><dd><p>Read an alternate PQG value from the specified file when generating DSA key pairs. If this argument is not used, <span class="command"><strong>certutil</strong></span> generates its own PQG value. PQG files are created with a separate DSA utility.</p><p>Elliptic curve name is one of the ones from SUITE B: nistp256, nistp384, nistp521</p><p>
@@ -104,18 +104,18 @@ of the attribute codes:
 	</p></li><li class="listitem"><p>
 		ocspResponder
 	</p></li><li class="listitem"><p>
 		stepUp
 	</p></li><li class="listitem"><p>
 		msTrustListSign
 	</p></li><li class="listitem"><p>
 		critical
-	</p></li></ul></div><p>X.509 certificate extensions are described in RFC 5280.</p></dd><dt><span class="term">-7 emailAddrs</span></dt><dd><p>Add a comma-separated list of email addresses to the subject alternative name extension of a certificate or certificate request that is being created or added to the database. Subject alternative name extensions are described in Section 4.2.1.7 of RFC 3280.</p></dd><dt><span class="term">-8 dns-names</span></dt><dd><p>Add a comma-separated list of DNS names to the subject alternative name extension of a certificate or certificate request that is being created or added to the database. Subject alternative name extensions are described in Section 4.2.1.7 of RFC 3280.</p></dd><dt><span class="term">--extAIA</span></dt><dd><p>Add the Authority Information Access extension to the certificate. X.509 certificate extensions are described in RFC 5280.</p></dd><dt><span class="term">--extSIA</span></dt><dd><p>Add the Subject Information Access extension to the certificate. X.509 certificate extensions are described in RFC 5280.</p></dd><dt><span class="term">--extCP</span></dt><dd><p>Add the Certificate Policies extension to the certificate. X.509 certificate extensions are described in RFC 5280.</p></dd><dt><span class="term">--extPM</span></dt><dd><p>Add the Policy Mappings extension to the certificate. X.509 certificate extensions are described in RFC 5280.</p></dd><dt><span class="term">--extPC</span></dt><dd><p>Add the Policy Constraints extension to the certificate. X.509 certificate extensions are described in RFC 5280.</p></dd><dt><span class="term">--extIA</span></dt><dd><p>Add the Inhibit Any Policy Access extension to the certificate. X.509 certificate extensions are described in RFC 5280.</p></dd><dt><span class="term">--extSKID</span></dt><dd><p>Add the Subject Key ID extension to the certificate. X.509 certificate extensions are described in RFC 5280.</p></dd><dt><span class="term">--extNC</span></dt><dd><p>Add a Name Constraint extension to the certificate. X.509 certificate extensions are described in RFC 5280.</p></dd><dt><span class="term">--keyAttrFlags attrflags</span></dt><dd><p>
-PKCS #11 key Attributes. Comma separated list of key attribute flags, selected from the following list of choices: {token | session} {public | private} {sensitive | insensitive} {modifiable | unmodifiable} {extractable | unextractable}</p></dd><dt><span class="term">--keyFlagsOn opflags, </span><span class="term">--keyFlagsOff opflags</span></dt><dd><p>
+	</p></li></ul></div><p>X.509 certificate extensions are described in RFC 5280.</p></dd><dt><span class="term">-7 emailAddrs</span></dt><dd><p>Add a comma-separated list of email addresses to the subject alternative name extension of a certificate or certificate request that is being created or added to the database. Subject alternative name extensions are described in Section 4.2.1.7 of RFC 3280.</p></dd><dt><span class="term">-8 dns-names</span></dt><dd><p>Add a comma-separated list of DNS names to the subject alternative name extension of a certificate or certificate request that is being created or added to the database. Subject alternative name extensions are described in Section 4.2.1.7 of RFC 3280.</p></dd><dt><span class="term">--extAIA</span></dt><dd><p>Add the Authority Information Access extension to the certificate. X.509 certificate extensions are described in RFC 5280.</p></dd><dt><span class="term">--extSIA</span></dt><dd><p>Add the Subject Information Access extension to the certificate. X.509 certificate extensions are described in RFC 5280.</p></dd><dt><span class="term">--extCP</span></dt><dd><p>Add the Certificate Policies extension to the certificate. X.509 certificate extensions are described in RFC 5280.</p></dd><dt><span class="term">--extPM</span></dt><dd><p>Add the Policy Mappings extension to the certificate. X.509 certificate extensions are described in RFC 5280.</p></dd><dt><span class="term">--extPC</span></dt><dd><p>Add the Policy Constraints extension to the certificate. X.509 certificate extensions are described in RFC 5280.</p></dd><dt><span class="term">--extIA</span></dt><dd><p>Add the Inhibit Any Policy Access extension to the certificate. X.509 certificate extensions are described in RFC 5280.</p></dd><dt><span class="term">--extSKID</span></dt><dd><p>Add the Subject Key ID extension to the certificate. X.509 certificate extensions are described in RFC 5280.</p></dd><dt><span class="term">--extNC</span></dt><dd><p>Add a Name Constraint extension to the certificate. X.509 certificate extensions are described in RFC 5280.</p></dd><dt><span class="term">--empty-password</span></dt><dd><p>Use empty password when creating new certificate database with -N.</p></dd><dt><span class="term">--keyAttrFlags attrflags</span></dt><dd><p>
+PKCS #11 key Attributes. Comma separated list of key attribute flags, selected from the following list of choices: {token | session} {public | private} {sensitive | insensitive} {modifiable | unmodifiable} {extractable | unextractable}</p></dd><dt><span class="term">--keyOpFlagsOn opflags, </span><span class="term">--keyOpFlagsOff opflags</span></dt><dd><p>
 PKCS #11 key Operation Flags.
 Comma separated list of one or more of the following:
 {token | session} {public | private} {sensitive | insensitive} {modifiable | unmodifiable} {extractable | unextractable}
           </p></dd><dt><span class="term">--source-dir certdir</span></dt><dd><p>Identify the certificate database directory to upgrade.</p></dd><dt><span class="term">--source-prefix certdir</span></dt><dd><p>Give the prefix of the certificate and key databases to upgrade.</p></dd><dt><span class="term">--upgrade-id uniqueID</span></dt><dd><p>Give the unique ID of the database to upgrade.</p></dd><dt><span class="term">--upgrade-token-name name</span></dt><dd><p>Set the name of the token to use while it is being upgraded.</p></dd><dt><span class="term">-@ pwfile</span></dt><dd><p>Give the name of a password file to use for the database being upgraded.</p></dd></dl></div></div><div class="refsection"><a name="basic-usage"></a><h2>Usage and Examples</h2><p>
 		Most of the command options in the examples listed here have more arguments available. The arguments included in these examples are the most common ones or are used to illustrate a specific scenario. Use the <code class="option">-H</code> option to show the complete list of arguments for each command option.
 	</p><p><span class="command"><strong>Creating New Security Databases</strong></span></p><p>
 		Certificates, keys, and security modules related to managing certificates are stored in three related databases:
 	</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
--- a/security/nss/doc/html/modutil.html
+++ b/security/nss/doc/html/modutil.html
@@ -1,9 +1,9 @@
-<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>MODUTIL</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="MODUTIL"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">MODUTIL</th></tr></table><hr></div><div class="refentry"><a name="modutil"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>modutil — Manage PKCS #11 module information within the security module database.</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">modutil</code>  [<em class="replaceable"><code>options</code></em>] [[<em class="replaceable"><code>arguments</code></em>]]</p></div></div><div class="refsection"><a name="idm207698456864"></a><h2>STATUS</h2><p>This documentation is still work in progress. Please contribute to the initial review in <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836477" target="_top">Mozilla NSS bug 836477</a>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>MODUTIL</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="MODUTIL"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">MODUTIL</th></tr></table><hr></div><div class="refentry"><a name="modutil"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>modutil — Manage PKCS #11 module information within the security module database.</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">modutil</code>  [<em class="replaceable"><code>options</code></em>] [[<em class="replaceable"><code>arguments</code></em>]]</p></div></div><div class="refsection"><a name="idm224666099264"></a><h2>STATUS</h2><p>This documentation is still work in progress. Please contribute to the initial review in <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836477" target="_top">Mozilla NSS bug 836477</a>
     </p></div><div class="refsection"><a name="description"></a><h2>Description</h2><p>The Security Module Database Tool, <span class="command"><strong>modutil</strong></span>, is a command-line utility for managing PKCS #11 module information both within <code class="filename">secmod.db</code> files and within hardware tokens. <span class="command"><strong>modutil</strong></span> can add and delete PKCS #11 modules, change passwords on security databases, set defaults, list module contents, enable or disable slots, enable or disable FIPS 140-2 compliance, and assign default providers for cryptographic operations. This tool can also create certificate, key, and module security database files.</p><p>The tasks associated with security module database management are part of a process that typically also involves managing key databases and certificate databases.</p></div><div class="refsection"><a name="options"></a><h2>Options</h2><p>
 		Running <span class="command"><strong>modutil</strong></span> always requires one (and only one) option to specify the type of module operation. Each option may take arguments, anywhere from none to multiple arguments.
 	</p><p><span class="command"><strong>Options</strong></span></p><div class="variablelist"><dl class="variablelist"><dt><span class="term">-add modulename</span></dt><dd><p>Add the named PKCS #11 module to the database. Use this option with the <code class="option">-libfile</code>, <code class="option">-ciphers</code>, and <code class="option">-mechanisms</code> arguments.</p></dd><dt><span class="term">-changepw tokenname</span></dt><dd><p>Change the password on the named token. If the token has not been initialized, this option initializes the password. Use this option with the <code class="option">-pwfile</code> and <code class="option">-newpwfile</code> arguments. A <span class="emphasis"><em>password</em></span> is equivalent to a personal identification number (PIN).</p></dd><dt><span class="term">-chkfips</span></dt><dd><p>Verify whether the module is in the given FIPS mode. <span class="command"><strong>true</strong></span> means to verify that the module is in FIPS mode, while <span class="command"><strong>false</strong></span> means to verify that the module is not in FIPS mode.</p></dd><dt><span class="term">-create</span></dt><dd><p>Create new certificate, key, and module databases. Use the <code class="option">-dbdir</code> directory argument to specify a directory. If any of these databases already exist in a specified directory, <span class="command"><strong>modutil</strong></span> returns an error message.</p></dd><dt><span class="term">-default modulename</span></dt><dd><p>Specify the security mechanisms for which the named module will be a default provider. The security mechanisms are specified with the <code class="option">-mechanisms</code> argument.</p></dd><dt><span class="term">-delete modulename</span></dt><dd><p>Delete the named module. The default NSS PKCS #11 module cannot be deleted.</p></dd><dt><span class="term">-disable modulename</span></dt><dd><p>Disable all slots on the named module. Use the <code class="option">-slot</code> argument to disable a specific slot.</p></dd><dt><span class="term">-enable modulename</span></dt><dd><p>Enable all slots on the named module. Use the <code class="option">-slot</code> argument to enable a specific slot.</p></dd><dt><span class="term">-fips [true | false]</span></dt><dd><p>Enable (true) or disable (false) FIPS 140-2 compliance for the default NSS module.</p></dd><dt><span class="term">-force</span></dt><dd><p>Disable <span class="command"><strong>modutil</strong></span>'s interactive prompts so it can be run from a script. Use this option only after manually testing each planned operation to check for warnings and to ensure that bypassing the prompts will cause no security lapses or loss of database integrity.</p></dd><dt><span class="term">-jar JAR-file</span></dt><dd><p>Add a new PKCS #11 module to the database using the named JAR file. Use this command with the <code class="option">-installdir</code> and <code class="option">-tempdir</code> arguments. The JAR file uses the NSS PKCS #11 JAR format to identify all the files to be installed, the module's name, the mechanism flags, and the cipher flags, as well as any files to be installed on the target machine, including the PKCS #11 module library file and other files such as documentation. This is covered in the JAR installation file section in the man page, which details the special script needed to perform an installation through a server or with <span class="command"><strong>modutil</strong></span>. </p></dd><dt><span class="term">-list [modulename]</span></dt><dd><p>Display basic information about the contents of the <code class="filename">secmod.db</code> file. Specifying a <span class="emphasis"><em>modulename</em></span> displays detailed information about a particular module and its slots and tokens.</p></dd><dt><span class="term">-rawadd</span></dt><dd><p>Add the module spec string to the <code class="filename">secmod.db</code> database.</p></dd><dt><span class="term">-rawlist</span></dt><dd><p>Display the module specs for a specified module or for all loadable modules.</p></dd><dt><span class="term">-undefault modulename</span></dt><dd><p>Specify the security mechanisms for which the named module will not be a default provider. The security mechanisms are specified with the <code class="option">-mechanisms</code> argument.</p></dd></dl></div><p><span class="command"><strong>Arguments</strong></span></p><div class="variablelist"><dl class="variablelist"><dt><span class="term">MODULE</span></dt><dd><p>Give the security module to access.</p></dd><dt><span class="term">MODULESPEC</span></dt><dd><p>Give the security module spec to load into the security database.</p></dd><dt><span class="term">-ciphers cipher-enable-list</span></dt><dd><p>Enable specific ciphers in a module that is being added to the database. The <span class="emphasis"><em>cipher-enable-list</em></span> is a colon-delimited list of cipher names. Enclose this list in quotation marks if it contains spaces.</p></dd><dt><span class="term">-dbdir [sql:]directory</span></dt><dd><p>Specify the database directory in which to access or create security module database files.</p><p><span class="command"><strong>modutil</strong></span> supports two types of databases: the legacy security databases (<code class="filename">cert8.db</code>, <code class="filename">key3.db</code>, and <code class="filename">secmod.db</code>) and new SQLite databases (<code class="filename">cert9.db</code>, <code class="filename">key4.db</code>, and <code class="filename">pkcs11.txt</code>). If the prefix <span class="command"><strong>sql:</strong></span> is not used, then the tool assumes that the given databases are in the old format.</p></dd><dt><span class="term">--dbprefix prefix</span></dt><dd><p>Specify the prefix used on the database files, such as <code class="filename">my_</code> for <code class="filename">my_cert8.db</code>. This option is provided as a special case. Changing the names of the certificate and key databases is not recommended.</p></dd><dt><span class="term">-installdir root-installation-directory</span></dt><dd><p>Specify the root installation directory relative to which files will be installed by the <code class="option">-jar</code> option. This directory should be one below which it is appropriate to store dynamic library files, such as a server's root directory.</p></dd><dt><span class="term">-libfile library-file</span></dt><dd><p>Specify a path to a library file containing the implementation of the PKCS #11 interface module that is being added to the database.</p></dd><dt><span class="term">-mechanisms mechanism-list</span></dt><dd><p>Specify the security mechanisms for which a particular module will be flagged as a default provider. The <span class="emphasis"><em>mechanism-list</em></span> is a colon-delimited list of mechanism names. Enclose this list in quotation marks if it contains spaces.</p><p>The module becomes a default provider for the listed mechanisms when those mechanisms are enabled. If more than one module claims to be a particular mechanism's default provider, that mechanism's default provider is undefined.</p><p><span class="command"><strong>modutil</strong></span> supports several mechanisms: RSA, DSA, RC2, RC4, RC5, AES, DES, DH, SHA1, SHA256, SHA512, SSL, TLS, MD5, MD2, RANDOM (for random number generation), and FRIENDLY (meaning certificates are publicly readable).</p></dd><dt><span class="term">-newpwfile new-password-file</span></dt><dd><p>Specify a text file containing a token's new or replacement password so that a password can be entered automatically with the <code class="option">-changepw</code> option.</p></dd><dt><span class="term">-nocertdb</span></dt><dd><p>Do not open the certificate or key databases. This has several effects:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>With the <code class="option">-create</code> command, only a module security file is created; certificate and key databases are not created.</p></li><li class="listitem"><p>With the <code class="option">-jar</code> command, signatures on the JAR file are not checked.</p></li><li class="listitem"><p>With the <code class="option">-changepw</code> command, the password on the NSS internal module cannot be set or changed, since this password is stored in the key database.</p></li></ul></div></dd><dt><span class="term">-pwfile old-password-file</span></dt><dd><p>Specify a text file containing a token's existing password so that a password can be entered automatically when the <code class="option">-changepw</code> option is used to change passwords.</p></dd><dt><span class="term">-secmod secmodname</span></dt><dd><p>Give the name of the security module database (like <code class="filename">secmod.db</code>) to load.</p></dd><dt><span class="term">-slot slotname</span></dt><dd><p>Specify a particular slot to be enabled or disabled with the <code class="option">-enable</code> or <code class="option">-disable</code> options.</p></dd><dt><span class="term">-string CONFIG_STRING</span></dt><dd><p>Pass a configuration string for the module being added to the database.</p></dd><dt><span class="term">-tempdir temporary-directory</span></dt><dd><p>Give a directory location where temporary files are created during the installation by the <code class="option">-jar</code> option. If no temporary directory is specified, the current directory is used.</p></dd></dl></div></div><div class="refsection"><a name="usage-and-examples"></a><h2>Usage and Examples</h2><p><span class="command"><strong>Creating Database Files</strong></span></p><p>Before any operations can be performed, there must be a set of security databases available. <span class="command"><strong>modutil</strong></span> can be used to create these files. The only required argument is the database that where the databases will be located.</p><pre class="programlisting">modutil -create -dbdir [sql:]directory</pre><p><span class="command"><strong>Adding a Cryptographic Module</strong></span></p><p>Adding a PKCS #11 module means submitting a supporting library file, enabling its ciphers, and setting default provider status for various security mechanisms. This can be done by supplying all of the information through <span class="command"><strong>modutil</strong></span> directly or by running a JAR file and install script. For the most basic case, simply upload the library:</p><pre class="programlisting">modutil -add modulename -libfile library-file [-ciphers cipher-enable-list] [-mechanisms mechanism-list] </pre><p>For example:
 </p><pre class="programlisting">modutil -dbdir sql:/home/my/sharednssdb -add "Example PKCS #11 Module" -libfile "/tmp/crypto.so" -mechanisms RSA:DSA:RC2:RANDOM 
 
 Using database directory ... 
 Module "Example PKCS #11 Module" added to database.</pre><p>
         </p><p><span class="command"><strong>Installing a Cryptographic Module from a JAR File</strong></span></p><p>PKCS #11 modules can also be loaded using a JAR file, which contains all of the required libraries and an installation script that describes how to install the module. The JAR install script is described in more detail in <a class="xref" href="index.html#jar-install-file" title="JAR Installation File Format">the section called “JAR Installation File Format”</a>.</p><p>The JAR installation script defines the setup information for each platform that the module can be installed on. For example:</p><pre class="programlisting">Platforms { 
--- a/security/nss/doc/html/pk12util.html
+++ b/security/nss/doc/html/pk12util.html
@@ -1,15 +1,15 @@
 <html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>PK12UTIL</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="PK12UTIL"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">PK12UTIL</th></tr></table><hr></div><div class="refentry"><a name="pk12util"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>pk12util — Export and import keys and certificate to or from a PKCS #12 file and the NSS database</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">pk12util</code>  [-i p12File [-h tokenname] [-v] [common-options] ] [
         -l p12File [-h tokenname] [-r] [common-options] ] [
         -o p12File -n certname [-c keyCipher] [-C certCipher] [-m|--key_len keyLen] [-n|--cert_key_len certKeyLen] [common-options] ] [
 
 common-options are:
 [-d [sql:]directory] [-P dbprefix] [-k slotPasswordFile|-K slotPassword] [-w p12filePasswordFile|-W p12filePassword] 
-      ]</p></div></div><div class="refsection"><a name="idm207680667808"></a><h2>STATUS</h2><p>This documentation is still work in progress. Please contribute to the initial review in <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836477" target="_top">Mozilla NSS bug 836477</a>
+      ]</p></div></div><div class="refsection"><a name="idm224682436944"></a><h2>STATUS</h2><p>This documentation is still work in progress. Please contribute to the initial review in <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836477" target="_top">Mozilla NSS bug 836477</a>
     </p></div><div class="refsection"><a name="description"></a><h2>Description</h2><p>The PKCS #12 utility, <span class="command"><strong>pk12util</strong></span>, enables sharing certificates among any server that supports PKCS#12. The tool can import certificates and keys from PKCS#12 files into security databases, export certificates, and list certificates and keys.</p></div><div class="refsection"><a name="options"></a><h2>Options and Arguments</h2><p><span class="command"><strong>Options</strong></span></p><div class="variablelist"><dl class="variablelist"><dt><span class="term">-i p12file</span></dt><dd><p>Import keys and certificates from a PKCS#12 file into a security database.</p></dd><dt><span class="term">-l p12file</span></dt><dd><p>List the keys and certificates in PKCS#12 file.</p></dd><dt><span class="term">-o p12file</span></dt><dd><p>Export keys and certificates from the security database to a PKCS#12 file.</p></dd></dl></div><p><span class="command"><strong>Arguments</strong></span></p><div class="variablelist"><dl class="variablelist"><dt><span class="term">-n certname</span></dt><dd><p>Specify the nickname of the cert and private key to export.</p></dd><dt><span class="term">-d [sql:]directory</span></dt><dd><p>Specify the database directory into which to import to or export from certificates and keys.</p><p><span class="command"><strong>pk12util</strong></span> supports two types of databases: the legacy security databases (<code class="filename">cert8.db</code>, <code class="filename">key3.db</code>, and <code class="filename">secmod.db</code>) and new SQLite databases (<code class="filename">cert9.db</code>, <code class="filename">key4.db</code>, and <code class="filename">pkcs11.txt</code>). If the prefix <span class="command"><strong>sql:</strong></span> is not used, then the tool assumes that the given databases are in the old format.</p></dd><dt><span class="term">-P prefix</span></dt><dd><p>Specify the prefix used on the certificate and key databases. This option is provided as a special case. 
           Changing the names of the certificate and key databases is not recommended.</p></dd><dt><span class="term">-h tokenname</span></dt><dd><p>Specify the name of the token to import into or export from.</p></dd><dt><span class="term">-v </span></dt><dd><p>Enable debug logging when importing.</p></dd><dt><span class="term">-k slotPasswordFile</span></dt><dd><p>Specify the text file containing the slot's password.</p></dd><dt><span class="term">-K slotPassword</span></dt><dd><p>Specify the slot's password.</p></dd><dt><span class="term">-w p12filePasswordFile</span></dt><dd><p>Specify the text file containing the pkcs #12 file password.</p></dd><dt><span class="term">-W p12filePassword</span></dt><dd><p>Specify the pkcs #12 file password.</p></dd><dt><span class="term">-c keyCipher</span></dt><dd><p>Specify the key encryption algorithm.</p></dd><dt><span class="term">-C certCipher</span></dt><dd><p>Specify the key cert (overall package) encryption algorithm.</p></dd><dt><span class="term">-m | --key-len  keyLength</span></dt><dd><p>Specify the desired length of the symmetric key to be used to encrypt the private key.</p></dd><dt><span class="term">-n | --cert-key-len  certKeyLength</span></dt><dd><p>Specify the desired length of the symmetric key to be used to encrypt the certificates and other meta-data.</p></dd><dt><span class="term">-r</span></dt><dd><p>Dumps all of the data in raw (binary) form. This must be saved as a DER file. The default is to return information in a pretty-print ASCII format, which displays the information about the certificates and public keys in the p12 file.</p></dd></dl></div></div><div class="refsection"><a name="return-codes"></a><h2>Return Codes</h2><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p> 0 - No error</p></li><li class="listitem"><p> 1 - User Cancelled</p></li><li class="listitem"><p> 2 - Usage error</p></li><li class="listitem"><p> 6 - NLS init error</p></li><li class="listitem"><p> 8 - Certificate DB open error</p></li><li class="listitem"><p> 9 - Key DB open error</p></li><li class="listitem"><p> 10 - File initialization error</p></li><li class="listitem"><p> 11 - Unicode conversion error</p></li><li class="listitem"><p> 12 - Temporary file creation error</p></li><li class="listitem"><p> 13 - PKCS11 get slot error</p></li><li class="listitem"><p> 14 - PKCS12 decoder start error</p></li><li class="listitem"><p> 15 - error read from import file</p></li><li class="listitem"><p> 16 - pkcs12 decode error</p></li><li class="listitem"><p> 17 - pkcs12 decoder verify error</p></li><li class="listitem"><p> 18 - pkcs12 decoder validate bags error</p></li><li class="listitem"><p> 19 - pkcs12 decoder import bags error</p></li><li class="listitem"><p> 20 - key db conversion version 3 to version 2 error</p></li><li class="listitem"><p> 21 - cert db conversion version 7 to version 5 error</p></li><li class="listitem"><p> 22 - cert and key dbs patch error</p></li><li class="listitem"><p> 23 - get default cert db error</p></li><li class="listitem"><p> 24 - find cert by nickname error</p></li><li class="listitem"><p> 25 - create export context error</p></li><li class="listitem"><p> 26 - PKCS12 add password itegrity error</p></li><li class="listitem"><p> 27 - cert and key Safes creation error</p></li><li class="listitem"><p> 28 - PKCS12 add cert and key error</p></li><li class="listitem"><p> 29 - PKCS12 encode error</p></li></ul></div></div><div class="refsection"><a name="examples"></a><h2>Examples</h2><p><span class="command"><strong>Importing Keys and Certificates</strong></span></p><p>The most basic usage of <span class="command"><strong>pk12util</strong></span> for importing a certificate or key is the PKCS#12 input file (<code class="option">-i</code>) and some way to specify the security database being accessed (either <code class="option">-d</code> for a directory or <code class="option">-h</code> for a token).
     </p><pre class="programlisting">pk12util -i p12File [-h tokenname] [-v] [-d [sql:]directory] [-P dbprefix] [-k slotPasswordFile|-K slotPassword] [-w p12filePasswordFile|-W p12filePassword]</pre><p>For example:</p><pre class="programlisting"># pk12util -i /tmp/cert-files/users.p12 -d sql:/home/my/sharednssdb
 
 Enter a password which will be used to encrypt your keys.
 The password should be at least 8 characters long,
 and should contain at least one non-alphabetic character.
 
--- a/security/nss/doc/html/pp.html
+++ b/security/nss/doc/html/pp.html
@@ -1,7 +1,7 @@
-<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>PP</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="PP"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">PP</th></tr></table><hr></div><div class="refentry"><a name="pp"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>pp — Prints certificates, keys, crls, and pkcs7 files</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">pp -t type [-a] [-i input] [-o output]</code> </p></div></div><div class="refsection"><a name="idm207695084256"></a><h2>STATUS</h2><p>This documentation is still work in progress. Please contribute to the initial review in <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836477" target="_top">Mozilla NSS bug 836477</a>
-    </p></div><div class="refsection"><a name="idm207691286816"></a><h2>Description</h2><p><span class="command"><strong>pp </strong></span>pretty-prints private and public key, certificate, certificate-request,
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>PP</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="PP"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">PP</th></tr></table><hr></div><div class="refentry"><a name="pp"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>pp — Prints certificates, keys, crls, and pkcs7 files</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">pp -t type [-a] [-i input] [-o output]</code> </p></div></div><div class="refsection"><a name="idm224681757664"></a><h2>STATUS</h2><p>This documentation is still work in progress. Please contribute to the initial review in <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836477" target="_top">Mozilla NSS bug 836477</a>
+    </p></div><div class="refsection"><a name="idm224678000880"></a><h2>Description</h2><p><span class="command"><strong>pp </strong></span>pretty-prints private and public key, certificate, certificate-request,
                      pkcs7 or crl files
-    </p></div><div class="refsection"><a name="idm207691284880"></a><h2>Options</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-t </code> <em class="replaceable"><code>type</code></em></span></dt><dd><p class="simpara">specify the input, one of {private-key | public-key | certificate | certificate-request | pkcs7 | crl}</p><p class="simpara"></p></dd><dt><span class="term"><code class="option">-a </code></span></dt><dd>Input is in ascii encoded form (RFC1113)</dd><dt><span class="term"><code class="option">-i </code> <em class="replaceable"><code>inputfile</code></em></span></dt><dd>Define an input file to use (default is stdin)</dd><dt><span class="term"><code class="option">-u </code> <em class="replaceable"><code>outputfile</code></em></span></dt><dd>Define an output file to use (default is stdout)</dd></dl></div></div><div class="refsection"><a name="resources"></a><h2>Additional Resources</h2><p>NSS is maintained in conjunction with PKI and security-related projects through Mozilla and Fedora. The most closely-related project is Dogtag PKI, with a project wiki at <a class="ulink" href="http://pki.fedoraproject.org/wiki/" target="_top">PKI Wiki</a>. </p><p>For information specifically about NSS, the NSS project wiki is located at <a class="ulink" href="http://www.mozilla.org/projects/security/pki/nss/" target="_top">Mozilla NSS site</a>. The NSS site relates directly to NSS code changes and releases.</p><p>Mailing lists: pki-devel@redhat.com and pki-users@redhat.com</p><p>IRC: Freenode at #dogtag-pki</p></div><div class="refsection"><a name="authors"></a><h2>Authors</h2><p>The NSS tools were written and maintained by developers with Netscape, Red Hat,  Sun, Oracle, Mozilla, and Google.</p><p>
+    </p></div><div class="refsection"><a name="idm224677998992"></a><h2>Options</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-t </code> <em class="replaceable"><code>type</code></em></span></dt><dd><p class="simpara">specify the input, one of {private-key | public-key | certificate | certificate-request | pkcs7 | crl}</p><p class="simpara"></p></dd><dt><span class="term"><code class="option">-a </code></span></dt><dd>Input is in ascii encoded form (RFC1113)</dd><dt><span class="term"><code class="option">-i </code> <em class="replaceable"><code>inputfile</code></em></span></dt><dd>Define an input file to use (default is stdin)</dd><dt><span class="term"><code class="option">-u </code> <em class="replaceable"><code>outputfile</code></em></span></dt><dd>Define an output file to use (default is stdout)</dd></dl></div></div><div class="refsection"><a name="resources"></a><h2>Additional Resources</h2><p>NSS is maintained in conjunction with PKI and security-related projects through Mozilla and Fedora. The most closely-related project is Dogtag PKI, with a project wiki at <a class="ulink" href="http://pki.fedoraproject.org/wiki/" target="_top">PKI Wiki</a>. </p><p>For information specifically about NSS, the NSS project wiki is located at <a class="ulink" href="http://www.mozilla.org/projects/security/pki/nss/" target="_top">Mozilla NSS site</a>. The NSS site relates directly to NSS code changes and releases.</p><p>Mailing lists: pki-devel@redhat.com and pki-users@redhat.com</p><p>IRC: Freenode at #dogtag-pki</p></div><div class="refsection"><a name="authors"></a><h2>Authors</h2><p>The NSS tools were written and maintained by developers with Netscape, Red Hat,  Sun, Oracle, Mozilla, and Google.</p><p>
 	Authors: Elio Maldonado &lt;emaldona@redhat.com&gt;, Deon Lackey &lt;dlackey@redhat.com&gt;.
     </p></div><div class="refsection"><a name="license"></a><h2>LICENSE</h2><p>Licensed under the Mozilla Public License, v. 2.0.  If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
     </p></div></div><div class="navfooter"><hr></div></body></html>
--- a/security/nss/doc/html/signtool.html
+++ b/security/nss/doc/html/signtool.html
@@ -1,9 +1,9 @@
-<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>signtool</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="signtool"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">signtool</th></tr></table><hr></div><div class="refentry"><a name="signtool"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>signtool — Digitally sign objects and files.</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">signtool</code>  [-k keyName] [[-h]] [[-H]] [[-l]] [[-L]] [[-M]] [[-v]] [[-w]] [[-G nickname]] [[--keysize | -s size]] [[-b basename]] [[-c Compression Level] ] [[-d cert-dir] ] [[-i installer script] ] [[-m metafile] ] [[-x name] ] [[-f filename] ] [[-t|--token tokenname] ] [[-e extension] ] [[-o] ] [[-z] ] [[-X] ] [[--outfile] ] [[--verbose value] ] [[--norecurse] ] [[--leavearc] ] [[-j directory] ] [[-Z jarfile] ] [[-O] ] [[-p password] ] [directory-tree] [archive]</p></div></div><div class="refsection"><a name="idm207702595360"></a><h2>STATUS</h2><p>This documentation is still work in progress. Please contribute to the initial review in <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836477" target="_top">Mozilla NSS bug 836477</a>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>signtool</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="signtool"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">signtool</th></tr></table><hr></div><div class="refentry"><a name="signtool"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>signtool — Digitally sign objects and files.</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">signtool</code>  [-k keyName] [[-h]] [[-H]] [[-l]] [[-L]] [[-M]] [[-v]] [[-w]] [[-G nickname]] [[--keysize | -s size]] [[-b basename]] [[-c Compression Level] ] [[-d cert-dir] ] [[-i installer script] ] [[-m metafile] ] [[-x name] ] [[-f filename] ] [[-t|--token tokenname] ] [[-e extension] ] [[-o] ] [[-z] ] [[-X] ] [[--outfile] ] [[--verbose value] ] [[--norecurse] ] [[--leavearc] ] [[-j directory] ] [[-Z jarfile] ] [[-O] ] [[-p password] ] [directory-tree] [archive]</p></div></div><div class="refsection"><a name="idm224666150896"></a><h2>STATUS</h2><p>This documentation is still work in progress. Please contribute to the initial review in <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836477" target="_top">Mozilla NSS bug 836477</a>
     </p></div><div class="refsection"><a name="description"></a><h2>Description</h2><p>The Signing Tool, <span class="command"><strong>signtool</strong></span>, creates digital signatures and uses a Java Archive (JAR) file to associate the signatures with files in a directory. Electronic software distribution over any network involves potential security problems. To help address some of these problems, you can associate digital signatures with the files in a JAR archive. Digital signatures allow SSL-enabled clients to perform two important operations:</p><p>* Confirm the identity of the individual, company, or other entity whose digital signature is associated with the files</p><p>* Check whether the files have been tampered with since being signed</p><p>If you have a signing certificate, you can use Netscape Signing Tool to digitally sign files and package them as a JAR file. An object-signing certificate is a special kind of certificate that allows you to associate your digital signature with one or more files.</p><p>An individual file can potentially be signed with multiple digital signatures. For example, a commercial software developer might sign the files that constitute a software product to prove that the files are indeed from a particular company. A network administrator manager might sign the same files with an additional digital signature based on a company-generated certificate to indicate that the product is approved for use within the company.</p><p>The significance of a digital signature is comparable to the significance of a handwritten signature. Once you have signed a file, it is difficult to claim later that you didn't sign it. In some situations, a digital signature may be considered as legally binding as a handwritten signature. Therefore, you should take great care to ensure that you can stand behind any file you sign and distribute.</p><p>For example, if you are a software developer, you should test your code to make sure it is virus-free before signing it. Similarly, if you are a network administrator, you should make sure, before signing any code, that it comes from a reliable source and will run correctly with the software installed on the machines to which you are distributing it.</p><p>Before you can use Netscape Signing Tool to sign files, you must have an object-signing certificate, which is a special certificate whose associated private key is used to create digital signatures. For testing purposes only, you can create an object-signing certificate with Netscape Signing Tool 1.3. When testing is finished and you are ready to disitribute your software, you should obtain an object-signing certificate from one of two kinds of sources:</p><p>* An independent certificate authority (CA) that authenticates your identity and charges you a fee. You typically get a certificate from an independent CA if you want to sign software that will be distributed over the Internet.</p><p>* CA server software running on your corporate intranet or extranet. Netscape Certificate Management System provides a complete management solution for creating, deploying, and managing certificates, including CAs that issue object-signing certificates.</p><p>You must also have a certificate for the CA that issues your signing certificate before you can sign files. If the certificate authority's certificate isn't already installed in your copy of Communicator, you typically install it by clicking the appropriate link on the certificate authority's web site, for example on the page from which you initiated enrollment for your signing certificate. This is the case for some test certificates, as well as certificates issued by Netscape Certificate Management System: you must download the the CA certificate in addition to obtaining your own signing certificate. CA certificates for several certificate authorities are preinstalled in the Communicator certificate database.</p><p>When you receive an object-signing certificate for your own use, it is automatically installed in your copy of the Communicator client software. Communicator supports the public-key cryptography standard known as PKCS #12, which governs key portability. You can, for example, move an object-signing certificate and its associated private key from one computer to another on a credit-card-sized device called a smart card.</p></div><div class="refsection"><a name="options"></a><h2>Options</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term">-b basename</span></dt><dd><p>Specifies the base filename for the .rsa and .sf files in the META-INF directory to conform with the JAR format. For example, <span class="emphasis"><em>-b signatures</em></span> causes the files to be named signatures.rsa and signatures.sf. The default is signtool.</p></dd><dt><span class="term">-c#</span></dt><dd><p>
 	Specifies the compression level for the -J or -Z option. The symbol # represents a number from 0 to 9, where 0 means no compression and 9 means maximum compression. The higher the level of compression, the smaller the output but the longer the operation takes.
 
 If the -c# option is not used with either the -J or the -Z option, the default compression value used by both the -J and -Z options is 6.
 </p></dd><dt><span class="term">-d certdir</span></dt><dd><p>
 	Specifies your certificate database directory; that is, the directory in which you placed your key3.db and cert7.db files. To specify the current directory, use "-d." (including the period).
 
 The Unix version of signtool assumes ~/.netscape unless told otherwise. The NT version of signtool always requires the use of the -d option to specify where the database files are located.
--- a/security/nss/doc/html/signver.html
+++ b/security/nss/doc/html/signver.html
@@ -1,12 +1,12 @@
-<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>SIGNVER</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="SIGNVER"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">SIGNVER</th></tr></table><hr></div><div class="refentry"><a name="signver"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>signver — Verify a detached PKCS#7 signature for a file.</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">signtool</code>    -A  |   -V    -d <em class="replaceable"><code>directory</code></em>  [-a] [-i <em class="replaceable"><code>input_file</code></em>] [-o <em class="replaceable"><code>output_file</code></em>] [-s <em class="replaceable"><code>signature_file</code></em>] [-v]</p></div></div><div class="refsection"><a name="idm207691938384"></a><h2>STATUS</h2><p>This documentation is still work in progress. Please contribute to the initial review in <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836477" target="_top">Mozilla NSS bug 836477</a>
-    </p></div><div class="refsection"><a name="description"></a><h2>Description</h2><p>The Signature Verification Tool, <span class="command"><strong>signver</strong></span>, is a simple command-line utility that unpacks a base-64-encoded PKCS#7 signed object and verifies the digital signature using standard cryptographic techniques. The Signature Verification Tool can also display the contents of the signed object.</p></div><div class="refsection"><a name="options"></a><h2>Options</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term">-A</span></dt><dd><p>Displays all of the information in the PKCS#7 signature.</p></dd><dt><span class="term">-V</span></dt><dd><p>Verifies the digital signature.</p></dd><dt><span class="term">-d [sql:]<span class="emphasis"><em>directory</em></span></span></dt><dd><p>Specify the database directory which contains the certificates and keys.</p><p><span class="command"><strong>signver</strong></span> supports two types of databases: the legacy security databases (<code class="filename">cert8.db</code>, <code class="filename">key3.db</code>, and <code class="filename">secmod.db</code>) and new SQLite databases (<code class="filename">cert9.db</code>, <code class="filename">key4.db</code>, and <code class="filename">pkcs11.txt</code>). If the prefix <span class="command"><strong>sql:</strong></span> is not used, then the tool assumes that the given databases are in the old format.</p></dd><dt><span class="term">-a</span></dt><dd><p>Sets that the given signature file is in ASCII format.</p></dd><dt><span class="term">-i <span class="emphasis"><em>input_file</em></span></span></dt><dd><p>Gives the input file for the object with signed data.</p></dd><dt><span class="term">-o <span class="emphasis"><em>output_file</em></span></span></dt><dd><p>Gives the output file to which to write the results.</p></dd><dt><span class="term">-s <span class="emphasis"><em>signature_file</em></span></span></dt><dd><p>Gives the input file for the digital signature.</p></dd><dt><span class="term">-v</span></dt><dd><p>Enables verbose output.</p></dd></dl></div></div><div class="refsection"><a name="examples"></a><h2>Extended Examples</h2><div class="refsection"><a name="idm207695803904"></a><h3>Verifying a Signature</h3><p>The <code class="option">-V</code> option verifies that the signature in a given signature file is valid when used to sign the given object (from the input file).</p><pre class="programlisting">signver -V -s <em class="replaceable"><code>signature_file</code></em> -i <em class="replaceable"><code>signed_file</code></em> -d sql:/home/my/sharednssdb
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>SIGNVER</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="SIGNVER"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">SIGNVER</th></tr></table><hr></div><div class="refentry"><a name="signver"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>signver — Verify a detached PKCS#7 signature for a file.</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">signtool</code>    -A  |   -V    -d <em class="replaceable"><code>directory</code></em>  [-a] [-i <em class="replaceable"><code>input_file</code></em>] [-o <em class="replaceable"><code>output_file</code></em>] [-s <em class="replaceable"><code>signature_file</code></em>] [-v]</p></div></div><div class="refsection"><a name="idm224680848704"></a><h2>STATUS</h2><p>This documentation is still work in progress. Please contribute to the initial review in <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836477" target="_top">Mozilla NSS bug 836477</a>
+    </p></div><div class="refsection"><a name="description"></a><h2>Description</h2><p>The Signature Verification Tool, <span class="command"><strong>signver</strong></span>, is a simple command-line utility that unpacks a base-64-encoded PKCS#7 signed object and verifies the digital signature using standard cryptographic techniques. The Signature Verification Tool can also display the contents of the signed object.</p></div><div class="refsection"><a name="options"></a><h2>Options</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term">-A</span></dt><dd><p>Displays all of the information in the PKCS#7 signature.</p></dd><dt><span class="term">-V</span></dt><dd><p>Verifies the digital signature.</p></dd><dt><span class="term">-d [sql:]<span class="emphasis"><em>directory</em></span></span></dt><dd><p>Specify the database directory which contains the certificates and keys.</p><p><span class="command"><strong>signver</strong></span> supports two types of databases: the legacy security databases (<code class="filename">cert8.db</code>, <code class="filename">key3.db</code>, and <code class="filename">secmod.db</code>) and new SQLite databases (<code class="filename">cert9.db</code>, <code class="filename">key4.db</code>, and <code class="filename">pkcs11.txt</code>). If the prefix <span class="command"><strong>sql:</strong></span> is not used, then the tool assumes that the given databases are in the old format.</p></dd><dt><span class="term">-a</span></dt><dd><p>Sets that the given signature file is in ASCII format.</p></dd><dt><span class="term">-i <span class="emphasis"><em>input_file</em></span></span></dt><dd><p>Gives the input file for the object with signed data.</p></dd><dt><span class="term">-o <span class="emphasis"><em>output_file</em></span></span></dt><dd><p>Gives the output file to which to write the results.</p></dd><dt><span class="term">-s <span class="emphasis"><em>signature_file</em></span></span></dt><dd><p>Gives the input file for the digital signature.</p></dd><dt><span class="term">-v</span></dt><dd><p>Enables verbose output.</p></dd></dl></div></div><div class="refsection"><a name="examples"></a><h2>Extended Examples</h2><div class="refsection"><a name="idm224681951616"></a><h3>Verifying a Signature</h3><p>The <code class="option">-V</code> option verifies that the signature in a given signature file is valid when used to sign the given object (from the input file).</p><pre class="programlisting">signver -V -s <em class="replaceable"><code>signature_file</code></em> -i <em class="replaceable"><code>signed_file</code></em> -d sql:/home/my/sharednssdb
 
-signatureValid=yes</pre></div><div class="refsection"><a name="idm207695800736"></a><h3>Printing Signature Data</h3><p>
+signatureValid=yes</pre></div><div class="refsection"><a name="idm224679496656"></a><h3>Printing Signature Data</h3><p>
 			The <code class="option">-A</code> option prints all of the information contained in a signature file. Using the <code class="option">-o</code> option prints the signature file information to the given output file rather than stdout.
 		</p><pre class="programlisting">signver -A -s <em class="replaceable"><code>signature_file</code></em> -o <em class="replaceable"><code>output_file</code></em></pre></div></div><div class="refsection"><a name="databases"></a><h2>NSS Database Types</h2><p>NSS originally used BerkeleyDB databases to store security information. 
 The last versions of these <span class="emphasis"><em>legacy</em></span> databases are:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
 			cert8.db for certificates
 		</p></li><li class="listitem"><p>
 			key3.db for keys
 		</p></li><li class="listitem"><p>
 			secmod.db for PKCS #11 module information
--- a/security/nss/doc/html/ssltap.html
+++ b/security/nss/doc/html/ssltap.html
@@ -1,9 +1,9 @@
-<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>SSLTAP</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="SSLTAP"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">SSLTAP</th></tr></table><hr></div><div class="refentry"><a name="ssltap"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>ssltap — Tap into SSL connections and display the data going by </p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">libssltap</code>  [-vhfsxl] [-p port] [hostname:port]</p></div></div><div class="refsection"><a name="idm207705899984"></a><h2>STATUS</h2><p>This documentation is still work in progress. Please contribute to the initial review in <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836477" target="_top">Mozilla NSS bug 836477</a>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>SSLTAP</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="SSLTAP"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">SSLTAP</th></tr></table><hr></div><div class="refentry"><a name="ssltap"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>ssltap — Tap into SSL connections and display the data going by </p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">libssltap</code>  [-vhfsxl] [-p port] [hostname:port]</p></div></div><div class="refsection"><a name="idm224680842512"></a><h2>STATUS</h2><p>This documentation is still work in progress. Please contribute to the initial review in <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836477" target="_top">Mozilla NSS bug 836477</a>
     </p></div><div class="refsection"><a name="description"></a><h2>Description</h2><p>The SSL Debugging Tool <span class="command"><strong>ssltap</strong></span> is an SSL-aware command-line proxy. It watches TCP connections and displays the data going by. If a connection is SSL, the data display includes interpreted SSL records and handshaking</p></div><div class="refsection"><a name="options"></a><h2>Options</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term">-v </span></dt><dd><p>Print a version string for the tool.</p></dd><dt><span class="term">-h </span></dt><dd><p>
 Turn on hex/ASCII printing. Instead of outputting raw data, the command interprets each record as a numbered line of hex values, followed by the same data as ASCII characters. The two parts are separated by a vertical bar. Nonprinting characters are replaced by dots. 
         </p></dd><dt><span class="term">-f </span></dt><dd><p>
 Turn on fancy printing. Output is printed in colored HTML. Data sent from the client to the server is in blue; the server's reply is in red. When used with looping mode, the different connections are separated with horizontal lines. You can use this option to upload the output into a browser. 
         </p></dd><dt><span class="term">-s </span></dt><dd><p>
 Turn on SSL parsing and decoding. The tool does not automatically detect SSL sessions. If you are intercepting an SSL connection, use this option so that the tool can detect and decode SSL structures.
 	  </p><p>
 If the tool detects a certificate chain, it saves the DER-encoded certificates into files in the current directory. The files are named cert.0x, where x is the sequence number of the certificate.
--- a/security/nss/doc/html/vfychain.html
+++ b/security/nss/doc/html/vfychain.html
@@ -1,9 +1,9 @@
-<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>VFYCHAIN</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="VFYCHAIN"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">VFYCHAIN</th></tr></table><hr></div><div class="refentry"><a name="vfychain"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>vfychain  — vfychain [options] [revocation options] certfile [[options] certfile] ...</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">vfychain</code> </p></div></div><div class="refsection"><a name="idm207689306736"></a><h2>STATUS</h2><p>This documentation is still work in progress. Please contribute to the initial review in <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836477" target="_top">Mozilla NSS bug 836477</a>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>VFYCHAIN</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="VFYCHAIN"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">VFYCHAIN</th></tr></table><hr></div><div class="refentry"><a name="vfychain"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>vfychain  — vfychain [options] [revocation options] certfile [[options] certfile] ...</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">vfychain</code> </p></div></div><div class="refsection"><a name="idm224658292400"></a><h2>STATUS</h2><p>This documentation is still work in progress. Please contribute to the initial review in <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836477" target="_top">Mozilla NSS bug 836477</a>
     </p></div><div class="refsection"><a name="description"></a><h2>Description</h2><p>The verification Tool, <span class="command"><strong>vfychain</strong></span>, verifies certificate chains. <span class="command"><strong>modutil</strong></span> can add and delete PKCS #11 modules, change passwords on security databases, set defaults, list module contents, enable or disable slots, enable or disable FIPS 140-2 compliance, and assign default providers for cryptographic operations. This tool can also create certificate, key, and module security database files.</p><p>The tasks associated with security module database management are part of a process that typically also involves managing key databases and certificate databases.</p></div><div class="refsection"><a name="options"></a><h2>Options</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-a</code></span></dt><dd>the following certfile is base64 encoded</dd><dt><span class="term"><code class="option">-b </code> <em class="replaceable"><code>YYMMDDHHMMZ</code></em></span></dt><dd>Validate date (default: now)</dd><dt><span class="term"><code class="option">-d </code> <em class="replaceable"><code>directory</code></em></span></dt><dd>database directory</dd><dt><span class="term"><code class="option">-f </code> </span></dt><dd>Enable cert fetching from AIA URL</dd><dt><span class="term"><code class="option">-o </code> <em class="replaceable"><code>oid</code></em></span></dt><dd>Set policy OID for cert validation(Format OID.1.2.3)</dd><dt><span class="term"><code class="option">-p </code></span></dt><dd><p class="simpara">Use PKIX Library to validate certificate by calling:</p><p class="simpara">	   * CERT_VerifyCertificate if specified once,</p><p class="simpara">	   * CERT_PKIXVerifyCert if specified twice and more.</p></dd><dt><span class="term"><code class="option">-r </code></span></dt><dd>Following certfile is raw binary DER (default)</dd><dt><span class="term"><code class="option">-t</code></span></dt><dd>Following cert is explicitly trusted (overrides db trust)</dd><dt><span class="term"><code class="option">-u </code> <em class="replaceable"><code>usage</code></em></span></dt><dd><p>
 	 	 0=SSL client, 1=SSL server, 2=SSL StepUp, 3=SSL CA,
 	     4=Email signer, 5=Email recipient, 6=Object signer,
 		 9=ProtectedObjectSigner, 10=OCSP responder, 11=Any CA
             </p></dd><dt><span class="term"><code class="option">-T </code></span></dt><dd>Trust both explicit trust anchors (-t) and the database. (Without this option, the default is to only trust certificates marked -t, if there are any, or to trust the database if there are certificates marked -t.)
             </dd><dt><span class="term"><code class="option">-v </code></span></dt><dd>Verbose mode. Prints root cert subject(double the
 			 argument for whole root cert info)
             </dd><dt><span class="term"><code class="option">-w </code> <em class="replaceable"><code>password</code></em></span></dt><dd>Database password</dd><dt><span class="term"><code class="option">-W </code> <em class="replaceable"><code>pwfile</code></em></span></dt><dd>Password file</dd><dt><span class="term"><code class="option"></code></span></dt><dd><p class="simpara">Revocation options for PKIX API (invoked with -pp options) is a
--- a/security/nss/doc/html/vfyserv.html
+++ b/security/nss/doc/html/vfyserv.html
@@ -1,5 +1,5 @@
-<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>VFYSERV</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="VFYSERV"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">VFYSERV</th></tr></table><hr></div><div class="refentry"><a name="vfyserv"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>vfyserv  — TBD</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">vfyserv</code> </p></div></div><div class="refsection"><a name="idm207703284240"></a><h2>STATUS</h2><p>This documentation is still work in progress. Please contribute to the initial review in <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836477" target="_top">Mozilla NSS bug 836477</a>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>VFYSERV</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="VFYSERV"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">VFYSERV</th></tr></table><hr></div><div class="refentry"><a name="vfyserv"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>vfyserv  — TBD</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">vfyserv</code> </p></div></div><div class="refsection"><a name="idm224662974480"></a><h2>STATUS</h2><p>This documentation is still work in progress. Please contribute to the initial review in <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836477" target="_top">Mozilla NSS bug 836477</a>
     </p></div><div class="refsection"><a name="description"></a><h2>Description</h2><p>The <span class="command"><strong>vfyserv </strong></span> tool verifies a certificate chain</p></div><div class="refsection"><a name="options"></a><h2>Options</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option"></code> <em class="replaceable"><code></code></em></span></dt><dd><p class="simpara"></p><p class="simpara"></p></dd></dl></div></div><div class="refsection"><a name="resources"></a><h2>Additional Resources</h2><p>For information about NSS and other tools related to NSS (like JSS), check out the NSS project wiki at <a class="ulink" href="http://www.mozilla.org/projects/security/pki/nss/" target="_top">http://www.mozilla.org/projects/security/pki/nss/</a>. The NSS site relates directly to NSS code changes and releases.</p><p>Mailing lists: https://lists.mozilla.org/listinfo/dev-tech-crypto</p><p>IRC: Freenode at #dogtag-pki</p></div><div class="refsection"><a name="authors"></a><h2>Authors</h2><p>The NSS tools were written and maintained by developers with Netscape, Red Hat,  Sun, Oracle, Mozilla, and Google.</p><p>
 	Authors: Elio Maldonado &lt;emaldona@redhat.com&gt;, Deon Lackey &lt;dlackey@redhat.com&gt;.
     </p></div><div class="refsection"><a name="license"></a><h2>LICENSE</h2><p>Licensed under the Mozilla Public License, v. 2.0.  If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
     </p></div></div><div class="navfooter"><hr></div></body></html>
--- a/security/nss/doc/nroff/certutil.1
+++ b/security/nss/doc/nroff/certutil.1
@@ -1,18 +1,18 @@
 '\" t
 .\"     Title: CERTUTIL
 .\"    Author: [see the "Authors" section]
 .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\"      Date: 19 July 2013
+.\"      Date: 12 November 2013
 .\"    Manual: NSS Security Tools
 .\"    Source: nss-tools
 .\"  Language: English
 .\"
-.TH "CERTUTIL" "1" "19 July 2013" "nss-tools" "NSS Security Tools"
+.TH "CERTUTIL" "1" "12 November 2013" "nss-tools" "NSS Security Tools"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 .\" http://bugs.debian.org/507673
 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 .ie \n(.g .ds Aq \(aq
@@ -246,16 +246,21 @@ NSS recognizes the following prefixes:
 If no prefix is specified the default type is retrieved from NSS_DEFAULT_DB_TYPE\&. If NSS_DEFAULT_DB_TYPE is not set then dbm: is the default\&.
 .RE
 .PP
 \-e
 .RS 4
 Check a certificate\*(Aqs signature during the process of validating a certificate\&.
 .RE
 .PP
+\-\-email email\-address
+.RS 4
+Specify the email address of a certificate to list\&. Used with the \-L command option\&.
+.RE
+.PP
 \-f password\-file
 .RS 4
 Specify a file that will automatically supply the password to include in a certificate or to access a certificate database\&. This is a plain\-text file containing one password\&. Be sure to prevent unauthorized access to this file\&.
 .RE
 .PP
 \-g keysize
 .RS 4
 Set a key size to use when generating new public and private key pairs\&. The minimum is 512 bits and the maximum is 8192 bits\&. The default is 1024 bits\&. Any size between the minimum and maximum is allowed\&.
@@ -900,22 +905,27 @@ Add the Inhibit Any Policy Access extens
 Add the Subject Key ID extension to the certificate\&. X\&.509 certificate extensions are described in RFC 5280\&.
 .RE
 .PP
 \-\-extNC
 .RS 4
 Add a Name Constraint extension to the certificate\&. X\&.509 certificate extensions are described in RFC 5280\&.
 .RE
 .PP
+\-\-empty\-password
+.RS 4
+Use empty password when creating new certificate database with \-N\&.
+.RE
+.PP
 \-\-keyAttrFlags attrflags
 .RS 4
 PKCS #11 key Attributes\&. Comma separated list of key attribute flags, selected from the following list of choices: {token | session} {public | private} {sensitive | insensitive} {modifiable | unmodifiable} {extractable | unextractable}
 .RE
 .PP
-\-\-keyFlagsOn opflags, \-\-keyFlagsOff opflags
+\-\-keyOpFlagsOn opflags, \-\-keyOpFlagsOff opflags
 .RS 4
 PKCS #11 key Operation Flags\&. Comma separated list of one or more of the following: {token | session} {public | private} {sensitive | insensitive} {modifiable | unmodifiable} {extractable | unextractable}
 .RE
 .PP
 \-\-source\-dir certdir
 .RS 4
 Identify the certificate database directory to upgrade\&.
 .RE
--- a/security/nss/doc/nroff/pk12util.1
+++ b/security/nss/doc/nroff/pk12util.1
@@ -1,18 +1,18 @@
 '\" t
 .\"     Title: PK12UTIL
 .\"    Author: [see the "Authors" section]
 .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\"      Date: 19 July 2013
+.\"      Date: 12 November 2013
 .\"    Manual: NSS Security Tools
 .\"    Source: nss-tools
 .\"  Language: English
 .\"
-.TH "PK12UTIL" "1" "19 July 2013" "nss-tools" "NSS Security Tools"
+.TH "PK12UTIL" "1" "12 November 2013" "nss-tools" "NSS Security Tools"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 .\" http://bugs.debian.org/507673
 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 .ie \n(.g .ds Aq \(aq
--- a/security/nss/doc/nroff/pp.1
+++ b/security/nss/doc/nroff/pp.1
@@ -1,18 +1,18 @@
 '\" t
 .\"     Title: PP
 .\"    Author: [see the "Authors" section]
 .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\"      Date: 19 July 2013
+.\"      Date: 12 November 2013
 .\"    Manual: NSS Security Tools
 .\"    Source: nss-tools
 .\"  Language: English
 .\"
-.TH "PP" "1" "19 July 2013" "nss-tools" "NSS Security Tools"
+.TH "PP" "1" "12 November 2013" "nss-tools" "NSS Security Tools"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 .\" http://bugs.debian.org/507673
 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 .ie \n(.g .ds Aq \(aq
--- a/security/nss/doc/nroff/signtool.1
+++ b/security/nss/doc/nroff/signtool.1
@@ -1,18 +1,18 @@
 '\" t
 .\"     Title: signtool
 .\"    Author: [see the "Authors" section]
 .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\"      Date: 19 July 2013
+.\"      Date: 12 November 2013
 .\"    Manual: NSS Security Tools
 .\"    Source: nss-tools
 .\"  Language: English
 .\"
-.TH "SIGNTOOL" "1" "19 July 2013" "nss-tools" "NSS Security Tools"
+.TH "SIGNTOOL" "1" "12 November 2013" "nss-tools" "NSS Security Tools"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 .\" http://bugs.debian.org/507673
 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 .ie \n(.g .ds Aq \(aq
--- a/security/nss/doc/nroff/signver.1
+++ b/security/nss/doc/nroff/signver.1
@@ -1,18 +1,18 @@
 '\" t
 .\"     Title: SIGNVER
 .\"    Author: [see the "Authors" section]
 .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\"      Date: 19 July 2013
+.\"      Date: 12 November 2013
 .\"    Manual: NSS Security Tools
 .\"    Source: nss-tools
 .\"  Language: English
 .\"
-.TH "SIGNVER" "1" "19 July 2013" "nss-tools" "NSS Security Tools"
+.TH "SIGNVER" "1" "12 November 2013" "nss-tools" "NSS Security Tools"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 .\" http://bugs.debian.org/507673
 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 .ie \n(.g .ds Aq \(aq
--- a/security/nss/doc/nroff/ssltap.1
+++ b/security/nss/doc/nroff/ssltap.1
@@ -1,18 +1,18 @@
 '\" t
 .\"     Title: SSLTAP
 .\"    Author: [see the "Authors" section]
 .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\"      Date: 19 July 2013
+.\"      Date: 12 November 2013
 .\"    Manual: NSS Security Tools
 .\"    Source: nss-tools
 .\"  Language: English
 .\"
-.TH "SSLTAP" "1" "19 July 2013" "nss-tools" "NSS Security Tools"
+.TH "SSLTAP" "1" "12 November 2013" "nss-tools" "NSS Security Tools"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 .\" http://bugs.debian.org/507673
 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 .ie \n(.g .ds Aq \(aq
--- a/security/nss/doc/nroff/vfychain.1
+++ b/security/nss/doc/nroff/vfychain.1
@@ -1,18 +1,18 @@
 '\" t
 .\"     Title: VFYCHAIN
 .\"    Author: [see the "Authors" section]
 .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\"      Date: 19 July 2013
+.\"      Date: 12 November 2013
 .\"    Manual: NSS Security Tools
 .\"    Source: nss-tools
 .\"  Language: English
 .\"
-.TH "VFYCHAIN" "1" "19 July 2013" "nss-tools" "NSS Security Tools"
+.TH "VFYCHAIN" "1" "12 November 2013" "nss-tools" "NSS Security Tools"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 .\" http://bugs.debian.org/507673
 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 .ie \n(.g .ds Aq \(aq
--- a/security/nss/doc/nroff/vfyserv.1
+++ b/security/nss/doc/nroff/vfyserv.1
@@ -1,18 +1,18 @@
 '\" t
 .\"     Title: VFYSERV
 .\"    Author: [see the "Authors" section]
 .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\"      Date: 19 July 2013
+.\"      Date: 12 November 2013
 .\"    Manual: NSS Security Tools
 .\"    Source: nss-tools
 .\"  Language: English
 .\"
-.TH "VFYSERV" "1" "19 July 2013" "nss-tools" "NSS Security Tools"
+.TH "VFYSERV" "1" "12 November 2013" "nss-tools" "NSS Security Tools"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 .\" http://bugs.debian.org/507673
 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 .ie \n(.g .ds Aq \(aq
--- a/security/nss/lib/certdb/cert.h
+++ b/security/nss/lib/certdb/cert.h
@@ -1213,33 +1213,44 @@ CERTCertList *
 CERT_MatchUserCert(CERTCertDBHandle *handle,
 		   SECCertUsage usage,
 		   int nCANames, char **caNames,
 		   void *proto_win);
 
 CERTCertList *
 CERT_NewCertList(void);
 
+/* free the cert list and all the certs in the list */
 void
 CERT_DestroyCertList(CERTCertList *certs);
 
 /* remove the node and free the cert */
 void
 CERT_RemoveCertListNode(CERTCertListNode *node);
 
+/* equivalent to CERT_AddCertToListTailWithData(certs, cert, NULL) */
 SECStatus
 CERT_AddCertToListTail(CERTCertList *certs, CERTCertificate *cert);
 
+/* equivalent to CERT_AddCertToListHeadWithData(certs, cert, NULL) */
 SECStatus
 CERT_AddCertToListHead(CERTCertList *certs, CERTCertificate *cert);
 
+/*
+ * The new cert list node takes ownership of "cert". "cert" is freed
+ * when the list node is removed.
+ */
 SECStatus
 CERT_AddCertToListTailWithData(CERTCertList *certs, CERTCertificate *cert,
 							 void *appData);
 
+/*
+ * The new cert list node takes ownership of "cert". "cert" is freed
+ * when the list node is removed.
+ */
 SECStatus
 CERT_AddCertToListHeadWithData(CERTCertList *certs, CERTCertificate *cert,
 							 void *appData);
 
 typedef PRBool (* CERTSortCallback)(CERTCertificate *certa,
 				    CERTCertificate *certb,
 				    void *arg);
 SECStatus
@@ -1497,16 +1508,22 @@ CERT_UnlockCertTrust(const CERTCertifica
  * non-null, the data is put there, otherwise a SECItem is allocated.
  * Allocation from "arena" if it is non-null, heap otherwise.  Any problem
  * results in a NULL being returned (and an appropriate error set).
  */ 
 extern SECItem *
 CERT_GetSPKIDigest(PLArenaPool *arena, const CERTCertificate *cert,
                    SECOidTag digestAlg, SECItem *fill);
 
+/*
+ * Digest the cert's subject name using the specified algorithm.
+ */
+extern SECItem *
+CERT_GetSubjectNameDigest(PLArenaPool *arena, const CERTCertificate *cert,
+                          SECOidTag digestAlg, SECItem *fill);
 
 SECStatus CERT_CheckCRL(CERTCertificate* cert, CERTCertificate* issuer,
                         const SECItem* dp, PRTime t, void* wincx);
 
 
 /*
  * Add a CERTNameConstraint to the CERTNameConstraint list
  */
--- a/security/nss/lib/certdb/certt.h
+++ b/security/nss/lib/certdb/certt.h
@@ -1101,16 +1101,21 @@ typedef enum {
  *              other methods.
  * CONTINUE_TESTING means:
  *                  We will continue and test the next allowed
  *                  specified method.
  */
 #define CERT_REV_M_STOP_TESTING_ON_FRESH_INFO        0UL
 #define CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO    32UL
 
+/* When this flag is used, libpkix will never attempt to use the GET HTTP
+ * method for OCSP requests; it will always use POST.
+ */
+#define CERT_REV_M_FORCE_POST_METHOD_FOR_OCSP 64UL
+
 /*
  * The following flags are supposed to be used to control bits in
  *     CERTRevocationTests.cert_rev_method_independent_flags
  * All Flags are prefixed by CERT_REV_M_, where _M_ indicates
  * this is a method independent flag.
  */
 
 /*
--- a/security/nss/lib/certdb/polcyxtn.c
+++ b/security/nss/lib/certdb/polcyxtn.c
@@ -638,16 +638,19 @@ CERT_DecodeOidSequence(const SECItem *se
 
     if ( rv != SECSuccess ) {
 	goto loser;
     }
 
     return(oidSeq);
     
 loser:
+    if (arena) {
+        PORT_FreeArena(arena, PR_FALSE);
+    }
     return(NULL);
 }
 
 
 void
 CERT_DestroyOidSequence(CERTOidSequence *oidSeq)
 {
     if ( oidSeq != NULL ) {
--- a/security/nss/lib/certhigh/ocsp.c
+++ b/security/nss/lib/certhigh/ocsp.c
@@ -19,16 +19,17 @@
 #include "secder.h"
 #include "cert.h"
 #include "xconst.h"
 #include "secerr.h"
 #include "secoid.h"
 #include "hasht.h"
 #include "sechash.h"
 #include "secasn1.h"
+#include "plbase64.h"
 #include "keyhi.h"
 #include "cryptohi.h"
 #include "ocsp.h"
 #include "ocspti.h"
 #include "ocspi.h"
 #include "genname.h"
 #include "certxutl.h"
 #include "pk11func.h"	/* for PK11_HashBuf */
@@ -81,64 +82,59 @@ static struct OCSPGlobalStruct {
     const SEC_HttpClientFcn *defaultHttpClientFcn;
     PRInt32 maxCacheEntries;
     PRUint32 minimumSecondsToNextFetchAttempt;
     PRUint32 maximumSecondsToNextFetchAttempt;
     PRUint32 timeoutSeconds;
     OCSPCacheData cache;
     SEC_OcspFailureMode ocspFailureMode;
     CERT_StringFromCertFcn alternateOCSPAIAFcn;
+    PRBool forcePost;
 } OCSP_Global = { NULL, 
                   NULL, 
                   DEFAULT_OCSP_CACHE_SIZE, 
                   DEFAULT_MINIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT,
                   DEFAULT_MAXIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT,
                   DEFAULT_OSCP_TIMEOUT_SECONDS,
                   {NULL, 0, NULL, NULL},
                   ocspMode_FailureIsVerificationFailure,
-                  NULL
+                  NULL,
+                  PR_FALSE
                 };
 
 
 
 /* Forward declarations */
 static SECItem *
 ocsp_GetEncodedOCSPResponseFromRequest(PLArenaPool *arena, 
                                        CERTOCSPRequest *request,
-                                       const char *location, PRTime time,
+                                       const char *location,
+				       const char *mechanism,
+				       PRTime time,
                                        PRBool addServiceLocator,
                                        void *pwArg,
                                        CERTOCSPRequest **pRequest);
 static SECStatus
 ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle, 
                               CERTOCSPCertID *certID, 
                               CERTCertificate *cert, 
                               PRTime time, 
                               void *pwArg,
                               PRBool *certIDWasConsumed,
                               SECStatus *rv_ocsp);
 
 static SECStatus
-ocsp_CacheEncodedOCSPResponse(CERTCertDBHandle *handle,
-			      CERTOCSPCertID *certID,
-			      CERTCertificate *cert,
-			      PRTime time,
-			      void *pwArg,
-			      const SECItem *encodedResponse,
-			      PRBool cacheInvalid,
-			      PRBool *certIDWasConsumed,
-			      SECStatus *rv_ocsp);
-
-static SECStatus
-ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle, 
-                                        CERTOCSPResponse *response, 
-                                        CERTOCSPCertID   *certID,
-                                        CERTCertificate  *signerCert,
-                                        PRTime            time,
-                                        CERTOCSPSingleResponse **pSingleResponse);
+ocsp_GetDecodedVerifiedSingleResponseForID(CERTCertDBHandle *handle,
+					   CERTOCSPCertID *certID,
+					   CERTCertificate *cert,
+					   PRTime time,
+					   void *pwArg,
+					   const SECItem *encodedResponse,
+					   CERTOCSPResponse **pDecodedResponse,
+					   CERTOCSPSingleResponse **pSingle);
 
 static SECStatus
 ocsp_CertRevokedAfter(ocspRevokedInfo *revokedInfo, PRTime time);
 
 static CERTOCSPCertID *
 cert_DupOCSPCertID(const CERTOCSPCertID *src);
 
 #ifndef DEBUG
@@ -1455,25 +1451,22 @@ static const SEC_ASN1Template ocsp_Servi
  *   Returns a NULL on error and a pointer to the SECItem with the
  *   encoded value otherwise.  Any error is likely to be low-level
  *   (e.g. no memory).
  */
 SECItem *
 CERT_EncodeOCSPRequest(PLArenaPool *arena, CERTOCSPRequest *request,
 		       void *pwArg)
 {
-    ocspTBSRequest *tbsRequest;
     SECStatus rv;
 
     /* XXX All of these should generate errors if they fail. */
     PORT_Assert(request);
     PORT_Assert(request->tbsRequest);
 
-    tbsRequest = request->tbsRequest;
-
     if (request->tbsRequest->extensionHandle != NULL) {
 	rv = CERT_FinishExtensions(request->tbsRequest->extensionHandle);
 	request->tbsRequest->extensionHandle = NULL;
 	if (rv != SECSuccess)
 	    return NULL;
     }
 
     /*
@@ -1650,19 +1643,19 @@ CERT_GetSPKIDigest(PLArenaPool *arena, c
     DER_ConvertBitString(&spk);
 
     return ocsp_DigestValue(arena, digestAlg, fill, &spk);
 }
 
 /*
  * Digest the cert's subject name using the specified algorithm.
  */
-static SECItem *
-cert_GetSubjectNameDigest(PLArenaPool *arena, const CERTCertificate *cert,
-                           SECOidTag digestAlg, SECItem *fill)
+SECItem *
+CERT_GetSubjectNameDigest(PLArenaPool *arena, const CERTCertificate *cert,
+                          SECOidTag digestAlg, SECItem *fill)
 {
     SECItem name;
 
     /*
      * Copy just the length and data pointer (nothing needs to be freed)
      * of the subject name
      */
     name = cert->derSubject;
@@ -1701,29 +1694,29 @@ ocsp_CreateCertID(PLArenaPool *arena, CE
 	goto loser; 
     }
 
     issuerCert = CERT_FindCertIssuer(cert, time, certUsageAnyCA);
     if (issuerCert == NULL) {
 	goto loser;
     }
 
-    if (cert_GetSubjectNameDigest(arena, issuerCert, SEC_OID_SHA1,
+    if (CERT_GetSubjectNameDigest(arena, issuerCert, SEC_OID_SHA1,
                                   &(certID->issuerNameHash)) == NULL) {
         goto loser;
     }
     certID->issuerSHA1NameHash.data = certID->issuerNameHash.data;
     certID->issuerSHA1NameHash.len = certID->issuerNameHash.len;
 
-    if (cert_GetSubjectNameDigest(arena, issuerCert, SEC_OID_MD5,
+    if (CERT_GetSubjectNameDigest(arena, issuerCert, SEC_OID_MD5,
                                   &(certID->issuerMD5NameHash)) == NULL) {
         goto loser;
     }
 
-    if (cert_GetSubjectNameDigest(arena, issuerCert, SEC_OID_MD2,
+    if (CERT_GetSubjectNameDigest(arena, issuerCert, SEC_OID_MD2,
                                   &(certID->issuerMD2NameHash)) == NULL) {
         goto loser;
     }
 
     if (CERT_GetSPKIDigest(arena, issuerCert, SEC_OID_SHA1,
 				   &(certID->issuerKeyHash)) == NULL) {
 	goto loser;
     }
@@ -2975,16 +2968,22 @@ loser:
 
 /*
  * Sends an encoded OCSP request to the server identified by "location",
  * and returns the socket on which it was sent (so can listen for the reply).
  * "location" is expected to be a valid URL -- an error parsing it produces
  * SEC_ERROR_CERT_BAD_ACCESS_LOCATION.  Other errors are likely problems
  * connecting to it, or writing to it, or allocating memory, and the low-level
  * errors appropriate to the problem will be set.
+ * if (encodedRequest == NULL)
+ *   then location MUST already include the full request,
+ *        including base64 and urlencode,
+ *        and the request will be sent with GET
+ * if (encodedRequest != NULL)
+ *   then the request will be sent with POST
  */
 static PRFileDesc *
 ocsp_SendEncodedRequest(const char *location, const SECItem *encodedRequest)
 {
     char *hostname = NULL;
     char *path = NULL;
     PRUint16 port;
     SECStatus rv;
@@ -3007,34 +3006,50 @@ ocsp_SendEncodedRequest(const char *loca
     if (sock == NULL)
 	goto loser;
 
     portstr[0] = '\0';
     if (port != 80) {
         PR_snprintf(portstr, sizeof(portstr), ":%d", port);
     }
 
-    header = PR_smprintf("POST %s HTTP/1.0\r\n"
-			 "Host: %s%s\r\n"
-			 "Content-Type: application/ocsp-request\r\n"
-			 "Content-Length: %u\r\n\r\n",
-			 path, hostname, portstr, encodedRequest->len);
-    if (header == NULL)
-	goto loser;
-
-    /*
-     * The NSPR documentation promises that if it can, it will write the full
-     * amount; this will not return a partial value expecting us to loop.
-     */
-    if (PR_Write(sock, header, (PRInt32) PORT_Strlen(header)) < 0)
-	goto loser;
-
-    if (PR_Write(sock, encodedRequest->data,
-		 (PRInt32) encodedRequest->len) < 0)
-	goto loser;
+    if (!encodedRequest) {
+      header = PR_smprintf("GET %s HTTP/1.0\r\n"
+                          "Host: %s%s\r\n\r\n",
+                          path, hostname, portstr);
+      if (header == NULL)
+          goto loser;
+
+      /*
+      * The NSPR documentation promises that if it can, it will write the full
+      * amount; this will not return a partial value expecting us to loop.
+      */
+      if (PR_Write(sock, header, (PRInt32) PORT_Strlen(header)) < 0)
+          goto loser;
+    }
+    else {
+      header = PR_smprintf("POST %s HTTP/1.0\r\n"
+                          "Host: %s%s\r\n"
+                          "Content-Type: application/ocsp-request\r\n"
+                          "Content-Length: %u\r\n\r\n",
+                          path, hostname, portstr, encodedRequest->len);
+      if (header == NULL)
+          goto loser;
+
+      /*
+      * The NSPR documentation promises that if it can, it will write the full
+      * amount; this will not return a partial value expecting us to loop.
+      */
+      if (PR_Write(sock, header, (PRInt32) PORT_Strlen(header)) < 0)
+          goto loser;
+
+      if (PR_Write(sock, encodedRequest->data,
+                  (PRInt32) encodedRequest->len) < 0)
+          goto loser;
+    }
 
     returnSock = sock;
     sock = NULL;
 
 loser:
     if (header != NULL)
 	PORT_Free(header);
     if (sock != NULL)
@@ -3333,16 +3348,23 @@ CERT_ParseURL(const char *url, char **pH
     return ocsp_ParseURL(url, pHostname, pPort, pPath);
 }
 
 /*
  * Limit the size of http responses we are willing to accept.
  */
 #define MAX_WANTED_OCSP_RESPONSE_LEN 64*1024
 
+/* if (encodedRequest == NULL)
+ *   then location MUST already include the full request,
+ *        including base64 and urlencode,
+ *        and the request will be sent with GET
+ * if (encodedRequest != NULL)
+ *   then the request will be sent with POST
+ */
 static SECItem *
 fetchOcspHttpClientV1(PLArenaPool *arena, 
                       const SEC_HttpClientFcnV1 *hcv1, 
                       const char *location, 
                       const SECItem *encodedRequest)
 {
     char *hostname = NULL;
     char *path = NULL;
@@ -3376,24 +3398,25 @@ fetchOcspHttpClientV1(PLArenaPool *arena
        - it's sufficient to call TryFcn once
        No lock for accessing OCSP_Global.timeoutSeconds, bug 406120
     */
 
     if ((*hcv1->createFcn)(
             pServerSession,
             "http",
             path,
-            "POST",
+            encodedRequest ? "POST" : "GET",
             PR_TicksPerSecond() * OCSP_Global.timeoutSeconds,
             &pRequestSession) != SECSuccess) {
         PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR);
         goto loser;
     }
 
-    if ((*hcv1->setPostDataFcn)(
+    if (encodedRequest &&
+        (*hcv1->setPostDataFcn)(
             pRequestSession, 
             (char*)encodedRequest->data,
             encodedRequest->len,
             "application/ocsp-request") != SECSuccess) {
         PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR);
         goto loser;
     }
 
@@ -3439,17 +3462,17 @@ loser:
 	PORT_Free(path);
     if (hostname != NULL)
 	PORT_Free(hostname);
     
     return encodedResponse;
 }
 
 /*
- * FUNCTION: CERT_GetEncodedOCSPResponse
+ * FUNCTION: CERT_GetEncodedOCSPResponseByMechanism
  *   Creates and sends a request to an OCSP responder, then reads and
  *   returns the (encoded) response.
  * INPUTS:
  *   PLArenaPool *arena
  *     Pointer to arena from which return value will be allocated.
  *     If NULL, result will be allocated from the heap (and thus should
  *     be freed via SECITEM_FreeItem).
  *   CERTCertList *certList
@@ -3457,16 +3480,21 @@ loser:
  *     Note that all of these certificates should have the same issuer,
  *     or it's expected the response will be signed by a trusted responder.
  *     If the certs need to be broken up into multiple requests, that
  *     must be handled by the caller (and thus by having multiple calls
  *     to this routine), who knows about where the request(s) are being
  *     sent and whether there are any trusted responders in place.
  *   const char *location
  *     The location of the OCSP responder (a URL).
+ *   const char *mechanism
+ *     The protocol mechanisms used when retrieving the OCSP response.
+ *     Currently support: "GET" (http GET) and "POST" (http POST).
+ *     Additionals mechanisms for http or other protocols might be added
+ *     in the future.
  *   PRTime time
  *     Indicates the time for which the certificate status is to be 
  *     determined -- this may be used in the search for the cert's issuer
  *     but has no other bearing on the operation.
  *   PRBool addServiceLocator
  *     If true, the Service Locator extension should be added to the
  *     single request(s) for each cert.
  *   CERTCertificate *signerCert
@@ -3485,73 +3513,247 @@ loser:
  *   Returns a pointer to the SECItem holding the response.
  *   On error, returns null with error set describing the reason:
  *	SEC_ERROR_UNKNOWN_ISSUER
  *	SEC_ERROR_CERT_BAD_ACCESS_LOCATION
  *	SEC_ERROR_OCSP_BAD_HTTP_RESPONSE
  *   Other errors are low-level problems (no memory, bad database, etc.).
  */
 SECItem *
-CERT_GetEncodedOCSPResponse(PLArenaPool *arena, CERTCertList *certList,
-			    const char *location, PRTime time,
-			    PRBool addServiceLocator,
-			    CERTCertificate *signerCert, void *pwArg,
-			    CERTOCSPRequest **pRequest)
+CERT_GetEncodedOCSPResponseByMechanism(PLArenaPool *arena, CERTCertList *certList,
+				       const char *location, const char *mechanism,
+				       PRTime time, PRBool addServiceLocator,
+				       CERTCertificate *signerCert, void *pwArg,
+				       CERTOCSPRequest **pRequest)
 {
     CERTOCSPRequest *request;
     request = CERT_CreateOCSPRequest(certList, time, addServiceLocator,
                                      signerCert);
     if (!request)
         return NULL;
     return ocsp_GetEncodedOCSPResponseFromRequest(arena, request, location, 
-                                                  time, addServiceLocator, 
+                                                  mechanism, time, addServiceLocator, 
                                                   pwArg, pRequest);
 }
 
+/*
+ * FUNCTION: CERT_GetEncodedOCSPResponse
+ *   Creates and sends a request to an OCSP responder, then reads and
+ *   returns the (encoded) response.
+ *
+ * This is a legacy API that behaves identically to
+ * CERT_GetEncodedOCSPResponseByMechanism using the "POST" mechanism.
+ */
+SECItem *
+CERT_GetEncodedOCSPResponse(PLArenaPool *arena, CERTCertList *certList,
+			    const char *location, PRTime time,
+			    PRBool addServiceLocator,
+			    CERTCertificate *signerCert, void *pwArg,
+			    CERTOCSPRequest **pRequest)
+{
+    return CERT_GetEncodedOCSPResponseByMechanism(arena, certList, location,
+                                                  "POST", time, addServiceLocator,
+						  signerCert, pwArg, pRequest);
+}
+
+/* URL encode a buffer that consists of base64-characters, only,
+ * which means we can use a simple encoding logic.
+ * 
+ * No output buffer size checking is performed.
+ * You should call the function twice, to calculate the required buffer size.
+ * 
+ * If the outpufBuf parameter is NULL, the function will calculate the 
+ * required size, including the trailing zero termination char.
+ * 
+ * The function returns the number of bytes calculated or produced.
+ */
+size_t
+ocsp_UrlEncodeBase64Buf(const char *base64Buf, char *outputBuf)
+{
+    const char *walkInput = NULL;
+    char *walkOutput = outputBuf;
+    size_t count = 0;
+    
+    for (walkInput=base64Buf; *walkInput; ++walkInput) {
+	char c = *walkInput;
+	if (isspace(c))
+	    continue;
+	switch (c) {
+	  case '+':
+	    if (outputBuf) {
+		strcpy(walkOutput, "%2B");
+		walkOutput += 3;
+	    }
+	    count += 3;
+	    break;
+	  case '/':
+	    if (outputBuf) {
+		strcpy(walkOutput, "%2F");
+		walkOutput += 3;
+	    }
+	    count += 3;
+	    break;
+	  case '=':
+	    if (outputBuf) {
+		strcpy(walkOutput, "%3D");
+		walkOutput += 3;
+	    }
+	    count += 3;
+	    break;
+	  default:
+	    if (outputBuf) {
+		*walkOutput = *walkInput;
+		++walkOutput;
+	    }
+	    ++count;
+	    break;
+	}
+    }
+    if (outputBuf) {
+	*walkOutput = 0;
+    }
+    ++count;
+    return count;
+}
+
+enum { max_get_request_size = 255 }; /* defined by RFC2560 */
+
+static SECItem *
+cert_GetOCSPResponse(PLArenaPool *arena, const char *location, 
+                     const SECItem *encodedRequest);
+
 static SECItem *
 ocsp_GetEncodedOCSPResponseFromRequest(PLArenaPool *arena,
                                        CERTOCSPRequest *request,
-                                       const char *location, PRTime time,
+                                       const char *location,
+				       const char *mechanism,
+				       PRTime time,
                                        PRBool addServiceLocator,
                                        void *pwArg,
                                        CERTOCSPRequest **pRequest)
 {
     SECItem *encodedRequest = NULL;
     SECItem *encodedResponse = NULL;
     SECStatus rv;
 
+    if (!location || !*location) /* location should be at least one byte */
+        goto loser;
+
     rv = CERT_AddOCSPAcceptableResponses(request,
 					 SEC_OID_PKIX_OCSP_BASIC_RESPONSE);
     if (rv != SECSuccess)
 	goto loser;
 
     encodedRequest = CERT_EncodeOCSPRequest(NULL, request, pwArg);
     if (encodedRequest == NULL)
 	goto loser;
 
-    encodedResponse = CERT_PostOCSPRequest(arena, location, encodedRequest);
+    if (!strcmp(mechanism, "GET")) {
+        encodedResponse = cert_GetOCSPResponse(arena, location, encodedRequest);
+    }
+    else if (!strcmp(mechanism, "POST")) {
+        encodedResponse = CERT_PostOCSPRequest(arena, location, encodedRequest);
+    }
+    else {
+	goto loser;
+    }
 
     if (encodedResponse != NULL && pRequest != NULL) {
 	*pRequest = request;
 	request = NULL;			/* avoid destroying below */
     }
 
 loser:
     if (request != NULL)
 	CERT_DestroyOCSPRequest(request);
     if (encodedRequest != NULL)
 	SECITEM_FreeItem(encodedRequest, PR_TRUE);
-
     return encodedResponse;
 }
 
+static SECItem *
+cert_FetchOCSPResponse(PLArenaPool *arena,  const char *location, 
+                       const SECItem *encodedRequest);
+
+/* using HTTP GET mechanism */
+static SECItem *
+cert_GetOCSPResponse(PLArenaPool *arena, const char *location, 
+                     const SECItem *encodedRequest)
+{
+    char *walkOutput = NULL;
+    char *fullGetPath = NULL;
+    size_t pathLength;
+    PRInt32 urlEncodedBufLength;
+    size_t base64size;
+    unsigned char b64ReqBuf[max_get_request_size+1];
+    size_t slashLengthIfNeeded = 0;
+    size_t getURLLength;
+    SECItem *item;
+
+    if (!location || !*location) {
+	return NULL;
+    }
+    
+    pathLength = strlen(location);
+    if (location[pathLength-1] != '/') {
+	slashLengthIfNeeded = 1;
+    }
+    
+    /* Calculation as documented by PL_Base64Encode function.
+     * Use integer conversion to avoid having to use function ceil().
+     */
+    base64size = (((encodedRequest->len +2)/3) * 4);
+    if (base64size > max_get_request_size) {
+	return NULL;
+    }
+    memset(b64ReqBuf, 0, sizeof(b64ReqBuf));
+    PL_Base64Encode(encodedRequest->data, encodedRequest->len, b64ReqBuf);
+
+    urlEncodedBufLength = ocsp_UrlEncodeBase64Buf(b64ReqBuf, NULL);
+    getURLLength = pathLength + urlEncodedBufLength + slashLengthIfNeeded;
+    
+    /* urlEncodedBufLength already contains room for the zero terminator.
+     * Add another if we must add the '/' char.
+     */
+    if (arena) {
+        fullGetPath = (char*)PORT_ArenaAlloc(arena, getURLLength);
+    } else {
+        fullGetPath = (char*)PORT_Alloc(getURLLength);
+    }
+    if (!fullGetPath) {
+	return NULL;
+    }
+ 
+    strcpy(fullGetPath, location);
+    walkOutput = fullGetPath + pathLength;
+    
+    if (walkOutput > fullGetPath && slashLengthIfNeeded) {
+        strcpy(walkOutput, "/");
+        ++walkOutput;
+    }
+    ocsp_UrlEncodeBase64Buf(b64ReqBuf, walkOutput);
+
+    item = cert_FetchOCSPResponse(arena, fullGetPath, NULL);
+    if (!arena) {
+	PORT_Free(fullGetPath);
+    }
+    return item;
+}
+
 SECItem *
 CERT_PostOCSPRequest(PLArenaPool *arena,  const char *location, 
                      const SECItem *encodedRequest)
 {
+    return cert_FetchOCSPResponse(arena, location, encodedRequest);
+}
+
+SECItem *
+cert_FetchOCSPResponse(PLArenaPool *arena,  const char *location, 
+                       const SECItem *encodedRequest)
+{
     const SEC_HttpClientFcn *registeredHttpClient;
     SECItem *encodedResponse = NULL;
 
     registeredHttpClient = SEC_GetRegisteredHttpClient();
 
     if (registeredHttpClient && registeredHttpClient->version == 1) {
         encodedResponse = fetchOcspHttpClientV1(
                               arena,
@@ -3569,28 +3771,30 @@ CERT_PostOCSPRequest(PLArenaPool *arena,
 
     return encodedResponse;
 }
 
 static SECItem *
 ocsp_GetEncodedOCSPResponseForSingleCert(PLArenaPool *arena, 
                                          CERTOCSPCertID *certID, 
                                          CERTCertificate *singleCert, 
-                                         const char *location, PRTime time,
+                                         const char *location,
+					 const char *mechanism,
+					 PRTime time,
                                          PRBool addServiceLocator,
                                          void *pwArg,
                                          CERTOCSPRequest **pRequest)
 {
     CERTOCSPRequest *request;
     request = cert_CreateSingleCertOCSPRequest(certID, singleCert, time, 
                                                addServiceLocator, NULL);
     if (!request)
         return NULL;
     return ocsp_GetEncodedOCSPResponseFromRequest(arena, request, location, 
-                                                  time, addServiceLocator, 
+                                                  mechanism, time, addServiceLocator, 
                                                   pwArg, pRequest);
 }
 
 /* Checks a certificate for the key usage extension of OCSP signer. */
 static PRBool
 ocsp_CertIsOCSPDesignatedResponder(CERTCertificate *cert)
 {
     SECStatus rv;
@@ -3784,16 +3988,19 @@ ocsp_GetSignerCertificate(CERTCertDBHand
 	} else if (issuer && ocsp_matchcert(certIndex,issuer)) {
 	    signerCert = CERT_DupCertificate(issuer);
 	} 
 	for (i=0; (signerCert == NULL) && (i < certCount); i++) {
 	    if (ocsp_matchcert(certIndex,certs[i])) {
 		signerCert = CERT_DupCertificate(certs[i]);
 	    }
 	}
+	if (signerCert == NULL) {
+	    PORT_SetError(SEC_ERROR_UNKNOWN_CERT);
+	}
     }
 
 finish:
     if (certs != NULL) {
 	CERT_DestroyCertArray(certs, certCount);
     }
 
     return signerCert;
@@ -4242,17 +4449,17 @@ ocsp_AuthorizedResponderForCertID(CERTCe
     if (keyHash != NULL) {
 
         keyHashEQ =
             (SECITEM_CompareItem(keyHash,
                                  &certID->issuerKeyHash) == SECEqual);
         SECITEM_FreeItem(keyHash, PR_TRUE);
     }
     if (keyHashEQ &&
-        (nameHash = cert_GetSubjectNameDigest(NULL, signerCert,
+        (nameHash = CERT_GetSubjectNameDigest(NULL, signerCert,
                                               hashAlg, NULL))) {
         nameHashEQ =
             (SECITEM_CompareItem(nameHash,
                                  &certID->issuerNameHash) == SECEqual);
             
         SECITEM_FreeItem(nameHash, PR_TRUE);
         if (nameHashEQ) {
             /* The issuer of the cert is the the signer of the response */
@@ -4281,17 +4488,17 @@ ocsp_AuthorizedResponderForCertID(CERTCe
          * but the following will give slightly more information.
          * Once we have an error stack, things will be much better.
          */
         PORT_SetError(SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE);
         return PR_FALSE;
     }
 
     keyHash = CERT_GetSPKIDigest(NULL, issuerCert, hashAlg, NULL);
-    nameHash = cert_GetSubjectNameDigest(NULL, issuerCert, hashAlg, NULL);
+    nameHash = CERT_GetSubjectNameDigest(NULL, issuerCert, hashAlg, NULL);
 
     CERT_DestroyCertificate(issuerCert);
 
     if (keyHash != NULL && nameHash != NULL) {
         keyHashEQ = 
             (SECITEM_CompareItem(keyHash,
                                  &certID->issuerKeyHash) == SECEqual);
 
@@ -4667,17 +4874,17 @@ ocsp_CertRevokedAfter(ocspRevokedInfo *r
 
     return SECFailure;
 }
 
 /*
  * See if the cert represented in the single response had a good status
  * at the specified time.
  */
-static SECStatus
+SECStatus
 ocsp_CertHasGoodStatus(ocspCertStatus *status, PRTime time)
 {
     SECStatus rv;
     switch (status->certStatusType) {
     case ocspCertStatus_good:
         rv = SECSuccess;
         break;
     case ocspCertStatus_revoked:
@@ -4893,18 +5100,20 @@ CERT_CacheOCSPResponseFromSideChannel(CE
 				      CERTCertificate *cert,
 				      PRTime time,
 				      const SECItem *encodedResponse,
 				      void *pwArg)
 {
     CERTOCSPCertID *certID = NULL;
     PRBool certIDWasConsumed = PR_FALSE;
     SECStatus rv = SECFailure;
-    SECStatus rvOcsp;
+    SECStatus rvOcsp = SECFailure;
     SECErrorCodes dummy_error_code; /* we ignore this */
+    CERTOCSPResponse *decodedResponse = NULL;
+    CERTOCSPSingleResponse *singleResponse = NULL;
 
     /* The OCSP cache can be in three states regarding this certificate:
      *    + Good (cached, timely, 'good' response, or revoked in the future)
      *    + Revoked (cached, timely, but doesn't fit in the last category)
      *    + Miss (no knowledge)
      *
      * Likewise, the side-channel information can be
      *    + Good (timely, 'good' response, or revoked in the future)
@@ -4935,17 +5144,17 @@ CERT_CacheOCSPResponseFromSideChannel(CE
      *
      * When we fetch from the network we might choose to cache a negative
      * result when the response is invalid. This saves us hammering, uselessly,
      * at a broken responder. However, side channels are commonly attacker
      * controlled and so we must not cache a negative result for an Invalid
      * side channel.
      */
 
-    if (!cert) {
+    if (!cert || !encodedResponse) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
     }
     certID = CERT_CreateOCSPCertID(cert, time);
     if (!certID)
         return SECFailure;
     rv = ocsp_GetCachedOCSPResponseStatusIfFresh(
         certID, time, PR_FALSE, /* ignoreGlobalOcspFailureSetting */
@@ -4953,22 +5162,31 @@ CERT_CacheOCSPResponseFromSideChannel(CE
     if (rv == SECSuccess && rvOcsp == SECSuccess) {
         /* The cached value is good. We don't want to waste time validating
          * this OCSP response. This is the first column in the table above. */
         CERT_DestroyOCSPCertID(certID);
         return rv;
     }
 
     /* The logic for caching the more recent response is handled in
-     * ocsp_CreateOrUpdateCacheEntry, which is called by this function. */
-    rv = ocsp_CacheEncodedOCSPResponse(handle, certID, cert, time,
-                                       pwArg, encodedResponse,
-                                       PR_FALSE /* don't cache if invalid */,
-                                       &certIDWasConsumed,
-                                       &rvOcsp);
+     * ocsp_CacheSingleResponse. */
+
+    rv = ocsp_GetDecodedVerifiedSingleResponseForID(handle, certID, cert,
+						    time, pwArg,
+						    encodedResponse,
+						    &decodedResponse,
+						    &singleResponse);
+    if (rv == SECSuccess) {
+	rvOcsp = ocsp_SingleResponseCertHasGoodStatus(singleResponse, time);
+	/* Cache any valid singleResponse, regardless of status. */
+	ocsp_CacheSingleResponse(certID, singleResponse, &certIDWasConsumed);
+    }
+    if (decodedResponse) {
+	CERT_DestroyOCSPResponse(decodedResponse);
+    }
     if (!certIDWasConsumed) {
         CERT_DestroyOCSPCertID(certID);
     }
     return rv == SECSuccess ? rvOcsp : rv;
 }
 
 /*
  * Status in *certIDWasConsumed will always be correct, regardless of 
@@ -4984,23 +5202,40 @@ ocsp_GetOCSPStatusFromNetwork(CERTCertDB
                               SECStatus *rv_ocsp)
 {
     char *location = NULL;
     PRBool locationIsDefault;
     SECItem *encodedResponse = NULL;
     CERTOCSPRequest *request = NULL;
     SECStatus rv = SECFailure;
 
+    CERTOCSPResponse *decodedResponse = NULL;
+    CERTOCSPSingleResponse *singleResponse = NULL;
+    enum { stageGET, stagePOST } currentStage;
+    PRBool retry = PR_FALSE;
+
     if (!certIDWasConsumed || !rv_ocsp) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
     }
     *certIDWasConsumed = PR_FALSE;
     *rv_ocsp = SECFailure;
 
+    if (!OCSP_Global.monitor) {
+        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
+        return SECFailure;
+    }
+    PR_EnterMonitor(OCSP_Global.monitor);
+    if (OCSP_Global.forcePost) {
+        currentStage = stagePOST;
+    } else {
+        currentStage = stageGET;
+    }
+    PR_ExitMonitor(OCSP_Global.monitor);
+
     /*
      * The first thing we need to do is find the location of the responder.
      * This will be the value of the default responder (if enabled), else
      * it will come out of the AIA extension in the cert (if present).
      * If we have no such location, then this cert does not "deserve" to
      * be checked -- that is, we consider it a success and just return.
      * The way we tell that is by looking at the error number to see if
      * the problem was no AIA extension was found; any other error was
@@ -5036,46 +5271,97 @@ ocsp_GetOCSPStatusFromNetwork(CERTCertDB
      */
 
     /*
      * XXX If/when signing of requests is supported, that second NULL
      * should be changed to be the signer certificate.  Not sure if that
      * should be passed into this function or retrieved via some operation
      * on the handle/context.
      */
-    encodedResponse = 
-        ocsp_GetEncodedOCSPResponseForSingleCert(NULL, certID, cert, location,
-                                                 time, locationIsDefault,
-                                                 pwArg, &request);
-    if (encodedResponse == NULL) {
-        goto loser;
-    }
-
-    rv = ocsp_CacheEncodedOCSPResponse(handle, certID, cert, time, pwArg,
-                                       encodedResponse,
-                                       PR_TRUE /* cache if invalid */,
-                                       certIDWasConsumed, rv_ocsp);
-
-loser:
-    if (request != NULL)
-	CERT_DestroyOCSPRequest(request);
-    if (encodedResponse != NULL)
-	SECITEM_FreeItem(encodedResponse, PR_TRUE);
-    if (location != NULL)
-	PORT_Free(location);
-
+
+    do {
+	const char *mechanism;
+	PRBool validResponseWithAccurateInfo = PR_FALSE;
+	retry = PR_FALSE;
+	*rv_ocsp = SECFailure;
+
+	if (currentStage == stageGET) {
+	    mechanism = "GET";
+	} else if (currentStage == stagePOST) {
+	    mechanism = "POST";
+	} else {
+	    PORT_Assert(0); /* our code is flawed */
+	}
+
+	encodedResponse = 
+	    ocsp_GetEncodedOCSPResponseForSingleCert(NULL, certID, cert,
+						     location, mechanism,
+						     time, locationIsDefault,
+						     pwArg, &request);
+
+	if (encodedResponse) {
+	    rv = ocsp_GetDecodedVerifiedSingleResponseForID(handle, certID, cert,
+							    time, pwArg,
+							    encodedResponse,
+							    &decodedResponse,
+							    &singleResponse);
+	    if (rv == SECSuccess) {
+		switch (singleResponse->certStatus->certStatusType) {
+		    case ocspCertStatus_good:
+		    case ocspCertStatus_revoked:
+			validResponseWithAccurateInfo = PR_TRUE;
+			break;
+		}
+		*rv_ocsp = ocsp_SingleResponseCertHasGoodStatus(singleResponse, time);
+	    }
+	}
+
+	if (currentStage == stageGET) {
+	    /* only accept GET response if good or revoked */
+	    if (validResponseWithAccurateInfo) {
+		ocsp_CacheSingleResponse(certID, singleResponse, 
+					 certIDWasConsumed);
+	    } else {
+		retry = PR_TRUE;
+		currentStage = stagePOST;
+	    }
+	} else {
+	    /* cache the POST respone, regardless of status */
+	    if (!singleResponse) {
+		cert_RememberOCSPProcessingFailure(certID, certIDWasConsumed);
+	    } else {
+		ocsp_CacheSingleResponse(certID, singleResponse, 
+					 certIDWasConsumed);
+	    }
+	}
+
+	if (encodedResponse) {
+	    SECITEM_FreeItem(encodedResponse, PR_TRUE);
+	    encodedResponse = NULL;
+	}
+	if (request) {
+	    CERT_DestroyOCSPRequest(request);
+	    request = NULL;
+	}
+	if (decodedResponse) {
+	    CERT_DestroyOCSPResponse(decodedResponse);
+	    decodedResponse = NULL;
+	}
+	singleResponse = NULL;
+
+    } while (retry);
+
+    PORT_Free(location);
     return rv;
 }
 
 /*
- * FUNCTION: ocsp_CacheEncodedOCSPResponse
+ * FUNCTION: ocsp_GetDecodedVerifiedSingleResponseForID
  *   This function decodes an OCSP response and checks for a valid response
- *   concerning the given certificate. If such a response is not found
- *   then nothing is cached. Otherwise, if it is a good response, or if
- *   cacheNegative is true, the results are stored in the OCSP cache.
+ *   concerning the given certificate.
  *
  *   Note: a 'valid' response is one that parses successfully, is not an OCSP
  *   exception (see RFC 2560 Section 2.3), is correctly signed and is current.
  *   A 'good' response is a valid response that attests that the certificate
  *   is not currently revoked (see RFC 2560 Section 2.2).
  *
  * INPUTS:
  *   CERTCertDBHandle *handle
@@ -5085,119 +5371,121 @@ loser:
  *   CERTCertificate *cert
  *     the certificate being checked
  *   PRTime time
  *     time for which status is to be determined
  *   void *pwArg
  *     the opaque argument to the password prompting function.
  *   SECItem *encodedResponse
  *     the DER encoded bytes of the OCSP response
- *   PRBool cacheInvalid
- *     If true then invalid responses will cause a negative cache entry to be
- *     created. (Invalid means bad syntax, bad signature etc)
- *   PRBool *certIDWasConsumed
- *     (output) on return, this is true iff |certID| was consumed by this
- *     function.
- *   SECStatus *rv_ocsp
- *     (output) on return, this is SECSuccess iff the response is good (see
- *     definition of 'good' above).
+ *   CERTOCSPResponse **pDecodedResponse
+ *     (output) The caller must ALWAYS check for this output parameter,
+ *     and if it's non-null, must destroy it using CERT_DestroyOCSPResponse.
+ *   CERTOCSPSingleResponse **pSingle
+ *     (output) on success, this points to the single response that corresponds
+ *     to the certID parameter. Points to the inside of pDecodedResponse.
+ *     It isn't a copy, don't free it.
  * RETURN:
  *   SECSuccess iff the response is valid.
  */
 static SECStatus
-ocsp_CacheEncodedOCSPResponse(CERTCertDBHandle *handle,
-			      CERTOCSPCertID *certID,
-			      CERTCertificate *cert,
-			      PRTime time,
-			      void *pwArg,
-			      const SECItem *encodedResponse,
-                              PRBool cacheInvalid,
-			      PRBool *certIDWasConsumed,
-			      SECStatus *rv_ocsp)
+ocsp_GetDecodedVerifiedSingleResponseForID(CERTCertDBHandle *handle,
+					   CERTOCSPCertID *certID,
+					   CERTCertificate *cert,
+					   PRTime time,
+					   void *pwArg,
+					   const SECItem *encodedResponse,
+					   CERTOCSPResponse **pDecodedResponse,
+					   CERTOCSPSingleResponse **pSingle)
 {
-    CERTOCSPResponse *response = NULL;
     CERTCertificate *signerCert = NULL;
     CERTCertificate *issuerCert = NULL;
-    CERTOCSPSingleResponse *single = NULL;
     SECStatus rv = SECFailure;
 
-    *certIDWasConsumed = PR_FALSE;
-    *rv_ocsp = SECFailure;
-
-    response = CERT_DecodeOCSPResponse(encodedResponse);
-    if (response == NULL) {
-	goto loser;
+    if (!pSingle || !pDecodedResponse) {
+	return SECFailure;
+    }
+    *pSingle = NULL;
+    *pDecodedResponse = CERT_DecodeOCSPResponse(encodedResponse);
+    if (!*pDecodedResponse) {
+	return SECFailure;
     }
 
     /*
      * Okay, we at least have a response that *looks* like a response!
      * Now see if the overall response status value is good or not.
      * If not, we set an error and give up.  (It means that either the
      * server had a problem, or it didn't like something about our
      * request.  Either way there is nothing to do but give up.)
      * Otherwise, we continue to find the actual per-cert status
      * in the response.
      */
-    if (CERT_GetOCSPResponseStatus(response) != SECSuccess) {
+    if (CERT_GetOCSPResponseStatus(*pDecodedResponse) != SECSuccess) {
 	goto loser;
     }
 
     /*
      * If we've made it this far, we expect a response with a good signature.
      * So, check for that.
      */
     issuerCert = CERT_FindCertIssuer(cert, time, certUsageAnyCA);
-    rv = CERT_VerifyOCSPResponseSignature(response, handle, pwArg, &signerCert,
-			issuerCert);
-    if (rv != SECSuccess)
+    rv = CERT_VerifyOCSPResponseSignature(*pDecodedResponse, handle, pwArg,
+                                          &signerCert, issuerCert);
+    if (rv != SECSuccess) {
 	goto loser;
+    }
 
     PORT_Assert(signerCert != NULL);	/* internal consistency check */
     /* XXX probably should set error, return failure if signerCert is null */
 
-
     /*
      * Again, we are only doing one request for one cert.
      * XXX When we handle cert chains, the following code will obviously
      * have to be modified, in coordation with the code above that will
      * have to determine how to make multiple requests, etc. 
      */
-
-    rv = ocsp_GetVerifiedSingleResponseForCertID(handle, response, certID, 
-                                                 signerCert, time, &single);
-    if (rv != SECSuccess)
-        goto loser;
-
-    *rv_ocsp = ocsp_SingleResponseCertHasGoodStatus(single, time);
-
+    rv = ocsp_GetVerifiedSingleResponseForCertID(handle, *pDecodedResponse, certID, 
+                                                 signerCert, time, pSingle);
 loser:
-    /* If single == NULL here then the response was invalid. */
-    if (single != NULL || cacheInvalid) {
+    if (issuerCert != NULL)
+	CERT_DestroyCertificate(issuerCert);
+    if (signerCert != NULL)
+	CERT_DestroyCertificate(signerCert);
+    return rv;
+}
+
+/*
+ * FUNCTION: ocsp_CacheSingleResponse
+ *   This function requires that the caller has checked that the response
+ *   is valid and verified. 
+ *   The (positive or negative) valid response will be used to update the cache.
+ * INPUTS:
+ *   CERTOCSPCertID *certID
+ *     the cert ID corresponding to |cert|
+ *   PRBool *certIDWasConsumed
+ *     (output) on return, this is true iff |certID| was consumed by this
+ *     function.
+ */
+void
+ocsp_CacheSingleResponse(CERTOCSPCertID *certID,
+			 CERTOCSPSingleResponse *single,
+			 PRBool *certIDWasConsumed)
+{
+    if (single != NULL) {
 	PR_EnterMonitor(OCSP_Global.monitor);
 	if (OCSP_Global.maxCacheEntries >= 0) {
-	    /* single == NULL means: remember response failure */
 	    ocsp_CreateOrUpdateCacheEntry(&OCSP_Global.cache, certID, single,
 					  certIDWasConsumed);
 	    /* ignore cache update failures */
 	}
 	PR_ExitMonitor(OCSP_Global.monitor);
     }
-
-    /* 'single' points within the response so there's no need to free it. */
-
-    if (issuerCert != NULL)
-	CERT_DestroyCertificate(issuerCert);
-    if (signerCert != NULL)
-	CERT_DestroyCertificate(signerCert);
-    if (response != NULL)
-	CERT_DestroyOCSPResponse(response);
-    return rv;
 }
 
-static SECStatus
+SECStatus
 ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle, 
                                         CERTOCSPResponse *response, 
                                         CERTOCSPCertID   *certID,
                                         CERTCertificate  *signerCert,
                                         PRTime            time,
                                         CERTOCSPSingleResponse 
                                             **pSingleResponse)
 {
@@ -5780,16 +6068,30 @@ CERT_DisableOCSPDefaultResponder(CERTCer
 
     /*
      * Finally, record the fact.
      */
     statusContext->useDefaultResponder = PR_FALSE;
     return SECSuccess;
 }
 
+SECStatus
+CERT_ForcePostMethodForOCSP(PRBool forcePost)
+{
+    if (!OCSP_Global.monitor) {
+        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
+        return SECFailure;
+    }
+
+    PR_EnterMonitor(OCSP_Global.monitor);
+    OCSP_Global.forcePost = forcePost;
+    PR_ExitMonitor(OCSP_Global.monitor);
+
+    return SECSuccess;
+}
 
 SECStatus
 CERT_GetOCSPResponseStatus(CERTOCSPResponse *response)
 {
     PORT_Assert(response);
     if (response->statusValue == ocspResponse_successful)
 	return SECSuccess;
 
--- a/security/nss/lib/certhigh/ocsp.h
+++ b/security/nss/lib/certhigh/ocsp.h
@@ -166,16 +166,25 @@ CERT_EnableOCSPDefaultResponder(CERTCert
  *     responder.
  * RETURN:
  *   Returns SECFailure if an error occurred; SECSuccess otherwise.
  *   Errors very unlikely (like random memory corruption...).
  */
 extern SECStatus
 CERT_DisableOCSPDefaultResponder(CERTCertDBHandle *handle);
 
+/* If forcePost is set, OCSP requests will only be sent using the HTTP POST
+ * method. When forcePost is not set, OCSP requests will be sent using the
+ * HTTP GET method, with a fallback to POST when we fail to receive a response
+ * and/or when we receive an uncacheable response like "Unknown." 
+ *
+ * The default is to use GET and fallback to POST.
+ */
+extern SECStatus CERT_ForcePostMethodForOCSP(PRBool forcePost);
+
 /*
  * -------------------------------------------------------
  * The Functions above are those expected to be used by a client
  * providing OCSP status checking along with every cert verification.
  * The functions below are for OCSP testing, debugging, or clients
  * or servers performing more specialized OCSP tasks.
  * -------------------------------------------------------
  */
--- a/security/nss/lib/certhigh/ocspi.h
+++ b/security/nss/lib/certhigh/ocspi.h
@@ -134,9 +134,28 @@ ocsp_GetResponderLocation(CERTCertDBHand
  * tells how to treat an ocsp response fetching failure.
  * RETURNS:
  *   if PR_TRUE is returned, then treat fetching as a
  *   revoked cert status.
  */
 PRBool
 ocsp_FetchingFailureIsVerificationFailure(void);
 
+size_t
+ocsp_UrlEncodeBase64Buf(const char *base64Buf, char *outputBuf);
+
+SECStatus
+ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle, 
+                                        CERTOCSPResponse *response, 
+                                        CERTOCSPCertID   *certID,
+                                        CERTCertificate  *signerCert,
+                                        PRTime            time,
+                                        CERTOCSPSingleResponse **pSingleResponse);
+
+SECStatus
+ocsp_CertHasGoodStatus(ocspCertStatus *status, PRTime time);
+
+void
+ocsp_CacheSingleResponse(CERTOCSPCertID *certID,
+			 CERTOCSPSingleResponse *single,
+			 PRBool *certIDWasConsumed);
+
 #endif /* _OCSPI_H_ */
--- a/security/nss/lib/ckfw/builtins/certdata.txt
+++ b/security/nss/lib/ckfw/builtins/certdata.txt
@@ -9143,149 +9143,16 @@ CKA_SERIAL_NUMBER MULTILINE_OCTAL
 \002\001\001
 END
 CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
 CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
 CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
 CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
 
 #
-# Certificate "Wells Fargo Root CA"
-#
-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 "Wells Fargo Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\202\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\024\060\022\006\003\125\004\012\023\013\127\145\154\154\163
-\040\106\141\162\147\157\061\054\060\052\006\003\125\004\013\023
-\043\127\145\154\154\163\040\106\141\162\147\157\040\103\145\162
-\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157
-\162\151\164\171\061\057\060\055\006\003\125\004\003\023\046\127
-\145\154\154\163\040\106\141\162\147\157\040\122\157\157\164\040
-\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164\150
-\157\162\151\164\171
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\202\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\024\060\022\006\003\125\004\012\023\013\127\145\154\154\163
-\040\106\141\162\147\157\061\054\060\052\006\003\125\004\013\023
-\043\127\145\154\154\163\040\106\141\162\147\157\040\103\145\162
-\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157
-\162\151\164\171\061\057\060\055\006\003\125\004\003\023\046\127
-\145\154\154\163\040\106\141\162\147\157\040\122\157\157\164\040
-\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164\150
-\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\071\344\227\236
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\345\060\202\002\315\240\003\002\001\002\002\004\071
-\344\227\236\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\060\201\202\061\013\060\011\006\003\125\004\006\023\002
-\125\123\061\024\060\022\006\003\125\004\012\023\013\127\145\154
-\154\163\040\106\141\162\147\157\061\054\060\052\006\003\125\004
-\013\023\043\127\145\154\154\163\040\106\141\162\147\157\040\103
-\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164
-\150\157\162\151\164\171\061\057\060\055\006\003\125\004\003\023
-\046\127\145\154\154\163\040\106\141\162\147\157\040\122\157\157
-\164\040\103\145\162\164\151\146\151\143\141\164\145\040\101\165
-\164\150\157\162\151\164\171\060\036\027\015\060\060\061\060\061
-\061\061\066\064\061\062\070\132\027\015\062\061\060\061\061\064
-\061\066\064\061\062\070\132\060\201\202\061\013\060\011\006\003
-\125\004\006\023\002\125\123\061\024\060\022\006\003\125\004\012
-\023\013\127\145\154\154\163\040\106\141\162\147\157\061\054\060
-\052\006\003\125\004\013\023\043\127\145\154\154\163\040\106\141
-\162\147\157\040\103\145\162\164\151\146\151\143\141\164\151\157
-\156\040\101\165\164\150\157\162\151\164\171\061\057\060\055\006
-\003\125\004\003\023\046\127\145\154\154\163\040\106\141\162\147
-\157\040\122\157\157\164\040\103\145\162\164\151\146\151\143\141
-\164\145\040\101\165\164\150\157\162\151\164\171\060\202\001\042
-\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003
-\202\001\017\000\060\202\001\012\002\202\001\001\000\325\250\063
-\073\046\371\064\377\315\233\176\345\004\107\316\000\342\175\167
-\347\061\302\056\047\245\115\150\271\061\272\215\103\131\227\307
-\163\252\177\075\134\100\236\005\345\241\342\211\331\114\270\077
-\233\371\014\264\310\142\031\054\105\256\221\036\163\161\101\304
-\113\023\375\160\302\045\254\042\365\165\013\267\123\344\245\053
-\335\316\275\034\072\172\303\367\023\217\046\124\234\026\153\153
-\257\373\330\226\261\140\232\110\340\045\042\044\171\064\316\016
-\046\000\013\116\253\375\213\316\202\327\057\010\160\150\301\250
-\012\371\164\117\007\253\244\371\342\203\176\047\163\164\076\270
-\371\070\102\374\245\250\133\110\043\263\353\343\045\262\200\256
-\226\324\012\234\302\170\232\306\150\030\256\067\142\067\136\121
-\165\250\130\143\300\121\356\100\170\176\250\257\032\240\341\260
-\170\235\120\214\173\347\263\374\216\043\260\333\145\000\160\204
-\001\010\000\024\156\124\206\232\272\314\371\067\020\366\340\336
-\204\055\235\244\205\067\323\207\343\025\320\301\027\220\176\031
-\041\152\022\251\166\375\022\002\351\117\041\136\027\002\003\001
-\000\001\243\141\060\137\060\017\006\003\125\035\023\001\001\377
-\004\005\060\003\001\001\377\060\114\006\003\125\035\040\004\105
-\060\103\060\101\006\013\140\206\110\001\206\373\173\207\007\001
-\013\060\062\060\060\006\010\053\006\001\005\005\007\002\001\026
-\044\150\164\164\160\072\057\057\167\167\167\056\167\145\154\154
-\163\146\141\162\147\157\056\143\157\155\057\143\145\162\164\160
-\157\154\151\143\171\060\015\006\011\052\206\110\206\367\015\001
-\001\005\005\000\003\202\001\001\000\322\047\335\234\012\167\053
-\273\042\362\002\265\112\112\221\371\321\055\276\344\273\032\150
-\357\016\244\000\351\356\347\357\356\366\371\345\164\244\302\330
-\122\130\304\164\373\316\153\265\073\051\171\030\132\357\233\355
-\037\153\066\356\110\045\045\024\266\126\242\020\350\356\247\177
-\320\077\243\320\303\135\046\356\007\314\303\301\044\041\207\036
-\337\052\022\123\157\101\026\347\355\256\224\372\214\162\372\023
-\107\360\074\176\256\175\021\072\023\354\355\372\157\162\144\173
-\235\175\177\046\375\172\373\045\255\352\076\051\177\114\343\000
-\127\062\260\263\351\355\123\027\331\213\262\024\016\060\350\345
-\325\023\306\144\257\304\000\325\330\130\044\374\365\217\354\361
-\307\175\245\333\017\047\321\306\362\100\210\346\037\366\141\250
-\364\102\310\271\067\323\251\276\054\126\170\302\162\233\131\135
-\065\100\212\350\116\143\032\266\351\040\152\121\342\316\244\220
-\337\166\160\231\134\160\103\115\267\266\247\031\144\116\222\267
-\305\221\074\177\110\026\145\173\026\375\313\374\373\331\325\326
-\117\041\145\073\112\177\107\243\373
-END
-
-# Trust for Certificate "Wells Fargo Root CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Wells Fargo Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\223\346\253\042\003\003\265\043\050\334\332\126\236\272\344\321
-\321\314\373\145
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\040\013\112\172\210\247\251\102\206\212\137\164\126\173\210\005
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\202\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\024\060\022\006\003\125\004\012\023\013\127\145\154\154\163
-\040\106\141\162\147\157\061\054\060\052\006\003\125\004\013\023
-\043\127\145\154\154\163\040\106\141\162\147\157\040\103\145\162
-\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157
-\162\151\164\171\061\057\060\055\006\003\125\004\003\023\046\127
-\145\154\154\163\040\106\141\162\147\157\040\122\157\157\164\040
-\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164\150
-\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\071\344\227\236
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
 # Certificate "Swisscom Root CA 1"
 #
 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 "Swisscom Root CA 1"
 CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
@@ -26211,8 +26078,542 @@ CKA_ISSUER MULTILINE_OCTAL
 END
 CKA_SERIAL_NUMBER MULTILINE_OCTAL
 \002\011\000\222\270\210\333\260\212\301\143
 END
 CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
 CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
 CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
 CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
+
+#
+# Certificate "SG TRUST SERVICES RACINE"
+#
+# Issuer: C=FR,O=SG TRUST SERVICES,OU=0002 43525289500022,CN=SG TRUST SERVICES RACINE
+# Serial Number:3e:d5:51:19:e6:4d:ce:7e
+# Subject: C=FR,O=SG TRUST SERVICES,OU=0002 43525289500022,CN=SG TRUST SERVICES RACINE
+# Not Valid Before: Mon Sep 06 12:53:42 2010
+# Not Valid After : Thu Sep 05 12:53:42 2030
+# Fingerprint (MD5): 25:EF:CF:48:4A:84:B7:30:9F:60:D3:1D:56:91:2F:E1
+# Fingerprint (SHA1): 0C:62:8F:5C:55:70:B1:C9:57:FA:FD:38:3F:B0:3D:7B:7D:D7:B9:C6
+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 "SG TRUST SERVICES RACINE"
+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
+CKA_SUBJECT MULTILINE_OCTAL
+\060\152\061\041\060\037\006\003\125\004\003\023\030\123\107\040
+\124\122\125\123\124\040\123\105\122\126\111\103\105\123\040\122
+\101\103\111\116\105\061\034\060\032\006\003\125\004\013\023\023
+\060\060\060\062\040\064\063\065\062\065\062\070\071\065\060\060
+\060\062\062\061\032\060\030\006\003\125\004\012\023\021\123\107
+\040\124\122\125\123\124\040\123\105\122\126\111\103\105\123\061
+\013\060\011\006\003\125\004\006\023\002\106\122
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\152\061\041\060\037\006\003\125\004\003\023\030\123\107\040
+\124\122\125\123\124\040\123\105\122\126\111\103\105\123\040\122
+\101\103\111\116\105\061\034\060\032\006\003\125\004\013\023\023
+\060\060\060\062\040\064\063\065\062\065\062\070\071\065\060\060
+\060\062\062\061\032\060\030\006\003\125\004\012\023\021\123\107
+\040\124\122\125\123\124\040\123\105\122\126\111\103\105\123\061
+\013\060\011\006\003\125\004\006\023\002\106\122
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\010\076\325\121\031\346\115\316\176
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\006\031\060\202\004\001\240\003\002\001\002\002\010\076
+\325\121\031\346\115\316\176\060\015\006\011\052\206\110\206\367
+\015\001\001\013\005\000\060\152\061\041\060\037\006\003\125\004
+\003\023\030\123\107\040\124\122\125\123\124\040\123\105\122\126
+\111\103\105\123\040\122\101\103\111\116\105\061\034\060\032\006
+\003\125\004\013\023\023\060\060\060\062\040\064\063\065\062\065
+\062\070\071\065\060\060\060\062\062\061\032\060\030\006\003\125
+\004\012\023\021\123\107\040\124\122\125\123\124\040\123\105\122
+\126\111\103\105\123\061\013\060\011\006\003\125\004\006\023\002
+\106\122\060\036\027\015\061\060\060\071\060\066\061\062\065\063
+\064\062\132\027\015\063\060\060\071\060\065\061\062\065\063\064
+\062\132\060\152\061\041\060\037\006\003\125\004\003\023\030\123
+\107\040\124\122\125\123\124\040\123\105\122\126\111\103\105\123
+\040\122\101\103\111\116\105\061\034\060\032\006\003\125\004\013
+\023\023\060\060\060\062\040\064\063\065\062\065\062\070\071\065
+\060\060\060\062\062\061\032\060\030\006\003\125\004\012\023\021
+\123\107\040\124\122\125\123\124\040\123\105\122\126\111\103\105
+\123\061\013\060\011\006\003\125\004\006\023\002\106\122\060\202
+\002\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005
+\000\003\202\002\017\000\060\202\002\012\002\202\002\001\000\332
+\250\126\002\354\174\225\360\116\351\012\322\267\007\243\042\213
+\120\263\271\056\031\075\127\333\031\252\322\053\344\316\102\342
+\154\241\344\135\045\036\063\035\266\105\321\264\372\131\212\126
+\160\311\155\010\166\151\160\232\346\307\234\010\060\023\376\346
+\321\222\150\141\076\114\021\362\156\362\261\173\127\126\113\011
+\275\334\017\331\161\014\350\232\067\336\042\020\034\231\136\326
+\261\027\007\323\244\071\055\302\032\163\375\312\113\051\007\302
+\171\051\310\310\046\256\054\304\374\043\310\113\342\206\126\017
+\050\375\266\207\033\150\137\071\144\105\375\150\203\154\165\044
+\036\074\165\231\141\372\322\024\370\251\113\261\330\175\247\170
+\322\023\142\145\265\326\276\176\152\003\274\265\262\374\144\060
+\303\320\302\231\075\231\244\323\315\321\261\304\123\207\173\114
+\023\023\146\177\277\325\145\123\150\371\134\036\345\264\377\066
+\231\105\243\237\142\300\177\021\202\001\124\336\017\145\245\071
+\256\235\110\114\211\243\020\073\340\346\203\365\260\332\054\036
+\172\034\134\037\000\254\314\253\247\140\144\263\306\305\173\307
+\125\106\164\074\220\201\016\112\216\131\235\124\260\110\261\122
+\114\073\230\356\253\332\064\267\123\315\111\332\057\353\225\276
+\014\127\021\366\226\114\004\171\134\231\325\345\344\276\157\352
+\107\356\121\113\357\042\046\256\265\330\021\252\103\273\170\277
+\013\176\264\335\317\164\035\045\251\211\143\261\342\064\201\304
+\210\065\070\342\002\015\017\023\311\325\052\202\025\360\212\304
+\103\062\126\344\123\035\035\254\266\317\175\233\226\135\036\144
+\351\164\163\304\126\344\026\112\122\155\222\071\323\341\115\016
+\077\142\271\336\255\265\035\145\271\135\122\376\135\011\251\234
+\264\244\014\331\057\105\166\245\317\216\152\232\236\252\260\021
+\241\353\141\306\353\077\036\374\146\264\022\235\106\177\062\026
+\211\276\161\105\257\221\041\331\375\223\277\264\002\221\102\377
+\111\037\355\213\025\150\335\037\216\254\233\335\202\005\234\104
+\151\026\144\027\126\137\101\017\112\117\004\017\145\120\206\223
+\227\354\105\277\135\302\034\334\317\304\330\072\346\170\005\320
+\305\125\125\251\136\376\253\072\041\273\345\162\024\367\013\002
+\003\001\000\001\243\201\302\060\201\277\060\035\006\003\125\035
+\016\004\026\004\024\051\040\313\361\303\017\332\006\216\023\223
+\207\376\137\140\032\051\273\363\266\060\017\006\003\125\035\023
+\001\001\377\004\005\060\003\001\001\377\060\037\006\003\125\035
+\043\004\030\060\026\200\024\051\040\313\361\303\017\332\006\216
+\023\223\207\376\137\140\032\051\273\363\266\060\021\006\003\125
+\035\040\004\012\060\010\060\006\006\004\125\035\040\000\060\111
+\006\003\125\035\037\004\102\060\100\060\076\240\074\240\072\206
+\070\150\164\164\160\072\057\057\143\162\154\056\163\147\164\162
+\165\163\164\163\145\162\166\151\143\145\163\056\143\157\155\057
+\162\141\143\151\156\145\055\107\162\157\165\160\145\123\107\057
+\114\141\164\145\163\164\103\122\114\060\016\006\003\125\035\017
+\001\001\377\004\004\003\002\001\006\060\015\006\011\052\206\110
+\206\367\015\001\001\013\005\000\003\202\002\001\000\114\106\147
+\340\104\120\365\305\266\272\262\121\012\045\023\035\267\307\210
+\056\037\271\053\144\240\313\223\210\122\131\252\140\365\314\051
+\122\027\377\004\347\067\264\061\021\106\176\053\036\154\247\213
+\074\107\232\136\364\252\135\220\073\105\075\237\112\311\212\173
+\216\300\356\076\171\213\222\243\310\224\112\270\050\021\153\246
+\045\137\135\275\307\310\373\203\117\125\061\346\134\360\023\174
+\343\275\177\052\054\067\067\224\111\257\204\037\024\047\242\130
+\020\217\012\071\067\032\022\040\101\217\031\366\251\037\031\355
+\262\064\262\255\175\063\104\213\137\012\007\103\362\166\105\105
+\055\255\344\215\016\000\375\004\010\252\347\153\373\027\275\260
+\010\126\016\065\052\162\360\263\347\115\072\117\015\334\363\140
+\022\263\070\144\214\333\371\341\046\215\057\357\116\350\044\107
+\076\066\064\212\151\017\050\153\213\207\306\275\205\046\371\323
+\353\151\041\126\140\221\326\367\340\142\302\250\161\256\056\336
+\146\043\265\122\106\246\244\110\067\054\177\001\026\127\021\367
+\047\015\016\345\017\326\220\105\341\036\077\041\334\322\374\026
+\030\023\076\115\152\262\046\152\100\136\045\170\375\070\364\254
+\130\172\067\033\230\100\004\307\216\311\324\304\147\141\261\230
+\256\360\315\016\334\271\257\145\203\173\012\004\212\077\141\252
+\367\135\101\206\346\306\114\302\117\072\134\126\352\050\073\247
+\104\317\310\112\144\365\162\140\055\343\103\270\112\340\165\074
+\062\344\252\026\327\021\271\301\105\331\233\146\143\146\345\042
+\267\064\356\272\325\164\057\045\144\363\201\124\313\167\336\127
+\324\223\343\254\007\061\072\076\134\003\203\127\123\307\360\376
+\150\330\045\120\115\022\310\346\341\225\215\147\253\074\223\077
+\027\002\272\070\327\236\367\060\245\075\075\104\001\063\032\232
+\237\216\320\237\361\356\060\210\163\357\256\044\031\272\227\163
+\025\301\354\161\014\204\144\265\173\354\274\151\076\244\155\011
+\026\066\312\112\071\212\313\247\173\306\035\176\347\063\210\311
+\276\060\155\234\205\225\041\351\107\073\006\176\201\342\352\106
+\346\160\130\200\346\250\362\235\013\151\321\063\211\131\060\363
+\144\323\013\366\316\053\011\373\175\020\166\056\020
+END
+
+# Trust for "SG TRUST SERVICES RACINE"
+# Issuer: C=FR,O=SG TRUST SERVICES,OU=0002 43525289500022,CN=SG TRUST SERVICES RACINE
+# Serial Number:3e:d5:51:19:e6:4d:ce:7e
+# Subject: C=FR,O=SG TRUST SERVICES,OU=0002 43525289500022,CN=SG TRUST SERVICES RACINE
+# Not Valid Before: Mon Sep 06 12:53:42 2010
+# Not Valid After : Thu Sep 05 12:53:42 2030
+# Fingerprint (MD5): 25:EF:CF:48:4A:84:B7:30:9F:60:D3:1D:56:91:2F:E1
+# Fingerprint (SHA1): 0C:62:8F:5C:55:70:B1:C9:57:FA:FD:38:3F:B0:3D:7B:7D:D7:B9:C6
+CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
+CKA_TOKEN CK_BBOOL CK_TRUE
+CKA_PRIVATE CK_BBOOL CK_FALSE
+CKA_MODIFIABLE CK_BBOOL CK_FALSE
+CKA_LABEL UTF8 "SG TRUST SERVICES RACINE"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\014\142\217\134\125\160\261\311\127\372\375\070\077\260\075\173
+\175\327\271\306
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\045\357\317\110\112\204\267\060\237\140\323\035\126\221\057\341
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\152\061\041\060\037\006\003\125\004\003\023\030\123\107\040
+\124\122\125\123\124\040\123\105\122\126\111\103\105\123\040\122
+\101\103\111\116\105\061\034\060\032\006\003\125\004\013\023\023
+\060\060\060\062\040\064\063\065\062\065\062\070\071\065\060\060
+\060\062\062\061\032\060\030\006\003\125\004\012\023\021\123\107
+\040\124\122\125\123\124\040\123\105\122\126\111\103\105\123\061
+\013\060\011\006\003\125\004\006\023\002\106\122
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\010\076\325\121\031\346\115\316\176
+END
+CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
+CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
+CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
+CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
+
+#
+# Certificate "ACCVRAIZ1"
+#
+# Issuer: C=ES,O=ACCV,OU=PKIACCV,CN=ACCVRAIZ1
+# Serial Number:5e:c3:b7:a6:43:7f:a4:e0
+# Subject: C=ES,O=ACCV,OU=PKIACCV,CN=ACCVRAIZ1
+# Not Valid Before: Thu May 05 09:37:37 2011
+# Not Valid After : Tue Dec 31 09:37:37 2030
+# Fingerprint (MD5): D0:A0:5A:EE:05:B6:09:94:21:A1:7D:F1:B2:29:82:02
+# Fingerprint (SHA1): 93:05:7A:88:15:C6:4F:CE:88:2F:FA:91:16:52:28:78:BC:53:64:17
+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 "ACCVRAIZ1"
+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
+CKA_SUBJECT MULTILINE_OCTAL
+\060\102\061\022\060\020\006\003\125\004\003\014\011\101\103\103
+\126\122\101\111\132\061\061\020\060\016\006\003\125\004\013\014
+\007\120\113\111\101\103\103\126\061\015\060\013\006\003\125\004
+\012\014\004\101\103\103\126\061\013\060\011\006\003\125\004\006
+\023\002\105\123
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\102\061\022\060\020\006\003\125\004\003\014\011\101\103\103
+\126\122\101\111\132\061\061\020\060\016\006\003\125\004\013\014
+\007\120\113\111\101\103\103\126\061\015\060\013\006\003\125\004
+\012\014\004\101\103\103\126\061\013\060\011\006\003\125\004\006
+\023\002\105\123
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\010\136\303\267\246\103\177\244\340
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\007\323\060\202\005\273\240\003\002\001\002\002\010\136
+\303\267\246\103\177\244\340\060\015\006\011\052\206\110\206\367
+\015\001\001\005\005\000\060\102\061\022\060\020\006\003\125\004
+\003\014\011\101\103\103\126\122\101\111\132\061\061\020\060\016
+\006\003\125\004\013\014\007\120\113\111\101\103\103\126\061\015
+\060\013\006\003\125\004\012\014\004\101\103\103\126\061\013\060
+\011\006\003\125\004\006\023\002\105\123\060\036\027\015\061\061
+\060\065\060\065\060\071\063\067\063\067\132\027\015\063\060\061
+\062\063\061\060\071\063\067\063\067\132\060\102\061\022\060\020
+\006\003\125\004\003\014\011\101\103\103\126\122\101\111\132\061
+\061\020\060\016\006\003\125\004\013\014\007\120\113\111\101\103
+\103\126\061\015\060\013\006\003\125\004\012\014\004\101\103\103
+\126\061\013\060\011\006\003\125\004\006\023\002\105\123\060\202
+\002\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005
+\000\003\202\002\017\000\060\202\002\012\002\202\002\001\000\233
+\251\253\277\141\112\227\257\057\227\146\232\164\137\320\331\226
+\375\317\342\344\146\357\037\037\107\063\302\104\243\337\232\336
+\037\265\124\335\025\174\151\065\021\157\273\310\014\216\152\030
+\036\330\217\331\026\274\020\110\066\134\360\143\263\220\132\134
+\044\067\327\243\326\313\011\161\271\361\001\162\204\260\175\333
+\115\200\315\374\323\157\311\370\332\266\016\202\322\105\205\250
+\033\150\250\075\350\364\104\154\275\241\302\313\003\276\214\076
+\023\000\204\337\112\110\300\343\042\012\350\351\067\247\030\114
+\261\011\015\043\126\177\004\115\331\027\204\030\245\310\332\100
+\224\163\353\316\016\127\074\003\201\072\235\012\241\127\103\151
+\254\127\155\171\220\170\345\265\264\073\330\274\114\215\050\241
+\247\243\247\272\002\116\045\321\052\256\355\256\003\042\270\153
+\040\017\060\050\124\225\177\340\356\316\012\146\235\321\100\055
+\156\042\257\235\032\301\005\031\322\157\300\362\237\370\173\263
+\002\102\373\120\251\035\055\223\017\043\253\306\301\017\222\377
+\320\242\025\365\123\011\161\034\377\105\023\204\346\046\136\370
+\340\210\034\012\374\026\266\250\163\006\270\360\143\204\002\240
+\306\132\354\347\164\337\160\256\243\203\045\352\326\307\227\207
+\223\247\306\212\212\063\227\140\067\020\076\227\076\156\051\025
+\326\241\017\321\210\054\022\237\157\252\244\306\102\353\101\242
+\343\225\103\323\001\205\155\216\273\073\363\043\066\307\376\073
+\340\241\045\007\110\253\311\211\164\377\010\217\200\277\300\226
+\145\363\356\354\113\150\275\235\210\303\061\263\100\361\350\317
+\366\070\273\234\344\321\177\324\345\130\233\174\372\324\363\016
+\233\165\221\344\272\122\056\031\176\321\365\315\132\031\374\272
+\006\366\373\122\250\113\231\004\335\370\371\264\213\120\243\116
+\142\211\360\207\044\372\203\102\301\207\372\325\055\051\052\132
+\161\172\144\152\327\047\140\143\015\333\316\111\365\215\037\220
+\211\062\027\370\163\103\270\322\132\223\206\141\326\341\165\012
+\352\171\146\166\210\117\161\353\004\045\326\012\132\172\223\345
+\271\113\027\100\017\261\266\271\365\336\117\334\340\263\254\073
+\021\160\140\204\112\103\156\231\040\300\051\161\012\300\145\002
+\003\001\000\001\243\202\002\313\060\202\002\307\060\175\006\010
+\053\006\001\005\005\007\001\001\004\161\060\157\060\114\006\010
+\053\006\001\005\005\007\060\002\206\100\150\164\164\160\072\057
+\057\167\167\167\056\141\143\143\166\056\145\163\057\146\151\154
+\145\141\144\155\151\156\057\101\162\143\150\151\166\157\163\057
+\143\145\162\164\151\146\151\143\141\144\157\163\057\162\141\151
+\172\141\143\143\166\061\056\143\162\164\060\037\006\010\053\006
+\001\005\005\007\060\001\206\023\150\164\164\160\072\057\057\157
+\143\163\160\056\141\143\143\166\056\145\163\060\035\006\003\125
+\035\016\004\026\004\024\322\207\264\343\337\067\047\223\125\366
+\126\352\201\345\066\314\214\036\077\275\060\017\006\003\125\035
+\023\001\001\377\004\005\060\003\001\001\377\060\037\006\003\125
+\035\043\004\030\060\026\200\024\322\207\264\343\337\067\047\223
+\125\366\126\352\201\345\066\314\214\036\077\275\060\202\001\163
+\006\003\125\035\040\004\202\001\152\060\202\001\146\060\202\001
+\142\006\004\125\035\040\000\060\202\001\130\060\202\001\042\006
+\010\053\006\001\005\005\007\002\002\060\202\001\024\036\202\001
+\020\000\101\000\165\000\164\000\157\000\162\000\151\000\144\000
+\141\000\144\000\040\000\144\000\145\000\040\000\103\000\145\000
+\162\000\164\000\151\000\146\000\151\000\143\000\141\000\143\000
+\151\000\363\000\156\000\040\000\122\000\141\000\355\000\172\000
+\040\000\144\000\145\000\040\000\154\000\141\000\040\000\101\000
+\103\000\103\000\126\000\040\000\050\000\101\000\147\000\145\000
+\156\000\143\000\151\000\141\000\040\000\144\000\145\000\040\000
+\124\000\145\000\143\000\156\000\157\000\154\000\157\000\147\000
+\355\000\141\000\040\000\171\000\040\000\103\000\145\000\162\000
+\164\000\151\000\146\000\151\000\143\000\141\000\143\000\151\000
+\363\000\156\000\040\000\105\000\154\000\145\000\143\000\164\000
+\162\000\363\000\156\000\151\000\143\000\141\000\054\000\040\000
+\103\000\111\000\106\000\040\000\121\000\064\000\066\000\060\000
+\061\000\061\000\065\000\066\000\105\000\051\000\056\000\040\000
+\103\000\120\000\123\000\040\000\145\000\156\000\040\000\150\000
+\164\000\164\000\160\000\072\000\057\000\057\000\167\000\167\000
+\167\000\056\000\141\000\143\000\143\000\166\000\056\000\145\000
+\163\060\060\006\010\053\006\001\005\005\007\002\001\026\044\150
+\164\164\160\072\057\057\167\167\167\056\141\143\143\166\056\145
+\163\057\154\145\147\151\163\154\141\143\151\157\156\137\143\056
+\150\164\155\060\125\006\003\125\035\037\004\116\060\114\060\112
+\240\110\240\106\206\104\150\164\164\160\072\057\057\167\167\167
+\056\141\143\143\166\056\145\163\057\146\151\154\145\141\144\155
+\151\156\057\101\162\143\150\151\166\157\163\057\143\145\162\164
+\151\146\151\143\141\144\157\163\057\162\141\151\172\141\143\143
+\166\061\137\144\145\162\056\143\162\154\060\016\006\003\125\035
+\017\001\001\377\004\004\003\002\001\006\060\027\006\003\125\035
+\021\004\020\060\016\201\014\141\143\143\166\100\141\143\143\166
+\056\145\163\060\015\006\011\052\206\110\206\367\015\001\001\005
+\005\000\003\202\002\001\000\227\061\002\237\347\375\103\147\110
+\104\024\344\051\207\355\114\050\146\320\217\065\332\115\141\267
+\112\227\115\265\333\220\340\005\056\016\306\171\320\362\227\151
+\017\275\004\107\331\276\333\265\051\332\233\331\256\251\231\325
+\323\074\060\223\365\215\241\250\374\006\215\104\364\312\026\225
+\174\063\334\142\213\250\067\370\047\330\011\055\033\357\310\024
+\047\040\251\144\104\377\056\326\165\252\154\115\140\100\031\111
+\103\124\143\332\342\314\272\146\345\117\104\172\133\331\152\201
+\053\100\325\177\371\001\047\130\054\310\355\110\221\174\077\246
+\000\317\304\051\163\021\066\336\206\031\076\235\356\031\212\033
+\325\260\355\216\075\234\052\300\015\330\075\146\343\074\015\275
+\325\224\134\342\342\247\065\033\004\000\366\077\132\215\352\103
+\275\137\211\035\251\301\260\314\231\342\115\000\012\332\311\047
+\133\347\023\220\134\344\365\063\242\125\155\334\340\011\115\057
+\261\046\133\047\165\000\011\304\142\167\051\010\137\236\131\254
+\266\176\255\237\124\060\042\003\301\036\161\144\376\371\070\012
+\226\030\335\002\024\254\043\313\006\034\036\244\175\215\015\336
+\047\101\350\255\332\025\267\260\043\335\053\250\323\332\045\207
+\355\350\125\104\115\210\364\066\176\204\232\170\254\367\016\126
+\111\016\326\063\045\326\204\120\102\154\040\022\035\052\325\276
+\274\362\160\201\244\160\140\276\005\265\233\236\004\104\276\141
+\043\254\351\245\044\214\021\200\224\132\242\242\271\111\322\301
+\334\321\247\355\061\021\054\236\031\246\356\341\125\341\300\352
+\317\015\204\344\027\267\242\174\245\336\125\045\006\356\314\300
+\207\134\100\332\314\225\077\125\340\065\307\270\204\276\264\135
+\315\172\203\001\162\356\207\346\137\035\256\265\205\306\046\337
+\346\301\232\351\036\002\107\237\052\250\155\251\133\317\354\105
+\167\177\230\047\232\062\135\052\343\204\356\305\230\146\057\226
+\040\035\335\330\303\047\327\260\371\376\331\175\315\320\237\217
+\013\024\130\121\237\057\213\303\070\055\336\350\217\326\215\207
+\244\365\126\103\026\231\054\364\244\126\264\064\270\141\067\311
+\302\130\200\033\240\227\241\374\131\215\351\021\366\321\017\113
+\125\064\106\052\213\206\073
+END
+
+# Trust for "ACCVRAIZ1"
+# Issuer: C=ES,O=ACCV,OU=PKIACCV,CN=ACCVRAIZ1
+# Serial Number:5e:c3:b7:a6:43:7f:a4:e0
+# Subject: C=ES,O=ACCV,OU=PKIACCV,CN=ACCVRAIZ1
+# Not Valid Before: Thu May 05 09:37:37 2011
+# Not Valid After : Tue Dec 31 09:37:37 2030
+# Fingerprint (MD5): D0:A0:5A:EE:05:B6:09:94:21:A1:7D:F1:B2:29:82:02
+# Fingerprint (SHA1): 93:05:7A:88:15:C6:4F:CE:88:2F:FA:91:16:52:28:78:BC:53:64:17
+CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
+CKA_TOKEN CK_BBOOL CK_TRUE
+CKA_PRIVATE CK_BBOOL CK_FALSE
+CKA_MODIFIABLE CK_BBOOL CK_FALSE
+CKA_LABEL UTF8 "ACCVRAIZ1"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\223\005\172\210\025\306\117\316\210\057\372\221\026\122\050\170
+\274\123\144\027
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\320\240\132\356\005\266\011\224\041\241\175\361\262\051\202\002
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\102\061\022\060\020\006\003\125\004\003\014\011\101\103\103
+\126\122\101\111\132\061\061\020\060\016\006\003\125\004\013\014
+\007\120\113\111\101\103\103\126\061\015\060\013\006\003\125\004
+\012\014\004\101\103\103\126\061\013\060\011\006\003\125\004\006
+\023\002\105\123
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\010\136\303\267\246\103\177\244\340
+END
+CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
+CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
+CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
+CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
+
+#
+# Certificate "TWCA Global Root CA"
+#
+# Issuer: CN=TWCA Global Root CA,OU=Root CA,O=TAIWAN-CA,C=TW
+# Serial Number: 3262 (0xcbe)
+# Subject: CN=TWCA Global Root CA,OU=Root CA,O=TAIWAN-CA,C=TW
+# Not Valid Before: Wed Jun 27 06:28:33 2012
+# Not Valid After : Tue Dec 31 15:59:59 2030
+# Fingerprint (MD5): F9:03:7E:CF:E6:9E:3C:73:7A:2A:90:07:69:FF:2B:96
+# Fingerprint (SHA1): 9C:BB:48:53:F6:A4:F6:D3:52:A4:E8:32:52:55:60:13:F5:AD:AF:65
+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 "TWCA Global Root CA"
+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
+CKA_SUBJECT MULTILINE_OCTAL
+\060\121\061\013\060\011\006\003\125\004\006\023\002\124\127\061
+\022\060\020\006\003\125\004\012\023\011\124\101\111\127\101\116
+\055\103\101\061\020\060\016\006\003\125\004\013\023\007\122\157
+\157\164\040\103\101\061\034\060\032\006\003\125\004\003\023\023
+\124\127\103\101\040\107\154\157\142\141\154\040\122\157\157\164
+\040\103\101
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\121\061\013\060\011\006\003\125\004\006\023\002\124\127\061
+\022\060\020\006\003\125\004\012\023\011\124\101\111\127\101\116
+\055\103\101\061\020\060\016\006\003\125\004\013\023\007\122\157
+\157\164\040\103\101\061\034\060\032\006\003\125\004\003\023\023
+\124\127\103\101\040\107\154\157\142\141\154\040\122\157\157\164
+\040\103\101
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\002\014\276
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\005\101\060\202\003\051\240\003\002\001\002\002\002\014
+\276\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000
+\060\121\061\013\060\011\006\003\125\004\006\023\002\124\127\061
+\022\060\020\006\003\125\004\012\023\011\124\101\111\127\101\116
+\055\103\101\061\020\060\016\006\003\125\004\013\023\007\122\157
+\157\164\040\103\101\061\034\060\032\006\003\125\004\003\023\023
+\124\127\103\101\040\107\154\157\142\141\154\040\122\157\157\164
+\040\103\101\060\036\027\015\061\062\060\066\062\067\060\066\062
+\070\063\063\132\027\015\063\060\061\062\063\061\061\065\065\071
+\065\071\132\060\121\061\013\060\011\006\003\125\004\006\023\002
+\124\127\061\022\060\020\006\003\125\004\012\023\011\124\101\111
+\127\101\116\055\103\101\061\020\060\016\006\003\125\004\013\023
+\007\122\157\157\164\040\103\101\061\034\060\032\006\003\125\004
+\003\023\023\124\127\103\101\040\107\154\157\142\141\154\040\122
+\157\157\164\040\103\101\060\202\002\042\060\015\006\011\052\206
+\110\206\367\015\001\001\001\005\000\003\202\002\017\000\060\202
+\002\012\002\202\002\001\000\260\005\333\310\353\214\304\156\212
+\041\357\216\115\234\161\012\037\122\160\355\155\202\234\227\305
+\327\114\116\105\111\313\100\102\265\022\064\154\031\302\164\244
+\061\137\205\002\227\354\103\063\012\123\322\234\214\216\267\270
+\171\333\053\325\152\362\216\146\304\356\053\001\007\222\324\263
+\320\002\337\120\366\125\257\146\016\313\340\107\140\057\053\062
+\071\065\122\072\050\203\370\173\026\306\030\270\142\326\107\045
+\221\316\360\031\022\115\255\143\365\323\077\165\137\051\360\241
+\060\034\052\240\230\246\025\275\356\375\031\066\360\342\221\103
+\217\372\312\326\020\047\111\114\357\335\301\361\205\160\233\312
+\352\250\132\103\374\155\206\157\163\351\067\105\251\360\066\307
+\314\210\165\036\273\154\006\377\233\153\076\027\354\141\252\161
+\174\306\035\242\367\111\351\025\265\074\326\241\141\365\021\367
+\005\157\035\375\021\276\320\060\007\302\051\260\011\116\046\334
+\343\242\250\221\152\037\302\221\105\210\134\345\230\270\161\245
+\025\031\311\174\165\021\314\160\164\117\055\233\035\221\104\375
+\126\050\240\376\273\206\152\310\372\134\013\130\334\306\113\166
+\310\253\042\331\163\017\245\364\132\002\211\077\117\236\042\202
+\356\242\164\123\052\075\123\047\151\035\154\216\062\054\144\000
+\046\143\141\066\116\243\106\267\077\175\263\055\254\155\220\242
+\225\242\316\317\332\202\347\007\064\031\226\351\270\041\252\051
+\176\246\070\276\216\051\112\041\146\171\037\263\303\265\011\147
+\336\326\324\007\106\363\052\332\346\042\067\140\313\201\266\017
+\240\017\351\310\225\177\277\125\221\005\172\317\075\025\300\157
+\336\011\224\001\203\327\064\033\314\100\245\360\270\233\147\325
+\230\221\073\247\204\170\225\046\244\132\010\370\053\164\264\000
+\004\074\337\270\024\216\350\337\251\215\154\147\222\063\035\300
+\267\322\354\222\310\276\011\277\054\051\005\157\002\153\236\357
+\274\277\052\274\133\300\120\217\101\160\161\207\262\115\267\004
+\251\204\243\062\257\256\356\153\027\213\262\261\376\154\341\220
+\214\210\250\227\110\316\310\115\313\363\006\317\137\152\012\102
+\261\036\036\167\057\216\240\346\222\016\006\374\005\042\322\046
+\341\061\121\175\062\334\017\002\003\001\000\001\243\043\060\041
+\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001\006
+\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001
+\377\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000
+\003\202\002\001\000\137\064\201\166\357\226\035\325\345\265\331
+\002\143\204\026\301\256\240\160\121\247\367\114\107\065\310\013
+\327\050\075\211\161\331\252\063\101\352\024\033\154\041\000\300
+\154\102\031\176\237\151\133\040\102\337\242\322\332\304\174\227
+\113\215\260\350\254\310\356\245\151\004\231\012\222\246\253\047
+\056\032\115\201\277\204\324\160\036\255\107\376\375\112\235\063
+\340\362\271\304\105\010\041\012\332\151\151\163\162\015\276\064
+\376\224\213\255\303\036\065\327\242\203\357\345\070\307\245\205
+\037\253\317\064\354\077\050\376\014\361\127\206\116\311\125\367
+\034\324\330\245\175\006\172\157\325\337\020\337\201\116\041\145
+\261\266\341\027\171\225\105\006\316\137\314\334\106\211\143\150
+\104\215\223\364\144\160\240\075\235\050\005\303\071\160\270\142
+\173\040\375\344\333\351\010\241\270\236\075\011\307\117\373\054
+\370\223\166\101\336\122\340\341\127\322\235\003\274\167\236\376
+\236\051\136\367\301\121\140\037\336\332\013\262\055\165\267\103
+\110\223\347\366\171\306\204\135\200\131\140\224\374\170\230\217
+\074\223\121\355\100\220\007\337\144\143\044\313\116\161\005\241
+\327\224\032\210\062\361\042\164\042\256\245\246\330\022\151\114
+\140\243\002\356\053\354\324\143\222\013\136\276\057\166\153\243
+\266\046\274\217\003\330\012\362\114\144\106\275\071\142\345\226
+\353\064\143\021\050\314\225\361\255\357\357\334\200\130\110\351
+\113\270\352\145\254\351\374\200\265\265\310\105\371\254\301\237
+\331\271\352\142\210\216\304\361\113\203\022\255\346\213\204\326
+\236\302\353\203\030\237\152\273\033\044\140\063\160\314\354\367
+\062\363\134\331\171\175\357\236\244\376\311\043\303\044\356\025
+\222\261\075\221\117\046\206\275\146\163\044\023\352\244\256\143
+\301\255\175\204\003\074\020\170\206\033\171\343\304\363\362\004
+\225\040\256\043\202\304\263\072\000\142\277\346\066\044\341\127
+\272\307\036\220\165\325\137\077\225\141\053\301\073\315\345\263
+\150\141\320\106\046\251\041\122\151\055\353\056\307\353\167\316
+\246\072\265\003\063\117\166\321\347\134\124\001\135\313\170\364
+\311\014\277\317\022\216\027\055\043\150\224\347\253\376\251\262
+\053\006\320\004\315
+END
+
+# Trust for "TWCA Global Root CA"
+# Issuer: CN=TWCA Global Root CA,OU=Root CA,O=TAIWAN-CA,C=TW
+# Serial Number: 3262 (0xcbe)
+# Subject: CN=TWCA Global Root CA,OU=Root CA,O=TAIWAN-CA,C=TW
+# Not Valid Before: Wed Jun 27 06:28:33 2012
+# Not Valid After : Tue Dec 31 15:59:59 2030
+# Fingerprint (MD5): F9:03:7E:CF:E6:9E:3C:73:7A:2A:90:07:69:FF:2B:96
+# Fingerprint (SHA1): 9C:BB:48:53:F6:A4:F6:D3:52:A4:E8:32:52:55:60:13:F5:AD:AF:65
+CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
+CKA_TOKEN CK_BBOOL CK_TRUE
+CKA_PRIVATE CK_BBOOL CK_FALSE
+CKA_MODIFIABLE CK_BBOOL CK_FALSE
+CKA_LABEL UTF8 "TWCA Global Root CA"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\234\273\110\123\366\244\366\323\122\244\350\062\122\125\140\023
+\365\255\257\145
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\371\003\176\317\346\236\074\163\172\052\220\007\151\377\053\226
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\121\061\013\060\011\006\003\125\004\006\023\002\124\127\061
+\022\060\020\006\003\125\004\012\023\011\124\101\111\127\101\116
+\055\103\101\061\020\060\016\006\003\125\004\013\023\007\122\157
+\157\164\040\103\101\061\034\060\032\006\003\125\004\003\023\023
+\124\127\103\101\040\107\154\157\142\141\154\040\122\157\157\164
+\040\103\101
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\002\014\276
+END
+CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
+CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
+CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
+CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
--- a/security/nss/lib/ckfw/builtins/nssckbi.h
+++ b/security/nss/lib/ckfw/builtins/nssckbi.h
@@ -40,18 +40,18 @@
  *     ...
  *   - NSS 3.29 branch: 250-255
  *
  * NSS_BUILTINS_LIBRARY_VERSION_MINOR is a CK_BYTE.  It's not clear
  * whether we may use its full range (0-255) or only 0-99 because
  * of the comment in the CK_VERSION type definition.
  */
 #define NSS_BUILTINS_LIBRARY_VERSION_MAJOR 1
-#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 94
-#define NSS_BUILTINS_LIBRARY_VERSION "1.94"
+#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 95
+#define NSS_BUILTINS_LIBRARY_VERSION "1.95"
 
 /* These version numbers detail the semantic changes to the ckfw engine. */
 #define NSS_BUILTINS_HARDWARE_VERSION_MAJOR 1
 #define NSS_BUILTINS_HARDWARE_VERSION_MINOR 0
 
 /* These version numbers detail the semantic changes to ckbi itself 
  * (new PKCS #11 objects), etc. */
 #define NSS_BUILTINS_FIRMWARE_VERSION_MAJOR 1
--- a/security/nss/lib/freebl/unix_rand.c
+++ b/security/nss/lib/freebl/unix_rand.c
@@ -967,18 +967,22 @@ size_t RNG_FileUpdate(const char *fileNa
     
     /* suppress valgrind warnings due to holes in struct stat */
     memset(&stat_buf, 0, sizeof(stat_buf));
 
     if (stat((char *)fileName, &stat_buf) < 0)
 	return fileBytes;
     RNG_RandomUpdate(&stat_buf, sizeof(stat_buf));
     
-    file = fopen((char *)fileName, "r");
+    file = fopen(fileName, "r");
     if (file != NULL) {
+	/* Set buffering mode to unbuffered I/O to avoid reading more bytes
+	 * than we need from /dev/urandom. Moreover, we read into a buffer
+	 * of size BUFSIZ, so buffered I/O has no performance advantage. */
+	setvbuf(file, NULL, _IONBF, 0);
 	while (limit > fileBytes) {
 	    bytes = PR_MIN(sizeof buffer, limit - fileBytes);
 	    bytes = fread(buffer, 1, bytes, file);
 	    if (bytes == 0) 
 		break;
 	    RNG_RandomUpdate(buffer, bytes);
 	    fileBytes      += bytes;
 	    totalFileBytes += bytes;
@@ -1004,17 +1008,17 @@ void RNG_FileForRNG(const char *fileName
     RNG_FileUpdate(fileName, TOTAL_FILE_LIMIT);
 }
 
 void ReadSingleFile(const char *fileName)
 {
     FILE *        file;
     unsigned char buffer[BUFSIZ];
     
-    file = fopen((char *)fileName, "rb");
+    file = fopen(fileName, "rb");
     if (file != NULL) {
 	while (fread(buffer, 1, sizeof(buffer), file) > 0)
 	    ;
 	fclose(file);
     } 
 }
 
 #define _POSIX_PTHREAD_SEMANTICS
@@ -1129,16 +1133,19 @@ size_t RNG_SystemRNG(void *dest, size_t 
     size_t bytes;
     size_t fileBytes = 0;
     unsigned char *buffer = dest;
 
     file = fopen("/dev/urandom", "r");
     if (file == NULL) {
 	return rng_systemFromNoise(dest, maxLen);
     }
+    /* Set buffering mode to unbuffered I/O to avoid reading more bytes
+     * than we need from /dev/urandom. */
+    setvbuf(file, NULL, _IONBF, 0);
     while (maxLen > fileBytes) {
 	bytes = maxLen - fileBytes;
 	bytes = fread(buffer, 1, bytes, file);
 	if (bytes == 0) 
 	    break;
 	fileBytes += bytes;
 	buffer += bytes;
     }
--- a/security/nss/lib/libpkix/include/pkix_errorstrings.h
+++ b/security/nss/lib/libpkix/include/pkix_errorstrings.h
@@ -1089,9 +1089,11 @@ PKIX_ERRORENTRY(X500NAMEEQUALSFAILED,PKI
 PKIX_ERRORENTRY(X500NAMEGETCOMMONNAMEFAILED,pkix_pl_X500Name_GetCommonName failed,0),
 PKIX_ERRORENTRY(X500NAMEGETCOUNTRYNAMEFAILED,pkix_pl_X500Name_GetCountryName failed,0),
 PKIX_ERRORENTRY(X500NAMEGETORGNAMEFAILED,pkix_pl_X500Name_GetOrgName failed,0),
 PKIX_ERRORENTRY(X500NAMEGETSECNAMEFAILED,pkix_pl_X500Name_GetSECName failed,0),
 PKIX_ERRORENTRY(X500NAMEHASHCODEFAILED,PKIX_PL_X500Name_Hashcode failed,0),
 PKIX_ERRORENTRY(X500NAMEMATCHFAILED,PKIX_PL_X500Name_Match failed,0),
 PKIX_ERRORENTRY(X500NAMETOSTRINGFAILED,PKIX_PL_X500Name_ToString failed,0),
 PKIX_ERRORENTRY(X500NAMETOSTRINGHELPERFAILED,pkix_pl_X500Name_ToString_Helper failed,0),
-PKIX_ERRORENTRY(ZEROLENGTHBYTEARRAYFORCRLENCODING,Zero-length ByteArray for CRL encoding,0)
+PKIX_ERRORENTRY(ZEROLENGTHBYTEARRAYFORCRLENCODING,Zero-length ByteArray for CRL encoding,0),
+PKIX_ERRORENTRY(INVALIDOCSPHTTPMETHOD,Unsupported HTTP Method for OCSP retrieval,0),
+PKIX_ERRORENTRY(OCSPGETREQUESTTOOBIG,OCSP request too big for HTTP GET method,0)
--- a/security/nss/lib/libpkix/pkix/checker/pkix_ocspchecker.c
+++ b/security/nss/lib/libpkix/pkix/checker/pkix_ocspchecker.c
@@ -195,22 +195,28 @@ cleanup:
 }
 
 
 /*
  * The OCSPChecker is created in an idle state, and remains in this state until
  * either (a) the default Responder has been set and enabled, and a Check
  * request is received with no responder specified, or (b) a Check request is
  * received with a specified responder. A request message is constructed and
- * given to the HttpClient. If non-blocking I/O is used the client may return
- * with WOULDBLOCK, in which case the OCSPChecker returns the WOULDBLOCK
- * condition to its caller in turn. On a subsequent call the I/O is resumed.
- * When a response is received it is decoded and the results provided to the
- * caller.
+ * given to the HttpClient. When a response is received it is decoded and the
+ * results provided to the caller.
  *
+ * During the most recent enhancement of this function, it has been found that
+ * it doesn't correctly implement non-blocking I/O.
+ * 
+ * The nbioContext is used in two places, for "response-obtaining" and
+ * for "response-verification".
+ * 
+ * However, if this function gets called to resume, it always
+ * repeats the "request creation" and "response fetching" steps!
+ * As a result, the earlier operation is never resumed.
  */
 PKIX_Error *
 pkix_OcspChecker_CheckExternal(
         PKIX_PL_Cert *cert,
         PKIX_PL_Cert *issuer,
         PKIX_PL_Date *date,
         pkix_RevocationMethod *checkerObject,
         PKIX_ProcessingParams *procParams,
@@ -225,16 +231,18 @@ pkix_OcspChecker_CheckExternal(
         PKIX_Boolean passed = PKIX_TRUE;
         pkix_OcspChecker *checker = NULL;
         PKIX_PL_OcspCertID *cid = NULL;
         PKIX_PL_OcspRequest *request = NULL;
         PKIX_PL_OcspResponse *response = NULL;
         PKIX_PL_Date *validity = NULL;
         PKIX_RevocationStatus revStatus = PKIX_RevStatus_NoInfo;
         void *nbioContext = NULL;
+        enum { stageGET, stagePOST } currentStage;
+        PRBool retry = PR_FALSE;
 
         PKIX_ENTER(OCSPCHECKER, "pkix_OcspChecker_CheckExternal");
 
         PKIX_CHECK(
             pkix_CheckType((PKIX_PL_Object*)checkerObject,
                            PKIX_OCSPCHECKER_TYPE, plContext),
                 PKIX_OBJECTNOTOCSPCHECKER);
 
@@ -253,94 +261,160 @@ pkix_OcspChecker_CheckExternal(
             PKIX_OCSPREQUESTCREATEFAILED);
         
         if (uriFound == PKIX_FALSE) {
             /* no caching for certs lacking URI */
             resultCode = 0;
             goto cleanup;
         }
 
-        /* send request and create a response object */
-        PKIX_CHECK(
-            pkix_pl_OcspResponse_Create(request, NULL,
-                                        checker->certVerifyFcn,
-                                        &nbioContext,
-                                        &response,
-                                        plContext),
-            PKIX_OCSPRESPONSECREATEFAILED);
-        if (nbioContext != 0) {
-            *pNBIOContext = nbioContext;
-            goto cleanup;
-        }
-        
-        PKIX_CHECK(
-            pkix_pl_OcspResponse_Decode(response, &passed,
-                                        &resultCode, plContext),
-            PKIX_OCSPRESPONSEDECODEFAILED);
-        if (passed == PKIX_FALSE) {
-            goto cleanup;
-        }
-        
-        PKIX_CHECK(
-            pkix_pl_OcspResponse_GetStatus(response, &passed,
-                                           &resultCode, plContext),
-            PKIX_OCSPRESPONSEGETSTATUSRETURNEDANERROR);
-        if (passed == PKIX_FALSE) {
-            goto cleanup;
+        if (methodFlags & CERT_REV_M_FORCE_POST_METHOD_FOR_OCSP) {
+            /* Do not try HTTP GET, only HTTP POST */
+            currentStage = stagePOST;
+        } else {
+            /* Try HTTP GET first, falling back to POST */
+            currentStage = stageGET;
         }
 
-        PKIX_CHECK(
-            pkix_pl_OcspResponse_VerifySignature(response, cert,
-                                                 procParams, &passed, 
-                                                 &nbioContext, plContext),
-            PKIX_OCSPRESPONSEVERIFYSIGNATUREFAILED);
-       	if (nbioContext != 0) {
-               	*pNBIOContext = nbioContext;
-                goto cleanup;
-        }
-        if (passed == PKIX_FALSE) {
-                goto cleanup;
-        }
+        do {
+                const char *mechanism;
+                passed = PKIX_TRUE;
+
+                retry = PR_FALSE;
+                if (currentStage == stageGET) {
+                        mechanism = "GET";
+                } else if (currentStage == stagePOST) {
+                        mechanism = "POST";
+                } else {
+                        PORT_Assert(0); /* our code is flawed */
+                }
+
+                /* send request and create a response object */
+                PKIX_CHECK_NO_GOTO(
+                    pkix_pl_OcspResponse_Create(request, mechanism, NULL,
+                                                checker->certVerifyFcn,
+                                                &nbioContext,
+                                                &response,
+                                                plContext),
+                    PKIX_OCSPRESPONSECREATEFAILED);
+
+                if (pkixErrorResult) {
+                    passed = PKIX_FALSE;
+                }
+
+                if (passed && nbioContext != 0) {
+                        *pNBIOContext = nbioContext;
+                        goto cleanup;
+                }
+
+                if (passed){
+                        PKIX_CHECK_NO_GOTO(
+                            pkix_pl_OcspResponse_Decode(response, &passed,
+                                                        &resultCode, plContext),
+                            PKIX_OCSPRESPONSEDECODEFAILED);
+                        if (pkixErrorResult) {
+                            passed = PKIX_FALSE;
+                        }
+                }
+                
+                if (passed){
+                        PKIX_CHECK_NO_GOTO(
+                            pkix_pl_OcspResponse_GetStatus(response, &passed,
+                                                           &resultCode, plContext),
+                            PKIX_OCSPRESPONSEGETSTATUSRETURNEDANERROR);
+                        if (pkixErrorResult) {
+                            passed = PKIX_FALSE;
+                        }
+                }
 
-        PKIX_CHECK(
-            pkix_pl_OcspResponse_GetStatusForCert(cid, response, date,
-                                                  &passed, &resultCode,
-                                                  plContext),
-            PKIX_OCSPRESPONSEGETSTATUSFORCERTFAILED);
-        if (passed == PKIX_FALSE) {
-            revStatus = pkix_OcspChecker_MapResultCodeToRevStatus(resultCode);
-        } else {
-            revStatus = PKIX_RevStatus_Success;
-        }
+                if (passed){
+                        PKIX_CHECK_NO_GOTO(
+                            pkix_pl_OcspResponse_VerifySignature(response, cert,
+                                                                 procParams, &passed, 
+                                                                 &nbioContext, plContext),
+                            PKIX_OCSPRESPONSEVERIFYSIGNATUREFAILED);
+                        if (pkixErrorResult) {
+                            passed = PKIX_FALSE;
+                        } else {
+                                if (nbioContext != 0) {
+                                        *pNBIOContext = nbioContext;
+                                        goto cleanup;
+                                }
+                        }
+                }
+
+                if (!passed && currentStage == stagePOST) {
+                        /* We won't retry a POST failure, so it's final.
+                         * Because the following block with its call to
+                         *   pkix_pl_OcspResponse_GetStatusForCert
+                         * will take care of caching good or bad state,
+                         * but we only execute that next block if there hasn't
+                         * been a failure yet, we must cache the POST
+                         * failure now.
+                         */
+                         
+                        if (cid && cid->certID) {
+                                /* Caching MIGHT consume the cid. */
+                                PKIX_Error *err;
+                                err = PKIX_PL_OcspCertID_RememberOCSPProcessingFailure(
+                                        cid, plContext);
+                                if (err) {
+                                        PKIX_PL_Object_DecRef((PKIX_PL_Object*)err, plContext);
+                                }
+                        }
+                }
+
+                if (passed){
+                        PKIX_Boolean allowCachingOfFailures =
+                                (currentStage == stagePOST) ? PKIX_TRUE : PKIX_FALSE;
+                        
+                        PKIX_CHECK_NO_GOTO(
+                            pkix_pl_OcspResponse_GetStatusForCert(cid, response,
+                                                                  allowCachingOfFailures,
+                                                                  date,
+                                                                  &passed, &resultCode,
+                                                                  plContext),
+                            PKIX_OCSPRESPONSEGETSTATUSFORCERTFAILED);
+                        if (pkixErrorResult) {
+                            passed = PKIX_FALSE;
+                        } else if (passed == PKIX_FALSE) {
+                                revStatus = pkix_OcspChecker_MapResultCodeToRevStatus(resultCode);
+                        } else {
+                                revStatus = PKIX_RevStatus_Success;
+                        }
+                }
+
+                if (currentStage == stageGET && revStatus != PKIX_RevStatus_Success &&
+                                                revStatus != PKIX_RevStatus_Revoked) {
+                        /* we'll retry */
+                        PKIX_DECREF(response);
+                        retry = PR_TRUE;
+                        currentStage = stagePOST;
+                        revStatus = PKIX_RevStatus_NoInfo;
+                        if (pkixErrorResult) {
+                                PKIX_PL_Object_DecRef((PKIX_PL_Object*)pkixErrorResult,
+                                                      plContext);
+                                pkixErrorResult = NULL;
+                        }
+                }
+        } while (retry);
 
 cleanup:
         if (revStatus == PKIX_RevStatus_NoInfo && (uriFound || 
 	    methodFlags & PKIX_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE) &&
             methodFlags & PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO) {
             revStatus = PKIX_RevStatus_Revoked;
         }
         *pRevStatus = revStatus;
 
-        /* ocsp carries only tree statuses: good, bad, and unknown.
+        /* ocsp carries only three statuses: good, bad, and unknown.
          * revStatus is used to pass them. reasonCode is always set
          * to be unknown. */
         *pReasonCode = crlEntryReasonUnspecified;
 
-        if (!passed && cid && cid->certID) {
-                /* We still own the certID object, which means that 
-                 * it did not get consumed to create a cache entry.
-                 * Let's make sure there is one.
-                 */
-                PKIX_Error *err;
-                err = PKIX_PL_OcspCertID_RememberOCSPProcessingFailure(
-                        cid, plContext);
-                if (err) {
-                        PKIX_PL_Object_DecRef((PKIX_PL_Object*)err, plContext);
-                }
-        }
         PKIX_DECREF(cid);
         PKIX_DECREF(request);
         PKIX_DECREF(response);
 
         PKIX_RETURN(OCSPCHECKER);
 }
 
 
--- 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
@@ -336,16 +336,18 @@ pkix_pl_OcspResponse_RegisterSelf(void *
  *  supplied, the default verification function is used.
  *
  *  The contents of "request" are ignored on calls subsequent to a WOULDBLOCK
  *  return, and the caller is permitted to supply NULL.
  *
  * PARAMETERS
  *  "request"
  *      Address of the OcspRequest for which a response is desired.
+ *  "httpMechanism"
+ *      GET or POST
  *  "responder"
  *      Address, if non-NULL, of the SEC_HttpClientFcn to be sent the OCSP
  *      query.
  *  "verifyFcn"
  *      Address, if non-NULL, of the OcspResponse_VerifyCallback function to be
  *      used to verify the Cert of the OCSP responder.
  *  "pNBIOContext"
  *      Address at which platform-dependent information is stored for handling
@@ -359,16 +361,17 @@ pkix_pl_OcspResponse_RegisterSelf(void *
  * RETURNS:
  *  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_Create(
         PKIX_PL_OcspRequest *request,
+        const char *httpMechanism,
         void *responder,
         PKIX_PL_VerifyCallback verifyFcn,
         void **pNBIOContext,
         PKIX_PL_OcspResponse **pResponse,
         void *plContext)
 {
         void *nbioContext = NULL;
         PKIX_PL_OcspResponse *ocspResponse = NULL;
@@ -384,16 +387,20 @@ pkix_pl_OcspResponse_Create(
         SEC_HTTP_REQUEST_SESSION sessionRequest = NULL;
         SECItem *encodedRequest = NULL;
         PRUint16 responseCode = 0;
         char *responseData = NULL;
  
         PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_Create");
         PKIX_NULLCHECK_TWO(pNBIOContext, pResponse);
 
+	if (!strcmp(httpMechanism, "GET") && !strcmp(httpMechanism, "POST")) {
+		PKIX_ERROR(PKIX_INVALIDOCSPHTTPMETHOD);
+	}
+
         nbioContext = *pNBIOContext;
         *pNBIOContext = NULL;
 
         if (nbioContext != NULL) {
 
                 ocspResponse = *pResponse;
                 PKIX_NULLCHECK_ONE(ocspResponse);
 
@@ -417,16 +424,19 @@ pkix_pl_OcspResponse_Create(
                 /* Is there a default responder and is it enabled? */
                 if (responder) {
                     httpClient = (const SEC_HttpClientFcn *)responder;
                 } else {
                     httpClient = SEC_GetRegisteredHttpClient();
                 }
 
                 if (httpClient && (httpClient->version == 1)) {
+			char *fullGetPath = NULL;
+			const char *sessionPath = NULL;
+			PRBool usePOST = !strcmp(httpMechanism, "POST");
 
                         hcv1 = &(httpClient->fcnTable.ftable1);
 
                         PKIX_CHECK(pkix_pl_OcspRequest_GetLocation
                                 (request, &location, plContext),
                                 PKIX_OCSPREQUESTGETLOCATIONFAILED);
 
                         /* parse location -> hostname, port, path */    
@@ -436,31 +446,78 @@ pkix_pl_OcspResponse_Create(
                         }
 
                         rv = (*hcv1->createSessionFcn)(hostname, port,
                                                        &serverSession);
                         if (rv != SECSuccess) {
                                 PKIX_ERROR(PKIX_OCSPSERVERERROR);
                         }       
 
-                        rv = (*hcv1->createFcn)(serverSession, "http", path,
-                                                "POST",
+			if (usePOST) {
+				sessionPath = path;
+			} else {
+				/* calculate, are we allowed to use GET? */
+				enum { max_get_request_size = 255 }; /* defined by RFC2560 */
+				unsigned char b64ReqBuf[max_get_request_size+1];
+				size_t base64size;
+				size_t slashLengthIfNeeded = 0;
+				size_t pathLength;
+				PRInt32 urlEncodedBufLength;
+				size_t getURLLength;
+				char *walkOutput = NULL;
+
+				pathLength = strlen(path);
+				if (path[pathLength-1] != '/') {
+					slashLengthIfNeeded = 1;
+				}
+				base64size = (((encodedRequest->len +2)/3) * 4);
+				if (base64size > max_get_request_size) {
+					PKIX_ERROR(PKIX_OCSPGETREQUESTTOOBIG);
+				}
+				memset(b64ReqBuf, 0, sizeof(b64ReqBuf));
+				PL_Base64Encode(encodedRequest->data, encodedRequest->len, b64ReqBuf);
+				urlEncodedBufLength = ocsp_UrlEncodeBase64Buf(b64ReqBuf, NULL);
+				getURLLength = pathLength + urlEncodedBufLength + slashLengthIfNeeded;
+				fullGetPath = (char*)PORT_Alloc(getURLLength);
+				if (!fullGetPath) {
+					PKIX_ERROR(PKIX_OUTOFMEMORY);
+				}
+				strcpy(fullGetPath, path);
+				walkOutput = fullGetPath + pathLength;
+				if (walkOutput > fullGetPath && slashLengthIfNeeded) {
+					strcpy(walkOutput, "/");
+					++walkOutput;
+				}
+				ocsp_UrlEncodeBase64Buf(b64ReqBuf, walkOutput);
+				sessionPath = fullGetPath;
+			}
+
+                        rv = (*hcv1->createFcn)(serverSession, "http",
+                                                sessionPath, httpMechanism,
                                                 PR_SecondsToInterval(timeout),
                                                 &sessionRequest);
+			sessionPath = NULL;
+			if (fullGetPath) {
+				PORT_Free(fullGetPath);
+				fullGetPath = NULL;
+			}
+			
                         if (rv != SECSuccess) {
                                 PKIX_ERROR(PKIX_OCSPSERVERERROR);
                         }       
 
-                        rv = (*hcv1->setPostDataFcn)(sessionRequest,
-                                                  (char *)encodedRequest->data,
-                                                  encodedRequest->len,
-                                                  "application/ocsp-request");
-                        if (rv != SECSuccess) {
-                                PKIX_ERROR(PKIX_OCSPSERVERERROR);
-                        }       
+			if (usePOST) {
+				rv = (*hcv1->setPostDataFcn)(sessionRequest,
+							  (char *)encodedRequest->data,
+							  encodedRequest->len,
+							  "application/ocsp-request");
+				if (rv != SECSuccess) {
+					PKIX_ERROR(PKIX_OCSPSERVERERROR);
+				}
+			}
 
                         /* create a PKIX_PL_OcspResponse object */
                         PKIX_CHECK(PKIX_PL_Object_Alloc
                                     (PKIX_OCSPRESPONSE_TYPE,
                                     sizeof (PKIX_PL_OcspResponse),
                                     (PKIX_PL_Object **)&ocspResponse,
                                     plContext),
                                     PKIX_COULDNOTCREATEOBJECT);
@@ -792,20 +849,22 @@ pkix_pl_OcspResponse_VerifySignature(
                 }
             }
             
             response->signerCert = 
                 ocsp_GetSignerCertificate(response->handle, tbsData,
                                           signature, issuerCert);
             
             if (response->signerCert == NULL) {
-                PORT_SetError(SEC_ERROR_UNKNOWN_SIGNER);
+                if (PORT_GetError() == SEC_ERROR_UNKNOWN_CERT) {
+                    /* Make the error a little more specific. */
+                    PORT_SetError(SEC_ERROR_OCSP_INVALID_SIGNING_CERT);
+                }
                 goto cleanup;
-            }
-            
+            }            
             PKIX_CHECK( 
                 PKIX_PL_Cert_CreateFromCERTCertificate(response->signerCert,
                                                        &(response->pkixSignerCert),
                                                        plContext),
                 PKIX_CERTCREATEWITHNSSCERTFAILED);
             
             /*
              * We could mark this true at the top of this function, or
@@ -932,25 +991,25 @@ 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_Boolean allowCachingOfFailures,
         PKIX_PL_Date *validity,
         PKIX_Boolean *pPassed,
         SECErrorCodes *pReturnCode,
         void *plContext)
 {
         PRTime time = 0;
         SECStatus rv = SECFailure;
-        SECStatus rvCache;
-        PRBool certIDWasConsumed = PR_FALSE;
+        CERTOCSPSingleResponse *single = NULL;
 
         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.
@@ -961,25 +1020,44 @@ pkix_pl_OcspResponse_GetStatusForCert(
         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,
-                                      time,
-                                      &certIDWasConsumed,
-                                      &rvCache);
-        if (certIDWasConsumed) {
-                cid->certID = NULL;
+        rv = ocsp_GetVerifiedSingleResponseForCertID(response->handle,
+                                                     response->nssOCSPResponse,
+                                                     cid->certID, 
+                                                     response->signerCert,
+                                                     time, &single);
+        if (rv == SECSuccess) {
+                /*
+                 * Check whether the status says revoked, and if so 
+                 * how that compares to the time value passed into this routine.
+                 */
+                rv = ocsp_CertHasGoodStatus(single->certStatus, time);
+        }
+
+        if (rv == SECSuccess || allowCachingOfFailures) {
+                /* allowed to update the cache */
+                PRBool certIDWasConsumed = PR_FALSE;
+
+                if (single) {
+                        ocsp_CacheSingleResponse(cid->certID,single,
+                                                 &certIDWasConsumed);
+                } else {
+                        cert_RememberOCSPProcessingFailure(cid->certID,
+                                                           &certIDWasConsumed);
+                }
+
+                if (certIDWasConsumed) {
+                        cid->certID = NULL;
+                }
         }
 
 	if (rv == SECSuccess) {
                 *pPassed = PKIX_TRUE;
                 *pReturnCode = 0;
         } else {
                 *pPassed = PKIX_FALSE;
                 *pReturnCode = PORT_GetError();
--- 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
@@ -12,16 +12,17 @@
 #define _PKIX_PL_OCSPRESPONSE_H
 
 #include "pkix_pl_common.h"
 #include "pkix_pl_ocspcertid.h"
 #include "hasht.h"
 #include "cryptohi.h"
 #include "ocspti.h"
 #include "ocspi.h"
+#include "plbase64.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 #define MAX_OCSP_RESPONSE_LEN (64*1024)
 
 struct PKIX_PL_OcspResponseStruct{
@@ -42,16 +43,17 @@ struct PKIX_PL_OcspResponseStruct{
 
 /* see source file for function documentation */
 
 PKIX_Error *pkix_pl_OcspResponse_RegisterSelf(void *plContext);
 
 PKIX_Error *
 pkix_pl_OcspResponse_Create(
         PKIX_PL_OcspRequest *request,
+        const char *httpMechanism,
         void *responder,
         PKIX_PL_VerifyCallback verifyFcn,
         void **pNBIOContext,
         PKIX_PL_OcspResponse **pResponse,
         void *plContext);
 
 PKIX_Error *
 pkix_pl_OcspResponse_Decode(
@@ -75,16 +77,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_Boolean allowCachingOfFailures,
         PKIX_PL_Date *validity,
         PKIX_Boolean *pPassed,
         SECErrorCodes *pReturnCode,
         void *plContext);
 
 PKIX_Error *
 PKIX_PL_OcspResponse_UseBuildChain(
         PKIX_PL_Cert *signerCert,
--- a/security/nss/lib/nss/nss.def
+++ b/security/nss/lib/nss/nss.def
@@ -1032,8 +1032,18 @@ PK11_SignWithSymKey;
 CERT_EncodeNameConstraintsExtension;
 PK11_Decrypt;
 PK11_Encrypt;
 CERT_PostOCSPRequest;
 CERT_AddCertToListHead;
 ;+    local:
 ;+       *;
 ;+};
+;+NSS_3.15.4 { 	# NSS 3.15.4 release
+;+    global:
+CERT_DestroyCrl;
+CERT_ForcePostMethodForOCSP;
+CERT_GetEncodedOCSPResponseByMechanism;
+CERT_GetSPKIDigest;
+CERT_GetSubjectNameDigest;
+;+    local:
+;+       *;
+;+};
--- a/security/nss/lib/nss/nss.h
+++ b/security/nss/lib/nss/nss.h
@@ -28,22 +28,22 @@
 
 /*
  * NSS's major version, minor version, patch level, build number, and whether
  * this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
  */
-#define NSS_VERSION  "3.15.3" _NSS_ECC_STRING _NSS_CUSTOMIZED
+#define NSS_VERSION  "3.15.4" _NSS_ECC_STRING _NSS_CUSTOMIZED " Beta"
 #define NSS_VMAJOR   3
 #define NSS_VMINOR   15
-#define NSS_VPATCH   3
+#define NSS_VPATCH   4
 #define NSS_VBUILD   0
-#define NSS_BETA     PR_FALSE
+#define NSS_BETA     PR_TRUE
 
 #ifndef RC_INVOKED
 
 #include "seccomon.h"
 
 typedef struct NSSInitParametersStr NSSInitParameters;
 
 /*
--- a/security/nss/lib/pk11wrap/pk11pub.h
+++ b/security/nss/lib/pk11wrap/pk11pub.h
@@ -765,19 +765,19 @@ PK11_GetPBEIV(SECAlgorithmID *algid, SEC
  */
 CK_MECHANISM_TYPE
 PK11_GetPBECryptoMechanism(SECAlgorithmID *algid, 
 			   SECItem **param, SECItem *pwd);
 
 /**********************************************************************
  * Functions to manage secmod flags
  **********************************************************************/
-PK11DefaultArrayEntry * PK11_GetDefaultArray(int *);
-SECStatus PK11_UpdateSlotAttribute(PK11SlotInfo *, PK11DefaultArrayEntry *,
-							PRBool );
+PK11DefaultArrayEntry *PK11_GetDefaultArray(int *size);
+SECStatus PK11_UpdateSlotAttribute(PK11SlotInfo *slot,
+				   PK11DefaultArrayEntry *entry, PRBool add);
 
 /**********************************************************************
  * Functions to look at PKCS #11 dependent data
  **********************************************************************/
 PK11GenericObject *PK11_FindGenericObjects(PK11SlotInfo *slot, 
 						CK_OBJECT_CLASS objClass);
 PK11GenericObject *PK11_GetNextGenericObject(PK11GenericObject *object);
 PK11GenericObject *PK11_GetPrevGenericObject(PK11GenericObject *object);
--- a/security/nss/lib/pk11wrap/secmodi.h
+++ b/security/nss/lib/pk11wrap/secmodi.h
@@ -89,18 +89,16 @@ char *secmod_MkAppendTokensList(PLArenaP
 void SECMOD_SlotDestroyModule(SECMODModule *module, PRBool fromSlot);
 CK_RV pk11_notify(CK_SESSION_HANDLE session, CK_NOTIFICATION event,
                                                          CK_VOID_PTR pdata);
 void pk11_SignedToUnsigned(CK_ATTRIBUTE *attrib);
 CK_OBJECT_HANDLE pk11_FindObjectByTemplate(PK11SlotInfo *slot,
 					CK_ATTRIBUTE *inTemplate,int tsize);
 CK_OBJECT_HANDLE *pk11_FindObjectsByTemplate(PK11SlotInfo *slot,
 			CK_ATTRIBUTE *inTemplate,int tsize, int *objCount);
-SECStatus PK11_UpdateSlotAttribute(PK11SlotInfo *slot,
-				 PK11DefaultArrayEntry *entry, PRBool add);
 
 #define PK11_GETTAB(x) ((CK_FUNCTION_LIST_PTR)((x)->functionList))
 #define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \
 		(x)->pValue=(v); (x)->ulValueLen = (l);
 SECStatus PK11_CreateNewObject(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
                                const CK_ATTRIBUTE *theTemplate, int count,
                                 PRBool token, CK_OBJECT_HANDLE *objectID);
 
--- a/security/nss/lib/softoken/pkcs11c.c
+++ b/security/nss/lib/softoken/pkcs11c.c
@@ -1166,28 +1166,32 @@ CK_RV NSC_DecryptUpdate(CK_SESSION_HANDL
     crv = sftk_GetContext(hSession,&context,SFTK_DECRYPT,PR_TRUE,NULL);
     if (crv != CKR_OK) return crv;
 
     /* this can only happen on an NSS programming error */
     PORT_Assert((context->padDataLength == 0) 
 		|| context->padDataLength == context->blockSize);
 
 
+    if (context->doPad) {
+	/* Check the data length for block ciphers. If we are padding,
+	 * then we must be using a block cipher. In the non-padding case
+	 * the error will be returned by the underlying decryption
+	 * function when we do the actual decrypt. We need to do the
+	 * check here to avoid returning a negative length to the caller
+	 * or reading before the beginning of the pEncryptedPart buffer.
+ 	 */
+	if ((ulEncryptedPartLen == 0) ||
+	    (ulEncryptedPartLen % context->blockSize) != 0) {
+	    return CKR_ENCRYPTED_DATA_LEN_RANGE;
+	}
+    }
+
     if (!pPart) {
 	if (context->doPad) {
-	    /* we can check the data length here because if we are padding,
-	     * then we must be using a block cipher. In the non-padding case
-	     * the error will be returned by the underlying decryption
-	     * function when do do the actual decrypt. We need to do the
-	     * check here to avoid returning a negative length to the caller.
- 	     */
-	    if ((ulEncryptedPartLen == 0) ||
-		(ulEncryptedPartLen % context->blockSize) != 0) {
-		return CKR_ENCRYPTED_DATA_LEN_RANGE;
-	    }
 	    *pulPartLen = 
 		ulEncryptedPartLen + context->padDataLength - context->blockSize;
 	    return CKR_OK;
 	}
 	/* for stream ciphers there is are no constraints on ulEncryptedPartLen.
 	 * for block ciphers, it must be a multiple of blockSize. The error is
 	 * detected when this function is called again do decrypt the output.
 	 */
--- a/security/nss/lib/softoken/softkver.h
+++ b/security/nss/lib/softoken/softkver.h
@@ -20,16 +20,16 @@
 
 /*
  * Softoken's major version, minor version, patch level, build number,
  * and whether this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
  */
-#define SOFTOKEN_VERSION  "3.15.3" SOFTOKEN_ECC_STRING
+#define SOFTOKEN_VERSION  "3.15.4" SOFTOKEN_ECC_STRING " Beta"
 #define SOFTOKEN_VMAJOR   3
 #define SOFTOKEN_VMINOR   15
-#define SOFTOKEN_VPATCH   3
+#define SOFTOKEN_VPATCH   4
 #define SOFTOKEN_VBUILD   0
-#define SOFTOKEN_BETA     PR_FALSE
+#define SOFTOKEN_BETA     PR_TRUE
 
 #endif /* _SOFTKVER_H_ */
--- a/security/nss/lib/ssl/ssl.def
+++ b/security/nss/lib/ssl/ssl.def
@@ -158,8 +158,16 @@ SSL_SetSRTPCiphers;
 ;+};
 ;+NSS_3.15 {      # NSS 3.15 release
 ;+    global:
 SSL_PeerStapledOCSPResponses;
 SSL_SetStapledOCSPResponses;
 ;+    local:
 ;+*;
 ;+};
+;+NSS_3.15.4 {    # NSS 3.15.4 release
+;+    global:
+SSL_PeerCertificateChain;
+SSL_RecommendedCanFalseStart;
+SSL_SetCanFalseStartCallback;
+;+    local:
+;+*;
+;+};
--- a/security/nss/lib/ssl/ssl.h
+++ b/security/nss/lib/ssl/ssl.h
@@ -116,24 +116,27 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRF
 #define SSL_REQUIRE_SAFE_NEGOTIATION   21 /* Peer must send Signaling       */
 					  /* Cipher Suite Value (SCSV) or   */
                                           /* Renegotiation  Info (RI)       */
 					  /* extension in ALL handshakes.   */
                                           /* default: off                   */
 #define SSL_ENABLE_FALSE_START         22 /* Enable SSL false start (off by */
                                           /* default, applies only to       */
                                           /* clients). False start is a     */
-/* mode where an SSL client will start sending application data before      */
-/* verifying the server's Finished message. This means that we could end up */
-/* sending data to an imposter. However, the data will be encrypted and     */
-/* only the true server can derive the session key. Thus, so long as the    */
-/* cipher isn't broken this is safe. Because of this, False Start will only */
-/* occur on RSA or DH ciphersuites where the cipher's key length is >= 80   */
-/* bits. The advantage of False Start is that it saves a round trip for     */
-/* client-speaks-first protocols when performing a full handshake.          */
+/* mode where an SSL client will start sending application data before
+ * verifying the server's Finished message. This means that we could end up
+ * sending data to an imposter. However, the data will be encrypted and
+ * only the true server can derive the session key. Thus, so long as the
+ * cipher isn't broken this is safe. The advantage of false start is that
+ * it saves a round trip for client-speaks-first protocols when performing a
+ * full handshake.
+ *
+ * In addition to enabling this option, the application must register a
+ * callback using the SSL_SetCanFalseStartCallback function.
+ */
 
 /* For SSL 3.0 and TLS 1.0, by default we prevent chosen plaintext attacks
  * on SSL CBC mode cipher suites (see RFC 4346 Section F.3) by splitting
  * non-empty application_data records into two records; the first record has
  * only the first byte of plaintext, and the second has the rest.
  *
  * This only prevents the attack in the sending direction; the connection may
  * still be vulnerable to such attacks if the peer does not implement a similar
@@ -392,16 +395,25 @@ SSL_IMPORT SECStatus SSL_SecurityStatus(
 ** Return the certificate for our SSL peer. If the client calls this
 ** it will always return the server's certificate. If the server calls
 ** this, it may return NULL if client authentication is not enabled or
 ** if the client had no certificate when asked.
 **	"fd" the socket "file" descriptor
 */
 SSL_IMPORT CERTCertificate *SSL_PeerCertificate(PRFileDesc *fd);
 
+/*
+** Return the certificates presented by the SSL peer. If the SSL peer
+** did not present certificates, return NULL with the
+** SSL_ERROR_NO_CERTIFICATE error. On failure, return NULL with an error
+** code other than SSL_ERROR_NO_CERTIFICATE.
+**	"fd" the socket "file" descriptor
+*/
+SSL_IMPORT CERTCertList *SSL_PeerCertificateChain(PRFileDesc *fd);
+
 /* SSL_PeerStapledOCSPResponses returns the OCSP responses that were provided
  * by the TLS server. The return value is a pointer to an internal SECItemArray
  * that contains the returned OCSP responses; it is only valid until the
  * callback function that calls SSL_PeerStapledOCSPResponses returns.
  *
  * If no OCSP responses were given by the server then the result will be empty.
  * If there was an error, then the result will be NULL.
  *
@@ -648,24 +660,55 @@ SSL_IMPORT SECStatus SSL_SetMaxServerCac
 /* called in child to inherit SID Cache variables. 
  * If envString is NULL, this function will use the value of the environment
  * variable "SSL_INHERITANCE", otherwise the string value passed in will be 
  * used.
  */
 SSL_IMPORT SECStatus SSL_InheritMPServerSIDCache(const char * envString);
 
 /*
-** Set the callback on a particular socket that gets called when we finish
-** performing a handshake.
+** Set the callback that gets called when a TLS handshake is complete. The
+** handshake callback is called after verifying the peer's Finished message and
+** before processing incoming application data.
+**
+** For the initial handshake: If the handshake false started (see
+** SSL_ENABLE_FALSE_START), then application data may already have been sent
+** before the handshake callback is called. If we did not false start then the
+** callback will get called before any application data is sent.
 */
 typedef void (PR_CALLBACK *SSLHandshakeCallback)(PRFileDesc *fd,
                                                  void *client_data);
 SSL_IMPORT SECStatus SSL_HandshakeCallback(PRFileDesc *fd, 
 			          SSLHandshakeCallback cb, void *client_data);
 
+/* Applications that wish to enable TLS false start must set this callback
+** function. NSS will invoke the functon to determine if a particular
+** connection should use false start or not. SECSuccess indicates that the
+** callback completed successfully, and if so *canFalseStart indicates if false
+** start can be used. If the callback does not return SECSuccess then the
+** handshake will be canceled. NSS's recommended criteria can be evaluated by
+** calling SSL_RecommendedCanFalseStart.
+**
+** If no false start callback is registered then false start will never be
+** done, even if the SSL_ENABLE_FALSE_START option is enabled.
+**/
+typedef SECStatus (PR_CALLBACK *SSLCanFalseStartCallback)(
+    PRFileDesc *fd, void *arg, PRBool *canFalseStart);
+
+SSL_IMPORT SECStatus SSL_SetCanFalseStartCallback(
+    PRFileDesc *fd, SSLCanFalseStartCallback callback, void *arg);
+
+/* This function sets *canFalseStart according to the recommended criteria for
+** false start. These criteria may change from release to release and may depend
+** on which handshake features have been negotiated and/or properties of the
+** certifciates/keys used on the connection.
+*/
+SSL_IMPORT SECStatus SSL_RecommendedCanFalseStart(PRFileDesc *fd,
+                                                  PRBool *canFalseStart);
+
 /*
 ** For the server, request a new handshake.  For the client, begin a new
 ** handshake.  If flushCache is non-zero, the SSL3 cache entry will be 
 ** flushed first, ensuring that a full SSL handshake will be done.
 ** If flushCache is zero, and an SSL connection is established, it will 
 ** do the much faster session restart handshake.  This will change the 
 ** session keys without doing another private key operation.
 */
--- a/security/nss/lib/ssl/ssl3con.c
+++ b/security/nss/lib/ssl/ssl3con.c
@@ -80,102 +80,116 @@ static SECStatus ssl3_AESGCMBypass(ssl3K
 
 /* This list of SSL3 cipher suites is sorted in descending order of
  * precedence (desirability).  It only includes cipher suites we implement.
  * This table is modified by SSL3_SetPolicy(). The ordering of cipher suites
  * in this table must match the ordering in SSL_ImplementedCiphers (sslenum.c)
  */
 static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
    /*      cipher_suite                     policy       enabled   isPresent */
+
 #ifdef NSS_ENABLE_ECC
  { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE},
  { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,   SSL_ALLOWED, PR_FALSE, PR_FALSE},
-#endif /* NSS_ENABLE_ECC */
- { TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,     SSL_ALLOWED, PR_TRUE,  PR_FALSE},
- { TLS_RSA_WITH_AES_128_GCM_SHA256,         SSL_ALLOWED, PR_TRUE,  PR_FALSE},
-
-#ifdef NSS_ENABLE_ECC
+ { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,    SSL_ALLOWED, PR_FALSE, PR_FALSE},
+ { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,      SSL_ALLOWED, PR_FALSE, PR_FALSE},
+ { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE},
+ { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,   SSL_ALLOWED, PR_FALSE, PR_FALSE},
  { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,    SSL_ALLOWED, PR_FALSE, PR_FALSE},
  { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,      SSL_ALLOWED, PR_FALSE, PR_FALSE},
-#endif /* NSS_ENABLE_ECC */
- { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,   SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,   SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_DHE_RSA_WITH_AES_256_CBC_SHA,        SSL_ALLOWED, PR_TRUE,  PR_FALSE},
- { TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,     SSL_ALLOWED, PR_TRUE,  PR_FALSE},
- { TLS_DHE_DSS_WITH_AES_256_CBC_SHA,        SSL_ALLOWED, PR_TRUE,  PR_FALSE},
-#ifdef NSS_ENABLE_ECC
- { TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,       SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,     SSL_ALLOWED, PR_FALSE, PR_FALSE},
-#endif /* NSS_ENABLE_ECC */
- { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,       SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_RSA_WITH_AES_256_CBC_SHA,            SSL_ALLOWED, PR_TRUE,  PR_FALSE},
- { TLS_RSA_WITH_AES_256_CBC_SHA256,         SSL_ALLOWED, PR_TRUE,  PR_FALSE},
-
-#ifdef NSS_ENABLE_ECC
- { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,    SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE},
+ { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,   SSL_ALLOWED, PR_FALSE, PR_FALSE},
+ { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,     SSL_ALLOWED, PR_FALSE, PR_FALSE},
  { TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,        SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,      SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,   SSL_ALLOWED, PR_FALSE, PR_FALSE},
  { TLS_ECDHE_RSA_WITH_RC4_128_SHA,          SSL_ALLOWED, PR_FALSE, PR_FALSE},
 #endif /* NSS_ENABLE_ECC */
+
+ { TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,     SSL_ALLOWED, PR_TRUE,  PR_FALSE},
+ { TLS_DHE_RSA_WITH_AES_128_CBC_SHA,        SSL_ALLOWED, PR_TRUE,  PR_FALSE},
+ { TLS_DHE_DSS_WITH_AES_128_CBC_SHA,        SSL_ALLOWED, PR_TRUE,  PR_FALSE},
+ { TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,     SSL_ALLOWED, PR_TRUE,  PR_FALSE},
  { TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,   SSL_ALLOWED, PR_FALSE, PR_FALSE},
  { TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,   SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_DHE_RSA_WITH_AES_128_CBC_SHA,        SSL_ALLOWED, PR_TRUE,  PR_FALSE},
- { TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,     SSL_ALLOWED, PR_TRUE,  PR_FALSE},
- { TLS_DHE_DSS_WITH_AES_128_CBC_SHA,        SSL_ALLOWED, PR_TRUE,  PR_FALSE},
+ { TLS_DHE_RSA_WITH_AES_256_CBC_SHA,        SSL_ALLOWED, PR_TRUE,  PR_FALSE},
+ { TLS_DHE_DSS_WITH_AES_256_CBC_SHA,        SSL_ALLOWED, PR_TRUE,  PR_FALSE},
+ { TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,     SSL_ALLOWED, PR_TRUE,  PR_FALSE},
+ { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,   SSL_ALLOWED, PR_FALSE, PR_FALSE},
+ { TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,   SSL_ALLOWED, PR_FALSE, PR_FALSE},
+ { SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,       SSL_ALLOWED, PR_TRUE,  PR_FALSE},
+ { SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,       SSL_ALLOWED, PR_TRUE,  PR_FALSE},
  { TLS_DHE_DSS_WITH_RC4_128_SHA,            SSL_ALLOWED, PR_FALSE, PR_FALSE},
+
 #ifdef NSS_ENABLE_ECC
+ { TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,     SSL_ALLOWED, PR_FALSE, PR_FALSE},
  { TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,       SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_ECDH_RSA_WITH_RC4_128_SHA,           SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,     SSL_ALLOWED, PR_FALSE, PR_FALSE},
+ { TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,     SSL_ALLOWED, PR_FALSE, PR_FALSE},
+ { TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,       SSL_ALLOWED, PR_FALSE, PR_FALSE},
+ { TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,    SSL_ALLOWED, PR_FALSE, PR_FALSE},
+ { TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,      SSL_ALLOWED, PR_FALSE, PR_FALSE},
  { TLS_ECDH_ECDSA_WITH_RC4_128_SHA,         SSL_ALLOWED, PR_FALSE, PR_FALSE},
+ { TLS_ECDH_RSA_WITH_RC4_128_SHA,           SSL_ALLOWED, PR_FALSE, PR_FALSE},
 #endif /* NSS_ENABLE_ECC */
- { TLS_RSA_WITH_SEED_CBC_SHA,               SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,       SSL_ALLOWED, PR_FALSE, PR_FALSE},
+
+ /* RSA */
+ { TLS_RSA_WITH_AES_128_GCM_SHA256,         SSL_ALLOWED, PR_TRUE,  PR_FALSE},
  { TLS_RSA_WITH_AES_128_CBC_SHA,            SSL_ALLOWED, PR_TRUE,  PR_FALSE},
  { TLS_RSA_WITH_AES_128_CBC_SHA256,         SSL_ALLOWED, PR_TRUE,  PR_FALSE},
+ { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,       SSL_ALLOWED, PR_FALSE, PR_FALSE},
+ { TLS_RSA_WITH_AES_256_CBC_SHA,            SSL_ALLOWED, PR_TRUE,  PR_FALSE},
+ { TLS_RSA_WITH_AES_256_CBC_SHA256,         SSL_ALLOWED, PR_TRUE,  PR_FALSE},
+ { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,       SSL_ALLOWED, PR_FALSE, PR_FALSE},
+ { TLS_RSA_WITH_SEED_CBC_SHA,               SSL_ALLOWED, PR_FALSE, PR_FALSE},
+ { SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,      SSL_ALLOWED, PR_FALSE, PR_FALSE},
+ { SSL_RSA_WITH_3DES_EDE_CBC_SHA,           SSL_ALLOWED, PR_TRUE,  PR_FALSE},
  { SSL_RSA_WITH_RC4_128_SHA,                SSL_ALLOWED, PR_TRUE,  PR_FALSE},
  { SSL_RSA_WITH_RC4_128_MD5,                SSL_ALLOWED, PR_TRUE,  PR_FALSE},
 
-#ifdef NSS_ENABLE_ECC
- { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,   SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,     SSL_ALLOWED, PR_FALSE, PR_FALSE},
-#endif /* NSS_ENABLE_ECC */
- { SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,       SSL_ALLOWED, PR_TRUE,  PR_FALSE},
- { SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,       SSL_ALLOWED, PR_TRUE,  PR_FALSE},
-#ifdef NSS_ENABLE_ECC
- { TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,      SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,    SSL_ALLOWED, PR_FALSE, PR_FALSE},
-#endif /* NSS_ENABLE_ECC */
- { SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,      SSL_ALLOWED, PR_FALSE, PR_FALSE},
- { SSL_RSA_WITH_3DES_EDE_CBC_SHA,           SSL_ALLOWED, PR_TRUE,  PR_FALSE},
-
-
+ /* 56-bit DES "domestic" cipher suites */
  { SSL_DHE_RSA_WITH_DES_CBC_SHA,            SSL_ALLOWED, PR_FALSE, PR_FALSE},
  { SSL_DHE_DSS_WITH_DES_CBC_SHA,            SSL_ALLOWED, PR_FALSE, PR_FALSE},
  { SSL_RSA_FIPS_WITH_DES_CBC_SHA,           SSL_ALLOWED, PR_FALSE, PR_FALSE},
  { SSL_RSA_WITH_DES_CBC_SHA,                SSL_ALLOWED, PR_FALSE, PR_FALSE},
+
+ /* export ciphersuites with 1024-bit public key exchange keys */
  { TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,      SSL_ALLOWED, PR_FALSE, PR_FALSE},
  { TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,     SSL_ALLOWED, PR_FALSE, PR_FALSE},
 
+ /* export ciphersuites with 512-bit public key exchange keys */
  { SSL_RSA_EXPORT_WITH_RC4_40_MD5,          SSL_ALLOWED, PR_FALSE, PR_FALSE},
  { SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,      SSL_ALLOWED, PR_FALSE, PR_FALSE},
 
+ /* ciphersuites with no encryption */
 #ifdef NSS_ENABLE_ECC
  { TLS_ECDHE_ECDSA_WITH_NULL_SHA,           SSL_ALLOWED, PR_FALSE, PR_FALSE},
  { TLS_ECDHE_RSA_WITH_NULL_SHA,             SSL_ALLOWED, PR_FALSE, PR_FALSE},
  { TLS_ECDH_RSA_WITH_NULL_SHA,              SSL_ALLOWED, PR_FALSE, PR_FALSE},
  { TLS_ECDH_ECDSA_WITH_NULL_SHA,            SSL_ALLOWED, PR_FALSE, PR_FALSE},
 #endif /* NSS_ENABLE_ECC */
  { SSL_RSA_WITH_NULL_SHA,                   SSL_ALLOWED, PR_FALSE, PR_FALSE},
  { TLS_RSA_WITH_NULL_SHA256,                SSL_ALLOWED, PR_FALSE, PR_FALSE},
  { SSL_RSA_WITH_NULL_MD5,                   SSL_ALLOWED, PR_FALSE, PR_FALSE},
 };
 
+/* Verify that SSL_ImplementedCiphers and cipherSuites are in consistent order.
+ */
+#ifdef DEBUG
+void ssl3_CheckCipherSuiteOrderConsistency()
+{
+    unsigned int i;
+
+    /* Note that SSL_ImplementedCiphers has more elements than cipherSuites
+     * because it SSL_ImplementedCiphers includes SSL 2.0 cipher suites.
+     */
+    PORT_Assert(SSL_NumImplementedCiphers >= PR_ARRAY_SIZE(cipherSuites));
+
+    for (i = 0; i < PR_ARRAY_SIZE(cipherSuites); ++i) {
+        PORT_Assert(SSL_ImplementedCiphers[i] == cipherSuites[i].cipher_suite);
+    }
+}
+#endif
+
 /* This list of SSL3 compression methods is sorted in descending order of
  * precedence (desirability).  It only includes compression methods we
  * implement.
  */
 static const /*SSLCompressionMethod*/ PRUint8 compressions [] = {
 #ifdef NSS_ENABLE_ZLIB
     ssl_compression_deflate,
 #endif
@@ -860,26 +874,20 @@ ssl3_NegotiateVersion(sslSocket *ss, SSL
     PORT_Assert(ssl3_VersionIsSupported(ss->protocolVariant, ss->version));
 
     return SECSuccess;
 }
 
 static SECStatus
 ssl3_GetNewRandom(SSL3Random *random)
 {
-    PRUint32 gmt = ssl_Time();
     SECStatus rv;
 
-    random->rand[0] = (unsigned char)(gmt >> 24);
-    random->rand[1] = (unsigned char)(gmt >> 16);
-    random->rand[2] = (unsigned char)(gmt >>  8);
-    random->rand[3] = (unsigned char)(gmt);
-
     /* first 4 bytes are reserverd for time */
-    rv = PK11_GenerateRandom(&random->rand[4], SSL3_RANDOM_LENGTH - 4);
+    rv = PK11_GenerateRandom(random->rand, SSL3_RANDOM_LENGTH);
     if (rv != SECSuccess) {
 	ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);
     }
     return rv;
 }
 
 /* Called by ssl3_SendServerKeyExchange and ssl3_SendCertificateVerify */
 SECStatus
@@ -1007,17 +1015,17 @@ ssl3_VerifySignedHashes(SSL3Hashes *hash
 	    hashItem.data = hash->u.s.sha;
 	    hashItem.len = sizeof(hash->u.s.sha);
 	} else {
 	    hashItem.data = hash->u.raw;
 	    hashItem.len = hash->len;
 	}
 	/* Allow DER encoded DSA signatures in SSL 3.0 */
 	if (isTLS || buf->len != SECKEY_SignatureLen(key)) {
-	    signature = DSAU_DecodeDerSig(buf);
+	    signature = DSAU_DecodeDerSigToLen(buf, SECKEY_SignatureLen(key));
 	    if (!signature) {
 	    	PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
 		return SECFailure;
 	    }
 	    buf = signature;
 	}
 	break;
 
@@ -2707,21 +2715,23 @@ ssl3_CompressMACEncryptRecord(ssl3Cipher
  *    bytes are used.
  * ssl_SEND_FLAG_FORCE_INTO_BUFFER
  *    As above, except this suppresses all write attempts, and forces
  *    all ciphertext into the pending ciphertext buffer.
  * ssl_SEND_FLAG_USE_EPOCH (for DTLS)
  *    Forces the use of the provided epoch
  * ssl_SEND_FLAG_CAP_RECORD_VERSION
  *    Caps the record layer version number of TLS ClientHello to { 3, 1 }
- *    (TLS 1.0). Some TLS 1.0 servers (which seem to use F5 BIG-IP) ignore 
+ *    (TLS 1.0). Some TLS 1.0 servers (which seem to use F5 BIG-IP) ignore
  *    ClientHello.client_version and use the record layer version number
  *    (TLSPlaintext.version) instead when negotiating protocol versions. In
  *    addition, if the record layer version number of ClientHello is { 3, 2 }
- *    (TLS 1.1) or higher, these servers reset the TCP connections. Set this
+ *    (TLS 1.1) or higher, these servers reset the TCP connections. Lastly,
+ *    some F5 BIG-IP servers hang if a record containing a ClientHello has a
+ *    version greater than { 3, 1 } and a length greater than 255. Set this
  *    flag to work around such servers.
  */
 PRInt32
 ssl3_SendRecord(   sslSocket *        ss,
                    DTLSEpoch          epoch, /* DTLS only */
                    SSL3ContentType    type,
 		   const SSL3Opaque * pIn,   /* input buffer */
 		   PRInt32            nIn,   /* bytes of input */
@@ -2730,17 +2740,17 @@ ssl3_SendRecord(   sslSocket *        ss
     sslBuffer      *          wrBuf 	  = &ss->sec.writeBuf;
     SECStatus                 rv;
     PRInt32                   totalSent   = 0;
     PRBool                    capRecordVersion;
 
     SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d",
 		SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type),
 		nIn));
-    PRINT_BUF(3, (ss, "Send record (plain text)", pIn, nIn));
+    PRINT_BUF(50, (ss, "Send record (plain text)", pIn, nIn));
 
     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
 
     capRecordVersion = ((flags & ssl_SEND_FLAG_CAP_RECORD_VERSION) != 0);
 
     if (capRecordVersion) {
 	/* ssl_SEND_FLAG_CAP_RECORD_VERSION can only be used with the
 	 * TLS initial ClientHello. */
@@ -3848,16 +3858,38 @@ ssl3_InitHandshakeHashes(sslSocket *ss)
 		return SECFailure;
 	    }
 	    ss->ssl3.hs.hashType = handshake_hash_single;
 
 	    if (PK11_DigestBegin(ss->ssl3.hs.sha) != SECSuccess) {
 		ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
 		return SECFailure;
 	    }
+
+	    /* Create a backup SHA-1 hash for a potential client auth
+	     * signature.
+	     *
+	     * In TLS 1.2, ssl3_ComputeHandshakeHashes always uses the
+	     * handshake hash function (SHA-256). If the server or the client
+	     * does not support SHA-256 as a signature hash, we can either
+	     * maintain a backup SHA-1 handshake hash or buffer all handshake
+	     * messages.
+	     */
+	    if (!ss->sec.isServer) {
+		ss->ssl3.hs.backupHash = PK11_CreateDigestContext(SEC_OID_SHA1);
+		if (ss->ssl3.hs.backupHash == NULL) {
+		    ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+		    return SECFailure;
+		}
+
+		if (PK11_DigestBegin(ss->ssl3.hs.backupHash) != SECSuccess) {
+		    ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+		    return SECFailure;
+		}
+	    }
 	} else {
 	    /* Both ss->ssl3.hs.md5 and ss->ssl3.hs.sha should be NULL or
 	     * created successfully. */
 	    ss->ssl3.hs.md5 = PK11_CreateDigestContext(SEC_OID_MD5);
 	    if (ss->ssl3.hs.md5 == NULL) {
 		ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
 		return SECFailure;
 	    }
@@ -3958,16 +3990,23 @@ ssl3_UpdateHandshakeHashes(sslSocket *ss
     }
 #endif
     if (ss->ssl3.hs.hashType == handshake_hash_single) {
 	rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l);
 	if (rv != SECSuccess) {
 	    ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
 	    return rv;
 	}
+	if (ss->ssl3.hs.backupHash) {
+	    rv = PK11_DigestOp(ss->ssl3.hs.backupHash, b, l);
+	    if (rv != SECSuccess) {
+		ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+		return rv;
+	    }
+	}
     } else {
 	rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l);
 	if (rv != SECSuccess) {
 	    ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
 	    return rv;
 	}
 	rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l);
 	if (rv != SECSuccess) {
@@ -4706,16 +4745,41 @@ tls12_loser:
 	    if (shaStateBuf != shaStackBuf) {
 		PORT_ZFree(shaStateBuf, shaStateLen);
 	    }
 	}
     }
     return rv;
 }
 
+static SECStatus
+ssl3_ComputeBackupHandshakeHashes(sslSocket * ss,
+				  SSL3Hashes * hashes) /* output goes here. */
+{
+    SECStatus rv = SECSuccess;
+
+    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+    PORT_Assert( !ss->sec.isServer );
+    PORT_Assert( ss->ssl3.hs.hashType == handshake_hash_single );
+
+    rv = PK11_DigestFinal(ss->ssl3.hs.backupHash, hashes->u.raw, &hashes->len,
+			  sizeof(hashes->u.raw));
+    if (rv != SECSuccess) {
+	ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+	rv = SECFailure;
+	goto loser;
+    }
+    hashes->hashAlg = SEC_OID_SHA1;
+
+loser:
+    PK11_DestroyContext(ss->ssl3.hs.backupHash, PR_TRUE);
+    ss->ssl3.hs.backupHash = NULL;
+    return rv;
+}
+
 /*
  * SSL 2 based implementations pass in the initial outbound buffer
  * so that the handshake hash can contain the included information.
  *
  * Called from ssl2_BeginClientHandshake() in sslcon.c
  */
 SECStatus
 ssl3_StartHandshakeHash(sslSocket *ss, unsigned char * buf, int length)
@@ -4969,19 +5033,19 @@ ssl3_SendClientHello(sslSocket *ss, PRBo
     }
 
     /* how many suites does our PKCS11 support (regardless of policy)? */
     num_suites = ssl3_config_match_init(ss);
     if (!num_suites)
     	return SECFailure;	/* ssl3_config_match_init has set error code. */
 
     /* HACK for SCSV in SSL 3.0.  On initial handshake, prepend SCSV,
-     * only if we're willing to complete an SSL 3.0 handshake.
+     * only if TLS is disabled.
      */
-    if (!ss->firstHsDone && ss->vrange.min == SSL_LIBRARY_VERSION_3_0) {
+    if (!ss->firstHsDone && !isTLS) {
 	/* Must set this before calling Hello Extension Senders, 
 	 * to suppress sending of empty RI extension.
 	 */
 	ss->ssl3.hs.sendingSCSV = PR_TRUE;
     }
 
     if (isTLS || (ss->firstHsDone && ss->peerRequestedProtection)) {
 	PRUint32 maxBytes = 65535; /* 2^16 - 1 */
@@ -5156,17 +5220,17 @@ ssl3_SendClientHello(sslSocket *ss, PRBo
     if (ss->ssl3.hs.sendingSCSV) {
 	/* Since we sent the SCSV, pretend we sent empty RI extension. */
 	TLSExtensionData *xtnData = &ss->xtnData;
 	xtnData->advertised[xtnData->numAdvertised++] = 
 	    ssl_renegotiation_info_xtn;
     }
 
     flags = 0;
-    if (!ss->firstHsDone && !requestingResume && !IS_DTLS(ss)) {
+    if (!ss->firstHsDone && !IS_DTLS(ss)) {
 	flags |= ssl_SEND_FLAG_CAP_RECORD_VERSION;
     }
     rv = ssl3_FlushHandshake(ss, flags);
     if (rv != SECSuccess) {
 	return rv;	/* error code set by ssl3_FlushHandshake */
     }
 
     ss->ssl3.hs.ws = wait_server_hello;
@@ -5955,17 +6019,23 @@ ssl3_SendCertificateVerify(sslSocket *ss
 
     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
 
     SSL_TRC(3, ("%d: SSL3[%d]: send certificate_verify handshake",
 		SSL_GETPID(), ss->fd));
 
     ssl_GetSpecReadLock(ss);
-    rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0);
+    if (ss->ssl3.hs.hashType == handshake_hash_single &&
+	ss->ssl3.hs.backupHash) {
+	rv = ssl3_ComputeBackupHandshakeHashes(ss, &hashes);
+	PORT_Assert(!ss->ssl3.hs.backupHash);
+    } else {
+	rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0);
+    }
     ssl_ReleaseSpecReadLock(ss);
     if (rv != SECSuccess) {
 	goto done;	/* err code was set by ssl3_ComputeHandshakeHashes */
     }
 
     isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
     isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
     keyType = ss->ssl3.clientPrivateKey->keyType;
@@ -5998,21 +6068,16 @@ ssl3_SendCertificateVerify(sslSocket *ss
 	goto done;	/* error code set by AppendHandshake */
     }
     if (isTLS12) {
 	rv = ssl3_TLSSignatureAlgorithmForKeyType(keyType,
 						  &sigAndHash.sigAlg);
 	if (rv != SECSuccess) {
 	    goto done;
 	}
-	/* We always sign using the handshake hash function. It's possible that
-	 * a server could support SHA-256 as the handshake hash but not as a
-	 * signature hash. In that case we wouldn't be able to do client
-	 * certificates with it. The alternative is to buffer all handshake
-	 * messages. */
 	sigAndHash.hashAlg = hashes.hashAlg;
 
 	rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash);
 	if (rv != SECSuccess) {
 	    goto done; 	/* err set by AppendHandshake. */
 	}
     }
     rv = ssl3_AppendHandshakeVariable(ss, buf.data, buf.len, 2);
@@ -6669,16 +6734,80 @@ loser:
     return SECFailure;
 
 no_memory:	/* no-memory error has already been set. */
     ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
     return SECFailure;
 }
 
 
+/*
+ * Returns true if the client authentication key is an RSA or DSA key that
+ * may be able to sign only SHA-1 hashes.
+ */
+static PRBool
+ssl3_ClientKeyPrefersSHA1(sslSocket *ss)
+{
+    SECKEYPublicKey *pubk;
+    PRBool preferSha1 = PR_FALSE;
+
+    /* If the key is a 1024-bit RSA or DSA key, assume conservatively that
+     * it may be unable to sign SHA-256 hashes. This is the case for older
+     * Estonian ID cards that have 1024-bit RSA keys. In FIPS 186-2 and
+     * older, DSA key size is at most 1024 bits and the hash function must
+     * be SHA-1.
+     */
+    pubk = CERT_ExtractPublicKey(ss->ssl3.clientCertificate);
+    if (pubk == NULL) {
+	return PR_FALSE;
+    }
+    if (pubk->keyType == rsaKey || pubk->keyType == dsaKey) {
+	preferSha1 = SECKEY_PublicKeyStrength(pubk) <= 128;
+    }
+    SECKEY_DestroyPublicKey(pubk);
+    return preferSha1;
+}
+
+/* Destroys the backup handshake hash context if we don't need it. */
+static void
+ssl3_DestroyBackupHandshakeHashIfNotNeeded(sslSocket *ss,
+					   const SECItem *algorithms)
+{
+    PRBool needBackupHash = PR_FALSE;
+    unsigned int i;
+
+#ifndef NO_PKCS11_BYPASS
+    /* Backup handshake hash is not supported in PKCS #11 bypass mode. */
+    if (ss->opt.bypassPKCS11) {
+	PORT_Assert(!ss->ssl3.hs.backupHash);
+	return;
+    }
+#endif
+    PORT_Assert(ss->ssl3.hs.backupHash);
+    /* XXX It would be better to first figure out if the server accepts
+     * SHA-1 and then call ssl3_ClientKeyPrefersSHA1, because
+     * ssl3_ClientKeyPrefersSHA1 is the more expensive operation.
+     */
+    if (ssl3_ClientKeyPrefersSHA1(ss)) {
+	/* Use SHA-1 if the server supports it. */
+	for (i = 0; i < algorithms->len; i += 2) {
+	    if (algorithms->data[i] == tls_hash_sha1 &&
+		(algorithms->data[i+1] == tls_sig_rsa ||
+		 algorithms->data[i+1] == tls_sig_dsa)) {
+		needBackupHash = PR_TRUE;
+		break;
+	    }
+	}
+    }
+    if (!needBackupHash) {
+	PK11_DestroyContext(ss->ssl3.hs.backupHash, PR_TRUE);
+	ss->ssl3.hs.backupHash = NULL;
+    }
+}
+
 typedef struct dnameNode {
     struct dnameNode *next;
     SECItem           name;
 } dnameNode;
 
 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
  * ssl3 Certificate Request message.
  * Caller must hold Handshake and RecvBuf locks.
@@ -6826,26 +6955,25 @@ ssl3_HandleCertificateRequest(sslSocket 
         }
 	/* Setting ssl3.clientCertChain non-NULL will cause
 	 * ssl3_HandleServerHelloDone to call SendCertificate.
 	 */
 	ss->ssl3.clientCertChain = CERT_CertChainFromCert(
 					ss->ssl3.clientCertificate,
 					certUsageSSLClient, PR_FALSE);
 	if (ss->ssl3.clientCertChain == NULL) {
-	    if (ss->ssl3.clientCertificate != NULL) {
-		CERT_DestroyCertificate(ss->ssl3.clientCertificate);
-		ss->ssl3.clientCertificate = NULL;
-	    }
-	    if (ss->ssl3.clientPrivateKey != NULL) {
-		SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
-		ss->ssl3.clientPrivateKey = NULL;
-	    }
+	    CERT_DestroyCertificate(ss->ssl3.clientCertificate);
+	    ss->ssl3.clientCertificate = NULL;
+	    SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
+	    ss->ssl3.clientPrivateKey = NULL;
 	    goto send_no_certificate;
 	}
+	if (ss->ssl3.hs.hashType == handshake_hash_single) {
+	    ssl3_DestroyBackupHandshakeHashIfNotNeeded(ss, &algorithms);
+	}
 	break;	/* not an error */
 
     case SECFailure:
     default:
 send_no_certificate:
 	if (isTLS) {
 	    ss->ssl3.sendEmptyCert = PR_TRUE;
 	} else {
@@ -6869,46 +6997,82 @@ loser:
     PORT_SetError(errCode);
     rv = SECFailure;
 done:
     if (arena != NULL)
     	PORT_FreeArena(arena, PR_FALSE);
     return rv;
 }
 
+static SECStatus
+ssl3_CheckFalseStart(sslSocket *ss)
+{
+    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+    PORT_Assert( !ss->ssl3.hs.authCertificatePending );
+    PORT_Assert( !ss->ssl3.hs.canFalseStart );
+
+    if (!ss->canFalseStartCallback) {
+	SSL_TRC(3, ("%d: SSL[%d]: no false start callback so no false start",
+		    SSL_GETPID(), ss->fd));
+    } else {
+	PRBool maybeFalseStart;
+	SECStatus rv;
+
+	/* An attacker can control the selected ciphersuite so we only wish to
+	 * do False Start in the case that the selected ciphersuite is
+	 * sufficiently strong that the attack can gain no advantage.
+	 * Therefore we always require an 80-bit cipher. */
+        ssl_GetSpecReadLock(ss);
+        maybeFalseStart = ss->ssl3.cwSpec->cipher_def->secret_key_size >= 10;
+        ssl_ReleaseSpecReadLock(ss);
+
+	if (!maybeFalseStart) {
+	    SSL_TRC(3, ("%d: SSL[%d]: no false start due to weak cipher",
+			SSL_GETPID(), ss->fd));
+	} else {
+	    rv = (ss->canFalseStartCallback)(ss->fd,
+					     ss->canFalseStartCallbackData,
+					     &ss->ssl3.hs.canFalseStart);
+	    if (rv == SECSuccess) {
+		SSL_TRC(3, ("%d: SSL[%d]: false start callback returned %s",
+			    SSL_GETPID(), ss->fd,
+			    ss->ssl3.hs.canFalseStart ? "TRUE" : "FALSE"));
+	    } else {
+		SSL_TRC(3, ("%d: SSL[%d]: false start callback failed (%s)",
+			    SSL_GETPID(), ss->fd,
+			    PR_ErrorToName(PR_GetError())));
+	    }
+	    return rv;
+	}
+    }
+
+    ss->ssl3.hs.canFalseStart = PR_FALSE;
+    return SECSuccess;
+}
+
 PRBool
-ssl3_CanFalseStart(sslSocket *ss) {
-    PRBool rv;
+ssl3_WaitingForStartOfServerSecondRound(sslSocket *ss)
+{
+    PRBool result;
 
     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
 
-    /* XXX: does not take into account whether we are waiting for
-     * SSL_AuthCertificateComplete or SSL_RestartHandshakeAfterCertReq. If/when
-     * that is done, this function could return different results each time it
-     * would be called.
-     */
-
-    ssl_GetSpecReadLock(ss);
-    rv = ss->opt.enableFalseStart &&
-	 !ss->sec.isServer &&
-	 !ss->ssl3.hs.isResuming &&
-	 ss->ssl3.cwSpec &&
-
-	 /* An attacker can control the selected ciphersuite so we only wish to
-	  * do False Start in the case that the selected ciphersuite is
-	  * sufficiently strong that the attack can gain no advantage.
-	  * Therefore we require an 80-bit cipher and a forward-secret key
-	  * exchange. */
-	 ss->ssl3.cwSpec->cipher_def->secret_key_size >= 10 &&
-	(ss->ssl3.hs.kea_def->kea == kea_dhe_dss ||
-	 ss->ssl3.hs.kea_def->kea == kea_dhe_rsa ||
-	 ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa ||
-	 ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa);
-    ssl_ReleaseSpecReadLock(ss);
-    return rv;
+    switch (ss->ssl3.hs.ws) {
+    case wait_new_session_ticket:
+        result = PR_TRUE;
+        break;
+    case wait_change_cipher:
+        result = !ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn);
+        break;
+    default:
+        result = PR_FALSE;
+        break;
+    }
+
+    return result;
 }
 
 static SECStatus ssl3_SendClientSecondRound(sslSocket *ss);
 
 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
  * ssl3 Server Hello Done message.
  * Caller must hold Handshake and RecvBuf locks.
  */
@@ -6949,16 +7113,24 @@ ssl3_SendClientSecondRound(sslSocket *ss
 
     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
 
     sendClientCert = !ss->ssl3.sendEmptyCert &&
 		     ss->ssl3.clientCertChain  != NULL &&
 		     ss->ssl3.clientPrivateKey != NULL;
 
+    if (!sendClientCert &&
+	ss->ssl3.hs.hashType == handshake_hash_single &&
+	ss->ssl3.hs.backupHash) {
+	/* Don't need the backup handshake hash. */
+	PK11_DestroyContext(ss->ssl3.hs.backupHash, PR_TRUE);
+	ss->ssl3.hs.backupHash = NULL;
+    }
+
     /* We must wait for the server's certificate to be authenticated before
      * sending the client certificate in order to disclosing the client
      * certificate to an attacker that does not have a valid cert for the
      * domain we are connecting to.
      *
      * XXX: We should do the same for the NPN extension, but for that we
      * need an option to give the application the ability to leak the NPN
      * information to get better performance.
@@ -6980,16 +7152,19 @@ ssl3_SendClientSecondRound(sslSocket *ss
      */
     if (ss->ssl3.hs.restartTarget) {
 	PR_NOT_REACHED("unexpected ss->ssl3.hs.restartTarget");
 	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
 	return SECFailure;
     }
     if (ss->ssl3.hs.authCertificatePending &&
 	(sendClientCert || ss->ssl3.sendEmptyCert || ss->firstHsDone)) {
+	SSL_TRC(3, ("%d: SSL3[%p]: deferring ssl3_SendClientSecondRound because"
+		    " certificate authentication is still pending.",
+		    SSL_GETPID(), ss->fd));
 	ss->ssl3.hs.restartTarget = ssl3_SendClientSecondRound;
 	return SECWouldBlock;
     }
 
     ssl_GetXmitBufLock(ss);		/*******************************/
 
     if (ss->ssl3.sendEmptyCert) {
 	ss->ssl3.sendEmptyCert = PR_FALSE;
@@ -7017,42 +7192,75 @@ ssl3_SendClientSecondRound(sslSocket *ss
         }
     }
 
     rv = ssl3_SendChangeCipherSpecs(ss);
     if (rv != SECSuccess) {
 	goto loser;	/* err code was set. */
     }
 
-    /* XXX: If the server's certificate hasn't been authenticated by this
-     * point, then we may be leaking this NPN message to an attacker.
+    /* This must be done after we've set ss->ssl3.cwSpec in
+     * ssl3_SendChangeCipherSpecs because SSL_GetChannelInfo uses information
+     * from cwSpec. This must be done before we call ssl3_CheckFalseStart
+     * because the false start callback (if any) may need the information from
+     * the functions that depend on this being set.
      */
+    ss->enoughFirstHsDone = PR_TRUE;
+
     if (!ss->firstHsDone) {
+	/* XXX: If the server's certificate hasn't been authenticated by this
+	 * point, then we may be leaking this NPN message to an attacker.
+	 */
 	rv = ssl3_SendNextProto(ss);
 	if (rv != SECSuccess) {
 	    goto loser;	/* err code was set. */
 	}
+
+	if (ss->opt.enableFalseStart) {
+	    if (!ss->ssl3.hs.authCertificatePending) {
+		/* When we fix bug 589047, we will need to know whether we are
+		 * false starting before we try to flush the client second
+		 * round to the network. With that in mind, we purposefully
+		 * call ssl3_CheckFalseStart before calling ssl3_SendFinished,
+		 * which includes a call to ssl3_FlushHandshake, so that
+		 * no application develops a reliance on such flushing being
+		 * done before its false start callback is called.
+		 */
+		ssl_ReleaseXmitBufLock(ss);
+		rv = ssl3_CheckFalseStart(ss);
+		ssl_GetXmitBufLock(ss);
+		if (rv != SECSuccess) {
+		    goto loser;
+		}
+	    } else {
+		/* The certificate authentication and the server's Finished
+		 * message are racing each other. If the certificate
+		 * authentication wins, then we will try to false start in
+		 * ssl3_AuthCertificateComplete.
+		 */
+		SSL_TRC(3, ("%d: SSL3[%p]: deferring false start check because"
+			    " certificate authentication is still pending.",
+			    SSL_GETPID(), ss->fd));
+	    }
+	}
     }
 
     rv = ssl3_SendFinished(ss, 0);
     if (rv != SECSuccess) {
 	goto loser;	/* err code was set. */
     }
 
     ssl_ReleaseXmitBufLock(ss);		/*******************************/
 
     if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn))
 	ss->ssl3.hs.ws = wait_new_session_ticket;
     else
 	ss->ssl3.hs.ws = wait_change_cipher;
 
-    /* Do the handshake callback for sslv3 here, if we can false start. */
-    if (ss->handshakeCallback != NULL && ssl3_CanFalseStart(ss)) {
-	(ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
-    }
+    PORT_Assert(ssl3_WaitingForStartOfServerSecondRound(ss));
 
     return SECSuccess;
 
 loser:
     ssl_ReleaseXmitBufLock(ss);
     return rv;
 }
 
@@ -9617,23 +9825,16 @@ ssl3_AuthCertificate(sslSocket *ss)
 	    if (ss->sec.isServer) {
 		errCode = SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SERVERS;
 		rv = SECFailure;
 		goto loser;
 	    }
 
 	    ss->ssl3.hs.authCertificatePending = PR_TRUE;
 	    rv = SECSuccess;
-
-	    /* XXX: Async cert validation and False Start don't work together
-	     * safely yet; if we leave False Start enabled, we may end up false
-	     * starting (sending application data) before we
-	     * SSL_AuthCertificateComplete has been called.
-	     */
-	    ss->opt.enableFalseStart = PR_FALSE;
 	}
 
 	if (rv != SECSuccess) {
 	    ssl3_SendAlertForCertError(ss, errCode);
 	    goto loser;
 	}
     }
 
@@ -9747,26 +9948,52 @@ ssl3_AuthCertificateComplete(sslSocket *
 
     if (error != 0) {
 	ss->ssl3.hs.restartTarget = ssl3_AlwaysFail;
 	ssl3_SendAlertForCertError(ss, error);
 	rv = SECSuccess;
     } else if (ss->ssl3.hs.restartTarget != NULL) {
 	sslRestartTarget target = ss->ssl3.hs.restartTarget;
 	ss->ssl3.hs.restartTarget = NULL;
+
+	if (target == ssl3_FinishHandshake) {
+	    SSL_TRC(3,("%d: SSL3[%p]: certificate authentication lost the race"
+		       " with peer's finished message", SSL_GETPID(), ss->fd));
+	}
+
 	rv = target(ss);
 	/* Even if we blocked here, we have accomplished enough to claim
 	 * success. Any remaining work will be taken care of by subsequent
 	 * calls to SSL_ForceHandshake/PR_Send/PR_Read/etc. 
 	 */
 	if (rv == SECWouldBlock) {
 	    rv = SECSuccess;
 	}
     } else {
-	rv = SECSuccess;
+	SSL_TRC(3, ("%d: SSL3[%p]: certificate authentication won the race with"
+        	    " peer's finished message", SSL_GETPID(), ss->fd));
+
+	PORT_Assert(!ss->firstHsDone);
+	PORT_Assert(!ss->sec.isServer);
+	PORT_Assert(!ss->ssl3.hs.isResuming);
+	PORT_Assert(ss->ssl3.hs.ws != idle_handshake);
+
+	if (ss->opt.enableFalseStart &&
+	    !ss->firstHsDone &&
+	    !ss->sec.isServer &&
+	    !ss->ssl3.hs.isResuming &&
+	    ssl3_WaitingForStartOfServerSecondRound(ss)) {
+	    /* ssl3_SendClientSecondRound deferred the false start check because
+	     * certificate authentication was pending, so we do it now if we still
+	     * haven't received any of the server's second round yet.
+	     */
+	    rv = ssl3_CheckFalseStart(ss);
+	} else {
+	    rv = SECSuccess;
+	}
     }
 
 done:
     ssl_ReleaseSSL3HandshakeLock(ss);
     ssl_ReleaseRecvBufLock(ss);
 
     return rv;
 }
@@ -9845,17 +10072,18 @@ ssl3_TLSPRFWithMasterSecret(ssl3CipherSp
 	    rv = TLS_PRF(&spec->msItem, label, &inData, &outData, isFIPS);
 	}
 	PORT_Assert(rv != SECSuccess || outData.len == outLen);
 #endif
     }
     return rv;
 }
 
-/* called from ssl3_HandleServerHelloDone
+/* called from ssl3_SendClientSecondRound
+ *             ssl3_HandleFinished
  */
 static SECStatus
 ssl3_SendNextProto(sslSocket *ss)
 {
     SECStatus rv;
     int padding_len;
     static const unsigned char padding[32] = {0};
 
@@ -9938,17 +10166,17 @@ ssl3_RecordKeyLog(sslSocket *ss)
     ssl_ReleaseSpecReadLock(ss);
 
     if (fwrite(buf, sizeof(buf), 1, ssl_keylog_iob) != 1)
         return;
     fflush(ssl_keylog_iob);
     return;
 }
 
-/* called from ssl3_HandleServerHelloDone
+/* called from ssl3_SendClientSecondRound
  *             ssl3_HandleClientHello
  *             ssl3_HandleFinished
  */
 static SECStatus
 ssl3_SendFinished(sslSocket *ss, PRInt32 flags)
 {
     ssl3CipherSpec *cwSpec;
     PRBool          isTLS;
@@ -10216,19 +10444,16 @@ ssl3_HandleFinished(sslSocket *ss, SSL3O
     }
 
 xmit_loser:
     ssl_ReleaseXmitBufLock(ss);	/*************************************/
     if (rv != SECSuccess) {
         return rv;
     }
 
-    ss->gs.writeOffset = 0;
-    ss->gs.readOffset  = 0;
-
     if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) {
 	effectiveExchKeyType = kt_rsa;
     } else {
 	effectiveExchKeyType = ss->ssl3.hs.kea_def->exchKeyType;
     }
 
     if (sid->cached == never_cached && !ss->opt.noCache && ss->sec.cache) {
 	/* fill in the sid */
@@ -10283,38 +10508,38 @@ xmit_loser:
 	ss->ssl3.hs.restartTarget = ssl3_FinishHandshake;
 	return SECWouldBlock;
     }
 
     rv = ssl3_FinishHandshake(ss);
     return rv;
 }
 
+/* The return type is SECStatus instead of void because this function needs
+ * to have type sslRestartTarget.
+ */
 SECStatus
 ssl3_FinishHandshake(sslSocket * ss)
 {
     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
     PORT_Assert( ss->ssl3.hs.restartTarget == NULL );
 
     /* The first handshake is now completed. */
     ss->handshake           = NULL;
-    ss->firstHsDone         = PR_TRUE;
 
     if (ss->ssl3.hs.cacheSID) {
 	(*ss->sec.cache)(ss->sec.ci.sid);
 	ss->ssl3.hs.cacheSID = PR_FALSE;
     }
 
+    ss->ssl3.hs.canFalseStart = PR_FALSE; /* False Start phase is complete */
     ss->ssl3.hs.ws = idle_handshake;
 
-    /* Do the handshake callback for sslv3 here, if we cannot false start. */
-    if (ss->handshakeCallback != NULL && !ssl3_CanFalseStart(ss)) {
-	(ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
-    }
+    ssl_FinishHandshake(ss);
 
     return SECSuccess;
 }
 
 /* Called from ssl3_HandleHandshake() when it has gathered a complete ssl3
  * hanshake message.
  * Caller must hold Handshake and RecvBuf locks.
  */
@@ -11269,17 +11494,16 @@ process_it:
 	/* XXX Send an alert ???  */
 	PORT_SetError(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE);
 	rv = SECFailure;
 	break;
     }
 
     ssl_ReleaseSSL3HandshakeLock(ss);
     return rv;
-
 }
 
 /*
  * Initialization functions
  */
 
 /* Called from ssl3_InitState, immediately below. */
 /* Caller must hold the SpecWriteLock. */
--- a/security/nss/lib/ssl/ssl3gthr.c
+++ b/security/nss/lib/ssl/ssl3gthr.c
@@ -270,21 +270,27 @@ dtls_GatherData(sslSocket *ss, sslGather
  *
  * Caller must hold the recv buf lock.
  */
 int
 ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
 {
     SSL3Ciphertext cText;
     int            rv;
-    PRBool         canFalseStart = PR_FALSE;
+    PRBool         keepGoing = PR_TRUE;
 
     SSL_TRC(30, ("ssl3_GatherCompleteHandshake"));
 
+    /* ssl3_HandleRecord may end up eventually calling ssl_FinishHandshake,
+     * which requires the 1stHandshakeLock, which must be acquired before the
+     * RecvBufLock.
+     */
+    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+
     do {
 	PRBool handleRecordNow = PR_FALSE;
 
 	ssl_GetSSL3HandshakeLock(ss);
 
 	/* Without this, we may end up wrongly reporting
 	 * SSL_ERROR_RX_UNEXPECTED_* errors if we receive any records from the
 	 * peer while we are waiting to be restarted.
@@ -359,34 +365,62 @@ ssl3_GatherCompleteHandshake(sslSocket *
 		    cText.seq_num.high <<= 8; cText.seq_num.low <<= 8;
 		    cText.seq_num.high |= ss->gs.hdr[3 + i];
 		    cText.seq_num.low |= ss->gs.hdr[7 + i];
 		}
 	    }
 
 	    cText.buf     = &ss->gs.inbuf;
 	    rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf);
+
+	    if (rv == (int) SECSuccess && ss->gs.buf.len > 0) {
+		/* We have application data to return to the application. This
+		 * prioritizes returning application data to the application over
+		 * completing any renegotiation handshake we may be doing.
+		 */
+		PORT_Assert(ss->firstHsDone);
+		PORT_Assert(cText.type == content_application_data);
+		break;
+	    }
 	}
 	if (rv < 0) {
 	    return ss->recvdCloseNotify ? 0 : rv;
 	}
 
-	/* If we kicked off a false start in ssl3_HandleServerHelloDone, break
-	 * out of this loop early without finishing the handshake.
-	 */
-	if (ss->opt.enableFalseStart) {
-	    ssl_GetSSL3HandshakeLock(ss);
-	    canFalseStart = (ss->ssl3.hs.ws == wait_change_cipher ||
-			     ss->ssl3.hs.ws == wait_new_session_ticket) &&
-		            ssl3_CanFalseStart(ss);
-	    ssl_ReleaseSSL3HandshakeLock(ss);
+	PORT_Assert(keepGoing);
+	ssl_GetSSL3HandshakeLock(ss);
+	if (ss->ssl3.hs.ws == idle_handshake) {
+	    /* We are done with the current handshake so stop trying to
+	     * handshake. Note that it would be safe to test ss->firstHsDone
+	     * instead of ss->ssl3.hs.ws. By testing ss->ssl3.hs.ws instead,
+	     * we prioritize completing a renegotiation handshake over sending
+	     * application data.
+	     */
+	    PORT_Assert(ss->firstHsDone);
+	    PORT_Assert(!ss->ssl3.hs.canFalseStart);
+	    keepGoing = PR_FALSE;
+	} else if (ss->ssl3.hs.canFalseStart) {
+	    /* Prioritize sending application data over trying to complete
+	     * the handshake if we're false starting.
+	     *
+	     * If we were to do this check at the beginning of the loop instead
+	     * of here, then this function would become be a no-op after
+	     * receiving the ServerHelloDone in the false start case, and we
+	     * would never complete the handshake.
+	     */
+	    PORT_Assert(!ss->firstHsDone);
+
+	    if (ssl3_WaitingForStartOfServerSecondRound(ss)) {
+		keepGoing = PR_FALSE;
+	    } else {
+		ss->ssl3.hs.canFalseStart = PR_FALSE;
+	    }
 	}
-    } while (ss->ssl3.hs.ws != idle_handshake &&
-             !canFalseStart &&
-             ss->gs.buf.len == 0);
+	ssl_ReleaseSSL3HandshakeLock(ss);
+    } while (keepGoing);
 
     ss->gs.readOffset = 0;
     ss->gs.writeOffset = ss->gs.buf.len;
     return 1;
 }
 
 /* Repeatedly gather in a record and when complete, Handle that record.
  * Repeat this until some application data is received.
@@ -399,15 +433,18 @@ ssl3_GatherCompleteHandshake(sslSocket *
  * Called from DoRecv in sslsecur.c
  * Caller must hold the recv buf lock.
  */
 int
 ssl3_GatherAppDataRecord(sslSocket *ss, int flags)
 {
     int            rv;
 
+    /* ssl3_GatherCompleteHandshake requires both of these locks. */
+    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+
     do {
 	rv = ssl3_GatherCompleteHandshake(ss, flags);
     } while (rv > 0 && ss->gs.buf.len == 0);
 
     return rv;
 }
--- a/security/nss/lib/ssl/sslauth.c
+++ b/security/nss/lib/ssl/sslauth.c
@@ -23,16 +23,56 @@ SSL_PeerCertificate(PRFileDesc *fd)
     }
     if (ss->opt.useSecurity && ss->sec.peerCert) {
 	return CERT_DupCertificate(ss->sec.peerCert);
     }
     return 0;
 }
 
 /* NEED LOCKS IN HERE.  */
+CERTCertList *
+SSL_PeerCertificateChain(PRFileDesc *fd)
+{
+    sslSocket *ss;
+    CERTCertList *chain = NULL;
+    CERTCertificate *cert;
+    ssl3CertNode *cur;
+
+    ss = ssl_FindSocket(fd);
+    if (!ss) {
+	SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificateChain",
+		 SSL_GETPID(), fd));
+	return NULL;
+    }
+    if (!ss->opt.useSecurity || !ss->sec.peerCert) {
+	PORT_SetError(SSL_ERROR_NO_CERTIFICATE);
+	return NULL;
+    }
+    chain = CERT_NewCertList();
+    if (!chain) {
+	return NULL;
+    }
+    cert = CERT_DupCertificate(ss->sec.peerCert);
+    if (CERT_AddCertToListTail(chain, cert) != SECSuccess) {
+	goto loser;
+    }
+    for (cur = ss->ssl3.peerCertChain; cur; cur = cur->next) {
+	cert = CERT_DupCertificate(cur->cert);
+	if (CERT_AddCertToListTail(chain, cert) != SECSuccess) {
+	    goto loser;
+	}
+    }
+    return chain;
+
+loser:
+    CERT_DestroyCertList(chain);
+    return NULL;
+}
+
+/* NEED LOCKS IN HERE.  */
 CERTCertificate *
 SSL_LocalCertificate(PRFileDesc *fd)
 {
     sslSocket *ss;
 
     ss = ssl_FindSocket(fd);
     if (!ss) {
 	SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificate",
@@ -55,17 +95,16 @@ SSL_LocalCertificate(PRFileDesc *fd)
 /* NEED LOCKS IN HERE.  */
 SECStatus
 SSL_SecurityStatus(PRFileDesc *fd, int *op, char **cp, int *kp0, int *kp1,
 		   char **ip, char **sp)
 {
     sslSocket *ss;
     const char *cipherName;
     PRBool isDes = PR_FALSE;
-    PRBool enoughFirstHsDone = PR_FALSE;
 
     ss = ssl_FindSocket(fd);
     if (!ss) {
 	SSL_DBG(("%d: SSL[%d]: bad socket in SecurityStatus",
 		 SSL_GETPID(), fd));
 	return SECFailure;
     }
 
@@ -73,24 +112,17 @@ SSL_SecurityStatus(PRFileDesc *fd, int *
     if (kp0) *kp0 = 0;
     if (kp1) *kp1 = 0;
     if (ip) *ip = 0;
     if (sp) *sp = 0;
     if (op) {
 	*op = SSL_SECURITY_STATUS_OFF;
     }
 
-    if (ss->firstHsDone) {
-	enoughFirstHsDone = PR_TRUE;
-    } else if (ss->version >= SSL_LIBRARY_VERSION_3_0 &&
-	       ssl3_CanFalseStart(ss)) {
-	enoughFirstHsDone = PR_TRUE;
-    }
-
-    if (ss->opt.useSecurity && enoughFirstHsDone) {
+    if (ss->opt.useSecurity && ss->enoughFirstHsDone) {
 	if (ss->version < SSL_LIBRARY_VERSION_3_0) {
 	    cipherName = ssl_cipherName[ss->sec.cipherType];
 	} else {
 	    cipherName = ssl3_cipherName[ss->sec.cipherType];
 	}
 	PORT_Assert(cipherName);
 	if (cipherName) {
             if (PORT_Strstr(cipherName, "DES")) isDes = PR_TRUE;
@@ -222,19 +254,24 @@ SSL_AuthCertificate(void *arg, PRFileDes
     if (!ss) {
 	return SECFailure;
     }
 
     handle = (CERTCertDBHandle *)arg;
     certStatusArray = &ss->sec.ci.sid->peerCertStatus;
 
     if (certStatusArray->len) {
-        CERT_CacheOCSPResponseFromSideChannel(handle, ss->sec.peerCert,
-					now, &certStatusArray->items[0],
-					ss->pkcs11PinArg);
+	PORT_SetError(0);
+	if (CERT_CacheOCSPResponseFromSideChannel(handle, ss->sec.peerCert, now,
+						  &certStatusArray->items[0],
+						  ss->pkcs11PinArg)
+		!= SECSuccess) {
+	    PRErrorCode error = PR_GetError();
+	    PORT_Assert(error != 0);
+	}
     }
 
     /* this may seem backwards, but isn't. */
     certUsage = isServer ? certUsageSSLClient : certUsageSSLServer;
 
     rv = CERT_VerifyCert(handle, ss->sec.peerCert, checkSig, certUsage,
 			 now, ss->pkcs11PinArg, NULL);
 
--- a/security/nss/lib/ssl/sslenum.c
+++ b/security/nss/lib/ssl/sslenum.c
@@ -5,103 +5,96 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ssl.h"
 #include "sslproto.h"
 
 /*
- * The ciphers are listed in the following order:
- * - stronger ciphers before weaker ciphers
- * - national ciphers before international ciphers
- * - faster ciphers before slower ciphers
- *
- * National ciphers such as Camellia are listed before international ciphers
- * such as AES and RC4 to allow servers that prefer Camellia to negotiate
- * Camellia without having to disable AES and RC4, which are needed for
- * interoperability with clients that don't yet implement Camellia.
- *
  * The ordering of cipher suites in this table must match the ordering in
  * the cipherSuites table in ssl3con.c.
  *
  * If new ECC cipher suites are added, also update the ssl3CipherSuite arrays
  * in ssl3ecc.c.
  *
  * Finally, update the ssl_V3_SUITES_IMPLEMENTED macro in sslimpl.h.
+ *
+ * The ordering is as follows:
+ *    * No-encryption cipher suites last
+ *    * Export/weak/obsolete cipher suites before no-encryption cipher suites
+ *    * Order by key exchange algorithm: ECDHE, then DHE, then ECDH, RSA.
+ *    * Within key agreement sections, order by symmetric encryption algorithm:
+ *      AES-128, then Camellia-128, then AES-256, then Camellia-256, then SEED,
+ *      then FIPS-3DES, then 3DES, then RC4. AES is commonly accepted as a
+ *      strong cipher internationally, and is often hardware-accelerated.
+ *      Camellia also has wide international support across standards
+ *      organizations. SEED is only recommended by the Korean government. 3DES
+ *      only provides 112 bits of security. RC4 is now deprecated or forbidden
+ *      by many standards organizations.
+ *    * Within symmetric algorithm sections, order by message authentication
+ *      algorithm: GCM, then HMAC-SHA1, then HMAC-SHA256, then HMAC-MD5.
+ *    * Within message authentication algorithm sections, order by asymmetric
+ *      signature algorithm: ECDSA, then RSA, then DSS.
  */
 const PRUint16 SSL_ImplementedCiphers[] = {
-    /* AES-GCM */
 #ifdef NSS_ENABLE_ECC
     TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
     TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
-#endif /* NSS_ENABLE_ECC */
-    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
-    TLS_RSA_WITH_AES_128_GCM_SHA256,
-
-    /* 256-bit */
-#ifdef NSS_ENABLE_ECC
+    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
     TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
     TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
-#endif /* NSS_ENABLE_ECC */
-    TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
-    TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
-    TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
-    TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
-    TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
-#ifdef NSS_ENABLE_ECC
-    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
-    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
-#endif /* NSS_ENABLE_ECC */
-    TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
-    TLS_RSA_WITH_AES_256_CBC_SHA,
-    TLS_RSA_WITH_AES_256_CBC_SHA256,
-
-    /* 128-bit */
-#ifdef NSS_ENABLE_ECC
-    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
-    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+    TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
+    TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
     TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
-    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
-    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
     TLS_ECDHE_RSA_WITH_RC4_128_SHA,
 #endif /* NSS_ENABLE_ECC */
+
+    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+    TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
+    TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
+    TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
     TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
     TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,
-    TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
-    TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
-    TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
+    TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
+    TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
+    TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
+    TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
+    TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
+    SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
+    SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
     TLS_DHE_DSS_WITH_RC4_128_SHA,
+
 #ifdef NSS_ENABLE_ECC
+    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
     TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
-    TLS_ECDH_RSA_WITH_RC4_128_SHA,
-    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
+    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
+    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
+    TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
+    TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
     TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
+    TLS_ECDH_RSA_WITH_RC4_128_SHA,
 #endif /* NSS_ENABLE_ECC */
-    TLS_RSA_WITH_SEED_CBC_SHA,
-    TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
+
+    TLS_RSA_WITH_AES_128_GCM_SHA256,
     TLS_RSA_WITH_AES_128_CBC_SHA,
     TLS_RSA_WITH_AES_128_CBC_SHA256,
+    TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
+    TLS_RSA_WITH_AES_256_CBC_SHA,
+    TLS_RSA_WITH_AES_256_CBC_SHA256,
+    TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
+    TLS_RSA_WITH_SEED_CBC_SHA,
+    SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,
+    SSL_RSA_WITH_3DES_EDE_CBC_SHA,
     SSL_RSA_WITH_RC4_128_SHA,
     SSL_RSA_WITH_RC4_128_MD5,
 
-    /* 112-bit 3DES */
-#ifdef NSS_ENABLE_ECC
-    TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
-    TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
-#endif /* NSS_ENABLE_ECC */
-    SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
-    SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
-#ifdef NSS_ENABLE_ECC
-    TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
-    TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
-#endif /* NSS_ENABLE_ECC */
-    SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,
-    SSL_RSA_WITH_3DES_EDE_CBC_SHA,
-
     /* 56-bit DES "domestic" cipher suites */
     SSL_DHE_RSA_WITH_DES_CBC_SHA,
     SSL_DHE_DSS_WITH_DES_CBC_SHA,
     SSL_RSA_FIPS_WITH_DES_CBC_SHA,
     SSL_RSA_WITH_DES_CBC_SHA,
 
     /* export ciphersuites with 1024-bit public key exchange keys */
     TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,
--- a/security/nss/lib/ssl/sslimpl.h
+++ b/security/nss/lib/ssl/sslimpl.h
@@ -812,16 +812,20 @@ typedef struct SSL3HandshakeStateStr {
      * of the freebl <HASH>_Clone functions, so we need a dedicated function
      * pointer for the <HASH>_Clone function. */
     void (*sha_clone)(void *dest, void *src);
 #endif
     /* PKCS #11 mode:
      * SSL 3.0 - TLS 1.1 use both |md5| and |sha|. |md5| is used for MD5 and
      * |sha| for SHA-1.
      * TLS 1.2 and later use only |sha|, for SHA-256. */
+    /* NOTE: On the client side, TLS 1.2 and later use |md5| as a backup
+     * handshake hash for generating client auth signatures. Confusingly, the
+     * backup hash function is SHA-1. */
+#define backupHash md5
     PK11Context *         md5;
     PK11Context *         sha;
 
 const ssl3KEADef *        kea_def;
     ssl3CipherSuite       cipher_suite;
 const ssl3CipherSuiteDef *suite_def;
     SSLCompressionMethod  compression;
     sslBuffer             msg_body;    /* protected by recvBufLock */
@@ -850,16 +854,18 @@ const ssl3CipherSuiteDef *suite_def;
     PRBool                authCertificatePending;
     /* Which function should SSL_RestartHandshake* call if we're blocked?
      * One of NULL, ssl3_SendClientSecondRound, ssl3_FinishHandshake,
      * or ssl3_AlwaysFail */
     sslRestartTarget      restartTarget;
     /* Shared state between ssl3_HandleFinished and ssl3_FinishHandshake */
     PRBool                cacheSID;
 
+    PRBool                canFalseStart;   /* Can/did we False Start */
+
     /* clientSigAndHash contains the contents of the signature_algorithms
      * extension (if any) from the client. This is only valid for TLS 1.2
      * or later. */
     SSL3SignatureAndHashAlgorithm *clientSigAndHash;
     unsigned int          numClientSigAndHash;
 
     /* This group of values is used for DTLS */
     PRUint16              sendMessageSeq;  /* The sending message sequence
@@ -1124,16 +1130,20 @@ struct sslSocketStr {
     sslOptions       opt;
     /* Enabled version range */
     SSLVersionRange  vrange;
 
     /* State flags */
     unsigned long    clientAuthRequested;
     unsigned long    delayDisabled;       /* Nagle delay disabled */
     unsigned long    firstHsDone;         /* first handshake is complete. */
+    unsigned long    enoughFirstHsDone;   /* enough of the first handshake is
+					   * done for callbacks to be able to
+					   * retrieve channel security
+					   * parameters from the SSL socket. */
     unsigned long    handshakeBegun;     
     unsigned long    lastWriteBlocked;   
     unsigned long    recvdCloseNotify;    /* received SSL EOF. */
     unsigned long    TCPconnected;       
     unsigned long    appDataBuffered;
     unsigned long    peerRequestedProtection; /* from old renegotiation */
 
     /* version of the protocol to use */
@@ -1164,16 +1174,18 @@ const unsigned char *  preferredCipher;
     SSLGetClientAuthData      getClientAuthData;
     void                     *getClientAuthDataArg;
     SSLSNISocketConfig        sniSocketConfig;
     void                     *sniSocketConfigArg;
     SSLBadCertHandler         handleBadCert;
     void                     *badCertArg;
     SSLHandshakeCallback      handshakeCallback;
     void                     *handshakeCallbackData;
+    SSLCanFalseStartCallback  canFalseStartCallback;
+    void                     *canFalseStartCallbackData;
     void                     *pkcs11PinArg;
     SSLNextProtoCallback      nextProtoCallback;
     void                     *nextProtoArg;
 
     PRIntervalTime            rTimeout; /* timeout for NSPR I/O */
     PRIntervalTime            wTimeout; /* timeout for NSPR I/O */
     PRIntervalTime            cTimeout; /* timeout for NSPR I/O */
 
@@ -1366,17 +1378,29 @@ extern int       ssl3_SendApplicationDat
 extern PRBool    ssl_FdIsBlocking(PRFileDesc *fd);
 
 extern PRBool    ssl_SocketIsBlocking(sslSocket *ss);
 
 extern void      ssl3_SetAlwaysBlock(sslSocket *ss);
 
 extern SECStatus ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled);
 
-extern PRBool    ssl3_CanFalseStart(sslSocket *ss);
+extern void      ssl_FinishHandshake(sslSocket *ss);
+
+/* Returns PR_TRUE if we are still waiting for the server to respond to our
+ * client second round. Once we've received any part of the server's second
+ * round then we don't bother trying to false start since it is almost always
+ * the case that the NewSessionTicket, ChangeCipherSoec, and Finished messages
+ * were sent in the same packet and we want to process them all at the same
+ * time. If we were to try to false start in the middle of the server's second
+ * round, then we would increase the number of I/O operations
+ * (SSL_ForceHandshake/PR_Recv/PR_Send/etc.) needed to finish the handshake.
+ */
+extern PRBool    ssl3_WaitingForStartOfServerSecondRound(sslSocket *ss);
+
 extern SECStatus
 ssl3_CompressMACEncryptRecord(ssl3CipherSpec *   cwSpec,
 		              PRBool             isServer,
 			      PRBool             isDTLS,
 			      PRBool             capRecordVersion,
                               SSL3ContentType    type,
 		              const SSL3Opaque * pIn,
 		              PRUint32           contentLen,
@@ -1821,16 +1845,20 @@ extern void dtls_RecordSetRecvd(DTLSRecv
 extern void dtls_RehandshakeCleanup(sslSocket *ss);
 extern SSL3ProtocolVersion
 dtls_TLSVersionToDTLSVersion(SSL3ProtocolVersion tlsv);
 extern SSL3ProtocolVersion
 dtls_DTLSVersionToTLSVersion(SSL3ProtocolVersion dtlsv);
 
 /********************** misc calls *********************/
 
+#ifdef DEBUG
+extern void ssl3_CheckCipherSuiteOrderConsistency();
+#endif
+
 extern int ssl_MapLowLevelError(int hiLevelError);
 
 extern PRUint32 ssl_Time(void);
 
 extern void SSL_AtomicIncrementLong(long * x);
 
 SECStatus SSL_DisableDefaultExportCipherSuites(void);
 SECStatus SSL_DisableExportCipherSuites(PRFileDesc * fd);
--- a/security/nss/lib/ssl/sslinfo.c
+++ b/security/nss/lib/ssl/sslinfo.c
@@ -21,41 +21,33 @@ ssl_GetCompressionMethodName(SSLCompress
 }
 
 SECStatus 
 SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
 {
     sslSocket *      ss;
     SSLChannelInfo   inf;
     sslSessionID *   sid;
-    PRBool           enoughFirstHsDone = PR_FALSE;
 
     if (!info || len < sizeof inf.length) { 
 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
 	return SECFailure;
     }
 
     ss = ssl_FindSocket(fd);
     if (!ss) {
 	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetChannelInfo",
 		 SSL_GETPID(), fd));
 	return SECFailure;
     }
 
     memset(&inf, 0, sizeof inf);
     inf.length = PR_MIN(sizeof inf, len);
 
-    if (ss->firstHsDone) {
-	enoughFirstHsDone = PR_TRUE;
-    } else if (ss->version >= SSL_LIBRARY_VERSION_3_0 &&
-	       ssl3_CanFalseStart(ss)) {
-	enoughFirstHsDone = PR_TRUE;
-    }
-
-    if (ss->opt.useSecurity && enoughFirstHsDone) {
+    if (ss->opt.useSecurity && ss->enoughFirstHsDone) {
         sid = ss->sec.ci.sid;
 	inf.protocolVersion  = ss->version;
 	inf.authKeyBits      = ss->sec.authKeyBits;
 	inf.keaKeyBits       = ss->sec.keaKeyBits;
 	if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */
 	    inf.cipherSuite           = ss->sec.cipherType | 0xff00;
 	    inf.compressionMethod     = ssl_compression_null;
 	    inf.compressionMethodName = "N/A";
--- a/security/nss/lib/ssl/sslinit.c
+++ b/security/nss/lib/ssl/sslinit.c
@@ -17,12 +17,17 @@ static int ssl_inited = 0;
 SECStatus
 ssl_Init(void)
 {
     if (!ssl_inited) {
 	if (ssl_InitializePRErrorTable() != SECSuccess) {
 	    PORT_SetError(SEC_ERROR_NO_MEMORY);
 	    return (SECFailure);
 	}
+
+#ifdef DEBUG
+        ssl3_CheckCipherSuiteOrderConsistency();
+#endif
+
 	ssl_inited = 1;
     }
     return SECSuccess;
 }
--- a/security/nss/lib/ssl/sslsecur.c
+++ b/security/nss/lib/ssl/sslsecur.c
@@ -92,33 +92,23 @@ ssl_Do1stHandshake(sslSocket *ss)
 	    ss->nextHandshake = 0;
 	}
 	if (ss->handshake == 0) {
 	    /* Previous handshake finished. Switch to security handshake */
 	    ss->handshake = ss->securityHandshake;
 	    ss->securityHandshake = 0;
 	}
 	if (ss->handshake == 0) {
-	    ssl_GetRecvBufLock(ss);
-	    ss->gs.recordLen = 0;
-	    ssl_ReleaseRecvBufLock(ss);
-
-	    SSL_TRC(3, ("%d: SSL[%d]: handshake is completed",
-			SSL_GETPID(), ss->fd));
-            /* call handshake callback for ssl v2 */
-	    /* for v3 this is done in ssl3_HandleFinished() */
-	    if ((ss->handshakeCallback != NULL) && /* has callback */
-		(!ss->firstHsDone) &&              /* only first time */
-		(ss->version < SSL_LIBRARY_VERSION_3_0)) {  /* not ssl3 */
-		ss->firstHsDone     = PR_TRUE;
-		(ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
+	    /* for v3 this is done in ssl3_FinishHandshake */
+	    if (!ss->firstHsDone && ss->version < SSL_LIBRARY_VERSION_3_0) {
+		ssl_GetRecvBufLock(ss);
+		ss->gs.recordLen = 0;
+		ssl_FinishHandshake(ss);
+		ssl_ReleaseRecvBufLock(ss);
 	    }
-	    ss->firstHsDone         = PR_TRUE;
-	    ss->gs.writeOffset = 0;
-	    ss->gs.readOffset  = 0;
 	    break;
 	}
 	rv = (*ss->handshake)(ss);
 	++loopCount;
     /* This code must continue to loop on SECWouldBlock, 
      * or any positive value.	See XXX_1 comments.
      */
     } while (rv != SECFailure);  	/* was (rv >= 0); XXX_1 */
@@ -129,16 +119,34 @@ ssl_Do1stHandshake(sslSocket *ss)
 
     if (rv == SECWouldBlock) {
 	PORT_SetError(PR_WOULD_BLOCK_ERROR);
 	rv = SECFailure;
     }
     return rv;
 }
 
+void
+ssl_FinishHandshake(sslSocket *ss)
+{
+    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
+    PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+
+    SSL_TRC(3, ("%d: SSL[%d]: handshake is completed", SSL_GETPID(), ss->fd));
+
+    ss->firstHsDone = PR_TRUE;
+    ss->enoughFirstHsDone = PR_TRUE;
+    ss->gs.writeOffset = 0;
+    ss->gs.readOffset  = 0;
+
+    if (ss->handshakeCallback) {
+	(ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
+    }
+}
+
 /*
  * Handshake function that blocks.  Used to force a
  * retry on a connection on the next read/write.
  */
 static SECStatus
 ssl3_AlwaysBlock(sslSocket *ss)
 {
     PORT_SetError(PR_WOULD_BLOCK_ERROR);	/* perhaps redundant. */
@@ -201,31 +209,34 @@ SSL_ResetHandshake(PRFileDesc *s, PRBool
 
     SSL_LOCK_READER(ss);
     SSL_LOCK_WRITER(ss);
 
     /* Reset handshake state */
     ssl_Get1stHandshakeLock(ss);
 
     ss->firstHsDone = PR_FALSE;
+    ss->enoughFirstHsDone = PR_FALSE;
     if ( asServer ) {
 	ss->handshake = ssl2_BeginServerHandshake;
 	ss->handshaking = sslHandshakingAsServer;
     } else {
 	ss->handshake = ssl2_BeginClientHandshake;
 	ss->handshaking = sslHandshakingAsClient;
     }
     ss->nextHandshake       = 0;
     ss->securityHandshake   = 0;
 
     ssl_GetRecvBufLock(ss);
     status = ssl_InitGather(&ss->gs);
     ssl_ReleaseRecvBufLock(ss);
 
     ssl_GetSSL3HandshakeLock(ss);
+    ss->ssl3.hs.canFalseStart = PR_FALSE;
+    ss->ssl3.hs.restartTarget = NULL;
 
     /*
     ** Blow away old security state and get a fresh setup.
     */
     ssl_GetXmitBufLock(ss); 
     ssl_ResetSecurityInfo(&ss->sec, PR_TRUE);
     status = ssl_CreateSecurityInfo(ss);
     ssl_ReleaseXmitBufLock(ss); 
@@ -326,16 +337,81 @@ SSL_HandshakeCallback(PRFileDesc *fd, SS
     ss->handshakeCallbackData = client_data;
 
     ssl_ReleaseSSL3HandshakeLock(ss);
     ssl_Release1stHandshakeLock(ss);
 
     return SECSuccess;
 }
 
+/* Register an application callback to be called when false start may happen.
+** Acquires and releases HandshakeLock.
+*/
+SECStatus
+SSL_SetCanFalseStartCallback(PRFileDesc *fd, SSLCanFalseStartCallback cb,
+			     void *arg)
+{
+    sslSocket *ss;
+
+    ss = ssl_FindSocket(fd);
+    if (!ss) {
+	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetCanFalseStartCallback",
+		 SSL_GETPID(), fd));
+	return SECFailure;
+    }
+
+    if (!ss->opt.useSecurity) {
+	PORT_SetError(SEC_ERROR_INVALID_ARGS);
+	return SECFailure;
+    }
+
+    ssl_Get1stHandshakeLock(ss);
+    ssl_GetSSL3HandshakeLock(ss);
+
+    ss->canFalseStartCallback     = cb;
+    ss->canFalseStartCallbackData = arg;
+
+    ssl_ReleaseSSL3HandshakeLock(ss);
+    ssl_Release1stHandshakeLock(ss);
+
+    return SECSuccess;
+}
+
+SECStatus
+SSL_RecommendedCanFalseStart(PRFileDesc *fd, PRBool *canFalseStart)
+{
+    sslSocket *ss;
+
+    *canFalseStart = PR_FALSE;
+    ss = ssl_FindSocket(fd);
+    if (!ss) {
+	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_RecommendedCanFalseStart",
+		 SSL_GETPID(), fd));
+	return SECFailure;
+    }
+
+    if (!ss->ssl3.initialized) {
+	PORT_SetError(SEC_ERROR_INVALID_ARGS);
+	return SECFailure;
+    }
+
+    if (ss->version < SSL_LIBRARY_VERSION_3_0) {
+	PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
+	return SECFailure;
+    }
+
+    /* Require a forward-secret key exchange. */
+    *canFalseStart = ss->ssl3.hs.kea_def->kea == kea_dhe_dss ||
+		     ss->ssl3.hs.kea_def->kea == kea_dhe_rsa ||
+		     ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa ||
+		     ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa;
+
+    return SECSuccess;
+}
+
 /* Try to make progress on an SSL handshake by attempting to read the 
 ** next handshake from the peer, and sending any responses.
 ** For non-blocking sockets, returns PR_ERROR_WOULD_BLOCK  if it cannot 
 ** read the next handshake from the underlying socket.
 ** For SSLv2, returns when handshake is complete or fatal error occurs.
 ** For SSLv3, returns when handshake is complete, or application data has
 ** arrived that must be taken by application before handshake can continue, 
 ** or a fatal error occurs.
@@ -519,16 +595,19 @@ ssl_SendSavedWriteData(sslSocket *ss)
 */
 static int 
 DoRecv(sslSocket *ss, unsigned char *out, int len, int flags)
 {
     int              rv;
     int              amount;
     int              available;
 
+    /* ssl3_GatherAppDataRecord may call ssl_FinishHandshake, which needs the
+     * 1stHandshakeLock. */
+    ssl_Get1stHandshakeLock(ss);
     ssl_GetRecvBufLock(ss);
 
     available = ss->gs.writeOffset - ss->gs.readOffset;
     if (available == 0) {
 	/* Get some more data */
 	if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
 	    /* Wait for application data to arrive.  */
 	    rv = ssl3_GatherAppDataRecord(ss, 0);
@@ -585,16 +664,17 @@ DoRecv(sslSocket *ss, unsigned char *out
     rv = amount;
 
     SSL_TRC(30, ("%d: SSL[%d]: amount=%d available=%d",
 		 SSL_GETPID(), ss->fd, amount, available));
     PRINT_BUF(4, (ss, "DoRecv receiving plaintext:", out, amount));
 
 done:
     ssl_ReleaseRecvBufLock(ss);
+    ssl_Release1stHandshakeLock(ss);
     return rv;
 }
 
 /************************************************************************/
 
 /*
 ** Return SSLKEAType derived from cert's Public Key algorithm info.
 */
@@ -1151,17 +1231,18 @@ ssl_SecureRead(sslSocket *ss, unsigned c
 {
     return ssl_SecureRecv(ss, buf, len, 0);
 }
 
 /* Caller holds the SSL Socket's write lock. SSL_LOCK_WRITER(ss) */
 int
 ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
 {
-    int              rv		= 0;
+    int rv = 0;
+    PRBool falseStart = PR_FALSE;
 
     SSL_TRC(2, ("%d: SSL[%d]: SecureSend: sending %d bytes",
 		SSL_GETPID(), ss->fd, len));
 
     if (ss->shutdownHow & ssl_SHUTDOWN_SEND) {
 	PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR);
     	rv = PR_FAILURE;
 	goto done;
@@ -1186,29 +1267,24 @@ ssl_SecureSend(sslSocket *ss, const unsi
     if (rv < 0) {
 	goto done;
     }
 
     if (len > 0) 
     	ss->writerThread = PR_GetCurrentThread();
     /* If any of these is non-zero, the initial handshake is not done. */
     if (!ss->firstHsDone) {
-	PRBool canFalseStart = PR_FALSE;
 	ssl_Get1stHandshakeLock(ss);
-	if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
+	if (ss->opt.enableFalseStart &&
+	    ss->version >= SSL_LIBRARY_VERSION_3_0) {
 	    ssl_GetSSL3HandshakeLock(ss);
-	    if ((ss->ssl3.hs.ws == wait_change_cipher ||
-		ss->ssl3.hs.ws == wait_finished ||
-		ss->ssl3.hs.ws == wait_new_session_ticket) &&
-		ssl3_CanFalseStart(ss)) {
-		canFalseStart = PR_TRUE;
-	    }
+	    falseStart = ss->ssl3.hs.canFalseStart;
 	    ssl_ReleaseSSL3HandshakeLock(ss);
 	}
-	if (!canFalseStart &&
+	if (!falseStart &&
 	    (ss->handshake || ss->nextHandshake || ss->securityHandshake)) {
 	    rv = ssl_Do1stHandshake(ss);
 	}
 	ssl_Release1stHandshakeLock(ss);
     }
     if (rv < 0) {
     	ss->writerThread = NULL;
 	goto done;
@@ -1223,16 +1299,27 @@ ssl_SecureSend(sslSocket *ss, const unsi
     }
     PORT_Assert(buf != NULL);
     if (!buf) {
 	PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
     	rv = PR_FAILURE;
 	goto done;
     }
 
+    if (!ss->firstHsDone) {
+	PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_3_0);
+#ifdef DEBUG
+	ssl_GetSSL3HandshakeLock(ss);
+	PORT_Assert(ss->ssl3.hs.canFalseStart);
+	ssl_ReleaseSSL3HandshakeLock(ss);
+#endif
+	SSL_TRC(3, ("%d: SSL[%d]: SecureSend: sending data due to false start",
+		    SSL_GETPID(), ss->fd));
+    }
+
     /* Send out the data using one of these functions:
      *	ssl2_SendClear, ssl2_SendStream, ssl2_SendBlock, 
      *  ssl3_SendApplicationData
      */
     ssl_GetXmitBufLock(ss);
     rv = (*ss->sec.send)(ss, buf, len, flags);
     ssl_ReleaseXmitBufLock(ss);
     ss->writerThread = NULL;
--- a/security/nss/lib/ssl/sslsock.c
+++ b/security/nss/lib/ssl/sslsock.c
@@ -262,16 +262,18 @@ ssl_DupSocket(sslSocket *os)
 	    ss->getClientAuthData     = os->getClientAuthData;
 	    ss->getClientAuthDataArg  = os->getClientAuthDataArg;
             ss->sniSocketConfig       = os->sniSocketConfig;
             ss->sniSocketConfigArg    = os->sniSocketConfigArg;
 	    ss->handleBadCert         = os->handleBadCert;
 	    ss->badCertArg            = os->badCertArg;
 	    ss->handshakeCallback     = os->handshakeCallback;
 	    ss->handshakeCallbackData = os->handshakeCallbackData;
+	    ss->canFalseStartCallback = os->canFalseStartCallback;
+	    ss->canFalseStartCallbackData = os->canFalseStartCallbackData;
 	    ss->pkcs11PinArg          = os->pkcs11PinArg;
     
 	    /* Create security data */
 	    rv = ssl_CopySecurityInfo(ss, os);
 	    if (rv != SECSuccess) {
 		goto loser;
 	    }
 	}
@@ -2254,20 +2256,24 @@ ssl_Poll(PRFileDesc *fd, PRInt16 how_fla
 		    ** The code should select on write, not read.
 		    */
 		    new_flags ^=  PR_POLL_READ;	   /* don't select on read. */
 		    new_flags |=  PR_POLL_WRITE;   /* do    select on write. */
 		}
 	    } else if (new_flags & PR_POLL_WRITE) {
 		    /* The caller is trying to write, but the handshake is 
 		    ** blocked waiting for data to read, and the first 
-		    ** handshake has been sent.  so do NOT to poll on write.
+		    ** handshake has been sent.  So do NOT to poll on write
+		    ** unless we did false start.
 		    */
-		    new_flags ^=  PR_POLL_WRITE;   /* don't select on write. */
-		    new_flags |=  PR_POLL_READ;	   /* do    select on read. */
+		    if (!(ss->version >= SSL_LIBRARY_VERSION_3_0 &&
+			ss->ssl3.hs.canFalseStart)) {
+			new_flags ^= PR_POLL_WRITE; /* don't select on write. */
+		    }
+		    new_flags |= PR_POLL_READ;      /* do    select on read. */
 	    }
 	}
     } else if ((new_flags & PR_POLL_READ) && (SSL_DataPending(fd) > 0)) {
 	*p_out_flags = PR_POLL_READ;	/* it's ready already. */
 	return new_flags;
     } else if ((ss->lastWriteBlocked) && (how_flags & PR_POLL_READ) &&
 	       (ss->pendingBuf.len != 0)) { /* write data waiting to be sent */
 	new_flags |=  PR_POLL_WRITE;   /* also select on write. */
--- a/security/nss/lib/util/nssutil.h
+++ b/security/nss/lib/util/nssutil.h
@@ -14,22 +14,22 @@
 
 /*
  * NSS utilities's major version, minor version, patch level, build number,
  * and whether this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
  */
-#define NSSUTIL_VERSION  "3.15.3"
+#define NSSUTIL_VERSION  "3.15.4 Beta"
 #define NSSUTIL_VMAJOR   3
 #define NSSUTIL_VMINOR   15
-#define NSSUTIL_VPATCH   3
+#define NSSUTIL_VPATCH   4
 #define NSSUTIL_VBUILD   0
-#define NSSUTIL_BETA     PR_FALSE
+#define NSSUTIL_BETA     PR_TRUE
 
 SEC_BEGIN_PROTOS
 
 /*
  * Returns a const string of the UTIL library version.
  */
 extern const char *NSSUTIL_GetVersion(void);
 
--- a/security/nss/tests/chains/chains.sh
+++ b/security/nss/tests/chains/chains.sh
@@ -106,23 +106,32 @@ kill_httpserv()
 
 ########################### start_httpserv #############################
 # local shell function to start the httpserver with the parameters required 
 # for this test and log information (parameters, start time)
 # also: wait until the server is up and running
 ########################################################################
 start_httpserv()
 {
+  HTTP_METHOD=$1
+
   if [ -n "$testname" ] ; then
       echo "$SCRIPTNAME: $testname ----"
   fi
   echo "httpserv starting at `date`"
+  ODDIR="${HOSTDIR}/chains/OCSPD"
   echo "httpserv -D -p ${NSS_AIA_PORT} ${SERVER_OPTIONS} \\"
+  echo "         -A OCSPRoot -C ${ODDIR}/OCSPRoot.crl -A OCSPCA1 -C ${ODDIR}/OCSPCA1.crl \\"
+  echo "         -A OCSPCA2  -C ${ODDIR}/OCSPCA2.crl  -A OCSPCA3 -C ${ODDIR}/OCSPCA3.crl \\"
+  echo "         -O ${HTTP_METHOD} -d ${ODDIR}/ServerDB/ -f ${ODDIR}/ServerDB/dbpasswd \\"
   echo "         -i ${HTTPPID} $verbose &"
   ${PROFTOOL} ${BINDIR}/httpserv -D -p ${NSS_AIA_PORT} ${SERVER_OPTIONS} \
+                 -A OCSPRoot -C ${ODDIR}/OCSPRoot.crl -A OCSPCA1 -C ${ODDIR}/OCSPCA1.crl \
+                 -A OCSPCA2  -C ${ODDIR}/OCSPCA2.crl  -A OCSPCA3 -C ${ODDIR}/OCSPCA3.crl \
+                 -O ${HTTP_METHOD} -d ${ODDIR}/ServerDB/ -f ${ODDIR}/ServerDB/dbpasswd \
                  -i ${HTTPPID} $verbose &
   RET=$?
 
   # The PID $! returned by the MKS or Cygwin shell is not the PID of
   # the real background process, but rather the PID of a helper
   # process (sh.exe).  MKS's kill command has a bug: invoking kill
   # on the helper process does not terminate the real background
   # process.  Our workaround has been to have httpserv save its PID
@@ -175,44 +184,56 @@ chains_init()
 
     AIA_FILES="${HOSTDIR}/aiafiles"
 
     CU_DATA=${HOSTDIR}/cu_data
     CRL_DATA=${HOSTDIR}/crl_data
 
     DEFAULT_AIA_BASE_PORT=$(expr ${PORT:-8631} + 10)
     NSS_AIA_PORT=${NSS_AIA_PORT:-$DEFAULT_AIA_BASE_PORT}
+    DEFAULT_UNUSED_PORT=$(expr ${PORT:-8631} + 11)
+    NSS_UNUSED_PORT=${NSS_UNUSED_PORT:-$DEFAULT_UNUSED_PORT}
     NSS_AIA_HTTP=${NSS_AIA_HTTP:-"http://${HOSTADDR}:${NSS_AIA_PORT}"}
     NSS_AIA_PATH=${NSS_AIA_PATH:-$HOSTDIR/aiahttp}
+    NSS_AIA_OCSP=${NSS_AIA_OCSP:-$NSS_AIA_HTTP/ocsp}
+    NSS_OCSP_UNUSED=${NSS_AIA_OCSP_UNUSED:-"http://${HOSTADDR}:${NSS_UNUSED_PORT}"}
+
+    html_head "Certificate Chains Tests"
+}
+
+chains_run_httpserv()
+{
+    HTTP_METHOD=$1
 
     if [ -n "${NSS_AIA_PATH}" ]; then
         HTTPPID=${NSS_AIA_PATH}/http_pid.$$
         mkdir -p "${NSS_AIA_PATH}"
         SAVEPWD=`pwd`
         cd "${NSS_AIA_PATH}"
         # Start_httpserv sets environment variables, which are required for
         # correct cleanup. (Running it in a subshell doesn't work, the
         # value of $SHELL_HTTPPID wouldn't arrive in this scope.)
-        start_httpserv
+        start_httpserv ${HTTP_METHOD}
         cd "${SAVEPWD}"
     fi
+}
 
-    html_head "Certificate Chains Tests"
+chains_stop_httpserv()
+{
+    if [ -n "${NSS_AIA_PATH}" ]; then
+        kill_httpserv
+    fi
 }
 
 ############################ chains_cleanup ############################
 # local shell function to finish this script (no exit since it might be
 # sourced)
 ########################################################################
 chains_cleanup()
 {
-    if [ -n "${NSS_AIA_PATH}" ]; then
-        kill_httpserv
-    fi
-
     html "</TABLE><BR>"
     cd ${QADIR}
     . common/cleanup.sh
 }
 
 ############################ print_cu_data #############################
 # local shell function to print certutil input data
 ########################################################################
@@ -508,20 +529,26 @@ n
 n"
     fi
 }
 
 process_ocsp()
 {
     if [ -n "${OCSP}" ]; then
         OPTIONS="${OPTIONS} --extAIA"
+ 
+	if [ "${OCSP}" = "offline" ]; then
+	    MY_OCSP_URL=${NSS_OCSP_UNUSED}
+	else
+	    MY_OCSP_URL=${NSS_AIA_OCSP}
+	fi
 
         DATA="${DATA}2
 7
-${NSS_AIA_OCSP}:${OCSP}
+${MY_OCSP_URL}
 0
 n
 n
 "
     fi
 }
 
 process_crldp()
@@ -664,41 +691,57 @@ create_pkcs7()
 ############################# import_key ###############################
 # local shell function to import private key + cert into database
 ########################################################################
 import_key()
 {
     KEY_NAME=$1.p12
     DB=$2
 
-    KEY_FILE=${QADIR}/libpkix/certs/${KEY_NAME}
+    KEY_FILE=../OCSPD/${KEY_NAME}
 
     TESTNAME="Importing p12 key ${KEY_NAME} to ${DB} database"
     echo "${SCRIPTNAME}: ${TESTNAME}"
     echo "${BINDIR}/pk12util -d ${DB} -i ${KEY_FILE} -k ${DB}/dbpasswd -W nssnss"
     ${BINDIR}/pk12util -d ${DB} -i ${KEY_FILE} -k ${DB}/dbpasswd -W nssnss
     html_msg $? 0 "${SCENARIO}${TESTNAME}"
 }
 
+export_key()
+{
+    KEY_NAME=$1.p12
+    DB=$2
+
+    TESTNAME="Exporting $1 as ${KEY_NAME} from ${DB} database"
+    echo "${SCRIPTNAME}: ${TESTNAME}"
+    echo "${BINDIR}/pk12util -d ${DB} -o ${KEY_NAME} -n $1 -k ${DB}/dbpasswd -W nssnss"
+    ${BINDIR}/pk12util -d ${DB} -o ${KEY_NAME} -n $1 -k ${DB}/dbpasswd -W nssnss
+    html_msg $? 0 "${SCENARIO}${TESTNAME}"
+}
+
 ############################# import_cert ##############################
 # local shell function to import certificate into database
 ########################################################################
 import_cert()
 {
     IMPORT=$1
     DB=$2
 
     CERT_NICK=`echo ${IMPORT} | cut -d: -f1`
     CERT_ISSUER=`echo ${IMPORT} | cut -d: -f2`
     CERT_TRUST=`echo ${IMPORT} | cut -d: -f3`
 
     if [ "${CERT_ISSUER}" = "x" ]; then
         CERT_ISSUER=
         CERT=${CERT_NICK}.cert
         CERT_FILE="${QADIR}/libpkix/certs/${CERT}"
+    elif [ "${CERT_ISSUER}" = "d" ]; then
+        CERT_ISSUER=
+        CERT=${CERT_NICK}.der
+        CERT_FILE="../OCSPD/${CERT}"
     else
         CERT=${CERT_NICK}${CERT_ISSUER}.der
         CERT_FILE=${CERT}
     fi
 
     IS_ASCII=`grep -c -- "-----BEGIN CERTIFICATE-----" ${CERT_FILE}`
 
     ASCII_OPT=
@@ -800,16 +843,18 @@ revoke_cert()
 # REV_OPTS - revocation options
 ########################################################################
 
 ############################# verify_cert ##############################
 # local shell function to verify certificate validity
 ########################################################################
 verify_cert()
 {
+    ENGINE=$1
+
     DB_OPT=
     FETCH_OPT=
     POLICY_OPT=
     TRUST_OPT=
     VFY_CERTS=
     VFY_LIST=
     TRUST_AND_DB_OPT=
 
@@ -849,25 +894,29 @@ verify_cert()
     for ITEM in ${VERIFY}; do
         CERT_NICK=`echo ${ITEM} | cut -d: -f1`
         CERT_ISSUER=`echo ${ITEM} | cut -d: -f2`
 
         if [ "${CERT_ISSUER}" = "x" ]; then
             CERT="${QADIR}/libpkix/certs/${CERT_NICK}.cert"
             VFY_CERTS="${VFY_CERTS} ${CERT}"
             VFY_LIST="${VFY_LIST} ${CERT_NICK}.cert"
+        elif [ "${CERT_ISSUER}" = "d" ]; then
+            CERT="../OCSPD/${CERT_NICK}.der"
+            VFY_CERTS="${VFY_CERTS} ${CERT}"
+            VFY_LIST="${VFY_LIST} ${CERT_NICK}.cert"
         else
             CERT=${CERT_NICK}${CERT_ISSUER}.der
             VFY_CERTS="${VFY_CERTS} ${CERT}"
             VFY_LIST="${VFY_LIST} ${CERT}"
         fi
     done
 
-    VFY_OPTS_TNAME="${TRUST_AND_DB_OPT} ${REV_OPTS} ${DB_OPT} ${FETCH_OPT} ${USAGE_OPT} ${POLICY_OPT} ${TRUST_OPT}"
-    VFY_OPTS_ALL="${DB_OPT} -pp -vv ${TRUST_AND_DB_OPT} ${REV_OPTS} ${FETCH_OPT} ${USAGE_OPT} ${POLICY_OPT} ${VFY_CERTS} ${TRUST_OPT}"
+    VFY_OPTS_TNAME="${DB_OPT} ${ENGINE} ${TRUST_AND_DB_OPT} ${REV_OPTS} ${FETCH_OPT} ${USAGE_OPT} ${POLICY_OPT} ${TRUST_OPT}"
+    VFY_OPTS_ALL="${DB_OPT} ${ENGINE} -vv ${TRUST_AND_DB_OPT} ${REV_OPTS} ${FETCH_OPT} ${USAGE_OPT} ${POLICY_OPT} ${VFY_CERTS} ${TRUST_OPT}"
 
     TESTNAME="Verifying certificate(s) ${VFY_LIST} with flags ${VFY_OPTS_TNAME}"
     echo "${SCRIPTNAME}: ${TESTNAME}"
     echo "vfychain ${VFY_OPTS_ALL}"
 
     if [ -z "${MEMLEAK_DBG}" ]; then
         VFY_OUT=$(${BINDIR}/vfychain ${VFY_OPTS_ALL} 2>&1)
         RESULT=$?
@@ -906,26 +955,31 @@ check_ocsp()
 
     CERT_NICK=`echo ${OCSP_CERT} | cut -d: -f1`
     CERT_ISSUER=`echo ${OCSP_CERT} | cut -d: -f2`
 
     if [ "${CERT_ISSUER}" = "x" ]; then
         CERT_ISSUER=
         CERT=${CERT_NICK}.cert
         CERT_FILE="${QADIR}/libpkix/certs/${CERT}"
+    elif [ "${CERT_ISSUER}" = "d" ]; then
+        CERT_ISSUER=
+        CERT=${CERT_NICK}.der
+        CERT_FILE="../OCSPD/${CERT}"
     else
         CERT=${CERT_NICK}${CERT_ISSUER}.der
         CERT_FILE=${CERT}
     fi
 
     # sample line:
     #   URI: "http://ocsp.server:2601"
-    OCSP_HOST=$(${BINDIR}/pp -t certificate -i ${CERT_FILE} | grep URI | sed "s/.*:\/\///" | sed "s/:.*//")
-    OCSP_PORT=$(${BINDIR}/pp -t certificate -i ${CERT_FILE} | grep URI | sed "s/.*:.*:\([0-9]*\)\"/\1/")
+    OCSP_HOST=$(${BINDIR}/pp -w -t certificate -i ${CERT_FILE} | grep URI | sed "s/.*:\/\///" | sed "s/:.*//")
+    OCSP_PORT=$(${BINDIR}/pp -w -t certificate -i ${CERT_FILE} | grep URI | sed "s/^.*:.*:\/\/.*:\([0-9]*\).*$/\1/")
 
+    echo "tstclnt -h ${OCSP_HOST} -p ${OCSP_PORT} -q -t 20"
     tstclnt -h ${OCSP_HOST} -p ${OCSP_PORT} -q -t 20
     return $?
 }
 
 ############################ parse_result ##############################
 # local shell function to process expected result value
 # this function was created for case that expected result depends on
 # some conditions - in our case type of cert DB
@@ -978,16 +1032,17 @@ parse_config()
             CRLDP=
             OCSP=
             DB=
             EMAILS=
             EXT_KU=
             EXT_NS=
             EXT_EKU=
             SERIAL=
+	    EXPORT_KEY=
             ;;
         "type")
             TYPE="${VALUE}"
             ;;
         "issuer")
             if [ -n "${ISSUER}" ]; then
                 if [ -z "${DB}" ]; then
                     create_entity "${ENTITY}" "${TYPE}"
@@ -1043,16 +1098,19 @@ parse_config()
             create_crl "${ISSUER}"
             ;;
         "revoke")
             REVOKE="${VALUE}"
             ;;
         "serial")
             SERIAL="${VALUE}"
             ;;
+	"export_key")
+	    EXPORT_KEY=1
+	    ;;
         "copycrl")
             COPYCRL="${VALUE}"
             copy_crl "${COPYCRL}"
             ;;
         "verify")
             VERIFY="${VALUE}"
             TRUST=
             TRUST_AND_DB=
@@ -1143,21 +1201,28 @@ parse_config()
             if [ -n "${ENTITY}" ]; then
                 if [ -z "${DB}" ]; then
                     create_entity "${ENTITY}" "${TYPE}"
                 fi
                 sign_cert "${ENTITY}" "${ISSUER}" "${TYPE}"
                 if [ "${TYPE}" = "Bridge" ]; then
                     create_pkcs7 "${ENTITY}"
                 fi
+		if [ -n "${EXPORT_KEY}" ]; then
+		    export_key "${ENTITY}" "${DB}"
+		fi
                 ENTITY=
             fi
 
             if [ -n "${VERIFY}" ]; then
-                verify_cert
+                verify_cert "-pp"
+		if [ -n "${VERIFY_CLASSIC_ENGINE_TOO}" ]; then
+		    verify_cert ""
+		    verify_cert "-p"
+		fi
                 VERIFY=
             fi
 
             if [ -n "${REVOKE}" ]; then
                 revoke_cert "${REVOKE}" "${DB}"
                 REVOKE=
             fi
             ;;
@@ -1171,35 +1236,71 @@ parse_config()
     done
 
     if [ -n "${MEMLEAK_DBG}" ]; then
         log_parse
         html_msg $? 0 "${SCENARIO}Memory leak checking" 
     fi
 }
 
+process_scenario()
+{
+    SCENARIO_FILE=$1
+
+    > ${AIA_FILES}
+
+    parse_config < "${QADIR}/chains/scenarios/${SCENARIO_FILE}"
+
+    while read AIA_FILE
+    do
+	rm ${AIA_FILE} 2> /dev/null
+    done < ${AIA_FILES}
+    rm ${AIA_FILES}
+}
+
+# process ocspd.cfg separately
+chains_ocspd()
+{
+    process_scenario "ocspd.cfg"
+}
+
+# process ocsp.cfg separately
+chains_method()
+{
+    process_scenario "method.cfg"
+}
+
 ############################# chains_main ##############################
 # local shell function to process all testing scenarios
 ########################################################################
 chains_main()
 {
     while read LINE 
     do
         [ `echo ${LINE} | cut -b 1` != "#" ] || continue
 
-        > ${AIA_FILES}
-
-        parse_config < "${QADIR}/chains/scenarios/${LINE}"
+	[ ${LINE} != 'ocspd.cfg' ] || continue
+	[ ${LINE} != 'method.cfg' ] || continue
 
-        while read AIA_FILE
-        do
-            rm ${AIA_FILE} 2> /dev/null
-        done < ${AIA_FILES}
-        rm ${AIA_FILES}
+	process_scenario ${LINE}
     done < "${CHAINS_SCENARIOS}"
 }
 
 ################################ main ##################################
 
 chains_init
+VERIFY_CLASSIC_ENGINE_TOO=
+chains_ocspd
+VERIFY_CLASSIC_ENGINE_TOO=1
+chains_run_httpserv get
+chains_method
+chains_stop_httpserv
+chains_run_httpserv post
+chains_method
+chains_stop_httpserv
+VERIFY_CLASSIC_ENGINE_TOO=
+chains_run_httpserv random
 chains_main
+chains_stop_httpserv
+chains_run_httpserv get-unknown
+chains_main
+chains_stop_httpserv
 chains_cleanup
-
--- a/security/nss/tests/chains/ocspd-config/readme
+++ b/security/nss/tests/chains/ocspd-config/readme
@@ -1,18 +1,3 @@
-This script is used to generate certificates used by ocspd.
+OBSOLETE
 
-Some steps to run (only once - before all OCSP testing):
-1.  Edit security/nss/tests/chains/scenarios/scenarios to have there only ocspd.cfg
-2.  Set environment variable to run only chains tests: export NSS_TESTS=chains.sh
-3.  Set environment variable to have the correct URI in the certificates: export NSS_AIA_OCSP=http://dochinups.us.oracle.com
-4.  Run tests: ./all.sh
-5.  Go to results directory: cd tests_results/security/${HOST}.${ID}/chains
-6.  Copy ocspd-certs.sh and ocspd.conf.template to this directory
-7.  Run: ./ocspd-certs.sh OCSPD ${OCSPD_ETC_DIR} ${LIBPKIX_CERTS_DIR}:
-    Example: ./ocspd-certs.sh OCSPD /export/iopr/openca-ocsp-responder/etc/ocspdPKIX \
-       ~/nss/securitytip/mozilla/security/nss/tests/libpkix/certs
-8.  Commit the new certificates that have been generated under ~/nss/securitytip/mozilla/security/nss/tests/libpkix/certs
-9.  Copy config files and keys/certs/crls to ocspd etc directory:
-    cp *.conf /Volumes/dochinups.red.iplanet.com/openca-ocsp-responder/etc/ocspdPKIX
-    cp *.pem *.key /Volumes/dochinups.red.iplanet.com/openca-ocsp-responder/etc/ocspdPKIX/OCSPD
-10. Start ocsp deamons on dochinups (for all configs).
-
+tests have been changed to use a local ocsp server (using httpserv)
--- a/security/nss/tests/chains/scenarios/ocsp.cfg
+++ b/security/nss/tests/chains/scenarios/ocsp.cfg
@@ -1,177 +1,177 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 scenario OCSP
 
-check_ocsp OCSPEE11:x
+check_ocsp OCSPEE11OCSPCA1:d
 
 db OCSPRoot
-import OCSPRoot:x:CT,C,C
+import OCSPRoot:d:CT,C,C
 
 db OCSPCA1
 import_key OCSPCA1
 
 crl OCSPCA1
 
 revoke OCSPCA1
   serial 3
 
 revoke OCSPCA1
   serial 4 
 
 testdb OCSPRoot
 
 #EE - OK, CA - OK
-verify OCSPEE11:x
-  cert OCSPCA1:x
+verify OCSPEE11OCSPCA1:d
+  cert OCSPCA1OCSPRoot:d
   trust OCSPRoot
   rev_type leaf
   rev_flags requireFreshInfo
   rev_mtype ocsp
   result pass
 
 #EE - revoked, CA - OK
-verify OCSPEE12:x
-  cert OCSPCA1:x
+verify OCSPEE12OCSPCA1:d
+  cert OCSPCA1OCSPRoot:d
   trust OCSPRoot
   rev_type leaf
   rev_flags requireFreshInfo
   rev_mtype ocsp
   result fail
 
 #EE - unknown 
-verify OCSPEE15:x
-  cert OCSPCA1:x
+verify OCSPEE15OCSPCA1:d
+  cert OCSPCA1OCSPRoot:d
   trust OCSPRoot
   rev_type leaf
   rev_mtype ocsp
   result pass
 
 #EE - unknown, requireFreshInfo
-verify OCSPEE15:x
-  cert OCSPCA1:x
+verify OCSPEE15OCSPCA1:d
+  cert OCSPCA1OCSPRoot:d
   trust OCSPRoot
   rev_type leaf
   rev_flags requireFreshInfo
   rev_mtype ocsp
   result fail
 
 #EE - OK, CA - revoked, leaf, no fresh info
-verify OCSPEE21:x
-  cert OCSPCA2:x
+verify OCSPEE21OCSPCA2:d
+  cert OCSPCA2OCSPRoot:d
   trust OCSPRoot
   rev_type leaf
   rev_mtype ocsp
   result pass
 
 #EE - OK, CA - revoked, leaf, requireFreshInfo
-verify OCSPEE21:x
-  cert OCSPCA2:x
+verify OCSPEE21OCSPCA2:d
+  cert OCSPCA2OCSPRoot:d
   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
+verify OCSPEE21OCSPCA2:d
+  cert OCSPCA2OCSPRoot:d
   trust OCSPRoot
   rev_type chain
   rev_flags requireFreshInfo
   rev_mtype ocsp
   result fail
 
 #EE - OK, CA - unknown
-verify OCSPEE31:x
-  cert OCSPCA3:x
+verify OCSPEE31OCSPCA3:d
+  cert OCSPCA3OCSPRoot:d
   trust OCSPRoot
   rev_type leaf
   rev_mtype ocsp
   result pass
 
 #EE - OK, CA - unknown, requireFreshInfo
-verify OCSPEE31:x
-  cert OCSPCA3:x
+verify OCSPEE31OCSPCA3:d
+  cert OCSPCA3OCSPRoot:d
   trust OCSPRoot
   rev_type leaf
   rev_flags requireFreshInfo
   rev_mtype ocsp
   result fail
 
 #EE - revoked, doNotUse
-verify OCSPEE12:x
-  cert OCSPCA1:x
+verify OCSPEE12OCSPCA1:d
+  cert OCSPCA1OCSPRoot:d
   trust OCSPRoot
   rev_type leaf
   rev_mtype ocsp
   rev_mflags doNotUse
   result pass
 
 #EE - revoked, forbidFetching
-verify OCSPEE12:x
-  cert OCSPCA1:x
+verify OCSPEE12OCSPCA1:d
+  cert OCSPCA1OCSPRoot:d
   trust OCSPRoot
   rev_type leaf
   rev_mtype ocsp
   rev_mflags forbidFetching
   result pass
 
 #EE - unknown status, failIfNoInfo
-verify OCSPEE15:x
-  cert OCSPCA1:x
+verify OCSPEE15OCSPCA1:d
+  cert OCSPCA1OCSPRoot:d
   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
+verify OCSPEE21OCSPCA2:d
+  cert OCSPCA2OCSPRoot:d
   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
+verify OCSPEE13OCSPCA1:d
+  cert OCSPCA1OCSPRoot:d
   trust OCSPCA1
   rev_type leaf
   rev_flags testLocalInfoFirst
   rev_mtype ocsp
   result pass
 
 db OCSPRoot1
-import OCSPRoot:x:CT,C,C
+import OCSPRoot:d:CT,C,C
 
-verify OCSPEE23:x
-  cert OCSPCA2:x
+verify OCSPEE23OCSPCA2:d
+  cert OCSPCA2OCSPRoot:d
   trust OCSPRoot
   rev_type chain
   rev_mtype ocsp
   rev_type leaf
   rev_mtype ocsp
   result fail
 
 db OCSPRoot2
-import OCSPRoot:x:T,,
+import OCSPRoot:d:T,,
 
 # bug 527438
 # expected result of this test is FAIL
-verify OCSPEE23:x
-  cert OCSPCA2:x
+verify OCSPEE23OCSPCA2:d
+  cert OCSPCA2OCSPRoot:d
   trust OCSPRoot
   rev_type chain
   rev_mtype ocsp
   rev_type leaf
   rev_mtype ocsp
   result pass
 
--- a/security/nss/tests/chains/scenarios/ocspd.cfg
+++ b/security/nss/tests/chains/scenarios/ocspd.cfg
@@ -2,114 +2,118 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 scenario OCSPD
 
 #root CA
 entity OCSPRoot
   type Root
+  export_key
 
 #CA - OK
 entity OCSPCA1
   type Intermediate
   issuer OCSPRoot
   serial 1
-  ocsp 2600
+  ocsp online
+  export_key
 
 #CA - revoked
 entity OCSPCA2
   type Intermediate
   issuer OCSPRoot
   serial 2
-  ocsp 2600
+  ocsp online
+  export_key
 
 #CA - unknown status
 entity OCSPCA3
   type Intermediate
   issuer OCSPRoot
   serial 3
-  ocsp 2599
+  ocsp offline
+  export_key
 
 #EE - OK
 entity OCSPEE11
   type EE
   issuer OCSPCA1
   serial 1
-  ocsp 2601
+  ocsp online
 
 #EE - revoked on OCSP
 entity OCSPEE12
   type EE
   issuer OCSPCA1
   serial 2
-  ocsp 2601
+  ocsp online
 
 #EE - revoked on CRL
 entity OCSPEE13
   type EE
   issuer OCSPCA1
   serial 3
-  ocsp 2601
+  ocsp online
 
 #EE - revoked on OCSP and CRL
 entity OCSPEE14
   type EE
   issuer OCSPCA1
   serial 4
-  ocsp 2601
+  ocsp online
 
 #EE - unknown status
 entity OCSPEE15
   type EE
   issuer OCSPCA1
   serial 5
-  ocsp 2599
+  ocsp offline
 
 #EE - valid EE, revoked CA
 entity OCSPEE21
   type EE
   issuer OCSPCA2
   serial 1
-  ocsp 2602
+  ocsp online
 
 #EE - revoked EE, revoked CA
 entity OCSPEE22
   type EE 
   issuer OCSPCA2 
   serial 2
-  ocsp 2602
+  ocsp online
 
 #EE - revoked EE, CA pointing to invalid OCSP
 entity OCSPEE23
   type EE 
   issuer OCSPCA2 
   serial 3
-  ocsp 2599
+  ocsp offline
 
 #EE - valid EE, CA pointing to invalid OCSP
 entity OCSPEE31
   type EE
   issuer OCSPCA3
   serial 1
-  ocsp 2603
+  ocsp online
 
 #EE - revoked EE, CA pointing to invalid OCSP
 entity OCSPEE32
   type EE 
   issuer OCSPCA3 
   serial 2
-  ocsp 2603
+  ocsp online
 
 #EE - EE pointing to invalid OCSP, CA pointing to invalid OCSP
 entity OCSPEE33
   type EE 
   issuer OCSPCA3 
   serial 3
-  ocsp 2599
+  ocsp offline
 
 crl OCSPRoot
 
 revoke OCSPRoot
   serial 2
 
 crl OCSPCA1
 
@@ -130,8 +134,39 @@ revoke OCSPCA2
 crl OCSPCA3
 
 revoke OCSPCA3
   serial 2
 
 revoke OCSPCA3
   serial 3
 
+# Used for running a single OCSP server (httpserv) instance that can
+# handle multiple CAs, e.g.:
+# httpserv -p 8641 -d . -f dbpasswd \
+#   -A OCSPRoot -C OCSPRoot.crl -A OCSPCA1 -C OCSPCA1.crl \
+#   -A OCSPCA2 -C OCSPCA2.crl -A OCSPCA3 -C OCSPCA3.crl
+db Server
+import OCSPRoot::CT,C,C
+import_key OCSPRoot
+import_key OCSPCA1
+import_key OCSPCA2
+import_key OCSPCA3
+
+# A DB containing all certs, but no keys.
+# Useful for manual OCSP client testing, e.g.:
+# ocspclnt -d .  -S OCSPEE12OCSPCA1 -u s
+db Client
+import OCSPRoot::CT,C,C
+import OCSPCA1OCSPRoot::
+import OCSPCA2OCSPRoot::
+import OCSPCA3OCSPRoot::
+import OCSPEE11OCSPCA1::
+import OCSPEE12OCSPCA1::
+import OCSPEE13OCSPCA1::
+import OCSPEE14OCSPCA1::
+import OCSPEE15OCSPCA1::
+import OCSPEE21OCSPCA2::
+import OCSPEE22OCSPCA2::
+import OCSPEE23OCSPCA2::
+import OCSPEE31OCSPCA3::
+import OCSPEE32OCSPCA3::
+import OCSPEE33OCSPCA3::
--- a/security/nss/tests/chains/scenarios/scenarios
+++ b/security/nss/tests/chains/scenarios/scenarios
@@ -29,16 +29,25 @@
 # 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 *****
+#
+# Scenario ocspd.cfg will always be processed first,
+# regardless of its presence in this list.
+#
+# Scenario method.cfg will always be processed, regardless of its presence
+# in this list, and will be processed twice, once with httpserv -O get 
+# and once with -O post. Because method.cfg will be executed with both
+# classic and libpkix engines, it must not contain any policy checks.
+#
 bridge.cfg
 megabridge_3_2.cfg
 extension.cfg
 extension2.cfg
 anypolicy.cfg
 anypolicywithlevel.cfg
 explicitPolicy.cfg
 mapping.cfg
--- a/security/nss/tests/ocsp/ocsp.sh
+++ b/security/nss/tests/ocsp/ocsp.sh
@@ -44,78 +44,11 @@ ocsp_init()
   SCRIPTNAME=ocsp.sh
   echo "$SCRIPTNAME: OCSP tests ==============================="
 
   REQF=${QADIR}/ssl/sslreq.dat
 
   cd ${CLIENTDIR}
 }
 
-ocsp_stapling()
-{
-  # Parameter -4 is used as a temporary workaround for lack of IPv6 connectivity
-  # on some build bot slaves.
-
-  TESTNAME="startssl valid, supports OCSP stapling"
-  echo "$SCRIPTNAME: $TESTNAME"
-  echo "tstclnt -4 -V tls1.0: -T -v -F -M 1 -O -h kuix.de -p 5143 -d . < ${REQF}"
-  ${BINDIR}/tstclnt -4 -V tls1.0: -T -v -F -M 1 -O -h kuix.de -p 5143 -d . < ${REQF}
-  html_msg $? 0 "$TESTNAME"
-
-  TESTNAME="startssl revoked, supports OCSP stapling"
-  echo "$SCRIPTNAME: $TESTNAME"
-  echo "tstclnt -4 -V tls1.0: -T -v -F -M 1 -O -h kuix.de -p 5144 -d . < ${REQF}"
-  ${BINDIR}/tstclnt -4 -V tls1.0: -T -v -F -M 1 -O -h kuix.de -p 5144 -d . < ${REQF}
-  html_msg $? 3 "$TESTNAME"
-
-  TESTNAME="comodo trial test expired revoked, supports OCSP stapling"
-  echo "$SCRIPTNAME: $TESTNAME"
-  echo "tstclnt -4 -V tls1.0: -T -v -F -M 1 -O -h kuix.de -p 5145 -d . < ${REQF}"
-  ${BINDIR}/tstclnt -4 -V tls1.0: -T -v -F -M 1 -O -h kuix.de -p 5145 -d . < ${REQF}
-  html_msg $? 1 "$TESTNAME"
-
-  TESTNAME="thawte (expired) valid, supports OCSP stapling"
-  echo "$SCRIPTNAME: $TESTNAME"
-  echo "tstclnt -4 -V tls1.0: -T -v -F -M 1 -O -h kuix.de -p 5146 -d . < ${REQF}"
-  ${BINDIR}/tstclnt -4 -V tls1.0: -T -v -F -M 1 -O -h kuix.de -p 5146 -d . < ${REQF}
-  html_msg $? 1 "$TESTNAME"
-
-  TESTNAME="thawte (expired) revoked, supports OCSP stapling"
-  echo "$SCRIPTNAME: $TESTNAME"
-  echo "tstclnt -4 -V tls1.0: -T -v -F -M 1 -O -h kuix.de -p 5147 -d . < ${REQF}"
-  ${BINDIR}/tstclnt -4 -V tls1.0: -T -v -F -M 1 -O -h kuix.de -p 5147 -d . < ${REQF}
-  html_msg $? 1 "$TESTNAME"
-
-  TESTNAME="digicert valid, supports OCSP stapling"
-  echo "$SCRIPTNAME: $TESTNAME"
-  echo "tstclnt -4 -V tls1.0: -T -v -F -M 1 -O -h kuix.de -p 5148 -d . < ${REQF}"
-  ${BINDIR}/tstclnt -4 -V tls1.0: -T -v -F -M 1 -O -h kuix.de -p 5148 -d . < ${REQF}
-  html_msg $? 0 "$TESTNAME"
-
-  TESTNAME="digicert revoked, supports OCSP stapling"
-  echo "$SCRIPTNAME: $TESTNAME"
-  echo "tstclnt -4 -V tls1.0: -T -v -F -M 1 -O -h kuix.de -p 5149 -d . < ${REQF}"
-  ${BINDIR}/tstclnt -4 -V tls1.0: -T -v -F -M 1 -O -h kuix.de -p 5149 -d . < ${REQF}
-  html_msg $? 3 "$TESTNAME"
-
-  TESTNAME="live valid, supports OCSP stapling"
-  echo "$SCRIPTNAME: $TESTNAME"
-  echo "tstclnt -V tls1.0: -T -v -F -M 1 -O -h login.live.com -p 443 -d . < ${REQF}"
-  ${BINDIR}/tstclnt -V tls1.0: -T -v -F -M 1 -O -h login.live.com -p 443 -d . < ${REQF}
-  html_msg $? 0 "$TESTNAME"
-
-  TESTNAME="startssl valid, doesn't support OCSP stapling"
-  echo "$SCRIPTNAME: $TESTNAME"
-  echo "tstclnt -4 -V tls1.0: -T -v -F -M 1 -O -h kuix.de -p 443 -d . < ${REQF}"
-  ${BINDIR}/tstclnt -4 -V tls1.0: -T -v -F -M 1 -O -h kuix.de -p 443 -d . < ${REQF}
-  html_msg $? 2 "$TESTNAME"
-
-  TESTNAME="cacert untrusted, doesn't support OCSP stapling"
-  echo "$SCRIPTNAME: $TESTNAME"
-  echo "tstclnt -V tls1.0: -T -v -F -M 1 -O -h www.cacert.org -p 443 -d . < ${REQF}"
-  ${BINDIR}/tstclnt -V tls1.0: -T -v -F -M 1 -O -h www.cacert.org -p 443 -d . < ${REQF}
-  html_msg $? 1 "$TESTNAME"
-}
-
 ################## main #################################################
 ocsp_init
 ocsp_iopr_run
-ocsp_stapling