Skip to content
File

Blob: src/workerd/api/tests/starttls-nodejs-server.js

javascript146 lines
1// Copyright (c) 2017-2024 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4 
5/*
6 * This file serves a server that tries to upgrade tls connections and send messages.
7 * This file is designed to run as a sidecar
8 */
9 
10const net = require('node:net');
11const tls = require('node:tls');
12const assert = require('node:assert');
13 
14// Create a self-signed certificate for TLS with proper SAN extension
15function createSelfSignedCert() {
16 const key = `-----BEGIN PRIVATE KEY-----
17MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDIWfGy2tRsqANt
18J1F/52bIDzMDxlmSkDpu3U3Ehq6TmH2hNBcLOWuWLvG8Np9artnzk8QnodfN8yEJ
190HRzZ6mRjVIUHJOb3+L1+0ePOM8dtWvG0AOd95K0T0imJRLPR18UjHl5OLE7mMS9
20CGHa6mDTGKzTcdxtpkjiyoNgfdKKSKzLplga5if36leGJ2+mEhOAc/cV1kqOx+hP
21VGAOz5p3OnkgolC8hZ3WTsAFEYMU0QoPNs7jVCVNGH9t3qPiWV2/7XaNQoMnMHgq
22yyljcvDo0O0dw0HKtBVIMhz5xHHGZqJNM/R36MeHzO+cIYhJz+ncknu62+IlQOCY
23eyHuxvpRAgMBAAECggEAB3SXYqsze+6doAZ2SS7se3XbVWDgbOyKjB0Wm4FShkIG
24rMTCNcP3fbF2A+W5dNesWxzM0Be87thFCrcz2iaJoBW07/QnRwXkDXjCDzGTPX0G
25i3GqrMptbmHD55DaHBYBEwPuMkVajQfwjEM/VvThUQGqTrz+MaNeM3hLPsA34Tbl
26wigHK+4tyAFLkYkvsxXYHs1F23ey2ubFUyBI8gvfayOvr4MOVfEbQZsmz3IB5jjk
27oK5EaMJuhty65pb9Pi6ncSbfVQ2aciNgHjZs/is/WQfQPB2jYBPpmaFQbZc2pseZ
288zTLvF+GKZng4hQE1F+F6DUf9sxb54Eu1XqzqGlrdQKBgQDkQc5fJj72rF9RkiBN
29zeEK0Ngihm9Jzsb544i7DT/4jPWwa1+dt+kNVqguDbcxi4tCi+P8BwTnfX5M31d2
30/Si9nDBpP+WLLRHjFq2AQf05JvFc1/7s4KvWBrfKbwiN+uxrstB2lDuFp386B20U
31stsCBu/nawjt5lYY7S0zPokkJQKBgQDgs9rTJNnRuaaEpUxqRdR6zR3z0Qe1B1Ga
32y6z8OqiX3N+wM9uAcrTzGOtPKvB4glcJZrrQp0NSxkJVsFBzPBCfUfjIV/IiOqS1
33nE/rrEKEG7ZVkxDUsdeS8KiVKBJjLch/hrT0udgv4vndXqeaJuNzbD1yfiKbPnY5
34yGC78uqvvQKBgGUGMx6twMRQekeSEzYcXvP4hxCQy4SxPiOvbv7K2HtbeApDG6ik
35k0NSDVGExIXrKxGi9J7BRIxoYJQJbZ6+YV+6VzreCuxUYExP5y6TBk5bTAw5lRym
36O6eYhZPVHMYqPqVUGSvCY629+nNmggLdPk1hYKDeIK+aeJTDtHOvw+b5AoGAZI74
37wf8+34WWyMv026ZuhZpf6ipEqbYhxgWaX7KcmoHFNWSvudcbtaMUQ3Sy8ytZaiKo
38PhJspZGGRDTIfBmIUtRrYrVA7iKSbZgLiCuqBNcmDTvoj1cbY24B8+Zf/DSUAsY1
39G0RERIHuUiw3E1yN86yf/yoFsLYOUKOk7teyQX0CgYBFUzUeVszODI/1NeKuGdoR
401uJk2gt7hH4t7GdX4G78h3i6P5pa7qSyUXqBm53nXrYhEFRiVgDh5BoRnoKKWomj
41IDidHZX3fMoQvdKAT8sUbT/Q3KKWPFqGv7frdpQe+JM0DwwjjPrMtUWhuve455XW
42bCKgoxoaqEPUzY9CyI+RZg==
43-----END PRIVATE KEY-----`;
44 
45 const cert = `-----BEGIN CERTIFICATE-----
46MIIDmTCCAoGgAwIBAgIUFdaq1aN7zHoSsmLp6ItxnM1VOPEwDQYJKoZIhvcNAQEL
47BQAwTjELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFRlc3QxDTALBgNVBAcMBFRlc3Qx
48DTALBgNVBAoMBFRlc3QxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0yNTA3MjYwNjI3
49MDZaFw0yNjA3MjYwNjI3MDZaME4xCzAJBgNVBAYTAlVTMQ0wCwYDVQQIDARUZXN0
50MQ0wCwYDVQQHDARUZXN0MQ0wCwYDVQQKDARUZXN0MRIwEAYDVQQDDAlsb2NhbGhv
51c3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIWfGy2tRsqANtJ1F/
5252bIDzMDxlmSkDpu3U3Ehq6TmH2hNBcLOWuWLvG8Np9artnzk8QnodfN8yEJ0HRz
53Z6mRjVIUHJOb3+L1+0ePOM8dtWvG0AOd95K0T0imJRLPR18UjHl5OLE7mMS9CGHa
546mDTGKzTcdxtpkjiyoNgfdKKSKzLplga5if36leGJ2+mEhOAc/cV1kqOx+hPVGAO
55z5p3OnkgolC8hZ3WTsAFEYMU0QoPNs7jVCVNGH9t3qPiWV2/7XaNQoMnMHgqyylj
56cvDo0O0dw0HKtBVIMhz5xHHGZqJNM/R36MeHzO+cIYhJz+ncknu62+IlQOCYeyHu
57xvpRAgMBAAGjbzBtMB0GA1UdDgQWBBQ6R0NLwjufqWjT75cFdzHW9bh2DDAfBgNV
58HSMEGDAWgBQ6R0NLwjufqWjT75cFdzHW9bh2DDAPBgNVHRMBAf8EBTADAQH/MBoG
59A1UdEQQTMBGCCWxvY2FsaG9zdIcEfwAAATANBgkqhkiG9w0BAQsFAAOCAQEAToR4
60CaI9HAfSSXE+6fPthp+qrwPmfx3rW0RskpjKuqemZmIK7ydU9pcYuGtc6CPen614
61RfFoaWtPltbNU0KV79P4zTRNYxqTKcEyhsjyAGbLA+bJtJE3hlDrfPGVyepZETXE
627Ig4XPyXi4M+WmvLboAF2dHC+H1XoWp3agIN45VRnr5uPVNX19dTbr0gc3WxLEUH
63N839sKGVB9GVaQhF/4Z8ia0bluirf+6SNAaN/veJA40ixGEkHN3gqX4ZTZWl5rji
643cLdth83wmueKxiBp8ov78ubmdPiBsyIVrsb8jEsxRPAKX8gEx09S/yIIs1ZEGi9
65wG73FlfFCc09zjmYww==
66-----END CERTIFICATE-----`;
67 
68 return { key, cert };
69}
70 
71const serverCA = net
72 .createServer((s) => {
73 console.log('ServerCA: New connection received');
74 
75 // Send initial greeting
76 s.write('HELLO\n');
77 
78 // Wait for one response then upgrade to TLS
79 s.once('data', (data) => {
80 const response = data.toString().trim();
81 console.log('ServerCA: Received response:', response);
82 
83 if (response === 'HELLO_BACK') {
84 s.write('START_TLS\n', () => {
85 console.log('ServerCA: Sent START_TLS, upgrading to TLS');
86 
87 // Small delay to ensure START_TLS is sent
88 console.log('serverCA: Creating TLS socket');
89 const tlsSocket = new tls.TLSSocket(s, {
90 isServer: true,
91 server: serverCA,
92 secureContext: tls.createSecureContext(createSelfSignedCert()),
93 requestCert: false,
94 SNICallback: (hostname, callback) => {
95 console.log('serverCA: SNI callback for hostname:', hostname);
96 assert.strictEqual(hostname, 'localhost');
97 callback(null, null);
98 },
99 });
100 
101 console.log('serverCA: Setting up TLS event handlers');
102 
103 tlsSocket.on('secure', () => {
104 console.log('serverCA: TLS handshake complete');
105 
106 // Handle TLS data
107 tlsSocket.on('data', (data) => {
108 const message = data.toString().trim();
109 console.log('serverCA: Received TLS message:', message);
110 
111 if (message === 'ping') {
112 console.log('serverCA: Sending pong response');
113 tlsSocket.write('pong\n', (err) => {
114 if (err) {
115 console.log('serverCA: Error writing pong:', err);
116 } else {
117 console.log('serverCA: Pong sent successfully');
118 }
119 });
120 }
121 });
122 });
123 
124 tlsSocket.on('error', (err) => {
125 console.log('ServerCA TLS error:', err.message);
126 });
127 
128 tlsSocket.on('close', () => {
129 console.log('serverCA: TLS socket closed');
130 });
131 
132 console.log('serverCA: TLS socket created, waiting for handshake');
133 
134 // The TLS handshake should start when the client initiates it
135 });
136 }
137 });
138 
139 s.on('error', (err) => {
140 console.log('ServerCA socket error:', err.message);
141 });
142 })
143 .listen(process.env.STARTTLS_CA_PORT, () => {
144 console.info(`ServerCA listening on port ${serverCA.address().port}`);
145 });