Skip to main content

SSLStream support added to Npgsql!

Yesterday I merged a pull request which adds support to .Net SSLStream in Npgsql.

When Npgsql development started, in 2002, there was no SSL support in .net 1.0 and 1.1. It was added later in .net 2.0 but the support to SSLStream was never added to Npgsql.

This all changed a few weeks ago when Dave G created a patch which adds support to .Net SSLStream in Npgsql. He also said that one of the motivations was the fact that the current SSL support was returning error when using client certificate authentication. (I'll post a tutorial about how to use client certificates later)

There is a very old feature request (like since 2005!) to somehow create a single Npgsql.dll which incorporates Mono.Security.dll assembly. This would easy the deployment of Npgsql and version control. This feature request generated a discussion about the removal of Mono.Security dependency and possible impact in current user code. 

In order to get the lowest impact by this change, instead of immediately remove the callbacks and break a lot of user code, I asked Dave to keep the callbacks and mark them obsolete. This way,  users will be warned about those callbacks instructed to use the SSLStream RemoteCertificateValidationCallback instead.

In order to use the new SSL code, you just need to add a callback to ValidateRemoteCertificateCallback.
It can be as simple as:

NpgsqlConnection conn = new NpgsqlConnection(CONNSTRING);
conn.ValidateRemoteCertificateCallback += (abc=> { return true; };


This callback simply returns true indicating you are accepting the server certificate. Obviously, returning true without doing any validation should be done for testing purposes only.

Please, give it a try and let me know if you have any problems. 

Comments

Unknown said…
Hi Francisco.

Please, tell me how to connect to PostgreSQL database with SSL encryption and client certificate. May be you have some example on VB.NET or C#.

I try to use the following code for Npgsql:

'=======================================================
Imports System.Security.Cryptography.X509Certificates
Imports System.Security.Cryptography
Imports Npgsql

Public Class Form1

Private WithEvents cnn As NpgsqlConnection

Private Sub cmdConnection_Click(sender As Object, e As EventArgs) Handles cmdConnection.Click
System.Net.ServicePointManager.ServerCertificateValidationCallback = New System.Net.Security.RemoteCertificateValidationCallback(AddressOf bypassAllCertificateStuff)
cnn = New NpgsqlConnection
cnn.ConnectionString = "Server=serveraddress.ru;Port=5432;Database=documents;Userid=ArchiveUser;Password=mypassword;SSL=true;SslMode=Require;"
cnn.Open()
'test connection only
cnn.Close()
MsgBox("OK")
End Sub

'callback for client's certificate
Private Sub cnn_ProvideClientCertificatesCallback(certificates As X509CertificateCollection) Handles cnn.ProvideClientCertificatesCallback
Dim cert As X509Certificate2 = New X509Certificate2("C:\Users\programmer\Documents" & "\client.pfx", "mypassword")
certificates.Add(cert)
End Sub

'callback for server's certificate
Friend Function bypassAllCertificateStuff(ByVal sender As Object, ByVal cert As System.Security.Cryptography.X509Certificates.X509Certificate, ByVal chain As System.Security.Cryptography.X509Certificates.X509Chain, ByVal [error] As System.Net.Security.SslPolicyErrors) As Boolean
'trust any certificate
Return True
End Function
End Class
'=======================================================

I have two certificates on client: "client.crt" and "client.key". This certificates can work properly with ODBC driver.
Then I make "client.pfx" from "client.crt" and "client.key" by this command:

openssl pkcs12 -inkey client.key -in client.crt -export -out client.pfx

VB.NET can load this pfx container and show information about this certificate and it's private key (HasPrivateKey property is True).

Also I can load this pfx to Windows store and get it back with private key from there. Npgsql also cannot work with this certificate from store.

I always recieve the error "28000 connection requires a valid client certificate". PostgreSQL writes log "SSL connection from (anonymous)".

CN in certificate is the same as Userid in connection string.

What is wrong?

Maxim Sitnikov.
Hi, Maxim!

Why are you using this line:
System.Net.ServicePointManager.ServerCertificateValidationCallback = New System.Net.Security.RemoteCertificateValidationCallback(AddressOf bypassAllCertificateStuff)

You should pass this callback to NpgsqlConnection. I think this may be your problem.

I don't know vb.net very well and I may be missing somethig, but I think that as long as you set the callback to NpgsqlConnection, you should get it working as this callbacks makes use of your client certificate.

I hope it helps.
conan said…
J'ai eu la chance de rattraper un peu le chef Gillespie. En fait, sa passion pour les montres a causé quelques ennuis sur le tournage du spectacle.rolex pas cher En répondant à son désir de porter ses Pelagos à l'antenne, Gillespie a déclaré: "J'ai littéralement dû mendier de récupérer ma montre des producteurs! Personne n'est censé pouvoir porter une montre parce que de nos jours,fausse montre la plupart des gens ont des montres numériques qui pourrait être utilisé pour obtenir des informations autres que le temps. Je devais leur prouver que ma montre était "démodée" et simplement dire l'heure. "

Popular posts from this blog

Npgsql Tips: Using " in (...)" queries with parameters list and "any" operator

Hi, all! We have received some users questions about how to send a list of values to be used in queries using the "in" operator. Something like: select foo, bar from table where foo in (blah1, blah2, blah3); Npgsql supports array-like parameter values and the first idea to have this working would try to use it directly: NpgsqlCommand command = new NpgsqlCommand("select * from tablee where field_serial in (:parameterlist)", conn); ArrayList l = new ArrayList(); l.Add(5); l.Add(6); command.Parameters.Add(new NpgsqlParameter("parameterlist", NpgsqlDbType.Array | NpgsqlDbType.Integer)); command.Parameters[0].Value = l.ToArray(); NpgsqlDataReader dr = command.ExecuteReader(); but unfortunately this won't work as expected. Npgsql will send a query like this: select * from tablee where field_serial in ((array[5,6])::int4[]) And Postgresql will complain with the followin...

Fixed! LOG: unexpected EOF on client connection

Hi all! Since we implemented connection pool in Npgsql, we received some complaints about EOF log messages being generated on Postgresql logs when using Npgsql. This was caused by Npgsql not sending the proper terminate message to Postgresql on pooled connections when the application terminated or more specifically when the assembly was unloaded. This is a long time problem with Npgsql connection pool. I even talked about it in the past . Up to now, I had no idea about how to fix that as I wasn't able to close the connections in the pool. When I tried to put a finalizer in NpgsqlConnectorPool, which would be triggered when the assembly was unloaded, I received object already disposed exceptions when trying to send something to the stream. That's when I came up with the "excellent" idea of subclassing the networkstream class and override its Dispose method so that I could send the postgresql terminate message before it was disposed! :) It worked like a charm! ...

Npgsql 2.2.0 final release is out!

This is Npgsql 2.2.0 Final Release This release contains 249 commits since the last stable release. Includes bug fixes, improvements and new features. Update notice: If you have been using Npgsql 2.2.0-rc2, you don't need to update to this version. They are the same except for the Assembly version information. Major highlights Visual Studio DDEX support   Kenji Uno added support for DDEX. Now you can use Npgsql with Visual Studio data designer. This is a missing feature a lot of our users requested in the past. Kenji added a tutorial about how to use Npgsql with DDEX. You can find it here: https://github.com/npgsql/Npgsql/wiki/Visual-Studio-Design-Time-Support---DDEX-Provider#install-npgsqlddexprovidervsix   Entity Framework   David Karlaš added support for EFMigration and Database creation in EF6+. Now it is possible to start Code First projects without needing to create a database upfront. EntityFramework and Npgsql will take care of it. E...