sync. up with the main branch SAMPLES_BRANCH
authorElio Maldonado <emaldona@redhat.com>
Mon, 12 Oct 2015 07:30:24 -0700
branchSAMPLES_BRANCH
changeset 11642 bcf37ee47d307912e94cf7114a44b989ac3c3783
parent 11332 72aa807c09e5114be1232448d420395375bf22d0 (current diff)
parent 11641 2f6ef09e9495765dda738dfc091effb7183f6d87 (diff)
child 11643 e00623942549a1f84added21316139574b48c69f
push id797
push useremaldona@redhat.com
push dateMon, 12 Oct 2015 21:15:44 +0000
sync. up with the main branch
Makefile
lib/dbm/include/cdefs.h
lib/dbm/include/mpool.h
tests/ssl_gtests/ssl_gtests.sh
new file mode 100644
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+*~
+*.swp
+*OPT.OBJ/
+*DBG.OBJ/
+*DBG.OBJD/
--- a/.hgtags
+++ b/.hgtags
@@ -1524,8 +1524,36 @@ 358730f7261da6aa7b1ee19aafb22c0fc40506f8
 e65f62b51d62b882f3de467b7cba7fb2699dbf8b NSS_3_17_2_RC0
 fb8925f6648d5c7829b74853bc5585ec250b85b4 NSS_3_17_2_RTM
 1882a6db68fd34cd907e3c3fa398455f15b80784 NSS_3_18_BETA1
 c92f97d1bd26d81a1a7b98a05985cade88132a2f NSS_3_18_BETA2
 f9bac028f79a6b2129c561137f1d4312c981cedd NSS_3_18_BETA3
 01c19c751a742cd382c121a33dac7c65cdb2fd50 NSS_3_18_BETA4
 f5c1de4478efd102de37ecdd488a89070159432f NSS_3_17_3_RC0
 092819bde8dbf774f7ca761add1ab002d0209f12 NSS_3_17_3_RTM
+0455ebb9ad001507fcd795df23f452cb0be80832 NSS_3_18_BETA5
+fb546430479b31cd7ea40226c44e40913e4bb227 NSS_3_18_BETA6
+8b41721a1e1531d7a91fff13fa04a4c5a389ba48 NSS_3_17_4_RC0
+858493460699bce43b9bbe1e397c6a929db6ca9f NSS_3_17_4_RTM
+483fbe78c2b2707a53185e63ab37d72af4883aa5 NSS_3_18_BETA7
+a1a73fb115562b7122ecbba2da587aa3bc39ed57 NSS_3_18_RC0
+52c02fe9ce3aec27f11a589b8e98ddc79234ec86 NSS_3_18_RC1
+5dd4763f532ff3bd3145912c29b5f1e694abd8e9 NSS_3_18_RTM
+5dd4763f532ff3bd3145912c29b5f1e694abd8e9 NSS_3_18_RTM
+0000000000000000000000000000000000000000 NSS_3_18_RTM
+c89e2dedb1277ec0acda8e8fccfbeb5034addc4c NSS_3_18_RC2
+0000000000000000000000000000000000000000 NSS_3_18_RTM
+b01f280a73e940731d24ab37740ee5fa14264cef NSS_3_18_RTM
+9dde22ab19d1c7c5e0acbdfcab99550313ca733a NSS_3_18_1_BETA1
+431691e123f03c151b7b54579e488a1687edc9e2 NSS_3_19_BETA2
+c1bd3c0eaa342b1a628efcfef9e99aacc3f0c20a NSS_3_19_BETA3
+1a2a200aeb4002fdb63b412fe50f8e2ba90a82ef NSS_3_19_BETA4
+342f7e837802c1efc73992776ace45f2c8fdfb47 NSS_3_19_BETA5
+607a836b01ed2660eafda422ba2266b5cc91740b NSS_3_19_RC0
+af38c6ffbe4efafee3cf5920ebf0db6ce298f01e NSS_3_19_RTM
+ae72d76f8d2472505b499c498191c3ce441b6a17 NSS_3_19_1_BETA1
+ae72d76f8d2472505b499c498191c3ce441b6a17 NSS_3_19_1_BETA1
+736d9f81295197d3ba63a4ece70f1c377d28e630 NSS_3_19_1_BETA1
+537d7fc8624c289e4f818a4c69847eaedecceccb NSS_3_19_1_RTM
+2b29dfe134a5fd5ba2c4e80074b7cf8fc2d36cfd NSS_3_19_2_BETA1
+97d30005dd7bb02b15bd2b8a27e2426c49d06d69 NSS_3_19_2_RTM
+6e60855257f0f3d34cb51cdd2aba1800b7834f7f NSS_3_21_Beta1
+dc5a3f75d9d5d0fc6dd5f5b60b5b9be693dbbc78 NSS_3_21_Beta2
--- a/Makefile
+++ b/Makefile
@@ -51,17 +51,21 @@ nss_clean_all: clobber_nspr clobber
 NSPR_CONFIG_STATUS = $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME)/config.status
 NSPR_CONFIGURE = $(CORE_DEPTH)/../nspr/configure
 
 #
 # Translate coreconf build options to NSPR configure options.
 #
 
 ifeq ($(OS_TARGET),Android)
-NSPR_CONFIGURE_OPTS += --with-android-ndk=$(ANDROID_NDK) --target=arm-linux-androideabi --with-android-version=$(OS_TARGET_RELEASE)
+NSPR_CONFIGURE_OPTS += --with-android-ndk=$(ANDROID_NDK) \
+                       --target=$(ANDROID_PREFIX) \
+                       --with-android-version=$(OS_TARGET_RELEASE) \
+                       --with-android-toolchain=$(ANDROID_TOOLCHAIN) \
+                       --with-android-platform=$(ANDROID_SYSROOT)
 endif
 ifdef BUILD_OPT
 NSPR_CONFIGURE_OPTS += --disable-debug --enable-optimize
 endif
 ifdef USE_X32
 NSPR_CONFIGURE_OPTS += --enable-x32
 endif
 ifdef USE_64
new file mode 100644
--- /dev/null
+++ b/circle.yml
@@ -0,0 +1,18 @@
+checkout:
+    post:
+        - cd ..; hg clone https://hg.mozilla.org/projects/nspr
+
+test:
+    override:
+        - make nss_build_all
+        - cd tests; NSS_TESTS=ssl_gtests NSS_CYCLES=standard ./all.sh
+
+machine:
+    environment:
+        { USE_64: 1,
+          NSS_ENABLE_TLS_1_3: 1,
+          NSS_BUILD_GTESTS: 1,
+        }
+    hosts:
+
+
--- a/cmd/bltest/blapitest.c
+++ b/cmd/bltest/blapitest.c
@@ -51,18 +51,17 @@ char *testdir = NULL;
 #define TIMEFINISH(time, reps) \
     time2 = (PRIntervalTime)(PR_IntervalNow() - time1); \
     time1 = PR_IntervalToMilliseconds(time2); \
     time = ((double)(time1))/reps;
 
 #define TIMEMARK(seconds) \
     time1 = PR_SecondsToInterval(seconds); \
     { \
-        PRInt64 tmp, L100; \
-        LL_I2L(L100, 100); \
+        PRInt64 tmp; \
         if (time2 == 0) { \
             time2 = 1; \
         } \
         LL_DIV(tmp, time1, time2); \
         if (tmp < 10) { \
             if (tmp == 0) { \
                 opsBetweenChecks = 1; \
             } else { \
@@ -308,29 +307,28 @@ char2_from_hex(unsigned char byteval, ch
     return SECSuccess;
 }
 
 void
 serialize_key(SECItem *it, int ni, PRFileDesc *file)
 {
     unsigned char len[4];
     int i;
-    SECStatus status;
     NSSBase64Encoder *cx;
     cx = NSSBase64Encoder_Create(output_ascii, file);
     for (i=0; i<ni; i++, it++) {
 	len[0] = (it->len >> 24) & 0xff;
 	len[1] = (it->len >> 16) & 0xff;
 	len[2] = (it->len >>  8) & 0xff;
 	len[3] = (it->len	 & 0xff);
-	status = NSSBase64Encoder_Update(cx, len, 4);
-	status = NSSBase64Encoder_Update(cx, it->data, it->len);
+	NSSBase64Encoder_Update(cx, len, 4);
+	NSSBase64Encoder_Update(cx, it->data, it->len);
     }
-    status = NSSBase64Encoder_Destroy(cx, PR_FALSE);
-    status = PR_Write(file, "\r\n", 2);
+    NSSBase64Encoder_Destroy(cx, PR_FALSE);
+    PR_Write(file, "\r\n", 2);
 }
 
 void
 key_from_filedata(PLArenaPool *arena, SECItem *it, int ns, int ni, SECItem *filedata)
 {
     int fpos = 0;
     int i, len;
     unsigned char *buf = filedata->data;
@@ -1431,17 +1429,17 @@ bltest_rc5_init(bltestCipherInfo *cipher
 SECStatus
 bltest_aes_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
 {
     bltestSymmKeyParams *aesp = &cipherInfo->params.sk;
     bltestAuthSymmKeyParams *gcmp = &cipherInfo->params.ask;
     int minorMode;
     int i;
     int keylen   = aesp->key.buf.len;
-    int blocklen = AES_BLOCK_SIZE; 
+    unsigned int blocklen = AES_BLOCK_SIZE;
     PRIntervalTime time1, time2;
     unsigned char *params;
     int len;
     CK_AES_CTR_PARAMS ctrParams;
     CK_GCM_PARAMS gcmParams;
 
     params = aesp->iv.buf.data;
     switch (cipherInfo->mode) {
@@ -1630,16 +1628,18 @@ bltest_rsa_init(bltestCipherInfo *cipher
         case bltestRSA_PSS:
             cipherInfo->cipher.pubkeyCipher = encrypt ? rsa_signDigestPSS
                                                       : rsa_verifyDigestPSS;
             break;
         case bltestRSA_OAEP:
             cipherInfo->cipher.pubkeyCipher = encrypt ? rsa_encryptOAEP
                                                       : rsa_decryptOAEP;
             break;
+        default:
+            break;
     }
     return SECSuccess;
 }
 
 SECStatus
 blapi_pqg_param_gen(unsigned int keysize, PQGParams **pqg, PQGVerify **vfy)
 {
     if (keysize < 1024) {
@@ -2564,18 +2564,16 @@ getHighUnitBytes(PRInt64 res)
 static void
 printPR_smpString(const char *sformat, char *reportStr,
                   const char *nformat, PRInt64 rNum)
 {
     if (reportStr) {
         fprintf(stdout, sformat, reportStr);
         PR_smprintf_free(reportStr);
     } else {
-        int prnRes;
-        LL_L2I(prnRes, rNum);
         fprintf(stdout, nformat, rNum);
     }
 }
 
 static char*
 getHighUnitOps(PRInt64 res)
 {
     int spl[] = {0, 0, 0, 0};
@@ -2786,18 +2784,18 @@ mode_str_to_hash_alg(const SECItem *mode
     switch (mode) {
         case bltestMD2:    return HASH_AlgMD2;
         case bltestMD5:    return HASH_AlgMD5;
         case bltestSHA1:   return HASH_AlgSHA1;
         case bltestSHA224: return HASH_AlgSHA224;
         case bltestSHA256: return HASH_AlgSHA256;
         case bltestSHA384: return HASH_AlgSHA384;
         case bltestSHA512: return HASH_AlgSHA512;
+        default: return HASH_AlgNULL;
     }
-    return HASH_AlgNULL;
 }
 
 void
 get_params(PLArenaPool *arena, bltestParams *params,
 	   bltestCipherMode mode, int j)
 {
     char filename[256];
     char *modestr = mode_strings[mode];
@@ -2999,17 +2997,17 @@ ReadFileToItem(SECItem *dst, const char 
 static SECStatus
 blapi_selftest(bltestCipherMode *modes, int numModes, int inoff, int outoff,
                PRBool encrypt, PRBool decrypt)
 {
     bltestCipherInfo cipherInfo;
     bltestIO pt, ct;
     bltestCipherMode mode;
     bltestParams *params;
-    int i, j, nummodes, numtests;
+    unsigned int i, j, nummodes, numtests;
     char *modestr;
     char filename[256];
     PLArenaPool *arena;
     SECItem item;
     SECStatus rv = SECSuccess, srv;
 
     PORT_Memset(&cipherInfo, 0, sizeof(cipherInfo));
     arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
@@ -3452,23 +3450,22 @@ static secuCommandFlag bltest_options[] 
     { /* opt_MonteCarlo   */ '3', PR_FALSE, 0, PR_FALSE },
     { /* opt_ThreadNum    */ '4', PR_TRUE,  0, PR_FALSE },
     { /* opt_SecondsToRun */ '5', PR_TRUE,  0, PR_FALSE },
     { /* opt_CmdLine	  */ '-', PR_FALSE, 0, PR_FALSE }
 };
 
 int main(int argc, char **argv)
 {
-    char *infileName, *outfileName, *keyfileName, *ivfileName;
     SECStatus rv = SECFailure;
 
-    double              totalTime;
+    double              totalTime = 0.0;
     PRIntervalTime      time1, time2;
     PRFileDesc          *outfile = NULL;
-    bltestCipherInfo    *cipherInfoListHead, *cipherInfo;
+    bltestCipherInfo    *cipherInfoListHead, *cipherInfo = NULL;
     bltestIOMode        ioMode;
     int                 bufsize, exponent, curThrdNum;
 #ifndef NSS_DISABLE_ECC
     char		*curveName = NULL;
 #endif
     int			 i, commandsEntered;
     int			 inoff, outoff;
     int                  threads = 1;
@@ -3506,18 +3503,16 @@ int main(int argc, char **argv)
     if (rv == SECFailure) {
 	fprintf(stderr, "%s: command line parsing error!\n", progName);
 	goto print_usage;
     }
     rv = SECFailure;
 
     cipherInfo = PORT_ZNew(bltestCipherInfo);
     cipherInfoListHead = cipherInfo;
-    /* set some defaults */
-    infileName = outfileName = keyfileName = ivfileName = NULL;
 
     /* Check the number of commands entered on the command line. */
     commandsEntered = 0;
     for (i=0; i<bltest.numCommands; i++)
 	if (bltest.commands[i].activated)
 	    commandsEntered++;
 
     if (commandsEntered > 1 &&
@@ -3552,17 +3547,17 @@ int main(int argc, char **argv)
      * Handle three simple cases first
      */
 
     /* test the RSA_PopulatePrivateKey function */
     if (bltest.commands[cmd_RSAPopulate].activated) {
 	unsigned int keySize = 1024;
 	unsigned long exponent = 65537;
 	int rounds = 1;
-	int ret;
+	int ret = -1;
 	
 	if (bltest.options[opt_KeySize].activated) {
 	    keySize = PORT_Atoi(bltest.options[opt_KeySize].arg);
 	}
 	if (bltest.options[opt_Rounds].activated) {
 	    rounds = PORT_Atoi(bltest.options[opt_Rounds].arg);
 	}
 	if (bltest.options[opt_Exponent].activated) {
@@ -3707,18 +3702,20 @@ int main(int argc, char **argv)
 	curveName = NULL;
 #endif
 
     if (bltest.commands[cmd_Verify].activated &&
         !bltest.options[opt_SigFile].activated) {
         fprintf(stderr, "%s: You must specify a signature file with -f.\n",
                 progName);
 
-      print_usage:
-        PORT_Free(cipherInfo);
+print_usage:
+        if (cipherInfo) {
+            PORT_Free(cipherInfo);
+        }
         Usage();
     }
 
     if (bltest.options[opt_MonteCarlo].activated) {
         cipherInfo->mCarlo = PR_TRUE;
     } else {
         cipherInfo->mCarlo = PR_FALSE;
     }
--- a/cmd/certcgi/certcgi.c
+++ b/cmd/certcgi/certcgi.c
@@ -351,91 +351,16 @@ find_field_bool(Pair    *data,
 	
     if  ((rv != NULL) && (PORT_Strcmp(rv, "true")) == 0) {
 	return PR_TRUE;
     } else {
 	return PR_FALSE;
     }
 }
 
-static char *
-update_data_by_name(Pair  *data, 
-		    char  *field_name,
-                    char  *new_data)
-    /* replaces the data in the data structure associated with 
-       a name with new data, returns null if not found */
-{
-    int                   i = 0;
-    int                   found = 0;
-    int                   length = 100;
-    char                  *new;
-
-    while (return_name(data, i) != NULL) {
-	if (PORT_Strcmp(return_name(data, i), field_name) == 0) {
-	    new = make_copy_string( new_data, length, '\0');
-	    PORT_Free(return_data(data, i));
-	    found = 1;
-	    (*(data + i)).data = new;
-	    break;
-	}
-	i++;
-    }
-    if (!found) {
-	new = NULL;
-    }
-    return new;
-}
-
-static char *
-update_data_by_index(Pair  *data, 
-		     int   n, 
-		     char  *new_data)
-    /* replaces the data of a particular index in the data structure */
-{
-    int                    length = 100;
-    char                   *new;
-
-    new = make_copy_string(new_data, length, '\0');
-    PORT_Free(return_data(data, n));
-    (*(data + n)).data = new;
-    return new;
-}
-
-
-static Pair *
-add_field(Pair   *data, 
-	  char*  field_name, 
-	  char*  field_data)
-    /* adds a new name/data pair to the data structure */
-{
-    int          i = 0;
-    int          j;
-    int          name_length = 100;
-    int          data_length = 100;
-
-    while(return_name(data, i) != NULL) {
-	i++;
-    }
-    j = START_FIELDS;
-    while ( j < (i + 1) ) {
-	j = j * 2;
-    }
-    if (j == (i + 1)) {
-	data = (Pair *) PORT_Realloc(data, (j * 2) * sizeof(Pair));
-	if (data == NULL) {
-	    error_allocate();
-	}
-    }
-    (*(data + i)).name = make_copy_string(field_name, name_length, '\0');
-    (*(data + i)).data = make_copy_string(field_data, data_length, '\0');
-    (data + i + 1)->name = NULL;
-    return data;
-}
-
-
 static CERTCertificateRequest *
 makeCertReq(Pair             *form_data,
 	    int              which_priv_key)
     /* makes and encodes a certrequest */
 {
 
     PK11SlotInfo             *slot;
     CERTCertificateRequest   *certReq = NULL;
@@ -522,40 +447,36 @@ MakeV1Cert(CERTCertDBHandle        *hand
 	   Pair                    *data)
 {
     CERTCertificate                 *issuerCert = NULL;
     CERTValidity                    *validity;
     CERTCertificate                 *cert = NULL;
     PRExplodedTime                  printableTime;
     PRTime                          now, 
 	                            after;
-    SECStatus rv;
-   
-    
-
     if ( !selfsign ) {
 	issuerCert = CERT_FindCertByNameString(handle, issuerNameStr);
 	if (!issuerCert) {
 	    error_out("ERROR: Could not find issuer's certificate");
 	    return NULL;
 	}
     }
     if (find_field_bool(data, "manValidity", PR_TRUE)) {
-	rv = DER_AsciiToTime(&now, find_field(data, "notBefore", PR_TRUE));
+	(void)DER_AsciiToTime(&now, find_field(data, "notBefore", PR_TRUE));
     } else {
 	now = PR_Now();
     }
     PR_ExplodeTime (now, PR_GMTParameters, &printableTime);
     if ( warpmonths ) {
 	printableTime.tm_month += warpmonths;
 	now = PR_ImplodeTime (&printableTime);
 	PR_ExplodeTime (now, PR_GMTParameters, &printableTime);
     }
     if (find_field_bool(data, "manValidity", PR_TRUE)) {
-	rv = DER_AsciiToTime(&after, find_field(data, "notAfter", PR_TRUE));
+	(void)DER_AsciiToTime(&after, find_field(data, "notAfter", PR_TRUE));
 	PR_ExplodeTime (after, PR_GMTParameters, &printableTime);
     } else {
 	printableTime.tm_month += 3;
 	after = PR_ImplodeTime (&printableTime);
     }
     /* note that the time is now in micro-second unit */
     validity = CERT_CreateValidity (now, after);
 
@@ -582,21 +503,21 @@ get_serial_number(Pair  *data)
     char                *filename = SERIAL_FILE;
     char                *SN;
     FILE                *serialFile;
 
 
     if (find_field_bool(data, "serial-auto", PR_TRUE)) {
 	serialFile = fopen(filename, "r");
 	if (serialFile != NULL) {
-	    fread(&serial, sizeof(int), 1, serialFile);
-	    if (ferror(serialFile) != 0) {
+	    size_t nread = fread(&serial, sizeof(int), 1, serialFile);
+	    if (ferror(serialFile) != 0 || nread != 1) {
 		error_out("Error: Unable to read serial number file");
 	    }
-	    if (serial == 4294967295) {
+	    if (serial == -1) {
 		serial = 21;
 	    }
 	    fclose(serialFile);
 	    ++serial;
 	    serialFile = fopen(filename,"w");
 	    if (serialFile == NULL) {
 	        error_out("ERROR: Unable to open serial number file for writing");
 	    }
@@ -1412,62 +1333,59 @@ string_to_ipaddress(char *string)
     *(ipaddress->data + j) = '\0';
     if (j != 4 && j != 8) {
 	error_out("ERROR: Improperly formated IP Address");
     }
     ipaddress->len = j;
     return ipaddress;
 }
 
+static int
+chr_to_hex(char c) {
+    if (isdigit(c)) {
+        return c - '0';
+    }
+    if (isxdigit(c)) {
+        return toupper(c) - 'A' + 10;
+    }
+    return -1;
+}
+
 static SECItem *
-string_to_binary(char  *string)
+string_to_binary(char *string)
 {
     SECItem            *rv;
-    int                high_digit;
-    int                low_digit;
 
     rv = (SECItem *) PORT_ZAlloc(sizeof(SECItem));
     if (rv == NULL) {
 	error_allocate();
     }
     rv->data = (unsigned char *) PORT_ZAlloc((PORT_Strlen(string))/3 + 2);
-    while (!isxdigit(*string)) {
+    rv->len = 0;
+    while (*string && !isxdigit(*string)) {
 	string++;
     }
-    rv->len = 0;
-    while (*string != '\0') {
-	if (isxdigit(*string)) {
-	    if (*string >= '0' && *string <= '9') {
-		high_digit = *string - '0';
-	    } else {
-		*string = toupper(*string);
-		high_digit = *string - 'A' + 10;
-	    }
-	    string++;
-	    if (*string >= '0' && *string <= '9') {
-		low_digit = *string - '0';
-	    } else {
-		*string = toupper(*string);
-		low_digit = *string - 'A' + 10;
-	    }
-	    (rv->len)++;
-	} else {
-	    if (*string == ':') {
-		string++;
-	    } else {
-		if (*string == ' ') {
-		    while (*string == ' ') {
-			string++;
-		    }
-		}
-		if (*string != '\0') {
-		    error_out("ERROR: Improperly formated binary encoding");
-		}
-	    }
-	} 
+    while (*string) {
+        int high, low;
+        high = chr_to_hex(*string++);
+        low = chr_to_hex(*string++);
+        if (high < 0 || low < 0) {
+            error_out("ERROR: Improperly formated binary encoding");
+        }
+	rv->data[(rv->len)++] = high << 4 | low;
+        if (*string != ':') {
+            break;
+        }
+        ++string;
+    }
+    while (*string == ' ') {
+       ++string;
+    }
+    if (*string) {
+        error_out("ERROR: Junk after binary encoding");
     }
 
     return rv;
 }
 
 static SECStatus
 MakeGeneralName(char             *name, 
 		CERTGeneralName  *genName,
--- a/cmd/certutil/certext.c
+++ b/cmd/certutil/certext.c
@@ -982,20 +982,23 @@ AddNameConstraints(void *extHandle)
         }
 
         (void) SEC_ASN1EncodeInteger(arena, &current->min, 0);
 
         if (!GetGeneralName(arena, &current->name, PR_TRUE)) {
             GEN_BREAK(SECFailure);
         }
 
-        PrintChoicesAndGetAnswer("Type of Name Constraint?\n"
+        if (PrintChoicesAndGetAnswer("Type of Name Constraint?\n"
             "\t1 - permitted\n\t2 - excluded\n\tAny"
             "other number to finish\n\tChoice",
-            buffer, sizeof(buffer));
+            buffer, sizeof(buffer)) != SECSuccess) {
+            GEN_BREAK(SECFailure);
+        }
+
         intValue = PORT_Atoi(buffer);
         switch (intValue) {
         case 1:
             if (constraints->permited == NULL) {
                 constraints->permited = last_permited = current;
             }
             last_permited->l.next = &(current->l);
             current->l.prev = &(last_permited->l);
@@ -1821,21 +1824,23 @@ AddInfoAccess(void *extHandle, PRBool ad
                     "Subject Information Access extension:\n");
                 intValue = caRepository;
             } else {
                 puts("Adding \"Time Stamping Services\" access method type for "
                     "Subject Information Access extension:\n");
                 intValue = timeStamping;
             }
         } else {
-            PrintChoicesAndGetAnswer("Enter access method type "
+            if (PrintChoicesAndGetAnswer("Enter access method type "
                 "for Authority Information Access extension:\n"
                 "\t1 - CA Issuers\n\t2 - OCSP\n\tAny"
                 "other number to finish\n\tChoice",
-                buffer, sizeof(buffer));
+                buffer, sizeof(buffer)) != SECSuccess) {
+                GEN_BREAK (SECFailure);
+            }
             intValue = PORT_Atoi(buffer);
         }
         if (addSIAExt) {
             switch (intValue) {
               case caRepository:
                   oid = SECOID_FindOIDByTag(SEC_OID_PKIX_CA_REPOSITORY);
                   break;
                   
--- a/cmd/certutil/certutil.c
+++ b/cmd/certutil/certutil.c
@@ -35,17 +35,17 @@
 #include "secoid.h"
 #include "certdb.h"
 #include "nss.h"
 #include "certutil.h"
 
 #define MIN_KEY_BITS		512
 /* MAX_KEY_BITS should agree with MAX_RSA_MODULUS in freebl */
 #define MAX_KEY_BITS		8192
-#define DEFAULT_KEY_BITS	1024
+#define DEFAULT_KEY_BITS	2048
 
 #define GEN_BREAK(e) rv=e; break;
 
 char *progName;
 
 static CERTCertificateRequest *
 GetCertRequest(const SECItem *reqDER)
 {
@@ -175,17 +175,17 @@ AddCert(PK11SlotInfo *slot, CERTCertDBHa
     CERT_DestroyCertificate (cert);
     PORT_Free(trust);
 
     return rv;
 }
 
 static SECStatus
 CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType,
-        SECOidTag hashAlgTag, CERTName *subject, char *phone, int ascii, 
+        SECOidTag hashAlgTag, CERTName *subject, const char *phone, int ascii,
 	const char *emailAddrs, const char *dnsNames,
         certutilExtnList extnList, const char *extGeneric,
         /*out*/ SECItem *result)
 {
     CERTSubjectPublicKeyInfo *spki;
     CERTCertificateRequest *cr;
     SECItem *encoding;
     SECOidTag signAlgTag;
@@ -265,17 +265,17 @@ CertReq(SECKEYPrivateKey *privk, SECKEYP
 	}
 
 	name = CERT_GetCommonName(subject);
 	if (!name) {
 	    name = PORT_Strdup("(not specified)");
 	}
 
 	if (!phone)
-	    phone = strdup("(not specified)");
+	    phone = "(not specified)";
 
 	email = CERT_GetCertEmailAddress(subject);
 	if (!email)
 	    email = PORT_Strdup("(not specified)");
 
 	org = CERT_GetOrgName(subject);
 	if (!org)
 	    org = PORT_Strdup("(not specified)");
@@ -318,16 +318,17 @@ CertReq(SECKEYPrivateKey *privk, SECKEYP
 		    PORT_Memcpy(result->data + headerLen, obuf, obufLen);
 		    PORT_Memcpy(result->data + headerLen + obufLen,
 				trailer, trailerLen);
 		}
 		PR_smprintf_free(trailer);
 	    }
 	    PR_smprintf_free(header);
 	}
+	PORT_Free(obuf);
     } else {
 	(void) SECITEM_CopyItem(NULL, result, &signedReq);
     }
 
     if (!result->data) {
 oom:    SECU_PrintError(progName, "out of memory");
 	PORT_SetError(SEC_ERROR_NO_MEMORY);
 	rv = SECFailure;
@@ -603,16 +604,37 @@ DeleteCert(CERTCertDBHandle *handle, cha
     rv = SEC_DeletePermCertificate(cert);
     CERT_DestroyCertificate(cert);
     if (rv) {
 	SECU_PrintError(progName, "unable to delete certificate");
     }
     return rv;
 }
 
+static SECStatus 
+RenameCert(CERTCertDBHandle *handle, char *name, char *newName)
+{
+    SECStatus rv;
+    CERTCertificate *cert;
+
+    cert = CERT_FindCertByNicknameOrEmailAddr(handle, name);
+    if (!cert) {
+	SECU_PrintError(progName, "could not find certificate named \"%s\"",
+			name);
+	return SECFailure;
+    }
+
+    rv = __PK11_SetCertificateNickname(cert, newName);
+    CERT_DestroyCertificate(cert);
+    if (rv) {
+	SECU_PrintError(progName, "unable to rename certificate");
+    }
+    return rv;
+}
+
 static SECStatus
 ValidateCert(CERTCertDBHandle *handle, char *name, char *date,
              char *certUsage, PRBool checkSig, PRBool logit,
              PRBool ascii, secuPWData *pwdata)
 {
     SECStatus rv;
     CERTCertificate *cert = NULL;
     PRTime timeBoundary;
@@ -966,29 +988,31 @@ ListModules(void)
 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] [--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", 
+    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"
+        "\t\t [-f pwfile] [-d certdir] [-P dbprefix] [-Z hashAlg]\n"
         "\t\t [-1 | --keyUsage [keyUsageKeyword,..]] [-2] [-3] [-4]\n"
         "\t\t [-5 | --nsCertType [nsCertTypeKeyword,...]]\n"
         "\t\t [-6 | --extKeyUsage [extKeyUsageKeyword,...]] [-7 emailAddrs]\n"
         "\t\t [-8 dns-names] [-a]\n",
 	progName);
     FPS "\t%s -D -n cert-name [-d certdir] [-P dbprefix]\n", progName);
-    FPS "\t%s -E -n cert-name -t trustargs [-d certdir] [-P dbprefix] [-a] [-i input]\n", 
+    FPS "\t%s --rename -n cert-name --new-n new-cert-name\n"
+        "\t\t [-d certdir] [-P dbprefix]\n", progName);
+    FPS "\t%s -E -n cert-name -t trustargs [-d certdir] [-P dbprefix] [-a] [-i input]\n",
 	progName);
     FPS "\t%s -F -n nickname [-d certdir] [-P dbprefix]\n", 
 	progName);
     FPS "\t%s -G -n key-name [-h token-name] [-k rsa] [-g key-size] [-y exp]\n" 
 	"\t\t [-f pwfile] [-z noisefile] [-d certdir] [-P dbprefix]\n", progName);
     FPS "\t%s -G [-h token-name] -k dsa [-q pqgfile -g key-size] [-f pwfile]\n"
 	"\t\t [-z noisefile] [-d certdir] [-P dbprefix]\n", progName);
 #ifndef NSS_DISABLE_ECC
@@ -1012,27 +1036,28 @@ PrintSyntax(char *progName)
     FPS "\t\t [-f targetPWfile] [-@ sourcePWFile]\n");
     FPS "\t%s -L [-n cert-name] [-h token-name] [--email email-address]\n",
 	progName);
     FPS "\t\t [-X] [-r] [-a] [--dump-ext-val OID] [-d certdir] [-P dbprefix]\n");
     FPS "\t%s -M -n cert-name -t trustargs [-d certdir] [-P dbprefix]\n",
 	progName);
     FPS "\t%s -O -n cert-name [-X] [-d certdir] [-a] [-P dbprefix]\n", progName);
     FPS "\t%s -R -s subj -o cert-request-file [-d certdir] [-P dbprefix] [-p phone] [-a]\n"
-	"\t\t [-7 emailAddrs] [-k key-type-or-id] [-h token-name] [-f pwfile] [-g key-size]\n",
+        "\t\t [-7 emailAddrs] [-k key-type-or-id] [-h token-name] [-f pwfile]\n"
+        "\t\t [-g key-size] [-Z hashAlg]\n",
 	progName);
     FPS "\t%s -V -n cert-name -u usage [-b time] [-e] [-a]\n"
 	"\t\t[-X] [-d certdir] [-P dbprefix]\n",
 	progName);
     FPS "Usage:  %s -W [-d certdir] [-f pwfile] [-@newpwfile]\n",
 	progName);
     FPS "\t%s -S -n cert-name -s subj [-c issuer-name | -x]  -t trustargs\n"
 	"\t\t [-k key-type-or-id] [-q key-params] [-h token-name] [-g key-size]\n"
         "\t\t [-m serial-number] [-w warp-months] [-v months-valid]\n"
-	"\t\t [-f pwfile] [-d certdir] [-P dbprefix]\n"
+        "\t\t [-f pwfile] [-d certdir] [-P dbprefix] [-Z hashAlg]\n"
         "\t\t [-p phone] [-1] [-2] [-3] [-4] [-5] [-6] [-7 emailAddrs]\n"
         "\t\t [-8 DNS-names]\n"
         "\t\t [--extAIA] [--extSIA] [--extCP] [--extPM] [--extPC] [--extIA]\n"
         "\t\t [--extSKID] [--extNC] [--extSAN type:name[,type:name]...]\n"
 	"\t\t [--extGeneric OID:critical-flag:filename[,OID:critical-flag:filename]...]\n", progName);
     FPS "\t%s -U [-X] [-d certdir] [-P dbprefix]\n", progName);
     exit(1);
 }
@@ -1133,16 +1158,21 @@ static void luC(enum usage_level ul, con
         "   -v months-valid");
     FPS "%-20s Specify the password file\n",
         "   -f pwfile");
     FPS "%-20s Cert database directory (default is ~/.netscape)\n",
         "   -d certdir");
     FPS "%-20s Cert & Key database prefix\n",
         "   -P dbprefix");
     FPS "%-20s \n"
+              "%-20s Specify the hash algorithm to use. Possible keywords:\n"
+              "%-20s \"MD2\", \"MD4\", \"MD5\", \"SHA1\", \"SHA224\",\n"
+              "%-20s \"SHA256\", \"SHA384\", \"SHA512\"\n",
+        "   -Z hashAlg", "", "", "");
+    FPS "%-20s \n"
               "%-20s Create key usage extension. Possible keywords:\n"
               "%-20s \"digitalSignature\", \"nonRepudiation\", \"keyEncipherment\",\n"
               "%-20s \"dataEncipherment\", \"keyAgreement\", \"certSigning\",\n"
               "%-20s \"crlSigning\", \"critical\"\n",
         "   -1 | --keyUsage keyword,keyword,...", "", "", "", "");
     FPS "%-20s Create basic constraint extension\n",
         "   -2 ");
     FPS "%-20s Create authority key ID extension\n",
@@ -1472,16 +1502,21 @@ static void luR(enum usage_level ul, con
     FPS "%-20s Specify the password file\n",
         "   -f pwfile");
     FPS "%-20s Key database directory (default is ~/.netscape)\n",
         "   -d keydir");
     FPS "%-20s Cert & Key database prefix\n",
         "   -P dbprefix");
     FPS "%-20s Specify the contact phone number (\"123-456-7890\")\n",
         "   -p phone");
+    FPS "%-20s \n"
+              "%-20s Specify the hash algorithm to use. Possible keywords:\n"
+              "%-20s \"MD2\", \"MD4\", \"MD5\", \"SHA1\", \"SHA224\",\n"
+              "%-20s \"SHA256\", \"SHA384\", \"SHA512\"\n",
+        "   -Z hashAlg", "", "", "");
     FPS "%-20s Output the cert request in ASCII (RFC1113); default is binary\n",
         "   -a");
     FPS "%-20s \n",
         "   See -S for available extension options");
     FPS "%-20s \n",
         "   See -G for available key flag options");
     FPS "\n");
 }
@@ -1533,16 +1568,35 @@ static void luW(enum usage_level ul, con
         "   -d certdir");
     FPS "%-20s Specify a file with the current password\n",
         "   -f pwfile");
     FPS "%-20s Specify a file with the new password in two lines\n",
         "   -@ newpwfile");
     FPS "\n");
 }
 
+static void luRename(enum usage_level ul, const char *command)
+{
+    int is_my_command = (command && 0 == strcmp(command, "rename"));
+    if (ul == usage_all || !command || is_my_command)
+    FPS "%-15s Change the database nickname of a certificate\n",
+        "--rename");
+    if (ul == usage_selected && !is_my_command)
+        return;
+    FPS "%-20s The old nickname of the cert to rename\n",
+        "   -n cert-name");
+    FPS "%-20s The new nickname of the cert to rename\n",
+        "   --new-n new-name");
+    FPS "%-20s Cert database directory (default is ~/.netscape)\n",
+        "   -d certdir");
+    FPS "%-20s Cert & Key database prefix\n",
+        "   -P dbprefix");
+    FPS "\n");
+}
+
 static void luUpgradeMerge(enum usage_level ul, const char *command)
 {
     int is_my_command = (command && 0 == strcmp(command, "upgrade-merge"));
     if (ul == usage_all || !command || is_my_command)
     FPS "%-15s Upgrade an old database and merge it into a new one\n",
         "--upgrade-merge");
     if (ul == usage_selected && !is_my_command)
         return;
@@ -1633,16 +1687,21 @@ static void luS(enum usage_level ul, con
     FPS "%-20s Specify the password file\n",
         "   -f pwfile");
     FPS "%-20s Cert database directory (default is ~/.netscape)\n",
         "   -d certdir");
     FPS "%-20s Cert & Key database prefix\n",
         "   -P dbprefix");
     FPS "%-20s Specify the contact phone number (\"123-456-7890\")\n",
         "   -p phone");
+    FPS "%-20s \n"
+              "%-20s Specify the hash algorithm to use. Possible keywords:\n"
+              "%-20s \"MD2\", \"MD4\", \"MD5\", \"SHA1\", \"SHA224\",\n"
+              "%-20s \"SHA256\", \"SHA384\", \"SHA512\"\n",
+        "   -Z hashAlg", "", "", "");
     FPS "%-20s Create key usage extension\n",
         "   -1 ");
     FPS "%-20s Create basic constraint extension\n",
         "   -2 ");
     FPS "%-20s Create authority key ID extension\n",
         "   -3 ");
     FPS "%-20s Create crl distribution point extension\n",
         "   -4 ");
@@ -1690,16 +1749,17 @@ static void luS(enum usage_level ul, con
 static void LongUsage(char *progName, enum usage_level ul, const char *command)
 {
     luA(ul, command);
     luB(ul, command);
     luE(ul, command);
     luC(ul, command);
     luG(ul, command);
     luD(ul, command);
+    luRename(ul, command);
     luF(ul, command);
     luU(ul, command);
     luK(ul, command);
     luL(ul, command);
     luM(ul, command);
     luN(ul, command);
     luT(ul, command);
     luO(ul, command);
@@ -2189,16 +2249,17 @@ enum {
     cmd_TokenReset,
     cmd_ListModules,
     cmd_CheckCertValidity,
     cmd_ChangePassword,
     cmd_Version,
     cmd_Batch,
     cmd_Merge,
     cmd_UpgradeMerge, /* test only */
+    cmd_Rename,
     max_cmd
 };
 
 /*  Certutil options */
 enum certutilOpts {
     opt_SSOPass = 0,
     opt_AddKeyUsageExt,
     opt_AddBasicConstraintExt,
@@ -2257,16 +2318,17 @@ enum certutilOpts {
     opt_KeyOpFlagsOn,
     opt_KeyOpFlagsOff,
     opt_KeyAttrFlags,
     opt_EmptyPassword,
     opt_CertVersion,
     opt_AddSubjectAltNameExt,
     opt_DumpExtensionValue,
     opt_GenericExtensions,
+    opt_NewNickname,
     opt_Help
 };
 
 static const
 secuCommandFlag commands_init[] =
 {
 	{ /* cmd_AddCert             */  'A', PR_FALSE, 0, PR_FALSE },
 	{ /* cmd_CreateNewCert       */  'C', PR_FALSE, 0, PR_FALSE },
@@ -2287,17 +2349,19 @@ secuCommandFlag commands_init[] =
 	{ /* cmd_TokenReset          */  'T', PR_FALSE, 0, PR_FALSE },
 	{ /* cmd_ListModules         */  'U', PR_FALSE, 0, PR_FALSE },
 	{ /* cmd_CheckCertValidity   */  'V', PR_FALSE, 0, PR_FALSE },
 	{ /* cmd_ChangePassword      */  'W', PR_FALSE, 0, PR_FALSE },
 	{ /* cmd_Version             */  'Y', PR_FALSE, 0, PR_FALSE },
 	{ /* cmd_Batch               */  'B', PR_FALSE, 0, PR_FALSE },
 	{ /* cmd_Merge               */   0,  PR_FALSE, 0, PR_FALSE, "merge" },
 	{ /* cmd_UpgradeMerge        */   0,  PR_FALSE, 0, PR_FALSE, 
-                                                   "upgrade-merge" }
+                                                   "upgrade-merge" },
+	{ /* cmd_Rename              */   0,  PR_FALSE, 0, PR_FALSE, 
+                                                   "rename" }
 };
 #define NUM_COMMANDS ((sizeof commands_init) / (sizeof commands_init[0]))
  
 static const 
 secuCommandFlag options_init[] =
 {
 	{ /* opt_SSOPass             */  '0', PR_TRUE,  0, PR_FALSE },
 	{ /* opt_AddKeyUsageExt      */  '1', PR_FALSE, 0, PR_FALSE },
@@ -2373,16 +2437,18 @@ secuCommandFlag options_init[] =
                                                    "empty-password"},
         { /* opt_CertVersion         */  0,   PR_TRUE, 0, PR_FALSE,
                                                    "certVersion"},
 	{ /* opt_AddSubjectAltExt    */  0,   PR_TRUE,  0, PR_FALSE, "extSAN"},
 	{ /* opt_DumpExtensionValue  */  0,   PR_TRUE, 0, PR_FALSE, 
                                                    "dump-ext-val"},
 	{ /* opt_GenericExtensions   */  0,   PR_TRUE, 0, PR_FALSE, 
                                                    "extGeneric"},
+	{ /* opt_NewNickname         */  0,   PR_TRUE, 0, PR_FALSE, 
+                                                   "new-n"},
 };
 #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, 
@@ -2398,24 +2464,25 @@ certutil_main(int argc, char **argv, PRB
 {
     CERTCertDBHandle *certHandle;
     PK11SlotInfo *slot = NULL;
     CERTName *  subject         = 0;
     PRFileDesc *inFile          = PR_STDIN;
     PRFileDesc *outFile         = PR_STDOUT;
     SECItem     certReqDER      = { siBuffer, NULL, 0 };
     SECItem     certDER         = { siBuffer, NULL, 0 };
-    char *      slotname        = "internal";
-    char *      certPrefix      = "";
+    const char *slotname        = "internal";
+    const char *certPrefix      = "";
     char *      sourceDir       = "";
-    char *      srcCertPrefix   = "";
+    const char *srcCertPrefix   = "";
     char *      upgradeID        = "";
     char *      upgradeTokenName     = "";
     KeyType     keytype         = rsaKey;
     char *      name            = NULL;
+    char *      newName         = NULL;
     char *      email            = NULL;
     char *      keysource       = NULL;
     SECOidTag   hashAlgTag      = SEC_OID_UNKNOWN;
     int	        keysize	        = DEFAULT_KEY_BITS;
     int         publicExponent  = 0x010001;
     int         certVersion     = SEC_CERTIFICATE_VERSION_3;
     unsigned int serialNumber   = 0;
     int         warpmonths      = 0;
@@ -2512,17 +2579,17 @@ certutil_main(int argc, char **argv, PRB
 
     }
 
     /*  -h specify token name  */
     if (certutil.options[opt_TokenName].activated) {
 	if (PL_strcmp(certutil.options[opt_TokenName].arg, "all") == 0)
 	    slotname = NULL;
 	else
-	    slotname = PL_strdup(certutil.options[opt_TokenName].arg);
+	    slotname = certutil.options[opt_TokenName].arg;
     }
 
     /*  -Z hash type  */
     if (certutil.options[opt_Hash].activated) {
 	char * arg = certutil.options[opt_Hash].arg;
         hashAlgTag = SECU_StringToSignatureAlgTag(arg);
         if (hashAlgTag == SEC_OID_UNKNOWN) {
 	    PR_fprintf(PR_STDERR, "%s -Z:  %s is not a recognized type.\n",
@@ -2572,26 +2639,26 @@ certutil_main(int argc, char **argv, PRB
 	    return 255;
 	}
 	serialNumber = sn;
     }
 
     /*  -P certdb name prefix */
     if (certutil.options[opt_DBPrefix].activated) {
         if (certutil.options[opt_DBPrefix].arg) {
-            certPrefix = strdup(certutil.options[opt_DBPrefix].arg);
+            certPrefix = certutil.options[opt_DBPrefix].arg;
         } else {
             Usage(progName);
         }
     }
 
     /*  --source-prefix certdb name prefix */
     if (certutil.options[opt_SourcePrefix].activated) {
         if (certutil.options[opt_SourcePrefix].arg) {
-            srcCertPrefix = strdup(certutil.options[opt_SourcePrefix].arg);
+            srcCertPrefix = certutil.options[opt_SourcePrefix].arg;
         } else {
             Usage(progName);
         }
     }
 
     /*  -q PQG file or curve name */
     if (certutil.options[opt_PQGFile].activated) {
 #ifndef NSS_DISABLE_ECC
@@ -2764,16 +2831,29 @@ certutil_main(int argc, char **argv, PRB
     if (certutil.commands[cmd_CheckCertValidity].activated &&
         !certutil.options[opt_Usage].activated) {
 	PR_fprintf(PR_STDERR, 
 	           "%s -V: specify a usage to validate the cert for (-u).\n",
 	           progName);
 	return 255;
     }
 
+    /* Rename needs an old and a new nickname */
+    if (certutil.commands[cmd_Rename].activated &&
+        !(certutil.options[opt_Nickname].activated &&
+          certutil.options[opt_NewNickname].activated)) {
+
+	PR_fprintf(PR_STDERR, 
+	           "%s --rename: specify an old nickname (-n) and\n"
+                   "   a new nickname (--new-n).\n",
+	           progName);
+	return 255;
+    }
+
+
     /* Upgrade/Merge needs a source database and a upgrade id. */
     if (certutil.commands[cmd_UpgradeMerge].activated &&
         !(certutil.options[opt_SourceDir].activated &&
           certutil.options[opt_UpgradeID].activated)) {
 
 	PR_fprintf(PR_STDERR, 
 	           "%s --upgrade-merge: specify an upgrade database directory "
 		   "(--source-dir) and\n"
@@ -2845,16 +2925,17 @@ certutil_main(int argc, char **argv, PRB
 	               "%s:  unable to open \"%s\" for writing (%ld, %ld).\n",
 	               progName, certutil.options[opt_OutputFile].arg,
 	               PR_GetError(), PR_GetOSError());
 	    return 255;
 	}
     }
 
     name = SECU_GetOptionArg(&certutil, opt_Nickname);
+    newName = SECU_GetOptionArg(&certutil, opt_NewNickname);
     email = SECU_GetOptionArg(&certutil, opt_Emailaddress);
 
     PK11_SetPasswordFunc(SECU_GetModulePassword);
 
     if (PR_TRUE == initialize) {
         /*  Initialize NSPR and NSS.  */
         PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
 	if (!certutil.commands[cmd_UpgradeMerge].activated) {
@@ -3083,16 +3164,21 @@ merge_fail:
 	rv = ListModules();
 	goto shutdown;
     }
     /*  Delete cert (-D)  */
     if (certutil.commands[cmd_DeleteCert].activated) {
 	rv = DeleteCert(certHandle, name);
 	goto shutdown;
     }
+    /*  Rename cert (--rename)  */
+    if (certutil.commands[cmd_Rename].activated) {
+	rv = RenameCert(certHandle, name, newName);
+	goto shutdown;
+    }
     /*  Delete key (-F)  */
     if (certutil.commands[cmd_DeleteKey].activated) {
 	rv = DeleteKey(name, &pwdata);
 	goto shutdown;
     }
     /*  Modify trust attribute for cert (-M)  */
     if (certutil.commands[cmd_ModifyCertTrust].activated) {
 	rv = ChangeTrustAttributes(certHandle, slot, name, 
--- a/cmd/certutil/keystuff.c
+++ b/cmd/certutil/keystuff.c
@@ -128,74 +128,102 @@ UpdateRNG(void)
     tio.c_cc[VMIN] = orig_cc_min;
     tio.c_cc[VTIME] = orig_cc_time;
     tcsetattr(fd, TCSAFLUSH, &tio);
 #endif
     return rv;
 }
 
 static const unsigned char P[] = { 0, 
-       0x98, 0xef, 0x3a, 0xae, 0x70, 0x98, 0x9b, 0x44, 
-       0xdb, 0x35, 0x86, 0xc1, 0xb6, 0xc2, 0x47, 0x7c, 
-       0xb4, 0xff, 0x99, 0xe8, 0xae, 0x44, 0xf2, 0xeb, 
-       0xc3, 0xbe, 0x23, 0x0f, 0x65, 0xd0, 0x4c, 0x04, 
-       0x82, 0x90, 0xa7, 0x9d, 0x4a, 0xc8, 0x93, 0x7f, 
-       0x41, 0xdf, 0xf8, 0x80, 0x6b, 0x0b, 0x68, 0x7f, 
-       0xaf, 0xe4, 0xa8, 0xb5, 0xb2, 0x99, 0xc3, 0x69, 
-       0xfb, 0x3f, 0xe7, 0x1b, 0xd0, 0x0f, 0xa9, 0x7a, 
-       0x4a, 0x04, 0xbf, 0x50, 0x9e, 0x22, 0x33, 0xb8, 
-       0x89, 0x53, 0x24, 0x10, 0xf9, 0x68, 0x77, 0xad, 
-       0xaf, 0x10, 0x68, 0xb8, 0xd3, 0x68, 0x5d, 0xa3, 
-       0xc3, 0xeb, 0x72, 0x3b, 0xa0, 0x0b, 0x73, 0x65, 
-       0xc5, 0xd1, 0xfa, 0x8c, 0xc0, 0x7d, 0xaa, 0x52, 
-       0x29, 0x34, 0x44, 0x01, 0xbf, 0x12, 0x25, 0xfe, 
-       0x18, 0x0a, 0xc8, 0x3f, 0xc1, 0x60, 0x48, 0xdb, 
-       0xad, 0x93, 0xb6, 0x61, 0x67, 0xd7, 0xa8, 0x2d };
+        0xc6, 0x2a, 0x47, 0x73, 0xea, 0x78, 0xfa, 0x65,
+        0x47, 0x69, 0x39, 0x10, 0x08, 0x55, 0x6a, 0xdd,
+        0xbf, 0x77, 0xe1, 0x9a, 0x69, 0x73, 0xba, 0x66,
+        0x37, 0x08, 0x93, 0x9e, 0xdb, 0x5d, 0x01, 0x08,
+        0xb8, 0x3a, 0x73, 0xe9, 0x85, 0x5f, 0xa7, 0x2b,
+        0x63, 0x7f, 0xd0, 0xc6, 0x4c, 0xdc, 0xfc, 0x8b,
+        0xa6, 0x03, 0xc9, 0x9c, 0x80, 0x5e, 0xec, 0xc6,
+        0x21, 0x23, 0xf7, 0x8e, 0xa4, 0x7b, 0x77, 0x83,
+        0x02, 0x44, 0xf8, 0x05, 0xd7, 0x36, 0x52, 0x13,
+        0x57, 0x78, 0x97, 0xf3, 0x7b, 0xcf, 0x1f, 0xc9,
+        0x2a, 0xa4, 0x71, 0x9d, 0xa8, 0xd8, 0x5d, 0xc5,
+        0x3b, 0x64, 0x3a, 0x72, 0x60, 0x62, 0xb0, 0xb8,
+        0xf3, 0xb1, 0xe7, 0xb9, 0x76, 0xdf, 0x74, 0xbe,
+        0x87, 0x6a, 0xd2, 0xf1, 0xa9, 0x44, 0x8b, 0x63,
+        0x76, 0x4f, 0x5d, 0x21, 0x63, 0xb5, 0x4f, 0x3c,
+        0x7b, 0x61, 0xb2, 0xf3, 0xea, 0xc5, 0xd8, 0xef,
+        0x30, 0x50, 0x59, 0x33, 0x61, 0xc0, 0xf3, 0x6e,
+        0x21, 0xcf, 0x15, 0x35, 0x4a, 0x87, 0x2b, 0xc3,
+        0xf6, 0x5a, 0x1f, 0x24, 0x22, 0xc5, 0xeb, 0x47,
+        0x34, 0x4a, 0x1b, 0xb5, 0x2e, 0x71, 0x52, 0x8f,
+        0x2d, 0x7d, 0xa9, 0x96, 0x8a, 0x7c, 0x61, 0xdb,
+        0xc0, 0xdc, 0xf1, 0xca, 0x28, 0x69, 0x1c, 0x97,
+        0xad, 0xea, 0x0d, 0x9e, 0x02, 0xe6, 0xe5, 0x7d,
+        0xad, 0xe0, 0x42, 0x91, 0x4d, 0xfa, 0xe2, 0x81,
+        0x16, 0x2b, 0xc2, 0x96, 0x3b, 0x32, 0x8c, 0x20,
+        0x69, 0x8b, 0x5b, 0x17, 0x3c, 0xf9, 0x13, 0x6c,
+        0x98, 0x27, 0x1c, 0xca, 0xcf, 0x33, 0xaa, 0x93,
+        0x21, 0xaf, 0x17, 0x6e, 0x5e, 0x00, 0x37, 0xd9,
+        0x34, 0x8a, 0x47, 0xd2, 0x1c, 0x67, 0x32, 0x60,
+        0xb6, 0xc7, 0xb0, 0xfd, 0x32, 0x90, 0x93, 0x32,
+        0xaa, 0x11, 0xba, 0x23, 0x19, 0x39, 0x6a, 0x42,
+        0x7c, 0x1f, 0xb7, 0x28, 0xdb, 0x64, 0xad, 0xd9 };
 static const unsigned char Q[] = { 0,
-       0xb5, 0xb0, 0x84, 0x8b, 0x44, 0x29, 0xf6, 0x33, 
-       0x59, 0xa1, 0x3c, 0xbe, 0xd2, 0x7f, 0x35, 0xa1, 
-       0x76, 0x27, 0x03, 0x81                         };
+        0xe6, 0xa3, 0xc9, 0xc6, 0x51, 0x92, 0x8b, 0xb3,
+        0x98, 0x8f, 0x97, 0xb8, 0x31, 0x0d, 0x4a, 0x03,
+        0x1e, 0xba, 0x4e, 0xe6, 0xc8, 0x90, 0x98, 0x1d,
+        0x3a, 0x95, 0xf4, 0xf1 };
 static const unsigned char G[] = { 
-       0x04, 0x0e, 0x83, 0x69, 0xf1, 0xcd, 0x7d, 0xe5, 
-       0x0c, 0x78, 0x93, 0xd6, 0x49, 0x6f, 0x00, 0x04, 
-       0x4e, 0x0e, 0x6c, 0x37, 0xaa, 0x38, 0x22, 0x47, 
-       0xd2, 0x58, 0xec, 0x83, 0x12, 0x95, 0xf9, 0x9c, 
-       0xf1, 0xf4, 0x27, 0xff, 0xd7, 0x99, 0x57, 0x35, 
-       0xc6, 0x64, 0x4c, 0xc0, 0x47, 0x12, 0x31, 0x50, 
-       0x82, 0x3c, 0x2a, 0x07, 0x03, 0x01, 0xef, 0x30, 
-       0x09, 0x89, 0x82, 0x41, 0x76, 0x71, 0xda, 0x9e, 
-       0x57, 0x8b, 0x76, 0x38, 0x37, 0x5f, 0xa5, 0xcd, 
-       0x32, 0x84, 0x45, 0x8d, 0x4c, 0x17, 0x54, 0x2b, 
-       0x5d, 0xc2, 0x6b, 0xba, 0x3e, 0xa0, 0x7b, 0x95, 
-       0xd7, 0x00, 0x42, 0xf7, 0x08, 0xb8, 0x83, 0x87, 
-       0x60, 0xe1, 0xe5, 0xf4, 0x1a, 0x54, 0xc2, 0x20, 
-       0xda, 0x38, 0x3a, 0xd1, 0xb6, 0x10, 0xf4, 0xcb, 
-       0x35, 0xda, 0x97, 0x92, 0x87, 0xd6, 0xa5, 0x37, 
-       0x62, 0xb4, 0x93, 0x4a, 0x15, 0x21, 0xa5, 0x10 };
+        0x70, 0x32, 0x58, 0x5d, 0xb3, 0xbf, 0xc3, 0x62,
+        0x63, 0x0b, 0xf8, 0xa5, 0xe1, 0xed, 0xeb, 0x79,
+        0xac, 0x18, 0x41, 0x64, 0xb3, 0xda, 0x4c, 0xa7,
+        0x92, 0x63, 0xb1, 0x33, 0x7c, 0xcb, 0x43, 0xdc,
+        0x1f, 0x38, 0x63, 0x5e, 0x0e, 0x6d, 0x45, 0xd1,
+        0xc9, 0x67, 0xf3, 0xcf, 0x3d, 0x2d, 0x16, 0x4e,
+        0x92, 0x16, 0x06, 0x59, 0x29, 0x89, 0x6f, 0x54,
+        0xff, 0xc5, 0x71, 0xc8, 0x3a, 0x95, 0x84, 0xb6,
+        0x7e, 0x7b, 0x1e, 0x8b, 0x47, 0x9d, 0x7a, 0x3a,
+        0x36, 0x9b, 0x70, 0x2f, 0xd1, 0xbd, 0xef, 0xe8,
+        0x3a, 0x41, 0xd4, 0xf3, 0x1f, 0x81, 0xc7, 0x1f,
+        0x96, 0x7c, 0x30, 0xab, 0xf4, 0x7a, 0xac, 0x93,
+        0xed, 0x6f, 0x67, 0xb0, 0xc9, 0x5b, 0xf3, 0x83,
+        0x9d, 0xa0, 0xd7, 0xb9, 0x01, 0xed, 0x28, 0xae,
+        0x1c, 0x6e, 0x2e, 0x48, 0xac, 0x9f, 0x7d, 0xf3,
+        0x00, 0x48, 0xee, 0x0e, 0xfb, 0x7e, 0x5e, 0xcb,
+        0xf5, 0x39, 0xd8, 0x92, 0x90, 0x61, 0x2d, 0x1e,
+        0x3c, 0xd3, 0x55, 0x0d, 0x34, 0xd1, 0x81, 0xc4,
+        0x89, 0xea, 0x94, 0x2b, 0x56, 0x33, 0x73, 0x58,
+        0x48, 0xbf, 0x23, 0x72, 0x19, 0x5f, 0x19, 0xac,
+        0xff, 0x09, 0xc8, 0xcd, 0xab, 0x71, 0xef, 0x9e,
+        0x20, 0xfd, 0xe3, 0xb8, 0x27, 0x9e, 0x65, 0xb1,
+        0x85, 0xcd, 0x88, 0xfe, 0xd4, 0xd7, 0x64, 0x4d,
+        0xe1, 0xe8, 0xa6, 0xe5, 0x96, 0xc8, 0x5d, 0x9c,
+        0xc6, 0x70, 0x6b, 0xba, 0x77, 0x4e, 0x90, 0x4a,
+        0xb0, 0x96, 0xc5, 0xa0, 0x9e, 0x2c, 0x01, 0x03,
+        0xbe, 0xbd, 0x71, 0xba, 0x0a, 0x6f, 0x9f, 0xe5,
+        0xdb, 0x04, 0x08, 0xf2, 0x9e, 0x0f, 0x1b, 0xac,
+        0xcd, 0xbb, 0x65, 0x12, 0xcf, 0x77, 0xc9, 0x7d,
+        0xbe, 0x94, 0x4b, 0x9c, 0x5b, 0xde, 0x0d, 0xfa,
+        0x57, 0xdd, 0x77, 0x32, 0xf0, 0x5b, 0x34, 0xfd,
+        0x19, 0x95, 0x33, 0x60, 0x87, 0xe2, 0xa2, 0xf4 };
 
-/*  h:
- *      4a:76:30:89:eb:e1:81:7c:99:0b:39:7f:95:4a:65:72:
- *      c6:b4:05:92:48:6c:3c:b2:7e:e7:39:f3:92:7d:c1:3f:
- *      bf:e1:fd:b3:4a:46:3e:ce:29:80:e3:d6:f4:59:c6:92:
- *      16:2b:0e:d7:d6:bb:ef:94:36:31:c2:66:46:c5:4a:77:
- *      aa:95:84:ef:99:7e:e3:9c:d9:a0:32:42:09:b6:4e:d0:
- *      b3:c8:5e:06:df:a1:ac:4d:2d:f9:08:c2:cb:4b:a4:42:
- *      db:8a:5b:de:25:6e:2b:5b:ca:00:75:2c:57:00:18:aa:
- *      68:59:a1:94:03:07:94:78:38:bc:f8:7c:1e:1c:a3:2e
- *  SEED:
- *      b5:44:66:c9:0f:f1:ca:1c:95:45:ce:90:74:89:14:f2:
- *      13:3e:23:5a:b0:6a:bf:86:ad:cb:a0:7d:ce:3b:c8:16:
- *      7f:2d:a2:1a:cb:33:7d:c1:e7:d7:07:aa:1b:a2:d7:89:
- *      f5:a4:db:f7:8b:50:00:cd:b4:7d:25:81:3f:f8:a8:dd:
- *      6c:46:e5:77:b5:60:7e:75:79:b8:99:57:c1:c4:f3:f7:
- *      17:ca:43:00:b8:33:b6:06:8f:4d:91:ed:23:a5:66:1b:
- *      ef:14:d7:bc:21:2b:82:d8:ab:fa:fd:a7:c3:4d:bf:52:
- *      af:8e:57:59:61:1a:4e:65:c6:90:d6:a6:ff:0b:15:b1
- *  g:       1024
- *  counter: 1003
+
+/* P, Q, G have been generated using the NSS makepqg utility:
+ *         makepqg -l 2048 -g 224 -r
+ * (see also: bug 1170322)
+ *
+ *   h: 1 (0x1)
+ *   SEED:
+ *       d2:0b:c5:63:1b:af:dc:36:b7:7c:b9:3e:36:01:a0:8f:
+ *       0e:be:d0:38:e4:78:d5:3c:7c:9e:a9:9a:d2:0b:c5:63:
+ *       1b:af:dc:36:b7:7c:b9:3e:36:01:a0:8f:0e:be:d0:38:
+ *       e4:78:d5:3c:7c:9e:c7:70:d2:0b:c5:63:1b:af:dc:36:
+ *       b7:7c:b9:3e:36:01:a0:8f:0e:be:d0:38:e4:78:d5:3c:
+ *       7c:9e:aa:3e
+ *   g:       672
+ *   counter: 0
  */
 
 static const SECKEYPQGParams default_pqg_params = {
     NULL,
     { 0, (unsigned char *)P, sizeof(P) },
     { 0, (unsigned char *)Q, sizeof(Q) },
     { 0, (unsigned char *)G, sizeof(G) }
 };
--- a/cmd/checkcert/checkcert.c
+++ b/cmd/checkcert/checkcert.c
@@ -117,30 +117,27 @@ void checkName(CERTName *n, char *fieldN
 static
 SECStatus
 OurVerifyData(unsigned char *buf, int len, SECKEYPublicKey *key,
 	      SECItem *sig, SECAlgorithmID *sigAlgorithm)
 {
     SECStatus rv;
     VFYContext *cx;
     SECOidData *sigAlgOid, *oiddata;
-    SECOidTag sigAlgTag;
     SECOidTag hashAlgTag;
     int showDigestOid=0;
 
     cx = VFY_CreateContextWithAlgorithmID(key, sig, sigAlgorithm, &hashAlgTag, 
                                           NULL);
     if (cx == NULL)
 	return SECFailure;
 
     sigAlgOid = SECOID_FindOID(&sigAlgorithm->algorithm);
     if (sigAlgOid == 0)
 	return SECFailure;
-    sigAlgTag = sigAlgOid->offset;
-
 
     if (showDigestOid) {
 	oiddata = SECOID_FindOIDByTag(hashAlgTag);
 	if ( oiddata ) {
 	    printf("PROBLEM: (cont) Digest OID is %s\n", oiddata->desc);
 	} else {
 	    SECU_PrintAsHex(stdout,
 			    &oiddata->oid, "PROBLEM: UNKNOWN OID", 0);
@@ -215,40 +212,39 @@ CERTCertificate *createEmptyCertificate(
     if (c) {
 	c->referenceCount = 1;
 	c->arena = arena;
     } else {
 	PORT_FreeArena(arena,PR_TRUE);
     }
 
     return c;
-}    
-
-
+}
 
 
 int main(int argc, char **argv)
 {
-    int rv, verbose=0, force=0;
+    int verbose=0, force=0;
     int ascii=0, issuerAscii=0;
     char *progName=0;
     PRFileDesc *inFile=0, *issuerCertFile=0;
     SECItem derCert, derIssuerCert;
     PLArenaPool *arena=0;
     CERTSignedData *signedData=0;
     CERTCertificate *cert=0, *issuerCert=0;
     SECKEYPublicKey *rsapubkey=0;
     SECAlgorithmID md5WithRSAEncryption, md2WithRSAEncryption;
     SECAlgorithmID sha1WithRSAEncryption, rsaEncryption;
     SECItem spk;
     int selfSigned=0;
     int invalid=0;
     char *inFileName = NULL, *issuerCertFileName = NULL;
     PLOptState *optstate;
     PLOptStatus status;
+    SECStatus rv;
 
     PORT_Memset(&md5WithRSAEncryption, 0, sizeof(md5WithRSAEncryption));
     PORT_Memset(&md2WithRSAEncryption, 0, sizeof(md2WithRSAEncryption));
     PORT_Memset(&sha1WithRSAEncryption, 0, sizeof(sha1WithRSAEncryption));
     PORT_Memset(&rsaEncryption, 0, sizeof(rsaEncryption));
 
     progName = strrchr(argv[0], '/');
     progName = progName ? progName+1 : argv[0];
@@ -384,43 +380,63 @@ int main(int argc, char **argv)
 
 
     if (verbose) {
 	printf("Decoded ok as an X509 certificate.\n");
     }
 
     SECU_RegisterDynamicOids();
     rv = SECU_PrintSignedData(stdout, &derCert, "Certificate", 0,
-			      SECU_PrintCertificate);
+			      (SECU_PPFunc)SECU_PrintCertificate);
 
     if (rv) {
 	fprintf(stderr, "%s: Unable to pretty print cert. Error: %d\n",
 		progName, PORT_GetError());
 	if (!force) {
 	    exit(1);
 	}
     }
 
 
     /* Do various checks on the cert */
 
     printf("\n");
 
     /* Check algorithms */
-    SECOID_SetAlgorithmID(arena, &md5WithRSAEncryption,
+    rv = SECOID_SetAlgorithmID(arena, &md5WithRSAEncryption,
 		       SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION, NULL);
+    if (rv) {
+	fprintf(stderr, "%s: failed to set algorithm ID for SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION.\n",
+                progName);
+	exit(1);
+    }
 
-    SECOID_SetAlgorithmID(arena, &md2WithRSAEncryption,
+    rv = SECOID_SetAlgorithmID(arena, &md2WithRSAEncryption,
 		       SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION, NULL);
+    if (rv) {
+	fprintf(stderr, "%s: failed to set algorithm ID for SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION.\n",
+                progName);
+	exit(1);
+    }
 
-    SECOID_SetAlgorithmID(arena, &sha1WithRSAEncryption,
+    rv = SECOID_SetAlgorithmID(arena, &sha1WithRSAEncryption,
 		       SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION, NULL);
+    if (rv) {
+	fprintf(stderr, "%s: failed to set algorithm ID for SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION.\n",
+                progName);
+	exit(1);
+    }
 
-    SECOID_SetAlgorithmID(arena, &rsaEncryption,
+    rv = SECOID_SetAlgorithmID(arena, &rsaEncryption,
 		       SEC_OID_PKCS1_RSA_ENCRYPTION, NULL);
+    if (rv) {
+	fprintf(stderr, "%s: failed to set algorithm ID for SEC_OID_PKCS1_RSA_ENCRYPTION.\n",
+                progName);
+	exit(1);
+    }
 
     {
 	int isMD5RSA = (SECOID_CompareAlgorithmID(&cert->signature,
 					       &md5WithRSAEncryption) == 0);
 	int isMD2RSA = (SECOID_CompareAlgorithmID(&cert->signature,
 					       &md2WithRSAEncryption) == 0);
 	int isSHA1RSA = (SECOID_CompareAlgorithmID(&cert->signature,
 					       &sha1WithRSAEncryption) == 0);
--- a/cmd/crlutil/crlgen.c
+++ b/cmd/crlutil/crlgen.c
@@ -540,17 +540,17 @@ crlgen_AddCrlNumber(CRLGENGeneratorData 
 /* Creates Cert Revocation Reason code extension. Encodes it and
  * returns as SECItem structure */
 static SECItem*
 crlgen_CreateReasonCode(PLArenaPool *arena, const char **dataArr,
                         int *extCode)
 {
     SECItem *encodedItem;
     void *dummy;
-    void *mark;
+    void *mark = NULL;
     int code = 0;
 
     PORT_Assert(arena && dataArr);
     if (!arena || !dataArr) {
         goto loser;
     } 
 
     mark = PORT_ArenaMark(arena);
@@ -578,29 +578,31 @@ crlgen_CreateReasonCode(PLArenaPool *are
     if (!dummy) {
         goto loser;
     }
 
     *extCode = SEC_OID_X509_REASON_CODE;
     return encodedItem;
 
   loser:
-    PORT_ArenaRelease (arena, mark);
+    if (mark) {
+        PORT_ArenaRelease (arena, mark);
+    }
     return NULL;
 }
 
 /* Creates Cert Invalidity Date extension. Encodes it and
  * returns as SECItem structure */
 static SECItem*
 crlgen_CreateInvalidityDate(PLArenaPool *arena, const char **dataArr,
                        int *extCode)
 {
     SECItem *encodedItem;
     int length = 0;
-    void *mark;
+    void *mark = NULL;
 
     PORT_Assert(arena && dataArr);
     if (!arena || !dataArr) {
         goto loser;
     } 
 
     mark = PORT_ArenaMark(arena);
 
@@ -619,17 +621,19 @@ crlgen_CreateInvalidityDate(PLArenaPool 
 
     PORT_Memcpy(encodedItem->data, dataArr[2], (encodedItem->len = length) *
                 sizeof(char));
 
     *extCode = SEC_OID_X509_INVALID_DATE;
     return encodedItem;
     
   loser:
-    PORT_ArenaRelease(arena, mark);
+    if (mark) {
+        PORT_ArenaRelease(arena, mark);
+    }
     return NULL;
 }
 
 /* Creates(by calling extCreator function) and adds extension to a set
  * of already added certs. Uses values of rangeFrom and rangeTo from
  * CRLGENCrlGenCtl structure for identifying the inclusive set of certs */
 static SECStatus
 crlgen_AddEntryExtension(CRLGENGeneratorData *crlGenData,
@@ -1074,26 +1078,23 @@ crlgen_AddCert(CRLGENGeneratorData *crlG
 
 
 /* Removes certs from entryDataHashTable which have certId serial number.
  * certId can have value of a range of certs */
 static SECStatus
 crlgen_RmCert(CRLGENGeneratorData *crlGenData, char *certId)
 {
     PRUint64 i = 0;
-    PLArenaPool *arena;
 
     PORT_Assert(crlGenData && certId);
     if (!crlGenData || !certId) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
     }
 
-    arena = crlGenData->signCrl->arena;
-
     if (crlgen_SetNewRangeField(crlGenData, certId) == SECFailure &&
         certId) {
         return SECFailure;
     }
 
     for (i = 0;i < crlGenData->rangeTo - crlGenData->rangeFrom + 1;i++) {
         SECItem* certIdItem = SEC_ASN1EncodeInteger(NULL, NULL,
                                                     crlGenData->rangeFrom + i);
@@ -1164,17 +1165,17 @@ crlgen_setNextDataFn_field(CRLGENGenerat
     PORT_Assert(crlGenData);
     if (!crlGenData) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
     }
 
     switch (crlGenData->contextId) {
       case CRLGEN_CHANGE_RANGE_CONTEXT:
-          if (dtype != CRLGEN_TYPE_DIGIT || dtype != CRLGEN_TYPE_DIGIT_RANGE) {
+          if (dtype != CRLGEN_TYPE_DIGIT && dtype != CRLGEN_TYPE_DIGIT_RANGE) {
               crlgen_PrintError(crlGenData->parsedLineNum,
                                 "range value should have "
                                 "numeric or numeric range values.\n");
               return SECFailure;
           }
           break;
       case CRLGEN_NEXT_UPDATE_CONTEXT:
       case CRLGEN_UPDATE_CONTEXT:
--- a/cmd/crlutil/crlutil.c
+++ b/cmd/crlutil/crlutil.c
@@ -123,17 +123,17 @@ static void ListCRLNames (CERTCertDBHand
 
 	crlNode  = crlList->first;
 
         fprintf (stdout, "\n");
 	fprintf (stdout, "\n%-40s %-5s\n\n", "CRL names", "CRL Type");
 	while (crlNode) {
 	    char* asciiname = NULL;
 	    CERTCertificate *cert = NULL;
-	    if (crlNode->crl && &crlNode->crl->crl.derName) {
+	    if (crlNode->crl && crlNode->crl->crl.derName.data != NULL) {
 	        cert = CERT_FindCertByName(certHandle,
 	                                   &crlNode->crl->crl.derName);
 	        if (!cert) {
 	            SECU_PrintError(progName, "could not find signing "
 	                         "certificate in database");
 	        }
 	    }
 	    if (cert) {
@@ -693,41 +693,45 @@ GenerateCRL (CERTCertDBHandle *certHandl
         SECU_PrintError(progName, "fail to allocate memory\n");
         return SECFailure;
     }
 
     if (modifyFlag == PR_TRUE) {
         signCrl = CreateModifiedCRLCopy(arena, certHandle, &cert, certNickName,
                                          inFile, decodeOptions, importOptions);
         if (signCrl == NULL) {
+            rv = SECFailure;
             goto loser;
         }
     }
 
     if (!cert) {
         cert = FindSigningCert(certHandle, signCrl, certNickName);
         if (cert == NULL) {
+            rv = SECFailure;
             goto loser;
         }
     }
 
     if (!signCrl) {
         if (modifyFlag == PR_TRUE) {
             if (!outFileName) {
                 int len = strlen(certNickName) + 5;
                 outFileName = PORT_ArenaAlloc(arena, len);
                 PR_snprintf(outFileName, len, "%s.crl", certNickName);
             }
             SECU_PrintError(progName, "Will try to generate crl. "
                             "It will be saved in file: %s",
                             outFileName);
         }
         signCrl = CreateNewCrl(arena, certHandle, cert);
-        if (!signCrl)
+        if (!signCrl) {
+            rv = SECFailure;
             goto loser;
+        }
     }
 
     rv = UpdateCrl(signCrl, inCrlInitFile);
     if (rv != SECSuccess) {
         goto loser;
     }
 
     rv = SignAndStoreCrl(signCrl, cert, outFileName, hashAlgTag, ascii,
--- a/cmd/crmftest/testcrmf.c
+++ b/cmd/crmftest/testcrmf.c
@@ -122,23 +122,27 @@ debug_test(SECItem *src, char *filePath)
     }
     PR_Write(fileDesc, src->data, src->len);
     
 }
 
 SECStatus
 get_serial_number(long *dest)
 {
-   SECStatus   rv;
+    SECStatus rv;
 
-   if (dest == NULL) {
+    if (dest == NULL) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
-   }
+    }
     rv = PK11_GenerateRandom((unsigned char *)dest, sizeof(long));
+    if (rv != SECSuccess) {
+       /* PK11_GenerateRandom calls PORT_SetError */
+       return SECFailure;
+    }
     /* make serial number positive */
     if (*dest < 0L)
     	*dest = - *dest;
     return SECSuccess;
 }
 
 PK11RSAGenParams *
 GetRSAParams(void) 
@@ -932,28 +936,16 @@ DoCMMFStuff(void)
         CERT_DestroyCertificate(cert);
     }
     if (list) {
         CERT_DestroyCertList(list);
     }
     return rv;
 }
 
-static CK_MECHANISM_TYPE
-mapWrapKeyType(KeyType keyType)
-{
-    switch (keyType) {
-    case rsaKey:
-        return CKM_RSA_PKCS;
-    default:
-        break;
-    }
-    return CKM_INVALID_MECHANISM;
-} 
-
 #define KNOWN_MESSAGE_LENGTH 20 /*160 bits*/
 
 int
 DoKeyRecovery( SECKEYPrivateKey *privKey)
 {
 #ifdef DOING_KEY_RECOVERY  /* Doesn't compile yet. */
     SECKEYPublicKey      *pubKey;
     PK11SlotInfo         *slot;
@@ -1528,20 +1520,16 @@ main(int argc, char **argv)
     PLOptState       *optstate;
     PLOptStatus       status;
     char             *password = NULL;
     char             *pwfile = NULL;
     int               irv     = 0;
     PRUint32          flags   = 0;
     SECStatus         rv;
     PRBool            nssInit = PR_FALSE;
-    PRBool            pArg    = PR_FALSE;
-    PRBool            eArg    = PR_FALSE;
-    PRBool            sArg    = PR_FALSE;
-    PRBool            PArg    = PR_FALSE;
 
     memset( &signPair,  0, sizeof signPair);
     memset( &cryptPair, 0, sizeof cryptPair);
     printf ("\ncrmftest v1.0\n");
     optstate = PL_CreateOptState(argc, argv, "d:p:e:s:P:f:");
     while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
 	switch (optstate->option) {
 	case 'd':
@@ -1554,43 +1542,39 @@ main(int argc, char **argv)
 	    nssInit = PR_TRUE;
 	    break;
 	case 'p':
 	    personalCert = PORT_Strdup(optstate->value);
 	    if (personalCert == NULL) {
 	        printf ("-p  failed\n");
 	        return 603;
 	    }
-	    pArg = PR_TRUE;
 	    break;
 	case 'e':
 	    recoveryEncrypter = PORT_Strdup(optstate->value);
 	    if (recoveryEncrypter == NULL) {
 	        printf ("-e  failed\n");
 	        return 602;
 	    }
-	    eArg = PR_TRUE;
 	    break;
 	case 's':
 	    caCertName = PORT_Strdup(optstate->value);
 	    if (caCertName == NULL) {
 	        printf ("-s  failed\n");
 	        return 604;
 	    }
-	    sArg = PR_TRUE;
 	    break;
 	case 'P':
 	    password = PORT_Strdup(optstate->value);
 	    if (password == NULL) {
 	        printf ("-P  failed\n");
 	        return 606;
 	    }
             pwdata.source = PW_PLAINTEXT;
             pwdata.data = password;
-	    PArg = PR_TRUE;
 	    break;
         case 'f':
 	    pwfile = PORT_Strdup(optstate->value);
 	    if (pwfile == NULL) {
 	        printf ("-f  failed\n");
 	        return 607;
 	    }
             pwdata.source = PW_FROMFILE;
--- a/cmd/fipstest/fipstest.c
+++ b/cmd/fipstest/fipstest.c
@@ -12,16 +12,31 @@
 #include "secerr.h"
 #include "secder.h"
 #include "secdig.h"
 #include "secoid.h"
 #include "ec.h"
 #include "hasht.h"
 #include "lowkeyi.h"
 #include "softoken.h"
+#include "pkcs11t.h"
+#define __PASTE(x,y) x##y
+#undef CK_PKCS11_FUNCTION_INFO
+#undef CK_NEED_ARG_LIST
+#define CK_EXTERN extern
+#define CK_PKCS11_FUNCTION_INFO(func) \
+                CK_RV __PASTE(NS,func)
+#define CK_NEED_ARG_LIST        1
+#include "pkcs11f.h"
+#undef CK_PKCS11_FUNCTION_INFO
+#undef CK_NEED_ARG_LIST
+#undef __PASTE
+#define SSL3_RANDOM_LENGTH              32
+
+
 
 #if 0
 #include "../../lib/freebl/mpi/mpi.h"
 #endif
 
 #ifndef NSS_DISABLE_ECC
 extern SECStatus
 EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams);
@@ -41,64 +56,64 @@ EC_CopyParams(PLArenaPool *arena, ECPara
 
 SECStatus
 hex_to_byteval(const char *c2, unsigned char *byteval)
 {
     int i;
     unsigned char offset;
     *byteval = 0;
     for (i=0; i<2; i++) {
-	if (c2[i] >= '0' && c2[i] <= '9') {
-	    offset = c2[i] - '0';
-	    *byteval |= offset << 4*(1-i);
-	} else if (c2[i] >= 'a' && c2[i] <= 'f') {
-	    offset = c2[i] - 'a';
-	    *byteval |= (offset + 10) << 4*(1-i);
-	} else if (c2[i] >= 'A' && c2[i] <= 'F') {
-	    offset = c2[i] - 'A';
-	    *byteval |= (offset + 10) << 4*(1-i);
-	} else {
-	    return SECFailure;
-	}
+        if (c2[i] >= '0' && c2[i] <= '9') {
+            offset = c2[i] - '0';
+            *byteval |= offset << 4*(1-i);
+        } else if (c2[i] >= 'a' && c2[i] <= 'f') {
+            offset = c2[i] - 'a';
+            *byteval |= (offset + 10) << 4*(1-i);
+        } else if (c2[i] >= 'A' && c2[i] <= 'F') {
+            offset = c2[i] - 'A';
+            *byteval |= (offset + 10) << 4*(1-i);
+        } else {
+            return SECFailure;
+        }
     }
     return SECSuccess;
 }
 
 SECStatus
 byteval_to_hex(unsigned char byteval, char *c2, char a)
 {
     int i;
     unsigned char offset;
     for (i=0; i<2; i++) {
-	offset = (byteval >> 4*(1-i)) & 0x0f;
-	if (offset < 10) {
-	    c2[i] = '0' + offset;
-	} else {
-	    c2[i] = a + offset - 10;
-	}
+        offset = (byteval >> 4*(1-i)) & 0x0f;
+        if (offset < 10) {
+            c2[i] = '0' + offset;
+        } else {
+            c2[i] = a + offset - 10;
+        }
     }
     return SECSuccess;
 }
 
 void
 to_hex_str(char *str, const unsigned char *buf, unsigned int len)
 {
     unsigned int i;
     for (i=0; i<len; i++) {
-	byteval_to_hex(buf[i], &str[2*i], 'a');
+        byteval_to_hex(buf[i], &str[2*i], 'a');
     }
     str[2*len] = '\0';
 }
 
 void
 to_hex_str_cap(char *str, const unsigned char *buf, unsigned int len)
 {
     unsigned int i;
     for (i=0; i<len; i++) {
-	byteval_to_hex(buf[i], &str[2*i], 'A');
+        byteval_to_hex(buf[i], &str[2*i], 'A');
     }
     str[2*len] = '\0';
 }
 
 /*
  * Convert a string of hex digits (str) to an array (buf) of len bytes.
  * Return PR_TRUE if the hex string can fit in the byte array.  Return
  * PR_FALSE if the hex string is empty or is too long.
@@ -108,51 +123,51 @@ from_hex_str(unsigned char *buf, unsigne
 {
     unsigned int nxdigit;  /* number of hex digits in str */
     unsigned int i;  /* index into buf */
     unsigned int j;  /* index into str */
 
     /* count the hex digits */
     nxdigit = 0;
     for (nxdigit = 0; isxdigit(str[nxdigit]); nxdigit++) {
-	/* empty body */
+        /* empty body */
     }
     if (nxdigit == 0) {
-	return PR_FALSE;
+        return PR_FALSE;
     }
     if (nxdigit > 2*len) {
-	/*
-	 * The input hex string is too long, but we allow it if the
-	 * extra digits are leading 0's.
-	 */
-	for (j = 0; j < nxdigit-2*len; j++) {
-	    if (str[j] != '0') {
-		return PR_FALSE;
-	    }
-	}
-	/* skip leading 0's */
-	str += nxdigit-2*len;
-	nxdigit = 2*len;
+        /*
+         * The input hex string is too long, but we allow it if the
+         * extra digits are leading 0's.
+         */
+        for (j = 0; j < nxdigit-2*len; j++) {
+            if (str[j] != '0') {
+                return PR_FALSE;
+            }
+        }
+        /* skip leading 0's */
+        str += nxdigit-2*len;
+        nxdigit = 2*len;
     }
     for (i=0, j=0; i< len; i++) {
-	if (2*i < 2*len-nxdigit) {
-	    /* Handle a short input as if we padded it with leading 0's. */
-	    if (2*i+1 < 2*len-nxdigit) {
-		buf[i] = 0;
-	    } else {
-		char tmp[2];
-		tmp[0] = '0';
-		tmp[1] = str[j];
-		hex_to_byteval(tmp, &buf[i]);
-		j++;
-	    }
-	} else {
-	    hex_to_byteval(&str[j], &buf[i]);
-	    j += 2;
-	}
+        if (2*i < 2*len-nxdigit) {
+            /* Handle a short input as if we padded it with leading 0's. */
+            if (2*i+1 < 2*len-nxdigit) {
+                buf[i] = 0;
+            } else {
+                char tmp[2];
+                tmp[0] = '0';
+                tmp[1] = str[j];
+                hex_to_byteval(tmp, &buf[i]);
+                j++;
+            }
+        } else {
+            hex_to_byteval(&str[j], &buf[i]);
+            j += 2;
+        }
     }
     return PR_TRUE;
 }
 
 SECStatus
 tdea_encrypt_buf(
     int mode,
     const unsigned char *key, 
@@ -283,21 +298,21 @@ tdea_kat_mmt(char *reqfn)
 {
     char buf[180];      /* holds one line from the input REQUEST file.
                          * needs to be large enough to hold the longest
                          * line "CIPHERTEXT = <180 hex digits>\n".
                          */
     FILE *req;       /* input stream from the REQUEST file */
     FILE *resp;      /* output stream to the RESPONSE file */
     int i, j;
-    int mode;           /* NSS_DES_EDE3 (ECB) or NSS_DES_EDE3_CBC */
+    int mode = NSS_DES_EDE3;           /* NSS_DES_EDE3 (ECB) or NSS_DES_EDE3_CBC */
     int crypt = DECRYPT;    /* 1 means encrypt, 0 means decrypt */
     unsigned char key[24];              /* TDEA 3 key bundle */
     unsigned int numKeys = 0;
-    unsigned char iv[8];		/* for all modes except ECB */
+    unsigned char iv[8];                /* for all modes except ECB */
     unsigned char plaintext[8*20];     /* 1 to 20 blocks */
     unsigned int plaintextlen;
     unsigned char ciphertext[8*20];   /* 1 to 20 blocks */  
     unsigned int ciphertextlen;
     SECStatus rv;
 
     req = fopen(reqfn, "r");
     resp = stdout;
@@ -871,54 +886,54 @@ aes_encrypt_buf(
 {
     SECStatus rv = SECFailure;
     AESContext *cx;
     unsigned char doublecheck[10*16];  /* 1 to 10 blocks */
     unsigned int doublechecklen = 0;
 
     cx = AES_CreateContext(key, iv, mode, PR_TRUE, keysize, 16);
     if (cx == NULL) {
-	goto loser;
+        goto loser;
     }
     rv = AES_Encrypt(cx, output, outputlen, maxoutputlen, input, inputlen);
     if (rv != SECSuccess) {
-	goto loser;
+        goto loser;
     }
     if (*outputlen != inputlen) {
-	goto loser;
+        goto loser;
     }
     AES_DestroyContext(cx, PR_TRUE);
     cx = NULL;
 
     /*
      * Doublecheck our result by decrypting the ciphertext and
      * compare the output with the input plaintext.
      */
     cx = AES_CreateContext(key, iv, mode, PR_FALSE, keysize, 16);
     if (cx == NULL) {
-	goto loser;
+        goto loser;
     }
     rv = AES_Decrypt(cx, doublecheck, &doublechecklen, sizeof doublecheck,
-	output, *outputlen);
+        output, *outputlen);
     if (rv != SECSuccess) {
-	goto loser;
+        goto loser;
     }
     if (doublechecklen != *outputlen) {
-	goto loser;
+        goto loser;
     }
     AES_DestroyContext(cx, PR_TRUE);
     cx = NULL;
     if (memcmp(doublecheck, input, inputlen) != 0) {
-	goto loser;
+        goto loser;
     }
     rv = SECSuccess;
 
 loser:
     if (cx != NULL) {
-	AES_DestroyContext(cx, PR_TRUE);
+        AES_DestroyContext(cx, PR_TRUE);
     }
     return rv;
 }
 
 SECStatus
 aes_decrypt_buf(
     int mode,
     const unsigned char *key, unsigned int keysize,
@@ -928,58 +943,274 @@ aes_decrypt_buf(
 {
     SECStatus rv = SECFailure;
     AESContext *cx;
     unsigned char doublecheck[10*16];  /* 1 to 10 blocks */
     unsigned int doublechecklen = 0;
 
     cx = AES_CreateContext(key, iv, mode, PR_FALSE, keysize, 16);
     if (cx == NULL) {
-	goto loser;
+        goto loser;
     }
     rv = AES_Decrypt(cx, output, outputlen, maxoutputlen,
-	input, inputlen);
+        input, inputlen);
     if (rv != SECSuccess) {
-	goto loser;
+        goto loser;
     }
     if (*outputlen != inputlen) {
-	goto loser;
+        goto loser;
     }
     AES_DestroyContext(cx, PR_TRUE);
     cx = NULL;
 
     /*
      * Doublecheck our result by encrypting the plaintext and
      * compare the output with the input ciphertext.
      */
     cx = AES_CreateContext(key, iv, mode, PR_TRUE, keysize, 16);
     if (cx == NULL) {
-	goto loser;
+        goto loser;
     }
     rv = AES_Encrypt(cx, doublecheck, &doublechecklen, sizeof doublecheck,
-	output, *outputlen);
+        output, *outputlen);
     if (rv != SECSuccess) {
-	goto loser;
+        goto loser;
     }
     if (doublechecklen != *outputlen) {
-	goto loser;
+        goto loser;
     }
     AES_DestroyContext(cx, PR_TRUE);
     cx = NULL;
     if (memcmp(doublecheck, input, inputlen) != 0) {
-	goto loser;
+        goto loser;
     }
     rv = SECSuccess;
 
 loser:
     if (cx != NULL) {
-	AES_DestroyContext(cx, PR_TRUE);
+        AES_DestroyContext(cx, PR_TRUE);
     }
     return rv;
 }
+/*
+ * Perform the AES GCM tests.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+aes_gcm(char *reqfn, int encrypt)
+{
+    char buf[512];      /* holds one line from the input REQUEST file.
+                         * needs to be large enough to hold the longest
+                         * line "CIPHERTEXT = <320 hex digits>\n".
+                         */
+    FILE *aesreq;       /* input stream from the REQUEST file */
+    FILE *aesresp;      /* output stream to the RESPONSE file */
+    int i, j;
+    unsigned char key[32];              /* 128, 192, or 256 bits */
+    unsigned int keysize = 0;
+    unsigned char iv[128];                /* handle large gcm IV's */
+    unsigned char plaintext[10*16];     /* 1 to 10 blocks */
+    unsigned int plaintextlen;
+    unsigned char ciphertext[11*16];    /* 1 to 10 blocks + tag */
+    unsigned int ciphertextlen;
+    unsigned char aad[11*16];            /* 1 to 10 blocks + tag */
+    unsigned int aadlen = 0;
+    unsigned int tagbits;
+    unsigned int taglen = 0;
+    unsigned int ivlen;
+    CK_GCM_PARAMS params;
+    SECStatus rv;
+
+    aesreq = fopen(reqfn, "r");
+    aesresp = stdout;
+    while (fgets(buf, sizeof buf, aesreq) != NULL) {
+        /* a comment or blank line */
+        if (buf[0] == '#' || buf[0] == '\n') {
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* [ENCRYPT] or [DECRYPT] */
+        if (buf[0] == '[') {
+            if (strncmp(buf, "[Taglen", 7)  == 0) {
+                if (sscanf(buf, "[Taglen = %d]", &tagbits) != 1) {
+                    goto loser;
+                }
+                taglen = tagbits/8;
+            } 
+            if (strncmp(buf, "[IVlen", 6)  == 0) {
+                if (sscanf(buf, "[IVlen = %d]", &ivlen) != 1) {
+                    goto loser;
+                }
+                ivlen=ivlen/8;
+            } 
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* "COUNT = x" begins a new data set */
+        if (strncmp(buf, "Count", 5) == 0) {
+            /* zeroize the variables for the test with this data set */
+            memset(key, 0, sizeof key);
+            keysize = 0;
+            memset(iv, 0, sizeof iv);
+            memset(plaintext, 0, sizeof plaintext);
+            plaintextlen = 0;
+            memset(ciphertext, 0, sizeof ciphertext);
+            ciphertextlen = 0;
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* KEY = ... */
+        if (strncmp(buf, "Key", 3) == 0) {
+            i = 3;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &key[j]);
+            }
+            keysize = j;
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* IV = ... */
+        if (strncmp(buf, "IV", 2) == 0) {
+            i = 2;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<sizeof iv; i+=2,j++) {
+                hex_to_byteval(&buf[i], &iv[j]);
+            }
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* PLAINTEXT = ... */
+        if (strncmp(buf, "PT", 2) == 0) {
+            /* sanity check */
+            if (!encrypt) {
+                goto loser;
+            }
+
+            i = 2;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &plaintext[j]);
+            }
+            plaintextlen = j;
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* CIPHERTEXT = ... */
+        if (strncmp(buf, "CT", 2) == 0) {
+            /* sanity check */
+            if (encrypt) {
+                goto loser;
+            }
+
+            i = 2;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &ciphertext[j]);
+            }
+            ciphertextlen = j;
+            fputs(buf, aesresp);
+            continue;
+        }
+        if (strncmp(buf, "AAD", 3) == 0) {
+            i = 3;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &aad[j]);
+            }
+            aadlen = j;
+            fputs(buf, aesresp);
+            if (encrypt) {
+                if (encrypt == 2) {
+                    rv = RNG_GenerateGlobalRandomBytes(iv, ivlen);
+                    if (rv != SECSuccess) {
+                        goto loser;
+                    }
+                }
+                params.pIv = iv;
+                params.ulIvLen = ivlen;
+                params.pAAD = aad;
+                params.ulAADLen = aadlen;
+                params.ulTagBits = tagbits;
+                rv = aes_encrypt_buf(NSS_AES_GCM, key, keysize,
+                (unsigned char *)&params,
+                ciphertext, &ciphertextlen, sizeof ciphertext,
+                plaintext, plaintextlen);
+                if (rv != SECSuccess) {
+                    goto loser;
+                }
+
+		if (encrypt == 2) {
+                    fputs("IV = ", aesresp);
+                    to_hex_str(buf, iv, ivlen);
+                    fputs(buf, aesresp);
+                    fputc('\n', aesresp);
+		}
+                fputs("CT = ", aesresp);
+                j = ciphertextlen-taglen;
+                to_hex_str(buf, ciphertext, j);
+                fputs(buf, aesresp);
+                fputs("\nTag = ", aesresp);
+                to_hex_str(buf, ciphertext+j, taglen);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+            }
+            continue;
+        }
+        if (strncmp(buf, "Tag", 3) == 0) {
+            /* sanity check */
+            if (encrypt) {
+                goto loser;
+            }
+
+            i = 3;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &ciphertext[j+ciphertextlen]);
+            }
+            ciphertextlen += j;
+            params.pIv = iv;
+            params.ulIvLen = ivlen;
+            params.pAAD = aad;
+            params.ulAADLen = aadlen;
+            params.ulTagBits = tagbits;
+            rv = aes_decrypt_buf(NSS_AES_GCM, key, keysize,
+                (unsigned char *)&params,
+                plaintext, &plaintextlen, sizeof plaintext,
+                ciphertext, ciphertextlen);
+            fputs(buf, aesresp);
+            if (rv != SECSuccess) {
+                fprintf(aesresp,"FAIL\n");
+            } else {
+                fputs("PT = ", aesresp);
+                to_hex_str(buf, plaintext, plaintextlen);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+            }
+            continue;
+        }
+    }
+loser:
+    fclose(aesreq);
+}
 
 /*
  * Perform the AES Known Answer Test (KAT) or Multi-block Message
  * Test (MMT) in ECB or CBC mode.  The KAT (there are four types)
  * and MMT have the same structure: given the key and IV (CBC mode
  * only), encrypt the given plaintext or decrypt the given ciphertext.
  * So we can handle them the same way.
  *
@@ -992,147 +1223,147 @@ aes_kat_mmt(char *reqfn)
 {
     char buf[512];      /* holds one line from the input REQUEST file.
                          * needs to be large enough to hold the longest
                          * line "CIPHERTEXT = <320 hex digits>\n".
                          */
     FILE *aesreq;       /* input stream from the REQUEST file */
     FILE *aesresp;      /* output stream to the RESPONSE file */
     int i, j;
-    int mode;           /* NSS_AES (ECB) or NSS_AES_CBC */
+    int mode = NSS_AES;           /* NSS_AES (ECB) or NSS_AES_CBC */
     int encrypt = 0;    /* 1 means encrypt, 0 means decrypt */
     unsigned char key[32];              /* 128, 192, or 256 bits */
-    unsigned int keysize;
-    unsigned char iv[16];		/* for all modes except ECB */
+    unsigned int keysize = 0;
+    unsigned char iv[16];                /* for all modes except ECB */
     unsigned char plaintext[10*16];     /* 1 to 10 blocks */
     unsigned int plaintextlen;
     unsigned char ciphertext[10*16];    /* 1 to 10 blocks */
     unsigned int ciphertextlen;
     SECStatus rv;
 
     aesreq = fopen(reqfn, "r");
     aesresp = stdout;
     while (fgets(buf, sizeof buf, aesreq) != NULL) {
-	/* a comment or blank line */
-	if (buf[0] == '#' || buf[0] == '\n') {
-	    fputs(buf, aesresp);
-	    continue;
-	}
-	/* [ENCRYPT] or [DECRYPT] */
-	if (buf[0] == '[') {
-	    if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
-		encrypt = 1;
-	    } else {
-		encrypt = 0;
-	    }
-	    fputs(buf, aesresp);
-	    continue;
-	}
-	/* "COUNT = x" begins a new data set */
-	if (strncmp(buf, "COUNT", 5) == 0) {
-	    mode = NSS_AES;
-	    /* zeroize the variables for the test with this data set */
-	    memset(key, 0, sizeof key);
-	    keysize = 0;
-	    memset(iv, 0, sizeof iv);
-	    memset(plaintext, 0, sizeof plaintext);
-	    plaintextlen = 0;
-	    memset(ciphertext, 0, sizeof ciphertext);
-	    ciphertextlen = 0;
-	    fputs(buf, aesresp);
-	    continue;
-	}
-	/* KEY = ... */
-	if (strncmp(buf, "KEY", 3) == 0) {
-	    i = 3;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; isxdigit(buf[i]); i+=2,j++) {
-		hex_to_byteval(&buf[i], &key[j]);
-	    }
-	    keysize = j;
-	    fputs(buf, aesresp);
-	    continue;
-	}
-	/* IV = ... */
-	if (strncmp(buf, "IV", 2) == 0) {
-	    mode = NSS_AES_CBC;
-	    i = 2;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; j<sizeof iv; i+=2,j++) {
-		hex_to_byteval(&buf[i], &iv[j]);
-	    }
-	    fputs(buf, aesresp);
-	    continue;
-	}
-	/* PLAINTEXT = ... */
-	if (strncmp(buf, "PLAINTEXT", 9) == 0) {
-	    /* sanity check */
-	    if (!encrypt) {
-		goto loser;
-	    }
-
-	    i = 9;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; isxdigit(buf[i]); i+=2,j++) {
-		hex_to_byteval(&buf[i], &plaintext[j]);
-	    }
-	    plaintextlen = j;
-
-	    rv = aes_encrypt_buf(mode, key, keysize,
-		(mode == NSS_AES) ? NULL : iv,
-		ciphertext, &ciphertextlen, sizeof ciphertext,
-		plaintext, plaintextlen);
-	    if (rv != SECSuccess) {
-		goto loser;
-	    }
-
-	    fputs(buf, aesresp);
-	    fputs("CIPHERTEXT = ", aesresp);
-	    to_hex_str(buf, ciphertext, ciphertextlen);
-	    fputs(buf, aesresp);
-	    fputc('\n', aesresp);
-	    continue;
-	}
-	/* CIPHERTEXT = ... */
-	if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
-	    /* sanity check */
-	    if (encrypt) {
-		goto loser;
-	    }
-
-	    i = 10;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; isxdigit(buf[i]); i+=2,j++) {
-		hex_to_byteval(&buf[i], &ciphertext[j]);
-	    }
-	    ciphertextlen = j;
-
-	    rv = aes_decrypt_buf(mode, key, keysize,
-		(mode == NSS_AES) ? NULL : iv,
-		plaintext, &plaintextlen, sizeof plaintext,
-		ciphertext, ciphertextlen);
-	    if (rv != SECSuccess) {
-		goto loser;
-	    }
-
-	    fputs(buf, aesresp);
-	    fputs("PLAINTEXT = ", aesresp);
-	    to_hex_str(buf, plaintext, plaintextlen);
-	    fputs(buf, aesresp);
-	    fputc('\n', aesresp);
-	    continue;
-	}
+        /* a comment or blank line */
+        if (buf[0] == '#' || buf[0] == '\n') {
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* [ENCRYPT] or [DECRYPT] */
+        if (buf[0] == '[') {
+            if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
+                encrypt = 1;
+            } else {
+                encrypt = 0;
+            }
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* "COUNT = x" begins a new data set */
+        if (strncmp(buf, "COUNT", 5) == 0) {
+            mode = NSS_AES;
+            /* zeroize the variables for the test with this data set */
+            memset(key, 0, sizeof key);
+            keysize = 0;
+            memset(iv, 0, sizeof iv);
+            memset(plaintext, 0, sizeof plaintext);
+            plaintextlen = 0;
+            memset(ciphertext, 0, sizeof ciphertext);
+            ciphertextlen = 0;
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* KEY = ... */
+        if (strncmp(buf, "KEY", 3) == 0) {
+            i = 3;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &key[j]);
+            }
+            keysize = j;
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* IV = ... */
+        if (strncmp(buf, "IV", 2) == 0) {
+            mode = NSS_AES_CBC;
+            i = 2;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<sizeof iv; i+=2,j++) {
+                hex_to_byteval(&buf[i], &iv[j]);
+            }
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* PLAINTEXT = ... */
+        if (strncmp(buf, "PLAINTEXT", 9) == 0) {
+            /* sanity check */
+            if (!encrypt) {
+                goto loser;
+            }
+
+            i = 9;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &plaintext[j]);
+            }
+            plaintextlen = j;
+
+            rv = aes_encrypt_buf(mode, key, keysize,
+                (mode == NSS_AES) ? NULL : iv,
+                ciphertext, &ciphertextlen, sizeof ciphertext,
+                plaintext, plaintextlen);
+            if (rv != SECSuccess) {
+                goto loser;
+            }
+
+            fputs(buf, aesresp);
+            fputs("CIPHERTEXT = ", aesresp);
+            to_hex_str(buf, ciphertext, ciphertextlen);
+            fputs(buf, aesresp);
+            fputc('\n', aesresp);
+            continue;
+        }
+        /* CIPHERTEXT = ... */
+        if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
+            /* sanity check */
+            if (encrypt) {
+                goto loser;
+            }
+
+            i = 10;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &ciphertext[j]);
+            }
+            ciphertextlen = j;
+
+            rv = aes_decrypt_buf(mode, key, keysize,
+                (mode == NSS_AES) ? NULL : iv,
+                plaintext, &plaintextlen, sizeof plaintext,
+                ciphertext, ciphertextlen);
+            if (rv != SECSuccess) {
+                goto loser;
+            }
+
+            fputs(buf, aesresp);
+            fputs("PLAINTEXT = ", aesresp);
+            to_hex_str(buf, plaintext, plaintextlen);
+            fputs(buf, aesresp);
+            fputc('\n', aesresp);
+            continue;
+        }
     }
 loser:
     fclose(aesreq);
 }
 
 /*
  * Generate Key[i+1] from Key[i], CT[j-1], and CT[j] for AES Monte Carlo
  * Test (MCT) in ECB and CBC modes.
@@ -1140,42 +1371,42 @@ loser:
 void
 aes_mct_next_key(unsigned char *key, unsigned int keysize,
     const unsigned char *ciphertext_1, const unsigned char *ciphertext)
 {
     int k;
 
     switch (keysize) {
     case 16:  /* 128-bit key */
-	/* Key[i+1] = Key[i] xor CT[j] */
-	for (k=0; k<16; k++) {
-	    key[k] ^= ciphertext[k];
-	}
-	break;
+        /* Key[i+1] = Key[i] xor CT[j] */
+        for (k=0; k<16; k++) {
+            key[k] ^= ciphertext[k];
+        }
+        break;
     case 24:  /* 192-bit key */
-	/*
-	 * Key[i+1] = Key[i] xor (last 64-bits of
-	 *            CT[j-1] || CT[j])
-	 */
-	for (k=0; k<8; k++) {
-	    key[k] ^= ciphertext_1[k+8];
-	}
-	for (k=8; k<24; k++) {
-	    key[k] ^= ciphertext[k-8];
-	}
-	break;
+        /*
+         * Key[i+1] = Key[i] xor (last 64-bits of
+         *            CT[j-1] || CT[j])
+         */
+        for (k=0; k<8; k++) {
+            key[k] ^= ciphertext_1[k+8];
+        }
+        for (k=8; k<24; k++) {
+            key[k] ^= ciphertext[k-8];
+        }
+        break;
     case 32:  /* 256-bit key */
-	/* Key[i+1] = Key[i] xor (CT[j-1] || CT[j]) */
-	for (k=0; k<16; k++) {
-	    key[k] ^= ciphertext_1[k];
-	}
-	for (k=16; k<32; k++) {
-	    key[k] ^= ciphertext[k-16];
-	}
-	break;
+        /* Key[i+1] = Key[i] xor (CT[j-1] || CT[j]) */
+        for (k=0; k<16; k++) {
+            key[k] ^= ciphertext_1[k];
+        }
+        for (k=16; k<32; k++) {
+            key[k] ^= ciphertext[k-16];
+        }
+        break;
     }
 }
 
 /*
  * Perform the AES Monte Carlo Test (MCT) in ECB mode.  MCT exercises
  * our AES code in streaming mode because the plaintext or ciphertext
  * is generated block by block as we go, so we can't collect all the
  * plaintext or ciphertext in one buffer and encrypt or decrypt it in
@@ -1192,272 +1423,272 @@ aes_ecb_mct(char *reqfn)
                          * needs to be large enough to hold the longest
                          * line "KEY = <64 hex digits>\n".
                          */
     FILE *aesreq;       /* input stream from the REQUEST file */
     FILE *aesresp;      /* output stream to the RESPONSE file */
     int i, j;
     int encrypt = 0;    /* 1 means encrypt, 0 means decrypt */
     unsigned char key[32];              /* 128, 192, or 256 bits */
-    unsigned int keysize;
+    unsigned int keysize = 0;
     unsigned char plaintext[16];        /* PT[j] */
     unsigned char plaintext_1[16];      /* PT[j-1] */
     unsigned char ciphertext[16];       /* CT[j] */
     unsigned char ciphertext_1[16];     /* CT[j-1] */
     unsigned char doublecheck[16];
     unsigned int outputlen;
-    AESContext *cx = NULL;	/* the operation being tested */
+    AESContext *cx = NULL;        /* the operation being tested */
     AESContext *cx2 = NULL;     /* the inverse operation done in parallel
                                  * to doublecheck our result.
                                  */
     SECStatus rv;
 
     aesreq = fopen(reqfn, "r");
     aesresp = stdout;
     while (fgets(buf, sizeof buf, aesreq) != NULL) {
-	/* a comment or blank line */
-	if (buf[0] == '#' || buf[0] == '\n') {
-	    fputs(buf, aesresp);
-	    continue;
-	}
-	/* [ENCRYPT] or [DECRYPT] */
-	if (buf[0] == '[') {
-	    if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
-		encrypt = 1;
-	    } else {
-		encrypt = 0;
-	    }
-	    fputs(buf, aesresp);
-	    continue;
-	}
-	/* "COUNT = x" begins a new data set */
-	if (strncmp(buf, "COUNT", 5) == 0) {
-	    /* zeroize the variables for the test with this data set */
-	    memset(key, 0, sizeof key);
-	    keysize = 0;
-	    memset(plaintext, 0, sizeof plaintext);
-	    memset(ciphertext, 0, sizeof ciphertext);
-	    continue;
-	}
-	/* KEY = ... */
-	if (strncmp(buf, "KEY", 3) == 0) {
-	    /* Key[0] = Key */
-	    i = 3;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; isxdigit(buf[i]); i+=2,j++) {
-		hex_to_byteval(&buf[i], &key[j]);
-	    }
-	    keysize = j;
-	    continue;
-	}
-	/* PLAINTEXT = ... */
-	if (strncmp(buf, "PLAINTEXT", 9) == 0) {
-	    /* sanity check */
-	    if (!encrypt) {
-		goto loser;
-	    }
-	    /* PT[0] = PT */
-	    i = 9;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; j<sizeof plaintext; i+=2,j++) {
-		hex_to_byteval(&buf[i], &plaintext[j]);
-	    }
-
-	    for (i=0; i<100; i++) {
-		sprintf(buf, "COUNT = %d\n", i);
-	        fputs(buf, aesresp);
-		/* Output Key[i] */
-		fputs("KEY = ", aesresp);
-		to_hex_str(buf, key, keysize);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-		/* Output PT[0] */
-		fputs("PLAINTEXT = ", aesresp);
-		to_hex_str(buf, plaintext, sizeof plaintext);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-
-		cx = AES_CreateContext(key, NULL, NSS_AES,
-		    PR_TRUE, keysize, 16);
-		if (cx == NULL) {
-		    goto loser;
-		}
-		/*
-		 * doublecheck our result by decrypting the result
-		 * and comparing the output with the plaintext.
-		 */
-		cx2 = AES_CreateContext(key, NULL, NSS_AES,
-		    PR_FALSE, keysize, 16);
-		if (cx2 == NULL) {
-		    goto loser;
-		}
-		for (j=0; j<1000; j++) {
-		    /* Save CT[j-1] */
-		    memcpy(ciphertext_1, ciphertext, sizeof ciphertext);
-
-		    /* CT[j] = AES(Key[i], PT[j]) */
-		    outputlen = 0;
-		    rv = AES_Encrypt(cx,
-			ciphertext, &outputlen, sizeof ciphertext,
-			plaintext, sizeof plaintext);
-		    if (rv != SECSuccess) {
-			goto loser;
-		    }
-		    if (outputlen != sizeof plaintext) {
-			goto loser;
-		    }
-
-		    /* doublecheck our result */
-		    outputlen = 0;
-		    rv = AES_Decrypt(cx2,
-			doublecheck, &outputlen, sizeof doublecheck,
-			ciphertext, sizeof ciphertext);
-		    if (rv != SECSuccess) {
-			goto loser;
-		    }
-		    if (outputlen != sizeof ciphertext) {
-			goto loser;
-		    }
-		    if (memcmp(doublecheck, plaintext, sizeof plaintext)) {
-			goto loser;
-		    }
-
-		    /* PT[j+1] = CT[j] */
-		    memcpy(plaintext, ciphertext, sizeof plaintext);
-		}
-		AES_DestroyContext(cx, PR_TRUE);
-		cx = NULL;
-		AES_DestroyContext(cx2, PR_TRUE);
-		cx2 = NULL;
-
-		/* Output CT[j] */
-		fputs("CIPHERTEXT = ", aesresp);
-		to_hex_str(buf, ciphertext, sizeof ciphertext);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-
-		/* Key[i+1] = Key[i] xor ... */
-		aes_mct_next_key(key, keysize, ciphertext_1, ciphertext);
-		/* PT[0] = CT[j] */
-		/* done at the end of the for(j) loop */
-
-		fputc('\n', aesresp);
-	    }
-
-	    continue;
-	}
-	/* CIPHERTEXT = ... */
-	if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
-	    /* sanity check */
-	    if (encrypt) {
-		goto loser;
-	    }
-	    /* CT[0] = CT */
-	    i = 10;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; isxdigit(buf[i]); i+=2,j++) {
-		hex_to_byteval(&buf[i], &ciphertext[j]);
-	    }
-
-	    for (i=0; i<100; i++) {
-		sprintf(buf, "COUNT = %d\n", i);
-	        fputs(buf, aesresp);
-		/* Output Key[i] */
-		fputs("KEY = ", aesresp);
-		to_hex_str(buf, key, keysize);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-		/* Output CT[0] */
-		fputs("CIPHERTEXT = ", aesresp);
-		to_hex_str(buf, ciphertext, sizeof ciphertext);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-
-		cx = AES_CreateContext(key, NULL, NSS_AES,
-		    PR_FALSE, keysize, 16);
-		if (cx == NULL) {
-		    goto loser;
-		}
-		/*
-		 * doublecheck our result by encrypting the result
-		 * and comparing the output with the ciphertext.
-		 */
-		cx2 = AES_CreateContext(key, NULL, NSS_AES,
-		    PR_TRUE, keysize, 16);
-		if (cx2 == NULL) {
-		    goto loser;
-		}
-		for (j=0; j<1000; j++) {
-		    /* Save PT[j-1] */
-		    memcpy(plaintext_1, plaintext, sizeof plaintext);
-
-		    /* PT[j] = AES(Key[i], CT[j]) */
-		    outputlen = 0;
-		    rv = AES_Decrypt(cx,
-			plaintext, &outputlen, sizeof plaintext,
-			ciphertext, sizeof ciphertext);
-		    if (rv != SECSuccess) {
-			goto loser;
-		    }
-		    if (outputlen != sizeof ciphertext) {
-			goto loser;
-		    }
-
-		    /* doublecheck our result */
-		    outputlen = 0;
-		    rv = AES_Encrypt(cx2,
-			doublecheck, &outputlen, sizeof doublecheck,
-			plaintext, sizeof plaintext);
-		    if (rv != SECSuccess) {
-			goto loser;
-		    }
-		    if (outputlen != sizeof plaintext) {
-			goto loser;
-		    }
-		    if (memcmp(doublecheck, ciphertext, sizeof ciphertext)) {
-			goto loser;
-		    }
-
-		    /* CT[j+1] = PT[j] */
-		    memcpy(ciphertext, plaintext, sizeof ciphertext);
-		}
-		AES_DestroyContext(cx, PR_TRUE);
-		cx = NULL;
-		AES_DestroyContext(cx2, PR_TRUE);
-		cx2 = NULL;
-
-		/* Output PT[j] */
-		fputs("PLAINTEXT = ", aesresp);
-		to_hex_str(buf, plaintext, sizeof plaintext);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-
-		/* Key[i+1] = Key[i] xor ... */
-		aes_mct_next_key(key, keysize, plaintext_1, plaintext);
-		/* CT[0] = PT[j] */
-		/* done at the end of the for(j) loop */
-
-		fputc('\n', aesresp);
-	    }
-
-	    continue;
-	}
+        /* a comment or blank line */
+        if (buf[0] == '#' || buf[0] == '\n') {
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* [ENCRYPT] or [DECRYPT] */
+        if (buf[0] == '[') {
+            if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
+                encrypt = 1;
+            } else {
+                encrypt = 0;
+            }
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* "COUNT = x" begins a new data set */
+        if (strncmp(buf, "COUNT", 5) == 0) {
+            /* zeroize the variables for the test with this data set */
+            memset(key, 0, sizeof key);
+            keysize = 0;
+            memset(plaintext, 0, sizeof plaintext);
+            memset(ciphertext, 0, sizeof ciphertext);
+            continue;
+        }
+        /* KEY = ... */
+        if (strncmp(buf, "KEY", 3) == 0) {
+            /* Key[0] = Key */
+            i = 3;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &key[j]);
+            }
+            keysize = j;
+            continue;
+        }
+        /* PLAINTEXT = ... */
+        if (strncmp(buf, "PLAINTEXT", 9) == 0) {
+            /* sanity check */
+            if (!encrypt) {
+                goto loser;
+            }
+            /* PT[0] = PT */
+            i = 9;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<sizeof plaintext; i+=2,j++) {
+                hex_to_byteval(&buf[i], &plaintext[j]);
+            }
+
+            for (i=0; i<100; i++) {
+                sprintf(buf, "COUNT = %d\n", i);
+                fputs(buf, aesresp);
+                /* Output Key[i] */
+                fputs("KEY = ", aesresp);
+                to_hex_str(buf, key, keysize);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+                /* Output PT[0] */
+                fputs("PLAINTEXT = ", aesresp);
+                to_hex_str(buf, plaintext, sizeof plaintext);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+
+                cx = AES_CreateContext(key, NULL, NSS_AES,
+                    PR_TRUE, keysize, 16);
+                if (cx == NULL) {
+                    goto loser;
+                }
+                /*
+                 * doublecheck our result by decrypting the result
+                 * and comparing the output with the plaintext.
+                 */
+                cx2 = AES_CreateContext(key, NULL, NSS_AES,
+                    PR_FALSE, keysize, 16);
+                if (cx2 == NULL) {
+                    goto loser;
+                }
+                for (j=0; j<1000; j++) {
+                    /* Save CT[j-1] */
+                    memcpy(ciphertext_1, ciphertext, sizeof ciphertext);
+
+                    /* CT[j] = AES(Key[i], PT[j]) */
+                    outputlen = 0;
+                    rv = AES_Encrypt(cx,
+                        ciphertext, &outputlen, sizeof ciphertext,
+                        plaintext, sizeof plaintext);
+                    if (rv != SECSuccess) {
+                        goto loser;
+                    }
+                    if (outputlen != sizeof plaintext) {
+                        goto loser;
+                    }
+
+                    /* doublecheck our result */
+                    outputlen = 0;
+                    rv = AES_Decrypt(cx2,
+                        doublecheck, &outputlen, sizeof doublecheck,
+                        ciphertext, sizeof ciphertext);
+                    if (rv != SECSuccess) {
+                        goto loser;
+                    }
+                    if (outputlen != sizeof ciphertext) {
+                        goto loser;
+                    }
+                    if (memcmp(doublecheck, plaintext, sizeof plaintext)) {
+                        goto loser;
+                    }
+
+                    /* PT[j+1] = CT[j] */
+                    memcpy(plaintext, ciphertext, sizeof plaintext);
+                }
+                AES_DestroyContext(cx, PR_TRUE);
+                cx = NULL;
+                AES_DestroyContext(cx2, PR_TRUE);
+                cx2 = NULL;
+
+                /* Output CT[j] */
+                fputs("CIPHERTEXT = ", aesresp);
+                to_hex_str(buf, ciphertext, sizeof ciphertext);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+
+                /* Key[i+1] = Key[i] xor ... */
+                aes_mct_next_key(key, keysize, ciphertext_1, ciphertext);
+                /* PT[0] = CT[j] */
+                /* done at the end of the for(j) loop */
+
+                fputc('\n', aesresp);
+            }
+
+            continue;
+        }
+        /* CIPHERTEXT = ... */
+        if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
+            /* sanity check */
+            if (encrypt) {
+                goto loser;
+            }
+            /* CT[0] = CT */
+            i = 10;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &ciphertext[j]);
+            }
+
+            for (i=0; i<100; i++) {
+                sprintf(buf, "COUNT = %d\n", i);
+                fputs(buf, aesresp);
+                /* Output Key[i] */
+                fputs("KEY = ", aesresp);
+                to_hex_str(buf, key, keysize);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+                /* Output CT[0] */
+                fputs("CIPHERTEXT = ", aesresp);
+                to_hex_str(buf, ciphertext, sizeof ciphertext);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+
+                cx = AES_CreateContext(key, NULL, NSS_AES,
+                    PR_FALSE, keysize, 16);
+                if (cx == NULL) {
+                    goto loser;
+                }
+                /*
+                 * doublecheck our result by encrypting the result
+                 * and comparing the output with the ciphertext.
+                 */
+                cx2 = AES_CreateContext(key, NULL, NSS_AES,
+                    PR_TRUE, keysize, 16);
+                if (cx2 == NULL) {
+                    goto loser;
+                }
+                for (j=0; j<1000; j++) {
+                    /* Save PT[j-1] */
+                    memcpy(plaintext_1, plaintext, sizeof plaintext);
+
+                    /* PT[j] = AES(Key[i], CT[j]) */
+                    outputlen = 0;
+                    rv = AES_Decrypt(cx,
+                        plaintext, &outputlen, sizeof plaintext,
+                        ciphertext, sizeof ciphertext);
+                    if (rv != SECSuccess) {
+                        goto loser;
+                    }
+                    if (outputlen != sizeof ciphertext) {
+                        goto loser;
+                    }
+
+                    /* doublecheck our result */
+                    outputlen = 0;
+                    rv = AES_Encrypt(cx2,
+                        doublecheck, &outputlen, sizeof doublecheck,
+                        plaintext, sizeof plaintext);
+                    if (rv != SECSuccess) {
+                        goto loser;
+                    }
+                    if (outputlen != sizeof plaintext) {
+                        goto loser;
+                    }
+                    if (memcmp(doublecheck, ciphertext, sizeof ciphertext)) {
+                        goto loser;
+                    }
+
+                    /* CT[j+1] = PT[j] */
+                    memcpy(ciphertext, plaintext, sizeof ciphertext);
+                }
+                AES_DestroyContext(cx, PR_TRUE);
+                cx = NULL;
+                AES_DestroyContext(cx2, PR_TRUE);
+                cx2 = NULL;
+
+                /* Output PT[j] */
+                fputs("PLAINTEXT = ", aesresp);
+                to_hex_str(buf, plaintext, sizeof plaintext);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+
+                /* Key[i+1] = Key[i] xor ... */
+                aes_mct_next_key(key, keysize, plaintext_1, plaintext);
+                /* CT[0] = PT[j] */
+                /* done at the end of the for(j) loop */
+
+                fputc('\n', aesresp);
+            }
+
+            continue;
+        }
     }
 loser:
     if (cx != NULL) {
-	AES_DestroyContext(cx, PR_TRUE);
+        AES_DestroyContext(cx, PR_TRUE);
     }
     if (cx2 != NULL) {
-	AES_DestroyContext(cx2, PR_TRUE);
+        AES_DestroyContext(cx2, PR_TRUE);
     }
     fclose(aesreq);
 }
 
 /*
  * Perform the AES Monte Carlo Test (MCT) in CBC mode.  MCT exercises
  * our AES code in streaming mode because the plaintext or ciphertext
  * is generated block by block as we go, so we can't collect all the
@@ -1475,380 +1706,380 @@ aes_cbc_mct(char *reqfn)
                          * needs to be large enough to hold the longest
                          * line "KEY = <64 hex digits>\n".
                          */
     FILE *aesreq;       /* input stream from the REQUEST file */
     FILE *aesresp;      /* output stream to the RESPONSE file */
     int i, j;
     int encrypt = 0;    /* 1 means encrypt, 0 means decrypt */
     unsigned char key[32];              /* 128, 192, or 256 bits */
-    unsigned int keysize;
+    unsigned int keysize = 0;
     unsigned char iv[16];
     unsigned char plaintext[16];        /* PT[j] */
     unsigned char plaintext_1[16];      /* PT[j-1] */
     unsigned char ciphertext[16];       /* CT[j] */
     unsigned char ciphertext_1[16];     /* CT[j-1] */
     unsigned char doublecheck[16];
     unsigned int outputlen;
-    AESContext *cx = NULL;	/* the operation being tested */
+    AESContext *cx = NULL;        /* the operation being tested */
     AESContext *cx2 = NULL;     /* the inverse operation done in parallel
                                  * to doublecheck our result.
                                  */
     SECStatus rv;
 
     aesreq = fopen(reqfn, "r");
     aesresp = stdout;
     while (fgets(buf, sizeof buf, aesreq) != NULL) {
-	/* a comment or blank line */
-	if (buf[0] == '#' || buf[0] == '\n') {
-	    fputs(buf, aesresp);
-	    continue;
-	}
-	/* [ENCRYPT] or [DECRYPT] */
-	if (buf[0] == '[') {
-	    if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
-		encrypt = 1;
-	    } else {
-		encrypt = 0;
-	    }
-	    fputs(buf, aesresp);
-	    continue;
-	}
-	/* "COUNT = x" begins a new data set */
-	if (strncmp(buf, "COUNT", 5) == 0) {
-	    /* zeroize the variables for the test with this data set */
-	    memset(key, 0, sizeof key);
-	    keysize = 0;
-	    memset(iv, 0, sizeof iv);
-	    memset(plaintext, 0, sizeof plaintext);
-	    memset(ciphertext, 0, sizeof ciphertext);
-	    continue;
-	}
-	/* KEY = ... */
-	if (strncmp(buf, "KEY", 3) == 0) {
-	    /* Key[0] = Key */
-	    i = 3;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; isxdigit(buf[i]); i+=2,j++) {
-		hex_to_byteval(&buf[i], &key[j]);
-	    }
-	    keysize = j;
-	    continue;
-	}
-	/* IV = ... */
-	if (strncmp(buf, "IV", 2) == 0) {
-	    /* IV[0] = IV */
-	    i = 2;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; j<sizeof iv; i+=2,j++) {
-		hex_to_byteval(&buf[i], &iv[j]);
-	    }
-	    continue;
-	}
-	/* PLAINTEXT = ... */
-	if (strncmp(buf, "PLAINTEXT", 9) == 0) {
-	    /* sanity check */
-	    if (!encrypt) {
-		goto loser;
-	    }
-	    /* PT[0] = PT */
-	    i = 9;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; j<sizeof plaintext; i+=2,j++) {
-		hex_to_byteval(&buf[i], &plaintext[j]);
-	    }
-
-	    for (i=0; i<100; i++) {
-		sprintf(buf, "COUNT = %d\n", i);
-	        fputs(buf, aesresp);
-		/* Output Key[i] */
-		fputs("KEY = ", aesresp);
-		to_hex_str(buf, key, keysize);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-		/* Output IV[i] */
-		fputs("IV = ", aesresp);
-		to_hex_str(buf, iv, sizeof iv);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-		/* Output PT[0] */
-		fputs("PLAINTEXT = ", aesresp);
-		to_hex_str(buf, plaintext, sizeof plaintext);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-
-		cx = AES_CreateContext(key, iv, NSS_AES_CBC,
-		    PR_TRUE, keysize, 16);
-		if (cx == NULL) {
-		    goto loser;
-		}
-		/*
-		 * doublecheck our result by decrypting the result
-		 * and comparing the output with the plaintext.
-		 */
-		cx2 = AES_CreateContext(key, iv, NSS_AES_CBC,
-		    PR_FALSE, keysize, 16);
-		if (cx2 == NULL) {
-		    goto loser;
-		}
-		/* CT[-1] = IV[i] */
-		memcpy(ciphertext, iv, sizeof ciphertext);
-		for (j=0; j<1000; j++) {
-		    /* Save CT[j-1] */
-		    memcpy(ciphertext_1, ciphertext, sizeof ciphertext);
-		    /*
-		     * If ( j=0 )
-		     *      CT[j] = AES(Key[i], IV[i], PT[j])
-		     *      PT[j+1] = IV[i] (= CT[j-1])
-		     * Else
-		     *      CT[j] = AES(Key[i], PT[j])
-		     *      PT[j+1] = CT[j-1]
-		     */
-		    outputlen = 0;
-		    rv = AES_Encrypt(cx,
-			ciphertext, &outputlen, sizeof ciphertext,
-			plaintext, sizeof plaintext);
-		    if (rv != SECSuccess) {
-			goto loser;
-		    }
-		    if (outputlen != sizeof plaintext) {
-			goto loser;
-		    }
-
-		    /* doublecheck our result */
-		    outputlen = 0;
-		    rv = AES_Decrypt(cx2,
-			doublecheck, &outputlen, sizeof doublecheck,
-			ciphertext, sizeof ciphertext);
-		    if (rv != SECSuccess) {
-			goto loser;
-		    }
-		    if (outputlen != sizeof ciphertext) {
-			goto loser;
-		    }
-		    if (memcmp(doublecheck, plaintext, sizeof plaintext)) {
-			goto loser;
-		    }
-
-		    memcpy(plaintext, ciphertext_1, sizeof plaintext);
-		}
-		AES_DestroyContext(cx, PR_TRUE);
-		cx = NULL;
-		AES_DestroyContext(cx2, PR_TRUE);
-		cx2 = NULL;
-
-		/* Output CT[j] */
-		fputs("CIPHERTEXT = ", aesresp);
-		to_hex_str(buf, ciphertext, sizeof ciphertext);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-
-		/* Key[i+1] = Key[i] xor ... */
-		aes_mct_next_key(key, keysize, ciphertext_1, ciphertext);
-		/* IV[i+1] = CT[j] */
-		memcpy(iv, ciphertext, sizeof iv);
-		/* PT[0] = CT[j-1] */
-		/* done at the end of the for(j) loop */
-
-		fputc('\n', aesresp);
-	    }
-
-	    continue;
-	}
-	/* CIPHERTEXT = ... */
-	if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
-	    /* sanity check */
-	    if (encrypt) {
-		goto loser;
-	    }
-	    /* CT[0] = CT */
-	    i = 10;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; isxdigit(buf[i]); i+=2,j++) {
-		hex_to_byteval(&buf[i], &ciphertext[j]);
-	    }
-
-	    for (i=0; i<100; i++) {
-		sprintf(buf, "COUNT = %d\n", i);
-	        fputs(buf, aesresp);
-		/* Output Key[i] */
-		fputs("KEY = ", aesresp);
-		to_hex_str(buf, key, keysize);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-		/* Output IV[i] */
-		fputs("IV = ", aesresp);
-		to_hex_str(buf, iv, sizeof iv);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-		/* Output CT[0] */
-		fputs("CIPHERTEXT = ", aesresp);
-		to_hex_str(buf, ciphertext, sizeof ciphertext);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-
-		cx = AES_CreateContext(key, iv, NSS_AES_CBC,
-		    PR_FALSE, keysize, 16);
-		if (cx == NULL) {
-		    goto loser;
-		}
-		/*
-		 * doublecheck our result by encrypting the result
-		 * and comparing the output with the ciphertext.
-		 */
-		cx2 = AES_CreateContext(key, iv, NSS_AES_CBC,
-		    PR_TRUE, keysize, 16);
-		if (cx2 == NULL) {
-		    goto loser;
-		}
-		/* PT[-1] = IV[i] */
-		memcpy(plaintext, iv, sizeof plaintext);
-		for (j=0; j<1000; j++) {
-		    /* Save PT[j-1] */
-		    memcpy(plaintext_1, plaintext, sizeof plaintext);
-		    /*
-		     * If ( j=0 )
-		     *      PT[j] = AES(Key[i], IV[i], CT[j])
-		     *      CT[j+1] = IV[i] (= PT[j-1])
-		     * Else
-		     *      PT[j] = AES(Key[i], CT[j])
-		     *      CT[j+1] = PT[j-1]
-		     */
-		    outputlen = 0;
-		    rv = AES_Decrypt(cx,
-			plaintext, &outputlen, sizeof plaintext,
-			ciphertext, sizeof ciphertext);
-		    if (rv != SECSuccess) {
-			goto loser;
-		    }
-		    if (outputlen != sizeof ciphertext) {
-			goto loser;
-		    }
-
-		    /* doublecheck our result */
-		    outputlen = 0;
-		    rv = AES_Encrypt(cx2,
-			doublecheck, &outputlen, sizeof doublecheck,
-			plaintext, sizeof plaintext);
-		    if (rv != SECSuccess) {
-			goto loser;
-		    }
-		    if (outputlen != sizeof plaintext) {
-			goto loser;
-		    }
-		    if (memcmp(doublecheck, ciphertext, sizeof ciphertext)) {
-			goto loser;
-		    }
-
-		    memcpy(ciphertext, plaintext_1, sizeof ciphertext);
-		}
-		AES_DestroyContext(cx, PR_TRUE);
-		cx = NULL;
-		AES_DestroyContext(cx2, PR_TRUE);
-		cx2 = NULL;
-
-		/* Output PT[j] */
-		fputs("PLAINTEXT = ", aesresp);
-		to_hex_str(buf, plaintext, sizeof plaintext);
-		fputs(buf, aesresp);
-		fputc('\n', aesresp);
-
-		/* Key[i+1] = Key[i] xor ... */
-		aes_mct_next_key(key, keysize, plaintext_1, plaintext);
-		/* IV[i+1] = PT[j] */
-		memcpy(iv, plaintext, sizeof iv);
-		/* CT[0] = PT[j-1] */
-		/* done at the end of the for(j) loop */
-
-		fputc('\n', aesresp);
-	    }
-
-	    continue;
-	}
+        /* a comment or blank line */
+        if (buf[0] == '#' || buf[0] == '\n') {
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* [ENCRYPT] or [DECRYPT] */
+        if (buf[0] == '[') {
+            if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
+                encrypt = 1;
+            } else {
+                encrypt = 0;
+            }
+            fputs(buf, aesresp);
+            continue;
+        }
+        /* "COUNT = x" begins a new data set */
+        if (strncmp(buf, "COUNT", 5) == 0) {
+            /* zeroize the variables for the test with this data set */
+            memset(key, 0, sizeof key);
+            keysize = 0;
+            memset(iv, 0, sizeof iv);
+            memset(plaintext, 0, sizeof plaintext);
+            memset(ciphertext, 0, sizeof ciphertext);
+            continue;
+        }
+        /* KEY = ... */
+        if (strncmp(buf, "KEY", 3) == 0) {
+            /* Key[0] = Key */
+            i = 3;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &key[j]);
+            }
+            keysize = j;
+            continue;
+        }
+        /* IV = ... */
+        if (strncmp(buf, "IV", 2) == 0) {
+            /* IV[0] = IV */
+            i = 2;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<sizeof iv; i+=2,j++) {
+                hex_to_byteval(&buf[i], &iv[j]);
+            }
+            continue;
+        }
+        /* PLAINTEXT = ... */
+        if (strncmp(buf, "PLAINTEXT", 9) == 0) {
+            /* sanity check */
+            if (!encrypt) {
+                goto loser;
+            }
+            /* PT[0] = PT */
+            i = 9;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<sizeof plaintext; i+=2,j++) {
+                hex_to_byteval(&buf[i], &plaintext[j]);
+            }
+
+            for (i=0; i<100; i++) {
+                sprintf(buf, "COUNT = %d\n", i);
+                fputs(buf, aesresp);
+                /* Output Key[i] */
+                fputs("KEY = ", aesresp);
+                to_hex_str(buf, key, keysize);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+                /* Output IV[i] */
+                fputs("IV = ", aesresp);
+                to_hex_str(buf, iv, sizeof iv);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+                /* Output PT[0] */
+                fputs("PLAINTEXT = ", aesresp);
+                to_hex_str(buf, plaintext, sizeof plaintext);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+
+                cx = AES_CreateContext(key, iv, NSS_AES_CBC,
+                    PR_TRUE, keysize, 16);
+                if (cx == NULL) {
+                    goto loser;
+                }
+                /*
+                 * doublecheck our result by decrypting the result
+                 * and comparing the output with the plaintext.
+                 */
+                cx2 = AES_CreateContext(key, iv, NSS_AES_CBC,
+                    PR_FALSE, keysize, 16);
+                if (cx2 == NULL) {
+                    goto loser;
+                }
+                /* CT[-1] = IV[i] */
+                memcpy(ciphertext, iv, sizeof ciphertext);
+                for (j=0; j<1000; j++) {
+                    /* Save CT[j-1] */
+                    memcpy(ciphertext_1, ciphertext, sizeof ciphertext);
+                    /*
+                     * If ( j=0 )
+                     *      CT[j] = AES(Key[i], IV[i], PT[j])
+                     *      PT[j+1] = IV[i] (= CT[j-1])
+                     * Else
+                     *      CT[j] = AES(Key[i], PT[j])
+                     *      PT[j+1] = CT[j-1]
+                     */
+                    outputlen = 0;
+                    rv = AES_Encrypt(cx,
+                        ciphertext, &outputlen, sizeof ciphertext,
+                        plaintext, sizeof plaintext);
+                    if (rv != SECSuccess) {
+                        goto loser;
+                    }
+                    if (outputlen != sizeof plaintext) {
+                        goto loser;
+                    }
+
+                    /* doublecheck our result */
+                    outputlen = 0;
+                    rv = AES_Decrypt(cx2,
+                        doublecheck, &outputlen, sizeof doublecheck,
+                        ciphertext, sizeof ciphertext);
+                    if (rv != SECSuccess) {
+                        goto loser;
+                    }
+                    if (outputlen != sizeof ciphertext) {
+                        goto loser;
+                    }
+                    if (memcmp(doublecheck, plaintext, sizeof plaintext)) {
+                        goto loser;
+                    }
+
+                    memcpy(plaintext, ciphertext_1, sizeof plaintext);
+                }
+                AES_DestroyContext(cx, PR_TRUE);
+                cx = NULL;
+                AES_DestroyContext(cx2, PR_TRUE);
+                cx2 = NULL;
+
+                /* Output CT[j] */
+                fputs("CIPHERTEXT = ", aesresp);
+                to_hex_str(buf, ciphertext, sizeof ciphertext);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+
+                /* Key[i+1] = Key[i] xor ... */
+                aes_mct_next_key(key, keysize, ciphertext_1, ciphertext);
+                /* IV[i+1] = CT[j] */
+                memcpy(iv, ciphertext, sizeof iv);
+                /* PT[0] = CT[j-1] */
+                /* done at the end of the for(j) loop */
+
+                fputc('\n', aesresp);
+            }
+
+            continue;
+        }
+        /* CIPHERTEXT = ... */
+        if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
+            /* sanity check */
+            if (encrypt) {
+                goto loser;
+            }
+            /* CT[0] = CT */
+            i = 10;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &ciphertext[j]);
+            }
+
+            for (i=0; i<100; i++) {
+                sprintf(buf, "COUNT = %d\n", i);
+                fputs(buf, aesresp);
+                /* Output Key[i] */
+                fputs("KEY = ", aesresp);
+                to_hex_str(buf, key, keysize);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+                /* Output IV[i] */
+                fputs("IV = ", aesresp);
+                to_hex_str(buf, iv, sizeof iv);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+                /* Output CT[0] */
+                fputs("CIPHERTEXT = ", aesresp);
+                to_hex_str(buf, ciphertext, sizeof ciphertext);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+
+                cx = AES_CreateContext(key, iv, NSS_AES_CBC,
+                    PR_FALSE, keysize, 16);
+                if (cx == NULL) {
+                    goto loser;
+                }
+                /*
+                 * doublecheck our result by encrypting the result
+                 * and comparing the output with the ciphertext.
+                 */
+                cx2 = AES_CreateContext(key, iv, NSS_AES_CBC,
+                    PR_TRUE, keysize, 16);
+                if (cx2 == NULL) {
+                    goto loser;
+                }
+                /* PT[-1] = IV[i] */
+                memcpy(plaintext, iv, sizeof plaintext);
+                for (j=0; j<1000; j++) {
+                    /* Save PT[j-1] */
+                    memcpy(plaintext_1, plaintext, sizeof plaintext);
+                    /*
+                     * If ( j=0 )
+                     *      PT[j] = AES(Key[i], IV[i], CT[j])
+                     *      CT[j+1] = IV[i] (= PT[j-1])
+                     * Else
+                     *      PT[j] = AES(Key[i], CT[j])
+                     *      CT[j+1] = PT[j-1]
+                     */
+                    outputlen = 0;
+                    rv = AES_Decrypt(cx,
+                        plaintext, &outputlen, sizeof plaintext,
+                        ciphertext, sizeof ciphertext);
+                    if (rv != SECSuccess) {
+                        goto loser;
+                    }
+                    if (outputlen != sizeof ciphertext) {
+                        goto loser;
+                    }
+
+                    /* doublecheck our result */
+                    outputlen = 0;
+                    rv = AES_Encrypt(cx2,
+                        doublecheck, &outputlen, sizeof doublecheck,
+                        plaintext, sizeof plaintext);
+                    if (rv != SECSuccess) {
+                        goto loser;
+                    }
+                    if (outputlen != sizeof plaintext) {
+                        goto loser;
+                    }
+                    if (memcmp(doublecheck, ciphertext, sizeof ciphertext)) {
+                        goto loser;
+                    }
+
+                    memcpy(ciphertext, plaintext_1, sizeof ciphertext);
+                }
+                AES_DestroyContext(cx, PR_TRUE);
+                cx = NULL;
+                AES_DestroyContext(cx2, PR_TRUE);
+                cx2 = NULL;
+
+                /* Output PT[j] */
+                fputs("PLAINTEXT = ", aesresp);
+                to_hex_str(buf, plaintext, sizeof plaintext);
+                fputs(buf, aesresp);
+                fputc('\n', aesresp);
+
+                /* Key[i+1] = Key[i] xor ... */
+                aes_mct_next_key(key, keysize, plaintext_1, plaintext);
+                /* IV[i+1] = PT[j] */
+                memcpy(iv, plaintext, sizeof iv);
+                /* CT[0] = PT[j-1] */
+                /* done at the end of the for(j) loop */
+
+                fputc('\n', aesresp);
+            }
+
+            continue;
+        }
     }
 loser:
     if (cx != NULL) {
-	AES_DestroyContext(cx, PR_TRUE);
+        AES_DestroyContext(cx, PR_TRUE);
     }
     if (cx2 != NULL) {
-	AES_DestroyContext(cx2, PR_TRUE);
+        AES_DestroyContext(cx2, PR_TRUE);
     }
     fclose(aesreq);
 }
 
 void write_compact_string(FILE *out, unsigned char *hash, unsigned int len)
 {
     unsigned int i;
     int j, count = 0, last = -1, z = 0;
     long start = ftell(out);
     for (i=0; i<len; i++) {
-	for (j=7; j>=0; j--) {
-	    if (last < 0) {
-		last = (hash[i] & (1 << j)) ? 1 : 0;
-		fprintf(out, "%d ", last);
-		count = 1;
-	    } else if (hash[i] & (1 << j)) {
-		if (last) {
-		    count++; 
-		} else { 
-		    last = 0;
-		    fprintf(out, "%d ", count);
-		    count = 1;
-		    z++;
-		}
-	    } else {
-		if (!last) {
-		    count++; 
-		} else { 
-		    last = 1;
-		    fprintf(out, "%d ", count);
-		    count = 1;
-		    z++;
-		}
-	    }
-	}
+        for (j=7; j>=0; j--) {
+            if (last < 0) {
+                last = (hash[i] & (1 << j)) ? 1 : 0;
+                fprintf(out, "%d ", last);
+                count = 1;
+            } else if (hash[i] & (1 << j)) {
+                if (last) {
+                    count++; 
+                } else { 
+                    last = 0;
+                    fprintf(out, "%d ", count);
+                    count = 1;
+                    z++;
+                }
+            } else {
+                if (!last) {
+                    count++; 
+                } else { 
+                    last = 1;
+                    fprintf(out, "%d ", count);
+                    count = 1;
+                    z++;
+                }
+            }
+        }
     }
     fprintf(out, "^\n");
     fseek(out, start, SEEK_SET);
     fprintf(out, "%d ", z);
     fseek(out, 0, SEEK_END);
 }
 
 int get_next_line(FILE *req, char *key, char *val, FILE *rsp)
 {
     int ignore = 0;
     char *writeto = key;
     int w = 0;
     int c;
     while ((c = fgetc(req)) != EOF) {
-	if (ignore) {
-	    fprintf(rsp, "%c", c);
-	    if (c == '\n') return ignore;
-	} else if (c == '\n') {
-	    break;
-	} else if (c == '#') {
-	    ignore = 1;
-	    fprintf(rsp, "%c", c);
-	} else if (c == '=') {
-	    writeto[w] = '\0';
-	    w = 0;
-	    writeto = val;
-	} else if (c == ' ' || c == '[' || c == ']') {
-	    continue;
-	} else {
-	    writeto[w++] = c;
-	}
+        if (ignore) {
+            fprintf(rsp, "%c", c);
+            if (c == '\n') return ignore;
+        } else if (c == '\n') {
+            break;
+        } else if (c == '#') {
+            ignore = 1;
+            fprintf(rsp, "%c", c);
+        } else if (c == '=') {
+            writeto[w] = '\0';
+            w = 0;
+            writeto = val;
+        } else if (c == ' ' || c == '[' || c == ']') {
+            continue;
+        } else {
+            writeto[w++] = c;
+        }
     }
     writeto[w] = '\0';
     return (c == EOF) ? -1 : ignore;
 }
 
 #ifndef NSS_DISABLE_ECC
 typedef struct curveNameTagPairStr {
     char *curveName;
@@ -1945,28 +2176,28 @@ getECParams(const char *curve)
 {
     SECItem *ecparams;
     SECOidData *oidData = NULL;
     SECOidTag curveOidTag = SEC_OID_UNKNOWN; /* default */
     int i, numCurves;
 
     if (curve != NULL) {
         numCurves = sizeof(nameTagPair)/sizeof(CurveNameTagPair);
-	for (i = 0; ((i < numCurves) && (curveOidTag == SEC_OID_UNKNOWN)); 
-	     i++) {
-	    if (PL_strcmp(curve, nameTagPair[i].curveName) == 0)
-	        curveOidTag = nameTagPair[i].curveOidTag;
-	}
+        for (i = 0; ((i < numCurves) && (curveOidTag == SEC_OID_UNKNOWN)); 
+             i++) {
+            if (PL_strcmp(curve, nameTagPair[i].curveName) == 0)
+                curveOidTag = nameTagPair[i].curveOidTag;
+        }
     }
 
     /* Return NULL if curve name is not recognized */
     if ((curveOidTag == SEC_OID_UNKNOWN) || 
-	(oidData = SECOID_FindOIDByTag(curveOidTag)) == NULL) {
+        (oidData = SECOID_FindOIDByTag(curveOidTag)) == NULL) {
         fprintf(stderr, "Unrecognized elliptic curve %s\n", curve);
-	return NULL;
+        return NULL;
     }
 
     ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len));
 
     /* 
      * ecparams->data needs to contain the ASN encoding of an object ID (OID)
      * representing the named curve. The actual OID is in 
      * oidData->oid.data so we simply prepend 0x06 and OID length
@@ -1974,16 +2205,131 @@ getECParams(const char *curve)
     ecparams->data[0] = SEC_ASN1_OBJECT_ID;
     ecparams->data[1] = oidData->oid.len;
     memcpy(ecparams->data + 2, oidData->oid.data, oidData->oid.len);
 
     return ecparams;
 }
 
 /*
+ * HASH_ functions are available to full NSS apps and internally inside
+ * freebl, but not exported to users of freebl. Create short stubs to
+ * replace the functionality for fipstest.
+ */
+SECStatus
+fips_hashBuf(HASH_HashType type, unsigned char *hashBuf, 
+                                        unsigned char *msg, int len)
+{
+    SECStatus rv = SECFailure;
+
+    switch (type) {
+    case HASH_AlgSHA1:
+        rv = SHA1_HashBuf(hashBuf, msg, len);
+        break;
+    case HASH_AlgSHA224:
+        rv = SHA224_HashBuf(hashBuf, msg, len);
+        break;
+    case HASH_AlgSHA256:
+        rv = SHA256_HashBuf(hashBuf, msg, len);
+        break;
+    case HASH_AlgSHA384:
+        rv = SHA384_HashBuf(hashBuf, msg, len);
+        break;
+    case HASH_AlgSHA512:
+        rv = SHA512_HashBuf(hashBuf, msg, len);
+        break;
+    default:
+        break;
+    }
+    return rv;
+}
+
+int
+fips_hashLen(HASH_HashType type)
+{
+    int len = 0;
+
+    switch (type) {
+    case HASH_AlgSHA1:
+        len = SHA1_LENGTH;
+        break;
+    case HASH_AlgSHA224:
+        len = SHA224_LENGTH;
+        break;
+    case HASH_AlgSHA256:
+        len = SHA256_LENGTH;
+        break;
+    case HASH_AlgSHA384:
+        len = SHA384_LENGTH;
+        break;
+    case HASH_AlgSHA512:
+        len = SHA512_LENGTH;
+        break;
+    default:
+        break;
+    }
+    return len;
+}
+
+SECOidTag
+fips_hashOid(HASH_HashType type)
+{
+    SECOidTag oid = SEC_OID_UNKNOWN;
+
+    switch (type) {
+    case HASH_AlgSHA1:
+        oid = SEC_OID_SHA1;
+        break;
+    case HASH_AlgSHA224:
+        oid = SEC_OID_SHA224;
+        break;
+    case HASH_AlgSHA256:
+        oid = SEC_OID_SHA256;
+        break;
+    case HASH_AlgSHA384:
+        oid = SEC_OID_SHA384;
+        break;
+    case HASH_AlgSHA512:
+        oid = SEC_OID_SHA512;
+        break;
+    default:
+        break;
+    }
+    return oid;
+}
+
+HASH_HashType
+sha_get_hashType(int hashbits)
+{
+    HASH_HashType hashType = HASH_AlgNULL;
+
+    switch (hashbits) {
+    case 1:
+    case (SHA1_LENGTH*PR_BITS_PER_BYTE): 
+        hashType = HASH_AlgSHA1;
+        break;
+    case (SHA224_LENGTH*PR_BITS_PER_BYTE): 
+        hashType = HASH_AlgSHA224;
+        break;
+    case (SHA256_LENGTH*PR_BITS_PER_BYTE): 
+        hashType = HASH_AlgSHA256;
+        break;
+    case (SHA384_LENGTH*PR_BITS_PER_BYTE): 
+        hashType = HASH_AlgSHA384;
+        break;
+    case (SHA512_LENGTH*PR_BITS_PER_BYTE): 
+        hashType = HASH_AlgSHA512;
+        break;
+    default:
+        break;
+    }
+    return hashType;
+}
+
+/*
  * Perform the ECDSA Key Pair Generation Test.
  *
  * reqfn is the pathname of the REQUEST file.
  *
  * The output RESPONSE file is written to stdout.
  */
 void
 ecdsa_keypair_test(char *reqfn)
@@ -1991,100 +2337,114 @@ ecdsa_keypair_test(char *reqfn)
     char buf[256];      /* holds one line from the input REQUEST file
                          * or to the output RESPONSE file.
                          * needs to be large enough to hold the longest
                          * line "Qx = <144 hex digits>\n".
                          */
     FILE *ecdsareq;     /* input stream from the REQUEST file */
     FILE *ecdsaresp;    /* output stream to the RESPONSE file */
     char curve[16];     /* "nistxddd" */
-    ECParams *ecparams;
+    ECParams *ecparams = NULL;
     int N;
     int i;
     unsigned int len;
 
     ecdsareq = fopen(reqfn, "r");
     ecdsaresp = stdout;
     strcpy(curve, "nist");
     while (fgets(buf, sizeof buf, ecdsareq) != NULL) {
-	/* a comment or blank line */
-	if (buf[0] == '#' || buf[0] == '\n') {
-	    fputs(buf, ecdsaresp);
-	    continue;
-	}
-	/* [X-ddd] */
-	if (buf[0] == '[') {
-	    const char *src;
-	    char *dst;
-	    SECItem *encodedparams;
-
-	    src = &buf[1];
-	    dst = &curve[4];
-	    *dst++ = tolower(*src);
-	    src += 2;  /* skip the hyphen */
-	    *dst++ = *src++;
-	    *dst++ = *src++;
-	    *dst++ = *src++;
-	    *dst = '\0';
-	    encodedparams = getECParams(curve);
-	    if (encodedparams == NULL) {
-		goto loser;
-	    }
-	    if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
-		goto loser;
-	    }
-	    SECITEM_FreeItem(encodedparams, PR_TRUE);
-	    fputs(buf, ecdsaresp);
-	    continue;
-	}
-	/* N = x */
-	if (buf[0] == 'N') {
-	    if (sscanf(buf, "N = %d", &N) != 1) {
-		goto loser;
-	    }
-	    for (i = 0; i < N; i++) {
-		ECPrivateKey *ecpriv;
-
-		if (EC_NewKey(ecparams, &ecpriv) != SECSuccess) {
-		    goto loser;
-		}
-		fputs("d = ", ecdsaresp);
-		to_hex_str(buf, ecpriv->privateValue.data,
-			   ecpriv->privateValue.len);
-		fputs(buf, ecdsaresp);
-		fputc('\n', ecdsaresp);
-		if (EC_ValidatePublicKey(ecparams, &ecpriv->publicValue)
-		    != SECSuccess) {
-		    goto loser;
-		}
-		len = ecpriv->publicValue.len;
-		if (len%2 == 0) {
-		    goto loser;
-		}
-		len = (len-1)/2;
-		if (ecpriv->publicValue.data[0]
-		    != EC_POINT_FORM_UNCOMPRESSED) {
-		    goto loser;
-		}
-		fputs("Qx = ", ecdsaresp);
-		to_hex_str(buf, &ecpriv->publicValue.data[1], len);
-		fputs(buf, ecdsaresp);
-		fputc('\n', ecdsaresp);
-		fputs("Qy = ", ecdsaresp);
-		to_hex_str(buf, &ecpriv->publicValue.data[1+len], len);
-		fputs(buf, ecdsaresp);
-		fputc('\n', ecdsaresp);
-		fputc('\n', ecdsaresp);
-		PORT_FreeArena(ecpriv->ecParams.arena, PR_TRUE);
-	    }
-	    PORT_FreeArena(ecparams->arena, PR_FALSE);
-	    continue;
-	}
+        /* a comment or blank line */
+        if (buf[0] == '#' || buf[0] == '\n') {
+            fputs(buf, ecdsaresp);
+            continue;
+        }
+        /* [X-ddd] */
+        if (buf[0] == '[') {
+            const char *src;
+            char *dst;
+            SECItem *encodedparams;
+
+            if (buf[1] == 'B') {
+                fputs(buf, ecdsaresp);
+                continue;
+            }
+            if (ecparams) {
+                PORT_FreeArena(ecparams->arena, PR_FALSE);
+                ecparams = NULL;
+            }
+
+            src = &buf[1];
+            dst = &curve[4];
+            *dst++ = tolower(*src);
+            src += 2;  /* skip the hyphen */
+            *dst++ = *src++;
+            *dst++ = *src++;
+            *dst++ = *src++;
+            *dst = '\0';
+            encodedparams = getECParams(curve);
+            if (encodedparams == NULL) {
+                fprintf(stderr, "Unknown curve %s.", curve);
+                goto loser;
+            }
+            if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
+                fprintf(stderr, "Curve %s not supported.\n", curve);
+                goto loser;
+            }
+            SECITEM_FreeItem(encodedparams, PR_TRUE);
+            fputs(buf, ecdsaresp);
+            continue;
+        }
+        /* N = x */
+        if (buf[0] == 'N') {
+            if (sscanf(buf, "N = %d", &N) != 1) {
+                goto loser;
+            }
+            for (i = 0; i < N; i++) {
+                ECPrivateKey *ecpriv;
+
+                if (EC_NewKey(ecparams, &ecpriv) != SECSuccess) {
+                    goto loser;
+                }
+                fputs("d = ", ecdsaresp);
+                to_hex_str(buf, ecpriv->privateValue.data,
+                           ecpriv->privateValue.len);
+                fputs(buf, ecdsaresp);
+                fputc('\n', ecdsaresp);
+                if (EC_ValidatePublicKey(ecparams, &ecpriv->publicValue)
+                    != SECSuccess) {
+                    goto loser;
+                }
+                len = ecpriv->publicValue.len;
+                if (len%2 == 0) {
+                    goto loser;
+                }
+                len = (len-1)/2;
+                if (ecpriv->publicValue.data[0]
+                    != EC_POINT_FORM_UNCOMPRESSED) {
+                    goto loser;
+                }
+                fputs("Qx = ", ecdsaresp);
+                to_hex_str(buf, &ecpriv->publicValue.data[1], len);
+                fputs(buf, ecdsaresp);
+                fputc('\n', ecdsaresp);
+                fputs("Qy = ", ecdsaresp);
+                to_hex_str(buf, &ecpriv->publicValue.data[1+len], len);
+                fputs(buf, ecdsaresp);
+                fputc('\n', ecdsaresp);
+                fputc('\n', ecdsaresp);
+                PORT_FreeArena(ecpriv->ecParams.arena, PR_TRUE);
+            }
+            continue;
+        }
     }
 loser:
+    if (ecparams) {
+        PORT_FreeArena(ecparams->arena, PR_FALSE);
+        ecparams = NULL;
+    }
     fclose(ecdsareq);
 }
 
 /*
  * Perform the ECDSA Public Key Validation Test.
  *
  * reqfn is the pathname of the REQUEST file.
  *
@@ -2098,110 +2458,112 @@ ecdsa_pkv_test(char *reqfn)
                          * line "Qx = <144 hex digits>\n".
                          */
     FILE *ecdsareq;     /* input stream from the REQUEST file */
     FILE *ecdsaresp;    /* output stream to the RESPONSE file */
     char curve[16];     /* "nistxddd" */
     ECParams *ecparams = NULL;
     SECItem pubkey;
     unsigned int i;
-    unsigned int len;
+    unsigned int len = 0;
     PRBool keyvalid = PR_TRUE;
 
     ecdsareq = fopen(reqfn, "r");
     ecdsaresp = stdout;
     strcpy(curve, "nist");
     pubkey.data = NULL;
     while (fgets(buf, sizeof buf, ecdsareq) != NULL) {
-	/* a comment or blank line */
-	if (buf[0] == '#' || buf[0] == '\n') {
-	    fputs(buf, ecdsaresp);
-	    continue;
-	}
-	/* [X-ddd] */
-	if (buf[0] == '[') {
-	    const char *src;
-	    char *dst;
-	    SECItem *encodedparams;
-
-	    src = &buf[1];
-	    dst = &curve[4];
-	    *dst++ = tolower(*src);
-	    src += 2;  /* skip the hyphen */
-	    *dst++ = *src++;
-	    *dst++ = *src++;
-	    *dst++ = *src++;
-	    *dst = '\0';
-	    if (ecparams != NULL) {
-		PORT_FreeArena(ecparams->arena, PR_FALSE);
-		ecparams = NULL;
-	    }
-	    encodedparams = getECParams(curve);
-	    if (encodedparams == NULL) {
-		goto loser;
-	    }
-	    if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
-		goto loser;
-	    }
-	    SECITEM_FreeItem(encodedparams, PR_TRUE);
-	    len = (ecparams->fieldID.size + 7) >> 3;
-	    if (pubkey.data != NULL) {
-		PORT_Free(pubkey.data);
-		pubkey.data = NULL;
-	    }
-	    SECITEM_AllocItem(NULL, &pubkey, 2*len+1);
-	    if (pubkey.data == NULL) {
-		goto loser;
-	    }
-	    pubkey.data[0] = EC_POINT_FORM_UNCOMPRESSED;
-	    fputs(buf, ecdsaresp);
-	    continue;
-	}
-	/* Qx = ... */
-	if (strncmp(buf, "Qx", 2) == 0) {
-	    fputs(buf, ecdsaresp);
-	    i = 2;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    keyvalid = from_hex_str(&pubkey.data[1], len, &buf[i]);
-	    continue;
-	}
-	/* Qy = ... */
-	if (strncmp(buf, "Qy", 2) == 0) {
-	    fputs(buf, ecdsaresp);
-	    if (!keyvalid) {
-		fputs("Result = F\n", ecdsaresp);
-		continue;
-	    }
-	    i = 2;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    keyvalid = from_hex_str(&pubkey.data[1+len], len, &buf[i]);
-	    if (!keyvalid) {
-		fputs("Result = F\n", ecdsaresp);
-		continue;
-	    }
-	    if (EC_ValidatePublicKey(ecparams, &pubkey) == SECSuccess) {
-		fputs("Result = P\n", ecdsaresp);
-	    } else if (PORT_GetError() == SEC_ERROR_BAD_KEY) {
-		fputs("Result = F\n", ecdsaresp);
-	    } else {
-		goto loser;
-	    }
-	    continue;
-	}
+        /* a comment or blank line */
+        if (buf[0] == '#' || buf[0] == '\n') {
+            fputs(buf, ecdsaresp);
+            continue;
+        }
+        /* [X-ddd] */
+        if (buf[0] == '[') {
+            const char *src;
+            char *dst;
+            SECItem *encodedparams;
+
+            src = &buf[1];
+            dst = &curve[4];
+            *dst++ = tolower(*src);
+            src += 2;  /* skip the hyphen */
+            *dst++ = *src++;
+            *dst++ = *src++;
+            *dst++ = *src++;
+            *dst = '\0';
+            if (ecparams != NULL) {
+                PORT_FreeArena(ecparams->arena, PR_FALSE);
+                ecparams = NULL;
+            }
+            encodedparams = getECParams(curve);
+            if (encodedparams == NULL) {
+                fprintf(stderr, "Unknown curve %s.", curve);
+                goto loser;
+            }
+            if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
+                fprintf(stderr, "Curve %s not supported.\n", curve);
+                goto loser;
+            }
+            SECITEM_FreeItem(encodedparams, PR_TRUE);
+            len = (ecparams->fieldID.size + 7) >> 3;
+            if (pubkey.data != NULL) {
+                PORT_Free(pubkey.data);
+                pubkey.data = NULL;
+            }
+            SECITEM_AllocItem(NULL, &pubkey, 2*len+1);
+            if (pubkey.data == NULL) {
+                goto loser;
+            }
+            pubkey.data[0] = EC_POINT_FORM_UNCOMPRESSED;
+            fputs(buf, ecdsaresp);
+            continue;
+        }
+        /* Qx = ... */
+        if (strncmp(buf, "Qx", 2) == 0) {
+            fputs(buf, ecdsaresp);
+            i = 2;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            keyvalid = from_hex_str(&pubkey.data[1], len, &buf[i]);
+            continue;
+        }
+        /* Qy = ... */
+        if (strncmp(buf, "Qy", 2) == 0) {
+            fputs(buf, ecdsaresp);
+            if (!keyvalid) {
+                fputs("Result = F\n", ecdsaresp);
+                continue;
+            }
+            i = 2;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            keyvalid = from_hex_str(&pubkey.data[1+len], len, &buf[i]);
+            if (!keyvalid) {
+                fputs("Result = F\n", ecdsaresp);
+                continue;
+            }
+            if (EC_ValidatePublicKey(ecparams, &pubkey) == SECSuccess) {
+                fputs("Result = P\n", ecdsaresp);
+            } else if (PORT_GetError() == SEC_ERROR_BAD_KEY) {
+                fputs("Result = F\n", ecdsaresp);
+            } else {
+                goto loser;
+            }
+            continue;
+        }
     }
 loser:
     if (ecparams != NULL) {
-	PORT_FreeArena(ecparams->arena, PR_FALSE);
+        PORT_FreeArena(ecparams->arena, PR_FALSE);
     }
     if (pubkey.data != NULL) {
-	PORT_Free(pubkey.data);
+        PORT_Free(pubkey.data);
     }
     fclose(ecdsareq);
 }
 
 /*
  * Perform the ECDSA Signature Generation Test.
  *
  * reqfn is the pathname of the REQUEST file.
@@ -2219,129 +2581,155 @@ ecdsa_siggen_test(char *reqfn)
     FILE *ecdsareq;     /* input stream from the REQUEST file */
     FILE *ecdsaresp;    /* output stream to the RESPONSE file */
     char curve[16];     /* "nistxddd" */
     ECParams *ecparams = NULL;
     int i, j;
     unsigned int len;
     unsigned char msg[512];  /* message to be signed (<= 128 bytes) */
     unsigned int msglen;
-    unsigned char sha1[20];  /* SHA-1 hash (160 bits) */
+    unsigned char  sha[HASH_LENGTH_MAX];    /* SHA digest */
+    unsigned int   shaLength = 0;           /* length of SHA */
+    HASH_HashType  shaAlg = HASH_AlgNULL;   /* type of SHA Alg */
     unsigned char sig[2*MAX_ECKEY_LEN];
     SECItem signature, digest;
 
     ecdsareq = fopen(reqfn, "r");
     ecdsaresp = stdout;
     strcpy(curve, "nist");
     while (fgets(buf, sizeof buf, ecdsareq) != NULL) {
-	/* a comment or blank line */
-	if (buf[0] == '#' || buf[0] == '\n') {
-	    fputs(buf, ecdsaresp);
-	    continue;
-	}
-	/* [X-ddd] */
-	if (buf[0] == '[') {
-	    const char *src;
-	    char *dst;
-	    SECItem *encodedparams;
-
-	    src = &buf[1];
-	    dst = &curve[4];
-	    *dst++ = tolower(*src);
-	    src += 2;  /* skip the hyphen */
-	    *dst++ = *src++;
-	    *dst++ = *src++;
-	    *dst++ = *src++;
-	    *dst = '\0';
-	    if (ecparams != NULL) {
-		PORT_FreeArena(ecparams->arena, PR_FALSE);
-		ecparams = NULL;
-	    }
-	    encodedparams = getECParams(curve);
-	    if (encodedparams == NULL) {
-		goto loser;
-	    }
-	    if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
-		goto loser;
-	    }
-	    SECITEM_FreeItem(encodedparams, PR_TRUE);
-	    fputs(buf, ecdsaresp);
-	    continue;
-	}
-	/* Msg = ... */
-	if (strncmp(buf, "Msg", 3) == 0) {
-	    ECPrivateKey *ecpriv;
-
-	    i = 3;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; isxdigit(buf[i]); i+=2,j++) {
-		hex_to_byteval(&buf[i], &msg[j]);
-	    }
-	    msglen = j;
-	    if (SHA1_HashBuf(sha1, msg, msglen) != SECSuccess) {
-		goto loser;
-	    }
-	    fputs(buf, ecdsaresp);
-
-	    if (EC_NewKey(ecparams, &ecpriv) != SECSuccess) {
-		goto loser;
-	    }
-	    if (EC_ValidatePublicKey(ecparams, &ecpriv->publicValue)
-		!= SECSuccess) {
-		goto loser;
-	    }
-	    len = ecpriv->publicValue.len;
-	    if (len%2 == 0) {
-		goto loser;
-	    }
-	    len = (len-1)/2;
-	    if (ecpriv->publicValue.data[0] != EC_POINT_FORM_UNCOMPRESSED) {
-		goto loser;
-	    }
-	    fputs("Qx = ", ecdsaresp);
-	    to_hex_str(buf, &ecpriv->publicValue.data[1], len);
-	    fputs(buf, ecdsaresp);
-	    fputc('\n', ecdsaresp);
-	    fputs("Qy = ", ecdsaresp);
-	    to_hex_str(buf, &ecpriv->publicValue.data[1+len], len);
-	    fputs(buf, ecdsaresp);
-	    fputc('\n', ecdsaresp);
-
-	    digest.type = siBuffer;
-	    digest.data = sha1;
-	    digest.len = sizeof sha1;
-	    signature.type = siBuffer;
-	    signature.data = sig;
-	    signature.len = sizeof sig;
-	    if (ECDSA_SignDigest(ecpriv, &signature, &digest) != SECSuccess) {
-		goto loser;
-	    }
-	    len = signature.len;
-	    if (len%2 != 0) {
-		goto loser;
-	    }
-	    len = len/2;
-	    fputs("R = ", ecdsaresp);
-	    to_hex_str(buf, &signature.data[0], len);
-	    fputs(buf, ecdsaresp);
-	    fputc('\n', ecdsaresp);
-	    fputs("S = ", ecdsaresp);
-	    to_hex_str(buf, &signature.data[len], len);
-	    fputs(buf, ecdsaresp);
-	    fputc('\n', ecdsaresp);
-
-	    PORT_FreeArena(ecpriv->ecParams.arena, PR_TRUE);
-	    continue;
-	}
+        /* a comment or blank line */
+        if (buf[0] == '#' || buf[0] == '\n') {
+            fputs(buf, ecdsaresp);
+            continue;
+        }
+        /* [X-ddd] */
+        if (buf[0] == '[') {
+            const char *src;
+            char *dst;
+            SECItem *encodedparams;
+
+            src = &buf[1];
+            dst = &curve[4];
+            *dst++ = tolower(*src);
+            src += 2;  /* skip the hyphen */
+            *dst++ = *src++;
+            *dst++ = *src++;
+            *dst++ = *src++;
+            *dst = '\0';
+            src++; /* skip the comma */
+            /* set the SHA Algorithm */
+            if (strncmp(src, "SHA-1", 5) == 0) {
+                shaAlg = HASH_AlgSHA1;
+            } else if (strncmp(src, "SHA-224", 7) == 0) {
+                shaAlg = HASH_AlgSHA224;
+            } else if (strncmp(src, "SHA-256", 7) == 0) {
+                shaAlg = HASH_AlgSHA256;
+            } else if (strncmp(src, "SHA-384", 7)== 0) {
+               shaAlg = HASH_AlgSHA384;
+            } else if (strncmp(src, "SHA-512", 7) == 0) {
+               shaAlg = HASH_AlgSHA512;
+            } else {
+               fprintf(ecdsaresp, "ERROR: Unable to find SHAAlg type");
+               goto loser;
+            }
+            if (ecparams != NULL) {
+                PORT_FreeArena(ecparams->arena, PR_FALSE);
+                ecparams = NULL;
+            }
+            encodedparams = getECParams(curve);
+            if (encodedparams == NULL) {
+                fprintf(stderr, "Unknown curve %s.", curve);
+                goto loser;
+            }
+            if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
+                fprintf(stderr, "Curve %s not supported.\n", curve);
+                goto loser;
+            }
+            SECITEM_FreeItem(encodedparams, PR_TRUE);
+            fputs(buf, ecdsaresp);
+            continue;
+        }
+        /* Msg = ... */
+        if (strncmp(buf, "Msg", 3) == 0) {
+            ECPrivateKey *ecpriv;
+
+            i = 3;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &msg[j]);
+            }
+            msglen = j;
+            shaLength = fips_hashLen(shaAlg);
+            if (fips_hashBuf(shaAlg,sha,msg,msglen) != SECSuccess) {
+                if (shaLength == 0) {
+                        fprintf(ecdsaresp, "ERROR: SHAAlg not defined.");
+                }
+                fprintf(ecdsaresp, "ERROR: Unable to generate SHA%x",
+                        shaLength == 160 ? 1 : shaLength);
+                goto loser;
+            }
+            fputs(buf, ecdsaresp);
+
+            if (EC_NewKey(ecparams, &ecpriv) != SECSuccess) {
+                goto loser;
+            }
+            if (EC_ValidatePublicKey(ecparams, &ecpriv->publicValue)
+                != SECSuccess) {
+                goto loser;
+            }
+            len = ecpriv->publicValue.len;
+            if (len%2 == 0) {
+                goto loser;
+            }
+            len = (len-1)/2;
+            if (ecpriv->publicValue.data[0] != EC_POINT_FORM_UNCOMPRESSED) {
+                goto loser;
+            }
+            fputs("Qx = ", ecdsaresp);
+            to_hex_str(buf, &ecpriv->publicValue.data[1], len);
+            fputs(buf, ecdsaresp);
+            fputc('\n', ecdsaresp);
+            fputs("Qy = ", ecdsaresp);
+            to_hex_str(buf, &ecpriv->publicValue.data[1+len], len);
+            fputs(buf, ecdsaresp);
+            fputc('\n', ecdsaresp);
+
+            digest.type = siBuffer;
+            digest.data = sha;
+            digest.len = shaLength;
+            signature.type = siBuffer;
+            signature.data = sig;
+            signature.len = sizeof sig;
+            if (ECDSA_SignDigest(ecpriv, &signature, &digest) != SECSuccess) {
+                goto loser;
+            }
+            len = signature.len;
+            if (len%2 != 0) {
+                goto loser;
+            }
+            len = len/2;
+            fputs("R = ", ecdsaresp);
+            to_hex_str(buf, &signature.data[0], len);
+            fputs(buf, ecdsaresp);
+            fputc('\n', ecdsaresp);
+            fputs("S = ", ecdsaresp);
+            to_hex_str(buf, &signature.data[len], len);
+            fputs(buf, ecdsaresp);
+            fputc('\n', ecdsaresp);
+
+            PORT_FreeArena(ecpriv->ecParams.arena, PR_TRUE);
+            continue;
+        }
     }
 loser:
     if (ecparams != NULL) {
-	PORT_FreeArena(ecparams->arena, PR_FALSE);
+        PORT_FreeArena(ecparams->arena, PR_FALSE);
     }
     fclose(ecdsareq);
 }
 
 /*
  * Perform the ECDSA Signature Verification Test.
  *
  * reqfn is the pathname of the REQUEST file.
@@ -2355,231 +2743,220 @@ ecdsa_sigver_test(char *reqfn)
                          * needs to be large enough to hold the longest
                          * line "Msg = <256 hex digits>\n".
                          */
     FILE *ecdsareq;     /* input stream from the REQUEST file */
     FILE *ecdsaresp;    /* output stream to the RESPONSE file */
     char curve[16];     /* "nistxddd" */
     ECPublicKey ecpub;
     unsigned int i, j;
-    unsigned int flen;  /* length in bytes of the field size */
-    unsigned int olen;  /* length in bytes of the base point order */
+    unsigned int flen = 0;  /* length in bytes of the field size */
+    unsigned int olen = 0;  /* length in bytes of the base point order */
     unsigned char msg[512];  /* message that was signed (<= 128 bytes) */
-    unsigned int msglen;
-    unsigned char sha1[20];  /* SHA-1 hash (160 bits) */
+    unsigned int msglen = 0;
+    unsigned char  sha[HASH_LENGTH_MAX];    /* SHA digest */
+    unsigned int   shaLength = 0;           /* length of SHA */
+    HASH_HashType  shaAlg = HASH_AlgNULL;   /* type of SHA Alg */
     unsigned char sig[2*MAX_ECKEY_LEN];
     SECItem signature, digest;
     PRBool keyvalid = PR_TRUE;
     PRBool sigvalid = PR_TRUE;
 
     ecdsareq = fopen(reqfn, "r");
     ecdsaresp = stdout;
     ecpub.ecParams.arena = NULL;
     strcpy(curve, "nist");
     while (fgets(buf, sizeof buf, ecdsareq) != NULL) {
-	/* a comment or blank line */
-	if (buf[0] == '#' || buf[0] == '\n') {
-	    fputs(buf, ecdsaresp);
-	    continue;
-	}
-	/* [X-ddd] */
-	if (buf[0] == '[') {
-	    const char *src;
-	    char *dst;
-	    SECItem *encodedparams;
-	    ECParams *ecparams;
-
-	    src = &buf[1];
-	    dst = &curve[4];
-	    *dst++ = tolower(*src);
-	    src += 2;  /* skip the hyphen */
-	    *dst++ = *src++;
-	    *dst++ = *src++;
-	    *dst++ = *src++;
-	    *dst = '\0';
-	    encodedparams = getECParams(curve);
-	    if (encodedparams == NULL) {
-		goto loser;
-	    }
-	    if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
-		goto loser;
-	    }
-	    SECITEM_FreeItem(encodedparams, PR_TRUE);
-	    if (ecpub.ecParams.arena != NULL) {
-		PORT_FreeArena(ecpub.ecParams.arena, PR_FALSE);
-	    }
-	    ecpub.ecParams.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-	    if (ecpub.ecParams.arena == NULL) {
-		goto loser;
-	    }
-	    if (EC_CopyParams(ecpub.ecParams.arena, &ecpub.ecParams, ecparams)
-		!= SECSuccess) {
-		goto loser;
-	    }
-	    PORT_FreeArena(ecparams->arena, PR_FALSE);
-	    flen = (ecpub.ecParams.fieldID.size + 7) >> 3;
-	    olen = ecpub.ecParams.order.len;
-	    if (2*olen > sizeof sig) {
-		goto loser;
-	    }
-	    ecpub.publicValue.type = siBuffer;
-	    ecpub.publicValue.data = NULL;
-	    ecpub.publicValue.len = 0;
-	    SECITEM_AllocItem(ecpub.ecParams.arena,
-			      &ecpub.publicValue, 2*flen+1);
-	    if (ecpub.publicValue.data == NULL) {
-		goto loser;
-	    }
-	    ecpub.publicValue.data[0] = EC_POINT_FORM_UNCOMPRESSED;
-	    fputs(buf, ecdsaresp);
-	    continue;
-	}
-	/* Msg = ... */
-	if (strncmp(buf, "Msg", 3) == 0) {
-	    i = 3;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; isxdigit(buf[i]); i+=2,j++) {
-		hex_to_byteval(&buf[i], &msg[j]);
-	    }
-	    msglen = j;
-	    if (SHA1_HashBuf(sha1, msg, msglen) != SECSuccess) {
-		goto loser;
-	    }
-	    fputs(buf, ecdsaresp);
-
-	    digest.type = siBuffer;
-	    digest.data = sha1;
-	    digest.len = sizeof sha1;
-
-	    continue;
-	}
-	/* Qx = ... */
-	if (strncmp(buf, "Qx", 2) == 0) {
-	    fputs(buf, ecdsaresp);
-	    i = 2;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    keyvalid = from_hex_str(&ecpub.publicValue.data[1], flen,
-				    &buf[i]);
-	    continue;
-	}
-	/* Qy = ... */
-	if (strncmp(buf, "Qy", 2) == 0) {
-	    fputs(buf, ecdsaresp);
-	    if (!keyvalid) {
-		continue;
-	    }
-	    i = 2;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    keyvalid = from_hex_str(&ecpub.publicValue.data[1+flen], flen,
-				    &buf[i]);
-	    if (!keyvalid) {
-		continue;
-	    }
-	    if (EC_ValidatePublicKey(&ecpub.ecParams, &ecpub.publicValue)
-		!= SECSuccess) {
-		if (PORT_GetError() == SEC_ERROR_BAD_KEY) {
-		    keyvalid = PR_FALSE;
-		} else {
-		    goto loser;
-		}
-	    }
-	    continue;
-	}
-	/* R = ... */
-	if (buf[0] == 'R') {
-	    fputs(buf, ecdsaresp);
-	    i = 1;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    sigvalid = from_hex_str(sig, olen, &buf[i]);
-	    continue;
-	}
-	/* S = ... */
-	if (buf[0] == 'S') {
-	    fputs(buf, ecdsaresp);
-	    i = 1;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    if (sigvalid) {
-		sigvalid = from_hex_str(&sig[olen], olen, &buf[i]);
-	    }
-	    signature.type = siBuffer;
-	    signature.data = sig;
-	    signature.len = 2*olen;
-
-	    if (!keyvalid || !sigvalid) {
-		fputs("Result = F\n", ecdsaresp);
-	    } else if (ECDSA_VerifyDigest(&ecpub, &signature, &digest)
-		== SECSuccess) {
-		fputs("Result = P\n", ecdsaresp);
-	    } else {
-		fputs("Result = F\n", ecdsaresp);
-	    }
-	    continue;
-	}
+        /* a comment or blank line */
+        if (buf[0] == '#' || buf[0] == '\n') {
+            fputs(buf, ecdsaresp);
+            continue;
+        }
+        /* [X-ddd] */
+        if (buf[0] == '[') {
+            const char *src;
+            char *dst;
+            SECItem *encodedparams;
+            ECParams *ecparams;
+
+            src = &buf[1];
+            dst = &curve[4];
+            *dst++ = tolower(*src);
+            src += 2;  /* skip the hyphen */
+            *dst++ = *src++;
+            *dst++ = *src++;
+            *dst++ = *src++;
+            *dst = '\0';
+            src++; /* skip the comma */
+            /* set the SHA Algorithm */
+            if (strncmp(src, "SHA-1", 5) == 0) {
+                shaAlg = HASH_AlgSHA1;
+            } else if (strncmp(src, "SHA-224", 7) == 0) {
+                shaAlg = HASH_AlgSHA224;
+            } else if (strncmp(src, "SHA-256", 7) == 0) {
+                shaAlg = HASH_AlgSHA256;
+            } else if (strncmp(src, "SHA-384", 7)== 0) {
+               shaAlg = HASH_AlgSHA384;
+            } else if (strncmp(src, "SHA-512", 7) == 0) {
+               shaAlg = HASH_AlgSHA512;
+            } else {
+               fprintf(ecdsaresp, "ERROR: Unable to find SHAAlg type");
+               goto loser;
+            }
+            encodedparams = getECParams(curve);
+            if (encodedparams == NULL) {
+                fprintf(stderr, "Unknown curve %s.", curve);
+                goto loser;
+            }
+            if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
+                fprintf(stderr, "Curve %s not supported.\n", curve);
+                goto loser;
+            }
+            SECITEM_FreeItem(encodedparams, PR_TRUE);
+            if (ecpub.ecParams.arena != NULL) {
+                PORT_FreeArena(ecpub.ecParams.arena, PR_FALSE);
+            }
+            ecpub.ecParams.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+            if (ecpub.ecParams.arena == NULL) {
+                goto loser;
+            }
+            if (EC_CopyParams(ecpub.ecParams.arena, &ecpub.ecParams, ecparams)
+                != SECSuccess) {
+                goto loser;
+            }
+            PORT_FreeArena(ecparams->arena, PR_FALSE);
+            flen = (ecpub.ecParams.fieldID.size + 7) >> 3;
+            olen = ecpub.ecParams.order.len;
+            if (2*olen > sizeof sig) {
+                goto loser;
+            }
+            ecpub.publicValue.type = siBuffer;
+            ecpub.publicValue.data = NULL;
+            ecpub.publicValue.len = 0;
+            SECITEM_AllocItem(ecpub.ecParams.arena,
+                              &ecpub.publicValue, 2*flen+1);
+            if (ecpub.publicValue.data == NULL) {
+                goto loser;
+            }
+            ecpub.publicValue.data[0] = EC_POINT_FORM_UNCOMPRESSED;
+            fputs(buf, ecdsaresp);
+            continue;
+        }
+        /* Msg = ... */
+        if (strncmp(buf, "Msg", 3) == 0) {
+            i = 3;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; isxdigit(buf[i]); i+=2,j++) {
+                hex_to_byteval(&buf[i], &msg[j]);
+            }
+            msglen = j;
+            shaLength = fips_hashLen(shaAlg);
+            if (fips_hashBuf(shaAlg,sha,msg,msglen) != SECSuccess) {
+                if (shaLength == 0) {
+                        fprintf(ecdsaresp, "ERROR: SHAAlg not defined.");
+                }
+                fprintf(ecdsaresp, "ERROR: Unable to generate SHA%x",
+                        shaLength == 160 ? 1 : shaLength);
+                goto loser;
+            }
+            fputs(buf, ecdsaresp);
+
+            digest.type = siBuffer;
+            digest.data = sha;
+            digest.len = shaLength;
+
+            continue;
+        }
+        /* Qx = ... */
+        if (strncmp(buf, "Qx", 2) == 0) {
+            fputs(buf, ecdsaresp);
+            i = 2;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            keyvalid = from_hex_str(&ecpub.publicValue.data[1], flen,
+                                    &buf[i]);
+            continue;
+        }
+        /* Qy = ... */
+        if (strncmp(buf, "Qy", 2) == 0) {
+            fputs(buf, ecdsaresp);
+            if (!keyvalid) {
+                continue;
+            }
+            i = 2;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            keyvalid = from_hex_str(&ecpub.publicValue.data[1+flen], flen,
+                                    &buf[i]);
+            if (!keyvalid) {
+                continue;
+            }
+            if (EC_ValidatePublicKey(&ecpub.ecParams, &ecpub.publicValue)
+                != SECSuccess) {
+                if (PORT_GetError() == SEC_ERROR_BAD_KEY) {
+                    keyvalid = PR_FALSE;
+                } else {
+                    goto loser;
+                }
+            }
+            continue;
+        }
+        /* R = ... */
+        if (buf[0] == 'R') {
+            fputs(buf, ecdsaresp);
+            i = 1;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            sigvalid = from_hex_str(sig, olen, &buf[i]);
+            continue;
+        }
+        /* S = ... */
+        if (buf[0] == 'S') {
+            fputs(buf, ecdsaresp);
+            i = 1;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            if (sigvalid) {
+                sigvalid = from_hex_str(&sig[olen], olen, &buf[i]);
+            }
+            signature.type = siBuffer;
+            signature.data = sig;
+            signature.len = 2*olen;
+
+            if (!keyvalid || !sigvalid) {
+                fputs("Result = F\n", ecdsaresp);
+            } else if (ECDSA_VerifyDigest(&ecpub, &signature, &digest)
+                == SECSuccess) {
+                fputs("Result = P\n", ecdsaresp);
+            } else {
+                fputs("Result = F\n", ecdsaresp);
+            }
+            continue;
+        }
     }
 loser:
     if (ecpub.ecParams.arena != NULL) {
-	PORT_FreeArena(ecpub.ecParams.arena, PR_FALSE);
+        PORT_FreeArena(ecpub.ecParams.arena, PR_FALSE);
     }
     fclose(ecdsareq);
 }
 #endif /* NSS_DISABLE_ECC */
 
-
-/*
- * Read a value from the test and allocate the result.
- */
-static unsigned char *
-alloc_value(char *buf, int *len)
-{
-    unsigned char * value;
-    int i, count;
-
-    if (strncmp(buf, "<None>", 6) == 0) {
-	*len = 0;
-	return NULL;
-    }
-
-    /* find the length of the number */
-    for (count = 0; isxdigit(buf[count]); count++);
-    *len = count/2;
-
-    if (*len == 0) {
-	return NULL;
-    }
-
-    value = PORT_Alloc(*len);
-    if (!value) {
-	*len = 0;
-	return NULL;
-    }
-	
-    for (i=0; i<*len; buf+=2 , i++) {
-	hex_to_byteval(buf, &value[i]);
-    }
-    
-
-    return value;
-}
-
 PRBool
 isblankline(char *b)
 {
    while (isspace(*b)) b++;
    if ((*b == '\n') || (*b == 0)) {
-	return PR_TRUE;
+        return PR_TRUE;
    }
    return PR_FALSE;
 }
 
 static int debug = 0;
 
 /*
  * Perform the Hash_DRBG (CAVS) for the RNG algorithm
@@ -2594,112 +2971,114 @@ drbg(char *reqfn)
     char buf[2000];   /* test case has some very long lines, returned bits
      * as high as 800 bytes (6400 bits). That 1600 byte
      * plus a tag */
     char buf2[2000]; 
     FILE *rngreq;       /* input stream from the REQUEST file */
     FILE *rngresp;      /* output stream to the RESPONSE file */
     
     unsigned int i, j;
+#ifdef HANDLE_PREDICTION_RESISTANCE
     PRBool predictionResistance = PR_FALSE;
+#endif
     unsigned char *nonce =  NULL;
     int nonceLen = 0;
     unsigned char *personalizationString =  NULL;
     int personalizationStringLen = 0;
     unsigned char *additionalInput =  NULL;
     int additionalInputLen = 0;
     unsigned char *entropyInput = NULL;
     int entropyInputLen = 0;
-    unsigned char predictedreturn_bytes[SHA256_LENGTH];
-    unsigned char return_bytes[SHA256_LENGTH];
-    int return_bytes_len = SHA256_LENGTH;
+    unsigned char *predictedreturn_bytes = NULL;
+    unsigned char *return_bytes = NULL;
+    int return_bytes_len = 0;
     enum { NONE, INSTANTIATE, GENERATE, RESEED, RESULT } command =
     NONE;
     PRBool genResult = PR_FALSE;
     SECStatus rv;
     
     rngreq = fopen(reqfn, "r");
     rngresp = stdout;
     while (fgets(buf, sizeof buf, rngreq) != NULL) {
        switch (command) {
             case INSTANTIATE:
-		if (debug) {
-		    fputs("# PRNGTEST_Instantiate(",rngresp);
-		    to_hex_str(buf2,entropyInput, entropyInputLen);
-		    fputs(buf2,rngresp);
-		    fprintf(rngresp,",%d,",entropyInputLen);
-		    to_hex_str(buf2,nonce, nonceLen);
-		    fputs(buf2,rngresp);
-		    fprintf(rngresp,",%d,",nonceLen);
-		    to_hex_str(buf2,personalizationString, 
-					personalizationStringLen);
-		    fputs(buf2,rngresp);
-		    fprintf(rngresp,",%d)\n", personalizationStringLen);
-		}
+                if (debug) {
+                    fputs("# PRNGTEST_Instantiate(",rngresp);
+                    to_hex_str(buf2,entropyInput, entropyInputLen);
+                    fputs(buf2,rngresp);
+                    fprintf(rngresp,",%d,",entropyInputLen);
+                    to_hex_str(buf2,nonce, nonceLen);
+                    fputs(buf2,rngresp);
+                    fprintf(rngresp,",%d,",nonceLen);
+                    to_hex_str(buf2,personalizationString, 
+                                        personalizationStringLen);
+                    fputs(buf2,rngresp);
+                    fprintf(rngresp,",%d)\n", personalizationStringLen);
+                }
                 rv = PRNGTEST_Instantiate(entropyInput, entropyInputLen,
                                           nonce, nonceLen,
                                           personalizationString, 
-				          personalizationStringLen);
+                                          personalizationStringLen);
                 if (rv != SECSuccess) {
                     goto loser;
                 }
                 break;
                     
             case GENERATE:
             case RESULT:
                 memset(return_bytes, 0, return_bytes_len);
-		if (debug) {
-		    fputs("# PRNGTEST_Generate(returnbytes",rngresp);
-		    fprintf(rngresp,",%d,", return_bytes_len);
-		    to_hex_str(buf2,additionalInput, additionalInputLen);
-		    fputs(buf2,rngresp);
-		    fprintf(rngresp,",%d)\n",additionalInputLen);
-		}
+                if (debug) {
+                    fputs("# PRNGTEST_Generate(returnbytes",rngresp);
+                    fprintf(rngresp,",%d,", return_bytes_len);
+                    to_hex_str(buf2,additionalInput, additionalInputLen);
+                    fputs(buf2,rngresp);
+                    fprintf(rngresp,",%d)\n",additionalInputLen);
+                }
                 rv = PRNGTEST_Generate((PRUint8 *) return_bytes, 
-					return_bytes_len,
+                                        return_bytes_len,
                                        (PRUint8 *) additionalInput, 
-					additionalInputLen);
+                                        additionalInputLen);
                 if (rv != SECSuccess) {
                     goto loser;
                 }
                     
                 if (command == RESULT) {
                     fputs("ReturnedBits = ", rngresp);
                     to_hex_str(buf2, return_bytes, return_bytes_len);
                     fputs(buf2, rngresp);
                     fputc('\n', rngresp);
-		    if (debug) {
-			fputs("# PRNGTEST_Uninstantiate()\n",rngresp);
-		    }
+                    if (debug) {
+                        fputs("# PRNGTEST_Uninstantiate()\n",rngresp);
+                    }
                     rv = PRNGTEST_Uninstantiate();
                     if (rv != SECSuccess) {
                         goto loser;
                     }
                 } else if (debug) {
                     fputs("#ReturnedBits = ", rngresp);
                     to_hex_str(buf2, return_bytes, return_bytes_len);
                     fputs(buf2, rngresp);
                     fputc('\n', rngresp);
-		}
+                }
                     
                 memset(additionalInput, 0, additionalInputLen);
                 break;
                     
             case RESEED:
                 if (entropyInput || additionalInput) {
-		    if (debug) {
-			fputs("# PRNGTEST_Reseed(",rngresp);
-			fprintf(rngresp,",%d,", return_bytes_len);
-			to_hex_str(buf2,entropyInput, entropyInputLen);
-			fputs(buf2,rngresp);
-			fprintf(rngresp,",%d,", entropyInputLen);
-			to_hex_str(buf2,additionalInput, additionalInputLen);
-			fputs(buf2,rngresp);
-			fprintf(rngresp,",%d)\n",additionalInputLen);
-		    }	
+                    if (debug) {
+                        fputs("# PRNGTEST_Reseed(",rngresp);
+                        fprintf(rngresp,",%d,", return_bytes_len);
+                        to_hex_str(buf2,entropyInput, entropyInputLen);
+                        fputs(buf2,rngresp);
+                        fprintf(rngresp,",%d,", entropyInputLen);
+                        to_hex_str(buf2,additionalInput, additionalInputLen);
+                        fputs(buf2,rngresp);
+                        fprintf(rngresp,",%d)\n",additionalInputLen);
+                    }        
                     rv = PRNGTEST_Reseed(entropyInput, entropyInputLen,
                                              additionalInput, additionalInputLen);
                     if (rv != SECSuccess) {
                         goto loser;
                     }
                 }
                 memset(entropyInput, 0, entropyInputLen);
                 memset(additionalInput, 0, additionalInputLen);
@@ -2718,40 +3097,64 @@ drbg(char *reqfn)
         
         /* [Hash - SHA256] */
         if (strncmp(buf, "[SHA-256]", 9) == 0) {
             fputs(buf, rngresp);
             continue;
         }
         
         if (strncmp(buf, "[PredictionResistance", 21)  == 0) {
+#ifdef HANDLE_PREDICTION_RESISTANCE
             i = 21;
             while (isspace(buf[i]) || buf[i] == '=') {
                 i++;
             }    
             if (strncmp(buf, "False", 5) == 0) {
                 predictionResistance = PR_FALSE;
             } else {
                 predictionResistance = PR_TRUE;
             }
+#endif
             
             fputs(buf, rngresp);
             continue;
         }
+
+        if (strncmp(buf, "[ReturnedBitsLen", 16)  == 0) {
+            if (return_bytes) {
+                PORT_ZFree(return_bytes, return_bytes_len);
+                return_bytes = NULL;
+            }
+	    if (predictedreturn_bytes) {
+                PORT_ZFree(predictedreturn_bytes, return_bytes_len);
+                predictedreturn_bytes = NULL;
+            }
+            return_bytes_len = 0;
+            if (sscanf(buf, "[ReturnedBitsLen = %d]", &return_bytes_len) != 1) {
+                goto loser;
+            }
+            return_bytes_len = return_bytes_len/8;
+            if (return_bytes_len > 0) {
+                return_bytes = PORT_Alloc(return_bytes_len);
+                predictedreturn_bytes = PORT_Alloc(return_bytes_len);
+            }
+            fputs(buf, rngresp);
+            continue;
+        }
         
         if (strncmp(buf, "[EntropyInputLen", 16)  == 0) {
             if (entropyInput) {
                 PORT_ZFree(entropyInput, entropyInputLen);
                 entropyInput = NULL;
                 entropyInputLen = 0;
             }
             if (sscanf(buf, "[EntropyInputLen = %d]", &entropyInputLen) != 1) {
                 goto loser;
             }
-	    entropyInputLen = entropyInputLen/8;
+            entropyInputLen = entropyInputLen/8;
             if (entropyInputLen > 0) {
                 entropyInput = PORT_Alloc(entropyInputLen);
             }
             fputs(buf, rngresp);
             continue;
         }
         
         if (strncmp(buf, "[NonceLen", 9)  == 0) {
@@ -2759,17 +3162,17 @@ drbg(char *reqfn)
                 PORT_ZFree(nonce, nonceLen);
                 nonce = NULL;
                 nonceLen = 0;
             }
             
             if (sscanf(buf, "[NonceLen = %d]", &nonceLen) != 1) {
                 goto loser;
             }
-	    nonceLen = nonceLen/8;
+            nonceLen = nonceLen/8;
             if (nonceLen > 0) {
                 nonce = PORT_Alloc(nonceLen);
             }               
             fputs(buf, rngresp);
             continue;
         }
         
         if (strncmp(buf, "[PersonalizationStringLen", 16)  == 0) {
@@ -2777,17 +3180,17 @@ drbg(char *reqfn)
                 PORT_ZFree(personalizationString, personalizationStringLen);
                 personalizationString = NULL;
                 personalizationStringLen = 0;
             }
             
             if (sscanf(buf, "[PersonalizationStringLen = %d]", &personalizationStringLen) != 1) {
                 goto loser;
             }
-	    personalizationStringLen = personalizationStringLen / 8;
+            personalizationStringLen = personalizationStringLen / 8;
             if (personalizationStringLen > 0) {
                 personalizationString = PORT_Alloc(personalizationStringLen);
             }
             fputs(buf, rngresp);
             
             continue;
         }
         
@@ -2796,17 +3199,17 @@ drbg(char *reqfn)
                 PORT_ZFree(additionalInput, additionalInputLen);
                 additionalInput = NULL;
                 additionalInputLen = 0;
             }
             
             if (sscanf(buf, "[AdditionalInputLen = %d]", &additionalInputLen) != 1) {
                 goto loser;
             }
-	    additionalInputLen = additionalInputLen/8;
+            additionalInputLen = additionalInputLen/8;
             if (additionalInputLen > 0) {
                 additionalInput = PORT_Alloc(additionalInputLen);
             }
             fputs(buf, rngresp);
             continue;
         }
         
         if (strncmp(buf, "COUNT", 5) == 0) {
@@ -2933,38 +3336,38 @@ drbg(char *reqfn)
                 i++;
             }
             for (j=0; isxdigit(buf[i]); i+=2,j++) { /*j<additionalInputLen*/
                 hex_to_byteval(&buf[i], &predictedreturn_bytes[j]);
             }          
 
             if (memcmp(return_bytes, 
                        predictedreturn_bytes, return_bytes_len) != 0) {
-		if (debug) {
+                if (debug) {
                 fprintf(rngresp, "# Generate failed:\n");
                 fputs(  "#   predicted=", rngresp);
                 to_hex_str(buf, predictedreturn_bytes, 
                            return_bytes_len);
                 fputs(buf, rngresp);
                 fputs("\n#   actual  = ", rngresp);
                 fputs(buf2, rngresp);
                 fputc('\n', rngresp);
 
-		} else {
+                } else {
                 fprintf(stderr, "Generate failed:\n");
                 fputs(  "   predicted=", stderr);
                 to_hex_str(buf, predictedreturn_bytes, 
                            return_bytes_len);
                 fputs(buf, stderr);
                 fputs("\n   actual  = ", stderr);
                 fputs(buf2, stderr);
                 fputc('\n', stderr);
-		}
-            }
-            memset(predictedreturn_bytes, 0 , sizeof predictedreturn_bytes);
+                }
+            }
+            memset(predictedreturn_bytes, 0 , return_bytes_len);
 
             continue;
         }
     }
 loser:
     fclose(rngreq);
 }
 
@@ -2985,112 +3388,112 @@ rng_vst(char *reqfn)
                          * needs to be large enough to hold the longest
                          * line "XSeed = <128 hex digits>\n".
                          */
     FILE *rngreq;       /* input stream from the REQUEST file */
     FILE *rngresp;      /* output stream to the RESPONSE file */
     unsigned int i, j;
     unsigned char Q[DSA1_SUBPRIME_LEN];
     PRBool hasQ = PR_FALSE;
-    unsigned int b;  /* 160 <= b <= 512, b is a multiple of 8 */
+    unsigned int b = 0;  /* 160 <= b <= 512, b is a multiple of 8 */
     unsigned char XKey[512/8];
     unsigned char XSeed[512/8];
     unsigned char GENX[DSA1_SIGNATURE_LEN];
     unsigned char DSAX[DSA1_SUBPRIME_LEN];
     SECStatus rv;
 
     rngreq = fopen(reqfn, "r");
     rngresp = stdout;
     while (fgets(buf, sizeof buf, rngreq) != NULL) {
-	/* a comment or blank line */
-	if (buf[0] == '#' || buf[0] == '\n') {
-	    fputs(buf, rngresp);
-	    continue;
-	}
-	/* [Xchange - SHA1] */
-	if (buf[0] == '[') {
-	    fputs(buf, rngresp);
-	    continue;
-	}
-	/* Q = ... */
-	if (buf[0] == 'Q') {
-	    i = 1;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; j<sizeof Q; i+=2,j++) {
-		hex_to_byteval(&buf[i], &Q[j]);
-	    }
-	    fputs(buf, rngresp);
-	    hasQ = PR_TRUE;
-	    continue;
-	}
-	/* "COUNT = x" begins a new data set */
-	if (strncmp(buf, "COUNT", 5) == 0) {
-	    /* zeroize the variables for the test with this data set */
-	    b = 0;
-	    memset(XKey, 0, sizeof XKey);
-	    memset(XSeed, 0, sizeof XSeed);
-	    fputs(buf, rngresp);
-	    continue;
-	}
-	/* b = ... */
-	if (buf[0] == 'b') {
-	    i = 1;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    b = atoi(&buf[i]);
-	    if (b < 160 || b > 512 || b%8 != 0) {
-		goto loser;
-	    }
-	    fputs(buf, rngresp);
-	    continue;
-	}
-	/* XKey = ... */
-	if (strncmp(buf, "XKey", 4) == 0) {
-	    i = 4;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; j<b/8; i+=2,j++) {
-		hex_to_byteval(&buf[i], &XKey[j]);
-	    }
-	    fputs(buf, rngresp);
-	    continue;
-	}
-	/* XSeed = ... */
-	if (strncmp(buf, "XSeed", 5) == 0) {
-	    i = 5;
-	    while (isspace(buf[i]) || buf[i] == '=') {
-		i++;
-	    }
-	    for (j=0; j<b/8; i+=2,j++) {
-		hex_to_byteval(&buf[i], &XSeed[j]);
-	    }
-	    fputs(buf, rngresp);
-
-	    rv = FIPS186Change_GenerateX(XKey, XSeed, GENX);
-	    if (rv != SECSuccess) {
-		goto loser;
-	    }
-	    fputs("X = ", rngresp);
-	    if (hasQ) {
-		rv = FIPS186Change_ReduceModQForDSA(GENX, Q, DSAX);
-		if (rv != SECSuccess) {
-		    goto loser;
-		}
-		to_hex_str(buf, DSAX, sizeof DSAX);
-	    } else {
-		to_hex_str(buf, GENX, sizeof GENX);
-	    }
-	    fputs(buf, rngresp);
-	    fputc('\n', rngresp);
-	    continue;
-	}
+        /* a comment or blank line */
+        if (buf[0] == '#' || buf[0] == '\n') {
+            fputs(buf, rngresp);
+            continue;
+        }
+        /* [Xchange - SHA1] */
+        if (buf[0] == '[') {
+            fputs(buf, rngresp);
+            continue;
+        }
+        /* Q = ... */
+        if (buf[0] == 'Q') {
+            i = 1;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<sizeof Q; i+=2,j++) {
+                hex_to_byteval(&buf[i], &Q[j]);
+            }
+            fputs(buf, rngresp);
+            hasQ = PR_TRUE;
+            continue;
+        }
+        /* "COUNT = x" begins a new data set */
+        if (strncmp(buf, "COUNT", 5) == 0) {
+            /* zeroize the variables for the test with this data set */
+            b = 0;
+            memset(XKey, 0, sizeof XKey);
+            memset(XSeed, 0, sizeof XSeed);
+            fputs(buf, rngresp);
+            continue;
+        }
+        /* b = ... */
+        if (buf[0] == 'b') {
+            i = 1;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            b = atoi(&buf[i]);
+            if (b < 160 || b > 512 || b%8 != 0) {
+                goto loser;
+            }
+            fputs(buf, rngresp);
+            continue;
+        }
+        /* XKey = ... */
+        if (strncmp(buf, "XKey", 4) == 0) {
+            i = 4;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<b/8; i+=2,j++) {
+                hex_to_byteval(&buf[i], &XKey[j]);
+            }
+            fputs(buf, rngresp);
+            continue;
+        }
+        /* XSeed = ... */
+        if (strncmp(buf, "XSeed", 5) == 0) {
+            i = 5;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<b/8; i+=2,j++) {
+                hex_to_byteval(&buf[i], &XSeed[j]);
+            }
+            fputs(buf, rngresp);
+
+            rv = FIPS186Change_GenerateX(XKey, XSeed, GENX);
+            if (rv != SECSuccess) {
+                goto loser;
+            }
+            fputs("X = ", rngresp);
+            if (hasQ) {
+                rv = FIPS186Change_ReduceModQForDSA(GENX, Q, DSAX);
+                if (rv != SECSuccess) {
+                    goto loser;
+                }
+                to_hex_str(buf, DSAX, sizeof DSAX);
+            } else {
+                to_hex_str(buf, GENX, sizeof GENX);
+            }
+            fputs(buf, rngresp);
+            fputc('\n', rngresp);
+            continue;
+        }
     }
 loser:
     fclose(rngreq);
 }
 
 /*
  * Perform the RNG Monte Carlo Test (MCT) for the RNG algorithm
  * "DSA - Generation of X", used both as specified and as a generic
@@ -3108,17 +3511,17 @@ rng_mct(char *reqfn)
                          * needs to be large enough to hold the longest
                          * line "XSeed = <128 hex digits>\n".
                          */
     FILE *rngreq;       /* input stream from the REQUEST file */
     FILE *rngresp;      /* output stream to the RESPONSE file */
     unsigned int i, j;
     unsigned char Q[DSA1_SUBPRIME_LEN];
     PRBool hasQ = PR_FALSE;
-    unsigned int b;  /* 160 <= b <= 512, b is a multiple of 8 */
+    unsigned int b = 0;  /* 160 <= b <= 512, b is a multiple of 8 */
     unsigned char XKey[512/8];
     unsigned char XSeed[512/8];
     unsigned char GENX[2*SHA1_LENGTH];
     unsigned char DSAX[DSA1_SUBPRIME_LEN];
     SECStatus rv;
 
     rngreq = fopen(reqfn, "r");
     rngresp = stdout;
@@ -3213,131 +3616,16 @@ rng_mct(char *reqfn)
 	    continue;
 	}
     }
 loser:
     fclose(rngreq);
 }
 
 /*
- * HASH_ functions are available to full NSS apps and internally inside
- * freebl, but not exported to users of freebl. Create short stubs to
- * replace the functionality for fipstest.
- */
-SECStatus
-fips_hashBuf(HASH_HashType type, unsigned char *hashBuf, 
-					unsigned char *msg, int len)
-{
-    SECStatus rv = SECFailure;
-
-    switch (type) {
-    case HASH_AlgSHA1:
-	rv = SHA1_HashBuf(hashBuf, msg, len);
-	break;
-    case HASH_AlgSHA224:
-	rv = SHA224_HashBuf(hashBuf, msg, len);
-	break;
-    case HASH_AlgSHA256:
-	rv = SHA256_HashBuf(hashBuf, msg, len);
-	break;
-    case HASH_AlgSHA384:
-	rv = SHA384_HashBuf(hashBuf, msg, len);
-	break;
-    case HASH_AlgSHA512:
-	rv = SHA512_HashBuf(hashBuf, msg, len);
-	break;
-    default:
-	break;
-    }
-    return rv;
-}
-
-int
-fips_hashLen(HASH_HashType type)
-{
-    int len = 0;
-
-    switch (type) {
-    case HASH_AlgSHA1:
-	len = SHA1_LENGTH;
-	break;
-    case HASH_AlgSHA224:
-	len = SHA224_LENGTH;
-	break;
-    case HASH_AlgSHA256:
-	len = SHA256_LENGTH;
-	break;
-    case HASH_AlgSHA384:
-	len = SHA384_LENGTH;
-	break;
-    case HASH_AlgSHA512:
-	len = SHA512_LENGTH;
-	break;
-    default:
-	break;
-    }
-    return len;
-}
-
-SECOidTag
-fips_hashOid(HASH_HashType type)
-{
-    SECOidTag oid = SEC_OID_UNKNOWN;
-
-    switch (type) {
-    case HASH_AlgSHA1:
-	oid = SEC_OID_SHA1;
-	break;
-    case HASH_AlgSHA224:
-	oid = SEC_OID_SHA224;
-	break;
-    case HASH_AlgSHA256:
-	oid = SEC_OID_SHA256;
-	break;
-    case HASH_AlgSHA384:
-	oid = SEC_OID_SHA384;
-	break;
-    case HASH_AlgSHA512:
-	oid = SEC_OID_SHA512;
-	break;
-    default:
-	break;
-    }
-    return oid;
-}
-
-HASH_HashType
-sha_get_hashType(int hashbits)
-{
-    HASH_HashType hashType = HASH_AlgNULL;
-
-    switch (hashbits) {
-    case 1:
-    case (SHA1_LENGTH*PR_BITS_PER_BYTE):
-	hashType = HASH_AlgSHA1;
-	break;
-    case (SHA224_LENGTH*PR_BITS_PER_BYTE):
-	hashType = HASH_AlgSHA224;
-	break;
-    case (SHA256_LENGTH*PR_BITS_PER_BYTE):
-	hashType = HASH_AlgSHA256;
-	break;
-    case (SHA384_LENGTH*PR_BITS_PER_BYTE):
-	hashType = HASH_AlgSHA384;
-	break;
-    case (SHA512_LENGTH*PR_BITS_PER_BYTE):
-	hashType = HASH_AlgSHA512;
-	break;
-    default:
-	break;
-    }
-    return hashType;
-}
-
-/*
  * Calculate the SHA Message Digest 
  *
  * MD = Message digest 
  * MDLen = length of Message Digest and SHA_Type
  * msg = message to digest 
  * msgLen = length of message to digest
  */
 SECStatus sha_calcMD(unsigned char *MD, unsigned int MDLen, unsigned char *msg, unsigned int msgLen) 
@@ -3411,20 +3699,20 @@ SECStatus sha_mct_test(unsigned int MDLe
  *
  * reqfn is the pathname of the input REQUEST file.
  *
  * The output RESPONSE file is written to stdout.
  */
 void sha_test(char *reqfn) 
 {
     unsigned int i, j;
-    unsigned int MDlen;   /* the length of the Message Digest in Bytes  */
-    unsigned int msgLen;  /* the length of the input Message in Bytes */
+    unsigned int MDlen = 0;   /* the length of the Message Digest in Bytes  */
+    unsigned int msgLen = 0;  /* the length of the input Message in Bytes */
     unsigned char *msg = NULL; /* holds the message to digest.*/
-    size_t bufSize = 25608; /*MAX buffer size */
+    size_t bufSize = 256*128; /*MAX buffer size */
     char *buf = NULL;      /* holds one line from the input REQUEST file.*/
     unsigned char seed[HASH_LENGTH_MAX];   /* max size of seed 64 bytes */
     unsigned char MD[HASH_LENGTH_MAX];     /* message digest */
 
     FILE *req = NULL;  /* input stream from the REQUEST file */
     FILE *resp;        /* output stream to the RESPONSE file */
 
     buf = PORT_ZAlloc(bufSize);
@@ -3589,28 +3877,28 @@ hmac_calc(unsigned char *hmac_computed,
  *
  * The output RESPONSE file is written to stdout.
  */
 void hmac_test(char *reqfn) 
 {
     unsigned int i, j;
     size_t bufSize =      400;    /* MAX buffer size */
     char *buf = NULL;  /* holds one line from the input REQUEST file.*/
-    unsigned int keyLen;          /* Key Length */  
+    unsigned int keyLen = 0;      /* Key Length */  
     unsigned char key[200];       /* key MAX size = 184 */
     unsigned int msgLen = 128;    /* the length of the input  */
                                   /*  Message is always 128 Bytes */
     unsigned char *msg = NULL;    /* holds the message to digest.*/
-    unsigned int HMACLen;         /* the length of the HMAC Bytes  */
-    unsigned int TLen;            /* the length of the requested */
+    unsigned int HMACLen = 0;     /* the length of the HMAC Bytes  */
+    unsigned int TLen = 0;        /* the length of the requested */
                                   /* truncated HMAC Bytes */
     unsigned char HMAC[HASH_LENGTH_MAX];  /* computed HMAC */
     unsigned char expectedHMAC[HASH_LENGTH_MAX]; /* for .fax files that have */ 
                                                  /* supplied known answer */
-    HASH_HashType hash_alg;       /* HMAC type */
+    HASH_HashType hash_alg = HASH_AlgNULL;       /* HMAC type */
     
 
     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;
@@ -3721,17 +4009,17 @@ void hmac_test(char *reqfn)
                 hex_to_byteval(&buf[i], &msg[j]);
             }
            fputs(buf, resp);
            /* calculate the HMAC and output */ 
            if (hmac_calc(HMAC, HMACLen, key, keyLen,   
                          msg, msgLen, hash_alg) != SECSuccess) {
                goto loser;
            }
-           fputs("MAC = ", resp);
+           fputs("Mac = ", resp);
            to_hex_str(buf, HMAC, TLen);
            fputs(buf, resp);
            fputc('\n', resp);
            continue;
         }
     }
 loser:
     if (req) {
@@ -3786,48 +4074,48 @@ dsa_keypair_test(char *reqfn)
                 pqg = NULL;
             }
             if(vfy!=NULL) {
                 PQG_DestroyVerify(vfy);
                 vfy = NULL;
             }
 
             if (sscanf(buf, "[mod = L=%d, N=%d]", &L, &N) != 2) {
-		use_dsa1 = PR_TRUE;
+                use_dsa1 = PR_TRUE;
                 if (sscanf(buf, "[mod = %d]", &L) != 1) {
                     goto loser;
-		}
+                }
             }
             fputs(buf, dsaresp);
             fputc('\n', dsaresp);
 
-	    if (use_dsa1) {
+            if (use_dsa1) {
                 /*************************************************************
                  * PQG_ParamGenSeedLen doesn't take a key size, it takes an 
-		 * index that points to a valid key size.
+                 * index that points to a valid key size.
                  */
                 keySizeIndex = PQG_PBITS_TO_INDEX(L);
                 if(keySizeIndex == -1 || L<512 || L>1024) {
                    fprintf(dsaresp,
                         "DSA key size must be a multiple of 64 between 512 "
                         "and 1024, inclusive");
                     goto loser;
                 }
 
                 /* Generate the parameters P, Q, and G */
                 if (PQG_ParamGenSeedLen(keySizeIndex, PQG_TEST_SEED_BYTES,
                     &pqg, &vfy) != SECSuccess) {
                     fprintf(dsaresp, 
-				"ERROR: Unable to generate PQG parameters");
+                                "ERROR: Unable to generate PQG parameters");
                     goto loser;
                 }
-	    } else {
+            } else {
                 if (PQG_ParamGenV2(L, N, N, &pqg, &vfy) != SECSuccess) {
                     fprintf(dsaresp, 
-				"ERROR: Unable to generate PQG parameters");
+                                "ERROR: Unable to generate PQG parameters");
                     goto loser;
                 }
             }
 
             /* output P, Q, and G */
             to_hex_str(buf, pqg->prime.data, pqg->prime.len);
             fprintf(dsaresp, "P = %s\n", buf);
             to_hex_str(buf, pqg->subPrime.data, pqg->subPrime.len);
@@ -3866,17 +4154,17 @@ loser:
     fclose(dsareq);
 }
 
 /*
  * pqg generation type
  */
 typedef enum {
     FIPS186_1,/* Generate/Verify P,Q & G  according to FIPS 186-1 */
-    A_1_1_2, /* Generate Probable P & Q */
+    A_1_2_1, /* Generate Provable P & Q */
     A_1_1_3, /* Verify Probable P & Q */
     A_1_2_2, /* Verify Provable P & Q */
     A_2_1,   /* Generate Unverifiable G */
     A_2_2,   /* Assure Unverifiable G */
     A_2_3,   /* Generate Verifiable G */
     A_2_4    /* Verify Verifiable G */
 } dsa_pqg_type;
 
@@ -3896,17 +4184,17 @@ dsa_pqgver_test(char *reqfn)
                          */
     FILE *dsareq;     /* input stream from the REQUEST file */
     FILE *dsaresp;    /* output stream to the RESPONSE file */
     int N;
     int L;
     unsigned int i, j;
     PQGParams pqg;
     PQGVerify vfy;
-    unsigned int pghSize;        /* size for p, g, and h */
+    unsigned int pghSize = 0;    /* size for p, g, and h */
     dsa_pqg_type type = FIPS186_1;
 
     dsareq = fopen(reqfn, "r");
     dsaresp = stdout;
     memset(&pqg, 0, sizeof(pqg));
     memset(&vfy, 0, sizeof(vfy));
 
     while (fgets(buf, sizeof buf, dsareq) != NULL) {
@@ -3914,47 +4202,47 @@ dsa_pqgver_test(char *reqfn)
         if (buf[0] == '#' || buf[0] == '\n') {
             fputs(buf, dsaresp);
             continue;
         }
 
         /* [A.xxxxx ] */
         if (buf[0] == '['  && buf[1] == 'A') {
 
-	    if (strncmp(&buf[1],"A.1.1.3",7) == 0) {
-		type = A_1_1_3;
-	    } else if (strncmp(&buf[1],"A.2.2",5) == 0) {
-		type = A_2_2;
-	    } else if (strncmp(&buf[1],"A.2.4",5) == 0) {
-		type = A_2_4;
-	    } else if (strncmp(&buf[1],"A.1.2.2",7) == 0) {
-		type = A_1_2_2;
-	    /* validate our output from PQGGEN */
-	    } else if (strncmp(&buf[1],"A.1.1.2",7) == 0) {
-		type = A_2_4; /* validate PQ and G together */
-	    } else {
-		fprintf(stderr, "Unknown dsa ver test %s\n", &buf[1]);
-		exit(1);
-	    }
-		
+            if (strncmp(&buf[1],"A.1.1.3",7) == 0) {
+                type = A_1_1_3;
+            } else if (strncmp(&buf[1],"A.2.2",5) == 0) {
+                type = A_2_2;
+            } else if (strncmp(&buf[1],"A.2.4",5) == 0) {
+                type = A_2_4;
+            } else if (strncmp(&buf[1],"A.1.2.2",7) == 0) {
+                type = A_1_2_2;
+            /* validate our output from PQGGEN */
+            } else if (strncmp(&buf[1],"A.1.1.2",7) == 0) {
+                type = A_2_4; /* validate PQ and G together */
+            } else {
+                fprintf(stderr, "Unknown dsa ver test %s\n", &buf[1]);
+                exit(1);
+            }
+                
             fputs(buf, dsaresp);
             continue;
         }
-	
+        
 
         /* [Mod = x] */
         if (buf[0] == '[') {
 
-	    if (type == FIPS186_1) {
+            if (type == FIPS186_1) {
                 N=160;
                 if (sscanf(buf, "[mod = %d]", &L) != 1) {
                     goto loser;
-		}
-	    } else if (sscanf(buf, "[mod = L=%d, N=%d", &L, &N) != 2) {
-		goto loser;
+                }
+            } else if (sscanf(buf, "[mod = L=%d, N=%d", &L, &N) != 2) {
+                goto loser;
             }
 
             if (pqg.prime.data) { /* P */
                 SECITEM_ZfreeItem(&pqg.prime, PR_FALSE);
             }
             if (pqg.subPrime.data) { /* Q */
                 SECITEM_ZfreeItem(&pqg.subPrime, PR_FALSE);
             }
@@ -3968,27 +4256,27 @@ dsa_pqgver_test(char *reqfn)
                 SECITEM_ZfreeItem(&vfy.h, PR_FALSE);
             }
 
             fputs(buf, dsaresp);
 
             /*calculate the size of p, g, and h then allocate items  */
             pghSize = L/8;
 
-	    pqg.base.data = vfy.h.data = NULL;
-	    vfy.seed.len = pqg.base.len = vfy.h.len = 0;
+            pqg.base.data = vfy.h.data = NULL;
+            vfy.seed.len = pqg.base.len = vfy.h.len = 0;
             SECITEM_AllocItem(NULL, &pqg.prime, pghSize);
             SECITEM_AllocItem(NULL, &vfy.seed, pghSize*3);
-	    if (type == A_2_2) {
-		SECITEM_AllocItem(NULL, &vfy.h, pghSize);
-	    	vfy.h.len = pghSize;
-	    } else if (type == A_2_4) {
-		SECITEM_AllocItem(NULL, &vfy.h, 1);
-	    	vfy.h.len = 1;
-	    }
+            if (type == A_2_2) {
+                SECITEM_AllocItem(NULL, &vfy.h, pghSize);
+                    vfy.h.len = pghSize;
+            } else if (type == A_2_4) {
+                SECITEM_AllocItem(NULL, &vfy.h, 1);
+                    vfy.h.len = 1;
+            }
             pqg.prime.len = pghSize;
             /* q is always N bits */
             SECITEM_AllocItem(NULL, &pqg.subPrime, N/8);
             pqg.subPrime.len = N/8;
             vfy.counter = -1;
 
             continue;
         }
@@ -4037,150 +4325,150 @@ dsa_pqgver_test(char *reqfn)
             fputs(buf, dsaresp);
             continue;
         }
 
         /* Seed = ...  or domain_parameter_seed = ... */
         if (strncmp(buf, "Seed", 4) == 0) {
             i = 4;
         } else if (strncmp(buf, "domain_parameter_seed", 21) == 0) {
-	    i = 21;
-	} else if (strncmp(buf,"firstseed",9) == 0) {
-	    i = 9;
-	} else {
-	    i = 0;
-	}
-	if (i) {
+            i = 21;
+        } else if (strncmp(buf,"firstseed",9) == 0) {
+            i = 9;
+        } else {
+            i = 0;
+        }
+        if (i) {
             while (isspace(buf[i]) || buf[i] == '=') {
                 i++;
             }
             for (j=0; isxdigit(buf[i]); i+=2,j++) {
                 hex_to_byteval(&buf[i], &vfy.seed.data[j]);
             }
-	    vfy.seed.len = j;
+            vfy.seed.len = j;
 
             fputs(buf, dsaresp);
-	    if (type == A_2_4) {
-		SECStatus result;
+            if (type == A_2_4) {
+                SECStatus result;
 
                 /* Verify the Parameters */
                 SECStatus rv = PQG_VerifyParams(&pqg, &vfy, &result);
                 if (rv != SECSuccess) {
                     goto loser;
                 }
                 if (result == SECSuccess) {
                     fprintf(dsaresp, "Result = P\n");
                 } else {
                     fprintf(dsaresp, "Result = F\n");
                 }
-	    }
+            }
             continue;
         }
-	if ((strncmp(buf,"pseed",5) == 0) ||
-	    (strncmp(buf,"qseed",5) == 0))
-	{
-	    i = 5;
+        if ((strncmp(buf,"pseed",5) == 0) ||
+            (strncmp(buf,"qseed",5) == 0))
+        {
+            i = 5;
             while (isspace(buf[i]) || buf[i] == '=') {
                 i++;
             }
             for (j=vfy.seed.len; isxdigit(buf[i]); i+=2,j++) {
                 hex_to_byteval(&buf[i], &vfy.seed.data[j]);
             }
-	    vfy.seed.len = j;
+            vfy.seed.len = j;
             fputs(buf, dsaresp);
 
             continue;
-	}
+        }
         if (strncmp(buf, "index", 4) == 0) {
-	    i=5;
+            i=5;
             while (isspace(buf[i]) || buf[i] == '=') {
                 i++;
             }
-	    hex_to_byteval(&buf[i], &vfy.h.data[0]);
-	    vfy.h.len = 1;
+            hex_to_byteval(&buf[i], &vfy.h.data[0]);
+            vfy.h.len = 1;
             fputs(buf, dsaresp);
-	}
+        }
 
         /* c = ...  or counter=*/
         if (buf[0] == 'c')  {
-	    if (strncmp(buf,"counter", 7) == 0) {
+            if (strncmp(buf,"counter", 7) == 0) {
                 if (sscanf(buf, "counter = %u", &vfy.counter) != 1) {
                     goto loser;
-		}
-	    } else {
+                }
+            } else {
                 if (sscanf(buf, "c = %u", &vfy.counter) != 1) {
                     goto loser;
-		}
+                }
             }
 
             fputs(buf, dsaresp);
             if (type == A_1_1_3) {
-		SECStatus result;
+                SECStatus result;
                 /* only verify P and Q, we have everything now. do it */
                 SECStatus rv = PQG_VerifyParams(&pqg, &vfy, &result);
                 if (rv != SECSuccess) {
                     goto loser;
                 }
                 if (result == SECSuccess) {
                     fprintf(dsaresp, "Result = P\n");
                 } else {
                     fprintf(dsaresp, "Result = F\n");
                 }
                 fprintf(dsaresp, "\n");
             }
             continue;
         }
-	if (strncmp(buf,"pgen_counter", 12) == 0) {
+        if (strncmp(buf,"pgen_counter", 12) == 0) {
             if (sscanf(buf, "pgen_counter = %u", &vfy.counter) != 1) {
                 goto loser;
-            }	
+            }        
             fputs(buf, dsaresp);
-	    continue;
-	}
-	if (strncmp(buf,"qgen_counter", 12) == 0) {
+            continue;
+        }
+        if (strncmp(buf,"qgen_counter", 12) == 0) {
             fputs(buf, dsaresp);
             if (type == A_1_2_2) {
-		SECStatus result;
+                SECStatus result;
                 /* only verify P and Q, we have everything now. do it */
                 SECStatus rv = PQG_VerifyParams(&pqg, &vfy, &result);
                 if (rv != SECSuccess) {
                     goto loser;
                 }
                 if (result == SECSuccess) {
                     fprintf(dsaresp, "Result = P\n");
                 } else {
                     fprintf(dsaresp, "Result = F\n");
                 }
                 fprintf(dsaresp, "\n");
             } 
-	    continue;
-	}
+            continue;
+        }
         /* H = ... */
         if (buf[0] == 'H') {
             SECStatus rv, result = SECFailure;
 
             i = 1;
             while (isspace(buf[i]) || buf[i] == '=') {
                 i++;
             }
             for (j=0; isxdigit(buf[i]); i+=2,j++) {
                 hex_to_byteval(&buf[i], &vfy.h.data[j]);
             }
-	    vfy.h.len = j;
+            vfy.h.len = j;
             fputs(buf, dsaresp);
 
-	    /* this should be a byte value. Remove the leading zeros. If
-	     * it doesn't reduce to a byte, PQG_VerifyParams will catch it 
-	    if (type == A_2_2) {
-		data_save = vfy.h.data;
-		while(vfy.h.data[0] && (vfy.h.len > 1)) {
-			vfy.h.data++;
-			vfy.h.len--;
-		}
-	    } */
+            /* this should be a byte value. Remove the leading zeros. If
+             * it doesn't reduce to a byte, PQG_VerifyParams will catch it 
+            if (type == A_2_2) {
+                data_save = vfy.h.data;
+                while(vfy.h.data[0] && (vfy.h.len > 1)) {
+                        vfy.h.data++;
+                        vfy.h.len--;
+                }
+            } */
 
             /* Verify the Parameters */
             rv = PQG_VerifyParams(&pqg, &vfy, &result);
             if (rv != SECSuccess) {
                 goto loser;
             }
             if (result == SECSuccess) {
                 fprintf(dsaresp, "Result = P\n");
@@ -4227,84 +4515,91 @@ dsa_pqggen_test(char *reqfn)
                          */
     FILE *dsareq;     /* input stream from the REQUEST file */
     FILE *dsaresp;    /* output stream to the RESPONSE file */
     int count;            /* number of times to generate parameters */
     int N;
     int L;
     int i;
     unsigned int j;
+    int output_g = 1;
     PQGParams *pqg = NULL;
     PQGVerify *vfy = NULL;
-    unsigned int keySizeIndex;
+    unsigned int keySizeIndex = 0;
     dsa_pqg_type type = FIPS186_1;
 
     dsareq = fopen(reqfn, "r");
     dsaresp = stdout;
     while (fgets(buf, sizeof buf, dsareq) != NULL) {
         /* a comment or blank line */
         if (buf[0] == '#' || buf[0] == '\n') {
             fputs(buf, dsaresp);
             continue;
         }
 
         /* [A.xxxxx ] */
         if (buf[0] == '['  && buf[1] == 'A') {
-	    if (strncmp(&buf[1],"A.1.1.2",7) == 0) {
-		type = A_1_1_2;
-	    } else if (strncmp(&buf[1],"A.2.1",5) == 0) {
-		fprintf(stderr, "NSS only Generates G with P&Q\n");
-		exit(1);
-	    } else if (strncmp(&buf[1],"A.2.3",5) == 0) {
-		fprintf(stderr, "NSS only Generates G with P&Q\n");
+            if (strncmp(&buf[1],"A.1.1.2",7) == 0) {
+                fprintf(stderr, "NSS does Generate Probablistic Primes\n");
 		exit(1);
-	    } else if (strncmp(&buf[1],"A.1.2.1",7) == 0) {
-		fprintf(stderr, "NSS does not support Shawe-Taylor Primes\n");
-		exit(1);
-	    } else {
-		fprintf(stderr, "Unknown dsa ver test %s\n", &buf[1]);
-		exit(1);
-	    }
+            } else if (strncmp(&buf[1],"A.2.1",5) == 0) {
+                type = A_1_2_1;
+		output_g = 1;
+                exit(1);
+            } else if (strncmp(&buf[1],"A.2.3",5) == 0) {
+                fprintf(stderr, "NSS only Generates G with P&Q\n");
+                exit(1);
+            } else if (strncmp(&buf[1],"A.1.2.1",7) == 0) {
+                type = A_1_2_1;
+		output_g = 0;
+            } else {
+                fprintf(stderr, "Unknown dsa pqggen test %s\n", &buf[1]);
+                exit(1);
+            }
             fputs(buf, dsaresp);
             continue;
         }
 
         /* [Mod = ... ] */
         if (buf[0] == '[') {
 
-	    if (type == FIPS186_1) {
+            if (type == FIPS186_1) {
                 N=160;
                 if (sscanf(buf, "[mod = %d]", &L) != 1) {
                     goto loser;
-		}
-	    } else if (sscanf(buf, "[mod = L=%d, N=%d", &L, &N) != 2) {
-		goto loser;
+                }
+            } else if (sscanf(buf, "[mod = L=%d, N=%d", &L, &N) != 2) {
+                goto loser;
             }
 
             fputs(buf, dsaresp);
             fputc('\n', dsaresp);
 
-	    if (type == FIPS186_1) {
+            if (type == FIPS186_1) {
                 /************************************************************
                  * PQG_ParamGenSeedLen doesn't take a key size, it takes an
                  * index that points to a valid key size.
                  */
                 keySizeIndex = PQG_PBITS_TO_INDEX(L);
                 if(keySizeIndex == -1 || L<512 || L>1024) {
                    fprintf(dsaresp,
                         "DSA key size must be a multiple of 64 between 512 "
                         "and 1024, inclusive");
                     goto loser;
                 }
             }
             continue;
         }
         /* N = ... */
         if (buf[0] == 'N') {
-            if (sscanf(buf, "N = %d", &count) != 1) {
+	    if (strncmp(buf, "Num", 3) == 0) {
+                if (sscanf(buf, "Num = %d", &count) != 1) {
+                    goto loser;
+                }
+            } else if (sscanf(buf, "N = %d", &count) != 1) {
                 goto loser;
             }
             for (i = 0; i < count; i++) {
                 SECStatus rv;
 
                 if (type == FIPS186_1) {
                     rv = PQG_ParamGenSeedLen(keySizeIndex, PQG_TEST_SEED_BYTES,
                          &pqg, &vfy);
@@ -4315,34 +4610,48 @@ dsa_pqggen_test(char *reqfn)
                     fprintf(dsaresp,
                             "ERROR: Unable to generate PQG parameters");
                     goto loser;
                 }
                 to_hex_str(buf, pqg->prime.data, pqg->prime.len);
                 fprintf(dsaresp, "P = %s\n", buf);
                 to_hex_str(buf, pqg->subPrime.data, pqg->subPrime.len);
                 fprintf(dsaresp, "Q = %s\n", buf);
-                to_hex_str(buf, pqg->base.data, pqg->base.len);
-                fprintf(dsaresp, "G = %s\n", buf);
-		if (type == FIPS186_1) {
+		if (output_g) {
+                    to_hex_str(buf, pqg->base.data, pqg->base.len);
+                    fprintf(dsaresp, "G = %s\n", buf);
+		}
+                if (type == FIPS186_1) {
                     to_hex_str(buf, vfy->seed.data, vfy->seed.len);
                     fprintf(dsaresp, "Seed = %s\n", buf);
                     fprintf(dsaresp, "c = %d\n", vfy->counter);
                     to_hex_str(buf, vfy->h.data, vfy->h.len);
                     fputs("H = ", dsaresp);
                     for (j=vfy->h.len; j< pqg->prime.len; j++) {
-                	fprintf(dsaresp, "00");
+                        fprintf(dsaresp, "00");
                     }
                     fprintf(dsaresp, "%s\n", buf);
-		} else {
-                    fprintf(dsaresp, "counter = %d\n", vfy->counter);
-		    fprintf(dsaresp, "index = %02x\n", vfy->h.data[0]);
-                    to_hex_str(buf, vfy->seed.data, vfy->seed.len);
-                    fprintf(dsaresp, "domain_parameter_seed = %s\n", buf);
-		}
+                } else {
+                    unsigned int seedlen = vfy->seed.len/2;
+		    unsigned int pgen_counter = vfy->counter >> 16;
+		    unsigned int qgen_counter = vfy->counter & 0xffff;
+                    /*fprintf(dsaresp, "index = %02x\n", vfy->h.data[0]); */
+                    to_hex_str(buf, vfy->seed.data, seedlen);
+                    fprintf(dsaresp, "pseed = %s\n", buf);
+                    to_hex_str(buf, vfy->seed.data+seedlen, seedlen);
+                    fprintf(dsaresp, "qseed = %s\n", buf);
+                    fprintf(dsaresp, "pgen_counter = %d\n", pgen_counter);
+                    fprintf(dsaresp, "qgen_counter = %d\n", qgen_counter);
+		    if (output_g) {
+                        to_hex_str(buf, vfy->seed.data, vfy->seed.len);
+                        fprintf(dsaresp, "domain_parameter_seed = %s\n", buf);
+		        fprintf(dsaresp, "index = %02x\n", vfy->h.data[0]);
+		    }
+		
+                }
                 fputc('\n', dsaresp);
                 if(pqg!=NULL) {
                     PQG_DestroyParams(pqg);
                     pqg = NULL;
                 }
                 if(vfy!=NULL) {
                     PQG_DestroyVerify(vfy);
                     vfy = NULL;
@@ -4418,17 +4727,17 @@ dsa_siggen_test(char *reqfn)
             if (dsakey != NULL) {
                     PORT_FreeArena(dsakey->params.arena, PR_TRUE);
                     dsakey = NULL;
             }
 
             if (sscanf(buf, "[mod = L=%d,  N=%d, SHA-%d]", &L, & N,
                 &hashNum) != 3) {
                 use_dsa1 = PR_TRUE;
-		hashNum = 1;
+                hashNum = 1;
                 if (sscanf(buf, "[mod = %d]", &modulus) != 1) {
                     goto loser;
                 }
             }
             fputs(buf, dsaresp);
             fputc('\n', dsaresp);
 
             /****************************************************************
@@ -4465,47 +4774,47 @@ dsa_siggen_test(char *reqfn)
             fprintf(dsaresp, "G = %s\n", buf);
 
             /* create DSA Key */
             if (DSA_NewKey(pqg, &dsakey) != SECSuccess) {
                 fprintf(dsaresp, "ERROR: Unable to generate DSA key");
                 goto loser;
             }
  
-	    hashType = sha_get_hashType(hashNum);
-	    if (hashType == HASH_AlgNULL) {
-		fprintf(dsaresp, "ERROR: invalid hash (SHA-%d)",hashNum);
-		goto loser;
-	    }
+            hashType = sha_get_hashType(hashNum);
+            if (hashType == HASH_AlgNULL) {
+                fprintf(dsaresp, "ERROR: invalid hash (SHA-%d)",hashNum);
+                goto loser;
+            }
             continue;
         }
 
         /* Msg = ... */
         if (strncmp(buf, "Msg", 3) == 0) {
             unsigned char msg[128]; /* MAX msg 128 */
             unsigned int len = 0;
 
-	    if (hashType == HASH_AlgNULL) {
-		fprintf(dsaresp, "ERROR: Hash Alg not set");
-		goto loser;
-	    }
+            if (hashType == HASH_AlgNULL) {
+                fprintf(dsaresp, "ERROR: Hash Alg not set");
+                goto loser;
+            }
 
             memset(hashBuf, 0, sizeof hashBuf);
             memset(sig,  0, sizeof sig);
 
             i = 3;
             while (isspace(buf[i]) || buf[i] == '=') {
                 i++;
             }
             for (j=0; isxdigit(buf[i]); i+=2,j++) {
                 hex_to_byteval(&buf[i], &msg[j]);
             }
             if (fips_hashBuf(hashType, hashBuf, msg, j) != SECSuccess) {
                  fprintf(dsaresp, "ERROR: Unable to generate SHA% digest", 
-			 hashNum);
+                         hashNum);
                  goto loser;
             }
 
 
             digest.type = siBuffer;
             digest.data = hashBuf;
             digest.len = fips_hashLen(hashType);
             signature.type = siBuffer;
@@ -4590,18 +4899,18 @@ dsa_sigver_test(char *reqfn)
             continue;
         }
 
         /* [Mod = x] */
         if (buf[0] == '[') {
 
             if (sscanf(buf, "[mod = L=%d,  N=%d, SHA-%d]", &L, & N,
                 &hashNum) != 3) {
-		N=160;
-		hashNum = 1;
+                N=160;
+                hashNum = 1;
                 if (sscanf(buf, "[mod = %d]", &L) != 1) {
                     goto loser;
                 }
             }
 
             if (pubkey.params.prime.data) { /* P */
                 SECITEM_ZfreeItem(&pubkey.params.prime, PR_FALSE);
             }
@@ -4623,21 +4932,21 @@ dsa_sigver_test(char *reqfn)
             SECITEM_AllocItem(NULL, &pubkey.publicValue, pgySize);
             pubkey.params.prime.len = pubkey.params.base.len = pgySize;
             pubkey.publicValue.len = pgySize;
 
             /* q always N/8 bytes */
             SECITEM_AllocItem(NULL, &pubkey.params.subPrime, N/8);
             pubkey.params.subPrime.len = N/8;
 
-	    hashType = sha_get_hashType(hashNum);
-	    if (hashType == HASH_AlgNULL) {
-		fprintf(dsaresp, "ERROR: invalid hash (SHA-%d)",hashNum);
-		goto loser;
-	    }
+            hashType = sha_get_hashType(hashNum);
+            if (hashType == HASH_AlgNULL) {
+                fprintf(dsaresp, "ERROR: invalid hash (SHA-%d)",hashNum);
+                goto loser;
+            }
 
             continue;
         }
         /* P = ... */
         if (buf[0] == 'P') {
             i = 1;
             while (isspace(buf[i]) || buf[i] == '=') {
                 i++;
@@ -4681,31 +4990,31 @@ dsa_sigver_test(char *reqfn)
             continue;
         }
 
         /* Msg = ... */
         if (strncmp(buf, "Msg", 3) == 0) {
             unsigned char msg[128]; /* MAX msg 128 */
             memset(hashBuf, 0, sizeof hashBuf);
 
-	    if (hashType == HASH_AlgNULL) {
-		fprintf(dsaresp, "ERROR: Hash Alg not set");
-		goto loser;
-	    }
+            if (hashType == HASH_AlgNULL) {
+                fprintf(dsaresp, "ERROR: Hash Alg not set");
+                goto loser;
+            }
 
             i = 3;
             while (isspace(buf[i]) || buf[i] == '=') {
                 i++;
             }
             for (j=0; isxdigit(buf[i]); i+=2,j++) {
                 hex_to_byteval(&buf[i], &msg[j]);
             }
             if (fips_hashBuf(hashType, hashBuf, msg, j) != SECSuccess) {
                 fprintf(dsaresp, "ERROR: Unable to generate SHA-%d digest",
-								hashNum);
+                                                                hashNum);
                 goto loser;
             }
 
             fputs(buf, dsaresp);
             continue;
         }
 
         /* Y = ... */
@@ -4735,44 +5044,44 @@ dsa_sigver_test(char *reqfn)
             }
 
             fputs(buf, dsaresp);
             continue;
         }
 
         /* S = ... */
         if (buf[0] == 'S') {
-	    if (hashType == HASH_AlgNULL) {
-		fprintf(dsaresp, "ERROR: Hash Alg not set");
-		goto loser;
-	    }
+            if (hashType == HASH_AlgNULL) {
+                fprintf(dsaresp, "ERROR: Hash Alg not set");
+                goto loser;
+            }
 
             i = 1;
             while (isspace(buf[i]) || buf[i] == '=') {
                 i++;
             }
             for (j=pubkey.params.subPrime.len; 
-				j< pubkey.params.subPrime.len*2; i+=2,j++) {
+                                j< pubkey.params.subPrime.len*2; i+=2,j++) {
                 hex_to_byteval(&buf[i], &sig[j]);
             }
             fputs(buf, dsaresp);
 
             digest.type = siBuffer;
             digest.data = hashBuf;
             digest.len = fips_hashLen(hashType);
             signature.type = siBuffer;
             signature.data = sig;
             signature.len = pubkey.params.subPrime.len*2;
 
             if (DSA_VerifyDigest(&pubkey, &signature, &digest) == SECSuccess) {
                 fprintf(dsaresp, "Result = P\n");
             } else {
                 fprintf(dsaresp, "Result = F\n");
             }
-	    fprintf(dsaresp, "\n");
+            fprintf(dsaresp, "\n");
             continue;
         }
     }
 loser:
     fclose(dsareq);
     if (pubkey.params.prime.data) { /* P */
         SECITEM_ZfreeItem(&pubkey.params.prime, PR_FALSE);
     }
@@ -4782,16 +5091,128 @@ loser:
     if (pubkey.params.base.data) {    /* G */
         SECITEM_ZfreeItem(&pubkey.params.base, PR_FALSE);
     }
     if (pubkey.publicValue.data) {    /* Y */
         SECITEM_ZfreeItem(&pubkey.publicValue, PR_FALSE);
     }
 }
 
+static void 
+pad(unsigned char *buf, int pad_len, unsigned char *src, int src_len) 
+{
+    int offset = 0;
+    /* this shouldn't happen, fail right away rather than produce bad output */
+    if (pad_len < src_len) {
+	fprintf(stderr, "data bigger than expected! %d > %d\n", src_len, pad_len);
+	exit(1);
+    }
+
+    offset = pad_len - src_len;
+    memset(buf, 0, offset);
+    memcpy(buf+offset, src, src_len);
+    return;
+}
+
+
+/*
+ * Perform the DSA Key Pair Generation Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+rsa_keypair_test(char *reqfn)
+{
+    char buf[800];       /* holds one line from the input REQUEST file
+                         * or to the output RESPONSE file.
+                         * 800 to hold (384 public key (x2 for HEX) + 1'\n'
+                         */
+    unsigned char buf2[400];   /* can't need more then 1/2 buf length */
+    FILE *rsareq;     /* input stream from the REQUEST file */
+    FILE *rsaresp;    /* output stream to the RESPONSE file */
+    int count;
+    int i;
+    int keySize;   /* key size in bits*/
+    int len = 0;       /* key size in bytes */
+    int len2 = 0;      /* key size in bytes/2 (prime size) */
+    SECItem e;
+    unsigned char default_e[] = { 0x1, 0x0, 0x1 };
+
+    e.data = default_e;
+    e.len = sizeof (default_e);
+
+    rsareq = fopen(reqfn, "r");
+    rsaresp = stdout;
+    while (fgets(buf, sizeof buf, rsareq) != NULL) {
+        /* a comment or blank line */
+        if (buf[0] == '#' || buf[0] == '\n') {
+            fputs(buf, rsaresp);
+            continue;
+        }
+
+        /* [Mod = x] */
+        if (buf[0] == '[') {
+	    if (buf[1] == 'm') {
+        	if (sscanf(buf, "[mod = %d]", &keySize) != 1) {
+                    goto loser;
+        	}
+		len = keySize/8;
+		len2 = keySize/16;
+	    }
+            fputs(buf, rsaresp);
+            continue;
+        }
+        /* N = ...*/
+        if (buf[0] == 'N') {
+
+            if (sscanf(buf, "N = %d", &count) != 1) {
+                goto loser;
+            }
+
+            /* Generate a DSA key, and output the key pair for N times */
+            for (i = 0; i < count; i++) {
+                RSAPrivateKey *rsakey = NULL;
+                if ((rsakey = RSA_NewKey(keySize, &e)) == NULL) {
+                    fprintf(rsaresp, "ERROR: Unable to generate RSA key");
+                    goto loser;
+                }
+	        pad(buf2,len,rsakey->publicExponent.data,
+					 rsakey->publicExponent.len);
+                to_hex_str(buf, buf2, len);
+                fprintf(rsaresp, "e = %s\n", buf);
+	        pad(buf2,len2,rsakey->prime1.data,
+					 rsakey->prime1.len);
+                to_hex_str(buf, buf2, len2);
+                fprintf(rsaresp, "p = %s\n", buf);
+	        pad(buf2,len2,rsakey->prime2.data,
+					 rsakey->prime2.len);
+                to_hex_str(buf, buf2, len2);
+                fprintf(rsaresp, "q = %s\n", buf);
+	        pad(buf2,len,rsakey->modulus.data,
+					 rsakey->modulus.len);
+                to_hex_str(buf, buf2, len);
+                fprintf(rsaresp, "n = %s\n", buf);
+	        pad(buf2,len,rsakey->privateExponent.data,
+					 rsakey->privateExponent.len);
+                to_hex_str(buf, buf2, len);
+                fprintf(rsaresp, "d = %s\n", buf);
+                fprintf(rsaresp, "\n");
+                PORT_FreeArena(rsakey->arena, PR_TRUE);
+                rsakey = NULL;
+            }
+            continue;
+        }
+
+    }
+loser:
+    fclose(rsareq);
+}
+
 /*
  * Perform the RSA Signature Generation Test.
  *
  * reqfn is the pathname of the REQUEST file.
  *
  * The output RESPONSE file is written to stdout.
  */
 void
@@ -4940,26 +5361,26 @@ rsa_siggen_test(char *reqfn)
 
             i = 3;
             while (isspace(buf[i]) || buf[i] == '=') {
                 i++;
             }
             for (j=0; isxdigit(buf[i]) && j < sizeof(msg); i+=2,j++) {
                 hex_to_byteval(&buf[i], &msg[j]);
             }
-	    shaLength = fips_hashLen(shaAlg);
-	    if (fips_hashBuf(shaAlg,sha,msg,j) != SECSuccess) {
-		if (shaLength == 0) {
-            	    fprintf(rsaresp, "ERROR: SHAAlg not defined.");
-		}
+            shaLength = fips_hashLen(shaAlg);
+            if (fips_hashBuf(shaAlg,sha,msg,j) != SECSuccess) {
+                if (shaLength == 0) {
+                        fprintf(rsaresp, "ERROR: SHAAlg not defined.");
+                }
                 fprintf(rsaresp, "ERROR: Unable to generate SHA%x",
-			shaLength == 160 ? 1 : shaLength);
+                        shaLength == 160 ? 1 : shaLength);
                 goto loser;
             }
-	    shaOid = fips_hashOid(shaAlg);
+            shaOid = fips_hashOid(shaAlg);
 
             /* Perform RSA signature with the RSA private key. */
             rv = RSA_HashSign( shaOid,
                                rsa_private_key,
                                rsa_computed_signature,
                                &rsa_bytes_signed,
                                nsslowkey_PrivateModulusLen(rsa_private_key),
                                sha,
@@ -5164,23 +5585,23 @@ rsa_sigver_test(char *reqfn)
             while (isspace(buf[i]) || buf[i] == '=') {
                 i++;
             }
 
             for (j=0; isxdigit(buf[i]) && j < sizeof msg; i+=2,j++) {
                 hex_to_byteval(&buf[i], &msg[j]);
             }
 
-	    shaLength = fips_hashLen(shaAlg);
-	    if (fips_hashBuf(shaAlg,sha,msg,j) != SECSuccess) {
-		if (shaLength == 0) {
-            	    fprintf(rsaresp, "ERROR: SHAAlg not defined.");
-		}
+            shaLength = fips_hashLen(shaAlg);
+            if (fips_hashBuf(shaAlg,sha,msg,j) != SECSuccess) {
+                if (shaLength == 0) {
+                        fprintf(rsaresp, "ERROR: SHAAlg not defined.");
+                }
                 fprintf(rsaresp, "ERROR: Unable to generate SHA%x",
-			shaLength == 160 ? 1 : shaLength);
+                        shaLength == 160 ? 1 : shaLength);
                 goto loser;
             }
 
             fputs(buf, rsaresp);
             continue;
 
         }
 
@@ -5203,16 +5624,18 @@ rsa_sigver_test(char *reqfn)
 
             for (j=0; isxdigit(buf[i]) && j < sizeof signature; i+=2,j++) {
                 hex_to_byteval(&buf[i], &signature[j]);
             }
 
             signatureLength = j;
             fputs(buf, rsaresp);
 
+            shaOid = fips_hashOid(shaAlg);
+
             /* Perform RSA verification with the RSA public key. */
             rv = RSA_HashCheckSign( shaOid,
                                     rsa_public_key,
                                     signature,
                                     signatureLength,
                                     sha,
                                     shaLength);
             if( rv == SECSuccess ) {
@@ -5228,16 +5651,312 @@ loser:
     if (rsaBlapiPublicKey.modulus.data) { /* n */
         SECITEM_ZfreeItem(&rsaBlapiPublicKey.modulus, PR_FALSE);
     }
     if (rsaBlapiPublicKey.publicExponent.data) { /* e */
         SECITEM_ZfreeItem(&rsaBlapiPublicKey.publicExponent, PR_FALSE);
     }
 }
 
+void
+tls(char *reqfn)
+{
+    char buf[256];      /* holds one line from the input REQUEST file.
+                         * needs to be large enough to hold the longest
+                         * line "XSeed = <128 hex digits>\n".
+                         */
+    unsigned char *pms = NULL;
+    int pms_len;
+    unsigned char *master_secret = NULL;
+    unsigned char *key_block = NULL;
+    int key_block_len;
+    unsigned char serverHello_random[SSL3_RANDOM_LENGTH];
+    unsigned char clientHello_random[SSL3_RANDOM_LENGTH];
+    unsigned char server_random[SSL3_RANDOM_LENGTH];
+    unsigned char client_random[SSL3_RANDOM_LENGTH];
+    FILE *tlsreq = NULL; /* input stream from the REQUEST file */
+    FILE *tlsresp;       /* output stream to the RESPONSE file */
+    unsigned int i, j;
+    CK_SLOT_ID slotList[10];
+    CK_SLOT_ID slotID;
+    CK_ULONG slotListCount = sizeof(slotList)/sizeof(slotList[0]);
+    CK_ULONG count;
+    static const CK_C_INITIALIZE_ARGS pk11args= {
+	NULL, NULL, NULL, NULL, CKF_LIBRARY_CANT_CREATE_OS_THREADS , 
+	(void *)"flags=readOnly,noCertDB,noModDB", NULL };
+    static CK_OBJECT_CLASS ck_secret = CKO_SECRET_KEY;
+    static CK_KEY_TYPE ck_generic = CKK_GENERIC_SECRET;
+    static CK_BBOOL ck_true = CK_TRUE;
+    static CK_ULONG one = 1;
+    CK_ATTRIBUTE create_template[] = {
+	{ CKA_VALUE,        NULL,        0                  },
+	{ CKA_CLASS,        &ck_secret,  sizeof(ck_secret)  },
+	{ CKA_KEY_TYPE,     &ck_generic, sizeof(ck_generic) },
+	{ CKA_DERIVE,       &ck_true,    sizeof (ck_true)   },
+    };
+    CK_ULONG create_template_count = 
+			sizeof(create_template)/sizeof(create_template[0]);
+    CK_ATTRIBUTE derive_template[] = {
+	{ CKA_CLASS,        &ck_secret,  sizeof(ck_secret)  },
+	{ CKA_KEY_TYPE,     &ck_generic, sizeof(ck_generic) },
+	{ CKA_DERIVE,       &ck_true,    sizeof(ck_true)    },
+	{ CKA_VALUE_LEN,    &one,        sizeof(one)        },
+    };
+    CK_ULONG derive_template_count = 
+			sizeof(derive_template)/sizeof(derive_template[0]);
+    CK_ATTRIBUTE master_template = 
+	{ CKA_VALUE, NULL, 0 };
+    CK_ATTRIBUTE kb1_template = 
+	{ CKA_VALUE, NULL, 0 };
+    CK_ATTRIBUTE kb2_template = 
+	{ CKA_VALUE, NULL, 0 };
+    
+
+    CK_MECHANISM master_mech = { CKM_TLS_MASTER_KEY_DERIVE , NULL, 0 };
+    CK_MECHANISM key_block_mech = { CKM_TLS_KEY_AND_MAC_DERIVE , NULL, 0};
+    CK_SSL3_MASTER_KEY_DERIVE_PARAMS master_params;
+    CK_SSL3_KEY_MAT_PARAMS key_block_params;
+    CK_SSL3_KEY_MAT_OUT key_material;
+    CK_RV crv;
+
+    /* set up PKCS #11 parameters */
+    master_params.pVersion = NULL;
+    master_params.RandomInfo.pClientRandom = clientHello_random;
+    master_params.RandomInfo.ulClientRandomLen = sizeof(clientHello_random);
+    master_params.RandomInfo.pServerRandom = serverHello_random;
+    master_params.RandomInfo.ulServerRandomLen = sizeof(serverHello_random);
+    master_mech.pParameter = (void *) &master_params;
+    master_mech.ulParameterLen = sizeof(master_params);
+    key_block_params.ulMacSizeInBits = 0;
+    key_block_params.ulKeySizeInBits = 0;
+    key_block_params.ulIVSizeInBits = 0;
+    key_block_params.bIsExport = PR_FALSE; /* ignored anyway for TLS mech */
+    key_block_params.RandomInfo.pClientRandom = client_random;
+    key_block_params.RandomInfo.ulClientRandomLen = sizeof(client_random);
+    key_block_params.RandomInfo.pServerRandom = server_random;
+    key_block_params.RandomInfo.ulServerRandomLen = sizeof(server_random);
+    key_block_params.pReturnedKeyMaterial = &key_material;
+    key_block_mech.pParameter = (void *) &key_block_params;
+    key_block_mech.ulParameterLen = sizeof(key_block_params);
+    
+
+    crv = NSC_Initialize((CK_VOID_PTR)&pk11args);
+    if (crv != CKR_OK) {
+	fprintf(stderr,"NSC_Initialize failed crv=0x%x\n",(unsigned int)crv);
+	goto loser;
+    }
+    count = slotListCount;
+    crv = NSC_GetSlotList(PR_TRUE,slotList, &count);
+    if (crv != CKR_OK) {
+	fprintf(stderr,"NSC_GetSlotList failed crv=0x%x\n",(unsigned int)crv);
+	goto loser;
+    }
+    if ((count > slotListCount) || count < 1) {
+	fprintf(stderr,
+"NSC_GetSlotList returned too many or too few slots: %d slots max=%d min=1\n",
+		(int) count, (int) slotListCount);
+	goto loser;
+    }
+    slotID = slotList[0];
+    tlsreq = fopen(reqfn, "r");
+    tlsresp = stdout;
+    while (fgets(buf, sizeof buf, tlsreq) != NULL) {
+        /* a comment or blank line */
+        if (buf[0] == '#' || buf[0] == '\n') {
+            fputs(buf, tlsresp);
+            continue;
+        }
+        /* [Xchange - SHA1] */
+        if (buf[0] == '[') {
+            if (strncmp(buf, "[TLS", 4)  == 0) {
+		if (buf[7] == '0') {
+    		    master_mech.mechanism = CKM_TLS_MASTER_KEY_DERIVE;
+    		    key_block_mech.mechanism = CKM_TLS_KEY_AND_MAC_DERIVE;
+		} else if (buf[7] == '2') {
+    		    master_mech.mechanism = 
+					CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256;
+    		    key_block_mech.mechanism = 
+					CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256;
+		} else {
+		    fprintf(stderr, "Unknown TLS type %x\n", 
+						(unsigned int)buf[0]);
+		    goto loser;
+		} 
+	    }
+            if (strncmp(buf, "[pre-master", 11)  == 0) {
+                if (sscanf(buf, "[pre-master secret length = %d]", 
+				&pms_len) != 1) {
+                    goto loser;
+                }
+                pms_len = pms_len/8;
+		pms = malloc(pms_len);
+	 	master_secret = malloc(pms_len);
+		create_template[0].pValue = pms;
+		create_template[0].ulValueLen = pms_len;
+		master_template.pValue = master_secret;
+		master_template.ulValueLen = pms_len;
+            } 
+            if (strncmp(buf, "[key", 4)  == 0) {
+                if (sscanf(buf, "[key block length = %d]", &key_block_len) != 1) {
+                    goto loser;
+                }
+    		key_block_params.ulKeySizeInBits = 8;
+    		key_block_params.ulIVSizeInBits = key_block_len/2-8;
+                key_block_len=key_block_len/8;
+		key_block = malloc(key_block_len);
+		kb1_template.pValue = &key_block[0];
+		kb1_template.ulValueLen = 1;
+		kb2_template.pValue = &key_block[1];
+		kb2_template.ulValueLen = 1;
+		key_material.pIVClient = &key_block[2];
+		key_material.pIVServer = &key_block[2+key_block_len/2-1];
+            } 
+            fputs(buf, tlsresp);
+            continue;
+        }
+        /* "COUNT = x" begins a new data set */
+        if (strncmp(buf, "COUNT", 5) == 0) {
+            /* zeroize the variables for the test with this data set */
+            memset(pms, 0, pms_len);
+            memset(master_secret, 0, pms_len);
+            memset(key_block, 0, key_block_len);
+            fputs(buf, tlsresp);
+            continue;
+        }
+        /* pre_master_secret = ... */
+        if (strncmp(buf, "pre_master_secret", 17) == 0) {
+            i = 17;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<pms_len; i+=2,j++) {
+                hex_to_byteval(&buf[i], &pms[j]);
+            }
+            fputs(buf, tlsresp);
+            continue;
+        }
+        /* serverHello_random = ... */
+        if (strncmp(buf, "serverHello_random", 18) == 0) {
+            i = 18;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<SSL3_RANDOM_LENGTH; i+=2,j++) {
+                hex_to_byteval(&buf[i], &serverHello_random[j]);
+            }
+            fputs(buf, tlsresp);
+            continue;
+        }
+        /* clientHello_random = ... */
+        if (strncmp(buf, "clientHello_random", 18) == 0) {
+            i = 18;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<SSL3_RANDOM_LENGTH; i+=2,j++) {
+                hex_to_byteval(&buf[i], &clientHello_random[j]);
+            }
+            fputs(buf, tlsresp);
+            continue;
+        }
+        /* server_random = ... */
+        if (strncmp(buf, "server_random", 13) == 0) {
+            i = 13;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<SSL3_RANDOM_LENGTH; i+=2,j++) {
+                hex_to_byteval(&buf[i], &server_random[j]);
+            }
+            fputs(buf, tlsresp);
+            continue;
+        }
+        /* client_random = ... */
+        if (strncmp(buf, "client_random", 13) == 0) {
+	    CK_SESSION_HANDLE session;
+ 	    CK_OBJECT_HANDLE pms_handle;
+ 	    CK_OBJECT_HANDLE master_handle;
+ 	    CK_OBJECT_HANDLE fake_handle;
+            i = 13;
+            while (isspace(buf[i]) || buf[i] == '=') {
+                i++;
+            }
+            for (j=0; j<SSL3_RANDOM_LENGTH; i+=2,j++) {
+                hex_to_byteval(&buf[i], &client_random[j]);
+            }
+            fputs(buf, tlsresp);
+	    crv = NSC_OpenSession(slotID, 0, NULL, NULL, &session);
+	    if (crv != CKR_OK) {
+		fprintf(stderr,"NSC_OpenSession failed crv=0x%x\n",
+							(unsigned int)crv);
+		goto loser;
+	    }
+	    crv = NSC_CreateObject(session, create_template, 
+					create_template_count, &pms_handle);
+	    if (crv != CKR_OK) {
+		fprintf(stderr,"NSC_CreateObject failed crv=0x%x\n",
+							(unsigned int)crv);
+		goto loser;
+	    }
+	    crv = NSC_DeriveKey(session, &master_mech, pms_handle, 
+		derive_template, derive_template_count-1, &master_handle);
+	    if (crv != CKR_OK) {
+		fprintf(stderr,"NSC_DeriveKey(master) failed crv=0x%x\n",
+							(unsigned int) crv);
+		goto loser;
+	    }
+	    crv = NSC_GetAttributeValue(session, master_handle, 
+							&master_template, 1);
+	    if (crv != CKR_OK) {
+		fprintf(stderr,"NSC_GetAttribute failed crv=0x%x\n",
+							(unsigned int) crv);
+		goto loser;
+	    }
+            fputs("master_secret = ", tlsresp);
+            to_hex_str(buf, master_secret, pms_len);
+            fputs(buf, tlsresp);
+            fputc('\n', tlsresp);
+	    crv = NSC_DeriveKey(session, &key_block_mech, master_handle,
+			derive_template, derive_template_count, &fake_handle);
+	    if (crv != CKR_OK) {
+		fprintf(stderr,
+			"NSC_DeriveKey(keyblock) failed crv=0x%x\n",
+							(unsigned int) crv);
+		goto loser;
+	    }
+	    crv = NSC_GetAttributeValue(session, key_material.hClientKey, 
+							&kb1_template, 1);
+	    if (crv != CKR_OK) {
+		fprintf(stderr,"NSC_GetAttribute failed crv=0x%x\n",
+							(unsigned int) crv);
+		goto loser;
+	    }
+	    crv = NSC_GetAttributeValue(session, key_material.hServerKey, 
+							&kb2_template, 1);
+	    if (crv != CKR_OK) {
+		fprintf(stderr,"NSC_GetAttribute failed crv=0x%x\n",
+							(unsigned int) crv);
+		goto loser;
+	    }
+            fputs("key_block = ", tlsresp);
+            to_hex_str(buf, key_block, key_block_len);
+            fputs(buf, tlsresp);
+            fputc('\n', tlsresp);
+	    crv = NSC_CloseSession(session);
+            continue;
+        }
+    }
+loser:
+    NSC_Finalize(NULL);
+    if (pms) free(pms);
+    if (master_secret) free(master_secret);
+    if (key_block) free(key_block);
+    if (tlsreq) fclose(tlsreq);
+}
+
 int main(int argc, char **argv)
 {
     if (argc < 2) exit (-1);
 
     RNG_RNGInit();
     SECOID_Init();
 
     /*************/
@@ -5260,33 +5979,41 @@ int main(int argc, char **argv)
                     /* CBC mode */
                     tdea_mct(NSS_DES_EDE3_CBC, argv[4]);
                 }
         }
     /*************/
     /*   AES     */
     /*************/
     } else if (strcmp(argv[1], "aes") == 0) {
-	/* argv[2]=kat|mmt|mct argv[3]=ecb|cbc argv[4]=<test name>.req */
-	if (       strcmp(argv[2], "kat") == 0) {
-	    /* Known Answer Test (KAT) */
-	    aes_kat_mmt(argv[4]);
-	} else if (strcmp(argv[2], "mmt") == 0) {
-	    /* Multi-block Message Test (MMT) */
-	    aes_kat_mmt(argv[4]);
-	} else if (strcmp(argv[2], "mct") == 0) {
-	    /* Monte Carlo Test (MCT) */
-	    if (       strcmp(argv[3], "ecb") == 0) {
-		/* ECB mode */
-		aes_ecb_mct(argv[4]);
-	    } else if (strcmp(argv[3], "cbc") == 0) {
-		/* CBC mode */
-		aes_cbc_mct(argv[4]);
-	    }
-	}
+        /* argv[2]=kat|mmt|mct argv[3]=ecb|cbc argv[4]=<test name>.req */
+        if (       strcmp(argv[2], "kat") == 0) {
+            /* Known Answer Test (KAT) */
+            aes_kat_mmt(argv[4]);
+        } else if (strcmp(argv[2], "mmt") == 0) {
+            /* Multi-block Message Test (MMT) */
+            aes_kat_mmt(argv[4]);
+        } else if (strcmp(argv[2], "gcm") == 0) {
+            if (       strcmp(argv[3], "decrypt") == 0) {
+                aes_gcm(argv[4],0);
+            } else if (strcmp(argv[3], "encrypt_extiv") == 0) {
+                aes_gcm(argv[4],1);
+            } else if (strcmp(argv[3], "encrypt_intiv") == 0) {
+                aes_gcm(argv[4],2);
+            }
+        } else if (strcmp(argv[2], "mct") == 0) {
+            /* Monte Carlo Test (MCT) */
+            if (       strcmp(argv[3], "ecb") == 0) {
+                /* ECB mode */
+                aes_ecb_mct(argv[4]);
+            } else if (strcmp(argv[3], "cbc") == 0) {
+                /* CBC mode */
+                aes_cbc_mct(argv[4]);
+            }
+        }
     /*************/
     /*   SHA     */
     /*************/
     } else if (strcmp(argv[1], "sha") == 0) {
         sha_test(argv[2]);
     /*************/
     /*   RSA     */
     /*************/
@@ -5294,17 +6021,20 @@ int main(int argc, char **argv)
         /* argv[2]=siggen|sigver */
         /* argv[3]=<test name>.req */
         if (strcmp(argv[2], "siggen") == 0) {
             /* Signature Generation Test */
             rsa_siggen_test(argv[3]);
         } else if (strcmp(argv[2], "sigver") == 0) {
             /* Signature Verification Test */
             rsa_sigver_test(argv[3]);
-        }
+        } else if (strcmp(argv[2], "keypair") == 0) {
+            /* Key Pair Generation Test */
+            rsa_keypair_test(argv[3]);
+	}
     /*************/
     /*   HMAC    */
     /*************/
     } else if (strcmp(argv[1], "hmac") == 0) {
         hmac_test(argv[2]);
     /*************/
     /*   DSA     */
     /*************/
--- a/cmd/httpserv/httpserv.c
+++ b/cmd/httpserv/httpserv.c
@@ -334,17 +334,16 @@ typedef struct caRevoInfoStr caRevoInfo;
 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[] = {
@@ -707,18 +706,18 @@ handle_connection(
 		  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*/
+			  nextUpdate = PR_Now() + (PRTime)60*60*24 * PR_USEC_PER_SEC; /*tomorrow*/
+			  revoDate = PR_Now() - (PRTime)60*60*24 * PR_USEC_PER_SEC; /*yesterday*/
 		      }
 		  }
 	      }
 
 	      {
 		  PRTime now = PR_Now();
 		  PLArenaPool *arena = NULL;
 		  CERTOCSPSingleResponse *sr;
--- a/cmd/lib/basicutil.c
+++ b/cmd/lib/basicutil.c
@@ -236,17 +236,17 @@ void SECU_Newline(FILE *out)
 {
     fprintf(out, "\n");
 }
 
 void
 SECU_PrintAsHex(FILE *out, const SECItem *data, const char *m, int level)
 {
     unsigned i;
-    int column;
+    int column = 0;
     PRBool isString     = PR_TRUE;
     PRBool isWhiteSpace = PR_TRUE;
     PRBool printedHex   = PR_FALSE;
     unsigned int limit = 15;
 
     if ( m ) {
 	SECU_Indent(out, level); fprintf(out, "%s:", m);
 	level++;
@@ -679,17 +679,17 @@ static unsigned char nibble(char c) {
     c = PORT_Tolower(c);
     return ( c >= '0' && c <= '9') ? c - '0' :
            ( c >= 'a' && c <= 'f') ? c - 'a' +10 : -1;
 }
 
 SECStatus
 SECU_SECItemHexStringToBinary(SECItem* srcdest)
 {
-    int i;
+    unsigned int i;
 
     if (!srcdest) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
     }
     if (srcdest->len < 4 || (srcdest->len % 2) ) {
         /* too short to convert, or even number of characters */
         PORT_SetError(SEC_ERROR_BAD_DATA);
--- a/cmd/lib/derprint.c
+++ b/cmd/lib/derprint.c
@@ -441,17 +441,17 @@ prettyPrintLength(FILE *out, const unsig
 	    if (il < 0) return -1;
 	    *lenp = (unsigned) il;
 	} else {
 	    *lenp = 0;
 	    *indefinitep = PR_TRUE;
 	}
 	lenLen = nb + 1;
 	if (raw) {
-	    int i;
+	    unsigned int i;
 
 	    rv = prettyPrintByte(out, lbyte, lv);
 	    if (rv < 0)
 		return rv;
 	    for (i = 0; i < nb; i++) {
 		rv = prettyPrintByte(out, data[i], lv);
 		if (rv < 0)
 		    return rv;
@@ -498,19 +498,20 @@ prettyPrintItem(FILE *out, const unsigne
 	data += slen;
 
 	lenLen = prettyPrintLength(out, data, end, &slen, &indefinite, lv, raw);
 	if (lenLen < 0)
 	    return lenLen;
 	data += lenLen;
 
 	/*
-	 * Just quit now if slen more bytes puts us off the end.
+	 * Just quit now if slen more bytes puts us off the end,
+	 * or if there's no more data to process.
 	 */
-	if ((data + slen) > end) {
+	if ((data + slen) >= end) {
 	    PORT_SetError(SEC_ERROR_BAD_DER);
 	    return -1;
 	}
 
         if (code & SEC_ASN1_CONSTRUCTED) {
 	    if (slen > 0 || indefinite) {
 		slen = prettyPrintItem(out, data,
 				       slen == 0 ? end : data + slen,
--- a/cmd/lib/pk11table.c
+++ b/cmd/lib/pk11table.c
@@ -572,17 +572,17 @@ const Constant _consts[] = {
 	mkEntry(CKT_NSS_TRUST_UNKNOWN, Trust),
 	mkEntry(CKT_NSS_VALID_DELEGATOR, Trust),
 
 	mkEntry(CK_EFFECTIVELY_INFINITE, AvailableSizes),
 	mkEntry(CK_UNAVAILABLE_INFORMATION, CurrentSize),
 };
 
 const Constant *consts = &_consts[0];
-const int constCount = sizeof(_consts)/sizeof(_consts[0]);
+const unsigned int constCount = sizeof(_consts)/sizeof(_consts[0]);
 
 const Commands _commands[] = {
     {"C_Initialize", F_C_Initialize,
 "C_Initialize pInitArgs\n\n"
 "C_Initialize initializes the PKCS #11 library.\n"
 "  pInitArgs  if this is not NULL_PTR it gets cast to and dereferenced\n",
 	{ArgInitializeArgs, ArgNone, ArgNone, ArgNone, ArgNone,
 	 ArgNone, ArgNone, ArgNone, ArgNone, ArgNone }},
@@ -1384,17 +1384,17 @@ const Topics _topics[] = {
 };
 
 const Topics  *topics= &_topics[0];
 const int topicCount = sizeof(_topics) / sizeof(_topics[0]);
 
 const char *
 getName(CK_ULONG value, ConstType type)
 {
-    int i;
+    unsigned int i;
     
     for (i=0; i < constCount; i++) {
         if (consts[i].type == type && consts[i].value == value) {
             return consts[i].name;
         }
         if (type == ConstNone && consts[i].value == value) {
             return consts[i].name;
         }
@@ -1404,17 +1404,17 @@ getName(CK_ULONG value, ConstType type)
 }
 
 const char *
 getNameFromAttribute(CK_ATTRIBUTE_TYPE type)
 {
     return getName(type, ConstAttribute);
 }
 
-int totalKnownType(ConstType type) {
-    int count = 0;
-    int i;
+unsigned int totalKnownType(ConstType type) {
+    unsigned int count = 0;
+    unsigned int i;
  
     for (i=0; i < constCount; i++) {
         if (consts[i].type == type) count++;
     }
     return count;
 }
--- a/cmd/lib/pk11table.h
+++ b/cmd/lib/pk11table.h
@@ -157,24 +157,24 @@ typedef struct _topics {
  * the command array itself. Make name to function and it's arguments
  */
 
 extern const char **valueString;
 extern const int valueCount;
 extern const char **constTypeString;
 extern const int constTypeCount;
 extern const Constant *consts;
-extern const int constCount;
+extern const unsigned int constCount;
 extern const Commands *commands;
 extern const int commandCount;
 extern const Topics *topics;
 extern const int topicCount;
 
 extern const char *
 getName(CK_ULONG value, ConstType type);
 
 extern const char *
 getNameFromAttribute(CK_ATTRIBUTE_TYPE type);
 
-extern int totalKnownType(ConstType type);
+extern unsigned int totalKnownType(ConstType type);
 
 #endif /* _PK11_TABLE_H_ */
 
--- a/cmd/lib/secpwd.c
+++ b/cmd/lib/secpwd.c
@@ -69,30 +69,32 @@ char *SEC_GetPassword(FILE *input, FILE 
     for (;;) {
 	/* Prompt for password */
 	if (isTTY) {
 	    fprintf(output, "%s", prompt);
             fflush (output);
 	    echoOff(infd);
 	}
 
-	QUIET_FGETS ( phrase, sizeof(phrase), input);
+	if (QUIET_FGETS(phrase, sizeof(phrase), input) == NULL) {
+            return NULL;
+        }
 
 	if (isTTY) {
 	    fprintf(output, "\n");
 	    echoOn(infd);
 	}
 
 	/* stomp on newline */
 	phrase[PORT_Strlen(phrase)-1] = 0;
 
 	/* Validate password */
 	if (!(*ok)(phrase)) {
 	    /* Not weird enough */
-	    if (!isTTY) return 0;
+	    if (!isTTY) return NULL;
 	    fprintf(output, "Password must be at least 8 characters long with one or more\n");
 	    fprintf(output, "non-alphabetic characters\n");
 	    continue;
 	}
 	return (char*) PORT_Strdup(phrase);
     }
 }
 
--- a/cmd/lib/secutil.c
+++ b/cmd/lib/secutil.c
@@ -370,40 +370,43 @@ SECU_ChangePW2(PK11SlotInfo *slot, char 
 
 	if (PK11_CheckUserPassword(slot, oldpw) != SECSuccess) {
 	    if (pwdata.source == PW_NONE) {
 		PR_fprintf(PR_STDERR, "Invalid password.  Try again.\n");
 	    } else {
 		PR_fprintf(PR_STDERR, "Invalid password.\n");
 		PORT_Memset(oldpw, 0, PL_strlen(oldpw));
 		PORT_Free(oldpw);
-		return SECFailure;
+		rv = SECFailure;
+                goto done;
 	    }
 	} else
 	    break;
 
 	PORT_Free(oldpw);
     }
 
     newpw = secu_InitSlotPassword(slot, PR_FALSE, &newpwdata);
 
-    if (PK11_ChangePW(slot, oldpw, newpw) != SECSuccess) {
+    rv = PK11_ChangePW(slot, oldpw, newpw);
+    if (rv != SECSuccess) {
 	PR_fprintf(PR_STDERR, "Failed to change password.\n");
-	return SECFailure;
+    } else {
+        PR_fprintf(PR_STDOUT, "Password changed successfully.\n");
     }
 
     PORT_Memset(oldpw, 0, PL_strlen(oldpw));
     PORT_Free(oldpw);
 
-    PR_fprintf(PR_STDOUT, "Password changed successfully.\n");
-
 done:
-    PORT_Memset(newpw, 0, PL_strlen(newpw));
-    PORT_Free(newpw);
-    return SECSuccess;
+    if (newpw) {
+        PORT_Memset(newpw, 0, PL_strlen(newpw));
+        PORT_Free(newpw);
+    }
+    return rv;
 }
 
 struct matchobj {
     SECItem index;
     char *nname;
     PRBool found;
 };
 
@@ -1545,17 +1548,17 @@ SECU_PrintDumpDerIssuerAndSerial(FILE *o
     }
 
     PORT_Free(derIssuerB64);
     PORT_Free(derSerialB64);
     
     fprintf(out, "Serial DER as C source: \n{ %d, \"", c->serialNumber.len);
 
     {
-      int i;
+      unsigned int i;
       for (i=0; i < c->serialNumber.len; ++i) {
         unsigned char *chardata = (unsigned char*)(c->serialNumber.data);
         unsigned char c = *(chardata + i);
         
         fprintf(out, "\\x%02x", c);
       }
       fprintf(out, "\" }\n");
     }
@@ -2407,16 +2410,55 @@ SECU_PrintCertificate(FILE *out, const S
 	secu_PrintDecodedBitString(out, &c->subjectID, "Subject Unique ID", level+1);
     SECU_PrintExtensions(out, c->extensions, "Signed Extensions", level+1);
 loser:
     PORT_FreeArena(arena, PR_FALSE);
     return rv;
 }
 
 int
+SECU_PrintCertificateBasicInfo(FILE *out, const SECItem *der, const char *m, int level)
+{
+    PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+    CERTCertificate *c;
+    int rv = SEC_ERROR_NO_MEMORY;
+    
+    if (!arena)
+	return rv;
+
+    /* Decode certificate */
+    c = PORT_ArenaZNew(arena, CERTCertificate);
+    if (!c)
+	goto loser;
+    c->arena = arena;
+    rv = SEC_ASN1DecodeItem(arena, c, 
+                            SEC_ASN1_GET(CERT_CertificateTemplate), der);
+    if (rv) {
+        SECU_Indent(out, level); 
+	SECU_PrintErrMsg(out, level, "Error", "Parsing extension");
+	SECU_PrintAny(out, der, "Raw", level);
+	goto loser;
+    }
+    /* Pretty print it out */
+    SECU_Indent(out, level); fprintf(out, "%s:\n", m);
+    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);
+loser:
+    PORT_FreeArena(arena, PR_FALSE);
+    return rv;
+}
+
+int
 SECU_PrintSubjectPublicKeyInfo(FILE *out, SECItem *der, char *m, int level)
 {
     PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
     int          rv    = SEC_ERROR_NO_MEMORY;
     CERTSubjectPublicKeyInfo spki;
 
     if (!arena)
 	return rv;
@@ -2698,17 +2740,17 @@ secu_PrintPKCS7Signed(FILE *out, SEC_PKC
 
     /* Parse and list certificates (if any) */
     if (src->rawCerts != NULL) {
 	SECU_Indent(out, level + 1);  fprintf(out, "Certificate List:\n");
 	iv = 0;
 	while ((aCert = src->rawCerts[iv++]) != NULL) {
 	    sprintf(om, "Certificate (%x)", iv);
 	    rv = SECU_PrintSignedData(out, aCert, om, level + 2, 
-				      SECU_PrintCertificate);
+				      (SECU_PPFunc)SECU_PrintCertificate);
 	    if (rv)
 		return rv;
 	}
     }
 
     /* Parse and list CRL's (if any) */
     if (src->crls != NULL) {
 	SECU_Indent(out, level + 1);  
@@ -2817,17 +2859,17 @@ secu_PrintPKCS7SignedAndEnveloped(FILE *
 
     /* Parse and list certificates (if any) */
     if (src->rawCerts != NULL) {
 	SECU_Indent(out, level + 1);  fprintf(out, "Certificate List:\n");
 	iv = 0;
 	while ((aCert = src->rawCerts[iv++]) != NULL) {
 	    sprintf(om, "Certificate (%x)", iv);
 	    rv = SECU_PrintSignedData(out, aCert, om, level + 2, 
-				      SECU_PrintCertificate);
+				      (SECU_PPFunc)SECU_PrintCertificate);
 	    if (rv)
 		return rv;
 	}
     }
 
     /* Parse and list CRL's (if any) */
     if (src->crls != NULL) {
 	SECU_Indent(out, level + 1);  
@@ -3147,17 +3189,17 @@ SEC_PrintCertificateAndTrust(CERTCertifi
     SECStatus rv;
     SECItem data;
     CERTCertTrust certTrust;
     
     data.data = cert->derCert.data;
     data.len = cert->derCert.len;
 
     rv = SECU_PrintSignedData(stdout, &data, label, 0,
-			      SECU_PrintCertificate);
+			      (SECU_PPFunc)SECU_PrintCertificate);
     if (rv) {
 	return(SECFailure);
     }
     if (trust) {
 	SECU_PrintTrustFlags(stdout, trust,
 	                     "Certificate Trust Flags", 1);
     } else if (CERT_GetCertTrust(cert, &certTrust) == SECSuccess) {
 	SECU_PrintTrustFlags(stdout, &certTrust,
@@ -3238,33 +3280,33 @@ SECU_displayVerifyLog(FILE *outfile, CER
 		    }
 		}
 	    }
 	    fprintf(outfile, "  ERROR %ld: %s\n", node->error,
 			    SECU_Strerror(node->error));
 	    errstr = NULL;
 	    switch (node->error) {
 	    case SEC_ERROR_INADEQUATE_KEY_USAGE:
-		flags = (unsigned int)node->arg;
+		flags = (unsigned int)((char *)node->arg - (char *)NULL);
 		switch (flags) {
 		case KU_DIGITAL_SIGNATURE:
 		    errstr = "Cert cannot sign.";
 		    break;
 		case KU_KEY_ENCIPHERMENT:
 		    errstr = "Cert cannot encrypt.";
 		    break;
 		case KU_KEY_CERT_SIGN:
 		    errstr = "Cert cannot sign other certs.";
 		    break;
 		default:
 		    errstr = "[unknown usage].";
 		    break;
 		}
 	    case SEC_ERROR_INADEQUATE_CERT_TYPE:
-		flags = (unsigned int)node->arg;
+		flags = (unsigned int)((char *)node->arg - (char *)NULL);
 		switch (flags) {
 		case NS_CERT_TYPE_SSL_CLIENT:
 		case NS_CERT_TYPE_SSL_SERVER:
 		    errstr = "Cert cannot be used for SSL.";
 		    break;
 		case NS_CERT_TYPE_SSL_CA:
 		    errstr = "Cert cannot be used as an SSL CA.";
 		    break;
--- a/cmd/lib/secutil.h
+++ b/cmd/lib/secutil.h
@@ -216,16 +216,19 @@ int SECU_CheckCertNameExists(CERTCertDBH
 /* Dump contents of cert req */
 extern int SECU_PrintCertificateRequest(FILE *out, SECItem *der, char *m,
 	int level);
 
 /* Dump contents of certificate */
 extern int SECU_PrintCertificate(FILE *out, const SECItem *der, const char *m,
                                  int level);
 
+extern int SECU_PrintCertificateBasicInfo(FILE *out, const SECItem *der, const char *m,
+                                 int level);
+
 extern int SECU_PrintDumpDerIssuerAndSerial(FILE *out, SECItem *der, char *m,
                                  int level);
 
 /* Dump contents of a DER certificate name (issuer or subject) */
 extern int SECU_PrintDERName(FILE *out, SECItem *der, const char *m, int level);
 
 /* print trust flags on a cert */
 extern void SECU_PrintTrustFlags(FILE *out, CERTCertTrust *trust, char *m, 
--- a/cmd/modutil/error.h
+++ b/cmd/modutil/error.h
@@ -128,30 +128,12 @@ typedef enum {
 	DEFAULT_SUCCESS_MSG,
 	UNDEFAULT_SUCCESS_MSG,
 	BROWSER_RUNNING_MSG,
 	ABORTING_MSG,
 
 	LAST_MSG  /* must be last */
 } Message;
 
-static char *msgStrings[] = {
-	"FIPS mode enabled.\n",
-	"FIPS mode disabled.\n",
-	"Using database directory %s...\n",
-	"Creating \"%s\"...",
-	"Module \"%s\" added to database.\n",
-	"Module \"%s\" deleted from database.\n",
-	"Token \"%s\" password changed successfully.\n",
-	"Incorrect password, try again...\n",
-	"Passwords do not match, try again...\n",
-	"done.\n",
-	"Slot \"%s\" %s.\n",
-	"Successfully changed defaults.\n",
-	"Successfully changed defaults.\n",
-"\nWARNING: Performing this operation while the browser is running could cause"
-"\ncorruption of your security databases. If the browser is currently running,"
-"\nyou should exit browser before continuing this operation. Type "
-"\n'q <enter>' to abort, or <enter> to continue: ",
-	"\nAborting...\n"
-};
+/* defined in modutil.c */
+extern char *msgStrings[];
 
 #endif /* MODUTIL_ERROR_H */
--- a/cmd/modutil/install.c
+++ b/cmd/modutil/install.c
@@ -115,19 +115,20 @@ static char *msgStrings[] = {
 typedef struct StringNode_str {
     char *str;
     struct StringNode_str* next;
 } StringNode;
 
 StringNode* StringNode_new()
 {
 	StringNode* new_this;
-	new_this = (StringNode*)malloc(sizeof(StringNode));
-  new_this->str=NULL;
-  new_this->next=NULL;
+	new_this = (StringNode*)PR_Malloc(sizeof(StringNode));
+	PORT_Assert(new_this != NULL);
+	new_this->str = NULL;
+	new_this->next = NULL;
 	return new_this;
 }
 
 void StringNode_delete(StringNode* s) 
 {
 	if(s->str) {
 		PR_Free(s->str);
 		s->str=NULL;
--- a/cmd/modutil/installparse.c
+++ b/cmd/modutil/installparse.c
@@ -198,34 +198,34 @@ Pk11Install_yyerror(char *message)
 int
 yyparse()
 {
     register int yym, yyn, yystate;
 #if YYDEBUG
     register char *yys;
     extern char *getenv();
 
-    if (yys = getenv("YYDEBUG"))
+    if ((yys = getenv("YYDEBUG")) != NULL)
     {
         yyn = *yys;
         if (yyn >= '0' && yyn <= '9')
             yydebug = yyn - '0';
     }
 #endif
 
     yynerrs = 0;
     yyerrflag = 0;
     yychar = (-1);
 
     yyssp = yyss;
     yyvsp = yyvs;
     *yyssp = yystate = 0;
 
 yyloop:
-    if (yyn = yydefred[yystate]) goto yyreduce;
+    if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
     if (yychar < 0)
     {
         if ((yychar = yylex()) < 0) yychar = 0;
 #if YYDEBUG
         if (yydebug)
         {
             yys = 0;
             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
--- a/cmd/modutil/lex.Pk11Install_yy.c
+++ b/cmd/modutil/lex.Pk11Install_yy.c
@@ -1095,16 +1095,17 @@ register char *yy_bp;
 
 	yytext_ptr = yy_bp;
 	yy_hold_char = *yy_cp;
 	yy_c_buf_p = yy_cp;
 	}
 #endif	/* ifndef YY_NO_UNPUT */
 
 
+#ifndef YY_NO_INPUT
 #ifdef __cplusplus
 static int yyinput()
 #else
 static int input()
 #endif
 	{
 	int c;
 
@@ -1166,16 +1167,17 @@ static int input()
 
 	c = *(unsigned char *) yy_c_buf_p;	/* cast for 8-bit char's */
 	*yy_c_buf_p = '\0';	/* preserve yytext */
 	yy_hold_char = *++yy_c_buf_p;
 
 
 	return c;
 	}
+#endif	/* ifndef YY_NO_INPUT */
 
 
 #ifdef YY_USE_PROTOS
 void yyrestart( FILE *input_file )
 #else
 void yyrestart( input_file )
 FILE *input_file;
 #endif
--- a/cmd/modutil/manifest.mn
+++ b/cmd/modutil/manifest.mn
@@ -19,16 +19,16 @@ CSRCS = modutil.c		\
 		$(NULL)
 
 CPPSRCS = 
 
 PROGRAM =  modutil
 
 REQUIRES = seccmd nss dbm
 
-DEFINES = -DNSPR20
+DEFINES = -DNSPR20 -DYY_NO_UNPUT -DYY_NO_INPUT
 
 # sigh
 #INCLUDES += -I$(CORE_DEPTH)/nss/lib/pk11wrap
 
 # USE_STATIC_LIBS = 1 
 
 EXTRA_LIBS = $(JAR_LIBS)
--- a/cmd/modutil/modutil.c
+++ b/cmd/modutil/modutil.c
@@ -117,16 +117,37 @@ static char *optionStrings[] = {
 	"-installdir",
 	"-tempdir",
 	"-secmod",
 	"-nocertdb",
 	"-string",
 	"-chkfips",
 };
 
+char *msgStrings[] = {
+	"FIPS mode enabled.\n",
+	"FIPS mode disabled.\n",
+	"Using database directory %s...\n",
+	"Creating \"%s\"...",
+	"Module \"%s\" added to database.\n",
+	"Module \"%s\" deleted from database.\n",
+	"Token \"%s\" password changed successfully.\n",
+	"Incorrect password, try again...\n",
+	"Passwords do not match, try again...\n",
+	"done.\n",
+	"Slot \"%s\" %s.\n",
+	"Successfully changed defaults.\n",
+	"Successfully changed defaults.\n",
+"\nWARNING: Performing this operation while the browser is running could cause"
+"\ncorruption of your security databases. If the browser is currently running,"
+"\nyou should exit browser before continuing this operation. Type "
+"\n'q <enter>' to abort, or <enter> to continue: ",
+	"\nAborting...\n"
+};
+
 /* Increment i if doing so would have i still be less than j.  If you
    are able to do this, return 0.  Otherwise return 1. */
 #define TRY_INC(i,j)  ( ((i+1)<j) ? (++i, 0) : 1 )
 
 /********************************************************************
  *
  * file-wide variables obtained from the command line
  */
--- a/cmd/multinit/multinit.c
+++ b/cmd/multinit/multinit.c
@@ -309,37 +309,16 @@ appendHex(unsigned char nibble)
     if (nibble <= 9) {
 	appendLabel('0'+nibble);
     } else {
 	appendLabel('a'+nibble-10);
     }
 }
 
 /*
- * append a secitem as colon separated hex bytes.
- */
-static void
-appendItem(SECItem *item)
-{
-    int i;
-
-    if (!buffer.data) {
-	return;
-    }
-
-    appendLabel(':');
-    for (i=0; i < item->len; i++) {
-	unsigned char byte=item->data[i];
-	appendHex(byte >> 4);
-	appendHex(byte & 0xf);
-	appendLabel(':');
-    }
-}
-
-/*
  * append a 32 bit integer (even on a 64 bit platform).
  * for simplicity append it as a hex value, full extension with 0x prefix.
  */
 static void
 appendInt(unsigned int value)
 {
     int i;
 
@@ -488,17 +467,17 @@ sort_CN(CERTCertificate *certa, CERTCert
  */
 void
 do_list_certs(const char *progName, int log)
 {
    CERTCertList *list;
    CERTCertList *sorted;
    CERTCertListNode *node;
    CERTCertTrust trust;
-   int i;
+   unsigned int i;
 
    list = PK11_ListCerts(PK11CertListUnique, NULL);
    if (list == NULL) {
 	fprintf(stderr,"ERROR: no certs found %s\n", 
 		SECU_Strerror(PORT_GetError()));
 	appendLabel('C');
 	appendString("none");
 	return;
--- a/cmd/ocspclnt/ocspclnt.c
+++ b/cmd/ocspclnt/ocspclnt.c
@@ -557,17 +557,17 @@ print_raw_certificates (FILE *out_file, 
 	fprintf (out_file, "No Certificates.\n");
 	return;
     }
 
     fprintf (out_file, "Certificate List:\n");
     while ((raw_cert = raw_certs[i++]) != NULL) {
 	sprintf (cert_label, "Certificate (%d)", i);
 	(void) SECU_PrintSignedData (out_file, raw_cert, cert_label, level + 1,
-				     SECU_PrintCertificate);
+				     (SECU_PPFunc)SECU_PrintCertificate);
     }
 }
 
 
 static void
 print_ocsp_extensions (FILE *out_file, CERTCertExtension **extensions,
 		       char *msg, int level)
 {
@@ -959,17 +959,17 @@ main (int argc, char **argv)
     int		 ccert, vcert;
     const char	*db_dir, *date_str, *cert_usage_str, *name;
     const char	*responder_name, *responder_url, *signer_name;
     PRBool	 add_acceptable_responses, add_service_locator;
     SECItem	*data = NULL;
     PLOptState	*optstate;
     SECStatus	 rv;
     CERTCertDBHandle *handle = NULL;
-    SECCertUsage cert_usage;
+    SECCertUsage cert_usage = certUsageSSLClient;
     PRTime	 verify_time;
     CERTCertificate *cert = NULL;
     PRBool ascii = PR_FALSE;
 
     retval = -1;		/* what we return/exit with on error */
 
     program_name = PL_strrchr(argv[0], '/');
     program_name = program_name ? (program_name + 1) : argv[0];
--- a/cmd/ocspresp/ocspresp.c
+++ b/cmd/ocspresp/ocspresp.c
@@ -124,25 +124,22 @@ main(int argc, char **argv)
     CERTCertDBHandle *certHandle = NULL;
     CERTCertificate *caCert = NULL, *cert = NULL;
     CERTOCSPCertID *cid = NULL;
     PLArenaPool *arena = NULL;
     PRTime now = PR_Now();
     
     SECItem *encoded = NULL;
     CERTOCSPResponse *decoded = NULL;
-    SECStatus statusDecoded;
 
     SECItem *encodedRev = NULL;
     CERTOCSPResponse *decodedRev = NULL;
-    SECStatus statusDecodedRev;
     
     SECItem *encodedFail = NULL;
     CERTOCSPResponse *decodedFail = NULL;
-    SECStatus statusDecodedFail;
 
     CERTCertificate *obtainedSignerCert = NULL;
 
     if (argc != 4 && argc != 6) {
         return Usage();
     }
 
     if (argc == 6) {
@@ -176,50 +173,57 @@ main(int argc, char **argv)
         goto loser;
 
     cid = CERT_CreateOCSPCertID(cert, now);
 
     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
     encoded = encode(arena, cid, caCert);
     PORT_Assert(encoded);
     decoded = CERT_DecodeOCSPResponse(encoded);
-    statusDecoded = CERT_GetOCSPResponseStatus(decoded);
-    PORT_Assert(statusDecoded == SECSuccess);
+    PORT_CheckSuccess(CERT_GetOCSPResponseStatus(decoded));
 
-    statusDecoded = CERT_VerifyOCSPResponseSignature(decoded, certHandle, &pwdata,
-                                                &obtainedSignerCert, caCert);
-    PORT_Assert(statusDecoded == SECSuccess);
-    statusDecoded = CERT_GetOCSPStatusForCertID(certHandle, decoded, cid,
-                                                obtainedSignerCert, now);
-    PORT_Assert(statusDecoded == SECSuccess);
+    PORT_CheckSuccess(CERT_VerifyOCSPResponseSignature(decoded, certHandle, &pwdata,
+                                                        &obtainedSignerCert, caCert));
+    PORT_CheckSuccess(CERT_GetOCSPStatusForCertID(certHandle, decoded, cid,
+                                                   obtainedSignerCert, now));
     CERT_DestroyCertificate(obtainedSignerCert);
 
     encodedRev = encodeRevoked(arena, cid, caCert);
     PORT_Assert(encodedRev);
     decodedRev = CERT_DecodeOCSPResponse(encodedRev);
-    statusDecodedRev = CERT_GetOCSPResponseStatus(decodedRev);
-    PORT_Assert(statusDecodedRev == SECSuccess);
+    PORT_CheckSuccess(CERT_GetOCSPResponseStatus(decodedRev));
 
-    statusDecodedRev = CERT_VerifyOCSPResponseSignature(decodedRev, certHandle, &pwdata,
-                                                        &obtainedSignerCert, caCert);
-    PORT_Assert(statusDecodedRev == SECSuccess);
-    statusDecodedRev = CERT_GetOCSPStatusForCertID(certHandle, decodedRev, cid,
+    PORT_CheckSuccess(CERT_VerifyOCSPResponseSignature(decodedRev, certHandle, &pwdata,
+                                                        &obtainedSignerCert, caCert));
+#ifdef DEBUG
+    {
+        SECStatus rv = CERT_GetOCSPStatusForCertID(certHandle, decodedRev, cid,
                                                    obtainedSignerCert, now);
-    PORT_Assert(statusDecodedRev == SECFailure);
-    PORT_Assert(PORT_GetError() == SEC_ERROR_REVOKED_CERTIFICATE);
+        PORT_Assert(rv == SECFailure);
+        PORT_Assert(PORT_GetError() == SEC_ERROR_REVOKED_CERTIFICATE);
+    }
+#else
+    (void)CERT_GetOCSPStatusForCertID(certHandle, decodedRev, cid,
+                                      obtainedSignerCert, now);
+#endif
     CERT_DestroyCertificate(obtainedSignerCert);
     
     encodedFail = CERT_CreateEncodedOCSPErrorResponse(
         arena, SEC_ERROR_OCSP_TRY_SERVER_LATER);
     PORT_Assert(encodedFail);
     decodedFail = CERT_DecodeOCSPResponse(encodedFail);
-    statusDecodedFail = CERT_GetOCSPResponseStatus(decodedFail);
-    PORT_Assert(statusDecodedFail == SECFailure);
-    PORT_Assert(PORT_GetError() == SEC_ERROR_OCSP_TRY_SERVER_LATER);
-
+#ifdef DEBUG
+    {
+        SECStatus rv = CERT_GetOCSPResponseStatus(decodedFail);
+        PORT_Assert(rv == SECFailure);
+        PORT_Assert(PORT_GetError() == SEC_ERROR_OCSP_TRY_SERVER_LATER);
+    }
+#else
+    (void)CERT_GetOCSPResponseStatus(decodedFail);
+#endif
     retval = 0;
 loser:
     if (retval != 0)
         SECU_PrintError(argv[0], "tests failed");
     
     if (cid)
         CERT_DestroyOCSPCertID(cid);
     if (cert)
--- a/cmd/oidcalc/oidcalc.c
+++ b/cmd/oidcalc/oidcalc.c
@@ -39,23 +39,23 @@ main(int argc, char **argv)
     nextstr = strchr(curstr, '.');
 
     if ( nextstr ) {
 	*nextstr = '\0';
     }
 
     secondval = atoi(curstr);
     
-    if ( ( firstval < 0 ) || ( firstval > 2 ) ) {
+    if ( firstval > 2 ) {
 	fprintf(stderr, "first component out of range\n");
 	exit(-1);
 	
     }
     
-    if ( ( secondval < 0 ) || ( secondval > 39 ) ) {
+    if ( secondval > 39 ) {
 	fprintf(stderr, "second component out of range\n");
 	exit(-1);
     }
     
     printf("0x%x, ", ( firstval * 40 ) + secondval );
     while ( nextstr ) {
 	curstr = nextstr + 1;
 
--- a/cmd/p7env/p7env.c
+++ b/cmd/p7env/p7env.c
@@ -125,29 +125,27 @@ EncryptFile(FILE *outFile, FILE *inFile,
     return 0;
 }
 
 int
 main(int argc, char **argv)
 {
     char *progName;
     FILE *inFile, *outFile;
-    char *certName;
     CERTCertDBHandle *certHandle;
     struct recipient *recipients, *rcpt;
     PLOptState *optstate;
     PLOptStatus status;
     SECStatus rv;
 
     progName = strrchr(argv[0], '/');
     progName = progName ? progName+1 : argv[0];
 
     inFile = NULL;
     outFile = NULL;
-    certName = NULL;
     recipients = NULL;
     rcpt = NULL;
 
     /*
      * Parse command line arguments
      * XXX This needs to be enhanced to allow selection of algorithms
      * and key sizes (or to look up algorithms and key sizes for each
      * recipient in the magic database).
--- a/cmd/pk11gcmtest/pk11gcmtest.c
+++ b/cmd/pk11gcmtest/pk11gcmtest.c
@@ -161,32 +161,32 @@ aes_gcm_kat(const char *respfn)
 {
     char buf[512];      /* holds one line from the input REQUEST file.
                          * needs to be large enough to hold the longest
                          * line "CIPHERTEXT = <320 hex digits>\n".
                          */
     FILE *aesresp;      /* input stream from the RESPONSE file */
     int i, j;
     unsigned int test_group = 0;
-    unsigned int num_tests;
+    unsigned int num_tests = 0;
     PRBool is_encrypt;
     unsigned char key[32];              /* 128, 192, or 256 bits */
-    unsigned int keysize;
+    unsigned int keysize = 16;
     unsigned char iv[10*16];            /* 1 to 10 blocks */
-    unsigned int ivsize;
+    unsigned int ivsize = 12;
     unsigned char plaintext[10*16];     /* 1 to 10 blocks */
     unsigned int plaintextlen = 0;
     unsigned char aad[10*16];           /* 1 to 10 blocks */
     unsigned int aadlen = 0;
     unsigned char ciphertext[10*16];    /* 1 to 10 blocks */
-    unsigned int ciphertextlen;
+    unsigned int ciphertextlen = 0;
     unsigned char tag[16];
-    unsigned int tagsize;
+    unsigned int tagsize = 16;
     unsigned char output[10*16];         /* 1 to 10 blocks */
-    unsigned int outputlen;
+    unsigned int outputlen = 0;
 
     unsigned int expected_keylen = 0;
     unsigned int expected_ivlen = 0;
     unsigned int expected_ptlen = 0;
     unsigned int expected_aadlen = 0;
     unsigned int expected_taglen = 0;
     SECStatus rv;
 
--- a/cmd/pk11mode/pk11mode.c
+++ b/cmd/pk11mode/pk11mode.c
@@ -2085,27 +2085,27 @@ CK_RV PKM_Mechanism(CK_FUNCTION_LIST_PTR
                                             pMechanismList, &mechanismCount);
     if (crv != CKR_OK) {
         PKM_Error( "C_GetMechanismList failed with 0x%08X, %-26s\n", crv, 
                    PKM_CK_RVtoStr(crv));
         return crv;
     }
     PKM_LogIt("C_GetMechanismList returned the mechanism types:\n");
     if (verbose) {
-        for (i = 1; i <= mechanismCount; i++) {
-            mechName = getName(pMechanismList[(i-1)], ConstMechanism);
+        for (i = 0; i < mechanismCount; i++) {
+            mechName = getName(pMechanismList[(i)], ConstMechanism);
 
             /* output two mechanism name on each line */
             /* currently the longest known mechansim name length is 37 */
             if (mechName) {
                 printf("%-40s",mechName);
             } else {
                 printf("Unknown mechanism: 0x%08lX ", pMechanismList[i]);
             }    
-            if ((i != 0) && ((i % 2) == 0 )) printf("\n");
+            if ((i % 2) == 1 ) printf("\n");
         }
         printf("\n\n");
     }
 
     for ( i = 0; i < mechanismCount; i++ ) {
         CK_MECHANISM_INFO minfo;
 
         memset(&minfo, 0, sizeof(CK_MECHANISM_INFO));
@@ -3501,18 +3501,18 @@ CK_RV PKM_FindAllObjects(CK_FUNCTION_LIS
                          CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen) {
     CK_RV crv = CKR_OK;
 
     CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0;
     CK_SESSION_INFO sinfo;
     CK_ATTRIBUTE_PTR pTemplate;
     CK_ULONG tnObjects = 0;
     int curMode;
-    int i;
-    int  number_of_all_known_attribute_types = totalKnownType(ConstAttribute);
+    unsigned int i;
+    unsigned int  number_of_all_known_attribute_types = totalKnownType(ConstAttribute);
 
     NUMTESTS++; /* increment NUMTESTS */
 
     crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
                                        NULL, NULL, &h);
     if ( CKR_OK != crv ) {
         PKM_Error("C_OpenSession(%lu, CKF_SERIAL_SESSION, , )"
                   "returned 0x%08X, %-26s\n", pSlotList[slotID], crv, 
@@ -4553,17 +4553,17 @@ CK_RV
 PKM_TLSMasterKeyDerive( CK_FUNCTION_LIST_PTR pFunctionList,
                         CK_SLOT_ID * pSlotList, CK_ULONG slotID,
                         CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen,
                         CK_MECHANISM_TYPE mechType,
                         enum_random_t rnd)  {
     CK_SESSION_HANDLE hSession;
     CK_RV crv;
     CK_MECHANISM            mk_mech;
-    CK_VERSION              expected_version, version;
+    CK_VERSION              version;
     CK_OBJECT_CLASS         class = CKO_SECRET_KEY;
     CK_KEY_TYPE             type = CKK_GENERIC_SECRET;
     CK_BBOOL                derive_bool = true;
     CK_ATTRIBUTE            attrs[4];
     CK_ULONG                attrs_count = 4;
     CK_OBJECT_HANDLE        pmk_obj = CK_INVALID_HANDLE;
     CK_OBJECT_HANDLE        mk_obj = CK_INVALID_HANDLE;
     CK_SSL3_MASTER_KEY_DERIVE_PARAMS mkd_params;
@@ -4620,18 +4620,16 @@ PKM_TLSMasterKeyDerive( CK_FUNCTION_LIST
 
     switch (mechType) {
     case CKM_TLS_MASTER_KEY_DERIVE_DH:
         isDH = true;
         /* FALLTHRU */
     case CKM_TLS_MASTER_KEY_DERIVE:
         attrs[3].pValue = NULL;
         attrs[3].ulValueLen = 0;
-        expected_version.major = 3;
-        expected_version.minor = 1;
 
         mkd_params.RandomInfo.pClientRandom = (unsigned char * ) TLSClientRandom;
         mkd_params.RandomInfo.ulClientRandomLen =
         sizeof (TLSClientRandom);
         mkd_params.RandomInfo.pServerRandom = (unsigned char * ) TLSServerRandom;
         mkd_params.RandomInfo.ulServerRandomLen =
         sizeof (TLSServerRandom);
         break;
--- a/cmd/pk12util/pk12util.c
+++ b/cmd/pk12util/pk12util.c
@@ -40,17 +40,17 @@ Usage(char *progName)
     FPS "\t\t [-k slotpwfile | -K slotpw] [-w p12filepwfile | -W p12filepw]\n");
     FPS "\t\t [-v]\n");
 
     FPS "Usage:	 %s -o exportfile -n certname [-d certdir] [-P dbprefix]\n",
 		progName);
     FPS "\t\t [-c key_cipher] [-C cert_cipher]\n"
         "\t\t [-m | --key_len keyLen] [--cert_key_len certKeyLen] [-v]\n");
     FPS "\t\t [-k slotpwfile | -K slotpw]\n"
-		"\t\t [-w p12filepwfile | -W p12filefilepw]\n");
+        "\t\t [-w p12filepwfile | -W p12filepw]\n");
 
     exit(PK12UERR_USAGE);
 }
 
 static PRBool
 p12u_OpenFile(p12uContext *p12cxt, PRBool fileRead)
 {
     if(!p12cxt || !p12cxt->filename) {
@@ -96,19 +96,16 @@ p12u_DestroyContext(p12uContext **ppCtx,
     PR_Free(*ppCtx);
     *ppCtx = NULL;
 }
 
 static p12uContext *
 p12u_InitContext(PRBool fileImport, char *filename)
 {
     p12uContext *p12cxt;
-    PRBool fileExist;
-
-    fileExist = fileImport;
 
     p12cxt = PORT_ZNew(p12uContext);
     if(!p12cxt) {
 	return NULL;
     }
 
     p12cxt->error = PR_FALSE;
     p12cxt->errorValue = 0;
@@ -754,17 +751,17 @@ P12U_ListPKCS12File(char *in_file, PK11S
 			                    "Cannot create output file");
 			} else {
 			    PR_Write(fd, dip->der->data, dip->der->len);
 			    PR_Close(fd);
 			}
 		    } else 
                     if (SECU_PrintSignedData(stdout, dip->der,
                             (dip->hasKey) ? "(has private key)" : "",
-                             0, SECU_PrintCertificate) != 0) {
+                             0, (SECU_PPFunc)SECU_PrintCertificate) != 0) {
                         SECU_PrintError(progName,"PKCS12 print cert bag failed");
                     }
                     if (dip->friendlyName != NULL) {
                         printf("    Friendly Name: %s\n\n",
                                 dip->friendlyName->data);
                     }
 		    if (dip->shroudAlg) {
 			SECU_PrintAlgorithmID(stdout, dip->shroudAlg,
--- a/cmd/pk1sign/pk1sign.c
+++ b/cmd/pk1sign/pk1sign.c
@@ -170,17 +170,17 @@ SignFile(FILE *outFile, PRFileDesc *inFi
 int
 main(int argc, char **argv)
 {
     char *progName;
     FILE *outFile;
     PRFileDesc *inFile;
     char *keyName = NULL;
     CERTCertDBHandle *certHandle;
-    CERTCertificate *cert;
+    CERTCertificate *cert = NULL;
     PLOptState *optstate;
     PLOptStatus status;
     SECStatus rv;
 
     progName = strrchr(argv[0], '/');
     progName = progName ? progName+1 : argv[0];
 
     inFile = NULL;
--- a/cmd/platlibs.mk
+++ b/cmd/platlibs.mk
@@ -82,18 +82,18 @@ EXTRA_LIBS += \
 	$(DIST)/lib/$(LIB_PREFIX)certdb.$(LIB_SUFFIX) \
 	$(SOFTOKENLIB) \
 	$(CRYPTOLIB) \
 	$(DIST)/lib/$(LIB_PREFIX)nsspki.$(LIB_SUFFIX) \
 	$(DIST)/lib/$(LIB_PREFIX)nssdev.$(LIB_SUFFIX) \
 	$(DIST)/lib/$(LIB_PREFIX)nssb.$(LIB_SUFFIX) \
 	$(PKIXLIB) \
 	$(DBMLIB) \
-	$(DIST)/lib/$(LIB_PREFIX)$(SQLITE_LIB_NAME).$(LIB_SUFFIX) \
-	$(DIST)/lib/$(LIB_PREFIX)nssutil3.$(LIB_SUFFIX) \
+	$(SQLITE_LIB_DIR)/$(LIB_PREFIX)$(SQLITE_LIB_NAME).$(LIB_SUFFIX) \
+	$(NSSUTIL_LIB_DIR)/$(LIB_PREFIX)nssutil3.$(LIB_SUFFIX) \
 	$(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.$(LIB_SUFFIX) \
 	$(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.$(LIB_SUFFIX) \
 	$(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.$(LIB_SUFFIX) \
 	$(NULL)
 
 # $(PROGRAM) has NO explicit dependencies on $(OS_LIBS)
 #OS_LIBS += \
 	wsock32.lib \
@@ -130,17 +130,17 @@ EXTRA_LIBS += \
 
 ifeq ($(OS_ARCH), AIX) 
 EXTRA_SHARED_LIBS += -brtl 
 endif
 
 # $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS)
 # $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
 EXTRA_SHARED_LIBS += \
-	-L$(DIST)/lib \
+	-L$(SQLITE_LIB_DIR) \
 	-l$(SQLITE_LIB_NAME) \
 	-L$(NSSUTIL_LIB_DIR) \
 	-lnssutil3 \
 	-L$(NSPR_LIB_DIR) \
 	-lplc4 \
 	-lplds4 \
 	-lnspr4 \
 	$(NULL)
@@ -148,17 +148,17 @@ endif
 
 else # USE_STATIC_LIBS
 # can't do this in manifest.mn because OS_ARCH isn't defined there.
 ifeq ($(OS_ARCH), WINNT)
 
 # $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
 EXTRA_LIBS += \
 	$(DIST)/lib/$(LIB_PREFIX)sectool.$(LIB_SUFFIX) \
-	$(DIST)/lib/$(IMPORT_LIB_PREFIX)nssutil3$(IMPORT_LIB_SUFFIX) \
+	$(NSSUTIL_LIB_DIR)/$(IMPORT_LIB_PREFIX)nssutil3$(IMPORT_LIB_SUFFIX) \
 	$(DIST)/lib/$(IMPORT_LIB_PREFIX)smime3$(IMPORT_LIB_SUFFIX) \
 	$(DIST)/lib/$(IMPORT_LIB_PREFIX)ssl3$(IMPORT_LIB_SUFFIX) \
 	$(DIST)/lib/$(IMPORT_LIB_PREFIX)nss3$(IMPORT_LIB_SUFFIX) \
 	$(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4$(IMPORT_LIB_SUFFIX) \
 	$(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4$(IMPORT_LIB_SUFFIX) \
 	$(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4$(IMPORT_LIB_SUFFIX) \
 	$(NULL)
 
--- a/cmd/pp/pp.c
+++ b/cmd/pp/pp.c
@@ -20,24 +20,26 @@ extern int fprintf(FILE *, char *, ...);
 #include "nss.h"
 
 static void Usage(char *progName)
 {
     fprintf(stderr,
 	    "Usage:  %s [-t type] [-a] [-i input] [-o output] [-w] [-u]\n",
 	    progName);
     fprintf(stderr, "Pretty prints a file containing ASN.1 data in DER or ascii format.\n");
-    fprintf(stderr, "%-14s Specify input and display type: %s (sk),\n",
-	    "-t type", SEC_CT_PRIVATE_KEY);
+    fprintf(stderr, "%-14s Specify input and display type:", "-t type");
+#ifdef HAVE_EPV_TEMPLATE
+    fprintf(stderr, " %s (sk),", SEC_CT_PRIVATE_KEY);
+#endif
+    fprintf(stderr, "\n");
     fprintf(stderr, "%-14s %s (pk), %s (c), %s (cr),\n", "", SEC_CT_PUBLIC_KEY,
 	    SEC_CT_CERTIFICATE, SEC_CT_CERTIFICATE_REQUEST);
     fprintf(stderr, "%-14s %s (ci), %s (p7), %s or %s (n).\n", "", SEC_CT_CERTIFICATE_ID,
             SEC_CT_PKCS7, SEC_CT_CRL, SEC_CT_NAME);
-    fprintf(stderr, "%-14s (Use either the long type name or the shortcut.)\n", "", SEC_CT_CERTIFICATE_ID,
-            SEC_CT_PKCS7, SEC_CT_CRL, SEC_CT_NAME);
+    fprintf(stderr, "%-14s (Use either the long type name or the shortcut.)\n", "");
     fprintf(stderr, "%-14s Input is in ascii encoded form (RFC1113)\n",
 	    "-a");
     fprintf(stderr, "%-14s Define an input file to use (default is stdin)\n",
 	    "-i input");
     fprintf(stderr, "%-14s Define an output file to use (default is stdout)\n",
 	    "-o output");
     fprintf(stderr, "%-14s Don't wrap long output lines\n",
 	    "-w");
@@ -132,17 +134,17 @@ int main(int argc, char **argv)
     data.len = der.len;
 
     SECU_EnableWrap(wrap);
 
     /* Pretty print it */
     if (PORT_Strcmp(typeTag, SEC_CT_CERTIFICATE) == 0 ||
         PORT_Strcmp(typeTag, "c") == 0) {
 	rv = SECU_PrintSignedData(outFile, &data, "Certificate", 0,
-			     SECU_PrintCertificate);
+			     (SECU_PPFunc)SECU_PrintCertificate);
     } else if (PORT_Strcmp(typeTag, SEC_CT_CERTIFICATE_ID) == 0 ||
                PORT_Strcmp(typeTag, "ci") == 0) {
         rv = SECU_PrintSignedContent(outFile, &data, 0, 0,
                                      SECU_PrintDumpDerIssuerAndSerial);
     } else if (PORT_Strcmp(typeTag, SEC_CT_CERTIFICATE_REQUEST) == 0 ||
                PORT_Strcmp(typeTag, "cr") == 0) {
 	rv = SECU_PrintSignedData(outFile, &data, "Certificate Request", 0,
 			     SECU_PrintCertificateRequest);
--- a/cmd/sdrtest/sdrtest.c
+++ b/cmd/sdrtest/sdrtest.c
@@ -66,19 +66,19 @@ long_usage (char *program_name)
     PR_fprintf (pr_stderr,
 		"  %-13s supply \"password\" on the command line\n",
 		"-p password");
 }
 
 int 
 readStdin(SECItem * result)
 {
-  int bufsize = 0;
+  unsigned int bufsize = 0;
   int cc;
-  int wanted  = 8192;
+  unsigned int wanted  = 8192U;
 
   result->len = 0;
   result->data = NULL;
   do {
     if (bufsize < wanted) {
       unsigned char * tmpData = (unsigned char *)PR_Realloc(result->data, wanted);
       if (!tmpData) {
 	if (verbose) PR_fprintf(pr_stderr, "Allocation of buffer failed\n");
--- a/cmd/selfserv/selfserv.c
+++ b/cmd/selfserv/selfserv.c
@@ -60,29 +60,29 @@ static int handle_connection( PRFileDesc
 
 static const char envVarName[] = { SSL_ENV_VAR_NAME };
 static const char inheritableSockName[] = { "SELFSERV_LISTEN_SOCKET" };
 
 #define DEFAULT_BULK_TEST 16384
 #define MAX_BULK_TEST     1048576 /* 1 MB */
 static PRBool testBulk;
 static PRUint32 testBulkSize       = DEFAULT_BULK_TEST;
-static PRUint32 testBulkTotal;
+static PRInt32 testBulkTotal;
 static char* testBulkBuf;
 static PRDescIdentity log_layer_id = PR_INVALID_IO_LAYER;
 static PRFileDesc *loggingFD;
 static PRIOMethods loggingMethods;
 
 static PRBool logStats;
 static PRBool loggingLayer;
 static int logPeriod = 30;
-static PRUint32 loggerOps;
-static PRUint32 loggerBytes;
-static PRUint32 loggerBytesTCP;
-static PRUint32 bulkSentChunks;
+static PRInt32 loggerOps;
+static PRInt32 loggerBytes;
+static PRInt32 loggerBytesTCP;
+static PRInt32 bulkSentChunks;
 static enum ocspStaplingModeEnum {
     osm_disabled,  /* server doesn't support stapling */
     osm_good,      /* supply a signed good status */
     osm_revoked,   /* supply a signed revoked status */
     osm_unknown,   /* supply a signed unknown status */
     osm_failure,   /* supply a unsigned failure status, "try later" */
     osm_badsig,    /* supply a good status response with a bad signature */
     osm_corrupted, /* supply a corrupted data block as the status */
@@ -114,38 +114,41 @@ const int ssl3CipherSuites[] = {
     TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,		/* g */
     -1, /* SSL_FORTEZZA_DMS_WITH_NULL_SHA,	 * h */
     TLS_RSA_WITH_NULL_MD5,			/* i */
     SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,		/* j */
     SSL_RSA_FIPS_WITH_DES_CBC_SHA,		/* k */
     TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,	/* l */
     TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,	        /* m */
     TLS_RSA_WITH_RC4_128_SHA,			/* n */
-    -1, /* TLS_DHE_DSS_WITH_RC4_128_SHA, 	 * o */
-    -1, /* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,	 * p */
-    -1, /* TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,	 * q */
-    -1, /* TLS_DHE_RSA_WITH_DES_CBC_SHA,	 * r */
-    -1, /* TLS_DHE_DSS_WITH_DES_CBC_SHA,	 * s */
-    -1, /* TLS_DHE_DSS_WITH_AES_128_CBC_SHA,	 * t */
-    -1, /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA,	 * u */
+    TLS_DHE_DSS_WITH_RC4_128_SHA, 	 /* o */
+    TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,	 /* p */
+    TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,	 /* q */
+    TLS_DHE_RSA_WITH_DES_CBC_SHA,	 /* r */
+    TLS_DHE_DSS_WITH_DES_CBC_SHA,	 /* s */
+    TLS_DHE_DSS_WITH_AES_128_CBC_SHA,	 /* t */
+    TLS_DHE_RSA_WITH_AES_128_CBC_SHA,	 /* u */
     TLS_RSA_WITH_AES_128_CBC_SHA,     	    	/* v */
-    -1, /* TLS_DHE_DSS_WITH_AES_256_CBC_SHA,	 * w */
-    -1, /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA,	 * x */
+    TLS_DHE_DSS_WITH_AES_256_CBC_SHA,	 /* w */
+    TLS_DHE_RSA_WITH_AES_256_CBC_SHA,	 /* x */
     TLS_RSA_WITH_AES_256_CBC_SHA,     	    	/* y */
     TLS_RSA_WITH_NULL_SHA,			/* z */
     0
 };
 
 /* data and structures for shutdown */
 static int	stopping;
 
 static PRBool  noDelay;
 static int     requestCert;
 static int	verbose;
 static SECItem	bigBuf;
+static int configureDHE = -1; /* -1: don't configure, 0 disable, >=1 enable*/
+static int configureReuseECDHE = -1; /* -1: don't configure, 0 refresh, >=1 reuse*/
+static int configureWeakDHE = -1; /* -1: don't configure, 0 disable, >=1 enable*/
 
 static PRThread * acceptorThread;
 
 static PRLogModuleInfo *lm;
 
 #define PRINTF  if (verbose)  printf
 #define FPRINTF if (verbose) fprintf
 #define FLUSH	if (verbose) { fflush(stdout); fflush(stderr); }
@@ -155,21 +158,22 @@ static void
 PrintUsageHeader(const char *progName)
 {
     fprintf(stderr, 
 "Usage: %s -n rsa_nickname -p port [-BDENRbjlmrsuvx] [-w password]\n"
 "         [-t threads] [-i pid_file] [-c ciphers] [-Y] [-d dbdir] [-g numblocks]\n"
 "         [-f password_file] [-L [seconds]] [-M maxProcs] [-P dbprefix]\n"
 "         [-V [min-version]:[max-version]] [-a sni_name]\n"
 "         [ T <good|revoked|unknown|badsig|corrupted|none|ocsp>] [-A ca]\n"
+"         [-C SSLCacheEntries] [-S dsa_nickname]"
 #ifndef NSS_DISABLE_ECC
-"         [-C SSLCacheEntries] [-e ec_nickname]\n"
-#else
-"         [-C SSLCacheEntries]\n"
+                                                " [-e ec_nickname]"
 #endif /* NSS_DISABLE_ECC */
+"\n"
+"         -U [0|1] -H [0|1] -W [0|1]\n"
         ,progName);
 }
 
 static void
 PrintParameterUsage()
 {
     fputs(
 "-V [min]:[max] restricts the set of enabled SSL/TLS protocol versions.\n"
@@ -211,16 +215,19 @@ PrintParameterUsage()
 "   good, revoked, unknown: Include locally signed response. Requires: -A\n"
 "   failure: return a failure response (try later, unsigned)\n"
 "   badsig: use a good status but with an invalid signature\n"
 "   corrupted: stapled cert status is an invalid block of data\n"
 "   random: each connection uses a random status from this list:\n"
 "           good, revoked, unknown, failure, badsig, corrupted\n"
 "   ocsp: fetch from external OCSP server using AIA, or none\n"
 "-A <ca> Nickname of a CA used to sign a stapled cert status\n"
+"-U override default ECDHE ephemeral key reuse, 0: refresh, 1: reuse\n"
+"-H override default DHE server support, 0: disable, 1: enable\n"
+"-W override default DHE server weak parameters support, 0: disable, 1: enable\n"
 "-c Restrict ciphers\n"
 "-Y prints cipher values allowed for parameter -c and exits\n"
     , stderr);
 }
 
 static void
 Usage(const char *progName)
 {
@@ -247,17 +254,26 @@ PrintCipherUsage(const char *progName)
 "f    SSL3 RSA EXPORT WITH RC4 40 MD5\n"
 "g    SSL3 RSA EXPORT WITH RC2 CBC 40 MD5\n"
 "i    SSL3 RSA WITH NULL MD5\n"
 "j    SSL3 RSA FIPS WITH 3DES EDE CBC SHA\n"
 "k    SSL3 RSA FIPS WITH DES CBC SHA\n"
 "l    SSL3 RSA EXPORT WITH DES CBC SHA\t(new)\n"
 "m    SSL3 RSA EXPORT WITH RC4 56 SHA\t(new)\n"
 "n    SSL3 RSA WITH RC4 128 SHA\n"
+"o    TLS_DHE_DSS_WITH_RC4_128_SHA\n"
+"p    TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA\n"
+"q    TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA\n"
+"r    TLS_DHE_RSA_WITH_DES_CBC_SHA\n"
+"s    TLS_DHE_DSS_WITH_DES_CBC_SHA\n"
+"t    TLS_DHE_DSS_WITH_AES_128_CBC_SHA\n"
+"u    TLS_DHE_RSA_WITH_AES_128_CBC_SHA\n"
 "v    SSL3 RSA WITH AES 128 CBC SHA\n"
+"w    TLS_DHE_DSS_WITH_AES_256_CBC_SHA\n"
+"x    TLS_DHE_RSA_WITH_AES_256_CBC_SHA\n"
 "y    SSL3 RSA WITH AES 256 CBC SHA\n"
 "z    SSL3 RSA WITH NULL SHA\n"
 "\n"
 ":WXYZ  Use cipher with hex code { 0xWX , 0xYZ } in TLS\n"
     , stderr);
 }
 
 static const char *
@@ -407,20 +423,21 @@ printSecurityInfo(PRFileDesc *fd)
 	if (result == SECSuccess) {
 	    FPRINTF(stderr, 
 	    "selfserv: SSL version %d.%d using %d-bit %s with %d-bit %s MAC\n",
 	       channel.protocolVersion >> 8, channel.protocolVersion & 0xff,
 	       suite.effectiveKeyBits, suite.symCipherName, 
 	       suite.macBits, suite.macAlgorithmName);
 	    FPRINTF(stderr, 
 	    "selfserv: Server Auth: %d-bit %s, Key Exchange: %d-bit %s\n"
-	    "          Compression: %s\n",
+            "          Compression: %s, Extended Master Secret: %s\n",
 	       channel.authKeyBits, suite.authAlgorithmName,
 	       channel.keaKeyBits,  suite.keaTypeName,
-	       channel.compressionMethodName);
+               channel.compressionMethodName,
+               channel.extendedMasterSecretUsed ? "Yes": "No");
     	}
     }
     if (verbose) {
         SECItem *hostInfo  = SSL_GetNegotiatedHostInfo(fd);
         if (hostInfo) {
             char namePref[] = "selfserv: Negotiated server name: ";
 
             fprintf(stderr, "%s", namePref);
@@ -481,18 +498,18 @@ mySSLSNISocketConfig(PRFileDesc *fd, con
 
     PORT_Assert(fd && sniNameArr);
     if (!fd || !sniNameArr) {
 	return SSL_SNI_SEND_ALERT;
     }
 
     pwdata = SSL_RevealPinArg(fd);
 
-    for (;current && i < sniNameArrSize;i++) {
-        int j = 0;
+    for (;current && (PRUint32)i < sniNameArrSize;i++) {
+        unsigned int j = 0;
         for (;j < MAX_VIRT_SERVER_NAME_ARRAY_INDEX && nameArr[j];j++) {
             if (!PORT_Strncmp(nameArr[j],
                               (const char *)current[i].data,
                               current[i].len) &&
                 PORT_Strlen(nameArr[j]) == current[i].len) {
                 const char *nickName = nameArr[j];
                 if (j == 0) {
                     /* default cert */
@@ -730,18 +747,18 @@ terminateWorkerThreads(void)
 static void 
 logger(void *arg)
 {
     PRFloat64 seconds;
     PRFloat64 opsPerSec;
     PRIntervalTime period;
     PRIntervalTime previousTime;
     PRIntervalTime latestTime;
-    PRUint32 previousOps;
-    PRUint32 ops;
+    PRInt32 previousOps;
+    PRInt32 ops;
     PRIntervalTime logPeriodTicks = PR_TicksPerSecond();
     PRFloat64 secondsPerTick = 1.0 / (PRFloat64)logPeriodTicks;
     int iterations = 0;
     int secondsElapsed = 0;
     static PRInt64 totalPeriodBytes = 0;
     static PRInt64 totalPeriodBytesTCP = 0;
 
     previousOps = loggerOps;
@@ -750,17 +767,17 @@ logger(void *arg)
     for (;;) {
         /* OK, implementing a new sleep algorithm here... always sleep 
          * for 1 second but print out info at the user-specified interval.
          * This way, we don't overflow all of our PR_Atomic* functions and 
          * we don't have to use locks. 
          */
         PR_Sleep(logPeriodTicks);
         secondsElapsed++;
-        totalPeriodBytes +=  PR_ATOMIC_SET(&loggerBytes, 0);
+        totalPeriodBytes += PR_ATOMIC_SET(&loggerBytes, 0);
         totalPeriodBytesTCP += PR_ATOMIC_SET(&loggerBytesTCP, 0);
         if (secondsElapsed != logPeriod) {
             continue;
         }
         /* when we reach the user-specified logging interval, print out all
          * data 
          */
         secondsElapsed = 0;
@@ -816,16 +833,18 @@ PRBool NoReuse         = PR_FALSE;
 PRBool hasSidCache     = PR_FALSE;
 PRBool disableStepDown = PR_FALSE;
 PRBool bypassPKCS11    = PR_FALSE;
 PRBool disableLocking  = PR_FALSE;
 PRBool testbypass      = PR_FALSE;
 PRBool enableSessionTickets = PR_FALSE;
 PRBool enableCompression    = PR_FALSE;
 PRBool failedToNegotiateName  = PR_FALSE;
+PRBool enableExtendedMasterSecret = PR_FALSE;
+
 static char  *virtServerNameArray[MAX_VIRT_SERVER_NAME_ARRAY_INDEX];
 static int                  virtServerNameIndex = 1;
 
 
 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[] = {
@@ -1108,48 +1127,48 @@ makeCorruptedOCSPResponse(PLArenaPool *a
 
 SECItemArray *
 makeSignedOCSPResponse(PLArenaPool *arena, ocspStaplingModeType osm,
 		       CERTCertificate *cert, secuPWData *pwdata)
 {
     SECItemArray *result = NULL;
     SECItem *ocspResponse = NULL;
     CERTOCSPSingleResponse **singleResponses;
-    CERTOCSPSingleResponse *sr;
+    CERTOCSPSingleResponse *sr = NULL;
     CERTOCSPCertID *cid = NULL;
     CERTCertificate *ca;
     PRTime now = PR_Now();
     PRTime nextUpdate;
 
     PORT_Assert(cert != NULL);
 
     ca = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), ocspStaplingCA);
     if (!ca)
 	errExit("cannot find CA");
 
     cid = CERT_CreateOCSPCertID(cert, now);
     if (!cid)
 	errExit("cannot created cid");
 
-    nextUpdate = now + 60*60*24 * PR_USEC_PER_SEC; /* plus 1 day */
+    nextUpdate = now + (PRTime)60*60*24 * PR_USEC_PER_SEC; /* plus 1 day */
 
     switch (osm) {
 	case osm_good:
 	case osm_badsig:
 	    sr = CERT_CreateOCSPSingleResponseGood(arena, cid, now,
 						   &nextUpdate);
 	    break;
 	case osm_unknown:
 	    sr = CERT_CreateOCSPSingleResponseUnknown(arena, cid, now,
 						      &nextUpdate);
 	    break;
 	case osm_revoked:
 	    sr = CERT_CreateOCSPSingleResponseRevoked(arena, cid, now,
 		&nextUpdate,
-		now - 60*60*24 * PR_USEC_PER_SEC, /* minus 1 day */
+		now - (PRTime)60*60*24 * PR_USEC_PER_SEC, /* minus 1 day */
 		NULL);
 	    break;
 	default:
 	    PORT_Assert(0);
 	    break;
     }
 
     if (!sr)
@@ -1900,16 +1919,44 @@ server_main(
     if (virtServerNameIndex >1) {
         rv = SSL_SNISocketConfigHook(model_sock, mySSLSNISocketConfig,
                                      (void*)&virtServerNameArray);
         if (rv != SECSuccess) {
             errExit("error enabling SNI extension ");
         }
     }
 
+    if (configureDHE > -1) {
+	rv = SSL_OptionSet(model_sock, SSL_ENABLE_SERVER_DHE, (configureDHE > 0));
+        if (rv != SECSuccess) {
+            errExit("error configuring server side DHE support");
+        }
+    }
+
+    if (configureReuseECDHE > -1) {
+	rv = SSL_OptionSet(model_sock, SSL_REUSE_SERVER_ECDHE_KEY, (configureReuseECDHE > 0));
+        if (rv != SECSuccess) {
+            errExit("error configuring server side reuse of ECDHE key");
+        }
+    }
+
+    if (configureWeakDHE > -1) {
+	rv = SSL_EnableWeakDHEPrimeGroup(model_sock, (configureWeakDHE > 0));
+        if (rv != SECSuccess) {
+            errExit("error configuring weak DHE prime group");
+        }
+    }
+
+    if  (enableExtendedMasterSecret) {
+        rv = SSL_OptionSet(model_sock, SSL_ENABLE_EXTENDED_MASTER_SECRET, PR_TRUE);
+	if (rv != SECSuccess) {
+	    errExit("error enabling extended master secret ");
+	}
+    }
+
     for (kea = kt_rsa; kea < kt_kea_size; kea++) {
 	if (cert[kea] != NULL) {
 	    secStatus = SSL_ConfigSecureServer(model_sock, 
 	    		cert[kea], privKey[kea], kea);
 	    if (secStatus != SECSuccess)
 		errExit("SSL_ConfigSecureServer");
 	}
     }
@@ -2131,16 +2178,17 @@ SECStatus enableOCSPStapling(const char*
 int
 main(int argc, char **argv)
 {
     char *               progName    = NULL;
     char *               nickName    = NULL;
 #ifndef NSS_DISABLE_ECC
     char *               ecNickName   = NULL;
 #endif
+    char *               dsaNickName  = NULL;
     const char *         fileName    = NULL;
     char *               cipherString= NULL;
     const char *         dir         = ".";
     char *               passwd      = NULL;
     char *               pwfile      = NULL;
     const char *         pidFile     = NULL;
     char *               tmp;
     char *               envString;
@@ -2175,30 +2223,33 @@ main(int argc, char **argv)
 
     PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
     SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledVersions);
 
     /* please keep this list of options in ASCII collating sequence.
     ** numbers, then capital letters, then lower case, alphabetical. 
     */
     optstate = PL_CreateOptState(argc, argv, 
-        "2:A:BC:DEL:M:NP:RT:V:Ya:bc:d:e:f:g:hi:jk:lmn:op:qrst:uvw:xyz");
+        "2:A:BC:DEGH:L:M:NP:RS:T:U:V:W:Ya:bc:d:e:f:g:hi:jk:lmn:op:qrst:uvw:xyz");
     while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
 	++optionsFound;
 	switch(optstate->option) {
 	case '2': fileName = optstate->value; break;
 
 	case 'A': ocspStaplingCA = PORT_Strdup(optstate->value); break;
 
 	case 'B': bypassPKCS11 = PR_TRUE; break;
 
         case 'C': if (optstate->value) NumSidCacheEntries = PORT_Atoi(optstate->value); break;
 
 	case 'D': noDelay = PR_TRUE; break;
 	case 'E': disableStepDown = PR_TRUE; break;
+	case 'H': configureDHE = (PORT_Atoi(optstate->value) != 0); break;
+
+        case 'G': enableExtendedMasterSecret = PR_TRUE; break;
 
 	case 'I': /* reserved for OCSP multi-stapling */ break;
 
         case 'L':
             logStats = PR_TRUE;
 	    if (optstate->value == NULL) {
 	    	logPeriod = 30;
 	    } else {
@@ -2212,35 +2263,41 @@ main(int argc, char **argv)
 	    if (maxProcs < 1)         maxProcs = 1;
 	    if (maxProcs > MAX_PROCS) maxProcs = MAX_PROCS;
 	    break;
 
 	case 'N': NoReuse = PR_TRUE; break;
 
 	case 'R': disableRollBack = PR_TRUE; break;
 
+	case 'S': dsaNickName = PORT_Strdup(optstate->value); break;
+
 	case 'T':
 	    if (enableOCSPStapling(optstate->value) != SECSuccess) {
 		fprintf(stderr, "Invalid OCSP stapling mode.\n");
 		fprintf(stderr, "Run '%s -h' for usage information.\n", progName);
 		exit(53);
 	    }
 	    break;
 
+	case 'U': configureReuseECDHE = (PORT_Atoi(optstate->value) != 0); break;
+
         case 'V': if (SECU_ParseSSLVersionRangeString(optstate->value,
                           enabledVersions, enableSSL2,
                           &enabledVersions, &enableSSL2) != SECSuccess) {
                       Usage(progName);
                   }
                   break;
 
+	case 'W': configureWeakDHE = (PORT_Atoi(optstate->value) != 0); break;
+
         case 'Y': PrintCipherUsage(progName); exit(0); break;
         
 	case 'a': if (virtServerNameIndex >= MAX_VIRT_SERVER_NAME_ARRAY_INDEX) {
-                      Usage(progName);
+                      Usage(progName); break;
                   }
                   virtServerNameArray[virtServerNameIndex++] =
                       PORT_Strdup(optstate->value); break;
 
 	case 'b': bindOnly = PR_TRUE; break;
 
 	case 'c': cipherString = PORT_Strdup(optstate->value); break;
 
@@ -2357,16 +2414,17 @@ main(int argc, char **argv)
 	}
         if (listen_sock) {
             PR_Close(listen_sock);
         }
 	exit(0);
     }
 
     if ((nickName == NULL)
+        && (dsaNickName == NULL)
  #ifndef NSS_DISABLE_ECC
 						&& (ecNickName == NULL)
  #endif
     ) {
 
 	fprintf(stderr, "Required arg '-n' (rsa nickname) not supplied.\n");
 	fprintf(stderr, "Run '%s -h' for usage information.\n", progName);
         exit(6);
@@ -2588,16 +2646,43 @@ main(int argc, char **argv)
 		exit(14);
 	    }
 	    fprintf(stderr, "selfserv: %s can%s bypass\n", nickName,
 		    bypassOK ? "" : "not");
 	}
 	setupCertStatus(certStatusArena, ocspStaplingMode, cert[kt_rsa], kt_rsa,
 			&pwdata);
     }
+    if (dsaNickName) {
+	/* Investigate if ssl_kea_dh should be changed to ssl_auth_dsa.
+	 * See bug 102794.*/
+	cert[ssl_kea_dh] = PK11_FindCertFromNickname(dsaNickName, &pwdata);
+	if (cert[ssl_kea_dh] == NULL) {
+	    fprintf(stderr, "selfserv: Can't find certificate %s\n", dsaNickName);
+	    exit(12);
+	}
+	privKey[ssl_kea_dh] = PK11_FindKeyByAnyCert(cert[ssl_kea_dh], &pwdata);
+	if (privKey[ssl_kea_dh] == NULL) {
+	    fprintf(stderr, "selfserv: Can't find Private Key for cert %s\n",
+	            dsaNickName);
+	    exit(11);
+	}
+	if (testbypass) {
+	    PRBool bypassOK;
+	    if (SSL_CanBypass(cert[ssl_kea_dh], privKey[ssl_kea_dh], protos, cipherlist,
+	                      nciphers, &bypassOK, &pwdata) != SECSuccess) {
+		SECU_PrintError(progName, "Bypass test failed %s\n", nickName);
+		exit(14);
+	    }
+	    fprintf(stderr, "selfserv: %s can%s bypass\n", nickName,
+		    bypassOK ? "" : "not");
+	}
+	setupCertStatus(certStatusArena, ocspStaplingMode, cert[ssl_kea_dh], ssl_kea_dh,
+			&pwdata);
+    }
 #ifndef NSS_DISABLE_ECC
     if (ecNickName) {
 	cert[kt_ecdh] = PK11_FindCertFromNickname(ecNickName, &pwdata);
 	if (cert[kt_ecdh] == NULL) {
 	    fprintf(stderr, "selfserv: Can't find certificate %s\n",
 		    ecNickName);
 	    exit(13);
 	}
@@ -2620,16 +2705,23 @@ main(int argc, char **argv)
 	setupCertStatus(certStatusArena, ocspStaplingMode, cert[kt_ecdh], kt_ecdh,
 			&pwdata);
     }
 #endif /* NSS_DISABLE_ECC */
 
     if (testbypass)
 	goto cleanup;
 
+    if (configureWeakDHE > 0) {
+	fprintf(stderr, "selfserv: Creating dynamic weak DH parameters\n");
+	rv = SSL_EnableWeakDHEPrimeGroup(NULL, PR_TRUE);
+	fprintf(stderr, "selfserv: Done creating dynamic weak DH parameters\n");
+    }
+
+
 /* allocate the array of thread slots, and launch the worker threads. */
     rv = launch_threads(&jobLoop, 0, 0, requestCert, useLocalThreads);
 
     if (rv == SECSuccess && logStats) {
 	loggerThread = PR_CreateThread(PR_SYSTEM_THREAD, 
 			logger, NULL, PR_PRIORITY_NORMAL, 
                         useLocalThreads ? PR_LOCAL_THREAD:PR_GLOBAL_THREAD,
                         PR_JOINABLE_THREAD, 0);
--- a/cmd/shlibsign/shlibsign.c
+++ b/cmd/shlibsign/shlibsign.c
@@ -190,16 +190,20 @@ static const unsigned char base[] = {
     0x08, 0xcd, 0x68, 0x3a, 0x77, 0xc2, 0xc5, 0xf1, 
     0x99, 0x0f, 0x15, 0x1b, 0x6a, 0x8c, 0x3d, 0x18, 
     0x2b, 0x6f, 0xdc, 0x2b, 0xd8, 0xb5, 0x9b, 0xb8, 
     0x2d, 0x57, 0x92, 0x1c, 0x46, 0x27, 0xaf, 0x6d, 
     0xe1, 0x45, 0xcf, 0x0b, 0x3f, 0xfa, 0x07, 0xcc, 
     0x14, 0x8e, 0xe7, 0xb8, 0xaa, 0xd5, 0xd1, 0x36, 
     0x1d, 0x7e, 0x5e, 0x7d, 0xfa, 0x5b, 0x77, 0x1f };
 
+/*
+ * The constants h, seed, & counter aren't used in the code; they're provided
+ * here (commented-out) so that human readers can verify that our our PQG
+ * parameters were generated properly.
 static const unsigned char h[] = { 
     0x41, 0x87, 0x47, 0x79, 0xd8, 0xba, 0x4e, 0xac, 
     0x44, 0x4f, 0x6b, 0xd2, 0x16, 0x5e, 0x04, 0xc6, 
     0xc2, 0x29, 0x93, 0x5e, 0xbd, 0xc7, 0xa9, 0x8f, 
     0x23, 0xa1, 0xc8, 0xee, 0x80, 0x64, 0xd5, 0x67, 
     0x3c, 0xba, 0x59, 0x9a, 0x06, 0x0c, 0xcc, 0x29, 
     0x56, 0xc0, 0xb2, 0x21, 0xe0, 0x5b, 0x52, 0xcd, 
     0x84, 0x73, 0x57, 0xfd, 0xd8, 0xc3, 0x5b, 0x13, 
@@ -227,16 +231,17 @@ static const unsigned char seed[] = { 0x
     0x4f, 0x4c, 0x58, 0x1c, 0x7f, 0x61, 0x3c, 0x36, 
     0xd5, 0x2f, 0xa5, 0x66, 0xd8, 0x2f, 0xce, 0x6e, 
     0x8e, 0x20, 0x48, 0x4a, 0xbb, 0xe3, 0xe0, 0xb2, 
     0x50, 0x33, 0x63, 0x8a, 0x5b, 0x2d, 0x6a, 0xbe, 
     0x4c, 0x28, 0x81, 0x53, 0x5b, 0xe4, 0xf6, 0xfc, 
     0x64, 0x06, 0x13, 0x51, 0xeb, 0x4a, 0x91, 0x9c };
 
 static const unsigned int counter=1496;
+ */
 
 static const unsigned char prime2[] = { 0x00,
     0xa4, 0xc2, 0x83, 0x4f, 0x36, 0xd3, 0x4f, 0xae,
     0xa0, 0xb1, 0x47, 0x43, 0xa8, 0x15, 0xee, 0xad,
     0xa3, 0x98, 0xa3, 0x29, 0x45, 0xae, 0x5c, 0xd9,
     0x12, 0x99, 0x09, 0xdc, 0xef, 0x05, 0xb4, 0x98,
     0x05, 0xaa, 0x07, 0xaa, 0x83, 0x89, 0xd7, 0xba,
     0xd1, 0x25, 0x56, 0x58, 0xd1, 0x73, 0x3c, 0xd0,
@@ -302,16 +307,20 @@ static const unsigned char base2[] = { 0
     0xa2, 0x6f, 0xf8, 0xba, 0x99, 0x90, 0xc7, 0xe5,
     0xb1, 0x3c, 0x10, 0x34, 0x86, 0x6a, 0x6a, 0x1f,
     0x39, 0x63, 0x58, 0xe1, 0x5e, 0x97, 0x95, 0x45,
     0x40, 0x38, 0x45, 0x6f, 0x02, 0xb5, 0x86, 0x6e,
     0xae, 0x2f, 0x32, 0x7e, 0xa1, 0x3a, 0x34, 0x2c,
     0x1c, 0xd3, 0xff, 0x4e, 0x2c, 0x38, 0x1c, 0xaa,
     0x2e, 0x66, 0xbe, 0x32, 0x3e, 0x3c, 0x06, 0x5f };
 
+/*
+ * The constants h2, seed2, & counter2 aren't used in the code; they're provided
+ * here (commented-out) so that human readers can verify that our our PQG
+ * parameters were generated properly.
 static const unsigned char h2[] = { 
     0x30, 0x91, 0xa1, 0x2e, 0x40, 0xa5, 0x7d, 0xf7,
     0xdc, 0xed, 0xee, 0x05, 0xc2, 0x31, 0x91, 0x37,
     0xda, 0xc5, 0xe3, 0x47, 0xb5, 0x35, 0x4b, 0xfd,
     0x18, 0xb2, 0x7e, 0x67, 0x1e, 0x92, 0x22, 0xe7,
     0xf5, 0x00, 0x71, 0xc0, 0x86, 0x8d, 0x90, 0x31,
     0x36, 0x3e, 0xd0, 0x94, 0x5d, 0x2f, 0x9a, 0x68,
     0xd2, 0xf8, 0x3d, 0x5e, 0x84, 0x42, 0x35, 0xda,
@@ -371,16 +380,17 @@ static const unsigned char seed2[] = { 0
     0x2d, 0x91, 0xf9, 0x84, 0x45, 0x4d, 0xc7, 0xe1,
     0xee, 0xd4, 0xb8, 0x61, 0x3b, 0x13, 0xb7, 0xba,
     0x95, 0x39, 0xf6, 0x3d, 0x89, 0xbd, 0xa5, 0x80,
     0x93, 0xf7, 0xe5, 0x17, 0x05, 0xc5, 0x65, 0xb7,
     0xde, 0xc9, 0x9f, 0x04, 0x87, 0xcf, 0x4f, 0x86,
     0xc3, 0x29, 0x7d, 0xb7, 0x89, 0xbf, 0xe3, 0xde };
 
 static const unsigned int counter2=210;
+ */
 
 struct tuple_str {
     CK_RV         errNum;
     const char * errString;
 };
 
 typedef struct tuple_str tuple_str;
 
@@ -507,17 +517,17 @@ CK_RVtoStr(CK_RV errNum) {
             }
             lastNum = num;
         }
         initDone = 1;
     }
 
     /* Do binary search of table. */
     while (low + 1 < high) {
-        i = (low + high) / 2;
+        i = low + (high - low) / 2;
         num = errStrings[i].errNum;
         if (errNum == num)
             return errStrings[i].errString;
         if (errNum < num)
             high = i;
         else
             low = i;
     }
@@ -692,17 +702,17 @@ int main(int argc, char **argv)
     PRFileDesc *fd;
     PRStatus rv = PR_SUCCESS;
     const char  *input_file = NULL; /* read/create encrypted data from here */
     char  *output_file = NULL;	/* write new encrypted data here */
     int bytesRead;
     int bytesWritten;
     unsigned char file_buf[512];
     int count=0;
-    int keySize = 0;
+    unsigned int keySize = 0;
     int i;
     PRBool verify = PR_FALSE;
     static PRBool FIPSMODE = PR_FALSE;
     PRBool successful = PR_FALSE;
 
 #ifdef USES_LINKS
     int ret;
     struct stat stat_buf;
--- a/cmd/signtool/certgen.c
+++ b/cmd/signtool/certgen.c
@@ -68,16 +68,19 @@ GenerateCert(char *nickname, int keysize
 	    "must choose a different nickname.\n", nickname);
 	errorCount++;
 	exit(ERRX);
     }
 
     LL_L2UI(serial, PR_Now());
 
     subject = GetSubjectFromUser(serial);
+    if (!subject) {
+	FatalError("Unable to get subject from user");
+    }
 
     cert = GenerateSelfSignedObjectSigningCert(nickname, db, subject,
          		serial, keysize, token);
 
     if (cert) {
 	output_ca_cert(cert, db);
 	CERT_DestroyCertificate(cert);
     }
@@ -117,17 +120,19 @@ GetSubjectFromUser(unsigned long serial)
 #ifdef VERBOSE_PROMPTS
     PR_fprintf(PR_STDOUT, "\nCOMMON NAME\n"
         "Enter the full name you want to give your certificate. (Example: Test-Only\n"
         "Object Signing Certificate)\n"
         "-->");
 #else
     PR_fprintf(PR_STDOUT, "certificate common name: ");
 #endif
-    fgets(buf, STDIN_BUF_SIZE, stdin);
+    if (!fgets(buf, STDIN_BUF_SIZE, stdin)) {
+	return NULL;
+    }
     cp = chop(buf);
     if (*cp == '\0') {
 	sprintf(common_name_buf, "%s (%lu)", DEFAULT_COMMON_NAME,
 	     serial);
 	cp = common_name_buf;
     }
     common_name = PORT_ZAlloc(strlen(cp) + 6);
     if (!common_name) {
@@ -139,17 +144,19 @@ GetSubjectFromUser(unsigned long serial)
 #ifdef VERBOSE_PROMPTS
     PR_fprintf(PR_STDOUT, "\nORGANIZATION NAME\n"
         "Enter the name of your organization. For example, this could be the name\n"
         "of your company.\n"
         "-->");
 #else
     PR_fprintf(PR_STDOUT, "organization: ");
 #endif
-    fgets(buf, STDIN_BUF_SIZE, stdin);
+    if (!fgets(buf, STDIN_BUF_SIZE, stdin)) {
+	return NULL;
+    }
     cp = chop(buf);
     if (*cp != '\0') {
 	org = PORT_ZAlloc(strlen(cp) + 5);
 	if (!org) {
 	    out_of_memory();
 	}
 	sprintf(org, "O=%s, ", cp);
 	subjectlen += strlen(org);
@@ -158,17 +165,19 @@ GetSubjectFromUser(unsigned long serial)
 #ifdef VERBOSE_PROMPTS
     PR_fprintf(PR_STDOUT, "\nORGANIZATION UNIT\n"
         "Enter the name of your organization unit.  For example, this could be the\n"
         "name of your department.\n"
         "-->");
 #else
     PR_fprintf(PR_STDOUT, "organization unit: ");
 #endif
-    fgets(buf, STDIN_BUF_SIZE, stdin);
+    if (!fgets(buf, STDIN_BUF_SIZE, stdin)) {
+	return NULL;
+    }
     cp = chop(buf);
     if (*cp != '\0') {
 	orgunit = PORT_ZAlloc(strlen(cp) + 6);
 	if (!orgunit) {
 	    out_of_memory();
 	}
 	sprintf(orgunit, "OU=%s, ", cp);
 	subjectlen += strlen(orgunit);
@@ -176,17 +185,19 @@ GetSubjectFromUser(unsigned long serial)
 
 #ifdef VERBOSE_PROMPTS
     PR_fprintf(PR_STDOUT, "\nSTATE\n"
         "Enter the name of your state or province.\n"
         "-->");
 #else
     PR_fprintf(PR_STDOUT, "state or province: ");
 #endif
-    fgets(buf, STDIN_BUF_SIZE, stdin);
+    if (!fgets(buf, STDIN_BUF_SIZE, stdin)) {
+	return NULL;
+    }
     cp = chop(buf);
     if (*cp != '\0') {
 	state = PORT_ZAlloc(strlen(cp) + 6);
 	if (!state) {
 	    out_of_memory();
 	}
 	sprintf(state, "ST=%s, ", cp);
 	subjectlen += strlen(state);
@@ -194,17 +205,19 @@ GetSubjectFromUser(unsigned long serial)
 
 #ifdef VERBOSE_PROMPTS
     PR_fprintf(PR_STDOUT, "\nCOUNTRY\n"
         "Enter the 2-character abbreviation for the name of your country.\n"
         "-->");
 #else
     PR_fprintf(PR_STDOUT, "country (must be exactly 2 characters): ");
 #endif
-    fgets(buf, STDIN_BUF_SIZE, stdin);
+    if (!fgets(buf, STDIN_BUF_SIZE, stdin)) {
+	return NULL;
+    }
     cp = chop(cp);
     if (strlen(cp) != 2) {
 	*cp = '\0';	/* country code must be 2 chars */
     }
     if (*cp != '\0') {
 	country = PORT_ZAlloc(strlen(cp) + 5);
 	if (!country) {
 	    out_of_memory();
@@ -215,17 +228,19 @@ GetSubjectFromUser(unsigned long serial)
 
 #ifdef VERBOSE_PROMPTS
     PR_fprintf(PR_STDOUT, "\nUSERNAME\n"
         "Enter your system username or UID\n"
         "-->");
 #else
     PR_fprintf(PR_STDOUT, "username: ");
 #endif
-    fgets(buf, STDIN_BUF_SIZE, stdin);
+    if (!fgets(buf, STDIN_BUF_SIZE, stdin)) {
+	return NULL;
+    }
     cp = chop(buf);
     if (*cp != '\0') {
 	uid = PORT_ZAlloc(strlen(cp) + 7);
 	if (!uid) {
 	    out_of_memory();
 	}
 	sprintf(uid, "UID=%s, ", cp);
 	subjectlen += strlen(uid);
@@ -233,17 +248,19 @@ GetSubjectFromUser(unsigned long serial)
 
 #ifdef VERBOSE_PROMPTS
     PR_fprintf(PR_STDOUT, "\nEMAIL ADDRESS\n"
         "Enter your email address.\n"
         "-->");
 #else
     PR_fprintf(PR_STDOUT, "email address: ");
 #endif
-    fgets(buf, STDIN_BUF_SIZE, stdin);
+    if (!fgets(buf, STDIN_BUF_SIZE, stdin)) {
+	return NULL;
+    }
     cp = chop(buf);
     if (*cp != '\0') {
 	email = PORT_ZAlloc(strlen(cp) + 5);
 	if (!email) {
 	    out_of_memory();
 	}
 	sprintf(email, "E=%s,", cp);
 	subjectlen += strlen(email);
@@ -415,17 +432,16 @@ set_cert_type(CERTCertificate *cert, uns
 static SECItem *
 sign_cert(CERTCertificate *cert, SECKEYPrivateKey *privk)
 {
     SECStatus rv;
 
     SECItem der2;
     SECItem * result2;
 
-    void	*dummy;
     SECOidTag alg = SEC_OID_UNKNOWN;
 
     alg = SEC_GetSignatureAlgorithmOidTag(privk->keyType, SEC_OID_UNKNOWN);
     if (alg == SEC_OID_UNKNOWN) {
 	FatalError("Unknown key type");
     }
 
     rv = SECOID_SetAlgorithmID (cert->arena, &cert->signature, alg, 0);
@@ -435,17 +451,17 @@ sign_cert(CERTCertificate *cert, SECKEYP
 	     PROGRAM_NAME);
 	errorCount++;
 	exit (ERRX);
     }
 
     der2.len = 0;
     der2.data = NULL;
 
-    dummy = SEC_ASN1EncodeItem
+    (void)SEC_ASN1EncodeItem
         (cert->arena, &der2, cert, SEC_ASN1_GET(CERT_CertificateTemplate));
 
     if (rv != SECSuccess) {
 	PR_fprintf(errorFD, "%s: error encoding cert\n", PROGRAM_NAME);
 	errorCount++;
 	exit (ERRX);
     }
 
--- a/cmd/signtool/util.c
+++ b/cmd/signtool/util.c
@@ -11,19 +11,21 @@ static int	is_dir (char *filename);
 
 /***********************************************************
  * Nasty hackish function definitions
  */
 
 long	*mozilla_event_queue = 0;
 
 #ifndef XP_WIN
-char	*XP_GetString (int i)
+char *XP_GetString (int i)
 {
-    return SECU_Strerror (i);
+    /* nasty hackish cast to avoid changing the signature of
+     * JAR_init_callbacks() */
+    return (char *)SECU_Strerror (i);
 }
 #endif
 
 void	FE_SetPasswordEnabled()
 {
 }
 
 
--- a/cmd/ssltap/ssltap.c
+++ b/cmd/ssltap/ssltap.c
@@ -36,22 +36,22 @@
 #include "ocsp.h"
 #include "ocspti.h"     /* internals for pretty-printing routines *only* */
 
 struct _DataBufferList;
 struct _DataBuffer;
 
 typedef struct _DataBufferList {
   struct _DataBuffer *first,*last;
-  int size;
+  unsigned int size;
   int isEncrypted;
   unsigned char * msgBuf;
-  int             msgBufOffset;
-  int             msgBufSize;
-  int             hMACsize;
+  unsigned int msgBufOffset;
+  unsigned int msgBufSize;
+  unsigned int hMACsize;
 } DataBufferList;
 
 typedef struct _DataBuffer {
   unsigned char *buffer;
   int length;
   int offset;  /* offset of first good byte */
   struct _DataBuffer *next;
 } DataBuffer;
@@ -561,36 +561,36 @@ void print_sslv2(DataBufferList *s, unsi
 	       (PRUint32)(GET_SHORT((chv2->cslength))));
     PR_fprintf(PR_STDOUT,"           sid-length = %d (0x%02x)\n",
 	       (PRUint32)(GET_SHORT((chv2->sidlength))),
 	       (PRUint32)(GET_SHORT((chv2->sidlength))));
     PR_fprintf(PR_STDOUT,"           challenge-length = %d (0x%02x)\n",
 	       (PRUint32)(GET_SHORT((chv2->rndlength))),
 	       (PRUint32)(GET_SHORT((chv2->rndlength))));
     PR_fprintf(PR_STDOUT,"           cipher-suites = { \n");
-    for (p=0;p<GET_SHORT((chv2->cslength));p+=3) {
+    for (p=0;p<(PRUint32)GET_SHORT((chv2->cslength));p+=3) {
       PRUint32 cs_int    = GET_24((&chv2->csuites[p]));
       const char *cs_str = V2CipherString(cs_int);
 
       PR_fprintf(PR_STDOUT,"                (0x%06x) %s\n",
 		  cs_int, cs_str);
     }
     q = p;
     PR_fprintf(PR_STDOUT,"                }\n");
-    if (chv2->sidlength) {
+    if (GET_SHORT((chv2->sidlength))) {
       PR_fprintf(PR_STDOUT,"           session-id = { ");
-      for (p=0;p<GET_SHORT((chv2->sidlength));p+=2) {
+      for (p=0;p<(PRUint32)GET_SHORT((chv2->sidlength));p+=2) {
 	PR_fprintf(PR_STDOUT,"0x%04x ",(PRUint32)(GET_SHORT((&chv2->csuites[p+q]))));
       }
     }
     q += p;
     PR_fprintf(PR_STDOUT,"}\n");
-    if (chv2->rndlength) {
+    if (GET_SHORT((chv2->rndlength))) {
       PR_fprintf(PR_STDOUT,"           challenge = { ");
-      for (p=0;p<GET_SHORT((chv2->rndlength));p+=2) {
+      for (p=0;p<(PRUint32)GET_SHORT((chv2->rndlength));p+=2) {
 	PR_fprintf(PR_STDOUT,"0x%04x ",(PRUint32)(GET_SHORT((&chv2->csuites[p+q]))));
       }
       PR_fprintf(PR_STDOUT,"}\n");
     }
     PR_fprintf(PR_STDOUT,"}\n");
     break;
     /* end of V2 CLientHello Parsing */
 
@@ -973,17 +973,17 @@ print_status_response(SECItem *data)
  */
 void print_ssl3_handshake(unsigned char *recordBuf, 
                           unsigned int   recordLen,
                           SSLRecord *    sr,
 			  DataBufferList *s)
 {
   struct sslhandshake sslh; 
   unsigned char *     hsdata;  
-  int                 offset=0;
+  unsigned int offset=0;
 
   PR_fprintf(PR_STDOUT,"   handshake {\n");
 
   if (s->msgBufOffset && s->msgBuf) {
     /* append recordBuf to msgBuf, then use msgBuf */
     if (s->msgBufOffset + recordLen > s->msgBufSize) {
       int             newSize = s->msgBufOffset + recordLen;
       unsigned char * newBuf = PORT_Realloc(s->msgBuf, newSize);
@@ -1360,17 +1360,17 @@ void print_ssl3_handshake(unsigned char 
 	if (sslhexparse) print_hex(sslh.length, hsdata);
 	PR_fprintf(PR_STDOUT,"         }\n");
 
       }
     }  /* end of switch sslh.type */
     offset += sslh.length + 4; 
   } /* while */
   if (offset < recordLen) { /* stuff left over */
-    int newMsgLen = recordLen - offset;
+    unsigned int newMsgLen = recordLen - offset;
     if (!s->msgBuf) {
       s->msgBuf = PORT_Alloc(newMsgLen);
       if (!s->msgBuf) {
 	PR_ASSERT(s->msgBuf);
 	showErr( "Malloc failed");
         exit(11);
       }
       s->msgBufSize = newMsgLen;
--- a/cmd/strsclnt/strsclnt.c
+++ b/cmd/strsclnt/strsclnt.c
@@ -493,17 +493,16 @@ init_thread_data(void)
 }
 
 /**************************************************************************
 ** End   thread management routines.
 **************************************************************************/
 
 PRBool useModelSocket = PR_TRUE;
 
-static const char stopCmd[] = { "GET /stop " };
 static const char outHeader[] = {
     "HTTP/1.0 200 OK\r\n"
     "Server: Netscape-Enterprise/2.0a\r\n"
     "Date: Tue, 26 Aug 1997 22:10:05 GMT\r\n"
     "Content-type: text/plain\r\n"
     "\r\n"
 };
 
@@ -562,18 +561,18 @@ lockedVars_AddToCount(lockedVars * lv, i
 int
 do_writes(
     void *       a,
     void *       b,
     int          c)
 {
     PRFileDesc *	ssl_sock	= (PRFileDesc *)a;
     lockedVars *	lv 		= (lockedVars *)b;
-    int			sent  		= 0;
-    int 		count		= 0;
+    unsigned int sent = 0;
+    int count = 0;
 
     while (sent < bigBuf.len) {
 
 	count = PR_Send(ssl_sock, bigBuf.data + sent, bigBuf.len - sent, 
 	                0, maxInterval);
 	if (count < 0) {
 	    errWarn("PR_Send bigBuf");
 	    break;
@@ -707,17 +706,17 @@ handle_connection( PRFileDesc *ssl_sock,
 
 #ifdef USE_SOCK_PEER_ID
 
 PRInt32 lastFullHandshakePeerID;
 
 void
 myHandshakeCallback(PRFileDesc *socket, void *arg) 
 {
-    PR_ATOMIC_SET(&lastFullHandshakePeerID, (PRInt32) arg);
+    PR_ATOMIC_SET(&lastFullHandshakePeerID, (PRInt32)((char *)arg - (char *)NULL));
 }
 
 #endif
 
 /* one copy of this function is launched in a separate thread for each
 ** connection to be made.
 */
 int
@@ -727,17 +726,16 @@ do_connects(
     int         tid)
 {
     PRNetAddr  *        addr		= (PRNetAddr *)  a;
     PRFileDesc *        model_sock	= (PRFileDesc *) b;
     PRFileDesc *        ssl_sock	= 0;
     PRFileDesc *        tcp_sock	= 0;
     PRStatus	        prStatus;
     PRUint32            sleepInterval	= 50; /* milliseconds */
-    SECStatus   	result;
     int                 rv 		= SECSuccess;
     PRSocketOptionData  opt;
 
 retry:
 
     tcp_sock = PR_OpenTCPSocket(addr->raw.family);
     if (tcp_sock == NULL) {
 	errExit("PR_OpenTCPSocket");
@@ -834,34 +832,35 @@ retry:
             thisPeerID = PR_ATOMIC_INCREMENT(&sockPeerID);
         } else {
             /* reuse previous sockPeerID for restart handhsake */
             thisPeerID = lastFullHandshakePeerID;
         }
         PR_snprintf(sockPeerIDString, sizeof(sockPeerIDString), "ID%d",
                     thisPeerID);
         SSL_SetSockPeerID(ssl_sock, sockPeerIDString);
-        SSL_HandshakeCallback(ssl_sock, myHandshakeCallback, (void*)thisPeerID);
+        SSL_HandshakeCallback(ssl_sock, myHandshakeCallback,
+                              (char *)NULL + thisPeerID);
 #else
             /* force a full handshake by setting the no cache option */
             SSL_OptionSet(ssl_sock, SSL_NO_CACHE, 1);
 #endif
     }
     rv = SSL_ResetHandshake(ssl_sock, /* asServer */ 0);
     if (rv != SECSuccess) {
 	errWarn("SSL_ResetHandshake");
 	goto done;
     }
 
     PR_ATOMIC_INCREMENT(&numConnected);
 
     if (bigBuf.data != NULL) {
-	result = handle_fdx_connection( ssl_sock, tid);
+	(void)handle_fdx_connection( ssl_sock, tid);
     } else {
-	result = handle_connection( ssl_sock, tid);
+	(void)handle_connection( ssl_sock, tid);
     }
 
     PR_ATOMIC_DECREMENT(&numConnected);
 
 done:
     if (ssl_sock) {
 	PR_Close(ssl_sock);
     } else if (tcp_sock) {
--- a/cmd/symkeyutil/symkeyutil.c
+++ b/cmd/symkeyutil/symkeyutil.c
@@ -1010,18 +1010,17 @@ main(int argc, char **argv)
                 for (se = PK11_GetFirstSafe(slotList); se; 
                                     se=PK11_GetNextSafe(slotList,se, PR_FALSE)) {
                     rv = ListKeys(se->slot,&printLabel,&pwdata);
                     if (rv !=SECSuccess) {
                         break;
                     }
                 }
                 if (se) {
-                    SECStatus rv2 = PK11_FreeSlotListElement(slotList, se);
-                    PORT_Assert(SECSuccess == rv2);
+                    PORT_CheckSuccess(PK11_FreeSlotListElement(slotList, se));
                 }
                 PK11_FreeSlotList(slotList);
             }
 	}
     }
 
     /*  Move key (-M)  */
     if (symKeyUtil.commands[cmd_MoveKey].activated) {
--- a/cmd/tstclnt/manifest.mn
+++ b/cmd/tstclnt/manifest.mn
@@ -12,11 +12,12 @@ MODULE = nss
 # and gets translated into $LINCS in manifest.mnw
 # The MODULE is always implicitly required.
 # Listing it here in REQUIRES makes it appear twice in the cc command line.
 REQUIRES = seccmd dbm 
 
 # DIRS = 
 
 CSRCS	= tstclnt.c  
+DEFINES += -DDLL_PREFIX=\"$(DLL_PREFIX)\" -DDLL_SUFFIX=\"$(DLL_SUFFIX)\"
 
 PROGRAM	= tstclnt
 
--- a/cmd/tstclnt/tstclnt.c
+++ b/cmd/tstclnt/tstclnt.c
@@ -27,16 +27,17 @@
 #include "nspr.h"
 #include "prio.h"
 #include "prnetdb.h"
 #include "nss.h"
 #include "ocsp.h"
 #include "ssl.h"
 #include "sslproto.h"
 #include "pk11func.h"
+#include "secmod.h"
 #include "plgetopt.h"
 #include "plstr.h"
 
 #if defined(WIN32)
 #include <fcntl.h>
 #include <io.h>
 #endif
 
@@ -92,16 +93,17 @@ int ssl3CipherSuites[] = {
     TLS_DHE_RSA_WITH_AES_256_CBC_SHA,       	/* x */
     TLS_RSA_WITH_AES_256_CBC_SHA,     	    	/* y */
     TLS_RSA_WITH_NULL_SHA,			/* z */
     0
 };
 
 unsigned long __cmp_umuls;
 PRBool verbose;
+int dumpServerChain = 0;
 int renegotiationsToDo = 0;
 int renegotiationsDone = 0;
 
 static char *progName;
 
 secuPWData  pwdata          = { PW_NONE, 0 };
 
 void printSecurityInfo(PRFileDesc *fd)
@@ -122,20 +124,21 @@ void printSecurityInfo(PRFileDesc *fd)
 	if (result == SECSuccess) {
 	    FPRINTF(stderr, 
 	    "tstclnt: SSL version %d.%d using %d-bit %s with %d-bit %s MAC\n",
 	       channel.protocolVersion >> 8, channel.protocolVersion & 0xff,
 	       suite.effectiveKeyBits, suite.symCipherName, 
 	       suite.macBits, suite.macAlgorithmName);
 	    FPRINTF(stderr, 
 	    "tstclnt: Server Auth: %d-bit %s, Key Exchange: %d-bit %s\n"
-	    "         Compression: %s\n",
+            "         Compression: %s, Extended Master Secret: %s\n",
 	       channel.authKeyBits, suite.authAlgorithmName,
 	       channel.keaKeyBits,  suite.keaTypeName,
-	       channel.compressionMethodName);
+               channel.compressionMethodName,
+               channel.extendedMasterSecretUsed ? "Yes": "No");
     	}
     }
     cert = SSL_RevealCert(fd);
     if (cert) {
 	char * ip = CERT_NameToAscii(&cert->issuer);
 	char * sp = CERT_NameToAscii(&cert->subject);
         if (sp) {
 	    fprintf(stderr, "subject DN: %s\n", sp);
@@ -174,33 +177,40 @@ handshakeCallback(PRFileDesc *fd, void *
 	++renegotiationsDone;
     }
 }
 
 static void PrintUsageHeader(const char *progName)
 {
     fprintf(stderr, 
 "Usage:  %s -h host [-a 1st_hs_name ] [-a 2nd_hs_name ] [-p port]\n"
-                    "[-d certdir] [-n nickname] [-Bafosvx] [-c ciphers] [-Y]\n"
+                    "[-D | -d certdir] [-C] [-b | -R root-module] \n"
+		    "[-n nickname] [-Bafosvx] [-c ciphers] [-Y]\n"
                     "[-V [min-version]:[max-version]] [-K] [-T]\n"
                     "[-r N] [-w passwd] [-W pwfile] [-q [-t seconds]]\n", 
             progName);
 }
 
 static void PrintParameterUsage(void)
 {
     fprintf(stderr, "%-20s Send different SNI name. 1st_hs_name - at first\n"
                     "%-20s handshake, 2nd_hs_name - at second handshake.\n"
                     "%-20s Default is host from the -h argument.\n", "-a name",
                     "", "");
     fprintf(stderr, "%-20s Hostname to connect with\n", "-h host");
     fprintf(stderr, "%-20s Port number for SSL server\n", "-p port");
     fprintf(stderr, 
             "%-20s Directory with cert database (default is ~/.netscape)\n",
 	    "-d certdir");
+    fprintf(stderr, "%-20s Run without a cert database\n", "-D");
+    fprintf(stderr, "%-20s Load the default \"builtins\" root CA module\n", "-b");
+    fprintf(stderr, "%-20s Load the given root CA module\n", "-R");
+    fprintf(stderr, "%-20s Print certificate chain information\n", "-C");
+    fprintf(stderr, "%-20s (use -C twice to print more certificate details)\n", "");
+    fprintf(stderr, "%-20s (use -C three times to include PEM format certificate dumps)\n", "");
     fprintf(stderr, "%-20s Nickname of key and cert for client auth\n", 
                     "-n nickname");
     fprintf(stderr, 
             "%-20s Bypass PKCS11 layer for SSL encryption and MACing.\n", "-B");
     fprintf(stderr, 
             "%-20s Restricts the set of enabled SSL/TLS protocols versions.\n"
             "%-20s All versions are enabled by default.\n"
             "%-20s Possible values for min/max: ssl2 ssl3 tls1.0 tls1.1 tls1.2\n"
@@ -217,16 +227,17 @@ static void PrintParameterUsage(void)
     fprintf(stderr, "%-20s Use export policy.\n", "-x");
     fprintf(stderr, "%-20s Ping the server and then exit.\n", "-q");
     fprintf(stderr, "%-20s Timeout for server ping (default: no timeout).\n", "-t seconds");
     fprintf(stderr, "%-20s Renegotiate N times (resuming session if N>1).\n", "-r N");
     fprintf(stderr, "%-20s Enable the session ticket extension.\n", "-u");
     fprintf(stderr, "%-20s Enable compression.\n", "-z");
     fprintf(stderr, "%-20s Enable false start.\n", "-g");
     fprintf(stderr, "%-20s Enable the cert_status extension (OCSP stapling).\n", "-T");
+    fprintf(stderr, "%-20s Enable the extended master secret extension (session hash).\n", "-G");
     fprintf(stderr, "%-20s Require fresh revocation info from side channel.\n"
                     "%-20s -F once means: require for server cert only\n"
                     "%-20s -F twice means: require for intermediates, too\n"
                     "%-20s (Connect, handshake with server, disable dynamic download\n"
                     "%-20s  of OCSP/CRL, verify cert using CERT_PKIXVerifyCert.)\n"
                     "%-20s Exit code:\n"
                     "%-20s 0: have fresh and valid revocation data, status good\n"
                     "%-20s 1: cert failed to verify, prior to revocation checking\n"
@@ -495,25 +506,127 @@ verifyFromSideChannel(CERTCertificate *c
             EXIT_CODE_SIDECHANNELTEST_NODATA;
         return;
     }
     
     sca->sideChannelRevocationTestResultCode = 
         EXIT_CODE_SIDECHANNELTEST_REVOKED;
 }
 
+
+static void
+dumpCertificatePEM(CERTCertificate *cert)
+{
+    SECItem data;
+    data.data = cert->derCert.data;
+    data.len = cert->derCert.len;
+    fprintf(stderr, "%s\n%s\n%s\n", NS_CERT_HEADER, 
+	    BTOA_DataToAscii(data.data, data.len), NS_CERT_TRAILER);
+}
+
+static void
+dumpServerCertificateChain(PRFileDesc *fd)
+{
+    CERTCertList *peerCertChain = NULL;
+    CERTCertListNode *node = NULL;
+    CERTCertificate *peerCert = NULL;
+    CERTCertificateList *foundChain = NULL;
+    SECU_PPFunc dumpFunction = NULL;
+    PRBool dumpCertPEM = PR_FALSE;
+
+    if (!dumpServerChain) {
+	return;
+    }
+    else if (dumpServerChain == 1) {
+	dumpFunction = (SECU_PPFunc)SECU_PrintCertificateBasicInfo;
+    } else {
+	dumpFunction = (SECU_PPFunc)SECU_PrintCertificate;
+	if (dumpServerChain > 2) {
+	    dumpCertPEM = PR_TRUE;
+	}
+    }
+
+    SECU_EnableWrap(PR_FALSE);
+
+    fprintf(stderr, "==== certificate(s) sent by server: ====\n");
+    peerCertChain = SSL_PeerCertificateChain(fd);
+    if (peerCertChain) {
+        node = CERT_LIST_HEAD(peerCertChain);
+        while ( ! CERT_LIST_END(node, peerCertChain) ) {
+            CERTCertificate *cert = node->cert;
+            SECU_PrintSignedContent(stderr, &cert->derCert, "Certificate", 0,
+                                    dumpFunction);
+	    if (dumpCertPEM) {
+		dumpCertificatePEM(cert);
+	    }
+            node = CERT_LIST_NEXT(node);   
+        }
+    }
+
+    if (peerCertChain) {
+	peerCert = SSL_RevealCert(fd);
+	if (peerCert) {
+	    foundChain = CERT_CertChainFromCert(peerCert, certificateUsageSSLServer,
+						PR_TRUE);
+	}
+	if (foundChain) {
+	    unsigned int count = 0;
+	    fprintf(stderr, "==== locally found issuer certificate(s): ====\n");
+	    for(count = 0; count < (unsigned int)foundChain->len; count++) {
+		CERTCertificate *c;
+		PRBool wasSentByServer = PR_FALSE;
+		c = CERT_FindCertByDERCert(CERT_GetDefaultCertDB(), &foundChain->certs[count]);
+
+		node = CERT_LIST_HEAD(peerCertChain);
+		while ( ! CERT_LIST_END(node, peerCertChain) ) {
+		    CERTCertificate *cert = node->cert;
+		    if (CERT_CompareCerts(cert, c)) {
+			wasSentByServer = PR_TRUE;
+			break;
+		    }
+		    node = CERT_LIST_NEXT(node);   
+		}
+		
+		if (!wasSentByServer) {
+		    SECU_PrintSignedContent(stderr, &c->derCert, "Certificate", 0,
+					    dumpFunction);
+		    if (dumpCertPEM) {
+			dumpCertificatePEM(c);
+		    }
+		}
+		CERT_DestroyCertificate(c);
+	    }
+	    CERT_DestroyCertificateList(foundChain);
+	}
+	if (peerCert) {
+	    CERT_DestroyCertificate(peerCert);
+	}
+
+	CERT_DestroyCertList(peerCertChain);
+	peerCertChain = NULL;
+    }
+
+    fprintf(stderr, "==== end of certificate chain information ====\n");
+    fflush(stderr);
+}
+
 static SECStatus 
 ownAuthCertificate(void *arg, PRFileDesc *fd, PRBool checkSig,
                        PRBool isServer)
 {
     ServerCertAuth * serverCertAuth = (ServerCertAuth *) arg;
 
+    if (dumpServerChain) {
+	dumpServerCertificateChain(fd);
+    }
+
+
     if (!serverCertAuth->shouldPause) {
         CERTCertificate *cert;
-        int i;
+        unsigned int i;
         const SECItemArray *csa;
 
         if (!serverCertAuth->testFreshStatusFromSideChannel) {
             return SSL_AuthCertificate(serverCertAuth->dbHandle, 
                                        fd, checkSig, isServer);
         }
 
         /* No verification attempt must have happened before now,
@@ -528,18 +641,17 @@ ownAuthCertificate(void *arg, PRFileDesc
 
         csa = SSL_PeerStapledOCSPResponses(fd);
         if (csa) {
             for (i = 0; i < csa->len; ++i) {
 		PORT_SetError(0);
 		if (CERT_CacheOCSPResponseFromSideChannel(
 			serverCertAuth->dbHandle, cert, PR_Now(),
 			&csa->items[i], arg) != SECSuccess) {
-		    PRErrorCode error = PR_GetError();
-		    PORT_Assert(error != 0);
+		    PORT_Assert(PR_GetError() != 0);
 		}
             }
         }
     
         verifyFromSideChannel(cert, serverCertAuth);
         CERT_DestroyCertificate(cert);
         /* return success to ensure our caller will continue and we will 
          * reach the code that handles 
@@ -804,16 +916,17 @@ int main(int argc, char **argv)
     int                bypassPKCS11 = 0;
     int                disableLocking = 0;
     int                useExportPolicy = 0;
     int                enableSessionTickets = 0;
     int                enableCompression = 0;
     int                enableFalseStart = 0;
     int                enableCertStatus = 0;
     int                forceFallbackSCSV = 0;
+    int                enableExtendedMasterSecret = 0;
     PRSocketOptionData opt;
     PRNetAddr          addr;
     PRPollDesc         pollset[2];
     PRBool             allowIPv4 = PR_TRUE;
     PRBool             allowIPv6 = PR_TRUE;
     PRBool             pingServerFirst = PR_FALSE;
     int                pingTimeoutSeconds = -1;
     PRBool             clientSpeaksFirst = PR_FALSE;
@@ -823,16 +936,19 @@ int main(int argc, char **argv)
     int                headerSeparatorPtrnId = 0;
     int                error = 0;
     PRUint16           portno = 443;
     char *             hs1SniHostName = NULL;
     char *             hs2SniHostName = NULL;
     PLOptState *optstate;
     PLOptStatus optstatus;
     PRStatus prStatus;
+    PRBool openDB = PR_TRUE;
+    PRBool loadDefaultRootCAs = PR_FALSE;
+    char *rootModule = NULL;
 
     serverCertAuth.shouldPause = PR_TRUE;
     serverCertAuth.isPaused = PR_FALSE;
     serverCertAuth.dbHandle = NULL;
     serverCertAuth.testFreshStatusFromSideChannel = PR_FALSE;
     serverCertAuth.sideChannelRevocationTestResultCode = EXIT_CODE_HANDSHAKE_FAILED;
     serverCertAuth.requireDataForIntermediates = PR_FALSE;
     serverCertAuth.allowOCSPSideChannelData = PR_TRUE;
@@ -849,34 +965,40 @@ int main(int argc, char **argv)
        if (sec > 0) {
            maxInterval = PR_SecondsToInterval(sec);
        }
     }
 
     SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledVersions);
 
     optstate = PL_CreateOptState(argc, argv,
-                                 "46BFKM:OSTV:W:Ya:c:d:fgh:m:n:op:qr:st:uvw:xz");
+                                 "46BCDFGKM:OR:STV:W:Ya:bc:d:fgh:m:n:op:qr:st:uvw:xz");
     while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
 	switch (optstate->option) {
 	  case '?':
 	  default : Usage(progName); 			break;
 
           case '4': allowIPv6 = PR_FALSE; if (!allowIPv4) Usage(progName); break;
           case '6': allowIPv4 = PR_FALSE; if (!allowIPv6) Usage(progName); break;
 
           case 'B': bypassPKCS11 = 1; 			break;
 
+          case 'C': ++dumpServerChain; 			break;
+
+          case 'D': openDB = PR_FALSE; 			break;
+
           case 'F': if (serverCertAuth.testFreshStatusFromSideChannel) {
                         /* parameter given twice or more */
                         serverCertAuth.requireDataForIntermediates = PR_TRUE;
                     }
                     serverCertAuth.testFreshStatusFromSideChannel = PR_TRUE;
                     break;
 
+          case 'G': enableExtendedMasterSecret = PR_TRUE; break;
+
 	  case 'I': /* reserved for OCSP multi-stapling */ break;
 
           case 'O': serverCertAuth.shouldPause = PR_FALSE; break;
 
           case 'K': forceFallbackSCSV = PR_TRUE; break;
 
           case 'M': switch (atoi(optstate->value)) {
                       case 1:
@@ -890,16 +1012,18 @@ int main(int argc, char **argv)
                       case 0:
                       default:
                           serverCertAuth.allowOCSPSideChannelData = PR_TRUE;
                           serverCertAuth.allowCRLSideChannelData = PR_TRUE;
                           break;
                     };
                     break;
 
+          case 'R': rootModule = PORT_Strdup(optstate->value); break;
+
           case 'S': skipProtoHeader = PR_TRUE;                 break;
 
           case 'T': enableCertStatus = 1;               break;
 
           case 'V': if (SECU_ParseSSLVersionRangeString(optstate->value,
                             enabledVersions, enableSSL2,
                             &enabledVersions, &enableSSL2) != SECSuccess) {
                         Usage(progName);
@@ -912,16 +1036,18 @@ int main(int argc, char **argv)
                         hs1SniHostName = PORT_Strdup(optstate->value);
                     } else if (!hs2SniHostName) {
                         hs2SniHostName =  PORT_Strdup(optstate->value);
                     } else {
                         Usage(progName);
                     }
                     break;
 
+          case 'b': loadDefaultRootCAs = PR_TRUE;                 break;
+
           case 'c': cipherString = PORT_Strdup(optstate->value); break;
 
           case 'g': enableFalseStart = 1; 		break;
 
           case 'd': certDir = PORT_Strdup(optstate->value);   break;
 
           case 'f': clientSpeaksFirst = PR_TRUE;        break;
 
@@ -967,25 +1093,37 @@ int main(int argc, char **argv)
 	}
     }
 
     PL_DestroyOptState(optstate);
 
     if (optstatus == PL_OPT_BAD)
 	Usage(progName);
 
-    if (!host || !portno) 
+    if (!host || !portno) {
+        fprintf(stderr, "%s: parameters -h and -p are mandatory\n", progName);
     	Usage(progName);
+    }
 
     if (serverCertAuth.testFreshStatusFromSideChannel
         && serverCertAuth.shouldPause) {
         fprintf(stderr, "%s: -F requires the use of -O\n", progName);
         exit(1);
     }
 
+    if (certDir && !openDB) {
+        fprintf(stderr, "%s: Cannot combine parameters -D and -d\n", progName);
+        exit(1);
+    }
+
+    if (rootModule && loadDefaultRootCAs) {
+        fprintf(stderr, "%s: Cannot combine parameters -b and -R\n", progName);
+        exit(1);
+    }
+
     PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
 
     PK11_SetPasswordFunc(SECU_GetModulePassword);
 
     status = PR_StringToNetAddr(host, &addr);
     if (status == PR_SUCCESS) {
     	addr.inet.port = PR_htons(portno);
     } else {
@@ -1068,20 +1206,36 @@ int main(int argc, char **argv)
     if (!certDir) {
         certDir = SECU_DefaultSSLDir(); /* Look in $SSL_DIR */
         certDir = SECU_ConfigDirectory(certDir);
     } else {
         char *certDirTmp = certDir;
         certDir = SECU_ConfigDirectory(certDirTmp);
         PORT_Free(certDirTmp);
     }
-    rv = NSS_Init(certDir);
-    if (rv != SECSuccess) {
-        SECU_PrintError(progName, "unable to open cert database");
-        return 1;
+
+    if (openDB) {
+	rv = NSS_Init(certDir);
+	if (rv != SECSuccess) {
+	    SECU_PrintError(progName, "unable to open cert database");
+	    return 1;
+	}
+    } else {
+	rv = NSS_NoDB_Init(NULL);
+	if (rv != SECSuccess) {
+	    SECU_PrintError(progName, "failed to initialize NSS");
+	    return 1;
+	}
+    }
+
+    if (loadDefaultRootCAs) {
+	SECMOD_AddNewModule("Builtins",
+			    DLL_PREFIX"nssckbi."DLL_SUFFIX, 0, 0);
+    } else if (rootModule) {
+	SECMOD_AddNewModule("Builtins", rootModule, 0, 0);
     }
 
     /* set the policy bits true for all the cipher suites. */
     if (useExportPolicy)
         NSS_SetExportPolicy();
     else
         NSS_SetDomesticPolicy();
 
@@ -1128,17 +1282,17 @@ int main(int argc, char **argv)
     if (cipherString) {
     	char *cstringSaved = cipherString;
     	int ndx;
 
 	while (0 != (ndx = *cipherString++)) {
 	    int  cipher;
 
 	    if (ndx == ':') {
-		int ctmp;
+		int ctmp = 0;
 
 		cipher = 0;
 		HEXCHAR_TO_INT(*cipherString, ctmp)
 		cipher |= (ctmp << 12);
 		cipherString++;
 		HEXCHAR_TO_INT(*cipherString, ctmp)
 		cipher |= (ctmp << 8);
 		cipherString++;
@@ -1232,16 +1386,25 @@ int main(int argc, char **argv)
 
     /* enable cert status (OCSP stapling). */
     rv = SSL_OptionSet(s, SSL_ENABLE_OCSP_STAPLING, enableCertStatus);
     if (rv != SECSuccess) {
         SECU_PrintError(progName, "error enabling cert status (OCSP stapling)");
         return 1;
     }
 
+    /* enable extended master secret mode */
+    if  (enableExtendedMasterSecret) {
+        rv = SSL_OptionSet(s, SSL_ENABLE_EXTENDED_MASTER_SECRET, PR_TRUE);
+	if (rv != SECSuccess) {
+            SECU_PrintError(progName, "error enabling extended master secret");
+            return 1;
+	}
+    }
+
     SSL_SetPKCS11PinArg(s, &pwdata);
 
     serverCertAuth.dbHandle = CERT_GetDefaultCertDB();
 
     SSL_AuthCertificateHook(s, ownAuthCertificate, &serverCertAuth);
     if (override) {
 	SSL_BadCertHook(s, ownBadCertHandler, NULL);
     }
--- a/cmd/vfychain/vfychain.c
+++ b/cmd/vfychain/vfychain.c
@@ -328,17 +328,17 @@ parseRevMethodsAndFlags()
 }
 
 SECStatus
 configureRevocationParams(CERTRevocationFlags *flags)
 {
    int i;
    unsigned int testType = REVCONFIG_TEST_UNDEFINED;
    static CERTRevocationTests *revTests = NULL;
-   PRUint64 *revFlags;
+   PRUint64 *revFlags = NULL;
 
    for(i = 0;i < REV_METHOD_INDEX_MAX;i++) {
        if (revMethodsData[i].testType == REVCONFIG_TEST_UNDEFINED) {
            continue;
        }
        if (revMethodsData[i].testType != testType) {
            testType = revMethodsData[i].testType;
            if (testType == REVCONFIG_TEST_CHAIN) {
--- a/cmd/vfyserv/vfyserv.c
+++ b/cmd/vfyserv/vfyserv.c
@@ -505,17 +505,17 @@ main(int argc, char **argv)
 
 	    /* disable all the ciphers, then enable the ones we want. */
 	    disableAllSSLCiphers();
 
 	    while (0 != (ndx = *cipherString++)) {
 		int  cipher;
 
 		if (ndx == ':') {
-		    int ctmp;
+		    int ctmp = 0;
 
 		    cipher = 0;
 		    HEXCHAR_TO_INT(*cipherString, ctmp)
 		    cipher |= (ctmp << 12);
 		    cipherString++;
 		    HEXCHAR_TO_INT(*cipherString, ctmp)
 		    cipher |= (ctmp << 8);
 		    cipherString++;
--- a/cmd/vfyserv/vfyutil.c
+++ b/cmd/vfyserv/vfyutil.c
@@ -598,17 +598,17 @@ lockedVars_AddToCount(lockedVars * lv, i
  * multiple treads. But it should not be a problem since we
  * consider vfyserv to be single threaded(see bug 353477).
  */
 
 void
 dumpCertChain(CERTCertificate *cert, SECCertUsage usage)
 {
     CERTCertificateList *certList;
-    int count = 0;
+    unsigned int count = 0;
 
     certList = CERT_CertChainFromCert(cert, usage, PR_TRUE);
     if (certList == NULL) {
         errWarn("CERT_CertChainFromCert");
         return;
     }
 
     for(count = 0; count < (unsigned int)certList->len; count++) {
--- a/coreconf/Darwin.mk
+++ b/coreconf/Darwin.mk
@@ -78,16 +78,36 @@ endif
 # or it may be a declaration of a symbol defined in another file:
 #     extern int x;
 # Use the -fno-common option to force all commons to become true
 # definitions so that the linker can catch multiply-defined symbols.
 # Also, common symbols are not allowed with Darwin dynamic libraries.
 
 OS_CFLAGS	= $(DSO_CFLAGS) $(OS_REL_CFLAGS) -Wall -fno-common -pipe -DDARWIN -DHAVE_STRERROR -DHAVE_BSD_FLOCK $(DARWIN_SDK_CFLAGS)
 
+ifeq (clang,$(shell $(CC) -? 2>&1 >/dev/null | sed -e 's/:.*//;1q'))
+NSS_HAS_GCC48 = true
+endif
+ifndef NSS_HAS_GCC48
+NSS_HAS_GCC48 := $(shell \
+  [ `$(CC) -dumpversion | cut -f 1 -d . -` -eq 4 -a \
+    `$(CC) -dumpversion | cut -f 2 -d . -` -ge 8 -o \
+    `$(CC) -dumpversion | cut -f 1 -d . -` -ge 5 ] && \
+  echo true || echo false)
+export NSS_HAS_GCC48
+endif
+ifeq (true,$(NSS_HAS_GCC48))
+OS_CFLAGS += -Werror
+else
+# Old versions of gcc (< 4.8) don't support #pragma diagnostic in functions.
+# Use this to disable use of that #pragma and the warnings it suppresses.
+OS_CFLAGS += -DNSS_NO_GCC48 -Wno-unused-variable -Wno-strict-aliasing
+$(warning Unable to find gcc >= 4.8 disabling -Werror)
+endif
+
 ifdef BUILD_OPT
 ifeq (11,$(ALLOW_OPT_CODE_SIZE)$(OPT_CODE_SIZE))
 	OPTIMIZER       = -Oz
 else
 	OPTIMIZER	= -O2
 endif
 ifdef MOZ_DEBUG_SYMBOLS
 	ifdef MOZ_DEBUG_FLAGS
@@ -111,8 +131,27 @@ DLL_SUFFIX	= dylib
 ifdef MAPFILE
 	MKSHLIB += -exported_symbols_list $(MAPFILE)
 endif
 PROCESS_MAP_FILE = grep -v ';+' $< | grep -v ';-' | \
                 sed -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,,' -e 's,^,_,' > $@
 
 USE_SYSTEM_ZLIB = 1
 ZLIB_LIBS	= -lz
+
+# The system sqlite library in the latest version of Mac OS X often becomes
+# newer than the sqlite library in NSS. This may result in certain Mac OS X
+# system libraries having unresolved sqlite symbols during the shlibsign step
+# of the NSS build when we set DYLD_LIBRARY_PATH to the NSS lib directory and
+# the NSS libsqlite3.dylib is used instead of the system one. So just use the
+# system sqlite library on Mac, if it's sufficiently new.
+
+SYS_SQLITE3_VERSION_FULL := $(shell /usr/bin/sqlite3 -version | awk '{print $$1}')
+SYS_SQLITE3_VERSION_MAJOR := $(shell echo $(SYS_SQLITE3_VERSION_FULL) | awk -F. '{ print $$1 }')
+SYS_SQLITE3_VERSION_MINOR := $(shell echo $(SYS_SQLITE3_VERSION_FULL) | awk -F. '{ print $$2 }')
+
+ifeq (3,$(SYS_SQLITE3_VERSION_MAJOR))
+    ifeq (,$(filter-out 0 1 2 3 4,$(SYS_SQLITE3_VERSION_MINOR)))
+        # sqlite <= 3.4.x is too old, it doesn't provide sqlite3_file_control
+    else
+        NSS_USE_SYSTEM_SQLITE = 1
+    endif
+endif
--- a/coreconf/Linux.mk
+++ b/coreconf/Linux.mk
@@ -21,18 +21,21 @@ CCC			= g++
 RANLIB			= ranlib
 
 DEFAULT_COMPILER = gcc
 
 ifeq ($(OS_TARGET),Android)
 ifndef ANDROID_NDK
 	$(error Must set ANDROID_NDK to the path to the android NDK first)
 endif
+ifndef ANDROID_TOOLCHAIN_VERSION
+	$(error Must set ANDROID_TOOLCHAIN_VERSION to the requested version number)
+endif
 	ANDROID_PREFIX=$(OS_TEST)-linux-androideabi
-	ANDROID_TARGET=$(ANDROID_PREFIX)-4.4.3
+	ANDROID_TARGET=$(ANDROID_PREFIX)-$(ANDROID_TOOLCHAIN_VERSION)
 	# should autodetect which linux we are on, currently android only
 	# supports linux-x86 prebuilts
 	ANDROID_TOOLCHAIN=$(ANDROID_NDK)/toolchains/$(ANDROID_TARGET)/prebuilt/linux-x86
 	ANDROID_SYSROOT=$(ANDROID_NDK)/platforms/android-$(OS_TARGET_RELEASE)/arch-$(OS_TEST)
 	ANDROID_CC=$(ANDROID_TOOLCHAIN)/bin/$(ANDROID_PREFIX)-gcc
 # internal tools need to be built with the native compiler
 ifndef INTERNAL_TOOLS
 	CC = $(ANDROID_CC) --sysroot=$(ANDROID_SYSROOT)
@@ -120,24 +123,60 @@ ifdef MOZ_DEBUG_SYMBOLS
 	ifdef MOZ_DEBUG_FLAGS
 		OPTIMIZER += $(MOZ_DEBUG_FLAGS)
 	else
 		OPTIMIZER += -gdwarf-2
 	endif
 endif
 endif
 
+ifndef COMPILER_TAG
+COMPILER_TAG = _$(shell $(CC) -? 2>&1 >/dev/null | sed -e 's/:.*//;1q')
+CCC_COMPILER_TAG = _$(shell $(CCC) -? 2>&1 >/dev/null | sed -e 's/:.*//;1q')
+endif
 
 ifeq ($(USE_PTHREADS),1)
 OS_PTHREAD = -lpthread 
 endif
 
-OS_CFLAGS		= $(DSO_CFLAGS) $(OS_REL_CFLAGS) $(ARCHFLAG) -Wall -Werror-implicit-function-declaration -Wno-switch -pipe -ffunction-sections -fdata-sections -DLINUX -Dlinux -DHAVE_STRERROR
+OS_CFLAGS		= $(DSO_CFLAGS) $(OS_REL_CFLAGS) $(ARCHFLAG) -Wall -pipe -ffunction-sections -fdata-sections -DLINUX -Dlinux -DHAVE_STRERROR
 OS_LIBS			= $(OS_PTHREAD) -ldl -lc
 
+ifeq ($(COMPILER_TAG),_clang)
+# -Qunused-arguments : clang objects to arguments that it doesn't understand
+#    and fixing this would require rearchitecture
+# -Wno-parentheses-equality : because clang warns about macro expansions
+OS_CFLAGS += -Qunused-arguments -Wno-parentheses-equality
+ifdef BUILD_OPT
+# clang is unable to handle glib's expansion of strcmp and similar for optimized
+# builds, so ignore the resulting errors.
+# See https://llvm.org/bugs/show_bug.cgi?id=20144
+OS_CFLAGS += -Wno-array-bounds -Wno-unevaluated-expression
+endif
+# Clang reports its version as an older gcc, but it's OK
+NSS_HAS_GCC48 = true
+endif
+
+ifndef NSS_HAS_GCC48
+NSS_HAS_GCC48 := $(shell \
+  [ `$(CC) -dumpversion | cut -f 1 -d . -` -eq 4 -a \
+    `$(CC) -dumpversion | cut -f 2 -d . -` -ge 8 -o \
+    `$(CC) -dumpversion | cut -f 1 -d . -` -ge 5 ] && \
+  echo true || echo false)
+export NSS_HAS_GCC48
+endif
+ifeq (true,$(NSS_HAS_GCC48))
+OS_CFLAGS += -Werror
+else
+# Old versions of gcc (< 4.8) don't support #pragma diagnostic in functions.
+# Use this to disable use of that #pragma and the warnings it suppresses.
+OS_CFLAGS += -DNSS_NO_GCC48
+$(warning Unable to find gcc >= 4.8 disabling -Werror)
+endif
+
 ifdef USE_PTHREADS
 	DEFINES		+= -D_REENTRANT
 endif
 
 ARCH			= linux
 
 DSO_CFLAGS		= -fPIC
 DSO_LDOPTS		= -shared $(ARCHFLAG) -Wl,--gc-sections
--- a/coreconf/WIN32.mk
+++ b/coreconf/WIN32.mk
@@ -19,18 +19,19 @@ ifdef NS_USE_GCC
 	RANLIB       = ranlib
 	BSDECHO      = echo
 	RC           = windres.exe -O coff --use-temp-file
 	LINK_DLL      = $(CC) $(OS_DLLFLAGS) $(DLLFLAGS)
 else
 	CC           = cl
 	CCC          = cl
 	LINK         = link
+        LDFLAGS += -nologo
 	AR           = lib
-	AR          += -NOLOGO -OUT:$@
+	AR          += -nologo -OUT:$@
 	RANLIB       = echo
 	BSDECHO      = echo
 	RC           = rc.exe
 	MT           = mt.exe
 	# Check for clang-cl
 	CLANG_CL    := $(shell expr `$(CC) -? 2>&1 | grep -w clang | wc -l` \> 0)
 	# Determine compiler version
 	ifeq ($(CLANG_CL),1)
@@ -98,20 +99,17 @@ XP_DEFINE   += -DXP_PC
 ifdef NS_USE_GCC
 LIB_SUFFIX   = a
 else
 LIB_SUFFIX   = lib
 endif
 DLL_SUFFIX   = dll
 
 ifdef NS_USE_GCC
-    # The -mnop-fun-dllimport flag allows us to avoid a drawback of
-    # the dllimport attribute that a pointer to a function marked as
-    # dllimport cannot be used as as a constant address.
-    OS_CFLAGS += -mwindows -mms-bitfields -mnop-fun-dllimport
+    OS_CFLAGS += -mwindows -mms-bitfields -Werror
     _GEN_IMPORT_LIB=-Wl,--out-implib,$(IMPORT_LIBRARY)
     DLLFLAGS  += -mwindows -o $@ -shared -Wl,--export-all-symbols $(if $(IMPORT_LIBRARY),$(_GEN_IMPORT_LIB))
     ifdef BUILD_OPT
 	ifeq (11,$(ALLOW_OPT_CODE_SIZE)$(OPT_CODE_SIZE))
 		OPTIMIZER += -Os
 	else
 		OPTIMIZER += -O2
 	endif
@@ -120,17 +118,17 @@ ifdef NS_USE_GCC
 	OPTIMIZER  += -g
 	NULLSTRING :=
 	SPACE      := $(NULLSTRING) # end of the line
 	USERNAME   := $(subst $(SPACE),_,$(USERNAME))
 	USERNAME   := $(subst -,_,$(USERNAME))
 	DEFINES    += -DDEBUG -D_DEBUG -UNDEBUG -DDEBUG_$(USERNAME)
     endif
 else # !NS_USE_GCC
-    OS_CFLAGS += -W3 -nologo -D_CRT_SECURE_NO_WARNINGS \
+    OS_CFLAGS += -W3 -WX -nologo -D_CRT_SECURE_NO_WARNINGS \
 		 -D_CRT_NONSTDC_NO_WARNINGS
     OS_DLLFLAGS += -nologo -DLL -SUBSYSTEM:WINDOWS
     ifeq ($(_MSC_VER),$(_MSC_VER_6))
     ifndef MOZ_DEBUG_SYMBOLS
 	OS_DLLFLAGS += -PDB:NONE
     endif
     endif
     ifdef USE_DYNAMICBASE
@@ -185,21 +183,21 @@ ifeq ($(_MSC_VER),$(_MSC_VER_6))
 ifndef MOZ_DEBUG_SYMBOLS
 	LDFLAGS    += -PDB:NONE 
 endif
 endif
 	# Purify requires /FIXED:NO when linking EXEs.
 	LDFLAGS    += /FIXED:NO
     endif
 ifneq ($(_MSC_VER),$(_MSC_VER_6))
-    # Convert certain deadly warnings to errors (see list at end of file)
-    OS_CFLAGS += -we4002 -we4003 -we4004 -we4006 -we4009 -we4013 \
-     -we4015 -we4028 -we4033 -we4035 -we4045 -we4047 -we4053 -we4054 -we4063 \
-     -we4064 -we4078 -we4087 -we4090 -we4098 -we4390 -we4551 -we4553 -we4715
-
+    # NSS has too many of these to fix, downgrade the warning
+    # Disable C4267: conversion from 'size_t' to 'type', possible loss of data
+    # Disable C4244: conversion from 'type1' to 'type2', possible loss of data
+    # Disable C4018: 'expression' : signed/unsigned mismatch
+    OS_CFLAGS += -w44267 -w44244 -w44018
     ifeq ($(_MSC_VER_GE_12),1)
 	OS_CFLAGS += -FS
     endif
 endif # !MSVC6
 endif # NS_USE_GCC
 
 ifdef USE_64
 DEFINES += -DWIN64
@@ -212,20 +210,23 @@ ifdef USE_64
 	DEFINES += -D_AMD64_
 	# Use subsystem 5.02 to allow running on Windows XP.
 	ifeq ($(_MSC_VER_GE_11),1)
 		LDFLAGS += -SUBSYSTEM:CONSOLE,5.02
 	endif
 else
 	DEFINES += -D_X86_
 	# VS2012 defaults to -arch:SSE2. Use -arch:IA32 to avoid requiring
-	# SSE2.
+	# SSE2. Clang-cl gets confused by -arch:IA32, so don't add it.
+	# (See https://llvm.org/bugs/show_bug.cgi?id=24335)
 	# Use subsystem 5.01 to allow running on Windows XP.
 	ifeq ($(_MSC_VER_GE_11),1)
-		OS_CFLAGS += -arch:IA32
+		ifneq ($(CLANG_CL),1)
+			OS_CFLAGS += -arch:IA32
+		endif
 		LDFLAGS += -SUBSYSTEM:CONSOLE,5.01
 	endif
 endif
 endif
 ifeq ($(CPU_ARCH), ALPHA)
 	DEFINES += -D_ALPHA_=1
 endif
 
@@ -361,37 +362,8 @@ ifdef LIBRARY_NAME
 endif
 
 #
 # override the TARGETS defined in ruleset.mk, adding IMPORT_LIBRARY
 #
 ifndef TARGETS
     TARGETS = $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY) $(PROGRAM)
 endif
-
-# list of MSVC warnings converted to errors above:
-# 4002: too many actual parameters for macro 'identifier'
-# 4003: not enough actual parameters for macro 'identifier'
-# 4004: incorrect construction after 'defined'
-# 4006: #undef expected an identifier
-# 4009: string too big; trailing characters truncated
-# 4015: 'identifier' : type of bit field must be integral
-# 4028: formal parameter different from declaration
-# 4033: 'function' must return a value
-# 4035: 'function' : no return value
-# 4045: 'identifier' : array bounds overflow
-# 4047: 'function' : 'type 1' differs in levels of indirection from 'type 2'
-# 4053: one void operand for '?:'
-# 4054: 'conversion' : from function pointer 'type1' to data pointer 'type2'
-# 4059: pascal string too big, length byte is length % 256
-# 4063: case 'identifier' is not a valid value for switch of enum 'identifier'
-# 4064: switch of incomplete enum 'identifier'
-# 4078: case constant 'value' too big for the type of the switch expression
-# 4087: 'function' : declared with 'void' parameter list
-# 4090: 'function' : different 'const' qualifiers
-# 4098: 'function' : void function returning a value
-# 4390: ';' : empty controlled statement found; is this the intent?
-# 4541: RTTI train wreck
-# 4715: not all control paths return a value
-# 4013: function undefined; assuming extern returning int
-# 4553: '==' : operator has no effect; did you intend '='?
-# 4551: function call missing argument list
-
--- a/coreconf/arch.mk
+++ b/coreconf/arch.mk
@@ -275,23 +275,32 @@ endif
 # The following flags are defined in the individual $(OS_CONFIG).mk
 # files.
 #
 # CPU_TAG is defined if the CPU is not the most common CPU.
 # COMPILER_TAG is defined if the compiler is not the default compiler.
 # IMPL_STRATEGY may be defined too.
 #
 
+ifdef CROSS_COMPILE
+OBJDIR_NAME = $(OS_TARGET)$(OS_RELEASE)$(CPU_TAG)$(LIBC_TAG)$(IMPL_STRATEGY)$(OBJDIR_TAG).OBJ
+else
 OBJDIR_NAME = $(OS_TARGET)$(OS_RELEASE)$(CPU_TAG)$(COMPILER_TAG)$(LIBC_TAG)$(IMPL_STRATEGY)$(OBJDIR_TAG).OBJ
+endif
+
 
 ifeq (,$(filter-out WIN%,$(OS_TARGET)))
 ifndef BUILD_OPT
 #
 # Define USE_DEBUG_RTL if you want to use the debug runtime library
 # (RTL) in the debug build
 #
 ifdef USE_DEBUG_RTL
+    ifdef CROSS_COMPILE
+    OBJDIR_NAME = $(OS_TARGET)$(OS_RELEASE)$(CPU_TAG)$(IMPL_STRATEGY)$(OBJDIR_TAG).OBJD
+    else
     OBJDIR_NAME = $(OS_TARGET)$(OS_RELEASE)$(CPU_TAG)$(COMPILER_TAG)$(IMPL_STRATEGY)$(OBJDIR_TAG).OBJD
+    endif
 endif
 endif
 endif
 
 MK_ARCH = included
--- a/coreconf/command.mk
+++ b/coreconf/command.mk
@@ -6,18 +6,17 @@
 #######################################################################
 # Master "Core Components" default command macros;                    #
 # can be overridden in <arch>.mk                                      #
 #######################################################################
 
 AS            = $(CC)
 ASFLAGS      += $(CFLAGS)
 CCF           = $(CC) $(CFLAGS)
-LINK_DLL      = $(LINK) $(OS_DLLFLAGS) $(DLLFLAGS)
-LINK_EXE      = $(LINK) $(OS_LFLAGS) $(LFLAGS)
+LINK_DLL      = $(LINK) $(OS_DLLFLAGS) $(DLLFLAGS) $(XLDFLAGS)
 CFLAGS        = $(OPTIMIZER) $(OS_CFLAGS) $(XP_DEFINE) $(DEFINES) $(INCLUDES) \
 		$(XCFLAGS)
 PERL          = perl
 RANLIB        = echo
 TAR           = /bin/tar
 #
 # For purify
 #
--- a/coreconf/location.mk
+++ b/coreconf/location.mk
@@ -62,13 +62,17 @@ endif
 ifdef SOFTOKEN_INCLUDE_DIR
     INCLUDES += -I$(SOFTOKEN_INCLUDE_DIR)
 endif
 
 ifndef SOFTOKEN_LIB_DIR
     SOFTOKEN_LIB_DIR = $(DIST)/lib
 endif
 
+ifndef SQLITE_LIB_DIR
+    SQLITE_LIB_DIR = $(DIST)/lib
+endif
+
 ifndef SQLITE_LIB_NAME
     SQLITE_LIB_NAME = sqlite3
 endif
 
 MK_LOCATION = included
--- a/coreconf/mkdepend/parse.c
+++ b/coreconf/mkdepend/parse.c
@@ -345,17 +345,17 @@ define2(char *name, char *val, struct in
 
     below = first = 0;
     last = file->i_ndefs - 1;
     while (last >= first)
     {
 	/* Fast inline binary search */
 	register char *s1;
 	register char *s2;
-	register int middle = (first + last) / 2;
+	register int middle = first + (last - first) / 2;
 
 	/* Fast inline strchr() */
 	s1 = name;
 	s2 = file->i_defs[middle]->s_name;
 	while (*s1++ == *s2++)
 	    if (s2[-1] == '\0') break;
 
 	/* If exact match, set sp and break */
@@ -431,17 +431,17 @@ slookup(char *symbol, struct inclist *fi
 	register int first = 0;
 	register int last = file->i_ndefs - 1;
 
 	if (file) while (last >= first)
 	{
 	    /* Fast inline binary search */
 	    register char *s1;
 	    register char *s2;
-	    register int middle = (first + last) / 2;
+	    register int middle = first + (last - first) / 2;
 
 	    /* Fast inline strchr() */
 	    s1 = symbol;
 	    s2 = file->i_defs[middle]->s_name;
 	    while (*s1++ == *s2++)
 	        if (s2[-1] == '\0') break;
 
 	    /* If exact match, we're done */
--- a/coreconf/rules.mk
+++ b/coreconf/rules.mk
@@ -236,17 +236,17 @@ endif
 alltags:
 	rm -f TAGS
 	find . -name dist -prune -o \( -name '*.[hc]' -o -name '*.cp' -o -name '*.cpp' \) -print | xargs etags -a
 	find . -name dist -prune -o \( -name '*.[hc]' -o -name '*.cp' -o -name '*.cpp' \) -print | xargs ctags -a
 
 $(PROGRAM): $(OBJS) $(EXTRA_LIBS)
 	@$(MAKE_OBJDIR)
 ifeq (,$(filter-out _WIN%,$(NS_USE_GCC)_$(OS_TARGET)))
-	$(MKPROG) $(subst /,\\,$(OBJS)) -Fe$@ -link $(LDFLAGS) $(subst /,\\,$(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS))
+	$(MKPROG) $(subst /,\\,$(OBJS)) -Fe$@ -link $(LDFLAGS) $(XLDFLAGS) $(subst /,\\,$(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS))
 ifdef MT
 	if test -f $@.manifest; then \
 		$(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
 		rm -f $@.manifest; \
 	fi
 endif	# MSVC with manifest tool
 else
 	$(MKPROG) -o $@ $(CFLAGS) $(OBJS) $(LDFLAGS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS)
@@ -267,16 +267,20 @@ endif
 
 
 ifeq ($(OS_TARGET),OS2)
 $(IMPORT_LIBRARY): $(MAPFILE)
 	rm -f $@
 	$(IMPLIB) $@ $<
 	$(RANLIB) $@
 endif
+ifeq ($(OS_ARCH),WINNT)
+$(IMPORT_LIBRARY): $(LIBRARY)
+	cp -f $< $@
+endif
 
 ifdef SHARED_LIBRARY_LIBS
 ifdef BUILD_TREE
 SUB_SHLOBJS = $(foreach dir,$(SHARED_LIBRARY_DIRS),$(shell $(MAKE) -C $(dir) --no-print-directory get_objs))
 else
 SUB_SHLOBJS = $(foreach dir,$(SHARED_LIBRARY_DIRS),$(addprefix $(dir)/,$(shell $(MAKE) -C $(dir) --no-print-directory get_objs)))
 endif
 endif
@@ -327,17 +331,17 @@ endif
 	@$(MAKE_OBJDIR)
 	$(PROCESS_MAP_FILE)
 
 
 $(OBJDIR)/$(PROG_PREFIX)%$(PROG_SUFFIX): $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX)
 	@$(MAKE_OBJDIR)
 ifeq (,$(filter-out _WIN%,$(NS_USE_GCC)_$(OS_TARGET)))
 	$(MKPROG) $< -Fe$@ -link \
-	$(LDFLAGS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS)
+	$(LDFLAGS) $(XLDFLAGS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS)
 ifdef MT
 	if test -f $@.manifest; then \
 		$(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
 		rm -f $@.manifest; \
 	fi
 endif	# MSVC with manifest tool
 else
 	$(MKPROG) -o $@ $(CFLAGS) $< \
@@ -415,52 +419,66 @@ endif
 
 $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.S
 	@$(MAKE_OBJDIR)
 	$(AS) -o $@ $(ASFLAGS) -c $<
 
 $(OBJDIR)/$(PROG_PREFIX)%: %.cpp
 	@$(MAKE_OBJDIR)
 ifdef USE_NT_C_SYNTAX
-	$(CCC) -Fo$@ -c $(CFLAGS) $(call core_abspath,$<)
+	$(CCC) -Fo$@ -c $(CFLAGS) $(CXXFLAGS) $(call core_abspath,$<)
 else
 ifdef NEED_ABSOLUTE_PATH
-	$(CCC) -o $@ -c $(CFLAGS) $(call core_abspath,$<)
+	$(CCC) -o $@ -c $(CFLAGS) $(CXXFLAGS) $(call core_abspath,$<)
 else
-	$(CCC) -o $@ -c $(CFLAGS) $<
+	$(CCC) -o $@ -c $(CFLAGS) $(CXXFLAGS) $<
 endif
 endif
 
 #
 # Please keep the next two rules in sync.
 #
 $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.cc
-	@$(MAKE_OBJDIR)
-	$(CCC) -o $@ -c $(CFLAGS) $<
+	$(MAKE_OBJDIR)
+ifdef STRICT_CPLUSPLUS_SUFFIX
+	echo "#line 1 \"$<\"" | cat - $< > $(OBJDIR)/t_$*.cc
+	$(CCC) -o $@ -c $(CFLAGS) $(CXXFLAGS) $(OBJDIR)/t_$*.cc
+	rm -f $(OBJDIR)/t_$*.cc
+else
+ifdef USE_NT_C_SYNTAX
+	$(CCC) -Fo$@ -c $(CFLAGS) $(CXXFLAGS) $(call core_abspath,$<)
+else
+ifdef NEED_ABSOLUTE_PATH
+	$(CCC) -o $@ -c $(CFLAGS) $(CXXFLAGS) $(call core_abspath,$<)
+else
+	$(CCC) -o $@ -c $(CFLAGS) $(CXXFLAGS) $<
+endif
+endif
+endif #STRICT_CPLUSPLUS_SUFFIX
 
 $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.cpp
 	@$(MAKE_OBJDIR)
 ifdef STRICT_CPLUSPLUS_SUFFIX
 	echo "#line 1 \"$<\"" | cat - $< > $(OBJDIR)/t_$*.cc
-	$(CCC) -o $@ -c $(CFLAGS) $(OBJDIR)/t_$*.cc
+	$(CCC) -o $@ -c $(CFLAGS) $(CXXFLAGS) $(OBJDIR)/t_$*.cc
 	rm -f $(OBJDIR)/t_$*.cc
 else
 ifdef USE_NT_C_SYNTAX
-	$(CCC) -Fo$@ -c $(CFLAGS) $(call core_abspath,$<)
+	$(CCC) -Fo$@ -c $(CFLAGS) $(CXXFLAGS) $(call core_abspath,$<)
 else
 ifdef NEED_ABSOLUTE_PATH
-	$(CCC) -o $@ -c $(CFLAGS) $(call core_abspath,$<)
+	$(CCC) -o $@ -c $(CFLAGS) $(CXXFLAGS) $(call core_abspath,$<)
 else
-	$(CCC) -o $@ -c $(CFLAGS) $<
+	$(CCC) -o $@ -c $(CFLAGS) $(CXXFLAGS) $<
 endif
 endif
 endif #STRICT_CPLUSPLUS_SUFFIX
 
 %.i: %.cpp
-	$(CCC) -C -E $(CFLAGS) $< > $@
+	$(CCC) -C -E $(CFLAGS) $(CXXFLAGS) $< > $@
 
 %.i: %.c
 ifeq (,$(filter-out WIN%,$(OS_TARGET)))
 	$(CC) -C /P $(CFLAGS) $< 
 else
 	$(CC) -C -E $(CFLAGS) $< > $@
 endif
 
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -34,29 +34,16 @@ date.xml:
 
 version.xml:
 	echo -n ${VERSION} > $@
 
 .PHONY : $(MANPAGES)
 .PHONY : $(HTMLPAGES)
 .PHONY : $(TXTPAGES)
 
-#------------------------------------------
-# Package a tar ball for building in fedora
-# Include the makefile and .xml files only
-# man pages will be created at build time
-#------------------------------------------
-
-tarball:
-	rm -rf $(name); \
-	mkdir -p $(name)/nroff; \
-	cp Makefile $(name); \
-	cp *.xml $(name); \
-	tar cvjf $(name)-$(date).tar.bz2 $(name)
-
 #--------------------------------------------------------
 # manpages
 #--------------------------------------------------------
 
 nroff/%.1 : %.xml
 	$(COMPILE.1) $<
 	
 MANPAGES = \
--- a/doc/certutil.xml
+++ b/doc/certutil.xml
@@ -68,16 +68,21 @@
       </varlistentry>
 
       <varlistentry>
         <term>-D </term>
         <listitem><para>Delete a certificate from the certificate database.</para></listitem>
       </varlistentry>
 
       <varlistentry>
+        <term>--rename </term>
+        <listitem><para>Change the database nickname of a certificate.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term>-E </term>
         <listitem><para>Add an email certificate to the certificate database.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         <term>-F</term>
         <listitem><para>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 
 <option>-d</option> argument. Use the <option>-k</option> argument to specify explicitly whether to delete a DSA, RSA, or ECC key. If you don't use the <option>-k</option> argument, the option looks for an RSA key matching the specified nickname. 
@@ -242,17 +247,17 @@ Add one or multiple extensions that cert
         <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>
-        <listitem><para>Set a key size to use when generating new public and private key pairs. The minimum is 512 bits and the maximum is 16384 bits. The default is 1024 bits. Any size between the minimum and maximum is allowed.</para></listitem>
+        <listitem><para>Set a key size to use when generating new public and private key pairs. The minimum is 512 bits and the maximum is 16384 bits. The default is 2048 bits. Any size between the minimum and maximum is allowed.</para></listitem>