Subject: [Acme] Implementation of ACME in Node.JS

From: Prasheel Soni <[email-masked]>
Date: Fri, 3 Nov 2017 19:07:38 +0530

Hi Devs,

I'm a beginner in ACME and trying to implement it in Node.JS. I came across
some doubts while implementing it. Here are some of them:

1) What is TLS SNI Challenge and How to implement this in Node.JS, can
anyone suggest some links to videos or documents or tutorials which I can
refer for better understanding.

2) What should be the process flow of 'new-order' implementation process?

3) What should be the implementation strategy if there is no
'pre-authorization'?

Thanks

*Prasheel*

‌

---

From: Ilari Liusvaara <[email-masked]>
Date: Fri, 3 Nov 2017 19:19:39 +0200

> some doubts while implementing it. Here are some of them:

Note that in the below, "server" and "ACME client" may or may not be
the same entity. Server is the process that listens for port 443, ACME
client is the process that talks with the ACME server, which is taken
to be the CA.

> refer for better understanding.

Basically, ACME has a set of challenge methods. Challenge methods are
methods intended for the server to authenticate to the CA that it is
the name it claims to be.

TLS SNI challenge, internally called "tls-sni-02" is one such method.
In it, the acme client provisions a self-signed certificate containing
given names in SubjectAlternativeNames section for a specific TLS Server
Name Indication value. The CA will then contact the server, using IP
address resolved from the DNS A or AAAA record for the name to validate,
always on port 443, send the specific Server Name Indication value, and
check that the returned certificate consists of the given names. If it
does, the challenge is valid. Otherwise the challenge fails.

As far as I understand, the names (of DNS type) that need to appear in
the certifiate are computed as follows:

1) encode(sha256(token)) || ".token.acme.invalid"
2) encode(sha256(token||"."||accountfp)) || . ".ka.acme.invalid"

Where:

encode(x) does the following:
	- Encode x into 64 lowercase hexadecimal digits.
	- Split the result into two halves of 32 hexdigits each.
	- Concatenate the halves back with "." in between.
|| is string concatenation.
sha256(x) is (binary) SHA-256 hash of x.
"foo" is the fixed ASCII string foo.

Both names need to appear, and only these names can appear. The
request will be sent for 1), as ServerName of HostName type.

If you are writing ACME client, Note that unless the TLS stack or the
webserver has special support for this method, it will require very
nasty hacks. I am aware of just one piece of software (that I
happended to write) with such support that is programmable from
outside. Some other pieces of software also have internal support for
internal ACME client, but nothing to use from outside.

For the above reason, I would not advise you to use tls-sni-01 if
the ACME client is separate from the server. Use http-01 instead
in this case (or dns-01 if you have access to API that modifies
DNS data).

Also note that there is _no_ way for server to verify the purported
challenge is legimate or what it actually covers. This is in contrast
to the http-01 and dns-01 methods, where the server can indeed verify
that the challenge is for name it is purported to be (by at least
causing validation to fail if it is not).

> 2) What should be the process flow of 'new-order' implementation process?

1) Client sends new-order request containg names it wants in the
   certiifcate. This list can contain wildcards.
2) The CA creates authorizations it wants, none of them for a wildcard,
   and returns the list to the ACME client.
3) The ACME client solves one challenge for each authorization returned.
4) The ACME client finalizes the order.
5) The ACME client downloads the certificate.
 
> 3) What should be the implementation strategy if there is no

For the ACME client, Instead of figuring authorizations you need, let
the CA tell what it needs.

For the CA, if the order can not be immediately satisfied, create
authorizations for each name you need authorized before issuance,
and return this list to the ACME client.

-Ilari