5

I'm using the NpgSqlConnection for .net core web api project. Current PostgreSQL server has been move to another one and need to connect using the client certificates. We are provided with 3 certificate files named client-cert.pem, client-key.pem and server-ca.pem. I was able to connect to the server using the client cert & key files through the pgAdmin from browser. But, I'm not able to connect from my code. Tried several methods from internet but still I'm getting the below error.

{"28000: connection requires a valid client certificate"}

The code snippet I'm trying is given below.

var connectionString = "User ID=" + _dOptions.Value.AuthenticationCredentials.UserName
               + ";Password=" + _dOptions.Value.AuthenticationCredentials.PassWord
               + ";Server=" + _dOptions.Value.Server
               + ";Port=" + _dOptions.Value.Port.ToString()
               + ";Database=" + _dOptions.Value.Database
               + ";Integrated Security=true;Pooling=true;SSL Mode=Require;Trust Server Certificate=true";

_con = new NpgsqlConnection(connectionString);
_con.ProvideClientCertificatesCallback += new ProvideClientCertificatesCallback(MyClientCertificates);
private void MyClientCertificates(X509CertificateCollection certificates)
{
      var cert = new X509Certificate("C:\\Users\\c-Anish\\Documents\\cloud_sql_replica_certs\\DEV\\client-cert.pem");
      certificates.Add(cert);
}

Also, here we are using only the client certificate named client-cert.pem, but, I think we may need to use the client-key.pem ? If so, how can I add that ? What am I missing here ?

Any help will be highly appreciated as I'm stuck with this issue.

3
  • It should be possible to provide environmant variables PGSSLCERT, PGSSLKEY and PGSSLROOTCERT that point to the files. Commented Oct 8, 2020 at 13:35
  • I have tried that, but getting the same error message. Commented Oct 8, 2020 at 14:02
  • Didn't get a solution yet. Can anyone help ? Commented Oct 9, 2020 at 5:11

1 Answer 1

4

I got a solution for this and thought of posting it here which may help others who are facing the similar issue.

It didn't worked with .pem files. I have converted it to a .pfx file using the below command and it started working fine.

openssl pkcs12 -inkey C:\Certs\client-key.pem -in C:\Certs\client-cert.pem -export -out C:\Certs\client-cert.pfx

Reference: Certificate Authentication Support

EDIT

Instead of creating the physical pfx file, I was able to combine the two pem files and got it worked. Code snippet is given below for someone for reference in future.

public X509Certificate2 GetCombinedCertificateAndKey(string certificatePath, string privateKeyPath)
    {
        using var publicKey = new X509Certificate2(certificatePath);

        var privateKeyText = System.IO.File.ReadAllText(privateKeyPath);
        var privateKeyBlocks = privateKeyText.Split("-", StringSplitOptions.RemoveEmptyEntries);
        var privateKeyBytes = Convert.FromBase64String(privateKeyBlocks[1]);
        using var rsa = RSA.Create();

        if (privateKeyBlocks[0] == "BEGIN PRIVATE KEY")
        {
            rsa.ImportPkcs8PrivateKey(privateKeyBytes, out _);
        }
        else if (privateKeyBlocks[0] == "BEGIN RSA PRIVATE KEY")
        {
            rsa.ImportRSAPrivateKey(privateKeyBytes, out _);
        }

        var keyPair = publicKey.CopyWithPrivateKey(rsa);
        var Certificate = new X509Certificate2(keyPair.Export(X509ContentType.Pfx));
        return Certificate;
    }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.