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) {