Fix the return type of felem_is_zero_int which should be int.
[oweals/openssl.git] / apps / s_client.c
index d53bca14a0b75d29ff45ce1428f2c7d3d06acc1a..dc467994f8e2423b5e6d6656a732215806b02ff6 100644 (file)
@@ -242,9 +242,9 @@ static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity,
                                   unsigned char *psk,
                                   unsigned int max_psk_len)
 {
-    unsigned int psk_len = 0;
     int ret;
-    BIGNUM *bn = NULL;
+    long key_len;
+    unsigned char *key;
 
     if (c_debug)
         BIO_printf(bio_c_out, "psk_client_cb\n");
@@ -265,32 +265,29 @@ static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity,
     if (c_debug)
         BIO_printf(bio_c_out, "created identity '%s' len=%d\n", identity,
                    ret);
-    ret = BN_hex2bn(&bn, psk_key);
-    if (!ret) {
-        BIO_printf(bio_err, "Could not convert PSK key '%s' to BIGNUM\n",
+
+    /* convert the PSK key to binary */
+    key = string_to_hex(psk_key, &key_len);
+    if (key == NULL) {
+        BIO_printf(bio_err, "Could not convert PSK key '%s' to buffer\n",
                    psk_key);
-        if (bn)
-            BN_free(bn);
         return 0;
     }
-
-    if ((unsigned int)BN_num_bytes(bn) > max_psk_len) {
+    if ((unsigned long)key_len > (unsigned long)max_psk_len) {
         BIO_printf(bio_err,
-                   "psk buffer of callback is too small (%d) for key (%d)\n",
-                   max_psk_len, BN_num_bytes(bn));
-        BN_free(bn);
+                   "psk buffer of callback is too small (%d) for key (%ld)\n",
+                   max_psk_len, key_len);
+        OPENSSL_free(key);
         return 0;
     }
 
-    psk_len = BN_bn2bin(bn, psk);
-    BN_free(bn);
-    if (psk_len == 0)
-        goto out_err;
+    memcpy(psk, key, key_len);
+    OPENSSL_free(key);
 
     if (c_debug)
-        BIO_printf(bio_c_out, "created PSK len=%d\n", psk_len);
+        BIO_printf(bio_c_out, "created PSK len=%ld\n", key_len);
 
-    return psk_len;
+    return key_len;
  out_err:
     if (c_debug)
         BIO_printf(bio_err, "Error in PSK client callback\n");
@@ -308,7 +305,7 @@ static void sc_usage(void)
                " -connect host:port - who to connect to (default is %s:%s)\n",
                SSL_HOST_NAME, PORT_STR);
     BIO_printf(bio_err,
-               " -verify_host host - check peer certificate matches \"host\"\n");
+               " -verify_hostname host - check peer certificate matches \"host\"\n");
     BIO_printf(bio_err,
                " -verify_email email - check peer certificate matches \"email\"\n");
     BIO_printf(bio_err,
@@ -331,6 +328,8 @@ static void sc_usage(void)
                " -pass arg     - private key file pass phrase source\n");
     BIO_printf(bio_err, " -CApath arg   - PEM format directory of CA's\n");
     BIO_printf(bio_err, " -CAfile arg   - PEM format file of CA's\n");
+    BIO_printf(bio_err,
+               " -no_alt_chains - only ever use the first certificate chain found\n");
     BIO_printf(bio_err,
                " -reconnect    - Drop and re-make the connection with the same Session-ID\n");
     BIO_printf(bio_err,
@@ -388,8 +387,6 @@ static void sc_usage(void)
                " -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");
-    BIO_printf(bio_err,
-               " -serverpref   - Use server's cipher preferences (only SSLv2)\n");
     BIO_printf(bio_err,
                " -cipher       - preferred cipher to use, use the 'openssl ciphers'\n");
     BIO_printf(bio_err,
@@ -422,6 +419,14 @@ static void sc_usage(void)
                " -no_ticket        - disable use of RFC4507bis session tickets\n");
     BIO_printf(bio_err,
                " -serverinfo types - send empty ClientHello extensions (comma-separated numbers)\n");
+    BIO_printf(bio_err,
+               " -curves arg       - Elliptic curves to advertise (colon-separated list)\n");
+    BIO_printf(bio_err,
+               " -sigalgs arg      - Signature algorithms to support (colon-separated list)\n");
+    BIO_printf(bio_err,
+               " -client_sigalgs arg - Signature algorithms to support for client\n");
+    BIO_printf(bio_err,
+               "                       certificate authentication (colon-separated list)\n");
 #endif
 #ifndef OPENSSL_NO_NEXTPROTONEG
     BIO_printf(bio_err,
@@ -689,12 +694,12 @@ int MAIN(int argc, char **argv)
     char *inrand = NULL;
     int mbuf_len = 0;
     struct timeval timeout, *timeoutp;
-#ifndef OPENSSL_NO_ENGINE
     char *engine_id = NULL;
+    ENGINE *e = NULL;
+#ifndef OPENSSL_NO_ENGINE
     char *ssl_client_engine_id = NULL;
     ENGINE *ssl_client_engine = NULL;
 #endif
-    ENGINE *e = NULL;
 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
     struct timeval tv;
 # if defined(OPENSSL_SYS_BEOS_R5)
@@ -739,6 +744,7 @@ int MAIN(int argc, char **argv)
     int crl_format = FORMAT_PEM;
     int crl_download = 0;
     STACK_OF(X509_CRL) *crls = NULL;
+    int prot_opt = 0, no_prot_opt = 0;
 
     meth = SSLv23_client_method();
 
@@ -842,7 +848,8 @@ int MAIN(int argc, char **argv)
             if (badarg)
                 goto bad;
             continue;
-        } else if (args_ssl(&argv, &argc, cctx, &badarg, bio_err, &ssl_args)) {
+        } else if (args_ssl(&argv, &argc, cctx, &badarg, bio_err, &ssl_args,
+                            &no_prot_opt)) {
             if (badarg)
                 goto bad;
             continue;
@@ -934,31 +941,42 @@ int MAIN(int argc, char **argv)
         }
 #endif
 #ifndef OPENSSL_NO_SSL2
-        else if (strcmp(*argv, "-ssl2") == 0)
+        else if (strcmp(*argv, "-ssl2") == 0) {
             meth = SSLv2_client_method();
+            prot_opt++;
+        }
 #endif
 #ifndef OPENSSL_NO_SSL3_METHOD
-        else if (strcmp(*argv, "-ssl3") == 0)
+        else if (strcmp(*argv, "-ssl3") == 0) {
             meth = SSLv3_client_method();
+            prot_opt++;
+        }
 #endif
 #ifndef OPENSSL_NO_TLS1
-        else if (strcmp(*argv, "-tls1_2") == 0)
+        else if (strcmp(*argv, "-tls1_2") == 0) {
             meth = TLSv1_2_client_method();
-        else if (strcmp(*argv, "-tls1_1") == 0)
+            prot_opt++;
+        } else if (strcmp(*argv, "-tls1_1") == 0) {
             meth = TLSv1_1_client_method();
-        else if (strcmp(*argv, "-tls1") == 0)
+            prot_opt++;
+        } else if (strcmp(*argv, "-tls1") == 0) {
             meth = TLSv1_client_method();
+            prot_opt++;
+        }
 #endif
 #ifndef OPENSSL_NO_DTLS1
         else if (strcmp(*argv, "-dtls") == 0) {
             meth = DTLS_client_method();
             socket_type = SOCK_DGRAM;
+            prot_opt++;
         } else if (strcmp(*argv, "-dtls1") == 0) {
             meth = DTLSv1_client_method();
             socket_type = SOCK_DGRAM;
+            prot_opt++;
         } else if (strcmp(*argv, "-dtls1_2") == 0) {
             meth = DTLSv1_2_client_method();
             socket_type = SOCK_DGRAM;
+            prot_opt++;
         } else if (strcmp(*argv, "-timeout") == 0)
             enable_timeouts = 1;
         else if (strcmp(*argv, "-mtu") == 0) {
@@ -1141,6 +1159,17 @@ int MAIN(int argc, char **argv)
     }
 #endif
 
+    if (prot_opt > 1) {
+        BIO_printf(bio_err, "Cannot supply multiple protocol flags\n");
+        goto end;
+    }
+
+    if (prot_opt == 1 && no_prot_opt) {
+        BIO_printf(bio_err, "Cannot supply both a protocol flag and "
+                            "\"-no_<prot>\"\n");
+        goto end;
+    }
+
     OpenSSL_add_ssl_algorithms();
     SSL_load_error_strings();
 
@@ -1157,8 +1186,8 @@ int MAIN(int argc, char **argv)
         next_proto.data = NULL;
 #endif
 
-#ifndef OPENSSL_NO_ENGINE
     e = setup_engine(bio_err, engine_id, 1);
+#ifndef OPENSSL_NO_ENGINE
     if (ssl_client_engine_id) {
         ssl_client_engine = ENGINE_by_id(ssl_client_engine_id);
         if (!ssl_client_engine) {
@@ -1532,7 +1561,10 @@ int MAIN(int argc, char **argv)
     SSL_set_connect_state(con);
 
     /* ok, lets connect */
-    width = SSL_get_fd(con) + 1;
+    if (fileno_stdin() > SSL_get_fd(con))
+        width = fileno_stdin() + 1;
+    else
+        width = SSL_get_fd(con) + 1;
 
     read_tty = 1;
     write_tty = 0;
@@ -1635,6 +1667,8 @@ int MAIN(int argc, char **argv)
             if (strstr(mbuf, "/stream:features>"))
                 goto shut;
             seen = BIO_read(sbio, mbuf, BUFSIZZ);
+            if (seen <= 0)
+                goto shut;
             mbuf[seen] = 0;
         }
         BIO_printf(sbio,
@@ -1715,9 +1749,11 @@ int MAIN(int argc, char **argv)
 #if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined (OPENSSL_SYS_BEOS_R5)
             if (tty_on) {
                 if (read_tty)
-                    openssl_fdset(fileno(stdin), &readfds);
+                    openssl_fdset(fileno_stdin(), &readfds);
+#if !defined(OPENSSL_SYS_VMS)
                 if (write_tty)
-                    openssl_fdset(fileno(stdout), &writefds);
+                    openssl_fdset(fileno_stdout(), &writefds);
+#endif
             }
             if (read_ssl)
                 openssl_fdset(SSL_get_fd(con), &readfds);
@@ -1787,14 +1823,14 @@ int MAIN(int argc, char **argv)
             /* Under BeOS-R5 the situation is similar to DOS */
             i = 0;
             stdin_set = 0;
-            (void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
+            (void)fcntl(fileno_stdin(), F_SETFL, O_NONBLOCK);
             if (!write_tty) {
                 if (read_tty) {
                     tv.tv_sec = 1;
                     tv.tv_usec = 0;
                     i = select(width, (void *)&readfds, (void *)&writefds,
                                NULL, &tv);
-                    if (read(fileno(stdin), sbuf, 0) >= 0)
+                    if (read(fileno_stdin(), sbuf, 0) >= 0)
                         stdin_set = 1;
                     if (!i && (stdin_set != 1 || !read_tty))
                         continue;
@@ -1802,7 +1838,7 @@ int MAIN(int argc, char **argv)
                     i = select(width, (void *)&readfds, (void *)&writefds,
                                NULL, timeoutp);
             }
-            (void)fcntl(fileno(stdin), F_SETFL, 0);
+            (void)fcntl(fileno_stdin(), F_SETFL, 0);
 #else
             i = select(width, (void *)&readfds, (void *)&writefds,
                        NULL, timeoutp);
@@ -1878,11 +1914,11 @@ int MAIN(int argc, char **argv)
                 goto shut;
             }
         }
-#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5) || defined(OPENSSL_SYS_VMS)
         /* Assume Windows/DOS/BeOS can always write */
         else if (!ssl_pending && write_tty)
 #else
-        else if (!ssl_pending && FD_ISSET(fileno(stdout), &writefds))
+        else if (!ssl_pending && FD_ISSET(fileno_stdout(), &writefds))
 #endif
         {
 #ifdef CHARSET_EBCDIC
@@ -1980,7 +2016,7 @@ int MAIN(int argc, char **argv)
 #elif defined(OPENSSL_SYS_BEOS_R5)
         else if (stdin_set)
 #else
-        else if (FD_ISSET(fileno(stdin), &readfds))
+        else if (FD_ISSET(fileno_stdin(), &readfds))
 #endif
         {
             if (crlf) {
@@ -2063,6 +2099,9 @@ int MAIN(int argc, char **argv)
         sk_X509_pop_free(chain, X509_free);
     if (pass)
         OPENSSL_free(pass);
+#ifndef OPENSSL_NO_SRP
+    OPENSSL_free(srp_arg.srppassin);
+#endif
     if (vpm)
         X509_VERIFY_PARAM_free(vpm);
     ssl_excert_free(exc);
@@ -2086,6 +2125,7 @@ int MAIN(int argc, char **argv)
         OPENSSL_cleanse(mbuf, BUFSIZZ);
         OPENSSL_free(mbuf);
     }
+    release_engine(e);
     if (bio_c_out != NULL) {
         BIO_free(bio_c_out);
         bio_c_out = NULL;
@@ -2094,6 +2134,7 @@ int MAIN(int argc, char **argv)
         BIO_free(bio_c_msg);
         bio_c_msg = NULL;
     }
+    SSL_COMP_free_compression_methods();
     apps_shutdown();
     OPENSSL_EXIT(ret);
 }