Browse code

Add options to restrict cipher negotiation

Add --ncp-disable to completely disable cipher negotiation, and
--ncp-ciphers to specify which ciphers to accept from the server.

v2:
* fix --disable-crypto builds
* use register_signal() instead of operating directly on c->sig
* add man-page entry for new options

v3:
* rebased on client-side NCP v3

v4:
* rebased on client-side NCP v4

Signed-off-by: Steffan Karger <steffan@karger.me>
Acked-by: Arne Schwabe <arne@rfc2549.org>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <1467149700-10042-1-git-send-email-steffan@karger.me>
URL: http://article.gmane.org/gmane.network.openvpn.devel/12008
Signed-off-by: Gert Doering <gert@greenie.muc.de>

Steffan Karger authored on 2016/06/29 06:35:00
Showing 9 changed files
... ...
@@ -4131,6 +4131,19 @@ Set
4131 4131
 to disable encryption.
4132 4132
 .\"*********************************************************
4133 4133
 .TP
4134
+.B \-\-ncp\-ciphers cipher_list
4135
+Restrict the allowed ciphers to be negotiated to the ciphers in
4136
+.B cipher_list\fR.
4137
+.B cipher_list
4138
+is a colon-separated list of ciphers, and defaults to
4139
+"AES-256-GCM:AES-128-GCM".
4140
+.\"*********************************************************
4141
+.TP
4142
+.B \-\-ncp\-disable
4143
+Disable "negotiable crypto parameters".  This completely disables cipher
4144
+negotiation.
4145
+.\"*********************************************************
4146
+.TP
4134 4147
 .B \-\-keysize n
4135 4148
 Size of cipher key in bits (optional).
4136 4149
 If unspecified, defaults to cipher-specific default.  The
... ...
@@ -1745,7 +1745,7 @@ options_hash_changed_or_zero(const struct md5_digest *a,
1745 1745
 }
1746 1746
 #endif /* P2MP */
1747 1747
 
1748
-void
1748
+bool
1749 1749
 do_up (struct context *c, bool pulled_options, unsigned int option_types_found)
1750 1750
 {
1751 1751
   if (!c->c2.do_up_ran)
... ...
@@ -1753,7 +1753,13 @@ do_up (struct context *c, bool pulled_options, unsigned int option_types_found)
1753 1753
       reset_coarse_timers (c);
1754 1754
 
1755 1755
       if (pulled_options && option_types_found)
1756
-	do_deferred_options (c, option_types_found);
1756
+	{
1757
+	  if (!do_deferred_options (c, option_types_found))
1758
+	    {
1759
+	      msg (D_PUSH_ERRORS, "ERROR: Failed to apply push options");
1760
+	      return false;
1761
+	    }
1762
+	}
1757 1763
 
1758 1764
       /* if --up-delay specified, open tun, do ifconfig, and run up script now */
1759 1765
       if (c->options.up_delay || PULL_DEFINED (&c->options))
... ...
@@ -1808,6 +1814,7 @@ do_up (struct context *c, bool pulled_options, unsigned int option_types_found)
1808 1808
 	
1809 1809
       c->c2.do_up_ran = true;
1810 1810
     }
1811
+  return true;
1811 1812
 }
1812 1813
 
1813 1814
 /*
... ...
@@ -1825,7 +1832,6 @@ pull_permission_mask (const struct context *c)
1825 1825
     | OPT_P_SHAPER
1826 1826
     | OPT_P_TIMER
1827 1827
     | OPT_P_COMP
1828
-    | OPT_P_CRYPTO
1829 1828
     | OPT_P_PERSIST
1830 1829
     | OPT_P_MESSAGES
1831 1830
     | OPT_P_EXPLICIT_NOTIFY
... ...
@@ -1836,13 +1842,18 @@ pull_permission_mask (const struct context *c)
1836 1836
   if (!c->options.route_nopull)
1837 1837
     flags |= (OPT_P_ROUTE | OPT_P_IPWIN32);
1838 1838
 
1839
+#ifdef ENABLE_CRYPTO
1840
+  if (c->options.ncp_enabled)
1841
+    flags |= OPT_P_NCP;
1842
+#endif
1843
+
1839 1844
   return flags;
1840 1845
 }
1841 1846
 
1842 1847
 /*
1843 1848
  * Handle non-tun-related pulled options.
1844 1849
  */
1845
-void
1850
+bool
1846 1851
 do_deferred_options (struct context *c, const unsigned int found)
1847 1852
 {
1848 1853
   if (found & OPT_P_MESSAGES)
... ...
@@ -1934,15 +1945,18 @@ do_deferred_options (struct context *c, const unsigned int found)
1934 1934
   if (c->options.pull)
1935 1935
     {
1936 1936
       struct tls_session *session = &c->c2.tls_multi->session[TM_ACTIVE];
1937
-      if (found & OPT_P_CRYPTO)
1937
+      if (found & OPT_P_NCP)
1938 1938
 	msg (D_PUSH, "OPTIONS IMPORT: data channel crypto options modified");
1939 1939
       /* Do not regenerate keys if server sends an extra push request */
1940
-      if (!session->key[KS_PRIMARY].crypto_options.key_ctx_bi.initialized)
1940
+      if (!session->key[KS_PRIMARY].crypto_options.key_ctx_bi.initialized &&
1941
+	  !tls_session_update_crypto_params(session, &c->options, &c->c2.frame))
1941 1942
 	{
1942
-	  tls_session_update_crypto_params(session, &c->options, &c->c2.frame);
1943
+	  msg (D_TLS_ERRORS, "OPTIONS ERROR: failed to import crypto options");
1944
+	  return false;
1943 1945
 	}
1944 1946
     }
1945 1947
 #endif
1948
+  return true;
1946 1949
 }
1947 1950
 
1948 1951
 /*
... ...
@@ -2272,6 +2286,9 @@ do_init_crypto_tls_c1 (struct context *c)
2272 2272
 	      &c->c1.ks.tls_auth_key, file, options->key_direction, flags);
2273 2273
 	}
2274 2274
 
2275
+      c->c1.ciphername = options->ciphername;
2276
+      c->c1.authname = options->authname;
2277
+
2275 2278
 #if 0 /* was: #if ENABLE_INLINE_FILES --  Note that enabling this code will break restarts */
2276 2279
       if (options->priv_key_file_inline)
2277 2280
 	{
... ...
@@ -2348,6 +2365,9 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
2348 2348
   to.replay_window = options->replay_window;
2349 2349
   to.replay_time = options->replay_time;
2350 2350
   to.tcp_mode = link_socket_proto_connection_oriented (options->ce.proto);
2351
+  to.config_ciphername = c->c1.ciphername;
2352
+  to.config_authname = c->c1.authname;
2353
+  to.ncp_enabled = options->ncp_enabled;
2351 2354
   to.transition_window = options->transition_window;
2352 2355
   to.handshake_window = options->handshake_window;
2353 2356
   to.packet_timeout = options->tls_timeout;
... ...
@@ -81,7 +81,7 @@ bool do_test_crypto (const struct options *o);
81 81
 
82 82
 void context_gc_free (struct context *c);
83 83
 
84
-void do_up (struct context *c,
84
+bool do_up (struct context *c,
85 85
 	    bool pulled_options,
86 86
 	    unsigned int option_types_found);
87 87
 
... ...
@@ -91,7 +91,7 @@ const char *format_common_name (struct context *c, struct gc_arena *gc);
91 91
 
92 92
 void reset_coarse_timers (struct context *c);
93 93
 
94
-void do_deferred_options (struct context *c, const unsigned int found);
94
+bool do_deferred_options (struct context *c, const unsigned int found);
95 95
 
96 96
 void inherit_context_child (struct context *dest,
97 97
 			    const struct context *src);
... ...
@@ -210,6 +210,9 @@ struct context_1
210 210
   struct user_pass *auth_user_pass;
211 211
                                 /**< Username and password for
212 212
                                  *   authentication. */
213
+
214
+  const char *ciphername;	/**< Data channel cipher from config file */
215
+  const char *authname;		/**< Data channel auth from config file */
213 216
 #endif
214 217
 };
215 218
 
... ...
@@ -522,6 +522,8 @@ static const char usage_message[] =
522 522
   "--cipher alg    : Encrypt packets with cipher algorithm alg\n"
523 523
   "                  (default=%s).\n"
524 524
   "                  Set alg=none to disable encryption.\n"
525
+  "--ncp-ciphers list : List of ciphers that are allowed to be negotiated.\n"
526
+  "--ncp-disable   : Disable cipher negotiation.\n"
525 527
   "--prng alg [nsl] : For PRNG, use digest algorithm alg, and\n"
526 528
   "                   nonce_secret_len=nsl.  Set alg=none to disable PRNG.\n"
527 529
 #ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH
... ...
@@ -829,6 +831,12 @@ init_options (struct options *o, const bool init_gc)
829 829
 #ifdef ENABLE_CRYPTO
830 830
   o->ciphername = "BF-CBC";
831 831
   o->ciphername_defined = true;
832
+#ifdef HAVE_AEAD_CIPHER_MODES /* IV_NCP=2 requires GCM support */
833
+  o->ncp_enabled = true;
834
+#else
835
+  o->ncp_enabled = false;
836
+#endif
837
+  o->ncp_ciphers = "AES-256-GCM:AES-128-GCM";
832 838
   o->authname = "SHA1";
833 839
   o->authname_defined = true;
834 840
   o->prng_hash = "SHA1";
... ...
@@ -6637,7 +6645,7 @@ add_option (struct options *options,
6637 6637
     }
6638 6638
   else if (streq (p[0], "auth") && p[1] && !p[2])
6639 6639
     {
6640
-      VERIFY_PERMISSION (OPT_P_CRYPTO);
6640
+      VERIFY_PERMISSION (OPT_P_GENERAL);
6641 6641
       options->authname_defined = true;
6642 6642
       options->authname = p[1];
6643 6643
       if (streq (options->authname, "none"))
... ...
@@ -6648,12 +6656,12 @@ add_option (struct options *options,
6648 6648
     }
6649 6649
   else if (streq (p[0], "auth") && !p[1])
6650 6650
     {
6651
-      VERIFY_PERMISSION (OPT_P_CRYPTO);
6651
+      VERIFY_PERMISSION (OPT_P_GENERAL);
6652 6652
       options->authname_defined = true;
6653 6653
     }
6654 6654
   else if (streq (p[0], "cipher") && p[1] && !p[2])
6655 6655
     {
6656
-      VERIFY_PERMISSION (OPT_P_CRYPTO);
6656
+      VERIFY_PERMISSION (OPT_P_NCP);
6657 6657
       options->ciphername_defined = true;
6658 6658
       options->ciphername = p[1];
6659 6659
       if (streq (options->ciphername, "none"))
... ...
@@ -6664,12 +6672,22 @@ add_option (struct options *options,
6664 6664
     }
6665 6665
   else if (streq (p[0], "cipher") && !p[1])
6666 6666
     {
6667
-      VERIFY_PERMISSION (OPT_P_CRYPTO);
6667
+      VERIFY_PERMISSION (OPT_P_GENERAL);
6668 6668
       options->ciphername_defined = true;
6669 6669
     }
6670
+  else if (streq (p[0], "ncp-ciphers") && p[1] && !p[2])
6671
+    {
6672
+      VERIFY_PERMISSION (OPT_P_GENERAL);
6673
+      options->ncp_ciphers = p[1];
6674
+    }
6675
+  else if (streq (p[0], "ncp-disable") && !p[1])
6676
+    {
6677
+      VERIFY_PERMISSION (OPT_P_GENERAL);
6678
+      options->ncp_enabled = false;
6679
+    }
6670 6680
   else if (streq (p[0], "prng") && p[1] && !p[3])
6671 6681
     {
6672
-      VERIFY_PERMISSION (OPT_P_CRYPTO);
6682
+      VERIFY_PERMISSION (OPT_P_GENERAL);
6673 6683
       if (streq (p[1], "none"))
6674 6684
 	options->prng_hash = NULL;
6675 6685
       else
... ...
@@ -6691,12 +6709,12 @@ add_option (struct options *options,
6691 6691
     }
6692 6692
   else if (streq (p[0], "no-replay") && !p[1])
6693 6693
     {
6694
-      VERIFY_PERMISSION (OPT_P_CRYPTO);
6694
+      VERIFY_PERMISSION (OPT_P_GENERAL);
6695 6695
       options->replay = false;
6696 6696
     }
6697 6697
   else if (streq (p[0], "replay-window") && !p[3])
6698 6698
     {
6699
-      VERIFY_PERMISSION (OPT_P_CRYPTO);
6699
+      VERIFY_PERMISSION (OPT_P_GENERAL);
6700 6700
       if (p[1])
6701 6701
 	{
6702 6702
 	  int replay_window;
... ...
@@ -6736,12 +6754,12 @@ add_option (struct options *options,
6736 6736
     }
6737 6737
   else if (streq (p[0], "mute-replay-warnings") && !p[1])
6738 6738
     {
6739
-      VERIFY_PERMISSION (OPT_P_CRYPTO);
6739
+      VERIFY_PERMISSION (OPT_P_GENERAL);
6740 6740
       options->mute_replay_warnings = true;
6741 6741
     }
6742 6742
   else if (streq (p[0], "no-iv") && !p[1])
6743 6743
     {
6744
-      VERIFY_PERMISSION (OPT_P_CRYPTO);
6744
+      VERIFY_PERMISSION (OPT_P_GENERAL);
6745 6745
       options->use_iv = false;
6746 6746
     }
6747 6747
   else if (streq (p[0], "replay-persist") && p[1] && !p[2])
... ...
@@ -6771,7 +6789,7 @@ add_option (struct options *options,
6771 6771
     {
6772 6772
       int keysize;
6773 6773
 
6774
-      VERIFY_PERMISSION (OPT_P_CRYPTO);
6774
+      VERIFY_PERMISSION (OPT_P_NCP);
6775 6775
       keysize = atoi (p[1]) / 8;
6776 6776
       if (keysize < 0 || keysize > MAX_CIPHER_KEY_LENGTH)
6777 6777
 	{
... ...
@@ -6800,7 +6818,7 @@ add_option (struct options *options,
6800 6800
     }
6801 6801
   else if (streq (p[0], "ecdh-curve") && p[1] && !p[2])
6802 6802
     {
6803
-      VERIFY_PERMISSION (OPT_P_CRYPTO);
6803
+      VERIFY_PERMISSION (OPT_P_GENERAL);
6804 6804
       options->ecdh_curve= p[1];
6805 6805
     }
6806 6806
   else if (streq (p[0], "tls-server") && !p[1])
... ...
@@ -471,6 +471,8 @@ struct options
471 471
   int key_direction;
472 472
   bool ciphername_defined;
473 473
   const char *ciphername;
474
+  bool ncp_enabled;
475
+  const char *ncp_ciphers;
474 476
   bool authname_defined;
475 477
   const char *authname;
476 478
   int keysize;
... ...
@@ -615,7 +617,7 @@ struct options
615 615
 #define OPT_P_PERSIST_IP      (1<<9)
616 616
 #define OPT_P_COMP            (1<<10) /* TODO */
617 617
 #define OPT_P_MESSAGES        (1<<11)
618
-#define OPT_P_CRYPTO          (1<<12) /* TODO */
618
+#define OPT_P_NCP             (1<<12) /**< Negotiable crypto parameters */
619 619
 #define OPT_P_TLS_PARMS       (1<<13) /* TODO */
620 620
 #define OPT_P_MTU             (1<<14) /* TODO */
621 621
 #define OPT_P_NICE            (1<<15)
... ...
@@ -239,11 +239,20 @@ incoming_push_message (struct context *c, const struct buffer *buffer)
239 239
     {
240 240
       c->options.push_option_types_found |= option_types_found;
241 241
 
242
+      /* delay bringing tun/tap up until --push parms received from remote */
242 243
       if (status == PUSH_MSG_REPLY)
243
-	do_up (c, true, c->options.push_option_types_found ); /* delay bringing tun/tap up until --push parms received from remote */
244
+	{
245
+	  if (!do_up (c, true, c->options.push_option_types_found))
246
+	    {
247
+	      msg (D_PUSH_ERRORS, "Failed to open tun/tap interface");
248
+	      register_signal (c, SIGUSR1, "do_up-failed");
249
+	      goto cleanup;
250
+	    }
251
+	}
244 252
       event_timeout_clear (&c->c2.push_request_interval);
245 253
     }
246 254
 
255
+cleanup:
247 256
   gc_free (&gc);
248 257
 }
249 258
 
... ...
@@ -1640,6 +1640,24 @@ key_ctx_update_implicit_iv(struct key_ctx *ctx, uint8_t *key, size_t key_len) {
1640 1640
     }
1641 1641
 }
1642 1642
 
1643
+static bool
1644
+item_in_list(const char *item, const char *list)
1645
+{
1646
+  char *tmp_ciphers = string_alloc (list, NULL);
1647
+  char *tmp_ciphers_orig = tmp_ciphers;
1648
+
1649
+  const char *token = strtok (tmp_ciphers, ":");
1650
+  while(token)
1651
+    {
1652
+      if (0 == strcmp (token, item))
1653
+	break;
1654
+      token = strtok (NULL, ":");
1655
+    }
1656
+  free(tmp_ciphers_orig);
1657
+
1658
+  return token != NULL;
1659
+}
1660
+
1643 1661
 bool
1644 1662
 tls_session_update_crypto_params(struct tls_session *session,
1645 1663
     const struct options *options, struct frame *frame)
... ...
@@ -1650,6 +1668,15 @@ tls_session_update_crypto_params(struct tls_session *session,
1650 1650
   ASSERT (!session->opt->server);
1651 1651
   ASSERT (ks->authenticated);
1652 1652
 
1653
+  if (0 != strcmp(options->ciphername, session->opt->config_ciphername) &&
1654
+      !item_in_list(options->ciphername, options->ncp_ciphers))
1655
+    {
1656
+      msg (D_TLS_ERRORS, "Error: pushed cipher not allowed - %s not in %s or %s",
1657
+	  options->ciphername, session->opt->config_ciphername,
1658
+	  options->ncp_ciphers);
1659
+      return false;
1660
+    }
1661
+
1653 1662
   init_key_type (&session->opt->key_type, options->ciphername,
1654 1663
     options->ciphername_defined, options->authname, options->authname_defined,
1655 1664
     options->keysize, true, true);
... ...
@@ -1931,7 +1958,7 @@ push_peer_info(struct buffer *buf, struct tls_session *session)
1931 1931
       buf_printf(&out, "IV_PROTO=2\n");
1932 1932
 
1933 1933
       /* support for Negotiable Crypto Paramters */
1934
-      if (session->opt->pull)
1934
+      if (session->opt->ncp_enabled && session->opt->pull)
1935 1935
 	buf_printf(&out, "IV_NCP=2\n");
1936 1936
 
1937 1937
       /* push compression status */
... ...
@@ -273,6 +273,10 @@ struct tls_options
273 273
   int replay_time;                     /* --replay-window parm */
274 274
   bool tcp_mode;
275 275
 
276
+  const char *config_ciphername;
277
+  const char *config_authname;
278
+  bool ncp_enabled;
279
+
276 280
   /* packet authentication for TLS handshake */
277 281
   struct crypto_options tls_auth;
278 282