diff options
Diffstat (limited to 'src/openvpn/ssl_verify.c')
-rw-r--r-- | src/openvpn/ssl_verify.c | 104 |
1 files changed, 78 insertions, 26 deletions
diff --git a/src/openvpn/ssl_verify.c b/src/openvpn/ssl_verify.c index 334eb29..9cd36d7 100644 --- a/src/openvpn/ssl_verify.c +++ b/src/openvpn/ssl_verify.c @@ -17,10 +17,9 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** @@ -80,6 +79,28 @@ setenv_untrusted(struct tls_session *session) setenv_link_socket_actual(session->opt->es, "untrusted", &session->untrusted_addr, SA_IP_PORT); } + +/** + * 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) +{ + if(multi) + { + if (multi->auth_token) + { + secure_memzero(multi->auth_token, AUTH_TOKEN_SIZE); + free(multi->auth_token); + } + multi->auth_token = NULL; + multi->auth_token_sent = false; + } +} + + /* * Remove authenticated state from all sessions in the given tunnel */ @@ -88,10 +109,14 @@ tls_deauthenticate(struct tls_multi *multi) { if (multi) { - int i, j; - for (i = 0; i < TM_SIZE; ++i) - for (j = 0; j < KS_SIZE; ++j) + wipe_auth_token(multi); + for (int i = 0; i < TM_SIZE; ++i) + { + for (int j = 0; j < KS_SIZE; ++j) + { multi->session[i].key[j].authenticated = false; + } + } } } @@ -248,7 +273,9 @@ cert_hash_free(struct cert_hash_set *chs) { int i; for (i = 0; i < MAX_CERT_DEPTH; ++i) + { free(chs->ch[i]); + } free(chs); } } @@ -690,8 +717,31 @@ verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_dep /* verify level 1 cert, i.e. the CA that signed our leaf cert */ if (cert_depth == 1 && opt->verify_hash) { - struct buffer sha1_hash = x509_get_sha1_fingerprint(cert, &gc); - if (memcmp(BPTR(&sha1_hash), opt->verify_hash, BLEN(&sha1_hash))) + struct buffer ca_hash = {0}; + + switch (opt->verify_hash_algo) + { + case MD_SHA1: + ca_hash = x509_get_sha1_fingerprint(cert, &gc); + break; + + case MD_SHA256: + ca_hash = x509_get_sha256_fingerprint(cert, &gc); + break; + + default: + /* This should normally not happen at all; the algorithm used + * is parsed by add_option() [options.c] and set to a predefined + * value in an enumerated type. So if this unlikely scenario + * happens, consider this a failure + */ + msg(M_WARN, "Unexpected invalid algorithm used with " + "--verify-hash (%i)", opt->verify_hash_algo); + ret = FAILURE; + goto cleanup; + } + + if (memcmp(BPTR(&ca_hash), opt->verify_hash, BLEN(&ca_hash))) { msg(D_TLS_ERRORS, "TLS Error: level-1 certificate hash verification failed"); goto cleanup; @@ -1213,21 +1263,6 @@ 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 */ @@ -1279,7 +1314,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); + /* auth-token cleared in tls_lock_username() on failure */ ks->authenticated = false; goto done; } @@ -1300,7 +1335,6 @@ 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) { - wipe_auth_token(multi); ks->authenticated = false; tls_deauthenticate(multi); @@ -1472,6 +1506,7 @@ verify_final_auth_checks(struct tls_multi *multi, struct tls_session *session) if (!cn || !strcmp(cn, CCD_DEFAULT) || !test_file(path)) { ks->authenticated = false; + wipe_auth_token(multi); msg(D_TLS_ERRORS, "TLS Auth Error: --client-config-dir authentication failed for common name '%s' file='%s'", session->common_name, path ? path : "UNDEF"); @@ -1480,4 +1515,21 @@ verify_final_auth_checks(struct tls_multi *multi, struct tls_session *session) gc_free(&gc); } } + +void +tls_x509_clear_env(struct env_set *es) +{ + struct env_item *item = es->list; + while (item) + { + struct env_item *next = item->next; + if (item->string + && 0 == strncmp("X509_", item->string, strlen("X509_"))) + { + env_set_del(es, item->string); + } + item = next; + } +} + #endif /* ENABLE_CRYPTO */ |