src/openvpn/ssl_verify.h
9a160b79
 /*
  *  OpenVPN -- An application to securely tunnel IP networks
  *             over a single TCP/UDP port, with support for SSL/TLS-based
  *             session authentication and key exchange,
  *             packet encryption, packet authentication, and
  *             packet compression.
  *
49979459
  *  Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
  *  Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com>
9a160b79
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2
  *  as published by the Free Software Foundation.
  *
  *  This program is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
caa54ac3
  *  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.
9a160b79
  */
 
 /**
  * @file Control Channel Verification Module
  */
 
 #ifndef SSL_VERIFY_H_
 #define SSL_VERIFY_H_
 
 #include "syshead.h"
 #include "misc.h"
 #include "ssl_common.h"
 
 /* Include OpenSSL-specific code */
9b33b5a4
 #ifdef ENABLE_CRYPTO_OPENSSL
9a160b79
 #include "ssl_verify_openssl.h"
 #endif
86d8cd68
 #ifdef ENABLE_CRYPTO_MBEDTLS
74586c65
 #include "ssl_verify_mbedtls.h"
53f97e1e
 #endif
9a160b79
 
fe100528
 #include "ssl_verify_backend.h"
 
82f925b6
 /*
  * Keep track of certificate hashes at various depths
  */
 
 /** Maximum certificate depth we will allow */
 #define MAX_CERT_DEPTH 16
 
 /** Structure containing the hash for a single certificate */
 struct cert_hash {
81d882d5
     unsigned char sha256_hash[256/8];
82f925b6
 };
 
 /** Structure containing the hashes for a full certificate chain */
 struct cert_hash_set {
81d882d5
     struct cert_hash *ch[MAX_CERT_DEPTH]; /**< Array of certificate hashes */
82f925b6
 };
 
9f0fc745
 #define VERIFY_X509_NONE                0
 #define VERIFY_X509_SUBJECT_DN          1
 #define VERIFY_X509_SUBJECT_RDN         2
 #define VERIFY_X509_SUBJECT_RDN_PREFIX  3
82f925b6
 
d0811e64
 #define TLS_AUTHENTICATION_SUCCEEDED  0
 #define TLS_AUTHENTICATION_FAILED     1
 #define TLS_AUTHENTICATION_DEFERRED   2
 #define TLS_AUTHENTICATION_UNDEFINED  3
 
 /*
  * Return current session authentication state.  Return
  * value is TLS_AUTHENTICATION_x.
  *
  * TODO: document this function
  */
81d882d5
 int tls_authentication_status(struct tls_multi *multi, const int latency);
d0811e64
 
 /** Check whether the \a ks \c key_state is ready to receive data channel
  *   packets.
  *   @ingroup data_crypto
  *
  *   If true, it is safe to assume that this session has been authenticated
  *   by TLS.
  *
  *   @note This macro only works if S_SENT_KEY + 1 == S_GOT_KEY. */
 #define DECRYPT_KEY_ENABLED(multi, ks) ((ks)->state >= (S_GOT_KEY - (multi)->opt.server))
 
 /**
  * Remove the given key state's auth control file, if it exists.
  *
81d882d5
  * @param ks    The key state the remove the file for
d0811e64
  */
81d882d5
 void key_state_rm_auth_control_file(struct key_state *ks);
d0811e64
 
82f925b6
 /**
  * Frees the given set of certificate hashes.
  *
81d882d5
  * @param chs   The certificate hash set to free.
82f925b6
  */
81d882d5
 void cert_hash_free(struct cert_hash_set *chs);
82f925b6
 
 /**
  * Locks the certificate hash set used in the given tunnel
  *
81d882d5
  * @param multi The tunnel to lock
82f925b6
  */
81d882d5
 void tls_lock_cert_hash_set(struct tls_multi *multi);
82f925b6
 
88aaf1ae
 /**
530af3ef
  * Locks the common name field for the given tunnel
  *
81d882d5
  * @param multi The tunnel to lock
530af3ef
  */
81d882d5
 void tls_lock_common_name(struct tls_multi *multi);
530af3ef
 
 /**
  * Returns the common name field for the given tunnel
  *
81d882d5
  * @param multi The tunnel to return the common name for
  * @param null  Whether null may be returned. If not, "UNDEF" will be returned.
530af3ef
  */
81d882d5
 const char *tls_common_name(const struct tls_multi *multi, const bool null);
530af3ef
 
d0811e64
 /**
  * Returns the username field for the given tunnel
  *
81d882d5
  * @param multi The tunnel to return the username for
  * @param null  Whether null may be returned. If not, "UNDEF" will be returned.
d0811e64
  */
81d882d5
 const char *tls_username(const struct tls_multi *multi, const bool null);
530af3ef
 
0c0c178a
 /**
  * Compares certificates hashes, returns true if hashes are equal.
  *
  * @param chs1 cert 1 hash set
  * @param chs2 cert 2 hash set
  */
81d882d5
 bool cert_hash_compare(const struct cert_hash_set *chs1, const struct cert_hash_set *chs2);
0c0c178a
 
530af3ef
 #ifdef ENABLE_PF
 
 /**
  * Retrieve the given tunnel's common name and its hash value.
  *
81d882d5
  * @param multi         The tunnel to use
  * @param cn            Common name's string
  * @param cn_hash       Common name's hash value
530af3ef
  *
  * @return true if the common name was set, false otherwise.
  */
 static inline bool
81d882d5
 tls_common_name_hash(const struct tls_multi *multi, const char **cn, uint32_t *cn_hash)
530af3ef
 {
81d882d5
     if (multi)
530af3ef
     {
81d882d5
         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;
         }
530af3ef
     }
81d882d5
     return false;
530af3ef
 }
 
 #endif
 
 /**
d0811e64
  * Verify the given username and password, using either an external script, a
  * plugin, or the management interface.
  *
  * If authentication succeeds, the appropriate state is filled into the
  * session's primary key state's authenticated field. Authentication may also
  * be deferred, in which case the key state's auth_deferred field is filled in.
  *
81d882d5
  * @param up            The username and password to verify.
  * @param multi         The TLS multi structure to verify usernames against.
  * @param session       The current TLS session
d0811e64
  *
  */
 void verify_user_pass(struct user_pass *up, struct tls_multi *multi,
81d882d5
                       struct tls_session *session);
d0811e64
 
 /**
88aaf1ae
  * 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.
  *
81d882d5
  * @param multi         The TLS multi structure to verify locked structures.
  * @param session       The current TLS session
88aaf1ae
  *
  */
 void verify_final_auth_checks(struct tls_multi *multi, struct tls_session *session);
 
fe100528
 struct x509_track
 {
81d882d5
     const struct x509_track *next;
     const char *name;
 #define XT_FULL_CHAIN (1<<0)
     unsigned int flags;
     int nid;
fe100528
 };
 
d0811e64
 /*
06d22777
  * Certificate checking for verify_nsCertType
  */
 /** Do not perform Netscape certificate type verification */
 #define NS_CERT_CHECK_NONE (0)
 /** Do not perform Netscape certificate type verification */
 #define NS_CERT_CHECK_SERVER (1<<0)
 /** Do not perform Netscape certificate type verification */
 #define NS_CERT_CHECK_CLIENT (1<<1)
 
92a5b9fb
 /** Require keyUsage to be present in cert (0xFFFF is an invalid KU value) */
 #define OPENVPN_KU_REQUIRED (0xFFFF)
 
06d22777
 /*
d0811e64
  * TODO: document
  */
 #ifdef MANAGEMENT_DEF_AUTH
81d882d5
 bool tls_authenticate_key(struct tls_multi *multi, const unsigned int mda_key_id, const bool auth, const char *client_reason);
 
 void man_def_auth_set_client_reason(struct tls_multi *multi, const char *client_reason);
 
d0811e64
 #endif
 
 static inline const char *
81d882d5
 tls_client_reason(struct tls_multi *multi)
d0811e64
 {
 #ifdef ENABLE_DEF_AUTH
81d882d5
     return multi->client_reason;
d0811e64
 #else
81d882d5
     return NULL;
d0811e64
 #endif
 }
 
fd036181
 /** Remove any X509_ env variables from env_set es */
 void tls_x509_clear_env(struct env_set *es);
 
d0154a3a
 #endif /* SSL_VERIFY_H_ */