diff options
author | Adriaan de Jong <dejong@fox-it.com> | 2011-06-29 16:30:38 +0200 |
---|---|---|
committer | David Sommerseth <davids@redhat.com> | 2011-10-19 22:31:46 +0200 |
commit | b5563f1154a4a4e1d4742b7194e4974a3b53b78f (patch) | |
tree | 1a42b4a1ee18a38c67db8cf6f0c9682322a309e4 | |
parent | ac3e8d62ba14d4ee376fd3c9f20bccc3e53e7371 (diff) | |
download | openvpn-b5563f1154a4a4e1d4742b7194e4974a3b53b78f.tar.gz openvpn-b5563f1154a4a4e1d4742b7194e4974a3b53b78f.tar.xz openvpn-b5563f1154a4a4e1d4742b7194e4974a3b53b78f.zip |
Refactored root TLS option settings
- Started merge of new feature (x509_altnames), will continue in a
future patch
Signed-off-by: Adriaan de Jong <dejong@fox-it.com>
Acked-by: Gert Doering <gert@greenie.muc.de>
Signed-off-by: David Sommerseth <davids@redhat.com>
-rw-r--r-- | ssl.c | 75 | ||||
-rw-r--r-- | ssl_backend.h | 22 | ||||
-rw-r--r-- | ssl_common.h | 6 | ||||
-rw-r--r-- | ssl_openssl.c | 51 | ||||
-rw-r--r-- | ssl_verify_openssl.h | 35 |
5 files changed, 118 insertions, 71 deletions
@@ -899,34 +899,7 @@ get_peer_cert(X509_STORE_CTX *ctx, const char *tmp_dir, struct gc_arena *gc) char * x509_username_field; /* GLOBAL */ -/** @name Function for authenticating a new connection from a remote OpenVPN peer - * @{ */ - -/** - * Verify that the remote OpenVPN peer's certificate allows setting up a - * VPN tunnel. - * @ingroup control_tls - * - * This callback function is called every time a new TLS session is being - * setup to determine whether the remote OpenVPN peer's certificate is - * allowed to connect. The callback functionality is configured in the \c - * init_ssl() function, which calls the OpenSSL library's \c - * SSL_CTX_set_verify() function with \c verify_callback() as its callback - * argument. - * - * @param preverify_ok - Whether the remote OpenVPN peer's certificate - * past verification. A value of 1 means it - * verified successfully, 0 means it failed. - * @param ctx - The complete context used by the OpenSSL library - * to verify the certificate chain. - * - * @return The return value indicates whether the supplied certificate is - * allowed to set up a VPN tunnel. The following values can be - * returned: - * - \c 0: failure, this certificate is not allowed to connect. - * - \c 1: success, this certificate is allowed to connect. - */ -static int +int verify_callback (int preverify_ok, X509_STORE_CTX * ctx) { char *subject = NULL; @@ -1629,31 +1602,6 @@ tls_deauthenticate (struct tls_multi *multi) } } -#ifndef INFO_CALLBACK_SSL_CONST -#define INFO_CALLBACK_SSL_CONST const -#endif -/* - * Print debugging information on SSL/TLS session negotiation. - */ -static void -info_callback (INFO_CALLBACK_SSL_CONST SSL * s, int where, int ret) -{ - if (where & SSL_CB_LOOP) - { - dmsg (D_HANDSHAKE_VERBOSE, "SSL state (%s): %s", - where & SSL_ST_CONNECT ? "connect" : - where & SSL_ST_ACCEPT ? "accept" : - "undefined", SSL_state_string_long (s)); - } - else if (where & SSL_CB_ALERT) - { - dmsg (D_HANDSHAKE_VERBOSE, "SSL alert (%s): %s: %s", - where & SSL_CB_READ ? "read" : "write", - SSL_alert_type_string_long (ret), - SSL_alert_desc_string_long (ret)); - } -} - #ifdef MANAGMENT_EXTERNAL_KEY /* encrypt */ @@ -2035,14 +1983,9 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx) tls_ctx_client_new(new_ctx); } - ctx = new_ctx->ctx; + tls_ctx_set_options(new_ctx, options->ssl_flags); - /* Set SSL options */ - SSL_CTX_set_session_cache_mode (ctx, SSL_SESS_CACHE_OFF); - SSL_CTX_set_options (ctx, SSL_OP_SINGLE_DH_USE); - - /* Set callback for getting password from user to decrypt private key */ - SSL_CTX_set_default_passwd_cb (ctx, pem_password_callback); + ctx = new_ctx->ctx; if (options->pkcs12_file) { @@ -2321,13 +2264,8 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx) BIO_free (bio); } - /* Require peer certificate verification */ #if P2MP_SERVER - if (options->ssl_flags & SSLF_CLIENT_CERT_NOT_REQUIRED) - { - msg (M_WARN, "WARNING: POTENTIALLY DANGEROUS OPTION --client-cert-not-required may accept clients which do not present a certificate"); - } - else + if (!(options->ssl_flags & SSLF_CLIENT_CERT_NOT_REQUIRED)) #endif { #ifdef ENABLE_X509ALTUSERNAME @@ -2335,13 +2273,8 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx) #else x509_username_field = X509_USERNAME_FIELD_DEFAULT; #endif - SSL_CTX_set_verify (ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, - verify_callback); } - /* Connection information callback */ - SSL_CTX_set_info_callback (ctx, info_callback); - /* Allowable ciphers */ if (options->cipher_list) { diff --git a/ssl_backend.h b/ssl_backend.h index d974279..f3f7202 100644 --- a/ssl_backend.h +++ b/ssl_backend.h @@ -43,6 +43,17 @@ * Functions implemented in ssl.c for use by the backend SSL library * */ + +/** + * Callback to retrieve the user's password + * + * @param buf Buffer to return the password in + * @param size Size of the buffer + * @param rwflag Unused, needed for OpenSSL compatibility + * @param u Unused, needed for OpenSSL compatibility + */ +int pem_password_callback (char *buf, int size, int rwflag, void *u); + /* * * Functions used in ssl.c which must be implemented by the backend SSL library @@ -95,6 +106,17 @@ void tls_ctx_free(struct tls_root_ctx *ctx); bool tls_ctx_initialised(struct tls_root_ctx *ctx); /** + * Set any library specific options. + * + * Examples include disabling session caching, the password callback to use, + * and session verification parameters. + * + * @param ctx TLS context to set options on + * @param ssl_flags SSL flags to set + */ +void tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags); + +/* * Load Diffie Hellman Parameters, and load them into the library-specific * TLS context. * diff --git a/ssl_common.h b/ssl_common.h index 060e6c6..6aa70d0 100644 --- a/ssl_common.h +++ b/ssl_common.h @@ -38,4 +38,10 @@ #include "ssl_backend.h" + /* configuration file boolean options */ +# define SSLF_CLIENT_CERT_NOT_REQUIRED (1<<0) +# define SSLF_USERNAME_AS_COMMON_NAME (1<<1) +# define SSLF_AUTH_USER_PASS_OPTIONAL (1<<2) +# define SSLF_NO_NAME_REMAPPING (1<<3) +# define SSLF_OPT_VERIFY (1<<4) #endif /* SSL_COMMON_H_ */ diff --git a/ssl_openssl.c b/ssl_openssl.c index 886ca9b..77dd077 100644 --- a/ssl_openssl.c +++ b/ssl_openssl.c @@ -130,6 +130,57 @@ bool tls_ctx_initialised(struct tls_root_ctx *ctx) return NULL != ctx->ctx; } +/* + * Print debugging information on SSL/TLS session negotiation. + */ + +#ifndef INFO_CALLBACK_SSL_CONST +#define INFO_CALLBACK_SSL_CONST const +#endif +static void +info_callback (INFO_CALLBACK_SSL_CONST SSL * s, int where, int ret) +{ + if (where & SSL_CB_LOOP) + { + dmsg (D_HANDSHAKE_VERBOSE, "SSL state (%s): %s", + where & SSL_ST_CONNECT ? "connect" : + where & SSL_ST_ACCEPT ? "accept" : + "undefined", SSL_state_string_long (s)); + } + else if (where & SSL_CB_ALERT) + { + dmsg (D_HANDSHAKE_VERBOSE, "SSL alert (%s): %s: %s", + where & SSL_CB_READ ? "read" : "write", + SSL_alert_type_string_long (ret), + SSL_alert_desc_string_long (ret)); + } +} + +void +tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags) +{ + ASSERT(NULL != ctx); + + SSL_CTX_set_session_cache_mode (ctx->ctx, SSL_SESS_CACHE_OFF); + SSL_CTX_set_options (ctx->ctx, SSL_OP_SINGLE_DH_USE); + SSL_CTX_set_default_passwd_cb (ctx->ctx, pem_password_callback); + + /* Require peer certificate verification */ +#if P2MP_SERVER + if (ssl_flags & SSLF_CLIENT_CERT_NOT_REQUIRED) + { + msg (M_WARN, "WARNING: POTENTIALLY DANGEROUS OPTION " + "--client-cert-not-required may accept clients which do not present " + "a certificate"); + } + else +#endif + SSL_CTX_set_verify (ctx->ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + verify_callback); + + SSL_CTX_set_info_callback (ctx->ctx, info_callback); +} + void tls_ctx_load_dh_params (struct tls_root_ctx *ctx, const char *dh_file #if ENABLE_INLINE_FILES diff --git a/ssl_verify_openssl.h b/ssl_verify_openssl.h index e48f109..099788a 100644 --- a/ssl_verify_openssl.h +++ b/ssl_verify_openssl.h @@ -32,4 +32,39 @@ #define SSL_VERIFY_OPENSSL_H_ #include <openssl/x509.h> +/** @name Function for authenticating a new connection from a remote OpenVPN peer + * @{ */ + +/** + * Verify that the remote OpenVPN peer's certificate allows setting up a + * VPN tunnel. + * @ingroup control_tls + * + * This callback function is called every time a new TLS session is being + * setup to determine whether the remote OpenVPN peer's certificate is + * allowed to connect. It is called for once for every certificate in the chain. + * The callback functionality is configured in the \c init_ssl() function, which + * calls the OpenSSL library's \c SSL_CTX_set_verify() function with \c + * verify_callback() as its callback argument. + * + * It checks preverify_ok, and registers the certificate hash. If these steps + * succeed, it calls the \c verify_cert() function, which performs + * OpenVPN-specific verification. + * + * @param preverify_ok - Whether the remote OpenVPN peer's certificate + * past verification. A value of 1 means it + * verified successfully, 0 means it failed. + * @param ctx - The complete context used by the OpenSSL library + * to verify the certificate chain. + * + * @return The return value indicates whether the supplied certificate is + * allowed to set up a VPN tunnel. The following values can be + * returned: + * - \c 0: failure, this certificate is not allowed to connect. + * - \c 1: success, this certificate is allowed to connect. + */ +int verify_callback (int preverify_ok, X509_STORE_CTX * ctx); + +/** @} name Function for authenticating a new connection from a remote OpenVPN peer */ + #endif /* SSL_VERIFY_OPENSSL_H_ */ |