Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrading connection to tls in 1.17.x errors with UnsupportedCertVersion #13350

Closed
porsager opened this issue Jan 12, 2022 · 16 comments
Closed
Labels

Comments

@porsager
Copy link

The following happens when trying to do startTls to a postgres server with a self signed certificate. It works in 1.16.4

Sending fatal alert BadCertificate
error: Uncaught (in promise) InvalidData: invalid peer certificate contents: invalid peer certificate: UnsupportedCertVersion
  while (await conn.read(b))
         ^
    at async read (deno:ext/net/01_net.js:21:19)
    at async connected (file:///Users/rasmus/Projects/deno-ssl/index.js:16:10)

Small repro case here:

Deno.connect({ transport: 'tcp', port: 5432, hostname: 'localhost' }).then(async conn => {
  await conn.write(new Uint8Array([0, 0, 0, 8, 4, 210, 22, 47]))
  const b = new Uint8Array(128)

  while (await conn.read(b)) {
    if (b[0] === 83) {
      Deno.startTls(conn, { hostname: 'localhost' }).then(connected)
      break
    }
  }

})

async function connected(conn) {
  const b = new Uint8Array(128)
  while (await conn.read(b))
    console.log(b[0])
}

@porsager porsager changed the title Upgrading connection to tls in 1.17.x errors with UnsupprtedCertVersion Upgrading connection to tls in 1.17.x errors with UnsupportedCertVersion Jan 12, 2022
@lucacasonato
Copy link
Member

The exact code works with 1.16.4? Can you please include the self signed certificate, or at least instructions for how to generate a failing certificate / private key?

@porsager
Copy link
Author

Ah sorry, forgot to mention I'm running with --unsafely-ignore-certificate-errors for the test, so should that even matter?

@porsager
Copy link
Author

porsager commented Jan 13, 2022

Even so, it is generated using openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout server.key -out server.crt

@lucacasonato
Copy link
Member

@piscisaureus can you investigate?

@piscisaureus
Copy link
Member

I tested it with this code, and it works for me.

import { assertStrictEquals } from "https://deno.land/std/testing/asserts.ts";

const tcp = await Deno.connect({
  transport: "tcp",
  hostname: "127.0.0.1",
  port: 5432,
});
await tcp.write(new Uint8Array([0, 0, 0, 8, 4, 210, 22, 47]));
const buf1 = new Uint8Array(1);
assertStrictEquals(await tcp.read(buf1), 1);
assertStrictEquals(buf1[0], 83);

const tls = await Deno.startTls(tcp, { hostname: "localhost" });
const buf2 = new Uint8Array(1024);
while (await tls.read(buf2) !== null) {
  console.log(buf2);
}

@porsager
Copy link
Author

porsager commented Jan 13, 2022

Just tried your code, and I still get the error. Is there anything I can provide you with from my run to help?

Sending fatal alert BadCertificate
error: Uncaught (in promise) InvalidData: invalid peer certificate contents: invalid peer certificate: UnsupportedCertVersion
while (await tls.read(buf2) !== null) {
       ^
    at async read (deno:ext/net/01_net.js:21:19)
    at async file:///Users/rasmus/Projects/deno-ssl/index.js:15:8

@piscisaureus
Copy link
Member

It works in 1.16.4
generated using openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout server.key -out server.crt

Can you re-test your test case and confirm that it definitely, without any doubt, works in Deno 1.16.4.

I think that you'll find that 1.16.4 also rejects your certificate (although with a different error "InvalidData: invalid certificate: BadDER", due to this recent webpki change).

@porsager
Copy link
Author

Yes, but I only get that error in 1.16.4 if I run without --unsafely-ignore-certificate-errors.

@piscisaureus
Copy link
Member

It seems that rustls (or webpki) refuses to parse self signed X509 version 1 certificates and rejects them as invalid.
I'm not sure that this is really a bug as this is really nonstandard (although still pretty common).

When I use a X509v3 certificate it works (provided --unsafely-ignore-certificate-errors is used). On mac you can generate one as follows:

openssl req -new -x509 -nodes -days 365 -text -subj "/CN=localhost" -extensions v3_req \
    -config <(cat /etc/ssl/openssl.cnf <(printf "\n[v3_req]\nbasicConstraints=critical,CA:TRUE\nkeyUsage=nonRepudiation,digitalSignature,keyEncipherment\nsubjectAltName=DNS:localhost")) \
    -keyout server.key -out server.crt 

I think that is not advisable though, it'd be better to use self signed root CA instead

@piscisaureus
Copy link
Member

More context:

rustls/rustls#127
briansmith/webpki#90

@porsager
Copy link
Author

Ah, well the error was correct then :)

I just couldn't find anywhere in the changelog that this should have changed from 16 -> 17, but I suppose it was a dependency change/update that broke/disabled it?

If my understanding is correct, this PR briansmith/webpki#219 should fix it?

@piscisaureus
Copy link
Member

I just couldn't find anywhere in the changelog that this should have changed from 16 -> 17, but I suppose it was a dependency change/update that broke/disabled it?

I suspect it might have been the rustls 0.19.1 -> 0.20.0 upgrade (which also upgraded webpki 0.21.4 -> 0.22.0): a2f1357.

@stale
Copy link

stale bot commented Mar 16, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Mar 16, 2022
@porsager
Copy link
Author

My understanding is that this will be fixed with a coming update of webpki, but until that has gone into Deno I don't suppose this issue should be closed?

@stale stale bot removed the stale label Mar 16, 2022
@pcj
Copy link

pcj commented Apr 11, 2022

Note I see this error message as well, though I'm not using a self-signed cert.

TLS connection failed with message: invalid peer certificate contents: invalid peer certificate: UnsupportedCertVersion
Defaulting to non-encrypted connection
deno 1.20.4 (release, x86_64-apple-darwin)
v8 10.0.139.6
typescript 4.6.2

@stale
Copy link

stale bot commented Jun 11, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Jun 11, 2022
@stale stale bot closed this as completed Jun 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants