X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=apps%2Fs_server.c;h=9b5106d02fd5986d5942734e3557997fd9b25928;hp=86fed6f5939191069c36f1052bf5870edc69bcdf;hb=1fb6b0bf3e895c6b30f9c95a23284f93e4fa19b0;hpb=f479eab2271c06d73d2e473ce47b0fc6ab742cef diff --git a/apps/s_server.c b/apps/s_server.c index 86fed6f593..9b5106d02f 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -1,5 +1,5 @@ /* - * 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. * @@ -37,6 +37,7 @@ typedef unsigned int u_int; #include #include "apps.h" +#include "progs.h" #include #include #include @@ -114,6 +115,7 @@ static long socket_mtu; * code. */ static int dtlslisten = 0; +static int stateless = 0; static int early_data = 0; static SSL_SESSION *psksess = NULL; @@ -206,14 +208,10 @@ static int psk_find_session_cb(SSL *ssl, const unsigned char *identity, 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; } @@ -238,6 +236,7 @@ typedef struct srpsrvparm_st { SRP_VBASE *vb; SRP_user_pwd *user; } srpsrvparm; +static srpsrvparm srp_callback_parm; /* * This callback pretends to require some asynchronous logic in order to @@ -724,13 +723,6 @@ static int not_resumable_sess_cb(SSL *s, int is_forward_secure) 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, @@ -751,7 +743,7 @@ typedef enum OPTION_choice { 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, @@ -933,6 +925,7 @@ const OPTIONS s_server_options[] = { {"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 @@ -1025,6 +1018,7 @@ int s_server_main(int argc, char *argv[]) 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 */ @@ -1496,6 +1490,9 @@ int s_server_main(int argc, char *argv[]) dtlslisten = 1; #endif break; + case OPT_STATELESS: + stateless = 1; + break; case OPT_ID_PREFIX: session_id_prefix = opt_arg(); break; @@ -1527,9 +1524,7 @@ int s_server_main(int argc, char *argv[]) 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(); @@ -1564,6 +1559,8 @@ int s_server_main(int argc, char *argv[]) break; case OPT_EARLY_DATA: early_data = 1; + if (max_early_data == -1) + max_early_data = SSL3_RT_MAX_PLAIN_LENGTH; break; } } @@ -1588,6 +1585,11 @@ int s_server_main(int argc, char *argv[]) } #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, @@ -1746,6 +1748,10 @@ int s_server_main(int argc, char *argv[]) } 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", @@ -1754,9 +1760,11 @@ int s_server_main(int argc, char *argv[]) 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) { @@ -1832,8 +1840,6 @@ int s_server_main(int argc, char *argv[]) } 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)) { @@ -2019,7 +2025,7 @@ int s_server_main(int argc, char *argv[]) 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; @@ -2029,11 +2035,15 @@ int s_server_main(int argc, char *argv[]) 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; @@ -2340,10 +2350,14 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) (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); } @@ -2465,9 +2479,6 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) 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, @@ -2478,10 +2489,6 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) 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'))) { @@ -2492,10 +2499,19 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) 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"; @@ -2687,81 +2703,87 @@ static int init_ssl_connection(SSL *con) 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; } @@ -2808,7 +2830,7 @@ static void print_connection_info(SSL *con) 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);