summaryrefslogtreecommitdiff
path: root/src/openvpn/ssl_verify.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvpn/ssl_verify.c')
-rw-r--r--src/openvpn/ssl_verify.c104
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 */