Allow multiple IDN xn-- indicators
[openssl.git] / apps / s_client.c
index 3d607ea90d088f72cedf9f5350a54cec27061c83..d27ee3dd35ab2c120f41f51f31be7b3c2df48046 100644 (file)
@@ -203,7 +203,6 @@ static int c_debug=0;
 #ifndef OPENSSL_NO_TLSEXT
 static int c_tlsextdebug=0;
 static int c_status_req=0;
-static int c_proof_debug=0;
 #endif
 static int c_msg=0;
 static int c_showcerts=0;
@@ -215,7 +214,6 @@ static void sc_usage(void);
 static void print_stuff(BIO *berr,SSL *con,int full);
 #ifndef OPENSSL_NO_TLSEXT
 static int ocsp_resp_cb(SSL *s, void *arg);
-static int audit_proof_cb(SSL *s, void *arg);
 #endif
 static BIO *bio_c_out=NULL;
 static BIO *bio_c_msg=NULL;
@@ -293,11 +291,12 @@ 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_host host - check peer certificate matches \"host\"\n");
+       BIO_printf(bio_err," -verify_email email - check peer certificate matches \"email\"\n");
+       BIO_printf(bio_err," -verify_ip ipaddr - check peer certificate matches \"ipaddr\"\n");
 
        BIO_printf(bio_err," -verify arg   - turn on peer certificate verification\n");
+       BIO_printf(bio_err," -verify_return_error - return verification errors\n");
        BIO_printf(bio_err," -cert arg     - certificate file to use, PEM format assumed\n");
        BIO_printf(bio_err," -certform arg - certificate format (PEM or DER) PEM default\n");
        BIO_printf(bio_err," -key arg      - Private key file to use, in cert file if\n");
@@ -308,6 +307,7 @@ static void sc_usage(void)
        BIO_printf(bio_err," -CAfile arg   - PEM format file of CA's\n");
        BIO_printf(bio_err," -reconnect    - Drop and re-make the connection with the same Session-ID\n");
        BIO_printf(bio_err," -pause        - sleep(1) after each read(2) and write(2) system call\n");
+       BIO_printf(bio_err," -prexit       - print session information even on connection failure\n");
        BIO_printf(bio_err," -showcerts    - show all certificates in the chain\n");
        BIO_printf(bio_err," -debug        - extra output\n");
 #ifdef WATT32
@@ -335,14 +335,17 @@ static void sc_usage(void)
        BIO_printf(bio_err," -srppass arg      - password for 'user'\n");
        BIO_printf(bio_err," -srp_lateuser     - SRP username into second ClientHello message\n");
        BIO_printf(bio_err," -srp_moregroups   - Tolerate other than the known g N values.\n");
-       BIO_printf(bio_err," -srp_strength int - minimal mength in bits for N (default %d).\n",SRP_MINIMAL_N);
+       BIO_printf(bio_err," -srp_strength int - minimal length in bits for N (default %d).\n",SRP_MINIMAL_N);
 #endif
        BIO_printf(bio_err," -ssl2         - just use SSLv2\n");
+#ifndef OPENSSL_NO_SSL3_METHOD
        BIO_printf(bio_err," -ssl3         - just use SSLv3\n");
+#endif
        BIO_printf(bio_err," -tls1_2       - just use TLSv1.2\n");
        BIO_printf(bio_err," -tls1_1       - just use TLSv1.1\n");
        BIO_printf(bio_err," -tls1         - just use TLSv1\n");
        BIO_printf(bio_err," -dtls1        - just use DTLSv1\n");    
+       BIO_printf(bio_err," -fallback_scsv - send TLS_FALLBACK_SCSV\n");
        BIO_printf(bio_err," -mtu          - set the link layer MTU\n");
        BIO_printf(bio_err," -no_tls1_2/-no_tls1_1/-no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n");
        BIO_printf(bio_err," -bugs         - Switch on all SSL implementation bug workarounds\n");
@@ -365,17 +368,16 @@ static void sc_usage(void)
        BIO_printf(bio_err," -tlsextdebug      - hex dump of all TLS extensions received\n");
        BIO_printf(bio_err," -status           - request certificate status from server\n");
        BIO_printf(bio_err," -no_ticket        - disable use of RFC4507bis session tickets\n");
-       BIO_printf(bio_err," -proof_debug      - request an audit proof and print its hex dump\n");
+       BIO_printf(bio_err," -serverinfo types - send empty ClientHello extensions (comma-separated numbers)\n");
+#endif
 # ifndef OPENSSL_NO_NEXTPROTONEG
        BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
 # endif
        BIO_printf(bio_err," -alpn arg         - enable ALPN extension, considering named protocols supported (comma-separated list)\n");
-#ifndef OPENSSL_NO_TLSEXT
-       BIO_printf(bio_err," -serverinfo types - send empty ClientHello extensions (comma-separated numbers)\n");
-#endif
-#endif
        BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
+#ifndef OPENSSL_NO_SRTP
        BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
+#endif
        BIO_printf(bio_err," -keymatexport label   - Export keying material using label\n");
        BIO_printf(bio_err," -keymatexportlen len  - Export len bytes of keying material (default 20)\n");
        }
@@ -515,7 +517,9 @@ static char * MS_CALLBACK ssl_give_srp_client_pwd_cb(SSL *s, void *arg)
        }
 
 #endif
+#ifndef OPENSSL_NO_SRTP
        char *srtp_profiles = NULL;
+#endif
 
 # ifndef OPENSSL_NO_NEXTPROTONEG
 /* This the context that we pass to next_proto_cb */
@@ -551,9 +555,9 @@ static int next_proto_cb(SSL *s, unsigned char **out, unsigned char *outlen, con
        }
 # endif  /* ndef OPENSSL_NO_NEXTPROTONEG */
 
-static int serverinfo_cli_cb(SSL* s, unsigned short ext_type,
-                            const unsigned char* in, unsigned short inlen, 
-                            int* al, void* arg)
+static int serverinfo_cli_parse_cb(SSL* s, unsigned int ext_type,
+                                  const unsigned char* in, size_t inlen, 
+                                  int* al, void* arg)
        {
        char pem_name[100];
        unsigned char ext_buf[4 + 65536];
@@ -652,6 +656,7 @@ int MAIN(int argc, char **argv)
        char *sess_out = NULL;
        struct sockaddr peer;
        int peerlen = sizeof(peer);
+       int fallback_scsv = 0;
        int enable_timeouts = 0 ;
        long socket_mtu = 0;
 #ifndef OPENSSL_NO_JPAKE
@@ -822,8 +827,6 @@ static char *jpake_secret = NULL;
                        c_tlsextdebug=1;
                else if (strcmp(*argv,"-status") == 0)
                        c_status_req=1;
-               else if (strcmp(*argv,"-proof_debug") == 0)
-                       c_proof_debug=1;
 #endif
 #ifdef WATT32
                else if (strcmp(*argv,"-wdebug") == 0)
@@ -902,7 +905,7 @@ static char *jpake_secret = NULL;
                else if (strcmp(*argv,"-ssl2") == 0)
                        meth=SSLv2_client_method();
 #endif
-#ifndef OPENSSL_NO_SSL3
+#ifndef OPENSSL_NO_SSL3_METHOD
                else if (strcmp(*argv,"-ssl3") == 0)
                        meth=SSLv3_client_method();
 #endif
@@ -938,6 +941,10 @@ static char *jpake_secret = NULL;
                        socket_mtu = atol(*(++argv));
                        }
 #endif
+               else if (strcmp(*argv,"-fallback_scsv") == 0)
+                       {
+                       fallback_scsv = 1;
+                       }
                else if (strcmp(*argv,"-keyform") == 0)
                        {
                        if (--argc < 1) goto bad;
@@ -1084,11 +1091,13 @@ static char *jpake_secret = NULL;
                        jpake_secret = *++argv;
                        }
 #endif
+#ifndef OPENSSL_NO_SRTP
                else if (strcmp(*argv,"-use_srtp") == 0)
                        {
                        if (--argc < 1) goto bad;
                        srtp_profiles = *(++argv);
                        }
+#endif
                else if (strcmp(*argv,"-keymatexport") == 0)
                        {
                        if (--argc < 1) goto bad;
@@ -1310,6 +1319,8 @@ bad:
                        BIO_printf(bio_c_out, "PSK key given or JPAKE in use, setting client callback\n");
                SSL_CTX_set_psk_client_callback(ctx, psk_client_cb);
                }
+#endif
+#ifndef OPENSSL_NO_SRTP
        if (srtp_profiles != NULL)
                SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles);
 #endif
@@ -1339,16 +1350,13 @@ bad:
                }
 #endif
 #ifndef OPENSSL_NO_TLSEXT
-               if (serverinfo_types_count)
+               for (i = 0; i < serverinfo_types_count; i++)
                        {
-                       for (i = 0; i < serverinfo_types_count; i++)
-                               {
-                               SSL_CTX_set_custom_cli_ext(ctx,
-                                                          serverinfo_types[i],
-                                                          NULL, 
-                                                          serverinfo_cli_cb,
-                                                          NULL);
-                               }
+                       SSL_CTX_add_client_custom_ext(ctx,
+                                                     serverinfo_types[i],
+                                                     NULL, NULL, NULL,
+                                                     serverinfo_cli_parse_cb,
+                                                     NULL);
                        }
 #endif
 
@@ -1397,9 +1405,6 @@ bad:
                }
 
 #endif
-       if (c_proof_debug)
-               SSL_CTX_set_tlsext_authz_server_audit_proof_cb(ctx,
-                                                              audit_proof_cb);
 #endif
 
        con=SSL_new(ctx);
@@ -1426,9 +1431,10 @@ bad:
                SSL_set_session(con, sess);
                SSL_SESSION_free(sess);
                }
-#ifndef OPENSSL_NO_DANE
-       SSL_pull_tlsa_record(con,host,port);
-#endif
+
+       if (fallback_scsv)
+               SSL_set_mode(con, SSL_MODE_SEND_FALLBACK_SCSV);
+
 #ifndef OPENSSL_NO_TLSEXT
        if (servername != NULL)
                {
@@ -1503,10 +1509,22 @@ re_start:
                        BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
                        }
 
-               if (socket_mtu > 28)
+               if (socket_mtu)
                        {
+                       if(socket_mtu < DTLS_get_link_min_mtu(con))
+                               {
+                               BIO_printf(bio_err,"MTU too small. Must be at least %ld\n",
+                                       DTLS_get_link_min_mtu(con));
+                               BIO_free(sbio);
+                               goto shut;
+                               }
                        SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
-                       SSL_set_mtu(con, socket_mtu - 28);
+                       if(!DTLS_set_link_mtu(con, socket_mtu))
+                               {
+                               BIO_printf(bio_err, "Failed to set MTU\n");
+                               BIO_free(sbio);
+                               goto shut;
+                               }
                        }
                else
                        /* want to do MTU discovery */
@@ -1743,6 +1761,7 @@ SSL_set_tlsext_status_ids(con, ids);
                                                "CONNECTION ESTABLISHED\n");
                                        print_ssl_summary(bio_err, con);
                                        }
+
                                print_stuff(bio_c_out,con,full_log);
                                if (full_log > 0) full_log--;
 
@@ -2321,6 +2340,7 @@ static void print_stuff(BIO *bio, SSL *s, int full)
        }
 #endif
 
+#ifndef OPENSSL_NO_SRTP
        {
        SRTP_PROTECTION_PROFILE *srtp_profile=SSL_get_selected_srtp_profile(s);
  
@@ -2328,6 +2348,7 @@ static void print_stuff(BIO *bio, SSL *s, int full)
                BIO_printf(bio,"SRTP Extension negotiated, profile=%s\n",
                           srtp_profile->name);
        }
+#endif
  
        SSL_SESSION_print(bio,SSL_get_session(s));
        if (keymatexportlabel != NULL)
@@ -2392,26 +2413,4 @@ static int ocsp_resp_cb(SSL *s, void *arg)
        return 1;
        }
 
-static int audit_proof_cb(SSL *s, void *arg)
-       {
-       const unsigned char *proof;
-       size_t proof_len;
-       size_t i;
-       SSL_SESSION *sess = SSL_get_session(s);
-
-       proof = SSL_SESSION_get_tlsext_authz_server_audit_proof(sess,
-                                                               &proof_len);
-       if (proof != NULL)
-               {
-               BIO_printf(bio_c_out, "Audit proof: ");
-               for (i = 0; i < proof_len; ++i)
-                       BIO_printf(bio_c_out, "%02X", proof[i]);
-               BIO_printf(bio_c_out, "\n");
-               }
-       else
-               {
-               BIO_printf(bio_c_out, "No audit proof found.\n");
-               }
-       return 1;
-       }
 #endif