Tls-alpn-01 Change Cipher Spec

Please fill out the fields below so we can help you better. Note: you must provide your domain name to get help. Domain names for issued certificates are all made public in Certificate Transparency logs (e.g. https://crt.sh/?q=example.com), so withholding your domain name here does not increase secrecy, but only makes it harder for us to provide help.

My domain is: www.rtvnc.com

I ran this command:

It produced this output:

My web server is (include version): custom webserver

The operating system my web server runs on is (include version): Windows 10

My hosting provider, if applicable, is:

I can login to a root shell on my machine (yes or no, or I don’t know): yes

I’m using a control panel to manage my site (no, or provide the name and version of the control panel):

The version of my client is (e.g. output of certbot --version or certbot-auto --version if you’re using Certbot):

Hi

I just wasted 3 days trying to get tls-alpn-01 validation working. The problem turned out to be a missing ‘Change Cipher Spec’ handshake message I wasn’t sending.

I feel these ‘Change Cipher Spec’ messages are unnecessary since the certificate was already sent in the Server Hello.

Please change the draft so these ‘Change Cipher Spec’ messages are no longer required, or at least give a more meaningful error message than 400-invalid .

If you weren’t sending Change Cipher Spec then you weren’t completing the TLS handshake, despite the fact that the final connection in tls-alpn-01 requires that no data be sent and the connection immediately closed after the handshake is complete. It’s simpler not to allow breaking the well-proven protocol just because the last few steps might not be strictly necessary.

5 Likes

I respectfully disagree, if it’s not necessary it should not be enforced. Also wonder what Greta Thunberg might think of all these pki-calculations going on for no good reason :wink:

The CA does try to pass down more specific and meaningful errors whenever possible.

I worked this scenario a little bit and it seems to me that you should have encountered this error:

error code 400 “urn:ietf:params:acme:error:connection”: Timeout during read (your server may be slow or overloaded)

Do you have any suggestion how it could be reasonably improved? Without knowing ahead of time that your server does not plan to send a follow-up to its ServerHello, it doesn’t seem possible to distinguish between a generic read timeout and your issue. Plus, a dropped packet is far more likely.

I can appreciate the desire for this. I tried to implement a TLS-ALPN responder written using an eBPF filter (extremely limited and rudimentary VM), but stuffing the entire TLS handshake into it turned out to be too much of a challenge. Being able to respond with a (basically static) ServerHello would have made this a super trivial task.

But it does feel like tempting fate to do this. A CA is concerned with safety and it’s hard to predict what kind of wacky unintended consequences might come out of it.

3 Likes

I did get the timeouts occasionally, as well as the 400-invalid.

Do you have any suggestion how it could be reasonably improved?

Of course, it could’ve told me ‘Received a valid certificate in Server Hello but failed to complete the handshake’. If that was the error I wouldn’t have looked into possible DNS or network infrastructure issues, and I would’ve known my certificate was accepted.

Being able to respond with a (basically static) ServerHello would have made this a super trivial task.

Indeed, you’d only need to change the extensions, which aren’t encrypted. Well you’d still need SHA256 but that’s it.

But it does feel like tempting fate to do this. A CA is concerned with safety

A CA should also be concerned about efficiency, and simplicity. I doubt this would have any unintended consequences regarding safety.

1 Like

While aborting the connection after the Server Hello message may have worked in TLS 1.2 and older this is not compatible with TLS 1.3 as the ALPN extension is sent in the encrypted extensions message after key negotiation. Instead of having to develop separate versions of the specification for different TLS versions the IETF working group decided it was best to make the challenge version agnostic. Requiring the TLS handshake complete also allows for broader compatibility with off the shelf TLS libraries instead of requiring client developers to roll their own TLS implementations, which would be far more likely to lead to bugs.

6 Likes

Still having some mixed feelings but I’ll accept the TLS version agnosticism argument.

This does lead to some other questions, why aren’t you already using TLSv1.3 and (when) do you plan to end 1.2 support?

They are. If you look in the ClientHello sent by the Let’s Encrypt validation server, the supported_versions extension describes the versions the client is willing to negotiate:

This replaces the old client_version field, which stays at TLS 1.2, allowing the server to negotiate an older version if required.

1 Like

For some reason it’s not sending me the 1.3 option in Client Hello. Any ideas?

You’re right - I was testing against acme-staging-v02. Looks like production has it disabled for now.

Actually, we have TLS 1.3 disabled for both prod and staging. If you’re seeing it in staging we’d like to confirm why. Would you be able to share a packet capture or details of how you reproduced?

For the question of why we haven’t yet enabled TLS 1.3: We’ve just been meaning to check that it doesn’t break things egregiously. We’ll probably roll it out soon!

2 Likes

You right. I triggered an ALPN test by Let’s Debug and then looked at the wrong ClientHello message. This comment reinforced it in my head D:.

2 Likes

Thinking about agnosticism a bit more, why are you putting the challenge response in the certificate instead of simply sending it as an https response using any (possibly static) self-signed certificate? Wouldn’t that be even-more-agnostic since you’re not depending on the acme-tls/1 not getting dropped by some outdated server or ambitious network administrator? The challenge response would also be encrypted for little extra cost (since you’re negotiating keys anyway). What about session reuse (or persistent https connections) for customers (like myself) who will request multiple certificates sequentially, I’d imagine this won’t work if the certificate changes for every domain?

1 Like

tls-alpn challenge is based upon this article of CA/B baseline

3.2.2.4.10. TLS Using a Random Number
Confirming the Applicant’s control over the FQDN by confirming the presence of a Random Value within a Certificate on the Authorization Domain Name which is accessible by the CA via TLS over an Authorized Port.

And I think CA cannot ignore certificate error when access https page.

1 Like

You can configure your “tls-alpn-01” responder to answer with a different certificate depending on the domain that was requested in the handshake, so this should work fine.

Thanks for the update! FWIW when I tried to reproduce this I also wound up looking at the wrong ClientHello message for a while and got very confused.

Sorry for the confusing comment on #4489; we just never wound up actually deploying the change, but it’s queued up now.

And I think CA cannot ignore certificate error when access https page.

Well they’re already forcing a complete handshake and don’t allow any certificate/protocol errors. The symmetric keys are already negotiated and can be used for regular https traffic unless I’m missing smth.

You can configure your “tls-alpn-01” responder to answer with a different certificate depending on the domain that was requested in the handshake, so this should work fine.

Please elaborate. How exactly are you going to avoid the key renegotiation for different domains? Fairly sure it can’t be done for <= 1.2, not sure about 1.3+ but it seems tricky.

Perhaps I misunderstood you. There is no goal, implicit or explicit, to reuse TCP connections across validations for multiple domains that share an IP address. TCP connections are cheap relative to certificate issuance, so this would add complexity without significant benefits.

this would add complexity without significant benefits

I’m not sure what your ratio #(sub)domains/#users is but your processing power requirements (for the tls-alpn-01 validation) should reduce by close to that factor if you somehow manage to avoid key renegotiation and reuse sessions/connections. It might be insignificant considering all other https calls you’re processing, idk. It would be easy if the validation response was sent as regular https content…

Update: We’ve enabled outbound TLS 1.3 for validation requests in both staging and production.

6 Likes