mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
350 lines
13 KiB
Diff
350 lines
13 KiB
Diff
|
Index: mozilla/security/nss/cmd/tstclnt/tstclnt.c
|
||
|
===================================================================
|
||
|
RCS file: /cvsroot/mozilla/security/nss/cmd/tstclnt/tstclnt.c,v
|
||
|
retrieving revision 1.64
|
||
|
diff -u -8 -p -r1.64 tstclnt.c
|
||
|
--- mozilla/security/nss/cmd/tstclnt/tstclnt.c 6 Oct 2011 22:42:33 -0000 1.64
|
||
|
+++ mozilla/security/nss/cmd/tstclnt/tstclnt.c 16 Nov 2011 08:24:12 -0000
|
||
|
@@ -212,16 +212,18 @@ static void Usage(const char *progName)
|
||
|
"-n nickname");
|
||
|
fprintf(stderr,
|
||
|
"%-20s Bypass PKCS11 layer for SSL encryption and MACing.\n", "-B");
|
||
|
fprintf(stderr, "%-20s Disable SSL v2.\n", "-2");
|
||
|
fprintf(stderr, "%-20s Disable SSL v3.\n", "-3");
|
||
|
fprintf(stderr, "%-20s Disable TLS (SSL v3.1).\n", "-T");
|
||
|
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");
|
||
|
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 Renegotiate N times (resuming session if N>1).\n", "-r N");
|
||
|
fprintf(stderr, "%-20s Enable the session ticket extension.\n", "-u");
|
||
|
fprintf(stderr, "%-20s Enable compression.\n", "-z");
|
||
|
@@ -288,30 +290,54 @@ disableAllSSLCiphers(void)
|
||
|
fprintf(stderr,
|
||
|
"SSL_CipherPrefSet didn't like value 0x%04x (i = %d): %s\n",
|
||
|
suite, i, SECU_Strerror(err));
|
||
|
exit(2);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+typedef struct
|
||
|
+{
|
||
|
+ PRBool shouldPause; /* PR_TRUE if we should use asynchronous peer cert
|
||
|
+ * authentication */
|
||
|
+ PRBool isPaused; /* PR_TRUE if libssl is waiting for us to validate the
|
||
|
+ * peer's certificate and restart the handshake. */
|
||
|
+ void * dbHandle; /* Certificate database handle to use while
|
||
|
+ * authenticating the peer's certificate. */
|
||
|
+} ServerCertAuth;
|
||
|
+
|
||
|
/*
|
||
|
* Callback is called when incoming certificate is not valid.
|
||
|
* Returns SECSuccess to accept the cert anyway, SECFailure to reject.
|
||
|
*/
|
||
|
static SECStatus
|
||
|
ownBadCertHandler(void * arg, PRFileDesc * socket)
|
||
|
{
|
||
|
PRErrorCode err = PR_GetError();
|
||
|
/* can log invalid cert here */
|
||
|
fprintf(stderr, "Bad server certificate: %d, %s\n", err,
|
||
|
SECU_Strerror(err));
|
||
|
return SECSuccess; /* override, say it's OK. */
|
||
|
}
|
||
|
|
||
|
+static SECStatus
|
||
|
+ownAuthCertificate(void *arg, PRFileDesc *fd, PRBool checkSig,
|
||
|
+ PRBool isServer)
|
||
|
+{
|
||
|
+ ServerCertAuth * serverCertAuth = (ServerCertAuth *) arg;
|
||
|
+
|
||
|
+ FPRINTF(stderr, "using asynchronous certificate validation\n", progName);
|
||
|
+
|
||
|
+ PORT_Assert(serverCertAuth->shouldPause);
|
||
|
+ PORT_Assert(!serverCertAuth->isPaused);
|
||
|
+ serverCertAuth->isPaused = PR_TRUE;
|
||
|
+ return SECWouldBlock;
|
||
|
+}
|
||
|
+
|
||
|
SECStatus
|
||
|
own_GetClientAuthData(void * arg,
|
||
|
PRFileDesc * socket,
|
||
|
struct CERTDistNamesStr * caNames,
|
||
|
struct CERTCertificateStr ** pRetCert,
|
||
|
struct SECKEYPrivateKeyStr **pRetKey)
|
||
|
{
|
||
|
if (verbose > 1) {
|
||
|
@@ -493,21 +519,47 @@ separateReqHeader(const PRFileDesc* outF
|
||
|
} else if (((c) >= 'a') && ((c) <= 'f')) { \
|
||
|
i = (c) - 'a' + 10; \
|
||
|
} else if (((c) >= 'A') && ((c) <= 'F')) { \
|
||
|
i = (c) - 'A' + 10; \
|
||
|
} else { \
|
||
|
Usage(progName); \
|
||
|
}
|
||
|
|
||
|
+static SECStatus
|
||
|
+restartHandshakeAfterServerCertIfNeeded(PRFileDesc * fd,
|
||
|
+ ServerCertAuth * serverCertAuth,
|
||
|
+ PRBool override)
|
||
|
+{
|
||
|
+ SECStatus rv;
|
||
|
+
|
||
|
+ if (!serverCertAuth->isPaused)
|
||
|
+ return SECSuccess;
|
||
|
+
|
||
|
+ FPRINTF(stderr, "%s: handshake was paused by auth certificate hook\n",
|
||
|
+ progName);
|
||
|
+
|
||
|
+ serverCertAuth->isPaused = PR_FALSE;
|
||
|
+ rv = SSL_AuthCertificate(serverCertAuth->dbHandle, fd, PR_TRUE, PR_FALSE);
|
||
|
+ if (rv != SECSuccess && override) {
|
||
|
+ rv = ownBadCertHandler(NULL, fd);
|
||
|
+ }
|
||
|
+ if (rv != SECSuccess) {
|
||
|
+ return rv;
|
||
|
+ }
|
||
|
+
|
||
|
+ rv = SSL_RestartHandshakeAfterAuthCertificate(fd);
|
||
|
+
|
||
|
+ return rv;
|
||
|
+}
|
||
|
+
|
||
|
int main(int argc, char **argv)
|
||
|
{
|
||
|
PRFileDesc * s;
|
||
|
PRFileDesc * std_out;
|
||
|
- CERTCertDBHandle * handle;
|
||
|
char * host = NULL;
|
||
|
char * certDir = NULL;
|
||
|
char * nickname = NULL;
|
||
|
char * cipherString = NULL;
|
||
|
char * tmp;
|
||
|
int multiplier = 0;
|
||
|
SECStatus rv;
|
||
|
PRStatus status;
|
||
|
@@ -525,51 +577,58 @@ int main(int argc, char **argv)
|
||
|
int enableFalseStart = 0;
|
||
|
PRSocketOptionData opt;
|
||
|
PRNetAddr addr;
|
||
|
PRPollDesc pollset[2];
|
||
|
PRBool pingServerFirst = PR_FALSE;
|
||
|
PRBool clientSpeaksFirst = PR_FALSE;
|
||
|
PRBool wrStarted = PR_FALSE;
|
||
|
PRBool skipProtoHeader = PR_FALSE;
|
||
|
+ ServerCertAuth serverCertAuth;
|
||
|
int headerSeparatorPtrnId = 0;
|
||
|
int error = 0;
|
||
|
PRUint16 portno = 443;
|
||
|
char * hs1SniHostName = NULL;
|
||
|
char * hs2SniHostName = NULL;
|
||
|
PLOptState *optstate;
|
||
|
PLOptStatus optstatus;
|
||
|
PRStatus prStatus;
|
||
|
|
||
|
+ serverCertAuth.shouldPause = PR_TRUE;
|
||
|
+ serverCertAuth.isPaused = PR_FALSE;
|
||
|
+ serverCertAuth.dbHandle = NULL;
|
||
|
+
|
||
|
progName = strrchr(argv[0], '/');
|
||
|
if (!progName)
|
||
|
progName = strrchr(argv[0], '\\');
|
||
|
progName = progName ? progName+1 : argv[0];
|
||
|
|
||
|
tmp = PR_GetEnv("NSS_DEBUG_TIMEOUT");
|
||
|
if (tmp && tmp[0]) {
|
||
|
int sec = PORT_Atoi(tmp);
|
||
|
if (sec > 0) {
|
||
|
maxInterval = PR_SecondsToInterval(sec);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
optstate = PL_CreateOptState(argc, argv,
|
||
|
- "23BSTW:a:c:d:fgh:m:n:op:qr:suvw:xz");
|
||
|
+ "23BOSTW:a:c:d:fgh:m:n:op:qr:suvw:xz");
|
||
|
while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
|
||
|
switch (optstate->option) {
|
||
|
case '?':
|
||
|
default : Usage(progName); break;
|
||
|
|
||
|
case '2': disableSSL2 = 1; break;
|
||
|
|
||
|
case '3': disableSSL3 = 1; break;
|
||
|
|
||
|
case 'B': bypassPKCS11 = 1; break;
|
||
|
|
||
|
+ case 'O': serverCertAuth.shouldPause = PR_FALSE; break;
|
||
|
+
|
||
|
case 'S': skipProtoHeader = PR_TRUE; break;
|
||
|
|
||
|
case 'T': disableTLS = 1; break;
|
||
|
|
||
|
case 'a': if (!hs1SniHostName) {
|
||
|
hs1SniHostName = PORT_Strdup(optstate->value);
|
||
|
} else if (!hs2SniHostName) {
|
||
|
hs2SniHostName = PORT_Strdup(optstate->value);
|
||
|
@@ -645,24 +704,18 @@ int main(int argc, char **argv)
|
||
|
} else {
|
||
|
char *certDirTmp = certDir;
|
||
|
certDir = SECU_ConfigDirectory(certDirTmp);
|
||
|
PORT_Free(certDirTmp);
|
||
|
}
|
||
|
rv = NSS_Init(certDir);
|
||
|
if (rv != SECSuccess) {
|
||
|
SECU_PrintError(progName, "unable to open cert database");
|
||
|
-#if 0
|
||
|
- rv = CERT_OpenVolatileCertDB(handle);
|
||
|
- CERT_SetDefaultCertDB(handle);
|
||
|
-#else
|
||
|
return 1;
|
||
|
-#endif
|
||
|
}
|
||
|
- handle = CERT_GetDefaultCertDB();
|
||
|
|
||
|
/* 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. */
|
||
|
@@ -871,17 +924,23 @@ int main(int argc, char **argv)
|
||
|
rv = SSL_OptionSet(s, SSL_ENABLE_FALSE_START, enableFalseStart);
|
||
|
if (rv != SECSuccess) {
|
||
|
SECU_PrintError(progName, "error enabling false start");
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
SSL_SetPKCS11PinArg(s, &pwdata);
|
||
|
|
||
|
- SSL_AuthCertificateHook(s, SSL_AuthCertificate, (void *)handle);
|
||
|
+ serverCertAuth.dbHandle = CERT_GetDefaultCertDB();
|
||
|
+
|
||
|
+ if (serverCertAuth.shouldPause) {
|
||
|
+ SSL_AuthCertificateHook(s, ownAuthCertificate, &serverCertAuth);
|
||
|
+ } else {
|
||
|
+ SSL_AuthCertificateHook(s, SSL_AuthCertificate, serverCertAuth.dbHandle);
|
||
|
+ }
|
||
|
if (override) {
|
||
|
SSL_BadCertHook(s, ownBadCertHandler, NULL);
|
||
|
}
|
||
|
SSL_GetClientAuthDataHook(s, own_GetClientAuthData, (void *)nickname);
|
||
|
SSL_HandshakeCallback(s, handshakeCallback, hs2SniHostName);
|
||
|
if (hs1SniHostName) {
|
||
|
SSL_SetURL(s, hs1SniHostName);
|
||
|
} else {
|
||
|
@@ -979,16 +1038,24 @@ int main(int argc, char **argv)
|
||
|
** socket, read data from socket and write to stdout.
|
||
|
*/
|
||
|
FPRINTF(stderr, "%s: ready...\n", progName);
|
||
|
|
||
|
while (pollset[SSOCK_FD].in_flags | pollset[STDIN_FD].in_flags) {
|
||
|
char buf[4000]; /* buffer for stdin */
|
||
|
int nb; /* num bytes read from stdin. */
|
||
|
|
||
|
+ rv = restartHandshakeAfterServerCertIfNeeded(s, &serverCertAuth,
|
||
|
+ override);
|
||
|
+ if (rv != SECSuccess) {
|
||
|
+ error = 254; /* 254 (usually) means "handshake failed" */
|
||
|
+ SECU_PrintError(progName, "authentication of server cert failed");
|
||
|
+ goto done;
|
||
|
+ }
|
||
|
+
|
||
|
pollset[SSOCK_FD].out_flags = 0;
|
||
|
pollset[STDIN_FD].out_flags = 0;
|
||
|
|
||
|
FPRINTF(stderr, "%s: about to call PR_Poll !\n", progName);
|
||
|
filesReady = PR_Poll(pollset, npds, PR_INTERVAL_NO_TIMEOUT);
|
||
|
if (filesReady < 0) {
|
||
|
SECU_PrintError(progName, "select failed");
|
||
|
error = 1;
|
||
|
@@ -1037,16 +1104,25 @@ int main(int argc, char **argv)
|
||
|
goto done;
|
||
|
}
|
||
|
cc = 0;
|
||
|
}
|
||
|
bufp += cc;
|
||
|
nb -= cc;
|
||
|
if (nb <= 0)
|
||
|
break;
|
||
|
+
|
||
|
+ rv = restartHandshakeAfterServerCertIfNeeded(s,
|
||
|
+ &serverCertAuth, override);
|
||
|
+ if (rv != SECSuccess) {
|
||
|
+ error = 254; /* 254 (usually) means "handshake failed" */
|
||
|
+ SECU_PrintError(progName, "authentication of server cert failed");
|
||
|
+ goto done;
|
||
|
+ }
|
||
|
+
|
||
|
pollset[SSOCK_FD].in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
|
||
|
pollset[SSOCK_FD].out_flags = 0;
|
||
|
FPRINTF(stderr,
|
||
|
"%s: about to call PR_Poll on writable socket !\n",
|
||
|
progName);
|
||
|
cc = PR_Poll(pollset, 1, PR_INTERVAL_NO_TIMEOUT);
|
||
|
FPRINTF(stderr,
|
||
|
"%s: PR_Poll returned with writable socket !\n",
|
||
|
Index: mozilla/security/nss/tests/ssl/ssl.sh
|
||
|
===================================================================
|
||
|
RCS file: /cvsroot/mozilla/security/nss/tests/ssl/ssl.sh,v
|
||
|
retrieving revision 1.106
|
||
|
diff -u -8 -p -r1.106 ssl.sh
|
||
|
--- mozilla/security/nss/tests/ssl/ssl.sh 29 Jan 2010 22:36:25 -0000 1.106
|
||
|
+++ mozilla/security/nss/tests/ssl/ssl.sh 16 Nov 2011 08:24:14 -0000
|
||
|
@@ -303,16 +303,26 @@ ssl_cov()
|
||
|
|
||
|
exec < ${SSLCOV}
|
||
|
while read ectype tls param testname
|
||
|
do
|
||
|
echo "${testname}" | grep "EXPORT" > /dev/null
|
||
|
EXP=$?
|
||
|
echo "${testname}" | grep "SSL2" > /dev/null
|
||
|
SSL2=$?
|
||
|
+
|
||
|
+ if [ "${SSL2}" -eq 0 ] ; then
|
||
|
+ # We cannot use asynchronous cert verification with SSL2
|
||
|
+ SSL2_FLAGS=-O
|
||
|
+ else
|
||
|
+ # Do not enable SSL2 for non-SSL2-specific tests. SSL2 is disabled by
|
||
|
+ # default in libssl but it is enabled by default in tstclnt; we want
|
||
|
+ # to test the libssl default whenever possible.
|
||
|
+ SSL2_FLAGS=-2
|
||
|
+ fi
|
||
|
|
||
|
if [ "$NORM_EXT" = "Extended Test" -a "${SSL2}" -eq 0 ] ; then
|
||
|
echo "$SCRIPTNAME: skipping $testname for $NORM_EXT"
|
||
|
elif [ "$ectype" = "ECC" -a -z "$NSS_ENABLE_ECC" ] ; then
|
||
|
echo "$SCRIPTNAME: skipping $testname (ECC only)"
|
||
|
elif [ "$SERVER_MODE" = "fips" -o "$CLIENT_MODE" = "fips" ] && [ "$SSL2" -eq 0 -o "$EXP" -eq 0 ] ; then
|
||
|
echo "$SCRIPTNAME: skipping $testname (non-FIPS only)"
|
||
|
elif [ "`echo $ectype | cut -b 1`" != "#" ] ; then
|
||
|
@@ -345,21 +355,21 @@ ssl_cov()
|
||
|
is_selfserv_alive
|
||
|
else
|
||
|
kill_selfserv
|
||
|
start_selfserv
|
||
|
mixed=0
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
- echo "tstclnt -p ${PORT} -h ${HOSTADDR} -c ${param} ${TLS_FLAG} ${CLIENT_OPTIONS} \\"
|
||
|
+ echo "tstclnt -p ${PORT} -h ${HOSTADDR} -c ${param} ${TLS_FLAG} ${SSL2_FLAGS} ${CLIENT_OPTIONS} \\"
|
||
|
echo " -f -d ${P_R_CLIENTDIR} -v -w nss < ${REQUEST_FILE}"
|
||
|
|
||
|
rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
|
||
|
- ${PROFTOOL} ${BINDIR}/tstclnt -p ${PORT} -h ${HOSTADDR} -c ${param} ${TLS_FLAG} ${CLIENT_OPTIONS} -f \
|
||
|
+ ${PROFTOOL} ${BINDIR}/tstclnt -p ${PORT} -h ${HOSTADDR} -c ${param} ${TLS_FLAG} ${SSL2_FLAGS} ${CLIENT_OPTIONS} -f \
|
||
|
-d ${P_R_CLIENTDIR} -v -w nss < ${REQUEST_FILE} \
|
||
|
>${TMP}/$HOST.tmp.$$ 2>&1
|
||
|
ret=$?
|
||
|
cat ${TMP}/$HOST.tmp.$$
|
||
|
rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
|
||
|
html_msg $ret 0 "${testname}" \
|
||
|
"produced a returncode of $ret, expected is 0"
|
||
|
fi
|