Subject: Re: [Acme] "Slide 21" follow-up (textual encoding question) PART 2

From: Niklas Keller <[email-masked]>
Date: Sun, 2 Apr 2017 14:03:37 +0200

>
> Sean,
>
> The working group felt pretty clearly that the BEGIN/END base64 encoding
> was the format used by "all" web servers and that anything else would
> require the client to translate into that format.
>

That's true, but using a format that can just be dumped without inspection
makes these private key injection attacks easier.

I'm all for simple clients, but that ends where simplicity means not
checking inputs and outputs.

Regards, Niklas

---

From: Richard Barnes <[email-masked]>
Date: Sun, 2 Apr 2017 15:06:20 -0500

On Fri, Mar 31, 2017 at 5:23 PM, Sean Leonard <[email-masked]> wrote:

> Hi ACME:
>
> SECOND PART.
>
> I think some of my comments may have been misconstrued about the “**Don't
> call it PEM certificate chain** (slide 21)” issue.
>
> Textual encoding amounts to a way to ASCII-armor binary data in plain
> text. This is obvious because the human usability that it enables is:
> “copy-and-paste from your web browser or e-mail client into a text file”.
> And the problem with human usability is that when you tell people to copy
> and paste things, they don’t know or they ignore *what* they are copying
> and pasting, so they can facilitate transmitting malicious content across
> security boundaries.
>
> Human interaction is not a design goal in ACME. You want humans to touch
> this stuff as little as possible. By letting software “copy and paste” the
> ACME server’s response to anything, *without validating it*, you facilitate
> attacks such as the private key substitution attack. (There are others, for
> example, OpenSSL behaves differently when you supply it with -----TRUSTED
> CERTIFICATE-----.)
>

You're confusing parsing with validation.  Yes, if we provide things in
some non-de-facto-standard format, then clients will have to reformat
things.  That introduces some likelihood that the reformatting will break
on invalid inputs, but it's far from guaranteed.

That said, the idea of "inlining" the certificate / chain doesn't seem
completely awful.  On the one hand, it would save an HTTP round-trip in the
common case, and we don't have anything else in the protocol that relies on
a certificate being referenced indepenedently from the order that created
it.  On the other hand, it seems like there could be some utility in the
future to being able to refer to the certificate per se, vs. the order that
created it.  I could go either way.

If we do inline the certificate into the order, ISTM the natural thing to
do would be to just present it in base64url-encoded form:

{
  // existing order fields
  "certificate": "[[ base64url data ]]",
  "chain": ["[[ base64url data ]]", ...]
}

Then it would just be a syntactic transformation to whatever an HTTP server
accepts.

--Richard

>
> If the WG’s consensus is that you really want a separate certificate URI
> (seriously: why? you want it retrievable over ldap:// or ni:// or
> something?), then the URI dereference should return *just* certificates in
> a well-defined way. Blobs of text (regardless of what MIME type you serve
> it as) are not well-defined compared to the gold standard of
> application/pkix-cert. If your goal really is so that a human being can
> take the certificate URI and put it in their web browser and copy and paste
> the certificate, then it should be served as text/plain; charset=us-ascii.
> Or if you want, text/html and include some dancing hamsters and last-minute
> unilateral changes to the CA contract (because hunting-and-picking for
> -----BEGIN CERTIFICATE----- in HTML source works exactly the same way, it’s
> called “page scraping”). But I thought that the point of ACME is to get
> away from page scraping techniques.
>
> Anyway, if you want a format at a separate URI that includes the
> certificate and the ACME server’s proposed chain and is automatable, my
> first suggestion is multipart/mixed where each part is
> application/pkix-cert. Most web browsers don't handle multipart/mixed
> responses well, but the point is that you’re not supposed to use a web
> browser to get this URI.
>
> My second suggestion is (what I wrote initially): a new binary type,
> application/pkix-certs (or cert-chain), with concatenated DER-encoded
> certificates: the first one is the subject certificate you’re interested in
> and the others “SHOULD” be in TLS order.
>
> Thanks,
>
> Sean
>
> _______________________________________________
> Acme mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/acme
>

---

From: Sean Leonard <[email-masked]>
Date: Mon, 3 Apr 2017 02:00:20 -0700

On 4/2/2017 1:06 PM, Richard Barnes wrote:
>
>
> On Fri, Mar 31, 2017 at 5:23 PM, Sean Leonard <[email-masked] 
> <mailto:[email-masked]>> wrote:
>
>     Hi ACME:
>
>     SECOND PART.
>     [...]
>
> completely awful.  On the one hand, it would save an HTTP round-trip 
> in the common case, and we don't have anything else in the protocol 
> that relies on a certificate being referenced indepenedently from the 
> order that created it.  On the other hand, it seems like there could 
> be some utility in the future to being able to refer to the 
> certificate per se, vs. the order that created it. I could go either way.

That's the idea (in PART 1, anyway).

The issue of whether a certificate should be referred to by reference 
(URI) or by value (supplied as the certificate itself) is discussed in 
draft-seantek-certspec-11. In this case, I do not see any additional 
value in /requiring/ a separate URI to access the certificate octets. 
Put another way: if you want a separate URI instead of the certificate, 
because you don't want to store the certificate, then you will have to 
store the separate URI somewhere. And, if you are storing the separate 
URI, you have a place to store the certificate in the first place.

Perhaps there is business value in a CA standing up a sensible 
(well-known) URI scheme, such as:

https://www.cawebsite.com/.well-known/getcert?host=FOO.BAR.COM&{other 
parameters}

...but that is outside of the scope of the (current) protocol for this 
working group. Compare with draft-bhjl-x509-srv-03. I could see it being 
added to the ACME server as a "feature", but that is up to you all.

>
> If we do inline the certificate into the order, ISTM the natural thing 
> to do would be to just present it in base64url-encoded form:
>
> {
>   // existing order fields
> Then it would just be a syntactic transformation to whatever an HTTP 
> server accepts.

Something like that could be okay. Although I suppose some "aesthetics" 
are involved, the choice for JSON format is not exactly bikeshedding. If 
it's in JSON then some part of it ought to be an array. The main point 
(raised in PART 1) is that inlining makes things faster and sidesteps 
all of the problems raised by MIME types and text blobs in PART 2.

I note that a base64url-encoded version of the DER octets of a 
certificate are already included in this protocol, in Certificate 
Revocation Section 7.6.

Sean

---

From: Niklas Keller <[email-masked]>
Date: Mon, 3 Apr 2017 13:28:58 +0200

One potential issue I can see with embedding certificates with the
currently proposed format directly into orders are alternative chains.
Chains usually do not change between orders, so they could be kept with
separate URIs for cachability and less bloat in the order response.

e.g.

"certificate": base64url(derEncodedCertificate),
"chains": [
   "https://.../chain",
   "https://.../alternate-chain"
]

Regards, Niklas

---

From: Logan Widick <[email-masked]>
Date: Mon, 3 Apr 2017 07:54:08 -0500

I think that having separate URIs to reduce bloat is a good idea. I
understand that the client needs to send the CSR as a field in the
new-order request payload for security. However, in the server response,
could the CSR be a URI that would allow the client to retrieve the CSR that
the client submitted in DER format? So, could new-order requests look like:

{
csr: "base64url(derEncodedCSR)"
//rest of fields in new-order here
}

And the server's order response look like:
{
csrLink: "[link to DER encoded CSR]"
certificate: "[link to DER encoded certificate]"
chains: [array of links to chains as suggested by Niklas]
//rest of fields in order response here (except for "csr")
}

For consistency, I think the chain links (when retrieved) should be
concatenated DER.

Sincerely,

Logan Widick

On Apr 3, 2017 06:29, "Niklas Keller" <[email-masked]> wrote:

e.g.

Regards, Niklas

---

From: "Salz, Rich" <[email-masked]>
Date: Mon, 3 Apr 2017 15:43:16 +0000

Speaking as an individual, I think returning the certlist in the response will lead to careless clients than can *only* handle synchronous cert creation.

This strikes me as a premature optimization.

---

From: Sean Leonard <[email-masked]>
Date: Mon, 3 Apr 2017 14:07:32 -0700

On 4/3/2017 5:54 AM, Logan Widick wrote:
> new-order request payload for security. However, in the server 
> response, could the CSR be a URI that would allow the client to 
> retrieve the CSR that the client submitted in DER format? So, could 
> new-order requests look like:
>
> {

The wrinkle with this proposal is that CSRs are likely non-public data. 
They could contain personally identifiable information in the metadata, 
or other random stuff. It is undesirable to have a link that has to be 
maintained for the lifetime of the order history, which could be 
harvested by search engines or otherwise made public. Typically CAs 
harvest the public key and discard the rest (after verifying the 
authenticity of the CSR). Therefore, I am not in favor of URIs for CSR data.

The case for URIs for issued end-entity certificates is half-half. 
Certificates are public documents, but it's an extra round-trip and you 
have to save the same amount of state on the client side (i.e., the 
certificate URI).

The case for URI(s) for CA certificates in the validation chain is 
strongest, since they are unlikely to change and are reused across many 
customers. Basically "de-duplication". On the other hand, there are 
business/usability advantages to packaging up "everything you need to 
run your web server" in one neat package. I think that CA 
operators/implementers would have the most authority to weigh in on what 
works best.

> For consistency, I think the chain links (when retrieved) should be 

I am in favor of DER. :) (But less sure about whether links are 
desirable in the first place.)

I could have sworn that when certificate retrieval is done over the 
wire, CMS (PKCS #7) is an IETF standardized type for blobs of 
certificates. Oh yeah, here it is:
RFC 5280 Section 4.2.2.1 (it's repeated elsewhere):

    HTTP server implementations accessed via the URI SHOULD specify the
    media type application/pkix-cert [RFC2585 <https://tools.ietf.org/html/rfc2585>] in the content-type header
    field of the response for a single DER encoded certificate and SHOULD
    specify the media type application/pkcs7-mime [RFC2797 <https://tools.ietf.org/html/rfc2797>] in the
    content-type header field of the response for "certs-only" CMS
    messages.  For FTP, the name of a file that contains a single DER
    encoded certificate SHOULD have a suffix of ".cer" [RFC2585 <https://tools.ietf.org/html/rfc2585>] and the
    name of a file that contains a "certs-only" CMS message SHOULD have a
    suffix of ".p7c" [RFC2797 <https://tools.ietf.org/html/rfc2797>].  Consuming clients may use the media type
    or file extension as a hint to the content, but should not depend
    solely on the presence of the correct media type or file extension in
    the server response.

Just sayin'... ;-)

It is worth pointing out that PKCS #7 / CMS "certs-only", amounts to 
concatenated DER certificates plus a little bit of goo at the beginning 
and end (which can be ignored/skipped). Here is a dump of a .p7s file I 
have lying around using asn1js:

SEQUENCE(2 elem)
OBJECT IDENTIFIER1.2.840.113549.1.7.2
[0](1 elem)
SEQUENCE(5 elem)
INTEGER1
SET(0 elem)
SEQUENCE(1 elem)
OBJECT IDENTIFIER1.2.840.113549.1.7.1
[0](3 elem)
SEQUENCE(3 elem)
SEQUENCE(3 elem)
SEQUENCE(3 elem)
SET(0 elem)

In this case, the SEQ -> [0] -> SEQ -> [0] has three certificates, which 
start with SEQUENCE. Rip and go.

Finally, here is how you convert from p7s to textual certificates:
   openssl pkcs7 -inform DER -in yourfile.p7s -print_certs

The advantage of the command-line/OpenSSL recipe above, is that you are 
guaranteed that the output will only be -----BEGIN CERTIFICATE----- 
things. Non-certificates shall not pass.

Sean

>
> Sincerely,
>
> Logan Widick
>
> On Apr 3, 2017 06:29, "Niklas Keller" <[email-masked] 
> <mailto:[email-masked]>> wrote:
>
>     currently proposed format directly into orders are alternative
>     chains. Chains usually do not change between orders, so they could
>     be kept with separate URIs for cachability and less bloat in the
>     order response.
>
>     e.g.
>
>     [email-masked] <mailto:[email-masked]>
>     <https://www.ietf.org/mailman/listinfo/acme>
>
>

---

From: Hugo Landau <[email-masked]>
Date: Sun, 9 Apr 2017 10:11:12 +0100

I agree that end certificate data should be inlined in the certificate
object, rather than being hosted at a separate certificate URI, so long
as GET requests for order resources do not require authentication and
can thus be easily polled (which is currently the case).

I'm indifferent as to whether certificate data in the certificate object
is a PEM formatted JSON string or base64url-encoded DER formatted JSON
string.

I think it's essential to support multiple certificate chains and
referencing these by an array of URIs makes sense to me.

I think it should be a requirement that the server always list its
"recommended" chain first in that array, so that clueless clients can
always have a sensible default to go with. (i.e., Let's Encrypt would
list its current IdenTrust-based chain first, and its ISRG-based ahin
second).

I think having the certificate chains encoded in a format other than
concatenated PEM is likely to be more trouble than it's worth.

I think it's important that those certificate chains should include the
root certificate, because it's required for some applications (DANE).
Clients which do not require the root certificate can simply be mandated
to strip off the last certificate returned in the chain. This is my
preference. Alternatively, if that's viewed as too error-prone, a link
rel=up link from the chain URL to the root URL could be used.

I don't agree that including the certificate in the certificate object
will cause badly implemented clients to assume synchronous issuance; one
simply polls the order resource until the certificate appears. This is
no different than waiting for a certificate URI to appear. (The current
specification doesn't provide for requests to the certificate URI to
defer a response; that was in a previous version.)

---

From: Sean Leonard <[email-masked]>
Date: Tue, 11 Apr 2017 07:33:47 -0700

So what I am hearing is that there are rising voices in favor of PART 1, namely inlining the certificate data, which obviates (i.e., removes) the need for a separate MIME type.

As for the format of end-entity certificate data: if it’s in JSON then it has to be some textual encoding. I am mostly indifferent to RFC 7468 textual encoding vs. base64/base64url, but on balance I think base64/base64url is better because that’s the same format as the csr field, which means that clients and servers have to process it anyway. Furthermore, we don’t want naive clients to dump the contents of the certificate field into their web server preferences, since that results in the same validation problem as before in letting through more than just a single certificate. It’s also smaller. (I don’t understand why base64url was chosen over base64, is that some JWS requirement or something? Please help me understand that.)

I can’t say whether support for multiple chains is necessary, but several people have identified it as being useful. So that should be some kind of array.

If URIs are used to retrieve the certificate chain(s), ACME doesn’t currently specify what kinds of URIs clients and servers need to support—the draft ought to say something about that. RFC 5280 describes URI access mechanisms using HTTP, HTTPS, FTP, LDAP, and X.500 without recommending any particular thing. I think the same constellation of URIs ought to be supported (proposed text: “Some URI schemes are documented in [RFC5280].” — not recommending any particular thing). This is less work than people might think, as many crypto stacks implement rudimentary HTTP/HTTPS, FTP, and LDAP clients anyway (yes, even LDAP). If “enterprise” is a use case for this protocol then LDAP should be supported anyway. (Note: if the data: URI is also supported, then you have an option for inlining in a different part of the software stack, not sure if folks want to go there as data: is base64 rather than base64url.)

The draft could also discuss that the caIssuers access method (RFC 5280 Section 4.2.2.1) SHOULD be filled in the subject certificate, and the clients are to follow those URIs to get any CA certificate chains. Then you can just let the crypto stack have at it. In MS CAPI it is just a flag (default is on) to CertGetCertificateChain.

The protocol could allow both inlined certificate data (array of base64(url)-encoded certs)) and URI options. This is more complicated, but as pointed out above, URIs are mostly supported by crypto stacks anyway. Again, it’s just one call in MS CAPI: CryptRetrieveObjectByUrl. (See also CryptGetObjectUrl.)

Sean

> On Apr 9, 2017, at 2:11 AM, Hugo Landau <[email-masked]> wrote:
>

---

From: Ilari Liusvaara <[email-masked]>
Date: Tue, 11 Apr 2017 18:34:46 +0300

On Tue, Apr 11, 2017 at 07:33:47AM -0700, Sean Leonard wrote:
> 
> As for the format of end-entity certificate data: if it’s in JSON
> then it has to be some textual encoding. I am mostly indifferent
> to RFC 7468 textual encoding vs. base64/base64url, but on balance
> I think base64/base64url is better because that’s the same format
> as the csr field, which means that clients and servers have to
> process it anyway. Furthermore, we don’t want naive clients to
> dump the contents of the certificate field into their web server
> preferences, since that results in the same validation problem as
> before in letting through more than just a single certificate. It’s
> also smaller. (I don’t understand why base64url was chosen over
> base64, is that some JWS requirement or something? Please help me
> understand that.)

Well, JWS tends to use base64url.

And dumping a array of base64url encoded certificates into "PEM"
file is not difficult:

1) For each entry:
1a) Write "-----BEGIN CERTIFICATE-----" and linefeed
1b) Check that the string consists of only alphanumerics, - and _.
1c) Replace - with +, and _ with / in string.
1d) Pad to multiple of 4 with =.
1e) Write out the modified string, wrapping to 72 characters.
1f) Write "-----END CERTIFICATE-----" and linefeed.

This method is not vulernable to special certificate types.

> I can’t say whether support for multiple chains is necessary,
> but several people have identified it as being useful. So that
> should be some kind of array.

Problem is, since multiple chains are involved, it becomes
some sort of array of array.

And if you dump all the certificates in chains there, assume lots
of servers will end up with serving such "chains" (which break TLS 1.2
rules).

> If URIs are used to retrieve the certificate chain(s), ACME
> doesn’t currently specify what kinds of URIs clients and servers
> need to support—the draft ought to say something about that. RFC
> 5280 describes URI access mechanisms using HTTP, HTTPS, FTP, LDAP,
> and X.500 without recommending any particular thing. I think the
> same constellation of URIs ought to be supported (proposed text:
> “Some URI schemes are documented in [RFC5280].” — not recommending
> any particular thing). This is less work than people might think,
> as many crypto stacks implement rudimentary HTTP/HTTPS, FTP, and
> LDAP clients anyway (yes, even LDAP). If “enterprise” is a use
> case for this protocol then LDAP should be supported anyway. (Note:
> if the data: URI is also supported, then you have an option for
> inlining in a different part of the software stack, not sure if
 folks want to go there as data: is base64 rather than base64url.)

I presume URLs are all HTTPS.

> The draft could also discuss that the caIssuers access method
> (RFC 5280 Section 4.2.2.1) SHOULD be filled in the subject
>  certificate, and the clients are to follow those URIs to get any
> CA certificate chains. Then you can just let the crypto stack
> have at it. In MS CAPI it is just a flag (default is on) to
> CertGetCertificateChain.

Way too complicated for most clients.

And didn't that kind of thing blow up rather badly when LE updated
their intermediates (from X1/X2 to X3/X4)?

> The protocol could allow both inlined certificate data (array of
> base64(url)-encoded certs)) and URI options. This is more complicated,
> but as pointed out above, URIs are mostly supported by crypto stacks
> anyway. Again, it’s just one call in MS CAPI: CryptRetrieveObjectByUrl.
> (See also CryptGetObjectUrl.)

Doing something because MS CAPI makes it easy is a bad idea. Most
users won't be using anything that has anything to do with CAPI.

-Ilari

---

From: Sean Leonard <[email-masked]>
Date: Tue, 11 Apr 2017 09:10:15 -0700

> On Apr 11, 2017, at 8:34 AM, Ilari Liusvaara <[email-masked]> wrote:
> 

Thanks for the algorithm. :) Yup, pretty easy.

> some sort of array of array.

…which is not a problem, since that’s what it is anyway, regardless of whether it’s a JSON [ [ “” ] ] or something else. Nested structures are just fine.

> of servers will end up with serving such "chains" (which break TLS 1.2

Less sure about this one, I would think a naive implementation would just pick the first chain in the array of chains, and not do any checking (as opposed to doing validation checking before putting into production).

> I presume URLs are all HTTPS.

I don’t think that presumption is warranted. Besides, they could be straight HTTP, it avoids circularity problems if you can’t validate the server cert or client cert for mutual auth because somehow your validation depends on ACME or this-and-that (hand wave).

Note: there *is* a substitution attack if, during the ACME protocol, you retrieve the certificate URI over HTTP and an adversary man-in-the-middle attacks the communication and provides you with the wrong cert. Yet it’s unclear what exactly the harm is, since you have the private key, it would just be a DoS attack. Well, the harm is much more obvious if you don’t check the text that is returned and there is a -----BEGIN RSA PRIVATE KEY----- snuck in the middle there. :^)

> their intermediates (from X1/X2 to X3/X4)?

Not familiar with the history on that one, maybe a link would be helpful?

> users won't be using anything that has anything to do with CAPI.

I know people around here like to hate on MS CAPI but that is what a significant fraction of TLS clients use.

When RFC 7468 was written, we checked the behavior of at least five different implementations: OS X/iOS Cryptographic Services, MS CAPI, OpenSSL, Mozilla NSS, and GnuTLS. Wish we checked others but didn’t have the time, unfortunately. You would be surprised how finicky the different implementations are when it came to line endings and whitespace, for example.

I thought we strive around these parts to check at least two independent implementations. “Apache and Nginix” are not two independent implementations, since they both use OpenSSL (and both, notably, in more-or-less the same way). OpenSSL is fine software but it’s not the only deployed software out there, that’s my point.

Regards,

Sean

---

From: Ilari Liusvaara <[email-masked]>
Date: Tue, 11 Apr 2017 20:21:52 +0300

On Tue, Apr 11, 2017 at 09:10:15AM -0700, Sean Leonard wrote:
> …which is not a problem, since that’s what it is anyway, regardless
> of whether it’s a JSON [ [ “” ] ] or something else. Nested structures
> are just fine.
> 
> > 
> Less sure about this one, I would think a naive implementation would
> just pick the first chain in the array of chains, and not do any
> checking (as opposed to doing validation checking before putting into
> production).

Oops, that was phrased in unclear way. I meant that if all the
certificates are dumped into one array, you will likely get those
kinds of chains sent from TLS servers.

If it is array of arrays, and ACME client picks the first one, then
obviously only that chain gets sent.

And I expect number of ACME clients that do no validation before
throwing cert into production to outnumber the ones that do even
some validation.

> I don’t think that presumption is warranted. Besides, they could
> be straight HTTP, it avoids circularity problems if you can’t
> validate the server cert or client cert for mutual auth because
> somehow your validation depends on ACME or this-and-that (hand wave).

Is this about servers fetching their existing certificates from CA on
startup? I don't think that would be in scope for ACME.

Also, I presume that any such fetch has reasonable TA list (NOT
using the "system default" one).

> Note: there *is* a substitution attack if, during the ACME protocol,
> you retrieve the certificate URI over HTTP and an adversary man-in-
> the-middle attacks the communication and provides you with the wrong
> cert. Yet it’s unclear what exactly the harm is, since you have the
> private key, it would just be a DoS attack. Well, the harm is much
> more obvious if you don’t check the text that is returned and there
> is a -----BEGIN RSA PRIVATE KEY----- snuck in the middle there. :^)

AFAICT, scenarios where having private key in material obtained would
make any sense lead into circular dependicies.

> Not familiar with the history on that one, maybe a link would be helpful?

Basically, Let's Encrypt got new intermediate that has different
subject but the same key. Casued IIS (the webserver) chain building to
go crazy, building incorrect certificate chain (containing wrong
intermediate) until one cleared some system certificate storage
(it took weeks to figure out what one needed to do to fix the problem).

> significant fraction of TLS clients use.

And even more significant fraction don't. So you can't assume MS CAPI
behavior.

> When RFC 7468 was written, we checked the behavior of at least five
> different implementations: OS X/iOS Cryptographic Services, MS CAPI,
> OpenSSL, Mozilla NSS, and GnuTLS. Wish we checked others but didn’t
> have the time, unfortunately. You would be surprised how finicky the
> different implementations are when it came to line endings and
> whitespace, for example.

Reading one of my own implementations with regards to PEM parsing:

- Line endings are either '\n' or '\r\n', both are treated the same.
- In base64 lines, ASCII 0x20 and 0x09 are ignored. Otherwise lines have
  to consist of valid Base64 characters.
- If padding is present, there must be exactly correct amount to bring
  size to multiple of 4.
- No extraneous characters are allowed in BEGIN and END lines.
- Only "CERTIFICATE" blocks are read. There must be at least one.
- All blocks are decoded as base64, but non-CERTIFICATE blocks are
  ignored.
- Lines outside blocks are igored.

(Well, those are supposed to be the rules, actually looks like the
code has a bug that causes it to blow up if it ever encounters any
block that isn't CERTIFICATE.

> I thought we strive around these parts to check at least two independent
> implementations. “Apache and Nginix” are not two independent
> implementations, since they both use OpenSSL (and both, notably, in
> more-or-less the same way). OpenSSL is fine software but it’s not the
> only deployed software out there, that’s my point.

Yeah, and my point is that MS CAPI is not the only deployed software,
and thing that are easy in MS CAPI may be hard otherwise.

-Ilari

---

From: Sean Leonard <[email-masked]>
Date: Tue, 11 Apr 2017 22:35:47 -0700

> On Apr 11, 2017, at 10:21 AM, Ilari Liusvaara <[email-masked]> wrote:
> 

Yes, it is an array of arrays.

> throwing cert into production to outnumber the ones that do even

An old Russian proverb: “Trust, but verify.” This is not just about verification in the narrow certificate validation sense: it’s about sanitizing your inputs (verify in the broad sense).

Implementations (currently) do not have to verify the input from the server. They should verify in the broad sense (making sure that the returned data is “certificates, and only certificates”); they should also also verify in the narrow sense (validate the certificate chains to a TA and is currently good). But I am not going to push for the latter too hard because I am not so sure everyone around here is going to implement that, so the blood is on their hands if they throw a cert into production and millions of clients fail out.

> startup? I don't think that would be in scope for ACME.

No, I was referring to the once-a-year (or quarter or whatever) certificate update, which is in-scope for ACME. I was not envisioning that servers fetch existing certificates on software startup.

***

As for the rest: it sounds like there is value in separating the subject certificate in one field (base64url encoded), and the intermediate CA certificate chains (plural) in another field, which may, or may not, include the root. There is some value in inlining the certificate chains (arrays of arrays of base64url-encoded certificates), and some value in referencing certificate chains by URIs (arrays of URIs).

I think that as long as the ACME client has flexibility in terms of how to determine the appropriate certificate chains that it wants to put into production (and that the ACME draft says so), then it is fine. The subject certificate is fixed, but the ACME client can use any intermediate cert chain when in production, or figure out its own custom thing.

In terms of the format of certificate chains, I am in favor of a chain being an array of base64url-encoded certificates, and the “chains” field being an array of such chain arrays. This is mainly because I really don’t see certificate chains changing during the lifetime of a subject certificate, and it’s not difficult for an ACME server to serve the same static data in response to a dynamic request. For resource- or time-constrained ACME clients, this also leads to the most predictable and rapid behavior.

Note: if you want both by-value and by-reference, a base64url certificate always begins with “M”, while an absolute URI always contains “:”. Therefore you can overload the field so that it can be a URI or a string depending on whether these factors are present (specifically, if “:” is in the string). But then again you can also just say data:application/pkix-cert;base64,MIICAS… and get the same effect if they are always URIs.

Sean

---

From: Logan Widick <[email-masked]>
Date: Wed, 19 Apr 2017 23:44:52 -0500

On Apr 3, 2017 16:07, "Sean Leonard" <[email-masked]> wrote:

{

The wrinkle with this proposal is that CSRs are likely non-public data.
They could contain personally identifiable information in the metadata, or
other random stuff. It is undesirable to have a link that has to be
maintained for the lifetime of the order history, which could be harvested
by search engines or otherwise made public. Typically CAs harvest the
public key and discard the rest (after verifying the authenticity of the
CSR). Therefore, I am not in favor of URIs for CSR data.

Since CAs would harvest data from CSRs and then discard the rest after
authenticity checks, and the identifiers would appear elsewhere (in the
authorizations), could the "csr" field apply to the new-order request and
be absent from the order object?

The case for URI(s) for CA certificates in the validation chain is
strongest, since they are unlikely to change and are reused across many
customers. Basically "de-duplication". On the other hand, there are
business/usability advantages to packaging up "everything you need to run
your web server" in one neat package.

When certificates are embedded in order objects, won't the order objects
get quite large?

I am in favor of DER. :) (But less sure about whether links are desirable
in the first place.)

I could have sworn that when certificate retrieval is done over the wire,
CMS (PKCS #7) is an IETF standardized type for blobs of certificates. Oh
yeah, here it is:
RFC 5280 Section 4.2.2.1 (it's repeated elsewhere):

   HTTP server implementations accessed via the URI SHOULD specify the
   media type application/pkix-cert [RFC2585
<https://tools.ietf.org/html/rfc2585>] in the content-type header
   field of the response for a single DER encoded certificate and SHOULD
   specify the media type application/pkcs7-mime [RFC2797
<https://tools.ietf.org/html/rfc2797>] in the
   content-type header field of the response for "certs-only" CMS
   messages.  For FTP, the name of a file that contains a single DER
   encoded certificate SHOULD have a suffix of ".cer" [RFC2585
<https://tools.ietf.org/html/rfc2585>] and the
   name of a file that contains a "certs-only" CMS message SHOULD have a
   suffix of ".p7c" [RFC2797 <https://tools.ietf.org/html/rfc2797>].
Consuming clients may use the media type
   or file extension as a hint to the content, but should not depend
   solely on the presence of the correct media type or file extension in
   the server response.

Just sayin'... ;-)

It is worth pointing out that PKCS #7 / CMS "certs-only", amounts to
concatenated DER certificates plus a little bit of goo at the beginning and
end (which can be ignored/skipped). Here is a dump of a .p7s file I have
lying around using asn1js:

SEQUENCE(2 elem)

The advantage of the command-line/OpenSSL recipe above, is that you are
guaranteed that the output will only be -----BEGIN CERTIFICATE----- things.
Non-certificates shall not pass.

That already standardized type would be better.

e.g.

"certificate": base64url(derEncodedCertificate),
"chains": [
   "https://.../chain" <https://.../chain>,
   "https://.../alternate-chain" <https://.../alternate-chain>
]

Regards, Niklas

---

From: Sean Leonard <[email-masked]>
Date: Thu, 27 Apr 2017 23:35:51 -0700

> On Apr 19, 2017, at 9:44 PM, Logan Widick <[email-masked]> wrote:
> 
> 
> 
> On Apr 3, 2017 16:07, "Sean Leonard" <[email-masked] <mailto:[email-masked]>> wrote:
>> I think that having separate URIs to reduce bloat is a good idea. I understand that the client needs to send the CSR as a field in the new-order request payload for security. However, in the server response, could the CSR be a URI that would allow the client to retrieve the CSR that the client submitted in DER format? So, could new-order requests look like: 
>> 
>> {
> The wrinkle with this proposal is that CSRs are likely non-public data. They could contain personally identifiable information in the metadata, or other random stuff. It is undesirable to have a link that has to be maintained for the lifetime of the order history, which could be harvested by search engines or otherwise made public. Typically CAs harvest the public key and discard the rest (after verifying the authenticity of the CSR). Therefore, I am not in favor of URIs for CSR data.
> 
> Since CAs would harvest data from CSRs and then discard the rest after authenticity checks, and the identifiers would appear elsewhere (in the authorizations), could the "csr" field apply to the new-order request and be absent from the order object? 

They “could” be. But, I think the point of keeping the CSR around is partially for reference purposes. I am aware of web servers that keep the CSR around for users (customers) to stash.

> 
> 
> The case for URIs for issued end-entity certificates is half-half. Certificates are public documents, but it's an extra round-trip and you have to save the same amount of state on the client side (i.e., the certificate URI).
> 
> The case for URI(s) for CA certificates in the validation chain is strongest, since they are unlikely to change and are reused across many customers. Basically "de-duplication". On the other hand, there are business/usability advantages to packaging up "everything you need to run your web server" in one neat package. 
> 
> When certificates are embedded in order objects, won't the order objects get quite large?

They will get larger, but it’s not clear that the size is really going to be an issue. The client has to download the certificates anyway eventually. It is (arguably) more bookkeeping to store them separately, e.g., via separate URIs.

>> 
>> For consistency, I think the chain links (when retrieved) should be concatenated DER. 
> 
> I am in favor of DER. :) (But less sure about whether links are desirable in the first place.)
> 
> I could have sworn that when certificate retrieval is done over the wire, CMS (PKCS #7) is an IETF standardized type for blobs of certificates. Oh yeah, here it is:
> It is worth pointing out that PKCS #7 / CMS "certs-only", amounts to concatenated DER certificates plus a little bit of goo at the beginning and end (which can be ignored/skipped). Here is a dump of a .p7s file I have lying around using asn1js:
> 
> SEQUENCE(2 elem)
> In this case, the SEQ -> [0] -> SEQ -> [0] has three certificates, which start with SEQUENCE. Rip and go.
> 
> The advantage of the command-line/OpenSSL recipe above, is that you are guaranteed that the output will only be -----BEGIN CERTIFICATE----- things. Non-certificates shall not pass.
> 

Great. My point here is to keep with what already exists.

Regards,

Sean