Acme.sh - tls-alpn-01 how to question

Hi Everyone,

I’m actually working on my Master’s thesis (protocol acme, automation, …) and I can’t find answer to one of my question.

I generate a certificate through tls-alpn-01 challenge with acme.sh client I took some traces but there are some info I can’t find.

In the RFC draft draft-ietf-acme-tls-alpn-01 it’s mentioned the following:

  1. Verify that the ServerHello contains a ALPN extension containing the value “acme-tls/1” and that the certificate returned contains a subjectAltName extension containing the dNSName being validated and no other entries and a critical acmeValidation extension containing the digest computed in step 1. The comparison of dNSNames MUST be case insensitive [RFC4343]. Note that as ACME doesn’t support Unicode identifiers all dNSNames MUST be encoded using the [RFC3492] rules.

In the tcpdump traces I see the “Client Hello” and it’s containing the extension “application_layer_protocol_negotiation” but in the answer from the server, “Server Hello” I can’t find the extension but in the RFC it’s mandatory.

image

Does this part of the ciphered data or is it simply missing ? Can someone can help me to figure out if it’s normal ?

Thanks a lot for your help.

2 Likes

Yes, you got it. In TLS 1.3, this information is now sent in the EncryptedExtensions part of the handshake - not visible to Wireshark unless you setup SSLKEYLOGFILE. Any extensions which are not strictly required to establish the initial encryption, will have relocated there.

If you force acme.sh to use TLS 1.2 or lower (by changing its s_server call to include -no_tls1_3), you would be able to see the normal list of extensions in the ServerHello message.

Edit:

Later versions of the draft no longer make any reference to the ServerHello message, and simply mention:

  1. The ACME server verifies that during the TLS handshake the
    application-layer protocol “acme-tls/1” was successfully negotiated
5 Likes

Thanks for the feedback !

2 Likes

:wave: Hi @hjacquemin,

That’s cool :slight_smile: I bet folks in the community forum would be interested in reading your thesis after you’ve defended it. Don’t be shy about posting a link here when it’s ready!

I think @_az hinted at this in their answer about your specific question (thanks!) but I wanted to make explicit that draft-ietf-acme-tls-alpn-01 is an out of date reference. draft-ietf-acme-tls-alpn-07 is the most up to date reference and is the draft that’s in the RFC editor queue now.

One important difference between -01 and -07 is the id-pe-acmeIdentifier OID used. It was changed to avoid a conflict. Boulder happens to allow both for the time being but that will change one day and using the -07 OID will be important for broader compatibility.

Hope that helps!

2 Likes

Thanks for the complementary information.

My thesis will be written in French it will ba hard to publish it here…

I have a last question, in the certificate generated during the challenge how is encoded the value of the ip-pe-acmeIdentifier OID ?

how I can decode this:

1.3.6.1.5.5.7.1.31: critical
                . ..,`x..$..g.^..Y..Dxw.+.......7.

First part = OID but how can I decode the value . ..,x…$…g.^…Y…Dxw.+…7.` ??

Thanks

2 Likes

https://datatracker.ietf.org/doc/draft-ietf-acme-tls-alpn/?include_text=1 [page 2]

id-pe-acmeIdentifier OBJECT IDENTIFIER ::= { id-pe 31 }

The extension has the following ASN.1 [X.680] format :

Authorization ::= OCTET STRING (SIZE (32))

The extnValue of the id-pe-acmeIdentifier extension is the ASN.1 DER
encoding [X.690] of the Authorization structure, which contains the
SHA-256 digest of the key authorization for the challenge.

2 Likes

Hi @orangepizza I read that too in the RFC but do you know an online tool to decode this ?

1 Like

Peut-être non! Nous avons un sous-forum français. Je parle un petit peu aussi :slight_smile:

You can find general purpose ASN.1 decoders online (e.g. this one) but that will only help you get some raw unencoded extension value bytes.

There likely isn’t a general purpose web tool that is aware of the TLS-ALPN-01 extension OID and semantics for decoding. Here’s a quick Go program (no error checking!) you can run online as a starting point: https://play.golang.com/p/6RCf4qFAfcm

You can give it a PEM encoded TLS-ALPN-01 challenge response certificate in place of testCert and it will print something like:

TLS-ALPN-01 extension value (32 bytes): f3ee591db1cab0c4a1e58ad009c022a814fe7362526ebd0ca39639b54ff53fbe

The decoded value should always be 32 bytes because it’s an ASN.1 encoded SHA256 digest (32 bytes == 256 bits).

Hope that helps!

1 Like