Digest API calculates MD4/MD5 digests etc which
are deprecated. In order to use those one needs to
load OpenSSL legacy provider and EVP_MD_fetch() to
fetch digest implementation from all loaded providers.
EVP_MD_fetch() takes library context as an argument,
so we need to pass it there through the digest api stack.
Signed-off-by: Lev Stipakov <lev@openvpn.net>
When trying to connect to a very old OpenVPN server (TLS 1.0) that
supports only outdated signature algorithm but at the same time
requiring a tls-cert-profile of legacy or higher, you can run into
the issue of not allowing the outdated signature algorithm of the
server.
OpenSSL 3.0.8 has added a specific error code for this situation that
we treat as fatal error, similar to the way we treat no common cipher
or no common TLS version.
Signed-off-by: Arne Schwabe <arne@openvpn.net>
This is the result after running 'clang-format -i' on all C++ files and
headers, with the defined formatting rules in .clang-format.
Only the openvpn/common/unicode-impl.hpp has been excluded, as that is
mostly a copy of an external project.
Signed-off-by: David Sommerseth <davids@openvpn.net>
throw() is the same as noexcept(true), which is the same as noexpect.
(https://en.cppreference.com/w/cpp/language/noexcept_spec)
noexpect is more standard nowadays and less likely to create confusion.
Single argument constructors should be marked explicit so they do not
end up being acidentially called.
OpenVPNClient::connect method doesn't communicate common OpenSSL errors
through it's return value due to lack of mappings of OpenSSL errors
to OpenVPN error codes in OpenSSLException implementation.
This commit fixes the issue by introducing new error codes:
- SSL_CA_MD_TOO_WEAK
- SSL_CA_KEY_TOO_SMALL
- SSL_DH_KEY_TOO_SMALL
These error codes are mapped to corresponding OpenSSL errors:
- SSL_R_CA_MD_TOO_WEAK
- SSL_R_CA_KEY_TOO_SMALL
- SSL_R_DH_KEY_TOO_SMALL
Signed-off-by: Dmitriy Dudnik <dmitro.dudnik@openvpn.net>
Implemented according to Wintun documentation
and reference client code.
For send and receive ring, client allocates buffer,
creates event and passes it to Wintun under LocalSystem
privileges. When data is availabe for read, Wintun
moves tail pointer of send ring and signals via
send ring's event. To write, client writes to tail
pointer of receive ring and signals via receive ring's event.
Signed-off-by: Lev Stipakov <lev@openvpn.net>
Error::TUN_HALT, when passed up via tun_error(), now
sends an Explicit Exit Notify message before disconnect.
Signed-off-by: James Yonan <james@openvpn.net>
The metadata that may be possibly be contained in the WKc has to be
verified by means of a user implemented behaviour.
Implement an abstract class that exports a verify() method to be
used for this purpose.
Users can extend this class and override the verify() method with
their own.
A basic implementation is also provided: it will just ignore the
metadata (if any) and report success to the core.
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
to HTTP CONNECT but implemented over the OpenVPN protocol.
1. Client connects to relay server as if it were connecting
to an ordinary OpenVPN server.
2. Client authenticates to relay server using its client
certificate.
3. Client sends a PUSH_REQUEST method to relay server which
then replies with a RELAY message instead of PUSH_REPLY.
4. On receiving the RELAY message, the client attempts to
reconnect using the existing transport socket. The
server will proxy this new connection (at the transport
layer) to a second server (chosen by the relay server)
that is the target of proxy.
5. The client must establish and authenticate a new session
from scratch with the target server, only reusing the
transport layer socket from the original connection to
the relay server.
6. The relay acts as a man-in-the-middle only at the
transport layer (like most proxies), i.e. it forwards
the encrypted session between client and target server
without decrypting or having the capability to decrypt
the session.
7. The client is designed to protect against potentially
untrusted or malicious relays:
(a) The client never transmits the target server
username/password credentials to the relay server.
(b) The relay forwards the encrypted OpenVPN session
between client and target server without having
access to the session keys.
(c) The client configuration has a special directive
for relay server CA (<relay-extra-ca>) and relay
server tls-auth key (<relay-tls-auth>) to allow
for separation of TLS/crypto configuration between
relay and target servers.
(d) The client will reject any PUSH_REPLY messages
from the relay itself to prevent the relay from
trying to establish a tunnel directly with the
client.
Example configuring a client for relay:
# remote addresses point to the relay server
remote ... 1194 udp
remote ... 443 tcp
# include all other directives for connecting
# to the target server
# enable relay mode
relay-mode
# constrain the relay server's cert type
relay-ns-cert-type server
# include extra CAs that validate the relay
# server cert (optional).
<relay-extra-ca>
-----BEGIN CERTIFICATE-----
. . .
-----END CERTIFICATE-----
</relay-extra-ca>
# specify the TLS auth key for the relay server
relay-key-direction 1
<relay-tls-auth>
-----BEGIN OpenVPN Static key V1-----
. . .
-----END OpenVPN Static key V1-----
</relay-tls-auth>
Triple DES, and other 64-bit block-size ciphers vulnerable
to "Sweet32" birthday attack (CVE-2016-6329). Limit such
cipher keys to no more than 64 MB of data
encrypted/decrypted. While our overall goal is to limit
data-limited keys to 64 MB, we trigger a renegotiation
at 48 MB to compensate for possible delays in renegotiation
and rollover to the new key.
This client-side implementation extends data limit
protection to the entire session, even when the server
doesn't implement data limits.
This capability is advertised to servers via the a
peer info setting:
IV_BS64DL=1
meaning "Block-Size 64-bit Data Limit". The "1" indicates
the implementation version.
The implementation currently has some limitations:
* Keys are renegotiated at a maximum rate of once per
5 seconds to reduce the likelihood of loss of
synchronization between peers.
* The maximum renegotiation rate may be further extended
if the peer delays rollover from the old to new key
after renegotiation.
Added N_KEY_LIMIT_RENEG stats counter to count the number
of data-limit-triggered renegotiations.
Added new stats counter KEY_STATE_ERROR which roughly
corresponds to the OpenVPN 2.x error "TLS Error:
local/remote TLS keys are out of sync".
Prevously, the TLS ack/retransmit timeout was hardcoded to
2 seconds. Now we lower the default to 1 second and make
it variable using the (pushable) "tls-timeout" directive.
Additionally, the tls-timeout directive can be specified
in milliseconds instead of seconds by using the
"tls-timeout-ms" form of the directive.
Made the "become primary" time duration configurable via
the (pushable) "become-primary" directive which accepts
a number-of-seconds parameter. become-primary indicates
the time delay between renegotiation and rollover to the
new key for encryption/transmission. become-primary
defaults to the handshake-window which in turn defaults
to 60 seconds.
Incremented core version to 3.0.20.
(instead of 2):
(a) ordinary events such as CONNECTING, CONNECTED,
(b) nonfatal errors such as TRANSPORT_ERROR that will
automatically trigger a reconnect, and
(c) fatal errors such as AUTH_FAILED, that will be followed
by a DISCONNECT
In ClientAPI::Event, added a new "fatal" boolean to indicate
when errors are fatal.
Added a new non-fatal event TUN_ERROR that triggers a
reconnect when errors are indicated in tunio.hpp.
allowing backtracks of up to 2048 (previous limit was 64).
In addition, we now maintain the packet ID window as a bit
array (previously a byte array was used).
the transport layer socket (UDP, TCP, or HTTP proxy) encounters
a send error that indicates potential network reconfiguration
at the system level.
TRANSPORT_ERROR will trigger a core-level reconnect in 5 seconds
(higher than the usual 2), and also notify the higher levels
(above ClientAPI::OpenVPNClient), allowing them to schedule
their own network reachability tests to preempt the default
5-second reconnect.
* Renamed SSL method write_ciphertext_ready() to
read_cleartext_ready() for clarity.
* It's important that read_cleartext_ready() returns an accurate
status. To this end, add ssl_get_bytes_avail to the return
expression for PolarSSL:
return !ct_in.empty() || ssl_get_bytes_avail(ssl);
This will also consider buffering inside of PolarSSL,
and avoid potential deadlocks.
Other SSL modules (AppleCrypto and OpenSSL) have been
commented to warn of this issue.
* Factored out constants such as SHOULD_RETRY to namespace
SSLConst.
* Added flags var to SSL configs.
* Added new SSL flag LOG_VERIFY_STATUS. If disabled,
makes for a quiet SSL negotiation if no errors.
* Detect SSL partial writes and designate a new error status
code (SSL_PARTIAL_WRITE).
* In ProtoStackBase, detect unclassified errors from SSL layer
(throw unknown_status_from_ssl_layer).
* PolarSSL module now recognizes Close Notify status and returns
SSLConst::PEER_CLOSE_NOTIFY.
* In ProtoStackBase, factored out some error handling into
common method.
(MacLifeCycle).
Monitor connection lifecycle notifications, such as sleep, wakeup,
network-unavailable, and network-available.
Note that not all platforms define a lifecycle object. Some
platforms such as Android and iOS manage lifecycle notifications at
the service level, and they call pause(), resume(), reconnect(),
etc. as needed using the main ovpncli API.
Also, added a reason string to Pause event.
of errors. Use this callback to detect STATUS_CANCELLED
returns from Windows TAP driver which translates to
ERROR_OPERATION_ABORTED 995 (0x3E3) from userspace.
This will trigger a fatal error in the client
Error::TUN_IFACE_DISABLED ("TAP adapter is disabled").
tls-version-min <version> ['or-highest'] -- sets the minimum
TLS version we will accept from the peer. Examples for version
include "1.0", "1.1", or "1.2". If 'or-highest' is specified
and version is not recognized, we will only accept the highest TLS
version supported by the local SSL implementation.
Examples:
tls-version-min 1.1 -- fail the connection unless peer can
connect at TLS 1.1 or higher.
tls-version-min 1.3 or-highest -- require that the peer
connect at TLS 1.3 or higher, however if the local SSL
implementation doesn't support TLS 1.3 (as it wouldn't in 2013
since TLS 1.3 doesn't exist yet), reduce the minimum required
version to the highest version supported by the local SSL
implementation (such as TLS 1.2). This is intended to allow
client configurations to target higher TLS versions that are
supported on the server, even if some older clients don't
support these versions yet.
like the rest of the core.
Added verbose() method to class SessionStats so that clients can
know whether to pass extra text data to error() virtual method.
multiple addresses will be treated as if each address was an
individual remote directive.
Fixed issue where UDP transport driver was calling socket
connect method synchronously. This can cause exceptions
to be thrown in corner cases, such as "No route to host"
on OSX/iOS for connections to IPv6 addresses when no default
IPv6 route exists on system. Refactoring UDP connect
operation to be asychronous fixes the issue.
Implemented remote-random.
to communicate specific errors or warnings.
Added TUN_IFACE_CREATE event, which indicates an error creating
the tun interface.
Added REROUTE_GW_NO_DNS error stat, which indicates that
redirect-gateway (IPv4) was processed without an accompanying
DNS directive.
connect intent to service when already connected.
One of the ramifications of the "hot connect" fix above is that
OpenVPNClientBase.is_active() will now return a value that is
instantaneously up-to-date, whereas events might lag because
of the mechanics of inter-thread message posting. Keep this in
mind when correlating received events to is_active() values.
For C++ core threads, increased allowed thread-stop delay to 2.5
seconds before thread is marked as unresponsive and abandoned.
Previous delay was 1 second. This delay can't be made too long,
otherwise Android will tell the user that the app is unresponsive
and invite them to kill it.
When closing out an abandoned core thread, indicate this condition
with a new event type called CORE_THREAD_ABANDONED. If the thread
is abandoned due to lack of response to a disconnect request, then
the CORE_THREAD_ABANDONED event will occur followed by
CORE_THREAD_INACTIVE. For core threads that properly exit,
the DISCONNECTED event will be followed by CORE_THREAD_INACTIVE.
Added save_as_filename parameter to importProfileRemote method for
controlling the filename that the imported profile is saved as.
This parameter may be set to null to have the method choose an
appropriate name. To have an imported profile replace an existing
profile, the filenames much match.
Added UI_OVERLOADED debugging constant to OpenVPNClient to allow
the UI to connect to a profile when already connected to another
profile in order to test "hot connect".
Added new events CLIENT_HALT and CLIENT_RESTART for compatibility
with an Access Server feature that allows the server to remotely
kill or restart the client.
When connecting a profile, the core will now automatically fill in
the username if it is not specified for userlocked profiles.
Version 0.902.
* Implemented connection timeout.
* Implemented show raw stats page.
* Work around issue where sometimes core doesn't stop when
stop() method is called, because of delays in canceling
Asio DNS resolution thread.