OpenVPN 2.4 Evaluation Summary and Report

Posted on May 11, 2017 by Caleb Chen
openvpn audit report

Contents

1 Executive Summary
2 Introduction
2.1 Scope
2.2 Approach
2.3 Classification and Severity Rating
3 Findings
3.1 Summary of Findings
3.2 Static Analysis Results
3.3 Dynamic Analysis Results
3.4 Detailed Findings
3.4.1 OVPN-01: Sensitive authentication token not wiped on certain TLS
auth errors

3.4.2 OVPN-02: Potentially flawed TLS control channel encryption
3.4.3 OVPN-03: Insecure configuration options
3.4.4 OVPN-04: Possible NULL pointer dereferences
3.4.5 OVPN-05: Possible allocation of zero bytes with malloc
3.4.6 OVPN-06: Remove workaround to support obsolete versions of OpenSSL (v0.9.6b)
3.4.7 OVPN-07: Remove system() from sample authentication plugin
3.4.8 OVPN-08: OpenVPN configuration risks
4 Review Diffs
4.1 Overview
4.2 Summary of Diffs
4.2.1 OpenVPN v2.2 to v2.4 beta release
4.2.2 OpenVPN v2.4 beta to v2.4 official release
4.3 Analysis
5 Conclusions
6 Bibliography

Executive Summary

From December 2016 through February 2017, Cryptography Engineering performed an independent security review of the OpenVPN codebase looking to uncover various types of security weaknesses in core components. This review was funded by Private Internet Access(TM) (PIA), although PIA did not direct the review or modify the results.

The security review of OpenVPN involved both a manual and automated analysis of the codebase using different tools and techniques. We first manually analyzed the core code for several classes of C vulnerabilities which include stack/heap-based overflows, off-by-one errors, format string vulnerability, double free, use after free, possible null pointer dereferencing and other related errors. We also looked for cryptographic weaknesses such as insecure deletion of keys in memory as well as weaknesses in randomness generation for keys and encryption. Our overall approach was to manually analyze the encryption, authentication, and TLS modules (instantiated with either OpenSSL or mbed TLS) and find potential issues that could compromise the confidentiality and/or integrity of VPN connections.

During this process, we discovered several issues in the official 2.4 release that were simultaneously discovered and fixed by the OpenVPN developers in the main repository. We also identified a number of low and medium severity issues that we recommend should be addressed in the next official release of OpenVPN. Overall we are glad to report that no major vulnerabilities were found in the version of OpenVPN that was reviewed.

Introduction

OpenVPN is an open source, fully featured user-space SSL VPN solution for securely tunneling private network traffic (OSI layer 2 or 3) over a public insecure network (e.g., the Internet). OpenVPN uses SSL/TLS as its underlying cryptographic engine to secure point-to-point and site-to-site VPN connections. Each VPN connection consists of two channels: a control channel and a data channel. The control channel is protected using the TLS protocol while the data channel uses a custom encryption protocol. The OpenVPN solution uses the OpenSSL and the mbed TLS library to provide encryption, authentication, and integrity. In addition, OpenVPN is a portable and scalable solution that is widely deployed today.

2.1 Scope

We performed a security review of the OpenVPN codebase looking to uncover various types of security weaknesses in core components. OpenVPN is a large and complex piece of software with many configuration options and features. During this limited engagement, our code review included the following modules/components of OpenVPN:

– The TLS control module which provides a secure encapsulation of control channel messages exchanged between a client and a server. This also includes TLS hardening modules such as the control channel authentication (–tls-auth) and control channel encryption with authentication (–tls-crypt).

– The data channel module which provides the encryption for data channel packets going through the VPN tunnel (e.g., IP packets or ethernet frames) and the key generation components which controls how peers generate and exchange key material for data channel encryption.

– The control channel processor module which handles the negotiation of data channel security parameters and maintenance of the VPN tunnel (from setup to cleanup). In addition, this includes the control channel negotiation state machine and protocol.

– The source of randomness for initialization vectors (IV), key generation, session identifiers, packet identifiers, and the implementation of the hash-based DRBG construction (–prng).

– The network socket module and the management interface which allows administrative control of a running client or server via an external program using a TCP or unix domain socket.

– The OpenVPN plugin module (–plugin) for custom authentication functionality on the server-side via an external shell script, shared object (for *nix systems) or DLL (for Windows). This also includes plugins for PAM authentication, reducing the privilege of scripts before execution (or down-root), deferred authentication for servers while establishing a TLS session and packet filtering.

– The client authentication methods which include username/passwords, X.509 certificates, authentication tokens and smart cards (via PKCS11).We also reviewed the source code associated with several configurations/features of OpenVPN, which include the following:

– Client/Server modes: single client versus multi-client and server configurations.

– Key management: use of pre-shared static key mode versus TLS-negotiated key exchange mode.

– Certificate Verification: use of –tls-verify scripting mechanism to prevent possible man-in-the-middle attacks by checking the subject details of the server’s X.509 certificate. In addition, granular verification of certain fields via the –verify-x509-name and –x509-username-field options. The –verify-x509-name option will match a host’s X.509 name and –x509-username-field will match other fields such as the email address, subject alternative name and so on. Finally, use of –ns-cert-type to check that the peer’s certificate was signed with an explicit “client” or “server” designation to prevent impersonation attacks.

– User Verification: use of –auth-user-pass-verify to establish a client’s identity while the connection is still considered untrusted.

– Certificate Revocation Lists: use of –crl-verify to check that the peer’s certificate is not in a given certificate revocation list.

– Port Sharing: share the port with another application such as a web server (on say port 443). This features allows an OpenVPN server to proxy non-VPN connections to the web server when the protocol is in TCP mode.

– HTTP Proxy authentication: use of an HTTP proxy to connect to a remote server under the supported authentication methods (e.g., none, basic and NTLM).

– Cipher Negotiation: use of –ncp-ciphers to negotiate block ciphers to choose for the data channel encryption.

2.2 Approach

The security review of OpenVPN involved both a manual and automated analysis of the codebase using different tools and techniques. We first manually analyzed the core code for several classes of C vulnerabilities which include stack/heap-based overflows, off-by-one errors, format string vulnerability, double free, use after free, possible null pointer dereferencing and other related errors. We also looked for cryptographic weaknesses such as insecure deletion of keys in memory as well as weaknesses in randomness generation for keys and encryption. Our overall approach was to manually analyze the encryption, authentication, and TLS modules (instantiated with either OpenSSL or mbed TLS) and find potential issues that could compromise the confidentiality and/or integrity of VPN connections.

We then performed an automated memory analysis of the code base using both static analysis tools (e.g., clang static analyzer1) and dynamic analysis tools (e.g., AddressSanitizer2) to uncover any of the above classes of security vulnerabilities. Our goal was to run as many common and uncommon configurations of OpenVPN from the perspective of users. Historically, the tools we employ here have been effectively used to find critical vulnerabilities in many other open source projects. Thus, such tools are part of our overall strategy to quickly find or rule out classes of vulnerabilities in the OpenVPN core code.

2.3 Classification and Severity Rating

We classified the issues found during the security review of OpenVPN according to the Common Weakness Enumeration (CWE)3 list. In addition, we followed a simple severity rating system of low, medium or high based on best practices for securely coding in C, best practices for cryptographic implementations, and common use cases of OpenVPN and the potential security impact.

Low. A low severity rating indicates that the issue poses a relatively small or limited risk to users.
Medium. A medium severity rating indicates that the issue could potentially be exploited and an individual user could be compromised.
High. A high severity rating indicates that a large number of users are at significant risk of compromise and the issue should be addressed immediately.

[1] https://clang-analyzer.llvm.org/
[2] http://clang.llvm.org/docs/AddressSanitizer.html
[3] https://cwe.mitre.org

Findings

We began the review with with the OpenVPN 2.4 beta version released on December 2nd, 2016 (commit ref 1c587a11) and proceeded with a manual source code review in addition to an automated memory analysis. Following the official 2.4 release on December 27th, 2016, we manually reviewed the differences between the 2.4 beta version and the official release (commit ref 307abe7b) to verify that no new vulnerabilities were introduced. In addition, we reviewed the differences between the official 2.2 release from November 30, 2014 and the current 2.4 release.

3.1 Summary of Findings

During this process, we discovered several issues in the official 2.4 release that were simultaneously discovered and fixed by the OpenVPN developers in the main repository. We also identified a number of low and medium severity issues that we recommend should be addressed in the next official release of OpenVPN. We provide a high-level summary of the issues in Table 3.1 below and expand on these issues in Section 3.4. Overall we are glad to report that no major vulnerabilities were found in the version of OpenVPN that was reviewed.

We now provide some highlights of our review. From a software security perspective, the OpenVPN developers have followed best practices to prevent common vulnerabilities which lead to remote code exploitation. For instance, they provide their own buffer library API for safely manipulating blocks of dynamically allocated memory. In addition, they include wrappers such as strncpyt() and openvpn_snprintf() and provide a safe layer around unsafe C standard library versions. That is, the wrappers include appropriate buffer overflow checks and enforce NULL termination. Furthermore, sensitive data and keys are securely wiped from memory (e.g., using a volatile pointer and zeroing each byte in buffer) to prevent information leaks.

In terms of the cryptographic aspects of OpenVPN, we analyzed the code to determine all sources of random and pseudorandom numbers. We found three such sources in the code. The first source is defined in init_random_seed() using srand(gettimeofday()) and is considered a weak source of (pseudo)random numbers. The second source is defined in prng_bytes() using a hash-based DRBG construction that is initially seeded with a cryptographically strong random number generator (or CSRNG) from the crypto backend (using OpenSSL or mbed TLS). Finally, the third option is based only on the CSRNG (via rand_bytes()) from the crypto backend.

With this in mind, we tried to find any use of weak random numbers for any crypto-related operations. Fortunately, we confirmed that weak random numbers are only used for scheduling tasks such as sending a ping or when to do TLS renegotiation. Randomness for key generation, authentication tokens and other crypto operations come from the CSRNG while session identifiers and IVs are sourced from the PRNG.

We further analyzed the data channel encryption functionality in terms of the different block-cipher modes of operations and options available to users. Our goal was to determine whether IVs are generated in a sufficiently safe way for non-CBC modes of encryption. For ciphertext feedback (CFB) and output feedback (OFB) modes, a unique IV is chosen for the session from a random packet counter (4 bytes), the current timestamp (4 bytes) and the rest are zeros. Similarly, for GCM, the IV comprises a random packet counter (of 4 bytes) and the remaining bytes of the IV are derived via the TLS PRF (in a normal TLS connection these bytes would form the MAC key, but they are not used for this purpose due to the fact that GCM is an AEAD mode).

While the original NIST recommendation states that a unique IV is sufficient for security for CFB and OFB, a recent analysis by Phillip Rogaway [5] in 2011 shows an attack on CFB/OFB mode if the attacker is able to somehow pick the IV. Based on how CFB/OFB is used in OpenVPN, we tried to find ways an attacker might try to influence or pick the IV. One such possibility is to try to disable the random packet counter (e.g., –no-replay) but OpenVPN explicitly prevents disabling this option if CFB or OFB is the cipher.1 We believe that predictable IVs are safe provided the IVs do not repeat and the attacker cannot pick them. Thus, there is no concrete attack against this construction for CFB and OFB in OpenVPN. Moreover, the approach for choosing IVs for the GCM mode is also sufficient for security.

In terms of the TLS control layer, we analyzed the state machine, negotiation between peers, and how a trusted TLS session is established. In addition, we analyzed the cryptographic “firewall” provided by the –tls-auth and –tls-crypt features to harden the underlying TLS layer. Our goal was to find weaknesses that might allow an attacker to strip this outer layer and then possibly compromise the TLS layer as well. While we did not uncover any major vulnerabilities with these advanced features, we describe some potential issues to consider for –tls-crypt in Section 3.4.2.

We then analyzed the X.509 certificate verification and revocation for any flaws in the OpenVPN logic that a compromised peer could leverage. The only potential issue here relates to using –verify-x509-name to match the prefix in a certificate common name. This particular feature is intended for custom generated certificates and should not be used to verify third-party certificates. However, this issue is also noted in the documentation and users are clearly warned.

In summary, we did not uncover any major flaws or vulnerabilities in OpenVPN but we do recommend improvements to the source based on our detailed findings in Section 3.4. We

Table 3.1: Summary of Findings

also report on the results of applying static and dynamic analysis tools on the OpenVPN 2.4 release in Section 3.2 and Section 3.3, respectively.

3.2 Static Analysis Results

We employed the clang static analyzer to automatically find bugs in the OpenVPN 2.4 release. The clang static analyzer is a source code level analyzer built on top of the clang/LLVM compiler toolchain. Using the clang static analysis tool, we were able to identify at least 3 possible NULL pointer dereference bugs (CWE-476) and 1 case where there is an undefined allocation of 0 bytes error (CWE-131). These results are discussed in Section 3.4.

We also used the static analyzer built into the SciTools Understand Interactive Development Environment (IDE) 2 and found a few potential bugs relative to unsafe C APIs such as strcat and strcpy. On further inspection, we discovered that the potential buffer overflow bugs were false positives. In particular, there were appropriate bound or length checks in the target buffer prior to using the unsafe C functions.

3.3 Dynamic Analysis Results

Using dynamic analysis, we analyzed the memory usage of both an OpenVPN client and server using a variety of configuration options and features. Our goal was to find memory corruption bugs such as heap overflow, use after free/scope, double free and so on by instrumenting OpenVPN at compile time. Specifically, we leveraged the AddressSanitizer (or ASAN) tool, a memory corruption detector for C/C++ code, to find such bugs in the client and server binaries. ASAN consists of an LLVM pass over the code at compile time and replaces every call to the malloc function to detect these bugs.

We note here that all of our memory analysis tests were based on a configuration of OpenVPN using either OpenSSL v1.0.1f or mbed TLS 2.4.0 on Linux/Mac OS X. In addition, the configurations we tested consisted of the features described in Section 2.1. Our analysis focused on most commonly used configurations that would have the highest impact in terms of users. Not including the known bug found while compiling with –disable-crypto, another issue we encountered during this process was compiling PKCS11 support with the mbed TLS crypto backend. This is due to an issue in the configure script.3

We did not uncover any memory corruption bugs in the configurations that we tested. A main reason for this is that OpenVPN memory management includes a garbage collector which tracks dynamic allocations (via a linked list of entries) and frees the memory collectively. The instances in which memory corruption bugs have been found in the past were when the associated utility functions for working with the garbage collector were not used properly. Thus, there is value in continuing to run ASAN on OpenVPN as the code continues to grow and improve.

3.4 Detailed Findings

In this section, we describe the detailed findings from the security review of OpenVPN.

3.4.1 OVPN-01: Sensitive authentication token not wiped on certain TLS auth errors

The auth-token feature provides a means for the server to avoid storing passwords in memory and instead use a temporary random token as an alternative to passing the password. If it is detected that the TLS certificate common name or certificate hashes has changed, the TLS session is disabled without first erasing the token from memory. We refer to the verify_final_auth_checks() function (in src/openvpn/ssl_verify.c from lines 1440-1462 below). To be safe, we recommend calling wipe_auth_token() prior to tls_deauthenticate() if TLS auth errors below occur and NULL!=multi->auth_token and session->opt->auth_token_generate && multi->auth_token_sent hold.

3.4.2 OVPN-02: Potentially flawed TLS control channel encryption

TLS-crypt (–tls-crypt) is a recent feature added to OpenVPN as a hardening layer on top of the TLS layer. TLS-crypt provides the ability to encrypt and authenticate the TLS control channel with knowledge of a pre-shared key. Recall that the control channel is used to exchange network parameters and key material to setup the data channel. The main purpose of this feature is to hide TLS certificate and other tunnel configuration information. Up until now, the protections were for authenticating the messages sent over the TLS control channel using pre-shared keys. The new solution in OpenVPN 2.4 adds encryption on top of the authentication (tls_crypt_wrap/tls_crypt_unwrap functions found in src/openvpn/tls_ crypt.c). We provide a high-level of the encryption algorithm (obtained from the source) and the potentially vulnerable decryption code:

message = control channel plaintext
header = opcode (1 byte) || session_id (8 bytes) || packet_id (8 bytes)
Ka = authentication key (256 bits)
Ke = encryption key (256 bits)
(Ka and Ke are pre-shared keys and similar to the –tls-auth)
auth_tag = HMAC-SHA256(Ka, header || message)
IV = 128 most-significant bits of auth_tag
CT = AES-256-CTR(Ke, IV, message)
output = header || auth_tag || CT

There are two things we noticed about this feature when used in the intended context. First, in the multi-client and server configuration, lots of peers will share the same pre-shared keys over an extended period of time. Second, the IV is the first 128-bits of the authentication tag and this approach is assumed secure if the HMAC-SHA2 is a secure pseudo-random function (PRF).4 With this said, there are two potential issues with this construction which have been well documented in the literature:

  • If IVs collide (or repeat), then a passive attacker could easily recover the message. Although this would result in a complete loss of privacy, it is a known downside of using CTR mode encryption and IV collisions should be rare given the use of a secure PRF.
  • The CT is not MAC’ed which could allow a TLS-crypt enabled server to process invalid ciphertexts before the authentication tag can be checked. This is assuming replay protection is disabled using the –no-replay flag and this is a standard encrypt-and-authenticate type of construction which has known weaknesses.

Given that TLS-crypt provides a means to hide the initialization of a TLS handshake with a OpenVPN server, the attack would be difficult to execute in practice and the worst an attacker can do is cause a denial of service for TLS-crypt clients. Nevertheless, we recommend revisiting the TLS-crypt construction to defend against these possibilities.

3.4.3 OVPN-03: Insecure configuration options

There are a number of options provided by OpenVPN that may result in a less secure deployment of the VPN client and/or server from a cryptographic perspective. Thus, if the user intends on using the encryption/authentication features in OpenVPN, then the availability of some of the following options could lead to an insecure deployment. Due to this risk, we recommend that these options should either be deprecated or removed in future versions of OpenVPN:

1. The –prng option can be instantiated with weak hash functions when used in conjunction with TLS-based key exchange. The weak options are MD4/MD5 for OpenSSL and MD5 for mbed TLS. While the use of such weak hash functions may not lead to an exploitable vulnerability, these options for the PRNG are not approved for the hash-based DRBG specification in NIST SP800-90A.5

2. The –no-iv option disables choosing a random IV for non-CFB/OFB mode of encryption in the data channel. This option is dangerous and should not be used in any circumstance where confidentiality is desired. That is, the encryption becomes more predictable and leads to a loss of privacy. With that said, we are glad to see that this feature has been deprecated in version 2.4 and will be removed completely in version 2.5.

3. The –no-replay option disables replay protection against replay attacks at the cryptographic layer. Replay protection is critical for preventing things like SYN floods attacks, and other types of active attacks against the data channel encryption. Given that replay protection desired in most uses of OpenVPN, it’s not clear what use cases are addressed by disabling replay protection. We recommend removing this option if there is no strong enough justification.

4. In the event a user chooses a block cipher with a 64-bit block size (e.g., Blowfish), the SWEET326 mitigation can be disabled if the –reneg-bytes option is specified by the user. While this is allowed on purpose, we recommend that users should be prevented from bypassing the SWEET32 mitigation. This could mean just ignoring the user specified values in this particular case.

5. SHA-1 and Blowfish are the defaults for message digests and block ciphers. While we understand that users might want these options for backwards compatibility reasons, SHA-1 (for example) should be phased out in cryptographic implementations due to the weaknesses uncovered by several researchers [2, 3, 6, 7]. The same applies to the Blowfish cipher. Thus, we recommend making the defaults SHA-2 and AES instead and force users to intentionally specify these weaker options whenever backwards compatibility is required for a specific deployment.

6. For the data channel, encryption without authentication should be highly emphasized as insecure in the event that the cipher is not an AEAD cipher. Specifically, if a user specifies –auth none and –cipher AES-128-CBC (or CFB/OFB) then the ciphertext is not authenticated via HMAC. Perhaps, this should also result in a warning that this specific configuration is insecure in addition to stating that no authentication algorithm was specified.

3.4.4 OVPN-04: Possible NULL pointer dereferences

We found a few places in the source in which a NULL pointer could possibly be dereferenced. These bugs typically cause a segmentation fault in the program but rarely can be exploited by an attacker. In the Mac OS X keychain management client (contrib/keychain-mcd/ cert_data.c), the calls to malloc do not include a NULL check for the resulting pointer. See lines 68, 217, 257 and 518. We describe other instances in the core code that were discovered using the clang static analyzer:

  • In the deferred authentication sample plugin (sample/sample-plugins/defer/simple.c), the username is retrieved from the environment and not checked for NULL prior to being used in sscanf on line 193.
  • In the recv_line function in src/openvpn/proxy.c, if lookahead=NULL and a number of conditions hold, it is possible to dereference a NULL pointer on line 170.
  • In the phase2_socks_client function in src/openvpn/socket.c, it is possible to dereference a NULL pointer if using a socks proxy, current_remote is NULL, protocol is UDP, and sock->sd is not undefined. If all these conditions hold, then on line 2054 access to field ai_addr results in a NULL pointer dereference.

3.4.5 OVPN-05: Possible allocation of zero bytes with malloc

In some cases when allocating a zero byte buffer a non-null pointer could be returned by malloc. However, reading from or writing to the allocated memory area via the non-null pointer is undefined behavior.7 Such is the case in the buffer_list_aggregate function in buffer.c when it makes a call to buffer_list_aggregate_separator(bl,max,””) function. If this function is called with bl having one 0-length buffer and sep=””, then sep_len will always be 0 and the second time through the for loop more==NULL and count gets incremented to 2 before exiting the loop. This would result in size=0 and was found via the clang static analyzer.

3.4.6 OVPN-06: Remove workaround to support obsolete versions of OpenSSL (v0.9.6b)

Because OpenVPN now requires OpenSSL versions 0.9.8 or higher, the workarounds to deal with the bug in OpenSSL v0.9.6b with respect to ASN1_STRING_to_UTF8 are no longer necessary.

Thus, we recommend removing the workarounds here: (1) src/openvpn/ssl_verify_ openssl.c, lines 459 and 547, (2) sample/sample-plugins/log/log_v3.c, line 231 and (3) sample/sample-plugins/keying-material-exporter-demo/keyingmaterialexporter.c, line 149. We emphasize that removing this workaround is simply a code improvement.

3.4.7 OVPN-07: Remove system() from sample authentication plugin

The deferred authentication plugin allows an OpenVPN server to delay client authentication (e.g., 20 seconds) after a successful TLS handshake (see sample/sample-plugins/defer/ simple.c). This is one of the accepted methods available to users to customize authentication (when –auth-user-pass-verify is used). Although sample plugins are merely for demonstration purposes, they work out of the box with a server and users might use the example as is. Thus, it is important to review these kinds of components as well. The sample plugin uses the system() call which is generally unsafe for C programs because it is prone to shell expansions. We recommend rewriting this sample plugin using execve() to give users a safe default plugin for deferred authentication.

3.4.8 OVPN-08: OpenVPN configuration risks

This section describes configuration options available since early 1.x and 2.x versions of OpenVPN that can lead to unsafe deployments from a software security perspective. While we do not consider these security vulnerabilities of OpenVPN, they can potentially put users at risk of compromise. We recommend that the OpenVPN developers consider eliminating these features in future versions of OpenVPN in favor of safer options and workarounds:

  • The third script security level (–script-security 3) allows passwords to be passed to scripts using environment variables. Unprivileged processes on the same system will be able to access these variables as well. Given that this is unsafe on certain platforms and users are encouraged not to use it, there does not seem to be a good enough reason outside of backwards compatibility to continue supporting this mode. Any feature that requires this level of script security should be rewritten to use safer approaches such as files.
  • The –tls-verify option provides an external scripting capability for a client or server tochecktheX.509nameforanuntrustedTLSsession.8 Giventhecertificatedepthand the common name on the certificate, the custom script can selectively accept certificates then return 0 to allow the TLS handshake or 1 for failure if there is no match. While this advanced feature offers flexibility in terms of how the script chooses to test the certificate, it comes with additional security risk and an expanded attack surface (e.g., especially if users go beyond the sample scripts provided in the OpenVPN distribution and misuse it). Therefore, the recently added –verify-x509-name option is a much safer alternative that effectively provides the same feature without the elevated risks.
  • The –comp-lzo enables compression on the server side of an OpenVPN connection. This compression is only enabled when the client also chooses to use it. While we did not evaluate specific risks from using compression on OpenVPN connections, there exist numerous published results on the risks of using compression in specific underlying protocols that might be tunneled via an OpenVPN connection (e.g., [4]). We recommend warning users about the risks of compression on encrypted channels.

[1] The timestamp is the only thing that an attacker could possibly control.
[2] https://scitools.com/features
[3] Others have had similar issues https://bugzilla.redhat.com/show_bug.cgi?id=1408889#c6
[4] RFC 4868 – https://tools.ietf.org/html/rfc4868
[5] http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
[6] https://sweet32.info/
[7] https://www.securecoding.cert.org/confluence/display/c/MEM04-C.+Beware+of+zero-length+allocations
[8] Note that this option is only called after a number of other certificate fields have been verified but before checking if the certificate has been revoked.

Review Diffs

4.1 Overview

Part of the OpenVPN audit consists of reviewing the differences between OpenVPN version 2.2 and 2.4. The goal is to better understand the main differences and uncover potential vulnerabilities that could have been inserted. To accomplish this, we first reviewed the diffs between the 2.4 beta version and the official 2.2 release, then focused on the diffs between the 2.4 beta and official 2.4 release. We provide the results of our analysis from each review in Section 4.3.

4.2 Summary of Diffs

This section provides a summary of the highlights between the OpenVPN 2.2 version and the latest 2.4 release.

4.2.1 OpenVPN v2.2 to v2.4 beta release

Between the OpenVPN v2.2 release and v2.4 beta release, there were over 1,200 commits in the OpenVPN github repository.

OpenVPN version 2.3 was the first major release by the community and incorporated several improvements to existing features and added approximately 9 new features. We list some of the notable features which allow users to provide access to the encryption keys via the management interface (–management-external-key), provide granular access to X.509 fields in the scripts/plugins (–x509-track), provide extra certificates to complete a certificate authority chain (–extra-certs), provide a SHA-1 fingerprint of a level-1 certificate for TLS certificate verification (–verify-hash), and provide other X.509v3 fields to use for authentication instead of the common name (–x509-username-field). In addition, PolarSSL (later renamed to mbed TLS) was added as a backend for SSL/TLS crypto operations.

There were several security vulnerabilities that were fixed in this release. In particular, there was one buffer overflow vulnerability in the auth-pam plugin with respect to user supplied data (commit 7c0ecd11). A off-by-one vulnerability when parsing the common name field from X.509 certificates (commit ecd934b1) and a heap overflow vulnerability when accessing getaddrinfo() results. Moreover, a denial of service vulnerability when port sharing OpenVPN with a web server (commit 007738e9) and a few NULL pointer dereference vulnerabilities were also fixed. The only crypto-related vulnerability is a collision attack on small block ciphers (also known as SWEET32 [1]) and the mitigation for this attack was part of this release.

The OpenVPN 2.4 beta release incorporated some crypto improvements which include the TLS control channel encryption (–tls-crypt), authentication via generated tokens when client re-authenticates (–auth-gen-token), data channel cipher negotiation (–ncp-ciphers), support for authenticated encryption modes such as AES-GCM and support for external storage of the client certificate (–management-external-cert). In addition, a number of options were deprecated due to exposing users to potential security problems. For example, the –no-iv option disables the pseudo-random IV for data channel encryption. On one hand, the major changes in OpenVPN 2.4 aim to provide users with features that make using OpenVPN safer such as the NCP feature.

Unfortunately, these features introduce some additional complexities as it relates to certificate verification (e.g., –x509-username-field) and different options for users to choose from to validate a peer’s certificate.

4.2.2 OpenVPN v2.4 beta to v2.4 official release

We reviewed approximately 33 commits between the beta version of 2.4 and the official 2.4 release. Most of the commits were improvements to the documentation regarding recently added features, improvements to the build system and minor bug fixes. For example, disallowing the –no-iv option whenever negotiable crypto parameters (NCP) are enabled. Because AES-GCM is the default when NCP is turned on, using –no-iv in conjunction would make the encryption insecure. Additionally, there were a few commits that cleaned up some recently added features. For instance, adding error handling and secure memory deletion for authentication tokens (–auth-gen-token) when options are pulled by a client, disallows re-opening a tunnel if the cipher changes. Also, when compiling with the –disable-crypto flag, OpenVPN will crash due to an extra string format specifier in the usage message (see src/openvpn/options.c, line 4080). Compiling without crypto is fairly uncommon and the issue was fixed by the OpenVPN developers in the github source repository. Finally, the –no-iv option was deprecated in the official 2.4 release and slated for removal in the OpenVPN 2.5 release.

4.3 Analysis

We observed a few things relative to the new security features added in versions 2.3 and 2.4. In particular, TLS-crypt might not be ready for widespread use given the problems we described in Section 3.4.2. In addition, when the negotiable cipher parameter feature is enabled, the peer does not really “negotiate” the cipher with other peers. Instead the default is to pick the first cipher that matches between peers rather than the best. This is not ideal in some scenarios but having this feature is a major step in the right direction.

Another observation is that the management interface for controlling a client continues to expand in terms of supporting external private keys and certificates. All of this is done without providing a security layer. Given that the management interface can be viewed as another plugin for applications to customize the cryptographic aspects of the OpenVPN client (or server), this feature could lead to potential misuse. As such, we recommend that a security layer be designed to provide confidentiality for the management interface in addition to making authentication a default requirement rather than an optional one.

In summary, we are glad to report that not very many security vulnerabilities were found in general post version 2.2 which is a good sign for the security aspects of OpenVPN. To the best of our knowledge, we could not identify any major vulnerabilities that might have been introduced as one of the commits we reviewed.

Conclusions

Given the numerous options and features provided by OpenVPN, vulnerabilities may crop up from certain feature combinations. This will be an ongoing challenge for OpenVPN developers to catch these problems early as the code base continues to evolve and expand. While the overall cryptographic design of OpenVPN is solid, some of the options available may undermine a user’s ability to deploy a secure VPN solution. As such, we recommend that the OpenVPN developers continue to document the risks of using certain advanced features to users. As the code changes, we recommend continuing to run static and dynamic analysis tools prior to each release. Finally, we also reiterate that the OpenVPN developers should continue to deprecate or remove insecure options from the code base and provide safe workarounds whenever possible.

Bibliography

[1]  Karthikeyan Bhargavan and Ga ̈etan Leurent. On the practical (in-) security of 64-bit block ciphers: Collision attacks on http over tls and openvpn. In Proceedings of the 2016 ACM SIGSAC Conference on Computer and Communications Security, pages 456–467. ACM, 2016.

 

[2]  Eli Biham, Rafi Chen, Antoine Joux, Patrick Carribault, Christophe Lemuet, and William Jalby. Collisions of sha-0 and reduced sha-1. In Annual International Conference on the Theory and Applications of Cryptographic Techniques, pages 36–57. Springer, 2005.

 

[3]  John Kelsey and Bruce Schneier. Second preimages on n-bit hash functions for much less than 2^n work. Cryptology ePrint Archive, Report 2004/304, 2004. http://eprint. iacr.org/2004/304.

 

[4]  Juliano Rizzo and Thai Duong. The CRIME attack. Available at https://www.ekoparty.org/archive/2012/CRIME_ekoparty2012.pdf, 2012.

 

[5]  Phillip Rogaway. Evaluation of some blockcipher modes of operation. Evaluation carried out for the Cryptography Research and Evaluation Committees (CRYPTREC) for the Government of Japan, 2011.

 

[6]  Marc Stevens, Elie Bursztein, Pierre Karpman, Ange Albertini, and Yarik Markov. The first collision for full SHA-1, 2017. https://shattered.io/static/shattered.pdf.

 

[7]  Xiaoyun Wang, Yiqun Lisa Yin, and Hongbo Yu. Finding collisions in the full sha-1. In Annual International Cryptology Conference, pages 17–36. Springer, 2005.