Repository: certbot/certbot

Issue:
With multiple domains, key mismatch for snakeoil cert
```
letsencrypt --server http://localhost:4000/directory --no-verify-ssl --dvsni-port 5001 --simple-http-port 5001           --text         --agree-eula         --agree-tos         --email "" --authenticator nginx -d yo.wtf -d foo.wtf auth  

...
2015-10-07 22:20:07,914:ERROR:letsencrypt_nginx.configurator:Nginx Restart Failed!
nginx: [emerg] SSL_CTX_use_PrivateKey_file("/var/lib/letsencrypt/snakeoil/0037_key.pem") failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch)
```

This doesn't happen with a single domain. Poking around, it looks like multiple snakeoil keys are created but only one cert, which is probably the reason for the mismatch.



Discussion:
I'm also getting this error. I invoked the client simply with "letsencrypt", having the nginx plugin installed, and selected multiple domains. Then I get this error:

```
2015-12-03 23:25:45,174:ERROR:letsencrypt_nginx.configurator:Nginx Restart Failed!

2015/12/03 23:25:45 [emerg] 25958#0: SSL_CTX_use_PrivateKey_file("/var/lib/letsencrypt/snakeoil/0016_key.pem") failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch)
```

And after that:

```
Correct zName not found for TLS SNI challenge.
```

For a single domain, it also works for me.

i've seen this issue on an ubuntu server with openssl 1.0.1f but moving the cert and key to a parabola server with openssl 1.0.2d worked correctly

but i got the same error on ubuntu wily with openssl 1.0.2d

I'm using Arch Linux, and have tried openssl 1.0.2d and 1.0.2e.

well it may be a nginx error since the same cert loaded+worked fine with dovecot, postfix and prosody

fails in debian jessie with libssl 1.0.1k and both nginx 1.6 from debian and nginx 1.8 from phusion passenger...

@jsha these are not the snakeoil certs, could you edit the title?

@fauno: Could you explain more? You mean the problem is using a snakeoil key with a non-snakeoil cert? 

Jacob Hoffman-Andrews notifications@github.com writes:

> @fauno: Could you explain more? You mean the problem is using a
> snakeoil key with a non-snakeoil cert?

you reported the issue for the snakeoil certs, but i'm having the same
error with the production certs.

have you solved it?

## 

:>

Ah, now I get it. The issue is not regarding the staging certs ("happy hacker fake CA"), but regarding the self-signed (snakeoil) certs that the letsencrypt client creates locally to solve the TLS-SNI challenge.

the error i see is with the live certs:

```
nginx: [emerg] SSL_CTX_use_PrivateKey_file("/etc/letsencrypt/live/domain.com/privkey.pem") failed (SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch)
```

## 

http://librevpn.org.ar

That's a different problem, probably related to the configuration of your Nginx. Please post about it on https://community.letsencrypt.org/, including the relevant sections of your Nginx configuration.

done: https://community.letsencrypt.org/t/key-values-mismatch-error-using-live-certs-on-nginx/7029


Resolving patch:
diff --git a/letsencrypt-nginx/letsencrypt_nginx/configurator.py b/letsencrypt-nginx/letsencrypt_nginx/configurator.py
--- a/letsencrypt-nginx/letsencrypt_nginx/configurator.py
+++ b/letsencrypt-nginx/letsencrypt_nginx/configurator.py
@@ -310,10 +310,10 @@ def _get_snakeoil_paths(self):
         key = OpenSSL.crypto.load_privatekey(
             OpenSSL.crypto.FILETYPE_PEM, le_key.pem)
         cert = acme_crypto_util.gen_ss_cert(key, domains=[socket.gethostname()])
-        cert_path = os.path.join(tmp_dir, "cert.pem")
         cert_pem = OpenSSL.crypto.dump_certificate(
             OpenSSL.crypto.FILETYPE_PEM, cert)
-        with open(cert_path, 'w') as cert_file:
+        cert_file, cert_path = le_util.unique_file(os.path.join(tmp_dir, "cert.pem"))
+        with cert_file:
             cert_file.write(cert_pem)
         return cert_path, le_key.file
 
diff --git a/letsencrypt/crypto_util.py b/letsencrypt/crypto_util.py
--- a/letsencrypt/crypto_util.py
+++ b/letsencrypt/crypto_util.py
@@ -53,8 +53,8 @@ def init_save_key(key_size, key_dir, keyname="key-letsencrypt.pem"):
                                config.strict_permissions)
     key_f, key_path = le_util.unique_file(
         os.path.join(key_dir, keyname), 0o600)
-    key_f.write(key_pem)
-    key_f.close()
+    with key_f:
+        key_f.write(key_pem)
 
     logger.info("Generating key (%d bits): %s", key_size, key_path)
 


Test patch: