summaryrefslogtreecommitdiffstats
path: root/security/nss/cmd/tstclnt/tstclnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/cmd/tstclnt/tstclnt.c')
-rw-r--r--security/nss/cmd/tstclnt/tstclnt.c301
1 files changed, 65 insertions, 236 deletions
diff --git a/security/nss/cmd/tstclnt/tstclnt.c b/security/nss/cmd/tstclnt/tstclnt.c
index 1ad99502b..959afec59 100644
--- a/security/nss/cmd/tstclnt/tstclnt.c
+++ b/security/nss/cmd/tstclnt/tstclnt.c
@@ -31,7 +31,6 @@
#include "ocsp.h"
#include "ssl.h"
#include "sslproto.h"
-#include "sslexp.h"
#include "pk11func.h"
#include "secmod.h"
#include "plgetopt.h"
@@ -96,7 +95,6 @@ PRBool verbose;
int dumpServerChain = 0;
int renegotiationsToDo = 0;
int renegotiationsDone = 0;
-PRBool initializedServerSessionCache = PR_FALSE;
static char *progName;
@@ -180,7 +178,7 @@ PrintUsageHeader(const char *progName)
"[-n nickname] [-Bafosvx] [-c ciphers] [-Y] [-Z]\n"
"[-V [min-version]:[max-version]] [-K] [-T] [-U]\n"
"[-r N] [-w passwd] [-W pwfile] [-q [-t seconds]] [-I groups]\n"
- "[-A requestfile] [-L totalconnections] [-P {client,server}] [-Q]\n"
+ "[-A requestfile] [-L totalconnections]\n"
"\n",
progName);
}
@@ -204,7 +202,7 @@ PrintParameterUsage(void)
fprintf(stderr, "%-20s Print certificate chain information\n", "-C");
fprintf(stderr, "%-20s (use -C twice to print more certificate details)\n", "");
fprintf(stderr, "%-20s (use -C three times to include PEM format certificate dumps)\n", "");
- fprintf(stderr, "%-20s Nickname of key and cert\n",
+ fprintf(stderr, "%-20s Nickname of key and cert for client auth\n",
"-n nickname");
fprintf(stderr,
"%-20s Restricts the set of enabled SSL/TLS protocols versions.\n"
@@ -253,9 +251,6 @@ PrintParameterUsage(void)
"%-20s The following values are valid:\n"
"%-20s P256, P384, P521, x25519, FF2048, FF3072, FF4096, FF6144, FF8192\n",
"-I", "", "");
- fprintf(stderr, "%-20s Enable alternative TLS 1.3 handshake\n", "-X alt-server-hello");
- fprintf(stderr, "%-20s Use DTLS\n", "-P {client, server}");
- fprintf(stderr, "%-20s Exit after handshake\n", "-Q");
}
static void
@@ -919,12 +914,6 @@ char *requestString = NULL;
PRInt32 requestStringLen = 0;
PRBool requestSent = PR_FALSE;
PRBool enableZeroRtt = PR_FALSE;
-PRBool enableAltServerHello = PR_FALSE;
-PRBool useDTLS = PR_FALSE;
-PRBool actAsServer = PR_FALSE;
-PRBool stopAfterHandshake = PR_FALSE;
-PRBool requestToExit = PR_FALSE;
-char *versionString = NULL;
static int
writeBytesToServer(PRFileDesc *s, const char *buf, int nb)
@@ -1007,129 +996,12 @@ handshakeCallback(PRFileDesc *fd, void *client_data)
writeBytesToServer(fd, requestString, requestStringLen);
}
}
- if (stopAfterHandshake) {
- requestToExit = PR_TRUE;
- }
}
#define REQUEST_WAITING (requestString && !requestSent)
-static SECStatus
-installServerCertificate(PRFileDesc *s, char *nickname)
-{
- CERTCertificate *cert;
- SECKEYPrivateKey *privKey = NULL;
-
- if (!nickname) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- cert = PK11_FindCertFromNickname(nickname, &pwdata);
- if (cert == NULL) {
- return SECFailure;
- }
-
- privKey = PK11_FindKeyByAnyCert(cert, &pwdata);
- if (privKey == NULL) {
- return SECFailure;
- }
- if (SSL_ConfigServerCert(s, cert, privKey, NULL, 0) != SECSuccess) {
- return SECFailure;
- }
- SECKEY_DestroyPrivateKey(privKey);
- CERT_DestroyCertificate(cert);
-
- return SECSuccess;
-}
-
-static SECStatus
-bindToClient(PRFileDesc *s)
-{
- PRStatus status;
- status = PR_Bind(s, &addr);
- if (status != PR_SUCCESS) {
- return SECFailure;
- }
-
- for (;;) {
- /* Bind the remote address on first packet. This must happen
- * before we SSL-ize the socket because we need to get the
- * peer's address before SSLizing. Recvfrom gives us that
- * while not consuming any data. */
- unsigned char tmp;
- PRNetAddr remote;
- int nb;
-
- nb = PR_RecvFrom(s, &tmp, 1, PR_MSG_PEEK,
- &remote, PR_INTERVAL_NO_TIMEOUT);
- if (nb != 1)
- continue;
-
- status = PR_Connect(s, &remote, PR_INTERVAL_NO_TIMEOUT);
- if (status != PR_SUCCESS) {
- SECU_PrintError(progName, "server bind to remote end failed");
- return SECFailure;
- }
- return SECSuccess;
- }
-
- /* Unreachable. */
-}
-
-static SECStatus
-connectToServer(PRFileDesc *s, PRPollDesc *pollset)
-{
- PRStatus status;
- PRInt32 filesReady;
-
- status = PR_Connect(s, &addr, PR_INTERVAL_NO_TIMEOUT);
- if (status != PR_SUCCESS) {
- if (PR_GetError() == PR_IN_PROGRESS_ERROR) {
- if (verbose)
- SECU_PrintError(progName, "connect");
- milliPause(50 * multiplier);
- pollset[SSOCK_FD].in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
- pollset[SSOCK_FD].out_flags = 0;
- pollset[SSOCK_FD].fd = s;
- while (1) {
- FPRINTF(stderr,
- "%s: about to call PR_Poll for connect completion!\n",
- progName);
- filesReady = PR_Poll(pollset, 1, PR_INTERVAL_NO_TIMEOUT);
- if (filesReady < 0) {
- SECU_PrintError(progName, "unable to connect (poll)");
- return SECFailure;
- }
- FPRINTF(stderr,
- "%s: PR_Poll returned 0x%02x for socket out_flags.\n",
- progName, pollset[SSOCK_FD].out_flags);
- if (filesReady == 0) { /* shouldn't happen! */
- SECU_PrintError(progName, "%s: PR_Poll returned zero!\n");
- return SECFailure;
- }
- status = PR_GetConnectStatus(pollset);
- if (status == PR_SUCCESS) {
- break;
- }
- if (PR_GetError() != PR_IN_PROGRESS_ERROR) {
- SECU_PrintError(progName, "unable to connect (poll)");
- return SECFailure;
- }
- SECU_PrintError(progName, "poll");
- milliPause(50 * multiplier);
- }
- } else {
- SECU_PrintError(progName, "unable to connect");
- return SECFailure;
- }
- }
-
- return SECSuccess;
-}
-
static int
-run(void)
+run_client(void)
{
int headerSeparatorPtrnId = 0;
int error = 0;
@@ -1145,23 +1017,13 @@ run(void)
requestSent = PR_FALSE;
/* Create socket */
- if (useDTLS) {
- s = PR_OpenUDPSocket(addr.raw.family);
- } else {
- s = PR_OpenTCPSocket(addr.raw.family);
- }
-
+ s = PR_OpenTCPSocket(addr.raw.family);
if (s == NULL) {
SECU_PrintError(progName, "error creating socket");
error = 1;
goto done;
}
- if (actAsServer) {
- if (bindToClient(s) != SECSuccess) {
- return 1;
- }
- }
opt.option = PR_SockOpt_Nonblocking;
opt.value.non_blocking = PR_TRUE; /* default */
if (serverCertAuth.testFreshStatusFromSideChannel) {
@@ -1174,16 +1036,13 @@ run(void)
goto done;
}
- if (useDTLS) {
- s = DTLS_ImportFD(NULL, s);
- } else {
- s = SSL_ImportFD(NULL, s);
- }
+ s = SSL_ImportFD(NULL, s);
if (s == NULL) {
SECU_PrintError(progName, "error importing socket");
error = 1;
goto done;
}
+
SSL_SetPKCS11PinArg(s, &pwdata);
rv = SSL_OptionSet(s, SSL_SECURITY, 1);
@@ -1193,7 +1052,7 @@ run(void)
goto done;
}
- rv = SSL_OptionSet(s, actAsServer ? SSL_HANDSHAKE_AS_SERVER : SSL_HANDSHAKE_AS_CLIENT, 1);
+ rv = SSL_OptionSet(s, SSL_HANDSHAKE_AS_CLIENT, 1);
if (rv != SECSuccess) {
SECU_PrintError(progName, "error enabling client handshake");
error = 1;
@@ -1319,16 +1178,6 @@ run(void)
}
}
- /* Alternate ServerHello content type (TLS 1.3 only) */
- if (enableAltServerHello) {
- rv = SSL_UseAltServerHelloType(s, PR_TRUE);
- if (rv != SECSuccess) {
- SECU_PrintError(progName, "error enabling alternate ServerHello type");
- error = 1;
- goto done;
- }
- }
-
/* require the use of fixed finite-field DH groups */
if (requireDHNamedGroups) {
rv = SSL_OptionSet(s, SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
@@ -1363,21 +1212,7 @@ run(void)
if (override) {
SSL_BadCertHook(s, ownBadCertHandler, NULL);
}
- if (actAsServer) {
- rv = installServerCertificate(s, nickname);
- if (rv != SECSuccess) {
- SECU_PrintError(progName, "error installing server cert");
- return 1;
- }
- rv = SSL_ConfigServerSessionIDCache(1024, 0, 0, ".");
- if (rv != SECSuccess) {
- SECU_PrintError(progName, "error configuring session cache");
- return 1;
- }
- initializedServerSessionCache = PR_TRUE;
- } else {
- SSL_GetClientAuthDataHook(s, own_GetClientAuthData, (void *)nickname);
- }
+ SSL_GetClientAuthDataHook(s, own_GetClientAuthData, (void *)nickname);
SSL_HandshakeCallback(s, handshakeCallback, hs2SniHostName);
if (hs1SniHostName) {
SSL_SetURL(s, hs1SniHostName);
@@ -1385,27 +1220,56 @@ run(void)
SSL_SetURL(s, host);
}
- if (actAsServer) {
- rv = SSL_ResetHandshake(s, PR_TRUE /* server */);
- if (rv != SECSuccess) {
- return 1;
- }
- } else {
- /* Try to connect to the server */
- rv = connectToServer(s, pollset);
- if (rv != SECSuccess) {
- ;
+ /* Try to connect to the server */
+ status = PR_Connect(s, &addr, PR_INTERVAL_NO_TIMEOUT);
+ if (status != PR_SUCCESS) {
+ if (PR_GetError() == PR_IN_PROGRESS_ERROR) {
+ if (verbose)
+ SECU_PrintError(progName, "connect");
+ milliPause(50 * multiplier);
+ pollset[SSOCK_FD].in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
+ pollset[SSOCK_FD].out_flags = 0;
+ pollset[SSOCK_FD].fd = s;
+ while (1) {
+ FPRINTF(stderr,
+ "%s: about to call PR_Poll for connect completion!\n",
+ progName);
+ filesReady = PR_Poll(pollset, 1, PR_INTERVAL_NO_TIMEOUT);
+ if (filesReady < 0) {
+ SECU_PrintError(progName, "unable to connect (poll)");
+ error = 1;
+ goto done;
+ }
+ FPRINTF(stderr,
+ "%s: PR_Poll returned 0x%02x for socket out_flags.\n",
+ progName, pollset[SSOCK_FD].out_flags);
+ if (filesReady == 0) { /* shouldn't happen! */
+ FPRINTF(stderr, "%s: PR_Poll returned zero!\n", progName);
+ error = 1;
+ goto done;
+ }
+ status = PR_GetConnectStatus(pollset);
+ if (status == PR_SUCCESS) {
+ break;
+ }
+ if (PR_GetError() != PR_IN_PROGRESS_ERROR) {
+ SECU_PrintError(progName, "unable to connect (poll)");
+ error = 1;
+ goto done;
+ }
+ SECU_PrintError(progName, "poll");
+ milliPause(50 * multiplier);
+ }
+ } else {
+ SECU_PrintError(progName, "unable to connect");
error = 1;
goto done;
}
}
pollset[SSOCK_FD].fd = s;
- pollset[SSOCK_FD].in_flags = PR_POLL_EXCEPT;
- if (!actAsServer)
- pollset[SSOCK_FD].in_flags |= (clientSpeaksFirst ? 0 : PR_POLL_READ);
- else
- pollset[SSOCK_FD].in_flags |= PR_POLL_READ;
+ pollset[SSOCK_FD].in_flags = PR_POLL_EXCEPT |
+ (clientSpeaksFirst ? 0 : PR_POLL_READ);
pollset[STDIN_FD].fd = PR_GetSpecialFD(PR_StandardInput);
if (!REQUEST_WAITING) {
pollset[STDIN_FD].in_flags = PR_POLL_READ;
@@ -1455,11 +1319,9 @@ run(void)
** Select on stdin and on the socket. Write data from stdin to
** socket, read data from socket and write to stdout.
*/
- requestToExit = PR_FALSE;
FPRINTF(stderr, "%s: ready...\n", progName);
- while (!requestToExit &&
- ((pollset[SSOCK_FD].in_flags | pollset[STDIN_FD].in_flags) ||
- REQUEST_WAITING)) {
+ while ((pollset[SSOCK_FD].in_flags | pollset[STDIN_FD].in_flags) ||
+ REQUEST_WAITING) {
char buf[4000]; /* buffer for stdin */
int nb; /* num bytes read from stdin. */
@@ -1645,10 +1507,12 @@ main(int argc, char **argv)
}
}
+ SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledVersions);
+
/* XXX: 'B' was used in the past but removed in 3.28,
* please leave some time before resuing it. */
optstate = PL_CreateOptState(argc, argv,
- "46A:CDFGHI:KL:M:OP:QR:STUV:W:X:YZa:bc:d:fgh:m:n:op:qr:st:uvw:z");
+ "46A:CDFGHI:KL:M:OR:STUV:W:YZa:bc:d:fgh:m:n:op:qr:st:uvw:z");
while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
switch (optstate->option) {
case '?':
@@ -1729,21 +1593,6 @@ main(int argc, char **argv)
};
break;
- case 'P':
- useDTLS = PR_TRUE;
- if (!strcmp(optstate->value, "server")) {
- actAsServer = 1;
- } else {
- if (strcmp(optstate->value, "client")) {
- Usage(progName);
- }
- }
- break;
-
- case 'Q':
- stopAfterHandshake = PR_TRUE;
- break;
-
case 'R':
rootModule = PORT_Strdup(optstate->value);
break;
@@ -1761,16 +1610,14 @@ main(int argc, char **argv)
break;
case 'V':
- versionString = PORT_Strdup(optstate->value);
- break;
-
- case 'X':
- if (!strcmp(optstate->value, "alt-server-hello")) {
- enableAltServerHello = PR_TRUE;
- } else {
+ if (SECU_ParseSSLVersionRangeString(optstate->value,
+ enabledVersions, &enabledVersions) !=
+ SECSuccess) {
+ fprintf(stderr, "Bad version specified.\n");
Usage(progName);
}
break;
+
case 'Y':
PrintCipherUsage(progName);
exit(0);
@@ -1880,19 +1727,8 @@ main(int argc, char **argv)
break;
}
}
- PL_DestroyOptState(optstate);
- SSL_VersionRangeGetSupported(useDTLS ? ssl_variant_datagram : ssl_variant_stream, &enabledVersions);
-
- if (versionString) {
- if (SECU_ParseSSLVersionRangeString(versionString,
- enabledVersions, &enabledVersions) !=
- SECSuccess) {
- fprintf(stderr, "Bad version specified.\n");
- Usage(progName);
- }
- PORT_Free(versionString);
- }
+ PL_DestroyOptState(optstate);
if (optstatus == PL_OPT_BAD) {
Usage(progName);
@@ -1922,7 +1758,7 @@ main(int argc, char **argv)
PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
PK11_SetPasswordFunc(SECU_GetModulePassword);
- memset(&addr, 0, sizeof(addr));
+
status = PR_StringToNetAddr(host, &addr);
if (status == PR_SUCCESS) {
addr.inet.port = PR_htons(portno);
@@ -1934,7 +1770,6 @@ main(int argc, char **argv)
addrInfo = PR_GetAddrInfoByName(host, PR_AF_UNSPEC,
PR_AI_ADDRCONFIG | PR_AI_NOCANONNAME);
if (!addrInfo) {
- fprintf(stderr, "HOSTNAME=%s\n", host);
SECU_PrintError(progName, "error looking up host");
error = 1;
goto done;
@@ -2049,7 +1884,7 @@ main(int argc, char **argv)
}
while (numConnections--) {
- error = run();
+ error = run_client();
if (error) {
goto done;
}
@@ -2080,12 +1915,6 @@ done:
}
if (NSS_IsInitialized()) {
SSL_ClearSessionCache();
- if (initializedServerSessionCache) {
- if (SSL_ShutdownServerSessionIDCache() != SECSuccess) {
- error = 1;
- }
- }
-
if (NSS_Shutdown() != SECSuccess) {
error = 1;
}