D
Deno

help

HTTPS w/ client certificate – works in Node.js, not in Deno

Aabi5/19/2023
I am making an HTTPS call with a client certificate. It works great in Node.js, but when I try to do the equivalent in Deno, I get a TLS handshake error. Any ideas on what I'm doing wrong? Node.js version:
$ cat node.mjs
import https, { Agent } from "https";
import fs from "fs";

const key = fs.readFileSync("my_key.pem");
const cert = fs.readFileSync("my_cert.pem");
const ca = fs.readFileSync("my_ca.pem");

https.get(process.env.SECRET_URL, {
agent: new Agent({
key: key,
cert: cert,
ca: ca,
}),
}, (resp) => {
console.log(`status: ${resp.statusCode}`);
});

$ node --version
v20.1.0

$ node node.mjs
status: 403 # <-- this means it worked
$ cat node.mjs
import https, { Agent } from "https";
import fs from "fs";

const key = fs.readFileSync("my_key.pem");
const cert = fs.readFileSync("my_cert.pem");
const ca = fs.readFileSync("my_ca.pem");

https.get(process.env.SECRET_URL, {
agent: new Agent({
key: key,
cert: cert,
ca: ca,
}),
}, (resp) => {
console.log(`status: ${resp.statusCode}`);
});

$ node --version
v20.1.0

$ node node.mjs
status: 403 # <-- this means it worked
Deno version:
$ cat deno.ts
const caCert = await Deno.readTextFile("my_ca.pem");
const certChain = await Deno.readTextFile("my_cert.pem");
const privateKey = await Deno.readTextFile("my_key.pem");

const httpClient = Deno.createHttpClient({
caCerts: [caCert],
certChain: certChain,
privateKey: privateKey,
});

const resp = await fetch(Deno.env.get("SECRET_URL")!, {
client: httpClient,
});

console.log(`status: ${resp.status}`);

$ deno --version
deno 1.33.4 (release, aarch64-apple-darwin)
v8 11.4.183.2
typescript 5.0.4

$ deno run --unstable -A deno.ts
TLS alert received: AlertMessagePayload {
level: Fatal,
description: HandshakeFailure,
}
error: Uncaught TypeError: error sending request for url (<redacted>): error trying to connect: received fatal alert: HandshakeFailure
const resp = await fetch(Deno.env.get("SECRET_URL")!, {
^
at async mainFetch (ext:deno_fetch/26_fetch.js:266:12)
at async fetch (ext:deno_fetch/26_fetch.js:490:7)
at async .../deno.ts:11:14
$ cat deno.ts
const caCert = await Deno.readTextFile("my_ca.pem");
const certChain = await Deno.readTextFile("my_cert.pem");
const privateKey = await Deno.readTextFile("my_key.pem");

const httpClient = Deno.createHttpClient({
caCerts: [caCert],
certChain: certChain,
privateKey: privateKey,
});

const resp = await fetch(Deno.env.get("SECRET_URL")!, {
client: httpClient,
});

console.log(`status: ${resp.status}`);

$ deno --version
deno 1.33.4 (release, aarch64-apple-darwin)
v8 11.4.183.2
typescript 5.0.4

$ deno run --unstable -A deno.ts
TLS alert received: AlertMessagePayload {
level: Fatal,
description: HandshakeFailure,
}
error: Uncaught TypeError: error sending request for url (<redacted>): error trying to connect: received fatal alert: HandshakeFailure
const resp = await fetch(Deno.env.get("SECRET_URL")!, {
^
at async mainFetch (ext:deno_fetch/26_fetch.js:266:12)
at async fetch (ext:deno_fetch/26_fetch.js:490:7)
at async .../deno.ts:11:14
Alright, I've been trying to debug this for many hours, and it seems that the issue might be that rustls, which is backing Deno's TLS support, simply doesn't support TLS 1.2 and/or certain ciphers. This sucks. Is anyone else able to tell me if this is supported by rustls or not? I can't seem to find a straight answer.
New, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : AES256-GCM-SHA384
New, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : AES256-GCM-SHA384
Okay, so it seems that rustls will not support any cipher without "forward secrecy", whatever that is. And apparently the server I'm communicating with does not speak any ciphers that support forward secrecy. Dammit...

Looking for more? Join the community!

Recommended Posts
Using encrypted private keys with DenoSo it seems to me that Deno doesn't provide any helpers for making HTTPS requests with encrypted priError when using readline.question()I get this error with the following code ```ts import process from 'node:process' import readline fjsx in denoHi, I have simple code that takes use of jsx. Based on deno docs, the jsx support should be ootb. IsExpress pt2 tutorial links to itselfAt the very start of the tutorial, it mentions that part 1 got up and running, but the link points tonboard is infiniteSeems like the onboarding process is broken and won't stop repeating itself You need to be a new memDeno mobile app?Anyone has made a mobile app using deno? I was planning to use Fresh and https://capacitorjs.com/ tWhat is the best way to count values with Deno.Kv?I want to show the total values in the database. It seems that the only way is with `kv.list()` and Does kv delete recursively?For example, if I have entries with keys: `['users', 1]`, `['users', 2]`, will `kv.delete(['users'])How do I send a simple text file to the printer?Hello. I am looking for an example of how to send a simple text file tot eh printer in Deno. Is thisActive Handles and RequestsI'm running into an issue with the `excel4node` NPM library, where after new'ing a Workbook, the proOak, `ctx.assert`, and middlewareI thought that `ctx.assert` would somehow "carry along" the information about the asserted conditionChecking for circular module dependencies?Hi, I’m wondering if there is some way to detect whether there are circular dependencies in a set ofList of all deno.land packages?Is there a list somewhere of all the deno.land packages on one page?Safety measures (statically, not runtime) for libraries that require environment variables?Suppose I have a Deno library which expects certain environment variables to have been configured, o