--- Begin Message ---
- To: Debian Bug Tracking System <submit@bugs.debian.org>
- Subject: bookworm-pu: package openvpn/2.6.3-1+deb12u3
- From: Bernhard Schmidt <berni@debian.org>
- Date: Wed, 30 Apr 2025 23:41:10 +0200
- Message-id: <174604927015.1367712.6716109834796821507.reportbug@fliwatuet.svr02.mucip.net>
Package: release.debian.org
Severity: normal
Tags: bookworm
User: release.debian.org@packages.debian.org
Usertags: pu
X-Debbugs-Cc: openvpn@packages.debian.org
Control: affects -1 + src:openvpn
[ Reason ]
In agreement with the security team I'd like to fix three CVEs in Bookworm
through a normal stable update. The diff is a bit larger than I hoped for,
because the key material included for the build-time _tests_ expired in the
meantime. Aquila Macedo at Ubuntu was kind enough to provide a backport that
has been imported into the package (that's
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1086653)
The only other change is that the Salsa CI pipeline for the bookworm
branch is now using the bookworm environment. After that change there
has been a build error in the Salsa CI about changes to various MSVC
files that I cannot reproduce in an unstable environment on Salsa nor
locally. I fixed that by adding the files to d/source/options. I'm fine
dropping that bookworm-only change if you want me to, but that means the Salsa
CI would not be useful anymore (and I'm not exactly sure whether the
autobuilders will behave like Salsa or like my local sbuild)
[ Impact ]
Package with three (not that severe) CVEs
Package currently cannot be rebuilt due to expired certs in the testsuite
[ Tests ]
- Build time testsuite
- proposed package has been installed on one of on my employers eduVPN nodes
- proposed package has been tested locally
[ Risks ]
The code is non-trivial, but has been imported directly from an upstream commit
already released
[ Checklist ]
[X] *all* changes are documented in the d/changelog
[X] I reviewed all changes and I approve them
[X] attach debdiff against the package in (old)stable
[X] the issue is verified as fixed in unstable
[ Changes ]
See changelog
openvpn (2.6.3-1+deb12u3) bookworm; urgency=medium
[ Bernhard Schmidt ]
* Cherry-Pick upstream fixes for various CVEs (Closes: #1074488)
- CVE-2025-2704: possible ASSERT() on OpenVPN servers using --tls-crypt-v2
(Closes: #1101935)
- CVE-2024-5594: malicious peer can DoS or send garbage to logs
- CVE-2024-28882: client can circumvent management client-kill
both (Closes: #1074488)
* Run salsa pipeline in Bookworm environment
- add d/source/options to make it build in Bookworm Salsa
[ Aquila Macedo ]
* d/p/sample-keys-renew-10-years: import upstream patch to update expired
certificates used in the build-time tests (Closes: #1086653)
-- Bernhard Schmidt <berni@debian.org> Wed, 02 Apr 2025 17:45:15 +0200
[ Other info ]
diffstat for openvpn-2.6.3 openvpn-2.6.3
changelog | 18
patches/CVE-2024-28882.patch | 131 ++
patches/CVE-2024-5594.patch | 355 ++++++
patches/CVE-2025-2704.patch | 282 +++++
patches/sample-keys-renew-10-years.patch | 1618 +++++++++++++++++++++++++++++++
patches/series | 4
salsa-ci.yml | 3
source/options | 2
8 files changed, 2413 insertions(+)
diff -Nru openvpn-2.6.3/debian/changelog openvpn-2.6.3/debian/changelog
--- openvpn-2.6.3/debian/changelog 2023-11-11 23:21:37.000000000 +0100
+++ openvpn-2.6.3/debian/changelog 2025-04-02 17:45:15.000000000 +0200
@@ -1,3 +1,21 @@
+openvpn (2.6.3-1+deb12u3) bookworm; urgency=medium
+
+ [ Bernhard Schmidt ]
+ * Cherry-Pick upstream fixes for various CVEs (Closes: #1074488)
+ - CVE-2025-2704: possible ASSERT() on OpenVPN servers using --tls-crypt-v2
+ (Closes: #1101935)
+ - CVE-2024-5594: malicious peer can DoS or send garbage to logs
+ - CVE-2024-28882: client can circumvent management client-kill
+ both (Closes: #1074488)
+ * Run salsa pipeline in Bookworm environment
+ - add d/source/options to make it build in Bookworm Salsa
+
+ [ Aquila Macedo ]
+ * d/p/sample-keys-renew-10-years: import upstream patch to update expired
+ certificates used in the build-time tests (Closes: #1086653)
+
+ -- Bernhard Schmidt <berni@debian.org> Wed, 02 Apr 2025 17:45:15 +0200
+
openvpn (2.6.3-1+deb12u2) bookworm-security; urgency=medium
* Cherry-Pick upstream fixes for two CVEs
diff -Nru openvpn-2.6.3/debian/patches/CVE-2024-28882.patch openvpn-2.6.3/debian/patches/CVE-2024-28882.patch
--- openvpn-2.6.3/debian/patches/CVE-2024-28882.patch 1970-01-01 01:00:00.000000000 +0100
+++ openvpn-2.6.3/debian/patches/CVE-2024-28882.patch 2025-04-02 17:45:15.000000000 +0200
@@ -0,0 +1,131 @@
+From 65fb67cd6c320a426567b2922c4282fb8738ba3f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Reynir=20Bj=C3=B6rnsson?= <reynir@reynir.dk>
+Date: Thu, 16 May 2024 13:58:08 +0200
+Subject: [PATCH] Only schedule_exit() once
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+If an exit has already been scheduled we should not schedule it again.
+Otherwise, the exit signal is never emitted if the peer reschedules the
+exit before the timeout occurs.
+
+schedule_exit() now only takes the context as argument. The signal is
+hard coded to SIGTERM, and the interval is read directly from the
+context options.
+
+Furthermore, schedule_exit() now returns a bool signifying whether an
+exit was scheduled; false if exit is already scheduled. The call sites
+are updated accordingly. A notable difference is that management is only
+notified *once* when an exit is scheduled - we no longer notify
+management on redundant exit.
+
+This patch was assigned a CVE number after already reviewed and ACKed,
+because it was discovered that a misbehaving client can use the (now
+fixed) server behaviour to avoid being disconnected by means of a
+managment interface "client-kill" command - the security issue here is
+"client can circumvent security policy set by management interface".
+
+This only affects previously authenticated clients, and only management
+client-kill, so normal renegotion / AUTH_FAIL ("your session ends") is not
+affected.
+
+CVE: 2024-28882
+
+Change-Id: I9457f005f4ba970502e6b667d9dc4299a588d661
+Signed-off-by: Reynir Björnsson <reynir@reynir.dk>
+Acked-by: Arne Schwabe <arne-openvpn@rfc2549.org>
+Message-Id: <20240516120434.23499-1-gert@greenie.muc.de>
+URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg28679.html
+Signed-off-by: Gert Doering <gert@greenie.muc.de>
+(cherry picked from commit 55bb3260c12bae33b6a8eac73cbb6972f8517411)
+---
+ src/openvpn/forward.c | 15 +++++++++++----
+ src/openvpn/forward.h | 2 +-
+ src/openvpn/push.c | 12 +++++++-----
+ 3 files changed, 19 insertions(+), 10 deletions(-)
+
+--- a/src/openvpn/forward.c
++++ b/src/openvpn/forward.c
+@@ -516,17 +516,24 @@ check_server_poll_timeout(struct context
+ }
+
+ /*
+- * Schedule a signal n_seconds from now.
++ * Schedule a SIGTERM signal c->options.scheduled_exit_interval seconds from now.
+ */
+-void
+-schedule_exit(struct context *c, const int n_seconds, const int signal)
++bool
++schedule_exit(struct context *c)
+ {
++ const int n_seconds = c->options.scheduled_exit_interval;
++ /* don't reschedule if already scheduled. */
++ if (event_timeout_defined(&c->c2.scheduled_exit))
++ {
++ return false;
++ }
+ tls_set_single_session(c->c2.tls_multi);
+ update_time();
+ reset_coarse_timers(c);
+ event_timeout_init(&c->c2.scheduled_exit, n_seconds, now);
+- c->c2.scheduled_exit_signal = signal;
++ c->c2.scheduled_exit_signal = SIGTERM;
+ msg(D_SCHED_EXIT, "Delayed exit in %d seconds", n_seconds);
++ return true;
+ }
+
+ /*
+--- a/src/openvpn/forward.h
++++ b/src/openvpn/forward.h
+@@ -302,7 +302,7 @@ void reschedule_multi_process(struct con
+
+ void process_ip_header(struct context *c, unsigned int flags, struct buffer *buf);
+
+-void schedule_exit(struct context *c, const int n_seconds, const int signal);
++bool schedule_exit(struct context *c);
+
+ static inline struct link_socket_info *
+ get_link_socket_info(struct context *c)
+--- a/src/openvpn/push.c
++++ b/src/openvpn/push.c
+@@ -206,7 +206,11 @@ receive_exit_message(struct context *c)
+ * */
+ if (c->options.mode == MODE_SERVER)
+ {
+- schedule_exit(c, c->options.scheduled_exit_interval, SIGTERM);
++ if (!schedule_exit(c))
++ {
++ /* Return early when we don't need to notify management */
++ return;
++ }
+ }
+ else
+ {
+@@ -387,7 +391,7 @@ __attribute__ ((format(__printf__, 4, 5)
+ void
+ send_auth_failed(struct context *c, const char *client_reason)
+ {
+- if (event_timeout_defined(&c->c2.scheduled_exit))
++ if (!schedule_exit(c))
+ {
+ msg(D_TLS_DEBUG, "exit already scheduled for context");
+ return;
+@@ -397,8 +401,6 @@ send_auth_failed(struct context *c, cons
+ static const char auth_failed[] = "AUTH_FAILED";
+ size_t len;
+
+- schedule_exit(c, c->options.scheduled_exit_interval, SIGTERM);
+-
+ len = (client_reason ? strlen(client_reason)+1 : 0) + sizeof(auth_failed);
+ if (len > PUSH_BUNDLE_SIZE)
+ {
+@@ -488,7 +490,7 @@ send_auth_pending_messages(struct tls_mu
+ void
+ send_restart(struct context *c, const char *kill_msg)
+ {
+- schedule_exit(c, c->options.scheduled_exit_interval, SIGTERM);
++ schedule_exit(c);
+ send_control_channel_string(c, kill_msg ? kill_msg : "RESTART", D_PUSH);
+ }
+
diff -Nru openvpn-2.6.3/debian/patches/CVE-2024-5594.patch openvpn-2.6.3/debian/patches/CVE-2024-5594.patch
--- openvpn-2.6.3/debian/patches/CVE-2024-5594.patch 1970-01-01 01:00:00.000000000 +0100
+++ openvpn-2.6.3/debian/patches/CVE-2024-5594.patch 2025-04-02 17:45:15.000000000 +0200
@@ -0,0 +1,355 @@
+From 90e7a858e5594d9a019ad2b4ac6154124986291a Mon Sep 17 00:00:00 2001
+From: Arne Schwabe <arne@rfc2549.org>
+Date: Mon, 27 May 2024 15:02:41 +0200
+Subject: [PATCH] Properly handle null bytes and invalid characters in control
+ messages
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This makes OpenVPN more picky in accepting control message in two aspects:
+- Characters are checked in the whole buffer and not until the first
+ NUL byte
+- if the message contains invalid characters, we no longer continue
+ evaluating a fixed up version of the message but rather stop
+ processing it completely.
+
+Previously it was possible to get invalid characters to end up in log
+files or on a terminal.
+
+This also prepares the logic a bit in the direction of having a proper
+framing of control messages separated by null bytes instead of relying
+on the TLS framing for that. All OpenVPN implementations write the 0
+bytes between control commands.
+
+This patch also include several improvement suggestion from Reynir
+(thanks!).
+
+CVE: 2024-5594
+
+Reported-By: Reynir Björnsson <reynir@reynir.dk>
+Change-Id: I0d926f910637dabc89bf5fa919dc6beef1eb46d9
+Signed-off-by: Arne Schwabe <arne@rfc2549.org>
+Acked-by: Antonio Quartulli <a@unstable.cc>
+
+Message-Id: <20240619103004.56460-1-gert@greenie.muc.de>
+URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg28791.html
+Signed-off-by: Gert Doering <gert@greenie.muc.de>
+(cherry picked from commit 414f428fa29694090ec4c46b10a8aba419c85659)
+---
+ src/openvpn/buffer.c | 17 ++++
+ src/openvpn/buffer.h | 11 +++
+ src/openvpn/forward.c | 121 ++++++++++++++++---------
+ tests/unit_tests/openvpn/test_buffer.c | 109 ++++++++++++++++++++++
+ 4 files changed, 215 insertions(+), 43 deletions(-)
+
+--- a/src/openvpn/buffer.c
++++ b/src/openvpn/buffer.c
+@@ -1115,6 +1115,23 @@ string_mod(char *str, const unsigned int
+ return ret;
+ }
+
++bool
++string_check_buf(struct buffer *buf, const unsigned int inclusive, const unsigned int exclusive)
++{
++ ASSERT(buf);
++
++ for (int i = 0; i < BLEN(buf); i++)
++ {
++ char c = BSTR(buf)[i];
++
++ if (!char_inc_exc(c, inclusive, exclusive))
++ {
++ return false;
++ }
++ }
++ return true;
++}
++
+ const char *
+ string_mod_const(const char *str,
+ const unsigned int inclusive,
+--- a/src/openvpn/buffer.h
++++ b/src/openvpn/buffer.h
+@@ -945,6 +945,17 @@ bool string_class(const char *str, const
+
+ bool string_mod(char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace);
+
++/**
++ * Check a buffer if it only consists of allowed characters.
++ *
++ * @param buf The buffer to be checked.
++ * @param inclusive The character classes that are allowed.
++ * @param exclusive Character classes that are not allowed even if they are also in inclusive.
++ * @return True if the string consists only of allowed characters, false otherwise.
++ */
++bool
++string_check_buf(struct buffer *buf, const unsigned int inclusive, const unsigned int exclusive);
++
+ const char *string_mod_const(const char *str,
+ const unsigned int inclusive,
+ const unsigned int exclusive,
+--- a/src/openvpn/forward.c
++++ b/src/openvpn/forward.c
+@@ -232,6 +232,51 @@ check_tls(struct context *c)
+ }
+ }
+
++static void
++parse_incoming_control_channel_command(struct context *c, struct buffer *buf)
++{
++ if (buf_string_match_head_str(buf, "AUTH_FAILED"))
++ {
++ receive_auth_failed(c, buf);
++ }
++ else if (buf_string_match_head_str(buf, "PUSH_"))
++ {
++ incoming_push_message(c, buf);
++ }
++ else if (buf_string_match_head_str(buf, "RESTART"))
++ {
++ server_pushed_signal(c, buf, true, 7);
++ }
++ else if (buf_string_match_head_str(buf, "HALT"))
++ {
++ server_pushed_signal(c, buf, false, 4);
++ }
++ else if (buf_string_match_head_str(buf, "INFO_PRE"))
++ {
++ server_pushed_info(c, buf, 8);
++ }
++ else if (buf_string_match_head_str(buf, "INFO"))
++ {
++ server_pushed_info(c, buf, 4);
++ }
++ else if (buf_string_match_head_str(buf, "CR_RESPONSE"))
++ {
++ receive_cr_response(c, buf);
++ }
++ else if (buf_string_match_head_str(buf, "AUTH_PENDING"))
++ {
++ receive_auth_pending(c, buf);
++ }
++ else if (buf_string_match_head_str(buf, "EXIT"))
++ {
++ receive_exit_message(c);
++ }
++ else
++ {
++ msg(D_PUSH_ERRORS, "WARNING: Received unknown control message: %s", BSTR(buf));
++ }
++}
++
+ /*
+ * Handle incoming configuration
+ * messages on the control channel.
+@@ -247,51 +292,41 @@ check_incoming_control_channel(struct co
+ struct buffer buf = alloc_buf_gc(len, &gc);
+ if (tls_rec_payload(c->c2.tls_multi, &buf))
+ {
+- /* force null termination of message */
+- buf_null_terminate(&buf);
+-
+- /* enforce character class restrictions */
+- string_mod(BSTR(&buf), CC_PRINT, CC_CRLF, 0);
+
+- if (buf_string_match_head_str(&buf, "AUTH_FAILED"))
+- {
+- receive_auth_failed(c, &buf);
+- }
+- else if (buf_string_match_head_str(&buf, "PUSH_"))
+- {
+- incoming_push_message(c, &buf);
+- }
+- else if (buf_string_match_head_str(&buf, "RESTART"))
+- {
+- server_pushed_signal(c, &buf, true, 7);
+- }
+- else if (buf_string_match_head_str(&buf, "HALT"))
+- {
+- server_pushed_signal(c, &buf, false, 4);
+- }
+- else if (buf_string_match_head_str(&buf, "INFO_PRE"))
+- {
+- server_pushed_info(c, &buf, 8);
+- }
+- else if (buf_string_match_head_str(&buf, "INFO"))
++ while (BLEN(&buf) > 1)
+ {
+- server_pushed_info(c, &buf, 4);
+- }
+- else if (buf_string_match_head_str(&buf, "CR_RESPONSE"))
+- {
+- receive_cr_response(c, &buf);
+- }
+- else if (buf_string_match_head_str(&buf, "AUTH_PENDING"))
+- {
+- receive_auth_pending(c, &buf);
+- }
+- else if (buf_string_match_head_str(&buf, "EXIT"))
+- {
+- receive_exit_message(c);
+- }
+- else
+- {
+- msg(D_PUSH_ERRORS, "WARNING: Received unknown control message: %s", BSTR(&buf));
++ /* commands on the control channel are seperated by 0x00 bytes.
++ * cmdlen does not include the 0 byte of the string */
++ int cmdlen = (int)strnlen(BSTR(&buf), BLEN(&buf));
++
++ if (cmdlen < BLEN(&buf))
++ {
++ /* include the NUL byte and ensure NUL termination */
++ int cmdlen = (int)strlen(BSTR(&buf)) + 1;
++
++ /* Construct a buffer that only holds the current command and
++ * its closing NUL byte */
++ struct buffer cmdbuf = alloc_buf_gc(cmdlen, &gc);
++ buf_write(&cmdbuf, BPTR(&buf), cmdlen);
++
++ /* check we have only printable characters or null byte in the
++ * command string and no newlines */
++ if (!string_check_buf(&buf, CC_PRINT | CC_NULL, CC_CRLF))
++ {
++ msg(D_PUSH_ERRORS, "WARNING: Received control with invalid characters: %s",
++ format_hex(BPTR(&buf), BLEN(&buf), 256, &gc));
++ }
++ else
++ {
++ parse_incoming_control_channel_command(c, &cmdbuf);
++ }
++ }
++ else
++ {
++ msg(D_PUSH_ERRORS, "WARNING: Ignoring control channel "
++ "message command without NUL termination");
++ }
++ buf_advance(&buf, cmdlen);
+ }
+ }
+ else
+--- a/tests/unit_tests/openvpn/test_buffer.c
++++ b/tests/unit_tests/openvpn/test_buffer.c
+@@ -261,6 +261,112 @@ test_buffer_gc_realloc(void **state)
+ gc_free(&gc);
+ }
+
++static void
++test_character_class(void **state)
++{
++ char buf[256];
++ strcpy(buf, "There is \x01 a nice 1234 year old tr\x7f ee!");
++ assert_false(string_mod(buf, CC_PRINT, 0, '@'));
++ assert_string_equal(buf, "There is @ a nice 1234 year old tr@ ee!");
++
++ strcpy(buf, "There is \x01 a nice 1234 year old tr\x7f ee!");
++ assert_true(string_mod(buf, CC_ANY, 0, '@'));
++ assert_string_equal(buf, "There is \x01 a nice 1234 year old tr\x7f ee!");
++
++ /* 0 as replace removes characters */
++ strcpy(buf, "There is \x01 a nice 1234 year old tr\x7f ee!");
++ assert_false(string_mod(buf, CC_PRINT, 0, '\0'));
++ assert_string_equal(buf, "There is a nice 1234 year old tr ee!");
++
++ strcpy(buf, "There is \x01 a nice 1234 year old tr\x7f ee!");
++ assert_false(string_mod(buf, CC_PRINT, CC_DIGIT, '@'));
++ assert_string_equal(buf, "There is @ a nice @@@@ year old tr@ ee!");
++
++ strcpy(buf, "There is \x01 a nice 1234 year old tr\x7f ee!");
++ assert_false(string_mod(buf, CC_ALPHA, CC_DIGIT, '.'));
++ assert_string_equal(buf, "There.is...a.nice......year.old.tr..ee.");
++
++ strcpy(buf, "There is \x01 a 'nice' \"1234\"\n year old \ntr\x7f ee!");
++ assert_false(string_mod(buf, CC_ALPHA|CC_DIGIT|CC_NEWLINE|CC_SINGLE_QUOTE, CC_DOUBLE_QUOTE|CC_BLANK, '.'));
++ assert_string_equal(buf, "There.is...a.'nice'..1234.\n.year.old.\ntr..ee.");
++
++ strcpy(buf, "There is a \\'nice\\' \"1234\" [*] year old \ntree!");
++ assert_false(string_mod(buf, CC_PRINT, CC_BACKSLASH|CC_ASTERISK, '.'));
++ assert_string_equal(buf, "There is a .'nice.' \"1234\" [.] year old .tree!");
++}
++
++
++static void
++test_character_string_mod_buf(void **state)
++{
++ struct gc_arena gc = gc_new();
++
++ struct buffer buf = alloc_buf_gc(1024, &gc);
++
++ const char test1[] = "There is a nice 1234\x00 year old tree!";
++ buf_write(&buf, test1, sizeof(test1));
++
++ /* allow the null bytes and string but not the ! */
++ assert_false(string_check_buf(&buf, CC_ALNUM | CC_SPACE | CC_NULL, 0));
++
++ /* remove final ! and null byte to pass */
++ buf_inc_len(&buf, -2);
++ assert_true(string_check_buf(&buf, CC_ALNUM | CC_SPACE | CC_NULL, 0));
++
++ /* Check excluding digits works */
++ assert_false(string_check_buf(&buf, CC_ALNUM | CC_SPACE | CC_NULL, CC_DIGIT));
++ gc_free(&gc);
++}
++
++static void
++test_snprintf(void **state)
++{
++ /* we used to have a custom openvpn_snprintf function because some
++ * OS (the comment did not specify which) did not always put the
++ * null byte there. So we unit test this to be sure.
++ *
++ * This probably refers to the MSVC behaviour, see also
++ * https://stackoverflow.com/questions/7706936/is-snprintf-always-null-terminating
++ */
++
++ /* Instead of trying to trick the compiler here, disable the warnings
++ * for this unit test. We know that the results will be truncated
++ * and we want to test that */
++#if defined(__GNUC__)
++/* some clang version do not understand -Wformat-truncation, so ignore the
++ * warning to avoid warnings/errors (-Werror) about unknown pragma/option */
++#if defined(__clang__)
++#pragma clang diagnostic push
++#pragma clang diagnostic ignored "-Wunknown-warning-option"
++#endif
++#pragma GCC diagnostic push
++#pragma GCC diagnostic ignored "-Wformat-truncation"
++#endif
++
++ char buf[10] = { 'a' };
++ int ret = 0;
++
++ ret = snprintf(buf, sizeof(buf), "0123456789abcde");
++ assert_int_equal(ret, 15);
++ assert_int_equal(buf[9], '\0');
++
++ memset(buf, 'b', sizeof(buf));
++ ret = snprintf(buf, sizeof(buf), "- %d - %d -", 77, 88);
++ assert_int_equal(ret, 11);
++ assert_int_equal(buf[9], '\0');
++
++ memset(buf, 'c', sizeof(buf));
++ ret = snprintf(buf, sizeof(buf), "- %8.2f", 77.8899);
++ assert_int_equal(ret, 10);
++ assert_int_equal(buf[9], '\0');
++
++#if defined(__GNUC__)
++#pragma GCC diagnostic pop
++#if defined(__clang__)
++#pragma clang diagnostic pop
++#endif
++#endif
++}
+
+ int
+ main(void)
+@@ -291,6 +397,9 @@ main(void)
+ cmocka_unit_test(test_buffer_free_gc_one),
+ cmocka_unit_test(test_buffer_free_gc_two),
+ cmocka_unit_test(test_buffer_gc_realloc),
++ cmocka_unit_test(test_character_class),
++ cmocka_unit_test(test_character_string_mod_buf),
++ cmocka_unit_test(test_snprintf)
+ };
+
+ return cmocka_run_group_tests_name("buffer", tests, NULL, NULL);
diff -Nru openvpn-2.6.3/debian/patches/CVE-2025-2704.patch openvpn-2.6.3/debian/patches/CVE-2025-2704.patch
--- openvpn-2.6.3/debian/patches/CVE-2025-2704.patch 1970-01-01 01:00:00.000000000 +0100
+++ openvpn-2.6.3/debian/patches/CVE-2025-2704.patch 2025-04-02 17:45:15.000000000 +0200
@@ -0,0 +1,282 @@
+From d3015bfd65348db629dab51e20a9d4e2f3b23493 Mon Sep 17 00:00:00 2001
+From: Arne Schwabe <arne@rfc2549.org>
+Date: Tue, 1 Apr 2025 19:30:37 +0200
+Subject: [PATCH] Allow tls-crypt-v2 to be setup only on initial packet of a
+ session
+
+This fixes an internal server error condition that can be triggered by a
+malicous authenticated client, a very unlucky corruption of packets in
+transit or by an attacker that is able to inject a specially created
+packet at the right time and is able to observe the traffic to construct
+the packet.
+
+The error condition results in an ASSERT statement being triggered,
+
+NOTE: due to the security sensitive nature, this patch was prepared
+under embargo on the security@openvpn.net mailing list, and thus has
+no publically available "mailing list discussion before merge" URL.
+
+CVE: 2025-2704
+Change-Id: I07c1352204d308e5bde5f0b85e561a5dd0bc63c8
+Signed-off-by: Arne Schwabe <arne@rfc2549.org>
+Acked-by: Gert Doering <gert@greenie.muc.de>
+Message-Id: <385d88f0-d7c9-4330-82ff-9f5931183afd@rfc2549.org>
+Signed-off-by: Gert Doering <gert@greenie.muc.de>
+(cherry picked from commit 82ee2fe4b42d9988c59ae3f83bd56a54d54e8c76)
+---
+ src/openvpn/ssl.c | 26 +++++++++++++++++++----
+ src/openvpn/ssl_common.h | 15 +++++++------
+ src/openvpn/ssl_pkt.c | 7 +++---
+ src/openvpn/ssl_pkt.h | 12 +++++++++--
+ src/openvpn/tls_crypt.c | 24 ++++++++++++++++++++-
+ src/openvpn/tls_crypt.h | 7 +++++-
+ tests/unit_tests/openvpn/test_tls_crypt.c | 2 +-
+ 7 files changed, 75 insertions(+), 18 deletions(-)
+
+diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c
+index 4fa7ea6fc45..5a0bf95aace 100644
+--- a/src/openvpn/ssl.c
++++ b/src/openvpn/ssl.c
+@@ -848,6 +848,9 @@ state_name(int state)
+ case S_INITIAL:
+ return "S_INITIAL";
+
++ case S_PRE_START_SKIP:
++ return "S_PRE_START_SKIP";
++
+ case S_PRE_START:
+ return "S_PRE_START";
+
+@@ -2598,7 +2601,7 @@ session_move_pre_start(const struct tls_session *session,
+ }
+ INCR_GENERATED;
+
+- ks->state = S_PRE_START;
++ ks->state = skip_initial_send ? S_PRE_START_SKIP : S_PRE_START;
+
+ struct gc_arena gc = gc_new();
+ dmsg(D_TLS_DEBUG, "TLS: Initial Handshake, sid=%s",
+@@ -3801,7 +3804,7 @@ tls_pre_decrypt(struct tls_multi *multi,
+ }
+
+ if (!read_control_auth(buf, tls_session_get_tls_wrap(session, key_id), from,
+- session->opt))
++ session->opt, true))
+ {
+ goto error;
+ }
+@@ -3871,7 +3874,7 @@ tls_pre_decrypt(struct tls_multi *multi,
+ if (op == P_CONTROL_SOFT_RESET_V1 && ks->state >= S_GENERATED_KEYS)
+ {
+ if (!read_control_auth(buf, tls_session_get_tls_wrap(session, key_id),
+- from, session->opt))
++ from, session->opt, false))
+ {
+ goto error;
+ }
+@@ -3884,6 +3887,15 @@ tls_pre_decrypt(struct tls_multi *multi,
+ }
+ else
+ {
++ bool initial_packet = false;
++ if (ks->state == S_PRE_START_SKIP)
++ {
++ /* When we are coming from the session_skip_to_pre_start
++ * method, we allow this initial packet to setup the
++ * tls-crypt-v2 peer specific key */
++ initial_packet = true;
++ ks->state = S_PRE_START;
++ }
+ /*
+ * Remote responding to our key renegotiation request?
+ */
+@@ -3893,8 +3905,14 @@ tls_pre_decrypt(struct tls_multi *multi,
+ }
+
+ if (!read_control_auth(buf, tls_session_get_tls_wrap(session, key_id),
+- from, session->opt))
++ from, session->opt, initial_packet))
+ {
++ /* if an initial packet in read_control_auth, we rather
++ * error out than anything else */
++ if (initial_packet)
++ {
++ multi->n_hard_errors++;
++ }
+ goto error;
+ }
+
+diff --git a/src/openvpn/ssl_common.h b/src/openvpn/ssl_common.h
+index 085256347ec..8b6ae3f2430 100644
+--- a/src/openvpn/ssl_common.h
++++ b/src/openvpn/ssl_common.h
+@@ -80,22 +80,25 @@
+ #define S_INITIAL 1 /**< Initial \c key_state state after
+ * initialization by \c key_state_init()
+ * before start of three-way handshake. */
+-#define S_PRE_START 2 /**< Waiting for the remote OpenVPN peer
++#define S_PRE_START_SKIP 2 /**< Waiting for the remote OpenVPN peer
+ * to acknowledge during the initial
+ * three-way handshake. */
+-#define S_START 3 /**< Three-way handshake is complete,
++#define S_PRE_START 3 /**< Waiting for the remote OpenVPN peer
++ * to acknowledge during the initial
++ * three-way handshake. */
++#define S_START 4 /**< Three-way handshake is complete,
+ * start of key exchange. */
+-#define S_SENT_KEY 4 /**< Local OpenVPN process has sent its
++#define S_SENT_KEY 5 /**< Local OpenVPN process has sent its
+ * part of the key material. */
+-#define S_GOT_KEY 5 /**< Local OpenVPN process has received
++#define S_GOT_KEY 6 /**< Local OpenVPN process has received
+ * the remote's part of the key
+ * material. */
+-#define S_ACTIVE 6 /**< Operational \c key_state state
++#define S_ACTIVE 7 /**< Operational \c key_state state
+ * immediately after negotiation has
+ * completed while still within the
+ * handshake window. Deferred auth and
+ * client connect can still be pending. */
+-#define S_GENERATED_KEYS 7 /**< The data channel keys have been generated
++#define S_GENERATED_KEYS 8 /**< The data channel keys have been generated
+ * The TLS session is fully authenticated
+ * when reaching this state. */
+
+diff --git a/src/openvpn/ssl_pkt.c b/src/openvpn/ssl_pkt.c
+index 689cd7f99f9..41299f462db 100644
+--- a/src/openvpn/ssl_pkt.c
++++ b/src/openvpn/ssl_pkt.c
+@@ -200,7 +200,8 @@ bool
+ read_control_auth(struct buffer *buf,
+ struct tls_wrap_ctx *ctx,
+ const struct link_socket_actual *from,
+- const struct tls_options *opt)
++ const struct tls_options *opt,
++ bool initial_packet)
+ {
+ struct gc_arena gc = gc_new();
+ bool ret = false;
+@@ -208,7 +209,7 @@ read_control_auth(struct buffer *buf,
+ const uint8_t opcode = *(BPTR(buf)) >> P_OPCODE_SHIFT;
+ if ((opcode == P_CONTROL_HARD_RESET_CLIENT_V3
+ || opcode == P_CONTROL_WKC_V1)
+- && !tls_crypt_v2_extract_client_key(buf, ctx, opt))
++ && !tls_crypt_v2_extract_client_key(buf, ctx, opt, initial_packet))
+ {
+ msg(D_TLS_ERRORS,
+ "TLS Error: can not extract tls-crypt-v2 client key from %s",
+@@ -373,7 +374,7 @@ tls_pre_decrypt_lite(const struct tls_auth_standalone *tas,
+ * into newbuf or just setting newbuf to point to the start of control
+ * message */
+ bool status = read_control_auth(&state->newbuf, &state->tls_wrap_tmp,
+- from, NULL);
++ from, NULL, true);
+
+ if (!status)
+ {
+diff --git a/src/openvpn/ssl_pkt.h b/src/openvpn/ssl_pkt.h
+index c8a27fba9d7..2033da61ff7 100644
+--- a/src/openvpn/ssl_pkt.h
++++ b/src/openvpn/ssl_pkt.h
+@@ -207,14 +207,22 @@ write_control_auth(struct tls_session *session,
+ bool prepend_ack);
+
+
+-/*
++
++/**
+ * Read a control channel authentication record.
++ * @param buf buffer that holds the incoming packet
++ * @param ctx control channel security context
++ * @param from incoming link socket address
++ * @param opt tls options struct for the session
++ * @param initial_packet whether this is the initial packet for the connection
++ * @return if the packet was successfully processed
+ */
+ bool
+ read_control_auth(struct buffer *buf,
+ struct tls_wrap_ctx *ctx,
+ const struct link_socket_actual *from,
+- const struct tls_options *opt);
++ const struct tls_options *opt,
++ bool initial_packet);
+
+
+ /**
+diff --git a/src/openvpn/tls_crypt.c b/src/openvpn/tls_crypt.c
+index 975d31fafb5..50228e786e0 100644
+--- a/src/openvpn/tls_crypt.c
++++ b/src/openvpn/tls_crypt.c
+@@ -612,7 +612,8 @@ tls_crypt_v2_verify_metadata(const struct tls_wrap_ctx *ctx,
+ bool
+ tls_crypt_v2_extract_client_key(struct buffer *buf,
+ struct tls_wrap_ctx *ctx,
+- const struct tls_options *opt)
++ const struct tls_options *opt,
++ bool initial_packet)
+ {
+ if (!ctx->tls_crypt_v2_server_key.cipher)
+ {
+@@ -641,6 +642,27 @@ tls_crypt_v2_extract_client_key(struct buffer *buf,
+ return false;
+ }
+
++ if (!initial_packet)
++ {
++ /* This might be a harmless resend of the packet but it is better to
++ * just ignore the WKC part than trying to setup tls-crypt keys again.
++ *
++ * A CONTROL_WKC_V1 packets has a normal packet part and an appended
++ * wrapped control key. These are authenticated individually. We already
++ * set up tls-crypt with the wrapped key, so we are ignoring this part
++ * of the message but we return the normal packet part as the normal
++ * part of the message might have been corrupted earlier and discarded
++ * and this is resend. So return the normal part of the packet,
++ * basically transforming the CONTROL_WKC_V1 into a normal CONTROL_V1
++ * packet*/
++ msg(D_TLS_ERRORS, "control channel security already setup ignoring "
++ "wrapped key part of packet.");
++
++ /* Remove client key from buffer so tls-crypt code can unwrap message */
++ ASSERT(buf_inc_len(buf, -(BLEN(&wrapped_client_key))));
++ return true;
++ }
++
+ ctx->tls_crypt_v2_metadata = alloc_buf(TLS_CRYPT_V2_MAX_METADATA_LEN);
+ if (!tls_crypt_v2_unwrap_client_key(&ctx->original_wrap_keydata,
+ &ctx->tls_crypt_v2_metadata,
+diff --git a/src/openvpn/tls_crypt.h b/src/openvpn/tls_crypt.h
+index 8c87e2080a1..331c0c060a7 100644
+--- a/src/openvpn/tls_crypt.h
++++ b/src/openvpn/tls_crypt.h
+@@ -207,11 +207,16 @@ void tls_crypt_v2_init_client_key(struct key_ctx_bi *key,
+ * message.
+ * @param ctx tls-wrap context to be initialized with the client key.
+ *
++ * @param initial_packet whether this is the initial packet of the
++ * connection. Only in these scenarios unwrapping
++ * of a tls-crypt-v2 key is allowed
++ *
+ * @returns true if a key was successfully extracted.
+ */
+ bool tls_crypt_v2_extract_client_key(struct buffer *buf,
+ struct tls_wrap_ctx *ctx,
+- const struct tls_options *opt);
++ const struct tls_options *opt,
++ bool initial_packet);
+
+ /**
+ * Generate a tls-crypt-v2 server key, and write to file.
+diff --git a/tests/unit_tests/openvpn/test_tls_crypt.c b/tests/unit_tests/openvpn/test_tls_crypt.c
+index 465543a740e..3eac04cf9ce 100644
+--- a/tests/unit_tests/openvpn/test_tls_crypt.c
++++ b/tests/unit_tests/openvpn/test_tls_crypt.c
+@@ -533,7 +533,7 @@ tls_crypt_v2_wrap_unwrap_max_metadata(void **state)
+ .mode = TLS_WRAP_CRYPT,
+ .tls_crypt_v2_server_key = ctx->server_keys.encrypt,
+ };
+- assert_true(tls_crypt_v2_extract_client_key(&ctx->wkc, &wrap_ctx, NULL));
++ assert_true(tls_crypt_v2_extract_client_key(&ctx->wkc, &wrap_ctx, NULL, true));
+ tls_wrap_free(&wrap_ctx);
+ }
+
diff -Nru openvpn-2.6.3/debian/patches/sample-keys-renew-10-years.patch openvpn-2.6.3/debian/patches/sample-keys-renew-10-years.patch
--- openvpn-2.6.3/debian/patches/sample-keys-renew-10-years.patch 1970-01-01 01:00:00.000000000 +0100
+++ openvpn-2.6.3/debian/patches/sample-keys-renew-10-years.patch 2025-04-02 17:45:15.000000000 +0200
@@ -0,0 +1,1618 @@
+Origin: https://github.com/OpenVPN/openvpn/commit/78e0c5f2f57a18e8ea60951696a458a4b3ff3621
+Reviewed-by: Aquila Macedo Costa <aquilamacedo@riseup.net>
+Last-Update: 2025-03-04
+
+From 78e0c5f2f57a18e8ea60951696a458a4b3ff3621 Mon Sep 17 00:00:00 2001
+From: Frank Lichtenheld <frank@lichtenheld.com>
+Date: Tue, 21 Nov 2023 12:04:30 +0100
+Subject: [PATCH] sample-keys: renew for the next 10 years
+
+Old expiration was October 2024, less than a year away.
+Give everyone the chance to get the new keys before tests
+start failing.
+
+Change-Id: Ie264ec1ec61fd71e8cc87987be3e2adc2735c201
+Signed-off-by: Frank Lichtenheld <frank@lichtenheld.com>
+Message-Id: <20231121110430.16893-1-frank@lichtenheld.com>
+URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg27530.html
+Signed-off-by: Gert Doering <gert@greenie.muc.de>
+---
+ sample/sample-config-files/loopback-client | 313 +++++++++++++++--------------
+ sample/sample-keys/ca.crt | 67 +++---
+ sample/sample-keys/ca.key | 100 ++++-----
+ sample/sample-keys/client-ec.crt | 129 ++++++------
+ sample/sample-keys/client-ec.key | 6 +-
+ sample/sample-keys/client-pass.key | 60 +++---
+ sample/sample-keys/client.crt | 162 +++++++--------
+ sample/sample-keys/client.key | 52 ++---
+ sample/sample-keys/client.p12 | Bin 4533 -> 4707 bytes
+ sample/sample-keys/dh2048.pem | 12 +-
+ sample/sample-keys/gen-sample-keys.sh | 3 +-
+ sample/sample-keys/server-ec.crt | 132 ++++++------
+ sample/sample-keys/server-ec.key | 6 +-
+ sample/sample-keys/server.crt | 166 +++++++--------
+ sample/sample-keys/server.key | 52 ++---
+ sample/sample-keys/ta.key | 32 +--
+ 16 files changed, 648 insertions(+), 644 deletions(-)
+
+diff --git a/sample/sample-config-files/loopback-client b/sample/sample-config-files/loopback-client
+index 8ac3d1d..7965eb6 100644
+--- a/sample/sample-config-files/loopback-client
++++ b/sample/sample-config-files/loopback-client
+@@ -24,70 +24,71 @@ remote-cert-tls server
+ #ca sample-keys/ca.crt
+ <ca>
+ -----BEGIN CERTIFICATE-----
+-MIIGKDCCBBCgAwIBAgIJAKFO3vqQ8q6BMA0GCSqGSIb3DQEBCwUAMGYxCzAJBgNV
+-BAYTAktHMQswCQYDVQQIEwJOQTEQMA4GA1UEBxMHQklTSEtFSzEVMBMGA1UEChMM
+-T3BlblZQTi1URVNUMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW4w
+-HhcNMTQxMDIyMjE1OTUyWhcNMjQxMDE5MjE1OTUyWjBmMQswCQYDVQQGEwJLRzEL
+-MAkGA1UECBMCTkExEDAOBgNVBAcTB0JJU0hLRUsxFTATBgNVBAoTDE9wZW5WUE4t
+-VEVTVDEhMB8GCSqGSIb3DQEJARYSbWVAbXlob3N0Lm15ZG9tYWluMIICIjANBgkq
+-hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsJVPCqt3vtoDW2U0DII1QIh2Qs0dqh88
+-8nivxAIm2LTq93e9fJhsq3P/UVYAYSeCIrekXypR0EQgSgcNTvGBMe20BoHO5yvb
+-GjKPmjfLj6XRotCOGy8EDl/hLgRY9efiA8wsVfuvF2q/FblyJQPR/gPiDtTmUiqF
+-qXa7AJmMrqFsnWppOuGd7Qc6aTsae4TF1e/gUTCTraa7NeHowDaKhdyFmEEnCYR5
+-CeUsx2JlFWAH8PCrxBpHYbmGyvS0kH3+rQkaSM/Pzc2bS4ayHaOYRK5XsGq8XiNG
+-KTTLnSaCdPeHsI+3xMHmEh+u5Og2DFGgvyD22gde6W2ezvEKCUDrzR7bsnYqqyUy
+-n7LxnkPXGyvR52T06G8KzLKQRmDlPIXhzKMO07qkHmIonXTdF7YI1azwHpAtN4dS
+-rUe1bvjiTSoEsQPfOAyvD0RMK/CBfgEZUzAB50e/IlbZ84c0DJfUMOm4xCyft1HF
+-YpYeyCf5dxoIjweCPOoP426+aTXM7kqq0ieIr6YxnKV6OGGLKEY+VNZh1DS7enqV
+-HP5i8eimyuUYPoQhbK9xtDGMgghnc6Hn8BldPMcvz98HdTEH4rBfA3yNuCxLSNow
+-4jJuLjNXh2QeiUtWtkXja7ec+P7VqKTduJoRaX7cs+8E3ImigiRnvmK+npk7Nt1y
+-YE9hBRhSoLsCAwEAAaOB2DCB1TAdBgNVHQ4EFgQUK0DlyX319JY46S/jL9lAZMmO
+-BZswgZgGA1UdIwSBkDCBjYAUK0DlyX319JY46S/jL9lAZMmOBZuhaqRoMGYxCzAJ
+-BgNVBAYTAktHMQswCQYDVQQIEwJOQTEQMA4GA1UEBxMHQklTSEtFSzEVMBMGA1UE
+-ChMMT3BlblZQTi1URVNUMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21h
+-aW6CCQChTt76kPKugTAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG
+-9w0BAQsFAAOCAgEABc77f4C4P8fIS+V8qCJmVNSDU44UZBc+D+J6ZTgW8JeOHUIj
+-Bh++XDg3gwat7pIWQ8AU5R7h+fpBI9n3dadyIsMHGwSogHY9Gw7di2RVtSFajEth
+-rvrq0JbzpwoYedMh84sJ2qI/DGKW9/Is9+O52fR+3z3dY3gNRDPQ5675BQ5CQW9I
+-AJgLOqzD8Q0qrXYi7HaEqzNx6p7RDTuhFgvTd+vS5d5+28Z5fm2umnq+GKHF8W5P
+-ylp2Js119FTVO7brusAMKPe5emc7tC2ov8OFFemQvfHR41PLryap2VD81IOgmt/J
+-kX/j/y5KGux5HZ3lxXqdJbKcAq4NKYQT0mCkRD4l6szaCEJ+k0SiM9DdTcBDefhR
+-9q+pCOyMh7d8QjQ1075mF7T+PGkZQUW1DUjEfrZhICnKgq+iEoUmM0Ee5WtRqcnu
+-5BTGQ2mSfc6rV+Vr+eYXqcg7Nxb3vFXYSTod1UhefonVqwdmyJ2sC79zp36Tbo2+
+-65NW2WJK7KzPUyOJU0U9bcu0utvDOvGWmG+aHbymJgcoFzvZmlXqMXn97pSFn4jV
+-y3SLRgJXOw1QLXL2Y5abcuoBVr4gCOxxk2vBeVxOMRXNqSWZOFIF1bu/PxuDA+Sa
+-hEi44aHbPXt9opdssz/hdGfd8Wo7vEJrbg7c6zR6C/Akav1Rzy9oohIdgOw=
++MIIGPjCCBCagAwIBAgIUb1C400ZucjRZvAAz3XyuEusnRgYwDQYJKoZIhvcNAQEL
++BQAwZjELMAkGA1UEBhMCS0cxCzAJBgNVBAgMAk5BMRAwDgYDVQQHDAdCSVNIS0VL
++MRUwEwYDVQQKDAxPcGVuVlBOLVRFU1QxITAfBgkqhkiG9w0BCQEWEm1lQG15aG9z
++dC5teWRvbWFpbjAeFw0yMzExMDcxMjIzMzlaFw0zMzExMDQxMjIzMzlaMGYxCzAJ
++BgNVBAYTAktHMQswCQYDVQQIDAJOQTEQMA4GA1UEBwwHQklTSEtFSzEVMBMGA1UE
++CgwMT3BlblZQTi1URVNUMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21h
++aW4wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCI+p/ZLGUHCANTTFaK
++nw+J3wi+ef2EKJ5WHt5PWMuBeaDpeU4Ghuaow8HlRPjG9lDRHtn+WQgZz9nUejYH
+++wtmN2BHwJAM4OeUVoB95tBrxd/VDCrdIvypVKldHsU3VkEbvPAl1jq68WVk+DXM
++FZqTUoafDK+irOvL7Z5j2gA3FDzRUQs0L+jCvRTl4omFSjSQwoBCoVXxNEAg9jgy
++lNWUHx+JHDB8dk+gEmDai20ggBWeAeThUU9dVZvwjv4E7zMRMx1skCRdWcyALJQf
++fjc9q6gnB9X9nPxXdWb/lYKcivJBmBRHLeirnUFL2S2IYRc2H0ZbX1d+WzDJV37+
++DKYy9ehltyHFiaXmZThJ2Kg/mAD55U3NCWNBXmQ0CvzhUh6QIQiOJNQHmK0qxgnc
++POJeE4X55dv1nAGD/0fGeHTcuShzUoipCKAd1CZdXK2Ge3gZRH2WUvlQGd5JARd4
++3zbd2wXZX0h0e1/BWQVeXx/Cg6u31B5lll7B3rWeoZHvfV9DSC7e3IEOhgzG5cyA
++h+wrtlCszjiMreHSSYCQh9tlyK+ACOJUFtZFGdseBsMxRgXWtHr+ypW2iJI4KsEU
++/MNXr1Bqg7FGxIw0Oyc2zyzjgD9aq4CKEy64MYB1ZYf41Rbc2Z+pMx1MW9orsPp7
++qSp6SmpTk0RTHpH0O2wNC9F26wIDAQABo4HjMIHgMB0GA1UdDgQWBBRzsbjWipVr
++EuB0fMVXVZiUW6x4XjCBowYDVR0jBIGbMIGYgBRzsbjWipVrEuB0fMVXVZiUW6x4
++XqFqpGgwZjELMAkGA1UEBhMCS0cxCzAJBgNVBAgMAk5BMRAwDgYDVQQHDAdCSVNI
++S0VLMRUwEwYDVQQKDAxPcGVuVlBOLVRFU1QxITAfBgkqhkiG9w0BCQEWEm1lQG15
++aG9zdC5teWRvbWFpboIUb1C400ZucjRZvAAz3XyuEusnRgYwDAYDVR0TBAUwAwEB
++/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBABqhFuSPgqplHQtFnWwQ
++TKfrElQJ07gF0eaBBijQVSm2MswB2xnWF/S2NRjIpw7k5ZlmZsAbCVcGMwqJOkfJ
++yX3Z7gK+yNrZehzNSOCkv+H79ExsS9/HETSqZxMevIIH7O0t/pACv20f85unBzhc
++x+980RzufuHK17sG3Z+z+d6i9XDhaZvV/gm6bWTXft1ufRzI5R48xWVAfJd1X9Ln
++bZmqF9Ye1GHxka1Xna9nOCgAuYYoGxq2VkUSIjlRCMaLCHlsWEn0JbRnQXPfBts6
++/yQBywcEekKRutCugn5bn625kAJHWGxcb0xIXj+Rqnp2++p33lbE4J09zfIkh5hV
++RvCSzaE0Z3Kly9237CV+DyAqzrBJq5HHN/AT6+xFd2yGPMPKH8hKbf3jIprexNEp
++oG1XC/dsPFkPLUyeD++kVjzsLiDmYAn2x3Dco6cWD7FfEljb1pHkAp5CctU9TjZH
++21xcAsPbfS0vrDmj8zG7eTU+BtleL4AfxEVsMBzrUB6jSdUMpJ/hRtni4RxOHLmU
++0DqtHIqrDrC5Gb2KunNUIYqPp+80LSD1/Edo5Vr+k5AiFYCzZFXSab+6e4hEsLEV
++nQNMmcPVWATQ2najGfNftmhwQx9hU4gJaCw/rfhEmwIif5BxgG5VPUzy97T+GmOZ
++InB0RDylv3Lq3Hs8mBF4nRt7
+ -----END CERTIFICATE-----
+ </ca>
+ #key sample-keys/client.key
+ <key>
+ -----BEGIN PRIVATE KEY-----
+-MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDsZY/pEsIaW+ZW
+-KgipgjotRHijADuwn+cnEECT7/HMPqCqBKKAGxOp5v6B1nCQqNjU3jDYNQDSvmLw
+-SNr8FY3Exm0LmfErgwAK0yojC+XN+TXfQ2EVcq2VmPZzIUFeoN1HJ6DVmtRBqBwd
+-VyBxF4/3KJ4+B87s1Q5CTx50R45HndIUKCcsFBD10Za1k3SE7/kE3o1Kb993q+rR
+-WNNE/loEAf8Gepf3/eNXSOHw30ATn2YjWuNVVD1UOe4A+RLx0t90LrrX8I3G3RhY
+-HJMiC3X6qNbgtS8tudT+uU+G4nVIFmD7P8m0MEIp+zuzK7lZgWpG80WDv/3VGv83
+-DG9b/WHxAgMBAAECggEBAIOdaCpUD02trOh8LqZxowJhBOl7z7/ex0uweMPk67LT
+-i5AdVHwOlzwZJ8oSIknoOBEMRBWcLQEojt1JMuL2/R95emzjIKshHHzqZKNulFvB
+-TIUpdnwChTKtH0mqUkLlPU3Ienty4IpNlpmfUKimfbkWHERdBJBHbtDsTABhdo3X
+-9pCF/yRKqJS2Fy/Mkl3gv1y/NB1OL4Jhl7vQbf+kmgfQN2qdOVe2BOKQ8NlPUDmE
+-/1XNIDaE3s6uvUaoFfwowzsCCwN2/8QrRMMKkjvV+lEVtNmQdYxj5Xj5IwS0vkK0
+-6icsngW87cpZxxc1zsRWcSTloy5ohub4FgKhlolmigECgYEA+cBlxzLvaMzMlBQY
+-kCac9KQMvVL+DIFHlZA5i5L/9pRVp4JJwj3GUoehFJoFhsxnKr8HZyLwBKlCmUVm
+-VxnshRWiAU18emUmeAtSGawlAS3QXhikVZDdd/L20YusLT+DXV81wlKR97/r9+17
+-klQOLkSdPm9wcMDOWMNHX8bUg8kCgYEA8k+hQv6+TR/+Beao2IIctFtw/EauaJiJ
+-wW5ql1cpCLPMAOQUvjs0Km3zqctfBF8mUjdkcyJ4uhL9FZtfywY22EtRIXOJ/8VR
+-we65mVo6RLR8YVM54sihanuFOnlyF9LIBWB+9pUfh1/Y7DSebh7W73uxhAxQhi3Y
+-QwfIQIFd8OkCgYBalH4VXhLYhpaYCiXSej6ot6rrK2N6c5Tb2MAWMA1nh+r84tMP
+-gMoh+pDgYPAqMI4mQbxUmqZEeoLuBe6VHpDav7rPECRaW781AJ4ZM4cEQ3Jz/inz
+-4qOAMn10CF081/Ez9ykPPlU0bsYNWHNd4eB2xWnmUBKOwk7UgJatVPaUiQKBgQCI
+-f18CVGpzG9CHFnaK8FCnMNOm6VIaTcNcGY0mD81nv5Dt943P054BQMsAHTY7SjZW
+-HioRyZtkhonXAB2oSqnekh7zzxgv4sG5k3ct8evdBCcE1FNJc2eqikZ0uDETRoOy
+-s7cRxNNr+QxDkyikM+80HOPU1PMPgwfOSrX90GJQ8QKBgEBKohGMV/sNa4t14Iau
+-qO8aagoqh/68K9GFXljsl3/iCSa964HIEREtW09Qz1w3dotEgp2w8bsDa+OwWrLy
+-0SY7T5jRViM3cDWRlUBLrGGiL0FiwsfqiRiji60y19erJgrgyGVIb1kIgIBRkgFM
+-2MMweASzTmZcri4PA/5C0HYb
++MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDdrrIKQObP4cGi
++odKDLDGY4huyhUBnAPqrv8+dFNHGt2ODql+cFKDSTQQ6SpLmkkukhkAmQr2Dt/xJ
++t1bSyudwhRaPizvaR56LakrI5qjermstUiIMnc9nu30eZgVTi3yurdGmUl89nmso
++GFfZoUItwLBN2krwKaoCNIYCqq9nCQbtRSGOjPh1Vsfq6E+IjhyLW2gtsWal5MY2
++4nCN/u8Q8FL4U5a/flFw8j+uWIc40aNr9jhRmxbOZzWObXZjTWubfXfaVW8gsWZP
++mi2kczpSIYY886ZaZ+V9EPU2ViF+AyK9mOkYtD+ztQ3t1e9Ulm+dRmxvDrpLGvfM
++1OUkutKlAgMBAAECggEANwi9ron6QzWaqtNdva7lCT1o/uLR4EB/+s99rVOT2K+C
++hxdu8QK2Aj+YgxgsbA15tfiWSGldPywX9/0KEv7IgkioFy7Lxx7sn1PeCQ4qck3+
++0ZuIVHWBHhGPuFI/lEQWyg7g81eTyWpg0+1nMeI02cLyggFlhUXyrOV5N4REU2GW
++C0KBQFyVQJPrFszomK8qsHOu/gaGC1vOwgIID3cQ3iLKXkoHNmHO4hgbeSy+SfDP
++Q5C0xxKQa2RUz0nLbByuGtLYOsJmbjUMWjFXyjmwBsPCcvRmFRdnxFvlnzwGEH4M
++ZKsw+49p1iJFyuCv7KJ/ILLJmoEuryjrSmdj3esIqQKBgQDwC24VBQLNmlug8rkG
++YWaRePsWRJylDlWIeHnfmGe27p7ytxOvGe6hnPu6nfg8nXHtruZCIhGya6qbuVmL
++vGrg94ia4MSpDVUgGiElXXQ/Pl7O9/lnSlIlxcBAgd8uggxIAzCeYI6c3r7AQcmY
++jARMwYNCxJjz5nLctMe2MCs4LwKBgQDsatDXb3xr6jmflCUZa8Kx8SOgBWEZTEGz
++KEoCQWnF2fHUCy4Bwm8Imnws3iX0198TyxkVD2rP8oGwFj2SAVtI2L8Y/g5A05TA
++knfmVECvGp/MN266ZdCA8G/MKbk727TxyJs+4AseAi5p6cBULqZHsJaZE74qlcEl
++5gFQu35ZawKBgBBgRz9J2zoZmLyvMm48ANpVzZNkVOdxxeYMigv2AsVZHCDk2oPs
++mfoOkqHVmxTPjPExKGZEmr54V+hNyc0dqpD0ci5WvTPnQ/JvtektqfuSjrdB9ZLV
++YCtRhV8hPQ+YMaxMA2oankAXdh35nv44NybhYMoSTXj+NMHX13QXbytjAoGAdVKw
++3yixWzB6dinjm1Dx5rJfVos024QPWqRUzfe+UPROYUdHBpKB3YgktXNs7KuwRbdV
++dDEZdabIGyV+WpWXwnflpbZ2Rk95k3NcUw5ep0cUJBkiNxhNt58aK/xMs1rd2dsO
++x84RVkwI0oCw9FXOKOeGZOL6TVHR70fMQU86bY8CgYEAqg/1AD9lXzbR57zaR/br
++AIn0WWU2mnU7Dc4uhmQd9+JExqrplKKHrUp8eQEOW8nij6MbPYlpgkMdatvDOJqP
++WrYtwZsKXGhnalvbS3ye20HqpjYpBR7co3Q9KMaaDNoQe9HtjbT80GXpQEbJN2Iu
++ADo3hPoX0yENIbKFccMuptM=
+ -----END PRIVATE KEY-----
+ </key>
+ #cert sample-keys/client.crt
+@@ -96,104 +97,104 @@ Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 2 (0x2)
+- Signature Algorithm: sha256WithRSAEncryption
++ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=KG, ST=NA, L=BISHKEK, O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
+ Validity
+- Not Before: Oct 22 21:59:53 2014 GMT
+- Not After : Oct 19 21:59:53 2024 GMT
++ Not Before: Nov 7 12:23:39 2023 GMT
++ Not After : Nov 4 12:23:39 2033 GMT
+ Subject: C=KG, ST=NA, O=OpenVPN-TEST, CN=Test-Client/emailAddress=me@myhost.mydomain
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+- 00:ec:65:8f:e9:12:c2:1a:5b:e6:56:2a:08:a9:82:
+- 3a:2d:44:78:a3:00:3b:b0:9f:e7:27:10:40:93:ef:
+- f1:cc:3e:a0:aa:04:a2:80:1b:13:a9:e6:fe:81:d6:
+- 70:90:a8:d8:d4:de:30:d8:35:00:d2:be:62:f0:48:
+- da:fc:15:8d:c4:c6:6d:0b:99:f1:2b:83:00:0a:d3:
+- 2a:23:0b:e5:cd:f9:35:df:43:61:15:72:ad:95:98:
+- f6:73:21:41:5e:a0:dd:47:27:a0:d5:9a:d4:41:a8:
+- 1c:1d:57:20:71:17:8f:f7:28:9e:3e:07:ce:ec:d5:
+- 0e:42:4f:1e:74:47:8e:47:9d:d2:14:28:27:2c:14:
+- 10:f5:d1:96:b5:93:74:84:ef:f9:04:de:8d:4a:6f:
+- df:77:ab:ea:d1:58:d3:44:fe:5a:04:01:ff:06:7a:
+- 97:f7:fd:e3:57:48:e1:f0:df:40:13:9f:66:23:5a:
+- e3:55:54:3d:54:39:ee:00:f9:12:f1:d2:df:74:2e:
+- ba:d7:f0:8d:c6:dd:18:58:1c:93:22:0b:75:fa:a8:
+- d6:e0:b5:2f:2d:b9:d4:fe:b9:4f:86:e2:75:48:16:
+- 60:fb:3f:c9:b4:30:42:29:fb:3b:b3:2b:b9:59:81:
+- 6a:46:f3:45:83:bf:fd:d5:1a:ff:37:0c:6f:5b:fd:
+- 61:f1
++ 00:dd:ae:b2:0a:40:e6:cf:e1:c1:a2:a1:d2:83:2c:
++ 31:98:e2:1b:b2:85:40:67:00:fa:ab:bf:cf:9d:14:
++ d1:c6:b7:63:83:aa:5f:9c:14:a0:d2:4d:04:3a:4a:
++ 92:e6:92:4b:a4:86:40:26:42:bd:83:b7:fc:49:b7:
++ 56:d2:ca:e7:70:85:16:8f:8b:3b:da:47:9e:8b:6a:
++ 4a:c8:e6:a8:de:ae:6b:2d:52:22:0c:9d:cf:67:bb:
++ 7d:1e:66:05:53:8b:7c:ae:ad:d1:a6:52:5f:3d:9e:
++ 6b:28:18:57:d9:a1:42:2d:c0:b0:4d:da:4a:f0:29:
++ aa:02:34:86:02:aa:af:67:09:06:ed:45:21:8e:8c:
++ f8:75:56:c7:ea:e8:4f:88:8e:1c:8b:5b:68:2d:b1:
++ 66:a5:e4:c6:36:e2:70:8d:fe:ef:10:f0:52:f8:53:
++ 96:bf:7e:51:70:f2:3f:ae:58:87:38:d1:a3:6b:f6:
++ 38:51:9b:16:ce:67:35:8e:6d:76:63:4d:6b:9b:7d:
++ 77:da:55:6f:20:b1:66:4f:9a:2d:a4:73:3a:52:21:
++ 86:3c:f3:a6:5a:67:e5:7d:10:f5:36:56:21:7e:03:
++ 22:bd:98:e9:18:b4:3f:b3:b5:0d:ed:d5:ef:54:96:
++ 6f:9d:46:6c:6f:0e:ba:4b:1a:f7:cc:d4:e5:24:ba:
++ d2:a5
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ X509v3 Subject Key Identifier:
+- D2:B4:36:0F:B1:FC:DD:A5:EA:2A:F7:C7:23:89:FA:E3:FA:7A:44:1D
++ 59:33:B9:2E:63:D1:17:A8:9F:BD:D8:CE:94:21:C5:41:C7:31:62:5D
+ X509v3 Authority Key Identifier:
+- keyid:2B:40:E5:C9:7D:F5:F4:96:38:E9:2F:E3:2F:D9:40:64:C9:8E:05:9B
++ keyid:73:B1:B8:D6:8A:95:6B:12:E0:74:7C:C5:57:55:98:94:5B:AC:78:5E
+ DirName:/C=KG/ST=NA/L=BISHKEK/O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
+- serial:A1:4E:DE:FA:90:F2:AE:81
+-
++ serial:6F:50:B8:D3:46:6E:72:34:59:BC:00:33:DD:7C:AE:12:EB:27:46:06
+ Signature Algorithm: sha256WithRSAEncryption
+- 7f:e0:fe:84:a7:ec:df:62:a5:cd:3c:c1:e6:42:b1:31:12:f0:
+- b9:da:a7:9e:3f:bd:96:52:b6:fc:55:74:64:3e:e4:ff:7e:aa:
+- f7:3e:06:18:5f:73:85:f8:c8:e0:67:1b:4d:97:ca:05:d0:37:
+- 07:33:64:9b:e6:78:77:14:9a:55:bb:2a:ac:c3:7f:c9:15:08:
+- 83:5c:c8:c2:61:d3:71:4c:05:0b:2b:cb:a3:87:6d:a0:32:ed:
+- b0:b3:27:97:4a:55:8d:01:2a:30:56:68:ab:f2:da:5c:10:73:
+- c9:aa:0a:9c:4b:4c:a0:5b:51:6e:0a:7e:6c:53:80:b0:00:e1:
+- 1e:9a:4c:0a:37:9e:20:89:bc:c5:e5:79:58:b7:45:ff:d3:c4:
+- a1:fd:d9:78:3d:45:16:74:df:82:44:1d:1d:81:50:5a:b9:32:
+- 4c:e2:4f:3f:0e:3a:65:5a:64:83:3b:29:31:c4:99:88:bc:c5:
+- 84:39:f2:19:12:e1:66:d0:ea:fb:75:b1:d2:27:be:91:59:a3:
+- 2b:09:d5:5c:bf:46:8e:d6:67:d6:0b:ec:da:ab:f0:80:19:87:
+- 64:07:a9:77:b1:5e:0c:e2:c5:1d:6a:ac:5d:23:f3:30:75:36:
+- 4e:ca:c3:4e:b0:4d:8c:2c:ce:52:61:63:de:d5:f5:ef:ef:0a:
+- 6b:23:25:26:3c:3a:f2:c3:c2:16:19:3f:a9:32:ba:68:f9:c9:
+- 12:3c:3e:c6:1f:ff:9b:4e:f4:90:b0:63:f5:d1:33:00:30:5a:
+- e8:24:fa:35:44:9b:6a:80:f3:a6:cc:7b:3c:73:5f:50:c4:30:
+- 71:d8:74:90:27:0a:01:4e:a5:5e:b1:f8:da:c2:61:81:11:ae:
+- 29:a3:8f:fa:7e:4c:4e:62:b1:00:de:92:e3:8f:6a:2e:da:d9:
+- 38:5d:6b:7c:0d:e4:01:aa:c8:c6:6d:8b:cd:c0:c8:6e:e4:57:
+- 21:8a:f6:46:30:d9:ad:51:a1:87:96:a6:53:c9:1e:c6:bb:c3:
+- eb:55:fe:8c:d6:5c:d5:c6:f3:ca:b0:60:d2:d4:2a:1f:88:94:
+- d3:4c:1a:da:0c:94:fe:c1:5d:0d:2a:db:99:29:5d:f6:dd:16:
+- c4:c8:4d:74:9e:80:d9:d0:aa:ed:7b:e3:30:e4:47:d8:f5:15:
+- c1:71:b8:c6:fd:ee:fc:9e:b2:5f:b5:b7:92:ed:ff:ca:37:f6:
+- c7:82:b4:54:13:9b:83:cd:87:8b:7e:64:f6:2e:54:3a:22:b1:
+- c5:c1:f4:a5:25:53:9a:4d:a8:0f:e7:35:4b:89:df:19:83:66:
+- 64:d9:db:d1:61:2b:24:1b:1d:44:44:fb:49:30:87:b7:49:23:
+- 08:02:8a:e0:25:f3:f4:43
++ Signature Value:
++ 2a:9e:02:65:f4:3c:c0:37:88:f0:21:f9:fd:2e:7c:f4:8b:bb:
++ 67:7d:f7:48:0c:98:f7:a1:46:4e:33:af:68:77:f4:53:03:09:
++ fd:4e:32:cb:0f:2c:f1:16:37:35:65:aa:68:79:16:a9:32:03:
++ d7:89:10:ef:ba:fd:e1:26:2c:60:7c:3b:42:60:68:47:cf:61:
++ 88:00:77:e7:71:76:49:78:35:52:45:a4:31:7e:2b:e1:0a:c8:
++ ed:e1:a7:28:2f:23:a3:ce:ce:b5:99:6b:54:4d:df:d2:64:0a:
++ b7:c5:25:1e:d4:f7:a1:fd:4f:f3:12:d3:26:5f:3b:b2:93:93:
++ d1:8b:4b:4e:dc:d0:15:63:d1:77:36:75:34:76:37:59:ff:a0:
++ 81:01:ec:b6:42:2f:bd:85:5d:d0:ef:ff:90:61:d6:91:b0:f5:
++ e6:94:66:7e:4c:20:06:c4:2e:0c:9b:9f:7f:89:f0:3e:8f:e5:
++ 06:6c:81:75:a2:0b:c5:ac:44:f1:32:cc:57:90:a0:19:47:8c:
++ 25:7a:d5:f1:61:1f:19:bf:4c:31:da:44:c1:30:91:e8:b5:cc:
++ e4:7e:20:55:0a:b9:dc:f3:5e:f5:7c:d1:0b:ee:71:c6:d6:38:
++ 7e:85:7b:6c:cb:10:85:1e:6a:50:ab:c3:ae:f9:ff:96:4f:a3:
++ 76:d6:fd:c0:f9:c7:9a:60:a8:8c:e5:9a:c5:a9:7b:63:11:ef:
++ 7b:b9:9b:1f:63:51:a8:6d:2b:d6:f7:ef:51:bd:a8:32:9e:92:
++ aa:24:01:c9:e3:6a:c8:94:2e:d2:66:b2:c7:17:e5:06:53:9a:
++ bd:8a:19:8f:3a:51:7a:25:11:e5:e8:59:f7:1b:df:95:98:35:
++ c1:a6:74:15:6b:b1:2c:97:9b:fe:76:7e:56:20:4d:ee:07:8a:
++ b9:8b:bc:92:a9:19:81:28:91:4e:d2:9f:51:99:72:c0:12:76:
++ 5b:c8:74:68:b5:9d:43:53:c1:af:39:b9:28:82:a0:0e:bb:ef:
++ 21:d8:71:dd:02:af:dc:df:48:7b:39:21:7d:83:76:ea:e2:c7:
++ 16:bb:d2:1a:1d:22:f6:4b:47:15:56:41:06:4d:39:1c:96:3f:
++ 25:2d:83:8f:a4:a2:86:fa:0e:e9:45:9c:bf:26:40:e6:3e:9e:
++ d5:00:9f:ce:76:6f:df:cb:b2:85:b8:83:f2:ed:8b:b6:5a:68:
++ b5:c7:1b:ab:19:75:60:f3:5b:e7:5c:70:27:d9:1c:d8:24:f0:
++ 2a:aa:2a:a6:98:77:d6:36:d9:02:35:a8:d3:2c:19:88:b8:0b:
++ d3:76:58:72:54:99:94:9a:ee:38:9b:8d:8e:10:48:cd:28:50:
++ 31:b2:4b:d3:69:7b:91:b4
+ -----BEGIN CERTIFICATE-----
+-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
+-CAKK4CXz9EM=
++DQEBAQUAA4IBDwAwggEKAoIBAQDdrrIKQObP4cGiodKDLDGY4huyhUBnAPqrv8+d
++FNHGt2ODql+cFKDSTQQ6SpLmkkukhkAmQr2Dt/xJt1bSyudwhRaPizvaR56LakrI
++5qjermstUiIMnc9nu30eZgVTi3yurdGmUl89nmsoGFfZoUItwLBN2krwKaoCNIYC
++qq9nCQbtRSGOjPh1Vsfq6E+IjhyLW2gtsWal5MY24nCN/u8Q8FL4U5a/flFw8j+u
++WIc40aNr9jhRmxbOZzWObXZjTWubfXfaVW8gsWZPmi2kczpSIYY886ZaZ+V9EPU2
++ViF+AyK9mOkYtD+ztQ3t1e9Ulm+dRmxvDrpLGvfM1OUkutKlAgMBAAGjgdMwgdAw
++CQYDVR0TBAIwADAdBgNVHQ4EFgQUWTO5LmPRF6ifvdjOlCHFQccxYl0wgaMGA1Ud
++IwSBmzCBmIAUc7G41oqVaxLgdHzFV1WYlFuseF6haqRoMGYxCzAJBgNVBAYTAktH
++MQswCQYDVQQIDAJOQTEQMA4GA1UEBwwHQklTSEtFSzEVMBMGA1UECgwMT3BlblZQ
++Ti1URVNUMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW6CFG9QuNNG
++bnI0WbwAM918rhLrJ0YGMA0GCSqGSIb3DQEBCwUAA4ICAQAqngJl9DzAN4jwIfn9
++Lnz0i7tnffdIDJj3oUZOM69od/RTAwn9TjLLDyzxFjc1ZapoeRapMgPXiRDvuv3h
++JixgfDtCYGhHz2GIAHfncXZJeDVSRaQxfivhCsjt4acoLyOjzs61mWtUTd/SZAq3
++xSUe1Peh/U/zEtMmXzuyk5PRi0tO3NAVY9F3NnU0djdZ/6CBAey2Qi+9hV3Q7/+Q
++YdaRsPXmlGZ+TCAGxC4Mm59/ifA+j+UGbIF1ogvFrETxMsxXkKAZR4wletXxYR8Z
++v0wx2kTBMJHotczkfiBVCrnc8171fNEL7nHG1jh+hXtsyxCFHmpQq8Ou+f+WT6N2
++1v3A+ceaYKiM5ZrFqXtjEe97uZsfY1GobSvW9+9RvagynpKqJAHJ42rIlC7SZrLH
++F+UGU5q9ihmPOlF6JRHl6Fn3G9+VmDXBpnQVa7Esl5v+dn5WIE3uB4q5i7ySqRmB
++KJFO0p9RmXLAEnZbyHRotZ1DU8GvObkogqAOu+8h2HHdAq/c30h7OSF9g3bq4scW
++u9IaHSL2S0cVVkEGTTkclj8lLYOPpKKG+g7pRZy/JkDmPp7VAJ/Odm/fy7KFuIPy
++7Yu2Wmi1xxurGXVg81vnXHAn2RzYJPAqqiqmmHfWNtkCNajTLBmIuAvTdlhyVJmU
++mu44m42OEEjNKFAxskvTaXuRtA==
+ -----END CERTIFICATE-----
+ </cert>
+ #tls-auth sample-keys/ta.key 1
+@@ -203,22 +204,22 @@ key-direction 1
+ # 2048 bit OpenVPN static key
+ #
+ -----BEGIN OpenVPN Static key V1-----
+-a863b1cbdb911ff4ef3360ce135157e7
+-241a465f5045f51cf9a92ebc24da34fd
+-5fc48456778c977e374d55a8a7298aef
+-40d0ab0c60b5e09838510526b73473a0
+-8da46a8c352572dd86d4a871700a915b
+-6aaa58a9dac560db2dfdd7ef15a202e1
+-fca6913d7ee79c678c5798fbf7bd920c
+-caa7a64720908da7254598b052d07f55
+-5e31dc5721932cffbdd8965d04107415
+-46c86823da18b66aab347e4522cc05ff
+-634968889209c96b1024909cd4ce574c
+-f829aa9c17d5df4a66043182ee23635d
+-8cabf5a7ba02345ad94a3aa25a63d55c
+-e13f4ad235a0825e3fe17f9419baff1c
+-e73ad1dd652f1e48c7102fe8ee181e54
+-10a160ae255f63fd01db1f29e6efcb8e
++21d94830510107f8753d3b6f3145e01d
++ed37075115afcb0538ecdd8503ee9663
++7218c9ed38d908d594231d7d143c73da
++5055310f89d336da99c8b3dcb18909c7
++9dd44f540670ebc0f120beb7211e9683
++9cb542572c48bfa7ffaa9a22cb8304b7
++869b92f4442918e598745bb78ac8877f
++02b00a7cdef3f2446c130d39a7c45126
++9ef399fd6029cdfc80a7c604041312ab
++0a969bc906bdee6e6d707afdcbe8c7fb
++97beb66049c3d328340775025433ceba
++1e38008a826cf92443d903106199373b
++dadd9c2c735cf481e580db4e81b99f12
++e3f46b6159c687cd1b9e689f7712573c
++0f02735a45573dfb5cd55cf464942389
++2c7e91f439bdd7337a8ceebd302cfbfa
+ -----END OpenVPN Static key V1-----
+ </tls-auth>
+ cipher AES-256-GCM
+diff --git a/sample/sample-keys/ca.crt b/sample/sample-keys/ca.crt
+index a11bafa..a088711 100644
+--- a/sample/sample-keys/ca.crt
++++ b/sample/sample-keys/ca.crt
+@@ -1,35 +1,36 @@
+ -----BEGIN CERTIFICATE-----
+-MIIGKDCCBBCgAwIBAgIJAKFO3vqQ8q6BMA0GCSqGSIb3DQEBCwUAMGYxCzAJBgNV
+-BAYTAktHMQswCQYDVQQIEwJOQTEQMA4GA1UEBxMHQklTSEtFSzEVMBMGA1UEChMM
+-T3BlblZQTi1URVNUMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW4w
+-HhcNMTQxMDIyMjE1OTUyWhcNMjQxMDE5MjE1OTUyWjBmMQswCQYDVQQGEwJLRzEL
+-MAkGA1UECBMCTkExEDAOBgNVBAcTB0JJU0hLRUsxFTATBgNVBAoTDE9wZW5WUE4t
+-VEVTVDEhMB8GCSqGSIb3DQEJARYSbWVAbXlob3N0Lm15ZG9tYWluMIICIjANBgkq
+-hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsJVPCqt3vtoDW2U0DII1QIh2Qs0dqh88
+-8nivxAIm2LTq93e9fJhsq3P/UVYAYSeCIrekXypR0EQgSgcNTvGBMe20BoHO5yvb
+-GjKPmjfLj6XRotCOGy8EDl/hLgRY9efiA8wsVfuvF2q/FblyJQPR/gPiDtTmUiqF
+-qXa7AJmMrqFsnWppOuGd7Qc6aTsae4TF1e/gUTCTraa7NeHowDaKhdyFmEEnCYR5
+-CeUsx2JlFWAH8PCrxBpHYbmGyvS0kH3+rQkaSM/Pzc2bS4ayHaOYRK5XsGq8XiNG
+-KTTLnSaCdPeHsI+3xMHmEh+u5Og2DFGgvyD22gde6W2ezvEKCUDrzR7bsnYqqyUy
+-n7LxnkPXGyvR52T06G8KzLKQRmDlPIXhzKMO07qkHmIonXTdF7YI1azwHpAtN4dS
+-rUe1bvjiTSoEsQPfOAyvD0RMK/CBfgEZUzAB50e/IlbZ84c0DJfUMOm4xCyft1HF
+-YpYeyCf5dxoIjweCPOoP426+aTXM7kqq0ieIr6YxnKV6OGGLKEY+VNZh1DS7enqV
+-HP5i8eimyuUYPoQhbK9xtDGMgghnc6Hn8BldPMcvz98HdTEH4rBfA3yNuCxLSNow
+-4jJuLjNXh2QeiUtWtkXja7ec+P7VqKTduJoRaX7cs+8E3ImigiRnvmK+npk7Nt1y
+-YE9hBRhSoLsCAwEAAaOB2DCB1TAdBgNVHQ4EFgQUK0DlyX319JY46S/jL9lAZMmO
+-BZswgZgGA1UdIwSBkDCBjYAUK0DlyX319JY46S/jL9lAZMmOBZuhaqRoMGYxCzAJ
+-BgNVBAYTAktHMQswCQYDVQQIEwJOQTEQMA4GA1UEBxMHQklTSEtFSzEVMBMGA1UE
+-ChMMT3BlblZQTi1URVNUMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21h
+-aW6CCQChTt76kPKugTAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG
+-9w0BAQsFAAOCAgEABc77f4C4P8fIS+V8qCJmVNSDU44UZBc+D+J6ZTgW8JeOHUIj
+-Bh++XDg3gwat7pIWQ8AU5R7h+fpBI9n3dadyIsMHGwSogHY9Gw7di2RVtSFajEth
+-rvrq0JbzpwoYedMh84sJ2qI/DGKW9/Is9+O52fR+3z3dY3gNRDPQ5675BQ5CQW9I
+-AJgLOqzD8Q0qrXYi7HaEqzNx6p7RDTuhFgvTd+vS5d5+28Z5fm2umnq+GKHF8W5P
+-ylp2Js119FTVO7brusAMKPe5emc7tC2ov8OFFemQvfHR41PLryap2VD81IOgmt/J
+-kX/j/y5KGux5HZ3lxXqdJbKcAq4NKYQT0mCkRD4l6szaCEJ+k0SiM9DdTcBDefhR
+-9q+pCOyMh7d8QjQ1075mF7T+PGkZQUW1DUjEfrZhICnKgq+iEoUmM0Ee5WtRqcnu
+-5BTGQ2mSfc6rV+Vr+eYXqcg7Nxb3vFXYSTod1UhefonVqwdmyJ2sC79zp36Tbo2+
+-65NW2WJK7KzPUyOJU0U9bcu0utvDOvGWmG+aHbymJgcoFzvZmlXqMXn97pSFn4jV
+-y3SLRgJXOw1QLXL2Y5abcuoBVr4gCOxxk2vBeVxOMRXNqSWZOFIF1bu/PxuDA+Sa
+-hEi44aHbPXt9opdssz/hdGfd8Wo7vEJrbg7c6zR6C/Akav1Rzy9oohIdgOw=
++MIIGPjCCBCagAwIBAgIUb1C400ZucjRZvAAz3XyuEusnRgYwDQYJKoZIhvcNAQEL
++BQAwZjELMAkGA1UEBhMCS0cxCzAJBgNVBAgMAk5BMRAwDgYDVQQHDAdCSVNIS0VL
++MRUwEwYDVQQKDAxPcGVuVlBOLVRFU1QxITAfBgkqhkiG9w0BCQEWEm1lQG15aG9z
++dC5teWRvbWFpbjAeFw0yMzExMDcxMjIzMzlaFw0zMzExMDQxMjIzMzlaMGYxCzAJ
++BgNVBAYTAktHMQswCQYDVQQIDAJOQTEQMA4GA1UEBwwHQklTSEtFSzEVMBMGA1UE
++CgwMT3BlblZQTi1URVNUMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21h
++aW4wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCI+p/ZLGUHCANTTFaK
++nw+J3wi+ef2EKJ5WHt5PWMuBeaDpeU4Ghuaow8HlRPjG9lDRHtn+WQgZz9nUejYH
+++wtmN2BHwJAM4OeUVoB95tBrxd/VDCrdIvypVKldHsU3VkEbvPAl1jq68WVk+DXM
++FZqTUoafDK+irOvL7Z5j2gA3FDzRUQs0L+jCvRTl4omFSjSQwoBCoVXxNEAg9jgy
++lNWUHx+JHDB8dk+gEmDai20ggBWeAeThUU9dVZvwjv4E7zMRMx1skCRdWcyALJQf
++fjc9q6gnB9X9nPxXdWb/lYKcivJBmBRHLeirnUFL2S2IYRc2H0ZbX1d+WzDJV37+
++DKYy9ehltyHFiaXmZThJ2Kg/mAD55U3NCWNBXmQ0CvzhUh6QIQiOJNQHmK0qxgnc
++POJeE4X55dv1nAGD/0fGeHTcuShzUoipCKAd1CZdXK2Ge3gZRH2WUvlQGd5JARd4
++3zbd2wXZX0h0e1/BWQVeXx/Cg6u31B5lll7B3rWeoZHvfV9DSC7e3IEOhgzG5cyA
++h+wrtlCszjiMreHSSYCQh9tlyK+ACOJUFtZFGdseBsMxRgXWtHr+ypW2iJI4KsEU
++/MNXr1Bqg7FGxIw0Oyc2zyzjgD9aq4CKEy64MYB1ZYf41Rbc2Z+pMx1MW9orsPp7
++qSp6SmpTk0RTHpH0O2wNC9F26wIDAQABo4HjMIHgMB0GA1UdDgQWBBRzsbjWipVr
++EuB0fMVXVZiUW6x4XjCBowYDVR0jBIGbMIGYgBRzsbjWipVrEuB0fMVXVZiUW6x4
++XqFqpGgwZjELMAkGA1UEBhMCS0cxCzAJBgNVBAgMAk5BMRAwDgYDVQQHDAdCSVNI
++S0VLMRUwEwYDVQQKDAxPcGVuVlBOLVRFU1QxITAfBgkqhkiG9w0BCQEWEm1lQG15
++aG9zdC5teWRvbWFpboIUb1C400ZucjRZvAAz3XyuEusnRgYwDAYDVR0TBAUwAwEB
++/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBABqhFuSPgqplHQtFnWwQ
++TKfrElQJ07gF0eaBBijQVSm2MswB2xnWF/S2NRjIpw7k5ZlmZsAbCVcGMwqJOkfJ
++yX3Z7gK+yNrZehzNSOCkv+H79ExsS9/HETSqZxMevIIH7O0t/pACv20f85unBzhc
++x+980RzufuHK17sG3Z+z+d6i9XDhaZvV/gm6bWTXft1ufRzI5R48xWVAfJd1X9Ln
++bZmqF9Ye1GHxka1Xna9nOCgAuYYoGxq2VkUSIjlRCMaLCHlsWEn0JbRnQXPfBts6
++/yQBywcEekKRutCugn5bn625kAJHWGxcb0xIXj+Rqnp2++p33lbE4J09zfIkh5hV
++RvCSzaE0Z3Kly9237CV+DyAqzrBJq5HHN/AT6+xFd2yGPMPKH8hKbf3jIprexNEp
++oG1XC/dsPFkPLUyeD++kVjzsLiDmYAn2x3Dco6cWD7FfEljb1pHkAp5CctU9TjZH
++21xcAsPbfS0vrDmj8zG7eTU+BtleL4AfxEVsMBzrUB6jSdUMpJ/hRtni4RxOHLmU
++0DqtHIqrDrC5Gb2KunNUIYqPp+80LSD1/Edo5Vr+k5AiFYCzZFXSab+6e4hEsLEV
++nQNMmcPVWATQ2najGfNftmhwQx9hU4gJaCw/rfhEmwIif5BxgG5VPUzy97T+GmOZ
++InB0RDylv3Lq3Hs8mBF4nRt7
+ -----END CERTIFICATE-----
+diff --git a/sample/sample-keys/ca.key b/sample/sample-keys/ca.key
+index 8b11bc2..e923884 100644
+--- a/sample/sample-keys/ca.key
++++ b/sample/sample-keys/ca.key
+@@ -1,52 +1,52 @@
+ -----BEGIN PRIVATE KEY-----
+-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
+-B1RaqQXwzqrCH0F/vw3lRceYhcQvzcQ=
++MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQCI+p/ZLGUHCANT
++TFaKnw+J3wi+ef2EKJ5WHt5PWMuBeaDpeU4Ghuaow8HlRPjG9lDRHtn+WQgZz9nU
++ejYH+wtmN2BHwJAM4OeUVoB95tBrxd/VDCrdIvypVKldHsU3VkEbvPAl1jq68WVk
+++DXMFZqTUoafDK+irOvL7Z5j2gA3FDzRUQs0L+jCvRTl4omFSjSQwoBCoVXxNEAg
++9jgylNWUHx+JHDB8dk+gEmDai20ggBWeAeThUU9dVZvwjv4E7zMRMx1skCRdWcyA
++LJQffjc9q6gnB9X9nPxXdWb/lYKcivJBmBRHLeirnUFL2S2IYRc2H0ZbX1d+WzDJ
++V37+DKYy9ehltyHFiaXmZThJ2Kg/mAD55U3NCWNBXmQ0CvzhUh6QIQiOJNQHmK0q
++xgncPOJeE4X55dv1nAGD/0fGeHTcuShzUoipCKAd1CZdXK2Ge3gZRH2WUvlQGd5J
++ARd43zbd2wXZX0h0e1/BWQVeXx/Cg6u31B5lll7B3rWeoZHvfV9DSC7e3IEOhgzG
++5cyAh+wrtlCszjiMreHSSYCQh9tlyK+ACOJUFtZFGdseBsMxRgXWtHr+ypW2iJI4
++KsEU/MNXr1Bqg7FGxIw0Oyc2zyzjgD9aq4CKEy64MYB1ZYf41Rbc2Z+pMx1MW9or
++sPp7qSp6SmpTk0RTHpH0O2wNC9F26wIDAQABAoIB/03LuNT2nmo+NwOYGuzjQUeM
++eKd/vDIWWORoKm69wvHaQ/wFCr37Fc+ovMDD616N8j10d1ql5T4HCwfesdEnXljD
++k+RU68wT1OvdJ5Yj84w0mQ0c1TtXFhsVsChiL8htEtC04vK1RphRt0s8GQDkANI/
++STXwz2Pe32sG4Q/iTcO3EkzBwVEfDQxkf4CyPNRVIZMVu+sOSoSfFB2/TXxfTrgA
++iVsZGgS+i1+a2p0OuzXb2cl+mrv+8g2Czj0pSgDURU5QRwDGi+CuuorN7xx6i+Uw
++khNH7X3SbnE9lAU2PF0KchMSUy6gp6YTiExPBXj80+fib4Wd+CdY2S1K9rNgOGG7
++4yOU9vbkgt4r+cXFu/NvG2GBMw5/Dqn7tFu+nLxC98/IrgFbsFPMwD/vS4IWYw+a
++CSy7Ed3FfPNlvE7Q2VoDOVpJoUAJZWrLFOisMSCSSq9Zfxc45Usz+hzg85nysywD
++5FS6LvGEdXJu0FTUHrBMBmcbYpdyVrY7qeQ2k4imC9+AKt+MuswJ+ofBLkxhgWlN
++NAaGOFdDKszDjYYgLEszL6M5Uwk+iBWfhPB0kuAqMCfljWwMVz6Apg6kjF4vk6rF
++ObvlXAcchk7SuxHJFgRLGWw5WzPXxmK7StrDLpWiiWqnqf7LKpnclKlan8ML5vo4
++swwfDO6Q9Jw07fPoJfUCggEBALvAanX7Z8Dbc86uYh08myZPn4GHrz7qc1ouvV5T
++QsQ4iWEvVomPLtw57iSWX5x2hot7XyEZETOj+RHxmRsNHIewWk0+iAKAe9fw2FJD
++8DDki585G6HOsw/rN00xWymT47cLyESlYIq3eJYuZld8tCmg7Nfoe83CiRZXChlQ
++1TZWQlWxPR/Ykv6fitZrLfByl8JrVUNwr3rBMeegXF5d6tZ8FB89BiyOkdDrO8fz
++ZIACG60+6QN9pghcCz8tDJKqYyhcd/Z4LNmBqMeCyX1LJ8Ig0paXF1B/iV9Cxsti
++aV/m+nLea9HGy3RlFe5NgRqDaqctv/Aq4NkmGgvB5Bbx678CggEBALrFdzVKeOjl
++vlkA5f95eVWmpr0DK5/r2ZM+i8zTCBhzxlFDL3pC2hmVk41bE4O9RNrzCwgqO8Aa
++GtwA7iqT5B1dmYhypt62iK1ZZce+l93JLLInTP3UCCFVzwC/akrcRHQdyKh9MyP7
++tAgdTaM49xlaakiems0KxpR2RQ2dzQMPUDxqiD20bcIErIVk1+1mk2l6MiqTAHHx
++fK/WtULQGSAPwHJmhrGKKwUPJIChcDGJxMtrnpD5tcZpjF3W6+xZbyqcgYMwbpOn
++cALvKzfA0Cg0/oAOdcrVJU+iQyXUDIN57ezwAU/oyGVOofIVQn4xVBaH3F/JtAAG
++TM+WygbP79UCggEBAKsWQ+0PExSi5XzJW47Y02it1ePrCL6EVmkvflCd/pFgE5AD
++2w+u8jysbV3ZyXaCa0hfO+ilNw+ftC+twJ7t67mZ8i/Bc58UBcZZKkaMsitbl/+X
++wp5IBNPUu6gT+caBhVgf3HbxXHALkE8KKSg/8sycYDa/G1H8m39IAWPgTOoe4IPF
++5rVGXWy5ZYLOWCZrxe7cb+3smXt64Ub40jML0htxJcTxjta7dBS0xt0F5ebgBOhy
++E1OjA9FKTtVa78IWkhUNbiOijvwFMw/bFlCeU7SKxFuFgzFPhpbP+ucK3osNp9tU
++41tdk7iVBM8KwUKvzlhZUDZCXHKETee432gpO3ECggEAJGJZcbE7UquG5FHPfHBO
++mcfoTYPzmKjabtvNYi5uMk1DggsjkZ66XCeOYggvCgfyBPE54fJQR4EOYHNx8itz
++UeEtCq7DITnP8G0s7beMYDFTmrUbQ4tttgjAVbX0X/b/AtvWfjQ9pTHghYAn4rcz
++M+YwNEtpfq4ttzg/BYMLMCBokgxy1Ap1I0nDzgyyH9ZOu0qJwU9307qmfp7GGujt
++LBjFdcPRU37GGKs1gjVw5MWg57vkXPu4VJm1NYar2RQnGtb4R/VEZVFF+dxbv/W4
++10xTk+C9Q7E4HoZOrGzdrzMujWzH5KhFea7Sz5UiqfC0H9uBq8tgXGzdw8btPlx9
++rQKCAQEApnc3/WwS4fsbbZKjycvZu102sZfDRx1lYPpylUyEKm9iSq97miuC5/bO
++J3HkK9e+uye3klB3lYnNHKjeFEDoq8DJJ33M/pyY9BuowOZtLJcGu5Krq42FFpaZ
++HIEcZWMwDPaNLunZAXkGpqdw7GPNivSrzy20iJgJLEVXwr0krT5UMVRKo5Xsq/P1
++rxJ78psVCsbOHvVgUfN6fHPf1I+EyLB+Dipr3qPNU1Aty0OCdI+2BeT90ovZiKvu
++dBnuWQOR7HlBimgHsF4Gb9Akjoix6SJKbm/E9GvLfUYbiIkARc99QC3G6h17PGiF
++C2j6oHefg+K1iyTA4LCTAkHWax2ggg==
+ -----END PRIVATE KEY-----
+diff --git a/sample/sample-keys/client-ec.crt b/sample/sample-keys/client-ec.crt
+index 759daba..c948b11 100644
+--- a/sample/sample-keys/client-ec.crt
++++ b/sample/sample-keys/client-ec.crt
+@@ -1,85 +1,86 @@
+ Certificate:
+ Data:
+ Version: 3 (0x2)
+- Serial Number: 4 (0x4)
+- Signature Algorithm: sha256WithRSAEncryption
++ Serial Number: 7 (0x7)
++ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=KG, ST=NA, L=BISHKEK, O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
+ Validity
+- Not Before: Oct 22 21:59:53 2014 GMT
+- Not After : Oct 19 21:59:53 2024 GMT
++ Not Before: Nov 7 12:23:40 2023 GMT
++ Not After : Nov 4 12:23:40 2033 GMT
+ Subject: C=KG, ST=NA, O=OpenVPN-TEST, CN=Test-Client-EC/emailAddress=me@myhost.mydomain
+ Subject Public Key Info:
+ Public Key Algorithm: id-ecPublicKey
+ Public-Key: (256 bit)
+ pub:
+- 04:3b:ce:62:5d:6f:87:82:75:24:c2:58:f5:0e:88:
+- 4d:57:0d:06:b2:71:88:87:58:19:bb:de:5f:7f:52:
+- 62:51:a2:48:91:83:48:91:90:3e:87:02:0f:15:51:
+- f9:68:97:12:0a:fd:d2:3c:87:83:4b:65:54:00:44:
+- 8d:28:76:49:05
++ 04:25:bd:3e:da:c5:cd:35:c0:44:d5:82:11:77:7a:
++ 24:12:1e:40:53:7a:ff:0d:0c:67:05:94:ce:5d:44:
++ 26:51:9b:0c:57:b1:38:30:9d:bd:13:03:59:12:0e:
++ c8:35:5c:ca:b6:d1:81:41:9d:ac:9f:ec:2b:58:07:
++ 29:6d:d3:5f:5c
+ ASN1 OID: secp256k1
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ X509v3 Subject Key Identifier:
+- 64:F6:49:88:E7:74:C1:AB:A5:FA:4F:2B:71:3C:25:13:3D:C8:94:C5
++ D4:76:DB:EC:D0:11:63:0E:FE:BA:4E:10:76:22:07:D7:99:02:DE:F6
+ X509v3 Authority Key Identifier:
+- keyid:2B:40:E5:C9:7D:F5:F4:96:38:E9:2F:E3:2F:D9:40:64:C9:8E:05:9B
++ keyid:73:B1:B8:D6:8A:95:6B:12:E0:74:7C:C5:57:55:98:94:5B:AC:78:5E
+ DirName:/C=KG/ST=NA/L=BISHKEK/O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
+- serial:A1:4E:DE:FA:90:F2:AE:81
+-
++ serial:6F:50:B8:D3:46:6E:72:34:59:BC:00:33:DD:7C:AE:12:EB:27:46:06
+ Signature Algorithm: sha256WithRSAEncryption
+- 32:3d:f0:08:67:dd:03:73:76:cc:76:52:0a:f6:97:d1:c6:fa:
+- 5f:d3:e6:28:c9:75:a7:08:a8:34:49:69:cf:eb:ab:da:86:b3:
+- 2e:65:17:ee:7e:b6:b5:6b:15:0b:dc:11:3a:b9:5a:b3:80:b8:
+- bb:f4:6c:cf:88:3a:10:83:7e:10:a0:82:87:6e:06:ec:78:62:
+- d4:d1:44:27:dd:2c:19:d8:1a:a1:ae:f4:a0:00:7f:53:5a:40:
+- 8a:c2:83:77:4b:26:7d:53:b0:d3:0f:2f:7c:28:70:ef:74:58:
+- 5b:de:81:94:4c:63:19:f0:79:cb:6c:b2:ec:32:1b:4b:e4:62:
+- 22:4f:ad:ac:4a:6f:a9:6e:c4:2a:8d:8a:88:19:09:fd:88:93:
+- 3c:27:4d:91:95:ff:57:84:13:fd:4a:68:db:20:df:10:e6:81:
+- 1d:fd:e7:1d:35:fb:19:02:dd:b5:5f:a0:c1:07:ec:74:b4:ef:
+- 8b:f9:33:9a:f2:a6:3b:6e:b6:4a:52:ab:5d:99:76:64:62:c4:
+- d5:3a:c6:81:8d:eb:c8:4b:02:af:e1:ca:60:e9:8d:c7:a9:2b:
+- ea:4f:56:31:d3:9a:11:c2:9c:83:5c:a2:8d:98:fe:cc:a5:ad:
+- 1f:51:c4:6e:cf:ff:a0:51:64:c8:7f:7f:32:05:4c:8d:7f:bf:
+- b8:ed:e5:81:5f:81:bd:1d:9b:3f:8a:83:27:26:b4:69:84:8b:
+- e5:d9:ea:fd:08:a8:aa:e4:3a:dc:29:4d:80:6c:13:f7:45:ce:
+- 92:f2:a9:f3:5f:90:83:d6:23:0f:50:e5:40:09:4c:6b:f2:73:
+- aa:d8:49:a7:a9:81:6e:bb:f2:e4:a5:7f:19:39:1d:65:f3:11:
+- 97:b1:2b:7c:2f:36:77:7f:75:fd:88:44:90:7c:f2:33:8d:cd:
+- 2c:f6:76:60:33:d3:f4:b3:8c:81:d7:85:89:cc:d7:d5:2c:94:
+- a9:31:3f:d3:63:a7:dc:82:3f:0a:d8:c5:71:97:69:3b:c1:69:
+- cb:f0:1b:be:15:c0:be:aa:fd:e8:13:2c:0c:3f:72:7b:7d:9c:
+- 3b:7f:b8:82:36:4b:ad:4d:16:19:b9:1c:b3:2d:d7:5f:8b:f8:
+- 14:ce:d4:13:e5:82:7a:1d:40:28:08:65:4a:19:d7:7a:35:09:
+- db:36:48:4b:96:44:bd:1f:12:b2:39:08:1e:5b:66:25:9b:e0:
+- 16:d3:79:05:e3:f6:90:da:95:95:33:a1:53:a8:3c:a9:f0:b2:
+- f5:d0:aa:80:a0:96:ca:8c:45:62:c2:74:04:91:68:27:fb:e9:
+- 97:be:3a:87:8a:85:28:2d:6e:a9:60:9b:63:ba:65:98:5e:bb:
+- 02:ee:ac:ba:be:f6:42:26
++ Signature Value:
++ 72:fd:18:d4:c2:0f:ba:6f:94:f2:f9:26:8b:93:fb:d5:99:df:
++ f7:aa:e6:27:f2:89:86:ff:6d:0a:24:ea:ae:d4:68:7b:08:38:
++ 8a:7a:f9:a2:4d:e5:fe:2e:e1:bb:09:8c:2d:df:85:7b:01:dd:
++ 58:4b:15:2a:db:49:10:ab:f1:78:49:fb:94:b3:31:e3:09:e0:
++ 63:3c:d0:f2:34:18:de:37:0a:2d:d3:02:d5:ae:05:49:57:e7:
++ 47:d0:70:3f:f1:35:28:82:79:00:b3:c8:45:00:86:77:d7:68:
++ 63:d2:3d:8b:ef:a9:f8:99:97:fe:d0:0a:98:cb:7a:7b:73:28:
++ 77:f4:bb:cf:1c:63:7e:64:60:87:f7:51:68:e9:7a:90:70:d8:
++ a0:e2:c6:88:70:62:2c:49:ac:ba:8c:2e:c5:d7:c9:42:8b:44:
++ cc:ae:f3:40:79:1c:99:09:2c:4c:24:89:55:41:ce:c6:52:a9:
++ a3:b7:4c:e6:75:63:4f:b6:70:84:1b:3e:56:f5:42:5f:b1:50:
++ 46:eb:33:41:28:f8:30:f6:f9:f9:c0:5d:9b:a4:af:8e:03:c8:
++ 3e:88:66:04:2e:5b:ec:50:36:a8:d1:9f:8e:e0:59:40:bb:f8:
++ ff:45:7d:40:2e:6d:f0:e8:84:5b:db:7e:0d:88:b3:a2:f6:34:
++ 5b:b9:a1:1d:a0:fa:85:78:3b:9b:b3:0b:6c:f1:03:06:9c:f1:
++ e3:ba:64:a3:5c:d8:c8:d5:73:4a:3f:4d:83:aa:e8:c4:ce:dd:
++ 92:23:b2:c8:ab:e5:39:93:d9:d7:ca:70:c2:ff:8f:71:40:f6:
++ c4:89:4a:72:0b:2a:7a:20:15:5b:a4:e9:75:a0:df:93:2b:7d:
++ 1a:54:39:2c:80:4f:21:32:5f:9f:d8:96:08:2f:dc:e2:45:1f:
++ 96:e9:31:84:90:2e:1d:07:92:56:a8:22:49:25:1b:bf:47:d5:
++ fa:34:e9:cc:7c:b2:18:ca:5e:d6:76:5e:b6:19:72:c0:10:d6:
++ c2:c6:f1:03:d4:0e:62:28:d8:56:e1:08:3a:f4:54:8f:7b:0d:
++ a5:62:53:8a:72:7b:2f:fa:80:8a:3a:54:4d:11:5c:58:7e:fc:
++ 15:30:9b:fe:ef:35:a1:00:c0:15:0f:47:14:af:09:9f:1e:dd:
++ 7a:ed:ea:2b:c8:a1:51:26:a3:d1:25:8c:31:1b:41:30:27:ca:
++ e8:3f:00:2b:83:8f:b4:f8:11:30:71:b8:4c:d8:af:48:88:aa:
++ e5:96:3e:f8:01:a9:17:b6:f2:09:27:d0:e9:b3:b3:89:b2:0f:
++ f7:c5:78:b3:b2:e1:26:a2:78:2b:4c:9d:99:57:4f:7e:fa:fe:
++ 9b:ae:6f:c4:6a:b1:7c:d0
+ -----BEGIN CERTIFICATE-----
+-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
++m65vxGqxfNA=
+ -----END CERTIFICATE-----
+diff --git a/sample/sample-keys/client-ec.key b/sample/sample-keys/client-ec.key
+index 8131380..b0c81ff 100644
+--- a/sample/sample-keys/client-ec.key
++++ b/sample/sample-keys/client-ec.key
+@@ -1,5 +1,5 @@
+ -----BEGIN PRIVATE KEY-----
+-MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQg2RVk/d0yok086M9bLPIi
+-eu4DfcBUwphOnkje1/7VSY+hRANCAAQ7zmJdb4eCdSTCWPUOiE1XDQaycYiHWBm7
+-3l9/UmJRokiRg0iRkD6HAg8VUflolxIK/dI8h4NLZVQARI0odkkF
++MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQggBG28jKEqUG3n/wcnvcr
++h2VP5dXkRChxqLw3ydT+HpGhRANCAAQlvT7axc01wETVghF3eiQSHkBTev8NDGcF
++lM5dRCZRmwxXsTgwnb0TA1kSDsg1XMq20YFBnayf7CtYBylt019c
+ -----END PRIVATE KEY-----
+diff --git a/sample/sample-keys/client-pass.key b/sample/sample-keys/client-pass.key
+index 2bb8d4e..089f906 100644
+--- a/sample/sample-keys/client-pass.key
++++ b/sample/sample-keys/client-pass.key
+@@ -1,30 +1,30 @@
+------BEGIN RSA PRIVATE KEY-----
+-Proc-Type: 4,ENCRYPTED
+-DEK-Info: AES-256-CBC,ECC1F209896FC2621233FFF6F1FFD045
+-
+-i6t7VKTyNNELTvrBO464e02nFg9rvYwumxd0sfqcPtaKmRK2mrZmEd/Xh0Nv1WyB
+-PyuJo78qQixAtxObRbkSNINzTr5C8IDrE6+wQYCJinvO54U0o+ksv0tsyLngz1cb
+-is8ZqHXrRgJ3qGFQWmFRtFKFQvSXOTDX3fLkEB53HfeblQCxBCnJ82Sp7ivnVR/j
+-Q8qQRy1RMbzIN0trEGf0Zi4tHEvXL1u7Y+olQzSlmWWaQt20hhXUOMLhMtlRsAo7
+-AwjlE94JjAfJ1q1dwIcRN4c9Lk8GkiX6w7nDpRACDpk2S8ifCqi69eGe4+g7owhL
+-74bgs64PmM9a2sNXy1v6WE3c/t6sSrZiMvrGsqMo4sBlrQ9WXe0Naon7heBkPcdS
+-px0YJjnyBXHMIH+ASmALSJ5JXq9vt2xRFf0dOsGapxhP+7bZJ5Pwyk/yUu5uHFbM
+-/aBemlrZJzlKeYiiwpwx2whQAtDwN41zMG+r27EzSU/AaDV40NPiwwycpWt/Bp1e
+-z1ag0JuS0an+PK4jmREtzT5U5BeAVM91x8YttOPpmUIpahAa1zwdYPRAIkbmPJ4z
+-ZH+9YoPH4hoBQKdIhshYktjdI++xNiKXAUGUz5YoX8S68SsLdmKvhnQ7fu5VvOkA
+-2pb7taXGy7zfn+a/fWauhuceV9HPlAXMIu3GsssODoNly3vpcFeiMySKppygJ3Eg
+-A3o9n8UepD+jXflKG/R/t7U3hT6LqSIvQWqBqYMEVFMCNzSsJ/ce/4veFvx343zT
+-qdxuzYqyiXM74cynpfqHdVa9SFICTesNdVDI0FdOXhSQ4bHJc7Xp9FFJdS0lMRw4
+-ACwKxvs8lo4Gx1WFyCqH5OxosKtDHQYzdUJfSWVJlhhOFR3GncR9qSe3O5fkhJfs
+-TALnC+xTJyCkSB2k0/bxVLIhlkPdCwzsrN/B6X2CDBdg0mQIo0LaPzGF8VneM20d
+-XebYn751XSiL3HKyq8G5AEFwj9AO3Q8gKuP2fPoWdngJ2GT+mt1m2fIw9Igu39J0
+-ZMegyUN0wSIiA5AkgryK9U+PJEiJmLzOJ/NGr7E5tPF18eZWapK4KZ8TXC4RNiye
+-g+apGa+xZJz2VQp/Mrcdj9D4UDJFQjrvKaS0PXJDoYUXFBoMv3rxijzRVxlhhuJY
+-yZ0At+UqZD5wpuWW6DRrgJIpy0HNhbaLmgsU0Co0HKviB0x8hvMJbi/uCoPTOdPz
+-sPB7CN2i3oXe7xw1HfSTSFWb4leqjlKwNgfV42ox0QUjkkADeeuY+56g/B2+QmdE
+-vXrc6sDwfNUwRUzeMn8yfum/aW1y/wrqF/qPTBQqFd85vlzS+NfXIKDg04cAljTu
+-+2BLzvizh9Bb68iG4PykNXbjbAir1EbQG1tCzq1eKhERjgrxdv6+XqAmvchMCeL5
+-L6hvfQFBPCo/4xnMpU5wooFarO/kGdKlGr5rXOydgfL618Td18BIX+FHQFb3zzVU
+-y2NR4++DslJAZgAU+512zzpW1m3JtaRoyqyoLE2YFPlW804Xc1PBB3Ix6Wyzcegy
+-D4qMk5qxjBkXEsBBSCYfVbWoMBeMhnvxkz0b9wkPtAW/jEJCB2Kkn/5yMC0DkePO
+------END RSA PRIVATE KEY-----
++-----BEGIN ENCRYPTED PRIVATE KEY-----
++MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIVDt6h9I/tNsCAggA
++MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBDK/DTdm5la+nBeb36XV2oxBIIE
++0Elt0ly1Cwc1o6EHRs3rFT3EYqm9DMVrcQgquI0qdbbUMtAsDmMFmW9TI7wedCDR
++Ey3olanxK2dwz9qupSmtH25j4dFtPVxfF0moND6I4cQTmzBzTOjkK4LzgMucWfFL
+++J/GQxJsh0npaEu2t7HSpbKDR4uWcRiPkjxc7gFRPJH8NF51ySnF7htUODh/lmsM
++mRbdD5asKzIvrOJSVWBs7RLtj8GRCHttOLMq6ib3O0/8WvBDPEVXfPJMH8JRNxJc
++woz6CSOPoI7yd9tKnRf0YGOuPiFWc1J1LTqgvWxVuwaUGrlwRZQ3nMnKK9jfXIGr
++FmhkHYFqWX2tpYy1nI9i7qYqG0MdWTmf/Gng1/YA5jTDW3dpcCnm5bd2eyzgw0qG
++PFnjjdVlJnEKZe5phTzrffzKWW8oOBDRww63RtgnNykipPK2V+Wq3RHQ3Oach8ZB
++0RqyLCG1wFLN9qA3TmvmPDDLsksLj9LiCstqo6FyHrvy1NFsCVlVqeVcOay1VCT9
++ApFHa5SRaW5PxTSUKfses1eIjB48Z+yplJ+6sIkv4jrTcXyjrJSmZA8GU1jVvO08
++O2W4PGLX3C4B6iIel2eZMyG2EHM24kIAH4Dqx+GDZBhSuRBwhTN7+c9nX3fmVs3t
++cTe1uPOYu73W9zHLOSIRkO8WKcyoTzf5FQqfVhVRLmb1Z0pA+qVQps6g7DyL1/da
++zwHYgdAk0wSK20JYlXOz+7lYUsg/o4sFKTYseHVQIhXyEfUIE5gBxTEltCc+FBlI
++q0wLW5axVFJZx1uaEV0/mAOLSkL8QEKd5VOlV+mT7sDk38AdyoBbk2rmmn4SeYB5
++tmAzNC1d8aTAANo51bvt9BL3gzzvAduwuzl/3kYGsd7ASnrYZYDMwxtObR3Ltj12
++Jq+Uv9lknmsbuhNWY/rXE0eQT2sT7PIW4Y3HqxzVlA3TeWc6ug7GLbabQMfeFPct
++OouOgj74jIvqBRYzLvyAdLKBuDadSVvCpxJddgS9mc3Ne53YPKtT8tPSuPzDVLRp
++rMQyHKh+C9HCEozDGAjzLbr/icE1PfmxDfKbl99C5bRG2WlSL3VNxcuRr7o09LRK
++Y2k/zE0WzQtgiNaV9MOykcf3NBgRhIYwpH+O1oT2kxlorAWJbh3FyFZUxZlPr+we
++dZSBXtrZ/6aevm76f/qsHvjqC3MfHbQ5544Z5lEvPGke2w7du7Vcu7141Oghzl0a
++qw1gCok/CKy4iWoTS8sfnaKB5eXhk9KFHN/ALHztDQlq2qQ6O2KEIndHzd3IAspB
++NgEFW+UmSankwA5QnDCoyqgvnybaCJwRcsk189PJYOUQMKrvwzdYWQJIkA/XZDGq
++3TF9+bm7hJifD4nOMI0RYU5kROPLR4nKUTkRVOaMEdV8jTCWzjPaffiYKk8IDVhy
++zVnKpuuiPBU6mZKIlBwMAEwUdFSUZ8huRCoa8UGqyukJmYR5JSxJVwtqwtCqHsXd
++2nujp0MvGdJy7V/9TIocKCbJOgubuOYt3F+tp78fUYY0P0TAVIa94Be/P5B+tzKN
++/EjT+mv6RP6YnFSKSGC8CKTolPa2rKJBH+UpaHdFdbKifmY+snIMe2wzYlI62gFj
++uJc7ZHyi4MMbzdWSLblOP+KUhn0qKBJAS12cgOVWP5bb
++-----END ENCRYPTED PRIVATE KEY-----
+diff --git a/sample/sample-keys/client.crt b/sample/sample-keys/client.crt
+index 1744cb2..9718d34 100644
+--- a/sample/sample-keys/client.crt
++++ b/sample/sample-keys/client.crt
+@@ -2,102 +2,102 @@ Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 2 (0x2)
+- Signature Algorithm: sha256WithRSAEncryption
++ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=KG, ST=NA, L=BISHKEK, O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
+ Validity
+- Not Before: Oct 22 21:59:53 2014 GMT
+- Not After : Oct 19 21:59:53 2024 GMT
++ Not Before: Nov 7 12:23:39 2023 GMT
++ Not After : Nov 4 12:23:39 2033 GMT
+ Subject: C=KG, ST=NA, O=OpenVPN-TEST, CN=Test-Client/emailAddress=me@myhost.mydomain
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+- 00:ec:65:8f:e9:12:c2:1a:5b:e6:56:2a:08:a9:82:
+- 3a:2d:44:78:a3:00:3b:b0:9f:e7:27:10:40:93:ef:
+- f1:cc:3e:a0:aa:04:a2:80:1b:13:a9:e6:fe:81:d6:
+- 70:90:a8:d8:d4:de:30:d8:35:00:d2:be:62:f0:48:
+- da:fc:15:8d:c4:c6:6d:0b:99:f1:2b:83:00:0a:d3:
+- 2a:23:0b:e5:cd:f9:35:df:43:61:15:72:ad:95:98:
+- f6:73:21:41:5e:a0:dd:47:27:a0:d5:9a:d4:41:a8:
+- 1c:1d:57:20:71:17:8f:f7:28:9e:3e:07:ce:ec:d5:
+- 0e:42:4f:1e:74:47:8e:47:9d:d2:14:28:27:2c:14:
+- 10:f5:d1:96:b5:93:74:84:ef:f9:04:de:8d:4a:6f:
+- df:77:ab:ea:d1:58:d3:44:fe:5a:04:01:ff:06:7a:
+- 97:f7:fd:e3:57:48:e1:f0:df:40:13:9f:66:23:5a:
+- e3:55:54:3d:54:39:ee:00:f9:12:f1:d2:df:74:2e:
+- ba:d7:f0:8d:c6:dd:18:58:1c:93:22:0b:75:fa:a8:
+- d6:e0:b5:2f:2d:b9:d4:fe:b9:4f:86:e2:75:48:16:
+- 60:fb:3f:c9:b4:30:42:29:fb:3b:b3:2b:b9:59:81:
+- 6a:46:f3:45:83:bf:fd:d5:1a:ff:37:0c:6f:5b:fd:
+- 61:f1
++ 00:dd:ae:b2:0a:40:e6:cf:e1:c1:a2:a1:d2:83:2c:
++ 31:98:e2:1b:b2:85:40:67:00:fa:ab:bf:cf:9d:14:
++ d1:c6:b7:63:83:aa:5f:9c:14:a0:d2:4d:04:3a:4a:
++ 92:e6:92:4b:a4:86:40:26:42:bd:83:b7:fc:49:b7:
++ 56:d2:ca:e7:70:85:16:8f:8b:3b:da:47:9e:8b:6a:
++ 4a:c8:e6:a8:de:ae:6b:2d:52:22:0c:9d:cf:67:bb:
++ 7d:1e:66:05:53:8b:7c:ae:ad:d1:a6:52:5f:3d:9e:
++ 6b:28:18:57:d9:a1:42:2d:c0:b0:4d:da:4a:f0:29:
++ aa:02:34:86:02:aa:af:67:09:06:ed:45:21:8e:8c:
++ f8:75:56:c7:ea:e8:4f:88:8e:1c:8b:5b:68:2d:b1:
++ 66:a5:e4:c6:36:e2:70:8d:fe:ef:10:f0:52:f8:53:
++ 96:bf:7e:51:70:f2:3f:ae:58:87:38:d1:a3:6b:f6:
++ 38:51:9b:16:ce:67:35:8e:6d:76:63:4d:6b:9b:7d:
++ 77:da:55:6f:20:b1:66:4f:9a:2d:a4:73:3a:52:21:
++ 86:3c:f3:a6:5a:67:e5:7d:10:f5:36:56:21:7e:03:
++ 22:bd:98:e9:18:b4:3f:b3:b5:0d:ed:d5:ef:54:96:
++ 6f:9d:46:6c:6f:0e:ba:4b:1a:f7:cc:d4:e5:24:ba:
++ d2:a5
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ X509v3 Subject Key Identifier:
+- D2:B4:36:0F:B1:FC:DD:A5:EA:2A:F7:C7:23:89:FA:E3:FA:7A:44:1D
++ 59:33:B9:2E:63:D1:17:A8:9F:BD:D8:CE:94:21:C5:41:C7:31:62:5D
+ X509v3 Authority Key Identifier:
+- keyid:2B:40:E5:C9:7D:F5:F4:96:38:E9:2F:E3:2F:D9:40:64:C9:8E:05:9B
++ keyid:73:B1:B8:D6:8A:95:6B:12:E0:74:7C:C5:57:55:98:94:5B:AC:78:5E
+ DirName:/C=KG/ST=NA/L=BISHKEK/O=OpenVPN-TEST/emailAddress=me@myhost.mydomain
+- serial:A1:4E:DE:FA:90:F2:AE:81
+-
++ serial:6F:50:B8:D3:46:6E:72:34:59:BC:00:33:DD:7C:AE:12:EB:27:46:06
+ Signature Algorithm: sha256WithRSAEncryption
+- 7f:e0:fe:84:a7:ec:df:62:a5:cd:3c:c1:e6:42:b1:31:12:f0:
+- b9:da:a7:9e:3f:bd:96:52:b6:fc:55:74:64:3e:e4:ff:7e:aa:
+- f7:3e:06:18:5f:73:85:f8:c8:e0:67:1b:4d:97:ca:05:d0:37:
+- 07:33:64:9b:e6:78:77:14:9a:55:bb:2a:ac:c3:7f:c9:15:08:
+- 83:5c:c8:c2:61:d3:71:4c:05:0b:2b:cb:a3:87:6d:a0:32:ed:
+- b0:b3:27:97:4a:55:8d:01:2a:30:56:68:ab:f2:da:5c:10:73:
+- c9:aa:0a:9c:4b:4c:a0:5b:51:6e:0a:7e:6c:53:80:b0:00:e1:
+- 1e:9a:4c:0a:37:9e:20:89:bc:c5:e5:79:58:b7:45:ff:d3:c4:
+- a1:fd:d9:78:3d:45:16:74:df:82:44:1d:1d:81:50:5a:b9:32:
+- 4c:e2:4f:3f:0e:3a:65:5a:64:83:3b:29:31:c4:99:88:bc:c5:
+- 84:39:f2:19:12:e1:66:d0:ea:fb:75:b1:d2:27:be:91:59:a3:
+- 2b:09:d5:5c:bf:46:8e:d6:67:d6:0b:ec:da:ab:f0:80:19:87:
+- 64:07:a9:77:b1:5e:0c:e2:c5:1d:6a:ac:5d:23:f3:30:75:36:
+- 4e:ca:c3:4e:b0:4d:8c:2c:ce:52:61:63:de:d5:f5:ef:ef:0a:
+- 6b:23:25:26:3c:3a:f2:c3:c2:16:19:3f:a9:32:ba:68:f9:c9:
+- 12:3c:3e:c6:1f:ff:9b:4e:f4:90:b0:63:f5:d1:33:00:30:5a:
+- e8:24:fa:35:44:9b:6a:80:f3:a6:cc:7b:3c:73:5f:50:c4:30:
+- 71:d8:74:90:27:0a:01:4e:a5:5e:b1:f8:da:c2:61:81:11:ae:
+- 29:a3:8f:fa:7e:4c:4e:62:b1:00:de:92:e3:8f:6a:2e:da:d9:
+- 38:5d:6b:7c:0d:e4:01:aa:c8:c6:6d:8b:cd:c0:c8:6e:e4:57:
+- 21:8a:f6:46:30:d9:ad:51:a1:87:96:a6:53:c9:1e:c6:bb:c3:
+- eb:55:fe:8c:d6:5c:d5:c6:f3:ca:b0:60:d2:d4:2a:1f:88:94:
+- d3:4c:1a:da:0c:94:fe:c1:5d:0d:2a:db:99:29:5d:f6:dd:16:
+- c4:c8:4d:74:9e:80:d9:d0:aa:ed:7b:e3:30:e4:47:d8:f5:15:
+- c1:71:b8:c6:fd:ee:fc:9e:b2:5f:b5:b7:92:ed:ff:ca:37:f6:
+- c7:82:b4:54:13:9b:83:cd:87:8b:7e:64:f6:2e:54:3a:22:b1:
+- c5:c1:f4:a5:25:53:9a:4d:a8:0f:e7:35:4b:89:df:19:83:66:
+- 64:d9:db:d1:61:2b:24:1b:1d:44:44:fb:49:30:87:b7:49:23:
+- 08:02:8a:e0:25:f3:f4:43
++ Signature Value:
++ 2a:9e:02:65:f4:3c:c0:37:88:f0:21:f9:fd:2e:7c:f4:8b:bb:
++ 67:7d:f7:48:0c:98:f7:a1:46:4e:33:af:68:77:f4:53:03:09:
++ fd:4e:32:cb:0f:2c:f1:16:37:35:65:aa:68:79:16:a9:32:03:
++ d7:89:10:ef:ba:fd:e1:26:2c:60:7c:3b:42:60:68:47:cf:61:
++ 88:00:77:e7:71:76:49:78:35:52:45:a4:31:7e:2b:e1:0a:c8:
++ ed:e1:a7:28:2f:23:a3:ce:ce:b5:99:6b:54:4d:df:d2:64:0a:
++ b7:c5:25:1e:d4:f7:a1:fd:4f:f3:12:d3:26:5f:3b:b2:93:93:
++ d1:8b:4b:4e:dc:d0:15:63:d1:77:36:75:34:76:37:59:ff:a0:
++ 81:01:ec:b6:42:2f:bd:85:5d:d0:ef:ff:90:61:d6:91:b0:f5:
++ e6:94:66:7e:4c:20:06:c4:2e:0c:9b:9f:7f:89:f0:3e:8f:e5:
++ 06:6c:81:75:a2:0b:c5:ac:44:f1:32:cc:57:90:a0:19:47:8c:
++ 25:7a:d5:f1:61:1f:19:bf:4c:31:da:44:c1:30:91:e8:b5:cc:
++ e4:7e:20:55:0a:b9:dc:f3:5e:f5:7c:d1:0b:ee:71:c6:d6:38:
++ 7e:85:7b:6c:cb:10:85:1e:6a:50:ab:c3:ae:f9:ff:96:4f:a3:
++ 76:d6:fd:c0:f9:c7:9a:60:a8:8c:e5:9a:c5:a9:7b:63:11:ef:
++ 7b:b9:9b:1f:63:51:a8:6d:2b:d6:f7:ef:51:bd:a8:32:9e:92:
++ aa:24:01:c9:e3:6a:c8:94:2e:d2:66:b2:c7:17:e5:06:53:9a:
++ bd:8a:19:8f:3a:51:7a:25:11:e5:e8:59:f7:1b:df:95:98:35:
++ c1:a6:74:15:6b:b1:2c:97:9b:fe:76:7e:56:20:4d:ee:07:8a:
++ b9:8b:bc:92:a9:19:81:28:91:4e:d2:9f:51:99:72:c0:12:76:
++ 5b:c8:74:68:b5:9d:43:53:c1:af:39:b9:28:82:a0:0e:bb:ef:
++ 21:d8:71:dd:02:af:dc:df:48:7b:39:21:7d:83:76:ea:e2:c7:
++ 16:bb:d2:1a:1d:22:f6:4b:47:15:56:41:06:4d:39:1c:96:3f:
++ 25:2d:83:8f:a4:a2:86:fa:0e:e9:45:9c:bf:26:40:e6:3e:9e:
++ d5:00:9f:ce:76:6f:df:cb:b2:85:b8:83:f2:ed:8b:b6:5a:68:
++ b5:c7:1b:ab:19:75:60:f3:5b:e7:5c:70:27:d9:1c:d8:24:f0:
++ 2a:aa:2a:a6:98:77:d6:36:d9:02:35:a8:d3:2c:19:88:b8:0b:
++ d3:76:58:72:54:99:94:9a:ee:38:9b:8d:8e:10:48:cd:28:50:
++ 31:b2:4b:d3:69:7b:91:b4
+ -----BEGIN CERTIFICATE-----
+-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
+-CAKK4CXz9EM=
++DQEBAQUAA4IBDwAwggEKAoIBAQDdrrIKQObP4cGiodKDLDGY4huyhUBnAPqrv8+d
++FNHGt2ODql+cFKDSTQQ6SpLmkkukhkAmQr2Dt/xJt1bSyudwhRaPizvaR56LakrI
++5qjermstUiIMnc9nu30eZgVTi3yurdGmUl89nmsoGFfZoUItwLBN2krwKaoCNIYC
++qq9nCQbtRSGOjPh1Vsfq6E+IjhyLW2gtsWal5MY24nCN/u8Q8FL4U5a/flFw8j+u
++WIc40aNr9jhRmxbOZzWObXZjTWubfXfaVW8gsWZPmi2kczpSIYY886ZaZ+V9EPU2
++ViF+AyK9mOkYtD+ztQ3t1e9Ulm+dRmxvDrpLGvfM1OUkutKlAgMBAAGjgdMwgdAw
++CQYDVR0TBAIwADAdBgNVHQ4EFgQUWTO5LmPRF6ifvdjOlCHFQccxYl0wgaMGA1Ud
++IwSBmzCBmIAUc7G41oqVaxLgdHzFV1WYlFuseF6haqRoMGYxCzAJBgNVBAYTAktH
++MQswCQYDVQQIDAJOQTEQMA4GA1UEBwwHQklTSEtFSzEVMBMGA1UECgwMT3BlblZQ
++Ti1URVNUMSEwHwYJKoZIhvcNAQkBFhJtZUBteWhvc3QubXlkb21haW6CFG9QuNNG
++bnI0WbwAM918rhLrJ0YGMA0GCSqGSIb3DQEBCwUAA4ICAQAqngJl9DzAN4jwIfn9
++Lnz0i7tnffdIDJj3oUZOM69od/RTAwn9TjLLDyzxFjc1ZapoeRapMgPXiRDvuv3h
++JixgfDtCYGhHz2GIAHfncXZJeDVSRaQxfivhCsjt4acoLyOjzs61mWtUTd/SZAq3
++xSUe1Peh/U/zEtMmXzuyk5PRi0tO3NAVY9F3NnU0djdZ/6CBAey2Qi+9hV3Q7/+Q
++YdaRsPXmlGZ+TCAGxC4Mm59/ifA+j+UGbIF1ogvFrETxMsxXkKAZR4wletXxYR8Z
++v0wx2kTBMJHotczkfiBVCrnc8171fNEL7nHG1jh+hXtsyxCFHmpQq8Ou+f+WT6N2
++1v3A+ceaYKiM5ZrFqXtjEe97uZsfY1GobSvW9+9RvagynpKqJAHJ42rIlC7SZrLH
++F+UGU5q9ihmPOlF6JRHl6Fn3G9+VmDXBpnQVa7Esl5v+dn5WIE3uB4q5i7ySqRmB
++KJFO0p9RmXLAEnZbyHRotZ1DU8GvObkogqAOu+8h2HHdAq/c30h7OSF9g3bq4scW
++u9IaHSL2S0cVVkEGTTkclj8lLYOPpKKG+g7pRZy/JkDmPp7VAJ/Odm/fy7KFuIPy
++7Yu2Wmi1xxurGXVg81vnXHAn2RzYJPAqqiqmmHfWNtkCNajTLBmIuAvTdlhyVJmU
++mu44m42OEEjNKFAxskvTaXuRtA==
+ -----END CERTIFICATE-----
+diff --git a/sample/sample-keys/client.key b/sample/sample-keys/client.key
+index 6d31489..4eb2768 100644
+--- a/sample/sample-keys/client.key
++++ b/sample/sample-keys/client.key
+@@ -1,28 +1,28 @@
+ -----BEGIN PRIVATE KEY-----
+-MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDsZY/pEsIaW+ZW
+-KgipgjotRHijADuwn+cnEECT7/HMPqCqBKKAGxOp5v6B1nCQqNjU3jDYNQDSvmLw
+-SNr8FY3Exm0LmfErgwAK0yojC+XN+TXfQ2EVcq2VmPZzIUFeoN1HJ6DVmtRBqBwd
+-VyBxF4/3KJ4+B87s1Q5CTx50R45HndIUKCcsFBD10Za1k3SE7/kE3o1Kb993q+rR
+-WNNE/loEAf8Gepf3/eNXSOHw30ATn2YjWuNVVD1UOe4A+RLx0t90LrrX8I3G3RhY
+-HJMiC3X6qNbgtS8tudT+uU+G4nVIFmD7P8m0MEIp+zuzK7lZgWpG80WDv/3VGv83
+-DG9b/WHxAgMBAAECggEBAIOdaCpUD02trOh8LqZxowJhBOl7z7/ex0uweMPk67LT
+-i5AdVHwOlzwZJ8oSIknoOBEMRBWcLQEojt1JMuL2/R95emzjIKshHHzqZKNulFvB
+-TIUpdnwChTKtH0mqUkLlPU3Ienty4IpNlpmfUKimfbkWHERdBJBHbtDsTABhdo3X
+-9pCF/yRKqJS2Fy/Mkl3gv1y/NB1OL4Jhl7vQbf+kmgfQN2qdOVe2BOKQ8NlPUDmE
+-/1XNIDaE3s6uvUaoFfwowzsCCwN2/8QrRMMKkjvV+lEVtNmQdYxj5Xj5IwS0vkK0
+-6icsngW87cpZxxc1zsRWcSTloy5ohub4FgKhlolmigECgYEA+cBlxzLvaMzMlBQY
+-kCac9KQMvVL+DIFHlZA5i5L/9pRVp4JJwj3GUoehFJoFhsxnKr8HZyLwBKlCmUVm
+-VxnshRWiAU18emUmeAtSGawlAS3QXhikVZDdd/L20YusLT+DXV81wlKR97/r9+17
+-klQOLkSdPm9wcMDOWMNHX8bUg8kCgYEA8k+hQv6+TR/+Beao2IIctFtw/EauaJiJ
+-wW5ql1cpCLPMAOQUvjs0Km3zqctfBF8mUjdkcyJ4uhL9FZtfywY22EtRIXOJ/8VR
+-we65mVo6RLR8YVM54sihanuFOnlyF9LIBWB+9pUfh1/Y7DSebh7W73uxhAxQhi3Y
+-QwfIQIFd8OkCgYBalH4VXhLYhpaYCiXSej6ot6rrK2N6c5Tb2MAWMA1nh+r84tMP
+-gMoh+pDgYPAqMI4mQbxUmqZEeoLuBe6VHpDav7rPECRaW781AJ4ZM4cEQ3Jz/inz
+-4qOAMn10CF081/Ez9ykPPlU0bsYNWHNd4eB2xWnmUBKOwk7UgJatVPaUiQKBgQCI
+-f18CVGpzG9CHFnaK8FCnMNOm6VIaTcNcGY0mD81nv5Dt943P054BQMsAHTY7SjZW
+-HioRyZtkhonXAB2oSqnekh7zzxgv4sG5k3ct8evdBCcE1FNJc2eqikZ0uDETRoOy
+-s7cRxNNr+QxDkyikM+80HOPU1PMPgwfOSrX90GJQ8QKBgEBKohGMV/sNa4t14Iau
+-qO8aagoqh/68K9GFXljsl3/iCSa964HIEREtW09Qz1w3dotEgp2w8bsDa+OwWrLy
+-0SY7T5jRViM3cDWRlUBLrGGiL0FiwsfqiRiji60y19erJgrgyGVIb1kIgIBRkgFM
+-2MMweASzTmZcri4PA/5C0HYb
++MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDdrrIKQObP4cGi
++odKDLDGY4huyhUBnAPqrv8+dFNHGt2ODql+cFKDSTQQ6SpLmkkukhkAmQr2Dt/xJ
++t1bSyudwhRaPizvaR56LakrI5qjermstUiIMnc9nu30eZgVTi3yurdGmUl89nmso
++GFfZoUItwLBN2krwKaoCNIYCqq9nCQbtRSGOjPh1Vsfq6E+IjhyLW2gtsWal5MY2
++4nCN/u8Q8FL4U5a/flFw8j+uWIc40aNr9jhRmxbOZzWObXZjTWubfXfaVW8gsWZP
++mi2kczpSIYY886ZaZ+V9EPU2ViF+AyK9mOkYtD+ztQ3t1e9Ulm+dRmxvDrpLGvfM
++1OUkutKlAgMBAAECggEANwi9ron6QzWaqtNdva7lCT1o/uLR4EB/+s99rVOT2K+C
++hxdu8QK2Aj+YgxgsbA15tfiWSGldPywX9/0KEv7IgkioFy7Lxx7sn1PeCQ4qck3+
++0ZuIVHWBHhGPuFI/lEQWyg7g81eTyWpg0+1nMeI02cLyggFlhUXyrOV5N4REU2GW
++C0KBQFyVQJPrFszomK8qsHOu/gaGC1vOwgIID3cQ3iLKXkoHNmHO4hgbeSy+SfDP
++Q5C0xxKQa2RUz0nLbByuGtLYOsJmbjUMWjFXyjmwBsPCcvRmFRdnxFvlnzwGEH4M
++ZKsw+49p1iJFyuCv7KJ/ILLJmoEuryjrSmdj3esIqQKBgQDwC24VBQLNmlug8rkG
++YWaRePsWRJylDlWIeHnfmGe27p7ytxOvGe6hnPu6nfg8nXHtruZCIhGya6qbuVmL
++vGrg94ia4MSpDVUgGiElXXQ/Pl7O9/lnSlIlxcBAgd8uggxIAzCeYI6c3r7AQcmY
++jARMwYNCxJjz5nLctMe2MCs4LwKBgQDsatDXb3xr6jmflCUZa8Kx8SOgBWEZTEGz
++KEoCQWnF2fHUCy4Bwm8Imnws3iX0198TyxkVD2rP8oGwFj2SAVtI2L8Y/g5A05TA
++knfmVECvGp/MN266ZdCA8G/MKbk727TxyJs+4AseAi5p6cBULqZHsJaZE74qlcEl
++5gFQu35ZawKBgBBgRz9J2zoZmLyvMm48ANpVzZNkVOdxxeYMigv2AsVZHCDk2oPs
++mfoOkqHVmxTPjPExKGZEmr54V+hNyc0dqpD0ci5WvTPnQ/JvtektqfuSjrdB9ZLV
++YCtRhV8hPQ+YMaxMA2oankAXdh35nv44NybhYMoSTXj+NMHX13QXbytjAoGAdVKw
++3yixWzB6dinjm1Dx5rJfVos024QPWqRUzfe+UPROYUdHBpKB3YgktXNs7KuwRbdV
++dDEZdabIGyV+WpWXwnflpbZ2Rk95k3NcUw5ep0cUJBkiNxhNt58aK/xMs1rd2dsO
++x84RVkwI0oCw9FXOKOeGZOL6TVHR70fMQU86bY8CgYEAqg/1AD9lXzbR57zaR/br
++AIn0WWU2mnU7Dc4uhmQd9+JExqrplKKHrUp8eQEOW8nij6MbPYlpgkMdatvDOJqP
++WrYtwZsKXGhnalvbS3ye20HqpjYpBR7co3Q9KMaaDNoQe9HtjbT80GXpQEbJN2Iu
++ADo3hPoX0yENIbKFccMuptM=
+ -----END PRIVATE KEY-----
+diff --git a/sample/sample-keys/client.p12 b/sample/sample-keys/client.p12
+index 8458c79..67335ac 100644
+--- a/sample/sample-keys/client.p12
++++ b/sample/sample-keys/client.p12
+@@ -1,21 +1,23 @@
+-0?±0?w *?H?÷
?h?d0?`0? *?H?÷
?0? 0?ý *?H?÷
0
+-*?H?÷
0?Ze8ÅÛ ??ÐMîÃn ?*GÇþu?zÈɹ??ýBXªeÙpÓ8Áø·¾ñc4Üç}?5\?½(?O¹¨W[û°2v vѳ@Wr¢ö¡Ï@&Óp&?'y? L¦äyÓc?#¸3VÑ ?d9!e+'?´?iâ0¿?½d??>tÝ?\oÝ\ê?p`ÿd??Í?çï"ÎH;Á7g:??Þ?úÏ?d?6(Qõè{ðm´û´à¾rBcñô£±îtxÁ%?É,?Ôr5?@ý?1?¶ü:V?"¬å<N¯ÅK5=>(ð0þ?ÝÈ¢£ñmXÔGAÀ$¢¬¾.±`?Ý