Certificates for certain purposes should contain additional attributes, e.g. for XMPP, cf. this and that. It would be nice if the CA supported issuing certificates containing such attributes from CSRs without stripping the recommended attributes.
This is a follow up issue of https://github.com/letsencrypt/letsencrypt/issues/2032
This should probably be retitled "Support SRV-ID". Which would indeed be nice.
I suppose certificates for any SRV-ID should be offered if hostname control is proven. You can still control the dissemination of certificates to different daemons, giving SRV-ID a small amount of meaning.
If boulder has an authorization for DNS-name XXX, I believe should allow _X509v3 Subject Alternative Names_ in the following form:
For XMPP, this is:
SRV-ID support is a major requirement for allowing XMPP-server-as-a-service implementations. If I am the owner of company.example and I want cheapxmpp.example to run my XMPP service, currently I need to provide them with a key/certificate that they could use to impersonate the company.example webserver.
If the owner of company.example was able to get a cert with SRV-ID SANs _xmpp-client.company.example and _xmpp-server.company.example (but no DNS-IDs / hostname CN), that cert could be used for delegating XMPP in a secure way.
@ge0rg This is interesting. This suggests that rather than granting SRV-ID when hostname control is proven, as I suggested above, the ACME protocol should be extended so that authorization for a SRV-ID can be obtained explicitly.
There is one hiccup with challenges; a SRV-ID does not specify a transport layer protocol but SRV does, so this change to the spec would need to specify some mapping for the purposes of name resolution for the purposes of challenge verification. A simple solution would be to always use TCP, which makes sense since all challenge methods which connect to the host use it anyway.
@hlandau I consciously left out ACME from my prior comment to reduce confusion. The alternative approach would be indeed to extend ACME in a way that allows limiting domain authorization to a certain service type, using that type of service for challenge verificattion in the first place, i.e. make the ACME server contact the XMPP server via XMPP to obtain an XMPP-only certificate. But this looks like a much bigger implementation burden to me, compared to letting the domain owner do the hard work. On the other hand, it would make certificate automation feasible.
I haven't looked deeply into DNS-based verification yet, but I could also imagine something along the lines of:
_xmpp-server._tcp.company.example IN SRV ... xmpp.cheapxmpp.example_xmpp-server._tcp.company.example_acme-challenge.xmpp.cheapxmpp.example/TXT_xmpp-server.company.example only, not for DNS-ID company.example[...] a SRV-ID does not specify a transport layer protocol but SRV does, [...]
Indeed, SRV-ID is protocol agnostic, but I think you are right that it makes sense to use TCP for challenge verification, as it is less susceptible to address manipulation attacks.
I understand that this issue was not filed against the ACME protocol spec, but despite the risk of confusion I think it's worth discussing how the protocol would interact with this feature. Obviously the CA shouldn't blindly trust SRVName subject alternative names in CSRs, so the protocol must be involved somehow.
- The ACME server follows the SRV record and expects the challenge response to be located under
_acme-challenge.xmpp.cheapxmpp.example/TXT
I'm assuming that in your example the ACME server chose _acme-challenge.xmpp.cheapxmpp.example because xmpp.cheapxmpp.example is the name in the _xmpp-server._tcp.company.example SRV record. Is that correct?
If so, this would require cheapxmpp.example to set up that DNS record. Setting up that DNS record might not be feasible if cheapxmpp.example is a 3rd party (outsourced service).
Fortunately, it is not necessary to involve cheapxmpp.example because the name of the target in the SRV record doesn't matter when validating the certificate. Theoretically, company.example could later switch outsourced XMPP services to a different 3rd party, change the SRV records, and still use the same certificate.
Validating a request for a SRVName SAN of _Service.example.com is really the same as validating control over example.com, so the same mechanism used to issue ordinary example.com certificates can be used.
How about this procedure:
_Service.example.comexample.comcn=example.com:example.comcn=example.com, do NOT use a Subject of the form cn=example.com in the resulting certificate and do NOT add a dNSName SAN (to prevent an outsourced XMPP service from being able to impersonate the customer's other services)cn=example.com, add a dNSName SAN for example.com if one does not already existcn=example.com, then set the Subject to have the form cn=example.com where example.com is the DNS name in the first dNSName SANSuppose a company owns example.com and has Jabber IDs of the form [email protected]. They have the following DNS records for the XMPP service:
_xmpp-client._tcp.example.com IN SRV 0 0 5222 xmpp.example.com
_xmpp-server._tcp.example.com IN SRV 0 0 5269 xmpp.example.com
_xmpp-server._tcp.conference.example.com IN SRV 0 0 5269 xmpp.example.com
_xmppconnect.example.com IN TXT "_xmpp-client-xbosh=https://xmpp.example.com:5280/http-bind"
The entire ACME process could look like this:
_acme-verify._tcp.example.com IN SRV 0 0 49152 acme.example.com
_acme-verify._tcp.xmpp.example.com IN SRV 0 0 49152 acme.example.com
_acme-verify._tcp.conference.example.com IN SRV 0 0 49152 acme.example.com
acme.example.com and configures it to expect challenges on port 49152Name in xmpp.example.com, example.com, conference.example.com:Name_acme-verify._tcp.Name and gets back a reply of acme.example.com port 49152acme.example.com port 49152Name to the clientcn=xmpp.example.comxmpp.example.com_xmpp-client.example.com_xmpp-server.example.com_xmpp-server.conference.example.comxmpp.example.com, example.com, and conference.example.com@rhanden I'm not really sure where you are heading to. The issue I want to solve is delegation of (XMPP) service operations without exposing a full DNS-ID certificate to third parties. I see two alternative approaches to solve this problem:
The domain owner of company.example requests a certificate with an SRV-ID SAN and no DNS-ID/hostname CN, i.e. based on a CSR from the actual XMPP service provider.
The domain owner already has proven ownership (by means that are out of scope for the discussion). Therefore they are eligible to a certificate containing any valid SRV-IDs for their domain, as the SRV-ID is a weaker ownership assertion than the DNS-ID they can get under the currrent rules.
This approach does not require touching the ACME protocol, but it can not be as easily automated, as the domain owner and service operator need to collaborate for each new certificate. It also precludes the service operator from getting a single certificate containing SRV-IDs for multiple customers. Still, this can be probably achieved with a bunch of cronjobs at both parties, and I would consider this a reasonable short-term solution to the problem.
The only possible restriction I can see here is a whitelist of allowed service names that can be prepended to the domain part.
Of course it would be much easier (to automate) if the service operator (cheapxmpp.example) can directly get appropriate certificates from the CA. However, if we allow the service operator to authenticate for the domain, they could easily get a DNS-ID certificate that they could use to attack the domain's other services (web, email, ...).
Therefore I sketched a proposal to allow the service operator to prove "service ownership" to the CA, i.e. "I am operating the XMPP service(s) for company.example". This service ownership in turn will permit the operator to directly request SRV-ID certificates for the given service from the CA, but not a DNS-ID certificate for company.example.
Such a feature is obvioulsy much more complex to pull off, as it requires multiple changes in the design:
@rhansen Your proposal sounds like it implements another way for a client to prove domain ownership, by using a new DNS SRV record to tell the ACME server where the ACME client is located. It looks off-topic for issuing SRV-IDs and for the service delegation problem, so I'd suggest to put it into a separate ticket against ACME or boulder.
@rhansen I'm not really sure where you are heading to. The issue I want to solve is delegation of (XMPP) service operations without exposing a full DNS-ID certificate to third parties.
I believe the proposal I made (the enumerated list above the "Example" section in my comment) addresses this on the server (boulder) side. It assumes the "domain owner obtains the certificate" approach. (The client would be responsible for ensuring that the CSR it sends to the server does not include any dNSName SANs, but that's out of scope for this issue.)
Therefore I sketched a proposal to allow the service operator to prove "service ownership" to the CA, i.e. "I am operating the XMPP service(s) for company.example". This service ownership in turn will permit the operator to directly request SRV-ID certificates for the given service from the CA, but not a DNS-ID certificate for company.example.
Ahh, now I understand why your earlier comment has the server checking _acme-challenge.xmpp.cheapxmpp.example/TXT. I apologize for not understanding that you were going for the "service operator obtains certificate" approach in your earlier comment.
@rhansen Your proposal sounds like it implements another way for a client to prove domain ownership, by using a new DNS SRV record to tell the ACME server where the ACME client is located.
The part of my comment in the "Example" section is not intended to be a proposal, just an example of how the "domain owner obtains certificate" approach could work for XMPP. The existing HTTP-01 and TLS-SNI-01 identifier validation challenges don't really work well for XMPP, so I made up a new one to have a better story.
It looks off-topic for issuing SRV-IDs and for the service delegation problem,
Thinking about it more, the identifier validation challenge I made up in my example could work for the "service operator obtains certificate" approach. Whether it would work depends on how the hypothetical "acme-verify" protocol implied by the example would operate. That protocol could be designed so that the host named by the _acme-verify._tcp.company.example SRV record sends the ACME server a message that means, "I am delegating DNS name validation of company.example to cheapxmpp.example, but only for SRVName SANs for services _xmpp-server and _xmpp-client." The ACME server would then need to remember the delegation along with its limited scope when issuing a certificate to the cheapxmpp.example client.
so I'd suggest to put it into a separate ticket against ACME or boulder.
Looks like someone has already proposed something similar but not as potentially expressive: ietf-wg-acme/acme/pull/83
I believe the proposal I made (the enumerated list above the "Example" section in my comment) addresses this on the server (boulder) side.
Ah, indeed. I don't know enough about boulder's internal processing when CN or SANs from the CSR are considered "incomplete", so the clarifications in 4.-6. do make sense.
[service operator obtains certificate]
That protocol could be designed so that the host named by the
_acme-verify._tcp.company.exampleSRV record sends the ACME server a message that means, "I am delegating DNS name validation ofcompany.exampletocheapxmpp.example, but only for SRVName SANs for services_xmpp-serverand_xmpp-client." The ACME server would then need to remember the delegation along with its limited scope when issuing a certificate to thecheapxmpp.exampleclient.
That means adding delegation of ownership validation into the ACME protocol?
I'd rather keep it "simple" by using the expressiveness of already deployed protocols. My first idea was for the ACME server to follow SRV records during TXT-based ownership validation (https://github.com/letsencrypt/boulder/issues/1309#issuecomment-192391883).
Another possibility would be to "restrict" the delegation by inserting protocol tokens into the proposed SRV validation (https://github.com/ietf-wg-acme/acme/pull/83) record: Let the SRV record be constructed as _acme-challenge._http-01._tcp._xmpp-client.company.example (give or take another _tcp) and point to CheapXMPP's ACME client.
Both variants should work without changing the ACME protocol (provided that _xmpp-client.company.example is a valid domain token), and the ACME server does not need to keep additional state when performing a service ownership check.
That means adding delegation of ownership validation into the ACME protocol?
Yes, but the concept of delegation only needs to exist in the identifier validation challenge protocol. (HTTP-01 and DNS-01 already support delegation. For HTTP-01, just do a 301 or 302 redirect to the 3rd party, or if ietf-wg-acme/acme#83 is accepted then use that SRV record to delegate. For DNS-01, create a CNAME pointed at the 3rd party.)
I'd rather keep it "simple" by using the expressiveness of already deployed protocols.
It may be possible to use the existing DNS identifier type to handle SRV, but care would have to be taken to ensure that the specific mechanism for handling SRV is safe, reliable, and does not get in the way of anything else. I'm worried that reusing the existing DNS name identifier type for SRVName SANs would result in a problematic or complex protocol, but maybe there's a way to do it that's simple and robust.
I'm guessing that in the long run it would be better to introduce a new identifier type specifically for SRV (where the type is a tuple consisting of a service name and a DNS name, like {"xmpp-client", "company.example"}) and use that type to get SRVName SANs.
My first idea was for the ACME server to follow SRV records during TXT-based ownership validation (#1309 (comment)).
Following SRV records means the owner can't prevent cheapxmpp.example from obtaining a certificate in company.example's name. I think the validation protocol should require the name owner to explicitly delegate if delegation is desired. CNAME records can solve that problem.
Another possibility would be to "restrict" the delegation by inserting protocol tokens into the proposed SRV validation (ietf-wg-acme/acme#83) record: Let the SRV record be constructed as
_acme-challenge._http-01._tcp._xmpp-client.company.example(give or take another_tcp) and point to CheapXMPP's ACME client.
Yes, that would work. That record could even be a CNAME to some cheapxmpp.example name, and _they_ can resolve the record to whatever ACME client they want.
There should still be some way to communicate to the CA that the resulting cert should have _xmpp-client.company.example in a SRVName SAN, not in a dNSName SAN or in the subject, but it's fail-safe: If the CA accidentally put _xmpp-client.company.example in the subject and in a dNSName SAN it wouldn't give cheapxmpp.example the ability to impersonate other company.example services.
Both variants should work without changing the ACME protocol (provided that
_xmpp-client.company.exampleis a valid domain token),
It does require a change: The CA needs to know that these are requests for SRVName SANs.
It could assume this from the leading _ in the name, but that's dangerous because it prevents a leading _ in DNS names from being used for other (non-SRV) purposes. Or it could test whether _Service._Protocol.Name resolves, but what does it choose for _Protocol? If it only tests _tcp and _udp then that makes it harder for some new protocol to gain acceptance.
Regardless of the approach, the specific behavior would need to be documented in the protocol spec.
and the ACME server does not need to keep additional state when performing a service ownership check.
That's should be true for any delegation mechanism. There's no need to remember anything extra when following a redirection.
The following is a proposal described in the form of an example scenario. In this scenario, I assume:
company.example wants to outsource their XMPP service to cheapxmpp.examplecompany.example wants cheapxmpp.example to take care of obtaining certificates_Service.Name, except successful validation only authorizes the client to add a SRVName SAN of _Service.Name to a certificate (the DNS name _Service.Name can't be used in the subject or in any dNSName SANs unless separately authorized via a DNS name request)These are the steps taken to set up the XMPP service with a certificate:
company.example creates the following DNS records for its XMPP service:
$ORIGIN company.example.
_xmpp-client._tcp IN CNAME _xmpp-client._tcp.company.example._customers.cheapxmpp.example.
_xmpp-server._tcp IN CNAME _xmpp-server._tcp.company.example._customers.cheapxmpp.example.
_xmpp-server._tcp.conference IN CNAME _xmpp-server._tcp.conference.company.example._customers.cheapxmpp.example.
_xmppconnect IN CNAME _xmppconnect.company.example._customers.cheapxmpp.example.
company.example creates the following DNS records to allow cheapxmpp.example to obtain the relevant certificates on company.example's behalf:
$ORIGIN company.example.
_acme-challenge-http._tcp._xmpp-client IN CNAME _acme-challenge-http._tcp._xmpp-client.company.example._customers.cheapxmpp.example.
_acme-challenge-http._tcp._xmpp-server IN CNAME _acme-challenge-http._tcp._xmpp-server.company.example._customers.cheapxmpp.example.
_acme-challenge-http._tcp._xmpp-server.conference IN CNAME _acme-challenge-http._tcp._xmpp-server.conference.company.example._customers.cheapxmpp.example.
cheapxmpp.example creates the following DNS records for company.example:
$ORIGIN company.example._customers.cheapxmpp.example.
_xmpp-client._tcp IN SRV 0 0 5222 cheapxmpp.example.
_xmpp-server._tcp IN SRV 0 0 5269 cheapxmpp.example.
_xmpp-server._tcp.conference IN SRV 0 0 5269 cheapxmpp.example.
_xmppconnect IN TXT "_xmpp-client-xbosh=https://cheapxmpp.example:5280/http-bind"
_acme-challenge-http._tcp._xmpp-client IN SRV 0 0 80 acme.cheapxmpp.example.
_acme-challenge-http._tcp._xmpp-server IN SRV 0 0 80 acme.cheapxmpp.example.
_acme-challenge-http._tcp._xmpp-server.conference IN SRV 0 0 80 acme.cheapxmpp.example.
xmpp-client, company.example}, {xmpp-server, company.example}, and {xmpp-server, conference.company.example}:cheapxmpp.example's ACME client contacts the ACME server and requests authorization to use {Service, Name}http-01 challenge_acme-challenge-http._tcp._Service.Name SRV record to acme.cheapxmpp.example port 80cn=cheapxmpp.example (for BOSH connections)cheapxmpp.example (for BOSH connections)_xmpp-client.company.example_xmpp-server.company.example_xmpp-server.conference.company.examplecheapxmpp.example has been previously authorized because it is used in certificates for other customers)_Service.Name in the CSR, the ACME server verifies that the client is authorized to use the SRV name {Service, Name}This is not on the immediate roadmap, so closing the Boulder issue, but we may consider in the future.
@jsha Would a concrete proposal (protocol spec and boulder patches) be considered for merging, or does “not in the immediate roadmap” mean “patches aren't welcome”?
@nbraud The CAB Fourm Baseline regulations disallow SRVName type otherNames to be included in the subjectAltName extension which means while Boulder could add support for this Let's Encrypt would be unable to use it, which makes the prospect of having that extra code in the tree quite unappealing.
There has been some recent movement on changing the rules so SRV-IDs can be used, but until that actually happens I don't think we'll accept any patches that add this feature.
@rolandshoemaker Oh, thanks. I had a look at the CA/B Baseline Requirements, but missed 7.1.4.2.1
I might have a stab at it (assuming the requirements are changed per proposal in the ballot), but obviously this cannot land in production without the CA/B rule change being effective.
Don't the CA//B Fourm Baseline regulations apply primarily to the web, not other TLS using protocols and services?
@Zash the regulations apply to CAs that want to issue certificates for the web. This leads to the unfortunate situation that if LE wants to be accepted by browsers, it must comply with the Baseline regulations and thus must not issue certificates with SRVNames for anybody.
https://github.com/letsencrypt/boulder/issues/1309#issuecomment-223735868
This is not on the immediate roadmap [in 2016], so closing the Boulder issue, but we may consider in the future.
It's the future, any chance you may reconsider?
The CABForum Baseline Requirements still prohibit issuance of certificates whose subjectAltName field contains anything other than dNSNames or a iPAddresss. We cannot issue certificates with SRVName SANs.
Most helpful comment
https://github.com/letsencrypt/boulder/issues/1309#issuecomment-223735868
It's the future, any chance you may reconsider?