Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TLS: Improve story with intermediate and/or multiple CAs #1220

Open
PiotrSikora opened this issue Jul 7, 2017 · 19 comments · Fixed by #1251
Open

TLS: Improve story with intermediate and/or multiple CAs #1220

PiotrSikora opened this issue Jul 7, 2017 · 19 comments · Fixed by #1251
Labels
area/tls enhancement Feature requests. Not bugs or questions. help wanted Needs help!

Comments

@PiotrSikora
Copy link
Contributor

(forked from #615)

Currently, Envoy assumes that:

  • there is single CA in ca_cert_file (at least when it comes to client certificates, displaying CA information and calculating expiration dates),
  • there are no intermediates in cert_chain_file (at least for the purpose of calculating expiration dates).

@mattklein123 How useful is the expiration date tracking in practice? Are you using this in production?

@timperrett Could you verify that this fixes the issues you described in #615?

diff --git a/source/common/ssl/context_impl.cc b/source/common/ssl/context_impl.cc
index 1ca93c4b7..aa94ba32f 100644
--- a/source/common/ssl/context_impl.cc
+++ b/source/common/ssl/context_impl.cc
@@ -45,9 +45,12 @@ ContextImpl::ContextImpl(ContextManagerImpl& parent, Stats::Scope& scope, Contex
           fmt::format("Failed to load verify locations file {}", config.caCertFile()));
     }
 
-    // This will send an acceptable CA list to browsers which will prevent pop ups.
-    rc = SSL_CTX_add_client_CA(ctx_.get(), ca_cert_.get());
-    RELEASE_ASSERT(1 == rc);
+    bssl::UniquePtr<STACK_OF(X509_NAME)> list(SSL_load_client_CA_file(config.caCertFile().c_str()));
+    if (nullptr == list) {
+      throw EnvoyException(
+          fmt::format("Failed to load verify locations file {}", config.caCertFile()));
+    }
+    SSL_CTX_set_client_CA_list(ctx_.get(), list.release());
 
     verify_mode = SSL_VERIFY_PEER;
   }
@mattklein123
Copy link
Member

How useful is the expiration date tracking in practice? Are you using this in production?

Extremely useful. We have dashboards and alarms based on this information. Definitely can't lose it.

@mattklein123 mattklein123 added the enhancement Feature requests. Not bugs or questions. label Jul 7, 2017
@timperrett
Copy link
Contributor

@mattklein123 huh, this should be documented for sure - i had no idea Envoy reported that information! That would indeed be useful when using externally rooted certificates

@timperrett
Copy link
Contributor

@PiotrSikora absolutely - i'll do it mid-morning and report back. Thanks for tracking this down!

@mattklein123
Copy link
Member

@timperret the admin endpoint is documented (though it could be better):
https://lyft.github.io/envoy/docs/operations/admin.html#get--certs

But I don't think the server level stats are now that I search for it:
https://github.com/lyft/envoy/blob/master/source/server/server.h#L37

Will make a note to document unless someone else gets to it first.

@timperrett
Copy link
Contributor

@PiotrSikora excellent - this does indeed seem to resolve the issue. I tried the scenarios previously enumerated in #615, and it works!

HUZZAH!

Nice one @PiotrSikora 🍻 🏅

@timperrett
Copy link
Contributor

@PiotrSikora one bit of feedback on this change: in certain cases, I need to use a browser (mainly for tooling cases that are secured with mTLS). Safari prompts me for a client certificate, but Chrome and Firefox do not... they seem to get stuck in a loop of some kind. When we use the same certs with nginx this doesn't happen, so im wondering if there's some subtle bug here?

@timperrett
Copy link
Contributor

@PiotrSikora ok some more information on this: best i can tell right now, it appears that its actually verifying against the list of CAs (as per my previous note at the end of last week), but what its not doing - and i believe this is incorrect - is its still only presenting the head of the list as an acceptable client CA, which is why the browsers don't prompt for a choice.

@PiotrSikora
Copy link
Contributor Author

PiotrSikora commented Jul 11, 2017

@timperrett it definitely sends a list of CAs with the patch. You can see that list when connecting with openssl s_client, under Acceptable client certificate CA names. It's 1 item with the master branch, and multiple items with the patch.

I also verified that the CertificateRequest message is sent to Chrome with both: tcpdump and chrome://net-internals.

Please note that Chrome won't ask for the client certificate (via the popup window) if it doesn't have any certificate that matches client certificate CA from the list sent by the server... But you say that it works with NGINX, so it should have matching certificate.

Are you using exactly the same files with both: NGINX & Envoy? NGINX is also using SSL_CTX_set_client_CA_list(), so there shouldn't be a difference.

You didn't revert the patch, by any chance, did you?

@timperrett
Copy link
Contributor

@PiotrSikora todays lesson is that Tim should not be programming past midnight, as no productive work can happen. Had been upgrading Envoy and testing out various patches and did indeed use the wrong build when i was testing this on another project, making last nights lack of sleep entirely fruitless.

Very sorry for the noise - i've re-tested this morning with the correct build and yep, you're right: its sending down the full list of acceptable CAs. 🍻

@mattklein123 mattklein123 added this to the 1.4.0 milestone Jul 12, 2017
PiotrSikora added a commit to PiotrSikora/envoy that referenced this issue Jul 12, 2017
Partially fixes envoyproxy#1220.

Signed-off-by: Piotr Sikora <piotrsikora@google.com>
@mattklein123
Copy link
Member

@PiotrSikora this got auto closed by the other PR. Since you said "partially fixes" I'm going to reopen this. Let me know if it should be closed.

@mattklein123 mattklein123 reopened this Jul 13, 2017
@PiotrSikora
Copy link
Contributor Author

The negotiation with multiple CAs is fixed, the part that's still broken is /certs and calculating expiration dates. Should we track it here (and keep this open) or split into another issue? Up to you, I don't have a preference.

@mattklein123
Copy link
Member

Tracking here is fine with me.

@mattklein123 mattklein123 modified the milestones: 1.4.0, 1.5.0 Aug 4, 2017
@mattklein123 mattklein123 modified the milestones: 1.5.0, 1.6.0 Nov 3, 2017
@mattklein123 mattklein123 removed this from the 1.6.0 milestone Jan 13, 2018
@stale
Copy link

stale bot commented Jun 20, 2018

This issue has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in the next 7 days unless it is tagged "help wanted" or other activity occurs. Thank you for your contributions.

@stale stale bot added the stale stalebot believes this issue/PR has not been touched recently label Jun 20, 2018
@mattklein123 mattklein123 added the help wanted Needs help! label Jun 20, 2018
@stale stale bot removed the stale stalebot believes this issue/PR has not been touched recently label Jun 20, 2018
@kramerul
Copy link

kramerul commented Oct 18, 2018

We are also interested in supporting this scenario.

But in our case I think it looks a little bit different.
We would like to have an intermediate CA ( subca.crt signed by a root CA ca.crt), which is not known to envoy, but envoy is aware of the root CA ca.crt. It should be possible to open the connection to envoy with a client certificate subca-client.crt, which is signed by this intermediate CA subca.crt.

Openssl supports such a scenario:

openssl s_server -accept 9001 -www  -CAfile ca.crt \
    -cert server.crt -key server.key  -verify 3
openssl s_client   -connect  <server>:9001   \
   -key subca-client.key -cert subca-client.crt  \
    -CAfile subca.crt   \
    -servername <server>

rshriram pushed a commit to rshriram/envoy that referenced this issue Oct 30, 2018
Automatic merge from submit-queue.

Update Envoy SHA to version 1.6.0

Signed-off-by: Gary Brown <gary@brownuk.com>

**What this PR does / why we need it**:
This PR updates the Envoy SHA to use the commit associated with version 1.6.0. This version includes an update to propagate the B3 sampled header value.

**Release note**:

```release-note
NONE
```
@dsymonds
Copy link

I am also interested in improvements here.

My use case has not been directly mentioned before: it is to support TLS cert rotation when using plain certs as a CA file. That is, I have Envoy doing TLS termination for clients that provide self-signed certificates. Envoy is configured to load those same certs as the downstream tls_context.common_tls_context.validation_context.trusted_ca. This works fine, except when trying to rotate certs gracefully with the usual three-step shuffle of loading both certs into the trusted CA pool, switching clients to using the new certs, then unloading the old cert from the trusted CA pool. Envoy only checks client-presented certs against the first entry in the CA pool, when it seems like it could easily check them all.

@tazmanian10
Copy link

Hello,

I have been trying to set multiple trusted CAs through Secret Discovery Service, however it seems that only the first one in the file is taken into account. Is there any other way i am missing out in order to set a list of trusted CAs, or is the feature not supported at all through SDS?

@PiotrSikora
Copy link
Contributor Author

Multiple trusted CAs should work in the same file / SDS resource. How are you testing this, exactly? In any case, please open a separate issue, since this issue is tracking expiration date when using intermediate certificates.

@jhanbo
Copy link

jhanbo commented Aug 19, 2021

Hello, we are facing the same issue, just only the first certificate in the file is picked up and the rest is ignored

@jhanbo
Copy link

jhanbo commented Sep 28, 2021

Hello, we are facing the same issue, just only the first certificate in the file is picked up and the rest is ignored

Hello, just to confirm, it works pretty fine. Our issue was that we used Multiple CAs which have the same issuer.

jpsim pushed a commit that referenced this issue Nov 28, 2022
Description: This PR implements all of the enum-related code, like translating between string- and enum-representations. It also implements `RetryPolicy`, since it's related to `RetryRule` (and defined in the same file).

Risk Level: Low
Testing: N/A, will follow up when everything is finished with e2e testing + unit testing in Python and/orC++
Docs Changes: N/A
Release Notes: N/A

Signed-off-by: Cerek Hillen <chillen@lyft.com>
Signed-off-by: JP Simard <jp@jpsim.com>
jpsim pushed a commit that referenced this issue Nov 29, 2022
Description: This PR implements all of the enum-related code, like translating between string- and enum-representations. It also implements `RetryPolicy`, since it's related to `RetryRule` (and defined in the same file).

Risk Level: Low
Testing: N/A, will follow up when everything is finished with e2e testing + unit testing in Python and/orC++
Docs Changes: N/A
Release Notes: N/A

Signed-off-by: Cerek Hillen <chillen@lyft.com>
Signed-off-by: JP Simard <jp@jpsim.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/tls enhancement Feature requests. Not bugs or questions. help wanted Needs help!
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants