Get your own Node server
const tls = require('tls');
const fs = require('fs');
const { generateKeyPairSync, createHash } = require('crypto');
const path = require('path');

// Generate self-signed certificates if they don't exist
function generateSelfSignedCert() {
  const certPath = path.join(__dirname, 'selfsigned-cert.pem');
  const keyPath = path.join(__dirname, 'selfsigned-key.pem');
  
  // Check if files already exist
  if (fs.existsSync(certPath) && fs.existsSync(keyPath)) {
    return {
      cert: fs.readFileSync(certPath),
      key: fs.readFileSync(keyPath)
    };
  }
  
  console.log('Generating self-signed certificate...');
  
  // Generate a key pair
  const { privateKey, publicKey } = generateKeyPairSync('rsa', {
    modulusLength: 2048,
    publicKeyEncoding: {
      type: 'spki',
      format: 'pem'
    },
    privateKeyEncoding: {
      type: 'pkcs8',
      format: 'pem',
      cipher: 'aes-256-cbc',
      passphrase: 'topsecret'
    }
  });
  
  // Create a self-signed certificate
  const cert = require('crypto').createCertificate({
    key: privateKey,
    publicKey: publicKey,
    serialNumber: '01',
    issuer: {
      C: 'US',
      ST: 'California',
      L: 'San Francisco',
      O: 'Test',
      OU: 'Test',
      CN: 'localhost'
    },
    subject: {
      C: 'US',
      ST: 'California',
      L: 'San Francisco',
      O: 'Test',
      OU: 'Test',
      CN: 'localhost'
    },
    days: 365,
    selfSigned: true
  });
  
  // Save the certificate and key
  fs.writeFileSync(certPath, cert.toString());
  fs.writeFileSync(keyPath, privateKey);
  
  console.log('Self-signed certificate generated');
  
  return {
    cert: cert.toString(),
    key: privateKey
  };
}

// Generate or load self-signed certificate
const { cert, key } = generateSelfSignedCert();

// TLS server options
const options = {
  key: key,
  cert: cert,
  
  // Request client certificate (optional)
  requestCert: true,
  
  // Reject connections without certificates (set to false for testing)
  rejectUnauthorized: false,
  
  // Enable all cipher suites for testing (not recommended for production)
  ciphers: 'ALL',
  
  // Minimum TLS version
  minVersion: 'TLSv1.2',
  
  // Session timeout in seconds
  sessionTimeout: 300
};

// Create a TLS server
const server = tls.createServer(options, (socket) => {
  console.log('Client connected');
  
  // Get client certificate information
  const cert = socket.getPeerCertificate();
  const clientAuth = socket.authorized ? 'authorized' : 'unauthorized';
  
  console.log(`Client ${clientAuth}: ${socket.remoteAddress}:${socket.remotePort}`);
  
  if (socket.authorized) {
    console.log('Client certificate:');
    console.log(`  Subject: ${cert.subject.CN}`);
    console.log(`  Issuer: ${cert.issuer.CN}`);
    console.log(`  Valid from: ${cert.valid_from}`);
    console.log(`  Valid to: ${cert.valid_to}`);
  } else {
    console.log('Client did not present a valid certificate');
    console.log('Authorization error:', socket.authorizationError);
  }
  
  // Handle data from client
  socket.on('data', (data) => {
    const message = data.toString().trim();
    console.log(`Received from client: ${message}`);
    
    // Echo the message back to the client
    socket.write(`Server echo: ${message}\n`);
    
    // Close connection if client sends 'quit'
    if (message.toLowerCase() === 'quit') {
      console.log('Client requested to close connection');
      socket.end('Goodbye!\n');
    }
  });
  
  // Handle client disconnection
  socket.on('end', () => {
    console.log(`Client ${socket.remoteAddress}:${socket.remotePort} disconnected`);
  });
  
  // Handle socket errors
  socket.on('error', (err) => {
    console.error(`Socket error: ${err.message}`);
  });
  
  // Send welcome message
  socket.write('Welcome to the TLS server! Type "quit" to disconnect.\n');
  socket.write('> ');
});

// Handle server errors
server.on('tlsClientError', (err, tlsSocket) => {
  console.error('TLS client error:', err.message);
  if (tlsSocket) {
    tlsSocket.destroy();
  }
});

// Start the server
const PORT = 8443;
server.listen(PORT, () => {
  console.log(`TLS server listening on port ${PORT}`);
  console.log('You can test with:');
  console.log(`  openssl s_client -connect localhost:${PORT} -servername localhost -tls1_2`);
  console.log('Or use the test client that will be started next...');
  
  // Start a test client
  startTestClient();
});

// Function to start a test client
function startTestClient() {
  console.log('\n=== Starting test client ===');
  
  const clientOptions = {
    host: 'localhost',
    port: PORT,
    rejectUnauthorized: false, // For testing with self-signed certificates
    servername: 'localhost' // SNI (Server Name Indication)
  };
  
  const client = tls.connect(clientOptions, () => {
    console.log('Connected to server');
    console.log('Client connected:', client.authorized ? 'Authorized' : 'Unauthorized');
    
    // Send a test message
    client.write('Hello from test client\n');
    
    // Close connection after a short delay
    setTimeout(() => {
      client.end('quit\n');
    }, 1000);
  });
  
  client.on('data', (data) => {
    console.log('Server says:', data.toString().trim());
  });
  
  client.on('end', () => {
    console.log('Disconnected from server');
  });
  
  client.on('error', (err) => {
    console.error('Client error:', err.message);
  });
  
  // Handle process termination
  process.on('SIGINT', () => {
    console.log('\nShutting down...');
    client.end();
    server.close();
    process.exit(0);
  });
}

// Handle process termination
process.on('SIGINT', () => {
  console.log('\nShutting down server...');
  server.close(() => {
    console.log('Server closed');
    process.exit(0);
  });
});

              
Generating self-signed certificate...
Self-signed certificate generated
TLS server listening on port 8443
You can test with:
  openssl s_client -connect localhost:8443 -servername localhost -tls1_2
Or use the test client that will be started next...

=== Starting test client ===
Connected to server
Client connected: Unauthorized
Server says: Welcome to the TLS server! Type "quit" to disconnect.
> Server echo: Hello from test client
Server says: > 
Disconnected from server

Shutting down...
Client 127.0.0.1:12345 disconnected
Server closed