~ubuntu-branches/ubuntu/saucy/nss/saucy-security

« back to all changes in this revision

Viewing changes to mozilla/security/nss/cmd/tstclnt/tstclnt.c

  • Committer: Package Import Robot
  • Author(s): Timo Aaltonen
  • Date: 2012-11-27 18:19:23 UTC
  • mfrom: (1.1.17) (39.1.1 raring-proposed)
  • Revision ID: package-import@ubuntu.com-20121127181923-k491xj878qya0xgn
Tags: 2:3.14-1ubuntu1
* Merge from Debian unstable. Remaining changes:
  - control: Change Vcs-* to XS-Debian-Vcs-*.
  - rules: Include libnssb.a and libnssckfw.a in the -dev package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* ***** BEGIN LICENSE BLOCK *****
2
 
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3
 
 *
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/
8
 
 *
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
12
 
 * License.
13
 
 *
14
 
 * The Original Code is the Netscape security libraries.
15
 
 *
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.
20
 
 *
21
 
 * Contributor(s):
22
 
 *   Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
23
 
 *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
24
 
 *
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.
36
 
 *
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/. */
38
4
 
39
5
/*
40
6
**
43
9
*/
44
10
 
45
11
#include "secutil.h"
 
12
#include "basicutil.h"
46
13
 
47
14
#if defined(XP_UNIX)
48
15
#include <unistd.h>
193
160
    }
194
161
}
195
162
 
196
 
static void Usage(const char *progName)
 
163
static void PrintUsageHeader(const char *progName)
197
164
{
198
165
    fprintf(stderr, 
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", 
 
170
            progName);
 
171
}
 
172
 
 
173
static void PrintParameterUsage(void)
 
174
{
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",
205
178
                    "", "");
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");
212
185
                    "-n nickname");
213
186
    fprintf(stderr, 
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");
 
188
    fprintf(stderr, 
 
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");
 
210
}
 
211
 
 
212
static void Usage(const char *progName)
 
213
{
 
214
    PrintUsageHeader(progName);
 
215
    PrintParameterUsage();
 
216
    exit(1);
 
217
}
 
218
 
 
219
static void PrintCipherUsage(const char *progName)
 
220
{
 
221
    PrintUsageHeader(progName);
229
222
    fprintf(stderr, "%-20s Letter(s) chosen from the following list\n", 
230
223
                    "-c ciphers");
231
224
    fprintf(stderr, 
293
286
    }
294
287
}
295
288
 
 
289
typedef struct
 
290
{
 
291
   PRBool shouldPause; /* PR_TRUE if we should use asynchronous peer cert 
 
292
                        * authentication */
 
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
} ServerCertAuth;
 
298
 
296
299
/*
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. */
308
311
}
309
312
 
 
313
static SECStatus 
 
314
ownAuthCertificate(void *arg, PRFileDesc *fd, PRBool checkSig,
 
315
                       PRBool isServer)
 
316
{
 
317
    ServerCertAuth * serverCertAuth = (ServerCertAuth *) arg;
 
318
 
 
319
    FPRINTF(stderr, "%s: using asynchronous certificate validation\n",
 
320
            progName);
 
321
 
 
322
    PORT_Assert(serverCertAuth->shouldPause);
 
323
    PORT_Assert(!serverCertAuth->isPaused);
 
324
    serverCertAuth->isPaused = PR_TRUE;
 
325
    return SECWouldBlock;
 
326
}
 
327
 
310
328
SECStatus
311
329
own_GetClientAuthData(void *                       arg,
312
330
                      PRFileDesc *                 socket,
498
516
        Usage(progName); \
499
517
    }
500
518
 
 
519
static SECStatus
 
520
restartHandshakeAfterServerCertIfNeeded(PRFileDesc * fd,
 
521
                                        ServerCertAuth * serverCertAuth,
 
522
                                        PRBool override)
 
523
{
 
524
    SECStatus rv;
 
525
    PRErrorCode status;
 
526
    
 
527
    if (!serverCertAuth->isPaused)
 
528
        return SECSuccess;
 
529
    
 
530
    FPRINTF(stderr, "%s: handshake was paused by auth certificate hook\n",
 
531
            progName);
 
532
 
 
533
    serverCertAuth->isPaused = PR_FALSE;
 
534
    rv = SSL_AuthCertificate(serverCertAuth->dbHandle, fd, PR_TRUE, PR_FALSE);
 
535
    if (rv != SECSuccess) {
 
536
        status = PR_GetError();
 
537
        if (status == 0) {
 
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);
 
543
        }
 
544
    }
 
545
    if (rv == SECSuccess) {
 
546
        status = 0;
 
547
    }
 
548
 
 
549
    if (SSL_AuthCertificateComplete(fd, status) != SECSuccess) {
 
550
        rv = SECFailure;
 
551
    }
 
552
 
 
553
    return rv;
 
554
}
 
555
    
501
556
int main(int argc, char **argv)
502
557
{
503
558
    PRFileDesc *       s;
504
559
    PRFileDesc *       std_out;
505
 
    CERTCertDBHandle * handle;
506
560
    char *             host     =  NULL;
507
561
    char *             certDir  =  NULL;
508
562
    char *             nickname =  NULL;
514
568
    PRInt32            filesReady;
515
569
    int                npds;
516
570
    int                override = 0;
517
 
    int                disableSSL2 = 0;
518
 
    int                disableSSL3 = 0;
519
 
    int                disableTLS  = 0;
 
571
    SSLVersionRange    enabledVersions;
 
572
    PRBool             enableSSL2 = PR_TRUE;
520
573
    int                bypassPKCS11 = 0;
521
574
    int                disableLocking = 0;
522
575
    int                useExportPolicy = 0;
527
580
    PRNetAddr          addr;
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;
534
589
    int                error = 0;
535
590
    PRUint16           portno = 443;
539
594
    PLOptStatus optstatus;
540
595
    PRStatus prStatus;
541
596
 
 
597
    serverCertAuth.shouldPause = PR_TRUE;
 
598
    serverCertAuth.isPaused = PR_FALSE;
 
599
    serverCertAuth.dbHandle = NULL;
 
600
 
542
601
    progName = strrchr(argv[0], '/');
543
602
    if (!progName)
544
603
        progName = strrchr(argv[0], '\\');
552
611
       }
553
612
    }
554
613
 
 
614
    SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledVersions);
 
615
 
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) {
559
620
          case '?':
560
621
          default : Usage(progName);                    break;
561
622
 
562
 
          case '2': disableSSL2 = 1;                    break;
563
 
 
564
 
          case '3': disableSSL3 = 1;                    break;
565
 
 
566
623
          case 'B': bypassPKCS11 = 1;                   break;
567
624
 
 
625
          case 'O': serverCertAuth.shouldPause = PR_FALSE; break;
 
626
 
568
627
          case 'S': skipProtoHeader = PR_TRUE;                 break;
569
628
 
570
 
          case 'T': disableTLS  = 1;                    break;
 
629
          case 'V': if (SECU_ParseSSLVersionRangeString(optstate->value,
 
630
                            enabledVersions, enableSSL2,
 
631
                            &enabledVersions, &enableSSL2) != SECSuccess) {
 
632
                        Usage(progName);
 
633
                    }
 
634
                    break;
 
635
 
 
636
          case 'Y': PrintCipherUsage(progName); exit(0); break;
571
637
 
572
638
          case 'a': if (!hs1SniHostName) {
573
639
                        hs1SniHostName = PORT_Strdup(optstate->value);
603
669
          case 'q': pingServerFirst = PR_TRUE;          break;
604
670
 
605
671
          case 's': disableLocking = 1;                 break;
 
672
          
 
673
          case 't': pingTimeoutSeconds = atoi(optstate->value); break;
606
674
 
607
675
          case 'u': enableSessionTickets = PR_TRUE;     break;
608
676
 
638
706
 
639
707
    PK11_SetPasswordFunc(SECU_GetModulePassword);
640
708
 
641
 
    /* open the cert DB, the key DB, and the secmod DB. */
642
 
    if (!certDir) {
643
 
        certDir = SECU_DefaultSSLDir(); /* Look in $SSL_DIR */
644
 
        certDir = SECU_ConfigDirectory(certDir);
645
 
    } else {
646
 
        char *certDirTmp = certDir;
647
 
        certDir = SECU_ConfigDirectory(certDirTmp);
648
 
        PORT_Free(certDirTmp);
649
 
    }
650
 
    rv = NSS_Init(certDir);
651
 
    if (rv != SECSuccess) {
652
 
        SECU_PrintError(progName, "unable to open cert database");
653
 
#if 0
654
 
    rv = CERT_OpenVolatileCertDB(handle);
655
 
        CERT_SetDefaultCertDB(handle);
656
 
#else
657
 
        return 1;
658
 
#endif
659
 
    }
660
 
    handle = CERT_GetDefaultCertDB();
661
 
 
662
 
    /* set the policy bits true for all the cipher suites. */
663
 
    if (useExportPolicy)
664
 
        NSS_SetExportPolicy();
665
 
    else
666
 
        NSS_SetDomesticPolicy();
667
 
 
668
 
    /* all the SSL2 and SSL3 cipher suites are enabled by default. */
669
 
    if (cipherString) {
670
 
        /* disable all the ciphers, then enable the ones we want. */
671
 
        disableAllSSLCiphers();
672
 
    }
673
 
 
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) {
703
738
        int iter = 0;
704
739
        PRErrorCode err;
 
740
        int max_attempts = MAX_WAIT_FOR_SERVER;
 
741
        if (pingTimeoutSeconds >= 0) {
 
742
          /* If caller requested a timeout, let's try just twice. */
 
743
          max_attempts = 2;
 
744
        }
705
745
        do {
 
746
            PRIntervalTime timeoutInterval = PR_INTERVAL_NO_TIMEOUT;
706
747
            s = PR_OpenTCPSocket(addr.raw.family);
707
748
            if (s == NULL) {
708
749
                SECU_PrintError(progName, "Failed to create a TCP socket");
716
757
                                "Failed to set blocking socket option");
717
758
                return 1;
718
759
            }
719
 
            prStatus = PR_Connect(s, &addr, PR_INTERVAL_NO_TIMEOUT);
 
760
            if (pingTimeoutSeconds >= 0) {
 
761
              timeoutInterval = PR_SecondsToInterval(pingTimeoutSeconds);
 
762
            }
 
763
            prStatus = PR_Connect(s, &addr, timeoutInterval);
720
764
            if (prStatus == PR_SUCCESS) {
721
765
                PR_Shutdown(s, PR_SHUTDOWN_BOTH);
722
766
                PR_Close(s);
723
 
               if (NSS_Shutdown() != SECSuccess) {
724
 
                   exit(1);
725
 
               }
726
767
                PR_Cleanup();
727
768
                return 0;
728
769
            }
734
775
            }
735
776
            PR_Close(s);
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");
740
781
        return 1;
741
782
    }
742
783
 
 
784
    /* open the cert DB, the key DB, and the secmod DB. */
 
785
    if (!certDir) {
 
786
        certDir = SECU_DefaultSSLDir(); /* Look in $SSL_DIR */
 
787
        certDir = SECU_ConfigDirectory(certDir);
 
788
    } else {
 
789
        char *certDirTmp = certDir;
 
790
        certDir = SECU_ConfigDirectory(certDirTmp);
 
791
        PORT_Free(certDirTmp);
 
792
    }
 
793
    rv = NSS_Init(certDir);
 
794
    if (rv != SECSuccess) {
 
795
        SECU_PrintError(progName, "unable to open cert database");
 
796
        return 1;
 
797
    }
 
798
 
 
799
    /* set the policy bits true for all the cipher suites. */
 
800
    if (useExportPolicy)
 
801
        NSS_SetExportPolicy();
 
802
    else
 
803
        NSS_SetDomesticPolicy();
 
804
 
 
805
    /* all the SSL2 and SSL3 cipher suites are enabled by default. */
 
806
    if (cipherString) {
 
807
        /* disable all the ciphers, then enable the ones we want. */
 
808
        disableAllSSLCiphers();
 
809
    }
 
810
 
743
811
    /* Create socket */
744
812
    s = PR_OpenTCPSocket(addr.raw.family);
745
813
    if (s == NULL) {
815
883
        PORT_Free(cstringSaved);
816
884
    }
817
885
 
818
 
    rv = SSL_OptionSet(s, SSL_ENABLE_SSL2, !disableSSL2);
819
 
    if (rv != SECSuccess) {
820
 
        SECU_PrintError(progName, "error enabling SSLv2 ");
821
 
        return 1;
822
 
    }
823
 
 
824
 
    rv = SSL_OptionSet(s, SSL_ENABLE_SSL3, !disableSSL3);
825
 
    if (rv != SECSuccess) {
826
 
        SECU_PrintError(progName, "error enabling SSLv3 ");
827
 
        return 1;
828
 
    }
829
 
 
830
 
    rv = SSL_OptionSet(s, SSL_ENABLE_TLS, !disableTLS);
831
 
    if (rv != SECSuccess) {
832
 
        SECU_PrintError(progName, "error enabling TLS ");
833
 
        return 1;
834
 
    }
835
 
 
836
 
    rv = SSL_OptionSet(s, SSL_V2_COMPATIBLE_HELLO, !disableSSL2);
837
 
    if (rv != SECSuccess) {
838
 
        SECU_PrintError(progName, "error enabling SSLv2 compatible hellos ");
839
 
        return 1;
 
886
    rv = SSL_VersionRangeSet(s, &enabledVersions);
 
887
    if (rv != SECSuccess) {
 
888
        SECU_PrintError(progName, "error setting SSL/TLS version range ");
 
889
        return 1;
 
890
    }
 
891
 
 
892
    rv = SSL_OptionSet(s, SSL_ENABLE_SSL2, enableSSL2);
 
893
    if (rv != SECSuccess) {
 
894
       SECU_PrintError(progName, "error enabling SSLv2 ");
 
895
       return 1;
 
896
    }
 
897
 
 
898
    rv = SSL_OptionSet(s, SSL_V2_COMPATIBLE_HELLO, enableSSL2);
 
899
    if (rv != SECSuccess) {
 
900
        SECU_PrintError(progName, "error enabling SSLv2 compatible hellos ");
 
901
        return 1;
840
902
    }
841
903
 
842
904
    /* enable PKCS11 bypass */
876
938
 
877
939
    SSL_SetPKCS11PinArg(s, &pwdata);
878
940
 
879
 
    SSL_AuthCertificateHook(s, SSL_AuthCertificate, (void *)handle);
 
941
    serverCertAuth.dbHandle = CERT_GetDefaultCertDB();
 
942
 
 
943
    if (serverCertAuth.shouldPause) {
 
944
        SSL_AuthCertificateHook(s, ownAuthCertificate, &serverCertAuth);
 
945
    } else {
 
946
        SSL_AuthCertificateHook(s, SSL_AuthCertificate, serverCertAuth.dbHandle);
 
947
    }
880
948
    if (override) {
881
949
        SSL_BadCertHook(s, ownBadCertHandler, NULL);
882
950
    }
984
1052
        char buf[4000]; /* buffer for stdin */
985
1053
        int nb;         /* num bytes read from stdin. */
986
1054
 
 
1055
        rv = restartHandshakeAfterServerCertIfNeeded(s, &serverCertAuth,
 
1056
                                                     override);
 
1057
        if (rv != SECSuccess) {
 
1058
            error = 254; /* 254 (usually) means "handshake failed" */
 
1059
            SECU_PrintError(progName, "authentication of server cert failed");
 
1060
            goto done;
 
1061
        }
 
1062
                
987
1063
        pollset[SSOCK_FD].out_flags = 0;
988
1064
        pollset[STDIN_FD].out_flags = 0;
989
1065
 
1042
1118
                    nb   -= cc;
1043
1119
                    if (nb <= 0) 
1044
1120
                        break;
 
1121
 
 
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");
 
1127
                        goto done;
 
1128
                    }
 
1129
 
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,