190 lines
4.9 KiB
JavaScript
190 lines
4.9 KiB
JavaScript
var forge = require('../js/forge');
|
|
|
|
// function to create certificate
|
|
var createCert = function(cn, data) {
|
|
console.log(
|
|
'Generating 512-bit key-pair and certificate for \"' + cn + '\".');
|
|
var keys = forge.pki.rsa.generateKeyPair(512);
|
|
console.log('key-pair created.');
|
|
|
|
var cert = forge.pki.createCertificate();
|
|
cert.serialNumber = '01';
|
|
cert.validity.notBefore = new Date();
|
|
cert.validity.notAfter = new Date();
|
|
cert.validity.notAfter.setFullYear(
|
|
cert.validity.notBefore.getFullYear() + 1);
|
|
var attrs = [{
|
|
name: 'commonName',
|
|
value: cn
|
|
}, {
|
|
name: 'countryName',
|
|
value: 'US'
|
|
}, {
|
|
shortName: 'ST',
|
|
value: 'Virginia'
|
|
}, {
|
|
name: 'localityName',
|
|
value: 'Blacksburg'
|
|
}, {
|
|
name: 'organizationName',
|
|
value: 'Test'
|
|
}, {
|
|
shortName: 'OU',
|
|
value: 'Test'
|
|
}];
|
|
cert.setSubject(attrs);
|
|
cert.setIssuer(attrs);
|
|
cert.setExtensions([{
|
|
name: 'basicConstraints',
|
|
cA: true
|
|
}, {
|
|
name: 'keyUsage',
|
|
keyCertSign: true,
|
|
digitalSignature: true,
|
|
nonRepudiation: true,
|
|
keyEncipherment: true,
|
|
dataEncipherment: true
|
|
}, {
|
|
name: 'subjectAltName',
|
|
altNames: [{
|
|
type: 6, // URI
|
|
value: 'http://myuri.com/webid#me'
|
|
}]
|
|
}]);
|
|
// FIXME: add subjectKeyIdentifier extension
|
|
// FIXME: add authorityKeyIdentifier extension
|
|
cert.publicKey = keys.publicKey;
|
|
|
|
// self-sign certificate
|
|
cert.sign(keys.privateKey);
|
|
|
|
// save data
|
|
data[cn] = {
|
|
cert: forge.pki.certificateToPem(cert),
|
|
privateKey: forge.pki.privateKeyToPem(keys.privateKey)
|
|
};
|
|
|
|
console.log('certificate created for \"' + cn + '\": \n' + data[cn].cert);
|
|
};
|
|
|
|
var end = {};
|
|
var data = {};
|
|
|
|
// create certificate for server and client
|
|
createCert('server', data);
|
|
createCert('client', data);
|
|
|
|
var success = false;
|
|
|
|
// create TLS client
|
|
end.client = forge.tls.createConnection({
|
|
server: false,
|
|
caStore: [data.server.cert],
|
|
sessionCache: {},
|
|
// supported cipher suites in order of preference
|
|
cipherSuites: [
|
|
forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA,
|
|
forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA],
|
|
virtualHost: 'server',
|
|
verify: function(c, verified, depth, certs) {
|
|
console.log(
|
|
'TLS Client verifying certificate w/CN: \"' +
|
|
certs[0].subject.getField('CN').value +
|
|
'\", verified: ' + verified + '...');
|
|
return verified;
|
|
},
|
|
connected: function(c) {
|
|
console.log('Client connected...');
|
|
|
|
// send message to server
|
|
setTimeout(function() {
|
|
c.prepareHeartbeatRequest('heartbeat');
|
|
c.prepare('Hello Server');
|
|
}, 1);
|
|
},
|
|
getCertificate: function(c, hint) {
|
|
console.log('Client getting certificate ...');
|
|
return data.client.cert;
|
|
},
|
|
getPrivateKey: function(c, cert) {
|
|
return data.client.privateKey;
|
|
},
|
|
tlsDataReady: function(c) {
|
|
// send TLS data to server
|
|
end.server.process(c.tlsData.getBytes());
|
|
},
|
|
dataReady: function(c) {
|
|
var response = c.data.getBytes();
|
|
console.log('Client received \"' + response + '\"');
|
|
success = (response === 'Hello Client');
|
|
c.close();
|
|
},
|
|
heartbeatReceived: function(c, payload) {
|
|
console.log('Client received heartbeat: ' + payload.getBytes());
|
|
},
|
|
closed: function(c) {
|
|
console.log('Client disconnected.');
|
|
if(success) {
|
|
console.log('PASS');
|
|
} else {
|
|
console.log('FAIL');
|
|
}
|
|
},
|
|
error: function(c, error) {
|
|
console.log('Client error: ' + error.message);
|
|
}
|
|
});
|
|
|
|
// create TLS server
|
|
end.server = forge.tls.createConnection({
|
|
server: true,
|
|
caStore: [data.client.cert],
|
|
sessionCache: {},
|
|
// supported cipher suites in order of preference
|
|
cipherSuites: [
|
|
forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA,
|
|
forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA],
|
|
connected: function(c) {
|
|
console.log('Server connected');
|
|
c.prepareHeartbeatRequest('heartbeat');
|
|
},
|
|
verifyClient: true,
|
|
verify: function(c, verified, depth, certs) {
|
|
console.log(
|
|
'Server verifying certificate w/CN: \"' +
|
|
certs[0].subject.getField('CN').value +
|
|
'\", verified: ' + verified + '...');
|
|
return verified;
|
|
},
|
|
getCertificate: function(c, hint) {
|
|
console.log('Server getting certificate for \"' + hint[0] + '\"...');
|
|
return data.server.cert;
|
|
},
|
|
getPrivateKey: function(c, cert) {
|
|
return data.server.privateKey;
|
|
},
|
|
tlsDataReady: function(c) {
|
|
// send TLS data to client
|
|
end.client.process(c.tlsData.getBytes());
|
|
},
|
|
dataReady: function(c) {
|
|
console.log('Server received \"' + c.data.getBytes() + '\"');
|
|
|
|
// send response
|
|
c.prepare('Hello Client');
|
|
c.close();
|
|
},
|
|
heartbeatReceived: function(c, payload) {
|
|
console.log('Server received heartbeat: ' + payload.getBytes());
|
|
},
|
|
closed: function(c) {
|
|
console.log('Server disconnected.');
|
|
},
|
|
error: function(c, error) {
|
|
console.log('Server error: ' + error.message);
|
|
}
|
|
});
|
|
|
|
console.log('created TLS client and server, doing handshake...');
|
|
end.client.handshake();
|