pact-net icon indicating copy to clipboard operation
pact-net copied to clipboard

'WithSslVerificationDisabled' doesnt disable ssl verification

Open bulat30 opened this issue 1 year ago • 12 comments
trafficstars

I'm trying to implement a simple provider test using pact-broker as the pact source. But I get a certificate verification error when connecting to the broker, although I use WithSslVerificationDisabled. I also tried using the PACT_DISABLE_SSL_VERIFICATION and PACT_BROKER_DISABLE_SSL_VERIFICATION variables, but the error persists Package - "PactNet" Version="4.5.0", OS - windows, framework - net7.0

Environment.SetEnvironmentVariable("PACT_DISABLE_SSL_VERIFICATION", "true");
Environment.SetEnvironmentVariable("PACT_BROKER_DISABLE_SSL_VERIFICATION", "true");
var pactVerifier = new PactVerifier(new PactVerifierConfig() { Outputters = new[] { new XunitOutput(testOutputHelper) }, LogLevel = PactLogLevel.Debug });
pactVerifier
               .ServiceProvider("my_service", new Uri("http://localhost:5000"))
               .WithPactBrokerSource(new Uri("https://myhost"), opt =>
                   {
                       opt.PublishResults(Guid.NewGuid().ToString());
                   })
               .WithSslVerificationDisabled()
               .Verify();

Verifier Logs: reqwest::async_impl::client: rustls failed to parse DER certificate MissingOrMalformedExtensions Certificate pact_verifier::pact_broker: Fetching path '/' from pact broker rustls::conn: Sending fatal alert BadCertificate pact_verifier: Failed to load pact - \x1b[31mCould not load pacts from the pact broker.

bulat30 avatar Feb 09 '24 09:02 bulat30

@mefellows this looks like an FFI error similar to the one I found a while ago about falling to parse certs.

It looks like it still tries to load the cert bundle when when SSL verification is disabled, and it's the parsing that fails.

adamrodger avatar Feb 09 '24 16:02 adamrodger

@adamrodger Could you tell please when i can expect a fix? And is there any way to temporarily bypass this bug?

bulat30 avatar Feb 10 '24 10:02 bulat30

The defect is in a different library, not in PactNet. Pull requests are gratefully expected if this is urgent.

Alternatively your quickest option will be to identify and remove and invalid certificate on your machine so that it doesn't fail to parse.

adamrodger avatar Feb 10 '24 14:02 adamrodger

@bulat30 the issue is an underlying dependency attempts to load all certificates from the host into a trust store, so that when outbound https calls are made, it can compare the presented certificate to those chains that are trusted.

There is a certificate on your host somewhere that is invalid, and that's the issue that we're seeing. I thought we had found the library that caused the issue, but that was actually a different problem.

I'll create a tracking issue upstream to fix this.

See also the original upstream issue.

mefellows avatar Feb 13 '24 06:02 mefellows

@mefellows thanks! i tried to load all certificates chain from the broker host into a trust store on client side using a browser, and also tried to specify the path to these certificates using the SSL_CERT_DIR variable and the path to each of the certificates using SSL_CERT_FILE, but, unfortunately, every time I get BadCertificate error (rustls::conn: Sending fatal alert BadCertificate)

bulat30 avatar Feb 13 '24 07:02 bulat30

No worries. Unfortunately none of those options would circumvent the issue described above.

You could use the repro Adam created here to potentially find and understand which certificate is causing the problem. It might be the one presented in the pact broker (presumably it's a self-signed cert?) so you might start there.

mefellows avatar Feb 13 '24 07:02 mefellows

I was just trying to remember where that sample app was 😂

I thought the native TLS lib had changed so that you can handle parsing errors in user code, but perhaps not? Or is it a dependency of a dependency so we don't get the chance to handle the error?

adamrodger avatar Feb 13 '24 19:02 adamrodger

I thought the native TLS lib had changed so that you can handle parsing errors in user code, but perhaps not? Or is it a dependency of a dependency so we don't get the chance to handle the error?

Yeah it was, but that was handled in a dependency of a dependency. This error looks related but I think is slightly different.

In the linked issue above, I actually think the disabling of certificate checking is behind a rust feature that doesn't apply to the rust feature of the TLS library we use. That is, in my reading at least, the method is a no-op which is why we are getting this error.

mefellows avatar Feb 13 '24 22:02 mefellows

I found invalid certificates only on clientside and the errors "reqwest::async_impl::client: rustls failed to parse DER certificate MissingOrMalformedExtensions Certificate" disappeared. But I still get the BadCertificate error :( Logs: INFO ThreadId(01) pact_verifier::pact_broker: Fetching path '/' from pact broker DEBUG ThreadId(01) reqwest::connect: starting new connection: https:// DEBUG ThreadId(01) hyper::client::connect::http: connecting to DEBUG ThreadId(01) rustls::client::hs: No cached session for DnsName(DnsName(DnsName("")))
DEBUG ThreadId(01) rustls::client::hs: Not resuming any session WARN ThreadId(01) rustls::conn: Sending fatal alert BadCertificate
ERROR ThreadId(01) pact_verifier: Failed to load pact - \x1b[31mCould not load pacts from the pact broker

bulat30 avatar Feb 14 '24 08:02 bulat30

That looks more like the certificate of the broker you're using is invalid to me. I'm not sure if you're using a self hosted broker or Pactflow though.

adamrodger avatar Feb 15 '24 08:02 adamrodger

Im using self hosted broker with self signed certificate. rustls-native-certs didn't find invalid certs on the broker host

bulat30 avatar Feb 15 '24 08:02 bulat30

Yeah so that means that the host where you're running the tests doesn't trust the cert being used by the broker.

I can't really help you with that because that depends if/how you configure those certs, and PactNet is behaving as expected in the scenario where that's not configured properly.

Your best bet is to try and use something like curl -v https://broker.example.org to connect to the broker from the machine running the tests, and that will allow you to confirm when the certificate is properly trusted by the OS without needing PactNet in the loop at all. Once that works then PactNet will also.

adamrodger avatar Feb 15 '24 10:02 adamrodger