Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- var net = require('net')
- , encryption = require('./../encryption')
- , ursa = require('ursa')
- , exec = require('child_process').exec
- , fs = require('fs')
- , sh = require('execSync')
- var stdin = process.openStdin()
- var username, password, connection, privateKey, publicKey, otherPublicKey = false, userNames = [], certificate = false, myId, isNew = true
- privateKey = ursa.generatePrivateKey()
- publicKey = privateKey.toPublicPem().toString()
- fs.writeFileSync('private-key.pem', privateKey.toPrivatePem().toString())
- /**************
- GENERATING CERTIFICATE REQUEST AND SENDING IT TO THE CERTIFICATE AUTHOROTY
- ***************/
- sh.exec("openssl req -new -key private-key.pem -out request.pem -subj /C=SY/ST=Syria/L=Damascus/O=A/emailAddress=a@a.com")
- var request = fs.readFileSync('request.pem').toString()
- var caServer = net.connect(5000, function(){
- caServer.write(request)
- caServer.on('data', function(data){
- //getting certificate
- var res = sh.exec('openssl x509 -req -in request.pem -signkey private-key.pem -out certificate.pem')
- certificate = fs.readFileSync('certificate.pem').toString()
- //AFTER WE GET A CERTIFICATE, WE CONNECT TO THE CHAT SERVER
- connectServer()
- })
- })
- var receiveId = false
- var otherPublicKeys = []
- var sessionKey = 'asdf'
- //THIS FUNCTION IS USED TO INITIALIZE THE CONNECTION BETWEEN THE CLIENT AND SERVER
- function initialization(){
- //WE FIRST SEND THE PUBLIC KEY TO THE SERVER
- connection.write(publicKey)
- //THEN WE GET INPUT FROM THE USER
- console.log('Please enter your username!')
- stdin.addListener('data', function(data){
- //WE RECEIVE THE USERNAME
- if (!username){
- username = data
- connection.write(username)
- console.log('Please enter your password')
- //THEN WE RECEIVE THE PASSWORD AND SEND IT
- } else if (!password) {
- password = data
- connection.write(password)
- //THEN WE FINALLY START SENDING DATA ENCRYPTED WITH THE SESSION KEY, ATTACHED WITH OUR ID AND OUR SIGNITURE
- //FORMAT: [signiature:userId:encryptedMessage]
- } else {
- connection.write(encryption.sign(data, privateKey) + ':' + myId.toString() + ':' +encryption.encryptAES(data, sessionKey))
- }
- })
- }
- /*
- FUNCTION TO PROCESS INCOMING DATA
- WE HAVE 4 BASIC INCOMING
- 1) PUBLIC KEYS
- whenever a new user joins the chat group, we send his public key to all other connecting clients
- so that these clients can use this key to verify the digital signed messages sent by this client
- each public key is attached with the client id that it belongs to in addition to the username of
- this client
- Multiple keys are sent in the following format
- -----BEGIN PUBLIC KEY-----
- XXXXXXXXXXXXXXXXXXXXXXXXX
- -----END PUBLIC KEY-----
- username1
- -----END PUBLIC KEY-----
- id1
- -----BEGIN PUBLIC KEY-----
- YYYYYYYYYYYYYYYYYYYYYYYYYY
- -----END PUBLIC KEY-----
- username2
- -----END PUBLIC KEY-----
- id2
- ====
- 2) SESSION KEY
- whever a new client joins the chat group, his is sent a sessionKey that he should use to encrypt
- that he should use to encrypt and decrypt all outgoing and incoming messages
- 3) CLIENT ID
- each client has a unique id that he receives from the server. if the client has an id of 0, then
- he is the first client , and he is responsible for generating and distributing the sessino key
- 4) CHAT MESSAGES
- after the chat user finally gets the session key, he starts sending and receiveing chat message.
- each message is composed of three parts: [signiture:userId:encryptedMessage]
- */
- function input(data){
- var parsed = data.toString()
- var type = parsed.substring(0, 3)
- var string = parsed.substring(3, parsed.length)
- if (type === 'pub'){
- string.split('-----BEGIN PUBLIC KEY-----\n').forEach(function(message){
- if (message.length > 1){
- var isCertificate = true
- var isName = true
- var key, receivedIndex, receivedName
- message.split('-----END PUBLIC KEY-----\n').forEach(function(message){
- if (isCertificate){
- message = '-----BEGIN PUBLIC KEY-----\n' + message + '-----END PUBLIC KEY-----\n'
- key = ursa.createPublicKey(message)
- isCertificate = false
- } else if (isName) {
- receivedName = message
- isName = false
- } else {
- receivedIndex = parseInt(message)
- otherPublicKeys[receivedIndex] = key
- userNames[receivedIndex] = receivedName
- isCertificate = true
- isName = true
- }
- })
- console.log('========================================')
- console.log('SERVER: receiving key of client ' + receivedIndex)
- console.log(key.toPublicPem().toString().slice(0, -1))
- console.log('========================================')
- //IF I AM THE SESSION ADMIN, I SHOULD SEND THE SESSION KEY TO THE NEW CONNECTING CLIENT
- if (myId == 0 && receivedIndex != 0){
- connection.write('sessionKey:' + receivedIndex + ':'+ encryption.encrypt(sessionKey, key))
- }
- }
- })
- } else if (parsed.indexOf('sessionKey') >= 0){
- var result = string.split(':')
- sessionKey = encryption.decrypt(result[2], privateKey)
- console.log('========================================')
- console.log('SERVER: receiving session key: ' + sessionKey)
- console.log('========================================')
- } else if (isNew) {
- myId = parseInt(data.toString())
- console.log('SERVER: Your ID is: '+myId)
- isNew = false
- } else {
- var triple = data.toString().split(':') //converting the received buffer to a string
- var signiture = triple[0]
- var userId = parseInt(triple[1])
- var string = triple[2]
- var decryptedString = encryption.decryptAES(string, sessionKey)
- if (encryption.verify(decryptedString, signiture, otherPublicKeys[userId])){
- //removing /n character
- console.log("| " + userNames[userId] + ': ' + decryptedString.substr(0, decryptedString.length-1))
- } else {
- console.log('Error! The sent string has been changed!!!')
- }
- }
- }
- function connectServer(){
- connection = net.connect(4000, "localhost", initialization)
- connection.on('data', input)
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement