X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=apps%2Fs_server.c;h=929a08bd85b06cc49a299cbf69b3610e3439dba3;hp=2ff58b67f9c99ebcac984b978e3ddc8e6fcf9276;hb=72a7a7021fa8bc82a11bc08bac1b0241a92143d0;hpb=ae3947de09522206d61c0206a733517b10a910f8 diff --git a/apps/s_server.c b/apps/s_server.c index 2ff58b67f9..929a08bd85 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-2019 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * Copyright 2005 Nokia. All rights reserved. * @@ -35,10 +35,9 @@ typedef unsigned int u_int; #endif -#include #include -#define USE_SOCKETS #include "apps.h" +#include "progs.h" #include #include #include @@ -59,6 +58,7 @@ typedef unsigned int u_int; #ifdef CHARSET_EBCDIC #include #endif +#include "internal/sockets.h" static int not_resumable_sess_cb(SSL *s, int is_forward_secure); static int sv_body(int s, int stype, int prot, unsigned char *context); @@ -115,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; @@ -191,8 +192,10 @@ static int psk_find_session_cb(SSL *ssl, const unsigned char *identity, const SSL_CIPHER *cipher = NULL; if (strlen(psk_identity) != identity_len - || memcmp(psk_identity, identity, identity_len) != 0) - return 0; + || memcmp(psk_identity, identity, identity_len) != 0) { + *sess = NULL; + return 1; + } if (psksess != NULL) { SSL_SESSION_up_ref(psksess); @@ -207,13 +210,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 */ + BIO_printf(bio_err, "Error finding suitable ciphersuite\n"); OPENSSL_free(key); return 0; } @@ -239,6 +239,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 @@ -256,7 +257,7 @@ static int ssl_srp_server_param_cb(SSL *s, int *ad, void *arg) if (p->login == NULL && p->user == NULL) { p->login = SSL_get_srp_username(s); BIO_printf(bio_err, "SRP username = \"%s\"\n", p->login); - return (-1); + return -1; } if (p->user == NULL) { @@ -356,9 +357,9 @@ static int ebcdic_read(BIO *b, char *out, int outl) BIO *next = BIO_next(b); if (out == NULL || outl == 0) - return (0); + return 0; if (next == NULL) - return (0); + return 0; ret = BIO_read(next, out, outl); if (ret > 0) @@ -374,7 +375,7 @@ static int ebcdic_write(BIO *b, const char *in, int inl) int num; if ((in == NULL) || (inl <= 0)) - return (0); + return 0; if (next == NULL) return 0; @@ -397,7 +398,7 @@ static int ebcdic_write(BIO *b, const char *in, int inl) ret = BIO_write(next, wbuf->buff, inl); - return (ret); + return ret; } static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr) @@ -406,7 +407,7 @@ static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr) BIO *next = BIO_next(b); if (next == NULL) - return (0); + return 0; switch (cmd) { case BIO_CTRL_DUP: ret = 0L; @@ -415,7 +416,7 @@ static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr) ret = BIO_ctrl(next, cmd, num, ptr); break; } - return (ret); + return ret; } static int ebcdic_gets(BIO *bp, char *buf, int size) @@ -459,9 +460,17 @@ static int ssl_servername_cb(SSL *s, int *ad, void *arg) { tlsextctx *p = (tlsextctx *) arg; const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name); - if (servername != NULL && p->biodebug != NULL) - BIO_printf(p->biodebug, "Hostname in TLS extension: \"%s\"\n", - servername); + + if (servername != NULL && p->biodebug != NULL) { + const char *cp = servername; + unsigned char uc; + + BIO_printf(p->biodebug, "Hostname in TLS extension: \""); + while ((uc = *cp++) != 0) + BIO_printf(p->biodebug, + isascii(uc) && isprint(uc) ? "%c" : "\\x%02x", uc); + BIO_printf(p->biodebug, "\"\n"); + } if (p->servername == NULL) return SSL_TLSEXT_ERR_NOACK; @@ -717,13 +726,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, @@ -744,11 +746,12 @@ 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, - OPT_KEYLOG_FILE, OPT_MAX_EARLY, OPT_EARLY_DATA, + OPT_KEYLOG_FILE, OPT_MAX_EARLY, OPT_RECV_MAX_EARLY, OPT_EARLY_DATA, + OPT_S_NUM_TICKETS, OPT_ANTI_REPLAY, OPT_NO_ANTI_REPLAY, OPT_SCTP_LABEL_BUG, OPT_R_ENUM, OPT_S_ENUM, OPT_V_ENUM, @@ -780,13 +783,14 @@ const OPTIONS s_server_options[] = { "PEM serverinfo file for certificate"}, {"certform", OPT_CERTFORM, 'F', "Certificate format (PEM or DER) PEM default"}, - {"key", OPT_KEY, '<', + {"key", OPT_KEY, 's', "Private Key if not in -cert; default is " TEST_CERT}, {"keyform", OPT_KEYFORM, 'f', "Key format (PEM, DER or ENGINE) PEM default"}, {"pass", OPT_PASS, 's', "Private key file pass phrase source"}, {"dcert", OPT_DCERT, '<', "Second certificate file to use (usually for DSA)"}, + {"dhparam", OPT_DHPARAM, '<', "DH parameters file to use"}, {"dcertform", OPT_DCERTFORM, 'F', "Second certificate format (PEM or DER) PEM default"}, {"dkey", OPT_DKEY, '<', @@ -925,6 +929,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 @@ -933,6 +938,7 @@ const OPTIONS s_server_options[] = { #endif #ifndef OPENSSL_NO_SCTP {"sctp", OPT_SCTP, '-', "Use SCTP"}, + {"sctp_label_bug", OPT_SCTP_LABEL_BUG, '-', "Enable SCTP label length bug"}, #endif #ifndef OPENSSL_NO_DH {"no_dhe", OPT_NO_DHE, '-', "Disable ephemeral DH"}, @@ -952,8 +958,14 @@ const OPTIONS s_server_options[] = { #endif {"keylogfile", OPT_KEYLOG_FILE, '>', "Write TLS secrets to file"}, {"max_early_data", OPT_MAX_EARLY, 'n', - "The maximum number of bytes of early data"}, + "The maximum number of bytes of early data as advertised in tickets"}, + {"recv_max_early_data", OPT_RECV_MAX_EARLY, 'n', + "The maximum number of bytes of early data (hard limit)"}, {"early_data", OPT_EARLY_DATA, '-', "Attempt to read early data"}, + {"num_tickets", OPT_S_NUM_TICKETS, 'n', + "The number of TLSv1.3 session tickets that a server will automatically issue" }, + {"anti_replay", OPT_ANTI_REPLAY, '-', "Switch on anti-replay protection (default)"}, + {"no_anti_replay", OPT_NO_ANTI_REPLAY, '-', "Switch off anti-replay protection"}, {NULL, OPT_EOF, 0, NULL} }; @@ -1016,6 +1028,9 @@ int s_server_main(int argc, char *argv[]) #ifndef OPENSSL_NO_SRP char *srpuserseed = NULL; char *srp_verifier_file = NULL; +#endif +#ifndef OPENSSL_NO_SRTP + char *srtp_profiles = NULL; #endif int min_version = 0, max_version = 0, prot_opt = 0, no_prot_opt = 0; int s_server_verify = SSL_VERIFY_NONE; @@ -1031,8 +1046,11 @@ int s_server_main(int argc, char *argv[]) unsigned int split_send_fragment = 0, max_pipelines = 0; const char *s_serverinfo_file = NULL; const char *keylog_file = NULL; - int max_early_data = -1; + int max_early_data = -1, recv_max_early_data = -1; char *psksessf = NULL; +#ifndef OPENSSL_NO_SCTP + int sctp_label_bug = 0; +#endif /* Init of few remaining global variables */ local_argc = argc; @@ -1250,6 +1268,9 @@ int s_server_main(int argc, char *argv[]) goto opthelp; break; case OPT_S_CASES: + case OPT_S_NUM_TICKETS: + case OPT_ANTI_REPLAY: + case OPT_NO_ANTI_REPLAY: if (ssl_args == NULL) ssl_args = sk_OPENSSL_STRING_new_null(); if (ssl_args == NULL @@ -1390,7 +1411,7 @@ int s_server_main(int argc, char *argv[]) for (p = psk_key = opt_arg(); *p; p++) { if (isxdigit(_UC(*p))) continue; - BIO_printf(bio_err, "Not a hex number '%s'\n", *argv); + BIO_printf(bio_err, "Not a hex number '%s'\n", psk_key); goto end; } break; @@ -1471,6 +1492,11 @@ int s_server_main(int argc, char *argv[]) case OPT_SCTP: #ifndef OPENSSL_NO_SCTP protocol = IPPROTO_SCTP; +#endif + break; + case OPT_SCTP_LABEL_BUG: +#ifndef OPENSSL_NO_SCTP + sctp_label_bug = 1; #endif break; case OPT_TIMEOUT: @@ -1488,6 +1514,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; @@ -1554,8 +1583,17 @@ int s_server_main(int argc, char *argv[]) goto end; } break; + case OPT_RECV_MAX_EARLY: + recv_max_early_data = atoi(opt_arg()); + if (recv_max_early_data < 0) { + BIO_printf(bio_err, "Invalid value for recv_max_early_data\n"); + goto end; + } + break; case OPT_EARLY_DATA: early_data = 1; + if (max_early_data == -1) + max_early_data = SSL3_RT_MAX_PLAIN_LENGTH; break; } } @@ -1580,6 +1618,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, @@ -1587,6 +1630,11 @@ int s_server_main(int argc, char *argv[]) goto end; } #endif + if (early_data && (www > 0 || rev)) { + BIO_printf(bio_err, + "Can't use -early_data in combination with -www, -WWW, -HTTP, or -rev\n"); + goto end; + } #ifndef OPENSSL_NO_SCTP if (protocol == IPPROTO_SCTP) { @@ -1736,8 +1784,15 @@ int s_server_main(int argc, char *argv[]) ERR_print_errors(bio_err); goto end; } + + SSL_CTX_clear_mode(ctx, SSL_MODE_AUTO_RETRY); + 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", @@ -1746,9 +1801,17 @@ int s_server_main(int argc, char *argv[]) goto end; } } - if (SSL_CTX_set_min_proto_version(ctx, min_version) == 0) + +#ifndef OPENSSL_NO_SCTP + if (protocol == IPPROTO_SCTP && sctp_label_bug == 1) + SSL_CTX_set_mode(ctx, SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG); +#endif + + 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) { @@ -1824,8 +1887,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)) { @@ -2011,7 +2072,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; @@ -2021,11 +2082,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; @@ -2076,9 +2141,9 @@ int s_server_main(int argc, char *argv[]) if (max_early_data >= 0) SSL_CTX_set_max_early_data(ctx, max_early_data); + if (recv_max_early_data >= 0) + SSL_CTX_set_recv_max_early_data(ctx, recv_max_early_data); - BIO_printf(bio_s_out, "ACCEPT\n"); - (void)BIO_flush(bio_s_out); if (rev) server_cb = rev_body; else if (www) @@ -2091,7 +2156,7 @@ int s_server_main(int argc, char *argv[]) unlink(host); #endif do_server(&accept_socket, host, port, socket_family, socket_type, protocol, - server_cb, context, naccept); + server_cb, context, naccept, bio_s_out); print_stats(bio_s_out, ctx); ret = 0; end: @@ -2132,7 +2197,7 @@ int s_server_main(int argc, char *argv[]) #ifdef CHARSET_EBCDIC BIO_meth_free(methods_ebcdic); #endif - return (ret); + return ret; } static void print_stats(BIO *bio, SSL_CTX *ssl_ctx) @@ -2173,9 +2238,7 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) SSL *con = NULL; BIO *sbio; struct timeval timeout; -#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) - struct timeval tv; -#else +#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)) struct timeval *timeoutp; #endif #ifndef OPENSSL_NO_DTLS @@ -2194,22 +2257,25 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) BIO_printf(bio_err, "Turned on non blocking io\n"); } + con = SSL_new(ctx); if (con == NULL) { - con = SSL_new(ctx); + ret = -1; + goto err; + } - if (s_tlsextdebug) { - SSL_set_tlsext_debug_callback(con, tlsext_cb); - SSL_set_tlsext_debug_arg(con, bio_s_out); - } + if (s_tlsextdebug) { + SSL_set_tlsext_debug_callback(con, tlsext_cb); + SSL_set_tlsext_debug_arg(con, bio_s_out); + } - if (context - && !SSL_set_session_id_context(con, - context, strlen((char *)context))) { - BIO_printf(bio_err, "Error setting session id context\n"); - ret = -1; - goto err; - } + if (context != NULL + && !SSL_set_session_id_context(con, context, + strlen((char *)context))) { + BIO_printf(bio_err, "Error setting session id context\n"); + ret = -1; + goto err; } + if (!SSL_clear(con)) { BIO_printf(bio_err, "Error clearing SSL connection\n"); ret = -1; @@ -2254,11 +2320,10 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); # ifndef OPENSSL_NO_SCTP - if (prot != IPPROTO_SCTP) { + if (prot != IPPROTO_SCTP) +# endif /* Turn on cookie exchange. Not necessary for SCTP */ SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE); - } -# endif } else #endif sbio = BIO_new_socket(s, BIO_NOCLOSE); @@ -2330,10 +2395,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); } @@ -2370,26 +2439,23 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) * second and check for any keypress. In a proper Windows * application we wouldn't do this because it is inefficient. */ - tv.tv_sec = 1; - tv.tv_usec = 0; - i = select(width, (void *)&readfds, NULL, NULL, &tv); + timeout.tv_sec = 1; + timeout.tv_usec = 0; + i = select(width, (void *)&readfds, NULL, NULL, &timeout); if (has_stdin_waiting()) read_from_terminal = 1; if ((i < 0) || (!i && !read_from_terminal)) continue; #else - if ((SSL_version(con) == DTLS1_VERSION) && - DTLSv1_get_timeout(con, &timeout)) + if (SSL_is_dtls(con) && DTLSv1_get_timeout(con, &timeout)) timeoutp = &timeout; else timeoutp = NULL; i = select(width, (void *)&readfds, NULL, NULL, timeoutp); - if ((SSL_version(con) == DTLS1_VERSION) - && DTLSv1_handle_timeout(con) > 0) { + if ((SSL_is_dtls(con)) && DTLSv1_handle_timeout(con) > 0) BIO_printf(bio_err, "TIMEOUT occurred\n"); - } if (i <= 0) continue; @@ -2455,9 +2521,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, @@ -2468,10 +2531,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'))) { @@ -2482,10 +2541,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"; @@ -2647,10 +2715,7 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) } BIO_printf(bio_s_out, "CONNECTION CLOSED\n"); OPENSSL_clear_free(buf, bufsize); - if (ret >= 0) - BIO_printf(bio_s_out, "ACCEPT\n"); - (void)BIO_flush(bio_s_out); - return (ret); + return ret; } static void close_accept_socket(void) @@ -2677,83 +2742,91 @@ 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; + } + + (void)BIO_ctrl_set_connected(wbio, client); 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); + return 1; } BIO_printf(bio_err, "ERROR\n"); @@ -2765,7 +2838,7 @@ static int init_ssl_connection(SSL *con) } /* Always print any error messages */ ERR_print_errors(bio_err); - return (0); + return 0; } print_connection_info(con); @@ -2798,7 +2871,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); @@ -2868,7 +2941,7 @@ static DH *load_dh_param(const char *dhfile) ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); err: BIO_free(bio); - return (ret); + return ret; } #endif @@ -2916,8 +2989,10 @@ static int www_body(int s, int stype, int prot, unsigned char *context) if (context != NULL && !SSL_set_session_id_context(con, context, - strlen((char *)context))) + strlen((char *)context))) { + SSL_free(con); goto err; + } sbio = BIO_new_socket(s, BIO_NOCLOSE); if (s_nbio_test) { @@ -2929,7 +3004,7 @@ static int www_body(int s, int stype, int prot, unsigned char *context) SSL_set_bio(con, sbio, sbio); SSL_set_accept_state(con); - /* SSL_set_fd(con,s); */ + /* No need to free |con| after this. Done by BIO_free(ssl_bio) */ BIO_set_ssl(ssl_bio, con, BIO_CLOSE); BIO_push(io, ssl_bio); #ifdef CHARSET_EBCDIC @@ -3113,9 +3188,10 @@ static int www_body(int s, int stype, int prot, unsigned char *context) PEM_write_bio_X509(io, peer); X509_free(peer); peer = NULL; - } else + } else { BIO_puts(io, "no client certificate available\n"); - BIO_puts(io, "\r\n\r\n"); + } + BIO_puts(io, "\r\n\r\n"); break; } else if ((www == 2 || www == 3) && (strncmp("GET /", buf, 5) == 0)) { @@ -3251,11 +3327,9 @@ static int www_body(int s, int stype, int prot, unsigned char *context) SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); err: - if (ret >= 0) - BIO_printf(bio_s_out, "ACCEPT\n"); OPENSSL_free(buf); BIO_free_all(io); - return (ret); + return ret; } static int rev_body(int s, int stype, int prot, unsigned char *context) @@ -3286,6 +3360,7 @@ static int rev_body(int s, int stype, int prot, unsigned char *context) if (context != NULL && !SSL_set_session_id_context(con, context, strlen((char *)context))) { + SSL_free(con); ERR_print_errors(bio_err); goto err; } @@ -3294,6 +3369,7 @@ static int rev_body(int s, int stype, int prot, unsigned char *context) SSL_set_bio(con, sbio, sbio); SSL_set_accept_state(con); + /* No need to free |con| after this. Done by BIO_free(ssl_bio) */ BIO_set_ssl(ssl_bio, con, BIO_CLOSE); BIO_push(io, ssl_bio); #ifdef CHARSET_EBCDIC @@ -3408,7 +3484,7 @@ static int rev_body(int s, int stype, int prot, unsigned char *context) OPENSSL_free(buf); BIO_free_all(io); - return (ret); + return ret; } #define MAX_SESSION_ID_ATTEMPTS 10