Skip to content

Use platform native implementation of TLS/SSL #214

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

Closed
LukaszDargiewicz opened this issue Nov 7, 2016 · 17 comments
Closed

Use platform native implementation of TLS/SSL #214

LukaszDargiewicz opened this issue Nov 7, 2016 · 17 comments

Comments

@LukaszDargiewicz
Copy link

On windows openssl is not using system certificate store. Even if you have postgresql server secured with qualified certificate, you need to provide its qualified CA certificate for successful handshake.
This CA certificate should be in system certificate store.
Solution is to use native tls implementation which have access to system certificate store.

@sfackler
Copy link
Owner

sfackler commented Nov 7, 2016

The TLS implementation is pluggable - there are currently implementations for OpenSSL and OSX's Secure Transport. The only reason an SChannel implementation is missing is that I don't have Postgres installed on my Windows machine :). Would you be interested in making a PR with an implementation using the https://crates.io/crates/schannel crate?

@LukaszDargiewicz
Copy link
Author

LukaszDargiewicz commented Nov 7, 2016 via email

@sfackler
Copy link
Owner

sfackler commented Nov 9, 2016

I've just added support for the native-tls crate, which will use SChannel on Windows: 667b730

It would still be reasonable to support schannel directly, of course!

@LukaszDargiewicz
Copy link
Author

I've just pushed branch origin into my fork with 2 commits.
I have no success with testing schannel-rs support in rust-postgres so far.
When connecting to postgresql server:

  • using native-tls implentation I get error "Credentials provided are incomplete and unverificable (os error 590624)" (translated)
  • using mine schannel implementation I got error "Server and client cannot communicate, because not using common algorithm. (os error -2146893007)" (translated)
  • using openssl implementation with mine-inroduced custom Openssl method and provide ca certificate file i got connected no problem.

Looking in rust-native-tls code i found that when building credentials on credentials builder it is executed only enable_protocols method with provided tls1+ protocols.
When I connect with my schannel implementation I got the same error 590624. When I additionally provide (all) supported_algorithms (also tried different algorithms combination) to credential builder I got error -2146893007.

@sfackler
Copy link
Owner

The certificate error is probably because the certificate your Postgres is configured with isn't registered in your system's trust root.

@LukaszDargiewicz
Copy link
Author

I have no problem connecting without providing ca certificate with pgjdbc or pgadmin3 or odbc etc. Certificate is qualified. I need to provide ca certificate to openssl only in windows. Just checked on linux it works without provide ca certificate.

@sfackler
Copy link
Owner

All of those things have different trust stores. pgjdbc will pull it from the Java keystore. pgadmin will apparently ignore the certificate entirely by default (!). If it's working on Linux, I'd assume it's because the root certificate was added to the trust store there.

@LukaszDargiewicz
Copy link
Author

In pgadmin ssl is set required (checked certificate). Certificate is trusted by Certum Trusted Network CA.
Certificate is not custom added to trust store.

@sfackler
Copy link
Owner

Oh, not totally sure if it's commercially signed, unless Windows doesn't trust that root maybe?

@LukaszDargiewicz
Copy link
Author

trust

@LukaszDargiewicz
Copy link
Author

What about ODBC mentioned earlier?

@sfackler
Copy link
Owner

I'm not familiar with ODBC personally, unfortunately.

The trust issue seems like something that should be filed against the schannel-rs repo I think, ideally with a repro against a publicly accessible server.

@LukaszDargiewicz
Copy link
Author

LukaszDargiewicz commented Nov 10, 2016

I just tested simple test connection to web server via tls (same server host as postgresql's and same certificate with same ca-bundle) using example code in test.rs in schannel-rs and it succeed.
I think it is something strange with postgresql communication protocol or used algorithms.

I could test that simple connection to postgresql via tlsstream but I don't know how to talk to postgres.

@sfackler
Copy link
Owner

Interesting!

Doing a TLS handshake with Postgres takes a bit of work, but isn't too terrible:

  1. Open a TCP connection.
  2. Write a big endian 32 bit 8 value, followed by a big endian 32 bit 80877103 value.
  3. Read a single byte - it should be a b'S'.
  4. Do a TLS handshake like normal.

@LukaszDargiewicz
Copy link
Author

The same errors with simple connection... but I found the cause. It was postgresql server configuration. According to documentation when in postgresql.conf is defined ssl_ca_file, then certificate from that file is used for validating client certificate provided by client (what?) even if actually this certificate is not used after. Without ssl_ca_file this client certificate is not verified and connection is successful.
After this both implementations (native-tls and schannel) are usable. Also tested native-tls in linux.

@LukaszDargiewicz
Copy link
Author

I like this native-tls implementation - simple and multiplatform.

@sfackler
Copy link
Owner

Ah ha! Client certificate authentication is a somewhat rarely used feature of SSL.

Glad you're finding native-tls useful!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants