#endif
static int not_resumable_sess_cb(SSL *s, int is_forward_secure);
-static int sv_body(int s, int stype, unsigned char *context);
-static int www_body(int s, int stype, unsigned char *context);
-static int rev_body(int s, int stype, unsigned char *context);
+static int sv_body(int s, int stype, int prot, unsigned char *context);
+static int www_body(int s, int stype, int prot, unsigned char *context);
+static int rev_body(int s, int stype, int prot, unsigned char *context);
static void close_accept_socket(void);
static int init_ssl_connection(SSL *s);
static void print_stats(BIO *bp, SSL_CTX *ctx);
#endif
static void print_connection_info(SSL *con);
-/* static int load_CA(SSL_CTX *ctx, char *file);*/
-
static const int bufsize = 16 * 1024;
static int accept_socket = -1;
#ifndef OPENSSL_NO_DTLS
static int enable_timeouts = 0;
static long socket_mtu;
-
#endif
+
+/*
+ * We define this but make it always be 0 in no-dtls builds to simplify the
+ * code.
+ */
static int dtlslisten = 0;
+static int early_data = 0;
+
#ifndef OPENSSL_NO_PSK
-static char *psk_identity = "Client_identity";
+static const char psk_identity[] = "Client_identity";
char *psk_key = NULL; /* by default PSK is not used */
-static int early_data = 0;
-
static unsigned int psk_server_cb(SSL *ssl, const char *identity,
unsigned char *psk,
unsigned int max_psk_len)
}
/* Structure passed to cert status callback */
-
typedef struct tlsextstatusctx_st {
int timeout;
/* File to load OCSP Response from (or NULL if no file) */
/* This is the context that we pass to next_proto_cb */
typedef struct tlsextnextprotoctx_st {
unsigned char *data;
- unsigned int len;
+ size_t len;
} tlsextnextprotoctx;
static int next_proto_cb(SSL *s, const unsigned char **data,
OPT_SRPUSERSEED, OPT_REV, OPT_WWW, OPT_UPPER_WWW, OPT_HTTP, OPT_ASYNC,
OPT_SSL_CONFIG, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES, OPT_READ_BUF,
OPT_SSL3, OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1,
- OPT_DTLS1_2, OPT_TIMEOUT, OPT_MTU, OPT_LISTEN,
+ OPT_DTLS1_2, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_LISTEN,
OPT_ID_PREFIX, OPT_RAND, OPT_SERVERNAME, OPT_SERVERNAME_FATAL,
OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN,
OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN,
#ifndef OPENSSL_NO_DTLS1_2
{"dtls1_2", OPT_DTLS1_2, '-', "Just talk DTLSv1.2"},
#endif
+#ifndef OPENSSL_NO_SCTP
+ {"sctp", OPT_SCTP, '-', "Use SCTP"},
+#endif
#ifndef OPENSSL_NO_DH
{"no_dhe", OPT_NO_DHE, '-', "Disable ephemeral DH"},
#endif
int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM;
int rev = 0, naccept = -1, sdebug = 0;
- int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM;
+ int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM, protocol = 0;
int state = 0, crl_format = FORMAT_PEM, crl_download = 0;
char *host = NULL;
char *port = BUF_strdup(PORT);
tlsextalpnctx alpn_ctx = { NULL, 0 };
#ifndef OPENSSL_NO_PSK
/* by default do not send a PSK identity hint */
- static char *psk_identity_hint = NULL;
+ char *psk_identity_hint = NULL;
char *p;
#endif
#ifndef OPENSSL_NO_SRP
min_version = DTLS1_2_VERSION;
max_version = DTLS1_2_VERSION;
socket_type = SOCK_DGRAM;
+#endif
+ break;
+ case OPT_SCTP:
+#ifndef OPENSSL_NO_SCTP
+ protocol = IPPROTO_SCTP;
#endif
break;
case OPT_TIMEOUT:
}
#endif
+#ifndef OPENSSL_NO_SCTP
+ if (protocol == IPPROTO_SCTP) {
+ if (socket_type != SOCK_DGRAM) {
+ BIO_printf(bio_err, "Can't use -sctp without DTLS\n");
+ goto end;
+ }
+ /* SCTP is unusual. It uses DTLS over a SOCK_STREAM protocol */
+ socket_type = SOCK_STREAM;
+ }
+#endif
+
if (split_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) {
BIO_printf(bio_err, "Bad split send fragment size\n");
goto end;
}
#if !defined(OPENSSL_NO_NEXTPROTONEG)
if (next_proto_neg_in) {
- size_t len;
- next_proto.data = next_protos_parse(&len, next_proto_neg_in);
+ next_proto.data = next_protos_parse(&next_proto.len, next_proto_neg_in);
if (next_proto.data == NULL)
goto end;
- next_proto.len = len;
- } else {
- next_proto.data = NULL;
}
#endif
alpn_ctx.data = NULL;
if (alpn_in) {
- size_t len;
- alpn_ctx.data = next_protos_parse(&len, alpn_in);
+ alpn_ctx.data = next_protos_parse(&alpn_ctx.len, alpn_in);
if (alpn_ctx.data == NULL)
goto end;
- alpn_ctx.len = len;
}
if (crl_file) {
&& unlink_unix_path)
unlink(host);
#endif
- do_server(&accept_socket, host, port, socket_family, socket_type,
+ do_server(&accept_socket, host, port, socket_family, socket_type, protocol,
server_cb, context, naccept);
print_stats(bio_s_out, ctx);
ret = 0;
SSL_CTX_sess_get_cache_size(ssl_ctx));
}
-static int sv_body(int s, int stype, unsigned char *context)
+static int sv_body(int s, int stype, int prot, unsigned char *context)
{
char *buf = NULL;
fd_set readfds;
#else
struct timeval *timeoutp;
#endif
+#ifndef OPENSSL_NO_DTLS
+ #ifndef OPENSSL_NO_SCTP
+ int isdtls = (stype == SOCK_DGRAM || prot == IPPROTO_SCTP);
+ #else
+ int isdtls = (stype == SOCK_DGRAM);
+ #endif
+#endif
buf = app_malloc(bufsize, "server buffer");
if (s_nbio) {
goto err;
}
#ifndef OPENSSL_NO_DTLS
- if (stype == SOCK_DGRAM) {
-
- sbio = BIO_new_dgram(s, BIO_NOCLOSE);
+ if (isdtls) {
+#ifndef OPENSSL_NO_SCTP
+ if (prot == IPPROTO_SCTP)
+ sbio = BIO_new_dgram_sctp(s, BIO_NOCLOSE);
+ else
+#endif
+ sbio = BIO_new_dgram(s, BIO_NOCLOSE);
if (enable_timeouts) {
timeout.tv_sec = 0;
/* want to do MTU discovery */
BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
- /* turn on cookie exchange */
- SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE);
+ if (prot != IPPROTO_SCTP) {
+ /* Turn on cookie exchange. Not necessary for SCTP */
+ SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE);
+ }
} else
#endif
sbio = BIO_new_socket(s, BIO_NOCLOSE);
+ if (sbio == NULL) {
+ BIO_printf(bio_err, "Unable to create BIO\n");
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+
if (s_nbio_test) {
BIO *test;
ssl_print_point_formats(bio_s_out, con);
ssl_print_groups(bio_s_out, con, 0);
#endif
+ print_ca_names(bio_s_out, con);
BIO_printf(bio_s_out, "CIPHER is %s\n", (str != NULL) ? str : "(NONE)");
#if !defined(OPENSSL_NO_NEXTPROTONEG)
}
#endif
-static int www_body(int s, int stype, unsigned char *context)
+static int www_body(int s, int stype, int prot, unsigned char *context)
{
char *buf = NULL;
int ret = 1;
#ifndef OPENSSL_NO_EC
ssl_print_groups(io, con, 0);
#endif
+ print_ca_names(io, con);
BIO_printf(io, (SSL_session_reused(con)
? "---\nReused, " : "---\nNew, "));
c = SSL_get_current_cipher(con);
return (ret);
}
-static int rev_body(int s, int stype, unsigned char *context)
+static int rev_body(int s, int stype, int prot, unsigned char *context)
{
char *buf = NULL;
int i;