/*
- * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
* Copyright 2005 Nokia. All rights reserved.
*
#include <openssl/bn.h>
#include "apps.h"
+#include "progs.h"
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
* code.
*/
static int dtlslisten = 0;
+static int stateless = 0;
static int early_data = 0;
static SSL_SESSION *psksess = NULL;
return 0;
}
- if (key_len == EVP_MD_size(EVP_sha256()))
- cipher = SSL_CIPHER_find(ssl, tls13_aes128gcmsha256_id);
- else if(key_len == EVP_MD_size(EVP_sha384()))
- cipher = SSL_CIPHER_find(ssl, tls13_aes256gcmsha384_id);
-
+ /* We default to SHA256 */
+ cipher = SSL_CIPHER_find(ssl, tls13_aes128gcmsha256_id);
if (cipher == NULL) {
- /* Doesn't look like a suitable TLSv1.3 key. Ignore it */
- OPENSSL_free(key);
+ BIO_printf(bio_err, "Error finding suitable ciphersuite\n");
return 0;
}
SRP_VBASE *vb;
SRP_user_pwd *user;
} srpsrvparm;
+static srpsrvparm srp_callback_parm;
/*
* This callback pretends to require some asynchronous logic in order to
return is_forward_secure;
}
-#ifndef OPENSSL_NO_SRP
-static srpsrvparm srp_callback_parm;
-#endif
-#ifndef OPENSSL_NO_SRTP
-static char *srtp_profiles = NULL;
-#endif
-
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ENGINE,
OPT_4, OPT_6, OPT_ACCEPT, OPT_PORT, OPT_UNIX, OPT_UNLINK, OPT_NACCEPT,
OPT_UPPER_WWW, OPT_HTTP, OPT_ASYNC, OPT_SSL_CONFIG,
OPT_MAX_SEND_FRAG, 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_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_LISTEN,
+ OPT_DTLS1_2, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_LISTEN, OPT_STATELESS,
OPT_ID_PREFIX, OPT_SERVERNAME, OPT_SERVERNAME_FATAL,
OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN,
OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN,
{"listen", OPT_LISTEN, '-',
"Listen for a DTLS ClientHello with a cookie and then connect"},
#endif
+ {"stateless", OPT_STATELESS, '-', "Require TLSv1.3 cookies"},
#ifndef OPENSSL_NO_DTLS1
{"dtls1", OPT_DTLS1, '-', "Just talk DTLSv1"},
#endif
char *srpuserseed = NULL;
char *srp_verifier_file = NULL;
#endif
+ char *srtp_profiles = NULL;
int min_version = 0, max_version = 0, prot_opt = 0, no_prot_opt = 0;
int s_server_verify = SSL_VERIFY_NONE;
int s_server_session_id_context = 1; /* anything will do */
dtlslisten = 1;
#endif
break;
+ case OPT_STATELESS:
+ stateless = 1;
+ break;
case OPT_ID_PREFIX:
session_id_prefix = opt_arg();
break;
alpn_in = opt_arg();
break;
case OPT_SRTP_PROFILES:
-#ifndef OPENSSL_NO_SRTP
srtp_profiles = opt_arg();
-#endif
break;
case OPT_KEYMATEXPORT:
keymatexportlabel = opt_arg();
break;
case OPT_EARLY_DATA:
early_data = 1;
+ if (max_early_data == -1)
+ max_early_data = SSL3_RT_MAX_PLAIN_LENGTH;
break;
}
}
}
#endif
+ if (stateless && socket_type != SOCK_STREAM) {
+ BIO_printf(bio_err, "Can only use --stateless with TLS\n");
+ goto end;
+ }
+
#ifdef AF_UNIX
if (socket_family == AF_UNIX && socket_type != SOCK_STREAM) {
BIO_printf(bio_err,
}
if (sdebug)
ssl_ctx_security_debug(ctx, sdebug);
+
+ if (!config_ctx(cctx, ssl_args, ctx))
+ goto end;
+
if (ssl_config) {
if (SSL_CTX_config(ctx, ssl_config) == 0) {
BIO_printf(bio_err, "Error using configuration \"%s\"\n",
goto end;
}
}
- if (SSL_CTX_set_min_proto_version(ctx, min_version) == 0)
+ if (min_version != 0
+ && SSL_CTX_set_min_proto_version(ctx, min_version) == 0)
goto end;
- if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0)
+ if (max_version != 0
+ && SSL_CTX_set_max_proto_version(ctx, max_version) == 0)
goto end;
if (session_id_prefix) {
}
ssl_ctx_add_crls(ctx, crls, 0);
- if (!config_ctx(cctx, ssl_args, ctx))
- goto end;
if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile,
crls, crl_download)) {
SSL_CTX_set_verify(ctx, s_server_verify, verify_callback);
if (!SSL_CTX_set_session_id_context(ctx,
(void *)&s_server_session_id_context,
- sizeof s_server_session_id_context)) {
+ sizeof(s_server_session_id_context))) {
BIO_printf(bio_err, "error setting session id context\n");
ERR_print_errors(bio_err);
goto end;
SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie_callback);
SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie_callback);
+ /* Set TLS1.3 cookie generation and verification callbacks */
+ SSL_CTX_set_stateless_cookie_generate_cb(ctx, generate_stateless_cookie_callback);
+ SSL_CTX_set_stateless_cookie_verify_cb(ctx, verify_stateless_cookie_callback);
+
if (ctx2 != NULL) {
SSL_CTX_set_verify(ctx2, s_server_verify, verify_callback);
if (!SSL_CTX_set_session_id_context(ctx2,
(void *)&s_server_session_id_context,
- sizeof s_server_session_id_context)) {
+ sizeof(s_server_session_id_context))) {
BIO_printf(bio_err, "error setting session id context\n");
ERR_print_errors(bio_err);
goto end;
(void)BIO_flush(bio_s_out);
}
}
- if (write_header)
- BIO_printf(bio_s_out, "No early data received\n");
- else
+ if (write_header) {
+ if (SSL_get_early_data_status(con) == SSL_EARLY_DATA_NOT_SENT)
+ BIO_printf(bio_s_out, "No early data received\n");
+ else
+ BIO_printf(bio_s_out, "Early data was rejected\n");
+ } else {
BIO_printf(bio_s_out, "\nEnd of early data\n");
+ }
if (SSL_is_init_finished(con))
print_connection_info(con);
}
printf("SSL_do_handshake -> %d\n", i);
i = 0; /* 13; */
continue;
- /*
- * strcpy(buf,"server side RE-NEGOTIATE\n");
- */
}
if ((buf[0] == 'R') && ((buf[1] == '\n') || (buf[1] == '\r'))) {
SSL_set_verify(con,
printf("SSL_do_handshake -> %d\n", i);
i = 0; /* 13; */
continue;
- /*
- * strcpy(buf,"server side RE-NEGOTIATE asking for client
- * cert\n");
- */
}
if ((buf[0] == 'K' || buf[0] == 'k')
&& ((buf[1] == '\n') || (buf[1] == '\r'))) {
printf("SSL_do_handshake -> %d\n", i);
i = 0;
continue;
- /*
- * strcpy(buf,"server side RE-NEGOTIATE asking for client
- * cert\n");
- */
+ }
+ if (buf[0] == 'c' && ((buf[1] == '\n') || (buf[1] == '\r'))) {
+ SSL_set_verify(con, SSL_VERIFY_PEER, NULL);
+ i = SSL_verify_client_post_handshake(con);
+ if (i == 0) {
+ printf("Failed to initiate request\n");
+ ERR_print_errors(bio_err);
+ } else {
+ i = SSL_do_handshake(con);
+ printf("SSL_do_handshake -> %d\n", i);
+ i = 0;
+ }
+ continue;
}
if (buf[0] == 'P') {
static const char *str = "Lets print some clear text\n";
long verify_err;
int retry = 0;
-#ifndef OPENSSL_NO_DTLS
- if (dtlslisten) {
+ if (dtlslisten || stateless) {
BIO_ADDR *client = NULL;
- if ((client = BIO_ADDR_new()) == NULL) {
- BIO_printf(bio_err, "ERROR - memory\n");
- return 0;
+ if (dtlslisten) {
+ if ((client = BIO_ADDR_new()) == NULL) {
+ BIO_printf(bio_err, "ERROR - memory\n");
+ return 0;
+ }
+ i = DTLSv1_listen(con, client);
+ } else {
+ i = SSL_stateless(con);
}
- i = DTLSv1_listen(con, client);
if (i > 0) {
BIO *wbio;
int fd = -1;
- wbio = SSL_get_wbio(con);
- if (wbio) {
- BIO_get_fd(wbio, &fd);
- }
+ if (dtlslisten) {
+ wbio = SSL_get_wbio(con);
+ if (wbio) {
+ BIO_get_fd(wbio, &fd);
+ }
- if (!wbio || BIO_connect(fd, client, 0) == 0) {
- BIO_printf(bio_err, "ERROR - unable to connect\n");
+ if (!wbio || BIO_connect(fd, client, 0) == 0) {
+ BIO_printf(bio_err, "ERROR - unable to connect\n");
+ BIO_ADDR_free(client);
+ return 0;
+ }
BIO_ADDR_free(client);
- return 0;
+ dtlslisten = 0;
+ } else {
+ stateless = 0;
}
- BIO_ADDR_free(client);
- dtlslisten = 0;
i = SSL_accept(con);
} else {
BIO_ADDR_free(client);
}
- } else
-#endif
-
- do {
- i = SSL_accept(con);
+ } else {
+ do {
+ i = SSL_accept(con);
- if (i <= 0)
- retry = is_retryable(con, i);
+ if (i <= 0)
+ retry = is_retryable(con, i);
#ifdef CERT_CB_TEST_RETRY
- {
+ {
+ while (i <= 0
+ && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP
+ && SSL_get_state(con) == TLS_ST_SR_CLNT_HELLO) {
+ BIO_printf(bio_err,
+ "LOOKUP from certificate callback during accept\n");
+ i = SSL_accept(con);
+ if (i <= 0)
+ retry = is_retryable(con, i);
+ }
+ }
+#endif
+
+#ifndef OPENSSL_NO_SRP
while (i <= 0
- && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP
- && SSL_get_state(con) == TLS_ST_SR_CLNT_HELLO) {
- BIO_printf(bio_err,
- "LOOKUP from certificate callback during accept\n");
+ && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) {
+ BIO_printf(bio_s_out, "LOOKUP during accept %s\n",
+ srp_callback_parm.login);
+ SRP_user_pwd_free(srp_callback_parm.user);
+ srp_callback_parm.user =
+ SRP_VBASE_get1_by_user(srp_callback_parm.vb,
+ srp_callback_parm.login);
+ if (srp_callback_parm.user)
+ BIO_printf(bio_s_out, "LOOKUP done %s\n",
+ srp_callback_parm.user->info);
+ else
+ BIO_printf(bio_s_out, "LOOKUP not successful\n");
i = SSL_accept(con);
if (i <= 0)
retry = is_retryable(con, i);
}
- }
-#endif
-
-#ifndef OPENSSL_NO_SRP
- while (i <= 0
- && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) {
- BIO_printf(bio_s_out, "LOOKUP during accept %s\n",
- srp_callback_parm.login);
- SRP_user_pwd_free(srp_callback_parm.user);
- srp_callback_parm.user =
- SRP_VBASE_get1_by_user(srp_callback_parm.vb,
- srp_callback_parm.login);
- if (srp_callback_parm.user)
- BIO_printf(bio_s_out, "LOOKUP done %s\n",
- srp_callback_parm.user->info);
- else
- BIO_printf(bio_s_out, "LOOKUP not successful\n");
- i = SSL_accept(con);
- if (i <= 0)
- retry = is_retryable(con, i);
- }
#endif
- } while (i < 0 && SSL_waiting_for_async(con));
+ } while (i < 0 && SSL_waiting_for_async(con));
+ }
if (i <= 0) {
- if ((dtlslisten && i == 0)
- || (!dtlslisten && retry)) {
+ if (((dtlslisten || stateless) && i == 0)
+ || (!dtlslisten && !stateless && retry)) {
BIO_printf(bio_s_out, "DELAY\n");
return 1;
}
peer = NULL;
}
- if (SSL_get_shared_ciphers(con, buf, sizeof buf) != NULL)
+ if (SSL_get_shared_ciphers(con, buf, sizeof(buf)) != NULL)
BIO_printf(bio_s_out, "Shared ciphers:%s\n", buf);
str = SSL_CIPHER_get_name(SSL_get_current_cipher(con));
ssl_print_sigalgs(bio_s_out, con);