Skip to content

Preserve configured order of intermediate CA certificate chain#956

Closed
rousskov wants to merge 1 commit intosquid-cache:masterfrom
measurement-factory:SQUID-642-preserve-port-CAs-order
Closed

Preserve configured order of intermediate CA certificate chain#956
rousskov wants to merge 1 commit intosquid-cache:masterfrom
measurement-factory:SQUID-642-preserve-port-CAs-order

Conversation

@rousskov
Copy link
Contributor

@rousskov rousskov commented Jan 5, 2022

https_port ... tls-cert=signing,itsIssuer,itsIssuerIssuer.pem

The order was reversed in commit cf48712, probably by accident. Wrong
order violates TLS protocol and breaks TLS clients that are incapable of
reordering received intermediate CAs. Squid deployments that use
wrong-order bundles (to compensate for this bug) should reorder their
bundles when deploying this fix (or wait for Squid to order certificates
correctly, regardless of the bundle order -- a work in progress).

This is a Measurement Factory project.

@rousskov
Copy link
Contributor Author

rousskov commented Jan 5, 2022

PR description: ... or wait for Squid to order certificates correctly, regardless of the bundle order -- a work in progress

Those changes are nearly ready. I extracted this order fix and the #955 changes from a large/complex patch that improves certificate handling. That patch is finishing internal review/testing cycles. Factory will post the corresponding PR (or PRs) when these two surgical fixes are closed.

    https_port ... tls-cert=signing,itsIssuer,itsIssuerIssuer.pem

The order was reversed in commit cf48712, probably by accident. Wrong
order violates TLS protocol and breaks TLS clients that are incapable of
reordering received intermediate CAs. Squid deployments that use
wrong-order bundles (to compensate for this bug) should reorder their
bundles when deploying this fix (or wait for Squid to order certificates
correctly, regardless of the bundle order -- a work in progress).

OpenSSL sends the signing certificate first. After that, OpenSSL sends
certificates in the order they are stored in the chain, so we must push
them in on-the-wire order, as defined by RFC 8446 Section 4.4.2: "The
sender's certificate MUST come in the first CertificateEntry in the
list. Each following certificate SHOULD directly certify the one
immediately preceding it."
@rousskov rousskov force-pushed the SQUID-642-preserve-port-CAs-order branch from 600c204 to 5ee4efa Compare January 5, 2022 18:36
Copy link
Contributor

@yadij yadij left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Veto. The relevant RFC 8446 text is "Each following certificate SHOULD directly certify the one immediately preceding it."

Note the words preceding it. That means the chain is required to have the following syntax:
cert -> issuer CA 1 -> issuer CA 2 -> (optional) root CA

The value stored in latestCert is verified by X509_check_issued() to be certified by the previous entry appended to chain (ie its tail). Which makes emplace_back the correct RFC compliant logic if we assume the input file is correct.

@rousskov
Copy link
Contributor Author

rousskov commented Jan 7, 2022

Veto. The relevant RFC 8446 text is "Each following certificate SHOULD directly certify the one immediately preceding it."

Note the words preceding it. That means the chain is required to have the following syntax: cert -> issuer CA 1 -> issuer CA 2 -> (optional) root CA

Official code violates the above RFC requirement. Official code reverses the RFC-prescribed chain order to become: (optional) root CA -> issuer CA 2 -> issuer CA 1.

Here is a simplified (but equivalent) version of the official code and the proposed change, preserving unfortunate official variable names:

  ca = loadNextCertificateFromTheBundle();
  X509_check_issued(ca, latestCert); // i.e. ca signed/issued/certified latestCert
- chain.emplace_front(ca); // XXX: LIFO; Root (the last certificate to load) becomes the first chain entry
+ chain.emplace_back(ca); // OK: FIFO; Root is the last chain entry
  latestCert = ca;

The value stored in latestCert is verified by X509_check_issued() to be certified by the previous entry appended to chain (ie its tail).

I cannot find a way to interpret what you are saying so that it matches official code. There is an interpretation that matches PR code, but that does not explain your veto.

Here is what is actually going on in this very confusing code, in more precise/clear terms:

  • Squid makes sure that the newly/just loaded-from-the-bundle certificate (ca) signed/issued/certified the previously loaded certificate (misnamed latestCert). This requires that the bundle uses the RFC-recommended on-the-wire certificate order. OK.
  • Official Squid then makes ca the very first certificate in the chain. Bug! For example, the root CA certificate1 is loaded last but becomes the very first certificate in the final chain. It should be the last!
  • PR code then makes ca the very last certificate in the chain. OK.

Which makes emplace_back the correct RFC compliant logic if we assume the input file is correct.

Exactly! Why are you vetoing the PR that does what you describe as "correct RFC compliant logic"? Here is what the PR diff says, verbatim:

-    chain.emplace_front(latestCert);
+    chain.emplace_back(latestCert);

Footnotes

  1. Assuming, for simplicity of the example sake, that the root CA certificate is present in the bundle and is chained by Squid.

@rousskov rousskov requested a review from yadij January 7, 2022 15:27
@rousskov rousskov added the S-waiting-for-reviewer ready for review: Set this when requesting a (re)review using GitHub PR Reviewers box label Jan 7, 2022
@yadij yadij added M-cleared-for-merge https://github.com/measurement-factory/anubis#pull-request-labels and removed S-waiting-for-reviewer ready for review: Set this when requesting a (re)review using GitHub PR Reviewers box labels Jan 9, 2022
@yadij
Copy link
Contributor

yadij commented Jan 9, 2022

Sorry, misread the patch. :( cleared for merge now.

squid-anubis pushed a commit that referenced this pull request Jan 10, 2022
    https_port ... tls-cert=signing,itsIssuer,itsIssuerIssuer.pem

The order was reversed in commit cf48712, probably by accident. Wrong
order violates TLS protocol and breaks TLS clients that are incapable of
reordering received intermediate CAs. Squid deployments that use
wrong-order bundles (to compensate for this bug) should reorder their
bundles when deploying this fix (or wait for Squid to order certificates
correctly, regardless of the bundle order -- a work in progress).

This is a Measurement Factory project.
@squid-anubis squid-anubis added the M-waiting-staging-checks https://github.com/measurement-factory/anubis#pull-request-labels label Jan 10, 2022
@squid-anubis squid-anubis added M-merged https://github.com/measurement-factory/anubis#pull-request-labels and removed M-waiting-staging-checks https://github.com/measurement-factory/anubis#pull-request-labels M-cleared-for-merge https://github.com/measurement-factory/anubis#pull-request-labels labels Jan 10, 2022
squidadm pushed a commit to squidadm/squid that referenced this pull request Jan 23, 2022
…ain (squid-cache#956)

    https_port ... tls-cert=signing,itsIssuer,itsIssuerIssuer.pem

The order was reversed in commit cf48712, probably by accident. Wrong
order violates TLS protocol and breaks TLS clients that are incapable of
reordering received intermediate CAs. Squid deployments that use
wrong-order bundles (to compensate for this bug) should reorder their
bundles when deploying this fix (or wait for Squid to order certificates
correctly, regardless of the bundle order -- a work in progress).

This is a Measurement Factory project.
yadij pushed a commit that referenced this pull request Jan 24, 2022
…ain (#956)

    https_port ... tls-cert=signing,itsIssuer,itsIssuerIssuer.pem

The order was reversed in commit cf48712, probably by accident. Wrong
order violates TLS protocol and breaks TLS clients that are incapable of
reordering received intermediate CAs. Squid deployments that use
wrong-order bundles (to compensate for this bug) should reorder their
bundles when deploying this fix (or wait for Squid to order certificates
correctly, regardless of the bundle order -- a work in progress).

This is a Measurement Factory project.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

M-merged https://github.com/measurement-factory/anubis#pull-request-labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

Comments