update usage messages
[openssl.git] / apps / s_client.c
index 578b541b13fc147f968d764a34a4e81bb6f0bf34..7d22c070f5563efcbba3d5e2a202989e1cb8acf3 100644 (file)
@@ -193,6 +193,7 @@ typedef unsigned int u_int;
 extern int verify_depth;
 extern int verify_error;
 extern int verify_return_error;
+extern int verify_quiet;
 
 #ifdef FIONBIO
 static int c_nbio=0;
@@ -220,6 +221,7 @@ static BIO *bio_c_out=NULL;
 static BIO *bio_c_msg=NULL;
 static int c_quiet=0;
 static int c_ign_eof=0;
+static int c_brief=0;
 
 #ifndef OPENSSL_NO_PSK
 /* Default PSK identity and key */
@@ -291,6 +293,9 @@ static void sc_usage(void)
        BIO_printf(bio_err," -host host     - use -connect instead\n");
        BIO_printf(bio_err," -port port     - use -connect instead\n");
        BIO_printf(bio_err," -connect host:port - who to connect to (default is %s:%s)\n",SSL_HOST_NAME,PORT_STR);
+       BIO_printf(bio_err," -checkhost host - check peer certificate matches \"host\"\n");
+       BIO_printf(bio_err," -checkemail email - check peer certificate matches \"email\"\n");
+       BIO_printf(bio_err," -checkip ipaddr - check peer certificate matches \"ipaddr\"\n");
 
        BIO_printf(bio_err," -verify arg   - turn on peer certificate verification\n");
        BIO_printf(bio_err," -cert arg     - certificate file to use, PEM format assumed\n");
@@ -557,7 +562,7 @@ int MAIN(int, char **);
 
 int MAIN(int argc, char **argv)
        {
-       unsigned int off=0, clr=0;
+       int build_chain = 0;
        SSL *con=NULL;
 #ifndef OPENSSL_NO_KRB5
        KSSL_CTX *kctx;
@@ -575,8 +580,8 @@ int MAIN(int argc, char **argv)
        char *passarg = NULL, *pass = NULL;
        X509 *cert = NULL;
        EVP_PKEY *key = NULL;
-       char *CApath=NULL,*CAfile=NULL,*cipher=NULL;
-       int reconnect=0,badop=0,verify=SSL_VERIFY_NONE,bugs=0;
+       char *CApath=NULL,*CAfile=NULL;
+       int reconnect=0,badop=0,verify=SSL_VERIFY_NONE;
        int crlf=0;
        int write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending;
        SSL_CTX *ctx=NULL;
@@ -605,7 +610,6 @@ int MAIN(int argc, char **argv)
 #endif
 #ifndef OPENSSL_NO_TLSEXT
        char *servername = NULL; 
-       char *curves=NULL;
         tlsextctx tlsextcbp = 
         {NULL,0};
 # ifndef OPENSSL_NO_NEXTPROTONEG
@@ -626,6 +630,12 @@ int MAIN(int argc, char **argv)
        int srp_lateuser = 0;
        SRP_ARG srp_arg = {NULL,NULL,0,0,0,1024};
 #endif
+       SSL_EXCERT *exc = NULL;
+
+       unsigned char *checkhost = NULL, *checkemail = NULL;
+       char *checkip = NULL;
+       SSL_CONF_CTX *cctx = NULL;
+       STACK_OF(OPENSSL_STRING) *ssl_args = NULL;
 
        meth=SSLv23_client_method();
 
@@ -642,6 +652,11 @@ int MAIN(int argc, char **argv)
 
        if (!load_config(bio_err, NULL))
                goto end;
+       cctx = SSL_CONF_CTX_new();
+       if (!cctx)
+               goto end;
+       SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT);
+       SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CMDLINE);
 
        if (    ((cbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||
                ((sbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||
@@ -683,7 +698,8 @@ int MAIN(int argc, char **argv)
                        verify=SSL_VERIFY_PEER;
                        if (--argc < 1) goto bad;
                        verify_depth=atoi(*(++argv));
-                       BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
+                       if (!c_quiet)
+                               BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
                        }
                else if (strcmp(*argv,"-cert") == 0)
                        {
@@ -713,6 +729,26 @@ int MAIN(int argc, char **argv)
                        }
                else if (strcmp(*argv,"-verify_return_error") == 0)
                        verify_return_error = 1;
+               else if (strcmp(*argv,"-verify_quiet") == 0)
+                       verify_quiet = 1;
+               else if (strcmp(*argv,"-brief") == 0)
+                       {
+                       c_brief = 1;
+                       verify_quiet = 1;
+                       c_quiet = 1;
+                       }
+               else if (args_excert(&argv, &argc, &badarg, bio_err, &exc))
+                       {
+                       if (badarg)
+                               goto bad;
+                       continue;
+                       }
+               else if (args_ssl(&argv, &argc, cctx, &badarg, bio_err, &ssl_args))
+                       {
+                       if (badarg)
+                               goto bad;
+                       continue;
+                       }
                else if (strcmp(*argv,"-prexit") == 0)
                        prexit=1;
                else if (strcmp(*argv,"-crlf") == 0)
@@ -841,8 +877,6 @@ int MAIN(int argc, char **argv)
                        socket_mtu = atol(*(++argv));
                        }
 #endif
-               else if (strcmp(*argv,"-bugs") == 0)
-                       bugs=1;
                else if (strcmp(*argv,"-keyform") == 0)
                        {
                        if (--argc < 1) goto bad;
@@ -867,26 +901,14 @@ int MAIN(int argc, char **argv)
                        if (--argc < 1) goto bad;
                        CApath= *(++argv);
                        }
+               else if (strcmp(*argv,"-build_chain") == 0)
+                       build_chain = 1;
                else if (strcmp(*argv,"-CAfile") == 0)
                        {
                        if (--argc < 1) goto bad;
                        CAfile= *(++argv);
                        }
-               else if (strcmp(*argv,"-no_tls1_2") == 0)
-                       off|=SSL_OP_NO_TLSv1_2;
-               else if (strcmp(*argv,"-no_tls1_1") == 0)
-                       off|=SSL_OP_NO_TLSv1_1;
-               else if (strcmp(*argv,"-no_tls1") == 0)
-                       off|=SSL_OP_NO_TLSv1;
-               else if (strcmp(*argv,"-no_ssl3") == 0)
-                       off|=SSL_OP_NO_SSLv3;
-               else if (strcmp(*argv,"-no_ssl2") == 0)
-                       off|=SSL_OP_NO_SSLv2;
-               else if (strcmp(*argv,"-no_comp") == 0)
-                       { off|=SSL_OP_NO_COMPRESSION; }
 #ifndef OPENSSL_NO_TLSEXT
-               else if (strcmp(*argv,"-no_ticket") == 0)
-                       { off|=SSL_OP_NO_TICKET; }
 # ifndef OPENSSL_NO_NEXTPROTONEG
                else if (strcmp(*argv,"-nextprotoneg") == 0)
                        {
@@ -895,19 +917,6 @@ int MAIN(int argc, char **argv)
                        }
 # endif
 #endif
-               else if (strcmp(*argv,"-serverpref") == 0)
-                       off|=SSL_OP_CIPHER_SERVER_PREFERENCE;
-               else if (strcmp(*argv,"-legacy_renegotiation") == 0)
-                       off|=SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
-               else if (strcmp(*argv,"-legacy_server_connect") == 0)
-                       { off|=SSL_OP_LEGACY_SERVER_CONNECT; }
-               else if (strcmp(*argv,"-no_legacy_server_connect") == 0)
-                       { clr|=SSL_OP_LEGACY_SERVER_CONNECT; }
-               else if (strcmp(*argv,"-cipher") == 0)
-                       {
-                       if (--argc < 1) goto bad;
-                       cipher= *(++argv);
-                       }
 #ifdef FIONBIO
                else if (strcmp(*argv,"-nbio") == 0)
                        { c_nbio=1; }
@@ -953,12 +962,22 @@ int MAIN(int argc, char **argv)
                        servername= *(++argv);
                        /* meth=TLSv1_client_method(); */
                        }
-               else if (strcmp(*argv,"-curves") == 0)
+#endif
+               else if (strcmp(*argv,"-checkhost") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       checkhost=(unsigned char *)*(++argv);
+                       }
+               else if (strcmp(*argv,"-checkemail") == 0)
                        {
                        if (--argc < 1) goto bad;
-                       curves= *(++argv);
+                       checkemail=(unsigned char *)*(++argv);
+                       }
+               else if (strcmp(*argv,"-checkip") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       checkip=*(++argv);
                        }
-#endif
 #ifndef OPENSSL_NO_JPAKE
                else if (strcmp(*argv,"-jpake") == 0)
                        {
@@ -1087,6 +1106,9 @@ bad:
                        }
                }
 
+       if (!load_excert(&exc, bio_err))
+               goto end;
+
        if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
                && !RAND_status())
                {
@@ -1127,6 +1149,12 @@ bad:
        if (vpm)
                SSL_CTX_set1_param(ctx, vpm);
 
+       if (!args_ssl_call(ctx, bio_err, cctx, ssl_args))
+               {
+               ERR_print_errors(bio_err);
+               goto end;
+               }
+
 #ifndef OPENSSL_NO_ENGINE
        if (ssl_client_engine)
                {
@@ -1155,13 +1183,7 @@ bad:
        if (srtp_profiles != NULL)
                SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles);
 #endif
-       if (bugs)
-               SSL_CTX_set_options(ctx,SSL_OP_ALL|off);
-       else
-               SSL_CTX_set_options(ctx,off);
-
-       if (clr)
-               SSL_CTX_clear_options(ctx, clr);
+       if (exc) ssl_ctx_set_excert(ctx, exc);
        /* DTLS: partial reads end up discarding unread UDP bytes :-( 
         * Setting read ahead solves this problem.
         */
@@ -1173,20 +1195,12 @@ bad:
 #endif
 
        if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
-       if (cipher != NULL)
-               if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
-               BIO_printf(bio_err,"error setting cipher list\n");
-               ERR_print_errors(bio_err);
-               goto end;
-       }
 #if 0
        else
                SSL_CTX_set_cipher_list(ctx,getenv("SSL_CIPHER"));
 #endif
 
        SSL_CTX_set_verify(ctx,verify,verify_callback);
-       if (!set_cert_key_stuff(ctx,cert,key, NULL))
-               goto end;
 
        if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
                (!SSL_CTX_set_default_verify_paths(ctx)))
@@ -1196,13 +1210,10 @@ bad:
                /* goto end; */
                }
 
-#ifndef OPENSSL_NO_TLSEXT
-       if (curves != NULL)
-               if(!SSL_CTX_set1_curves_list(ctx,curves)) {
-               BIO_printf(bio_err,"error setting curve list\n");
-               ERR_print_errors(bio_err);
+       if (!set_cert_key_stuff(ctx,cert,key, NULL, build_chain))
                goto end;
-       }
+
+#ifndef OPENSSL_NO_TLSEXT
        if (servername != NULL)
                {
                tlsextcbp.biodebug = bio_err;
@@ -1564,6 +1575,14 @@ SSL_set_tlsext_status_ids(con, ids);
                                        else 
                                                BIO_printf(bio_err, "Error writing session file %s\n", sess_out);
                                        }
+                               if (c_brief)
+                                       {
+                                       BIO_puts(bio_err,
+                                               "CONNECTION ESTABLISHED\n");
+                                       print_ssl_summary(bio_err, con);
+                                       }
+                               print_ssl_cert_checks(bio_err, con, checkhost,
+                                                       checkemail, checkip);
                                print_stuff(bio_c_out,con,full_log);
                                if (full_log > 0) full_log--;
 
@@ -1926,6 +1945,10 @@ end:
                        print_stuff(bio_c_out,con,1);
                SSL_free(con);
                }
+#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+       if (next_proto.data)
+               OPENSSL_free(next_proto.data);
+#endif
        if (ctx != NULL) SSL_CTX_free(ctx);
        if (cert)
                X509_free(cert);
@@ -1933,6 +1956,11 @@ end:
                EVP_PKEY_free(key);
        if (pass)
                OPENSSL_free(pass);
+       ssl_excert_free(exc);
+       if (ssl_args)
+               sk_OPENSSL_STRING_free(ssl_args);
+       if (cctx)
+               SSL_CONF_CTX_free(cctx);
        if (cbuf != NULL) { OPENSSL_cleanse(cbuf,BUFSIZZ); OPENSSL_free(cbuf); }
        if (sbuf != NULL) { OPENSSL_cleanse(sbuf,BUFSIZZ); OPENSSL_free(sbuf); }
        if (mbuf != NULL) { OPENSSL_cleanse(mbuf,BUFSIZZ); OPENSSL_free(mbuf); }
@@ -2053,6 +2081,7 @@ static void print_stuff(BIO *bio, SSL *s, int full)
                        }
 
                ssl_print_sigalgs(bio, s);
+               ssl_print_tmp_key(bio, s);
 
                BIO_printf(bio,"---\nSSL handshake has read %ld bytes and written %ld bytes\n",
                        BIO_number_read(SSL_get_rbio(s)),