1e71b7053SJung-uk Kim /* 2*11c7efe3SJung-uk Kim * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. 3e71b7053SJung-uk Kim * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved 41f13597dSJung-uk Kim * Copyright 2005 Nokia. All rights reserved. 51f13597dSJung-uk Kim * 6e71b7053SJung-uk Kim * Licensed under the OpenSSL license (the "License"). You may not use 7e71b7053SJung-uk Kim * this file except in compliance with the License. You can obtain a copy 8e71b7053SJung-uk Kim * in the file LICENSE in the source distribution or at 9e71b7053SJung-uk Kim * https://www.openssl.org/source/license.html 101f13597dSJung-uk Kim */ 113b4e3dcbSSimon L. B. Nielsen 121f13597dSJung-uk Kim #include <ctype.h> 1374664626SKris Kennaway #include <stdio.h> 1474664626SKris Kennaway #include <stdlib.h> 1574664626SKris Kennaway #include <string.h> 16e71b7053SJung-uk Kim #if defined(_WIN32) 17e71b7053SJung-uk Kim /* Included before async.h to avoid some warnings */ 18e71b7053SJung-uk Kim # include <windows.h> 19e71b7053SJung-uk Kim #endif 203b4e3dcbSSimon L. B. Nielsen 215c87c606SMark Murray #include <openssl/e_os2.h> 22e71b7053SJung-uk Kim #include <openssl/async.h> 23e71b7053SJung-uk Kim #include <openssl/ssl.h> 2474664626SKris Kennaway 25e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SOCK 263b4e3dcbSSimon L. B. Nielsen 276f9291ceSJung-uk Kim /* 286f9291ceSJung-uk Kim * With IPv6, it looks like Digital has mixed up the proper order of 296f9291ceSJung-uk Kim * recursive header file inclusion, resulting in the compiler complaining 306f9291ceSJung-uk Kim * that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which is 316f9291ceSJung-uk Kim * needed to have fileno() declared correctly... So let's define u_int 326f9291ceSJung-uk Kim */ 335c87c606SMark Murray #if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT) 3474664626SKris Kennaway # define __U_INT 3574664626SKris Kennaway typedef unsigned int u_int; 3674664626SKris Kennaway #endif 3774664626SKris Kennaway 3874664626SKris Kennaway #include <openssl/bn.h> 3974664626SKris Kennaway #include "apps.h" 40e71b7053SJung-uk Kim #include "progs.h" 4174664626SKris Kennaway #include <openssl/err.h> 4274664626SKris Kennaway #include <openssl/pem.h> 4374664626SKris Kennaway #include <openssl/x509.h> 4474664626SKris Kennaway #include <openssl/ssl.h> 455740a5e3SKris Kennaway #include <openssl/rand.h> 46db522d3aSSimon L. B. Nielsen #include <openssl/ocsp.h> 473b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_DH 483b4e3dcbSSimon L. B. Nielsen # include <openssl/dh.h> 493b4e3dcbSSimon L. B. Nielsen #endif 503b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_RSA 513b4e3dcbSSimon L. B. Nielsen # include <openssl/rsa.h> 523b4e3dcbSSimon L. B. Nielsen #endif 531f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP 541f13597dSJung-uk Kim # include <openssl/srp.h> 551f13597dSJung-uk Kim #endif 5674664626SKris Kennaway #include "s_apps.h" 573b4e3dcbSSimon L. B. Nielsen #include "timeouts.h" 58e71b7053SJung-uk Kim #ifdef CHARSET_EBCDIC 59e71b7053SJung-uk Kim #include <openssl/ebcdic.h> 6074664626SKris Kennaway #endif 61e71b7053SJung-uk Kim #include "internal/sockets.h" 6274664626SKris Kennaway 63e71b7053SJung-uk Kim static int not_resumable_sess_cb(SSL *s, int is_forward_secure); 64e71b7053SJung-uk Kim static int sv_body(int s, int stype, int prot, unsigned char *context); 65e71b7053SJung-uk Kim static int www_body(int s, int stype, int prot, unsigned char *context); 66e71b7053SJung-uk Kim static int rev_body(int s, int stype, int prot, unsigned char *context); 6774664626SKris Kennaway static void close_accept_socket(void); 6874664626SKris Kennaway static int init_ssl_connection(SSL *s); 6974664626SKris Kennaway static void print_stats(BIO *bp, SSL_CTX *ctx); 70e71b7053SJung-uk Kim static int generate_session_id(SSL *ssl, unsigned char *id, 715c87c606SMark Murray unsigned int *id_len); 727bded2dbSJung-uk Kim static void init_session_cache_ctx(SSL_CTX *sctx); 737bded2dbSJung-uk Kim static void free_sessions(void); 745c87c606SMark Murray #ifndef OPENSSL_NO_DH 753b4e3dcbSSimon L. B. Nielsen static DH *load_dh_param(const char *dhfile); 7674664626SKris Kennaway #endif 77e71b7053SJung-uk Kim static void print_connection_info(SSL *con); 783b4e3dcbSSimon L. B. Nielsen 79e71b7053SJung-uk Kim static const int bufsize = 16 * 1024; 8074664626SKris Kennaway static int accept_socket = -1; 8174664626SKris Kennaway 8274664626SKris Kennaway #define TEST_CERT "server.pem" 83db522d3aSSimon L. B. Nielsen #define TEST_CERT2 "server2.pem" 8474664626SKris Kennaway 8574664626SKris Kennaway static int s_nbio = 0; 8674664626SKris Kennaway static int s_nbio_test = 0; 87e71b7053SJung-uk Kim static int s_crlf = 0; 8874664626SKris Kennaway static SSL_CTX *ctx = NULL; 89db522d3aSSimon L. B. Nielsen static SSL_CTX *ctx2 = NULL; 9074664626SKris Kennaway static int www = 0; 9174664626SKris Kennaway 9274664626SKris Kennaway static BIO *bio_s_out = NULL; 937bded2dbSJung-uk Kim static BIO *bio_s_msg = NULL; 9474664626SKris Kennaway static int s_debug = 0; 95db522d3aSSimon L. B. Nielsen static int s_tlsextdebug = 0; 965c87c606SMark Murray static int s_msg = 0; 9774664626SKris Kennaway static int s_quiet = 0; 987bded2dbSJung-uk Kim static int s_ign_eof = 0; 997bded2dbSJung-uk Kim static int s_brief = 0; 10074664626SKris Kennaway 1011f13597dSJung-uk Kim static char *keymatexportlabel = NULL; 1021f13597dSJung-uk Kim static int keymatexportlen = 20; 1031f13597dSJung-uk Kim 104e71b7053SJung-uk Kim static int async = 0; 105e71b7053SJung-uk Kim 1065c87c606SMark Murray static const char *session_id_prefix = NULL; 107f579bf8eSKris Kennaway 108e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS 1093b4e3dcbSSimon L. B. Nielsen static int enable_timeouts = 0; 1106a599222SSimon L. B. Nielsen static long socket_mtu; 1116a599222SSimon L. B. Nielsen #endif 1123b4e3dcbSSimon L. B. Nielsen 113e71b7053SJung-uk Kim /* 114e71b7053SJung-uk Kim * We define this but make it always be 0 in no-dtls builds to simplify the 115e71b7053SJung-uk Kim * code. 116e71b7053SJung-uk Kim */ 117e71b7053SJung-uk Kim static int dtlslisten = 0; 118e71b7053SJung-uk Kim static int stateless = 0; 1197bded2dbSJung-uk Kim 120e71b7053SJung-uk Kim static int early_data = 0; 121e71b7053SJung-uk Kim static SSL_SESSION *psksess = NULL; 1227bded2dbSJung-uk Kim 1231f13597dSJung-uk Kim static char *psk_identity = "Client_identity"; 1241f13597dSJung-uk Kim char *psk_key = NULL; /* by default PSK is not used */ 1251f13597dSJung-uk Kim 126e71b7053SJung-uk Kim #ifndef OPENSSL_NO_PSK 1271f13597dSJung-uk Kim static unsigned int psk_server_cb(SSL *ssl, const char *identity, 1286f9291ceSJung-uk Kim unsigned char *psk, 1296f9291ceSJung-uk Kim unsigned int max_psk_len) 1301f13597dSJung-uk Kim { 131aeb5019cSJung-uk Kim long key_len = 0; 132aeb5019cSJung-uk Kim unsigned char *key; 1331f13597dSJung-uk Kim 1341f13597dSJung-uk Kim if (s_debug) 1351f13597dSJung-uk Kim BIO_printf(bio_s_out, "psk_server_cb\n"); 136e71b7053SJung-uk Kim if (identity == NULL) { 1371f13597dSJung-uk Kim BIO_printf(bio_err, "Error: client did not send PSK identity\n"); 1381f13597dSJung-uk Kim goto out_err; 1391f13597dSJung-uk Kim } 1401f13597dSJung-uk Kim if (s_debug) 1411f13597dSJung-uk Kim BIO_printf(bio_s_out, "identity_len=%d identity=%s\n", 1426f9291ceSJung-uk Kim (int)strlen(identity), identity); 1431f13597dSJung-uk Kim 1441f13597dSJung-uk Kim /* here we could lookup the given identity e.g. from a database */ 1456f9291ceSJung-uk Kim if (strcmp(identity, psk_identity) != 0) { 146e71b7053SJung-uk Kim BIO_printf(bio_s_out, "PSK warning: client identity not what we expected" 1476f9291ceSJung-uk Kim " (got '%s' expected '%s')\n", identity, psk_identity); 148e71b7053SJung-uk Kim } else { 1491f13597dSJung-uk Kim if (s_debug) 1501f13597dSJung-uk Kim BIO_printf(bio_s_out, "PSK client identity found\n"); 151e71b7053SJung-uk Kim } 1521f13597dSJung-uk Kim 1531f13597dSJung-uk Kim /* convert the PSK key to binary */ 154e71b7053SJung-uk Kim key = OPENSSL_hexstr2buf(psk_key, &key_len); 155aeb5019cSJung-uk Kim if (key == NULL) { 156aeb5019cSJung-uk Kim BIO_printf(bio_err, "Could not convert PSK key '%s' to buffer\n", 1576f9291ceSJung-uk Kim psk_key); 1581f13597dSJung-uk Kim return 0; 1591f13597dSJung-uk Kim } 160aeb5019cSJung-uk Kim if (key_len > (int)max_psk_len) { 1616f9291ceSJung-uk Kim BIO_printf(bio_err, 162aeb5019cSJung-uk Kim "psk buffer of callback is too small (%d) for key (%ld)\n", 163aeb5019cSJung-uk Kim max_psk_len, key_len); 164aeb5019cSJung-uk Kim OPENSSL_free(key); 1651f13597dSJung-uk Kim return 0; 1661f13597dSJung-uk Kim } 1671f13597dSJung-uk Kim 168aeb5019cSJung-uk Kim memcpy(psk, key, key_len); 169aeb5019cSJung-uk Kim OPENSSL_free(key); 1701f13597dSJung-uk Kim 1711f13597dSJung-uk Kim if (s_debug) 172aeb5019cSJung-uk Kim BIO_printf(bio_s_out, "fetched PSK len=%ld\n", key_len); 173aeb5019cSJung-uk Kim return key_len; 1741f13597dSJung-uk Kim out_err: 1751f13597dSJung-uk Kim if (s_debug) 1761f13597dSJung-uk Kim BIO_printf(bio_err, "Error in PSK server callback\n"); 177e71b7053SJung-uk Kim (void)BIO_flush(bio_err); 178e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 1791f13597dSJung-uk Kim return 0; 1801f13597dSJung-uk Kim } 1811f13597dSJung-uk Kim #endif 1821f13597dSJung-uk Kim 183e71b7053SJung-uk Kim static int psk_find_session_cb(SSL *ssl, const unsigned char *identity, 184e71b7053SJung-uk Kim size_t identity_len, SSL_SESSION **sess) 185e71b7053SJung-uk Kim { 186e71b7053SJung-uk Kim SSL_SESSION *tmpsess = NULL; 187e71b7053SJung-uk Kim unsigned char *key; 188e71b7053SJung-uk Kim long key_len; 189e71b7053SJung-uk Kim const SSL_CIPHER *cipher = NULL; 190e71b7053SJung-uk Kim 191e71b7053SJung-uk Kim if (strlen(psk_identity) != identity_len 192e71b7053SJung-uk Kim || memcmp(psk_identity, identity, identity_len) != 0) { 193c9cf7b5cSJung-uk Kim *sess = NULL; 194c9cf7b5cSJung-uk Kim return 1; 195e71b7053SJung-uk Kim } 196e71b7053SJung-uk Kim 197e71b7053SJung-uk Kim if (psksess != NULL) { 198e71b7053SJung-uk Kim SSL_SESSION_up_ref(psksess); 199e71b7053SJung-uk Kim *sess = psksess; 200e71b7053SJung-uk Kim return 1; 201e71b7053SJung-uk Kim } 202e71b7053SJung-uk Kim 203e71b7053SJung-uk Kim key = OPENSSL_hexstr2buf(psk_key, &key_len); 204e71b7053SJung-uk Kim if (key == NULL) { 205e71b7053SJung-uk Kim BIO_printf(bio_err, "Could not convert PSK key '%s' to buffer\n", 206e71b7053SJung-uk Kim psk_key); 207e71b7053SJung-uk Kim return 0; 208e71b7053SJung-uk Kim } 209e71b7053SJung-uk Kim 210e71b7053SJung-uk Kim /* We default to SHA256 */ 211e71b7053SJung-uk Kim cipher = SSL_CIPHER_find(ssl, tls13_aes128gcmsha256_id); 212e71b7053SJung-uk Kim if (cipher == NULL) { 213e71b7053SJung-uk Kim BIO_printf(bio_err, "Error finding suitable ciphersuite\n"); 214e71b7053SJung-uk Kim OPENSSL_free(key); 215e71b7053SJung-uk Kim return 0; 216e71b7053SJung-uk Kim } 217e71b7053SJung-uk Kim 218e71b7053SJung-uk Kim tmpsess = SSL_SESSION_new(); 219e71b7053SJung-uk Kim if (tmpsess == NULL 220e71b7053SJung-uk Kim || !SSL_SESSION_set1_master_key(tmpsess, key, key_len) 221e71b7053SJung-uk Kim || !SSL_SESSION_set_cipher(tmpsess, cipher) 222e71b7053SJung-uk Kim || !SSL_SESSION_set_protocol_version(tmpsess, SSL_version(ssl))) { 223e71b7053SJung-uk Kim OPENSSL_free(key); 224e71b7053SJung-uk Kim return 0; 225e71b7053SJung-uk Kim } 226e71b7053SJung-uk Kim OPENSSL_free(key); 227e71b7053SJung-uk Kim *sess = tmpsess; 228e71b7053SJung-uk Kim 229e71b7053SJung-uk Kim return 1; 230e71b7053SJung-uk Kim } 231e71b7053SJung-uk Kim 2321f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP 2331f13597dSJung-uk Kim /* This is a context that we pass to callbacks */ 2346f9291ceSJung-uk Kim typedef struct srpsrvparm_st { 2351f13597dSJung-uk Kim char *login; 2361f13597dSJung-uk Kim SRP_VBASE *vb; 2371f13597dSJung-uk Kim SRP_user_pwd *user; 2381f13597dSJung-uk Kim } srpsrvparm; 239e71b7053SJung-uk Kim static srpsrvparm srp_callback_parm; 2401f13597dSJung-uk Kim 2416f9291ceSJung-uk Kim /* 2426f9291ceSJung-uk Kim * This callback pretends to require some asynchronous logic in order to 2436f9291ceSJung-uk Kim * obtain a verifier. When the callback is called for a new connection we 2446f9291ceSJung-uk Kim * return with a negative value. This will provoke the accept etc to return 2456f9291ceSJung-uk Kim * with an LOOKUP_X509. The main logic of the reinvokes the suspended call 2466f9291ceSJung-uk Kim * (which would normally occur after a worker has finished) and we set the 2476f9291ceSJung-uk Kim * user parameters. 2481f13597dSJung-uk Kim */ 249e71b7053SJung-uk Kim static int ssl_srp_server_param_cb(SSL *s, int *ad, void *arg) 2501f13597dSJung-uk Kim { 2511f13597dSJung-uk Kim srpsrvparm *p = (srpsrvparm *) arg; 2524c6a0400SJung-uk Kim int ret = SSL3_AL_FATAL; 2534c6a0400SJung-uk Kim 2546f9291ceSJung-uk Kim if (p->login == NULL && p->user == NULL) { 2551f13597dSJung-uk Kim p->login = SSL_get_srp_username(s); 2561f13597dSJung-uk Kim BIO_printf(bio_err, "SRP username = \"%s\"\n", p->login); 257e71b7053SJung-uk Kim return -1; 2581f13597dSJung-uk Kim } 2591f13597dSJung-uk Kim 2606f9291ceSJung-uk Kim if (p->user == NULL) { 2611f13597dSJung-uk Kim BIO_printf(bio_err, "User %s doesn't exist\n", p->login); 2624c6a0400SJung-uk Kim goto err; 2631f13597dSJung-uk Kim } 2644c6a0400SJung-uk Kim 2656f9291ceSJung-uk Kim if (SSL_set_srp_server_param 2666f9291ceSJung-uk Kim (s, p->user->N, p->user->g, p->user->s, p->user->v, 2676f9291ceSJung-uk Kim p->user->info) < 0) { 2681f13597dSJung-uk Kim *ad = SSL_AD_INTERNAL_ERROR; 2694c6a0400SJung-uk Kim goto err; 2701f13597dSJung-uk Kim } 2716f9291ceSJung-uk Kim BIO_printf(bio_err, 2726f9291ceSJung-uk Kim "SRP parameters set: username = \"%s\" info=\"%s\" \n", 2736f9291ceSJung-uk Kim p->login, p->user->info); 2744c6a0400SJung-uk Kim ret = SSL_ERROR_NONE; 2754c6a0400SJung-uk Kim 2764c6a0400SJung-uk Kim err: 2774c6a0400SJung-uk Kim SRP_user_pwd_free(p->user); 2781f13597dSJung-uk Kim p->user = NULL; 2791f13597dSJung-uk Kim p->login = NULL; 2804c6a0400SJung-uk Kim return ret; 2811f13597dSJung-uk Kim } 2821f13597dSJung-uk Kim 2831f13597dSJung-uk Kim #endif 2841f13597dSJung-uk Kim 28574664626SKris Kennaway static int local_argc = 0; 28674664626SKris Kennaway static char **local_argv; 28774664626SKris Kennaway 28874664626SKris Kennaway #ifdef CHARSET_EBCDIC 28974664626SKris Kennaway static int ebcdic_new(BIO *bi); 29074664626SKris Kennaway static int ebcdic_free(BIO *a); 29174664626SKris Kennaway static int ebcdic_read(BIO *b, char *out, int outl); 2925c87c606SMark Murray static int ebcdic_write(BIO *b, const char *in, int inl); 2935c87c606SMark Murray static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr); 29474664626SKris Kennaway static int ebcdic_gets(BIO *bp, char *buf, int size); 2955c87c606SMark Murray static int ebcdic_puts(BIO *bp, const char *str); 29674664626SKris Kennaway 29774664626SKris Kennaway # define BIO_TYPE_EBCDIC_FILTER (18|0x0200) 298e71b7053SJung-uk Kim static BIO_METHOD *methods_ebcdic = NULL; 29974664626SKris Kennaway 300e71b7053SJung-uk Kim /* This struct is "unwarranted chumminess with the compiler." */ 3016f9291ceSJung-uk Kim typedef struct { 30274664626SKris Kennaway size_t alloced; 30374664626SKris Kennaway char buff[1]; 30474664626SKris Kennaway } EBCDIC_OUTBUFF; 30574664626SKris Kennaway 306e71b7053SJung-uk Kim static const BIO_METHOD *BIO_f_ebcdic_filter() 30774664626SKris Kennaway { 308e71b7053SJung-uk Kim if (methods_ebcdic == NULL) { 309e71b7053SJung-uk Kim methods_ebcdic = BIO_meth_new(BIO_TYPE_EBCDIC_FILTER, 310e71b7053SJung-uk Kim "EBCDIC/ASCII filter"); 311e71b7053SJung-uk Kim if (methods_ebcdic == NULL 312e71b7053SJung-uk Kim || !BIO_meth_set_write(methods_ebcdic, ebcdic_write) 313e71b7053SJung-uk Kim || !BIO_meth_set_read(methods_ebcdic, ebcdic_read) 314e71b7053SJung-uk Kim || !BIO_meth_set_puts(methods_ebcdic, ebcdic_puts) 315e71b7053SJung-uk Kim || !BIO_meth_set_gets(methods_ebcdic, ebcdic_gets) 316e71b7053SJung-uk Kim || !BIO_meth_set_ctrl(methods_ebcdic, ebcdic_ctrl) 317e71b7053SJung-uk Kim || !BIO_meth_set_create(methods_ebcdic, ebcdic_new) 318e71b7053SJung-uk Kim || !BIO_meth_set_destroy(methods_ebcdic, ebcdic_free)) 319e71b7053SJung-uk Kim return NULL; 320e71b7053SJung-uk Kim } 321e71b7053SJung-uk Kim return methods_ebcdic; 32274664626SKris Kennaway } 32374664626SKris Kennaway 32474664626SKris Kennaway static int ebcdic_new(BIO *bi) 32574664626SKris Kennaway { 32674664626SKris Kennaway EBCDIC_OUTBUFF *wbuf; 32774664626SKris Kennaway 328e71b7053SJung-uk Kim wbuf = app_malloc(sizeof(*wbuf) + 1024, "ebcdic wbuf"); 32974664626SKris Kennaway wbuf->alloced = 1024; 33074664626SKris Kennaway wbuf->buff[0] = '\0'; 33174664626SKris Kennaway 332e71b7053SJung-uk Kim BIO_set_data(bi, wbuf); 333e71b7053SJung-uk Kim BIO_set_init(bi, 1); 334e71b7053SJung-uk Kim return 1; 33574664626SKris Kennaway } 33674664626SKris Kennaway 33774664626SKris Kennaway static int ebcdic_free(BIO *a) 33874664626SKris Kennaway { 339e71b7053SJung-uk Kim EBCDIC_OUTBUFF *wbuf; 340e71b7053SJung-uk Kim 3416f9291ceSJung-uk Kim if (a == NULL) 342e71b7053SJung-uk Kim return 0; 343e71b7053SJung-uk Kim wbuf = BIO_get_data(a); 344e71b7053SJung-uk Kim OPENSSL_free(wbuf); 345e71b7053SJung-uk Kim BIO_set_data(a, NULL); 346e71b7053SJung-uk Kim BIO_set_init(a, 0); 347e71b7053SJung-uk Kim 348e71b7053SJung-uk Kim return 1; 34974664626SKris Kennaway } 35074664626SKris Kennaway 35174664626SKris Kennaway static int ebcdic_read(BIO *b, char *out, int outl) 35274664626SKris Kennaway { 35374664626SKris Kennaway int ret = 0; 354e71b7053SJung-uk Kim BIO *next = BIO_next(b); 35574664626SKris Kennaway 3566f9291ceSJung-uk Kim if (out == NULL || outl == 0) 357e71b7053SJung-uk Kim return 0; 358e71b7053SJung-uk Kim if (next == NULL) 359e71b7053SJung-uk Kim return 0; 36074664626SKris Kennaway 361e71b7053SJung-uk Kim ret = BIO_read(next, out, outl); 36274664626SKris Kennaway if (ret > 0) 36374664626SKris Kennaway ascii2ebcdic(out, out, ret); 364e71b7053SJung-uk Kim return ret; 36574664626SKris Kennaway } 36674664626SKris Kennaway 3675c87c606SMark Murray static int ebcdic_write(BIO *b, const char *in, int inl) 36874664626SKris Kennaway { 36974664626SKris Kennaway EBCDIC_OUTBUFF *wbuf; 370e71b7053SJung-uk Kim BIO *next = BIO_next(b); 37174664626SKris Kennaway int ret = 0; 37274664626SKris Kennaway int num; 37374664626SKris Kennaway 3746f9291ceSJung-uk Kim if ((in == NULL) || (inl <= 0)) 375e71b7053SJung-uk Kim return 0; 376e71b7053SJung-uk Kim if (next == NULL) 377e71b7053SJung-uk Kim return 0; 37874664626SKris Kennaway 379e71b7053SJung-uk Kim wbuf = (EBCDIC_OUTBUFF *) BIO_get_data(b); 38074664626SKris Kennaway 3816f9291ceSJung-uk Kim if (inl > (num = wbuf->alloced)) { 38274664626SKris Kennaway num = num + num; /* double the size */ 38374664626SKris Kennaway if (num < inl) 38474664626SKris Kennaway num = inl; 385e71b7053SJung-uk Kim OPENSSL_free(wbuf); 386e71b7053SJung-uk Kim wbuf = app_malloc(sizeof(*wbuf) + num, "grow ebcdic wbuf"); 38774664626SKris Kennaway 38874664626SKris Kennaway wbuf->alloced = num; 38974664626SKris Kennaway wbuf->buff[0] = '\0'; 39074664626SKris Kennaway 391e71b7053SJung-uk Kim BIO_set_data(b, wbuf); 39274664626SKris Kennaway } 39374664626SKris Kennaway 39474664626SKris Kennaway ebcdic2ascii(wbuf->buff, in, inl); 39574664626SKris Kennaway 396e71b7053SJung-uk Kim ret = BIO_write(next, wbuf->buff, inl); 39774664626SKris Kennaway 398e71b7053SJung-uk Kim return ret; 39974664626SKris Kennaway } 40074664626SKris Kennaway 4015c87c606SMark Murray static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr) 40274664626SKris Kennaway { 40374664626SKris Kennaway long ret; 404e71b7053SJung-uk Kim BIO *next = BIO_next(b); 40574664626SKris Kennaway 406e71b7053SJung-uk Kim if (next == NULL) 407e71b7053SJung-uk Kim return 0; 4086f9291ceSJung-uk Kim switch (cmd) { 40974664626SKris Kennaway case BIO_CTRL_DUP: 41074664626SKris Kennaway ret = 0L; 41174664626SKris Kennaway break; 41274664626SKris Kennaway default: 413e71b7053SJung-uk Kim ret = BIO_ctrl(next, cmd, num, ptr); 41474664626SKris Kennaway break; 41574664626SKris Kennaway } 416e71b7053SJung-uk Kim return ret; 41774664626SKris Kennaway } 41874664626SKris Kennaway 41974664626SKris Kennaway static int ebcdic_gets(BIO *bp, char *buf, int size) 42074664626SKris Kennaway { 4215c87c606SMark Murray int i, ret = 0; 422e71b7053SJung-uk Kim BIO *next = BIO_next(bp); 423e71b7053SJung-uk Kim 424e71b7053SJung-uk Kim if (next == NULL) 425e71b7053SJung-uk Kim return 0; 42674664626SKris Kennaway /* return(BIO_gets(bp->next_bio,buf,size));*/ 4276f9291ceSJung-uk Kim for (i = 0; i < size - 1; ++i) { 42874664626SKris Kennaway ret = ebcdic_read(bp, &buf[i], 1); 42974664626SKris Kennaway if (ret <= 0) 43074664626SKris Kennaway break; 4316f9291ceSJung-uk Kim else if (buf[i] == '\n') { 43274664626SKris Kennaway ++i; 43374664626SKris Kennaway break; 43474664626SKris Kennaway } 43574664626SKris Kennaway } 43674664626SKris Kennaway if (i < size) 43774664626SKris Kennaway buf[i] = '\0'; 43874664626SKris Kennaway return (ret < 0 && i == 0) ? ret : i; 43974664626SKris Kennaway } 44074664626SKris Kennaway 4415c87c606SMark Murray static int ebcdic_puts(BIO *bp, const char *str) 44274664626SKris Kennaway { 443e71b7053SJung-uk Kim if (BIO_next(bp) == NULL) 444e71b7053SJung-uk Kim return 0; 44574664626SKris Kennaway return ebcdic_write(bp, str, strlen(str)); 44674664626SKris Kennaway } 44774664626SKris Kennaway #endif 44874664626SKris Kennaway 449db522d3aSSimon L. B. Nielsen /* This is a context that we pass to callbacks */ 450db522d3aSSimon L. B. Nielsen typedef struct tlsextctx_st { 451db522d3aSSimon L. B. Nielsen char *servername; 452db522d3aSSimon L. B. Nielsen BIO *biodebug; 453db522d3aSSimon L. B. Nielsen int extension_error; 454db522d3aSSimon L. B. Nielsen } tlsextctx; 455db522d3aSSimon L. B. Nielsen 456e71b7053SJung-uk Kim static int ssl_servername_cb(SSL *s, int *ad, void *arg) 457db522d3aSSimon L. B. Nielsen { 458db522d3aSSimon L. B. Nielsen tlsextctx *p = (tlsextctx *) arg; 459db522d3aSSimon L. B. Nielsen const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name); 460db522d3aSSimon L. B. Nielsen 461e71b7053SJung-uk Kim if (servername != NULL && p->biodebug != NULL) { 462e71b7053SJung-uk Kim const char *cp = servername; 463e71b7053SJung-uk Kim unsigned char uc; 464e71b7053SJung-uk Kim 465e71b7053SJung-uk Kim BIO_printf(p->biodebug, "Hostname in TLS extension: \""); 466e71b7053SJung-uk Kim while ((uc = *cp++) != 0) 467e71b7053SJung-uk Kim BIO_printf(p->biodebug, 468e71b7053SJung-uk Kim isascii(uc) && isprint(uc) ? "%c" : "\\x%02x", uc); 469e71b7053SJung-uk Kim BIO_printf(p->biodebug, "\"\n"); 470e71b7053SJung-uk Kim } 471e71b7053SJung-uk Kim 472e71b7053SJung-uk Kim if (p->servername == NULL) 473db522d3aSSimon L. B. Nielsen return SSL_TLSEXT_ERR_NOACK; 474db522d3aSSimon L. B. Nielsen 475e71b7053SJung-uk Kim if (servername != NULL) { 476a93cbc2bSJung-uk Kim if (strcasecmp(servername, p->servername)) 477db522d3aSSimon L. B. Nielsen return p->extension_error; 478e71b7053SJung-uk Kim if (ctx2 != NULL) { 4791f13597dSJung-uk Kim BIO_printf(p->biodebug, "Switching server context.\n"); 480db522d3aSSimon L. B. Nielsen SSL_set_SSL_CTX(s, ctx2); 481db522d3aSSimon L. B. Nielsen } 482db522d3aSSimon L. B. Nielsen } 483db522d3aSSimon L. B. Nielsen return SSL_TLSEXT_ERR_OK; 484db522d3aSSimon L. B. Nielsen } 485db522d3aSSimon L. B. Nielsen 486db522d3aSSimon L. B. Nielsen /* Structure passed to cert status callback */ 487db522d3aSSimon L. B. Nielsen typedef struct tlsextstatusctx_st { 488e71b7053SJung-uk Kim int timeout; 489e71b7053SJung-uk Kim /* File to load OCSP Response from (or NULL if no file) */ 490e71b7053SJung-uk Kim char *respin; 491db522d3aSSimon L. B. Nielsen /* Default responder to use */ 492db522d3aSSimon L. B. Nielsen char *host, *path, *port; 493db522d3aSSimon L. B. Nielsen int use_ssl; 494db522d3aSSimon L. B. Nielsen int verbose; 495db522d3aSSimon L. B. Nielsen } tlsextstatusctx; 496db522d3aSSimon L. B. Nielsen 497e71b7053SJung-uk Kim static tlsextstatusctx tlscstatp = { -1 }; 498e71b7053SJung-uk Kim 499e71b7053SJung-uk Kim #ifndef OPENSSL_NO_OCSP 500db522d3aSSimon L. B. Nielsen 5016f9291ceSJung-uk Kim /* 502e71b7053SJung-uk Kim * Helper function to get an OCSP_RESPONSE from a responder. This is a 503e71b7053SJung-uk Kim * simplified version. It examines certificates each time and makes one OCSP 504e71b7053SJung-uk Kim * responder query for each request. A full version would store details such as 505e71b7053SJung-uk Kim * the OCSP certificate IDs and minimise the number of OCSP responses by caching 506e71b7053SJung-uk Kim * them until they were considered "expired". 507db522d3aSSimon L. B. Nielsen */ 508e71b7053SJung-uk Kim static int get_ocsp_resp_from_responder(SSL *s, tlsextstatusctx *srctx, 509e71b7053SJung-uk Kim OCSP_RESPONSE **resp) 510db522d3aSSimon L. B. Nielsen { 511e71b7053SJung-uk Kim char *host = NULL, *port = NULL, *path = NULL; 512db522d3aSSimon L. B. Nielsen int use_ssl; 5131f13597dSJung-uk Kim STACK_OF(OPENSSL_STRING) *aia = NULL; 514db522d3aSSimon L. B. Nielsen X509 *x = NULL; 515e71b7053SJung-uk Kim X509_STORE_CTX *inctx = NULL; 516e71b7053SJung-uk Kim X509_OBJECT *obj; 517db522d3aSSimon L. B. Nielsen OCSP_REQUEST *req = NULL; 518db522d3aSSimon L. B. Nielsen OCSP_CERTID *id = NULL; 519db522d3aSSimon L. B. Nielsen STACK_OF(X509_EXTENSION) *exts; 520db522d3aSSimon L. B. Nielsen int ret = SSL_TLSEXT_ERR_NOACK; 521db522d3aSSimon L. B. Nielsen int i; 522e71b7053SJung-uk Kim 523db522d3aSSimon L. B. Nielsen /* Build up OCSP query from server certificate */ 524db522d3aSSimon L. B. Nielsen x = SSL_get_certificate(s); 525db522d3aSSimon L. B. Nielsen aia = X509_get1_ocsp(x); 526e71b7053SJung-uk Kim if (aia != NULL) { 5271f13597dSJung-uk Kim if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0), 5286f9291ceSJung-uk Kim &host, &port, &path, &use_ssl)) { 529e71b7053SJung-uk Kim BIO_puts(bio_err, "cert_status: can't parse AIA URL\n"); 530db522d3aSSimon L. B. Nielsen goto err; 531db522d3aSSimon L. B. Nielsen } 532db522d3aSSimon L. B. Nielsen if (srctx->verbose) 533e71b7053SJung-uk Kim BIO_printf(bio_err, "cert_status: AIA URL: %s\n", 5341f13597dSJung-uk Kim sk_OPENSSL_STRING_value(aia, 0)); 5356f9291ceSJung-uk Kim } else { 536e71b7053SJung-uk Kim if (srctx->host == NULL) { 537e71b7053SJung-uk Kim BIO_puts(bio_err, 5386f9291ceSJung-uk Kim "cert_status: no AIA and no default responder URL\n"); 539db522d3aSSimon L. B. Nielsen goto done; 540db522d3aSSimon L. B. Nielsen } 541db522d3aSSimon L. B. Nielsen host = srctx->host; 542db522d3aSSimon L. B. Nielsen path = srctx->path; 543db522d3aSSimon L. B. Nielsen port = srctx->port; 544db522d3aSSimon L. B. Nielsen use_ssl = srctx->use_ssl; 545db522d3aSSimon L. B. Nielsen } 546db522d3aSSimon L. B. Nielsen 547e71b7053SJung-uk Kim inctx = X509_STORE_CTX_new(); 548e71b7053SJung-uk Kim if (inctx == NULL) 549e71b7053SJung-uk Kim goto err; 550e71b7053SJung-uk Kim if (!X509_STORE_CTX_init(inctx, 551db522d3aSSimon L. B. Nielsen SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)), 552db522d3aSSimon L. B. Nielsen NULL, NULL)) 553db522d3aSSimon L. B. Nielsen goto err; 554e71b7053SJung-uk Kim obj = X509_STORE_CTX_get_obj_by_subject(inctx, X509_LU_X509, 555e71b7053SJung-uk Kim X509_get_issuer_name(x)); 556e71b7053SJung-uk Kim if (obj == NULL) { 557e71b7053SJung-uk Kim BIO_puts(bio_err, "cert_status: Can't retrieve issuer certificate.\n"); 558db522d3aSSimon L. B. Nielsen goto done; 559db522d3aSSimon L. B. Nielsen } 560e71b7053SJung-uk Kim id = OCSP_cert_to_id(NULL, x, X509_OBJECT_get0_X509(obj)); 561e71b7053SJung-uk Kim X509_OBJECT_free(obj); 562e71b7053SJung-uk Kim if (id == NULL) 563db522d3aSSimon L. B. Nielsen goto err; 564e71b7053SJung-uk Kim req = OCSP_REQUEST_new(); 565e71b7053SJung-uk Kim if (req == NULL) 566db522d3aSSimon L. B. Nielsen goto err; 567db522d3aSSimon L. B. Nielsen if (!OCSP_request_add0_id(req, id)) 568db522d3aSSimon L. B. Nielsen goto err; 569db522d3aSSimon L. B. Nielsen id = NULL; 570db522d3aSSimon L. B. Nielsen /* Add any extensions to the request */ 571db522d3aSSimon L. B. Nielsen SSL_get_tlsext_status_exts(s, &exts); 5726f9291ceSJung-uk Kim for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { 573db522d3aSSimon L. B. Nielsen X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); 574db522d3aSSimon L. B. Nielsen if (!OCSP_REQUEST_add_ext(req, ext, -1)) 575db522d3aSSimon L. B. Nielsen goto err; 576db522d3aSSimon L. B. Nielsen } 577e71b7053SJung-uk Kim *resp = process_responder(req, host, path, port, use_ssl, NULL, 578db522d3aSSimon L. B. Nielsen srctx->timeout); 579e71b7053SJung-uk Kim if (*resp == NULL) { 580e71b7053SJung-uk Kim BIO_puts(bio_err, "cert_status: error querying responder\n"); 581db522d3aSSimon L. B. Nielsen goto done; 582db522d3aSSimon L. B. Nielsen } 583e71b7053SJung-uk Kim 584db522d3aSSimon L. B. Nielsen ret = SSL_TLSEXT_ERR_OK; 585e71b7053SJung-uk Kim goto done; 586e71b7053SJung-uk Kim 587e71b7053SJung-uk Kim err: 588e71b7053SJung-uk Kim ret = SSL_TLSEXT_ERR_ALERT_FATAL; 589db522d3aSSimon L. B. Nielsen done: 590e71b7053SJung-uk Kim /* 591e71b7053SJung-uk Kim * If we parsed aia we need to free; otherwise they were copied and we 592e71b7053SJung-uk Kim * don't 593e71b7053SJung-uk Kim */ 594e71b7053SJung-uk Kim if (aia != NULL) { 595db522d3aSSimon L. B. Nielsen OPENSSL_free(host); 596db522d3aSSimon L. B. Nielsen OPENSSL_free(path); 597db522d3aSSimon L. B. Nielsen OPENSSL_free(port); 598db522d3aSSimon L. B. Nielsen X509_email_free(aia); 599db522d3aSSimon L. B. Nielsen } 600db522d3aSSimon L. B. Nielsen OCSP_CERTID_free(id); 601db522d3aSSimon L. B. Nielsen OCSP_REQUEST_free(req); 602e71b7053SJung-uk Kim X509_STORE_CTX_free(inctx); 603db522d3aSSimon L. B. Nielsen return ret; 604db522d3aSSimon L. B. Nielsen } 6051f13597dSJung-uk Kim 606e71b7053SJung-uk Kim /* 607e71b7053SJung-uk Kim * Certificate Status callback. This is called when a client includes a 608e71b7053SJung-uk Kim * certificate status request extension. The response is either obtained from a 609e71b7053SJung-uk Kim * file, or from an OCSP responder. 610e71b7053SJung-uk Kim */ 611e71b7053SJung-uk Kim static int cert_status_cb(SSL *s, void *arg) 612e71b7053SJung-uk Kim { 613e71b7053SJung-uk Kim tlsextstatusctx *srctx = arg; 614e71b7053SJung-uk Kim OCSP_RESPONSE *resp = NULL; 615e71b7053SJung-uk Kim unsigned char *rspder = NULL; 616e71b7053SJung-uk Kim int rspderlen; 617e71b7053SJung-uk Kim int ret = SSL_TLSEXT_ERR_ALERT_FATAL; 618e71b7053SJung-uk Kim 619e71b7053SJung-uk Kim if (srctx->verbose) 620e71b7053SJung-uk Kim BIO_puts(bio_err, "cert_status: callback called\n"); 621e71b7053SJung-uk Kim 622e71b7053SJung-uk Kim if (srctx->respin != NULL) { 623e71b7053SJung-uk Kim BIO *derbio = bio_open_default(srctx->respin, 'r', FORMAT_ASN1); 624e71b7053SJung-uk Kim if (derbio == NULL) { 625e71b7053SJung-uk Kim BIO_puts(bio_err, "cert_status: Cannot open OCSP response file\n"); 626e71b7053SJung-uk Kim goto err; 627e71b7053SJung-uk Kim } 628e71b7053SJung-uk Kim resp = d2i_OCSP_RESPONSE_bio(derbio, NULL); 629e71b7053SJung-uk Kim BIO_free(derbio); 630e71b7053SJung-uk Kim if (resp == NULL) { 631e71b7053SJung-uk Kim BIO_puts(bio_err, "cert_status: Error reading OCSP response\n"); 632e71b7053SJung-uk Kim goto err; 633e71b7053SJung-uk Kim } 634e71b7053SJung-uk Kim } else { 635e71b7053SJung-uk Kim ret = get_ocsp_resp_from_responder(s, srctx, &resp); 636e71b7053SJung-uk Kim if (ret != SSL_TLSEXT_ERR_OK) 637e71b7053SJung-uk Kim goto err; 638e71b7053SJung-uk Kim } 639e71b7053SJung-uk Kim 640e71b7053SJung-uk Kim rspderlen = i2d_OCSP_RESPONSE(resp, &rspder); 641e71b7053SJung-uk Kim if (rspderlen <= 0) 642e71b7053SJung-uk Kim goto err; 643e71b7053SJung-uk Kim 644e71b7053SJung-uk Kim SSL_set_tlsext_status_ocsp_resp(s, rspder, rspderlen); 645e71b7053SJung-uk Kim if (srctx->verbose) { 646e71b7053SJung-uk Kim BIO_puts(bio_err, "cert_status: ocsp response sent:\n"); 647e71b7053SJung-uk Kim OCSP_RESPONSE_print(bio_err, resp, 2); 648e71b7053SJung-uk Kim } 649e71b7053SJung-uk Kim 650e71b7053SJung-uk Kim ret = SSL_TLSEXT_ERR_OK; 651e71b7053SJung-uk Kim 652e71b7053SJung-uk Kim err: 653e71b7053SJung-uk Kim if (ret != SSL_TLSEXT_ERR_OK) 654e71b7053SJung-uk Kim ERR_print_errors(bio_err); 655e71b7053SJung-uk Kim 656e71b7053SJung-uk Kim OCSP_RESPONSE_free(resp); 657e71b7053SJung-uk Kim 658e71b7053SJung-uk Kim return ret; 659e71b7053SJung-uk Kim } 660e71b7053SJung-uk Kim #endif 661e71b7053SJung-uk Kim 6621f13597dSJung-uk Kim #ifndef OPENSSL_NO_NEXTPROTONEG 6631f13597dSJung-uk Kim /* This is the context that we pass to next_proto_cb */ 6641f13597dSJung-uk Kim typedef struct tlsextnextprotoctx_st { 6651f13597dSJung-uk Kim unsigned char *data; 666e71b7053SJung-uk Kim size_t len; 6671f13597dSJung-uk Kim } tlsextnextprotoctx; 6681f13597dSJung-uk Kim 6696f9291ceSJung-uk Kim static int next_proto_cb(SSL *s, const unsigned char **data, 6706f9291ceSJung-uk Kim unsigned int *len, void *arg) 6711f13597dSJung-uk Kim { 6721f13597dSJung-uk Kim tlsextnextprotoctx *next_proto = arg; 6731f13597dSJung-uk Kim 6741f13597dSJung-uk Kim *data = next_proto->data; 6751f13597dSJung-uk Kim *len = next_proto->len; 6761f13597dSJung-uk Kim 6771f13597dSJung-uk Kim return SSL_TLSEXT_ERR_OK; 6781f13597dSJung-uk Kim } 6791f13597dSJung-uk Kim #endif /* ndef OPENSSL_NO_NEXTPROTONEG */ 6801f13597dSJung-uk Kim 6817bded2dbSJung-uk Kim /* This the context that we pass to alpn_cb */ 6827bded2dbSJung-uk Kim typedef struct tlsextalpnctx_st { 6837bded2dbSJung-uk Kim unsigned char *data; 684e71b7053SJung-uk Kim size_t len; 6857bded2dbSJung-uk Kim } tlsextalpnctx; 6867bded2dbSJung-uk Kim 6877bded2dbSJung-uk Kim static int alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen, 6887bded2dbSJung-uk Kim const unsigned char *in, unsigned int inlen, void *arg) 6897bded2dbSJung-uk Kim { 6907bded2dbSJung-uk Kim tlsextalpnctx *alpn_ctx = arg; 6917bded2dbSJung-uk Kim 6927bded2dbSJung-uk Kim if (!s_quiet) { 6937bded2dbSJung-uk Kim /* We can assume that |in| is syntactically valid. */ 694e71b7053SJung-uk Kim unsigned int i; 6957bded2dbSJung-uk Kim BIO_printf(bio_s_out, "ALPN protocols advertised by the client: "); 6967bded2dbSJung-uk Kim for (i = 0; i < inlen;) { 6977bded2dbSJung-uk Kim if (i) 6987bded2dbSJung-uk Kim BIO_write(bio_s_out, ", ", 2); 6997bded2dbSJung-uk Kim BIO_write(bio_s_out, &in[i + 1], in[i]); 7007bded2dbSJung-uk Kim i += in[i] + 1; 7017bded2dbSJung-uk Kim } 7027bded2dbSJung-uk Kim BIO_write(bio_s_out, "\n", 1); 7037bded2dbSJung-uk Kim } 7047bded2dbSJung-uk Kim 7057bded2dbSJung-uk Kim if (SSL_select_next_proto 7067bded2dbSJung-uk Kim ((unsigned char **)out, outlen, alpn_ctx->data, alpn_ctx->len, in, 7077bded2dbSJung-uk Kim inlen) != OPENSSL_NPN_NEGOTIATED) { 7087bded2dbSJung-uk Kim return SSL_TLSEXT_ERR_NOACK; 7097bded2dbSJung-uk Kim } 7107bded2dbSJung-uk Kim 7117bded2dbSJung-uk Kim if (!s_quiet) { 7127bded2dbSJung-uk Kim BIO_printf(bio_s_out, "ALPN protocols selected: "); 7137bded2dbSJung-uk Kim BIO_write(bio_s_out, *out, *outlen); 7147bded2dbSJung-uk Kim BIO_write(bio_s_out, "\n", 1); 7157bded2dbSJung-uk Kim } 7167bded2dbSJung-uk Kim 7177bded2dbSJung-uk Kim return SSL_TLSEXT_ERR_OK; 7187bded2dbSJung-uk Kim } 7191f13597dSJung-uk Kim 720e71b7053SJung-uk Kim static int not_resumable_sess_cb(SSL *s, int is_forward_secure) 721e71b7053SJung-uk Kim { 722e71b7053SJung-uk Kim /* disable resumption for sessions with forward secure ciphers */ 723e71b7053SJung-uk Kim return is_forward_secure; 724e71b7053SJung-uk Kim } 725f579bf8eSKris Kennaway 726e71b7053SJung-uk Kim typedef enum OPTION_choice { 727e71b7053SJung-uk Kim OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ENGINE, 728e71b7053SJung-uk Kim OPT_4, OPT_6, OPT_ACCEPT, OPT_PORT, OPT_UNIX, OPT_UNLINK, OPT_NACCEPT, 729e71b7053SJung-uk Kim OPT_VERIFY, OPT_NAMEOPT, OPT_UPPER_V_VERIFY, OPT_CONTEXT, OPT_CERT, OPT_CRL, 730e71b7053SJung-uk Kim OPT_CRL_DOWNLOAD, OPT_SERVERINFO, OPT_CERTFORM, OPT_KEY, OPT_KEYFORM, 731e71b7053SJung-uk Kim OPT_PASS, OPT_CERT_CHAIN, OPT_DHPARAM, OPT_DCERTFORM, OPT_DCERT, 732e71b7053SJung-uk Kim OPT_DKEYFORM, OPT_DPASS, OPT_DKEY, OPT_DCERT_CHAIN, OPT_NOCERT, 733e71b7053SJung-uk Kim OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH, OPT_NO_CACHE, 734e71b7053SJung-uk Kim OPT_EXT_CACHE, OPT_CRLFORM, OPT_VERIFY_RET_ERROR, OPT_VERIFY_QUIET, 735e71b7053SJung-uk Kim OPT_BUILD_CHAIN, OPT_CAFILE, OPT_NOCAFILE, OPT_CHAINCAFILE, 736e71b7053SJung-uk Kim OPT_VERIFYCAFILE, OPT_NBIO, OPT_NBIO_TEST, OPT_IGN_EOF, OPT_NO_IGN_EOF, 737e71b7053SJung-uk Kim OPT_DEBUG, OPT_TLSEXTDEBUG, OPT_STATUS, OPT_STATUS_VERBOSE, 738e71b7053SJung-uk Kim OPT_STATUS_TIMEOUT, OPT_STATUS_URL, OPT_STATUS_FILE, OPT_MSG, OPT_MSGFILE, 739e71b7053SJung-uk Kim OPT_TRACE, OPT_SECURITY_DEBUG, OPT_SECURITY_DEBUG_VERBOSE, OPT_STATE, 740e71b7053SJung-uk Kim OPT_CRLF, OPT_QUIET, OPT_BRIEF, OPT_NO_DHE, 741e71b7053SJung-uk Kim OPT_NO_RESUME_EPHEMERAL, OPT_PSK_IDENTITY, OPT_PSK_HINT, OPT_PSK, 742e71b7053SJung-uk Kim OPT_PSK_SESS, OPT_SRPVFILE, OPT_SRPUSERSEED, OPT_REV, OPT_WWW, 743e71b7053SJung-uk Kim OPT_UPPER_WWW, OPT_HTTP, OPT_ASYNC, OPT_SSL_CONFIG, 744e71b7053SJung-uk Kim OPT_MAX_SEND_FRAG, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES, OPT_READ_BUF, 745e71b7053SJung-uk Kim OPT_SSL3, OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1, 746e71b7053SJung-uk Kim OPT_DTLS1_2, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_LISTEN, OPT_STATELESS, 747e71b7053SJung-uk Kim OPT_ID_PREFIX, OPT_SERVERNAME, OPT_SERVERNAME_FATAL, 748e71b7053SJung-uk Kim OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN, 749e71b7053SJung-uk Kim OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, 750e71b7053SJung-uk Kim OPT_KEYLOG_FILE, OPT_MAX_EARLY, OPT_RECV_MAX_EARLY, OPT_EARLY_DATA, 7516935a639SJung-uk Kim OPT_S_NUM_TICKETS, OPT_ANTI_REPLAY, OPT_NO_ANTI_REPLAY, OPT_SCTP_LABEL_BUG, 752e71b7053SJung-uk Kim OPT_R_ENUM, 753e71b7053SJung-uk Kim OPT_S_ENUM, 754e71b7053SJung-uk Kim OPT_V_ENUM, 755e71b7053SJung-uk Kim OPT_X_ENUM 756e71b7053SJung-uk Kim } OPTION_CHOICE; 757e71b7053SJung-uk Kim 758e71b7053SJung-uk Kim const OPTIONS s_server_options[] = { 759e71b7053SJung-uk Kim {"help", OPT_HELP, '-', "Display this summary"}, 760e71b7053SJung-uk Kim {"port", OPT_PORT, 'p', 761e71b7053SJung-uk Kim "TCP/IP port to listen on for connections (default is " PORT ")"}, 762e71b7053SJung-uk Kim {"accept", OPT_ACCEPT, 's', 763e71b7053SJung-uk Kim "TCP/IP optional host and port to listen on for connections (default is *:" PORT ")"}, 764e71b7053SJung-uk Kim #ifdef AF_UNIX 765e71b7053SJung-uk Kim {"unix", OPT_UNIX, 's', "Unix domain socket to accept on"}, 766db522d3aSSimon L. B. Nielsen #endif 767e71b7053SJung-uk Kim {"4", OPT_4, '-', "Use IPv4 only"}, 768e71b7053SJung-uk Kim {"6", OPT_6, '-', "Use IPv6 only"}, 769e71b7053SJung-uk Kim #ifdef AF_UNIX 770e71b7053SJung-uk Kim {"unlink", OPT_UNLINK, '-', "For -unix, unlink existing socket first"}, 771e71b7053SJung-uk Kim #endif 772e71b7053SJung-uk Kim {"context", OPT_CONTEXT, 's', "Set session ID context"}, 773e71b7053SJung-uk Kim {"verify", OPT_VERIFY, 'n', "Turn on peer certificate verification"}, 774e71b7053SJung-uk Kim {"Verify", OPT_UPPER_V_VERIFY, 'n', 775e71b7053SJung-uk Kim "Turn on peer certificate verification, must have a cert"}, 776e71b7053SJung-uk Kim {"cert", OPT_CERT, '<', "Certificate file to use; default is " TEST_CERT}, 777e71b7053SJung-uk Kim {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, 778e71b7053SJung-uk Kim {"naccept", OPT_NACCEPT, 'p', "Terminate after #num connections"}, 779e71b7053SJung-uk Kim {"serverinfo", OPT_SERVERINFO, 's', 780e71b7053SJung-uk Kim "PEM serverinfo file for certificate"}, 781e71b7053SJung-uk Kim {"certform", OPT_CERTFORM, 'F', 782e71b7053SJung-uk Kim "Certificate format (PEM or DER) PEM default"}, 783e71b7053SJung-uk Kim {"key", OPT_KEY, 's', 784e71b7053SJung-uk Kim "Private Key if not in -cert; default is " TEST_CERT}, 785e71b7053SJung-uk Kim {"keyform", OPT_KEYFORM, 'f', 786e71b7053SJung-uk Kim "Key format (PEM, DER or ENGINE) PEM default"}, 787e71b7053SJung-uk Kim {"pass", OPT_PASS, 's', "Private key file pass phrase source"}, 788e71b7053SJung-uk Kim {"dcert", OPT_DCERT, '<', 789e71b7053SJung-uk Kim "Second certificate file to use (usually for DSA)"}, 790e71b7053SJung-uk Kim {"dhparam", OPT_DHPARAM, '<', "DH parameters file to use"}, 791e71b7053SJung-uk Kim {"dcertform", OPT_DCERTFORM, 'F', 792e71b7053SJung-uk Kim "Second certificate format (PEM or DER) PEM default"}, 793e71b7053SJung-uk Kim {"dkey", OPT_DKEY, '<', 794e71b7053SJung-uk Kim "Second private key file to use (usually for DSA)"}, 795e71b7053SJung-uk Kim {"dkeyform", OPT_DKEYFORM, 'F', 796e71b7053SJung-uk Kim "Second key format (PEM, DER or ENGINE) PEM default"}, 797e71b7053SJung-uk Kim {"dpass", OPT_DPASS, 's', "Second private key file pass phrase source"}, 798e71b7053SJung-uk Kim {"nbio_test", OPT_NBIO_TEST, '-', "Test with the non-blocking test bio"}, 799e71b7053SJung-uk Kim {"crlf", OPT_CRLF, '-', "Convert LF from terminal into CRLF"}, 800e71b7053SJung-uk Kim {"debug", OPT_DEBUG, '-', "Print more output"}, 801e71b7053SJung-uk Kim {"msg", OPT_MSG, '-', "Show protocol messages"}, 802e71b7053SJung-uk Kim {"msgfile", OPT_MSGFILE, '>', 803e71b7053SJung-uk Kim "File to send output of -msg or -trace, instead of stdout"}, 804e71b7053SJung-uk Kim {"state", OPT_STATE, '-', "Print the SSL states"}, 805e71b7053SJung-uk Kim {"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"}, 806e71b7053SJung-uk Kim {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"}, 807e71b7053SJung-uk Kim {"no-CAfile", OPT_NOCAFILE, '-', 808e71b7053SJung-uk Kim "Do not load the default certificates file"}, 809e71b7053SJung-uk Kim {"no-CApath", OPT_NOCAPATH, '-', 810e71b7053SJung-uk Kim "Do not load certificates from the default certificates directory"}, 811e71b7053SJung-uk Kim {"nocert", OPT_NOCERT, '-', "Don't use any certificates (Anon-DH)"}, 812e71b7053SJung-uk Kim {"quiet", OPT_QUIET, '-', "No server output"}, 813e71b7053SJung-uk Kim {"no_resume_ephemeral", OPT_NO_RESUME_EPHEMERAL, '-', 814e71b7053SJung-uk Kim "Disable caching and tickets if ephemeral (EC)DH is used"}, 815e71b7053SJung-uk Kim {"www", OPT_WWW, '-', "Respond to a 'GET /' with a status page"}, 816e71b7053SJung-uk Kim {"WWW", OPT_UPPER_WWW, '-', "Respond to a 'GET with the file ./path"}, 817e71b7053SJung-uk Kim {"servername", OPT_SERVERNAME, 's', 818e71b7053SJung-uk Kim "Servername for HostName TLS extension"}, 819e71b7053SJung-uk Kim {"servername_fatal", OPT_SERVERNAME_FATAL, '-', 820e71b7053SJung-uk Kim "mismatch send fatal alert (default warning alert)"}, 821e71b7053SJung-uk Kim {"cert2", OPT_CERT2, '<', 822e71b7053SJung-uk Kim "Certificate file to use for servername; default is" TEST_CERT2}, 823e71b7053SJung-uk Kim {"key2", OPT_KEY2, '<', 824e71b7053SJung-uk Kim "-Private Key file to use for servername if not in -cert2"}, 825e71b7053SJung-uk Kim {"tlsextdebug", OPT_TLSEXTDEBUG, '-', 826e71b7053SJung-uk Kim "Hex dump of all TLS extensions received"}, 827e71b7053SJung-uk Kim {"HTTP", OPT_HTTP, '-', "Like -WWW but ./path includes HTTP headers"}, 828e71b7053SJung-uk Kim {"id_prefix", OPT_ID_PREFIX, 's', 829e71b7053SJung-uk Kim "Generate SSL/TLS session IDs prefixed by arg"}, 830e71b7053SJung-uk Kim OPT_R_OPTIONS, 831e71b7053SJung-uk Kim {"keymatexport", OPT_KEYMATEXPORT, 's', 832e71b7053SJung-uk Kim "Export keying material using label"}, 833e71b7053SJung-uk Kim {"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p', 834e71b7053SJung-uk Kim "Export len bytes of keying material (default 20)"}, 835e71b7053SJung-uk Kim {"CRL", OPT_CRL, '<', "CRL file to use"}, 836e71b7053SJung-uk Kim {"crl_download", OPT_CRL_DOWNLOAD, '-', 837e71b7053SJung-uk Kim "Download CRL from distribution points"}, 838e71b7053SJung-uk Kim {"cert_chain", OPT_CERT_CHAIN, '<', 839e71b7053SJung-uk Kim "certificate chain file in PEM format"}, 840e71b7053SJung-uk Kim {"dcert_chain", OPT_DCERT_CHAIN, '<', 841e71b7053SJung-uk Kim "second certificate chain file in PEM format"}, 842e71b7053SJung-uk Kim {"chainCApath", OPT_CHAINCAPATH, '/', 843e71b7053SJung-uk Kim "use dir as certificate store path to build CA certificate chain"}, 844e71b7053SJung-uk Kim {"verifyCApath", OPT_VERIFYCAPATH, '/', 845e71b7053SJung-uk Kim "use dir as certificate store path to verify CA certificate"}, 846e71b7053SJung-uk Kim {"no_cache", OPT_NO_CACHE, '-', "Disable session cache"}, 847e71b7053SJung-uk Kim {"ext_cache", OPT_EXT_CACHE, '-', 848e71b7053SJung-uk Kim "Disable internal cache, setup and use external cache"}, 849e71b7053SJung-uk Kim {"CRLform", OPT_CRLFORM, 'F', "CRL format (PEM or DER) PEM is default"}, 850e71b7053SJung-uk Kim {"verify_return_error", OPT_VERIFY_RET_ERROR, '-', 851e71b7053SJung-uk Kim "Close connection on verification error"}, 852e71b7053SJung-uk Kim {"verify_quiet", OPT_VERIFY_QUIET, '-', 853e71b7053SJung-uk Kim "No verify output except verify errors"}, 854e71b7053SJung-uk Kim {"build_chain", OPT_BUILD_CHAIN, '-', "Build certificate chain"}, 855e71b7053SJung-uk Kim {"chainCAfile", OPT_CHAINCAFILE, '<', 856e71b7053SJung-uk Kim "CA file for certificate chain (PEM format)"}, 857e71b7053SJung-uk Kim {"verifyCAfile", OPT_VERIFYCAFILE, '<', 858e71b7053SJung-uk Kim "CA file for certificate verification (PEM format)"}, 859e71b7053SJung-uk Kim {"ign_eof", OPT_IGN_EOF, '-', "ignore input eof (default when -quiet)"}, 860e71b7053SJung-uk Kim {"no_ign_eof", OPT_NO_IGN_EOF, '-', "Do not ignore input eof"}, 861e71b7053SJung-uk Kim #ifndef OPENSSL_NO_OCSP 862e71b7053SJung-uk Kim {"status", OPT_STATUS, '-', "Request certificate status from server"}, 863e71b7053SJung-uk Kim {"status_verbose", OPT_STATUS_VERBOSE, '-', 864e71b7053SJung-uk Kim "Print more output in certificate status callback"}, 865e71b7053SJung-uk Kim {"status_timeout", OPT_STATUS_TIMEOUT, 'n', 866e71b7053SJung-uk Kim "Status request responder timeout"}, 867e71b7053SJung-uk Kim {"status_url", OPT_STATUS_URL, 's', "Status request fallback URL"}, 868e71b7053SJung-uk Kim {"status_file", OPT_STATUS_FILE, '<', 869e71b7053SJung-uk Kim "File containing DER encoded OCSP Response"}, 870e71b7053SJung-uk Kim #endif 871e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SSL_TRACE 872e71b7053SJung-uk Kim {"trace", OPT_TRACE, '-', "trace protocol messages"}, 873e71b7053SJung-uk Kim #endif 874e71b7053SJung-uk Kim {"security_debug", OPT_SECURITY_DEBUG, '-', 875e71b7053SJung-uk Kim "Print output from SSL/TLS security framework"}, 876e71b7053SJung-uk Kim {"security_debug_verbose", OPT_SECURITY_DEBUG_VERBOSE, '-', 877e71b7053SJung-uk Kim "Print more output from SSL/TLS security framework"}, 878e71b7053SJung-uk Kim {"brief", OPT_BRIEF, '-', 879e71b7053SJung-uk Kim "Restrict output to brief summary of connection parameters"}, 880e71b7053SJung-uk Kim {"rev", OPT_REV, '-', 881e71b7053SJung-uk Kim "act as a simple test server which just sends back with the received text reversed"}, 882e71b7053SJung-uk Kim {"async", OPT_ASYNC, '-', "Operate in asynchronous mode"}, 883e71b7053SJung-uk Kim {"ssl_config", OPT_SSL_CONFIG, 's', 884e71b7053SJung-uk Kim "Configure SSL_CTX using the configuration 'val'"}, 885e71b7053SJung-uk Kim {"max_send_frag", OPT_MAX_SEND_FRAG, 'p', "Maximum Size of send frames "}, 886e71b7053SJung-uk Kim {"split_send_frag", OPT_SPLIT_SEND_FRAG, 'p', 887e71b7053SJung-uk Kim "Size used to split data for encrypt pipelines"}, 888e71b7053SJung-uk Kim {"max_pipelines", OPT_MAX_PIPELINES, 'p', 889e71b7053SJung-uk Kim "Maximum number of encrypt/decrypt pipelines to be used"}, 890e71b7053SJung-uk Kim {"read_buf", OPT_READ_BUF, 'p', 891e71b7053SJung-uk Kim "Default read buffer size to be used for connections"}, 892e71b7053SJung-uk Kim OPT_S_OPTIONS, 893e71b7053SJung-uk Kim OPT_V_OPTIONS, 894e71b7053SJung-uk Kim OPT_X_OPTIONS, 895e71b7053SJung-uk Kim {"nbio", OPT_NBIO, '-', "Use non-blocking IO"}, 896e71b7053SJung-uk Kim {"psk_identity", OPT_PSK_IDENTITY, 's', "PSK identity to expect"}, 897e71b7053SJung-uk Kim #ifndef OPENSSL_NO_PSK 898e71b7053SJung-uk Kim {"psk_hint", OPT_PSK_HINT, 's', "PSK identity hint to use"}, 899e71b7053SJung-uk Kim #endif 900e71b7053SJung-uk Kim {"psk", OPT_PSK, 's', "PSK in hex (without 0x)"}, 901e71b7053SJung-uk Kim {"psk_session", OPT_PSK_SESS, '<', "File to read PSK SSL session from"}, 9021f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP 903e71b7053SJung-uk Kim {"srpvfile", OPT_SRPVFILE, '<', "The verifier file for SRP"}, 904e71b7053SJung-uk Kim {"srpuserseed", OPT_SRPUSERSEED, 's', 905e71b7053SJung-uk Kim "A seed string for a default user salt"}, 906e71b7053SJung-uk Kim #endif 907e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SSL3 908e71b7053SJung-uk Kim {"ssl3", OPT_SSL3, '-', "Just talk SSLv3"}, 909e71b7053SJung-uk Kim #endif 910e71b7053SJung-uk Kim #ifndef OPENSSL_NO_TLS1 911e71b7053SJung-uk Kim {"tls1", OPT_TLS1, '-', "Just talk TLSv1"}, 912e71b7053SJung-uk Kim #endif 913e71b7053SJung-uk Kim #ifndef OPENSSL_NO_TLS1_1 914e71b7053SJung-uk Kim {"tls1_1", OPT_TLS1_1, '-', "Just talk TLSv1.1"}, 915e71b7053SJung-uk Kim #endif 916e71b7053SJung-uk Kim #ifndef OPENSSL_NO_TLS1_2 917e71b7053SJung-uk Kim {"tls1_2", OPT_TLS1_2, '-', "just talk TLSv1.2"}, 918e71b7053SJung-uk Kim #endif 919e71b7053SJung-uk Kim #ifndef OPENSSL_NO_TLS1_3 920e71b7053SJung-uk Kim {"tls1_3", OPT_TLS1_3, '-', "just talk TLSv1.3"}, 921e71b7053SJung-uk Kim #endif 922e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS 923e71b7053SJung-uk Kim {"dtls", OPT_DTLS, '-', "Use any DTLS version"}, 924e71b7053SJung-uk Kim {"timeout", OPT_TIMEOUT, '-', "Enable timeouts"}, 925e71b7053SJung-uk Kim {"mtu", OPT_MTU, 'p', "Set link layer MTU"}, 926e71b7053SJung-uk Kim {"listen", OPT_LISTEN, '-', 927e71b7053SJung-uk Kim "Listen for a DTLS ClientHello with a cookie and then connect"}, 928e71b7053SJung-uk Kim #endif 929e71b7053SJung-uk Kim {"stateless", OPT_STATELESS, '-', "Require TLSv1.3 cookies"}, 930e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS1 931e71b7053SJung-uk Kim {"dtls1", OPT_DTLS1, '-', "Just talk DTLSv1"}, 932e71b7053SJung-uk Kim #endif 933e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS1_2 934e71b7053SJung-uk Kim {"dtls1_2", OPT_DTLS1_2, '-', "Just talk DTLSv1.2"}, 935e71b7053SJung-uk Kim #endif 936e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SCTP 937e71b7053SJung-uk Kim {"sctp", OPT_SCTP, '-', "Use SCTP"}, 9386935a639SJung-uk Kim {"sctp_label_bug", OPT_SCTP_LABEL_BUG, '-', "Enable SCTP label length bug"}, 939e71b7053SJung-uk Kim #endif 940e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DH 941e71b7053SJung-uk Kim {"no_dhe", OPT_NO_DHE, '-', "Disable ephemeral DH"}, 942e71b7053SJung-uk Kim #endif 943e71b7053SJung-uk Kim #ifndef OPENSSL_NO_NEXTPROTONEG 944e71b7053SJung-uk Kim {"nextprotoneg", OPT_NEXTPROTONEG, 's', 945e71b7053SJung-uk Kim "Set the advertised protocols for the NPN extension (comma-separated list)"}, 9461f13597dSJung-uk Kim #endif 94709286989SJung-uk Kim #ifndef OPENSSL_NO_SRTP 948e71b7053SJung-uk Kim {"use_srtp", OPT_SRTP_PROFILES, 's', 949e71b7053SJung-uk Kim "Offer SRTP key management with a colon-separated profile list"}, 95009286989SJung-uk Kim #endif 951e71b7053SJung-uk Kim {"alpn", OPT_ALPN, 's', 952e71b7053SJung-uk Kim "Set the advertised protocols for the ALPN extension (comma-separated list)"}, 953e71b7053SJung-uk Kim #ifndef OPENSSL_NO_ENGINE 954e71b7053SJung-uk Kim {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, 955e71b7053SJung-uk Kim #endif 956e71b7053SJung-uk Kim {"keylogfile", OPT_KEYLOG_FILE, '>', "Write TLS secrets to file"}, 957e71b7053SJung-uk Kim {"max_early_data", OPT_MAX_EARLY, 'n', 958e71b7053SJung-uk Kim "The maximum number of bytes of early data as advertised in tickets"}, 959e71b7053SJung-uk Kim {"recv_max_early_data", OPT_RECV_MAX_EARLY, 'n', 960e71b7053SJung-uk Kim "The maximum number of bytes of early data (hard limit)"}, 961e71b7053SJung-uk Kim {"early_data", OPT_EARLY_DATA, '-', "Attempt to read early data"}, 962e71b7053SJung-uk Kim {"num_tickets", OPT_S_NUM_TICKETS, 'n', 963e71b7053SJung-uk Kim "The number of TLSv1.3 session tickets that a server will automatically issue" }, 964e71b7053SJung-uk Kim {"anti_replay", OPT_ANTI_REPLAY, '-', "Switch on anti-replay protection (default)"}, 965e71b7053SJung-uk Kim {"no_anti_replay", OPT_NO_ANTI_REPLAY, '-', "Switch off anti-replay protection"}, 966e71b7053SJung-uk Kim {NULL, OPT_EOF, 0, NULL} 967e71b7053SJung-uk Kim }; 968db522d3aSSimon L. B. Nielsen 969e71b7053SJung-uk Kim #define IS_PROT_FLAG(o) \ 970e71b7053SJung-uk Kim (o == OPT_SSL3 || o == OPT_TLS1 || o == OPT_TLS1_1 || o == OPT_TLS1_2 \ 971e71b7053SJung-uk Kim || o == OPT_TLS1_3 || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2) 972e71b7053SJung-uk Kim 973e71b7053SJung-uk Kim int s_server_main(int argc, char *argv[]) 97474664626SKris Kennaway { 975e71b7053SJung-uk Kim ENGINE *engine = NULL; 976e71b7053SJung-uk Kim EVP_PKEY *s_key = NULL, *s_dkey = NULL; 977e71b7053SJung-uk Kim SSL_CONF_CTX *cctx = NULL; 978e71b7053SJung-uk Kim const SSL_METHOD *meth = TLS_server_method(); 979e71b7053SJung-uk Kim SSL_EXCERT *exc = NULL; 980e71b7053SJung-uk Kim STACK_OF(OPENSSL_STRING) *ssl_args = NULL; 981e71b7053SJung-uk Kim STACK_OF(X509) *s_chain = NULL, *s_dchain = NULL; 982e71b7053SJung-uk Kim STACK_OF(X509_CRL) *crls = NULL; 983e71b7053SJung-uk Kim X509 *s_cert = NULL, *s_dcert = NULL; 9841f13597dSJung-uk Kim X509_VERIFY_PARAM *vpm = NULL; 985e71b7053SJung-uk Kim const char *CApath = NULL, *CAfile = NULL, *chCApath = NULL, *chCAfile = NULL; 986e71b7053SJung-uk Kim char *dpassarg = NULL, *dpass = NULL; 987e71b7053SJung-uk Kim char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL; 988e71b7053SJung-uk Kim char *crl_file = NULL, *prog; 989e71b7053SJung-uk Kim #ifdef AF_UNIX 990e71b7053SJung-uk Kim int unlink_unix_path = 0; 991e71b7053SJung-uk Kim #endif 992e71b7053SJung-uk Kim do_server_cb server_cb; 993e71b7053SJung-uk Kim int vpmtouched = 0, build_chain = 0, no_cache = 0, ext_cache = 0; 994dea77ea6SJung-uk Kim #ifndef OPENSSL_NO_DH 995f579bf8eSKris Kennaway char *dhfile = NULL; 996dea77ea6SJung-uk Kim int no_dhe = 0; 997dea77ea6SJung-uk Kim #endif 998e71b7053SJung-uk Kim int nocert = 0, ret = 1; 999e71b7053SJung-uk Kim int noCApath = 0, noCAfile = 0; 10003b4e3dcbSSimon L. B. Nielsen int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM; 10013b4e3dcbSSimon L. B. Nielsen int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM; 1002e71b7053SJung-uk Kim int rev = 0, naccept = -1, sdebug = 0; 1003e71b7053SJung-uk Kim int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM, protocol = 0; 1004e71b7053SJung-uk Kim int state = 0, crl_format = FORMAT_PEM, crl_download = 0; 1005e71b7053SJung-uk Kim char *host = NULL; 1006e71b7053SJung-uk Kim char *port = BUF_strdup(PORT); 1007e71b7053SJung-uk Kim unsigned char *context = NULL; 1008e71b7053SJung-uk Kim OPTION_CHOICE o; 1009db522d3aSSimon L. B. Nielsen EVP_PKEY *s_key2 = NULL; 1010db522d3aSSimon L. B. Nielsen X509 *s_cert2 = NULL; 1011db522d3aSSimon L. B. Nielsen tlsextctx tlsextcbp = { NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING }; 1012e71b7053SJung-uk Kim const char *ssl_config = NULL; 1013e71b7053SJung-uk Kim int read_buf_len = 0; 10141f13597dSJung-uk Kim #ifndef OPENSSL_NO_NEXTPROTONEG 10151f13597dSJung-uk Kim const char *next_proto_neg_in = NULL; 10167bded2dbSJung-uk Kim tlsextnextprotoctx next_proto = { NULL, 0 }; 1017db522d3aSSimon L. B. Nielsen #endif 10187bded2dbSJung-uk Kim const char *alpn_in = NULL; 10197bded2dbSJung-uk Kim tlsextalpnctx alpn_ctx = { NULL, 0 }; 10201f13597dSJung-uk Kim #ifndef OPENSSL_NO_PSK 10211f13597dSJung-uk Kim /* by default do not send a PSK identity hint */ 1022e71b7053SJung-uk Kim char *psk_identity_hint = NULL; 10231f13597dSJung-uk Kim #endif 1024e71b7053SJung-uk Kim char *p; 10251f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP 10261f13597dSJung-uk Kim char *srpuserseed = NULL; 10271f13597dSJung-uk Kim char *srp_verifier_file = NULL; 10281f13597dSJung-uk Kim #endif 1029e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SRTP 1030e71b7053SJung-uk Kim char *srtp_profiles = NULL; 1031e71b7053SJung-uk Kim #endif 1032e71b7053SJung-uk Kim int min_version = 0, max_version = 0, prot_opt = 0, no_prot_opt = 0; 1033e71b7053SJung-uk Kim int s_server_verify = SSL_VERIFY_NONE; 1034e71b7053SJung-uk Kim int s_server_session_id_context = 1; /* anything will do */ 1035e71b7053SJung-uk Kim const char *s_cert_file = TEST_CERT, *s_key_file = NULL, *s_chain_file = NULL; 1036e71b7053SJung-uk Kim const char *s_cert_file2 = TEST_CERT2, *s_key_file2 = NULL; 1037e71b7053SJung-uk Kim char *s_dcert_file = NULL, *s_dkey_file = NULL, *s_dchain_file = NULL; 1038e71b7053SJung-uk Kim #ifndef OPENSSL_NO_OCSP 1039e71b7053SJung-uk Kim int s_tlsextstatus = 0; 1040e71b7053SJung-uk Kim #endif 1041e71b7053SJung-uk Kim int no_resume_ephemeral = 0; 1042e71b7053SJung-uk Kim unsigned int max_send_fragment = 0; 1043e71b7053SJung-uk Kim unsigned int split_send_fragment = 0, max_pipelines = 0; 1044e71b7053SJung-uk Kim const char *s_serverinfo_file = NULL; 1045e71b7053SJung-uk Kim const char *keylog_file = NULL; 1046e71b7053SJung-uk Kim int max_early_data = -1, recv_max_early_data = -1; 1047e71b7053SJung-uk Kim char *psksessf = NULL; 10486935a639SJung-uk Kim #ifndef OPENSSL_NO_SCTP 10496935a639SJung-uk Kim int sctp_label_bug = 0; 10506935a639SJung-uk Kim #endif 10517bded2dbSJung-uk Kim 1052e71b7053SJung-uk Kim /* Init of few remaining global variables */ 105374664626SKris Kennaway local_argc = argc; 105474664626SKris Kennaway local_argv = argv; 105574664626SKris Kennaway 1056e71b7053SJung-uk Kim ctx = ctx2 = NULL; 1057e71b7053SJung-uk Kim s_nbio = s_nbio_test = 0; 1058e71b7053SJung-uk Kim www = 0; 1059e71b7053SJung-uk Kim bio_s_out = NULL; 1060e71b7053SJung-uk Kim s_debug = 0; 1061e71b7053SJung-uk Kim s_msg = 0; 1062e71b7053SJung-uk Kim s_quiet = 0; 1063e71b7053SJung-uk Kim s_brief = 0; 1064e71b7053SJung-uk Kim async = 0; 10655c87c606SMark Murray 10667bded2dbSJung-uk Kim cctx = SSL_CONF_CTX_new(); 1067e71b7053SJung-uk Kim vpm = X509_VERIFY_PARAM_new(); 1068e71b7053SJung-uk Kim if (cctx == NULL || vpm == NULL) 10697bded2dbSJung-uk Kim goto end; 1070e71b7053SJung-uk Kim SSL_CONF_CTX_set_flags(cctx, 1071e71b7053SJung-uk Kim SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CMDLINE); 10727bded2dbSJung-uk Kim 1073e71b7053SJung-uk Kim prog = opt_init(argc, argv, s_server_options); 1074e71b7053SJung-uk Kim while ((o = opt_next()) != OPT_EOF) { 1075e71b7053SJung-uk Kim if (IS_PROT_FLAG(o) && ++prot_opt > 1) { 1076e71b7053SJung-uk Kim BIO_printf(bio_err, "Cannot supply multiple protocol flags\n"); 1077e71b7053SJung-uk Kim goto end; 10787bded2dbSJung-uk Kim } 1079e71b7053SJung-uk Kim if (IS_NO_PROT_FLAG(o)) 1080e71b7053SJung-uk Kim no_prot_opt++; 1081e71b7053SJung-uk Kim if (prot_opt == 1 && no_prot_opt) { 1082e71b7053SJung-uk Kim BIO_printf(bio_err, 1083e71b7053SJung-uk Kim "Cannot supply both a protocol flag and '-no_<prot>'\n"); 1084e71b7053SJung-uk Kim goto end; 1085e71b7053SJung-uk Kim } 1086e71b7053SJung-uk Kim switch (o) { 1087e71b7053SJung-uk Kim case OPT_EOF: 1088e71b7053SJung-uk Kim case OPT_ERR: 1089e71b7053SJung-uk Kim opthelp: 1090e71b7053SJung-uk Kim BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); 1091e71b7053SJung-uk Kim goto end; 1092e71b7053SJung-uk Kim case OPT_HELP: 1093e71b7053SJung-uk Kim opt_help(s_server_options); 1094e71b7053SJung-uk Kim ret = 0; 1095e71b7053SJung-uk Kim goto end; 1096e71b7053SJung-uk Kim 1097e71b7053SJung-uk Kim case OPT_4: 1098e71b7053SJung-uk Kim #ifdef AF_UNIX 1099e71b7053SJung-uk Kim if (socket_family == AF_UNIX) { 1100e71b7053SJung-uk Kim OPENSSL_free(host); host = NULL; 1101e71b7053SJung-uk Kim OPENSSL_free(port); port = NULL; 1102e71b7053SJung-uk Kim } 1103e71b7053SJung-uk Kim #endif 1104e71b7053SJung-uk Kim socket_family = AF_INET; 1105e71b7053SJung-uk Kim break; 1106e71b7053SJung-uk Kim case OPT_6: 1107e71b7053SJung-uk Kim if (1) { 1108e71b7053SJung-uk Kim #ifdef AF_INET6 1109e71b7053SJung-uk Kim #ifdef AF_UNIX 1110e71b7053SJung-uk Kim if (socket_family == AF_UNIX) { 1111e71b7053SJung-uk Kim OPENSSL_free(host); host = NULL; 1112e71b7053SJung-uk Kim OPENSSL_free(port); port = NULL; 1113e71b7053SJung-uk Kim } 1114e71b7053SJung-uk Kim #endif 1115e71b7053SJung-uk Kim socket_family = AF_INET6; 1116e71b7053SJung-uk Kim } else { 1117e71b7053SJung-uk Kim #endif 1118e71b7053SJung-uk Kim BIO_printf(bio_err, "%s: IPv6 domain sockets unsupported\n", prog); 1119e71b7053SJung-uk Kim goto end; 1120e71b7053SJung-uk Kim } 1121e71b7053SJung-uk Kim break; 1122e71b7053SJung-uk Kim case OPT_PORT: 1123e71b7053SJung-uk Kim #ifdef AF_UNIX 1124e71b7053SJung-uk Kim if (socket_family == AF_UNIX) { 1125e71b7053SJung-uk Kim socket_family = AF_UNSPEC; 1126e71b7053SJung-uk Kim } 1127e71b7053SJung-uk Kim #endif 1128e71b7053SJung-uk Kim OPENSSL_free(port); port = NULL; 1129e71b7053SJung-uk Kim OPENSSL_free(host); host = NULL; 1130e71b7053SJung-uk Kim if (BIO_parse_hostserv(opt_arg(), NULL, &port, BIO_PARSE_PRIO_SERV) < 1) { 1131e71b7053SJung-uk Kim BIO_printf(bio_err, 1132e71b7053SJung-uk Kim "%s: -port argument malformed or ambiguous\n", 1133e71b7053SJung-uk Kim port); 1134e71b7053SJung-uk Kim goto end; 1135e71b7053SJung-uk Kim } 1136e71b7053SJung-uk Kim break; 1137e71b7053SJung-uk Kim case OPT_ACCEPT: 1138e71b7053SJung-uk Kim #ifdef AF_UNIX 1139e71b7053SJung-uk Kim if (socket_family == AF_UNIX) { 1140e71b7053SJung-uk Kim socket_family = AF_UNSPEC; 1141e71b7053SJung-uk Kim } 1142e71b7053SJung-uk Kim #endif 1143e71b7053SJung-uk Kim OPENSSL_free(port); port = NULL; 1144e71b7053SJung-uk Kim OPENSSL_free(host); host = NULL; 1145e71b7053SJung-uk Kim if (BIO_parse_hostserv(opt_arg(), &host, &port, BIO_PARSE_PRIO_SERV) < 1) { 1146e71b7053SJung-uk Kim BIO_printf(bio_err, 1147e71b7053SJung-uk Kim "%s: -accept argument malformed or ambiguous\n", 1148e71b7053SJung-uk Kim port); 1149e71b7053SJung-uk Kim goto end; 1150e71b7053SJung-uk Kim } 1151e71b7053SJung-uk Kim break; 1152e71b7053SJung-uk Kim #ifdef AF_UNIX 1153e71b7053SJung-uk Kim case OPT_UNIX: 1154e71b7053SJung-uk Kim socket_family = AF_UNIX; 1155e71b7053SJung-uk Kim OPENSSL_free(host); host = BUF_strdup(opt_arg()); 1156e71b7053SJung-uk Kim OPENSSL_free(port); port = NULL; 1157e71b7053SJung-uk Kim break; 1158e71b7053SJung-uk Kim case OPT_UNLINK: 1159e71b7053SJung-uk Kim unlink_unix_path = 1; 1160e71b7053SJung-uk Kim break; 1161e71b7053SJung-uk Kim #endif 1162e71b7053SJung-uk Kim case OPT_NACCEPT: 1163e71b7053SJung-uk Kim naccept = atol(opt_arg()); 1164e71b7053SJung-uk Kim break; 1165e71b7053SJung-uk Kim case OPT_VERIFY: 116674664626SKris Kennaway s_server_verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; 1167e71b7053SJung-uk Kim verify_args.depth = atoi(opt_arg()); 11687bded2dbSJung-uk Kim if (!s_quiet) 1169e71b7053SJung-uk Kim BIO_printf(bio_err, "verify depth is %d\n", verify_args.depth); 1170e71b7053SJung-uk Kim break; 1171e71b7053SJung-uk Kim case OPT_UPPER_V_VERIFY: 11726f9291ceSJung-uk Kim s_server_verify = 11736f9291ceSJung-uk Kim SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | 117474664626SKris Kennaway SSL_VERIFY_CLIENT_ONCE; 1175e71b7053SJung-uk Kim verify_args.depth = atoi(opt_arg()); 11767bded2dbSJung-uk Kim if (!s_quiet) 11776f9291ceSJung-uk Kim BIO_printf(bio_err, 11786f9291ceSJung-uk Kim "verify depth is %d, must return a certificate\n", 1179e71b7053SJung-uk Kim verify_args.depth); 1180e71b7053SJung-uk Kim break; 1181e71b7053SJung-uk Kim case OPT_CONTEXT: 1182e71b7053SJung-uk Kim context = (unsigned char *)opt_arg(); 1183e71b7053SJung-uk Kim break; 1184e71b7053SJung-uk Kim case OPT_CERT: 1185e71b7053SJung-uk Kim s_cert_file = opt_arg(); 1186e71b7053SJung-uk Kim break; 1187e71b7053SJung-uk Kim case OPT_NAMEOPT: 1188e71b7053SJung-uk Kim if (!set_nameopt(opt_arg())) 1189e71b7053SJung-uk Kim goto end; 1190e71b7053SJung-uk Kim break; 1191e71b7053SJung-uk Kim case OPT_CRL: 1192e71b7053SJung-uk Kim crl_file = opt_arg(); 1193e71b7053SJung-uk Kim break; 1194e71b7053SJung-uk Kim case OPT_CRL_DOWNLOAD: 11957bded2dbSJung-uk Kim crl_download = 1; 1196e71b7053SJung-uk Kim break; 1197e71b7053SJung-uk Kim case OPT_SERVERINFO: 1198e71b7053SJung-uk Kim s_serverinfo_file = opt_arg(); 1199e71b7053SJung-uk Kim break; 1200e71b7053SJung-uk Kim case OPT_CERTFORM: 1201e71b7053SJung-uk Kim if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &s_cert_format)) 1202e71b7053SJung-uk Kim goto opthelp; 1203e71b7053SJung-uk Kim break; 1204e71b7053SJung-uk Kim case OPT_KEY: 1205e71b7053SJung-uk Kim s_key_file = opt_arg(); 1206e71b7053SJung-uk Kim break; 1207e71b7053SJung-uk Kim case OPT_KEYFORM: 1208e71b7053SJung-uk Kim if (!opt_format(opt_arg(), OPT_FMT_ANY, &s_key_format)) 1209e71b7053SJung-uk Kim goto opthelp; 1210e71b7053SJung-uk Kim break; 1211e71b7053SJung-uk Kim case OPT_PASS: 1212e71b7053SJung-uk Kim passarg = opt_arg(); 1213e71b7053SJung-uk Kim break; 1214e71b7053SJung-uk Kim case OPT_CERT_CHAIN: 1215e71b7053SJung-uk Kim s_chain_file = opt_arg(); 1216e71b7053SJung-uk Kim break; 1217e71b7053SJung-uk Kim case OPT_DHPARAM: 1218dea77ea6SJung-uk Kim #ifndef OPENSSL_NO_DH 1219e71b7053SJung-uk Kim dhfile = opt_arg(); 1220dea77ea6SJung-uk Kim #endif 1221e71b7053SJung-uk Kim break; 1222e71b7053SJung-uk Kim case OPT_DCERTFORM: 1223e71b7053SJung-uk Kim if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &s_dcert_format)) 1224e71b7053SJung-uk Kim goto opthelp; 1225e71b7053SJung-uk Kim break; 1226e71b7053SJung-uk Kim case OPT_DCERT: 1227e71b7053SJung-uk Kim s_dcert_file = opt_arg(); 1228e71b7053SJung-uk Kim break; 1229e71b7053SJung-uk Kim case OPT_DKEYFORM: 1230e71b7053SJung-uk Kim if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &s_dkey_format)) 1231e71b7053SJung-uk Kim goto opthelp; 1232e71b7053SJung-uk Kim break; 1233e71b7053SJung-uk Kim case OPT_DPASS: 1234e71b7053SJung-uk Kim dpassarg = opt_arg(); 1235e71b7053SJung-uk Kim break; 1236e71b7053SJung-uk Kim case OPT_DKEY: 1237e71b7053SJung-uk Kim s_dkey_file = opt_arg(); 1238e71b7053SJung-uk Kim break; 1239e71b7053SJung-uk Kim case OPT_DCERT_CHAIN: 1240e71b7053SJung-uk Kim s_dchain_file = opt_arg(); 1241e71b7053SJung-uk Kim break; 1242e71b7053SJung-uk Kim case OPT_NOCERT: 124374664626SKris Kennaway nocert = 1; 1244e71b7053SJung-uk Kim break; 1245e71b7053SJung-uk Kim case OPT_CAPATH: 1246e71b7053SJung-uk Kim CApath = opt_arg(); 1247e71b7053SJung-uk Kim break; 1248e71b7053SJung-uk Kim case OPT_NOCAPATH: 1249e71b7053SJung-uk Kim noCApath = 1; 1250e71b7053SJung-uk Kim break; 1251e71b7053SJung-uk Kim case OPT_CHAINCAPATH: 1252e71b7053SJung-uk Kim chCApath = opt_arg(); 1253e71b7053SJung-uk Kim break; 1254e71b7053SJung-uk Kim case OPT_VERIFYCAPATH: 1255e71b7053SJung-uk Kim vfyCApath = opt_arg(); 1256e71b7053SJung-uk Kim break; 1257e71b7053SJung-uk Kim case OPT_NO_CACHE: 12586a599222SSimon L. B. Nielsen no_cache = 1; 1259e71b7053SJung-uk Kim break; 1260e71b7053SJung-uk Kim case OPT_EXT_CACHE: 12617bded2dbSJung-uk Kim ext_cache = 1; 1262e71b7053SJung-uk Kim break; 1263e71b7053SJung-uk Kim case OPT_CRLFORM: 1264e71b7053SJung-uk Kim if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &crl_format)) 1265e71b7053SJung-uk Kim goto opthelp; 1266e71b7053SJung-uk Kim break; 1267e71b7053SJung-uk Kim case OPT_S_CASES: 1268e71b7053SJung-uk Kim case OPT_S_NUM_TICKETS: 1269e71b7053SJung-uk Kim case OPT_ANTI_REPLAY: 1270e71b7053SJung-uk Kim case OPT_NO_ANTI_REPLAY: 1271e71b7053SJung-uk Kim if (ssl_args == NULL) 1272e71b7053SJung-uk Kim ssl_args = sk_OPENSSL_STRING_new_null(); 1273e71b7053SJung-uk Kim if (ssl_args == NULL 1274e71b7053SJung-uk Kim || !sk_OPENSSL_STRING_push(ssl_args, opt_flag()) 1275e71b7053SJung-uk Kim || !sk_OPENSSL_STRING_push(ssl_args, opt_arg())) { 1276e71b7053SJung-uk Kim BIO_printf(bio_err, "%s: Memory allocation failure\n", prog); 1277e71b7053SJung-uk Kim goto end; 1278e71b7053SJung-uk Kim } 1279e71b7053SJung-uk Kim break; 1280e71b7053SJung-uk Kim case OPT_V_CASES: 1281e71b7053SJung-uk Kim if (!opt_verify(o, vpm)) 1282e71b7053SJung-uk Kim goto end; 1283e71b7053SJung-uk Kim vpmtouched++; 1284e71b7053SJung-uk Kim break; 1285e71b7053SJung-uk Kim case OPT_X_CASES: 1286e71b7053SJung-uk Kim if (!args_excert(o, &exc)) 1287e71b7053SJung-uk Kim goto end; 1288e71b7053SJung-uk Kim break; 1289e71b7053SJung-uk Kim case OPT_VERIFY_RET_ERROR: 1290e71b7053SJung-uk Kim verify_args.return_error = 1; 1291e71b7053SJung-uk Kim break; 1292e71b7053SJung-uk Kim case OPT_VERIFY_QUIET: 1293e71b7053SJung-uk Kim verify_args.quiet = 1; 1294e71b7053SJung-uk Kim break; 1295e71b7053SJung-uk Kim case OPT_BUILD_CHAIN: 12967bded2dbSJung-uk Kim build_chain = 1; 1297e71b7053SJung-uk Kim break; 1298e71b7053SJung-uk Kim case OPT_CAFILE: 1299e71b7053SJung-uk Kim CAfile = opt_arg(); 1300e71b7053SJung-uk Kim break; 1301e71b7053SJung-uk Kim case OPT_NOCAFILE: 1302e71b7053SJung-uk Kim noCAfile = 1; 1303e71b7053SJung-uk Kim break; 1304e71b7053SJung-uk Kim case OPT_CHAINCAFILE: 1305e71b7053SJung-uk Kim chCAfile = opt_arg(); 1306e71b7053SJung-uk Kim break; 1307e71b7053SJung-uk Kim case OPT_VERIFYCAFILE: 1308e71b7053SJung-uk Kim vfyCAfile = opt_arg(); 1309e71b7053SJung-uk Kim break; 1310e71b7053SJung-uk Kim case OPT_NBIO: 13116f9291ceSJung-uk Kim s_nbio = 1; 1312e71b7053SJung-uk Kim break; 1313e71b7053SJung-uk Kim case OPT_NBIO_TEST: 1314e71b7053SJung-uk Kim s_nbio = s_nbio_test = 1; 1315e71b7053SJung-uk Kim break; 1316e71b7053SJung-uk Kim case OPT_IGN_EOF: 13177bded2dbSJung-uk Kim s_ign_eof = 1; 1318e71b7053SJung-uk Kim break; 1319e71b7053SJung-uk Kim case OPT_NO_IGN_EOF: 13207bded2dbSJung-uk Kim s_ign_eof = 0; 1321e71b7053SJung-uk Kim break; 1322e71b7053SJung-uk Kim case OPT_DEBUG: 13236f9291ceSJung-uk Kim s_debug = 1; 1324e71b7053SJung-uk Kim break; 1325e71b7053SJung-uk Kim case OPT_TLSEXTDEBUG: 1326db522d3aSSimon L. B. Nielsen s_tlsextdebug = 1; 1327e71b7053SJung-uk Kim break; 1328e71b7053SJung-uk Kim case OPT_STATUS: 1329e71b7053SJung-uk Kim #ifndef OPENSSL_NO_OCSP 1330db522d3aSSimon L. B. Nielsen s_tlsextstatus = 1; 1331e71b7053SJung-uk Kim #endif 1332e71b7053SJung-uk Kim break; 1333e71b7053SJung-uk Kim case OPT_STATUS_VERBOSE: 1334e71b7053SJung-uk Kim #ifndef OPENSSL_NO_OCSP 1335e71b7053SJung-uk Kim s_tlsextstatus = tlscstatp.verbose = 1; 1336e71b7053SJung-uk Kim #endif 1337e71b7053SJung-uk Kim break; 1338e71b7053SJung-uk Kim case OPT_STATUS_TIMEOUT: 1339e71b7053SJung-uk Kim #ifndef OPENSSL_NO_OCSP 1340db522d3aSSimon L. B. Nielsen s_tlsextstatus = 1; 1341e71b7053SJung-uk Kim tlscstatp.timeout = atoi(opt_arg()); 1342e71b7053SJung-uk Kim #endif 1343e71b7053SJung-uk Kim break; 1344e71b7053SJung-uk Kim case OPT_STATUS_URL: 1345e71b7053SJung-uk Kim #ifndef OPENSSL_NO_OCSP 1346db522d3aSSimon L. B. Nielsen s_tlsextstatus = 1; 1347e71b7053SJung-uk Kim if (!OCSP_parse_url(opt_arg(), 1348db522d3aSSimon L. B. Nielsen &tlscstatp.host, 1349db522d3aSSimon L. B. Nielsen &tlscstatp.port, 13506f9291ceSJung-uk Kim &tlscstatp.path, &tlscstatp.use_ssl)) { 1351db522d3aSSimon L. B. Nielsen BIO_printf(bio_err, "Error parsing URL\n"); 135274664626SKris Kennaway goto end; 135374664626SKris Kennaway } 1354e71b7053SJung-uk Kim #endif 1355e71b7053SJung-uk Kim break; 1356e71b7053SJung-uk Kim case OPT_STATUS_FILE: 1357e71b7053SJung-uk Kim #ifndef OPENSSL_NO_OCSP 1358e71b7053SJung-uk Kim s_tlsextstatus = 1; 1359e71b7053SJung-uk Kim tlscstatp.respin = opt_arg(); 1360e71b7053SJung-uk Kim #endif 1361e71b7053SJung-uk Kim break; 1362e71b7053SJung-uk Kim case OPT_MSG: 1363e71b7053SJung-uk Kim s_msg = 1; 1364e71b7053SJung-uk Kim break; 1365e71b7053SJung-uk Kim case OPT_MSGFILE: 1366e71b7053SJung-uk Kim bio_s_msg = BIO_new_file(opt_arg(), "w"); 1367e71b7053SJung-uk Kim break; 1368e71b7053SJung-uk Kim case OPT_TRACE: 1369e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SSL_TRACE 1370e71b7053SJung-uk Kim s_msg = 2; 1371e71b7053SJung-uk Kim #endif 1372e71b7053SJung-uk Kim break; 1373e71b7053SJung-uk Kim case OPT_SECURITY_DEBUG: 1374e71b7053SJung-uk Kim sdebug = 1; 1375e71b7053SJung-uk Kim break; 1376e71b7053SJung-uk Kim case OPT_SECURITY_DEBUG_VERBOSE: 1377e71b7053SJung-uk Kim sdebug = 2; 1378e71b7053SJung-uk Kim break; 1379e71b7053SJung-uk Kim case OPT_STATE: 1380e71b7053SJung-uk Kim state = 1; 1381e71b7053SJung-uk Kim break; 1382e71b7053SJung-uk Kim case OPT_CRLF: 1383e71b7053SJung-uk Kim s_crlf = 1; 1384e71b7053SJung-uk Kim break; 1385e71b7053SJung-uk Kim case OPT_QUIET: 1386e71b7053SJung-uk Kim s_quiet = 1; 1387e71b7053SJung-uk Kim break; 1388e71b7053SJung-uk Kim case OPT_BRIEF: 1389e71b7053SJung-uk Kim s_quiet = s_brief = verify_args.quiet = 1; 1390e71b7053SJung-uk Kim break; 1391e71b7053SJung-uk Kim case OPT_NO_DHE: 1392e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DH 1393e71b7053SJung-uk Kim no_dhe = 1; 1394e71b7053SJung-uk Kim #endif 1395e71b7053SJung-uk Kim break; 1396e71b7053SJung-uk Kim case OPT_NO_RESUME_EPHEMERAL: 1397e71b7053SJung-uk Kim no_resume_ephemeral = 1; 1398e71b7053SJung-uk Kim break; 1399e71b7053SJung-uk Kim case OPT_PSK_IDENTITY: 1400e71b7053SJung-uk Kim psk_identity = opt_arg(); 1401e71b7053SJung-uk Kim break; 1402e71b7053SJung-uk Kim case OPT_PSK_HINT: 1403e71b7053SJung-uk Kim #ifndef OPENSSL_NO_PSK 1404e71b7053SJung-uk Kim psk_identity_hint = opt_arg(); 1405e71b7053SJung-uk Kim #endif 1406e71b7053SJung-uk Kim break; 1407e71b7053SJung-uk Kim case OPT_PSK: 1408e71b7053SJung-uk Kim for (p = psk_key = opt_arg(); *p; p++) { 1409e71b7053SJung-uk Kim if (isxdigit(_UC(*p))) 1410e71b7053SJung-uk Kim continue; 14116935a639SJung-uk Kim BIO_printf(bio_err, "Not a hex number '%s'\n", psk_key); 1412e71b7053SJung-uk Kim goto end; 1413e71b7053SJung-uk Kim } 1414e71b7053SJung-uk Kim break; 1415e71b7053SJung-uk Kim case OPT_PSK_SESS: 1416e71b7053SJung-uk Kim psksessf = opt_arg(); 1417e71b7053SJung-uk Kim break; 1418e71b7053SJung-uk Kim case OPT_SRPVFILE: 1419e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SRP 1420e71b7053SJung-uk Kim srp_verifier_file = opt_arg(); 1421e71b7053SJung-uk Kim if (min_version < TLS1_VERSION) 1422e71b7053SJung-uk Kim min_version = TLS1_VERSION; 1423e71b7053SJung-uk Kim #endif 1424e71b7053SJung-uk Kim break; 1425e71b7053SJung-uk Kim case OPT_SRPUSERSEED: 1426e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SRP 1427e71b7053SJung-uk Kim srpuserseed = opt_arg(); 1428e71b7053SJung-uk Kim if (min_version < TLS1_VERSION) 1429e71b7053SJung-uk Kim min_version = TLS1_VERSION; 1430e71b7053SJung-uk Kim #endif 1431e71b7053SJung-uk Kim break; 1432e71b7053SJung-uk Kim case OPT_REV: 1433e71b7053SJung-uk Kim rev = 1; 1434e71b7053SJung-uk Kim break; 1435e71b7053SJung-uk Kim case OPT_WWW: 1436e71b7053SJung-uk Kim www = 1; 1437e71b7053SJung-uk Kim break; 1438e71b7053SJung-uk Kim case OPT_UPPER_WWW: 1439e71b7053SJung-uk Kim www = 2; 1440e71b7053SJung-uk Kim break; 1441e71b7053SJung-uk Kim case OPT_HTTP: 1442e71b7053SJung-uk Kim www = 3; 1443e71b7053SJung-uk Kim break; 1444e71b7053SJung-uk Kim case OPT_SSL_CONFIG: 1445e71b7053SJung-uk Kim ssl_config = opt_arg(); 1446e71b7053SJung-uk Kim break; 1447e71b7053SJung-uk Kim case OPT_SSL3: 1448e71b7053SJung-uk Kim min_version = SSL3_VERSION; 1449e71b7053SJung-uk Kim max_version = SSL3_VERSION; 1450e71b7053SJung-uk Kim break; 1451e71b7053SJung-uk Kim case OPT_TLS1_3: 1452e71b7053SJung-uk Kim min_version = TLS1_3_VERSION; 1453e71b7053SJung-uk Kim max_version = TLS1_3_VERSION; 1454e71b7053SJung-uk Kim break; 1455e71b7053SJung-uk Kim case OPT_TLS1_2: 1456e71b7053SJung-uk Kim min_version = TLS1_2_VERSION; 1457e71b7053SJung-uk Kim max_version = TLS1_2_VERSION; 1458e71b7053SJung-uk Kim break; 1459e71b7053SJung-uk Kim case OPT_TLS1_1: 1460e71b7053SJung-uk Kim min_version = TLS1_1_VERSION; 1461e71b7053SJung-uk Kim max_version = TLS1_1_VERSION; 1462e71b7053SJung-uk Kim break; 1463e71b7053SJung-uk Kim case OPT_TLS1: 1464e71b7053SJung-uk Kim min_version = TLS1_VERSION; 1465e71b7053SJung-uk Kim max_version = TLS1_VERSION; 1466e71b7053SJung-uk Kim break; 1467e71b7053SJung-uk Kim case OPT_DTLS: 1468e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS 1469e71b7053SJung-uk Kim meth = DTLS_server_method(); 1470e71b7053SJung-uk Kim socket_type = SOCK_DGRAM; 1471e71b7053SJung-uk Kim #endif 1472e71b7053SJung-uk Kim break; 1473e71b7053SJung-uk Kim case OPT_DTLS1: 1474e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS 1475e71b7053SJung-uk Kim meth = DTLS_server_method(); 1476e71b7053SJung-uk Kim min_version = DTLS1_VERSION; 1477e71b7053SJung-uk Kim max_version = DTLS1_VERSION; 1478e71b7053SJung-uk Kim socket_type = SOCK_DGRAM; 1479e71b7053SJung-uk Kim #endif 1480e71b7053SJung-uk Kim break; 1481e71b7053SJung-uk Kim case OPT_DTLS1_2: 1482e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS 1483e71b7053SJung-uk Kim meth = DTLS_server_method(); 1484e71b7053SJung-uk Kim min_version = DTLS1_2_VERSION; 1485e71b7053SJung-uk Kim max_version = DTLS1_2_VERSION; 1486e71b7053SJung-uk Kim socket_type = SOCK_DGRAM; 1487e71b7053SJung-uk Kim #endif 1488e71b7053SJung-uk Kim break; 1489e71b7053SJung-uk Kim case OPT_SCTP: 1490e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SCTP 1491e71b7053SJung-uk Kim protocol = IPPROTO_SCTP; 1492e71b7053SJung-uk Kim #endif 1493e71b7053SJung-uk Kim break; 14946935a639SJung-uk Kim case OPT_SCTP_LABEL_BUG: 14956935a639SJung-uk Kim #ifndef OPENSSL_NO_SCTP 14966935a639SJung-uk Kim sctp_label_bug = 1; 14976935a639SJung-uk Kim #endif 14986935a639SJung-uk Kim break; 1499e71b7053SJung-uk Kim case OPT_TIMEOUT: 1500e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS 1501e71b7053SJung-uk Kim enable_timeouts = 1; 1502e71b7053SJung-uk Kim #endif 1503e71b7053SJung-uk Kim break; 1504e71b7053SJung-uk Kim case OPT_MTU: 1505e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS 1506e71b7053SJung-uk Kim socket_mtu = atol(opt_arg()); 1507e71b7053SJung-uk Kim #endif 1508e71b7053SJung-uk Kim break; 1509e71b7053SJung-uk Kim case OPT_LISTEN: 1510e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS 1511e71b7053SJung-uk Kim dtlslisten = 1; 1512e71b7053SJung-uk Kim #endif 1513e71b7053SJung-uk Kim break; 1514e71b7053SJung-uk Kim case OPT_STATELESS: 1515e71b7053SJung-uk Kim stateless = 1; 1516e71b7053SJung-uk Kim break; 1517e71b7053SJung-uk Kim case OPT_ID_PREFIX: 1518e71b7053SJung-uk Kim session_id_prefix = opt_arg(); 1519e71b7053SJung-uk Kim break; 1520e71b7053SJung-uk Kim case OPT_ENGINE: 1521e71b7053SJung-uk Kim engine = setup_engine(opt_arg(), 1); 1522e71b7053SJung-uk Kim break; 1523e71b7053SJung-uk Kim case OPT_R_CASES: 1524e71b7053SJung-uk Kim if (!opt_rand(o)) 1525e71b7053SJung-uk Kim goto end; 1526e71b7053SJung-uk Kim break; 1527e71b7053SJung-uk Kim case OPT_SERVERNAME: 1528e71b7053SJung-uk Kim tlsextcbp.servername = opt_arg(); 1529e71b7053SJung-uk Kim break; 1530e71b7053SJung-uk Kim case OPT_SERVERNAME_FATAL: 1531e71b7053SJung-uk Kim tlsextcbp.extension_error = SSL_TLSEXT_ERR_ALERT_FATAL; 1532e71b7053SJung-uk Kim break; 1533e71b7053SJung-uk Kim case OPT_CERT2: 1534e71b7053SJung-uk Kim s_cert_file2 = opt_arg(); 1535e71b7053SJung-uk Kim break; 1536e71b7053SJung-uk Kim case OPT_KEY2: 1537e71b7053SJung-uk Kim s_key_file2 = opt_arg(); 1538e71b7053SJung-uk Kim break; 1539e71b7053SJung-uk Kim case OPT_NEXTPROTONEG: 1540e71b7053SJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG 1541e71b7053SJung-uk Kim next_proto_neg_in = opt_arg(); 1542e71b7053SJung-uk Kim #endif 1543e71b7053SJung-uk Kim break; 1544e71b7053SJung-uk Kim case OPT_ALPN: 1545e71b7053SJung-uk Kim alpn_in = opt_arg(); 1546e71b7053SJung-uk Kim break; 1547e71b7053SJung-uk Kim case OPT_SRTP_PROFILES: 1548e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SRTP 1549e71b7053SJung-uk Kim srtp_profiles = opt_arg(); 1550e71b7053SJung-uk Kim #endif 1551e71b7053SJung-uk Kim break; 1552e71b7053SJung-uk Kim case OPT_KEYMATEXPORT: 1553e71b7053SJung-uk Kim keymatexportlabel = opt_arg(); 1554e71b7053SJung-uk Kim break; 1555e71b7053SJung-uk Kim case OPT_KEYMATEXPORTLEN: 1556e71b7053SJung-uk Kim keymatexportlen = atoi(opt_arg()); 1557e71b7053SJung-uk Kim break; 1558e71b7053SJung-uk Kim case OPT_ASYNC: 1559e71b7053SJung-uk Kim async = 1; 1560e71b7053SJung-uk Kim break; 1561e71b7053SJung-uk Kim case OPT_MAX_SEND_FRAG: 1562e71b7053SJung-uk Kim max_send_fragment = atoi(opt_arg()); 1563e71b7053SJung-uk Kim break; 1564e71b7053SJung-uk Kim case OPT_SPLIT_SEND_FRAG: 1565e71b7053SJung-uk Kim split_send_fragment = atoi(opt_arg()); 1566e71b7053SJung-uk Kim break; 1567e71b7053SJung-uk Kim case OPT_MAX_PIPELINES: 1568e71b7053SJung-uk Kim max_pipelines = atoi(opt_arg()); 1569e71b7053SJung-uk Kim break; 1570e71b7053SJung-uk Kim case OPT_READ_BUF: 1571e71b7053SJung-uk Kim read_buf_len = atoi(opt_arg()); 1572e71b7053SJung-uk Kim break; 1573e71b7053SJung-uk Kim case OPT_KEYLOG_FILE: 1574e71b7053SJung-uk Kim keylog_file = opt_arg(); 1575e71b7053SJung-uk Kim break; 1576e71b7053SJung-uk Kim case OPT_MAX_EARLY: 1577e71b7053SJung-uk Kim max_early_data = atoi(opt_arg()); 1578e71b7053SJung-uk Kim if (max_early_data < 0) { 1579e71b7053SJung-uk Kim BIO_printf(bio_err, "Invalid value for max_early_data\n"); 1580e71b7053SJung-uk Kim goto end; 1581e71b7053SJung-uk Kim } 1582e71b7053SJung-uk Kim break; 1583e71b7053SJung-uk Kim case OPT_RECV_MAX_EARLY: 1584e71b7053SJung-uk Kim recv_max_early_data = atoi(opt_arg()); 1585e71b7053SJung-uk Kim if (recv_max_early_data < 0) { 1586e71b7053SJung-uk Kim BIO_printf(bio_err, "Invalid value for recv_max_early_data\n"); 1587e71b7053SJung-uk Kim goto end; 1588e71b7053SJung-uk Kim } 1589e71b7053SJung-uk Kim break; 1590e71b7053SJung-uk Kim case OPT_EARLY_DATA: 1591e71b7053SJung-uk Kim early_data = 1; 1592e71b7053SJung-uk Kim if (max_early_data == -1) 1593e71b7053SJung-uk Kim max_early_data = SSL3_RT_MAX_PLAIN_LENGTH; 1594e71b7053SJung-uk Kim break; 1595e71b7053SJung-uk Kim } 1596e71b7053SJung-uk Kim } 1597e71b7053SJung-uk Kim argc = opt_num_rest(); 1598e71b7053SJung-uk Kim argv = opt_rest(); 1599e71b7053SJung-uk Kim 1600e71b7053SJung-uk Kim #ifndef OPENSSL_NO_NEXTPROTONEG 1601e71b7053SJung-uk Kim if (min_version == TLS1_3_VERSION && next_proto_neg_in != NULL) { 1602e71b7053SJung-uk Kim BIO_printf(bio_err, "Cannot supply -nextprotoneg with TLSv1.3\n"); 1603e71b7053SJung-uk Kim goto opthelp; 1604e71b7053SJung-uk Kim } 1605e71b7053SJung-uk Kim #endif 1606e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS 16076f9291ceSJung-uk Kim if (www && socket_type == SOCK_DGRAM) { 16086f9291ceSJung-uk Kim BIO_printf(bio_err, "Can't use -HTTP, -www or -WWW with DTLS\n"); 1609a93cbc2bSJung-uk Kim goto end; 1610a93cbc2bSJung-uk Kim } 161174664626SKris Kennaway 1612e71b7053SJung-uk Kim if (dtlslisten && socket_type != SOCK_DGRAM) { 1613e71b7053SJung-uk Kim BIO_printf(bio_err, "Can only use -listen with DTLS\n"); 16141f13597dSJung-uk Kim goto end; 16151f13597dSJung-uk Kim } 16161f13597dSJung-uk Kim #endif 16171f13597dSJung-uk Kim 1618e71b7053SJung-uk Kim if (stateless && socket_type != SOCK_STREAM) { 1619e71b7053SJung-uk Kim BIO_printf(bio_err, "Can only use --stateless with TLS\n"); 1620aeb5019cSJung-uk Kim goto end; 1621aeb5019cSJung-uk Kim } 1622aeb5019cSJung-uk Kim 1623e71b7053SJung-uk Kim #ifdef AF_UNIX 1624e71b7053SJung-uk Kim if (socket_family == AF_UNIX && socket_type != SOCK_STREAM) { 1625e71b7053SJung-uk Kim BIO_printf(bio_err, 1626e71b7053SJung-uk Kim "Can't use unix sockets and datagrams together\n"); 1627aeb5019cSJung-uk Kim goto end; 1628aeb5019cSJung-uk Kim } 1629e71b7053SJung-uk Kim #endif 1630c9cf7b5cSJung-uk Kim if (early_data && (www > 0 || rev)) { 1631c9cf7b5cSJung-uk Kim BIO_printf(bio_err, 1632c9cf7b5cSJung-uk Kim "Can't use -early_data in combination with -www, -WWW, -HTTP, or -rev\n"); 1633c9cf7b5cSJung-uk Kim goto end; 1634c9cf7b5cSJung-uk Kim } 1635aeb5019cSJung-uk Kim 1636e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SCTP 1637e71b7053SJung-uk Kim if (protocol == IPPROTO_SCTP) { 1638e71b7053SJung-uk Kim if (socket_type != SOCK_DGRAM) { 1639e71b7053SJung-uk Kim BIO_printf(bio_err, "Can't use -sctp without DTLS\n"); 1640e71b7053SJung-uk Kim goto end; 1641e71b7053SJung-uk Kim } 1642e71b7053SJung-uk Kim /* SCTP is unusual. It uses DTLS over a SOCK_STREAM protocol */ 1643e71b7053SJung-uk Kim socket_type = SOCK_STREAM; 1644e71b7053SJung-uk Kim } 1645e71b7053SJung-uk Kim #endif 16465c87c606SMark Murray 1647e71b7053SJung-uk Kim if (!app_passwd(passarg, dpassarg, &pass, &dpass)) { 16483b4e3dcbSSimon L. B. Nielsen BIO_printf(bio_err, "Error getting password\n"); 16493b4e3dcbSSimon L. B. Nielsen goto end; 16503b4e3dcbSSimon L. B. Nielsen } 16513b4e3dcbSSimon L. B. Nielsen 16523b4e3dcbSSimon L. B. Nielsen if (s_key_file == NULL) 16533b4e3dcbSSimon L. B. Nielsen s_key_file = s_cert_file; 1654e71b7053SJung-uk Kim 1655db522d3aSSimon L. B. Nielsen if (s_key_file2 == NULL) 1656db522d3aSSimon L. B. Nielsen s_key_file2 = s_cert_file2; 16573b4e3dcbSSimon L. B. Nielsen 1658e71b7053SJung-uk Kim if (!load_excert(&exc)) 16597bded2dbSJung-uk Kim goto end; 16607bded2dbSJung-uk Kim 16616f9291ceSJung-uk Kim if (nocert == 0) { 1662e71b7053SJung-uk Kim s_key = load_key(s_key_file, s_key_format, 0, pass, engine, 16633b4e3dcbSSimon L. B. Nielsen "server certificate private key file"); 1664e71b7053SJung-uk Kim if (s_key == NULL) { 16653b4e3dcbSSimon L. B. Nielsen ERR_print_errors(bio_err); 16663b4e3dcbSSimon L. B. Nielsen goto end; 16673b4e3dcbSSimon L. B. Nielsen } 16683b4e3dcbSSimon L. B. Nielsen 1669e71b7053SJung-uk Kim s_cert = load_cert(s_cert_file, s_cert_format, 1670e71b7053SJung-uk Kim "server certificate file"); 16713b4e3dcbSSimon L. B. Nielsen 1672e71b7053SJung-uk Kim if (s_cert == NULL) { 16733b4e3dcbSSimon L. B. Nielsen ERR_print_errors(bio_err); 16743b4e3dcbSSimon L. B. Nielsen goto end; 16753b4e3dcbSSimon L. B. Nielsen } 1676e71b7053SJung-uk Kim if (s_chain_file != NULL) { 1677e71b7053SJung-uk Kim if (!load_certs(s_chain_file, &s_chain, FORMAT_PEM, NULL, 1678e71b7053SJung-uk Kim "server certificate chain")) 16797bded2dbSJung-uk Kim goto end; 16807bded2dbSJung-uk Kim } 1681e71b7053SJung-uk Kim 1682e71b7053SJung-uk Kim if (tlsextcbp.servername != NULL) { 1683e71b7053SJung-uk Kim s_key2 = load_key(s_key_file2, s_key_format, 0, pass, engine, 1684db522d3aSSimon L. B. Nielsen "second server certificate private key file"); 1685e71b7053SJung-uk Kim if (s_key2 == NULL) { 1686db522d3aSSimon L. B. Nielsen ERR_print_errors(bio_err); 1687db522d3aSSimon L. B. Nielsen goto end; 16883b4e3dcbSSimon L. B. Nielsen } 16893b4e3dcbSSimon L. B. Nielsen 1690e71b7053SJung-uk Kim s_cert2 = load_cert(s_cert_file2, s_cert_format, 1691e71b7053SJung-uk Kim "second server certificate file"); 1692db522d3aSSimon L. B. Nielsen 1693e71b7053SJung-uk Kim if (s_cert2 == NULL) { 1694db522d3aSSimon L. B. Nielsen ERR_print_errors(bio_err); 1695db522d3aSSimon L. B. Nielsen goto end; 1696db522d3aSSimon L. B. Nielsen } 1697db522d3aSSimon L. B. Nielsen } 169809286989SJung-uk Kim } 16997bded2dbSJung-uk Kim #if !defined(OPENSSL_NO_NEXTPROTONEG) 17006f9291ceSJung-uk Kim if (next_proto_neg_in) { 1701e71b7053SJung-uk Kim next_proto.data = next_protos_parse(&next_proto.len, next_proto_neg_in); 17021f13597dSJung-uk Kim if (next_proto.data == NULL) 17031f13597dSJung-uk Kim goto end; 17041f13597dSJung-uk Kim } 17051f13597dSJung-uk Kim #endif 17067bded2dbSJung-uk Kim alpn_ctx.data = NULL; 17077bded2dbSJung-uk Kim if (alpn_in) { 1708e71b7053SJung-uk Kim alpn_ctx.data = next_protos_parse(&alpn_ctx.len, alpn_in); 17097bded2dbSJung-uk Kim if (alpn_ctx.data == NULL) 17107bded2dbSJung-uk Kim goto end; 17117bded2dbSJung-uk Kim } 17127bded2dbSJung-uk Kim 1713e71b7053SJung-uk Kim if (crl_file != NULL) { 17147bded2dbSJung-uk Kim X509_CRL *crl; 17157bded2dbSJung-uk Kim crl = load_crl(crl_file, crl_format); 1716e71b7053SJung-uk Kim if (crl == NULL) { 17177bded2dbSJung-uk Kim BIO_puts(bio_err, "Error loading CRL\n"); 17187bded2dbSJung-uk Kim ERR_print_errors(bio_err); 17197bded2dbSJung-uk Kim goto end; 17207bded2dbSJung-uk Kim } 17217bded2dbSJung-uk Kim crls = sk_X509_CRL_new_null(); 1722e71b7053SJung-uk Kim if (crls == NULL || !sk_X509_CRL_push(crls, crl)) { 17237bded2dbSJung-uk Kim BIO_puts(bio_err, "Error adding CRL\n"); 17247bded2dbSJung-uk Kim ERR_print_errors(bio_err); 17257bded2dbSJung-uk Kim X509_CRL_free(crl); 17267bded2dbSJung-uk Kim goto end; 17277bded2dbSJung-uk Kim } 17287bded2dbSJung-uk Kim } 17291f13597dSJung-uk Kim 1730e71b7053SJung-uk Kim if (s_dcert_file != NULL) { 17313b4e3dcbSSimon L. B. Nielsen 17323b4e3dcbSSimon L. B. Nielsen if (s_dkey_file == NULL) 17333b4e3dcbSSimon L. B. Nielsen s_dkey_file = s_dcert_file; 17343b4e3dcbSSimon L. B. Nielsen 1735e71b7053SJung-uk Kim s_dkey = load_key(s_dkey_file, s_dkey_format, 1736e71b7053SJung-uk Kim 0, dpass, engine, "second certificate private key file"); 1737e71b7053SJung-uk Kim if (s_dkey == NULL) { 17383b4e3dcbSSimon L. B. Nielsen ERR_print_errors(bio_err); 17393b4e3dcbSSimon L. B. Nielsen goto end; 17403b4e3dcbSSimon L. B. Nielsen } 17413b4e3dcbSSimon L. B. Nielsen 1742e71b7053SJung-uk Kim s_dcert = load_cert(s_dcert_file, s_dcert_format, 1743e71b7053SJung-uk Kim "second server certificate file"); 17443b4e3dcbSSimon L. B. Nielsen 1745e71b7053SJung-uk Kim if (s_dcert == NULL) { 17463b4e3dcbSSimon L. B. Nielsen ERR_print_errors(bio_err); 17473b4e3dcbSSimon L. B. Nielsen goto end; 17483b4e3dcbSSimon L. B. Nielsen } 1749e71b7053SJung-uk Kim if (s_dchain_file != NULL) { 1750e71b7053SJung-uk Kim if (!load_certs(s_dchain_file, &s_dchain, FORMAT_PEM, NULL, 1751e71b7053SJung-uk Kim "second server certificate chain")) 17527bded2dbSJung-uk Kim goto end; 17537bded2dbSJung-uk Kim } 17543b4e3dcbSSimon L. B. Nielsen 17553b4e3dcbSSimon L. B. Nielsen } 17563b4e3dcbSSimon L. B. Nielsen 17576f9291ceSJung-uk Kim if (bio_s_out == NULL) { 17587bded2dbSJung-uk Kim if (s_quiet && !s_debug) { 175974664626SKris Kennaway bio_s_out = BIO_new(BIO_s_null()); 1760e71b7053SJung-uk Kim if (s_msg && bio_s_msg == NULL) 1761e71b7053SJung-uk Kim bio_s_msg = dup_bio_out(FORMAT_TEXT); 17626f9291ceSJung-uk Kim } else { 176374664626SKris Kennaway if (bio_s_out == NULL) 1764e71b7053SJung-uk Kim bio_s_out = dup_bio_out(FORMAT_TEXT); 176574664626SKris Kennaway } 176674664626SKris Kennaway } 1767e71b7053SJung-uk Kim #if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC) 176874664626SKris Kennaway if (nocert) 176974664626SKris Kennaway #endif 177074664626SKris Kennaway { 177174664626SKris Kennaway s_cert_file = NULL; 177274664626SKris Kennaway s_key_file = NULL; 177374664626SKris Kennaway s_dcert_file = NULL; 177474664626SKris Kennaway s_dkey_file = NULL; 1775db522d3aSSimon L. B. Nielsen s_cert_file2 = NULL; 1776db522d3aSSimon L. B. Nielsen s_key_file2 = NULL; 177774664626SKris Kennaway } 177874664626SKris Kennaway 177974664626SKris Kennaway ctx = SSL_CTX_new(meth); 17806f9291ceSJung-uk Kim if (ctx == NULL) { 178174664626SKris Kennaway ERR_print_errors(bio_err); 178274664626SKris Kennaway goto end; 178374664626SKris Kennaway } 1784e71b7053SJung-uk Kim 1785e71b7053SJung-uk Kim SSL_CTX_clear_mode(ctx, SSL_MODE_AUTO_RETRY); 1786e71b7053SJung-uk Kim 1787e71b7053SJung-uk Kim if (sdebug) 1788e71b7053SJung-uk Kim ssl_ctx_security_debug(ctx, sdebug); 1789e71b7053SJung-uk Kim 1790e71b7053SJung-uk Kim if (!config_ctx(cctx, ssl_args, ctx)) 1791e71b7053SJung-uk Kim goto end; 1792e71b7053SJung-uk Kim 1793e71b7053SJung-uk Kim if (ssl_config) { 1794e71b7053SJung-uk Kim if (SSL_CTX_config(ctx, ssl_config) == 0) { 1795e71b7053SJung-uk Kim BIO_printf(bio_err, "Error using configuration \"%s\"\n", 1796e71b7053SJung-uk Kim ssl_config); 1797e71b7053SJung-uk Kim ERR_print_errors(bio_err); 1798e71b7053SJung-uk Kim goto end; 1799e71b7053SJung-uk Kim } 1800e71b7053SJung-uk Kim } 18016935a639SJung-uk Kim 18026935a639SJung-uk Kim #ifndef OPENSSL_NO_SCTP 18036935a639SJung-uk Kim if (protocol == IPPROTO_SCTP && sctp_label_bug == 1) 18046935a639SJung-uk Kim SSL_CTX_set_mode(ctx, SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG); 18056935a639SJung-uk Kim #endif 18066935a639SJung-uk Kim 1807e71b7053SJung-uk Kim if (min_version != 0 1808e71b7053SJung-uk Kim && SSL_CTX_set_min_proto_version(ctx, min_version) == 0) 1809e71b7053SJung-uk Kim goto end; 1810e71b7053SJung-uk Kim if (max_version != 0 1811e71b7053SJung-uk Kim && SSL_CTX_set_max_proto_version(ctx, max_version) == 0) 1812e71b7053SJung-uk Kim goto end; 1813e71b7053SJung-uk Kim 18146f9291ceSJung-uk Kim if (session_id_prefix) { 18155c87c606SMark Murray if (strlen(session_id_prefix) >= 32) 18165c87c606SMark Murray BIO_printf(bio_err, 18175c87c606SMark Murray "warning: id_prefix is too long, only one new session will be possible\n"); 18186f9291ceSJung-uk Kim if (!SSL_CTX_set_generate_session_id(ctx, generate_session_id)) { 18195c87c606SMark Murray BIO_printf(bio_err, "error setting 'id_prefix'\n"); 18205c87c606SMark Murray ERR_print_errors(bio_err); 18215c87c606SMark Murray goto end; 18225c87c606SMark Murray } 18235c87c606SMark Murray BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix); 18245c87c606SMark Murray } 182574664626SKris Kennaway SSL_CTX_set_quiet_shutdown(ctx, 1); 1826e71b7053SJung-uk Kim if (exc != NULL) 18277bded2dbSJung-uk Kim ssl_ctx_set_excert(ctx, exc); 182874664626SKris Kennaway 18296f9291ceSJung-uk Kim if (state) 18306f9291ceSJung-uk Kim SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback); 18316a599222SSimon L. B. Nielsen if (no_cache) 18326a599222SSimon L. B. Nielsen SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); 18337bded2dbSJung-uk Kim else if (ext_cache) 18347bded2dbSJung-uk Kim init_session_cache_ctx(ctx); 18356a599222SSimon L. B. Nielsen else 183674664626SKris Kennaway SSL_CTX_sess_set_cache_size(ctx, 128); 183774664626SKris Kennaway 1838e71b7053SJung-uk Kim if (async) { 1839e71b7053SJung-uk Kim SSL_CTX_set_mode(ctx, SSL_MODE_ASYNC); 1840e71b7053SJung-uk Kim } 18411f13597dSJung-uk Kim 1842e71b7053SJung-uk Kim if (max_send_fragment > 0 1843e71b7053SJung-uk Kim && !SSL_CTX_set_max_send_fragment(ctx, max_send_fragment)) { 1844e71b7053SJung-uk Kim BIO_printf(bio_err, "%s: Max send fragment size %u is out of permitted range\n", 1845e71b7053SJung-uk Kim prog, max_send_fragment); 184674664626SKris Kennaway goto end; 184774664626SKris Kennaway } 1848e71b7053SJung-uk Kim 1849e71b7053SJung-uk Kim if (split_send_fragment > 0 1850e71b7053SJung-uk Kim && !SSL_CTX_set_split_send_fragment(ctx, split_send_fragment)) { 1851e71b7053SJung-uk Kim BIO_printf(bio_err, "%s: Split send fragment size %u is out of permitted range\n", 1852e71b7053SJung-uk Kim prog, split_send_fragment); 1853e71b7053SJung-uk Kim goto end; 1854e71b7053SJung-uk Kim } 1855e71b7053SJung-uk Kim if (max_pipelines > 0 1856e71b7053SJung-uk Kim && !SSL_CTX_set_max_pipelines(ctx, max_pipelines)) { 1857e71b7053SJung-uk Kim BIO_printf(bio_err, "%s: Max pipelines %u is out of permitted range\n", 1858e71b7053SJung-uk Kim prog, max_pipelines); 1859e71b7053SJung-uk Kim goto end; 1860e71b7053SJung-uk Kim } 1861e71b7053SJung-uk Kim 1862e71b7053SJung-uk Kim if (read_buf_len > 0) { 1863e71b7053SJung-uk Kim SSL_CTX_set_default_read_buffer_len(ctx, read_buf_len); 1864e71b7053SJung-uk Kim } 1865e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SRTP 1866e71b7053SJung-uk Kim if (srtp_profiles != NULL) { 1867e71b7053SJung-uk Kim /* Returns 0 on success! */ 1868e71b7053SJung-uk Kim if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles) != 0) { 1869e71b7053SJung-uk Kim BIO_printf(bio_err, "Error setting SRTP profile\n"); 1870e71b7053SJung-uk Kim ERR_print_errors(bio_err); 1871e71b7053SJung-uk Kim goto end; 1872e71b7053SJung-uk Kim } 1873e71b7053SJung-uk Kim } 187474664626SKris Kennaway #endif 187574664626SKris Kennaway 1876e71b7053SJung-uk Kim if (!ctx_set_verify_locations(ctx, CAfile, CApath, noCAfile, noCApath)) { 187774664626SKris Kennaway ERR_print_errors(bio_err); 1878e71b7053SJung-uk Kim goto end; 187974664626SKris Kennaway } 1880e71b7053SJung-uk Kim if (vpmtouched && !SSL_CTX_set1_param(ctx, vpm)) { 1881e71b7053SJung-uk Kim BIO_printf(bio_err, "Error setting verify params\n"); 1882e71b7053SJung-uk Kim ERR_print_errors(bio_err); 1883e71b7053SJung-uk Kim goto end; 1884e71b7053SJung-uk Kim } 18851f13597dSJung-uk Kim 18867bded2dbSJung-uk Kim ssl_ctx_add_crls(ctx, crls, 0); 18877bded2dbSJung-uk Kim 18887bded2dbSJung-uk Kim if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile, 18897bded2dbSJung-uk Kim crls, crl_download)) { 18907bded2dbSJung-uk Kim BIO_printf(bio_err, "Error loading store locations\n"); 18917bded2dbSJung-uk Kim ERR_print_errors(bio_err); 18927bded2dbSJung-uk Kim goto end; 18937bded2dbSJung-uk Kim } 1894e71b7053SJung-uk Kim 18956f9291ceSJung-uk Kim if (s_cert2) { 1896db522d3aSSimon L. B. Nielsen ctx2 = SSL_CTX_new(meth); 18976f9291ceSJung-uk Kim if (ctx2 == NULL) { 1898db522d3aSSimon L. B. Nielsen ERR_print_errors(bio_err); 1899db522d3aSSimon L. B. Nielsen goto end; 1900db522d3aSSimon L. B. Nielsen } 1901db522d3aSSimon L. B. Nielsen } 1902db522d3aSSimon L. B. Nielsen 1903e71b7053SJung-uk Kim if (ctx2 != NULL) { 1904db522d3aSSimon L. B. Nielsen BIO_printf(bio_s_out, "Setting secondary ctx parameters\n"); 1905db522d3aSSimon L. B. Nielsen 1906e71b7053SJung-uk Kim if (sdebug) 1907*11c7efe3SJung-uk Kim ssl_ctx_security_debug(ctx2, sdebug); 1908e71b7053SJung-uk Kim 19096f9291ceSJung-uk Kim if (session_id_prefix) { 1910db522d3aSSimon L. B. Nielsen if (strlen(session_id_prefix) >= 32) 1911db522d3aSSimon L. B. Nielsen BIO_printf(bio_err, 1912db522d3aSSimon L. B. Nielsen "warning: id_prefix is too long, only one new session will be possible\n"); 19136f9291ceSJung-uk Kim if (!SSL_CTX_set_generate_session_id(ctx2, generate_session_id)) { 1914db522d3aSSimon L. B. Nielsen BIO_printf(bio_err, "error setting 'id_prefix'\n"); 1915db522d3aSSimon L. B. Nielsen ERR_print_errors(bio_err); 1916db522d3aSSimon L. B. Nielsen goto end; 1917db522d3aSSimon L. B. Nielsen } 1918db522d3aSSimon L. B. Nielsen BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix); 1919db522d3aSSimon L. B. Nielsen } 1920db522d3aSSimon L. B. Nielsen SSL_CTX_set_quiet_shutdown(ctx2, 1); 1921e71b7053SJung-uk Kim if (exc != NULL) 19227bded2dbSJung-uk Kim ssl_ctx_set_excert(ctx2, exc); 1923db522d3aSSimon L. B. Nielsen 19246f9291ceSJung-uk Kim if (state) 19256f9291ceSJung-uk Kim SSL_CTX_set_info_callback(ctx2, apps_ssl_info_callback); 1926db522d3aSSimon L. B. Nielsen 19276a599222SSimon L. B. Nielsen if (no_cache) 19286a599222SSimon L. B. Nielsen SSL_CTX_set_session_cache_mode(ctx2, SSL_SESS_CACHE_OFF); 19297bded2dbSJung-uk Kim else if (ext_cache) 19307bded2dbSJung-uk Kim init_session_cache_ctx(ctx2); 19316a599222SSimon L. B. Nielsen else 1932db522d3aSSimon L. B. Nielsen SSL_CTX_sess_set_cache_size(ctx2, 128); 1933db522d3aSSimon L. B. Nielsen 1934e71b7053SJung-uk Kim if (async) 1935e71b7053SJung-uk Kim SSL_CTX_set_mode(ctx2, SSL_MODE_ASYNC); 1936e71b7053SJung-uk Kim 1937e71b7053SJung-uk Kim if (!ctx_set_verify_locations(ctx2, CAfile, CApath, noCAfile, 1938e71b7053SJung-uk Kim noCApath)) { 1939db522d3aSSimon L. B. Nielsen ERR_print_errors(bio_err); 1940e71b7053SJung-uk Kim goto end; 1941db522d3aSSimon L. B. Nielsen } 1942e71b7053SJung-uk Kim if (vpmtouched && !SSL_CTX_set1_param(ctx2, vpm)) { 1943e71b7053SJung-uk Kim BIO_printf(bio_err, "Error setting verify params\n"); 1944e71b7053SJung-uk Kim ERR_print_errors(bio_err); 1945e71b7053SJung-uk Kim goto end; 1946e71b7053SJung-uk Kim } 19477bded2dbSJung-uk Kim 19487bded2dbSJung-uk Kim ssl_ctx_add_crls(ctx2, crls, 0); 1949e71b7053SJung-uk Kim if (!config_ctx(cctx, ssl_args, ctx2)) 19507bded2dbSJung-uk Kim goto end; 1951db522d3aSSimon L. B. Nielsen } 19521f13597dSJung-uk Kim #ifndef OPENSSL_NO_NEXTPROTONEG 19531f13597dSJung-uk Kim if (next_proto.data) 19546f9291ceSJung-uk Kim SSL_CTX_set_next_protos_advertised_cb(ctx, next_proto_cb, 19556f9291ceSJung-uk Kim &next_proto); 19561f13597dSJung-uk Kim #endif 19577bded2dbSJung-uk Kim if (alpn_ctx.data) 19587bded2dbSJung-uk Kim SSL_CTX_set_alpn_select_cb(ctx, alpn_cb, &alpn_ctx); 195974664626SKris Kennaway 19605c87c606SMark Murray #ifndef OPENSSL_NO_DH 19616f9291ceSJung-uk Kim if (!no_dhe) { 19625c87c606SMark Murray DH *dh = NULL; 19635c87c606SMark Murray 1964e71b7053SJung-uk Kim if (dhfile != NULL) 19655c87c606SMark Murray dh = load_dh_param(dhfile); 1966e71b7053SJung-uk Kim else if (s_cert_file != NULL) 19675c87c606SMark Murray dh = load_dh_param(s_cert_file); 19685c87c606SMark Murray 19696f9291ceSJung-uk Kim if (dh != NULL) { 197074664626SKris Kennaway BIO_printf(bio_s_out, "Setting temp DH parameters\n"); 19716f9291ceSJung-uk Kim } else { 197274664626SKris Kennaway BIO_printf(bio_s_out, "Using default temp DH parameters\n"); 197374664626SKris Kennaway } 197474664626SKris Kennaway (void)BIO_flush(bio_s_out); 197574664626SKris Kennaway 1976e71b7053SJung-uk Kim if (dh == NULL) { 1977e71b7053SJung-uk Kim SSL_CTX_set_dh_auto(ctx, 1); 1978e71b7053SJung-uk Kim } else if (!SSL_CTX_set_tmp_dh(ctx, dh)) { 1979e71b7053SJung-uk Kim BIO_puts(bio_err, "Error setting temp DH parameters\n"); 1980e71b7053SJung-uk Kim ERR_print_errors(bio_err); 1981e71b7053SJung-uk Kim DH_free(dh); 1982e71b7053SJung-uk Kim goto end; 1983e71b7053SJung-uk Kim } 1984e71b7053SJung-uk Kim 1985e71b7053SJung-uk Kim if (ctx2 != NULL) { 19866f9291ceSJung-uk Kim if (!dhfile) { 1987db522d3aSSimon L. B. Nielsen DH *dh2 = load_dh_param(s_cert_file2); 19886f9291ceSJung-uk Kim if (dh2 != NULL) { 1989db522d3aSSimon L. B. Nielsen BIO_printf(bio_s_out, "Setting temp DH parameters\n"); 1990db522d3aSSimon L. B. Nielsen (void)BIO_flush(bio_s_out); 1991db522d3aSSimon L. B. Nielsen 1992db522d3aSSimon L. B. Nielsen DH_free(dh); 1993db522d3aSSimon L. B. Nielsen dh = dh2; 1994db522d3aSSimon L. B. Nielsen } 1995db522d3aSSimon L. B. Nielsen } 1996e71b7053SJung-uk Kim if (dh == NULL) { 1997e71b7053SJung-uk Kim SSL_CTX_set_dh_auto(ctx2, 1); 1998e71b7053SJung-uk Kim } else if (!SSL_CTX_set_tmp_dh(ctx2, dh)) { 1999e71b7053SJung-uk Kim BIO_puts(bio_err, "Error setting temp DH parameters\n"); 2000e71b7053SJung-uk Kim ERR_print_errors(bio_err); 2001e71b7053SJung-uk Kim DH_free(dh); 2002e71b7053SJung-uk Kim goto end; 2003db522d3aSSimon L. B. Nielsen } 2004e71b7053SJung-uk Kim } 200574664626SKris Kennaway DH_free(dh); 200674664626SKris Kennaway } 200774664626SKris Kennaway #endif 200874664626SKris Kennaway 20097bded2dbSJung-uk Kim if (!set_cert_key_stuff(ctx, s_cert, s_key, s_chain, build_chain)) 20103b4e3dcbSSimon L. B. Nielsen goto end; 2011e71b7053SJung-uk Kim 20127bded2dbSJung-uk Kim if (s_serverinfo_file != NULL 20137bded2dbSJung-uk Kim && !SSL_CTX_use_serverinfo_file(ctx, s_serverinfo_file)) { 20147bded2dbSJung-uk Kim ERR_print_errors(bio_err); 20157bded2dbSJung-uk Kim goto end; 20167bded2dbSJung-uk Kim } 2017e71b7053SJung-uk Kim 2018e71b7053SJung-uk Kim if (ctx2 != NULL 2019e71b7053SJung-uk Kim && !set_cert_key_stuff(ctx2, s_cert2, s_key2, NULL, build_chain)) 2020db522d3aSSimon L. B. Nielsen goto end; 2021e71b7053SJung-uk Kim 20226f9291ceSJung-uk Kim if (s_dcert != NULL) { 20237bded2dbSJung-uk Kim if (!set_cert_key_stuff(ctx, s_dcert, s_dkey, s_dchain, build_chain)) 202474664626SKris Kennaway goto end; 202574664626SKris Kennaway } 202674664626SKris Kennaway 2027e71b7053SJung-uk Kim if (no_resume_ephemeral) { 2028e71b7053SJung-uk Kim SSL_CTX_set_not_resumable_session_callback(ctx, 2029e71b7053SJung-uk Kim not_resumable_sess_cb); 203074664626SKris Kennaway 2031e71b7053SJung-uk Kim if (ctx2 != NULL) 2032e71b7053SJung-uk Kim SSL_CTX_set_not_resumable_session_callback(ctx2, 2033e71b7053SJung-uk Kim not_resumable_sess_cb); 203474664626SKris Kennaway } 20351f13597dSJung-uk Kim #ifndef OPENSSL_NO_PSK 2036e71b7053SJung-uk Kim if (psk_key != NULL) { 20371f13597dSJung-uk Kim if (s_debug) 2038e71b7053SJung-uk Kim BIO_printf(bio_s_out, "PSK key given, setting server callback\n"); 20391f13597dSJung-uk Kim SSL_CTX_set_psk_server_callback(ctx, psk_server_cb); 20401f13597dSJung-uk Kim } 20411f13597dSJung-uk Kim 20426f9291ceSJung-uk Kim if (!SSL_CTX_use_psk_identity_hint(ctx, psk_identity_hint)) { 20431f13597dSJung-uk Kim BIO_printf(bio_err, "error setting PSK identity hint to context\n"); 20441f13597dSJung-uk Kim ERR_print_errors(bio_err); 20451f13597dSJung-uk Kim goto end; 20461f13597dSJung-uk Kim } 20471f13597dSJung-uk Kim #endif 2048e71b7053SJung-uk Kim if (psksessf != NULL) { 2049e71b7053SJung-uk Kim BIO *stmp = BIO_new_file(psksessf, "r"); 2050e71b7053SJung-uk Kim 2051e71b7053SJung-uk Kim if (stmp == NULL) { 2052e71b7053SJung-uk Kim BIO_printf(bio_err, "Can't open PSK session file %s\n", psksessf); 2053e71b7053SJung-uk Kim ERR_print_errors(bio_err); 2054e71b7053SJung-uk Kim goto end; 2055e71b7053SJung-uk Kim } 2056e71b7053SJung-uk Kim psksess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL); 2057e71b7053SJung-uk Kim BIO_free(stmp); 2058e71b7053SJung-uk Kim if (psksess == NULL) { 2059e71b7053SJung-uk Kim BIO_printf(bio_err, "Can't read PSK session file %s\n", psksessf); 2060e71b7053SJung-uk Kim ERR_print_errors(bio_err); 2061e71b7053SJung-uk Kim goto end; 2062e71b7053SJung-uk Kim } 2063e71b7053SJung-uk Kim 2064e71b7053SJung-uk Kim } 2065e71b7053SJung-uk Kim 2066e71b7053SJung-uk Kim if (psk_key != NULL || psksess != NULL) 2067e71b7053SJung-uk Kim SSL_CTX_set_psk_find_session_callback(ctx, psk_find_session_cb); 20681f13597dSJung-uk Kim 206974664626SKris Kennaway SSL_CTX_set_verify(ctx, s_server_verify, verify_callback); 2070e71b7053SJung-uk Kim if (!SSL_CTX_set_session_id_context(ctx, 2071e71b7053SJung-uk Kim (void *)&s_server_session_id_context, 2072e71b7053SJung-uk Kim sizeof(s_server_session_id_context))) { 2073e71b7053SJung-uk Kim BIO_printf(bio_err, "error setting session id context\n"); 2074e71b7053SJung-uk Kim ERR_print_errors(bio_err); 2075e71b7053SJung-uk Kim goto end; 2076e71b7053SJung-uk Kim } 207774664626SKris Kennaway 20786a599222SSimon L. B. Nielsen /* Set DTLS cookie generation and verification callbacks */ 20796a599222SSimon L. B. Nielsen SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie_callback); 20806a599222SSimon L. B. Nielsen SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie_callback); 20816a599222SSimon L. B. Nielsen 2082e71b7053SJung-uk Kim /* Set TLS1.3 cookie generation and verification callbacks */ 2083e71b7053SJung-uk Kim SSL_CTX_set_stateless_cookie_generate_cb(ctx, generate_stateless_cookie_callback); 2084e71b7053SJung-uk Kim SSL_CTX_set_stateless_cookie_verify_cb(ctx, verify_stateless_cookie_callback); 208574664626SKris Kennaway 2086e71b7053SJung-uk Kim if (ctx2 != NULL) { 2087e71b7053SJung-uk Kim SSL_CTX_set_verify(ctx2, s_server_verify, verify_callback); 2088e71b7053SJung-uk Kim if (!SSL_CTX_set_session_id_context(ctx2, 2089e71b7053SJung-uk Kim (void *)&s_server_session_id_context, 2090e71b7053SJung-uk Kim sizeof(s_server_session_id_context))) { 2091e71b7053SJung-uk Kim BIO_printf(bio_err, "error setting session id context\n"); 2092e71b7053SJung-uk Kim ERR_print_errors(bio_err); 2093e71b7053SJung-uk Kim goto end; 2094e71b7053SJung-uk Kim } 2095db522d3aSSimon L. B. Nielsen tlsextcbp.biodebug = bio_s_out; 2096db522d3aSSimon L. B. Nielsen SSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb); 2097db522d3aSSimon L. B. Nielsen SSL_CTX_set_tlsext_servername_arg(ctx2, &tlsextcbp); 2098db522d3aSSimon L. B. Nielsen SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); 2099db522d3aSSimon L. B. Nielsen SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp); 2100db522d3aSSimon L. B. Nielsen } 21011f13597dSJung-uk Kim 21021f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP 21036f9291ceSJung-uk Kim if (srp_verifier_file != NULL) { 21041f13597dSJung-uk Kim srp_callback_parm.vb = SRP_VBASE_new(srpuserseed); 21051f13597dSJung-uk Kim srp_callback_parm.user = NULL; 21061f13597dSJung-uk Kim srp_callback_parm.login = NULL; 21076f9291ceSJung-uk Kim if ((ret = 21086f9291ceSJung-uk Kim SRP_VBASE_init(srp_callback_parm.vb, 21096f9291ceSJung-uk Kim srp_verifier_file)) != SRP_NO_ERROR) { 21101f13597dSJung-uk Kim BIO_printf(bio_err, 21111f13597dSJung-uk Kim "Cannot initialize SRP verifier file \"%s\":ret=%d\n", 21121f13597dSJung-uk Kim srp_verifier_file, ret); 21131f13597dSJung-uk Kim goto end; 21141f13597dSJung-uk Kim } 21151f13597dSJung-uk Kim SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_callback); 21161f13597dSJung-uk Kim SSL_CTX_set_srp_cb_arg(ctx, &srp_callback_parm); 21171f13597dSJung-uk Kim SSL_CTX_set_srp_username_callback(ctx, ssl_srp_server_param_cb); 21186f9291ceSJung-uk Kim } else 21191f13597dSJung-uk Kim #endif 21206f9291ceSJung-uk Kim if (CAfile != NULL) { 2121db522d3aSSimon L. B. Nielsen SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(CAfile)); 2122e71b7053SJung-uk Kim 2123db522d3aSSimon L. B. Nielsen if (ctx2) 2124db522d3aSSimon L. B. Nielsen SSL_CTX_set_client_CA_list(ctx2, SSL_load_client_CA_file(CAfile)); 2125db522d3aSSimon L. B. Nielsen } 2126e71b7053SJung-uk Kim #ifndef OPENSSL_NO_OCSP 2127e71b7053SJung-uk Kim if (s_tlsextstatus) { 2128e71b7053SJung-uk Kim SSL_CTX_set_tlsext_status_cb(ctx, cert_status_cb); 2129e71b7053SJung-uk Kim SSL_CTX_set_tlsext_status_arg(ctx, &tlscstatp); 2130e71b7053SJung-uk Kim if (ctx2) { 2131e71b7053SJung-uk Kim SSL_CTX_set_tlsext_status_cb(ctx2, cert_status_cb); 2132e71b7053SJung-uk Kim SSL_CTX_set_tlsext_status_arg(ctx2, &tlscstatp); 2133e71b7053SJung-uk Kim } 2134e71b7053SJung-uk Kim } 2135e71b7053SJung-uk Kim #endif 2136e71b7053SJung-uk Kim if (set_keylog_file(ctx, keylog_file)) 2137e71b7053SJung-uk Kim goto end; 21381f13597dSJung-uk Kim 2139e71b7053SJung-uk Kim if (max_early_data >= 0) 2140e71b7053SJung-uk Kim SSL_CTX_set_max_early_data(ctx, max_early_data); 2141e71b7053SJung-uk Kim if (recv_max_early_data >= 0) 2142e71b7053SJung-uk Kim SSL_CTX_set_recv_max_early_data(ctx, recv_max_early_data); 2143e71b7053SJung-uk Kim 21447bded2dbSJung-uk Kim if (rev) 2145e71b7053SJung-uk Kim server_cb = rev_body; 21467bded2dbSJung-uk Kim else if (www) 2147e71b7053SJung-uk Kim server_cb = www_body; 214874664626SKris Kennaway else 2149e71b7053SJung-uk Kim server_cb = sv_body; 2150e71b7053SJung-uk Kim #ifdef AF_UNIX 2151e71b7053SJung-uk Kim if (socket_family == AF_UNIX 2152e71b7053SJung-uk Kim && unlink_unix_path) 2153e71b7053SJung-uk Kim unlink(host); 2154e71b7053SJung-uk Kim #endif 2155e71b7053SJung-uk Kim do_server(&accept_socket, host, port, socket_family, socket_type, protocol, 2156e71b7053SJung-uk Kim server_cb, context, naccept, bio_s_out); 215774664626SKris Kennaway print_stats(bio_s_out, ctx); 215874664626SKris Kennaway ret = 0; 215974664626SKris Kennaway end: 21606f9291ceSJung-uk Kim SSL_CTX_free(ctx); 2161e71b7053SJung-uk Kim SSL_SESSION_free(psksess); 2162e71b7053SJung-uk Kim set_keylog_file(NULL, NULL); 21633b4e3dcbSSimon L. B. Nielsen X509_free(s_cert); 21647bded2dbSJung-uk Kim sk_X509_CRL_pop_free(crls, X509_CRL_free); 21653b4e3dcbSSimon L. B. Nielsen X509_free(s_dcert); 21663b4e3dcbSSimon L. B. Nielsen EVP_PKEY_free(s_key); 21673b4e3dcbSSimon L. B. Nielsen EVP_PKEY_free(s_dkey); 21687bded2dbSJung-uk Kim sk_X509_pop_free(s_chain, X509_free); 21697bded2dbSJung-uk Kim sk_X509_pop_free(s_dchain, X509_free); 21703b4e3dcbSSimon L. B. Nielsen OPENSSL_free(pass); 21713b4e3dcbSSimon L. B. Nielsen OPENSSL_free(dpass); 2172e71b7053SJung-uk Kim OPENSSL_free(host); 2173e71b7053SJung-uk Kim OPENSSL_free(port); 217409286989SJung-uk Kim X509_VERIFY_PARAM_free(vpm); 21757bded2dbSJung-uk Kim free_sessions(); 217609286989SJung-uk Kim OPENSSL_free(tlscstatp.host); 217709286989SJung-uk Kim OPENSSL_free(tlscstatp.port); 217809286989SJung-uk Kim OPENSSL_free(tlscstatp.path); 21796f9291ceSJung-uk Kim SSL_CTX_free(ctx2); 2180db522d3aSSimon L. B. Nielsen X509_free(s_cert2); 2181db522d3aSSimon L. B. Nielsen EVP_PKEY_free(s_key2); 21827bded2dbSJung-uk Kim #ifndef OPENSSL_NO_NEXTPROTONEG 21837bded2dbSJung-uk Kim OPENSSL_free(next_proto.data); 21847bded2dbSJung-uk Kim #endif 21857bded2dbSJung-uk Kim OPENSSL_free(alpn_ctx.data); 21867bded2dbSJung-uk Kim ssl_excert_free(exc); 21877bded2dbSJung-uk Kim sk_OPENSSL_STRING_free(ssl_args); 21887bded2dbSJung-uk Kim SSL_CONF_CTX_free(cctx); 2189e71b7053SJung-uk Kim release_engine(engine); 219074664626SKris Kennaway BIO_free(bio_s_out); 219174664626SKris Kennaway bio_s_out = NULL; 21927bded2dbSJung-uk Kim BIO_free(bio_s_msg); 21937bded2dbSJung-uk Kim bio_s_msg = NULL; 2194e71b7053SJung-uk Kim #ifdef CHARSET_EBCDIC 2195e71b7053SJung-uk Kim BIO_meth_free(methods_ebcdic); 2196e71b7053SJung-uk Kim #endif 2197e71b7053SJung-uk Kim return ret; 219874664626SKris Kennaway } 219974664626SKris Kennaway 220074664626SKris Kennaway static void print_stats(BIO *bio, SSL_CTX *ssl_ctx) 220174664626SKris Kennaway { 220274664626SKris Kennaway BIO_printf(bio, "%4ld items in the session cache\n", 220374664626SKris Kennaway SSL_CTX_sess_number(ssl_ctx)); 22043b4e3dcbSSimon L. B. Nielsen BIO_printf(bio, "%4ld client connects (SSL_connect())\n", 220574664626SKris Kennaway SSL_CTX_sess_connect(ssl_ctx)); 22063b4e3dcbSSimon L. B. Nielsen BIO_printf(bio, "%4ld client renegotiates (SSL_connect())\n", 220774664626SKris Kennaway SSL_CTX_sess_connect_renegotiate(ssl_ctx)); 22083b4e3dcbSSimon L. B. Nielsen BIO_printf(bio, "%4ld client connects that finished\n", 220974664626SKris Kennaway SSL_CTX_sess_connect_good(ssl_ctx)); 22103b4e3dcbSSimon L. B. Nielsen BIO_printf(bio, "%4ld server accepts (SSL_accept())\n", 221174664626SKris Kennaway SSL_CTX_sess_accept(ssl_ctx)); 22123b4e3dcbSSimon L. B. Nielsen BIO_printf(bio, "%4ld server renegotiates (SSL_accept())\n", 221374664626SKris Kennaway SSL_CTX_sess_accept_renegotiate(ssl_ctx)); 22143b4e3dcbSSimon L. B. Nielsen BIO_printf(bio, "%4ld server accepts that finished\n", 221574664626SKris Kennaway SSL_CTX_sess_accept_good(ssl_ctx)); 22163b4e3dcbSSimon L. B. Nielsen BIO_printf(bio, "%4ld session cache hits\n", SSL_CTX_sess_hits(ssl_ctx)); 22176f9291ceSJung-uk Kim BIO_printf(bio, "%4ld session cache misses\n", 22186f9291ceSJung-uk Kim SSL_CTX_sess_misses(ssl_ctx)); 22196f9291ceSJung-uk Kim BIO_printf(bio, "%4ld session cache timeouts\n", 22206f9291ceSJung-uk Kim SSL_CTX_sess_timeouts(ssl_ctx)); 22216f9291ceSJung-uk Kim BIO_printf(bio, "%4ld callback cache hits\n", 22226f9291ceSJung-uk Kim SSL_CTX_sess_cb_hits(ssl_ctx)); 22233b4e3dcbSSimon L. B. Nielsen BIO_printf(bio, "%4ld cache full overflows (%ld allowed)\n", 222474664626SKris Kennaway SSL_CTX_sess_cache_full(ssl_ctx), 222574664626SKris Kennaway SSL_CTX_sess_get_cache_size(ssl_ctx)); 222674664626SKris Kennaway } 222774664626SKris Kennaway 2228e71b7053SJung-uk Kim static int sv_body(int s, int stype, int prot, unsigned char *context) 222974664626SKris Kennaway { 223074664626SKris Kennaway char *buf = NULL; 223174664626SKris Kennaway fd_set readfds; 223274664626SKris Kennaway int ret = 1, width; 223374664626SKris Kennaway int k, i; 223474664626SKris Kennaway unsigned long l; 223574664626SKris Kennaway SSL *con = NULL; 223674664626SKris Kennaway BIO *sbio; 22376a599222SSimon L. B. Nielsen struct timeval timeout; 2238e71b7053SJung-uk Kim #if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)) 22396a599222SSimon L. B. Nielsen struct timeval *timeoutp; 2240f579bf8eSKris Kennaway #endif 2241e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS 2242e71b7053SJung-uk Kim # ifndef OPENSSL_NO_SCTP 2243e71b7053SJung-uk Kim int isdtls = (stype == SOCK_DGRAM || prot == IPPROTO_SCTP); 2244e71b7053SJung-uk Kim # else 2245e71b7053SJung-uk Kim int isdtls = (stype == SOCK_DGRAM); 2246e71b7053SJung-uk Kim # endif 224774664626SKris Kennaway #endif 224874664626SKris Kennaway 2249e71b7053SJung-uk Kim buf = app_malloc(bufsize, "server buffer"); 2250e71b7053SJung-uk Kim if (s_nbio) { 2251e71b7053SJung-uk Kim if (!BIO_socket_nbio(s, 1)) 2252e71b7053SJung-uk Kim ERR_print_errors(bio_err); 2253e71b7053SJung-uk Kim else if (!s_quiet) 2254e71b7053SJung-uk Kim BIO_printf(bio_err, "Turned on non blocking io\n"); 2255e71b7053SJung-uk Kim } 2256e71b7053SJung-uk Kim 2257f579bf8eSKris Kennaway con = SSL_new(ctx); 2258e71b7053SJung-uk Kim if (con == NULL) { 2259e71b7053SJung-uk Kim ret = -1; 2260e71b7053SJung-uk Kim goto err; 2261e71b7053SJung-uk Kim } 2262e71b7053SJung-uk Kim 22636f9291ceSJung-uk Kim if (s_tlsextdebug) { 2264db522d3aSSimon L. B. Nielsen SSL_set_tlsext_debug_callback(con, tlsext_cb); 2265db522d3aSSimon L. B. Nielsen SSL_set_tlsext_debug_arg(con, bio_s_out); 2266db522d3aSSimon L. B. Nielsen } 226774664626SKris Kennaway 2268e71b7053SJung-uk Kim if (context != NULL 2269e71b7053SJung-uk Kim && !SSL_set_session_id_context(con, context, 2270e71b7053SJung-uk Kim strlen((char *)context))) { 2271e71b7053SJung-uk Kim BIO_printf(bio_err, "Error setting session id context\n"); 2272e71b7053SJung-uk Kim ret = -1; 2273e71b7053SJung-uk Kim goto err; 2274e71b7053SJung-uk Kim } 22753b4e3dcbSSimon L. B. Nielsen 2276e71b7053SJung-uk Kim if (!SSL_clear(con)) { 2277e71b7053SJung-uk Kim BIO_printf(bio_err, "Error clearing SSL connection\n"); 2278e71b7053SJung-uk Kim ret = -1; 2279e71b7053SJung-uk Kim goto err; 2280e71b7053SJung-uk Kim } 2281e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS 2282e71b7053SJung-uk Kim if (isdtls) { 2283e71b7053SJung-uk Kim # ifndef OPENSSL_NO_SCTP 2284e71b7053SJung-uk Kim if (prot == IPPROTO_SCTP) 2285e71b7053SJung-uk Kim sbio = BIO_new_dgram_sctp(s, BIO_NOCLOSE); 2286e71b7053SJung-uk Kim else 2287e71b7053SJung-uk Kim # endif 22883b4e3dcbSSimon L. B. Nielsen sbio = BIO_new_dgram(s, BIO_NOCLOSE); 22893b4e3dcbSSimon L. B. Nielsen 22906f9291ceSJung-uk Kim if (enable_timeouts) { 22913b4e3dcbSSimon L. B. Nielsen timeout.tv_sec = 0; 22923b4e3dcbSSimon L. B. Nielsen timeout.tv_usec = DGRAM_RCV_TIMEOUT; 22933b4e3dcbSSimon L. B. Nielsen BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); 22943b4e3dcbSSimon L. B. Nielsen 22953b4e3dcbSSimon L. B. Nielsen timeout.tv_sec = 0; 22963b4e3dcbSSimon L. B. Nielsen timeout.tv_usec = DGRAM_SND_TIMEOUT; 22973b4e3dcbSSimon L. B. Nielsen BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout); 22983b4e3dcbSSimon L. B. Nielsen } 22993b4e3dcbSSimon L. B. Nielsen 23006f9291ceSJung-uk Kim if (socket_mtu) { 23016f9291ceSJung-uk Kim if (socket_mtu < DTLS_get_link_min_mtu(con)) { 2302751d2991SJung-uk Kim BIO_printf(bio_err, "MTU too small. Must be at least %ld\n", 2303751d2991SJung-uk Kim DTLS_get_link_min_mtu(con)); 2304751d2991SJung-uk Kim ret = -1; 2305751d2991SJung-uk Kim BIO_free(sbio); 2306751d2991SJung-uk Kim goto err; 2307751d2991SJung-uk Kim } 23083b4e3dcbSSimon L. B. Nielsen SSL_set_options(con, SSL_OP_NO_QUERY_MTU); 23096f9291ceSJung-uk Kim if (!DTLS_set_link_mtu(con, socket_mtu)) { 2310751d2991SJung-uk Kim BIO_printf(bio_err, "Failed to set MTU\n"); 2311751d2991SJung-uk Kim ret = -1; 2312751d2991SJung-uk Kim BIO_free(sbio); 2313751d2991SJung-uk Kim goto err; 2314751d2991SJung-uk Kim } 23156f9291ceSJung-uk Kim } else 23163b4e3dcbSSimon L. B. Nielsen /* want to do MTU discovery */ 23173b4e3dcbSSimon L. B. Nielsen BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); 23183b4e3dcbSSimon L. B. Nielsen 2319e71b7053SJung-uk Kim # ifndef OPENSSL_NO_SCTP 2320e71b7053SJung-uk Kim if (prot != IPPROTO_SCTP) 2321e71b7053SJung-uk Kim # endif 2322e71b7053SJung-uk Kim /* Turn on cookie exchange. Not necessary for SCTP */ 23233b4e3dcbSSimon L. B. Nielsen SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE); 23246f9291ceSJung-uk Kim } else 2325e71b7053SJung-uk Kim #endif 232674664626SKris Kennaway sbio = BIO_new_socket(s, BIO_NOCLOSE); 23273b4e3dcbSSimon L. B. Nielsen 2328e71b7053SJung-uk Kim if (sbio == NULL) { 2329e71b7053SJung-uk Kim BIO_printf(bio_err, "Unable to create BIO\n"); 2330e71b7053SJung-uk Kim ERR_print_errors(bio_err); 2331e71b7053SJung-uk Kim goto err; 2332e71b7053SJung-uk Kim } 2333e71b7053SJung-uk Kim 23346f9291ceSJung-uk Kim if (s_nbio_test) { 233574664626SKris Kennaway BIO *test; 233674664626SKris Kennaway 233774664626SKris Kennaway test = BIO_new(BIO_f_nbio_test()); 233874664626SKris Kennaway sbio = BIO_push(test, sbio); 233974664626SKris Kennaway } 2340db522d3aSSimon L. B. Nielsen 234174664626SKris Kennaway SSL_set_bio(con, sbio, sbio); 234274664626SKris Kennaway SSL_set_accept_state(con); 234374664626SKris Kennaway /* SSL_set_fd(con,s); */ 234474664626SKris Kennaway 23456f9291ceSJung-uk Kim if (s_debug) { 23463b4e3dcbSSimon L. B. Nielsen BIO_set_callback(SSL_get_rbio(con), bio_dump_callback); 23475471f83eSSimon L. B. Nielsen BIO_set_callback_arg(SSL_get_rbio(con), (char *)bio_s_out); 234874664626SKris Kennaway } 23496f9291ceSJung-uk Kim if (s_msg) { 23507bded2dbSJung-uk Kim #ifndef OPENSSL_NO_SSL_TRACE 23517bded2dbSJung-uk Kim if (s_msg == 2) 23527bded2dbSJung-uk Kim SSL_set_msg_callback(con, SSL_trace); 23537bded2dbSJung-uk Kim else 23547bded2dbSJung-uk Kim #endif 23555c87c606SMark Murray SSL_set_msg_callback(con, msg_cb); 23567bded2dbSJung-uk Kim SSL_set_msg_callback_arg(con, bio_s_msg ? bio_s_msg : bio_s_out); 23575c87c606SMark Murray } 2358e71b7053SJung-uk Kim 23596f9291ceSJung-uk Kim if (s_tlsextdebug) { 2360db522d3aSSimon L. B. Nielsen SSL_set_tlsext_debug_callback(con, tlsext_cb); 2361db522d3aSSimon L. B. Nielsen SSL_set_tlsext_debug_arg(con, bio_s_out); 2362db522d3aSSimon L. B. Nielsen } 2363e71b7053SJung-uk Kim 2364e71b7053SJung-uk Kim if (early_data) { 2365e71b7053SJung-uk Kim int write_header = 1, edret = SSL_READ_EARLY_DATA_ERROR; 2366e71b7053SJung-uk Kim size_t readbytes; 2367e71b7053SJung-uk Kim 2368e71b7053SJung-uk Kim while (edret != SSL_READ_EARLY_DATA_FINISH) { 2369e71b7053SJung-uk Kim for (;;) { 2370e71b7053SJung-uk Kim edret = SSL_read_early_data(con, buf, bufsize, &readbytes); 2371e71b7053SJung-uk Kim if (edret != SSL_READ_EARLY_DATA_ERROR) 2372e71b7053SJung-uk Kim break; 2373e71b7053SJung-uk Kim 2374e71b7053SJung-uk Kim switch (SSL_get_error(con, 0)) { 2375e71b7053SJung-uk Kim case SSL_ERROR_WANT_WRITE: 2376e71b7053SJung-uk Kim case SSL_ERROR_WANT_ASYNC: 2377e71b7053SJung-uk Kim case SSL_ERROR_WANT_READ: 2378e71b7053SJung-uk Kim /* Just keep trying - busy waiting */ 2379e71b7053SJung-uk Kim continue; 2380e71b7053SJung-uk Kim default: 2381e71b7053SJung-uk Kim BIO_printf(bio_err, "Error reading early data\n"); 2382e71b7053SJung-uk Kim ERR_print_errors(bio_err); 2383e71b7053SJung-uk Kim goto err; 2384e71b7053SJung-uk Kim } 2385e71b7053SJung-uk Kim } 2386e71b7053SJung-uk Kim if (readbytes > 0) { 2387e71b7053SJung-uk Kim if (write_header) { 2388e71b7053SJung-uk Kim BIO_printf(bio_s_out, "Early data received:\n"); 2389e71b7053SJung-uk Kim write_header = 0; 2390e71b7053SJung-uk Kim } 2391e71b7053SJung-uk Kim raw_write_stdout(buf, (unsigned int)readbytes); 2392e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 2393e71b7053SJung-uk Kim } 2394e71b7053SJung-uk Kim } 2395e71b7053SJung-uk Kim if (write_header) { 2396e71b7053SJung-uk Kim if (SSL_get_early_data_status(con) == SSL_EARLY_DATA_NOT_SENT) 2397e71b7053SJung-uk Kim BIO_printf(bio_s_out, "No early data received\n"); 2398e71b7053SJung-uk Kim else 2399e71b7053SJung-uk Kim BIO_printf(bio_s_out, "Early data was rejected\n"); 2400e71b7053SJung-uk Kim } else { 2401e71b7053SJung-uk Kim BIO_printf(bio_s_out, "\nEnd of early data\n"); 2402e71b7053SJung-uk Kim } 2403e71b7053SJung-uk Kim if (SSL_is_init_finished(con)) 2404e71b7053SJung-uk Kim print_connection_info(con); 2405e71b7053SJung-uk Kim } 240674664626SKris Kennaway 2407aeb5019cSJung-uk Kim if (fileno_stdin() > s) 2408aeb5019cSJung-uk Kim width = fileno_stdin() + 1; 2409aeb5019cSJung-uk Kim else 241074664626SKris Kennaway width = s + 1; 24116f9291ceSJung-uk Kim for (;;) { 2412f579bf8eSKris Kennaway int read_from_terminal; 2413f579bf8eSKris Kennaway int read_from_sslcon; 2414f579bf8eSKris Kennaway 2415f579bf8eSKris Kennaway read_from_terminal = 0; 2416e71b7053SJung-uk Kim read_from_sslcon = SSL_has_pending(con) 2417e71b7053SJung-uk Kim || (async && SSL_waiting_for_async(con)); 2418f579bf8eSKris Kennaway 24196f9291ceSJung-uk Kim if (!read_from_sslcon) { 242074664626SKris Kennaway FD_ZERO(&readfds); 2421e71b7053SJung-uk Kim #if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) 2422aeb5019cSJung-uk Kim openssl_fdset(fileno_stdin(), &readfds); 242374664626SKris Kennaway #endif 24241f13597dSJung-uk Kim openssl_fdset(s, &readfds); 24256f9291ceSJung-uk Kim /* 24266f9291ceSJung-uk Kim * Note: under VMS with SOCKETSHR the second parameter is 24276f9291ceSJung-uk Kim * currently of type (int *) whereas under other systems it is 24286f9291ceSJung-uk Kim * (void *) if you don't have a cast it will choke the compiler: 24296f9291ceSJung-uk Kim * if you do have a cast then you can either go for (int *) or 24306f9291ceSJung-uk Kim * (void *). 243174664626SKris Kennaway */ 2432e71b7053SJung-uk Kim #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) 24336f9291ceSJung-uk Kim /* 24346f9291ceSJung-uk Kim * Under DOS (non-djgpp) and Windows we can't select on stdin: 24356f9291ceSJung-uk Kim * only on sockets. As a workaround we timeout the select every 2436f579bf8eSKris Kennaway * second and check for any keypress. In a proper Windows 2437f579bf8eSKris Kennaway * application we wouldn't do this because it is inefficient. 2438f579bf8eSKris Kennaway */ 2439e71b7053SJung-uk Kim timeout.tv_sec = 1; 2440e71b7053SJung-uk Kim timeout.tv_usec = 0; 2441e71b7053SJung-uk Kim i = select(width, (void *)&readfds, NULL, NULL, &timeout); 2442e71b7053SJung-uk Kim if (has_stdin_waiting()) 2443f579bf8eSKris Kennaway read_from_terminal = 1; 2444e71b7053SJung-uk Kim if ((i < 0) || (!i && !read_from_terminal)) 24451f13597dSJung-uk Kim continue; 2446f579bf8eSKris Kennaway #else 2447e71b7053SJung-uk Kim if (SSL_is_dtls(con) && DTLSv1_get_timeout(con, &timeout)) 24486a599222SSimon L. B. Nielsen timeoutp = &timeout; 24496a599222SSimon L. B. Nielsen else 24506a599222SSimon L. B. Nielsen timeoutp = NULL; 24516a599222SSimon L. B. Nielsen 24526a599222SSimon L. B. Nielsen i = select(width, (void *)&readfds, NULL, NULL, timeoutp); 24536a599222SSimon L. B. Nielsen 2454e71b7053SJung-uk Kim if ((SSL_is_dtls(con)) && DTLSv1_handle_timeout(con) > 0) 2455e71b7053SJung-uk Kim BIO_printf(bio_err, "TIMEOUT occurred\n"); 24566a599222SSimon L. B. Nielsen 24576f9291ceSJung-uk Kim if (i <= 0) 24586f9291ceSJung-uk Kim continue; 2459aeb5019cSJung-uk Kim if (FD_ISSET(fileno_stdin(), &readfds)) 2460f579bf8eSKris Kennaway read_from_terminal = 1; 2461f579bf8eSKris Kennaway #endif 2462f579bf8eSKris Kennaway if (FD_ISSET(s, &readfds)) 2463f579bf8eSKris Kennaway read_from_sslcon = 1; 2464f579bf8eSKris Kennaway } 24656f9291ceSJung-uk Kim if (read_from_terminal) { 24666f9291ceSJung-uk Kim if (s_crlf) { 246774664626SKris Kennaway int j, lf_num; 246874664626SKris Kennaway 24691f13597dSJung-uk Kim i = raw_read_stdin(buf, bufsize / 2); 247074664626SKris Kennaway lf_num = 0; 247174664626SKris Kennaway /* both loops are skipped when i <= 0 */ 247274664626SKris Kennaway for (j = 0; j < i; j++) 247374664626SKris Kennaway if (buf[j] == '\n') 247474664626SKris Kennaway lf_num++; 24756f9291ceSJung-uk Kim for (j = i - 1; j >= 0; j--) { 247674664626SKris Kennaway buf[j + lf_num] = buf[j]; 24776f9291ceSJung-uk Kim if (buf[j] == '\n') { 247874664626SKris Kennaway lf_num--; 247974664626SKris Kennaway i++; 248074664626SKris Kennaway buf[j + lf_num] = '\r'; 248174664626SKris Kennaway } 248274664626SKris Kennaway } 248374664626SKris Kennaway assert(lf_num == 0); 2484e71b7053SJung-uk Kim } else { 24851f13597dSJung-uk Kim i = raw_read_stdin(buf, bufsize); 2486e71b7053SJung-uk Kim } 2487aeb5019cSJung-uk Kim 24887bded2dbSJung-uk Kim if (!s_quiet && !s_brief) { 24896f9291ceSJung-uk Kim if ((i <= 0) || (buf[0] == 'Q')) { 249074664626SKris Kennaway BIO_printf(bio_s_out, "DONE\n"); 2491e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 2492e71b7053SJung-uk Kim BIO_closesocket(s); 249374664626SKris Kennaway close_accept_socket(); 249474664626SKris Kennaway ret = -11; 249574664626SKris Kennaway goto err; 249674664626SKris Kennaway } 24976f9291ceSJung-uk Kim if ((i <= 0) || (buf[0] == 'q')) { 249874664626SKris Kennaway BIO_printf(bio_s_out, "DONE\n"); 2499e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 25003b4e3dcbSSimon L. B. Nielsen if (SSL_version(con) != DTLS1_VERSION) 2501e71b7053SJung-uk Kim BIO_closesocket(s); 25026f9291ceSJung-uk Kim /* 25036f9291ceSJung-uk Kim * close_accept_socket(); ret= -11; 25046f9291ceSJung-uk Kim */ 250574664626SKris Kennaway goto err; 250674664626SKris Kennaway } 25071f13597dSJung-uk Kim #ifndef OPENSSL_NO_HEARTBEATS 25086f9291ceSJung-uk Kim if ((buf[0] == 'B') && ((buf[1] == '\n') || (buf[1] == '\r'))) { 25091f13597dSJung-uk Kim BIO_printf(bio_err, "HEARTBEATING\n"); 25101f13597dSJung-uk Kim SSL_heartbeat(con); 25111f13597dSJung-uk Kim i = 0; 25121f13597dSJung-uk Kim continue; 25131f13597dSJung-uk Kim } 25141f13597dSJung-uk Kim #endif 25156f9291ceSJung-uk Kim if ((buf[0] == 'r') && ((buf[1] == '\n') || (buf[1] == '\r'))) { 251674664626SKris Kennaway SSL_renegotiate(con); 251774664626SKris Kennaway i = SSL_do_handshake(con); 251874664626SKris Kennaway printf("SSL_do_handshake -> %d\n", i); 251974664626SKris Kennaway i = 0; /* 13; */ 252074664626SKris Kennaway continue; 252174664626SKris Kennaway } 25226f9291ceSJung-uk Kim if ((buf[0] == 'R') && ((buf[1] == '\n') || (buf[1] == '\r'))) { 252374664626SKris Kennaway SSL_set_verify(con, 25246f9291ceSJung-uk Kim SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, 25256f9291ceSJung-uk Kim NULL); 252674664626SKris Kennaway SSL_renegotiate(con); 252774664626SKris Kennaway i = SSL_do_handshake(con); 252874664626SKris Kennaway printf("SSL_do_handshake -> %d\n", i); 252974664626SKris Kennaway i = 0; /* 13; */ 253074664626SKris Kennaway continue; 2531e71b7053SJung-uk Kim } 2532e71b7053SJung-uk Kim if ((buf[0] == 'K' || buf[0] == 'k') 2533e71b7053SJung-uk Kim && ((buf[1] == '\n') || (buf[1] == '\r'))) { 2534e71b7053SJung-uk Kim SSL_key_update(con, buf[0] == 'K' ? 2535e71b7053SJung-uk Kim SSL_KEY_UPDATE_REQUESTED 2536e71b7053SJung-uk Kim : SSL_KEY_UPDATE_NOT_REQUESTED); 2537e71b7053SJung-uk Kim i = SSL_do_handshake(con); 2538e71b7053SJung-uk Kim printf("SSL_do_handshake -> %d\n", i); 2539e71b7053SJung-uk Kim i = 0; 2540e71b7053SJung-uk Kim continue; 2541e71b7053SJung-uk Kim } 2542e71b7053SJung-uk Kim if (buf[0] == 'c' && ((buf[1] == '\n') || (buf[1] == '\r'))) { 2543e71b7053SJung-uk Kim SSL_set_verify(con, SSL_VERIFY_PEER, NULL); 2544e71b7053SJung-uk Kim i = SSL_verify_client_post_handshake(con); 2545e71b7053SJung-uk Kim if (i == 0) { 2546e71b7053SJung-uk Kim printf("Failed to initiate request\n"); 2547e71b7053SJung-uk Kim ERR_print_errors(bio_err); 2548e71b7053SJung-uk Kim } else { 2549e71b7053SJung-uk Kim i = SSL_do_handshake(con); 2550e71b7053SJung-uk Kim printf("SSL_do_handshake -> %d\n", i); 2551e71b7053SJung-uk Kim i = 0; 2552e71b7053SJung-uk Kim } 2553e71b7053SJung-uk Kim continue; 255474664626SKris Kennaway } 25556f9291ceSJung-uk Kim if (buf[0] == 'P') { 25563b4e3dcbSSimon L. B. Nielsen static const char *str = "Lets print some clear text\n"; 255774664626SKris Kennaway BIO_write(SSL_get_wbio(con), str, strlen(str)); 255874664626SKris Kennaway } 25596f9291ceSJung-uk Kim if (buf[0] == 'S') { 256074664626SKris Kennaway print_stats(bio_s_out, SSL_get_SSL_CTX(con)); 256174664626SKris Kennaway } 256274664626SKris Kennaway } 256374664626SKris Kennaway #ifdef CHARSET_EBCDIC 256474664626SKris Kennaway ebcdic2ascii(buf, buf, i); 256574664626SKris Kennaway #endif 256674664626SKris Kennaway l = k = 0; 25676f9291ceSJung-uk Kim for (;;) { 256874664626SKris Kennaway /* should do a select for the write */ 256974664626SKris Kennaway #ifdef RENEG 25706f9291ceSJung-uk Kim static count = 0; 25716f9291ceSJung-uk Kim if (++count == 100) { 25726f9291ceSJung-uk Kim count = 0; 25736f9291ceSJung-uk Kim SSL_renegotiate(con); 25746f9291ceSJung-uk Kim } 257574664626SKris Kennaway #endif 257674664626SKris Kennaway k = SSL_write(con, &(buf[l]), (unsigned int)i); 25771f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP 25786f9291ceSJung-uk Kim while (SSL_get_error(con, k) == SSL_ERROR_WANT_X509_LOOKUP) { 25791f13597dSJung-uk Kim BIO_printf(bio_s_out, "LOOKUP renego during write\n"); 25804c6a0400SJung-uk Kim SRP_user_pwd_free(srp_callback_parm.user); 25816f9291ceSJung-uk Kim srp_callback_parm.user = 25824c6a0400SJung-uk Kim SRP_VBASE_get1_by_user(srp_callback_parm.vb, 25836f9291ceSJung-uk Kim srp_callback_parm.login); 25841f13597dSJung-uk Kim if (srp_callback_parm.user) 25856f9291ceSJung-uk Kim BIO_printf(bio_s_out, "LOOKUP done %s\n", 25866f9291ceSJung-uk Kim srp_callback_parm.user->info); 25871f13597dSJung-uk Kim else 25881f13597dSJung-uk Kim BIO_printf(bio_s_out, "LOOKUP not successful\n"); 25891f13597dSJung-uk Kim k = SSL_write(con, &(buf[l]), (unsigned int)i); 25901f13597dSJung-uk Kim } 25911f13597dSJung-uk Kim #endif 25926f9291ceSJung-uk Kim switch (SSL_get_error(con, k)) { 259374664626SKris Kennaway case SSL_ERROR_NONE: 259474664626SKris Kennaway break; 2595e71b7053SJung-uk Kim case SSL_ERROR_WANT_ASYNC: 2596e71b7053SJung-uk Kim BIO_printf(bio_s_out, "Write BLOCK (Async)\n"); 2597e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 2598e71b7053SJung-uk Kim wait_for_async(con); 2599e71b7053SJung-uk Kim break; 260074664626SKris Kennaway case SSL_ERROR_WANT_WRITE: 260174664626SKris Kennaway case SSL_ERROR_WANT_READ: 260274664626SKris Kennaway case SSL_ERROR_WANT_X509_LOOKUP: 260374664626SKris Kennaway BIO_printf(bio_s_out, "Write BLOCK\n"); 2604e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 260574664626SKris Kennaway break; 2606e71b7053SJung-uk Kim case SSL_ERROR_WANT_ASYNC_JOB: 2607e71b7053SJung-uk Kim /* 2608e71b7053SJung-uk Kim * This shouldn't ever happen in s_server. Treat as an error 2609e71b7053SJung-uk Kim */ 261074664626SKris Kennaway case SSL_ERROR_SYSCALL: 261174664626SKris Kennaway case SSL_ERROR_SSL: 261274664626SKris Kennaway BIO_printf(bio_s_out, "ERROR\n"); 2613e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 261474664626SKris Kennaway ERR_print_errors(bio_err); 261574664626SKris Kennaway ret = 1; 261674664626SKris Kennaway goto err; 261774664626SKris Kennaway /* break; */ 261874664626SKris Kennaway case SSL_ERROR_ZERO_RETURN: 261974664626SKris Kennaway BIO_printf(bio_s_out, "DONE\n"); 2620e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 262174664626SKris Kennaway ret = 1; 262274664626SKris Kennaway goto err; 262374664626SKris Kennaway } 2624ed6b93beSJung-uk Kim if (k > 0) { 262574664626SKris Kennaway l += k; 262674664626SKris Kennaway i -= k; 2627ed6b93beSJung-uk Kim } 26286f9291ceSJung-uk Kim if (i <= 0) 26296f9291ceSJung-uk Kim break; 263074664626SKris Kennaway } 263174664626SKris Kennaway } 26326f9291ceSJung-uk Kim if (read_from_sslcon) { 2633e71b7053SJung-uk Kim /* 2634e71b7053SJung-uk Kim * init_ssl_connection handles all async events itself so if we're 2635e71b7053SJung-uk Kim * waiting for async then we shouldn't go back into 2636e71b7053SJung-uk Kim * init_ssl_connection 2637e71b7053SJung-uk Kim */ 2638e71b7053SJung-uk Kim if ((!async || !SSL_waiting_for_async(con)) 2639e71b7053SJung-uk Kim && !SSL_is_init_finished(con)) { 264074664626SKris Kennaway i = init_ssl_connection(con); 264174664626SKris Kennaway 26426f9291ceSJung-uk Kim if (i < 0) { 264374664626SKris Kennaway ret = 0; 264474664626SKris Kennaway goto err; 26456f9291ceSJung-uk Kim } else if (i == 0) { 264674664626SKris Kennaway ret = 1; 264774664626SKris Kennaway goto err; 264874664626SKris Kennaway } 26496f9291ceSJung-uk Kim } else { 265074664626SKris Kennaway again: 265174664626SKris Kennaway i = SSL_read(con, (char *)buf, bufsize); 26521f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP 26536f9291ceSJung-uk Kim while (SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) { 26541f13597dSJung-uk Kim BIO_printf(bio_s_out, "LOOKUP renego during read\n"); 26554c6a0400SJung-uk Kim SRP_user_pwd_free(srp_callback_parm.user); 26566f9291ceSJung-uk Kim srp_callback_parm.user = 26574c6a0400SJung-uk Kim SRP_VBASE_get1_by_user(srp_callback_parm.vb, 26586f9291ceSJung-uk Kim srp_callback_parm.login); 26591f13597dSJung-uk Kim if (srp_callback_parm.user) 26606f9291ceSJung-uk Kim BIO_printf(bio_s_out, "LOOKUP done %s\n", 26616f9291ceSJung-uk Kim srp_callback_parm.user->info); 26621f13597dSJung-uk Kim else 26631f13597dSJung-uk Kim BIO_printf(bio_s_out, "LOOKUP not successful\n"); 26641f13597dSJung-uk Kim i = SSL_read(con, (char *)buf, bufsize); 26651f13597dSJung-uk Kim } 26661f13597dSJung-uk Kim #endif 26676f9291ceSJung-uk Kim switch (SSL_get_error(con, i)) { 266874664626SKris Kennaway case SSL_ERROR_NONE: 266974664626SKris Kennaway #ifdef CHARSET_EBCDIC 267074664626SKris Kennaway ascii2ebcdic(buf, buf, i); 267174664626SKris Kennaway #endif 26726f9291ceSJung-uk Kim raw_write_stdout(buf, (unsigned int)i); 2673e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 2674e71b7053SJung-uk Kim if (SSL_has_pending(con)) 26756f9291ceSJung-uk Kim goto again; 267674664626SKris Kennaway break; 2677e71b7053SJung-uk Kim case SSL_ERROR_WANT_ASYNC: 2678e71b7053SJung-uk Kim BIO_printf(bio_s_out, "Read BLOCK (Async)\n"); 2679e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 2680e71b7053SJung-uk Kim wait_for_async(con); 2681e71b7053SJung-uk Kim break; 268274664626SKris Kennaway case SSL_ERROR_WANT_WRITE: 268374664626SKris Kennaway case SSL_ERROR_WANT_READ: 268474664626SKris Kennaway BIO_printf(bio_s_out, "Read BLOCK\n"); 2685e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 268674664626SKris Kennaway break; 2687e71b7053SJung-uk Kim case SSL_ERROR_WANT_ASYNC_JOB: 2688e71b7053SJung-uk Kim /* 2689e71b7053SJung-uk Kim * This shouldn't ever happen in s_server. Treat as an error 2690e71b7053SJung-uk Kim */ 269174664626SKris Kennaway case SSL_ERROR_SYSCALL: 269274664626SKris Kennaway case SSL_ERROR_SSL: 269374664626SKris Kennaway BIO_printf(bio_s_out, "ERROR\n"); 2694e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 269574664626SKris Kennaway ERR_print_errors(bio_err); 269674664626SKris Kennaway ret = 1; 269774664626SKris Kennaway goto err; 269874664626SKris Kennaway case SSL_ERROR_ZERO_RETURN: 269974664626SKris Kennaway BIO_printf(bio_s_out, "DONE\n"); 2700e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 270174664626SKris Kennaway ret = 1; 270274664626SKris Kennaway goto err; 270374664626SKris Kennaway } 270474664626SKris Kennaway } 270574664626SKris Kennaway } 270674664626SKris Kennaway } 270774664626SKris Kennaway err: 27086f9291ceSJung-uk Kim if (con != NULL) { 270974664626SKris Kennaway BIO_printf(bio_s_out, "shutting down SSL\n"); 271074664626SKris Kennaway SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); 27111f13597dSJung-uk Kim SSL_free(con); 27121f13597dSJung-uk Kim } 271374664626SKris Kennaway BIO_printf(bio_s_out, "CONNECTION CLOSED\n"); 2714e71b7053SJung-uk Kim OPENSSL_clear_free(buf, bufsize); 2715e71b7053SJung-uk Kim return ret; 271674664626SKris Kennaway } 271774664626SKris Kennaway 271874664626SKris Kennaway static void close_accept_socket(void) 271974664626SKris Kennaway { 272074664626SKris Kennaway BIO_printf(bio_err, "shutdown accept socket\n"); 27216f9291ceSJung-uk Kim if (accept_socket >= 0) { 2722e71b7053SJung-uk Kim BIO_closesocket(accept_socket); 272374664626SKris Kennaway } 272474664626SKris Kennaway } 272574664626SKris Kennaway 2726e71b7053SJung-uk Kim static int is_retryable(SSL *con, int i) 2727e71b7053SJung-uk Kim { 2728e71b7053SJung-uk Kim int err = SSL_get_error(con, i); 2729e71b7053SJung-uk Kim 2730e71b7053SJung-uk Kim /* If it's not a fatal error, it must be retryable */ 2731e71b7053SJung-uk Kim return (err != SSL_ERROR_SSL) 2732e71b7053SJung-uk Kim && (err != SSL_ERROR_SYSCALL) 2733e71b7053SJung-uk Kim && (err != SSL_ERROR_ZERO_RETURN); 2734e71b7053SJung-uk Kim } 2735e71b7053SJung-uk Kim 273674664626SKris Kennaway static int init_ssl_connection(SSL *con) 273774664626SKris Kennaway { 273874664626SKris Kennaway int i; 2739e71b7053SJung-uk Kim long verify_err; 2740e71b7053SJung-uk Kim int retry = 0; 274174664626SKris Kennaway 2742e71b7053SJung-uk Kim if (dtlslisten || stateless) { 2743e71b7053SJung-uk Kim BIO_ADDR *client = NULL; 2744e71b7053SJung-uk Kim 2745e71b7053SJung-uk Kim if (dtlslisten) { 2746e71b7053SJung-uk Kim if ((client = BIO_ADDR_new()) == NULL) { 2747e71b7053SJung-uk Kim BIO_printf(bio_err, "ERROR - memory\n"); 2748e71b7053SJung-uk Kim return 0; 2749e71b7053SJung-uk Kim } 2750e71b7053SJung-uk Kim i = DTLSv1_listen(con, client); 2751e71b7053SJung-uk Kim } else { 2752e71b7053SJung-uk Kim i = SSL_stateless(con); 2753e71b7053SJung-uk Kim } 2754e71b7053SJung-uk Kim if (i > 0) { 2755e71b7053SJung-uk Kim BIO *wbio; 2756e71b7053SJung-uk Kim int fd = -1; 2757e71b7053SJung-uk Kim 2758e71b7053SJung-uk Kim if (dtlslisten) { 2759e71b7053SJung-uk Kim wbio = SSL_get_wbio(con); 2760e71b7053SJung-uk Kim if (wbio) { 2761e71b7053SJung-uk Kim BIO_get_fd(wbio, &fd); 2762e71b7053SJung-uk Kim } 2763e71b7053SJung-uk Kim 2764e71b7053SJung-uk Kim if (!wbio || BIO_connect(fd, client, 0) == 0) { 2765e71b7053SJung-uk Kim BIO_printf(bio_err, "ERROR - unable to connect\n"); 2766e71b7053SJung-uk Kim BIO_ADDR_free(client); 2767e71b7053SJung-uk Kim return 0; 2768e71b7053SJung-uk Kim } 27696935a639SJung-uk Kim 27706935a639SJung-uk Kim (void)BIO_ctrl_set_connected(wbio, client); 2771e71b7053SJung-uk Kim BIO_ADDR_free(client); 2772e71b7053SJung-uk Kim dtlslisten = 0; 2773e71b7053SJung-uk Kim } else { 2774e71b7053SJung-uk Kim stateless = 0; 2775e71b7053SJung-uk Kim } 27761f13597dSJung-uk Kim i = SSL_accept(con); 2777e71b7053SJung-uk Kim } else { 2778e71b7053SJung-uk Kim BIO_ADDR_free(client); 2779e71b7053SJung-uk Kim } 2780e71b7053SJung-uk Kim } else { 2781e71b7053SJung-uk Kim do { 2782e71b7053SJung-uk Kim i = SSL_accept(con); 2783e71b7053SJung-uk Kim 2784e71b7053SJung-uk Kim if (i <= 0) 2785e71b7053SJung-uk Kim retry = is_retryable(con, i); 27867bded2dbSJung-uk Kim #ifdef CERT_CB_TEST_RETRY 27877bded2dbSJung-uk Kim { 2788e71b7053SJung-uk Kim while (i <= 0 2789e71b7053SJung-uk Kim && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP 2790e71b7053SJung-uk Kim && SSL_get_state(con) == TLS_ST_SR_CLNT_HELLO) { 2791e71b7053SJung-uk Kim BIO_printf(bio_err, 27927bded2dbSJung-uk Kim "LOOKUP from certificate callback during accept\n"); 27937bded2dbSJung-uk Kim i = SSL_accept(con); 2794e71b7053SJung-uk Kim if (i <= 0) 2795e71b7053SJung-uk Kim retry = is_retryable(con, i); 27967bded2dbSJung-uk Kim } 27977bded2dbSJung-uk Kim } 27987bded2dbSJung-uk Kim #endif 2799e71b7053SJung-uk Kim 28001f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP 2801e71b7053SJung-uk Kim while (i <= 0 2802e71b7053SJung-uk Kim && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) { 28036f9291ceSJung-uk Kim BIO_printf(bio_s_out, "LOOKUP during accept %s\n", 28046f9291ceSJung-uk Kim srp_callback_parm.login); 28054c6a0400SJung-uk Kim SRP_user_pwd_free(srp_callback_parm.user); 28066f9291ceSJung-uk Kim srp_callback_parm.user = 28074c6a0400SJung-uk Kim SRP_VBASE_get1_by_user(srp_callback_parm.vb, 28086f9291ceSJung-uk Kim srp_callback_parm.login); 28091f13597dSJung-uk Kim if (srp_callback_parm.user) 28106f9291ceSJung-uk Kim BIO_printf(bio_s_out, "LOOKUP done %s\n", 28116f9291ceSJung-uk Kim srp_callback_parm.user->info); 28121f13597dSJung-uk Kim else 28131f13597dSJung-uk Kim BIO_printf(bio_s_out, "LOOKUP not successful\n"); 28141f13597dSJung-uk Kim i = SSL_accept(con); 2815e71b7053SJung-uk Kim if (i <= 0) 2816e71b7053SJung-uk Kim retry = is_retryable(con, i); 28171f13597dSJung-uk Kim } 28181f13597dSJung-uk Kim #endif 2819e71b7053SJung-uk Kim } while (i < 0 && SSL_waiting_for_async(con)); 2820e71b7053SJung-uk Kim } 28217bded2dbSJung-uk Kim 28226f9291ceSJung-uk Kim if (i <= 0) { 2823e71b7053SJung-uk Kim if (((dtlslisten || stateless) && i == 0) 2824e71b7053SJung-uk Kim || (!dtlslisten && !stateless && retry)) { 282574664626SKris Kennaway BIO_printf(bio_s_out, "DELAY\n"); 2826e71b7053SJung-uk Kim return 1; 282774664626SKris Kennaway } 282874664626SKris Kennaway 282974664626SKris Kennaway BIO_printf(bio_err, "ERROR\n"); 2830e71b7053SJung-uk Kim 2831e71b7053SJung-uk Kim verify_err = SSL_get_verify_result(con); 2832e71b7053SJung-uk Kim if (verify_err != X509_V_OK) { 283374664626SKris Kennaway BIO_printf(bio_err, "verify error:%s\n", 2834e71b7053SJung-uk Kim X509_verify_cert_error_string(verify_err)); 28357bded2dbSJung-uk Kim } 28367bded2dbSJung-uk Kim /* Always print any error messages */ 283774664626SKris Kennaway ERR_print_errors(bio_err); 2838e71b7053SJung-uk Kim return 0; 283974664626SKris Kennaway } 284074664626SKris Kennaway 2841e71b7053SJung-uk Kim print_connection_info(con); 2842e71b7053SJung-uk Kim return 1; 2843e71b7053SJung-uk Kim } 2844e71b7053SJung-uk Kim 2845e71b7053SJung-uk Kim static void print_connection_info(SSL *con) 2846e71b7053SJung-uk Kim { 2847e71b7053SJung-uk Kim const char *str; 2848e71b7053SJung-uk Kim X509 *peer; 2849e71b7053SJung-uk Kim char buf[BUFSIZ]; 2850e71b7053SJung-uk Kim #if !defined(OPENSSL_NO_NEXTPROTONEG) 2851e71b7053SJung-uk Kim const unsigned char *next_proto_neg; 2852e71b7053SJung-uk Kim unsigned next_proto_neg_len; 2853e71b7053SJung-uk Kim #endif 2854e71b7053SJung-uk Kim unsigned char *exportedkeymat; 2855e71b7053SJung-uk Kim int i; 2856e71b7053SJung-uk Kim 28577bded2dbSJung-uk Kim if (s_brief) 2858e71b7053SJung-uk Kim print_ssl_summary(con); 28597bded2dbSJung-uk Kim 286074664626SKris Kennaway PEM_write_bio_SSL_SESSION(bio_s_out, SSL_get_session(con)); 286174664626SKris Kennaway 286274664626SKris Kennaway peer = SSL_get_peer_certificate(con); 28636f9291ceSJung-uk Kim if (peer != NULL) { 286474664626SKris Kennaway BIO_printf(bio_s_out, "Client certificate\n"); 286574664626SKris Kennaway PEM_write_bio_X509(bio_s_out, peer); 2866e71b7053SJung-uk Kim dump_cert_text(bio_s_out, peer); 286774664626SKris Kennaway X509_free(peer); 2868e71b7053SJung-uk Kim peer = NULL; 286974664626SKris Kennaway } 287074664626SKris Kennaway 2871dee36b4fSJung-uk Kim if (SSL_get_shared_ciphers(con, buf, sizeof(buf)) != NULL) 287274664626SKris Kennaway BIO_printf(bio_s_out, "Shared ciphers:%s\n", buf); 287374664626SKris Kennaway str = SSL_CIPHER_get_name(SSL_get_current_cipher(con)); 28747bded2dbSJung-uk Kim ssl_print_sigalgs(bio_s_out, con); 28757bded2dbSJung-uk Kim #ifndef OPENSSL_NO_EC 28767bded2dbSJung-uk Kim ssl_print_point_formats(bio_s_out, con); 2877e71b7053SJung-uk Kim ssl_print_groups(bio_s_out, con, 0); 28787bded2dbSJung-uk Kim #endif 2879e71b7053SJung-uk Kim print_ca_names(bio_s_out, con); 288074664626SKris Kennaway BIO_printf(bio_s_out, "CIPHER is %s\n", (str != NULL) ? str : "(NONE)"); 288109286989SJung-uk Kim 2882e71b7053SJung-uk Kim #if !defined(OPENSSL_NO_NEXTPROTONEG) 28831f13597dSJung-uk Kim SSL_get0_next_proto_negotiated(con, &next_proto_neg, &next_proto_neg_len); 28846f9291ceSJung-uk Kim if (next_proto_neg) { 28851f13597dSJung-uk Kim BIO_printf(bio_s_out, "NEXTPROTO is "); 28861f13597dSJung-uk Kim BIO_write(bio_s_out, next_proto_neg, next_proto_neg_len); 28871f13597dSJung-uk Kim BIO_printf(bio_s_out, "\n"); 28881f13597dSJung-uk Kim } 28891f13597dSJung-uk Kim #endif 289009286989SJung-uk Kim #ifndef OPENSSL_NO_SRTP 28911f13597dSJung-uk Kim { 28921f13597dSJung-uk Kim SRTP_PROTECTION_PROFILE *srtp_profile 28931f13597dSJung-uk Kim = SSL_get_selected_srtp_profile(con); 28941f13597dSJung-uk Kim 28951f13597dSJung-uk Kim if (srtp_profile) 28961f13597dSJung-uk Kim BIO_printf(bio_s_out, "SRTP Extension negotiated, profile=%s\n", 28971f13597dSJung-uk Kim srtp_profile->name); 28981f13597dSJung-uk Kim } 289909286989SJung-uk Kim #endif 2900e71b7053SJung-uk Kim if (SSL_session_reused(con)) 29016f9291ceSJung-uk Kim BIO_printf(bio_s_out, "Reused session-id\n"); 29026a599222SSimon L. B. Nielsen BIO_printf(bio_s_out, "Secure Renegotiation IS%s supported\n", 29036a599222SSimon L. B. Nielsen SSL_get_secure_renegotiation_support(con) ? "" : " NOT"); 2904e71b7053SJung-uk Kim if ((SSL_get_options(con) & SSL_OP_NO_RENEGOTIATION)) 2905e71b7053SJung-uk Kim BIO_printf(bio_s_out, "Renegotiation is DISABLED\n"); 2906e71b7053SJung-uk Kim 29076f9291ceSJung-uk Kim if (keymatexportlabel != NULL) { 29081f13597dSJung-uk Kim BIO_printf(bio_s_out, "Keying material exporter:\n"); 29091f13597dSJung-uk Kim BIO_printf(bio_s_out, " Label: '%s'\n", keymatexportlabel); 29106f9291ceSJung-uk Kim BIO_printf(bio_s_out, " Length: %i bytes\n", keymatexportlen); 2911e71b7053SJung-uk Kim exportedkeymat = app_malloc(keymatexportlen, "export key"); 29121f13597dSJung-uk Kim if (!SSL_export_keying_material(con, exportedkeymat, 29131f13597dSJung-uk Kim keymatexportlen, 29141f13597dSJung-uk Kim keymatexportlabel, 29151f13597dSJung-uk Kim strlen(keymatexportlabel), 29166f9291ceSJung-uk Kim NULL, 0, 0)) { 29171f13597dSJung-uk Kim BIO_printf(bio_s_out, " Error\n"); 29186f9291ceSJung-uk Kim } else { 29191f13597dSJung-uk Kim BIO_printf(bio_s_out, " Keying material: "); 29201f13597dSJung-uk Kim for (i = 0; i < keymatexportlen; i++) 29216f9291ceSJung-uk Kim BIO_printf(bio_s_out, "%02X", exportedkeymat[i]); 29221f13597dSJung-uk Kim BIO_printf(bio_s_out, "\n"); 29231f13597dSJung-uk Kim } 29241f13597dSJung-uk Kim OPENSSL_free(exportedkeymat); 29251f13597dSJung-uk Kim } 29261f13597dSJung-uk Kim 2927e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 292874664626SKris Kennaway } 292974664626SKris Kennaway 29305c87c606SMark Murray #ifndef OPENSSL_NO_DH 29313b4e3dcbSSimon L. B. Nielsen static DH *load_dh_param(const char *dhfile) 293274664626SKris Kennaway { 293374664626SKris Kennaway DH *ret = NULL; 293474664626SKris Kennaway BIO *bio; 293574664626SKris Kennaway 2936f579bf8eSKris Kennaway if ((bio = BIO_new_file(dhfile, "r")) == NULL) 293774664626SKris Kennaway goto err; 293874664626SKris Kennaway ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); 293974664626SKris Kennaway err: 29406f9291ceSJung-uk Kim BIO_free(bio); 2941e71b7053SJung-uk Kim return ret; 294274664626SKris Kennaway } 294374664626SKris Kennaway #endif 294474664626SKris Kennaway 2945e71b7053SJung-uk Kim static int www_body(int s, int stype, int prot, unsigned char *context) 294674664626SKris Kennaway { 294774664626SKris Kennaway char *buf = NULL; 294874664626SKris Kennaway int ret = 1; 2949a3ddd25aSSimon L. B. Nielsen int i, j, k, dot; 295074664626SKris Kennaway SSL *con; 29511f13597dSJung-uk Kim const SSL_CIPHER *c; 295274664626SKris Kennaway BIO *io, *ssl_bio, *sbio; 2953e71b7053SJung-uk Kim #ifdef RENEG 2954e71b7053SJung-uk Kim int total_bytes = 0; 2955a3ddd25aSSimon L. B. Nielsen #endif 2956e71b7053SJung-uk Kim int width; 2957e71b7053SJung-uk Kim fd_set readfds; 295874664626SKris Kennaway 2959e71b7053SJung-uk Kim /* Set width for a select call if needed */ 2960e71b7053SJung-uk Kim width = s + 1; 2961e71b7053SJung-uk Kim 2962e71b7053SJung-uk Kim buf = app_malloc(bufsize, "server www buffer"); 296374664626SKris Kennaway io = BIO_new(BIO_f_buffer()); 296474664626SKris Kennaway ssl_bio = BIO_new(BIO_f_ssl()); 29656f9291ceSJung-uk Kim if ((io == NULL) || (ssl_bio == NULL)) 29666f9291ceSJung-uk Kim goto err; 296774664626SKris Kennaway 29686f9291ceSJung-uk Kim if (s_nbio) { 2969e71b7053SJung-uk Kim if (!BIO_socket_nbio(s, 1)) 297074664626SKris Kennaway ERR_print_errors(bio_err); 2971e71b7053SJung-uk Kim else if (!s_quiet) 2972e71b7053SJung-uk Kim BIO_printf(bio_err, "Turned on non blocking io\n"); 297374664626SKris Kennaway } 297474664626SKris Kennaway 297574664626SKris Kennaway /* lets make the output buffer a reasonable size */ 29766f9291ceSJung-uk Kim if (!BIO_set_write_buffer_size(io, bufsize)) 29776f9291ceSJung-uk Kim goto err; 297874664626SKris Kennaway 29796f9291ceSJung-uk Kim if ((con = SSL_new(ctx)) == NULL) 29806f9291ceSJung-uk Kim goto err; 2981e71b7053SJung-uk Kim 29826f9291ceSJung-uk Kim if (s_tlsextdebug) { 2983db522d3aSSimon L. B. Nielsen SSL_set_tlsext_debug_callback(con, tlsext_cb); 2984db522d3aSSimon L. B. Nielsen SSL_set_tlsext_debug_arg(con, bio_s_out); 2985db522d3aSSimon L. B. Nielsen } 2986e71b7053SJung-uk Kim 2987e71b7053SJung-uk Kim if (context != NULL 2988e71b7053SJung-uk Kim && !SSL_set_session_id_context(con, context, 2989e71b7053SJung-uk Kim strlen((char *)context))) { 2990e71b7053SJung-uk Kim SSL_free(con); 2991e71b7053SJung-uk Kim goto err; 29925c87c606SMark Murray } 299374664626SKris Kennaway 299474664626SKris Kennaway sbio = BIO_new_socket(s, BIO_NOCLOSE); 29956f9291ceSJung-uk Kim if (s_nbio_test) { 299674664626SKris Kennaway BIO *test; 299774664626SKris Kennaway 299874664626SKris Kennaway test = BIO_new(BIO_f_nbio_test()); 299974664626SKris Kennaway sbio = BIO_push(test, sbio); 300074664626SKris Kennaway } 300174664626SKris Kennaway SSL_set_bio(con, sbio, sbio); 300274664626SKris Kennaway SSL_set_accept_state(con); 300374664626SKris Kennaway 3004e71b7053SJung-uk Kim /* No need to free |con| after this. Done by BIO_free(ssl_bio) */ 300574664626SKris Kennaway BIO_set_ssl(ssl_bio, con, BIO_CLOSE); 300674664626SKris Kennaway BIO_push(io, ssl_bio); 300774664626SKris Kennaway #ifdef CHARSET_EBCDIC 300874664626SKris Kennaway io = BIO_push(BIO_new(BIO_f_ebcdic_filter()), io); 300974664626SKris Kennaway #endif 301074664626SKris Kennaway 30116f9291ceSJung-uk Kim if (s_debug) { 30123b4e3dcbSSimon L. B. Nielsen BIO_set_callback(SSL_get_rbio(con), bio_dump_callback); 30135471f83eSSimon L. B. Nielsen BIO_set_callback_arg(SSL_get_rbio(con), (char *)bio_s_out); 301474664626SKris Kennaway } 30156f9291ceSJung-uk Kim if (s_msg) { 30167bded2dbSJung-uk Kim #ifndef OPENSSL_NO_SSL_TRACE 30177bded2dbSJung-uk Kim if (s_msg == 2) 30187bded2dbSJung-uk Kim SSL_set_msg_callback(con, SSL_trace); 30197bded2dbSJung-uk Kim else 30207bded2dbSJung-uk Kim #endif 30215c87c606SMark Murray SSL_set_msg_callback(con, msg_cb); 30227bded2dbSJung-uk Kim SSL_set_msg_callback_arg(con, bio_s_msg ? bio_s_msg : bio_s_out); 30235c87c606SMark Murray } 302474664626SKris Kennaway 30256f9291ceSJung-uk Kim for (;;) { 302674664626SKris Kennaway i = BIO_gets(io, buf, bufsize - 1); 30276f9291ceSJung-uk Kim if (i < 0) { /* error */ 3028e71b7053SJung-uk Kim if (!BIO_should_retry(io) && !SSL_waiting_for_async(con)) { 302974664626SKris Kennaway if (!s_quiet) 303074664626SKris Kennaway ERR_print_errors(bio_err); 303174664626SKris Kennaway goto err; 30326f9291ceSJung-uk Kim } else { 303374664626SKris Kennaway BIO_printf(bio_s_out, "read R BLOCK\n"); 303480815a77SJung-uk Kim #ifndef OPENSSL_NO_SRP 303580815a77SJung-uk Kim if (BIO_should_io_special(io) 303680815a77SJung-uk Kim && BIO_get_retry_reason(io) == BIO_RR_SSL_X509_LOOKUP) { 303780815a77SJung-uk Kim BIO_printf(bio_s_out, "LOOKUP renego during read\n"); 30384c6a0400SJung-uk Kim SRP_user_pwd_free(srp_callback_parm.user); 303980815a77SJung-uk Kim srp_callback_parm.user = 30404c6a0400SJung-uk Kim SRP_VBASE_get1_by_user(srp_callback_parm.vb, 304180815a77SJung-uk Kim srp_callback_parm.login); 304280815a77SJung-uk Kim if (srp_callback_parm.user) 304380815a77SJung-uk Kim BIO_printf(bio_s_out, "LOOKUP done %s\n", 304480815a77SJung-uk Kim srp_callback_parm.user->info); 304580815a77SJung-uk Kim else 304680815a77SJung-uk Kim BIO_printf(bio_s_out, "LOOKUP not successful\n"); 304780815a77SJung-uk Kim continue; 304880815a77SJung-uk Kim } 304980815a77SJung-uk Kim #endif 3050e71b7053SJung-uk Kim #if !defined(OPENSSL_SYS_MSDOS) 305174664626SKris Kennaway sleep(1); 305274664626SKris Kennaway #endif 305374664626SKris Kennaway continue; 305474664626SKris Kennaway } 30556f9291ceSJung-uk Kim } else if (i == 0) { /* end of input */ 305674664626SKris Kennaway ret = 1; 305774664626SKris Kennaway goto end; 305874664626SKris Kennaway } 305974664626SKris Kennaway 306074664626SKris Kennaway /* else we have data */ 306174664626SKris Kennaway if (((www == 1) && (strncmp("GET ", buf, 4) == 0)) || 30626f9291ceSJung-uk Kim ((www == 2) && (strncmp("GET /stats ", buf, 11) == 0))) { 306374664626SKris Kennaway char *p; 3064e71b7053SJung-uk Kim X509 *peer = NULL; 306574664626SKris Kennaway STACK_OF(SSL_CIPHER) *sk; 30663b4e3dcbSSimon L. B. Nielsen static const char *space = " "; 306774664626SKris Kennaway 3068e71b7053SJung-uk Kim if (www == 1 && strncmp("GET /reneg", buf, 10) == 0) { 3069e71b7053SJung-uk Kim if (strncmp("GET /renegcert", buf, 14) == 0) 3070e71b7053SJung-uk Kim SSL_set_verify(con, 3071e71b7053SJung-uk Kim SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, 3072e71b7053SJung-uk Kim NULL); 3073e71b7053SJung-uk Kim i = SSL_renegotiate(con); 3074e71b7053SJung-uk Kim BIO_printf(bio_s_out, "SSL_renegotiate -> %d\n", i); 3075e71b7053SJung-uk Kim /* Send the HelloRequest */ 3076e71b7053SJung-uk Kim i = SSL_do_handshake(con); 3077e71b7053SJung-uk Kim if (i <= 0) { 3078e71b7053SJung-uk Kim BIO_printf(bio_s_out, "SSL_do_handshake() Retval %d\n", 3079e71b7053SJung-uk Kim SSL_get_error(con, i)); 3080e71b7053SJung-uk Kim ERR_print_errors(bio_err); 3081e71b7053SJung-uk Kim goto err; 3082e71b7053SJung-uk Kim } 3083e71b7053SJung-uk Kim /* Wait for a ClientHello to come back */ 3084e71b7053SJung-uk Kim FD_ZERO(&readfds); 3085e71b7053SJung-uk Kim openssl_fdset(s, &readfds); 3086e71b7053SJung-uk Kim i = select(width, (void *)&readfds, NULL, NULL, NULL); 3087e71b7053SJung-uk Kim if (i <= 0 || !FD_ISSET(s, &readfds)) { 3088e71b7053SJung-uk Kim BIO_printf(bio_s_out, 3089e71b7053SJung-uk Kim "Error waiting for client response\n"); 3090e71b7053SJung-uk Kim ERR_print_errors(bio_err); 3091e71b7053SJung-uk Kim goto err; 3092e71b7053SJung-uk Kim } 3093e71b7053SJung-uk Kim /* 3094e71b7053SJung-uk Kim * We're not actually expecting any data here and we ignore 3095e71b7053SJung-uk Kim * any that is sent. This is just to force the handshake that 3096e71b7053SJung-uk Kim * we're expecting to come from the client. If they haven't 3097e71b7053SJung-uk Kim * sent one there's not much we can do. 3098e71b7053SJung-uk Kim */ 3099e71b7053SJung-uk Kim BIO_gets(io, buf, bufsize - 1); 3100e71b7053SJung-uk Kim } 3101e71b7053SJung-uk Kim 31026f9291ceSJung-uk Kim BIO_puts(io, 31036f9291ceSJung-uk Kim "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n"); 310474664626SKris Kennaway BIO_puts(io, "<HTML><BODY BGCOLOR=\"#ffffff\">\n"); 310574664626SKris Kennaway BIO_puts(io, "<pre>\n"); 3106e71b7053SJung-uk Kim /* BIO_puts(io, OpenSSL_version(OPENSSL_VERSION)); */ 310774664626SKris Kennaway BIO_puts(io, "\n"); 31086f9291ceSJung-uk Kim for (i = 0; i < local_argc; i++) { 3109e71b7053SJung-uk Kim const char *myp; 3110e71b7053SJung-uk Kim for (myp = local_argv[i]; *myp; myp++) 3111e71b7053SJung-uk Kim switch (*myp) { 3112e71b7053SJung-uk Kim case '<': 3113e71b7053SJung-uk Kim BIO_puts(io, "<"); 3114e71b7053SJung-uk Kim break; 3115e71b7053SJung-uk Kim case '>': 3116e71b7053SJung-uk Kim BIO_puts(io, ">"); 3117e71b7053SJung-uk Kim break; 3118e71b7053SJung-uk Kim case '&': 3119e71b7053SJung-uk Kim BIO_puts(io, "&"); 3120e71b7053SJung-uk Kim break; 3121e71b7053SJung-uk Kim default: 3122e71b7053SJung-uk Kim BIO_write(io, myp, 1); 3123e71b7053SJung-uk Kim break; 3124e71b7053SJung-uk Kim } 312574664626SKris Kennaway BIO_write(io, " ", 1); 312674664626SKris Kennaway } 312774664626SKris Kennaway BIO_puts(io, "\n"); 312874664626SKris Kennaway 312909286989SJung-uk Kim BIO_printf(io, 313009286989SJung-uk Kim "Secure Renegotiation IS%s supported\n", 313109286989SJung-uk Kim SSL_get_secure_renegotiation_support(con) ? 313209286989SJung-uk Kim "" : " NOT"); 313309286989SJung-uk Kim 31346f9291ceSJung-uk Kim /* 31356f9291ceSJung-uk Kim * The following is evil and should not really be done 31366f9291ceSJung-uk Kim */ 313774664626SKris Kennaway BIO_printf(io, "Ciphers supported in s_server binary\n"); 313874664626SKris Kennaway sk = SSL_get_ciphers(con); 313974664626SKris Kennaway j = sk_SSL_CIPHER_num(sk); 31406f9291ceSJung-uk Kim for (i = 0; i < j; i++) { 314174664626SKris Kennaway c = sk_SSL_CIPHER_value(sk, i); 314274664626SKris Kennaway BIO_printf(io, "%-11s:%-25s ", 31436f9291ceSJung-uk Kim SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c)); 314474664626SKris Kennaway if ((((i + 1) % 2) == 0) && (i + 1 != j)) 314574664626SKris Kennaway BIO_puts(io, "\n"); 314674664626SKris Kennaway } 314774664626SKris Kennaway BIO_puts(io, "\n"); 314874664626SKris Kennaway p = SSL_get_shared_ciphers(con, buf, bufsize); 31496f9291ceSJung-uk Kim if (p != NULL) { 31506f9291ceSJung-uk Kim BIO_printf(io, 31516f9291ceSJung-uk Kim "---\nCiphers common between both SSL end points:\n"); 315274664626SKris Kennaway j = i = 0; 31536f9291ceSJung-uk Kim while (*p) { 31546f9291ceSJung-uk Kim if (*p == ':') { 315574664626SKris Kennaway BIO_write(io, space, 26 - j); 315674664626SKris Kennaway i++; 315774664626SKris Kennaway j = 0; 315874664626SKris Kennaway BIO_write(io, ((i % 3) ? " " : "\n"), 1); 31596f9291ceSJung-uk Kim } else { 316074664626SKris Kennaway BIO_write(io, p, 1); 316174664626SKris Kennaway j++; 316274664626SKris Kennaway } 316374664626SKris Kennaway p++; 316474664626SKris Kennaway } 316574664626SKris Kennaway BIO_puts(io, "\n"); 316674664626SKris Kennaway } 31677bded2dbSJung-uk Kim ssl_print_sigalgs(io, con); 31687bded2dbSJung-uk Kim #ifndef OPENSSL_NO_EC 3169e71b7053SJung-uk Kim ssl_print_groups(io, con, 0); 31707bded2dbSJung-uk Kim #endif 3171e71b7053SJung-uk Kim print_ca_names(io, con); 3172e71b7053SJung-uk Kim BIO_printf(io, (SSL_session_reused(con) 31736f9291ceSJung-uk Kim ? "---\nReused, " : "---\nNew, ")); 317474664626SKris Kennaway c = SSL_get_current_cipher(con); 317574664626SKris Kennaway BIO_printf(io, "%s, Cipher is %s\n", 31766f9291ceSJung-uk Kim SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c)); 317774664626SKris Kennaway SSL_SESSION_print(io, SSL_get_session(con)); 317874664626SKris Kennaway BIO_printf(io, "---\n"); 317974664626SKris Kennaway print_stats(io, SSL_get_SSL_CTX(con)); 318074664626SKris Kennaway BIO_printf(io, "---\n"); 318174664626SKris Kennaway peer = SSL_get_peer_certificate(con); 31826f9291ceSJung-uk Kim if (peer != NULL) { 318374664626SKris Kennaway BIO_printf(io, "Client certificate\n"); 318474664626SKris Kennaway X509_print(io, peer); 318574664626SKris Kennaway PEM_write_bio_X509(io, peer); 3186e71b7053SJung-uk Kim X509_free(peer); 3187e71b7053SJung-uk Kim peer = NULL; 3188e71b7053SJung-uk Kim } else { 318974664626SKris Kennaway BIO_puts(io, "no client certificate available\n"); 3190e71b7053SJung-uk Kim } 319147902a71SJung-uk Kim BIO_puts(io, "</pre></BODY></HTML>\r\n\r\n"); 319274664626SKris Kennaway break; 31936f9291ceSJung-uk Kim } else if ((www == 2 || www == 3) 31946f9291ceSJung-uk Kim && (strncmp("GET /", buf, 5) == 0)) { 319574664626SKris Kennaway BIO *file; 319674664626SKris Kennaway char *p, *e; 31976f9291ceSJung-uk Kim static const char *text = 31986f9291ceSJung-uk Kim "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n"; 319974664626SKris Kennaway 320074664626SKris Kennaway /* skip the '/' */ 320174664626SKris Kennaway p = &(buf[5]); 32025740a5e3SKris Kennaway 32035740a5e3SKris Kennaway dot = 1; 32046f9291ceSJung-uk Kim for (e = p; *e != '\0'; e++) { 32055740a5e3SKris Kennaway if (e[0] == ' ') 32065740a5e3SKris Kennaway break; 320774664626SKris Kennaway 320817f01e99SJung-uk Kim if (e[0] == ':') { 320917f01e99SJung-uk Kim /* Windows drive. We treat this the same way as ".." */ 321017f01e99SJung-uk Kim dot = -1; 321117f01e99SJung-uk Kim break; 321217f01e99SJung-uk Kim } 321317f01e99SJung-uk Kim 32146f9291ceSJung-uk Kim switch (dot) { 32155740a5e3SKris Kennaway case 1: 32165740a5e3SKris Kennaway dot = (e[0] == '.') ? 2 : 0; 32175740a5e3SKris Kennaway break; 32185740a5e3SKris Kennaway case 2: 32195740a5e3SKris Kennaway dot = (e[0] == '.') ? 3 : 0; 32205740a5e3SKris Kennaway break; 32215740a5e3SKris Kennaway case 3: 322217f01e99SJung-uk Kim dot = (e[0] == '/' || e[0] == '\\') ? -1 : 0; 32235740a5e3SKris Kennaway break; 32245740a5e3SKris Kennaway } 32255740a5e3SKris Kennaway if (dot == 0) 322617f01e99SJung-uk Kim dot = (e[0] == '/' || e[0] == '\\') ? 1 : 0; 32275740a5e3SKris Kennaway } 32286f9291ceSJung-uk Kim dot = (dot == 3) || (dot == -1); /* filename contains ".." 32296f9291ceSJung-uk Kim * component */ 323074664626SKris Kennaway 32316f9291ceSJung-uk Kim if (*e == '\0') { 323274664626SKris Kennaway BIO_puts(io, text); 323374664626SKris Kennaway BIO_printf(io, "'%s' is an invalid file name\r\n", p); 323474664626SKris Kennaway break; 323574664626SKris Kennaway } 323674664626SKris Kennaway *e = '\0'; 323774664626SKris Kennaway 32386f9291ceSJung-uk Kim if (dot) { 323974664626SKris Kennaway BIO_puts(io, text); 324017f01e99SJung-uk Kim BIO_printf(io, "'%s' contains '..' or ':'\r\n", p); 324174664626SKris Kennaway break; 324274664626SKris Kennaway } 324374664626SKris Kennaway 324417f01e99SJung-uk Kim if (*p == '/' || *p == '\\') { 324574664626SKris Kennaway BIO_puts(io, text); 324674664626SKris Kennaway BIO_printf(io, "'%s' is an invalid path\r\n", p); 324774664626SKris Kennaway break; 324874664626SKris Kennaway } 324974664626SKris Kennaway 325074664626SKris Kennaway /* if a directory, do the index thang */ 32516f9291ceSJung-uk Kim if (app_isdir(p) > 0) { 32525740a5e3SKris Kennaway BIO_puts(io, text); 32535740a5e3SKris Kennaway BIO_printf(io, "'%s' is a directory\r\n", p); 32545740a5e3SKris Kennaway break; 325574664626SKris Kennaway } 325674664626SKris Kennaway 32576f9291ceSJung-uk Kim if ((file = BIO_new_file(p, "r")) == NULL) { 325874664626SKris Kennaway BIO_puts(io, text); 325974664626SKris Kennaway BIO_printf(io, "Error opening '%s'\r\n", p); 326074664626SKris Kennaway ERR_print_errors(io); 326174664626SKris Kennaway break; 326274664626SKris Kennaway } 326374664626SKris Kennaway 326474664626SKris Kennaway if (!s_quiet) 326574664626SKris Kennaway BIO_printf(bio_err, "FILE:%s\n", p); 326674664626SKris Kennaway 32676f9291ceSJung-uk Kim if (www == 2) { 326874664626SKris Kennaway i = strlen(p); 326974664626SKris Kennaway if (((i > 5) && (strcmp(&(p[i - 5]), ".html") == 0)) || 327074664626SKris Kennaway ((i > 4) && (strcmp(&(p[i - 4]), ".php") == 0)) || 327174664626SKris Kennaway ((i > 4) && (strcmp(&(p[i - 4]), ".htm") == 0))) 32726f9291ceSJung-uk Kim BIO_puts(io, 32736f9291ceSJung-uk Kim "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n"); 327474664626SKris Kennaway else 32756f9291ceSJung-uk Kim BIO_puts(io, 32766f9291ceSJung-uk Kim "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n"); 32775c87c606SMark Murray } 327874664626SKris Kennaway /* send the file */ 32796f9291ceSJung-uk Kim for (;;) { 328074664626SKris Kennaway i = BIO_read(file, buf, bufsize); 32816f9291ceSJung-uk Kim if (i <= 0) 32826f9291ceSJung-uk Kim break; 328374664626SKris Kennaway 328474664626SKris Kennaway #ifdef RENEG 328574664626SKris Kennaway total_bytes += i; 3286e71b7053SJung-uk Kim BIO_printf(bio_err, "%d\n", i); 32876f9291ceSJung-uk Kim if (total_bytes > 3 * 1024) { 328874664626SKris Kennaway total_bytes = 0; 3289e71b7053SJung-uk Kim BIO_printf(bio_err, "RENEGOTIATE\n"); 329074664626SKris Kennaway SSL_renegotiate(con); 329174664626SKris Kennaway } 329274664626SKris Kennaway #endif 329374664626SKris Kennaway 32946f9291ceSJung-uk Kim for (j = 0; j < i;) { 329574664626SKris Kennaway #ifdef RENEG 32966f9291ceSJung-uk Kim static count = 0; 32976f9291ceSJung-uk Kim if (++count == 13) { 32986f9291ceSJung-uk Kim SSL_renegotiate(con); 32996f9291ceSJung-uk Kim } 330074664626SKris Kennaway #endif 330174664626SKris Kennaway k = BIO_write(io, &(buf[j]), i - j); 33026f9291ceSJung-uk Kim if (k <= 0) { 3303e71b7053SJung-uk Kim if (!BIO_should_retry(io) 3304e71b7053SJung-uk Kim && !SSL_waiting_for_async(con)) 330574664626SKris Kennaway goto write_error; 33066f9291ceSJung-uk Kim else { 330774664626SKris Kennaway BIO_printf(bio_s_out, "rwrite W BLOCK\n"); 330874664626SKris Kennaway } 33096f9291ceSJung-uk Kim } else { 331074664626SKris Kennaway j += k; 331174664626SKris Kennaway } 331274664626SKris Kennaway } 331374664626SKris Kennaway } 331474664626SKris Kennaway write_error: 331574664626SKris Kennaway BIO_free(file); 331674664626SKris Kennaway break; 331774664626SKris Kennaway } 331874664626SKris Kennaway } 331974664626SKris Kennaway 33206f9291ceSJung-uk Kim for (;;) { 332174664626SKris Kennaway i = (int)BIO_flush(io); 33226f9291ceSJung-uk Kim if (i <= 0) { 332374664626SKris Kennaway if (!BIO_should_retry(io)) 332474664626SKris Kennaway break; 33256f9291ceSJung-uk Kim } else 332674664626SKris Kennaway break; 332774664626SKris Kennaway } 332874664626SKris Kennaway end: 332974664626SKris Kennaway /* make sure we re-use sessions */ 333074664626SKris Kennaway SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); 333174664626SKris Kennaway 333274664626SKris Kennaway err: 33336f9291ceSJung-uk Kim OPENSSL_free(buf); 33346f9291ceSJung-uk Kim BIO_free_all(io); 3335e71b7053SJung-uk Kim return ret; 333674664626SKris Kennaway } 333774664626SKris Kennaway 3338e71b7053SJung-uk Kim static int rev_body(int s, int stype, int prot, unsigned char *context) 33397bded2dbSJung-uk Kim { 33407bded2dbSJung-uk Kim char *buf = NULL; 33417bded2dbSJung-uk Kim int i; 33427bded2dbSJung-uk Kim int ret = 1; 33437bded2dbSJung-uk Kim SSL *con; 33447bded2dbSJung-uk Kim BIO *io, *ssl_bio, *sbio; 33457bded2dbSJung-uk Kim 3346e71b7053SJung-uk Kim buf = app_malloc(bufsize, "server rev buffer"); 33477bded2dbSJung-uk Kim io = BIO_new(BIO_f_buffer()); 33487bded2dbSJung-uk Kim ssl_bio = BIO_new(BIO_f_ssl()); 33497bded2dbSJung-uk Kim if ((io == NULL) || (ssl_bio == NULL)) 33507bded2dbSJung-uk Kim goto err; 33517bded2dbSJung-uk Kim 33527bded2dbSJung-uk Kim /* lets make the output buffer a reasonable size */ 33537bded2dbSJung-uk Kim if (!BIO_set_write_buffer_size(io, bufsize)) 33547bded2dbSJung-uk Kim goto err; 33557bded2dbSJung-uk Kim 33567bded2dbSJung-uk Kim if ((con = SSL_new(ctx)) == NULL) 33577bded2dbSJung-uk Kim goto err; 3358e71b7053SJung-uk Kim 33597bded2dbSJung-uk Kim if (s_tlsextdebug) { 33607bded2dbSJung-uk Kim SSL_set_tlsext_debug_callback(con, tlsext_cb); 33617bded2dbSJung-uk Kim SSL_set_tlsext_debug_arg(con, bio_s_out); 33627bded2dbSJung-uk Kim } 3363e71b7053SJung-uk Kim if (context != NULL 3364e71b7053SJung-uk Kim && !SSL_set_session_id_context(con, context, 3365e71b7053SJung-uk Kim strlen((char *)context))) { 3366e71b7053SJung-uk Kim SSL_free(con); 3367e71b7053SJung-uk Kim ERR_print_errors(bio_err); 3368e71b7053SJung-uk Kim goto err; 33697bded2dbSJung-uk Kim } 33707bded2dbSJung-uk Kim 33717bded2dbSJung-uk Kim sbio = BIO_new_socket(s, BIO_NOCLOSE); 33727bded2dbSJung-uk Kim SSL_set_bio(con, sbio, sbio); 33737bded2dbSJung-uk Kim SSL_set_accept_state(con); 33747bded2dbSJung-uk Kim 3375e71b7053SJung-uk Kim /* No need to free |con| after this. Done by BIO_free(ssl_bio) */ 33767bded2dbSJung-uk Kim BIO_set_ssl(ssl_bio, con, BIO_CLOSE); 33777bded2dbSJung-uk Kim BIO_push(io, ssl_bio); 33787bded2dbSJung-uk Kim #ifdef CHARSET_EBCDIC 33797bded2dbSJung-uk Kim io = BIO_push(BIO_new(BIO_f_ebcdic_filter()), io); 33807bded2dbSJung-uk Kim #endif 33817bded2dbSJung-uk Kim 33827bded2dbSJung-uk Kim if (s_debug) { 33837bded2dbSJung-uk Kim BIO_set_callback(SSL_get_rbio(con), bio_dump_callback); 33847bded2dbSJung-uk Kim BIO_set_callback_arg(SSL_get_rbio(con), (char *)bio_s_out); 33857bded2dbSJung-uk Kim } 33867bded2dbSJung-uk Kim if (s_msg) { 33877bded2dbSJung-uk Kim #ifndef OPENSSL_NO_SSL_TRACE 33887bded2dbSJung-uk Kim if (s_msg == 2) 33897bded2dbSJung-uk Kim SSL_set_msg_callback(con, SSL_trace); 33907bded2dbSJung-uk Kim else 33917bded2dbSJung-uk Kim #endif 33927bded2dbSJung-uk Kim SSL_set_msg_callback(con, msg_cb); 33937bded2dbSJung-uk Kim SSL_set_msg_callback_arg(con, bio_s_msg ? bio_s_msg : bio_s_out); 33947bded2dbSJung-uk Kim } 33957bded2dbSJung-uk Kim 33967bded2dbSJung-uk Kim for (;;) { 33977bded2dbSJung-uk Kim i = BIO_do_handshake(io); 33987bded2dbSJung-uk Kim if (i > 0) 33997bded2dbSJung-uk Kim break; 34007bded2dbSJung-uk Kim if (!BIO_should_retry(io)) { 34017bded2dbSJung-uk Kim BIO_puts(bio_err, "CONNECTION FAILURE\n"); 34027bded2dbSJung-uk Kim ERR_print_errors(bio_err); 34037bded2dbSJung-uk Kim goto end; 34047bded2dbSJung-uk Kim } 340580815a77SJung-uk Kim #ifndef OPENSSL_NO_SRP 340680815a77SJung-uk Kim if (BIO_should_io_special(io) 340780815a77SJung-uk Kim && BIO_get_retry_reason(io) == BIO_RR_SSL_X509_LOOKUP) { 340880815a77SJung-uk Kim BIO_printf(bio_s_out, "LOOKUP renego during accept\n"); 34094c6a0400SJung-uk Kim SRP_user_pwd_free(srp_callback_parm.user); 341080815a77SJung-uk Kim srp_callback_parm.user = 34114c6a0400SJung-uk Kim SRP_VBASE_get1_by_user(srp_callback_parm.vb, 341280815a77SJung-uk Kim srp_callback_parm.login); 341380815a77SJung-uk Kim if (srp_callback_parm.user) 341480815a77SJung-uk Kim BIO_printf(bio_s_out, "LOOKUP done %s\n", 341580815a77SJung-uk Kim srp_callback_parm.user->info); 341680815a77SJung-uk Kim else 341780815a77SJung-uk Kim BIO_printf(bio_s_out, "LOOKUP not successful\n"); 341880815a77SJung-uk Kim continue; 341980815a77SJung-uk Kim } 342080815a77SJung-uk Kim #endif 34217bded2dbSJung-uk Kim } 34227bded2dbSJung-uk Kim BIO_printf(bio_err, "CONNECTION ESTABLISHED\n"); 3423e71b7053SJung-uk Kim print_ssl_summary(con); 34247bded2dbSJung-uk Kim 34257bded2dbSJung-uk Kim for (;;) { 34267bded2dbSJung-uk Kim i = BIO_gets(io, buf, bufsize - 1); 34277bded2dbSJung-uk Kim if (i < 0) { /* error */ 34287bded2dbSJung-uk Kim if (!BIO_should_retry(io)) { 34297bded2dbSJung-uk Kim if (!s_quiet) 34307bded2dbSJung-uk Kim ERR_print_errors(bio_err); 34317bded2dbSJung-uk Kim goto err; 34327bded2dbSJung-uk Kim } else { 34337bded2dbSJung-uk Kim BIO_printf(bio_s_out, "read R BLOCK\n"); 343480815a77SJung-uk Kim #ifndef OPENSSL_NO_SRP 343580815a77SJung-uk Kim if (BIO_should_io_special(io) 343680815a77SJung-uk Kim && BIO_get_retry_reason(io) == BIO_RR_SSL_X509_LOOKUP) { 343780815a77SJung-uk Kim BIO_printf(bio_s_out, "LOOKUP renego during read\n"); 34384c6a0400SJung-uk Kim SRP_user_pwd_free(srp_callback_parm.user); 343980815a77SJung-uk Kim srp_callback_parm.user = 34404c6a0400SJung-uk Kim SRP_VBASE_get1_by_user(srp_callback_parm.vb, 344180815a77SJung-uk Kim srp_callback_parm.login); 344280815a77SJung-uk Kim if (srp_callback_parm.user) 344380815a77SJung-uk Kim BIO_printf(bio_s_out, "LOOKUP done %s\n", 344480815a77SJung-uk Kim srp_callback_parm.user->info); 344580815a77SJung-uk Kim else 344680815a77SJung-uk Kim BIO_printf(bio_s_out, "LOOKUP not successful\n"); 344780815a77SJung-uk Kim continue; 344880815a77SJung-uk Kim } 344980815a77SJung-uk Kim #endif 3450e71b7053SJung-uk Kim #if !defined(OPENSSL_SYS_MSDOS) 34517bded2dbSJung-uk Kim sleep(1); 34527bded2dbSJung-uk Kim #endif 34537bded2dbSJung-uk Kim continue; 34547bded2dbSJung-uk Kim } 34557bded2dbSJung-uk Kim } else if (i == 0) { /* end of input */ 34567bded2dbSJung-uk Kim ret = 1; 34577bded2dbSJung-uk Kim BIO_printf(bio_err, "CONNECTION CLOSED\n"); 34587bded2dbSJung-uk Kim goto end; 34597bded2dbSJung-uk Kim } else { 34607bded2dbSJung-uk Kim char *p = buf + i - 1; 34617bded2dbSJung-uk Kim while (i && (*p == '\n' || *p == '\r')) { 34627bded2dbSJung-uk Kim p--; 34637bded2dbSJung-uk Kim i--; 34647bded2dbSJung-uk Kim } 3465e71b7053SJung-uk Kim if (!s_ign_eof && (i == 5) && (strncmp(buf, "CLOSE", 5) == 0)) { 34667bded2dbSJung-uk Kim ret = 1; 34677bded2dbSJung-uk Kim BIO_printf(bio_err, "CONNECTION CLOSED\n"); 34687bded2dbSJung-uk Kim goto end; 34697bded2dbSJung-uk Kim } 34707bded2dbSJung-uk Kim BUF_reverse((unsigned char *)buf, NULL, i); 34717bded2dbSJung-uk Kim buf[i] = '\n'; 34727bded2dbSJung-uk Kim BIO_write(io, buf, i + 1); 34737bded2dbSJung-uk Kim for (;;) { 34747bded2dbSJung-uk Kim i = BIO_flush(io); 34757bded2dbSJung-uk Kim if (i > 0) 34767bded2dbSJung-uk Kim break; 34777bded2dbSJung-uk Kim if (!BIO_should_retry(io)) 34787bded2dbSJung-uk Kim goto end; 34797bded2dbSJung-uk Kim } 34807bded2dbSJung-uk Kim } 34817bded2dbSJung-uk Kim } 34827bded2dbSJung-uk Kim end: 34837bded2dbSJung-uk Kim /* make sure we re-use sessions */ 34847bded2dbSJung-uk Kim SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); 34857bded2dbSJung-uk Kim 34867bded2dbSJung-uk Kim err: 34877bded2dbSJung-uk Kim 34887bded2dbSJung-uk Kim OPENSSL_free(buf); 34897bded2dbSJung-uk Kim BIO_free_all(io); 3490e71b7053SJung-uk Kim return ret; 34917bded2dbSJung-uk Kim } 34927bded2dbSJung-uk Kim 34935c87c606SMark Murray #define MAX_SESSION_ID_ATTEMPTS 10 3494e71b7053SJung-uk Kim static int generate_session_id(SSL *ssl, unsigned char *id, 34955c87c606SMark Murray unsigned int *id_len) 34965c87c606SMark Murray { 34975c87c606SMark Murray unsigned int count = 0; 34985c87c606SMark Murray do { 3499aeb5019cSJung-uk Kim if (RAND_bytes(id, *id_len) <= 0) 3500ed6b93beSJung-uk Kim return 0; 35016f9291ceSJung-uk Kim /* 35026f9291ceSJung-uk Kim * Prefix the session_id with the required prefix. NB: If our prefix 35036f9291ceSJung-uk Kim * is too long, clip it - but there will be worse effects anyway, eg. 35046f9291ceSJung-uk Kim * the server could only possibly create 1 session ID (ie. the 35056f9291ceSJung-uk Kim * prefix!) so all future session negotiations will fail due to 35066f9291ceSJung-uk Kim * conflicts. 35076f9291ceSJung-uk Kim */ 35085c87c606SMark Murray memcpy(id, session_id_prefix, 35095c87c606SMark Murray (strlen(session_id_prefix) < *id_len) ? 35105c87c606SMark Murray strlen(session_id_prefix) : *id_len); 35115c87c606SMark Murray } 35125c87c606SMark Murray while (SSL_has_matching_session_id(ssl, id, *id_len) && 35135c87c606SMark Murray (++count < MAX_SESSION_ID_ATTEMPTS)); 35145c87c606SMark Murray if (count >= MAX_SESSION_ID_ATTEMPTS) 35155c87c606SMark Murray return 0; 35165c87c606SMark Murray return 1; 35175c87c606SMark Murray } 35187bded2dbSJung-uk Kim 35197bded2dbSJung-uk Kim /* 35207bded2dbSJung-uk Kim * By default s_server uses an in-memory cache which caches SSL_SESSION 35217bded2dbSJung-uk Kim * structures without any serialisation. This hides some bugs which only 35227bded2dbSJung-uk Kim * become apparent in deployed servers. By implementing a basic external 35237bded2dbSJung-uk Kim * session cache some issues can be debugged using s_server. 35247bded2dbSJung-uk Kim */ 35257bded2dbSJung-uk Kim 35267bded2dbSJung-uk Kim typedef struct simple_ssl_session_st { 35277bded2dbSJung-uk Kim unsigned char *id; 35287bded2dbSJung-uk Kim unsigned int idlen; 35297bded2dbSJung-uk Kim unsigned char *der; 35307bded2dbSJung-uk Kim int derlen; 35317bded2dbSJung-uk Kim struct simple_ssl_session_st *next; 35327bded2dbSJung-uk Kim } simple_ssl_session; 35337bded2dbSJung-uk Kim 35347bded2dbSJung-uk Kim static simple_ssl_session *first = NULL; 35357bded2dbSJung-uk Kim 35367bded2dbSJung-uk Kim static int add_session(SSL *ssl, SSL_SESSION *session) 35377bded2dbSJung-uk Kim { 3538e71b7053SJung-uk Kim simple_ssl_session *sess = app_malloc(sizeof(*sess), "get session"); 35397bded2dbSJung-uk Kim unsigned char *p; 35407bded2dbSJung-uk Kim 35417bded2dbSJung-uk Kim SSL_SESSION_get_id(session, &sess->idlen); 35427bded2dbSJung-uk Kim sess->derlen = i2d_SSL_SESSION(session, NULL); 3543e71b7053SJung-uk Kim if (sess->derlen < 0) { 3544e71b7053SJung-uk Kim BIO_printf(bio_err, "Error encoding session\n"); 3545e71b7053SJung-uk Kim OPENSSL_free(sess); 3546e71b7053SJung-uk Kim return 0; 3547e71b7053SJung-uk Kim } 35487bded2dbSJung-uk Kim 3549e71b7053SJung-uk Kim sess->id = OPENSSL_memdup(SSL_SESSION_get_id(session, NULL), sess->idlen); 3550e71b7053SJung-uk Kim sess->der = app_malloc(sess->derlen, "get session buffer"); 3551e71b7053SJung-uk Kim if (!sess->id) { 3552e71b7053SJung-uk Kim BIO_printf(bio_err, "Out of memory adding to external cache\n"); 35537bded2dbSJung-uk Kim OPENSSL_free(sess->id); 35547bded2dbSJung-uk Kim OPENSSL_free(sess->der); 35557bded2dbSJung-uk Kim OPENSSL_free(sess); 35567bded2dbSJung-uk Kim return 0; 35577bded2dbSJung-uk Kim } 35587bded2dbSJung-uk Kim p = sess->der; 3559e71b7053SJung-uk Kim 3560e71b7053SJung-uk Kim /* Assume it still works. */ 3561e71b7053SJung-uk Kim if (i2d_SSL_SESSION(session, &p) != sess->derlen) { 3562e71b7053SJung-uk Kim BIO_printf(bio_err, "Unexpected session encoding length\n"); 3563e71b7053SJung-uk Kim OPENSSL_free(sess->id); 3564e71b7053SJung-uk Kim OPENSSL_free(sess->der); 3565e71b7053SJung-uk Kim OPENSSL_free(sess); 3566e71b7053SJung-uk Kim return 0; 3567e71b7053SJung-uk Kim } 35687bded2dbSJung-uk Kim 35697bded2dbSJung-uk Kim sess->next = first; 35707bded2dbSJung-uk Kim first = sess; 35717bded2dbSJung-uk Kim BIO_printf(bio_err, "New session added to external cache\n"); 35727bded2dbSJung-uk Kim return 0; 35737bded2dbSJung-uk Kim } 35747bded2dbSJung-uk Kim 3575e71b7053SJung-uk Kim static SSL_SESSION *get_session(SSL *ssl, const unsigned char *id, int idlen, 35767bded2dbSJung-uk Kim int *do_copy) 35777bded2dbSJung-uk Kim { 35787bded2dbSJung-uk Kim simple_ssl_session *sess; 35797bded2dbSJung-uk Kim *do_copy = 0; 35807bded2dbSJung-uk Kim for (sess = first; sess; sess = sess->next) { 35817bded2dbSJung-uk Kim if (idlen == (int)sess->idlen && !memcmp(sess->id, id, idlen)) { 35827bded2dbSJung-uk Kim const unsigned char *p = sess->der; 35837bded2dbSJung-uk Kim BIO_printf(bio_err, "Lookup session: cache hit\n"); 35847bded2dbSJung-uk Kim return d2i_SSL_SESSION(NULL, &p, sess->derlen); 35857bded2dbSJung-uk Kim } 35867bded2dbSJung-uk Kim } 35877bded2dbSJung-uk Kim BIO_printf(bio_err, "Lookup session: cache miss\n"); 35887bded2dbSJung-uk Kim return NULL; 35897bded2dbSJung-uk Kim } 35907bded2dbSJung-uk Kim 35917bded2dbSJung-uk Kim static void del_session(SSL_CTX *sctx, SSL_SESSION *session) 35927bded2dbSJung-uk Kim { 35937bded2dbSJung-uk Kim simple_ssl_session *sess, *prev = NULL; 35947bded2dbSJung-uk Kim const unsigned char *id; 35957bded2dbSJung-uk Kim unsigned int idlen; 35967bded2dbSJung-uk Kim id = SSL_SESSION_get_id(session, &idlen); 35977bded2dbSJung-uk Kim for (sess = first; sess; sess = sess->next) { 35987bded2dbSJung-uk Kim if (idlen == sess->idlen && !memcmp(sess->id, id, idlen)) { 35997bded2dbSJung-uk Kim if (prev) 36007bded2dbSJung-uk Kim prev->next = sess->next; 36017bded2dbSJung-uk Kim else 36027bded2dbSJung-uk Kim first = sess->next; 36037bded2dbSJung-uk Kim OPENSSL_free(sess->id); 36047bded2dbSJung-uk Kim OPENSSL_free(sess->der); 36057bded2dbSJung-uk Kim OPENSSL_free(sess); 36067bded2dbSJung-uk Kim return; 36077bded2dbSJung-uk Kim } 36087bded2dbSJung-uk Kim prev = sess; 36097bded2dbSJung-uk Kim } 36107bded2dbSJung-uk Kim } 36117bded2dbSJung-uk Kim 36127bded2dbSJung-uk Kim static void init_session_cache_ctx(SSL_CTX *sctx) 36137bded2dbSJung-uk Kim { 36147bded2dbSJung-uk Kim SSL_CTX_set_session_cache_mode(sctx, 36157bded2dbSJung-uk Kim SSL_SESS_CACHE_NO_INTERNAL | 36167bded2dbSJung-uk Kim SSL_SESS_CACHE_SERVER); 36177bded2dbSJung-uk Kim SSL_CTX_sess_set_new_cb(sctx, add_session); 36187bded2dbSJung-uk Kim SSL_CTX_sess_set_get_cb(sctx, get_session); 36197bded2dbSJung-uk Kim SSL_CTX_sess_set_remove_cb(sctx, del_session); 36207bded2dbSJung-uk Kim } 36217bded2dbSJung-uk Kim 36227bded2dbSJung-uk Kim static void free_sessions(void) 36237bded2dbSJung-uk Kim { 36247bded2dbSJung-uk Kim simple_ssl_session *sess, *tsess; 36257bded2dbSJung-uk Kim for (sess = first; sess;) { 36267bded2dbSJung-uk Kim OPENSSL_free(sess->id); 36277bded2dbSJung-uk Kim OPENSSL_free(sess->der); 36287bded2dbSJung-uk Kim tsess = sess; 36297bded2dbSJung-uk Kim sess = sess->next; 36307bded2dbSJung-uk Kim OPENSSL_free(tsess); 36317bded2dbSJung-uk Kim } 36327bded2dbSJung-uk Kim first = NULL; 36337bded2dbSJung-uk Kim } 3634e71b7053SJung-uk Kim 3635e71b7053SJung-uk Kim #endif /* OPENSSL_NO_SOCK */ 3636