Squashed 'OpenVPN Adapter/Vendors/openvpn/' changes from 098fd412a..e6d68831a

e6d68831a deps: update mbedTLS to 2.7.0
59de63fa6 cli.cpp: added OPENVPN_REMOTE_OVERRIDE
caf9cf6c1 RedirectPipe: added additional flags for flexibility
68595de4d ClientAPI::RemoteOverride: added error status
37d848ca2 Log lines from C++ exceptions should contain the text "exception"
f05802cf9 Increase server validation of password size to 16KB to support bundling SAML messages.
52e4d4a5f Increase client validation of password/response size to 16KB to support bundling SAML messages.
a0416ed92 [OVPN3-209] win: add dependencies checksum verification
f6eadbc4d [OVPN3-206] Refactor Windows build system
7b30c2f12 [OVPN3-220] proto.hpp: send initial options set on rekeying
33dd2f29e mbedtls: backport fixes for CVE-2018-0487
0912a9b62 [OVPN3-213] build system: mbedtls timing tests
98fa55576 deps: update asio to 1.12.0
620531101 [OVPN3-215] asio: apply external patches
f4a73bde5 [OVPN3-215] asio: rebase external patches on top of our current commit ID
a61cac928 mbedtls: Patches from 2.7 to fix timing test failures
c892f41fb win: tune dependencies build
8a394a37d [OVPN3-213] build system: mbedtls timing tests
0a3dd67da [OVPN3-190] tun linux: add to/from_json methods
44c6cdfdc [OVPN3-206] readme: update Windows build instructions
0edec4a09 [OVPN3-206] win: update directories in VS projects
3d6fd62cb mac build: improve unittest stability
758ae98c6 [OVPN3-209] win: add dependencies checksum verification
a7642ee82 [OVPN3-205] win: apply mbedTLS patches
ac94b6eb7 [OVPN3-206] Refactor Windows build system
c5bc3859e mbedTLS: don't set endpoint twice in conf object
3d5dd9ee3 [OVPN3-199] mac build: do not overwrite DEP_DIR
b713762ba mbedtls: Patches from 2.7 to fix timing test failures
37ab79fa6 tun linux: apply changes from 362acf0
6a7aee2c9 [OVPN3-190] tun: implement persistence
1d2ebb07f [OVPN3-190] tun: move tun creation to separate class
53e33d634 [OVPN3-190] tun: move content of tun to tuncli
85d3377c2 [OVPN3-190] tun: move tun setup methods to separate file
735b985eb i/o layer:  wrap raw pointers embedded in closures
322ae24b5 OptionList: support variadic template parameter pack in constructors
8a012b454 lz4: added namespace and improved error handling
34998e94a zlib: removed verbose parameter
846ed217d OpenSSL: set SSL_MODE_RELEASE_BUFFERS to conserve memory by releasing unneeded buffers
32e3ea117 OptionList: added show_unused_options() method
fe38233a8 Buffer: added typedefs for thread-safe refcounts
b34b6271e compression: added compress_lz4() and decompress_lz4()
755e1a181 linux/core.hpp: added exclude_from_core() function
a7f6fe64f ManClientInstance::Send: added userprop_local_update() virtual method
94526ac19 BufferAllocated: fixed regression in buffer copy
33c16812e [OVPN3-144] mbedTLS: fix support for 4096bit encrypted keys
f249ab4bd [OVPN3-144] build-mbedtls: run make check before compiling
5040aef4c [OVPN3-144] build-mbedtls: apply patches using git-apply instead of patch
8a5e838ab [OVPN3-144] mbedTLS: fix incompatibility with PKI created by OpenSSL 1.1
e7badefd7 proto.hpp/tls-crypt: fix access to ACK IDs during packet validation
73fa974db proto.hpp: print buffer exception in case of packet access error
79ad5eded Estblishing a stable branch
1c5f20ab0 Hide the @ sign in logs if username is empty
01ee1f5a4 Added ClientAPI::Config::retryOnAuthFailed parameter
05880b136 Added ProfileParseLimits::MAX_SERVER_LIST_SIZE and raise limit to 4096
eedee4fa6 cli.cpp: allow -s server override to reference a friendly name
6e350e9f9 Linux tun setup: use LinuxGW46 to obtain gateway info
3e044c6c7 top-level .gitignore was missing a trailing newline
a27355ac7 Use C++11 push_back(std::move(...))) for pushing objects onto vectors
8c3af2704 HostPort::split_host_port: support unix socket filename as an alternative kind of host
14b588c86 asio: added asio_resolver_results_to_string()
fd6e8e9bf AsioPolySock: minor changes to remote_endpoint_str()
06f5e4d71 AsioBoundSocket::Socket: added to_string() method
8fd968532 RemoteList: minor cleanup in set_endpoint_range()
f9fc2f54e BufferAllocated: improve movability
8cb8d52cd string: added first_line() method
a26b1646b AsioPolySock: extend AltRouting support
ef3a40c27 Listen::Item: added AltRouting mode
02e786bc9 write_binary_atomic: support ConstBuffer
6745799c9 fileunix: added read_binary_unix_fast()
5689c2d9c write_binary_unix(): added ConstBuffer variant
2b0e76453 enum_dir: refactor to allow enumeration via lambda
116a5bd5e bufstr: added const_buf_from_string() method
f8ec81413 Buffer: added const_buffer_ref() variant accepting a const argument
ae98aa8b6 AsioPolySock: support AltRouting
8f81479f1 AsioBoundSocket::Socket: support inheritance
9598918e9 ServerProto: added schedule_disconnect() method.
4516cf67b ServerProto: reset CoarseTime object when AsioTimer is canceled
0ffc76a0b Route: implement operator< so Route objects can be used as map/set keys.
c4af9f68b event_loop_wait_barrier: raise default timeout to 30 seconds
d7fe87540 appversion.hpp: rename VERSION -> BUILD_VERSION

git-subtree-dir: OpenVPN Adapter/Vendors/openvpn
git-subtree-split: e6d68831a71131b7d92fbea93d3b9cbe10ba2068
This commit is contained in:
Sergey Abramchuk
2018-04-04 12:34:20 +03:00
parent 055bb04c14
commit 84ad2a289f
81 changed files with 5189 additions and 856 deletions

2
.gitignore vendored
View File

@@ -1,4 +1,4 @@
README.html
x64
*.vcxproj.user
*.ipch
*.ipch

View File

@@ -149,60 +149,30 @@ To connect::
Building the OpenVPN 3 client on Windows
----------------------------------------
Those instructions were tested with Git Bash.
Prerequisites:
- Visual Studio 2015
- Visual Studio 2017
- Python 2.7
To make python interpreter work inside Git Bash terminal, add::
alias python='winpty python.exe'
to ``.bashrc``.
Clone the OpenVPN 3 source repo::
$ mkdir ovpn3
$ cd ovpn3
$ git clone https://github.com/OpenVPN/openvpn3.git core
> c:\Temp>mkdir O3
> c:\Temp>cd O3
> c:\Temp\O3>git clone https://github.com/OpenVPN/openvpn3.git core
Create ``parms_local.py`` inside ``~/ovpn3/core/win`` directory which overrides build settings from ``parms.py``. For example:
Download and build dependencies::
.. code-block:: python
> c:\Temp\O3>cd core\win
> c:\Temp\O3\core\win>set O3=C:\Temp\O3 && python buildep.py
PARMS = {
"OVPN3" : "c:\\Users\\user\\Projects\\ovpn3",
"TAP" : "c:\\Users\\user\\Projects\\tap-windows",
"DEP" : "c:\\Users\\user\\Downloads",
"BUILD" : "c:\\Users\\user\\Projects\\ovpn3-build",
"LIB_VERSIONS" : {
"asio" : "asio-cc1bd58f9ebb15afbebf53207015ff690b338195"
},
"GTEST_ROOT": "c:\\Users\\user\\Projects\\googletest"
}
Build test client::
Download dependencies as tar(zip)balls to DEP directory defined in previous step:
> c:\Temp\O3\core\win>set O3=C:\Temp\O3 && python build.py
1. Asio — https://github.com/chriskohlhoff/asio
2. mbed TLS (2.3.0 or higher) — https://tls.mbed.org/
3. LZ4 — https://github.com/Cyan4973/lz4
Visual Studio 2015 project and solution files are located in ``O3\core\win`` directory.
Before opening project you need to build dependencies and define OVPN3_ROOT
environmental variable (``C:\Temp\O3`` from example above).
Extract and build dependencies (assuming you are in ``~/ovpn3/core/win`` directory)::
$ python buildep.py
Build the OpenVPN 3 client executable:
$ python build.py
Visual Studio 2015 project and solution files are located in ``~/ovpn3/core/win`` directory.
Before opening project you need to build dependencies and define environmental variables:
- OVPN3_BUILD - path where dependencies are build (BUILD in parms.py)
- OVPN3_CORE - path where ovpn3-core was checked out (OVPN3 in parms.py)
- OVPN3_TAP_WINDOWS - path where tap-windows was checked out (TAP in parms.py)
Testing
-------

63
VersionNumbering.rst Normal file
View File

@@ -0,0 +1,63 @@
OpenVPN 3 version numbering and release process
===============================================
OpenVPN 3 version numbers will always be prefixed with ``3.`` which
indicates the OpenVPN generation. This library is the third
generation of the OpenVPN protocol implementation.
As of OpenVPN 3.2, we will use a single positive integer indicating a
release number as the version reference.
Git branches and versioning
---------------------------
Main development will happen on the git master branch. This will not
contain any specific version. It is will be set to ``3.git:master``.
This branch will contain both stable and unstable code, which will be
bleeding edge at any time. Do not depend on git master for production code.
Once features and fixes in git master has stabilized, they will be
merged into the ``stable`` branch. Code extracted from the stable branch
will contain the release number of the last release. The stable
branch is suitable for production code.
It is not set up a specific plan for when releases will occur. We
might want to collect up a smaller set of features before defining it
ready as a release, depending on the size of the changes. At the
release time, the version string will be updated and tagged (with
a PGP signature).
We should not pile up too many features for each release. It is
better to release often with smaller changesets.
Hot-fixes
---------
We will not do any patch number releases unless strictly needed for
older releases numbers. Such releases will be called hot-fixes and
will be handled in separate branches only when needed. These branches
will be named ``hotfix/3.X``; where X denotes the release number the
hotfix targets. Hotfixes need to update the version string as well
as attaching a git tag with the proper version number.
**Hot-fixes should be avoided as much as possible** and we should
**encourage users to base their work on the stable branch** primarily.
Hot-fixes will only be used for highly critical issues which cannot
wait for a release or the feature gap to move to a newer release is
considered too big. But it should also only occur for releases which
are still relevant.
Examples
--------
git ``master`` branch: version string will be ``3.git:master``
git ``stable`` branch: version string will be ``3.2``, ``3.3``, etc
hotfix for v3.2 will be in ``hotfix/3.2`` and the version string will be
``3.2.1``
Similarly, hotfix for v3.3 will be found in ``hotfix/3.3`` and the version
string will be ``3.3.1``.

View File

@@ -322,6 +322,8 @@ namespace openvpn {
const std::string title = "remote-override";
ClientAPI::RemoteOverride ro;
parent->remote_override(ro);
if (!ro.error.empty())
throw Exception("remote override exception: " + ro.error);
RemoteList::Item::Ptr ri(new RemoteList::Item);
if (!ro.ip.empty())
ri->set_ip_addr(IP::Addr(ro.ip, title));
@@ -414,6 +416,7 @@ namespace openvpn {
bool google_dns_fallback = false;
bool synchronous_dns_lookup = false;
bool autologin_sessions = false;
bool retry_on_auth_failed = false;
std::string private_key_password;
std::string external_pki_alias;
bool disable_client_cert = false;
@@ -654,6 +657,7 @@ namespace openvpn {
state->google_dns_fallback = config.googleDnsFallback;
state->synchronous_dns_lookup = config.synchronousDnsLookup;
state->autologin_sessions = config.autologinSessions;
state->retry_on_auth_failed = config.retryOnAuthFailed;
state->private_key_password = config.privateKeyPassword;
if (!config.protoOverride.empty())
state->proto_override = Protocol::parse(config.protoOverride, Protocol::NO_SUFFIX);
@@ -921,6 +925,7 @@ namespace openvpn {
cc.google_dns_fallback = state->google_dns_fallback;
cc.synchronous_dns_lookup = state->synchronous_dns_lookup;
cc.autologin_sessions = state->autologin_sessions;
cc.retry_on_auth_failed = state->retry_on_auth_failed;
cc.proto_context_options = state->proto_context_options;
cc.http_proxy_options = state->http_proxy_options;
cc.alt_proxy = state->alt_proxy;

View File

@@ -203,6 +203,10 @@ namespace openvpn {
// Enable autologin sessions
bool autologinSessions = true;
// If true, consider AUTH_FAILED to be a non-fatal error,
// and retry the connection after a pause.
bool retryOnAuthFailed = false;
// An ID used for get-certificate and RSA signing callbacks
// for External PKI profiles.
std::string externalPkiAlias;
@@ -411,6 +415,7 @@ namespace openvpn {
std::string ip; // or ip must be defined (or both)
std::string port;
std::string proto;
std::string error; // if non-empty, indicates an error
};
namespace Private {

27
deps/asio/build-asio vendored
View File

@@ -21,13 +21,28 @@ fi
PACKAGE=${ASIO_VERSION}
FNAME=${ASIO_VERSION}.tar.gz
PV=${ASIO_VERSION#*-}
URL=https://github.com/chriskohlhoff/asio/archive/${PV}.tar.gz
URL=https://github.com/chriskohlhoff/asio/archive/${ASIO_VERSION}.tar.gz
CSUM=${ASIO_CSUM}
DIST=asio
download
cd $DEP_DIR
rm -rf asio*
tar xf $DL/$ASIO_VERSION.tar.gz
cp -a $ASIO_VERSION asio
if [ "$NO_WIPE" = "1" ]; then
echo RETAIN existing source
else
echo WIPE and reunzip source
cd $DEP_DIR
rm -rf $DIST asio-$ASIO_VERSION
tar xfz $DL/$FNAME
cd asio-$ASIO_VERSION
# apply pre-generated patches
for file in $O3/core/deps/asio/patches/*.patch; do
echo Applying patch: $file
git apply $file
done
cd ..
cp -a asio-$ASIO_VERSION $DIST
fi

View File

@@ -1,25 +0,0 @@
From 48f2e874280f0d93d1a3df2e48aacc9e13b8eef5 Mon Sep 17 00:00:00 2001
From: James Yonan <james@openvpn.net>
Date: Wed, 1 Mar 2017 13:45:38 -0700
Subject: Android appears to not support pthread_condattr_setclock
---
asio/include/asio/detail/impl/posix_event.ipp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/asio/include/asio/detail/impl/posix_event.ipp b/asio/include/asio/detail/impl/posix_event.ipp
index a62c434..c4b7982 100644
--- a/asio/include/asio/detail/impl/posix_event.ipp
+++ b/asio/include/asio/detail/impl/posix_event.ipp
@@ -31,7 +31,7 @@ namespace detail {
posix_event::posix_event()
: state_(0)
{
-#if (defined(__MACH__) && defined(__APPLE__))
+#if (defined(__MACH__) && defined(__APPLE__)) || defined(__ANDROID__)
int error = ::pthread_cond_init(&cond_, 0);
#else // (defined(__MACH__) && defined(__APPLE__))
::pthread_condattr_t attr;
--
2.7.4

View File

@@ -1,8 +1,8 @@
From 430862dee0dd960be1f702cc5ae0e7c0525d48a4 Mon Sep 17 00:00:00 2001
From 28cdfe3f923affa87420a47f8ac71e791c77bcde Mon Sep 17 00:00:00 2001
From: James Yonan <james@openvpn.net>
Date: Wed, 3 Aug 2016 11:42:38 -0600
Subject: =?UTF-8?q?Added=20Apple=20NAT64=20support=20when=20both=20ASIO=5F?=
=?UTF-8?q?HAS=5FGETADDRINFO=0Aand=20ASIO=5FAPPLE=5FNAT64=20are=20defined.?=
Date: Mon, 19 Mar 2018 11:24:10 +0800
Subject: [PATCH] Added Apple NAT64 support when both ASIO_HAS_GETADDRINFO and
ASIO_APPLE_NAT64 ar defined
* When calling getaddrinfo(), Apple recommends to set
AI_DEFAULT flags in hint.
@@ -16,13 +16,14 @@ Subject: =?UTF-8?q?Added=20Apple=20NAT64=20support=20when=20both=20ASIO=5F?=
1 file changed, 17 insertions(+)
diff --git a/asio/include/asio/detail/impl/socket_ops.ipp b/asio/include/asio/detail/impl/socket_ops.ipp
index d72afec..4f66c77 100644
index b3b1a0cf..e1a07e06 100644
--- a/asio/include/asio/detail/impl/socket_ops.ipp
+++ b/asio/include/asio/detail/impl/socket_ops.ipp
@@ -3276,6 +3276,23 @@ asio::error_code getaddrinfo(const char* host,
@@ -3338,6 +3338,23 @@ asio::error_code getaddrinfo(const char* host,
# endif
#elif !defined(ASIO_HAS_GETADDRINFO)
int error = getaddrinfo_emulation(host, service, &hints, result);
return ec = translate_addrinfo_error(error);
+ return ec = translate_addrinfo_error(error);
+#elif defined(ASIO_HAS_GETADDRINFO) && defined(ASIO_APPLE_NAT64)
+ // For NAT64 compatibility, Apple recommends to set AI_DEFAULT flags
+ addrinfo_type new_hints = hints;
@@ -33,16 +34,15 @@ index d72afec..4f66c77 100644
+ // for non-link-local addresses. Workaround by forcing scope ID to 0 for
+ // non-link-local addresses.
+ if (!error && (*result)->ai_family == AF_INET6)
+ {
+ sockaddr_in6* a6 = (sockaddr_in6*)(*result)->ai_addr;
+ if (a6->sin6_scope_id && !(IN6_IS_ADDR_LINKLOCAL(&a6->sin6_addr) || IN6_IS_ADDR_MC_NODELOCAL(&a6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&a6->sin6_addr)))
+ a6->sin6_scope_id = 0;
+ }
+ {
+ sockaddr_in6* a6 = (sockaddr_in6*)(*result)->ai_addr;
+ if (a6->sin6_scope_id && !(IN6_IS_ADDR_LINKLOCAL(&a6->sin6_addr) || IN6_IS_ADDR_MC_NODELOCAL(&a6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&a6->sin6_addr)))
+ a6->sin6_scope_id = 0;
+ }
+
+ return ec = translate_addrinfo_error(error);
return ec = translate_addrinfo_error(error);
#else
int error = ::getaddrinfo(host, service, &hints, result);
return ec = translate_addrinfo_error(error);
--
1.8.5.2 (Apple Git-48)
2.16.2

View File

@@ -1,14 +1,15 @@
From d1758fee525c6adde63ff13df1ce00c63a9b7671 Mon Sep 17 00:00:00 2001
From c6cb856ac923472e56d8dd631585b4ca58e71c31 Mon Sep 17 00:00:00 2001
From: James Yonan <james@openvpn.net>
Date: Wed, 2 Sep 2015 12:18:48 -0700
Subject: Added randomize() method to asio::ip::tcp::resolver::results_type.
Subject: [PATCH] Added randomize() method to
asio::ip::tcp::resolver::results_type.
---
asio/include/asio/ip/basic_resolver_results.hpp | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/asio/include/asio/ip/basic_resolver_results.hpp b/asio/include/asio/ip/basic_resolver_results.hpp
index dec2c7e..ae36906 100644
index 4146a46b..f0ae258c 100644
--- a/asio/include/asio/ip/basic_resolver_results.hpp
+++ b/asio/include/asio/ip/basic_resolver_results.hpp
@@ -18,6 +18,7 @@
@@ -33,5 +34,5 @@ index dec2c7e..ae36906 100644
typedef std::vector<basic_resolver_entry<InternetProtocol> > values_type;
};
--
1.8.5.2 (Apple Git-48)
2.16.2

View File

@@ -1,19 +1,18 @@
From 630edbebfc2f77ad29480d884e20d0b767883ac2 Mon Sep 17 00:00:00 2001
From 69a6d6aec54b41f4ceac3ac2ba14465a36bf1984 Mon Sep 17 00:00:00 2001
From: James Yonan <james@openvpn.net>
Date: Mon, 27 Feb 2017 13:01:26 -0700
Subject: =?UTF-8?q?Added=20user=20code=20hook=20async=5Fconnect=5Fpost=5Fo?=
=?UTF-8?q?pen()=20to=20be=20called=0Aimmediately=20after=20socket=20open?=
=?UTF-8?q?=20in=20async=5Fconnect.?=
Subject: [PATCH] Added user code hook async_connect_post_open() to be called
immediately after socket open in async_connect.
---
asio/include/asio/basic_socket.hpp | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/asio/include/asio/basic_socket.hpp b/asio/include/asio/basic_socket.hpp
index cbd9b35..dbc9297 100644
index 43430161..0d1b0d28 100644
--- a/asio/include/asio/basic_socket.hpp
+++ b/asio/include/asio/basic_socket.hpp
@@ -866,6 +866,8 @@ public:
@@ -865,6 +865,8 @@ public:
asio::error_code ec;
const protocol_type protocol = peer_endpoint.protocol();
this->get_service().open(this->get_implementation(), protocol, ec);
@@ -22,7 +21,7 @@ index cbd9b35..dbc9297 100644
if (ec)
{
async_completion<ConnectHandler,
@@ -1742,6 +1744,11 @@ protected:
@@ -1741,6 +1743,11 @@ protected:
}
private:
@@ -35,5 +34,5 @@ index cbd9b35..dbc9297 100644
basic_socket(const basic_socket&) ASIO_DELETED;
basic_socket& operator=(const basic_socket&) ASIO_DELETED;
--
1.8.5.2 (Apple Git-48)
2.16.2

14
deps/lib-versions vendored
View File

@@ -1,10 +1,16 @@
export ASIO_VERSION=asio-862aed305dcf91387535519c9549c17630339a12
export ASIO_CSUM=65eb4e0997795e4c7c76325387311c3b9d211754615c275bfe5ca6e186dc322b
export ASIO_VERSION=asio-1-12-0
export ASIO_CSUM=fa8c3a16dc2163f5b3451f2a14ce95277c971f46700497d4e94af6059c00dc06
export LZ4_VERSION=lz4-1.8.0
export LZ4_CSUM=2ca482ea7a9bb103603108b5a7510b7592b90158c151ff50a28f1ca8389fccf6
export MBEDTLS_VERSION=mbedtls-2.6.0
export MBEDTLS_CSUM=99bc9d4212d3d885eeb96273bcde8ecc649a481404b8d7ea7bb26397c9909687
export MBEDTLS_VERSION=mbedtls-2.7.0
export MBEDTLS_CSUM=aeb66d6cd43aa1c79c145d15845c655627a7fc30d624148aaafbb6c36d7f55ef
export OPENSSL_VERSION=openssl-1.0.2h
export JSONCPP_VERSION=1.8.4
export JSONCPP_CSUM=c49deac9e0933bcb7044f08516861a2d560988540b23de2ac1ad443b219afdb6
export TAP_VERSION=0e30f5c13b3c7b0bdd60da915350f653e4c14d92
export TAP_CSUM=8ff65f9e741c5ecfe1af904eaa38713f05639ce9457ef92041fd8e6b2a170315

View File

@@ -53,10 +53,21 @@ else
# apply pre-generated patches
for file in $O3/core/deps/mbedtls/patches/*.patch; do
patch -p1 <$file
echo Applying patch: $file
git apply $file
done
fi
if [[ "x$TARGET" == xlinux* || "x$TARGET" == xosx* ]]; then
# run unit tests and then clean
echo RUNNING CHECK
make check
echo CLEANING
make clean
fi
echo BUILDING
# compiler vars
CC=cc
LD=ld

View File

@@ -1,7 +1,18 @@
diff -urw mbedtls-2.6.0.orig/library/x509.c mbedtls-2.6.0/library/x509.c
--- mbedtls-2.6.0.orig/library/x509.c 2017-11-03 11:46:21.403848065 +0800
+++ mbedtls-2.6.0/library/x509.c 2017-11-03 11:58:46.259817520 +0800
@@ -559,13 +559,20 @@
From 62dd1588a7ec3501edfaf9470cf7a1ca15cb4ba1 Mon Sep 17 00:00:00 2001
From: Antonio Quartulli <antonio@openvpn.net>
Date: Tue, 20 Mar 2018 09:35:47 +0800
Subject: [PATCH] relax x509 date format check
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
---
library/x509.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/library/x509.c b/library/x509.c
index 371d6da1..df2cea81 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -565,13 +565,20 @@ static int x509_parse_time( unsigned char **p, size_t len, size_t yearlen,
/*
* Parse seconds if present
*/
@@ -23,7 +34,7 @@ diff -urw mbedtls-2.6.0.orig/library/x509.c mbedtls-2.6.0/library/x509.c
/*
* Parse trailing 'Z' if present
@@ -575,6 +582,15 @@
@@ -581,6 +588,15 @@ static int x509_parse_time( unsigned char **p, size_t len, size_t yearlen,
(*p)++;
len--;
}
@@ -39,3 +50,6 @@ diff -urw mbedtls-2.6.0.orig/library/x509.c mbedtls-2.6.0/library/x509.c
/*
* We should have parsed all characters at this point
--
2.16.2

View File

@@ -0,0 +1,154 @@
From 56df6d5003b20fa673b67fb06c2ec03a8197c4c2 Mon Sep 17 00:00:00 2001
From: Antonio Quartulli <antonio@openvpn.net>
Date: Wed, 20 Dec 2017 07:03:55 +0800
Subject: [PATCH] pkcs5v2: add support for additional hmacSHA algorithms
Currently only SHA1 is supported as PRF algorithm for PBKDF2
(PKCS#5 v2.0).
This means that keys encrypted and authenticated using
another algorithm of the SHA family cannot be decrypted.
This deficiency has become particularly incumbent now that
PKIs created with OpenSSL1.1 are encrypting keys using
hmacSHA256 by default (OpenSSL1.0 used PKCS#5 v1.0 by default
and even if v2 was forced, it would still use hmacSHA1).
Enable support for all the digest algorithms of the SHA
family for PKCS#5 v2.0.
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
---
include/mbedtls/oid.h | 18 +++++++++++++++
library/oid.c | 45 ++++++++++++++++++++++++++++++++++++++
library/pkcs5.c | 4 +---
tests/suites/test_suite_pkcs5.data | 4 ++--
4 files changed, 66 insertions(+), 5 deletions(-)
diff --git a/include/mbedtls/oid.h b/include/mbedtls/oid.h
index bf2ef5ec..408645ec 100644
--- a/include/mbedtls/oid.h
+++ b/include/mbedtls/oid.h
@@ -228,6 +228,14 @@
#define MBEDTLS_OID_HMAC_SHA1 MBEDTLS_OID_RSA_COMPANY "\x02\x07" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 7 } */
+#define MBEDTLS_OID_HMAC_SHA224 MBEDTLS_OID_RSA_COMPANY "\x02\x08" /**< id-hmacWithSHA224 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 8 } */
+
+#define MBEDTLS_OID_HMAC_SHA256 MBEDTLS_OID_RSA_COMPANY "\x02\x09" /**< id-hmacWithSHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 9 } */
+
+#define MBEDTLS_OID_HMAC_SHA384 MBEDTLS_OID_RSA_COMPANY "\x02\x0A" /**< id-hmacWithSHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 10 } */
+
+#define MBEDTLS_OID_HMAC_SHA512 MBEDTLS_OID_RSA_COMPANY "\x02\x0B" /**< id-hmacWithSHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 11 } */
+
/*
* Encryption algorithms
*/
@@ -514,6 +522,16 @@ int mbedtls_oid_get_oid_by_sig_alg( mbedtls_pk_type_t pk_alg, mbedtls_md_type_t
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_md_alg( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg );
+
+/**
+ * \brief Translate hmac algorithm OID into md_type
+ *
+ * \param oid OID to use
+ * \param md_hmac place to store message hmac algorithm
+ *
+ * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
+ */
+int mbedtls_oid_get_md_hmac( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_hmac );
#endif /* MBEDTLS_MD_C */
/**
diff --git a/library/oid.c b/library/oid.c
index f13826ed..edea950f 100644
--- a/library/oid.c
+++ b/library/oid.c
@@ -625,6 +625,51 @@ static const oid_md_alg_t oid_md_alg[] =
FN_OID_TYPED_FROM_ASN1(oid_md_alg_t, md_alg, oid_md_alg)
FN_OID_GET_ATTR1(mbedtls_oid_get_md_alg, oid_md_alg_t, md_alg, mbedtls_md_type_t, md_alg)
FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_md, oid_md_alg_t, oid_md_alg, mbedtls_md_type_t, md_alg)
+
+/*
+ * For HMAC digestAlgorithm
+ */
+typedef struct {
+ mbedtls_oid_descriptor_t descriptor;
+ mbedtls_md_type_t md_hmac;
+} oid_md_hmac_t;
+
+static const oid_md_hmac_t oid_md_hmac[] =
+{
+#if defined(MBEDTLS_SHA1_C)
+ {
+ { ADD_LEN( MBEDTLS_OID_HMAC_SHA1 ), "hmacSHA1", "HMAC-SHA-1" },
+ MBEDTLS_MD_SHA1,
+ },
+#endif /* MBEDTLS_SHA1_C */
+#if defined(MBEDTLS_SHA256_C)
+ {
+ { ADD_LEN( MBEDTLS_OID_HMAC_SHA224 ), "hmacSHA224", "HMAC-SHA-224" },
+ MBEDTLS_MD_SHA224,
+ },
+ {
+ { ADD_LEN( MBEDTLS_OID_HMAC_SHA256 ), "hmacSHA256", "HMAC-SHA-256" },
+ MBEDTLS_MD_SHA256,
+ },
+#endif /* MBEDTLS_SHA256_C */
+#if defined(MBEDTLS_SHA512_C)
+ {
+ { ADD_LEN( MBEDTLS_OID_HMAC_SHA384 ), "hmacSHA384", "HMAC-SHA-384" },
+ MBEDTLS_MD_SHA384,
+ },
+ {
+ { ADD_LEN( MBEDTLS_OID_HMAC_SHA512 ), "hmacSHA512", "HMAC-SHA-512" },
+ MBEDTLS_MD_SHA512,
+ },
+#endif /* MBEDTLS_SHA512_C */
+ {
+ { NULL, 0, NULL, NULL },
+ MBEDTLS_MD_NONE,
+ },
+};
+
+FN_OID_TYPED_FROM_ASN1(oid_md_hmac_t, md_hmac, oid_md_hmac)
+FN_OID_GET_ATTR1(mbedtls_oid_get_md_hmac, oid_md_hmac_t, md_hmac, mbedtls_md_type_t, md_hmac)
#endif /* MBEDTLS_MD_C */
#if defined(MBEDTLS_PKCS12_C)
diff --git a/library/pkcs5.c b/library/pkcs5.c
index e28d5a84..95f44fa9 100644
--- a/library/pkcs5.c
+++ b/library/pkcs5.c
@@ -96,11 +96,9 @@ static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params,
if( ( ret = mbedtls_asn1_get_alg_null( &p, end, &prf_alg_oid ) ) != 0 )
return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
- if( MBEDTLS_OID_CMP( MBEDTLS_OID_HMAC_SHA1, &prf_alg_oid ) != 0 )
+ if( mbedtls_oid_get_md_hmac( &prf_alg_oid, md_type ) != 0 )
return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
- *md_type = MBEDTLS_MD_SHA1;
-
if( p != end )
return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
diff --git a/tests/suites/test_suite_pkcs5.data b/tests/suites/test_suite_pkcs5.data
index e609d62b..4c2c0bb6 100644
--- a/tests/suites/test_suite_pkcs5.data
+++ b/tests/suites/test_suite_pkcs5.data
@@ -82,9 +82,9 @@ PBES2 Decrypt (bad, PBKDF2 params explicit prf_alg overlong)
depends_on:MBEDTLS_SHA1_C:MBEDTLS_DES_C
mbedtls_pkcs5_pbes2:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"301D06092A864886F70D01050C301004082ED7F24A1D516DD7020208003001":"":"":MBEDTLS_ERR_PKCS5_INVALID_FORMAT + MBEDTLS_ERR_ASN1_OUT_OF_DATA:""
-PBES2 Decrypt (bad, PBKDF2 params explicit prf_alg != HMAC-SHA1)
+PBES2 Decrypt (bad, PBKDF2 params explicit prf_alg != HMAC-SHA*)
depends_on:MBEDTLS_SHA1_C:MBEDTLS_DES_C
-mbedtls_pkcs5_pbes2:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"302706092A864886F70D01050C301A04082ED7F24A1D516DD702020800300A06082A864886F70D0208":"":"":MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE:""
+mbedtls_pkcs5_pbes2:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"302706092A864886F70D01050C301A04082ED7F24A1D516DD702020800300A06082A864886F70D0206":"":"":MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE:""
PBES2 Decrypt (bad, PBKDF2 params extra data)
depends_on:MBEDTLS_SHA1_C:MBEDTLS_DES_C
--
2.16.2

View File

@@ -0,0 +1,128 @@
From bb029567d8a2b55e500a85c916a8d22ae9434ab3 Mon Sep 17 00:00:00 2001
From: Antonio Quartulli <antonio@openvpn.net>
Date: Wed, 31 Jan 2018 23:23:02 +0800
Subject: [PATCH] tests/pkcs5/pbkdf2_hmac: add unit tests for additional SHA
algorithms
Test vectors for SHA224,256,384 and 512 have been
generated using Python's hashlib module by the
following oneliner:
import binascii, hashlib
binascii.hexlify(hashlib.pbkdf2_hmac(ALGO, binascii.unhexlify('PASSWORD'), binascii.unhexlify('SALT'), ITER, KEYLEN)))
where ALGO was 'sha224', 'sha256', 'sha384' and 'sha512'
respectively.
Values for PASSWORD, SALT, ITER and KEYLEN were copied from the
existent test vectors for SHA1.
For SHA256 we also have two test vectors coming from RFC7914 Sec 11.
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
---
tests/suites/test_suite_pkcs5.data | 88 ++++++++++++++++++++++++++++++++++++++
1 file changed, 88 insertions(+)
diff --git a/tests/suites/test_suite_pkcs5.data b/tests/suites/test_suite_pkcs5.data
index 4c2c0bb6..f3c421d0 100644
--- a/tests/suites/test_suite_pkcs5.data
+++ b/tests/suites/test_suite_pkcs5.data
@@ -18,6 +18,94 @@ PBKDF2 RFC 6070 Test Vector #6 (SHA1)
depends_on:MBEDTLS_SHA1_C
pbkdf2_hmac:MBEDTLS_MD_SHA1:"7061737300776f7264":"7361006c74":4096:16:"56fa6aa75548099dcc37d7f03425e0c3"
+PBKDF2 Python hashlib Test Vector #1 (SHA224)
+depends_on:MBEDTLS_SHA256_C
+pbkdf2_hmac:MBEDTLS_MD_SHA224:"70617373776f7264":"73616c74":1:20:"3c198cbdb9464b7857966bd05b7bc92bc1cc4e6e"
+
+PBKDF2 Python hashlib Test Vector #2 (SHA224)
+depends_on:MBEDTLS_SHA256_C
+pbkdf2_hmac:MBEDTLS_MD_SHA224:"70617373776f7264":"73616c74":2:20:"93200ffa96c5776d38fa10abdf8f5bfc0054b971"
+
+PBKDF2 Python hashlib Test Vector #3 (SHA224)
+depends_on:MBEDTLS_SHA256_C
+pbkdf2_hmac:MBEDTLS_MD_SHA224:"70617373776f7264":"73616c74":4096:20:"218c453bf90635bd0a21a75d172703ff6108ef60"
+
+PBKDF2 Python hashlib Test Vector #5 (SHA224)
+depends_on:MBEDTLS_SHA256_C
+pbkdf2_hmac:MBEDTLS_MD_SHA224:"70617373776f726450415353574f524470617373776f7264":"73616c7453414c5473616c7453414c5473616c7453414c5473616c7453414c5473616c74":4096:25:"056c4ba438ded91fc14e0594e6f52b87e1f3690c0dc0fbc057"
+
+PBKDF2 Python hashlib Test Vector #6 (SHA224)
+depends_on:MBEDTLS_SHA256_C
+pbkdf2_hmac:MBEDTLS_MD_SHA224:"7061737300776f7264":"7361006c74":4096:16:"9b4011b641f40a2a500a31d4a392d15c"
+
+PBKDF2 RFC 7914 Sec 11 Test Vector #1 (SHA256)
+depends_on:MBEDTLS_SHA256_C
+pbkdf2_hmac:MBEDTLS_MD_SHA256:"706173737764":"73616c74":1:64:"55ac046e56e3089fec1691c22544b605f94185216dde0465e68b9d57c20dacbc49ca9cccf179b645991664b39d77ef317c71b845b1e30bd509112041d3a19783"
+
+PBKDF2 RFC 7914 Sec 11 Test Vector #2 (SHA256)
+depends_on:MBEDTLS_SHA256_C
+pbkdf2_hmac:MBEDTLS_MD_SHA256:"50617373776f7264":"4e61436c":80000:64:"4ddcd8f60b98be21830cee5ef22701f9641a4418d04c0414aeff08876b34ab56a1d425a1225833549adb841b51c9b3176a272bdebba1d078478f62b397f33c8d"
+
+PBKDF2 Python hashlib Test Vector #1 (SHA256)
+depends_on:MBEDTLS_SHA256_C
+pbkdf2_hmac:MBEDTLS_MD_SHA256:"70617373776f7264":"73616c74":1:20:"120fb6cffcf8b32c43e7225256c4f837a86548c9"
+
+PBKDF2 Python hashlib Test Vector #2 (SHA256)
+depends_on:MBEDTLS_SHA256_C
+pbkdf2_hmac:MBEDTLS_MD_SHA256:"70617373776f7264":"73616c74":2:20:"ae4d0c95af6b46d32d0adff928f06dd02a303f8e"
+
+PBKDF2 Python hashlib Test Vector #3 (SHA256)
+depends_on:MBEDTLS_SHA256_C
+pbkdf2_hmac:MBEDTLS_MD_SHA256:"70617373776f7264":"73616c74":4096:20:"c5e478d59288c841aa530db6845c4c8d962893a0"
+
+PBKDF2 Python hashlib Test Vector #5 (SHA256)
+depends_on:MBEDTLS_SHA256_C
+pbkdf2_hmac:MBEDTLS_MD_SHA256:"70617373776f726450415353574f524470617373776f7264":"73616c7453414c5473616c7453414c5473616c7453414c5473616c7453414c5473616c74":4096:25:"348c89dbcbd32b2f32d814b8116e84cf2b17347ebc1800181c"
+
+PBKDF2 Python hashlib Test Vector #6 (SHA256)
+depends_on:MBEDTLS_SHA256_C
+pbkdf2_hmac:MBEDTLS_MD_SHA256:"7061737300776f7264":"7361006c74":4096:16:"89b69d0516f829893c696226650a8687"
+
+PBKDF2 Python hashlib Test Vector #1 (SHA384)
+depends_on:MBEDTLS_SHA512_C
+pbkdf2_hmac:MBEDTLS_MD_SHA384:"70617373776f7264":"73616c74":1:20:"c0e14f06e49e32d73f9f52ddf1d0c5c719160923"
+
+PBKDF2 Python hashlib Test Vector #2 (SHA384)
+depends_on:MBEDTLS_SHA512_C
+pbkdf2_hmac:MBEDTLS_MD_SHA384:"70617373776f7264":"73616c74":2:20:"54f775c6d790f21930459162fc535dbf04a93918"
+
+PBKDF2 Python hashlib Test Vector #3 (SHA384)
+depends_on:MBEDTLS_SHA512_C
+pbkdf2_hmac:MBEDTLS_MD_SHA384:"70617373776f7264":"73616c74":4096:20:"559726be38db125bc85ed7895f6e3cf574c7a01c"
+
+PBKDF2 Python hashlib Test Vector #5 (SHA384)
+depends_on:MBEDTLS_SHA512_C
+pbkdf2_hmac:MBEDTLS_MD_SHA384:"70617373776f726450415353574f524470617373776f7264":"73616c7453414c5473616c7453414c5473616c7453414c5473616c7453414c5473616c74":4096:25:"819143ad66df9a552559b9e131c52ae6c5c1b0eed18f4d283b"
+
+PBKDF2 Python hashlib Test Vector #6 (SHA384)
+depends_on:MBEDTLS_SHA512_C
+pbkdf2_hmac:MBEDTLS_MD_SHA384:"7061737300776f7264":"7361006c74":4096:16:"a3f00ac8657e095f8e0823d232fc60b3"
+
+PBKDF2 Python hashlib Test Vector #1 (SHA512)
+depends_on:MBEDTLS_SHA512_C
+pbkdf2_hmac:MBEDTLS_MD_SHA512:"70617373776f7264":"73616c74":1:20:"867f70cf1ade02cff3752599a3a53dc4af34c7a6"
+
+PBKDF2 Python hashlib Test Vector #2 (SHA512)
+depends_on:MBEDTLS_SHA512_C
+pbkdf2_hmac:MBEDTLS_MD_SHA512:"70617373776f7264":"73616c74":2:20:"e1d9c16aa681708a45f5c7c4e215ceb66e011a2e"
+
+PBKDF2 Python hashlib Test Vector #3 (SHA512)
+depends_on:MBEDTLS_SHA512_C
+pbkdf2_hmac:MBEDTLS_MD_SHA512:"70617373776f7264":"73616c74":4096:20:"d197b1b33db0143e018b12f3d1d1479e6cdebdcc"
+
+PBKDF2 Python hashlib Test Vector #5 (SHA512)
+depends_on:MBEDTLS_SHA512_C
+pbkdf2_hmac:MBEDTLS_MD_SHA512:"70617373776f726450415353574f524470617373776f7264":"73616c7453414c5473616c7453414c5473616c7453414c5473616c7453414c5473616c74":4096:25:"8c0511f4c6e597c6ac6315d8f0362e225f3c501495ba23b868"
+
+PBKDF2 Python hashlib Test Vector #6 (SHA512)
+depends_on:MBEDTLS_SHA512_C
+pbkdf2_hmac:MBEDTLS_MD_SHA512:"7061737300776f7264":"7361006c74":4096:16:"9d9e9c4cd21fe4be24d5b8244c759665"
+
PBES2 Decrypt (OK)
depends_on:MBEDTLS_SHA1_C:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
mbedtls_pkcs5_pbes2:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"301B06092A864886F70D01050C300E04082ED7F24A1D516DD702020800301406082A864886F70D030704088A4FCC9DCC394910":"70617373776f7264":"1B60098D4834CA752D37B430E70B7A085CFF86E21F4849F969DD1DF623342662443F8BD1252BF83CEF6917551B08EF55A69C8F2BFFC93BCB2DFE2E354DA28F896D1BD1BFB972A1251219A6EC7183B0A4CF2C4998449ED786CAE2138437289EB2203974000C38619DA57A4E685D29649284602BD1806131772DA11A682674DC22B2CF109128DDB7FD980E1C5741FC0DB7":0:"308187020100301306072A8648CE3D020106082A8648CE3D030107046D306B0201010420F12A1320760270A83CBFFD53F6031EF76A5D86C8A204F2C30CA9EBF51F0F0EA7A1440342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFF060606060606"
--
2.16.2

View File

@@ -0,0 +1,49 @@
From d09cecb5f7d1e66476c97a35caee7248930ef425 Mon Sep 17 00:00:00 2001
From: Antonio Quartulli <a@unstable.cc>
Date: Wed, 31 Jan 2018 23:45:09 +0800
Subject: [PATCH] tests/pkcs5/pbkdf2_hmac: extend array to accommodate longer
results
Some unit tests for pbkdf2_hmac() have results longer than
99bytes when represented in hexadecimal form.
For this reason extend the result array to accommodate
longer strings.
At the same time make memset() parametric to avoid
bugs in the future.
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
---
tests/suites/test_suite_pkcs5.function | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tests/suites/test_suite_pkcs5.function b/tests/suites/test_suite_pkcs5.function
index 8fabec08..3ad64805 100644
--- a/tests/suites/test_suite_pkcs5.function
+++ b/tests/suites/test_suite_pkcs5.function
@@ -14,7 +14,7 @@ void pbkdf2_hmac( int hash, char *hex_password_string,
{
unsigned char pw_str[100];
unsigned char salt_str[100];
- unsigned char dst_str[100];
+ unsigned char dst_str[200];
mbedtls_md_context_t ctx;
const mbedtls_md_info_t *info;
@@ -24,9 +24,9 @@ void pbkdf2_hmac( int hash, char *hex_password_string,
mbedtls_md_init( &ctx );
- memset(pw_str, 0x00, 100);
- memset(salt_str, 0x00, 100);
- memset(dst_str, 0x00, 100);
+ memset(pw_str, 0x00, sizeof(pw_str));
+ memset(salt_str, 0x00, sizeof(salt_str));
+ memset(dst_str, 0x00, sizeof(dst_str));
pw_len = unhexify( pw_str, hex_password_string );
salt_len = unhexify( salt_str, hex_salt_string );
--
2.16.2

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,604 @@
From 7ed2575f310fd889fba025aa760f74ec1b41924b Mon Sep 17 00:00:00 2001
From: Antonio Quartulli <antonio@openvpn.net>
Date: Thu, 1 Feb 2018 14:03:36 +0800
Subject: [PATCH] tests_suite_pkparse: new PKCS8-v2 keys with PRF != SHA1
Extend the pkparse test suite with the newly created keys
encrypted using PKCS#8 with PKCS#5 v2.0 with PRF being
SHA224, 256, 384 and 512.
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
---
tests/suites/test_suite_pkparse.data | 576 +++++++++++++++++++++++++++++++++++
1 file changed, 576 insertions(+)
diff --git a/tests/suites/test_suite_pkparse.data b/tests/suites/test_suite_pkparse.data
index 416f9dfe..1bf06270 100644
--- a/tests/suites/test_suite_pkparse.data
+++ b/tests/suites/test_suite_pkparse.data
@@ -362,6 +362,582 @@ Parse RSA Key #49.2 (PKCS#8 encrypted v2 PBKDF2 DES DER, 4096-bit, no PW)
depends_on:MBEDTLS_DES_C:MBEDTLS_SHA1_C:MBEDTLS_PKCS5_C
pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+Parse RSA Key #50 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.pem":"PolarSSLTest":0
+
+Parse RSA Key #50.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #50.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #51 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.pem":"PolarSSLTest":0
+
+Parse RSA Key #51.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #51.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #52 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha224.pem":"PolarSSLTest":0
+
+Parse RSA Key #52.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha224.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #52.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha224.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #53 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224 DER)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.der":"PolarSSLTest":0
+
+Parse RSA Key #53.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224 DER, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #53.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224 DER, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #54 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224 DER, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.der":"PolarSSLTest":0
+
+Parse RSA Key #54.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224 DER, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #54.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224 DER, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #55 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224 DER, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha224.der":"PolarSSLTest":0
+
+Parse RSA Key #55.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224 DER, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha224.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #55.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA224 DER, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha224.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #56 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.pem":"PolarSSLTest":0
+
+Parse RSA Key #56.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #56.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #57 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.pem":"PolarSSLTest":0
+
+Parse RSA Key #57.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #57.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #58 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.pem":"PolarSSLTest":0
+
+Parse RSA Key #58.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #58.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #59 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224 DER)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.der":"PolarSSLTest":0
+
+Parse RSA Key #59.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224 DER, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #59.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224 DER, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #60 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224 DER, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.der":"PolarSSLTest":0
+
+Parse RSA Key #60.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224 DER, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #60.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224 DER, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #61 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224 DER, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.der":"PolarSSLTest":0
+
+Parse RSA Key #61.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224 DER, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #61.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA224 DER, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #62 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.pem":"PolarSSLTest":0
+
+Parse RSA Key #62.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #62.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #63 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.pem":"PolarSSLTest":0
+
+Parse RSA Key #63.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #63.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #64 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.pem":"PolarSSLTest":0
+
+Parse RSA Key #64.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #64.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #65 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256 DER)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.der":"PolarSSLTest":0
+
+Parse RSA Key #65.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256 DER, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #65.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256 DER, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #66 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256 DER, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.der":"PolarSSLTest":0
+
+Parse RSA Key #66.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256 DER, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #66.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256 DER, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #67 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256 DER, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.der":"PolarSSLTest":0
+
+Parse RSA Key #68.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256 DER, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #68.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA256 DER, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #69 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.pem":"PolarSSLTest":0
+
+Parse RSA Key #69.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #69.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #70 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.pem":"PolarSSLTest":0
+
+Parse RSA Key #70.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #70.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #71 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha256.pem":"PolarSSLTest":0
+
+Parse RSA Key #71.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha256.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #71.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha256.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #72 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256 DER)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.der":"PolarSSLTest":0
+
+Parse RSA Key #72.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256 DER, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #72.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256 DER, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #73 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256 DER, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.der":"PolarSSLTest":0
+
+Parse RSA Key #73.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256 DER, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #73.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256 DER, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #74 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256 DER, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha256.der":"PolarSSLTest":0
+
+Parse RSA Key #74.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256 DER, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha256.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #74.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA256 DER, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA256_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha256.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #75 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.pem":"PolarSSLTest":0
+
+Parse RSA Key #75.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #75.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #76 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.pem":"PolarSSLTest":0
+
+Parse RSA Key #76.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #76.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #77 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha384.pem":"PolarSSLTest":0
+
+Parse RSA Key #77.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha384.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #77.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha384.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #78 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384 DER)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.der":"PolarSSLTest":0
+
+Parse RSA Key #78.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384 DER, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #78.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384 DER, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #79 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384 DER, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.der":"PolarSSLTest":0
+
+Parse RSA Key #79.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384 DER, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #79.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384 DER, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #80 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384 DER, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha384.der":"PolarSSLTest":0
+
+Parse RSA Key #80.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384 DER, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha384.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #80.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA384 DER, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha384.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #81 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha384.pem":"PolarSSLTest":0
+
+Parse RSA Key #81.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha384.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #81.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha384.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #82 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.pem":"PolarSSLTest":0
+
+Parse RSA Key #82.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #82.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #83 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha384.pem":"PolarSSLTest":0
+
+Parse RSA Key #83.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha384.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #83.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha384.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #84 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384 DER)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha384.der":"PolarSSLTest":0
+
+Parse RSA Key #84.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384 DER, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha384.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #85.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384 DER, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha384.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #86 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384 DER, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.der":"PolarSSLTest":0
+
+Parse RSA Key #86.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384 DER, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #86.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384 DER, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #87 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384 DER, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha384.der":"PolarSSLTest":0
+
+Parse RSA Key #87.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384 DER, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha384.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #87.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA384 DER, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha384.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #88 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.pem":"PolarSSLTest":0
+
+Parse RSA Key #88.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #88.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #89 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.pem":"PolarSSLTest":0
+
+Parse RSA Key #89.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #89.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #90 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.pem":"PolarSSLTest":0
+
+Parse RSA Key #90.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #90.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #91 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512 DER)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.der":"PolarSSLTest":0
+
+Parse RSA Key #91.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512 DER, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #91.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512 DER, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #92 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512 DER, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.der":"PolarSSLTest":0
+
+Parse RSA Key #92.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512 DER, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #92.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512 DER, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #93 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512 DER, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.der":"PolarSSLTest":0
+
+Parse RSA Key #93.1 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512 DER, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #93.2 (PKCS#8 encrypted v2 PBKDF2 3DES hmacWithSHA512 DER, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #94 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.pem":"PolarSSLTest":0
+
+Parse RSA Key #94.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #94.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #95 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.pem":"PolarSSLTest":0
+
+Parse RSA Key #95.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #95.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #96 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.pem":"PolarSSLTest":0
+
+Parse RSA Key #96.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.pem":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #96.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.pem":"":MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+
+Parse RSA Key #97 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512 DER)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.der":"PolarSSLTest":0
+
+Parse RSA Key #97.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512 DER, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #97.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512 DER, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #98 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512 DER, 2048-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.der":"PolarSSLTest":0
+
+Parse RSA Key #98.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512 DER, 2048-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #98.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512 DER, 2048-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
+Parse RSA Key #99 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512 DER, 4096-bit)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.der":"PolarSSLTest":0
+
+Parse RSA Key #99.1 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512 DER, 4096-bit, wrong PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.der":"PolarSSLTes":MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+
+Parse RSA Key #99.2 (PKCS#8 encrypted v2 PBKDF2 DES hmacWithSHA512 DER, 4096-bit, no PW)
+depends_on:MBEDTLS_DES_C:MBEDTLS_SHA512_C:MBEDTLS_PKCS5_C
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
Parse Public RSA Key #1 (PKCS#8 wrapped)
depends_on:MBEDTLS_MD5_C:MBEDTLS_PEM_PARSE_C
pk_parse_public_keyfile_rsa:"data_files/format_gen.pub":0
--
2.16.2

View File

@@ -26,6 +26,7 @@
#include <sstream>
#include <vector>
#include <cstdint> // for std::uint32_t
#include <tuple>
#include <openvpn/common/size.hpp>
#include <openvpn/common/exception.hpp>
@@ -172,7 +173,12 @@ namespace openvpn {
bool operator==(const RouteType& other) const
{
return prefix_len == other.prefix_len && addr == other.addr;
return std::tie(prefix_len, addr) == std::tie(other.prefix_len, other.addr);
}
bool operator<(const RouteType& other) const
{
return std::tie(prefix_len, addr) < std::tie(other.prefix_len, other.addr);
}
template <typename HASH>

View File

@@ -33,7 +33,7 @@ namespace openvpn {
namespace CF {
// essentially a vector of void *, used as source for array and dictionary constructors
typedef BufferAllocatedType<CFTypeRef> SrcList;
typedef BufferAllocatedType<CFTypeRef, thread_unsafe_refcount> SrcList;
inline Array array(const SrcList& values)
{

View File

@@ -154,7 +154,7 @@ namespace openvpn {
}
catch (const std::exception& e)
{
OPENVPN_LOG("MacLifeCycle Exception: " << e.what());
OPENVPN_LOG("MacLifeCycle exception: " << e.what());
}
// cleanup
@@ -306,7 +306,7 @@ namespace openvpn {
}
catch (const std::exception& e)
{
OPENVPN_LOG("MacLifeCycle::action_timer_callback: " << e.what());
OPENVPN_LOG("MacLifeCycle::action_timer_callback exception: " << e.what());
}
}

View File

@@ -30,6 +30,7 @@
#include <openvpn/addr/ip.hpp>
#include <openvpn/common/extern.hpp>
#include <openvpn/common/to_string.hpp>
namespace openvpn {
namespace AsioBoundSocket {
@@ -51,7 +52,31 @@ namespace openvpn {
bind_local_port = port;
}
private:
std::string to_string() const
{
std::string ret;
ret.reserve(64);
if (bind_local_addr.defined())
{
ret += "local=[";
ret += bind_local_addr.to_string();
ret += "]:";
ret += openvpn::to_string(bind_local_port);
}
try {
const std::string re = openvpn::to_string(remote_endpoint());
if (!ret.empty())
ret += ' ';
ret += "remote=";
ret += re;
}
catch (const std::exception& e)
{
}
return ret;
}
protected:
virtual void async_connect_post_open(const protocol_type& protocol, openvpn_io::error_code& ec) override
{
if (bind_local_addr.defined())
@@ -63,6 +88,7 @@ namespace openvpn {
}
}
private:
IP::Addr bind_local_addr;
unsigned short bind_local_port = 0;
};

View File

@@ -36,7 +36,9 @@
#include <openvpn/common/sockopt.hpp>
#include <openvpn/addr/ip.hpp>
#ifdef OPENVPN_POLYSOCK_SUPPORTS_BIND
#if defined(OPENVPN_POLYSOCK_SUPPORTS_ALT_ROUTING)
#include <openvpn/asio/alt_routing.hpp>
#elif defined(OPENVPN_POLYSOCK_SUPPORTS_BIND)
#include <openvpn/asio/asioboundsock.hpp>
#endif
@@ -67,6 +69,11 @@ namespace openvpn {
virtual void tcp_nodelay() {}
virtual void set_cloexec() {}
virtual int native_handle()
{
return -1;
}
#ifdef ASIO_HAS_LOCAL_SOCKETS
virtual bool peercreds(SockOpt::Creds& cr)
{
@@ -74,6 +81,13 @@ namespace openvpn {
}
#endif
#if defined(OPENVPN_POLYSOCK_SUPPORTS_ALT_ROUTING)
virtual bool alt_routing_enabled()
{
return false;
}
#endif
virtual bool is_open() const = 0;
virtual bool is_local() const = 0;
@@ -112,10 +126,18 @@ namespace openvpn {
socket.async_receive(buf, std::move(callback));
}
#if !defined(OPENVPN_POLYSOCK_SUPPORTS_ALT_ROUTING)
virtual std::string remote_endpoint_str() const override
{
return to_string(socket.remote_endpoint());
try {
return "TCP " + openvpn::to_string(socket.remote_endpoint());
}
catch (const std::exception&)
{
return "TCP";
}
}
#endif
virtual bool remote_ip_port(IP::Addr& addr, unsigned int& port) const override
{
@@ -124,7 +146,7 @@ namespace openvpn {
port = socket.remote_endpoint().port();
return true;
}
catch (std::exception&)
catch (const std::exception&)
{
return false;
}
@@ -164,7 +186,24 @@ namespace openvpn {
return false;
}
#ifdef OPENVPN_POLYSOCK_SUPPORTS_BIND
virtual int native_handle() override
{
return socket.native_handle();
}
#if defined(OPENVPN_POLYSOCK_SUPPORTS_ALT_ROUTING)
virtual std::string remote_endpoint_str() const override
{
return "TCP ALT " + socket.to_string();
}
virtual bool alt_routing_enabled() override
{
return socket.alt_routing_enabled();
}
AltRouting::Socket socket;
#elif defined(OPENVPN_POLYSOCK_SUPPORTS_BIND)
AsioBoundSocket::Socket socket;
#else
openvpn_io::ip::tcp::socket socket;
@@ -237,6 +276,11 @@ namespace openvpn {
return true;
}
virtual int native_handle() override
{
return socket.native_handle();
}
openvpn_io::local::stream_protocol::socket socket;
};
#endif

View File

@@ -0,0 +1,49 @@
// OpenVPN -- An application to securely tunnel IP networks
// over a single port, with support for SSL/TLS-based
// session authentication and key exchange,
// packet encryption, packet authentication, and
// packet compression.
//
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License Version 3
// 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 in the COPYING file.
// If not, see <http://www.gnu.org/licenses/>.
#pragma once
#include <string>
#include <openvpn/common/to_string.hpp>
namespace openvpn {
template <class EPRANGE>
inline std::string asio_resolver_results_to_string(const EPRANGE& endpoint_range)
{
std::string ret;
ret.reserve(64);
bool first = true;
for (const auto &i : endpoint_range)
{
if (!first)
ret += ' ';
ret += '[';
ret += openvpn::to_string(i.endpoint().address());
ret += "]:";
ret += openvpn::to_string(i.endpoint().port());
first = false;
}
return ret;
}
}

View File

@@ -57,7 +57,8 @@ namespace openvpn {
bool is_valid_user_pass() const
{
return validate_auth_cred(username) && validate_auth_cred(password);
return ValidateCreds::is_valid(ValidateCreds::USERNAME, username)
&& ValidateCreds::is_valid(ValidateCreds::PASSWORD, password);
}
bool is_valid() const

View File

@@ -25,19 +25,38 @@
#include <openvpn/common/unicode.hpp>
namespace openvpn {
// Authentication credential (username, password, or response) must
// satisfy these constraints:
//
// 1. must be a valid UTF-8 string
// 2. must not contain control or space characters
// 3. length must be <= 256 unicode characters
//
// Note that we don't check that string is non-empty here,
// callers should do this themselves if necessary.
template <typename STRING>
inline bool validate_auth_cred(const STRING& cred)
{
return Unicode::is_valid_utf8(cred, 256 | Unicode::UTF8_NO_CTRL | Unicode::UTF8_NO_SPACE);
// Validate authentication credential.
// Must be UTF-8.
// Other checks on size and content below.
// We don't check that the credential is non-empty.
namespace ValidateCreds {
enum Type {
USERNAME,
PASSWORD,
RESPONSE
};
template <typename STRING>
static bool is_valid(const Type type, const STRING& cred)
{
size_t max_len_flags;
switch (type)
{
case USERNAME:
// length <= 256 unicode chars, no control chars allowed
max_len_flags = 256 | Unicode::UTF8_NO_CTRL;
break;
case PASSWORD:
case RESPONSE:
// length <= 16384 unicode chars
max_len_flags = 16384;
break;
default:
return false;
}
return Unicode::is_valid_utf8(cred, max_len_flags);
}
}
}

View File

@@ -53,7 +53,7 @@
#include <string>
#include <cstring>
#include <algorithm>
#include <type_traits> // for std::is_nothrow_move_constructible
#include <type_traits> // for std::is_nothrow_move_constructible, std::remove_const
#ifndef OPENVPN_NO_IO
#include <openvpn/io/io.hpp>
@@ -136,11 +136,17 @@ namespace openvpn {
Status status_;
};
template <typename T, typename R>
class BufferAllocatedType;
template <typename T>
class BufferType {
template <typename, typename> friend class BufferAllocatedType;
public:
typedef T* type;
typedef const T* const_type;
typedef typename std::remove_const<T>::type NCT; // non-const type
BufferType()
{
@@ -469,14 +475,14 @@ namespace openvpn {
prepend((const T*)data, size);
}
void read(T* data, const size_t size)
void read(NCT* data, const size_t size)
{
std::memcpy(data, read_alloc(size), size * sizeof(T));
}
void read(void* data, const size_t size)
{
read((T*)data, size);
read((NCT*)data, size);
}
T* write_alloc(const size_t size)
@@ -575,7 +581,7 @@ namespace openvpn {
size_t capacity_; // maximum number of array objects of type T for which memory is allocated, starting at data_
};
template <typename T, typename R = thread_unsafe_refcount>
template <typename T, typename R>
class BufferAllocatedType : public BufferType<T>, public RC<R>
{
using BufferType<T>::data_;
@@ -583,6 +589,8 @@ namespace openvpn {
using BufferType<T>::size_;
using BufferType<T>::capacity_;
template <typename, typename> friend class BufferAllocatedType;
public:
enum {
CONSTRUCT_ZERO = (1<<0), // if enabled, constructors/init will zero allocated space
@@ -636,19 +644,19 @@ namespace openvpn {
}
}
template <typename OT>
BufferAllocatedType(const BufferType<OT>& other, const unsigned int flags)
template <typename T_>
BufferAllocatedType(const BufferType<T_>& other, const unsigned int flags)
{
static_assert(sizeof(T) == sizeof(OT), "size inconsistency");
offset_ = other.offset();
size_ = other.size();
capacity_ = other.capacity();
static_assert(sizeof(T) == sizeof(T_), "size inconsistency");
offset_ = other.offset_;
size_ = other.size_;
capacity_ = other.capacity_;
flags_ = flags;
if (capacity_)
{
data_ = new T[capacity_];
if (size_)
std::memcpy(data_ + offset_, other.c_data(), size_ * sizeof(T));
std::memcpy(data_ + offset_, other.data_ + offset_, size_ * sizeof(T));
}
}
@@ -724,16 +732,17 @@ namespace openvpn {
BufferType<T>::init_headroom(headroom);
}
void move(BufferAllocatedType& other)
template <typename T_, typename R_>
void move(BufferAllocatedType<T_, R_>& other)
{
if (data_)
delete_(data_, capacity_, flags_);
move_(other);
}
RCPtr<BufferAllocatedType<T>> move_to_ptr()
RCPtr<BufferAllocatedType<T, R>> move_to_ptr()
{
RCPtr<BufferAllocatedType<T>> bp = new BufferAllocatedType<T>();
RCPtr<BufferAllocatedType<T, R>> bp = new BufferAllocatedType<T, R>();
bp->move(*this);
return bp;
}
@@ -747,7 +756,8 @@ namespace openvpn {
std::swap(flags_, other.flags_);
}
BufferAllocatedType(BufferAllocatedType&& other) noexcept
template <typename T_, typename R_>
BufferAllocatedType(BufferAllocatedType<T_, R_>&& other) noexcept
{
move_(other);
}
@@ -812,7 +822,8 @@ namespace openvpn {
capacity_ = newcap;
}
void move_(BufferAllocatedType& other)
template <typename T_, typename R_>
void move_(BufferAllocatedType<T_, R_>& other)
{
data_ = other.data_;
offset_ = other.offset_;
@@ -844,17 +855,30 @@ namespace openvpn {
unsigned int flags_;
};
// specializations of BufferType for unsigned char
typedef BufferType<unsigned char> Buffer;
typedef BufferType<const unsigned char> ConstBuffer;
typedef BufferAllocatedType<unsigned char> BufferAllocated;
typedef BufferAllocatedType<unsigned char, thread_unsafe_refcount> BufferAllocated;
typedef RCPtr<BufferAllocated> BufferPtr;
// BufferAllocated with thread-safe refcount
typedef BufferAllocatedType<unsigned char, thread_safe_refcount> BufferAllocatedTS;
typedef RCPtr<BufferAllocatedTS> BufferPtrTS;
// cast BufferType<T> to BufferType<const T>
template <typename T>
inline BufferType<const T>& const_buffer_ref(BufferType<T>& src)
{
return (BufferType<const T>&)src;
}
template <typename T>
inline const BufferType<const T>& const_buffer_ref(const BufferType<T>& src)
{
return (const BufferType<const T>&)src;
}
} // namespace openvpn
#endif // OPENVPN_BUFFER_BUFFER_H

View File

@@ -98,6 +98,13 @@ namespace openvpn {
{
buf.write((unsigned char *)str, std::strlen(str));
}
// Note: ConstBuffer deep links to str, so returned ConstBuffer
// is only defined while str is in scope.
inline ConstBuffer const_buf_from_string(const std::string& str)
{
return ConstBuffer((const unsigned char *)str.c_str(), str.size(), true);
}
}
#endif

96
openvpn/buffer/lz4.hpp Normal file
View File

@@ -0,0 +1,96 @@
// OpenVPN -- An application to securely tunnel IP networks
// over a single port, with support for SSL/TLS-based
// session authentication and key exchange,
// packet encryption, packet authentication, and
// packet compression.
//
// Copyright (C) 2012-2017 OpenVPN Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License Version 3
// 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program in the COPYING file.
// If not, see <http://www.gnu.org/licenses/>.
#pragma once
#include <cstdint> // for std::uint32_t, uint64_t, etc.
#include <lz4.h>
#include <openvpn/common/exception.hpp>
#include <openvpn/common/socktypes.hpp> // for ntohl/htonl
#include <openvpn/buffer/buffer.hpp>
namespace openvpn {
namespace LZ4 {
OPENVPN_EXCEPTION(lz4_error);
inline BufferPtr compress(const ConstBuffer& src,
const size_t headroom,
const size_t tailroom)
{
// sanity check
if (src.size() > LZ4_MAX_INPUT_SIZE)
OPENVPN_THROW(lz4_error, "compress buffer size=" << src.size() << " exceeds LZ4_MAX_INPUT_SIZE=" << LZ4_MAX_INPUT_SIZE);
// allocate dest buffer
BufferPtr dest = new BufferAllocated(sizeof(std::uint32_t) + headroom + tailroom + LZ4_COMPRESSBOUND(src.size()), 0);
dest->init_headroom(headroom);
// as a hint to receiver, write the decompressed size
{
const std::uint32_t size = htonl(src.size());
dest->write(&size, sizeof(size));
}
// compress
const int comp_size = ::LZ4_compress_default((const char *)src.c_data(), (char *)dest->data_end(),
(int)src.size(), (int)dest->remaining(tailroom));
if (comp_size <= 0)
OPENVPN_THROW(lz4_error, "LZ4_compress_default returned error status=" << comp_size);
dest->inc_size(comp_size);
return dest;
}
inline BufferPtr decompress(const ConstBuffer& source,
const size_t headroom,
const size_t tailroom,
size_t max_decompressed_size=LZ4_MAX_INPUT_SIZE)
{
// get the decompressed size
ConstBuffer src(source);
if (src.size() < sizeof(std::uint32_t))
OPENVPN_THROW(lz4_error, "decompress buffer size=" << src.size() << " is too small");
std::uint32_t size;
src.read(&size, sizeof(size));
size = ntohl(size);
if (max_decompressed_size > LZ4_MAX_INPUT_SIZE)
max_decompressed_size = LZ4_MAX_INPUT_SIZE;
if (max_decompressed_size && size > max_decompressed_size)
OPENVPN_THROW(lz4_error, "decompress expansion size=" << size << " is too large (must be <= " << max_decompressed_size << ')');
// allocate dest buffer
BufferPtr dest = new BufferAllocated(headroom + tailroom + size, 0);
dest->init_headroom(headroom);
// decompress
const int decomp_size = LZ4_decompress_safe((const char *)src.c_data(), (char *)dest->data(),
(int)src.size(), size);
if (decomp_size <= 0)
OPENVPN_THROW(lz4_error, "LZ4_decompress_safe returned error status=" << decomp_size);
if (decomp_size != size)
OPENVPN_THROW(lz4_error, "decompress size inconsistency expected_size=" << size << " actual_size=" << decomp_size);
dest->inc_size(decomp_size);
return dest;
}
}
}

View File

@@ -22,12 +22,6 @@
#ifndef OPENVPN_BUFFER_ZLIB_H
#define OPENVPN_BUFFER_ZLIB_H
#ifdef OPENVPN_GZIP_DEBUG
#define OPENVPN_GZIP_VERBOSE true
#else
#define OPENVPN_GZIP_VERBOSE false
#endif
#ifdef HAVE_ZLIB
#include <cstring> // for std::memset
@@ -57,7 +51,6 @@ namespace openvpn {
const size_t headroom,
const size_t tailroom,
const int level,
const bool verbose=OPENVPN_GZIP_VERBOSE,
const int window_bits=15,
const int mem_level=8)
{
@@ -90,8 +83,6 @@ namespace openvpn {
if (status != Z_STREAM_END)
OPENVPN_THROW(zlib_error, "zlib deflate failed, error=" << status);
b->set_size(zs.s.total_out);
if (verbose)
OPENVPN_LOG("*** COMPRESS " << src->size() << " -> " << b->size());
return b;
}
else
@@ -102,7 +93,6 @@ namespace openvpn {
const size_t headroom,
const size_t tailroom,
const size_t max_size,
const bool verbose=OPENVPN_GZIP_VERBOSE,
const size_t block_size=4096,
const int window_bits=15)
{
@@ -142,8 +132,6 @@ namespace openvpn {
OPENVPN_THROW(zlib_error, "zlib inflate max_size " << max_size << " exceeded");
hr = tr = 0;
} while (status == Z_OK);
if (verbose)
OPENVPN_LOG("*** DECOMPRESS " << src->size() << " -> " << blist.join_size());
return blist.join(headroom, tailroom, true);
}
else

View File

@@ -429,14 +429,18 @@ namespace openvpn {
{
ClientEvent::Base::Ptr ev = new ClientEvent::DynamicChallenge(reason);
client_options->events().add_event(std::move(ev));
stop();
}
else
{
ClientEvent::Base::Ptr ev = new ClientEvent::AuthFailed(reason);
client_options->events().add_event(std::move(ev));
client_options->stats().error(Error::AUTH_FAILED);
if (client_options->retry_on_auth_failed())
queue_restart(5000);
else
stop();
}
stop();
}
break;
case Error::TUN_SETUP_FAILED:

View File

@@ -33,6 +33,7 @@ namespace openvpn {
MAX_DIRECTIVE_SIZE=64, // maximum number of chars in an OpenVPN directive
OPT_OVERHEAD=64, // bytes overhead of one option/directive, for accounting purposes
TERM_OVERHEAD=16, // bytes overhead of one argument in an option, for accounting purposes
MAX_SERVER_LIST_SIZE=4096, // maximum server list size, i.e. "setenv SERVER ..."
};
}
}

View File

@@ -275,7 +275,8 @@ namespace openvpn {
{
std::ostringstream out;
// eg. "godot@foo.bar.gov:443 (1.2.3.4) via TCPv4 on tun0/5.5.1.1"
out << user << '@';
if (!user.empty())
out << user << '@';
if (server_host.find_first_of(':') == std::string::npos)
out << server_host;
else

View File

@@ -142,6 +142,7 @@ namespace openvpn {
int default_key_direction = -1;
bool force_aes_cbc_ciphersuites = false;
bool autologin_sessions = false;
bool retry_on_auth_failed = false;
std::string tls_version_min_override;
std::string tls_cert_profile_override;
PeerInfo::Set::Ptr extra_peer_info;
@@ -193,7 +194,8 @@ namespace openvpn {
autologin_sessions(false),
creds_locked(false),
asio_work_always_on_(false),
synchronous_dns_lookup(false)
synchronous_dns_lookup(false),
retry_on_auth_failed_(config.retry_on_auth_failed)
#ifdef OPENVPN_EXTERNAL_TRANSPORT_FACTORY
,extern_transport_factory(config.extern_transport_factory)
#endif
@@ -376,6 +378,8 @@ namespace openvpn {
tunconf->tun_prop.remote_list = remote_list;
tunconf->frame = frame;
tunconf->stats = cli_stats;
if (config.tun_persist)
tunconf->tun_persist.reset(new TunLinux::TunPersist(true, false, nullptr));
tunconf->load(opt);
tun_factory = tunconf;
}
@@ -489,8 +493,7 @@ namespace openvpn {
}
// show unused options
if (opt.n_unused())
OPENVPN_LOG(OPENVPN_UNUSED_OPTIONS << std::endl << opt.render(Option::RENDER_TRUNC_64|Option::RENDER_NUMBER|Option::RENDER_BRACKET|Option::RENDER_UNUSED));
opt.show_unused_options(OPENVPN_UNUSED_OPTIONS);
}
static PeerInfo::Set::Ptr build_peer_info(const Config& config, const ParseClientConfig& pcc, const bool autologin_sessions)
@@ -548,6 +551,11 @@ namespace openvpn {
return false;
}
bool retry_on_auth_failed() const
{
return retry_on_auth_failed_;
}
Client::Config::Ptr client_config(const bool relay_mode)
{
Client::Config::Ptr cli_config = new Client::Config;
@@ -836,6 +844,7 @@ namespace openvpn {
bool creds_locked;
bool asio_work_always_on_;
bool synchronous_dns_lookup;
bool retry_on_auth_failed_;
PushOptionsBase::Ptr push_base;
OptionList::FilterBase::Ptr pushed_options_filter;
ClientLifeCycle::Ptr client_lifecycle;

View File

@@ -27,6 +27,7 @@
#include <vector>
#include <string>
#include <sstream>
#include <utility>
#ifdef HAVE_CONFIG_JSONCPP
#include "json/json.h"
@@ -76,7 +77,7 @@ namespace openvpn {
reset_pod();
// limits
const size_t max_server_list_size = 64;
const size_t max_server_list_size = ProfileParseLimits::MAX_SERVER_LIST_SIZE;
// setenv UV_x
PeerInfo::Set::Ptr peer_info_uv(new PeerInfo::Set);
@@ -123,7 +124,7 @@ namespace openvpn {
se.friendlyName = slist[1];
}
if (!se.server.empty() && !se.friendlyName.empty() && serverList_.size() < max_server_list_size)
serverList_.push_back(se);
serverList_.push_back(std::move(se));
}
else if (arg1 == "PUSH_PEER_INFO")
pushPeerInfo_ = true;
@@ -260,7 +261,7 @@ namespace openvpn {
Option::validate_string("HOST_LIST server", se.server, 256);
Option::validate_string("HOST_LIST friendly name", se.friendlyName, 256);
if (!se.server.empty() && !se.friendlyName.empty() && serverList_.size() < max_server_list_size)
serverList_.push_back(se);
serverList_.push_back(std::move(se));
}
}
}
@@ -346,7 +347,7 @@ namespace openvpn {
{
Option opt;
opt.push_back("client");
options.push_back(opt);
options.push_back(std::move(opt));
added = true;
}
@@ -356,7 +357,7 @@ namespace openvpn {
Option opt;
opt.push_back("dev");
opt.push_back("tun");
options.push_back(opt);
options.push_back(std::move(opt));
added = true;
}
if (added)

View File

@@ -702,7 +702,7 @@ namespace openvpn {
}
catch (const std::exception& e)
{
OPENVPN_LOG("Error parsing client-ip: " << e.what());
OPENVPN_LOG("exception parsing client-ip: " << e.what());
}
ev->tun_name = tun->tun_name();
connected_ = std::move(ev);
@@ -873,7 +873,7 @@ namespace openvpn {
}
catch (const std::exception& e)
{
OPENVPN_LOG("Error parsing inactive: " << e.what());
OPENVPN_LOG("exception parsing inactive: " << e.what());
}
}

View File

@@ -137,9 +137,8 @@ namespace openvpn {
// cache a list of DNS-resolved IP addresses
template <class EPRANGE>
void set_endpoint_range(EPRANGE& endpoint_range, RandomAPI* rng)
void set_endpoint_range(const EPRANGE& endpoint_range, RandomAPI* rng)
{
EPRANGE end;
res_addr_list.reset(new ResolvedAddrList());
for (const auto &i : endpoint_range)
{

View File

@@ -93,7 +93,7 @@ namespace openvpn {
}
catch (const std::exception& e)
{
OPENVPN_LOG("ActionThread Exception: " << e.what());
OPENVPN_LOG("ActionThread exception: " << e.what());
}
openvpn_io::post(io_context, [self=Ptr(this), status]()
{

View File

@@ -22,12 +22,12 @@
#ifndef OPENVPN_COMMON_APPVERSION_H
#define OPENVPN_COMMON_APPVERSION_H
// VERSION version can be passed on build command line
// BUILD_VERSION version can be passed on build command line
#include <openvpn/common/stringize.hpp>
#ifdef VERSION
#define MY_VERSION OPENVPN_STRINGIZE(VERSION)
#ifdef BUILD_VERSION
#define MY_VERSION OPENVPN_STRINGIZE(BUILD_VERSION)
#else
#define MY_VERSION "0.1.0"
#endif

View File

@@ -34,10 +34,28 @@
#include <openvpn/common/size.hpp>
#include <openvpn/common/exception.hpp>
#include <openvpn/common/uniqueptr.hpp>
#include <openvpn/common/function.hpp>
namespace openvpn {
OPENVPN_EXCEPTION(enum_dir_error);
inline bool enum_dir(const std::string& dirname,
Function<void(std::string fn)> func)
{
unique_ptr_del<DIR> dir(::opendir(dirname.c_str()), [](DIR* d) { ::closedir(d); });
if (!dir)
return false;
struct dirent *e;
while ((e = ::readdir(dir.get())) != nullptr)
{
std::string fn(e->d_name);
if (fn != "." && fn != "..")
func(std::move(fn));
}
return true;
}
inline std::vector<std::string> enum_dir(const std::string& dirname,
const size_t size_hint=0,
const bool sort=false)
@@ -45,23 +63,18 @@ namespace openvpn {
std::vector<std::string> ret;
if (size_hint)
ret.reserve(size_hint);
unique_ptr_del<DIR> dir(::opendir(dirname.c_str()), [](DIR* d) { ::closedir(d); });
if (!dir)
throw enum_dir_error(dirname + ": cannot open directory");
struct dirent *e;
while ((e = ::readdir(dir.get())) != nullptr)
{
std::string fn(e->d_name);
if (fn != "." && fn != "..")
if (!enum_dir(dirname, [&ret](std::string fn) {
ret.push_back(std::move(fn));
}
}))
throw enum_dir_error(dirname + ": cannot open directory");
if (sort)
std::sort(ret.begin(), ret.end());
return ret;
}
}
#endif

View File

@@ -47,7 +47,7 @@ namespace openvpn {
inline void write_binary_atomic(const std::string& fn,
const std::string& tmpdir,
const mode_t mode,
const Buffer& buf,
const ConstBuffer& buf,
RandomAPI& rng)
{
// generate temporary filename
@@ -65,6 +65,15 @@ namespace openvpn {
OPENVPN_THROW(file_unix_error, "error moving '" << tfn << "' -> '" << fn << "' : " << strerror_str(eno));
}
}
inline void write_binary_atomic(const std::string& fn,
const std::string& tmpdir,
const mode_t mode,
const Buffer& buf,
RandomAPI& rng)
{
return write_binary_atomic(fn, tmpdir, mode, const_buffer_ref(buf), rng);
}
}
#endif

View File

@@ -82,6 +82,13 @@ namespace openvpn {
write_binary_unix(fn, mode, buf.c_data(), buf.size());
}
inline void write_binary_unix(const std::string& fn,
const mode_t mode,
const ConstBuffer& buf)
{
write_binary_unix(fn, mode, buf.c_data(), buf.size());
}
inline void write_text_unix(const std::string& fn,
const mode_t mode,
const std::string& content)
@@ -140,6 +147,19 @@ namespace openvpn {
return bp;
}
inline bool read_binary_unix_fast(const std::string& fn,
Buffer& out)
{
ScopedFD fd(::open(fn.c_str(), O_RDONLY|O_CLOEXEC));
if (!fd.defined())
return errno;
const ssize_t status = ::read(fd(), out.data_end(), out.remaining(0));
if (status < 0)
return errno;
out.inc_size(status);
return 0;
}
inline std::string read_text_unix(const std::string& filename,
const std::uint64_t max_size = 0,
const unsigned int buffer_flags = 0)

View File

@@ -85,6 +85,23 @@ namespace openvpn {
return true;
}
inline bool is_valid_unix_sock_char(const unsigned char c)
{
return c >= 0x21 && c <= 0x7E;
}
inline bool is_valid_unix_sock(const std::string& host)
{
if (!host.length() || host.length() > 256)
return false;
for (const auto &c : host)
{
if (!is_valid_unix_sock_char(c))
return false;
}
return true;
}
inline void validate_host(const std::string& host, const std::string& title)
{
if (!is_valid_host(host))
@@ -95,8 +112,11 @@ namespace openvpn {
std::string& host,
std::string& port,
const std::string& default_port,
const bool allow_unix,
unsigned int *port_save = nullptr)
{
if (port_save)
*port_save = 0;
const size_t pos = str.find_last_of(':');
const size_t cb = str.find_last_of(']');
if (pos != std::string::npos && (cb == std::string::npos || pos > cb))
@@ -118,7 +138,10 @@ namespace openvpn {
if (host.length() >= 2 && host[0] == '[' && host[host.length()-1] == ']')
host = host.substr(1, host.length()-2);
return is_valid_host(host) && is_valid_port(port, port_save);
if (allow_unix && port == "unix")
return is_valid_unix_sock(host);
else
return is_valid_host(host) && is_valid_port(port, port_save);
}
}

View File

@@ -104,7 +104,7 @@ namespace openvpn {
Option(T first, Args... args)
{
reserve(1 + sizeof...(args));
from_list(first, args...);
from_list(std::move(first), std::forward<Args>(args)...);
}
static validate_status validate(const std::string& str, const size_t max_len)
@@ -360,8 +360,8 @@ namespace openvpn {
template<typename T, typename... Args>
void from_list(T first, Args... args)
{
from_list(first);
from_list(args...);
from_list(std::move(first));
from_list(std::forward<Args>(args)...);
}
volatile mutable bool touched_ = false;
@@ -661,6 +661,18 @@ namespace openvpn {
}
};
OptionList()
{
}
template<typename T, typename... Args>
OptionList(T first, Args... args)
{
reserve(1 + sizeof...(args));
from_list(std::move(first), std::forward<Args>(args)...);
update_map();
}
static OptionList parse_from_csv_static(const std::string& str, Limits* lim)
{
OptionList ret;
@@ -1268,6 +1280,17 @@ namespace openvpn {
return n;
}
void show_unused_options(const char *title=nullptr) const
{
// show unused options
if (n_unused())
{
if (!title)
title = "NOTE: Unused Options";
OPENVPN_LOG_NTNL(title << std::endl << render(Option::RENDER_TRUNC_64|Option::RENDER_NUMBER|Option::RENDER_BRACKET|Option::RENDER_UNUSED));
}
}
// Add item to underlying option list while updating map as well.
void add_item(const Option& opt)
{
@@ -1401,6 +1424,18 @@ namespace openvpn {
OPENVPN_THROW(option_error, "line " << line_num << " is too long");
}
void from_list(Option opt)
{
push_back(std::move(opt));
}
template<typename T, typename... Args>
void from_list(T first, Args... args)
{
from_list(std::move(first));
from_list(std::forward<Args>(args)...);
}
IndexMap map_;
};

View File

@@ -118,11 +118,13 @@ namespace openvpn {
const Argv& argv,
const Environ* env,
RedirectPipe::InOut& inout,
const bool combine_out_err)
unsigned int redirect_pipe_flags)
{
SignalBlockerPipe sbpipe;
RedirectPipe remote;
RedirectPipe local(remote, combine_out_err, !inout.in.empty());
if (!inout.in.empty())
redirect_pipe_flags |= RedirectPipe::ENABLE_IN;
RedirectPipe local(remote, redirect_pipe_flags);
const pid_t pid = system_cmd_async(cmd, argv, env, &remote);
if (pid < pid_t(0))
return -1;
@@ -159,7 +161,7 @@ namespace openvpn {
os << "Error: command failed to execute" << std::endl;
#else
RedirectPipe::InOut inout;
const int status = system_cmd(argv[0], argv, nullptr, inout, true);
const int status = system_cmd(argv[0], argv, nullptr, inout, RedirectPipe::COMBINE_OUT_ERR);
if (status < 0)
os << "Error: command failed to execute" << std::endl;
os << inout.out;

View File

@@ -202,6 +202,14 @@ namespace openvpn {
class RedirectPipe : public RedirectStdFD
{
public:
enum {
COMBINE_OUT_ERR = (1<<0), // capture combined stdout/stderr using a pipe
ENABLE_IN = (1<<1), // make a string -> stdin pipe, otherwise redirect stdin from /dev/null
IGNORE_IN = (1<<2), // don't touch stdin
IGNORE_OUT = (1<<3), // don't touch stdout
IGNORE_ERR = (1<<4), // don't touch stderr
};
struct InOut
{
std::string in;
@@ -212,40 +220,50 @@ namespace openvpn {
RedirectPipe() {}
RedirectPipe(RedirectStdFD& remote,
const bool combine_out_err_arg,
const bool enable_in)
const unsigned int flags_arg)
: flags(flags_arg)
{
int fd[2];
// stdout
Pipe::make_pipe(fd);
out.reset(cloexec(fd[0]));
remote.out.reset(fd[1]);
if (!(flags & IGNORE_OUT))
{
int fd[2];
Pipe::make_pipe(fd);
out.reset(cloexec(fd[0]));
remote.out.reset(fd[1]);
}
// stderr
combine_out_err = remote.combine_out_err = combine_out_err_arg;
if (!combine_out_err)
if (!(flags & IGNORE_ERR))
{
Pipe::make_pipe(fd);
err.reset(cloexec(fd[0]));
remote.err.reset(fd[1]);
combine_out_err = remote.combine_out_err = ((flags & (COMBINE_OUT_ERR|IGNORE_OUT)) == COMBINE_OUT_ERR);
if (!combine_out_err)
{
int fd[2];
Pipe::make_pipe(fd);
err.reset(cloexec(fd[0]));
remote.err.reset(fd[1]);
}
}
// stdin
if (enable_in)
if (!(flags & IGNORE_IN))
{
Pipe::make_pipe(fd);
in.reset(cloexec(fd[1]));
remote.in.reset(fd[0]);
}
else
{
// open /dev/null for stdin
remote.in.reset(::open("/dev/null", O_RDONLY, 0));
if (!remote.in.defined())
if (flags & ENABLE_IN)
{
const int eno = errno;
OPENVPN_THROW(redirect_std_err, "error opening /dev/null : " << strerror_str(eno));
int fd[2];
Pipe::make_pipe(fd);
in.reset(cloexec(fd[1]));
remote.in.reset(fd[0]);
}
else
{
// open /dev/null for stdin
remote.in.reset(::open("/dev/null", O_RDONLY, 0));
if (!remote.in.defined())
{
const int eno = errno;
OPENVPN_THROW(redirect_std_err, "error opening /dev/null : " << strerror_str(eno));
}
}
}
}
@@ -253,12 +271,24 @@ namespace openvpn {
void transact(InOut& inout)
{
openvpn_io::io_context io_context(1);
Pipe::SD_OUT send_in(io_context, inout.in, in);
Pipe::SD_IN recv_out(io_context, out);
Pipe::SD_IN recv_err(io_context, err);
std::unique_ptr<Pipe::SD_OUT> send_in;
std::unique_ptr<Pipe::SD_IN> recv_out;
std::unique_ptr<Pipe::SD_IN> recv_err;
if (!(flags & IGNORE_IN))
send_in.reset(new Pipe::SD_OUT(io_context, inout.in, in));
if (!(flags & IGNORE_OUT))
recv_out.reset(new Pipe::SD_IN(io_context, out));
if (!(flags & IGNORE_ERR))
recv_err.reset(new Pipe::SD_IN(io_context, err));
io_context.run();
inout.out = recv_out.content();
inout.err = recv_err.content();
if (recv_out)
inout.out = recv_out->content();
if (recv_err)
inout.err = recv_err->content();
}
private:
@@ -273,6 +303,7 @@ namespace openvpn {
return fd;
}
const unsigned int flags = 0;
};
}

View File

@@ -222,6 +222,16 @@ namespace openvpn {
return str.find_first_of('\n') != std::string::npos;
}
// return the first line (without newline) of a multi-line string
std::string first_line(const std::string& str)
{
const size_t pos = str.find_first_of('\n');
if (pos != std::string::npos)
return str.substr(0, pos);
else
return str;
}
// Define a common interpretation of what constitutes a space character.
// Return true if c is a space char.
inline bool is_space(const char c)

View File

@@ -24,6 +24,6 @@
#ifndef OPENVPN_COMMON_VERSION_H
#define OPENVPN_COMMON_VERSION_H
#define OPENVPN_VERSION "3.1.2"
#define OPENVPN_VERSION "3.git:master"
#endif // OPENVPN_COMMON_VERSION_H

View File

@@ -28,7 +28,7 @@
namespace openvpn {
template <typename THREAD_COMMON>
inline void event_loop_wait_barrier(THREAD_COMMON& tc,
const unsigned int seconds=10)
const unsigned int seconds=30)
{
// barrier prior to event-loop entry
switch (tc.event_loop_bar.wait(seconds))

View File

@@ -40,7 +40,7 @@ namespace openvpn {
class StaticKey
{
friend class OpenVPNStaticKey;
typedef BufferAllocatedType<unsigned char> key_t;
typedef BufferAllocated key_t;
public:
StaticKey() {}

View File

@@ -43,6 +43,22 @@ namespace openvpn {
pthread_t current_thread = pthread_self();
return pthread_setaffinity_np(current_thread, sizeof(cpu_set_t), &cpuset);
}
inline int exclude_from_core(const int core_id)
{
const int num_cores = n_cores();
if (num_cores <= 1 || core_id >= num_cores)
return EINVAL;
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
for (int i = 0; i < num_cores; ++i)
if (i != core_id)
CPU_SET(i, &cpuset);
pthread_t current_thread = pthread_self();
return pthread_setaffinity_np(current_thread, sizeof(cpu_set_t), &cpuset);
}
}
#endif

View File

@@ -687,16 +687,26 @@ namespace openvpn {
clear();
try {
const Config& c = *ctx->config;
int status;
int endpoint, status;
// set pointer back to parent
parent = ctx;
// set client/server mode
if (c.mode.is_server())
{
endpoint = MBEDTLS_SSL_IS_SERVER;
authcert.reset(new AuthCert());
}
else if (c.mode.is_client())
endpoint = MBEDTLS_SSL_IS_CLIENT;
else
throw MbedTLSException("unknown client/server mode");
// init SSL configuration object
sslconf = new mbedtls_ssl_config;
mbedtls_ssl_config_init(sslconf);
mbedtls_ssl_config_defaults(sslconf,
c.mode.is_client() ? MBEDTLS_SSL_IS_CLIENT : MBEDTLS_SSL_IS_SERVER,
mbedtls_ssl_config_defaults(sslconf, endpoint,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT);
@@ -707,17 +717,6 @@ namespace openvpn {
ssl = new mbedtls_ssl_context;
mbedtls_ssl_init(ssl);
// set client/server mode
if (c.mode.is_server())
{
mbedtls_ssl_conf_endpoint(sslconf, MBEDTLS_SSL_IS_SERVER);
authcert.reset(new AuthCert());
}
else if (c.mode.is_client())
mbedtls_ssl_conf_endpoint(sslconf, MBEDTLS_SSL_IS_CLIENT);
else
throw MbedTLSException("unknown client/server mode");
// set minimum TLS version
if (!c.force_aes_cbc_ciphersuites || c.tls_version_min > TLSVersion::UNDEF)
{
@@ -1345,7 +1344,7 @@ namespace openvpn {
}
catch (const std::exception& e)
{
OPENVPN_LOG("MbedTLSContext::epki_sign: " << e.what());
OPENVPN_LOG("MbedTLSContext::epki_sign exception: " << e.what());
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
}

View File

@@ -128,7 +128,7 @@ namespace openvpn {
argv.emplace_back("-6");
argv.emplace_back("route");
argv.emplace_back("show");
const int status = system_cmd(argv[0], argv, nullptr, pipe, false);
const int status = system_cmd(argv[0], argv, nullptr, pipe, 0);
if (status != 0)
OPENVPN_THROW(linux_gw_error, "command returned error status " << status << " : " << argv.to_string());
return pipe.out;

View File

@@ -522,6 +522,9 @@ namespace openvpn {
if (!ssl)
throw OpenSSLException("OpenSSLContext::SSL: SSL_new failed");
// release unneeded buffers
SSL_set_mode(ssl, SSL_MODE_RELEASE_BUFFERS);
// verify hostname
if (hostname)
{
@@ -791,7 +794,7 @@ namespace openvpn {
}
catch (const std::exception& e)
{
OPENVPN_LOG("OpenSSLContext::ExternalPKIImpl::rsa_priv_enc: " << e.what());
OPENVPN_LOG("OpenSSLContext::ExternalPKIImpl::rsa_priv_enc exception: " << e.what());
++self->n_errors;
return -1;
}

View File

@@ -44,6 +44,9 @@ namespace openvpn {
SSLUnspecified,
SSLOn,
SSLOff,
#ifdef OPENVPN_POLYSOCK_SUPPORTS_ALT_ROUTING
AltRouting,
#endif
};
std::string directive;
@@ -60,10 +63,22 @@ namespace openvpn {
if (!proto.is_local())
ret += ' ' + port;
ret += ' ' + std::string(proto.str()) + ' ' + openvpn::to_string(n_threads);
if (ssl == SSLOn)
ret += " ssl";
else if (ssl == SSLOff)
ret += " !ssl";
switch (ssl)
{
case SSLUnspecified:
break;
case SSLOn:
ret += " ssl";
break;
case SSLOff:
ret += " !ssl";
break;
#ifdef OPENVPN_POLYSOCK_SUPPORTS_ALT_ROUTING
case AltRouting:
ret += " alt";
break;
#endif
}
return ret;
}
@@ -192,6 +207,10 @@ namespace openvpn {
}
else if (ssl_qualifier == "!ssl")
e.ssl = Item::SSLOff;
#ifdef OPENVPN_POLYSOCK_SUPPORTS_ALT_ROUTING
else if (ssl_qualifier == "alt")
e.ssl = Item::AltRouting;
#endif
else
OPENVPN_THROW(option_error, e.directive << ": unrecognized SSL qualifier");
}

View File

@@ -87,6 +87,9 @@ namespace openvpn {
const std::string* username,
const bool challenge,
const bool throw_on_error) = 0;
// notify of local user properties update
virtual void userprop_local_update() = 0;
};
// Base class for the client instance receiver. Note that all
@@ -113,6 +116,9 @@ namespace openvpn {
// send control channel message
virtual void post_cc_msg(BufferPtr&& msg) = 0;
// schedule a low-level connection disconnect in seconds
virtual void schedule_disconnect(const unsigned int seconds) = 0;
// set up relay to target
virtual void relay(const IP::Addr& target, const int port) = 0;

View File

@@ -327,12 +327,12 @@ namespace openvpn {
const AuthCert::Ptr& auth_cert) override
{
constexpr size_t MAX_USERNAME_SIZE = 256;
constexpr size_t MAX_PASSWORD_SIZE = 256;
constexpr size_t MAX_PASSWORD_SIZE = 16384;
if (get_management())
{
AuthCreds::Ptr auth_creds(new AuthCreds(Unicode::utf8_printable(username, MAX_USERNAME_SIZE|Unicode::UTF8_FILTER),
Unicode::utf8_printable(password, MAX_PASSWORD_SIZE|Unicode::UTF8_FILTER),
Unicode::utf8_printable(password, MAX_PASSWORD_SIZE|Unicode::UTF8_FILTER|Unicode::UTF8_PASS_FMT),
Unicode::utf8_printable(peer_info, Unicode::UTF8_FILTER|Unicode::UTF8_PASS_FMT)));
ManLink::send->auth_request(auth_creds, auth_cert, peer_addr);
}
@@ -512,6 +512,15 @@ namespace openvpn {
set_housekeeping_timer();
}
virtual void schedule_disconnect(const unsigned int seconds)
{
if (halt || did_client_halt_restart)
return;
Base::update_now();
disconnect_in(Time::Duration::seconds(seconds));
set_housekeeping_timer();
}
virtual void post_cc_msg(BufferPtr&& msg) override
{
if (halt || !Base::primary_defined())
@@ -621,6 +630,7 @@ namespace openvpn {
else
{
housekeeping_timer.cancel();
housekeeping_schedule.reset();
}
}
}

View File

@@ -338,6 +338,10 @@ namespace openvpn {
// Compatibility
bool force_aes_cbc_ciphersuites = false;
// For compatibility with openvpn2 we send initial options on rekeying,
// instead of possible modifications caused by NCP
std::string initial_options;
void load(const OptionList& opt, const ProtoContextOptions& pco,
const int default_key_direction, const bool server)
@@ -669,6 +673,9 @@ namespace openvpn {
// transmitted to peer for options consistency check
std::string options_string()
{
if (!initial_options.empty())
return initial_options;
std::ostringstream out;
const bool server = ssl_factory->mode().is_server();
@@ -708,8 +715,10 @@ namespace openvpn {
out << ",tls-server";
else
out << ",tls-client";
initial_options = out.str();
return out.str();
return initial_options;
}
// generate a string summarizing information about the client
@@ -1593,8 +1602,9 @@ namespace openvpn {
return validate_tls_plain(recv, proto, now);
}
}
catch (BufferException&)
catch (BufferException& e)
{
OPENVPN_LOG_PROTO_VERBOSE("validate() exception: " << e.what());
}
return false;
}
@@ -1764,9 +1774,9 @@ namespace openvpn {
// verify tls_auth packet ID
const bool pid_ok = proto.ta_pid_recv.test_add(pid, t, false);
// make sure that our own PSID is contained in packet received from peer
if (ReliableAck::ack_skip(recv))
if (ReliableAck::ack_skip(work))
{
ProtoSessionID dest_psid(recv);
ProtoSessionID dest_psid(work);
if (!proto.psid_self.match(dest_psid))
return false;
}

View File

@@ -304,16 +304,15 @@ namespace openvpn {
frame_context.prepare(tcpfrom->buf);
socket.async_receive(frame_context.mutable_buffer_clamp(tcpfrom->buf),
[self=Ptr(this), tcpfrom](const openvpn_io::error_code& error, const size_t bytes_recvd)
[self=Ptr(this), tcpfrom=PacketFrom::SPtr(tcpfrom)](const openvpn_io::error_code& error, const size_t bytes_recvd) mutable
{
self->handle_recv(tcpfrom, error, bytes_recvd);
self->handle_recv(std::move(tcpfrom), error, bytes_recvd);
});
}
void handle_recv(PacketFrom *tcpfrom, const openvpn_io::error_code& error, const size_t bytes_recvd)
void handle_recv(PacketFrom::SPtr pfp, const openvpn_io::error_code& error, const size_t bytes_recvd)
{
OPENVPN_LOG_TCPLINK_VERBOSE("TCPLink::handle_recv: " << error.message());
PacketFrom::SPtr pfp(tcpfrom);
if (!halt)
{
if (!error)
@@ -331,7 +330,7 @@ namespace openvpn {
}
catch (const std::exception& e)
{
OPENVPN_LOG_TCPLINK_ERROR("TCP packet extract error: " << e.what());
OPENVPN_LOG_TCPLINK_ERROR("TCP packet extract exception: " << e.what());
stats->error(Error::TCP_SIZE_ERROR);
read_handler->tcp_error_handler("TCP_SIZE_ERROR");
stop();

View File

@@ -141,16 +141,15 @@ namespace openvpn {
frame_context.prepare(udpfrom->buf);
socket.async_receive_from(frame_context.mutable_buffer(udpfrom->buf),
udpfrom->sender_endpoint,
[self=Ptr(this), udpfrom](const openvpn_io::error_code& error, const size_t bytes_recvd)
[self=Ptr(this), udpfrom=PacketFrom::SPtr(udpfrom)](const openvpn_io::error_code& error, const size_t bytes_recvd) mutable
{
self->handle_read(udpfrom, error, bytes_recvd);
self->handle_read(std::move(udpfrom), error, bytes_recvd);
});
}
void handle_read(PacketFrom *udpfrom, const openvpn_io::error_code& error, const size_t bytes_recvd)
void handle_read(PacketFrom::SPtr pfp, const openvpn_io::error_code& error, const size_t bytes_recvd)
{
OPENVPN_LOG_UDPLINK_VERBOSE("UDPLink::handle_read: " << error.message());
PacketFrom::SPtr pfp(udpfrom);
if (!halt)
{
if (bytes_recvd)
@@ -200,7 +199,7 @@ namespace openvpn {
}
catch (openvpn_io::system_error& e)
{
OPENVPN_LOG_UDPLINK_ERROR("UDP send error: " << e.what());
OPENVPN_LOG_UDPLINK_ERROR("UDP send exception: " << e.what());
stats->error(Error::NETWORK_SEND_ERROR);
return e.code().value();
}

View File

@@ -199,7 +199,7 @@ namespace openvpn {
catch (const std::exception& e)
{
if (!quiet)
OPENVPN_LOG("Error processing route-metric: " << e.what());
OPENVPN_LOG("exception processing route-metric: " << e.what());
}
}
@@ -396,7 +396,7 @@ namespace openvpn {
catch (const std::exception& e)
{
if (!quiet)
OPENVPN_LOG("Error parsing IPv4 route: " << o.render(OPT_RENDER_FLAGS) << " : " << e.what());
OPENVPN_LOG("exception parsing IPv4 route: " << o.render(OPT_RENDER_FLAGS) << " : " << e.what());
}
}
}
@@ -424,7 +424,7 @@ namespace openvpn {
catch (const std::exception& e)
{
if (!quiet)
OPENVPN_LOG("Error parsing IPv6 route: " << o.render(OPT_RENDER_FLAGS) << " : " << e.what());
OPENVPN_LOG("exception parsing IPv6 route: " << o.render(OPT_RENDER_FLAGS) << " : " << e.what());
}
}
}
@@ -451,7 +451,7 @@ namespace openvpn {
catch (const std::exception& e)
{
if (!quiet)
OPENVPN_LOG("Error adding remote bypass route: " << addr.to_string() << " : " << e.what());
OPENVPN_LOG("exception adding remote bypass route: " << addr.to_string() << " : " << e.what());
}
}
}
@@ -561,7 +561,7 @@ namespace openvpn {
catch (const std::exception& e)
{
if (!quiet)
OPENVPN_LOG("Error parsing dhcp-option: " << o.render(OPT_RENDER_FLAGS) << " : " << e.what());
OPENVPN_LOG("exception parsing dhcp-option: " << o.render(OPT_RENDER_FLAGS) << " : " << e.what());
}
}
try {
@@ -584,7 +584,7 @@ namespace openvpn {
catch (const std::exception& e)
{
if (!quiet)
OPENVPN_LOG("Error setting dhcp-option for proxy: " << e.what());
OPENVPN_LOG("exception setting dhcp-option for proxy: " << e.what());
}
}
return flags;
@@ -606,7 +606,7 @@ namespace openvpn {
catch (const std::exception& e)
{
if (!quiet)
OPENVPN_LOG("Error parsing dhcp-option: " << o.render(OPT_RENDER_FLAGS) << " : " << e.what());
OPENVPN_LOG("exception parsing dhcp-option: " << o.render(OPT_RENDER_FLAGS) << " : " << e.what());
}
}
}

View File

@@ -24,307 +24,49 @@
#ifndef OPENVPN_TUN_LINUX_CLIENT_TUNCLI_H
#define OPENVPN_TUN_LINUX_CLIENT_TUNCLI_H
#include <openvpn/common/exception.hpp>
#include <openvpn/common/file.hpp>
#include <openvpn/common/split.hpp>
#include <openvpn/common/splitlines.hpp>
#include <openvpn/common/hexstr.hpp>
#include <openvpn/common/to_string.hpp>
#include <openvpn/common/process.hpp>
#include <openvpn/common/action.hpp>
#include <openvpn/addr/route.hpp>
#include <openvpn/tun/builder/capture.hpp>
#include <openvpn/tun/linux/tun.hpp>
#include <openvpn/tun/client/tunbase.hpp>
#include <openvpn/tun/client/tunprop.hpp>
#include <openvpn/asio/asioerr.hpp>
#include <openvpn/common/cleanup.hpp>
#include <openvpn/common/scoped_fd.hpp>
#include <openvpn/tun/builder/setup.hpp>
#include <openvpn/tun/tunio.hpp>
#include <openvpn/tun/persist/tunpersist.hpp>
#include <openvpn/tun/linux/client/tunsetup.hpp>
namespace openvpn {
namespace TunLinux {
OPENVPN_EXCEPTION(tun_linux_error);
enum { // add_del_route flags
R_IPv6=(1<<0),
R_ADD_SYS=(1<<1),
R_ADD_DCO=(1<<2),
R_ADD_ALL=R_ADD_SYS|R_ADD_DCO,
struct PacketFrom
{
typedef std::unique_ptr<PacketFrom> SPtr;
BufferAllocated buf;
};
inline IP::Addr cvt_pnr_ip_v4(const std::string& hexaddr)
template <typename ReadHandler>
class Tun : public TunIO<ReadHandler, PacketFrom, openvpn_io::posix::stream_descriptor>
{
BufferAllocated v(4, BufferAllocated::CONSTRUCT_ZERO);
parse_hex(v, hexaddr);
if (v.size() != 4)
throw tun_linux_error("bad hex address");
IPv4::Addr ret = IPv4::Addr::from_bytes(v.data());
return IP::Addr::from_ipv4(ret);
}
typedef TunIO<ReadHandler, PacketFrom, openvpn_io::posix::stream_descriptor> Base;
inline IP::Addr get_default_gateway_v4()
{
typedef std::vector<std::string> strvec;
const std::string proc_net_route = read_text_simple("/proc/net/route");
SplitLines in(proc_net_route, 0);
while (in(true))
{
const std::string& line = in.line_ref();
strvec v = Split::by_space<strvec, StandardLex, SpaceMatch, Split::NullLimit>(line);
if (v.size() >= 8)
{
if (v[1] == "00000000" && v[7] == "00000000")
{
const IP::Addr gw = cvt_pnr_ip_v4(v[2]);
return gw;
}
}
}
throw tun_linux_error("can't determine default gateway");
}
public:
typedef RCPtr<Tun> Ptr;
inline void add_del_route(const std::string& addr_str,
const int prefix_len,
const std::string& gateway_str,
const unsigned int flags,
std::vector<IP::Route>* rtvec,
Action::Ptr& create,
Action::Ptr& destroy)
{
if (flags & R_IPv6)
{
const IPv6::Addr addr = IPv6::Addr::from_string(addr_str);
const IPv6::Addr netmask = IPv6::Addr::netmask_from_prefix_len(prefix_len);
const IPv6::Addr net = addr & netmask;
if (flags & R_ADD_SYS)
{
// ip route add 2001:db8:1::/48 via 2001:db8:1::1
Command::Ptr add(new Command);
add->argv.push_back("/sbin/ip");
add->argv.push_back("-6");
add->argv.push_back("route");
add->argv.push_back("add");
add->argv.push_back(net.to_string() + '/' + openvpn::to_string(prefix_len));
add->argv.push_back("via");
add->argv.push_back(gateway_str);
create = add;
// for the destroy command, copy the add command but replace "add" with "delete"
Command::Ptr del(add->copy());
del->argv[3] = "del";
destroy = del;
}
if (rtvec && (flags & R_ADD_DCO))
rtvec->emplace_back(IP::Addr::from_ipv6(net), prefix_len);
}
else
{
const IPv4::Addr addr = IPv4::Addr::from_string(addr_str);
const IPv4::Addr netmask = IPv4::Addr::netmask_from_prefix_len(prefix_len);
const IPv4::Addr net = addr & netmask;
if (flags & R_ADD_SYS)
{
// ip route add 192.0.2.128/25 via 192.0.2.1
Command::Ptr add(new Command);
add->argv.push_back("/sbin/ip");
add->argv.push_back("-4");
add->argv.push_back("route");
add->argv.push_back("add");
add->argv.push_back(net.to_string() + '/' + openvpn::to_string(prefix_len));
add->argv.push_back("via");
add->argv.push_back(gateway_str);
create = add;
// for the destroy command, copy the add command but replace "add" with "delete"
Command::Ptr del(add->copy());
del->argv[3] = "del";
destroy = del;
}
if (rtvec && (flags & R_ADD_DCO))
rtvec->emplace_back(IP::Addr::from_ipv4(net), prefix_len);
}
}
inline void add_del_route(const std::string& addr_str,
const int prefix_len,
const std::string& gateway_str,
const unsigned int flags,
std::vector<IP::Route>* rtvec,
ActionList& create,
ActionList& destroy)
{
Action::Ptr c, d;
add_del_route(addr_str, prefix_len, gateway_str, flags, rtvec, c, d);
create.add(c);
destroy.add(d);
}
inline void iface_up(const std::string& iface_name,
const int mtu,
ActionList& create,
ActionList& destroy)
{
Tun(openvpn_io::io_context& io_context,
ReadHandler read_handler_arg,
const Frame::Ptr& frame_arg,
const SessionStats::Ptr& stats_arg,
const int socket,
const std::string& name)
: Base(read_handler_arg, frame_arg, stats_arg)
{
Command::Ptr add(new Command);
add->argv.push_back("/sbin/ip");
add->argv.push_back("link");
add->argv.push_back("set");
add->argv.push_back(iface_name);
add->argv.push_back("up");
if (mtu > 0)
{
add->argv.push_back("mtu");
add->argv.push_back(openvpn::to_string(mtu));
}
create.add(add);
// for the destroy command, copy the add command but replace "up" with "down"
Command::Ptr del(add->copy());
del->argv[4] = "down";
destroy.add(del);
}
}
inline void iface_config(const std::string& iface_name,
int unit,
const TunBuilderCapture& pull,
std::vector<IP::Route>* rtvec,
ActionList& create,
ActionList& destroy)
{
// set local4 and local6 to point to IPv4/6 route configurations
const TunBuilderCapture::RouteAddress* local4 = pull.vpn_ipv4();
const TunBuilderCapture::RouteAddress* local6 = pull.vpn_ipv6();
// Set IPv4 Interface
if (local4)
{
Command::Ptr add(new Command);
add->argv.push_back("/sbin/ip");
add->argv.push_back("-4");
add->argv.push_back("addr");
add->argv.push_back("add");
add->argv.push_back(local4->address + '/' + openvpn::to_string(local4->prefix_length));
add->argv.push_back("broadcast");
add->argv.push_back((IPv4::Addr::from_string(local4->address) | ~IPv4::Addr::netmask_from_prefix_len(local4->prefix_length)).to_string());
add->argv.push_back("dev");
add->argv.push_back(iface_name);
if (unit >= 0)
{
add->argv.push_back("label");
add->argv.push_back(iface_name + ':' + openvpn::to_string(unit));
}
create.add(add);
// for the destroy command, copy the add command but replace "add" with "delete"
Command::Ptr del(add->copy());
del->argv[3] = "del";
destroy.add(del);
// add interface route to rtvec if defined
add_del_route(local4->address, local4->prefix_length, local4->address, R_ADD_DCO, rtvec, create, destroy);
}
// Set IPv6 Interface
if (local6 && !pull.block_ipv6)
{
Command::Ptr add(new Command);
add->argv.push_back("/sbin/ip");
add->argv.push_back("-6");
add->argv.push_back("addr");
add->argv.push_back("add");
add->argv.push_back(local6->address + '/' + openvpn::to_string(local6->prefix_length));
add->argv.push_back("dev");
add->argv.push_back(iface_name);
create.add(add);
// for the destroy command, copy the add command but replace "add" with "delete"
Command::Ptr del(add->copy());
del->argv[3] = "del";
destroy.add(del);
// add interface route to rtvec if defined
add_del_route(local6->address, local6->prefix_length, local6->address, R_ADD_DCO|R_IPv6, rtvec, create, destroy);
}
}
inline void tun_config(const std::string& iface_name,
const TunBuilderCapture& pull,
std::vector<IP::Route>* rtvec,
ActionList& create,
ActionList& destroy)
{
const IP::Addr gw4 = get_default_gateway_v4();
// set local4 and local6 to point to IPv4/6 route configurations
const TunBuilderCapture::RouteAddress* local4 = pull.vpn_ipv4();
const TunBuilderCapture::RouteAddress* local6 = pull.vpn_ipv6();
// configure interface
iface_up(iface_name, pull.mtu, create, destroy);
iface_config(iface_name, -1, pull, rtvec, create, destroy);
// Process Routes
{
for (const auto &route : pull.add_routes)
{
if (route.ipv6)
{
if (!pull.block_ipv6)
add_del_route(route.address, route.prefix_length, local6->gateway, R_ADD_ALL|R_IPv6, rtvec, create, destroy);
}
else
{
if (local4 && !local4->gateway.empty())
add_del_route(route.address, route.prefix_length, local4->gateway, R_ADD_ALL, rtvec, create, destroy);
else
OPENVPN_LOG("ERROR: IPv4 route pushed without IPv4 ifconfig and/or route-gateway");
}
}
Base::name_ = name;
Base::retain_stream = true;
Base::stream = new openvpn_io::posix::stream_descriptor(io_context, socket);
OPENVPN_LOG_TUN(Base::name_ << " opened");
}
// Process exclude routes
{
for (const auto &route : pull.exclude_routes)
{
if (route.ipv6)
{
OPENVPN_LOG("NOTE: exclude IPv6 routes not supported yet"); // fixme
}
else
{
if (gw4.defined())
add_del_route(route.address, route.prefix_length, gw4.to_string(), R_ADD_SYS, rtvec, create, destroy);
else
OPENVPN_LOG("NOTE: cannot determine gateway for exclude IPv4 routes");
}
}
}
~Tun() { Base::stop(); }
};
// Process IPv4 redirect-gateway
if (pull.reroute_gw.ipv4)
{
// add bypass route
if (!pull.remote_address.ipv6 && !(pull.reroute_gw.flags & RedirectGatewayFlags::RG_LOCAL))
add_del_route(pull.remote_address.address, 32, gw4.to_string(), R_ADD_SYS, rtvec, create, destroy);
add_del_route("0.0.0.0", 1, local4->gateway, R_ADD_ALL, rtvec, create, destroy);
add_del_route("128.0.0.0", 1, local4->gateway, R_ADD_ALL, rtvec, create, destroy);
}
// Process IPv6 redirect-gateway
if (pull.reroute_gw.ipv6 && !pull.block_ipv6)
{
add_del_route("0000::", 1, local6->gateway, R_ADD_ALL|R_IPv6, rtvec, create, destroy);
add_del_route("8000::", 1, local6->gateway, R_ADD_ALL|R_IPv6, rtvec, create, destroy);
}
// fixme -- Process block-ipv6
// fixme -- Handle pushed DNS servers
}
typedef TunPersistTemplate<ScopedFD> TunPersist;
class ClientConfig : public TunClientFactory
{
@@ -340,6 +82,9 @@ namespace openvpn {
Frame::Ptr frame;
SessionStats::Ptr stats;
TunBuilderSetup::Factory::Ptr tun_setup_factory;
TunPersist::Ptr tun_persist;
void load(const OptionList& opt)
{
// set a default MTU
@@ -363,6 +108,15 @@ namespace openvpn {
virtual TunClient::Ptr new_tun_client_obj(openvpn_io::io_context& io_context,
TunClientParent& parent,
TransportClient* transcli);
TunBuilderSetup::Base::Ptr new_setup_obj()
{
if (tun_setup_factory)
return tun_setup_factory->new_setup_obj();
else
return new TunLinux::Setup();
}
private:
ClientConfig() {}
};
@@ -380,54 +134,94 @@ namespace openvpn {
if (!impl)
{
halt = false;
if (config->tun_persist)
{
OPENVPN_LOG("TunPersist: long-term session scope");
tun_persist = config->tun_persist; // long-term persistent
}
else
{
OPENVPN_LOG("TunPersist: short-term connection scope");
tun_persist.reset(new TunPersist(true, false, nullptr)); // short-term
}
try {
const IP::Addr server_addr = transcli.server_endpoint_addr();
// notify parent
parent.tun_pre_tun_config();
int sd = -1;
// parse pushed options
TunBuilderCapture::Ptr po(new TunBuilderCapture());
TunProp::configure_builder(po.get(),
state.get(),
config->stats.get(),
server_addr,
config->tun_prop,
opt,
nullptr,
false);
// Check if persisted tun session matches properties of to-be-created session
if (tun_persist->use_persisted_tun(server_addr, config->tun_prop, opt))
{
state = tun_persist->state();
sd = tun_persist->obj();
state = tun_persist->state();
OPENVPN_LOG("TunPersist: reused tun context");
}
else
{
// notify parent
parent.tun_pre_tun_config();
OPENVPN_LOG("CAPTURED OPTIONS:" << std::endl << po->to_string());
// close old tun handle if persisted
tun_persist->close();
// configure tun/tap interface properties
ActionList::Ptr add_cmds = new ActionList();
remove_cmds.reset(new ActionList());
// parse pushed options
TunBuilderCapture::Ptr po(new TunBuilderCapture());
TunProp::configure_builder(po.get(),
state.get(),
config->stats.get(),
server_addr,
config->tun_prop,
opt,
nullptr,
false);
OPENVPN_LOG("CAPTURED OPTIONS:" << std::endl << po->to_string());
// create new tun setup object
tun_setup = config->new_setup_obj();
// create config object for tun setup layer
Setup::Config tsconf;
tsconf.layer = config->tun_prop.layer;
tsconf.dev_name = config->dev_name;
tsconf.txqueuelen = config->txqueuelen;
// open/config tun
{
std::ostringstream os;
auto os_print = Cleanup([&os](){ OPENVPN_LOG_STRING(os.str()); });
sd = tun_setup->establish(*po, &tsconf, nullptr, os);
}
// persist tun settings state
state->iface_name = tsconf.iface_name;
tun_persist->persist_tun_state(sd, state);
// enable tun_setup destructor
tun_persist->add_destructor(tun_setup);
}
// start tun
impl.reset(new TunImpl(io_context,
this,
config->frame,
config->stats,
config->dev_name,
config->tun_prop.layer,
config->txqueuelen
sd,
state->iface_name
));
impl->start(config->n_parallel);
// get the iface name
state->iface_name = impl->name();
// configure tun properties
TunLinux::tun_config(state->iface_name, *po, nullptr, *add_cmds, *remove_cmds);
// execute commands to bring up interface
add_cmds->execute(std::cout);
// signal that we are connected
parent.tun_connected();
}
catch (const std::exception& e)
{
if (tun_persist)
tun_persist->close();
stop();
parent.tun_error(Error::TUN_SETUP_FAILED, e.what());
}
@@ -522,22 +316,21 @@ namespace openvpn {
{
halt = true;
// remove added routes
if (remove_cmds)
remove_cmds->execute(std::cout);
// stop tun
if (impl)
impl->stop();
tun_persist.reset();
}
}
openvpn_io::io_context& io_context;
TunPersist::Ptr tun_persist;
ClientConfig::Ptr config;
TunClientParent& parent;
TunImpl::Ptr impl;
TunProp::State::Ptr state;
ActionList::Ptr remove_cmds;
TunBuilderSetup::Base::Ptr tun_setup;
bool halt;
};

View File

@@ -0,0 +1,473 @@
// OpenVPN -- An application to securely tunnel IP networks
// over a single port, with support for SSL/TLS-based
// session authentication and key exchange,
// packet encryption, packet authentication, and
// packet compression.
//
// Copyright (C) 2012-2017 OpenVPN Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License Version 3
// 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program in the COPYING file.
// If not, see <http://www.gnu.org/licenses/>.
// Client tun interface for Linux.
#ifndef OPENVPN_TUN_LINUX_CLIENT_TUNSETUP_H
#define OPENVPN_TUN_LINUX_CLIENT_TUNSETUP_H
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <net/if.h>
#include <linux/if_tun.h>
#include <openvpn/common/exception.hpp>
#include <openvpn/common/file.hpp>
#include <openvpn/common/split.hpp>
#include <openvpn/common/splitlines.hpp>
#include <openvpn/common/hexstr.hpp>
#include <openvpn/common/to_string.hpp>
#include <openvpn/common/process.hpp>
#include <openvpn/common/action.hpp>
#include <openvpn/addr/route.hpp>
#include <openvpn/tun/builder/capture.hpp>
#include <openvpn/tun/builder/setup.hpp>
#include <openvpn/tun/client/tunbase.hpp>
#include <openvpn/tun/client/tunprop.hpp>
#include <openvpn/netconf/linux/gw.hpp>
namespace openvpn {
namespace TunLinux {
OPENVPN_EXCEPTION(tun_linux_error);
OPENVPN_EXCEPTION(tun_open_error);
OPENVPN_EXCEPTION(tun_layer_error);
OPENVPN_EXCEPTION(tun_ioctl_error);
OPENVPN_EXCEPTION(tun_fcntl_error);
OPENVPN_EXCEPTION(tun_name_error);
OPENVPN_EXCEPTION(tun_tx_queue_len_error);
OPENVPN_EXCEPTION(tun_ifconfig_error);
enum { // add_del_route flags
R_IPv6=(1<<0),
R_ADD_SYS=(1<<1),
R_ADD_DCO=(1<<2),
R_ADD_ALL=R_ADD_SYS|R_ADD_DCO,
};
inline IP::Addr cvt_pnr_ip_v4(const std::string& hexaddr)
{
BufferAllocated v(4, BufferAllocated::CONSTRUCT_ZERO);
parse_hex(v, hexaddr);
if (v.size() != 4)
throw tun_linux_error("bad hex address");
IPv4::Addr ret = IPv4::Addr::from_bytes(v.data());
return IP::Addr::from_ipv4(ret);
}
inline void add_del_route(const std::string& addr_str,
const int prefix_len,
const std::string& gateway_str,
const std::string& dev,
const unsigned int flags,
std::vector<IP::Route>* rtvec,
Action::Ptr& create,
Action::Ptr& destroy)
{
if (flags & R_IPv6)
{
const IPv6::Addr addr = IPv6::Addr::from_string(addr_str);
const IPv6::Addr netmask = IPv6::Addr::netmask_from_prefix_len(prefix_len);
const IPv6::Addr net = addr & netmask;
if (flags & R_ADD_SYS)
{
// ip route add 2001:db8:1::/48 via 2001:db8:1::1
Command::Ptr add(new Command);
add->argv.push_back("/sbin/ip");
add->argv.push_back("-6");
add->argv.push_back("route");
add->argv.push_back("add");
add->argv.push_back(net.to_string() + '/' + openvpn::to_string(prefix_len));
add->argv.push_back("via");
add->argv.push_back(gateway_str);
if (!dev.empty())
{
add->argv.push_back("dev");
add->argv.push_back(dev);
}
create = add;
// for the destroy command, copy the add command but replace "add" with "delete"
Command::Ptr del(add->copy());
del->argv[3] = "del";
destroy = del;
}
if (rtvec && (flags & R_ADD_DCO))
rtvec->emplace_back(IP::Addr::from_ipv6(net), prefix_len);
}
else
{
const IPv4::Addr addr = IPv4::Addr::from_string(addr_str);
const IPv4::Addr netmask = IPv4::Addr::netmask_from_prefix_len(prefix_len);
const IPv4::Addr net = addr & netmask;
if (flags & R_ADD_SYS)
{
// ip route add 192.0.2.128/25 via 192.0.2.1
Command::Ptr add(new Command);
add->argv.push_back("/sbin/ip");
add->argv.push_back("-4");
add->argv.push_back("route");
add->argv.push_back("add");
add->argv.push_back(net.to_string() + '/' + openvpn::to_string(prefix_len));
add->argv.push_back("via");
add->argv.push_back(gateway_str);
create = add;
// for the destroy command, copy the add command but replace "add" with "delete"
Command::Ptr del(add->copy());
del->argv[3] = "del";
destroy = del;
}
if (rtvec && (flags & R_ADD_DCO))
rtvec->emplace_back(IP::Addr::from_ipv4(net), prefix_len);
}
}
inline void add_del_route(const std::string& addr_str,
const int prefix_len,
const std::string& gateway_str,
const std::string& dev,
const unsigned int flags,// add interface route to rtvec if defined
std::vector<IP::Route>* rtvec,
ActionList& create,
ActionList& destroy)
{
Action::Ptr c, d;
add_del_route(addr_str, prefix_len, gateway_str, dev, flags, rtvec, c, d);
create.add(c);
destroy.add(d);
}
inline void iface_up(const std::string& iface_name,
const int mtu,
ActionList& create,
ActionList& destroy)
{
{
Command::Ptr add(new Command);
add->argv.push_back("/sbin/ip");
add->argv.push_back("link");
add->argv.push_back("set");
add->argv.push_back(iface_name);
add->argv.push_back("up");
if (mtu > 0)
{
add->argv.push_back("mtu");
add->argv.push_back(openvpn::to_string(mtu));
}
create.add(add);
// for the destroy command, copy the add command but replace "up" with "down"
Command::Ptr del(add->copy());
del->argv[4] = "down";
destroy.add(del);
}
}
inline void iface_config(const std::string& iface_name,
int unit,
const TunBuilderCapture& pull,
std::vector<IP::Route>* rtvec,
ActionList& create,
ActionList& destroy)
{
// set local4 and local6 to point to IPv4/6 route configurations
const TunBuilderCapture::RouteAddress* local4 = pull.vpn_ipv4();
const TunBuilderCapture::RouteAddress* local6 = pull.vpn_ipv6();
// Set IPv4 Interface
if (local4)
{
Command::Ptr add(new Command);
add->argv.push_back("/sbin/ip");
add->argv.push_back("-4");
add->argv.push_back("addr");
add->argv.push_back("add");
add->argv.push_back(local4->address + '/' + openvpn::to_string(local4->prefix_length));
add->argv.push_back("broadcast");
add->argv.push_back((IPv4::Addr::from_string(local4->address) | ~IPv4::Addr::netmask_from_prefix_len(local4->prefix_length)).to_string());
add->argv.push_back("dev");
add->argv.push_back(iface_name);
if (unit >= 0)
{
add->argv.push_back("label");
add->argv.push_back(iface_name + ':' + openvpn::to_string(unit));
}
create.add(add);
// for the destroy command, copy the add command but replace "add" with "delete"
Command::Ptr del(add->copy());
del->argv[3] = "del";
destroy.add(del);
// add interface route to rtvec if defined
add_del_route(local4->address, local4->prefix_length, local4->address, iface_name, R_ADD_DCO, rtvec, create, destroy);
}
// Set IPv6 Interface
if (local6 && !pull.block_ipv6)
{
Command::Ptr add(new Command);
add->argv.push_back("/sbin/ip");
add->argv.push_back("-6");
add->argv.push_back("addr");
add->argv.push_back("add");
add->argv.push_back(local6->address + '/' + openvpn::to_string(local6->prefix_length));
add->argv.push_back("dev");
add->argv.push_back(iface_name);
create.add(add);
// for the destroy command, copy the add command but replace "add" with "delete"
Command::Ptr del(add->copy());
del->argv[3] = "del";
destroy.add(del);
// add interface route to rtvec if defined
add_del_route(local6->address, local6->prefix_length, local6->address, iface_name, R_ADD_DCO|R_IPv6, rtvec, create, destroy);
}
}
inline void tun_config(const std::string& iface_name,
const TunBuilderCapture& pull,
std::vector<IP::Route>* rtvec,
ActionList& create,
ActionList& destroy)
{
const LinuxGW46 gw(true);
// set local4 and local6 to point to IPv4/6 route configurations
const TunBuilderCapture::RouteAddress* local4 = pull.vpn_ipv4();
const TunBuilderCapture::RouteAddress* local6 = pull.vpn_ipv6();
// configure interface
iface_up(iface_name, pull.mtu, create, destroy);
iface_config(iface_name, -1, pull, rtvec, create, destroy);
// Process Routes
{
for (const auto &route : pull.add_routes)
{
if (route.ipv6)
{
if (!pull.block_ipv6)
add_del_route(route.address, route.prefix_length, local6->gateway, iface_name, R_ADD_ALL|R_IPv6, rtvec, create, destroy);
}
else
{
if (local4 && !local4->gateway.empty())
add_del_route(route.address, route.prefix_length, local4->gateway, iface_name, R_ADD_ALL, rtvec, create, destroy);
else
OPENVPN_LOG("ERROR: IPv4 route pushed without IPv4 ifconfig and/or route-gateway");
}
}
}
// Process exclude routes
{
for (const auto &route : pull.exclude_routes)
{
if (route.ipv6)
{
OPENVPN_LOG("NOTE: exclude IPv6 routes not supported yet"); // fixme
}
else
{
if (gw.v4.defined())
add_del_route(route.address, route.prefix_length, gw.v4.addr().to_string(), gw.v4.dev(), R_ADD_SYS, rtvec, create, destroy);
else
OPENVPN_LOG("NOTE: cannot determine gateway for exclude IPv4 routes");
}
}
}
// Process IPv4 redirect-gateway
if (pull.reroute_gw.ipv4)
{
// add bypass route
if (!pull.remote_address.ipv6 && !(pull.reroute_gw.flags & RedirectGatewayFlags::RG_LOCAL))
add_del_route(pull.remote_address.address, 32, gw.v4.addr().to_string(), gw.v4.dev(), R_ADD_SYS, rtvec, create, destroy);
add_del_route("0.0.0.0", 1, local4->gateway, iface_name, R_ADD_ALL, rtvec, create, destroy);
add_del_route("128.0.0.0", 1, local4->gateway, iface_name, R_ADD_ALL, rtvec, create, destroy);
}
// Process IPv6 redirect-gateway
if (pull.reroute_gw.ipv6 && !pull.block_ipv6)
{
// add bypass route
if (pull.remote_address.ipv6 && !(pull.reroute_gw.flags & RedirectGatewayFlags::RG_LOCAL))
add_del_route(pull.remote_address.address, 128, gw.v6.addr().to_string(), gw.v6.dev(), R_ADD_SYS|R_IPv6, rtvec, create, destroy);
add_del_route("0000::", 1, local6->gateway, iface_name, R_ADD_ALL|R_IPv6, rtvec, create, destroy);
add_del_route("8000::", 1, local6->gateway, iface_name, R_ADD_ALL|R_IPv6, rtvec, create, destroy);
}
// fixme -- Process block-ipv6
// fixme -- Handle pushed DNS servers
}
class Setup : public TunBuilderSetup::Base
{
public:
typedef RCPtr<Setup> Ptr;
struct Config : public TunBuilderSetup::Config
{
std::string iface_name;
Layer layer; // OSI layer
std::string dev_name;
int txqueuelen;
#ifdef HAVE_JSON
virtual Json::Value to_json() override
{
Json::Value root(Json::objectValue);
root["iface_name"] = Json::Value(iface_name);
root["layer"] = Json::Value(layer.str());
root["dev_name"] = Json::Value(dev_name);
root["txqueuelen"] = Json::Value(txqueuelen);
return root;
};
virtual void from_json(const Json::Value& root, const std::string& title) override
{
json::assert_dict(root, title);
json::to_string(root, iface_name, "iface_name", title);
layer = Layer::from_str(json::get_string(root, "layer", title));
json::to_string(root, dev_name, "dev_name", title);
json::to_int(root, txqueuelen, "txqueuelen", title);
}
#endif
};
virtual void destroy(std::ostream &os)
{
// remove added routes
if (remove_cmds)
remove_cmds->execute(std::cout);
}
virtual int establish(const TunBuilderCapture& pull, // defined by TunBuilderSetup::Base
TunBuilderSetup::Config* config,
Stop* stop,
std::ostream& os) override
{
// get configuration
Config *conf = dynamic_cast<Config *>(config);
if (!conf)
throw tun_linux_error("missing config");
static const char node[] = "/dev/net/tun";
ScopedFD fd(open(node, O_RDWR));
if (!fd.defined())
OPENVPN_THROW(tun_open_error, "error opening tun device " << node << ": " << errinfo(errno));
struct ifreq ifr;
std::memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_ONE_QUEUE;
ifr.ifr_flags |= IFF_NO_PI;
if (conf->layer() == Layer::OSI_LAYER_3)
ifr.ifr_flags |= IFF_TUN;
else if (conf->layer() == Layer::OSI_LAYER_2)
ifr.ifr_flags |= IFF_TAP;
else
throw tun_layer_error("unknown OSI layer");
open_unit(conf->dev_name, ifr, fd);
if (fcntl (fd(), F_SETFL, O_NONBLOCK) < 0)
throw tun_fcntl_error(errinfo(errno));
// Set the TX send queue size
if (conf->txqueuelen)
{
struct ifreq netifr;
ScopedFD ctl_fd(socket (AF_INET, SOCK_DGRAM, 0));
if (ctl_fd.defined())
{
std::memset(&netifr, 0, sizeof(netifr));
strcpy (netifr.ifr_name, ifr.ifr_name);
netifr.ifr_qlen = conf->txqueuelen;
if (ioctl (ctl_fd(), SIOCSIFTXQLEN, (void *) &netifr) < 0)
throw tun_tx_queue_len_error(errinfo(errno));
}
else
throw tun_tx_queue_len_error(errinfo(errno));
}
conf->iface_name = ifr.ifr_name;
ActionList::Ptr add_cmds = new ActionList();
remove_cmds.reset(new ActionListReversed()); // remove commands executed in reversed order
// configure tun properties
tun_config(ifr.ifr_name, pull, nullptr, *add_cmds, *remove_cmds);
// execute commands to bring up interface
add_cmds->execute(std::cout);
return fd.release();
}
private:
void open_unit(const std::string& name, struct ifreq& ifr, ScopedFD& fd)
{
if (!name.empty())
{
const int max_units = 256;
for (int unit = 0; unit < max_units; ++unit)
{
std::string n = name;
if (unit)
n += openvpn::to_string(unit);
if (n.length() < IFNAMSIZ)
::strcpy (ifr.ifr_name, n.c_str());
else
throw tun_name_error();
if (ioctl (fd(), TUNSETIFF, (void *) &ifr) == 0)
return;
}
const int eno = errno;
OPENVPN_THROW(tun_ioctl_error, "failed to open tun device '" << name << "' after trying " << max_units << " units : " << errinfo(eno));
}
else
{
if (ioctl (fd(), TUNSETIFF, (void *) &ifr) < 0)
{
const int eno = errno;
OPENVPN_THROW(tun_ioctl_error, "failed to open tun device '" << name << "' : " << errinfo(eno));
}
}
}
ActionListReversed::Ptr remove_cmds;
};
}
} // namespace openvpn
#endif // OPENVPN_TUN_LINUX_CLIENT_TUNCLI_H

View File

@@ -1,162 +0,0 @@
// OpenVPN -- An application to securely tunnel IP networks
// over a single port, with support for SSL/TLS-based
// session authentication and key exchange,
// packet encryption, packet authentication, and
// packet compression.
//
// Copyright (C) 2012-2017 OpenVPN Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License Version 3
// 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program in the COPYING file.
// If not, see <http://www.gnu.org/licenses/>.
// Low-level tun interface driver for Linux, client/server independent.
#ifndef OPENVPN_TUN_LINUX_TUN_H
#define OPENVPN_TUN_LINUX_TUN_H
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <net/if.h>
#include <linux/if_tun.h>
#include <string>
#include <sstream>
#include <memory>
#include <openvpn/asio/asioerr.hpp>
#include <openvpn/common/process.hpp>
#include <openvpn/common/to_string.hpp>
#include <openvpn/common/scoped_fd.hpp>
#include <openvpn/tun/tunio.hpp>
#include <openvpn/tun/layer.hpp>
#include <openvpn/log/sessionstats.hpp>
#include <openvpn/frame/frame.hpp>
namespace openvpn {
namespace TunLinux {
struct PacketFrom
{
typedef std::unique_ptr<PacketFrom> SPtr;
BufferAllocated buf;
};
// exceptions
OPENVPN_EXCEPTION(tun_open_error);
OPENVPN_EXCEPTION(tun_layer_error);
OPENVPN_EXCEPTION(tun_ioctl_error);
OPENVPN_EXCEPTION(tun_fcntl_error);
OPENVPN_EXCEPTION(tun_name_error);
OPENVPN_EXCEPTION(tun_tx_queue_len_error);
OPENVPN_EXCEPTION(tun_ifconfig_error);
template <typename ReadHandler>
class Tun : public TunIO<ReadHandler, PacketFrom, openvpn_io::posix::stream_descriptor>
{
typedef TunIO<ReadHandler, PacketFrom, openvpn_io::posix::stream_descriptor> Base;
public:
typedef RCPtr<Tun> Ptr;
Tun(openvpn_io::io_context& io_context,
ReadHandler read_handler_arg,
const Frame::Ptr& frame_arg,
const SessionStats::Ptr& stats_arg,
const std::string& name,
const Layer& layer,
const int txqueuelen)
: Base(read_handler_arg, frame_arg, stats_arg)
{
static const char node[] = "/dev/net/tun";
ScopedFD fd(open(node, O_RDWR));
if (!fd.defined())
OPENVPN_THROW(tun_open_error, "error opening tun device " << node << ": " << errinfo(errno));
struct ifreq ifr;
std::memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_ONE_QUEUE;
ifr.ifr_flags |= IFF_NO_PI;
if (layer() == Layer::OSI_LAYER_3)
ifr.ifr_flags |= IFF_TUN;
else if (layer() == Layer::OSI_LAYER_2)
ifr.ifr_flags |= IFF_TAP;
else
throw tun_layer_error("unknown OSI layer");
open_unit(name, ifr, fd);
if (fcntl (fd(), F_SETFL, O_NONBLOCK) < 0)
throw tun_fcntl_error(errinfo(errno));
// Set the TX send queue size
if (txqueuelen)
{
struct ifreq netifr;
ScopedFD ctl_fd(socket (AF_INET, SOCK_DGRAM, 0));
if (ctl_fd.defined())
{
std::memset(&netifr, 0, sizeof(netifr));
strcpy (netifr.ifr_name, ifr.ifr_name);
netifr.ifr_qlen = txqueuelen;
if (ioctl (ctl_fd(), SIOCSIFTXQLEN, (void *) &netifr) < 0)
throw tun_tx_queue_len_error(errinfo(errno));
}
else
throw tun_tx_queue_len_error(errinfo(errno));
}
Base::name_ = ifr.ifr_name;
Base::stream = new openvpn_io::posix::stream_descriptor(io_context, fd.release());
OPENVPN_LOG_TUN(Base::name_ << " opened");
}
~Tun() { Base::stop(); }
private:
static void open_unit(const std::string& name, struct ifreq& ifr, ScopedFD& fd)
{
if (!name.empty())
{
const int max_units = 256;
for (int unit = 0; unit < max_units; ++unit)
{
std::string n = name;
if (unit)
n += openvpn::to_string(unit);
if (n.length() < IFNAMSIZ)
::strcpy (ifr.ifr_name, n.c_str());
else
throw tun_name_error();
if (ioctl (fd(), TUNSETIFF, (void *) &ifr) == 0)
return;
}
const int eno = errno;
OPENVPN_THROW(tun_ioctl_error, "failed to open tun device '" << name << "' after trying " << max_units << " units : " << errinfo(eno));
}
else
{
if (ioctl (fd(), TUNSETIFF, (void *) &ifr) < 0)
{
const int eno = errno;
OPENVPN_THROW(tun_ioctl_error, "failed to open tun device '" << name << "' : " << errinfo(eno));
}
}
}
};
}
} // namespace openvpn
#endif // OPENVPN_TUN_LINUX_TUN_H

View File

@@ -217,7 +217,7 @@ namespace openvpn {
}
catch (const std::exception& e)
{
OPENVPN_LOG("MacDNS: setdns: " << e.what());
OPENVPN_LOG("MacDNS: setdns exception: " << e.what());
}
return mod;
}
@@ -248,7 +248,7 @@ namespace openvpn {
}
catch (const std::exception& e)
{
OPENVPN_LOG("MacDNS: resetdns: " << e.what());
OPENVPN_LOG("MacDNS: resetdns exception: " << e.what());
}
return mod;
}

View File

@@ -211,7 +211,7 @@ namespace openvpn {
}
catch (const std::exception& e)
{
OPENVPN_LOG("MacDNSWatchdog::thread_func: " << e.what());
OPENVPN_LOG("MacDNSWatchdog::thread_func exception: " << e.what());
}
cancel_push_timer();
}
@@ -272,7 +272,7 @@ namespace openvpn {
}
catch (const std::exception& e)
{
OPENVPN_LOG("MacDNSWatchdog::push_timer_callback: " << e.what());
OPENVPN_LOG("MacDNSWatchdog::push_timer_callback exception: " << e.what());
}
}

View File

@@ -94,7 +94,7 @@ namespace openvpn {
}
catch (const std::exception& e)
{
OPENVPN_LOG("*** TUN BUILDER CAPTURE ERROR: " << e.what());
OPENVPN_LOG("*** TUN BUILDER CAPTURE exception: " << e.what());
}
}
#endif

View File

@@ -83,7 +83,7 @@ namespace openvpn {
}
catch (const std::exception& e)
{
OPENVPN_LOG("TunWrap destructor: " << e.what());
OPENVPN_LOG("TunWrap destructor exception: " << e.what());
}
}

View File

@@ -113,7 +113,7 @@ namespace openvpn {
}
catch (openvpn_io::system_error& e)
{
OPENVPN_LOG_TUN_ERROR("TUN write error: " << e.what());
OPENVPN_LOG_TUN_ERROR("TUN write exception: " << e.what());
tun_error(Error::TUN_WRITE_ERROR, &e.code());
return false;
}
@@ -146,7 +146,7 @@ namespace openvpn {
}
catch (openvpn_io::system_error& e)
{
OPENVPN_LOG_TUN_ERROR("TUN write error: " << e.what());
OPENVPN_LOG_TUN_ERROR("TUN write exception: " << e.what());
tun_error(Error::TUN_WRITE_ERROR, &e.code());
return false;
}
@@ -206,16 +206,15 @@ namespace openvpn {
// queue read on tun device
stream->async_read_some(frame_context.mutable_buffer(tunfrom->buf),
[self=Ptr(this), tunfrom](const openvpn_io::error_code& error, const size_t bytes_recvd)
[self=Ptr(this), tunfrom=typename PacketFrom::SPtr(tunfrom)](const openvpn_io::error_code& error, const size_t bytes_recvd) mutable
{
self->handle_read(tunfrom, error, bytes_recvd);
self->handle_read(std::move(tunfrom), error, bytes_recvd);
});
}
void handle_read(PacketFrom *tunfrom, const openvpn_io::error_code& error, const size_t bytes_recvd)
void handle_read(typename PacketFrom::SPtr pfp, const openvpn_io::error_code& error, const size_t bytes_recvd)
{
OPENVPN_LOG_TUN_VERBOSE("TunIO::handle_read: " << error.message());
typename PacketFrom::SPtr pfp(tunfrom);
if (!halt)
{
if (!error)

View File

@@ -68,6 +68,10 @@
#include <openvpn/ssl/peerinfo.hpp>
#include <openvpn/ssl/sslchoose.hpp>
#ifdef OPENVPN_REMOTE_OVERRIDE
#include <openvpn/common/process.hpp>
#endif
#if defined(USE_MBEDTLS)
#include <openvpn/mbedtls/util/pkcs1.hpp>
#endif
@@ -129,6 +133,13 @@ public:
}
}
#ifdef OPENVPN_REMOTE_OVERRIDE
void set_remote_override_cmd(const std::string& cmd)
{
remote_override_cmd = cmd;
}
#endif
private:
virtual bool socket_protect(int socket) override
{
@@ -304,10 +315,51 @@ private:
return false;
}
#ifdef OPENVPN_REMOTE_OVERRIDE
virtual bool remote_override_enabled() override
{
return !remote_override_cmd.empty();
}
virtual void remote_override(ClientAPI::RemoteOverride& ro)
{
RedirectPipe::InOut pio;
Argv argv;
argv.emplace_back(remote_override_cmd);
OPENVPN_LOG(argv.to_string());
const int status = system_cmd(remote_override_cmd,
argv,
nullptr,
pio,
RedirectPipe::IGNORE_ERR);
if (!status)
{
const std::string out = string::first_line(pio.out);
OPENVPN_LOG("REMOTE OVERRIDE: " << out);
auto svec = string::split(out, ',');
if (svec.size() == 4)
{
ro.host = svec[0];
ro.ip = svec[1];
ro.port = svec[2];
ro.proto = svec[3];
}
else
ro.error = "cannot parse remote-override, expecting host,ip,port,proto (at least one or both of host and ip must be defined)";
}
else
ro.error = "status=" + std::to_string(status);
}
#endif
std::mutex log_mutex;
std::string dc_cookie;
RandomAPI::Ptr rng; // random data source for epki
volatile ClockTickAction clock_tick_action = CT_UNDEF;
#ifdef OPENVPN_REMOTE_OVERRIDE
std::string remote_override_cmd;
#endif
};
static Client *the_client = nullptr; // GLOBAL
@@ -543,11 +595,15 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content)
{ "merge", no_argument, nullptr, 'm' },
{ "version", no_argument, nullptr, 'v' },
{ "auto-sess", no_argument, nullptr, 'a' },
{ "auth-retry", no_argument, nullptr, 'Y' },
{ "tcprof-override", required_argument, nullptr, 'X' },
{ "ssl-debug", required_argument, nullptr, 1 },
{ "epki-cert", required_argument, nullptr, 2 },
{ "epki-ca", required_argument, nullptr, 3 },
{ "epki-key", required_argument, nullptr, 4 },
#ifdef OPENVPN_REMOTE_OVERRIDE
{ "remote-override",required_argument, nullptr, 5 },
#endif
{ nullptr, 0, nullptr, 0 }
};
@@ -588,6 +644,7 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content)
int sslDebugLevel = 0;
bool googleDnsFallback = false;
bool autologinSessions = false;
bool retryOnAuthFailed = false;
bool tunPersist = false;
bool merge = false;
bool version = false;
@@ -596,10 +653,13 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content)
std::string epki_cert_fn;
std::string epki_ca_fn;
std::string epki_key_fn;
#ifdef OPENVPN_REMOTE_OVERRIDE
std::string remote_override_cmd;
#endif
int ch;
optind = 1;
while ((ch = getopt_long(argc, argv, "BAdeTCxfgjmvau:p:r:D:P:6:s:t:c:z:M:h:q:U:W:I:G:k:X:R:", longopts, nullptr)) != -1)
while ((ch = getopt_long(argc, argv, "BAdeTCxfgjmvaYu:p:r:D:P:6:s:t:c:z:M:h:q:U:W:I:G:k:X:R:", longopts, nullptr)) != -1)
{
switch (ch)
{
@@ -615,6 +675,11 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content)
case 4: // --epki-key
epki_key_fn = optarg;
break;
#ifdef OPENVPN_REMOTE_OVERRIDE
case 5: // --remote-override
remote_override_cmd = optarg;
break;
#endif
case 'e':
eval = true;
break;
@@ -693,6 +758,9 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content)
case 'a':
autologinSessions = true;
break;
case 'Y':
retryOnAuthFailed = true;
break;
case 'j':
tunPersist = true;
break;
@@ -786,6 +854,7 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content)
config.sslDebugLevel = sslDebugLevel;
config.googleDnsFallback = googleDnsFallback;
config.autologinSessions = autologinSessions;
config.retryOnAuthFailed = retryOnAuthFailed;
config.tunPersist = tunPersist;
config.gremlinConfig = gremlin;
config.info = true;
@@ -798,9 +867,25 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content)
PeerInfo::Set::parse_csv(peer_info, config.peerInfo);
// allow -s server override to reference a friendly name
// in the config.
// setenv SERVER <HOST>/<FRIENDLY_NAME>
if (!config.serverOverride.empty())
{
const ClientAPI::EvalConfig eval = ClientAPI::OpenVPNClient::eval_config_static(config);
for (auto &se : eval.serverList)
{
if (config.serverOverride == se.friendlyName)
{
config.serverOverride = se.server;
break;
}
}
}
if (eval)
{
ClientAPI::EvalConfig eval = ClientAPI::OpenVPNClient::eval_config_static(config);
const ClientAPI::EvalConfig eval = ClientAPI::OpenVPNClient::eval_config_static(config);
std::cout << "EVAL PROFILE" << std::endl;
std::cout << "error=" << eval.error << std::endl;
std::cout << "message=" << eval.message << std::endl;
@@ -814,6 +899,9 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content)
std::cout << "privateKeyPasswordRequired=" << eval.privateKeyPasswordRequired << std::endl;
std::cout << "allowPasswordSave=" << eval.allowPasswordSave << std::endl;
if (!config.serverOverride.empty())
std::cout << "server=" << config.serverOverride << std::endl;
for (size_t i = 0; i < eval.serverList.size(); ++i)
{
const ClientAPI::ServerEntry& se = eval.serverList[i];
@@ -823,7 +911,7 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content)
else
{
Client client;
ClientAPI::EvalConfig eval = client.eval_config(config);
const ClientAPI::EvalConfig eval = client.eval_config(config);
if (eval.error)
OPENVPN_THROW_EXCEPTION("eval config error: " << eval.message);
if (eval.autologin)
@@ -866,6 +954,10 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content)
#endif
}
#ifdef OPENVPN_REMOTE_OVERRIDE
client.set_remote_override_cmd(remote_override_cmd);
#endif
std::cout << "CONNECTING..." << std::endl;
// start the client thread
@@ -908,6 +1000,9 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content)
std::cout << "--proto, -P : protocol override (udp|tcp)" << std::endl;
std::cout << "--server, -s : server override" << std::endl;
std::cout << "--port, -R : port override" << std::endl;
#ifdef OPENVPN_REMOTE_OVERRIDE
std::cout << "--remote-override : command to run to generate next remote (returning host,ip,port,proto)" << std::endl;
#endif
std::cout << "--ipv6, -6 : IPv6 (yes|no|default)" << std::endl;
std::cout << "--timeout, -t : timeout" << std::endl;
std::cout << "--compress, -c : compression mode (yes|no|asym)" << std::endl;
@@ -932,6 +1027,7 @@ int openvpn_client(int argc, char *argv[], const std::string* profile_content)
std::cout << "--ssl-debug : SSL debug level" << std::endl;
std::cout << "--google-dns, -g : enable Google DNS fallback" << std::endl;
std::cout << "--auto-sess, -a : request autologin session" << std::endl;
std::cout << "--auth-retry, -Y : retry connection on auth failure" << std::endl;
std::cout << "--persist-tun, -j : keep TUN interface open across reconnects" << std::endl;
std::cout << "--peer-info, -I : peer info key/value list in the form K1=V1,K2=V2,..." << std::endl;
std::cout << "--gremlin, -G : gremlin info (send_delay_ms, recv_delay_ms, send_drop_prob, recv_drop_prob)" << std::endl;

View File

@@ -6,6 +6,7 @@ GCC_EXTRA="$GCC_EXTRA -DOPENVPN_SHOW_SESSION_TOKEN"
[ "$GREMLIN" = "1" ] && GCC_EXTRA="$GCC_EXTRA -DOPENVPN_GREMLIN"
[ "$DEX" = "1" ] && GCC_EXTRA="$GCC_EXTRA -DOPENVPN_DISABLE_EXPLICIT_EXIT"
[ "$BS64" = "1" ] && GCC_EXTRA="$GCC_EXTRA -DOPENVPN_BS64_DATA_LIMIT=2500000"
[ "$ROVER" = "1" ] && GCC_EXTRA="$GCC_EXTRA -DOPENVPN_REMOTE_OVERRIDE"
if [ "$AGENT" = "1" ]; then
GCC_EXTRA="$GCC_EXTRA -DOPENVPN_COMMAND_AGENT"
fi

View File

@@ -88,14 +88,14 @@
<WarningLevel>TurnOffAllWarnings</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>false</SDLCheck>
<AdditionalIncludeDirectories>$(OVPN3_BUILD)\amd64\mbedtls\include;$(OVPN3_BUILD)\amd64\lz4\lib;$(GTEST_ROOT)\googletest\include;$(OVPN3_CORE);$(OVPN3_BUILD)\amd64\asio\asio\include;$(OVPN3_TAP_WINDOWS)\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(OVPN3_ROOT)\deps\amd64\mbedtls\include;$(OVPN3_ROOT)\deps\amd64\lz4\lib;$(GTEST_ROOT)\googletest\include;$(OVPN3_ROOT)\core;$(OVPN3_ROOT)\deps\amd64\asio\asio\include;$(OVPN3_ROOT)\deps\amd64\tap-windows\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NOMINMAX;_WIN32_WINNT=0x0600;USE_ASIO;ASIO_STANDALONE;USE_MBEDTLS;HAVE_LZ4;OPENVPN_FORCE_TUN_NULL;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>lz4.lib;mbedtls.lib;Iphlpapi.lib;gtest.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OVPN3_BUILD)\amd64\mbedtls\library;$(GTEST_ROOT)\googlemock\gtest\Debug\;%(AdditionalLibraryDirectories);$(OVPN3_BUILD)\amd64\lz4\lib</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(OVPN3_ROOT)\deps\amd64\mbedtls\library;$(GTEST_ROOT)\googlemock\gtest\Debug\;%(AdditionalLibraryDirectories);$(OVPN3_ROOT)\deps\amd64\lz4\lib</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -123,7 +123,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<AdditionalIncludeDirectories>$(OVPN3_BUILD)\amd64\mbedtls\include;$(OVPN3_BUILD)\amd64\lz4\lib;$(GTEST_ROOT)\googletest\include;$(OVPN3_CORE);$(OVPN3_BUILD)\amd64\asio\asio\include;$(OVPN3_TAP_WINDOWS)\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(OVPN3_ROOT)\deps\amd64\mbedtls\include;$(OVPN3_ROOT)\deps\amd64\lz4\lib;$(GTEST_ROOT)\googletest\include;$(OVPN3_ROOT)\core;$(OVPN3_ROOT)\deps\amd64\asio\asio\include;$(OVPN3_ROOT)\deps\amd64\tap-windows\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NOMINMAX;_WIN32_WINNT=0x0600;USE_ASIO;ASIO_STANDALONE;USE_MBEDTLS;HAVE_LZ4;OPENVPN_FORCE_TUN_NULL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
@@ -131,7 +131,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>lz4.lib;mbedtls.lib;Iphlpapi.lib;gtest.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OVPN3_BUILD)\amd64\mbedtls\library;$(GTEST_ROOT)\googlemock\gtest\Release\;%(AdditionalLibraryDirectories);$(OVPN3_BUILD)\amd64\lz4\lib</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(OVPN3_ROOT)\deps\amd64\mbedtls\library;$(GTEST_ROOT)\googlemock\gtest\Release\;%(AdditionalLibraryDirectories);$(OVPN3_ROOT)\deps\amd64\lz4\lib</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup>

View File

@@ -1,5 +1,5 @@
export PLATFORM=osx
export DEP_DIR=$HOME/src/mac
[ -z "$DEP_DIR" ] && export DEP_DIR=$HOME/src/mac
export APPLE_FAMILY=1
export DEBUG_BUILD=0
export GPP_CMD=clang++

View File

@@ -1,5 +1,5 @@
export PLATFORM=osx-dbg
export DEP_DIR=$HOME/src/mac
[ -z "$DEP_DIR" ] && export DEP_DIR=$HOME/src/mac
export APPLE_FAMILY=1
export DEBUG_BUILD=1
export GPP_CMD=clang++

View File

@@ -1,5 +1,5 @@
export PLATFORM=osx
export DEP_DIR=$HOME/src/mac
[ -z "$DEP_DIR" ] && export DEP_DIR=$HOME/src/mac
export APPLE_FAMILY=1
export DEBUG_BUILD=0
export GPP_CMD=clang++

View File

@@ -1,5 +1,5 @@
export PLATFORM=osx-dbg
export DEP_DIR=$HOME/src/mac
[ -z "$DEP_DIR" ] && export DEP_DIR=$HOME/src/mac
export APPLE_FAMILY=1
export DEBUG_BUILD=1
export GPP_CMD=clang++

View File

@@ -39,7 +39,7 @@ def build(parms, srcfile, unit_test=False):
# onto VC command line.
options = {
"ovpn3" : parms['OVPN3'],
"tap" : os.path.join(parms['TAP'], 'src'),
"tap" : os.path.join(build_dir(parms), "tap-windows", "src"),
"tap_component_id" : parms['TAP_WIN_COMPONENT_ID'],
"asio" : os.path.join(build_dir(parms), "asio"),
"mbedtls" : os.path.join(build_dir(parms), "mbedtls"),
@@ -62,7 +62,7 @@ def build(parms, srcfile, unit_test=False):
options['extra_lib'] += " fwpuclnt.lib"
# Add jsoncpp (optional)
if 'jsoncpp' in parms['LIB_VERSIONS']:
if parms.get('USE_JSONCPP'):
options["jsoncpp"] = os.path.join(build_dir(parms), "jsoncpp")
options['extra_inc'] += " /DHAVE_JSONCPP /I %(jsoncpp)s/dist" % options
options['extra_lib_path'] += " /LIBPATH:%(jsoncpp)s/dist" % options
@@ -82,12 +82,9 @@ def build(parms, srcfile, unit_test=False):
if __name__ == "__main__":
import sys
from parms import PARMS
# some parameters might be redefined, like in Jenkins multibranch pipeline case
PARMS['BUILD'] = os.environ.get('BUILD', PARMS['BUILD'])
PARMS['OVPN3'] = os.environ.get('OVPN3', PARMS['OVPN3'])
params = read_params()
src = src_fn_argv(PARMS, sys.argv[1:])
src = src_fn_argv(params, sys.argv[1:])
unit_test = is_unit_test(sys.argv[1:])
build(PARMS, src, unit_test)
build(params, src, unit_test)

View File

@@ -1,4 +1,6 @@
import os, re
import glob
import os
import re
from utils import *
@@ -14,26 +16,33 @@ def compile_one_file(parms, srcfile, incdirs):
def build_asio(parms):
print "**************** ASIO"
with Cd(build_dir(parms)) as cd:
with Cd(build_dir(parms)):
asio_ver = parms["ASIO_VERSION"]
url = "https://github.com/chriskohlhoff/asio/archive/%s.tar.gz" % asio_ver
arch_path = os.path.join(build_dir(parms), download(url))
checksum = sha256_checksum(arch_path)
if checksum != parms["ASIO_CSUM"]:
sys.exit("Checksum mismatch, expected %s, actual %s" % (parms["ASIO_CSUM"], checksum))
with ModEnv('PATH', "%s\\bin;%s" % (parms.get('GIT'), os.environ['PATH'])):
dist = os.path.realpath('asio')
rmtree(dist)
d = expand('asio', parms['DEP'], parms.get('LIB_VERSIONS'))
os.rename(d, dist)
extract(arch_path, "gz")
rmtree("asio")
os.rename("asio-%s" % asio_ver, "asio")
rm(arch_path)
def build_mbedtls(parms):
print "**************** MBEDTLS"
with Cd(build_dir(parms)) as cd:
with Cd(build_dir(parms)):
url = "https://tls.mbed.org/download/%s-apache.tgz" % parms["MBEDTLS_VERSION"]
arch_path = os.path.join(build_dir(parms), download(url))
checksum = sha256_checksum(arch_path)
if checksum != parms["MBEDTLS_CSUM"]:
sys.exit("Checksum mismatch, expected %s, actual %s" % (parms["MBEDTLS_CSUM"], checksum))
with ModEnv('PATH', "%s\\bin;%s" % (parms.get('GIT'), os.environ['PATH'])):
extract(arch_path, "gz")
dist = os.path.realpath('mbedtls')
rmtree(dist)
d = expand('mbedtls', parms['DEP'], parms.get('LIB_VERSIONS'))
if d.endswith("-apache"):
d = d[:-7]
elif d.endswith("-gpl"):
d = d[:-4]
os.rename(d, dist)
os.rename(parms["MBEDTLS_VERSION"], dist)
rm(arch_path)
# edit mbedTLS config.h
conf_fn = os.path.join(dist, 'include', 'mbedtls', 'config.h')
@@ -43,6 +52,17 @@ def build_mbedtls(parms):
with open(conf_fn, 'w') as f:
f.write(conf)
# apply patches
unapplicable_patches = ["0005-data_files-pkcs8-v2-add-keys-generated-with-PRF-SHA1.patch"]
for patch_file in glob.glob(os.path.join(parms.get('OVPN3'), "core", "deps", "mbedtls", "patches", "*.patch")):
for unapplicable_patch in unapplicable_patches:
if patch_file.endswith(unapplicable_patch):
print "Skipping %s, 'git apply' doesn't apply it on Windows" % patch_file
break
else:
call(["git", "apply", "--whitespace=nowarn", "--ignore-space-change", "--verbose", patch_file], cwd=dist)
# compile the source files
os.chdir(os.path.join(dist, "library"))
obj = []
@@ -58,30 +78,56 @@ def build_mbedtls(parms):
def build_lz4(parms):
print "**************** LZ4"
with Cd(build_dir(parms)) as cd:
with Cd(build_dir(parms)):
url = "https://github.com/lz4/lz4/archive/v%s.tar.gz" % parms["LZ4_VERSION"][4:]
arch_name = download(url)
checksum = sha256_checksum(arch_name)
if checksum != parms["LZ4_CSUM"]:
sys.exit("Checksum mismatch, expected %s, actual %s" % (parms["LZ4_CSUM"], checksum))
with ModEnv('PATH', "%s\\bin;%s" % (parms.get('GIT'), os.environ['PATH'])):
extract(arch_name, "gz")
dist = os.path.realpath('lz4')
rmtree(dist)
d = expand('lz4', parms['DEP'], parms.get('LIB_VERSIONS'))
os.rename(d, dist)
os.rename(parms["LZ4_VERSION"], dist)
rm(arch_name)
os.chdir(os.path.join(dist, "lib"))
compile_one_file(parms, "lz4.c", ())
vc_cmd(parms, r"lib /OUT:lz4.lib lz4.obj")
def build_tap(parms):
print "**************** Windows-TAP"
with Cd(build_dir(parms)):
url = "https://github.com/OpenVPN/tap-windows6/archive/%s.zip" % parms["TAP_VERSION"]
arch_name = download(url)
checksum = sha256_checksum(arch_name)
if checksum != parms["TAP_CSUM"]:
sys.exit("Checksum mismatch, expected %s, actual %s" % (parms["TAP_CSUM"], checksum))
with ModEnv('PATH', "%s\\bin;%s" % (parms.get('GIT'), os.environ['PATH'])):
extract(arch_name, "zip")
dist = os.path.realpath('tap-windows')
rmtree(dist)
os.rename("tap-windows6-%s" % parms["TAP_VERSION"], dist)
rm(arch_name)
def build_jsoncpp(parms):
if 'jsoncpp' in parms['LIB_VERSIONS']:
print "**************** JSONCPP"
with Cd(build_dir(parms)) as cd:
with ModEnv('PATH', "%s\\bin;%s" % (parms.get('GIT'), os.environ['PATH'])):
dist = os.path.realpath('jsoncpp')
rmtree(dist)
d = expand('jsoncpp', parms['DEP'], parms.get('LIB_VERSIONS'))
os.rename(d, dist)
os.chdir(dist)
call(["python", "amalgamate.py"])
os.chdir(os.path.join(dist, "dist"))
compile_one_file(parms, "jsoncpp.cpp", (".",))
vc_cmd(parms, r"lib /OUT:jsoncpp.lib jsoncpp.obj")
print "**************** JSONCPP"
with Cd(build_dir(parms)):
url = "https://github.com/open-source-parsers/jsoncpp/archive/%s.tar.gz" % parms["JSONCPP_VERSION"]
arch_name = download(url)
checksum = sha256_checksum(arch_name)
if checksum != parms["JSONCPP_CSUM"]:
sys.exit("Checksum mismatch, expected %s, actual %s" % (parms["JSONCPP_CSUM"], checksum))
with ModEnv('PATH', "%s\\bin;%s" % (parms.get('GIT'), os.environ['PATH'])):
dist = os.path.realpath('jsoncpp')
rmtree(dist)
extract(arch_name, "gz")
rm(arch_name)
os.rename("jsoncpp-%s" % parms["JSONCPP_VERSION"], dist)
os.chdir(dist)
call(["python", "amalgamate.py"])
os.chdir(os.path.join(dist, "dist"))
compile_one_file(parms, "jsoncpp.cpp", (".",))
vc_cmd(parms, r"lib /OUT:jsoncpp.lib jsoncpp.obj")
def build_all(parms):
wipetree(build_dir(parms))
@@ -89,13 +135,7 @@ def build_all(parms):
build_mbedtls(parms)
build_lz4(parms)
build_jsoncpp(parms)
build_tap(parms)
if __name__ == "__main__":
from parms import PARMS
# some parameters might be redefined, like in Jenkins multibranch pipeline case
PARMS['BUILD'] = os.environ.get('BUILD', PARMS['BUILD'])
PARMS['OVPN3'] = os.environ.get('OVPN3', PARMS['OVPN3'])
PARMS['ARCH'] = os.environ.get('ARCH', PARMS['ARCH'])
build_all(PARMS)
build_all(read_params())

View File

@@ -460,7 +460,7 @@
<Optimization>Disabled</Optimization>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NOMINMAX;_WIN32_WINNT=0x0600;USE_ASIO;ASIO_STANDALONE;USE_MBEDTLS;HAVE_LZ4;TAP_WIN_COMPONENT_ID=tap0901;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(OVPN3_BUILD)\amd64\mbedtls\include;$(OVPN3_TAP_WINDOWS)\src;$(OVPN3_BUILD)\amd64\asio\asio\include;$(OVPN3_BUILD)\amd64\lz4\lib;$(OVPN3_CORE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(OVPN3_ROOT)\deps\amd64\mbedtls\include;$(OVPN3_ROOT)\deps\amd64\tap-windows\src;$(OVPN3_ROOT)\deps\amd64\asio\asio\include;$(OVPN3_ROOT)\deps\amd64\lz4\lib;$(OVPN3_ROOT)\core;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<SuppressStartupBanner>false</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
@@ -468,7 +468,7 @@
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(OVPN3_BUILD)\amd64\mbedtls\library;$(OVPN3_BUILD)\amd64\lz4\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(OVPN3_ROOT)\deps\amd64\mbedtls\library;$(OVPN3_ROOT)\deps\amd64\lz4\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>lz4.lib;mbedtls.lib;fwpuclnt.lib;ws2_32.lib;crypt32.lib;iphlpapi.lib;winmm.lib;advapi32.lib;wininet.lib;shell32.lib;ole32.lib;rpcrt4.lib</AdditionalDependencies>
<ShowProgress>NotSet</ShowProgress>
</Link>
@@ -499,14 +499,14 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NOMINMAX;_WIN32_WINNT=0x0600;USE_ASIO;ASIO_STANDALONE;USE_MBEDTLS;HAVE_LZ4;TAP_WIN_COMPONENT_ID=tap0901;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(OVPN3_BUILD)\amd64\mbedtls\include;$(OVPN3_TAP_WINDOWS)\src;$(OVPN3_BUILD)\amd64\asio\asio\include;$(OVPN3_BUILD)\amd64\lz4\lib;$(OVPN3_CORE);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(OVPN3_ROOT)\deps\amd64\mbedtls\include;$(OVPN3_ROOT)\deps\amd64\tap-windows\src;$(OVPN3_ROOT)\deps\amd64\asio\asio\include;$(OVPN3_ROOT)\deps\amd64\lz4\lib;$(OVPN3_ROOT)\core;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(OVPN3_BUILD)\amd64\mbedtls\library;$(OVPN3_BUILD)\amd64\lz4\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(OVPN3_ROOT)\deps\amd64\mbedtls\library;$(OVPN3_ROOT)\deps\amd64\lz4\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>lz4.lib;mbedtls.lib;fwpuclnt.lib;ws2_32.lib;crypt32.lib;iphlpapi.lib;winmm.lib;advapi32.lib;wininet.lib;shell32.lib;ole32.lib;rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>

View File

@@ -1,26 +0,0 @@
PARMS = {
"DEBUG" : False,
"STATIC" : True,
"OVPN3" : "c:\\src\\ovpn3",
"TAP" : "c:\\src\\tap-windows6",
"TAP_WIN_COMPONENT_ID" : "tap0901", # Community: tap0901, Access Server: tapoas
"DEP" : "z:\\james\\downloads",
"BUILD" : "c:\\src\\ovpn3-build",
"PATCH" : "c:\\src\\as\\pyovpn\\patch",
"GIT" : "c:\\Program Files (x86)\\Git",
"CPP_EXTRA" : "",
"MSVC_DIR" : "c:\\Program Files (x86)\\Microsoft Visual Studio 14.0",
"ARCH" : "amd64", # one of amd64, x86, or x86_xp (note that x86_xp requires vcvarsall.bat patch)
"LIB_VERSIONS" : {
'asio' : "asio-20170227",
'mbedtls' : "mbedtls-2.4.0",
'lz4' : "lz4-1.7.5",
},
"GTEST_ROOT": ""
}
try:
from parms_local import PARMS as parms_local
PARMS.update(parms_local)
except ImportError:
pass

View File

@@ -1,4 +1,7 @@
import os, sys, re, stat, shutil, tarfile, zipfile, subprocess
import requests
import rfc6266
import hashlib
j = os.path.join
@@ -260,3 +263,51 @@ def zipdir(path, ziph):
for root, dirs, files in os.walk(path):
for file in files:
ziph.write(os.path.join(root, file))
def download(url):
print "Downloading %s" % url
response = requests.get(url)
fname = rfc6266.parse_headers(response.headers['content-disposition']).filename_unsafe
with open(fname, "wb") as f:
f.write(response.content)
return fname
def sha256_checksum(filename, block_size=65536):
sha256 = hashlib.sha256()
with open(filename, 'rb') as f:
for block in iter(lambda: f.read(block_size), b''):
sha256.update(block)
return sha256.hexdigest()
def read_params():
if not os.environ.get('O3'):
sys.exit("Missing required O3 env variable")
params={}
params['OVPN3'] = os.environ.get('O3').rstrip()
if not os.environ.get('DEP_DIR'):
params["BUILD"] = os.path.join(params['OVPN3'], "deps")
else:
params['BUILD'] = os.environ.get('DEP_DIR').rstrip()
params['ARCH'] = os.environ.get('ARCH', 'amd64').rstrip()
params['DEBUG'] = os.environ.get('DEBUG')
params['STATIC'] = os.environ.get('STATIC')
params['MSVC_DIR'] = os.environ.get('MSVC_DIR', 'c:\\Program Files (x86)\\Microsoft Visual Studio 14.0').rstrip()
# Community: tap0901, Access Server: tapoas
params['TAP_WIN_COMPONENT_ID'] = os.environ.get('TAP_WIN_COMPONENT_ID', 'tap0901')
params['CPP_EXTRA'] = os.environ.get('CPP_EXTRA', '').rstrip()
if os.environ.get('USE_JSONSPP'):
params['USE_JSONCPP'] = True
if os.environ.get('USE_JSONSPP'):
params['CONNECT'] = True
params['GTEST_ROOT'] = os.environ.get('GTEST_ROOT')
# read versions
with open(os.path.join(params['OVPN3'], "core", "deps", "lib-versions")) as f:
for l in [line.strip() for line in f if line.strip()]:
name, val = l.split("=")
if name.startswith("export"):
name = name[6:].strip()
params[name] = val
return params