src/openvpn/ssl.c
6fbf66fa
 /*
  *  OpenVPN -- An application to securely tunnel IP networks
  *             over a single TCP/UDP port, with support for SSL/TLS-based
  *             session authentication and key exchange,
  *             packet encryption, packet authentication, and
  *             packet compression.
  *
49979459
  *  Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
  *  Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com>
e3d38865
  *  Copyright (C) 2008-2013 David Sommerseth <dazo@users.sourceforge.net>
0c1f7ad5
  *
6fbf66fa
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2
  *  as published by the Free Software Foundation.
  *
  *  This program is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
caa54ac3
  *  You should have received a copy of the GNU General Public License along
  *  with this program; if not, write to the Free Software Foundation, Inc.,
  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
6fbf66fa
  */
 
95993a1d
 /**
  * @file Control Channel SSL/Data channel negotiation Module
  */
 
6fbf66fa
 /*
  * The routines in this file deal with dynamically negotiating
  * the data channel HMAC and cipher keys through a TLS session.
  *
  * Both the TLS session and the data channel are multiplexed
  * over the same TCP/UDP port.
  */
c110b289
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #elif defined(_MSC_VER)
 #include "config-msvc.h"
 #endif
 
1bda73a7
 #include "syshead.h"
cdc65ea0
 #include "win32.h"
6fbf66fa
 
 #include "error.h"
 #include "common.h"
 #include "socket.h"
 #include "misc.h"
 #include "fdmisc.h"
 #include "interval.h"
 #include "perf.h"
 #include "status.h"
 #include "gremlin.h"
ce98fd24
 #include "pkcs11.h"
7fb0e07e
 #include "route.h"
c6e24fa3
 #include "tls_crypt.h"
6fbf66fa
 
95993a1d
 #include "ssl.h"
 #include "ssl_verify.h"
 #include "ssl_backend.h"
 
6fbf66fa
 #include "memdbg.h"
 
 #ifndef ENABLE_OCC
 static const char ssl_default_options_string[] = "V0 UNDEF";
 #endif
 
 static inline const char *
81d882d5
 local_options_string(const struct tls_session *session)
6fbf66fa
 {
 #ifdef ENABLE_OCC
81d882d5
     return session->opt->local_options;
6fbf66fa
 #else
81d882d5
     return ssl_default_options_string;
6fbf66fa
 #endif
 }
 
 #ifdef MEASURE_TLS_HANDSHAKE_STATS
 
 static int tls_handshake_success; /* GLOBAL */
 static int tls_handshake_error;   /* GLOBAL */
 static int tls_packets_generated; /* GLOBAL */
 static int tls_packets_sent;      /* GLOBAL */
 
 #define INCR_SENT       ++tls_packets_sent
 #define INCR_GENERATED  ++tls_packets_generated
 #define INCR_SUCCESS    ++tls_handshake_success
 #define INCR_ERROR      ++tls_handshake_error
 
 void
 show_tls_performance_stats(void)
 {
81d882d5
     msg(D_TLS_DEBUG_LOW, "TLS Handshakes, success=%f%% (good=%d, bad=%d), retransmits=%f%%",
         (double) tls_handshake_success / (tls_handshake_success + tls_handshake_error) * 100.0,
         tls_handshake_success, tls_handshake_error,
         (double) (tls_packets_sent - tls_packets_generated) / tls_packets_generated * 100.0);
6fbf66fa
 }
81d882d5
 #else  /* ifdef MEASURE_TLS_HANDSHAKE_STATS */
6fbf66fa
 
 #define INCR_SENT
 #define INCR_GENERATED
 #define INCR_SUCCESS
 #define INCR_ERROR
 
81d882d5
 #endif /* ifdef MEASURE_TLS_HANDSHAKE_STATS */
6fbf66fa
 
3b23b18d
 /**
  * SSL/TLS Cipher suite name translation table
  */
 static const tls_cipher_name_pair tls_cipher_name_translation_table[] = {
     {"ADH-SEED-SHA", "TLS-DH-anon-WITH-SEED-CBC-SHA"},
     {"AES128-GCM-SHA256", "TLS-RSA-WITH-AES-128-GCM-SHA256"},
     {"AES128-SHA256", "TLS-RSA-WITH-AES-128-CBC-SHA256"},
     {"AES128-SHA", "TLS-RSA-WITH-AES-128-CBC-SHA"},
     {"AES256-GCM-SHA384", "TLS-RSA-WITH-AES-256-GCM-SHA384"},
     {"AES256-SHA256", "TLS-RSA-WITH-AES-256-CBC-SHA256"},
     {"AES256-SHA", "TLS-RSA-WITH-AES-256-CBC-SHA"},
     {"CAMELLIA128-SHA256", "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256"},
     {"CAMELLIA128-SHA", "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA"},
     {"CAMELLIA256-SHA256", "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256"},
     {"CAMELLIA256-SHA", "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA"},
     {"DES-CBC3-SHA", "TLS-RSA-WITH-3DES-EDE-CBC-SHA"},
     {"DES-CBC-SHA", "TLS-RSA-WITH-DES-CBC-SHA"},
     {"DH-DSS-SEED-SHA", "TLS-DH-DSS-WITH-SEED-CBC-SHA"},
     {"DHE-DSS-AES128-GCM-SHA256", "TLS-DHE-DSS-WITH-AES-128-GCM-SHA256"},
     {"DHE-DSS-AES128-SHA256", "TLS-DHE-DSS-WITH-AES-128-CBC-SHA256"},
     {"DHE-DSS-AES128-SHA", "TLS-DHE-DSS-WITH-AES-128-CBC-SHA"},
     {"DHE-DSS-AES256-GCM-SHA384", "TLS-DHE-DSS-WITH-AES-256-GCM-SHA384"},
     {"DHE-DSS-AES256-SHA256", "TLS-DHE-DSS-WITH-AES-256-CBC-SHA256"},
     {"DHE-DSS-AES256-SHA", "TLS-DHE-DSS-WITH-AES-256-CBC-SHA"},
     {"DHE-DSS-CAMELLIA128-SHA256", "TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA256"},
     {"DHE-DSS-CAMELLIA128-SHA", "TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA"},
     {"DHE-DSS-CAMELLIA256-SHA256", "TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA256"},
     {"DHE-DSS-CAMELLIA256-SHA", "TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA"},
     {"DHE-DSS-SEED-SHA", "TLS-DHE-DSS-WITH-SEED-CBC-SHA"},
     {"DHE-RSA-AES128-GCM-SHA256", "TLS-DHE-RSA-WITH-AES-128-GCM-SHA256"},
     {"DHE-RSA-AES128-SHA256", "TLS-DHE-RSA-WITH-AES-128-CBC-SHA256"},
     {"DHE-RSA-AES128-SHA", "TLS-DHE-RSA-WITH-AES-128-CBC-SHA"},
     {"DHE-RSA-AES256-GCM-SHA384", "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384"},
     {"DHE-RSA-AES256-SHA256", "TLS-DHE-RSA-WITH-AES-256-CBC-SHA256"},
     {"DHE-RSA-AES256-SHA", "TLS-DHE-RSA-WITH-AES-256-CBC-SHA"},
     {"DHE-RSA-CAMELLIA128-SHA256", "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256"},
     {"DHE-RSA-CAMELLIA128-SHA", "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA"},
     {"DHE-RSA-CAMELLIA256-SHA256", "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256"},
     {"DHE-RSA-CAMELLIA256-SHA", "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA"},
e7ec6a3a
     {"DHE-RSA-CHACHA20-POLY1305", "TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256"},
3b23b18d
     {"DHE-RSA-SEED-SHA", "TLS-DHE-RSA-WITH-SEED-CBC-SHA"},
     {"DH-RSA-SEED-SHA", "TLS-DH-RSA-WITH-SEED-CBC-SHA"},
     {"ECDH-ECDSA-AES128-GCM-SHA256", "TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256"},
     {"ECDH-ECDSA-AES128-SHA256", "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256"},
     {"ECDH-ECDSA-AES128-SHA", "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA"},
     {"ECDH-ECDSA-AES256-GCM-SHA384", "TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384"},
     {"ECDH-ECDSA-AES256-SHA256", "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA256"},
     {"ECDH-ECDSA-AES256-SHA384", "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384"},
     {"ECDH-ECDSA-AES256-SHA", "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA"},
     {"ECDH-ECDSA-CAMELLIA128-SHA256", "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA256"},
     {"ECDH-ECDSA-CAMELLIA128-SHA", "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA"},
     {"ECDH-ECDSA-CAMELLIA256-SHA256", "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA256"},
     {"ECDH-ECDSA-CAMELLIA256-SHA", "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA"},
     {"ECDH-ECDSA-DES-CBC3-SHA", "TLS-ECDH-ECDSA-WITH-3DES-EDE-CBC-SHA"},
     {"ECDH-ECDSA-DES-CBC-SHA", "TLS-ECDH-ECDSA-WITH-DES-CBC-SHA"},
     {"ECDH-ECDSA-RC4-SHA", "TLS-ECDH-ECDSA-WITH-RC4-128-SHA"},
     {"ECDHE-ECDSA-AES128-GCM-SHA256", "TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256"},
     {"ECDHE-ECDSA-AES128-SHA256", "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256"},
     {"ECDHE-ECDSA-AES128-SHA384", "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA384"},
     {"ECDHE-ECDSA-AES128-SHA", "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA"},
     {"ECDHE-ECDSA-AES256-GCM-SHA384", "TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384"},
     {"ECDHE-ECDSA-AES256-SHA256", "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA256"},
     {"ECDHE-ECDSA-AES256-SHA384", "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384"},
     {"ECDHE-ECDSA-AES256-SHA", "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA"},
     {"ECDHE-ECDSA-CAMELLIA128-SHA256", "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256"},
     {"ECDHE-ECDSA-CAMELLIA128-SHA", "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA"},
     {"ECDHE-ECDSA-CAMELLIA256-SHA256", "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA256"},
     {"ECDHE-ECDSA-CAMELLIA256-SHA", "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA"},
e7ec6a3a
     {"ECDHE-ECDSA-CHACHA20-POLY1305", "TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256"},
3b23b18d
     {"ECDHE-ECDSA-DES-CBC3-SHA", "TLS-ECDHE-ECDSA-WITH-3DES-EDE-CBC-SHA"},
     {"ECDHE-ECDSA-DES-CBC-SHA", "TLS-ECDHE-ECDSA-WITH-DES-CBC-SHA"},
     {"ECDHE-ECDSA-RC4-SHA", "TLS-ECDHE-ECDSA-WITH-RC4-128-SHA"},
     {"ECDHE-RSA-AES128-GCM-SHA256", "TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256"},
     {"ECDHE-RSA-AES128-SHA256", "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256"},
     {"ECDHE-RSA-AES128-SHA384", "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA384"},
     {"ECDHE-RSA-AES128-SHA", "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA"},
     {"ECDHE-RSA-AES256-GCM-SHA384", "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384"},
     {"ECDHE-RSA-AES256-SHA256", "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA256"},
     {"ECDHE-RSA-AES256-SHA384", "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384"},
     {"ECDHE-RSA-AES256-SHA", "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA"},
     {"ECDHE-RSA-CAMELLIA128-SHA256", "TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA256"},
     {"ECDHE-RSA-CAMELLIA128-SHA", "TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA"},
     {"ECDHE-RSA-CAMELLIA256-SHA256", "TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA256"},
     {"ECDHE-RSA-CAMELLIA256-SHA", "TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA"},
e7ec6a3a
     {"ECDHE-RSA-CHACHA20-POLY1305", "TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256"},
3b23b18d
     {"ECDHE-RSA-DES-CBC3-SHA", "TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA"},
     {"ECDHE-RSA-DES-CBC-SHA", "TLS-ECDHE-RSA-WITH-DES-CBC-SHA"},
     {"ECDHE-RSA-RC4-SHA", "TLS-ECDHE-RSA-WITH-RC4-128-SHA"},
     {"ECDH-RSA-AES128-GCM-SHA256", "TLS-ECDH-RSA-WITH-AES-128-GCM-SHA256"},
     {"ECDH-RSA-AES128-SHA256", "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA256"},
     {"ECDH-RSA-AES128-SHA384", "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA384"},
     {"ECDH-RSA-AES128-SHA", "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA"},
     {"ECDH-RSA-AES256-GCM-SHA384", "TLS-ECDH-RSA-WITH-AES-256-GCM-SHA384"},
     {"ECDH-RSA-AES256-SHA256", "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA256"},
     {"ECDH-RSA-AES256-SHA384", "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA384"},
     {"ECDH-RSA-AES256-SHA", "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA"},
     {"ECDH-RSA-CAMELLIA128-SHA256", "TLS-ECDH-RSA-WITH-CAMELLIA-128-CBC-SHA256"},
     {"ECDH-RSA-CAMELLIA128-SHA", "TLS-ECDH-RSA-WITH-CAMELLIA-128-CBC-SHA"},
     {"ECDH-RSA-CAMELLIA256-SHA256", "TLS-ECDH-RSA-WITH-CAMELLIA-256-CBC-SHA256"},
     {"ECDH-RSA-CAMELLIA256-SHA", "TLS-ECDH-RSA-WITH-CAMELLIA-256-CBC-SHA"},
     {"ECDH-RSA-DES-CBC3-SHA", "TLS-ECDH-RSA-WITH-3DES-EDE-CBC-SHA"},
     {"ECDH-RSA-DES-CBC-SHA", "TLS-ECDH-RSA-WITH-DES-CBC-SHA"},
     {"ECDH-RSA-RC4-SHA", "TLS-ECDH-RSA-WITH-RC4-128-SHA"},
     {"EDH-DSS-DES-CBC3-SHA", "TLS-DHE-DSS-WITH-3DES-EDE-CBC-SHA"},
     {"EDH-DSS-DES-CBC-SHA", "TLS-DHE-DSS-WITH-DES-CBC-SHA"},
     {"EDH-RSA-DES-CBC3-SHA", "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA"},
     {"EDH-RSA-DES-CBC-SHA", "TLS-DHE-RSA-WITH-DES-CBC-SHA"},
     {"EXP-DES-CBC-SHA", "TLS-RSA-EXPORT-WITH-DES40-CBC-SHA"},
     {"EXP-EDH-DSS-DES-CBC-SHA", "TLS-DH-DSS-EXPORT-WITH-DES40-CBC-SHA"},
     {"EXP-EDH-RSA-DES-CBC-SHA", "TLS-DH-RSA-EXPORT-WITH-DES40-CBC-SHA"},
     {"EXP-RC2-CBC-MD5", "TLS-RSA-EXPORT-WITH-RC2-CBC-40-MD5"},
     {"EXP-RC4-MD5", "TLS-RSA-EXPORT-WITH-RC4-40-MD5"},
     {"NULL-MD5", "TLS-RSA-WITH-NULL-MD5"},
     {"NULL-SHA256", "TLS-RSA-WITH-NULL-SHA256"},
     {"NULL-SHA", "TLS-RSA-WITH-NULL-SHA"},
     {"PSK-3DES-EDE-CBC-SHA", "TLS-PSK-WITH-3DES-EDE-CBC-SHA"},
     {"PSK-AES128-CBC-SHA", "TLS-PSK-WITH-AES-128-CBC-SHA"},
     {"PSK-AES256-CBC-SHA", "TLS-PSK-WITH-AES-256-CBC-SHA"},
     {"PSK-RC4-SHA", "TLS-PSK-WITH-RC4-128-SHA"},
     {"RC4-MD5", "TLS-RSA-WITH-RC4-128-MD5"},
     {"RC4-SHA", "TLS-RSA-WITH-RC4-128-SHA"},
     {"SEED-SHA", "TLS-RSA-WITH-SEED-CBC-SHA"},
     {"SRP-DSS-3DES-EDE-CBC-SHA", "TLS-SRP-SHA-DSS-WITH-3DES-EDE-CBC-SHA"},
     {"SRP-DSS-AES-128-CBC-SHA", "TLS-SRP-SHA-DSS-WITH-AES-128-CBC-SHA"},
     {"SRP-DSS-AES-256-CBC-SHA", "TLS-SRP-SHA-DSS-WITH-AES-256-CBC-SHA"},
     {"SRP-RSA-3DES-EDE-CBC-SHA", "TLS-SRP-SHA-RSA-WITH-3DES-EDE-CBC-SHA"},
     {"SRP-RSA-AES-128-CBC-SHA", "TLS-SRP-SHA-RSA-WITH-AES-128-CBC-SHA"},
     {"SRP-RSA-AES-256-CBC-SHA", "TLS-SRP-SHA-RSA-WITH-AES-256-CBC-SHA"},
0146fd00
 #ifdef ENABLE_CRYPTO_OPENSSL
7246ccfd
     /* OpenSSL-specific group names */
0146fd00
     {"DEFAULT", "DEFAULT"},
     {"ALL", "ALL"},
7246ccfd
     {"HIGH", "HIGH"}, {"!HIGH", "!HIGH"},
     {"MEDIUM", "MEDIUM"}, {"!MEDIUM", "!MEDIUM"},
     {"LOW", "LOW"}, {"!LOW", "!LOW"},
     {"ECDH", "ECDH"}, {"!ECDH", "!ECDH"},
     {"ECDSA", "ECDSA"}, {"!ECDSA", "!ECDSA"},
     {"EDH", "EDH"}, {"!EDH", "!EDH"},
     {"EXP", "EXP"}, {"!EXP", "!EXP"},
     {"RSA", "RSA"}, {"!RSA", "!RSA"},
     {"kRSA", "kRSA"}, {"!kRSA", "!kRSA"},
     {"SRP", "SRP"}, {"!SRP", "!SRP"},
0146fd00
 #endif
3b23b18d
     {NULL, NULL}
 };
 
66407e11
 /**
  * Update the implicit IV for a key_ctx_bi based on TLS session ids and cipher
  * used.
  *
  * Note that the implicit IV is based on the HMAC key, but only in AEAD modes
  * where the HMAC key is not used for an actual HMAC.
  *
81d882d5
  * @param ctx                   Encrypt/decrypt key context
  * @param key                   HMAC key, used to calculate implicit IV
  * @param key_len               HMAC key length
66407e11
  */
 static void
 key_ctx_update_implicit_iv(struct key_ctx *ctx, uint8_t *key, size_t key_len);
 
3b23b18d
 const tls_cipher_name_pair *
4cd4899e
 tls_get_cipher_name_pair(const char *cipher_name, size_t len)
 {
81d882d5
     const tls_cipher_name_pair *pair = tls_cipher_name_translation_table;
3b23b18d
 
4cd4899e
     while (pair->openssl_name != NULL)
     {
81d882d5
         if ((strlen(pair->openssl_name) == len && 0 == memcmp(cipher_name, pair->openssl_name, len))
             || (strlen(pair->iana_name) == len && 0 == memcmp(cipher_name, pair->iana_name, len)))
         {
             return pair;
         }
         pair++;
     }
3b23b18d
 
81d882d5
     /* No entry found, return NULL */
     return NULL;
3b23b18d
 }
6fbf66fa
 
752caece
 /**
  * Limit the reneg_bytes value when using a small-block (<128 bytes) cipher.
  *
81d882d5
  * @param cipher        The current cipher (may be NULL).
  * @param reneg_bytes   Pointer to the current reneg_bytes, updated if needed.
  *                      May *not* be NULL.
752caece
  */
 static void
81d882d5
 tls_limit_reneg_bytes(const cipher_kt_t *cipher, int *reneg_bytes)
752caece
 {
6d0d0af9
     if (cipher && cipher_kt_insecure(cipher))
752caece
     {
81d882d5
         if (*reneg_bytes == -1) /* Not user-specified */
         {
             msg(M_WARN, "WARNING: cipher with small block size in use, "
                 "reducing reneg-bytes to 64MB to mitigate SWEET32 attacks.");
             *reneg_bytes = 64 * 1024 * 1024;
         }
752caece
     }
 }
 
9e0963c1
 /*
  * Max number of bytes we will add
  * for data structures common to both
  * data and control channel packets.
  * (opcode only).
6fbf66fa
  */
 void
 tls_adjust_frame_parameters(struct frame *frame)
 {
81d882d5
     frame_add_to_extra_frame(frame, 1); /* space for opcode */
6fbf66fa
 }
 
 /*
  * Max number of bytes we will add
81d882d5
  * to control channel packet.
6fbf66fa
  */
 static void
 tls_init_control_channel_frame_parameters(const struct frame *data_channel_frame,
81d882d5
                                           struct frame *frame)
6fbf66fa
 {
81d882d5
     /*
      * frame->extra_frame is already initialized with tls_auth buffer requirements,
      * if --tls-auth is enabled.
      */
 
     /* inherit link MTU and extra_link from data channel */
     frame->link_mtu = data_channel_frame->link_mtu;
     frame->extra_link = data_channel_frame->extra_link;
 
     /* set extra_frame */
     tls_adjust_frame_parameters(frame);
     reliable_ack_adjust_frame_parameters(frame, CONTROL_SEND_ACK_MAX);
     frame_add_to_extra_frame(frame, SID_SIZE + sizeof(packet_id_type));
 
     /* set dynamic link MTU to cap control channel packets at 1250 bytes */
     ASSERT(TUN_LINK_DELTA(frame) < min_int(frame->link_mtu, 1250));
     frame->link_mtu_dynamic = min_int(frame->link_mtu, 1250) - TUN_LINK_DELTA(frame);
6fbf66fa
 }
 
 void
e2a0cad4
 init_ssl_lib(void)
6fbf66fa
 {
81d882d5
     tls_init_lib();
6fbf66fa
 
81d882d5
     crypto_init_lib();
6fbf66fa
 }
 
 void
e2a0cad4
 free_ssl_lib(void)
6fbf66fa
 {
81d882d5
     crypto_uninit_lib();
     prng_uninit();
 
     tls_free_lib();
6fbf66fa
 }
 
 /*
  * OpenSSL library calls pem_password_callback if the
  * private key is protected by a password.
  */
 
 static struct user_pass passbuf; /* GLOBAL */
 
 void
81d882d5
 pem_password_setup(const char *auth_file)
6fbf66fa
 {
81d882d5
     if (!strlen(passbuf.password))
     {
         get_user_pass(&passbuf, auth_file, UP_TYPE_PRIVATE_KEY, GET_USER_PASS_MANAGEMENT|GET_USER_PASS_PASSWORD_ONLY);
     }
6fbf66fa
 }
 
 int
81d882d5
 pem_password_callback(char *buf, int size, int rwflag, void *u)
6fbf66fa
 {
81d882d5
     if (buf)
6fbf66fa
     {
81d882d5
         /* prompt for password even if --askpass wasn't specified */
         pem_password_setup(NULL);
         strncpynt(buf, passbuf.password, size);
         purge_user_pass(&passbuf, false);
6fbf66fa
 
81d882d5
         return strlen(buf);
6fbf66fa
     }
81d882d5
     return 0;
6fbf66fa
 }
 
 /*
  * Auth username/password handling
  */
 
 static bool auth_user_pass_enabled;     /* GLOBAL */
 static struct user_pass auth_user_pass; /* GLOBAL */
 
66b9409b
 #ifdef ENABLE_MANAGEMENT
3cf9dd88
 static char *auth_challenge; /* GLOBAL */
 #endif
 
6fbf66fa
 void
81d882d5
 auth_user_pass_setup(const char *auth_file, const struct static_challenge_info *sci)
6fbf66fa
 {
81d882d5
     auth_user_pass_enabled = true;
     if (!auth_user_pass.defined)
5f31881e
     {
66b9409b
 #ifdef ENABLE_MANAGEMENT
81d882d5
         if (auth_challenge) /* dynamic challenge/response */
         {
             get_user_pass_cr(&auth_user_pass,
                              auth_file,
                              UP_TYPE_AUTH,
                              GET_USER_PASS_MANAGEMENT|GET_USER_PASS_DYNAMIC_CHALLENGE,
                              auth_challenge);
         }
         else if (sci) /* static challenge response */
         {
             int flags = GET_USER_PASS_MANAGEMENT|GET_USER_PASS_STATIC_CHALLENGE;
             if (sci->flags & SC_ECHO)
             {
                 flags |= GET_USER_PASS_STATIC_CHALLENGE_ECHO;
             }
             get_user_pass_cr(&auth_user_pass,
                              auth_file,
                              UP_TYPE_AUTH,
                              flags,
                              sci->challenge_text);
         }
         else
66b9409b
 #endif /* ifdef ENABLE_MANAGEMENT */
81d882d5
         get_user_pass(&auth_user_pass, auth_file, UP_TYPE_AUTH, GET_USER_PASS_MANAGEMENT);
5f31881e
     }
6fbf66fa
 }
 
 /*
  * Disable password caching
  */
 void
81d882d5
 ssl_set_auth_nocache(void)
6fbf66fa
 {
81d882d5
     passbuf.nocache = true;
     auth_user_pass.nocache = true;
57116536
     /* wait for push-reply, because auth-token may invert nocache */
     auth_user_pass.wait_for_push = true;
6fbf66fa
 }
 
 /*
0db046f2
  * Set an authentication token
  */
 void
81d882d5
 ssl_set_auth_token(const char *token)
0db046f2
 {
57116536
     if (auth_user_pass.nocache)
     {
         msg(M_INFO,
             "auth-token received, disabling auth-nocache for the "
             "authentication token");
         auth_user_pass.nocache = false;
     }
 
81d882d5
     set_auth_token(&auth_user_pass, token);
0db046f2
 }
 
 /*
6fbf66fa
  * Forget private key password AND auth-user-pass username/password.
  */
 void
81d882d5
 ssl_purge_auth(const bool auth_user_pass_only)
6fbf66fa
 {
81d882d5
     if (!auth_user_pass_only)
0db046f2
     {
18b5fbdf
 #ifdef ENABLE_PKCS11
81d882d5
         pkcs11_logout();
718526e0
 #endif
81d882d5
         purge_user_pass(&passbuf, true);
0db046f2
     }
81d882d5
     purge_user_pass(&auth_user_pass, true);
66b9409b
 #ifdef ENABLE_MANAGEMENT
81d882d5
     ssl_purge_auth_challenge();
3cf9dd88
 #endif
 }
 
66b9409b
 #ifdef ENABLE_MANAGEMENT
3cf9dd88
 
 void
81d882d5
 ssl_purge_auth_challenge(void)
3cf9dd88
 {
81d882d5
     free(auth_challenge);
     auth_challenge = NULL;
6fbf66fa
 }
 
3cf9dd88
 void
81d882d5
 ssl_put_auth_challenge(const char *cr_str)
3cf9dd88
 {
81d882d5
     ssl_purge_auth_challenge();
     auth_challenge = string_alloc(cr_str, NULL);
3cf9dd88
 }
 
 #endif
 
6fbf66fa
 /*
4b67f984
  * Parse a TLS version string, returning a TLS_VER_x constant.
  * If version string is not recognized and extra == "or-highest",
  * return tls_version_max().
  */
 int
6cb15b90
 tls_version_parse(const char *vstr, const char *extra)
4b67f984
 {
81d882d5
     const int max_version = tls_version_max();
     if (!strcmp(vstr, "1.0") && TLS_VER_1_0 <= max_version)
     {
         return TLS_VER_1_0;
     }
     else if (!strcmp(vstr, "1.1") && TLS_VER_1_1 <= max_version)
     {
         return TLS_VER_1_1;
     }
     else if (!strcmp(vstr, "1.2") && TLS_VER_1_2 <= max_version)
     {
         return TLS_VER_1_2;
     }
8ca9eda1
     else if (!strcmp(vstr, "1.3") && TLS_VER_1_3 <= max_version)
     {
         return TLS_VER_1_3;
     }
81d882d5
     else if (extra && !strcmp(extra, "or-highest"))
     {
         return max_version;
     }
     else
     {
         return TLS_VER_BAD;
     }
4b67f984
 }
 
ce91c187
 /**
  * Load (or possibly reload) the CRL file into the SSL context.
  * No reload is performed under the following conditions:
  * - the CRL file was passed inline
  * - the CRL file was not modified since the last (re)load
  *
  * @param ssl_ctx       The TLS context to use when reloading the CRL
  * @param crl_file      The file name to load the CRL from, or
  *                      "[[INLINE]]" in the case of inline files.
  * @param crl_inline    A string containing the CRL
  */
 static void
 tls_ctx_reload_crl(struct tls_root_ctx *ssl_ctx, const char *crl_file,
81d882d5
                    const char *crl_file_inline)
ce91c187
 {
81d882d5
     /* if something goes wrong with stat(), we'll store 0 as mtime */
     platform_stat_t crl_stat = {0};
 
     /*
      * an inline CRL can't change at runtime, therefore there is no need to
      * reload it. It will be reloaded upon config change + SIGHUP.
      * Use always '1' as dummy timestamp in this case: it will trigger the
      * first load, but will prevent any future reload.
      */
     if (crl_file_inline)
ce91c187
     {
81d882d5
         crl_stat.st_mtime = 1;
ce91c187
     }
81d882d5
     else if (platform_stat(crl_file, &crl_stat) < 0)
ce91c187
     {
81d882d5
         msg(M_WARN, "WARNING: Failed to stat CRL file, not (re)loading CRL.");
         return;
ce91c187
     }
 
81d882d5
     /*
      * Store the CRL if this is the first time or if the file was changed since
      * the last load.
      * Note: Windows does not support tv_nsec.
      */
     if ((ssl_ctx->crl_last_size == crl_stat.st_size)
f3705dd1
         && (ssl_ctx->crl_last_mtime == crl_stat.st_mtime))
81d882d5
     {
         return;
     }
ce91c187
 
f3705dd1
     ssl_ctx->crl_last_mtime = crl_stat.st_mtime;
81d882d5
     ssl_ctx->crl_last_size = crl_stat.st_size;
     backend_tls_ctx_reload_crl(ssl_ctx, crl_file, crl_file_inline);
ce91c187
 }
 
4b67f984
 /*
6fbf66fa
  * Initialize SSL context.
  * All files are in PEM format.
  */
62451786
 void
81d882d5
 init_ssl(const struct options *options, struct tls_root_ctx *new_ctx)
6fbf66fa
 {
81d882d5
     ASSERT(NULL != new_ctx);
62451786
 
81d882d5
     tls_clear_error();
6fbf66fa
 
81d882d5
     if (options->tls_server)
6fbf66fa
     {
81d882d5
         tls_ctx_server_new(new_ctx);
bd9aa06f
 
81d882d5
         if (options->dh_file)
         {
             tls_ctx_load_dh_params(new_ctx, options->dh_file,
                                    options->dh_file_inline);
         }
6fbf66fa
     }
81d882d5
     else                        /* if client */
6fbf66fa
     {
81d882d5
         tls_ctx_client_new(new_ctx);
6fbf66fa
     }
 
aba75874
     /* Restrict allowed certificate crypto algorithms */
     tls_ctx_set_cert_profile(new_ctx, options->tls_cert_profile);
 
26345ba6
     /* Allowable ciphers */
ea4ee313
     /* Since @SECLEVEL also influences loading of certificates, set the
26345ba6
      * cipher restrictions before loading certificates */
     tls_ctx_restrict_ciphers(new_ctx, options->cipher_list);
ea4ee313
     tls_ctx_restrict_ciphers_tls13(new_ctx, options->cipher_list_tls13);
26345ba6
 
0e8a30c0
     if (!tls_ctx_set_options(new_ctx, options->ssl_flags))
     {
         goto err;
     }
ac3e8d62
 
81d882d5
     if (options->pkcs12_file)
6fbf66fa
     {
81d882d5
         if (0 != tls_ctx_load_pkcs12(new_ctx, options->pkcs12_file,
                                      options->pkcs12_file_inline, !options->ca_file))
         {
             goto err;
         }
6fbf66fa
     }
ce98fd24
 #ifdef ENABLE_PKCS11
81d882d5
     else if (options->pkcs11_providers[0])
d1013cfe
     {
81d882d5
         if (!tls_ctx_use_pkcs11(new_ctx, options->pkcs11_id_management, options->pkcs11_id))
         {
             msg(M_WARN, "Cannot load certificate \"%s\" using PKCS#11 interface",
                 options->pkcs11_id);
             goto err;
         }
d1013cfe
     }
ce98fd24
 #endif
93c22ecc
 #ifdef ENABLE_CRYPTOAPI
81d882d5
     else if (options->cryptoapi_cert)
d1013cfe
     {
81d882d5
         tls_ctx_load_cryptoapi(new_ctx, options->cryptoapi_cert);
d1013cfe
     }
6fbf66fa
 #endif
66b9409b
 #ifdef ENABLE_MANAGEMENT
98bfeeb4
     else if (options->management_flags & MF_EXTERNAL_CERT)
81d882d5
     {
98bfeeb4
         char *cert = management_query_cert(management,
                                            options->management_certificate);
         tls_ctx_load_cert_file(new_ctx, INLINE_FILE_TAG, cert);
         free(cert);
f4047d74
     }
cf69617b
 #endif
98bfeeb4
     else if (options->cert_file)
     {
         tls_ctx_load_cert_file(new_ctx, options->cert_file, options->cert_file_inline);
     }
 
     if (options->priv_key_file)
81d882d5
     {
98bfeeb4
         if (0 != tls_ctx_load_priv_file(new_ctx, options->priv_key_file,
                                         options->priv_key_file_inline))
81d882d5
         {
98bfeeb4
             goto err;
81d882d5
         }
98bfeeb4
     }
66b9409b
 #ifdef ENABLE_MANAGEMENT
98bfeeb4
     else if (options->management_flags & MF_EXTERNAL_KEY)
     {
         if (tls_ctx_use_management_external_key(new_ctx))
81d882d5
         {
98bfeeb4
             msg (M_WARN, "Cannot initialize mamagement-external-key");
             goto err;
81d882d5
         }
d67c3147
     }
98bfeeb4
 #endif
6fbf66fa
 
81d882d5
     if (options->ca_file || options->ca_path)
e83b8190
     {
81d882d5
         tls_ctx_load_ca(new_ctx, options->ca_file, options->ca_file_inline,
                         options->ca_path, options->tls_server);
6fbf66fa
     }
e83b8190
 
81d882d5
     /* Load extra certificates that are part of our own certificate
      * chain but shouldn't be included in the verify chain */
     if (options->extra_certs_file)
7966d75a
     {
81d882d5
         tls_ctx_load_extra_certs(new_ctx, options->extra_certs_file, options->extra_certs_file_inline);
7966d75a
     }
 
81d882d5
     /* Check certificate notBefore and notAfter */
     tls_ctx_check_cert_time(new_ctx);
091edd8e
 
81d882d5
     /* Read CRL */
     if (options->crl_file && !(options->ssl_flags & SSLF_CRL_VERIFY_DIR))
160504a2
     {
81d882d5
         tls_ctx_reload_crl(new_ctx, options->crl_file, options->crl_file_inline);
160504a2
     }
 
81d882d5
     /* Once keys and cert are loaded, load ECDH parameters */
     if (options->tls_server)
     {
         tls_ctx_load_ecdh_params(new_ctx, options->ecdh_curve);
     }
609e8131
 
86d8cd68
 #ifdef ENABLE_CRYPTO_MBEDTLS
81d882d5
     /* Personalise the random by mixing in the certificate */
     tls_ctx_personalise_random(new_ctx);
6efeaa2e
 #endif
 
81d882d5
     tls_clear_error();
     return;
6fbf66fa
 
81d882d5
 err:
     tls_clear_error();
     tls_ctx_free(new_ctx);
     return;
6fbf66fa
 }
 
 /*
  * Map internal constants to ascii names.
  */
 static const char *
81d882d5
 state_name(int state)
 {
     switch (state)
     {
         case S_UNDEF:
             return "S_UNDEF";
 
         case S_INITIAL:
             return "S_INITIAL";
 
         case S_PRE_START:
             return "S_PRE_START";
 
         case S_START:
             return "S_START";
 
         case S_SENT_KEY:
             return "S_SENT_KEY";
 
         case S_GOT_KEY:
             return "S_GOT_KEY";
 
         case S_ACTIVE:
             return "S_ACTIVE";
 
         case S_NORMAL_OP:
             return "S_NORMAL_OP";
 
         case S_ERROR:
             return "S_ERROR";
 
         default:
             return "S_???";
6fbf66fa
     }
 }
 
 static const char *
81d882d5
 packet_opcode_name(int op)
 {
     switch (op)
     {
         case P_CONTROL_HARD_RESET_CLIENT_V1:
             return "P_CONTROL_HARD_RESET_CLIENT_V1";
 
         case P_CONTROL_HARD_RESET_SERVER_V1:
             return "P_CONTROL_HARD_RESET_SERVER_V1";
 
         case P_CONTROL_HARD_RESET_CLIENT_V2:
             return "P_CONTROL_HARD_RESET_CLIENT_V2";
 
         case P_CONTROL_HARD_RESET_SERVER_V2:
             return "P_CONTROL_HARD_RESET_SERVER_V2";
 
283290bf
         case P_CONTROL_HARD_RESET_CLIENT_V3:
             return "P_CONTROL_HARD_RESET_CLIENT_V3";
 
81d882d5
         case P_CONTROL_SOFT_RESET_V1:
             return "P_CONTROL_SOFT_RESET_V1";
 
         case P_CONTROL_V1:
             return "P_CONTROL_V1";
 
         case P_ACK_V1:
             return "P_ACK_V1";
 
         case P_DATA_V1:
             return "P_DATA_V1";
 
         case P_DATA_V2:
             return "P_DATA_V2";
 
         default:
             return "P_???";
6fbf66fa
     }
 }
 
 static const char *
81d882d5
 session_index_name(int index)
6fbf66fa
 {
81d882d5
     switch (index)
6fbf66fa
     {
81d882d5
         case TM_ACTIVE:
             return "TM_ACTIVE";
 
         case TM_UNTRUSTED:
             return "TM_UNTRUSTED";
 
         case TM_LAME_DUCK:
             return "TM_LAME_DUCK";
 
         default:
             return "TM_???";
6fbf66fa
     }
 }
 
 /*
  * For debugging.
  */
 static const char *
81d882d5
 print_key_id(struct tls_multi *multi, struct gc_arena *gc)
6fbf66fa
 {
81d882d5
     int i;
     struct buffer out = alloc_buf_gc(256, gc);
6fbf66fa
 
81d882d5
     for (i = 0; i < KEY_SCAN_SIZE; ++i)
6fbf66fa
     {
81d882d5
         struct key_state *ks = multi->key_scan[i];
         buf_printf(&out, " [key#%d state=%s id=%d sid=%s]", i,
                    state_name(ks->state), ks->key_id,
                    session_id_print(&ks->session_id_remote, gc));
6fbf66fa
     }
 
81d882d5
     return BSTR(&out);
6fbf66fa
 }
 
9900e023
 bool
81d882d5
 is_hard_reset(int op, int key_method)
6fbf66fa
 {
81d882d5
     if (!key_method || key_method == 1)
     {
         if (op == P_CONTROL_HARD_RESET_CLIENT_V1 || op == P_CONTROL_HARD_RESET_SERVER_V1)
         {
             return true;
         }
     }
6fbf66fa
 
81d882d5
     if (!key_method || key_method >= 2)
     {
283290bf
         if (op == P_CONTROL_HARD_RESET_CLIENT_V2 || op == P_CONTROL_HARD_RESET_SERVER_V2
             || op == P_CONTROL_HARD_RESET_CLIENT_V3)
81d882d5
         {
             return true;
         }
     }
6fbf66fa
 
81d882d5
     return false;
6fbf66fa
 }
 
4c5c5974
 /** @addtogroup control_processor
  *  @{ */
 
 /** @name Functions for initialization and cleanup of key_state structures
  *  @{ */
 
 /**
  * Initialize a \c key_state structure.
  * @ingroup control_processor
  *
  * This function initializes a \c key_state structure associated with a \c
  * tls_session.  It sets up the structure's SSL-BIO, sets the object's \c
  * key_state.state to \c S_INITIAL, and sets the session ID and key ID two
  * appropriate values based on the \c tls_session's internal state.  It
  * also initializes a new set of structures for the \link reliable
  * Reliability Layer\endlink.
  *
  * @param session      - A pointer to the \c tls_session structure
  *                       associated with the \a ks argument.
  * @param ks           - A pointer to the \c key_state structure to be
  *                       initialized.  This structure should already have
  *                       been allocated before calling this function.
6fbf66fa
  */
 static void
81d882d5
 key_state_init(struct tls_session *session, struct key_state *ks)
 {
     update_time();
 
     CLEAR(*ks);
 
     /*
      * Build TLS object that reads/writes ciphertext
      * to/from memory BIOs.
      */
     key_state_ssl_init(&ks->ks_ssl, &session->opt->ssl_ctx, session->opt->server,
                        session);
 
     /* Set control-channel initiation mode */
     ks->initial_opcode = session->initial_opcode;
     session->initial_opcode = P_CONTROL_SOFT_RESET_V1;
     ks->state = S_INITIAL;
     ks->key_id = session->key_id;
 
     /*
      * key_id increments to KEY_ID_MASK then recycles back to 1.
      * This way you know that if key_id is 0, it is the first key.
      */
     ++session->key_id;
     session->key_id &= P_KEY_ID_MASK;
     if (!session->key_id)
     {
         session->key_id = 1;
     }
 
     /* allocate key source material object */
     ALLOC_OBJ_CLEAR(ks->key_src, struct key_source2);
 
     /* allocate reliability objects */
     ALLOC_OBJ_CLEAR(ks->send_reliable, struct reliable);
     ALLOC_OBJ_CLEAR(ks->rec_reliable, struct reliable);
     ALLOC_OBJ_CLEAR(ks->rec_ack, struct reliable_ack);
 
     /* allocate buffers */
     ks->plaintext_read_buf = alloc_buf(TLS_CHANNEL_BUF_SIZE);
     ks->plaintext_write_buf = alloc_buf(TLS_CHANNEL_BUF_SIZE);
     ks->ack_write_buf = alloc_buf(BUF_SIZE(&session->opt->frame));
     reliable_init(ks->send_reliable, BUF_SIZE(&session->opt->frame),
                   FRAME_HEADROOM(&session->opt->frame), TLS_RELIABLE_N_SEND_BUFFERS,
                   ks->key_id ? false : session->opt->xmit_hold);
     reliable_init(ks->rec_reliable, BUF_SIZE(&session->opt->frame),
                   FRAME_HEADROOM(&session->opt->frame), TLS_RELIABLE_N_REC_BUFFERS,
                   false);
     reliable_set_timeout(ks->send_reliable, session->opt->packet_timeout);
 
     /* init packet ID tracker */
     if (session->opt->replay)
     {
         packet_id_init(&ks->crypto_options.packet_id,
                        session->opt->replay_window, session->opt->replay_time, "SSL",
                        ks->key_id);
     }
 
     ks->crypto_options.pid_persist = NULL;
2d9c6d20
 
90efcacb
 #ifdef MANAGEMENT_DEF_AUTH
81d882d5
     ks->mda_key_id = session->opt->mda_context->mda_key_id_counter++;
90efcacb
 #endif
6fbf66fa
 }
 
4c5c5974
 
 /**
  * Cleanup a \c key_state structure.
  * @ingroup control_processor
  *
  * This function cleans up a \c key_state structure.  It frees the
  * associated SSL-BIO, and the structures allocated for the \link reliable
  * Reliability Layer\endlink.
  *
  * @param ks           - A pointer to the \c key_state structure to be
  *                       cleaned up.
  * @param clear        - Whether the memory allocated for the \a ks object
  *                       should be overwritten with 0s.
  */
6fbf66fa
 static void
81d882d5
 key_state_free(struct key_state *ks, bool clear)
6fbf66fa
 {
81d882d5
     ks->state = S_UNDEF;
6fbf66fa
 
81d882d5
     key_state_ssl_free(&ks->ks_ssl);
6fbf66fa
 
81d882d5
     free_key_ctx_bi(&ks->crypto_options.key_ctx_bi);
     free_buf(&ks->plaintext_read_buf);
     free_buf(&ks->plaintext_write_buf);
     free_buf(&ks->ack_write_buf);
     buffer_list_free(ks->paybuf);
6fbf66fa
 
81d882d5
     if (ks->send_reliable)
6fbf66fa
     {
81d882d5
         reliable_free(ks->send_reliable);
         free(ks->send_reliable);
6fbf66fa
     }
 
81d882d5
     if (ks->rec_reliable)
6fbf66fa
     {
81d882d5
         reliable_free(ks->rec_reliable);
         free(ks->rec_reliable);
6fbf66fa
     }
 
81d882d5
     if (ks->rec_ack)
     {
         free(ks->rec_ack);
     }
6fbf66fa
 
81d882d5
     if (ks->key_src)
     {
         free(ks->key_src);
     }
6fbf66fa
 
81d882d5
     packet_id_free(&ks->crypto_options.packet_id);
6fbf66fa
 
90efcacb
 #ifdef PLUGIN_DEF_AUTH
81d882d5
     key_state_rm_auth_control_file(ks);
47ae8457
 #endif
344ee918
 
81d882d5
     if (clear)
     {
         secure_memzero(ks, sizeof(*ks));
     }
6fbf66fa
 }
 
4c5c5974
 /** @} name Functions for initialization and cleanup of key_state structures */
 
 /** @} addtogroup control_processor */
 
 
3ba6b9ff
 /**
  * Returns whether or not the server should check for username/password
  *
81d882d5
  * @param session       The current TLS session
3ba6b9ff
  *
81d882d5
  * @return              true if username and password verification is enabled,
  *                      false if not.
3ba6b9ff
  */
 static inline bool
 tls_session_user_pass_enabled(struct tls_session *session)
 {
81d882d5
     return (session->opt->auth_user_pass_verify_script
             || plugin_defined(session->opt->plugins, OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY)
3ba6b9ff
 #ifdef MANAGEMENT_DEF_AUTH
81d882d5
             || management_enable_def_auth(management)
3ba6b9ff
 #endif
81d882d5
             );
3ba6b9ff
 }
 
4c5c5974
 
 /** @addtogroup control_processor
  *  @{ */
 
 /** @name Functions for initialization and cleanup of tls_session structures
  *  @{ */
 
 /**
  * Initialize a \c tls_session structure.
  * @ingroup control_processor
  *
  * This function initializes a \c tls_session structure.  This includes
  * generating a random session ID, and initializing the \c KS_PRIMARY \c
  * key_state in the \c tls_session.key array.
  *
  * @param multi        - A pointer to the \c tls_multi structure
  *                       associated with the \a session argument.
  * @param session      - A pointer to the \c tls_session structure to be
  *                       initialized.  This structure should already have
  *                       been allocated before calling this function.
6fbf66fa
  */
 static void
81d882d5
 tls_session_init(struct tls_multi *multi, struct tls_session *session)
6fbf66fa
 {
81d882d5
     struct gc_arena gc = gc_new();
 
     dmsg(D_TLS_DEBUG, "TLS: tls_session_init: entry");
6fbf66fa
 
81d882d5
     CLEAR(*session);
6fbf66fa
 
81d882d5
     /* Set options data to point to parent's option structure */
     session->opt = &multi->opt;
6fbf66fa
 
81d882d5
     /* Randomize session # if it is 0 */
     while (!session_id_defined(&session->session_id))
4cd4899e
     {
81d882d5
         session_id_random(&session->session_id);
4cd4899e
     }
6fbf66fa
 
81d882d5
     /* Are we a TLS server or client? */
     ASSERT(session->opt->key_method >= 1);
     if (session->opt->key_method == 1)
6fbf66fa
     {
81d882d5
         session->initial_opcode = session->opt->server ?
                                   P_CONTROL_HARD_RESET_SERVER_V1 : P_CONTROL_HARD_RESET_CLIENT_V1;
6fbf66fa
     }
81d882d5
     else /* session->opt->key_method >= 2 */
6fbf66fa
     {
283290bf
         if (session->opt->server)
         {
             session->initial_opcode = P_CONTROL_HARD_RESET_SERVER_V2;
         }
         else
         {
             session->initial_opcode = session->opt->tls_crypt_v2 ?
                     P_CONTROL_HARD_RESET_CLIENT_V3 : P_CONTROL_HARD_RESET_CLIENT_V2;
         }
6fbf66fa
     }
 
81d882d5
     /* Initialize control channel authentication parameters */
     session->tls_wrap = session->opt->tls_wrap;
     session->tls_wrap.work = alloc_buf(BUF_SIZE(&session->opt->frame));
6fbf66fa
 
81d882d5
     /* initialize packet ID replay window for --tls-auth */
     packet_id_init(&session->tls_wrap.opt.packet_id,
                    session->opt->replay_window,
                    session->opt->replay_time,
                    "TLS_WRAP", session->key_id);
6fbf66fa
 
81d882d5
     /* load most recent packet-id to replay protect on --tls-auth */
     packet_id_persist_load_obj(session->tls_wrap.opt.pid_persist,
                                &session->tls_wrap.opt.packet_id);
6fbf66fa
 
81d882d5
     key_state_init(session, &session->key[KS_PRIMARY]);
6fbf66fa
 
81d882d5
     dmsg(D_TLS_DEBUG, "TLS: tls_session_init: new session object, sid=%s",
          session_id_print(&session->session_id, &gc));
6fbf66fa
 
81d882d5
     gc_free(&gc);
6fbf66fa
 }
 
4c5c5974
 /**
  * Clean up a \c tls_session structure.
  * @ingroup control_processor
  *
  * This function cleans up a \c tls_session structure.  This includes
  * cleaning up all associated \c key_state structures.
  *
  * @param session      - A pointer to the \c tls_session structure to be
  *                       cleaned up.
  * @param clear        - Whether the memory allocated for the \a session
  *                       object should be overwritten with 0s.
  */
6fbf66fa
 static void
81d882d5
 tls_session_free(struct tls_session *session, bool clear)
6fbf66fa
 {
19dffdbd
     tls_wrap_free(&session->tls_wrap);
c6e24fa3
 
19dffdbd
     for (size_t i = 0; i < KS_SIZE; ++i)
4cd4899e
     {
81d882d5
         key_state_free(&session->key[i], false);
4cd4899e
     }
6fbf66fa
 
81d882d5
     if (session->common_name)
     {
         free(session->common_name);
     }
6fbf66fa
 
81d882d5
     cert_hash_free(session->cert_hash_set);
ec4a500b
 
81d882d5
     if (clear)
     {
         secure_memzero(session, sizeof(*session));
     }
6fbf66fa
 }
 
4c5c5974
 /** @} name Functions for initialization and cleanup of tls_session structures */
 
 /** @} addtogroup control_processor */
 
 
6fbf66fa
 static void
81d882d5
 move_session(struct tls_multi *multi, int dest, int src, bool reinit_src)
6fbf66fa
 {
81d882d5
     msg(D_TLS_DEBUG_LOW, "TLS: move_session: dest=%s src=%s reinit_src=%d",
         session_index_name(dest),
         session_index_name(src),
         reinit_src);
     ASSERT(src != dest);
     ASSERT(src >= 0 && src < TM_SIZE);
     ASSERT(dest >= 0 && dest < TM_SIZE);
     tls_session_free(&multi->session[dest], false);
     multi->session[dest] = multi->session[src];
 
     if (reinit_src)
     {
         tls_session_init(multi, &multi->session[src]);
     }
     else
     {
         secure_memzero(&multi->session[src], sizeof(multi->session[src]));
     }
6fbf66fa
 
81d882d5
     dmsg(D_TLS_DEBUG, "TLS: move_session: exit");
6fbf66fa
 }
 
 static void
81d882d5
 reset_session(struct tls_multi *multi, struct tls_session *session)
6fbf66fa
 {
81d882d5
     tls_session_free(session, false);
     tls_session_init(multi, session);
6fbf66fa
 }
 
 /*
  * Used to determine in how many seconds we should be
  * called again.
  */
 static inline void
4cd4899e
 compute_earliest_wakeup(interval_t *earliest, interval_t seconds_from_now)
 {
81d882d5
     if (seconds_from_now < *earliest)
     {
         *earliest = seconds_from_now;
     }
     if (*earliest < 0)
     {
         *earliest = 0;
     }
6fbf66fa
 }
 
 /*
  * Return true if "lame duck" or retiring key has expired and can
  * no longer be used.
  */
 static inline bool
81d882d5
 lame_duck_must_die(const struct tls_session *session, interval_t *wakeup)
 {
     const struct key_state *lame = &session->key[KS_LAME_DUCK];
     if (lame->state >= S_INITIAL)
     {
         const time_t local_now = now;
         ASSERT(lame->must_die); /* a lame duck key must always have an expiration */
         if (local_now < lame->must_die)
         {
             compute_earliest_wakeup(wakeup, lame->must_die - local_now);
             return false;
         }
         else
         {
             return true;
         }
     }
     else if (lame->state == S_ERROR)
     {
         return true;
     }
     else
     {
         return false;
     }
6fbf66fa
 }
 
 struct tls_multi *
81d882d5
 tls_multi_init(struct tls_options *tls_options)
6fbf66fa
 {
81d882d5
     struct tls_multi *ret;
6fbf66fa
 
81d882d5
     ALLOC_OBJ_CLEAR(ret, struct tls_multi);
6fbf66fa
 
81d882d5
     /* get command line derived options */
     ret->opt = *tls_options;
6fbf66fa
 
81d882d5
     /* set up list of keys to be scanned by data channel encrypt and decrypt routines */
     ASSERT(SIZE(ret->key_scan) == 3);
     ret->key_scan[0] = &ret->session[TM_ACTIVE].key[KS_PRIMARY];
     ret->key_scan[1] = &ret->session[TM_ACTIVE].key[KS_LAME_DUCK];
     ret->key_scan[2] = &ret->session[TM_LAME_DUCK].key[KS_LAME_DUCK];
6fbf66fa
 
81d882d5
     /* By default not use P_DATA_V2 */
     ret->use_peer_id = false;
65eedc35
 
81d882d5
     return ret;
6fbf66fa
 }
 
 void
81d882d5
 tls_multi_init_finalize(struct tls_multi *multi, const struct frame *frame)
6fbf66fa
 {
81d882d5
     tls_init_control_channel_frame_parameters(frame, &multi->opt.frame);
 
     /* initialize the active and untrusted sessions */
6fbf66fa
 
81d882d5
     tls_session_init(multi, &multi->session[TM_ACTIVE]);
6fbf66fa
 
81d882d5
     if (!multi->opt.single_session)
     {
         tls_session_init(multi, &multi->session[TM_UNTRUSTED]);
     }
6fbf66fa
 }
 
 /*
  * Initialize and finalize a standalone tls-auth verification object.
  */
 
 struct tls_auth_standalone *
81d882d5
 tls_auth_standalone_init(struct tls_options *tls_options,
                          struct gc_arena *gc)
6fbf66fa
 {
81d882d5
     struct tls_auth_standalone *tas;
6fbf66fa
 
81d882d5
     ALLOC_OBJ_CLEAR_GC(tas, struct tls_auth_standalone, gc);
6fbf66fa
 
81d882d5
     tas->tls_wrap = tls_options->tls_wrap;
c6e24fa3
 
81d882d5
     /*
      * Standalone tls-auth is in read-only mode with respect to TLS
      * control channel state.  After we build a new client instance
      * object, we will process this session-initiating packet for real.
      */
     tas->tls_wrap.opt.flags |= CO_IGNORE_PACKET_ID;
6fbf66fa
 
81d882d5
     /* get initial frame parms, still need to finalize */
     tas->frame = tls_options->frame;
6fbf66fa
 
81d882d5
     return tas;
6fbf66fa
 }
 
 void
81d882d5
 tls_auth_standalone_finalize(struct tls_auth_standalone *tas,
                              const struct frame *frame)
6fbf66fa
 {
81d882d5
     tls_init_control_channel_frame_parameters(frame, &tas->frame);
6fbf66fa
 }
 
 /*
  * Set local and remote option compatibility strings.
  * Used to verify compatibility of local and remote option
  * sets.
  */
 void
81d882d5
 tls_multi_init_set_options(struct tls_multi *multi,
                            const char *local,
                            const char *remote)
6fbf66fa
 {
 #ifdef ENABLE_OCC
81d882d5
     /* initialize options string */
     multi->opt.local_options = local;
     multi->opt.remote_options = remote;
6fbf66fa
 #endif
 }
 
897f8be4
 /*
  * Cleanup a tls_multi structure and free associated memory allocations.
4c5c5974
  */
6fbf66fa
 void
81d882d5
 tls_multi_free(struct tls_multi *multi, bool clear)
6fbf66fa
 {
81d882d5
     int i;
6fbf66fa
 
81d882d5
     ASSERT(multi);
6fbf66fa
 
5733ef66
 #ifdef MANAGEMENT_DEF_AUTH
81d882d5
     man_def_auth_set_client_reason(multi, NULL);
aaf72974
 
a8be7379
 #endif
0a48ae36
 #if P2MP_SERVER
81d882d5
     free(multi->peer_info);
5733ef66
 #endif
 
81d882d5
     if (multi->locked_cn)
     {
         free(multi->locked_cn);
     }
6fbf66fa
 
81d882d5
     if (multi->locked_username)
     {
         free(multi->locked_username);
     }
71b557ba
 
81d882d5
     cert_hash_free(multi->locked_cert_hash_set);
ec4a500b
 
81d882d5
     if (multi->auth_token)
270dc911
     {
81d882d5
         secure_memzero(multi->auth_token, AUTH_TOKEN_SIZE);
         free(multi->auth_token);
270dc911
     }
 
81d882d5
     free(multi->remote_ciphername);
6e5ad2fa
 
81d882d5
     for (i = 0; i < TM_SIZE; ++i)
4cd4899e
     {
81d882d5
         tls_session_free(&multi->session[i], false);
4cd4899e
     }
6fbf66fa
 
81d882d5
     if (clear)
     {
         secure_memzero(multi, sizeof(*multi));
     }
6fbf66fa
 
81d882d5
     free(multi);
6fbf66fa
 }
 
4c5c5974
 
6fbf66fa
 /*
  * Move a packet authentication HMAC + related fields to or from the front
  * of the buffer so it can be processed by encrypt/decrypt.
  */
 
 /*
  * Dependent on hmac size, opcode size, and session_id size.
  * Will assert if too small.
  */
 #define SWAP_BUF_SIZE 256
 
 static bool
81d882d5
 swap_hmac(struct buffer *buf, const struct crypto_options *co, bool incoming)
6fbf66fa
 {
81d882d5
     const struct key_ctx *ctx;
6fbf66fa
 
81d882d5
     ASSERT(co);
6fbf66fa
 
81d882d5
     ctx = (incoming ? &co->key_ctx_bi.decrypt : &co->key_ctx_bi.encrypt);
     ASSERT(ctx->hmac);
6fbf66fa
 
81d882d5
     {
         /* hmac + packet_id (8 bytes) */
         const int hmac_size = hmac_ctx_size(ctx->hmac) + packet_id_size(true);
6fbf66fa
 
81d882d5
         /* opcode + session_id */
         const int osid_size = 1 + SID_SIZE;
6fbf66fa
 
81d882d5
         int e1, e2;
         uint8_t *b = BPTR(buf);
         uint8_t buf1[SWAP_BUF_SIZE];
         uint8_t buf2[SWAP_BUF_SIZE];
6fbf66fa
 
81d882d5
         if (incoming)
         {
             e1 = osid_size;
             e2 = hmac_size;
         }
         else
         {
             e1 = hmac_size;
             e2 = osid_size;
         }
 
         ASSERT(e1 <= SWAP_BUF_SIZE && e2 <= SWAP_BUF_SIZE);
 
         if (buf->len >= e1 + e2)
         {
             memcpy(buf1, b, e1);
             memcpy(buf2, b + e1, e2);
             memcpy(b, buf2, e2);
             memcpy(b + e2, buf1, e1);
             return true;
         }
         else
         {
             return false;
         }
     }
6fbf66fa
 }
 
 #undef SWAP_BUF_SIZE
 
 /*
  * Write a control channel authentication record.
  */
 static void
81d882d5
 write_control_auth(struct tls_session *session,
                    struct key_state *ks,
                    struct buffer *buf,
                    struct link_socket_actual **to_link_addr,
                    int opcode,
                    int max_ack,
                    bool prepend_ack)
6fbf66fa
 {
81d882d5
     uint8_t header = ks->key_id | (opcode << P_OPCODE_SHIFT);
     struct buffer null = clear_buf();
6fbf66fa
 
81d882d5
     ASSERT(link_socket_actual_defined(&ks->remote_addr));
     ASSERT(reliable_ack_write
                (ks->rec_ack, buf, &ks->session_id_remote, max_ack, prepend_ack));
c6e24fa3
 
19dffdbd
     msg(D_TLS_DEBUG, "%s(): %s", __func__, packet_opcode_name(opcode));
 
81d882d5
     if (session->tls_wrap.mode == TLS_WRAP_AUTH
         || session->tls_wrap.mode == TLS_WRAP_NONE)
c6e24fa3
     {
81d882d5
         ASSERT(session_id_write_prepend(&session->session_id, buf));
         ASSERT(buf_write_prepend(buf, &header, sizeof(header)));
c6e24fa3
     }
81d882d5
     if (session->tls_wrap.mode == TLS_WRAP_AUTH)
6fbf66fa
     {
81d882d5
         /* no encryption, only write hmac */
         openvpn_encrypt(buf, null, &session->tls_wrap.opt);
         ASSERT(swap_hmac(buf, &session->tls_wrap.opt, false));
c6e24fa3
     }
81d882d5
     else if (session->tls_wrap.mode == TLS_WRAP_CRYPT)
c6e24fa3
     {
81d882d5
         ASSERT(buf_init(&session->tls_wrap.work, buf->offset));
         ASSERT(buf_write(&session->tls_wrap.work, &header, sizeof(header)));
         ASSERT(session_id_write(&session->session_id, &session->tls_wrap.work));
19dffdbd
         if (!tls_crypt_wrap(buf, &session->tls_wrap.work, &session->tls_wrap.opt))
81d882d5
         {
             buf->len = 0;
             return;
         }
19dffdbd
 
         if (opcode == P_CONTROL_HARD_RESET_CLIENT_V3)
         {
             if (!buf_copy(&session->tls_wrap.work,
                           session->tls_wrap.tls_crypt_v2_wkc))
             {
                 msg(D_TLS_ERRORS, "Could not append tls-crypt-v2 client key");
                 buf->len = 0;
                 return;
             }
         }
 
         /* Don't change the original data in buf, it's used by the reliability
          * layer to resend on failure. */
         *buf = session->tls_wrap.work;
6fbf66fa
     }
81d882d5
     *to_link_addr = &ks->remote_addr;
6fbf66fa
 }
 
 /*
  * Read a control channel authentication record.
  */
 static bool
81d882d5
 read_control_auth(struct buffer *buf,
                   struct tls_wrap_ctx *ctx,
ff931c5e
                   const struct link_socket_actual *from,
                   const struct tls_options *opt)
6fbf66fa
 {
81d882d5
     struct gc_arena gc = gc_new();
     bool ret = false;
6fbf66fa
 
19dffdbd
     const uint8_t opcode = *(BPTR(buf)) >> P_OPCODE_SHIFT;
     if (opcode == P_CONTROL_HARD_RESET_CLIENT_V3
ff931c5e
         && !tls_crypt_v2_extract_client_key(buf, ctx, opt))
19dffdbd
     {
         msg (D_TLS_ERRORS,
              "TLS Error: can not extract tls-crypt-v2 client key from %s",
              print_link_socket_actual(from, &gc));
         goto cleanup;
     }
 
81d882d5
     if (ctx->mode == TLS_WRAP_AUTH)
6fbf66fa
     {
81d882d5
         struct buffer null = clear_buf();
6fbf66fa
 
81d882d5
         /* move the hmac record to the front of the packet */
         if (!swap_hmac(buf, &ctx->opt, true))
         {
             msg(D_TLS_ERRORS,
                 "TLS Error: cannot locate HMAC in incoming packet from %s",
                 print_link_socket_actual(from, &gc));
             gc_free(&gc);
             return false;
         }
6fbf66fa
 
81d882d5
         /* authenticate only (no decrypt) and remove the hmac record
          * from the head of the buffer */
         openvpn_decrypt(buf, null, &ctx->opt, NULL, BPTR(buf));
         if (!buf->len)
         {
             msg(D_TLS_ERRORS,
                 "TLS Error: incoming packet authentication failed from %s",
                 print_link_socket_actual(from, &gc));
             goto cleanup;
         }
6fbf66fa
 
     }
81d882d5
     else if (ctx->mode == TLS_WRAP_CRYPT)
c6e24fa3
     {
fca89379
         struct buffer tmp = alloc_buf_gc(buf_forward_capacity_total(buf), &gc);
81d882d5
         if (!tls_crypt_unwrap(buf, &tmp, &ctx->opt))
         {
             msg(D_TLS_ERRORS, "TLS Error: tls-crypt unwrapping failed from %s",
                 print_link_socket_actual(from, &gc));
             goto cleanup;
         }
         ASSERT(buf_init(buf, buf->offset));
         ASSERT(buf_copy(buf, &tmp));
fca89379
         buf_clear(&tmp);
c6e24fa3
     }
19dffdbd
     else if (ctx->tls_crypt_v2_server_key.cipher)
     {
         /* If tls-crypt-v2 is enabled, require *some* wrapping */
         msg(D_TLS_ERRORS, "TLS Error: could not determine wrapping from %s",
             print_link_socket_actual(from, &gc));
         /* TODO Do we want to support using tls-crypt-v2 and no control channel
          * wrapping at all simultaneously?  That would allow server admins to
          * upgrade clients one-by-one without running a second instance, but we
          * should not enable it by default because it breaks DoS-protection.
          * So, add something like --tls-crypt-v2-allow-insecure-fallback ? */
         goto cleanup;
     }
6fbf66fa
 
81d882d5
     if (ctx->mode == TLS_WRAP_NONE || ctx->mode == TLS_WRAP_AUTH)
c6e24fa3
     {
81d882d5
         /* advance buffer pointer past opcode & session_id since our caller
          * already read it */
         buf_advance(buf, SID_SIZE + 1);
c6e24fa3
     }
6fbf66fa
 
81d882d5
     ret = true;
c6e24fa3
 cleanup:
81d882d5
     gc_free(&gc);
     return ret;
6fbf66fa
 }
 
 /*
  * For debugging, print contents of key_source2 structure.
  */
 
 static void
81d882d5
 key_source_print(const struct key_source *k,
                  const char *prefix)
6fbf66fa
 {
81d882d5
     struct gc_arena gc = gc_new();
 
     VALGRIND_MAKE_READABLE((void *)k->pre_master, sizeof(k->pre_master));
     VALGRIND_MAKE_READABLE((void *)k->random1, sizeof(k->random1));
     VALGRIND_MAKE_READABLE((void *)k->random2, sizeof(k->random2));
 
     dmsg(D_SHOW_KEY_SOURCE,
          "%s pre_master: %s",
          prefix,
          format_hex(k->pre_master, sizeof(k->pre_master), 0, &gc));
     dmsg(D_SHOW_KEY_SOURCE,
          "%s random1: %s",
          prefix,
          format_hex(k->random1, sizeof(k->random1), 0, &gc));
     dmsg(D_SHOW_KEY_SOURCE,
          "%s random2: %s",
          prefix,
          format_hex(k->random2, sizeof(k->random2), 0, &gc));
 
     gc_free(&gc);
6fbf66fa
 }
 
 static void
81d882d5
 key_source2_print(const struct key_source2 *k)
6fbf66fa
 {
81d882d5
     key_source_print(&k->client, "Client");
     key_source_print(&k->server, "Server");
6fbf66fa
 }
 
 /*
eab0cf2d
  * Generate the hash required by for the \c tls1_PRF function.
6fbf66fa
  *
81d882d5
  * @param md_kt         Message digest to use
  * @param sec           Secret to base the hash on
  * @param sec_len       Length of the secret
  * @param seed          Seed to hash
  * @param seed_len      Length of the seed
  * @param out           Output buffer
  * @param olen          Length of the output buffer
6fbf66fa
  */
72bcdfdc
 static void
eab0cf2d
 tls1_P_hash(const md_kt_t *md_kt,
81d882d5
             const uint8_t *sec,
             int sec_len,
             const uint8_t *seed,
             int seed_len,
             uint8_t *out,
             int olen)
 {
     struct gc_arena gc = gc_new();
     int chunk;
aba98e90
     hmac_ctx_t *ctx;
     hmac_ctx_t *ctx_tmp;
81d882d5
     uint8_t A1[MAX_HMAC_KEY_LENGTH];
     unsigned int A1_len;
6fbf66fa
 
 #ifdef ENABLE_DEBUG
81d882d5
     const int olen_orig = olen;
     const uint8_t *out_orig = out;
6fbf66fa
 #endif
eab0cf2d
 
aba98e90
     ctx = hmac_ctx_new();
     ctx_tmp = hmac_ctx_new();
eab0cf2d
 
81d882d5
     dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash sec: %s", format_hex(sec, sec_len, 0, &gc));
     dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash seed: %s", format_hex(seed, seed_len, 0, &gc));
6fbf66fa
 
81d882d5
     chunk = md_kt_size(md_kt);
     A1_len = md_kt_size(md_kt);
6fbf66fa
 
aba98e90
     hmac_ctx_init(ctx, sec, sec_len, md_kt);
     hmac_ctx_init(ctx_tmp, sec, sec_len, md_kt);
eab0cf2d
 
aba98e90
     hmac_ctx_update(ctx,seed,seed_len);
     hmac_ctx_final(ctx, A1);
6fbf66fa
 
81d882d5
     for (;; )
6fbf66fa
     {
aba98e90
         hmac_ctx_reset(ctx);
         hmac_ctx_reset(ctx_tmp);
         hmac_ctx_update(ctx,A1,A1_len);
         hmac_ctx_update(ctx_tmp,A1,A1_len);
         hmac_ctx_update(ctx,seed,seed_len);
6fbf66fa
 
81d882d5
         if (olen > chunk)
         {
aba98e90
             hmac_ctx_final(ctx, out);
81d882d5
             out += chunk;
             olen -= chunk;
aba98e90
             hmac_ctx_final(ctx_tmp, A1); /* calc the next A1 value */
81d882d5
         }
         else    /* last one */
         {
aba98e90
             hmac_ctx_final(ctx, A1);
81d882d5
             memcpy(out,A1,olen);
             break;
         }
6fbf66fa
     }
aba98e90
     hmac_ctx_cleanup(ctx);
     hmac_ctx_free(ctx);
     hmac_ctx_cleanup(ctx_tmp);
     hmac_ctx_free(ctx_tmp);
81d882d5
     secure_memzero(A1, sizeof(A1));
6fbf66fa
 
81d882d5
     dmsg(D_SHOW_KEY_SOURCE, "tls1_P_hash out: %s", format_hex(out_orig, olen_orig, 0, &gc));
     gc_free(&gc);
6fbf66fa
 }
 
eab0cf2d
 /*
  * Use the TLS PRF function for generating data channel keys.
  * This code is based on the OpenSSL library.
  *
  * TLS generates keys as such:
  *
  * master_secret[48] = PRF(pre_master_secret[48], "master secret",
  *                         ClientHello.random[32] + ServerHello.random[32])
  *
  * key_block[] = PRF(SecurityParameters.master_secret[48],
  *                 "key expansion",
  *                 SecurityParameters.server_random[32] +
  *                 SecurityParameters.client_random[32]);
  *
  * Notes:
  *
  * (1) key_block contains a full set of 4 keys.
  * (2) The pre-master secret is generated by the client.
  */
6fbf66fa
 static void
66407e11
 tls1_PRF(const uint8_t *label,
81d882d5
          int label_len,
          const uint8_t *sec,
          int slen,
          uint8_t *out1,
          int olen)
6fbf66fa
 {
81d882d5
     struct gc_arena gc = gc_new();
     const md_kt_t *md5 = md_kt_get("MD5");
     const md_kt_t *sha1 = md_kt_get("SHA1");
     int len,i;
     const uint8_t *S1,*S2;
     uint8_t *out2;
6fbf66fa
 
81d882d5
     out2 = (uint8_t *) gc_malloc(olen, false, &gc);
6fbf66fa
 
81d882d5
     len = slen/2;
     S1 = sec;
     S2 = &(sec[len]);
     len += (slen&1); /* add for odd, make longer */
6fbf66fa
 
81d882d5
     tls1_P_hash(md5,S1,len,label,label_len,out1,olen);
     tls1_P_hash(sha1,S2,len,label,label_len,out2,olen);
6fbf66fa
 
81d882d5
     for (i = 0; i<olen; i++)
4cd4899e
     {
81d882d5
         out1[i] ^= out2[i];
4cd4899e
     }
6fbf66fa
 
81d882d5
     secure_memzero(out2, olen);
6fbf66fa
 
81d882d5
     dmsg(D_SHOW_KEY_SOURCE, "tls1_PRF out[%d]: %s", olen, format_hex(out1, olen, 0, &gc));
6fbf66fa
 
81d882d5
     gc_free(&gc);
6fbf66fa
 }
 
 static void
81d882d5
 openvpn_PRF(const uint8_t *secret,
             int secret_len,
             const char *label,
             const uint8_t *client_seed,
             int client_seed_len,
             const uint8_t *server_seed,
             int server_seed_len,
             const struct session_id *client_sid,
             const struct session_id *server_sid,
             uint8_t *output,
             int output_len)
6fbf66fa
 {
81d882d5
     /* concatenate seed components */
6fbf66fa
 
81d882d5
     struct buffer seed = alloc_buf(strlen(label)
                                    + client_seed_len
                                    + server_seed_len
                                    + SID_SIZE * 2);
6fbf66fa
 
81d882d5
     ASSERT(buf_write(&seed, label, strlen(label)));
     ASSERT(buf_write(&seed, client_seed, client_seed_len));
     ASSERT(buf_write(&seed, server_seed, server_seed_len));
6fbf66fa
 
81d882d5
     if (client_sid)
     {
         ASSERT(buf_write(&seed, client_sid->id, SID_SIZE));
     }
     if (server_sid)
     {
         ASSERT(buf_write(&seed, server_sid->id, SID_SIZE));
     }
6fbf66fa
 
81d882d5
     /* compute PRF */
     tls1_PRF(BPTR(&seed), BLEN(&seed), secret, secret_len, output, output_len);
6fbf66fa
 
81d882d5
     buf_clear(&seed);
     free_buf(&seed);
6fbf66fa
 
81d882d5
     VALGRIND_MAKE_READABLE((void *)output, output_len);
6fbf66fa
 }
 
81d882d5
 /*
6fbf66fa
  * Using source entropy from local and remote hosts, mix into
  * master key.
  */
 static bool
81d882d5
 generate_key_expansion(struct key_ctx_bi *key,
                        const struct key_type *key_type,
                        const struct key_source2 *key_src,
                        const struct session_id *client_sid,
                        const struct session_id *server_sid,
                        bool server)
 {
     uint8_t master[48] = { 0 };
     struct key2 key2 = { 0 };
     bool ret = false;
 
     if (key->initialized)
     {
         msg(D_TLS_ERRORS, "TLS Error: key already initialized");
         goto exit;
     }
 
     /* debugging print of source key material */
     key_source2_print(key_src);
 
     /* compute master secret */
     openvpn_PRF(key_src->client.pre_master,
                 sizeof(key_src->client.pre_master),
                 KEY_EXPANSION_ID " master secret",
                 key_src->client.random1,
                 sizeof(key_src->client.random1),
                 key_src->server.random1,
                 sizeof(key_src->server.random1),
                 NULL,
                 NULL,
                 master,
                 sizeof(master));
 
     /* compute key expansion */
     openvpn_PRF(master,
                 sizeof(master),
                 KEY_EXPANSION_ID " key expansion",
                 key_src->client.random2,
                 sizeof(key_src->client.random2),
                 key_src->server.random2,
                 sizeof(key_src->server.random2),
                 client_sid,
                 server_sid,
                 (uint8_t *)key2.keys,
                 sizeof(key2.keys));
 
     key2.n = 2;
 
     key2_print(&key2, key_type, "Master Encrypt", "Master Decrypt");
 
     /* check for weak keys */
     for (int i = 0; i < 2; ++i)
     {
         fixup_key(&key2.keys[i], key_type);
         if (!check_key(&key2.keys[i], key_type))
         {
             msg(D_TLS_ERRORS, "TLS Error: Bad dynamic key generated");
             goto exit;
         }
     }
 
     /* Initialize OpenSSL key contexts */
974513ea
     int key_direction = server ? KEY_DIRECTION_INVERSE : KEY_DIRECTION_NORMAL;
     init_key_ctx_bi(key, &key2, key_direction, key_type, "Data Channel");
81d882d5
 
     /* Initialize implicit IVs */
     key_ctx_update_implicit_iv(&key->encrypt, key2.keys[(int)server].hmac,
                                MAX_HMAC_KEY_LENGTH);
     key_ctx_update_implicit_iv(&key->decrypt, key2.keys[1-(int)server].hmac,
                                MAX_HMAC_KEY_LENGTH);
 
     ret = true;
 
 exit:
     secure_memzero(&master, sizeof(master));
     secure_memzero(&key2, sizeof(key2));
 
     return ret;
6fbf66fa
 }
 
66407e11
 static void
4cd4899e
 key_ctx_update_implicit_iv(struct key_ctx *ctx, uint8_t *key, size_t key_len)
 {
81d882d5
     const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt(ctx->cipher);
66407e11
 
81d882d5
     /* Only use implicit IV in AEAD cipher mode, where HMAC key is not used */
     if (cipher_kt_mode_aead(cipher_kt))
66407e11
     {
81d882d5
         size_t impl_iv_len = 0;
         ASSERT(cipher_kt_iv_size(cipher_kt) >= OPENVPN_AEAD_MIN_IV_LEN);
         impl_iv_len = cipher_kt_iv_size(cipher_kt) - sizeof(packet_id_type);
         ASSERT(impl_iv_len <= OPENVPN_MAX_IV_LENGTH);
         ASSERT(impl_iv_len <= key_len);
         memcpy(ctx->implicit_iv, key, impl_iv_len);
         ctx->implicit_iv_len = impl_iv_len;
66407e11
     }
 }
 
6e5ad2fa
 bool
 tls_item_in_cipher_list(const char *item, const char *list)
d728ebed
 {
81d882d5
     char *tmp_ciphers = string_alloc(list, NULL);
     char *tmp_ciphers_orig = tmp_ciphers;
d728ebed
 
81d882d5
     const char *token = strtok(tmp_ciphers, ":");
     while (token)
d728ebed
     {
81d882d5
         if (0 == strcmp(token, item))
         {
             break;
         }
         token = strtok(NULL, ":");
d728ebed
     }
81d882d5
     free(tmp_ciphers_orig);
d728ebed
 
81d882d5
     return token != NULL;
d728ebed
 }
 
6e5ad2fa
 void
 tls_poor_mans_ncp(struct options *o, const char *remote_ciphername)
 {
81d882d5
     if (o->ncp_enabled && remote_ciphername
         && 0 != strcmp(o->ciphername, remote_ciphername))
6e5ad2fa
     {
81d882d5
         if (tls_item_in_cipher_list(remote_ciphername, o->ncp_ciphers))
         {
             o->ciphername = string_alloc(remote_ciphername, &o->gc);
             msg(D_TLS_DEBUG_LOW, "Using peer cipher '%s'", o->ciphername);
         }
6e5ad2fa
     }
 }
 
e2ffdb7c
 /**
  * Generate data channel keys for the supplied TLS session.
  *
  * This erases the source material used to generate the data channel keys, and
  * can thus be called only once per session.
  */
 static bool
 tls_session_generate_data_channel_keys(struct tls_session *session)
97894360
 {
81d882d5
     bool ret = false;
     struct key_state *ks = &session->key[KS_PRIMARY];   /* primary key */
     const struct session_id *client_sid = session->opt->server ?
                                           &ks->session_id_remote : &session->session_id;
     const struct session_id *server_sid = !session->opt->server ?
                                           &ks->session_id_remote : &session->session_id;
 
     ASSERT(ks->authenticated);
 
     ks->crypto_options.flags = session->opt->crypto_flags;
     if (!generate_key_expansion(&ks->crypto_options.key_ctx_bi,
                                 &session->opt->key_type, ks->key_src, client_sid, server_sid,
                                 session->opt->server))
e2ffdb7c
     {
81d882d5
         msg(D_TLS_ERRORS, "TLS Error: generate_key_expansion failed");
         goto cleanup;
e2ffdb7c
     }
81d882d5
     tls_limit_reneg_bytes(session->opt->key_type.cipher,
                           &session->opt->renegotiate_bytes);
e2ffdb7c
 
81d882d5
     ret = true;
e2ffdb7c
 cleanup:
81d882d5
     secure_memzero(ks->key_src, sizeof(*ks->key_src));
     return ret;
e2ffdb7c
 }
 
 bool
 tls_session_update_crypto_params(struct tls_session *session,
3be9a1c1
                                  struct options *options, struct frame *frame)
e2ffdb7c
 {
81d882d5
     if (!session->opt->server
         && 0 != strcmp(options->ciphername, session->opt->config_ciphername)
         && !tls_item_in_cipher_list(options->ciphername, options->ncp_ciphers))
d728ebed
     {
81d882d5
         msg(D_TLS_ERRORS, "Error: pushed cipher not allowed - %s not in %s or %s",
             options->ciphername, session->opt->config_ciphername,
             options->ncp_ciphers);
3be9a1c1
         /* undo cipher push, abort connection setup */
         options->ciphername = session->opt->config_ciphername;
81d882d5
         return false;
d728ebed
     }
 
d4071dd1
     if (strcmp(options->ciphername, session->opt->config_ciphername))
     {
         msg(D_HANDSHAKE, "Data Channel: using negotiated cipher '%s'",
             options->ciphername);
956bb1c3
         if (options->keysize)
         {
             msg(D_HANDSHAKE, "NCP: overriding user-set keysize with default");
             options->keysize = 0;
         }
d4071dd1
     }
 
81d882d5
     init_key_type(&session->opt->key_type, options->ciphername,
                   options->authname, options->keysize, true, true);
97894360
 
81d882d5
     bool packet_id_long_form = cipher_kt_mode_ofb_cfb(session->opt->key_type.cipher);
     session->opt->crypto_flags &= ~(CO_PACKET_ID_LONG_FORM);
     if (packet_id_long_form)
     {
         session->opt->crypto_flags |= CO_PACKET_ID_LONG_FORM;
     }
97894360
 
81d882d5
     /* Update frame parameters: undo worst-case overhead, add actual overhead */
ed31cf2a
     frame_remove_from_extra_frame(frame, crypto_max_overhead());
81d882d5
     crypto_adjust_frame_parameters(frame, &session->opt->key_type,
ef910e3e
                                    options->replay, packet_id_long_form);
81d882d5
     frame_finalize(frame, options->ce.link_mtu_defined, options->ce.link_mtu,
                    options->ce.tun_mtu_defined, options->ce.tun_mtu);
     frame_init_mssfix(frame, options);
     frame_print(frame, D_MTU_INFO, "Data Channel MTU parms");
97894360
 
81d882d5
     return tls_session_generate_data_channel_keys(session);
97894360
 }
 
6fbf66fa
 static bool
81d882d5
 random_bytes_to_buf(struct buffer *buf,
                     uint8_t *out,
                     int outlen)
6fbf66fa
 {
81d882d5
     if (!rand_bytes(out, outlen))
     {
         msg(M_FATAL, "ERROR: Random number generator cannot obtain entropy for key generation [SSL]");
     }
     if (!buf_write(buf, out, outlen))
     {
         return false;
     }
     return true;
6fbf66fa
 }
 
 static bool
81d882d5
 key_source2_randomize_write(struct key_source2 *k2,
                             struct buffer *buf,
                             bool server)
6fbf66fa
 {
81d882d5
     struct key_source *k = &k2->client;
     if (server)
     {
         k = &k2->server;
     }
6fbf66fa
 
81d882d5
     CLEAR(*k);
6fbf66fa
 
81d882d5
     if (!server)
6fbf66fa
     {
81d882d5
         if (!random_bytes_to_buf(buf, k->pre_master, sizeof(k->pre_master)))
         {
             return false;
         }
6fbf66fa
     }
 
81d882d5
     if (!random_bytes_to_buf(buf, k->random1, sizeof(k->random1)))
     {
         return false;
     }
     if (!random_bytes_to_buf(buf, k->random2, sizeof(k->random2)))
     {
         return false;
     }
6fbf66fa
 
81d882d5
     return true;
6fbf66fa
 }
 
 static int
81d882d5
 key_source2_read(struct key_source2 *k2,
                  struct buffer *buf,
                  bool server)
6fbf66fa
 {
81d882d5
     struct key_source *k = &k2->client;
6fbf66fa
 
81d882d5
     if (!server)
     {
         k = &k2->server;
     }
6fbf66fa
 
81d882d5
     CLEAR(*k);
6fbf66fa
 
81d882d5
     if (server)
6fbf66fa
     {
81d882d5
         if (!buf_read(buf, k->pre_master, sizeof(k->pre_master)))
         {
             return 0;
         }
6fbf66fa
     }
 
81d882d5
     if (!buf_read(buf, k->random1, sizeof(k->random1)))
     {
         return 0;
     }
     if (!buf_read(buf, k->random2, sizeof(k->random2)))
     {
         return 0;
     }
6fbf66fa
 
81d882d5
     return 1;
6fbf66fa
 }
 
dc85dae6
 static void
81d882d5
 flush_payload_buffer(struct key_state *ks)
dc85dae6
 {
81d882d5
     struct buffer *b;
57513aac
 
81d882d5
     while ((b = buffer_list_peek(ks->paybuf)))
dc85dae6
     {
81d882d5
         key_state_write_plaintext_const(&ks->ks_ssl, b->data, b->len);
         buffer_list_pop(ks->paybuf);
dc85dae6
     }
 }
 
6fbf66fa
 /* true if no in/out acknowledgements pending */
 #define FULL_SYNC \
81d882d5
     (reliable_empty(ks->send_reliable) && reliable_ack_empty(ks->rec_ack))
6fbf66fa
 
 /*
  * Move the active key to the lame duck key and reinitialize the
  * active key.
  */
 static void
81d882d5
 key_state_soft_reset(struct tls_session *session)
6fbf66fa
 {
81d882d5
     struct key_state *ks = &session->key[KS_PRIMARY];      /* primary key */
     struct key_state *ks_lame = &session->key[KS_LAME_DUCK]; /* retiring key */
57513aac
 
81d882d5
     ks->must_die = now + session->opt->transition_window; /* remaining lifetime of old key */
     key_state_free(ks_lame, false);
     *ks_lame = *ks;
6fbf66fa
 
81d882d5
     key_state_init(session, ks);
     ks->session_id_remote = ks_lame->session_id_remote;
     ks->remote_addr = ks_lame->remote_addr;
6fbf66fa
 }
 
 /*
  * Read/write strings from/to a struct buffer with a u16 length prefix.
  */
 
 static bool
81d882d5
 write_empty_string(struct buffer *buf)
fef565a3
 {
81d882d5
     if (!buf_write_u16(buf, 0))
     {
         return false;
     }
     return true;
fef565a3
 }
 
 static bool
81d882d5
 write_string(struct buffer *buf, const char *str, const int maxlen)
6fbf66fa
 {
81d882d5
     const int len = strlen(str) + 1;
     if (len < 1 || (maxlen >= 0 && len > maxlen))
     {
         return false;
     }
     if (!buf_write_u16(buf, len))
     {
         return false;
     }
     if (!buf_write(buf, str, len))
     {
         return false;
     }
     return true;
6fbf66fa
 }
 
 static bool
81d882d5
 read_string(struct buffer *buf, char *str, const unsigned int capacity)
6fbf66fa
 {
81d882d5
     const int len = buf_read_u16(buf);
     if (len < 1 || len > (int)capacity)
     {
         return false;
     }
     if (!buf_read(buf, str, len))
     {
         return false;
     }
     str[len-1] = '\0';
     return true;
6fbf66fa
 }
 
aaf72974
 static char *
81d882d5
 read_string_alloc(struct buffer *buf)
aaf72974
 {
81d882d5
     const int len = buf_read_u16(buf);
     char *str;
aaf72974
 
81d882d5
     if (len < 1)
     {
         return NULL;
     }
     str = (char *) malloc(len);
     check_malloc_return(str);
     if (!buf_read(buf, str, len))
aaf72974
     {
81d882d5
         free(str);
         return NULL;
aaf72974
     }
81d882d5
     str[len-1] = '\0';
     return str;
aaf72974
 }
 
6fbf66fa
 /*
  * Handle the reading and writing of key data to and from
  * the TLS control channel (cleartext).
  */
 
 static bool
81d882d5
 key_method_1_write(struct buffer *buf, struct tls_session *session)
6fbf66fa
 {
81d882d5
     struct key key;
     struct key_state *ks = &session->key[KS_PRIMARY];      /* primary key */
6fbf66fa
 
81d882d5
     ASSERT(session->opt->key_method == 1);
     ASSERT(buf_init(buf, 0));
6fbf66fa
 
81d882d5
     generate_key_random(&key, &session->opt->key_type);
     if (!check_key(&key, &session->opt->key_type))
6fbf66fa
     {
81d882d5
         msg(D_TLS_ERRORS, "TLS Error: Bad encrypting key generated");
         return false;
6fbf66fa
     }
 
81d882d5
     if (!write_key(&key, &session->opt->key_type, buf))
6fbf66fa
     {
81d882d5
         msg(D_TLS_ERRORS, "TLS Error: write_key failed");
         return false;
6fbf66fa
     }
 
81d882d5
     init_key_ctx(&ks->crypto_options.key_ctx_bi.encrypt, &key,
                  &session->opt->key_type, OPENVPN_OP_ENCRYPT,
                  "Data Channel Encrypt");
     secure_memzero(&key, sizeof(key));
6fbf66fa
 
81d882d5
     /* send local options string */
     {
         const char *local_options = local_options_string(session);
         const int optlen = strlen(local_options) + 1;
         if (!buf_write(buf, local_options, optlen))
         {
             msg(D_TLS_ERRORS, "TLS Error: KM1 write options failed");
             return false;
         }
     }
6fbf66fa
 
81d882d5
     return true;
6fbf66fa
 }
 
 static bool
aaf72974
 push_peer_info(struct buffer *buf, struct tls_session *session)
 {
81d882d5
     struct gc_arena gc = gc_new();
     bool ret = false;
aaf72974
 
81d882d5
     if (session->opt->push_peer_info_detail > 0)
aaf72974
     {
81d882d5
         struct env_set *es = session->opt->es;
         struct env_item *e;
         struct buffer out = alloc_buf_gc(512*3, &gc);
aaf72974
 
81d882d5
         /* push version */
         buf_printf(&out, "IV_VER=%s\n", PACKAGE_VERSION);
aaf72974
 
81d882d5
         /* push platform */
aaf72974
 #if defined(TARGET_LINUX)
81d882d5
         buf_printf(&out, "IV_PLAT=linux\n");
aaf72974
 #elif defined(TARGET_SOLARIS)
81d882d5
         buf_printf(&out, "IV_PLAT=solaris\n");
aaf72974
 #elif defined(TARGET_OPENBSD)
81d882d5
         buf_printf(&out, "IV_PLAT=openbsd\n");
aaf72974
 #elif defined(TARGET_DARWIN)
81d882d5
         buf_printf(&out, "IV_PLAT=mac\n");
aaf72974
 #elif defined(TARGET_NETBSD)
81d882d5
         buf_printf(&out, "IV_PLAT=netbsd\n");
aaf72974
 #elif defined(TARGET_FREEBSD)
81d882d5
         buf_printf(&out, "IV_PLAT=freebsd\n");
a55b3cdb
 #elif defined(TARGET_ANDROID)
81d882d5
         buf_printf(&out, "IV_PLAT=android\n");
445b192a
 #elif defined(_WIN32)
81d882d5
         buf_printf(&out, "IV_PLAT=win\n");
aaf72974
 #endif
 
81d882d5
         /* support for P_DATA_V2 */
         buf_printf(&out, "IV_PROTO=2\n");
65eedc35
 
81d882d5
         /* support for Negotiable Crypto Paramters */
         if (session->opt->ncp_enabled
             && (session->opt->mode == MODE_SERVER || session->opt->pull))
         {
             buf_printf(&out, "IV_NCP=2\n");
         }
97894360
 
81d882d5
         /* push compression status */
38d96bd7
 #ifdef USE_COMP
81d882d5
         comp_generate_peer_info_string(&session->opt->comp_options, &out);
6c34e74f
 #endif
 
81d882d5
         if (session->opt->push_peer_info_detail >= 2)
598e03f0
         {
81d882d5
             /* push mac addr */
             struct route_gateway_info rgi;
             get_default_gateway(&rgi);
             if (rgi.flags & RGI_HWADDR_DEFINED)
             {
                 buf_printf(&out, "IV_HWADDR=%s\n", format_hex_ex(rgi.hwaddr, 6, 0, 1, ":", &gc));
             }
             buf_printf(&out, "IV_SSL=%s\n", get_ssl_library_version() );
445b192a
 #if defined(_WIN32)
81d882d5
             buf_printf(&out, "IV_PLAT_VER=%s\n", win32_version_string(&gc, false));
cdc65ea0
 #endif
f3a2cd25
         }
598e03f0
 
81d882d5
         /* push env vars that begin with UV_, IV_PLAT_VER and IV_GUI_VER */
         for (e = es->list; e != NULL; e = e->next)
         {
             if (e->string)
             {
                 if ((((strncmp(e->string, "UV_", 3)==0
                        || strncmp(e->string, "IV_PLAT_VER=", sizeof("IV_PLAT_VER=")-1)==0)
                       && session->opt->push_peer_info_detail >= 2)
                      || (strncmp(e->string,"IV_GUI_VER=",sizeof("IV_GUI_VER=")-1)==0))
                     && buf_safe(&out, strlen(e->string)+1))
                 {
                     buf_printf(&out, "%s\n", e->string);
                 }
             }
         }
 
         if (!write_string(buf, BSTR(&out), -1))
         {
             goto error;
         }
     }
     else
aaf72974
     {
81d882d5
         if (!write_empty_string(buf)) /* no peer info */
         {
             goto error;
         }
aaf72974
     }
81d882d5
     ret = true;
aaf72974
 
81d882d5
 error:
     gc_free(&gc);
     return ret;
aaf72974
 }
 
 static bool
81d882d5
 key_method_2_write(struct buffer *buf, struct tls_session *session)
6fbf66fa
 {
81d882d5
     struct key_state *ks = &session->key[KS_PRIMARY];      /* primary key */
57513aac
 
81d882d5
     ASSERT(session->opt->key_method == 2);
     ASSERT(buf_init(buf, 0));
6fbf66fa
 
81d882d5
     /* write a uint32 0 */
     if (!buf_write_u32(buf, 0))
     {
         goto error;
     }
6fbf66fa
 
81d882d5
     /* write key_method + flags */
     if (!buf_write_u8(buf, (session->opt->key_method & KEY_METHOD_MASK)))
     {
         goto error;
     }
6fbf66fa
 
81d882d5
     /* write key source material */
     if (!key_source2_randomize_write(ks->key_src, buf, session->opt->server))
     {
         goto error;
     }
6fbf66fa
 
81d882d5
     /* write options string */
     {
         if (!write_string(buf, local_options_string(session), TLS_OPTIONS_LEN))
         {
             goto error;
         }
     }
6fbf66fa
 
81d882d5
     /* write username/password if specified */
     if (auth_user_pass_enabled)
6fbf66fa
     {
66b9409b
 #ifdef ENABLE_MANAGEMENT
81d882d5
         auth_user_pass_setup(session->opt->auth_user_pass_file, session->opt->sci);
eab3e22f
 #else
81d882d5
         auth_user_pass_setup(session->opt->auth_user_pass_file, NULL);
eab3e22f
 #endif
81d882d5
         if (!write_string(buf, auth_user_pass.username, -1))
         {
             goto error;
         }
         if (!write_string(buf, auth_user_pass.password, -1))
         {
             goto error;
         }
57116536
         /* if auth-nocache was specified, the auth_user_pass object reaches
          * a "complete" state only after having received the push-reply
          * message.
          * This is the case because auth-token statement in a push-reply would
          * invert its nocache.
          *
          * For this reason, skip the purge operation here if no push-reply
          * message has been received yet.
          *
          * This normally happens upon first negotiation only.
          */
         if (!auth_user_pass.wait_for_push)
         {
             purge_user_pass(&auth_user_pass, false);
         }
6fbf66fa
     }
81d882d5
     else
aaf72974
     {
81d882d5
         if (!write_empty_string(buf)) /* no username */
         {
             goto error;
         }
         if (!write_empty_string(buf)) /* no password */
         {
             goto error;
         }
aaf72974
     }
 
81d882d5
     if (!push_peer_info(buf, session))
     {
         goto error;
     }
6fbf66fa
 
81d882d5
     /* Generate tunnel keys if we're a TLS server.
      * If we're a p2mp server and IV_NCP >= 2 is negotiated, the first key
      * generation is postponed until after the pull/push, so we can process pushed
      * cipher directives.
      */
     if (session->opt->server && !(session->opt->ncp_enabled
                                   && session->opt->mode == MODE_SERVER && ks->key_id <= 0))
6fbf66fa
     {
81d882d5
         if (ks->authenticated)
         {
             if (!tls_session_generate_data_channel_keys(session))
             {
                 msg(D_TLS_ERRORS, "TLS Error: server generate_key_expansion failed");
                 goto error;
             }
         }
6fbf66fa
     }
 
81d882d5
     return true;
6fbf66fa
 
81d882d5
 error:
     msg(D_TLS_ERRORS, "TLS Error: Key Method #2 write failed");
     secure_memzero(ks->key_src, sizeof(*ks->key_src));
     return false;
6fbf66fa
 }
 
 static bool
81d882d5
 key_method_1_read(struct buffer *buf, struct tls_session *session)
6fbf66fa
 {
81d882d5
     int status;
     struct key key;
     struct key_state *ks = &session->key[KS_PRIMARY];      /* primary key */
6fbf66fa
 
81d882d5
     ASSERT(session->opt->key_method == 1);
6fbf66fa
 
81d882d5
     if (!session->verified)
6fbf66fa
     {
81d882d5
         msg(D_TLS_ERRORS,
             "TLS Error: Certificate verification failed (key-method 1)");
         goto error;
6fbf66fa
     }
 
81d882d5
     status = read_key(&key, &session->opt->key_type, buf);
     if (status != 1)
6fbf66fa
     {
81d882d5
         msg(D_TLS_ERRORS,
             "TLS Error: Error reading data channel key from plaintext buffer");
         goto error;
6fbf66fa
     }
 
81d882d5
     if (!check_key(&key, &session->opt->key_type))
6fbf66fa
     {
81d882d5
         msg(D_TLS_ERRORS, "TLS Error: Bad decrypting key received from peer");
         goto error;
6fbf66fa
     }
 
81d882d5
     if (buf->len < 1)
6fbf66fa
     {
81d882d5
         msg(D_TLS_ERRORS, "TLS Error: Missing options string");
         goto error;
6fbf66fa
     }
 
 #ifdef ENABLE_OCC
81d882d5
     /* compare received remote options string
      * with our locally computed options string */
     if (!session->opt->disable_occ
         && !options_cmp_equal_safe((char *) BPTR(buf), session->opt->remote_options, buf->len))
6fbf66fa
     {
81d882d5
         options_warning_safe((char *) BPTR(buf), session->opt->remote_options, buf->len);
6fbf66fa
     }
 #endif
 
81d882d5
     buf_clear(buf);
6fbf66fa
 
81d882d5
     init_key_ctx(&ks->crypto_options.key_ctx_bi.decrypt, &key,
                  &session->opt->key_type, OPENVPN_OP_DECRYPT,
                  "Data Channel Decrypt");
     secure_memzero(&key, sizeof(key));
     ks->authenticated = true;
     return true;
6fbf66fa
 
81d882d5
 error:
     buf_clear(buf);
     secure_memzero(&key, sizeof(key));
     return false;
6fbf66fa
 }
 
 static bool
81d882d5
 key_method_2_read(struct buffer *buf, struct tls_multi *multi, struct tls_session *session)
6fbf66fa
 {
81d882d5
     struct key_state *ks = &session->key[KS_PRIMARY];      /* primary key */
d0811e64
 
81d882d5
     int key_method_flags;
     bool username_status, password_status;
6fbf66fa
 
81d882d5
     struct gc_arena gc = gc_new();
     char *options;
2b60198e
     struct user_pass *up = NULL;
90efcacb
 
81d882d5
     /* allocate temporary objects */
     ALLOC_ARRAY_CLEAR_GC(options, char, TLS_OPTIONS_LEN, &gc);
90efcacb
 
81d882d5
     ASSERT(session->opt->key_method == 2);
6fbf66fa
 
81d882d5
     /* discard leading uint32 */
     if (!buf_advance(buf, 4))
     {
         msg(D_TLS_ERRORS, "TLS ERROR: Plaintext buffer too short (%d bytes).",
             buf->len);
         goto error;
     }
6fbf66fa
 
81d882d5
     /* get key method */
     key_method_flags = buf_read_u8(buf);
     if ((key_method_flags & KEY_METHOD_MASK) != 2)
6fbf66fa
     {
81d882d5
         msg(D_TLS_ERRORS,
             "TLS ERROR: Unknown key_method/flags=%d received from remote host",
             key_method_flags);
         goto error;
6fbf66fa
     }
 
81d882d5
     /* get key source material (not actual keys yet) */
     if (!key_source2_read(ks->key_src, buf, session->opt->server))
6fbf66fa
     {
81d882d5
         msg(D_TLS_ERRORS, "TLS Error: Error reading remote data channel key source entropy from plaintext buffer");
         goto error;
6fbf66fa
     }
 
81d882d5
     /* get options */
     if (!read_string(buf, options, TLS_OPTIONS_LEN))
6fbf66fa
     {
81d882d5
         msg(D_TLS_ERRORS, "TLS Error: Failed to read required OCC options string");
         goto error;
6fbf66fa
     }
 
81d882d5
     ks->authenticated = false;
d0811e64
 
81d882d5
     /* always extract username + password fields from buf, even if not
      * authenticating for it, because otherwise we can't get at the
      * peer_info data which follows behind
      */
     ALLOC_OBJ_CLEAR_GC(up, struct user_pass, &gc);
     username_status = read_string(buf, up->username, USER_PASS_LEN);
     password_status = read_string(buf, up->password, USER_PASS_LEN);
a8be7379
 
1eb9a127
 #if P2MP_SERVER
81d882d5
     /* get peer info from control channel */
     free(multi->peer_info);
     multi->peer_info = read_string_alloc(buf);
     if (multi->peer_info)
     {
         output_peer_info_env(session->opt->es, multi->peer_info);
a17aa981
     }
a8be7379
 
81d882d5
     free(multi->remote_ciphername);
     multi->remote_ciphername =
         options_string_extract_option(options, "cipher", NULL);
 
     if (tls_peer_info_ncp_ver(multi->peer_info) < 2)
6fbf66fa
     {
81d882d5
         /* Peer does not support NCP, but leave NCP enabled if the local and
          * remote cipher do not match to attempt 'poor-man's NCP'.
          */
         if (multi->remote_ciphername == NULL
             || 0 == strcmp(multi->remote_ciphername, multi->opt.config_ciphername))
         {
             session->opt->ncp_enabled = false;
         }
     }
 #endif /* if P2MP_SERVER */
 
     if (tls_session_user_pass_enabled(session))
     {
         /* Perform username/password authentication */
         if (!username_status || !password_status)
         {
             CLEAR(*up);
             if (!(session->opt->ssl_flags & SSLF_AUTH_USER_PASS_OPTIONAL))
             {
                 msg(D_TLS_ERRORS, "TLS Error: Auth Username/Password was not provided by peer");
                 goto error;
             }
         }
6fbf66fa
 
81d882d5
         verify_user_pass(up, multi, session);
6fbf66fa
     }
81d882d5
     else
6fbf66fa
     {
81d882d5
         /* Session verification should have occurred during TLS negotiation*/
         if (!session->verified)
         {
             msg(D_TLS_ERRORS,
                 "TLS Error: Certificate verification failed (key-method 2)");
             goto error;
         }
         ks->authenticated = true;
6fbf66fa
     }
 
81d882d5
     /* clear username and password from memory */
     secure_memzero(up, sizeof(*up));
a8be7379
 
81d882d5
     /* Perform final authentication checks */
     if (ks->authenticated)
6fbf66fa
     {
81d882d5
         verify_final_auth_checks(multi, session);
6fbf66fa
     }
 
 #ifdef ENABLE_OCC
81d882d5
     /* check options consistency */
     if (!session->opt->disable_occ
         && !options_cmp_equal(options, session->opt->remote_options))
6fbf66fa
     {
81d882d5
         options_warning(options, session->opt->remote_options);
         if (session->opt->ssl_flags & SSLF_OPT_VERIFY)
         {
             msg(D_TLS_ERRORS, "Option inconsistency warnings triggering disconnect due to --opt-verify");
             ks->authenticated = false;
         }
6fbf66fa
     }
 #endif
 
81d882d5
     buf_clear(buf);
6fbf66fa
 
81d882d5
     /*
      * Call OPENVPN_PLUGIN_TLS_FINAL plugin if defined, for final
      * veto opportunity over authentication decision.
      */
     if (ks->authenticated && plugin_defined(session->opt->plugins, OPENVPN_PLUGIN_TLS_FINAL))
d92819fa
     {
81d882d5
         key_state_export_keying_material(&ks->ks_ssl, session);
685e486e
 
81d882d5
         if (plugin_call(session->opt->plugins, OPENVPN_PLUGIN_TLS_FINAL, NULL, NULL, session->opt->es) != OPENVPN_PLUGIN_FUNC_SUCCESS)
         {
             ks->authenticated = false;
         }
685e486e
 
81d882d5
         setenv_del(session->opt->es, "exported_keying_material");
d92819fa
     }
 
81d882d5
     /*
      * Generate tunnel keys if we're a client.
      * If --pull is enabled, the first key generation is postponed until after the
      * pull/push, so we can process pushed cipher directives.
      */
     if (!session->opt->server && (!session->opt->pull || ks->key_id > 0))
6fbf66fa
     {
81d882d5
         if (!tls_session_generate_data_channel_keys(session))
         {
             msg(D_TLS_ERRORS, "TLS Error: client generate_key_expansion failed");
             goto error;
         }
6fbf66fa
     }
 
81d882d5
     gc_free(&gc);
     return true;
6fbf66fa
 
81d882d5
 error:
     secure_memzero(ks->key_src, sizeof(*ks->key_src));
2b60198e
     if (up)
     {
         secure_memzero(up, sizeof(*up));
     }
81d882d5
     buf_clear(buf);
     gc_free(&gc);
     return false;
6fbf66fa
 }
 
1c4af9ea
 static int
81d882d5
 auth_deferred_expire_window(const struct tls_options *o)
1c4af9ea
 {
81d882d5
     int ret = o->handshake_window;
     const int r2 = o->renegotiate_seconds / 2;
112e6704
 
81d882d5
     if (o->renegotiate_seconds && r2 < ret)
     {
         ret = r2;
     }
     return ret;
1c4af9ea
 }
 
6fbf66fa
 /*
  * This is the primary routine for processing TLS stuff inside the
  * the main event loop.  When this routine exits
  * with non-error status, it will set *wakeup to the number of seconds
  * when it wants to be called again.
  *
  * Return value is true if we have placed a packet in *to_link which we
  * want to send to our peer.
  */
 static bool
81d882d5
 tls_process(struct tls_multi *multi,
             struct tls_session *session,
             struct buffer *to_link,
             struct link_socket_actual **to_link_addr,
             struct link_socket_info *to_link_socket_info,
             interval_t *wakeup)
 {
     struct gc_arena gc = gc_new();
     struct buffer *buf;
     bool state_change = false;
     bool active = false;
     struct key_state *ks = &session->key[KS_PRIMARY];      /* primary key */
     struct key_state *ks_lame = &session->key[KS_LAME_DUCK]; /* retiring key */
 
     /* Make sure we were initialized and that we're not in an error state */
     ASSERT(ks->state != S_UNDEF);
     ASSERT(ks->state != S_ERROR);
     ASSERT(session_id_defined(&session->session_id));
 
     /* Should we trigger a soft reset? -- new key, keeps old key for a while */
     if (ks->state >= S_ACTIVE
         && ((session->opt->renegotiate_seconds
              && now >= ks->established + session->opt->renegotiate_seconds)
             || (session->opt->renegotiate_bytes > 0
                 && ks->n_bytes >= session->opt->renegotiate_bytes)
             || (session->opt->renegotiate_packets
                 && ks->n_packets >= session->opt->renegotiate_packets)
             || (packet_id_close_to_wrapping(&ks->crypto_options.packet_id.send))))
     {
dd996463
         msg(D_TLS_DEBUG_LOW, "TLS: soft reset sec=%d/%d bytes=" counter_format
             "/%d pkts=" counter_format "/%d",
             (int) (now - ks->established), session->opt->renegotiate_seconds,
81d882d5
             ks->n_bytes, session->opt->renegotiate_bytes,
             ks->n_packets, session->opt->renegotiate_packets);
         key_state_soft_reset(session);
     }
 
     /* Kill lame duck key transition_window seconds after primary key negotiation */
     if (lame_duck_must_die(session, wakeup))
     {
         key_state_free(ks_lame, true);
         msg(D_TLS_DEBUG_LOW, "TLS: tls_process: killed expiring key");
     }
 
     do
     {
         update_time();
 
         dmsg(D_TLS_DEBUG, "TLS: tls_process: chg=%d ks=%s lame=%s to_link->len=%d wakeup=%d",
              state_change,
              state_name(ks->state),
              state_name(ks_lame->state),
              to_link->len,
              *wakeup);
 
         state_change = false;
 
         /*
          * TLS activity is finished once we get to S_ACTIVE,
          * though we will still process acknowledgements.
          *
          * CHANGED with 2.0 -> now we may send tunnel configuration
          * info over the control channel.
          */
 
         /* Initial handshake */
         if (ks->state == S_INITIAL)
         {
             buf = reliable_get_buf_output_sequenced(ks->send_reliable);
             if (buf)
             {
                 ks->must_negotiate = now + session->opt->handshake_window;
                 ks->auth_deferred_expire = now + auth_deferred_expire_window(session->opt);
 
                 /* null buffer */
                 reliable_mark_active_outgoing(ks->send_reliable, buf, ks->initial_opcode);
                 INCR_GENERATED;
 
                 ks->state = S_PRE_START;
                 state_change = true;
                 dmsg(D_TLS_DEBUG, "TLS: Initial Handshake, sid=%s",
                      session_id_print(&session->session_id, &gc));
6fbf66fa
 
 #ifdef ENABLE_MANAGEMENT
81d882d5
                 if (management && ks->initial_opcode != P_CONTROL_SOFT_RESET_V1)
                 {
                     management_set_state(management,
                                          OPENVPN_STATE_WAIT,
                                          NULL,
                                          NULL,
                                          NULL,
                                          NULL,
                                          NULL);
                 }
c5da6dbf
 #endif
81d882d5
             }
         }
 
         /* Are we timed out on receive? */
         if (now >= ks->must_negotiate)
         {
             if (ks->state < S_ACTIVE)
             {
                 msg(D_TLS_ERRORS,
                     "TLS Error: TLS key negotiation failed to occur within %d seconds (check your network connectivity)",
                     session->opt->handshake_window);
                 goto error;
             }
             else /* assume that ks->state == S_ACTIVE */
             {
                 dmsg(D_TLS_DEBUG_MED, "STATE S_NORMAL_OP");
                 ks->state = S_NORMAL_OP;
                 ks->must_negotiate = 0;
             }
         }
 
         /* Wait for Initial Handshake ACK */
         if (ks->state == S_PRE_START && FULL_SYNC)
         {
             ks->state = S_START;
             state_change = true;
 
             /*
              * Attempt CRL reload before TLS negotiation. Won't be performed if
              * the file was not modified since the last reload
              */
             if (session->opt->crl_file
                 && !(session->opt->ssl_flags & SSLF_CRL_VERIFY_DIR))
             {
                 tls_ctx_reload_crl(&session->opt->ssl_ctx,
                                    session->opt->crl_file, session->opt->crl_file_inline);
             }
 
fd036181
             /* New connection, remove any old X509 env variables */
             tls_x509_clear_env(session->opt->es);
 
81d882d5
             dmsg(D_TLS_DEBUG_MED, "STATE S_START");
         }
 
         /* Wait for ACK */
         if (((ks->state == S_GOT_KEY && !session->opt->server)
              || (ks->state == S_SENT_KEY && session->opt->server)))
         {
             if (FULL_SYNC)
             {
                 ks->established = now;
                 dmsg(D_TLS_DEBUG_MED, "STATE S_ACTIVE");
                 if (check_debug_level(D_HANDSHAKE))
                 {
                     print_details(&ks->ks_ssl, "Control Channel:");
                 }
                 state_change = true;
                 ks->state = S_ACTIVE;
                 INCR_SUCCESS;
 
                 /* Set outgoing address for data channel packets */
                 link_socket_set_outgoing_addr(NULL, to_link_socket_info, &ks->remote_addr, session->common_name, session->opt->es);
 
                 /* Flush any payload packets that were buffered before our state transitioned to S_ACTIVE */
                 flush_payload_buffer(ks);
dc85dae6
 
6fbf66fa
 #ifdef MEASURE_TLS_HANDSHAKE_STATS
81d882d5
                 show_tls_performance_stats();
6fbf66fa
 #endif
81d882d5
             }
         }
 
         /* Reliable buffer to outgoing TCP/UDP (send up to CONTROL_SEND_ACK_MAX ACKs
          * for previously received packets) */
         if (!to_link->len && reliable_can_send(ks->send_reliable))
         {
             int opcode;
             struct buffer b;
 
             buf = reliable_send(ks->send_reliable, &opcode);
             ASSERT(buf);
             b = *buf;
             INCR_SENT;
 
             write_control_auth(session, ks, &b, to_link_addr, opcode,
                                CONTROL_SEND_ACK_MAX, true);
             *to_link = b;
             active = true;
             state_change = true;
             dmsg(D_TLS_DEBUG, "Reliable -> TCP/UDP");
             break;
         }
 
         /* Write incoming ciphertext to TLS object */
         buf = reliable_get_buf_sequenced(ks->rec_reliable);
         if (buf)
         {
             int status = 0;
             if (buf->len)
             {
                 status = key_state_write_ciphertext(&ks->ks_ssl, buf);
                 if (status == -1)
                 {
                     msg(D_TLS_ERRORS,
                         "TLS Error: Incoming Ciphertext -> TLS object write error");
                     goto error;
                 }
             }
             else
             {
                 status = 1;
             }
             if (status == 1)
             {
                 reliable_mark_deleted(ks->rec_reliable, buf, true);
                 state_change = true;
                 dmsg(D_TLS_DEBUG, "Incoming Ciphertext -> TLS");
             }
         }
 
         /* Read incoming plaintext from TLS object */
         buf = &ks->plaintext_read_buf;
         if (!buf->len)
         {
             int status;
 
             ASSERT(buf_init(buf, 0));
             status = key_state_read_plaintext(&ks->ks_ssl, buf, TLS_CHANNEL_BUF_SIZE);
             update_time();
             if (status == -1)
             {
                 msg(D_TLS_ERRORS, "TLS Error: TLS object -> incoming plaintext read error");
                 goto error;
             }
             if (status == 1)
             {
                 state_change = true;
                 dmsg(D_TLS_DEBUG, "TLS -> Incoming Plaintext");
b00d56e1
 
                 /* More data may be available, wake up again asap to check. */
                 *wakeup = 0;
81d882d5
             }
         }
 
         /* Send Key */
         buf = &ks->plaintext_write_buf;
         if (!buf->len && ((ks->state == S_START && !session->opt->server)
                           || (ks->state == S_GOT_KEY && session->opt->server)))
         {
             if (session->opt->key_method == 1)
             {
                 if (!key_method_1_write(buf, session))
                 {
                     goto error;
                 }
             }
             else if (session->opt->key_method == 2)
             {
                 if (!key_method_2_write(buf, session))
                 {
                     goto error;
                 }
             }
             else
             {
                 ASSERT(0);
             }
 
             state_change = true;
             dmsg(D_TLS_DEBUG_MED, "STATE S_SENT_KEY");
             ks->state = S_SENT_KEY;
         }
 
         /* Receive Key */
         buf = &ks->plaintext_read_buf;
         if (buf->len
             && ((ks->state == S_SENT_KEY && !session->opt->server)
                 || (ks->state == S_START && session->opt->server)))
         {
             if (session->opt->key_method == 1)
             {
                 if (!key_method_1_read(buf, session))
                 {
                     goto error;
                 }
             }
             else if (session->opt->key_method == 2)
             {
                 if (!key_method_2_read(buf, multi, session))
                 {
                     goto error;
                 }
             }
             else
             {
                 ASSERT(0);
             }
 
             state_change = true;
             dmsg(D_TLS_DEBUG_MED, "STATE S_GOT_KEY");
             ks->state = S_GOT_KEY;
         }
 
         /* Write outgoing plaintext to TLS object */
         buf = &ks->plaintext_write_buf;
         if (buf->len)
         {
             int status = key_state_write_plaintext(&ks->ks_ssl, buf);
             if (status == -1)
             {
                 msg(D_TLS_ERRORS,
                     "TLS ERROR: Outgoing Plaintext -> TLS object write error");
                 goto error;
             }
             if (status == 1)
             {
                 state_change = true;
                 dmsg(D_TLS_DEBUG, "Outgoing Plaintext -> TLS");
             }
         }
 
         /* Outgoing Ciphertext to reliable buffer */
         if (ks->state >= S_START)
         {
             buf = reliable_get_buf_output_sequenced(ks->send_reliable);
             if (buf)
             {
                 int status = key_state_read_ciphertext(&ks->ks_ssl, buf, PAYLOAD_SIZE_DYNAMIC(&multi->opt.frame));
                 if (status == -1)
                 {
                     msg(D_TLS_ERRORS,
                         "TLS Error: Ciphertext -> reliable TCP/UDP transport read error");
                     goto error;
                 }
                 if (status == 1)
                 {
                     reliable_mark_active_outgoing(ks->send_reliable, buf, P_CONTROL_V1);
                     INCR_GENERATED;
                     state_change = true;
                     dmsg(D_TLS_DEBUG, "Outgoing Ciphertext -> Reliable");
                 }
             }
         }
     }
     while (state_change);
 
     update_time();
 
     /* Send 1 or more ACKs (each received control packet gets one ACK) */
     if (!to_link->len && !reliable_ack_empty(ks->rec_ack))
     {
         struct buffer buf = ks->ack_write_buf;
         ASSERT(buf_init(&buf, FRAME_HEADROOM(&multi->opt.frame)));
         write_control_auth(session, ks, &buf, to_link_addr, P_ACK_V1,
                            RELIABLE_ACK_SIZE, false);
         *to_link = buf;
         active = true;
         dmsg(D_TLS_DEBUG, "Dedicated ACK -> TCP/UDP");
     }
 
     /* When should we wake up again? */
     {
         if (ks->state >= S_INITIAL)
         {
             compute_earliest_wakeup(wakeup,
                                     reliable_send_timeout(ks->send_reliable));
 
             if (ks->must_negotiate)
             {
                 compute_earliest_wakeup(wakeup, ks->must_negotiate - now);
             }
         }
 
         if (ks->established && session->opt->renegotiate_seconds)
         {
             compute_earliest_wakeup(wakeup,
                                     ks->established + session->opt->renegotiate_seconds - now);
         }
 
         /* prevent event-loop spinning by setting minimum wakeup of 1 second */
         if (*wakeup <= 0)
         {
             *wakeup = 1;
 
             /* if we had something to send to remote, but to_link was busy,
              * let caller know we need to be called again soon */
             active = true;
         }
 
         dmsg(D_TLS_DEBUG, "TLS: tls_process: timeout set to %d", *wakeup);
 
         gc_free(&gc);
         return active;
     }
6fbf66fa
 
 error:
81d882d5
     tls_clear_error();
     ks->state = S_ERROR;
     msg(D_TLS_ERRORS, "TLS Error: TLS handshake failed");
     INCR_ERROR;
     gc_free(&gc);
     return false;
6fbf66fa
 }
 
 /*
  * Called by the top-level event loop.
  *
  * Basically decides if we should call tls_process for
  * the active or untrusted sessions.
  */
 
344ee918
 int
81d882d5
 tls_multi_process(struct tls_multi *multi,
                   struct buffer *to_link,
                   struct link_socket_actual **to_link_addr,
                   struct link_socket_info *to_link_socket_info,
                   interval_t *wakeup)
 {
     struct gc_arena gc = gc_new();
     int i;
     int active = TLSMP_INACTIVE;
     bool error = false;
     int tas;
 
     perf_push(PERF_TLS_MULTI_PROCESS);
 
     tls_clear_error();
 
     /*
      * Process each session object having state of S_INITIAL or greater,
      * and which has a defined remote IP addr.
      */
 
     for (i = 0; i < TM_SIZE; ++i)
     {
         struct tls_session *session = &multi->session[i];
         struct key_state *ks = &session->key[KS_PRIMARY];
         struct key_state *ks_lame = &session->key[KS_LAME_DUCK];
 
         /* set initial remote address */
         if (i == TM_ACTIVE && ks->state == S_INITIAL
             && link_socket_actual_defined(&to_link_socket_info->lsa->actual))
         {
             ks->remote_addr = to_link_socket_info->lsa->actual;
         }
 
         dmsg(D_TLS_DEBUG,
              "TLS: tls_multi_process: i=%d state=%s, mysid=%s, stored-sid=%s, stored-ip=%s",
              i,
              state_name(ks->state),
              session_id_print(&session->session_id, &gc),
              session_id_print(&ks->session_id_remote, &gc),
              print_link_socket_actual(&ks->remote_addr, &gc));
 
         if (ks->state >= S_INITIAL && link_socket_actual_defined(&ks->remote_addr))
         {
             struct link_socket_actual *tla = NULL;
 
             update_time();
 
             if (tls_process(multi, session, to_link, &tla,
                             to_link_socket_info, wakeup))
             {
                 active = TLSMP_ACTIVE;
             }
 
             /*
              * If tls_process produced an outgoing packet,
              * return the link_socket_actual object (which
              * contains the outgoing address).
              */
             if (tla)
             {
                 multi->to_link_addr = *tla;
                 *to_link_addr = &multi->to_link_addr;
             }
 
             /*
              * If tls_process hits an error:
              * (1) If the session has an unexpired lame duck key, preserve it.
              * (2) Reinitialize the session.
              * (3) Increment soft error count
              */
             if (ks->state == S_ERROR)
             {
                 ++multi->n_soft_errors;
 
                 if (i == TM_ACTIVE)
                 {
                     error = true;
                 }
 
                 if (i == TM_ACTIVE
                     && ks_lame->state >= S_ACTIVE
                     && !multi->opt.single_session)
                 {
                     move_session(multi, TM_LAME_DUCK, TM_ACTIVE, true);
                 }
                 else
                 {
                     reset_session(multi, session);
                 }
             }
         }
     }
 
     update_time();
 
     tas = tls_authentication_status(multi, TLS_MULTI_AUTH_STATUS_INTERVAL);
 
     /*
      * If lame duck session expires, kill it.
      */
     if (lame_duck_must_die(&multi->session[TM_LAME_DUCK], wakeup))
     {
         tls_session_free(&multi->session[TM_LAME_DUCK], true);
         msg(D_TLS_DEBUG_LOW, "TLS: tls_multi_process: killed expiring key");
     }
 
     /*
      * If untrusted session achieves TLS authentication,
      * move it to active session, usurping any prior session.
      *
      * A semi-trusted session is one in which the certificate authentication
      * succeeded (if cert verification is enabled) but the username/password
      * verification failed.  A semi-trusted session can forward data on the
      * TLS control channel but not on the tunnel channel.
      */
     if (DECRYPT_KEY_ENABLED(multi, &multi->session[TM_UNTRUSTED].key[KS_PRIMARY]))
     {
         move_session(multi, TM_ACTIVE, TM_UNTRUSTED, true);
         msg(D_TLS_DEBUG_LOW, "TLS: tls_multi_process: untrusted session promoted to %strusted",
             tas == TLS_AUTHENTICATION_SUCCEEDED ? "" : "semi-");
     }
 
     /*
      * A hard error means that TM_ACTIVE hit an S_ERROR state and that no
      * other key state objects are S_ACTIVE or higher.
      */
     if (error)
     {
         for (i = 0; i < (int) SIZE(multi->key_scan); ++i)
         {
             if (multi->key_scan[i]->state >= S_ACTIVE)
             {
                 goto nohard;
             }
         }
         ++multi->n_hard_errors;
     }
 nohard:
6fbf66fa
 
 #ifdef ENABLE_DEBUG
81d882d5
     /* DEBUGGING -- flood peer with repeating connection attempts */
     {
         const int throw_level = GREMLIN_CONNECTION_FLOOD_LEVEL(multi->opt.gremlin);
         if (throw_level)
         {
             for (i = 0; i < (int) SIZE(multi->key_scan); ++i)
             {
                 if (multi->key_scan[i]->state >= throw_level)
                 {
                     ++multi->n_hard_errors;
                     ++multi->n_soft_errors;
                 }
             }
         }
     }
6fbf66fa
 #endif
 
81d882d5
     perf_pop();
     gc_free(&gc);
344ee918
 
81d882d5
     return (tas == TLS_AUTHENTICATION_FAILED) ? TLSMP_KILL : active;
6fbf66fa
 }
 
 /*
  * Pre and post-process the encryption & decryption buffers in order
  * to implement a multiplexed TLS channel over the TCP/UDP port.
  */
 
 /*
  *
  * When we are in TLS mode, this is the first routine which sees
  * an incoming packet.
  *
  * If it's a data packet, we set opt so that our caller can
  * decrypt it.  We also give our caller the appropriate decryption key.
  *
  * If it's a control packet, we authenticate it and process it,
  * possibly creating a new tls_session if it represents the
  * first packet of a new session.  For control packets, we will
  * also zero the size of *buf so that our caller ignores the
  * packet on our return.
  *
  * Note that openvpn only allows one active session at a time,
  * so a new session (once authenticated) will always usurp
  * an old session.
  *
  * Return true if input was an authenticated control channel
  * packet.
  *
  * If we are running in TLS thread mode, all public routines
  * below this point must be called with the L_TLS lock held.
  */
 
 bool
81d882d5
 tls_pre_decrypt(struct tls_multi *multi,
                 const struct link_socket_actual *from,
                 struct buffer *buf,
                 struct crypto_options **opt,
                 bool floated,
                 const uint8_t **ad_start)
 {
     struct gc_arena gc = gc_new();
     bool ret = false;
 
     if (buf->len > 0)
     {
         int i;
         int op;
         int key_id;
 
         /* get opcode and key ID */
         {
             uint8_t c = *BPTR(buf);
             op = c >> P_OPCODE_SHIFT;
             key_id = c & P_KEY_ID_MASK;
         }
 
         if ((op == P_DATA_V1) || (op == P_DATA_V2))
         {
             /* data channel packet */
             for (i = 0; i < KEY_SCAN_SIZE; ++i)
             {
                 struct key_state *ks = multi->key_scan[i];
 
                 /*
                  * This is the basic test of TLS state compatibility between a local OpenVPN
                  * instance and its remote peer.
                  *
                  * If the test fails, it tells us that we are getting a packet from a source
                  * which claims reference to a prior negotiated TLS session, but the local
                  * OpenVPN instance has no memory of such a negotiation.
                  *
                  * It almost always occurs on UDP sessions when the passive side of the
                  * connection is restarted without the active side restarting as well (the
                  * passive side is the server which only listens for the connections, the
                  * active side is the client which initiates connections).
                  */
                 if (DECRYPT_KEY_ENABLED(multi, ks)
                     && key_id == ks->key_id
                     && ks->authenticated
47ae8457
 #ifdef ENABLE_DEF_AUTH
81d882d5
                     && !ks->auth_deferred
47ae8457
 #endif
81d882d5
                     && (floated || link_socket_actual_match(from, &ks->remote_addr)))
                 {
                     if (!ks->crypto_options.key_ctx_bi.initialized)
                     {
c215c58f
                         msg(D_MULTI_DROPPED,
81d882d5
                             "Key %s [%d] not initialized (yet), dropping packet.",
                             print_link_socket_actual(from, &gc), key_id);
                         goto error_lite;
                     }
 
                     /* return appropriate data channel decrypt key in opt */
                     *opt = &ks->crypto_options;
                     if (op == P_DATA_V2)
                     {
                         *ad_start = BPTR(buf);
                     }
                     ASSERT(buf_advance(buf, 1));
                     if (op == P_DATA_V1)
                     {
                         *ad_start = BPTR(buf);
                     }
                     else if (op == P_DATA_V2)
                     {
                         if (buf->len < 4)
                         {
                             msg(D_TLS_ERRORS, "Protocol error: received P_DATA_V2 from %s but length is < 4",
                                 print_link_socket_actual(from, &gc));
                             goto error;
                         }
                         ASSERT(buf_advance(buf, 3));
                     }
 
                     ++ks->n_packets;
                     ks->n_bytes += buf->len;
                     dmsg(D_TLS_KEYSELECT,
                          "TLS: tls_pre_decrypt, key_id=%d, IP=%s",
                          key_id, print_link_socket_actual(from, &gc));
                     gc_free(&gc);
                     return ret;
                 }
             }
 
             msg(D_TLS_ERRORS,
                 "TLS Error: local/remote TLS keys are out of sync: %s [%d]",
                 print_link_socket_actual(from, &gc), key_id);
             goto error_lite;
         }
         else                      /* control channel packet */
         {
             bool do_burst = false;
             bool new_link = false;
             struct session_id sid; /* remote session ID */
 
             /* verify legal opcode */
             if (op < P_FIRST_OPCODE || op > P_LAST_OPCODE)
             {
                 msg(D_TLS_ERRORS,
                     "TLS Error: unknown opcode received from %s op=%d",
                     print_link_socket_actual(from, &gc), op);
                 goto error;
             }
 
             /* hard reset ? */
             if (is_hard_reset(op, 0))
             {
                 /* verify client -> server or server -> client connection */
                 if (((op == P_CONTROL_HARD_RESET_CLIENT_V1
283290bf
                       || op == P_CONTROL_HARD_RESET_CLIENT_V2
                       || op == P_CONTROL_HARD_RESET_CLIENT_V3) && !multi->opt.server)
81d882d5
                     || ((op == P_CONTROL_HARD_RESET_SERVER_V1
                          || op == P_CONTROL_HARD_RESET_SERVER_V2) && multi->opt.server))
                 {
                     msg(D_TLS_ERRORS,
                         "TLS Error: client->client or server->server connection attempted from %s",
                         print_link_socket_actual(from, &gc));
                     goto error;
                 }
             }
 
             /*
              * Authenticate Packet
              */
             dmsg(D_TLS_DEBUG, "TLS: control channel, op=%s, IP=%s",
                  packet_opcode_name(op), print_link_socket_actual(from, &gc));
 
             /* get remote session-id */
             {
                 struct buffer tmp = *buf;
                 buf_advance(&tmp, 1);
                 if (!session_id_read(&sid, &tmp) || !session_id_defined(&sid))
                 {
                     msg(D_TLS_ERRORS,
                         "TLS Error: session-id not found in packet from %s",
                         print_link_socket_actual(from, &gc));
                     goto error;
                 }
             }
 
             /* use session ID to match up packet with appropriate tls_session object */
             for (i = 0; i < TM_SIZE; ++i)
             {
                 struct tls_session *session = &multi->session[i];
                 struct key_state *ks = &session->key[KS_PRIMARY];
 
                 dmsg(D_TLS_DEBUG,
                      "TLS: initial packet test, i=%d state=%s, mysid=%s, rec-sid=%s, rec-ip=%s, stored-sid=%s, stored-ip=%s",
                      i,
                      state_name(ks->state),
                      session_id_print(&session->session_id, &gc),
                      session_id_print(&sid, &gc),
                      print_link_socket_actual(from, &gc),
                      session_id_print(&ks->session_id_remote, &gc),
                      print_link_socket_actual(&ks->remote_addr, &gc));
 
                 if (session_id_equal(&ks->session_id_remote, &sid))
                 /* found a match */
                 {
                     if (i == TM_LAME_DUCK)
                     {
                         msg(D_TLS_ERRORS,
                             "TLS ERROR: received control packet with stale session-id=%s",
                             session_id_print(&sid, &gc));
                         goto error;
                     }
                     dmsg(D_TLS_DEBUG,
                          "TLS: found match, session[%d], sid=%s",
                          i, session_id_print(&sid, &gc));
                     break;
                 }
             }
 
             /*
              * Initial packet received.
              */
 
             if (i == TM_SIZE && is_hard_reset(op, 0))
             {
                 struct tls_session *session = &multi->session[TM_ACTIVE];
                 struct key_state *ks = &session->key[KS_PRIMARY];
 
                 if (!is_hard_reset(op, multi->opt.key_method))
                 {
                     msg(D_TLS_ERRORS, "TLS ERROR: initial packet local/remote key_method mismatch, local key_method=%d, op=%s",
                         multi->opt.key_method,
                         packet_opcode_name(op));
                     goto error;
                 }
 
                 /*
                  * If we have no session currently in progress, the initial packet will
                  * open a new session in TM_ACTIVE rather than TM_UNTRUSTED.
                  */
                 if (!session_id_defined(&ks->session_id_remote))
                 {
                     if (multi->opt.single_session && multi->n_sessions)
                     {
                         msg(D_TLS_ERRORS,
                             "TLS Error: Cannot accept new session request from %s due to session context expire or --single-session [1]",
                             print_link_socket_actual(from, &gc));
                         goto error;
                     }
6fbf66fa
 
 #ifdef ENABLE_MANAGEMENT
81d882d5
                     if (management)
                     {
                         management_set_state(management,
                                              OPENVPN_STATE_AUTH,
                                              NULL,
                                              NULL,
                                              NULL,
                                              NULL,
                                              NULL);
                     }
6fbf66fa
 #endif
 
81d882d5
                     msg(D_TLS_DEBUG_LOW,
                         "TLS: Initial packet from %s, sid=%s",
                         print_link_socket_actual(from, &gc),
                         session_id_print(&sid, &gc));
 
                     do_burst = true;
                     new_link = true;
                     i = TM_ACTIVE;
                     session->untrusted_addr = *from;
                 }
             }
 
             if (i == TM_SIZE && is_hard_reset(op, 0))
             {
                 /*
                  * No match with existing sessions,
                  * probably a new session.
                  */
                 struct tls_session *session = &multi->session[TM_UNTRUSTED];
 
                 /*
                  * If --single-session, don't allow any hard-reset connection request
                  * unless it the the first packet of the session.
                  */
                 if (multi->opt.single_session)
                 {
                     msg(D_TLS_ERRORS,
                         "TLS Error: Cannot accept new session request from %s due to session context expire or --single-session [2]",
                         print_link_socket_actual(from, &gc));
                     goto error;
                 }
 
                 if (!is_hard_reset(op, multi->opt.key_method))
                 {
                     msg(D_TLS_ERRORS, "TLS ERROR: new session local/remote key_method mismatch, local key_method=%d, op=%s",
                         multi->opt.key_method,
                         packet_opcode_name(op));
                     goto error;
                 }
 
ff931c5e
                 if (!read_control_auth(buf, &session->tls_wrap, from,
                                        session->opt))
81d882d5
                 {
                     goto error;
                 }
 
                 /*
                  * New session-initiating control packet is authenticated at this point,
                  * assuming that the --tls-auth command line option was used.
                  *
                  * Without --tls-auth, we leave authentication entirely up to TLS.
                  */
                 msg(D_TLS_DEBUG_LOW,
                     "TLS: new session incoming connection from %s",
                     print_link_socket_actual(from, &gc));
 
                 new_link = true;
                 i = TM_UNTRUSTED;
                 session->untrusted_addr = *from;
             }
             else
             {
                 struct tls_session *session = &multi->session[i];
                 struct key_state *ks = &session->key[KS_PRIMARY];
 
                 /*
                  * Packet must belong to an existing session.
                  */
                 if (i != TM_ACTIVE && i != TM_UNTRUSTED)
                 {
                     msg(D_TLS_ERRORS,
                         "TLS Error: Unroutable control packet received from %s (si=%d op=%s)",
                         print_link_socket_actual(from, &gc),
                         i,
                         packet_opcode_name(op));
                     goto error;
                 }
 
                 /*
                  * Verify remote IP address
                  */
                 if (!new_link && !link_socket_actual_match(&ks->remote_addr, from))
                 {
                     msg(D_TLS_ERRORS, "TLS Error: Received control packet from unexpected IP addr: %s",
                         print_link_socket_actual(from, &gc));
                     goto error;
                 }
 
                 /*
                  * Remote is requesting a key renegotiation
                  */
                 if (op == P_CONTROL_SOFT_RESET_V1
                     && DECRYPT_KEY_ENABLED(multi, ks))
                 {
ff931c5e
                     if (!read_control_auth(buf, &session->tls_wrap, from,
                                            session->opt))
81d882d5
                     {
                         goto error;
                     }
 
                     key_state_soft_reset(session);
 
                     dmsg(D_TLS_DEBUG,
                          "TLS: received P_CONTROL_SOFT_RESET_V1 s=%d sid=%s",
                          i, session_id_print(&sid, &gc));
                 }
                 else
                 {
                     /*
                      * Remote responding to our key renegotiation request?
                      */
                     if (op == P_CONTROL_SOFT_RESET_V1)
                     {
                         do_burst = true;
                     }
 
ff931c5e
                     if (!read_control_auth(buf, &session->tls_wrap, from,
                                            session->opt))
81d882d5
                     {
                         goto error;
                     }
 
                     dmsg(D_TLS_DEBUG,
                          "TLS: received control channel packet s#=%d sid=%s",
                          i, session_id_print(&sid, &gc));
                 }
             }
 
             /*
df612f63
              * We have an authenticated control channel packet (if --tls-auth was set).
              * Now pass to our reliability layer which deals with
81d882d5
              * packet acknowledgements, retransmits, sequencing, etc.
              */
             {
                 struct tls_session *session = &multi->session[i];
                 struct key_state *ks = &session->key[KS_PRIMARY];
 
                 /* Make sure we were initialized and that we're not in an error state */
                 ASSERT(ks->state != S_UNDEF);
                 ASSERT(ks->state != S_ERROR);
                 ASSERT(session_id_defined(&session->session_id));
 
                 /* Let our caller know we processed a control channel packet */
                 ret = true;
 
                 /*
                  * Set our remote address and remote session_id
                  */
                 if (new_link)
                 {
                     ks->session_id_remote = sid;
                     ks->remote_addr = *from;
                     ++multi->n_sessions;
                 }
                 else if (!link_socket_actual_match(&ks->remote_addr, from))
                 {
                     msg(D_TLS_ERRORS,
                         "TLS Error: Existing session control channel packet from unknown IP address: %s",
                         print_link_socket_actual(from, &gc));
                     goto error;
                 }
 
                 /*
                  * Should we do a retransmit of all unacknowledged packets in
                  * the send buffer?  This improves the start-up efficiency of the
                  * initial key negotiation after the 2nd peer comes online.
                  */
                 if (do_burst && !session->burst)
                 {
                     reliable_schedule_now(ks->send_reliable);
                     session->burst = true;
                 }
 
                 /* Check key_id */
                 if (ks->key_id != key_id)
                 {
                     msg(D_TLS_ERRORS,
                         "TLS ERROR: local/remote key IDs out of sync (%d/%d) ID: %s",
                         ks->key_id, key_id, print_key_id(multi, &gc));
                     goto error;
                 }
 
                 /*
                  * Process incoming ACKs for packets we can now
                  * delete from reliable send buffer
                  */
                 {
                     /* buffers all packet IDs to delete from send_reliable */
                     struct reliable_ack send_ack;
 
                     send_ack.len = 0;
                     if (!reliable_ack_read(&send_ack, buf, &session->session_id))
                     {
                         msg(D_TLS_ERRORS,
                             "TLS Error: reading acknowledgement record from packet");
                         goto error;
                     }
                     reliable_send_purge(ks->send_reliable, &send_ack);
                 }
 
                 if (op != P_ACK_V1 && reliable_can_get(ks->rec_reliable))
                 {
                     packet_id_type id;
 
                     /* Extract the packet ID from the packet */
                     if (reliable_ack_read_packet_id(buf, &id))
                     {
                         /* Avoid deadlock by rejecting packet that would de-sequentialize receive buffer */
                         if (reliable_wont_break_sequentiality(ks->rec_reliable, id))
                         {
                             if (reliable_not_replay(ks->rec_reliable, id))
                             {
                                 /* Save incoming ciphertext packet to reliable buffer */
                                 struct buffer *in = reliable_get_buf(ks->rec_reliable);
                                 ASSERT(in);
5774cf4c
                                 if(!buf_copy(in, buf))
                                 {
                                     msg(D_MULTI_DROPPED,
                                         "Incoming control channel packet too big, dropping.");
                                     goto error;
                                 }
81d882d5
                                 reliable_mark_active_incoming(ks->rec_reliable, in, id, op);
                             }
 
                             /* Process outgoing acknowledgment for packet just received, even if it's a replay */
                             reliable_ack_acknowledge_packet_id(ks->rec_ack, id);
                         }
                     }
                 }
             }
         }
     }
 
 done:
     buf->len = 0;
     *opt = NULL;
     gc_free(&gc);
     return ret;
 
 error:
     ++multi->n_soft_errors;
 error_lite:
     tls_clear_error();
     goto done;
6fbf66fa
 }
 
 /*
  * This function is similar to tls_pre_decrypt, except it is called
  * when we are in server mode and receive an initial incoming
  * packet.  Note that we don't modify
  * any state in our parameter objects.  The purpose is solely to
  * determine whether we should generate a client instance
  * object, in which case true is returned.
  *
  * This function is essentially the first-line HMAC firewall
  * on the UDP port listener in --mode server mode.
  */
 bool
81d882d5
 tls_pre_decrypt_lite(const struct tls_auth_standalone *tas,
                      const struct link_socket_actual *from,
                      const struct buffer *buf)
 
 {
     struct gc_arena gc = gc_new();
     bool ret = false;
 
     if (buf->len > 0)
     {
         int op;
         int key_id;
 
         /* get opcode and key ID */
         {
             uint8_t c = *BPTR(buf);
             op = c >> P_OPCODE_SHIFT;
             key_id = c & P_KEY_ID_MASK;
         }
 
         /* this packet is from an as-yet untrusted source, so
          * scrutinize carefully */
 
283290bf
         if (op != P_CONTROL_HARD_RESET_CLIENT_V2
             && op != P_CONTROL_HARD_RESET_CLIENT_V3)
81d882d5
         {
             /*
              * This can occur due to bogus data or DoS packets.
              */
             dmsg(D_TLS_STATE_ERRORS,
                  "TLS State Error: No TLS state for client %s, opcode=%d",
                  print_link_socket_actual(from, &gc),
                  op);
             goto error;
         }
 
         if (key_id != 0)
         {
             dmsg(D_TLS_STATE_ERRORS,
                  "TLS State Error: Unknown key ID (%d) received from %s -- 0 was expected",
                  key_id,
                  print_link_socket_actual(from, &gc));
             goto error;
         }
 
         if (buf->len > EXPANDED_SIZE_DYNAMIC(&tas->frame))
         {
             dmsg(D_TLS_STATE_ERRORS,
                  "TLS State Error: Large packet (size %d) received from %s -- a packet no larger than %d bytes was expected",
                  buf->len,
                  print_link_socket_actual(from, &gc),
                  EXPANDED_SIZE_DYNAMIC(&tas->frame));
             goto error;
         }
 
         {
             struct buffer newbuf = clone_buf(buf);
             struct tls_wrap_ctx tls_wrap_tmp = tas->tls_wrap;
             bool status;
 
             /* HMAC test, if --tls-auth was specified */
ff931c5e
             status = read_control_auth(&newbuf, &tls_wrap_tmp, from, NULL);
81d882d5
             free_buf(&newbuf);
ff931c5e
             free_buf(&tls_wrap_tmp.tls_crypt_v2_metadata);
19dffdbd
             if (tls_wrap_tmp.cleanup_key_ctx)
             {
                 free_key_ctx_bi(&tls_wrap_tmp.opt.key_ctx_bi);
             }
81d882d5
             if (!status)
             {
                 goto error;
             }
 
             /*
              * At this point, if --tls-auth is being used, we know that
              * the packet has passed the HMAC test, but we don't know if
              * it is a replay yet.  We will attempt to defeat replays
              * by not advancing to the S_START state until we
              * receive an ACK from our first reply to the client
              * that includes an HMAC of our randomly generated 64 bit
              * session ID.
              *
              * On the other hand if --tls-auth is not being used, we
              * will proceed to begin the TLS authentication
              * handshake with only cursory integrity checks having
              * been performed, since we will be leaving the task
              * of authentication solely up to TLS.
              */
 
             ret = true;
         }
     }
     gc_free(&gc);
     return ret;
 
 error:
     tls_clear_error();
     gc_free(&gc);
     return ret;
6fbf66fa
 }
 
 /* Choose the key with which to encrypt a data packet */
 void
81d882d5
 tls_pre_encrypt(struct tls_multi *multi,
                 struct buffer *buf, struct crypto_options **opt)
 {
     multi->save_ks = NULL;
     if (buf->len > 0)
     {
         int i;
         struct key_state *ks_select = NULL;
         for (i = 0; i < KEY_SCAN_SIZE; ++i)
         {
             struct key_state *ks = multi->key_scan[i];
             if (ks->state >= S_ACTIVE
                 && ks->authenticated
                 && ks->crypto_options.key_ctx_bi.initialized
47ae8457
 #ifdef ENABLE_DEF_AUTH
81d882d5
                 && !ks->auth_deferred
47ae8457
 #endif
81d882d5
                 )
             {
                 if (!ks_select)
                 {
                     ks_select = ks;
                 }
                 if (now >= ks->auth_deferred_expire)
                 {
                     ks_select = ks;
                     break;
                 }
             }
         }
 
         if (ks_select)
         {
             *opt = &ks_select->crypto_options;
             multi->save_ks = ks_select;
             dmsg(D_TLS_KEYSELECT, "TLS: tls_pre_encrypt: key_id=%d", ks_select->key_id);
             return;
         }
         else
         {
             struct gc_arena gc = gc_new();
             dmsg(D_TLS_KEYSELECT, "TLS Warning: no data channel send key available: %s",
                  print_key_id(multi, &gc));
             gc_free(&gc);
         }
     }
 
     buf->len = 0;
     *opt = NULL;
6fbf66fa
 }
 
 void
81d882d5
 tls_prepend_opcode_v1(const struct tls_multi *multi, struct buffer *buf)
6fbf66fa
 {
81d882d5
     struct key_state *ks = multi->save_ks;
     uint8_t op;
66407e11
 
81d882d5
     msg(D_TLS_DEBUG, __func__);
66407e11
 
81d882d5
     ASSERT(ks);
66407e11
 
81d882d5
     op = (P_DATA_V1 << P_OPCODE_SHIFT) | ks->key_id;
     ASSERT(buf_write_prepend(buf, &op, 1));
66407e11
 }
 
 void
81d882d5
 tls_prepend_opcode_v2(const struct tls_multi *multi, struct buffer *buf)
66407e11
 {
81d882d5
     struct key_state *ks = multi->save_ks;
     uint32_t peer;
6fbf66fa
 
81d882d5
     msg(D_TLS_DEBUG, __func__);
66407e11
 
81d882d5
     ASSERT(ks);
66407e11
 
81d882d5
     peer = htonl(((P_DATA_V2 << P_OPCODE_SHIFT) | ks->key_id) << 24
                  | (multi->peer_id & 0xFFFFFF));
     ASSERT(buf_write_prepend(buf, &peer, 4));
66407e11
 }
 
 void
81d882d5
 tls_post_encrypt(struct tls_multi *multi, struct buffer *buf)
66407e11
 {
81d882d5
     struct key_state *ks = multi->save_ks;
     multi->save_ks = NULL;
66407e11
 
81d882d5
     if (buf->len > 0)
6fbf66fa
     {
81d882d5
         ASSERT(ks);
65eedc35
 
81d882d5
         ++ks->n_packets;
         ks->n_bytes += buf->len;
6fbf66fa
     }
 }
 
 /*
  * Send a payload over the TLS control channel.
  * Called externally.
  */
 
 bool
81d882d5
 tls_send_payload(struct tls_multi *multi,
                  const uint8_t *data,
                  int size)
6fbf66fa
 {
81d882d5
     struct tls_session *session;
     struct key_state *ks;
     bool ret = false;
6fbf66fa
 
81d882d5
     tls_clear_error();
6fbf66fa
 
81d882d5
     ASSERT(multi);
6fbf66fa
 
81d882d5
     session = &multi->session[TM_ACTIVE];
     ks = &session->key[KS_PRIMARY];
6fbf66fa
 
81d882d5
     if (ks->state >= S_ACTIVE)
6fbf66fa
     {
81d882d5
         if (key_state_write_plaintext_const(&ks->ks_ssl, data, size) == 1)
         {
             ret = true;
         }
6fbf66fa
     }
81d882d5
     else
dc85dae6
     {
81d882d5
         if (!ks->paybuf)
         {
             ks->paybuf = buffer_list_new(0);
         }
         buffer_list_push_data(ks->paybuf, data, (size_t)size);
         ret = true;
dc85dae6
     }
6fbf66fa
 
95993a1d
 
81d882d5
     tls_clear_error();
6fbf66fa
 
81d882d5
     return ret;
6fbf66fa
 }
 
 bool
81d882d5
 tls_rec_payload(struct tls_multi *multi,
                 struct buffer *buf)
6fbf66fa
 {
81d882d5
     struct tls_session *session;
     struct key_state *ks;
     bool ret = false;
6fbf66fa
 
81d882d5
     tls_clear_error();
6fbf66fa
 
81d882d5
     ASSERT(multi);
6fbf66fa
 
81d882d5
     session = &multi->session[TM_ACTIVE];
     ks = &session->key[KS_PRIMARY];
6fbf66fa
 
81d882d5
     if (ks->state >= S_ACTIVE && BLEN(&ks->plaintext_read_buf))
6fbf66fa
     {
81d882d5
         if (buf_copy(buf, &ks->plaintext_read_buf))
         {
             ret = true;
         }
         ks->plaintext_read_buf.len = 0;
6fbf66fa
     }
 
81d882d5
     tls_clear_error();
6fbf66fa
 
81d882d5
     return ret;
6fbf66fa
 }
 
65eedc35
 void
81d882d5
 tls_update_remote_addr(struct tls_multi *multi, const struct link_socket_actual *addr)
65eedc35
 {
81d882d5
     struct gc_arena gc = gc_new();
     int i, j;
65eedc35
 
81d882d5
     for (i = 0; i < TM_SIZE; ++i)
65eedc35
     {
81d882d5
         struct tls_session *session = &multi->session[i];
65eedc35
 
81d882d5
         for (j = 0; j < KS_SIZE; ++j)
         {
             struct key_state *ks = &session->key[j];
65eedc35
 
81d882d5
             if (!link_socket_actual_defined(&ks->remote_addr)
                 || link_socket_actual_match(addr, &ks->remote_addr))
             {
                 continue;
             }
65eedc35
 
81d882d5
             dmsg(D_TLS_KEYSELECT, "TLS: tls_update_remote_addr from IP=%s to IP=%s",
                  print_link_socket_actual(&ks->remote_addr, &gc),
                  print_link_socket_actual(addr, &gc));
65eedc35
 
81d882d5
             ks->remote_addr = *addr;
         }
65eedc35
     }
81d882d5
     gc_free(&gc);
65eedc35
 }
 
a17aa981
 int
 tls_peer_info_ncp_ver(const char *peer_info)
 {
81d882d5
     const char *ncpstr = peer_info ? strstr(peer_info, "IV_NCP=") : NULL;
     if (ncpstr)
a17aa981
     {
81d882d5
         int ncp = 0;
         int r = sscanf(ncpstr, "IV_NCP=%d", &ncp);
         if (r == 1)
         {
             return ncp;
         }
a17aa981
     }
81d882d5
     return 0;
a17aa981
 }
 
dc4fa3c4
 bool
4cd4899e
 tls_check_ncp_cipher_list(const char *list)
 {
81d882d5
     bool unsupported_cipher_found = false;
dc4fa3c4
 
81d882d5
     ASSERT(list);
dc4fa3c4
 
81d882d5
     char *const tmp_ciphers = string_alloc(list, NULL);
     const char *token = strtok(tmp_ciphers, ":");
     while (token)
dc4fa3c4
     {
81d882d5
         if (!cipher_kt_get(translate_cipher_name_from_openvpn(token)))
         {
             msg(M_WARN, "Unsupported cipher in --ncp-ciphers: %s", token);
             unsupported_cipher_found = true;
         }
         token = strtok(NULL, ":");
dc4fa3c4
     }
81d882d5
     free(tmp_ciphers);
dc4fa3c4
 
81d882d5
     return 0 < strlen(list) && !unsupported_cipher_found;
dc4fa3c4
 }
 
7aeabadd
 void
 show_available_tls_ciphers(const char *cipher_list,
                            const char *cipher_list_tls13,
                            const char *tls_cert_profile)
 {
     printf("Available TLS Ciphers, listed in order of preference:\n");
 
 #if (ENABLE_CRYPTO_OPENSSL && OPENSSL_VERSION_NUMBER >= 0x1010100fL)
     printf("\nFor TLS 1.3 and newer (--tls-ciphersuites):\n\n");
     show_available_tls_ciphers_list(cipher_list_tls13, tls_cert_profile, true);
 #else
     (void) cipher_list_tls13;  /* Avoid unused warning */
 #endif
 
     printf("\nFor TLS 1.2 and older (--tls-cipher):\n\n");
     show_available_tls_ciphers_list(cipher_list, tls_cert_profile, false);
 
     printf("\n"
     "Be aware that that whether a cipher suite in this list can actually work\n"
     "depends on the specific setup of both peers. See the man page entries of\n"
     "--tls-cipher and --show-tls for more details.\n\n"
     );
 }
 
6fbf66fa
 /*
  * Dump a human-readable rendition of an openvpn packet
  * into a garbage collectable string which is returned.
  */
 const char *
81d882d5
 protocol_dump(struct buffer *buffer, unsigned int flags, struct gc_arena *gc)
6fbf66fa
 {
81d882d5
     struct buffer out = alloc_buf_gc(256, gc);
     struct buffer buf = *buffer;
6fbf66fa
 
81d882d5
     uint8_t c;
     int op;
     int key_id;
6fbf66fa
 
81d882d5
     int tls_auth_hmac_size = (flags & PD_TLS_AUTH_HMAC_SIZE_MASK);
6fbf66fa
 
81d882d5
     if (buf.len <= 0)
6fbf66fa
     {
81d882d5
         buf_printf(&out, "DATA UNDEF len=%d", buf.len);
         goto done;
6fbf66fa
     }
 
81d882d5
     if (!(flags & PD_TLS))
     {
         goto print_data;
     }
6fbf66fa
 
81d882d5
     /*
      * Initial byte (opcode)
      */
     if (!buf_read(&buf, &c, sizeof(c)))
     {
         goto done;
     }
     op = (c >> P_OPCODE_SHIFT);
     key_id = c & P_KEY_ID_MASK;
     buf_printf(&out, "%s kid=%d", packet_opcode_name(op), key_id);
6fbf66fa
 
81d882d5
     if ((op == P_DATA_V1) || (op == P_DATA_V2))
     {
         goto print_data;
     }
6fbf66fa
 
81d882d5
     /*
      * Session ID
      */
     {
         struct session_id sid;
6fbf66fa
 
81d882d5
         if (!session_id_read(&sid, &buf))
         {
             goto done;
         }
         if (flags & PD_VERBOSE)
         {
             buf_printf(&out, " sid=%s", session_id_print(&sid, gc));
         }
     }
6fbf66fa
 
81d882d5
     /*
      * tls-auth hmac + packet_id
      */
     if (tls_auth_hmac_size)
6fbf66fa
     {
81d882d5
         struct packet_id_net pin;
         uint8_t tls_auth_hmac[MAX_HMAC_KEY_LENGTH];
6fbf66fa
 
81d882d5
         ASSERT(tls_auth_hmac_size <= MAX_HMAC_KEY_LENGTH);
6fbf66fa
 
81d882d5
         if (!buf_read(&buf, tls_auth_hmac, tls_auth_hmac_size))
         {
             goto done;
         }
         if (flags & PD_VERBOSE)
         {
             buf_printf(&out, " tls_hmac=%s", format_hex(tls_auth_hmac, tls_auth_hmac_size, 0, gc));
         }
6fbf66fa
 
81d882d5
         if (!packet_id_read(&pin, &buf, true))
         {
             goto done;
         }
         buf_printf(&out, " pid=%s", packet_id_net_print(&pin, (flags & PD_VERBOSE), gc));
6fbf66fa
     }
 
81d882d5
     /*
      * ACK list
      */
     buf_printf(&out, " %s", reliable_ack_print(&buf, (flags & PD_VERBOSE), gc));
6fbf66fa
 
81d882d5
     if (op == P_ACK_V1)
     {
         goto done;
     }
6fbf66fa
 
81d882d5
     /*
      * Packet ID
      */
     {
         packet_id_type l;
         if (!buf_read(&buf, &l, sizeof(l)))
         {
             goto done;
         }
         l = ntohpid(l);
         buf_printf(&out, " pid=" packet_id_format, (packet_id_print_type)l);
     }
6fbf66fa
 
 print_data:
81d882d5
     if (flags & PD_SHOW_DATA)
     {
         buf_printf(&out, " DATA %s", format_hex(BPTR(&buf), BLEN(&buf), 80, gc));
     }
     else
     {
         buf_printf(&out, " DATA len=%d", buf.len);
     }
6fbf66fa
 
 done:
81d882d5
     return BSTR(&out);
6fbf66fa
 }
 
57116536
 void
 delayed_auth_pass_purge(void)
 {
     auth_user_pass.wait_for_push = false;
     purge_user_pass(&auth_user_pass, false);
 }