diff options
-rw-r--r-- | ssl.c | 75 | ||||
-rw-r--r-- | ssl.h | 25 | ||||
-rw-r--r-- | ssl_verify.c | 67 | ||||
-rw-r--r-- | ssl_verify.h | 46 |
4 files changed, 113 insertions, 100 deletions
@@ -554,32 +554,6 @@ setenv_untrusted (struct tls_session *session) setenv_link_socket_actual (session->opt->es, "untrusted", &session->untrusted_addr, SA_IP_PORT); } -static void -set_common_name (struct tls_session *session, const char *common_name) -{ - if (session->common_name) - { - free (session->common_name); - session->common_name = NULL; -#ifdef ENABLE_PF - session->common_name_hashval = 0; -#endif - } - if (common_name) - { - session->common_name = string_alloc (common_name, NULL); -#ifdef ENABLE_PF - { - const uint32_t len = (uint32_t) strlen (common_name); - if (len) - session->common_name_hashval = hash_func ((const uint8_t*)common_name, len+1, 0); - else - session->common_name_hashval = 0; - } -#endif - } -} - #if OPENSSL_VERSION_NUMBER >= 0x00907000L bool verify_cert_eku (X509 *x509, const char * const expected_oid) { @@ -1113,35 +1087,6 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx) /** @} name Function for authenticating a new connection from a remote OpenVPN peer */ -void -tls_set_common_name (struct tls_multi *multi, const char *common_name) -{ - if (multi) - set_common_name (&multi->session[TM_ACTIVE], common_name); -} - -const char * -tls_common_name (const struct tls_multi *multi, const bool null) -{ - const char *ret = NULL; - if (multi) - ret = multi->session[TM_ACTIVE].common_name; - if (ret && strlen (ret)) - return ret; - else if (null) - return NULL; - else - return "UNDEF"; -} - -void -tls_lock_common_name (struct tls_multi *multi) -{ - const char *cn = multi->session[TM_ACTIVE].common_name; - if (cn && !multi->locked_cn) - multi->locked_cn = string_alloc (cn, NULL); -} - static bool tls_lock_username (struct tls_multi *multi, const char *username) { @@ -3294,26 +3239,6 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi ks->authenticated = true; } - /* While it shouldn't really happen, don't allow the common name to be NULL */ - if (!session->common_name) - set_common_name (session, ""); - - /* Don't allow the CN to change once it's been locked */ - if (ks->authenticated && multi->locked_cn) - { - const char *cn = session->common_name; - if (cn && strcmp (cn, multi->locked_cn)) - { - msg (D_TLS_ERRORS, "TLS Auth Error: TLS object CN attempted to change from '%s' to '%s' -- tunnel disabled", - multi->locked_cn, - cn); - - /* change the common name back to its original value and disable the tunnel */ - set_common_name (session, multi->locked_cn); - tls_deauthenticate (multi); - } - } - /* Perform final authentication checks */ if (ks->authenticated) { @@ -521,11 +521,6 @@ bool tls_send_payload (struct tls_multi *multi, bool tls_rec_payload (struct tls_multi *multi, struct buffer *buf); -const char *tls_common_name (const struct tls_multi* multi, const bool null); -const char *tls_username(const struct tls_multi *multi, const bool null); -void tls_set_common_name (struct tls_multi *multi, const char *common_name); -void tls_lock_common_name (struct tls_multi *multi); - #define TLS_AUTHENTICATION_SUCCEEDED 0 #define TLS_AUTHENTICATION_FAILED 1 #define TLS_AUTHENTICATION_DEFERRED 2 @@ -592,26 +587,6 @@ tls_client_reason (struct tls_multi *multi) #endif } -#ifdef ENABLE_PF - -static inline bool -tls_common_name_hash (const struct tls_multi *multi, const char **cn, uint32_t *cn_hash) -{ - if (multi) - { - const struct tls_session *s = &multi->session[TM_ACTIVE]; - if (s->common_name && s->common_name[0] != '\0') - { - *cn = s->common_name; - *cn_hash = s->common_name_hashval; - return true; - } - } - return false; -} - -#endif - /* * protocol_dump() flags */ diff --git a/ssl_verify.c b/ssl_verify.c index 37efafb..b8f66f7 100644 --- a/ssl_verify.c +++ b/ssl_verify.c @@ -49,6 +49,54 @@ tls_deauthenticate (struct tls_multi *multi) } } +void +set_common_name (struct tls_session *session, const char *common_name) +{ + if (session->common_name) + { + free (session->common_name); + session->common_name = NULL; +#ifdef ENABLE_PF + session->common_name_hashval = 0; +#endif + } + if (common_name) + { + session->common_name = string_alloc (common_name, NULL); +#ifdef ENABLE_PF + { + const uint32_t len = (uint32_t) strlen (common_name); + if (len) + session->common_name_hashval = hash_func ((const uint8_t*)common_name, len+1, 0); + else + session->common_name_hashval = 0; + } +#endif + } +} + +const char * +tls_common_name (const struct tls_multi *multi, const bool null) +{ + const char *ret = NULL; + if (multi) + ret = multi->session[TM_ACTIVE].common_name; + if (ret && strlen (ret)) + return ret; + else if (null) + return NULL; + else + return "UNDEF"; +} + +void +tls_lock_common_name (struct tls_multi *multi) +{ + const char *cn = multi->session[TM_ACTIVE].common_name; + if (cn && !multi->locked_cn) + multi->locked_cn = string_alloc (cn, NULL); +} + void cert_hash_remember (struct tls_session *session, const int error_depth, const unsigned char *sha1_hash) @@ -156,6 +204,25 @@ tls_lock_cert_hash_set (struct tls_multi *multi) void verify_final_auth_checks(struct tls_multi *multi, struct tls_session *session) { + /* While it shouldn't really happen, don't allow the common name to be NULL */ + if (!session->common_name) + set_common_name (session, ""); + + /* Don't allow the CN to change once it's been locked */ + if (multi->locked_cn) + { + const char *cn = session->common_name; + if (cn && strcmp (cn, multi->locked_cn)) + { + msg (D_TLS_ERRORS, "TLS Auth Error: TLS object CN attempted to change from '%s' to '%s' -- tunnel disabled", + multi->locked_cn, + cn); + + /* change the common name back to its original value and disable the tunnel */ + set_common_name (session, multi->locked_cn); + tls_deauthenticate (multi); + } + } /* Don't allow the cert hashes to change once they have been locked */ if (multi->locked_cert_hash_set) diff --git a/ssl_verify.h b/ssl_verify.h index 4440acd..b76a16a 100644 --- a/ssl_verify.h +++ b/ssl_verify.h @@ -73,6 +73,52 @@ void cert_hash_free (struct cert_hash_set *chs); void tls_lock_cert_hash_set (struct tls_multi *multi); /** + * Locks the common name field for the given tunnel + * + * @param multi The tunnel to lock + */ +void tls_lock_common_name (struct tls_multi *multi); + +/** + * Returns the common name field for the given tunnel + * + * @param multi The tunnel to return the common name for + * @param null Whether null may be returned. If not, "UNDEF" will be returned. + */ +const char *tls_common_name (const struct tls_multi* multi, const bool null); + +void tls_set_common_name (struct tls_multi *multi, const char *common_name); + +#ifdef ENABLE_PF + +/** + * Retrieve the given tunnel's common name and its hash value. + * + * @param multi The tunnel to use + * @param cn Common name's string + * @param cn_hash Common name's hash value + * + * @return true if the common name was set, false otherwise. + */ +static inline bool +tls_common_name_hash (const struct tls_multi *multi, const char **cn, uint32_t *cn_hash) +{ + if (multi) + { + const struct tls_session *s = &multi->session[TM_ACTIVE]; + if (s->common_name && s->common_name[0] != '\0') + { + *cn = s->common_name; + *cn_hash = s->common_name_hashval; + return true; + } + } + return false; +} + +#endif + +/** * Perform final authentication checks, including locking of the cn, the allowed * certificate hashes, and whether a client config entry exists in the * client config directory. |