X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;f=apps%2Fs_server.c;h=ef39a4f538cb14de1149444e9ea78dc96999419c;hb=ff25dd1a47525c88500dd61cdeb27faaea6ee599;hp=20d2497e7ba9d431249a3b52268de0b9ab2ab423;hpb=df894947c4f04dedb0bded25195bc2fc7b2b6915;p=openssl.git diff --git a/apps/s_server.c b/apps/s_server.c index 20d2497e7b..ef39a4f538 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. * @@ -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); @@ -67,7 +67,7 @@ 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); -static int generate_session_id(const SSL *ssl, unsigned char *id, +static int generate_session_id(SSL *ssl, unsigned char *id, unsigned int *id_len); static void init_session_cache_ctx(SSL_CTX *sctx); static void free_sessions(void); @@ -115,14 +115,15 @@ static long socket_mtu; * code. */ static int dtlslisten = 0; +static int stateless = 0; static int early_data = 0; static SSL_SESSION *psksess = NULL; -#ifndef OPENSSL_NO_PSK static char *psk_identity = "Client_identity"; char *psk_key = NULL; /* by default PSK is not used */ +#ifndef OPENSSL_NO_PSK static unsigned int psk_server_cb(SSL *ssl, const char *identity, unsigned char *psk, unsigned int max_psk_len) @@ -179,15 +180,51 @@ static unsigned int psk_server_cb(SSL *ssl, const char *identity, } #endif +#define TLS13_AES_128_GCM_SHA256_BYTES ((const unsigned char *)"\x13\x01") +#define TLS13_AES_256_GCM_SHA384_BYTES ((const unsigned char *)"\x13\x02") + static int psk_find_session_cb(SSL *ssl, const unsigned char *identity, size_t identity_len, SSL_SESSION **sess) { + SSL_SESSION *tmpsess = NULL; + unsigned char *key; + long key_len; + const SSL_CIPHER *cipher = NULL; + if (strlen(psk_identity) != identity_len || memcmp(psk_identity, identity, identity_len) != 0) return 0; - SSL_SESSION_up_ref(psksess); - *sess = psksess; + if (psksess != NULL) { + SSL_SESSION_up_ref(psksess); + *sess = psksess; + return 1; + } + + key = OPENSSL_hexstr2buf(psk_key, &key_len); + if (key == NULL) { + BIO_printf(bio_err, "Could not convert PSK key '%s' to buffer\n", + psk_key); + return 0; + } + + /* We default to SHA256 */ + cipher = SSL_CIPHER_find(ssl, tls13_aes128gcmsha256_id); + if (cipher == NULL) { + BIO_printf(bio_err, "Error finding suitable ciphersuite\n"); + return 0; + } + + tmpsess = SSL_SESSION_new(); + if (tmpsess == NULL + || !SSL_SESSION_set1_master_key(tmpsess, key, key_len) + || !SSL_SESSION_set_cipher(tmpsess, cipher) + || !SSL_SESSION_set_protocol_version(tmpsess, SSL_version(ssl))) { + OPENSSL_free(key); + return 0; + } + OPENSSL_free(key); + *sess = tmpsess; return 1; } @@ -199,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 @@ -216,7 +254,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) { @@ -316,9 +354,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) @@ -334,7 +372,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; @@ -357,7 +395,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) @@ -366,7 +404,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; @@ -375,7 +413,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) @@ -419,9 +457,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; @@ -677,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, @@ -704,11 +743,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_ID_PREFIX, OPT_RAND, OPT_SERVERNAME, OPT_SERVERNAME_FATAL, + 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_R_ENUM, OPT_S_ENUM, OPT_V_ENUM, OPT_X_ENUM @@ -739,13 +779,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, '<', @@ -785,8 +826,7 @@ const OPTIONS s_server_options[] = { {"HTTP", OPT_HTTP, '-', "Like -WWW but ./path includes HTTP headers"}, {"id_prefix", OPT_ID_PREFIX, 's', "Generate SSL/TLS session IDs prefixed by arg"}, - {"rand", OPT_RAND, 's', - "Load the file(s) into the random number generator"}, + OPT_R_OPTIONS, {"keymatexport", OPT_KEYMATEXPORT, 's', "Export keying material using label"}, {"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p', @@ -852,11 +892,11 @@ const OPTIONS s_server_options[] = { OPT_V_OPTIONS, OPT_X_OPTIONS, {"nbio", OPT_NBIO, '-', "Use non-blocking IO"}, -#ifndef OPENSSL_NO_PSK {"psk_identity", OPT_PSK_IDENTITY, 's', "PSK identity to expect"}, +#ifndef OPENSSL_NO_PSK {"psk_hint", OPT_PSK_HINT, 's', "PSK identity hint to use"}, - {"psk", OPT_PSK, 's', "PSK in hex (without 0x)"}, #endif + {"psk", OPT_PSK, 's', "PSK in hex (without 0x)"}, {"psk_session", OPT_PSK_SESS, '<', "File to read PSK SSL session from"}, #ifndef OPENSSL_NO_SRP {"srpvfile", OPT_SRPVFILE, '<', "The verifier file for SRP"}, @@ -885,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 @@ -934,7 +975,7 @@ int s_server_main(int argc, char *argv[]) X509 *s_cert = NULL, *s_dcert = NULL; X509_VERIFY_PARAM *vpm = NULL; const char *CApath = NULL, *CAfile = NULL, *chCApath = NULL, *chCAfile = NULL; - char *dpassarg = NULL, *dpass = NULL, *inrand = NULL; + char *dpassarg = NULL, *dpass = NULL; char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL; char *crl_file = NULL, *prog; #ifdef AF_UNIX @@ -971,12 +1012,13 @@ int s_server_main(int argc, char *argv[]) #ifndef OPENSSL_NO_PSK /* by default do not send a PSK identity hint */ char *psk_identity_hint = NULL; - char *p; #endif + char *p; #ifndef OPENSSL_NO_SRP 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 */ @@ -1339,9 +1381,7 @@ int s_server_main(int argc, char *argv[]) no_resume_ephemeral = 1; break; case OPT_PSK_IDENTITY: -#ifndef OPENSSL_NO_PSK psk_identity = opt_arg(); -#endif break; case OPT_PSK_HINT: #ifndef OPENSSL_NO_PSK @@ -1349,14 +1389,12 @@ int s_server_main(int argc, char *argv[]) #endif break; case OPT_PSK: -#ifndef OPENSSL_NO_PSK for (p = psk_key = opt_arg(); *p; p++) { if (isxdigit(_UC(*p))) continue; BIO_printf(bio_err, "Not a hex number '%s'\n", *argv); goto end; } -#endif break; case OPT_PSK_SESS: psksessf = opt_arg(); @@ -1452,14 +1490,18 @@ 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; case OPT_ENGINE: engine = setup_engine(opt_arg(), 1); break; - case OPT_RAND: - inrand = opt_arg(); + case OPT_R_CASES: + if (!opt_rand(o)) + goto end; break; case OPT_SERVERNAME: tlsextcbp.servername = opt_arg(); @@ -1482,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(); @@ -1519,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; } } @@ -1543,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, @@ -1672,15 +1719,6 @@ int s_server_main(int argc, char *argv[]) } - if (!app_RAND_load_file(NULL, 1) && inrand == NULL - && !RAND_status()) { - BIO_printf(bio_err, - "warning, not much extra random data, consider using the -rand option\n"); - } - if (inrand != NULL) - BIO_printf(bio_err, "%ld semi-random bytes loaded\n", - app_RAND_load_files(inrand)); - if (bio_s_out == NULL) { if (s_quiet && !s_debug) { bio_s_out = BIO_new(BIO_s_null()); @@ -1710,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", @@ -1718,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) { @@ -1796,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)) { @@ -1974,13 +2016,16 @@ int s_server_main(int argc, char *argv[]) ERR_print_errors(bio_err); goto end; } - SSL_CTX_set_psk_find_session_callback(ctx, psk_find_session_cb); + } + if (psk_key != NULL || psksess != NULL) + SSL_CTX_set_psk_find_session_callback(ctx, psk_find_session_cb); + 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; @@ -1990,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; @@ -2046,8 +2095,6 @@ int s_server_main(int argc, char *argv[]) if (max_early_data >= 0) SSL_CTX_set_max_early_data(ctx, 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) @@ -2060,11 +2107,12 @@ 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: SSL_CTX_free(ctx); + SSL_SESSION_free(psksess); set_keylog_file(NULL, NULL); X509_free(s_cert); sk_X509_CRL_pop_free(crls, X509_CRL_free); @@ -2100,7 +2148,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) @@ -2141,9 +2189,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 @@ -2162,22 +2208,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; @@ -2222,11 +2271,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); @@ -2298,10 +2346,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); } @@ -2338,9 +2390,9 @@ 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)) @@ -2423,9 +2475,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, @@ -2436,10 +2485,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'))) { @@ -2450,10 +2495,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"; @@ -2615,10 +2669,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) @@ -2645,83 +2696,89 @@ 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); + return 1; } BIO_printf(bio_err, "ERROR\n"); @@ -2733,7 +2790,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); @@ -2766,7 +2823,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); @@ -2836,7 +2893,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 @@ -3081,9 +3138,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)) { @@ -3219,11 +3277,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) @@ -3376,11 +3432,11 @@ 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 -static int generate_session_id(const SSL *ssl, unsigned char *id, +static int generate_session_id(SSL *ssl, unsigned char *id, unsigned int *id_len) { unsigned int count = 0;