I fixed this problem by modifying the Npgsql source. Rather than using Mono's Mono.Security.Protocol.Tls.SslClientStream
, I changed it to use System.Net.Security.SslStream
instead. These were the steps I took:
Modify
NpgsqlClosedState.cs
:- Remove the
using Mono.Security.Protocol.Tls;
directive and the one below it. - Add a
using System.Net.Security;
directive. In the
NpgsqlClosedState.Open()
method, where it saysif (response == 'S')
, changed it to:if (response == 'S') { //create empty collection X509CertificateCollection clientCertificates = new X509CertificateCollection(); //trigger the callback to fetch some certificates context.DefaultProvideClientCertificatesCallback(clientCertificates); // Create SslStream, wrapping around NpgsqlStream SslStream sstream = new SslStream(stream, true, delegate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors errors) { // Create callback to validate server cert here return true; }); sstream.AuthenticateAsClient(context.Host, clientCertificates, System.Security.Authentication.SslProtocols.Default, false); stream = sstream; }
- Remove the
Modify
NpgsqlConnection.cs
, remove theusing Mono...
directives. This will cause a number of errors regarding missing types, in particular, these will be regarding 3 sets of delegate/event combos that use Mono types. The errors will always appear in groups of three because these callbacks all tie in with Mono'sSslClientStream
class. Remove each group of three and replace it with a singleValidateServerCertificate
delegate/event. This single event should be used in the constructor for theSslStream
class that was used in step 1.3 above.The changes to
NpgsqlConnection.cs
will trigger more errors in other filesNpgsqlConnector.cs
,NpgsqlConnectorPool.cs
etc. but the fix is the same, replace the 3 Mono-based callbacks with the newValidateServerCertificate
.
Once all that is done, Npgsql can be used without Mono components and with (for me) working SSL certificate authentication.
My pull request on github can be found here.