auth-gen-token: Hardening memory cleanup on auth-token failuers
PATCH 1/1 auth-gen-token: Hardening memory cleanup on auth-token failuers
Further improve the memory management when a clients --auth-token fails the server side token authentication enabled via --auth-gen-token.
--- src/openvpn/ssl_verify.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-)
src/openvpn/ssl_verify.c +18 -4
@@ -1108,6 +1108,21 @@ verify_user_pass_management (struct tls_session *session, const struct user_pass }#endif +/** +* Wipes the authentication token out of the memory, frees and cleans up related buffers and flags +* +* @param multi Pointer to a multi object holding the auth_token variables +*/ +static void +wipe_auth_token (struct tls_multi *multi) +{ +secure_memzero (multi->auth_token,AUTH_TOKEN_SIZE ); +free (multi->auth_token); + multi->auth_token =NULL ; + multi->auth_token_sent = false; +} + +/* * Main username/password verification entry point */
@@ -1157,6 +1172,7 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,/* Ensure that the username has not changed */ if (!tls_lock_username (multi, up->username)) { +wipe_auth_token (multi); ks->authenticated = false; goto done; }
@@ -1168,6 +1184,7 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi, && (multi->auth_token_tstamp + session->opt->auth_token_lifetime) < now) {msg (D_HANDSHAKE ,"Auth-token for client expired\n" ); +wipe_auth_token (multi); ks->authenticated = false; goto done; }
@@ -1176,10 +1193,7 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,if (memcmp_constant_time (multi->auth_token, up->password,strlen (multi->auth_token)) !=0 ) { -secure_memzero (multi->auth_token,AUTH_TOKEN_SIZE ); -free (multi->auth_token); - multi->auth_token =NULL ; - multi->auth_token_sent = false; +wipe_auth_token (multi); ks->authenticated = false;tls_deauthenticate (multi);
Signature · 1 line
1.8.3.1
Hi,
Quoted 52 lines · David Sommerseth
Further improve the memory management when a clients --auth-token fails the server side token authentication enabled via --auth-gen-token.
Signed-off-by David Sommerseth <[email protected]...>--- src/openvpn/ssl_verify.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-)src/openvpn/ssl_verify.c +17
-0@@ -1108,6 +1108,21 @@ verify_user_pass_management (struct tls_session *session, const struct user_pass }#endif +/** +* Wipes the authentication token out of the memory, frees and cleans up related buffers and flags +* +* @param multi Pointer to a multi object holding the auth_token variables +*/ +static void +wipe_auth_token (struct tls_multi *multi) +{ +secure_memzero (multi->auth_token,AUTH_TOKEN_SIZE ); +free (multi->auth_token); + multi->auth_token =NULL ; + multi->auth_token_sent = false; +} + +/* * Main username/password verification entry point */ @@ -1157,6 +1172,7 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,/* Ensure that the username has not changed */ if (!tls_lock_username (multi, up->username)) { +wipe_auth_token (multi); ks->authenticated = false; goto done; }@@ -1168,6 +1184,7 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi, && (multi->auth_token_tstamp + session->opt->auth_token_lifetime) < now) {msg (D_HANDSHAKE ,"Auth-token for client expired\n" ); +wipe_auth_token (multi); ks->authenticated = false; goto done; }@@ -1176,10 +1193,7 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi, if (memcmp_constant_time(multi->auth_token, up->password,
src/openvpn/ssl_verify.c verify_user_pass(struct user_pass *up, struct tls_multi *multi, · line 1199
Quoted 10 lines
src/openvpn/ssl_verify.c +1
-4strlen(multi->auth_token)) != 0) { -secure_memzero (multi->auth_token,AUTH_TOKEN_SIZE ); -free (multi->auth_token); - multi->auth_token =NULL ; - multi->auth_token_sent = false; +wipe_auth_token (multi); ks->authenticated = false;tls_deauthenticate (multi);
Looks good, but I think there's one more occurance you should incorporate in the patch:
if (openvpn_base64_encode(tok, AUTH_TOKEN_SIZE,
&multi->auth_token) < AUTH_TOKEN_SIZE)
{
msg(D_TLS_ERRORS, "BASE64 encoding of token failed. "
"No auth-token will be activated now");
if (multi->auth_token)
{
secure_memzero(multi->auth_token, AUTH_TOKEN_SIZE);
free(multi->auth_token);
multi->auth_token = NULL;
}-Steffan
Hi,
Quoted 5 lines · Steffan Karger
Looks good, but I think there's one more occurance you should incorporate in the patch:
if (openvpn_base64_encode(tok,
AUTH_TOKEN_SIZE,&multi->auth_token) < AUTH_TOKEN_SIZE)
Under which conditions can this ever fail? In other words: if this fails, should we consider it a major programming error and ASSERT()?
gert
Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany [email protected]...
fax: +49-89-35655025 [email protected]...Quoted 11 lines · Gert Doering
Hi,
Quoted 5 lines · Steffan Karger
Looks good, but I think there's one more occurance you should incorporate in the patch:
if (openvpn_base64_encode(tok,
AUTH_TOKEN_SIZE,&multi->auth_token) < AUTH_TOKEN_SIZE)Under which conditions can this ever fail? In other words: if this fails, should we consider it a major programming error and
ASSERT()?
It can only fail if there's a malloc() failure in openvpn_base64_encode(). But I agree, ASSERT() is probably more reasonable here.
I'll send a v2 patch with assert here instead.
Side track .... the malloc() size calculation in base64.c:66 is, well, interesting:
p = s = (char *) malloc(size * 4 / 3 + 4);
Signature · 4 lines
kind regards, David Sommerseth OpenVPN Technologies, Inc
PATCH v2 1/1 auth-gen-token: Hardening memory cleanup on auth-token failuers
In reply to David SommersethFurther improve the memory management when a clients --auth-token fails the server side token authentication enabled via --auth-gen-token.
v2 - Add ASSERT() if base64 encoding of token fails
--- src/openvpn/ssl_verify.c | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-)
src/openvpn/ssl_verify.c +23 -22
@@ -1108,6 +1108,21 @@ verify_user_pass_management (struct tls_session *session, const struct user_pass }#endif +/** +* Wipes the authentication token out of the memory, frees and cleans up related buffers and flags +* +* @param multi Pointer to a multi object holding the auth_token variables +*/ +static void +wipe_auth_token (struct tls_multi *multi) +{ +secure_memzero (multi->auth_token,AUTH_TOKEN_SIZE ); +free (multi->auth_token); + multi->auth_token =NULL ; + multi->auth_token_sent = false; +} + +/* * Main username/password verification entry point */
@@ -1157,6 +1172,7 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,/* Ensure that the username has not changed */ if (!tls_lock_username (multi, up->username)) { +wipe_auth_token (multi); ks->authenticated = false; goto done; }
@@ -1168,6 +1184,7 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi, && (multi->auth_token_tstamp + session->opt->auth_token_lifetime) < now) {msg (D_HANDSHAKE ,"Auth-token for client expired\n" ); +wipe_auth_token (multi); ks->authenticated = false; goto done; }
@@ -1176,10 +1193,7 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,if (memcmp_constant_time (multi->auth_token, up->password,strlen (multi->auth_token)) !=0 ) { -secure_memzero (multi->auth_token,AUTH_TOKEN_SIZE ); -free (multi->auth_token); - multi->auth_token =NULL ; - multi->auth_token_sent = false; +wipe_auth_token (multi); ks->authenticated = false;tls_deauthenticate (multi);
@@ -1255,24 +1269,11 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,/* The token should be longer than the input when * being base64 encoded */ -if (openvpn_base64_encode (tok,AUTH_TOKEN_SIZE , - &multi->auth_token) <AUTH_TOKEN_SIZE ) - { -msg (D_TLS_ERRORS ,"BASE64 encoding of token failed. " -"No auth-token will be activated now" ); -if (multi->auth_token) - { -secure_memzero (multi->auth_token,AUTH_TOKEN_SIZE ); -free (multi->auth_token); - multi->auth_token =NULL ; - } - } -else - { - multi->auth_token_tstamp = now; -dmsg (D_SHOW_KEYS ,"Generated token for client: %s" , - multi->auth_token); - } +ASSERT (openvpn_base64_encode (tok,AUTH_TOKEN_SIZE , + &multi->auth_token) <AUTH_TOKEN_SIZE ); + multi->auth_token_tstamp = now; +dmsg (D_SHOW_KEYS ,"Generated token for client: %s" , + multi->auth_token); }if ((session->opt->ssl_flags &SSLF_USERNAME_AS_COMMON_NAME ))
Signature · 1 line
1.8.3.1
Hi,
Quoted 4 lines · David Sommerseth
Further improve the memory management when a clients --auth-token fails the server side token authentication enabled via --auth-gen-token.
v2 - Add
ASSERT()if base64 encoding of token fails
This will need rebasing because of the reformatting.
src/openvpn/ssl_verify.c verify_user_pass(struct user_pass *up, struct tls_multi *multi, · line 1273
Quoted 12 lines
src/openvpn/ssl_verify.c +2
-5@@ -1255,24 +1269,11 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,/* The token should be longer than the input when * being base64 encoded */ -if (openvpn_base64_encode (tok,AUTH_TOKEN_SIZE , - &multi->auth_token) <AUTH_TOKEN_SIZE ) - { -msg (D_TLS_ERRORS ,"BASE64 encoding of token failed. " -"No auth-token will be activated now" ); +ASSERT (openvpn_base64_encode (tok,AUTH_TOKEN_SIZE , + &multi->auth_token) <AUTH_TOKEN_SIZE );
Uhm, I think the < should be a > now?
-Steffan
[lets try unencrypted this time.]
Quoted 10 lines · Steffan Karger
Hi,
Quoted 4 lines · David Sommerseth
Further improve the memory management when a clients --auth-token fails the server side token authentication enabled via --auth-gen-token.
v2 - Add
ASSERT()if base64 encoding of token failsThis will need rebasing because of the reformatting.
Quoted 15 lines
src/openvpn/ssl_verify.c verify_user_pass(struct user_pass *up, struct tls_multi *multi, · line 1273
Quoted 12 lines
src/openvpn/ssl_verify.c +2
-5@@ -1255,24 +1269,11 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,/* The token should be longer than the input when * being base64 encoded */ -if (openvpn_base64_encode (tok,AUTH_TOKEN_SIZE , - &multi->auth_token) <AUTH_TOKEN_SIZE ) - { -msg (D_TLS_ERRORS ,"BASE64 encoding of token failed. " -"No auth-token will be activated now" ); +ASSERT (openvpn_base64_encode (tok,AUTH_TOKEN_SIZE , + &multi->auth_token) <AUTH_TOKEN_SIZE );Uhm, I think the < should be a > now?
*facepalm*
I was completely sure I had tested it. I really did run tests. I just ran the server and client on the opposite hosts. So the VM which had not been updated which should run the client ran the server mode instead ... thus no issues :/
I'll send a v3 patch now.
Signature · 4 lines
kind regards, David Sommerseth OpenVPN Technologies, Inc
PATCH v3 1/1 auth-gen-token: Hardening memory cleanup on auth-token failuers
In reply to David SommersethFurther improve the memory management when a clients --auth-token fails the server side token authentication enabled via --auth-gen-token.
v2 - Add ASSERT() if base64 encoding of token fails v3 - Use proper boolean logic in ASSERT()
--- src/openvpn/ssl_verify.c | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-)
src/openvpn/ssl_verify.c +23 -22
@@ -1108,6 +1108,21 @@ verify_user_pass_management (struct tls_session *session, const struct user_pass }#endif +/** +* Wipes the authentication token out of the memory, frees and cleans up related buffers and flags +* +* @param multi Pointer to a multi object holding the auth_token variables +*/ +static void +wipe_auth_token (struct tls_multi *multi) +{ +secure_memzero (multi->auth_token,AUTH_TOKEN_SIZE ); +free (multi->auth_token); + multi->auth_token =NULL ; + multi->auth_token_sent = false; +} + +/* * Main username/password verification entry point */
@@ -1157,6 +1172,7 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,/* Ensure that the username has not changed */ if (!tls_lock_username (multi, up->username)) { +wipe_auth_token (multi); ks->authenticated = false; goto done; }
@@ -1168,6 +1184,7 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi, && (multi->auth_token_tstamp + session->opt->auth_token_lifetime) < now) {msg (D_HANDSHAKE ,"Auth-token for client expired\n" ); +wipe_auth_token (multi); ks->authenticated = false; goto done; }
@@ -1176,10 +1193,7 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,if (memcmp_constant_time (multi->auth_token, up->password,strlen (multi->auth_token)) !=0 ) { -secure_memzero (multi->auth_token,AUTH_TOKEN_SIZE ); -free (multi->auth_token); - multi->auth_token =NULL ; - multi->auth_token_sent = false; +wipe_auth_token (multi); ks->authenticated = false;tls_deauthenticate (multi);
@@ -1255,24 +1269,11 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,/* The token should be longer than the input when * being base64 encoded */ -if (openvpn_base64_encode (tok,AUTH_TOKEN_SIZE , - &multi->auth_token) <AUTH_TOKEN_SIZE ) - { -msg (D_TLS_ERRORS ,"BASE64 encoding of token failed. " -"No auth-token will be activated now" ); -if (multi->auth_token) - { -secure_memzero (multi->auth_token,AUTH_TOKEN_SIZE ); -free (multi->auth_token); - multi->auth_token =NULL ; - } - } -else - { - multi->auth_token_tstamp = now; -dmsg (D_SHOW_KEYS ,"Generated token for client: %s" , - multi->auth_token); - } +ASSERT (openvpn_base64_encode (tok,AUTH_TOKEN_SIZE , + &multi->auth_token) >AUTH_TOKEN_SIZE ); + multi->auth_token_tstamp = now; +dmsg (D_SHOW_KEYS ,"Generated token for client: %s" , + multi->auth_token); }if ((session->opt->ssl_flags &SSLF_USERNAME_AS_COMMON_NAME ))
Signature · 1 line
1.8.3.1
PATCH v4 1/1 auth-gen-token: Hardening memory cleanup on auth-token failuers
In reply to David SommersethFurther improve the memory management when a clients --auth-token fails the server side token authentication enabled via --auth-gen-token.
v2 - Add ASSERT() if base64 encoding of token fails v3 - Use proper boolean logic in ASSERT() v4 - Rebase against The Great Reformatting
--- src/openvpn/ssl_verify.c | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-)
src/openvpn/ssl_verify.c +24 -22
@@ -1213,6 +1213,21 @@ verify_user_pass_management(struct tls_session *session, const struct user_pass }#endif /* ifdef MANAGEMENT_DEF_AUTH */ +/** +* Wipes the authentication token out of the memory, frees and cleans up related buffers and flags +* +* @param multi Pointer to a multi object holding the auth_token variables +*/ +static void +wipe_auth_token (struct tls_multi *multi) +{ +secure_memzero (multi->auth_token,AUTH_TOKEN_SIZE ); +free (multi->auth_token); + multi->auth_token =NULL ; + multi->auth_token_sent = false; +} + +/* * Main username/password verification entry point */
@@ -1264,6 +1279,7 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,/* Ensure that the username has not changed */ if (!tls_lock_username (multi, up->username)) { +wipe_auth_token (multi); ks->authenticated = false; goto done; }
@@ -1275,6 +1291,7 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi, && (multi->auth_token_tstamp + session->opt->auth_token_lifetime) < now) {msg (D_HANDSHAKE ,"Auth-token for client expired\n" ); +wipe_auth_token (multi); ks->authenticated = false; goto done; }
@@ -1283,10 +1300,7 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,if (memcmp_constant_time (multi->auth_token, up->password,strlen (multi->auth_token)) !=0 ) { -secure_memzero (multi->auth_token,AUTH_TOKEN_SIZE ); -free (multi->auth_token); - multi->auth_token =NULL ; - multi->auth_token_sent = false; +wipe_auth_token (multi); ks->authenticated = false;tls_deauthenticate (multi);
@@ -1374,30 +1388,18 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,/* The token should be longer than the input when * being base64 encoded */ -if (openvpn_base64_encode (tok,AUTH_TOKEN_SIZE , - &multi->auth_token) <AUTH_TOKEN_SIZE ) - { -msg (D_TLS_ERRORS ,"BASE64 encoding of token failed. " -"No auth-token will be activated now" ); -if (multi->auth_token) - { -secure_memzero (multi->auth_token,AUTH_TOKEN_SIZE ); -free (multi->auth_token); - multi->auth_token =NULL ; - } - } -else - { - multi->auth_token_tstamp = now; -dmsg (D_SHOW_KEYS ,"Generated token for client: %s" , - multi->auth_token); - } +ASSERT (openvpn_base64_encode (tok,AUTH_TOKEN_SIZE , + &multi->auth_token) >AUTH_TOKEN_SIZE ); + multi->auth_token_tstamp = now; +dmsg (D_SHOW_KEYS ,"Generated token for client: %s" , + multi->auth_token); }if ((session->opt->ssl_flags &SSLF_USERNAME_AS_COMMON_NAME )) {set_common_name (session, up->username); } +#ifdef ENABLE_DEF_AUTH msg(D_HANDSHAKE, "TLS: Username/Password authentication %s for username '%s' %s", ks->auth_deferred ? "deferred" : "succeeded",
Signature · 1 line
1.8.3.1
Quoted 94 lines · David Sommerseth
Further improve the memory management when a clients --auth-token fails the server side token authentication enabled via --auth-gen-token.
v2 - Add
ASSERT()if base64 encoding of token fails v3 - Use proper boolean logic inASSERT()v4 - Rebase against The Great ReformattingSigned-off-by David Sommerseth <[email protected]...>--- src/openvpn/ssl_verify.c | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-)src/openvpn/ssl_verify.c +23
-22@@ -1213,6 +1213,21 @@ verify_user_pass_management(struct tls_session *session, const struct user_pass }#endif /* ifdef MANAGEMENT_DEF_AUTH */ +/** +* Wipes the authentication token out of the memory, frees and cleans up related buffers and flags +* +* @param multi Pointer to a multi object holding the auth_token variables +*/ +static void +wipe_auth_token (struct tls_multi *multi) +{ +secure_memzero (multi->auth_token,AUTH_TOKEN_SIZE ); +free (multi->auth_token); + multi->auth_token =NULL ; + multi->auth_token_sent = false; +} + +/* * Main username/password verification entry point */ @@ -1264,6 +1279,7 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,/* Ensure that the username has not changed */ if (!tls_lock_username (multi, up->username)) { +wipe_auth_token (multi); ks->authenticated = false; goto done; }@@ -1275,6 +1291,7 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi, && (multi->auth_token_tstamp + session->opt->auth_token_lifetime) < now) {msg (D_HANDSHAKE ,"Auth-token for client expired\n" ); +wipe_auth_token (multi); ks->authenticated = false; goto done; }@@ -1283,10 +1300,7 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,if (memcmp_constant_time (multi->auth_token, up->password,strlen (multi->auth_token)) !=0 ) { -secure_memzero (multi->auth_token,AUTH_TOKEN_SIZE ); -free (multi->auth_token); - multi->auth_token =NULL ; - multi->auth_token_sent = false; +wipe_auth_token (multi); ks->authenticated = false;tls_deauthenticate (multi);@@ -1374,30 +1388,18 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,/* The token should be longer than the input when * being base64 encoded */ -if (openvpn_base64_encode (tok,AUTH_TOKEN_SIZE , - &multi->auth_token) <AUTH_TOKEN_SIZE ) - { -msg (D_TLS_ERRORS ,"BASE64 encoding of token failed. " -"No auth-token will be activated now" ); -if (multi->auth_token) - { -secure_memzero (multi->auth_token,AUTH_TOKEN_SIZE ); -free (multi->auth_token); - multi->auth_token =NULL ; - } - } -else - { - multi->auth_token_tstamp = now; -dmsg (D_SHOW_KEYS ,"Generated token for client: %s" , - multi->auth_token); - } +ASSERT (openvpn_base64_encode (tok,AUTH_TOKEN_SIZE , + &multi->auth_token) >AUTH_TOKEN_SIZE ); + multi->auth_token_tstamp = now; +dmsg (D_SHOW_KEYS ,"Generated token for client: %s" , + multi->auth_token);
src/openvpn/ssl_verify.c verify_user_pass(struct user_pass *up, struct tls_multi *multi, · line 1405
Quoted 10 lines
src/openvpn/ssl_verify.c +1
-0}if ((session->opt->ssl_flags &SSLF_USERNAME_AS_COMMON_NAME )) {set_common_name (session, up->username); } +#ifdef ENABLE_DEF_AUTH msg(D_HANDSHAKE, "TLS: Username/Password authentication %s for username '%s' %s", ks->auth_deferred ? "deferred" : "succeeded",
Code looks good now, and passes my tests. ACK.
-Steffan
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Your patch has been applied to the master branch
commit 5d4cabff18718981a66ab9066b49297e42cb22b4
Author: David Sommerseth Date: Fri Dec 16 11:25:07 2016 +0100
auth-gen-token: Hardening memory cleanup on auth-token failuers
Signed-off-by: David Sommerseth <[email protected]...>
Acked-by: Steffan Karger <[email protected]...>
Message-Id: <[email protected]...>
URL: http://www.mail-archive.com/search?l=mid&[email protected]...- --
kind regards,
David Sommerseth
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)
iQIcBAEBAgAGBQJYU8t9AAoJEIbPlEyWcf3yoR0P/ilDxQ9iHIbMLnOBS/nyraJs hivVeWBK+OLYTP6ysMist8Rok5Nky6+m6SPuagGD5QMaFMVrPvTrDoWqYJxKhMM+ cHZSr0xPTwujTRr/BCqEiVCpJdO1SKVPgWbwPnXE7Jh1a35MnPC7c/IoEgFqY8j4 DfG4tCL1AoS0b9g9RozVkTr0RYLJaTIos6zHV57wQfJOezy1njBrK2dPC8bDmHic h7JVYPma7LgzOGsq7Iuo2Hc3Gp5gAbckMWkAF3pbPbIS2gYMiXdSK2Dgur/1U90S BvbwQ5BAb8ynzgVnKXFaTsjHLVsnGwKU1vlB9qi5yfdyNjpayuwAU9YrtSGeVCvP xw07tI9Jrsbu3ssFC/8l0VgmPRNmPADhsK+JU0rAmA/8ZLsqirYI/z+bbTvxMm8+ 0QFsV7bU1BK8TwhzVY+1HCtdNkpGrARAguK+2zVY3Q5ZLTyRjHNiVHeL2GXW7YQR ML7XXzw06jAfbR277U/7kzhqiYMoh2uV80+BboO7KKeaQP3QocCaQsxdU7ziKWUm yO7rbHHwFOneFFK4MvDHYfY0w/sdYrtepDvi/g617I/0u3xD+/1HPQ4PgOJ0dUNT DAULMMIwSOjU9MjEIBZaujHuLFRS6JXEtHlL5R1fdZvaP/tKXVNu5ix5jF7h2qmx VA7qLW0X32b+5ZTt9q7N
=GgJj
-----END PGP SIGNATURE-----