const https = require('https'); const forge = require('node-forge'); const crypto = require('crypto'); const fs = require('fs'); const path = require('path'); // Generate CA certificate const ca = generateCACertificate(); const caCertPem = pemEncodeCert(ca.cert); // Generate server certificate signed by CA const serverCert = generateCertificate(ca, 'localhost'); const serverCertPem = pemEncodeCert(serverCert.cert); const serverKeyPem = pemEncodeKey(serverCert.privateKey); // Generate client certificate signed by CA const clientCert = generateCertificate(ca, 'client'); const clientCertPem = pemEncodeCert(clientCert.cert); const clientKeyPem = pemEncodeKey(clientCert.privateKey); fs.writeFileSync(path.join(__dirname, "server.ca"), caCertPem); fs.writeFileSync(path.join(__dirname, "server.key"), serverKeyPem); fs.writeFileSync(path.join(__dirname, "server.cert"), serverCertPem); const uWS = require('../dist/uws'); const port = 8086; const app = uWS.SSLApp({ cert_file_name: path.join(__dirname, "server.cert"), key_file_name: path.join(__dirname, "server.key"), ca_file_name: path.join(__dirname, "server.ca") }).get('/*', (res, req) => { const clientCert = res.getX509Certificate(); const x509 = new crypto.X509Certificate(clientCert); if (x509.verify(crypto.createPublicKey(caCertPem))) { res.end(`Hello World! your certificate is valid!`); } else res.end('Hello World!'); }).listen(port, (token) => { if (token) { console.log('Listening to port ' + port); sendClientRequest(); } else { console.log('Failed to listen to port ' + port); } }); function generateCACertificate() { const keys = forge.pki.rsa.generateKeyPair(2048); const cert = forge.pki.createCertificate(); cert.publicKey = keys.publicKey; cert.serialNumber = '01'; cert.validity.notBefore = new Date(); cert.validity.notAfter = new Date(); cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1); const attrs = [ { name: 'commonName', value: 'example.org' }, { name: 'countryName', value: 'US' }, { shortName: 'ST', value: 'California' }, { name: 'localityName', value: 'San Francisco' }, { name: 'organizationName', value: 'example.org' }, { shortName: 'OU', value: 'Test' } ]; cert.setSubject(attrs); cert.setIssuer(attrs); cert.setExtensions([{ name: 'basicConstraints', cA: true }]); cert.sign(keys.privateKey, forge.md.sha256.create()); return { privateKey: keys.privateKey, publicKey: keys.publicKey, cert: cert }; } function generateCertificate(ca, commonName) { const keys = forge.pki.rsa.generateKeyPair(2048); const cert = forge.pki.createCertificate(); cert.publicKey = keys.publicKey; cert.serialNumber = '02'; cert.validity.notBefore = new Date(); cert.validity.notAfter = new Date(); cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1); const attrs = [ { name: 'commonName', value: commonName } ]; cert.setSubject(attrs); cert.setIssuer(ca.cert.subject.attributes); cert.sign(ca.privateKey, forge.md.sha256.create()); return { privateKey: keys.privateKey, cert: cert }; } function pemEncodeCert(cert) { return forge.pki.certificateToPem(cert); } function pemEncodeKey(key) { return forge.pki.privateKeyToPem(key); } function sendClientRequest() { const clientOptions = { hostname: 'localhost', port: port, path: '/', method: 'GET', key: clientKeyPem, cert: clientCertPem, ca: [caCertPem], rejectUnauthorized: false }; const req = https.request(clientOptions, (res) => { let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { console.log('Response from server:', data); }); }); req.on('error', (e) => { console.error('errp', e); }); req.end(); }