diff --git a/.gitignore b/.gitignore index a332ac0..4a2d375 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ README.html x64 *.vcxproj.user -*.ipch \ No newline at end of file +*.ipch diff --git a/README.rst b/README.rst index 2825b1f..44550d4 100644 --- a/README.rst +++ b/README.rst @@ -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 ------- diff --git a/VersionNumbering.rst b/VersionNumbering.rst new file mode 100644 index 0000000..0d32e58 --- /dev/null +++ b/VersionNumbering.rst @@ -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``. diff --git a/client/ovpncli.cpp b/client/ovpncli.cpp index 5892717..e9cf6ba 100644 --- a/client/ovpncli.cpp +++ b/client/ovpncli.cpp @@ -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; diff --git a/client/ovpncli.hpp b/client/ovpncli.hpp index 3059d09..82a2c25 100644 --- a/client/ovpncli.hpp +++ b/client/ovpncli.hpp @@ -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 { diff --git a/deps/asio/build-asio b/deps/asio/build-asio index a89207e..e4fa9f8 100755 --- a/deps/asio/build-asio +++ b/deps/asio/build-asio @@ -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 diff --git a/deps/asio/patch/0001-Android-appears-to-not-support-pthread_condattr_setc.patch b/deps/asio/patch/0001-Android-appears-to-not-support-pthread_condattr_setc.patch deleted file mode 100644 index 9e44211..0000000 --- a/deps/asio/patch/0001-Android-appears-to-not-support-pthread_condattr_setc.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 48f2e874280f0d93d1a3df2e48aacc9e13b8eef5 Mon Sep 17 00:00:00 2001 -From: James Yonan -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 - diff --git a/deps/asio/patch/0001-Added-Apple-NAT64-support-when-both-ASIO_HAS_GETADDR.patch b/deps/asio/patches/0001-Added-Apple-NAT64-support-when-both-ASIO_HAS_GETADDR.patch similarity index 67% rename from deps/asio/patch/0001-Added-Apple-NAT64-support-when-both-ASIO_HAS_GETADDR.patch rename to deps/asio/patches/0001-Added-Apple-NAT64-support-when-both-ASIO_HAS_GETADDR.patch index 4bca87e..0bf2eb6 100644 --- a/deps/asio/patch/0001-Added-Apple-NAT64-support-when-both-ASIO_HAS_GETADDR.patch +++ b/deps/asio/patches/0001-Added-Apple-NAT64-support-when-both-ASIO_HAS_GETADDR.patch @@ -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 -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 diff --git a/deps/asio/patch/0001-Added-randomize-method-to-asio-ip-tcp-resolver-resul.patch b/deps/asio/patches/0002-Added-randomize-method-to-asio-ip-tcp-resolver-resul.patch similarity index 82% rename from deps/asio/patch/0001-Added-randomize-method-to-asio-ip-tcp-resolver-resul.patch rename to deps/asio/patches/0002-Added-randomize-method-to-asio-ip-tcp-resolver-resul.patch index b3f41e1..22bdac1 100644 --- a/deps/asio/patch/0001-Added-randomize-method-to-asio-ip-tcp-resolver-resul.patch +++ b/deps/asio/patches/0002-Added-randomize-method-to-asio-ip-tcp-resolver-resul.patch @@ -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 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 > values_type; }; -- -1.8.5.2 (Apple Git-48) +2.16.2 diff --git a/deps/asio/patch/0002-Added-user-code-hook-async_connect_post_open-to-be-c.patch b/deps/asio/patches/0003-Added-user-code-hook-async_connect_post_open-to-be-c.patch similarity index 72% rename from deps/asio/patch/0002-Added-user-code-hook-async_connect_post_open-to-be-c.patch rename to deps/asio/patches/0003-Added-user-code-hook-async_connect_post_open-to-be-c.patch index 9139b17..a9ad6c3 100644 --- a/deps/asio/patch/0002-Added-user-code-hook-async_connect_post_open-to-be-c.patch +++ b/deps/asio/patches/0003-Added-user-code-hook-async_connect_post_open-to-be-c.patch @@ -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 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 +Date: Tue, 20 Mar 2018 09:35:47 +0800 +Subject: [PATCH] relax x509 date format check + +Signed-off-by: Antonio Quartulli +--- + 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 + diff --git a/deps/mbedtls/patches/0002-pkcs5v2-add-support-for-additional-hmacSHA-algorithm.patch b/deps/mbedtls/patches/0002-pkcs5v2-add-support-for-additional-hmacSHA-algorithm.patch new file mode 100644 index 0000000..157ff29 --- /dev/null +++ b/deps/mbedtls/patches/0002-pkcs5v2-add-support-for-additional-hmacSHA-algorithm.patch @@ -0,0 +1,154 @@ +From 56df6d5003b20fa673b67fb06c2ec03a8197c4c2 Mon Sep 17 00:00:00 2001 +From: Antonio Quartulli +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 +--- + 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 + diff --git a/deps/mbedtls/patches/0003-tests-pkcs5-pbkdf2_hmac-add-unit-tests-for-additiona.patch b/deps/mbedtls/patches/0003-tests-pkcs5-pbkdf2_hmac-add-unit-tests-for-additiona.patch new file mode 100644 index 0000000..ad46ebb --- /dev/null +++ b/deps/mbedtls/patches/0003-tests-pkcs5-pbkdf2_hmac-add-unit-tests-for-additiona.patch @@ -0,0 +1,128 @@ +From bb029567d8a2b55e500a85c916a8d22ae9434ab3 Mon Sep 17 00:00:00 2001 +From: Antonio Quartulli +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 +--- + 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 + diff --git a/deps/mbedtls/patches/0004-tests-pkcs5-pbkdf2_hmac-extend-array-to-accommodate-.patch b/deps/mbedtls/patches/0004-tests-pkcs5-pbkdf2_hmac-extend-array-to-accommodate-.patch new file mode 100644 index 0000000..ed67848 --- /dev/null +++ b/deps/mbedtls/patches/0004-tests-pkcs5-pbkdf2_hmac-extend-array-to-accommodate-.patch @@ -0,0 +1,49 @@ +From d09cecb5f7d1e66476c97a35caee7248930ef425 Mon Sep 17 00:00:00 2001 +From: Antonio Quartulli +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 +--- + 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 + diff --git a/deps/mbedtls/patches/0005-data_files-pkcs8-v2-add-keys-generated-with-PRF-SHA1.patch b/deps/mbedtls/patches/0005-data_files-pkcs8-v2-add-keys-generated-with-PRF-SHA1.patch new file mode 100644 index 0000000..9eecc17 --- /dev/null +++ b/deps/mbedtls/patches/0005-data_files-pkcs8-v2-add-keys-generated-with-PRF-SHA1.patch @@ -0,0 +1,2593 @@ +From 4e96327a813d2e1d06dfb7e44caacb400fd8769b Mon Sep 17 00:00:00 2001 +From: Antonio Quartulli +Date: Thu, 1 Feb 2018 13:54:13 +0800 +Subject: [PATCH] data_files/pkcs8-v2: add keys generated with PRF != SHA1 + +We now have support for the entire SHA family to be used as +PRF in PKCS#5 v2.0, therefore we need to add new keys to test +these new functionalities. + +This patch adds the new keys in `tests/data_files` and +commands to generate them in `tests/data_files/Makefile`. + +Note that the pkcs8 command in OpenSSL 1.0 called with +the -v2 argument generates keys using PKCS#5 v2.0 with SHA1 +as PRF by default. + +(This behaviour has changed in OpenSSL 1.1, where the exact same +command instead uses PKCS#5 v2.0 with SHA256) + +The new keys are generated by specifying different PRFs with +-v2prf. + +Signed-off-by: Antonio Quartulli +--- + tests/data_files/Makefile | 568 +++++++++++++++++++++ + .../rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.der | Bin 0 -> 728 bytes + .../rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.pem | 18 + + .../rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.der | Bin 0 -> 728 bytes + .../rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.pem | 18 + + .../rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.der | Bin 0 -> 728 bytes + .../rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.pem | 18 + + .../rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.der | Bin 0 -> 728 bytes + .../rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.pem | 18 + + .../rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.der | Bin 0 -> 725 bytes + .../rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.pem | 18 + + .../rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.der | Bin 0 -> 725 bytes + .../rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.pem | 18 + + .../rsa_pkcs8_pbes2_pbkdf2_1024_des_sha384.der | Bin 0 -> 725 bytes + .../rsa_pkcs8_pbes2_pbkdf2_1024_des_sha384.pem | 18 + + .../rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.der | Bin 0 -> 725 bytes + .../rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.pem | 18 + + .../rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.der | Bin 0 -> 1312 bytes + .../rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.pem | 30 ++ + .../rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.der | Bin 0 -> 1312 bytes + .../rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.pem | 30 ++ + .../rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.der | Bin 0 -> 1312 bytes + .../rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.pem | 30 ++ + .../rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.der | Bin 0 -> 1312 bytes + .../rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.pem | 30 ++ + .../rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.der | Bin 0 -> 1309 bytes + .../rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.pem | 30 ++ + .../rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.der | Bin 0 -> 1309 bytes + .../rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.pem | 30 ++ + .../rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.der | Bin 0 -> 1309 bytes + .../rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.pem | 30 ++ + .../rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.der | Bin 0 -> 1309 bytes + .../rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.pem | 30 ++ + .../rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha224.der | Bin 0 -> 2464 bytes + .../rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha224.pem | 54 ++ + .../rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.der | Bin 0 -> 2464 bytes + .../rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.pem | 54 ++ + .../rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha384.der | Bin 0 -> 2464 bytes + .../rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha384.pem | 54 ++ + .../rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.der | Bin 0 -> 2464 bytes + .../rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.pem | 54 ++ + .../rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.der | Bin 0 -> 2461 bytes + .../rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.pem | 54 ++ + .../rsa_pkcs8_pbes2_pbkdf2_4096_des_sha256.der | Bin 0 -> 2461 bytes + .../rsa_pkcs8_pbes2_pbkdf2_4096_des_sha256.pem | 54 ++ + .../rsa_pkcs8_pbes2_pbkdf2_4096_des_sha384.der | Bin 0 -> 2461 bytes + .../rsa_pkcs8_pbes2_pbkdf2_4096_des_sha384.pem | 54 ++ + .../rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.der | Bin 0 -> 2461 bytes + .../rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.pem | 54 ++ + 49 files changed, 1384 insertions(+) + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.der + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.pem + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.der + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.pem + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.der + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.pem + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.der + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.pem + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.der + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.pem + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.der + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.pem + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha384.der + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha384.pem + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.der + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.pem + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.der + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.pem + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.der + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.pem + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.der + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.pem + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.der + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.pem + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.der + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.pem + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.der + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.pem + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.der + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.pem + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.der + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.pem + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha224.der + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha224.pem + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.der + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.pem + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha384.der + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha384.pem + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.der + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.pem + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.der + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.pem + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha256.der + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha256.pem + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha384.der + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha384.pem + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.der + create mode 100644 tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.pem + +diff --git a/tests/data_files/Makefile b/tests/data_files/Makefile +index d4aed678..7069b4f3 100644 +--- a/tests/data_files/Makefile ++++ b/tests/data_files/Makefile +@@ -392,6 +392,574 @@ server1_all: server1.csr server1.crt server1.noauthid.crt server1.crt.openssl se + + + ++################################################################ ++#### Generate various RSA keys ++################################################################ ++ ++### Password used for PKCS1-encoded encrypted RSA keys ++keys_rsa_basic_pwd = testkey ++ ++### Password used for PKCS8-encoded encrypted RSA keys ++keys_rsa_pkcs8_pwd = PolarSSLTest ++ ++### Basic 1024-, 2048- and 4096-bit unencrypted RSA keys from which ++### all other encrypted RSA keys are derived. ++rsa_pkcs1_1024_clear.pem: ++ $(OPENSSL) genrsa -out $@ 1024 ++all_final += rsa_pkcs1_1024_clear.pem ++rsa_pkcs1_2048_clear.pem: ++ $(OPENSSL) genrsa -out $@ 2048 ++all_final += rsa_pkcs1_2048_clear.pem ++rsa_pkcs1_4096_clear.pem: ++ $(OPENSSL) genrsa -out $@ 4096 ++all_final += rsa_pkcs1_4096_clear.pem ++ ++### ++### PKCS1-encoded, encrypted RSA keys ++### ++ ++### 1024-bit ++rsa_pkcs1_1024_des.pem: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) rsa -des -in $< -out $@ -passout "pass:$(keys_rsa_basic_pwd)" ++all_final += rsa_pkcs1_1024_des.pem ++rsa_pkcs1_1024_3des.pem: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) rsa -des3 -in $< -out $@ -passout "pass:$(keys_rsa_basic_pwd)" ++all_final += rsa_pkcs1_1024_3des.pem ++rsa_pkcs1_1024_aes128.pem: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) rsa -aes128 -in $< -out $@ -passout "pass:$(keys_rsa_basic_pwd)" ++all_final += rsa_pkcs1_1024_aes128.pem ++rsa_pkcs1_1024_aes192.pem: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) rsa -aes192 -in $< -out $@ -passout "pass:$(keys_rsa_basic_pwd)" ++all_final += rsa_pkcs1_1024_aes192.pem ++rsa_pkcs1_1024_aes256.pem: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) rsa -aes256 -in $< -out $@ -passout "pass:$(keys_rsa_basic_pwd)" ++all_final += rsa_pkcs1_1024_aes256.pem ++keys_rsa_enc_basic_1024: rsa_pkcs1_1024_des.pem rsa_pkcs1_1024_3des.pem rsa_pkcs1_1024_aes128.pem rsa_pkcs1_1024_aes192.pem rsa_pkcs1_1024_aes256.pem ++ ++# 2048-bit ++rsa_pkcs1_2048_des.pem: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) rsa -des -in $< -out $@ -passout "pass:$(keys_rsa_basic_pwd)" ++all_final += rsa_pkcs1_2048_des.pem ++rsa_pkcs1_2048_3des.pem: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) rsa -des3 -in $< -out $@ -passout "pass:$(keys_rsa_basic_pwd)" ++all_final += rsa_pkcs1_2048_3des.pem ++rsa_pkcs1_2048_aes128.pem: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) rsa -aes128 -in $< -out $@ -passout "pass:$(keys_rsa_basic_pwd)" ++all_final += rsa_pkcs1_2048_aes128.pem ++rsa_pkcs1_2048_aes192.pem: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) rsa -aes192 -in $< -out $@ -passout "pass:$(keys_rsa_basic_pwd)" ++all_final += rsa_pkcs1_2048_aes192.pem ++rsa_pkcs1_2048_aes256.pem: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) rsa -aes256 -in $< -out $@ -passout "pass:$(keys_rsa_basic_pwd)" ++all_final += rsa_pkcs1_2048_aes256.pem ++keys_rsa_enc_basic_2048: rsa_pkcs1_2048_des.pem rsa_pkcs1_2048_3des.pem rsa_pkcs1_2048_aes128.pem rsa_pkcs1_2048_aes192.pem rsa_pkcs1_2048_aes256.pem ++ ++# 4096-bit ++rsa_pkcs1_4096_des.pem: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) rsa -des -in $< -out $@ -passout "pass:$(keys_rsa_basic_pwd)" ++all_final += rsa_pkcs1_4096_des.pem ++rsa_pkcs1_4096_3des.pem: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) rsa -des3 -in $< -out $@ -passout "pass:$(keys_rsa_basic_pwd)" ++all_final += rsa_pkcs1_4096_3des.pem ++rsa_pkcs1_4096_aes128.pem: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) rsa -aes128 -in $< -out $@ -passout "pass:$(keys_rsa_basic_pwd)" ++all_final += rsa_pkcs1_4096_aes128.pem ++rsa_pkcs1_4096_aes192.pem: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) rsa -aes192 -in $< -out $@ -passout "pass:$(keys_rsa_basic_pwd)" ++all_final += rsa_pkcs1_4096_aes192.pem ++rsa_pkcs1_4096_aes256.pem: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) rsa -aes256 -in $< -out $@ -passout "pass:$(keys_rsa_basic_pwd)" ++all_final += rsa_pkcs1_4096_aes256.pem ++keys_rsa_enc_basic_4096: rsa_pkcs1_4096_des.pem rsa_pkcs1_4096_3des.pem rsa_pkcs1_4096_aes128.pem rsa_pkcs1_4096_aes192.pem rsa_pkcs1_4096_aes256.pem ++ ++### ++### PKCS8-v1 encoded, encrypted RSA keys ++### ++ ++### 1024-bit ++rsa_pkcs8_pbe_sha1_1024_3des.der: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" -topk8 -v1 PBE-SHA1-3DES ++all_final += rsa_pkcs8_pbe_sha1_1024_3des.der ++rsa_pkcs8_pbe_sha1_1024_3des.pem: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" -topk8 -v1 PBE-SHA1-3DES ++all_final += rsa_pkcs8_pbe_sha1_1024_3des.pem ++keys_rsa_enc_pkcs8_v1_1024_3des: rsa_pkcs8_pbe_sha1_1024_3des.pem rsa_pkcs8_pbe_sha1_1024_3des.der ++ ++rsa_pkcs8_pbe_sha1_1024_2des.der: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" -topk8 -v1 PBE-SHA1-2DES ++all_final += rsa_pkcs8_pbe_sha1_1024_2des.der ++rsa_pkcs8_pbe_sha1_1024_2des.pem: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" -topk8 -v1 PBE-SHA1-2DES ++all_final += rsa_pkcs8_pbe_sha1_1024_2des.pem ++keys_rsa_enc_pkcs8_v1_1024_2des: rsa_pkcs8_pbe_sha1_1024_2des.pem rsa_pkcs8_pbe_sha1_1024_2des.der ++ ++rsa_pkcs8_pbe_sha1_1024_rc4_128.der: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" -topk8 -v1 PBE-SHA1-RC4-128 ++all_final += rsa_pkcs8_pbe_sha1_1024_rc4_128.der ++rsa_pkcs8_pbe_sha1_1024_rc4_128.pem: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" -topk8 -v1 PBE-SHA1-RC4-128 ++all_final += rsa_pkcs8_pbe_sha1_1024_rc4_128.pem ++keys_rsa_enc_pkcs8_v1_1024_rc4_128: rsa_pkcs8_pbe_sha1_1024_rc4_128.pem rsa_pkcs8_pbe_sha1_1024_rc4_128.der ++ ++keys_rsa_enc_pkcs8_v1_1024: keys_rsa_enc_pkcs8_v1_1024_3des keys_rsa_enc_pkcs8_v1_1024_2des keys_rsa_enc_pkcs8_v1_1024_rc4_128 ++ ++### 2048-bit ++rsa_pkcs8_pbe_sha1_2048_3des.der: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" -topk8 -v1 PBE-SHA1-3DES ++all_final += rsa_pkcs8_pbe_sha1_2048_3des.der ++rsa_pkcs8_pbe_sha1_2048_3des.pem: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" -topk8 -v1 PBE-SHA1-3DES ++all_final += rsa_pkcs8_pbe_sha1_2048_3des.pem ++keys_rsa_enc_pkcs8_v1_2048_3des: rsa_pkcs8_pbe_sha1_2048_3des.pem rsa_pkcs8_pbe_sha1_2048_3des.der ++ ++rsa_pkcs8_pbe_sha1_2048_2des.der: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" -topk8 -v1 PBE-SHA1-2DES ++all_final += rsa_pkcs8_pbe_sha1_2048_2des.der ++rsa_pkcs8_pbe_sha1_2048_2des.pem: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" -topk8 -v1 PBE-SHA1-2DES ++all_final += rsa_pkcs8_pbe_sha1_2048_2des.pem ++keys_rsa_enc_pkcs8_v1_2048_2des: rsa_pkcs8_pbe_sha1_2048_2des.pem rsa_pkcs8_pbe_sha1_2048_2des.der ++ ++rsa_pkcs8_pbe_sha1_2048_rc4_128.der: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" -topk8 -v1 PBE-SHA1-RC4-128 ++all_final += rsa_pkcs8_pbe_sha1_2048_rc4_128.der ++rsa_pkcs8_pbe_sha1_2048_rc4_128.pem: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" -topk8 -v1 PBE-SHA1-RC4-128 ++all_final += rsa_pkcs8_pbe_sha1_2048_rc4_128.pem ++keys_rsa_enc_pkcs8_v1_2048_rc4_128: rsa_pkcs8_pbe_sha1_2048_rc4_128.pem rsa_pkcs8_pbe_sha1_2048_rc4_128.der ++ ++keys_rsa_enc_pkcs8_v1_2048: keys_rsa_enc_pkcs8_v1_2048_3des keys_rsa_enc_pkcs8_v1_2048_2des keys_rsa_enc_pkcs8_v1_2048_rc4_128 ++ ++### 4096-bit ++rsa_pkcs8_pbe_sha1_4096_3des.der: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" -topk8 -v1 PBE-SHA1-3DES ++all_final += rsa_pkcs8_pbe_sha1_4096_3des.der ++rsa_pkcs8_pbe_sha1_4096_3des.pem: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" -topk8 -v1 PBE-SHA1-3DES ++all_final += rsa_pkcs8_pbe_sha1_4096_3des.pem ++keys_rsa_enc_pkcs8_v1_4096_3des: rsa_pkcs8_pbe_sha1_4096_3des.pem rsa_pkcs8_pbe_sha1_4096_3des.der ++ ++rsa_pkcs8_pbe_sha1_4096_2des.der: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" -topk8 -v1 PBE-SHA1-2DES ++all_final += rsa_pkcs8_pbe_sha1_4096_2des.der ++rsa_pkcs8_pbe_sha1_4096_2des.pem: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" -topk8 -v1 PBE-SHA1-2DES ++all_final += rsa_pkcs8_pbe_sha1_4096_2des.pem ++keys_rsa_enc_pkcs8_v1_4096_2des: rsa_pkcs8_pbe_sha1_4096_2des.pem rsa_pkcs8_pbe_sha1_4096_2des.der ++ ++rsa_pkcs8_pbe_sha1_4096_rc4_128.der: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" -topk8 -v1 PBE-SHA1-RC4-128 ++all_final += rsa_pkcs8_pbe_sha1_4096_rc4_128.der ++rsa_pkcs8_pbe_sha1_4096_rc4_128.pem: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" -topk8 -v1 PBE-SHA1-RC4-128 ++all_final += rsa_pkcs8_pbe_sha1_4096_rc4_128.pem ++keys_rsa_enc_pkcs8_v1_4096_rc4_128: rsa_pkcs8_pbe_sha1_4096_rc4_128.pem rsa_pkcs8_pbe_sha1_4096_rc4_128.der ++ ++keys_rsa_enc_pkcs8_v1_4096: keys_rsa_enc_pkcs8_v1_4096_3des keys_rsa_enc_pkcs8_v1_4096_2des keys_rsa_enc_pkcs8_v1_4096_rc4_128 ++ ++### ++### PKCS8-v2 encoded, encrypted RSA keys, no PRF specified (default for OpenSSL1.0: hmacWithSHA1) ++### ++ ++### 1024-bit ++rsa_pkcs8_pbes2_pbkdf2_1024_3des.der: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_1024_3des.der ++rsa_pkcs8_pbes2_pbkdf2_1024_3des.pem: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_1024_3des.pem ++keys_rsa_enc_pkcs8_v2_1024_3des: rsa_pkcs8_pbes2_pbkdf2_1024_3des.der rsa_pkcs8_pbes2_pbkdf2_1024_3des.pem ++ ++rsa_pkcs8_pbes2_pbkdf2_1024_des.der: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_1024_des.der ++rsa_pkcs8_pbes2_pbkdf2_1024_des.pem: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_1024_des.pem ++keys_rsa_enc_pkcs8_v2_1024_des: rsa_pkcs8_pbes2_pbkdf2_1024_des.der rsa_pkcs8_pbes2_pbkdf2_1024_des.pem ++ ++keys_rsa_enc_pkcs8_v2_1024: keys_rsa_enc_pkcs8_v2_1024_3des keys_rsa_enc_pkcs8_v2_1024_des ++ ++### 2048-bit ++rsa_pkcs8_pbes2_pbkdf2_2048_3des.der: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_2048_3des.der ++rsa_pkcs8_pbes2_pbkdf2_2048_3des.pem: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_2048_3des.pem ++keys_rsa_enc_pkcs8_v2_2048_3des: rsa_pkcs8_pbes2_pbkdf2_2048_3des.der rsa_pkcs8_pbes2_pbkdf2_2048_3des.pem ++ ++rsa_pkcs8_pbes2_pbkdf2_2048_des.der: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_2048_des.der ++rsa_pkcs8_pbes2_pbkdf2_2048_des.pem: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_2048_des.pem ++keys_rsa_enc_pkcs8_v2_2048_des: rsa_pkcs8_pbes2_pbkdf2_2048_des.der rsa_pkcs8_pbes2_pbkdf2_2048_des.pem ++ ++keys_rsa_enc_pkcs8_v2_2048: keys_rsa_enc_pkcs8_v2_2048_3des keys_rsa_enc_pkcs8_v2_2048_des ++ ++### 4096-bit ++rsa_pkcs8_pbes2_pbkdf2_4096_3des.der: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_4096_3des.der ++rsa_pkcs8_pbes2_pbkdf2_4096_3des.pem: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_4096_3des.pem ++keys_rsa_enc_pkcs8_v2_4096_3des: rsa_pkcs8_pbes2_pbkdf2_4096_3des.der rsa_pkcs8_pbes2_pbkdf2_4096_3des.pem ++ ++rsa_pkcs8_pbes2_pbkdf2_4096_des.der: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_4096_des.der ++rsa_pkcs8_pbes2_pbkdf2_4096_des.pem: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_4096_des.pem ++keys_rsa_enc_pkcs8_v2_4096_des: rsa_pkcs8_pbes2_pbkdf2_4096_des.der rsa_pkcs8_pbes2_pbkdf2_4096_des.pem ++ ++keys_rsa_enc_pkcs8_v2_4096: keys_rsa_enc_pkcs8_v2_4096_3des keys_rsa_enc_pkcs8_v2_4096_des ++ ++### ++### PKCS8-v2 encoded, encrypted RSA keys, PRF hmacWithSHA224 ++### ++ ++### 1024-bit ++rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.der: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -v2prf hmacWithSHA224 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.der ++rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.pem: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -v2prf hmacWithSHA224 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.pem ++keys_rsa_enc_pkcs8_v2_1024_3des_sha224: rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.der rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.pem ++ ++rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.der: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA224 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.der ++rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.pem: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA224 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.pem ++keys_rsa_enc_pkcs8_v2_1024_des_sha224: rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.der rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.pem ++ ++keys_rsa_enc_pkcs8_v2_1024_sha224: keys_rsa_enc_pkcs8_v2_1024_3des_sha224 keys_rsa_enc_pkcs8_v2_1024_des_sha224 ++ ++### 2048-bit ++rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.der: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -v2prf hmacWithSHA224 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.der ++rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.pem: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -v2prf hmacWithSHA224 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.pem ++keys_rsa_enc_pkcs8_v2_2048_3des_sha224: rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.der rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.pem ++ ++rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.der: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA224 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.der ++rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.pem: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA224 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.pem ++keys_rsa_enc_pkcs8_v2_2048_des_sha224: rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.der rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.pem ++ ++keys_rsa_enc_pkcs8_v2_2048_sha224: keys_rsa_enc_pkcs8_v2_2048_3des_sha224 keys_rsa_enc_pkcs8_v2_2048_des_sha224 ++ ++### 4096-bit ++rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha224.der: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -v2prf hmacWithSHA224 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha224.der ++rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha224.pem: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -v2prf hmacWithSHA224 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha224.pem ++keys_rsa_enc_pkcs8_v2_4096_3des_sha224: rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha224.der rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha224.pem ++ ++rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.der: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA224 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.der ++rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.pem: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA224 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.pem ++keys_rsa_enc_pkcs8_v2_4096_des_sha224: rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.der rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.pem ++ ++keys_rsa_enc_pkcs8_v2_4096_sha224: keys_rsa_enc_pkcs8_v2_4096_3des_sha224 keys_rsa_enc_pkcs8_v2_4096_des_sha224 ++ ++### ++### PKCS8-v2 encoded, encrypted RSA keys, PRF hmacWithSHA256 ++### ++ ++### 1024-bit ++rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.der: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -v2prf hmacWithSHA256 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.der ++rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.pem: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -v2prf hmacWithSHA256 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.pem ++keys_rsa_enc_pkcs8_v2_1024_3des_sha256: rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.der rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.pem ++ ++rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.der: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA256 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.der ++rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.pem: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA256 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.pem ++keys_rsa_enc_pkcs8_v2_1024_des_sha256: rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.der rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.pem ++ ++keys_rsa_enc_pkcs8_v2_1024_sha256: keys_rsa_enc_pkcs8_v2_1024_3des_sha256 keys_rsa_enc_pkcs8_v2_1024_des_sha256 ++ ++### 2048-bit ++rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.der: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -v2prf hmacWithSHA256 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.der ++rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.pem: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -v2prf hmacWithSHA256 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.pem ++keys_rsa_enc_pkcs8_v2_2048_3des_sha256: rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.der rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.pem ++ ++rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.der: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA256 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.der ++rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.pem: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA256 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.pem ++keys_rsa_enc_pkcs8_v2_2048_des_sha256: rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.der rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.pem ++ ++keys_rsa_enc_pkcs8_v2_2048_sha256: keys_rsa_enc_pkcs8_v2_2048_3des_sha256 keys_rsa_enc_pkcs8_v2_2048_des_sha256 ++ ++### 4096-bit ++rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.der: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -v2prf hmacWithSHA256 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.der ++rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.pem: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -v2prf hmacWithSHA256 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.pem ++keys_rsa_enc_pkcs8_v2_4096_3des_sha256: rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.der rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.pem ++ ++rsa_pkcs8_pbes2_pbkdf2_4096_des_sha256.der: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA256 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_4096_des_sha256.der ++rsa_pkcs8_pbes2_pbkdf2_4096_des_sha256.pem: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA256 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_4096_des_sha256.pem ++keys_rsa_enc_pkcs8_v2_4096_des_sha256: rsa_pkcs8_pbes2_pbkdf2_4096_des_sha256.der rsa_pkcs8_pbes2_pbkdf2_4096_des_sha256.pem ++ ++keys_rsa_enc_pkcs8_v2_4096_sha256: keys_rsa_enc_pkcs8_v2_4096_3des_sha256 keys_rsa_enc_pkcs8_v2_4096_des_sha256 ++ ++### ++### PKCS8-v2 encoded, encrypted RSA keys, PRF hmacWithSHA384 ++### ++ ++### 1024-bit ++rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.der: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -v2prf hmacWithSHA384 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.der ++rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.pem: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -v2prf hmacWithSHA384 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.pem ++keys_rsa_enc_pkcs8_v2_1024_3des_sha384: rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.der rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.pem ++ ++rsa_pkcs8_pbes2_pbkdf2_1024_des_sha384.der: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA384 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_1024_des_sha384.der ++rsa_pkcs8_pbes2_pbkdf2_1024_des_sha384.pem: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA384 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_1024_des_sha384.pem ++keys_rsa_enc_pkcs8_v2_1024_des_sha384: rsa_pkcs8_pbes2_pbkdf2_1024_des_sha384.der rsa_pkcs8_pbes2_pbkdf2_1024_des_sha384.pem ++ ++keys_rsa_enc_pkcs8_v2_1024_sha384: keys_rsa_enc_pkcs8_v2_1024_3des_sha384 keys_rsa_enc_pkcs8_v2_1024_des_sha384 ++ ++### 2048-bit ++rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.der: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -v2prf hmacWithSHA384 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.der ++rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.pem: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -v2prf hmacWithSHA384 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.pem ++keys_rsa_enc_pkcs8_v2_2048_3des_sha384: rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.der rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.pem ++ ++rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.der: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA384 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.der ++rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.pem: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA384 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.pem ++keys_rsa_enc_pkcs8_v2_2048_des_sha384: rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.der rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.pem ++ ++keys_rsa_enc_pkcs8_v2_2048_sha384: keys_rsa_enc_pkcs8_v2_2048_3des_sha384 keys_rsa_enc_pkcs8_v2_2048_des_sha384 ++ ++### 4096-bit ++rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha384.der: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -v2prf hmacWithSHA384 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha384.der ++rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha384.pem: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -v2prf hmacWithSHA384 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha384.pem ++keys_rsa_enc_pkcs8_v2_4096_3des_sha384: rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha384.der rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha384.pem ++ ++rsa_pkcs8_pbes2_pbkdf2_4096_des_sha384.der: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA384 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_4096_des_sha384.der ++rsa_pkcs8_pbes2_pbkdf2_4096_des_sha384.pem: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA384 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_4096_des_sha384.pem ++keys_rsa_enc_pkcs8_v2_4096_des_sha384: rsa_pkcs8_pbes2_pbkdf2_4096_des_sha384.der rsa_pkcs8_pbes2_pbkdf2_4096_des_sha384.pem ++ ++keys_rsa_enc_pkcs8_v2_4096_sha384: keys_rsa_enc_pkcs8_v2_4096_3des_sha384 keys_rsa_enc_pkcs8_v2_4096_des_sha384 ++ ++### ++### PKCS8-v2 encoded, encrypted RSA keys, PRF hmacWithSHA512 ++### ++ ++### 1024-bit ++rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.der: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -v2prf hmacWithSHA512 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.der ++rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.pem: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -v2prf hmacWithSHA512 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.pem ++keys_rsa_enc_pkcs8_v2_1024_3des_sha512: rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.der rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.pem ++ ++rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.der: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA512 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.der ++rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.pem: rsa_pkcs1_1024_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA512 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.pem ++keys_rsa_enc_pkcs8_v2_1024_des_sha512: rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.der rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.pem ++ ++keys_rsa_enc_pkcs8_v2_1024_sha512: keys_rsa_enc_pkcs8_v2_1024_3des_sha512 keys_rsa_enc_pkcs8_v2_1024_des_sha512 ++ ++### 2048-bit ++rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.der: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -v2prf hmacWithSHA512 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.der ++rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.pem: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -v2prf hmacWithSHA512 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.pem ++keys_rsa_enc_pkcs8_v2_2048_3des_sha512: rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.der rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.pem ++ ++rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.der: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA512 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.der ++rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.pem: rsa_pkcs1_2048_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA512 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.pem ++keys_rsa_enc_pkcs8_v2_2048_des_sha512: rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.der rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.pem ++ ++keys_rsa_enc_pkcs8_v2_2048_sha512: keys_rsa_enc_pkcs8_v2_2048_3des_sha512 keys_rsa_enc_pkcs8_v2_2048_des_sha512 ++ ++### 4096-bit ++rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.der: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -v2prf hmacWithSHA512 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.der ++rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.pem: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des3 -v2prf hmacWithSHA512 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.pem ++keys_rsa_enc_pkcs8_v2_4096_3des_sha512: rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.der rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.pem ++ ++rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.der: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA512 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.der ++rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.pem: rsa_pkcs1_4096_clear.pem ++ $(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA512 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)" ++all_final += rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.pem ++keys_rsa_enc_pkcs8_v2_4096_des_sha512: rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.der rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.pem ++ ++keys_rsa_enc_pkcs8_v2_4096_sha512: keys_rsa_enc_pkcs8_v2_4096_3des_sha512 keys_rsa_enc_pkcs8_v2_4096_des_sha512 ++ ++### ++### Rules to generate all RSA keys from a particular class ++### ++ ++### Generate basic unencrypted RSA keys ++keys_rsa_unenc: rsa_pkcs1_1024_clear.pem rsa_pkcs1_2048_clear.pem rsa_pkcs1_4096_clear.pem ++ ++### Generate PKCS1-encoded encrypted RSA keys ++keys_rsa_enc_basic: keys_rsa_enc_basic_1024 keys_rsa_enc_basic_2048 keys_rsa_enc_basic_4096 ++ ++### Generate PKCS8-v1 encrypted RSA keys ++keys_rsa_enc_pkcs8_v1: keys_rsa_enc_pkcs8_v1_1024 keys_rsa_enc_pkcs8_v1_2048 keys_rsa_enc_pkcs8_v1_4096 ++ ++### Generate PKCS8-v2 encrypted RSA keys ++keys_rsa_enc_pkcs8_v2: keys_rsa_enc_pkcs8_v2_1024 keys_rsa_enc_pkcs8_v2_2048 keys_rsa_enc_pkcs8_v2_4096 keys_rsa_enc_pkcs8_v2_1024_sha224 keys_rsa_enc_pkcs8_v2_2048_sha224 keys_rsa_enc_pkcs8_v2_4096_sha224 keys_rsa_enc_pkcs8_v2_1024_sha256 keys_rsa_enc_pkcs8_v2_2048_sha256 keys_rsa_enc_pkcs8_v2_4096_sha256 keys_rsa_enc_pkcs8_v2_1024_sha384 keys_rsa_enc_pkcs8_v2_2048_sha384 keys_rsa_enc_pkcs8_v2_4096_sha384 keys_rsa_enc_pkcs8_v2_1024_sha512 keys_rsa_enc_pkcs8_v2_2048_sha512 keys_rsa_enc_pkcs8_v2_4096_sha512 ++ ++### Generate all RSA keys ++keys_rsa_all: keys_rsa_unenc keys_rsa_enc_basic keys_rsa_enc_pkcs8_v1 keys_rsa_enc_pkcs8_v2 ++ ++ ++ ++################################################################ ++### Generate certificates for CRT write check tests ++################################################################ ++ ++### The test files use the Mbed TLS generated certificates server1*.crt, ++### but for comparison with OpenSSL also rules for OpenSSL-generated ++### certificates server1*.crt.openssl are offered. ++### ++### Known differences: ++### * OpenSSL encodes trailing zero-bits in bit-strings occurring in X.509 extension ++### as unused bits, while Mbed TLS doesn't. ++ ++test_ca_server1_db = test-ca.server1.db ++test_ca_server1_serial = test-ca.server1.serial ++test_ca_server1_config_file = test-ca.server1.opensslconf ++ ++server1.csr: server1.key server1_csr.opensslconf ++ $(OPENSSL) req -keyform PEM -key server1.key -config server1_csr.opensslconf -out $@ -new ++all_final += server1.csr ++ ++server1.crt: server1.key server1.csr $(test_ca_crt) $(test_ca_key_file_rsa) ++ $(MBEDTLS_CERT_WRITE) request_file=server1.csr issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) version=1 not_before=20110212144406 not_after=20210212144406 md=SHA1 version=3 output_file=$@ ++server1.noauthid.crt: server1.key server1.csr $(test_ca_crt) $(test_ca_key_file_rsa) ++ $(MBEDTLS_CERT_WRITE) request_file=server1.csr issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) not_before=20110212144406 not_after=20210212144406 md=SHA1 authority_identifier=0 version=3 output_file=$@ ++server1.der: server1.crt ++ $(OPENSSL) x509 -inform PEM -in $< -outform DER -out $@ ++all_final += server1.crt server1.noauthid.crt server1.der ++ ++server1.key_usage.crt: server1.key server1.csr $(test_ca_crt) $(test_ca_key_file_rsa) ++ $(MBEDTLS_CERT_WRITE) request_file=server1.csr issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) version=1 not_before=20110212144406 not_after=20210212144406 md=SHA1 key_usage=digital_signature,non_repudiation,key_encipherment version=3 output_file=$@ ++server1.key_usage_noauthid.crt: server1.key server1.csr $(test_ca_crt) $(test_ca_key_file_rsa) ++ $(MBEDTLS_CERT_WRITE) request_file=server1.csr issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) version=1 not_before=20110212144406 not_after=20210212144406 md=SHA1 key_usage=digital_signature,non_repudiation,key_encipherment authority_identifier=0 version=3 output_file=$@ ++server1.key_usage.der: server1.key_usage.crt ++ $(OPENSSL) x509 -inform PEM -in $< -outform DER -out $@ ++all_final += server1.key_usage.crt server1.key_usage_noauthid.crt server1.key_usage.der ++ ++server1.cert_type.crt: server1.key server1.csr $(test_ca_crt) $(test_ca_key_file_rsa) ++ $(MBEDTLS_CERT_WRITE) request_file=server1.csr issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) version=1 not_before=20110212144406 not_after=20210212144406 md=SHA1 ns_cert_type=ssl_server version=3 output_file=$@ ++server1.cert_type_noauthid.crt: server1.key server1.csr $(test_ca_crt) $(test_ca_key_file_rsa) ++ $(MBEDTLS_CERT_WRITE) request_file=server1.csr issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) version=1 not_before=20110212144406 not_after=20210212144406 md=SHA1 ns_cert_type=ssl_server authority_identifier=0 version=3 output_file=$@ ++server1.cert_type.der: server1.cert_type.crt ++ $(OPENSSL) x509 -inform PEM -in $< -outform DER -out $@ ++all_final += server1.cert_type.crt server1.cert_type_noauthid.crt server1.cert_type.der ++ ++server1.v1.crt: server1.key server1.csr $(test_ca_crt) $(test_ca_key_file_rsa) ++ $(MBEDTLS_CERT_WRITE) request_file=server1.csr issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) version=1 not_before=20110212144406 not_after=20210212144406 md=SHA1 version=1 output_file=$@ ++server1.v1.der: server1.v1.crt ++ $(OPENSSL) x509 -inform PEM -in $< -outform DER -out $@ ++all_final += server1.v1.crt server1.v1.der ++ ++# OpenSSL-generated certificates for comparison ++# Also provide certificates in DER format to allow ++# direct binary comparison using e.g. dumpasn1 ++server1.crt.openssl server1.key_usage.crt.openssl server1.cert_type.crt.openssl: server1.key server1.csr $(test_ca_crt) $(test_ca_key_file_rsa) $(test_ca_server1_config_file) ++ echo "01" > $(test_ca_server1_serial) ++ rm -f $(test_ca_server1_db) ++ touch $(test_ca_server1_db) ++ $(OPENSSL) ca -batch -passin "pass:$(test_ca_pwd_rsa)" -config $(test_ca_server1_config_file) -in server1.csr -extensions v3_ext -extfile $@.v3_ext -out $@ ++server1.der.openssl: server1.crt.openssl ++ $(OPENSSL) x509 -inform PEM -in $< -outform DER -out $@ ++server1.key_usage.der.openssl: server1.key_usage.crt.openssl ++ $(OPENSSL) x509 -inform PEM -in $< -outform DER -out $@ ++server1.cert_type.der.openssl: server1.cert_type.crt.openssl ++ $(OPENSSL) x509 -inform PEM -in $< -outform DER -out $@ ++ ++server1.v1.crt.openssl: server1.key server1.csr $(test_ca_crt) $(test_ca_key_file_rsa) $(test_ca_server1_config_file) ++ echo "01" > $(test_ca_server1_serial) ++ rm -f $(test_ca_server1_db) ++ touch $(test_ca_server1_db) ++ $(OPENSSL) ca -batch -passin "pass:$(test_ca_pwd_rsa)" -config $(test_ca_server1_config_file) -in server1.csr -out $@ ++server1.v1.der.openssl: server1.v1.crt.openssl ++ $(OPENSSL) x509 -inform PEM -in $< -outform DER -out $@ ++ ++server1_all: server1.csr server1.crt server1.noauthid.crt server1.crt.openssl server1.v1.crt server1.v1.crt.openssl server1.key_usage.crt server1.key_usage_noauthid.crt server1.key_usage.crt.openssl server1.cert_type.crt server1.cert_type_noauthid.crt server1.cert_type.crt.openssl server1.der server1.der.openssl server1.v1.der server1.v1.der.openssl server1.key_usage.der server1.key_usage.der.openssl server1.cert_type.der server1.cert_type.der.openssl ++ ++ ++ + ################################################################ + #### Meta targets + ################################################################ +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.der b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.der +new file mode 100644 +index 0000000000000000000000000000000000000000..4d55a591130415c2fe32e3b9152471b3c9c5d8e5 +GIT binary patch +literal 728 +zcmV;}0w?`2f&$bqP6i1ohDe6@4FLrWFhMXW1_>&LNQU&90UmRshQ@;Gp-Q= +z0tf&w3gmBIG`st_(NFpncKNK%a4x_6kDwR@_XtXQZJaw +z&-O|Gw}*kdOXWz?X4G$ni$U&XTx|*XzG*1wLqX9(kO!B{C}yEaZrh*7sIQd9BQ4L~ +z>FQNEAJS!#FVi})RcG(;mRJk=1`X$GC7s#_d$|dO9wKINpuFejF;ZUh!`o7RzVf4- +zDED92{rGHXHg9D~fY_MTe;XEKuWFx+)%p(fFL@p=s@cc_!DhFNnVt+67on=NrmJML +zTQZ)H4u|aW*=RXuj~?R4TWH^pMJ{SlSubvRs{a^t=lMMx6@3W7C9tTra_+0Ru5hbi +zT$X>L3G2mw|Bi?krWsj3OX!Lrhvv)Ptp_d>AjWj;J}aL{y4s*C15-%p?_p_jPB&kd +zpOg8K9+rWxJ|TpR=dN|Hv6%xx-miqchQslXgpn{$lzoIhv|vjN<2XUbD+t)D@=b%e +zhE2>`^{<~qC88w`Nu4!7t}XuS*!bA1?83YXwTf8QCXyvL$b41=gm1#1X&;~zCTC+3 +zHF%Lau?Xce!O=JXfFCN!RPj;aoGd^Yr=b__;=-q8dTC9y!kv8b;~5Gpb(*b`+c^!a +ze~opsFVK7Np4K$Y_;;5-JYd2}K=+`u8E!F(-LpZfnvy-Gea15iYN4aylyr$={Al^n +z5e_js& + +literal 0 +HcmV?d00001 + +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.pem b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.pem +new file mode 100644 +index 00000000..b47b5e8f +--- /dev/null ++++ b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha224.pem +@@ -0,0 +1,18 @@ ++-----BEGIN ENCRYPTED PRIVATE KEY----- ++MIIC1DBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIc1vbNC/8pHsCAggA ++MAwGCCqGSIb3DQIIBQAwFAYIKoZIhvcNAwcECLMkF/Djhb0fBIICgAg/jv44TuAQ ++yB+WMkHpvVS25ZLJabHUyHLS+vqhEkz2AqvJNETL/L6bIHRD1o4BJ8Fcrc339Bz+ ++zuFHnK7JG0PzRKl9RcO/SY9lfLFNkXtyPxB6DtSXeYTV49NtAvWPV46LSBnMqnP5 ++/Tkmk+sE3Lx+sBMqe/rpBeZM31fB9ShS9FgDGfE+ARvzcuQslYNazdT2KVeu+5Tp ++qSN1lhAW18Dwo3r1IpnhWGZ5r66TEEunhGI+mX9GdkDhhFiHHn3tUPiWSh9UAPH2 ++W59/c7sY0Rn5AmqeHu6F2b99ScRaLhkt6aFNnBAcnrjHhqZJOl4UOR7OGL3WlNjN ++FXfCzJ3/+lA+NNEVWScb4xs6RNQRnJ9NHyfdSJuQQM/HXhaW1nSYoFS8nKDpenXA ++8hb3gbrGeB0MybmpGtiR4MhJD7FWnH0uQsA4dOrrx2XYaPUBZGtqzvrIDmzO6jv1 ++ixmuSyw7nZSYqT554tPT97oBRPHhQVdz7fGBEqxrBNJR1cQjS35Q3oes6jarzTsu ++z8REC1QXZtgbWZvlm2m0iwKhQItqOfSnlNkL0IUJGUF8j3Ijz/fbNsfPOObpQCic ++ARz1Mnq9ZaDMrvMMpJHcMhYe3y75zuv9WODuPl9vNVc7KRRWgqVDmBHYZqHh4M2w ++T86WrEbnbNEHHPhXgSsaKYXvBD7zWocfQ3r2HEstHj9AmoqslxIDptqJv/8Lye9E ++kbv+d48oEkStDIfa032Ha95zsMp7BuvWStwnOG2q5sCexNpQdw3Mp7Y2oejVKRS8 ++Vc/icnFu35VxZLq/vBEFEDjzbCQ0ayk+GKYWyAxW7gsmWtSWDskv0WaJ0cNj5u2L +++BsyzY8Hw7s= ++-----END ENCRYPTED PRIVATE KEY----- +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.der b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.der +new file mode 100644 +index 0000000000000000000000000000000000000000..2ec275f143a9bcd1b9f17cb220140bbc17ff95d7 +GIT binary patch +literal 728 +zcmV;}0w?`2f&$bqP6i1ohDe6@4FLrWFhMXW1_>&LNQU&90UlY;ErM%$%NVh +z0tf&w3BtR;`W9zJI|G!laEfJ_H!|*Cm-l2p`RH`2!_XMk4~o3ci2pZXjycH4$nZ8@`B#winYFo=w5k1=PHeFC|u2{9HpVGXm74;h03D^Btq +zw}#aR+nl}1Tf9g2a{N(3&_8HUW%kXeyx*A`wbj*LIZxfH? +zfy0w}pa@HReT1;U6o{mzLHBc7uNX(_2ZKeJKpOk!3lRJydc{T1SasXspCP0zQiuzMvlc{bd^{DDb99*VW(syC- +zj+=va7!K9qEc(s%pXdWKVsLROPWhR4g#cCO^4D>~l{?!>vVo*0FGvBUbh+8BbA&tO +zGT~(mhpEUc$k*y}pr$PitycW1U4_TgQ9=0S8*?9_ifH%|O8nABYYVOM{tLTkXi<** +zqq#Wjw;!j^jpSzrc-HM);*WEk|g`|wj^R%mzA~W(Xgiu+eaIEDbRLCEbnmQkY +KfKkKkx^K4em|dj+ + +literal 0 +HcmV?d00001 + +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.pem b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.pem +new file mode 100644 +index 00000000..95934548 +--- /dev/null ++++ b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha256.pem +@@ -0,0 +1,18 @@ ++-----BEGIN ENCRYPTED PRIVATE KEY----- ++MIIC1DBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQI9ROEj7BZDIsCAggA ++MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECD8QzMKCoJNPBIICgG/g7EGQ8k7c ++5j0huNkV3WdtH4a3b5w3xD5mzGy2LoTaM+iLdatb7JSA63v5KmWwYI9WDqGsbAfE ++gApGcoAkXtb2FlnMOb1azjDHVkHkMGkINKD8LvwGEb5/eqW6Qk1GS6WH2q7IuruG ++y77wsxkk2gLJcdO8+k0aLMZTQ5lyTm3d2ap2f5QA78NGo0n9zJJs6JAWsoXfdMZk ++ShrYwJWaAYDlFVn3vne55mC54Omx1wCqNM+0kkTvbCS1U96FYNzbvIZe1gaULxAc ++GkRIan8Mo5da+2jI0GZf6w9S5E3f8zi7lltGlfmcN4bMZR3fGwpAdPx7oW9j0GVc ++162Dmn8SS9tgT2pWeDb1DjjabeSc5YzMIJpblMJM6KB4g2GpKhuWNtfHLIxR0M+7 ++YTvmwE25L4Oq6bOzuM4lX8rp1fTqnOQDmXHIB7PO3w+kh2nxUwOoB/9nXNlkdUw6 ++CbsKOr0MV98Ab8pTvwhZUm3UhHzONInDkHH5POHqqWc5XCfpW1fekUuOIkr3yPrt ++F1lY0KBMq6FMcMm/aZDAaM6rB2yLzfe8ErtA7zwkfb3j44bYFFjo3WiaaBUnpmps ++oAHdDqJMpsfs2sQeEa7jMb6dGUjlUU/3S+nf9cpQAH2spWbDMhM5Sewc9JpGDk4w ++6KD9ICHr+FgT0sF8hTbBZifxAeuXuaq6r3LGaYNs6EvADC3MzSNu0dt2ZK4i804O ++y3LSXX/5zVqSbmtQ6NW5oL0bAR4SP+QLCJtXYLI0n7WWJwesFokW3ZWgvOJe40gk ++9oNQ8DyBRlK8ier9K/nyS0VVo6QGxPAKr2Th960ekBWleHr4UGnTUFM/iuTuOTJu ++l6dmAeTEdaE= ++-----END ENCRYPTED PRIVATE KEY----- +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.der b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.der +new file mode 100644 +index 0000000000000000000000000000000000000000..106aa99de7e8238acfef03a40dcbf05d2d0123ff +GIT binary patch +literal 728 +zcmV;}0w?`2f&$bqP6i1ohDe6@4FLrWFhMXW1_>&LNQU&90UkX_7#pQ_8xu$ +z0tf&w3 +zA|V}I@JRieAOg*4O-`E|X};Wd==p2=Gukmo@{-VwoIC^}vIldWf>tFnw|y6oFUJCO +z{11~q6}Cu-nCOdEraPy&i(ccG&J%9Pug~%`0dZv=?0kn!+Q;Xzf2->zDt$v(b9_w` +ztcela+b%f4^o#oy;PRS8?3T9jE&pS6OW?#H9mH@<>ML!$OJ;tkCJ*9+m{Q^pht^j+I(&+gr4XI=?`u+RO}{F`-`7Wz +zW)x)LLDHHSQNtuS%Zh{9)u}!bJZpx3Bl~v8Jf<1ioZy($*cFLpKTZVdB=PhDX*8Ju +z26GsqLIBec*>)8c&4f|FPozxFbPONn|4{5{EaA^$lw=gmLk?suJBxUKbvObA37wsj +zscr1hm;{9%B3J7J>?kyiqbHZ#dMwhEzX_jq`3_VnAv1JVKDQk>P?BIm_Bkh(=uuZi +ztJJ(K{|S^?MKK2!Xjom;`~YdX>T#3xt=q^QXGAoih*2x-M|T2A=^BF*+pd;ncvvPl +zPQEM_V%TVnM<6WT6&%SB@Wk6Su8j$CFy4f(&k$e%y$MPK-k>GN`-?vj^PVcdGQD9A +K`Vc1nEizwUwM>2h + +literal 0 +HcmV?d00001 + +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.pem b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.pem +new file mode 100644 +index 00000000..3baddefe +--- /dev/null ++++ b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha384.pem +@@ -0,0 +1,18 @@ ++-----BEGIN ENCRYPTED PRIVATE KEY----- ++MIIC1DBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIwD3fpS8RxVkCAggA ++MAwGCCqGSIb3DQIKBQAwFAYIKoZIhvcNAwcECOmyF+CEzwvIBIICgPFC3z4bUVPM ++EgLGuLP6CiDPSKuCx3VdAu5/G5WjjU+dDvEYDtOrVfbBpVhgGAYYuhXlI2bzoO2Z ++RPZLwmaVZMUUPqHjNZHND0BPsHnb54Lyw+xnhIvipYpt7m3+swL9JUzbK4bImhzD ++3UdVYaCwwnpnAcTy9gleqoQ2ikCX28Oc+bZ0VUUIX+KVbVOv3gNN4w5uTyUDRGgl ++AW2E2IKoNNW8oQzZYatdSMMb4Qu09HRevWpUkB//XGrCcC8aAwynxHrz7hSrJYbt ++SJVNsyl+djFRcKg8sudGUPua+mYWEecCs9/MVataWfpnT8hPtPUAQpyRpC9Yxa+c ++yYfl+7jHvJk54Lw92P9YAb5k0T57+G7Fpxi6MaXn6FAMqFHY2dJO7cxsg41qkF6A ++sc3nvcxAxj4gtCgV0d0vVLDjbgjcAevLbzOsJVDzB8y2i6V5l+2/ffV6DjjYO8Hb ++jVl6psDscX4VfX1zkEIyTF2P77luZ1gvXuFDw3+y+HpUAAE11vvFH1hmj7RR7uH+ ++Y1Y7gUvUA9KSvIStsSzfdcQwaZTMNdfUNkPzKHMVZJNQ2KYkv8F4QSA7qpC07Kt9 ++4iCj+D+8nMxS9s2xsZo3lgksB3srmn6ryQimEcLb/cFWbkTSGAah81UOIVtNJT1l ++Tmwv35rSTELD4YVWz7CHh9nE2JxeLg6WmtlzF5ALxi5L/grZUN8lx6jNeC8/O8fy ++twXR/LD1xmAn6wxcxraqnctBqzknpOP3Eize7pCDpOJR0Z1WaHvULez8G2CedEo2 ++SvU8YqnJ44ceom2V3wDS4+005Xq3zKDY6xL2htnDHd2vOPstGLfHxEppNpjBqa9A ++qj22QdMCv58= ++-----END ENCRYPTED PRIVATE KEY----- +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.der b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.der +new file mode 100644 +index 0000000000000000000000000000000000000000..cb158b59e3855c228ad6bfcf280904f87a26e0d9 +GIT binary patch +literal 728 +zcmV;}0w?`2f&$bqP6i1ohDe6@4FLrWFhMXW1_>&LNQU&90Ul3NPR|`k?;2c +z0tf&w3Kb>NmbbK?H&T*kc>;_L^5E1>6idd%d5sG%| +zDZwYjAm|0hRd0gw16$l`k1Z?vZ@~;cv39-n`z)-%13|*;?sd|gvrjh_kJLSBCpSo? +zMj*=Z4?n5ExksT7)r<9OkywX%(UNCsP!}x5^hlR8W$ccUn-tk+11{q8R<^PB2fv_n +z7nVy4-i@!(fwwZ25f3YZbXO;tjVNhgR3oU5T0#XD79l?^K+eW7+0enQiL~KbTY}|T0P%xntz|&oJ!dWqQPuT%>Z`MbtDMJUc+`iuUyYB-H +z)`2$KMgBo(%iauwddm@l=e84 +z=VkYcot@CDYnj?E+bt0GbS=jA6x5Nn$SV=`x^R#<7H-CJ2$e%G36D{w(MU?PnG=9N +z`#n+hDbuR*x6ybM#bee~ncw3mm1o2i|LF(24cZ}=ca{#a&Djp;bVEQONL6XAz86%L +z!`KG)EQ5Z}25(hkJfDzIoj9#R_cE_| +K7fa|51{f%?KunPU + +literal 0 +HcmV?d00001 + +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.pem b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.pem +new file mode 100644 +index 00000000..95d946bc +--- /dev/null ++++ b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_3des_sha512.pem +@@ -0,0 +1,18 @@ ++-----BEGIN ENCRYPTED PRIVATE KEY----- ++MIIC1DBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQINtUwWQJ0GUACAggA ++MAwGCCqGSIb3DQILBQAwFAYIKoZIhvcNAwcECADq8lFajhVgBIICgJfbFYo4Pk6o ++m0FhCL1/6VwE8oNU8iRbzYLs+ZjpHDKKs72N97M6FkPgwYQmcLBiJgYDfk+otjIy ++Sv2QOklnEi8Vu22c+5P7UQxbobSf26hGgRlvue9xwBWylnBj9VwvgUAhbKUKJDW2 ++lcUryZBQM9vX3cpeJUN7DsRFA0gyYjuoNTm1+Y1G4UqZcQUJyIVqSHA/dKpitnhR ++xRNP/IkkY4GxTE3VXSoOm9KecA72iAnBdzrO3yMx7PkWUotZolMXK//5eacginYw ++dSQIZDCnodaC0ugH/7QuKbe3UUyMt9b/a7Fx6c8CiR3xA1sJt0N9xGK0M1+JFBqr ++cewSxvF7I+IRRE6buo1S5rqzBTZFfGArvyklBKgC0UmSFu9B25HcQzrBEXMPneG7 ++W736jjfwclwKwboCXt/gHJBM69Pf2Y/Otjf1HGFcly9D+P8SPq8dkBSp49Ua9RpH ++gtXpaBiNZ9Q3DIXMu1U9wLYhYJZQxU+FQHuO4wGR7h1KdSzZCg84E/T232qDr1Rf ++7vLo7OHsAtQGU1pZGGorlTcY8KKwdeyo9Qk31jIZf4DwLKu+Zk1zICHrE1kuwNVE ++5dcIIKA86Pu4iw2i91At2GJbGJku9j173rSL4IHV4ESUKKoHMH2ncBfjcTtjBXXj ++FyauFwU6qFo71WXRMGKZpZgRenK2Lyr8/e1g/nEbHDfqN9ntgDlJhqku6ROP1Jns ++WzqnWRquSk93p0xDMZAXxUZSmCzGlBr5xPhCOmHp7YWZrLmKVdWXM/6MFWpj5KeW ++raxqwtiL0gU5wkKUkIxvIrjp0PqtU2q2dzwoL0blAXKEqU4v1nMeW2qhY30qz/rT ++wu95SzZgh+Q= ++-----END ENCRYPTED PRIVATE KEY----- +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.der b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.der +new file mode 100644 +index 0000000000000000000000000000000000000000..d29a1e69c87016dfda7bf260d80a2b721bc56b4a +GIT binary patch +literal 725 +zcmV;`0xJD5f&$SnO9lxlhDe6@4FLrWFg`FT1_>&LNQU&90UkP{*EfDX^(&c +z0tf&w3ikSmuYucgkjNL^8_S!!!$t@lKzZ?Q&su4^tGj(KiMcy +z>AieN0cZCBzLh?3`5lJ>4Xn`;1P076HZM0eo8_)iy=}2^#s?jP&h{Kda%*s|8YAXv +z3ZlN22OyP4pXH!J)4t_v*AP)N2P^=uJQssptRwPfN_%6W!`~LNHLS;V9IJ;Z!*ECt +zHPO&r8X038Qj}R4x6NIxsXkE^B4<6&KoyP(KVlDmJCu%E?^R6XJ

@Ahzpo>#Fp}wVx$N+d`grh7@@H1X-X?X0p +zcTKONM~r8UQm_u$9qOHK#&Ocph{A|0dlu#7>jc2e%Q6cF0huL-O#eMaxs`%R4ebij +zDZi0yN9qz5fusDQ7QAc_{fPHfxL{98k^mNV6$JvY#47rNxC(JKc>ky>La82F?30r~ +zJ#RZbJ)($aZW4a#Z3qB&+uvKB+?;R{x*ScKXtuIl +zMj1@AKGu^{V~L&knK$FehRq>N8F;F(EolHwm{T_(6Tl0c*O46blK~GwijE)lzjng0 +H>vXWe(bq*~ + +literal 0 +HcmV?d00001 + +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.pem b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.pem +new file mode 100644 +index 00000000..9fd035c5 +--- /dev/null ++++ b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha224.pem +@@ -0,0 +1,18 @@ ++-----BEGIN ENCRYPTED PRIVATE KEY----- ++MIIC0TBLBgkqhkiG9w0BBQ0wPjApBgkqhkiG9w0BBQwwHAQIoN4P/1fEZkUCAggA ++MAwGCCqGSIb3DQIIBQAwEQYFKw4DAgcECJntwhGUq6HXBIICgB4ql0o/M9lv7Px6 ++DUZBn1QFddPrr0slxLK7CoR1gabr9FI91o+dpyejeLHF2VFUYY3F56Q7f0P0b6Fo +++OekgX1ySvsM5EPGZBopXaAnAaoiYuZRSfiLeauHHCC/eJx5SH58pwqy0rY4j2ND ++U1dYB+AVsdpRVv/MOSn6MblqauywTo3rIleK8SsuywV7NqIDLb3CHWEkUQEHJoFB ++NfNb51u3GETcrYWf49V1WCbftPHj6YHlsfmUwivGCieAnNckJvUXa2TTXq+tWpO3 ++8ar1cRHCFZSgx2chTgY+S5KoXcSmTp1ilNb0XADQYyWGVH3FUo1BBVk+iwNWM6vA ++d6yhtdAATsdaA8e26ehXsWDUV5OVxctgjX6NVem7hJJEmGxRLQIYfR1Z2bsJp/eG ++ZiweIIhsSMyKQI1jTBV10VwX8M2ovffHfAmtxbZKGVPVLnxW+ilBy6YMR6viZW/1 ++EPVKeKjqlgZkhLVBNgu9WsIeP0I+RvNPMaRE8j028NW71WGdgwJ4Qb+Z3687Ob9q ++tgNwp32isZ0K99UX6fUj9sR+kEcF0yMaysE1PXJd56HNydftORdq9o0jetZadlE4 ++WYEvIfUd6U4nHK6OcUsNVNLua0XB1hH+K1CcPgY6JV90apsE05fP6oncPwDQT25s ++8wzGpitug30N8CtH/fS+4WjJo5qa8To/JZibg3KhufeRMYKLyflfV0cp7nMtdbtd ++e1CI6KFhD+oBLzsSdG0BrwaSVfxsayQQGuz3FYx2NlcTRhgXeM13pmqmv/xoMYqE +++BC0kiRhZ0yIh7Xpzg/FZNjbuQpQvqbYmlqFdKsz6YjeKcqvGMI9iav9nRA+ag3Q ++qUmDliI= ++-----END ENCRYPTED PRIVATE KEY----- +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.der b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.der +new file mode 100644 +index 0000000000000000000000000000000000000000..7f576bd16f29b70f450f515fae3912e520ce9c3a +GIT binary patch +literal 725 +zcmV;`0xJD5f&$SnO9lxlhDe6@4FLrWFg`FT1_>&LNQU&90UkwRi6VL+AS +zhhqw|Y6L;U58(5&u~ZS60S>504z9S!{-M9I|A!jBMaw%2N7kZd`>oc`44(Ud>I6G; +zeibpq4KDm<&+^zw+BcWtnoysd{27%KB|nx4Trc}bL@ae%6v!%VxZ=mr*2$k?B7Qzp +z5C+baLOI{*NXzV%@KFqC3ug;8_PXsBJDorKG=IGuzIU#Y|Bn2lncj1;eBfq~KCX@m +zw4sHXVhol~t_%5eb{tK`0eD4D*l?2!aIta^FMM7)jY#3WY4H%X{ZX%j3O|LGP5RN@ +zPj`ms2R0J6m=kYE0`lyK3yOuoq_ABF+pB^CcJI1_Thx-l4H=`u=HH@Wr!sk###k~@ +zNuSChRwe-0c$r7nB%33AZ2Dh8w_peNurm)7!?e4vzi6o=DR$r#9JYYw+sLM^pLKPc +z4lmu{6VpwpCt1TN7qC}?meG0*p#LHQR302Jjkr)-F5KX+){F_eo4XpJb@HMnZ&>Xc +zr?|pri~>0B*E@*w)@s;3CFCs!@6cX6U}3xB_*dL{`1ykbDm{tVi4dL=`NNV}+_3JR +zoHdmN0snUCUlRP}bD|9gDrt(r3{}p{GB=mBv|Acg?N->SL(wvU^n(+-dT!A{Xds#UkpxB9O0-OH#+l5j^DZ*AG!&O!fuUj!Lm&5s4LU +zu|O85j?wavhPw1Y)&xJwN>sd*&_1wTX_6>CATbRm|_{C%ldmM{qmbP#g0cFV5MA~xiBYr@N +HjSb}5LornW + +literal 0 +HcmV?d00001 + +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.pem b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.pem +new file mode 100644 +index 00000000..22d39e3e +--- /dev/null ++++ b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha256.pem +@@ -0,0 +1,18 @@ ++-----BEGIN ENCRYPTED PRIVATE KEY----- ++MIIC0TBLBgkqhkiG9w0BBQ0wPjApBgkqhkiG9w0BBQwwHAQIDhZ7Qmf2HYACAggA ++MAwGCCqGSIb3DQIJBQAwEQYFKw4DAgcECHj4bQ/zjLVVBIICgOZGVB9PiB/MTUYA ++HdiMnbJ3ackg1x5NBk4Jxlae/4WWBX9Cg6uGMA5CP6XlzhlFSDji+L7+OatW51/A ++0nREuJWAoAAlayQujwuXN5YWOHzlf8007IHzKQqGtRTjhgGSa5kddXzfYvqLVsdV ++MAb+8UZgc+6wO0Ag27rEWjvx4HKUzS03sqVqF/Rl22oK0VMbVWU12PqLMMBpL6BA ++19MKsKDe6yO4fRbipT3aJ0fv6RW6RESWAXc/9dG/P/0kEZXvi4OwR0dkT0s9m2D3 ++7r9Z+0AK5uSRU/ftcYIf5ARvIOLltfNN0TUo58I+f7CTKCDLUQbEfDLsHNuGaAfA ++YRLyZukS1fppZiog/JtwGQsIWMChxE4SVThmYhqJ4mCUA3I2SXKSaS4TMAPrEJm4 ++onOG2NSgHQWdf9cHNMHeGj4Ey+qgDHMYUC49ScsZQecdd395j5T0znIJk4ysawGr ++34vt8HIn6iCxp2ZbHzqLm1qeV2Lgme+G9IxJi9+UR+eL0BZdaCt6tdyF9/4HXXTz ++hrcHC7vFVVe1HnK4B2AzO2uitGE3aEodRertqJbafWyOfip6Agjbx/Eu5IDFFrCU ++KxgZxV4agc3/zjwmwapVEZdTr9pyP/6HBxIhhd0KEX9cVMauCcOA83U+iezBaZHS ++frP3GVqBs+CzCx4nIXiCRacc/pf6tec9nL7mbrUtT+lQoCOPcJKcUAZyW305+5Nq ++mGho5y6i+AsF1M1l/Ar2gUGMN9//VscombNMRFXUE2Q8yL5//gJRS1rN7U3w5dRI ++3Bk6pbMp+RlbtzeS2zA9cuLGWtxvdblYCo90p2iam8zqfDKEZ4dFfJlPZvRw2hot ++7BkFp/Q= ++-----END ENCRYPTED PRIVATE KEY----- +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha384.der b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha384.der +new file mode 100644 +index 0000000000000000000000000000000000000000..4445235c8391ac6a9b16a1999cc4b6e422272567 +GIT binary patch +literal 725 +zcmV;`0xJD5f&$SnO9lxlhDe6@4FLrWFg`FT1_>&LNQU&90UlQX*^4p%k*Oc +z0tf&w3A +z>|>be$lU!@4zr56BT&_O-^jC)e6^{yur#KJ&I_H5kRCr&a0jeSF>*4*?9%XO;qvQj +zF83p9d2>=jYjsau9FbBHM3OpqPZjdgl2nAz8 +z+`|7UV2DW+ +zRI|Vj-Ua)H?0Pfk$fML{OA1%z%Xg{5QlqqQD|!j-!*7odE`)@pAi^Hlnsh|13uX>I +zfOg3Tcl(U&i7&(av-rA)98lFo+We*&beP2|!k@F!QQe2zQ)aqJ{ox?)4OVx<|Hlpq +zEru22&;q|QeE6@RvzG{Jr6#jLSN+VV>Lj(HqD0jxyY7bGbB7>^`9$87k$%2Bg6Y;8 +zl#kCzeI5+pmtT{xdDiq5F+>}6iJsMH*usFLsjlC)K#p=r$Bp-xMsbgWtP1#WeEcr+T +zl!~w?eMG~3_;u(660^;g)^bv;YsszqWyo9lU(?2b)_57(O3_0Eg2AtDvMN6ix4M&w +ze|5Pw)p{&LNQU&90UmPfR3^TK>=w3 +z0tf&w3!B1cCy9k1yIyRo$2Rqx`}d +z#_Fb}F-5QZq!`>&U_Kfekbb!hBNTTL>y;s?48oi~UEPWFNm-NsM +z_6~C`#+MiP*gANV86KKnJeWA3FDxPgvgdrT(-@*(u796YfE9hdXQ0yuuG<@`tXrMJ +znfGAUB*JG{d#dLIVy}e +z%wBOXoivu(V9*PVUP`T~MzOu_&)QT_lvRMg+c~}{ +zG%AL>5LS1VkVzNs6J*GEU%%k)Js=g5)OGJM0-~boX$j;QG4Mo*(8S05z*A-!zy4`L +zjv;x|ZLQ0D_8fHXT7o}Gw=qg*(w9ghtwwpF<*a>C9%ykwt4^NLsHvG<{qoxR3(lNN +ze_yVEJPB>NOIW_Va+9rV*;vs`M%n|bWL6vJ1M@Np8J{-xV~?$f1x{U|k0=*sp2uS% +z5CV3V*X2R@m&{b(*2ngpXRQDjU7^WLhzA#y9UjWS0)z-@x7@=%hZ)&OL_O`fs3CP9 +HX^QSdO(Io5 + +literal 0 +HcmV?d00001 + +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.pem b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.pem +new file mode 100644 +index 00000000..12725abe +--- /dev/null ++++ b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_1024_des_sha512.pem +@@ -0,0 +1,18 @@ ++-----BEGIN ENCRYPTED PRIVATE KEY----- ++MIIC0TBLBgkqhkiG9w0BBQ0wPjApBgkqhkiG9w0BBQwwHAQIEfr61PLRSswCAggA ++MAwGCCqGSIb3DQILBQAwEQYFKw4DAgcECIis3kdV3MqyBIICgN8cVWWhMwix1YF1 ++5atoT1U1EWGOUokVtb+oTlqJfMvnZeCHc6kYMwbWvTqga88AUhSssFL9WaXPb67a ++BlhYYkijNdOcu7m0V331RWdzxGAYHHv6Zb+43+/a3fx0hYwWsAKBLKnYXbxAckA1 ++NSuItKnyrWCprvhelNLJRBY3aJG9EeqjIeh0MLFMbIhFJosnB7oMliYVu4DxnMNq ++JzWoiBHllgidjZm/vTTmfH9gL0ya6TwBgmj4gOvRu30P9wdBPxS7IZi0xj618SMm ++eOSVdRpuxvX4gzQ0TuWTzFIRdhCFx5fL366tVca/YZ+9qRO5oOqAucVKWZ5zcMVp ++yD1SOjMDP7x+3LBzIYAYb74kHol8ejIQM3IrO0nzANer5M/KWIRbXoDuyLzeiqrG ++FbzpL/kAQ37L7o+GS6gyYgN0lQoZxlgTt4t1+DCNAMWh4xmFTNJgXB6a846u6c41 ++K4GQrwOXGAr0pYdNg44fB5fqw+594VKxHEa+7MpMvzos4wsISkrCjbFRVCuO78HY ++rwsD6pWtac02fg+8+a8cTmUXGkzoEKE80hTC0r1SO2w0RabyjTHxRQyZtcCgavkr ++E6Avbabq3GDdxT4IpTI6LiDKFaRUpxMnTyToTlGzsi7sjELHDqgOw4/PbTeNeyJH ++PPqoB71p9Djitpw0plUoO9MWQQPWB7ro3W0g+2lS1782wTk+9jWBDVdgDV8+FYJG ++cr4GxoADHFOt2viKf+7cq5ZP8HxvLfHF4kULslea2AM+3yTQ5TTAahCbGOPVJgaA ++tcqOZIGpIxk+aRceZRrKPerXRmZvRItbgZ+QUCw3kRxgzanOHB671jp+VORMFzJR ++jhpl0rs= ++-----END ENCRYPTED PRIVATE KEY----- +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.der b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.der +new file mode 100644 +index 0000000000000000000000000000000000000000..56e17ea30dde27fecc6a96a819772e07593e7d20 +GIT binary patch +literal 1312 +zcmV+*1>gEGf(0BfP6i1ohDe6@4FLrWFhMXW1_>&LNQU&90UjmEypNdV`bk0 +z0tf&w3|i(fyyQD+flhtUi@@ +zOulBXzC0ixz1cpN5PXcXr4JLCKKm`G6|Thzl|Va32%EQ8TA9n5w2P!yQULQDYCJb0 +zwTi}BXu)Tk7wb#p#CaO!T&>Xis5 +z0kn&or^6du;RKZ)tBHB`6a(_(;%<^GFn1L+qI87x}h!JuyxM#e}wH +zvmAQM?DesX72Z2Wjt6BAe-Hxyb-YYQ?gG{eQFB1e6p*`uoW&Cxt}4`ZY5vG)Y?_0T +z>`8XXOyg3u?B8cXhTQoD*8=q%lFY8IJn5pQIT)!AoT`+u*+M`B&P8u{Bkg;ch`~?C +z3{ri(mM@^@-`DREhrIhkIdeavzr7*@isY2vKu8H%;c@Y +zC6~YF0^rvw*gada|2#hE4px#%O{v1j(xJRQeQBh>ziw|MorlWMdO*1ulArXcosc8XMA)+L-F15~W2c76Csr)w)GRdF!WY +zv7=1ydC~x0UVHwEtzpL=iM=aPJ|28)G>?=$$kU}{cBJH~GL+@&`#6}jEVTKRX7I7~ +zV@gTeEG@Td=p<>XB!=11azoTHgGP^~aMA;&*&+fSinf%esvWzZ~IwF>=9C`Y2o~`^Evsey;6u-ib`*mS#+!ogg +zo{WW|8$Ga)FvM(Yp!MPu9t +zHXE1CH8a>^?)1=v!Dg_pp&!?Ypgqh+@(?Vw$~?@72-ZcipeE8#+ojr*nMfB;_7h{F +z9F(F5%Q1ugWN{54m`BaHiZ?28N|F7C!_t=7#f#cQD33;AyVfA_;(n+j9gwiltUr66 +z&d2$hO8?ug7q_Ju&{E%qiJfjJltFR1eI_%*sE|j(a<4<<>VdI#TZ08oQ;%Ukk!MVr +zs%VlTie^!h86pQJ5xhMh#|$#5oHP$D1c+~I?<7PDI^-!ljaZY#7KqfI^-hX>pw*KP +zN6pGAEt8=rEH4>kYmtEr%|eFU-lR`x52v)qFr^s0t{OgL_XD%8sBZ|NK4FFR^?sN< +z{%1FU*v82^c4S!M9yXX8{wvGpVxGyv7Uho7?;Pz4V{b92LHg*LW}qvvH&4B|)wIXp +WhoI(N_@%t?rO{Ptb=-5^4%Ic2`EcO? + +literal 0 +HcmV?d00001 + +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.pem b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.pem +new file mode 100644 +index 00000000..8ed64603 +--- /dev/null ++++ b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha224.pem +@@ -0,0 +1,30 @@ ++-----BEGIN ENCRYPTED PRIVATE KEY----- ++MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIur3B1wRZWJ0CAggA ++MAwGCCqGSIb3DQIIBQAwFAYIKoZIhvcNAwcECEnKPmr6wiNuBIIEyKNZuEXIk0Eo ++AC7KnJWaEhSDsr4zte/uGDTeOGRVT6MreaWUH3i/zwHXsavEBsw9ksLYqxXsIeJ9 ++jfbn24gxlnKC4NR/GyDaIUBnwGlCZKGxoteoXBDXbQTFGLeHKs0ABUqjLZaPKvNB ++qt9wQS+zQ8I6zSQyslUfcDr3CZNgHADdmDFiKisAmT1pbtBgPgzmxLNSmx9C1qwG ++ejuZ/SJ0YYAdRPkDh1p2yEiAIfRVFTgWcjltcd69yDk7huA/2VCxWJyVDCGrEnlm ++UJyybUcXXofneBp/g0J3njaIbIftmYIC+763EKD/dqVIRXVxrkHyYcvZ2nVNUT73 ++Uflk+JuHIjTO4jHXiPcaPdAEPLeB2D3Geq5ISYOvTzOeurfD16Y9hrN3IHi9gedm ++JTcEPkAx2hcb19h74XlV5tcQ5ImsPgLRl0euODN07+nj14AFxCQhuoGx+Yj04NkK ++dV/l1rLsbmLiqr4n+y5ezGr0GJARVinLCBehptzxaipXPzRW71IQSddbtlSl1rz5 ++Npv0HlwGgwTacv7T0ZdWncaw0VjxjXAwHBD82fCiuH3qZAXEa0M4drxROeIncart ++MIky9qIRjfImr3oh6GLxNBB3FEFFf+23CO+Qt3vrh0j8sVYn3cpbgHcqv0q4fca7 ++Sq2okw4RjxcDHyLgWiR20tUkqJT8FYQr0u0Ay+LT2YVVO7+EQVqvlraQcOS4Fkfa ++Vnggn6sdyhWWCV1rab0v81qZYBvRoUK/ynICKCbXaJ8d1mirdNGgs3FxpVAiUPZ6 ++LYZ21Uwtj9OoeEQ06GPKq60xHjUmTsNiEkh31AIlSAgdsN/0+pUiD6f1lCWfiLUi ++8MuFUDXqkqXAvnJW2/mKrLvcx7Ebm02rkNw7AdAnUnEx9BGxD1B0TVZtRid6mPSO ++kXv7adNyBH7qoI9vGGQ1ptNRcNxhxqgGgtfwI+0mV6P6G8BJMl8urZYN8aAC7dJX ++/k9EICTUcOU6nIyFFe8tk4kkcjdo9BNkgB4JjANT4ptR2w950tYVqDMHBm1eKPBC ++bL3SnDDm4Cplsy7zAdUPsCe7/Zk3K2SJwUj/lDUTDGCTtq4RplfDEBWb218XWgA6 ++rHgi9/EFH3YCZM8EiE9Mnx9UafdnfKhk3tm3I5nKo56C54os/EKL8W+lhXYdK9dz ++peehTsjEQjF0/1OE0097XlCShP8E0bdluoFkD8mKYC7mGv0muJLuHdGMEaCKzKoS ++LBKpZNYdOu2wlFfCkf8zSWO4eZYKbSUL88AoEM7A/kquQsQnb80FkciPFazlF9lb ++ihxh3YD+TNH58zpYvqgOZkBflW4kKIYbyWOm+ARMq+eVph1aNKMdzeW7Gmf1Fab3 ++SQmfuEBAfS8u5ghW3J57q8gSJSGB8bpYWAmNGGeQE2g8C6HTxJ34kU2HoFLo8a1/ ++cqrExWl0/lkhwqc7PpvJbKIMxVOOXtVMrzG2XBCkfQSmtwwOqH1g6AZv+6sXyLZJ ++PmvQ+R/23+eDqp/lymz0G6F6B10pldgqt5FHYxGaVEp7GIx6L+GtI6G2qGxpHJA9 ++x//r3gdd21Fd6y7qHYOLO4fEYAe2sN0mJVjxFLsg9AhCzfxKEHsit5LMdTkGFRG0 ++XGP/QsVNcWJaYyaKTXaTCQ== ++-----END ENCRYPTED PRIVATE KEY----- +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.der b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.der +new file mode 100644 +index 0000000000000000000000000000000000000000..847de7a637e15dbd40950541ff5fbfb251255f45 +GIT binary patch +literal 1312 +zcmV+*1>gEGf(0BfP6i1ohDe6@4FLrWFhMXW1_>&LNQU&90Uj-fseZxA@*@Yn9f&|FNIhn)_E9dY` +zp5IA#Zal1)@vtOnxxy;BbmTxQ01}Ya5+>nzV>(Y?(m7^?C(PU*LVhthb!rd)diuXobR$#L;YuS^BoIghj{H +zEn9YWg1Wa+E_v&UR#FcbBMAnukZ4Vl9^*QH909)9s?-qcj+l^UdagC~OaLyC)A@md +zG&J2;LsE11UN;oDeBuO8kUq&hLKP+(DgB0^y_Ey^ONH*xmNCx}Ysf!G?hMBJ7yqcAWCizgJWoN-W{(= +zk(lvMO)sivA_$bAe}|ZVeFY+`uA(L=(_t5}AP^Bh(EsZ8Wc5cgBxb0($N7cz&EYt4 +z9Kc}cAzv7@qm@QI*R4qMZS=XueMG_zJzEis5}~vhU6WJ(jYUmS+2crQL7YKPNSD<; +zD0$b8=E9Qs^lx~Cc?&S~)GfdctPZ)cSw+!V$_?kKcl^#>Ibp%SDja~FOx3+pLF}Lj +zN86_Ina&4$Gi#09V!d5CVbmJzg$lY1D22d>D*mU1N$b8>$fsuYO<_cMn1G++7_5Lr +zxLf1hJp*TCQTL^)JA;7v!vlfyPZi7BS(%&}c!s!_D+LmR_aM(jK{pLCLIZ_{3MLIr +z>)2?d7*)6Wh&tIXYzA0)6!*XAhHS{=W((4cvEbbYQWtQ>A!=pTkmUJ0(~U*5n=<){RKnXKo#T76sl9%Hq+Fxf#1W*x +z!u3#41Xjq|RjA&9Djr_lG&1l2>Zsn(A-PaUYi6C@1I8%Be4S|>Twt^pV|_0k46~9w +zAt}OlURULK9CoOGLrO?uHaI~YUKvgrj`arT;;S3Qg}dc0(_bwm!EbC%_ePy}RV~v8 +zteUnd>et&;k#LV+oImtGO4|CAwSKp%ijHjH%W1D|;)oq~UD;^pbGkBe#}BKUZ-XBw +z-iGPhfNjVuo|tnyQ&ZNfMX_yh#DZK6J^PCfq3!tE%&d6;^wR~GD04(0!s<&FnJ`p> +z(;C%gz_UydfW0{phP-8F+D8eCkw(jJ14KTvYR`<~!NFsPFI|vr6#@X$GPw9O$V5p} +zsM#|HO85Q|5_zwJ0hKVeCZ@8DS&j)Bwn=6EzzB1q_)mPVyMQvznrjxVb$1Da#N~L| +zqz-x(5fA~guC~*oL3vH(klZA3%Jo>-LLv8^IfLN&2GiBX$D`*AX+byg01=u*lxU)% +z;!V%n|Hicy17L=|*ipFp&dN6&#bKy&7*pVCaA#O#x*glfaI;w1V#Wg@H5HeLR>!kk +W;TSo@PCc5A#R2q^wKv(pKESQ$cy#6f + +literal 0 +HcmV?d00001 + +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.pem b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.pem +new file mode 100644 +index 00000000..33a770e2 +--- /dev/null ++++ b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha256.pem +@@ -0,0 +1,30 @@ ++-----BEGIN ENCRYPTED PRIVATE KEY----- ++MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIv/X98EPvjcYCAggA ++MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECO5EBOummZrzBIIEyG+qrKhGE4TX ++ch9QUfLBhcklrpcd4xOF0FfwVfaO17gWAOp2Ukdm1MBof1fF2wU0hNG+dX+wIMhM ++/MFZWx5J0PLULmAe+m5rEVqRVY13Kxa5UJ8W4oglXVfeRkTvyuWr0Ov8E4wrh193 ++jmGXA+jAjMZaAgHWZzmHDX0NwEeoitkFEXJc3tt7WAaq93/QmtTYKH5eoae17M1o ++yiSAxI1uNzHryPRt+6hp1z+sCAcniIe0fF6GrmkS9KcFzO99yehhrxyojiFPLSDr ++Cfv8mWY7nUSFAW5UBR6KA6Ggp27FyKXKc/k9fvZzASJzyjxG90FHyIEdxw5KsWU5 ++NAAO+P2Da8aX2xctAnKxY78cFB9Iu5RSCGc92pp+G7OcdFUjXsYXr9KEX9s5bObh ++TuYGtepHEKLajFZ9JvhjQm/t2lYa0GGBNH5j1wwmfdIqZZR82mYgsgVVhyp8NC+Y ++Yw7K/rjZDgpQYSrUHGxlPYoxZwAHvbTHuTuGI3N3mS6kK4Y2NY0OLQOrVnFGNT57 ++ER2LK2PDUrk3tqTwpIcRKIqeMRayqNQ9MUsjjQ+v+yPcbwbZ78Ci2niq4vclq+84 ++tReLs/JBo4WHfdtFdzCnIqLVx2K6mjkaGL5q7tKYQoDjHxaU7Rp8cqy4d3EFovZr ++W15EZaFo70vsxN6Dkr7lkJdBbDbeQCdkTyL4sLimYKselKZZLUl/gKw2hCC8vfoU ++Jjs7td4IQ0vhBtVT46PUdLnvxcqpGoYBMiVNlGYowP0ugd2MHISFeMYytSSq4Kqn ++0OnbqG262WnuxXIufm86KTs9c/x1+ZTrAKrk6XarmbF8I7pB0jBjObZntGmZ05bF ++vJgRUDAx9sheNwPPiIM/7ttCDoxU1escT+u4l675FkHMhZDUSLSRqVNvGmt/ES2F ++c/dIq4iDGgG+MZP85S09ah5KKruDE7wvZdpA7NTWzSN/FL6JokU+GsaWGt32Hmia ++OK8F/CRtUfHFUjLIk/+v5wzqYWqI3LjorXQSV9pWmtahp1cLQ5Wba9vsPP/Wvi+2 ++m7FyBEJtgKP813YOND5ZG+NndlkUahwditGJ2XtpS4sDhFyQ50oQm6vVY3nxlkyi ++7gcCE8xOI8ufFS7CBl12pFys5XS6htkmBbMSncOoNo7P1kuu/n+CcjCnWAY1iFsN ++OkYOKDZlRdkbish4JqTe0LdRV2CcpGmDoZkMqAo/gacweT1OswgxPZqRAlaakDsk ++0z+wy1wNgJlLF6Mhub1zT15e1Q+/wHUNsAcIRbEsq4vfSVn562/umqqVZleHUfoB ++tAKAAIwee5aNB8fBcUFCqiNPFGnyuJdEy2QCu/xiFQ4M5EGGApPOoQpSCu40X8kx ++tIsIihquALlL2nx7jPvBIpasKq9SRRg54VYp+5WQBVxUSAY9EsaRSuNrkTJTG88q ++4WO5rHW3WFZOwfU2LGvjhz7SY+9H7B/A5aRuTuU9BkVnm5w9WtkS5pHU24WJ34MY ++LESH1yE99OtvHuz5PwX1kcoYKdGnd6OeNkRLWl72GeTiU8bTJkB8SHx9Ol4kVTuH ++fPsY/ekPh0rSuhj7L0kCTPJqU0+Xfl3rqWAKlpXLFzMKyIEhu9kGgGRAr7kB9ACL ++ocX/IfJDcGRqP9cpBI04aA== ++-----END ENCRYPTED PRIVATE KEY----- +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.der b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.der +new file mode 100644 +index 0000000000000000000000000000000000000000..5a7c60fe590ee880278ade7eccfce546bcc15bd9 +GIT binary patch +literal 1312 +zcmV+*1>gEGf(0BfP6i1ohDe6@4FLrWFhMXW1_>&LNQU&90UlC%Q{Y!e{4MB0{=p!!Yqp`4SQ-}}lNLuPKwhOY?4 +zNglW(sA9M}h~_=5oZF#93sRm#*2yPC9uDw|YcQpYFOoKC&p$q=R#a)Yn*Y~BDjQ;i +ztl!Rj%;X%O70|{{Jy3BrEE!5Phk^=SK$^5m1`c^)$7P!&w8b}nZ5vE}qvL1lZmvwv`y8B;S=UL> +zp#b-&VoDtl$bAfs-#ugfavEEt`uf+&--8a*%{Tw7^MtF&DE&hv1Y +zB#SWy(Y@HkuiN|T(JUSf7~a@&+}s8~Y*4^iw7kViBMZ*NE7zjTxNI|#@Tgh2x!TX! +zxDy&XuvlX)NDh41tBC$?l!+{n(;v7;(fyuAN&kFctVSD)Y#L|jCe>XqK=yresc~Sg +zry9JhHx94dW<|r{ZXwLA{lW|)+_h1LeARhVn0)scTU~2*7rm0M +zCXn;#+nfmh+IQ0tkpFHsnMSWeSWPD3i0N0D%%AHXOAxVPR>H0(fNz(#{W$ew8oc7> +z88W=rtj;XXJ+8+w(mo`E3h$=~`!Ap@eO*4m2I96#<75Wk9Cf{|e6dqGK1BwkT;mi@ +zN=ba26A}HyQKuyDToTp#_rz3I&u{mxiw}FL!P_zzF){!BET`DK2lkze?DQAOI{nHG +zo1M({SIN-61dN6!l)4f){?e$Ar?xi0(8>rsabWh1X{rsq +z5BedQsX>-By{%>bzozQrMv)QJujxLL7WXy0Y+2F1LV^LrSGH3Lmf$ExGf)rjT7eTw +zat0>n0yReol9_lmL)%T>?G6*UhJ;BNc~RHJHzKe2vw^upIpG +zggLQu7)hglR)w`^@6^q4w-5;0X0K=&^^3fz%2_<0-4_cRedkp|TDC7kT<^YGDX3mx +z+32gEGf(0BfP6i1ohDe6@4FLrWFhMXW1_>&LNQU&90UlZEa)UBEJ>CE +z0tf&w3?Q7#nW7FGvSTouMJ{j%o&M$T>MSs +zcZ!}KIi?eAOU>j>jhQ-B +z)5|mQ!lazCs=^k+D3vqvP+~eqLD>usN8+AtsRx1Eh9-b1;;LaMF@J!1`SKwjwD$}k +zBavcAJo>=Gob)=s8a}gVLt2g+Gb$FtL#Xv$(4=EI>)I&CJ`9zE-LV-ESyN8*8OaIo +zwqqAwd9HyRy(t>uVE!)ICFeuGuv85pAxbmwj0dVWIH9XVPkL9%AJY|Q5LBDG6D3xj +zhEkl#Mx>gT{p|@#kk*ON$;RyJv +zbv{ZNi>zQ5{fEI^_DL(5$EF0@Of7O}pckuaes>^)4hfqJ$uYdE%>me4t12uq6pucY +zc}M|SAh=>oq$r@f1Ktn-3my0Mzs2H%^=XR@mblzl0;vs%K*woV2e^T^br#G3sO~A# +z^xP8P)2%*-WmlhU18jmM4-; +zwCnS}(s5Ar0otJi9kYaA^3nA}-IIO_O|Fj#o}P1R4RTNdaPEpW4D1E(jqx_S=_^Z~ +z1xRRQ;C^dJyBe2ez8)o3Ww6r;<;>0AUsZ-3{Z~jNQY16v8o;bQsll|LI9!L8jnQ1K +zD{4UTV>%|krENZ8FAl|)r{`%v>uJU%y+waN<75Q>-W&LpI{rbfs@Uli^TvJj6Iv+T%4ulpF)iwC24CHc7wvNa@lTBXjZ +zZm!=29rkWP5hvaLYVz-8)w;A3X2ehykybmqcbAQus+S7xCI)_2h=oc~P_%EJ1Kjgw6&fFs?n^yoI5O{t=X221qT(*^eRevWi4dbG%Ai@) +zpg*UP;FRi~PX~}gv`HpYj~zPxMYG($FKO|1*I$}&I^ikkkz(#qNwEfJ3;_J +z;j>9IS1%OL%GPwCha`M}Fb-FzzjNxu5#gjhBFMgj%{wc4NV1l)cFR*0@pvu_;6Z1T +Wb#3`U=?D9U1ao!fEa9LXbvP}kJ8Uxm + +literal 0 +HcmV?d00001 + +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.pem b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.pem +new file mode 100644 +index 00000000..dd9897b3 +--- /dev/null ++++ b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha512.pem +@@ -0,0 +1,30 @@ ++-----BEGIN ENCRYPTED PRIVATE KEY----- ++MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQI9z8gVJbtqxwCAggA ++MAwGCCqGSIb3DQILBQAwFAYIKoZIhvcNAwcECCQqQHRFeFdeBIIEyMJpY0A21GrC ++pKBL07F7zOyuFIdwQT2f0wnL6lPWvUg02M2jlHCLDYlciCeUhE9fHUDA67814lvM ++dlZ8KgCsp+2mqkoZB/hRvvS+ZdUqkwSI1J3Wt5hz4dKq0cebJWpDAcY/+031+zTU ++9iCshfsWAGdlcAIBZOEXDwejNfIayp5cFKvQqg7kmED+KN71QmSVmVyKafh5m0SC ++2Y3CoZTQ1982VImx4ZOfh+r86XNkrKLj3KYC1K6DR64Uwq2yLNoypTjdUig81ste ++Dhqm+0YXVN4dxXCLF4desKWxN9v78VmCuHvYkRyunj9Q43GVp51cMQfFRBLWIqnB ++OrT8k020lne0MxO1xju2sr3GWA4Wn6MLqrxSdfTq+P7ZYcSh2BchkDPslxi5gNPS ++Hv5o28rkVW/K34UQw72Kur5JGMRNwJpye2rSPUbtLKb0z81nPzJMP+BCl9DttTr2 ++zDkkn/AFBRuKH0uWrKv+9f7FDu4hxsdFFnLcD6kWlX/V37b5tYAcy9Atd7lykw8F ++K8wAoYZHyzYaIR5otYV5XgjMcw+z9U+5t4ouXSYght88Y10Tq1IYnIx0I55KaV44 ++uCdrptsKnXXWvIux8h8p/SUwvJOrECc/nYxyfS42diH3V3VGV78fw6n74nDOYnLK ++ruIASg92TXUp3Qd8xdoiqdTfx8ZCgNy0mmrYycrP3cUciAYURuKWjjdTN++fk2Vx ++Rw1KTFgTf0Z3dxEMIKDHHDiGUbO9cE8oEMWCv0YJ9n97suoIN3vOcifxG/93RE5M ++1xe91IEY494/DdgsMqb0D4T0G5rbFHnNY8bTDKIDpvZKzcbnm9vnxPi7Q1S1kkJG ++230apDz1Rln0AFO51SAVS8QoF5wP69cL9vrC5miVh3mwqkDVoHnLNpJrT1o/XcVR ++Jl1j1t9lgFNJhVTltTPza4FydXRe2ZBCNKpDci1jFtD8KYZGOCc+PQtJ0Wtcx4qJ ++KVGO52gUT+DSxmaKd+3RyG7MsDw1CPT8inHkACa2G+GGQvqukbjLppQDkvmUPkTa ++fEotMYqnlvqznwiWURl962lyRJJsxClC6Q9R7Pe7pxohsthIHgZFMMuECenUdhYj ++3TdqtKKdbShoF2SBnwYUVScH2VR2ZE8ZLlldNIA+WswG4x242NoemE76JC6DyUQN ++WaxFLL813TmiLYtRq1QZsiqCqr2jRBMJA4cdCt4jMZXpLd8heviNtcPmf6uEpHV6 ++VBQmun8dCQAUeCHKsrkOLnAcnrIl9gPlyR6qVAI8tnfs4IezjnvAh7+cN8cQ1AZw ++xRvoAHJfR7GMT7Rp/GTLrSYU+swlnjrDLQ7DwZ6seOVyzmKo1zRjysQ7qF5m6ELp ++hlu6ED1/VZZw2kSbv6BVzYmWHCGnuyl/n9zXImMR9vcM/uTogjc/38F4zBlSyz78 ++wHy4EWMn2jWyRYYFfwwLvrxmU1IHkNUKYfaM6qeq7F8R7cqbZhZ1cCrAGcIhPrPy ++ig7iEmTblRw+ARmY+cjUuJtbU/a38kEfCMIbKKnUg4vUnO6s2XCGG9TpmcLR1Ti/ ++80tOsEuvg5ZJB3FFGHhSH1gDMAKQwCkcP4wbP/YhzBhq9WU24AA82RtOsFV4xjFV ++ptyV+PmEpJl0DpDeIv0I+w== ++-----END ENCRYPTED PRIVATE KEY----- +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.der b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.der +new file mode 100644 +index 0000000000000000000000000000000000000000..40026f98b436bb2da5a04dd12d8b9ca3ab7818cb +GIT binary patch +literal 1309 +zcmV+&1>*WJf(02cO9lxlhDe6@4FLrWFg`FT1_>&LNQU&90Ukd<|>*gFq+f? +z0tf&w3aL~@X%DZ6N +zP*KA2!@$u20EKj011qhd)gn9IKhN+?3c~_}jfE=7_7<_ygXt~RWA{y^XHmauOn3K0 +zrXj}9@bg6Ggpg~dN8H#_rJ7G3VO`yM7bZ~n7K5MB2Sln7Q8~ZsJBxZVBLC)3XJL}L +zpTDE=34pJ&P!-2W9lEUPaDKKD7#tD1ANC@J(ZV@b2=PC9Z>Wpzii=S5f +zO98X3IPwx%ms0<%o%Y^v_zQA3)6ugpv&rXno3g8-9-ma^Yr1?}1{j~Wk5;~#-F467 +zr5^`U7J0C7gDPNy93E_pYx9T+aN8Q;h(&fX>IZoL@m`4QEgC*@_zaiE-D1>BvX=^F +z8SgsOoFE$xU%=oU|MQ+_Ljd%3FmHIKS!Tb%Jt@yD@Fp0reIXp@M4m`G7pm +zzPwq=YhEGOldcHx-pq<;n8-YvB*2ub^|BnE+K)m1pqTv&7&>**LC85)5poj=x(a~n +zJ<0|2V73CIBhK1X2d0>Xkff2>Gordd=8C}=+GC+NX0Jkq-hTv~hvH9pQ-yCSE7lww +z1DU10CT2b+TxBr&|4uThr4G5sGy9hnaEP#J+Mne9AWk`$2@d0c +za?1g2PCB*VM4yhY(O7mjYkgBa#B{19y?iUFVa?|!xv!A^AzxViOu)&G)z_bhLFxVH +zK`qR6c0|;GULiWjvq(q1^?n3ppX#Tw(@|$w_Dlpf;`7h3*kLb)7e3{wJFl<+p?R#n +zrToXD!y*iuYZ7-bQ + +literal 0 +HcmV?d00001 + +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.pem b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.pem +new file mode 100644 +index 00000000..af4c4132 +--- /dev/null ++++ b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha224.pem +@@ -0,0 +1,30 @@ ++-----BEGIN ENCRYPTED PRIVATE KEY----- ++MIIFGTBLBgkqhkiG9w0BBQ0wPjApBgkqhkiG9w0BBQwwHAQI/++dnhs4VZYCAggA ++MAwGCCqGSIb3DQIIBQAwEQYFKw4DAgcECI5DLMkayM1pBIIEyEJHtZlUPIPn6DB6 ++Z017kFJdaF29AqSatT5tukN862+b+0bGwoda5aR5lr4edgmmwMhR+1pTewsWyZK1 ++xCYHwn0Jna1HXKRLfsoNdKCFPyvJkx9OdbNfop2uqbS/vrsriMKMloKV1KXUGqCI ++zZ7BVEgfgH4hZu7cX5HH0tMw2/CzrC5OjMhFq/OyRe4retfACxN34WVAqMM4/N0S ++S0ciNYR4C3vKu5+Nfk4R3GGMmmz1WejkYH0QMXFtq9IU8vbMUhAaBXIo7xwkAbQA ++UJF5lurXLJELCIR1KQVEjfYCXViH2ZbhAZuk2BV0B8qIKhh9GhvL+y2nporiEhN4 ++ddE7PdAmZPgi9vJ34+jY8E2UiXpXDkSr/8LpLRVQ/UISttARVkW49cOQ7oOV9hOB ++R+0K9fyZWAJI7cZQSsuIPSO5DwDkXclWUFYaa9C0BcHRaz8ACkHu2vSF94LwG1th ++WBvVvm9kTqznq2tNoAk18b4RKN2nVUkfhBJeR2GaJhzsshnpTo356kYNKpSUIm+S ++4bg087Zovrsf0C+49mr+9uGNbDQ2EfG2BJ31faBJ4bwRNata7l3FvqlMLBFJEpUf ++l2EIlr4qX9wfF9OnkmT0gGuuxwB9njCpe7XHbvjmvKalo9s9iP1z5rd9f6UPzDQh ++XdV9pooBusM2Z/VjkrUxRdyurlewD+UQn2MLiRF7t4Rgx5+4g6nooIQlcV49JhEP ++4Of5uDkWzHQ4G6TbffU/sd7THcwTp5wTot0BT2IPuP6qgLFRSQYwx5zplraVfTOm ++GmXD8Y0I8DP3bymMVSuJWFQrSL/8X5b3snOhzF1J9o21NqetXY+YkGIZPfL80jUm ++7ZRSsjz7A4M3MGhsD2i/gwGAUdkJ0kacdnBYCZjfvhEiMtyJhrtpRDT7pSFHCN4z ++jCok/m94d+mPXcI7dSCfQ+4FUSMXDX6IKv7ivsoJ8wqI3YiR9cHdK+EZLWPKb0xE ++I9Y1H93K9pQFlew3U7TzoFEJcee0JHlyM7JGShPQP/mPEoPsHTRoGjYwYp8OHEol ++GAjRutyMS5/pEL3zqT0nWsr8rEEwtm8tpPKuMclPt/p2LCpVBVgTpuVF/Hfnr8Ab ++teL2bpC/D0W0OOOMU3MlfU822vlm1gC5Yh+I/+b3jsgd4xH84PZUBGDLO5+Wrslw ++f5BPuO/DHADonB+DeGqwSFol7zxqYWufdI1jb1YE5pWV7dO2e0vTD7463o6V907+ ++Zfc4k7h5ohS/W+RGQDBM5lplssWcOPK5Rx8LpP/vXHFp6+EPnGJTFBg6I4fUYAZK ++HbJAnLkjWjfy7F4AEBkx8jBjYyDqNx3r4WLMU5ds06C5nzG0usTpAtoJk6k3G/Hr ++l/jMr/za+6TrtXyNBDGpZohgxP0wT4+hAMyLGymYnSWFlRVkkf0BANbtcJBszbAZ ++EvNvJaCecjVw2ZsnLo+rapA5V87wR6Rzpc5Yh6IxLQs/pNOcl8S9HhC+EzwcErLk ++J1LB5piJy64kLmzxC/wmJYvR5hY8GjMU8Q8cHOD5SVk0B87SOCt9LHuskl8j5/3/ ++tLEjJ4T6nHSf8swXl4B2e0td8/5Cf6mnyqiuOyQK1yGhMjXbi6taYaxb2fNHBV68 ++d6QDbGs8iCwGsp6ssw== ++-----END ENCRYPTED PRIVATE KEY----- +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.der b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.der +new file mode 100644 +index 0000000000000000000000000000000000000000..e25b4fb9c308623d9c7bdb0b8bebb48501c6be46 +GIT binary patch +literal 1309 +zcmV+&1>*WJf(02cO9lxlhDe6@4FLrWFg`FT1_>&LNQU&90Ulvi-eaBbXR%; +z0tf&w3$K-B+F7cPWJD#?kWM*0`QxfEuJ=Z*u +zC|lSMhVlY3Hn5v4*j}cM!PAx_5X3+D^h~1I0wJ##K?D}rnyNX*;Woy +zm{sf;2>xr&cKE*%SzL~p`^1&0QVy1gzGJaJu$kM~j5xYDmOy07RHcHY=DlgENR?JS +zn*N2@ks4L+r-%qLXI6|v^-_8DU-Wi1zO~P+*>vxFPq+sLr^M|utY-U(oh_Q$&QUd(h?*Tsu?7?y1C?DVtE(j85j@SzBbl*`Q6)zw5RoZD-M +z!=PWIP~acCJU?y(9Fq!{AKtqi>U~m94P~v%u6QCdMtr#JU>x1O8KOn$-TKYl)>&3NG@$p=5-@&=JWhYCQ`kIQz +z*EE{X^ug#30AM%0(ARhq(sv1pVsXEhU +zT$306K}H$MTB*+QKBoEiG3yPFvCoh+hXs*}ZD6W!<-dia6~q;f>LoZ9*h1znHYd== +z>fNa&m-*^rh&A4V_$8`!!6UdWa^MmxM%q*X=TL^mY{Z_^ +T$p#g`9VgTVL$n0dF>&=Da_4?b + +literal 0 +HcmV?d00001 + +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.pem b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.pem +new file mode 100644 +index 00000000..717d3ffb +--- /dev/null ++++ b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha256.pem +@@ -0,0 +1,30 @@ ++-----BEGIN ENCRYPTED PRIVATE KEY----- ++MIIFGTBLBgkqhkiG9w0BBQ0wPjApBgkqhkiG9w0BBQwwHAQIkkRHl74lgxACAggA ++MAwGCCqGSIb3DQIJBQAwEQYFKw4DAgcECAGUDJYAr+n6BIIEyOthlgMNgyfjvQd8 ++ZqQYF52juYrlvEdk/NY2xlEfa7NKUdEBS6jvL0lHOaCcn0dRbykqs+Do9yiWsW2A ++cQ5BLrie7C/IeZSaF90Dh90QUe/aFvE/1fBjwuSdLj6Rf12MRXxtyCJb0WkStrUB ++Rgb6ReGUiUVz7fJu0ePZeNKqVtCa+LDenaUaqo82L7y05KLoQP+qrQb94UK2B6IS ++xUSORehQZnf6dpoXHMS5CFCv4Lw/C2VusBIZnAhEVWm3MljxMycOJz27YMLXiczj ++H//rm8BhZQ5X2jYTvo8S0BPgRXPnxasvIAYLbAFvK3KP0umX7THVoYsXpwBgphS3 ++penm9HExXsyYLNbefq9jPL4LlatNDi2LAg1QOr30jxGC73xESbYsM1WYIB24RSNL ++ZKyhINxxsqcSkvuce5dtShWXkqD7P0nUNzygT1uSD4AJEKOaDL/YtA4dsTt/LCT7 ++Ct8w9TR2+QkQdxgZri1S9+jSmPQgcg0BobPMncysTjTyC59Oh9KPcJCThR4BXitz ++cvocqt1CsiKiMGR51xHfMs+p06DwTTz2LRYiLdXco72D57O4lixOk5LqXF0qiBfV ++mN7LTqBIvuYiK9aEBZ53HRRurAhrOWBJ/UxM/VYi+lyCAUBhRu9XI02g0HA2UrlX ++9RnuB/a44Ce5mgQWdEYdQIkI7JB0Kj05ktWdiXeLCPtTG0ytfQ0Cv/EwbWCG2tu6 ++PEEmayz3KqMR/Av9jqsnk2qU7kKqR7hySMfoTuaMGpjcxCpj3Lg6Tmo0Nrvn5svc ++NNChDlrgwyp4dX5ub1bwYYzibG8x23+fKKkil7NqZ3gqZ5ecmgX5XiU6VdBCz2kJ ++k1xGGiyt89+gDdmoc+HyjRTJgfChZWiI6EhV3LZOnMa0ZUpQiM4lmq0SlQ78zSmY ++ZyqG9dSEFWg6BMrOUpZbuY63wjvrxSHrHLAbCTlI9BRkFhmfwiyJ90FfMBUjBt6w ++yCPW2r5aFPIhngNS3EayJKhAwchGHN2XdfeDj9GFhWZAIQsXS8R7JuGDIug7+QMj ++WL77m1jy0K4PiGf3lt7PVy8KOqbiOHyzYQsuAuuMD7NZdV4+dVzznTe3HbXLWtxj ++itPFNuSudfFBotAWDV2yOF4B7XbcTw4CEGv9bVJoGatJdaubzidUHPJUozWYQX8K ++cw0LqdR8yxMtHOc9FYyawLbQMzcMzt/lijS75iO+vspT9TYXxf9rC5yX8xlSHHa0 ++jlgvjnTDyEsrUnGHk9kNe906GV42YDO9MUJPvUmlv6/bAKA5iWX2+Jo5rwIWk6sg ++vW33g7NPMn0I0pwzaWDaLd1XNP3JpjODwkL/5n9F2x1+LsbPpuk48DOnXQi7MV0J ++2ZWSSxZltTLpObG8mI4dWrh5DXeswJIIta4ki1lSyFLu+hMY+PUVozyd6GVd4T0o ++cVepNU1rHqxvsLHVkMsixypHpZwnkQigrE8EYeuMZQKPq7luHwh1AkTASr3SJF0/ ++uztq0vmtn/0+lg7rI0pW+oFAlscmcRMrcOCLaX/TkvgX1JvO5lspIjP6IdaXsYNJ ++14GImtXxQaPgAtWJ48o/AzF8KPez98DfnmpXKBM0K/kK5OGuxHvNCJ3eTDYS6X8I ++Sj6Qf6Z9cjwB2xRFkw== ++-----END ENCRYPTED PRIVATE KEY----- +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.der b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.der +new file mode 100644 +index 0000000000000000000000000000000000000000..6674c48a7ccdf918b248467c985a132cc019cc43 +GIT binary patch +literal 1309 +zcmV+&1>*WJf(02cO9lxlhDe6@4FLrWFg`FT1_>&LNQU&90Ul&C~s*CLpu5b +z0tf&w3`RdZJiQq1TSxeJ`1`tPC44q1#n +zB4Ikf2R#QptSWJb{k~?9`?v9r=A6Y@SGm6wUAVI`=w)GOvpv5zzDqXi7r*5`j2mCI +z2W{&nMa!N?dv0=htZ&CVoB_mTIW9?Z^W&hlq1WC1qJ<1$Dox$Th<}9#=TwZFDSVxfFqAkNy4$=0> +zUA>azHFB{G{%zP~lZ*x5d-WCF(pXMp)|{m#U&=h(dAH +z6ap!#3j#&@Rk!R2LNq+b!Dq1y3p@o$^Gw%`!Ou8vCSLa{zA93cix>}bdx-Znna +zcBbSb!7XJLV(S{B+OR*ST2`copwC=$K_Mwy^h7%=sTr?sv6`Rwb2*^M+W=L~7?xC( +zdYKroHA?SZ4E(4f?PrhwH^~d%8QAV(mU~;oD`6Ac>Iu-LREEUB}=6gXb;s>kZHsVWbHH?1J~r_?R1D>!h;4;Be@#2c2_<95#Kc@V#}x)iz?jEv|W> +z`PT7i3zNSk+=i}kA$dRo5bn5cu|nHrttz`BN#ex@!xsJ3oslZ>@}Q}|M^37`wO=+K +zJW^2-hsj=n3K>D@`ETj22xlmI`ksht4+YF?s#rV5z?&v(!Q1A`w@IlN5>7JzJ7*O8 +z=&|77E`;(a=iShPpcRXJro1qdk+v$`>_O}B%Jta#h<@$-1ZZ`&)YHHxa(etD8!wRr +z42#&%_`$iuJO7oJTOQzKbiB+xPe%fF)!6fIZLj^up4+}JIOlU-TK@Z|9(h{ZX1jWt +zt7i{?Bm5=g?)ldWBg$jPug{-ngz%6Id6X0ScAQvH{69+w|I|aB%hvGb!dP*^dxktQ +zSbB!qARZp;Ygqp1CNSA{(|+f4{{%z?0Xr)6ik>uT@NS_|;Dd)NE2nS4a7dl8bim!*WJf(02cO9lxlhDe6@4FLrWFg`FT1_>&LNQU&90Ul=q}f&OAA`jL +z0tf&w39@EMx|aB7s_f +z^JOy=u`ZcrMG9{?H&S)V<3~%sIblXjGf*k_RzbvNiUDYMFEcg{JI9A|tHT1v;vTxB^ +z?+56}D_*G>dbXDTn2Ae$hg2R?36*cDQ!*iI&!Nwdh%s8l6v374{7i7EW0{3tQKlR; +zJPM&dF7p)UH7w>GT&pai!4;7N+7(z;Lb#~oVCZsM=hotiA%;EFxmx4hYyNP9V9V20 +zZ2IZ&ypmP)vmc%yv@1ka$8%axQ=qLgYZAUM#AVh)*vc;U%$g8>L=lFPQa0q(-EY6J^Cfg8A9Umyz>Xay%$_6w|$%5Bj>?h;c4bX<^P^}S-bakIzSn% +zw=xp8#RT&N`7+-q|5QI3Cx=)1uIb%QA;Y*Chj}Y4oEr~@g-3APvtzSYp9=(<>hg(_A{Tp*{Cc-x~di~+6 +zzXe2OeJA`^WUVS=yy1Y04F{e-6I_PJpfsiq9nX!2o<)P6uNGfL*ekEaEg`>P!HPUi +z7gcY$F<%CmWgyznwjob-zzC`;+kqrn@satUiRF)Y2`D+QNFS4L2;j*Syi0ay7o_-P +z8Ja#No+#IU?(g{hn$)4GhBKv;%hI_gL#g(N +zFP}SDckbc}jmx#=4eUtDP%r+n>T&)=2V%=^*j34Ofv@e14-*V^5xh+Q$|q@uC_O^& +zcLmB;t|S53wbcWqrQx(c+y8H@5&TmU_gMR02xz{R5Ozg11PA#cO0J00V?Pf8V&n;J +z-HfOjv>ZYe@=h)))li=vDGdHwN+h?K7MUZ3CV(tq;$!oSvrKYQNMA{blk=X|HU%W! +z8UCiX4@L8jsdhL3rYjN;(UItQi*(0_^>;?w5Oaq#Z3=KwN8llY=sW1u-4~7po;a^o +z=s%BOtLLc9@%{$00&3+FE5$_k@=nzuDt!cCm_|u{DWYBGj7H-{D(> +TNEhrykb)NZ27EFE-xwT~zU6qK + +literal 0 +HcmV?d00001 + +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.pem b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.pem +new file mode 100644 +index 00000000..15521d43 +--- /dev/null ++++ b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_des_sha512.pem +@@ -0,0 +1,30 @@ ++-----BEGIN ENCRYPTED PRIVATE KEY----- ++MIIFGTBLBgkqhkiG9w0BBQ0wPjApBgkqhkiG9w0BBQwwHAQIzK6kx/qbJD8CAggA ++MAwGCCqGSIb3DQILBQAwEQYFKw4DAgcECD74OAvJ1+LsBIIEyOekZ0qcxeX6hEYZ ++4ONCHu41tmOKSvByGeUBZvenjJQ48AgTGYUXNoYri1ohnbQ3bcqiP0TUDfT4zRcQ ++ZFZLuzAtwV8ZfZcYRCQ7kKxGfkciZJhjeHeuBy3moEbznzg9TEPCVzoOD+k3f6+W ++7/bSycV7jk89CdaWU3FKU/W/RLZarpm99Uzat0Ecc2KOa/TckNTBvD9Ysj2j3D7Y ++UmdmfUGORvwQhJG0mwv7OpkLFbFbYBehWp8/Fk5izJVdJs+77c2qiQvgeend1D41 ++ZUBKtbKCoc3Inp83cSkl2XonncCUxBKLiWHAzZxhPiIHwZXGXHjCOUqbs/sXEogs ++3HT5PHVQjqPGIbl5B8NYetelB1h1Udq4Py1VZqjLhZFH8q2SnjRxC9to4bXaiW9N ++451NL5S8bJrcaun6E5cD74p32F8IOjR2Ojr3ofEFHQFVUFlLPY3gQ+IZs34hQBNR ++QY75ffQDykZPBpLw0hIJkr1LoYfuEMdN0tPRRxYVO1lKAW0xbOAd0UEslFcsyXCY ++oUnQP50nVpG44TI6bNfLj5y07EyMFo6vB/XiDXh9/Az8jIfsPeYOGIVMYFSnourw ++3cjTPFrJnEQd8CHxjLLnB3ZeXIo4l03hZBy+qFOIF2Ezke0fmRtjO+OUVm8lAy2Z ++J1wSTThBlsWX2/JOzh7kiWDipX0fN8sTGeepazxI8nNANX7ALcxwuLrjvPOmTxfX ++ElpwebOvCxonwWR0C1gyZ0feOI8kh0dKwe0xi2fqxCwxWzPxN3EQZ+FtoUdtzPoF ++7QRBFERPefUpO6214t1PgJMWvLjjCsOFy4tnF46nWI/r1XLOQlLP5cwAIXZlnSXz ++ky6YqPm2OniXq5XqvyLOMy1RoLINJY1dhgBXFtC5I1ZQAmGJGmX9IxVjrRky9kKt ++362X98edUUMMmW48L8RcyYOOVLpFewAmU/fr3qoUDjusOtC8O66J/V4vjI3G8Ve9 ++kNLiPxQqbyfHHdbC2Pp6rXZXcl7L5FW/fc2YaZRqCuFpuGXZQ+SKrMXKY8oLa4tL ++Emf4isvdlRQjuveXoebxPsoG9Ww3pz3nl7NQ40cnSxb1zxm/heQmAczPE0faDsOi ++pGAQP7jAefh2XwJ6RWRqzyuA3bDWC7E4ASYODIJ1IAogMMOlg940hlmCXZ/8993C ++aTncCQO10ibemZsWvD/X2+gL3LSgBi2Q6NjHqj4MPAe6yAOA2USc1GzwSW4WEpIg +++ttJpKZFnnnxzCfUU+pTz2ONGV7J5a50BiRLgslPawm0lbYl2BvjbSZJul9oqqy/ ++7FI5Jy83OaHrqyMSRNKZbkPWy58zrhQNaiUaCrLE3C+hzj1k9BXrWm39AQM7olnp ++T0yi7pivXYEff0/d8tClqQAzy0DnKEW58xQODxhFkZm70X0HkUABD3QObHb2DSjG ++PE1XV9pXP/3pci+SFznuvn0p6CN3l+rIXW+pb6O4KW65go0LTo1evIuKTFjVtZyf ++KqbgDrdu/Fd0KJJy7S2cg/i02x7TfcSJE8C3EDyyESpGegE8XAH2NEltO1yt0+/z ++26d06Hr2livL87yVpzW8b4H1SlifZmPhy082InF65W1w4hAmmsWARfPmZUG0LWoG ++6zRPj13ojxpLPr8kyw== ++-----END ENCRYPTED PRIVATE KEY----- +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha224.der b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha224.der +new file mode 100644 +index 0000000000000000000000000000000000000000..52ac321438292452b55de644c0893a40c4027c22 +GIT binary patch +literal 2464 +zcmV;R319Xwf(e{3P6i1ohDe6@4FLrWFhMXW1_>&LNQU&90UklbL~GWDau;{ +z0tf&w3zf#JzW08QCe!zTM}0hvt-dVemYKeS*}+4Pf-99hgW*VS{j>!`s}UPPazuLYAkHk0 +zILr@FnOj&vzVzQjdzQ@ +z@fL7i4OAR%Vbflzi~)ImbHci-UwVS`ii)wW05t}MP@MxY_XyGXvBwF$emCEM{6bnE +zjIiac2WhC;wExm$p7_BOPCQoqrLX~RkH0sKgf +z{+J$5=LLmYFxW-hc^u!c&v#XCGp-cx7y#D;4NIB}RnHHdg5^Hjs2Q;2-vacONU$Ks +zzP&6uD{QEbIAv$BCjUjjEEHdnqFXBoPn@=oPJ+A +z^#VPmGiWA9e)b(qaOdBjncsedb(ad60h%yh6}RNM(5+__N6zIi +z1;pBx6==3|7K}+3h3+LT5%#Q9pZpkuhM=9b(BsO14O}Czm{mj@f>BCh%POzPA9Y`! +zTGbQwMc}0js(OTbyt6#!cuov~UVwD(hx*I)1?L{*K7)M^Y0xByZimF?Iy>X<_GHbN +zK0y7(XI7i)#?=#G?1FemmDym2Tr|^v +zni3PE8gQ2=?*-c@ToUQ**DGpxy+PZdCTQOYD=AFUcEj?J(R6KB@~j7S*FH~Tmj+Vg +zdQUVe0G~8Zbc%?(!+NLin*)Z^kg1U_C@tfZ8{;}q(u +z!YmUx`lxB9{EA5#Qm9?)5+^QoYyb_(B<2-F<%FuGC3%KGQmvcwazE-2{8<~J^`;p! +z47S966~#RE#c1T!h;yI$K3@xbY-muv{~ixHEvAxb815HjxZBa(gQS*$&1K|VPBsR-KcYZt!f(K;3q%p +zywGn5YY`%)Ym5NL$0~}W+kJ***=x2yFSR-~DPWiitJMRQ6SU&yWes_?@i?hGiv@v0 +zI3ULah(n98eRi!@La3$E)-gAXF|o`fxkZ$<-8vUKhY+{f9C*cBiYr5drB~9o+>TjG +zBH&aoljO2G7c=C_hnmgm!=k?%d9=74Vxku1kO9d@qgJt#iDp$eD{rUHY5ow6(G`FA +zy0u@cwpRK}r{Uu}a!prlL~)q+`eLb^tKF@MIv1@OVlKKP2-zMy8a-WNLCs+|7<-?y +zN#yo~M({67a7As?eCv;;5OZ@N#2C%W0RH#K2QeIZUV+1|&7?Ft!^(@(5MG!NTogj; +zz$gF}B_r5$ZAAIf!2&`izQ?_Ikh}NVU)5*oGu#i_Gx%uRX?mTw~~UecHos#EO|b>Q-=QkU7!dNr!zGpW}3izmpL=eUvN<1kBEoyEhJDG +zxseHOa2L3neHFTdhTg{?v>6*v-Qal(2g`^>@~SaTq?h|=#-{WBm8c7f{%cP|`F#!^ +z0^4wN2c*qzuvm6&*PB7*>a+nmo6`lKJuZ5qhx3HfK=@!?pa53e*UtB-J#^nU?}V|R +z4jxuxJYr|oBTI8K40q_lp9fi21YNyQ89U2mC}hn40V7{>?y5oHYE@kr5B+?_|8iX1 +zKx4f2m;Ai^a;`f}E`D0dCvY;X)AdECJ?ys3maq>)s|+q^p@El$P6jSU*?|E{0(3kU +zT*dM6I5bV(M_UTcV!9p`8{qHmiLmmj&D^KZ`2!!lDLF!htLmdgU@-}4e6YAPPO;Xn +z#|`L26>OZq+i%xIbJX+Q9-MCUYi$p$A2Sd7GT46x)%`!XyB +zkIJ}wnXT(?6Y4Wu_xDWEU!`NESjXG)FL +z5lZ(XHGDt;V9JHKI~pkm-xQD4+vq>*JQlt?>Zw44J|}=NW1Mxg|G67(agp%7LhgsD +z<&J|Q6&OYL71Vhbj^CT4uxK9Gw@|5SH;Y?ZgBtAV0De@nf9!s%w0Ah|4T2SFJcj&N +zzmGj>@TM@V)ACL +zC1l|@*EN;$KNF!e`N^)s=8|2sC-c>MN5tF;t +zD|Cwzo~FHjCrs$>3Y`9?UM>Nk`y{cV!2r;1E%xqRN}`pAb*&)rs5E235D`gZ+^BlW +zfZYY5R}kAz>JVB;8SCp6^!Jcd3?4D&_P_YlCX>|1{dLi-bJ#BZnd5D_2#(`=)9^hD +e_tA4>9CWHIP~w&LNQU&90UmVz(!H58B4AL +z0tf&w3s-a5SVRdRD=Xeh5N>IJa#WUH18q~G{; +z({tM(Zr=U%4sK~~I`UQ&82?JM+ju4&SaLNfuOqqQBpk^+gv$$LlT}}}F_xnz^+R|? +z00S@v70%z)0WOr80YU_FIK|Bc^nk7^F6wy2tYmYjyB5c^d})@N9Sgs0o-0U>$Tyca +zyMidC;bmhz&9OgIKMD{}zeEym14MoB+SSQaui(T__SoI}<+3A)RbyWSljIuFk~QhS +zGer8|y=u2UB@l`Q$X)X+E2mEj)w?&2^#gf!31;am#V6^;g?V@lDU3MjAA;0ZpIrS>Y96F4rpt +zUMBkoI|ewF1!ugd4R)Su&I&=0$Q{VX|1=8bK!D?}Xb +zhn_Dl=X6fh;+3P=8Os}H8c1QzOYAtlp(j`w^|}&Bhha7 +z*F2{1R>F}N_r}Fodl(WKzcE#1hq>b{855s*$03XOy&;t?t$mZNBs`GlHBtv; +zlph3dH3G1>C(pV`=YlO4c8-OxFErX<>I8ZfK*f2%b8iG{S%;e>@Q;t?k&@*v^9kt# +zf1N^yO6YM|`uo4y87*Mj*pelH^SMAf4Y2_s%F7;`;GVJ?{POziy4Z172NTrlY2_OR +zLsK8J$TU)c^M3HNoC`INjMincOJEmVJ}+H>2zI7BUl=D&>f%G?4mv@iX>F-6aDd2{ +zy{Hco#fV9ku-x}dpWh^=AY=6|p=M3*z+S=~#aas12HbhC{#v#xm6fOYmdL9agsfe} +zV{4lXghf64YsP8S1(0mvkuLly+Imr}Qxef}Rfy`nirD4vgdx;y;Rb;r5L37?n|L+U +zD6JZBgpOl8$-Enu8HaY3I=iMM?6PrRUIywF0NosR?dHb;`fm(fzvV06Di&RF5R4t;H6JqBDG!Tg{S-spvzB-|oyp-?&3P?C;x~7q~6qI?3Hl_zP`0 +zR!h`Su|rLR6v=1jTg7}{_iO9Q3Gz;O|=FLYon +z)ED3W&ItYVOs??3Ni6X3zT*U-=r0}5Jw2`%P!SAjdrB{@Jc4b7bR}~2^eO;m!5L4X +zVYnb_98(iY;v3Lfh?_1qp);gdT2j3OCyWq +z720-moX6CbXbDNB8y_%RbdT<@J`8?4QoO8FOCiVv4Z}?L**U +zLIt%rg3ZK9B1kk4iUoJZA-PQW5Y%}BiVt$>uW-Zq=7YXK83%@*%fh*h0o|7>a^eouG0ieqULf(}43SvZCDM@Jh~{Zq2u`WS7FcdM)wA-=g|l=K{^()0 +zc_oif17?d=ni@lJuGFw9p)h#9lzp;VV@B}*%#@`l=MS0{p>o+h`9xHa+UFh_f%HNm +z-VbQ>ZMl1$CNE7e#QqM_#piVJC3oE1Uz2@Lt^kF}3@TmYUSMt{QuV4_kr_eKUL2#p +zGN?vnz=kNraDipK)mN`bkZNxqh74$EaPDsPZ3HI>Go0LXsW0A$X>b8e``5Ltm|kF$ +z_&>x4jd8e#X0FVK5s053wS5F)nFP;pDlrc?U~=Ve`E61K@cTX|!ZCrP*nybmk|Em5 +zWt8{iOCGsiT%pscYr1I=m-_HFeWbakzulj)4Fz%OF$Lkrdv=h^;eVBas%1Jl=fL4p +zw~y(n3aK5`i0iHQ&PI55zP7XkRJ>(F<(CBMU8ZbHtPEOaQ)w0py-{SfUY_N=;g`)o +z$RBu(Fxw<|Y5&25C~a6rMBF$#mGA44lJklb-7s$ZBbX-*l(`sljc)wJZ8ACqGQu2kZ9?G)PB0mr}($0n9#g^FLEr3SJtPz2}F^zukoRQ?KEqe5iinS5!Pe#TFJHY~KW83EI7~X|I1s +zo2GHp-K+QD9$0z|Y`5skMq=v|NFF&yoo-(d8Io^2PBt;UAIEyGJ(maFtP_WR5Va4c +zY}YJ#RCj0{-sk|14=?kiPJ{^63u(!(jYjvI0x +eeJBLQnG4K@p@xW=*%a(SGm`(}4;`;~T>;)MrLfTe + +literal 0 +HcmV?d00001 + +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.pem b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.pem +new file mode 100644 +index 00000000..c3c0635a +--- /dev/null ++++ b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha256.pem +@@ -0,0 +1,54 @@ ++-----BEGIN ENCRYPTED PRIVATE KEY----- ++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 ++WqDsuRKobaoDpFFCQBLvQA== ++-----END ENCRYPTED PRIVATE KEY----- +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha384.der b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha384.der +new file mode 100644 +index 0000000000000000000000000000000000000000..5dec3c8b3c5da6dc9cc4009dce20a08b77d6898c +GIT binary patch +literal 2464 +zcmV;R319Xwf(e{3P6i1ohDe6@4FLrWFhMXW1_>&LNQU&90UmJ`u9=H99wS! +z0tf&w3My>{W-d$o+TFUy)b3zyHOu!WJ9_*et!Q-f`# +zV~M7%bR4|Gp+SUQENPpvC)683y*njoZH809Mm>pTPr8+k{I+c~C$u_#k@+Zi(fM-? +z18a0^mJfWK;VU&Mo%YDB+H1Gb)I}%m_a#BM4d7)>OVAPq)vN+pB4P02{WXFl0-si@ +z!g^9qw;Ko_UD((nUzKH2sCtV(Z5@*str=tCPpJ$H7O_2=eE7d+R1bj3SA|!mk +zW)c&)IO^1cLemc-?v<@FJmU-Nn11UOvL=%#&vnQ?Ol+s#5I=%x06i?gWF>G)Na;Gj +zF@n~m@l@)GEbw|Q@Cqc_0>BXF&^J~TfKjY75SmVF7*cKkE+~(wMnkiLXo>(iqRyYd +zVxxP>zo5y~I^1@(UM6!Uci`4%n2A-QHzJ`eIkvVzqECcDf{I-?6$wz$xO%gMVH?3? +zVI<1{;bOgK%bDQ2-dy;&ebisdL38boEp#(kYXK*`+$gh32*ofYAGH)D2eboy;gCYQ +zR6wZlT;(WRX+NxLhDOxsoJ0M!tI(kZB5fNj$sMm`rrJ2!L17z~D?|5!s~)^C;4zMH +zb~})G|IfaaoZDu_Ch; +zM-h9D$c0vsw{wmX(gT6S>fy-op3zc*QEw3s!nWFST?zD^XnMyD9Xns5ts7tIq8#$= +zHCy&i0tmt$+wuq;Q&Fa-zj1-UYX$$?KvJfgMcE{cf0bQ}%FXa1YCP}3OF)g9jfM*c +zaG_kNghpSTYm|GIEixk#}GdMx8BlPLBB*PZa#%E9U1ykj2HJh +zLZ90RYvP^}j`1XC0N<7Omc6LZvb{@q*!pe2LU^fro)ooYt+zcutSj4FzQQt|o;Vy3 +zK_#L^2pCRElbXkc>ENH?wlE=_pFqGp|AU@@-?nkHAoNiA|N7!rsLM=?z~EvdG8nON +zP|vF{UHUJg^mysQ)iYBR`pjKYAdzNG=>>=p@v7QJuZd&d3i}|xyUr1;Gm~z9*1TD> +z!Pnv8<>lr0x(8b=-JS|Tq?b7~=ZM){44&hM`5?z2^m?ri?HHx`2sNRtYpuY5lPzN> +z(>eWl&O#%dNMBmJ25wS4{hQf9OO3B%+lVX4qH3< +z(MjyTxZ*y`jNfSSphT2A1U?mru+69r#!rS>WZU{~=E~@_d4&duGTY=-t3m73FLdv< +zGX73%ZDNRnfZ)6jiJBqLtP*^FL~m9sr2vI4;L~>o)V$wUn?^EH)x3=jPoXj7UjIKpK>>RyuP$ttA%8u*rA#$EpT% +zs;MlhqdnnNUB`!Ekm3hbd^CxVbuVZggXWxxoZbf65P$`U3Z-osNFYhNNk~P^8<*|_ +zcuL%0PvO#z^Ci*K+-7{Xf^N&+S~j=9HI&8On*D58b2?pgbxS!o9Z^P-&*dd_+hJ&; +zz(pxf7;#Z9`V+5=zmmd|L2%BCTiI+m0ar5}qcKV0f1~?+9jE{AJ6Y-RNzSRbup05P +zyKR$f;Q%wlI~0K6##3HFUjnaJQw{^hoCYes=uuur7qLW5X;1u*t?fq`?OcE5%lhQv +zm`Q9zORjx1X}~c}ee4=U7rIL;9?Qhh-I!~~YTs^}bDJ)5m0rm*!>WfrbUOpyyGo;g +z+%b&6f8{!|a;sJwgOL}!1dXp|r+#r21kcX_FI1f*Pb7qMK7|sSKITo+tlP+BvoUAm +z{C?Z$T9%sr2o2HkA0$O-(Wb}cats95DH3NlV;`rDHu+S3$rF5JVjgJ8Yl1Q{$@9p_ +zBI08vb}VMv&Y9?cbF=?l!8?Ct(3a2SJu8zbMl_u&&PX#CH?f5%NvH^3iha`=OuQ#O +z#W^rlje@1;4bL>w#PaViN-$~^YxQ3MMVBgSo`?l>-uDViOV!AQdVyx~;Zwo~;Z(1L* +zEo5cIIIjq(aov9Mw!e|09IZeLGVkwT{*p+v+63o!3n0s${VV;?U9z7thk@@;gVzoay}tBQfQ6I6#fn=)bdT`bT}sqTFPY3EEj1M%5_7U+EPOt43hQHojXPP-%i +zl{-$?OCY=JQ~F(8uXt>748}t)K{tgujt`$u2IcgGK+szN`dGJva7Y&S>Hxe9HeDJz +zh0QC`|Lg0(cJl15Qur44VjkZ`efjQx1&TPhiUZiymZAhj=qx45z*Ajgio?8&LNQU&90Uk%_7`Zhv +z&G3*KQCUaP^_nbiXRyXwF1{7J$|(46Bi6`qs-HBYP%%u9TLjNk0gh2%I5HKdOTd@SNa`h?bkdAhW>elC+_8_&6lr6hv>hHY +zYQR~q&90LS2>-LDdK$YG!*C}*I_p` +zj)zkp6x`;*izL>$Rl}63A}nb|9)#8;kc|nL2gJ30lr$lc$=~ +z=sWHrJ*vk!s6(~?ZLf5pFdH^5b%Cz9kVTcx_!Q_5H +z+k%ioc0h`U!jAvP(;m#7@*Ln15h_nD4`}OY`&?9)7gBtYMrq#NKAI5_-`$6X^~sI4 +z?8fGUrqK#+*CwsT%d6hVLXmn2;W#^p?siq_09kw}9ZkH_FdG}33ulA~9JDp9#Av%k +zopVFS&2Uwd4{ab9Mfjav!s6tnq|mGK*6uvP@A^to3NV0OXAuokUT+%z|#}4K#-@n^tbC^Ap3gK5fg+2zQBe +z8ijA~0(`ilp{j$_j2Kohx9>fx{T(ENq9p`^8p0MEY(T;oKZtY7B(br8a#IP+^+-fr +zIgW%;pju#r!!*h6ZA+9*DA&dcYq^6A5S&c}53q;|LJD(|acETCOmADF)@_2QO{ADM +z6A5<2v*7BC-6<{V=ax|LfF3O>Ht$NS5`%^oxxvjRzA&AS|2F!|(tNfc%ZK;W;AMRY +z%j@BB%m#5Gt4ci?x?Q@|)(wW=rfZcrTu$ttWBX1M1CQeWrJ=|H?YCI(M4u9-#DxpG +zPU-#&oXaBGXTK?-zL<)P>p3Q2VLHms%r5b5d2G1=9b(caZ|rY5%(d?}HAy6zO*w9# +zm``)~ak5BOV@PP5$z&xN)=U{HOk!5Sr-S*>w5yIMmwy|-laIXVEnw=!`kuAkJzoK)ZN0u(?^*=NsQQ82qxz-$}7m!|}y0)u0vZIjeGCy*jQ7Fo#S6iSAKAG|Q +zycuF}N^k480&ol97cEo$?*hVgJ}KP_d1dgNv<)f{WF^@^`CXeP3i4BVL`#<{?J^I~ +zXj*okL~~->t++P6v^Xe2>rYkbCN}6=Sud! +z#hHAWo+93u@*>{~5b){U_(3XoT#hjswYMH9P@@*-&~Y^0D&-+quN~E{>3(G9meErf +z!B)fDxX!sVACJBHE|qCM+oj8Nt%!6*2MlQ+T3j~O3#wU@7@yz$q@@z|KcTZy{JM|0#r#{h&E2y||jJHB$&6W!7V?lIE3{C4um^ +zLD%VqGQroR#cBJ>Fl}7z*?-_9F%CjK=Oy7W~{Q8%BHexLYW(j7D4G@b|tqKrh@U|pAv@{s~r|7 +z@rFLBKMsW1Iy7`eMxXg8TH(meOn`iU&(6{Aloau}E;Im!l?r<)XhqZqk4L9ZRS}l? +z9zWV!N4JCVzRnZq#|jS*?X4kHDH(m2-Rh&S0q*l*fx)}KkYW$7 +zK13nR^$5}M_)bgmrZ(7BLcJZ)(Mhx}!N3zSjhPS6)CSM|z)ud%kMU8}F=dJ6mHi`m +z&}{8LhaLY!T4X3Y^JfC5hExt@h+N!YG31jJ?3PMlMO)nkU#r~l_f +zHsx_XEq1uA9O_(L0CG4GRV($yTKFPOqlrG&e$0EsB1>$4fq^9^5m!7hksbCBFvbax +zzNH9pQ225`<0aT30qBOyD!q=ohSLyvqjcz5Tr~>||K>Ei?L3-?|7fpTmsO+1c?`^>&m2n{b%DWY9%DE#|2Tl0EG(RFvPc +e{6Tu9c+Zhuq%Ff|0yiDFj-7}y3{5}ZgZP}Xt*&4I + +literal 0 +HcmV?d00001 + +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.pem b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.pem +new file mode 100644 +index 00000000..194a8952 +--- /dev/null ++++ b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_3des_sha512.pem +@@ -0,0 +1,54 @@ ++-----BEGIN ENCRYPTED PRIVATE KEY----- ++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 ++HESFHzL1ejv9Y4y0O56l+w== ++-----END ENCRYPTED PRIVATE KEY----- +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.der b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.der +new file mode 100644 +index 0000000000000000000000000000000000000000..efd8b5c98f282ee9beb9b90e6e0a7d2691da2cbc +GIT binary patch +literal 2461 +zcmV;O31apzf(e;0O9lxlhDe6@4FLrWFg`FT1_>&LNQU&90Uk-v=6{XhaepS +z0tf&w3qza|(a(0bR?ZJnY} +zN6F@+l55rJg-#c$rPi +z=yIaX<5XFGv!|JOrBl5rc`BgKoIp~j5=JqvEyv{PEt;0M5@Nqf&FO5|)Q8S8HMWv9 +zhl~IlZsZABy#lHnHYXqr+Q>>KZs<3J81;!Lq)Rt0r1soU1|8L}B2p-vS@olXX79F% +z9~&GBNZGiiCWHjT){6D340&%VByy=N#5;V==>Zrp!I?uW8vid8t`h*$cXJ05`hRbF +zF1Ir?E2?Flf&KMZne5M+gA4Vqxpe0q>x0?Fn4@sf(T1sbZlnOgT+G +ze>9vpEXD(hQbFAN-*~#;&h&|OHrH!t%%*&}X9rNW6Llsni!?nj8W+A$%V4JQ<2D31 +z&wJ`cVEO)VkFH$yU^X4ZaB|qWxVCEn{jL8`z!;`;)o_;xm%`n96hV0sw4X|I%!}%H +z)k^k7JFSy2anEqQ@E*3Y-YP05<`{w42Zke&PF~=FfElbCF-g5dR_rm#g=s5940s__ +zZaStFnrA=Vg4PtMNHe72&e4%2-bZ7%8FTlGkl&A{X!zd$scMbBdDD@4kO`Yn`lNBf +zgVHrdNW5b0Jg-u!sTdb5Nn;0kFkLs$^beC6Xf&5I$f31zU0;Xx!OcO%`#r@|I;fsH +z5g$tY$%?MCE4PU)WyIXw17{|q{6n?IL6F1xa|g;h3x5Xj3JFK}8zMu)J7a?tRTjEx +z!YZxfvU8}jZyI_yEZD;Fdhj^fz>Iq}n4Gi%vpZ+7X3pVBJN9P&kjH^st6Z<)_lQqKv?7)fEOYk{)$f!w +zl48Yz2+-nCbk{MLrH3|`s3-e1z}t&|ay<~_0dQs^{OG?j?}DB%6A +z_ICIKn)qHn@*(szTgUOIH9Y1U;*j#hyYx|cxJW(~JlW-6jEVQGI3Ydt7Ue4RB5cl+ +zV$BDSESQm|B~I_kCk#VB*o|9##M1{```2@nq)q)zU!Wi-f2a&r5Be<}GSJi}JiD*xv +zlRUpuq6z6!2eI8`^J55?n^n=(C=7s@!mCw7JQLNjY<1(L5N!azdQ>IyKkK~dal9EY9!)i?tCj^f +zmW$O%DN3#4om0=}NLSt3Ql%*``;$d?_ZpLsAwK4pY|n{h(Zt4-tb9>$|2#+9hbEsLbt+ +zyqH1j9Ud4d84i(RK&tzIrGW`#Zsmhq7+vGF(H@u{BWGvrmo>J@C+=7i)a@_E?(Ld? +zhIHnb9tJAGXPTeUEG!jQ#z!v-60>)zL|uhYrjba9?Db66Q^6(r+`WJRXVcq5?)!V` +z8C%^=%FGnvW%e@jm$-Fci +zIv$|XW!2!FDv$nscT94!1WJezs?Qjhg6)8BF6;`2*P>%1^X1zvR1E#CDz|if*5deP +z_G;wu2;-m2i7cCZEe58Y)Km1Rc&1E+P<{b|WT^R$}h+0KASd$24A+c#qi?7VN +z8~(N+s5u$NoPnpyHJ^WweCFHZw}~2r^_V`VcWqQDq%y%AWZ}i*+HKmmjb!$24A6(K +zfIkcL>&~~2t2LJbl!5N6JjS)!g?nz%F?U2%9W>o6#NWs+Ew||o$=UL5QL|vQaqlUTi +zn||nh%w6Wn_FQtNUAJ#4x&qzkS?@V4vKhBFmeJVZ`x^g7ehw>OJ`K51=RGHYa$%XC0u~@mo{@ +zQnu8wE9=)p$6pLq>;0yIarD;!8OnLCw`XbG>G$6J=uo+1YDT}DMTA^5k(lGsj8Gd$ +z7Td{+9a^@rosAa;-T7+9{MQz6D&01tH+zY$;!U$jyvKb+aC@K+)fyoiLH4~m0Dhbk +z;!xrEU)vs;b9g~qTI@kgV8+8+t*9$cpCFh({szEZ@s|lh9J61Pe50P~Exc5TejXKu +zHvn8$ZhIj|o20Fic5J*cm(BE1_g9(>aF^@*(dB}huc`CTnIpmK!&{K7z +z2@ni;9W;wYsC_0bVc0@T9a9;xqq_dVgBT!ODqO{#O&tJ +z=nMX79Fd(BNtD_anv21Q_ERM3$n}H0{GfregQRsub=|oc34^1E1-Qk+Bua}}9)_M$ +zAP1{i;0_sVwG|t~L25LK?UfI-q+ubx*MXPCTHN`NP$&<^;0;!UgRcWsVKpZHa~tv9 +bPsEJav4jTW#X4ZBiEWB47NnWeA!0cUWns1? + +literal 0 +HcmV?d00001 + +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.pem b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.pem +new file mode 100644 +index 00000000..16b13a45 +--- /dev/null ++++ b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha224.pem +@@ -0,0 +1,54 @@ ++-----BEGIN ENCRYPTED PRIVATE KEY----- ++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 ++ZuoG/kXvaiCSaP0ceg== ++-----END ENCRYPTED PRIVATE KEY----- +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha256.der b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha256.der +new file mode 100644 +index 0000000000000000000000000000000000000000..460fec89132938172b51bcda4afe83ff843b8ba8 +GIT binary patch +literal 2461 +zcmV;O31apzf(e;0O9lxlhDe6@4FLrWFg`FT1_>&LNQU&90UlMC7T~- +z0tf&w3m^ +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 +zxX*7YFD0ZcE~|mKjMX2z3&Y0J6uT`I +z7RGc%!A!vK;~&D9zk73rClHV3Mq=|yAc|axf7pNTu0T;ubz)OeQV=%htfmi#kT$lw +zBnxenh@wx7X?A-<0KLI8LVt`wiN%IV37nAf5Zar9Gu@gd?}pTwl0H*(`hJT>?2T_$ +z1&}gpP5Yx#&o}~3Ou-RykhS>If|LNfHfsWFc1{Y@H_-Q~)w~l}x$i}GuS|4nWk;hCL5LisY(R7Y4qR_nD +z!)AE{qFb0FrJ`0)?MJalV-E>cql>pW1tV9g0CA;Qynwns_5*9@Dw{Nik$1tTkUdPD +zrGw7iiXZe;OG05~Ku7jqu^a(cW8hk6Pl6TNK@=W}PJnzMpV>9Lz_foLrFHP<8Pxi0 +zT`E+}d1c9(VdkRO54p1i+bwmw?`QQuAD$q}zl)K$B2UZKhc%1!erjcgmr~K~gknh2 +zqqA|1QfBjw7`qn%2q#t~)hk|moU*91EgJaH?pm#%k&PYftMU+izn*n>h+ztS6VMfI +zNk-z=1{UMC<SgC3F(j=WC&uGQaW{VylKhrPfqkE-X +z;2!W1J8dVUH(kPyso;W^FVCrOsc3aSfqURL{nH2%`~TUaPTs|I&#}=SVSZiRH$&(x +z{2w0dHlt`Pi+9L)T4bl+lIQ#i#X`rXM}8#t#$f_tVit_dxt7XG*c)ERxan~^o3?G7 +zEcNW=ivfl9!&#emEvC%)FjV3*Ekm6Rmr8z{@5Qjz>fLCY1f+UH_KowCO;vB{7N!=g +zD*eVFOCin5s?mNQLuVh1sbW_tNrUO1iZ$iwL5%j +zC5iNZ43BagH@LzsQPj)!B6>uot$`D$LA5%bCqXOz59l>6qRY%aNUar!#ww;JA}sAA +z#`6YmNf`aqW^z=QGa^6{CC$C5Us0DX9UczYDBoY<1*dJ5BxYrOH@|?{F9mKl!JL0R +zM>otoFFHDwVB%Z~gJd3!fvj*6I&cPU>X_UF|Bh^bjCc`I&Ip%q8~y0rLA(%rfBL_L +zSkW^vynN>2`|*}Zvu^MrRL@Kv4QzSk0@H?(bhmu}A$?gzh#o76wkV#0TW`;ulf;w8 +zXch*qyx;M{LumP{X{M%K>##@n?+x?NPWj+WG*acS87=!v?*X-eyRZ>Eu`5Lrlq4p^et6}_Ru +bSm+*sM*?^b>6&LNQU&90Ul(W|R5lgs$ZR +z0tf&w3k)74gr*hPTEhw{;BX20s@JZrB34{{>hzz6}L% +zn=6JPWzl%~B<=c31?speFn)D$ySTX%YM957Z6{@w5vEA20k*sIxu1$MacjPW$G31g +zejJgxhd0Cnhlu!+=uWfKQeAHN$ +zcTZ!Ul7NNHk4T)<2xYGAV>FC~%@dT=>}4&)c{Hgdnw^Bwe&QSu-(I)|;B*`;g+VA% +zey#CjaTQ@IJ7tMpr3?{~Oa5^AF2=_(YFKTb^IGqZoA4iIrgFQ-z+RPG!mZ}xOUOvA +zZz+(f(bIqpVwCoq_Uv6RAHGZOfC6WI#4M47-5}Z?5VKw}G&WI(W0>RzuEKES6;Q^e +zFjcwtwQ|sr6En*jH8902xfWY9*_-&}-dG_ka&MJVEhSKwrTX_G%bMzAkOXBV{MzDu +z#p)u@#1YI*Io9aPfByxjf>E`5A=3wfCR@BGrvU@1we*9Gbucy7A+|Q$pVrO`5t9hx +z{Jq`F=d}hO!b1_3)8ft}7r2F!Es&Ee@9Nxy-~J{cQLt`S<$*n;OKk2?T@#>I7DsTU +z%Fr&Gl)y^6roi|$0{YmoU6!CBulUPw2y+7@CxHPXRw-R(4aSL_eOlkqji1iCu1!O7 +zdhC6+NWhWRT}Z3`2*UWZ_^y@Q2xY>pi)VmmQUZyiG{}+MGHHncbldKsP?0wivxS&p +zyS_d0l%Dlb4<$FOa`oKsWq=NtzJVQ>s#7JY@)_mG~KzpeQp}osE}>?WJMK@w8|-nKT7dH +zadk$qwvG?MOf0cC7_$rc6jF{6!+_ebroQ6@(hQ_E6jp%}G)J#HLFQDr) +zhW5J$3w(_V;Z%~w@8AkTn!OQ2<`6b3kMK}clbYTWib|ab2L>OJZk*tbk0a^t8y`yJ +zK%crYXUyz2cum?wrpHGW6;Q!GCPA(4ea%BKQ=mXqHb=m9Oiidje|EhSQUJ-r#!Ihi +zZTp&EGtgV)D4Qf>&}J6aatRZ3wP0aH)VOwu0Pv}WGt^u$f5z +z==k{eE1HQ0^Ly3LF>XFveeD~JC0RbSOIb_f0oOK!h<%!8G<&8u?di&u!3=)^8f+Ml +zxPr=%pH51S5~G5~{GQLi=x9}=OMLR!QVw|?!y-o_IP7*Ai5MueNf9OfpDHnk{JGGL +z&Qm*rEqf=+eslMhE+A!+f4TvJjs+Y_Xf;*;5xt^L#{YapFWIA|LPp#bUag#>!TY>^*TMtt +zk?98H(g*P#YRRe~Q70%WIAiPa&gT-|A^SDjATGQ1p_YB?f-QVpq~)%D^>$S6H3fQpqQSsfamy}q76!;AI +z0QG(~giSZJPQFXF{php`+t*9zgWI?Vx%=;`RrQSax^ZI&7F7t$ppS&C_+sCJ>oz`- +zX@hzR+FLDQsAkYuZzV`GE&<4AYP4)#=7Et2 +zMxZSqibR)W41AiE*wB!*c3*_9$7P!zmzYu}0D!_;2PTa-qjF33hGckuOb3#ew1)MA +z(B|ZF-s**H5a6YD%G;kvt91O-%WKlA +z%*MIn#x@?&K4sQ;9Xu6&SMv(Zsw~iUe%({MKrsVIU6Fu+@v4p)O3{%p38BNL$9;BA +zAA3sa6JSR^L9Q3ximkDIXeg)FV#u}`Iw%N|Uc5hD#G3bK?UED>wmRTGUpls$xn*{Q +zfW`kY3}$wC!L*A@0@|>f;K1lyeEhuE6YuXPn;UVaRV%BffvmygLr%0+4}zlheoIpj +zLA!UpkGnDS>pKLg%PMd)SDgywWFxmRDKD~BJIXbC{Y +z8#-7M-24LT)M2hXILppKsC$}OletU_bUe-ik7Tr%cNV~g%uNh7 +zaOaA>H^9#y_=))N)jcWW5RKryzTA#F#8}mNyF!$d7~chQc!Ly^NMdv&_d_0A5}J8c=av|2P_8(+3S@>2dl^&Sxl?;brbK7^=SCO#K3DIk@NAW +z45y?~VN+OWLNj2|GIuECiB7Bv_e(}|CpLm&kocOJEbkch$K5D5tZYy3ehkxEXTs34 +zBMDQ@Q;ToXBv8dqvklzjqf^4-G2oj`43QU)t~jk?^AaY8(a(4WQWdTwSQNqbi_Pdx +zzJNjWuQHByvS(i`6|M~3%YkC^Evw*RZk@1{N*3RR*nLB!_{y_s{=~DoTp5)iEa<=H +bj>dCj?&mAXi&F{ARYpAz$k=4#E_aPOF5T4# + +literal 0 +HcmV?d00001 + +diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.pem b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.pem +new file mode 100644 +index 00000000..11504a6c +--- /dev/null ++++ b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.pem +@@ -0,0 +1,54 @@ ++-----BEGIN ENCRYPTED PRIVATE KEY----- ++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 ++3u+3zMTCMRDNhiJb3g== ++-----END ENCRYPTED PRIVATE KEY----- +-- +2.16.2 + diff --git a/deps/mbedtls/patches/0006-tests_suite_pkparse-new-PKCS8-v2-keys-with-PRF-SHA1.patch b/deps/mbedtls/patches/0006-tests_suite_pkparse-new-PKCS8-v2-keys-with-PRF-SHA1.patch new file mode 100644 index 0000000..b5b1614 --- /dev/null +++ b/deps/mbedtls/patches/0006-tests_suite_pkparse-new-PKCS8-v2-keys-with-PRF-SHA1.patch @@ -0,0 +1,604 @@ +From 7ed2575f310fd889fba025aa760f74ec1b41924b Mon Sep 17 00:00:00 2001 +From: Antonio Quartulli +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 +--- + 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 + diff --git a/openvpn/addr/route.hpp b/openvpn/addr/route.hpp index a7f1207..0aa1fdd 100644 --- a/openvpn/addr/route.hpp +++ b/openvpn/addr/route.hpp @@ -26,6 +26,7 @@ #include #include #include // for std::uint32_t +#include #include #include @@ -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 diff --git a/openvpn/apple/cf/cfhelper.hpp b/openvpn/apple/cf/cfhelper.hpp index 3960ed1..4c8d336 100644 --- a/openvpn/apple/cf/cfhelper.hpp +++ b/openvpn/apple/cf/cfhelper.hpp @@ -33,7 +33,7 @@ namespace openvpn { namespace CF { // essentially a vector of void *, used as source for array and dictionary constructors - typedef BufferAllocatedType SrcList; + typedef BufferAllocatedType SrcList; inline Array array(const SrcList& values) { diff --git a/openvpn/apple/maclife.hpp b/openvpn/apple/maclife.hpp index 143a240..e1a32ec 100644 --- a/openvpn/apple/maclife.hpp +++ b/openvpn/apple/maclife.hpp @@ -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()); } } diff --git a/openvpn/asio/asioboundsock.hpp b/openvpn/asio/asioboundsock.hpp index 2ae120e..f116751 100644 --- a/openvpn/asio/asioboundsock.hpp +++ b/openvpn/asio/asioboundsock.hpp @@ -30,6 +30,7 @@ #include #include +#include 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; }; diff --git a/openvpn/asio/asiopolysock.hpp b/openvpn/asio/asiopolysock.hpp index a3a06b7..d7f95d5 100644 --- a/openvpn/asio/asiopolysock.hpp +++ b/openvpn/asio/asiopolysock.hpp @@ -36,7 +36,9 @@ #include #include -#ifdef OPENVPN_POLYSOCK_SUPPORTS_BIND +#if defined(OPENVPN_POLYSOCK_SUPPORTS_ALT_ROUTING) +#include +#elif defined(OPENVPN_POLYSOCK_SUPPORTS_BIND) #include #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 diff --git a/openvpn/asio/asioresolverres.hpp b/openvpn/asio/asioresolverres.hpp new file mode 100644 index 0000000..627f1cf --- /dev/null +++ b/openvpn/asio/asioresolverres.hpp @@ -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 . + +#pragma once + +#include + +#include + +namespace openvpn { + + template + 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; + } + +} diff --git a/openvpn/auth/authcreds.hpp b/openvpn/auth/authcreds.hpp index 3b68225..43fec46 100644 --- a/openvpn/auth/authcreds.hpp +++ b/openvpn/auth/authcreds.hpp @@ -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 diff --git a/openvpn/auth/validatecreds.hpp b/openvpn/auth/validatecreds.hpp index 8b45b64..fe02f34 100644 --- a/openvpn/auth/validatecreds.hpp +++ b/openvpn/auth/validatecreds.hpp @@ -25,19 +25,38 @@ #include 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 - 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 + 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); + } } } diff --git a/openvpn/buffer/buffer.hpp b/openvpn/buffer/buffer.hpp index 41af8a2..9ee1927 100644 --- a/openvpn/buffer/buffer.hpp +++ b/openvpn/buffer/buffer.hpp @@ -53,7 +53,7 @@ #include #include #include -#include // for std::is_nothrow_move_constructible +#include // for std::is_nothrow_move_constructible, std::remove_const #ifndef OPENVPN_NO_IO #include @@ -136,11 +136,17 @@ namespace openvpn { Status status_; }; + template + class BufferAllocatedType; + template class BufferType { + template friend class BufferAllocatedType; + public: typedef T* type; typedef const T* const_type; + typedef typename std::remove_const::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 + template class BufferAllocatedType : public BufferType, public RC { using BufferType::data_; @@ -583,6 +589,8 @@ namespace openvpn { using BufferType::size_; using BufferType::capacity_; + template friend class BufferAllocatedType; + public: enum { CONSTRUCT_ZERO = (1<<0), // if enabled, constructors/init will zero allocated space @@ -636,19 +644,19 @@ namespace openvpn { } } - template - BufferAllocatedType(const BufferType& other, const unsigned int flags) + template + BufferAllocatedType(const BufferType& 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::init_headroom(headroom); } - void move(BufferAllocatedType& other) + template + void move(BufferAllocatedType& other) { if (data_) delete_(data_, capacity_, flags_); move_(other); } - RCPtr> move_to_ptr() + RCPtr> move_to_ptr() { - RCPtr> bp = new BufferAllocatedType(); + RCPtr> bp = new BufferAllocatedType(); bp->move(*this); return bp; } @@ -747,7 +756,8 @@ namespace openvpn { std::swap(flags_, other.flags_); } - BufferAllocatedType(BufferAllocatedType&& other) noexcept + template + BufferAllocatedType(BufferAllocatedType&& other) noexcept { move_(other); } @@ -812,7 +822,8 @@ namespace openvpn { capacity_ = newcap; } - void move_(BufferAllocatedType& other) + template + void move_(BufferAllocatedType& other) { data_ = other.data_; offset_ = other.offset_; @@ -844,17 +855,30 @@ namespace openvpn { unsigned int flags_; }; + // specializations of BufferType for unsigned char typedef BufferType Buffer; typedef BufferType ConstBuffer; - typedef BufferAllocatedType BufferAllocated; + typedef BufferAllocatedType BufferAllocated; typedef RCPtr BufferPtr; + // BufferAllocated with thread-safe refcount + typedef BufferAllocatedType BufferAllocatedTS; + typedef RCPtr BufferPtrTS; + + // cast BufferType to BufferType + template inline BufferType& const_buffer_ref(BufferType& src) { return (BufferType&)src; } + template + inline const BufferType& const_buffer_ref(const BufferType& src) + { + return (const BufferType&)src; + } + } // namespace openvpn #endif // OPENVPN_BUFFER_BUFFER_H diff --git a/openvpn/buffer/bufstr.hpp b/openvpn/buffer/bufstr.hpp index 8c30e10..1dd733c 100644 --- a/openvpn/buffer/bufstr.hpp +++ b/openvpn/buffer/bufstr.hpp @@ -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 diff --git a/openvpn/buffer/lz4.hpp b/openvpn/buffer/lz4.hpp new file mode 100644 index 0000000..05313b6 --- /dev/null +++ b/openvpn/buffer/lz4.hpp @@ -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 . + +#pragma once + +#include // for std::uint32_t, uint64_t, etc. + +#include + +#include +#include // for ntohl/htonl +#include + +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; + } + + } +} diff --git a/openvpn/buffer/zlib.hpp b/openvpn/buffer/zlib.hpp index 8d344dc..66d1da8 100644 --- a/openvpn/buffer/zlib.hpp +++ b/openvpn/buffer/zlib.hpp @@ -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 // 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 diff --git a/openvpn/client/cliconnect.hpp b/openvpn/client/cliconnect.hpp index 9bfa1e4..41851b1 100644 --- a/openvpn/client/cliconnect.hpp +++ b/openvpn/client/cliconnect.hpp @@ -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: diff --git a/openvpn/client/cliconstants.hpp b/openvpn/client/cliconstants.hpp index 14b53ad..4d2cee5 100644 --- a/openvpn/client/cliconstants.hpp +++ b/openvpn/client/cliconstants.hpp @@ -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 ..." }; } } diff --git a/openvpn/client/clievent.hpp b/openvpn/client/clievent.hpp index e688974..7a4cf6b 100644 --- a/openvpn/client/clievent.hpp +++ b/openvpn/client/clievent.hpp @@ -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 diff --git a/openvpn/client/cliopt.hpp b/openvpn/client/cliopt.hpp index 2919f6d..29a9116 100644 --- a/openvpn/client/cliopt.hpp +++ b/openvpn/client/cliopt.hpp @@ -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; diff --git a/openvpn/client/cliopthelper.hpp b/openvpn/client/cliopthelper.hpp index b1e1b9d..4fa11f0 100644 --- a/openvpn/client/cliopthelper.hpp +++ b/openvpn/client/cliopthelper.hpp @@ -27,6 +27,7 @@ #include #include #include +#include #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) diff --git a/openvpn/client/cliproto.hpp b/openvpn/client/cliproto.hpp index 47dcff6..74f8e1f 100644 --- a/openvpn/client/cliproto.hpp +++ b/openvpn/client/cliproto.hpp @@ -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()); } } diff --git a/openvpn/client/remotelist.hpp b/openvpn/client/remotelist.hpp index 2ee9076..b9285bc 100644 --- a/openvpn/client/remotelist.hpp +++ b/openvpn/client/remotelist.hpp @@ -137,9 +137,8 @@ namespace openvpn { // cache a list of DNS-resolved IP addresses template - 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) { diff --git a/openvpn/common/actionthread.hpp b/openvpn/common/actionthread.hpp index 88f412f..29f3f52 100644 --- a/openvpn/common/actionthread.hpp +++ b/openvpn/common/actionthread.hpp @@ -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]() { diff --git a/openvpn/common/appversion.hpp b/openvpn/common/appversion.hpp index 3441ba3..ecdc9c4 100644 --- a/openvpn/common/appversion.hpp +++ b/openvpn/common/appversion.hpp @@ -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 -#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 diff --git a/openvpn/common/enumdir.hpp b/openvpn/common/enumdir.hpp index 7e93b38..00ef6ed 100644 --- a/openvpn/common/enumdir.hpp +++ b/openvpn/common/enumdir.hpp @@ -34,10 +34,28 @@ #include #include #include +#include namespace openvpn { OPENVPN_EXCEPTION(enum_dir_error); + inline bool enum_dir(const std::string& dirname, + Function func) + { + unique_ptr_del 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 enum_dir(const std::string& dirname, const size_t size_hint=0, const bool sort=false) @@ -45,23 +63,18 @@ namespace openvpn { std::vector ret; if (size_hint) ret.reserve(size_hint); - unique_ptr_del 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 diff --git a/openvpn/common/fileatomic.hpp b/openvpn/common/fileatomic.hpp index 2713f56..1107a85 100644 --- a/openvpn/common/fileatomic.hpp +++ b/openvpn/common/fileatomic.hpp @@ -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 diff --git a/openvpn/common/fileunix.hpp b/openvpn/common/fileunix.hpp index ed2526a..cc6efa5 100644 --- a/openvpn/common/fileunix.hpp +++ b/openvpn/common/fileunix.hpp @@ -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) diff --git a/openvpn/common/hostport.hpp b/openvpn/common/hostport.hpp index 572b7e6..54d8e24 100644 --- a/openvpn/common/hostport.hpp +++ b/openvpn/common/hostport.hpp @@ -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); } } diff --git a/openvpn/common/options.hpp b/openvpn/common/options.hpp index 9fda7db..82ddfc5 100644 --- a/openvpn/common/options.hpp +++ b/openvpn/common/options.hpp @@ -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)...); } static validate_status validate(const std::string& str, const size_t max_len) @@ -360,8 +360,8 @@ namespace openvpn { template void from_list(T first, Args... args) { - from_list(first); - from_list(args...); + from_list(std::move(first)); + from_list(std::forward(args)...); } volatile mutable bool touched_ = false; @@ -661,6 +661,18 @@ namespace openvpn { } }; + OptionList() + { + } + + template + OptionList(T first, Args... args) + { + reserve(1 + sizeof...(args)); + from_list(std::move(first), std::forward(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 + void from_list(T first, Args... args) + { + from_list(std::move(first)); + from_list(std::forward(args)...); + } + IndexMap map_; }; diff --git a/openvpn/common/process.hpp b/openvpn/common/process.hpp index d541e52..05c8696 100644 --- a/openvpn/common/process.hpp +++ b/openvpn/common/process.hpp @@ -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; diff --git a/openvpn/common/redir.hpp b/openvpn/common/redir.hpp index 92f287b..fdb072f 100644 --- a/openvpn/common/redir.hpp +++ b/openvpn/common/redir.hpp @@ -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 send_in; + std::unique_ptr recv_out; + std::unique_ptr 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; }; } diff --git a/openvpn/common/string.hpp b/openvpn/common/string.hpp index 07d6afd..7fa386a 100644 --- a/openvpn/common/string.hpp +++ b/openvpn/common/string.hpp @@ -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) diff --git a/openvpn/common/version.hpp b/openvpn/common/version.hpp index d2c633a..21d4a65 100644 --- a/openvpn/common/version.hpp +++ b/openvpn/common/version.hpp @@ -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 diff --git a/openvpn/common/waitbarrier.hpp b/openvpn/common/waitbarrier.hpp index 02c32b2..604f38e 100644 --- a/openvpn/common/waitbarrier.hpp +++ b/openvpn/common/waitbarrier.hpp @@ -28,7 +28,7 @@ namespace openvpn { template 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)) diff --git a/openvpn/crypto/static_key.hpp b/openvpn/crypto/static_key.hpp index 082b1a8..4ad3fd4 100644 --- a/openvpn/crypto/static_key.hpp +++ b/openvpn/crypto/static_key.hpp @@ -40,7 +40,7 @@ namespace openvpn { class StaticKey { friend class OpenVPNStaticKey; - typedef BufferAllocatedType key_t; + typedef BufferAllocated key_t; public: StaticKey() {} diff --git a/openvpn/linux/core.hpp b/openvpn/linux/core.hpp index 22e90d3..1752932 100644 --- a/openvpn/linux/core.hpp +++ b/openvpn/linux/core.hpp @@ -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 diff --git a/openvpn/mbedtls/ssl/sslctx.hpp b/openvpn/mbedtls/ssl/sslctx.hpp index 897e0bb..c784986 100644 --- a/openvpn/mbedtls/ssl/sslctx.hpp +++ b/openvpn/mbedtls/ssl/sslctx.hpp @@ -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; } } diff --git a/openvpn/netconf/linux/gw.hpp b/openvpn/netconf/linux/gw.hpp index c0f4bf8..8681833 100644 --- a/openvpn/netconf/linux/gw.hpp +++ b/openvpn/netconf/linux/gw.hpp @@ -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; diff --git a/openvpn/openssl/ssl/sslctx.hpp b/openvpn/openssl/ssl/sslctx.hpp index bcb9100..cfc8d15 100644 --- a/openvpn/openssl/ssl/sslctx.hpp +++ b/openvpn/openssl/ssl/sslctx.hpp @@ -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; } diff --git a/openvpn/server/listenlist.hpp b/openvpn/server/listenlist.hpp index 64f9444..c8e6343 100644 --- a/openvpn/server/listenlist.hpp +++ b/openvpn/server/listenlist.hpp @@ -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"); } diff --git a/openvpn/server/manage.hpp b/openvpn/server/manage.hpp index c8b0fcd..d1ce2a9 100644 --- a/openvpn/server/manage.hpp +++ b/openvpn/server/manage.hpp @@ -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; diff --git a/openvpn/server/servproto.hpp b/openvpn/server/servproto.hpp index 661c02a..547a866 100644 --- a/openvpn/server/servproto.hpp +++ b/openvpn/server/servproto.hpp @@ -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(); } } } diff --git a/openvpn/ssl/proto.hpp b/openvpn/ssl/proto.hpp index 2f0d482..7a7b2c1 100644 --- a/openvpn/ssl/proto.hpp +++ b/openvpn/ssl/proto.hpp @@ -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; } diff --git a/openvpn/transport/tcplink.hpp b/openvpn/transport/tcplink.hpp index f081a1d..5499b5f 100644 --- a/openvpn/transport/tcplink.hpp +++ b/openvpn/transport/tcplink.hpp @@ -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(); diff --git a/openvpn/transport/udplink.hpp b/openvpn/transport/udplink.hpp index 241533d..bb2ee4a 100644 --- a/openvpn/transport/udplink.hpp +++ b/openvpn/transport/udplink.hpp @@ -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(); } diff --git a/openvpn/tun/client/tunprop.hpp b/openvpn/tun/client/tunprop.hpp index 384a841..5631e1e 100644 --- a/openvpn/tun/client/tunprop.hpp +++ b/openvpn/tun/client/tunprop.hpp @@ -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()); } } } diff --git a/openvpn/tun/linux/client/tuncli.hpp b/openvpn/tun/linux/client/tuncli.hpp index b8f6d83..fccccdd 100644 --- a/openvpn/tun/linux/client/tuncli.hpp +++ b/openvpn/tun/linux/client/tuncli.hpp @@ -24,307 +24,49 @@ #ifndef OPENVPN_TUN_LINUX_CLIENT_TUNCLI_H #define OPENVPN_TUN_LINUX_CLIENT_TUNCLI_H -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include 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 SPtr; + BufferAllocated buf; }; - inline IP::Addr cvt_pnr_ip_v4(const std::string& hexaddr) + template + class Tun : public TunIO { - 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 Base; - inline IP::Addr get_default_gateway_v4() - { - typedef std::vector 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(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 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* 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* 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* 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* 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 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; }; diff --git a/openvpn/tun/linux/client/tunsetup.hpp b/openvpn/tun/linux/client/tunsetup.hpp new file mode 100644 index 0000000..b9accc0 --- /dev/null +++ b/openvpn/tun/linux/client/tunsetup.hpp @@ -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 . + +// Client tun interface for Linux. + +#ifndef OPENVPN_TUN_LINUX_CLIENT_TUNSETUP_H +#define OPENVPN_TUN_LINUX_CLIENT_TUNSETUP_H + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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* 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* 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* 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* 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 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); + 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 diff --git a/openvpn/tun/linux/tun.hpp b/openvpn/tun/linux/tun.hpp deleted file mode 100644 index da15a20..0000000 --- a/openvpn/tun/linux/tun.hpp +++ /dev/null @@ -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 . - -// Low-level tun interface driver for Linux, client/server independent. - -#ifndef OPENVPN_TUN_LINUX_TUN_H -#define OPENVPN_TUN_LINUX_TUN_H - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace openvpn { - namespace TunLinux { - - struct PacketFrom - { - typedef std::unique_ptr 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 - class Tun : public TunIO - { - typedef TunIO Base; - - public: - typedef RCPtr 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 diff --git a/openvpn/tun/mac/macdns.hpp b/openvpn/tun/mac/macdns.hpp index 570dbab..4121ca3 100644 --- a/openvpn/tun/mac/macdns.hpp +++ b/openvpn/tun/mac/macdns.hpp @@ -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; } diff --git a/openvpn/tun/mac/macdns_watchdog.hpp b/openvpn/tun/mac/macdns_watchdog.hpp index fb183cc..2a92b03 100644 --- a/openvpn/tun/mac/macdns_watchdog.hpp +++ b/openvpn/tun/mac/macdns_watchdog.hpp @@ -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()); } } diff --git a/openvpn/tun/persist/tunpersist.hpp b/openvpn/tun/persist/tunpersist.hpp index f1dd28c..dc8d074 100644 --- a/openvpn/tun/persist/tunpersist.hpp +++ b/openvpn/tun/persist/tunpersist.hpp @@ -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 diff --git a/openvpn/tun/persist/tunwrap.hpp b/openvpn/tun/persist/tunwrap.hpp index 144572f..949776c 100644 --- a/openvpn/tun/persist/tunwrap.hpp +++ b/openvpn/tun/persist/tunwrap.hpp @@ -83,7 +83,7 @@ namespace openvpn { } catch (const std::exception& e) { - OPENVPN_LOG("TunWrap destructor: " << e.what()); + OPENVPN_LOG("TunWrap destructor exception: " << e.what()); } } diff --git a/openvpn/tun/tunio.hpp b/openvpn/tun/tunio.hpp index c1cb0c3..0a5098a 100644 --- a/openvpn/tun/tunio.hpp +++ b/openvpn/tun/tunio.hpp @@ -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) diff --git a/test/ovpncli/cli.cpp b/test/ovpncli/cli.cpp index 42d0843..717066c 100644 --- a/test/ovpncli/cli.cpp +++ b/test/ovpncli/cli.cpp @@ -68,6 +68,10 @@ #include #include +#ifdef OPENVPN_REMOTE_OVERRIDE +#include +#endif + #if defined(USE_MBEDTLS) #include #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 / + 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; diff --git a/test/ovpncli/go b/test/ovpncli/go index a95a92b..d059d22 100755 --- a/test/ovpncli/go +++ b/test/ovpncli/go @@ -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 diff --git a/test/unittests/unittests.vcxproj b/test/unittests/unittests.vcxproj index e842664..1d1e793 100644 --- a/test/unittests/unittests.vcxproj +++ b/test/unittests/unittests.vcxproj @@ -88,14 +88,14 @@ TurnOffAllWarnings Disabled false - $(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) + $(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) MultiThreadedDebug _CRT_SECURE_NO_WARNINGS;NOMINMAX;_WIN32_WINNT=0x0600;USE_ASIO;ASIO_STANDALONE;USE_MBEDTLS;HAVE_LZ4;OPENVPN_FORCE_TUN_NULL;_DEBUG;%(PreprocessorDefinitions) true lz4.lib;mbedtls.lib;Iphlpapi.lib;gtest.lib;%(AdditionalDependencies) - $(OVPN3_BUILD)\amd64\mbedtls\library;$(GTEST_ROOT)\googlemock\gtest\Debug\;%(AdditionalLibraryDirectories);$(OVPN3_BUILD)\amd64\lz4\lib + $(OVPN3_ROOT)\deps\amd64\mbedtls\library;$(GTEST_ROOT)\googlemock\gtest\Debug\;%(AdditionalLibraryDirectories);$(OVPN3_ROOT)\deps\amd64\lz4\lib @@ -123,7 +123,7 @@ true true false - $(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) + $(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) _CRT_SECURE_NO_WARNINGS;NOMINMAX;_WIN32_WINNT=0x0600;USE_ASIO;ASIO_STANDALONE;USE_MBEDTLS;HAVE_LZ4;OPENVPN_FORCE_TUN_NULL;%(PreprocessorDefinitions) @@ -131,7 +131,7 @@ true true lz4.lib;mbedtls.lib;Iphlpapi.lib;gtest.lib;%(AdditionalDependencies) - $(OVPN3_BUILD)\amd64\mbedtls\library;$(GTEST_ROOT)\googlemock\gtest\Release\;%(AdditionalLibraryDirectories);$(OVPN3_BUILD)\amd64\lz4\lib + $(OVPN3_ROOT)\deps\amd64\mbedtls\library;$(GTEST_ROOT)\googlemock\gtest\Release\;%(AdditionalLibraryDirectories);$(OVPN3_ROOT)\deps\amd64\lz4\lib diff --git a/vars/vars-osx b/vars/vars-osx index c27cabb..e4dc8c0 100644 --- a/vars/vars-osx +++ b/vars/vars-osx @@ -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++ diff --git a/vars/vars-osx-dbg b/vars/vars-osx-dbg index 721f512..34f5f5d 100644 --- a/vars/vars-osx-dbg +++ b/vars/vars-osx-dbg @@ -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++ diff --git a/vars/vars-osx64 b/vars/vars-osx64 index d5bb4aa..72e742c 100644 --- a/vars/vars-osx64 +++ b/vars/vars-osx64 @@ -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++ diff --git a/vars/vars-osx64-dbg b/vars/vars-osx64-dbg index 0652b34..635556d 100644 --- a/vars/vars-osx64-dbg +++ b/vars/vars-osx64-dbg @@ -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++ diff --git a/win/build.py b/win/build.py index 7906eaa..ff67364 100644 --- a/win/build.py +++ b/win/build.py @@ -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) diff --git a/win/buildep.py b/win/buildep.py index ecd831f..1d48489 100644 --- a/win/buildep.py +++ b/win/buildep.py @@ -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()) diff --git a/win/ovpn3-core.vcxproj b/win/ovpn3-core.vcxproj index 678afa4..5d670e8 100644 --- a/win/ovpn3-core.vcxproj +++ b/win/ovpn3-core.vcxproj @@ -460,7 +460,7 @@ Disabled false _CRT_SECURE_NO_WARNINGS;NOMINMAX;_WIN32_WINNT=0x0600;USE_ASIO;ASIO_STANDALONE;USE_MBEDTLS;HAVE_LZ4;TAP_WIN_COMPONENT_ID=tap0901;%(PreprocessorDefinitions) - $(OVPN3_BUILD)\amd64\mbedtls\include;$(OVPN3_TAP_WINDOWS)\src;$(OVPN3_BUILD)\amd64\asio\asio\include;$(OVPN3_BUILD)\amd64\lz4\lib;$(OVPN3_CORE);%(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) false ProgramDatabase /bigobj %(AdditionalOptions) @@ -468,7 +468,7 @@ true - $(OVPN3_BUILD)\amd64\mbedtls\library;$(OVPN3_BUILD)\amd64\lz4\lib;%(AdditionalLibraryDirectories) + $(OVPN3_ROOT)\deps\amd64\mbedtls\library;$(OVPN3_ROOT)\deps\amd64\lz4\lib;%(AdditionalLibraryDirectories) 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 NotSet @@ -499,14 +499,14 @@ true false _CRT_SECURE_NO_WARNINGS;NOMINMAX;_WIN32_WINNT=0x0600;USE_ASIO;ASIO_STANDALONE;USE_MBEDTLS;HAVE_LZ4;TAP_WIN_COMPONENT_ID=tap0901;%(PreprocessorDefinitions) - $(OVPN3_BUILD)\amd64\mbedtls\include;$(OVPN3_TAP_WINDOWS)\src;$(OVPN3_BUILD)\amd64\asio\asio\include;$(OVPN3_BUILD)\amd64\lz4\lib;$(OVPN3_CORE);%(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) MultiThreaded true true true - $(OVPN3_BUILD)\amd64\mbedtls\library;$(OVPN3_BUILD)\amd64\lz4\lib;%(AdditionalLibraryDirectories) + $(OVPN3_ROOT)\deps\amd64\mbedtls\library;$(OVPN3_ROOT)\deps\amd64\lz4\lib;%(AdditionalLibraryDirectories) 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) diff --git a/win/parms.py b/win/parms.py deleted file mode 100644 index 65d213e..0000000 --- a/win/parms.py +++ /dev/null @@ -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 diff --git a/win/utils.py b/win/utils.py index 4cbccb3..2a2b85b 100644 --- a/win/utils.py +++ b/win/utils.py @@ -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