Browse code

Refactor static/tls-auth key loading

Remove duplicate code, in preparation for adding --tls-crypt, which
otherwise would have to duplicate this code again.

This should be equivalent to the old code, except for two things:
* The log lines for static key initialization change slightly, from
"Static Encrypt/Decrypt" to "Incoming/Outgoing Static Key Encryption"
* We also 'check and fix highly unlikely key problems' for tls-auth
keys (boils down to a sanity-check for an all-zero key).

Signed-off-by: Steffan Karger <steffan.karger@fox-it.com>
Acked-by: Arne Schwabe <arne@rfc2549.org>
Message-Id: <1478636302-9678-2-git-send-email-steffan.karger@fox-it.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg12969.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>

Steffan Karger authored on 2016/11/09 05:18:18
Showing 3 changed files
... ...
@@ -1103,48 +1103,45 @@ test_crypto (struct crypto_options *co, struct frame* frame)
1103 1103
 }
1104 1104
 
1105 1105
 void
1106
-get_tls_handshake_key (const struct key_type *key_type,
1107
-		       struct key_ctx_bi *ctx,
1108
-		       const char *key_file,
1109
-		       const int key_direction,
1110
-		       const unsigned int flags)
1106
+crypto_read_openvpn_key (const struct key_type *key_type,
1107
+	struct key_ctx_bi *ctx, const char *key_file, const char *key_inline,
1108
+	const int key_direction, const char *key_name, const char *opt_name)
1111 1109
 {
1112
-  if (key_file)
1113
-    {
1114
-      struct key2 key2;
1115
-      struct key_direction_state kds;
1116
-
1117
-      if (flags & GHK_INLINE)
1118
-	{
1119
-	  read_key_file (&key2, key_file, RKF_INLINE|RKF_MUST_SUCCEED);
1120
-	}
1121
-      else
1122
-	{
1123
-	  read_key_file (&key2, key_file, RKF_MUST_SUCCEED);
1124
-	}
1125
-
1126
-	if (key2.n != 2)
1127
-	  {
1128
-	    msg (M_ERR, "Control Channel Authentication: File '%s' does not "
1129
-		"have OpenVPN Static Key format.  Using free-form passphrase "
1130
-		"file is not supported anymore.", key_file);
1131
-	  }
1132
-      /* handle key direction */
1133
-      key_direction_state_init (&kds, key_direction);
1134
-      must_have_n_keys (key_file, "tls-auth", &key2, kds.need_keys);
1110
+  struct key2 key2;
1111
+  struct key_direction_state kds;
1112
+  char log_prefix[128] = { 0 };
1135 1113
 
1136
-      /* initialize key in both directions */
1137
-      init_key_ctx (&ctx->encrypt, &key2.keys[kds.out_key], key_type, OPENVPN_OP_ENCRYPT,
1138
-		    "Outgoing Control Channel Authentication");
1139
-      init_key_ctx (&ctx->decrypt, &key2.keys[kds.in_key], key_type, OPENVPN_OP_DECRYPT,
1140
-		    "Incoming Control Channel Authentication");
1141
-
1142
-      CLEAR (key2);
1114
+  if (key_inline)
1115
+    {
1116
+      read_key_file (&key2, key_inline, RKF_MUST_SUCCEED|RKF_INLINE);
1143 1117
     }
1144 1118
   else
1145 1119
     {
1146
-      CLEAR (*ctx);
1120
+      read_key_file (&key2, key_file, RKF_MUST_SUCCEED);
1121
+    }
1122
+
1123
+  if (key2.n != 2)
1124
+    {
1125
+      msg (M_ERR, "File '%s' does not have OpenVPN Static Key format.  Using "
1126
+	   "free-form passphrase file is not supported anymore.", key_file);
1147 1127
     }
1128
+
1129
+  /* check for and fix highly unlikely key problems */
1130
+  verify_fix_key2 (&key2, key_type, key_file);
1131
+
1132
+  /* handle key direction */
1133
+  key_direction_state_init (&kds, key_direction);
1134
+  must_have_n_keys (key_file, opt_name, &key2, kds.need_keys);
1135
+
1136
+  /* initialize key in both directions */
1137
+  openvpn_snprintf (log_prefix, sizeof (log_prefix), "Outgoing %s", key_name);
1138
+  init_key_ctx (&ctx->encrypt, &key2.keys[kds.out_key], key_type,
1139
+		OPENVPN_OP_ENCRYPT, log_prefix);
1140
+  openvpn_snprintf (log_prefix, sizeof (log_prefix), "Incoming %s", key_name);
1141
+  init_key_ctx (&ctx->decrypt, &key2.keys[kds.in_key], key_type,
1142
+		OPENVPN_OP_DECRYPT, log_prefix);
1143
+
1144
+  CLEAR (key2);
1148 1145
 }
1149 1146
 
1150 1147
 /* header and footer for static key file */
... ...
@@ -465,12 +465,9 @@ void key2_print (const struct key2* k,
465 465
 		 const char* prefix0,
466 466
 		 const char* prefix1);
467 467
 
468
-#define GHK_INLINE  (1<<0)
469
-void get_tls_handshake_key (const struct key_type *key_type,
470
-			    struct key_ctx_bi *ctx,
471
-			    const char *passphrase_file,
472
-			    const int key_direction,
473
-			    const unsigned int flags);
468
+void crypto_read_openvpn_key (const struct key_type *key_type,
469
+	struct key_ctx_bi *ctx, const char *key_file, const char *key_inline,
470
+	const int key_direction, const char *key_name, const char *opt_name);
474 471
 
475 472
 /*
476 473
  * Inline functions
... ...
@@ -2147,33 +2147,11 @@ do_init_crypto_static (struct context *c, const unsigned int flags)
2147 2147
 		     options->keysize, options->test_crypto, true);
2148 2148
 
2149 2149
       /* Read cipher and hmac keys from shared secret file */
2150
-      {
2151
-	unsigned int rkf_flags = RKF_MUST_SUCCEED;
2152
-	const char *rkf_file = options->shared_secret_file;
2153
-
2154
-	if (options->shared_secret_file_inline)
2155
-	  {
2156
-	    rkf_file = options->shared_secret_file_inline;
2157
-	    rkf_flags |= RKF_INLINE;
2158
-	  }
2159
-	read_key_file (&key2, rkf_file, rkf_flags);
2160
-      }
2161
-
2162
-      /* Check for and fix highly unlikely key problems */
2163
-      verify_fix_key2 (&key2, &c->c1.ks.key_type,
2164
-		       options->shared_secret_file);
2165
-
2166
-      /* Initialize OpenSSL key objects */
2167
-      key_direction_state_init (&kds, options->key_direction);
2168
-      must_have_n_keys (options->shared_secret_file, "secret", &key2,
2169
-			kds.need_keys);
2170
-      init_key_ctx (&c->c1.ks.static_key.encrypt, &key2.keys[kds.out_key],
2171
-		    &c->c1.ks.key_type, OPENVPN_OP_ENCRYPT, "Static Encrypt");
2172
-      init_key_ctx (&c->c1.ks.static_key.decrypt, &key2.keys[kds.in_key],
2173
-		    &c->c1.ks.key_type, OPENVPN_OP_DECRYPT, "Static Decrypt");
2174
-
2175
-      /* Erase the temporary copy of key */
2176
-      CLEAR (key2);
2150
+      crypto_read_openvpn_key (&c->c1.ks.key_type, &c->c1.ks.static_key,
2151
+			       options->shared_secret_file,
2152
+			       options->shared_secret_file_inline,
2153
+			       options->key_direction, "Static Key Encryption",
2154
+			       "secret");
2177 2155
     }
2178 2156
   else
2179 2157
     {
... ...
@@ -2242,15 +2220,6 @@ do_init_crypto_tls_c1 (struct context *c)
2242 2242
       /* TLS handshake authentication (--tls-auth) */
2243 2243
       if (options->tls_auth_file)
2244 2244
 	{
2245
-	  unsigned int flags = 0;
2246
-	  const char *file = options->tls_auth_file;
2247
-
2248
-	  if (options->tls_auth_file_inline)
2249
-	    {
2250
-	      flags |= GHK_INLINE;
2251
-	      file = options->tls_auth_file_inline;
2252
-	    }
2253
-
2254 2245
 	  /* Initialize key_type for tls-auth with auth only */
2255 2246
 	  CLEAR (c->c1.ks.tls_auth_key_type);
2256 2247
 	  if (!streq (options->authname, "none"))
... ...
@@ -2265,8 +2234,10 @@ do_init_crypto_tls_c1 (struct context *c)
2265 2265
 		  "algorithm specified ('%s')", options->authname);
2266 2266
 	    }
2267 2267
 
2268
-	  get_tls_handshake_key (&c->c1.ks.tls_auth_key_type,
2269
-	      &c->c1.ks.tls_auth_key, file, options->key_direction, flags);
2268
+	  crypto_read_openvpn_key (&c->c1.ks.tls_auth_key_type,
2269
+	      &c->c1.ks.tls_auth_key, options->tls_auth_file,
2270
+	      options->tls_auth_file_inline, options->key_direction,
2271
+	      "Control Channel Authentication", "tls-auth");
2270 2272
 	}
2271 2273
 
2272 2274
       c->c1.ciphername = options->ciphername;