]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Refactored root TLS option settings
authorAdriaan de Jong <dejong@fox-it.com>
Wed, 29 Jun 2011 14:30:38 +0000 (16:30 +0200)
committerDavid Sommerseth <davids@redhat.com>
Wed, 19 Oct 2011 20:31:46 +0000 (22:31 +0200)
 - 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>
ssl.c
ssl_backend.h
ssl_common.h
ssl_openssl.c
ssl_verify_openssl.h

diff --git a/ssl.c b/ssl.c
index c5a23c13bc7cad0dd4086a8e21f6d63e1c0fc762..4c22a97706edb7e83802bdab703eb8483c49f351 100644 (file)
--- 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)
     {
index d97427956c47724b1d20e7ff56a4ab48a343c292..f3f7202ad2f1b9905664940c06af5919f1930e39 100644 (file)
  * 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.
  *
index 060e6c67eaade3f4c878b5c6dedaddd363ea0908..6aa70d0162a41e56fc6da461ff577b7782c8c6bd 100644 (file)
 
 #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_ */
index 886ca9b8b1fa6edce540b74606452621477fcb45..77dd077f1ce582d6e7ea0fc68ca007b0f210fe32 100644 (file)
@@ -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
index e48f1096e893df16fcffd48cf254934160168894..099788a671be4ff05d2486f7d71b4217cdc89d28 100644 (file)
 #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_ */