--- openvpn-2.4.7/configure.ac 2019-02-20 13:28:23.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/configure.ac 2019-08-29 12:56:28.000000000 +0200 @@ -405,6 +405,13 @@ ] ) +AX_CHECK_COMPILE_FLAG([ -Werror=implicit ], [ + CFLAGS="${CFLAGS} -Werror=implicit" +]) +AX_CHECK_COMPILE_FLAG([ -Werror=format -Werror=format-security ], [ + CFLAGS="${CFLAGS} -Werror=format -Werror=format-security" +]) + AC_C_CONST AC_C_INLINE AC_C_VOLATILE @@ -1362,6 +1369,8 @@ AC_SUBST([PLUGIN_AUTH_PAM_CFLAGS]) AC_SUBST([PLUGIN_AUTH_PAM_LIBS]) +AC_SUBST([OPENVPN_RELEASE], [PRODUCT_RELEASE]) + AM_CONDITIONAL([WIN32], [test "${WIN32}" = "yes"]) AM_CONDITIONAL([GIT_CHECKOUT], [test "${GIT_CHECKOUT}" = "yes"]) AM_CONDITIONAL([ENABLE_PLUGIN_AUTH_PAM], [test "${enable_plugin_auth_pam}" = "yes"]) --- openvpn-2.4.7/distro/systemd/openvpn-client@.service.in 2021-01-20 10:34:04.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/distro/systemd/openvpn-client@.service.in 2019-08-29 12:56:28.000000000 +0200 @@ -1,6 +1,6 @@ [Unit] Description=OpenVPN tunnel for %I -After=network-online.target +After=syslog.target network-online.target Wants=network-online.target Documentation=man:openvpn(8) Documentation=https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage --- openvpn-2.4.7/distro/systemd/openvpn-server@.service.in 2021-01-20 10:34:04.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/distro/systemd/openvpn-server@.service.in 2019-08-29 12:56:28.000000000 +0200 @@ -1,6 +1,6 @@ [Unit] Description=OpenVPN service for %I -After=network-online.target +After=syslog.target network-online.target Wants=network-online.target Documentation=man:openvpn(8) Documentation=https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage --- openvpn-2.4.7/doc/openvpn.8 2021-01-20 10:34:04.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/doc/openvpn.8 2019-08-29 12:56:28.000000000 +0200 @@ -2181,7 +2181,7 @@ is parsed on the command line even though the daemonization point occurs later. If one of the .B \-\-log -options is present, it will supersede syslog +options is present, it will supercede syslog redirection. The optional @@ -2292,7 +2292,7 @@ already exists it will be truncated. This option takes effect immediately when it is parsed in the command line -and will supersede syslog output if +and will supercede syslog output if .B \-\-daemon or .B \-\-inetd @@ -4280,6 +4280,17 @@ negotiation. .\"********************************************************* .TP +.B \-\-ncp\-enable +Enable "negotiable crypto parameters". Use this to enable server-side NCP. +Place this statement +.B after +any +.B server +or +.B mode server +statements in your config file. +.\"********************************************************* +.TP .B \-\-keysize n .B DEPRECATED This option will be removed in OpenVPN 2.6. @@ -4980,10 +4991,10 @@ The following profiles are supported: .B legacy -(default): SHA1 and newer, RSA 2048-bit+, any elliptic curve. +: SHA1 and newer, RSA 2048-bit+, any elliptic curve. .B preferred -: SHA2 and newer, RSA 2048-bit+, any elliptic curve. +(default): SHA2 and newer, RSA 2048-bit+, any elliptic curve. .B suiteb : SHA256/SHA384, ECDSA with P-256 or P-384. --- openvpn-2.4.7/sample/sample-config-files/client.conf 2021-01-20 10:34:04.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/sample/sample-config-files/client.conf 2019-08-29 12:56:28.000000000 +0200 @@ -59,7 +59,7 @@ # Downgrade privileges after initialization (non-Windows only) ;user nobody -;group nogroup +;group nobody # Try to preserve some state across restarts. persist-key --- openvpn-2.4.7/sample/sample-config-files/loopback-client 2019-02-20 13:28:20.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/sample/sample-config-files/loopback-client 2019-08-29 12:56:28.000000000 +0200 @@ -24,3 +24,5 @@ tls-auth sample-keys/ta.key 1 ping 1 inactive 120 10000000 +# Ensure testing does not wait for entropy (do not use in production) +min-platform-entropy 0 --- openvpn-2.4.7/sample/sample-config-files/loopback-server 2019-02-20 13:28:20.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/sample/sample-config-files/loopback-server 2019-08-29 12:56:28.000000000 +0200 @@ -24,3 +24,5 @@ tls-auth sample-keys/ta.key 0 ping 1 inactive 120 10000000 +# Ensure testing does not wait for entropy (do not use in production) +min-platform-entropy 0 --- openvpn-2.4.7/sample/sample-config-files/server.conf 2021-01-20 10:34:04.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/sample/sample-config-files/server.conf 2019-08-29 12:56:28.000000000 +0200 @@ -105,7 +105,7 @@ # is restarted, reconnecting clients can be assigned # the same virtual IP address from the pool that was # previously assigned. -ifconfig-pool-persist /var/log/openvpn/ipp.txt +ifconfig-pool-persist ipp.txt # Configure server mode for ethernet bridging. # You must first use your OS's bridging capability @@ -272,7 +272,7 @@ # You can uncomment this out on # non-Windows systems. ;user nobody -;group nogroup +;group nobody # The persist options will try to avoid # accessing certain resources on restart @@ -284,7 +284,7 @@ # Output a short status file showing # current connections, truncated # and rewritten every minute. -status /var/log/openvpn/openvpn-status.log +status openvpn-status.log # By default, log messages will go to the syslog (or # on Windows, if running as a service, they will go to @@ -293,8 +293,8 @@ # "log" will truncate the log file on OpenVPN startup, # while "log-append" will append to it. Use one # or the other (but not both). -;log /var/log/openvpn/openvpn.log -;log-append /var/log/openvpn/openvpn.log +;log openvpn.log +;log-append openvpn.log # Set the appropriate level of log # file verbosity. --- openvpn-2.4.7/sample/sample-config-files/static-home.conf 2021-01-20 10:34:04.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/sample/sample-config-files/static-home.conf 2019-08-29 12:56:28.000000000 +0200 @@ -43,7 +43,7 @@ # "nobody" after initialization # for extra security. ; user nobody -; group nogroup +; group nobody # If you built OpenVPN with # LZO compression, uncomment --- openvpn-2.4.7/sample/sample-config-files/static-office.conf 2021-01-20 10:34:04.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/sample/sample-config-files/static-office.conf 2019-08-29 12:56:28.000000000 +0200 @@ -40,7 +40,7 @@ # "nobody" after initialization # for extra security. ; user nobody -; group nogroup +; group nobody # If you built OpenVPN with # LZO compression, uncomment --- openvpn-2.4.7/sample/sample-config-files/tls-home.conf 2021-01-20 10:34:04.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/sample/sample-config-files/tls-home.conf 2019-08-29 12:56:28.000000000 +0200 @@ -51,7 +51,7 @@ # "nobody" after initialization # for extra security. ; user nobody -; group nogroup +; group nobody # If you built OpenVPN with # LZO compression, uncomment --- openvpn-2.4.7/sample/sample-config-files/tls-office.conf 2021-01-20 10:34:04.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/sample/sample-config-files/tls-office.conf 2019-08-29 12:56:28.000000000 +0200 @@ -51,7 +51,7 @@ # "nobody" after initialization # for extra security. ; user nobody -; group nogroup +; group nobody # If you built OpenVPN with # LZO compression, uncomment --- openvpn-2.4.7/sample/sample-keys/dh2048.pem 2019-02-20 13:28:20.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/sample/sample-keys/dh2048.pem 2019-08-29 12:56:28.000000000 +0200 @@ -1,8 +1,12 @@ -----BEGIN DH PARAMETERS----- -MIIBCAKCAQEArdnA32xujHPlPI+jPffHSoMUZ+b5gRz1H1Lw9//Gugm5TAsRiYrB -t2BDSsMKvAjyqN+i5SJv4TOk98kRRKB27iPvyXmiL945VaDQl/UehCySjYlGFUjW -9nuo+JwQxeSbw0TLiSYoYJZQ8X1CxPl9mgJl277O4cW1Gc8I/bWa+ipU/4K5wv3h -GI8nt+6A0jN3M/KebotMP101G4k0l0qsY4oRMTmP+z3oAP0qU9NZ1jiuMFVzRlNp -5FdYF7ctrH+tBF+QmyT4SRKSED4wE4oX6gp420NaBhIEQifIj75wlMDtxQlpkN+x -QkjsEbPlaPKHGQ4uupssChVUi8IM2yq5EwIBAg== +MIIBCAKCAQEA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlLOCDaAadWoxTpj0BV +89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N286Z4VeSWc39uK50 +T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/RgBYK+X0iP1YTknb +zSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2Ou1WMuF040zT9fBdX +Q6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQClCbAkbT +CD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwIBAg== -----END DH PARAMETERS----- + +These are the 2048 bit DH parameters from "Assigned Number for SKIP Protocols" +(http://www.skip-vpn.org/spec/numbers.html). +See there for how they were generated. --- openvpn-2.4.7/src/openvpn/Makefile.am 2019-02-20 13:28:23.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/Makefile.am 2019-08-29 12:56:28.000000000 +0200 @@ -38,6 +38,7 @@ sbin_PROGRAMS = openvpn openvpn_SOURCES = \ + allowed_crypto.c allowed_crypto.h \ argv.c argv.h \ base64.c base64.h \ basic.h \ --- openvpn-2.4.7/src/openvpn/allowed_crypto.c 1970-01-01 01:00:00.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/allowed_crypto.c 2019-08-29 12:56:28.000000000 +0200 @@ -0,0 +1,122 @@ +/* + * 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. + * + * Copyright (C) 2010-2016 Fox Crypto B.V. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** + * @file Restricted ciphers and digests code file. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + +#include "syshead.h" +#include "allowed_crypto.h" + +#ifdef ENABLE_CRYPTO + +/* Fox-IT hardening: only accept these data channel ciphers. */ +const char *allowed_data_channel_ciphers[] = { + "AES-256-CBC", + "AES-256-GCM", + NULL + }; + +/* Fox-IT hardening: only accept these data channel digests. */ +const char *allowed_data_channel_digests[] = { + "SHA256", + NULL + }; + +/* Fox-IT hardening: only accept these PRNG digests. */ +const char *allowed_prng_digests[] = { + "SHA256", + NULL + }; + + +/* + * Check whether a given cipher name is listed as allowed. + * Return 1 if the cipher is allowed, otherwise return 0. + */ +int is_allowed_data_channel_cipher(const char *name) +{ + const char **allowed = allowed_data_channel_ciphers; + for (; *allowed; ++allowed) + { + if (!strcasecmp(*allowed, name)) + return 1; + } + return 0; +} + +/* + * Check whether a given digest name is listed as allowed. + * Return 1 if the digest is allowed, otherwise return 0. + */ +int is_allowed_data_channel_digest(const char *name) +{ + const char **allowed = allowed_data_channel_digests; + for (; *allowed; ++allowed) + { + if (!strcasecmp(*allowed, name)) + return 1; + } + return 0; +} + +/* + * Check whether a given digest name is listed as allowed. + * Return 1 if the digest is allowed, otherwise return 0. + */ +int is_allowed_prng_digest(const char *name) +{ + const char **allowed = allowed_prng_digests; + for (; *allowed; ++allowed) + { + if (!strcasecmp(*allowed, name)) + return 1; + } + return 0; +} + +#ifdef ENABLE_CRYPTO_MBEDTLS +/* + * Check whether a given TLS cipher name is listed as allowed. + * Return 1 if the digest is allowed, otherwise return 0 + */ +int is_allowed_tls_cipher(const char *name) +{ + for (size_t i = 0; i < num_allowed_tls_cipher_suites; i++) + { + if (!strcasecmp(mbedtls_ssl_get_ciphersuite_name( + allowed_tls_cipher_suites[i]), name)) + return 1; + } + return 0; +} +#endif + +#endif /* ENABLE_CRYPTO */ --- openvpn-2.4.7/src/openvpn/allowed_crypto.h 1970-01-01 01:00:00.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/allowed_crypto.h 2019-08-29 12:56:28.000000000 +0200 @@ -0,0 +1,102 @@ +/* + * 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. + * + * Copyright (C) 2010-2016 Fox Crypto B.V. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/** + * @file Restricted ciphers and digests code file. + */ + +#ifndef _FOXIT_ALLOWED_CRYPTO_H_ +#define _FOXIT_ALLOWED_CRYPTO_H_ + +#ifdef ENABLE_CRYPTO + +#ifdef ENABLE_CRYPTO_MBEDTLS +#include + +/** + * List of allowed TLS ciphers. + * + * Lists the TLS cipher suites which can be used by the mbed TLS + * implementation. The are restricted by setting the allowed_ciphers + * in tls_root_ctx. + */ +static const int allowed_tls_cipher_suites[] = { + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + 0 +}; +static const size_t num_allowed_tls_cipher_suites = + sizeof(allowed_tls_cipher_suites)/sizeof(*allowed_tls_cipher_suites) - 1; + +#else +/** + * List of allowed TLS ciphers. + * + * This string lists the ciphers which can be used by the OpenSSL + * TLS implementation. The ciphers that OpenSSL will use are + * restricted by passing this string to the + * \c SSL_CTX_set_cipher_list() function. + */ +static const char *allowed_tls_ciphers = + "SSL-EDH-RSA-AES-256-SHA"; +#endif + + +/** + * Check whether a given cipher name is allowed. + * + * @param name - the cipher name to check. + * @return 1 if the cipher is acceptable, otherwise return 0. + */ +int is_allowed_data_channel_cipher(const char *name); + + +/** + * Check whether a given digest name is allowed. + * + * @param name - the digest name to check. + * @return 1 if the digest is acceptable, otherwise return 0. + */ +int is_allowed_data_channel_digest(const char *name); + +/** + * Check whether a given digest name is allowed. + * + * @param name - the digest name to check. + * @return 1 if the digest is acceptable, otherwise return 0. + */ +int is_allowed_prng_digest(const char *name); + +#ifdef ENABLE_CRYPTO_MBEDTLS +/* + * Check whether a given TLS cipher name is listed as allowed. + * Return 1 if the digest is allowed, otherwise return 0 + */ +int is_allowed_tls_cipher(const char *name); +#endif + +#endif /* ENABLE_CRYPTO */ +#endif /* _FOXIT_ALLOWED_CRYPTO_H_ */ --- openvpn-2.4.7/src/openvpn/buffer.c 2021-01-20 10:34:04.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/buffer.c 2019-08-29 12:56:28.000000000 +0200 @@ -44,7 +44,7 @@ unsigned long long res = (unsigned long long)m1 * (unsigned long long)m2 + (unsigned long long)extra; if (unlikely(m1 > limit) || unlikely(m2 > limit) || unlikely(extra > limit) || unlikely(res > (unsigned long long)limit)) { - msg(M_FATAL, "attempted allocation of excessively large array"); + msg(M_FATAL, "attemped allocation of excessively large array"); } return (size_t) res; } --- openvpn-2.4.7/src/openvpn/buffer.h 2019-02-20 13:28:23.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/buffer.h 2019-08-29 12:56:28.000000000 +0200 @@ -914,6 +914,11 @@ bool string_class(const char *str, const unsigned int inclusive, const unsigned int exclusive); +/** + * Modify string in place. Guaranteed to not increase string length. + * + * @return true if no replacements have been made, false otherwise. + */ bool string_mod(char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace); const char *string_mod_const(const char *str, --- openvpn-2.4.7/src/openvpn/crypto.c 2021-01-20 10:34:04.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/crypto.c 2019-08-29 12:56:28.000000000 +0200 @@ -32,6 +32,7 @@ #ifdef ENABLE_CRYPTO +#include "allowed_crypto.h" #include "crypto.h" #include "error.h" #include "integer.h" @@ -77,7 +78,6 @@ /* IV, packet-ID and implicit IV required for this mode. */ ASSERT(ctx->cipher); ASSERT(cipher_kt_mode_aead(cipher_kt)); - ASSERT(opt->flags & CO_USE_IV); ASSERT(packet_id_initialized(&opt->packet_id)); gc_init(&gc); @@ -192,10 +192,7 @@ if (cipher_kt_mode_cbc(cipher_kt)) { /* generate pseudo-random IV */ - if (opt->flags & CO_USE_IV) - { prng_bytes(iv_buf, iv_size); - } /* Put packet ID in plaintext buffer */ if (packet_id_initialized(&opt->packet_id) @@ -207,28 +204,26 @@ goto err; } } +#ifdef ENABLE_OFB_CFB_MODE else if (cipher_kt_mode_ofb_cfb(cipher_kt)) { struct buffer b; - /* IV and packet-ID required for this mode. */ - ASSERT(opt->flags & CO_USE_IV); + /* packet-ID required for this mode. */ ASSERT(packet_id_initialized(&opt->packet_id)); buf_set_write(&b, iv_buf, iv_size); ASSERT(packet_id_write(&opt->packet_id.send, &b, true, false)); } +#endif else /* We only support CBC, CFB, or OFB modes right now */ { ASSERT(0); } /* set the IV pseudo-randomly */ - if (opt->flags & CO_USE_IV) - { ASSERT(buf_write(&work, iv_buf, iv_size)); dmsg(D_PACKET_CONTENT, "ENCRYPT IV: %s", format_hex(iv_buf, iv_size, 0, &gc)); - } dmsg(D_PACKET_CONTENT, "ENCRYPT FROM: %s", format_hex(BPTR(buf), BLEN(buf), 80, &gc)); @@ -358,13 +353,13 @@ return ret; } -/* - * If (opt->flags & CO_USE_IV) is not NULL, we will read an IV from the packet. +/** + * Unwrap (authenticate, decrypt and check replay protection) AEAD-mode data + * channel packets. * * Set buf->len to 0 and return false on decrypt error. * - * On success, buf is set to point to plaintext, true - * is returned. + * On success, buf is set to point to plaintext, true is returned. */ static bool openvpn_decrypt_aead(struct buffer *buf, struct buffer work, @@ -398,7 +393,6 @@ /* IV and Packet ID required for this mode */ ASSERT(packet_id_initialized(&opt->packet_id)); - ASSERT(opt->flags & CO_USE_IV); /* Combine IV from explicit part from packet and implicit part from context */ { @@ -507,12 +501,12 @@ } /* - * If (opt->flags & CO_USE_IV) is not NULL, we will read an IV from the packet. + * Unwrap (authenticate, decrypt and check replay protection) CBC, OFB or CFB + * mode data channel packets. * * Set buf->len to 0 and return false on decrypt error. * - * On success, buf is set to point to plaintext, true - * is returned. + * On success, buf is set to point to plaintext, true is returned. */ static bool openvpn_decrypt_v1(struct buffer *buf, struct buffer work, @@ -572,22 +566,14 @@ /* initialize work buffer with FRAME_HEADROOM bytes of prepend capacity */ ASSERT(buf_init(&work, FRAME_HEADROOM_ADJ(frame, FRAME_HEADROOM_MARKER_DECRYPT))); - /* use IV if user requested it */ - if (opt->flags & CO_USE_IV) - { + /* read the IV from the packet */ if (buf->len < iv_size) { CRYPT_ERROR("missing IV info"); } memcpy(iv_buf, BPTR(buf), iv_size); ASSERT(buf_advance(buf, iv_size)); - } - - /* show the IV's initial state */ - if (opt->flags & CO_USE_IV) - { dmsg(D_PACKET_CONTENT, "DECRYPT IV: %s", format_hex(iv_buf, iv_size, 0, &gc)); - } if (buf->len < 1) { @@ -636,12 +622,12 @@ have_pin = true; } } +#ifdef ENABLE_OFB_CFB_MODE else if (cipher_kt_mode_ofb_cfb(cipher_kt)) { struct buffer b; - /* IV and packet-ID required for this mode. */ - ASSERT(opt->flags & CO_USE_IV); + /* packet-ID required for this mode. */ ASSERT(packet_id_initialized(&opt->packet_id)); buf_set_read(&b, iv_buf, iv_size); @@ -651,6 +637,7 @@ } have_pin = true; } +#endif else /* We only support CBC, CFB, or OFB modes right now */ { ASSERT(0); @@ -717,7 +704,6 @@ void crypto_adjust_frame_parameters(struct frame *frame, const struct key_type *kt, - bool use_iv, bool packet_id, bool packet_id_long_form) { @@ -730,10 +716,7 @@ if (kt->cipher) { - if (use_iv) - { crypto_overhead += cipher_kt_iv_size(kt->cipher); - } if (cipher_kt_mode_aead(kt->cipher)) { @@ -775,6 +758,12 @@ CLEAR(*kt); if (strcmp(ciphername, "none") != 0) { + /* Fox-IT hardening: only accept certain ciphers. */ + if (!is_allowed_data_channel_cipher(ciphername)) + { + msg (M_FATAL, "Cipher '%s' not allowed", ciphername); + } + kt->cipher = cipher_kt_get(translate_cipher_name_from_openvpn(ciphername)); if (!kt->cipher) { @@ -806,18 +795,19 @@ } else { - if (warn) - { - msg(M_WARN, "******* WARNING *******: '--cipher none' was specified. " - "This means NO encryption will be performed and tunnelled " - "data WILL be transmitted in clear text over the network! " - "PLEASE DO RECONSIDER THIS SETTING!"); - } + /* Fox-IT hardening: only accept certain ciphers; none not allowed. */ + msg (M_FATAL, "Cipher '%s' not allowed", ciphername); } if (strcmp(authname, "none") != 0) { if (!aead_cipher) /* Ignore auth for AEAD ciphers */ { + /* Fox-IT hardening: only accept certain digests. */ + if (!is_allowed_data_channel_digest(authname)) + { + msg (M_FATAL, "Message hash algorithm '%s' not allowed", authname); + } + kt->digest = md_kt_get(authname); kt->hmac_length = md_kt_size(kt->digest); @@ -829,14 +819,8 @@ } else if (!aead_cipher) { - if (warn) - { - msg(M_WARN, "******* WARNING *******: '--auth none' was specified. " - "This means no authentication will be performed on received " - "packets, meaning you CANNOT trust that the data received by " - "the remote side have NOT been manipulated. " - "PLEASE DO RECONSIDER THIS SETTING!"); - } + /* Fox-IT hardening: only accept certain digests; 'none' not allowed. */ + msg (M_FATAL, "Message hash algorithm '%s' not allowed", authname); } } @@ -876,7 +860,7 @@ if (kt->digest && kt->hmac_length > 0) { ctx->hmac = hmac_ctx_new(); - hmac_ctx_init(ctx->hmac, key->hmac, kt->hmac_length, kt->digest, 0); + hmac_ctx_init(ctx->hmac, key->hmac, kt->hmac_length, kt->digest); msg(D_HANDSHAKE, "%s: Using %d bit message hash '%s' for HMAC authentication", @@ -1026,15 +1010,14 @@ } void -check_replay_iv_consistency(const struct key_type *kt, bool packet_id, bool use_iv) +check_replay_consistency(const struct key_type *kt, bool packet_id) { ASSERT(kt); - if (!(packet_id && use_iv) && (cipher_kt_mode_ofb_cfb(kt->cipher) + if (!packet_id && (cipher_kt_mode_ofb_cfb(kt->cipher) || cipher_kt_mode_aead(kt->cipher))) { - msg(M_FATAL, "--no-replay or --no-iv cannot be used with a CFB, OFB or " - "AEAD mode cipher"); + msg(M_FATAL, "--no-replay cannot be used with a CFB, OFB or AEAD mode cipher"); } } @@ -1758,6 +1741,13 @@ prng_init(const char *md_name, const int nonce_secret_len_parm) { prng_uninit(); + + /* Fox-IT hardening: only accept certain digests. */ + if (md_name && !is_allowed_prng_digest(md_name)) + { + msg (M_FATAL, "Message hash algorithm '%s' not allowed for the PRNG", md_name); + } + nonce_md = md_name ? md_kt_get(md_name) : NULL; if (nonce_md) { --- openvpn-2.4.7/src/openvpn/crypto.h 2019-02-20 13:28:23.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/crypto.h 2019-08-29 12:56:28.000000000 +0200 @@ -38,8 +38,7 @@ * - \b HMAC, covering the ciphertext IV + ciphertext. The HMAC size depends * on the \c \-\-auth option. If \c \-\-auth \c none is specified, there is no * HMAC at all. - * - \b Ciphertext \b IV, if not disabled by \c \-\-no-iv. The IV size depends on - * the \c \-\-cipher option. + * - \b Ciphertext \b IV. The IV size depends on the \c \-\-cipher option. * - \b Packet \b ID, a 32-bit incrementing packet counter that provides replay * protection (if not disabled by \c \-\-no-replay). * - \b Timestamp, a 32-bit timestamp of the current time. @@ -123,6 +122,10 @@ #ifndef CRYPTO_H #define CRYPTO_H +#ifdef ENABLE_OFB_CFB_MODE +#error Fox-IT hardening: OFB/CFB mode disabled +#endif + #ifdef ENABLE_CRYPTO #include "crypto_backend.h" @@ -131,6 +134,11 @@ #include "packet_id.h" #include "mtu.h" +/** + * Maximum number of bytes read from /dev/random on startup. + */ +#define FOX_MIN_PLATFORM_ENTROPY_MAX 32 + /** Wrapper struct to pass around SHA256 digests */ struct sha256_digest { uint8_t digest[SHA256_DIGEST_LENGTH]; @@ -248,17 +256,13 @@ #define CO_PACKET_ID_LONG_FORM (1<<0) /**< Bit-flag indicating whether to use * OpenVPN's long packet ID format. */ -#define CO_USE_IV (1<<1) - /**< Bit-flag indicating whether to - * generate a pseudo-random IV for each - * packet being encrypted. */ -#define CO_IGNORE_PACKET_ID (1<<2) +#define CO_IGNORE_PACKET_ID (1<<1) /**< Bit-flag indicating whether to ignore * the packet ID of a received packet. * This flag is used during processing * of the first packet received from a * client. */ -#define CO_MUTE_REPLAY_WARNINGS (1<<3) +#define CO_MUTE_REPLAY_WARNINGS (1<<2) /**< Bit-flag indicating not to display * replay warnings. */ unsigned int flags; /**< Bit-flags determining behavior of @@ -287,7 +291,7 @@ void generate_key_random(struct key *key, const struct key_type *kt); -void check_replay_iv_consistency(const struct key_type *kt, bool packet_id, bool use_iv); +void check_replay_consistency(const struct key_type *kt, bool packet_id); bool check_key(struct key *key, const struct key_type *kt); @@ -421,7 +425,6 @@ /** Calculate crypto overhead and adjust frame to account for that */ void crypto_adjust_frame_parameters(struct frame *frame, const struct key_type *kt, - bool use_iv, bool packet_id, bool packet_id_long_form); --- openvpn-2.4.7/src/openvpn/crypto_backend.h 2021-01-20 10:34:04.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/crypto_backend.h 2019-08-29 12:56:28.000000000 +0200 @@ -125,6 +125,17 @@ */ int rand_bytes(uint8_t *output, int len); +/** + * Feed bytes into local entropy pool. + * + * @param data Pointer to data to feed in. + * @param len Length of data, in bytes. + * + * @return true on success, false on failure + */ +bool rand_update_manual(const void *data, size_t len); + + /* * * Key functions, allow manipulation of keys. @@ -604,11 +615,10 @@ * @param key The key to use for the HMAC * @param key_len The key length to use * @param kt Static message digest parameters - * @param prf_use Intended use for PRF in TLS protocol * */ void hmac_ctx_init(hmac_ctx_t *ctx, const uint8_t *key, int key_length, - const md_kt_t *kt, bool prf_use); + const md_kt_t *kt); /* * Free the given HMAC context. --- openvpn-2.4.7/src/openvpn/crypto_mbedtls.c 2021-01-20 10:34:04.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/crypto_mbedtls.c 2019-08-29 12:56:28.000000000 +0200 @@ -36,6 +36,7 @@ #if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_MBEDTLS) +#include "allowed_crypto.h" #include "errlevel.h" #include "basic.h" #include "buffer.h" @@ -53,6 +54,14 @@ #include +/** + * Entropy is gathered every FOX_ENTROPY_GATHER_FREQUENCY calls to the + * rand_bytes function. This is a fail-safe for when mbedtls's internal + * entropy gathering somehow fails to periodically gather entropy. + */ +#define FOX_ENTROPY_GATHER_FREQUENCY 100 + + /* * * Hardware engine support. Allows loading/unloading of engines. @@ -141,7 +150,8 @@ static void print_cipher(const cipher_kt_t *info) { - if (info && (cipher_kt_mode_cbc(info) + if (info && is_allowed_data_channel_cipher(cipher_kt_name(info)) + && (cipher_kt_mode_cbc(info) #ifdef HAVE_AEAD_CIPHER_MODES || cipher_kt_mode_aead(info) #endif @@ -212,7 +222,7 @@ { const mbedtls_md_info_t *info = mbedtls_md_info_from_type(*digests); - if (info) + if (info && is_allowed_data_channel_digest(md_kt_name(info))) { printf("%s %d bit default key\n", mbedtls_md_get_name(info), mbedtls_md_get_size(info) * 8); @@ -259,7 +269,8 @@ * 800-90 section 8.7.1). We have very little information at this stage. * Include Program Name, memory address of the context and PID. */ - buf_printf(&pers_string, "OpenVPN %0u %p %s", platform_getpid(), &cd_ctx, time_string(0, 0, 0, &gc)); + buf_printf(&pers_string, "OpenVPN %0u %p %s", platform_getpid(), + &cd_ctx, time_string(0, 0, true, &gc)); /* Initialise mbed TLS RNG, and built-in entropy sources */ mbedtls_entropy_init(&ec); @@ -291,6 +302,7 @@ int rand_bytes(uint8_t *output, int len) { + static int gather_delay = 0; mbedtls_ctr_drbg_context *rng_ctx = rand_ctx_get(); while (len > 0) @@ -303,11 +315,39 @@ output += blen; len -= blen; + + /* Hardening: add fail-safe entropy gathering */ + if (gather_delay++ >= FOX_ENTROPY_GATHER_FREQUENCY) + { + mbedtls_entropy_context *e_ctx = rng_ctx->p_entropy; + ASSERT(e_ctx != NULL); + if (0 != mbedtls_entropy_gather(e_ctx)) + return 0; + + gather_delay = 0; + } } return 1; } +bool rand_update_manual(const void *data, size_t len) +{ + mbedtls_ctr_drbg_context *rng_ctx = rand_ctx_get(); + + if (!rng_ctx) + { + return false; + } + + if (!mbed_ok(mbedtls_entropy_update_manual(rng_ctx->p_entropy, data, len))) + { + return false; + } + + return true; +} + /* * * Key functions, allow manipulation of keys. @@ -858,7 +898,7 @@ void hmac_ctx_init(mbedtls_md_context_t *ctx, const uint8_t *key, int key_len, - const mbedtls_md_info_t *kt, bool prf_use) + const mbedtls_md_info_t *kt) { ASSERT(NULL != kt && NULL != ctx); --- openvpn-2.4.7/src/openvpn/crypto_openssl.c 2021-01-20 10:34:04.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/crypto_openssl.c 2019-08-29 12:56:28.000000000 +0200 @@ -36,6 +36,7 @@ #if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_OPENSSL) +#include "allowed_crypto.h" #include "basic.h" #include "buffer.h" #include "integer.h" @@ -279,14 +280,17 @@ const char *var_key_size = (EVP_CIPHER_flags(cipher) & EVP_CIPH_VARIABLE_LENGTH) ? " by default" : ""; - const char *ssl_only = cipher_kt_mode_cbc(cipher) ? - "" : ", TLS client/server mode only"; + const char *ssl_only = ", TLS client/server mode only"; + if (is_allowed_data_channel_cipher( + translate_cipher_name_to_openvpn(EVP_CIPHER_name(cipher)))) + { printf("%s (%d bit key%s, %d bit block%s)\n", translate_cipher_name_to_openvpn(EVP_CIPHER_name(cipher)), EVP_CIPHER_key_length(cipher) * 8, var_key_size, cipher_kt_block_size(cipher) * 8, ssl_only); } +} void show_available_ciphers(void) @@ -416,6 +420,14 @@ return 1; } +bool +rand_update_manual(const void *data, size_t len) +{ + /* Assume a conservative 1 bit entropy per byte */ + RAND_add(data, len, len/8); + return true; +} + /* * * Key functions, allow manipulation of keys. @@ -935,17 +947,11 @@ void hmac_ctx_init(HMAC_CTX *ctx, const uint8_t *key, int key_len, - const EVP_MD *kt, bool prf_use) + const EVP_MD *kt) { ASSERT(NULL != kt && NULL != ctx); HMAC_CTX_reset(ctx); - - /* FIPS 140-2 explicitly allows MD5 for the use in PRF although it is not - * to be used anywhere else */ - if(kt == EVP_md5() && prf_use) - HMAC_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - HMAC_Init_ex(ctx, key, key_len, kt, NULL); /* make sure we used a big enough key */ --- openvpn-2.4.7/src/openvpn/init.c 2019-02-20 13:28:23.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/init.c 2019-08-29 12:56:28.000000000 +0200 @@ -865,8 +865,7 @@ struct gc_arena gc = gc_new(); uint8_t rndbuf[8]; int i; - prng_init("sha1", 16); - /*prng_init (NULL, 0);*/ + prng_init("sha256", 16); const int factor = 1; for (i = 0; i < factor * 8; ++i) { @@ -2505,11 +2504,6 @@ init_crypto_pre(c, flags); /* Initialize flags */ - if (c->options.use_iv) - { - c->c2.crypto_options.flags |= CO_USE_IV; - } - if (c->options.mute_replay_warnings) { c->c2.crypto_options.flags |= CO_MUTE_REPLAY_WARNINGS; @@ -2550,13 +2544,11 @@ c->c2.crypto_options.key_ctx_bi = c->c1.ks.static_key; /* Compute MTU parameters */ - crypto_adjust_frame_parameters(&c->c2.frame, - &c->c1.ks.key_type, - options->use_iv, options->replay, true); - - /* Sanity check on IV, sequence number, and cipher mode options */ - check_replay_iv_consistency(&c->c1.ks.key_type, options->replay, - options->use_iv); + crypto_adjust_frame_parameters(&c->c2.frame, &c->c1.ks.key_type, + options->replay, true); + + /* Sanity check on sequence number, and cipher mode options */ + check_replay_consistency(&c->c1.ks.key_type, options->replay); } /* @@ -2674,9 +2666,8 @@ return; } - /* Sanity check on IV, sequence number, and cipher mode options */ - check_replay_iv_consistency(&c->c1.ks.key_type, options->replay, - options->use_iv); + /* Sanity check on sequence number, and cipher mode options */ + check_replay_consistency(&c->c1.ks.key_type, options->replay); /* In short form, unique datagram identifier is 32 bits, in long form 64 bits */ packet_id_long_form = cipher_kt_mode_ofb_cfb(c->c1.ks.key_type.cipher); @@ -2690,18 +2681,13 @@ else { crypto_adjust_frame_parameters(&c->c2.frame, &c->c1.ks.key_type, - options->use_iv, options->replay, packet_id_long_form); + options->replay, packet_id_long_form); } tls_adjust_frame_parameters(&c->c2.frame); /* Set all command-line TLS-related options */ CLEAR(to); - if (options->use_iv) - { - to.crypto_flags |= CO_USE_IV; - } - if (options->mute_replay_warnings) { to.crypto_flags |= CO_MUTE_REPLAY_WARNINGS; @@ -2838,9 +2824,8 @@ to.tls_wrap.opt.key_ctx_bi = c->c1.ks.tls_wrap_key; to.tls_wrap.opt.pid_persist = &c->c1.pid_persist; to.tls_wrap.opt.flags |= CO_PACKET_ID_LONG_FORM; - crypto_adjust_frame_parameters(&to.frame, - &c->c1.ks.tls_auth_key_type, - false, true, true); + crypto_adjust_frame_parameters(&to.frame, &c->c1.ks.tls_auth_key_type, + true, true); } /* TLS handshake encryption (--tls-crypt) */ @@ -2890,41 +2875,53 @@ } } -/* - * No encryption or authentication. - */ -static void -do_init_crypto_none(const struct context *c) -{ - ASSERT(!c->options.test_crypto); - msg(M_WARN, - "******* WARNING *******: All encryption and authentication features " - "disabled -- All data will be tunnelled as clear text and will not be " - "protected against man-in-the-middle changes. " - "PLEASE DO RECONSIDER THIS CONFIGURATION!"); -} #endif /* ifdef ENABLE_CRYPTO */ static void do_init_crypto(struct context *c, const unsigned int flags) { -#ifdef ENABLE_CRYPTO - if (c->options.shared_secret_file) +#if !defined(_WIN32) + if (c->first_time) { - do_init_crypto_static(c, flags); + /* + * Fox-IT hardening: + * On unix-like platforms, read a few bytes from /dev/random to block + * until at least the platform believes to have gathered enough + * entropy. + */ + char tmp_buf[FOX_MIN_PLATFORM_ENTROPY_MAX] = { 0 }; + ASSERT(c->options.min_platform_entropy <= FOX_MIN_PLATFORM_ENTROPY_MAX); + msg(M_INFO, "Waiting for platform entropy, this may take a while..."); + FILE *dev_random = fopen( "/dev/random", "rb" ); + if (dev_random == NULL) + { + msg(M_FATAL, "Failed to open /dev/random"); } - else if (c->options.tls_server || c->options.tls_client) + + int read_len = fread(tmp_buf, 1, c->options.min_platform_entropy, + dev_random); + if (read_len != c->options.min_platform_entropy) + { + fclose(dev_random); + msg(M_FATAL, "Failed to read from /dev/random"); + } + + fclose(dev_random); + } +#endif + +#ifdef ENABLE_CRYPTO + if (c->options.tls_server || c->options.tls_client) { do_init_crypto_tls(c, flags); } - else /* no encryption or authentication. */ + else { - do_init_crypto_none(c); + msg(M_FATAL, "OpenVPN-NL requires enabling TLS. " + "Please use --server/--client (or --tls-server/--tls-client)"); } #else /* ENABLE_CRYPTO */ - msg(M_WARN, - "******* WARNING *******: " PACKAGE_NAME - " built without crypto library -- encryption and authentication features disabled -- all data will be tunnelled as cleartext"); +#error Fox-IT hardening: crypto MUST be enabled. #endif /* ENABLE_CRYPTO */ } @@ -3127,11 +3124,7 @@ #ifdef ENABLE_CRYPTO if (!o->replay) { - msg(M_WARN, "WARNING: You have disabled Replay Protection (--no-replay) which may make " PACKAGE_NAME " less secure"); - } - if (!o->use_iv) - { - msg(M_WARN, "WARNING: You have disabled Crypto IVs (--no-iv) which may make " PACKAGE_NAME " less secure"); + msg(M_FATAL, "ERROR: You attempted to disable Replay Protection (--no-replay) which may make " PACKAGE_NAME " less secure"); } if (o->tls_server) @@ -3144,7 +3137,7 @@ && !(o->ns_cert_type & NS_CERT_CHECK_SERVER) && !o->remote_cert_eku) { - msg(M_WARN, "WARNING: No server certificate verification method has been enabled. See http://openvpn.net/howto.html#mitm for more info."); + msg(M_FATAL, "ERROR: No server certificate verification method has been enabled. See http://openvpn.net/howto.html#mitm for more info."); } if (o->ns_cert_type) { --- openvpn-2.4.7/src/openvpn/lladdr.c 2021-01-20 10:34:04.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/lladdr.c 2019-08-29 12:56:28.000000000 +0200 @@ -50,7 +50,7 @@ "%s %s lladdr %s", IFCONFIG_PATH, ifname, lladdr); -#elif defined(TARGET_FREEBSD) || defined(__FreeBSD_kernel__) +#elif defined(TARGET_FREEBSD) argv_printf(&argv, "%s %s ether %s", IFCONFIG_PATH, --- openvpn-2.4.7/src/openvpn/ntlm.c 2021-01-20 10:34:04.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/ntlm.c 2019-08-29 12:56:28.000000000 +0200 @@ -88,7 +88,7 @@ const md_kt_t *md5_kt = md_kt_get("MD5"); hmac_ctx_t *hmac_ctx = hmac_ctx_new(); - hmac_ctx_init(hmac_ctx, key, key_len, md5_kt, 0); + hmac_ctx_init(hmac_ctx, key, key_len, md5_kt); hmac_ctx_update(hmac_ctx, data, data_len); hmac_ctx_final(hmac_ctx, result); hmac_ctx_cleanup(hmac_ctx); --- openvpn-2.4.7/src/openvpn/options.c 2021-01-20 10:34:04.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/options.c 2019-08-29 12:56:28.000000000 +0200 @@ -197,7 +197,7 @@ " is established. Multiple routes can be specified.\n" " netmask default: 255.255.255.255\n" " gateway default: taken from --route-gateway or --ifconfig\n" - " Specify default by leaving blank or setting to \"default\".\n" + " Specify default by leaving blank or setting to \"nil\".\n" "--route-ipv6 network/bits [gateway] [metric] :\n" " Add IPv6 route to routing table after connection\n" " is established. Multiple routes can be specified.\n" @@ -435,11 +435,6 @@ " Only valid in a client-specific config file.\n" "--disable : Client is disabled.\n" " Only valid in a client-specific config file.\n" - "--client-cert-not-required : (DEPRECATED) Don't require client certificate, client\n" - " will authenticate using username/password.\n" - "--verify-client-cert [none|optional|require] : perform no, optional or\n" - " mandatory client certificate verification.\n" - " Default is to require the client to supply a certificate.\n" "--username-as-common-name : For auth-user-pass authentication, use\n" " the authenticated username as the common name,\n" " rather than the common name from the client cert.\n" @@ -448,7 +443,7 @@ " user/pass via environment, if method='via-file', pass\n" " user/pass via temporary file.\n" "--auth-gen-token [lifetime] Generate a random authentication token which is pushed\n" - " to each client, replacing the password. Useful when\n" + " to each client, replacing the password. Usefull when\n" " OTP based two-factor auth mechanisms are in use and\n" " --reneg-* options are enabled. Optionally a lifetime in seconds\n" " for generated tokens can be set.\n" @@ -522,12 +517,7 @@ "\n" "Data Channel Encryption Options (must be compatible between peers):\n" "(These options are meaningful for both Static Key & TLS-mode)\n" - "--secret f [d] : Enable Static Key encryption mode (non-TLS).\n" - " Use shared secret file f, generate with --genkey.\n" - " The optional d parameter controls key directionality.\n" - " If d is specified, use separate keys for each\n" - " direction, set d=0 on one side of the connection,\n" - " and d=1 on the other side.\n" + /* Fox-IT hardening: removed secret option. */ "--auth alg : Authenticate packets with HMAC using message\n" " digest algorithm alg (default=%s).\n" " (usually adds 16 or 20 bytes per packet)\n" @@ -537,6 +527,7 @@ " Set alg=none to disable encryption.\n" "--ncp-ciphers list : List of ciphers that are allowed to be negotiated.\n" "--ncp-disable : Disable cipher negotiation.\n" + "--ncp-enable : Enable cipher negotiation.\n" "--prng alg [nsl] : For PRNG, use digest algorithm alg, and\n" " nonce_secret_len=nsl. Set alg=none to disable PRNG.\n" #ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH @@ -546,12 +537,10 @@ #ifndef ENABLE_CRYPTO_MBEDTLS "--engine [name] : Enable OpenSSL hardware crypto engine functionality.\n" #endif - "--no-replay : (DEPRECATED) Disable replay protection.\n" "--mute-replay-warnings : Silence the output of replay warnings to log file.\n" "--replay-window n [t] : Use a replay protection sliding window of size n\n" " and a time window of t seconds.\n" " Default n=%d t=%d\n" - "--no-iv : Disable cipher IV -- only allowed with CBC mode ciphers.\n" "--replay-persist file : Persist replay-protection state across sessions\n" " using file.\n" "--test-crypto : Run a self-test of crypto features enabled.\n" @@ -560,6 +549,10 @@ "--use-prediction-resistance: Enable prediction resistance on the random\n" " number generator.\n" #endif +#ifdef TARGET_LINUX + "--min-platform-entropy: The minimum number of bytes of /dev/random\n" + " entropy required at startup.\n" +#endif "\n" "TLS Key Negotiation Options:\n" "(These options are meaningful only for TLS-mode)\n" @@ -744,7 +737,7 @@ "\n" "Generate a random key (only for non-TLS static key encryption mode):\n" "--genkey : Generate a random key to be used as a shared secret,\n" - " for use with the --secret option.\n" + " for use with the --tls-auth or --tls-crypt option.\n" "--secret file : Write key to file.\n" #endif /* ENABLE_CRYPTO */ #ifdef ENABLE_FEATURE_TUN_PERSIST @@ -851,24 +844,24 @@ o->scheduled_exit_interval = 5; #endif #ifdef ENABLE_CRYPTO - o->ciphername = "BF-CBC"; + o->ciphername = "AES-256-CBC"; #ifdef HAVE_AEAD_CIPHER_MODES /* IV_NCP=2 requires GCM support */ o->ncp_enabled = true; #else o->ncp_enabled = false; #endif - o->ncp_ciphers = "AES-256-GCM:AES-128-GCM"; - o->authname = "SHA1"; - o->prng_hash = "SHA1"; + o->ncp_ciphers = "AES-256-GCM"; + o->authname = "SHA256"; + o->prng_hash = "SHA256"; o->prng_nonce_secret_len = 16; o->replay = true; o->replay_window = DEFAULT_SEQ_BACKTRACK; o->replay_time = DEFAULT_TIME_BACKTRACK; - o->use_iv = true; o->key_direction = KEY_DIRECTION_BIDIRECTIONAL; #ifdef ENABLE_PREDICTION_RESISTANCE o->use_prediction_resistance = false; #endif + o->min_platform_entropy = 16; o->key_method = 2; o->tls_timeout = 2; o->renegotiate_bytes = -1; @@ -876,6 +869,9 @@ o->handshake_window = 60; o->transition_window = 3600; o->tls_cert_profile = NULL; + o->cipher_list = "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384:" + "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:" + "TLS-DHE-RSA-WITH-AES-256-CBC-SHA256"; o->ecdh_curve = NULL; #ifdef ENABLE_X509ALTUSERNAME o->x509_username_field = X509_USERNAME_FIELD_DEFAULT; @@ -1671,11 +1667,11 @@ SHOW_INT(replay_window); SHOW_INT(replay_time); SHOW_STR(packet_id_file); - SHOW_BOOL(use_iv); SHOW_BOOL(test_crypto); #ifdef ENABLE_PREDICTION_RESISTANCE SHOW_BOOL(use_prediction_resistance); #endif + SHOW_INT(min_platform_entropy); SHOW_BOOL(tls_server); SHOW_BOOL(tls_client); @@ -1708,7 +1704,6 @@ SHOW_STR(cryptoapi_cert); #endif SHOW_STR(cipher_list); - SHOW_STR(cipher_list_tls13); SHOW_STR(tls_cert_profile); SHOW_STR(tls_verify); SHOW_STR(tls_export_cert); @@ -2338,10 +2333,6 @@ || PLUGIN_OPTION_LIST(options) || MAN_CLIENT_AUTH_ENABLED(options)); const char *postfix = "must be used with --management-client-auth, an --auth-user-pass-verify script, or plugin"; - if ((options->ssl_flags & (SSLF_CLIENT_CERT_NOT_REQUIRED|SSLF_CLIENT_CERT_OPTIONAL)) && !ccnr) - { - msg(M_USAGE, "--verify-client-cert none|optional %s", postfix); - } if ((options->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME) && !ccnr) { msg(M_USAGE, "--username-as-common-name %s", postfix); @@ -2399,10 +2390,6 @@ { msg(M_USAGE, "--connect-freq requires --mode server"); } - if (options->ssl_flags & (SSLF_CLIENT_CERT_NOT_REQUIRED|SSLF_CLIENT_CERT_OPTIONAL)) - { - msg(M_USAGE, "--client-cert-not-required and --verify-client-cert require --mode server"); - } if (options->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME) { msg(M_USAGE, "--username-as-common-name requires --mode server"); @@ -2453,14 +2440,6 @@ { msg(M_USAGE, "NCP cipher list contains unsupported ciphers."); } - if (options->ncp_enabled && !options->use_iv) - { - msg(M_USAGE, "--no-iv not allowed when NCP is enabled."); - } - if (!options->use_iv) - { - msg(M_WARN, "WARNING: --no-iv is deprecated and will be removed in 2.5"); - } if (options->keysize) { @@ -2491,13 +2470,6 @@ msg(M_USAGE, "specify only one of --tls-server, --tls-client, or --secret"); } - if (options->ssl_flags & (SSLF_CLIENT_CERT_NOT_REQUIRED|SSLF_CLIENT_CERT_OPTIONAL)) - { - msg(M_WARN, "WARNING: POTENTIALLY DANGEROUS OPTION " - "--verify-client-cert none|optional (or --client-cert-not-required) " - "may accept clients which do not present a certificate"); - } - if (options->key_method == 1) { msg(M_WARN, "WARNING: --key-method 1 is deprecated and will be removed " @@ -2723,7 +2695,6 @@ MUST_BE_UNDEF(pkcs12_file); #endif MUST_BE_UNDEF(cipher_list); - MUST_BE_UNDEF(cipher_list_tls13); MUST_BE_UNDEF(tls_cert_profile); MUST_BE_UNDEF(tls_verify); MUST_BE_UNDEF(tls_export_cert); @@ -3440,8 +3411,8 @@ init_key_type(&fake_kt, o->ciphername, o->authname, o->keysize, true, false); frame_remove_from_extra_frame(&fake_frame, crypto_max_overhead()); - crypto_adjust_frame_parameters(&fake_frame, &fake_kt, o->use_iv, - o->replay, cipher_kt_mode_ofb_cfb(fake_kt.cipher)); + crypto_adjust_frame_parameters(&fake_frame, &fake_kt, o->replay, + cipher_kt_mode_ofb_cfb(fake_kt.cipher)); frame_finalize(&fake_frame, o->ce.link_mtu_defined, o->ce.link_mtu, o->ce.tun_mtu_defined, o->ce.tun_mtu); msg(D_MTU_DEBUG, "%s: link-mtu %u -> %d", __func__, (unsigned int) link_mtu, @@ -3485,8 +3456,6 @@ * --auth * --keysize * --secret - * --no-replay - * --no-iv * * SSL Options: * @@ -3600,8 +3569,7 @@ { struct key_type kt; - ASSERT((o->shared_secret_file != NULL) - + (TLS_CLIENT == true) + ASSERT((TLS_CLIENT == true) + (TLS_SERVER == true) <= 1); @@ -3616,14 +3584,6 @@ { buf_printf(&out, ",secret"); } - if (!o->replay) - { - buf_printf(&out, ",no-replay"); - } - if (!o->use_iv) - { - buf_printf(&out, ",no-iv"); - } #ifdef ENABLE_PREDICTION_RESISTANCE if (o->use_prediction_resistance) @@ -5177,6 +5137,8 @@ else if (streq(p[1], "server")) { options->mode = MODE_SERVER; + /* Fox-IT hardening: disable NCP by default for servers */ + options->ncp_enabled = false; } #endif else @@ -6646,36 +6608,6 @@ VERIFY_PERMISSION(OPT_P_INHERIT); options->max_routes_per_client = max_int(atoi(p[1]), 1); } - else if (streq(p[0], "client-cert-not-required") && !p[1]) - { - VERIFY_PERMISSION(OPT_P_GENERAL); - options->ssl_flags |= SSLF_CLIENT_CERT_NOT_REQUIRED; - msg(M_WARN, "DEPRECATED OPTION: --client-cert-not-required, use --verify-client-cert instead"); - } - else if (streq(p[0], "verify-client-cert") && !p[2]) - { - VERIFY_PERMISSION(OPT_P_GENERAL); - - /* Reset any existing flags */ - options->ssl_flags &= ~SSLF_CLIENT_CERT_OPTIONAL; - options->ssl_flags &= ~SSLF_CLIENT_CERT_NOT_REQUIRED; - if (p[1]) - { - if (streq(p[1], "none")) - { - options->ssl_flags |= SSLF_CLIENT_CERT_NOT_REQUIRED; - } - else if (streq(p[1], "optional")) - { - options->ssl_flags |= SSLF_CLIENT_CERT_OPTIONAL; - } - else if (!streq(p[1], "require")) - { - msg(msglevel, "parameter to --verify-client-cert must be 'none', 'optional' or 'require'"); - goto err; - } - } - } else if (streq(p[0], "username-as-common-name") && !p[1]) { VERIFY_PERMISSION(OPT_P_GENERAL); @@ -6806,20 +6738,6 @@ options->port_share_port = p[2]; options->port_share_journal_dir = p[3]; } - else if (streq (p[0], "pkcs11-id-type") || - streq (p[0], "pkcs11-sign-mode") || - streq (p[0], "pkcs11-slot") || - streq (p[0], "pkcs11-slot-type") || - streq (p[0], "show-pkcs11-objects") || - streq (p[0], "show-pkcs11-slots")) - { - if (file) - msg (msglevel, "You are using an obsolete parameter in %s:%d: %s (%s).\nPlease see /usr/share/doc/openvpn/NEWS.Debian.gz for details.", - file, line, p[0], PACKAGE_VERSION); - else - msg (msglevel, "You are using an obsolete parameter: --%s (%s).\nPlease see /usr/share/doc/openvpn/NEWS.Debian.gz for details.", - p[0], PACKAGE_VERSION); - } #endif else if (streq(p[0], "client-to-client") && !p[1]) { @@ -7463,25 +7381,12 @@ else if (streq(p[0], "secret") && p[1] && !p[3]) { VERIFY_PERMISSION(OPT_P_GENERAL); - if (streq(p[1], INLINE_FILE_TAG) && p[2]) - { - options->shared_secret_file_inline = p[2]; - } - else if (p[2]) - { - int key_direction; - - key_direction = ascii2keydirection(msglevel, p[2]); - if (key_direction >= 0) - { - options->key_direction = key_direction; - } - else + if ((streq(p[1], INLINE_FILE_TAG) && p[2]) || (p[2])) { + msg (msglevel, "ERROR: static key mode (--secret) not supported."); goto err; } - } - options->shared_secret_file = p[1]; + options->shared_secret_file = p[1]; /* Needed for --test-crypto */ } else if (streq(p[0], "genkey") && !p[1]) { @@ -7508,6 +7413,11 @@ VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_INSTANCE); options->ncp_enabled = false; } + else if (streq(p[0], "ncp-enable") && !p[1]) + { + VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_INSTANCE); + options->ncp_enabled = true; + } else if (streq(p[0], "prng") && p[1] && !p[3]) { VERIFY_PERMISSION(OPT_P_GENERAL); @@ -7534,11 +7444,6 @@ } } } - else if (streq(p[0], "no-replay") && !p[1]) - { - VERIFY_PERMISSION(OPT_P_GENERAL); - options->replay = false; - } else if (streq(p[0], "replay-window") && !p[3]) { VERIFY_PERMISSION(OPT_P_GENERAL); @@ -7586,8 +7491,8 @@ } else if (streq(p[0], "no-iv") && !p[1]) { - VERIFY_PERMISSION(OPT_P_GENERAL); - options->use_iv = false; + msg(msglevel, + "--no-iv is no longer supported. Remove it from client and server configs."); } else if (streq(p[0], "replay-persist") && p[1] && !p[2]) { @@ -7635,6 +7540,41 @@ options->use_prediction_resistance = true; } #endif + else if (streq (p[0], "min-platform-entropy")) + { + VERIFY_PERMISSION (OPT_P_GENERAL); + int min_platform_entropy = strtol(p[1], NULL, 10); + + if (min_platform_entropy < 0) + { + msg (msglevel, "min-platform-entropy must be positive: %s", p[1]); + goto err; + } + if (min_platform_entropy > FOX_MIN_PLATFORM_ENTROPY_MAX) + { + msg (M_WARN, + "Warning: min-platform-entropy too high, capping to %u", + FOX_MIN_PLATFORM_ENTROPY_MAX); + min_platform_entropy = FOX_MIN_PLATFORM_ENTROPY_MAX; + } + options->min_platform_entropy = min_platform_entropy; + } +#ifndef WIN32 + else if (streq (p[0], "use-urandom")) + { + VERIFY_PERMISSION (OPT_P_GENERAL); + msg (M_WARN, + "Warning: --use-urandom is deprecated, remove from your config."); + } +#endif +#ifndef WIN32 + else if (streq (p[0], "use-urandom")) + { + VERIFY_PERMISSION (OPT_P_GENERAL); + msg (M_WARN, + "Warning: --use-urandom is deprecated, remove from your config."); + } +#endif else if (streq(p[0], "show-tls") && !p[1]) { VERIFY_PERMISSION(OPT_P_GENERAL); --- openvpn-2.4.7/src/openvpn/options.h 2019-02-20 13:28:23.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/options.h 2019-08-29 12:56:28.000000000 +0200 @@ -29,6 +29,11 @@ #ifndef OPTIONS_H #define OPTIONS_H +/* Fox-IT hardening: must compile with crypto and ssl defined. */ +#ifndef ENABLE_CRYPTO +# error "Compiling without ENABLE_CRYPTO is not supported." +#endif + #include "basic.h" #include "common.h" #include "mtu.h" @@ -486,11 +491,11 @@ int replay_window; int replay_time; const char *packet_id_file; - bool use_iv; bool test_crypto; #ifdef ENABLE_PREDICTION_RESISTANCE bool use_prediction_resistance; #endif + int min_platform_entropy; /* TLS (control channel) parms */ bool tls_server; --- openvpn-2.4.7/src/openvpn/reliable.c 2019-02-20 13:28:23.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/reliable.c 2019-08-29 12:56:28.000000000 +0200 @@ -43,6 +43,8 @@ #include "memdbg.h" +#define N_ACK_RETRANSMIT 3 + /* * verify that test - base < extent while allowing for base or test wraparound */ @@ -379,7 +381,10 @@ } #endif e->active = false; - break; + } + else if (e->active && e->packet_id < pid) + { + e->n_acks++; } } } @@ -552,7 +557,7 @@ if (e->active) { ++n_active; - if (now >= e->next_try) + if (now >= e->next_try || e->n_acks >= N_ACK_RETRANSMIT) { ++n_current; } @@ -567,30 +572,6 @@ return n_current > 0 && !rel->hold; } -#ifdef EXPONENTIAL_BACKOFF -/* return a unique point-in-time to trigger retry */ -static time_t -reliable_unique_retry(struct reliable *rel, time_t retry) -{ - int i; - while (true) - { - for (i = 0; i < rel->size; ++i) - { - struct reliable_entry *e = &rel->array[i]; - if (e->active && e->next_try == retry) - { - goto again; - } - } - break; -again: - ++retry; - } - return retry; -} -#endif /* ifdef EXPONENTIAL_BACKOFF */ - /* return next buffer to send to remote */ struct buffer * reliable_send(struct reliable *rel, int *opcode) @@ -602,7 +583,8 @@ for (i = 0; i < rel->size; ++i) { struct reliable_entry *e = &rel->array[i]; - if (e->active && local_now >= e->next_try) + if (e->active + && (e->n_acks >= N_ACK_RETRANSMIT || local_now >= e->next_try)) { if (!best || reliable_pid_min(e->packet_id, best->packet_id)) { @@ -614,12 +596,13 @@ { #ifdef EXPONENTIAL_BACKOFF /* exponential backoff */ - best->next_try = reliable_unique_retry(rel, local_now + best->timeout); + best->next_try = local_now + best->timeout; best->timeout *= 2; #else /* constant timeout, no backoff */ best->next_try = local_now + best->timeout; #endif + best->n_acks = 0; *opcode = best->opcode; dmsg(D_REL_DEBUG, "ACK reliable_send ID " packet_id_format " (size=%d to=%d)", (packet_id_print_type)best->packet_id, best->buf.len, @@ -707,6 +690,7 @@ e->opcode = opcode; e->next_try = 0; e->timeout = 0; + e->n_acks = 0; dmsg(D_REL_DEBUG, "ACK mark active incoming ID " packet_id_format, (packet_id_print_type)e->packet_id); return; } --- openvpn-2.4.7/src/openvpn/reliable.h 2019-02-20 13:28:23.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/reliable.h 2019-08-29 12:56:28.000000000 +0200 @@ -74,6 +74,7 @@ interval_t timeout; time_t next_try; packet_id_type packet_id; + size_t n_acks; int opcode; struct buffer buf; }; --- openvpn-2.4.7/src/openvpn/route.c 2021-01-20 10:34:04.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/route.c 2019-08-29 12:56:28.000000000 +0200 @@ -49,6 +49,7 @@ #endif #ifdef _WIN32 +#include #include "openvpn-msg.h" #define METRIC_NOT_USED ((DWORD)-1) @@ -1693,7 +1694,7 @@ argv_msg(D_ROUTE, &argv); status = openvpn_execve_check(&argv, es, 0, "ERROR: Solaris route add command failed"); -#elif defined(TARGET_FREEBSD) || defined(__FreeBSD_kernel__) +#elif defined(TARGET_FREEBSD) argv_printf(&argv, "%s add", ROUTE_PATH); @@ -1879,7 +1880,7 @@ network = print_in6_addr( r6->network, 0, &gc); gateway = print_in6_addr( r6->gateway, 0, &gc); -#if defined(TARGET_DARWIN) || defined(__FreeBSD_kernel__) \ +#if defined(TARGET_DARWIN) \ || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \ || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) @@ -2047,7 +2048,7 @@ argv_msg(D_ROUTE, &argv); status = openvpn_execve_check(&argv, es, 0, "ERROR: Solaris route add -inet6 command failed"); -#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) || defined(__FreeBSD_kernel__) +#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) argv_printf(&argv, "%s add -inet6 %s/%d", ROUTE_PATH, @@ -2239,7 +2240,7 @@ argv_msg(D_ROUTE, &argv); openvpn_execve_check(&argv, es, 0, "ERROR: Solaris route delete command failed"); -#elif defined(TARGET_FREEBSD) || defined(__FreeBSD_kernel__) +#elif defined(TARGET_FREEBSD) argv_printf(&argv, "%s delete -net %s %s %s", ROUTE_PATH, @@ -2346,7 +2347,7 @@ network = print_in6_addr( r6->network, 0, &gc); gateway = print_in6_addr( r6->gateway, 0, &gc); -#if defined(TARGET_DARWIN) || defined(__FreeBSD_kernel__) \ +#if defined(TARGET_DARWIN) \ || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \ || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) @@ -2481,7 +2482,7 @@ argv_msg(D_ROUTE, &argv); openvpn_execve_check(&argv, es, 0, "ERROR: Solaris route delete -inet6 command failed"); -#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) || defined(__FreeBSD_kernel__) +#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) argv_printf(&argv, "%s delete -inet6 %s/%d", ROUTE_PATH, @@ -3532,8 +3533,7 @@ #elif defined(TARGET_DARWIN) || defined(TARGET_SOLARIS) \ || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \ - || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) \ - || defined(__FreeBSD_kernel__) + || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) #include #include --- openvpn-2.4.7/src/openvpn/socks.c 2019-02-20 13:28:20.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/socks.c 2019-08-29 12:56:28.000000000 +0200 @@ -104,12 +104,13 @@ const int timeout_sec = 5; struct user_pass creds; ssize_t size; + bool ret = false; creds.defined = 0; if (!get_user_pass(&creds, p->authfile, UP_TYPE_SOCKS, GET_USER_PASS_MANAGEMENT)) { msg(M_NONFATAL, "SOCKS failed to get username/password."); - return false; + goto cleanup; } if ( (strlen(creds.username) > 255) || (strlen(creds.password) > 255) ) @@ -117,7 +118,7 @@ msg(M_NONFATAL, "SOCKS username and/or password exceeds 255 characters. " "Authentication not possible."); - return false; + goto cleanup; } openvpn_snprintf(to_send, sizeof(to_send), "\x01%c%s%c%s", (int) strlen(creds.username), creds.username, (int) strlen(creds.password), creds.password); @@ -126,7 +127,7 @@ if (size != strlen(to_send)) { msg(D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port write failed on send()"); - return false; + goto cleanup; } while (len < 2) @@ -147,21 +148,21 @@ get_signal(signal_received); if (*signal_received) { - return false; + goto cleanup; } /* timeout? */ if (status == 0) { msg(D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port read timeout expired"); - return false; + goto cleanup; } /* error */ if (status < 0) { msg(D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port read failed on select()"); - return false; + goto cleanup; } /* read single char */ @@ -171,7 +172,7 @@ if (size != 1) { msg(D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port read failed on recv()"); - return false; + goto cleanup; } /* store char in buffer */ @@ -182,10 +183,13 @@ if (buf[0] != 5 && buf[1] != 0) { msg(D_LINK_ERRORS, "socks_username_password_auth: server refused the authentication"); - return false; + goto cleanup; } - return true; + ret = true; +cleanup: + secure_memzero(&creds, sizeof(creds)); + return ret; } static bool --- openvpn-2.4.7/src/openvpn/ssl.c 2021-01-20 10:34:04.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/ssl.c 2019-08-29 12:56:28.000000000 +0200 @@ -1652,8 +1652,8 @@ chunk = md_kt_size(md_kt); A1_len = md_kt_size(md_kt); - hmac_ctx_init(ctx, sec, sec_len, md_kt, 1); - hmac_ctx_init(ctx_tmp, sec, sec_len, md_kt, 1); + hmac_ctx_init(ctx, sec, sec_len, md_kt); + hmac_ctx_init(ctx_tmp, sec, sec_len, md_kt); hmac_ctx_update(ctx,seed,seed_len); hmac_ctx_final(ctx, A1); @@ -2000,7 +2000,7 @@ /* Update frame parameters: undo worst-case overhead, add actual overhead */ frame_remove_from_extra_frame(frame, crypto_max_overhead()); crypto_adjust_frame_parameters(frame, &session->opt->key_type, - options->use_iv, options->replay, packet_id_long_form); + options->replay, packet_id_long_form); 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); @@ -2270,7 +2270,7 @@ buf_printf(&out, "IV_PLAT=mac\n"); #elif defined(TARGET_NETBSD) buf_printf(&out, "IV_PLAT=netbsd\n"); -#elif defined(TARGET_FREEBSD) || defined(__FreeBSD_kernel__) +#elif defined(TARGET_FREEBSD) buf_printf(&out, "IV_PLAT=freebsd\n"); #elif defined(TARGET_ANDROID) buf_printf(&out, "IV_PLAT=android\n"); @@ -2563,6 +2563,14 @@ goto error; } + const struct key_source *peer_key_source = session->opt->server ? + &ks->key_src->client : &ks->key_src->server; + if (!rand_update_manual(peer_key_source, sizeof(*peer_key_source))) + { + msg (D_TLS_ERRORS, "TLS ERROR: unable to update entropy"); + goto error; + } + /* get options */ if (!read_string(buf, options, TLS_OPTIONS_LEN)) { --- openvpn-2.4.7/src/openvpn/ssl.h 2019-02-20 13:28:23.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/ssl.h 2019-08-29 12:56:28.000000000 +0200 @@ -111,7 +111,7 @@ /* * Range of key exchange methods */ -#define KEY_METHOD_MIN 1 +#define KEY_METHOD_MIN 2 /* Fox-IT hardening: require key-method 2 */ #define KEY_METHOD_MAX 2 /* key method taken from lower 4 bits */ --- openvpn-2.4.7/src/openvpn/ssl_common.h 2019-02-20 13:28:23.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/ssl_common.h 2019-08-29 12:56:28.000000000 +0200 @@ -316,8 +316,8 @@ #endif /* configuration file SSL-related boolean and low-permutation options */ -#define SSLF_CLIENT_CERT_NOT_REQUIRED (1<<0) -#define SSLF_CLIENT_CERT_OPTIONAL (1<<1) +//#define SSLF_CLIENT_CERT_NOT_REQUIRED (1<<0) +//#define SSLF_CLIENT_CERT_OPTIONAL (1<<1) #define SSLF_USERNAME_AS_COMMON_NAME (1<<2) #define SSLF_AUTH_USER_PASS_OPTIONAL (1<<3) #define SSLF_OPT_VERIFY (1<<4) --- openvpn-2.4.7/src/openvpn/ssl_mbedtls.c 2019-02-20 13:28:23.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/ssl_mbedtls.c 2019-08-29 12:56:28.000000000 +0200 @@ -37,6 +37,7 @@ #if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_MBEDTLS) +#include "allowed_crypto.h" #include "errlevel.h" #include "ssl_backend.h" #include "base64.h" @@ -65,13 +66,16 @@ { /* Hashes from SHA-1 and above */ MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_RIPEMD160 ) | MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) | MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) | MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ), - 0xFFFFFFF, /* Any PK alg */ - 0xFFFFFFF, /* Any curve */ + /* Fox-IT hardening: Only RSA */ + MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_RSA) + | MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_RSA_ALT) + | MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_RSASSA_PSS), + /* Fox-IT hardening: No ECDSA */ + 0, 1024, /* RSA-1024 and larger */ }; @@ -82,8 +86,12 @@ MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) | MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ), - 0xFFFFFFF, /* Any PK alg */ - 0xFFFFFFF, /* Any curve */ + /* Fox-IT hardening: Only RSA */ + MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_RSA) + | MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_RSA_ALT) + | MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_RSASSA_PSS), + /* Fox-IT hardening: No ECDSA */ + 0, 2048, /* RSA-2048 and larger */ }; @@ -253,8 +261,12 @@ if (NULL == ciphers) { - return; /* Nothing to do */ - + /* Fox-IT hardening: use default restricted cipher suite list */ + ctx->allowed_ciphers = malloc(sizeof(allowed_tls_cipher_suites)); + check_malloc_return(ctx->allowed_ciphers); + memcpy (ctx->allowed_ciphers, allowed_tls_cipher_suites, + sizeof(allowed_tls_cipher_suites)); + return; } ciphers_len = strlen(ciphers); @@ -280,8 +292,16 @@ token = strtok(tmp_ciphers, ":"); while (token) { + if (is_allowed_tls_cipher(token)) + { ctx->allowed_ciphers[i] = mbedtls_ssl_get_ciphersuite_id( tls_translate_cipher_name(token)); + } + else + { + msg (M_WARN, "WARNING: cipher suite '%s' not allowed, ignoring.", token); + } + if (0 != ctx->allowed_ciphers[i]) { i++; @@ -294,17 +314,18 @@ void tls_ctx_set_cert_profile(struct tls_root_ctx *ctx, const char *profile) { - if (!profile || 0 == strcmp(profile, "legacy")) + if (!profile || 0 == strcmp(profile, "preferred")) { - ctx->cert_profile = openvpn_x509_crt_profile_legacy; + ctx->cert_profile = openvpn_x509_crt_profile_preferred; } - else if (0 == strcmp(profile, "preferred")) + else if (0 == strcmp(profile, "legacy")) { - ctx->cert_profile = openvpn_x509_crt_profile_preferred; + ctx->cert_profile = openvpn_x509_crt_profile_legacy; } else if (0 == strcmp(profile, "suiteb")) { - ctx->cert_profile = openvpn_x509_crt_profile_suiteb; + msg (M_FATAL, "ERROR: cert profile '%s' not support by OpenVPN-NL", + profile); } else { @@ -873,7 +894,10 @@ if (0 != memcmp(old_sha256_hash, sha256_hash, sizeof(sha256_hash))) { - mbedtls_ctr_drbg_update(cd_ctx, sha256_hash, 32); + if (!mbed_ok(mbedtls_ctr_drbg_update_ret(cd_ctx, sha256_hash, 32))) + { + msg(M_WARN, "WARNING: failed to personalise random, could not update CTR_DRBG"); + } memcpy(old_sha256_hash, sha256_hash, sizeof(old_sha256_hash)); } } @@ -1011,14 +1035,8 @@ ssl_ctx->priv_key)); /* Initialise SSL verification */ -#if P2MP_SERVER - if (session->opt->ssl_flags & SSLF_CLIENT_CERT_OPTIONAL) - { - mbedtls_ssl_conf_authmode(&ks_ssl->ssl_config, MBEDTLS_SSL_VERIFY_OPTIONAL); - } - else if (!(session->opt->ssl_flags & SSLF_CLIENT_CERT_NOT_REQUIRED)) -#endif { + /* Fox-IT hardening: client must present certificate. */ mbedtls_ssl_conf_authmode(&ks_ssl->ssl_config, MBEDTLS_SSL_VERIFY_REQUIRED); } mbedtls_ssl_conf_verify(&ks_ssl->ssl_config, verify_callback, session); @@ -1350,7 +1368,7 @@ return; } struct tls_root_ctx tls_ctx; - const int *ciphers = mbedtls_ssl_list_ciphersuites(); + const int *ciphers = allowed_tls_cipher_suites; tls_ctx_server_new(&tls_ctx); tls_ctx_set_cert_profile(&tls_ctx, tls_cert_profile); @@ -1361,11 +1379,17 @@ ciphers = tls_ctx.allowed_ciphers; } +#ifndef ENABLE_SMALL + printf("Available TLS Ciphers,\n"); + printf("listed in order of preference:\n\n"); +#endif + while (*ciphers != 0) { printf("%s\n", mbedtls_ssl_get_ciphersuite_name(*ciphers)); ciphers++; } + tls_ctx_free(&tls_ctx); } --- openvpn-2.4.7/src/openvpn/ssl_openssl.c 2019-02-20 13:28:23.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/ssl_openssl.c 2019-08-29 12:56:28.000000000 +0200 @@ -303,19 +303,9 @@ SSL_CTX_set_session_cache_mode(ctx->ctx, SSL_SESS_CACHE_OFF); SSL_CTX_set_default_passwd_cb(ctx->ctx, pem_password_callback); - /* Require peer certificate verification */ -#if P2MP_SERVER - if (ssl_flags & SSLF_CLIENT_CERT_NOT_REQUIRED) - { - flags = 0; - } - else if (ssl_flags & SSLF_CLIENT_CERT_OPTIONAL) - { - flags = SSL_VERIFY_PEER; - } -#endif - SSL_CTX_set_verify(ctx->ctx, flags, verify_callback); - + /* Fox-IT hardening: client must present certificate. */ + SSL_CTX_set_verify (ctx->ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + verify_callback); SSL_CTX_set_info_callback(ctx->ctx, info_callback); return true; --- openvpn-2.4.7/src/openvpn/ssl_verify.c 2019-02-20 13:28:23.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/ssl_verify.c 2019-08-29 12:56:28.000000000 +0200 @@ -56,18 +56,40 @@ /** Legal characters in a common name with --compat-names */ #define COMMON_NAME_CHAR_CLASS (CC_ALNUM|CC_UNDERBAR|CC_DASH|CC_DOT|CC_AT|CC_SLASH) -static void +static bool string_mod_remap_name(char *str, const unsigned int restrictive_flags) { if (compat_flag(COMPAT_FLAG_QUERY | COMPAT_NAMES) && !compat_flag(COMPAT_FLAG_QUERY | COMPAT_NO_NAME_REMAPPING)) { - string_mod(str, restrictive_flags, 0, '_'); + return string_mod(str, restrictive_flags, 0, '_'); } else { - string_mod(str, CC_PRINT, CC_CRLF, '_'); + return string_mod(str, CC_PRINT, CC_CRLF, '_'); + } } + +static char * +x509_get_issuer(openvpn_x509_cert_t *cert, int cert_depth, struct gc_arena *gc) +{ + char *issuer = backend_x509_get_issuer(cert, gc); + if (!issuer) + { + msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, " + "could not extract X509 issuer string from certificate", + cert_depth); + return NULL; + } + + /* enforce character class restrictions in X509 issuer */ + if (!string_mod_remap_name (issuer, X509_NAME_CHAR_CLASS)) + { + msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, illegal characters in " + "issuer string from certificate", cert_depth); + } + + return issuer; } /* @@ -495,6 +517,11 @@ format_hex_ex(BPTR(&sha256), BLEN(&sha256), 0, 1, ":", &gc)); } + /* export issuer as environmental variable */ + const char *issuer = x509_get_issuer(peer_cert, cert_depth, &gc); + openvpn_snprintf(envname, sizeof(envname), "tls_issuer_%d", cert_depth); + setenv_str(es, envname, issuer); + /* export serial number as environmental variable */ serial = backend_x509_get_serial(peer_cert, &gc); openvpn_snprintf(envname, sizeof(envname), "tls_serial_%d", cert_depth); @@ -689,8 +716,11 @@ } /* enforce character class restrictions in X509 name */ - string_mod_remap_name(subject, X509_NAME_CHAR_CLASS); - string_replace_leading(subject, '-', '_'); + if (!string_mod_remap_name (subject, X509_NAME_CHAR_CLASS)) + { + msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, illegal characters in " + "subject string from certificate", cert_depth); + } /* extract the username (default is CN) */ if (SUCCESS != backend_x509_get_username(common_name, sizeof(common_name), @@ -709,7 +739,11 @@ } /* enforce character class restrictions in common name */ - string_mod_remap_name(common_name, COMMON_NAME_CHAR_CLASS); + if (!string_mod_remap_name (common_name, COMMON_NAME_CHAR_CLASS)) + { + msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, illegal characters in " + "common name from certificate", cert_depth); + } /* warn if cert chain is too deep */ if (cert_depth >= MAX_CERT_DEPTH) --- openvpn-2.4.7/src/openvpn/ssl_verify_backend.h 2019-02-20 13:28:23.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/ssl_verify_backend.h 2019-08-29 12:56:28.000000000 +0200 @@ -132,6 +132,16 @@ bool x509_username_field_ext_supported(const char *extname); #endif +/** + * Return the certificate's issuer name. + * + * @param cert Certificate to retrieve the issuer from. + * @param gc Garbage collection arena to use when allocating string. + * + * @return Issuer name, or NULL on error. + */ +char *backend_x509_get_issuer(openvpn_x509_cert_t *cert, struct gc_arena *gc); + /* * Return the certificate's serial number in decimal string representation. * --- openvpn-2.4.7/src/openvpn/ssl_verify_mbedtls.c 2019-02-20 13:28:23.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/ssl_verify_mbedtls.c 2019-08-29 12:56:28.000000000 +0200 @@ -154,6 +154,24 @@ } char * +backend_x509_get_issuer(mbedtls_x509_crt *cert, struct gc_arena *gc) +{ + char tmp_issuer[MAX_SUBJECT_LENGTH] = {0}; + char *issuer = NULL; + + int ret = 0; + + ret = mbedtls_x509_dn_gets(tmp_issuer, MAX_SUBJECT_LENGTH-1, &cert->issuer); + if (ret > 0) + { + /* Allocate the required space for the issuer */ + issuer = string_alloc(tmp_issuer, gc); + } + + return issuer; +} + +char * backend_x509_get_serial(mbedtls_x509_crt *cert, struct gc_arena *gc) { char *buf = NULL; @@ -236,7 +254,8 @@ int ret = 0; ret = mbedtls_x509_dn_gets( tmp_subject, MAX_SUBJECT_LENGTH-1, &cert->subject ); - if (ret > 0) + /* Reject subjects with null characters, should be C string compatible */ + if (ret > 0 && ret == strlen(tmp_subject)) { /* Allocate the required space for the subject */ subject = string_alloc(tmp_subject, gc); --- openvpn-2.4.7/src/openvpn/ssl_verify_openssl.c 2019-02-20 13:28:23.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/ssl_verify_openssl.c 2019-08-29 12:56:28.000000000 +0200 @@ -278,6 +278,58 @@ } char * +backend_x509_get_issuer (X509 *cert, struct gc_arena *gc) +{ + BIO *issuer_bio = NULL; + BUF_MEM *issuer_mem; + char *issuer = NULL; + int maxlen = 0; + + /* + * Generate the issuer string in OpenSSL proprietary format, + * when in --compat-names mode + */ + if (compat_flag (COMPAT_FLAG_QUERY | COMPAT_NAMES)) + { + issuer = gc_malloc (256, false, gc); + X509_NAME_oneline (X509_get_issuer_name (cert), issuer, 256); + issuer[255] = '\0'; + return issuer; + } + + issuer_bio = BIO_new (BIO_s_mem ()); + if (issuer_bio == NULL) + { + goto err; + } + + X509_NAME_print_ex (issuer_bio, X509_get_issuer_name (cert), + 0, XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_FN_SN | + ASN1_STRFLGS_UTF8_CONVERT | ASN1_STRFLGS_ESC_CTRL); + + if (BIO_eof (issuer_bio)) + { + goto err; + } + + BIO_get_mem_ptr (issuer_bio, &issuer_mem); + + maxlen = issuer_mem->length + 1; + issuer = gc_malloc (maxlen, false, gc); + + memcpy (issuer, issuer_mem->data, maxlen); + issuer[maxlen - 1] = '\0'; + + err: + if (issuer_bio) + { + BIO_free (issuer_bio); + } + + return issuer; +} + +char * backend_x509_get_serial(openvpn_x509_cert_t *cert, struct gc_arena *gc) { ASN1_INTEGER *asn1_i; @@ -365,6 +417,12 @@ memcpy(subject, subject_mem->data, subject_mem->length); subject[subject_mem->length] = '\0'; + /* Reject subjects with null characters, should be C string compatible */ + if (strlen(subject) != subject_mem->length) + { + subject = NULL; + } + err: if (subject_bio) { --- openvpn-2.4.7/src/openvpn/syshead.h 2021-01-20 10:34:04.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/syshead.h 2019-08-29 12:56:28.000000000 +0200 @@ -297,7 +297,7 @@ #endif /* TARGET_OPENBSD */ -#if defined(TARGET_FREEBSD) || defined(__FreeBSD_kernel__) +#ifdef TARGET_FREEBSD #ifdef HAVE_SYS_UIO_H #include --- openvpn-2.4.7/src/openvpn/tun.c 2021-01-20 10:34:04.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/openvpn/tun.c 2019-08-29 12:56:28.000000000 +0200 @@ -845,7 +845,7 @@ #endif /* if defined(_WIN32) || defined(TARGET_DARWIN) || defined(TARGET_NETBSD) || defined(TARGET_OPENBSD) */ #if defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \ - || defined(TARGET_NETBSD) || defined(TARGET_OPENBSD) || defined(__FreeBSD_kernel__) + || defined(TARGET_NETBSD) || defined(TARGET_OPENBSD) /* we can't use true subnet mode on tun on all platforms, as that * conflicts with IPv6 (wants to use ND then, which we don't do), * but the OSes want "a remote address that is different from ours" @@ -1429,7 +1429,7 @@ add_route_connected_v6_net(tt, es); } -#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) || defined(__FreeBSD_kernel__) +#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) in_addr_t remote_end; /* for "virtual" subnet topology */ @@ -2785,7 +2785,7 @@ } } -#elif defined(TARGET_FREEBSD)||defined(__FreeBSD_kernel__) +#elif defined(TARGET_FREEBSD) static inline int freebsd_modify_read_write_return(int len) --- openvpn-2.4.7/src/plugins/auth-pam/auth-pam.c 2021-01-20 10:34:04.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/src/plugins/auth-pam/auth-pam.c 2019-08-29 12:56:28.000000000 +0200 @@ -716,7 +716,7 @@ struct user_pass up; int command; #ifdef USE_PAM_DLOPEN - static const char pam_so[] = "libpam.so.0"; + static const char pam_so[] = "libpam.so"; #endif /* --- openvpn-2.4.7/tests/t_lpback.sh 2019-02-20 13:28:23.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/tests/t_lpback.sh 2019-08-29 12:56:28.000000000 +0200 @@ -35,8 +35,9 @@ # GD, 2014-07-06 do not test RC5-* either (fails on NetBSD w/o libcrypto_rc5) CIPHERS=$(echo "$CIPHERS" | egrep -v '^(DES-EDE3-CFB1|DES-CFB1|RC5-)' ) -# Also test cipher 'none' -CIPHERS=${CIPHERS}$(printf "\nnone") +# Fox-IT hardening; test for cipher 'none' should fail, do not test here. +# See below for negative test +#CIPHERS=${CIPHERS}$(printf "\nnone") "${top_builddir}/src/openvpn/openvpn" --genkey --secret key.$$ set +e @@ -55,6 +56,50 @@ fi done +# Fox-IT hardening; verify that unsupported ciphers are indeed _not_ accepted, +# including 'none'. +CIPHERS='BF-CBC AES-128-CBC none' +for cipher in ${CIPHERS} +do + echo -n "Testing cipher ${cipher}... " + ( "${top_builddir}/src/openvpn/openvpn" --test-crypto --secret key.$$ --cipher ${cipher} ) >log.$$ 2>&1 + if [ $? = 0 ] ; then + echo "FAILED: ${cipher} should not be an accepted cipher" + cat log.$$ + e=1 + else + echo "OK: ${cipher} is not an accepted cipher (failure expected)" + fi +done + +# Fox-IT hardening; verify that SHA256 is a supported digest algorithm. +auth='SHA256' +echo -n "Testing digest algorithm ${auth}... " +( "${top_builddir}/src/openvpn/openvpn" --test-crypto --secret key.$$ --cipher AES-256-CBC --auth ${auth} ) >log.$$ 2>&1 +if [ $? != 0 ] ; then + echo "FAILED" + cat log.$$ + e=1 +else + echo "OK" +fi + +# Fox-IT hardening; verify that unsupported digests are indeed _not_ accepted, +# including 'none'. +DIGESTS='MD5 SHA1 none' +for auth in ${DIGESTS} +do + echo -n "Testing digest algorithm ${auth}... " + ( "${top_builddir}/src/openvpn/openvpn" --test-crypto --secret key.$$ --cipher AES-256-CBC --auth ${auth} ) >log.$$ 2>&1 + if [ $? = 0 ] ; then + echo "FAILED: ${auth} should not be an accepted digest algorithm" + cat log.$$ + e=1 + else + echo "OK: ${auth} is not an accepted digest algorithm (failure expected)" + fi +done + rm key.$$ log.$$ trap 0 exit $e --- openvpn-2.4.7/tests/unit_tests/README.md 1970-01-01 01:00:00.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/tests/unit_tests/README.md 2019-08-29 12:56:28.000000000 +0200 @@ -0,0 +1,40 @@ +Unit Tests +=========== + +This directory contains unit tests for openvpn. New features/bugfixes should be written in a test friendly way and come with corresponding tests. + +Run tests +---------- + +Tests are run by `make check`. A failed tests stops test execution. To run all +tests regardless of errors call `make -k check`. + +Add new tests to existing test suite +------------------------------------- + +Test suites are organized in directories. [example_test/](example_test/) is an example +for a test suite with two test executables. Feel free to use it as a template for new tests. + +Test suites +-------------------- + +Test suites live inside a subdirectory of `$ROOT/tests/unit_tests`, e.g. `$ROOT/tests/unit_tests/my_feature`. + +Test suites are configured by a `Makefile.am`. Tests are executed by testdrivers. One testsuite can contain more than one testdriver. + +### Hints +* Name suites & testdrivers in a way that the name of the driver says something about which component/feature is tested +* Name the testdriver executable `*_testdriver`. This way it gets picked up by the default `.gitignore` + * If this is not feasible: Add all output to a `.gitignore`* Use descriptive test names: `coffee_brewing__with_no_beans__fails` vs. `test34` +* Testing a configurable feature? Wrap test execution with a conditional (see [auth_pam](plugins/auth-pam/Makefile.am) for an example) +* Add multiple test-drivers when one testdriver looks crowded with tests + +### New Test Suites +1. Organize tests in folders for features. +2. Add the new test directory to `SUBDIRS` in `Makefile.am` +3. Edit `configure.ac` and add the new `Makefile` to `AC_CONFIG_FILES` +4. Run `./configure`, and *enable* the feature you'd like to test +5. Make sure that `make check` runs your tests +6. Check: Would a stranger be able to easily find your tests by you looking at the test output? +7. Run `./configure`, and *disable* the feature you'd like to test +8. Make sure that `make check` does *not run* your tests --- openvpn-2.4.7/tests/unit_tests/example_test/README.md 1970-01-01 01:00:00.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/tests/unit_tests/example_test/README.md 2019-08-29 12:56:28.000000000 +0200 @@ -0,0 +1,3 @@ +This test only checks that test compilation works. This example contains two test executables. + +These tests can be used as template for 'real' tests. --- openvpn-2.4.7/tests/unit_tests/openvpn/Makefile.am 2019-02-20 13:28:23.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/tests/unit_tests/openvpn/Makefile.am 2019-08-29 12:56:28.000000000 +0200 @@ -48,6 +48,7 @@ tls_crypt_testdriver_LDFLAGS = @TEST_LDFLAGS@ \ $(OPTIONAL_CRYPTO_LIBS) tls_crypt_testdriver_SOURCES = test_tls_crypt.c mock_msg.c \ + $(openvpn_srcdir)/allowed_crypto.c \ $(openvpn_srcdir)/buffer.c \ $(openvpn_srcdir)/crypto.c \ $(openvpn_srcdir)/crypto_mbedtls.c \ --- openvpn-2.4.7/tests/unit_tests/openvpn/mock_msg.h 1970-01-01 01:00:00.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/tests/unit_tests/openvpn/mock_msg.h 2019-08-29 12:56:28.000000000 +0200 @@ -0,0 +1,34 @@ +/* + * OpenVPN -- An application to securely tunnel IP networks + * over a single UDP port, with support for SSL/TLS-based + * session authentication and key exchange, + * packet encryption, packet authentication, and + * packet compression. + * + * Copyright (C) 2016-2018 Fox Crypto B.V. + * + * 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. + * + * 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. + */ + +#ifndef MOCK_MSG_H +#define MOCK_MSG_H + +/** + * Mock debug level defaults to 0, which gives clean(-ish) test reports. Call + * this function from your test driver to increase debug output when you + * need debug output. + */ +void mock_set_debug_level(int level); + +#endif /* MOCK_MSG */ --- openvpn-2.4.7/vendor/README.md 1970-01-01 01:00:00.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/vendor/README.md 2019-08-29 12:56:28.000000000 +0200 @@ -0,0 +1,8 @@ +Vendor +======== + +Vendor source libraries are included in this directory. Libraries are included +when there is no good way to ensure that the package is available on all +systems. + +`Makefile.am` compiles these libraries and installs them into ./dist. --- openvpn-2.4.7/version.m4 2019-02-20 13:28:23.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/version.m4 2019-08-29 12:56:28.000000000 +0200 @@ -1,13 +1,14 @@ dnl define the OpenVPN version define([PRODUCT_NAME], [OpenVPN]) -define([PRODUCT_TARNAME], [openvpn]) +define([PRODUCT_TARNAME], [openvpn-nl]) define([PRODUCT_VERSION_MAJOR], [2]) define([PRODUCT_VERSION_MINOR], [4]) define([PRODUCT_VERSION_PATCH], [.7]) m4_append([PRODUCT_VERSION], [PRODUCT_VERSION_MAJOR]) m4_append([PRODUCT_VERSION], [PRODUCT_VERSION_MINOR], [[.]]) m4_append([PRODUCT_VERSION], [PRODUCT_VERSION_PATCH], [[]]) -define([PRODUCT_BUGREPORT], [openvpn-users@lists.sourceforge.net]) +define([PRODUCT_RELEASE], [nl1]) +define([PRODUCT_BUGREPORT], [openvpn@fox-it.com]) define([PRODUCT_VERSION_RESOURCE], [2,4,7,0]) dnl define the TAP version define([PRODUCT_TAP_WIN_COMPONENT_ID], [tap0901]) --- openvpn-2.4.7/version.sh.in 2019-02-20 13:28:20.000000000 +0100 +++ openvpn-2.4.7-inside-openvpn-nl/version.sh.in 2019-08-29 12:56:28.000000000 +0200 @@ -1,4 +1,5 @@ OPENVPN_PACKAGE_NAME="@PACKAGE_NAME@" OPENVPN_PACKAGE_TARNAME="@PACKAGE_TARNAME@" OPENVPN_PACKAGE_VERSION="@PACKAGE_VERSION@" +OPENVPN_RELEASE="@OPENVPN_RELEASE@" OPENVPN_PACKAGE_HOST="@host@"