1e71b7053SJung-uk Kim /* 29a3ae0cdSJung-uk Kim * Copyright 1995-2021 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"); 1369a3ae0cdSJung-uk Kim 137*b2bf0c7eSJung-uk Kim if (!SSL_is_dtls(ssl) && SSL_version(ssl) >= TLS1_3_VERSION) { 1389a3ae0cdSJung-uk Kim /* 139*b2bf0c7eSJung-uk Kim * This callback is designed for use in (D)TLSv1.2 (or below). It is 140*b2bf0c7eSJung-uk Kim * possible to use a single callback for all protocol versions - but it 141*b2bf0c7eSJung-uk Kim * is preferred to use a dedicated callback for TLSv1.3. For TLSv1.3 we 142*b2bf0c7eSJung-uk Kim * have psk_find_session_cb. 1439a3ae0cdSJung-uk Kim */ 1449a3ae0cdSJung-uk Kim return 0; 1459a3ae0cdSJung-uk Kim } 1469a3ae0cdSJung-uk Kim 147e71b7053SJung-uk Kim if (identity == NULL) { 1481f13597dSJung-uk Kim BIO_printf(bio_err, "Error: client did not send PSK identity\n"); 1491f13597dSJung-uk Kim goto out_err; 1501f13597dSJung-uk Kim } 1511f13597dSJung-uk Kim if (s_debug) 1521f13597dSJung-uk Kim BIO_printf(bio_s_out, "identity_len=%d identity=%s\n", 1536f9291ceSJung-uk Kim (int)strlen(identity), identity); 1541f13597dSJung-uk Kim 1551f13597dSJung-uk Kim /* here we could lookup the given identity e.g. from a database */ 1566f9291ceSJung-uk Kim if (strcmp(identity, psk_identity) != 0) { 157e71b7053SJung-uk Kim BIO_printf(bio_s_out, "PSK warning: client identity not what we expected" 1586f9291ceSJung-uk Kim " (got '%s' expected '%s')\n", identity, psk_identity); 159e71b7053SJung-uk Kim } else { 1601f13597dSJung-uk Kim if (s_debug) 1611f13597dSJung-uk Kim BIO_printf(bio_s_out, "PSK client identity found\n"); 162e71b7053SJung-uk Kim } 1631f13597dSJung-uk Kim 1641f13597dSJung-uk Kim /* convert the PSK key to binary */ 165e71b7053SJung-uk Kim key = OPENSSL_hexstr2buf(psk_key, &key_len); 166aeb5019cSJung-uk Kim if (key == NULL) { 167aeb5019cSJung-uk Kim BIO_printf(bio_err, "Could not convert PSK key '%s' to buffer\n", 1686f9291ceSJung-uk Kim psk_key); 1691f13597dSJung-uk Kim return 0; 1701f13597dSJung-uk Kim } 171aeb5019cSJung-uk Kim if (key_len > (int)max_psk_len) { 1726f9291ceSJung-uk Kim BIO_printf(bio_err, 173aeb5019cSJung-uk Kim "psk buffer of callback is too small (%d) for key (%ld)\n", 174aeb5019cSJung-uk Kim max_psk_len, key_len); 175aeb5019cSJung-uk Kim OPENSSL_free(key); 1761f13597dSJung-uk Kim return 0; 1771f13597dSJung-uk Kim } 1781f13597dSJung-uk Kim 179aeb5019cSJung-uk Kim memcpy(psk, key, key_len); 180aeb5019cSJung-uk Kim OPENSSL_free(key); 1811f13597dSJung-uk Kim 1821f13597dSJung-uk Kim if (s_debug) 183aeb5019cSJung-uk Kim BIO_printf(bio_s_out, "fetched PSK len=%ld\n", key_len); 184aeb5019cSJung-uk Kim return key_len; 1851f13597dSJung-uk Kim out_err: 1861f13597dSJung-uk Kim if (s_debug) 1871f13597dSJung-uk Kim BIO_printf(bio_err, "Error in PSK server callback\n"); 188e71b7053SJung-uk Kim (void)BIO_flush(bio_err); 189e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 1901f13597dSJung-uk Kim return 0; 1911f13597dSJung-uk Kim } 1921f13597dSJung-uk Kim #endif 1931f13597dSJung-uk Kim 194e71b7053SJung-uk Kim static int psk_find_session_cb(SSL *ssl, const unsigned char *identity, 195e71b7053SJung-uk Kim size_t identity_len, SSL_SESSION **sess) 196e71b7053SJung-uk Kim { 197e71b7053SJung-uk Kim SSL_SESSION *tmpsess = NULL; 198e71b7053SJung-uk Kim unsigned char *key; 199e71b7053SJung-uk Kim long key_len; 200e71b7053SJung-uk Kim const SSL_CIPHER *cipher = NULL; 201e71b7053SJung-uk Kim 202e71b7053SJung-uk Kim if (strlen(psk_identity) != identity_len 203e71b7053SJung-uk Kim || memcmp(psk_identity, identity, identity_len) != 0) { 204c9cf7b5cSJung-uk Kim *sess = NULL; 205c9cf7b5cSJung-uk Kim return 1; 206e71b7053SJung-uk Kim } 207e71b7053SJung-uk Kim 208e71b7053SJung-uk Kim if (psksess != NULL) { 209e71b7053SJung-uk Kim SSL_SESSION_up_ref(psksess); 210e71b7053SJung-uk Kim *sess = psksess; 211e71b7053SJung-uk Kim return 1; 212e71b7053SJung-uk Kim } 213e71b7053SJung-uk Kim 214e71b7053SJung-uk Kim key = OPENSSL_hexstr2buf(psk_key, &key_len); 215e71b7053SJung-uk Kim if (key == NULL) { 216e71b7053SJung-uk Kim BIO_printf(bio_err, "Could not convert PSK key '%s' to buffer\n", 217e71b7053SJung-uk Kim psk_key); 218e71b7053SJung-uk Kim return 0; 219e71b7053SJung-uk Kim } 220e71b7053SJung-uk Kim 221e71b7053SJung-uk Kim /* We default to SHA256 */ 222e71b7053SJung-uk Kim cipher = SSL_CIPHER_find(ssl, tls13_aes128gcmsha256_id); 223e71b7053SJung-uk Kim if (cipher == NULL) { 224e71b7053SJung-uk Kim BIO_printf(bio_err, "Error finding suitable ciphersuite\n"); 225e71b7053SJung-uk Kim OPENSSL_free(key); 226e71b7053SJung-uk Kim return 0; 227e71b7053SJung-uk Kim } 228e71b7053SJung-uk Kim 229e71b7053SJung-uk Kim tmpsess = SSL_SESSION_new(); 230e71b7053SJung-uk Kim if (tmpsess == NULL 231e71b7053SJung-uk Kim || !SSL_SESSION_set1_master_key(tmpsess, key, key_len) 232e71b7053SJung-uk Kim || !SSL_SESSION_set_cipher(tmpsess, cipher) 233e71b7053SJung-uk Kim || !SSL_SESSION_set_protocol_version(tmpsess, SSL_version(ssl))) { 234e71b7053SJung-uk Kim OPENSSL_free(key); 235e71b7053SJung-uk Kim return 0; 236e71b7053SJung-uk Kim } 237e71b7053SJung-uk Kim OPENSSL_free(key); 238e71b7053SJung-uk Kim *sess = tmpsess; 239e71b7053SJung-uk Kim 240e71b7053SJung-uk Kim return 1; 241e71b7053SJung-uk Kim } 242e71b7053SJung-uk Kim 2431f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP 2441f13597dSJung-uk Kim /* This is a context that we pass to callbacks */ 2456f9291ceSJung-uk Kim typedef struct srpsrvparm_st { 2461f13597dSJung-uk Kim char *login; 2471f13597dSJung-uk Kim SRP_VBASE *vb; 2481f13597dSJung-uk Kim SRP_user_pwd *user; 2491f13597dSJung-uk Kim } srpsrvparm; 250e71b7053SJung-uk Kim static srpsrvparm srp_callback_parm; 2511f13597dSJung-uk Kim 2526f9291ceSJung-uk Kim /* 2536f9291ceSJung-uk Kim * This callback pretends to require some asynchronous logic in order to 2546f9291ceSJung-uk Kim * obtain a verifier. When the callback is called for a new connection we 2556f9291ceSJung-uk Kim * return with a negative value. This will provoke the accept etc to return 2566f9291ceSJung-uk Kim * with an LOOKUP_X509. The main logic of the reinvokes the suspended call 2576f9291ceSJung-uk Kim * (which would normally occur after a worker has finished) and we set the 2586f9291ceSJung-uk Kim * user parameters. 2591f13597dSJung-uk Kim */ 260e71b7053SJung-uk Kim static int ssl_srp_server_param_cb(SSL *s, int *ad, void *arg) 2611f13597dSJung-uk Kim { 2621f13597dSJung-uk Kim srpsrvparm *p = (srpsrvparm *) arg; 2634c6a0400SJung-uk Kim int ret = SSL3_AL_FATAL; 2644c6a0400SJung-uk Kim 2656f9291ceSJung-uk Kim if (p->login == NULL && p->user == NULL) { 2661f13597dSJung-uk Kim p->login = SSL_get_srp_username(s); 2671f13597dSJung-uk Kim BIO_printf(bio_err, "SRP username = \"%s\"\n", p->login); 268e71b7053SJung-uk Kim return -1; 2691f13597dSJung-uk Kim } 2701f13597dSJung-uk Kim 2716f9291ceSJung-uk Kim if (p->user == NULL) { 2721f13597dSJung-uk Kim BIO_printf(bio_err, "User %s doesn't exist\n", p->login); 2734c6a0400SJung-uk Kim goto err; 2741f13597dSJung-uk Kim } 2754c6a0400SJung-uk Kim 2766f9291ceSJung-uk Kim if (SSL_set_srp_server_param 2776f9291ceSJung-uk Kim (s, p->user->N, p->user->g, p->user->s, p->user->v, 2786f9291ceSJung-uk Kim p->user->info) < 0) { 2791f13597dSJung-uk Kim *ad = SSL_AD_INTERNAL_ERROR; 2804c6a0400SJung-uk Kim goto err; 2811f13597dSJung-uk Kim } 2826f9291ceSJung-uk Kim BIO_printf(bio_err, 2836f9291ceSJung-uk Kim "SRP parameters set: username = \"%s\" info=\"%s\" \n", 2846f9291ceSJung-uk Kim p->login, p->user->info); 2854c6a0400SJung-uk Kim ret = SSL_ERROR_NONE; 2864c6a0400SJung-uk Kim 2874c6a0400SJung-uk Kim err: 2884c6a0400SJung-uk Kim SRP_user_pwd_free(p->user); 2891f13597dSJung-uk Kim p->user = NULL; 2901f13597dSJung-uk Kim p->login = NULL; 2914c6a0400SJung-uk Kim return ret; 2921f13597dSJung-uk Kim } 2931f13597dSJung-uk Kim 2941f13597dSJung-uk Kim #endif 2951f13597dSJung-uk Kim 29674664626SKris Kennaway static int local_argc = 0; 29774664626SKris Kennaway static char **local_argv; 29874664626SKris Kennaway 29974664626SKris Kennaway #ifdef CHARSET_EBCDIC 30074664626SKris Kennaway static int ebcdic_new(BIO *bi); 30174664626SKris Kennaway static int ebcdic_free(BIO *a); 30274664626SKris Kennaway static int ebcdic_read(BIO *b, char *out, int outl); 3035c87c606SMark Murray static int ebcdic_write(BIO *b, const char *in, int inl); 3045c87c606SMark Murray static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr); 30574664626SKris Kennaway static int ebcdic_gets(BIO *bp, char *buf, int size); 3065c87c606SMark Murray static int ebcdic_puts(BIO *bp, const char *str); 30774664626SKris Kennaway 30874664626SKris Kennaway # define BIO_TYPE_EBCDIC_FILTER (18|0x0200) 309e71b7053SJung-uk Kim static BIO_METHOD *methods_ebcdic = NULL; 31074664626SKris Kennaway 311e71b7053SJung-uk Kim /* This struct is "unwarranted chumminess with the compiler." */ 3126f9291ceSJung-uk Kim typedef struct { 31374664626SKris Kennaway size_t alloced; 31474664626SKris Kennaway char buff[1]; 31574664626SKris Kennaway } EBCDIC_OUTBUFF; 31674664626SKris Kennaway 317e71b7053SJung-uk Kim static const BIO_METHOD *BIO_f_ebcdic_filter() 31874664626SKris Kennaway { 319e71b7053SJung-uk Kim if (methods_ebcdic == NULL) { 320e71b7053SJung-uk Kim methods_ebcdic = BIO_meth_new(BIO_TYPE_EBCDIC_FILTER, 321e71b7053SJung-uk Kim "EBCDIC/ASCII filter"); 322e71b7053SJung-uk Kim if (methods_ebcdic == NULL 323e71b7053SJung-uk Kim || !BIO_meth_set_write(methods_ebcdic, ebcdic_write) 324e71b7053SJung-uk Kim || !BIO_meth_set_read(methods_ebcdic, ebcdic_read) 325e71b7053SJung-uk Kim || !BIO_meth_set_puts(methods_ebcdic, ebcdic_puts) 326e71b7053SJung-uk Kim || !BIO_meth_set_gets(methods_ebcdic, ebcdic_gets) 327e71b7053SJung-uk Kim || !BIO_meth_set_ctrl(methods_ebcdic, ebcdic_ctrl) 328e71b7053SJung-uk Kim || !BIO_meth_set_create(methods_ebcdic, ebcdic_new) 329e71b7053SJung-uk Kim || !BIO_meth_set_destroy(methods_ebcdic, ebcdic_free)) 330e71b7053SJung-uk Kim return NULL; 331e71b7053SJung-uk Kim } 332e71b7053SJung-uk Kim return methods_ebcdic; 33374664626SKris Kennaway } 33474664626SKris Kennaway 33574664626SKris Kennaway static int ebcdic_new(BIO *bi) 33674664626SKris Kennaway { 33774664626SKris Kennaway EBCDIC_OUTBUFF *wbuf; 33874664626SKris Kennaway 339e71b7053SJung-uk Kim wbuf = app_malloc(sizeof(*wbuf) + 1024, "ebcdic wbuf"); 34074664626SKris Kennaway wbuf->alloced = 1024; 34174664626SKris Kennaway wbuf->buff[0] = '\0'; 34274664626SKris Kennaway 343e71b7053SJung-uk Kim BIO_set_data(bi, wbuf); 344e71b7053SJung-uk Kim BIO_set_init(bi, 1); 345e71b7053SJung-uk Kim return 1; 34674664626SKris Kennaway } 34774664626SKris Kennaway 34874664626SKris Kennaway static int ebcdic_free(BIO *a) 34974664626SKris Kennaway { 350e71b7053SJung-uk Kim EBCDIC_OUTBUFF *wbuf; 351e71b7053SJung-uk Kim 3526f9291ceSJung-uk Kim if (a == NULL) 353e71b7053SJung-uk Kim return 0; 354e71b7053SJung-uk Kim wbuf = BIO_get_data(a); 355e71b7053SJung-uk Kim OPENSSL_free(wbuf); 356e71b7053SJung-uk Kim BIO_set_data(a, NULL); 357e71b7053SJung-uk Kim BIO_set_init(a, 0); 358e71b7053SJung-uk Kim 359e71b7053SJung-uk Kim return 1; 36074664626SKris Kennaway } 36174664626SKris Kennaway 36274664626SKris Kennaway static int ebcdic_read(BIO *b, char *out, int outl) 36374664626SKris Kennaway { 36474664626SKris Kennaway int ret = 0; 365e71b7053SJung-uk Kim BIO *next = BIO_next(b); 36674664626SKris Kennaway 3676f9291ceSJung-uk Kim if (out == NULL || outl == 0) 368e71b7053SJung-uk Kim return 0; 369e71b7053SJung-uk Kim if (next == NULL) 370e71b7053SJung-uk Kim return 0; 37174664626SKris Kennaway 372e71b7053SJung-uk Kim ret = BIO_read(next, out, outl); 37374664626SKris Kennaway if (ret > 0) 37474664626SKris Kennaway ascii2ebcdic(out, out, ret); 375e71b7053SJung-uk Kim return ret; 37674664626SKris Kennaway } 37774664626SKris Kennaway 3785c87c606SMark Murray static int ebcdic_write(BIO *b, const char *in, int inl) 37974664626SKris Kennaway { 38074664626SKris Kennaway EBCDIC_OUTBUFF *wbuf; 381e71b7053SJung-uk Kim BIO *next = BIO_next(b); 38274664626SKris Kennaway int ret = 0; 38374664626SKris Kennaway int num; 38474664626SKris Kennaway 3856f9291ceSJung-uk Kim if ((in == NULL) || (inl <= 0)) 386e71b7053SJung-uk Kim return 0; 387e71b7053SJung-uk Kim if (next == NULL) 388e71b7053SJung-uk Kim return 0; 38974664626SKris Kennaway 390e71b7053SJung-uk Kim wbuf = (EBCDIC_OUTBUFF *) BIO_get_data(b); 39174664626SKris Kennaway 3926f9291ceSJung-uk Kim if (inl > (num = wbuf->alloced)) { 39374664626SKris Kennaway num = num + num; /* double the size */ 39474664626SKris Kennaway if (num < inl) 39574664626SKris Kennaway num = inl; 396e71b7053SJung-uk Kim OPENSSL_free(wbuf); 397e71b7053SJung-uk Kim wbuf = app_malloc(sizeof(*wbuf) + num, "grow ebcdic wbuf"); 39874664626SKris Kennaway 39974664626SKris Kennaway wbuf->alloced = num; 40074664626SKris Kennaway wbuf->buff[0] = '\0'; 40174664626SKris Kennaway 402e71b7053SJung-uk Kim BIO_set_data(b, wbuf); 40374664626SKris Kennaway } 40474664626SKris Kennaway 40574664626SKris Kennaway ebcdic2ascii(wbuf->buff, in, inl); 40674664626SKris Kennaway 407e71b7053SJung-uk Kim ret = BIO_write(next, wbuf->buff, inl); 40874664626SKris Kennaway 409e71b7053SJung-uk Kim return ret; 41074664626SKris Kennaway } 41174664626SKris Kennaway 4125c87c606SMark Murray static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr) 41374664626SKris Kennaway { 41474664626SKris Kennaway long ret; 415e71b7053SJung-uk Kim BIO *next = BIO_next(b); 41674664626SKris Kennaway 417e71b7053SJung-uk Kim if (next == NULL) 418e71b7053SJung-uk Kim return 0; 4196f9291ceSJung-uk Kim switch (cmd) { 42074664626SKris Kennaway case BIO_CTRL_DUP: 42174664626SKris Kennaway ret = 0L; 42274664626SKris Kennaway break; 42374664626SKris Kennaway default: 424e71b7053SJung-uk Kim ret = BIO_ctrl(next, cmd, num, ptr); 42574664626SKris Kennaway break; 42674664626SKris Kennaway } 427e71b7053SJung-uk Kim return ret; 42874664626SKris Kennaway } 42974664626SKris Kennaway 43074664626SKris Kennaway static int ebcdic_gets(BIO *bp, char *buf, int size) 43174664626SKris Kennaway { 4325c87c606SMark Murray int i, ret = 0; 433e71b7053SJung-uk Kim BIO *next = BIO_next(bp); 434e71b7053SJung-uk Kim 435e71b7053SJung-uk Kim if (next == NULL) 436e71b7053SJung-uk Kim return 0; 43774664626SKris Kennaway /* return(BIO_gets(bp->next_bio,buf,size));*/ 4386f9291ceSJung-uk Kim for (i = 0; i < size - 1; ++i) { 43974664626SKris Kennaway ret = ebcdic_read(bp, &buf[i], 1); 44074664626SKris Kennaway if (ret <= 0) 44174664626SKris Kennaway break; 4426f9291ceSJung-uk Kim else if (buf[i] == '\n') { 44374664626SKris Kennaway ++i; 44474664626SKris Kennaway break; 44574664626SKris Kennaway } 44674664626SKris Kennaway } 44774664626SKris Kennaway if (i < size) 44874664626SKris Kennaway buf[i] = '\0'; 44974664626SKris Kennaway return (ret < 0 && i == 0) ? ret : i; 45074664626SKris Kennaway } 45174664626SKris Kennaway 4525c87c606SMark Murray static int ebcdic_puts(BIO *bp, const char *str) 45374664626SKris Kennaway { 454e71b7053SJung-uk Kim if (BIO_next(bp) == NULL) 455e71b7053SJung-uk Kim return 0; 45674664626SKris Kennaway return ebcdic_write(bp, str, strlen(str)); 45774664626SKris Kennaway } 45874664626SKris Kennaway #endif 45974664626SKris Kennaway 460db522d3aSSimon L. B. Nielsen /* This is a context that we pass to callbacks */ 461db522d3aSSimon L. B. Nielsen typedef struct tlsextctx_st { 462db522d3aSSimon L. B. Nielsen char *servername; 463db522d3aSSimon L. B. Nielsen BIO *biodebug; 464db522d3aSSimon L. B. Nielsen int extension_error; 465db522d3aSSimon L. B. Nielsen } tlsextctx; 466db522d3aSSimon L. B. Nielsen 467e71b7053SJung-uk Kim static int ssl_servername_cb(SSL *s, int *ad, void *arg) 468db522d3aSSimon L. B. Nielsen { 469db522d3aSSimon L. B. Nielsen tlsextctx *p = (tlsextctx *) arg; 470db522d3aSSimon L. B. Nielsen const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name); 471db522d3aSSimon L. B. Nielsen 472e71b7053SJung-uk Kim if (servername != NULL && p->biodebug != NULL) { 473e71b7053SJung-uk Kim const char *cp = servername; 474e71b7053SJung-uk Kim unsigned char uc; 475e71b7053SJung-uk Kim 476e71b7053SJung-uk Kim BIO_printf(p->biodebug, "Hostname in TLS extension: \""); 477e71b7053SJung-uk Kim while ((uc = *cp++) != 0) 478e71b7053SJung-uk Kim BIO_printf(p->biodebug, 479e71b7053SJung-uk Kim isascii(uc) && isprint(uc) ? "%c" : "\\x%02x", uc); 480e71b7053SJung-uk Kim BIO_printf(p->biodebug, "\"\n"); 481e71b7053SJung-uk Kim } 482e71b7053SJung-uk Kim 483e71b7053SJung-uk Kim if (p->servername == NULL) 484db522d3aSSimon L. B. Nielsen return SSL_TLSEXT_ERR_NOACK; 485db522d3aSSimon L. B. Nielsen 486e71b7053SJung-uk Kim if (servername != NULL) { 487a93cbc2bSJung-uk Kim if (strcasecmp(servername, p->servername)) 488db522d3aSSimon L. B. Nielsen return p->extension_error; 489e71b7053SJung-uk Kim if (ctx2 != NULL) { 4901f13597dSJung-uk Kim BIO_printf(p->biodebug, "Switching server context.\n"); 491db522d3aSSimon L. B. Nielsen SSL_set_SSL_CTX(s, ctx2); 492db522d3aSSimon L. B. Nielsen } 493db522d3aSSimon L. B. Nielsen } 494db522d3aSSimon L. B. Nielsen return SSL_TLSEXT_ERR_OK; 495db522d3aSSimon L. B. Nielsen } 496db522d3aSSimon L. B. Nielsen 497db522d3aSSimon L. B. Nielsen /* Structure passed to cert status callback */ 498db522d3aSSimon L. B. Nielsen typedef struct tlsextstatusctx_st { 499e71b7053SJung-uk Kim int timeout; 500e71b7053SJung-uk Kim /* File to load OCSP Response from (or NULL if no file) */ 501e71b7053SJung-uk Kim char *respin; 502db522d3aSSimon L. B. Nielsen /* Default responder to use */ 503db522d3aSSimon L. B. Nielsen char *host, *path, *port; 504db522d3aSSimon L. B. Nielsen int use_ssl; 505db522d3aSSimon L. B. Nielsen int verbose; 506db522d3aSSimon L. B. Nielsen } tlsextstatusctx; 507db522d3aSSimon L. B. Nielsen 508e71b7053SJung-uk Kim static tlsextstatusctx tlscstatp = { -1 }; 509e71b7053SJung-uk Kim 510e71b7053SJung-uk Kim #ifndef OPENSSL_NO_OCSP 511db522d3aSSimon L. B. Nielsen 5126f9291ceSJung-uk Kim /* 513e71b7053SJung-uk Kim * Helper function to get an OCSP_RESPONSE from a responder. This is a 514e71b7053SJung-uk Kim * simplified version. It examines certificates each time and makes one OCSP 515e71b7053SJung-uk Kim * responder query for each request. A full version would store details such as 516e71b7053SJung-uk Kim * the OCSP certificate IDs and minimise the number of OCSP responses by caching 517e71b7053SJung-uk Kim * them until they were considered "expired". 518db522d3aSSimon L. B. Nielsen */ 519e71b7053SJung-uk Kim static int get_ocsp_resp_from_responder(SSL *s, tlsextstatusctx *srctx, 520e71b7053SJung-uk Kim OCSP_RESPONSE **resp) 521db522d3aSSimon L. B. Nielsen { 522e71b7053SJung-uk Kim char *host = NULL, *port = NULL, *path = NULL; 523db522d3aSSimon L. B. Nielsen int use_ssl; 5241f13597dSJung-uk Kim STACK_OF(OPENSSL_STRING) *aia = NULL; 525db522d3aSSimon L. B. Nielsen X509 *x = NULL; 526e71b7053SJung-uk Kim X509_STORE_CTX *inctx = NULL; 527e71b7053SJung-uk Kim X509_OBJECT *obj; 528db522d3aSSimon L. B. Nielsen OCSP_REQUEST *req = NULL; 529db522d3aSSimon L. B. Nielsen OCSP_CERTID *id = NULL; 530db522d3aSSimon L. B. Nielsen STACK_OF(X509_EXTENSION) *exts; 531db522d3aSSimon L. B. Nielsen int ret = SSL_TLSEXT_ERR_NOACK; 532db522d3aSSimon L. B. Nielsen int i; 533e71b7053SJung-uk Kim 534db522d3aSSimon L. B. Nielsen /* Build up OCSP query from server certificate */ 535db522d3aSSimon L. B. Nielsen x = SSL_get_certificate(s); 536db522d3aSSimon L. B. Nielsen aia = X509_get1_ocsp(x); 537e71b7053SJung-uk Kim if (aia != NULL) { 5381f13597dSJung-uk Kim if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0), 5396f9291ceSJung-uk Kim &host, &port, &path, &use_ssl)) { 540e71b7053SJung-uk Kim BIO_puts(bio_err, "cert_status: can't parse AIA URL\n"); 541db522d3aSSimon L. B. Nielsen goto err; 542db522d3aSSimon L. B. Nielsen } 543db522d3aSSimon L. B. Nielsen if (srctx->verbose) 544e71b7053SJung-uk Kim BIO_printf(bio_err, "cert_status: AIA URL: %s\n", 5451f13597dSJung-uk Kim sk_OPENSSL_STRING_value(aia, 0)); 5466f9291ceSJung-uk Kim } else { 547e71b7053SJung-uk Kim if (srctx->host == NULL) { 548e71b7053SJung-uk Kim BIO_puts(bio_err, 5496f9291ceSJung-uk Kim "cert_status: no AIA and no default responder URL\n"); 550db522d3aSSimon L. B. Nielsen goto done; 551db522d3aSSimon L. B. Nielsen } 552db522d3aSSimon L. B. Nielsen host = srctx->host; 553db522d3aSSimon L. B. Nielsen path = srctx->path; 554db522d3aSSimon L. B. Nielsen port = srctx->port; 555db522d3aSSimon L. B. Nielsen use_ssl = srctx->use_ssl; 556db522d3aSSimon L. B. Nielsen } 557db522d3aSSimon L. B. Nielsen 558e71b7053SJung-uk Kim inctx = X509_STORE_CTX_new(); 559e71b7053SJung-uk Kim if (inctx == NULL) 560e71b7053SJung-uk Kim goto err; 561e71b7053SJung-uk Kim if (!X509_STORE_CTX_init(inctx, 562db522d3aSSimon L. B. Nielsen SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)), 563db522d3aSSimon L. B. Nielsen NULL, NULL)) 564db522d3aSSimon L. B. Nielsen goto err; 565e71b7053SJung-uk Kim obj = X509_STORE_CTX_get_obj_by_subject(inctx, X509_LU_X509, 566e71b7053SJung-uk Kim X509_get_issuer_name(x)); 567e71b7053SJung-uk Kim if (obj == NULL) { 568e71b7053SJung-uk Kim BIO_puts(bio_err, "cert_status: Can't retrieve issuer certificate.\n"); 569db522d3aSSimon L. B. Nielsen goto done; 570db522d3aSSimon L. B. Nielsen } 571e71b7053SJung-uk Kim id = OCSP_cert_to_id(NULL, x, X509_OBJECT_get0_X509(obj)); 572e71b7053SJung-uk Kim X509_OBJECT_free(obj); 573e71b7053SJung-uk Kim if (id == NULL) 574db522d3aSSimon L. B. Nielsen goto err; 575e71b7053SJung-uk Kim req = OCSP_REQUEST_new(); 576e71b7053SJung-uk Kim if (req == NULL) 577db522d3aSSimon L. B. Nielsen goto err; 578db522d3aSSimon L. B. Nielsen if (!OCSP_request_add0_id(req, id)) 579db522d3aSSimon L. B. Nielsen goto err; 580db522d3aSSimon L. B. Nielsen id = NULL; 581db522d3aSSimon L. B. Nielsen /* Add any extensions to the request */ 582db522d3aSSimon L. B. Nielsen SSL_get_tlsext_status_exts(s, &exts); 5836f9291ceSJung-uk Kim for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { 584db522d3aSSimon L. B. Nielsen X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); 585db522d3aSSimon L. B. Nielsen if (!OCSP_REQUEST_add_ext(req, ext, -1)) 586db522d3aSSimon L. B. Nielsen goto err; 587db522d3aSSimon L. B. Nielsen } 588e71b7053SJung-uk Kim *resp = process_responder(req, host, path, port, use_ssl, NULL, 589db522d3aSSimon L. B. Nielsen srctx->timeout); 590e71b7053SJung-uk Kim if (*resp == NULL) { 591e71b7053SJung-uk Kim BIO_puts(bio_err, "cert_status: error querying responder\n"); 592db522d3aSSimon L. B. Nielsen goto done; 593db522d3aSSimon L. B. Nielsen } 594e71b7053SJung-uk Kim 595db522d3aSSimon L. B. Nielsen ret = SSL_TLSEXT_ERR_OK; 596e71b7053SJung-uk Kim goto done; 597e71b7053SJung-uk Kim 598e71b7053SJung-uk Kim err: 599e71b7053SJung-uk Kim ret = SSL_TLSEXT_ERR_ALERT_FATAL; 600db522d3aSSimon L. B. Nielsen done: 601e71b7053SJung-uk Kim /* 602e71b7053SJung-uk Kim * If we parsed aia we need to free; otherwise they were copied and we 603e71b7053SJung-uk Kim * don't 604e71b7053SJung-uk Kim */ 605e71b7053SJung-uk Kim if (aia != NULL) { 606db522d3aSSimon L. B. Nielsen OPENSSL_free(host); 607db522d3aSSimon L. B. Nielsen OPENSSL_free(path); 608db522d3aSSimon L. B. Nielsen OPENSSL_free(port); 609db522d3aSSimon L. B. Nielsen X509_email_free(aia); 610db522d3aSSimon L. B. Nielsen } 611db522d3aSSimon L. B. Nielsen OCSP_CERTID_free(id); 612db522d3aSSimon L. B. Nielsen OCSP_REQUEST_free(req); 613e71b7053SJung-uk Kim X509_STORE_CTX_free(inctx); 614db522d3aSSimon L. B. Nielsen return ret; 615db522d3aSSimon L. B. Nielsen } 6161f13597dSJung-uk Kim 617e71b7053SJung-uk Kim /* 618e71b7053SJung-uk Kim * Certificate Status callback. This is called when a client includes a 619e71b7053SJung-uk Kim * certificate status request extension. The response is either obtained from a 620e71b7053SJung-uk Kim * file, or from an OCSP responder. 621e71b7053SJung-uk Kim */ 622e71b7053SJung-uk Kim static int cert_status_cb(SSL *s, void *arg) 623e71b7053SJung-uk Kim { 624e71b7053SJung-uk Kim tlsextstatusctx *srctx = arg; 625e71b7053SJung-uk Kim OCSP_RESPONSE *resp = NULL; 626e71b7053SJung-uk Kim unsigned char *rspder = NULL; 627e71b7053SJung-uk Kim int rspderlen; 628e71b7053SJung-uk Kim int ret = SSL_TLSEXT_ERR_ALERT_FATAL; 629e71b7053SJung-uk Kim 630e71b7053SJung-uk Kim if (srctx->verbose) 631e71b7053SJung-uk Kim BIO_puts(bio_err, "cert_status: callback called\n"); 632e71b7053SJung-uk Kim 633e71b7053SJung-uk Kim if (srctx->respin != NULL) { 634e71b7053SJung-uk Kim BIO *derbio = bio_open_default(srctx->respin, 'r', FORMAT_ASN1); 635e71b7053SJung-uk Kim if (derbio == NULL) { 636e71b7053SJung-uk Kim BIO_puts(bio_err, "cert_status: Cannot open OCSP response file\n"); 637e71b7053SJung-uk Kim goto err; 638e71b7053SJung-uk Kim } 639e71b7053SJung-uk Kim resp = d2i_OCSP_RESPONSE_bio(derbio, NULL); 640e71b7053SJung-uk Kim BIO_free(derbio); 641e71b7053SJung-uk Kim if (resp == NULL) { 642e71b7053SJung-uk Kim BIO_puts(bio_err, "cert_status: Error reading OCSP response\n"); 643e71b7053SJung-uk Kim goto err; 644e71b7053SJung-uk Kim } 645e71b7053SJung-uk Kim } else { 646e71b7053SJung-uk Kim ret = get_ocsp_resp_from_responder(s, srctx, &resp); 647e71b7053SJung-uk Kim if (ret != SSL_TLSEXT_ERR_OK) 648e71b7053SJung-uk Kim goto err; 649e71b7053SJung-uk Kim } 650e71b7053SJung-uk Kim 651e71b7053SJung-uk Kim rspderlen = i2d_OCSP_RESPONSE(resp, &rspder); 652e71b7053SJung-uk Kim if (rspderlen <= 0) 653e71b7053SJung-uk Kim goto err; 654e71b7053SJung-uk Kim 655e71b7053SJung-uk Kim SSL_set_tlsext_status_ocsp_resp(s, rspder, rspderlen); 656e71b7053SJung-uk Kim if (srctx->verbose) { 657e71b7053SJung-uk Kim BIO_puts(bio_err, "cert_status: ocsp response sent:\n"); 658e71b7053SJung-uk Kim OCSP_RESPONSE_print(bio_err, resp, 2); 659e71b7053SJung-uk Kim } 660e71b7053SJung-uk Kim 661e71b7053SJung-uk Kim ret = SSL_TLSEXT_ERR_OK; 662e71b7053SJung-uk Kim 663e71b7053SJung-uk Kim err: 664e71b7053SJung-uk Kim if (ret != SSL_TLSEXT_ERR_OK) 665e71b7053SJung-uk Kim ERR_print_errors(bio_err); 666e71b7053SJung-uk Kim 667e71b7053SJung-uk Kim OCSP_RESPONSE_free(resp); 668e71b7053SJung-uk Kim 669e71b7053SJung-uk Kim return ret; 670e71b7053SJung-uk Kim } 671e71b7053SJung-uk Kim #endif 672e71b7053SJung-uk Kim 6731f13597dSJung-uk Kim #ifndef OPENSSL_NO_NEXTPROTONEG 6741f13597dSJung-uk Kim /* This is the context that we pass to next_proto_cb */ 6751f13597dSJung-uk Kim typedef struct tlsextnextprotoctx_st { 6761f13597dSJung-uk Kim unsigned char *data; 677e71b7053SJung-uk Kim size_t len; 6781f13597dSJung-uk Kim } tlsextnextprotoctx; 6791f13597dSJung-uk Kim 6806f9291ceSJung-uk Kim static int next_proto_cb(SSL *s, const unsigned char **data, 6816f9291ceSJung-uk Kim unsigned int *len, void *arg) 6821f13597dSJung-uk Kim { 6831f13597dSJung-uk Kim tlsextnextprotoctx *next_proto = arg; 6841f13597dSJung-uk Kim 6851f13597dSJung-uk Kim *data = next_proto->data; 6861f13597dSJung-uk Kim *len = next_proto->len; 6871f13597dSJung-uk Kim 6881f13597dSJung-uk Kim return SSL_TLSEXT_ERR_OK; 6891f13597dSJung-uk Kim } 6901f13597dSJung-uk Kim #endif /* ndef OPENSSL_NO_NEXTPROTONEG */ 6911f13597dSJung-uk Kim 6927bded2dbSJung-uk Kim /* This the context that we pass to alpn_cb */ 6937bded2dbSJung-uk Kim typedef struct tlsextalpnctx_st { 6947bded2dbSJung-uk Kim unsigned char *data; 695e71b7053SJung-uk Kim size_t len; 6967bded2dbSJung-uk Kim } tlsextalpnctx; 6977bded2dbSJung-uk Kim 6987bded2dbSJung-uk Kim static int alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen, 6997bded2dbSJung-uk Kim const unsigned char *in, unsigned int inlen, void *arg) 7007bded2dbSJung-uk Kim { 7017bded2dbSJung-uk Kim tlsextalpnctx *alpn_ctx = arg; 7027bded2dbSJung-uk Kim 7037bded2dbSJung-uk Kim if (!s_quiet) { 7047bded2dbSJung-uk Kim /* We can assume that |in| is syntactically valid. */ 705e71b7053SJung-uk Kim unsigned int i; 7067bded2dbSJung-uk Kim BIO_printf(bio_s_out, "ALPN protocols advertised by the client: "); 7077bded2dbSJung-uk Kim for (i = 0; i < inlen;) { 7087bded2dbSJung-uk Kim if (i) 7097bded2dbSJung-uk Kim BIO_write(bio_s_out, ", ", 2); 7107bded2dbSJung-uk Kim BIO_write(bio_s_out, &in[i + 1], in[i]); 7117bded2dbSJung-uk Kim i += in[i] + 1; 7127bded2dbSJung-uk Kim } 7137bded2dbSJung-uk Kim BIO_write(bio_s_out, "\n", 1); 7147bded2dbSJung-uk Kim } 7157bded2dbSJung-uk Kim 7167bded2dbSJung-uk Kim if (SSL_select_next_proto 7177bded2dbSJung-uk Kim ((unsigned char **)out, outlen, alpn_ctx->data, alpn_ctx->len, in, 7187bded2dbSJung-uk Kim inlen) != OPENSSL_NPN_NEGOTIATED) { 7197bded2dbSJung-uk Kim return SSL_TLSEXT_ERR_NOACK; 7207bded2dbSJung-uk Kim } 7217bded2dbSJung-uk Kim 7227bded2dbSJung-uk Kim if (!s_quiet) { 7237bded2dbSJung-uk Kim BIO_printf(bio_s_out, "ALPN protocols selected: "); 7247bded2dbSJung-uk Kim BIO_write(bio_s_out, *out, *outlen); 7257bded2dbSJung-uk Kim BIO_write(bio_s_out, "\n", 1); 7267bded2dbSJung-uk Kim } 7277bded2dbSJung-uk Kim 7287bded2dbSJung-uk Kim return SSL_TLSEXT_ERR_OK; 7297bded2dbSJung-uk Kim } 7301f13597dSJung-uk Kim 731e71b7053SJung-uk Kim static int not_resumable_sess_cb(SSL *s, int is_forward_secure) 732e71b7053SJung-uk Kim { 733e71b7053SJung-uk Kim /* disable resumption for sessions with forward secure ciphers */ 734e71b7053SJung-uk Kim return is_forward_secure; 735e71b7053SJung-uk Kim } 736f579bf8eSKris Kennaway 737e71b7053SJung-uk Kim typedef enum OPTION_choice { 738e71b7053SJung-uk Kim OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ENGINE, 739e71b7053SJung-uk Kim OPT_4, OPT_6, OPT_ACCEPT, OPT_PORT, OPT_UNIX, OPT_UNLINK, OPT_NACCEPT, 740e71b7053SJung-uk Kim OPT_VERIFY, OPT_NAMEOPT, OPT_UPPER_V_VERIFY, OPT_CONTEXT, OPT_CERT, OPT_CRL, 741e71b7053SJung-uk Kim OPT_CRL_DOWNLOAD, OPT_SERVERINFO, OPT_CERTFORM, OPT_KEY, OPT_KEYFORM, 742e71b7053SJung-uk Kim OPT_PASS, OPT_CERT_CHAIN, OPT_DHPARAM, OPT_DCERTFORM, OPT_DCERT, 743e71b7053SJung-uk Kim OPT_DKEYFORM, OPT_DPASS, OPT_DKEY, OPT_DCERT_CHAIN, OPT_NOCERT, 744e71b7053SJung-uk Kim OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH, OPT_NO_CACHE, 745e71b7053SJung-uk Kim OPT_EXT_CACHE, OPT_CRLFORM, OPT_VERIFY_RET_ERROR, OPT_VERIFY_QUIET, 746e71b7053SJung-uk Kim OPT_BUILD_CHAIN, OPT_CAFILE, OPT_NOCAFILE, OPT_CHAINCAFILE, 747e71b7053SJung-uk Kim OPT_VERIFYCAFILE, OPT_NBIO, OPT_NBIO_TEST, OPT_IGN_EOF, OPT_NO_IGN_EOF, 748e71b7053SJung-uk Kim OPT_DEBUG, OPT_TLSEXTDEBUG, OPT_STATUS, OPT_STATUS_VERBOSE, 749e71b7053SJung-uk Kim OPT_STATUS_TIMEOUT, OPT_STATUS_URL, OPT_STATUS_FILE, OPT_MSG, OPT_MSGFILE, 750e71b7053SJung-uk Kim OPT_TRACE, OPT_SECURITY_DEBUG, OPT_SECURITY_DEBUG_VERBOSE, OPT_STATE, 751e71b7053SJung-uk Kim OPT_CRLF, OPT_QUIET, OPT_BRIEF, OPT_NO_DHE, 752e71b7053SJung-uk Kim OPT_NO_RESUME_EPHEMERAL, OPT_PSK_IDENTITY, OPT_PSK_HINT, OPT_PSK, 753e71b7053SJung-uk Kim OPT_PSK_SESS, OPT_SRPVFILE, OPT_SRPUSERSEED, OPT_REV, OPT_WWW, 754e71b7053SJung-uk Kim OPT_UPPER_WWW, OPT_HTTP, OPT_ASYNC, OPT_SSL_CONFIG, 755e71b7053SJung-uk Kim OPT_MAX_SEND_FRAG, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES, OPT_READ_BUF, 756e71b7053SJung-uk Kim OPT_SSL3, OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1, 757e71b7053SJung-uk Kim OPT_DTLS1_2, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_LISTEN, OPT_STATELESS, 758e71b7053SJung-uk Kim OPT_ID_PREFIX, OPT_SERVERNAME, OPT_SERVERNAME_FATAL, 759e71b7053SJung-uk Kim OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN, 760e71b7053SJung-uk Kim OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, 761e71b7053SJung-uk Kim OPT_KEYLOG_FILE, OPT_MAX_EARLY, OPT_RECV_MAX_EARLY, OPT_EARLY_DATA, 7626935a639SJung-uk Kim OPT_S_NUM_TICKETS, OPT_ANTI_REPLAY, OPT_NO_ANTI_REPLAY, OPT_SCTP_LABEL_BUG, 763e71b7053SJung-uk Kim OPT_R_ENUM, 764e71b7053SJung-uk Kim OPT_S_ENUM, 765e71b7053SJung-uk Kim OPT_V_ENUM, 766e71b7053SJung-uk Kim OPT_X_ENUM 767e71b7053SJung-uk Kim } OPTION_CHOICE; 768e71b7053SJung-uk Kim 769e71b7053SJung-uk Kim const OPTIONS s_server_options[] = { 770e71b7053SJung-uk Kim {"help", OPT_HELP, '-', "Display this summary"}, 771e71b7053SJung-uk Kim {"port", OPT_PORT, 'p', 772e71b7053SJung-uk Kim "TCP/IP port to listen on for connections (default is " PORT ")"}, 773e71b7053SJung-uk Kim {"accept", OPT_ACCEPT, 's', 774e71b7053SJung-uk Kim "TCP/IP optional host and port to listen on for connections (default is *:" PORT ")"}, 775e71b7053SJung-uk Kim #ifdef AF_UNIX 776e71b7053SJung-uk Kim {"unix", OPT_UNIX, 's', "Unix domain socket to accept on"}, 777db522d3aSSimon L. B. Nielsen #endif 778e71b7053SJung-uk Kim {"4", OPT_4, '-', "Use IPv4 only"}, 779e71b7053SJung-uk Kim {"6", OPT_6, '-', "Use IPv6 only"}, 780e71b7053SJung-uk Kim #ifdef AF_UNIX 781e71b7053SJung-uk Kim {"unlink", OPT_UNLINK, '-', "For -unix, unlink existing socket first"}, 782e71b7053SJung-uk Kim #endif 783e71b7053SJung-uk Kim {"context", OPT_CONTEXT, 's', "Set session ID context"}, 784e71b7053SJung-uk Kim {"verify", OPT_VERIFY, 'n', "Turn on peer certificate verification"}, 785e71b7053SJung-uk Kim {"Verify", OPT_UPPER_V_VERIFY, 'n', 786e71b7053SJung-uk Kim "Turn on peer certificate verification, must have a cert"}, 787e71b7053SJung-uk Kim {"cert", OPT_CERT, '<', "Certificate file to use; default is " TEST_CERT}, 788e71b7053SJung-uk Kim {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, 789e71b7053SJung-uk Kim {"naccept", OPT_NACCEPT, 'p', "Terminate after #num connections"}, 790e71b7053SJung-uk Kim {"serverinfo", OPT_SERVERINFO, 's', 791e71b7053SJung-uk Kim "PEM serverinfo file for certificate"}, 792e71b7053SJung-uk Kim {"certform", OPT_CERTFORM, 'F', 793e71b7053SJung-uk Kim "Certificate format (PEM or DER) PEM default"}, 794e71b7053SJung-uk Kim {"key", OPT_KEY, 's', 795e71b7053SJung-uk Kim "Private Key if not in -cert; default is " TEST_CERT}, 796e71b7053SJung-uk Kim {"keyform", OPT_KEYFORM, 'f', 797e71b7053SJung-uk Kim "Key format (PEM, DER or ENGINE) PEM default"}, 798e71b7053SJung-uk Kim {"pass", OPT_PASS, 's', "Private key file pass phrase source"}, 799e71b7053SJung-uk Kim {"dcert", OPT_DCERT, '<', 800e71b7053SJung-uk Kim "Second certificate file to use (usually for DSA)"}, 801e71b7053SJung-uk Kim {"dhparam", OPT_DHPARAM, '<', "DH parameters file to use"}, 802e71b7053SJung-uk Kim {"dcertform", OPT_DCERTFORM, 'F', 803e71b7053SJung-uk Kim "Second certificate format (PEM or DER) PEM default"}, 804e71b7053SJung-uk Kim {"dkey", OPT_DKEY, '<', 805e71b7053SJung-uk Kim "Second private key file to use (usually for DSA)"}, 806e71b7053SJung-uk Kim {"dkeyform", OPT_DKEYFORM, 'F', 807e71b7053SJung-uk Kim "Second key format (PEM, DER or ENGINE) PEM default"}, 808e71b7053SJung-uk Kim {"dpass", OPT_DPASS, 's', "Second private key file pass phrase source"}, 809e71b7053SJung-uk Kim {"nbio_test", OPT_NBIO_TEST, '-', "Test with the non-blocking test bio"}, 810e71b7053SJung-uk Kim {"crlf", OPT_CRLF, '-', "Convert LF from terminal into CRLF"}, 811e71b7053SJung-uk Kim {"debug", OPT_DEBUG, '-', "Print more output"}, 812e71b7053SJung-uk Kim {"msg", OPT_MSG, '-', "Show protocol messages"}, 813e71b7053SJung-uk Kim {"msgfile", OPT_MSGFILE, '>', 814e71b7053SJung-uk Kim "File to send output of -msg or -trace, instead of stdout"}, 815e71b7053SJung-uk Kim {"state", OPT_STATE, '-', "Print the SSL states"}, 816e71b7053SJung-uk Kim {"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"}, 817e71b7053SJung-uk Kim {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"}, 818e71b7053SJung-uk Kim {"no-CAfile", OPT_NOCAFILE, '-', 819e71b7053SJung-uk Kim "Do not load the default certificates file"}, 820e71b7053SJung-uk Kim {"no-CApath", OPT_NOCAPATH, '-', 821e71b7053SJung-uk Kim "Do not load certificates from the default certificates directory"}, 822e71b7053SJung-uk Kim {"nocert", OPT_NOCERT, '-', "Don't use any certificates (Anon-DH)"}, 823e71b7053SJung-uk Kim {"quiet", OPT_QUIET, '-', "No server output"}, 824e71b7053SJung-uk Kim {"no_resume_ephemeral", OPT_NO_RESUME_EPHEMERAL, '-', 825e71b7053SJung-uk Kim "Disable caching and tickets if ephemeral (EC)DH is used"}, 826e71b7053SJung-uk Kim {"www", OPT_WWW, '-', "Respond to a 'GET /' with a status page"}, 827e71b7053SJung-uk Kim {"WWW", OPT_UPPER_WWW, '-', "Respond to a 'GET with the file ./path"}, 828e71b7053SJung-uk Kim {"servername", OPT_SERVERNAME, 's', 829e71b7053SJung-uk Kim "Servername for HostName TLS extension"}, 830e71b7053SJung-uk Kim {"servername_fatal", OPT_SERVERNAME_FATAL, '-', 831e71b7053SJung-uk Kim "mismatch send fatal alert (default warning alert)"}, 832e71b7053SJung-uk Kim {"cert2", OPT_CERT2, '<', 833e71b7053SJung-uk Kim "Certificate file to use for servername; default is" TEST_CERT2}, 834e71b7053SJung-uk Kim {"key2", OPT_KEY2, '<', 835e71b7053SJung-uk Kim "-Private Key file to use for servername if not in -cert2"}, 836e71b7053SJung-uk Kim {"tlsextdebug", OPT_TLSEXTDEBUG, '-', 837e71b7053SJung-uk Kim "Hex dump of all TLS extensions received"}, 838e71b7053SJung-uk Kim {"HTTP", OPT_HTTP, '-', "Like -WWW but ./path includes HTTP headers"}, 839e71b7053SJung-uk Kim {"id_prefix", OPT_ID_PREFIX, 's', 840e71b7053SJung-uk Kim "Generate SSL/TLS session IDs prefixed by arg"}, 841e71b7053SJung-uk Kim OPT_R_OPTIONS, 842e71b7053SJung-uk Kim {"keymatexport", OPT_KEYMATEXPORT, 's', 843e71b7053SJung-uk Kim "Export keying material using label"}, 844e71b7053SJung-uk Kim {"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p', 845e71b7053SJung-uk Kim "Export len bytes of keying material (default 20)"}, 846e71b7053SJung-uk Kim {"CRL", OPT_CRL, '<', "CRL file to use"}, 847e71b7053SJung-uk Kim {"crl_download", OPT_CRL_DOWNLOAD, '-', 848e71b7053SJung-uk Kim "Download CRL from distribution points"}, 849e71b7053SJung-uk Kim {"cert_chain", OPT_CERT_CHAIN, '<', 850e71b7053SJung-uk Kim "certificate chain file in PEM format"}, 851e71b7053SJung-uk Kim {"dcert_chain", OPT_DCERT_CHAIN, '<', 852e71b7053SJung-uk Kim "second certificate chain file in PEM format"}, 853e71b7053SJung-uk Kim {"chainCApath", OPT_CHAINCAPATH, '/', 854e71b7053SJung-uk Kim "use dir as certificate store path to build CA certificate chain"}, 855e71b7053SJung-uk Kim {"verifyCApath", OPT_VERIFYCAPATH, '/', 856e71b7053SJung-uk Kim "use dir as certificate store path to verify CA certificate"}, 857e71b7053SJung-uk Kim {"no_cache", OPT_NO_CACHE, '-', "Disable session cache"}, 858e71b7053SJung-uk Kim {"ext_cache", OPT_EXT_CACHE, '-', 859e71b7053SJung-uk Kim "Disable internal cache, setup and use external cache"}, 860e71b7053SJung-uk Kim {"CRLform", OPT_CRLFORM, 'F', "CRL format (PEM or DER) PEM is default"}, 861e71b7053SJung-uk Kim {"verify_return_error", OPT_VERIFY_RET_ERROR, '-', 862e71b7053SJung-uk Kim "Close connection on verification error"}, 863e71b7053SJung-uk Kim {"verify_quiet", OPT_VERIFY_QUIET, '-', 864e71b7053SJung-uk Kim "No verify output except verify errors"}, 865e71b7053SJung-uk Kim {"build_chain", OPT_BUILD_CHAIN, '-', "Build certificate chain"}, 866e71b7053SJung-uk Kim {"chainCAfile", OPT_CHAINCAFILE, '<', 867e71b7053SJung-uk Kim "CA file for certificate chain (PEM format)"}, 868e71b7053SJung-uk Kim {"verifyCAfile", OPT_VERIFYCAFILE, '<', 869e71b7053SJung-uk Kim "CA file for certificate verification (PEM format)"}, 870e71b7053SJung-uk Kim {"ign_eof", OPT_IGN_EOF, '-', "ignore input eof (default when -quiet)"}, 871e71b7053SJung-uk Kim {"no_ign_eof", OPT_NO_IGN_EOF, '-', "Do not ignore input eof"}, 872e71b7053SJung-uk Kim #ifndef OPENSSL_NO_OCSP 873e71b7053SJung-uk Kim {"status", OPT_STATUS, '-', "Request certificate status from server"}, 874e71b7053SJung-uk Kim {"status_verbose", OPT_STATUS_VERBOSE, '-', 875e71b7053SJung-uk Kim "Print more output in certificate status callback"}, 876e71b7053SJung-uk Kim {"status_timeout", OPT_STATUS_TIMEOUT, 'n', 877e71b7053SJung-uk Kim "Status request responder timeout"}, 878e71b7053SJung-uk Kim {"status_url", OPT_STATUS_URL, 's', "Status request fallback URL"}, 879e71b7053SJung-uk Kim {"status_file", OPT_STATUS_FILE, '<', 880e71b7053SJung-uk Kim "File containing DER encoded OCSP Response"}, 881e71b7053SJung-uk Kim #endif 882e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SSL_TRACE 883e71b7053SJung-uk Kim {"trace", OPT_TRACE, '-', "trace protocol messages"}, 884e71b7053SJung-uk Kim #endif 885e71b7053SJung-uk Kim {"security_debug", OPT_SECURITY_DEBUG, '-', 886e71b7053SJung-uk Kim "Print output from SSL/TLS security framework"}, 887e71b7053SJung-uk Kim {"security_debug_verbose", OPT_SECURITY_DEBUG_VERBOSE, '-', 888e71b7053SJung-uk Kim "Print more output from SSL/TLS security framework"}, 889e71b7053SJung-uk Kim {"brief", OPT_BRIEF, '-', 890e71b7053SJung-uk Kim "Restrict output to brief summary of connection parameters"}, 891e71b7053SJung-uk Kim {"rev", OPT_REV, '-', 892e71b7053SJung-uk Kim "act as a simple test server which just sends back with the received text reversed"}, 893e71b7053SJung-uk Kim {"async", OPT_ASYNC, '-', "Operate in asynchronous mode"}, 894e71b7053SJung-uk Kim {"ssl_config", OPT_SSL_CONFIG, 's', 895e71b7053SJung-uk Kim "Configure SSL_CTX using the configuration 'val'"}, 896e71b7053SJung-uk Kim {"max_send_frag", OPT_MAX_SEND_FRAG, 'p', "Maximum Size of send frames "}, 897e71b7053SJung-uk Kim {"split_send_frag", OPT_SPLIT_SEND_FRAG, 'p', 898e71b7053SJung-uk Kim "Size used to split data for encrypt pipelines"}, 899e71b7053SJung-uk Kim {"max_pipelines", OPT_MAX_PIPELINES, 'p', 900e71b7053SJung-uk Kim "Maximum number of encrypt/decrypt pipelines to be used"}, 901e71b7053SJung-uk Kim {"read_buf", OPT_READ_BUF, 'p', 902e71b7053SJung-uk Kim "Default read buffer size to be used for connections"}, 903e71b7053SJung-uk Kim OPT_S_OPTIONS, 904e71b7053SJung-uk Kim OPT_V_OPTIONS, 905e71b7053SJung-uk Kim OPT_X_OPTIONS, 906e71b7053SJung-uk Kim {"nbio", OPT_NBIO, '-', "Use non-blocking IO"}, 907e71b7053SJung-uk Kim {"psk_identity", OPT_PSK_IDENTITY, 's', "PSK identity to expect"}, 908e71b7053SJung-uk Kim #ifndef OPENSSL_NO_PSK 909e71b7053SJung-uk Kim {"psk_hint", OPT_PSK_HINT, 's', "PSK identity hint to use"}, 910e71b7053SJung-uk Kim #endif 911e71b7053SJung-uk Kim {"psk", OPT_PSK, 's', "PSK in hex (without 0x)"}, 912e71b7053SJung-uk Kim {"psk_session", OPT_PSK_SESS, '<', "File to read PSK SSL session from"}, 9131f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP 914e71b7053SJung-uk Kim {"srpvfile", OPT_SRPVFILE, '<', "The verifier file for SRP"}, 915e71b7053SJung-uk Kim {"srpuserseed", OPT_SRPUSERSEED, 's', 916e71b7053SJung-uk Kim "A seed string for a default user salt"}, 917e71b7053SJung-uk Kim #endif 918e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SSL3 919e71b7053SJung-uk Kim {"ssl3", OPT_SSL3, '-', "Just talk SSLv3"}, 920e71b7053SJung-uk Kim #endif 921e71b7053SJung-uk Kim #ifndef OPENSSL_NO_TLS1 922e71b7053SJung-uk Kim {"tls1", OPT_TLS1, '-', "Just talk TLSv1"}, 923e71b7053SJung-uk Kim #endif 924e71b7053SJung-uk Kim #ifndef OPENSSL_NO_TLS1_1 925e71b7053SJung-uk Kim {"tls1_1", OPT_TLS1_1, '-', "Just talk TLSv1.1"}, 926e71b7053SJung-uk Kim #endif 927e71b7053SJung-uk Kim #ifndef OPENSSL_NO_TLS1_2 928e71b7053SJung-uk Kim {"tls1_2", OPT_TLS1_2, '-', "just talk TLSv1.2"}, 929e71b7053SJung-uk Kim #endif 930e71b7053SJung-uk Kim #ifndef OPENSSL_NO_TLS1_3 931e71b7053SJung-uk Kim {"tls1_3", OPT_TLS1_3, '-', "just talk TLSv1.3"}, 932e71b7053SJung-uk Kim #endif 933e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS 934e71b7053SJung-uk Kim {"dtls", OPT_DTLS, '-', "Use any DTLS version"}, 935e71b7053SJung-uk Kim {"timeout", OPT_TIMEOUT, '-', "Enable timeouts"}, 936e71b7053SJung-uk Kim {"mtu", OPT_MTU, 'p', "Set link layer MTU"}, 937e71b7053SJung-uk Kim {"listen", OPT_LISTEN, '-', 938e71b7053SJung-uk Kim "Listen for a DTLS ClientHello with a cookie and then connect"}, 939e71b7053SJung-uk Kim #endif 940e71b7053SJung-uk Kim {"stateless", OPT_STATELESS, '-', "Require TLSv1.3 cookies"}, 941e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS1 942e71b7053SJung-uk Kim {"dtls1", OPT_DTLS1, '-', "Just talk DTLSv1"}, 943e71b7053SJung-uk Kim #endif 944e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS1_2 945e71b7053SJung-uk Kim {"dtls1_2", OPT_DTLS1_2, '-', "Just talk DTLSv1.2"}, 946e71b7053SJung-uk Kim #endif 947e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SCTP 948e71b7053SJung-uk Kim {"sctp", OPT_SCTP, '-', "Use SCTP"}, 9496935a639SJung-uk Kim {"sctp_label_bug", OPT_SCTP_LABEL_BUG, '-', "Enable SCTP label length bug"}, 950e71b7053SJung-uk Kim #endif 951e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DH 952e71b7053SJung-uk Kim {"no_dhe", OPT_NO_DHE, '-', "Disable ephemeral DH"}, 953e71b7053SJung-uk Kim #endif 954e71b7053SJung-uk Kim #ifndef OPENSSL_NO_NEXTPROTONEG 955e71b7053SJung-uk Kim {"nextprotoneg", OPT_NEXTPROTONEG, 's', 956e71b7053SJung-uk Kim "Set the advertised protocols for the NPN extension (comma-separated list)"}, 9571f13597dSJung-uk Kim #endif 95809286989SJung-uk Kim #ifndef OPENSSL_NO_SRTP 959e71b7053SJung-uk Kim {"use_srtp", OPT_SRTP_PROFILES, 's', 960e71b7053SJung-uk Kim "Offer SRTP key management with a colon-separated profile list"}, 96109286989SJung-uk Kim #endif 962e71b7053SJung-uk Kim {"alpn", OPT_ALPN, 's', 963e71b7053SJung-uk Kim "Set the advertised protocols for the ALPN extension (comma-separated list)"}, 964e71b7053SJung-uk Kim #ifndef OPENSSL_NO_ENGINE 965e71b7053SJung-uk Kim {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, 966e71b7053SJung-uk Kim #endif 967e71b7053SJung-uk Kim {"keylogfile", OPT_KEYLOG_FILE, '>', "Write TLS secrets to file"}, 968e71b7053SJung-uk Kim {"max_early_data", OPT_MAX_EARLY, 'n', 969e71b7053SJung-uk Kim "The maximum number of bytes of early data as advertised in tickets"}, 970e71b7053SJung-uk Kim {"recv_max_early_data", OPT_RECV_MAX_EARLY, 'n', 971e71b7053SJung-uk Kim "The maximum number of bytes of early data (hard limit)"}, 972e71b7053SJung-uk Kim {"early_data", OPT_EARLY_DATA, '-', "Attempt to read early data"}, 973e71b7053SJung-uk Kim {"num_tickets", OPT_S_NUM_TICKETS, 'n', 974e71b7053SJung-uk Kim "The number of TLSv1.3 session tickets that a server will automatically issue" }, 975e71b7053SJung-uk Kim {"anti_replay", OPT_ANTI_REPLAY, '-', "Switch on anti-replay protection (default)"}, 976e71b7053SJung-uk Kim {"no_anti_replay", OPT_NO_ANTI_REPLAY, '-', "Switch off anti-replay protection"}, 977e71b7053SJung-uk Kim {NULL, OPT_EOF, 0, NULL} 978e71b7053SJung-uk Kim }; 979db522d3aSSimon L. B. Nielsen 980e71b7053SJung-uk Kim #define IS_PROT_FLAG(o) \ 981e71b7053SJung-uk Kim (o == OPT_SSL3 || o == OPT_TLS1 || o == OPT_TLS1_1 || o == OPT_TLS1_2 \ 982e71b7053SJung-uk Kim || o == OPT_TLS1_3 || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2) 983e71b7053SJung-uk Kim 984e71b7053SJung-uk Kim int s_server_main(int argc, char *argv[]) 98574664626SKris Kennaway { 986e71b7053SJung-uk Kim ENGINE *engine = NULL; 987e71b7053SJung-uk Kim EVP_PKEY *s_key = NULL, *s_dkey = NULL; 988e71b7053SJung-uk Kim SSL_CONF_CTX *cctx = NULL; 989e71b7053SJung-uk Kim const SSL_METHOD *meth = TLS_server_method(); 990e71b7053SJung-uk Kim SSL_EXCERT *exc = NULL; 991e71b7053SJung-uk Kim STACK_OF(OPENSSL_STRING) *ssl_args = NULL; 992e71b7053SJung-uk Kim STACK_OF(X509) *s_chain = NULL, *s_dchain = NULL; 993e71b7053SJung-uk Kim STACK_OF(X509_CRL) *crls = NULL; 994e71b7053SJung-uk Kim X509 *s_cert = NULL, *s_dcert = NULL; 9951f13597dSJung-uk Kim X509_VERIFY_PARAM *vpm = NULL; 996e71b7053SJung-uk Kim const char *CApath = NULL, *CAfile = NULL, *chCApath = NULL, *chCAfile = NULL; 997e71b7053SJung-uk Kim char *dpassarg = NULL, *dpass = NULL; 998e71b7053SJung-uk Kim char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL; 999e71b7053SJung-uk Kim char *crl_file = NULL, *prog; 1000e71b7053SJung-uk Kim #ifdef AF_UNIX 1001e71b7053SJung-uk Kim int unlink_unix_path = 0; 1002e71b7053SJung-uk Kim #endif 1003e71b7053SJung-uk Kim do_server_cb server_cb; 1004e71b7053SJung-uk Kim int vpmtouched = 0, build_chain = 0, no_cache = 0, ext_cache = 0; 1005dea77ea6SJung-uk Kim #ifndef OPENSSL_NO_DH 1006f579bf8eSKris Kennaway char *dhfile = NULL; 1007dea77ea6SJung-uk Kim int no_dhe = 0; 1008dea77ea6SJung-uk Kim #endif 1009e71b7053SJung-uk Kim int nocert = 0, ret = 1; 1010e71b7053SJung-uk Kim int noCApath = 0, noCAfile = 0; 10113b4e3dcbSSimon L. B. Nielsen int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM; 10123b4e3dcbSSimon L. B. Nielsen int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM; 1013e71b7053SJung-uk Kim int rev = 0, naccept = -1, sdebug = 0; 1014e71b7053SJung-uk Kim int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM, protocol = 0; 1015e71b7053SJung-uk Kim int state = 0, crl_format = FORMAT_PEM, crl_download = 0; 1016e71b7053SJung-uk Kim char *host = NULL; 1017e71b7053SJung-uk Kim char *port = BUF_strdup(PORT); 1018e71b7053SJung-uk Kim unsigned char *context = NULL; 1019e71b7053SJung-uk Kim OPTION_CHOICE o; 1020db522d3aSSimon L. B. Nielsen EVP_PKEY *s_key2 = NULL; 1021db522d3aSSimon L. B. Nielsen X509 *s_cert2 = NULL; 1022db522d3aSSimon L. B. Nielsen tlsextctx tlsextcbp = { NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING }; 1023e71b7053SJung-uk Kim const char *ssl_config = NULL; 1024e71b7053SJung-uk Kim int read_buf_len = 0; 10251f13597dSJung-uk Kim #ifndef OPENSSL_NO_NEXTPROTONEG 10261f13597dSJung-uk Kim const char *next_proto_neg_in = NULL; 10277bded2dbSJung-uk Kim tlsextnextprotoctx next_proto = { NULL, 0 }; 1028db522d3aSSimon L. B. Nielsen #endif 10297bded2dbSJung-uk Kim const char *alpn_in = NULL; 10307bded2dbSJung-uk Kim tlsextalpnctx alpn_ctx = { NULL, 0 }; 10311f13597dSJung-uk Kim #ifndef OPENSSL_NO_PSK 10321f13597dSJung-uk Kim /* by default do not send a PSK identity hint */ 1033e71b7053SJung-uk Kim char *psk_identity_hint = NULL; 10341f13597dSJung-uk Kim #endif 1035e71b7053SJung-uk Kim char *p; 10361f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP 10371f13597dSJung-uk Kim char *srpuserseed = NULL; 10381f13597dSJung-uk Kim char *srp_verifier_file = NULL; 10391f13597dSJung-uk Kim #endif 1040e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SRTP 1041e71b7053SJung-uk Kim char *srtp_profiles = NULL; 1042e71b7053SJung-uk Kim #endif 1043e71b7053SJung-uk Kim int min_version = 0, max_version = 0, prot_opt = 0, no_prot_opt = 0; 1044e71b7053SJung-uk Kim int s_server_verify = SSL_VERIFY_NONE; 1045e71b7053SJung-uk Kim int s_server_session_id_context = 1; /* anything will do */ 1046e71b7053SJung-uk Kim const char *s_cert_file = TEST_CERT, *s_key_file = NULL, *s_chain_file = NULL; 1047e71b7053SJung-uk Kim const char *s_cert_file2 = TEST_CERT2, *s_key_file2 = NULL; 1048e71b7053SJung-uk Kim char *s_dcert_file = NULL, *s_dkey_file = NULL, *s_dchain_file = NULL; 1049e71b7053SJung-uk Kim #ifndef OPENSSL_NO_OCSP 1050e71b7053SJung-uk Kim int s_tlsextstatus = 0; 1051e71b7053SJung-uk Kim #endif 1052e71b7053SJung-uk Kim int no_resume_ephemeral = 0; 1053e71b7053SJung-uk Kim unsigned int max_send_fragment = 0; 1054e71b7053SJung-uk Kim unsigned int split_send_fragment = 0, max_pipelines = 0; 1055e71b7053SJung-uk Kim const char *s_serverinfo_file = NULL; 1056e71b7053SJung-uk Kim const char *keylog_file = NULL; 1057e71b7053SJung-uk Kim int max_early_data = -1, recv_max_early_data = -1; 1058e71b7053SJung-uk Kim char *psksessf = NULL; 10596935a639SJung-uk Kim #ifndef OPENSSL_NO_SCTP 10606935a639SJung-uk Kim int sctp_label_bug = 0; 10616935a639SJung-uk Kim #endif 10627bded2dbSJung-uk Kim 1063e71b7053SJung-uk Kim /* Init of few remaining global variables */ 106474664626SKris Kennaway local_argc = argc; 106574664626SKris Kennaway local_argv = argv; 106674664626SKris Kennaway 1067e71b7053SJung-uk Kim ctx = ctx2 = NULL; 1068e71b7053SJung-uk Kim s_nbio = s_nbio_test = 0; 1069e71b7053SJung-uk Kim www = 0; 1070e71b7053SJung-uk Kim bio_s_out = NULL; 1071e71b7053SJung-uk Kim s_debug = 0; 1072e71b7053SJung-uk Kim s_msg = 0; 1073e71b7053SJung-uk Kim s_quiet = 0; 1074e71b7053SJung-uk Kim s_brief = 0; 1075e71b7053SJung-uk Kim async = 0; 10765c87c606SMark Murray 10777bded2dbSJung-uk Kim cctx = SSL_CONF_CTX_new(); 1078e71b7053SJung-uk Kim vpm = X509_VERIFY_PARAM_new(); 1079e71b7053SJung-uk Kim if (cctx == NULL || vpm == NULL) 10807bded2dbSJung-uk Kim goto end; 1081e71b7053SJung-uk Kim SSL_CONF_CTX_set_flags(cctx, 1082e71b7053SJung-uk Kim SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CMDLINE); 10837bded2dbSJung-uk Kim 1084e71b7053SJung-uk Kim prog = opt_init(argc, argv, s_server_options); 1085e71b7053SJung-uk Kim while ((o = opt_next()) != OPT_EOF) { 1086e71b7053SJung-uk Kim if (IS_PROT_FLAG(o) && ++prot_opt > 1) { 1087e71b7053SJung-uk Kim BIO_printf(bio_err, "Cannot supply multiple protocol flags\n"); 1088e71b7053SJung-uk Kim goto end; 10897bded2dbSJung-uk Kim } 1090e71b7053SJung-uk Kim if (IS_NO_PROT_FLAG(o)) 1091e71b7053SJung-uk Kim no_prot_opt++; 1092e71b7053SJung-uk Kim if (prot_opt == 1 && no_prot_opt) { 1093e71b7053SJung-uk Kim BIO_printf(bio_err, 1094e71b7053SJung-uk Kim "Cannot supply both a protocol flag and '-no_<prot>'\n"); 1095e71b7053SJung-uk Kim goto end; 1096e71b7053SJung-uk Kim } 1097e71b7053SJung-uk Kim switch (o) { 1098e71b7053SJung-uk Kim case OPT_EOF: 1099e71b7053SJung-uk Kim case OPT_ERR: 1100e71b7053SJung-uk Kim opthelp: 1101e71b7053SJung-uk Kim BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); 1102e71b7053SJung-uk Kim goto end; 1103e71b7053SJung-uk Kim case OPT_HELP: 1104e71b7053SJung-uk Kim opt_help(s_server_options); 1105e71b7053SJung-uk Kim ret = 0; 1106e71b7053SJung-uk Kim goto end; 1107e71b7053SJung-uk Kim 1108e71b7053SJung-uk Kim case OPT_4: 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_INET; 1116e71b7053SJung-uk Kim break; 1117e71b7053SJung-uk Kim case OPT_6: 1118e71b7053SJung-uk Kim if (1) { 1119e71b7053SJung-uk Kim #ifdef AF_INET6 1120e71b7053SJung-uk Kim #ifdef AF_UNIX 1121e71b7053SJung-uk Kim if (socket_family == AF_UNIX) { 1122e71b7053SJung-uk Kim OPENSSL_free(host); host = NULL; 1123e71b7053SJung-uk Kim OPENSSL_free(port); port = NULL; 1124e71b7053SJung-uk Kim } 1125e71b7053SJung-uk Kim #endif 1126e71b7053SJung-uk Kim socket_family = AF_INET6; 1127e71b7053SJung-uk Kim } else { 1128e71b7053SJung-uk Kim #endif 1129e71b7053SJung-uk Kim BIO_printf(bio_err, "%s: IPv6 domain sockets unsupported\n", prog); 1130e71b7053SJung-uk Kim goto end; 1131e71b7053SJung-uk Kim } 1132e71b7053SJung-uk Kim break; 1133e71b7053SJung-uk Kim case OPT_PORT: 1134e71b7053SJung-uk Kim #ifdef AF_UNIX 1135e71b7053SJung-uk Kim if (socket_family == AF_UNIX) { 1136e71b7053SJung-uk Kim socket_family = AF_UNSPEC; 1137e71b7053SJung-uk Kim } 1138e71b7053SJung-uk Kim #endif 1139e71b7053SJung-uk Kim OPENSSL_free(port); port = NULL; 1140e71b7053SJung-uk Kim OPENSSL_free(host); host = NULL; 1141e71b7053SJung-uk Kim if (BIO_parse_hostserv(opt_arg(), NULL, &port, BIO_PARSE_PRIO_SERV) < 1) { 1142e71b7053SJung-uk Kim BIO_printf(bio_err, 1143e71b7053SJung-uk Kim "%s: -port argument malformed or ambiguous\n", 1144e71b7053SJung-uk Kim port); 1145e71b7053SJung-uk Kim goto end; 1146e71b7053SJung-uk Kim } 1147e71b7053SJung-uk Kim break; 1148e71b7053SJung-uk Kim case OPT_ACCEPT: 1149e71b7053SJung-uk Kim #ifdef AF_UNIX 1150e71b7053SJung-uk Kim if (socket_family == AF_UNIX) { 1151e71b7053SJung-uk Kim socket_family = AF_UNSPEC; 1152e71b7053SJung-uk Kim } 1153e71b7053SJung-uk Kim #endif 1154e71b7053SJung-uk Kim OPENSSL_free(port); port = NULL; 1155e71b7053SJung-uk Kim OPENSSL_free(host); host = NULL; 1156e71b7053SJung-uk Kim if (BIO_parse_hostserv(opt_arg(), &host, &port, BIO_PARSE_PRIO_SERV) < 1) { 1157e71b7053SJung-uk Kim BIO_printf(bio_err, 1158e71b7053SJung-uk Kim "%s: -accept argument malformed or ambiguous\n", 1159e71b7053SJung-uk Kim port); 1160e71b7053SJung-uk Kim goto end; 1161e71b7053SJung-uk Kim } 1162e71b7053SJung-uk Kim break; 1163e71b7053SJung-uk Kim #ifdef AF_UNIX 1164e71b7053SJung-uk Kim case OPT_UNIX: 1165e71b7053SJung-uk Kim socket_family = AF_UNIX; 1166e71b7053SJung-uk Kim OPENSSL_free(host); host = BUF_strdup(opt_arg()); 1167e71b7053SJung-uk Kim OPENSSL_free(port); port = NULL; 1168e71b7053SJung-uk Kim break; 1169e71b7053SJung-uk Kim case OPT_UNLINK: 1170e71b7053SJung-uk Kim unlink_unix_path = 1; 1171e71b7053SJung-uk Kim break; 1172e71b7053SJung-uk Kim #endif 1173e71b7053SJung-uk Kim case OPT_NACCEPT: 1174e71b7053SJung-uk Kim naccept = atol(opt_arg()); 1175e71b7053SJung-uk Kim break; 1176e71b7053SJung-uk Kim case OPT_VERIFY: 117774664626SKris Kennaway s_server_verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; 1178e71b7053SJung-uk Kim verify_args.depth = atoi(opt_arg()); 11797bded2dbSJung-uk Kim if (!s_quiet) 1180e71b7053SJung-uk Kim BIO_printf(bio_err, "verify depth is %d\n", verify_args.depth); 1181e71b7053SJung-uk Kim break; 1182e71b7053SJung-uk Kim case OPT_UPPER_V_VERIFY: 11836f9291ceSJung-uk Kim s_server_verify = 11846f9291ceSJung-uk Kim SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | 118574664626SKris Kennaway SSL_VERIFY_CLIENT_ONCE; 1186e71b7053SJung-uk Kim verify_args.depth = atoi(opt_arg()); 11877bded2dbSJung-uk Kim if (!s_quiet) 11886f9291ceSJung-uk Kim BIO_printf(bio_err, 11896f9291ceSJung-uk Kim "verify depth is %d, must return a certificate\n", 1190e71b7053SJung-uk Kim verify_args.depth); 1191e71b7053SJung-uk Kim break; 1192e71b7053SJung-uk Kim case OPT_CONTEXT: 1193e71b7053SJung-uk Kim context = (unsigned char *)opt_arg(); 1194e71b7053SJung-uk Kim break; 1195e71b7053SJung-uk Kim case OPT_CERT: 1196e71b7053SJung-uk Kim s_cert_file = opt_arg(); 1197e71b7053SJung-uk Kim break; 1198e71b7053SJung-uk Kim case OPT_NAMEOPT: 1199e71b7053SJung-uk Kim if (!set_nameopt(opt_arg())) 1200e71b7053SJung-uk Kim goto end; 1201e71b7053SJung-uk Kim break; 1202e71b7053SJung-uk Kim case OPT_CRL: 1203e71b7053SJung-uk Kim crl_file = opt_arg(); 1204e71b7053SJung-uk Kim break; 1205e71b7053SJung-uk Kim case OPT_CRL_DOWNLOAD: 12067bded2dbSJung-uk Kim crl_download = 1; 1207e71b7053SJung-uk Kim break; 1208e71b7053SJung-uk Kim case OPT_SERVERINFO: 1209e71b7053SJung-uk Kim s_serverinfo_file = opt_arg(); 1210e71b7053SJung-uk Kim break; 1211e71b7053SJung-uk Kim case OPT_CERTFORM: 1212e71b7053SJung-uk Kim if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &s_cert_format)) 1213e71b7053SJung-uk Kim goto opthelp; 1214e71b7053SJung-uk Kim break; 1215e71b7053SJung-uk Kim case OPT_KEY: 1216e71b7053SJung-uk Kim s_key_file = opt_arg(); 1217e71b7053SJung-uk Kim break; 1218e71b7053SJung-uk Kim case OPT_KEYFORM: 1219e71b7053SJung-uk Kim if (!opt_format(opt_arg(), OPT_FMT_ANY, &s_key_format)) 1220e71b7053SJung-uk Kim goto opthelp; 1221e71b7053SJung-uk Kim break; 1222e71b7053SJung-uk Kim case OPT_PASS: 1223e71b7053SJung-uk Kim passarg = opt_arg(); 1224e71b7053SJung-uk Kim break; 1225e71b7053SJung-uk Kim case OPT_CERT_CHAIN: 1226e71b7053SJung-uk Kim s_chain_file = opt_arg(); 1227e71b7053SJung-uk Kim break; 1228e71b7053SJung-uk Kim case OPT_DHPARAM: 1229dea77ea6SJung-uk Kim #ifndef OPENSSL_NO_DH 1230e71b7053SJung-uk Kim dhfile = opt_arg(); 1231dea77ea6SJung-uk Kim #endif 1232e71b7053SJung-uk Kim break; 1233e71b7053SJung-uk Kim case OPT_DCERTFORM: 1234e71b7053SJung-uk Kim if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &s_dcert_format)) 1235e71b7053SJung-uk Kim goto opthelp; 1236e71b7053SJung-uk Kim break; 1237e71b7053SJung-uk Kim case OPT_DCERT: 1238e71b7053SJung-uk Kim s_dcert_file = opt_arg(); 1239e71b7053SJung-uk Kim break; 1240e71b7053SJung-uk Kim case OPT_DKEYFORM: 1241e71b7053SJung-uk Kim if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &s_dkey_format)) 1242e71b7053SJung-uk Kim goto opthelp; 1243e71b7053SJung-uk Kim break; 1244e71b7053SJung-uk Kim case OPT_DPASS: 1245e71b7053SJung-uk Kim dpassarg = opt_arg(); 1246e71b7053SJung-uk Kim break; 1247e71b7053SJung-uk Kim case OPT_DKEY: 1248e71b7053SJung-uk Kim s_dkey_file = opt_arg(); 1249e71b7053SJung-uk Kim break; 1250e71b7053SJung-uk Kim case OPT_DCERT_CHAIN: 1251e71b7053SJung-uk Kim s_dchain_file = opt_arg(); 1252e71b7053SJung-uk Kim break; 1253e71b7053SJung-uk Kim case OPT_NOCERT: 125474664626SKris Kennaway nocert = 1; 1255e71b7053SJung-uk Kim break; 1256e71b7053SJung-uk Kim case OPT_CAPATH: 1257e71b7053SJung-uk Kim CApath = opt_arg(); 1258e71b7053SJung-uk Kim break; 1259e71b7053SJung-uk Kim case OPT_NOCAPATH: 1260e71b7053SJung-uk Kim noCApath = 1; 1261e71b7053SJung-uk Kim break; 1262e71b7053SJung-uk Kim case OPT_CHAINCAPATH: 1263e71b7053SJung-uk Kim chCApath = opt_arg(); 1264e71b7053SJung-uk Kim break; 1265e71b7053SJung-uk Kim case OPT_VERIFYCAPATH: 1266e71b7053SJung-uk Kim vfyCApath = opt_arg(); 1267e71b7053SJung-uk Kim break; 1268e71b7053SJung-uk Kim case OPT_NO_CACHE: 12696a599222SSimon L. B. Nielsen no_cache = 1; 1270e71b7053SJung-uk Kim break; 1271e71b7053SJung-uk Kim case OPT_EXT_CACHE: 12727bded2dbSJung-uk Kim ext_cache = 1; 1273e71b7053SJung-uk Kim break; 1274e71b7053SJung-uk Kim case OPT_CRLFORM: 1275e71b7053SJung-uk Kim if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &crl_format)) 1276e71b7053SJung-uk Kim goto opthelp; 1277e71b7053SJung-uk Kim break; 1278e71b7053SJung-uk Kim case OPT_S_CASES: 1279e71b7053SJung-uk Kim case OPT_S_NUM_TICKETS: 1280e71b7053SJung-uk Kim case OPT_ANTI_REPLAY: 1281e71b7053SJung-uk Kim case OPT_NO_ANTI_REPLAY: 1282e71b7053SJung-uk Kim if (ssl_args == NULL) 1283e71b7053SJung-uk Kim ssl_args = sk_OPENSSL_STRING_new_null(); 1284e71b7053SJung-uk Kim if (ssl_args == NULL 1285e71b7053SJung-uk Kim || !sk_OPENSSL_STRING_push(ssl_args, opt_flag()) 1286e71b7053SJung-uk Kim || !sk_OPENSSL_STRING_push(ssl_args, opt_arg())) { 1287e71b7053SJung-uk Kim BIO_printf(bio_err, "%s: Memory allocation failure\n", prog); 1288e71b7053SJung-uk Kim goto end; 1289e71b7053SJung-uk Kim } 1290e71b7053SJung-uk Kim break; 1291e71b7053SJung-uk Kim case OPT_V_CASES: 1292e71b7053SJung-uk Kim if (!opt_verify(o, vpm)) 1293e71b7053SJung-uk Kim goto end; 1294e71b7053SJung-uk Kim vpmtouched++; 1295e71b7053SJung-uk Kim break; 1296e71b7053SJung-uk Kim case OPT_X_CASES: 1297e71b7053SJung-uk Kim if (!args_excert(o, &exc)) 1298e71b7053SJung-uk Kim goto end; 1299e71b7053SJung-uk Kim break; 1300e71b7053SJung-uk Kim case OPT_VERIFY_RET_ERROR: 1301e71b7053SJung-uk Kim verify_args.return_error = 1; 1302e71b7053SJung-uk Kim break; 1303e71b7053SJung-uk Kim case OPT_VERIFY_QUIET: 1304e71b7053SJung-uk Kim verify_args.quiet = 1; 1305e71b7053SJung-uk Kim break; 1306e71b7053SJung-uk Kim case OPT_BUILD_CHAIN: 13077bded2dbSJung-uk Kim build_chain = 1; 1308e71b7053SJung-uk Kim break; 1309e71b7053SJung-uk Kim case OPT_CAFILE: 1310e71b7053SJung-uk Kim CAfile = opt_arg(); 1311e71b7053SJung-uk Kim break; 1312e71b7053SJung-uk Kim case OPT_NOCAFILE: 1313e71b7053SJung-uk Kim noCAfile = 1; 1314e71b7053SJung-uk Kim break; 1315e71b7053SJung-uk Kim case OPT_CHAINCAFILE: 1316e71b7053SJung-uk Kim chCAfile = opt_arg(); 1317e71b7053SJung-uk Kim break; 1318e71b7053SJung-uk Kim case OPT_VERIFYCAFILE: 1319e71b7053SJung-uk Kim vfyCAfile = opt_arg(); 1320e71b7053SJung-uk Kim break; 1321e71b7053SJung-uk Kim case OPT_NBIO: 13226f9291ceSJung-uk Kim s_nbio = 1; 1323e71b7053SJung-uk Kim break; 1324e71b7053SJung-uk Kim case OPT_NBIO_TEST: 1325e71b7053SJung-uk Kim s_nbio = s_nbio_test = 1; 1326e71b7053SJung-uk Kim break; 1327e71b7053SJung-uk Kim case OPT_IGN_EOF: 13287bded2dbSJung-uk Kim s_ign_eof = 1; 1329e71b7053SJung-uk Kim break; 1330e71b7053SJung-uk Kim case OPT_NO_IGN_EOF: 13317bded2dbSJung-uk Kim s_ign_eof = 0; 1332e71b7053SJung-uk Kim break; 1333e71b7053SJung-uk Kim case OPT_DEBUG: 13346f9291ceSJung-uk Kim s_debug = 1; 1335e71b7053SJung-uk Kim break; 1336e71b7053SJung-uk Kim case OPT_TLSEXTDEBUG: 1337db522d3aSSimon L. B. Nielsen s_tlsextdebug = 1; 1338e71b7053SJung-uk Kim break; 1339e71b7053SJung-uk Kim case OPT_STATUS: 1340e71b7053SJung-uk Kim #ifndef OPENSSL_NO_OCSP 1341db522d3aSSimon L. B. Nielsen s_tlsextstatus = 1; 1342e71b7053SJung-uk Kim #endif 1343e71b7053SJung-uk Kim break; 1344e71b7053SJung-uk Kim case OPT_STATUS_VERBOSE: 1345e71b7053SJung-uk Kim #ifndef OPENSSL_NO_OCSP 1346e71b7053SJung-uk Kim s_tlsextstatus = tlscstatp.verbose = 1; 1347e71b7053SJung-uk Kim #endif 1348e71b7053SJung-uk Kim break; 1349e71b7053SJung-uk Kim case OPT_STATUS_TIMEOUT: 1350e71b7053SJung-uk Kim #ifndef OPENSSL_NO_OCSP 1351db522d3aSSimon L. B. Nielsen s_tlsextstatus = 1; 1352e71b7053SJung-uk Kim tlscstatp.timeout = atoi(opt_arg()); 1353e71b7053SJung-uk Kim #endif 1354e71b7053SJung-uk Kim break; 1355e71b7053SJung-uk Kim case OPT_STATUS_URL: 1356e71b7053SJung-uk Kim #ifndef OPENSSL_NO_OCSP 1357db522d3aSSimon L. B. Nielsen s_tlsextstatus = 1; 1358e71b7053SJung-uk Kim if (!OCSP_parse_url(opt_arg(), 1359db522d3aSSimon L. B. Nielsen &tlscstatp.host, 1360db522d3aSSimon L. B. Nielsen &tlscstatp.port, 13616f9291ceSJung-uk Kim &tlscstatp.path, &tlscstatp.use_ssl)) { 1362db522d3aSSimon L. B. Nielsen BIO_printf(bio_err, "Error parsing URL\n"); 136374664626SKris Kennaway goto end; 136474664626SKris Kennaway } 1365e71b7053SJung-uk Kim #endif 1366e71b7053SJung-uk Kim break; 1367e71b7053SJung-uk Kim case OPT_STATUS_FILE: 1368e71b7053SJung-uk Kim #ifndef OPENSSL_NO_OCSP 1369e71b7053SJung-uk Kim s_tlsextstatus = 1; 1370e71b7053SJung-uk Kim tlscstatp.respin = opt_arg(); 1371e71b7053SJung-uk Kim #endif 1372e71b7053SJung-uk Kim break; 1373e71b7053SJung-uk Kim case OPT_MSG: 1374e71b7053SJung-uk Kim s_msg = 1; 1375e71b7053SJung-uk Kim break; 1376e71b7053SJung-uk Kim case OPT_MSGFILE: 1377e71b7053SJung-uk Kim bio_s_msg = BIO_new_file(opt_arg(), "w"); 1378e71b7053SJung-uk Kim break; 1379e71b7053SJung-uk Kim case OPT_TRACE: 1380e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SSL_TRACE 1381e71b7053SJung-uk Kim s_msg = 2; 1382e71b7053SJung-uk Kim #endif 1383e71b7053SJung-uk Kim break; 1384e71b7053SJung-uk Kim case OPT_SECURITY_DEBUG: 1385e71b7053SJung-uk Kim sdebug = 1; 1386e71b7053SJung-uk Kim break; 1387e71b7053SJung-uk Kim case OPT_SECURITY_DEBUG_VERBOSE: 1388e71b7053SJung-uk Kim sdebug = 2; 1389e71b7053SJung-uk Kim break; 1390e71b7053SJung-uk Kim case OPT_STATE: 1391e71b7053SJung-uk Kim state = 1; 1392e71b7053SJung-uk Kim break; 1393e71b7053SJung-uk Kim case OPT_CRLF: 1394e71b7053SJung-uk Kim s_crlf = 1; 1395e71b7053SJung-uk Kim break; 1396e71b7053SJung-uk Kim case OPT_QUIET: 1397e71b7053SJung-uk Kim s_quiet = 1; 1398e71b7053SJung-uk Kim break; 1399e71b7053SJung-uk Kim case OPT_BRIEF: 1400e71b7053SJung-uk Kim s_quiet = s_brief = verify_args.quiet = 1; 1401e71b7053SJung-uk Kim break; 1402e71b7053SJung-uk Kim case OPT_NO_DHE: 1403e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DH 1404e71b7053SJung-uk Kim no_dhe = 1; 1405e71b7053SJung-uk Kim #endif 1406e71b7053SJung-uk Kim break; 1407e71b7053SJung-uk Kim case OPT_NO_RESUME_EPHEMERAL: 1408e71b7053SJung-uk Kim no_resume_ephemeral = 1; 1409e71b7053SJung-uk Kim break; 1410e71b7053SJung-uk Kim case OPT_PSK_IDENTITY: 1411e71b7053SJung-uk Kim psk_identity = opt_arg(); 1412e71b7053SJung-uk Kim break; 1413e71b7053SJung-uk Kim case OPT_PSK_HINT: 1414e71b7053SJung-uk Kim #ifndef OPENSSL_NO_PSK 1415e71b7053SJung-uk Kim psk_identity_hint = opt_arg(); 1416e71b7053SJung-uk Kim #endif 1417e71b7053SJung-uk Kim break; 1418e71b7053SJung-uk Kim case OPT_PSK: 1419e71b7053SJung-uk Kim for (p = psk_key = opt_arg(); *p; p++) { 1420e71b7053SJung-uk Kim if (isxdigit(_UC(*p))) 1421e71b7053SJung-uk Kim continue; 14226935a639SJung-uk Kim BIO_printf(bio_err, "Not a hex number '%s'\n", psk_key); 1423e71b7053SJung-uk Kim goto end; 1424e71b7053SJung-uk Kim } 1425e71b7053SJung-uk Kim break; 1426e71b7053SJung-uk Kim case OPT_PSK_SESS: 1427e71b7053SJung-uk Kim psksessf = opt_arg(); 1428e71b7053SJung-uk Kim break; 1429e71b7053SJung-uk Kim case OPT_SRPVFILE: 1430e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SRP 1431e71b7053SJung-uk Kim srp_verifier_file = opt_arg(); 1432e71b7053SJung-uk Kim if (min_version < TLS1_VERSION) 1433e71b7053SJung-uk Kim min_version = TLS1_VERSION; 1434e71b7053SJung-uk Kim #endif 1435e71b7053SJung-uk Kim break; 1436e71b7053SJung-uk Kim case OPT_SRPUSERSEED: 1437e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SRP 1438e71b7053SJung-uk Kim srpuserseed = opt_arg(); 1439e71b7053SJung-uk Kim if (min_version < TLS1_VERSION) 1440e71b7053SJung-uk Kim min_version = TLS1_VERSION; 1441e71b7053SJung-uk Kim #endif 1442e71b7053SJung-uk Kim break; 1443e71b7053SJung-uk Kim case OPT_REV: 1444e71b7053SJung-uk Kim rev = 1; 1445e71b7053SJung-uk Kim break; 1446e71b7053SJung-uk Kim case OPT_WWW: 1447e71b7053SJung-uk Kim www = 1; 1448e71b7053SJung-uk Kim break; 1449e71b7053SJung-uk Kim case OPT_UPPER_WWW: 1450e71b7053SJung-uk Kim www = 2; 1451e71b7053SJung-uk Kim break; 1452e71b7053SJung-uk Kim case OPT_HTTP: 1453e71b7053SJung-uk Kim www = 3; 1454e71b7053SJung-uk Kim break; 1455e71b7053SJung-uk Kim case OPT_SSL_CONFIG: 1456e71b7053SJung-uk Kim ssl_config = opt_arg(); 1457e71b7053SJung-uk Kim break; 1458e71b7053SJung-uk Kim case OPT_SSL3: 1459e71b7053SJung-uk Kim min_version = SSL3_VERSION; 1460e71b7053SJung-uk Kim max_version = SSL3_VERSION; 1461e71b7053SJung-uk Kim break; 1462e71b7053SJung-uk Kim case OPT_TLS1_3: 1463e71b7053SJung-uk Kim min_version = TLS1_3_VERSION; 1464e71b7053SJung-uk Kim max_version = TLS1_3_VERSION; 1465e71b7053SJung-uk Kim break; 1466e71b7053SJung-uk Kim case OPT_TLS1_2: 1467e71b7053SJung-uk Kim min_version = TLS1_2_VERSION; 1468e71b7053SJung-uk Kim max_version = TLS1_2_VERSION; 1469e71b7053SJung-uk Kim break; 1470e71b7053SJung-uk Kim case OPT_TLS1_1: 1471e71b7053SJung-uk Kim min_version = TLS1_1_VERSION; 1472e71b7053SJung-uk Kim max_version = TLS1_1_VERSION; 1473e71b7053SJung-uk Kim break; 1474e71b7053SJung-uk Kim case OPT_TLS1: 1475e71b7053SJung-uk Kim min_version = TLS1_VERSION; 1476e71b7053SJung-uk Kim max_version = TLS1_VERSION; 1477e71b7053SJung-uk Kim break; 1478e71b7053SJung-uk Kim case OPT_DTLS: 1479e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS 1480e71b7053SJung-uk Kim meth = DTLS_server_method(); 1481e71b7053SJung-uk Kim socket_type = SOCK_DGRAM; 1482e71b7053SJung-uk Kim #endif 1483e71b7053SJung-uk Kim break; 1484e71b7053SJung-uk Kim case OPT_DTLS1: 1485e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS 1486e71b7053SJung-uk Kim meth = DTLS_server_method(); 1487e71b7053SJung-uk Kim min_version = DTLS1_VERSION; 1488e71b7053SJung-uk Kim max_version = DTLS1_VERSION; 1489e71b7053SJung-uk Kim socket_type = SOCK_DGRAM; 1490e71b7053SJung-uk Kim #endif 1491e71b7053SJung-uk Kim break; 1492e71b7053SJung-uk Kim case OPT_DTLS1_2: 1493e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS 1494e71b7053SJung-uk Kim meth = DTLS_server_method(); 1495e71b7053SJung-uk Kim min_version = DTLS1_2_VERSION; 1496e71b7053SJung-uk Kim max_version = DTLS1_2_VERSION; 1497e71b7053SJung-uk Kim socket_type = SOCK_DGRAM; 1498e71b7053SJung-uk Kim #endif 1499e71b7053SJung-uk Kim break; 1500e71b7053SJung-uk Kim case OPT_SCTP: 1501e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SCTP 1502e71b7053SJung-uk Kim protocol = IPPROTO_SCTP; 1503e71b7053SJung-uk Kim #endif 1504e71b7053SJung-uk Kim break; 15056935a639SJung-uk Kim case OPT_SCTP_LABEL_BUG: 15066935a639SJung-uk Kim #ifndef OPENSSL_NO_SCTP 15076935a639SJung-uk Kim sctp_label_bug = 1; 15086935a639SJung-uk Kim #endif 15096935a639SJung-uk Kim break; 1510e71b7053SJung-uk Kim case OPT_TIMEOUT: 1511e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS 1512e71b7053SJung-uk Kim enable_timeouts = 1; 1513e71b7053SJung-uk Kim #endif 1514e71b7053SJung-uk Kim break; 1515e71b7053SJung-uk Kim case OPT_MTU: 1516e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS 1517e71b7053SJung-uk Kim socket_mtu = atol(opt_arg()); 1518e71b7053SJung-uk Kim #endif 1519e71b7053SJung-uk Kim break; 1520e71b7053SJung-uk Kim case OPT_LISTEN: 1521e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS 1522e71b7053SJung-uk Kim dtlslisten = 1; 1523e71b7053SJung-uk Kim #endif 1524e71b7053SJung-uk Kim break; 1525e71b7053SJung-uk Kim case OPT_STATELESS: 1526e71b7053SJung-uk Kim stateless = 1; 1527e71b7053SJung-uk Kim break; 1528e71b7053SJung-uk Kim case OPT_ID_PREFIX: 1529e71b7053SJung-uk Kim session_id_prefix = opt_arg(); 1530e71b7053SJung-uk Kim break; 1531e71b7053SJung-uk Kim case OPT_ENGINE: 1532e71b7053SJung-uk Kim engine = setup_engine(opt_arg(), 1); 1533e71b7053SJung-uk Kim break; 1534e71b7053SJung-uk Kim case OPT_R_CASES: 1535e71b7053SJung-uk Kim if (!opt_rand(o)) 1536e71b7053SJung-uk Kim goto end; 1537e71b7053SJung-uk Kim break; 1538e71b7053SJung-uk Kim case OPT_SERVERNAME: 1539e71b7053SJung-uk Kim tlsextcbp.servername = opt_arg(); 1540e71b7053SJung-uk Kim break; 1541e71b7053SJung-uk Kim case OPT_SERVERNAME_FATAL: 1542e71b7053SJung-uk Kim tlsextcbp.extension_error = SSL_TLSEXT_ERR_ALERT_FATAL; 1543e71b7053SJung-uk Kim break; 1544e71b7053SJung-uk Kim case OPT_CERT2: 1545e71b7053SJung-uk Kim s_cert_file2 = opt_arg(); 1546e71b7053SJung-uk Kim break; 1547e71b7053SJung-uk Kim case OPT_KEY2: 1548e71b7053SJung-uk Kim s_key_file2 = opt_arg(); 1549e71b7053SJung-uk Kim break; 1550e71b7053SJung-uk Kim case OPT_NEXTPROTONEG: 1551e71b7053SJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG 1552e71b7053SJung-uk Kim next_proto_neg_in = opt_arg(); 1553e71b7053SJung-uk Kim #endif 1554e71b7053SJung-uk Kim break; 1555e71b7053SJung-uk Kim case OPT_ALPN: 1556e71b7053SJung-uk Kim alpn_in = opt_arg(); 1557e71b7053SJung-uk Kim break; 1558e71b7053SJung-uk Kim case OPT_SRTP_PROFILES: 1559e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SRTP 1560e71b7053SJung-uk Kim srtp_profiles = opt_arg(); 1561e71b7053SJung-uk Kim #endif 1562e71b7053SJung-uk Kim break; 1563e71b7053SJung-uk Kim case OPT_KEYMATEXPORT: 1564e71b7053SJung-uk Kim keymatexportlabel = opt_arg(); 1565e71b7053SJung-uk Kim break; 1566e71b7053SJung-uk Kim case OPT_KEYMATEXPORTLEN: 1567e71b7053SJung-uk Kim keymatexportlen = atoi(opt_arg()); 1568e71b7053SJung-uk Kim break; 1569e71b7053SJung-uk Kim case OPT_ASYNC: 1570e71b7053SJung-uk Kim async = 1; 1571e71b7053SJung-uk Kim break; 1572e71b7053SJung-uk Kim case OPT_MAX_SEND_FRAG: 1573e71b7053SJung-uk Kim max_send_fragment = atoi(opt_arg()); 1574e71b7053SJung-uk Kim break; 1575e71b7053SJung-uk Kim case OPT_SPLIT_SEND_FRAG: 1576e71b7053SJung-uk Kim split_send_fragment = atoi(opt_arg()); 1577e71b7053SJung-uk Kim break; 1578e71b7053SJung-uk Kim case OPT_MAX_PIPELINES: 1579e71b7053SJung-uk Kim max_pipelines = atoi(opt_arg()); 1580e71b7053SJung-uk Kim break; 1581e71b7053SJung-uk Kim case OPT_READ_BUF: 1582e71b7053SJung-uk Kim read_buf_len = atoi(opt_arg()); 1583e71b7053SJung-uk Kim break; 1584e71b7053SJung-uk Kim case OPT_KEYLOG_FILE: 1585e71b7053SJung-uk Kim keylog_file = opt_arg(); 1586e71b7053SJung-uk Kim break; 1587e71b7053SJung-uk Kim case OPT_MAX_EARLY: 1588e71b7053SJung-uk Kim max_early_data = atoi(opt_arg()); 1589e71b7053SJung-uk Kim if (max_early_data < 0) { 1590e71b7053SJung-uk Kim BIO_printf(bio_err, "Invalid value for max_early_data\n"); 1591e71b7053SJung-uk Kim goto end; 1592e71b7053SJung-uk Kim } 1593e71b7053SJung-uk Kim break; 1594e71b7053SJung-uk Kim case OPT_RECV_MAX_EARLY: 1595e71b7053SJung-uk Kim recv_max_early_data = atoi(opt_arg()); 1596e71b7053SJung-uk Kim if (recv_max_early_data < 0) { 1597e71b7053SJung-uk Kim BIO_printf(bio_err, "Invalid value for recv_max_early_data\n"); 1598e71b7053SJung-uk Kim goto end; 1599e71b7053SJung-uk Kim } 1600e71b7053SJung-uk Kim break; 1601e71b7053SJung-uk Kim case OPT_EARLY_DATA: 1602e71b7053SJung-uk Kim early_data = 1; 1603e71b7053SJung-uk Kim if (max_early_data == -1) 1604e71b7053SJung-uk Kim max_early_data = SSL3_RT_MAX_PLAIN_LENGTH; 1605e71b7053SJung-uk Kim break; 1606e71b7053SJung-uk Kim } 1607e71b7053SJung-uk Kim } 1608e71b7053SJung-uk Kim argc = opt_num_rest(); 1609e71b7053SJung-uk Kim argv = opt_rest(); 1610e71b7053SJung-uk Kim 1611e71b7053SJung-uk Kim #ifndef OPENSSL_NO_NEXTPROTONEG 1612e71b7053SJung-uk Kim if (min_version == TLS1_3_VERSION && next_proto_neg_in != NULL) { 1613e71b7053SJung-uk Kim BIO_printf(bio_err, "Cannot supply -nextprotoneg with TLSv1.3\n"); 1614e71b7053SJung-uk Kim goto opthelp; 1615e71b7053SJung-uk Kim } 1616e71b7053SJung-uk Kim #endif 1617e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS 16186f9291ceSJung-uk Kim if (www && socket_type == SOCK_DGRAM) { 16196f9291ceSJung-uk Kim BIO_printf(bio_err, "Can't use -HTTP, -www or -WWW with DTLS\n"); 1620a93cbc2bSJung-uk Kim goto end; 1621a93cbc2bSJung-uk Kim } 162274664626SKris Kennaway 1623e71b7053SJung-uk Kim if (dtlslisten && socket_type != SOCK_DGRAM) { 1624e71b7053SJung-uk Kim BIO_printf(bio_err, "Can only use -listen with DTLS\n"); 16251f13597dSJung-uk Kim goto end; 16261f13597dSJung-uk Kim } 16271f13597dSJung-uk Kim #endif 16281f13597dSJung-uk Kim 1629e71b7053SJung-uk Kim if (stateless && socket_type != SOCK_STREAM) { 1630e71b7053SJung-uk Kim BIO_printf(bio_err, "Can only use --stateless with TLS\n"); 1631aeb5019cSJung-uk Kim goto end; 1632aeb5019cSJung-uk Kim } 1633aeb5019cSJung-uk Kim 1634e71b7053SJung-uk Kim #ifdef AF_UNIX 1635e71b7053SJung-uk Kim if (socket_family == AF_UNIX && socket_type != SOCK_STREAM) { 1636e71b7053SJung-uk Kim BIO_printf(bio_err, 1637e71b7053SJung-uk Kim "Can't use unix sockets and datagrams together\n"); 1638aeb5019cSJung-uk Kim goto end; 1639aeb5019cSJung-uk Kim } 1640e71b7053SJung-uk Kim #endif 1641c9cf7b5cSJung-uk Kim if (early_data && (www > 0 || rev)) { 1642c9cf7b5cSJung-uk Kim BIO_printf(bio_err, 1643c9cf7b5cSJung-uk Kim "Can't use -early_data in combination with -www, -WWW, -HTTP, or -rev\n"); 1644c9cf7b5cSJung-uk Kim goto end; 1645c9cf7b5cSJung-uk Kim } 1646aeb5019cSJung-uk Kim 1647e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SCTP 1648e71b7053SJung-uk Kim if (protocol == IPPROTO_SCTP) { 1649e71b7053SJung-uk Kim if (socket_type != SOCK_DGRAM) { 1650e71b7053SJung-uk Kim BIO_printf(bio_err, "Can't use -sctp without DTLS\n"); 1651e71b7053SJung-uk Kim goto end; 1652e71b7053SJung-uk Kim } 1653e71b7053SJung-uk Kim /* SCTP is unusual. It uses DTLS over a SOCK_STREAM protocol */ 1654e71b7053SJung-uk Kim socket_type = SOCK_STREAM; 1655e71b7053SJung-uk Kim } 1656e71b7053SJung-uk Kim #endif 16575c87c606SMark Murray 1658e71b7053SJung-uk Kim if (!app_passwd(passarg, dpassarg, &pass, &dpass)) { 16593b4e3dcbSSimon L. B. Nielsen BIO_printf(bio_err, "Error getting password\n"); 16603b4e3dcbSSimon L. B. Nielsen goto end; 16613b4e3dcbSSimon L. B. Nielsen } 16623b4e3dcbSSimon L. B. Nielsen 16633b4e3dcbSSimon L. B. Nielsen if (s_key_file == NULL) 16643b4e3dcbSSimon L. B. Nielsen s_key_file = s_cert_file; 1665e71b7053SJung-uk Kim 1666db522d3aSSimon L. B. Nielsen if (s_key_file2 == NULL) 1667db522d3aSSimon L. B. Nielsen s_key_file2 = s_cert_file2; 16683b4e3dcbSSimon L. B. Nielsen 1669e71b7053SJung-uk Kim if (!load_excert(&exc)) 16707bded2dbSJung-uk Kim goto end; 16717bded2dbSJung-uk Kim 16726f9291ceSJung-uk Kim if (nocert == 0) { 1673e71b7053SJung-uk Kim s_key = load_key(s_key_file, s_key_format, 0, pass, engine, 16743b4e3dcbSSimon L. B. Nielsen "server certificate private key file"); 1675e71b7053SJung-uk Kim if (s_key == NULL) { 16763b4e3dcbSSimon L. B. Nielsen ERR_print_errors(bio_err); 16773b4e3dcbSSimon L. B. Nielsen goto end; 16783b4e3dcbSSimon L. B. Nielsen } 16793b4e3dcbSSimon L. B. Nielsen 1680e71b7053SJung-uk Kim s_cert = load_cert(s_cert_file, s_cert_format, 1681e71b7053SJung-uk Kim "server certificate file"); 16823b4e3dcbSSimon L. B. Nielsen 1683e71b7053SJung-uk Kim if (s_cert == NULL) { 16843b4e3dcbSSimon L. B. Nielsen ERR_print_errors(bio_err); 16853b4e3dcbSSimon L. B. Nielsen goto end; 16863b4e3dcbSSimon L. B. Nielsen } 1687e71b7053SJung-uk Kim if (s_chain_file != NULL) { 1688e71b7053SJung-uk Kim if (!load_certs(s_chain_file, &s_chain, FORMAT_PEM, NULL, 1689e71b7053SJung-uk Kim "server certificate chain")) 16907bded2dbSJung-uk Kim goto end; 16917bded2dbSJung-uk Kim } 1692e71b7053SJung-uk Kim 1693e71b7053SJung-uk Kim if (tlsextcbp.servername != NULL) { 1694e71b7053SJung-uk Kim s_key2 = load_key(s_key_file2, s_key_format, 0, pass, engine, 1695db522d3aSSimon L. B. Nielsen "second server certificate private key file"); 1696e71b7053SJung-uk Kim if (s_key2 == NULL) { 1697db522d3aSSimon L. B. Nielsen ERR_print_errors(bio_err); 1698db522d3aSSimon L. B. Nielsen goto end; 16993b4e3dcbSSimon L. B. Nielsen } 17003b4e3dcbSSimon L. B. Nielsen 1701e71b7053SJung-uk Kim s_cert2 = load_cert(s_cert_file2, s_cert_format, 1702e71b7053SJung-uk Kim "second server certificate file"); 1703db522d3aSSimon L. B. Nielsen 1704e71b7053SJung-uk Kim if (s_cert2 == NULL) { 1705db522d3aSSimon L. B. Nielsen ERR_print_errors(bio_err); 1706db522d3aSSimon L. B. Nielsen goto end; 1707db522d3aSSimon L. B. Nielsen } 1708db522d3aSSimon L. B. Nielsen } 170909286989SJung-uk Kim } 17107bded2dbSJung-uk Kim #if !defined(OPENSSL_NO_NEXTPROTONEG) 17116f9291ceSJung-uk Kim if (next_proto_neg_in) { 1712e71b7053SJung-uk Kim next_proto.data = next_protos_parse(&next_proto.len, next_proto_neg_in); 17131f13597dSJung-uk Kim if (next_proto.data == NULL) 17141f13597dSJung-uk Kim goto end; 17151f13597dSJung-uk Kim } 17161f13597dSJung-uk Kim #endif 17177bded2dbSJung-uk Kim alpn_ctx.data = NULL; 17187bded2dbSJung-uk Kim if (alpn_in) { 1719e71b7053SJung-uk Kim alpn_ctx.data = next_protos_parse(&alpn_ctx.len, alpn_in); 17207bded2dbSJung-uk Kim if (alpn_ctx.data == NULL) 17217bded2dbSJung-uk Kim goto end; 17227bded2dbSJung-uk Kim } 17237bded2dbSJung-uk Kim 1724e71b7053SJung-uk Kim if (crl_file != NULL) { 17257bded2dbSJung-uk Kim X509_CRL *crl; 17267bded2dbSJung-uk Kim crl = load_crl(crl_file, crl_format); 1727e71b7053SJung-uk Kim if (crl == NULL) { 17287bded2dbSJung-uk Kim BIO_puts(bio_err, "Error loading CRL\n"); 17297bded2dbSJung-uk Kim ERR_print_errors(bio_err); 17307bded2dbSJung-uk Kim goto end; 17317bded2dbSJung-uk Kim } 17327bded2dbSJung-uk Kim crls = sk_X509_CRL_new_null(); 1733e71b7053SJung-uk Kim if (crls == NULL || !sk_X509_CRL_push(crls, crl)) { 17347bded2dbSJung-uk Kim BIO_puts(bio_err, "Error adding CRL\n"); 17357bded2dbSJung-uk Kim ERR_print_errors(bio_err); 17367bded2dbSJung-uk Kim X509_CRL_free(crl); 17377bded2dbSJung-uk Kim goto end; 17387bded2dbSJung-uk Kim } 17397bded2dbSJung-uk Kim } 17401f13597dSJung-uk Kim 1741e71b7053SJung-uk Kim if (s_dcert_file != NULL) { 17423b4e3dcbSSimon L. B. Nielsen 17433b4e3dcbSSimon L. B. Nielsen if (s_dkey_file == NULL) 17443b4e3dcbSSimon L. B. Nielsen s_dkey_file = s_dcert_file; 17453b4e3dcbSSimon L. B. Nielsen 1746e71b7053SJung-uk Kim s_dkey = load_key(s_dkey_file, s_dkey_format, 1747e71b7053SJung-uk Kim 0, dpass, engine, "second certificate private key file"); 1748e71b7053SJung-uk Kim if (s_dkey == NULL) { 17493b4e3dcbSSimon L. B. Nielsen ERR_print_errors(bio_err); 17503b4e3dcbSSimon L. B. Nielsen goto end; 17513b4e3dcbSSimon L. B. Nielsen } 17523b4e3dcbSSimon L. B. Nielsen 1753e71b7053SJung-uk Kim s_dcert = load_cert(s_dcert_file, s_dcert_format, 1754e71b7053SJung-uk Kim "second server certificate file"); 17553b4e3dcbSSimon L. B. Nielsen 1756e71b7053SJung-uk Kim if (s_dcert == NULL) { 17573b4e3dcbSSimon L. B. Nielsen ERR_print_errors(bio_err); 17583b4e3dcbSSimon L. B. Nielsen goto end; 17593b4e3dcbSSimon L. B. Nielsen } 1760e71b7053SJung-uk Kim if (s_dchain_file != NULL) { 1761e71b7053SJung-uk Kim if (!load_certs(s_dchain_file, &s_dchain, FORMAT_PEM, NULL, 1762e71b7053SJung-uk Kim "second server certificate chain")) 17637bded2dbSJung-uk Kim goto end; 17647bded2dbSJung-uk Kim } 17653b4e3dcbSSimon L. B. Nielsen 17663b4e3dcbSSimon L. B. Nielsen } 17673b4e3dcbSSimon L. B. Nielsen 17686f9291ceSJung-uk Kim if (bio_s_out == NULL) { 17697bded2dbSJung-uk Kim if (s_quiet && !s_debug) { 177074664626SKris Kennaway bio_s_out = BIO_new(BIO_s_null()); 1771e71b7053SJung-uk Kim if (s_msg && bio_s_msg == NULL) 1772e71b7053SJung-uk Kim bio_s_msg = dup_bio_out(FORMAT_TEXT); 17736f9291ceSJung-uk Kim } else { 177474664626SKris Kennaway if (bio_s_out == NULL) 1775e71b7053SJung-uk Kim bio_s_out = dup_bio_out(FORMAT_TEXT); 177674664626SKris Kennaway } 177774664626SKris Kennaway } 1778e71b7053SJung-uk Kim #if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC) 177974664626SKris Kennaway if (nocert) 178074664626SKris Kennaway #endif 178174664626SKris Kennaway { 178274664626SKris Kennaway s_cert_file = NULL; 178374664626SKris Kennaway s_key_file = NULL; 178474664626SKris Kennaway s_dcert_file = NULL; 178574664626SKris Kennaway s_dkey_file = NULL; 1786db522d3aSSimon L. B. Nielsen s_cert_file2 = NULL; 1787db522d3aSSimon L. B. Nielsen s_key_file2 = NULL; 178874664626SKris Kennaway } 178974664626SKris Kennaway 179074664626SKris Kennaway ctx = SSL_CTX_new(meth); 17916f9291ceSJung-uk Kim if (ctx == NULL) { 179274664626SKris Kennaway ERR_print_errors(bio_err); 179374664626SKris Kennaway goto end; 179474664626SKris Kennaway } 1795e71b7053SJung-uk Kim 1796e71b7053SJung-uk Kim SSL_CTX_clear_mode(ctx, SSL_MODE_AUTO_RETRY); 1797e71b7053SJung-uk Kim 1798e71b7053SJung-uk Kim if (sdebug) 1799e71b7053SJung-uk Kim ssl_ctx_security_debug(ctx, sdebug); 1800e71b7053SJung-uk Kim 1801e71b7053SJung-uk Kim if (!config_ctx(cctx, ssl_args, ctx)) 1802e71b7053SJung-uk Kim goto end; 1803e71b7053SJung-uk Kim 1804e71b7053SJung-uk Kim if (ssl_config) { 1805e71b7053SJung-uk Kim if (SSL_CTX_config(ctx, ssl_config) == 0) { 1806e71b7053SJung-uk Kim BIO_printf(bio_err, "Error using configuration \"%s\"\n", 1807e71b7053SJung-uk Kim ssl_config); 1808e71b7053SJung-uk Kim ERR_print_errors(bio_err); 1809e71b7053SJung-uk Kim goto end; 1810e71b7053SJung-uk Kim } 1811e71b7053SJung-uk Kim } 18126935a639SJung-uk Kim 18136935a639SJung-uk Kim #ifndef OPENSSL_NO_SCTP 18146935a639SJung-uk Kim if (protocol == IPPROTO_SCTP && sctp_label_bug == 1) 18156935a639SJung-uk Kim SSL_CTX_set_mode(ctx, SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG); 18166935a639SJung-uk Kim #endif 18176935a639SJung-uk Kim 1818e71b7053SJung-uk Kim if (min_version != 0 1819e71b7053SJung-uk Kim && SSL_CTX_set_min_proto_version(ctx, min_version) == 0) 1820e71b7053SJung-uk Kim goto end; 1821e71b7053SJung-uk Kim if (max_version != 0 1822e71b7053SJung-uk Kim && SSL_CTX_set_max_proto_version(ctx, max_version) == 0) 1823e71b7053SJung-uk Kim goto end; 1824e71b7053SJung-uk Kim 18256f9291ceSJung-uk Kim if (session_id_prefix) { 18265c87c606SMark Murray if (strlen(session_id_prefix) >= 32) 18275c87c606SMark Murray BIO_printf(bio_err, 18285c87c606SMark Murray "warning: id_prefix is too long, only one new session will be possible\n"); 18296f9291ceSJung-uk Kim if (!SSL_CTX_set_generate_session_id(ctx, generate_session_id)) { 18305c87c606SMark Murray BIO_printf(bio_err, "error setting 'id_prefix'\n"); 18315c87c606SMark Murray ERR_print_errors(bio_err); 18325c87c606SMark Murray goto end; 18335c87c606SMark Murray } 18345c87c606SMark Murray BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix); 18355c87c606SMark Murray } 183674664626SKris Kennaway SSL_CTX_set_quiet_shutdown(ctx, 1); 1837e71b7053SJung-uk Kim if (exc != NULL) 18387bded2dbSJung-uk Kim ssl_ctx_set_excert(ctx, exc); 183974664626SKris Kennaway 18406f9291ceSJung-uk Kim if (state) 18416f9291ceSJung-uk Kim SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback); 18426a599222SSimon L. B. Nielsen if (no_cache) 18436a599222SSimon L. B. Nielsen SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); 18447bded2dbSJung-uk Kim else if (ext_cache) 18457bded2dbSJung-uk Kim init_session_cache_ctx(ctx); 18466a599222SSimon L. B. Nielsen else 184774664626SKris Kennaway SSL_CTX_sess_set_cache_size(ctx, 128); 184874664626SKris Kennaway 1849e71b7053SJung-uk Kim if (async) { 1850e71b7053SJung-uk Kim SSL_CTX_set_mode(ctx, SSL_MODE_ASYNC); 1851e71b7053SJung-uk Kim } 18521f13597dSJung-uk Kim 1853e71b7053SJung-uk Kim if (max_send_fragment > 0 1854e71b7053SJung-uk Kim && !SSL_CTX_set_max_send_fragment(ctx, max_send_fragment)) { 1855e71b7053SJung-uk Kim BIO_printf(bio_err, "%s: Max send fragment size %u is out of permitted range\n", 1856e71b7053SJung-uk Kim prog, max_send_fragment); 185774664626SKris Kennaway goto end; 185874664626SKris Kennaway } 1859e71b7053SJung-uk Kim 1860e71b7053SJung-uk Kim if (split_send_fragment > 0 1861e71b7053SJung-uk Kim && !SSL_CTX_set_split_send_fragment(ctx, split_send_fragment)) { 1862e71b7053SJung-uk Kim BIO_printf(bio_err, "%s: Split send fragment size %u is out of permitted range\n", 1863e71b7053SJung-uk Kim prog, split_send_fragment); 1864e71b7053SJung-uk Kim goto end; 1865e71b7053SJung-uk Kim } 1866e71b7053SJung-uk Kim if (max_pipelines > 0 1867e71b7053SJung-uk Kim && !SSL_CTX_set_max_pipelines(ctx, max_pipelines)) { 1868e71b7053SJung-uk Kim BIO_printf(bio_err, "%s: Max pipelines %u is out of permitted range\n", 1869e71b7053SJung-uk Kim prog, max_pipelines); 1870e71b7053SJung-uk Kim goto end; 1871e71b7053SJung-uk Kim } 1872e71b7053SJung-uk Kim 1873e71b7053SJung-uk Kim if (read_buf_len > 0) { 1874e71b7053SJung-uk Kim SSL_CTX_set_default_read_buffer_len(ctx, read_buf_len); 1875e71b7053SJung-uk Kim } 1876e71b7053SJung-uk Kim #ifndef OPENSSL_NO_SRTP 1877e71b7053SJung-uk Kim if (srtp_profiles != NULL) { 1878e71b7053SJung-uk Kim /* Returns 0 on success! */ 1879e71b7053SJung-uk Kim if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles) != 0) { 1880e71b7053SJung-uk Kim BIO_printf(bio_err, "Error setting SRTP profile\n"); 1881e71b7053SJung-uk Kim ERR_print_errors(bio_err); 1882e71b7053SJung-uk Kim goto end; 1883e71b7053SJung-uk Kim } 1884e71b7053SJung-uk Kim } 188574664626SKris Kennaway #endif 188674664626SKris Kennaway 1887e71b7053SJung-uk Kim if (!ctx_set_verify_locations(ctx, CAfile, CApath, noCAfile, noCApath)) { 188874664626SKris Kennaway ERR_print_errors(bio_err); 1889e71b7053SJung-uk Kim goto end; 189074664626SKris Kennaway } 1891e71b7053SJung-uk Kim if (vpmtouched && !SSL_CTX_set1_param(ctx, vpm)) { 1892e71b7053SJung-uk Kim BIO_printf(bio_err, "Error setting verify params\n"); 1893e71b7053SJung-uk Kim ERR_print_errors(bio_err); 1894e71b7053SJung-uk Kim goto end; 1895e71b7053SJung-uk Kim } 18961f13597dSJung-uk Kim 18977bded2dbSJung-uk Kim ssl_ctx_add_crls(ctx, crls, 0); 18987bded2dbSJung-uk Kim 18997bded2dbSJung-uk Kim if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile, 19007bded2dbSJung-uk Kim crls, crl_download)) { 19017bded2dbSJung-uk Kim BIO_printf(bio_err, "Error loading store locations\n"); 19027bded2dbSJung-uk Kim ERR_print_errors(bio_err); 19037bded2dbSJung-uk Kim goto end; 19047bded2dbSJung-uk Kim } 1905e71b7053SJung-uk Kim 19066f9291ceSJung-uk Kim if (s_cert2) { 1907db522d3aSSimon L. B. Nielsen ctx2 = SSL_CTX_new(meth); 19086f9291ceSJung-uk Kim if (ctx2 == NULL) { 1909db522d3aSSimon L. B. Nielsen ERR_print_errors(bio_err); 1910db522d3aSSimon L. B. Nielsen goto end; 1911db522d3aSSimon L. B. Nielsen } 1912db522d3aSSimon L. B. Nielsen } 1913db522d3aSSimon L. B. Nielsen 1914e71b7053SJung-uk Kim if (ctx2 != NULL) { 1915db522d3aSSimon L. B. Nielsen BIO_printf(bio_s_out, "Setting secondary ctx parameters\n"); 1916db522d3aSSimon L. B. Nielsen 1917e71b7053SJung-uk Kim if (sdebug) 191811c7efe3SJung-uk Kim ssl_ctx_security_debug(ctx2, sdebug); 1919e71b7053SJung-uk Kim 19206f9291ceSJung-uk Kim if (session_id_prefix) { 1921db522d3aSSimon L. B. Nielsen if (strlen(session_id_prefix) >= 32) 1922db522d3aSSimon L. B. Nielsen BIO_printf(bio_err, 1923db522d3aSSimon L. B. Nielsen "warning: id_prefix is too long, only one new session will be possible\n"); 19246f9291ceSJung-uk Kim if (!SSL_CTX_set_generate_session_id(ctx2, generate_session_id)) { 1925db522d3aSSimon L. B. Nielsen BIO_printf(bio_err, "error setting 'id_prefix'\n"); 1926db522d3aSSimon L. B. Nielsen ERR_print_errors(bio_err); 1927db522d3aSSimon L. B. Nielsen goto end; 1928db522d3aSSimon L. B. Nielsen } 1929db522d3aSSimon L. B. Nielsen BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix); 1930db522d3aSSimon L. B. Nielsen } 1931db522d3aSSimon L. B. Nielsen SSL_CTX_set_quiet_shutdown(ctx2, 1); 1932e71b7053SJung-uk Kim if (exc != NULL) 19337bded2dbSJung-uk Kim ssl_ctx_set_excert(ctx2, exc); 1934db522d3aSSimon L. B. Nielsen 19356f9291ceSJung-uk Kim if (state) 19366f9291ceSJung-uk Kim SSL_CTX_set_info_callback(ctx2, apps_ssl_info_callback); 1937db522d3aSSimon L. B. Nielsen 19386a599222SSimon L. B. Nielsen if (no_cache) 19396a599222SSimon L. B. Nielsen SSL_CTX_set_session_cache_mode(ctx2, SSL_SESS_CACHE_OFF); 19407bded2dbSJung-uk Kim else if (ext_cache) 19417bded2dbSJung-uk Kim init_session_cache_ctx(ctx2); 19426a599222SSimon L. B. Nielsen else 1943db522d3aSSimon L. B. Nielsen SSL_CTX_sess_set_cache_size(ctx2, 128); 1944db522d3aSSimon L. B. Nielsen 1945e71b7053SJung-uk Kim if (async) 1946e71b7053SJung-uk Kim SSL_CTX_set_mode(ctx2, SSL_MODE_ASYNC); 1947e71b7053SJung-uk Kim 1948e71b7053SJung-uk Kim if (!ctx_set_verify_locations(ctx2, CAfile, CApath, noCAfile, 1949e71b7053SJung-uk Kim noCApath)) { 1950db522d3aSSimon L. B. Nielsen ERR_print_errors(bio_err); 1951e71b7053SJung-uk Kim goto end; 1952db522d3aSSimon L. B. Nielsen } 1953e71b7053SJung-uk Kim if (vpmtouched && !SSL_CTX_set1_param(ctx2, vpm)) { 1954e71b7053SJung-uk Kim BIO_printf(bio_err, "Error setting verify params\n"); 1955e71b7053SJung-uk Kim ERR_print_errors(bio_err); 1956e71b7053SJung-uk Kim goto end; 1957e71b7053SJung-uk Kim } 19587bded2dbSJung-uk Kim 19597bded2dbSJung-uk Kim ssl_ctx_add_crls(ctx2, crls, 0); 1960e71b7053SJung-uk Kim if (!config_ctx(cctx, ssl_args, ctx2)) 19617bded2dbSJung-uk Kim goto end; 1962db522d3aSSimon L. B. Nielsen } 19631f13597dSJung-uk Kim #ifndef OPENSSL_NO_NEXTPROTONEG 19641f13597dSJung-uk Kim if (next_proto.data) 19656f9291ceSJung-uk Kim SSL_CTX_set_next_protos_advertised_cb(ctx, next_proto_cb, 19666f9291ceSJung-uk Kim &next_proto); 19671f13597dSJung-uk Kim #endif 19687bded2dbSJung-uk Kim if (alpn_ctx.data) 19697bded2dbSJung-uk Kim SSL_CTX_set_alpn_select_cb(ctx, alpn_cb, &alpn_ctx); 197074664626SKris Kennaway 19715c87c606SMark Murray #ifndef OPENSSL_NO_DH 19726f9291ceSJung-uk Kim if (!no_dhe) { 19735c87c606SMark Murray DH *dh = NULL; 19745c87c606SMark Murray 1975e71b7053SJung-uk Kim if (dhfile != NULL) 19765c87c606SMark Murray dh = load_dh_param(dhfile); 1977e71b7053SJung-uk Kim else if (s_cert_file != NULL) 19785c87c606SMark Murray dh = load_dh_param(s_cert_file); 19795c87c606SMark Murray 19806f9291ceSJung-uk Kim if (dh != NULL) { 198174664626SKris Kennaway BIO_printf(bio_s_out, "Setting temp DH parameters\n"); 19826f9291ceSJung-uk Kim } else { 198374664626SKris Kennaway BIO_printf(bio_s_out, "Using default temp DH parameters\n"); 198474664626SKris Kennaway } 198574664626SKris Kennaway (void)BIO_flush(bio_s_out); 198674664626SKris Kennaway 1987e71b7053SJung-uk Kim if (dh == NULL) { 1988e71b7053SJung-uk Kim SSL_CTX_set_dh_auto(ctx, 1); 1989e71b7053SJung-uk Kim } else if (!SSL_CTX_set_tmp_dh(ctx, dh)) { 1990e71b7053SJung-uk Kim BIO_puts(bio_err, "Error setting temp DH parameters\n"); 1991e71b7053SJung-uk Kim ERR_print_errors(bio_err); 1992e71b7053SJung-uk Kim DH_free(dh); 1993e71b7053SJung-uk Kim goto end; 1994e71b7053SJung-uk Kim } 1995e71b7053SJung-uk Kim 1996e71b7053SJung-uk Kim if (ctx2 != NULL) { 19976f9291ceSJung-uk Kim if (!dhfile) { 1998db522d3aSSimon L. B. Nielsen DH *dh2 = load_dh_param(s_cert_file2); 19996f9291ceSJung-uk Kim if (dh2 != NULL) { 2000db522d3aSSimon L. B. Nielsen BIO_printf(bio_s_out, "Setting temp DH parameters\n"); 2001db522d3aSSimon L. B. Nielsen (void)BIO_flush(bio_s_out); 2002db522d3aSSimon L. B. Nielsen 2003db522d3aSSimon L. B. Nielsen DH_free(dh); 2004db522d3aSSimon L. B. Nielsen dh = dh2; 2005db522d3aSSimon L. B. Nielsen } 2006db522d3aSSimon L. B. Nielsen } 2007e71b7053SJung-uk Kim if (dh == NULL) { 2008e71b7053SJung-uk Kim SSL_CTX_set_dh_auto(ctx2, 1); 2009e71b7053SJung-uk Kim } else if (!SSL_CTX_set_tmp_dh(ctx2, dh)) { 2010e71b7053SJung-uk Kim BIO_puts(bio_err, "Error setting temp DH parameters\n"); 2011e71b7053SJung-uk Kim ERR_print_errors(bio_err); 2012e71b7053SJung-uk Kim DH_free(dh); 2013e71b7053SJung-uk Kim goto end; 2014db522d3aSSimon L. B. Nielsen } 2015e71b7053SJung-uk Kim } 201674664626SKris Kennaway DH_free(dh); 201774664626SKris Kennaway } 201874664626SKris Kennaway #endif 201974664626SKris Kennaway 20207bded2dbSJung-uk Kim if (!set_cert_key_stuff(ctx, s_cert, s_key, s_chain, build_chain)) 20213b4e3dcbSSimon L. B. Nielsen goto end; 2022e71b7053SJung-uk Kim 20237bded2dbSJung-uk Kim if (s_serverinfo_file != NULL 20247bded2dbSJung-uk Kim && !SSL_CTX_use_serverinfo_file(ctx, s_serverinfo_file)) { 20257bded2dbSJung-uk Kim ERR_print_errors(bio_err); 20267bded2dbSJung-uk Kim goto end; 20277bded2dbSJung-uk Kim } 2028e71b7053SJung-uk Kim 2029e71b7053SJung-uk Kim if (ctx2 != NULL 2030e71b7053SJung-uk Kim && !set_cert_key_stuff(ctx2, s_cert2, s_key2, NULL, build_chain)) 2031db522d3aSSimon L. B. Nielsen goto end; 2032e71b7053SJung-uk Kim 20336f9291ceSJung-uk Kim if (s_dcert != NULL) { 20347bded2dbSJung-uk Kim if (!set_cert_key_stuff(ctx, s_dcert, s_dkey, s_dchain, build_chain)) 203574664626SKris Kennaway goto end; 203674664626SKris Kennaway } 203774664626SKris Kennaway 2038e71b7053SJung-uk Kim if (no_resume_ephemeral) { 2039e71b7053SJung-uk Kim SSL_CTX_set_not_resumable_session_callback(ctx, 2040e71b7053SJung-uk Kim not_resumable_sess_cb); 204174664626SKris Kennaway 2042e71b7053SJung-uk Kim if (ctx2 != NULL) 2043e71b7053SJung-uk Kim SSL_CTX_set_not_resumable_session_callback(ctx2, 2044e71b7053SJung-uk Kim not_resumable_sess_cb); 204574664626SKris Kennaway } 20461f13597dSJung-uk Kim #ifndef OPENSSL_NO_PSK 2047e71b7053SJung-uk Kim if (psk_key != NULL) { 20481f13597dSJung-uk Kim if (s_debug) 2049e71b7053SJung-uk Kim BIO_printf(bio_s_out, "PSK key given, setting server callback\n"); 20501f13597dSJung-uk Kim SSL_CTX_set_psk_server_callback(ctx, psk_server_cb); 20511f13597dSJung-uk Kim } 20521f13597dSJung-uk Kim 20536f9291ceSJung-uk Kim if (!SSL_CTX_use_psk_identity_hint(ctx, psk_identity_hint)) { 20541f13597dSJung-uk Kim BIO_printf(bio_err, "error setting PSK identity hint to context\n"); 20551f13597dSJung-uk Kim ERR_print_errors(bio_err); 20561f13597dSJung-uk Kim goto end; 20571f13597dSJung-uk Kim } 20581f13597dSJung-uk Kim #endif 2059e71b7053SJung-uk Kim if (psksessf != NULL) { 2060e71b7053SJung-uk Kim BIO *stmp = BIO_new_file(psksessf, "r"); 2061e71b7053SJung-uk Kim 2062e71b7053SJung-uk Kim if (stmp == NULL) { 2063e71b7053SJung-uk Kim BIO_printf(bio_err, "Can't open PSK session file %s\n", psksessf); 2064e71b7053SJung-uk Kim ERR_print_errors(bio_err); 2065e71b7053SJung-uk Kim goto end; 2066e71b7053SJung-uk Kim } 2067e71b7053SJung-uk Kim psksess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL); 2068e71b7053SJung-uk Kim BIO_free(stmp); 2069e71b7053SJung-uk Kim if (psksess == NULL) { 2070e71b7053SJung-uk Kim BIO_printf(bio_err, "Can't read PSK session file %s\n", psksessf); 2071e71b7053SJung-uk Kim ERR_print_errors(bio_err); 2072e71b7053SJung-uk Kim goto end; 2073e71b7053SJung-uk Kim } 2074e71b7053SJung-uk Kim 2075e71b7053SJung-uk Kim } 2076e71b7053SJung-uk Kim 2077e71b7053SJung-uk Kim if (psk_key != NULL || psksess != NULL) 2078e71b7053SJung-uk Kim SSL_CTX_set_psk_find_session_callback(ctx, psk_find_session_cb); 20791f13597dSJung-uk Kim 208074664626SKris Kennaway SSL_CTX_set_verify(ctx, s_server_verify, verify_callback); 2081e71b7053SJung-uk Kim if (!SSL_CTX_set_session_id_context(ctx, 2082e71b7053SJung-uk Kim (void *)&s_server_session_id_context, 2083e71b7053SJung-uk Kim sizeof(s_server_session_id_context))) { 2084e71b7053SJung-uk Kim BIO_printf(bio_err, "error setting session id context\n"); 2085e71b7053SJung-uk Kim ERR_print_errors(bio_err); 2086e71b7053SJung-uk Kim goto end; 2087e71b7053SJung-uk Kim } 208874664626SKris Kennaway 20896a599222SSimon L. B. Nielsen /* Set DTLS cookie generation and verification callbacks */ 20906a599222SSimon L. B. Nielsen SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie_callback); 20916a599222SSimon L. B. Nielsen SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie_callback); 20926a599222SSimon L. B. Nielsen 2093e71b7053SJung-uk Kim /* Set TLS1.3 cookie generation and verification callbacks */ 2094e71b7053SJung-uk Kim SSL_CTX_set_stateless_cookie_generate_cb(ctx, generate_stateless_cookie_callback); 2095e71b7053SJung-uk Kim SSL_CTX_set_stateless_cookie_verify_cb(ctx, verify_stateless_cookie_callback); 209674664626SKris Kennaway 2097e71b7053SJung-uk Kim if (ctx2 != NULL) { 2098e71b7053SJung-uk Kim SSL_CTX_set_verify(ctx2, s_server_verify, verify_callback); 2099e71b7053SJung-uk Kim if (!SSL_CTX_set_session_id_context(ctx2, 2100e71b7053SJung-uk Kim (void *)&s_server_session_id_context, 2101e71b7053SJung-uk Kim sizeof(s_server_session_id_context))) { 2102e71b7053SJung-uk Kim BIO_printf(bio_err, "error setting session id context\n"); 2103e71b7053SJung-uk Kim ERR_print_errors(bio_err); 2104e71b7053SJung-uk Kim goto end; 2105e71b7053SJung-uk Kim } 2106db522d3aSSimon L. B. Nielsen tlsextcbp.biodebug = bio_s_out; 2107db522d3aSSimon L. B. Nielsen SSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb); 2108db522d3aSSimon L. B. Nielsen SSL_CTX_set_tlsext_servername_arg(ctx2, &tlsextcbp); 2109db522d3aSSimon L. B. Nielsen SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); 2110db522d3aSSimon L. B. Nielsen SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp); 2111db522d3aSSimon L. B. Nielsen } 21121f13597dSJung-uk Kim 21131f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP 21146f9291ceSJung-uk Kim if (srp_verifier_file != NULL) { 21151f13597dSJung-uk Kim srp_callback_parm.vb = SRP_VBASE_new(srpuserseed); 21161f13597dSJung-uk Kim srp_callback_parm.user = NULL; 21171f13597dSJung-uk Kim srp_callback_parm.login = NULL; 21186f9291ceSJung-uk Kim if ((ret = 21196f9291ceSJung-uk Kim SRP_VBASE_init(srp_callback_parm.vb, 21206f9291ceSJung-uk Kim srp_verifier_file)) != SRP_NO_ERROR) { 21211f13597dSJung-uk Kim BIO_printf(bio_err, 21221f13597dSJung-uk Kim "Cannot initialize SRP verifier file \"%s\":ret=%d\n", 21231f13597dSJung-uk Kim srp_verifier_file, ret); 21241f13597dSJung-uk Kim goto end; 21251f13597dSJung-uk Kim } 21261f13597dSJung-uk Kim SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_callback); 21271f13597dSJung-uk Kim SSL_CTX_set_srp_cb_arg(ctx, &srp_callback_parm); 21281f13597dSJung-uk Kim SSL_CTX_set_srp_username_callback(ctx, ssl_srp_server_param_cb); 21296f9291ceSJung-uk Kim } else 21301f13597dSJung-uk Kim #endif 21316f9291ceSJung-uk Kim if (CAfile != NULL) { 2132db522d3aSSimon L. B. Nielsen SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(CAfile)); 2133e71b7053SJung-uk Kim 2134db522d3aSSimon L. B. Nielsen if (ctx2) 2135db522d3aSSimon L. B. Nielsen SSL_CTX_set_client_CA_list(ctx2, SSL_load_client_CA_file(CAfile)); 2136db522d3aSSimon L. B. Nielsen } 2137e71b7053SJung-uk Kim #ifndef OPENSSL_NO_OCSP 2138e71b7053SJung-uk Kim if (s_tlsextstatus) { 2139e71b7053SJung-uk Kim SSL_CTX_set_tlsext_status_cb(ctx, cert_status_cb); 2140e71b7053SJung-uk Kim SSL_CTX_set_tlsext_status_arg(ctx, &tlscstatp); 2141e71b7053SJung-uk Kim if (ctx2) { 2142e71b7053SJung-uk Kim SSL_CTX_set_tlsext_status_cb(ctx2, cert_status_cb); 2143e71b7053SJung-uk Kim SSL_CTX_set_tlsext_status_arg(ctx2, &tlscstatp); 2144e71b7053SJung-uk Kim } 2145e71b7053SJung-uk Kim } 2146e71b7053SJung-uk Kim #endif 2147e71b7053SJung-uk Kim if (set_keylog_file(ctx, keylog_file)) 2148e71b7053SJung-uk Kim goto end; 21491f13597dSJung-uk Kim 2150e71b7053SJung-uk Kim if (max_early_data >= 0) 2151e71b7053SJung-uk Kim SSL_CTX_set_max_early_data(ctx, max_early_data); 2152e71b7053SJung-uk Kim if (recv_max_early_data >= 0) 2153e71b7053SJung-uk Kim SSL_CTX_set_recv_max_early_data(ctx, recv_max_early_data); 2154e71b7053SJung-uk Kim 21557bded2dbSJung-uk Kim if (rev) 2156e71b7053SJung-uk Kim server_cb = rev_body; 21577bded2dbSJung-uk Kim else if (www) 2158e71b7053SJung-uk Kim server_cb = www_body; 215974664626SKris Kennaway else 2160e71b7053SJung-uk Kim server_cb = sv_body; 2161e71b7053SJung-uk Kim #ifdef AF_UNIX 2162e71b7053SJung-uk Kim if (socket_family == AF_UNIX 2163e71b7053SJung-uk Kim && unlink_unix_path) 2164e71b7053SJung-uk Kim unlink(host); 2165e71b7053SJung-uk Kim #endif 2166e71b7053SJung-uk Kim do_server(&accept_socket, host, port, socket_family, socket_type, protocol, 2167e71b7053SJung-uk Kim server_cb, context, naccept, bio_s_out); 216874664626SKris Kennaway print_stats(bio_s_out, ctx); 216974664626SKris Kennaway ret = 0; 217074664626SKris Kennaway end: 21716f9291ceSJung-uk Kim SSL_CTX_free(ctx); 2172e71b7053SJung-uk Kim SSL_SESSION_free(psksess); 2173e71b7053SJung-uk Kim set_keylog_file(NULL, NULL); 21743b4e3dcbSSimon L. B. Nielsen X509_free(s_cert); 21757bded2dbSJung-uk Kim sk_X509_CRL_pop_free(crls, X509_CRL_free); 21763b4e3dcbSSimon L. B. Nielsen X509_free(s_dcert); 21773b4e3dcbSSimon L. B. Nielsen EVP_PKEY_free(s_key); 21783b4e3dcbSSimon L. B. Nielsen EVP_PKEY_free(s_dkey); 21797bded2dbSJung-uk Kim sk_X509_pop_free(s_chain, X509_free); 21807bded2dbSJung-uk Kim sk_X509_pop_free(s_dchain, X509_free); 21813b4e3dcbSSimon L. B. Nielsen OPENSSL_free(pass); 21823b4e3dcbSSimon L. B. Nielsen OPENSSL_free(dpass); 2183e71b7053SJung-uk Kim OPENSSL_free(host); 2184e71b7053SJung-uk Kim OPENSSL_free(port); 218509286989SJung-uk Kim X509_VERIFY_PARAM_free(vpm); 21867bded2dbSJung-uk Kim free_sessions(); 218709286989SJung-uk Kim OPENSSL_free(tlscstatp.host); 218809286989SJung-uk Kim OPENSSL_free(tlscstatp.port); 218909286989SJung-uk Kim OPENSSL_free(tlscstatp.path); 21906f9291ceSJung-uk Kim SSL_CTX_free(ctx2); 2191db522d3aSSimon L. B. Nielsen X509_free(s_cert2); 2192db522d3aSSimon L. B. Nielsen EVP_PKEY_free(s_key2); 21937bded2dbSJung-uk Kim #ifndef OPENSSL_NO_NEXTPROTONEG 21947bded2dbSJung-uk Kim OPENSSL_free(next_proto.data); 21957bded2dbSJung-uk Kim #endif 21967bded2dbSJung-uk Kim OPENSSL_free(alpn_ctx.data); 21977bded2dbSJung-uk Kim ssl_excert_free(exc); 21987bded2dbSJung-uk Kim sk_OPENSSL_STRING_free(ssl_args); 21997bded2dbSJung-uk Kim SSL_CONF_CTX_free(cctx); 2200e71b7053SJung-uk Kim release_engine(engine); 220174664626SKris Kennaway BIO_free(bio_s_out); 220274664626SKris Kennaway bio_s_out = NULL; 22037bded2dbSJung-uk Kim BIO_free(bio_s_msg); 22047bded2dbSJung-uk Kim bio_s_msg = NULL; 2205e71b7053SJung-uk Kim #ifdef CHARSET_EBCDIC 2206e71b7053SJung-uk Kim BIO_meth_free(methods_ebcdic); 2207e71b7053SJung-uk Kim #endif 2208e71b7053SJung-uk Kim return ret; 220974664626SKris Kennaway } 221074664626SKris Kennaway 221174664626SKris Kennaway static void print_stats(BIO *bio, SSL_CTX *ssl_ctx) 221274664626SKris Kennaway { 221374664626SKris Kennaway BIO_printf(bio, "%4ld items in the session cache\n", 221474664626SKris Kennaway SSL_CTX_sess_number(ssl_ctx)); 22153b4e3dcbSSimon L. B. Nielsen BIO_printf(bio, "%4ld client connects (SSL_connect())\n", 221674664626SKris Kennaway SSL_CTX_sess_connect(ssl_ctx)); 22173b4e3dcbSSimon L. B. Nielsen BIO_printf(bio, "%4ld client renegotiates (SSL_connect())\n", 221874664626SKris Kennaway SSL_CTX_sess_connect_renegotiate(ssl_ctx)); 22193b4e3dcbSSimon L. B. Nielsen BIO_printf(bio, "%4ld client connects that finished\n", 222074664626SKris Kennaway SSL_CTX_sess_connect_good(ssl_ctx)); 22213b4e3dcbSSimon L. B. Nielsen BIO_printf(bio, "%4ld server accepts (SSL_accept())\n", 222274664626SKris Kennaway SSL_CTX_sess_accept(ssl_ctx)); 22233b4e3dcbSSimon L. B. Nielsen BIO_printf(bio, "%4ld server renegotiates (SSL_accept())\n", 222474664626SKris Kennaway SSL_CTX_sess_accept_renegotiate(ssl_ctx)); 22253b4e3dcbSSimon L. B. Nielsen BIO_printf(bio, "%4ld server accepts that finished\n", 222674664626SKris Kennaway SSL_CTX_sess_accept_good(ssl_ctx)); 22273b4e3dcbSSimon L. B. Nielsen BIO_printf(bio, "%4ld session cache hits\n", SSL_CTX_sess_hits(ssl_ctx)); 22286f9291ceSJung-uk Kim BIO_printf(bio, "%4ld session cache misses\n", 22296f9291ceSJung-uk Kim SSL_CTX_sess_misses(ssl_ctx)); 22306f9291ceSJung-uk Kim BIO_printf(bio, "%4ld session cache timeouts\n", 22316f9291ceSJung-uk Kim SSL_CTX_sess_timeouts(ssl_ctx)); 22326f9291ceSJung-uk Kim BIO_printf(bio, "%4ld callback cache hits\n", 22336f9291ceSJung-uk Kim SSL_CTX_sess_cb_hits(ssl_ctx)); 22343b4e3dcbSSimon L. B. Nielsen BIO_printf(bio, "%4ld cache full overflows (%ld allowed)\n", 223574664626SKris Kennaway SSL_CTX_sess_cache_full(ssl_ctx), 223674664626SKris Kennaway SSL_CTX_sess_get_cache_size(ssl_ctx)); 223774664626SKris Kennaway } 223874664626SKris Kennaway 2239e71b7053SJung-uk Kim static int sv_body(int s, int stype, int prot, unsigned char *context) 224074664626SKris Kennaway { 224174664626SKris Kennaway char *buf = NULL; 224274664626SKris Kennaway fd_set readfds; 224374664626SKris Kennaway int ret = 1, width; 224474664626SKris Kennaway int k, i; 224574664626SKris Kennaway unsigned long l; 224674664626SKris Kennaway SSL *con = NULL; 224774664626SKris Kennaway BIO *sbio; 22486a599222SSimon L. B. Nielsen struct timeval timeout; 2249e71b7053SJung-uk Kim #if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)) 22506a599222SSimon L. B. Nielsen struct timeval *timeoutp; 2251f579bf8eSKris Kennaway #endif 2252e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS 2253e71b7053SJung-uk Kim # ifndef OPENSSL_NO_SCTP 2254e71b7053SJung-uk Kim int isdtls = (stype == SOCK_DGRAM || prot == IPPROTO_SCTP); 2255e71b7053SJung-uk Kim # else 2256e71b7053SJung-uk Kim int isdtls = (stype == SOCK_DGRAM); 2257e71b7053SJung-uk Kim # endif 225874664626SKris Kennaway #endif 225974664626SKris Kennaway 2260e71b7053SJung-uk Kim buf = app_malloc(bufsize, "server buffer"); 2261e71b7053SJung-uk Kim if (s_nbio) { 2262e71b7053SJung-uk Kim if (!BIO_socket_nbio(s, 1)) 2263e71b7053SJung-uk Kim ERR_print_errors(bio_err); 2264e71b7053SJung-uk Kim else if (!s_quiet) 2265e71b7053SJung-uk Kim BIO_printf(bio_err, "Turned on non blocking io\n"); 2266e71b7053SJung-uk Kim } 2267e71b7053SJung-uk Kim 2268f579bf8eSKris Kennaway con = SSL_new(ctx); 2269e71b7053SJung-uk Kim if (con == NULL) { 2270e71b7053SJung-uk Kim ret = -1; 2271e71b7053SJung-uk Kim goto err; 2272e71b7053SJung-uk Kim } 2273e71b7053SJung-uk Kim 22746f9291ceSJung-uk Kim if (s_tlsextdebug) { 2275db522d3aSSimon L. B. Nielsen SSL_set_tlsext_debug_callback(con, tlsext_cb); 2276db522d3aSSimon L. B. Nielsen SSL_set_tlsext_debug_arg(con, bio_s_out); 2277db522d3aSSimon L. B. Nielsen } 227874664626SKris Kennaway 2279e71b7053SJung-uk Kim if (context != NULL 2280e71b7053SJung-uk Kim && !SSL_set_session_id_context(con, context, 2281e71b7053SJung-uk Kim strlen((char *)context))) { 2282e71b7053SJung-uk Kim BIO_printf(bio_err, "Error setting session id context\n"); 2283e71b7053SJung-uk Kim ret = -1; 2284e71b7053SJung-uk Kim goto err; 2285e71b7053SJung-uk Kim } 22863b4e3dcbSSimon L. B. Nielsen 2287e71b7053SJung-uk Kim if (!SSL_clear(con)) { 2288e71b7053SJung-uk Kim BIO_printf(bio_err, "Error clearing SSL connection\n"); 2289e71b7053SJung-uk Kim ret = -1; 2290e71b7053SJung-uk Kim goto err; 2291e71b7053SJung-uk Kim } 2292e71b7053SJung-uk Kim #ifndef OPENSSL_NO_DTLS 2293e71b7053SJung-uk Kim if (isdtls) { 2294e71b7053SJung-uk Kim # ifndef OPENSSL_NO_SCTP 2295e71b7053SJung-uk Kim if (prot == IPPROTO_SCTP) 2296e71b7053SJung-uk Kim sbio = BIO_new_dgram_sctp(s, BIO_NOCLOSE); 2297e71b7053SJung-uk Kim else 2298e71b7053SJung-uk Kim # endif 22993b4e3dcbSSimon L. B. Nielsen sbio = BIO_new_dgram(s, BIO_NOCLOSE); 23003b4e3dcbSSimon L. B. Nielsen 23016f9291ceSJung-uk Kim if (enable_timeouts) { 23023b4e3dcbSSimon L. B. Nielsen timeout.tv_sec = 0; 23033b4e3dcbSSimon L. B. Nielsen timeout.tv_usec = DGRAM_RCV_TIMEOUT; 23043b4e3dcbSSimon L. B. Nielsen BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); 23053b4e3dcbSSimon L. B. Nielsen 23063b4e3dcbSSimon L. B. Nielsen timeout.tv_sec = 0; 23073b4e3dcbSSimon L. B. Nielsen timeout.tv_usec = DGRAM_SND_TIMEOUT; 23083b4e3dcbSSimon L. B. Nielsen BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout); 23093b4e3dcbSSimon L. B. Nielsen } 23103b4e3dcbSSimon L. B. Nielsen 23116f9291ceSJung-uk Kim if (socket_mtu) { 23126f9291ceSJung-uk Kim if (socket_mtu < DTLS_get_link_min_mtu(con)) { 2313751d2991SJung-uk Kim BIO_printf(bio_err, "MTU too small. Must be at least %ld\n", 2314751d2991SJung-uk Kim DTLS_get_link_min_mtu(con)); 2315751d2991SJung-uk Kim ret = -1; 2316751d2991SJung-uk Kim BIO_free(sbio); 2317751d2991SJung-uk Kim goto err; 2318751d2991SJung-uk Kim } 23193b4e3dcbSSimon L. B. Nielsen SSL_set_options(con, SSL_OP_NO_QUERY_MTU); 23206f9291ceSJung-uk Kim if (!DTLS_set_link_mtu(con, socket_mtu)) { 2321751d2991SJung-uk Kim BIO_printf(bio_err, "Failed to set MTU\n"); 2322751d2991SJung-uk Kim ret = -1; 2323751d2991SJung-uk Kim BIO_free(sbio); 2324751d2991SJung-uk Kim goto err; 2325751d2991SJung-uk Kim } 23266f9291ceSJung-uk Kim } else 23273b4e3dcbSSimon L. B. Nielsen /* want to do MTU discovery */ 23283b4e3dcbSSimon L. B. Nielsen BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); 23293b4e3dcbSSimon L. B. Nielsen 2330e71b7053SJung-uk Kim # ifndef OPENSSL_NO_SCTP 2331e71b7053SJung-uk Kim if (prot != IPPROTO_SCTP) 2332e71b7053SJung-uk Kim # endif 2333e71b7053SJung-uk Kim /* Turn on cookie exchange. Not necessary for SCTP */ 23343b4e3dcbSSimon L. B. Nielsen SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE); 23356f9291ceSJung-uk Kim } else 2336e71b7053SJung-uk Kim #endif 233774664626SKris Kennaway sbio = BIO_new_socket(s, BIO_NOCLOSE); 23383b4e3dcbSSimon L. B. Nielsen 2339e71b7053SJung-uk Kim if (sbio == NULL) { 2340e71b7053SJung-uk Kim BIO_printf(bio_err, "Unable to create BIO\n"); 2341e71b7053SJung-uk Kim ERR_print_errors(bio_err); 2342e71b7053SJung-uk Kim goto err; 2343e71b7053SJung-uk Kim } 2344e71b7053SJung-uk Kim 23456f9291ceSJung-uk Kim if (s_nbio_test) { 234674664626SKris Kennaway BIO *test; 234774664626SKris Kennaway 234874664626SKris Kennaway test = BIO_new(BIO_f_nbio_test()); 234974664626SKris Kennaway sbio = BIO_push(test, sbio); 235074664626SKris Kennaway } 2351db522d3aSSimon L. B. Nielsen 235274664626SKris Kennaway SSL_set_bio(con, sbio, sbio); 235374664626SKris Kennaway SSL_set_accept_state(con); 235474664626SKris Kennaway /* SSL_set_fd(con,s); */ 235574664626SKris Kennaway 23566f9291ceSJung-uk Kim if (s_debug) { 23573b4e3dcbSSimon L. B. Nielsen BIO_set_callback(SSL_get_rbio(con), bio_dump_callback); 23585471f83eSSimon L. B. Nielsen BIO_set_callback_arg(SSL_get_rbio(con), (char *)bio_s_out); 235974664626SKris Kennaway } 23606f9291ceSJung-uk Kim if (s_msg) { 23617bded2dbSJung-uk Kim #ifndef OPENSSL_NO_SSL_TRACE 23627bded2dbSJung-uk Kim if (s_msg == 2) 23637bded2dbSJung-uk Kim SSL_set_msg_callback(con, SSL_trace); 23647bded2dbSJung-uk Kim else 23657bded2dbSJung-uk Kim #endif 23665c87c606SMark Murray SSL_set_msg_callback(con, msg_cb); 23677bded2dbSJung-uk Kim SSL_set_msg_callback_arg(con, bio_s_msg ? bio_s_msg : bio_s_out); 23685c87c606SMark Murray } 2369e71b7053SJung-uk Kim 23706f9291ceSJung-uk Kim if (s_tlsextdebug) { 2371db522d3aSSimon L. B. Nielsen SSL_set_tlsext_debug_callback(con, tlsext_cb); 2372db522d3aSSimon L. B. Nielsen SSL_set_tlsext_debug_arg(con, bio_s_out); 2373db522d3aSSimon L. B. Nielsen } 2374e71b7053SJung-uk Kim 2375e71b7053SJung-uk Kim if (early_data) { 2376e71b7053SJung-uk Kim int write_header = 1, edret = SSL_READ_EARLY_DATA_ERROR; 2377e71b7053SJung-uk Kim size_t readbytes; 2378e71b7053SJung-uk Kim 2379e71b7053SJung-uk Kim while (edret != SSL_READ_EARLY_DATA_FINISH) { 2380e71b7053SJung-uk Kim for (;;) { 2381e71b7053SJung-uk Kim edret = SSL_read_early_data(con, buf, bufsize, &readbytes); 2382e71b7053SJung-uk Kim if (edret != SSL_READ_EARLY_DATA_ERROR) 2383e71b7053SJung-uk Kim break; 2384e71b7053SJung-uk Kim 2385e71b7053SJung-uk Kim switch (SSL_get_error(con, 0)) { 2386e71b7053SJung-uk Kim case SSL_ERROR_WANT_WRITE: 2387e71b7053SJung-uk Kim case SSL_ERROR_WANT_ASYNC: 2388e71b7053SJung-uk Kim case SSL_ERROR_WANT_READ: 2389e71b7053SJung-uk Kim /* Just keep trying - busy waiting */ 2390e71b7053SJung-uk Kim continue; 2391e71b7053SJung-uk Kim default: 2392e71b7053SJung-uk Kim BIO_printf(bio_err, "Error reading early data\n"); 2393e71b7053SJung-uk Kim ERR_print_errors(bio_err); 2394e71b7053SJung-uk Kim goto err; 2395e71b7053SJung-uk Kim } 2396e71b7053SJung-uk Kim } 2397e71b7053SJung-uk Kim if (readbytes > 0) { 2398e71b7053SJung-uk Kim if (write_header) { 2399e71b7053SJung-uk Kim BIO_printf(bio_s_out, "Early data received:\n"); 2400e71b7053SJung-uk Kim write_header = 0; 2401e71b7053SJung-uk Kim } 2402e71b7053SJung-uk Kim raw_write_stdout(buf, (unsigned int)readbytes); 2403e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 2404e71b7053SJung-uk Kim } 2405e71b7053SJung-uk Kim } 2406e71b7053SJung-uk Kim if (write_header) { 2407e71b7053SJung-uk Kim if (SSL_get_early_data_status(con) == SSL_EARLY_DATA_NOT_SENT) 2408e71b7053SJung-uk Kim BIO_printf(bio_s_out, "No early data received\n"); 2409e71b7053SJung-uk Kim else 2410e71b7053SJung-uk Kim BIO_printf(bio_s_out, "Early data was rejected\n"); 2411e71b7053SJung-uk Kim } else { 2412e71b7053SJung-uk Kim BIO_printf(bio_s_out, "\nEnd of early data\n"); 2413e71b7053SJung-uk Kim } 2414e71b7053SJung-uk Kim if (SSL_is_init_finished(con)) 2415e71b7053SJung-uk Kim print_connection_info(con); 2416e71b7053SJung-uk Kim } 241774664626SKris Kennaway 2418aeb5019cSJung-uk Kim if (fileno_stdin() > s) 2419aeb5019cSJung-uk Kim width = fileno_stdin() + 1; 2420aeb5019cSJung-uk Kim else 242174664626SKris Kennaway width = s + 1; 24226f9291ceSJung-uk Kim for (;;) { 2423f579bf8eSKris Kennaway int read_from_terminal; 2424f579bf8eSKris Kennaway int read_from_sslcon; 2425f579bf8eSKris Kennaway 2426f579bf8eSKris Kennaway read_from_terminal = 0; 2427e71b7053SJung-uk Kim read_from_sslcon = SSL_has_pending(con) 2428e71b7053SJung-uk Kim || (async && SSL_waiting_for_async(con)); 2429f579bf8eSKris Kennaway 24306f9291ceSJung-uk Kim if (!read_from_sslcon) { 243174664626SKris Kennaway FD_ZERO(&readfds); 2432e71b7053SJung-uk Kim #if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) 2433aeb5019cSJung-uk Kim openssl_fdset(fileno_stdin(), &readfds); 243474664626SKris Kennaway #endif 24351f13597dSJung-uk Kim openssl_fdset(s, &readfds); 24366f9291ceSJung-uk Kim /* 24376f9291ceSJung-uk Kim * Note: under VMS with SOCKETSHR the second parameter is 24386f9291ceSJung-uk Kim * currently of type (int *) whereas under other systems it is 24396f9291ceSJung-uk Kim * (void *) if you don't have a cast it will choke the compiler: 24406f9291ceSJung-uk Kim * if you do have a cast then you can either go for (int *) or 24416f9291ceSJung-uk Kim * (void *). 244274664626SKris Kennaway */ 2443e71b7053SJung-uk Kim #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) 24446f9291ceSJung-uk Kim /* 24456f9291ceSJung-uk Kim * Under DOS (non-djgpp) and Windows we can't select on stdin: 24466f9291ceSJung-uk Kim * only on sockets. As a workaround we timeout the select every 2447f579bf8eSKris Kennaway * second and check for any keypress. In a proper Windows 2448f579bf8eSKris Kennaway * application we wouldn't do this because it is inefficient. 2449f579bf8eSKris Kennaway */ 2450e71b7053SJung-uk Kim timeout.tv_sec = 1; 2451e71b7053SJung-uk Kim timeout.tv_usec = 0; 2452e71b7053SJung-uk Kim i = select(width, (void *)&readfds, NULL, NULL, &timeout); 2453e71b7053SJung-uk Kim if (has_stdin_waiting()) 2454f579bf8eSKris Kennaway read_from_terminal = 1; 2455e71b7053SJung-uk Kim if ((i < 0) || (!i && !read_from_terminal)) 24561f13597dSJung-uk Kim continue; 2457f579bf8eSKris Kennaway #else 2458e71b7053SJung-uk Kim if (SSL_is_dtls(con) && DTLSv1_get_timeout(con, &timeout)) 24596a599222SSimon L. B. Nielsen timeoutp = &timeout; 24606a599222SSimon L. B. Nielsen else 24616a599222SSimon L. B. Nielsen timeoutp = NULL; 24626a599222SSimon L. B. Nielsen 24636a599222SSimon L. B. Nielsen i = select(width, (void *)&readfds, NULL, NULL, timeoutp); 24646a599222SSimon L. B. Nielsen 2465e71b7053SJung-uk Kim if ((SSL_is_dtls(con)) && DTLSv1_handle_timeout(con) > 0) 2466e71b7053SJung-uk Kim BIO_printf(bio_err, "TIMEOUT occurred\n"); 24676a599222SSimon L. B. Nielsen 24686f9291ceSJung-uk Kim if (i <= 0) 24696f9291ceSJung-uk Kim continue; 2470aeb5019cSJung-uk Kim if (FD_ISSET(fileno_stdin(), &readfds)) 2471f579bf8eSKris Kennaway read_from_terminal = 1; 2472f579bf8eSKris Kennaway #endif 2473f579bf8eSKris Kennaway if (FD_ISSET(s, &readfds)) 2474f579bf8eSKris Kennaway read_from_sslcon = 1; 2475f579bf8eSKris Kennaway } 24766f9291ceSJung-uk Kim if (read_from_terminal) { 24776f9291ceSJung-uk Kim if (s_crlf) { 247874664626SKris Kennaway int j, lf_num; 247974664626SKris Kennaway 24801f13597dSJung-uk Kim i = raw_read_stdin(buf, bufsize / 2); 248174664626SKris Kennaway lf_num = 0; 248274664626SKris Kennaway /* both loops are skipped when i <= 0 */ 248374664626SKris Kennaway for (j = 0; j < i; j++) 248474664626SKris Kennaway if (buf[j] == '\n') 248574664626SKris Kennaway lf_num++; 24866f9291ceSJung-uk Kim for (j = i - 1; j >= 0; j--) { 248774664626SKris Kennaway buf[j + lf_num] = buf[j]; 24886f9291ceSJung-uk Kim if (buf[j] == '\n') { 248974664626SKris Kennaway lf_num--; 249074664626SKris Kennaway i++; 249174664626SKris Kennaway buf[j + lf_num] = '\r'; 249274664626SKris Kennaway } 249374664626SKris Kennaway } 249474664626SKris Kennaway assert(lf_num == 0); 2495e71b7053SJung-uk Kim } else { 24961f13597dSJung-uk Kim i = raw_read_stdin(buf, bufsize); 2497e71b7053SJung-uk Kim } 2498aeb5019cSJung-uk Kim 24997bded2dbSJung-uk Kim if (!s_quiet && !s_brief) { 25006f9291ceSJung-uk Kim if ((i <= 0) || (buf[0] == 'Q')) { 250174664626SKris Kennaway BIO_printf(bio_s_out, "DONE\n"); 2502e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 2503e71b7053SJung-uk Kim BIO_closesocket(s); 250474664626SKris Kennaway close_accept_socket(); 250574664626SKris Kennaway ret = -11; 250674664626SKris Kennaway goto err; 250774664626SKris Kennaway } 25086f9291ceSJung-uk Kim if ((i <= 0) || (buf[0] == 'q')) { 250974664626SKris Kennaway BIO_printf(bio_s_out, "DONE\n"); 2510e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 25113b4e3dcbSSimon L. B. Nielsen if (SSL_version(con) != DTLS1_VERSION) 2512e71b7053SJung-uk Kim BIO_closesocket(s); 25136f9291ceSJung-uk Kim /* 25146f9291ceSJung-uk Kim * close_accept_socket(); ret= -11; 25156f9291ceSJung-uk Kim */ 251674664626SKris Kennaway goto err; 251774664626SKris Kennaway } 25181f13597dSJung-uk Kim #ifndef OPENSSL_NO_HEARTBEATS 25196f9291ceSJung-uk Kim if ((buf[0] == 'B') && ((buf[1] == '\n') || (buf[1] == '\r'))) { 25201f13597dSJung-uk Kim BIO_printf(bio_err, "HEARTBEATING\n"); 25211f13597dSJung-uk Kim SSL_heartbeat(con); 25221f13597dSJung-uk Kim i = 0; 25231f13597dSJung-uk Kim continue; 25241f13597dSJung-uk Kim } 25251f13597dSJung-uk Kim #endif 25266f9291ceSJung-uk Kim if ((buf[0] == 'r') && ((buf[1] == '\n') || (buf[1] == '\r'))) { 252774664626SKris Kennaway SSL_renegotiate(con); 252874664626SKris Kennaway i = SSL_do_handshake(con); 252974664626SKris Kennaway printf("SSL_do_handshake -> %d\n", i); 253074664626SKris Kennaway i = 0; /* 13; */ 253174664626SKris Kennaway continue; 253274664626SKris Kennaway } 25336f9291ceSJung-uk Kim if ((buf[0] == 'R') && ((buf[1] == '\n') || (buf[1] == '\r'))) { 253474664626SKris Kennaway SSL_set_verify(con, 25356f9291ceSJung-uk Kim SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, 25366f9291ceSJung-uk Kim NULL); 253774664626SKris Kennaway SSL_renegotiate(con); 253874664626SKris Kennaway i = SSL_do_handshake(con); 253974664626SKris Kennaway printf("SSL_do_handshake -> %d\n", i); 254074664626SKris Kennaway i = 0; /* 13; */ 254174664626SKris Kennaway continue; 2542e71b7053SJung-uk Kim } 2543e71b7053SJung-uk Kim if ((buf[0] == 'K' || buf[0] == 'k') 2544e71b7053SJung-uk Kim && ((buf[1] == '\n') || (buf[1] == '\r'))) { 2545e71b7053SJung-uk Kim SSL_key_update(con, buf[0] == 'K' ? 2546e71b7053SJung-uk Kim SSL_KEY_UPDATE_REQUESTED 2547e71b7053SJung-uk Kim : SSL_KEY_UPDATE_NOT_REQUESTED); 2548e71b7053SJung-uk Kim i = SSL_do_handshake(con); 2549e71b7053SJung-uk Kim printf("SSL_do_handshake -> %d\n", i); 2550e71b7053SJung-uk Kim i = 0; 2551e71b7053SJung-uk Kim continue; 2552e71b7053SJung-uk Kim } 2553e71b7053SJung-uk Kim if (buf[0] == 'c' && ((buf[1] == '\n') || (buf[1] == '\r'))) { 2554e71b7053SJung-uk Kim SSL_set_verify(con, SSL_VERIFY_PEER, NULL); 2555e71b7053SJung-uk Kim i = SSL_verify_client_post_handshake(con); 2556e71b7053SJung-uk Kim if (i == 0) { 2557e71b7053SJung-uk Kim printf("Failed to initiate request\n"); 2558e71b7053SJung-uk Kim ERR_print_errors(bio_err); 2559e71b7053SJung-uk Kim } else { 2560e71b7053SJung-uk Kim i = SSL_do_handshake(con); 2561e71b7053SJung-uk Kim printf("SSL_do_handshake -> %d\n", i); 2562e71b7053SJung-uk Kim i = 0; 2563e71b7053SJung-uk Kim } 2564e71b7053SJung-uk Kim continue; 256574664626SKris Kennaway } 25666f9291ceSJung-uk Kim if (buf[0] == 'P') { 25673b4e3dcbSSimon L. B. Nielsen static const char *str = "Lets print some clear text\n"; 256874664626SKris Kennaway BIO_write(SSL_get_wbio(con), str, strlen(str)); 256974664626SKris Kennaway } 25706f9291ceSJung-uk Kim if (buf[0] == 'S') { 257174664626SKris Kennaway print_stats(bio_s_out, SSL_get_SSL_CTX(con)); 257274664626SKris Kennaway } 257374664626SKris Kennaway } 257474664626SKris Kennaway #ifdef CHARSET_EBCDIC 257574664626SKris Kennaway ebcdic2ascii(buf, buf, i); 257674664626SKris Kennaway #endif 257774664626SKris Kennaway l = k = 0; 25786f9291ceSJung-uk Kim for (;;) { 257974664626SKris Kennaway /* should do a select for the write */ 258074664626SKris Kennaway #ifdef RENEG 25816f9291ceSJung-uk Kim static count = 0; 25826f9291ceSJung-uk Kim if (++count == 100) { 25836f9291ceSJung-uk Kim count = 0; 25846f9291ceSJung-uk Kim SSL_renegotiate(con); 25856f9291ceSJung-uk Kim } 258674664626SKris Kennaway #endif 258774664626SKris Kennaway k = SSL_write(con, &(buf[l]), (unsigned int)i); 25881f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP 25896f9291ceSJung-uk Kim while (SSL_get_error(con, k) == SSL_ERROR_WANT_X509_LOOKUP) { 25901f13597dSJung-uk Kim BIO_printf(bio_s_out, "LOOKUP renego during write\n"); 25914c6a0400SJung-uk Kim SRP_user_pwd_free(srp_callback_parm.user); 25926f9291ceSJung-uk Kim srp_callback_parm.user = 25934c6a0400SJung-uk Kim SRP_VBASE_get1_by_user(srp_callback_parm.vb, 25946f9291ceSJung-uk Kim srp_callback_parm.login); 25951f13597dSJung-uk Kim if (srp_callback_parm.user) 25966f9291ceSJung-uk Kim BIO_printf(bio_s_out, "LOOKUP done %s\n", 25976f9291ceSJung-uk Kim srp_callback_parm.user->info); 25981f13597dSJung-uk Kim else 25991f13597dSJung-uk Kim BIO_printf(bio_s_out, "LOOKUP not successful\n"); 26001f13597dSJung-uk Kim k = SSL_write(con, &(buf[l]), (unsigned int)i); 26011f13597dSJung-uk Kim } 26021f13597dSJung-uk Kim #endif 26036f9291ceSJung-uk Kim switch (SSL_get_error(con, k)) { 260474664626SKris Kennaway case SSL_ERROR_NONE: 260574664626SKris Kennaway break; 2606e71b7053SJung-uk Kim case SSL_ERROR_WANT_ASYNC: 2607e71b7053SJung-uk Kim BIO_printf(bio_s_out, "Write BLOCK (Async)\n"); 2608e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 2609e71b7053SJung-uk Kim wait_for_async(con); 2610e71b7053SJung-uk Kim break; 261174664626SKris Kennaway case SSL_ERROR_WANT_WRITE: 261274664626SKris Kennaway case SSL_ERROR_WANT_READ: 261374664626SKris Kennaway case SSL_ERROR_WANT_X509_LOOKUP: 261474664626SKris Kennaway BIO_printf(bio_s_out, "Write BLOCK\n"); 2615e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 261674664626SKris Kennaway break; 2617e71b7053SJung-uk Kim case SSL_ERROR_WANT_ASYNC_JOB: 2618e71b7053SJung-uk Kim /* 2619e71b7053SJung-uk Kim * This shouldn't ever happen in s_server. Treat as an error 2620e71b7053SJung-uk Kim */ 262174664626SKris Kennaway case SSL_ERROR_SYSCALL: 262274664626SKris Kennaway case SSL_ERROR_SSL: 262374664626SKris Kennaway BIO_printf(bio_s_out, "ERROR\n"); 2624e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 262574664626SKris Kennaway ERR_print_errors(bio_err); 262674664626SKris Kennaway ret = 1; 262774664626SKris Kennaway goto err; 262874664626SKris Kennaway /* break; */ 262974664626SKris Kennaway case SSL_ERROR_ZERO_RETURN: 263074664626SKris Kennaway BIO_printf(bio_s_out, "DONE\n"); 2631e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 263274664626SKris Kennaway ret = 1; 263374664626SKris Kennaway goto err; 263474664626SKris Kennaway } 2635ed6b93beSJung-uk Kim if (k > 0) { 263674664626SKris Kennaway l += k; 263774664626SKris Kennaway i -= k; 2638ed6b93beSJung-uk Kim } 26396f9291ceSJung-uk Kim if (i <= 0) 26406f9291ceSJung-uk Kim break; 264174664626SKris Kennaway } 264274664626SKris Kennaway } 26436f9291ceSJung-uk Kim if (read_from_sslcon) { 2644e71b7053SJung-uk Kim /* 2645e71b7053SJung-uk Kim * init_ssl_connection handles all async events itself so if we're 2646e71b7053SJung-uk Kim * waiting for async then we shouldn't go back into 2647e71b7053SJung-uk Kim * init_ssl_connection 2648e71b7053SJung-uk Kim */ 2649e71b7053SJung-uk Kim if ((!async || !SSL_waiting_for_async(con)) 2650e71b7053SJung-uk Kim && !SSL_is_init_finished(con)) { 265174664626SKris Kennaway i = init_ssl_connection(con); 265274664626SKris Kennaway 26536f9291ceSJung-uk Kim if (i < 0) { 265474664626SKris Kennaway ret = 0; 265574664626SKris Kennaway goto err; 26566f9291ceSJung-uk Kim } else if (i == 0) { 265774664626SKris Kennaway ret = 1; 265874664626SKris Kennaway goto err; 265974664626SKris Kennaway } 26606f9291ceSJung-uk Kim } else { 266174664626SKris Kennaway again: 266274664626SKris Kennaway i = SSL_read(con, (char *)buf, bufsize); 26631f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP 26646f9291ceSJung-uk Kim while (SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) { 26651f13597dSJung-uk Kim BIO_printf(bio_s_out, "LOOKUP renego during read\n"); 26664c6a0400SJung-uk Kim SRP_user_pwd_free(srp_callback_parm.user); 26676f9291ceSJung-uk Kim srp_callback_parm.user = 26684c6a0400SJung-uk Kim SRP_VBASE_get1_by_user(srp_callback_parm.vb, 26696f9291ceSJung-uk Kim srp_callback_parm.login); 26701f13597dSJung-uk Kim if (srp_callback_parm.user) 26716f9291ceSJung-uk Kim BIO_printf(bio_s_out, "LOOKUP done %s\n", 26726f9291ceSJung-uk Kim srp_callback_parm.user->info); 26731f13597dSJung-uk Kim else 26741f13597dSJung-uk Kim BIO_printf(bio_s_out, "LOOKUP not successful\n"); 26751f13597dSJung-uk Kim i = SSL_read(con, (char *)buf, bufsize); 26761f13597dSJung-uk Kim } 26771f13597dSJung-uk Kim #endif 26786f9291ceSJung-uk Kim switch (SSL_get_error(con, i)) { 267974664626SKris Kennaway case SSL_ERROR_NONE: 268074664626SKris Kennaway #ifdef CHARSET_EBCDIC 268174664626SKris Kennaway ascii2ebcdic(buf, buf, i); 268274664626SKris Kennaway #endif 26836f9291ceSJung-uk Kim raw_write_stdout(buf, (unsigned int)i); 2684e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 2685e71b7053SJung-uk Kim if (SSL_has_pending(con)) 26866f9291ceSJung-uk Kim goto again; 268774664626SKris Kennaway break; 2688e71b7053SJung-uk Kim case SSL_ERROR_WANT_ASYNC: 2689e71b7053SJung-uk Kim BIO_printf(bio_s_out, "Read BLOCK (Async)\n"); 2690e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 2691e71b7053SJung-uk Kim wait_for_async(con); 2692e71b7053SJung-uk Kim break; 269374664626SKris Kennaway case SSL_ERROR_WANT_WRITE: 269474664626SKris Kennaway case SSL_ERROR_WANT_READ: 269574664626SKris Kennaway BIO_printf(bio_s_out, "Read BLOCK\n"); 2696e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 269774664626SKris Kennaway break; 2698e71b7053SJung-uk Kim case SSL_ERROR_WANT_ASYNC_JOB: 2699e71b7053SJung-uk Kim /* 2700e71b7053SJung-uk Kim * This shouldn't ever happen in s_server. Treat as an error 2701e71b7053SJung-uk Kim */ 270274664626SKris Kennaway case SSL_ERROR_SYSCALL: 270374664626SKris Kennaway case SSL_ERROR_SSL: 270474664626SKris Kennaway BIO_printf(bio_s_out, "ERROR\n"); 2705e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 270674664626SKris Kennaway ERR_print_errors(bio_err); 270774664626SKris Kennaway ret = 1; 270874664626SKris Kennaway goto err; 270974664626SKris Kennaway case SSL_ERROR_ZERO_RETURN: 271074664626SKris Kennaway BIO_printf(bio_s_out, "DONE\n"); 2711e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 271274664626SKris Kennaway ret = 1; 271374664626SKris Kennaway goto err; 271474664626SKris Kennaway } 271574664626SKris Kennaway } 271674664626SKris Kennaway } 271774664626SKris Kennaway } 271874664626SKris Kennaway err: 27196f9291ceSJung-uk Kim if (con != NULL) { 272074664626SKris Kennaway BIO_printf(bio_s_out, "shutting down SSL\n"); 272174664626SKris Kennaway SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); 27221f13597dSJung-uk Kim SSL_free(con); 27231f13597dSJung-uk Kim } 272474664626SKris Kennaway BIO_printf(bio_s_out, "CONNECTION CLOSED\n"); 2725e71b7053SJung-uk Kim OPENSSL_clear_free(buf, bufsize); 2726e71b7053SJung-uk Kim return ret; 272774664626SKris Kennaway } 272874664626SKris Kennaway 272974664626SKris Kennaway static void close_accept_socket(void) 273074664626SKris Kennaway { 273174664626SKris Kennaway BIO_printf(bio_err, "shutdown accept socket\n"); 27326f9291ceSJung-uk Kim if (accept_socket >= 0) { 2733e71b7053SJung-uk Kim BIO_closesocket(accept_socket); 273474664626SKris Kennaway } 273574664626SKris Kennaway } 273674664626SKris Kennaway 2737e71b7053SJung-uk Kim static int is_retryable(SSL *con, int i) 2738e71b7053SJung-uk Kim { 2739e71b7053SJung-uk Kim int err = SSL_get_error(con, i); 2740e71b7053SJung-uk Kim 2741e71b7053SJung-uk Kim /* If it's not a fatal error, it must be retryable */ 2742e71b7053SJung-uk Kim return (err != SSL_ERROR_SSL) 2743e71b7053SJung-uk Kim && (err != SSL_ERROR_SYSCALL) 2744e71b7053SJung-uk Kim && (err != SSL_ERROR_ZERO_RETURN); 2745e71b7053SJung-uk Kim } 2746e71b7053SJung-uk Kim 274774664626SKris Kennaway static int init_ssl_connection(SSL *con) 274874664626SKris Kennaway { 274974664626SKris Kennaway int i; 2750e71b7053SJung-uk Kim long verify_err; 2751e71b7053SJung-uk Kim int retry = 0; 275274664626SKris Kennaway 2753e71b7053SJung-uk Kim if (dtlslisten || stateless) { 2754e71b7053SJung-uk Kim BIO_ADDR *client = NULL; 2755e71b7053SJung-uk Kim 2756e71b7053SJung-uk Kim if (dtlslisten) { 2757e71b7053SJung-uk Kim if ((client = BIO_ADDR_new()) == NULL) { 2758e71b7053SJung-uk Kim BIO_printf(bio_err, "ERROR - memory\n"); 2759e71b7053SJung-uk Kim return 0; 2760e71b7053SJung-uk Kim } 2761e71b7053SJung-uk Kim i = DTLSv1_listen(con, client); 2762e71b7053SJung-uk Kim } else { 2763e71b7053SJung-uk Kim i = SSL_stateless(con); 2764e71b7053SJung-uk Kim } 2765e71b7053SJung-uk Kim if (i > 0) { 2766e71b7053SJung-uk Kim BIO *wbio; 2767e71b7053SJung-uk Kim int fd = -1; 2768e71b7053SJung-uk Kim 2769e71b7053SJung-uk Kim if (dtlslisten) { 2770e71b7053SJung-uk Kim wbio = SSL_get_wbio(con); 2771e71b7053SJung-uk Kim if (wbio) { 2772e71b7053SJung-uk Kim BIO_get_fd(wbio, &fd); 2773e71b7053SJung-uk Kim } 2774e71b7053SJung-uk Kim 2775e71b7053SJung-uk Kim if (!wbio || BIO_connect(fd, client, 0) == 0) { 2776e71b7053SJung-uk Kim BIO_printf(bio_err, "ERROR - unable to connect\n"); 2777e71b7053SJung-uk Kim BIO_ADDR_free(client); 2778e71b7053SJung-uk Kim return 0; 2779e71b7053SJung-uk Kim } 27806935a639SJung-uk Kim 27816935a639SJung-uk Kim (void)BIO_ctrl_set_connected(wbio, client); 2782e71b7053SJung-uk Kim BIO_ADDR_free(client); 2783e71b7053SJung-uk Kim dtlslisten = 0; 2784e71b7053SJung-uk Kim } else { 2785e71b7053SJung-uk Kim stateless = 0; 2786e71b7053SJung-uk Kim } 27871f13597dSJung-uk Kim i = SSL_accept(con); 2788e71b7053SJung-uk Kim } else { 2789e71b7053SJung-uk Kim BIO_ADDR_free(client); 2790e71b7053SJung-uk Kim } 2791e71b7053SJung-uk Kim } else { 2792e71b7053SJung-uk Kim do { 2793e71b7053SJung-uk Kim i = SSL_accept(con); 2794e71b7053SJung-uk Kim 2795e71b7053SJung-uk Kim if (i <= 0) 2796e71b7053SJung-uk Kim retry = is_retryable(con, i); 27977bded2dbSJung-uk Kim #ifdef CERT_CB_TEST_RETRY 27987bded2dbSJung-uk Kim { 2799e71b7053SJung-uk Kim while (i <= 0 2800e71b7053SJung-uk Kim && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP 2801e71b7053SJung-uk Kim && SSL_get_state(con) == TLS_ST_SR_CLNT_HELLO) { 2802e71b7053SJung-uk Kim BIO_printf(bio_err, 28037bded2dbSJung-uk Kim "LOOKUP from certificate callback during accept\n"); 28047bded2dbSJung-uk Kim i = SSL_accept(con); 2805e71b7053SJung-uk Kim if (i <= 0) 2806e71b7053SJung-uk Kim retry = is_retryable(con, i); 28077bded2dbSJung-uk Kim } 28087bded2dbSJung-uk Kim } 28097bded2dbSJung-uk Kim #endif 2810e71b7053SJung-uk Kim 28111f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP 2812e71b7053SJung-uk Kim while (i <= 0 2813e71b7053SJung-uk Kim && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) { 28146f9291ceSJung-uk Kim BIO_printf(bio_s_out, "LOOKUP during accept %s\n", 28156f9291ceSJung-uk Kim srp_callback_parm.login); 28164c6a0400SJung-uk Kim SRP_user_pwd_free(srp_callback_parm.user); 28176f9291ceSJung-uk Kim srp_callback_parm.user = 28184c6a0400SJung-uk Kim SRP_VBASE_get1_by_user(srp_callback_parm.vb, 28196f9291ceSJung-uk Kim srp_callback_parm.login); 28201f13597dSJung-uk Kim if (srp_callback_parm.user) 28216f9291ceSJung-uk Kim BIO_printf(bio_s_out, "LOOKUP done %s\n", 28226f9291ceSJung-uk Kim srp_callback_parm.user->info); 28231f13597dSJung-uk Kim else 28241f13597dSJung-uk Kim BIO_printf(bio_s_out, "LOOKUP not successful\n"); 28251f13597dSJung-uk Kim i = SSL_accept(con); 2826e71b7053SJung-uk Kim if (i <= 0) 2827e71b7053SJung-uk Kim retry = is_retryable(con, i); 28281f13597dSJung-uk Kim } 28291f13597dSJung-uk Kim #endif 2830e71b7053SJung-uk Kim } while (i < 0 && SSL_waiting_for_async(con)); 2831e71b7053SJung-uk Kim } 28327bded2dbSJung-uk Kim 28336f9291ceSJung-uk Kim if (i <= 0) { 2834e71b7053SJung-uk Kim if (((dtlslisten || stateless) && i == 0) 2835e71b7053SJung-uk Kim || (!dtlslisten && !stateless && retry)) { 283674664626SKris Kennaway BIO_printf(bio_s_out, "DELAY\n"); 2837e71b7053SJung-uk Kim return 1; 283874664626SKris Kennaway } 283974664626SKris Kennaway 284074664626SKris Kennaway BIO_printf(bio_err, "ERROR\n"); 2841e71b7053SJung-uk Kim 2842e71b7053SJung-uk Kim verify_err = SSL_get_verify_result(con); 2843e71b7053SJung-uk Kim if (verify_err != X509_V_OK) { 284474664626SKris Kennaway BIO_printf(bio_err, "verify error:%s\n", 2845e71b7053SJung-uk Kim X509_verify_cert_error_string(verify_err)); 28467bded2dbSJung-uk Kim } 28477bded2dbSJung-uk Kim /* Always print any error messages */ 284874664626SKris Kennaway ERR_print_errors(bio_err); 2849e71b7053SJung-uk Kim return 0; 285074664626SKris Kennaway } 285174664626SKris Kennaway 2852e71b7053SJung-uk Kim print_connection_info(con); 2853e71b7053SJung-uk Kim return 1; 2854e71b7053SJung-uk Kim } 2855e71b7053SJung-uk Kim 2856e71b7053SJung-uk Kim static void print_connection_info(SSL *con) 2857e71b7053SJung-uk Kim { 2858e71b7053SJung-uk Kim const char *str; 2859e71b7053SJung-uk Kim X509 *peer; 2860e71b7053SJung-uk Kim char buf[BUFSIZ]; 2861e71b7053SJung-uk Kim #if !defined(OPENSSL_NO_NEXTPROTONEG) 2862e71b7053SJung-uk Kim const unsigned char *next_proto_neg; 2863e71b7053SJung-uk Kim unsigned next_proto_neg_len; 2864e71b7053SJung-uk Kim #endif 2865e71b7053SJung-uk Kim unsigned char *exportedkeymat; 2866e71b7053SJung-uk Kim int i; 2867e71b7053SJung-uk Kim 28687bded2dbSJung-uk Kim if (s_brief) 2869e71b7053SJung-uk Kim print_ssl_summary(con); 28707bded2dbSJung-uk Kim 287174664626SKris Kennaway PEM_write_bio_SSL_SESSION(bio_s_out, SSL_get_session(con)); 287274664626SKris Kennaway 287374664626SKris Kennaway peer = SSL_get_peer_certificate(con); 28746f9291ceSJung-uk Kim if (peer != NULL) { 287574664626SKris Kennaway BIO_printf(bio_s_out, "Client certificate\n"); 287674664626SKris Kennaway PEM_write_bio_X509(bio_s_out, peer); 2877e71b7053SJung-uk Kim dump_cert_text(bio_s_out, peer); 287874664626SKris Kennaway X509_free(peer); 2879e71b7053SJung-uk Kim peer = NULL; 288074664626SKris Kennaway } 288174664626SKris Kennaway 2882dee36b4fSJung-uk Kim if (SSL_get_shared_ciphers(con, buf, sizeof(buf)) != NULL) 288374664626SKris Kennaway BIO_printf(bio_s_out, "Shared ciphers:%s\n", buf); 288474664626SKris Kennaway str = SSL_CIPHER_get_name(SSL_get_current_cipher(con)); 28857bded2dbSJung-uk Kim ssl_print_sigalgs(bio_s_out, con); 28867bded2dbSJung-uk Kim #ifndef OPENSSL_NO_EC 28877bded2dbSJung-uk Kim ssl_print_point_formats(bio_s_out, con); 2888e71b7053SJung-uk Kim ssl_print_groups(bio_s_out, con, 0); 28897bded2dbSJung-uk Kim #endif 2890e71b7053SJung-uk Kim print_ca_names(bio_s_out, con); 289174664626SKris Kennaway BIO_printf(bio_s_out, "CIPHER is %s\n", (str != NULL) ? str : "(NONE)"); 289209286989SJung-uk Kim 2893e71b7053SJung-uk Kim #if !defined(OPENSSL_NO_NEXTPROTONEG) 28941f13597dSJung-uk Kim SSL_get0_next_proto_negotiated(con, &next_proto_neg, &next_proto_neg_len); 28956f9291ceSJung-uk Kim if (next_proto_neg) { 28961f13597dSJung-uk Kim BIO_printf(bio_s_out, "NEXTPROTO is "); 28971f13597dSJung-uk Kim BIO_write(bio_s_out, next_proto_neg, next_proto_neg_len); 28981f13597dSJung-uk Kim BIO_printf(bio_s_out, "\n"); 28991f13597dSJung-uk Kim } 29001f13597dSJung-uk Kim #endif 290109286989SJung-uk Kim #ifndef OPENSSL_NO_SRTP 29021f13597dSJung-uk Kim { 29031f13597dSJung-uk Kim SRTP_PROTECTION_PROFILE *srtp_profile 29041f13597dSJung-uk Kim = SSL_get_selected_srtp_profile(con); 29051f13597dSJung-uk Kim 29061f13597dSJung-uk Kim if (srtp_profile) 29071f13597dSJung-uk Kim BIO_printf(bio_s_out, "SRTP Extension negotiated, profile=%s\n", 29081f13597dSJung-uk Kim srtp_profile->name); 29091f13597dSJung-uk Kim } 291009286989SJung-uk Kim #endif 2911e71b7053SJung-uk Kim if (SSL_session_reused(con)) 29126f9291ceSJung-uk Kim BIO_printf(bio_s_out, "Reused session-id\n"); 29136a599222SSimon L. B. Nielsen BIO_printf(bio_s_out, "Secure Renegotiation IS%s supported\n", 29146a599222SSimon L. B. Nielsen SSL_get_secure_renegotiation_support(con) ? "" : " NOT"); 2915e71b7053SJung-uk Kim if ((SSL_get_options(con) & SSL_OP_NO_RENEGOTIATION)) 2916e71b7053SJung-uk Kim BIO_printf(bio_s_out, "Renegotiation is DISABLED\n"); 2917e71b7053SJung-uk Kim 29186f9291ceSJung-uk Kim if (keymatexportlabel != NULL) { 29191f13597dSJung-uk Kim BIO_printf(bio_s_out, "Keying material exporter:\n"); 29201f13597dSJung-uk Kim BIO_printf(bio_s_out, " Label: '%s'\n", keymatexportlabel); 29216f9291ceSJung-uk Kim BIO_printf(bio_s_out, " Length: %i bytes\n", keymatexportlen); 2922e71b7053SJung-uk Kim exportedkeymat = app_malloc(keymatexportlen, "export key"); 29231f13597dSJung-uk Kim if (!SSL_export_keying_material(con, exportedkeymat, 29241f13597dSJung-uk Kim keymatexportlen, 29251f13597dSJung-uk Kim keymatexportlabel, 29261f13597dSJung-uk Kim strlen(keymatexportlabel), 29276f9291ceSJung-uk Kim NULL, 0, 0)) { 29281f13597dSJung-uk Kim BIO_printf(bio_s_out, " Error\n"); 29296f9291ceSJung-uk Kim } else { 29301f13597dSJung-uk Kim BIO_printf(bio_s_out, " Keying material: "); 29311f13597dSJung-uk Kim for (i = 0; i < keymatexportlen; i++) 29326f9291ceSJung-uk Kim BIO_printf(bio_s_out, "%02X", exportedkeymat[i]); 29331f13597dSJung-uk Kim BIO_printf(bio_s_out, "\n"); 29341f13597dSJung-uk Kim } 29351f13597dSJung-uk Kim OPENSSL_free(exportedkeymat); 29361f13597dSJung-uk Kim } 2937aa906e2aSJohn Baldwin #ifndef OPENSSL_NO_KTLS 2938aa906e2aSJohn Baldwin if (BIO_get_ktls_send(SSL_get_wbio(con))) 2939aa906e2aSJohn Baldwin BIO_printf(bio_err, "Using Kernel TLS for sending\n"); 2940aa906e2aSJohn Baldwin if (BIO_get_ktls_recv(SSL_get_rbio(con))) 2941aa906e2aSJohn Baldwin BIO_printf(bio_err, "Using Kernel TLS for receiving\n"); 2942aa906e2aSJohn Baldwin #endif 29431f13597dSJung-uk Kim 2944e71b7053SJung-uk Kim (void)BIO_flush(bio_s_out); 294574664626SKris Kennaway } 294674664626SKris Kennaway 29475c87c606SMark Murray #ifndef OPENSSL_NO_DH 29483b4e3dcbSSimon L. B. Nielsen static DH *load_dh_param(const char *dhfile) 294974664626SKris Kennaway { 295074664626SKris Kennaway DH *ret = NULL; 295174664626SKris Kennaway BIO *bio; 295274664626SKris Kennaway 2953f579bf8eSKris Kennaway if ((bio = BIO_new_file(dhfile, "r")) == NULL) 295474664626SKris Kennaway goto err; 295574664626SKris Kennaway ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); 295674664626SKris Kennaway err: 29576f9291ceSJung-uk Kim BIO_free(bio); 2958e71b7053SJung-uk Kim return ret; 295974664626SKris Kennaway } 296074664626SKris Kennaway #endif 296174664626SKris Kennaway 2962e71b7053SJung-uk Kim static int www_body(int s, int stype, int prot, unsigned char *context) 296374664626SKris Kennaway { 296474664626SKris Kennaway char *buf = NULL; 296574664626SKris Kennaway int ret = 1; 2966a3ddd25aSSimon L. B. Nielsen int i, j, k, dot; 296774664626SKris Kennaway SSL *con; 29681f13597dSJung-uk Kim const SSL_CIPHER *c; 296974664626SKris Kennaway BIO *io, *ssl_bio, *sbio; 2970e71b7053SJung-uk Kim #ifdef RENEG 2971e71b7053SJung-uk Kim int total_bytes = 0; 2972a3ddd25aSSimon L. B. Nielsen #endif 2973e71b7053SJung-uk Kim int width; 2974e71b7053SJung-uk Kim fd_set readfds; 297574664626SKris Kennaway 2976e71b7053SJung-uk Kim /* Set width for a select call if needed */ 2977e71b7053SJung-uk Kim width = s + 1; 2978e71b7053SJung-uk Kim 2979e71b7053SJung-uk Kim buf = app_malloc(bufsize, "server www buffer"); 298074664626SKris Kennaway io = BIO_new(BIO_f_buffer()); 298174664626SKris Kennaway ssl_bio = BIO_new(BIO_f_ssl()); 29826f9291ceSJung-uk Kim if ((io == NULL) || (ssl_bio == NULL)) 29836f9291ceSJung-uk Kim goto err; 298474664626SKris Kennaway 29856f9291ceSJung-uk Kim if (s_nbio) { 2986e71b7053SJung-uk Kim if (!BIO_socket_nbio(s, 1)) 298774664626SKris Kennaway ERR_print_errors(bio_err); 2988e71b7053SJung-uk Kim else if (!s_quiet) 2989e71b7053SJung-uk Kim BIO_printf(bio_err, "Turned on non blocking io\n"); 299074664626SKris Kennaway } 299174664626SKris Kennaway 299274664626SKris Kennaway /* lets make the output buffer a reasonable size */ 29936f9291ceSJung-uk Kim if (!BIO_set_write_buffer_size(io, bufsize)) 29946f9291ceSJung-uk Kim goto err; 299574664626SKris Kennaway 29966f9291ceSJung-uk Kim if ((con = SSL_new(ctx)) == NULL) 29976f9291ceSJung-uk Kim goto err; 2998e71b7053SJung-uk Kim 29996f9291ceSJung-uk Kim if (s_tlsextdebug) { 3000db522d3aSSimon L. B. Nielsen SSL_set_tlsext_debug_callback(con, tlsext_cb); 3001db522d3aSSimon L. B. Nielsen SSL_set_tlsext_debug_arg(con, bio_s_out); 3002db522d3aSSimon L. B. Nielsen } 3003e71b7053SJung-uk Kim 3004e71b7053SJung-uk Kim if (context != NULL 3005e71b7053SJung-uk Kim && !SSL_set_session_id_context(con, context, 3006e71b7053SJung-uk Kim strlen((char *)context))) { 3007e71b7053SJung-uk Kim SSL_free(con); 3008e71b7053SJung-uk Kim goto err; 30095c87c606SMark Murray } 301074664626SKris Kennaway 301174664626SKris Kennaway sbio = BIO_new_socket(s, BIO_NOCLOSE); 30126f9291ceSJung-uk Kim if (s_nbio_test) { 301374664626SKris Kennaway BIO *test; 301474664626SKris Kennaway 301574664626SKris Kennaway test = BIO_new(BIO_f_nbio_test()); 301674664626SKris Kennaway sbio = BIO_push(test, sbio); 301774664626SKris Kennaway } 301874664626SKris Kennaway SSL_set_bio(con, sbio, sbio); 301974664626SKris Kennaway SSL_set_accept_state(con); 302074664626SKris Kennaway 3021e71b7053SJung-uk Kim /* No need to free |con| after this. Done by BIO_free(ssl_bio) */ 302274664626SKris Kennaway BIO_set_ssl(ssl_bio, con, BIO_CLOSE); 302374664626SKris Kennaway BIO_push(io, ssl_bio); 302474664626SKris Kennaway #ifdef CHARSET_EBCDIC 302574664626SKris Kennaway io = BIO_push(BIO_new(BIO_f_ebcdic_filter()), io); 302674664626SKris Kennaway #endif 302774664626SKris Kennaway 30286f9291ceSJung-uk Kim if (s_debug) { 30293b4e3dcbSSimon L. B. Nielsen BIO_set_callback(SSL_get_rbio(con), bio_dump_callback); 30305471f83eSSimon L. B. Nielsen BIO_set_callback_arg(SSL_get_rbio(con), (char *)bio_s_out); 303174664626SKris Kennaway } 30326f9291ceSJung-uk Kim if (s_msg) { 30337bded2dbSJung-uk Kim #ifndef OPENSSL_NO_SSL_TRACE 30347bded2dbSJung-uk Kim if (s_msg == 2) 30357bded2dbSJung-uk Kim SSL_set_msg_callback(con, SSL_trace); 30367bded2dbSJung-uk Kim else 30377bded2dbSJung-uk Kim #endif 30385c87c606SMark Murray SSL_set_msg_callback(con, msg_cb); 30397bded2dbSJung-uk Kim SSL_set_msg_callback_arg(con, bio_s_msg ? bio_s_msg : bio_s_out); 30405c87c606SMark Murray } 304174664626SKris Kennaway 30426f9291ceSJung-uk Kim for (;;) { 304374664626SKris Kennaway i = BIO_gets(io, buf, bufsize - 1); 30446f9291ceSJung-uk Kim if (i < 0) { /* error */ 3045e71b7053SJung-uk Kim if (!BIO_should_retry(io) && !SSL_waiting_for_async(con)) { 304674664626SKris Kennaway if (!s_quiet) 304774664626SKris Kennaway ERR_print_errors(bio_err); 304874664626SKris Kennaway goto err; 30496f9291ceSJung-uk Kim } else { 305074664626SKris Kennaway BIO_printf(bio_s_out, "read R BLOCK\n"); 305180815a77SJung-uk Kim #ifndef OPENSSL_NO_SRP 305280815a77SJung-uk Kim if (BIO_should_io_special(io) 305380815a77SJung-uk Kim && BIO_get_retry_reason(io) == BIO_RR_SSL_X509_LOOKUP) { 305480815a77SJung-uk Kim BIO_printf(bio_s_out, "LOOKUP renego during read\n"); 30554c6a0400SJung-uk Kim SRP_user_pwd_free(srp_callback_parm.user); 305680815a77SJung-uk Kim srp_callback_parm.user = 30574c6a0400SJung-uk Kim SRP_VBASE_get1_by_user(srp_callback_parm.vb, 305880815a77SJung-uk Kim srp_callback_parm.login); 305980815a77SJung-uk Kim if (srp_callback_parm.user) 306080815a77SJung-uk Kim BIO_printf(bio_s_out, "LOOKUP done %s\n", 306180815a77SJung-uk Kim srp_callback_parm.user->info); 306280815a77SJung-uk Kim else 306380815a77SJung-uk Kim BIO_printf(bio_s_out, "LOOKUP not successful\n"); 306480815a77SJung-uk Kim continue; 306580815a77SJung-uk Kim } 306680815a77SJung-uk Kim #endif 3067e71b7053SJung-uk Kim #if !defined(OPENSSL_SYS_MSDOS) 306874664626SKris Kennaway sleep(1); 306974664626SKris Kennaway #endif 307074664626SKris Kennaway continue; 307174664626SKris Kennaway } 30726f9291ceSJung-uk Kim } else if (i == 0) { /* end of input */ 307374664626SKris Kennaway ret = 1; 307474664626SKris Kennaway goto end; 307574664626SKris Kennaway } 307674664626SKris Kennaway 307774664626SKris Kennaway /* else we have data */ 307874664626SKris Kennaway if (((www == 1) && (strncmp("GET ", buf, 4) == 0)) || 30796f9291ceSJung-uk Kim ((www == 2) && (strncmp("GET /stats ", buf, 11) == 0))) { 308074664626SKris Kennaway char *p; 3081e71b7053SJung-uk Kim X509 *peer = NULL; 308274664626SKris Kennaway STACK_OF(SSL_CIPHER) *sk; 30833b4e3dcbSSimon L. B. Nielsen static const char *space = " "; 308474664626SKris Kennaway 3085e71b7053SJung-uk Kim if (www == 1 && strncmp("GET /reneg", buf, 10) == 0) { 3086e71b7053SJung-uk Kim if (strncmp("GET /renegcert", buf, 14) == 0) 3087e71b7053SJung-uk Kim SSL_set_verify(con, 3088e71b7053SJung-uk Kim SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, 3089e71b7053SJung-uk Kim NULL); 3090e71b7053SJung-uk Kim i = SSL_renegotiate(con); 3091e71b7053SJung-uk Kim BIO_printf(bio_s_out, "SSL_renegotiate -> %d\n", i); 3092e71b7053SJung-uk Kim /* Send the HelloRequest */ 3093e71b7053SJung-uk Kim i = SSL_do_handshake(con); 3094e71b7053SJung-uk Kim if (i <= 0) { 3095e71b7053SJung-uk Kim BIO_printf(bio_s_out, "SSL_do_handshake() Retval %d\n", 3096e71b7053SJung-uk Kim SSL_get_error(con, i)); 3097e71b7053SJung-uk Kim ERR_print_errors(bio_err); 3098e71b7053SJung-uk Kim goto err; 3099e71b7053SJung-uk Kim } 3100e71b7053SJung-uk Kim /* Wait for a ClientHello to come back */ 3101e71b7053SJung-uk Kim FD_ZERO(&readfds); 3102e71b7053SJung-uk Kim openssl_fdset(s, &readfds); 3103e71b7053SJung-uk Kim i = select(width, (void *)&readfds, NULL, NULL, NULL); 3104e71b7053SJung-uk Kim if (i <= 0 || !FD_ISSET(s, &readfds)) { 3105e71b7053SJung-uk Kim BIO_printf(bio_s_out, 3106e71b7053SJung-uk Kim "Error waiting for client response\n"); 3107e71b7053SJung-uk Kim ERR_print_errors(bio_err); 3108e71b7053SJung-uk Kim goto err; 3109e71b7053SJung-uk Kim } 3110e71b7053SJung-uk Kim /* 3111e71b7053SJung-uk Kim * We're not actually expecting any data here and we ignore 3112e71b7053SJung-uk Kim * any that is sent. This is just to force the handshake that 3113e71b7053SJung-uk Kim * we're expecting to come from the client. If they haven't 3114e71b7053SJung-uk Kim * sent one there's not much we can do. 3115e71b7053SJung-uk Kim */ 3116e71b7053SJung-uk Kim BIO_gets(io, buf, bufsize - 1); 3117e71b7053SJung-uk Kim } 3118e71b7053SJung-uk Kim 31196f9291ceSJung-uk Kim BIO_puts(io, 31206f9291ceSJung-uk Kim "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n"); 312174664626SKris Kennaway BIO_puts(io, "<HTML><BODY BGCOLOR=\"#ffffff\">\n"); 312274664626SKris Kennaway BIO_puts(io, "<pre>\n"); 3123e71b7053SJung-uk Kim /* BIO_puts(io, OpenSSL_version(OPENSSL_VERSION)); */ 312474664626SKris Kennaway BIO_puts(io, "\n"); 31256f9291ceSJung-uk Kim for (i = 0; i < local_argc; i++) { 3126e71b7053SJung-uk Kim const char *myp; 3127e71b7053SJung-uk Kim for (myp = local_argv[i]; *myp; myp++) 3128e71b7053SJung-uk Kim switch (*myp) { 3129e71b7053SJung-uk Kim case '<': 3130e71b7053SJung-uk Kim BIO_puts(io, "<"); 3131e71b7053SJung-uk Kim break; 3132e71b7053SJung-uk Kim case '>': 3133e71b7053SJung-uk Kim BIO_puts(io, ">"); 3134e71b7053SJung-uk Kim break; 3135e71b7053SJung-uk Kim case '&': 3136e71b7053SJung-uk Kim BIO_puts(io, "&"); 3137e71b7053SJung-uk Kim break; 3138e71b7053SJung-uk Kim default: 3139e71b7053SJung-uk Kim BIO_write(io, myp, 1); 3140e71b7053SJung-uk Kim break; 3141e71b7053SJung-uk Kim } 314274664626SKris Kennaway BIO_write(io, " ", 1); 314374664626SKris Kennaway } 314474664626SKris Kennaway BIO_puts(io, "\n"); 314574664626SKris Kennaway 314609286989SJung-uk Kim BIO_printf(io, 314709286989SJung-uk Kim "Secure Renegotiation IS%s supported\n", 314809286989SJung-uk Kim SSL_get_secure_renegotiation_support(con) ? 314909286989SJung-uk Kim "" : " NOT"); 315009286989SJung-uk Kim 31516f9291ceSJung-uk Kim /* 31526f9291ceSJung-uk Kim * The following is evil and should not really be done 31536f9291ceSJung-uk Kim */ 315474664626SKris Kennaway BIO_printf(io, "Ciphers supported in s_server binary\n"); 315574664626SKris Kennaway sk = SSL_get_ciphers(con); 315674664626SKris Kennaway j = sk_SSL_CIPHER_num(sk); 31576f9291ceSJung-uk Kim for (i = 0; i < j; i++) { 315874664626SKris Kennaway c = sk_SSL_CIPHER_value(sk, i); 315974664626SKris Kennaway BIO_printf(io, "%-11s:%-25s ", 31606f9291ceSJung-uk Kim SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c)); 316174664626SKris Kennaway if ((((i + 1) % 2) == 0) && (i + 1 != j)) 316274664626SKris Kennaway BIO_puts(io, "\n"); 316374664626SKris Kennaway } 316474664626SKris Kennaway BIO_puts(io, "\n"); 316574664626SKris Kennaway p = SSL_get_shared_ciphers(con, buf, bufsize); 31666f9291ceSJung-uk Kim if (p != NULL) { 31676f9291ceSJung-uk Kim BIO_printf(io, 31686f9291ceSJung-uk Kim "---\nCiphers common between both SSL end points:\n"); 316974664626SKris Kennaway j = i = 0; 31706f9291ceSJung-uk Kim while (*p) { 31716f9291ceSJung-uk Kim if (*p == ':') { 317274664626SKris Kennaway BIO_write(io, space, 26 - j); 317374664626SKris Kennaway i++; 317474664626SKris Kennaway j = 0; 317574664626SKris Kennaway BIO_write(io, ((i % 3) ? " " : "\n"), 1); 31766f9291ceSJung-uk Kim } else { 317774664626SKris Kennaway BIO_write(io, p, 1); 317874664626SKris Kennaway j++; 317974664626SKris Kennaway } 318074664626SKris Kennaway p++; 318174664626SKris Kennaway } 318274664626SKris Kennaway BIO_puts(io, "\n"); 318374664626SKris Kennaway } 31847bded2dbSJung-uk Kim ssl_print_sigalgs(io, con); 31857bded2dbSJung-uk Kim #ifndef OPENSSL_NO_EC 3186e71b7053SJung-uk Kim ssl_print_groups(io, con, 0); 31877bded2dbSJung-uk Kim #endif 3188e71b7053SJung-uk Kim print_ca_names(io, con); 3189e71b7053SJung-uk Kim BIO_printf(io, (SSL_session_reused(con) 31906f9291ceSJung-uk Kim ? "---\nReused, " : "---\nNew, ")); 319174664626SKris Kennaway c = SSL_get_current_cipher(con); 319274664626SKris Kennaway BIO_printf(io, "%s, Cipher is %s\n", 31936f9291ceSJung-uk Kim SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c)); 319474664626SKris Kennaway SSL_SESSION_print(io, SSL_get_session(con)); 319574664626SKris Kennaway BIO_printf(io, "---\n"); 319674664626SKris Kennaway print_stats(io, SSL_get_SSL_CTX(con)); 319774664626SKris Kennaway BIO_printf(io, "---\n"); 319874664626SKris Kennaway peer = SSL_get_peer_certificate(con); 31996f9291ceSJung-uk Kim if (peer != NULL) { 320074664626SKris Kennaway BIO_printf(io, "Client certificate\n"); 320174664626SKris Kennaway X509_print(io, peer); 320274664626SKris Kennaway PEM_write_bio_X509(io, peer); 3203e71b7053SJung-uk Kim X509_free(peer); 3204e71b7053SJung-uk Kim peer = NULL; 3205e71b7053SJung-uk Kim } else { 320674664626SKris Kennaway BIO_puts(io, "no client certificate available\n"); 3207e71b7053SJung-uk Kim } 320847902a71SJung-uk Kim BIO_puts(io, "</pre></BODY></HTML>\r\n\r\n"); 320974664626SKris Kennaway break; 32106f9291ceSJung-uk Kim } else if ((www == 2 || www == 3) 32116f9291ceSJung-uk Kim && (strncmp("GET /", buf, 5) == 0)) { 321274664626SKris Kennaway BIO *file; 321374664626SKris Kennaway char *p, *e; 32146f9291ceSJung-uk Kim static const char *text = 32156f9291ceSJung-uk Kim "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n"; 321674664626SKris Kennaway 321774664626SKris Kennaway /* skip the '/' */ 321874664626SKris Kennaway p = &(buf[5]); 32195740a5e3SKris Kennaway 32205740a5e3SKris Kennaway dot = 1; 32216f9291ceSJung-uk Kim for (e = p; *e != '\0'; e++) { 32225740a5e3SKris Kennaway if (e[0] == ' ') 32235740a5e3SKris Kennaway break; 322474664626SKris Kennaway 322517f01e99SJung-uk Kim if (e[0] == ':') { 322617f01e99SJung-uk Kim /* Windows drive. We treat this the same way as ".." */ 322717f01e99SJung-uk Kim dot = -1; 322817f01e99SJung-uk Kim break; 322917f01e99SJung-uk Kim } 323017f01e99SJung-uk Kim 32316f9291ceSJung-uk Kim switch (dot) { 32325740a5e3SKris Kennaway case 1: 32335740a5e3SKris Kennaway dot = (e[0] == '.') ? 2 : 0; 32345740a5e3SKris Kennaway break; 32355740a5e3SKris Kennaway case 2: 32365740a5e3SKris Kennaway dot = (e[0] == '.') ? 3 : 0; 32375740a5e3SKris Kennaway break; 32385740a5e3SKris Kennaway case 3: 323917f01e99SJung-uk Kim dot = (e[0] == '/' || e[0] == '\\') ? -1 : 0; 32405740a5e3SKris Kennaway break; 32415740a5e3SKris Kennaway } 32425740a5e3SKris Kennaway if (dot == 0) 324317f01e99SJung-uk Kim dot = (e[0] == '/' || e[0] == '\\') ? 1 : 0; 32445740a5e3SKris Kennaway } 32456f9291ceSJung-uk Kim dot = (dot == 3) || (dot == -1); /* filename contains ".." 32466f9291ceSJung-uk Kim * component */ 324774664626SKris Kennaway 32486f9291ceSJung-uk Kim if (*e == '\0') { 324974664626SKris Kennaway BIO_puts(io, text); 325074664626SKris Kennaway BIO_printf(io, "'%s' is an invalid file name\r\n", p); 325174664626SKris Kennaway break; 325274664626SKris Kennaway } 325374664626SKris Kennaway *e = '\0'; 325474664626SKris Kennaway 32556f9291ceSJung-uk Kim if (dot) { 325674664626SKris Kennaway BIO_puts(io, text); 325717f01e99SJung-uk Kim BIO_printf(io, "'%s' contains '..' or ':'\r\n", p); 325874664626SKris Kennaway break; 325974664626SKris Kennaway } 326074664626SKris Kennaway 326117f01e99SJung-uk Kim if (*p == '/' || *p == '\\') { 326274664626SKris Kennaway BIO_puts(io, text); 326374664626SKris Kennaway BIO_printf(io, "'%s' is an invalid path\r\n", p); 326474664626SKris Kennaway break; 326574664626SKris Kennaway } 326674664626SKris Kennaway 326774664626SKris Kennaway /* if a directory, do the index thang */ 32686f9291ceSJung-uk Kim if (app_isdir(p) > 0) { 32695740a5e3SKris Kennaway BIO_puts(io, text); 32705740a5e3SKris Kennaway BIO_printf(io, "'%s' is a directory\r\n", p); 32715740a5e3SKris Kennaway break; 327274664626SKris Kennaway } 327374664626SKris Kennaway 32746f9291ceSJung-uk Kim if ((file = BIO_new_file(p, "r")) == NULL) { 327574664626SKris Kennaway BIO_puts(io, text); 327674664626SKris Kennaway BIO_printf(io, "Error opening '%s'\r\n", p); 327774664626SKris Kennaway ERR_print_errors(io); 327874664626SKris Kennaway break; 327974664626SKris Kennaway } 328074664626SKris Kennaway 328174664626SKris Kennaway if (!s_quiet) 328274664626SKris Kennaway BIO_printf(bio_err, "FILE:%s\n", p); 328374664626SKris Kennaway 32846f9291ceSJung-uk Kim if (www == 2) { 328574664626SKris Kennaway i = strlen(p); 328674664626SKris Kennaway if (((i > 5) && (strcmp(&(p[i - 5]), ".html") == 0)) || 328774664626SKris Kennaway ((i > 4) && (strcmp(&(p[i - 4]), ".php") == 0)) || 328874664626SKris Kennaway ((i > 4) && (strcmp(&(p[i - 4]), ".htm") == 0))) 32896f9291ceSJung-uk Kim BIO_puts(io, 32906f9291ceSJung-uk Kim "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n"); 329174664626SKris Kennaway else 32926f9291ceSJung-uk Kim BIO_puts(io, 32936f9291ceSJung-uk Kim "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n"); 32945c87c606SMark Murray } 329574664626SKris Kennaway /* send the file */ 32966f9291ceSJung-uk Kim for (;;) { 329774664626SKris Kennaway i = BIO_read(file, buf, bufsize); 32986f9291ceSJung-uk Kim if (i <= 0) 32996f9291ceSJung-uk Kim break; 330074664626SKris Kennaway 330174664626SKris Kennaway #ifdef RENEG 330274664626SKris Kennaway total_bytes += i; 3303e71b7053SJung-uk Kim BIO_printf(bio_err, "%d\n", i); 33046f9291ceSJung-uk Kim if (total_bytes > 3 * 1024) { 330574664626SKris Kennaway total_bytes = 0; 3306e71b7053SJung-uk Kim BIO_printf(bio_err, "RENEGOTIATE\n"); 330774664626SKris Kennaway SSL_renegotiate(con); 330874664626SKris Kennaway } 330974664626SKris Kennaway #endif 331074664626SKris Kennaway 33116f9291ceSJung-uk Kim for (j = 0; j < i;) { 331274664626SKris Kennaway #ifdef RENEG 33136f9291ceSJung-uk Kim static count = 0; 33146f9291ceSJung-uk Kim if (++count == 13) { 33156f9291ceSJung-uk Kim SSL_renegotiate(con); 33166f9291ceSJung-uk Kim } 331774664626SKris Kennaway #endif 331874664626SKris Kennaway k = BIO_write(io, &(buf[j]), i - j); 33196f9291ceSJung-uk Kim if (k <= 0) { 3320e71b7053SJung-uk Kim if (!BIO_should_retry(io) 3321e71b7053SJung-uk Kim && !SSL_waiting_for_async(con)) 332274664626SKris Kennaway goto write_error; 33236f9291ceSJung-uk Kim else { 332474664626SKris Kennaway BIO_printf(bio_s_out, "rwrite W BLOCK\n"); 332574664626SKris Kennaway } 33266f9291ceSJung-uk Kim } else { 332774664626SKris Kennaway j += k; 332874664626SKris Kennaway } 332974664626SKris Kennaway } 333074664626SKris Kennaway } 333174664626SKris Kennaway write_error: 333274664626SKris Kennaway BIO_free(file); 333374664626SKris Kennaway break; 333474664626SKris Kennaway } 333574664626SKris Kennaway } 333674664626SKris Kennaway 33376f9291ceSJung-uk Kim for (;;) { 333874664626SKris Kennaway i = (int)BIO_flush(io); 33396f9291ceSJung-uk Kim if (i <= 0) { 334074664626SKris Kennaway if (!BIO_should_retry(io)) 334174664626SKris Kennaway break; 33426f9291ceSJung-uk Kim } else 334374664626SKris Kennaway break; 334474664626SKris Kennaway } 334574664626SKris Kennaway end: 334674664626SKris Kennaway /* make sure we re-use sessions */ 334774664626SKris Kennaway SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); 334874664626SKris Kennaway 334974664626SKris Kennaway err: 33506f9291ceSJung-uk Kim OPENSSL_free(buf); 33516f9291ceSJung-uk Kim BIO_free_all(io); 3352e71b7053SJung-uk Kim return ret; 335374664626SKris Kennaway } 335474664626SKris Kennaway 3355e71b7053SJung-uk Kim static int rev_body(int s, int stype, int prot, unsigned char *context) 33567bded2dbSJung-uk Kim { 33577bded2dbSJung-uk Kim char *buf = NULL; 33587bded2dbSJung-uk Kim int i; 33597bded2dbSJung-uk Kim int ret = 1; 33607bded2dbSJung-uk Kim SSL *con; 33617bded2dbSJung-uk Kim BIO *io, *ssl_bio, *sbio; 33627bded2dbSJung-uk Kim 3363e71b7053SJung-uk Kim buf = app_malloc(bufsize, "server rev buffer"); 33647bded2dbSJung-uk Kim io = BIO_new(BIO_f_buffer()); 33657bded2dbSJung-uk Kim ssl_bio = BIO_new(BIO_f_ssl()); 33667bded2dbSJung-uk Kim if ((io == NULL) || (ssl_bio == NULL)) 33677bded2dbSJung-uk Kim goto err; 33687bded2dbSJung-uk Kim 33697bded2dbSJung-uk Kim /* lets make the output buffer a reasonable size */ 33707bded2dbSJung-uk Kim if (!BIO_set_write_buffer_size(io, bufsize)) 33717bded2dbSJung-uk Kim goto err; 33727bded2dbSJung-uk Kim 33737bded2dbSJung-uk Kim if ((con = SSL_new(ctx)) == NULL) 33747bded2dbSJung-uk Kim goto err; 3375e71b7053SJung-uk Kim 33767bded2dbSJung-uk Kim if (s_tlsextdebug) { 33777bded2dbSJung-uk Kim SSL_set_tlsext_debug_callback(con, tlsext_cb); 33787bded2dbSJung-uk Kim SSL_set_tlsext_debug_arg(con, bio_s_out); 33797bded2dbSJung-uk Kim } 3380e71b7053SJung-uk Kim if (context != NULL 3381e71b7053SJung-uk Kim && !SSL_set_session_id_context(con, context, 3382e71b7053SJung-uk Kim strlen((char *)context))) { 3383e71b7053SJung-uk Kim SSL_free(con); 3384e71b7053SJung-uk Kim ERR_print_errors(bio_err); 3385e71b7053SJung-uk Kim goto err; 33867bded2dbSJung-uk Kim } 33877bded2dbSJung-uk Kim 33887bded2dbSJung-uk Kim sbio = BIO_new_socket(s, BIO_NOCLOSE); 33897bded2dbSJung-uk Kim SSL_set_bio(con, sbio, sbio); 33907bded2dbSJung-uk Kim SSL_set_accept_state(con); 33917bded2dbSJung-uk Kim 3392e71b7053SJung-uk Kim /* No need to free |con| after this. Done by BIO_free(ssl_bio) */ 33937bded2dbSJung-uk Kim BIO_set_ssl(ssl_bio, con, BIO_CLOSE); 33947bded2dbSJung-uk Kim BIO_push(io, ssl_bio); 33957bded2dbSJung-uk Kim #ifdef CHARSET_EBCDIC 33967bded2dbSJung-uk Kim io = BIO_push(BIO_new(BIO_f_ebcdic_filter()), io); 33977bded2dbSJung-uk Kim #endif 33987bded2dbSJung-uk Kim 33997bded2dbSJung-uk Kim if (s_debug) { 34007bded2dbSJung-uk Kim BIO_set_callback(SSL_get_rbio(con), bio_dump_callback); 34017bded2dbSJung-uk Kim BIO_set_callback_arg(SSL_get_rbio(con), (char *)bio_s_out); 34027bded2dbSJung-uk Kim } 34037bded2dbSJung-uk Kim if (s_msg) { 34047bded2dbSJung-uk Kim #ifndef OPENSSL_NO_SSL_TRACE 34057bded2dbSJung-uk Kim if (s_msg == 2) 34067bded2dbSJung-uk Kim SSL_set_msg_callback(con, SSL_trace); 34077bded2dbSJung-uk Kim else 34087bded2dbSJung-uk Kim #endif 34097bded2dbSJung-uk Kim SSL_set_msg_callback(con, msg_cb); 34107bded2dbSJung-uk Kim SSL_set_msg_callback_arg(con, bio_s_msg ? bio_s_msg : bio_s_out); 34117bded2dbSJung-uk Kim } 34127bded2dbSJung-uk Kim 34137bded2dbSJung-uk Kim for (;;) { 34147bded2dbSJung-uk Kim i = BIO_do_handshake(io); 34157bded2dbSJung-uk Kim if (i > 0) 34167bded2dbSJung-uk Kim break; 34177bded2dbSJung-uk Kim if (!BIO_should_retry(io)) { 34187bded2dbSJung-uk Kim BIO_puts(bio_err, "CONNECTION FAILURE\n"); 34197bded2dbSJung-uk Kim ERR_print_errors(bio_err); 34207bded2dbSJung-uk Kim goto end; 34217bded2dbSJung-uk Kim } 342280815a77SJung-uk Kim #ifndef OPENSSL_NO_SRP 342380815a77SJung-uk Kim if (BIO_should_io_special(io) 342480815a77SJung-uk Kim && BIO_get_retry_reason(io) == BIO_RR_SSL_X509_LOOKUP) { 342580815a77SJung-uk Kim BIO_printf(bio_s_out, "LOOKUP renego during accept\n"); 34264c6a0400SJung-uk Kim SRP_user_pwd_free(srp_callback_parm.user); 342780815a77SJung-uk Kim srp_callback_parm.user = 34284c6a0400SJung-uk Kim SRP_VBASE_get1_by_user(srp_callback_parm.vb, 342980815a77SJung-uk Kim srp_callback_parm.login); 343080815a77SJung-uk Kim if (srp_callback_parm.user) 343180815a77SJung-uk Kim BIO_printf(bio_s_out, "LOOKUP done %s\n", 343280815a77SJung-uk Kim srp_callback_parm.user->info); 343380815a77SJung-uk Kim else 343480815a77SJung-uk Kim BIO_printf(bio_s_out, "LOOKUP not successful\n"); 343580815a77SJung-uk Kim continue; 343680815a77SJung-uk Kim } 343780815a77SJung-uk Kim #endif 34387bded2dbSJung-uk Kim } 34397bded2dbSJung-uk Kim BIO_printf(bio_err, "CONNECTION ESTABLISHED\n"); 3440e71b7053SJung-uk Kim print_ssl_summary(con); 34417bded2dbSJung-uk Kim 34427bded2dbSJung-uk Kim for (;;) { 34437bded2dbSJung-uk Kim i = BIO_gets(io, buf, bufsize - 1); 34447bded2dbSJung-uk Kim if (i < 0) { /* error */ 34457bded2dbSJung-uk Kim if (!BIO_should_retry(io)) { 34467bded2dbSJung-uk Kim if (!s_quiet) 34477bded2dbSJung-uk Kim ERR_print_errors(bio_err); 34487bded2dbSJung-uk Kim goto err; 34497bded2dbSJung-uk Kim } else { 34507bded2dbSJung-uk Kim BIO_printf(bio_s_out, "read R BLOCK\n"); 345180815a77SJung-uk Kim #ifndef OPENSSL_NO_SRP 345280815a77SJung-uk Kim if (BIO_should_io_special(io) 345380815a77SJung-uk Kim && BIO_get_retry_reason(io) == BIO_RR_SSL_X509_LOOKUP) { 345480815a77SJung-uk Kim BIO_printf(bio_s_out, "LOOKUP renego during read\n"); 34554c6a0400SJung-uk Kim SRP_user_pwd_free(srp_callback_parm.user); 345680815a77SJung-uk Kim srp_callback_parm.user = 34574c6a0400SJung-uk Kim SRP_VBASE_get1_by_user(srp_callback_parm.vb, 345880815a77SJung-uk Kim srp_callback_parm.login); 345980815a77SJung-uk Kim if (srp_callback_parm.user) 346080815a77SJung-uk Kim BIO_printf(bio_s_out, "LOOKUP done %s\n", 346180815a77SJung-uk Kim srp_callback_parm.user->info); 346280815a77SJung-uk Kim else 346380815a77SJung-uk Kim BIO_printf(bio_s_out, "LOOKUP not successful\n"); 346480815a77SJung-uk Kim continue; 346580815a77SJung-uk Kim } 346680815a77SJung-uk Kim #endif 3467e71b7053SJung-uk Kim #if !defined(OPENSSL_SYS_MSDOS) 34687bded2dbSJung-uk Kim sleep(1); 34697bded2dbSJung-uk Kim #endif 34707bded2dbSJung-uk Kim continue; 34717bded2dbSJung-uk Kim } 34727bded2dbSJung-uk Kim } else if (i == 0) { /* end of input */ 34737bded2dbSJung-uk Kim ret = 1; 34747bded2dbSJung-uk Kim BIO_printf(bio_err, "CONNECTION CLOSED\n"); 34757bded2dbSJung-uk Kim goto end; 34767bded2dbSJung-uk Kim } else { 34777bded2dbSJung-uk Kim char *p = buf + i - 1; 34787bded2dbSJung-uk Kim while (i && (*p == '\n' || *p == '\r')) { 34797bded2dbSJung-uk Kim p--; 34807bded2dbSJung-uk Kim i--; 34817bded2dbSJung-uk Kim } 3482e71b7053SJung-uk Kim if (!s_ign_eof && (i == 5) && (strncmp(buf, "CLOSE", 5) == 0)) { 34837bded2dbSJung-uk Kim ret = 1; 34847bded2dbSJung-uk Kim BIO_printf(bio_err, "CONNECTION CLOSED\n"); 34857bded2dbSJung-uk Kim goto end; 34867bded2dbSJung-uk Kim } 34877bded2dbSJung-uk Kim BUF_reverse((unsigned char *)buf, NULL, i); 34887bded2dbSJung-uk Kim buf[i] = '\n'; 34897bded2dbSJung-uk Kim BIO_write(io, buf, i + 1); 34907bded2dbSJung-uk Kim for (;;) { 34917bded2dbSJung-uk Kim i = BIO_flush(io); 34927bded2dbSJung-uk Kim if (i > 0) 34937bded2dbSJung-uk Kim break; 34947bded2dbSJung-uk Kim if (!BIO_should_retry(io)) 34957bded2dbSJung-uk Kim goto end; 34967bded2dbSJung-uk Kim } 34977bded2dbSJung-uk Kim } 34987bded2dbSJung-uk Kim } 34997bded2dbSJung-uk Kim end: 35007bded2dbSJung-uk Kim /* make sure we re-use sessions */ 35017bded2dbSJung-uk Kim SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); 35027bded2dbSJung-uk Kim 35037bded2dbSJung-uk Kim err: 35047bded2dbSJung-uk Kim 35057bded2dbSJung-uk Kim OPENSSL_free(buf); 35067bded2dbSJung-uk Kim BIO_free_all(io); 3507e71b7053SJung-uk Kim return ret; 35087bded2dbSJung-uk Kim } 35097bded2dbSJung-uk Kim 35105c87c606SMark Murray #define MAX_SESSION_ID_ATTEMPTS 10 3511e71b7053SJung-uk Kim static int generate_session_id(SSL *ssl, unsigned char *id, 35125c87c606SMark Murray unsigned int *id_len) 35135c87c606SMark Murray { 35145c87c606SMark Murray unsigned int count = 0; 35155c87c606SMark Murray do { 3516aeb5019cSJung-uk Kim if (RAND_bytes(id, *id_len) <= 0) 3517ed6b93beSJung-uk Kim return 0; 35186f9291ceSJung-uk Kim /* 35196f9291ceSJung-uk Kim * Prefix the session_id with the required prefix. NB: If our prefix 35206f9291ceSJung-uk Kim * is too long, clip it - but there will be worse effects anyway, eg. 35216f9291ceSJung-uk Kim * the server could only possibly create 1 session ID (ie. the 35226f9291ceSJung-uk Kim * prefix!) so all future session negotiations will fail due to 35236f9291ceSJung-uk Kim * conflicts. 35246f9291ceSJung-uk Kim */ 35255c87c606SMark Murray memcpy(id, session_id_prefix, 35265c87c606SMark Murray (strlen(session_id_prefix) < *id_len) ? 35275c87c606SMark Murray strlen(session_id_prefix) : *id_len); 35285c87c606SMark Murray } 35295c87c606SMark Murray while (SSL_has_matching_session_id(ssl, id, *id_len) && 35305c87c606SMark Murray (++count < MAX_SESSION_ID_ATTEMPTS)); 35315c87c606SMark Murray if (count >= MAX_SESSION_ID_ATTEMPTS) 35325c87c606SMark Murray return 0; 35335c87c606SMark Murray return 1; 35345c87c606SMark Murray } 35357bded2dbSJung-uk Kim 35367bded2dbSJung-uk Kim /* 35377bded2dbSJung-uk Kim * By default s_server uses an in-memory cache which caches SSL_SESSION 35387bded2dbSJung-uk Kim * structures without any serialisation. This hides some bugs which only 35397bded2dbSJung-uk Kim * become apparent in deployed servers. By implementing a basic external 35407bded2dbSJung-uk Kim * session cache some issues can be debugged using s_server. 35417bded2dbSJung-uk Kim */ 35427bded2dbSJung-uk Kim 35437bded2dbSJung-uk Kim typedef struct simple_ssl_session_st { 35447bded2dbSJung-uk Kim unsigned char *id; 35457bded2dbSJung-uk Kim unsigned int idlen; 35467bded2dbSJung-uk Kim unsigned char *der; 35477bded2dbSJung-uk Kim int derlen; 35487bded2dbSJung-uk Kim struct simple_ssl_session_st *next; 35497bded2dbSJung-uk Kim } simple_ssl_session; 35507bded2dbSJung-uk Kim 35517bded2dbSJung-uk Kim static simple_ssl_session *first = NULL; 35527bded2dbSJung-uk Kim 35537bded2dbSJung-uk Kim static int add_session(SSL *ssl, SSL_SESSION *session) 35547bded2dbSJung-uk Kim { 3555e71b7053SJung-uk Kim simple_ssl_session *sess = app_malloc(sizeof(*sess), "get session"); 35567bded2dbSJung-uk Kim unsigned char *p; 35577bded2dbSJung-uk Kim 35587bded2dbSJung-uk Kim SSL_SESSION_get_id(session, &sess->idlen); 35597bded2dbSJung-uk Kim sess->derlen = i2d_SSL_SESSION(session, NULL); 3560e71b7053SJung-uk Kim if (sess->derlen < 0) { 3561e71b7053SJung-uk Kim BIO_printf(bio_err, "Error encoding session\n"); 3562e71b7053SJung-uk Kim OPENSSL_free(sess); 3563e71b7053SJung-uk Kim return 0; 3564e71b7053SJung-uk Kim } 35657bded2dbSJung-uk Kim 3566e71b7053SJung-uk Kim sess->id = OPENSSL_memdup(SSL_SESSION_get_id(session, NULL), sess->idlen); 3567e71b7053SJung-uk Kim sess->der = app_malloc(sess->derlen, "get session buffer"); 3568e71b7053SJung-uk Kim if (!sess->id) { 3569e71b7053SJung-uk Kim BIO_printf(bio_err, "Out of memory adding to external cache\n"); 35707bded2dbSJung-uk Kim OPENSSL_free(sess->id); 35717bded2dbSJung-uk Kim OPENSSL_free(sess->der); 35727bded2dbSJung-uk Kim OPENSSL_free(sess); 35737bded2dbSJung-uk Kim return 0; 35747bded2dbSJung-uk Kim } 35757bded2dbSJung-uk Kim p = sess->der; 3576e71b7053SJung-uk Kim 3577e71b7053SJung-uk Kim /* Assume it still works. */ 3578e71b7053SJung-uk Kim if (i2d_SSL_SESSION(session, &p) != sess->derlen) { 3579e71b7053SJung-uk Kim BIO_printf(bio_err, "Unexpected session encoding length\n"); 3580e71b7053SJung-uk Kim OPENSSL_free(sess->id); 3581e71b7053SJung-uk Kim OPENSSL_free(sess->der); 3582e71b7053SJung-uk Kim OPENSSL_free(sess); 3583e71b7053SJung-uk Kim return 0; 3584e71b7053SJung-uk Kim } 35857bded2dbSJung-uk Kim 35867bded2dbSJung-uk Kim sess->next = first; 35877bded2dbSJung-uk Kim first = sess; 35887bded2dbSJung-uk Kim BIO_printf(bio_err, "New session added to external cache\n"); 35897bded2dbSJung-uk Kim return 0; 35907bded2dbSJung-uk Kim } 35917bded2dbSJung-uk Kim 3592e71b7053SJung-uk Kim static SSL_SESSION *get_session(SSL *ssl, const unsigned char *id, int idlen, 35937bded2dbSJung-uk Kim int *do_copy) 35947bded2dbSJung-uk Kim { 35957bded2dbSJung-uk Kim simple_ssl_session *sess; 35967bded2dbSJung-uk Kim *do_copy = 0; 35977bded2dbSJung-uk Kim for (sess = first; sess; sess = sess->next) { 35987bded2dbSJung-uk Kim if (idlen == (int)sess->idlen && !memcmp(sess->id, id, idlen)) { 35997bded2dbSJung-uk Kim const unsigned char *p = sess->der; 36007bded2dbSJung-uk Kim BIO_printf(bio_err, "Lookup session: cache hit\n"); 36017bded2dbSJung-uk Kim return d2i_SSL_SESSION(NULL, &p, sess->derlen); 36027bded2dbSJung-uk Kim } 36037bded2dbSJung-uk Kim } 36047bded2dbSJung-uk Kim BIO_printf(bio_err, "Lookup session: cache miss\n"); 36057bded2dbSJung-uk Kim return NULL; 36067bded2dbSJung-uk Kim } 36077bded2dbSJung-uk Kim 36087bded2dbSJung-uk Kim static void del_session(SSL_CTX *sctx, SSL_SESSION *session) 36097bded2dbSJung-uk Kim { 36107bded2dbSJung-uk Kim simple_ssl_session *sess, *prev = NULL; 36117bded2dbSJung-uk Kim const unsigned char *id; 36127bded2dbSJung-uk Kim unsigned int idlen; 36137bded2dbSJung-uk Kim id = SSL_SESSION_get_id(session, &idlen); 36147bded2dbSJung-uk Kim for (sess = first; sess; sess = sess->next) { 36157bded2dbSJung-uk Kim if (idlen == sess->idlen && !memcmp(sess->id, id, idlen)) { 36167bded2dbSJung-uk Kim if (prev) 36177bded2dbSJung-uk Kim prev->next = sess->next; 36187bded2dbSJung-uk Kim else 36197bded2dbSJung-uk Kim first = sess->next; 36207bded2dbSJung-uk Kim OPENSSL_free(sess->id); 36217bded2dbSJung-uk Kim OPENSSL_free(sess->der); 36227bded2dbSJung-uk Kim OPENSSL_free(sess); 36237bded2dbSJung-uk Kim return; 36247bded2dbSJung-uk Kim } 36257bded2dbSJung-uk Kim prev = sess; 36267bded2dbSJung-uk Kim } 36277bded2dbSJung-uk Kim } 36287bded2dbSJung-uk Kim 36297bded2dbSJung-uk Kim static void init_session_cache_ctx(SSL_CTX *sctx) 36307bded2dbSJung-uk Kim { 36317bded2dbSJung-uk Kim SSL_CTX_set_session_cache_mode(sctx, 36327bded2dbSJung-uk Kim SSL_SESS_CACHE_NO_INTERNAL | 36337bded2dbSJung-uk Kim SSL_SESS_CACHE_SERVER); 36347bded2dbSJung-uk Kim SSL_CTX_sess_set_new_cb(sctx, add_session); 36357bded2dbSJung-uk Kim SSL_CTX_sess_set_get_cb(sctx, get_session); 36367bded2dbSJung-uk Kim SSL_CTX_sess_set_remove_cb(sctx, del_session); 36377bded2dbSJung-uk Kim } 36387bded2dbSJung-uk Kim 36397bded2dbSJung-uk Kim static void free_sessions(void) 36407bded2dbSJung-uk Kim { 36417bded2dbSJung-uk Kim simple_ssl_session *sess, *tsess; 36427bded2dbSJung-uk Kim for (sess = first; sess;) { 36437bded2dbSJung-uk Kim OPENSSL_free(sess->id); 36447bded2dbSJung-uk Kim OPENSSL_free(sess->der); 36457bded2dbSJung-uk Kim tsess = sess; 36467bded2dbSJung-uk Kim sess = sess->next; 36477bded2dbSJung-uk Kim OPENSSL_free(tsess); 36487bded2dbSJung-uk Kim } 36497bded2dbSJung-uk Kim first = NULL; 36507bded2dbSJung-uk Kim } 3651e71b7053SJung-uk Kim 3652e71b7053SJung-uk Kim #endif /* OPENSSL_NO_SOCK */ 3653