aboutsummaryrefslogtreecommitdiff
path: root/test/js/node/tls/node-tls-connect.test.ts
blob: 716dac3c6083a08b4a35f1877daaddc6713cb988 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import { TLSSocket, connect } from "tls";

it("should work with alpnProtocols", done => {
  try {
    let socket: TLSSocket | null = connect({
      ALPNProtocols: ["http/1.1"],
      host: "bun.sh",
      servername: "bun.sh",
      port: 443,
      rejectUnauthorized: false,
    });

    const timeout = setTimeout(() => {
      socket?.end();
      done("timeout");
    }, 3000);

    socket.on("error", err => {
      clearTimeout(timeout);
      done(err);
    });

    socket.on("secureConnect", () => {
      clearTimeout(timeout);
      done(socket?.alpnProtocol === "http/1.1" ? undefined : "alpnProtocol is not http/1.1");
      socket?.end();
      socket = null;
    });
  } catch (err) {
    done(err);
  }
});

it("should have peer certificate", async () => {
  const socket = (await new Promise((resolve, reject) => {
    const instance = connect(
      {
        ALPNProtocols: ["http/1.1"],
        host: "bun.sh",
        servername: "bun.sh",
        port: 443,
        rejectUnauthorized: false,
        requestCert: true,
      },
      function () {
        resolve(instance);
      },
    ).on("error", reject);
  })) as TLSSocket;

  try {
    expect(socket).toBeDefined();
    const cert = socket.getPeerCertificate();
    expect(cert).toBeDefined();
    expect(cert.subject).toBeDefined();
    expect(cert.subject.CN).toBe("bun.sh");
    expect(cert.issuer).toBeDefined();
    expect(cert.issuer.C).toBe("US");
    expect(cert.issuer.O).toBe("Google Trust Services LLC");
    expect(cert.issuer.CN).toBe("GTS CA 1P5");
    expect(cert.subjectaltname).toBe("DNS:bun.sh, DNS:*.bun.sh");
    expect(cert.infoAccess).toBeDefined();

    const infoAccess = cert.infoAccess as NodeJS.Dict<string[]>;
    expect(infoAccess["OCSP - URI"]).toBeDefined();
    expect(infoAccess["CA Issuers - URI"]).toBeDefined();
    expect(cert.ca).toBeFalse();
    expect(cert.bits).toBe(2048);
    expect(cert.modulus).toBe(
      "A9F58B9925E08DD3393E4A5DFDBFD249A21C33AF0F38624FAF20D39EB3AC78400789CF3FCBE8C3B18B1F03B3C96B2455D88A60A8D7B2112D35159DB39A592624545CE52E6184D0504D59E6C81DD1025526DEBA547D89A47F16830AC55929C80888F65066D29517905DB1C7E8446580DC439D715C4452D03A97BB0DBC82970C8A3F7E8ABADBBA30FBF6475E2D1783793A4AC60BC57EF5E945C976CE54EECB4A3DA7920AC5C711D5FC8D6A235EFC7FA4024F3930EDDDD1680E6AEA9BD50C89394018761187B4838B07D70BF10E28E4A62F8E2FC4998BC3B9189CD50F61693D79FF761E2D4DEB3998578A6D6015926F60A4172125255FAD01485513DC3C1AE082EF",
    );
    expect(cert.exponent).toBe("0x10001");
    expect(cert.pubkey).toBeInstanceOf(Buffer);
    expect(cert.valid_from).toBe("Jun  1 01:36:52 2023 GMT"); // yes this space is intentional
    expect(cert.valid_to).toBe("Aug 30 01:36:51 2023 GMT");
    expect(cert.fingerprint).toBe("41:66:63:69:DC:31:95:B6:89:7C:54:72:80:19:EA:58:EE:26:FC:FA");
    expect(cert.fingerprint256).toBe(
      "51:5D:10:ED:F9:F1:71:9C:03:EB:1D:17:37:2E:B0:CE:CA:8E:E7:E2:D7:D9:F0:9F:25:8D:4C:30:61:FE:86:3A",
    );
    expect(cert.fingerprint512).toBe(
      "61:C6:22:B6:19:B6:28:EC:5E:B1:B5:C7:A2:45:3B:A6:BA:D6:1D:A6:96:28:07:47:04:3B:04:3A:2D:A1:D7:8E:C4:55:83:B9:11:7F:6C:3B:EB:5A:66:C5:CC:E0:44:E8:4F:F1:6C:16:14:03:5B:71:76:F9:42:0C:04:5F:C0:F1",
    );
    expect(cert.serialNumber).toBe("03E071FE809E66081139F0BDD02AC346");
    expect(cert.raw).toBeInstanceOf(Buffer);
  } finally {
    socket.end();
  }
});

it("getCipher, getProtocol, getEphemeralKeyInfo, getSharedSigalgs, getSession, exportKeyingMaterial and isSessionReused should work", async () => {
  const socket = (await new Promise((resolve, reject) => {
    connect({
      ALPNProtocols: ["http/1.1"],
      host: "bun.sh",
      servername: "bun.sh",
      port: 443,
      rejectUnauthorized: false,
      requestCert: true,
    })
      .on("secure", resolve)
      .on("error", reject);
  })) as TLSSocket;

  try {
    expect(socket.getCipher()).toMatchObject({
      name: "TLS_AES_128_GCM_SHA256",
      standardName: "TLS_AES_128_GCM_SHA256",
      version: "TLSv1/SSLv3",
    });
    expect(socket.getProtocol()).toBe("TLSv1.3");
    expect(typeof socket.getEphemeralKeyInfo()).toBe("object");
    expect(socket.getSharedSigalgs()).toBeInstanceOf(Array);
    expect(socket.getSession()).toBeInstanceOf(Buffer);
    expect(socket.exportKeyingMaterial(512, "client finished")).toBeInstanceOf(Buffer);
    expect(socket.isSessionReused()).toBe(false);

    // BoringSSL does not support these methods for >= TLSv1.3
    expect(socket.getFinished()).toBeUndefined();
    expect(socket.getPeerFinished()).toBeUndefined();
  } finally {
    socket.end();
  }
});