Bug 1228555 - Remove support for SSLv2 r=mt,wtc,ekr
authorTim Taubert <ttaubert@mozilla.com>
Fri, 11 Mar 2016 11:52:04 +0100
changeset 11981 0c19072b85372534ecfe9874fb3315cbed8f3eab
parent 11980 4e474b9c302c68f8121c80a64ee14d977bda19c0
child 11982 52f57b0c5444cee33ff3417c6ef1f6799d2343ed
push id1054
push userttaubert@mozilla.com
push dateFri, 11 Mar 2016 10:55:11 +0000
reviewersmt, wtc, ekr
bugs1228555
Bug 1228555 - Remove support for SSLv2 r=mt,wtc,ekr
cmd/lib/secutil.c
cmd/lib/secutil.h
cmd/listsuites/listsuites.c
cmd/selfserv/selfserv.c
cmd/strsclnt/strsclnt.c
cmd/tstclnt/tstclnt.c
cmd/vfyserv/vfyserv.c
cmd/vfyserv/vfyserv.h
cmd/vfyserv/vfyutil.c
lib/ssl/SSLerrs.h
lib/ssl/derive.c
lib/ssl/manifest.mn
lib/ssl/notes.txt
lib/ssl/ssl.h
lib/ssl/ssl3con.c
lib/ssl/ssl3gthr.c
lib/ssl/sslauth.c
lib/ssl/sslcon.c
lib/ssl/sslenum.c
lib/ssl/sslerr.h
lib/ssl/sslgathr.c
lib/ssl/sslimpl.h
lib/ssl/sslinfo.c
lib/ssl/sslnonce.c
lib/ssl/sslproto.h
lib/ssl/sslsecur.c
lib/ssl/sslsnce.c
lib/ssl/sslsock.c
lib/ssl/ssltrace.c
lib/util/ciferfam.h
tests/iopr/server_scr/cipher.list
tests/pkcs11/netscape/suites/Makefile
tests/pkcs11/netscape/suites/config.mk
tests/pkcs11/netscape/suites/manifest.mn
tests/pkcs11/netscape/suites/security/Makefile
tests/pkcs11/netscape/suites/security/config.mk
tests/pkcs11/netscape/suites/security/manifest.mn
tests/pkcs11/netscape/suites/security/pkcs11/Makefile
tests/pkcs11/netscape/suites/security/pkcs11/config.mk
tests/pkcs11/netscape/suites/security/pkcs11/manifest.mn
tests/pkcs11/netscape/suites/security/pkcs11/pk11test.c
tests/pkcs11/netscape/suites/security/pkcs11/pk11test.h
tests/pkcs11/netscape/suites/security/pkcs11/pk11test.htp
tests/pkcs11/netscape/suites/security/pkcs11/pkcs11.h
tests/pkcs11/netscape/suites/security/pkcs11/pkcs11.reg
tests/pkcs11/netscape/suites/security/pkcs11/pkcs11.rep
tests/pkcs11/netscape/suites/security/pkcs11/rules.mk
tests/pkcs11/netscape/suites/security/ssl/Makefile
tests/pkcs11/netscape/suites/security/ssl/README
tests/pkcs11/netscape/suites/security/ssl/config.mk
tests/pkcs11/netscape/suites/security/ssl/manifest.mn
tests/pkcs11/netscape/suites/security/ssl/ssl.reg
tests/pkcs11/netscape/suites/security/ssl/sslc.c
tests/pkcs11/netscape/suites/security/ssl/sslc.h
tests/pkcs11/netscape/suites/security/ssl/ssls.c
tests/pkcs11/netscape/suites/security/ssl/ssls.h
tests/pkcs11/netscape/suites/security/ssl/sslt.c
tests/pkcs11/netscape/suites/security/ssl/sslt.h
tests/pkcs11/netscape/suites/security/ssl/sslt.htp
tests/pkcs11/netscape/suites/security/ssl/sslt.rep
tests/pkcs11/netscape/trivial/.cvsignore
tests/pkcs11/netscape/trivial/Makefile.in
tests/pkcs11/netscape/trivial/README.txt
tests/pkcs11/netscape/trivial/acconfig.h
tests/pkcs11/netscape/trivial/config.h.in
tests/pkcs11/netscape/trivial/configure
tests/pkcs11/netscape/trivial/configure.in
tests/pkcs11/netscape/trivial/install-sh
tests/pkcs11/netscape/trivial/trivial.c
tests/ssl/ssl.sh
tests/ssl/sslcov.txt
tests/ssl/sslstress.txt
--- a/cmd/lib/secutil.c
+++ b/cmd/lib/secutil.c
@@ -3692,20 +3692,16 @@ SECU_FindCertByNicknameOrFilename(CERTCe
 static SECStatus
 SECU_GetSSLVersionFromName(const char *buf, size_t bufLen, PRUint16 *version)
 {
     if (!buf || !version) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
     }
 
-    if (!PL_strncasecmp(buf, "ssl2", bufLen)) {
-        *version = SSL_LIBRARY_VERSION_2;
-        return SECSuccess;
-    }
     if (!PL_strncasecmp(buf, "ssl3", bufLen)) {
         *version = SSL_LIBRARY_VERSION_3_0;
         return SECSuccess;
     }
     if (!PL_strncasecmp(buf, "tls1.0", bufLen)) {
         *version = SSL_LIBRARY_VERSION_TLS_1_0;
         return SECSuccess;
     }
@@ -3725,84 +3721,76 @@ SECU_GetSSLVersionFromName(const char *b
 
     PORT_SetError(SEC_ERROR_INVALID_ARGS);
     return SECFailure;
 }
 
 SECStatus
 SECU_ParseSSLVersionRangeString(const char *input,
                                 const SSLVersionRange defaultVersionRange,
-                                const PRBool defaultEnableSSL2,
-                                SSLVersionRange *vrange, PRBool *enableSSL2)
+                                SSLVersionRange *vrange)
 {
     const char *colonPos;
     size_t colonIndex;
     const char *maxStr;
 
-    if (!input || !vrange || !enableSSL2) {
+    if (!input || !vrange) {
+        PORT_SetError(SEC_ERROR_INVALID_ARGS);
+        return SECFailure;
+    }
+
+    // We don't support SSL2 any longer.
+    if (defaultVersionRange.min < SSL_LIBRARY_VERSION_3_0 ||
+        defaultVersionRange.max < SSL_LIBRARY_VERSION_3_0) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
     }
 
     if (!strcmp(input, ":")) {
         /* special value, use default */
-        *enableSSL2 = defaultEnableSSL2;
         *vrange = defaultVersionRange;
         return SECSuccess;
     }
 
     colonPos = strchr(input, ':');
     if (!colonPos) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
     }
 
     colonIndex = colonPos - input;
     maxStr = colonPos + 1;
 
     if (!colonIndex) {
         /* colon was first character, min version is empty */
-        *enableSSL2 = defaultEnableSSL2;
         vrange->min = defaultVersionRange.min;
     } else {
         PRUint16 version;
         /* colonIndex is equivalent to the length of the min version substring */
         if (SECU_GetSSLVersionFromName(input, colonIndex, &version) != SECSuccess) {
             PORT_SetError(SEC_ERROR_INVALID_ARGS);
             return SECFailure;
         }
 
-        if (version == SSL_LIBRARY_VERSION_2) {
-            *enableSSL2 = PR_TRUE;
-            vrange->min = defaultVersionRange.min;
-        } else {
-            *enableSSL2 = PR_FALSE;
-            vrange->min = version;
-        }
+        vrange->min = version;
     }
 
     if (!*maxStr) {
         vrange->max = defaultVersionRange.max;
     } else {
         PRUint16 version;
         /* if max version is empty, then maxStr points to the string terminator */
         if (SECU_GetSSLVersionFromName(maxStr, strlen(maxStr), &version)
                 != SECSuccess) {
             PORT_SetError(SEC_ERROR_INVALID_ARGS);
             return SECFailure;
         }
 
-        if (version == SSL_LIBRARY_VERSION_2) {
-            /* consistency checking, require that min allows enableSSL2, too */
-            if (!*enableSSL2) {
-                PORT_SetError(SEC_ERROR_INVALID_ARGS);
-                return SECFailure;
-            }
-            /* we use 0 because SSL_LIBRARY_VERSION_NONE is private: */
-            vrange->min = 0;
-            vrange->max = 0;
-        } else {
-            vrange->max = version;
-        }
+        vrange->max = version;
+    }
+
+    if (vrange->min > vrange->max) {
+        PORT_SetError(SEC_ERROR_INVALID_ARGS);
+        return SECFailure;
     }
 
     return SECSuccess;
 }
--- a/cmd/lib/secutil.h
+++ b/cmd/lib/secutil.h
@@ -393,31 +393,25 @@ SECU_SECItemHexStringToBinary(SECItem* s
  * Both min and max values are optional.
  * The following syntax is used to specify the enabled protocol versions:
  * A string with only a max value is expected as ":{max}",
  * and all implemented versions less than or equal to max will be enabled.
  * A string with only a min value is expected as "{min}:",
  * and all implemented versions greater than or equal to min will be enabled.
  * A string consisting of a colon only means "all versions enabled".
  *
- * Because output parameter type SSLVersionRange doesn't allow to set
- * version 2 values, we use a separate boolean output parameter
- * to return whether SSL 2 is enabled.
- *
  * In order to avoid a link dependency from libsectool to libssl,
  * the caller must provide the desired default values for the min/max values,
- * by providing defaultEnableSSL2 and defaultVersionRange
- * (which can be obtained from libssl by calling SSL_VersionRangeGetSupported).
+ * by providing defaultVersionRange (which can be obtained from libssl by
+ * calling SSL_VersionRangeGetSupported).
  */
 SECStatus
 SECU_ParseSSLVersionRangeString(const char *input,
                                 const SSLVersionRange defaultVersionRange,
-                                const PRBool defaultEnableSSL2,
-                                SSLVersionRange *vrange,
-                                PRBool *enableSSL2);
+                                SSLVersionRange *vrange);
 
 /*
  *
  *  Error messaging
  *
  */
 
 void printflags(char *trusts, unsigned int flags);
--- a/cmd/listsuites/listsuites.c
+++ b/cmd/listsuites/listsuites.c
@@ -49,15 +49,14 @@ int main(int argc, char **argv)
 	}
 	fprintf(stdout, 
 		"%s:\n" /* up to 37 spaces  */
 		"  0x%04hx %-5s %-5s %-8s %3hd %-6s %-8s %-4s %-8s %-11s\n",
 		info.cipherSuiteName, info.cipherSuite, 
 		info.keaTypeName, info.authAlgorithmName, info.symCipherName, 
 		info.effectiveKeyBits, info.macAlgorithmName, 
 		enabled           ? "Enabled"     : "Disabled",
-		info.isFIPS       ? "FIPS" : 
-		  (SSL_IS_SSL2_CIPHER(info.cipherSuite) ? "SSL2" : ""),
+		info.isFIPS       ? "FIPS"        : "",
 		info.isExportable ? "Export"      : "Domestic",
 		info.nonStandard  ? "nonStandard" : "");
     }
     return errCount;
 }
--- a/cmd/selfserv/selfserv.c
+++ b/cmd/selfserv/selfserv.c
@@ -89,26 +89,16 @@ static enum ocspStaplingModeEnum {
     osm_random,    /* use a random response for each connection */
     osm_ocsp       /* retrieve ocsp status from external ocsp server,
 		      use empty status if server is unavailable */
 } ocspStaplingMode = osm_disabled;
 typedef enum ocspStaplingModeEnum ocspStaplingModeType;
 static char *ocspStaplingCA = NULL;
 static SECItemArray *certStatus[kt_kea_size] = { NULL };
 
-const int ssl2CipherSuites[] = {
-    SSL_EN_RC4_128_WITH_MD5,			/* A */
-    SSL_EN_RC4_128_EXPORT40_WITH_MD5,		/* B */
-    SSL_EN_RC2_128_CBC_WITH_MD5,		/* C */
-    SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5,	/* D */
-    SSL_EN_DES_64_CBC_WITH_MD5,			/* E */
-    SSL_EN_DES_192_EDE3_CBC_WITH_MD5,		/* F */
-    0
-};
-
 const int ssl3CipherSuites[] = {
     -1, /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA* a */
     -1, /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA	 * b */
     TLS_RSA_WITH_RC4_128_MD5,			/* c */
     TLS_RSA_WITH_3DES_EDE_CBC_SHA,		/* d */
     TLS_RSA_WITH_DES_CBC_SHA,			/* e */
     TLS_RSA_EXPORT_WITH_RC4_40_MD5,		/* f */
     TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,		/* g */
@@ -173,17 +163,17 @@ PrintUsageHeader(const char *progName)
 }
 
 static void
 PrintParameterUsage()
 {
     fputs(
 "-V [min]:[max] restricts the set of enabled SSL/TLS protocol versions.\n"
 "   All versions are enabled by default.\n"
-"   Possible values for min/max: ssl2 ssl3 tls1.0 tls1.1 tls1.2\n"
+"   Possible values for min/max: ssl3 tls1.0 tls1.1 tls1.2\n"
 "   Example: \"-V ssl3:\" enables SSL 3 and newer.\n"
 "-B bypasses the PKCS11 layer for SSL encryption and MACing\n"
 "-q checks for bypassability\n"
 "-D means disable Nagle delays in TCP\n"
 "-E means disable export ciphersuites and SSL step down key gen\n"
 "-R means disable detection of rollback from TLS to SSL3\n"
 "-a configure server for SNI.\n"
 "-k expected name negotiated on server sockets\n"
@@ -237,23 +227,16 @@ Usage(const char *progName)
 }
 
 static void
 PrintCipherUsage(const char *progName)
 {
     PrintUsageHeader(progName);
     fputs(
 "-c ciphers   Letter(s) chosen from the following list\n"
-"A    SSL2 RC4 128 WITH MD5\n"
-"B    SSL2 RC4 128 EXPORT40 WITH MD5\n"
-"C    SSL2 RC2 128 CBC WITH MD5\n"
-"D    SSL2 RC2 128 CBC EXPORT40 WITH MD5\n"
-"E    SSL2 DES 64 CBC WITH MD5\n"
-"F    SSL2 DES 192 EDE3 CBC WITH MD5\n"
-"\n"
 "c    SSL3 RSA WITH RC4 128 MD5\n"
 "d    SSL3 RSA WITH 3DES EDE CBC SHA\n"
 "e    SSL3 RSA WITH DES CBC SHA\n"
 "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"
@@ -823,17 +806,16 @@ logger(void *arg)
 
 
 /**************************************************************************
 ** End   thread management routines.
 **************************************************************************/
 
 PRBool useModelSocket  = PR_FALSE;
 static SSLVersionRange enabledVersions;
-PRBool enableSSL2      = PR_TRUE;
 PRBool disableRollBack = PR_FALSE;
 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;
@@ -1860,32 +1842,26 @@ server_main(
     } else {
 	model_sock = listen_sock = SSL_ImportFD(NULL, listen_sock);
 	if (listen_sock == NULL) {
 	    errExit("SSL_ImportFD");
 	}
     }
 
     /* do SSL configuration. */
-    rv = SSL_OptionSet(model_sock, SSL_SECURITY, 
-                       enableSSL2 || enabledVersions.min != 0);
+    rv = SSL_OptionSet(model_sock, SSL_SECURITY, enabledVersions.min != 0);
     if (rv < 0) {
 	errExit("SSL_OptionSet SSL_SECURITY");
     }
 
     rv = SSL_VersionRangeSet(model_sock, &enabledVersions);
     if (rv != SECSuccess) {
 	errExit("error setting SSL/TLS version range ");
     }
 
-    rv = SSL_OptionSet(model_sock, SSL_ENABLE_SSL2, enableSSL2);
-    if (rv != SECSuccess) {
-       errExit("error enabling SSLv2 ");
-    }
-
     rv = SSL_OptionSet(model_sock, SSL_ROLLBACK_DETECTION, !disableRollBack);
     if (rv != SECSuccess) {
 	errExit("error enabling RollBack detection ");
     }
     if (disableStepDown) {
 	rv = SSL_OptionSet(model_sock, SSL_NO_STEP_DOWN, PR_TRUE);
 	if (rv != SECSuccess) {
 	    errExit("error disabling SSL StepDown ");
@@ -2277,18 +2253,17 @@ main(int argc, char **argv)
 		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) {
+                          enabledVersions, &enabledVersions) != SECSuccess) {
                       Usage(progName);
                   }
                   break;
 
 	case 'W': configureWeakDHE = (PORT_Atoi(optstate->value) != 0); break;
 
         case 'Y': PrintCipherUsage(progName); exit(0); break;
         
@@ -2539,54 +2514,52 @@ main(int argc, char **argv)
 	if (disableStepDown) {
 	    rv = disableExportSSLCiphers();
 	    if (rv != SECSuccess) {
 		errExit("error disabling export ciphersuites ");
 	    }
     	}
     }
 
-    /* all the SSL2 and SSL3 cipher suites are enabled by default. */
+    /* all SSL3 cipher suites are enabled by default. */
     if (cipherString) {
     	char *cstringSaved = cipherString;
     	int ndx;
 
 	/* disable all the ciphers, then enable the ones we want. */
 	disableAllSSLCiphers();
 
 	while (0 != (ndx = *cipherString++)) {
-	    int  cipher;
+            int cipher = 0;
 
 	    if (ndx == ':') {
 		int ctmp;
 
-		cipher = 0;
 		HEXCHAR_TO_INT(*cipherString, ctmp)
 		cipher |= (ctmp << 12);
 		cipherString++;
 		HEXCHAR_TO_INT(*cipherString, ctmp)
 		cipher |= (ctmp << 8);
 		cipherString++;
 		HEXCHAR_TO_INT(*cipherString, ctmp)
 		cipher |= (ctmp << 4);
 		cipherString++;
 		HEXCHAR_TO_INT(*cipherString, ctmp)
 		cipher |= ctmp;
 		cipherString++;
 	    } else {
-		const int *cptr;
-
 		if (! isalpha(ndx)) {
 		    fprintf(stderr, 
 			    "Non-alphabetic char in cipher string (-c arg).\n");
 		    exit(9);
 		}
-		cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
-		for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; ) 
-		    /* do nothing */;
+                ndx = tolower(ndx) - 'a';
+                if (ndx < PR_ARRAY_SIZE(ssl3CipherSuites)) {
+                    cipher = ssl3CipherSuites[ndx];
+                }
 	    }
 	    if (cipher > 0) {
 		SECStatus status;
 		status = SSL_CipherPrefSetDefault(cipher, SSL_ALLOWED);
 		if (status != SECSuccess) 
 		    SECU_PrintError(progName, "SSL_CipherPrefSet()");
 	    } else {
 		fprintf(stderr, 
--- a/cmd/strsclnt/strsclnt.c
+++ b/cmd/strsclnt/strsclnt.c
@@ -41,26 +41,16 @@
 #endif
 
 #define RD_BUF_SIZE (60 * 1024)
 
 /* Include these cipher suite arrays to re-use tstclnt's 
  * cipher selection code.
  */
 
-int ssl2CipherSuites[] = {
-    SSL_EN_RC4_128_WITH_MD5,                    /* A */
-    SSL_EN_RC4_128_EXPORT40_WITH_MD5,           /* B */
-    SSL_EN_RC2_128_CBC_WITH_MD5,                /* C */
-    SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5,       /* D */
-    SSL_EN_DES_64_CBC_WITH_MD5,                 /* E */
-    SSL_EN_DES_192_EDE3_CBC_WITH_MD5,           /* F */
-    0
-};
-
 int ssl3CipherSuites[] = {
     -1, /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA* a */
     -1, /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA     * b */
     TLS_RSA_WITH_RC4_128_MD5,                   /* c */
     TLS_RSA_WITH_3DES_EDE_CBC_SHA,              /* d */
     TLS_RSA_WITH_DES_CBC_SHA,                   /* e */
     TLS_RSA_EXPORT_WITH_RC4_40_MD5,             /* f */
     TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,         /* g */
@@ -117,17 +107,16 @@ static int active_threads = 8; /* number
                                ** connect */
 static PRInt32 numUsed;
 /* end of variables protected by threadLock */
 
 static SSL3Statistics * ssl3stats;
 
 static int failed_already = 0;
 static SSLVersionRange enabledVersions;
-static PRBool enableSSL2      = PR_TRUE;
 static PRBool bypassPKCS11    = PR_FALSE;
 static PRBool disableLocking  = PR_FALSE;
 static PRBool ignoreErrors    = PR_FALSE;
 static PRBool enableSessionTickets = PR_FALSE;
 static PRBool enableCompression    = PR_FALSE;
 static PRBool enableFalseStart     = PR_FALSE;
 static PRBool enableCertStatus     = PR_FALSE;
 
@@ -158,17 +147,17 @@ Usage(const char *progName)
         "          2 -o's mean skip server certificate validation altogether.\n"
 	"       -D means no TCP delays\n"
 	"       -q means quit when server gone (timeout rather than retry forever)\n"
 	"       -s means disable SSL socket locking\n"
 	"       -N means no session reuse\n"
 	"       -P means do a specified percentage of full handshakes (0-100)\n"
         "       -V [min]:[max] restricts the set of enabled SSL/TLS protocols versions.\n"
         "          All versions are enabled by default.\n"
-        "          Possible values for min/max: ssl2 ssl3 tls1.0 tls1.1 tls1.2\n"
+        "          Possible values for min/max: ssl3 tls1.0 tls1.1 tls1.2\n"
         "          Example: \"-V ssl3:\" enables SSL 3 and newer.\n"
         "       -U means enable throttling up threads\n"
 	"       -B bypasses the PKCS11 layer for SSL encryption and MACing\n"
 	"       -T enable the cert_status extension (OCSP stapling)\n"
 	"       -u enable TLS Session Ticket extension\n"
 	"       -z enable compression\n"
 	"       -g enable false start\n",
 	progName);
@@ -1092,17 +1081,17 @@ client_main(
 	    SECU_PrintError(progName, "error looking up host address");
 	    return;
 	}
     }
 
     /* all suites except RSA_NULL_MD5 are enabled by Domestic Policy */
     NSS_SetDomesticPolicy();
 
-    /* all the SSL2 and SSL3 cipher suites are enabled by default. */
+    /* all SSL3 cipher suites are enabled by default. */
     if (cipherString) {
         int ndx;
 
         /* disable all the ciphers, then enable the ones we want. */
         disableAllSSLCiphers();
 
         while (0 != (ndx = *cipherString)) {
 	    const char * startCipher = cipherString++;
@@ -1120,21 +1109,20 @@ client_main(
 		if (cipher <= 0) {
 		    fprintf(stderr, "strsclnt: Invalid cipher value: %-5.5s\n",
 		                    startCipher);
 		    failed_already = 1;
 		    return;
 		}
 	    } else {
 		if (isalpha(ndx)) {
-		    const int *cptr;
-
-		    cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
-		    for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; ) 
-			/* do nothing */;
+                    ndx = tolower(ndx) - 'a';
+                    if (ndx < PR_ARRAY_SIZE(ssl3CipherSuites)) {
+                        cipher = ssl3CipherSuites[ndx];
+                    }
 		}
 	    	if (cipher <= 0) {
 		    fprintf(stderr, "strsclnt: Invalid cipher letter: %c\n", 
 		                    *startCipher);
 		    failed_already = 1;
 		    return;
 		}
 	    }
@@ -1158,37 +1146,26 @@ client_main(
 
     model_sock = SSL_ImportFD(NULL, model_sock);
     if (model_sock == NULL) {
 	errExit("SSL_ImportFD");
     }
 
     /* do SSL configuration. */
 
-    rv = SSL_OptionSet(model_sock, SSL_SECURITY,
-                       enableSSL2 || enabledVersions.min != 0);
+    rv = SSL_OptionSet(model_sock, SSL_SECURITY, enabledVersions.min != 0);
     if (rv < 0) {
 	errExit("SSL_OptionSet SSL_SECURITY");
     }
 
     rv = SSL_VersionRangeSet(model_sock, &enabledVersions);
     if (rv != SECSuccess) {
         errExit("error setting SSL/TLS version range ");
     }
 
-    rv = SSL_OptionSet(model_sock, SSL_ENABLE_SSL2, enableSSL2);
-    if (rv != SECSuccess) {
-       errExit("error enabling SSLv2 ");
-    }
-
-    rv = SSL_OptionSet(model_sock, SSL_V2_COMPATIBLE_HELLO, enableSSL2);
-    if (rv != SECSuccess) {
-        errExit("error enabling SSLv2 compatible hellos ");
-    }
-
     if (bigBuf.data) { /* doing FDX */
 	rv = SSL_OptionSet(model_sock, SSL_ENABLE_FDX, 1);
 	if (rv < 0) {
 	    errExit("SSL_OptionSet SSL_ENABLE_FDX");
 	}
     }
 
     if (NoReuse) {
@@ -1363,18 +1340,17 @@ main(int argc, char **argv)
         
 	case 'P': fullhs = PORT_Atoi(optstate->value); break;
 
 	case 'T': enableCertStatus = PR_TRUE; break;
 
 	case 'U': ThrottleUp = PR_TRUE; break;
         
         case 'V': if (SECU_ParseSSLVersionRangeString(optstate->value,
-                          enabledVersions, enableSSL2,
-                          &enabledVersions, &enableSSL2) != SECSuccess) {
+                          enabledVersions, &enabledVersions) != SECSuccess) {
                       Usage(progName);
                   }
                   break;
 
 	case 'a': sniHostName = PL_strdup(optstate->value); break;
 
 	case 'c': connections = PORT_Atoi(optstate->value); break;
 
@@ -1505,55 +1481,39 @@ main(int argc, char **argv)
     }
     if (sniHostName) {
         PL_strfree(sniHostName);
     }
 
     PL_strfree(hostName);
 
     /* some final stats. */
-    if (ssl3stats->hsh_sid_cache_hits +
-	ssl3stats->hsh_sid_cache_misses +
-	ssl3stats->hsh_sid_cache_not_ok +
-	ssl3stats->hsh_sid_stateless_resumes == 0) {
-	/* presumably we were testing SSL2. */
-	printf("strsclnt: SSL2 - %d server certificates tested.\n",
-               certsTested);
-    } else {
-	printf(
-	"strsclnt: %ld cache hits; %ld cache misses, %ld cache not reusable\n"
-	"          %ld stateless resumes\n",
-	    ssl3stats->hsh_sid_cache_hits, 
-	    ssl3stats->hsh_sid_cache_misses,
-	    ssl3stats->hsh_sid_cache_not_ok,
-	    ssl3stats->hsh_sid_stateless_resumes);
-    }
+    printf(
+    "strsclnt: %ld cache hits; %ld cache misses, %ld cache not reusable\n"
+    "          %ld stateless resumes\n",
+        ssl3stats->hsh_sid_cache_hits,
+        ssl3stats->hsh_sid_cache_misses,
+        ssl3stats->hsh_sid_cache_not_ok,
+        ssl3stats->hsh_sid_stateless_resumes);
 
     if (!NoReuse) {
 	if (enableSessionTickets)
 	    exitVal = (ssl3stats->hsh_sid_stateless_resumes == 0);
 	else
 	    exitVal = (ssl3stats->hsh_sid_cache_misses > 1) ||
 		      (ssl3stats->hsh_sid_stateless_resumes != 0);
 	if (!exitVal)
 	    exitVal = (ssl3stats->hsh_sid_cache_not_ok != 0) ||
 		      (certsTested > 1);
     } else {
 	printf("strsclnt: NoReuse - %d server certificates tested.\n",
                certsTested);
-        if (ssl3stats->hsh_sid_cache_hits +
-            ssl3stats->hsh_sid_cache_misses +
-            ssl3stats->hsh_sid_cache_not_ok +
-            ssl3stats->hsh_sid_stateless_resumes > 0) {
-            exitVal = (ssl3stats->hsh_sid_cache_misses != connections) ||
-                (ssl3stats->hsh_sid_stateless_resumes != 0) ||
-                (certsTested != connections);
-        } else {                /* ssl2 connections */
-            exitVal = (certsTested != connections);
-        }
+        exitVal = (ssl3stats->hsh_sid_cache_misses != connections) ||
+            (ssl3stats->hsh_sid_stateless_resumes != 0) ||
+            (certsTested != connections);
     }
 
     exitVal = ( exitVal || failed_already );
     SSL_ClearSessionCache();
     if (NSS_Shutdown() != SECSuccess) {
         printf("strsclnt: NSS_Shutdown() failed.\n");
         exit(1);
     }
--- a/cmd/tstclnt/tstclnt.c
+++ b/cmd/tstclnt/tstclnt.c
@@ -51,26 +51,16 @@
 
 #define EXIT_CODE_SIDECHANNELTEST_GOOD 0
 #define EXIT_CODE_SIDECHANNELTEST_BADCERT 1
 #define EXIT_CODE_SIDECHANNELTEST_NODATA 2
 #define EXIT_CODE_SIDECHANNELTEST_REVOKED 3
 
 PRIntervalTime maxInterval    = PR_INTERVAL_NO_TIMEOUT;
 
-int ssl2CipherSuites[] = {
-    SSL_EN_RC4_128_WITH_MD5,			/* A */
-    SSL_EN_RC4_128_EXPORT40_WITH_MD5,		/* B */
-    SSL_EN_RC2_128_CBC_WITH_MD5,		/* C */
-    SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5,	/* D */
-    SSL_EN_DES_64_CBC_WITH_MD5,			/* E */
-    SSL_EN_DES_192_EDE3_CBC_WITH_MD5,		/* F */
-    0
-};
-
 int ssl3CipherSuites[] = {
     -1, /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA* a */
     -1, /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA,	 * b */
     TLS_RSA_WITH_RC4_128_MD5,			/* c */
     TLS_RSA_WITH_3DES_EDE_CBC_SHA,		/* d */
     TLS_RSA_WITH_DES_CBC_SHA,			/* e */
     TLS_RSA_EXPORT_WITH_RC4_40_MD5,		/* f */
     TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,		/* g */
@@ -214,24 +204,24 @@ static void PrintParameterUsage(void)
     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"
+            "%-20s Possible values for min/max: ssl3 tls1.0 tls1.1 tls1.2\n"
             "%-20s Example: \"-V ssl3:\" enables SSL 3 and newer.\n",
             "-V [min]:[max]", "", "", "");
     fprintf(stderr, "%-20s Send TLS_FALLBACK_SCSV\n", "-K");
     fprintf(stderr, "%-20s Prints only payload data. Skips HTTP header.\n", "-S");
     fprintf(stderr, "%-20s Client speaks first. \n", "-f");
     fprintf(stderr, "%-20s Use synchronous certificate validation "
-                    "(required for SSL2)\n", "-O");
+                    "(currently required for TLS 1.3)\n", "-O");
     fprintf(stderr, "%-20s Override bad server cert. Make it OK.\n", "-o");
     fprintf(stderr, "%-20s Disable SSL socket locking.\n", "-s");
     fprintf(stderr, "%-20s Verbose progress reporting.\n", "-v");
     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");
@@ -268,23 +258,16 @@ static void Usage(const char *progName)
 }
 
 static void PrintCipherUsage(const char *progName)
 {
     PrintUsageHeader(progName);
     fprintf(stderr, "%-20s Letter(s) chosen from the following list\n", 
                     "-c ciphers");
     fprintf(stderr, 
-"A    SSL2 RC4 128 WITH MD5\n"
-"B    SSL2 RC4 128 EXPORT40 WITH MD5\n"
-"C    SSL2 RC2 128 CBC WITH MD5\n"
-"D    SSL2 RC2 128 CBC EXPORT40 WITH MD5\n"
-"E    SSL2 DES 64 CBC WITH MD5\n"
-"F    SSL2 DES 192 EDE3 CBC WITH MD5\n"
-"\n"
 "c    SSL3 RSA WITH RC4 128 MD5\n"
 "d    SSL3 RSA WITH 3DES EDE CBC SHA\n"
 "e    SSL3 RSA WITH DES CBC SHA\n"
 "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"
@@ -915,17 +898,16 @@ int main(int argc, char **argv)
     char *             tmp;
     int                multiplier = 0;
     SECStatus          rv;
     PRStatus           status;
     PRInt32            filesReady;
     int                npds;
     int                override = 0;
     SSLVersionRange    enabledVersions;
-    PRBool             enableSSL2 = PR_TRUE;
     int                bypassPKCS11 = 0;
     int                disableLocking = 0;
     int                useExportPolicy = 0;
     int                enableSessionTickets = 0;
     int                enableCompression = 0;
     int                enableFalseStart = 0;
     int                enableCertStatus = 0;
     int                enableSignedCertTimestamps = 0;
@@ -1030,18 +1012,17 @@ int main(int argc, char **argv)
 
           case 'S': skipProtoHeader = PR_TRUE;                 break;
 
           case 'T': enableCertStatus = 1;               break;
 
           case 'U': enableSignedCertTimestamps = 1;               break;
 
           case 'V': if (SECU_ParseSSLVersionRangeString(optstate->value,
-                            enabledVersions, enableSSL2,
-                            &enabledVersions, &enableSSL2) != SECSuccess) {
+                            enabledVersions, &enabledVersions) != SECSuccess) {
                         Usage(progName);
                     }
                     break;
 
           case 'Y': PrintCipherUsage(progName); exit(0); break;
 
           case 'a': if (!hs1SniHostName) {
                         hs1SniHostName = PORT_Strdup(optstate->value);
@@ -1245,17 +1226,17 @@ int main(int argc, char **argv)
     }
 
     /* set the policy bits true for all the cipher suites. */
     if (useExportPolicy)
         NSS_SetExportPolicy();
     else
         NSS_SetDomesticPolicy();
 
-    /* all the SSL2 and SSL3 cipher suites are enabled by default. */
+    /* all SSL3 cipher suites are enabled by default. */
     if (cipherString) {
         /* disable all the ciphers, then enable the ones we want. */
         disableAllSSLCiphers();
     }
 
     /* Create socket */
     s = PR_OpenTCPSocket(addr.raw.family);
     if (s == NULL) {
@@ -1284,48 +1265,46 @@ int main(int argc, char **argv)
     }
 
     rv = SSL_OptionSet(s, SSL_HANDSHAKE_AS_CLIENT, 1);
     if (rv != SECSuccess) {
 	SECU_PrintError(progName, "error enabling client handshake");
 	return 1;
     }
 
-    /* all the SSL2 and SSL3 cipher suites are enabled by default. */
+    /* all SSL3 cipher suites are enabled by default. */
     if (cipherString) {
     	char *cstringSaved = cipherString;
     	int ndx;
 
 	while (0 != (ndx = *cipherString++)) {
-	    int  cipher;
+            int cipher = 0;
 
 	    if (ndx == ':') {
 		int ctmp = 0;
 
-		cipher = 0;
 		HEXCHAR_TO_INT(*cipherString, ctmp)
 		cipher |= (ctmp << 12);
 		cipherString++;
 		HEXCHAR_TO_INT(*cipherString, ctmp)
 		cipher |= (ctmp << 8);
 		cipherString++;
 		HEXCHAR_TO_INT(*cipherString, ctmp)
 		cipher |= (ctmp << 4);
 		cipherString++;
 		HEXCHAR_TO_INT(*cipherString, ctmp)
 		cipher |= ctmp;
 		cipherString++;
 	    } else {
-		const int *cptr;
-
 		if (! isalpha(ndx))
 		    Usage(progName);
-		cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
-		for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; ) 
-		    /* do nothing */;
+                ndx = tolower(ndx) - 'a';
+                if (ndx < PR_ARRAY_SIZE(ssl3CipherSuites)) {
+                    cipher = ssl3CipherSuites[ndx];
+                }
 	    }
 	    if (cipher > 0) {
 		SECStatus status;
 		status = SSL_CipherPrefSet(s, cipher, SSL_ALLOWED);
 		if (status != SECSuccess) 
 		    SECU_PrintError(progName, "SSL_CipherPrefSet()");
 	    } else {
 		Usage(progName);
@@ -1335,28 +1314,16 @@ int main(int argc, char **argv)
     }
 
     rv = SSL_VersionRangeSet(s, &enabledVersions);
     if (rv != SECSuccess) {
         SECU_PrintError(progName, "error setting SSL/TLS version range ");
         return 1;
     }
 
-    rv = SSL_OptionSet(s, SSL_ENABLE_SSL2, enableSSL2);
-    if (rv != SECSuccess) {
-       SECU_PrintError(progName, "error enabling SSLv2 ");
-       return 1;
-    }
-
-    rv = SSL_OptionSet(s, SSL_V2_COMPATIBLE_HELLO, enableSSL2);
-    if (rv != SECSuccess) {
-        SECU_PrintError(progName, "error enabling SSLv2 compatible hellos ");
-        return 1;
-    }
-
     /* enable PKCS11 bypass */
     rv = SSL_OptionSet(s, SSL_BYPASS_PKCS11, bypassPKCS11);
     if (rv != SECSuccess) {
 	SECU_PrintError(progName, "error enabling PKCS11 bypass");
 	return 1;
     }
 
     /* disable SSL socket locking */
--- a/cmd/vfyserv/vfyserv.c
+++ b/cmd/vfyserv/vfyserv.c
@@ -36,18 +36,18 @@
 #include "nss.h"
 #include "secutil.h"
 #include "ocsp.h"
 
 #include "vfyserv.h"
 
 #define RD_BUF_SIZE (60 * 1024)
 
-extern int ssl2CipherSuites[];
 extern int ssl3CipherSuites[];
+extern int numSSL3CipherSuites;
 
 GlobalThreadMgr threadMGR;
 char *certNickname = NULL;
 char *hostName = NULL;
 secuPWData  pwdata          = { PW_NONE, 0 };
 unsigned short port = 0;
 PRBool dumpChain;
 
@@ -502,41 +502,40 @@ main(int argc, char **argv)
 	/* all the SSL2 and SSL3 cipher suites are enabled by default. */
 	if (cipherString) {
 	    int ndx;
 
 	    /* disable all the ciphers, then enable the ones we want. */
 	    disableAllSSLCiphers();
 
 	    while (0 != (ndx = *cipherString++)) {
-		int  cipher;
+                int cipher = 0;
 
 		if (ndx == ':') {
 		    int ctmp = 0;
 
-		    cipher = 0;
 		    HEXCHAR_TO_INT(*cipherString, ctmp)
 		    cipher |= (ctmp << 12);
 		    cipherString++;
 		    HEXCHAR_TO_INT(*cipherString, ctmp)
 		    cipher |= (ctmp << 8);
 		    cipherString++;
 		    HEXCHAR_TO_INT(*cipherString, ctmp)
 		    cipher |= (ctmp << 4);
 		    cipherString++;
 		    HEXCHAR_TO_INT(*cipherString, ctmp)
 		    cipher |= ctmp;
 		    cipherString++;
 		} else {
-		    const int *cptr;
 		    if (! isalpha(ndx))
 			Usage(progName);
-		    cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
-		    for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
-			/* do nothing */;
+                    ndx = tolower(ndx) - 'a';
+                    if (ndx < numSSL3CipherSuites) {
+                        cipher = ssl3CipherSuites[ndx];
+                    }
 		}
 		if (cipher > 0) {
 		    SSL_CipherPrefSetDefault(cipher, PR_TRUE);
 		} else {
 		    Usage(progName);
 		}
 	    }
 	}
--- a/cmd/vfyserv/vfyserv.h
+++ b/cmd/vfyserv/vfyserv.h
@@ -33,17 +33,16 @@
 #include "sslerror.h"
 */
 
 #define BUFFER_SIZE 10240
 
 /* Declare SSL cipher suites. */
 
 extern int cipherSuites[];
-extern int ssl2CipherSuites[];
 extern int ssl3CipherSuites[];
 
 /* Data buffer read from a socket. */
 typedef struct DataBufferStr {
 	char data[BUFFER_SIZE];
 	int  index;
 	int  remaining;
 	int  dataStart;
--- a/cmd/vfyserv/vfyutil.c
+++ b/cmd/vfyserv/vfyutil.c
@@ -9,26 +9,16 @@
 #include "secutil.h"
 
 
 extern PRBool dumpChain;
 extern void dumpCertChain(CERTCertificate *, SECCertUsage);
 
 /* Declare SSL cipher suites. */
 
-int ssl2CipherSuites[] = {
-    SSL_EN_RC4_128_WITH_MD5,              /* A */
-    SSL_EN_RC4_128_EXPORT40_WITH_MD5,     /* B */
-    SSL_EN_RC2_128_CBC_WITH_MD5,          /* C */
-    SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, /* D */
-    SSL_EN_DES_64_CBC_WITH_MD5,           /* E */
-    SSL_EN_DES_192_EDE3_CBC_WITH_MD5,     /* F */
-    0
-};
-
 int ssl3CipherSuites[] = {
     -1, /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA* a */
     -1, /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA,	 * b */
     TLS_RSA_WITH_RC4_128_MD5,			/* c */
     TLS_RSA_WITH_3DES_EDE_CBC_SHA,		/* d */
     TLS_RSA_WITH_DES_CBC_SHA,			/* e */
     TLS_RSA_EXPORT_WITH_RC4_40_MD5,		/* f */
     TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,		/* g */
@@ -48,16 +38,17 @@ int ssl3CipherSuites[] = {
     TLS_DHE_RSA_WITH_AES_128_CBC_SHA,       	/* u */
     TLS_RSA_WITH_AES_128_CBC_SHA,     	    	/* v */
     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
 };
+int numSSL3CipherSuites = PR_ARRAY_SIZE(ssl3CipherSuites);
 
 /**************************************************************************
 ** 
 ** SSL callback routines.
 **
 **************************************************************************/
 
 /* Function: char * myPasswd()
--- a/lib/ssl/SSLerrs.h
+++ b/lib/ssl/SSLerrs.h
@@ -1,12 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#define UNUSED_ERROR(x) ER3(SSL_ERROR_UNUSED_##x, (SSL_ERROR_BASE + x), \
+                            "Unrecognized SSL error_code.")
+
 /* SSL-specific security error codes  */
 /* caller must include "sslerr.h" */
 
 ER3(SSL_ERROR_EXPORT_ONLY_SERVER, SSL_ERROR_BASE + 0,
     "Unable to communicate securely.  Peer does not support high-grade encryption.")
 
 ER3(SSL_ERROR_US_ONLY_SERVER, SSL_ERROR_BASE + 1,
     "Unable to communicate securely.  Peer requires high-grade encryption which is not supported.")
@@ -15,33 +18,31 @@ ER3(SSL_ERROR_NO_CYPHER_OVERLAP, SSL_ERR
     "Cannot communicate securely with peer: no common encryption algorithm(s).")
 
 ER3(SSL_ERROR_NO_CERTIFICATE, SSL_ERROR_BASE + 3,
     "Unable to find the certificate or key necessary for authentication.")
 
 ER3(SSL_ERROR_BAD_CERTIFICATE, SSL_ERROR_BASE + 4,
     "Unable to communicate securely with peer: peers's certificate was rejected.")
 
-ER3(SSL_ERROR_UNUSED_5, SSL_ERROR_BASE + 5,
-    "Unrecognized SSL error code.")
+UNUSED_ERROR(5)
 
 ER3(SSL_ERROR_BAD_CLIENT, SSL_ERROR_BASE + 6,
     "The server has encountered bad data from the client.")
 
 ER3(SSL_ERROR_BAD_SERVER, SSL_ERROR_BASE + 7,
     "The client has encountered bad data from the server.")
 
 ER3(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE, SSL_ERROR_BASE + 8,
     "Unsupported certificate type.")
 
 ER3(SSL_ERROR_UNSUPPORTED_VERSION, SSL_ERROR_BASE + 9,
     "Peer using unsupported version of security protocol.")
 
-ER3(SSL_ERROR_UNUSED_10, SSL_ERROR_BASE + 10,
-    "Unrecognized SSL error code.")
+UNUSED_ERROR(10)
 
 ER3(SSL_ERROR_WRONG_CERTIFICATE, SSL_ERROR_BASE + 11,
     "Client authentication failed: private key in key database does not match public key in certificate database.")
 
 ER3(SSL_ERROR_BAD_CERT_DOMAIN, SSL_ERROR_BASE + 12,
     "Unable to communicate securely with peer: requested domain name does not match the server's certificate.")
 
 ER3(SSL_ERROR_POST_WARNING, SSL_ERROR_BASE + 13,
@@ -450,17 +451,17 @@ ER3(SSL_ERROR_RX_MALFORMED_ECDHE_KEY_SHA
 
 ER3(SSL_ERROR_RX_MALFORMED_DHE_KEY_SHARE, (SSL_ERROR_BASE + 141),
     "SSL received a malformed DHE key share handshake extension.")
 
 ER3(SSL_ERROR_RX_UNEXPECTED_ENCRYPTED_EXTENSIONS, (SSL_ERROR_BASE + 142),
     "SSL received an unexpected Encrypted Extensions handshake message.")
 
 ER3(SSL_ERROR_MISSING_EXTENSION_ALERT, (SSL_ERROR_BASE + 143),
-    "SSL received a missing_extenson alert.")
+    "SSL received a missing_extension alert.")
 
 ER3(SSL_ERROR_KEY_EXCHANGE_FAILURE, (SSL_ERROR_BASE + 144),
     "SSL had an error performing key exchange.")
 
 ER3(SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION, (SSL_ERROR_BASE + 145),
     "SSL received an extension that is not permitted for this version.")
 
 ER3(SSL_ERROR_RX_MALFORMED_ENCRYPTED_EXTENSIONS, (SSL_ERROR_BASE + 146),
--- a/lib/ssl/derive.c
+++ b/lib/ssl/derive.c
@@ -635,19 +635,18 @@ SSL_CanBypass(CERTCertificate *cert, SEC
     *pcanbypass = PR_TRUE;
     rv = SECFailure;
 
     /* determine which KEAs to test */
     /* 0 (TLS_NULL_WITH_NULL_NULL) is used as a list terminator because
      * SSL3 and TLS specs forbid negotiating that cipher suite number.
      */
     for (i = 0; i < nsuites && (suite = *ciphersuites++) != 0; i++) {
-        /* skip SSL2 cipher suites and ones NSS doesn't support */
-        if (SSL_GetCipherSuiteInfo(suite, &csdef, sizeof(csdef)) != SECSuccess ||
-            SSL_IS_SSL2_CIPHER(suite))
+        /* skip cipher suites NSS doesn't support */
+        if (SSL_GetCipherSuiteInfo(suite, &csdef, sizeof(csdef)) != SECSuccess)
             continue;
         switch (csdef.keaType) {
             case ssl_kea_rsa:
                 switch (csdef.cipherSuite) {
                     case TLS_RSA_EXPORT1024_WITH_RC4_56_SHA:
                     case TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA:
                     case TLS_RSA_EXPORT_WITH_RC4_40_MD5:
                     case TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
--- a/lib/ssl/manifest.mn
+++ b/lib/ssl/manifest.mn
@@ -26,17 +26,16 @@ CSRCS = \
 	sslauth.c \
 	sslcon.c \
 	ssldef.c \
 	sslenum.c \
 	sslerr.c \
 	sslerrstrs.c \
 	sslinit.c \
 	ssl3ext.c \
-	sslgathr.c \
 	sslmutex.c \
 	sslnonce.c \
 	sslreveal.c \
 	sslsecur.c \
 	sslsnce.c \
 	sslsock.c \
 	ssltrace.c \
 	sslver.c \
--- a/lib/ssl/notes.txt
+++ b/lib/ssl/notes.txt
@@ -5,28 +5,26 @@
 SSL's Buffers: enumerated and explained.
 
 ---------------------------------------------------------------------------
 incoming:
 
 gs = ss->gather
 hs = ss->ssl3->hs
 
-gs->inbuf   SSL3 only: incoming (encrypted) ssl records are placed here,
+gs->inbuf   incoming (encrypted) ssl records are placed here,
         and then decrypted (or copied) to gs->buf.
 
-gs->buf     SSL2: incoming SSL records are put here, and then decrypted
-        in place.
-        SSL3: ssl3_HandleHandshake puts decrypted ssl records here.
+gs->buf     ssl3_HandleHandshake puts decrypted ssl records here.
 
-hs.msg_body (SSL3 only) When an incoming handshake message spans more
+hs.msg_body When an incoming handshake message spans more
         than one ssl record, the first part(s) of it are accumulated
         here until it all arrives.
 
-hs.msgState (SSL3 only) an alternative set of pointers/lengths for gs->buf.
+hs.msgState an alternative set of pointers/lengths for gs->buf.
         Used only when a handleHandshake function returns SECWouldBlock.
         ssl3_HandleHandshake remembers how far it previously got by
         using these pointers instead of gs->buf when it is called
         after a previous SECWouldBlock return.
 
 ---------------------------------------------------------------------------
 outgoing:
 
@@ -60,46 +58,28 @@ user dialog to finish).  It is not the s
 Rank (order) of locks
 
 recvLock ->\ firstHandshake -> recvbuf -> ssl3Handshake -> xmitbuf -> "spec"
 sendLock ->/
 
 crypto and hash Data that must be protected while turning plaintext into
 ciphertext:
 
-SSL2:   (in ssl2_Send*)
-    sec->hash*
-    sec->hashcx     (ptr and data)
-    sec->enc
-    sec->writecx*   (ptr and content)
-    sec->sendSecret*(ptr and content)
-    sec->sendSequence       locked by xmitBufLock
-    sec->blockSize
-    sec->writeBuf*  (ptr & content) locked by xmitBufLock
-    "in"                locked by xmitBufLock
-
 SSl3:   (in ssl3_SendPlainText)
     ss->ssl3            (the pointer)
     ss->ssl3->current_write*    (the pointer and the data in the spec
                      and any data referenced by the spec.
 
     ss->sec->isServer
     ss->sec->writebuf* (ptr & content) locked by xmitBufLock
     "buf"                  locked by xmitBufLock
 
 crypto and hash data that must be protected while turning ciphertext into
 plaintext:
 
-SSL2:   (in ssl2_GatherData)
-    gs->*               (locked by recvBufLock )
-    sec->dec
-    sec->readcx
-    sec->hash*      (ptr and data)
-    sec->hashcx         (ptr and data)
-
 SSL3:   (in ssl3_HandleRecord )
     ssl3->current_read* (the pointer and all data refernced)
     ss->sec->isServer
 
 
 Data that must be protected while being used by a "writer":
 
 ss->pendingBuf.*
@@ -108,27 +88,17 @@ ss->saveBuf.*       (which is dead)
 in ssl3_sendPlainText
 
 ss->ssl3->current_write-> (spec)
 ss->sec->writeBuf.*
 ss->sec->isServer
 
 in SendBlock
 
-ss->sec->hash->length
-ss->sec->blockSize
 ss->sec->writeBuf.*
-ss->sec->sendSecret
-ss->sec->sendSequence
-ss->sec->writecx    *
 ss->pendingBuf
 
 --------------------------------------------------------------------------
 
 Data variables (not const) protected by the "sslGlobalDataLock".
 Note, this really should be a reader/writer lock.
 
-allowedByPolicy     sslcon.c
-maybeAllowedByPolicy    sslcon.c
-chosenPreference    sslcon.c
-policyWasSet        sslcon.c
-
 cipherSuites[]      ssl3con.c
--- a/lib/ssl/ssl.h
+++ b/lib/ssl/ssl.h
@@ -20,17 +20,17 @@
 #if defined(_WIN32) && !defined(IN_LIBSSL) && !defined(NSS_USE_STATIC_LIBS)
 #define SSL_IMPORT extern __declspec(dllimport)
 #else
 #define SSL_IMPORT extern
 #endif
 
 SEC_BEGIN_PROTOS
 
-/* constant table enumerating all implemented SSL 2 and 3 cipher suites. */
+/* constant table enumerating all implemented cipher suites. */
 SSL_IMPORT const PRUint16 SSL_ImplementedCiphers[];
 
 /* the same as the above, but is a function */
 SSL_IMPORT const PRUint16 *SSL_GetImplementedCiphers(void);
 
 /* number of entries in the above table. */
 SSL_IMPORT const PRUint16 SSL_NumImplementedCiphers;
 
--- a/lib/ssl/ssl3con.c
+++ b/lib/ssl/ssl3con.c
@@ -205,20 +205,17 @@ PR_STATIC_ASSERT(PR_ARRAY_SIZE(defaultSi
 /* Verify that SSL_ImplementedCiphers and cipherSuites are in consistent order.
  */
 #ifdef DEBUG
 void
 ssl3_CheckCipherSuiteOrderConsistency()
 {
     unsigned int i;
 
-    /* Note that SSL_ImplementedCiphers has more elements than cipherSuites
-     * because it SSL_ImplementedCiphers includes SSL 2.0 cipher suites.
-     */
-    PORT_Assert(SSL_NumImplementedCiphers >= PR_ARRAY_SIZE(cipherSuites));
+    PORT_Assert(SSL_NumImplementedCiphers == PR_ARRAY_SIZE(cipherSuites));
 
     for (i = 0; i < PR_ARRAY_SIZE(cipherSuites); ++i) {
         PORT_Assert(SSL_ImplementedCiphers[i] == cipherSuites[i].cipher_suite);
     }
 }
 #endif
 
 /* This list of SSL3 compression methods is sorted in descending order of
@@ -811,17 +808,17 @@ ssl3_config_match_init(sslSocket *ss)
     PRBool isServer;
     sslServerCerts *svrAuth;
 
     PORT_Assert(ss);
     if (!ss) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return 0;
     }
-    if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
+    if (SSL_ALL_VERSIONS_DISABLED(&ss->vrange)) {
         return 0;
     }
     isServer = (PRBool)(ss->sec.isServer != 0);
 
     for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
         suite = &ss->cipherSuites[i];
         if (suite->enabled) {
             ++numEnabled;
@@ -919,23 +916,23 @@ config_match(ssl3CipherSuiteCfg *suite, 
                     suite->policy != SSL_NOT_ALLOWED &&
                     suite->policy <= policy &&
                     ssl3_CipherSuiteAllowedForVersionRange(
                         suite->cipher_suite, vrange));
 }
 
 /* return number of cipher suites that match policy, enabled state and are
  * applicable for the configured protocol version range. */
-/* called from ssl3_SendClientHello and ssl3_ConstructV2CipherSpecsHack */
+/* called from ssl3_SendClientHello */
 static int
 count_cipher_suites(sslSocket *ss, int policy, PRBool enabled)
 {
     int i, count = 0;
 
-    if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
+    if (SSL_ALL_VERSIONS_DISABLED(&ss->vrange)) {
         return 0;
     }
     for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
         if (config_match(&ss->cipherSuites[i], policy, enabled, &ss->vrange, ss))
             count++;
     }
     if (count <= 0) {
         PORT_SetError(SSL_ERROR_SSL_DISABLED);
@@ -972,17 +969,17 @@ Null_Cipher(void *ctx, unsigned char *ou
  *
  * If allowLargerPeerVersion is true, peerVersion is the peer's highest
  * enabled version rather than the peer's selected version.
  */
 SECStatus
 ssl3_NegotiateVersion(sslSocket *ss, SSL3ProtocolVersion peerVersion,
                       PRBool allowLargerPeerVersion)
 {
-    if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
+    if (SSL_ALL_VERSIONS_DISABLED(&ss->vrange)) {
         PORT_SetError(SSL_ERROR_SSL_DISABLED);
         return SECFailure;
     }
 
     if (peerVersion < ss->vrange.min ||
         (peerVersion > ss->vrange.max && !allowLargerPeerVersion)) {
         PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
         return SECFailure;
@@ -2490,17 +2487,17 @@ ssl3_ComputeRecordMAC(
                 break;
         }
         if (!hashObj) {
             PORT_Assert(0);
             PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
             return SECFailure;
         }
 
-        if (spec->version <= SSL_LIBRARY_VERSION_3_0) {
+        if (spec->version == SSL_LIBRARY_VERSION_3_0) {
             unsigned int tempLen;
             unsigned char temp[MAX_MAC_LENGTH];
 
             /* compute "inner" part of SSL3 MAC */
             hashObj->begin(write_mac_context);
             if (useServerMacKey)
                 hashObj->update(write_mac_context,
                                 spec->server.write_mac_key_item.data,
@@ -2605,17 +2602,17 @@ ssl3_ComputeRecordMACConstantTime(
     }
 
     if (spec->mac_def->mac == mac_null) {
         *outLen = 0;
         return SECSuccess;
     }
 
     macType = CKM_NSS_HMAC_CONSTANT_TIME;
-    if (spec->version <= SSL_LIBRARY_VERSION_3_0) {
+    if (spec->version == SSL_LIBRARY_VERSION_3_0) {
         macType = CKM_NSS_SSL3_MAC_CONSTANT_TIME;
     }
 
     params.macAlg = spec->mac_def->mmech;
     params.ulBodyTotalLen = originalLen;
     params.pHeader = (unsigned char *)header; /* const cast */
     params.ulHeaderLen = headerLen;
 
@@ -4372,17 +4369,16 @@ ssl3_RestartHandshakeHashes(sslSocket *s
     return rv;
 }
 
 /*
  * Handshake messages
  */
 /* Called from  ssl3_InitHandshakeHashes()
 **      ssl3_AppendHandshake()
-**      ssl3_StartHandshakeHash()
 **      ssl3_HandleV2ClientHello()
 **      ssl3_HandleHandshakeMessage()
 ** Caller must hold the ssl3Handshake lock.
 */
 static SECStatus
 ssl3_UpdateHandshakeHashes(sslSocket *ss, const unsigned char *b,
                            unsigned int l)
 {
@@ -5226,60 +5222,24 @@ ssl3_ComputeBackupHandshakeHashes(sslSoc
     hashes->hashAlg = ssl_hash_sha1;
 
 loser:
     PK11_DestroyContext(ss->ssl3.hs.backupHash, PR_TRUE);
     ss->ssl3.hs.backupHash = NULL;
     return rv;
 }
 
-/*
- * SSL 2 based implementations pass in the initial outbound buffer
- * so that the handshake hash can contain the included information.
- *
- * Called from ssl2_BeginClientHandshake() in sslcon.c
- */
-SECStatus
-ssl3_StartHandshakeHash(sslSocket *ss, unsigned char *buf, int length)
-{
-    SECStatus rv;
-
-    ssl_GetSSL3HandshakeLock(ss); /**************************************/
-
-    rv = ssl3_InitState(ss);
-    if (rv != SECSuccess) {
-        goto done; /* ssl3_InitState has set the error code. */
-    }
-    rv = ssl3_RestartHandshakeHashes(ss);
-    if (rv != SECSuccess) {
-        goto done;
-    }
-
-    PORT_Memset(&ss->ssl3.hs.client_random, 0, SSL3_RANDOM_LENGTH);
-    PORT_Memcpy(
-        &ss->ssl3.hs.client_random.rand[SSL3_RANDOM_LENGTH - SSL_CHALLENGE_BYTES],
-        &ss->sec.ci.clientChallenge,
-        SSL_CHALLENGE_BYTES);
-
-    rv = ssl3_UpdateHandshakeHashes(ss, buf, length);
-    /* if it failed, ssl3_UpdateHandshakeHashes has set the error code. */
-
-done:
-    ssl_ReleaseSSL3HandshakeLock(ss); /**************************************/
-    return rv;
-}
-
 /**************************************************************************
  * end of Handshake Hash functions.
  * Begin Send and Handle functions for handshakes.
  **************************************************************************/
 
 /* Called from ssl3_HandleHelloRequest(),
  *             ssl3_RedoHandshake()
- *             ssl2_BeginClientHandshake (when resuming ssl3 session)
+ *             ssl_BeginClientHandshake (when resuming ssl3 session)
  *             dtls_HandleHelloVerifyRequest(with resending=PR_TRUE)
  */
 SECStatus
 ssl3_SendClientHello(sslSocket *ss, PRBool resending)
 {
     sslSessionID *sid;
     ssl3CipherSpec *cwSpec;
     SECStatus rv;
@@ -5322,31 +5282,31 @@ ssl3_SendClientHello(sslSocket *ss, PRBo
         return rv;
     }
 
     /*
      * During a renegotiation, ss->clientHelloVersion will be used again to
      * work around a Windows SChannel bug. Ensure that it is still enabled.
      */
     if (ss->firstHsDone) {
-        if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
+        if (SSL_ALL_VERSIONS_DISABLED(&ss->vrange)) {
             PORT_SetError(SSL_ERROR_SSL_DISABLED);
             return SECFailure;
         }
 
         if (ss->clientHelloVersion < ss->vrange.min ||
             ss->clientHelloVersion > ss->vrange.max) {
             PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
             return SECFailure;
         }
     }
 
     /* We ignore ss->sec.ci.sid here, and use ssl_Lookup because Lookup
      * handles expired entries and other details.
-     * XXX If we've been called from ssl2_BeginClientHandshake, then
+     * XXX If we've been called from ssl_BeginClientHandshake, then
      * this lookup is duplicative and wasteful.
      */
     sid = (ss->opt.noCache) ? NULL
                             : ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID, ss->url);
 
     /* We can't resume based on a different token. If the sid exists,
      * make sure the token that holds the master secret still exists ...
      * If we previously did client-auth, make sure that the token that holds
@@ -5492,20 +5452,18 @@ ssl3_SendClientHello(sslSocket *ss, PRBo
     }
     ssl_ReleaseSpecWriteLock(ss);
 
     if (ss->sec.ci.sid != NULL) {
         ssl_FreeSID(ss->sec.ci.sid); /* decrement ref count, free if zero */
     }
     ss->sec.ci.sid = sid;
 
-    ss->sec.send = ssl3_SendApplicationData;
-
     /* shouldn't get here if SSL3 is disabled, but ... */
-    if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
+    if (SSL_ALL_VERSIONS_DISABLED(&ss->vrange)) {
         PR_NOT_REACHED("No versions of SSL 3.0 or later are enabled");
         PORT_SetError(SSL_ERROR_SSL_DISABLED);
         return SECFailure;
     }
 
     /* how many suites does our PKCS11 support (regardless of policy)? */
     num_suites = ssl3_config_match_init(ss);
     if (!num_suites)
@@ -8323,30 +8281,16 @@ ssl3_HandleClientHello(sslSocket *ss, SS
     }
 
     /* Get peer name of client */
     rv = ssl_GetPeerInfo(ss);
     if (rv != SECSuccess) {
         return rv; /* error code is set. */
     }
 
-    /* Clearing the handshake pointers so that ssl_Do1stHandshake won't
-     * call ssl2_HandleMessage.
-     *
-     * The issue here is that TLS ordinarily starts out in
-     * ssl2_HandleV3HandshakeRecord() because of the backward-compatibility
-     * code paths. That function zeroes these next pointers. But with DTLS,
-     * we don't even try to do the v2 ClientHello so we skip that function
-     * and need to reset these values here.
-     */
-    if (IS_DTLS(ss)) {
-        ss->nextHandshake = 0;
-        ss->securityHandshake = 0;
-    }
-
     /* We might be starting session renegotiation in which case we should
      * clear previous state.
      */
     PORT_Memset(&ss->xtnData, 0, sizeof(TLSExtensionData));
     ss->statelessResume = PR_FALSE;
 
     if (IS_DTLS(ss)) {
         dtls_RehandshakeCleanup(ss);
@@ -8762,18 +8706,16 @@ suite_found:
     errCode = SSL_ERROR_NO_COMPRESSION_OVERLAP;
     /* null compression must be supported */
     goto alert_loser;
 
 compression_found:
     suites.data = NULL;
     comps.data = NULL;
 
-    ss->sec.send = ssl3_SendApplicationData;
-
     /* If there are any failures while processing the old sid,
      * we don't consider them to be errors.  Instead, We just behave
      * as if the client had sent us no sid to begin with, and make a new one.
      * The exception here is attempts to resume extended_master_secret
      * sessions without the extension, which causes an alert.
      */
     if (sid != NULL)
         do {
@@ -9200,17 +9142,16 @@ loser:
 
     PORT_SetError(errCode);
     return SECFailure;
 }
 
 /*
  * ssl3_HandleV2ClientHello is used when a V2 formatted hello comes
  * in asking to use the V3 handshake.
- * Called from ssl2_HandleClientHelloMessage() in sslcon.c
  */
 SECStatus
 ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length)
 {
     sslSessionID *sid = NULL;
     unsigned char *suites;
     unsigned char *random;
     SSL3ProtocolVersion version;
@@ -9363,17 +9304,16 @@ suite_found:
     if (ss->opt.requireSafeNegotiation &&
         !ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) {
         desc = handshake_failure;
         errCode = SSL_ERROR_UNSAFE_NEGOTIATION;
         goto alert_loser;
     }
 
     ss->ssl3.hs.compression = ssl_compression_null;
-    ss->sec.send = ssl3_SendApplicationData;
 
     /* we don't even search for a cache hit here.  It's just a miss. */
     SSL_AtomicIncrementLong(&ssl3stats.hch_sid_cache_misses);
     sid = ssl3_NewSessionID(ss, PR_TRUE);
     if (sid == NULL) {
         errCode = PORT_GetError();
         goto loser; /* memory error is set. */
     }
@@ -9390,23 +9330,16 @@ suite_found:
     ssl_GetXmitBufLock(ss);
     rv = ssl3_SendServerHelloSequence(ss);
     ssl_ReleaseXmitBufLock(ss);
     if (rv != SECSuccess) {
         errCode = PORT_GetError();
         goto loser;
     }
 
-    /* XXX_1    The call stack to here is:
-     * ssl_Do1stHandshake -> ssl2_HandleClientHelloMessage -> here.
-     * ssl2_HandleClientHelloMessage returns whatever we return here.
-     * ssl_Do1stHandshake will continue looping if it gets back either
-     *      SECSuccess or SECWouldBlock.
-     * SECSuccess is preferable here.  See XXX_1 in sslgathr.c.
-     */
     ssl_ReleaseSSL3HandshakeLock(ss);
     return SECSuccess;
 
 alert_loser:
     SSL3_SendAlert(ss, alert_fatal, desc);
 loser:
     ssl_ReleaseSSL3HandshakeLock(ss);
     PORT_SetError(errCode);
@@ -13108,17 +13041,16 @@ ssl3_InitCipherSpec(ssl3CipherSpec *spec
     spec->read_seq_num.high = 0;
     spec->read_seq_num.low = 0;
 
     spec->epoch = 0;
     dtls_InitRecvdRecords(&spec->recvdRecords);
 }
 
 /* Called from: ssl3_SendRecord
-**      ssl3_StartHandshakeHash() <- ssl2_BeginClientHandshake()
 **      ssl3_SendClientHello()
 **      ssl3_HandleV2ClientHello()
 **      ssl3_HandleRecord()
 **
 ** This function should perhaps acquire and release the SpecWriteLock.
 **
 **
 */
@@ -13431,54 +13363,16 @@ void
 ssl3_InitSocketPolicy(sslSocket *ss)
 {
     PORT_Memcpy(ss->cipherSuites, cipherSuites, sizeof cipherSuites);
     PORT_Memcpy(ss->ssl3.signatureAlgorithms, defaultSignatureAlgorithms,
                 sizeof(defaultSignatureAlgorithms));
     ss->ssl3.signatureAlgorithmCount = PR_ARRAY_SIZE(defaultSignatureAlgorithms);
 }
 
-/* ssl3_config_match_init must have already been called by
- * the caller of this function.
- */
-SECStatus
-ssl3_ConstructV2CipherSpecsHack(sslSocket *ss, unsigned char *cs, int *size)
-{
-    int i, count = 0;
-
-    PORT_Assert(ss != 0);
-    if (!ss) {
-        PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
-        return SECFailure;
-    }
-    if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
-        *size = 0;
-        return SECSuccess;
-    }
-    if (cs == NULL) {
-        *size = count_cipher_suites(ss, SSL_ALLOWED, PR_TRUE);
-        return SECSuccess;
-    }
-
-    /* ssl3_config_match_init was called by the caller of this function. */
-    for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
-        ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
-        if (config_match(suite, SSL_ALLOWED, PR_TRUE, &ss->vrange, ss)) {
-            if (cs != NULL) {
-                *cs++ = 0x00;
-                *cs++ = (suite->cipher_suite >> 8) & 0xFF;
-                *cs++ = suite->cipher_suite & 0xFF;
-            }
-            count++;
-        }
-    }
-    *size = count;
-    return SECSuccess;
-}
-
 /*
 ** If ssl3 socket has completed the first handshake, and is in idle state,
 ** then start a new handshake.
 ** If flushCache is true, the SID cache will be flushed first, forcing a
 ** "Full" handshake (not a session restart handshake), to be done.
 **
 ** called from SSL_RedoHandshake(), which already holds the handshake locks.
 */
@@ -13486,19 +13380,17 @@ SECStatus
 ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache)
 {
     sslSessionID *sid = ss->sec.ci.sid;
     SECStatus rv;
 
     PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
 
     if (!ss->firstHsDone ||
-        ((ss->version >= SSL_LIBRARY_VERSION_3_0) &&
-         ss->ssl3.initialized &&
-         (ss->ssl3.hs.ws != idle_handshake))) {
+        (ss->ssl3.initialized && (ss->ssl3.hs.ws != idle_handshake))) {
         PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED);
         return SECFailure;
     }
 
     if (IS_DTLS(ss)) {
         dtls_RehandshakeCleanup(ss);
     }
 
--- a/lib/ssl/ssl3gthr.c
+++ b/lib/ssl/ssl3gthr.c
@@ -5,16 +5,42 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "cert.h"
 #include "ssl.h"
 #include "sslimpl.h"
 #include "ssl3prot.h"
 
+/* Caller should hold RecvBufLock. */
+SECStatus
+ssl3_InitGather(sslGather *gs)
+{
+    SECStatus status;
+
+    gs->state = GS_INIT;
+    gs->writeOffset = 0;
+    gs->readOffset = 0;
+    gs->dtlsPacketOffset = 0;
+    gs->dtlsPacket.len = 0;
+    status = sslBuffer_Grow(&gs->buf, 4096);
+    return status;
+}
+
+/* Caller must hold RecvBufLock. */
+void
+ssl3_DestroyGather(sslGather *gs)
+{
+    if (gs) { /* the PORT_*Free functions check for NULL pointers. */
+        PORT_ZFree(gs->buf.buf, gs->buf.space);
+        PORT_Free(gs->inbuf.buf);
+        PORT_Free(gs->dtlsPacket.buf);
+    }
+}
+
 /*
  * Attempt to read in an entire SSL3 record.
  * Blocks here for blocking sockets, otherwise returns -1 with
  *  PR_WOULD_BLOCK_ERROR when socket would block.
  *
  * returns  1 if received a complete SSL3 record.
  * returns  0 if recv returns EOF
  * returns -1 if recv returns < 0
@@ -121,16 +147,18 @@ ssl3_GatherData(sslSocket *ss, sslGather
                     lbp = gs->inbuf.buf;
                 }
                 break; /* End this case.  Continue around the loop. */
 
             case GS_DATA:
                 /*
                 ** SSL3 record has been completely received.
                 */
+                SSL_TRC(10, ("%d: SSL[%d]: got record of %d bytes",
+                             SSL_GETPID(), ss->fd, gs->inbuf.len));
                 gs->state = GS_INIT;
                 return 1;
         }
     }
 
     return rv;
 }
 
--- a/lib/ssl/sslauth.c
+++ b/lib/ssl/sslauth.c
@@ -116,21 +116,17 @@ SSL_SecurityStatus(PRFileDesc *fd, int *
         *ip = 0;
     if (sp)
         *sp = 0;
     if (op) {
         *op = SSL_SECURITY_STATUS_OFF;
     }
 
     if (ss->opt.useSecurity && ss->enoughFirstHsDone) {
-        if (ss->version < SSL_LIBRARY_VERSION_3_0) {
-            cipherName = ssl_cipherName[ss->sec.cipherType];
-        } else {
-            cipherName = ssl3_cipherName[ss->sec.cipherType];
-        }
+        cipherName = ssl3_cipherName[ss->sec.cipherType];
         PORT_Assert(cipherName);
         if (cipherName) {
             if (PORT_Strstr(cipherName, "DES"))
                 isDes = PR_TRUE;
 
             if (cp) {
                 *cp = PORT_Strdup(cipherName);
             }
--- a/lib/ssl/sslcon.c
+++ b/lib/ssl/sslcon.c
@@ -15,67 +15,16 @@
 #include "sslimpl.h"
 #include "sslproto.h"
 #include "ssl3prot.h"
 #include "sslerr.h"
 #include "pk11func.h"
 #include "prinit.h"
 #include "prtime.h" /* for PR_Now() */
 
-static PRBool policyWasSet;
-
-#define ssl2_NUM_SUITES_IMPLEMENTED 6
-
-/* This list is sent back to the client when the client-hello message
- * contains no overlapping ciphers, so the client can report what ciphers
- * are supported by the server.  Unlike allCipherSuites (above), this list
- * is sorted by descending preference, not by cipherSuite number.
- */
-/* clang-format off */
-static const PRUint8 implementedCipherSuites[ssl2_NUM_SUITES_IMPLEMENTED * 3] = {
-    SSL_CK_RC4_128_WITH_MD5,                0x00, 0x80,
-    SSL_CK_RC2_128_CBC_WITH_MD5,            0x00, 0x80,
-    SSL_CK_DES_192_EDE3_CBC_WITH_MD5,       0x00, 0xC0,
-    SSL_CK_DES_64_CBC_WITH_MD5,             0x00, 0x40,
-    SSL_CK_RC4_128_EXPORT40_WITH_MD5,       0x00, 0x80,
-    SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5,   0x00, 0x80
-};
-
-
-typedef struct ssl2SpecsStr {
-    PRUint8 nkm; /* do this many hashes to generate key material. */
-    PRUint8 nkd; /* size of readKey and writeKey in bytes. */
-    PRUint8 blockSize;
-    PRUint8 blockShift;
-    CK_MECHANISM_TYPE mechanism;
-    PRUint8 keyLen; /* cipher symkey size in bytes. */
-    PRUint8 pubLen; /* publicly reveal this many bytes of key. */
-    PRUint8 ivLen;  /* length of IV data at *ca.    */
-} ssl2Specs;
-
-static const ssl2Specs ssl_Specs[] = {
-  /* NONE                                 */
-  { 0, 0, 0, 0 },
-  /* SSL_CK_RC4_128_WITH_MD5        */
-  { 2, 16, 1, 0, CKM_RC4,       16,   0, 0 },
-  /* SSL_CK_RC4_128_EXPORT40_WITH_MD5   */
-  { 2, 16, 1, 0, CKM_RC4,       16,  11, 0 },
-  /* SSL_CK_RC2_128_CBC_WITH_MD5        */
-  { 2, 16, 8, 3, CKM_RC2_CBC,   16,   0, 8 },
-  /* SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5   */
-  { 2, 16, 8, 3, CKM_RC2_CBC,   16,  11, 8 },
-  /* SSL_CK_IDEA_128_CBC_WITH_MD5       */
-  { 0, 0, 0, 0 },
-  /* SSL_CK_DES_64_CBC_WITH_MD5     */
-  { 1,  8, 8, 3, CKM_DES_CBC,    8,   0, 8 },
-  /* SSL_CK_DES_192_EDE3_CBC_WITH_MD5   */
-  { 3, 24, 8, 3, CKM_DES3_CBC,  24,   0, 8 },
-};
-/* clang-format on */
-
 #define SET_ERROR_CODE   /* reminder */
 #define TEST_FOR_FAILURE /* reminder */
 
 /*
 ** Put a string tag in the library so that we can examine an executable
 ** and see what kind of security it supports.
 */
 const char *ssl_version = "SECURITY_VERSION:"
@@ -84,1143 +33,57 @@ const char *ssl_version = "SECURITY_VERS
 #ifdef TRACE
                           " +trace"
 #endif
 #ifdef DEBUG
                           " +debug"
 #endif
     ;
 
-const char *const ssl_cipherName[] = {
-    "unknown",
-    "RC4",
-    "RC4-Export",
-    "RC2-CBC",
-    "RC2-CBC-Export",
-    "IDEA-CBC",
-    "DES-CBC",
-    "DES-EDE3-CBC",
-    "unknown",
-    "unknown", /* was fortezza, NO LONGER USED */
-};
-
-/* bit-masks, showing which SSLv2 suites are allowed.
- * lsb corresponds to first cipher suite in allCipherSuites[].
- */
-static PRUint16 allowedByPolicy;         /* all off by default */
-static PRUint16 maybeAllowedByPolicy;    /* all off by default */
-static PRUint16 chosenPreference = 0xff; /* all on  by default */
-
-/* bit values for the above two bit masks */
-#define SSL_CB_RC4_128_WITH_MD5 (1 << SSL_CK_RC4_128_WITH_MD5)
-#define SSL_CB_RC4_128_EXPORT40_WITH_MD5 (1 << SSL_CK_RC4_128_EXPORT40_WITH_MD5)
-#define SSL_CB_RC2_128_CBC_WITH_MD5 (1 << SSL_CK_RC2_128_CBC_WITH_MD5)
-#define SSL_CB_RC2_128_CBC_EXPORT40_WITH_MD5 (1 << SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5)
-#define SSL_CB_IDEA_128_CBC_WITH_MD5 (1 << SSL_CK_IDEA_128_CBC_WITH_MD5)
-#define SSL_CB_DES_64_CBC_WITH_MD5 (1 << SSL_CK_DES_64_CBC_WITH_MD5)
-#define SSL_CB_DES_192_EDE3_CBC_WITH_MD5 (1 << SSL_CK_DES_192_EDE3_CBC_WITH_MD5)
-#define SSL_CB_IMPLEMENTED                  \
-    (SSL_CB_RC4_128_WITH_MD5 |              \
-     SSL_CB_RC4_128_EXPORT40_WITH_MD5 |     \
-     SSL_CB_RC2_128_CBC_WITH_MD5 |          \
-     SSL_CB_RC2_128_CBC_EXPORT40_WITH_MD5 | \
-     SSL_CB_DES_64_CBC_WITH_MD5 |           \
-     SSL_CB_DES_192_EDE3_CBC_WITH_MD5)
-
-/* Construct a socket's list of cipher specs from the global default values.
- */
-static SECStatus
-ssl2_ConstructCipherSpecs(sslSocket *ss)
-{
-    PRUint8 *cs = NULL;
-    unsigned int allowed;
-    unsigned int count;
-    int ssl3_count = 0;
-    int final_count;
-    int i;
-    SECStatus rv;
-
-    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-
-    count = 0;
-    PORT_Assert(ss != 0);
-    allowed = !ss->opt.enableSSL2 ? 0 : (ss->allowedByPolicy &
-                                         ss->chosenPreference & SSL_CB_IMPLEMENTED);
-    while (allowed) {
-        if (allowed & 1)
-            ++count;
-        allowed >>= 1;
-    }
-
-    /* Call ssl3_config_match_init() once here,
-     * instead of inside ssl3_ConstructV2CipherSpecsHack(),
-     * because the latter gets called twice below,
-     * and then again in ssl2_BeginClientHandshake().
-     */
-    ssl3_config_match_init(ss);
-
-    /* ask SSL3 how many cipher suites it has. */
-    rv = ssl3_ConstructV2CipherSpecsHack(ss, NULL, &ssl3_count);
-    if (rv < 0)
-        return rv;
-    count += ssl3_count;
-
-    /* Allocate memory to hold cipher specs */
-    if (count > 0)
-        cs = (PRUint8 *)PORT_Alloc(count * 3);
-    else
-        PORT_SetError(SSL_ERROR_SSL_DISABLED);
-    if (cs == NULL)
-        return SECFailure;
-
-    if (ss->cipherSpecs != NULL) {
-        PORT_Free(ss->cipherSpecs);
-    }
-    ss->cipherSpecs = cs;
-    ss->sizeCipherSpecs = count * 3;
-
-    /* fill in cipher specs for SSL2 cipher suites */
-    allowed = !ss->opt.enableSSL2 ? 0 : (ss->allowedByPolicy &
-                                         ss->chosenPreference & SSL_CB_IMPLEMENTED);
-    for (i = 0; i < ssl2_NUM_SUITES_IMPLEMENTED * 3; i += 3) {
-        const PRUint8 *hs = implementedCipherSuites + i;
-        int ok = allowed & (1U << hs[0]);
-        if (ok) {
-            cs[0] = hs[0];
-            cs[1] = hs[1];
-            cs[2] = hs[2];
-            cs += 3;
-        }
-    }
-
-    /* now have SSL3 add its suites onto the end */
-    rv = ssl3_ConstructV2CipherSpecsHack(ss, cs, &final_count);
-
-    /* adjust for any difference between first pass and second pass */
-    ss->sizeCipherSpecs -= (ssl3_count - final_count) * 3;
-
-    return rv;
-}
-
-/* This function is called immediately after ssl2_ConstructCipherSpecs()
-** at the beginning of a handshake.  It detects cases where a protocol
-** (e.g. SSL2 or SSL3) is logically enabled, but all its cipher suites
-** for that protocol have been disabled.  If such cases, it clears the
-** enable bit for the protocol.  If no protocols remain enabled, or
-** if no cipher suites are found, it sets the error code and returns
-** SECFailure, otherwise it returns SECSuccess.
-*/
-static SECStatus
-ssl2_CheckConfigSanity(sslSocket *ss)
-{
-    unsigned int allowed;
-    int ssl3CipherCount = 0;
-    SECStatus rv;
-
-    /* count the SSL2 and SSL3 enabled ciphers.
-     * if either is zero, clear the socket's enable for that protocol.
-     */
-    if (!ss->cipherSpecs)
-        goto disabled;
-
-    allowed = ss->allowedByPolicy & ss->chosenPreference;
-    if (!allowed)
-        ss->opt.enableSSL2 = PR_FALSE; /* not really enabled if no ciphers */
-
-    /* ssl3_config_match_init was called in ssl2_ConstructCipherSpecs(). */
-    /* Ask how many ssl3 CipherSuites were enabled. */
-    rv = ssl3_ConstructV2CipherSpecsHack(ss, NULL, &ssl3CipherCount);
-    if (rv != SECSuccess || ssl3CipherCount <= 0) {
-        /* SSL3/TLS not really enabled if no ciphers */
-        ss->vrange.min = SSL_LIBRARY_VERSION_NONE;
-        ss->vrange.max = SSL_LIBRARY_VERSION_NONE;
-    }
-
-    if (!ss->opt.enableSSL2 && SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
-        SSL_DBG(("%d: SSL[%d]: Can't handshake! all versions disabled.",
-                 SSL_GETPID(), ss->fd));
-    disabled:
-        PORT_SetError(SSL_ERROR_SSL_DISABLED);
-        return SECFailure;
-    }
-    return SECSuccess;
-}
-
-/*
- * Since this is a global (not per-socket) setting, we cannot use the
- * HandshakeLock to protect this.  Probably want a global lock.
- */
-SECStatus
-ssl2_SetPolicy(PRInt32 which, PRInt32 policy)
-{
-    PRUint32 bitMask;
-    SECStatus rv = SECSuccess;
-
-    which &= 0x000f;
-    bitMask = 1 << which;
-
-    if (!(bitMask & SSL_CB_IMPLEMENTED)) {
-        PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
-        return SECFailure;
-    }
-
-    if (policy == SSL_ALLOWED) {
-        allowedByPolicy |= bitMask;
-        maybeAllowedByPolicy |= bitMask;
-    } else if (policy == SSL_RESTRICTED) {
-        allowedByPolicy &= ~bitMask;
-        maybeAllowedByPolicy |= bitMask;
-    } else {
-        allowedByPolicy &= ~bitMask;
-        maybeAllowedByPolicy &= ~bitMask;
-    }
-    allowedByPolicy &= SSL_CB_IMPLEMENTED;
-    maybeAllowedByPolicy &= SSL_CB_IMPLEMENTED;
-
-    policyWasSet = PR_TRUE;
-    return rv;
-}
-
-SECStatus
-ssl2_GetPolicy(PRInt32 which, PRInt32 *oPolicy)
-{
-    PRUint32 bitMask;
-    PRInt32 policy;
-
-    which &= 0x000f;
-    bitMask = 1 << which;
-
-    /* Caller assures oPolicy is not null. */
-    if (!(bitMask & SSL_CB_IMPLEMENTED)) {
-        PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
-        *oPolicy = SSL_NOT_ALLOWED;
-        return SECFailure;
-    }
-
-    if (maybeAllowedByPolicy & bitMask) {
-        policy = (allowedByPolicy & bitMask) ? SSL_ALLOWED : SSL_RESTRICTED;
-    } else {
-        policy = SSL_NOT_ALLOWED;
-    }
-
-    *oPolicy = policy;
-    return SECSuccess;
-}
-
-/*
- * Since this is a global (not per-socket) setting, we cannot use the
- * HandshakeLock to protect this.  Probably want a global lock.
- * Called from SSL_CipherPrefSetDefault in sslsock.c
- * These changes have no effect on any sslSockets already created.
- */
-SECStatus
-ssl2_CipherPrefSetDefault(PRInt32 which, PRBool enabled)
-{
-    PRUint32 bitMask;
-
-    which &= 0x000f;
-    bitMask = 1 << which;
-
-    if (!(bitMask & SSL_CB_IMPLEMENTED)) {
-        PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
-        return SECFailure;
-    }
-
-    if (enabled)
-        chosenPreference |= bitMask;
-    else
-        chosenPreference &= ~bitMask;
-    chosenPreference &= SSL_CB_IMPLEMENTED;
-
-    return SECSuccess;
-}
-
-SECStatus
-ssl2_CipherPrefGetDefault(PRInt32 which, PRBool *enabled)
-{
-    PRBool rv = PR_FALSE;
-    PRUint32 bitMask;
-
-    which &= 0x000f;
-    bitMask = 1 << which;
-
-    if (!(bitMask & SSL_CB_IMPLEMENTED)) {
-        PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
-        *enabled = PR_FALSE;
-        return SECFailure;
-    }
-
-    rv = (PRBool)((chosenPreference & bitMask) != 0);
-    *enabled = rv;
-    return SECSuccess;
-}
-
-SECStatus
-ssl2_CipherPrefSet(sslSocket *ss, PRInt32 which, PRBool enabled)
-{
-    PRUint32 bitMask;
-
-    which &= 0x000f;
-    bitMask = 1 << which;
-
-    if (!(bitMask & SSL_CB_IMPLEMENTED)) {
-        PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
-        return SECFailure;
-    }
-
-    if (enabled)
-        ss->chosenPreference |= bitMask;
-    else
-        ss->chosenPreference &= ~bitMask;
-    ss->chosenPreference &= SSL_CB_IMPLEMENTED;
-
-    return SECSuccess;
-}
-
-SECStatus
-ssl2_CipherPrefGet(sslSocket *ss, PRInt32 which, PRBool *enabled)
-{
-    PRBool rv = PR_FALSE;
-    PRUint32 bitMask;
-
-    which &= 0x000f;
-    bitMask = 1 << which;
-
-    if (!(bitMask & SSL_CB_IMPLEMENTED)) {
-        PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
-        *enabled = PR_FALSE;
-        return SECFailure;
-    }
-
-    rv = (PRBool)((ss->chosenPreference & bitMask) != 0);
-    *enabled = rv;
-    return SECSuccess;
-}
-
-/* copy global default policy into socket. */
-void
-ssl2_InitSocketPolicy(sslSocket *ss)
-{
-    ss->allowedByPolicy = allowedByPolicy;
-    ss->maybeAllowedByPolicy = maybeAllowedByPolicy;
-    ss->chosenPreference = chosenPreference;
-}
-
-/************************************************************************/
-
-/* Called from ssl2_CreateSessionCypher(), which already holds handshake lock.
- */
-static SECStatus
-ssl2_CreateMAC(sslSecurityInfo *sec, SECItem *readKey, SECItem *writeKey,
-               int cipherChoice)
-{
-    switch (cipherChoice) {
-        case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
-        case SSL_CK_RC2_128_CBC_WITH_MD5:
-        case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
-        case SSL_CK_RC4_128_WITH_MD5:
-        case SSL_CK_DES_64_CBC_WITH_MD5:
-        case SSL_CK_DES_192_EDE3_CBC_WITH_MD5:
-            sec->hash = HASH_GetHashObject(HASH_AlgMD5);
-            if (SECITEM_CopyItem(0, &sec->sendSecret, writeKey) ||
-                SECITEM_CopyItem(0, &sec->rcvSecret, readKey)) {
-                return SECFailure;
-            }
-            break;
-
-        default:
-            PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
-            return SECFailure;
-    }
-    sec->hashcx = (*sec->hash->create)();
-    if (sec->hashcx == NULL)
-        return SECFailure;
-    return SECSuccess;
-}
-
-/************************************************************************
- * All the Send functions below must acquire and release the socket's
- * xmitBufLock.
- */
-
-/* Called from all the Send* functions below. */
-static SECStatus
-ssl2_GetSendBuffer(sslSocket *ss, unsigned int len)
-{
-    SECStatus rv = SECSuccess;
-
-    PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
-
-    if (len < 128) {
-        len = 128;
-    }
-    if (len > ss->sec.ci.sendBuf.space) {
-        rv = sslBuffer_Grow(&ss->sec.ci.sendBuf, len);
-        if (rv != SECSuccess) {
-            SSL_DBG(("%d: SSL[%d]: ssl2_GetSendBuffer failed, tried to get %d bytes",
-                     SSL_GETPID(), ss->fd, len));
-            rv = SECFailure;
-        }
-    }
-    return rv;
-}
-
-/* Called from:
- * ssl2_ClientSetupSessionCypher()  <- ssl2_HandleServerHelloMessage()
- * ssl2_HandleRequestCertificate()  <- ssl2_HandleMessage()
-                                    <- ssl_Do1stHandshake()
- * ssl2_HandleMessage()             <- ssl_Do1stHandshake()
- * ssl2_HandleServerHelloMessage()  <- ssl_Do1stHandshake()
-                                    after ssl2_BeginClientHandshake()
- * ssl2_HandleClientHelloMessage()  <- ssl_Do1stHandshake()
-                                    after ssl2_BeginServerHandshake()
- *
- * Acquires and releases the socket's xmitBufLock.
- */
-int
-ssl2_SendErrorMessage(sslSocket *ss, int error)
-{
-    int rv;
-    PRUint8 msg[SSL_HL_ERROR_HBYTES];
-
-    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-
-    msg[0] = SSL_MT_ERROR;
-    msg[1] = MSB(error);
-    msg[2] = LSB(error);
-
-    ssl_GetXmitBufLock(ss); /***************************************/
-
-    SSL_TRC(3, ("%d: SSL[%d]: sending error %d", SSL_GETPID(), ss->fd, error));
-
-    ss->handshakeBegun = 1;
-    rv = (*ss->sec.send)(ss, msg, sizeof(msg), 0);
-    if (rv >= 0) {
-        rv = SECSuccess;
-    }
-    ssl_ReleaseXmitBufLock(ss); /***************************************/
-    return rv;
-}
-
-/* Called from ssl2_TryToFinish().
- * Acquires and releases the socket's xmitBufLock.
- */
-static SECStatus
-ssl2_SendClientFinishedMessage(sslSocket *ss)
-{
-    SECStatus rv = SECSuccess;
-    int sent;
-    PRUint8 msg[1 + SSL_CONNECTIONID_BYTES];
-
-    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-
-    ssl_GetXmitBufLock(ss); /***************************************/
-
-    if (ss->sec.ci.sentFinished == 0) {
-        ss->sec.ci.sentFinished = 1;
-
-        SSL_TRC(3, ("%d: SSL[%d]: sending client-finished",
-                    SSL_GETPID(), ss->fd));
-
-        msg[0] = SSL_MT_CLIENT_FINISHED;
-        PORT_Memcpy(msg + 1, ss->sec.ci.connectionID,
-                    sizeof(ss->sec.ci.connectionID));
-
-        DUMP_MSG(29, (ss, msg, 1 + sizeof(ss->sec.ci.connectionID)));
-        sent = (*ss->sec.send)(ss, msg, 1 + sizeof(ss->sec.ci.connectionID), 0);
-        rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
-    }
-    ssl_ReleaseXmitBufLock(ss); /***************************************/
-    return rv;
-}
-
-/* Called from
- * ssl2_HandleClientSessionKeyMessage() <- ssl2_HandleClientHelloMessage()
- * ssl2_HandleClientHelloMessage()      <- ssl_Do1stHandshake()
-                                        after ssl2_BeginServerHandshake()
- * Acquires and releases the socket's xmitBufLock.
- */
-static SECStatus
-ssl2_SendServerVerifyMessage(sslSocket *ss)
-{
-    PRUint8 *msg;
-    int sendLen;
-    int sent;
-    SECStatus rv;
-
-    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-
-    ssl_GetXmitBufLock(ss); /***************************************/
-
-    sendLen = 1 + SSL_CHALLENGE_BYTES;
-    rv = ssl2_GetSendBuffer(ss, sendLen);
-    if (rv != SECSuccess) {
-        goto done;
-    }
-
-    msg = ss->sec.ci.sendBuf.buf;
-    msg[0] = SSL_MT_SERVER_VERIFY;
-    PORT_Memcpy(msg + 1, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES);
-
-    DUMP_MSG(29, (ss, msg, sendLen));
-    sent = (*ss->sec.send)(ss, msg, sendLen, 0);
-
-    rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
-
-done:
-    ssl_ReleaseXmitBufLock(ss); /***************************************/
-    return rv;
-}
-
-/* Called from ssl2_TryToFinish().
- * Acquires and releases the socket's xmitBufLock.
- */
-static SECStatus
-ssl2_SendServerFinishedMessage(sslSocket *ss)
-{
-    sslSessionID *sid;
-    PRUint8 *msg;
-    int sendLen, sent;
-    SECStatus rv = SECSuccess;
-
-    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-
-    ssl_GetXmitBufLock(ss); /***************************************/
-
-    if (ss->sec.ci.sentFinished == 0) {
-        ss->sec.ci.sentFinished = 1;
-        PORT_Assert(ss->sec.ci.sid != 0);
-        sid = ss->sec.ci.sid;
-
-        SSL_TRC(3, ("%d: SSL[%d]: sending server-finished",
-                    SSL_GETPID(), ss->fd));
-
-        sendLen = 1 + sizeof(sid->u.ssl2.sessionID);
-        rv = ssl2_GetSendBuffer(ss, sendLen);
-        if (rv != SECSuccess) {
-            goto done;
-        }
-
-        msg = ss->sec.ci.sendBuf.buf;
-        msg[0] = SSL_MT_SERVER_FINISHED;
-        PORT_Memcpy(msg + 1, sid->u.ssl2.sessionID,
-                    sizeof(sid->u.ssl2.sessionID));
-
-        DUMP_MSG(29, (ss, msg, sendLen));
-        sent = (*ss->sec.send)(ss, msg, sendLen, 0);
-
-        if (sent < 0) {
-            /* If send failed, it is now a bogus  session-id */
-            if (ss->sec.uncache)
-                (*ss->sec.uncache)(sid);
-            rv = (SECStatus)sent;
-        } else if (!ss->opt.noCache) {
-            if (sid->cached == never_cached) {
-                (*ss->sec.cache)(sid);
-            }
-            rv = SECSuccess;
-        }
-        ssl_FreeSID(sid);
-        ss->sec.ci.sid = 0;
-    }
-done:
-    ssl_ReleaseXmitBufLock(ss); /***************************************/
-    return rv;
-}
-
-/* Called from ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage()
- *                                             after ssl2_BeginClientHandshake()
- * Acquires and releases the socket's xmitBufLock.
- */
-static SECStatus
-ssl2_SendSessionKeyMessage(sslSocket *ss, int cipher, int keySize,
-                           PRUint8 *ca, int caLen,
-                           PRUint8 *ck, int ckLen,
-                           PRUint8 *ek, int ekLen)
-{
-    PRUint8 *msg;
-    int sendLen;
-    int sent;
-    SECStatus rv;
-
-    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-
-    ssl_GetXmitBufLock(ss); /***************************************/
-
-    sendLen = SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen;
-    rv = ssl2_GetSendBuffer(ss, sendLen);
-    if (rv != SECSuccess)
-        goto done;
-
-    SSL_TRC(3, ("%d: SSL[%d]: sending client-session-key",
-                SSL_GETPID(), ss->fd));
-
-    msg = ss->sec.ci.sendBuf.buf;
-    msg[0] = SSL_MT_CLIENT_MASTER_KEY;
-    msg[1] = cipher;
-    msg[2] = MSB(keySize);
-    msg[3] = LSB(keySize);
-    msg[4] = MSB(ckLen);
-    msg[5] = LSB(ckLen);
-    msg[6] = MSB(ekLen);
-    msg[7] = LSB(ekLen);
-    msg[8] = MSB(caLen);
-    msg[9] = LSB(caLen);
-    PORT_Memcpy(msg + SSL_HL_CLIENT_MASTER_KEY_HBYTES, ck, ckLen);
-    PORT_Memcpy(msg + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen, ek, ekLen);
-    PORT_Memcpy(msg + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen, ca, caLen);
-
-    DUMP_MSG(29, (ss, msg, sendLen));
-    sent = (*ss->sec.send)(ss, msg, sendLen, 0);
-    rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
-done:
-    ssl_ReleaseXmitBufLock(ss); /***************************************/
-    return rv;
-}
-
-/* Called from ssl2_TriggerNextMessage() <- ssl2_HandleMessage()
- * Acquires and releases the socket's xmitBufLock.
- */
-static SECStatus
-ssl2_SendCertificateRequestMessage(sslSocket *ss)
-{
-    PRUint8 *msg;
-    int sent;
-    int sendLen;
-    SECStatus rv;
-
-    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-
-    ssl_GetXmitBufLock(ss); /***************************************/
-
-    sendLen = SSL_HL_REQUEST_CERTIFICATE_HBYTES + SSL_CHALLENGE_BYTES;
-    rv = ssl2_GetSendBuffer(ss, sendLen);
-    if (rv != SECSuccess)
-        goto done;
-
-    SSL_TRC(3, ("%d: SSL[%d]: sending certificate request",
-                SSL_GETPID(), ss->fd));
-
-    /* Generate random challenge for client to encrypt */
-    PK11_GenerateRandom(ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES);
-
-    msg = ss->sec.ci.sendBuf.buf;
-    msg[0] = SSL_MT_REQUEST_CERTIFICATE;
-    msg[1] = SSL_AT_MD5_WITH_RSA_ENCRYPTION;
-    PORT_Memcpy(msg + SSL_HL_REQUEST_CERTIFICATE_HBYTES,
-                ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES);
-
-    DUMP_MSG(29, (ss, msg, sendLen));
-    sent = (*ss->sec.send)(ss, msg, sendLen, 0);
-    rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
-done:
-    ssl_ReleaseXmitBufLock(ss); /***************************************/
-    return rv;
-}
-
-/* Called from ssl2_HandleRequestCertificate() <- ssl2_HandleMessage()
- * Acquires and releases the socket's xmitBufLock.
- */
-static int
-ssl2_SendCertificateResponseMessage(sslSocket *ss, SECItem *cert,
-                                    SECItem *encCode)
-{
-    PRUint8 *msg;
-    int rv, sendLen;
-
-    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-
-    ssl_GetXmitBufLock(ss); /***************************************/
-
-    sendLen = SSL_HL_CLIENT_CERTIFICATE_HBYTES + encCode->len + cert->len;
-    rv = ssl2_GetSendBuffer(ss, sendLen);
-    if (rv)
-        goto done;
-
-    SSL_TRC(3, ("%d: SSL[%d]: sending certificate response",
-                SSL_GETPID(), ss->fd));
-
-    msg = ss->sec.ci.sendBuf.buf;
-    msg[0] = SSL_MT_CLIENT_CERTIFICATE;
-    msg[1] = SSL_CT_X509_CERTIFICATE;
-    msg[2] = MSB(cert->len);
-    msg[3] = LSB(cert->len);
-    msg[4] = MSB(encCode->len);
-    msg[5] = LSB(encCode->len);
-    PORT_Memcpy(msg + SSL_HL_CLIENT_CERTIFICATE_HBYTES, cert->data, cert->len);
-    PORT_Memcpy(msg + SSL_HL_CLIENT_CERTIFICATE_HBYTES + cert->len,
-                encCode->data, encCode->len);
-
-    DUMP_MSG(29, (ss, msg, sendLen));
-    rv = (*ss->sec.send)(ss, msg, sendLen, 0);
-    if (rv >= 0) {
-        rv = SECSuccess;
-    }
-done:
-    ssl_ReleaseXmitBufLock(ss); /***************************************/
-    return rv;
-}
-
-/********************************************************************
-**  Send functions above this line must aquire & release the socket's
-**  xmitBufLock.
-** All the ssl2_Send functions below this line are called vis ss->sec.send
-**  and require that the caller hold the xmitBufLock.
-*/
-
-/*
-** Called from ssl2_SendStream, ssl2_SendBlock, but not from ssl2_SendClear.
-*/
-static SECStatus
-ssl2_CalcMAC(PRUint8 *result,
-             sslSecurityInfo *sec,
-             const PRUint8 *data,
-             unsigned int dataLen,
-             unsigned int paddingLen)
-{
-    const PRUint8 *secret = sec->sendSecret.data;
-    unsigned int secretLen = sec->sendSecret.len;
-    unsigned long sequenceNumber = sec->sendSequence;
-    unsigned int nout;
-    PRUint8 seq[4];
-    PRUint8 padding[32]; /* XXX max blocksize? */
-
-    if (!sec->hash || !sec->hash->length)
-        return SECSuccess;
-    if (!sec->hashcx)
-        return SECFailure;
-
-    /* Reset hash function */
-    (*sec->hash->begin)(sec->hashcx);
-
-    /* Feed hash the data */
-    (*sec->hash->update)(sec->hashcx, secret, secretLen);
-    (*sec->hash->update)(sec->hashcx, data, dataLen);
-    PORT_Memset(padding, paddingLen, paddingLen);
-    (*sec->hash->update)(sec->hashcx, padding, paddingLen);
-
-    seq[0] = (PRUint8)(sequenceNumber >> 24);
-    seq[1] = (PRUint8)(sequenceNumber >> 16);
-    seq[2] = (PRUint8)(sequenceNumber >> 8);
-    seq[3] = (PRUint8)(sequenceNumber);
-
-    PRINT_BUF(60, (0, "calc-mac secret:", secret, secretLen));
-    PRINT_BUF(60, (0, "calc-mac data:", data, dataLen));
-    PRINT_BUF(60, (0, "calc-mac padding:", padding, paddingLen));
-    PRINT_BUF(60, (0, "calc-mac seq:", seq, 4));
-
-    (*sec->hash->update)(sec->hashcx, seq, 4);
-
-    /* Get result */
-    (*sec->hash->end)(sec->hashcx, result, &nout, sec->hash->length);
-
-    return SECSuccess;
-}
-
-/*
-** Maximum transmission amounts. These are tiny bit smaller than they
-** need to be (they account for the MAC length plus some padding),
-** assuming the MAC is 16 bytes long and the padding is a max of 7 bytes
-** long. This gives an additional 9 bytes of slop to work within.
-*/
-#define MAX_STREAM_CYPHER_LEN 0x7fe0
-#define MAX_BLOCK_CYPHER_LEN 0x3fe0
-
-/*
-** Send some data in the clear.
-** Package up data with the length header and send it.
-**
-** Return count of bytes successfully written, or negative number (failure).
-*/
-static PRInt32
-ssl2_SendClear(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
-{
-    PRUint8 *out;
-    int rv;
-    unsigned int amount;
-    int count = 0;
-
-    PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
-
-    SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes in the clear",
-                 SSL_GETPID(), ss->fd, len));
-    PRINT_BUF(50, (ss, "clear data:", (PRUint8 *)in, len));
-
-    while (len) {
-        amount = PR_MIN(len, MAX_STREAM_CYPHER_LEN);
-        if (amount + 2 > ss->sec.writeBuf.space) {
-            rv = sslBuffer_Grow(&ss->sec.writeBuf, amount + 2);
-            if (rv != SECSuccess) {
-                count = rv;
-                break;
-            }
-        }
-        out = ss->sec.writeBuf.buf;
-
-        /*
-        ** Construct message.
-        */
-        out[0] = 0x80 | MSB(amount);
-        out[1] = LSB(amount);
-        PORT_Memcpy(&out[2], in, amount);
-
-        /* Now send the data */
-        rv = ssl_DefSend(ss, out, amount + 2, flags & ~ssl_SEND_FLAG_MASK);
-        if (rv < 0) {
-            if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) {
-                rv = 0;
-            } else {
-                /* Return short write if some data already went out... */
-                if (count == 0)
-                    count = rv;
-                break;
-            }
-        }
-
-        if ((unsigned)rv < (amount + 2)) {
-            /* Short write.  Save the data and return. */
-            if (ssl_SaveWriteData(ss, out + rv, amount + 2 - rv) ==
-                SECFailure) {
-                count = SECFailure;
-            } else {
-                count += amount;
-                ss->sec.sendSequence++;
-            }
-            break;
-        }
-
-        ss->sec.sendSequence++;
-        in += amount;
-        count += amount;
-        len -= amount;
-    }
-
-    return count;
-}
-
-/*
-** Send some data, when using a stream cipher. Stream ciphers have a
-** block size of 1. Package up the data with the length header
-** and send it.
-*/
-static PRInt32
-ssl2_SendStream(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
-{
-    PRUint8 *out;
-    int rv;
-    int count = 0;
-
-    int amount;
-    PRUint8 macLen;
-    int nout;
-    unsigned int buflen;
-
-    PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
-
-    SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using stream cipher",
-                 SSL_GETPID(), ss->fd, len));
-    PRINT_BUF(50, (ss, "clear data:", (PRUint8 *)in, len));
-
-    while (len) {
-        ssl_GetSpecReadLock(ss); /*************************************/
-
-        macLen = ss->sec.hash->length;
-        amount = PR_MIN(len, MAX_STREAM_CYPHER_LEN);
-        buflen = amount + 2 + macLen;
-        if (buflen > ss->sec.writeBuf.space) {
-            rv = sslBuffer_Grow(&ss->sec.writeBuf, buflen);
-            if (rv != SECSuccess) {
-                goto loser;
-            }
-        }
-        out = ss->sec.writeBuf.buf;
-        nout = amount + macLen;
-        out[0] = 0x80 | MSB(nout);
-        out[1] = LSB(nout);
-
-        /* Calculate MAC */
-        rv = ssl2_CalcMAC(out + 2, /* put MAC here */
-                          &ss->sec,
-                          in, amount, /* input addr & length */
-                          0);         /* no padding */
-        if (rv != SECSuccess)
-            goto loser;
-
-        /* Encrypt MAC */
-        rv = (*ss->sec.enc)(ss->sec.writecx, out + 2, &nout, macLen, out + 2, macLen);
-        if (rv)
-            goto loser;
-
-        /* Encrypt data from caller */
-        rv = (*ss->sec.enc)(ss->sec.writecx, out + 2 + macLen, &nout, amount, in, amount);
-        if (rv)
-            goto loser;
-
-        ssl_ReleaseSpecReadLock(ss); /*************************************/
-
-        PRINT_BUF(50, (ss, "encrypted data:", out, buflen));
-
-        rv = ssl_DefSend(ss, out, buflen, flags & ~ssl_SEND_FLAG_MASK);
-        if (rv < 0) {
-            if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) {
-                SSL_TRC(50, ("%d: SSL[%d]: send stream would block, "
-                             "saving data",
-                             SSL_GETPID(), ss->fd));
-                rv = 0;
-            } else {
-                SSL_TRC(10, ("%d: SSL[%d]: send stream error %d",
-                             SSL_GETPID(), ss->fd, PORT_GetError()));
-                /* Return short write if some data already went out... */
-                if (count == 0)
-                    count = rv;
-                goto done;
-            }
-        }
-
-        if ((unsigned)rv < buflen) {
-            /* Short write.  Save the data and return. */
-            if (ssl_SaveWriteData(ss, out + rv, buflen - rv) == SECFailure) {
-                count = SECFailure;
-            } else {
-                count += amount;
-                ss->sec.sendSequence++;
-            }
-            goto done;
-        }
-
-        ss->sec.sendSequence++;
-        in += amount;
-        count += amount;
-        len -= amount;
-    }
-
-done:
-    return count;
-
-loser:
-    ssl_ReleaseSpecReadLock(ss);
-    return SECFailure;
-}
-
-/*
-** Send some data, when using a block cipher. Package up the data with
-** the length header and send it.
-*/
-/* XXX assumes blocksize is > 7 */
-static PRInt32
-ssl2_SendBlock(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
-{
-    PRUint8 *out;  /* begining of output buffer.    */
-    PRUint8 *op;   /* next output byte goes here.   */
-    int rv;        /* value from funcs we called.   */
-    int count = 0; /* this function's return value. */
-
-    unsigned int hlen;    /* output record hdr len, 2 or 3 */
-    unsigned int macLen;  /* MAC is this many bytes long.  */
-    int amount;           /* of plaintext to go in record. */
-    unsigned int padding; /* add this many padding byte.   */
-    int nout;             /* ciphertext size after header. */
-    unsigned int buflen;  /* size of generated record.     */
-
-    PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
-
-    SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using block cipher",
-                 SSL_GETPID(), ss->fd, len));
-    PRINT_BUF(50, (ss, "clear data:", in, len));
-
-    while (len) {
-        ssl_GetSpecReadLock(ss); /*************************************/
-
-        macLen = ss->sec.hash->length;
-        /* Figure out how much to send, including mac and padding */
-        amount = PR_MIN(len, MAX_BLOCK_CYPHER_LEN);
-        nout = amount + macLen;
-        padding = nout & (ss->sec.blockSize - 1);
-        if (padding) {
-            hlen = 3;
-            padding = ss->sec.blockSize - padding;
-            nout += padding;
-        } else {
-            hlen = 2;
-        }
-        buflen = hlen + nout;
-        if (buflen > ss->sec.writeBuf.space) {
-            rv = sslBuffer_Grow(&ss->sec.writeBuf, buflen);
-            if (rv != SECSuccess) {
-                goto loser;
-            }
-        }
-        out = ss->sec.writeBuf.buf;
-
-        /* Construct header */
-        op = out;
-        if (padding) {
-            *op++ = MSB(nout);
-            *op++ = LSB(nout);
-            *op++ = padding;
-        } else {
-            *op++ = 0x80 | MSB(nout);
-            *op++ = LSB(nout);
-        }
-
-        /* Calculate MAC */
-        rv = ssl2_CalcMAC(op, /* MAC goes here. */
-                          &ss->sec,
-                          in, amount, /* intput addr, len */
-                          padding);
-        if (rv != SECSuccess)
-            goto loser;
-        op += macLen;
-
-        /* Copy in the input data */
-        /* XXX could eliminate the copy by folding it into the encryption */
-        PORT_Memcpy(op, in, amount);
-        op += amount;
-        if (padding) {
-            PORT_Memset(op, padding, padding);
-            op += padding;
-        }
-
-        /* Encrypt result */
-        rv = (*ss->sec.enc)(ss->sec.writecx, out + hlen, &nout, buflen - hlen,
-                            out + hlen, op - (out + hlen));
-        if (rv)
-            goto loser;
-
-        ssl_ReleaseSpecReadLock(ss); /*************************************/
-
-        PRINT_BUF(50, (ss, "final xmit data:", out, op - out));
-
-        rv = ssl_DefSend(ss, out, op - out, flags & ~ssl_SEND_FLAG_MASK);
-        if (rv < 0) {
-            if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) {
-                rv = 0;
-            } else {
-                SSL_TRC(10, ("%d: SSL[%d]: send block error %d",
-                             SSL_GETPID(), ss->fd, PORT_GetError()));
-                /* Return short write if some data already went out... */
-                if (count == 0)
-                    count = rv;
-                goto done;
-            }
-        }
-
-        if (rv < (op - out)) {
-            /* Short write.  Save the data and return. */
-            if (ssl_SaveWriteData(ss, out + rv, op - out - rv) == SECFailure) {
-                count = SECFailure;
-            } else {
-                count += amount;
-                ss->sec.sendSequence++;
-            }
-            goto done;
-        }
-
-        ss->sec.sendSequence++;
-        in += amount;
-        count += amount;
-        len -= amount;
-    }
-
-done:
-    return count;
-
-loser:
-    ssl_ReleaseSpecReadLock(ss);
-    return SECFailure;
-}
-
-/*
-** Called from: ssl2_HandleServerHelloMessage,
-**              ssl2_HandleClientSessionKeyMessage,
-**              ssl2_HandleClientHelloMessage,
-**
-*/
-static void
-ssl2_UseEncryptedSendFunc(sslSocket *ss)
-{
-    ssl_GetXmitBufLock(ss);
-    PORT_Assert(ss->sec.hashcx != 0);
-
-    ss->gs.encrypted = 1;
-    ss->sec.send = (ss->sec.blockSize > 1) ? ssl2_SendBlock : ssl2_SendStream;
-    ssl_ReleaseXmitBufLock(ss);
-}
-
-/* Called while initializing socket in ssl_CreateSecurityInfo().
-** This function allows us to keep the name of ssl2_SendClear static.
-*/
-void
-ssl2_UseClearSendFunc(sslSocket *ss)
-{
-    ss->sec.send = ssl2_SendClear;
-}
-
-/************************************************************************
-**          END of Send functions.                          *
-*************************************************************************/
-
 /***********************************************************************
- * For SSL3, this gathers in and handles records/messages until either
- *  the handshake is complete or application data is available.
- *
- * For SSL2, this gathers in only the next SSLV2 record.
+ * Gathers in and handles records/messages until either the handshake is
+ * complete or application data is available.
  *
  * Called from ssl_Do1stHandshake() via function pointer ss->handshake.
  * Caller must hold handshake lock.
  * This function acquires and releases the RecvBufLock.
  *
  * returns SECSuccess for success.
- * returns SECWouldBlock when that value is returned by ssl2_GatherRecord() or
+ * returns SECWouldBlock when that value is returned by
  *  ssl3_GatherCompleteHandshake().
  * returns SECFailure on all other errors.
  *
  * The gather functions called by ssl_GatherRecord1stHandshake are expected
  *  to return values interpreted as follows:
  *  1 : the function completed without error.
  *  0 : the function read EOF.
  * -1 : read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
  * -2 : the function wants ssl_GatherRecord1stHandshake to be called again
  *  immediately, by ssl_Do1stHandshake.
  *
  * This code is similar to, and easily confused with, DoRecv() in sslsecur.c
  *
  * This function is called from ssl_Do1stHandshake().
  * The following functions put ssl_GatherRecord1stHandshake into ss->handshake:
- *  ssl2_HandleMessage
- *  ssl2_HandleVerifyMessage
- *  ssl2_HandleServerHelloMessage
- *  ssl2_BeginClientHandshake
- *  ssl2_HandleClientSessionKeyMessage
+ *  ssl_BeginClientHandshake
  *  ssl3_RestartHandshakeAfterCertReq
  *  ssl3_RestartHandshakeAfterServerCert
- *  ssl2_HandleClientHelloMessage
- *  ssl2_BeginServerHandshake
+ *  ssl_BeginServerHandshake
  */
 SECStatus
 ssl_GatherRecord1stHandshake(sslSocket *ss)
 {
     int rv;
 
     PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
 
     ssl_GetRecvBufLock(ss);
 
-    /* The special case DTLS logic is needed here because the SSL/TLS
-     * version wants to auto-detect SSL2 vs. SSL3 on the initial handshake
-     * (ss->version == 0) but with DTLS it gets confused, so we force the
-     * SSL3 version.
-     */
-    if ((ss->version >= SSL_LIBRARY_VERSION_3_0) || IS_DTLS(ss)) {
-        /* Wait for handshake to complete, or application data to arrive.  */
-        rv = ssl3_GatherCompleteHandshake(ss, 0);
-    } else {
-        /* See if we have a complete record */
-        rv = ssl2_GatherRecord(ss, 0);
-    }
+    /* Wait for handshake to complete, or application data to arrive.  */
+    rv = ssl3_GatherCompleteHandshake(ss, 0);
     SSL_TRC(10, ("%d: SSL[%d]: handshake gathering, rv=%d",
                  SSL_GETPID(), ss->fd, rv));
 
     ssl_ReleaseRecvBufLock(ss);
 
     if (rv <= 0) {
         if (rv == SECWouldBlock) {
             /* Progress is blocked waiting for callback completion.  */
@@ -1230,1759 +93,49 @@ ssl_GatherRecord1stHandshake(sslSocket *
         }
         if (rv == 0) {
             /* EOF. Loser  */
             PORT_SetError(PR_END_OF_FILE_ERROR);
         }
         return SECFailure; /* rv is < 0 here. */
     }
 
-    SSL_TRC(10, ("%d: SSL[%d]: got handshake record of %d bytes",
-                 SSL_GETPID(), ss->fd, ss->gs.recordLen));
-
-    ss->handshake = 0; /* makes ssl_Do1stHandshake call ss->nextHandshake.*/
-    return SECSuccess;
-}
-
-/************************************************************************/
-
-/* Called from ssl2_ServerSetupSessionCypher()
- *             ssl2_ClientSetupSessionCypher()
- */
-static SECStatus
-ssl2_FillInSID(sslSessionID *sid,
-               int cipher,
-               PRUint8 *keyData,
-               int keyLen,
-               PRUint8 *ca,
-               int caLen,
-               int keyBits,
-               int secretKeyBits,
-               SSLSignType authAlgorithm,
-               PRUint32 authKeyBits,
-               SSLKEAType keaType,
-               PRUint32 keaKeyBits)
-{
-    PORT_Assert(sid->references == 1);
-    PORT_Assert(sid->cached == never_cached);
-    PORT_Assert(sid->u.ssl2.masterKey.data == 0);
-    PORT_Assert(sid->u.ssl2.cipherArg.data == 0);
-
-    sid->version = SSL_LIBRARY_VERSION_2;
-
-    sid->u.ssl2.cipherType = cipher;
-    sid->u.ssl2.masterKey.data = (PRUint8 *)PORT_Alloc(keyLen);
-    if (!sid->u.ssl2.masterKey.data) {
-        return SECFailure;
-    }
-    PORT_Memcpy(sid->u.ssl2.masterKey.data, keyData, keyLen);
-    sid->u.ssl2.masterKey.len = keyLen;
-    sid->u.ssl2.keyBits = keyBits;
-    sid->u.ssl2.secretKeyBits = secretKeyBits;
-    sid->authAlgorithm = authAlgorithm;
-    sid->authKeyBits = authKeyBits;
-    sid->keaType = keaType;
-    sid->keaKeyBits = keaKeyBits;
-    sid->lastAccessTime = sid->creationTime = ssl_Time();
-    sid->expirationTime = sid->creationTime + ssl_sid_timeout;
-
-    if (caLen) {
-        sid->u.ssl2.cipherArg.data = (PRUint8 *)PORT_Alloc(caLen);
-        if (!sid->u.ssl2.cipherArg.data) {
-            return SECFailure;
-        }
-        sid->u.ssl2.cipherArg.len = caLen;
-        PORT_Memcpy(sid->u.ssl2.cipherArg.data, ca, caLen);
-    }
-    return SECSuccess;
-}
-
-/*
-** Construct session keys given the masterKey (tied to the session-id),
-** the client's challenge and the server's nonce.
-**
-** Called from ssl2_CreateSessionCypher() <-
-*/
-static SECStatus
-ssl2_ProduceKeys(sslSocket *ss,
-                 SECItem *readKey,
-                 SECItem *writeKey,
-                 SECItem *masterKey,
-                 PRUint8 *challenge,
-                 PRUint8 *nonce,
-                 int cipherType)
-{
-    PK11Context *cx = 0;
-    unsigned nkm = 0; /* number of hashes to generate key mat. */
-    unsigned nkd = 0; /* size of readKey and writeKey. */
-    unsigned part;
-    unsigned i;
-    unsigned off;
-    SECStatus rv;
-    PRUint8 countChar;
-    PRUint8 km[3 * 16]; /* buffer for key material. */
-
-    readKey->data = 0;
-    writeKey->data = 0;
-
-    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-
-    rv = SECSuccess;
-    cx = PK11_CreateDigestContext(SEC_OID_MD5);
-    if (cx == NULL) {
-        ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
-        return SECFailure;
-    }
-
-    nkm = ssl_Specs[cipherType].nkm;
-    nkd = ssl_Specs[cipherType].nkd;
-
-    readKey->data = (PRUint8 *)PORT_Alloc(nkd);
-    if (!readKey->data)
-        goto loser;
-    readKey->len = nkd;
-
-    writeKey->data = (PRUint8 *)PORT_Alloc(nkd);
-    if (!writeKey->data)
-        goto loser;
-    writeKey->len = nkd;
-
-    /* Produce key material */
-    countChar = '0';
-    for (i = 0, off = 0; i < nkm; i++, off += 16) {
-        rv = PK11_DigestBegin(cx);
-        rv |= PK11_DigestOp(cx, masterKey->data, masterKey->len);
-        rv |= PK11_DigestOp(cx, &countChar, 1);
-        rv |= PK11_DigestOp(cx, challenge, SSL_CHALLENGE_BYTES);
-        rv |= PK11_DigestOp(cx, nonce, SSL_CONNECTIONID_BYTES);
-        rv |= PK11_DigestFinal(cx, km + off, &part, MD5_LENGTH);
-        if (rv != SECSuccess) {
-            ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
-            rv = SECFailure;
-            goto loser;
-        }
-        countChar++;
-    }
-
-    /* Produce keys */
-    PORT_Memcpy(readKey->data, km, nkd);
-    PORT_Memcpy(writeKey->data, km + nkd, nkd);
-
-loser:
-    PK11_DestroyContext(cx, PR_TRUE);
-    return rv;
-}
-
-/* Called from ssl2_ServerSetupSessionCypher()
-**                  <- ssl2_HandleClientSessionKeyMessage()
-**                          <- ssl2_HandleClientHelloMessage()
-** and from    ssl2_ClientSetupSessionCypher()
-**                  <- ssl2_HandleServerHelloMessage()
-*/
-static SECStatus
-ssl2_CreateSessionCypher(sslSocket *ss, sslSessionID *sid, PRBool isClient)
-{
-    SECItem *rk = NULL;
-    SECItem *wk = NULL;
-    SECItem *param;
-    SECStatus rv;
-    int cipherType = sid->u.ssl2.cipherType;
-    PK11SlotInfo *slot = NULL;
-    CK_MECHANISM_TYPE mechanism;
-    SECItem readKey;
-    SECItem writeKey;
-
-    void *readcx = 0;
-    void *writecx = 0;
-    readKey.data = 0;
-    writeKey.data = 0;
-
-    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-    if (ss->sec.ci.sid == 0)
-        goto sec_loser; /* don't crash if asserts are off */
-
-    /* Trying to cut down on all these switch statements that should be tables.
-     * So, test cipherType once, here, and then use tables below.
-     */
-    switch (cipherType) {
-        case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
-        case SSL_CK_RC4_128_WITH_MD5:
-        case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
-        case SSL_CK_RC2_128_CBC_WITH_MD5:
-        case SSL_CK_DES_64_CBC_WITH_MD5:
-        case SSL_CK_DES_192_EDE3_CBC_WITH_MD5:
-            break;
-
-        default:
-            SSL_DBG(("%d: SSL[%d]: ssl2_CreateSessionCypher: unknown cipher=%d",
-                     SSL_GETPID(), ss->fd, cipherType));
-            PORT_SetError(isClient ? SSL_ERROR_BAD_SERVER : SSL_ERROR_BAD_CLIENT);
-            goto sec_loser;
-    }
-
-    rk = isClient ? &readKey : &writeKey;
-    wk = isClient ? &writeKey : &readKey;
-
-    /* Produce the keys for this session */
-    rv = ssl2_ProduceKeys(ss, &readKey, &writeKey, &sid->u.ssl2.masterKey,
-                          ss->sec.ci.clientChallenge, ss->sec.ci.connectionID,
-                          cipherType);
-    if (rv != SECSuccess)
-        goto loser;
-    PRINT_BUF(7, (ss, "Session read-key: ", rk->data, rk->len));
-    PRINT_BUF(7, (ss, "Session write-key: ", wk->data, wk->len));
-
-    PORT_Memcpy(ss->sec.ci.readKey, readKey.data, readKey.len);
-    PORT_Memcpy(ss->sec.ci.writeKey, writeKey.data, writeKey.len);
-    ss->sec.ci.keySize = readKey.len;
-
-    /* Setup the MAC */
-    rv = ssl2_CreateMAC(&ss->sec, rk, wk, cipherType);
-    if (rv != SECSuccess)
-        goto loser;
-
-    /* First create the session key object */
-    SSL_TRC(3, ("%d: SSL[%d]: using %s", SSL_GETPID(), ss->fd,
-                ssl_cipherName[cipherType]));
-
-    mechanism = ssl_Specs[cipherType].mechanism;
-
-    /* set destructer before we call loser... */
-    ss->sec.destroy = (void (*)(void *, PRBool))PK11_DestroyContext;
-    slot = PK11_GetBestSlot(mechanism, ss->pkcs11PinArg);
-    if (slot == NULL)
-        goto loser;
-
-    param = PK11_ParamFromIV(mechanism, &sid->u.ssl2.cipherArg);
-    if (param == NULL)
-        goto loser;
-    readcx = PK11_CreateContextByRawKey(slot, mechanism, PK11_OriginUnwrap,
-                                        CKA_DECRYPT, rk, param,
-                                        ss->pkcs11PinArg);
-    SECITEM_FreeItem(param, PR_TRUE);
-    if (readcx == NULL)
-        goto loser;
-
-    /* build the client context */
-    param = PK11_ParamFromIV(mechanism, &sid->u.ssl2.cipherArg);
-    if (param == NULL)
-        goto loser;
-    writecx = PK11_CreateContextByRawKey(slot, mechanism, PK11_OriginUnwrap,
-                                         CKA_ENCRYPT, wk, param,
-                                         ss->pkcs11PinArg);
-    SECITEM_FreeItem(param, PR_TRUE);
-    if (writecx == NULL)
-        goto loser;
-    PK11_FreeSlot(slot);
-
-    rv = SECSuccess;
-    ss->sec.enc = (SSLCipher)PK11_CipherOp;
-    ss->sec.dec = (SSLCipher)PK11_CipherOp;
-    ss->sec.readcx = (void *)readcx;
-    ss->sec.writecx = (void *)writecx;
-    ss->sec.blockSize = ssl_Specs[cipherType].blockSize;
-    ss->sec.blockShift = ssl_Specs[cipherType].blockShift;
-    ss->sec.cipherType = sid->u.ssl2.cipherType;
-    ss->sec.keyBits = sid->u.ssl2.keyBits;
-    ss->sec.secretKeyBits = sid->u.ssl2.secretKeyBits;
-    goto done;
-
-loser:
-    if (ss->sec.destroy) {
-        if (readcx)
-            (*ss->sec.destroy)(readcx, PR_TRUE);
-        if (writecx)
-            (*ss->sec.destroy)(writecx, PR_TRUE);
-    }
-    ss->sec.destroy = NULL;
-    if (slot)
-        PK11_FreeSlot(slot);
-
-sec_loser:
-    rv = SECFailure;
-
-done:
-    if (rk) {
-        SECITEM_ZfreeItem(rk, PR_FALSE);
-    }
-    if (wk) {
-        SECITEM_ZfreeItem(wk, PR_FALSE);
-    }
-    return rv;
-}
-
-/*
-** Setup the server ciphers given information from a CLIENT-MASTER-KEY
-** message.
-**  "ss"      pointer to the ssl-socket object
-**  "cipher"  the cipher type to use
-**  "keyBits" the size of the final cipher key
-**  "ck"      the clear-key data
-**  "ckLen"   the number of bytes of clear-key data
-**  "ek"      the encrypted-key data
-**  "ekLen"   the number of bytes of encrypted-key data
-**  "ca"      the cipher-arg data
-**  "caLen"   the number of bytes of cipher-arg data
-**
-** The MASTER-KEY is constructed by first decrypting the encrypted-key
-** data. This produces the SECRET-KEY-DATA. The MASTER-KEY is composed by
-** concatenating the clear-key data with the SECRET-KEY-DATA. This code
-** checks to make sure that the client didn't send us an improper amount
-** of SECRET-KEY-DATA (it restricts the length of that data to match the
-** spec).
-**
-** Called from ssl2_HandleClientSessionKeyMessage().
-*/
-static SECStatus
-ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits,
-                              PRUint8 *ck, unsigned int ckLen,
-                              PRUint8 *ek, unsigned int ekLen,
-                              PRUint8 *ca, unsigned int caLen)
-{
-    PRUint8 *dk = NULL; /* decrypted master key */
-    sslSessionID *sid;
-    sslServerCerts *sc = ss->serverCerts + kt_rsa;
-    PRUint8 *kbuf = 0;  /* buffer for RSA decrypted data. */
-    unsigned int ddLen; /* length of RSA decrypted data in kbuf */
-    unsigned int keySize;
-    unsigned int dkLen; /* decrypted key length in bytes */
-    int modulusLen;
-    SECStatus rv;
-    PRUint16 allowed; /* cipher kinds enabled and allowed by policy */
-    PRUint8 mkbuf[SSL_MAX_MASTER_KEY_BYTES];
-
-    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
-    PORT_Assert((sc->SERVERKEY != 0));
-    PORT_Assert((ss->sec.ci.sid != 0));
-    sid = ss->sec.ci.sid;
-
-    /* Trying to cut down on all these switch statements that should be tables.
-     * So, test cipherType once, here, and then use tables below.
-     */
-    switch (cipher) {
-        case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
-        case SSL_CK_RC4_128_WITH_MD5:
-        case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
-        case SSL_CK_RC2_128_CBC_WITH_MD5:
-        case SSL_CK_DES_64_CBC_WITH_MD5:
-        case SSL_CK_DES_192_EDE3_CBC_WITH_MD5:
-            break;
-
-        default:
-            SSL_DBG(("%d: SSL[%d]: ssl2_ServerSetupSessionCypher: unknown cipher=%d",
-                     SSL_GETPID(), ss->fd, cipher));
-            PORT_SetError(SSL_ERROR_BAD_CLIENT);
-            goto loser;
-    }
-
-    allowed = ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED;
-    if (!(allowed & (1 << cipher))) {
-        /* client chose a kind we don't allow! */
-        SSL_DBG(("%d: SSL[%d]: disallowed cipher=%d",
-                 SSL_GETPID(), ss->fd, cipher));
-        PORT_SetError(SSL_ERROR_BAD_CLIENT);
-        goto loser;
-    }
-
-    keySize = ssl_Specs[cipher].keyLen;
-    if (keyBits != keySize * BPB) {
-        SSL_DBG(("%d: SSL[%d]: invalid master secret key length=%d (bits)!",
-                 SSL_GETPID(), ss->fd, keyBits));
-        PORT_SetError(SSL_ERROR_BAD_CLIENT);
-        goto loser;
-    }
-
-    if (ckLen != ssl_Specs[cipher].pubLen) {
-        SSL_DBG(("%d: SSL[%d]: invalid clear key length, ckLen=%d (bytes)!",
-                 SSL_GETPID(), ss->fd, ckLen));
-        PORT_SetError(SSL_ERROR_BAD_CLIENT);
-        goto loser;
-    }
-
-    if (caLen != ssl_Specs[cipher].ivLen) {
-        SSL_DBG(("%d: SSL[%d]: invalid key args length, caLen=%d (bytes)!",
-                 SSL_GETPID(), ss->fd, caLen));
-        PORT_SetError(SSL_ERROR_BAD_CLIENT);
-        goto loser;
-    }
-
-    modulusLen = PK11_GetPrivateModulusLen(sc->SERVERKEY);
-    if (modulusLen < 0) {
-        /* XXX If the key is bad, then PK11_PubDecryptRaw will fail below. */
-        modulusLen = ekLen;
-    }
-    if (ekLen > (unsigned int)modulusLen || ekLen + ckLen < keySize) {
-        SSL_DBG(("%d: SSL[%d]: invalid encrypted key length, ekLen=%d (bytes)!",
-                 SSL_GETPID(), ss->fd, ekLen));
-        PORT_SetError(SSL_ERROR_BAD_CLIENT);
-        goto loser;
-    }
-
-    /* allocate the buffer to hold the decrypted portion of the key. */
-    kbuf = (PRUint8 *)PORT_Alloc(modulusLen);
-    if (!kbuf) {
-        goto loser;
-    }
-    dkLen = keySize - ckLen;
-    dk = kbuf + modulusLen - dkLen;
-
-    /* Decrypt encrypted half of the key.
-    ** NOTE: PK11_PubDecryptRaw will barf on a non-RSA key. This is
-    ** desired behavior here.
-    */
-    rv = PK11_PubDecryptRaw(sc->SERVERKEY, kbuf, &ddLen, modulusLen, ek, ekLen);
-    if (rv != SECSuccess)
-        goto hide_loser;
-
-    /* Is the length of the decrypted data (ddLen) the expected value? */
-    if (modulusLen != ddLen)
-        goto hide_loser;
-
-    /* Cheaply verify that PKCS#1 was used to format the encryption block */
-    if ((kbuf[0] != 0x00) || (kbuf[1] != 0x02) || (dk[-1] != 0x00)) {
-        SSL_DBG(("%d: SSL[%d]: strange encryption block",
-                 SSL_GETPID(), ss->fd));
-        PORT_SetError(SSL_ERROR_BAD_CLIENT);
-        goto hide_loser;
-    }
-
-    /* Make sure we're not subject to a version rollback attack. */
-    if (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
-        static const PRUint8 threes[8] = { 0x03, 0x03, 0x03, 0x03,
-                                           0x03, 0x03, 0x03, 0x03 };
-
-        if (PORT_Memcmp(dk - 8 - 1, threes, 8) == 0) {
-            PORT_SetError(SSL_ERROR_BAD_CLIENT);
-            goto hide_loser;
-        }
-    }
-    if (0) {
-    hide_loser:
-        /* Defense against the Bleichenbacher attack.
-         * Provide the client with NO CLUES that the decrypted master key
-         * was erroneous.  Don't send any error messages.
-         * Instead, Generate a completely bogus master key .
-         */
-        PK11_GenerateRandom(dk, dkLen);
-    }
-
-    /*
-    ** Construct master key out of the pieces.
-    */
-    if (ckLen) {
-        PORT_Memcpy(mkbuf, ck, ckLen);
-    }
-    PORT_Memcpy(mkbuf + ckLen, dk, dkLen);
-
-    /* Fill in session-id */
-    rv = ssl2_FillInSID(sid, cipher, mkbuf, keySize, ca, caLen,
-                        keyBits, keyBits - (ckLen << 3),
-                        ss->sec.authAlgorithm, ss->sec.authKeyBits,
-                        ss->sec.keaType, ss->sec.keaKeyBits);
-    if (rv != SECSuccess) {
-        goto loser;
-    }
-
-    /* Create session ciphers */
-    rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE);
-    if (rv != SECSuccess) {
-        goto loser;
-    }
-
-    SSL_TRC(1, ("%d: SSL[%d]: server, using %s cipher, clear=%d total=%d",
-                SSL_GETPID(), ss->fd, ssl_cipherName[cipher],
-                ckLen << 3, keySize << 3));
-    rv = SECSuccess;
-    goto done;
-
-loser:
-    rv = SECFailure;
-
-done:
-    PORT_Free(kbuf);
-    return rv;
-}
-
-/************************************************************************/
-
-/*
-** Rewrite the incoming cipher specs, comparing to list of specs we support,
-** (ss->cipherSpecs) and eliminating anything we don't support
-**
-*  Note: Our list may contain SSL v3 ciphers.
-*  We MUST NOT match on any of those.
-*  Fortunately, this is easy to detect because SSLv3 ciphers have zero
-*  in the first byte, and none of the SSLv2 ciphers do.
-*
-*  Called from ssl2_HandleClientHelloMessage().
-*  Returns the number of bytes of "qualified cipher specs",
-*  which is typically a multiple of 3, but will be zero if there are none.
-*/
-static int
-ssl2_QualifyCypherSpecs(sslSocket *ss,
-                        PRUint8 *cs, /* cipher specs in client hello msg. */
-                        int csLen)
-{
-    PRUint8 *ms;
-    PRUint8 *hs;
-    PRUint8 *qs;
-    int mc;
-    int hc;
-    PRUint8 qualifiedSpecs[ssl2_NUM_SUITES_IMPLEMENTED * 3];
-
-    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
-
-    if (!ss->cipherSpecs) {
-        SECStatus rv = ssl2_ConstructCipherSpecs(ss);
-        if (rv != SECSuccess || !ss->cipherSpecs)
-            return 0;
-    }
-
-    PRINT_BUF(10, (ss, "specs from client:", cs, csLen));
-    qs = qualifiedSpecs;
-    ms = ss->cipherSpecs;
-    for (mc = ss->sizeCipherSpecs; mc > 0; mc -= 3, ms += 3) {
-        if (ms[0] == 0)
-            continue;
-        for (hs = cs, hc = csLen; hc > 0; hs += 3, hc -= 3) {
-            if ((hs[0] == ms[0]) &&
-                (hs[1] == ms[1]) &&
-                (hs[2] == ms[2])) {
-                /* Copy this cipher spec into the "keep" section */
-                qs[0] = hs[0];
-                qs[1] = hs[1];
-                qs[2] = hs[2];
-                qs += 3;
-                break;
-            }
-        }
-    }
-    hc = qs - qualifiedSpecs;
-    PRINT_BUF(10, (ss, "qualified specs from client:", qualifiedSpecs, hc));
-    PORT_Memcpy(cs, qualifiedSpecs, hc);
-    return hc;
-}
-
-/*
-** Pick the best cipher we can find, given the array of server cipher
-** specs.  Returns cipher number (e.g. SSL_CK_*), or -1 for no overlap.
-** If successful, stores the master key size (bytes) in *pKeyLen.
-**
-** This is correct only for the client side, but presently
-** this function is only called from
-**  ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage()
-**
-** Note that most servers only return a single cipher suite in their
-** ServerHello messages.  So, the code below for finding the "best" cipher
-** suite usually has only one choice.  The client and server should send
-** their cipher suite lists sorted in descending order by preference.
-*/
-static int
-ssl2_ChooseSessionCypher(sslSocket *ss,
-                         int hc,       /* number of cs's in hs. */
-                         PRUint8 *hs,  /* server hello's cipher suites. */
-                         int *pKeyLen) /* out: sym key size in bytes. */
-{
-    PRUint8 *ms;
-    unsigned int i;
-    int bestKeySize;
-    int bestRealKeySize;
-    int bestCypher;
-    int keySize;
-    int realKeySize;
-    PRUint8 *ohs = hs;
-    const PRUint8 *preferred;
-    static const PRUint8 noneSuch[3] = { 0, 0, 0 };
-
-    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
-
-    if (!ss->cipherSpecs) {
-        SECStatus rv = ssl2_ConstructCipherSpecs(ss);
-        if (rv != SECSuccess || !ss->cipherSpecs)
-            goto loser;
-    }
-
-    if (!ss->preferredCipher) {
-        unsigned int allowed = ss->allowedByPolicy & ss->chosenPreference &
-                               SSL_CB_IMPLEMENTED;
-        if (allowed) {
-            preferred = implementedCipherSuites;
-            for (i = ssl2_NUM_SUITES_IMPLEMENTED; i > 0; --i) {
-                if (0 != (allowed & (1U << preferred[0]))) {
-                    ss->preferredCipher = preferred;
-                    break;
-                }
-                preferred += 3;
-            }
-        }
-    }
-    preferred = ss->preferredCipher ? ss->preferredCipher : noneSuch;
-    /*
-    ** Scan list of ciphers received from peer and look for a match in
-    ** our list.
-    *  Note: Our list may contain SSL v3 ciphers.
-    *  We MUST NOT match on any of those.
-    *  Fortunately, this is easy to detect because SSLv3 ciphers have zero
-    *  in the first byte, and none of the SSLv2 ciphers do.
-    */
-    bestKeySize = bestRealKeySize = 0;
-    bestCypher = -1;
-    while (--hc >= 0) {
-        for (i = 0, ms = ss->cipherSpecs; i < ss->sizeCipherSpecs; i += 3, ms += 3) {
-            if ((hs[0] == preferred[0]) &&
-                (hs[1] == preferred[1]) &&
-                (hs[2] == preferred[2]) &&
-                hs[0] != 0) {
-                /* Pick this cipher immediately! */
-                *pKeyLen = (((hs[1] << 8) | hs[2]) + 7) >> 3;
-                return hs[0];
-            }
-            if ((hs[0] == ms[0]) && (hs[1] == ms[1]) && (hs[2] == ms[2]) &&
-                hs[0] != 0) {
-                /* Found a match */
-
-                /* Use secret keySize to determine which cipher is best */
-                realKeySize = (hs[1] << 8) | hs[2];
-                switch (hs[0]) {
-                    case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
-                    case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
-                        keySize = 40;
-                        break;
-                    default:
-                        keySize = realKeySize;
-                        break;
-                }
-                if (keySize > bestKeySize) {
-                    bestCypher = hs[0];
-                    bestKeySize = keySize;
-                    bestRealKeySize = realKeySize;
-                }
-            }
-        }
-        hs += 3;
-    }
-    if (bestCypher < 0) {
-        /*
-        ** No overlap between server and client. Re-examine server list
-        ** to see what kind of ciphers it does support so that we can set
-        ** the error code appropriately.
-        */
-        if ((ohs[0] == SSL_CK_RC4_128_WITH_MD5) ||
-            (ohs[0] == SSL_CK_RC2_128_CBC_WITH_MD5)) {
-            PORT_SetError(SSL_ERROR_US_ONLY_SERVER);
-        } else if ((ohs[0] == SSL_CK_RC4_128_EXPORT40_WITH_MD5) ||
-                   (ohs[0] == SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5)) {
-            PORT_SetError(SSL_ERROR_EXPORT_ONLY_SERVER);
-        } else {
-            PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
-        }
-        SSL_DBG(("%d: SSL[%d]: no cipher overlap", SSL_GETPID(), ss->fd));
-        goto loser;
-    }
-    *pKeyLen = (bestRealKeySize + 7) >> 3;
-    return bestCypher;
-
-loser:
-    return -1;
-}
-
-static SECStatus
-ssl2_ClientHandleServerCert(sslSocket *ss, PRUint8 *certData, int certLen)
-{
-    CERTCertificate *cert = NULL;
-    SECItem certItem;
-
-    certItem.data = certData;
-    certItem.len = certLen;
-
-    /* decode the certificate */
-    cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
-                                   PR_FALSE, PR_TRUE);
-
-    if (cert == NULL) {
-        SSL_DBG(("%d: SSL[%d]: decode of server certificate fails",
-                 SSL_GETPID(), ss->fd));
-        PORT_SetError(SSL_ERROR_BAD_CERTIFICATE);
-        return SECFailure;
-    }
-
-#ifdef TRACE
-    {
-        if (ssl_trace >= 1) {
-            char *issuer;
-            char *subject;
-            issuer = CERT_NameToAscii(&cert->issuer);
-            subject = CERT_NameToAscii(&cert->subject);
-            SSL_TRC(1, ("%d: server certificate issuer: '%s'",
-                        SSL_GETPID(), issuer ? issuer : "OOPS"));
-            SSL_TRC(1, ("%d: server name: '%s'",
-                        SSL_GETPID(), subject ? subject : "OOPS"));
-            PORT_Free(issuer);
-            PORT_Free(subject);
-        }
-    }
-#endif
-
-    ss->sec.peerCert = cert;
+    ss->handshake = NULL;
     return SECSuccess;
 }
 
-/*
- * Format one block of data for public/private key encryption using
- * the rules defined in PKCS #1. SSL2 does this itself to handle the
- * rollback detection.
- */
-#define RSA_BLOCK_MIN_PAD_LEN 8
-#define RSA_BLOCK_FIRST_OCTET 0x00
-#define RSA_BLOCK_AFTER_PAD_OCTET 0x00
-#define RSA_BLOCK_PUBLIC_OCTET 0x02
-unsigned char *
-ssl_FormatSSL2Block(unsigned modulusLen, SECItem *data)
-{
-    unsigned char *block;
-    unsigned char *bp;
-    int padLen;
-    SECStatus rv;
-    int i;
-
-    if (modulusLen < data->len + (3 + RSA_BLOCK_MIN_PAD_LEN)) {
-        PORT_SetError(SEC_ERROR_BAD_KEY);
-        return NULL;
-    }
-    block = (unsigned char *)PORT_Alloc(modulusLen);
-    if (block == NULL)
-        return NULL;
-
-    bp = block;
-
-    /*
-     * All RSA blocks start with two octets:
-     *  0x00 || BlockType
-     */
-    *bp++ = RSA_BLOCK_FIRST_OCTET;
-    *bp++ = RSA_BLOCK_PUBLIC_OCTET;
-
-    /*
-     * 0x00 || BT || Pad || 0x00 || ActualData
-     *   1      1   padLen    1      data->len
-     * Pad is all non-zero random bytes.
-     */
-    padLen = modulusLen - data->len - 3;
-    PORT_Assert(padLen >= RSA_BLOCK_MIN_PAD_LEN);
-    rv = PK11_GenerateRandom(bp, padLen);
-    if (rv == SECFailure)
-        goto loser;
-    /* replace all the 'zero' bytes */
-    for (i = 0; i < padLen; i++) {
-        while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET) {
-            rv = PK11_GenerateRandom(bp + i, 1);
-            if (rv == SECFailure)
-                goto loser;
-        }
-    }
-    bp += padLen;
-    *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
-    PORT_Memcpy(bp, data->data, data->len);
-
-    return block;
-loser:
-    if (block)
-        PORT_Free(block);
-    return NULL;
-}
-
-/*
-** Given the server's public key and cipher specs, generate a session key
-** that is ready to use for encrypting/decrypting the byte stream. At
-** the same time, generate the SSL_MT_CLIENT_MASTER_KEY message and
-** send it to the server.
-**
-** Called from ssl2_HandleServerHelloMessage()
-*/
+/* This function is called at the beginning of a handshake to ensure that at
+ * least one SSL/TLS version is enabled. */
 static SECStatus
-ssl2_ClientSetupSessionCypher(sslSocket *ss, PRUint8 *cs, int csLen)
+ssl_CheckConfigSanity(sslSocket *ss)
 {
-    sslSessionID *sid;
-    PRUint8 *ca; /* points to iv data, or NULL if none. */
-    PRUint8 *ekbuf = 0;
-    CERTCertificate *cert = 0;
-    SECKEYPublicKey *serverKey = 0;
-    unsigned modulusLen = 0;
-    SECStatus rv;
-    int cipher;
-    int keyLen; /* cipher symkey size in bytes. */
-    int ckLen;  /* publicly reveal this many bytes of key. */
-    int caLen;  /* length of IV data at *ca.    */
-    int nc;
-
-    unsigned char *eblock; /* holds unencrypted PKCS#1 formatted key. */
-    SECItem rek;           /* holds portion of symkey to be encrypted. */
-
-    PRUint8 keyData[SSL_MAX_MASTER_KEY_BYTES];
-    PRUint8 iv[8];
-
-    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-
-    eblock = NULL;
-
-    sid = ss->sec.ci.sid;
-    PORT_Assert(sid != 0);
-
-    cert = ss->sec.peerCert;
-
-    serverKey = CERT_ExtractPublicKey(cert);
-    if (!serverKey) {
-        SSL_DBG(("%d: SSL[%d]: extract public key failed: error=%d",
-                 SSL_GETPID(), ss->fd, PORT_GetError()));
-        PORT_SetError(SSL_ERROR_BAD_CERTIFICATE);
-        rv = SECFailure;
-        goto loser2;
-    }
-
-    ss->sec.authAlgorithm = ssl_sign_rsa;
-    ss->sec.keaType = ssl_kea_rsa;
-    ss->sec.keaKeyBits =
-        ss->sec.authKeyBits = SECKEY_PublicKeyStrengthInBits(serverKey);
-
-    /* Choose a compatible cipher with the server */
-    nc = csLen / 3;
-    cipher = ssl2_ChooseSessionCypher(ss, nc, cs, &keyLen);
-    if (cipher < 0) {
-        /* ssl2_ChooseSessionCypher has set error code. */
-        ssl2_SendErrorMessage(ss, SSL_PE_NO_CYPHERS);
-        goto loser;
-    }
-
-    /* Generate the random keys */
-    PK11_GenerateRandom(keyData, sizeof(keyData));
-
-    /*
-    ** Next, carve up the keys into clear and encrypted portions. The
-    ** clear data is taken from the start of keyData and the encrypted
-    ** portion from the remainder. Note that each of these portions is
-    ** carved in half, one half for the read-key and one for the
-    ** write-key.
-    */
-    ca = 0;
-
-    /* We know that cipher is a legit value here, because
-     * ssl2_ChooseSessionCypher doesn't return bogus values.
-     */
-    ckLen = ssl_Specs[cipher].pubLen; /* cleartext key length. */
-    caLen = ssl_Specs[cipher].ivLen;  /* IV length.     */
-    if (caLen) {
-        PORT_Assert(sizeof iv >= caLen);
-        PK11_GenerateRandom(iv, caLen);
-        ca = iv;
-    }
-
-    /* Fill in session-id */
-    rv = ssl2_FillInSID(sid, cipher, keyData, keyLen,
-                        ca, caLen, keyLen << 3, (keyLen - ckLen) << 3,
-                        ss->sec.authAlgorithm, ss->sec.authKeyBits,
-                        ss->sec.keaType, ss->sec.keaKeyBits);
-    if (rv != SECSuccess) {
-        goto loser;
-    }
-
-    SSL_TRC(1, ("%d: SSL[%d]: client, using %s cipher, clear=%d total=%d",
-                SSL_GETPID(), ss->fd, ssl_cipherName[cipher],
-                ckLen << 3, keyLen << 3));
-
-    /* Now setup read and write ciphers */
-    rv = ssl2_CreateSessionCypher(ss, sid, PR_TRUE);
-    if (rv != SECSuccess) {
-        goto loser;
-    }
-
-    /*
-    ** Fill in the encryption buffer with some random bytes. Then
-    ** copy in the portion of the session key we are encrypting.
-    */
-    modulusLen = SECKEY_PublicKeyStrength(serverKey);
-    rek.data = keyData + ckLen;
-    rek.len = keyLen - ckLen;
-    eblock = ssl_FormatSSL2Block(modulusLen, &rek);
-    if (eblock == NULL)
-        goto loser;
-
-    /* Set up the padding for version 2 rollback detection. */
-    /* XXX We should really use defines here */
-    if (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
-        PORT_Assert((modulusLen - rek.len) > 12);
-        PORT_Memset(eblock + modulusLen - rek.len - 8 - 1, 0x03, 8);
-    }
-    ekbuf = (PRUint8 *)PORT_Alloc(modulusLen);
-    if (!ekbuf)
-        goto loser;
-    PRINT_BUF(10, (ss, "master key encryption block:",
-                   eblock, modulusLen));
-
-    /* Encrypt ekitem */
-    rv = PK11_PubEncryptRaw(serverKey, ekbuf, eblock, modulusLen,
-                            ss->pkcs11PinArg);
-    if (rv)
-        goto loser;
-
-    /*  Now we have everything ready to send */
-    rv = ssl2_SendSessionKeyMessage(ss, cipher, keyLen << 3, ca, caLen,
-                                    keyData, ckLen, ekbuf, modulusLen);
-    if (rv != SECSuccess) {
-        goto loser;
-    }
-    rv = SECSuccess;
-    goto done;
-
-loser:
-    rv = SECFailure;
-
-loser2:
-done:
-    PORT_Memset(keyData, 0, sizeof(keyData));
-    PORT_ZFree(ekbuf, modulusLen);
-    PORT_ZFree(eblock, modulusLen);
-    SECKEY_DestroyPublicKey(serverKey);
-    return rv;
-}
-
-/************************************************************************/
-
-/*
- * Called from ssl2_HandleMessage in response to SSL_MT_SERVER_FINISHED message.
- * Caller holds recvBufLock and handshakeLock
- */
-static void
-ssl2_ClientRegSessionID(sslSocket *ss, PRUint8 *s)
-{
-    sslSessionID *sid = ss->sec.ci.sid;
-
-    /* Record entry in nonce cache */
-    if (sid->peerCert == NULL) {
-        PORT_Memcpy(sid->u.ssl2.sessionID, s, sizeof(sid->u.ssl2.sessionID));
-        sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
-    }
-    if (!ss->opt.noCache && sid->cached == never_cached)
-        (*ss->sec.cache)(sid);
-}
-
-/* Called from ssl2_HandleMessage() */
-static SECStatus
-ssl2_TriggerNextMessage(sslSocket *ss)
-{
-    SECStatus rv;
-
-    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-
-    if ((ss->sec.ci.requiredElements & CIS_HAVE_CERTIFICATE) &&
-        !(ss->sec.ci.sentElements & CIS_HAVE_CERTIFICATE)) {
-        ss->sec.ci.sentElements |= CIS_HAVE_CERTIFICATE;
-        rv = ssl2_SendCertificateRequestMessage(ss);
-        return rv;
-    }
-    return SECSuccess;
-}
-
-/* See if it's time to send our finished message, or if the handshakes are
-** complete.  Send finished message if appropriate.
-** Returns SECSuccess unless anything goes wrong.
-**
-** Called from ssl2_HandleMessage,
-**             ssl2_HandleVerifyMessage
-**             ssl2_HandleServerHelloMessage
-**             ssl2_HandleClientSessionKeyMessage
-*/
-static SECStatus
-ssl2_TryToFinish(sslSocket *ss)
-{
-    SECStatus rv;
-    char e, ef;
-
-    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-
-    e = ss->sec.ci.elements;
-    ef = e | CIS_HAVE_FINISHED;
-    if ((ef & ss->sec.ci.requiredElements) == ss->sec.ci.requiredElements) {
-        if (ss->sec.isServer) {
-            /* Send server finished message if we already didn't */
-            rv = ssl2_SendServerFinishedMessage(ss);
-        } else {
-            /* Send client finished message if we already didn't */
-            rv = ssl2_SendClientFinishedMessage(ss);
-        }
-        if (rv != SECSuccess) {
-            return rv;
-        }
-        if ((e & ss->sec.ci.requiredElements) == ss->sec.ci.requiredElements) {
-            /* Totally finished */
-            ss->handshake = 0;
-            return SECSuccess;
-        }
+    if (SSL_ALL_VERSIONS_DISABLED(&ss->vrange)) {
+        SSL_DBG(("%d: SSL[%d]: Can't handshake! all versions disabled.",
+                 SSL_GETPID(), ss->fd));
+        PORT_SetError(SSL_ERROR_SSL_DISABLED);
+        return SECFailure;
     }
     return SECSuccess;
 }
 
-/*
-** Called from ssl2_HandleRequestCertificate
-*/
-static SECStatus
-ssl2_SignResponse(sslSocket *ss,
-                  SECKEYPrivateKey *key,
-                  SECItem *response)
-{
-    SGNContext *sgn = NULL;
-    PRUint8 *challenge;
-    unsigned int len;
-    SECStatus rv = SECFailure;
-
-    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-
-    challenge = ss->sec.ci.serverChallenge;
-    len = ss->sec.ci.serverChallengeLen;
-
-    /* Sign the expected data... */
-    sgn = SGN_NewContext(SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION, key);
-    if (!sgn)
-        goto done;
-    rv = SGN_Begin(sgn);
-    if (rv != SECSuccess)
-        goto done;
-    rv = SGN_Update(sgn, ss->sec.ci.readKey, ss->sec.ci.keySize);
-    if (rv != SECSuccess)
-        goto done;
-    rv = SGN_Update(sgn, ss->sec.ci.writeKey, ss->sec.ci.keySize);
-    if (rv != SECSuccess)
-        goto done;
-    rv = SGN_Update(sgn, challenge, len);
-    if (rv != SECSuccess)
-        goto done;
-    rv = SGN_Update(sgn, ss->sec.peerCert->derCert.data,
-                    ss->sec.peerCert->derCert.len);
-    if (rv != SECSuccess)
-        goto done;
-    rv = SGN_End(sgn, response);
-    if (rv != SECSuccess)
-        goto done;
-
-done:
-    SGN_DestroyContext(sgn, PR_TRUE);
-    return rv == SECSuccess ? SECSuccess : SECFailure;
-}
-
-/*
-** Try to handle a request-certificate message. Get client's certificate
-** and private key and sign a message for the server to see.
-** Caller must hold handshakeLock
-**
-** Called from ssl2_HandleMessage().
-*/
-static int
-ssl2_HandleRequestCertificate(sslSocket *ss)
-{
-    CERTCertificate *cert = NULL; /* app-selected client cert. */
-    SECKEYPrivateKey *key = NULL; /* priv key for cert. */
-    SECStatus rv;
-    SECItem response;
-    int ret = 0;
-    PRUint8 authType;
-
-    /*
-     * These things all need to be initialized before we can "goto loser".
-     */
-    response.data = NULL;
-
-    /* get challenge info from connectionInfo */
-    authType = ss->sec.ci.authType;
-
-    if (authType != SSL_AT_MD5_WITH_RSA_ENCRYPTION) {
-        SSL_TRC(7, ("%d: SSL[%d]: unsupported auth type 0x%x", SSL_GETPID(),
-                    ss->fd, authType));
-        goto no_cert_error;
-    }
-
-    /* Get certificate and private-key from client */
-    if (!ss->getClientAuthData) {
-        SSL_TRC(7, ("%d: SSL[%d]: client doesn't support client-auth",
-                    SSL_GETPID(), ss->fd));
-        goto no_cert_error;
-    }
-    ret = (*ss->getClientAuthData)(ss->getClientAuthDataArg, ss->fd,
-                                   NULL, &cert, &key);
-    if (ret == SECWouldBlock) {
-        PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
-        ret = -1;
-        goto loser;
-    }
-
-    if (ret) {
-        goto no_cert_error;
-    }
-
-    /* check what the callback function returned */
-    if ((!cert) || (!key)) {
-        /* we are missing either the key or cert */
-        if (cert) {
-            /* got a cert, but no key - free it */
-            CERT_DestroyCertificate(cert);
-            cert = NULL;
-        }
-        if (key) {
-            /* got a key, but no cert - free it */
-            SECKEY_DestroyPrivateKey(key);
-            key = NULL;
-        }
-        goto no_cert_error;
-    }
-
-    rv = ssl2_SignResponse(ss, key, &response);
-    if (rv != SECSuccess) {
-        ret = -1;
-        goto loser;
-    }
-
-    /* Send response message */
-    ret = ssl2_SendCertificateResponseMessage(ss, &cert->derCert, &response);
-
-    /* Now, remember the cert we sent. But first, forget any previous one. */
-    if (ss->sec.localCert) {
-        CERT_DestroyCertificate(ss->sec.localCert);
-    }
-    ss->sec.localCert = CERT_DupCertificate(cert);
-    PORT_Assert(!ss->sec.ci.sid->localCert);
-    if (ss->sec.ci.sid->localCert) {
-        CERT_DestroyCertificate(ss->sec.ci.sid->localCert);
-    }
-    ss->sec.ci.sid->localCert = cert;
-    cert = NULL;
-
-    goto done;
-
-no_cert_error:
-    SSL_TRC(7, ("%d: SSL[%d]: no certificate (ret=%d)", SSL_GETPID(),
-                ss->fd, ret));
-    ret = ssl2_SendErrorMessage(ss, SSL_PE_NO_CERTIFICATE);
-
-loser:
-done:
-    if (cert) {
-        CERT_DestroyCertificate(cert);
-    }
-    if (key) {
-        SECKEY_DestroyPrivateKey(key);
-    }
-    if (response.data) {
-        PORT_Free(response.data);
-    }
-
-    return ret;
-}
-
-/*
-** Called from ssl2_HandleMessage for SSL_MT_CLIENT_CERTIFICATE message.
-** Caller must hold HandshakeLock and RecvBufLock, since cd and response
-** are contained in the gathered input data.
-*/
-static SECStatus
-ssl2_HandleClientCertificate(sslSocket *ss,
-                             PRUint8 certType, /* XXX unused */
-                             PRUint8 *cd,
-                             unsigned int cdLen,
-                             PRUint8 *response,
-                             unsigned int responseLen)
-{
-    CERTCertificate *cert = NULL;
-    SECKEYPublicKey *pubKey = NULL;
-    VFYContext *vfy = NULL;
-    SECItem *derCert;
-    SECStatus rv = SECFailure;
-    SECItem certItem;
-    SECItem rep;
-
-    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
-
-    /* Extract the certificate */
-    certItem.data = cd;
-    certItem.len = cdLen;
-
-    cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
-                                   PR_FALSE, PR_TRUE);
-    if (cert == NULL) {
-        goto loser;
-    }
-
-    /* save the certificate, since the auth routine will need it */
-    ss->sec.peerCert = cert;
-
-    /* Extract the public key */
-    pubKey = CERT_ExtractPublicKey(cert);
-    if (!pubKey)
-        goto loser;
-
-    /* Verify the response data... */
-    rep.data = response;
-    rep.len = responseLen;
-    /* SSL 2.0 only supports RSA certs, so we don't have to worry about
-     * DSA here. */
-    vfy = VFY_CreateContext(pubKey, &rep, SEC_OID_PKCS1_RSA_ENCRYPTION,
-                            ss->pkcs11PinArg);
-    if (!vfy)
-        goto loser;
-    rv = VFY_Begin(vfy);
-    if (rv)
-        goto loser;
-
-    rv = VFY_Update(vfy, ss->sec.ci.readKey, ss->sec.ci.keySize);
-    if (rv)
-        goto loser;
-    rv = VFY_Update(vfy, ss->sec.ci.writeKey, ss->sec.ci.keySize);
-    if (rv)
-        goto loser;
-    rv = VFY_Update(vfy, ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES);
-    if (rv)
-        goto loser;
-
-    derCert = &ss->serverCerts[kt_rsa].serverCert->derCert;
-    rv = VFY_Update(vfy, derCert->data, derCert->len);
-    if (rv)
-        goto loser;
-    rv = VFY_End(vfy);
-    if (rv)
-        goto loser;
-
-    /* Now ask the server application if it likes the certificate... */
-    rv = (SECStatus)(*ss->authCertificate)(ss->authCertificateArg,
-                                           ss->fd, PR_TRUE, PR_TRUE);
-    /* Hey, it liked it. */
-    if (SECSuccess == rv)
-        goto done;
-
-loser:
-    ss->sec.peerCert = NULL;
-    CERT_DestroyCertificate(cert);
-
-done:
-    VFY_DestroyContext(vfy, PR_TRUE);
-    SECKEY_DestroyPublicKey(pubKey);
-    return rv;
-}
-
-/*
-** Handle remaining messages between client/server. Process finished
-** messages from either side and any authentication requests.
-** This should only be called for SSLv2 handshake messages,
-** not for application data records.
-** Caller must hold handshake lock.
-**
-** Called from ssl_Do1stHandshake().
-**
-*/
-static SECStatus
-ssl2_HandleMessage(sslSocket *ss)
-{
-    PRUint8 *data;
-    PRUint8 *cid;
-    unsigned len, certType, certLen, responseLen;
-    int rv;
-
-    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-
-    ssl_GetRecvBufLock(ss);
-
-    data = ss->gs.buf.buf + ss->gs.recordOffset;
-
-    if (ss->gs.recordLen < 1) {
-        goto bad_peer;
-    }
-    SSL_TRC(3, ("%d: SSL[%d]: received %d message",
-                SSL_GETPID(), ss->fd, data[0]));
-    DUMP_MSG(29, (ss, data, ss->gs.recordLen));
-
-    switch (data[0]) {
-        case SSL_MT_CLIENT_FINISHED:
-            if (ss->sec.ci.elements & CIS_HAVE_FINISHED) {
-                SSL_DBG(("%d: SSL[%d]: dup client-finished message",
-                         SSL_GETPID(), ss->fd));
-                goto bad_peer;
-            }
-
-            /* See if nonce matches */
-            len = ss->gs.recordLen - 1;
-            cid = data + 1;
-            if ((len != sizeof(ss->sec.ci.connectionID)) ||
-                (PORT_Memcmp(ss->sec.ci.connectionID, cid, len) != 0)) {
-                SSL_DBG(("%d: SSL[%d]: bad connection-id", SSL_GETPID(), ss->fd));
-                PRINT_BUF(5, (ss, "sent connection-id",
-                              ss->sec.ci.connectionID,
-                              sizeof(ss->sec.ci.connectionID)));
-                PRINT_BUF(5, (ss, "rcvd connection-id", cid, len));
-                goto bad_peer;
-            }
-
-            SSL_TRC(5, ("%d: SSL[%d]: got client finished, waiting for 0x%d",
-                        SSL_GETPID(), ss->fd,
-                        ss->sec.ci.requiredElements ^ ss->sec.ci.elements));
-            ss->sec.ci.elements |= CIS_HAVE_FINISHED;
-            break;
-
-        case SSL_MT_SERVER_FINISHED:
-            if (ss->sec.ci.elements & CIS_HAVE_FINISHED) {
-                SSL_DBG(("%d: SSL[%d]: dup server-finished message",
-                         SSL_GETPID(), ss->fd));
-                goto bad_peer;
-            }
-
-            if (ss->gs.recordLen - 1 != SSL2_SESSIONID_BYTES) {
-                SSL_DBG(("%d: SSL[%d]: bad server-finished message, len=%d",
-                         SSL_GETPID(), ss->fd, ss->gs.recordLen));
-                goto bad_peer;
-            }
-            ssl2_ClientRegSessionID(ss, data + 1);
-            SSL_TRC(5, ("%d: SSL[%d]: got server finished, waiting for 0x%d",
-                        SSL_GETPID(), ss->fd,
-                        ss->sec.ci.requiredElements ^ ss->sec.ci.elements));
-            ss->sec.ci.elements |= CIS_HAVE_FINISHED;
-            break;
-
-        case SSL_MT_REQUEST_CERTIFICATE:
-            len = ss->gs.recordLen - 2;
-            if ((len < SSL_MIN_CHALLENGE_BYTES) ||
-                (len > SSL_MAX_CHALLENGE_BYTES)) {
-                /* Bad challenge */
-                SSL_DBG(("%d: SSL[%d]: bad cert request message: code len=%d",
-                         SSL_GETPID(), ss->fd, len));
-                goto bad_peer;
-            }
-
-            /* save auth request info */
-            ss->sec.ci.authType = data[1];
-            ss->sec.ci.serverChallengeLen = len;
-            PORT_Memcpy(ss->sec.ci.serverChallenge, data + 2, len);
-
-            rv = ssl2_HandleRequestCertificate(ss);
-            if (rv == SECWouldBlock) {
-                SSL_TRC(3, ("%d: SSL[%d]: async cert request",
-                            SSL_GETPID(), ss->fd));
-                /* someone is handling this asynchronously */
-                ssl_ReleaseRecvBufLock(ss);
-                return SECWouldBlock;
-            }
-            if (rv) {
-                SET_ERROR_CODE
-                goto loser;
-            }
-            break;
-
-        case SSL_MT_CLIENT_CERTIFICATE:
-            if (!ss->authCertificate) {
-                /* Server asked for authentication and can't handle it */
-                PORT_SetError(SSL_ERROR_BAD_SERVER);
-                goto loser;
-            }
-            if (ss->gs.recordLen < SSL_HL_CLIENT_CERTIFICATE_HBYTES) {
-                SET_ERROR_CODE
-                goto loser;
-            }
-            certType = data[1];
-            certLen = (data[2] << 8) | data[3];
-            responseLen = (data[4] << 8) | data[5];
-            if (certType != SSL_CT_X509_CERTIFICATE) {
-                PORT_SetError(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
-                goto loser;
-            }
-            if (certLen + responseLen + SSL_HL_CLIENT_CERTIFICATE_HBYTES >
-                ss->gs.recordLen) {
-                /* prevent overflow crash. */
-                rv = SECFailure;
-            } else
-                rv = ssl2_HandleClientCertificate(ss, data[1],
-                                                  data + SSL_HL_CLIENT_CERTIFICATE_HBYTES,
-                                                  certLen,
-                                                  data + SSL_HL_CLIENT_CERTIFICATE_HBYTES + certLen,
-                                                  responseLen);
-            if (rv) {
-                (void)ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
-                SET_ERROR_CODE
-                goto loser;
-            }
-            ss->sec.ci.elements |= CIS_HAVE_CERTIFICATE;
-            break;
-
-        case SSL_MT_ERROR:
-            rv = (data[1] << 8) | data[2];
-            SSL_TRC(2, ("%d: SSL[%d]: got error message, error=0x%x",
-                        SSL_GETPID(), ss->fd, rv));
-
-            /* Convert protocol error number into API error number */
-            switch (rv) {
-                case SSL_PE_NO_CYPHERS:
-                    rv = SSL_ERROR_NO_CYPHER_OVERLAP;
-                    break;
-                case SSL_PE_NO_CERTIFICATE:
-                    rv = SSL_ERROR_NO_CERTIFICATE;
-                    break;
-                case SSL_PE_BAD_CERTIFICATE:
-                    rv = SSL_ERROR_BAD_CERTIFICATE;
-                    break;
-                case SSL_PE_UNSUPPORTED_CERTIFICATE_TYPE:
-                    rv = SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE;
-                    break;
-                default:
-                    goto bad_peer;
-            }
-            /* XXX make certificate-request optionally fail... */
-            PORT_SetError(rv);
-            goto loser;
-
-        default:
-            SSL_DBG(("%d: SSL[%d]: unknown message %d",
-                     SSL_GETPID(), ss->fd, data[0]));
-            goto loser;
-    }
-
-    SSL_TRC(3, ("%d: SSL[%d]: handled %d message, required=0x%x got=0x%x",
-                SSL_GETPID(), ss->fd, data[0],
-                ss->sec.ci.requiredElements, ss->sec.ci.elements));
-
-    rv = ssl2_TryToFinish(ss);
-    if (rv != SECSuccess)
-        goto loser;
-
-    ss->gs.recordLen = 0;
-    ssl_ReleaseRecvBufLock(ss);
-
-    if (ss->handshake == 0) {
-        return SECSuccess;
-    }
-
-    ss->handshake = ssl_GatherRecord1stHandshake;
-    ss->nextHandshake = ssl2_HandleMessage;
-    return ssl2_TriggerNextMessage(ss);
-
-bad_peer:
-    PORT_SetError(ss->sec.isServer ? SSL_ERROR_BAD_CLIENT : SSL_ERROR_BAD_SERVER);
-/* FALL THROUGH */
-
-loser:
-    ssl_ReleaseRecvBufLock(ss);
-    return SECFailure;
-}
-
-/************************************************************************/
-
-/* Called from ssl_Do1stHandshake, after ssl2_HandleServerHelloMessage.
-*/
-static SECStatus
-ssl2_HandleVerifyMessage(sslSocket *ss)
-{
-    PRUint8 *data;
-    SECStatus rv;
-
-    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-    ssl_GetRecvBufLock(ss);
-
-    data = ss->gs.buf.buf + ss->gs.recordOffset;
-    DUMP_MSG(29, (ss, data, ss->gs.recordLen));
-    if ((ss->gs.recordLen != 1 + SSL_CHALLENGE_BYTES) ||
-        (data[0] != SSL_MT_SERVER_VERIFY) ||
-        NSS_SecureMemcmp(data + 1, ss->sec.ci.clientChallenge,
-                         SSL_CHALLENGE_BYTES)) {
-        /* Bad server */
-        PORT_SetError(SSL_ERROR_BAD_SERVER);
-        goto loser;
-    }
-    ss->sec.ci.elements |= CIS_HAVE_VERIFY;
-
-    SSL_TRC(5, ("%d: SSL[%d]: got server-verify, required=0x%d got=0x%x",
-                SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements,
-                ss->sec.ci.elements));
-
-    rv = ssl2_TryToFinish(ss);
-    if (rv)
-        goto loser;
-
-    ss->gs.recordLen = 0;
-    ssl_ReleaseRecvBufLock(ss);
-
-    if (ss->handshake == 0) {
-        return SECSuccess;
-    }
-    ss->handshake = ssl_GatherRecord1stHandshake;
-    ss->nextHandshake = ssl2_HandleMessage;
-    return SECSuccess;
-
-loser:
-    ssl_ReleaseRecvBufLock(ss);
-    return SECFailure;
-}
-
-/* Not static because ssl2_GatherData() tests ss->nextHandshake for this value.
- * ICK!
- * Called from ssl_Do1stHandshake after ssl2_BeginClientHandshake()
- */
-SECStatus
-ssl2_HandleServerHelloMessage(sslSocket *ss)
-{
-    sslSessionID *sid;
-    PRUint8 *cert;
-    PRUint8 *cs;
-    PRUint8 *data;
-    SECStatus rv;
-    unsigned int needed, sidHit, certLen, csLen, cidLen, certType, err;
-
-    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-
-    if (!ss->opt.enableSSL2) {
-        PORT_SetError(SSL_ERROR_SSL2_DISABLED);
-        return SECFailure;
-    }
-
-    ssl_GetRecvBufLock(ss);
-
-    PORT_Assert(ss->sec.ci.sid != 0);
-    sid = ss->sec.ci.sid;
-
-    data = ss->gs.buf.buf + ss->gs.recordOffset;
-    DUMP_MSG(29, (ss, data, ss->gs.recordLen));
-
-    /* Make sure first message has some data and is the server hello message */
-    if ((ss->gs.recordLen < SSL_HL_SERVER_HELLO_HBYTES) ||
-        (data[0] != SSL_MT_SERVER_HELLO)) {
-        if ((data[0] == SSL_MT_ERROR) && (ss->gs.recordLen == 3)) {
-            err = (data[1] << 8) | data[2];
-            if (err == SSL_PE_NO_CYPHERS) {
-                PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
-                goto loser;
-            }
-        }
-        goto bad_server;
-    }
-
-    sidHit = data[1];
-    certType = data[2];
-    ss->version = (data[3] << 8) | data[4];
-    certLen = (data[5] << 8) | data[6];
-    csLen = (data[7] << 8) | data[8];
-    cidLen = (data[9] << 8) | data[10];
-    cert = data + SSL_HL_SERVER_HELLO_HBYTES;
-    cs = cert + certLen;
-
-    SSL_TRC(5,
-            ("%d: SSL[%d]: server-hello, hit=%d vers=%x certLen=%d csLen=%d cidLen=%d",
-             SSL_GETPID(), ss->fd, sidHit, ss->version, certLen,
-             csLen, cidLen));
-    if (ss->version != SSL_LIBRARY_VERSION_2) {
-        if (ss->version < SSL_LIBRARY_VERSION_2) {
-            SSL_TRC(3, ("%d: SSL[%d]: demoting self (%x) to server version (%x)",
-                        SSL_GETPID(), ss->fd, SSL_LIBRARY_VERSION_2,
-                        ss->version));
-        } else {
-            SSL_TRC(1, ("%d: SSL[%d]: server version is %x (we are %x)",
-                        SSL_GETPID(), ss->fd, ss->version, SSL_LIBRARY_VERSION_2));
-            /* server claims to be newer but does not follow protocol */
-            PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
-            goto loser;
-        }
-    }
-
-    if ((SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen + cidLen >
-         ss->gs.recordLen) ||
-        (csLen % 3) != 0
-        /* || cidLen < SSL_CONNECTIONID_BYTES || cidLen > 32  */
-        ) {
-        goto bad_server;
-    }
-
-    /* Save connection-id.
-    ** This code only saves the first 16 byte of the connectionID.
-    ** If the connectionID is shorter than 16 bytes, it is zero-padded.
-    */
-    if (cidLen < sizeof ss->sec.ci.connectionID)
-        memset(ss->sec.ci.connectionID, 0, sizeof ss->sec.ci.connectionID);
-    cidLen = PR_MIN(cidLen, sizeof ss->sec.ci.connectionID);
-    PORT_Memcpy(ss->sec.ci.connectionID, cs + csLen, cidLen);
-
-    /* See if session-id hit */
-    needed = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED | CIS_HAVE_VERIFY;
-    if (sidHit) {
-        if (certLen || csLen) {
-            /* Uh oh - bogus server */
-            SSL_DBG(("%d: SSL[%d]: client, huh? hit=%d certLen=%d csLen=%d",
-                     SSL_GETPID(), ss->fd, sidHit, certLen, csLen));
-            goto bad_server;
-        }
-
-        /* Total winner. */
-        SSL_TRC(1, ("%d: SSL[%d]: client, using nonce for peer=0x%08x "
-                    "port=0x%04x",
-                    SSL_GETPID(), ss->fd, ss->sec.ci.peer, ss->sec.ci.port));
-        ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
-        ss->sec.authAlgorithm = sid->authAlgorithm;
-        ss->sec.authKeyBits = sid->authKeyBits;
-        ss->sec.keaType = sid->keaType;
-        ss->sec.keaKeyBits = sid->keaKeyBits;
-        rv = ssl2_CreateSessionCypher(ss, sid, PR_TRUE);
-        if (rv != SECSuccess) {
-            goto loser;
-        }
-    } else {
-        if (certType != SSL_CT_X509_CERTIFICATE) {
-            PORT_SetError(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
-            goto loser;
-        }
-        if (csLen == 0) {
-            PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
-            SSL_DBG(("%d: SSL[%d]: no cipher overlap",
-                     SSL_GETPID(), ss->fd));
-            goto loser;
-        }
-        if (certLen == 0) {
-            SSL_DBG(("%d: SSL[%d]: client, huh? certLen=%d csLen=%d",
-                     SSL_GETPID(), ss->fd, certLen, csLen));
-            goto bad_server;
-        }
-
-        if (sid->cached != never_cached) {
-            /* Forget our session-id - server didn't like it */
-            SSL_TRC(7, ("%d: SSL[%d]: server forgot me, uncaching session-id",
-                        SSL_GETPID(), ss->fd));
-            if (ss->sec.uncache)
-                (*ss->sec.uncache)(sid);
-            ssl_FreeSID(sid);
-            ss->sec.ci.sid = sid = PORT_ZNew(sslSessionID);
-            if (!sid) {
-                goto loser;
-            }
-            sid->references = 1;
-            sid->addr = ss->sec.ci.peer;
-            sid->port = ss->sec.ci.port;
-        }
-
-        /* decode the server's certificate */
-        rv = ssl2_ClientHandleServerCert(ss, cert, certLen);
-        if (rv != SECSuccess) {
-            if (PORT_GetError() == SSL_ERROR_BAD_CERTIFICATE) {
-                (void)ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
-            }
-            goto loser;
-        }
-
-        /* Setup new session cipher */
-        rv = ssl2_ClientSetupSessionCypher(ss, cs, csLen);
-        if (rv != SECSuccess) {
-            if (PORT_GetError() == SSL_ERROR_BAD_CERTIFICATE) {
-                (void)ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
-            }
-            goto loser;
-        }
-    }
-
-    /* Build up final list of required elements */
-    ss->sec.ci.elements = CIS_HAVE_MASTER_KEY;
-    ss->sec.ci.requiredElements = needed;
-
-    if (!sidHit) {
-        /* verify the server's certificate. if sidHit, don't check signatures */
-        rv = (*ss->authCertificate)(ss->authCertificateArg, ss->fd,
-                                    (PRBool)(!sidHit), PR_FALSE);
-        if (rv) {
-            if (ss->handleBadCert) {
-                rv = (*ss->handleBadCert)(ss->badCertArg, ss->fd);
-                if (rv) {
-                    if (rv == SECWouldBlock) {
-                        SSL_DBG(("%d: SSL[%d]: SSL2 bad cert handler returned "
-                                 "SECWouldBlock",
-                                 SSL_GETPID(), ss->fd));
-                        PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
-                        rv = SECFailure;
-                    } else {
-                        /* cert is bad */
-                        SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=%d",
-                                 SSL_GETPID(), ss->fd, PORT_GetError()));
-                    }
-                    goto loser;
-                }
-                /* cert is good */
-            } else {
-                SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=%d",
-                         SSL_GETPID(), ss->fd, PORT_GetError()));
-                goto loser;
-            }
-        }
-    }
-    /*
-    ** At this point we have a completed session key and our session
-    ** cipher is setup and ready to go. Switch to encrypted write routine
-    ** as all future message data is to be encrypted.
-    */
-    ssl2_UseEncryptedSendFunc(ss);
-
-    rv = ssl2_TryToFinish(ss);
-    if (rv != SECSuccess)
-        goto loser;
-
-    ss->gs.recordLen = 0;
-
-    ssl_ReleaseRecvBufLock(ss);
-
-    if (ss->handshake == 0) {
-        return SECSuccess;
-    }
-
-    SSL_TRC(5, ("%d: SSL[%d]: got server-hello, required=0x%d got=0x%x",
-                SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements,
-                ss->sec.ci.elements));
-    ss->handshake = ssl_GatherRecord1stHandshake;
-    ss->nextHandshake = ssl2_HandleVerifyMessage;
-    return SECSuccess;
-
-bad_server:
-    PORT_SetError(SSL_ERROR_BAD_SERVER);
-/* FALL THROUGH */
-
-loser:
-    ssl_ReleaseRecvBufLock(ss);
-    return SECFailure;
-}
-
 /* Sends out the initial client Hello message on the connection.
  * Acquires and releases the socket's xmitBufLock.
  */
 SECStatus
-ssl2_BeginClientHandshake(sslSocket *ss)
+ssl_BeginClientHandshake(sslSocket *ss)
 {
     sslSessionID *sid;
-    PRUint8 *msg;
-    PRUint8 *cp;
-    PRUint8 *localCipherSpecs = NULL;
-    unsigned int localCipherSize;
-    unsigned int i;
-    int sendLen, sidLen = 0;
     SECStatus rv;
-    TLSExtensionData *xtnData;
 
     PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
 
     ss->sec.isServer = 0;
-    ss->sec.sendSequence = 0;
-    ss->sec.rcvSequence = 0;
     ssl_ChooseSessionIDProcs(&ss->sec);
 
-    if (!ss->cipherSpecs) {
-        rv = ssl2_ConstructCipherSpecs(ss);
-        if (rv != SECSuccess)
-            goto loser;
-    }
-
-    /* count the SSL2 and SSL3 enabled ciphers.
-     * if either is zero, clear the socket's enable for that protocol.
-     */
-    rv = ssl2_CheckConfigSanity(ss);
+    rv = ssl_CheckConfigSanity(ss);
     if (rv != SECSuccess)
         goto loser;
 
     /* Get peer name of server */
     rv = ssl_GetPeerInfo(ss);
     if (rv < 0) {
 #ifdef HPUX11
         /*
@@ -3008,58 +161,28 @@ ssl2_BeginClientHandshake(sslSocket *ss)
 
     /* Try to find server in our session-id cache */
     if (ss->opt.noCache) {
         sid = NULL;
     } else {
         sid = ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID,
                             ss->url);
     }
-    while (sid) { /* this isn't really a loop */
-        PRBool sidVersionEnabled =
-            (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange) &&
-             sid->version >= ss->vrange.min &&
-             sid->version <= ss->vrange.max) ||
-            (sid->version < SSL_LIBRARY_VERSION_3_0 && ss->opt.enableSSL2);
-
-        /* if we're not doing this SID's protocol any more, drop it. */
-        if (!sidVersionEnabled) {
+    if (sid) {
+        if (sid->version >= ss->vrange.min && sid->version <= ss->vrange.max) {
+            PORT_Assert(!ss->sec.localCert);
+            ss->sec.localCert = CERT_DupCertificate(sid->localCert);
+        } else {
             if (ss->sec.uncache)
                 ss->sec.uncache(sid);
             ssl_FreeSID(sid);
             sid = NULL;
-            break;
         }
-        if (sid->version < SSL_LIBRARY_VERSION_3_0) {
-            /* If the cipher in this sid is not enabled, drop it. */
-            for (i = 0; i < ss->sizeCipherSpecs; i += 3) {
-                if (ss->cipherSpecs[i] == sid->u.ssl2.cipherType)
-                    break;
-            }
-            if (i >= ss->sizeCipherSpecs) {
-                if (ss->sec.uncache)
-                    ss->sec.uncache(sid);
-                ssl_FreeSID(sid);
-                sid = NULL;
-                break;
-            }
-        }
-        sidLen = sizeof(sid->u.ssl2.sessionID);
-        PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl2.sessionID,
-                      sidLen));
-        ss->version = sid->version;
-        PORT_Assert(!ss->sec.localCert);
-        if (ss->sec.localCert) {
-            CERT_DestroyCertificate(ss->sec.localCert);
-        }
-        ss->sec.localCert = CERT_DupCertificate(sid->localCert);
-        break; /* this isn't really a loop */
     }
     if (!sid) {
-        sidLen = 0;
         sid = PORT_ZNew(sslSessionID);
         if (!sid) {
             goto loser;
         }
         sid->references = 1;
         sid->cached = never_cached;
         sid->addr = ss->sec.ci.peer;
         sid->port = ss->sec.ci.port;
@@ -3069,591 +192,47 @@ ssl2_BeginClientHandshake(sslSocket *ss)
         if (ss->url != NULL) {
             sid->urlSvrName = PORT_Strdup(ss->url);
         }
     }
     ss->sec.ci.sid = sid;
 
     PORT_Assert(sid != NULL);
 
-    if ((sid->version >= SSL_LIBRARY_VERSION_3_0 || !ss->opt.v2CompatibleHello) &&
-        !SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
-        ss->gs.state = GS_INIT;
-        ss->handshake = ssl_GatherRecord1stHandshake;
-
-        /* ssl3_SendClientHello will override this if it succeeds. */
-        ss->version = SSL_LIBRARY_VERSION_3_0;
-
-        ssl_GetSSL3HandshakeLock(ss);
-        ssl_GetXmitBufLock(ss);
-        rv = ssl3_SendClientHello(ss, PR_FALSE);
-        ssl_ReleaseXmitBufLock(ss);
-        ssl_ReleaseSSL3HandshakeLock(ss);
-
-        return rv;
-    }
-#ifndef NSS_DISABLE_ECC
-    /* ensure we don't neogtiate ECC cipher suites with SSL2 hello */
-    ssl3_DisableECCSuites(ss, NULL); /* disable all ECC suites */
-    if (ss->cipherSpecs != NULL) {
-        PORT_Free(ss->cipherSpecs);
-        ss->cipherSpecs = NULL;
-        ss->sizeCipherSpecs = 0;
-    }
-#endif /* NSS_DISABLE_ECC */
-
-    if (!ss->cipherSpecs) {
-        rv = ssl2_ConstructCipherSpecs(ss);
-        if (rv < 0) {
-            return rv;
-        }
-    }
-    localCipherSpecs = ss->cipherSpecs;
-    localCipherSize = ss->sizeCipherSpecs;
-
-    /* Add 3 for SCSV */
-    sendLen = SSL_HL_CLIENT_HELLO_HBYTES + localCipherSize + 3 + sidLen +
-              SSL_CHALLENGE_BYTES;
-
-    /* Generate challenge bytes for server */
-    PK11_GenerateRandom(ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES);
-
-    ssl_GetXmitBufLock(ss); /***************************************/
-
-    rv = ssl2_GetSendBuffer(ss, sendLen);
-    if (rv)
-        goto unlock_loser;
+    ss->gs.state = GS_INIT;
+    ss->handshake = ssl_GatherRecord1stHandshake;
 
-    /* Construct client-hello message */
-    cp = msg = ss->sec.ci.sendBuf.buf;
-    msg[0] = SSL_MT_CLIENT_HELLO;
-    ss->clientHelloVersion = SSL3_ALL_VERSIONS_DISABLED(&ss->vrange) ? SSL_LIBRARY_VERSION_2
-                                                                     : ss->vrange.max;
-
-    msg[1] = MSB(ss->clientHelloVersion);
-    msg[2] = LSB(ss->clientHelloVersion);
-    /* Add 3 for SCSV */
-    msg[3] = MSB(localCipherSize + 3);
-    msg[4] = LSB(localCipherSize + 3);
-    msg[5] = MSB(sidLen);
-    msg[6] = LSB(sidLen);
-    msg[7] = MSB(SSL_CHALLENGE_BYTES);
-    msg[8] = LSB(SSL_CHALLENGE_BYTES);
-    cp += SSL_HL_CLIENT_HELLO_HBYTES;
-    PORT_Memcpy(cp, localCipherSpecs, localCipherSize);
-    cp += localCipherSize;
-    /*
-     * Add SCSV.  SSL 2.0 cipher suites are listed before SSL 3.0 cipher
-     * suites in localCipherSpecs for compatibility with SSL 2.0 servers.
-     * Since SCSV looks like an SSL 3.0 cipher suite, we can't add it at
-     * the beginning.
-     */
-    cp[0] = 0x00;
-    cp[1] = 0x00;
-    cp[2] = 0xff;
-    cp += 3;
-    if (sidLen) {
-        PORT_Memcpy(cp, sid->u.ssl2.sessionID, sidLen);
-        cp += sidLen;
-    }
-    PORT_Memcpy(cp, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES);
-
-    /* Send it to the server */
-    DUMP_MSG(29, (ss, msg, sendLen));
-    ss->handshakeBegun = 1;
-    rv = (*ss->sec.send)(ss, msg, sendLen, 0);
-
-    ssl_ReleaseXmitBufLock(ss); /***************************************/
-
-    if (rv < 0) {
-        goto loser;
-    }
-
-    rv = ssl3_StartHandshakeHash(ss, msg, sendLen);
-    if (rv < 0) {
-        goto loser;
-    }
+    /* ssl3_SendClientHello will override this if it succeeds. */
+    ss->version = SSL_LIBRARY_VERSION_3_0;
 
-    /*
-     * Since we sent the SCSV, pretend we sent empty RI extension.  We need
-     * to record the extension has been advertised after ssl3_InitState has
-     * been called, which ssl3_StartHandshakeHash took care for us above.
-     */
-    xtnData = &ss->xtnData;
-    xtnData->advertised[xtnData->numAdvertised++] = ssl_renegotiation_info_xtn;
-
-    /* Setup to receive servers hello message */
-    ssl_GetRecvBufLock(ss);
-    ss->gs.recordLen = 0;
-    ssl_ReleaseRecvBufLock(ss);
-
-    ss->handshake = ssl_GatherRecord1stHandshake;
-    ss->nextHandshake = ssl2_HandleServerHelloMessage;
-    return SECSuccess;
-
-unlock_loser:
+    ssl_GetSSL3HandshakeLock(ss);
+    ssl_GetXmitBufLock(ss);
+    rv = ssl3_SendClientHello(ss, PR_FALSE);
     ssl_ReleaseXmitBufLock(ss);
-loser:
-    return SECFailure;
-}
-
-/************************************************************************/
-
-/* Handle the CLIENT-MASTER-KEY message.
-** Acquires and releases RecvBufLock.
-** Called from ssl2_HandleClientHelloMessage().
-*/
-static SECStatus
-ssl2_HandleClientSessionKeyMessage(sslSocket *ss)
-{
-    PRUint8 *data;
-    unsigned int caLen;
-    unsigned int ckLen;
-    unsigned int ekLen;
-    unsigned int keyBits;
-    int cipher;
-    SECStatus rv;
-
-    ssl_GetRecvBufLock(ss);
-
-    data = ss->gs.buf.buf + ss->gs.recordOffset;
-    DUMP_MSG(29, (ss, data, ss->gs.recordLen));
+    ssl_ReleaseSSL3HandshakeLock(ss);
 
-    if ((ss->gs.recordLen < SSL_HL_CLIENT_MASTER_KEY_HBYTES) ||
-        (data[0] != SSL_MT_CLIENT_MASTER_KEY)) {
-        goto bad_client;
-    }
-    cipher = data[1];
-    keyBits = (data[2] << 8) | data[3];
-    ckLen = (data[4] << 8) | data[5];
-    ekLen = (data[6] << 8) | data[7];
-    caLen = (data[8] << 8) | data[9];
-
-    SSL_TRC(5, ("%d: SSL[%d]: session-key, cipher=%d keyBits=%d ckLen=%d ekLen=%d caLen=%d",
-                SSL_GETPID(), ss->fd, cipher, keyBits, ckLen, ekLen, caLen));
-
-    if (ss->gs.recordLen <
-        SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen) {
-        SSL_DBG(("%d: SSL[%d]: protocol size mismatch dataLen=%d",
-                 SSL_GETPID(), ss->fd, ss->gs.recordLen));
-        goto bad_client;
-    }
-
-    /* Use info from client to setup session key */
-    rv = ssl2_ServerSetupSessionCypher(ss, cipher, keyBits,
-                                       data + SSL_HL_CLIENT_MASTER_KEY_HBYTES,
-                                       ckLen,
-                                       data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen,
-                                       ekLen,
-                                       data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen,
-                                       caLen);
-    ss->gs.recordLen = 0; /* we're done with this record. */
-
-    ssl_ReleaseRecvBufLock(ss);
-
-    if (rv != SECSuccess) {
-        goto loser;
-    }
-    ss->sec.ci.elements |= CIS_HAVE_MASTER_KEY;
-    ssl2_UseEncryptedSendFunc(ss);
-
-    /* Send server verify message now that keys are established */
-    rv = ssl2_SendServerVerifyMessage(ss);
-    if (rv != SECSuccess)
-        goto loser;
-
-    rv = ssl2_TryToFinish(ss);
-    if (rv != SECSuccess)
-        goto loser;
-    if (ss->handshake == 0) {
-        return SECSuccess;
-    }
-
-    SSL_TRC(5, ("%d: SSL[%d]: server: waiting for elements=0x%d",
-                SSL_GETPID(), ss->fd,
-                ss->sec.ci.requiredElements ^ ss->sec.ci.elements));
-    ss->handshake = ssl_GatherRecord1stHandshake;
-    ss->nextHandshake = ssl2_HandleMessage;
-
-    return ssl2_TriggerNextMessage(ss);
-
-bad_client:
-    ssl_ReleaseRecvBufLock(ss);
-    PORT_SetError(SSL_ERROR_BAD_CLIENT);
-/* FALLTHROUGH */
+    return rv;
 
 loser:
     return SECFailure;
 }
 
-/*
-** Handle the initial hello message from the client
-**
-** not static because ssl2_GatherData() tests ss->nextHandshake for this value.
-*/
 SECStatus
-ssl2_HandleClientHelloMessage(sslSocket *ss)
-{
-    sslSessionID *sid;
-    sslServerCerts *sc;
-    CERTCertificate *serverCert;
-    PRUint8 *msg;
-    PRUint8 *data;
-    PRUint8 *cs;
-    PRUint8 *sd;
-    PRUint8 *cert = NULL;
-    PRUint8 *challenge;
-    unsigned int challengeLen;
-    SECStatus rv;
-    int csLen;
-    int sendLen;
-    int sdLen;
-    int certLen;
-    int pid;
-    int sent;
-    int gotXmitBufLock = 0;
-#if defined(SOLARIS) && defined(i386)
-    volatile PRUint8 hit;
-#else
-    int hit;
-#endif
-    PRUint8 csImpl[sizeof implementedCipherSuites];
-
-    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-
-    sc = ss->serverCerts + kt_rsa;
-    serverCert = sc->serverCert;
-
-    ssl_GetRecvBufLock(ss);
-
-    data = ss->gs.buf.buf + ss->gs.recordOffset;
-    DUMP_MSG(29, (ss, data, ss->gs.recordLen));
-
-    /* Make sure first message has some data and is the client hello message */
-    if ((ss->gs.recordLen < SSL_HL_CLIENT_HELLO_HBYTES) ||
-        (data[0] != SSL_MT_CLIENT_HELLO)) {
-        goto bad_client;
-    }
-
-    /* Get peer name of client */
-    rv = ssl_GetPeerInfo(ss);
-    if (rv != SECSuccess) {
-        goto loser;
-    }
-
-    /* Examine version information */
-    /*
-     * See if this might be a V2 client hello asking to use the V3 protocol
-     */
-    if ((data[0] == SSL_MT_CLIENT_HELLO) &&
-        (data[1] >= MSB(SSL_LIBRARY_VERSION_3_0)) &&
-        !SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
-        rv = ssl3_HandleV2ClientHello(ss, data, ss->gs.recordLen);
-        if (rv != SECFailure) { /* Success */
-            ss->handshake = NULL;
-            ss->nextHandshake = ssl_GatherRecord1stHandshake;
-            ss->securityHandshake = NULL;
-            ss->gs.state = GS_INIT;
-
-            /* ssl3_HandleV3ClientHello has set ss->version,
-            ** and has gotten us a brand new sid.
-            */
-            ss->sec.ci.sid->version = ss->version;
-        }
-        ssl_ReleaseRecvBufLock(ss);
-        return rv;
-    }
-    /* Previously, there was a test here to see if SSL2 was enabled.
-    ** If not, an error code was set, and SECFailure was returned,
-    ** without sending any error code to the other end of the connection.
-    ** That test has been removed.  If SSL2 has been disabled, there
-    ** should be no SSL2 ciphers enabled, and consequently, the code
-    ** below should send the ssl2 error message SSL_PE_NO_CYPHERS.
-    ** We now believe this is the correct thing to do, even when SSL2
-    ** has been explicitly disabled by the application.
-    */
-
-    /* Extract info from message */
-    ss->version = (data[1] << 8) | data[2];
-
-    /* If some client thinks ssl v2 is 2.0 instead of 0.2, we'll allow it.  */
-    if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
-        ss->version = SSL_LIBRARY_VERSION_2;
-    }
-
-    csLen = (data[3] << 8) | data[4];
-    sdLen = (data[5] << 8) | data[6];
-    challengeLen = (data[7] << 8) | data[8];
-    cs = data + SSL_HL_CLIENT_HELLO_HBYTES;
-    sd = cs + csLen;
-    challenge = sd + sdLen;
-    PRINT_BUF(7, (ss, "server, client session-id value:", sd, sdLen));
-
-    if (!csLen || (csLen % 3) != 0 ||
-        (sdLen != 0 && sdLen != SSL2_SESSIONID_BYTES) ||
-        challengeLen < SSL_MIN_CHALLENGE_BYTES ||
-        challengeLen > SSL_MAX_CHALLENGE_BYTES ||
-        (unsigned)ss->gs.recordLen !=
-            SSL_HL_CLIENT_HELLO_HBYTES + csLen + sdLen + challengeLen) {
-        SSL_DBG(("%d: SSL[%d]: bad client hello message, len=%d should=%d",
-                 SSL_GETPID(), ss->fd, ss->gs.recordLen,
-                 SSL_HL_CLIENT_HELLO_HBYTES + csLen + sdLen + challengeLen));
-        goto bad_client;
-    }
-
-    SSL_TRC(3, ("%d: SSL[%d]: client version is %x",
-                SSL_GETPID(), ss->fd, ss->version));
-    if (ss->version != SSL_LIBRARY_VERSION_2) {
-        if (ss->version > SSL_LIBRARY_VERSION_2) {
-            /*
-            ** Newer client than us. Things are ok because new clients
-            ** are required to be backwards compatible with old servers.
-            ** Change version number to our version number so that client
-            ** knows whats up.
-            */
-            ss->version = SSL_LIBRARY_VERSION_2;
-        } else {
-            SSL_TRC(1, ("%d: SSL[%d]: client version is %x (we are %x)",
-                        SSL_GETPID(), ss->fd, ss->version, SSL_LIBRARY_VERSION_2));
-            PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
-            goto loser;
-        }
-    }
-
-    /* Qualify cipher specs before returning them to client */
-    csLen = ssl2_QualifyCypherSpecs(ss, cs, csLen);
-    if (csLen == 0) {
-        /* no overlap, send client our list of supported SSL v2 ciphers. */
-        cs = csImpl;
-        csLen = sizeof implementedCipherSuites;
-        PORT_Memcpy(cs, implementedCipherSuites, csLen);
-        csLen = ssl2_QualifyCypherSpecs(ss, cs, csLen);
-        if (csLen == 0) {
-            /* We don't support any SSL v2 ciphers! */
-            ssl2_SendErrorMessage(ss, SSL_PE_NO_CYPHERS);
-            PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
-            goto loser;
-        }
-        /* Since this handhsake is going to fail, don't cache it. */
-        ss->opt.noCache = 1;
-    }
-
-    /* Squirrel away the challenge for later */
-    PORT_Memcpy(ss->sec.ci.clientChallenge, challenge, challengeLen);
-
-    /* Examine message and see if session-id is good */
-    ss->sec.ci.elements = 0;
-    if (sdLen > 0 && !ss->opt.noCache) {
-        SSL_TRC(7, ("%d: SSL[%d]: server, lookup client session-id for 0x%08x%08x%08x%08x",
-                    SSL_GETPID(), ss->fd, ss->sec.ci.peer.pr_s6_addr32[0],
-                    ss->sec.ci.peer.pr_s6_addr32[1],
-                    ss->sec.ci.peer.pr_s6_addr32[2],
-                    ss->sec.ci.peer.pr_s6_addr32[3]));
-        sid = (*ssl_sid_lookup)(&ss->sec.ci.peer, sd, sdLen, ss->dbHandle);
-    } else {
-        sid = NULL;
-    }
-    if (sid) {
-        /* Got a good session-id. Short cut! */
-        SSL_TRC(1, ("%d: SSL[%d]: server, using session-id for 0x%08x (age=%d)",
-                    SSL_GETPID(), ss->fd, ss->sec.ci.peer,
-                    ssl_Time() - sid->creationTime));
-        PRINT_BUF(1, (ss, "session-id value:", sd, sdLen));
-        ss->sec.ci.sid = sid;
-        ss->sec.ci.elements = CIS_HAVE_MASTER_KEY;
-        hit = 1;
-        certLen = 0;
-        csLen = 0;
-
-        ss->sec.authAlgorithm = sid->authAlgorithm;
-        ss->sec.authKeyBits = sid->authKeyBits;
-        ss->sec.keaType = sid->keaType;
-        ss->sec.keaKeyBits = sid->keaKeyBits;
-
-        rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE);
-        if (rv != SECSuccess) {
-            goto loser;
-        }
-    } else {
-        SECItem *derCert = &serverCert->derCert;
-
-        SSL_TRC(7, ("%d: SSL[%d]: server, lookup nonce missed",
-                    SSL_GETPID(), ss->fd));
-        if (!serverCert) {
-            SET_ERROR_CODE
-            goto loser;
-        }
-        hit = 0;
-        sid = PORT_ZNew(sslSessionID);
-        if (!sid) {
-            goto loser;
-        }
-        sid->references = 1;
-        sid->addr = ss->sec.ci.peer;
-        sid->port = ss->sec.ci.port;
-
-        /* Invent a session-id */
-        ss->sec.ci.sid = sid;
-        PK11_GenerateRandom(sid->u.ssl2.sessionID + 2, SSL2_SESSIONID_BYTES - 2);
-
-        pid = SSL_GETPID();
-        sid->u.ssl2.sessionID[0] = MSB(pid);
-        sid->u.ssl2.sessionID[1] = LSB(pid);
-        cert = derCert->data;
-        certLen = derCert->len;
-
-        /* pretend that server sids remember the local cert. */
-        PORT_Assert(!sid->localCert);
-        if (sid->localCert) {
-            CERT_DestroyCertificate(sid->localCert);
-        }
-        sid->localCert = CERT_DupCertificate(serverCert);
-
-        ss->sec.authAlgorithm = ssl_sign_rsa;
-        ss->sec.keaType = ssl_kea_rsa;
-        ss->sec.keaKeyBits =
-            ss->sec.authKeyBits = ss->serverCerts[kt_rsa].serverKeyBits;
-    }
-
-    /* server sids don't remember the local cert, so whether we found
-    ** a sid or not, just "remember" we used the rsa server cert.
-    */
-    if (ss->sec.localCert) {
-        CERT_DestroyCertificate(ss->sec.localCert);
-    }
-    ss->sec.localCert = CERT_DupCertificate(serverCert);
-
-    /* Build up final list of required elements */
-    ss->sec.ci.requiredElements = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED;
-    if (ss->opt.requestCertificate) {
-        ss->sec.ci.requiredElements |= CIS_HAVE_CERTIFICATE;
-    }
-    ss->sec.ci.sentElements = 0;
-
-    /* Send hello message back to client */
-    sendLen = SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen +
-              SSL_CONNECTIONID_BYTES;
-
-    ssl_GetXmitBufLock(ss);
-    gotXmitBufLock = 1;
-    rv = ssl2_GetSendBuffer(ss, sendLen);
-    if (rv != SECSuccess) {
-        goto loser;
-    }
-
-    SSL_TRC(3, ("%d: SSL[%d]: sending server-hello (%d)",
-                SSL_GETPID(), ss->fd, sendLen));
-
-    msg = ss->sec.ci.sendBuf.buf;
-    msg[0] = SSL_MT_SERVER_HELLO;
-    msg[1] = hit;
-    msg[2] = SSL_CT_X509_CERTIFICATE;
-    msg[3] = MSB(ss->version);
-    msg[4] = LSB(ss->version);
-    msg[5] = MSB(certLen);
-    msg[6] = LSB(certLen);
-    msg[7] = MSB(csLen);
-    msg[8] = LSB(csLen);
-    msg[9] = MSB(SSL_CONNECTIONID_BYTES);
-    msg[10] = LSB(SSL_CONNECTIONID_BYTES);
-    if (certLen) {
-        PORT_Memcpy(msg + SSL_HL_SERVER_HELLO_HBYTES, cert, certLen);
-    }
-    if (csLen) {
-        PORT_Memcpy(msg + SSL_HL_SERVER_HELLO_HBYTES + certLen, cs, csLen);
-    }
-    PORT_Memcpy(msg + SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen,
-                ss->sec.ci.connectionID, SSL_CONNECTIONID_BYTES);
-
-    DUMP_MSG(29, (ss, msg, sendLen));
-
-    ss->handshakeBegun = 1;
-    sent = (*ss->sec.send)(ss, msg, sendLen, 0);
-    if (sent < 0) {
-        goto loser;
-    }
-    ssl_ReleaseXmitBufLock(ss);
-    gotXmitBufLock = 0;
-
-    ss->gs.recordLen = 0;
-    ss->handshake = ssl_GatherRecord1stHandshake;
-    if (hit) {
-        /* Old SID Session key is good. Go encrypted */
-        ssl2_UseEncryptedSendFunc(ss);
-
-        /* Send server verify message now that keys are established */
-        rv = ssl2_SendServerVerifyMessage(ss);
-        if (rv != SECSuccess)
-            goto loser;
-
-        ss->nextHandshake = ssl2_HandleMessage;
-        ssl_ReleaseRecvBufLock(ss);
-        rv = ssl2_TriggerNextMessage(ss);
-        return rv;
-    }
-    ss->nextHandshake = ssl2_HandleClientSessionKeyMessage;
-    ssl_ReleaseRecvBufLock(ss);
-    return SECSuccess;
-
-bad_client:
-    PORT_SetError(SSL_ERROR_BAD_CLIENT);
-/* FALLTHROUGH */
-
-loser:
-    if (gotXmitBufLock) {
-        ssl_ReleaseXmitBufLock(ss);
-        gotXmitBufLock = 0;
-    }
-    SSL_TRC(10, ("%d: SSL[%d]: server, wait for client-hello lossage",
-                 SSL_GETPID(), ss->fd));
-    ssl_ReleaseRecvBufLock(ss);
-    return SECFailure;
-}
-
-SECStatus
-ssl2_BeginServerHandshake(sslSocket *ss)
+ssl_BeginServerHandshake(sslSocket *ss)
 {
     SECStatus rv;
-    sslServerCerts *rsaAuth = ss->serverCerts + kt_rsa;
 
     ss->sec.isServer = 1;
     ssl_ChooseSessionIDProcs(&ss->sec);
-    ss->sec.sendSequence = 0;
-    ss->sec.rcvSequence = 0;
 
-    /* don't turn on SSL2 if we don't have an RSA key and cert */
-    if (!rsaAuth->serverKeyPair || !rsaAuth->SERVERKEY ||
-        !rsaAuth->serverCert) {
-        ss->opt.enableSSL2 = PR_FALSE;
-    }
-
-    if (!ss->cipherSpecs) {
-        rv = ssl2_ConstructCipherSpecs(ss);
-        if (rv != SECSuccess)
-            goto loser;
-    }
-
-    /* count the SSL2 and SSL3 enabled ciphers.
-     * if either is zero, clear the socket's enable for that protocol.
-     */
-    rv = ssl2_CheckConfigSanity(ss);
+    rv = ssl_CheckConfigSanity(ss);
     if (rv != SECSuccess)
         goto loser;
 
-    /*
-    ** Generate connection-id. Always do this, even if things fail
-    ** immediately. This way the random number generator is always
-    ** rolling around, every time we get a connection.
-    */
-    PK11_GenerateRandom(ss->sec.ci.connectionID,
-                        sizeof(ss->sec.ci.connectionID));
-
-    ss->gs.recordLen = 0;
     ss->handshake = ssl_GatherRecord1stHandshake;
-    ss->nextHandshake = ssl2_HandleClientHelloMessage;
     return SECSuccess;
 
 loser:
     return SECFailure;
 }
 
 /* This function doesn't really belong in this file.
 ** It's here to keep AIX compilers from optimizing it away,
--- a/lib/ssl/sslenum.c
+++ b/lib/ssl/sslenum.c
@@ -130,24 +130,16 @@ const PRUint16 SSL_ImplementedCiphers[] 
     TLS_ECDHE_RSA_WITH_NULL_SHA,
     TLS_ECDH_RSA_WITH_NULL_SHA,
     TLS_ECDH_ECDSA_WITH_NULL_SHA,
 #endif /* NSS_DISABLE_ECC */
     TLS_RSA_WITH_NULL_SHA,
     TLS_RSA_WITH_NULL_SHA256,
     TLS_RSA_WITH_NULL_MD5,
 
-    /* SSL2 cipher suites. */
-    SSL_EN_RC4_128_WITH_MD5,
-    SSL_EN_RC2_128_CBC_WITH_MD5,
-    SSL_EN_DES_192_EDE3_CBC_WITH_MD5, /* actually 112, not 192 */
-    SSL_EN_DES_64_CBC_WITH_MD5,
-    SSL_EN_RC4_128_EXPORT40_WITH_MD5,
-    SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5,
-
     0
 
 };
 
 const PRUint16 SSL_NumImplementedCiphers =
     (sizeof SSL_ImplementedCiphers) / (sizeof SSL_ImplementedCiphers[0]) - 1;
 
 const PRUint16*
--- a/lib/ssl/sslerr.h
+++ b/lib/ssl/sslerr.h
@@ -13,47 +13,55 @@
 #define SSL_ERROR_LIMIT                         (SSL_ERROR_BASE + 1000)
 
 #define IS_SSL_ERROR(code) \
     (((code) >= SSL_ERROR_BASE) && ((code) < SSL_ERROR_LIMIT))
 
 #ifndef NO_SECURITY_ERROR_ENUM
 typedef enum {
     SSL_ERROR_EXPORT_ONLY_SERVER            = (SSL_ERROR_BASE +  0),
+                                            /* error 0 is obsolete */
     SSL_ERROR_US_ONLY_SERVER                = (SSL_ERROR_BASE +  1),
+                                            /* error 1 is obsolete */
     SSL_ERROR_NO_CYPHER_OVERLAP             = (SSL_ERROR_BASE +  2),
     /*
      * Received an alert reporting what we did wrong.  (more alerts below)
      */
     SSL_ERROR_NO_CERTIFICATE /*_ALERT */    = (SSL_ERROR_BASE +  3),
     SSL_ERROR_BAD_CERTIFICATE               = (SSL_ERROR_BASE +  4),
+                                            /* error 4 is obsolete */
     SSL_ERROR_UNUSED_5                      = (SSL_ERROR_BASE +  5),
                                             /* error 5 is obsolete */
     SSL_ERROR_BAD_CLIENT                    = (SSL_ERROR_BASE +  6),
     SSL_ERROR_BAD_SERVER                    = (SSL_ERROR_BASE +  7),
     SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE  = (SSL_ERROR_BASE +  8),
+                                            /* error 8 is obsolete */
     SSL_ERROR_UNSUPPORTED_VERSION           = (SSL_ERROR_BASE +  9),
     SSL_ERROR_UNUSED_10                     = (SSL_ERROR_BASE + 10),
                                             /* error 10 is obsolete */
     SSL_ERROR_WRONG_CERTIFICATE             = (SSL_ERROR_BASE + 11),
+                                            /* error 11 is obsolete */
     SSL_ERROR_BAD_CERT_DOMAIN               = (SSL_ERROR_BASE + 12),
     SSL_ERROR_POST_WARNING                  = (SSL_ERROR_BASE + 13),
+                                            /* error 13 is obsolete */
     SSL_ERROR_SSL2_DISABLED                 = (SSL_ERROR_BASE + 14),
+                                            /* error 14 is obsolete */
     SSL_ERROR_BAD_MAC_READ                  = (SSL_ERROR_BASE + 15),
     /*
      * Received an alert reporting what we did wrong.
      * (two more alerts above, and many more below)
      */
     SSL_ERROR_BAD_MAC_ALERT                 = (SSL_ERROR_BASE + 16),
     SSL_ERROR_BAD_CERT_ALERT                = (SSL_ERROR_BASE + 17),
     SSL_ERROR_REVOKED_CERT_ALERT            = (SSL_ERROR_BASE + 18),
     SSL_ERROR_EXPIRED_CERT_ALERT            = (SSL_ERROR_BASE + 19),
 
     SSL_ERROR_SSL_DISABLED                  = (SSL_ERROR_BASE + 20),
     SSL_ERROR_FORTEZZA_PQG                  = (SSL_ERROR_BASE + 21),
+                                            /* error 21 is obsolete */
     SSL_ERROR_UNKNOWN_CIPHER_SUITE          = (SSL_ERROR_BASE + 22),
     SSL_ERROR_NO_CIPHERS_SUPPORTED          = (SSL_ERROR_BASE + 23),
     SSL_ERROR_BAD_BLOCK_PADDING             = (SSL_ERROR_BASE + 24),
     SSL_ERROR_RX_RECORD_TOO_LONG            = (SSL_ERROR_BASE + 25),
     SSL_ERROR_TX_RECORD_TOO_LONG            = (SSL_ERROR_BASE + 26),
     /*
      * Received a malformed (too long or short) SSL handshake.
      */
@@ -114,17 +122,18 @@ typedef enum {
 
     SSL_ERROR_GENERATE_RANDOM_FAILURE       = (SSL_ERROR_BASE + 65),
     SSL_ERROR_SIGN_HASHES_FAILURE           = (SSL_ERROR_BASE + 66),
     SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE    = (SSL_ERROR_BASE + 67),
     SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE   = (SSL_ERROR_BASE + 68),
     SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE   = (SSL_ERROR_BASE + 69),
 
     SSL_ERROR_ENCRYPTION_FAILURE            = (SSL_ERROR_BASE + 70),
-    SSL_ERROR_DECRYPTION_FAILURE            = (SSL_ERROR_BASE + 71), /* don't use */
+    SSL_ERROR_DECRYPTION_FAILURE            = (SSL_ERROR_BASE + 71),
+                                            /* error 71 is obsolete */
     SSL_ERROR_SOCKET_WRITE_FAILURE          = (SSL_ERROR_BASE + 72),
 
     SSL_ERROR_MD5_DIGEST_FAILURE            = (SSL_ERROR_BASE + 73),
     SSL_ERROR_SHA_DIGEST_FAILURE            = (SSL_ERROR_BASE + 74),
     SSL_ERROR_MAC_COMPUTATION_FAILURE       = (SSL_ERROR_BASE + 75),
     SSL_ERROR_SYM_KEY_CONTEXT_FAILURE       = (SSL_ERROR_BASE + 76),
     SSL_ERROR_SYM_KEY_UNWRAP_FAILURE        = (SSL_ERROR_BASE + 77),
     SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED   = (SSL_ERROR_BASE + 78),
@@ -133,18 +142,18 @@ typedef enum {
     SSL_ERROR_SESSION_KEY_GEN_FAILURE       = (SSL_ERROR_BASE + 81),
     SSL_ERROR_NO_SERVER_KEY_FOR_ALG         = (SSL_ERROR_BASE + 82),
     SSL_ERROR_TOKEN_INSERTION_REMOVAL       = (SSL_ERROR_BASE + 83),
     SSL_ERROR_TOKEN_SLOT_NOT_FOUND          = (SSL_ERROR_BASE + 84),
     SSL_ERROR_NO_COMPRESSION_OVERLAP        = (SSL_ERROR_BASE + 85),
     SSL_ERROR_HANDSHAKE_NOT_COMPLETED       = (SSL_ERROR_BASE + 86),
     SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE      = (SSL_ERROR_BASE + 87),
     SSL_ERROR_CERT_KEA_MISMATCH             = (SSL_ERROR_BASE + 88),
-    /* SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA became obsolete in NSS 3.14. */
     SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA      = (SSL_ERROR_BASE + 89),
+                                            /* error 89 is obsolete */
     SSL_ERROR_SESSION_NOT_FOUND             = (SSL_ERROR_BASE + 90),
 
     SSL_ERROR_DECRYPTION_FAILED_ALERT       = (SSL_ERROR_BASE + 91),
     SSL_ERROR_RECORD_OVERFLOW_ALERT         = (SSL_ERROR_BASE + 92),
     SSL_ERROR_UNKNOWN_CA_ALERT              = (SSL_ERROR_BASE + 93),
     SSL_ERROR_ACCESS_DENIED_ALERT           = (SSL_ERROR_BASE + 94),
     SSL_ERROR_DECODE_ERROR_ALERT            = (SSL_ERROR_BASE + 95),
     SSL_ERROR_DECRYPT_ERROR_ALERT           = (SSL_ERROR_BASE + 96),
@@ -172,16 +181,17 @@ typedef enum {
 
     SSL_ERROR_RX_UNEXPECTED_UNCOMPRESSED_RECORD = (SSL_ERROR_BASE + 114),
 
     SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY  = (SSL_ERROR_BASE + 115),
 
     SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID    = (SSL_ERROR_BASE + 116),
 
     SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2 = (SSL_ERROR_BASE + 117),
+                                             /* error 117 is obsolete */
     SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SERVERS = (SSL_ERROR_BASE + 118),
     SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_CLIENTS = (SSL_ERROR_BASE + 119),
 
     SSL_ERROR_INVALID_VERSION_RANGE         = (SSL_ERROR_BASE + 120),
     SSL_ERROR_CIPHER_DISALLOWED_FOR_VERSION = (SSL_ERROR_BASE + 121),
 
     SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST = (SSL_ERROR_BASE + 122),
     SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST = (SSL_ERROR_BASE + 123),
deleted file mode 100644
--- a/lib/ssl/sslgathr.c
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- * Gather (Read) entire SSL2 records from socket into buffer.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "cert.h"
-#include "ssl.h"
-#include "sslimpl.h"
-#include "sslproto.h"
-
-/* Forward static declarations */
-static SECStatus ssl2_HandleV3HandshakeRecord(sslSocket *ss);
-
-/*
-** Gather a single record of data from the receiving stream. This code
-** first gathers the header (2 or 3 bytes long depending on the value of
-** the most significant bit in the first byte) then gathers up the data
-** for the record into gs->buf. This code handles non-blocking I/O
-** and is to be called multiple times until ss->sec.recordLen != 0.
-** This function decrypts the gathered record in place, in gs_buf.
- *
- * Caller must hold RecvBufLock.
- *
- * Returns +1 when it has gathered a complete SSLV2 record.
- * Returns  0 if it hits EOF.
- * Returns -1 (SECFailure)    on any error
- * Returns -2 (SECWouldBlock) when it gathers an SSL v3 client hello header.
-**
-** The SSL2 Gather State machine has 4 states:
-** GS_INIT   - Done reading in previous record.  Haven't begun to read in
-**             next record.  When ssl2_GatherData is called with the machine
-**             in this state, the machine will attempt to read the first 3
-**             bytes of the SSL2 record header, and will advance the state
-**             to GS_HEADER.
-**
-** GS_HEADER - The machine is in this state while waiting for the completion
-**             of the first 3 bytes of the SSL2 record.  When complete, the
-**             machine will compute the remaining unread length of this record
-**             and will initiate a read of that many bytes.  The machine will
-**             advance to one of two states, depending on whether the record
-**             is encrypted (GS_MAC), or unencrypted (GS_DATA).
-**
-** GS_MAC    - The machine is in this state while waiting for the remainder
-**             of the SSL2 record to be read in.  When the read is completed,
-**             the machine checks the record for valid length, decrypts it,
-**             and checks and discards the MAC, then advances to GS_INIT.
-**
-** GS_DATA   - The machine is in this state while waiting for the remainder
-**             of the unencrypted SSL2 record to be read in.  Upon completion,
-**             the machine advances to the GS_INIT state and returns the data.
-*/
-int
-ssl2_GatherData(sslSocket *ss, sslGather *gs, int flags)
-{
-    unsigned char *bp;
-    unsigned char *pBuf;
-    int nb, err, rv;
-
-    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
-
-    if (gs->state == GS_INIT) {
-        /* Initialize gathering engine */
-        gs->state = GS_HEADER;
-        gs->remainder = 3;
-        gs->count = 3;
-        gs->offset = 0;
-        gs->recordLen = 0;
-        gs->recordPadding = 0;
-        gs->hdr[2] = 0;
-
-        gs->writeOffset = 0;
-        gs->readOffset = 0;
-    }
-    if (gs->encrypted) {
-        PORT_Assert(ss->sec.hash != 0);
-    }
-
-    pBuf = gs->buf.buf;
-    for (;;) {
-        SSL_TRC(30, ("%d: SSL[%d]: gather state %d (need %d more)",
-                     SSL_GETPID(), ss->fd, gs->state, gs->remainder));
-        bp = ((gs->state != GS_HEADER) ? pBuf : gs->hdr) + gs->offset;
-        nb = ssl_DefRecv(ss, bp, gs->remainder, flags);
-        if (nb > 0) {
-            PRINT_BUF(60, (ss, "raw gather data:", bp, nb));
-        }
-        if (nb == 0) {
-            /* EOF */
-            SSL_TRC(30, ("%d: SSL[%d]: EOF", SSL_GETPID(), ss->fd));
-            rv = 0;
-            break;
-        }
-        if (nb < 0) {
-            SSL_DBG(("%d: SSL[%d]: recv error %d", SSL_GETPID(), ss->fd,
-                     PR_GetError()));
-            rv = SECFailure;
-            break;
-        }
-
-        gs->offset += nb;
-        gs->remainder -= nb;
-
-        if (gs->remainder > 0) {
-            continue;
-        }
-
-        /* Probably finished this piece */
-        switch (gs->state) {
-            case GS_HEADER:
-                if (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange) && !ss->firstHsDone) {
-
-                    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-
-                    /* If this looks like an SSL3 handshake record,
-                    ** and we're expecting an SSL2 Hello message from our peer,
-                    ** handle it here.
-                    */
-                    if (gs->hdr[0] == content_handshake) {
-                        if ((ss->nextHandshake == ssl2_HandleClientHelloMessage) ||
-                            (ss->nextHandshake == ssl2_HandleServerHelloMessage)) {
-                            rv = ssl2_HandleV3HandshakeRecord(ss);
-                            if (rv == SECFailure) {
-                                return SECFailure;
-                            }
-                        }
-                        /* XXX_1    The call stack to here is:
-                         * ssl_Do1stHandshake -> ssl_GatherRecord1stHandshake ->
-                         *          ssl2_GatherRecord -> here.
-                         * We want to return all the way out to ssl_Do1stHandshake,
-                         * and have it call ssl_GatherRecord1stHandshake again.
-                         * ssl_GatherRecord1stHandshake will call
-                         * ssl3_GatherCompleteHandshake when it is called again.
-                         *
-                         * Returning SECWouldBlock here causes
-                         * ssl_GatherRecord1stHandshake to return without clearing
-                         * ss->handshake, ensuring that ssl_Do1stHandshake will
-                         * call it again immediately.
-                         *
-                         * If we return 1 here, ssl_GatherRecord1stHandshake will
-                         * clear ss->handshake before returning, and thus will not
-                         * be called again by ssl_Do1stHandshake.
-                         */
-                        return SECWouldBlock;
-                    } else if (gs->hdr[0] == content_alert) {
-                        if (ss->nextHandshake == ssl2_HandleServerHelloMessage) {
-                            /* XXX This is a hack.  We're assuming that any failure
-                             * XXX on the client hello is a failure to match
-                             * XXX ciphers.
-                             */
-                            PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
-                            return SECFailure;
-                        }
-                    }
-                }
-
-                /* we've got the first 3 bytes.  The header may be two or three. */
-                if (gs->hdr[0] & 0x80) {
-                    /* This record has a 2-byte header, and no padding */
-                    gs->count = ((gs->hdr[0] & 0x7f) << 8) | gs->hdr[1];
-                    gs->recordPadding = 0;
-                } else {
-                    /* This record has a 3-byte header that is all read in now. */
-                    gs->count = ((gs->hdr[0] & 0x3f) << 8) | gs->hdr[1];
-                    /*  is_escape =  (gs->hdr[0] & 0x40) != 0; */
-                    gs->recordPadding = gs->hdr[2];
-                }
-                if (!gs->count) {
-                    PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
-                    goto cleanup;
-                }
-
-                if (gs->count > gs->buf.space) {
-                    err = sslBuffer_Grow(&gs->buf, gs->count);
-                    if (err) {
-                        return err;
-                    }
-                    pBuf = gs->buf.buf;
-                }
-
-                if (gs->hdr[0] & 0x80) {
-                    /* we've already read in the first byte of the body.
-                    ** Put it into the buffer.
-                    */
-                    pBuf[0] = gs->hdr[2];
-                    gs->offset = 1;
-                    gs->remainder = gs->count - 1;
-                } else {
-                    gs->offset = 0;
-                    gs->remainder = gs->count;
-                }
-
-                if (gs->encrypted) {
-                    gs->state = GS_MAC;
-                    gs->recordLen = gs->count - gs->recordPadding -
-                                    ss->sec.hash->length;
-                } else {
-                    gs->state = GS_DATA;
-                    gs->recordLen = gs->count;
-                }
-
-                break;
-
-            case GS_MAC:
-                /* Have read in entire rest of the ciphertext.
-                ** Check for valid length.
-                ** Decrypt it.
-                ** Check the MAC.
-                */
-                PORT_Assert(gs->encrypted);
-
-                {
-                    unsigned int macLen;
-                    int nout;
-                    unsigned char mac[SSL_MAX_MAC_BYTES];
-
-                    ssl_GetSpecReadLock(ss); /**********************************/
-
-                    /* If this is a stream cipher, blockSize will be 1,
-                     * and this test will always be false.
-                     * If this is a block cipher, this will detect records
-                     * that are not a multiple of the blocksize in length.
-                     */
-                    if (gs->count & (ss->sec.blockSize - 1)) {
-                        /* This is an error. Sender is misbehaving */
-                        SSL_DBG(("%d: SSL[%d]: sender, count=%d blockSize=%d",
-                                 SSL_GETPID(), ss->fd, gs->count,
-                                 ss->sec.blockSize));
-                        PORT_SetError(SSL_ERROR_BAD_BLOCK_PADDING);
-                        rv = SECFailure;
-                        goto spec_locked_done;
-                    }
-                    PORT_Assert(gs->count == gs->offset);
-
-                    if (gs->offset == 0) {
-                        rv = 0; /* means EOF. */
-                        goto spec_locked_done;
-                    }
-
-                    /* Decrypt the portion of data that we just received.
-                    ** Decrypt it in place.
-                    */
-                    rv = (*ss->sec.dec)(ss->sec.readcx, pBuf, &nout, gs->offset,
-                                        pBuf, gs->offset);
-                    if (rv != SECSuccess) {
-                        goto spec_locked_done;
-                    }
-
-                    /* Have read in all the MAC portion of record
-                    **
-                    ** Prepare MAC by resetting it and feeding it the shared secret
-                    */
-                    macLen = ss->sec.hash->length;
-                    if (gs->offset >= macLen) {
-                        PRUint32 sequenceNumber = ss->sec.rcvSequence++;
-                        unsigned char seq[4];
-
-                        seq[0] = (unsigned char)(sequenceNumber >> 24);
-                        seq[1] = (unsigned char)(sequenceNumber >> 16);
-                        seq[2] = (unsigned char)(sequenceNumber >> 8);
-                        seq[3] = (unsigned char)(sequenceNumber);
-
-                        (*ss->sec.hash->begin)(ss->sec.hashcx);
-                        (*ss->sec.hash->update)(ss->sec.hashcx, ss->sec.rcvSecret.data,
-                                                ss->sec.rcvSecret.len);
-                        (*ss->sec.hash->update)(ss->sec.hashcx, pBuf + macLen,
-                                                gs->offset - macLen);
-                        (*ss->sec.hash->update)(ss->sec.hashcx, seq, 4);
-                        (*ss->sec.hash->end)(ss->sec.hashcx, mac, &macLen, macLen);
-
-                        PORT_Assert(macLen == ss->sec.hash->length);
-
-                        ssl_ReleaseSpecReadLock(ss); /******************************/
-
-                        if (NSS_SecureMemcmp(mac, pBuf, macLen) != 0) {
-                            /* MAC's didn't match... */
-                            SSL_DBG(("%d: SSL[%d]: mac check failed, seq=%d",
-                                     SSL_GETPID(), ss->fd, ss->sec.rcvSequence));
-                            PRINT_BUF(1, (ss, "computed mac:", mac, macLen));
-                            PRINT_BUF(1, (ss, "received mac:", pBuf, macLen));
-                            PORT_SetError(SSL_ERROR_BAD_MAC_READ);
-                            rv = SECFailure;
-                            goto cleanup;
-                        }
-                    } else {
-                        ssl_ReleaseSpecReadLock(ss); /******************************/
-                    }
-
-                    if (gs->recordPadding + macLen <= gs->offset) {
-                        gs->recordOffset = macLen;
-                        gs->readOffset = macLen;
-                        gs->writeOffset = gs->offset - gs->recordPadding;
-                        rv = 1;
-                    } else {
-                        PORT_SetError(SSL_ERROR_BAD_BLOCK_PADDING);
-                    cleanup:
-                        /* nothing in the buffer any more. */
-                        gs->recordOffset = 0;
-                        gs->readOffset = 0;
-                        gs->writeOffset = 0;
-                        rv = SECFailure;
-                    }
-
-                    gs->recordLen = gs->writeOffset - gs->readOffset;
-                    gs->recordPadding = 0; /* forget we did any padding. */
-                    gs->state = GS_INIT;
-
-                    if (rv > 0) {
-                        PRINT_BUF(50, (ss, "recv clear record:",
-                                       pBuf + gs->recordOffset, gs->recordLen));
-                    }
-                    return rv;
-
-                spec_locked_done:
-                    ssl_ReleaseSpecReadLock(ss);
-                    return rv;
-                }
-
-            case GS_DATA:
-                /* Have read in all the DATA portion of record */
-
-                gs->recordOffset = 0;
-                gs->readOffset = 0;
-                gs->writeOffset = gs->offset;
-                PORT_Assert(gs->recordLen == gs->writeOffset - gs->readOffset);
-                gs->recordLen = gs->offset;
-                gs->recordPadding = 0;
-                gs->state = GS_INIT;
-
-                ++ss->sec.rcvSequence;
-
-                PRINT_BUF(50, (ss, "recv clear record:",
-                               pBuf + gs->recordOffset, gs->recordLen));
-                return 1;
-
-        } /* end switch gs->state */
-    }     /* end gather loop. */
-    return rv;
-}
-
-/*
-** Gather a single record of data from the receiving stream. This code
-** first gathers the header (2 or 3 bytes long depending on the value of
-** the most significant bit in the first byte) then gathers up the data
-** for the record into the readBuf. This code handles non-blocking I/O
-** and is to be called multiple times until ss->sec.recordLen != 0.
- *
- * Returns +1 when it has gathered a complete SSLV2 record.
- * Returns  0 if it hits EOF.
- * Returns -1 (SECFailure)    on any error
- * Returns -2 (SECWouldBlock)
- *
- * Called by ssl_GatherRecord1stHandshake in sslcon.c,
- * and by DoRecv in sslsecur.c
- * Caller must hold RecvBufLock.
- */
-int
-ssl2_GatherRecord(sslSocket *ss, int flags)
-{
-    return ssl2_GatherData(ss, &ss->gs, flags);
-}
-
-/* Caller should hold RecvBufLock. */
-SECStatus
-ssl_InitGather(sslGather *gs)
-{
-    SECStatus status;
-
-    gs->state = GS_INIT;
-    gs->writeOffset = 0;
-    gs->readOffset = 0;
-    gs->dtlsPacketOffset = 0;
-    gs->dtlsPacket.len = 0;
-    status = sslBuffer_Grow(&gs->buf, 4096);
-    return status;
-}
-
-/* Caller must hold RecvBufLock. */
-void
-ssl_DestroyGather(sslGather *gs)
-{
-    if (gs) { /* the PORT_*Free functions check for NULL pointers. */
-        PORT_ZFree(gs->buf.buf, gs->buf.space);
-        PORT_Free(gs->inbuf.buf);
-        PORT_Free(gs->dtlsPacket.buf);
-    }
-}
-
-/* Caller must hold RecvBufLock. */
-static SECStatus
-ssl2_HandleV3HandshakeRecord(sslSocket *ss)
-{
-    SECStatus rv;
-
-    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
-    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-
-    /* We've read in 3 bytes, there are 2 more to go in an ssl3 header. */
-    ss->gs.remainder = 2;
-    ss->gs.count = 0;
-
-    /* Clearing these handshake pointers ensures that
-     * ssl_Do1stHandshake won't call ssl2_HandleMessage when we return.
-     */
-    ss->nextHandshake = 0;
-    ss->securityHandshake = 0;
-
-    /* Setting ss->version to an SSL 3.x value will cause
-    ** ssl_GatherRecord1stHandshake to invoke ssl3_GatherCompleteHandshake()
-    ** the next time it is called.
-    **/
-    rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_MAX_SUPPORTED,
-                               PR_TRUE);
-    if (rv != SECSuccess) {
-        return rv;
-    }
-
-    ss->sec.send = ssl3_SendApplicationData;
-
-    return SECSuccess;
-}
--- a/lib/ssl/sslimpl.h
+++ b/lib/ssl/sslimpl.h
@@ -81,23 +81,19 @@ extern int Debug;
 
 #ifdef TRACE
 #define SSL_TRC(a, b)     \
     if (ssl_trace >= (a)) \
     ssl_Trace b
 #define PRINT_BUF(a, b)   \
     if (ssl_trace >= (a)) \
     ssl_PrintBuf b
-#define DUMP_MSG(a, b)    \
-    if (ssl_trace >= (a)) \
-    ssl_DumpMsg b
 #else
 #define SSL_TRC(a, b)
 #define PRINT_BUF(a, b)
-#define DUMP_MSG(a, b)
 #endif
 
 #ifdef DEBUG
 #define SSL_DBG(b) \
     if (ssl_debug) \
     ssl_Trace b
 #else
 #define SSL_DBG(b)
@@ -113,33 +109,22 @@ extern int Debug;
 
 typedef enum { SSLAppOpRead = 0,
                SSLAppOpWrite,
                SSLAppOpRDWR,
                SSLAppOpPost,
                SSLAppOpHeader
 } SSLAppOperation;
 
-#define SSL_MIN_MASTER_KEY_BYTES 5
-#define SSL_MAX_MASTER_KEY_BYTES 64
-
-#define SSL2_SESSIONID_BYTES 16
 #define SSL3_SESSIONID_BYTES 32
 
 #define SSL_MIN_CHALLENGE_BYTES 16
 #define SSL_MAX_CHALLENGE_BYTES 32
 #define SSL_CHALLENGE_BYTES 16
 
-#define SSL_CONNECTIONID_BYTES 16
-
-#define SSL_MIN_CYPHER_ARG_BYTES 0
-#define SSL_MAX_CYPHER_ARG_BYTES 32
-
-#define SSL_MAX_MAC_BYTES 16
-
 #define SSL3_RSA_PMS_LENGTH 48
 #define SSL3_MASTER_SECRET_LENGTH 48
 
 /* number of wrap mechanisms potentially used to wrap master secrets. */
 #define SSL_NUM_WRAP_MECHS 16
 
 /* This makes the cert cache entry exactly 4k. */
 #define SSL_MAX_CACHED_CERT_LEN 4060
@@ -181,24 +166,16 @@ typedef struct ssl3DHParamsStr ssl3DHPar
 
 struct ssl3CertNodeStr {
     struct ssl3CertNodeStr *next;
     CERTCertificate *cert;
 };
 
 typedef SECStatus (*sslHandshakeFunc)(sslSocket *ss);
 
-/* This type points to the low layer send func,
-** e.g. ssl2_SendStream or ssl3_SendPlainText.
-** These functions return the same values as PR_Send,
-** i.e.  >= 0 means number of bytes sent, < 0 means error.
-*/
-typedef PRInt32 (*sslSendFunc)(sslSocket *ss, const unsigned char *buf,
-                               PRInt32 n, PRInt32 flags);
-
 typedef void (*sslSessionIDCacheFunc)(sslSessionID *sid);
 typedef void (*sslSessionIDUncacheFunc)(sslSessionID *sid);
 typedef sslSessionID *(*sslSessionIDLookupFunc)(const PRIPv6Addr *addr,
                                                 unsigned char *sid,
                                                 unsigned int sidLen,
                                                 CERTCertDBHandle *dbHandle);
 
 /* registerable callback function that either appends extension to buffer
@@ -315,22 +292,22 @@ typedef struct sslOptionsStr {
     SECItem nextProtoNego;
 
     unsigned int useSecurity                : 1;  /*  1 */
     unsigned int useSocks                   : 1;  /*  2 */
     unsigned int requestCertificate         : 1;  /*  3 */
     unsigned int requireCertificate         : 2;  /*  4-5 */
     unsigned int handshakeAsClient          : 1;  /*  6 */
     unsigned int handshakeAsServer          : 1;  /*  7 */
-    unsigned int enableSSL2                 : 1;  /*  8 */
+    unsigned int unusedBit8                 : 1;  /*  8 */
     unsigned int unusedBit9                 : 1;  /*  9 */
     unsigned int unusedBit10                : 1;  /* 10 */
     unsigned int noCache                    : 1;  /* 11 */
     unsigned int fdx                        : 1;  /* 12 */
-    unsigned int v2CompatibleHello          : 1;  /* 13 */
+    unsigned int unusedBit13                : 1;  /* 13 */
     unsigned int detectRollBack             : 1;  /* 14 */
     unsigned int noStepDown                 : 1;  /* 15 */
     unsigned int bypassPKCS11               : 1;  /* 16 */
     unsigned int noLocks                    : 1;  /* 17 */
     unsigned int enableSessionTickets       : 1;  /* 18 */
     unsigned int enableDeflate              : 1;  /* 19 */
     unsigned int enableRenegotiation        : 2;  /* 20-21 */
     unsigned int requireSafeNegotiation     : 1;  /* 22 */
@@ -377,79 +354,57 @@ typedef struct sslServerCertsStr {
 #define ssl_SHUTDOWN_BOTH 3 /* PR_SHUTDOWN_BOTH +1 */
 
 /*
 ** A gather object. Used to read some data until a count has been
 ** satisfied. Primarily for support of async sockets.
 ** Everything in here is protected by the recvBufLock.
 */
 struct sslGatherStr {
-    int state; /* see GS_ values below. */ /* ssl 2 & 3 */
+    int state; /* see GS_ values below. */
 
     /* "buf" holds received plaintext SSL records, after decrypt and MAC check.
-     * SSL2: recv'd ciphertext records are put here, then decrypted in place.
-     * SSL3: recv'd ciphertext records are put in inbuf (see below), then
-     *       decrypted into buf.
+     * recv'd ciphertext records are put in inbuf (see below), then decrypted
+     * into buf.
      */
-    sslBuffer buf; /*recvBufLock*/ /* ssl 2 & 3 */
+    sslBuffer buf; /*recvBufLock*/
 
-    /* number of bytes previously read into hdr or buf(ssl2) or inbuf (ssl3).
+    /* number of bytes previously read into hdr or inbuf.
     ** (offset - writeOffset) is the number of ciphertext bytes read in but
     **     not yet deciphered.
     */
-    unsigned int offset; /* ssl 2 & 3 */
+    unsigned int offset;
 
     /* number of bytes to read in next call to ssl_DefRecv (recv) */
-    unsigned int remainder; /* ssl 2 & 3 */
-
-    /* Number of ciphertext bytes to read in after 2-byte SSL record header. */
-    unsigned int count; /* ssl2 only */
-
-    /* size of the final plaintext record.
-    ** == count - (recordPadding + MAC size)
-    */
-    unsigned int recordLen; /* ssl2 only */
+    unsigned int remainder;
 
-    /* number of bytes of padding to be removed after decrypting. */
-    /* This value is taken from the record's hdr[2], which means a too large
-     * value could crash us.
-     */
-    unsigned int recordPadding; /* ssl2 only */
-
-    /* plaintext DATA begins this many bytes into "buf".  */
-    unsigned int recordOffset; /* ssl2 only */
-
-    int encrypted; /* SSL2 session is now encrypted.  ssl2 only */
-
-    /* These next two values are used by SSL2 and SSL3.
-    ** DoRecv uses them to extract application data.
+    /* DoRecv uses the next two values to extract application data.
     ** The difference between writeOffset and readOffset is the amount of
     ** data available to the application.   Note that the actual offset of
     ** the data in "buf" is recordOffset (above), not readOffset.
     ** In the current implementation, this is made available before the
     ** MAC is checked!!
     */
     unsigned int readOffset; /* Spot where DATA reader (e.g. application
                                ** or handshake code) will read next.
                                ** Always zero for SSl3 application data.
                                */
     /* offset in buf/inbuf/hdr into which new data will be read from socket. */
     unsigned int writeOffset;
 
     /* Buffer for ssl3 to read (encrypted) data from the socket */
-    sslBuffer inbuf; /*recvBufLock*/ /* ssl3 only */
+    sslBuffer inbuf; /*recvBufLock*/
 
     /* The ssl[23]_GatherData functions read data into this buffer, rather
     ** than into buf or inbuf, while in the GS_HEADER state.
     ** The portion of the SSL record header put here always comes off the wire
     ** as plaintext, never ciphertext.
-    ** For SSL2, the plaintext portion is two bytes long.  For SSl3 it is 5.
-    ** For DTLS it is 13.
+    ** For SSL3/TLS, the plaintext portion is 5 bytes long. For DTLS it is 13.
     */
-    unsigned char hdr[13]; /* ssl 2 & 3 or dtls */
+    unsigned char hdr[13];
 
     /* Buffer for DTLS data read off the wire as a single datagram */
     sslBuffer dtlsPacket;
 
     /* the start of the buffered DTLS record in dtlsPacket */
     unsigned int dtlsPacketOffset;
 };
 
@@ -650,27 +605,16 @@ struct sslSessionIDStr {
 
     SSLSignType authAlgorithm;
     PRUint32 authKeyBits;
     SSLKEAType keaType;
     PRUint32 keaKeyBits;
 
     union {
         struct {
-            /* the V2 code depends upon the size of sessionID.  */
-            unsigned char sessionID[SSL2_SESSIONID_BYTES];
-
-            /* Stuff used to recreate key and read/write cipher objects */
-            SECItem masterKey; /* never wrapped */
-            int cipherType;
-            SECItem cipherArg;
-            int keyBits;
-            int secretKeyBits;
-        } ssl2;
-        struct {
             /* values that are copied into the server's on-disk SID cache. */
             PRUint8 sessionIDLength;
             SSL3Opaque sessionID[SSL3_SESSIONID_BYTES];
 
             ssl3CipherSuite cipherSuite;
             SSLCompressionMethod compression;
             int policy;
             ssl3SidKeys keys;
@@ -1138,120 +1082,60 @@ typedef struct SessionTicketStr {
  *     sendBuf in the ConnectInfo maintained by sslcon.c is used
  *              to hold handshake messages as they are accumulated
  */
 
 /*
 ** This is "ci", as in "ss->sec.ci".
 **
 ** Protection:  All the variables in here are protected by
-** firstHandshakeLock AND (in ssl3) ssl3HandshakeLock
+** firstHandshakeLock AND ssl3HandshakeLock
 */
 struct sslConnectInfoStr {
     /* outgoing handshakes appended to this. */
-    sslBuffer sendBuf; /*xmitBufLock*/ /* ssl 2 & 3 */
-
-    PRIPv6Addr peer;     /* ssl 2 & 3 */
-    unsigned short port; /* ssl 2 & 3 */
-
-    sslSessionID *sid; /* ssl 2 & 3 */
-
-    /* see CIS_HAVE defines below for the bit values in *elements. */
-    char elements;         /* ssl2 only */
-    char requiredElements; /* ssl2 only */
-    char sentElements;     /* ssl2 only */
-
-    char sentFinished; /* ssl2 only */
-
-    /* Length of server challenge.  Used by client when saving challenge */
-    int serverChallengeLen; /* ssl2 only */
-    /* type of authentication requested by server */
-    unsigned char authType; /* ssl2 only */
+    sslBuffer sendBuf; /*xmitBufLock*/
 
-    /* Challenge sent by client to server in client-hello message */
-    /* SSL3 gets a copy of this.  See ssl3_StartHandshakeHash().  */
-    unsigned char clientChallenge[SSL_MAX_CHALLENGE_BYTES]; /* ssl 2 & 3 */
-
-    /* Connection-id sent by server to client in server-hello message */
-    unsigned char connectionID[SSL_CONNECTIONID_BYTES]; /* ssl2 only */
-
-    /* Challenge sent by server to client in request-certificate message */
-    unsigned char serverChallenge[SSL_MAX_CHALLENGE_BYTES]; /* ssl2 only */
+    PRIPv6Addr peer;
+    unsigned short port;
 
-    /* Information kept to handle a request-certificate message */
-    unsigned char readKey[SSL_MAX_MASTER_KEY_BYTES];  /* ssl2 only */
-    unsigned char writeKey[SSL_MAX_MASTER_KEY_BYTES]; /* ssl2 only */
-    unsigned keySize;                                 /* ssl2 only */
+    sslSessionID *sid;
 };
 
-/* bit values for ci->elements, ci->requiredElements, sentElements. */
-#define CIS_HAVE_MASTER_KEY 0x01
-#define CIS_HAVE_CERTIFICATE 0x02
-#define CIS_HAVE_FINISHED 0x04
-#define CIS_HAVE_VERIFY 0x08
-
 /* Note: The entire content of this struct and whatever it points to gets
  * blown away by SSL_ResetHandshake().  This is "sec" as in "ss->sec".
  *
  * Unless otherwise specified below, the contents of this struct are
- * protected by firstHandshakeLock AND (in ssl3) ssl3HandshakeLock.
+ * protected by firstHandshakeLock AND ssl3HandshakeLock.
  */
 struct sslSecurityInfoStr {
-    sslSendFunc send; /*xmitBufLock*/   /* ssl 2 & 3 */
-    int isServer; /* Spec Lock?*/       /* ssl 2 & 3 */
-    sslBuffer writeBuf; /*xmitBufLock*/ /* ssl 2 & 3 */
+    int isServer;       /* Spec Lock?*/
+    sslBuffer writeBuf; /*xmitBufLock*/
 
-    int cipherType;             /* ssl 2 & 3 */
-    int keyBits;                /* ssl 2 & 3 */
-    int secretKeyBits;          /* ssl 2 & 3 */
-    CERTCertificate *localCert; /* ssl 2 & 3 */
-    CERTCertificate *peerCert;  /* ssl 2 & 3 */
-    SECKEYPublicKey *peerKey;   /* ssl3 only */
+    int cipherType;
+    int keyBits;
+    int secretKeyBits;
+    CERTCertificate *localCert;
+    CERTCertificate *peerCert;
+    SECKEYPublicKey *peerKey;
 
     SSLSignType authAlgorithm;
     PRUint32 authKeyBits;
     SSLKEAType keaType;
     PRUint32 keaKeyBits;
 
     /*
     ** Procs used for SID cache (nonce) management.
     ** Different implementations exist for clients/servers
     ** The lookup proc is only used for servers.  Baloney!
     */
-    sslSessionIDCacheFunc cache;     /* ssl 2 & 3 */
-    sslSessionIDUncacheFunc uncache; /* ssl 2 & 3 */
-
-    /*
-    ** everything below here is for ssl2 only.
-    ** This stuff is equivalent to SSL3's "spec", and is protected by the
-    ** same "Spec Lock" as used for SSL3's specs.
-    */
-    PRUint32 sendSequence; /*xmitBufLock*/ /* ssl2 only */
-    PRUint32 rcvSequence; /*recvBufLock*/  /* ssl2 only */
-
-    /* Hash information; used for one-way-hash functions (MD2, MD5, etc.) */
-    const SECHashObject *hash; /* Spec Lock */ /* ssl2 only */
-    void *hashcx; /* Spec Lock */              /* ssl2 only */
-
-    SECItem sendSecret; /* Spec Lock */ /* ssl2 only */
-    SECItem rcvSecret; /* Spec Lock */  /* ssl2 only */
-
-    /* Session cypher contexts; one for each direction */
-    void *readcx; /* Spec Lock */                    /* ssl2 only */
-    void *writecx; /* Spec Lock */                   /* ssl2 only */
-    SSLCipher enc; /* Spec Lock */                   /* ssl2 only */
-    SSLCipher dec; /* Spec Lock */                   /* ssl2 only */
-    void (*destroy)(void *, PRBool); /* Spec Lock */ /* ssl2 only */
-
-    /* Blocking information for the session cypher */
-    int blockShift; /* Spec Lock */ /* ssl2 only */
-    int blockSize; /* Spec Lock */  /* ssl2 only */
+    sslSessionIDCacheFunc cache;
+    sslSessionIDUncacheFunc uncache;
 
     /* These are used during a connection handshake */
-    sslConnectInfo ci; /* ssl 2 & 3 */
+    sslConnectInfo ci;
 };
 
 /*
 ** SSL Socket struct
 **
 ** Protection:  XXX
 */
 struct sslSocketStr {
@@ -1281,30 +1165,24 @@ struct sslSocketStr {
     unsigned long peerRequestedProtection; /* from old renegotiation */
 
     /* version of the protocol to use */
     SSL3ProtocolVersion version;
     SSL3ProtocolVersion clientHelloVersion; /* version sent in client hello. */
 
     sslSecurityInfo sec; /* not a pointer any more */
 
-    /* protected by firstHandshakeLock AND (in ssl3) ssl3HandshakeLock. */
-    const char *url; /* ssl 2 & 3 */
+    /* protected by firstHandshakeLock AND ssl3HandshakeLock. */
+    const char *url;
 
     sslHandshakeFunc handshake;         /*firstHandshakeLock*/
-    sslHandshakeFunc nextHandshake;     /*firstHandshakeLock*/
-    sslHandshakeFunc securityHandshake; /*firstHandshakeLock*/
 
     /* the following variable is only used with socks or other proxies. */
     char *peerID; /* String uniquely identifies target server. */
 
-    unsigned char *cipherSpecs;
-    unsigned int sizeCipherSpecs;
-    const unsigned char *preferredCipher;
-
     ssl3KeyPair *stepDownKeyPair; /* RSA step down keys */
 
     const ssl3DHParams *dheParams; /* DHE param */
     ssl3KeyPair *dheKeyPair;       /* DHE keys */
 
     /* Callbacks */
     SSLAuthCertificate authCertificate;
     void *authCertificateArg;
@@ -1352,20 +1230,16 @@ struct sslSocketStr {
     ** with this socket.
     */
     CERTCertDBHandle *dbHandle;
 
     PRThread *writerThread; /* thread holds SSL_LOCK_WRITER lock */
 
     PRUint16 shutdownHow; /* See ssl_SHUTDOWN defines below. */
 
-    PRUint16 allowedByPolicy;      /* copy of global policy bits. */
-    PRUint16 maybeAllowedByPolicy; /* copy of global policy bits. */
-    PRUint16 chosenPreference;     /* SSL2 cipher preferences. */
-
     sslHandshakingType handshaking;
 
     /* Gather object used for gathering data */
     sslGather gs; /*recvBufLock*/
 
     sslBuffer saveBuf;    /*xmitBufLock*/
     sslBuffer pendingBuf; /*xmitBufLock*/
 
@@ -1404,17 +1278,16 @@ extern NSSRWLock *ssl_global_data_lock;
 extern char ssl_debug;
 extern char ssl_trace;
 extern FILE *ssl_trace_iob;
 extern FILE *ssl_keylog_iob;
 extern CERTDistNames *ssl3_server_ca_list;
 extern PRUint32 ssl_sid_timeout;
 extern PRUint32 ssl3_sid_timeout;
 
-extern const char *const ssl_cipherName[];
 extern const char *const ssl3_cipherName[];
 
 extern sslSessionIDLookupFunc ssl_sid_lookup;
 extern sslSessionIDCacheFunc ssl_sid_cache;
 extern sslSessionIDUncacheFunc ssl_sid_uncache;
 
 /************************************************************************/
 
@@ -1469,45 +1342,38 @@ extern int ssl_SecureClose(sslSocket *ss
 
 /* Implementation of ops for secure socks case */
 extern int ssl_SecureSocksConnect(sslSocket *ss, const PRNetAddr *addr);
 extern PRFileDesc *ssl_SecureSocksAccept(sslSocket *ss, PRNetAddr *addr);
 extern PRFileDesc *ssl_FindTop(sslSocket *ss);
 
 /* Gather funcs. */
 extern sslGather *ssl_NewGather(void);
-extern SECStatus ssl_InitGather(sslGather *gs);
-extern void ssl_DestroyGather(sslGather *gs);
-extern int ssl2_GatherData(sslSocket *ss, sslGather *gs, int flags);
-extern int ssl2_GatherRecord(sslSocket *ss, int flags);
+extern SECStatus ssl3_InitGather(sslGather *gs);
+extern void ssl3_DestroyGather(sslGather *gs);
 extern SECStatus ssl_GatherRecord1stHandshake(sslSocket *ss);
 
-extern SECStatus ssl2_HandleClientHelloMessage(sslSocket *ss);
-extern SECStatus ssl2_HandleServerHelloMessage(sslSocket *ss);
-
 extern SECStatus ssl_CreateSecurityInfo(sslSocket *ss);
 extern SECStatus ssl_CopySecurityInfo(sslSocket *ss, sslSocket *os);
 extern void ssl_ResetSecurityInfo(sslSecurityInfo *sec, PRBool doMemset);
 extern void ssl_DestroySecurityInfo(sslSecurityInfo *sec);
 
 extern void ssl_PrintBuf(sslSocket *ss, const char *msg, const void *cp, int len);
-extern void ssl_DumpMsg(sslSocket *ss, unsigned char *bp, unsigned len);
 
 extern int ssl_SendSavedWriteData(sslSocket *ss);
 extern SECStatus ssl_SaveWriteData(sslSocket *ss,
                                    const void *p, unsigned int l);
-extern SECStatus ssl2_BeginClientHandshake(sslSocket *ss);
-extern SECStatus ssl2_BeginServerHandshake(sslSocket *ss);
+extern SECStatus ssl_BeginClientHandshake(sslSocket *ss);
+extern SECStatus ssl_BeginServerHandshake(sslSocket *ss);
 extern int ssl_Do1stHandshake(sslSocket *ss);
 
 extern SECStatus sslBuffer_Grow(sslBuffer *b, unsigned int newLen);
 extern SECStatus sslBuffer_Append(sslBuffer *b, const void *data,
                                   unsigned int len);
 
-extern void ssl2_UseClearSendFunc(sslSocket *ss);
 extern void ssl_ChooseSessionIDProcs(sslSecurityInfo *sec);
 
 extern void ssl3_InitCipherSpec(ssl3CipherSpec *spec);
 extern sslSessionID *ssl3_NewSessionID(sslSocket *ss, PRBool is_server);
 extern sslSessionID *ssl_LookupSID(const PRIPv6Addr *addr, PRUint16 port,
                                    const char *peerID, const char *urlSvrName);
 extern void ssl_FreeSID(sslSessionID *sid);
 
@@ -1681,33 +1547,31 @@ extern PRInt32 ssl3_SendRecord(sslSocket
  * in use.
  */
 #ifdef NSS_ENABLE_TLS_1_3
 #define SSL_LIBRARY_VERSION_MAX_SUPPORTED SSL_LIBRARY_VERSION_TLS_1_3
 #else
 #define SSL_LIBRARY_VERSION_MAX_SUPPORTED SSL_LIBRARY_VERSION_TLS_1_2
 #endif
 
-/* Rename this macro SSL_ALL_VERSIONS_DISABLED when SSL 2.0 is removed. */
-#define SSL3_ALL_VERSIONS_DISABLED(vrange) \
+#define SSL_ALL_VERSIONS_DISABLED(vrange) \
     ((vrange)->min == SSL_LIBRARY_VERSION_NONE)
 
 extern PRBool ssl3_VersionIsSupported(SSLProtocolVariant protocolVariant,
                                       SSL3ProtocolVersion version);
 
 extern SECStatus ssl3_KeyAndMacDeriveBypass(ssl3CipherSpec *pwSpec,
                                             const unsigned char *cr, const unsigned char *sr,
                                             PRBool isTLS, PRBool isExport);
 extern SECStatus ssl3_MasterSecretDeriveBypass(ssl3CipherSpec *pwSpec,
                                                const unsigned char *cr, const unsigned char *sr,
                                                const SECItem *pms, PRBool isTLS, PRBool isRSA);
 
 /* These functions are called from secnav, even though they're "private". */
 
-extern int ssl2_SendErrorMessage(struct sslSocketStr *ss, int error);
 extern int SSL_RestartHandshakeAfterCertReq(struct sslSocketStr *ss,
                                             CERTCertificate *cert,
                                             SECKEYPrivateKey *key,
                                             CERTCertificateList *certChain);
 extern sslSocket *ssl_FindSocket(PRFileDesc *fd);
 extern void ssl_FreeSocket(struct sslSocketStr *ssl);
 extern SECStatus SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level,
                                 SSL3AlertDescription desc);
@@ -1715,22 +1579,17 @@ extern SECStatus ssl3_DecodeError(sslSoc
 
 extern SECStatus ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error);
 
 /*
  * for dealing with SSL 3.0 clients sending SSL 2.0 format hellos
  */
 extern SECStatus ssl3_HandleV2ClientHello(
     sslSocket *ss, unsigned char *buffer, int length);
-extern SECStatus ssl3_StartHandshakeHash(
-    sslSocket *ss, unsigned char *buf, int length);
 
-/*
- * SSL3 specific routines
- */
 SECStatus ssl3_SendClientHello(sslSocket *ss, PRBool resending);
 
 /*
  * input into the SSL3 machinery from the actualy network reading code
  */
 SECStatus ssl3_HandleRecord(
     sslSocket *ss, SSL3Ciphertext *cipher, sslBuffer *out);
 
@@ -1804,36 +1663,26 @@ ECName ssl3_PubKey2ECName(SECKEYPublicKe
 
 ECName ssl3_GetCurveWithECKeyStrength(PRUint32 curvemsk, int requiredECCbits);
 ECName ssl3_GetCurveNameForServerSocket(sslSocket *ss);
 
 #endif /* NSS_DISABLE_ECC */
 
 extern SECStatus ssl3_CipherPrefSetDefault(ssl3CipherSuite which, PRBool on);
 extern SECStatus ssl3_CipherPrefGetDefault(ssl3CipherSuite which, PRBool *on);
-extern SECStatus ssl2_CipherPrefSetDefault(PRInt32 which, PRBool enabled);
-extern SECStatus ssl2_CipherPrefGetDefault(PRInt32 which, PRBool *enabled);
 
 extern SECStatus ssl3_CipherPrefSet(sslSocket *ss, ssl3CipherSuite which, PRBool on);
 extern SECStatus ssl3_CipherPrefGet(sslSocket *ss, ssl3CipherSuite which, PRBool *on);
-extern SECStatus ssl2_CipherPrefSet(sslSocket *ss, PRInt32 which, PRBool enabled);
-extern SECStatus ssl2_CipherPrefGet(sslSocket *ss, PRInt32 which, PRBool *enabled);
 
 extern SECStatus ssl3_SetPolicy(ssl3CipherSuite which, PRInt32 policy);
 extern SECStatus ssl3_GetPolicy(ssl3CipherSuite which, PRInt32 *policy);
-extern SECStatus ssl2_SetPolicy(PRInt32 which, PRInt32 policy);
-extern SECStatus ssl2_GetPolicy(PRInt32 which, PRInt32 *policy);
 
-extern void ssl2_InitSocketPolicy(sslSocket *ss);
 extern void ssl3_InitSocketPolicy(sslSocket *ss);
 extern void ssl3_InitCipherSpec(ssl3CipherSpec *spec);
 
-extern SECStatus ssl3_ConstructV2CipherSpecsHack(sslSocket *ss,
-                                                 unsigned char *cs, int *size);
-
 extern SECStatus ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache);
 extern SECStatus ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b,
                                              PRUint32 length);
 
 extern void ssl3_DestroySSL3Info(sslSocket *ss);
 
 extern SECStatus ssl3_NegotiateVersion(sslSocket *ss,
                                        SSL3ProtocolVersion peerVersion,
--- a/lib/ssl/sslinfo.c
+++ b/lib/ssl/sslinfo.c
@@ -45,21 +45,17 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLCh
     memset(&inf, 0, sizeof inf);
     inf.length = PR_MIN(sizeof inf, len);
 
     if (ss->opt.useSecurity && ss->enoughFirstHsDone) {
         sid = ss->sec.ci.sid;
         inf.protocolVersion = ss->version;
         inf.authKeyBits = ss->sec.authKeyBits;
         inf.keaKeyBits = ss->sec.keaKeyBits;
-        if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */
-            inf.cipherSuite = ss->sec.cipherType | 0xff00;
-            inf.compressionMethod = ssl_compression_null;
-            inf.compressionMethodName = "N/A";
-        } else if (ss->ssl3.initialized) { /* SSL3 and TLS */
+        if (ss->ssl3.initialized) {
             ssl_GetSpecReadLock(ss);
             /* XXX  The cipher suite should be in the specs and this
              * function should get it from cwSpec rather than from the "hs".
              * See bug 275744 comment 69 and bug 766137.
              */
             inf.cipherSuite = ss->ssl3.hs.cipher_suite;
             inf.compressionMethod = ss->ssl3.cwSpec->compression_method;
             ssl_ReleaseSpecReadLock(ss);
@@ -71,26 +67,20 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLCh
             inf.lastAccessTime = sid->lastAccessTime;
             inf.expirationTime = sid->expirationTime;
             inf.extendedMasterSecretUsed =
                 (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 ||
                  sid->u.ssl3.keys.extendedMasterSecretUsed)
                     ? PR_TRUE
                     : PR_FALSE;
 
-            if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */
-                inf.sessionIDLength = SSL2_SESSIONID_BYTES;
-                memcpy(inf.sessionID, sid->u.ssl2.sessionID,
-                       SSL2_SESSIONID_BYTES);
-            } else {
-                unsigned int sidLen = sid->u.ssl3.sessionIDLength;
-                sidLen = PR_MIN(sidLen, sizeof inf.sessionID);
-                inf.sessionIDLength = sidLen;
-                memcpy(inf.sessionID, sid->u.ssl3.sessionID, sidLen);
-            }
+            unsigned int sidLen = sid->u.ssl3.sessionIDLength;
+            sidLen = PR_MIN(sidLen, sizeof inf.sessionID);
+            inf.sessionIDLength = sidLen;
+            memcpy(inf.sessionID, sid->u.ssl3.sessionID, sidLen);
         }
     }
 
     memcpy(info, &inf, inf.length);
 
     return SECSuccess;
 }
 
@@ -112,21 +102,16 @@ SSL_GetPreliminaryChannelInfo(PRFileDesc
 
     ss = ssl_FindSocket(fd);
     if (!ss) {
         SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetPreliminaryChannelInfo",
                  SSL_GETPID(), fd));
         return SECFailure;
     }
 
-    if (ss->version < SSL_LIBRARY_VERSION_3_0) {
-        PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION);
-        return SECFailure;
-    }
-
     memset(&inf, 0, sizeof(inf));
     inf.length = PR_MIN(sizeof(inf), len);
 
     inf.valuesSet = ss->ssl3.hs.preliminaryInfo;
     inf.protocolVersion = ss->version;
     inf.cipherSuite = ss->ssl3.hs.cipher_suite;
 
     memcpy(info, &inf, inf.length);
@@ -219,17 +204,17 @@ static const SSLCipherSuiteInfo suiteInf
     {0,CS(TLS_RSA_EXPORT1024_WITH_RC4_56_SHA),    S_RSA, K_RSA, C_RC4, B_56,  M_SHA, 0, 1, 0 },
     {0,CS(TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA),   S_RSA, K_RSA, C_DES, B_DES, M_SHA, 0, 1, 0 },
     {0,CS(TLS_RSA_EXPORT_WITH_RC4_40_MD5),        S_RSA, K_RSA, C_RC4, B_40,  M_MD5, 0, 1, 0 },
     {0,CS(TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5),    S_RSA, K_RSA, C_RC2, B_40,  M_MD5, 0, 1, 0 },
     {0,CS(TLS_RSA_WITH_NULL_SHA256),              S_RSA, K_RSA, C_NULL,B_0,   M_SHA256, 0, 1, 0 },
     {0,CS(TLS_RSA_WITH_NULL_SHA),                 S_RSA, K_RSA, C_NULL,B_0,   M_SHA, 0, 1, 0 },
     {0,CS(TLS_RSA_WITH_NULL_MD5),                 S_RSA, K_RSA, C_NULL,B_0,   M_MD5, 0, 1, 0 },
 
-    #ifndef NSS_DISABLE_ECC
+#ifndef NSS_DISABLE_ECC
     /* ECC cipher suites */
     {0,CS(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_ECDHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0 },
     {0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256), S_ECDSA, K_ECDHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0 },
 
     {0,CS(TLS_ECDH_ECDSA_WITH_NULL_SHA),          S_ECDSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0 },
     {0,CS(TLS_ECDH_ECDSA_WITH_RC4_128_SHA),       S_ECDSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0 },
     {0,CS(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA),  S_ECDSA, K_ECDH, C_3DES, B_3DES, M_SHA, 1, 0, 0 },
     {0,CS(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA),   S_ECDSA, K_ECDH, C_AES, B_128, M_SHA, 1, 0, 0 },
@@ -251,25 +236,17 @@ static const SSLCipherSuiteInfo suiteInf
 
     {0,CS(TLS_ECDHE_RSA_WITH_NULL_SHA),           S_RSA, K_ECDHE, C_NULL, B_0, M_SHA, 0, 0, 0 },
     {0,CS(TLS_ECDHE_RSA_WITH_RC4_128_SHA),        S_RSA, K_ECDHE, C_RC4, B_128, M_SHA, 0, 0, 0 },
     {0,CS(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA),   S_RSA, K_ECDHE, C_3DES, B_3DES, M_SHA, 1, 0, 0 },
     {0,CS(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA),    S_RSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0 },
     {0,CS(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256), S_RSA, K_ECDHE, C_AES, B_128, M_SHA256, 1, 0, 0 },
     {0,CS(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA),    S_RSA, K_ECDHE, C_AES, B_256, M_SHA, 1, 0, 0 },
     {0,CS(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256), S_RSA, K_ECDHE, C_CHACHA20, B_256, M_AEAD_128, 0, 0, 0 },
-    #endif /* NSS_DISABLE_ECC */
-
-    /* SSL 2 table */
-    {0,CK(SSL_CK_RC4_128_WITH_MD5),               S_RSA, K_RSA, C_RC4, B_128, M_MD5, 0, 0, 0 },
-    {0,CK(SSL_CK_RC2_128_CBC_WITH_MD5),           S_RSA, K_RSA, C_RC2, B_128, M_MD5, 0, 0, 0 },
-    {0,CK(SSL_CK_DES_192_EDE3_CBC_WITH_MD5),      S_RSA, K_RSA, C_3DES,B_3DES,M_MD5, 0, 0, 0 },
-    {0,CK(SSL_CK_DES_64_CBC_WITH_MD5),            S_RSA, K_RSA, C_DES, B_DES, M_MD5, 0, 0, 0 },
-    {0,CK(SSL_CK_RC4_128_EXPORT40_WITH_MD5),      S_RSA, K_RSA, C_RC4, B_40,  M_MD5, 0, 1, 0 },
-    {0,CK(SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5),  S_RSA, K_RSA, C_RC2, B_40,  M_MD5, 0, 1, 0 }
+#endif /* NSS_DISABLE_ECC */
 };
 /* clang-format on */
 
 #define NUM_SUITEINFOS ((sizeof suiteInfo) / (sizeof suiteInfo[0]))
 
 SECStatus
 SSL_GetCipherSuiteInfo(PRUint16 cipherSuite,
                        SSLCipherSuiteInfo *info, PRUintn len)
--- a/lib/ssl/sslnonce.c
+++ b/lib/ssl/sslnonce.c
@@ -166,34 +166,29 @@ lock_cache(void)
  */
 static void
 ssl_DestroySID(sslSessionID *sid)
 {
     SSL_TRC(8, ("SSL: destroy sid: sid=0x%x cached=%d", sid, sid->cached));
     PORT_Assert(sid->references == 0);
     PORT_Assert(sid->cached != in_client_cache);
 
-    if (sid->version < SSL_LIBRARY_VERSION_3_0) {
-        SECITEM_ZfreeItem(&sid->u.ssl2.masterKey, PR_FALSE);
-        SECITEM_ZfreeItem(&sid->u.ssl2.cipherArg, PR_FALSE);
-    } else {
-        if (sid->u.ssl3.locked.sessionTicket.ticket.data) {
-            SECITEM_FreeItem(&sid->u.ssl3.locked.sessionTicket.ticket,
-                             PR_FALSE);
-        }
-        if (sid->u.ssl3.srvName.data) {
-            SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE);
-        }
-        if (sid->u.ssl3.signedCertTimestamps.data) {
-            SECITEM_FreeItem(&sid->u.ssl3.signedCertTimestamps, PR_FALSE);
-        }
+    if (sid->u.ssl3.locked.sessionTicket.ticket.data) {
+        SECITEM_FreeItem(&sid->u.ssl3.locked.sessionTicket.ticket,
+                         PR_FALSE);
+    }
+    if (sid->u.ssl3.srvName.data) {
+        SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE);
+    }
+    if (sid->u.ssl3.signedCertTimestamps.data) {
+        SECITEM_FreeItem(&sid->u.ssl3.signedCertTimestamps, PR_FALSE);
+    }
 
-        if (sid->u.ssl3.lock) {
-            PR_DestroyRWLock(sid->u.ssl3.lock);
-        }
+    if (sid->u.ssl3.lock) {
+        PR_DestroyRWLock(sid->u.ssl3.lock);
     }
 
     if (sid->peerID != NULL)
         PORT_Free((void *)sid->peerID); /* CONST */
 
     if (sid->urlSvrName != NULL)
         PORT_Free((void *)sid->urlSvrName); /* CONST */
 
@@ -281,18 +276,17 @@ ssl_LookupSID(const PRIPv6Addr *addr, PR
             ssl_FreeLockedSID(sid);                                 /* drop ref count, free. */
         } else if (!memcmp(&sid->addr, addr, sizeof(PRIPv6Addr)) && /* server IP addr matches */
                    (sid->port == port) &&                           /* server port matches */
                    /* proxy (peerID) matches */
                    (((peerID == NULL) && (sid->peerID == NULL)) ||
                     ((peerID != NULL) && (sid->peerID != NULL) &&
                      PORT_Strcmp(sid->peerID, peerID) == 0)) &&
                    /* is cacheable */
-                   (sid->version < SSL_LIBRARY_VERSION_3_0 ||
-                    sid->u.ssl3.keys.resumable) &&
+                   (sid->u.ssl3.keys.resumable) &&
                    /* server hostname matches. */
                    (sid->urlSvrName != NULL) &&
                    (0 == PORT_Strcmp(urlSvrName, sid->urlSvrName))) {
             /* Hit */
             sid->lastAccessTime = now;
             sid->references++;
             break;
         } else {
@@ -321,47 +315,36 @@ CacheSID(sslSessionID *sid)
                 sid->addr.pr_s6_addr32[3], sid->port, sid->creationTime,
                 sid->cached));
 
     if (!sid->urlSvrName) {
         /* don't cache this SID because it can never be matched */
         return;
     }
 
-    /* XXX should be different trace for version 2 vs. version 3 */
-    if (sid->version < SSL_LIBRARY_VERSION_3_0) {
-        expirationPeriod = ssl_sid_timeout;
-        PRINT_BUF(8, (0, "sessionID:",
-                      sid->u.ssl2.sessionID, sizeof(sid->u.ssl2.sessionID)));
-        PRINT_BUF(8, (0, "masterKey:",
-                      sid->u.ssl2.masterKey.data, sid->u.ssl2.masterKey.len));
-        PRINT_BUF(8, (0, "cipherArg:",
-                      sid->u.ssl2.cipherArg.data, sid->u.ssl2.cipherArg.len));
-    } else {
-        if (sid->u.ssl3.sessionIDLength == 0 &&
-            sid->u.ssl3.locked.sessionTicket.ticket.data == NULL)
-            return;
+    if (sid->u.ssl3.sessionIDLength == 0 &&
+        sid->u.ssl3.locked.sessionTicket.ticket.data == NULL)
+        return;
 
-        /* Client generates the SessionID if this was a stateless resume. */
-        if (sid->u.ssl3.sessionIDLength == 0) {
-            SECStatus rv;
-            rv = PK11_GenerateRandom(sid->u.ssl3.sessionID,
-                                     SSL3_SESSIONID_BYTES);
-            if (rv != SECSuccess)
-                return;
-            sid->u.ssl3.sessionIDLength = SSL3_SESSIONID_BYTES;
-        }
-        expirationPeriod = ssl3_sid_timeout;
-        PRINT_BUF(8, (0, "sessionID:",
-                      sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength));
+    /* Client generates the SessionID if this was a stateless resume. */
+    if (sid->u.ssl3.sessionIDLength == 0) {
+        SECStatus rv;
+        rv = PK11_GenerateRandom(sid->u.ssl3.sessionID,
+                                 SSL3_SESSIONID_BYTES);
+        if (rv != SECSuccess)
+            return;
+        sid->u.ssl3.sessionIDLength = SSL3_SESSIONID_BYTES;
+    }
+    expirationPeriod = ssl3_sid_timeout;
+    PRINT_BUF(8, (0, "sessionID:",
+                  sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength));
 
-        sid->u.ssl3.lock = PR_NewRWLock(PR_RWLOCK_RANK_NONE, NULL);
-        if (!sid->u.ssl3.lock) {
-            return;
-        }
+    sid->u.ssl3.lock = PR_NewRWLock(PR_RWLOCK_RANK_NONE, NULL);
+    if (!sid->u.ssl3.lock) {
+        return;
     }
     PORT_Assert(sid->creationTime != 0 && sid->expirationTime != 0);
     if (!sid->creationTime)
         sid->lastAccessTime = sid->creationTime = ssl_Time();
     if (!sid->expirationTime)
         sid->expirationTime = sid->creationTime + expirationPeriod;
 
     /*
@@ -388,29 +371,21 @@ UncacheSID(sslSessionID *zap)
     sslSessionID **sidp = &cache;
     sslSessionID *sid;
 
     if (zap->cached != in_client_cache) {
         return;
     }
 
     SSL_TRC(8, ("SSL: Uncache: zap=0x%x cached=%d addr=0x%08x%08x%08x%08x port=0x%04x "
-                "time=%x cipher=%d",
+                "time=%x cipherSuite=%d",
                 zap, zap->cached, zap->addr.pr_s6_addr32[0],
                 zap->addr.pr_s6_addr32[1], zap->addr.pr_s6_addr32[2],
                 zap->addr.pr_s6_addr32[3], zap->port, zap->creationTime,
-                zap->u.ssl2.cipherType));
-    if (zap->version < SSL_LIBRARY_VERSION_3_0) {
-        PRINT_BUF(8, (0, "sessionID:",
-                      zap->u.ssl2.sessionID, sizeof(zap->u.ssl2.sessionID)));
-        PRINT_BUF(8, (0, "masterKey:",
-                      zap->u.ssl2.masterKey.data, zap->u.ssl2.masterKey.len));
-        PRINT_BUF(8, (0, "cipherArg:",
-                      zap->u.ssl2.cipherArg.data, zap->u.ssl2.cipherArg.len));
-    }
+                zap->u.ssl3.cipherSuite));
 
     /* See if it's in the cache, if so nuke it */
     while ((sid = *sidp) != 0) {
         if (sid == zap) {
             /*
             ** Bingo. Reduce reference count by one so that when
             ** everyone is done with the sid we can free it up.
             */
--- a/lib/ssl/sslproto.h
+++ b/lib/ssl/sslproto.h
@@ -1,11 +1,11 @@
 /*
  * Various and sundry protocol constants. DON'T CHANGE THESE. These values
- * are mostly defined by the SSL2, SSL3, or TLS protocol specifications.
+ * are mostly defined by the SSL3 or TLS protocol specifications.
  * Cipher kinds and ciphersuites are part of the public API.
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __sslproto_h_
 #define __sslproto_h_
@@ -28,72 +28,29 @@
 /* deprecated old name */
 #define SSL_LIBRARY_VERSION_3_1_TLS SSL_LIBRARY_VERSION_TLS_1_0
 
 /* The DTLS versions used in the spec */
 #define SSL_LIBRARY_VERSION_DTLS_1_0_WIRE       ((~0x0100) & 0xffff)
 #define SSL_LIBRARY_VERSION_DTLS_1_2_WIRE       ((~0x0102) & 0xffff)
 #define SSL_LIBRARY_VERSION_DTLS_1_3_WIRE       ((~0x0103) & 0xffff)
 
-/* Header lengths of some of the messages */
-#define SSL_HL_ERROR_HBYTES                     3
-#define SSL_HL_CLIENT_HELLO_HBYTES              9
-#define SSL_HL_CLIENT_MASTER_KEY_HBYTES         10
-#define SSL_HL_CLIENT_FINISHED_HBYTES           1
-#define SSL_HL_SERVER_HELLO_HBYTES              11
-#define SSL_HL_SERVER_VERIFY_HBYTES             1
-#define SSL_HL_SERVER_FINISHED_HBYTES           1
-#define SSL_HL_REQUEST_CERTIFICATE_HBYTES       2
-#define SSL_HL_CLIENT_CERTIFICATE_HBYTES        6
-
-/* Security handshake protocol codes */
-#define SSL_MT_ERROR                            0
-#define SSL_MT_CLIENT_HELLO                     1
-#define SSL_MT_CLIENT_MASTER_KEY                2
-#define SSL_MT_CLIENT_FINISHED                  3
-#define SSL_MT_SERVER_HELLO                     4
-#define SSL_MT_SERVER_VERIFY                    5
-#define SSL_MT_SERVER_FINISHED                  6
-#define SSL_MT_REQUEST_CERTIFICATE              7
-#define SSL_MT_CLIENT_CERTIFICATE               8
-
 /* Certificate types */
 #define SSL_CT_X509_CERTIFICATE                 0x01
 #if 0 /* XXX Not implemented yet */
 #define SSL_PKCS6_CERTIFICATE                   0x02
 #endif
 #define SSL_AT_MD5_WITH_RSA_ENCRYPTION          0x01
 
 /* Error codes */
 #define SSL_PE_NO_CYPHERS                       0x0001
 #define SSL_PE_NO_CERTIFICATE                   0x0002
 #define SSL_PE_BAD_CERTIFICATE                  0x0004
 #define SSL_PE_UNSUPPORTED_CERTIFICATE_TYPE     0x0006
 
-/* Cypher kinds (not the spec version!) */
-#define SSL_CK_RC4_128_WITH_MD5                 0x01
-#define SSL_CK_RC4_128_EXPORT40_WITH_MD5        0x02
-#define SSL_CK_RC2_128_CBC_WITH_MD5             0x03
-#define SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5    0x04
-#define SSL_CK_IDEA_128_CBC_WITH_MD5            0x05
-#define SSL_CK_DES_64_CBC_WITH_MD5              0x06
-#define SSL_CK_DES_192_EDE3_CBC_WITH_MD5        0x07
-
-/* Cipher enables.  These are used only for SSL_EnableCipher
- * These values define the SSL2 suites, and do not colide with the
- * SSL3 Cipher suites defined below.
- */
-#define SSL_EN_RC4_128_WITH_MD5                 0xFF01
-#define SSL_EN_RC4_128_EXPORT40_WITH_MD5        0xFF02
-#define SSL_EN_RC2_128_CBC_WITH_MD5             0xFF03
-#define SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5    0xFF04
-#define SSL_EN_IDEA_128_CBC_WITH_MD5            0xFF05
-#define SSL_EN_DES_64_CBC_WITH_MD5              0xFF06
-#define SSL_EN_DES_192_EDE3_CBC_WITH_MD5        0xFF07
-
 /* Deprecated SSL 3.0 & libssl names replaced by IANA-registered TLS names. */
 #ifndef SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES
 #define SSL_NULL_WITH_NULL_NULL                TLS_NULL_WITH_NULL_NULL
 #define SSL_RSA_WITH_NULL_MD5                  TLS_RSA_WITH_NULL_MD5
 #define SSL_RSA_WITH_NULL_SHA                  TLS_RSA_WITH_NULL_SHA
 #define SSL_RSA_EXPORT_WITH_RC4_40_MD5         TLS_RSA_EXPORT_WITH_RC4_40_MD5
 #define SSL_RSA_WITH_RC4_128_MD5               TLS_RSA_WITH_RC4_128_MD5
 #define SSL_RSA_WITH_RC4_128_SHA               TLS_RSA_WITH_RC4_128_SHA
@@ -276,11 +233,45 @@
 
 /* DTLS-SRTP cipher suites from RFC 5764 */
 /* If you modify this, also modify MAX_DTLS_SRTP_CIPHER_SUITES in sslimpl.h */
 #define SRTP_AES128_CM_HMAC_SHA1_80             0x0001
 #define SRTP_AES128_CM_HMAC_SHA1_32             0x0002
 #define SRTP_NULL_HMAC_SHA1_80                  0x0005
 #define SRTP_NULL_HMAC_SHA1_32                  0x0006
 
+/* DO NOT USE. (deprecated, will be removed) */
+#define SSL_HL_ERROR_HBYTES                     3
+#define SSL_HL_CLIENT_HELLO_HBYTES              9
+#define SSL_HL_CLIENT_MASTER_KEY_HBYTES         10
+#define SSL_HL_CLIENT_FINISHED_HBYTES           1
+#define SSL_HL_SERVER_HELLO_HBYTES              11
+#define SSL_HL_SERVER_VERIFY_HBYTES             1
+#define SSL_HL_SERVER_FINISHED_HBYTES           1
+#define SSL_HL_REQUEST_CERTIFICATE_HBYTES       2
+#define SSL_HL_CLIENT_CERTIFICATE_HBYTES        6
+#define SSL_MT_ERROR                            0
+#define SSL_MT_CLIENT_HELLO                     1
+#define SSL_MT_CLIENT_MASTER_KEY                2
+#define SSL_MT_CLIENT_FINISHED                  3
+#define SSL_MT_SERVER_HELLO                     4
+#define SSL_MT_SERVER_VERIFY                    5
+#define SSL_MT_SERVER_FINISHED                  6
+#define SSL_MT_REQUEST_CERTIFICATE              7
+#define SSL_MT_CLIENT_CERTIFICATE               8
+#define SSL_CK_RC4_128_WITH_MD5                 0x01
+#define SSL_CK_RC4_128_EXPORT40_WITH_MD5        0x02
+#define SSL_CK_RC2_128_CBC_WITH_MD5             0x03
+#define SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5    0x04
+#define SSL_CK_IDEA_128_CBC_WITH_MD5            0x05
+#define SSL_CK_DES_64_CBC_WITH_MD5              0x06
+#define SSL_CK_DES_192_EDE3_CBC_WITH_MD5        0x07
+#define SSL_EN_RC4_128_WITH_MD5                 0xFF01
+#define SSL_EN_RC4_128_EXPORT40_WITH_MD5        0xFF02
+#define SSL_EN_RC2_128_CBC_WITH_MD5             0xFF03
+#define SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5    0xFF04
+#define SSL_EN_IDEA_128_CBC_WITH_MD5            0xFF05
+#define SSL_EN_DES_64_CBC_WITH_MD5              0xFF06
+#define SSL_EN_DES_192_EDE3_CBC_WITH_MD5        0xFF07
+
 /* clang-format on */
 
 #endif /* __sslproto_h_ */
--- a/lib/ssl/sslsecur.c
+++ b/lib/ssl/sslsecur.c
@@ -26,39 +26,21 @@
  *
  * In sslsocks.c:
  *  SocksGatherRecord
  *  SocksHandleReply
  *  SocksStartGather
  *
  * In sslcon.c:
  *  ssl_GatherRecord1stHandshake
- *  ssl2_HandleClientSessionKeyMessage
- *  ssl2_HandleMessage
- *  ssl2_HandleVerifyMessage
- *  ssl2_BeginClientHandshake
- *  ssl2_BeginServerHandshake
- *  ssl2_HandleClientHelloMessage
- *  ssl2_HandleServerHelloMessage
+ *  ssl_BeginClientHandshake
+ *  ssl_BeginServerHandshake
  *
- * The ss->handshake function returns SECWouldBlock under these conditions:
- * 1.   ssl_GatherRecord1stHandshake called ssl2_GatherData which read in
- *  the beginning of an SSL v3 hello message and returned SECWouldBlock
- *  to switch to SSL v3 handshake processing.
- *
- * 2.   ssl2_HandleClientHelloMessage discovered version 3.0 in the incoming
- *  v2 client hello msg, and called ssl3_HandleV2ClientHello which
- *  returned SECWouldBlock.
- *
- * 3.   SECWouldBlock was returned by one of the callback functions, via
- *  one of these paths:
- * -    ssl2_HandleMessage() -> ssl2_HandleRequestCertificate() ->
- *  ss->getClientAuthData()
- *
- * -    ssl2_HandleServerHelloMessage() -> ss->handleBadCert()
+ * The ss->handshake function returns SECWouldBlock if it was returned by
+ *  one of the callback functions, via one of these paths:
  *
  * -    ssl_GatherRecord1stHandshake() -> ssl3_GatherCompleteHandshake() ->
  *  ssl3_HandleRecord() -> ssl3_HandleHandshake() ->
  *  ssl3_HandleHandshakeMessage() -> ssl3_HandleCertificate() ->
  *  ss->handleBadCert()
  *
  * -    ssl_GatherRecord1stHandshake() -> ssl3_GatherCompleteHandshake() ->
  *  ssl3_HandleRecord() -> ssl3_HandleHandshake() ->
@@ -73,50 +55,25 @@
  *              ssl_SocksSend       in sslsocks.c
  *
  * Caller must hold the (write) handshakeLock.
  */
 int
 ssl_Do1stHandshake(sslSocket *ss)
 {
     int rv = SECSuccess;
-    int loopCount = 0;
 
-    do {
+    while (ss->handshake && rv == SECSuccess) {
         PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
         PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss));
         PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss));
         PORT_Assert(ss->opt.noLocks || !ssl_HaveSSL3HandshakeLock(ss));
 
-        if (ss->handshake == 0) {
-            /* Previous handshake finished. Switch to next one */
-            ss->handshake = ss->nextHandshake;
-            ss->nextHandshake = 0;
-        }
-        if (ss->handshake == 0) {
-            /* Previous handshake finished. Switch to security handshake */
-            ss->handshake = ss->securityHandshake;
-            ss->securityHandshake = 0;
-        }
-        if (ss->handshake == 0) {
-            /* for v3 this is done in ssl3_FinishHandshake */
-            if (!ss->firstHsDone && ss->version < SSL_LIBRARY_VERSION_3_0) {
-                ssl_GetRecvBufLock(ss);
-                ss->gs.recordLen = 0;
-                ssl_FinishHandshake(ss);
-                ssl_ReleaseRecvBufLock(ss);
-            }
-            break;
-        }
         rv = (*ss->handshake)(ss);
-        ++loopCount;
-        /* This code must continue to loop on SECWouldBlock,
-         * or any positive value.   See XXX_1 comments.
-         */
-    } while (rv != SECFailure); /* was (rv >= 0); XXX_1 */
+    };
 
     PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss));
     PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss));
     PORT_Assert(ss->opt.noLocks || !ssl_HaveSSL3HandshakeLock(ss));
 
     if (rv == SECWouldBlock) {
         PORT_SetError(PR_WOULD_BLOCK_ERROR);
         rv = SECFailure;
@@ -133,19 +90,18 @@ ssl_FinishHandshake(sslSocket *ss)
     SSL_TRC(3, ("%d: SSL[%d]: handshake is completed", SSL_GETPID(), ss->fd));
 
     ss->firstHsDone = PR_TRUE;
     ss->enoughFirstHsDone = PR_TRUE;
     ss->gs.writeOffset = 0;
     ss->gs.readOffset = 0;
 
     if (ss->handshakeCallback) {
-        PORT_Assert(ss->version < SSL_LIBRARY_VERSION_3_0 ||
-                    (ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) ==
-                        ssl_preinfo_all);
+        PORT_Assert((ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) ==
+                    ssl_preinfo_all);
         (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
     }
 }
 
 /*
  * Handshake function that blocks.  Used to force a
  * retry on a connection on the next read/write.
  */
@@ -159,17 +115,16 @@ ssl3_AlwaysBlock(sslSocket *ss)
 /*
  * set the initial handshake state machine to block
  */
 void
 ssl3_SetAlwaysBlock(sslSocket *ss)
 {
     if (!ss->firstHsDone) {
         ss->handshake = ssl3_AlwaysBlock;
-        ss->nextHandshake = 0;
     }
 }
 
 static SECStatus
 ssl_SetTimeout(PRFileDesc *fd, PRIntervalTime timeout)
 {
     sslSocket *ss;
 
@@ -214,27 +169,25 @@ SSL_ResetHandshake(PRFileDesc *s, PRBool
     SSL_LOCK_WRITER(ss);
 
     /* Reset handshake state */
     ssl_Get1stHandshakeLock(ss);
 
     ss->firstHsDone = PR_FALSE;
     ss->enoughFirstHsDone = PR_FALSE;
     if (asServer) {
-        ss->handshake = ssl2_BeginServerHandshake;
+        ss->handshake = ssl_BeginServerHandshake;
         ss->handshaking = sslHandshakingAsServer;
     } else {
-        ss->handshake = ssl2_BeginClientHandshake;
+        ss->handshake = ssl_BeginClientHandshake;
         ss->handshaking = sslHandshakingAsClient;
     }
-    ss->nextHandshake = 0;
-    ss->securityHandshake = 0;
 
     ssl_GetRecvBufLock(ss);
-    status = ssl_InitGather(&ss->gs);
+    status = ssl3_InitGather(&ss->gs);
     ssl_ReleaseRecvBufLock(ss);
 
     ssl_GetSSL3HandshakeLock(ss);
     ss->ssl3.hs.canFalseStart = PR_FALSE;
     ss->ssl3.hs.restartTarget = NULL;
 
     /*
     ** Blow away old security state and get a fresh setup.
@@ -273,25 +226,19 @@ SSL_ReHandshake(PRFileDesc *fd, PRBool f
         return SECFailure;
     }
 
     if (!ss->opt.useSecurity)
         return SECSuccess;
 
     ssl_Get1stHandshakeLock(ss);
 
-    /* SSL v2 protocol does not support subsequent handshakes. */
-    if (ss->version < SSL_LIBRARY_VERSION_3_0) {
-        PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
-        rv = SECFailure;
-    } else {
-        ssl_GetSSL3HandshakeLock(ss);
-        rv = ssl3_RedoHandshake(ss, flushCache); /* force full handshake. */
-        ssl_ReleaseSSL3HandshakeLock(ss);
-    }
+    ssl_GetSSL3HandshakeLock(ss);
+    rv = ssl3_RedoHandshake(ss, flushCache); /* force full handshake. */
+    ssl_ReleaseSSL3HandshakeLock(ss);
 
     ssl_Release1stHandshakeLock(ss);
 
     return rv;
 }
 
 /*
 ** Same as above, but with an I/O timeout.
@@ -392,36 +339,30 @@ SSL_RecommendedCanFalseStart(PRFileDesc 
         return SECFailure;
     }
 
     if (!ss->ssl3.initialized) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
     }
 
-    if (ss->version < SSL_LIBRARY_VERSION_3_0) {
-        PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
-        return SECFailure;
-    }
-
     /* Require a forward-secret key exchange. */
     *canFalseStart = ss->ssl3.hs.kea_def->kea == kea_dhe_dss ||
                      ss->ssl3.hs.kea_def->kea == kea_dhe_rsa ||
                      ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa ||
                      ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa;
 
     return SECSuccess;
 }
 
 /* Try to make progress on an SSL handshake by attempting to read the
 ** next handshake from the peer, and sending any responses.
 ** For non-blocking sockets, returns PR_ERROR_WOULD_BLOCK  if it cannot
 ** read the next handshake from the underlying socket.
-** For SSLv2, returns when handshake is complete or fatal error occurs.
-** For SSLv3, returns when handshake is complete, or application data has
+** Returns when handshake is complete, or application data has
 ** arrived that must be taken by application before handshake can continue,
 ** or a fatal error occurs.
 ** Application should use handshake completion callback to tell which.
 */
 SECStatus
 SSL_ForceHandshake(PRFileDesc *fd)
 {
     sslSocket *ss;
@@ -460,22 +401,19 @@ SSL_ForceHandshake(PRFileDesc *fd)
         ssl_ReleaseRecvBufLock(ss);
         if (gatherResult > 0) {
             rv = SECSuccess;
         } else if (gatherResult == 0) {
             PORT_SetError(PR_END_OF_FILE_ERROR);
         } else if (gatherResult == SECWouldBlock) {
             PORT_SetError(PR_WOULD_BLOCK_ERROR);
         }
-    } else if (!ss->firstHsDone) {
+    } else {
+        PORT_Assert(!ss->firstHsDone);
         rv = ssl_Do1stHandshake(ss);
-    } else {
-        /* tried to force handshake on an SSL 2 socket that has
-        ** already completed the handshake. */
-        rv = SECSuccess; /* just pretend we did it. */
     }
 
     ssl_Release1stHandshakeLock(ss);
 
     return rv;
 }
 
 /*
@@ -585,18 +523,17 @@ ssl_SendSavedWriteData(sslSocket *ss)
 
 /*
 ** Receive some application data on a socket.  Reads SSL records from the input
 ** stream, decrypts them and then copies them to the output buffer.
 ** Called from ssl_SecureRecv() below.
 **
 ** Caller does NOT hold 1stHandshakeLock because that handshake is over.
 ** Caller doesn't call this until initial handshake is complete.
-** For SSLv2, there is no subsequent handshake.
-** For SSLv3, the call to ssl3_GatherAppDataRecord may encounter handshake
+** The call to ssl3_GatherAppDataRecord may encounter handshake
 ** messages from a subsequent handshake.
 **
 ** This code is similar to, and easily confused with,
 **   ssl_GatherRecord1stHandshake() in sslcon.c
 */
 static int
 DoRecv(sslSocket *ss, unsigned char *out, int len, int flags)
 {
@@ -606,24 +543,18 @@ DoRecv(sslSocket *ss, unsigned char *out
 
     /* ssl3_GatherAppDataRecord may call ssl_FinishHandshake, which needs the
      * 1stHandshakeLock. */
     ssl_Get1stHandshakeLock(ss);
     ssl_GetRecvBufLock(ss);
 
     available = ss->gs.writeOffset - ss->gs.readOffset;
     if (available == 0) {
-        /* Get some more data */
-        if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
-            /* Wait for application data to arrive.  */
-            rv = ssl3_GatherAppDataRecord(ss, 0);
-        } else {
-            /* See if we have a complete record */
-            rv = ssl2_GatherRecord(ss, 0);
-        }
+        /* Wait for application data to arrive.  */
+        rv = ssl3_GatherAppDataRecord(ss, 0);
         if (rv <= 0) {
             if (rv == 0) {
                 /* EOF */
                 SSL_TRC(10, ("%d: SSL[%d]: ssl_recv EOF",
                              SSL_GETPID(), ss->fd));
                 goto done;
             }
             if ((rv != SECWouldBlock) &&
@@ -943,111 +874,49 @@ loser:
 
 /************************************************************************/
 
 SECStatus
 ssl_CreateSecurityInfo(sslSocket *ss)
 {
     SECStatus status;
 
-    /* initialize sslv2 socket to send data in the clear. */
-    ssl2_UseClearSendFunc(ss);
-
-    ss->sec.blockSize = 1;
-    ss->sec.blockShift = 0;
-
     ssl_GetXmitBufLock(ss);
     status = sslBuffer_Grow(&ss->sec.writeBuf, 4096);
     ssl_ReleaseXmitBufLock(ss);
 
     return status;
 }
 
 SECStatus
 ssl_CopySecurityInfo(sslSocket *ss, sslSocket *os)
 {
-    ss->sec.send = os->sec.send;
     ss->sec.isServer = os->sec.isServer;
     ss->sec.keyBits = os->sec.keyBits;
     ss->sec.secretKeyBits = os->sec.secretKeyBits;
 
     ss->sec.peerCert = CERT_DupCertificate(os->sec.peerCert);
     if (os->sec.peerCert && !ss->sec.peerCert)
         goto loser;
 
     ss->sec.cache = os->sec.cache;
     ss->sec.uncache = os->sec.uncache;
 
-    /* we don't dup the connection info. */
-
-    ss->sec.sendSequence = os->sec.sendSequence;
-    ss->sec.rcvSequence = os->sec.rcvSequence;
-
-    if (os->sec.hash && os->sec.hashcx) {
-        ss->sec.hash = os->sec.hash;
-        ss->sec.hashcx = os->sec.hash->clone(os->sec.hashcx);
-        if (os->sec.hashcx && !ss->sec.hashcx)
-            goto loser;
-    } else {
-        ss->sec.hash = NULL;
-        ss->sec.hashcx = NULL;
-    }
-
-    if (SECITEM_CopyItem(0, &ss->sec.sendSecret, &os->sec.sendSecret))
-        goto loser;
-    if (SECITEM_CopyItem(0, &ss->sec.rcvSecret, &os->sec.rcvSecret))
-        goto loser;
-
-    /* XXX following code is wrong if either cx != 0 */
-    PORT_Assert(os->sec.readcx == 0);
-    PORT_Assert(os->sec.writecx == 0);
-    ss->sec.readcx = os->sec.readcx;
-    ss->sec.writecx = os->sec.writecx;
-    ss->sec.destroy = 0;
-
-    ss->sec.enc = os->sec.enc;
-    ss->sec.dec = os->sec.dec;
-
-    ss->sec.blockShift = os->sec.blockShift;
-    ss->sec.blockSize = os->sec.blockSize;
-
     return SECSuccess;
 
 loser:
     return SECFailure;
 }
 
 /* Reset sec back to its initial state.
 ** Caller holds any relevant locks.
 */
 void
 ssl_ResetSecurityInfo(sslSecurityInfo *sec, PRBool doMemset)
 {
-    /* Destroy MAC */
-    if (sec->hash && sec->hashcx) {
-        (*sec->hash->destroy)(sec->hashcx, PR_TRUE);
-        sec->hashcx = NULL;
-        sec->hash = NULL;
-    }
-    SECITEM_ZfreeItem(&sec->sendSecret, PR_FALSE);
-    SECITEM_ZfreeItem(&sec->rcvSecret, PR_FALSE);
-
-    /* Destroy ciphers */
-    if (sec->destroy) {
-        (*sec->destroy)(sec->readcx, PR_TRUE);
-        (*sec->destroy)(sec->writecx, PR_TRUE);
-        sec->readcx = NULL;
-        sec->writecx = NULL;
-    } else {
-        PORT_Assert(sec->readcx == 0);
-        PORT_Assert(sec->writecx == 0);
-    }
-    sec->readcx = 0;
-    sec->writecx = 0;
-
     if (sec->localCert) {
         CERT_DestroyCertificate(sec->localCert);
         sec->localCert = NULL;
     }
     if (sec->peerCert) {
         CERT_DestroyCertificate(sec->peerCert);
         sec->peerCert = NULL;
     }
@@ -1086,20 +955,20 @@ ssl_DestroySecurityInfo(sslSecurityInfo 
 
 int
 ssl_SecureConnect(sslSocket *ss, const PRNetAddr *sa)
 {
     PRFileDesc *osfd = ss->fd->lower;
     int rv;
 
     if (ss->opt.handshakeAsServer) {
-        ss->securityHandshake = ssl2_BeginServerHandshake;
+        ss->handshake = ssl_BeginServerHandshake;
         ss->handshaking = sslHandshakingAsServer;
     } else {
-        ss->securityHandshake = ssl2_BeginClientHandshake;
+        ss->handshake = ssl_BeginClientHandshake;
         ss->handshaking = sslHandshakingAsClient;
     }
 
     /* connect to server */
     rv = osfd->methods->connect(osfd, sa, ss->cTimeout);
     if (rv == PR_SUCCESS) {
         ss->TCPconnected = 1;
     } else {
@@ -1140,18 +1009,17 @@ ssl_SecureConnect(sslSocket *ss, const P
  * in non-blocking mode.
  */
 
 int
 ssl_SecureClose(sslSocket *ss)
 {
     int rv;
 
-    if (ss->version >= SSL_LIBRARY_VERSION_3_0 &&
-        !(ss->shutdownHow & ssl_SHUTDOWN_SEND) &&
+    if (!(ss->shutdownHow & ssl_SHUTDOWN_SEND) &&
         ss->firstHsDone &&
         !ss->recvdCloseNotify &&
         ss->ssl3.initialized) {
 
         /* We don't want the final alert to be Nagle delayed. */
         if (!ss->delayDisabled) {
             ssl_EnableNagleDelay(ss, PR_FALSE);
             ss->delayDisabled = 1;
@@ -1172,17 +1040,16 @@ ssl_SecureShutdown(sslSocket *ss, int ns
     PRIntn sslHow = nsprHow + 1;
 
     if ((unsigned)nsprHow > PR_SHUTDOWN_BOTH) {
         PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
         return PR_FAILURE;
     }
 
     if ((sslHow & ssl_SHUTDOWN_SEND) != 0 &&
-        ss->version >= SSL_LIBRARY_VERSION_3_0 &&
         !(ss->shutdownHow & ssl_SHUTDOWN_SEND) &&
         ss->firstHsDone &&
         !ss->recvdCloseNotify &&
         ss->ssl3.initialized) {
 
         (void)SSL3_SendAlert(ss, alert_warning, close_notify);
     }
 
@@ -1220,17 +1087,17 @@ ssl_SecureRecv(sslSocket *ss, unsigned c
         }
         ssl_ReleaseXmitBufLock(ss);
     }
 
     rv = 0;
     /* If any of these is non-zero, the initial handshake is not done. */
     if (!ss->firstHsDone) {
         ssl_Get1stHandshakeLock(ss);
-        if (ss->handshake || ss->nextHandshake || ss->securityHandshake) {
+        if (ss->handshake) {
             rv = ssl_Do1stHandshake(ss);
         }
         ssl_Release1stHandshakeLock(ss);
     }
     if (rv < 0) {
         return rv;
     }
 
@@ -1285,24 +1152,22 @@ ssl_SecureSend(sslSocket *ss, const unsi
     }
 
     if (len > 0)
         ss->writerThread = PR_GetCurrentThread();
     /* If any of these is non-zero, the initial handshake is not done. */
     if (!ss->firstHsDone) {
         PRBool falseStart = PR_FALSE;
         ssl_Get1stHandshakeLock(ss);
-        if (ss->opt.enableFalseStart &&
-            ss->version >= SSL_LIBRARY_VERSION_3_0) {
+        if (ss->opt.enableFalseStart) {
             ssl_GetSSL3HandshakeLock(ss);
             falseStart = ss->ssl3.hs.canFalseStart;
             ssl_ReleaseSSL3HandshakeLock(ss);
         }
-        if (!falseStart &&
-            (ss->handshake || ss->nextHandshake || ss->securityHandshake)) {
+        if (!falseStart && ss->handshake) {
             rv = ssl_Do1stHandshake(ss);
         }
         ssl_Release1stHandshakeLock(ss);
     }
     if (rv < 0) {
         ss->writerThread = NULL;
         goto done;
     }
@@ -1317,32 +1182,27 @@ ssl_SecureSend(sslSocket *ss, const unsi
     PORT_Assert(buf != NULL);
     if (!buf) {
         PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
         rv = PR_FAILURE;
         goto done;
     }
 
     if (!ss->firstHsDone) {
-        PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_3_0);
 #ifdef DEBUG
         ssl_GetSSL3HandshakeLock(ss);
         PORT_Assert(ss->ssl3.hs.canFalseStart);
         ssl_ReleaseSSL3HandshakeLock(ss);
 #endif
         SSL_TRC(3, ("%d: SSL[%d]: SecureSend: sending data due to false start",
                     SSL_GETPID(), ss->fd));
     }
 
-    /* Send out the data using one of these functions:
-     *  ssl2_SendClear, ssl2_SendStream, ssl2_SendBlock,
-     *  ssl3_SendApplicationData
-     */
     ssl_GetXmitBufLock(ss);
-    rv = (*ss->sec.send)(ss, buf, len, flags);
+    rv = ssl3_SendApplicationData(ss, buf, len, flags);
     ssl_ReleaseXmitBufLock(ss);
     ss->writerThread = NULL;
 done:
     if (rv < 0) {
         SSL_TRC(2, ("%d: SSL[%d]: SecureSend: returning %d count, error %d",
                     SSL_GETPID(), ss->fd, rv, PORT_GetError()));
     } else {
         SSL_TRC(2, ("%d: SSL[%d]: SecureSend: returning %d count",
@@ -1496,25 +1356,19 @@ SSL_GetSessionID(PRFileDesc *fd)
     if (ss) {
         ssl_Get1stHandshakeLock(ss);
         ssl_GetSSL3HandshakeLock(ss);
 
         if (ss->opt.useSecurity && ss->firstHsDone && ss->sec.ci.sid) {
             item = (SECItem *)PORT_Alloc(sizeof(SECItem));
             if (item) {
                 sslSessionID *sid = ss->sec.ci.sid;
-                if (sid->version < SSL_LIBRARY_VERSION_3_0) {
-                    item->len = SSL2_SESSIONID_BYTES;
-                    item->data = (unsigned char *)PORT_Alloc(item->len);
-                    PORT_Memcpy(item->data, sid->u.ssl2.sessionID, item->len);
-                } else {
-                    item->len = sid->u.ssl3.sessionIDLength;
-                    item->data = (unsigned char *)PORT_Alloc(item->len);
-                    PORT_Memcpy(item->data, sid->u.ssl3.sessionID, item->len);
-                }
+                item->len = sid->u.ssl3.sessionIDLength;
+                item->data = (unsigned char *)PORT_Alloc(item->len);
+                PORT_Memcpy(item->data, sid->u.ssl3.sessionID, item->len);
             }
         }
 
         ssl_ReleaseSSL3HandshakeLock(ss);
         ssl_Release1stHandshakeLock(ss);
     }
     return item;
 }
@@ -1571,19 +1425,16 @@ SSL_AuthCertificateComplete(PRFileDesc *
         return SECFailure;
     }
 
     ssl_Get1stHandshakeLock(ss);
 
     if (!ss->ssl3.initialized) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         rv = SECFailure;
-    } else if (ss->version < SSL_LIBRARY_VERSION_3_0) {
-        PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
-        rv = SECFailure;
     } else {
         rv = ssl3_AuthCertificateComplete(ss, error);
     }
 
     ssl_Release1stHandshakeLock(ss);
 
     return rv;
 }
--- a/lib/ssl/sslsnce.c
+++ b/lib/ssl/sslsnce.c
@@ -100,27 +100,16 @@ struct sidCacheEntryStr {
     /* 32 */ PRUint8 sessionID[SSL3_SESSIONID_BYTES];
     /*  2 */ PRUint16 authAlgorithm;
     /*  2 */ PRUint16 authKeyBits;
     /*  2 */ PRUint16 keaType;
     /*  2 */ PRUint16 keaKeyBits;
     /* 72  - common header total */
 
     union {
-        struct {
-            /* 64 */ PRUint8 masterKey[SSL_MAX_MASTER_KEY_BYTES];
-            /* 32 */ PRUint8 cipherArg[SSL_MAX_CYPHER_ARG_BYTES];
-
-            /*  1 */ PRUint8 cipherType;
-            /*  1 */ PRUint8 masterKeyLen;
-            /*  1 */ PRUint8 keyBits;
-            /*  1 */ PRUint8 secretKeyBits;
-            /*  1 */ PRUint8 cipherArgLen;
-/*101 */} ssl2;
-
 struct {
     /*  2 */ ssl3CipherSuite cipherSuite;
     /*  2 */ PRUint16 compression; /* SSLCompressionMethod */
 
     /* 54 */ ssl3SidKeys keys; /* keys, wrapped as needed. */
 
     /*  4 */ PRUint32 masterWrapMech;
     /*  4 */ SSL3KEAType exchKeyType;
@@ -190,17 +179,16 @@ struct cacheDescStr {
     PRUint32 certCacheSize;
 
     PRUint32 numKeyCacheEntries;
     PRUint32 keyCacheSize;
 
     PRUint32 numSrvNameCacheEntries;
     PRUint32 srvNameCacheSize;
 
-    PRUint32 ssl2Timeout;
     PRUint32 ssl3Timeout;
 
     PRUint32 numSIDCacheLocksInitialized;
 
     /* These values are volatile, and are accessed through sharedCache-> */
     PRUint32 nextCertCacheEntry; /* certCacheLock protects */
     PRBool stopPolling;
     PRBool everInherited;
@@ -241,20 +229,16 @@ static PRBool isMultiProcess = PR_FALSE;
 #define DEF_CERT_CACHE_ENTRIES 250
 #define MIN_CERT_CACHE_ENTRIES 125 /* the effective size in old releases. */
 #define DEF_KEY_CACHE_ENTRIES 250
 #define DEF_NAME_CACHE_ENTRIES 1000
 
 #define SID_CACHE_ENTRIES_PER_SET 128
 #define SID_ALIGNMENT 16
 
-#define DEF_SSL2_TIMEOUT 100 /* seconds */
-#define MAX_SSL2_TIMEOUT 100 /* seconds */
-#define MIN_SSL2_TIMEOUT 5   /* seconds */
-
 #define DEF_SSL3_TIMEOUT 86400L /* 24 hours */
 #define MAX_SSL3_TIMEOUT 86400L /* 24 hours */
 #define MIN_SSL3_TIMEOUT 5      /* seconds  */
 
 #if defined(AIX) || defined(LINUX) || defined(NETBSD) || defined(OPENBSD)
 #define MAX_SID_CACHE_LOCKS 8 /* two FDs per lock */
 #elif defined(OSF1)
 #define MAX_SID_CACHE_LOCKS 16 /* one FD per lock */
@@ -452,177 +436,100 @@ ConvertFromSID(sidCacheEntry *to, sslSes
     to->creationTime = from->creationTime;
     to->lastAccessTime = from->lastAccessTime;
     to->expirationTime = from->expirationTime;
     to->authAlgorithm = from->authAlgorithm;
     to->authKeyBits = from->authKeyBits;
     to->keaType = from->keaType;
     to->keaKeyBits = from->keaKeyBits;
 
-    if (from->version < SSL_LIBRARY_VERSION_3_0) {
-        if ((from->u.ssl2.masterKey.len > SSL_MAX_MASTER_KEY_BYTES) ||
-            (from->u.ssl2.cipherArg.len > SSL_MAX_CYPHER_ARG_BYTES)) {
-            SSL_DBG(("%d: SSL: masterKeyLen=%d cipherArgLen=%d",
-                     myPid, from->u.ssl2.masterKey.len,
-                     from->u.ssl2.cipherArg.len));
-            to->valid = 0;
-            return;
-        }
+    to->u.ssl3.cipherSuite = from->u.ssl3.cipherSuite;
+    to->u.ssl3.compression = (PRUint16)from->u.ssl3.compression;
+    to->u.ssl3.keys = from->u.ssl3.keys;
+    to->u.ssl3.masterWrapMech = from->u.ssl3.masterWrapMech;
+    to->u.ssl3.exchKeyType = from->u.ssl3.exchKeyType;
+    to->sessionIDLength = from->u.ssl3.sessionIDLength;
+    to->u.ssl3.certIndex = -1;
+    to->u.ssl3.srvNameIndex = -1;
+    PORT_Memcpy(to->sessionID, from->u.ssl3.sessionID,
+                to->sessionIDLength);
 
-        to->u.ssl2.cipherType = from->u.ssl2.cipherType;
-        to->u.ssl2.masterKeyLen = from->u.ssl2.masterKey.len;
-        to->u.ssl2.cipherArgLen = from->u.ssl2.cipherArg.len;
-        to->u.ssl2.keyBits = from->u.ssl2.keyBits;
-        to->u.ssl2.secretKeyBits = from->u.ssl2.secretKeyBits;
-        to->sessionIDLength = SSL2_SESSIONID_BYTES;
-        PORT_Memcpy(to->sessionID, from->u.ssl2.sessionID, SSL2_SESSIONID_BYTES);
-        PORT_Memcpy(to->u.ssl2.masterKey, from->u.ssl2.masterKey.data,
-                    from->u.ssl2.masterKey.len);
-        PORT_Memcpy(to->u.ssl2.cipherArg, from->u.ssl2.cipherArg.data,
-                    from->u.ssl2.cipherArg.len);
-#ifdef DEBUG
-        PORT_Memset(to->u.ssl2.masterKey + from->u.ssl2.masterKey.len, 0,
-                    sizeof(to->u.ssl2.masterKey) - from->u.ssl2.masterKey.len);
-        PORT_Memset(to->u.ssl2.cipherArg + from->u.ssl2.cipherArg.len, 0,
-                    sizeof(to->u.ssl2.cipherArg) - from->u.ssl2.cipherArg.len);
-#endif
-        SSL_TRC(8, ("%d: SSL: ConvertSID: masterKeyLen=%d cipherArgLen=%d "
-                    "time=%d addr=0x%08x%08x%08x%08x cipherType=%d",
-                    myPid,
-                    to->u.ssl2.masterKeyLen, to->u.ssl2.cipherArgLen,
-                    to->creationTime, to->addr.pr_s6_addr32[0],
-                    to->addr.pr_s6_addr32[1], to->addr.pr_s6_addr32[2],
-                    to->addr.pr_s6_addr32[3], to->u.ssl2.cipherType));
-    } else {
-        /* This is an SSL v3 session */
-
-        to->u.ssl3.cipherSuite = from->u.ssl3.cipherSuite;
-        to->u.ssl3.compression = (PRUint16)from->u.ssl3.compression;
-        to->u.ssl3.keys = from->u.ssl3.keys;
-        to->u.ssl3.masterWrapMech = from->u.ssl3.masterWrapMech;
-        to->u.ssl3.exchKeyType = from->u.ssl3.exchKeyType;
-        to->sessionIDLength = from->u.ssl3.sessionIDLength;
-        to->u.ssl3.certIndex = -1;
-        to->u.ssl3.srvNameIndex = -1;
-        PORT_Memcpy(to->sessionID, from->u.ssl3.sessionID,
-                    to->sessionIDLength);
-
-        SSL_TRC(8, ("%d: SSL3: ConvertSID: time=%d addr=0x%08x%08x%08x%08x "
-                    "cipherSuite=%d",
-                    myPid, to->creationTime, to->addr.pr_s6_addr32[0],
-                    to->addr.pr_s6_addr32[1], to->addr.pr_s6_addr32[2],
-                    to->addr.pr_s6_addr32[3], to->u.ssl3.cipherSuite));
-    }
+    SSL_TRC(8, ("%d: SSL3: ConvertSID: time=%d addr=0x%08x%08x%08x%08x "
+                "cipherSuite=%d",
+                myPid, to->creationTime, to->addr.pr_s6_addr32[0],
+                to->addr.pr_s6_addr32[1], to->addr.pr_s6_addr32[2],
+                to->addr.pr_s6_addr32[3], to->u.ssl3.cipherSuite));
 }
 
 /*
 ** Convert shared memory cache-entry to local memory based one
 ** This is only called from ServerSessionIDLookup().
 */
 static sslSessionID *
 ConvertToSID(sidCacheEntry *from,
              certCacheEntry *pcce,
              srvNameCacheEntry *psnce,
              CERTCertDBHandle *dbHandle)
 {
     sslSessionID *to;
-    PRUint16 version = from->version;
 
     to = PORT_ZNew(sslSessionID);
     if (!to) {
         return 0;
     }
 
-    if (version < SSL_LIBRARY_VERSION_3_0) {
-        /* This is an SSL v2 session */
-        to->u.ssl2.masterKey.data =
-            (unsigned char *)PORT_Alloc(from->u.ssl2.masterKeyLen);
-        if (!to->u.ssl2.masterKey.data) {
+    to->u.ssl3.sessionIDLength = from->sessionIDLength;
+    to->u.ssl3.cipherSuite = from->u.ssl3.cipherSuite;
+    to->u.ssl3.compression = (SSLCompressionMethod)from->u.ssl3.compression;
+    to->u.ssl3.keys = from->u.ssl3.keys;
+    to->u.ssl3.masterWrapMech = from->u.ssl3.masterWrapMech;
+    to->u.ssl3.exchKeyType = from->u.ssl3.exchKeyType;
+    if (from->u.ssl3.srvNameIndex != -1 && psnce) {
+        SECItem name;
+        SECStatus rv;
+        name.type = psnce->type;
+        name.len = psnce->nameLen;
+        name.data = psnce->name;
+        rv = SECITEM_CopyItem(NULL, &to->u.ssl3.srvName, &name);
+        if (rv != SECSuccess) {
             goto loser;
         }
-        if (from->u.ssl2.cipherArgLen) {
-            to->u.ssl2.cipherArg.data =
-                (unsigned char *)PORT_Alloc(from->u.ssl2.cipherArgLen);
-            if (!to->u.ssl2.cipherArg.data) {
-                goto loser;
-            }
-            PORT_Memcpy(to->u.ssl2.cipherArg.data, from->u.ssl2.cipherArg,
-                        from->u.ssl2.cipherArgLen);
-        }
+    }
+
+    PORT_Memcpy(to->u.ssl3.sessionID, from->sessionID, from->sessionIDLength);
 
-        to->u.ssl2.cipherType = from->u.ssl2.cipherType;
-        to->u.ssl2.masterKey.len = from->u.ssl2.masterKeyLen;
-        to->u.ssl2.cipherArg.len = from->u.ssl2.cipherArgLen;
-        to->u.ssl2.keyBits = from->u.ssl2.keyBits;
-        to->u.ssl2.secretKeyBits = from->u.ssl2.secretKeyBits;
-        /*  to->sessionIDLength      = SSL2_SESSIONID_BYTES; */
-        PORT_Memcpy(to->u.ssl2.sessionID, from->sessionID, SSL2_SESSIONID_BYTES);
-        PORT_Memcpy(to->u.ssl2.masterKey.data, from->u.ssl2.masterKey,
-                    from->u.ssl2.masterKeyLen);
+    /* the portions of the SID that are only restored on the client
+     * are set to invalid values on the server.
+     */
+    to->u.ssl3.clientWriteKey = NULL;
+    to->u.ssl3.serverWriteKey = NULL;
 
-        SSL_TRC(8, ("%d: SSL: ConvertToSID: masterKeyLen=%d cipherArgLen=%d "
-                    "time=%d addr=0x%08x%08x%08x%08x cipherType=%d",
-                    myPid, to->u.ssl2.masterKey.len,
-                    to->u.ssl2.cipherArg.len, to->creationTime,
-                    to->addr.pr_s6_addr32[0], to->addr.pr_s6_addr32[1],
-                    to->addr.pr_s6_addr32[2], to->addr.pr_s6_addr32[3],
-                    to->u.ssl2.cipherType));
-    } else {
-        /* This is an SSL v3 session */
+    to->urlSvrName = NULL;
 
-        to->u.ssl3.sessionIDLength = from->sessionIDLength;
-        to->u.ssl3.cipherSuite = from->u.ssl3.cipherSuite;
-        to->u.ssl3.compression = (SSLCompressionMethod)from->u.ssl3.compression;
-        to->u.ssl3.keys = from->u.ssl3.keys;
-        to->u.ssl3.masterWrapMech = from->u.ssl3.masterWrapMech;
-        to->u.ssl3.exchKeyType = from->u.ssl3.exchKeyType;
-        if (from->u.ssl3.srvNameIndex != -1 && psnce) {
-            SECItem name;
-            SECStatus rv;
-            name.type = psnce->type;
-            name.len = psnce->nameLen;
-            name.data = psnce->name;
-            rv = SECITEM_CopyItem(NULL, &to->u.ssl3.srvName, &name);
-            if (rv != SECSuccess) {
-                goto loser;
-            }
-        }
+    to->u.ssl3.masterModuleID = (SECMODModuleID)-1; /* invalid value */
+    to->u.ssl3.masterSlotID = (CK_SLOT_ID)-1;       /* invalid value */
+    to->u.ssl3.masterWrapIndex = 0;
+    to->u.ssl3.masterWrapSeries = 0;
+    to->u.ssl3.masterValid = PR_FALSE;
 
-        PORT_Memcpy(to->u.ssl3.sessionID, from->sessionID, from->sessionIDLength);
+    to->u.ssl3.clAuthModuleID = (SECMODModuleID)-1; /* invalid value */
+    to->u.ssl3.clAuthSlotID = (CK_SLOT_ID)-1;       /* invalid value */
+    to->u.ssl3.clAuthSeries = 0;
+    to->u.ssl3.clAuthValid = PR_FALSE;
 
-        /* the portions of the SID that are only restored on the client
-         * are set to invalid values on the server.
-         */
-        to->u.ssl3.clientWriteKey = NULL;
-        to->u.ssl3.serverWriteKey = NULL;
-
-        to->urlSvrName = NULL;
-
-        to->u.ssl3.masterModuleID = (SECMODModuleID)-1; /* invalid value */
-        to->u.ssl3.masterSlotID = (CK_SLOT_ID)-1;       /* invalid value */
-        to->u.ssl3.masterWrapIndex = 0;
-        to->u.ssl3.masterWrapSeries = 0;
-        to->u.ssl3.masterValid = PR_FALSE;
+    if (from->u.ssl3.certIndex != -1 && pcce) {
+        SECItem derCert;
 
-        to->u.ssl3.clAuthModuleID = (SECMODModuleID)-1; /* invalid value */
-        to->u.ssl3.clAuthSlotID = (CK_SLOT_ID)-1;       /* invalid value */
-        to->u.ssl3.clAuthSeries = 0;
-        to->u.ssl3.clAuthValid = PR_FALSE;
-
-        if (from->u.ssl3.certIndex != -1 && pcce) {
-            SECItem derCert;
+        derCert.len = pcce->certLength;
+        derCert.data = pcce->cert;
 
-            derCert.len = pcce->certLength;
-            derCert.data = pcce->cert;
-
-            to->peerCert = CERT_NewTempCertificate(dbHandle, &derCert, NULL,
-                                                   PR_FALSE, PR_TRUE);
-            if (to->peerCert == NULL)
-                goto loser;
-        }
+        to->peerCert = CERT_NewTempCertificate(dbHandle, &derCert, NULL,
+                                               PR_FALSE, PR_TRUE);
+        if (to->peerCert == NULL)
+            goto loser;
     }
 
     to->version = from->version;
     to->creationTime = from->creationTime;
     to->lastAccessTime = from->lastAccessTime;
     to->expirationTime = from->expirationTime;
     to->cached = in_server_cache;
     to->addr = from->addr;
@@ -631,24 +538,17 @@ ConvertToSID(sidCacheEntry *from,
     to->authKeyBits = from->authKeyBits;
     to->keaType = from->keaType;
     to->keaKeyBits = from->keaKeyBits;
 
     return to;
 
 loser:
     if (to) {
-        if (version < SSL_LIBRARY_VERSION_3_0) {
-            if (to->u.ssl2.masterKey.data)
-                PORT_Free(to->u.ssl2.masterKey.data);
-            if (to->u.ssl2.cipherArg.data)
-                PORT_Free(to->u.ssl2.cipherArg.data);
-        } else {
-            SECITEM_FreeItem(&to->u.ssl3.srvName, PR_FALSE);
-        }
+        SECITEM_FreeItem(&to->u.ssl3.srvName, PR_FALSE);
         PORT_Free(to);
     }
     return NULL;
 }
 
 /*
 ** Perform some mumbo jumbo on the ip-address and the session-id value to
 ** compute a hash value.
@@ -750,72 +650,69 @@ ServerSessionIDLookup(const PRIPv6Addr *
 
     set = SIDindex(cache, addr, sessionID, sessionIDLength);
     now = LockSet(cache, set, 0);
     if (!now)
         return NULL;
 
     psce = FindSID(cache, set, now, addr, sessionID, sessionIDLength);
     if (psce) {
-        if (psce->version >= SSL_LIBRARY_VERSION_3_0) {
-            if ((cndx = psce->u.ssl3.certIndex) != -1) {
-
-                PRUint32 gotLock = LockSidCacheLock(cache->certCacheLock, now);
-                if (gotLock) {
-                    pcce = &cache->certCacheData[cndx];
+        if ((cndx = psce->u.ssl3.certIndex) != -1) {
+            PRUint32 gotLock = LockSidCacheLock(cache->certCacheLock, now);
+            if (gotLock) {
+                pcce = &cache->certCacheData[cndx];
 
-                    /* See if the cert's session ID matches the sce cache. */
-                    if ((pcce->sessionIDLength == psce->sessionIDLength) &&
-                        !PORT_Memcmp(pcce->sessionID, psce->sessionID,
-                                     pcce->sessionIDLength)) {
-                        cce = *pcce;
-                    } else {
-                        /* The cert doesen't match the SID cache entry,
-                        ** so invalidate the SID cache entry.
-                        */
-                        psce->valid = 0;
-                        psce = 0;
-                        pcce = 0;
-                    }
-                    UnlockSidCacheLock(cache->certCacheLock);
+                /* See if the cert's session ID matches the sce cache. */
+                if ((pcce->sessionIDLength == psce->sessionIDLength) &&
+                    !PORT_Memcmp(pcce->sessionID, psce->sessionID,
+                                 pcce->sessionIDLength)) {
+                    cce = *pcce;
                 } else {
-                    /* what the ??.  Didn't get the cert cache lock.
-                    ** Don't invalidate the SID cache entry, but don't find it.
+                    /* The cert doesen't match the SID cache entry,
+                    ** so invalidate the SID cache entry.
                     */
-                    PORT_Assert(!("Didn't get cert Cache Lock!"));
+                    psce->valid = 0;
                     psce = 0;
                     pcce = 0;
                 }
+                UnlockSidCacheLock(cache->certCacheLock);
+            } else {
+                /* what the ??.  Didn't get the cert cache lock.
+                ** Don't invalidate the SID cache entry, but don't find it.
+                */
+                PORT_Assert(!("Didn't get cert Cache Lock!"));
+                psce = 0;
+                pcce = 0;
             }
-            if (psce && ((cndx = psce->u.ssl3.srvNameIndex) != -1)) {
-                PRUint32 gotLock = LockSidCacheLock(cache->srvNameCacheLock,
-                                                    now);
-                if (gotLock) {
-                    psnce = &cache->srvNameCacheData[cndx];
+        }
+        if (psce && ((cndx = psce->u.ssl3.srvNameIndex) != -1)) {
+            PRUint32 gotLock = LockSidCacheLock(cache->srvNameCacheLock,
+                                                now);
+            if (gotLock) {
+                psnce = &cache->srvNameCacheData[cndx];
 
-                    if (!PORT_Memcmp(psnce->nameHash, psce->u.ssl3.srvNameHash,
-                                     SHA256_LENGTH)) {
-                        snce = *psnce;
-                    } else {
-                        /* The name doesen't match the SID cache entry,
-                        ** so invalidate the SID cache entry.
-                        */
-                        psce->valid = 0;
-                        psce = 0;
-                        psnce = 0;
-                    }
-                    UnlockSidCacheLock(cache->srvNameCacheLock);
+                if (!PORT_Memcmp(psnce->nameHash, psce->u.ssl3.srvNameHash,
+                                 SHA256_LENGTH)) {
+                    snce = *psnce;
                 } else {
-                    /* what the ??.  Didn't get the cert cache lock.
-                    ** Don't invalidate the SID cache entry, but don't find it.
+                    /* The name doesen't match the SID cache entry,
+                    ** so invalidate the SID cache entry.
                     */
-                    PORT_Assert(!("Didn't get name Cache Lock!"));
+                    psce->valid = 0;
                     psce = 0;
                     psnce = 0;
                 }
+                UnlockSidCacheLock(cache->srvNameCacheLock);
+            } else {
+                /* what the ??.  Didn't get the cert cache lock.
+                ** Don't invalidate the SID cache entry, but don't find it.
+                */
+                PORT_Assert(!("Didn't get name Cache Lock!"));
+                psce = 0;
+                psnce = 0;
             }
         }
         if (psce) {
             psce->lastAccessTime = now;
             sce = *psce; /* grab a copy while holding the lock */
         }
     }
     UnlockSet(cache, set);
@@ -831,72 +728,49 @@ ServerSessionIDLookup(const PRIPv6Addr *
 /*
 ** Place a sid into the cache, if it isn't already there.
 */
 static void
 ServerSessionIDCache(sslSessionID *sid)
 {
     sidCacheEntry sce;
     PRUint32 now = 0;
-    PRUint16 version = sid->version;
     cacheDesc *cache = &globalCache;
 
-    if ((version >= SSL_LIBRARY_VERSION_3_0) &&
-        (sid->u.ssl3.sessionIDLength == 0)) {
+    if (sid->u.ssl3.sessionIDLength == 0) {
         return;
     }
 
     if (sid->cached == never_cached || sid->cached == invalid_cache) {
         PRUint32 set;
 
         PORT_Assert(sid->creationTime != 0);
         if (!sid->creationTime)
             sid->lastAccessTime = sid->creationTime = ssl_Time();
-        if (version < SSL_LIBRARY_VERSION_3_0) {
-            /* override caller's expiration time, which uses client timeout
-             * duration, not server timeout duration.
-             */
-            sid->expirationTime = sid->creationTime + cache->ssl2Timeout;
-            SSL_TRC(8, ("%d: SSL: CacheMT: cached=%d addr=0x%08x%08x%08x%08x time=%x "
-                        "cipher=%d",
-                        myPid, sid->cached,
-                        sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1],
-                        sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3],
-                        sid->creationTime, sid->u.ssl2.cipherType));
-            PRINT_BUF(8, (0, "sessionID:", sid->u.ssl2.sessionID,
-                          SSL2_SESSIONID_BYTES));
-            PRINT_BUF(8, (0, "masterKey:", sid->u.ssl2.masterKey.data,
-                          sid->u.ssl2.masterKey.len));
-            PRINT_BUF(8, (0, "cipherArg:", sid->u.ssl2.cipherArg.data,
-                          sid->u.ssl2.cipherArg.len));
-        } else {
-            /* override caller's expiration time, which uses client timeout
-             * duration, not server timeout duration.
-             */
-            sid->expirationTime = sid->creationTime + cache->ssl3Timeout;
-            SSL_TRC(8, ("%d: SSL: CacheMT: cached=%d addr=0x%08x%08x%08x%08x time=%x "
-                        "cipherSuite=%d",
-                        myPid, sid->cached,
-                        sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1],
-                        sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3],
-                        sid->creationTime, sid->u.ssl3.cipherSuite));
-            PRINT_BUF(8, (0, "sessionID:", sid->u.ssl3.sessionID,
-                          sid->u.ssl3.sessionIDLength));
-        }
+        /* override caller's expiration time, which uses client timeout
+         * duration, not server timeout duration.
+         */
+        sid->expirationTime = sid->creationTime + cache->ssl3Timeout;
+        SSL_TRC(8, ("%d: SSL: CacheMT: cached=%d addr=0x%08x%08x%08x%08x time=%x "
+                    "cipherSuite=%d",
+                    myPid, sid->cached,
+                    sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1],
+                    sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3],
+                    sid->creationTime, sid->u.ssl3.cipherSuite));
+        PRINT_BUF(8, (0, "sessionID:", sid->u.ssl3.sessionID,
+                      sid->u.ssl3.sessionIDLength));
 
         ConvertFromSID(&sce, sid);
 
-        if (version >= SSL_LIBRARY_VERSION_3_0) {
-            SECItem *name = &sid->u.ssl3.srvName;
-            if (name->len && name->data) {
-                now = CacheSrvName(cache, name, &sce);
-            }
-            if (sid->peerCert != NULL) {
-                now = CacheCert(cache, sid->peerCert, &sce);
-            }
+        SECItem *name = &sid->u.ssl3.srvName;
+        if (name->len && name->data) {
+            now = CacheSrvName(cache, name, &sce);
+        }
+        if (sid->peerCert != NULL) {
+            now = CacheCert(cache, sid->peerCert, &sce);
         }
 
         set = SIDindex(cache, &sce.addr, sce.sessionID, sce.sessionIDLength);
         now = LockSet(cache, set, now);
         if (now) {
             PRUint32 next = cache->sidCacheSets[set].next;
             PRUint32 ndx = set * SID_CACHE_ENTRIES_PER_SET + next;
 
@@ -930,41 +804,25 @@ ServerSessionIDUncache(sslSessionID *sid
     if (sid == NULL)
         return;
 
     /* Uncaching a SID should never change the error code.
     ** So save it here and restore it before exiting.
     */
     err = PR_GetError();
 
-    if (sid->version < SSL_LIBRARY_VERSION_3_0) {
-        sessionID = sid->u.ssl2.sessionID;
-        sessionIDLength = SSL2_SESSIONID_BYTES;
-        SSL_TRC(8, ("%d: SSL: UncacheMT: valid=%d addr=0x%08x%08x%08x%08x time=%x "
-                    "cipher=%d",
-                    myPid, sid->cached,
-                    sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1],
-                    sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3],
-                    sid->creationTime, sid->u.ssl2.cipherType));
-        PRINT_BUF(8, (0, "sessionID:", sessionID, sessionIDLength));
-        PRINT_BUF(8, (0, "masterKey:", sid->u.ssl2.masterKey.data,
-                      sid->u.ssl2.masterKey.len));
-        PRINT_BUF(8, (0, "cipherArg:", sid->u.ssl2.cipherArg.data,
-                      sid->u.ssl2.cipherArg.len));
-    } else {
-        sessionID = sid->u.ssl3.sessionID;
-        sessionIDLength = sid->u.ssl3.sessionIDLength;
-        SSL_TRC(8, ("%d: SSL3: UncacheMT: valid=%d addr=0x%08x%08x%08x%08x time=%x "
-                    "cipherSuite=%d",
-                    myPid, sid->cached,
-                    sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1],
-                    sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3],
-                    sid->creationTime, sid->u.ssl3.cipherSuite));
-        PRINT_BUF(8, (0, "sessionID:", sessionID, sessionIDLength));
-    }
+    sessionID = sid->u.ssl3.sessionID;
+    sessionIDLength = sid->u.ssl3.sessionIDLength;
+    SSL_TRC(8, ("%d: SSL3: UncacheMT: valid=%d addr=0x%08x%08x%08x%08x time=%x "
+                "cipherSuite=%d",
+                myPid, sid->cached,
+                sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1],
+                sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3],
+                sid->creationTime, sid->u.ssl3.cipherSuite));
+    PRINT_BUF(8, (0, "sessionID:", sessionID, sessionIDLength));
     set = SIDindex(cache, &sid->addr, sessionID, sessionIDLength);
     now = LockSet(cache, set, 0);
     if (now) {
         psce = FindSID(cache, set, now, &sid->addr, sessionID, sessionIDLength);
         if (psce) {
             psce->valid = 0;
         }
         UnlockSet(cache, set);
@@ -1017,18 +875,18 @@ CloseCache(cacheDesc *cache)
         PR_CloseFileMap(cache->cacheMemMap);
         cache->cacheMemMap = NULL;
     }
     memset(cache, 0, sizeof *cache);
 }
 
 static SECStatus
 InitCache(cacheDesc *cache, int maxCacheEntries, int maxCertCacheEntries,
-          int maxSrvNameCacheEntries, PRUint32 ssl2_timeout,
-          PRUint32 ssl3_timeout, const char *directory, PRBool shared)
+          int maxSrvNameCacheEntries, PRUint32 ssl3_timeout,
+          const char *directory, PRBool shared)
 {
     ptrdiff_t ptr;
     sidCacheLock *pLock;
     char *cacheMem;
     PRFileMap *cacheMemMap;
     char *cfn = NULL; /* cache file name */
     int locks_initialized = 0;
     int locks_to_initialize = 0;
@@ -1139,28 +997,16 @@ InitCache(cacheDesc *cache, int maxCache
     cache->srvNameCacheData = (srvNameCacheEntry *)ptr;
     cache->srvNameCacheSize =
         cache->numSrvNameCacheEntries * sizeof(srvNameCacheEntry);
     ptr = (ptrdiff_t)(cache->srvNameCacheData + cache->numSrvNameCacheEntries);
     ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);
 
     cache->cacheMemSize = ptr;
 
-    if (ssl2_timeout) {
-        if (ssl2_timeout > MAX_SSL2_TIMEOUT) {
-            ssl2_timeout = MAX_SSL2_TIMEOUT;
-        }
-        if (ssl2_timeout < MIN_SSL2_TIMEOUT) {
-            ssl2_timeout = MIN_SSL2_TIMEOUT;
-        }
-        cache->ssl2Timeout = ssl2_timeout;
-    } else {
-        cache->ssl2Timeout = DEF_SSL2_TIMEOUT;
-    }
-
     if (ssl3_timeout) {
         if (ssl3_timeout > MAX_SSL3_TIMEOUT) {
             ssl3_timeout = MAX_SSL3_TIMEOUT;
         }
         if (ssl3_timeout < MIN_SSL3_TIMEOUT) {
             ssl3_timeout = MIN_SSL3_TIMEOUT;
         }
         cache->ssl3Timeout = ssl3_timeout;
@@ -1280,17 +1126,16 @@ SSL_SetMaxServerCacheLocks(PRUint32 maxL
     }
     ssl_max_sid_cache_locks = maxLocks - 2;
     /* The extra two are the cert cache lock and the key cache lock. */
     return SECSuccess;
 }
 
 static SECStatus
 ssl_ConfigServerSessionIDCacheInstanceWithOpt(cacheDesc *cache,
-                                              PRUint32 ssl2_timeout,
                                               PRUint32 ssl3_timeout,
                                               const char *directory,
                                               PRBool shared,
                                               int maxCacheEntries,
                                               int maxCertCacheEntries,
                                               int maxSrvNameCacheEntries)
 {
     SECStatus rv;
@@ -1304,18 +1149,17 @@ ssl_ConfigServerSessionIDCacheInstanceWi
         return rv;
     }
 
     myPid = SSL_GETPID();
     if (!directory) {
         directory = DEFAULT_CACHE_DIRECTORY;
     }
     rv = InitCache(cache, maxCacheEntries, maxCertCacheEntries,
-                   maxSrvNameCacheEntries, ssl2_timeout, ssl3_timeout,
-                   directory, shared);
+                   maxSrvNameCacheEntries, ssl3_timeout, directory, shared);
     if (rv) {
         SET_ERROR_CODE
         return SECFailure;
     }
 
     ssl_sid_lookup = ServerSessionIDLookup;
     ssl_sid_cache = ServerSessionIDCache;
     ssl_sid_uncache = ServerSessionIDUncache;
@@ -1325,17 +1169,16 @@ ssl_ConfigServerSessionIDCacheInstanceWi
 SECStatus
 SSL_ConfigServerSessionIDCacheInstance(cacheDesc *cache,
                                        int maxCacheEntries,
                                        PRUint32 ssl2_timeout,
                                        PRUint32 ssl3_timeout,
                                        const char *directory, PRBool shared)
 {
     return ssl_ConfigServerSessionIDCacheInstanceWithOpt(cache,
-                                                         ssl2_timeout,
                                                          ssl3_timeout,
                                                          directory,
                                                          shared,
                                                          maxCacheEntries,
                                                          -1, -1);
 }
 
 SECStatus
@@ -1366,18 +1209,17 @@ SSL_ShutdownServerSessionIDCache(void)
     SSL3_ShutdownServerCache();
     return SSL_ShutdownServerSessionIDCacheInstance(&globalCache);
 }
 
 /* Use this function, instead of SSL_ConfigServerSessionIDCache,
  * if the cache will be shared by multiple processes.
  */
 static SECStatus
-ssl_ConfigMPServerSIDCacheWithOpt(PRUint32 ssl2_timeout,
-                                  PRUint32 ssl3_timeout,
+ssl_ConfigMPServerSIDCacheWithOpt(PRUint32 ssl3_timeout,
                                   const char *directory,
                                   int maxCacheEntries,
                                   int maxCertCacheEntries,
                                   int maxSrvNameCacheEntries)
 {
     char *envValue;
     char *inhValue;
     cacheDesc *cache = &globalCache;
@@ -1385,17 +1227,17 @@ ssl_ConfigMPServerSIDCacheWithOpt(PRUint
     SECStatus result;
     PRStatus prStatus;
     SECStatus putEnvFailed;
     inheritance inherit;
     char fmString[PR_FILEMAP_STRING_BUFSIZE];
 
     isMultiProcess = PR_TRUE;
     result = ssl_ConfigServerSessionIDCacheInstanceWithOpt(cache,
-                                                           ssl2_timeout, ssl3_timeout, directory, PR_TRUE,
+                                                           ssl3_timeout, directory, PR_TRUE,
                                                            maxCacheEntries, maxCacheEntries, maxSrvNameCacheEntries);
     if (result != SECSuccess)
         return result;
 
     prStatus = PR_ExportFileMapAsString(cache->cacheMemMap,
                                         sizeof fmString, fmString);
     if ((prStatus != PR_SUCCESS) || !(fmStrLen = strlen(fmString))) {
         SET_ERROR_CODE
@@ -1435,18 +1277,17 @@ ssl_ConfigMPServerSIDCacheWithOpt(PRUint
  * if the cache will be shared by multiple processes.
  */
 SECStatus
 SSL_ConfigMPServerSIDCache(int maxCacheEntries,
                            PRUint32 ssl2_timeout,
                            PRUint32 ssl3_timeout,
                            const char *directory)
 {
-    return ssl_ConfigMPServerSIDCacheWithOpt(ssl2_timeout,
-                                             ssl3_timeout,
+    return ssl_ConfigMPServerSIDCacheWithOpt(ssl3_timeout,
                                              directory,
                                              maxCacheEntries,
                                              -1, -1);
 }
 
 SECStatus
 SSL_ConfigServerSessionIDCacheWithOpt(
     PRUint32 ssl2_timeout,
@@ -1455,22 +1296,21 @@ SSL_ConfigServerSessionIDCacheWithOpt(
     int maxCacheEntries,
     int maxCertCacheEntries,
     int maxSrvNameCacheEntries,
     PRBool enableMPCache)
 {
     if (!enableMPCache) {
         ssl_InitSessionCacheLocks(PR_FALSE);
         return ssl_ConfigServerSessionIDCacheInstanceWithOpt(&globalCache,
-                                                             ssl2_timeout, ssl3_timeout, directory, PR_FALSE,
+                                                             ssl3_timeout, directory, PR_FALSE,
                                                              maxCacheEntries, maxCertCacheEntries, maxSrvNameCacheEntries);
     } else {
-        return ssl_ConfigMPServerSIDCacheWithOpt(ssl2_timeout, ssl3_timeout,
-                                                 directory, maxCacheEntries, maxCertCacheEntries,
-                                                 maxSrvNameCacheEntries);
+        return ssl_ConfigMPServerSIDCacheWithOpt(ssl3_timeout, directory,
+                                                 maxCacheEntries, maxCertCacheEntries, maxSrvNameCacheEntries);
     }
 }
 
 SECStatus
 SSL_InheritMPServerSIDCacheInstance(cacheDesc *cache, const char *envString)
 {
     unsigned char *decoString = NULL;
     char *fmString = NULL;
--- a/lib/ssl/sslsock.c
+++ b/lib/ssl/sslsock.c
@@ -224,19 +224,16 @@ ssl_DupSocket(sslSocket *os)
 
         ss->ops = os->ops;
         ss->rTimeout = os->rTimeout;
         ss->wTimeout = os->wTimeout;
         ss->cTimeout = os->cTimeout;
         ss->dbHandle = os->dbHandle;
 
         /* copy ssl2&3 policy & prefs, even if it's not selected (yet) */
-        ss->allowedByPolicy = os->allowedByPolicy;
-        ss->maybeAllowedByPolicy = os->maybeAllowedByPolicy;
-        ss->chosenPreference = os->chosenPreference;
         PORT_Memcpy(ss->cipherSuites, os->cipherSuites, sizeof os->cipherSuites);
         PORT_Memcpy(ss->ssl3.dtlsSRTPCiphers, os->ssl3.dtlsSRTPCiphers,
                     sizeof(PRUint16) * os->ssl3.dtlsSRTPCipherCount);
         ss->ssl3.dtlsSRTPCipherCount = os->ssl3.dtlsSRTPCipherCount;
         PORT_Memcpy(ss->ssl3.signatureAlgorithms, os->ssl3.signatureAlgorithms,
                     sizeof(ss->ssl3.signatureAlgorithms[0]) *
                         os->ssl3.signatureAlgorithmCount);
         ss->ssl3.signatureAlgorithmCount = os->ssl3.signatureAlgorithmCount;
@@ -251,28 +248,16 @@ ssl_DupSocket(sslSocket *os)
                 goto loser;
             }
             PORT_Memcpy(ss->ssl3.dheGroups, os->ssl3.dheGroups,
                         sizeof(SSLDHEGroupType) * os->ssl3.numDHEGroups);
         } else {
             ss->ssl3.dheGroups = NULL;
         }
 
-        if (os->cipherSpecs) {
-            ss->cipherSpecs = (unsigned char *)PORT_Alloc(os->sizeCipherSpecs);
-            if (ss->cipherSpecs)
-                PORT_Memcpy(ss->cipherSpecs, os->cipherSpecs,
-                            os->sizeCipherSpecs);
-            ss->sizeCipherSpecs = os->sizeCipherSpecs;
-            ss->preferredCipher = os->preferredCipher;
-        } else {
-            ss->cipherSpecs = NULL; /* produced lazily */
-            ss->sizeCipherSpecs = 0;
-            ss->preferredCipher = NULL;
-        }
         if (ss->opt.useSecurity) {
             /* This int should be SSLKEAType, but CC on Irix complains,
              * during the for loop.
              */
             int i;
             sslServerCerts *oc = os->serverCerts;
             sslServerCerts *sc = ss->serverCerts;
 
@@ -376,27 +361,22 @@ ssl_DestroySocketContents(sslSocket *ss)
 
     /* Free up socket */
     ssl_DestroySecurityInfo(&ss->sec);
 
     ssl3_DestroySSL3Info(ss);
 
     PORT_Free(ss->saveBuf.buf);
     PORT_Free(ss->pendingBuf.buf);
-    ssl_DestroyGather(&ss->gs);
+    ssl3_DestroyGather(&ss->gs);
 
     if (ss->peerID != NULL)
         PORT_Free(ss->peerID);
     if (ss->url != NULL)
         PORT_Free((void *)ss->url); /* CONST */
-    if (ss->cipherSpecs) {
-        PORT_Free(ss->cipherSpecs);
-        ss->cipherSpecs = NULL;
-        ss->sizeCipherSpecs = 0;
-    }
 
     /* Clean up server configuration */
     for (i = kt_null; i < kt_kea_size; i++) {
         sslServerCerts *sc = ss->serverCerts + i;
         if (sc->serverCert != NULL)
             CERT_DestroyCertificate(sc->serverCert);
         if (sc->serverCertChain != NULL)
             CERT_DestroyCertificateList(sc->serverCertChain);
@@ -552,17 +532,17 @@ ssl_EnableTLS(SSLVersionRange *vrange, P
 {
     if (on) {
         /* don't turn it on if tls1.0 disallowed by by policy */
         if (!ssl_VersionIsSupportedByPolicy(ssl_variant_stream,
                                             SSL_LIBRARY_VERSION_TLS_1_0)) {
             return;
         }
     }
-    if (SSL3_ALL_VERSIONS_DISABLED(vrange)) {
+    if (SSL_ALL_VERSIONS_DISABLED(vrange)) {
         if (on) {
             vrange->min = SSL_LIBRARY_VERSION_TLS_1_0;
             vrange->max = SSL_LIBRARY_VERSION_TLS_1_0;
         } /* else don't change anything */
         return;
     }
 
     if (on) {
@@ -589,17 +569,17 @@ ssl_EnableSSL3(SSLVersionRange *vrange, 
 {
     if (on) {
         /* don't turn it on if ssl3 disallowed by by policy */
         if (!ssl_VersionIsSupportedByPolicy(ssl_variant_stream,
                                             SSL_LIBRARY_VERSION_3_0)) {
             return;
         }
     }
-    if (SSL3_ALL_VERSIONS_DISABLED(vrange)) {
+    if (SSL_ALL_VERSIONS_DISABLED(vrange)) {
         if (on) {
             vrange->min = SSL_LIBRARY_VERSION_3_0;
             vrange->max = SSL_LIBRARY_VERSION_3_0;
         } /* else don't change anything */
         return;
     }
 
     if (on) {
@@ -681,94 +661,41 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 wh
             if (IS_DTLS(ss)) {
                 if (on) {
                     PORT_SetError(SEC_ERROR_INVALID_ARGS);
                     rv = SECFailure; /* not allowed */
                 }
                 break;
             }
             ssl_EnableTLS(&ss->vrange, on);
-            ss->preferredCipher = NULL;
-            if (ss->cipherSpecs) {
-                PORT_Free(ss->cipherSpecs);
-                ss->cipherSpecs = NULL;
-                ss->sizeCipherSpecs = 0;
-            }
             break;
 
         case SSL_ENABLE_SSL3:
             if (IS_DTLS(ss)) {
                 if (on) {
                     PORT_SetError(SEC_ERROR_INVALID_ARGS);
                     rv = SECFailure; /* not allowed */
                 }
                 break;
             }
             ssl_EnableSSL3(&ss->vrange, on);
-            ss->preferredCipher = NULL;
-            if (ss->cipherSpecs) {
-                PORT_Free(ss->cipherSpecs);
-                ss->cipherSpecs = NULL;
-                ss->sizeCipherSpecs = 0;
-            }
-            break;
-
-        case SSL_ENABLE_SSL2:
-            if (IS_DTLS(ss)) {
-                if (on) {
-                    PORT_SetError(SEC_ERROR_INVALID_ARGS);
-                    rv = SECFailure; /* not allowed */
-                }
-                break;
-            }
-            if (on) {
-                /* don't turn it on if ssl2 disallowed by by policy */
-                if (!ssl_VersionIsSupportedByPolicy(ssl_variant_stream,
-                                                    SSL_LIBRARY_VERSION_2)) {
-                    break;
-                }
-            }
-            ss->opt.enableSSL2 = on;
-            if (on) {
-                ss->opt.v2CompatibleHello = on;
-            }
-            ss->preferredCipher = NULL;
-            if (ss->cipherSpecs) {
-                PORT_Free(ss->cipherSpecs);
-                ss->cipherSpecs = NULL;
-                ss->sizeCipherSpecs = 0;
-            }
             break;
 
         case SSL_NO_CACHE:
             ss->opt.noCache = on;
             break;
 
         case SSL_ENABLE_FDX:
             if (on && ss->opt.noLocks) {
                 PORT_SetError(SEC_ERROR_INVALID_ARGS);
                 rv = SECFailure;
             }
             ss->opt.fdx = on;
             break;
 
-        case SSL_V2_COMPATIBLE_HELLO:
-            if (IS_DTLS(ss)) {
-                if (on) {
-                    PORT_SetError(SEC_ERROR_INVALID_ARGS);
-                    rv = SECFailure; /* not allowed */
-                }
-                break;
-            }
-            ss->opt.v2CompatibleHello = on;
-            if (!on) {
-                ss->opt.enableSSL2 = on;
-            }
-            break;
-
         case SSL_ROLLBACK_DETECTION:
             ss->opt.detectRollBack = on;
             break;
 
         case SSL_NO_STEP_DOWN:
             ss->opt.noStepDown = on;
             if (on)
                 SSL_DisableExportCipherSuites(fd);
@@ -928,28 +855,22 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 wh
             on = ss->opt.handshakeAsServer;
             break;
         case SSL_ENABLE_TLS:
             on = ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_0;
             break;
         case SSL_ENABLE_SSL3:
             on = ss->vrange.min == SSL_LIBRARY_VERSION_3_0;
             break;
-        case SSL_ENABLE_SSL2:
-            on = ss->opt.enableSSL2;
-            break;
         case SSL_NO_CACHE:
             on = ss->opt.noCache;
             break;
         case SSL_ENABLE_FDX:
             on = ss->opt.fdx;
             break;
-        case SSL_V2_COMPATIBLE_HELLO:
-            on = ss->opt.v2CompatibleHello;
-            break;
         case SSL_ROLLBACK_DETECTION:
             on = ss->opt.detectRollBack;
             break;
         case SSL_NO_STEP_DOWN:
             on = ss->opt.noStepDown;
             break;
         case SSL_BYPASS_PKCS11:
             on = ss->opt.bypassPKCS11;
@@ -1045,28 +966,22 @@ SSL_OptionGetDefault(PRInt32 which, PRBo
             on = ssl_defaults.handshakeAsServer;
             break;
         case SSL_ENABLE_TLS:
             on = versions_defaults_stream.max >= SSL_LIBRARY_VERSION_TLS_1_0;
             break;
         case SSL_ENABLE_SSL3:
             on = versions_defaults_stream.min == SSL_LIBRARY_VERSION_3_0;
             break;
-        case SSL_ENABLE_SSL2:
-            on = ssl_defaults.enableSSL2;
-            break;
         case SSL_NO_CACHE:
             on = ssl_defaults.noCache;
             break;
         case SSL_ENABLE_FDX:
             on = ssl_defaults.fdx;
             break;
-        case SSL_V2_COMPATIBLE_HELLO:
-            on = ssl_defaults.v2CompatibleHello;
-            break;
         case SSL_ROLLBACK_DETECTION:
             on = ssl_defaults.detectRollBack;
             break;
         case SSL_NO_STEP_DOWN:
             on = ssl_defaults.noStepDown;
             break;
         case SSL_BYPASS_PKCS11:
             on = ssl_defaults.bypassPKCS11;
@@ -1184,49 +1099,28 @@ SSL_OptionSetDefault(PRInt32 which, PRBo
         case SSL_ENABLE_TLS:
             ssl_EnableTLS(&versions_defaults_stream, on);
             break;
 
         case SSL_ENABLE_SSL3:
             ssl_EnableSSL3(&versions_defaults_stream, on);
             break;
 
-        case SSL_ENABLE_SSL2:
-            if (on) {
-                /* don't turn it on if ssl2 disallowed by by policy */
-                if (!ssl_VersionIsSupportedByPolicy(ssl_variant_stream,
-                                                    SSL_LIBRARY_VERSION_2)) {
-                    break;
-                }
-            }
-            ssl_defaults.enableSSL2 = on;
-            if (on) {
-                ssl_defaults.v2CompatibleHello = on;
-            }
-            break;
-
         case SSL_NO_CACHE:
             ssl_defaults.noCache = on;
             break;
 
         case SSL_ENABLE_FDX:
             if (on && ssl_defaults.noLocks) {
                 PORT_SetError(SEC_ERROR_INVALID_ARGS);
                 return SECFailure;
             }
             ssl_defaults.fdx = on;
             break;
 
-        case SSL_V2_COMPATIBLE_HELLO:
-            ssl_defaults.v2CompatibleHello = on;
-            if (!on) {
-                ssl_defaults.enableSSL2 = on;
-            }
-            break;
-
         case SSL_ROLLBACK_DETECTION:
             ssl_defaults.detectRollBack = on;
             break;
 
         case SSL_NO_STEP_DOWN:
             ssl_defaults.noStepDown = on;
             if (on)
                 SSL_DisableDefaultExportCipherSuites();
@@ -1360,18 +1254,16 @@ SSL_SetPolicy(long which, int policy)
 
 SECStatus
 ssl_CipherPolicySet(PRInt32 which, PRInt32 policy)
 {
     SECStatus rv = SECSuccess;
 
     if (ssl_IsRemovedCipherSuite(which)) {
         rv = SECSuccess;
-    } else if (SSL_IS_SSL2_CIPHER(which)) {
-        rv = ssl2_SetPolicy(which, policy);
     } else {
         rv = ssl3_SetPolicy((ssl3CipherSuite)which, policy);
     }
     return rv;
 }
 SECStatus
 SSL_CipherPolicySet(PRInt32 which, PRInt32 policy)
 {
@@ -1390,18 +1282,16 @@ SSL_CipherPolicyGet(PRInt32 which, PRInt
 
     if (!oPolicy) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
     }
     if (ssl_IsRemovedCipherSuite(which)) {
         *oPolicy = SSL_NOT_ALLOWED;
         rv = SECSuccess;
-    } else if (SSL_IS_SSL2_CIPHER(which)) {
-        rv = ssl2_GetPolicy(which, oPolicy);
     } else {
         rv = ssl3_GetPolicy((ssl3CipherSuite)which, oPolicy);
     }
     return rv;
 }
 
 /* Part of the public NSS API.
  * Since this is a global (not per-socket) setting, we cannot use the
@@ -1421,30 +1311,23 @@ SSL_EnableCipher(long which, PRBool enab
     if (ssl_IsRemovedCipherSuite(which))
         return SECSuccess;
     return SSL_CipherPrefSetDefault(which, enabled);
 }
 
 SECStatus
 ssl_CipherPrefSetDefault(PRInt32 which, PRBool enabled)
 {
-    SECStatus rv = SECSuccess;
-
     if (ssl_IsRemovedCipherSuite(which))
         return SECSuccess;
     if (enabled && ssl_defaults.noStepDown && SSL_IsExportCipherSuite(which)) {
         PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
         return SECFailure;
     }
-    if (SSL_IS_SSL2_CIPHER(which)) {
-        rv = ssl2_CipherPrefSetDefault(which, enabled);
-    } else {
-        rv = ssl3_CipherPrefSetDefault((ssl3CipherSuite)which, enabled);
-    }
-    return rv;
+    return ssl3_CipherPrefSetDefault((ssl3CipherSuite)which, enabled);
 }
 
 SECStatus
 SSL_CipherPrefSetDefault(PRInt32 which, PRBool enabled)
 {
     SECStatus rv = ssl_Init();
 
     if (rv != SECSuccess) {
@@ -1460,46 +1343,38 @@ SSL_CipherPrefGetDefault(PRInt32 which, 
 
     if (!enabled) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
     }
     if (ssl_IsRemovedCipherSuite(which)) {
         *enabled = PR_FALSE;
         rv = SECSuccess;
-    } else if (SSL_IS_SSL2_CIPHER(which)) {
-        rv = ssl2_CipherPrefGetDefault(which, enabled);
     } else {
         rv = ssl3_CipherPrefGetDefault((ssl3CipherSuite)which, enabled);
     }
     return rv;
 }
 
 SECStatus
 SSL_CipherPrefSet(PRFileDesc *fd, PRInt32 which, PRBool enabled)
 {
-    SECStatus rv;
     sslSocket *ss = ssl_FindSocket(fd);
 
     if (!ss) {
         SSL_DBG(("%d: SSL[%d]: bad socket in CipherPrefSet", SSL_GETPID(), fd));
         return SECFailure;
     }
     if (ssl_IsRemovedCipherSuite(which))
         return SECSuccess;
     if (enabled && ss->opt.noStepDown && SSL_IsExportCipherSuite(which)) {
         PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
         return SECFailure;
     }
-    if (SSL_IS_SSL2_CIPHER(which)) {
-        rv = ssl2_CipherPrefSet(ss, which, enabled);
-    } else {
-        rv = ssl3_CipherPrefSet(ss, (ssl3CipherSuite)which, enabled);
-    }
-    return rv;
+    return ssl3_CipherPrefSet(ss, (ssl3CipherSuite)which, enabled);
 }
 
 SECStatus
 SSL_CipherPrefGet(PRFileDesc *fd, PRInt32 which, PRBool *enabled)
 {
     SECStatus rv;
     sslSocket *ss = ssl_FindSocket(fd);
 
@@ -1510,18 +1385,16 @@ SSL_CipherPrefGet(PRFileDesc *fd, PRInt3
     if (!ss) {
         SSL_DBG(("%d: SSL[%d]: bad socket in CipherPrefGet", SSL_GETPID(), fd));
         *enabled = PR_FALSE;
         return SECFailure;
     }
     if (ssl_IsRemovedCipherSuite(which)) {
         *enabled = PR_FALSE;
         rv = SECSuccess;
-    } else if (SSL_IS_SSL2_CIPHER(which)) {
-        rv = ssl2_CipherPrefGet(ss, which, enabled);
     } else {
         rv = ssl3_CipherPrefGet(ss, (ssl3CipherSuite)which, enabled);
     }
     return rv;
 }
 
 SECStatus
 NSS_SetDomesticPolicy(void)
@@ -2298,20 +2171,16 @@ SSL_PeerSignedCertTimestamps(PRFileDesc 
         return NULL;
     }
 
     if (!ss->sec.ci.sid) {
         PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
         return NULL;
     }
 
-    if (ss->sec.ci.sid->version < SSL_LIBRARY_VERSION_3_0) {
-        PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
-        return NULL;
-    }
     return &ss->sec.ci.sid->u.ssl3.signedCertTimestamps;
 }
 
 SECStatus
 SSL_VersionRangeGetSupported(SSLProtocolVariant protocolVariant,
                              SSLVersionRange *vrange)
 {
     if (!vrange) {
@@ -2534,20 +2403,20 @@ ssl_Accept(PRFileDesc *fd, PRNetAddr *so
     if (status != PR_SUCCESS)
         goto loser;
 
     /* Now start server connection handshake with client.
     ** Don't need locks here because nobody else has a reference to ns yet.
     */
     if (ns->opt.useSecurity) {
         if (ns->opt.handshakeAsClient) {
-            ns->handshake = ssl2_BeginClientHandshake;
+            ns->handshake = ssl_BeginClientHandshake;
             ss->handshaking = sslHandshakingAsClient;
         } else {
-            ns->handshake = ssl2_BeginServerHandshake;
+            ns->handshake = ssl_BeginServerHandshake;
             ss->handshaking = sslHandshakingAsServer;
         }
     }
     ns->TCPconnected = 1;
     return newfd;
 
 loser:
     if (ns != NULL)
@@ -2946,33 +2815,31 @@ ssl_Poll(PRFileDesc *fd, PRInt16 how_fla
                     new_flags |= PR_POLL_WRITE; /* do    select on write. */
                 }
             } else if (new_flags & PR_POLL_WRITE) {
                 /* The caller is trying to write, but the handshake is
                 ** blocked waiting for data to read, and the first
                 ** handshake has been sent.  So do NOT to poll on write
                 ** unless we did false start.
                 */
-                if (!(ss->version >= SSL_LIBRARY_VERSION_3_0 &&
-                      ss->ssl3.hs.canFalseStart)) {
+                if (!ss->ssl3.hs.canFalseStart) {
                     new_flags ^= PR_POLL_WRITE; /* don't select on write. */
                 }
                 new_flags |= PR_POLL_READ; /* do    select on read. */
             }
         }
     } else if ((new_flags & PR_POLL_READ) && (SSL_DataPending(fd) > 0)) {
         *p_out_flags = PR_POLL_READ; /* it's ready already. */
         return new_flags;
     } else if ((ss->lastWriteBlocked) && (how_flags & PR_POLL_READ) &&
                (ss->pendingBuf.len != 0)) { /* write data waiting to be sent */
         new_flags |= PR_POLL_WRITE;         /* also select on write. */
     }
 
-    if (ss->version >= SSL_LIBRARY_VERSION_3_0 &&
-        ss->ssl3.hs.restartTarget != NULL) {
+    if (ss->ssl3.hs.restartTarget != NULL) {
         /* Read and write will block until the asynchronous callback completes
          * (e.g. until SSL_AuthCertificateComplete is called), so don't tell
          * the caller to poll the socket unless there is pending write data.
          */
         if (ss->lastWriteBlocked && ss->pendingBuf.len != 0) {
             /* Ignore any newly-received data on the socket, but do wait for
              * the socket to become writable again. Here, it is OK for an error
              * to be detected, because our logic for sending pending write data
@@ -3577,19 +3444,16 @@ ssl_NewSocket(PRBool makeLocks, SSLProto
         ss->opt.noLocks = !makeLocks;
         ss->vrange = *VERSIONS_DEFAULTS(protocolVariant);
         ss->protocolVariant = protocolVariant;
 
         ss->peerID = NULL;
         ss->rTimeout = PR_INTERVAL_NO_TIMEOUT;
         ss->wTimeout = PR_INTERVAL_NO_TIMEOUT;
         ss->cTimeout = PR_INTERVAL_NO_TIMEOUT;
-        ss->cipherSpecs = NULL;
-        ss->sizeCipherSpecs = 0; /* produced lazily */
-        ss->preferredCipher = NULL;
         ss->url = NULL;
 
         for (i = kt_null; i < kt_kea_size; i++) {
             sslServerCerts *sc = ss->serverCerts + i;
             sc->serverCert = NULL;
             sc->serverCertChain = NULL;
             sc->serverKeyPair = NULL;
             sc->serverKeyBits = 0;
@@ -3609,30 +3473,29 @@ ssl_NewSocket(PRBool makeLocks, SSLProto
         ss->sniSocketConfigArg = NULL;
         ss->getClientAuthData = NULL;
         ss->handleBadCert = NULL;
         ss->badCertArg = NULL;
         ss->pkcs11PinArg = NULL;
         ss->ephemeralECDHKeyPair = NULL;
 
         ssl_ChooseOps(ss);
-        ssl2_InitSocketPolicy(ss);
         ssl3_InitSocketPolicy(ss);
         PR_INIT_CLIST(&ss->ssl3.hs.lastMessageFlight);
         PR_INIT_CLIST(&ss->ssl3.hs.remoteKeyShares);
 
         if (makeLocks) {
             status = ssl_MakeLocks(ss);
             if (status != SECSuccess)
                 goto loser;
         }
         status = ssl_CreateSecurityInfo(ss);
         if (status != SECSuccess)
             goto loser;
-        status = ssl_InitGather(&ss->gs);
+        status = ssl3_InitGather(&ss->gs);
         if (status != SECSuccess) {
         loser:
             ssl_DestroySocketContents(ss);
             ssl_DestroyLocks(ss);
             PORT_Free(ss);
             ss = NULL;
         }
     }
--- a/lib/ssl/ssltrace.c
+++ b/lib/ssl/ssltrace.c
@@ -65,166 +65,16 @@ ssl_PrintBuf(sslSocket *ss, const char *
         }
     }
     if (bp > buf) {
         *ap = 0;
         SSL_TRACE(("   %s", buf));
     }
 }
 
-#define LEN(cp) (((cp)[0] << 8) | ((cp)[1]))
-
-static void
-PrintType(sslSocket *ss, char *msg)
-{
-    if (ss) {
-        SSL_TRACE(("%d: SSL[%d]: dump-msg: %s", SSL_GETPID(), ss->fd, msg));
-    } else {
-        SSL_TRACE(("%d: SSL: dump-msg: %s", SSL_GETPID(), msg));
-    }
-}
-
-static void
-PrintInt(sslSocket *ss, char *msg, unsigned v)
-{
-    if (ss) {
-        SSL_TRACE(("%d: SSL[%d]:           %s=%u", SSL_GETPID(), ss->fd, msg, v));
-    } else {
-        SSL_TRACE(("%d: SSL:           %s=%u", SSL_GETPID(), msg, v));
-    }
-}
-
-/* PrintBuf is just like ssl_PrintBuf above, except that:
- * a) It prefixes each line of the buffer with "XX: SSL[xxx]           "
- * b) It dumps only hex, not ASCII.
- */
-static void
-PrintBuf(sslSocket *ss, char *msg, unsigned char *cp, int len)
-{
-    char buf[80];
-    char *bp;
-
-    if (ss) {
-        SSL_TRACE(("%d: SSL[%d]:           %s [Len: %d]",
-                   SSL_GETPID(), ss->fd, msg, len));
-    } else {
-        SSL_TRACE(("%d: SSL:           %s [Len: %d]",
-                   SSL_GETPID(), msg, len));
-    }
-    bp = buf;
-    while (--len >= 0) {
-        unsigned char ch = *cp++;
-        *bp++ = hex[(ch >> 4) & 0xf];
-        *bp++ = hex[ch & 0xf];
-        *bp++ = ' ';
-        if (bp + 4 > buf + 50) {
-            *bp = 0;
-            if (ss) {
-                SSL_TRACE(("%d: SSL[%d]:             %s",
-                           SSL_GETPID(), ss->fd, buf));
-            } else {
-                SSL_TRACE(("%d: SSL:             %s", SSL_GETPID(), buf));
-            }
-            bp = buf;
-        }
-    }
-    if (bp > buf) {
-        *bp = 0;
-        if (ss) {
-            SSL_TRACE(("%d: SSL[%d]:             %s",
-                       SSL_GETPID(), ss->fd, buf));
-        } else {
-            SSL_TRACE(("%d: SSL:             %s", SSL_GETPID(), buf));
-        }
-    }
-}
-
-void
-ssl_DumpMsg(sslSocket *ss, unsigned char *bp, unsigned len)
-{
-    switch (bp[0]) {
-        case SSL_MT_ERROR:
-            PrintType(ss, "Error");
-            PrintInt(ss, "error", LEN(bp + 1));
-            break;
-
-        case SSL_MT_CLIENT_HELLO: {
-            unsigned lcs = LEN(bp + 3);
-            unsigned ls = LEN(bp + 5);
-            unsigned lc = LEN(bp + 7);
-
-            PrintType(ss, "Client-Hello");
-
-            PrintInt(ss, "version (Major)", bp[1]);
-            PrintInt(ss, "version (minor)", bp[2]);
-
-            PrintBuf(ss, "cipher-specs", bp + 9, lcs);
-            PrintBuf(ss, "session-id", bp + 9 + lcs, ls);
-            PrintBuf(ss, "challenge", bp + 9 + lcs + ls, lc);
-        } break;
-        case SSL_MT_CLIENT_MASTER_KEY: {
-            unsigned lck = LEN(bp + 4);
-            unsigned lek = LEN(bp + 6);
-            unsigned lka = LEN(bp + 8);
-
-            PrintType(ss, "Client-Master-Key");
-
-            PrintInt(ss, "cipher-choice", bp[1]);
-            PrintInt(ss, "key-length", LEN(bp + 2));
-
-            PrintBuf(ss, "clear-key", bp + 10, lck);
-            PrintBuf(ss, "encrypted-key", bp + 10 + lck, lek);
-            PrintBuf(ss, "key-arg", bp + 10 + lck + lek, lka);
-        } break;
-        case SSL_MT_CLIENT_FINISHED:
-            PrintType(ss, "Client-Finished");
-            PrintBuf(ss, "connection-id", bp + 1, len - 1);
-            break;
-        case SSL_MT_SERVER_HELLO: {
-            unsigned lc = LEN(bp + 5);
-            unsigned lcs = LEN(bp + 7);
-            unsigned lci = LEN(bp + 9);
-
-            PrintType(ss, "Server-Hello");
-
-            PrintInt(ss, "session-id-hit", bp[1]);
-            PrintInt(ss, "certificate-type", bp[2]);
-            PrintInt(ss, "version (Major)", bp[3]);
-            PrintInt(ss, "version (minor)", bp[3]);
-            PrintBuf(ss, "certificate", bp + 11, lc);
-            PrintBuf(ss, "cipher-specs", bp + 11 + lc, lcs);
-            PrintBuf(ss, "connection-id", bp + 11 + lc + lcs, lci);
-        } break;
-        case SSL_MT_SERVER_VERIFY:
-            PrintType(ss, "Server-Verify");
-            PrintBuf(ss, "challenge", bp + 1, len - 1);
-            break;
-        case SSL_MT_SERVER_FINISHED:
-            PrintType(ss, "Server-Finished");
-            PrintBuf(ss, "session-id", bp + 1, len - 1);
-            break;
-        case SSL_MT_REQUEST_CERTIFICATE:
-            PrintType(ss, "Request-Certificate");
-            PrintInt(ss, "authentication-type", bp[1]);
-            PrintBuf(ss, "certificate-challenge", bp + 2, len - 2);
-            break;
-        case SSL_MT_CLIENT_CERTIFICATE: {
-            unsigned lc = LEN(bp + 2);
-            unsigned lr = LEN(bp + 4);
-            PrintType(ss, "Client-Certificate");
-            PrintInt(ss, "certificate-type", bp[1]);
-            PrintBuf(ss, "certificate", bp + 6, lc);
-            PrintBuf(ss, "response", bp + 6 + lc, lr);
-        } break;
-        default:
-            ssl_PrintBuf(ss, "sending *unknown* message type", bp, len);
-            return;
-    }
-}
-
 void
 ssl_Trace(const char *format, ...)
 {
     char buf[2000];
     va_list args;
 
     if (ssl_trace_iob) {
         va_start(args, format);
--- a/lib/util/ciferfam.h
+++ b/lib/util/ciferfam.h
@@ -9,17 +9,17 @@
 
 #ifndef _CIFERFAM_H_
 #define _CIFERFAM_H_
 
 #include "utilrename.h"
 /* Cipher Suite "Families" */
 #define CIPHER_FAMILY_PKCS12			"PKCS12"
 #define CIPHER_FAMILY_SMIME			"SMIME"
-#define CIPHER_FAMILY_SSL2			"SSLv2"
+#define CIPHER_FAMILY_SSL2                      "SSLv2" /* deprecated */
 #define CIPHER_FAMILY_SSL3			"SSLv3"
 #define CIPHER_FAMILY_SSL			"SSL"
 #define CIPHER_FAMILY_ALL			""
 #define CIPHER_FAMILY_UNKNOWN			"UNKNOWN"
 
 #define CIPHER_FAMILYID_MASK			0xFFFF0000L
 #define CIPHER_FAMILYID_SSL			0x00000000L
 #define CIPHER_FAMILYID_SMIME			0x00010000L
--- a/tests/iopr/server_scr/cipher.list
+++ b/tests/iopr/server_scr/cipher.list
@@ -110,26 +110,14 @@ TLS_DH_anon_WITH_AES_256_CBC_SHA        
 #
 TLS_RSA_EXPORT_WITH_DES_CBC_SHA         EXP1024-DES-CBC-SHA
 TLS_RSA_EXPORT_WITH_RC4_56_SHA          EXP1024-RC4-SHA
 TLS_DHE_DSS_EXPORT_WITH_DES_CBC_SHA     EXP1024-DHE-DSS-DES-CBC-SHA
 TLS_DHE_DSS_EXPORT_WITH_RC4_56_SHA      EXP1024-DHE-DSS-RC4-SHA
 TLS_DHE_DSS_WITH_RC4_128_SHA            DHE-DSS-RC4-SHA
 
 #
-#SSL v2.0 cipher suites.
-#
-SSL2_RC4_128_WITH_MD5                 RC4-MD5
-SSL2_RC4_128_EXPORT40_WITH_MD5        EXP-RC4-MD5
-SSL2_RC2_128_CBC_WITH_MD5             RC2-MD5
-SSL2_RC2_128_CBC_EXPORT40_WITH_MD5    EXP-RC2-MD5
-SSL2_IDEA_128_CBC_WITH_MD5            IDEA-CBC-MD5
-SSL2_DES_64_CBC_WITH_MD5              DES-CBC-MD5
-SSL2_DES_192_EDE3_CBC_WITH_MD5        DES-CBC3-MD5
-
-
-#
 # FIPS cipher list
 #        
 TLS_RSA_FIPS_WITH_3DES_EDE_CBC_SHA      Not_implemented
 TLS_RSA_FIPS_WITH_DES_CBC_SHA           Not_implemented
 SSL3_RSA_FIPS_WITH_3DES_EDE_CBC_SHA     Not_implemented
 SSL3_RSA_FIPS_WITH_DES_CBC_SHA          Not_implemented
deleted file mode 100644
--- a/tests/pkcs11/netscape/suites/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY).   #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL)          #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL)       #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL).      #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL)                              #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL)                           #
-#######################################################################
-
-# include $(CORE_DEPTH)/$(MODULE)/config/rules.mk
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL).                              #
-#######################################################################
-
-
-
deleted file mode 100644
--- a/tests/pkcs11/netscape/suites/config.mk
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-all::
-
-release:: release_security abort_rule
-
-release_security:
-	@echo "cd security; $(MAKE) release"
-	$(MAKE) -C security release
-
-abort_rule:
-	@"Security Complete. (Don't worry about this, it really should abort here!)"
deleted file mode 100644
--- a/tests/pkcs11/netscape/suites/manifest.mn
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../../../..
- 
-DIRS =  security \
-        $(NULL)
- 
deleted file mode 100644
--- a/tests/pkcs11/netscape/suites/security/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY).   #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL)          #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL)       #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL).      #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL)                              #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL)                           #
-#######################################################################
-
-#include $(CORE_DEPTH)/$(MODULE)/config/rules.mk
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL).                              #
-#######################################################################
-
-
-
deleted file mode 100644
--- a/tests/pkcs11/netscape/suites/security/config.mk
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-all::
-
-release:: release_des release_des3 release_sha1 release_dsa abort_rule
-
-release_des:
-	@echo "cd des; $(MAKE) release"
-	$(MAKE) -C des release
-
-release_des3:
-	@echo "cd des3; $(MAKE) release"
-	$(MAKE) -C des3 release
-
-release_sha1:
-	@echo "cd sha1; $(MAKE) release"
-	$(MAKE) -C sha1 release
-
-release_dsa:
-	@echo "cd dsa; $(MAKE) release"
-	$(MAKE) -C dsa release
-
-abort_rule:
-	@"Security Suites Complete. (Don't worry about this, it really should abort here!)"
deleted file mode 100644
--- a/tests/pkcs11/netscape/suites/security/manifest.mn
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../../../../..
-
-#MODULE = sectools
-
-DIRS =	pkcs11 \
-	ssl \
-	$(NULL)
-
deleted file mode 100644
--- a/tests/pkcs11/netscape/suites/security/pkcs11/Makefile
+++ /dev/null
@@ -1,49 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY).   #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL)          #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL)       #
-#######################################################################
-
-#include $(CORE_DEPTH)/$(MODULE)/config/config.mk
- 
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL).      #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL)                              #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL)                           #
-#######################################################################
-
-#include $(CORE_DEPTH)/$(MODULE)/config/rules.mk
-include $(CORE_DEPTH)/nss/cmd/platlibs.mk
-include $(CORE_DEPTH)/nss/cmd/platrules.mk
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL).                              #
-#######################################################################
-
-include rules.mk
deleted file mode 100644
--- a/tests/pkcs11/netscape/suites/security/pkcs11/config.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# Adjust specific variables for all platforms                         #
-#######################################################################
-OS_CFLAGS += -DNSPR20=1
-
-#######################################################################
-# Set the LDFLAGS value to encompass all normal link options, all     #
-# library names, and all special system linking options               #
-#######################################################################
-
-LDFLAGS = $(LDOPTS) $(LIBSECMOD) $(LIBHASH) $(LIBCERT) $(LIBKEY) \
-$(LIBCRYPTO) $(LIBSECUTIL) $(LIBDBM) $(LIBPLC) $(LIBPLDS) $(LIBPR) \
-$(LIBSECTOOLS) $(DLLSYSTEM)
-
-# These are the libraries from the PKCS #5 suite:
-#LDFLAGS = $(LDOPTS) $(LIBSECTOOLS) $(LIBSSL) $(LIBPKCS7) $(LIBCERT) $(LIBKEY) $(LIBSECMOD) $(LIBCRYPTO) $(LIBSECUTIL) $(LIBSECMOD) $(LIBSSL) $(LIBPKCS7) $(LIBCERT) $(LIBKEY) $(LIBCRYPTO) $(LIBSECUTIL) $(LIBHASH) $(LIBDBM) $(LIBPLDS) $(LIBPLC) $(LIBPR) $(DLLSYSTEM)
-
-#######################################################################
-# Set the TARGETS value to build one executable from each object file #
-#######################################################################
-
-# TARGETS = $(OBJS:$(OBJ_SUFFIX)=$(PROG_SUFFIX))
-
deleted file mode 100644
--- a/tests/pkcs11/netscape/suites/security/pkcs11/manifest.mn
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-CORE_DEPTH=../../../../../../..
-
-#MODULE = sectools
-
-CSRCS = pk11test.c
-
-PROGRAM = pk11test
-
-REQUIRES = seccmd dbm nss
-
-REGRESSION_SPEC = pkcs11.reg
-
-RESULTS_SUBDIR = security/pkcs11
deleted file mode 100644
--- a/tests/pkcs11/netscape/suites/security/pkcs11/pk11test.c
+++ /dev/null
@@ -1,1331 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#define VERSION_MAJOR 1
-#define VERSION_MINOR 0
-#define VERSION_POINT 7
-/* Standard C includes */
-#include <stdlib.h>
-#include <stdio.h>
-
-/* NSPR includes */
-#include <prio.h>
-#include <prprf.h>
-#include <plarena.h>
-#include <prinit.h>
-#include <prmem.h>
-
-/* security includes */
-#include <pkcs11t.h>
-#include <secmodt.h>
-#include <pk11func.h>
-#include <secmod.h>
-#include <secutil.h>
-#include <keyt.h>
-
-/* replacer header file */
-#include "pk11test.h"
-
-#include "pkcs11.h"
-
-void SEC_Init(void);
-
-PRStatus InitCrypto(char*);
-int TestUserManagement();
-int TestCrypto();
-MechInfo* GetMechInfo(CK_MECHANISM_TYPE type);
-int TestEncrypt(CK_MECHANISM_TYPE mech);
-int TestSign(CK_MECHANISM_TYPE mech);
-int TestDigest(CK_MECHANISM_TYPE mech);
-int TestHMAC(CK_MECHANISM_TYPE mech);
-int TestSymmetricEncrypt(CK_MECHANISM_TYPE mech);
-int TestPKEncrypt(CK_MECHANISM_TYPE mech);
-
-
-static char* userpw = NULL;
-static int secerror=0;
-/* PK11SymKey *symkey=NULL;*/
-PK11SlotInfo *slot=NULL;
-
-/* Errors */
-enum {
-	NO_ERROR_AT_ALL=0,
-	NO_SUCH_SLOT=1,
-	KEY_GEN_FAILED,
-	CREATE_CONTEXT_FAILED,
-	INTERNAL_RNG_FAILED,
-	MECH_NOT_FOUND,
-	INPUT_FILE_ERROR,
-	KEY_COPY_FAILED,
-	CIPHER_OP_FAILED,
-	FINALIZE_FAILED,
-	RESULTS_DONT_MATCH,
-	PARAM_GEN_FAILED,
-	PLAINTEXT_DOESNT_MATCH,
-	ENCRYPTION_IS_NOOP,
-	WRAP_PRIVKEY_FAILED,
-	WRAP_SYMKEY_FAILED,
-	UNWRAP_SYMKEY_FAILED,
-	UNWRAPPED_KEY_DOESNT_MATCH,
-	UNWRAP_PRIVKEY_FAILED,
-	SIGNATURE_FAILED,
-	SIGNATURE_DOESNT_VERIFY,
-	AUTHENTICATION_FAILED,
-	AUTHENTICATION_SUCCEEDED,
-	MODDB_ACCESS
-};
-
-static char* errString[] = {
-	"No error",
-	"No such slot",
-	"Failed to generate key",
-	"Failed to create a cryptographic context",
-	"Failed to generate random bytes",
-	"Mechanism was not found",
-	"Error in input file",
-	"Failed to copy key from internal to external module",
-	"Cipher operation failed",
-	"Cipher finalization failed",
-	"Internal module produced a different result than the target module",
-	"Failed to generate cryptographic parameters",
-	"Recovered plaintext does not match original plaintext",
-	"Ciphertext is the same as plaintext",
-	"Unable to wrap private key",
-	"Unable to wrap symmetric key",
-	"Unable to unwrap symmetric key",
-	"Unwrapped key does not match original key",
-	"Unable to unwrap private key",
-	"Signing operation failed",
-	"Incorrect signature: doesn't verify",
-	"Failed to authenticate to slot",
-	"Authenticated to slot with incorrect password",
-	"Unable to access security module database"
-};
-
-/***********************************************************************
- *
- * R e a d I n p u t F i l e
- *
- * Read tokenname and module name from the file with the indicated name.
- * Pass in the addresses of pointers.  They will be set to point at
- * dynamically-allocated memory.
- *
- * Returns 0 on success, -1 on error with file.
- */
-int
-ReadInputFile(char *filename, char**tokenname, char**moddbname, char **userpw)
-{
-	PRFileDesc* file=NULL;
-	char readbuf[1025];
-	int numbytes=0;
-	char *cp;
-
-	*tokenname = NULL;
-	*moddbname = NULL;
-
-	/* Open file */
-	file = PR_Open(filename, PR_RDONLY, 0);
-	if(!file) {
-		return -1;
-	}
-
-	/* Read in everything */
-	numbytes = PR_Read(file, readbuf, 1024);
-	if(numbytes==-1) {
-		goto loser;
-	}
-	readbuf[numbytes] = '\0'; /* make sure we're null-terminated */
-
-	/* Get tokenname */
-	cp = strtok(readbuf, "\r\n");
-	if(cp == NULL) {
-		goto loser;
-	}
-	*tokenname = PR_Malloc(strlen(cp)+1);
-	strcpy(*tokenname, cp);
-
-	/* get moddbname */
-	cp = strtok(NULL, "\r\n");
-	if(cp == NULL) {
-		goto loser;
-	}
-	*moddbname = PR_Malloc(strlen(cp)+1);
-	strcpy(*moddbname, cp);
-
-	/* Get module PIN */
-	cp = strtok(NULL, "\r\n");
-	if(cp == NULL) {
-		goto loser;
-	}
-	*userpw = PR_Malloc(strlen(cp)+1);
-	strcpy(*userpw, cp);
-
-	PR_Close(file);
-	return 0;
-
-loser:
-	if(file) {
-		PR_Close(file);
-	}
-	if(*tokenname) {
-		PR_Free(*tokenname);
-		*tokenname = NULL;
-	}
-	if(*moddbname) {
-		PR_Free(*moddbname);
-		*moddbname = NULL;
-	}
-	return -1;
-}
-
-static PRBool supplyPassword=PR_TRUE;
-char*
-PasswordFunc(PK11SlotInfo *slot, PRBool loadcerts, void *wincx)
-{
-	if(supplyPassword) {
-		/*PR_fprintf(PR_STDOUT, "Feeding password: |%s|\n", userpw);*/
-		supplyPassword = PR_FALSE;
-		return PL_strdup(userpw);
-	} else  {
-		/*PR_fprintf(PR_STDOUT, "PasswordFunc supplying NULL.\n");*/
-		return NULL;
-	}
-}
-	
-
-/**********************************************************************
- *
- * m a i n
- *
- */
-int
-main(int argc, char *argv[])
-{
-	char *tokenname=NULL;
-	char *moddbname=NULL;
-	int errcode;
-
-	if(argc < 3) {
-		PR_fprintf(PR_STDERR,
-"\nPKCS #11 Test Suite Version %d.%d.%d\n\
-Usage: pkcs11 testid configfile\n",VERSION_MAJOR,VERSION_MINOR,VERSION_POINT);
-		return -1;
-	}
-
-	testId = atoi(argv[1]);
-	if(ReadInputFile(argv[2], &tokenname, &moddbname, &userpw)) {
-		errcode = INPUT_FILE_ERROR;
-		goto loser;
-	}
-
-	PR_fprintf(PR_STDOUT, "testId=%d\n", testId);
-	PR_fprintf(PR_STDOUT, "tokenname=%s\n", tokenname);
-	PR_fprintf(PR_STDOUT, "moddbname=%s\n", moddbname);
-
-	PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
-
- 	if( InitCrypto(moddbname) != PR_SUCCESS ) {
-		errcode = MODDB_ACCESS;
-		goto loser;
-	}
-
-	slot = PK11_FindSlotByName(tokenname);
-	if(!slot) {
-		errcode = NO_SUCH_SLOT;
-		goto loser;
-	}
-
-	if(!REP_USE_CORRECT_PIN && userpw) {
-		/* don't use the pin passed in */
-		userpw[0]++;
-	}
-	PK11_SetPasswordFunc(PasswordFunc);
-	if(PK11_NeedLogin(slot)) {
-		SECStatus result;
-		supplyPassword = PR_TRUE;
-		result = PK11_Authenticate(slot, PR_FALSE, NULL);
-		/* If we just did an invalid login, login correctly so we don't
-		 * cause the token to lock us out */
-		if(!REP_USE_CORRECT_PIN) {
-			userpw[0]--;
-			supplyPassword = PR_TRUE;
-			PK11_Authenticate(slot, PR_FALSE, NULL);
-		}
-		if(REP_USE_CORRECT_PIN && result!=SECSuccess) {
-			errcode =  AUTHENTICATION_FAILED;
-			goto loser;
-		} else if(!REP_USE_CORRECT_PIN && result==SECSuccess) {
-			errcode = AUTHENTICATION_SUCCEEDED;
-			goto loser;
-		}
-	}
-
-	errcode = TestCrypto();
-
-loser:
-	if(tokenname) {
-		PR_Free(tokenname); tokenname = NULL;
-	}
-	if(moddbname) {
-		PR_Free(moddbname); moddbname = NULL;
-	}
-	if(errcode) {
-	    PR_fprintf(PR_STDOUT, "Exiting with error: %s.\n\n", errString[errcode]);
-	} else {
-		PR_fprintf(PR_STDOUT, "Test was successful\n\n");
-	}
-	return errcode;
-}
-
-/**********************************************************************
- *
- * I n i t C r y p t o
- *
- */
-PRStatus
-InitCrypto(char *moddbname)
-{
-	SEC_Init();
-
-	if( PR_Access(moddbname, PR_ACCESS_EXISTS) != PR_SUCCESS) {
-		PR_fprintf(PR_STDERR, "Error: %s does not exist.\n", moddbname);
-		return PR_FAILURE;
-	}
-	if( PR_Access(moddbname, PR_ACCESS_READ_OK) != PR_SUCCESS) {
-		PR_fprintf(PR_STDERR, "Error: %s is not readable.\n",
-			moddbname);
-		return PR_FAILURE;
-	}
-
-	SECMOD_init(moddbname);
-	return PR_SUCCESS;
-}
-
-/**********************************************************************
- *
- * T e s t C r y p t o
- *
- */
-int
-TestCrypto()
-{
-	MechInfo *mechInfo;
-	int errcode;
-	unsigned short testcount=0;
-
-	if(!PK11_DoesMechanism(slot, REP_MECHANISM)) {
-		return 0;
-	}
-
-	mechInfo = GetMechInfo(REP_MECHANISM);
-	/*PR_fprintf(PR_STDOUT, "Using mechanism %x.\n", REP_MECHANISM);*/
-	if(!mechInfo) {
-		PR_fprintf(PR_STDERR, "Unable to find mech %x\n",
-			REP_MECHANISM);
-		return MECH_NOT_FOUND;
-	}
-
-	if(mechInfo->op & ENCRYPT_OP) {
-		testcount++;
-		errcode = TestEncrypt(REP_MECHANISM);
-		if(errcode) return errcode;
-	}
-
-	if(mechInfo->op & SIGN_OP) {
-		testcount++;
-		errcode = TestSign(REP_MECHANISM);
-		if(errcode) return errcode;
-	}
-
-#if 0
-	if(mechInfo->op & DIGEST_OP) {
-		testcount++;
-		errcode = TestDigest(REP_MECHANISM);
-		if(errcode) return errcode;
-	}
-
-	if(mechInfo->op & HMAC_OP) {
-		testcount++;
-		errcode = TestHMAC(REP_MECHANISM);
-		if(errcode) return errcode;
-	}
-#endif
-
-	return 0;
-}
-
-/**********************************************************************
- *
- * I s S y m m e t r i c
- *
- */
-int
-IsSymmetric(CK_MECHANISM_TYPE mech)
-{
-	switch(mech) {
-	case CKM_RC2_ECB:
-	case CKM_RC2_CBC:
-	case CKM_RC2_CBC_PAD:
-	case CKM_RC4:
-	case CKM_RC5_ECB:
-	case CKM_RC5_CBC:
-	case CKM_RC5_CBC_PAD:
-	case CKM_DES_ECB:
-	case CKM_DES_CBC:
-	case CKM_DES_CBC_PAD:
-	case CKM_DES3_ECB:
-	case CKM_DES3_CBC:
-	case CKM_DES3_CBC_PAD:
-	case CKM_CAST_ECB:
-	case CKM_CAST_CBC: