From 5f698b82c7055df763f3830882ac5bad1397db23 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 1 Jul 2016 16:22:36 +0200 Subject: Use dashes for filenames --- server/helpers/peertube-crypto.js | 147 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 server/helpers/peertube-crypto.js (limited to 'server/helpers/peertube-crypto.js') diff --git a/server/helpers/peertube-crypto.js b/server/helpers/peertube-crypto.js new file mode 100644 index 000000000..46dff8d03 --- /dev/null +++ b/server/helpers/peertube-crypto.js @@ -0,0 +1,147 @@ +'use strict' + +const config = require('config') +const crypto = require('crypto') +const fs = require('fs') +const openssl = require('openssl-wrapper') +const path = require('path') +const ursa = require('ursa') + +const logger = require('./logger') + +const certDir = path.join(__dirname, '..', '..', config.get('storage.certs')) +const algorithm = 'aes-256-ctr' + +const peertubeCrypto = { + checkSignature: checkSignature, + createCertsIfNotExist: createCertsIfNotExist, + decrypt: decrypt, + encrypt: encrypt, + getCertDir: getCertDir, + sign: sign +} + +function checkSignature (publicKey, rawData, hexSignature) { + const crt = ursa.createPublicKey(publicKey) + const isValid = crt.hashAndVerify('sha256', new Buffer(rawData).toString('hex'), hexSignature, 'hex') + return isValid +} + +function createCertsIfNotExist (callback) { + certsExist(function (exist) { + if (exist === true) { + return callback(null) + } + + createCerts(function (err) { + return callback(err) + }) + }) +} + +function decrypt (key, data, callback) { + fs.readFile(getCertDir() + 'peertube.key.pem', function (err, file) { + if (err) return callback(err) + + const myPrivateKey = ursa.createPrivateKey(file) + const decryptedKey = myPrivateKey.decrypt(key, 'hex', 'utf8') + const decryptedData = symetricDecrypt(data, decryptedKey) + + return callback(null, decryptedData) + }) +} + +function encrypt (publicKey, data, callback) { + const crt = ursa.createPublicKey(publicKey) + + symetricEncrypt(data, function (err, dataEncrypted) { + if (err) return callback(err) + + const key = crt.encrypt(dataEncrypted.password, 'utf8', 'hex') + const encrypted = { + data: dataEncrypted.crypted, + key: key + } + + callback(null, encrypted) + }) +} + +function getCertDir () { + return certDir +} + +function sign (data) { + const myKey = ursa.createPrivateKey(fs.readFileSync(certDir + 'peertube.key.pem')) + const signature = myKey.hashAndSign('sha256', data, 'utf8', 'hex') + + return signature +} + +// --------------------------------------------------------------------------- + +module.exports = peertubeCrypto + +// --------------------------------------------------------------------------- + +function certsExist (callback) { + fs.exists(certDir + 'peertube.key.pem', function (exists) { + return callback(exists) + }) +} + +function createCerts (callback) { + certsExist(function (exist) { + if (exist === true) { + const string = 'Certs already exist.' + logger.warning(string) + return callback(new Error(string)) + } + + logger.info('Generating a RSA key...') + openssl.exec('genrsa', { 'out': certDir + 'peertube.key.pem', '2048': false }, function (err) { + if (err) { + logger.error('Cannot create private key on this pod.') + return callback(err) + } + logger.info('RSA key generated.') + + logger.info('Manage public key...') + openssl.exec('rsa', { 'in': certDir + 'peertube.key.pem', 'pubout': true, 'out': certDir + 'peertube.pub' }, function (err) { + if (err) { + logger.error('Cannot create public key on this pod.') + return callback(err) + } + + logger.info('Public key managed.') + return callback(null) + }) + }) + }) +} + +function generatePassword (callback) { + crypto.randomBytes(32, function (err, buf) { + if (err) return callback(err) + + callback(null, buf.toString('utf8')) + }) +} + +function symetricDecrypt (text, password) { + const decipher = crypto.createDecipher(algorithm, password) + let dec = decipher.update(text, 'hex', 'utf8') + dec += decipher.final('utf8') + return dec +} + +function symetricEncrypt (text, callback) { + generatePassword(function (err, password) { + if (err) return callback(err) + + const cipher = crypto.createCipher(algorithm, password) + let crypted = cipher.update(text, 'utf8', 'hex') + crypted += cipher.final('hex') + callback(null, { crypted: crypted, password: password }) + }) +} -- cgit v1.2.3