| 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(); |