twisted / txacme

Twisted client for the ACME (Automatic Certificate Management Environment) protocol
MIT License
45 stars 23 forks source link

subjectAlternativeName support (eg www.example.org also gets a sAN example.org) #37

Open twopir opened 8 years ago

twopir commented 8 years ago

It'd be incredibly convenient if txacme would, when renewing a certificate whose name starts with www, request that the cert contain a subjectAlternativeName without the www.

mithrandi commented 8 years ago

Dumping some intermediate thoughts, since I haven't fully solved this yet.

There seem to be (at least) two ways to handle this:

  1. Hardcode the handling; for example, a flag that turns on issuing having www.example.com as an extra sAN for every example.com cert. I don't much like this, because while www. is an extremely common subdomain, it's hardly the only one that exists. It's also aesthetically unpleasant to hardcode something like this.
  2. Encode the information about extra sANs in the certificate store. If the certificate store is some arbitrary database, this is relatively easy to do. But how do we handle this in the case of DirectoryStore?
    1. Use symlinks to link secondary names to the primary name.
      • Pro: Handles the txsni end of things without extra effort
      • Pro: Does not require extra tools to configure
      • Con: Too "cutesy"
      • Con: Not viable on Windows
    2. Use the existing certificate information
      • Pro: Makes it easy to migrate from existing certificates
      • Con: Harder to populate the txsni mapping
      • Con: Harder to configure (the touch trick wouldn't suffice anymore, some tool to generate a multi-name cert to start would be needed)
warner commented 7 years ago

Not necessarily a good idea, but what about adding an endpoint parameter that points to a .toml/.json/etc file with additional configuration preferences, including an "include www." flag for each listed domain name? e.g. le:~/certdata:configfile=~/certs.json:tcp:443

Or better, reserve a .json filename in the DirectoryStore for this metadata? It could have a "defaults" section, plus a section for each domain name, and then flags in each section. "add www." would be one flag, but maybe decisions about renewal frequency or challenge mode could be there too.

adiroiban commented 6 years ago

I am -1 on hardcoding www or adding an external toml file configuration.

I am ok with reserving a .json for the default DirectoryStore implementaiton. I am using a different directory store anyway :)


In terms of AcmeIssuingService API, maybe we can have:

  1. AcmeIssuingService.issue_cert(server_name, sans=None) sans can be a list of domain names, to trigger a sANs certificate. In this case server_name is used as certificate_name. So you end up calling AcmeIssuingService.issue_cert('my-server-x', ['domain.com', 'www.domain.com', 'open.domain.com']) .

  2. AcmeIssuingService.issue_sans(cert_name, [domain.com, www.domain.com, open.domain.com]) and then AcmeIssuingService.issue_cert can call AcmeIssuingService.issue_sans(server_name, [server_name])

  3. There is also the option of doing something like AcmeIssuingService.issue_cert(server_name, cert_name=None) where server_name can be Unicode or a list of unicodes. When is a list, it will trigger the SAN behaviour and cert_name is required. It can end up with a call lilk AcmeIssuingService.issue_cert([domain.com, www.domain.com, open.domain.com], cert_name)

I prefer option 2 as is explicit. The issue_sans name can be changed, but the main idea is to have a separate API for sANs certificates.


In terms of ICertificateStore interface with support for sANs, I think that we can continue to use the same interfance, but instead of server_name as the storage key, use cert_name.

I am looking at certbot https://github.com/certbot/certbot/blob/b50abddb5f144d0570ce57dfa87804e781037175/docs/cli-help.txt#L70 and I see that they have Certificate name and they use that name to create the persisted file name.

So ICertificateStore can index the stored objects based on a certificate name and not on the server_name (domain).

Beside renaming server_name to cert_name, I don't think there is other API change in ICertificateStore


I have not yet checked Client.request_challenges(identifier) to see how it can be extended for sANs.

adiroiban commented 5 years ago

In the end I added SAN support in a quick and dirty way ... but it works :) ... see https://github.com/twisted/txacme/compare/37-san-support

Instead of server_name I am using the storage key with the semantics of certificate_name. Certificate name can be a comma separated value of domain names.

I am using a simple in-memory dict based storage, but I guess that this also works with file based storage.

In this way, the API is not changed and is backward compatible.

If you want to use SAN certificates, just use comma separated domains.

I guess that "space" can also be used instead of "comma" character as the delimiter.

glyph commented 5 years ago

comma works for me; it's not valid in DNS names :)