]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Refactored tls_options, key_state, and key_source data structures
authorAdriaan de Jong <dejong@fox-it.com>
Thu, 30 Jun 2011 07:33:41 +0000 (09:33 +0200)
committerDavid Sommerseth <davids@redhat.com>
Fri, 21 Oct 2011 08:53:31 +0000 (10:53 +0200)
Signed-off-by: Adriaan de Jong <dejong@fox-it.com>
Acked-by: James Yonan <james@openvpn.net>
Signed-off-by: David Sommerseth <davids@redhat.com>
init.c
ssl.c
ssl.h
ssl_common.h
ssl_openssl.h

diff --git a/init.c b/init.c
index eb17b01c9f001b2848b78c62fbd220df56cf5ecb..54bb2d13ff9fda8744fda5285e546195a88366fa 100644 (file)
--- a/init.c
+++ b/init.c
@@ -2174,7 +2174,7 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
   if (packet_id_long_form)
     to.crypto_flags_or = CO_PACKET_ID_LONG_FORM;
 
-  to.ssl_ctx = c->c1.ks.ssl_ctx.ctx;
+  to.ssl_ctx = c->c1.ks.ssl_ctx;
   to.key_type = c->c1.ks.key_type;
   to.server = options->tls_server;
   to.key_method = options->key_method;
diff --git a/ssl.c b/ssl.c
index 8ef75abc6b7dab8e3a156e9582955a61b2841e1b..9328542667a126290d7760147496399f4916b10e 100644 (file)
--- a/ssl.c
+++ b/ssl.c
@@ -2042,7 +2042,7 @@ key_state_write_plaintext (struct tls_multi *multi, struct key_state *ks, struct
 {
   int ret;
   perf_push (PERF_BIO_WRITE_PLAINTEXT);
-  ret = bio_write (multi, ks->ssl_bio, BPTR(buf), BLEN(buf), "tls_write_plaintext");
+  ret = bio_write (multi, ks->ks_ssl.ssl_bio, BPTR(buf), BLEN(buf), "tls_write_plaintext");
   bio_write_post (ret, buf);
   perf_pop ();
   return ret;
@@ -2069,7 +2069,7 @@ key_state_write_plaintext_const (struct tls_multi *multi, struct key_state *ks,
 {
   int ret;
   perf_push (PERF_BIO_WRITE_PLAINTEXT);
-  ret = bio_write (multi, ks->ssl_bio, data, len, "tls_write_plaintext_const");
+  ret = bio_write (multi, ks->ks_ssl.ssl_bio, data, len, "tls_write_plaintext_const");
   perf_pop ();
   return ret;
 }
@@ -2099,7 +2099,7 @@ key_state_read_ciphertext (struct tls_multi *multi, struct key_state *ks, struct
 {
   int ret;
   perf_push (PERF_BIO_READ_CIPHERTEXT);
-  ret = bio_read (multi, ks->ct_out, buf, maxlen, "tls_read_ciphertext");
+  ret = bio_read (multi, ks->ks_ssl.ct_out, buf, maxlen, "tls_read_ciphertext");
   perf_pop ();
   return ret;
 }
@@ -2133,7 +2133,7 @@ key_state_write_ciphertext (struct tls_multi *multi, struct key_state *ks, struc
 {
   int ret;
   perf_push (PERF_BIO_WRITE_CIPHERTEXT);
-  ret = bio_write (multi, ks->ct_in, BPTR(buf), BLEN(buf), "tls_write_ciphertext");
+  ret = bio_write (multi, ks->ks_ssl.ct_in, BPTR(buf), BLEN(buf), "tls_write_ciphertext");
   bio_write_post (ret, buf);
   perf_pop ();
   return ret;
@@ -2164,7 +2164,7 @@ key_state_read_plaintext (struct tls_multi *multi, struct key_state *ks, struct
 {
   int ret;
   perf_push (PERF_BIO_READ_PLAINTEXT);
-  ret = bio_read (multi, ks->ssl_bio, buf, maxlen, "tls_read_plaintext");
+  ret = bio_read (multi, ks->ks_ssl.ssl_bio, buf, maxlen, "tls_read_plaintext");
   perf_pop ();
   return ret;
 }
@@ -2208,31 +2208,31 @@ key_state_init (struct tls_session *session, struct key_state *ks)
    */
   CLEAR (*ks);
 
-  ks->ssl = SSL_new (session->opt->ssl_ctx);
-  if (!ks->ssl)
+  ks->ks_ssl.ssl = SSL_new (session->opt->ssl_ctx.ctx);
+  if (!ks->ks_ssl.ssl)
     msg (M_SSLERR, "SSL_new failed");
 
   /* put session * in ssl object so we can access it
      from verify callback*/
-  SSL_set_ex_data (ks->ssl, mydata_index, session);
+  SSL_set_ex_data (ks->ks_ssl.ssl, mydata_index, session);
 
-  ks->ssl_bio = getbio (BIO_f_ssl (), "ssl_bio");
-  ks->ct_in = getbio (BIO_s_mem (), "ct_in");
-  ks->ct_out = getbio (BIO_s_mem (), "ct_out");
+  ks->ks_ssl.ssl_bio = getbio (BIO_f_ssl (), "ssl_bio");
+  ks->ks_ssl.ct_in = getbio (BIO_s_mem (), "ct_in");
+  ks->ks_ssl.ct_out = getbio (BIO_s_mem (), "ct_out");
 
 #ifdef BIO_DEBUG
-  bio_debug_oc ("open ssl_bio", ks->ssl_bio);
-  bio_debug_oc ("open ct_in", ks->ct_in);
-  bio_debug_oc ("open ct_out", ks->ct_out);
+  bio_debug_oc ("open ssl_bio", ks->ks_ssl.ssl_bio);
+  bio_debug_oc ("open ct_in", ks->ks_ssl.ct_in);
+  bio_debug_oc ("open ct_out", ks->ks_ssl.ct_out);
 #endif
 
   if (session->opt->server)
-    SSL_set_accept_state (ks->ssl);
+    SSL_set_accept_state (ks->ks_ssl.ssl);
   else
-    SSL_set_connect_state (ks->ssl);
+    SSL_set_connect_state (ks->ks_ssl.ssl);
 
-  SSL_set_bio (ks->ssl, ks->ct_in, ks->ct_out);
-  BIO_set_ssl (ks->ssl_bio, ks->ssl, BIO_NOCLOSE);
+  SSL_set_bio (ks->ks_ssl.ssl, ks->ks_ssl.ct_in, ks->ks_ssl.ct_out);
+  BIO_set_ssl (ks->ks_ssl.ssl_bio, ks->ks_ssl.ssl, BIO_NOCLOSE);
 
   /* Set control-channel initiation mode */
   ks->initial_opcode = session->initial_opcode;
@@ -2300,14 +2300,14 @@ key_state_free (struct key_state *ks, bool clear)
 {
   ks->state = S_UNDEF;
 
-  if (ks->ssl) {
+  if (ks->ks_ssl.ssl) {
 #ifdef BIO_DEBUG
-    bio_debug_oc ("close ssl_bio", ks->ssl_bio);
-    bio_debug_oc ("close ct_in", ks->ct_in);
-    bio_debug_oc ("close ct_out", ks->ct_out);
+    bio_debug_oc ("close ssl_bio", ks->ks_ssl.ssl_bio);
+    bio_debug_oc ("close ct_in", ks->ks_ssl.ct_in);
+    bio_debug_oc ("close ct_out", ks->ks_ssl.ct_out);
 #endif
-    BIO_free_all(ks->ssl_bio);
-    SSL_free (ks->ssl);
+    BIO_free_all(ks->ks_ssl.ssl_bio);
+    SSL_free (ks->ks_ssl.ssl);
   }
 
   free_key_ctx_bi (&ks->key);
@@ -4137,7 +4137,7 @@ tls_process (struct tls_multi *multi,
                  ks->established = now;
                  dmsg (D_TLS_DEBUG_MED, "STATE S_ACTIVE");
                  if (check_debug_level (D_HANDSHAKE))
-                   print_details (ks->ssl, "Control Channel:");
+                   print_details (ks->ks_ssl.ssl, "Control Channel:");
                  state_change = true;
                  ks->state = S_ACTIVE;
                  INCR_SUCCESS;
diff --git a/ssl.h b/ssl.h
index 0e8a7ae4fccca553663f7a0ee7a11ab6efca73f9..4af20e3de738a5a326ac7a32ece256f729696991 100644 (file)
--- a/ssl.h
+++ b/ssl.h
@@ -239,108 +239,6 @@ void init_ssl_lib (void);
  */
 void free_ssl_lib (void);
 
-/**
- * Container for one half of random material to be used in %key method 2
- * \ref key_generation "data channel key generation".
- * @ingroup control_processor
- */
-struct key_source {
-  uint8_t pre_master[48];       /**< Random used for master secret
-                                 *   generation, provided only by client
-                                 *   OpenVPN peer. */
-  uint8_t random1[32];          /**< Seed used for master secret
-                                 *   generation, provided by both client
-                                 *   and server. */
-  uint8_t random2[32];          /**< Seed used for key expansion, provided
-                                 *   by both client and server. */
-};
-
-
-/**
- * Container for both halves of random material to be used in %key method
- * 2 \ref key_generation "data channel key generation".
- * @ingroup control_processor
- */
-struct key_source2 {
-  struct key_source client;     /**< Random provided by client. */
-  struct key_source server;     /**< Random provided by server. */
-};
-
-/**
- * Security parameter state of one TLS and data channel %key session.
- * @ingroup control_processor
- *
- * This structure represents one security parameter session between
- * OpenVPN peers.  It includes the control channel TLS state and the data
- * channel crypto state.  It also contains the reliability layer
- * structures used for control channel messages.
- *
- * A new \c key_state structure is initialized for each hard or soft
- * reset.
- *
- * @see
- *  - This structure should be initialized using the \c key_state_init()
- *    function.
- *  - This structure should be cleaned up using the \c key_state_free()
- *    function.
- */
-struct key_state
-{
-  int state;
-  int key_id;                  /* inherited from struct tls_session below */
-
-  SSL *ssl;                    /* SSL object -- new obj created for each new key */
-  BIO *ssl_bio;                        /* read/write plaintext from here */
-  BIO *ct_in;                  /* write ciphertext to here */
-  BIO *ct_out;                 /* read ciphertext from here */
-
-  time_t established;          /* when our state went S_ACTIVE */
-  time_t must_negotiate;       /* key negotiation times out if not finished before this time */
-  time_t must_die;             /* this object is destroyed at this time */
-
-  int initial_opcode;          /* our initial P_ opcode */
-  struct session_id session_id_remote;   /* peer's random session ID */
-  struct link_socket_actual remote_addr; /* peer's IP addr */
-  struct packet_id packet_id;         /* for data channel, to prevent replay attacks */
-
-  struct key_ctx_bi key;              /* data channel keys for encrypt/decrypt/hmac */
-
-  struct key_source2 *key_src;         /* source entropy for key expansion */
-
-  struct buffer plaintext_read_buf;
-  struct buffer plaintext_write_buf;
-  struct buffer ack_write_buf;
-
-  struct reliable *send_reliable; /* holds a copy of outgoing packets until ACK received */
-  struct reliable *rec_reliable;  /* order incoming ciphertext packets before we pass to TLS */
-  struct reliable_ack *rec_ack;          /* buffers all packet IDs we want to ACK back to sender */
-
-  struct buffer_list *paybuf;
-
-  counter_type n_bytes;                 /* how many bytes sent/recvd since last key exchange */
-  counter_type n_packets;       /* how many packets sent/recvd since last key exchange */
-
-  /*
-   * If bad username/password, TLS connection will come up but 'authenticated' will be false.
-   */
-  bool authenticated;
-  time_t auth_deferred_expire;
-
-#ifdef ENABLE_DEF_AUTH
-  /* If auth_deferred is true, authentication is being deferred */
-  bool auth_deferred;
-#ifdef MANAGEMENT_DEF_AUTH
-  unsigned int mda_key_id;
-  unsigned int mda_status;
-#endif
-#ifdef PLUGIN_DEF_AUTH
-  unsigned int auth_control_status;
-  time_t acf_last_mod;
-  char *auth_control_file;
-#endif
-#endif
-};
-
 #ifdef ENABLE_X509_TRACK
 
 struct x509_track
@@ -356,115 +254,6 @@ void x509_track_add (const struct x509_track **ll_head, const char *name, int ms
 
 #endif
 
-/*
- * Our const options, obtained directly or derived from
- * command line options.
- */
-struct tls_options
-{
-  /* our master SSL_CTX from which all SSL objects derived */
-  SSL_CTX *ssl_ctx;
-
-  /* data channel cipher, hmac, and key lengths */
-  struct key_type key_type;
-
-  /* true if we are a TLS server, client otherwise */
-  bool server;
-
-  /* if true, don't xmit until first packet from peer is received */
-  bool xmit_hold;
-
-#ifdef ENABLE_OCC
-  /* local and remote options strings
-     that must match between client and server */
-  const char *local_options;
-  const char *remote_options;
-#endif
-
-  /* from command line */
-  int key_method;
-  bool replay;
-  bool single_session;
-#ifdef ENABLE_OCC
-  bool disable_occ;
-#endif
-#ifdef ENABLE_PUSH_PEER_INFO
-  bool push_peer_info;
-#endif
-  int transition_window;
-  int handshake_window;
-  interval_t packet_timeout;
-  int renegotiate_bytes;
-  int renegotiate_packets;
-  interval_t renegotiate_seconds;
-
-  /* cert verification parms */
-  const char *verify_command;
-  const char *verify_export_cert;
-  const char *verify_x509name;
-  const char *crl_file;
-  int ns_cert_type;
-  unsigned remote_cert_ku[MAX_PARMS];
-  const char *remote_cert_eku;
-  uint8_t *verify_hash;
-
-  /* allow openvpn config info to be
-     passed over control channel */
-  bool pass_config_info;
-
-  /* struct crypto_option flags */
-  unsigned int crypto_flags_and;
-  unsigned int crypto_flags_or;
-
-  int replay_window;                   /* --replay-window parm */
-  int replay_time;                     /* --replay-window parm */
-  bool tcp_mode;
-
-  /* packet authentication for TLS handshake */
-  struct crypto_options tls_auth;
-  struct key_ctx_bi tls_auth_key;
-
-  /* frame parameters for TLS control channel */
-  struct frame frame;
-
-  /* used for username/password authentication */
-  const char *auth_user_pass_verify_script;
-  bool auth_user_pass_verify_script_via_file;
-  const char *tmp_dir;
-
-  /* use the client-config-dir as a positive authenticator */
-  const char *client_config_dir_exclusive;
-
-  /* instance-wide environment variable set */
-  struct env_set *es;
-  const struct plugin_list *plugins;
-
-  /* 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)
-# define SSLF_CRL_VERIFY_DIR           (1<<5)
-  unsigned int ssl_flags;
-
-#ifdef MANAGEMENT_DEF_AUTH
-  struct man_def_auth_context *mda_context;
-#endif
-
-#ifdef ENABLE_X509_TRACK
-  const struct x509_track *x509_track;
-#endif
-
-#ifdef ENABLE_CLIENT_CR
-  const struct static_challenge_info *sci;
-#endif
-
-  /* --gremlin bits */
-  int gremlin;
-};
-
-
 /** @addtogroup control_processor
  *  @{ */
 /** @name Index of key_state objects within a tls_session structure
index 7a95274d1a78ffc308511bdadbc92257ae226109..02193bd104941048893a4d39ecdf7f46f601fc1d 100644 (file)
 #define UP_TYPE_AUTH        "Auth"
 #define UP_TYPE_PRIVATE_KEY "Private Key"
 
+/**
+ * Container for one half of random material to be used in %key method 2
+ * \ref key_generation "data channel key generation".
+ * @ingroup control_processor
+ */
+struct key_source {
+  uint8_t pre_master[48];       /**< Random used for master secret
+                                 *   generation, provided only by client
+                                 *   OpenVPN peer. */
+  uint8_t random1[32];          /**< Seed used for master secret
+                                 *   generation, provided by both client
+                                 *   and server. */
+  uint8_t random2[32];          /**< Seed used for key expansion, provided
+                                 *   by both client and server. */
+};
+
+
+/**
+ * Container for both halves of random material to be used in %key method
+ * 2 \ref key_generation "data channel key generation".
+ * @ingroup control_processor
+ */
+struct key_source2 {
+  struct key_source client;     /**< Random provided by client. */
+  struct key_source server;     /**< Random provided by server. */
+};
+
+/**
+ * Security parameter state of one TLS and data channel %key session.
+ * @ingroup control_processor
+ *
+ * This structure represents one security parameter session between
+ * OpenVPN peers.  It includes the control channel TLS state and the data
+ * channel crypto state.  It also contains the reliability layer
+ * structures used for control channel messages.
+ *
+ * A new \c key_state structure is initialized for each hard or soft
+ * reset.
+ *
+ * @see
+ *  - This structure should be initialized using the \c key_state_init()
+ *    function.
+ *  - This structure should be cleaned up using the \c key_state_free()
+ *    function.
+ */
+struct key_state
+{
+  int state;
+  int key_id;                  /* inherited from struct tls_session below */
+
+  struct key_state_ssl ks_ssl; /* contains SSL object and BIOs for the control channel */
+
+  time_t established;          /* when our state went S_ACTIVE */
+  time_t must_negotiate;       /* key negotiation times out if not finished before this time */
+  time_t must_die;             /* this object is destroyed at this time */
+
+  int initial_opcode;          /* our initial P_ opcode */
+  struct session_id session_id_remote;   /* peer's random session ID */
+  struct link_socket_actual remote_addr; /* peer's IP addr */
+  struct packet_id packet_id;         /* for data channel, to prevent replay attacks */
+
+  struct key_ctx_bi key;              /* data channel keys for encrypt/decrypt/hmac */
+
+  struct key_source2 *key_src;         /* source entropy for key expansion */
+
+  struct buffer plaintext_read_buf;
+  struct buffer plaintext_write_buf;
+  struct buffer ack_write_buf;
+
+  struct reliable *send_reliable; /* holds a copy of outgoing packets until ACK received */
+  struct reliable *rec_reliable;  /* order incoming ciphertext packets before we pass to TLS */
+  struct reliable_ack *rec_ack;          /* buffers all packet IDs we want to ACK back to sender */
+
+  struct buffer_list *paybuf;
+
+  counter_type n_bytes;                         /* how many bytes sent/recvd since last key exchange */
+  counter_type n_packets;               /* how many packets sent/recvd since last key exchange */
+
+  /*
+   * If bad username/password, TLS connection will come up but 'authenticated' will be false.
+   */
+  bool authenticated;
+  time_t auth_deferred_expire;
+
+#ifdef ENABLE_DEF_AUTH
+  /* If auth_deferred is true, authentication is being deferred */
+  bool auth_deferred;
+#ifdef MANAGEMENT_DEF_AUTH
+  unsigned int mda_key_id;
+  unsigned int mda_status;
+#endif
+#ifdef PLUGIN_DEF_AUTH
+  unsigned int auth_control_status;
+  time_t acf_last_mod;
+  char *auth_control_file;
+#endif
+#endif
+};
+
+/*
+ * Our const options, obtained directly or derived from
+ * command line options.
+ */
+struct tls_options
+{
+  /* our master TLS context from which all SSL objects derived */
+  struct tls_root_ctx ssl_ctx;
+
+  /* data channel cipher, hmac, and key lengths */
+  struct key_type key_type;
+
+  /* true if we are a TLS server, client otherwise */
+  bool server;
+
+  /* if true, don't xmit until first packet from peer is received */
+  bool xmit_hold;
+
+#ifdef ENABLE_OCC
+  /* local and remote options strings
+     that must match between client and server */
+  const char *local_options;
+  const char *remote_options;
+#endif
+
+  /* from command line */
+  int key_method;
+  bool replay;
+  bool single_session;
+#ifdef ENABLE_OCC
+  bool disable_occ;
+#endif
+#ifdef ENABLE_PUSH_PEER_INFO
+  bool push_peer_info;
+#endif
+  int transition_window;
+  int handshake_window;
+  interval_t packet_timeout;
+  int renegotiate_bytes;
+  int renegotiate_packets;
+  interval_t renegotiate_seconds;
+
+  /* cert verification parms */
+  const char *verify_command;
+  const char *verify_export_cert;
+  const char *verify_x509name;
+  const char *crl_file;
+  int ns_cert_type;
+  unsigned remote_cert_ku[MAX_PARMS];
+  const char *remote_cert_eku;
+  uint8_t *verify_hash;
+
+  /* allow openvpn config info to be
+     passed over control channel */
+  bool pass_config_info;
+
+  /* struct crypto_option flags */
+  unsigned int crypto_flags_and;
+  unsigned int crypto_flags_or;
+
+  int replay_window;                   /* --replay-window parm */
+  int replay_time;                     /* --replay-window parm */
+  bool tcp_mode;
+
+  /* packet authentication for TLS handshake */
+  struct crypto_options tls_auth;
+  struct key_ctx_bi tls_auth_key;
+
+  /* frame parameters for TLS control channel */
+  struct frame frame;
+
+  /* used for username/password authentication */
+  const char *auth_user_pass_verify_script;
+  bool auth_user_pass_verify_script_via_file;
+  const char *tmp_dir;
+
+  /* use the client-config-dir as a positive authenticator */
+  const char *client_config_dir_exclusive;
+
+  /* instance-wide environment variable set */
+  struct env_set *es;
+  const struct plugin_list *plugins;
+
   /* 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)
+# define SSLF_CRL_VERIFY_DIR           (1<<5)
+  unsigned int ssl_flags;
+
+#ifdef MANAGEMENT_DEF_AUTH
+  struct man_def_auth_context *mda_context;
+#endif
+
+#ifdef ENABLE_X509_TRACK
+  const struct x509_track *x509_track;
+#endif
+
+#ifdef ENABLE_CLIENT_CR
+  const struct static_challenge_info *sci;
+#endif
+
+  /* --gremlin bits */
+  int gremlin;
+};
+
 #endif /* SSL_COMMON_H_ */
index a87861be2eac5509ccc4a160bf7117bce75f2749..fc2052cb626e07f97f144026666354250768d192 100644 (file)
@@ -40,6 +40,13 @@ struct tls_root_ctx {
     SSL_CTX *ctx;
 };
 
+struct key_state_ssl {
+    SSL *ssl;                  /* SSL object -- new obj created for each new key */
+    BIO *ssl_bio;                      /* read/write plaintext from here */
+    BIO *ct_in;                        /* write ciphertext to here */
+    BIO *ct_out;                       /* read ciphertext from here */
+};
+
 /**
  * Allocate space in SSL objects in which to store a struct tls_session
  * pointer back to parent.