summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdriaan de Jong <dejong@fox-it.com>2011-06-29 16:30:38 +0200
committerDavid Sommerseth <davids@redhat.com>2011-10-19 22:31:46 +0200
commitb5563f1154a4a4e1d4742b7194e4974a3b53b78f (patch)
tree1a42b4a1ee18a38c67db8cf6f0c9682322a309e4
parentac3e8d62ba14d4ee376fd3c9f20bccc3e53e7371 (diff)
downloadopenvpn-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.c75
-rw-r--r--ssl_backend.h22
-rw-r--r--ssl_common.h6
-rw-r--r--ssl_openssl.c51
-rw-r--r--ssl_verify_openssl.h35
5 files changed, 118 insertions, 71 deletions
diff --git a/ssl.c b/ssl.c
index c5a23c1..4c22a97 100644
--- a/ssl.c
+++ b/ssl.c
@@ -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_ */