Index: openvpn-2.1.3/init.c =================================================================== --- openvpn-2.1.3.orig/init.c 2010-07-21 21:08:41.000000000 +0200 +++ openvpn-2.1.3/init.c 2010-09-29 13:11:02.373457337 +0200 @@ -1796,6 +1796,29 @@ 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 (); + int ret; + argv_printf (&argv, "/usr/sbin/openvpn-vulnkey -q %s", options->shared_secret_file); + argv_msg (M_INFO, &argv); + ret = openvpn_execve (&argv, c->c2.es, 0); + if (WEXITSTATUS (ret) == 1) + { + msg (M_WARN, "******* WARNING *******: '%s' is a known vulnerable key. See 'man openvpn-vulnkey' for details.", options->shared_secret_file); + } + else if (WEXITSTATUS (ret) != 0) + { + msg (M_WARN, "******* WARNING *******: '%s' cannot be verified as a non-vulnerable key. See 'man openvpn-vulnkey' for details.", options->shared_secret_file); + } + argv_reset (&argv); + } + init_crypto_pre (c, flags); /* Initialize packet ID tracking */ @@ -1881,6 +1904,7 @@ do_init_crypto_tls_c1 (struct context *c) { const struct options *options = &c->options; + SSL *ssl; if (!c->c1.ks.ssl_ctx) { @@ -1920,6 +1944,59 @@ /* 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) + { + int ret; + 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 ", bits); + ret = openvpn_execve (&argv, NULL, 0); + if (WEXITSTATUS (ret) == 1) + { + msg (M_WARN, "******* WARNING *******: '%s' is a known vulnerable key. See 'man openssl-vulnkey' for details.", options->priv_key_file); + } + else if (WEXITSTATUS (ret) != 0) + { + msg (M_WARN, "******* WARNING *******: '%s' cannot be verified as a non-vulnerable key. See 'man openssl-vulnkey' for details.", options->priv_key_file); + } + argv_reset (&argv); + } + EVP_PKEY_free (pkey); + } + } + SSL_free(ssl); + } + /* TLS handshake authentication (--tls-auth) */ if (options->tls_auth_file) {