1
/* ***** BEGIN LICENSE BLOCK *****
2
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
4
* The contents of this file are subject to the Mozilla Public License Version
5
* 1.1 (the "License"); you may not use this file except in compliance with
6
* the License. You may obtain a copy of the License at
7
* http://www.mozilla.org/MPL/
9
* Software distributed under the License is distributed on an "AS IS" basis,
10
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11
* for the specific language governing rights and limitations under the
14
* The Original Code is the Netscape security libraries.
16
* The Initial Developer of the Original Code is
17
* Netscape Communications Corporation.
18
* Portions created by the Initial Developer are Copyright (C) 1994-2000
19
* the Initial Developer. All Rights Reserved.
22
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
23
* Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
25
* Alternatively, the contents of this file may be used under the terms of
26
* either the GNU General Public License Version 2 or later (the "GPL"), or
27
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28
* in which case the provisions of the GPL or the LGPL are applicable instead
29
* of those above. If you wish to allow use of your version of this file only
30
* under the terms of either the GPL or the LGPL, and not to allow others to
31
* use your version of this file under the terms of the MPL, indicate your
32
* decision by deleting the provisions above and replace them with the notice
33
* and other provisions required by the GPL or the LGPL. If you do not delete
34
* the provisions above, a recipient may use your version of this file under
35
* the terms of any one of the MPL, the GPL or the LGPL.
37
* ***** END LICENSE BLOCK ***** */
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
* License, v. 2.0. If a copy of the MPL was not distributed with this
3
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
196
static void Usage(const char *progName)
163
static void PrintUsageHeader(const char *progName)
199
166
"Usage: %s -h host [-a 1st_hs_name ] [-a 2nd_hs_name ] [-p port]\n"
200
"[-d certdir] [-n nickname] [-23BTafosvx] [-c ciphers]\n"
201
"[-r N] [-w passwd] [-W pwfile] [-q]\n", progName);
167
"[-d certdir] [-n nickname] [-Bafosvx] [-c ciphers] [-Y]\n"
168
"[-V [min-version]:[max-version]]\n"
169
"[-r N] [-w passwd] [-W pwfile] [-q [-t seconds]]\n",
173
static void PrintParameterUsage(void)
202
175
fprintf(stderr, "%-20s Send different SNI name. 1st_hs_name - at first\n"
203
176
"%-20s handshake, 2nd_hs_name - at second handshake.\n"
204
"%-20s Defualt is host from the -h argument.\n", "-a name",
177
"%-20s Default is host from the -h argument.\n", "-a name",
206
179
fprintf(stderr, "%-20s Hostname to connect with\n", "-h host");
207
180
fprintf(stderr, "%-20s Port number for SSL server\n", "-p port");
214
187
"%-20s Bypass PKCS11 layer for SSL encryption and MACing.\n", "-B");
215
fprintf(stderr, "%-20s Disable SSL v2.\n", "-2");
216
fprintf(stderr, "%-20s Disable SSL v3.\n", "-3");
217
fprintf(stderr, "%-20s Disable TLS (SSL v3.1).\n", "-T");
189
"%-20s Restricts the set of enabled SSL/TLS protocols versions.\n"
190
"%-20s All versions are enabled by default.\n"
191
"%-20s Possible values for min/max: ssl2 ssl3 tls1.0 tls1.1\n"
192
"%-20s Example: \"-V ssl3:\" enables SSL 3 and newer.\n",
193
"-V [min]:[max]", "", "", "");
218
194
fprintf(stderr, "%-20s Prints only payload data. Skips HTTP header.\n", "-S");
219
195
fprintf(stderr, "%-20s Client speaks first. \n", "-f");
196
fprintf(stderr, "%-20s Use synchronous certificate validation "
197
"(required for SSL2)\n", "-O");
220
198
fprintf(stderr, "%-20s Override bad server cert. Make it OK.\n", "-o");
221
199
fprintf(stderr, "%-20s Disable SSL socket locking.\n", "-s");
222
200
fprintf(stderr, "%-20s Verbose progress reporting.\n", "-v");
223
201
fprintf(stderr, "%-20s Use export policy.\n", "-x");
224
202
fprintf(stderr, "%-20s Ping the server and then exit.\n", "-q");
203
fprintf(stderr, "%-20s Timeout for server ping (default: no timeout).\n", "-t seconds");
225
204
fprintf(stderr, "%-20s Renegotiate N times (resuming session if N>1).\n", "-r N");
226
205
fprintf(stderr, "%-20s Enable the session ticket extension.\n", "-u");
227
206
fprintf(stderr, "%-20s Enable compression.\n", "-z");
228
207
fprintf(stderr, "%-20s Enable false start.\n", "-g");
208
fprintf(stderr, "%-20s Restrict ciphers\n", "-c ciphers");
209
fprintf(stderr, "%-20s Print cipher values allowed for parameter -c and exit\n", "-Y");
212
static void Usage(const char *progName)
214
PrintUsageHeader(progName);
215
PrintParameterUsage();
219
static void PrintCipherUsage(const char *progName)
221
PrintUsageHeader(progName);
229
222
fprintf(stderr, "%-20s Letter(s) chosen from the following list\n",
291
PRBool shouldPause; /* PR_TRUE if we should use asynchronous peer cert
293
PRBool isPaused; /* PR_TRUE if libssl is waiting for us to validate the
294
* peer's certificate and restart the handshake. */
295
void * dbHandle; /* Certificate database handle to use while
296
* authenticating the peer's certificate. */
297
300
* Callback is called when incoming certificate is not valid.
298
301
* Returns SECSuccess to accept the cert anyway, SECFailure to reject.
307
310
return SECSuccess; /* override, say it's OK. */
314
ownAuthCertificate(void *arg, PRFileDesc *fd, PRBool checkSig,
317
ServerCertAuth * serverCertAuth = (ServerCertAuth *) arg;
319
FPRINTF(stderr, "%s: using asynchronous certificate validation\n",
322
PORT_Assert(serverCertAuth->shouldPause);
323
PORT_Assert(!serverCertAuth->isPaused);
324
serverCertAuth->isPaused = PR_TRUE;
325
return SECWouldBlock;
311
329
own_GetClientAuthData(void * arg,
312
330
PRFileDesc * socket,
498
516
Usage(progName); \
520
restartHandshakeAfterServerCertIfNeeded(PRFileDesc * fd,
521
ServerCertAuth * serverCertAuth,
527
if (!serverCertAuth->isPaused)
530
FPRINTF(stderr, "%s: handshake was paused by auth certificate hook\n",
533
serverCertAuth->isPaused = PR_FALSE;
534
rv = SSL_AuthCertificate(serverCertAuth->dbHandle, fd, PR_TRUE, PR_FALSE);
535
if (rv != SECSuccess) {
536
status = PR_GetError();
538
PR_NOT_REACHED("SSL_AuthCertificate return SECFailure without "
539
"setting error code.");
540
status = PR_INVALID_STATE_ERROR;
541
} else if (override) {
542
rv = ownBadCertHandler(NULL, fd);
545
if (rv == SECSuccess) {
549
if (SSL_AuthCertificateComplete(fd, status) != SECSuccess) {
501
556
int main(int argc, char **argv)
504
559
PRFileDesc * std_out;
505
CERTCertDBHandle * handle;
506
560
char * host = NULL;
507
561
char * certDir = NULL;
508
562
char * nickname = NULL;
528
581
PRPollDesc pollset[2];
529
582
PRBool pingServerFirst = PR_FALSE;
583
int pingTimeoutSeconds = -1;
530
584
PRBool clientSpeaksFirst = PR_FALSE;
531
585
PRBool wrStarted = PR_FALSE;
532
586
PRBool skipProtoHeader = PR_FALSE;
587
ServerCertAuth serverCertAuth;
533
588
int headerSeparatorPtrnId = 0;
535
590
PRUint16 portno = 443;
614
SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledVersions);
555
616
optstate = PL_CreateOptState(argc, argv,
556
"23BSTW:a:c:d:fgh:m:n:op:qr:suvw:xz");
617
"BOSV:W:Ya:c:d:fgh:m:n:op:qr:st:uvw:xz");
557
618
while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
558
619
switch (optstate->option) {
560
621
default : Usage(progName); break;
562
case '2': disableSSL2 = 1; break;
564
case '3': disableSSL3 = 1; break;
566
623
case 'B': bypassPKCS11 = 1; break;
625
case 'O': serverCertAuth.shouldPause = PR_FALSE; break;
568
627
case 'S': skipProtoHeader = PR_TRUE; break;
570
case 'T': disableTLS = 1; break;
629
case 'V': if (SECU_ParseSSLVersionRangeString(optstate->value,
630
enabledVersions, enableSSL2,
631
&enabledVersions, &enableSSL2) != SECSuccess) {
636
case 'Y': PrintCipherUsage(progName); exit(0); break;
572
638
case 'a': if (!hs1SniHostName) {
573
639
hs1SniHostName = PORT_Strdup(optstate->value);
639
707
PK11_SetPasswordFunc(SECU_GetModulePassword);
641
/* open the cert DB, the key DB, and the secmod DB. */
643
certDir = SECU_DefaultSSLDir(); /* Look in $SSL_DIR */
644
certDir = SECU_ConfigDirectory(certDir);
646
char *certDirTmp = certDir;
647
certDir = SECU_ConfigDirectory(certDirTmp);
648
PORT_Free(certDirTmp);
650
rv = NSS_Init(certDir);
651
if (rv != SECSuccess) {
652
SECU_PrintError(progName, "unable to open cert database");
654
rv = CERT_OpenVolatileCertDB(handle);
655
CERT_SetDefaultCertDB(handle);
660
handle = CERT_GetDefaultCertDB();
662
/* set the policy bits true for all the cipher suites. */
664
NSS_SetExportPolicy();
666
NSS_SetDomesticPolicy();
668
/* all the SSL2 and SSL3 cipher suites are enabled by default. */
670
/* disable all the ciphers, then enable the ones we want. */
671
disableAllSSLCiphers();
674
709
status = PR_StringToNetAddr(host, &addr);
675
710
if (status == PR_SUCCESS) {
676
711
addr.inet.port = PR_htons(portno);
702
737
if (pingServerFirst) {
740
int max_attempts = MAX_WAIT_FOR_SERVER;
741
if (pingTimeoutSeconds >= 0) {
742
/* If caller requested a timeout, let's try just twice. */
746
PRIntervalTime timeoutInterval = PR_INTERVAL_NO_TIMEOUT;
706
747
s = PR_OpenTCPSocket(addr.raw.family);
708
749
SECU_PrintError(progName, "Failed to create a TCP socket");
716
757
"Failed to set blocking socket option");
719
prStatus = PR_Connect(s, &addr, PR_INTERVAL_NO_TIMEOUT);
760
if (pingTimeoutSeconds >= 0) {
761
timeoutInterval = PR_SecondsToInterval(pingTimeoutSeconds);
763
prStatus = PR_Connect(s, &addr, timeoutInterval);
720
764
if (prStatus == PR_SUCCESS) {
721
765
PR_Shutdown(s, PR_SHUTDOWN_BOTH);
723
if (NSS_Shutdown() != SECSuccess) {
736
777
PR_Sleep(PR_MillisecondsToInterval(WAIT_INTERVAL));
737
} while (++iter < MAX_WAIT_FOR_SERVER);
778
} while (++iter < max_attempts);
738
779
SECU_PrintError(progName,
739
780
"Client timed out while waiting for connection to server");
784
/* open the cert DB, the key DB, and the secmod DB. */
786
certDir = SECU_DefaultSSLDir(); /* Look in $SSL_DIR */
787
certDir = SECU_ConfigDirectory(certDir);
789
char *certDirTmp = certDir;
790
certDir = SECU_ConfigDirectory(certDirTmp);
791
PORT_Free(certDirTmp);
793
rv = NSS_Init(certDir);
794
if (rv != SECSuccess) {
795
SECU_PrintError(progName, "unable to open cert database");
799
/* set the policy bits true for all the cipher suites. */
801
NSS_SetExportPolicy();
803
NSS_SetDomesticPolicy();
805
/* all the SSL2 and SSL3 cipher suites are enabled by default. */
807
/* disable all the ciphers, then enable the ones we want. */
808
disableAllSSLCiphers();
743
811
/* Create socket */
744
812
s = PR_OpenTCPSocket(addr.raw.family);
815
883
PORT_Free(cstringSaved);
818
rv = SSL_OptionSet(s, SSL_ENABLE_SSL2, !disableSSL2);
819
if (rv != SECSuccess) {
820
SECU_PrintError(progName, "error enabling SSLv2 ");
824
rv = SSL_OptionSet(s, SSL_ENABLE_SSL3, !disableSSL3);
825
if (rv != SECSuccess) {
826
SECU_PrintError(progName, "error enabling SSLv3 ");
830
rv = SSL_OptionSet(s, SSL_ENABLE_TLS, !disableTLS);
831
if (rv != SECSuccess) {
832
SECU_PrintError(progName, "error enabling TLS ");
836
rv = SSL_OptionSet(s, SSL_V2_COMPATIBLE_HELLO, !disableSSL2);
837
if (rv != SECSuccess) {
838
SECU_PrintError(progName, "error enabling SSLv2 compatible hellos ");
886
rv = SSL_VersionRangeSet(s, &enabledVersions);
887
if (rv != SECSuccess) {
888
SECU_PrintError(progName, "error setting SSL/TLS version range ");
892
rv = SSL_OptionSet(s, SSL_ENABLE_SSL2, enableSSL2);
893
if (rv != SECSuccess) {
894
SECU_PrintError(progName, "error enabling SSLv2 ");
898
rv = SSL_OptionSet(s, SSL_V2_COMPATIBLE_HELLO, enableSSL2);
899
if (rv != SECSuccess) {
900
SECU_PrintError(progName, "error enabling SSLv2 compatible hellos ");
842
904
/* enable PKCS11 bypass */
877
939
SSL_SetPKCS11PinArg(s, &pwdata);
879
SSL_AuthCertificateHook(s, SSL_AuthCertificate, (void *)handle);
941
serverCertAuth.dbHandle = CERT_GetDefaultCertDB();
943
if (serverCertAuth.shouldPause) {
944
SSL_AuthCertificateHook(s, ownAuthCertificate, &serverCertAuth);
946
SSL_AuthCertificateHook(s, SSL_AuthCertificate, serverCertAuth.dbHandle);
881
949
SSL_BadCertHook(s, ownBadCertHandler, NULL);
984
1052
char buf[4000]; /* buffer for stdin */
985
1053
int nb; /* num bytes read from stdin. */
1055
rv = restartHandshakeAfterServerCertIfNeeded(s, &serverCertAuth,
1057
if (rv != SECSuccess) {
1058
error = 254; /* 254 (usually) means "handshake failed" */
1059
SECU_PrintError(progName, "authentication of server cert failed");
987
1063
pollset[SSOCK_FD].out_flags = 0;
988
1064
pollset[STDIN_FD].out_flags = 0;
1122
rv = restartHandshakeAfterServerCertIfNeeded(s,
1123
&serverCertAuth, override);
1124
if (rv != SECSuccess) {
1125
error = 254; /* 254 (usually) means "handshake failed" */
1126
SECU_PrintError(progName, "authentication of server cert failed");
1045
1130
pollset[SSOCK_FD].in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
1046
1131
pollset[SSOCK_FD].out_flags = 0;
1047
1132
FPRINTF(stderr,