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

UUID datatype and COPY IN/OUT support added to cvs

Hi all! It was just added support to uuid datatype in cvs head. This type will be available in next Postgresql release 8.3. Thanks to David Bachmann for his patch! You can get more info about this patch in this mailing list post . Also was added support for copy in and copy out operations. Now, users can provide streams which can be copied directly to and from Postgresql tables! Thanks to Kalle Hallivuori for providing a patch! Thanks to Truviso for giving support to Kalle. More info about that including a demo and ready to use compiled Npgsql.dll versions can be found here . That's it! As soon as we get more features added, I will post info about them here. Stay tuned! :)

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

Stream seek error

Hi all! Since Npgsql RC1, we started to receive some error reports about problems when closing connections. The typical stack trace looked like this: System.NotSupportedException : This stream does not support seek operations. at System.Net.Sockets.NetworkStream.Seek(Int64 offset, SeekOrigin origin) at System.IO.BufferedStream.FlushRead() at System.IO.BufferedStream.WriteByte(Byte value) − at Npgsql.NpgsqlQuery.WriteToStream(Stream outputStream) in C:\Npgsql\Npgsql2\src\Npgsql\NpgsqlQuery.cs:line 62 − at Npgsql.NpgsqlReadyState.QueryEnum(NpgsqlConnector context, NpgsqlCommand command) in C:\Npgsql\Npgsql2\src\Npgsql\NpgsqlReadyState.cs:line 64 − at Npgsql.NpgsqlConnector.ReleasePlansPortals() in C:\Npgsql\Npgsql2\src\Npgsql\NpgsqlConnector.cs:line 373 − at Npgsql.NpgsqlConnectorPool.UngetPooledConnector(NpgsqlConnection Connection, NpgsqlConnector Connector) in C:\Npgsql\Npgsql2\src\Npgsql\NpgsqlConnectorPool.cs:line 541 − at Npgsql.NpgsqlConnectorPool.ReleasePooledConnector(NpgsqlConn