Skip to content

Commit 2ff6fef

Browse files
committed
Review comments
1 parent 72c86ae commit 2ff6fef

File tree

3 files changed

+31
-19
lines changed

3 files changed

+31
-19
lines changed

src/error.ts

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -80,30 +80,20 @@ export class CertificateError extends Error {
8080
const url = new URL(address);
8181
const socket = tls.connect(
8282
{
83-
port: parseInt(url.port, 10) || 443,
83+
port: Number.parseInt(url.port, 10) || 443,
8484
host: url.hostname,
8585
rejectUnauthorized: false,
8686
},
87-
async () => {
87+
() => {
8888
const x509 = socket.getPeerX509Certificate();
8989
socket.destroy();
9090
if (!x509) {
9191
throw new Error("no peer certificate");
9292
}
9393

94-
/**
95-
* We use "@peculiar/x509" for two reasons:
96-
* 1. Node's x509 returns an undefined `keyUsage` in Electron environments.
97-
* 2. Electron's checkIssued() will fail because it suffers from same
98-
* the key usage bug that we are trying to work around here in the first place.
99-
*/
94+
// We use "@peculiar/x509" because Node's x509 returns an undefined `keyUsage`.
10095
const cert = new X509Certificate(x509.toString());
101-
let isSelfIssued: boolean;
102-
try {
103-
isSelfIssued = await cert.isSelfSigned();
104-
} catch (err) {
105-
return reject(err);
106-
}
96+
const isSelfIssued = cert.subject === cert.issuer;
10797
if (!isSelfIssued) {
10898
return resolve(X509_ERR.PARTIAL_CHAIN);
10999
}

src/remote/remote.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ export class Remote {
344344
} catch (error) {
345345
subscription.dispose();
346346
reject(error);
347+
return;
347348
} finally {
348349
inProgress = false;
349350
}

test/unit/error.test.ts

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1+
import {
2+
KeyUsagesExtension,
3+
X509Certificate as X509CertificatePeculiar,
4+
} from "@peculiar/x509";
15
import axios from "axios";
6+
import { X509Certificate as X509CertificateNode } from "node:crypto";
27
import * as fs from "node:fs/promises";
38
import https from "node:https";
49
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
@@ -15,9 +20,7 @@ describe("Certificate errors", () => {
1520
// These tests run in Electron (BoringSSL) for accurate certificate validation testing.
1621

1722
it("should run in Electron environment", () => {
18-
const isElectron =
19-
process.versions.electron || process.env.ELECTRON_RUN_AS_NODE;
20-
expect(isElectron).toBeTruthy();
23+
expect(process.versions.electron).toBeTruthy();
2124
});
2225

2326
beforeAll(() => {
@@ -113,8 +116,7 @@ describe("Certificate errors", () => {
113116
});
114117

115118
// In Electron a self-issued certificate without the signing capability fails
116-
// (again with the same "unable to verify" error) but in Node self-issued
117-
// certificates are not required to have the signing capability.
119+
// (again with the same "unable to verify" error)
118120
it("detects self-signed certificates without signing capability", async () => {
119121
const address = await startServer("no-signing");
120122
const request = axios.get(address, {
@@ -146,6 +148,25 @@ describe("Certificate errors", () => {
146148
await expect(request).resolves.toHaveProperty("data", "foobar");
147149
});
148150

151+
// Node's X509Certificate.keyUsage is unreliable, so use a third-party parser
152+
// to verify the no-signing certificate lacks signing capabilities.
153+
it("parses no-signing cert keyUsage with third-party library", async () => {
154+
const certPem = await fs.readFile(
155+
getFixturePath("tls", "no-signing.crt"),
156+
"utf-8",
157+
);
158+
159+
// Node's implementation seems to always return `undefined`
160+
const nodeCert = new X509CertificateNode(certPem);
161+
expect(nodeCert.keyUsage).toBeUndefined();
162+
163+
// Here we can correctly get the KeyUsages
164+
const peculiarCert = new X509CertificatePeculiar(certPem);
165+
const extension = peculiarCert.getExtension(KeyUsagesExtension);
166+
expect(extension).toBeDefined();
167+
expect(extension?.usages).toBeTruthy();
168+
});
169+
149170
// Both environments give the same error code when a self-issued certificate is
150171
// untrusted.
151172
it("detects self-signed certificates", async () => {

0 commit comments

Comments
 (0)