BIO_printf(bio_err," -proof_debug - request an audit proof and print its hex dump\n");
# ifndef OPENSSL_NO_NEXTPROTONEG
BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
+ BIO_printf(bio_err," -alpn arg - enable ALPN extension, considering named protocols supported (comma-separated list)\n");
# endif
+#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");
BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
return SSL_TLSEXT_ERR_OK;
}
# 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)
+ {
+ 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), "SERVER_INFO %d", ext_type);
+ PEM_write_bio(bio_c_out, pem_name, "", ext_buf, 4 + inlen);
+ return 1;
+ }
+
#endif
enum
{NULL,0};
# ifndef OPENSSL_NO_NEXTPROTONEG
const char *next_proto_neg_in = NULL;
+ const char *alpn_in = NULL;
# endif
+# define MAX_SI_TYPES 100
+ unsigned short serverinfo_types[MAX_SI_TYPES];
+ int serverinfo_types_count = 0;
#endif
char *sess_in = NULL;
char *sess_out = NULL;
int enable_timeouts = 0 ;
long socket_mtu = 0;
#ifndef OPENSSL_NO_JPAKE
- char *jpake_secret = NULL;
+static char *jpake_secret = NULL;
+#define no_jpake !jpake_secret
+#else
+#define no_jpake 1
#endif
#ifndef OPENSSL_NO_SRP
char * srppass = NULL;
meth=TLSv1_client_method();
#endif
#ifndef OPENSSL_NO_DTLS1
+ else if (strcmp(*argv,"-dtls") == 0)
+ {
+ meth=DTLS_client_method();
+ socket_type=SOCK_DGRAM;
+ }
else if (strcmp(*argv,"-dtls1") == 0)
{
meth=DTLSv1_client_method();
socket_type=SOCK_DGRAM;
}
+ else if (strcmp(*argv,"-dtls1_2") == 0)
+ {
+ meth=DTLSv1_2_client_method();
+ socket_type=SOCK_DGRAM;
+ }
else if (strcmp(*argv,"-timeout") == 0)
enable_timeouts=1;
else if (strcmp(*argv,"-mtu") == 0)
if (--argc < 1) goto bad;
next_proto_neg_in = *(++argv);
}
+ else if (strcmp(*argv,"-alpn") == 0)
+ {
+ if (--argc < 1) goto bad;
+ alpn_in = *(++argv);
+ }
# endif
+ else if (strcmp(*argv,"-serverinfo") == 0)
+ {
+ char *c;
+ int start = 0;
+ int len;
+
+ if (--argc < 1) goto bad;
+ c = *(++argv);
+ serverinfo_types_count = 0;
+ len = strlen(c);
+ for (i = 0; i <= len; ++i)
+ {
+ if (i == len || c[i] == ',')
+ {
+ serverinfo_types[serverinfo_types_count]
+ = atoi(c+start);
+ serverinfo_types_count++;
+ start = i+1;
+ }
+ if (serverinfo_types_count == MAX_SI_TYPES)
+ break;
+ }
+ }
#endif
#ifdef FIONBIO
else if (strcmp(*argv,"-nbio") == 0)
}
psk_identity = "JPAKE";
}
-
- if (cipher)
- {
- BIO_printf(bio_err, "JPAKE sets cipher to PSK\n");
- goto end;
- }
- cipher = "PSK";
#endif
OpenSSL_add_ssl_algorithms();
if (vpm)
SSL_CTX_set1_param(ctx, vpm);
- if (!args_ssl_call(ctx, bio_err, cctx, ssl_args, 1))
+ if (!args_ssl_call(ctx, bio_err, cctx, ssl_args, 1, no_jpake))
{
ERR_print_errors(bio_err);
goto end;
*/
if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
-#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+#if !defined(OPENSSL_NO_TLSEXT)
+# if !defined(OPENSSL_NO_NEXTPROTONEG)
if (next_proto.data)
SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto);
+# endif
+ if (alpn_in)
+ {
+ unsigned short alpn_len;
+ unsigned char *alpn = next_protos_parse(&alpn_len, alpn_in);
+
+ if (alpn == NULL)
+ {
+ BIO_printf(bio_err, "Error parsing -alpn argument\n");
+ goto end;
+ }
+ SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len);
+ OPENSSL_free(alpn);
+ }
+#endif
+#ifndef OPENSSL_NO_TLSEXT
+ if (serverinfo_types_count)
+ {
+ for (i = 0; i < serverinfo_types_count; i++)
+ {
+ SSL_CTX_set_custom_cli_ext(ctx,
+ serverinfo_types[i],
+ NULL,
+ serverinfo_cli_cb,
+ NULL);
+ }
+ }
#endif
if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
#endif
if (c_Pause & 0x01) SSL_set_debug(con, 1);
- if ( SSL_version(con) == DTLS1_VERSION)
+ if (socket_type == SOCK_DGRAM)
{
sbio=BIO_new_dgram(s,BIO_NOCLOSE);
"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'"))
+ while (!strstr(mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'") &&
+ !strstr(mbuf, "<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\""))
{
- if (strstr(mbuf, "/stream:features>"))
- goto shut;
seen = BIO_read(sbio,mbuf,BUFSIZZ);
+
+ if (seen <= 0)
+ goto shut;
+
mbuf[seen] = 0;
}
BIO_printf(sbio, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
sk_OPENSSL_STRING_free(ssl_args);
if (cctx)
SSL_CONF_CTX_free(cctx);
+#ifndef OPENSSL_NO_JPAKE
+ if (jpake_secret && psk_key)
+ OPENSSL_free(psk_key);
+#endif
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); }
}
#endif
-#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+#if !defined(OPENSSL_NO_TLSEXT)
+# if !defined(OPENSSL_NO_NEXTPROTONEG)
if (next_proto.status != -1) {
const unsigned char *proto;
unsigned int proto_len;
BIO_write(bio, proto, proto_len);
BIO_write(bio, "\n", 1);
}
+ {
+ const unsigned char *proto;
+ unsigned int proto_len;
+ SSL_get0_alpn_selected(s, &proto, &proto_len);
+ if (proto_len > 0)
+ {
+ BIO_printf(bio, "ALPN protocol: ");
+ BIO_write(bio, proto, proto_len);
+ BIO_write(bio, "\n", 1);
+ }
+ else
+ BIO_printf(bio, "No ALPN negotiated\n");
+ }
+# endif
#endif
{