#include <openssl/pem.h>
#include <openssl/rand.h>
#include <openssl/ocsp.h>
+#include <openssl/bn.h>
#include "s_apps.h"
#include "timeouts.h"
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);
+#endif
static BIO *bio_c_out=NULL;
static int c_quiet=0;
static int c_ign_eof=0;
#ifndef OPENSSL_NO_PSK
/* Default PSK identity and key */
static char *psk_identity="Client_identity";
-static char *psk_key=NULL; /* by default PSK is not used */
+/*char *psk_key=NULL; by default PSK is not used */
static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity,
unsigned int max_identity_len, unsigned char *psk,
BIO_printf(bio_c_out, "Received PSK identity hint '%s'\n", hint);
/* lookup PSK identity and PSK key based on the given identity hint here */
- ret = BIO_snprintf(identity, max_identity_len, psk_identity);
+ ret = BIO_snprintf(identity, max_identity_len, "%s", psk_identity);
if (ret < 0 || (unsigned int)ret > max_identity_len)
goto out_err;
if (c_debug)
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
BIO_printf(bio_err," -ssl2 - just use SSLv2\n");
BIO_printf(bio_err," -ssl3 - just use SSLv3\n");
BIO_printf(bio_err," -tls1 - just use TLSv1\n");
BIO_printf(bio_err," -dtls1 - just use DTLSv1\n");
- BIO_printf(bio_err," -mtu - set the MTU\n");
+ BIO_printf(bio_err," -mtu - set the link layer MTU\n");
BIO_printf(bio_err," -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," -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\", and \"ftp\" are supported.\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
PROTO_SMTP,
PROTO_POP3,
PROTO_IMAP,
- PROTO_FTP
+ PROTO_FTP,
+ PROTO_XMPP
};
int MAIN(int, char **);
int mbuf_len=0;
#ifndef OPENSSL_NO_ENGINE
char *engine_id=NULL;
- ENGINE *e=NULL;
+ 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)
int stdin_set = 0;
#endif
#endif
-
#ifndef OPENSSL_NO_TLSEXT
char *servername = NULL;
tlsextctx tlsextcbp =
int peerlen = sizeof(peer);
int enable_timeouts = 0 ;
long socket_mtu = 0;
+#ifndef OPENSSL_NO_JPAKE
+ char *jpake_secret = NULL;
+#endif
#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
meth=SSLv23_client_method();
}
else if (strcmp(*argv,"-ign_eof") == 0)
c_ign_eof=1;
+ else if (strcmp(*argv,"-no_ign_eof") == 0)
+ c_ign_eof=0;
else if (strcmp(*argv,"-pause") == 0)
c_Pause=1;
else if (strcmp(*argv,"-debug") == 0)
starttls_proto = PROTO_IMAP;
else if (strcmp(*argv,"ftp") == 0)
starttls_proto = PROTO_FTP;
+ else if (strcmp(*argv, "xmpp") == 0)
+ starttls_proto = PROTO_XMPP;
else
goto bad;
}
if (--argc < 1) goto bad;
engine_id = *(++argv);
}
+ else if (strcmp(*argv,"-ssl_client_engine") == 0)
+ {
+ if (--argc < 1) goto bad;
+ ssl_client_engine_id = *(++argv);
+ }
#endif
else if (strcmp(*argv,"-rand") == 0)
{
servername= *(++argv);
/* meth=TLSv1_client_method(); */
}
+#endif
+#ifndef OPENSSL_NO_JPAKE
+ else if (strcmp(*argv,"-jpake") == 0)
+ {
+ if (--argc < 1) goto bad;
+ jpake_secret = *++argv;
+ }
#endif
else
{
goto end;
}
+#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
+ if (jpake_secret)
+ {
+ if (psk_key)
+ {
+ BIO_printf(bio_err,
+ "Can't use JPAKE and PSK together\n");
+ goto end;
+ }
+ psk_identity = "JPAKE";
+ }
+
+ if (cipher)
+ {
+ BIO_printf(bio_err, "JPAKE sets cipher to PSK\n");
+ goto end;
+ }
+ cipher = "PSK";
+#endif
+
OpenSSL_add_ssl_algorithms();
SSL_load_error_strings();
#ifndef OPENSSL_NO_ENGINE
e = setup_engine(bio_err, engine_id, 1);
+ if (ssl_client_engine_id)
+ {
+ ssl_client_engine = ENGINE_by_id(ssl_client_engine_id);
+ if (!ssl_client_engine)
+ {
+ BIO_printf(bio_err,
+ "Error getting client auth engine\n");
+ goto end;
+ }
+ }
+
#endif
if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
{
goto end;
}
+#ifndef OPENSSL_NO_ENGINE
+ if (ssl_client_engine)
+ {
+ if (!SSL_CTX_set_client_cert_engine(ctx, ssl_client_engine))
+ {
+ BIO_puts(bio_err, "Error setting client auth engine\n");
+ ERR_print_errors(bio_err);
+ ENGINE_free(ssl_client_engine);
+ goto end;
+ }
+ ENGINE_free(ssl_client_engine);
+ }
+#endif
+
#ifndef OPENSSL_NO_PSK
+#ifdef OPENSSL_NO_JPAKE
if (psk_key != NULL)
+#else
+ if (psk_key != NULL || jpake_secret)
+#endif
{
if (c_debug)
- BIO_printf(bio_c_out, "PSK key given, setting client callback\n");
+ 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
BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
}
- if (socket_mtu > 0)
+ if (socket_mtu > 28)
{
SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
- SSL_set_mtu(con, socket_mtu);
+ SSL_set_mtu(con, socket_mtu - 28);
}
else
/* want to do MTU discovery */
else
sbio=BIO_new_socket(s,BIO_NOCLOSE);
-
-
if (nbio_test)
{
BIO *test;
#endif
}
#endif
+#ifndef OPENSSL_NO_JPAKE
+ if (jpake_secret)
+ jpake_client_auth(bio_c_out, sbio, jpake_secret);
+#endif
SSL_set_bio(con,sbio,sbio);
SSL_set_connect_state(con);
BIO_printf(sbio,"AUTH TLS\r\n");
BIO_read(sbio,sbuf,BUFSIZZ);
}
+ if (starttls_proto == PROTO_XMPP)
+ {
+ int seen = 0;
+ BIO_printf(sbio,"<stream:stream "
+ "xmlns:stream='http://etherx.jabber.org/streams' "
+ "xmlns='jabber:client' to='%s' version='1.0'>", host);
+ seen = BIO_read(sbio,mbuf,BUFSIZZ);
+ mbuf[seen] = 0;
+ while (!strstr(mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'"))
+ {
+ if (strstr(mbuf, "/stream:features>"))
+ goto shut;
+ seen = BIO_read(sbio,mbuf,BUFSIZZ);
+ mbuf[seen] = 0;
+ }
+ BIO_printf(sbio, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
+ seen = BIO_read(sbio,sbuf,BUFSIZZ);
+ sbuf[seen] = 0;
+ if (!strstr(sbuf, "<proceed"))
+ goto shut;
+ mbuf[0] = 0;
+ }
for (;;)
{
char buf[BUFSIZ];
STACK_OF(X509) *sk;
STACK_OF(X509_NAME) *sk2;
- SSL_CIPHER *c;
+ const SSL_CIPHER *c;
X509_NAME *xn;
int j,i;
#ifndef OPENSSL_NO_COMP
(void)BIO_flush(bio);
}
+#ifndef OPENSSL_NO_TLSEXT
+
static int ocsp_resp_cb(SSL *s, void *arg)
{
const unsigned char *p;
OCSP_RESPONSE_free(rsp);
return 1;
}
+
+#endif