+ BIO_printf(bio_err, " -nbio - Run with non-blocking IO\n");
+#endif
+ BIO_printf(bio_err,
+ " -crlf - convert LF from terminal into CRLF\n");
+ BIO_printf(bio_err, " -quiet - no s_client output\n");
+ BIO_printf(bio_err,
+ " -ign_eof - ignore input eof (default when -quiet)\n");
+ BIO_printf(bio_err, " -no_ign_eof - don't ignore input eof\n");
+#ifndef OPENSSL_NO_PSK
+ BIO_printf(bio_err, " -psk_identity arg - PSK identity\n");
+ BIO_printf(bio_err, " -psk arg - PSK in hex (without 0x)\n");
+# ifndef OPENSSL_NO_JPAKE
+ BIO_printf(bio_err, " -jpake arg - JPAKE secret to use\n");
+# endif
+#endif
+#ifndef OPENSSL_NO_SRP
+ BIO_printf(bio_err,
+ " -srpuser user - SRP authentification for 'user'\n");
+ 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 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");
+ 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,
+ " command to see what is available\n");
+ BIO_printf(bio_err,
+ " -starttls prot - use the STARTTLS command before starting TLS\n");
+ BIO_printf(bio_err,
+ " for those protocols that support it, where\n");
+ BIO_printf(bio_err,
+ " 'prot' defines which one to assume. Currently,\n");
+ BIO_printf(bio_err,
+ " only \"smtp\", \"pop3\", \"imap\", \"ftp\" and \"xmpp\"\n");
+ BIO_printf(bio_err, " are supported.\n");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err,
+ " -engine id - Initialise and use the specified engine\n");
+#endif
+ BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR,
+ LIST_SEPARATOR_CHAR);
+ BIO_printf(bio_err, " -sess_out arg - file to write SSL session to\n");
+ BIO_printf(bio_err, " -sess_in arg - file to read SSL session from\n");
+#ifndef OPENSSL_NO_TLSEXT
+ BIO_printf(bio_err,
+ " -servername host - Set TLS extension servername in ClientHello\n");
+ 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,
+ " -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");
+ 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");
+}
+
+#ifndef OPENSSL_NO_TLSEXT
+
+/* This is a context that we pass to callbacks */
+typedef struct tlsextctx_st {
+ BIO *biodebug;
+ int ack;
+} tlsextctx;
+
+static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
+{
+ tlsextctx *p = (tlsextctx *) arg;
+ const char *hn = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
+ if (SSL_get_servername_type(s) != -1)
+ p->ack = !SSL_session_reused(s) && hn != NULL;
+ else
+ BIO_printf(bio_err, "Can't use SSL_get_servername\n");
+
+ return SSL_TLSEXT_ERR_OK;
+}
+
+# ifndef OPENSSL_NO_SRP
+
+/* This is a context that we pass to all callbacks */
+typedef struct srp_arg_st {
+ char *srppassin;
+ char *srplogin;
+ int msg; /* copy from c_msg */
+ int debug; /* copy from c_debug */
+ int amp; /* allow more groups */
+ int strength /* minimal size for N */ ;
+} SRP_ARG;
+
+# define SRP_NUMBER_ITERATIONS_FOR_PRIME 64
+
+static int srp_Verify_N_and_g(BIGNUM *N, BIGNUM *g)
+{
+ BN_CTX *bn_ctx = BN_CTX_new();
+ BIGNUM *p = BN_new();
+ BIGNUM *r = BN_new();
+ int ret =
+ g != NULL && N != NULL && bn_ctx != NULL && BN_is_odd(N) &&
+ BN_is_prime_ex(N, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) &&
+ p != NULL && BN_rshift1(p, N) &&
+ /* p = (N-1)/2 */
+ BN_is_prime_ex(p, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) &&
+ r != NULL &&
+ /* verify g^((N-1)/2) == -1 (mod N) */
+ BN_mod_exp(r, g, p, N, bn_ctx) &&
+ BN_add_word(r, 1) && BN_cmp(r, N) == 0;
+
+ if (r)
+ BN_free(r);
+ if (p)
+ BN_free(p);
+ if (bn_ctx)
+ BN_CTX_free(bn_ctx);
+ return ret;
+}
+
+/*-
+ * This callback is used here for two purposes:
+ * - extended debugging
+ * - making some primality tests for unknown groups
+ * The callback is only called for a non default group.
+ *
+ * An application does not need the call back at all if
+ * only the stanard groups are used. In real life situations,
+ * client and server already share well known groups,
+ * thus there is no need to verify them.
+ * Furthermore, in case that a server actually proposes a group that
+ * is not one of those defined in RFC 5054, it is more appropriate
+ * to add the group to a static list and then compare since
+ * primality tests are rather cpu consuming.
+ */
+
+static int MS_CALLBACK ssl_srp_verify_param_cb(SSL *s, void *arg)
+{
+ SRP_ARG *srp_arg = (SRP_ARG *)arg;
+ BIGNUM *N = NULL, *g = NULL;
+ if (!(N = SSL_get_srp_N(s)) || !(g = SSL_get_srp_g(s)))
+ return 0;
+ if (srp_arg->debug || srp_arg->msg || srp_arg->amp == 1) {
+ BIO_printf(bio_err, "SRP parameters:\n");
+ BIO_printf(bio_err, "\tN=");
+ BN_print(bio_err, N);
+ BIO_printf(bio_err, "\n\tg=");
+ BN_print(bio_err, g);
+ BIO_printf(bio_err, "\n");
+ }
+
+ if (SRP_check_known_gN_param(g, N))
+ return 1;
+
+ if (srp_arg->amp == 1) {
+ if (srp_arg->debug)
+ BIO_printf(bio_err,
+ "SRP param N and g are not known params, going to check deeper.\n");
+
+ /*
+ * The srp_moregroups is a real debugging feature. Implementors
+ * should rather add the value to the known ones. The minimal size
+ * has already been tested.
+ */
+ if (BN_num_bits(g) <= BN_BITS && srp_Verify_N_and_g(N, g))
+ return 1;
+ }
+ BIO_printf(bio_err, "SRP param N and g rejected.\n");
+ return 0;
+}
+
+# define PWD_STRLEN 1024
+
+static char *MS_CALLBACK ssl_give_srp_client_pwd_cb(SSL *s, void *arg)
+{
+ SRP_ARG *srp_arg = (SRP_ARG *)arg;
+ char *pass = (char *)OPENSSL_malloc(PWD_STRLEN + 1);
+ PW_CB_DATA cb_tmp;
+ int l;
+
+ cb_tmp.password = (char *)srp_arg->srppassin;
+ cb_tmp.prompt_info = "SRP user";
+ if ((l = password_callback(pass, PWD_STRLEN, 0, &cb_tmp)) < 0) {
+ BIO_printf(bio_err, "Can't read Password\n");
+ OPENSSL_free(pass);
+ return NULL;
+ }
+ *(pass + l) = '\0';
+
+ return pass;
+}
+
+# endif
+# ifndef OPENSSL_NO_SRTP
+char *srtp_profiles = NULL;
+# endif
+
+# ifndef OPENSSL_NO_NEXTPROTONEG
+/* This the context that we pass to next_proto_cb */
+typedef struct tlsextnextprotoctx_st {
+ unsigned char *data;
+ unsigned short len;
+ int status;
+} tlsextnextprotoctx;
+
+static tlsextnextprotoctx next_proto;
+
+static int next_proto_cb(SSL *s, unsigned char **out, unsigned char *outlen,
+ const unsigned char *in, unsigned int inlen,
+ void *arg)
+{
+ tlsextnextprotoctx *ctx = arg;
+
+ if (!c_quiet) {
+ /* We can assume that |in| is syntactically valid. */
+ unsigned i;
+ BIO_printf(bio_c_out, "Protocols advertised by server: ");
+ for (i = 0; i < inlen;) {
+ if (i)
+ BIO_write(bio_c_out, ", ", 2);
+ BIO_write(bio_c_out, &in[i + 1], in[i]);
+ i += in[i] + 1;
+ }
+ BIO_write(bio_c_out, "\n", 1);
+ }
+
+ ctx->status =
+ SSL_select_next_proto(out, outlen, in, inlen, ctx->data, ctx->len);
+ return SSL_TLSEXT_ERR_OK;
+}
+# endif /* ndef OPENSSL_NO_NEXTPROTONEG */
+
+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];
+
+ /* Reconstruct the type/len fields prior to extension data */
+ ext_buf[0] = ext_type >> 8;
+ ext_buf[1] = ext_type & 0xFF;
+ ext_buf[2] = inlen >> 8;
+ ext_buf[3] = inlen & 0xFF;
+ memcpy(ext_buf + 4, in, inlen);
+
+ BIO_snprintf(pem_name, sizeof(pem_name), "SERVERINFO FOR EXTENSION %d",
+ ext_type);
+ PEM_write_bio(bio_c_out, pem_name, "", ext_buf, 4 + inlen);
+ return 1;
+}
+
+#endif
+
+enum {
+ PROTO_OFF = 0,
+ PROTO_SMTP,
+ PROTO_POP3,
+ PROTO_IMAP,
+ PROTO_FTP,
+ PROTO_XMPP
+};