Hello!

Here is a possible fix to the bug, which checks the openssl-vulnkey return
code for more than just non-zero.

Jamie, does this look okay to you?  I haven't actually tested this myself,
as I'm travelling at the moment.

Thanks,

-Kees

-- 
Kees Cook                                            @debian.org
Description: call out to openssl-vulnkey to verify that OpenVPN key in
 use has not been affected by CVE-2008-0166 (Debian weak key checks).
Author: Jamie Strandboge <ja...@ubuntu.com>

Index: openvpn-2.1~rc19/init.c
===================================================================
--- openvpn-2.1~rc19.orig/init.c	2009-06-01 12:55:25.000000000 -0700
+++ openvpn-2.1~rc19/init.c	2009-10-29 21:36:00.000000000 -0700
@@ -1537,6 +1537,30 @@
   const struct options *options = &c->options;
   ASSERT (options->shared_secret_file);
 
+  /* CVE-2008-0166 (Debian weak key checks) */
+  /* Only check if we can actually read the key file. Unless the file does not
+   * exist in the first place, this should never happen (since static keys do
+   * not work with multi-client mode), but we test it anyway to be on the safe
+   * side and avoid wrong -vulnkey alerts. */
+  if (access (options->shared_secret_file, R_OK) == 0)
+    {
+      struct argv argv = argv_new ();
+      argv_printf (&argv, "/usr/sbin/openvpn-vulnkey -q %s", options->shared_secret_file);
+      argv_msg (M_INFO, &argv);
+      switch (openvpn_execve (&argv, c->c2.es, 0))
+        {
+          case 0:
+              break;
+          case 1:
+              msg (M_WARN, "******* WARNING *******: '%s' is a known vulnerable key. See 'man openvpn-vulnkey' for details.", options->shared_secret_file);
+              break;
+          default:
+              msg (M_WARN, "******* WARNING *******: '%s' cannot be verified as a non-vulnerable key. See 'man openvpn-vulnkey' for details.", options->shared_secret_file);
+              break;
+        }
+      argv_reset (&argv);
+    }
+
   init_crypto_pre (c, flags);
 
   /* Initialize packet ID tracking */
@@ -1622,6 +1646,7 @@
 do_init_crypto_tls_c1 (struct context *c)
 {
   const struct options *options = &c->options;
+  SSL *ssl;
 
   if (!c->c1.ks.ssl_ctx)
     {
@@ -1661,6 +1686,60 @@
       /* Initialize PRNG with config-specified digest */
       prng_init (options->prng_hash, options->prng_nonce_secret_len);
 
+      /* CVE-2008-0166 (Debian weak key checks)
+       * Obtain the modulus and bits from the certificate that was initialized,
+       * and send that to openssl-vulnkey.
+       */
+      ssl = SSL_new(c->c1.ks.ssl_ctx);
+      if (ssl != NULL)
+        {
+          X509* cert = NULL;
+          char *bn;
+          int bits;
+
+          cert = SSL_get_certificate(ssl);
+          if (cert != NULL)
+            {
+              EVP_PKEY *pkey = X509_get_pubkey (cert);
+              if (pkey != NULL)
+                {
+                  if (pkey->type == EVP_PKEY_RSA && pkey->pkey.rsa != NULL
+                      && pkey->pkey.rsa->n != NULL)
+                    {
+                      bits = BN_num_bits(pkey->pkey.rsa->n);
+                      bn = BN_bn2hex(pkey->pkey.rsa->n);
+                    }
+                  else if (pkey->type == EVP_PKEY_DSA && pkey->pkey.dsa != NULL
+                           && pkey->pkey.dsa->p != NULL)
+                    {
+                      bits = BN_num_bits(pkey->pkey.dsa->p);
+                      bn = BN_bn2hex(pkey->pkey.dsa->p);
+                    }
+                  if (bn != NULL)
+                    {
+                      struct argv argv = argv_new ();
+                      argv_printf (&argv, "/usr/bin/openssl-vulnkey -q -b %d -m %s", bits, bn);
+                      OPENSSL_free(bn);
+                      msg (M_INFO, "/usr/bin/openssl-vulnkey -q -b %d -m <modulus omitted>", bits);
+                      switch (openvpn_execve (&argv, NULL, 0) != 0)
+                        {
+                          case 0:
+                              break;
+                          case 1:
+                              msg (M_WARN, "******* WARNING *******: '%s' is a known vulnerable key. See 'man openvpn-vulnkey' for details.", options->shared_secret_file);
+                              break;
+                          default:
+                              msg (M_WARN, "******* WARNING *******: '%s' cannot be verified as a non-vulnerable key. See 'man openvpn-vulnkey' for details.", options->shared_secret_file);
+                              break;
+                        }
+                      argv_reset (&argv);
+                    }
+                  EVP_PKEY_free (pkey);
+               }
+            }
+            SSL_free(ssl);
+         }
+
       /* TLS handshake authentication (--tls-auth) */
       if (options->tls_auth_file)
 	{

Reply via email to