Repository: certbot/certbot

Issue:
Expand ignores new domains
A number of users on the community forum reported that they were having difficulties while trying to expand existing certificates. I was able to reproduce on a clean Ubuntu 16.04 installation, using `certbot` 0.10.0. I tested standalone and apache, so it's probably not plugin-specific.

Commands to reproduce, including output:
```
root@debug:~# ./certbot-auto certonly --standalone -d 1.debug.le.pf.vc -d 2.debug.le.pf.vc --staging --register-unsafely-without-email
Obtaining a new certificate
Performing the following challenges:
tls-sni-01 challenge for 1.debug.le.pf.vc
tls-sni-01 challenge for 2.debug.le.pf.vc
Waiting for verification...
Cleaning up challenges
Generating key (2048 bits): /etc/letsencrypt/keys/0000_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0000_csr-certbot.pem

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/1.debug.le.pf.vc/fullchain.pem. Your cert
   will expire on 2017-04-13. To obtain a new or tweaked version of
   this certificate in the future, simply run certbot-auto again. To
   non-interactively renew *all* of your certificates, run
   "certbot-auto renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.

root@debug:~# ./certbot-auto certonly --standalone -d 1.debug.le.pf.vc -d 2.debug.le.pf.vc -d 3.debug.le.pf.vc --staging --register-unsafely-without-email
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
You have an existing certificate that contains a portion of the domains you
requested (ref: /etc/letsencrypt/renewal/1.debug.le.pf.vc.conf)

It contains these names: 1.debug.le.pf.vc, 2.debug.le.pf.vc

You requested these names for the new certificate: 1.debug.le.pf.vc,
2.debug.le.pf.vc, 3.debug.le.pf.vc.

Do you want to expand and replace this existing certificate with the new
certificate?
-------------------------------------------------------------------------------
(E)xpand/(C)ancel: e
Renewing an existing certificate
Performing the following challenges:
tls-sni-01 challenge for 1.debug.le.pf.vc
tls-sni-01 challenge for 2.debug.le.pf.vc
Waiting for verification...
Cleaning up challenges
Generating key (2048 bits): /etc/letsencrypt/keys/0001_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0001_csr-certbot.pem

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/1.debug.le.pf.vc/fullchain.pem. Your cert
   will expire on 2017-04-13. To obtain a new or tweaked version of
   this certificate in the future, simply run certbot-auto again. To
   non-interactively renew *all* of your certificates, run
   "certbot-auto renew"

root@debug:~# openssl x509 -text -noout -in /etc/letsencrypt/live/1.debug.le.pf.vc/cert.pem | grep DNS
                DNS:1.debug.le.pf.vc, DNS:2.debug.le.pf.vc
```

Original reports:
https://community.letsencrypt.org/t/expands-not-working-on-pre-existing-cert-requests/25605?u=pfg
https://community.letsencrypt.org/t/workaround-for-5-domain-limit/25651?u=pfg


Discussion:
Thanks for the bug report @patf. We hope to have this fixed today.

Resolving patch:
diff --git a/certbot/main.py b/certbot/main.py
--- a/certbot/main.py
+++ b/certbot/main.py
@@ -100,7 +100,7 @@ def _auth_from_available(le_client, config, domains=None, certname=None, lineage
     try:
         if action == "renew":
             logger.info("Renewing an existing certificate")
-            renewal.renew_cert(config, le_client, lineage)
+            renewal.renew_cert(config, domains, le_client, lineage)
         elif action == "newcert":
             # TREAT AS NEW REQUEST
             logger.info("Obtaining a new certificate")
diff --git a/certbot/renewal.py b/certbot/renewal.py
--- a/certbot/renewal.py
+++ b/certbot/renewal.py
@@ -263,12 +263,14 @@ def _avoid_invalidating_lineage(config, lineage, original_server):
                     "unless you use the --break-my-certs flag!".format(names))
 
 
-def renew_cert(config, le_client, lineage):
+def renew_cert(config, domains, le_client, lineage):
     "Renew a certificate lineage."
     renewal_params = lineage.configuration["renewalparams"]
     original_server = renewal_params.get("server", cli.flag_default("server"))
     _avoid_invalidating_lineage(config, lineage, original_server)
-    new_certr, new_chain, new_key, _ = le_client.obtain_certificate(lineage.names())
+    if not domains:
+        domains = lineage.names()
+    new_certr, new_chain, new_key, _ = le_client.obtain_certificate(domains)
     if config.dry_run:
         logger.debug("Dry run: skipping updating lineage at %s",
                     os.path.dirname(lineage.cert))
@@ -281,7 +283,7 @@ def renew_cert(config, le_client, lineage):
         lineage.save_successor(prior_version, new_cert, new_key.pem, new_chain, config)
         lineage.update_all_links_to(lineage.latest_common_version())
 
-    hooks.renew_hook(config, lineage.names(), lineage.live_dir)
+    hooks.renew_hook(config, domains, lineage.live_dir)
 
 
 def report(msgs, category):


Test patch: