-
Notifications
You must be signed in to change notification settings - Fork 0
/
https-test.js
103 lines (87 loc) · 2.74 KB
/
https-test.js
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
'use strict';
const { createPublicKey, sign, verify } = require('crypto');
const fs = require('fs');
const https = require('https');
const pqc = require('../pqc-over-tcp');
const { kem, computeKeyId } = require('../protocol');
const httpsServerDebug = require('debug')('https:server');
const httpsClientDebug = require('debug')('https:client');
const httpsOptions = {
key: fs.readFileSync(`${__dirname}/key.pem`, 'ascii'),
cert: fs.readFileSync(`${__dirname}/cert.pem`, 'ascii')
};
// Generate the server key pair.
httpsServerDebug('generating keypair');
const { publicKey, privateKey } = kem.keypair();
const publicKeyId = computeKeyId(publicKey);
// Sign the public key id.
const publicKeySignature = sign('sha256', publicKeyId, httpsOptions.key);
// Create the HTTPS server.
const httpsServer = https.createServer(httpsOptions, (req, res) => {
httpsServerDebug('received request');
res.end('ok');
});
httpsServer.on('error', (err) => console.error(err));
httpsServer.on('clientError', (err, conn) => {
console.error(err);
conn.destroy(err);
});
const server = pqc.createServer({
getPublicKey(sni, callback) {
callback(null, publicKey);
},
getPublicKeyId(sni, callback) {
callback(null, publicKeyId, publicKeySignature);
},
getPrivateKey(sni, callback) {
callback(null, privateKey);
}
}, c => {
httpsServer.emit('connection', c);
c.on('error', err => console.error(err));
});
// Prevent the server from keeping the process running.
server.unref();
// Wait for the server to be bound to a port.
server.listen(8124, () => {
const conn = pqc.connect({
hostname: 'localhost',
port: 8124,
getPublicKey(id, signature, callback) {
if (signature.length === 0)
return callback(new Error('Missing signature'));
conn.publicKeyId = id;
conn.publicKeySignature = signature;
callback(null);
},
rememberPublicKey(id, key) {
// Ignore it
}
});
conn.on('error', err => console.error(err));
const req = https.request('https://localhost:8124/foo', {
socket: conn,
rejectUnauthorized: false
});
req.on('error', (err) => console.error(err));
req.on('socket', (socket) => {
socket.once('secureConnect', () => {
const certPublicKey = createPublicKey({
key: socket.getPeerCertificate().pubkey,
format: 'der',
type: 'spki'
});
if (verify('sha256', conn.publicKeyId, certPublicKey, conn.publicKeySignature)) {
httpsClientDebug('PQC public key was signed with TLS public key');
} else {
httpsClientDebug('PQC public key signature is invalid');
// TODO: End the connection
}
});
});
req.on('response', (res) => {
httpsClientDebug('received response');
res.resume();
});
req.end();
});