denodrivers / postgres

PostgreSQL driver for Deno

Home Page:https://denodrivers.github.io/postgres

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

invalid peer certificate: UnsupportedCertVersion

dragonwocky opened this issue · comments

commented

I'm not entirely sure where the fault here lies, but I'm having problems connecting to a database over TLS with deno-postgres.

I've put together this code to connect to the database based off the example in the docs (https://deno-postgres.com/#/?id=ssltls-connection):

const cert = await Deno.readTextFile(
    new URL("./postgres.crt", import.meta.url),
  ),
  config = {
    user: "postgres",
    password: Deno.env.get("POSTGRES_PWD"),
    hostname: Deno.env.get("POSTGRES_HOST"),
    port: "6543",
    database: "postgres",
    tls: { caCertificates: [cert] },
  },
  pool = new postgres.Pool(config, 3, true);

The postgres.crt file is an SSL certificate downloaded from within the database's Supabase dashboard:

image

When I run the script, I get this error:

Sending fatal alert BadCertificate
TLS connection failed with message: invalid peer certificate contents: invalid peer certificate: UnsupportedCertVersion
Defaulting to non-encrypted connection

This is happening both when I run the script locally and on Deno Deploy.

The only other reference to this error message I could find was denoland/deno#13350, so it may be related.

Thanks.

Edit: I get the same error both with and without including tls: { caCertificates: [cert] } in the config on Deno v1.18.1. If I downgrade to Deno v1.15.0 to test I get the following error (again both with and without adding the cert to the config):

Sending fatal alert DecodeError
TLS connection failed with message: invalid certificate: BadDER

Everything else seems to work, i.e. I can perform database operations successfully, but the TLS connection is failing.

I am also getting this same error trying to use Supabase's Postgres database (as in the issue above). I have included the certificate I am using if that would give a maintainer any hints of the issue.

The certificate
-----BEGIN CERTIFICATE-----
MIIDxDCCAqygAwIBAgIUbLxMod62P2ktCiAkxnKJwtE9VPYwDQYJKoZIhvcNAQEL
BQAwazELMAkGA1UEBhMCVVMxEDAOBgNVBAgMB0RlbHdhcmUxEzARBgNVBAcMCk5l
dyBDYXN0bGUxFTATBgNVBAoMDFN1cGFiYXNlIEluYzEeMBwGA1UEAwwVU3VwYWJh
c2UgUm9vdCAyMDIxIENBMB4XDTIxMDQyODEwNTY1M1oXDTMxMDQyNjEwNTY1M1ow
azELMAkGA1UEBhMCVVMxEDAOBgNVBAgMB0RlbHdhcmUxEzARBgNVBAcMCk5ldyBD
YXN0bGUxFTATBgNVBAoMDFN1cGFiYXNlIEluYzEeMBwGA1UEAwwVU3VwYWJhc2Ug
Um9vdCAyMDIxIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqQXW
QyHOB+qR2GJobCq/CBmQ40G0oDmCC3mzVnn8sv4XNeWtE5XcEL0uVih7Jo4Dkx1Q
DmGHBH1zDfgs2qXiLb6xpw/CKQPypZW1JssOTMIfQppNQ87K75Ya0p25Y3ePS2t2
GtvHxNjUV6kjOZjEn2yWEcBdpOVCUYBVFBNMB4YBHkNRDa/+S4uywAoaTWnCJLUi
cvTlHmMw6xSQQn1UfRQHk50DMCEJ7Cy1RxrZJrkXXRP3LqQL2ijJ6F4yMfh+Gyb4
O4XajoVj/+R4GwywKYrrS8PrSNtwxr5StlQO8zIQUSMiq26wM8mgELFlS/32Uclt
NaQ1xBRizkzpZct9DwIDAQABo2AwXjALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFKjX
uXY32CztkhImng4yJNUtaUYsMB8GA1UdIwQYMBaAFKjXuXY32CztkhImng4yJNUt
aUYsMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAB8spzNn+4VU
tVxbdMaX+39Z50sc7uATmus16jmmHjhIHz+l/9GlJ5KqAMOx26mPZgfzG7oneL2b
VW+WgYUkTT3XEPFWnTp2RJwQao8/tYPXWEJDc0WVQHrpmnWOFKU/d3MqBgBm5y+6
jB81TU/RG2rVerPDWP+1MMcNNy0491CTL5XQZ7JfDJJ9CCmXSdtTl4uUQnSuv/Qx
Cea13BX2ZgJc7Au30vihLhub52De4P/4gonKsNHYdbWjg7OWKwNv/zitGDVDB9Y2
CMTyZKG3XEu5Ghl1LEnI3QmEKsqaCLv12BnVjbkSeZsMnevJPs1Ye6TjjJwdik5P
o/bKiIz+Fq8=
-----END CERTIFICATE-----
The certificate data decoded to JSON
{
    "name": "\/C=US\/ST=Delware\/L=New Castle\/O=Supabase Inc\/CN=Supabase Root 2021 CA",
    "subject": {
        "C": "US",
        "ST": "Delware",
        "L": "New Castle",
        "O": "Supabase Inc",
        "CN": "Supabase Root 2021 CA"
    },
    "hash": "4cdc2cb7",
    "issuer": {
        "C": "US",
        "ST": "Delware",
        "L": "New Castle",
        "O": "Supabase Inc",
        "CN": "Supabase Root 2021 CA"
    },
    "version": 2,
    "serialNumber": "0x6CBC4CA1DEB63F692D0A2024C67289C2D13D54F6",
    "serialNumberHex": "6CBC4CA1DEB63F692D0A2024C67289C2D13D54F6",
    "validFrom": "210428105653Z",
    "validTo": "310426105653Z",
    "validFrom_time_t": 1619607413,
    "validTo_time_t": 1934967413,
    "signatureTypeSN": "RSA-SHA256",
    "signatureTypeLN": "sha256WithRSAEncryption",
    "signatureTypeNID": 668,
    "purposes": {
        "1": [
            false,
            true,
            "sslclient"
        ],
        "2": [
            false,
            true,
            "sslserver"
        ],
        "3": [
            false,
            true,
            "nssslserver"
        ],
        "4": [
            false,
            true,
            "smimesign"
        ],
        "5": [
            false,
            true,
            "smimeencrypt"
        ],
        "6": [
            true,
            true,
            "crlsign"
        ],
        "7": [
            true,
            true,
            "any"
        ],
        "8": [
            true,
            true,
            "ocsphelper"
        ],
        "9": [
            false,
            true,
            "timestampsign"
        ]
    },
    "extensions": {
        "keyUsage": "Certificate Sign, CRL Sign",
        "subjectKeyIdentifier": "A8:D7:B9:76:37:D8:2C:ED:92:12:26:9E:0E:32:24:D5:2D:69:46:2C",
        "authorityKeyIdentifier": "keyid:A8:D7:B9:76:37:D8:2C:ED:92:12:26:9E:0E:32:24:D5:2D:69:46:2C\n",
        "basicConstraints": "CA:TRUE"
    }
}

Deno is extremely strict regarding TLS connections, more so than other languages out there that simply skip this errors altogether

To skip this, you can run Deno with the --unsafely-ignore-certificate-errors flag ( https://deno.com/blog/v1.13#disable-tls-verification )

This will allow you to run TLS with non-compliant certificates (even though you really shouldn't)

The fault relies on your database providers, and I hope this problem gets solved eventually as there is quite a lot with broken certificates running around (AFAIK, only Amazon and Azure provide actual valid certificates for their hosting)

commented

I see. Is there any way to whitelist that specific certificate? (That's what I had understood the point of the tls: { caCertificates: [cert] } configuration option to be.)
I would rather not completely disable certificate checking.

The point of caCertificates is to add a certificate authority to your certificate store. This works if your certificate is self signed, because it tells Deno that the authority for that certificate is indeed trusted

The problem with your certificate is a different one however (UnsupportedCertVersion) so Deno can't add it to the list of trusted authorities, because it isn't a valid certificate in the first place

Just an update here, I've been talking with Supabase to get this fixed, and they fixed it today! Here's the final message from one of their engineers:

I have patched the SSL cert to return the SAN now. Deno shouldn't complain about the certs.

And I can confirm I'm no longer hitting that, and didn't have to replace the certificates.

Despite @BrunoBernardino's success, I've been trying to use a Supabase DB with Deno via this library and am getting the same error as @dragonwocky . I've just been investigating what's wrong and I believe I've got to the bottom of it. The CA cert Supabase provide is fine. All the certificates they use in the cert chain are valid, the problem is that the first certificate in their chain is a version 1 cert, but rusttls (used by Deno and therefore this library) doesn't support anything but X509 Version 3 certificates, because the webpki library rusttls uses to parse X509 certs only supports V3.

You can verify this by using openssl s_client to establish a TLS connection and view information on it, such as the certificates used by the server:

$ echo '' | openssl s_client -starttls postgres -connect db.YOURDB.supabase.co:5432 -showcerts -CAfile supabase_ca.pem

That will establish a connection to your DB, you should see a line saying Verification: OK near the end, and it'll print out the PEM form of the certificate chain. For me, the first certificate is a V1 (use openssl x509 -in supabase.pem -text to view the cert).

I've got a support ticket open with supabase at the minute, hopefully they can use V3 certificates for their DBs instead.

@h4l I haven't created any new Supabase projects recently, but one thing that happened since that I didn't mention here was that I had to open a support ticket and request they fix the certificates for all of my existing projects as well (not just the specific one I made the initial request for), so it seems like a manual thing they do. I did expect them to do it for new projects automatically, though, but maybe that's not a good assumption.

Interesting, thanks @BrunoBernardino . The support person I'm talking to also said they may need to upgrade my DB to use the latest certs, so that sounds like the same situation as you.

I heard back from Supabase a few days ago, they've given my DB a V3 cert which fixed the issue. They say that all new databases will have the V3 certs by default, and older DBs will be gradually updated over time.

@h4l -

They say that all new databases will have the V3 certs by default...

Just FYI, sadly that doesn't appear to be the case, as I'm getting this error with a DB I created in February. :-|

Hmm, that's disappointing to hear @farsightsoftware! I don't understand this, especially as SupaBase are using Deno themselves for their Edge Functions product. How can they provide a service that's not able to securely connect to their own DBs? Perhaps they expect everyone to use the HTTP REST API to interact with the db.